From 0b8973a81876d90f916507ac40d1381068dc986a Mon Sep 17 00:00:00 2001 From: "Luck, Tony" Date: Wed, 16 Dec 2009 22:59:29 +0000 Subject: intel-iommu: Fix section mismatch dmar_ir_support() uses dmar_tbl. dmar_tbl is declared as __initdata, but dmar_ir_support() is not declared as an __init function. Fix is simple since the only caller of dmar_ir_support (intr_remapping_supported) is an __init function. Signed-off-by: Tony Luck Signed-off-by: David Woodhouse --- drivers/pci/dmar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 83aae4747594..ffe22bc3ac8e 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -1456,7 +1456,7 @@ int dmar_reenable_qi(struct intel_iommu *iommu) /* * Check interrupt remapping support in DMAR table description. */ -int dmar_ir_support(void) +int __init dmar_ir_support(void) { struct acpi_table_dmar *dmar; dmar = (struct acpi_table_dmar *)dmar_tbl; -- cgit v1.2.3 From 68ca406930d6380b3be7ada5f15fcf85bfcbd552 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 19 Feb 2010 00:09:22 -0500 Subject: ACPI: delete the "acpi=ht" boot option acpi=ht was important in 2003 -- before ACPI was universally deployed and enabled by default in the major Linux distributions. At that time, there were a fair number of people who or chose to, or needed to, run with acpi=off, yet also wanted access to Hyper-threading. Today we find that many invocations of "acpi=ht" are accidental, and thus is it possible that it is doing more harm than good. In 2.6.34, we warn on invocation of acpi=ht. In 2.6.35, we delete the boot option. Signed-off-by: Len Brown --- Documentation/kernel-parameters.txt | 3 +-- arch/ia64/include/asm/acpi.h | 1 - arch/x86/include/asm/acpi.h | 2 -- arch/x86/kernel/acpi/boot.c | 19 +++---------------- arch/x86/lguest/boot.c | 1 - drivers/acpi/tables.c | 4 ++-- 6 files changed, 6 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 3bc48b0bd3a9..41b924ff0b51 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -143,11 +143,10 @@ and is between 256 and 4096 characters. It is defined in the file acpi= [HW,ACPI,X86] Advanced Configuration and Power Interface - Format: { force | off | ht | strict | noirq | rsdt } + Format: { force | off | strict | noirq | rsdt } force -- enable ACPI if default was off off -- disable ACPI if default was on noirq -- do not use ACPI for IRQ routing - ht -- run only enough ACPI to enable Hyper Threading strict -- Be less tolerant of platforms that are not strictly ACPI specification compliant. rsdt -- prefer RSDT over (default) XSDT diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h index 21adbd7f90f8..837dc82a013e 100644 --- a/arch/ia64/include/asm/acpi.h +++ b/arch/ia64/include/asm/acpi.h @@ -94,7 +94,6 @@ ia64_acpi_release_global_lock (unsigned int *lock) #define acpi_noirq 0 /* ACPI always enabled on IA64 */ #define acpi_pci_disabled 0 /* ACPI PCI always enabled on IA64 */ #define acpi_strict 1 /* no ACPI spec workarounds on IA64 */ -#define acpi_ht 0 /* no HT-only mode on IA64 */ #endif #define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */ static inline void disable_acpi(void) { } diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 56f462cf22d2..aa2c39d968fc 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -85,7 +85,6 @@ extern int acpi_ioapic; extern int acpi_noirq; extern int acpi_strict; extern int acpi_disabled; -extern int acpi_ht; extern int acpi_pci_disabled; extern int acpi_skip_timer_override; extern int acpi_use_timer_override; @@ -97,7 +96,6 @@ void acpi_pic_sci_set_trigger(unsigned int, u16); static inline void disable_acpi(void) { acpi_disabled = 1; - acpi_ht = 0; acpi_pci_disabled = 1; acpi_noirq = 1; } diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 7914ab0ad76e..63bcf39f8f24 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -62,7 +62,6 @@ EXPORT_SYMBOL(acpi_disabled); int acpi_noirq; /* skip ACPI IRQ initialization */ int acpi_pci_disabled; /* skip ACPI PCI scan and IRQ initialization */ EXPORT_SYMBOL(acpi_pci_disabled); -int acpi_ht __initdata = 1; /* enable HT */ int acpi_lapic; int acpi_ioapic; @@ -1460,9 +1459,8 @@ void __init acpi_boot_table_init(void) /* * If acpi_disabled, bail out - * One exception: acpi=ht continues far enough to enumerate LAPICs */ - if (acpi_disabled && !acpi_ht) + if (acpi_disabled) return; /* @@ -1493,9 +1491,8 @@ int __init early_acpi_boot_init(void) { /* * If acpi_disabled, bail out - * One exception: acpi=ht continues far enough to enumerate LAPICs */ - if (acpi_disabled && !acpi_ht) + if (acpi_disabled) return 1; /* @@ -1513,9 +1510,8 @@ int __init acpi_boot_init(void) /* * If acpi_disabled, bail out - * One exception: acpi=ht continues far enough to enumerate LAPICs */ - if (acpi_disabled && !acpi_ht) + if (acpi_disabled) return 1; acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf); @@ -1550,21 +1546,12 @@ static int __init parse_acpi(char *arg) /* acpi=force to over-ride black-list */ else if (strcmp(arg, "force") == 0) { acpi_force = 1; - acpi_ht = 1; acpi_disabled = 0; } /* acpi=strict disables out-of-spec workarounds */ else if (strcmp(arg, "strict") == 0) { acpi_strict = 1; } - /* Limit ACPI just to boot-time to enable HT */ - else if (strcmp(arg, "ht") == 0) { - if (!acpi_force) { - printk(KERN_WARNING "acpi=ht will be removed in Linux-2.6.35\n"); - disable_acpi(); - } - acpi_ht = 1; - } /* acpi=rsdt use RSDT instead of XSDT */ else if (strcmp(arg, "rsdt") == 0) { acpi_rsdt_forced = 1; diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 7e59dc1d3fc2..8eb9eed60282 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -1391,7 +1391,6 @@ __init void lguest_init(void) #endif #ifdef CONFIG_ACPI acpi_disabled = 1; - acpi_ht = 0; #endif /* diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 8a0ed2800e63..f336bca7c450 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -213,7 +213,7 @@ acpi_table_parse_entries(char *id, unsigned long table_end; acpi_size tbl_size; - if (acpi_disabled && !acpi_ht) + if (acpi_disabled) return -ENODEV; if (!handler) @@ -280,7 +280,7 @@ int __init acpi_table_parse(char *id, acpi_table_handler handler) struct acpi_table_header *table = NULL; acpi_size tbl_size; - if (acpi_disabled && !acpi_ht) + if (acpi_disabled) return -ENODEV; if (!handler) -- cgit v1.2.3 From 4adbbcc7b6cfb3dcf5ab49b06edb7752391b0e80 Mon Sep 17 00:00:00 2001 From: San Mehat Date: Sun, 8 Nov 2009 13:00:37 -0800 Subject: mmc: msm_sdcc: Clean up clock management and add a 10us delay after enabling clocks It appears that in some cases there may be a delay on the ARM9 in enabling our clock. As a result, we may put the controller into a bad state. Delay 10us after enabling clocks to let the peripheral settle. Note - this is all imperical. Also ensure set_ios() callback grabs the host lock. Signed-off-by: San Mehat Signed-off-by: Daniel Walker --- drivers/mmc/host/msm_sdcc.c | 80 ++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 4c068e5fe6b2..977932a4bf4b 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -735,20 +735,42 @@ msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq) spin_unlock_irqrestore(&host->lock, flags); } +static int inline +msmsdcc_enable_clocks(struct msmsdcc_host *host, int enable) +{ + int rc; + if (enable) { + rc = clk_enable(host->pclk); + if (rc) + return rc; + rc = clk_enable(host->clk); + if (rc) { + clk_disable(host->pclk); + return rc; + } + host->clks_on = 1; + udelay(10); + } else { + clk_disable(host->clk); + clk_disable(host->pclk); + host->clks_on = 0; + } + return 0; +} + static void msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct msmsdcc_host *host = mmc_priv(mmc); u32 clk = 0, pwr = 0; int rc; + unsigned long flags; + spin_lock_irqsave(&host->lock, flags); if (ios->clock) { - if (!host->clks_on) { - clk_enable(host->pclk); - clk_enable(host->clk); - host->clks_on = 1; - } + if (!host->clks_on) + msmsdcc_enable_clocks(host, 1); if (ios->clock != host->clk_rate) { rc = clk_set_rate(host->clk, ios->clock); if (rc < 0) @@ -793,11 +815,9 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) writel(pwr, host->base + MMCIPOWER); } - if (!(clk & MCI_CLK_ENABLE) && host->clks_on) { - clk_disable(host->clk); - clk_disable(host->pclk); - host->clks_on = 0; - } + if (!(clk & MCI_CLK_ENABLE) && host->clks_on) + msmsdcc_enable_clocks(host, 0); + spin_unlock_irqrestore(&host->lock, flags); } static void msmsdcc_enable_sdio_irq(struct mmc_host *mmc, int enable) @@ -899,7 +919,6 @@ msmsdcc_command_expired(unsigned long _data) pr_err("%s: Command timeout (%p %p %p %p)\n", mmc_hostname(host->mmc), mrq, mrq->cmd, mrq->data, host->dma.sg); - mrq->cmd->error = -ETIMEDOUT; msmsdcc_stop_data(host); @@ -1031,31 +1050,21 @@ msmsdcc_probe(struct platform_device *pdev) */ msmsdcc_init_dma(host); - /* - * Setup main peripheral bus clock - */ + /* Get our clocks */ host->pclk = clk_get(&pdev->dev, "sdc_pclk"); if (IS_ERR(host->pclk)) { ret = PTR_ERR(host->pclk); goto host_free; } - ret = clk_enable(host->pclk); - if (ret) - goto pclk_put; - - host->pclk_rate = clk_get_rate(host->pclk); - - /* - * Setup SDC MMC clock - */ host->clk = clk_get(&pdev->dev, "sdc_clk"); if (IS_ERR(host->clk)) { ret = PTR_ERR(host->clk); - goto pclk_disable; + goto pclk_put; } - ret = clk_enable(host->clk); + /* Enable clocks */ + ret = msmsdcc_enable_clocks(host, 1); if (ret) goto clk_put; @@ -1065,10 +1074,9 @@ msmsdcc_probe(struct platform_device *pdev) goto clk_disable; } + host->pclk_rate = clk_get_rate(host->pclk); host->clk_rate = clk_get_rate(host->clk); - host->clks_on = 1; - /* * Setup MMC host structure */ @@ -1187,11 +1195,9 @@ msmsdcc_probe(struct platform_device *pdev) if (host->stat_irq) free_irq(host->stat_irq, host); clk_disable: - clk_disable(host->clk); + msmsdcc_enable_clocks(host, 0); clk_put: clk_put(host->clk); - pclk_disable: - clk_disable(host->pclk); pclk_put: clk_put(host->pclk); host_free: @@ -1217,11 +1223,8 @@ msmsdcc_suspend(struct platform_device *dev, pm_message_t state) if (!rc) { writel(0, host->base + MMCIMASK0); - if (host->clks_on) { - clk_disable(host->clk); - clk_disable(host->pclk); - host->clks_on = 0; - } + if (host->clks_on) + msmsdcc_enable_clocks(host, 0); } } return rc; @@ -1238,11 +1241,8 @@ msmsdcc_resume(struct platform_device *dev) spin_lock_irqsave(&host->lock, flags); - if (!host->clks_on) { - clk_enable(host->pclk); - clk_enable(host->clk); - host->clks_on = 1; - } + if (!host->clks_on) + msmsdcc_enable_clocks(host, 1); writel(host->saved_irq0mask, host->base + MMCIMASK0); -- cgit v1.2.3 From b3fa579118b239e218e690f5ef76870aff6fe738 Mon Sep 17 00:00:00 2001 From: San Mehat Date: Mon, 2 Nov 2009 18:46:09 -0800 Subject: mmc: msm_sdcc: Snoop SDIO_CCCR_ABORT register Signed-off-by: San Mehat Signed-off-by: Daniel Walker --- drivers/mmc/host/msm_sdcc.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 977932a4bf4b..f4f7883271f0 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -355,6 +356,16 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data) } } +static int +snoop_cccr_abort(struct mmc_command *cmd) +{ + if ((cmd->opcode == 52) && + (cmd->arg & 0x80000000) && + (((cmd->arg >> 9) & 0x1ffff) == SDIO_CCCR_ABORT)) + return 1; + return 0; +} + static void msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, u32 c) { @@ -381,6 +392,9 @@ msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, u32 c) if (cmd == cmd->mrq->stop) c |= MCI_CSPM_MCIABORT; + if (snoop_cccr_abort(cmd)) + c |= MCI_CSPM_MCIABORT; + host->curr.cmd = cmd; host->stats.cmds++; -- cgit v1.2.3 From 5b00f40f90e7b17c11cf388680f43e8466b3666d Mon Sep 17 00:00:00 2001 From: San Mehat Date: Sat, 21 Nov 2009 09:22:14 -0800 Subject: msm: Add 'execute' datamover callback Based on a patch from Brent DeGraaf: "The datamover supports channels which can be shared amongst devices. As a result, the actual data transfer may occur some time after the request is queued up. Some devices such as mmc host controllers will timeout if a command is issued too far in advance of the actual transfer, so if dma to other devices on the same channel is already in progress or queued up, the added delay can cause pending transfers to fail before they start. This change extends the api to allow a user callback to be invoked just before the actual transfer takes place, thus allowing actions directly associated with the dma transfer, such as device commands, to be invoked with precise timing. Without this mechanism, there is no way for a driver to realize this timing. Also adds a user pointer to the command structure for use by the caller to reference information that may be needed by the callback routine for proper identification and processing associated with that specific request. This change is necessary to fix problems associated with excessive command timeouts and race conditions in the mmc driver." This patch also fixes all the callers of msm_dmov_enqueue_cmd() to ensure their callback function is NULL. Signed-off-by: San Mehat Cc: Brent DeGraaf Cc: Brian Swetland Signed-off-by: Daniel Walker --- arch/arm/mach-msm/dma.c | 5 +++++ arch/arm/mach-msm/include/mach/dma.h | 2 ++ drivers/mmc/host/msm_sdcc.c | 1 + 3 files changed, 8 insertions(+) (limited to 'drivers') diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c index f5420f9585c5..8df798ac70c7 100644 --- a/arch/arm/mach-msm/dma.c +++ b/arch/arm/mach-msm/dma.c @@ -63,6 +63,8 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) writel(DMOV_CONFIG_IRQ_EN, DMOV_CONFIG(id)); } #endif + if (cmd->execute_func) + cmd->execute_func(cmd); PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n", id, status); list_add_tail(&cmd->list, &active_commands[id]); if (!channel_active) @@ -108,6 +110,7 @@ int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr) cmd.dmov_cmd.cmdptr = cmdptr; cmd.dmov_cmd.complete_func = dmov_exec_cmdptr_complete_func; + cmd.dmov_cmd.execute_func = NULL; cmd.id = id; init_completion(&cmd.complete); @@ -210,6 +213,8 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id) cmd = list_entry(ready_commands[id].next, typeof(*cmd), list); list_del(&cmd->list); list_add_tail(&cmd->list, &active_commands[id]); + if (cmd->execute_func) + cmd->execute_func(cmd); PRINT_FLOW("msm_datamover_irq_handler id %d, start command\n", id); writel(cmd->cmdptr, DMOV_CMD_PTR(id)); } diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h index 5ab5bdffab07..78b0ffdf27e8 100644 --- a/arch/arm/mach-msm/include/mach/dma.h +++ b/arch/arm/mach-msm/include/mach/dma.h @@ -28,6 +28,8 @@ struct msm_dmov_cmd { void (*complete_func)(struct msm_dmov_cmd *cmd, unsigned int result, struct msm_dmov_errdata *err); + void (*execute_func)(struct msm_dmov_cmd *cmd); + void *data; }; void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd); diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index f4f7883271f0..02bec7c739e0 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -299,6 +299,7 @@ static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data) host->dma.hdr.cmdptr = DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(host->dma.cmdptr_busaddr); host->dma.hdr.complete_func = msmsdcc_dma_complete_func; + host->dma.hdr.execute_func = NULL; return 0; } -- cgit v1.2.3 From 865c8064a2fb07100525097983966b8e789bde1a Mon Sep 17 00:00:00 2001 From: San Mehat Date: Fri, 13 Nov 2009 13:42:06 -0800 Subject: mmc: msm_sdcc: Driver clocking/irq improvements - Clocks are now disabled after 1 second of inactivity - Fixed issue which was causing us to loop through our ISR twice - Bump core clock enable delay to 30us Signed-off-by: San Mehat Signed-off-by: Daniel Walker --- drivers/mmc/host/msm_sdcc.c | 89 +++++++++++++++++++++++++++++++-------------- drivers/mmc/host/msm_sdcc.h | 2 + 2 files changed, 63 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 02bec7c739e0..b4b637223b75 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -57,6 +57,32 @@ static unsigned int msmsdcc_sdioirq; #define PIO_SPINMAX 30 #define CMD_SPINMAX 20 + +static inline int +msmsdcc_enable_clocks(struct msmsdcc_host *host, int enable) +{ + int rc; + WARN_ON(enable == host->clks_on); + if (enable) { + rc = clk_enable(host->pclk); + if (rc) + return rc; + rc = clk_enable(host->clk); + if (rc) { + clk_disable(host->pclk); + return rc; + } + udelay(30); + host->clks_on = 1; + } else { + clk_disable(host->clk); + clk_disable(host->pclk); + host->clks_on = 0; + } + return 0; +} + + static void msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, u32 c); @@ -76,6 +102,8 @@ msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq) if (mrq->cmd->error == -ETIMEDOUT) mdelay(5); + if (host->use_bustimer) + mod_timer(&host->busclk_timer, jiffies + HZ); /* * Need to drop the host lock here; mmc_request_done may call * back into the driver... @@ -676,6 +704,12 @@ msmsdcc_irq(int irq, void *dev_id) status &= (readl(base + MMCIMASK0) | MCI_DATABLOCKENDMASK); writel(status, base + MMCICLEAR); + if (status & MCI_SDIOINTR) + status &= ~MCI_SDIOINTR; + + if (!status) + break; + msmsdcc_handle_irq_data(host, status, base); if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL | @@ -729,6 +763,8 @@ msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq) } host->curr.mrq = mrq; + if (!host->clks_on) + msmsdcc_enable_clocks(host, 1); if (mrq->data && mrq->data->flags & MMC_DATA_READ) msmsdcc_start_data(host, mrq->data); @@ -750,29 +786,6 @@ msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq) spin_unlock_irqrestore(&host->lock, flags); } -static int inline -msmsdcc_enable_clocks(struct msmsdcc_host *host, int enable) -{ - int rc; - if (enable) { - rc = clk_enable(host->pclk); - if (rc) - return rc; - rc = clk_enable(host->clk); - if (rc) { - clk_disable(host->pclk); - return rc; - } - host->clks_on = 1; - udelay(10); - } else { - clk_disable(host->clk); - clk_disable(host->pclk); - host->clks_on = 0; - } - return 0; -} - static void msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { @@ -782,10 +795,10 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) unsigned long flags; spin_lock_irqsave(&host->lock, flags); - if (ios->clock) { + if (!host->clks_on) + msmsdcc_enable_clocks(host, 1); - if (!host->clks_on) - msmsdcc_enable_clocks(host, 1); + if (ios->clock) { if (ios->clock != host->clk_rate) { rc = clk_set_rate(host->clk, ios->clock); if (rc < 0) @@ -829,8 +842,7 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) host->pwr = pwr; writel(pwr, host->base + MMCIPOWER); } - - if (!(clk & MCI_CLK_ENABLE) && host->clks_on) + if (host->clks_on) msmsdcc_enable_clocks(host, 0); spin_unlock_irqrestore(&host->lock, flags); } @@ -909,6 +921,19 @@ msmsdcc_status_notify_cb(int card_present, void *dev_id) msmsdcc_check_status((unsigned long) host); } +static void +msmsdcc_busclk_expired(unsigned long _data) +{ + struct msmsdcc_host *host = (struct msmsdcc_host *) _data; + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + if (host->clks_on) + msmsdcc_enable_clocks(host, 0); + + spin_unlock_irqrestore(&host->lock, flags); +} + /* * called when a command expires. * Dump some debugging, and then error @@ -942,6 +967,8 @@ msmsdcc_command_expired(unsigned long _data) host->curr.mrq = NULL; host->curr.cmd = NULL; + if (host->clks_on) + msmsdcc_enable_clocks(host, 0); spin_unlock_irqrestore(&host->lock, flags); mmc_request_done(host->mmc, mrq); } @@ -1048,6 +1075,8 @@ msmsdcc_probe(struct platform_device *pdev) host->cmdpoll = 1; + host->use_bustimer = 1; + host->base = ioremap(memres->start, PAGE_SIZE); if (!host->base) { ret = -ENOMEM; @@ -1167,6 +1196,10 @@ msmsdcc_probe(struct platform_device *pdev) host->command_timer.data = (unsigned long) host; host->command_timer.function = msmsdcc_command_expired; + init_timer(&host->busclk_timer); + host->busclk_timer.data = (unsigned long) host; + host->busclk_timer.function = msmsdcc_busclk_expired; + ret = request_irq(cmd_irqres->start, msmsdcc_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host); if (ret) diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h index 8c8448469811..6846bd7dff22 100644 --- a/drivers/mmc/host/msm_sdcc.h +++ b/drivers/mmc/host/msm_sdcc.h @@ -214,6 +214,8 @@ struct msmsdcc_host { struct clk *pclk; /* SDCC peripheral bus clock */ unsigned int clks_on; /* set if clocks are enabled */ struct timer_list command_timer; + struct timer_list busclk_timer; + int use_bustimer; unsigned int eject; /* eject state */ -- cgit v1.2.3 From 8b1c2ba274c8416afb7eab3bd788f98a917efe06 Mon Sep 17 00:00:00 2001 From: San Mehat Date: Mon, 16 Nov 2009 10:17:30 -0800 Subject: mmc: msm_sdcc: Wrap readl/writel calls with appropriate clk delays As it turns out, all sdcc register writes must be delayed by at least 3 core clock cycles for the writes to take effect. *sigh* Also removes the 30us constant delay on clock enable in favor of a 3 core clock delay. Signed-off-by: San Mehat Signed-off-by: Daniel Walker --- drivers/mmc/host/msm_sdcc.c | 116 +++++++++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index b4b637223b75..3b096f64ec52 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -62,6 +62,7 @@ static inline int msmsdcc_enable_clocks(struct msmsdcc_host *host, int enable) { int rc; + WARN_ON(enable == host->clks_on); if (enable) { rc = clk_enable(host->pclk); @@ -72,7 +73,8 @@ msmsdcc_enable_clocks(struct msmsdcc_host *host, int enable) clk_disable(host->pclk); return rc; } - udelay(30); + udelay(1 + ((3 * USEC_PER_SEC) / + (host->clk_rate ? host->clk_rate : msmsdcc_fmin))); host->clks_on = 1; } else { clk_disable(host->clk); @@ -82,6 +84,20 @@ msmsdcc_enable_clocks(struct msmsdcc_host *host, int enable) return 0; } +static inline unsigned int +msmsdcc_readl(struct msmsdcc_host *host, unsigned int reg) +{ + return readl(host->base + reg); +} + +static inline void +msmsdcc_writel(struct msmsdcc_host *host, u32 data, unsigned int reg) +{ + writel(data, host->base + reg); + /* 3 clk delay required! */ + udelay(1 + ((3 * USEC_PER_SEC) / + (host->clk_rate ? host->clk_rate : msmsdcc_fmin))); +} static void msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, @@ -90,7 +106,7 @@ msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, static void msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq) { - writel(0, host->base + MMCICOMMAND); + msmsdcc_writel(host, 0, MMCICOMMAND); BUG_ON(host->curr.data); @@ -116,7 +132,7 @@ msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq) static void msmsdcc_stop_data(struct msmsdcc_host *host) { - writel(0, host->base + MMCIDATACTRL); + msmsdcc_writel(host, 0, MMCIDATACTRL); host->curr.data = NULL; host->curr.got_dataend = host->curr.got_datablkend = 0; } @@ -200,7 +216,7 @@ msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd, if (!mrq->data->error) host->curr.data_xfered = host->curr.xfer_size; if (!mrq->data->stop || mrq->cmd->error) { - writel(0, host->base + MMCICOMMAND); + msmsdcc_writel(host, 0, MMCICOMMAND); host->curr.mrq = NULL; host->curr.cmd = NULL; mrq->data->bytes_xfered = host->curr.data_xfered; @@ -337,7 +353,6 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data) { unsigned int datactrl, timeout; unsigned long long clks; - void __iomem *base = host->base; unsigned int pio_irqmask = 0; host->curr.data = data; @@ -352,9 +367,9 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data) clks = (unsigned long long)data->timeout_ns * host->clk_rate; do_div(clks, NSEC_PER_SEC); timeout = data->timeout_clks + (unsigned int)clks; - writel(timeout, base + MMCIDATATIMER); + msmsdcc_writel(host, timeout, MMCIDATATIMER); - writel(host->curr.xfer_size, base + MMCIDATALENGTH); + msmsdcc_writel(host, host->curr.xfer_size, MMCIDATALENGTH); datactrl = MCI_DPSM_ENABLE | (data->blksz << 4); @@ -376,8 +391,8 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data) if (data->flags & MMC_DATA_READ) datactrl |= MCI_DPSM_DIRECTION; - writel(pio_irqmask, base + MMCIMASK1); - writel(datactrl, base + MMCIDATACTRL); + msmsdcc_writel(host, pio_irqmask, MMCIMASK1); + msmsdcc_writel(host, datactrl, MMCIDATACTRL); if (datactrl & MCI_DPSM_DMAENABLE) { host->dma.busy = 1; @@ -398,12 +413,8 @@ snoop_cccr_abort(struct mmc_command *cmd) static void msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, u32 c) { - void __iomem *base = host->base; - - if (readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE) { - writel(0, base + MMCICOMMAND); - udelay(2 + ((5 * 1000000) / host->clk_rate)); - } + if (msmsdcc_readl(host, MMCICOMMAND) & MCI_CPSM_ENABLE) + msmsdcc_writel(host, 0, MMCICOMMAND); c |= cmd->opcode | MCI_CPSM_ENABLE; @@ -428,8 +439,8 @@ msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, u32 c) host->stats.cmds++; - writel(cmd->arg, base + MMCIARGUMENT); - writel(c, base + MMCICOMMAND); + msmsdcc_writel(host, cmd->arg, MMCIARGUMENT); + msmsdcc_writel(host, c, MMCICOMMAND); } static void @@ -463,13 +474,11 @@ msmsdcc_data_err(struct msmsdcc_host *host, struct mmc_data *data, static int msmsdcc_pio_read(struct msmsdcc_host *host, char *buffer, unsigned int remain) { - void __iomem *base = host->base; uint32_t *ptr = (uint32_t *) buffer; int count = 0; - while (readl(base + MMCISTATUS) & MCI_RXDATAAVLBL) { - - *ptr = readl(base + MMCIFIFO + (count % MCI_FIFOSIZE)); + while (msmsdcc_readl(host, MMCISTATUS) & MCI_RXDATAAVLBL) { + *ptr = msmsdcc_readl(host, MMCIFIFO + (count % MCI_FIFOSIZE)); ptr++; count += sizeof(uint32_t); @@ -501,7 +510,7 @@ msmsdcc_pio_write(struct msmsdcc_host *host, char *buffer, if (remain == 0) break; - status = readl(base + MMCISTATUS); + status = msmsdcc_readl(host, MMCISTATUS); } while (status & MCI_TXFIFOHALFEMPTY); return ptr - buffer; @@ -511,7 +520,7 @@ static int msmsdcc_spin_on_status(struct msmsdcc_host *host, uint32_t mask, int maxspin) { while (maxspin) { - if ((readl(host->base + MMCISTATUS) & mask)) + if ((msmsdcc_readl(host, MMCISTATUS) & mask)) return 0; udelay(1); --maxspin; @@ -523,10 +532,9 @@ static int msmsdcc_pio_irq(int irq, void *dev_id) { struct msmsdcc_host *host = dev_id; - void __iomem *base = host->base; uint32_t status; - status = readl(base + MMCISTATUS); + status = msmsdcc_readl(host, MMCISTATUS); do { unsigned long flags; @@ -581,14 +589,14 @@ msmsdcc_pio_irq(int irq, void *dev_id) host->pio.sg_off = 0; } - status = readl(base + MMCISTATUS); + status = msmsdcc_readl(host, MMCISTATUS); } while (1); if (status & MCI_RXACTIVE && host->curr.xfer_remain < MCI_FIFOSIZE) - writel(MCI_RXDATAAVLBLMASK, base + MMCIMASK1); + msmsdcc_writel(host, MCI_RXDATAAVLBLMASK, MMCIMASK1); if (!host->curr.xfer_remain) - writel(0, base + MMCIMASK1); + msmsdcc_writel(host, 0, MMCIMASK1); return IRQ_HANDLED; } @@ -596,13 +604,12 @@ msmsdcc_pio_irq(int irq, void *dev_id) static void msmsdcc_do_cmdirq(struct msmsdcc_host *host, uint32_t status) { struct mmc_command *cmd = host->curr.cmd; - void __iomem *base = host->base; host->curr.cmd = NULL; - cmd->resp[0] = readl(base + MMCIRESPONSE0); - cmd->resp[1] = readl(base + MMCIRESPONSE1); - cmd->resp[2] = readl(base + MMCIRESPONSE2); - cmd->resp[3] = readl(base + MMCIRESPONSE3); + cmd->resp[0] = msmsdcc_readl(host, MMCIRESPONSE0); + cmd->resp[1] = msmsdcc_readl(host, MMCIRESPONSE1); + cmd->resp[2] = msmsdcc_readl(host, MMCIRESPONSE2); + cmd->resp[3] = msmsdcc_readl(host, MMCIRESPONSE3); del_timer(&host->command_timer); if (status & MCI_CMDTIMEOUT) { @@ -699,10 +706,11 @@ msmsdcc_irq(int irq, void *dev_id) spin_lock(&host->lock); do { - status = readl(base + MMCISTATUS); - - status &= (readl(base + MMCIMASK0) | MCI_DATABLOCKENDMASK); - writel(status, base + MMCICLEAR); + struct mmc_data *data; + status = msmsdcc_readl(host, MMCISTATUS); + status &= (msmsdcc_readl(host, MMCIMASK0) | + MCI_DATABLOCKENDMASK); + msmsdcc_writel(host, status, MMCICLEAR); if (status & MCI_SDIOINTR) status &= ~MCI_SDIOINTR; @@ -774,10 +782,11 @@ msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq) if (host->cmdpoll && !msmsdcc_spin_on_status(host, MCI_CMDRESPEND|MCI_CMDCRCFAIL|MCI_CMDTIMEOUT, CMD_SPINMAX)) { - uint32_t status = readl(host->base + MMCISTATUS); + uint32_t status = msmsdcc_readl(host, MMCISTATUS); msmsdcc_do_cmdirq(host, status); - writel(MCI_CMDRESPEND | MCI_CMDCRCFAIL | MCI_CMDTIMEOUT, - host->base + MMCICLEAR); + msmsdcc_writel(host, + MCI_CMDRESPEND | MCI_CMDCRCFAIL | MCI_CMDTIMEOUT, + MMCICLEAR); host->stats.cmdpoll_hits++; } else { host->stats.cmdpoll_misses++; @@ -836,11 +845,11 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) pwr |= MCI_OD; - writel(clk, host->base + MMCICLOCK); + msmsdcc_writel(host, clk, MMCICLOCK); if (host->pwr != pwr) { host->pwr = pwr; - writel(pwr, host->base + MMCIPOWER); + msmsdcc_writel(host, pwr, MMCIPOWER); } if (host->clks_on) msmsdcc_enable_clocks(host, 0); @@ -855,13 +864,13 @@ static void msmsdcc_enable_sdio_irq(struct mmc_host *mmc, int enable) spin_lock_irqsave(&host->lock, flags); if (msmsdcc_sdioirq == 1) { - status = readl(host->base + MMCIMASK0); + status = msmsdcc_readl(host, MMCIMASK0); if (enable) status |= MCI_SDIOINTOPERMASK; else status &= ~MCI_SDIOINTOPERMASK; host->saved_irq0mask = status; - writel(status, host->base + MMCIMASK0); + msmsdcc_writel(host, status, MMCIMASK0); } spin_unlock_irqrestore(&host->lock, flags); } @@ -950,19 +959,16 @@ msmsdcc_command_expired(unsigned long _data) mrq = host->curr.mrq; if (!mrq) { - pr_info("%s: Command expiry misfire\n", - mmc_hostname(host->mmc)); spin_unlock_irqrestore(&host->lock, flags); return; } - pr_err("%s: Command timeout (%p %p %p %p)\n", - mmc_hostname(host->mmc), mrq, mrq->cmd, - mrq->data, host->dma.sg); + pr_err("%s: Controller lockup detected\n", + mmc_hostname(host->mmc)); mrq->cmd->error = -ETIMEDOUT; msmsdcc_stop_data(host); - writel(0, host->base + MMCICOMMAND); + msmsdcc_writel(host, 0, MMCICOMMAND); host->curr.mrq = NULL; host->curr.cmd = NULL; @@ -1143,10 +1149,10 @@ msmsdcc_probe(struct platform_device *pdev) mmc->max_req_size = 33554432; /* MCI_DATA_LENGTH is 25 bits */ mmc->max_seg_size = mmc->max_req_size; - writel(0, host->base + MMCIMASK0); - writel(0x5e007ff, host->base + MMCICLEAR); /* Add: 1 << 25 */ + msmsdcc_writel(host, 0, MMCIMASK0); + msmsdcc_writel(host, 0x5e007ff, MMCICLEAR); - writel(MCI_IRQENABLE, host->base + MMCIMASK0); + msmsdcc_writel(host, MCI_IRQENABLE, MMCIMASK0); host->saved_irq0mask = MCI_IRQENABLE; /* @@ -1269,7 +1275,7 @@ msmsdcc_suspend(struct platform_device *dev, pm_message_t state) if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) rc = mmc_suspend_host(mmc, state); if (!rc) { - writel(0, host->base + MMCIMASK0); + msmsdcc_writel(host, 0, MMCIMASK0); if (host->clks_on) msmsdcc_enable_clocks(host, 0); @@ -1292,7 +1298,7 @@ msmsdcc_resume(struct platform_device *dev) if (!host->clks_on) msmsdcc_enable_clocks(host, 1); - writel(host->saved_irq0mask, host->base + MMCIMASK0); + msmsdcc_writel(host, host->saved_irq0mask, MMCIMASK0); spin_unlock_irqrestore(&host->lock, flags); -- cgit v1.2.3 From 51905dcbcf1f72a17f491c64485d513986110a6f Mon Sep 17 00:00:00 2001 From: San Mehat Date: Mon, 16 Nov 2009 11:59:01 -0800 Subject: mmc: msm_sdcc: Schedule clock disable after probe Signed-off-by: San Mehat Signed-off-by: Daniel Walker --- drivers/mmc/host/msm_sdcc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 3b096f64ec52..84b284e3a288 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -1242,6 +1242,8 @@ msmsdcc_probe(struct platform_device *pdev) if (host->timer.function) pr_info("%s: Polling status mode enabled\n", mmc_hostname(mmc)); + if (host->use_bustimer) + mod_timer(&host->busclk_timer, jiffies + HZ); return 0; cmd_irq_free: free_irq(cmd_irqres->start, host); -- cgit v1.2.3 From 56a8b5b8ae81bd766e527a0e5274a087c3c1109d Mon Sep 17 00:00:00 2001 From: San Mehat Date: Sat, 21 Nov 2009 12:29:46 -0800 Subject: mmc: msm_sdcc: Reduce command timeouts and improve reliability. Based on an original patch by Brent DeGraaf: "Previous versions of the SD driver were beset with excessive command timeouts. These timeouts were silent by default, but happened frequently, especially during heavy system activity and concurrent access of two or more SD devices. Worst case, these timeouts would occasionally hit at the end of a successful write, resulting in false failures that could adversely affect journaling file systems if timing was unfortunate. This update tightens the association and timing between dma transfers and the commands that trigger them by utilizing a new api implemented in the datamover. In addition, it also fixes a dma cache coherency issue that was exposed during testing of this fix that occasionally resulted in card corruption. Processing of results in the interrupt status routine was modified to process command results prior to data because overwritten command results were observed during testing since the data section can result in command issuances of its own. This change also eliminates the software command timeout, relying entirely on the hardware version, since the software timeout was found to cause problems of its own after extensive testing (having hardware timer and software timers addressing the same issue was found to cause a race condition under heavy system load)." This change originally added PROG_DONE handling, which has been split out into a separate patch. Also on our platform, the data mover driver maintains coherency to ensure API reliability, so the above mentioned cache corruption issue was not an issue for us. Signed-off-by: San Mehat Cc: Brian Swetland Change-Id: Ifbf17cfafb858106d73bf49af52b5161a265a484 Signed-off-by: San Mehat Signed-off-by: Daniel Walker --- drivers/mmc/host/msm_sdcc.c | 267 ++++++++++++++++++++++++-------------------- drivers/mmc/host/msm_sdcc.h | 14 ++- 2 files changed, 161 insertions(+), 120 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 84b284e3a288..524858597901 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -3,6 +3,7 @@ * * Copyright (C) 2007 Google Inc, * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. + * Copyright (C) 2009, Code Aurora Forum. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -47,6 +48,7 @@ #define DRIVER_NAME "msm-sdcc" +#define BUSCLK_TIMEOUT (HZ * 5) static unsigned int msmsdcc_fmin = 144000; static unsigned int msmsdcc_fmax = 50000000; static unsigned int msmsdcc_4bit = 1; @@ -106,8 +108,6 @@ msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, static void msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq) { - msmsdcc_writel(host, 0, MMCICOMMAND); - BUG_ON(host->curr.data); host->curr.mrq = NULL; @@ -119,7 +119,7 @@ msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq) mdelay(5); if (host->use_bustimer) - mod_timer(&host->busclk_timer, jiffies + HZ); + mod_timer(&host->busclk_timer, jiffies + BUSCLK_TIMEOUT); /* * Need to drop the host lock here; mmc_request_done may call * back into the driver... @@ -132,7 +132,6 @@ msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq) static void msmsdcc_stop_data(struct msmsdcc_host *host) { - msmsdcc_writel(host, 0, MMCIDATACTRL); host->curr.data = NULL; host->curr.got_dataend = host->curr.got_datablkend = 0; } @@ -153,6 +152,29 @@ uint32_t msmsdcc_fifo_addr(struct msmsdcc_host *host) return 0; } +static inline void +msmsdcc_start_command_exec(struct msmsdcc_host *host, u32 arg, u32 c) { + msmsdcc_writel(host, arg, MMCIARGUMENT); + msmsdcc_writel(host, c, MMCICOMMAND); +} + +static void +msmsdcc_dma_exec_func(struct msm_dmov_cmd *cmd) +{ + struct msmsdcc_host *host = (struct msmsdcc_host *)cmd->data; + + writel(host->cmd_timeout, host->base + MMCIDATATIMER); + writel((unsigned int)host->curr.xfer_size, host->base + MMCIDATALENGTH); + writel(host->cmd_pio_irqmask, host->base + MMCIMASK1); + writel(host->cmd_datactrl, host->base + MMCIDATACTRL); + + if (host->cmd_cmd) { + msmsdcc_start_command_exec(host, + (u32)host->cmd_cmd->arg, (u32)host->cmd_c); + } + host->dma.active = 1; +} + static void msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd, unsigned int result, @@ -165,6 +187,8 @@ msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd, struct mmc_request *mrq; spin_lock_irqsave(&host->lock, flags); + host->dma.active = 0; + mrq = host->curr.mrq; BUG_ON(!mrq); @@ -190,7 +214,6 @@ msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd, if (!mrq->data->error) mrq->data->error = -EIO; } - host->dma.busy = 0; dma_unmap_sg(mmc_dev(host->mmc), host->dma.sg, host->dma.num_ents, host->dma.dir); @@ -203,6 +226,7 @@ msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd, } host->dma.sg = NULL; + host->dma.busy = 0; if ((host->curr.got_dataend && host->curr.got_datablkend) || mrq->data->error) { @@ -262,6 +286,8 @@ static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data) host->dma.sg = data->sg; host->dma.num_ents = data->sg_len; + BUG_ON(host->dma.num_ents > NR_SG); /* Prevent memory corruption */ + nc = host->dma.nc; switch (host->pdev_id) { @@ -290,22 +316,15 @@ static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data) host->curr.user_pages = 0; - n = dma_map_sg(mmc_dev(host->mmc), host->dma.sg, - host->dma.num_ents, host->dma.dir); - - if (n != host->dma.num_ents) { - pr_err("%s: Unable to map in all sg elements\n", - mmc_hostname(host->mmc)); - host->dma.sg = NULL; - host->dma.num_ents = 0; - return -ENOMEM; - } - box = &nc->cmd[0]; for (i = 0; i < host->dma.num_ents; i++) { box->cmd = CMD_MODE_BOX; - if (i == (host->dma.num_ents - 1)) + /* Initialize sg dma address */ + sg->dma_address = page_to_dma(mmc_dev(host->mmc), sg_page(sg)) + + sg->offset; + + if (i == (host->dma.num_ents - 1)) box->cmd |= CMD_LC; rows = (sg_dma_len(sg) % MCI_FIFOSIZE) ? (sg_dma_len(sg) / MCI_FIFOSIZE) + 1 : @@ -343,13 +362,68 @@ static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data) host->dma.hdr.cmdptr = DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(host->dma.cmdptr_busaddr); host->dma.hdr.complete_func = msmsdcc_dma_complete_func; - host->dma.hdr.execute_func = NULL; + n = dma_map_sg(mmc_dev(host->mmc), host->dma.sg, + host->dma.num_ents, host->dma.dir); +/* dsb inside dma_map_sg will write nc out to mem as well */ + + if (n != host->dma.num_ents) { + printk(KERN_ERR "%s: Unable to map in all sg elements\n", + mmc_hostname(host->mmc)); + host->dma.sg = NULL; + host->dma.num_ents = 0; + return -ENOMEM; + } + + return 0; +} + +static int +snoop_cccr_abort(struct mmc_command *cmd) +{ + if ((cmd->opcode == 52) && + (cmd->arg & 0x80000000) && + (((cmd->arg >> 9) & 0x1ffff) == SDIO_CCCR_ABORT)) + return 1; return 0; } static void -msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data) +msmsdcc_start_command_deferred(struct msmsdcc_host *host, + struct mmc_command *cmd, u32 *c) +{ + *c |= (cmd->opcode | MCI_CPSM_ENABLE); + + if (cmd->flags & MMC_RSP_PRESENT) { + if (cmd->flags & MMC_RSP_136) + *c |= MCI_CPSM_LONGRSP; + *c |= MCI_CPSM_RESPONSE; + } + + if (/*interrupt*/0) + *c |= MCI_CPSM_INTERRUPT; + + if ((((cmd->opcode == 17) || (cmd->opcode == 18)) || + ((cmd->opcode == 24) || (cmd->opcode == 25))) || + (cmd->opcode == 53)) + *c |= MCI_CSPM_DATCMD; + + if (cmd == cmd->mrq->stop) + *c |= MCI_CSPM_MCIABORT; + + if (snoop_cccr_abort(cmd)) + *c |= MCI_CSPM_MCIABORT; + + if (host->curr.cmd != NULL) { + printk(KERN_ERR "%s: Overlapping command requests\n", + mmc_hostname(host->mmc)); + } + host->curr.cmd = cmd; +} + +static void +msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data, + struct mmc_command *cmd, u32 c) { unsigned int datactrl, timeout; unsigned long long clks; @@ -364,13 +438,6 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data) memset(&host->pio, 0, sizeof(host->pio)); - clks = (unsigned long long)data->timeout_ns * host->clk_rate; - do_div(clks, NSEC_PER_SEC); - timeout = data->timeout_clks + (unsigned int)clks; - msmsdcc_writel(host, timeout, MMCIDATATIMER); - - msmsdcc_writel(host, host->curr.xfer_size, MMCIDATALENGTH); - datactrl = MCI_DPSM_ENABLE | (data->blksz << 4); if (!msmsdcc_config_dma(host, data)) @@ -391,56 +458,51 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data) if (data->flags & MMC_DATA_READ) datactrl |= MCI_DPSM_DIRECTION; - msmsdcc_writel(host, pio_irqmask, MMCIMASK1); - msmsdcc_writel(host, datactrl, MMCIDATACTRL); + clks = (unsigned long long)data->timeout_ns * host->clk_rate; + do_div(clks, NSEC_PER_SEC); + timeout = data->timeout_clks + (unsigned int)clks*2 ; if (datactrl & MCI_DPSM_DMAENABLE) { + /* Save parameters for the exec function */ + host->cmd_timeout = timeout; + host->cmd_pio_irqmask = pio_irqmask; + host->cmd_datactrl = datactrl; + host->cmd_cmd = cmd; + + host->dma.hdr.execute_func = msmsdcc_dma_exec_func; + host->dma.hdr.data = (void *)host; host->dma.busy = 1; + + if (cmd) { + msmsdcc_start_command_deferred(host, cmd, &c); + host->cmd_c = c; + } msm_dmov_enqueue_cmd(host->dma.channel, &host->dma.hdr); - } -} + } else { + msmsdcc_writel(host, timeout, MMCIDATATIMER); -static int -snoop_cccr_abort(struct mmc_command *cmd) -{ - if ((cmd->opcode == 52) && - (cmd->arg & 0x80000000) && - (((cmd->arg >> 9) & 0x1ffff) == SDIO_CCCR_ABORT)) - return 1; - return 0; + msmsdcc_writel(host, host->curr.xfer_size, MMCIDATALENGTH); + + msmsdcc_writel(host, pio_irqmask, MMCIMASK1); + msmsdcc_writel(host, datactrl, MMCIDATACTRL); + + if (cmd) { + /* Daisy-chain the command if requested */ + msmsdcc_start_command(host, cmd, c); + } + } } static void msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, u32 c) { - if (msmsdcc_readl(host, MMCICOMMAND) & MCI_CPSM_ENABLE) - msmsdcc_writel(host, 0, MMCICOMMAND); - - c |= cmd->opcode | MCI_CPSM_ENABLE; - - if (cmd->flags & MMC_RSP_PRESENT) { - if (cmd->flags & MMC_RSP_136) - c |= MCI_CPSM_LONGRSP; - c |= MCI_CPSM_RESPONSE; - } - - if (cmd->opcode == 17 || cmd->opcode == 18 || - cmd->opcode == 24 || cmd->opcode == 25 || - cmd->opcode == 53) - c |= MCI_CSPM_DATCMD; - if (cmd == cmd->mrq->stop) c |= MCI_CSPM_MCIABORT; - if (snoop_cccr_abort(cmd)) - c |= MCI_CSPM_MCIABORT; - - host->curr.cmd = cmd; - host->stats.cmds++; - msmsdcc_writel(host, cmd->arg, MMCIARGUMENT); - msmsdcc_writel(host, c, MMCICOMMAND); + msmsdcc_start_command_deferred(host, cmd, &c); + msmsdcc_start_command_exec(host, cmd->arg, c); } static void @@ -611,7 +673,6 @@ static void msmsdcc_do_cmdirq(struct msmsdcc_host *host, uint32_t status) cmd->resp[2] = msmsdcc_readl(host, MMCIRESPONSE2); cmd->resp[3] = msmsdcc_readl(host, MMCIRESPONSE3); - del_timer(&host->command_timer); if (status & MCI_CMDTIMEOUT) { cmd->error = -ETIMEDOUT; } else if (status & MCI_CMDCRCFAIL && @@ -629,16 +690,24 @@ static void msmsdcc_do_cmdirq(struct msmsdcc_host *host, uint32_t status) msmsdcc_request_end(host, cmd->mrq); } else /* host->data == NULL */ msmsdcc_request_end(host, cmd->mrq); - } else if (!(cmd->data->flags & MMC_DATA_READ)) - msmsdcc_start_data(host, cmd->data); + } else if (cmd->data) + if (!(cmd->data->flags & MMC_DATA_READ)) + msmsdcc_start_data(host, cmd->data, + NULL, 0); } static void msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status, void __iomem *base) { - struct mmc_data *data = host->curr.data; + struct mmc_data *data; + if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL | + MCI_CMDTIMEOUT) && host->curr.cmd) { + msmsdcc_do_cmdirq(host, status); + } + + data = host->curr.data; if (!data) return; @@ -720,11 +789,6 @@ msmsdcc_irq(int irq, void *dev_id) msmsdcc_handle_irq_data(host, status, base); - if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL | - MCI_CMDTIMEOUT) && host->curr.cmd) { - msmsdcc_do_cmdirq(host, status); - } - if (status & MCI_SDIOINTOPER) { cardint = 1; status &= ~MCI_SDIOINTOPER; @@ -775,9 +839,10 @@ msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq) msmsdcc_enable_clocks(host, 1); if (mrq->data && mrq->data->flags & MMC_DATA_READ) - msmsdcc_start_data(host, mrq->data); - - msmsdcc_start_command(host, mrq->cmd, 0); + /* Queue/read data, daisy-chain command when data starts */ + msmsdcc_start_data(host, mrq->data, mrq->cmd, 0); + else + msmsdcc_start_command(host, mrq->cmd, 0); if (host->cmdpoll && !msmsdcc_spin_on_status(host, MCI_CMDRESPEND|MCI_CMDCRCFAIL|MCI_CMDTIMEOUT, @@ -790,7 +855,6 @@ msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq) host->stats.cmdpoll_hits++; } else { host->stats.cmdpoll_misses++; - mod_timer(&host->command_timer, jiffies + HZ); } spin_unlock_irqrestore(&host->lock, flags); } @@ -943,42 +1007,6 @@ msmsdcc_busclk_expired(unsigned long _data) spin_unlock_irqrestore(&host->lock, flags); } -/* - * called when a command expires. - * Dump some debugging, and then error - * out the transaction. - */ -static void -msmsdcc_command_expired(unsigned long _data) -{ - struct msmsdcc_host *host = (struct msmsdcc_host *) _data; - struct mmc_request *mrq; - unsigned long flags; - - spin_lock_irqsave(&host->lock, flags); - mrq = host->curr.mrq; - - if (!mrq) { - spin_unlock_irqrestore(&host->lock, flags); - return; - } - - pr_err("%s: Controller lockup detected\n", - mmc_hostname(host->mmc)); - mrq->cmd->error = -ETIMEDOUT; - msmsdcc_stop_data(host); - - msmsdcc_writel(host, 0, MMCICOMMAND); - - host->curr.mrq = NULL; - host->curr.cmd = NULL; - - if (host->clks_on) - msmsdcc_enable_clocks(host, 0); - spin_unlock_irqrestore(&host->lock, flags); - mmc_request_done(host->mmc, mrq); -} - static int msmsdcc_init_dma(struct msmsdcc_host *host) { @@ -1078,6 +1106,7 @@ msmsdcc_probe(struct platform_device *pdev) host->pdev_id = pdev->id; host->plat = plat; host->mmc = mmc; + host->curr.cmd = NULL; host->cmdpoll = 1; @@ -1194,14 +1223,6 @@ msmsdcc_probe(struct platform_device *pdev) host->eject = !host->oldstat; } - /* - * Setup a command timer. We currently need this due to - * some 'strange' timeout / error handling situations. - */ - init_timer(&host->command_timer); - host->command_timer.data = (unsigned long) host; - host->command_timer.function = msmsdcc_command_expired; - init_timer(&host->busclk_timer); host->busclk_timer.data = (unsigned long) host; host->busclk_timer.function = msmsdcc_busclk_expired; @@ -1243,7 +1264,7 @@ msmsdcc_probe(struct platform_device *pdev) pr_info("%s: Polling status mode enabled\n", mmc_hostname(mmc)); if (host->use_bustimer) - mod_timer(&host->busclk_timer, jiffies + HZ); + mod_timer(&host->busclk_timer, jiffies + BUSCLK_TIMEOUT); return 0; cmd_irq_free: free_irq(cmd_irqres->start, host); @@ -1267,10 +1288,14 @@ msmsdcc_suspend(struct platform_device *dev, pm_message_t state) { struct mmc_host *mmc = mmc_get_drvdata(dev); int rc = 0; + unsigned long flags; if (mmc) { struct msmsdcc_host *host = mmc_priv(mmc); + if (host->use_bustimer) + del_timer_sync(&host->busclk_timer); + spin_lock_irqsave(&host->lock, flags); if (host->stat_irq) disable_irq(host->stat_irq); @@ -1282,6 +1307,7 @@ msmsdcc_suspend(struct platform_device *dev, pm_message_t state) if (host->clks_on) msmsdcc_enable_clocks(host, 0); } + spin_unlock_irqrestore(&host->lock, flags); } return rc; } @@ -1300,6 +1326,9 @@ msmsdcc_resume(struct platform_device *dev) if (!host->clks_on) msmsdcc_enable_clocks(host, 1); + if (host->use_bustimer) + mod_timer(&host->busclk_timer, jiffies + BUSCLK_TIMEOUT); + msmsdcc_writel(host, host->saved_irq0mask, MMCIMASK0); spin_unlock_irqrestore(&host->lock, flags); diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h index 6846bd7dff22..361cb6efd248 100644 --- a/drivers/mmc/host/msm_sdcc.h +++ b/drivers/mmc/host/msm_sdcc.h @@ -171,6 +171,7 @@ struct msmsdcc_dma_data { int channel; struct msmsdcc_host *host; int busy; /* Set if DM is busy */ + int active; }; struct msmsdcc_pio_data { @@ -213,7 +214,6 @@ struct msmsdcc_host { struct clk *clk; /* main MMC bus clock */ struct clk *pclk; /* SDCC peripheral bus clock */ unsigned int clks_on; /* set if clocks are enabled */ - struct timer_list command_timer; struct timer_list busclk_timer; int use_bustimer; @@ -235,6 +235,18 @@ struct msmsdcc_host { struct msmsdcc_pio_data pio; int cmdpoll; struct msmsdcc_stats stats; + +#ifdef CONFIG_MMC_MSM7X00A_RESUME_IN_WQ + struct work_struct resume_task; +#endif + + /* Command parameters */ + unsigned int cmd_timeout; + unsigned int cmd_pio_irqmask; + unsigned int cmd_datactrl; + struct mmc_command *cmd_cmd; + u32 cmd_c; + }; #endif -- cgit v1.2.3 From c7fc9370df1433486dfa9460a833fae664e8be6c Mon Sep 17 00:00:00 2001 From: San Mehat Date: Sun, 22 Nov 2009 17:19:07 -0800 Subject: mmc: msm_sdcc: Fix bug where busclk expiry timer was not properly disabled Signed-off-by: San Mehat Signed-off-by: Daniel Walker --- drivers/mmc/host/msm_sdcc.c | 99 ++++++++++++++++++++++++--------------------- drivers/mmc/host/msm_sdcc.h | 1 - 2 files changed, 52 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 524858597901..591ef3c4e9a7 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -48,7 +48,7 @@ #define DRIVER_NAME "msm-sdcc" -#define BUSCLK_TIMEOUT (HZ * 5) +#define BUSCLK_TIMEOUT (HZ) static unsigned int msmsdcc_fmin = 144000; static unsigned int msmsdcc_fmax = 50000000; static unsigned int msmsdcc_4bit = 1; @@ -60,29 +60,42 @@ static unsigned int msmsdcc_sdioirq; #define CMD_SPINMAX 20 -static inline int -msmsdcc_enable_clocks(struct msmsdcc_host *host, int enable) +static inline void +msmsdcc_disable_clocks(struct msmsdcc_host *host, int deferr) { - int rc; + WARN_ON(!host->clks_on); - WARN_ON(enable == host->clks_on); - if (enable) { - rc = clk_enable(host->pclk); - if (rc) - return rc; - rc = clk_enable(host->clk); - if (rc) { - clk_disable(host->pclk); - return rc; - } - udelay(1 + ((3 * USEC_PER_SEC) / - (host->clk_rate ? host->clk_rate : msmsdcc_fmin))); - host->clks_on = 1; + if (deferr) { + mod_timer(&host->busclk_timer, jiffies + BUSCLK_TIMEOUT); } else { + del_timer_sync(&host->busclk_timer); +// dev_info(mmc_dev(host->mmc), "Immediate clock shutdown\n"); clk_disable(host->clk); clk_disable(host->pclk); host->clks_on = 0; } +} + +static inline int +msmsdcc_enable_clocks(struct msmsdcc_host *host) +{ + int rc; + + WARN_ON(host->clks_on); + + del_timer_sync(&host->busclk_timer); + + rc = clk_enable(host->pclk); + if (rc) + return rc; + rc = clk_enable(host->clk); + if (rc) { + clk_disable(host->pclk); + return rc; + } + udelay(1 + ((3 * USEC_PER_SEC) / + (host->clk_rate ? host->clk_rate : msmsdcc_fmin))); + host->clks_on = 1; return 0; } @@ -118,8 +131,7 @@ msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq) if (mrq->cmd->error == -ETIMEDOUT) mdelay(5); - if (host->use_bustimer) - mod_timer(&host->busclk_timer, jiffies + BUSCLK_TIMEOUT); + msmsdcc_disable_clocks(host, 1); /* * Need to drop the host lock here; mmc_request_done may call * back into the driver... @@ -240,12 +252,12 @@ msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd, if (!mrq->data->error) host->curr.data_xfered = host->curr.xfer_size; if (!mrq->data->stop || mrq->cmd->error) { - msmsdcc_writel(host, 0, MMCICOMMAND); host->curr.mrq = NULL; host->curr.cmd = NULL; mrq->data->bytes_xfered = host->curr.data_xfered; spin_unlock_irqrestore(&host->lock, flags); + msmsdcc_disable_clocks(host, 1); mmc_request_done(host->mmc, mrq); return; } else @@ -835,8 +847,14 @@ msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq) } host->curr.mrq = mrq; + + /* Need to drop the host lock here in case + * the busclk wd fires + */ + spin_unlock_irqrestore(&host->lock, flags); if (!host->clks_on) - msmsdcc_enable_clocks(host, 1); + msmsdcc_enable_clocks(host); + spin_lock_irqsave(&host->lock, flags); if (mrq->data && mrq->data->flags & MMC_DATA_READ) /* Queue/read data, daisy-chain command when data starts */ @@ -867,9 +885,10 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) int rc; unsigned long flags; - spin_lock_irqsave(&host->lock, flags); if (!host->clks_on) - msmsdcc_enable_clocks(host, 1); + msmsdcc_enable_clocks(host); + + spin_lock_irqsave(&host->lock, flags); if (ios->clock) { if (ios->clock != host->clk_rate) { @@ -915,8 +934,7 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) host->pwr = pwr; msmsdcc_writel(host, pwr, MMCIPOWER); } - if (host->clks_on) - msmsdcc_enable_clocks(host, 0); + msmsdcc_disable_clocks(host, 1); spin_unlock_irqrestore(&host->lock, flags); } @@ -1001,9 +1019,9 @@ msmsdcc_busclk_expired(unsigned long _data) unsigned long flags; spin_lock_irqsave(&host->lock, flags); + dev_info(mmc_dev(host->mmc), "Bus clock timer expired\n"); if (host->clks_on) - msmsdcc_enable_clocks(host, 0); - + msmsdcc_disable_clocks(host, 0); spin_unlock_irqrestore(&host->lock, flags); } @@ -1110,8 +1128,6 @@ msmsdcc_probe(struct platform_device *pdev) host->cmdpoll = 1; - host->use_bustimer = 1; - host->base = ioremap(memres->start, PAGE_SIZE); if (!host->base) { ret = -ENOMEM; @@ -1143,7 +1159,7 @@ msmsdcc_probe(struct platform_device *pdev) } /* Enable clocks */ - ret = msmsdcc_enable_clocks(host, 1); + ret = msmsdcc_enable_clocks(host); if (ret) goto clk_put; @@ -1263,8 +1279,7 @@ msmsdcc_probe(struct platform_device *pdev) if (host->timer.function) pr_info("%s: Polling status mode enabled\n", mmc_hostname(mmc)); - if (host->use_bustimer) - mod_timer(&host->busclk_timer, jiffies + BUSCLK_TIMEOUT); + msmsdcc_disable_clocks(host, 1); return 0; cmd_irq_free: free_irq(cmd_irqres->start, host); @@ -1272,7 +1287,7 @@ msmsdcc_probe(struct platform_device *pdev) if (host->stat_irq) free_irq(host->stat_irq, host); clk_disable: - msmsdcc_enable_clocks(host, 0); + msmsdcc_disable_clocks(host, 0); clk_put: clk_put(host->clk); pclk_put: @@ -1293,8 +1308,6 @@ msmsdcc_suspend(struct platform_device *dev, pm_message_t state) if (mmc) { struct msmsdcc_host *host = mmc_priv(mmc); - if (host->use_bustimer) - del_timer_sync(&host->busclk_timer); spin_lock_irqsave(&host->lock, flags); if (host->stat_irq) disable_irq(host->stat_irq); @@ -1304,10 +1317,10 @@ msmsdcc_suspend(struct platform_device *dev, pm_message_t state) if (!rc) { msmsdcc_writel(host, 0, MMCIMASK0); - if (host->clks_on) - msmsdcc_enable_clocks(host, 0); } spin_unlock_irqrestore(&host->lock, flags); + if (host->clks_on) + msmsdcc_disable_clocks(host, 0); } return rc; } @@ -1316,27 +1329,19 @@ static int msmsdcc_resume(struct platform_device *dev) { struct mmc_host *mmc = mmc_get_drvdata(dev); - unsigned long flags; if (mmc) { struct msmsdcc_host *host = mmc_priv(mmc); - spin_lock_irqsave(&host->lock, flags); - - if (!host->clks_on) - msmsdcc_enable_clocks(host, 1); - - if (host->use_bustimer) - mod_timer(&host->busclk_timer, jiffies + BUSCLK_TIMEOUT); + msmsdcc_enable_clocks(host); msmsdcc_writel(host, host->saved_irq0mask, MMCIMASK0); - spin_unlock_irqrestore(&host->lock, flags); - if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) mmc_resume_host(mmc); if (host->stat_irq) enable_irq(host->stat_irq); + msmsdcc_disable_clocks(host, 1); } return 0; } diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h index 361cb6efd248..da0039c9285e 100644 --- a/drivers/mmc/host/msm_sdcc.h +++ b/drivers/mmc/host/msm_sdcc.h @@ -215,7 +215,6 @@ struct msmsdcc_host { struct clk *pclk; /* SDCC peripheral bus clock */ unsigned int clks_on; /* set if clocks are enabled */ struct timer_list busclk_timer; - int use_bustimer; unsigned int eject; /* eject state */ -- cgit v1.2.3 From f4748499d3dc5e7cadecb977f0d4f1f4f4a8d8c5 Mon Sep 17 00:00:00 2001 From: San Mehat Date: Mon, 23 Nov 2009 15:36:31 -0800 Subject: mmc: msm_sdcc: Featurize busclock power save and disable it by default Signed-off-by: San Mehat Signed-off-by: Daniel Walker --- drivers/mmc/host/msm_sdcc.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 591ef3c4e9a7..bdafb642a713 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -48,6 +48,7 @@ #define DRIVER_NAME "msm-sdcc" +#define BUSCLK_PWRSAVE 0 #define BUSCLK_TIMEOUT (HZ) static unsigned int msmsdcc_fmin = 144000; static unsigned int msmsdcc_fmax = 50000000; @@ -65,6 +66,8 @@ msmsdcc_disable_clocks(struct msmsdcc_host *host, int deferr) { WARN_ON(!host->clks_on); + BUG_ON(host->curr.mrq); + if (deferr) { mod_timer(&host->busclk_timer, jiffies + BUSCLK_TIMEOUT); } else { @@ -131,7 +134,9 @@ msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq) if (mrq->cmd->error == -ETIMEDOUT) mdelay(5); +#if BUSCLK_PWRSAVE msmsdcc_disable_clocks(host, 1); +#endif /* * Need to drop the host lock here; mmc_request_done may call * back into the driver... @@ -257,7 +262,9 @@ msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd, mrq->data->bytes_xfered = host->curr.data_xfered; spin_unlock_irqrestore(&host->lock, flags); +#if BUSCLK_PWRSAVE msmsdcc_disable_clocks(host, 1); +#endif mmc_request_done(host->mmc, mrq); return; } else @@ -934,7 +941,9 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) host->pwr = pwr; msmsdcc_writel(host, pwr, MMCIPOWER); } +#if BUSCLK_PWRSAVE msmsdcc_disable_clocks(host, 1); +#endif spin_unlock_irqrestore(&host->lock, flags); } @@ -1279,7 +1288,9 @@ msmsdcc_probe(struct platform_device *pdev) if (host->timer.function) pr_info("%s: Polling status mode enabled\n", mmc_hostname(mmc)); +#if BUSCLK_PWRSAVE msmsdcc_disable_clocks(host, 1); +#endif return 0; cmd_irq_free: free_irq(cmd_irqres->start, host); @@ -1341,7 +1352,9 @@ msmsdcc_resume(struct platform_device *dev) mmc_resume_host(mmc); if (host->stat_irq) enable_irq(host->stat_irq); +#if BUSCLK_PWRSAVE msmsdcc_disable_clocks(host, 1); +#endif } return 0; } -- cgit v1.2.3 From b3b0ca84cfec581fba3ea8efaa8052cb5e6fc857 Mon Sep 17 00:00:00 2001 From: San Mehat Date: Tue, 24 Nov 2009 12:24:55 -0800 Subject: mmc: msm_sdcc: Fix issue where we might not end a sucessfull request Signed-off-by: San Mehat Signed-off-by: Daniel Walker --- drivers/mmc/host/msm_sdcc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index bdafb642a713..3ea66971edfc 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -208,6 +208,7 @@ msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd, mrq = host->curr.mrq; BUG_ON(!mrq); + WARN_ON(!mrq->data); if (!(result & DMOV_RSLT_VALID)) { pr_err("msmsdcc: Invalid DataMover result\n"); @@ -719,14 +720,13 @@ static void msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status, void __iomem *base) { - struct mmc_data *data; + struct mmc_data *data = host->curr.data; if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL | MCI_CMDTIMEOUT) && host->curr.cmd) { msmsdcc_do_cmdirq(host, status); } - data = host->curr.data; if (!data) return; @@ -739,7 +739,8 @@ msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status, msm_dmov_stop_cmd(host->dma.channel, &host->dma.hdr, 0); else { - msmsdcc_stop_data(host); + if (host->curr.data) + msmsdcc_stop_data(host); if (!data->stop) msmsdcc_request_end(host, data->mrq); else -- cgit v1.2.3 From 673ce00d7cb4ec060b5091992959da4a1d91c634 Mon Sep 17 00:00:00 2001 From: San Mehat Date: Wed, 25 Nov 2009 11:16:57 -0800 Subject: mmc: msm_sdcc: Don't disable interrupts while suspending Signed-off-by: San Mehat Signed-off-by: Daniel Walker --- drivers/mmc/host/msm_sdcc.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 3ea66971edfc..6e50939b6f88 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -1315,12 +1315,10 @@ msmsdcc_suspend(struct platform_device *dev, pm_message_t state) { struct mmc_host *mmc = mmc_get_drvdata(dev); int rc = 0; - unsigned long flags; if (mmc) { struct msmsdcc_host *host = mmc_priv(mmc); - spin_lock_irqsave(&host->lock, flags); if (host->stat_irq) disable_irq(host->stat_irq); @@ -1330,7 +1328,6 @@ msmsdcc_suspend(struct platform_device *dev, pm_message_t state) msmsdcc_writel(host, 0, MMCIMASK0); } - spin_unlock_irqrestore(&host->lock, flags); if (host->clks_on) msmsdcc_disable_clocks(host, 0); } -- cgit v1.2.3 From 24bbd7d5b422cde6a149ac2f9ac6e61e66536532 Mon Sep 17 00:00:00 2001 From: San Mehat Date: Tue, 1 Dec 2009 10:10:47 -0800 Subject: mmc: msm_sdcc: Enable busclk idle timer for power savings Signed-off-by: San Mehat Signed-off-by: Daniel Walker --- drivers/mmc/host/msm_sdcc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 6e50939b6f88..d42a2dd69325 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -48,7 +48,7 @@ #define DRIVER_NAME "msm-sdcc" -#define BUSCLK_PWRSAVE 0 +#define BUSCLK_PWRSAVE 1 #define BUSCLK_TIMEOUT (HZ) static unsigned int msmsdcc_fmin = 144000; static unsigned int msmsdcc_fmax = 50000000; @@ -72,7 +72,6 @@ msmsdcc_disable_clocks(struct msmsdcc_host *host, int deferr) mod_timer(&host->busclk_timer, jiffies + BUSCLK_TIMEOUT); } else { del_timer_sync(&host->busclk_timer); -// dev_info(mmc_dev(host->mmc), "Immediate clock shutdown\n"); clk_disable(host->clk); clk_disable(host->pclk); host->clks_on = 0; -- cgit v1.2.3 From 91bb64952a8c57826b01878925bea8831c71a492 Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Wed, 2 Dec 2009 17:21:07 -0800 Subject: mmc: msm_sdcc: Don't set host->curr.mrq until after we're sure the busclk timer won't fire Signed-off-by: San Mehat Signed-off-by: Daniel Walker --- drivers/mmc/host/msm_sdcc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index d42a2dd69325..28899ee392e2 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -853,8 +853,6 @@ msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq) return; } - host->curr.mrq = mrq; - /* Need to drop the host lock here in case * the busclk wd fires */ @@ -863,6 +861,8 @@ msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq) msmsdcc_enable_clocks(host); spin_lock_irqsave(&host->lock, flags); + host->curr.mrq = mrq; + if (mrq->data && mrq->data->flags & MMC_DATA_READ) /* Queue/read data, daisy-chain command when data starts */ msmsdcc_start_data(host, mrq->data, mrq->cmd, 0); -- cgit v1.2.3 From 6ac9ea69069804d357064357d0082b0eab4c87ce Mon Sep 17 00:00:00 2001 From: San Mehat Date: Wed, 2 Dec 2009 17:24:58 -0800 Subject: mmc: msm_sdcc: Fix the dma exec function to use the proper delays Signed-off-by: San Mehat Signed-off-by: Daniel Walker --- drivers/mmc/host/msm_sdcc.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 28899ee392e2..8329fd650c5f 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -177,17 +177,18 @@ msmsdcc_start_command_exec(struct msmsdcc_host *host, u32 arg, u32 c) { static void msmsdcc_dma_exec_func(struct msm_dmov_cmd *cmd) { - struct msmsdcc_host *host = (struct msmsdcc_host *)cmd->data; + struct msmsdcc_host *host = (struct msmsdcc_host *)cmd->data; - writel(host->cmd_timeout, host->base + MMCIDATATIMER); - writel((unsigned int)host->curr.xfer_size, host->base + MMCIDATALENGTH); - writel(host->cmd_pio_irqmask, host->base + MMCIMASK1); - writel(host->cmd_datactrl, host->base + MMCIDATACTRL); + msmsdcc_writel(host, host->cmd_timeout, MMCIDATATIMER); + msmsdcc_writel(host, (unsigned int)host->curr.xfer_size, MMCIDATALENGTH); + msmsdcc_writel(host, host->cmd_pio_irqmask, MMCIMASK1); + msmsdcc_writel(host, host->cmd_datactrl, MMCIDATACTRL); - if (host->cmd_cmd) { - msmsdcc_start_command_exec(host, - (u32)host->cmd_cmd->arg, (u32)host->cmd_c); - } + if (host->cmd_cmd) { + msmsdcc_start_command_exec(host, + (u32) host->cmd_cmd->arg, + (u32) host->cmd_c); + } host->dma.active = 1; } -- cgit v1.2.3 From d0719e59f4ad96616f7c02ef0201667e41778c88 Mon Sep 17 00:00:00 2001 From: San Mehat Date: Thu, 3 Dec 2009 10:58:54 -0800 Subject: mmc: msm_sdcc: Fix issue where clocks could be disabled mid transaction msmsdcc_enable_clocks() was incorrectly being called depending on the state of host->clks_on. This means the busclk idle timer was never being deleted if the clock was already on.. Bogus. Also fixes a possible double clk disable if the call to del_timer_sync() in msmsdcc_disable_clocks() raced with the busclk timer. Signed-off-by: San Mehat Signed-off-by: Daniel Walker --- drivers/mmc/host/msm_sdcc.c | 61 ++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 8329fd650c5f..47b1f2526521 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -61,7 +61,7 @@ static unsigned int msmsdcc_sdioirq; #define CMD_SPINMAX 20 -static inline void +static inline void msmsdcc_disable_clocks(struct msmsdcc_host *host, int deferr) { WARN_ON(!host->clks_on); @@ -72,9 +72,14 @@ msmsdcc_disable_clocks(struct msmsdcc_host *host, int deferr) mod_timer(&host->busclk_timer, jiffies + BUSCLK_TIMEOUT); } else { del_timer_sync(&host->busclk_timer); - clk_disable(host->clk); - clk_disable(host->pclk); - host->clks_on = 0; + /* Need to check clks_on again in case the busclk + * timer fired + */ + if (host->clks_on) { + clk_disable(host->clk); + clk_disable(host->pclk); + host->clks_on = 0; + } } } @@ -83,21 +88,21 @@ msmsdcc_enable_clocks(struct msmsdcc_host *host) { int rc; - WARN_ON(host->clks_on); - del_timer_sync(&host->busclk_timer); - rc = clk_enable(host->pclk); - if (rc) - return rc; - rc = clk_enable(host->clk); - if (rc) { - clk_disable(host->pclk); - return rc; + if (!host->clks_on) { + rc = clk_enable(host->pclk); + if (rc) + return rc; + rc = clk_enable(host->clk); + if (rc) { + clk_disable(host->pclk); + return rc; + } + udelay(1 + ((3 * USEC_PER_SEC) / + (host->clk_rate ? host->clk_rate : msmsdcc_fmin))); + host->clks_on = 1; } - udelay(1 + ((3 * USEC_PER_SEC) / - (host->clk_rate ? host->clk_rate : msmsdcc_fmin))); - host->clks_on = 1; return 0; } @@ -180,7 +185,8 @@ msmsdcc_dma_exec_func(struct msm_dmov_cmd *cmd) struct msmsdcc_host *host = (struct msmsdcc_host *)cmd->data; msmsdcc_writel(host, host->cmd_timeout, MMCIDATATIMER); - msmsdcc_writel(host, (unsigned int)host->curr.xfer_size, MMCIDATALENGTH); + msmsdcc_writel(host, (unsigned int)host->curr.xfer_size, + MMCIDATALENGTH); msmsdcc_writel(host, host->cmd_pio_irqmask, MMCIMASK1); msmsdcc_writel(host, host->cmd_datactrl, MMCIDATACTRL); @@ -854,13 +860,7 @@ msmsdcc_request(struct mmc_host *mmc, struct mmc_request *mrq) return; } - /* Need to drop the host lock here in case - * the busclk wd fires - */ - spin_unlock_irqrestore(&host->lock, flags); - if (!host->clks_on) - msmsdcc_enable_clocks(host); - spin_lock_irqsave(&host->lock, flags); + msmsdcc_enable_clocks(host); host->curr.mrq = mrq; @@ -893,11 +893,10 @@ msmsdcc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) int rc; unsigned long flags; - if (!host->clks_on) - msmsdcc_enable_clocks(host); - spin_lock_irqsave(&host->lock, flags); + msmsdcc_enable_clocks(host); + if (ios->clock) { if (ios->clock != host->clk_rate) { rc = clk_set_rate(host->clk, ios->clock); @@ -1026,13 +1025,9 @@ static void msmsdcc_busclk_expired(unsigned long _data) { struct msmsdcc_host *host = (struct msmsdcc_host *) _data; - unsigned long flags; - spin_lock_irqsave(&host->lock, flags); - dev_info(mmc_dev(host->mmc), "Bus clock timer expired\n"); if (host->clks_on) msmsdcc_disable_clocks(host, 0); - spin_unlock_irqrestore(&host->lock, flags); } static int @@ -1324,10 +1319,8 @@ msmsdcc_suspend(struct platform_device *dev, pm_message_t state) if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) rc = mmc_suspend_host(mmc, state); - if (!rc) { + if (!rc) msmsdcc_writel(host, 0, MMCIMASK0); - - } if (host->clks_on) msmsdcc_disable_clocks(host, 0); } -- cgit v1.2.3 From 1cd2296909e77702c68021ede9d87a1d967a6a99 Mon Sep 17 00:00:00 2001 From: San Mehat Date: Wed, 3 Feb 2010 12:59:29 -0800 Subject: drivers: mmc: msm_sdcc: Add EMBEDDED_SDIO support Signed-off-by: Dmitry Shmidt Signed-off-by: Daniel Walker --- drivers/mmc/host/msm_sdcc.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 47b1f2526521..b40558e18e87 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -616,7 +616,7 @@ msmsdcc_spin_on_status(struct msmsdcc_host *host, uint32_t mask, int maxspin) return -ETIMEDOUT; } -static int +static irqreturn_t msmsdcc_pio_irq(int irq, void *dev_id) { struct msmsdcc_host *host = dev_id; @@ -801,7 +801,6 @@ msmsdcc_irq(int irq, void *dev_id) spin_lock(&host->lock); do { - struct mmc_data *data; status = msmsdcc_readl(host, MMCISTATUS); status &= (msmsdcc_readl(host, MMCIMASK0) | MCI_DATABLOCKENDMASK); @@ -1145,6 +1144,15 @@ msmsdcc_probe(struct platform_device *pdev) host->dmares = dmares; spin_lock_init(&host->lock); +#ifdef CONFIG_MMC_EMBEDDED_SDIO + if (plat->embedded_sdio) + mmc_set_embedded_sdio_data(mmc, + &plat->embedded_sdio->cis, + &plat->embedded_sdio->cccr, + plat->embedded_sdio->funcs, + plat->embedded_sdio->num_funcs); +#endif + /* * Setup DMA */ -- cgit v1.2.3 From cecd87da83869ad4157295b87a2e51e38c3e03bf Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 4 Mar 2010 14:31:47 +0100 Subject: DMAENGINE: COH 901 318 rename confusing vars This fixes up the code with a lot of comments that make it readable, rename things with opaque names like "data" into something more appropriate, and remove some very confusing BUG() statements. Signed-off-by: Linus Walleij Signed-off-by: Dan Williams --- drivers/dma/coh901318.c | 103 ++++++++++++++++++++++++++++++------------------ 1 file changed, 65 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index 1656fdcdb6c2..20889c98e9b0 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -37,7 +37,7 @@ struct coh901318_desc { struct list_head node; struct scatterlist *sg; unsigned int sg_len; - struct coh901318_lli *data; + struct coh901318_lli *lli; enum dma_data_direction dir; unsigned long flags; }; @@ -283,7 +283,7 @@ static int coh901318_start(struct coh901318_chan *cohc) } static int coh901318_prep_linked_list(struct coh901318_chan *cohc, - struct coh901318_lli *data) + struct coh901318_lli *lli) { int channel = cohc->id; void __iomem *virtbase = cohc->base->virtbase; @@ -292,18 +292,18 @@ static int coh901318_prep_linked_list(struct coh901318_chan *cohc, COH901318_CX_STAT_SPACING*channel) & COH901318_CX_STAT_ACTIVE); - writel(data->src_addr, + writel(lli->src_addr, virtbase + COH901318_CX_SRC_ADDR + COH901318_CX_SRC_ADDR_SPACING * channel); - writel(data->dst_addr, virtbase + + writel(lli->dst_addr, virtbase + COH901318_CX_DST_ADDR + COH901318_CX_DST_ADDR_SPACING * channel); - writel(data->link_addr, virtbase + COH901318_CX_LNK_ADDR + + writel(lli->link_addr, virtbase + COH901318_CX_LNK_ADDR + COH901318_CX_LNK_ADDR_SPACING * channel); - writel(data->control, virtbase + COH901318_CX_CTRL + + writel(lli->control, virtbase + COH901318_CX_CTRL + COH901318_CX_CTRL_SPACING * channel); return 0; @@ -565,29 +565,30 @@ static int coh901318_config(struct coh901318_chan *cohc, */ static struct coh901318_desc *coh901318_queue_start(struct coh901318_chan *cohc) { - struct coh901318_desc *cohd_que; + struct coh901318_desc *cohd; - /* start queued jobs, if any + /* + * start queued jobs, if any * TODO: transmit all queued jobs in one go */ - cohd_que = coh901318_first_queued(cohc); + cohd = coh901318_first_queued(cohc); - if (cohd_que != NULL) { + if (cohd != NULL) { /* Remove from queue */ - coh901318_desc_remove(cohd_que); + coh901318_desc_remove(cohd); /* initiate DMA job */ cohc->busy = 1; - coh901318_desc_submit(cohc, cohd_que); + coh901318_desc_submit(cohc, cohd); - coh901318_prep_linked_list(cohc, cohd_que->data); + coh901318_prep_linked_list(cohc, cohd->lli); - /* start dma job */ + /* start dma job on this channel */ coh901318_start(cohc); } - return cohd_que; + return cohd; } /* @@ -622,7 +623,7 @@ static void dma_tasklet(unsigned long data) cohc->completed = cohd_fin->desc.cookie; /* release the lli allocation and remove the descriptor */ - coh901318_lli_free(&cohc->base->pool, &cohd_fin->data); + coh901318_lli_free(&cohc->base->pool, &cohd_fin->lli); /* return desc to free-list */ coh901318_desc_remove(cohd_fin); @@ -666,23 +667,44 @@ static void dma_tasklet(unsigned long data) /* called from interrupt context */ static void dma_tc_handle(struct coh901318_chan *cohc) { - BUG_ON(!cohc->allocated && (list_empty(&cohc->active) || - list_empty(&cohc->queue))); - - if (!cohc->allocated) + /* + * If the channel is not allocated, then we shouldn't have + * any TC interrupts on it. + */ + if (!cohc->allocated) { + dev_err(COHC_2_DEV(cohc), "spurious interrupt from " + "unallocated channel\n"); return; + } spin_lock(&cohc->lock); + /* + * When we reach this point, at least one queue item + * should have been moved over from cohc->queue to + * cohc->active and run to completion, that is why we're + * getting a terminal count interrupt is it not? + * If you get this BUG() the most probable cause is that + * the individual nodes in the lli chain have IRQ enabled, + * so check your platform config for lli chain ctrl. + */ + BUG_ON(list_empty(&cohc->active)); + cohc->nbr_active_done++; + /* + * This attempt to take a job from cohc->queue, put it + * into cohc->active and start it. + */ if (coh901318_queue_start(cohc) == NULL) cohc->busy = 0; - BUG_ON(list_empty(&cohc->active)); - spin_unlock(&cohc->lock); + /* + * This tasklet will remove items from cohc->active + * and thus terminates them. + */ if (cohc_chan_conf(cohc)->priority_high) tasklet_hi_schedule(&cohc->tasklet); else @@ -870,7 +892,7 @@ static struct dma_async_tx_descriptor * coh901318_prep_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, size_t size, unsigned long flags) { - struct coh901318_lli *data; + struct coh901318_lli *lli; struct coh901318_desc *cohd; unsigned long flg; struct coh901318_chan *cohc = to_coh901318_chan(chan); @@ -892,23 +914,23 @@ coh901318_prep_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, if ((lli_len << MAX_DMA_PACKET_SIZE_SHIFT) < size) lli_len++; - data = coh901318_lli_alloc(&cohc->base->pool, lli_len); + lli = coh901318_lli_alloc(&cohc->base->pool, lli_len); - if (data == NULL) + if (lli == NULL) goto err; ret = coh901318_lli_fill_memcpy( - &cohc->base->pool, data, src, size, dest, + &cohc->base->pool, lli, src, size, dest, cohc_chan_param(cohc)->ctrl_lli_chained, ctrl_last); if (ret) goto err; - COH_DBG(coh901318_list_print(cohc, data)); + COH_DBG(coh901318_list_print(cohc, lli)); /* Pick a descriptor to handle this transfer */ cohd = coh901318_desc_get(cohc); - cohd->data = data; + cohd->lli = lli; cohd->flags = flags; cohd->desc.tx_submit = coh901318_tx_submit; @@ -926,7 +948,7 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, unsigned long flags) { struct coh901318_chan *cohc = to_coh901318_chan(chan); - struct coh901318_lli *data; + struct coh901318_lli *lli; struct coh901318_desc *cohd; const struct coh901318_params *params; struct scatterlist *sg; @@ -999,13 +1021,13 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, } pr_debug("Allocate %d lli:s for this transfer\n", len); - data = coh901318_lli_alloc(&cohc->base->pool, len); + lli = coh901318_lli_alloc(&cohc->base->pool, len); - if (data == NULL) + if (lli == NULL) goto err_dma_alloc; - /* initiate allocated data list */ - ret = coh901318_lli_fill_sg(&cohc->base->pool, data, sgl, sg_len, + /* initiate allocated lli list */ + ret = coh901318_lli_fill_sg(&cohc->base->pool, lli, sgl, sg_len, cohc_dev_addr(cohc), ctrl_chained, ctrl, @@ -1014,14 +1036,14 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, if (ret) goto err_lli_fill; - COH_DBG(coh901318_list_print(cohc, data)); + COH_DBG(coh901318_list_print(cohc, lli)); /* Pick a descriptor to handle this transfer */ cohd = coh901318_desc_get(cohc); cohd->dir = direction; cohd->flags = flags; cohd->desc.tx_submit = coh901318_tx_submit; - cohd->data = data; + cohd->lli = lli; spin_unlock_irqrestore(&cohc->lock, flg); @@ -1065,7 +1087,12 @@ coh901318_issue_pending(struct dma_chan *chan) spin_lock_irqsave(&cohc->lock, flags); - /* Busy means that pending jobs are already being processed */ + /* + * Busy means that pending jobs are already being processed, + * and then there is no point in starting the queue: the + * terminal count interrupt on the channel will take the next + * job on the queue and execute it anyway. + */ if (!cohc->busy) coh901318_queue_start(cohc); @@ -1099,7 +1126,7 @@ coh901318_terminate_all(struct dma_chan *chan) while ((cohd = coh901318_first_active_get(cohc))) { /* release the lli allocation*/ - coh901318_lli_free(&cohc->base->pool, &cohd->data); + coh901318_lli_free(&cohc->base->pool, &cohd->lli); /* return desc to free-list */ coh901318_desc_remove(cohd); @@ -1108,7 +1135,7 @@ coh901318_terminate_all(struct dma_chan *chan) while ((cohd = coh901318_first_queued(cohc))) { /* release the lli allocation*/ - coh901318_lli_free(&cohc->base->pool, &cohd->data); + coh901318_lli_free(&cohc->base->pool, &cohd->lli); /* return desc to free-list */ coh901318_desc_remove(cohd); -- cgit v1.2.3 From 84c8447c544bc7579097649273bc3f4e1b5de6af Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 4 Mar 2010 14:40:30 +0100 Subject: DMAENGINE: COH 901 318 fix bytesleft This makes the function to get the number of bytes left in the ongoing DMA transaction actually work: the old code did not take neither lli:s nor queued jobs into account. Also fix a missing spinlock while we're at it. Signed-off-by: Linus Walleij Signed-off-by: Dan Williams --- drivers/dma/coh901318.c | 96 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 88 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index 20889c98e9b0..f636c4a87c7f 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -408,25 +408,100 @@ coh901318_first_queued(struct coh901318_chan *cohc) return d; } +static inline u32 coh901318_get_bytes_in_lli(struct coh901318_lli *in_lli) +{ + struct coh901318_lli *lli = in_lli; + u32 bytes = 0; + + while (lli) { + bytes += lli->control & COH901318_CX_CTRL_TC_VALUE_MASK; + lli = lli->virt_link_addr; + } + return bytes; +} + /* - * DMA start/stop controls + * Get the number of bytes left to transfer on this channel, + * it is unwise to call this before stopping the channel for + * absolute measures, but for a rough guess you can still call + * it. */ u32 coh901318_get_bytes_left(struct dma_chan *chan) { - unsigned long flags; - u32 ret; struct coh901318_chan *cohc = to_coh901318_chan(chan); + struct coh901318_desc *cohd; + struct list_head *pos; + unsigned long flags; + u32 left = 0; + int i = 0; spin_lock_irqsave(&cohc->lock, flags); - /* Read transfer count value */ - ret = readl(cohc->base->virtbase + - COH901318_CX_CTRL+COH901318_CX_CTRL_SPACING * - cohc->id) & COH901318_CX_CTRL_TC_VALUE_MASK; + /* + * If there are many queued jobs, we iterate and add the + * size of them all. We take a special look on the first + * job though, since it is probably active. + */ + list_for_each(pos, &cohc->active) { + /* + * The first job in the list will be working on the + * hardware. The job can be stopped but still active, + * so that the transfer counter is somewhere inside + * the buffer. + */ + cohd = list_entry(pos, struct coh901318_desc, node); + + if (i == 0) { + struct coh901318_lli *lli; + dma_addr_t ladd; + + /* Read current transfer count value */ + left = readl(cohc->base->virtbase + + COH901318_CX_CTRL + + COH901318_CX_CTRL_SPACING * cohc->id) & + COH901318_CX_CTRL_TC_VALUE_MASK; + + /* See if the transfer is linked... */ + ladd = readl(cohc->base->virtbase + + COH901318_CX_LNK_ADDR + + COH901318_CX_LNK_ADDR_SPACING * + cohc->id) & + ~COH901318_CX_LNK_LINK_IMMEDIATE; + /* Single transaction */ + if (!ladd) + continue; + + /* + * Linked transaction, follow the lli, find the + * currently processing lli, and proceed to the next + */ + lli = cohd->lli; + while (lli && lli->link_addr != ladd) + lli = lli->virt_link_addr; + + if (lli) + lli = lli->virt_link_addr; + + /* + * Follow remaining lli links around to count the total + * number of bytes left + */ + left += coh901318_get_bytes_in_lli(lli); + } else { + left += coh901318_get_bytes_in_lli(cohd->lli); + } + i++; + } + + /* Also count bytes in the queued jobs */ + list_for_each(pos, &cohc->queue) { + cohd = list_entry(pos, struct coh901318_desc, node); + left += coh901318_get_bytes_in_lli(cohd->lli); + } spin_unlock_irqrestore(&cohc->lock, flags); - return ret; + return left; } EXPORT_SYMBOL(coh901318_get_bytes_left); @@ -831,6 +906,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id) static int coh901318_alloc_chan_resources(struct dma_chan *chan) { struct coh901318_chan *cohc = to_coh901318_chan(chan); + unsigned long flags; dev_vdbg(COHC_2_DEV(cohc), "[%s] DMA channel %d\n", __func__, cohc->id); @@ -838,11 +914,15 @@ static int coh901318_alloc_chan_resources(struct dma_chan *chan) if (chan->client_count > 1) return -EBUSY; + spin_lock_irqsave(&cohc->lock, flags); + coh901318_config(cohc, NULL); cohc->allocated = 1; cohc->completed = chan->cookie = 1; + spin_unlock_irqrestore(&cohc->lock, flags); + return 1; } -- cgit v1.2.3 From de5d4453c5b224eefd02b6a141ed411a76d458af Mon Sep 17 00:00:00 2001 From: Richard Röjfors Date: Thu, 25 Mar 2010 19:44:21 +0100 Subject: dma: Add timb-dma MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the support for the DMA engine withing the timberdale FPGA. The DMA channels are strict device to host, or host to device and can not be used for generic memcpy. Signed-off-by: Richard Röjfors Signed-off-by: Dan Williams --- drivers/dma/Kconfig | 7 + drivers/dma/Makefile | 1 + drivers/dma/timb_dma.c | 853 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/timb_dma.h | 55 +++ 4 files changed, 916 insertions(+) create mode 100644 drivers/dma/timb_dma.c create mode 100644 include/linux/timb_dma.h (limited to 'drivers') diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index c27f80e5d531..a2fcb2ead892 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -149,6 +149,13 @@ config AMCC_PPC440SPE_ADMA help Enable support for the AMCC PPC440SPe RAID engines. +config TIMB_DMA + tristate "Timberdale FPGA DMA support" + depends on MFD_TIMBERDALE || HAS_IOMEM + select DMA_ENGINE + help + Enable support for the Timberdale FPGA DMA engine. + config ARCH_HAS_ASYNC_TX_FIND_CHANNEL bool diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 22bba3d5e2b6..40c627d8f73b 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -20,3 +20,4 @@ obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o obj-$(CONFIG_SH_DMAE) += shdma.o obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o obj-$(CONFIG_AMCC_PPC440SPE_ADMA) += ppc4xx/ +obj-$(CONFIG_TIMB_DMA) += timb_dma.o diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c new file mode 100644 index 000000000000..4dd710246c79 --- /dev/null +++ b/drivers/dma/timb_dma.c @@ -0,0 +1,853 @@ +/* + * timb_dma.c timberdale FPGA DMA driver + * Copyright (c) 2010 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* Supports: + * Timberdale FPGA DMA engine + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DRIVER_NAME "timb-dma" + +/* Global DMA registers */ +#define TIMBDMA_ACR 0x34 +#define TIMBDMA_32BIT_ADDR 0x01 + +#define TIMBDMA_ISR 0x080000 +#define TIMBDMA_IPR 0x080004 +#define TIMBDMA_IER 0x080008 + +/* Channel specific registers */ +/* RX instances base addresses are 0x00, 0x40, 0x80 ... + * TX instances base addresses are 0x18, 0x58, 0x98 ... + */ +#define TIMBDMA_INSTANCE_OFFSET 0x40 +#define TIMBDMA_INSTANCE_TX_OFFSET 0x18 + +/* RX registers, relative the instance base */ +#define TIMBDMA_OFFS_RX_DHAR 0x00 +#define TIMBDMA_OFFS_RX_DLAR 0x04 +#define TIMBDMA_OFFS_RX_LR 0x0C +#define TIMBDMA_OFFS_RX_BLR 0x10 +#define TIMBDMA_OFFS_RX_ER 0x14 +#define TIMBDMA_RX_EN 0x01 +/* bytes per Row, video specific register + * which is placed after the TX registers... + */ +#define TIMBDMA_OFFS_RX_BPRR 0x30 + +/* TX registers, relative the instance base */ +#define TIMBDMA_OFFS_TX_DHAR 0x00 +#define TIMBDMA_OFFS_TX_DLAR 0x04 +#define TIMBDMA_OFFS_TX_BLR 0x0C +#define TIMBDMA_OFFS_TX_LR 0x14 + + +#define TIMB_DMA_DESC_SIZE 8 + +struct timb_dma_desc { + struct list_head desc_node; + struct dma_async_tx_descriptor txd; + u8 *desc_list; + unsigned int desc_list_len; + bool interrupt; +}; + +struct timb_dma_chan { + struct dma_chan chan; + void __iomem *membase; + spinlock_t lock; /* Used for mutual exclusion */ + dma_cookie_t last_completed_cookie; + bool ongoing; + struct list_head active_list; + struct list_head queue; + struct list_head free_list; + unsigned int bytes_per_line; + enum dma_data_direction direction; + unsigned int descs; /* Descriptors to allocate */ + unsigned int desc_elems; /* number of elems per descriptor */ +}; + +struct timb_dma { + struct dma_device dma; + void __iomem *membase; + struct tasklet_struct tasklet; + struct timb_dma_chan channels[0]; +}; + +static struct device *chan2dev(struct dma_chan *chan) +{ + return &chan->dev->device; +} +static struct device *chan2dmadev(struct dma_chan *chan) +{ + return chan2dev(chan)->parent->parent; +} + +static struct timb_dma *tdchantotd(struct timb_dma_chan *td_chan) +{ + int id = td_chan->chan.chan_id; + return (struct timb_dma *)((u8 *)td_chan - + id * sizeof(struct timb_dma_chan) - sizeof(struct timb_dma)); +} + +/* Must be called with the spinlock held */ +static void __td_enable_chan_irq(struct timb_dma_chan *td_chan) +{ + int id = td_chan->chan.chan_id; + struct timb_dma *td = tdchantotd(td_chan); + u32 ier; + + /* enable interrupt for this channel */ + ier = ioread32(td->membase + TIMBDMA_IER); + ier |= 1 << id; + dev_dbg(chan2dev(&td_chan->chan), "Enabling irq: %d, IER: 0x%x\n", id, + ier); + iowrite32(ier, td->membase + TIMBDMA_IER); +} + +/* Should be called with the spinlock held */ +static bool __td_dma_done_ack(struct timb_dma_chan *td_chan) +{ + int id = td_chan->chan.chan_id; + struct timb_dma *td = (struct timb_dma *)((u8 *)td_chan - + id * sizeof(struct timb_dma_chan) - sizeof(struct timb_dma)); + u32 isr; + bool done = false; + + dev_dbg(chan2dev(&td_chan->chan), "Checking irq: %d, td: %p\n", id, td); + + isr = ioread32(td->membase + TIMBDMA_ISR) & (1 << id); + if (isr) { + iowrite32(isr, td->membase + TIMBDMA_ISR); + done = true; + } + + return done; +} + +static void __td_unmap_desc(struct timb_dma_chan *td_chan, const u8 *dma_desc, + bool single) +{ + dma_addr_t addr; + int len; + + addr = (dma_desc[7] << 24) | (dma_desc[6] << 16) | (dma_desc[5] << 8) | + dma_desc[4]; + + len = (dma_desc[3] << 8) | dma_desc[2]; + + if (single) + dma_unmap_single(chan2dev(&td_chan->chan), addr, len, + td_chan->direction); + else + dma_unmap_page(chan2dev(&td_chan->chan), addr, len, + td_chan->direction); +} + +static void __td_unmap_descs(struct timb_dma_desc *td_desc, bool single) +{ + struct timb_dma_chan *td_chan = container_of(td_desc->txd.chan, + struct timb_dma_chan, chan); + u8 *descs; + + for (descs = td_desc->desc_list; ; descs += TIMB_DMA_DESC_SIZE) { + __td_unmap_desc(td_chan, descs, single); + if (descs[0] & 0x02) + break; + } +} + +static int td_fill_desc(struct timb_dma_chan *td_chan, u8 *dma_desc, + struct scatterlist *sg, bool last) +{ + if (sg_dma_len(sg) > USHORT_MAX) { + dev_err(chan2dev(&td_chan->chan), "Too big sg element\n"); + return -EINVAL; + } + + /* length must be word aligned */ + if (sg_dma_len(sg) % sizeof(u32)) { + dev_err(chan2dev(&td_chan->chan), "Incorrect length: %d\n", + sg_dma_len(sg)); + return -EINVAL; + } + + dev_dbg(chan2dev(&td_chan->chan), "desc: %p, addr: %p\n", + dma_desc, (void *)(int)sg_dma_address(sg)); + + dma_desc[7] = (sg_dma_address(sg) >> 24) & 0xff; + dma_desc[6] = (sg_dma_address(sg) >> 16) & 0xff; + dma_desc[5] = (sg_dma_address(sg) >> 8) & 0xff; + dma_desc[4] = (sg_dma_address(sg) >> 0) & 0xff; + + dma_desc[3] = (sg_dma_len(sg) >> 8) & 0xff; + dma_desc[2] = (sg_dma_len(sg) >> 0) & 0xff; + + dma_desc[1] = 0x00; + dma_desc[0] = 0x21 | (last ? 0x02 : 0); /* tran, valid */ + + return 0; +} + +/* Must be called with the spinlock held */ +static void __td_start_dma(struct timb_dma_chan *td_chan) +{ + struct timb_dma_desc *td_desc; + + if (td_chan->ongoing) { + dev_err(chan2dev(&td_chan->chan), + "Transfer already ongoing\n"); + return; + } + + td_desc = list_entry(td_chan->active_list.next, struct timb_dma_desc, + desc_node); + + dev_dbg(chan2dev(&td_chan->chan), + "td_chan: %p, chan: %d, membase: %p\n", + td_chan, td_chan->chan.chan_id, td_chan->membase); + + if (td_chan->direction == DMA_FROM_DEVICE) { + + /* descriptor address */ + iowrite32(0, td_chan->membase + TIMBDMA_OFFS_RX_DHAR); + iowrite32(td_desc->txd.phys, td_chan->membase + + TIMBDMA_OFFS_RX_DLAR); + /* Bytes per line */ + iowrite32(td_chan->bytes_per_line, td_chan->membase + + TIMBDMA_OFFS_RX_BPRR); + /* enable RX */ + iowrite32(TIMBDMA_RX_EN, td_chan->membase + TIMBDMA_OFFS_RX_ER); + } else { + /* address high */ + iowrite32(0, td_chan->membase + TIMBDMA_OFFS_TX_DHAR); + iowrite32(td_desc->txd.phys, td_chan->membase + + TIMBDMA_OFFS_TX_DLAR); + } + + td_chan->ongoing = true; + + if (td_desc->interrupt) + __td_enable_chan_irq(td_chan); +} + +static void __td_finish(struct timb_dma_chan *td_chan) +{ + dma_async_tx_callback callback; + void *param; + struct dma_async_tx_descriptor *txd; + struct timb_dma_desc *td_desc; + + /* can happen if the descriptor is canceled */ + if (list_empty(&td_chan->active_list)) + return; + + td_desc = list_entry(td_chan->active_list.next, struct timb_dma_desc, + desc_node); + txd = &td_desc->txd; + + dev_dbg(chan2dev(&td_chan->chan), "descriptor %u complete\n", + txd->cookie); + + /* make sure to stop the transfer */ + if (td_chan->direction == DMA_FROM_DEVICE) + iowrite32(0, td_chan->membase + TIMBDMA_OFFS_RX_ER); +/* Currently no support for stopping DMA transfers + else + iowrite32(0, td_chan->membase + TIMBDMA_OFFS_TX_DLAR); +*/ + td_chan->last_completed_cookie = txd->cookie; + td_chan->ongoing = false; + + callback = txd->callback; + param = txd->callback_param; + + list_move(&td_desc->desc_node, &td_chan->free_list); + + if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) + __td_unmap_descs(td_desc, + txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE); + + /* + * The API requires that no submissions are done from a + * callback, so we don't need to drop the lock here + */ + if (callback) + callback(param); +} + +static u32 __td_ier_mask(struct timb_dma *td) +{ + int i; + u32 ret = 0; + + for (i = 0; i < td->dma.chancnt; i++) { + struct timb_dma_chan *td_chan = td->channels + i; + if (td_chan->ongoing) { + struct timb_dma_desc *td_desc = + list_entry(td_chan->active_list.next, + struct timb_dma_desc, desc_node); + if (td_desc->interrupt) + ret |= 1 << i; + } + } + + return ret; +} + +static void __td_start_next(struct timb_dma_chan *td_chan) +{ + struct timb_dma_desc *td_desc; + + BUG_ON(list_empty(&td_chan->queue)); + BUG_ON(td_chan->ongoing); + + td_desc = list_entry(td_chan->queue.next, struct timb_dma_desc, + desc_node); + + dev_dbg(chan2dev(&td_chan->chan), "%s: started %u\n", + __func__, td_desc->txd.cookie); + + list_move(&td_desc->desc_node, &td_chan->active_list); + __td_start_dma(td_chan); +} + +static dma_cookie_t td_tx_submit(struct dma_async_tx_descriptor *txd) +{ + struct timb_dma_desc *td_desc = container_of(txd, struct timb_dma_desc, + txd); + struct timb_dma_chan *td_chan = container_of(txd->chan, + struct timb_dma_chan, chan); + dma_cookie_t cookie; + + spin_lock_bh(&td_chan->lock); + + cookie = txd->chan->cookie; + if (++cookie < 0) + cookie = 1; + txd->chan->cookie = cookie; + txd->cookie = cookie; + + if (list_empty(&td_chan->active_list)) { + dev_dbg(chan2dev(txd->chan), "%s: started %u\n", __func__, + txd->cookie); + list_add_tail(&td_desc->desc_node, &td_chan->active_list); + __td_start_dma(td_chan); + } else { + dev_dbg(chan2dev(txd->chan), "tx_submit: queued %u\n", + txd->cookie); + + list_add_tail(&td_desc->desc_node, &td_chan->queue); + } + + spin_unlock_bh(&td_chan->lock); + + return cookie; +} + +static struct timb_dma_desc *td_alloc_init_desc(struct timb_dma_chan *td_chan) +{ + struct dma_chan *chan = &td_chan->chan; + struct timb_dma_desc *td_desc; + int err; + + td_desc = kzalloc(sizeof(struct timb_dma_desc), GFP_KERNEL); + if (!td_desc) { + dev_err(chan2dev(chan), "Failed to alloc descriptor\n"); + goto err; + } + + td_desc->desc_list_len = td_chan->desc_elems * TIMB_DMA_DESC_SIZE; + + td_desc->desc_list = kzalloc(td_desc->desc_list_len, GFP_KERNEL); + if (!td_desc->desc_list) { + dev_err(chan2dev(chan), "Failed to alloc descriptor\n"); + goto err; + } + + dma_async_tx_descriptor_init(&td_desc->txd, chan); + td_desc->txd.tx_submit = td_tx_submit; + td_desc->txd.flags = DMA_CTRL_ACK; + + td_desc->txd.phys = dma_map_single(chan2dmadev(chan), + td_desc->desc_list, td_desc->desc_list_len, DMA_TO_DEVICE); + + err = dma_mapping_error(chan2dmadev(chan), td_desc->txd.phys); + if (err) { + dev_err(chan2dev(chan), "DMA mapping error: %d\n", err); + goto err; + } + + return td_desc; +err: + kfree(td_desc->desc_list); + kfree(td_desc); + + return NULL; + +} + +static void td_free_desc(struct timb_dma_desc *td_desc) +{ + dev_dbg(chan2dev(td_desc->txd.chan), "Freeing desc: %p\n", td_desc); + dma_unmap_single(chan2dmadev(td_desc->txd.chan), td_desc->txd.phys, + td_desc->desc_list_len, DMA_TO_DEVICE); + + kfree(td_desc->desc_list); + kfree(td_desc); +} + +static void td_desc_put(struct timb_dma_chan *td_chan, + struct timb_dma_desc *td_desc) +{ + dev_dbg(chan2dev(&td_chan->chan), "Putting desc: %p\n", td_desc); + + spin_lock_bh(&td_chan->lock); + list_add(&td_desc->desc_node, &td_chan->free_list); + spin_unlock_bh(&td_chan->lock); +} + +static struct timb_dma_desc *td_desc_get(struct timb_dma_chan *td_chan) +{ + struct timb_dma_desc *td_desc, *_td_desc; + struct timb_dma_desc *ret = NULL; + + spin_lock_bh(&td_chan->lock); + list_for_each_entry_safe(td_desc, _td_desc, &td_chan->free_list, + desc_node) { + if (async_tx_test_ack(&td_desc->txd)) { + list_del(&td_desc->desc_node); + ret = td_desc; + break; + } + dev_dbg(chan2dev(&td_chan->chan), "desc %p not ACKed\n", + td_desc); + } + spin_unlock_bh(&td_chan->lock); + + return ret; +} + +static int td_alloc_chan_resources(struct dma_chan *chan) +{ + struct timb_dma_chan *td_chan = + container_of(chan, struct timb_dma_chan, chan); + int i; + + dev_dbg(chan2dev(chan), "%s: entry\n", __func__); + + BUG_ON(!list_empty(&td_chan->free_list)); + for (i = 0; i < td_chan->descs; i++) { + struct timb_dma_desc *td_desc = td_alloc_init_desc(td_chan); + if (!td_desc) { + if (i) + break; + else { + dev_err(chan2dev(chan), + "Couldnt allocate any descriptors\n"); + return -ENOMEM; + } + } + + td_desc_put(td_chan, td_desc); + } + + spin_lock_bh(&td_chan->lock); + td_chan->last_completed_cookie = 1; + chan->cookie = 1; + spin_unlock_bh(&td_chan->lock); + + return 0; +} + +static void td_free_chan_resources(struct dma_chan *chan) +{ + struct timb_dma_chan *td_chan = + container_of(chan, struct timb_dma_chan, chan); + struct timb_dma_desc *td_desc, *_td_desc; + LIST_HEAD(list); + + dev_dbg(chan2dev(chan), "%s: Entry\n", __func__); + + /* check that all descriptors are free */ + BUG_ON(!list_empty(&td_chan->active_list)); + BUG_ON(!list_empty(&td_chan->queue)); + + spin_lock_bh(&td_chan->lock); + list_splice_init(&td_chan->free_list, &list); + spin_unlock_bh(&td_chan->lock); + + list_for_each_entry_safe(td_desc, _td_desc, &list, desc_node) { + dev_dbg(chan2dev(chan), "%s: Freeing desc: %p\n", __func__, + td_desc); + td_free_desc(td_desc); + } +} + +static enum dma_status td_is_tx_complete(struct dma_chan *chan, + dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used) +{ + struct timb_dma_chan *td_chan = + container_of(chan, struct timb_dma_chan, chan); + dma_cookie_t last_used; + dma_cookie_t last_complete; + int ret; + + dev_dbg(chan2dev(chan), "%s: Entry\n", __func__); + + last_complete = td_chan->last_completed_cookie; + last_used = chan->cookie; + + ret = dma_async_is_complete(cookie, last_complete, last_used); + + if (done) + *done = last_complete; + if (used) + *used = last_used; + + dev_dbg(chan2dev(chan), + "%s: exit, ret: %d, last_complete: %d, last_used: %d\n", + __func__, ret, last_complete, last_used); + + return ret; +} + +static void td_issue_pending(struct dma_chan *chan) +{ + struct timb_dma_chan *td_chan = + container_of(chan, struct timb_dma_chan, chan); + + dev_dbg(chan2dev(chan), "%s: Entry\n", __func__); + spin_lock_bh(&td_chan->lock); + + if (!list_empty(&td_chan->active_list)) + /* transfer ongoing */ + if (__td_dma_done_ack(td_chan)) + __td_finish(td_chan); + + if (list_empty(&td_chan->active_list) && !list_empty(&td_chan->queue)) + __td_start_next(td_chan); + + spin_unlock_bh(&td_chan->lock); +} + +static struct dma_async_tx_descriptor *td_prep_slave_sg(struct dma_chan *chan, + struct scatterlist *sgl, unsigned int sg_len, + enum dma_data_direction direction, unsigned long flags) +{ + struct timb_dma_chan *td_chan = + container_of(chan, struct timb_dma_chan, chan); + struct timb_dma_desc *td_desc; + struct scatterlist *sg; + unsigned int i; + unsigned int desc_usage = 0; + + if (!sgl || !sg_len) { + dev_err(chan2dev(chan), "%s: No SG list\n", __func__); + return NULL; + } + + /* even channels are for RX, odd for TX */ + if (td_chan->direction != direction) { + dev_err(chan2dev(chan), + "Requesting channel in wrong direction\n"); + return NULL; + } + + td_desc = td_desc_get(td_chan); + if (!td_desc) { + dev_err(chan2dev(chan), "Not enough descriptors available\n"); + return NULL; + } + + td_desc->interrupt = (flags & DMA_PREP_INTERRUPT) != 0; + + for_each_sg(sgl, sg, sg_len, i) { + int err; + if (desc_usage > td_desc->desc_list_len) { + dev_err(chan2dev(chan), "No descriptor space\n"); + return NULL; + } + + err = td_fill_desc(td_chan, td_desc->desc_list + desc_usage, sg, + i == (sg_len - 1)); + if (err) { + dev_err(chan2dev(chan), "Failed to update desc: %d\n", + err); + td_desc_put(td_chan, td_desc); + return NULL; + } + desc_usage += TIMB_DMA_DESC_SIZE; + } + + dma_sync_single_for_device(chan2dmadev(chan), td_desc->txd.phys, + td_desc->desc_list_len, DMA_TO_DEVICE); + + return &td_desc->txd; +} + +static void td_terminate_all(struct dma_chan *chan) +{ + struct timb_dma_chan *td_chan = + container_of(chan, struct timb_dma_chan, chan); + struct timb_dma_desc *td_desc, *_td_desc; + + dev_dbg(chan2dev(chan), "%s: Entry\n", __func__); + + /* first the easy part, put the queue into the free list */ + spin_lock_bh(&td_chan->lock); + list_for_each_entry_safe(td_desc, _td_desc, &td_chan->queue, + desc_node) + list_move(&td_desc->desc_node, &td_chan->free_list); + + /* now tear down the runnning */ + __td_finish(td_chan); + spin_unlock_bh(&td_chan->lock); +} + +static void td_tasklet(unsigned long data) +{ + struct timb_dma *td = (struct timb_dma *)data; + u32 isr; + u32 ipr; + u32 ier; + int i; + + isr = ioread32(td->membase + TIMBDMA_ISR); + ipr = isr & __td_ier_mask(td); + + /* ack the interrupts */ + iowrite32(ipr, td->membase + TIMBDMA_ISR); + + for (i = 0; i < td->dma.chancnt; i++) + if (ipr & (1 << i)) { + struct timb_dma_chan *td_chan = td->channels + i; + spin_lock(&td_chan->lock); + __td_finish(td_chan); + if (!list_empty(&td_chan->queue)) + __td_start_next(td_chan); + spin_unlock(&td_chan->lock); + } + + ier = __td_ier_mask(td); + iowrite32(ier, td->membase + TIMBDMA_IER); +} + + +static irqreturn_t td_irq(int irq, void *devid) +{ + struct timb_dma *td = devid; + u32 ipr = ioread32(td->membase + TIMBDMA_IPR); + + if (ipr) { + /* disable interrupts, will be re-enabled in tasklet */ + iowrite32(0, td->membase + TIMBDMA_IER); + + tasklet_schedule(&td->tasklet); + + return IRQ_HANDLED; + } else + return IRQ_NONE; +} + + +static int __devinit td_probe(struct platform_device *pdev) +{ + struct timb_dma_platform_data *pdata = pdev->dev.platform_data; + struct timb_dma *td; + struct resource *iomem; + int irq; + int err; + int i; + + if (!pdata) { + dev_err(&pdev->dev, "No platform data\n"); + return -EINVAL; + } + + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!iomem) + return -EINVAL; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + if (!request_mem_region(iomem->start, resource_size(iomem), + DRIVER_NAME)) + return -EBUSY; + + td = kzalloc(sizeof(struct timb_dma) + + sizeof(struct timb_dma_chan) * pdata->nr_channels, GFP_KERNEL); + if (!td) { + err = -ENOMEM; + goto err_release_region; + } + + dev_dbg(&pdev->dev, "Allocated TD: %p\n", td); + + td->membase = ioremap(iomem->start, resource_size(iomem)); + if (!td->membase) { + dev_err(&pdev->dev, "Failed to remap I/O memory\n"); + err = -ENOMEM; + goto err_free_mem; + } + + /* 32bit addressing */ + iowrite32(TIMBDMA_32BIT_ADDR, td->membase + TIMBDMA_ACR); + + /* disable and clear any interrupts */ + iowrite32(0x0, td->membase + TIMBDMA_IER); + iowrite32(0xFFFFFFFF, td->membase + TIMBDMA_ISR); + + tasklet_init(&td->tasklet, td_tasklet, (unsigned long)td); + + err = request_irq(irq, td_irq, IRQF_SHARED, DRIVER_NAME, td); + if (err) { + dev_err(&pdev->dev, "Failed to request IRQ\n"); + goto err_tasklet_kill; + } + + td->dma.device_alloc_chan_resources = td_alloc_chan_resources; + td->dma.device_free_chan_resources = td_free_chan_resources; + td->dma.device_is_tx_complete = td_is_tx_complete; + td->dma.device_issue_pending = td_issue_pending; + + dma_cap_set(DMA_SLAVE, td->dma.cap_mask); + dma_cap_set(DMA_PRIVATE, td->dma.cap_mask); + td->dma.device_prep_slave_sg = td_prep_slave_sg; + td->dma.device_terminate_all = td_terminate_all; + + td->dma.dev = &pdev->dev; + + INIT_LIST_HEAD(&td->dma.channels); + + for (i = 0; i < pdata->nr_channels; i++, td->dma.chancnt++) { + struct timb_dma_chan *td_chan = &td->channels[i]; + struct timb_dma_platform_data_channel *pchan = + pdata->channels + i; + + /* even channels are RX, odd are TX */ + if (((i % 2) && pchan->rx) || (!(i % 2) && !pchan->rx)) { + dev_err(&pdev->dev, "Wrong channel configuration\n"); + err = -EINVAL; + goto err_tasklet_kill; + } + + td_chan->chan.device = &td->dma; + td_chan->chan.cookie = 1; + td_chan->chan.chan_id = i; + spin_lock_init(&td_chan->lock); + INIT_LIST_HEAD(&td_chan->active_list); + INIT_LIST_HEAD(&td_chan->queue); + INIT_LIST_HEAD(&td_chan->free_list); + + td_chan->descs = pchan->descriptors; + td_chan->desc_elems = pchan->descriptor_elements; + td_chan->bytes_per_line = pchan->bytes_per_line; + td_chan->direction = pchan->rx ? DMA_FROM_DEVICE : + DMA_TO_DEVICE; + + td_chan->membase = td->membase + + (i / 2) * TIMBDMA_INSTANCE_OFFSET + + (pchan->rx ? 0 : TIMBDMA_INSTANCE_TX_OFFSET); + + dev_dbg(&pdev->dev, "Chan: %d, membase: %p\n", + i, td_chan->membase); + + list_add_tail(&td_chan->chan.device_node, &td->dma.channels); + } + + err = dma_async_device_register(&td->dma); + if (err) { + dev_err(&pdev->dev, "Failed to register async device\n"); + goto err_free_irq; + } + + platform_set_drvdata(pdev, td); + + dev_dbg(&pdev->dev, "Probe result: %d\n", err); + return err; + +err_free_irq: + free_irq(irq, td); +err_tasklet_kill: + tasklet_kill(&td->tasklet); + iounmap(td->membase); +err_free_mem: + kfree(td); +err_release_region: + release_mem_region(iomem->start, resource_size(iomem)); + + return err; + +} + +static int __devexit td_remove(struct platform_device *pdev) +{ + struct timb_dma *td = platform_get_drvdata(pdev); + struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + int irq = platform_get_irq(pdev, 0); + + dma_async_device_unregister(&td->dma); + free_irq(irq, td); + tasklet_kill(&td->tasklet); + iounmap(td->membase); + kfree(td); + release_mem_region(iomem->start, resource_size(iomem)); + + platform_set_drvdata(pdev, NULL); + + dev_dbg(&pdev->dev, "Removed...\n"); + return 0; +} + +static struct platform_driver td_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + }, + .probe = td_probe, + .remove = __exit_p(td_remove), +}; + +static int __init td_init(void) +{ + return platform_driver_register(&td_driver); +} +module_init(td_init); + +static void __exit td_exit(void) +{ + platform_driver_unregister(&td_driver); +} +module_exit(td_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Timberdale DMA controller driver"); +MODULE_AUTHOR("Pelagicore AB "); +MODULE_ALIAS("platform:"DRIVER_NAME); diff --git a/include/linux/timb_dma.h b/include/linux/timb_dma.h new file mode 100644 index 000000000000..bb043e970b96 --- /dev/null +++ b/include/linux/timb_dma.h @@ -0,0 +1,55 @@ +/* + * timb_dma.h timberdale FPGA DMA driver defines + * Copyright (c) 2010 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* Supports: + * Timberdale FPGA DMA engine + */ + +#ifndef _LINUX_TIMB_DMA_H +#define _LINUX_TIMB_DMA_H + +/** + * struct timb_dma_platform_data_channel - Description of each individual + * DMA channel for the timberdale DMA driver + * @rx: true if this channel handles data in the direction to + * the CPU. + * @bytes_per_line: Number of bytes per line, this is specific for channels + * handling video data. For other channels this shall be left to 0. + * @descriptors: Number of descriptors to allocate for this channel. + * @descriptor_elements: Number of elements in each descriptor. + * + */ +struct timb_dma_platform_data_channel { + bool rx; + unsigned int bytes_per_line; + unsigned int descriptors; + unsigned int descriptor_elements; +}; + +/** + * struct timb_dma_platform_data - Platform data of the timberdale DMA driver + * @nr_channels: Number of defined channels in the channels array. + * @channels: Definition of the each channel. + * + */ +struct timb_dma_platform_data { + unsigned nr_channels; + struct timb_dma_platform_data_channel channels[32]; +}; + +#endif -- cgit v1.2.3 From 0f65169b1bf44220308e1ce1f6666ad03ddc27af Mon Sep 17 00:00:00 2001 From: Richard Röjfors Date: Fri, 26 Mar 2010 08:23:58 +0100 Subject: dma: timb-dma: Update comment and fix compiler warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An incremental patch which clarifies what the spinlock is used for and fixes a compiler warning. Signed-off-by: Richard Röjfors Signed-off-by: Dan Williams --- drivers/dma/timb_dma.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index 4dd710246c79..145f1c23408f 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -79,7 +79,10 @@ struct timb_dma_desc { struct timb_dma_chan { struct dma_chan chan; void __iomem *membase; - spinlock_t lock; /* Used for mutual exclusion */ + spinlock_t lock; /* Used to protect data structures, + especially the lists and descriptors, + from races between the tasklet and calls + from above */ dma_cookie_t last_completed_cookie; bool ongoing; struct list_head active_list; @@ -197,7 +200,7 @@ static int td_fill_desc(struct timb_dma_chan *td_chan, u8 *dma_desc, } dev_dbg(chan2dev(&td_chan->chan), "desc: %p, addr: %p\n", - dma_desc, (void *)(int)sg_dma_address(sg)); + dma_desc, (void *)sg_dma_address(sg)); dma_desc[7] = (sg_dma_address(sg) >> 24) & 0xff; dma_desc[6] = (sg_dma_address(sg) >> 16) & 0xff; -- cgit v1.2.3 From c3635c78e500a52c9fcd55de381a72928d9e054d Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 26 Mar 2010 16:44:01 -0700 Subject: DMAENGINE: generic slave control v2 Convert the device_terminate_all() operation on the DMA engine to a generic device_control() operation which can now optionally support also pausing and resuming DMA on a certain channel. Implemented for the COH 901 318 DMAC as an example. [dan.j.williams@intel.com: update for timberdale] Signed-off-by: Linus Walleij Acked-by: Mark Brown Cc: Maciej Sosnowski Cc: Nicolas Ferre Cc: Pavel Machek Cc: Li Yang Cc: Guennadi Liakhovetski Cc: Paul Mundt Cc: Ralf Baechle Cc: Haavard Skinnemoen Cc: Magnus Damm Cc: Liam Girdwood Cc: Joe Perches Cc: Roland Dreier Signed-off-by: Dan Williams --- arch/arm/mach-u300/include/mach/coh901318.h | 14 ---------- drivers/dma/at_hdmac.c | 10 +++++-- drivers/dma/coh901318.c | 42 +++++++++++++++++++---------- drivers/dma/dmaengine.c | 2 +- drivers/dma/dw_dmac.c | 10 +++++-- drivers/dma/fsldma.c | 13 ++++++--- drivers/dma/ipu/ipu_idmac.c | 21 ++++++++++----- drivers/dma/shdma.c | 12 ++++++--- drivers/dma/timb_dma.c | 9 +++++-- drivers/dma/txx9dmac.c | 10 +++++-- drivers/mmc/host/atmel-mci.c | 2 +- drivers/serial/sh-sci.c | 2 +- drivers/video/mx3fb.c | 3 ++- include/linux/dmaengine.h | 18 +++++++++++-- sound/soc/txx9/txx9aclc.c | 6 ++--- 15 files changed, 117 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-u300/include/mach/coh901318.h b/arch/arm/mach-u300/include/mach/coh901318.h index b8155b4e5ffa..43ec040e765b 100644 --- a/arch/arm/mach-u300/include/mach/coh901318.h +++ b/arch/arm/mach-u300/include/mach/coh901318.h @@ -109,20 +109,6 @@ struct coh901318_platform { */ u32 coh901318_get_bytes_left(struct dma_chan *chan); -/** - * coh901318_stop() - Stops dma transfer - * @chan: dma channel handle - * return 0 on success otherwise negative value - */ -void coh901318_stop(struct dma_chan *chan); - -/** - * coh901318_continue() - Resumes a stopped dma transfer - * @chan: dma channel handle - * return 0 on success otherwise negative value - */ -void coh901318_continue(struct dma_chan *chan); - /** * coh901318_filter_id() - DMA channel filter function * @chan: dma channel handle diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index efc1a61ca231..f9143cf9e50a 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -759,13 +759,17 @@ err_desc_get: return NULL; } -static void atc_terminate_all(struct dma_chan *chan) +static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct at_dma_chan *atchan = to_at_dma_chan(chan); struct at_dma *atdma = to_at_dma(chan->device); struct at_desc *desc, *_desc; LIST_HEAD(list); + /* Only supports DMA_TERMINATE_ALL */ + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + /* * This is only called when something went wrong elsewhere, so * we don't really care about the data. Just disable the @@ -789,6 +793,8 @@ static void atc_terminate_all(struct dma_chan *chan) /* Flush all pending and queued descriptors */ list_for_each_entry_safe(desc, _desc, &list, desc_node) atc_chain_complete(atchan, desc); + + return 0; } /** @@ -1091,7 +1097,7 @@ static int __init at_dma_probe(struct platform_device *pdev) if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)) { atdma->dma_common.device_prep_slave_sg = atc_prep_slave_sg; - atdma->dma_common.device_terminate_all = atc_terminate_all; + atdma->dma_common.device_control = atc_control; } dma_writel(atdma, EN, AT_DMA_ENABLE); diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index f636c4a87c7f..53c54e034aa3 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -506,10 +506,11 @@ u32 coh901318_get_bytes_left(struct dma_chan *chan) EXPORT_SYMBOL(coh901318_get_bytes_left); -/* Stops a transfer without losing data. Enables power save. - Use this function in conjunction with coh901318_continue(..) -*/ -void coh901318_stop(struct dma_chan *chan) +/* + * Pauses a transfer without losing data. Enables power save. + * Use this function in conjunction with coh901318_resume. + */ +static void coh901318_pause(struct dma_chan *chan) { u32 val; unsigned long flags; @@ -550,12 +551,11 @@ void coh901318_stop(struct dma_chan *chan) spin_unlock_irqrestore(&cohc->lock, flags); } -EXPORT_SYMBOL(coh901318_stop); -/* Continues a transfer that has been stopped via 300_dma_stop(..). +/* Resumes a transfer that has been stopped via 300_dma_stop(..). Power save is handled. */ -void coh901318_continue(struct dma_chan *chan) +static void coh901318_resume(struct dma_chan *chan) { u32 val; unsigned long flags; @@ -581,7 +581,6 @@ void coh901318_continue(struct dma_chan *chan) spin_unlock_irqrestore(&cohc->lock, flags); } -EXPORT_SYMBOL(coh901318_continue); bool coh901318_filter_id(struct dma_chan *chan, void *chan_id) { @@ -945,7 +944,7 @@ coh901318_free_chan_resources(struct dma_chan *chan) spin_unlock_irqrestore(&cohc->lock, flags); - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, DMA_TERMINATE_ALL); } @@ -1179,16 +1178,29 @@ coh901318_issue_pending(struct dma_chan *chan) spin_unlock_irqrestore(&cohc->lock, flags); } -static void -coh901318_terminate_all(struct dma_chan *chan) +static int +coh901318_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { unsigned long flags; struct coh901318_chan *cohc = to_coh901318_chan(chan); struct coh901318_desc *cohd; void __iomem *virtbase = cohc->base->virtbase; - coh901318_stop(chan); + if (cmd == DMA_PAUSE) { + coh901318_pause(chan); + return 0; + } + + if (cmd == DMA_RESUME) { + coh901318_resume(chan); + return 0; + } + + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + /* The remainder of this function terminates the transfer */ + coh901318_pause(chan); spin_lock_irqsave(&cohc->lock, flags); /* Clear any pending BE or TC interrupt */ @@ -1227,6 +1239,8 @@ coh901318_terminate_all(struct dma_chan *chan) cohc->busy = 0; spin_unlock_irqrestore(&cohc->lock, flags); + + return 0; } void coh901318_base_init(struct dma_device *dma, const int *pick_chans, struct coh901318_base *base) @@ -1344,7 +1358,7 @@ static int __init coh901318_probe(struct platform_device *pdev) base->dma_slave.device_prep_slave_sg = coh901318_prep_slave_sg; base->dma_slave.device_is_tx_complete = coh901318_is_tx_complete; base->dma_slave.device_issue_pending = coh901318_issue_pending; - base->dma_slave.device_terminate_all = coh901318_terminate_all; + base->dma_slave.device_control = coh901318_control; base->dma_slave.dev = &pdev->dev; err = dma_async_device_register(&base->dma_slave); @@ -1364,7 +1378,7 @@ static int __init coh901318_probe(struct platform_device *pdev) base->dma_memcpy.device_prep_dma_memcpy = coh901318_prep_memcpy; base->dma_memcpy.device_is_tx_complete = coh901318_is_tx_complete; base->dma_memcpy.device_issue_pending = coh901318_issue_pending; - base->dma_memcpy.device_terminate_all = coh901318_terminate_all; + base->dma_memcpy.device_control = coh901318_control; base->dma_memcpy.dev = &pdev->dev; /* * This controller can only access address at even 32bit boundaries, diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 87399cafce37..ffc4ee9c5e21 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -694,7 +694,7 @@ int dma_async_device_register(struct dma_device *device) BUG_ON(dma_has_cap(DMA_SLAVE, device->cap_mask) && !device->device_prep_slave_sg); BUG_ON(dma_has_cap(DMA_SLAVE, device->cap_mask) && - !device->device_terminate_all); + !device->device_control); BUG_ON(!device->device_alloc_chan_resources); BUG_ON(!device->device_free_chan_resources); diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index d28369f7afd2..8a6b85f61176 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -781,13 +781,17 @@ err_desc_get: return NULL; } -static void dwc_terminate_all(struct dma_chan *chan) +static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct dw_dma_chan *dwc = to_dw_dma_chan(chan); struct dw_dma *dw = to_dw_dma(chan->device); struct dw_desc *desc, *_desc; LIST_HEAD(list); + /* Only supports DMA_TERMINATE_ALL */ + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + /* * This is only called when something went wrong elsewhere, so * we don't really care about the data. Just disable the @@ -810,6 +814,8 @@ static void dwc_terminate_all(struct dma_chan *chan) /* Flush all pending and queued descriptors */ list_for_each_entry_safe(desc, _desc, &list, desc_node) dwc_descriptor_complete(dwc, desc); + + return 0; } static enum dma_status @@ -1338,7 +1344,7 @@ static int __init dw_probe(struct platform_device *pdev) dw->dma.device_prep_dma_memcpy = dwc_prep_dma_memcpy; dw->dma.device_prep_slave_sg = dwc_prep_slave_sg; - dw->dma.device_terminate_all = dwc_terminate_all; + dw->dma.device_control = dwc_control; dw->dma.device_is_tx_complete = dwc_is_tx_complete; dw->dma.device_issue_pending = dwc_issue_pending; diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index bbb4be5a3ff4..714fc46e7695 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -774,13 +774,18 @@ fail: return NULL; } -static void fsl_dma_device_terminate_all(struct dma_chan *dchan) +static int fsl_dma_device_control(struct dma_chan *dchan, + enum dma_ctrl_cmd cmd) { struct fsldma_chan *chan; unsigned long flags; + /* Only supports DMA_TERMINATE_ALL */ + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + if (!dchan) - return; + return -EINVAL; chan = to_fsl_chan(dchan); @@ -794,6 +799,8 @@ static void fsl_dma_device_terminate_all(struct dma_chan *dchan) fsldma_free_desc_list(chan, &chan->ld_running); spin_unlock_irqrestore(&chan->desc_lock, flags); + + return 0; } /** @@ -1332,7 +1339,7 @@ static int __devinit fsldma_of_probe(struct of_device *op, fdev->common.device_is_tx_complete = fsl_dma_is_complete; fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending; fdev->common.device_prep_slave_sg = fsl_dma_prep_slave_sg; - fdev->common.device_terminate_all = fsl_dma_device_terminate_all; + fdev->common.device_control = fsl_dma_device_control; fdev->common.dev = &op->dev; dev_set_drvdata(&op->dev, fdev); diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index 2a446397c884..39e7fb2a90e3 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1472,13 +1472,17 @@ static void idmac_issue_pending(struct dma_chan *chan) */ } -static void __idmac_terminate_all(struct dma_chan *chan) +static int __idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct idmac_channel *ichan = to_idmac_chan(chan); struct idmac *idmac = to_idmac(chan->device); unsigned long flags; int i; + /* Only supports DMA_TERMINATE_ALL */ + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + ipu_disable_channel(idmac, ichan, ichan->status >= IPU_CHANNEL_ENABLED); @@ -1505,17 +1509,22 @@ static void __idmac_terminate_all(struct dma_chan *chan) tasklet_enable(&to_ipu(idmac)->tasklet); ichan->status = IPU_CHANNEL_INITIALIZED; + + return 0; } -static void idmac_terminate_all(struct dma_chan *chan) +static int idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct idmac_channel *ichan = to_idmac_chan(chan); + int ret; mutex_lock(&ichan->chan_mutex); - __idmac_terminate_all(chan); + ret = __idmac_control(chan, cmd); mutex_unlock(&ichan->chan_mutex); + + return ret; } #ifdef DEBUG @@ -1607,7 +1616,7 @@ static void idmac_free_chan_resources(struct dma_chan *chan) mutex_lock(&ichan->chan_mutex); - __idmac_terminate_all(chan); + __idmac_control(chan, DMA_TERMINATE_ALL); if (ichan->status > IPU_CHANNEL_FREE) { #ifdef DEBUG @@ -1669,7 +1678,7 @@ static int __init ipu_idmac_init(struct ipu *ipu) /* Compulsory for DMA_SLAVE fields */ dma->device_prep_slave_sg = idmac_prep_slave_sg; - dma->device_terminate_all = idmac_terminate_all; + dma->device_control = idmac_control; INIT_LIST_HEAD(&dma->channels); for (i = 0; i < IPU_CHANNELS_NUM; i++) { @@ -1703,7 +1712,7 @@ static void __exit ipu_idmac_exit(struct ipu *ipu) for (i = 0; i < IPU_CHANNELS_NUM; i++) { struct idmac_channel *ichan = ipu->channel + i; - idmac_terminate_all(&ichan->dma_chan); + idmac_control(&ichan->dma_chan, DMA_TERMINATE_ALL); idmac_prep_slave_sg(&ichan->dma_chan, NULL, 0, DMA_NONE, 0); } diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 5d17e09cb625..ce28c1e22825 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -580,12 +580,16 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg( direction, flags); } -static void sh_dmae_terminate_all(struct dma_chan *chan) +static int sh_dmae_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct sh_dmae_chan *sh_chan = to_sh_chan(chan); + /* Only supports DMA_TERMINATE_ALL */ + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + if (!chan) - return; + return -EINVAL; dmae_halt(sh_chan); @@ -601,6 +605,8 @@ static void sh_dmae_terminate_all(struct dma_chan *chan) spin_unlock_bh(&sh_chan->desc_lock); sh_dmae_chan_ld_cleanup(sh_chan, true); + + return 0; } static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all) @@ -1029,7 +1035,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev) /* Compulsory for DMA_SLAVE fields */ shdev->common.device_prep_slave_sg = sh_dmae_prep_slave_sg; - shdev->common.device_terminate_all = sh_dmae_terminate_all; + shdev->common.device_control = sh_dmae_control; shdev->common.dev = &pdev->dev; /* Default transfer size of 32 bytes requires 32-byte alignment */ diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index 145f1c23408f..7c06471ef863 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -613,7 +613,7 @@ static struct dma_async_tx_descriptor *td_prep_slave_sg(struct dma_chan *chan, return &td_desc->txd; } -static void td_terminate_all(struct dma_chan *chan) +static int td_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct timb_dma_chan *td_chan = container_of(chan, struct timb_dma_chan, chan); @@ -621,6 +621,9 @@ static void td_terminate_all(struct dma_chan *chan) dev_dbg(chan2dev(chan), "%s: Entry\n", __func__); + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + /* first the easy part, put the queue into the free list */ spin_lock_bh(&td_chan->lock); list_for_each_entry_safe(td_desc, _td_desc, &td_chan->queue, @@ -630,6 +633,8 @@ static void td_terminate_all(struct dma_chan *chan) /* now tear down the runnning */ __td_finish(td_chan); spin_unlock_bh(&td_chan->lock); + + return 0; } static void td_tasklet(unsigned long data) @@ -743,7 +748,7 @@ static int __devinit td_probe(struct platform_device *pdev) dma_cap_set(DMA_SLAVE, td->dma.cap_mask); dma_cap_set(DMA_PRIVATE, td->dma.cap_mask); td->dma.device_prep_slave_sg = td_prep_slave_sg; - td->dma.device_terminate_all = td_terminate_all; + td->dma.device_control = td_control; td->dma.dev = &pdev->dev; diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c index 3ebc61067e54..e528e15f44ab 100644 --- a/drivers/dma/txx9dmac.c +++ b/drivers/dma/txx9dmac.c @@ -938,12 +938,16 @@ txx9dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, return &first->txd; } -static void txx9dmac_terminate_all(struct dma_chan *chan) +static int txx9dmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) { struct txx9dmac_chan *dc = to_txx9dmac_chan(chan); struct txx9dmac_desc *desc, *_desc; LIST_HEAD(list); + /* Only supports DMA_TERMINATE_ALL */ + if (cmd != DMA_TERMINATE_ALL) + return -EINVAL; + dev_vdbg(chan2dev(chan), "terminate_all\n"); spin_lock_bh(&dc->lock); @@ -958,6 +962,8 @@ static void txx9dmac_terminate_all(struct dma_chan *chan) /* Flush all pending and queued descriptors */ list_for_each_entry_safe(desc, _desc, &list, desc_node) txx9dmac_descriptor_complete(dc, desc); + + return 0; } static enum dma_status @@ -1153,7 +1159,7 @@ static int __init txx9dmac_chan_probe(struct platform_device *pdev) dc->dma.dev = &pdev->dev; dc->dma.device_alloc_chan_resources = txx9dmac_alloc_chan_resources; dc->dma.device_free_chan_resources = txx9dmac_free_chan_resources; - dc->dma.device_terminate_all = txx9dmac_terminate_all; + dc->dma.device_control = txx9dmac_control; dc->dma.device_is_tx_complete = txx9dmac_is_tx_complete; dc->dma.device_issue_pending = txx9dmac_issue_pending; if (pdata && pdata->memcpy_chan == ch) { diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 8072128e933b..ae6d24ba4f08 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -578,7 +578,7 @@ static void atmci_stop_dma(struct atmel_mci *host) struct dma_chan *chan = host->data_chan; if (chan) { - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, DMA_TERMINATE_ALL); atmci_dma_cleanup(host); } else { /* Data transfer was stopped by the interrupt handler */ diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index f7b9aff88f4a..690988237971 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -1087,7 +1087,7 @@ static void work_fn_rx(struct work_struct *work) unsigned long flags; int count; - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, DMA_TERMINATE_ALL); dev_dbg(port->dev, "Read %u bytes with cookie %d\n", sh_desc->partial, sh_desc->cookie); diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c index 772ba3f45e6f..3aa50bc276eb 100644 --- a/drivers/video/mx3fb.c +++ b/drivers/video/mx3fb.c @@ -387,7 +387,8 @@ static void sdc_disable_channel(struct mx3fb_info *mx3_fbi) spin_unlock_irqrestore(&mx3fb->lock, flags); - mx3_fbi->txd->chan->device->device_terminate_all(mx3_fbi->txd->chan); + mx3_fbi->txd->chan->device->device_control(mx3_fbi->txd->chan, + DMA_TERMINATE_ALL); mx3_fbi->txd = NULL; mx3_fbi->cookie = -EINVAL; } diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 20ea12c86fd0..0731802f876f 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -106,6 +106,19 @@ enum dma_ctrl_flags { DMA_PREP_FENCE = (1 << 9), }; +/** + * enum dma_ctrl_cmd - DMA operations that can optionally be exercised + * on a running channel. + * @DMA_TERMINATE_ALL: terminate all ongoing transfers + * @DMA_PAUSE: pause ongoing transfers + * @DMA_RESUME: resume paused transfer + */ +enum dma_ctrl_cmd { + DMA_TERMINATE_ALL, + DMA_PAUSE, + DMA_RESUME, +}; + /** * enum sum_check_bits - bit position of pq_check_flags */ @@ -261,7 +274,8 @@ struct dma_async_tx_descriptor { * @device_prep_dma_memset: prepares a memset operation * @device_prep_dma_interrupt: prepares an end of chain interrupt operation * @device_prep_slave_sg: prepares a slave dma operation - * @device_terminate_all: terminate all pending operations + * @device_control: manipulate all pending operations on a channel, returns + * zero or error code * @device_is_tx_complete: poll for transaction completion * @device_issue_pending: push pending transactions to hardware */ @@ -313,7 +327,7 @@ struct dma_device { struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, enum dma_data_direction direction, unsigned long flags); - void (*device_terminate_all)(struct dma_chan *chan); + int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd cmd); enum dma_status (*device_is_tx_complete)(struct dma_chan *chan, dma_cookie_t cookie, dma_cookie_t *last, diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c index efed64b8b026..b35d00706c0e 100644 --- a/sound/soc/txx9/txx9aclc.c +++ b/sound/soc/txx9/txx9aclc.c @@ -159,7 +159,7 @@ static void txx9aclc_dma_tasklet(unsigned long data) void __iomem *base = drvdata->base; spin_unlock_irqrestore(&dmadata->dma_lock, flags); - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, DMA_TERMINATE_ALL); /* first time */ for (i = 0; i < NR_DMA_CHAIN; i++) { desc = txx9aclc_dma_submit(dmadata, @@ -267,7 +267,7 @@ static int txx9aclc_pcm_close(struct snd_pcm_substream *substream) struct dma_chan *chan = dmadata->dma_chan; dmadata->frag_count = -1; - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, DMA_TERMINATE_ALL); return 0; } @@ -396,7 +396,7 @@ static int txx9aclc_pcm_remove(struct platform_device *pdev) struct dma_chan *chan = dmadata->dma_chan; if (chan) { dmadata->frag_count = -1; - chan->device->device_terminate_all(chan); + chan->device->device_control(chan, DMA_TERMINATE_ALL); dma_release_channel(chan); } dev->dmadata[i].dma_chan = NULL; -- cgit v1.2.3 From 0793448187643b50af89d36b08470baf45a3cab4 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 26 Mar 2010 16:50:49 -0700 Subject: DMAENGINE: generic channel status v2 Convert the device_is_tx_complete() operation on the DMA engine to a generic device_tx_status()operation which can return three states, DMA_TX_RUNNING, DMA_TX_COMPLETE, DMA_TX_PAUSED. [dan.j.williams@intel.com: update for timberdale] Signed-off-by: Linus Walleij Acked-by: Mark Brown Cc: Maciej Sosnowski Cc: Nicolas Ferre Cc: Pavel Machek Cc: Li Yang Cc: Guennadi Liakhovetski Cc: Paul Mundt Cc: Ralf Baechle Cc: Haavard Skinnemoen Cc: Magnus Damm Cc: Liam Girdwood Cc: Joe Perches Cc: Roland Dreier Signed-off-by: Dan Williams --- arch/arm/mach-u300/include/mach/coh901318.h | 7 ----- drivers/dma/at_hdmac.c | 29 ++++++++++--------- drivers/dma/coh901318.c | 25 ++++++++-------- drivers/dma/dmaengine.c | 2 +- drivers/dma/dw_dmac.c | 17 +++++------ drivers/dma/fsldma.c | 19 ++++++------- drivers/dma/ioat/dma.c | 12 ++++---- drivers/dma/ioat/dma.h | 22 +++++++-------- drivers/dma/ioat/dma_v2.c | 2 +- drivers/dma/ioat/dma_v3.c | 20 ++++++------- drivers/dma/iop-adma.c | 44 +++++++++++++++-------------- drivers/dma/ipu/ipu_idmac.c | 15 +++++----- drivers/dma/mpc512x_dma.c | 16 +++++------ drivers/dma/mv_xor.c | 32 +++++++++++---------- drivers/dma/ppc4xx/adma.c | 27 ++++++++++-------- drivers/dma/shdma.c | 17 ++++++----- drivers/dma/timb_dma.c | 15 +++++----- drivers/dma/txx9dmac.c | 16 +++++------ include/linux/dmaengine.h | 38 +++++++++++++++++++++---- 19 files changed, 203 insertions(+), 172 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-u300/include/mach/coh901318.h b/arch/arm/mach-u300/include/mach/coh901318.h index 43ec040e765b..193da2df732c 100644 --- a/arch/arm/mach-u300/include/mach/coh901318.h +++ b/arch/arm/mach-u300/include/mach/coh901318.h @@ -102,13 +102,6 @@ struct coh901318_platform { const int max_channels; }; -/** - * coh901318_get_bytes_left() - Get number of bytes left on a current transfer - * @chan: dma channel handle - * return number of bytes left, or negative on error - */ -u32 coh901318_get_bytes_left(struct dma_chan *chan); - /** * coh901318_filter_id() - DMA channel filter function * @chan: dma channel handle diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index f9143cf9e50a..ff75cf18d32e 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -798,29 +798,25 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) } /** - * atc_is_tx_complete - poll for transaction completion + * atc_tx_status - poll for transaction completion * @chan: DMA channel * @cookie: transaction identifier to check status of - * @done: if not %NULL, updated with last completed transaction - * @used: if not %NULL, updated with last used transaction + * @txstate: if not %NULL updated with transaction state * - * If @done and @used are passed in, upon return they reflect the driver + * If @txstate is passed in, upon return it reflect the driver * internal state and can be used with dma_async_is_complete() to check * the status of multiple cookies without re-checking hardware state. */ static enum dma_status -atc_is_tx_complete(struct dma_chan *chan, +atc_tx_status(struct dma_chan *chan, dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) + struct dma_tx_state *txstate) { struct at_dma_chan *atchan = to_at_dma_chan(chan); dma_cookie_t last_used; dma_cookie_t last_complete; enum dma_status ret; - dev_vdbg(chan2dev(chan), "is_tx_complete: %d (d%d, u%d)\n", - cookie, done ? *done : 0, used ? *used : 0); - spin_lock_bh(&atchan->lock); last_complete = atchan->completed_cookie; @@ -838,10 +834,15 @@ atc_is_tx_complete(struct dma_chan *chan, spin_unlock_bh(&atchan->lock); - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } + + dev_vdbg(chan2dev(chan), "tx_status: %d (d%d, u%d)\n", + cookie, last_complete ? last_complete : 0, + last_used ? last_used : 0); return ret; } @@ -1087,7 +1088,7 @@ static int __init at_dma_probe(struct platform_device *pdev) /* set base routines */ atdma->dma_common.device_alloc_chan_resources = atc_alloc_chan_resources; atdma->dma_common.device_free_chan_resources = atc_free_chan_resources; - atdma->dma_common.device_is_tx_complete = atc_is_tx_complete; + atdma->dma_common.device_tx_status = atc_tx_status; atdma->dma_common.device_issue_pending = atc_issue_pending; atdma->dma_common.dev = &pdev->dev; diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index 53c54e034aa3..309db3beef16 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -426,7 +426,7 @@ static inline u32 coh901318_get_bytes_in_lli(struct coh901318_lli *in_lli) * absolute measures, but for a rough guess you can still call * it. */ -u32 coh901318_get_bytes_left(struct dma_chan *chan) +static u32 coh901318_get_bytes_left(struct dma_chan *chan) { struct coh901318_chan *cohc = to_coh901318_chan(chan); struct coh901318_desc *cohd; @@ -503,8 +503,6 @@ u32 coh901318_get_bytes_left(struct dma_chan *chan) return left; } -EXPORT_SYMBOL(coh901318_get_bytes_left); - /* * Pauses a transfer without losing data. Enables power save. @@ -1136,9 +1134,8 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, } static enum dma_status -coh901318_is_tx_complete(struct dma_chan *chan, - dma_cookie_t cookie, dma_cookie_t *done, - dma_cookie_t *used) +coh901318_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct coh901318_chan *cohc = to_coh901318_chan(chan); dma_cookie_t last_used; @@ -1150,10 +1147,14 @@ coh901318_is_tx_complete(struct dma_chan *chan, ret = dma_async_is_complete(cookie, last_complete, last_used); - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = coh901318_get_bytes_left(chan); + } + + if (ret == DMA_IN_PROGRESS && cohc->stopped) + ret = DMA_PAUSED; return ret; } @@ -1356,7 +1357,7 @@ static int __init coh901318_probe(struct platform_device *pdev) base->dma_slave.device_alloc_chan_resources = coh901318_alloc_chan_resources; base->dma_slave.device_free_chan_resources = coh901318_free_chan_resources; base->dma_slave.device_prep_slave_sg = coh901318_prep_slave_sg; - base->dma_slave.device_is_tx_complete = coh901318_is_tx_complete; + base->dma_slave.device_tx_status = coh901318_tx_status; base->dma_slave.device_issue_pending = coh901318_issue_pending; base->dma_slave.device_control = coh901318_control; base->dma_slave.dev = &pdev->dev; @@ -1376,7 +1377,7 @@ static int __init coh901318_probe(struct platform_device *pdev) base->dma_memcpy.device_alloc_chan_resources = coh901318_alloc_chan_resources; base->dma_memcpy.device_free_chan_resources = coh901318_free_chan_resources; base->dma_memcpy.device_prep_dma_memcpy = coh901318_prep_memcpy; - base->dma_memcpy.device_is_tx_complete = coh901318_is_tx_complete; + base->dma_memcpy.device_tx_status = coh901318_tx_status; base->dma_memcpy.device_issue_pending = coh901318_issue_pending; base->dma_memcpy.device_control = coh901318_control; base->dma_memcpy.dev = &pdev->dev; diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index ffc4ee9c5e21..790caeeb4ccd 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -698,7 +698,7 @@ int dma_async_device_register(struct dma_device *device) BUG_ON(!device->device_alloc_chan_resources); BUG_ON(!device->device_free_chan_resources); - BUG_ON(!device->device_is_tx_complete); + BUG_ON(!device->device_tx_status); BUG_ON(!device->device_issue_pending); BUG_ON(!device->dev); diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 8a6b85f61176..263b70ee8562 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -819,9 +819,9 @@ static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) } static enum dma_status -dwc_is_tx_complete(struct dma_chan *chan, - dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) +dwc_tx_status(struct dma_chan *chan, + dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct dw_dma_chan *dwc = to_dw_dma_chan(chan); dma_cookie_t last_used; @@ -841,10 +841,11 @@ dwc_is_tx_complete(struct dma_chan *chan, ret = dma_async_is_complete(cookie, last_complete, last_used); } - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return ret; } @@ -1346,7 +1347,7 @@ static int __init dw_probe(struct platform_device *pdev) dw->dma.device_prep_slave_sg = dwc_prep_slave_sg; dw->dma.device_control = dwc_control; - dw->dma.device_is_tx_complete = dwc_is_tx_complete; + dw->dma.device_tx_status = dwc_tx_status; dw->dma.device_issue_pending = dwc_issue_pending; dma_writel(dw, CFG, DW_CFG_DMA_EN); diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 714fc46e7695..ca5e8a3dce72 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -971,13 +971,12 @@ static void fsl_dma_memcpy_issue_pending(struct dma_chan *dchan) } /** - * fsl_dma_is_complete - Determine the DMA status + * fsl_tx_status - Determine the DMA status * @chan : Freescale DMA channel */ -static enum dma_status fsl_dma_is_complete(struct dma_chan *dchan, +static enum dma_status fsl_tx_status(struct dma_chan *dchan, dma_cookie_t cookie, - dma_cookie_t *done, - dma_cookie_t *used) + struct dma_tx_state *txstate) { struct fsldma_chan *chan = to_fsl_chan(dchan); dma_cookie_t last_used; @@ -988,11 +987,11 @@ static enum dma_status fsl_dma_is_complete(struct dma_chan *dchan, last_used = dchan->cookie; last_complete = chan->completed_cookie; - if (done) - *done = last_complete; - - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return dma_async_is_complete(cookie, last_complete, last_used); } @@ -1336,7 +1335,7 @@ static int __devinit fsldma_of_probe(struct of_device *op, fdev->common.device_free_chan_resources = fsl_dma_free_chan_resources; fdev->common.device_prep_dma_interrupt = fsl_dma_prep_interrupt; fdev->common.device_prep_dma_memcpy = fsl_dma_prep_memcpy; - fdev->common.device_is_tx_complete = fsl_dma_is_complete; + fdev->common.device_tx_status = fsl_tx_status; fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending; fdev->common.device_prep_slave_sg = fsl_dma_prep_slave_sg; fdev->common.device_control = fsl_dma_device_control; diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index 0099340b9616..59cebbfc89ec 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c @@ -726,18 +726,18 @@ static void ioat1_timer_event(unsigned long data) } enum dma_status -ioat_is_dma_complete(struct dma_chan *c, dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) +ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct ioat_chan_common *chan = to_chan_common(c); struct ioatdma_device *device = chan->device; - if (ioat_is_complete(c, cookie, done, used) == DMA_SUCCESS) + if (ioat_tx_status(c, cookie, txstate) == DMA_SUCCESS) return DMA_SUCCESS; device->cleanup_fn((unsigned long) c); - return ioat_is_complete(c, cookie, done, used); + return ioat_tx_status(c, cookie, txstate); } static void ioat1_dma_start_null_desc(struct ioat_dma_chan *ioat) @@ -857,7 +857,7 @@ int __devinit ioat_dma_self_test(struct ioatdma_device *device) tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); if (tmo == 0 || - dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL) + dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test copy timed out, disabling\n"); err = -ENODEV; @@ -1198,7 +1198,7 @@ int __devinit ioat1_dma_probe(struct ioatdma_device *device, int dca) dma->device_issue_pending = ioat1_dma_memcpy_issue_pending; dma->device_alloc_chan_resources = ioat1_dma_alloc_chan_resources; dma->device_free_chan_resources = ioat1_dma_free_chan_resources; - dma->device_is_tx_complete = ioat_is_dma_complete; + dma->device_tx_status = ioat_dma_tx_status; err = ioat_probe(device); if (err) diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index 86b97ac8774e..23399672239e 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h @@ -142,15 +142,14 @@ static inline struct ioat_dma_chan *to_ioat_chan(struct dma_chan *c) } /** - * ioat_is_complete - poll the status of an ioat transaction + * ioat_tx_status - poll the status of an ioat transaction * @c: channel handle * @cookie: transaction identifier - * @done: if set, updated with last completed transaction - * @used: if set, updated with last used transaction + * @txstate: if set, updated with the transaction state */ static inline enum dma_status -ioat_is_complete(struct dma_chan *c, dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) +ioat_tx_status(struct dma_chan *c, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct ioat_chan_common *chan = to_chan_common(c); dma_cookie_t last_used; @@ -159,10 +158,11 @@ ioat_is_complete(struct dma_chan *c, dma_cookie_t cookie, last_used = c->cookie; last_complete = chan->completed_cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return dma_async_is_complete(cookie, last_complete, last_used); } @@ -338,8 +338,8 @@ struct dca_provider * __devinit ioat_dca_init(struct pci_dev *pdev, unsigned long ioat_get_current_completion(struct ioat_chan_common *chan); void ioat_init_channel(struct ioatdma_device *device, struct ioat_chan_common *chan, int idx); -enum dma_status ioat_is_dma_complete(struct dma_chan *c, dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used); +enum dma_status ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie, + struct dma_tx_state *txstate); void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags, size_t len, struct ioat_dma_descriptor *hw); bool ioat_cleanup_preamble(struct ioat_chan_common *chan, diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index 1ed5d66d7dca..f540e0be7f31 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c @@ -854,7 +854,7 @@ int __devinit ioat2_dma_probe(struct ioatdma_device *device, int dca) dma->device_issue_pending = ioat2_issue_pending; dma->device_alloc_chan_resources = ioat2_alloc_chan_resources; dma->device_free_chan_resources = ioat2_free_chan_resources; - dma->device_is_tx_complete = ioat_is_dma_complete; + dma->device_tx_status = ioat_tx_status; err = ioat_probe(device); if (err) diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index 26febc56dab1..d1adbf35268c 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c @@ -438,17 +438,17 @@ static void ioat3_timer_event(unsigned long data) } static enum dma_status -ioat3_is_complete(struct dma_chan *c, dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) +ioat3_tx_status(struct dma_chan *c, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct ioat2_dma_chan *ioat = to_ioat2_chan(c); - if (ioat_is_complete(c, cookie, done, used) == DMA_SUCCESS) + if (ioat_tx_status(c, cookie, txstate) == DMA_SUCCESS) return DMA_SUCCESS; ioat3_cleanup_poll(ioat); - return ioat_is_complete(c, cookie, done, used); + return ioat_tx_status(c, cookie, txstate); } static struct dma_async_tx_descriptor * @@ -976,7 +976,7 @@ static int __devinit ioat_xor_val_self_test(struct ioatdma_device *device) tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); - if (dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test xor timed out\n"); err = -ENODEV; goto free_resources; @@ -1030,7 +1030,7 @@ static int __devinit ioat_xor_val_self_test(struct ioatdma_device *device) tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); - if (dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test validate timed out\n"); err = -ENODEV; goto free_resources; @@ -1071,7 +1071,7 @@ static int __devinit ioat_xor_val_self_test(struct ioatdma_device *device) tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); - if (dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test memset timed out\n"); err = -ENODEV; goto free_resources; @@ -1114,7 +1114,7 @@ static int __devinit ioat_xor_val_self_test(struct ioatdma_device *device) tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); - if (dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test 2nd validate timed out\n"); err = -ENODEV; goto free_resources; @@ -1258,11 +1258,11 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) if (is_raid_device) { - dma->device_is_tx_complete = ioat3_is_complete; + dma->device_tx_status = ioat3_tx_status; device->cleanup_fn = ioat3_cleanup_event; device->timer_fn = ioat3_timer_event; } else { - dma->device_is_tx_complete = ioat_is_dma_complete; + dma->device_tx_status = ioat_dma_tx_status; device->cleanup_fn = ioat2_cleanup_event; device->timer_fn = ioat2_timer_event; } diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index ca6e6a0cb793..ee40dbba1879 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c @@ -893,14 +893,14 @@ static void iop_adma_free_chan_resources(struct dma_chan *chan) } /** - * iop_adma_is_complete - poll the status of an ADMA transaction + * iop_adma_status - poll the status of an ADMA transaction * @chan: ADMA channel handle * @cookie: ADMA transaction identifier + * @txstate: a holder for the current state of the channel or NULL */ -static enum dma_status iop_adma_is_complete(struct dma_chan *chan, +static enum dma_status iop_adma_status(struct dma_chan *chan, dma_cookie_t cookie, - dma_cookie_t *done, - dma_cookie_t *used) + struct dma_tx_state *txstate) { struct iop_adma_chan *iop_chan = to_iop_adma_chan(chan); dma_cookie_t last_used; @@ -910,10 +910,11 @@ static enum dma_status iop_adma_is_complete(struct dma_chan *chan, last_used = chan->cookie; last_complete = iop_chan->completed_cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } ret = dma_async_is_complete(cookie, last_complete, last_used); if (ret == DMA_SUCCESS) @@ -924,10 +925,11 @@ static enum dma_status iop_adma_is_complete(struct dma_chan *chan, last_used = chan->cookie; last_complete = iop_chan->completed_cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return dma_async_is_complete(cookie, last_complete, last_used); } @@ -1042,7 +1044,7 @@ static int __devinit iop_adma_memcpy_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(1); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test copy timed out, disabling\n"); @@ -1142,7 +1144,7 @@ iop_adma_xor_val_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test xor timed out, disabling\n"); @@ -1189,7 +1191,7 @@ iop_adma_xor_val_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test zero sum timed out, disabling\n"); err = -ENODEV; @@ -1213,7 +1215,7 @@ iop_adma_xor_val_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test memset timed out, disabling\n"); err = -ENODEV; @@ -1245,7 +1247,7 @@ iop_adma_xor_val_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test non-zero sum timed out, disabling\n"); err = -ENODEV; @@ -1340,7 +1342,7 @@ iop_adma_pq_zero_sum_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test pq timed out, disabling\n"); err = -ENODEV; @@ -1377,7 +1379,7 @@ iop_adma_pq_zero_sum_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test pq-zero-sum timed out, disabling\n"); err = -ENODEV; @@ -1409,7 +1411,7 @@ iop_adma_pq_zero_sum_self_test(struct iop_adma_device *device) iop_adma_issue_pending(dma_chan); msleep(8); - if (iop_adma_is_complete(dma_chan, cookie, NULL, NULL) != + if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_err(dev, "Self-test !pq-zero-sum timed out, disabling\n"); err = -ENODEV; @@ -1507,7 +1509,7 @@ static int __devinit iop_adma_probe(struct platform_device *pdev) /* set base routines */ dma_dev->device_alloc_chan_resources = iop_adma_alloc_chan_resources; dma_dev->device_free_chan_resources = iop_adma_free_chan_resources; - dma_dev->device_is_tx_complete = iop_adma_is_complete; + dma_dev->device_tx_status = iop_adma_status; dma_dev->device_issue_pending = iop_adma_issue_pending; dma_dev->dev = &pdev->dev; diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index 39e7fb2a90e3..b9cef8b1701c 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1646,15 +1646,16 @@ static void idmac_free_chan_resources(struct dma_chan *chan) tasklet_schedule(&to_ipu(idmac)->tasklet); } -static enum dma_status idmac_is_tx_complete(struct dma_chan *chan, - dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used) +static enum dma_status idmac_tx_status(struct dma_chan *chan, + dma_cookie_t cookie, struct dma_tx_state *txstate) { struct idmac_channel *ichan = to_idmac_chan(chan); - if (done) - *done = ichan->completed; - if (used) - *used = chan->cookie; + if (txstate) { + txstate->last = ichan->completed; + txstate->used = chan->cookie; + txstate->residue = 0; + } if (cookie != chan->cookie) return DMA_ERROR; return DMA_SUCCESS; @@ -1673,7 +1674,7 @@ static int __init ipu_idmac_init(struct ipu *ipu) dma->dev = ipu->dev; dma->device_alloc_chan_resources = idmac_alloc_chan_resources; dma->device_free_chan_resources = idmac_free_chan_resources; - dma->device_is_tx_complete = idmac_is_tx_complete; + dma->device_tx_status = idmac_tx_status; dma->device_issue_pending = idmac_issue_pending; /* Compulsory for DMA_SLAVE fields */ diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 3fdf1f46bd63..cb3a8e94ea48 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -540,8 +540,8 @@ static void mpc_dma_issue_pending(struct dma_chan *chan) /* Check request completion status */ static enum dma_status -mpc_dma_is_tx_complete(struct dma_chan *chan, dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) +mpc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan); unsigned long flags; @@ -553,11 +553,11 @@ mpc_dma_is_tx_complete(struct dma_chan *chan, dma_cookie_t cookie, last_complete = mchan->completed_cookie; spin_unlock_irqrestore(&mchan->lock, flags); - if (done) - *done = last_complete; - - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return dma_async_is_complete(cookie, last_complete, last_used); } @@ -693,7 +693,7 @@ static int __devinit mpc_dma_probe(struct of_device *op, dma->device_alloc_chan_resources = mpc_dma_alloc_chan_resources; dma->device_free_chan_resources = mpc_dma_free_chan_resources; dma->device_issue_pending = mpc_dma_issue_pending; - dma->device_is_tx_complete = mpc_dma_is_tx_complete; + dma->device_tx_status = mpc_dma_tx_status; dma->device_prep_dma_memcpy = mpc_dma_prep_memcpy; INIT_LIST_HEAD(&dma->channels); diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 466ab10c1ff1..79fb1dea691b 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -809,14 +809,14 @@ static void mv_xor_free_chan_resources(struct dma_chan *chan) } /** - * mv_xor_is_complete - poll the status of an XOR transaction + * mv_xor_status - poll the status of an XOR transaction * @chan: XOR channel handle * @cookie: XOR transaction identifier + * @txstate: XOR transactions state holder (or NULL) */ -static enum dma_status mv_xor_is_complete(struct dma_chan *chan, +static enum dma_status mv_xor_status(struct dma_chan *chan, dma_cookie_t cookie, - dma_cookie_t *done, - dma_cookie_t *used) + struct dma_tx_state *txstate) { struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan); dma_cookie_t last_used; @@ -826,10 +826,11 @@ static enum dma_status mv_xor_is_complete(struct dma_chan *chan, last_used = chan->cookie; last_complete = mv_chan->completed_cookie; mv_chan->is_complete_cookie = cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } ret = dma_async_is_complete(cookie, last_complete, last_used); if (ret == DMA_SUCCESS) { @@ -841,10 +842,11 @@ static enum dma_status mv_xor_is_complete(struct dma_chan *chan, last_used = chan->cookie; last_complete = mv_chan->completed_cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return dma_async_is_complete(cookie, last_complete, last_used); } @@ -974,7 +976,7 @@ static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device) async_tx_ack(tx); msleep(1); - if (mv_xor_is_complete(dma_chan, cookie, NULL, NULL) != + if (mv_xor_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test copy timed out, disabling\n"); @@ -1072,7 +1074,7 @@ mv_xor_xor_self_test(struct mv_xor_device *device) async_tx_ack(tx); msleep(8); - if (mv_xor_is_complete(dma_chan, cookie, NULL, NULL) != + if (mv_xor_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { dev_printk(KERN_ERR, dma_chan->device->dev, "Self-test xor timed out, disabling\n"); @@ -1167,7 +1169,7 @@ static int __devinit mv_xor_probe(struct platform_device *pdev) /* set base routines */ dma_dev->device_alloc_chan_resources = mv_xor_alloc_chan_resources; dma_dev->device_free_chan_resources = mv_xor_free_chan_resources; - dma_dev->device_is_tx_complete = mv_xor_is_complete; + dma_dev->device_tx_status = mv_xor_status; dma_dev->device_issue_pending = mv_xor_issue_pending; dma_dev->dev = &pdev->dev; diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index e69d87f24a25..d9a54c018652 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -3934,12 +3934,13 @@ static void ppc440spe_adma_free_chan_resources(struct dma_chan *chan) } /** - * ppc440spe_adma_is_complete - poll the status of an ADMA transaction + * ppc440spe_adma_tx_status - poll the status of an ADMA transaction * @chan: ADMA channel handle * @cookie: ADMA transaction identifier + * @txstate: a holder for the current state of the channel */ -static enum dma_status ppc440spe_adma_is_complete(struct dma_chan *chan, - dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used) +static enum dma_status ppc440spe_adma_tx_status(struct dma_chan *chan, + dma_cookie_t cookie, struct dma_tx_state *txstate) { struct ppc440spe_adma_chan *ppc440spe_chan; dma_cookie_t last_used; @@ -3950,10 +3951,11 @@ static enum dma_status ppc440spe_adma_is_complete(struct dma_chan *chan, last_used = chan->cookie; last_complete = ppc440spe_chan->completed_cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } ret = dma_async_is_complete(cookie, last_complete, last_used); if (ret == DMA_SUCCESS) @@ -3964,10 +3966,11 @@ static enum dma_status ppc440spe_adma_is_complete(struct dma_chan *chan, last_used = chan->cookie; last_complete = ppc440spe_chan->completed_cookie; - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return dma_async_is_complete(cookie, last_complete, last_used); } @@ -4179,7 +4182,7 @@ static void ppc440spe_adma_init_capabilities(struct ppc440spe_adma_device *adev) ppc440spe_adma_alloc_chan_resources; adev->common.device_free_chan_resources = ppc440spe_adma_free_chan_resources; - adev->common.device_is_tx_complete = ppc440spe_adma_is_complete; + adev->common.device_tx_status = ppc440spe_adma_tx_status; adev->common.device_issue_pending = ppc440spe_adma_issue_pending; /* Set prep routines based on capability */ diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index ce28c1e22825..8aeda9ceb225 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -738,10 +738,9 @@ static void sh_dmae_memcpy_issue_pending(struct dma_chan *chan) sh_chan_xfer_ld_queue(sh_chan); } -static enum dma_status sh_dmae_is_complete(struct dma_chan *chan, +static enum dma_status sh_dmae_tx_status(struct dma_chan *chan, dma_cookie_t cookie, - dma_cookie_t *done, - dma_cookie_t *used) + struct dma_tx_state *txstate) { struct sh_dmae_chan *sh_chan = to_sh_chan(chan); dma_cookie_t last_used; @@ -754,11 +753,11 @@ static enum dma_status sh_dmae_is_complete(struct dma_chan *chan, last_complete = sh_chan->completed_cookie; BUG_ON(last_complete < 0); - if (done) - *done = last_complete; - - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } spin_lock_bh(&sh_chan->desc_lock); @@ -1030,7 +1029,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev) = sh_dmae_alloc_chan_resources; shdev->common.device_free_chan_resources = sh_dmae_free_chan_resources; shdev->common.device_prep_dma_memcpy = sh_dmae_prep_memcpy; - shdev->common.device_is_tx_complete = sh_dmae_is_complete; + shdev->common.device_tx_status = sh_dmae_tx_status; shdev->common.device_issue_pending = sh_dmae_memcpy_issue_pending; /* Compulsory for DMA_SLAVE fields */ diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index 7c06471ef863..8fc28814561a 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -511,8 +511,8 @@ static void td_free_chan_resources(struct dma_chan *chan) } } -static enum dma_status td_is_tx_complete(struct dma_chan *chan, - dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used) +static enum dma_status td_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct timb_dma_chan *td_chan = container_of(chan, struct timb_dma_chan, chan); @@ -527,10 +527,11 @@ static enum dma_status td_is_tx_complete(struct dma_chan *chan, ret = dma_async_is_complete(cookie, last_complete, last_used); - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } dev_dbg(chan2dev(chan), "%s: exit, ret: %d, last_complete: %d, last_used: %d\n", @@ -742,7 +743,7 @@ static int __devinit td_probe(struct platform_device *pdev) td->dma.device_alloc_chan_resources = td_alloc_chan_resources; td->dma.device_free_chan_resources = td_free_chan_resources; - td->dma.device_is_tx_complete = td_is_tx_complete; + td->dma.device_tx_status = td_tx_status; td->dma.device_issue_pending = td_issue_pending; dma_cap_set(DMA_SLAVE, td->dma.cap_mask); diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c index e528e15f44ab..a44e422cbc27 100644 --- a/drivers/dma/txx9dmac.c +++ b/drivers/dma/txx9dmac.c @@ -967,9 +967,8 @@ static int txx9dmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) } static enum dma_status -txx9dmac_is_tx_complete(struct dma_chan *chan, - dma_cookie_t cookie, - dma_cookie_t *done, dma_cookie_t *used) +txx9dmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + struct dma_tx_state *txstate) { struct txx9dmac_chan *dc = to_txx9dmac_chan(chan); dma_cookie_t last_used; @@ -991,10 +990,11 @@ txx9dmac_is_tx_complete(struct dma_chan *chan, ret = dma_async_is_complete(cookie, last_complete, last_used); } - if (done) - *done = last_complete; - if (used) - *used = last_used; + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = 0; + } return ret; } @@ -1160,7 +1160,7 @@ static int __init txx9dmac_chan_probe(struct platform_device *pdev) dc->dma.device_alloc_chan_resources = txx9dmac_alloc_chan_resources; dc->dma.device_free_chan_resources = txx9dmac_free_chan_resources; dc->dma.device_control = txx9dmac_control; - dc->dma.device_is_tx_complete = txx9dmac_is_tx_complete; + dc->dma.device_tx_status = txx9dmac_tx_status; dc->dma.device_issue_pending = txx9dmac_issue_pending; if (pdata && pdata->memcpy_chan == ch) { dc->dma.device_prep_dma_memcpy = txx9dmac_prep_dma_memcpy; diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 0731802f876f..55b08e84ac8d 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -40,11 +40,13 @@ typedef s32 dma_cookie_t; * enum dma_status - DMA transaction status * @DMA_SUCCESS: transaction completed successfully * @DMA_IN_PROGRESS: transaction not yet processed + * @DMA_PAUSED: transaction is paused * @DMA_ERROR: transaction failed */ enum dma_status { DMA_SUCCESS, DMA_IN_PROGRESS, + DMA_PAUSED, DMA_ERROR, }; @@ -248,6 +250,21 @@ struct dma_async_tx_descriptor { spinlock_t lock; }; +/** + * struct dma_tx_state - filled in to report the status of + * a transfer. + * @last: last completed DMA cookie + * @used: last issued DMA cookie (i.e. the one in progress) + * @residue: the remaining number of bytes left to transmit + * on the selected transfer for states DMA_IN_PROGRESS and + * DMA_PAUSED if this is implemented in the driver, else 0 + */ +struct dma_tx_state { + dma_cookie_t last; + dma_cookie_t used; + u32 residue; +}; + /** * struct dma_device - info on the entity supplying DMA services * @chancnt: how many DMA channels are supported @@ -276,7 +293,10 @@ struct dma_async_tx_descriptor { * @device_prep_slave_sg: prepares a slave dma operation * @device_control: manipulate all pending operations on a channel, returns * zero or error code - * @device_is_tx_complete: poll for transaction completion + * @device_tx_status: poll for transaction completion, the optional + * txstate parameter can be supplied with a pointer to get a + * struct with auxilary transfer status information, otherwise the call + * will just return a simple status code * @device_issue_pending: push pending transactions to hardware */ struct dma_device { @@ -329,9 +349,9 @@ struct dma_device { unsigned long flags); int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd cmd); - enum dma_status (*device_is_tx_complete)(struct dma_chan *chan, - dma_cookie_t cookie, dma_cookie_t *last, - dma_cookie_t *used); + enum dma_status (*device_tx_status)(struct dma_chan *chan, + dma_cookie_t cookie, + struct dma_tx_state *txstate); void (*device_issue_pending)(struct dma_chan *chan); }; @@ -572,7 +592,15 @@ static inline void dma_async_issue_pending(struct dma_chan *chan) static inline enum dma_status dma_async_is_tx_complete(struct dma_chan *chan, dma_cookie_t cookie, dma_cookie_t *last, dma_cookie_t *used) { - return chan->device->device_is_tx_complete(chan, cookie, last, used); + struct dma_tx_state state; + enum dma_status status; + + status = chan->device->device_tx_status(chan, cookie, &state); + if (last) + *last = state.last; + if (used) + *used = state.used; + return status; } #define dma_async_memcpy_complete(chan, cookie, last, used)\ -- cgit v1.2.3 From bca3469205402d9fb14060d255d8786ae2256640 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 26 Mar 2010 16:52:10 -0700 Subject: dmaengine: provide helper for setting txstate Simple conditional struct filler to cut out some duplicated code. Signed-off-by: Dan Williams --- drivers/dma/at_hdmac.c | 7 +------ drivers/dma/coh901318.c | 8 ++------ drivers/dma/dw_dmac.c | 6 +----- drivers/dma/fsldma.c | 6 +----- drivers/dma/ioat/dma.h | 6 +----- drivers/dma/iop-adma.c | 15 ++------------- drivers/dma/ipu/ipu_idmac.c | 6 +----- drivers/dma/mpc512x_dma.c | 7 +------ drivers/dma/mv_xor.c | 13 ++----------- drivers/dma/ppc4xx/adma.c | 12 ++---------- drivers/dma/shdma.c | 7 +------ drivers/dma/timb_dma.c | 6 +----- drivers/dma/txx9dmac.c | 6 +----- include/linux/dmaengine.h | 10 ++++++++++ 14 files changed, 27 insertions(+), 88 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index ff75cf18d32e..93ed99c84cf1 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -834,12 +834,7 @@ atc_tx_status(struct dma_chan *chan, spin_unlock_bh(&atchan->lock); - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } - + dma_set_tx_state(txstate, last_complete, last_used, 0); dev_vdbg(chan2dev(chan), "tx_status: %d (d%d, u%d)\n", cookie, last_complete ? last_complete : 0, last_used ? last_used : 0); diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index 309db3beef16..4233440741a2 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -1147,12 +1147,8 @@ coh901318_tx_status(struct dma_chan *chan, dma_cookie_t cookie, ret = dma_async_is_complete(cookie, last_complete, last_used); - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = coh901318_get_bytes_left(chan); - } - + dma_set_tx_state(txstate, last_complete, last_used, + coh901318_get_bytes_left(chan)); if (ret == DMA_IN_PROGRESS && cohc->stopped) ret = DMA_PAUSED; diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 263b70ee8562..18fb5b41cedf 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -841,11 +841,7 @@ dwc_tx_status(struct dma_chan *chan, ret = dma_async_is_complete(cookie, last_complete, last_used); } - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } + dma_set_tx_state(txstate, last_complete, last_used, 0); return ret; } diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index ca5e8a3dce72..cb1924f46c9e 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -987,11 +987,7 @@ static enum dma_status fsl_tx_status(struct dma_chan *dchan, last_used = dchan->cookie; last_complete = chan->completed_cookie; - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } + dma_set_tx_state(txstate, last_complete, last_used, 0); return dma_async_is_complete(cookie, last_complete, last_used); } diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index 23399672239e..26f48ef94c5c 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h @@ -158,11 +158,7 @@ ioat_tx_status(struct dma_chan *c, dma_cookie_t cookie, last_used = c->cookie; last_complete = chan->completed_cookie; - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } + dma_set_tx_state(txstate, last_complete, last_used, 0); return dma_async_is_complete(cookie, last_complete, last_used); } diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index ee40dbba1879..e5d4b97b7fd5 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c @@ -909,13 +909,7 @@ static enum dma_status iop_adma_status(struct dma_chan *chan, last_used = chan->cookie; last_complete = iop_chan->completed_cookie; - - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } - + dma_set_tx_state(txstate, last_complete, last_used, 0); ret = dma_async_is_complete(cookie, last_complete, last_used); if (ret == DMA_SUCCESS) return ret; @@ -924,12 +918,7 @@ static enum dma_status iop_adma_status(struct dma_chan *chan, last_used = chan->cookie; last_complete = iop_chan->completed_cookie; - - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } + dma_set_tx_state(txstate, last_complete, last_used, 0); return dma_async_is_complete(cookie, last_complete, last_used); } diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index b9cef8b1701c..246a6143e4a7 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1651,11 +1651,7 @@ static enum dma_status idmac_tx_status(struct dma_chan *chan, { struct idmac_channel *ichan = to_idmac_chan(chan); - if (txstate) { - txstate->last = ichan->completed; - txstate->used = chan->cookie; - txstate->residue = 0; - } + dma_set_tx_state(txstate, ichan->completed, chan->cookie, 0); if (cookie != chan->cookie) return DMA_ERROR; return DMA_SUCCESS; diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index cb3a8e94ea48..7a750b95303c 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -553,12 +553,7 @@ mpc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie, last_complete = mchan->completed_cookie; spin_unlock_irqrestore(&mchan->lock, flags); - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } - + dma_set_tx_state(txstate, last_complete, last_used, 0); return dma_async_is_complete(cookie, last_complete, last_used); } diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 79fb1dea691b..4b8c1fcc834d 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -826,11 +826,7 @@ static enum dma_status mv_xor_status(struct dma_chan *chan, last_used = chan->cookie; last_complete = mv_chan->completed_cookie; mv_chan->is_complete_cookie = cookie; - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } + dma_set_tx_state(txstate, last_complete, last_used, 0); ret = dma_async_is_complete(cookie, last_complete, last_used); if (ret == DMA_SUCCESS) { @@ -842,12 +838,7 @@ static enum dma_status mv_xor_status(struct dma_chan *chan, last_used = chan->cookie; last_complete = mv_chan->completed_cookie; - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } - + dma_set_tx_state(txstate, last_complete, last_used, 0); return dma_async_is_complete(cookie, last_complete, last_used); } diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index d9a54c018652..5558419876e8 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -3951,11 +3951,7 @@ static enum dma_status ppc440spe_adma_tx_status(struct dma_chan *chan, last_used = chan->cookie; last_complete = ppc440spe_chan->completed_cookie; - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } + dma_set_tx_state(txstate, last_complete, last_used, 0); ret = dma_async_is_complete(cookie, last_complete, last_used); if (ret == DMA_SUCCESS) @@ -3966,11 +3962,7 @@ static enum dma_status ppc440spe_adma_tx_status(struct dma_chan *chan, last_used = chan->cookie; last_complete = ppc440spe_chan->completed_cookie; - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } + dma_set_tx_state(txstate, last_complete, last_used, 0); return dma_async_is_complete(cookie, last_complete, last_used); } diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 8aeda9ceb225..98f82cdb404c 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -752,12 +752,7 @@ static enum dma_status sh_dmae_tx_status(struct dma_chan *chan, last_used = chan->cookie; last_complete = sh_chan->completed_cookie; BUG_ON(last_complete < 0); - - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } + dma_set_tx_state(txstate, last_complete, last_used, 0); spin_lock_bh(&sh_chan->desc_lock); diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index 8fc28814561a..e20d5c1fa213 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -527,11 +527,7 @@ static enum dma_status td_tx_status(struct dma_chan *chan, dma_cookie_t cookie, ret = dma_async_is_complete(cookie, last_complete, last_used); - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } + dma_set_tx_state(txstate, last_complete, last_used, 0); dev_dbg(chan2dev(chan), "%s: exit, ret: %d, last_complete: %d, last_used: %d\n", diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c index a44e422cbc27..e523737639aa 100644 --- a/drivers/dma/txx9dmac.c +++ b/drivers/dma/txx9dmac.c @@ -990,11 +990,7 @@ txx9dmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, ret = dma_async_is_complete(cookie, last_complete, last_used); } - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = 0; - } + dma_set_tx_state(txstate, last_complete, last_used, 0); return ret; } diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 55b08e84ac8d..50b7b3e0d572 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -628,6 +628,16 @@ static inline enum dma_status dma_async_is_complete(dma_cookie_t cookie, return DMA_IN_PROGRESS; } +static inline void +dma_set_tx_state(struct dma_tx_state *st, dma_cookie_t last, dma_cookie_t used, u32 residue) +{ + if (st) { + st->last = last; + st->used = used; + st->residue = residue; + } +} + enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie); #ifdef CONFIG_DMA_ENGINE enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx); -- cgit v1.2.3 From 6a3cd3ea48584d14f60dce0b3c4e9e4428beb0fe Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 29 Mar 2010 15:54:40 +1100 Subject: async_tx: use of kzalloc/kfree requires the include of slab.h Signed-off-by: Stephen Rothwell Signed-off-by: Dan Williams --- drivers/dma/timb_dma.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index e20d5c1fa213..44b346d8d319 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -27,6 +27,7 @@ #include #include #include +#include #include -- cgit v1.2.3 From 6ad95513d60096b569e4e4bd721420f03b57e4d4 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 11 Mar 2010 12:20:06 -0700 Subject: ACPI: pci_root: save downstream bus range Previously, we only saved the root bus number, i.e., the beginning of the downstream bus range. We now support IORESOURCE_BUS resources, so this patch uses that to keep track of both the beginning and the end of the downstream bus range. It's important to know both the beginning and the end for supporting _CBA (see PCI Firmware spec, rev 3.0, sec 4.1.3) and so we know the limits for any possible PCI bus renumbering (we can't renumber downstream buses to be outside the bus number range claimed by the host bridge). It's clear from the spec that the bus range is supposed to be in _CRS, but if we don't find it there, we'll assume [_BBN - 0xFF] or [0 - 0xFF]. Signed-off-by: Bjorn Helgaas Reviewed-by: Kenji Kaneshige Signed-off-by: Len Brown --- drivers/acpi/pci_root.c | 67 +++++++++++++++++++++++++++++-------------------- include/acpi/acpi_bus.h | 2 +- 2 files changed, 41 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index d724736d56c8..bf476fea97ab 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -119,7 +119,8 @@ acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) struct acpi_pci_root *root; list_for_each_entry(root, &acpi_pci_roots, node) - if ((root->segment == (u16) seg) && (root->bus_nr == (u16) bus)) + if ((root->segment == (u16) seg) && + (root->secondary.start == (u16) bus)) return root->device->handle; return NULL; } @@ -153,7 +154,7 @@ EXPORT_SYMBOL_GPL(acpi_is_root_bridge); static acpi_status get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) { - int *busnr = data; + struct resource *res = data; struct acpi_resource_address64 address; if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && @@ -163,28 +164,27 @@ get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) acpi_resource_to_address64(resource, &address); if ((address.address_length > 0) && - (address.resource_type == ACPI_BUS_NUMBER_RANGE)) - *busnr = address.minimum; + (address.resource_type == ACPI_BUS_NUMBER_RANGE)) { + res->start = address.minimum; + res->end = address.minimum + address.address_length - 1; + } return AE_OK; } static acpi_status try_get_root_bridge_busnr(acpi_handle handle, - unsigned long long *bus) + struct resource *res) { acpi_status status; - int busnum; - busnum = -1; + res->start = -1; status = acpi_walk_resources(handle, METHOD_NAME__CRS, - get_root_bridge_busnr_callback, &busnum); + get_root_bridge_busnr_callback, res); if (ACPI_FAILURE(status)) return status; - /* Check if we really get a bus number from _CRS */ - if (busnum == -1) + if (res->start == -1) return AE_ERROR; - *bus = busnum; return AE_OK; } @@ -428,34 +428,47 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) struct acpi_device *child; u32 flags, base_flags; + root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); + if (!root) + return -ENOMEM; + segment = 0; status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL, &segment); if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { printk(KERN_ERR PREFIX "can't evaluate _SEG\n"); - return -ENODEV; + result = -ENODEV; + goto end; } /* Check _CRS first, then _BBN. If no _BBN, default to zero. */ - bus = 0; - status = try_get_root_bridge_busnr(device->handle, &bus); + root->secondary.flags = IORESOURCE_BUS; + status = try_get_root_bridge_busnr(device->handle, &root->secondary); if (ACPI_FAILURE(status)) { + /* + * We need both the start and end of the downstream bus range + * to interpret _CBA (MMCONFIG base address), so it really is + * supposed to be in _CRS. If we don't find it there, all we + * can do is assume [_BBN-0xFF] or [0-0xFF]. + */ + root->secondary.end = 0xFF; + printk(KERN_WARNING FW_BUG PREFIX + "no secondary bus range in _CRS\n"); status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus); - if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - printk(KERN_ERR PREFIX - "no bus number in _CRS and can't evaluate _BBN\n"); - return -ENODEV; + if (ACPI_SUCCESS(status)) + root->secondary.start = bus; + else if (status == AE_NOT_FOUND) + root->secondary.start = 0; + else { + printk(KERN_ERR PREFIX "can't evaluate _BBN\n"); + result = -ENODEV; + goto end; } } - root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); - if (!root) - return -ENOMEM; - INIT_LIST_HEAD(&root->node); root->device = device; root->segment = segment & 0xFFFF; - root->bus_nr = bus & 0xFF; strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); device->driver_data = root; @@ -474,9 +487,9 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) /* TBD: Locking */ list_add_tail(&root->node, &acpi_pci_roots); - printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n", + printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n", acpi_device_name(device), acpi_device_bid(device), - root->segment, root->bus_nr); + root->segment, &root->secondary); /* * Scan the Root Bridge @@ -485,11 +498,11 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) * PCI namespace does not get created until this call is made (and * thus the root bridge's pci_dev does not exist). */ - root->bus = pci_acpi_scan_root(device, segment, bus); + root->bus = pci_acpi_scan_root(device, segment, root->secondary.start); if (!root->bus) { printk(KERN_ERR PREFIX "Bus %04x:%02x not present in PCI namespace\n", - root->segment, root->bus_nr); + root->segment, (unsigned int)root->secondary.start); result = -ENODEV; goto end; } diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 7bf83ddf82e0..baacd98e7cc6 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -373,7 +373,7 @@ struct acpi_pci_root { struct acpi_pci_id id; struct pci_bus *bus; u16 segment; - u8 bus_nr; + struct resource secondary; /* downstream bus range */ u32 osc_support_set; /* _OSC state of support bits */ u32 osc_control_set; /* _OSC state of control bits */ -- cgit v1.2.3 From 57283776b2b821ba4d592f61cad04d0293412740 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 11 Mar 2010 12:20:11 -0700 Subject: ACPI: pci_root: pass acpi_pci_root to arch-specific scan The acpi_pci_root structure contains all the individual items (acpi_device, domain, bus number) we pass to pci_acpi_scan_root(), so just pass the single acpi_pci_root pointer directly. This will make it easier to add _CBA support later. For _CBA, we need the entire downstream bus range, not just the base bus number. We have that in the acpi_pci_root structure, so passing the pointer makes it available to the arch-specific code. Signed-off-by: Bjorn Helgaas Reviewed-by: Kenji Kaneshige Signed-off-by: Len Brown --- arch/ia64/pci/pci.c | 5 ++++- arch/x86/pci/acpi.c | 5 ++++- drivers/acpi/pci_root.c | 2 +- include/acpi/acpi_drivers.h | 3 +-- 4 files changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 64aff520b899..aa2533ae7e9e 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -335,8 +335,11 @@ pcibios_setup_root_windows(struct pci_bus *bus, struct pci_controller *ctrl) } struct pci_bus * __devinit -pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) +pci_acpi_scan_root(struct acpi_pci_root *root) { + struct acpi_device *device = root->device; + int domain = root->segment; + int bus = root->secondary.start; struct pci_controller *controller; unsigned int windows = 0; struct pci_bus *pbus; diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index e31160216efb..0b7882dbe784 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -229,8 +229,11 @@ res_alloc_fail: return; } -struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int domain, int busnum) +struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) { + struct acpi_device *device = root->device; + int domain = root->segment; + int busnum = root->secondary.start; struct pci_bus *bus; struct pci_sysdata *sd; int node; diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index bf476fea97ab..680450c905b3 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -498,7 +498,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) * PCI namespace does not get created until this call is made (and * thus the root bridge's pci_dev does not exist). */ - root->bus = pci_acpi_scan_root(device, segment, root->secondary.start); + root->bus = pci_acpi_scan_root(root); if (!root->bus) { printk(KERN_ERR PREFIX "Bus %04x:%02x not present in PCI namespace\n", diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index 4f7b44866b76..23d78b4d088b 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h @@ -104,8 +104,7 @@ int acpi_pci_bind_root(struct acpi_device *device); /* Arch-defined function to add a bus to the system */ -struct pci_bus *pci_acpi_scan_root(struct acpi_device *device, int domain, - int bus); +struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root); void pci_acpi_crs_quirks(void); /* -------------------------------------------------------------------------- -- cgit v1.2.3 From a009d29ea104c1bd8805a20018469897c2c2263c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 1 Apr 2010 12:27:44 +0200 Subject: ds2782_battery: Fix clientdata on removal Probably due to a copy & paste bug, clientdata was set again to the data structure (which is freed immediately afterwards) when it should be NULLed. Just remove the calls as the i2c-core does this automatically now. Signed-off-by: Wolfram Sang Cc: Ryan Mallon Cc: Hans Verkuil Cc: Jean Delvare Signed-off-by: Anton Vorontsov --- drivers/power/ds2782_battery.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/power/ds2782_battery.c b/drivers/power/ds2782_battery.c index da14f374cb60..305d463a880c 100644 --- a/drivers/power/ds2782_battery.c +++ b/drivers/power/ds2782_battery.c @@ -236,8 +236,6 @@ static int ds2782_battery_remove(struct i2c_client *client) idr_remove(&battery_id, info->id); mutex_unlock(&battery_lock); - i2c_set_clientdata(client, info); - kfree(info); return 0; } @@ -289,7 +287,6 @@ static int ds2782_battery_probe(struct i2c_client *client, fail_register: kfree(info->battery.name); fail_name: - i2c_set_clientdata(client, info); kfree(info); fail_info: mutex_lock(&battery_lock); -- cgit v1.2.3 From e3e8d1c93f9e6b766424b05f23f2416f22a0329d Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 28 Feb 2010 12:47:49 +0100 Subject: Driver for Zipit Z2 battery chip This patch adds driver for Zipit Z2 battery chip called AER915. No details are known about the chip. The chip is available through I2C bus at address 0x55 and it's register 0x02 contains battery voltage. Signed-off-by: Marek Vasut Signed-off-by: Anton Vorontsov --- drivers/power/Kconfig | 6 + drivers/power/Makefile | 1 + drivers/power/z2_battery.c | 328 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/z2_battery.h | 17 +++ 4 files changed, 352 insertions(+) create mode 100644 drivers/power/z2_battery.c create mode 100644 include/linux/z2_battery.h (limited to 'drivers') diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index faaa9b4d0d07..22f2fa912127 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -125,6 +125,12 @@ config BATTERY_MAX17040 in handheld and portable equipment. The MAX17040 is configured to operate with a single lithium cell +config BATTERY_Z2 + tristate "Z2 battery driver" + depends on I2C && MACH_ZIPIT2 + help + Say Y to include support for the battery on the Zipit Z2. + config CHARGER_PCF50633 tristate "NXP PCF50633 MBC" depends on MFD_PCF50633 diff --git a/drivers/power/Makefile b/drivers/power/Makefile index a2ba7c85c97a..a82f292e5c94 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -31,4 +31,5 @@ obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o +obj-$(CONFIG_BATTERY_Z2) += z2_battery.o obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o diff --git a/drivers/power/z2_battery.c b/drivers/power/z2_battery.c new file mode 100644 index 000000000000..9cca465436e3 --- /dev/null +++ b/drivers/power/z2_battery.c @@ -0,0 +1,328 @@ +/* + * Battery measurement code for Zipit Z2 + * + * Copyright (C) 2009 Peter Edwards + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define Z2_DEFAULT_NAME "Z2" + +struct z2_charger { + struct z2_battery_info *info; + int bat_status; + struct i2c_client *client; + struct power_supply batt_ps; + struct mutex work_lock; + struct work_struct bat_work; +}; + +static unsigned long z2_read_bat(struct z2_charger *charger) +{ + int data; + data = i2c_smbus_read_byte_data(charger->client, + charger->info->batt_I2C_reg); + if (data < 0) + return 0; + + return data * charger->info->batt_mult / charger->info->batt_div; +} + +static int z2_batt_get_property(struct power_supply *batt_ps, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct z2_charger *charger = container_of(batt_ps, struct z2_charger, + batt_ps); + struct z2_battery_info *info = charger->info; + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + val->intval = charger->bat_status; + break; + case POWER_SUPPLY_PROP_TECHNOLOGY: + val->intval = info->batt_tech; + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + if (info->batt_I2C_reg >= 0) + val->intval = z2_read_bat(charger); + else + return -EINVAL; + break; + case POWER_SUPPLY_PROP_VOLTAGE_MAX: + if (info->max_voltage >= 0) + val->intval = info->max_voltage; + else + return -EINVAL; + break; + case POWER_SUPPLY_PROP_VOLTAGE_MIN: + if (info->min_voltage >= 0) + val->intval = info->min_voltage; + else + return -EINVAL; + break; + case POWER_SUPPLY_PROP_PRESENT: + val->intval = 1; + break; + default: + return -EINVAL; + } + + return 0; +} + +static void z2_batt_ext_power_changed(struct power_supply *batt_ps) +{ + struct z2_charger *charger = container_of(batt_ps, struct z2_charger, + batt_ps); + schedule_work(&charger->bat_work); +} + +static void z2_batt_update(struct z2_charger *charger) +{ + int old_status = charger->bat_status; + struct z2_battery_info *info; + + info = charger->info; + + mutex_lock(&charger->work_lock); + + charger->bat_status = (info->charge_gpio >= 0) ? + (gpio_get_value(info->charge_gpio) ? + POWER_SUPPLY_STATUS_CHARGING : + POWER_SUPPLY_STATUS_DISCHARGING) : + POWER_SUPPLY_STATUS_UNKNOWN; + + if (old_status != charger->bat_status) { + pr_debug("%s: %i -> %i\n", charger->batt_ps.name, old_status, + charger->bat_status); + power_supply_changed(&charger->batt_ps); + } + + mutex_unlock(&charger->work_lock); +} + +static void z2_batt_work(struct work_struct *work) +{ + struct z2_charger *charger; + charger = container_of(work, struct z2_charger, bat_work); + z2_batt_update(charger); +} + +static irqreturn_t z2_charge_switch_irq(int irq, void *devid) +{ + struct z2_charger *charger = devid; + schedule_work(&charger->bat_work); + return IRQ_HANDLED; +} + +static int z2_batt_ps_init(struct z2_charger *charger, int props) +{ + int i = 0; + enum power_supply_property *prop; + struct z2_battery_info *info = charger->info; + + if (info->batt_tech >= 0) + props++; /* POWER_SUPPLY_PROP_TECHNOLOGY */ + if (info->batt_I2C_reg >= 0) + props++; /* POWER_SUPPLY_PROP_VOLTAGE_NOW */ + if (info->max_voltage >= 0) + props++; /* POWER_SUPPLY_PROP_VOLTAGE_MAX */ + if (info->min_voltage >= 0) + props++; /* POWER_SUPPLY_PROP_VOLTAGE_MIN */ + + prop = kzalloc(props * sizeof(*prop), GFP_KERNEL); + if (!prop) + return -ENOMEM; + + prop[i++] = POWER_SUPPLY_PROP_PRESENT; + if (info->charge_gpio >= 0) + prop[i++] = POWER_SUPPLY_PROP_STATUS; + if (info->batt_tech >= 0) + prop[i++] = POWER_SUPPLY_PROP_TECHNOLOGY; + if (info->batt_I2C_reg >= 0) + prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_NOW; + if (info->max_voltage >= 0) + prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_MAX; + if (info->min_voltage >= 0) + prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_MIN; + + if (!info->batt_name) { + dev_info(&charger->client->dev, + "Please consider setting proper battery " + "name in platform definition file, falling " + "back to name \" Z2_DEFAULT_NAME \"\n"); + charger->batt_ps.name = Z2_DEFAULT_NAME; + } else + charger->batt_ps.name = info->batt_name; + + charger->batt_ps.properties = prop; + charger->batt_ps.num_properties = props; + charger->batt_ps.type = POWER_SUPPLY_TYPE_BATTERY; + charger->batt_ps.get_property = z2_batt_get_property; + charger->batt_ps.external_power_changed = z2_batt_ext_power_changed; + charger->batt_ps.use_for_apm = 1; + + return 0; +} + +static int __devinit z2_batt_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret = 0; + int props = 1; /* POWER_SUPPLY_PROP_PRESENT */ + struct z2_charger *charger; + struct z2_battery_info *info = client->dev.platform_data; + + if (info == NULL) { + dev_err(&client->dev, + "Please set platform device platform_data" + " to a valid z2_battery_info pointer!\n"); + return -EINVAL; + } + + charger = kzalloc(sizeof(*charger), GFP_KERNEL); + if (charger == NULL) + return -ENOMEM; + + charger->bat_status = POWER_SUPPLY_STATUS_UNKNOWN; + charger->info = info; + charger->client = client; + i2c_set_clientdata(client, charger); + + mutex_init(&charger->work_lock); + + if (info->charge_gpio >= 0 && gpio_is_valid(info->charge_gpio)) { + ret = gpio_request(info->charge_gpio, "BATT CHRG"); + if (ret) + goto err; + + ret = gpio_direction_input(info->charge_gpio); + if (ret) + goto err2; + + set_irq_type(gpio_to_irq(info->charge_gpio), + IRQ_TYPE_EDGE_BOTH); + ret = request_irq(gpio_to_irq(info->charge_gpio), + z2_charge_switch_irq, IRQF_DISABLED, + "AC Detect", charger); + if (ret) + goto err3; + } + + ret = z2_batt_ps_init(charger, props); + if (ret) + goto err3; + + INIT_WORK(&charger->bat_work, z2_batt_work); + + ret = power_supply_register(&client->dev, &charger->batt_ps); + if (ret) + goto err4; + + schedule_work(&charger->bat_work); + + return 0; + +err4: + kfree(charger->batt_ps.properties); +err3: + if (info->charge_gpio >= 0 && gpio_is_valid(info->charge_gpio)) + free_irq(gpio_to_irq(info->charge_gpio), charger); +err2: + if (info->charge_gpio >= 0 && gpio_is_valid(info->charge_gpio)) + gpio_free(info->charge_gpio); +err: + kfree(charger); + return ret; +} + +static int __devexit z2_batt_remove(struct i2c_client *client) +{ + struct z2_charger *charger = i2c_get_clientdata(client); + struct z2_battery_info *info = charger->info; + + flush_scheduled_work(); + power_supply_unregister(&charger->batt_ps); + + kfree(charger->batt_ps.properties); + if (info->charge_gpio >= 0 && gpio_is_valid(info->charge_gpio)) { + free_irq(gpio_to_irq(info->charge_gpio), charger); + gpio_free(info->charge_gpio); + } + + kfree(charger); + + return 0; +} + +#ifdef CONFIG_PM +static int z2_batt_suspend(struct i2c_client *client, pm_message_t state) +{ + flush_scheduled_work(); + return 0; +} + +static int z2_batt_resume(struct i2c_client *client) +{ + struct z2_charger *charger = i2c_get_clientdata(client); + + schedule_work(&charger->bat_work); + return 0; +} +#else +#define z2_batt_suspend NULL +#define z2_batt_resume NULL +#endif + +static const struct i2c_device_id z2_batt_id[] = { + { "aer915", 0 }, + { } +}; + +static struct i2c_driver z2_batt_driver = { + .driver = { + .name = "z2-battery", + .owner = THIS_MODULE, + }, + .probe = z2_batt_probe, + .remove = z2_batt_remove, + .suspend = z2_batt_suspend, + .resume = z2_batt_resume, + .id_table = z2_batt_id, +}; + +static int __init z2_batt_init(void) +{ + return i2c_add_driver(&z2_batt_driver); +} + +static void __exit z2_batt_exit(void) +{ + i2c_del_driver(&z2_batt_driver); +} + +module_init(z2_batt_init); +module_exit(z2_batt_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Peter Edwards "); +MODULE_DESCRIPTION("Zipit Z2 battery driver"); diff --git a/include/linux/z2_battery.h b/include/linux/z2_battery.h new file mode 100644 index 000000000000..7b9750404d22 --- /dev/null +++ b/include/linux/z2_battery.h @@ -0,0 +1,17 @@ +#ifndef _LINUX_Z2_BATTERY_H +#define _LINUX_Z2_BATTERY_H + +struct z2_battery_info { + int batt_I2C_bus; + int batt_I2C_addr; + int batt_I2C_reg; + int charge_gpio; + int min_voltage; + int max_voltage; + int batt_div; + int batt_mult; + int batt_tech; + char *batt_name; +}; + +#endif -- cgit v1.2.3 From b5874f33bbaf00586d05de37706491ee37057e11 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 10 Mar 2010 18:27:40 +0000 Subject: wm831x_power: Use genirq Since the WM831x core has been converted to use genirq for the interrupt controller there is no longer any need for chip specific wrappers for IRQ operations. Convert to use genirq directly. Signed-off-by: Mark Brown Signed-off-by: Anton Vorontsov --- drivers/power/wm831x_power.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c index f85e80b1b400..bf2ff4132478 100644 --- a/drivers/power/wm831x_power.c +++ b/drivers/power/wm831x_power.c @@ -536,9 +536,9 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev) goto err_battery; irq = platform_get_irq_byname(pdev, "SYSLO"); - ret = wm831x_request_irq(wm831x, irq, wm831x_syslo_irq, - IRQF_TRIGGER_RISING, "SYSLO", - power); + ret = request_threaded_irq(irq, NULL, wm831x_syslo_irq, + IRQF_TRIGGER_RISING, "System power low", + power); if (ret != 0) { dev_err(&pdev->dev, "Failed to request SYSLO IRQ %d: %d\n", irq, ret); @@ -546,9 +546,9 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev) } irq = platform_get_irq_byname(pdev, "PWR SRC"); - ret = wm831x_request_irq(wm831x, irq, wm831x_pwr_src_irq, - IRQF_TRIGGER_RISING, "Power source", - power); + ret = request_threaded_irq(irq, NULL, wm831x_pwr_src_irq, + IRQF_TRIGGER_RISING, "Power source", + power); if (ret != 0) { dev_err(&pdev->dev, "Failed to request PWR SRC IRQ %d: %d\n", irq, ret); @@ -557,10 +557,10 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev) for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) { irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]); - ret = wm831x_request_irq(wm831x, irq, wm831x_bat_irq, - IRQF_TRIGGER_RISING, - wm831x_bat_irqs[i], - power); + ret = request_threaded_irq(irq, NULL, wm831x_bat_irq, + IRQF_TRIGGER_RISING, + wm831x_bat_irqs[i], + power); if (ret != 0) { dev_err(&pdev->dev, "Failed to request %s IRQ %d: %d\n", @@ -574,13 +574,13 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev) err_bat_irq: for (; i >= 0; i--) { irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]); - wm831x_free_irq(wm831x, irq, power); + free_irq(irq, power); } irq = platform_get_irq_byname(pdev, "PWR SRC"); - wm831x_free_irq(wm831x, irq, power); + free_irq(irq, power); err_syslo: irq = platform_get_irq_byname(pdev, "SYSLO"); - wm831x_free_irq(wm831x, irq, power); + free_irq(irq, power); err_usb: power_supply_unregister(usb); err_battery: @@ -595,19 +595,18 @@ err_kmalloc: static __devexit int wm831x_power_remove(struct platform_device *pdev) { struct wm831x_power *wm831x_power = platform_get_drvdata(pdev); - struct wm831x *wm831x = wm831x_power->wm831x; int irq, i; for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) { irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]); - wm831x_free_irq(wm831x, irq, wm831x_power); + free_irq(irq, wm831x_power); } irq = platform_get_irq_byname(pdev, "PWR SRC"); - wm831x_free_irq(wm831x, irq, wm831x_power); + free_irq(irq, wm831x_power); irq = platform_get_irq_byname(pdev, "SYSLO"); - wm831x_free_irq(wm831x, irq, wm831x_power); + free_irq(irq, wm831x_power); power_supply_unregister(&wm831x_power->battery); power_supply_unregister(&wm831x_power->wall); -- cgit v1.2.3 From a45946abb8991e17c39326854ed1314d20742ca6 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Thu, 11 Mar 2010 14:04:08 -0800 Subject: intel-iommu: use for_each_set_bit() Replace open-coded loop with for_each_set_bit(). Signed-off-by: Akinobu Mita Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/pci/intel-iommu.c | 33 +++++++-------------------------- 1 file changed, 7 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 417312528ddf..a0ac7197ffdd 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -491,13 +491,11 @@ static void domain_update_iommu_coherency(struct dmar_domain *domain) domain->iommu_coherency = 1; - i = find_first_bit(&domain->iommu_bmp, g_num_of_iommus); - for (; i < g_num_of_iommus; ) { + for_each_set_bit(i, &domain->iommu_bmp, g_num_of_iommus) { if (!ecap_coherent(g_iommus[i]->ecap)) { domain->iommu_coherency = 0; break; } - i = find_next_bit(&domain->iommu_bmp, g_num_of_iommus, i+1); } } @@ -507,13 +505,11 @@ static void domain_update_iommu_snooping(struct dmar_domain *domain) domain->iommu_snooping = 1; - i = find_first_bit(&domain->iommu_bmp, g_num_of_iommus); - for (; i < g_num_of_iommus; ) { + for_each_set_bit(i, &domain->iommu_bmp, g_num_of_iommus) { if (!ecap_sc_support(g_iommus[i]->ecap)) { domain->iommu_snooping = 0; break; } - i = find_next_bit(&domain->iommu_bmp, g_num_of_iommus, i+1); } } @@ -1194,8 +1190,7 @@ void free_dmar_iommu(struct intel_iommu *iommu) unsigned long flags; if ((iommu->domains) && (iommu->domain_ids)) { - i = find_first_bit(iommu->domain_ids, cap_ndoms(iommu->cap)); - for (; i < cap_ndoms(iommu->cap); ) { + for_each_set_bit(i, iommu->domain_ids, cap_ndoms(iommu->cap)) { domain = iommu->domains[i]; clear_bit(i, iommu->domain_ids); @@ -1207,9 +1202,6 @@ void free_dmar_iommu(struct intel_iommu *iommu) domain_exit(domain); } spin_unlock_irqrestore(&domain->iommu_lock, flags); - - i = find_next_bit(iommu->domain_ids, - cap_ndoms(iommu->cap), i+1); } } @@ -1292,14 +1284,11 @@ static void iommu_detach_domain(struct dmar_domain *domain, spin_lock_irqsave(&iommu->lock, flags); ndomains = cap_ndoms(iommu->cap); - num = find_first_bit(iommu->domain_ids, ndomains); - for (; num < ndomains; ) { + for_each_set_bit(num, iommu->domain_ids, ndomains) { if (iommu->domains[num] == domain) { found = 1; break; } - num = find_next_bit(iommu->domain_ids, - cap_ndoms(iommu->cap), num+1); } if (found) { @@ -1485,15 +1474,12 @@ static int domain_context_mapping_one(struct dmar_domain *domain, int segment, /* find an available domain id for this device in iommu */ ndomains = cap_ndoms(iommu->cap); - num = find_first_bit(iommu->domain_ids, ndomains); - for (; num < ndomains; ) { + for_each_set_bit(num, iommu->domain_ids, ndomains) { if (iommu->domains[num] == domain) { id = num; found = 1; break; } - num = find_next_bit(iommu->domain_ids, - cap_ndoms(iommu->cap), num+1); } if (found == 0) { @@ -3441,12 +3427,9 @@ static int vm_domain_min_agaw(struct dmar_domain *domain) int i; int min_agaw = domain->agaw; - i = find_first_bit(&domain->iommu_bmp, g_num_of_iommus); - for (; i < g_num_of_iommus; ) { + for_each_set_bit(i, &domain->iommu_bmp, g_num_of_iommus) { if (min_agaw > g_iommus[i]->agaw) min_agaw = g_iommus[i]->agaw; - - i = find_next_bit(&domain->iommu_bmp, g_num_of_iommus, i+1); } return min_agaw; @@ -3512,8 +3495,7 @@ static void iommu_free_vm_domain(struct dmar_domain *domain) iommu = drhd->iommu; ndomains = cap_ndoms(iommu->cap); - i = find_first_bit(iommu->domain_ids, ndomains); - for (; i < ndomains; ) { + for_each_set_bit(i, iommu->domain_ids, ndomains) { if (iommu->domains[i] == domain) { spin_lock_irqsave(&iommu->lock, flags); clear_bit(i, iommu->domain_ids); @@ -3521,7 +3503,6 @@ static void iommu_free_vm_domain(struct dmar_domain *domain) spin_unlock_irqrestore(&iommu->lock, flags); break; } - i = find_next_bit(iommu->domain_ids, ndomains, i+1); } } } -- cgit v1.2.3 From 8bdd77dd4ef99292f3d705c4c389c12f55641133 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Thu, 1 Apr 2010 13:24:35 +0300 Subject: intel-iommu mistakenly uses offset_pfn when caching mode is enabled intel_map_sg used offset_pfn which was set to zero when invalidating the IOTLB. intel_map_sg now uses size variable for this matter. Signed-off-by: Nadav Amit Signed-off-by: David Woodhouse --- drivers/pci/intel-iommu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index a0ac7197ffdd..341da41cde8b 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -2860,7 +2860,6 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne struct dmar_domain *domain; size_t size = 0; int prot = 0; - size_t offset_pfn = 0; struct iova *iova = NULL; int ret; struct scatterlist *sg; @@ -2914,7 +2913,7 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne /* it's a non-present to present mapping. Only flush if caching mode */ if (cap_caching_mode(iommu->cap)) - iommu_flush_iotlb_psi(iommu, 0, start_vpfn, offset_pfn); + iommu_flush_iotlb_psi(iommu, 0, start_vpfn, size); else iommu_flush_write_buffer(iommu); -- cgit v1.2.3 From 82653633b6161cdecc011d15bc9df1c7489bd9a2 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Thu, 1 Apr 2010 13:24:40 +0300 Subject: intel-iommu: Use correct domain ID when caching mode is enabled In caching-mode mappings of pages (changes from non-present to present) require invalidation. Currently, this IOTLB flush is performed with domain ID of zero. This is not according to the VT-d spec and causes big problems for emulating software. This patch uses the correct domain ID in IOTLB flushes. Device IOTLB invalidation is performed only on present to non-present changes. This decision is now based on explicit parameter instead of zero domain-ID. Signed-off-by: Nadav Amit Signed-off-by: David Woodhouse --- drivers/pci/intel-iommu.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 341da41cde8b..1880ee06d701 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -1064,7 +1064,7 @@ static void iommu_flush_dev_iotlb(struct dmar_domain *domain, } static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did, - unsigned long pfn, unsigned int pages) + unsigned long pfn, unsigned int pages, int map) { unsigned int mask = ilog2(__roundup_pow_of_two(pages)); uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT; @@ -1085,10 +1085,10 @@ static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did, DMA_TLB_PSI_FLUSH); /* - * In caching mode, domain ID 0 is reserved for non-present to present - * mapping flush. Device IOTLB doesn't need to be flushed in this case. + * In caching mode, changes of pages from non-present to present require + * flush. However, device IOTLB doesn't need to be flushed in this case. */ - if (!cap_caching_mode(iommu->cap) || did) + if (!cap_caching_mode(iommu->cap) || !map) iommu_flush_dev_iotlb(iommu->domains[did], addr, mask); } @@ -1544,7 +1544,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain, int segment, (((u16)bus) << 8) | devfn, DMA_CCMD_MASK_NOBIT, DMA_CCMD_DEVICE_INVL); - iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_DSI_FLUSH); + iommu->flush.flush_iotlb(iommu, domain->id, 0, 0, DMA_TLB_DSI_FLUSH); } else { iommu_flush_write_buffer(iommu); } @@ -2607,7 +2607,7 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, /* it's a non-present to present mapping. Only flush if caching mode */ if (cap_caching_mode(iommu->cap)) - iommu_flush_iotlb_psi(iommu, 0, mm_to_dma_pfn(iova->pfn_lo), size); + iommu_flush_iotlb_psi(iommu, domain->id, mm_to_dma_pfn(iova->pfn_lo), size, 1); else iommu_flush_write_buffer(iommu); @@ -2736,7 +2736,7 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr, if (intel_iommu_strict) { iommu_flush_iotlb_psi(iommu, domain->id, start_pfn, - last_pfn - start_pfn + 1); + last_pfn - start_pfn + 1, 0); /* free iova */ __free_iova(&domain->iovad, iova); } else { @@ -2826,7 +2826,7 @@ static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist, if (intel_iommu_strict) { iommu_flush_iotlb_psi(iommu, domain->id, start_pfn, - last_pfn - start_pfn + 1); + last_pfn - start_pfn + 1, 0); /* free iova */ __free_iova(&domain->iovad, iova); } else { @@ -2913,7 +2913,7 @@ static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int ne /* it's a non-present to present mapping. Only flush if caching mode */ if (cap_caching_mode(iommu->cap)) - iommu_flush_iotlb_psi(iommu, 0, start_vpfn, size); + iommu_flush_iotlb_psi(iommu, domain->id, start_vpfn, size, 1); else iommu_flush_write_buffer(iommu); -- cgit v1.2.3 From 78d5f0f500e6ba8f6cfd0673475ff4d941d705a2 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Thu, 8 Apr 2010 23:00:41 +0300 Subject: intel-iommu: Avoid global flushes with caching mode. While it may be efficient on real hardware, emulation of global invalidations is very expensive as all shadow entries must be examined. This patch changes the behaviour when caching mode is enabled (which is the case when IOMMU emulation takes place). In this case, page specific invalidation is used instead. Signed-off-by: Nadav Amit Signed-off-by: David Woodhouse --- drivers/pci/intel-iommu.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 1880ee06d701..9ce79b1bae83 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -2647,15 +2647,24 @@ static void flush_unmaps(void) if (!deferred_flush[i].next) continue; - iommu->flush.flush_iotlb(iommu, 0, 0, 0, + /* In caching mode, global flushes turn emulation expensive */ + if (!cap_caching_mode(iommu->cap)) + iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH); for (j = 0; j < deferred_flush[i].next; j++) { unsigned long mask; struct iova *iova = deferred_flush[i].iova[j]; - - mask = ilog2(mm_to_dma_pfn(iova->pfn_hi - iova->pfn_lo + 1)); - iommu_flush_dev_iotlb(deferred_flush[i].domain[j], - (uint64_t)iova->pfn_lo << PAGE_SHIFT, mask); + struct dmar_domain *domain = deferred_flush[i].domain[j]; + + /* On real hardware multiple invalidations are expensive */ + if (cap_caching_mode(iommu->cap)) + iommu_flush_iotlb_psi(iommu, domain->id, + iova->pfn_lo, iova->pfn_hi - iova->pfn_lo + 1, 0); + else { + mask = ilog2(mm_to_dma_pfn(iova->pfn_hi - iova->pfn_lo + 1)); + iommu_flush_dev_iotlb(deferred_flush[i].domain[j], + (uint64_t)iova->pfn_lo << PAGE_SHIFT, mask); + } __free_iova(&deferred_flush[i].domain[j]->iovad, iova); } deferred_flush[i].next = 0; -- cgit v1.2.3 From 5715f0f9d3814e83e5f2f754d3f7abdfa096a0b9 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 8 Apr 2010 19:58:22 +0100 Subject: intel-iommu: Don't complain that ACPI_DMAR_SCOPE_TYPE_IOAPIC is not supported Signed-off-by: Yinghai Lu Signed-off-by: David Woodhouse --- drivers/pci/dmar.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index ffe22bc3ac8e..a04bde9bd10f 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -130,9 +130,10 @@ static int __init dmar_parse_dev_scope(void *start, void *end, int *cnt, if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT || scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE) (*cnt)++; - else + else if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_IOAPIC) { printk(KERN_WARNING PREFIX - "Unsupported device scope\n"); + "Unsupported device scope\n"); + } start += scope->length; } if (*cnt == 0) -- cgit v1.2.3 From 680a7524622356f5476e8fad2fe32b2b68b432c0 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 8 Apr 2010 19:58:23 +0100 Subject: intel-iommu: Print out iommu seq_id more info on system with more than one IOMMU Signed-off-by: Yinghai Lu Signed-off-by: David Woodhouse --- drivers/pci/dmar.c | 3 ++- drivers/pci/intel-iommu.c | 9 ++++++--- drivers/pci/intr_remapping.c | 6 +++--- 3 files changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index a04bde9bd10f..d439917f37a9 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -806,7 +806,8 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) } ver = readl(iommu->reg + DMAR_VER_REG); - pr_info("IOMMU %llx: ver %d:%d cap %llx ecap %llx\n", + pr_info("IOMMU %d: reg_base_addr %llx ver %d:%d cap %llx ecap %llx\n", + iommu->seq_id, (unsigned long long)drhd->reg_base_addr, DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver), (unsigned long long)iommu->cap, diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 9ce79b1bae83..da40f0789739 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -1150,7 +1150,8 @@ static int iommu_init_domains(struct intel_iommu *iommu) unsigned long nlongs; ndomains = cap_ndoms(iommu->cap); - pr_debug("Number of Domains supportd <%ld>\n", ndomains); + pr_debug("IOMMU %d: Number of Domains supportd <%ld>\n", iommu->seq_id, + ndomains); nlongs = BITS_TO_LONGS(ndomains); spin_lock_init(&iommu->lock); @@ -2319,14 +2320,16 @@ int __init init_dmars(void) */ iommu->flush.flush_context = __iommu_flush_context; iommu->flush.flush_iotlb = __iommu_flush_iotlb; - printk(KERN_INFO "IOMMU 0x%Lx: using Register based " + printk(KERN_INFO "IOMMU %d 0x%Lx: using Register based " "invalidation\n", + iommu->seq_id, (unsigned long long)drhd->reg_base_addr); } else { iommu->flush.flush_context = qi_flush_context; iommu->flush.flush_iotlb = qi_flush_iotlb; - printk(KERN_INFO "IOMMU 0x%Lx: using Queued " + printk(KERN_INFO "IOMMU %d 0x%Lx: using Queued " "invalidation\n", + iommu->seq_id, (unsigned long long)drhd->reg_base_addr); } } diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c index 95b849130ad4..c13802a7e109 100644 --- a/drivers/pci/intr_remapping.c +++ b/drivers/pci/intr_remapping.c @@ -831,9 +831,9 @@ static int ir_parse_ioapic_hpet_scope(struct acpi_dmar_header *header, return -1; } - printk(KERN_INFO "IOAPIC id %d under DRHD base" - " 0x%Lx\n", scope->enumeration_id, - drhd->address); + printk(KERN_INFO "IOAPIC id %d under DRHD base " + " 0x%Lx IOMMU %d\n", scope->enumeration_id, + drhd->address, iommu->seq_id); ir_parse_one_ioapic_scope(scope, iommu); } else if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_HPET) { -- cgit v1.2.3 From dda565492776b7dff5f8507298d868745e734aab Mon Sep 17 00:00:00 2001 From: Yinghai Date: Fri, 9 Apr 2010 01:07:55 +0100 Subject: intel-iommu: use physfn to search drhd for VF When virtfn is used, we should use physfn to find correct drhd -v2: add pci_physfn() Suggested by Roland Dreier do can remove ifdef in dmar.c -v3: Chris pointed out we need that for dma_find_matched_atsr_unit too also change dmar_pci_device_match() static Signed-off-by: Yinghai Lu Acked-by: Roland Dreier Acked-by: Chris Wright Acked-by: Jesse Barnes Signed-off-by: David Woodhouse --- drivers/pci/dmar.c | 6 +++++- include/linux/pci.h | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index d439917f37a9..edc5f002e055 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -309,6 +309,8 @@ int dmar_find_matched_atsr_unit(struct pci_dev *dev) struct acpi_dmar_atsr *atsr; struct dmar_atsr_unit *atsru; + dev = pci_physfn(dev); + list_for_each_entry(atsru, &dmar_atsr_units, list) { atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header); if (atsr->segment == pci_domain_nr(dev->bus)) @@ -507,7 +509,7 @@ parse_dmar_table(void) return ret; } -int dmar_pci_device_match(struct pci_dev *devices[], int cnt, +static int dmar_pci_device_match(struct pci_dev *devices[], int cnt, struct pci_dev *dev) { int index; @@ -530,6 +532,8 @@ dmar_find_matched_drhd_unit(struct pci_dev *dev) struct dmar_drhd_unit *dmaru = NULL; struct acpi_dmar_hardware_unit *drhd; + dev = pci_physfn(dev); + list_for_each_entry(dmaru, &dmar_drhd_units, list) { drhd = container_of(dmaru->hdr, struct acpi_dmar_hardware_unit, diff --git a/include/linux/pci.h b/include/linux/pci.h index a788fa12ff31..a327322a33ab 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -334,6 +334,16 @@ struct pci_dev { #endif }; +static inline struct pci_dev *pci_physfn(struct pci_dev *dev) +{ +#ifdef CONFIG_PCI_IOV + if (dev->is_virtfn) + dev = dev->physfn; +#endif + + return dev; +} + extern struct pci_dev *alloc_pci_dev(void); #define pci_dev_b(n) list_entry(n, struct pci_dev, bus_list) -- cgit v1.2.3 From 4a96b4fcd6b35e9233df07b3c9ab38091edcfe7e Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Sun, 4 Apr 2010 15:19:52 +0200 Subject: firewire: ohci: add a function for reading PHY registers Move the register reading code from ohci_update_phy_reg() into a function which can be used separately. Signed-off-by: Clemens Ladisch Signed-off-by: Stefan Richter --- drivers/firewire/ohci.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index e33917bf97d2..8ebccda94df9 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -460,22 +460,36 @@ static inline void flush_writes(const struct fw_ohci *ohci) reg_read(ohci, OHCI1394_Version); } -static int ohci_update_phy_reg(struct fw_card *card, int addr, - int clear_bits, int set_bits) +static int read_phy_reg(struct fw_card *card, int addr, u32 *value) { struct fw_ohci *ohci = fw_ohci(card); - u32 val, old; + u32 val; reg_write(ohci, OHCI1394_PhyControl, OHCI1394_PhyControl_Read(addr)); flush_writes(ohci); msleep(2); val = reg_read(ohci, OHCI1394_PhyControl); if ((val & OHCI1394_PhyControl_ReadDone) == 0) { - fw_error("failed to set phy reg bits.\n"); + fw_error("failed to read phy reg bits\n"); return -EBUSY; } - old = OHCI1394_PhyControl_ReadData(val); + *value = OHCI1394_PhyControl_ReadData(val); + + return 0; +} + +static int ohci_update_phy_reg(struct fw_card *card, int addr, + int clear_bits, int set_bits) +{ + struct fw_ohci *ohci = fw_ohci(card); + u32 old; + int err; + + err = read_phy_reg(card, addr, &old); + if (err < 0) + return err; + old = (old & ~clear_bits) | set_bits; reg_write(ohci, OHCI1394_PhyControl, OHCI1394_PhyControl_Write(addr, old)); -- cgit v1.2.3 From e7014dada041982ae12ba7fd1967ca0ab0243e04 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 1 Apr 2010 16:40:18 +0200 Subject: firewire: ohci: do not clear PHY interrupt status inadvertently The interrupt status bits in PHY register 5 are cleared by writing a one bit. To avoid clearing them unadvertently, do not write them back when they were read as set, but only when they have been explicitly requested to be set. Signed-off-by: Clemens Ladisch Signed-off-by: Stefan Richter --- drivers/firewire/core.h | 1 + drivers/firewire/ohci.c | 7 +++++++ 2 files changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index fb0321300cce..b2a7b651473a 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h @@ -28,6 +28,7 @@ struct fw_packet; #define PHY_CONTENDER 0x40 #define PHY_BUS_RESET 0x40 #define PHY_BUS_SHORT_RESET 0x40 +#define PHY_INT_STATUS_BITS 0x3c #define BANDWIDTH_AVAILABLE_INITIAL 4915 #define BROADCAST_CHANNEL_INITIAL (1 << 31 | 31) diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 8ebccda94df9..525848f71c34 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -490,6 +490,13 @@ static int ohci_update_phy_reg(struct fw_card *card, int addr, if (err < 0) return err; + /* + * The interrupt status bits are cleared by writing a one bit. + * Avoid clearing them unless explicitly requested in set_bits. + */ + if (addr == 5) + clear_bits |= PHY_INT_STATUS_BITS; + old = (old & ~clear_bits) | set_bits; reg_write(ohci, OHCI1394_PhyControl, OHCI1394_PhyControl_Write(addr, old)); -- cgit v1.2.3 From 925e7a6504966b838c519f009086982c68e0666f Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Sun, 4 Apr 2010 15:19:54 +0200 Subject: firewire: ohci: enable 1394a enhancements The OHCI spec says that, if the programPhyEnable bit is set, the driver is responsible for configuring the IEEE1394a enhancements within the PHY and the link consistently. So do this. Also add a quirk to allow disabling these enhancements; this is needed for the TSB12LV22 where ack accelerations are buggy (erratum b). Signed-off-by: Clemens Ladisch Signed-off-by: Stefan Richter --- drivers/firewire/core.h | 4 +++ drivers/firewire/ohci.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++-- drivers/firewire/ohci.h | 2 +- 3 files changed, 86 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index b2a7b651473a..7a9759bf6837 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h @@ -27,8 +27,12 @@ struct fw_packet; #define PHY_LINK_ACTIVE 0x80 #define PHY_CONTENDER 0x40 #define PHY_BUS_RESET 0x40 +#define PHY_EXTENDED_REGISTERS 0xe0 #define PHY_BUS_SHORT_RESET 0x40 #define PHY_INT_STATUS_BITS 0x3c +#define PHY_ENABLE_ACCEL 0x02 +#define PHY_ENABLE_MULTI 0x01 +#define PHY_PAGE_SELECT 0xe0 #define BANDWIDTH_AVAILABLE_INITIAL 4915 #define BROADCAST_CHANNEL_INITIAL (1 << 31 | 31) diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 525848f71c34..e934713f3fce 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -236,13 +236,15 @@ static char ohci_driver_name[] = KBUILD_MODNAME; #define QUIRK_CYCLE_TIMER 1 #define QUIRK_RESET_PACKET 2 #define QUIRK_BE_HEADERS 4 +#define QUIRK_NO_1394A 8 /* In case of multiple matches in ohci_quirks[], only the first one is used. */ static const struct { unsigned short vendor, device, flags; } ohci_quirks[] = { {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, QUIRK_CYCLE_TIMER | - QUIRK_RESET_PACKET}, + QUIRK_RESET_PACKET | + QUIRK_NO_1394A}, {PCI_VENDOR_ID_TI, PCI_ANY_ID, QUIRK_RESET_PACKET}, {PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, @@ -257,6 +259,7 @@ MODULE_PARM_DESC(quirks, "Chip quirks (default = 0" ", nonatomic cycle timer = " __stringify(QUIRK_CYCLE_TIMER) ", reset packet generation = " __stringify(QUIRK_RESET_PACKET) ", AR/selfID endianess = " __stringify(QUIRK_BE_HEADERS) + ", no 1394a enhancements = " __stringify(QUIRK_NO_1394A) ")"); #ifdef CONFIG_FIREWIRE_OHCI_DEBUG @@ -504,6 +507,27 @@ static int ohci_update_phy_reg(struct fw_card *card, int addr, return 0; } +static int read_paged_phy_reg(struct fw_card *card, + int page, int addr, u32 *value) +{ + struct fw_ohci *ohci = fw_ohci(card); + u32 reg; + int err; + + err = ohci_update_phy_reg(card, 7, PHY_PAGE_SELECT, page << 5); + if (err < 0) + return err; + flush_writes(ohci); + msleep(2); + reg = reg_read(ohci, OHCI1394_PhyControl); + if ((reg & OHCI1394_PhyControl_WritePending) != 0) { + fw_error("failed to write phy reg bits\n"); + return -EBUSY; + } + + return read_phy_reg(card, addr, value); +} + static int ar_context_add_page(struct ar_context *ctx) { struct device *dev = ctx->ohci->card.device; @@ -1511,13 +1535,64 @@ static void copy_config_rom(__be32 *dest, const __be32 *src, size_t length) memset(&dest[length], 0, CONFIG_ROM_SIZE - size); } +static int configure_1394a_enhancements(struct fw_ohci *ohci) +{ + bool enable_1394a; + u32 reg, phy_compliance; + int clear, set, offset; + + /* Check if the driver should configure link and PHY. */ + if (!(reg_read(ohci, OHCI1394_HCControlSet) & + OHCI1394_HCControl_programPhyEnable)) + return 0; + + /* Paranoia: check whether the PHY supports 1394a, too. */ + enable_1394a = false; + if (read_phy_reg(&ohci->card, 2, ®) < 0) + return -EIO; + if ((reg & PHY_EXTENDED_REGISTERS) == PHY_EXTENDED_REGISTERS) { + if (read_paged_phy_reg(&ohci->card, 1, 8, &phy_compliance) < 0) + return -EIO; + if (phy_compliance >= 1) + enable_1394a = true; + } + + if (ohci->quirks & QUIRK_NO_1394A) + enable_1394a = false; + + /* Configure PHY and link consistently. */ + if (enable_1394a) { + clear = 0; + set = PHY_ENABLE_ACCEL | PHY_ENABLE_MULTI; + } else { + clear = PHY_ENABLE_ACCEL | PHY_ENABLE_MULTI; + set = 0; + } + if (ohci_update_phy_reg(&ohci->card, 5, clear, set) < 0) + return -EIO; + flush_writes(ohci); + msleep(2); + + if (enable_1394a) + offset = OHCI1394_HCControlSet; + else + offset = OHCI1394_HCControlClear; + reg_write(ohci, offset, OHCI1394_HCControl_aPhyEnhanceEnable); + + /* Clean up: configuration has been taken care of. */ + reg_write(ohci, OHCI1394_HCControlClear, + OHCI1394_HCControl_programPhyEnable); + + return 0; +} + static int ohci_enable(struct fw_card *card, const __be32 *config_rom, size_t length) { struct fw_ohci *ohci = fw_ohci(card); struct pci_dev *dev = to_pci_dev(card->device); u32 lps; - int i; + int i, err; if (software_reset(ohci)) { fw_error("Failed to reset ohci card.\n"); @@ -1581,6 +1656,10 @@ static int ohci_enable(struct fw_card *card, if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset); + err = configure_1394a_enhancements(ohci); + if (err < 0) + return err; + /* Activate link_on bit and contender bit in our self ID packets.*/ if (ohci_update_phy_reg(card, 4, 0, PHY_LINK_ACTIVE | PHY_CONTENDER) < 0) diff --git a/drivers/firewire/ohci.h b/drivers/firewire/ohci.h index ba492d85c516..d49e1469a986 100644 --- a/drivers/firewire/ohci.h +++ b/drivers/firewire/ohci.h @@ -67,7 +67,7 @@ #define OHCI1394_PhyControl_ReadDone 0x80000000 #define OHCI1394_PhyControl_ReadData(r) (((r) & 0x00ff0000) >> 16) #define OHCI1394_PhyControl_Write(addr, data) (((addr) << 8) | (data) | 0x00004000) -#define OHCI1394_PhyControl_WriteDone 0x00004000 +#define OHCI1394_PhyControl_WritePending 0x00004000 #define OHCI1394_IsochronousCycleTimer 0x0F0 #define OHCI1394_AsReqFilterHiSet 0x100 #define OHCI1394_AsReqFilterHiClear 0x104 -- cgit v1.2.3 From 54672386ccf36ffa21d1de8e75624af83f9b0eeb Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 1 Apr 2010 16:43:59 +0200 Subject: firewire: ohci: fix up configuration of TI chips On TI chips (OHCI-Lynx and later), enable link enhancements features that TI recommends to be used. None of these are required for proper operation, but they are safe and nice to have. In theory, these bits should have been set by default, but in practice, some BIOS/EEPROM writers apparently do not read the datasheet, or get spooked by names like "unfair". Signed-off-by: Clemens Ladisch Signed-off-by: Stefan Richter --- drivers/firewire/ohci.c | 19 ++++++++++++++++++- drivers/firewire/ohci.h | 8 ++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index e934713f3fce..6a27a0ef3b63 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -2431,7 +2431,7 @@ static int __devinit pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { struct fw_ohci *ohci; - u32 bus_options, max_receive, link_speed, version; + u32 bus_options, max_receive, link_speed, version, link_enh; u64 guid; int i, err, n_ir, n_it; size_t size; @@ -2484,6 +2484,23 @@ static int __devinit pci_probe(struct pci_dev *dev, if (param_quirks) ohci->quirks = param_quirks; + /* TI OHCI-Lynx and compatible: set recommended configuration bits. */ + if (dev->vendor == PCI_VENDOR_ID_TI) { + pci_read_config_dword(dev, PCI_CFG_TI_LinkEnh, &link_enh); + + /* adjust latency of ATx FIFO: use 1.7 KB threshold */ + link_enh &= ~TI_LinkEnh_atx_thresh_mask; + link_enh |= TI_LinkEnh_atx_thresh_1_7K; + + /* use priority arbitration for asynchronous responses */ + link_enh |= TI_LinkEnh_enab_unfair; + + /* required for aPhyEnhanceEnable to work */ + link_enh |= TI_LinkEnh_enab_accel; + + pci_write_config_dword(dev, PCI_CFG_TI_LinkEnh, link_enh); + } + ar_context_init(&ohci->ar_request_ctx, ohci, OHCI1394_AsReqRcvContextControlSet); diff --git a/drivers/firewire/ohci.h b/drivers/firewire/ohci.h index d49e1469a986..3bc9a5d744eb 100644 --- a/drivers/firewire/ohci.h +++ b/drivers/firewire/ohci.h @@ -154,4 +154,12 @@ #define OHCI1394_phy_tcode 0xe +/* TI extensions */ + +#define PCI_CFG_TI_LinkEnh 0xf4 +#define TI_LinkEnh_enab_accel 0x00000002 +#define TI_LinkEnh_enab_unfair 0x00000080 +#define TI_LinkEnh_atx_thresh_mask 0x00003000 +#define TI_LinkEnh_atx_thresh_1_7K 0x00001000 + #endif /* _FIREWIRE_OHCI_H */ -- cgit v1.2.3 From 35d999b12037b5ea0152889232629c25d45b0e26 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 10 Apr 2010 16:04:56 +0200 Subject: firewire: ohci: wait for PHY register accesses to complete Rather than having the arbitrary msleep(2) pause, let read_phy_reg() loop until the link--phy access was finished. Factor write_phy_reg() out of ohci_update_phy_reg() and of read_paged_phy_reg() and let it loop too until the link--phy access was finished. Like in the older ohci1394 driver, a timeout of 100 milliseconds is chosen. Unlike the old driver, we sleep instead of busy-wait in each waiting loop iteration. Instead of a loop, the waiting could probably also be implemented interrupt driven, but why bother. It would require up and running interrupt handling before the link was fully configured and enabled. Also modify functions a bit: Error return and value return can be combined in read_phy_reg() since the domain of values is only u8. Likewise in read_paged_phy_reg(). Signed-off-by: Stefan Richter --- drivers/firewire/ohci.c | 112 ++++++++++++++++++++++++------------------------ 1 file changed, 57 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 6a27a0ef3b63..5bbf42eb3f9a 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -463,35 +463,51 @@ static inline void flush_writes(const struct fw_ohci *ohci) reg_read(ohci, OHCI1394_Version); } -static int read_phy_reg(struct fw_card *card, int addr, u32 *value) +static int read_phy_reg(struct fw_ohci *ohci, int addr) { - struct fw_ohci *ohci = fw_ohci(card); u32 val; + int i; reg_write(ohci, OHCI1394_PhyControl, OHCI1394_PhyControl_Read(addr)); - flush_writes(ohci); - msleep(2); - val = reg_read(ohci, OHCI1394_PhyControl); - if ((val & OHCI1394_PhyControl_ReadDone) == 0) { - fw_error("failed to read phy reg bits\n"); - return -EBUSY; + for (i = 0; i < 10; i++) { + val = reg_read(ohci, OHCI1394_PhyControl); + if (val & OHCI1394_PhyControl_ReadDone) + return OHCI1394_PhyControl_ReadData(val); + + msleep(1); } + fw_error("failed to read phy reg\n"); - *value = OHCI1394_PhyControl_ReadData(val); + return -EBUSY; +} - return 0; +static int write_phy_reg(const struct fw_ohci *ohci, int addr, u32 val) +{ + int i; + + reg_write(ohci, OHCI1394_PhyControl, + OHCI1394_PhyControl_Write(addr, val)); + for (i = 0; i < 100; i++) { + val = reg_read(ohci, OHCI1394_PhyControl); + if (!(val & OHCI1394_PhyControl_WritePending)) + return 0; + + msleep(1); + } + fw_error("failed to write phy reg\n"); + + return -EBUSY; } static int ohci_update_phy_reg(struct fw_card *card, int addr, int clear_bits, int set_bits) { struct fw_ohci *ohci = fw_ohci(card); - u32 old; - int err; + int ret; - err = read_phy_reg(card, addr, &old); - if (err < 0) - return err; + ret = read_phy_reg(ohci, addr); + if (ret < 0) + return ret; /* * The interrupt status bits are cleared by writing a one bit. @@ -500,32 +516,18 @@ static int ohci_update_phy_reg(struct fw_card *card, int addr, if (addr == 5) clear_bits |= PHY_INT_STATUS_BITS; - old = (old & ~clear_bits) | set_bits; - reg_write(ohci, OHCI1394_PhyControl, - OHCI1394_PhyControl_Write(addr, old)); - - return 0; + return write_phy_reg(ohci, addr, (ret & ~clear_bits) | set_bits); } -static int read_paged_phy_reg(struct fw_card *card, - int page, int addr, u32 *value) +static int read_paged_phy_reg(struct fw_ohci *ohci, int page, int addr) { - struct fw_ohci *ohci = fw_ohci(card); - u32 reg; - int err; + int ret; - err = ohci_update_phy_reg(card, 7, PHY_PAGE_SELECT, page << 5); - if (err < 0) - return err; - flush_writes(ohci); - msleep(2); - reg = reg_read(ohci, OHCI1394_PhyControl); - if ((reg & OHCI1394_PhyControl_WritePending) != 0) { - fw_error("failed to write phy reg bits\n"); - return -EBUSY; - } + ret = ohci_update_phy_reg(&ohci->card, 7, PHY_PAGE_SELECT, page << 5); + if (ret < 0) + return ret; - return read_phy_reg(card, addr, value); + return read_phy_reg(ohci, addr); } static int ar_context_add_page(struct ar_context *ctx) @@ -1538,8 +1540,7 @@ static void copy_config_rom(__be32 *dest, const __be32 *src, size_t length) static int configure_1394a_enhancements(struct fw_ohci *ohci) { bool enable_1394a; - u32 reg, phy_compliance; - int clear, set, offset; + int ret, clear, set, offset; /* Check if the driver should configure link and PHY. */ if (!(reg_read(ohci, OHCI1394_HCControlSet) & @@ -1548,12 +1549,14 @@ static int configure_1394a_enhancements(struct fw_ohci *ohci) /* Paranoia: check whether the PHY supports 1394a, too. */ enable_1394a = false; - if (read_phy_reg(&ohci->card, 2, ®) < 0) - return -EIO; - if ((reg & PHY_EXTENDED_REGISTERS) == PHY_EXTENDED_REGISTERS) { - if (read_paged_phy_reg(&ohci->card, 1, 8, &phy_compliance) < 0) - return -EIO; - if (phy_compliance >= 1) + ret = read_phy_reg(ohci, 2); + if (ret < 0) + return ret; + if ((ret & PHY_EXTENDED_REGISTERS) == PHY_EXTENDED_REGISTERS) { + ret = read_paged_phy_reg(ohci, 1, 8); + if (ret < 0) + return ret; + if (ret >= 1) enable_1394a = true; } @@ -1568,10 +1571,9 @@ static int configure_1394a_enhancements(struct fw_ohci *ohci) clear = PHY_ENABLE_ACCEL | PHY_ENABLE_MULTI; set = 0; } - if (ohci_update_phy_reg(&ohci->card, 5, clear, set) < 0) - return -EIO; - flush_writes(ohci); - msleep(2); + ret = ohci_update_phy_reg(&ohci->card, 5, clear, set); + if (ret < 0) + return ret; if (enable_1394a) offset = OHCI1394_HCControlSet; @@ -1592,7 +1594,7 @@ static int ohci_enable(struct fw_card *card, struct fw_ohci *ohci = fw_ohci(card); struct pci_dev *dev = to_pci_dev(card->device); u32 lps; - int i, err; + int i, ret; if (software_reset(ohci)) { fw_error("Failed to reset ohci card.\n"); @@ -1656,14 +1658,14 @@ static int ohci_enable(struct fw_card *card, if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset); - err = configure_1394a_enhancements(ohci); - if (err < 0) - return err; + ret = configure_1394a_enhancements(ohci); + if (ret < 0) + return ret; /* Activate link_on bit and contender bit in our self ID packets.*/ - if (ohci_update_phy_reg(card, 4, 0, - PHY_LINK_ACTIVE | PHY_CONTENDER) < 0) - return -EIO; + ret = ohci_update_phy_reg(card, 4, 0, PHY_LINK_ACTIVE | PHY_CONTENDER); + if (ret < 0) + return ret; /* * When the link is not yet enabled, the atomic config rom -- cgit v1.2.3 From 5da3dac8d99c9933f12286fd73fa18e26f768bea Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Fri, 2 Apr 2010 14:05:02 +0200 Subject: firewire: ohci: cleanups and fix for nonstandard build without debug facility 1) Clean up two function names: The ohci_ prefix is only used in names of fw_card_driver hooks. There were two unnecessary exceptions. 2) Replace empty macros by empty inline functions so that call parameter type checking is available in #ifndef'd builds. 3) CONFIG_FIREWIRE_OHCI_DEBUG is currently a hidden kconfig variable, hence is not going to be switched off by anybody. Still, it can be switched off but then compilation will fail in ohci_enable() at the expression param_debug & OHCI_PARAM_DEBUG_BUSRESETS. Add the necessary definitions in the nonstandard case. Signed-off-by: Stefan Richter --- drivers/firewire/ohci.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 5bbf42eb3f9a..07deac77bc13 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -262,13 +262,13 @@ MODULE_PARM_DESC(quirks, "Chip quirks (default = 0" ", no 1394a enhancements = " __stringify(QUIRK_NO_1394A) ")"); -#ifdef CONFIG_FIREWIRE_OHCI_DEBUG - #define OHCI_PARAM_DEBUG_AT_AR 1 #define OHCI_PARAM_DEBUG_SELFIDS 2 #define OHCI_PARAM_DEBUG_IRQS 4 #define OHCI_PARAM_DEBUG_BUSRESETS 8 /* only effective before chip init */ +#ifdef CONFIG_FIREWIRE_OHCI_DEBUG + static int param_debug; module_param_named(debug, param_debug, int, 0644); MODULE_PARM_DESC(debug, "Verbose logging (default = 0" @@ -441,9 +441,10 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt) #else -#define log_irqs(evt) -#define log_selfids(node_id, generation, self_id_count, sid) -#define log_ar_at_event(dir, speed, header, evt) +#define param_debug 0 +static inline void log_irqs(u32 evt) {} +static inline void log_selfids(int node_id, int generation, int self_id_count, u32 *s) {} +static inline void log_ar_at_event(char dir, int speed, u32 *header, int evt) {} #endif /* CONFIG_FIREWIRE_OHCI_DEBUG */ @@ -2401,7 +2402,7 @@ static const struct fw_card_driver ohci_driver = { }; #ifdef CONFIG_PPC_PMAC -static void ohci_pmac_on(struct pci_dev *dev) +static void pmac_ohci_on(struct pci_dev *dev) { if (machine_is(powermac)) { struct device_node *ofn = pci_device_to_OF_node(dev); @@ -2413,7 +2414,7 @@ static void ohci_pmac_on(struct pci_dev *dev) } } -static void ohci_pmac_off(struct pci_dev *dev) +static void pmac_ohci_off(struct pci_dev *dev) { if (machine_is(powermac)) { struct device_node *ofn = pci_device_to_OF_node(dev); @@ -2425,8 +2426,8 @@ static void ohci_pmac_off(struct pci_dev *dev) } } #else -#define ohci_pmac_on(dev) -#define ohci_pmac_off(dev) +static inline void pmac_ohci_on(struct pci_dev *dev) {} +static inline void pmac_ohci_off(struct pci_dev *dev) {} #endif /* CONFIG_PPC_PMAC */ static int __devinit pci_probe(struct pci_dev *dev, @@ -2446,7 +2447,7 @@ static int __devinit pci_probe(struct pci_dev *dev, fw_card_initialize(&ohci->card, &ohci_driver, &dev->dev); - ohci_pmac_on(dev); + pmac_ohci_on(dev); err = pci_enable_device(dev); if (err) { @@ -2580,7 +2581,7 @@ static int __devinit pci_probe(struct pci_dev *dev, pci_disable_device(dev); fail_free: kfree(&ohci->card); - ohci_pmac_off(dev); + pmac_ohci_off(dev); fail: if (err == -ENOMEM) fw_error("Out of memory\n"); @@ -2623,7 +2624,7 @@ static void pci_remove(struct pci_dev *dev) pci_release_region(dev, 0); pci_disable_device(dev); kfree(&ohci->card); - ohci_pmac_off(dev); + pmac_ohci_off(dev); fw_notify("Removed fw-ohci device.\n"); } @@ -2644,7 +2645,7 @@ static int pci_suspend(struct pci_dev *dev, pm_message_t state) err = pci_set_power_state(dev, pci_choose_state(dev, state)); if (err) fw_error("pci_set_power_state failed with %d\n", err); - ohci_pmac_off(dev); + pmac_ohci_off(dev); return 0; } @@ -2654,7 +2655,7 @@ static int pci_resume(struct pci_dev *dev) struct fw_ohci *ohci = pci_get_drvdata(dev); int err; - ohci_pmac_on(dev); + pmac_ohci_on(dev); pci_set_power_state(dev, PCI_D0); pci_restore_state(dev); err = pci_enable_device(dev); -- cgit v1.2.3 From 3ac26b2ee30005930117fe6a180c139c5f300faf Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 10 Apr 2010 16:38:05 +0100 Subject: firewire: cdev: mark char device files as not seekable The character device file ABI (i.e. /dev/fw* character device file interface) does not make any use of lseek(), pread(), pwrite() (or any kind of write() at all). Use nonseekable_open() and, redundantly, set file_operations.llseek to no_llseek to remove any doubt whether the BKL-grabbing default_llseek handler is used. (Also shuffle file_operations initialization according to the order of handler definitions.) Signed-off-by: Stefan Richter --- drivers/firewire/core-cdev.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 0d3df0927efc..9d1a1a1a83c9 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -226,7 +226,7 @@ static int fw_device_op_open(struct inode *inode, struct file *file) list_add_tail(&client->link, &device->client_list); mutex_unlock(&device->client_list_mutex); - return 0; + return nonseekable_open(inode, file); } static void queue_event(struct client *client, struct event *event, @@ -1495,13 +1495,13 @@ static unsigned int fw_device_op_poll(struct file *file, poll_table * pt) const struct file_operations fw_device_ops = { .owner = THIS_MODULE, + .llseek = no_llseek, .open = fw_device_op_open, .read = fw_device_op_read, .unlocked_ioctl = fw_device_op_ioctl, - .poll = fw_device_op_poll, - .release = fw_device_op_release, .mmap = fw_device_op_mmap, - + .release = fw_device_op_release, + .poll = fw_device_op_poll, #ifdef CONFIG_COMPAT .compat_ioctl = fw_device_op_compat_ioctl, #endif -- cgit v1.2.3 From 7cfe21aae155c26193fde617dc61d37a79a63f86 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 10 Apr 2010 16:47:18 +0100 Subject: ieee1394: mark char device files as not seekable The - raw1394 (/dev/raw1394), - video1394 (/dev/video1394/*), - dv1394 (/dev/dv1394/*) character device file ABIs do not make any use of lseek(), pread(), or pwrite(). Therefore use nonseekable_open() and, redundantly, set file_operations.llseek to no_llseek to remove any doubt whether the BKL- grabbing default_llseek handler is used. Although all this is legacy code which should be left in peace until it is eventually removed (as it is superseded by firewire-core's ABI), this change seems still worth doing to further minimize the presence of BKL usage in the kernel. Signed-off-by: Stefan Richter --- drivers/ieee1394/dv1394.c | 11 ++++++----- drivers/ieee1394/raw1394.c | 3 ++- drivers/ieee1394/video1394.c | 5 +++-- 3 files changed, 11 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c index 9fd4a0d3206e..adaefabc40e9 100644 --- a/drivers/ieee1394/dv1394.c +++ b/drivers/ieee1394/dv1394.c @@ -1824,7 +1824,7 @@ static int dv1394_open(struct inode *inode, struct file *file) "and will not be available in the new firewire driver stack. " "Try libraw1394 based programs instead.\n", current->comm); - return 0; + return nonseekable_open(inode, file); } @@ -2153,17 +2153,18 @@ static struct cdev dv1394_cdev; static const struct file_operations dv1394_fops= { .owner = THIS_MODULE, - .poll = dv1394_poll, + .poll = dv1394_poll, .unlocked_ioctl = dv1394_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = dv1394_compat_ioctl, #endif .mmap = dv1394_mmap, .open = dv1394_open, - .write = dv1394_write, - .read = dv1394_read, + .write = dv1394_write, + .read = dv1394_read, .release = dv1394_release, - .fasync = dv1394_fasync, + .fasync = dv1394_fasync, + .llseek = no_llseek, }; diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index 8aa56ac07e29..b563d5e9fa2e 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c @@ -2834,7 +2834,7 @@ static int raw1394_open(struct inode *inode, struct file *file) file->private_data = fi; - return 0; + return nonseekable_open(inode, file); } static int raw1394_release(struct inode *inode, struct file *file) @@ -3035,6 +3035,7 @@ static const struct file_operations raw1394_fops = { .poll = raw1394_poll, .open = raw1394_open, .release = raw1394_release, + .llseek = no_llseek, }; static int __init init_raw1394(void) diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c index 949064a05675..a42bd6893bcf 100644 --- a/drivers/ieee1394/video1394.c +++ b/drivers/ieee1394/video1394.c @@ -1239,7 +1239,7 @@ static int video1394_open(struct inode *inode, struct file *file) ctx->current_ctx = NULL; file->private_data = ctx; - return 0; + return nonseekable_open(inode, file); } static int video1394_release(struct inode *inode, struct file *file) @@ -1287,7 +1287,8 @@ static const struct file_operations video1394_fops= .poll = video1394_poll, .mmap = video1394_mmap, .open = video1394_open, - .release = video1394_release + .release = video1394_release, + .llseek = no_llseek, }; /*** HOTPLUG STUFF **********************************************************/ -- cgit v1.2.3 From 0328ac267564089d9cedfb568f936d30a6debd21 Mon Sep 17 00:00:00 2001 From: Uri Simchoni Date: Thu, 8 Apr 2010 19:25:37 +0300 Subject: crypto: mv_cesa - Invoke the user callback from a softirq context Invoke the user callback from a softirq context Signed-off-by: Uri Simchoni Signed-off-by: Herbert Xu --- drivers/crypto/mv_cesa.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index b21ef635f352..3e60ba909434 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -275,7 +275,9 @@ static void dequeue_complete_req(void) sg_miter_stop(&cpg->p.dst_sg_it); mv_crypto_algo_completion(); cpg->eng_st = ENGINE_IDLE; + local_bh_disable(); req->base.complete(&req->base, 0); + local_bh_enable(); } } -- cgit v1.2.3 From 6bc6fcd609080461682c5cc0a1e3bf4345d6419d Mon Sep 17 00:00:00 2001 From: Uri Simchoni Date: Thu, 8 Apr 2010 19:25:56 +0300 Subject: crypto: mv_cesa - Remove compiler warning in mv_cesa driver Remove compiler warning Signed-off-by: Uri Simchoni Signed-off-by: Herbert Xu --- drivers/crypto/mv_cesa.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index 3e60ba909434..37d9f0688e75 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -178,6 +178,7 @@ static void mv_process_current_q(int first_block) op.config = CFG_OP_CRYPT_ONLY | CFG_ENCM_AES | CFG_ENC_MODE_ECB; break; case COP_AES_CBC: + default: op.config = CFG_OP_CRYPT_ONLY | CFG_ENCM_AES | CFG_ENC_MODE_CBC; op.enc_iv = ENC_IV_POINT(SRAM_DATA_IV) | ENC_IV_BUF_POINT(SRAM_DATA_IV_BUF); -- cgit v1.2.3 From f565e67ec1b8f4a95d21550f9b879fe86b4132e0 Mon Sep 17 00:00:00 2001 From: Uri Simchoni Date: Thu, 8 Apr 2010 19:26:34 +0300 Subject: crypto: mv_cesa - Fix situation where the dest sglist is organized differently than the source sglist Bugfix for situations where the destination scatterlist has a different buffer structure than the source scatterlist (e.g. source has one 2K buffer and dest has 2 1K buffers) Signed-off-by: Uri Simchoni Signed-off-by: Herbert Xu --- drivers/crypto/mv_cesa.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index 37d9f0688e75..018a95ce0c9b 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -242,6 +242,8 @@ static void dequeue_complete_req(void) struct ablkcipher_request *req = cpg->cur_req; void *buf; int ret; + int need_copy_len = cpg->p.crypt_len; + int sram_offset = 0; cpg->p.total_req_bytes += cpg->p.crypt_len; do { @@ -257,14 +259,16 @@ static void dequeue_complete_req(void) buf = cpg->p.dst_sg_it.addr; buf += cpg->p.dst_start; - dst_copy = min(cpg->p.crypt_len, cpg->p.sg_dst_left); - - memcpy(buf, cpg->sram + SRAM_DATA_OUT_START, dst_copy); + dst_copy = min(need_copy_len, cpg->p.sg_dst_left); + memcpy(buf, + cpg->sram + SRAM_DATA_OUT_START + sram_offset, + dst_copy); + sram_offset += dst_copy; cpg->p.sg_dst_left -= dst_copy; - cpg->p.crypt_len -= dst_copy; + need_copy_len -= dst_copy; cpg->p.dst_start += dst_copy; - } while (cpg->p.crypt_len > 0); + } while (need_copy_len > 0); BUG_ON(cpg->eng_st != ENGINE_W_DEQUEUE); if (cpg->p.total_req_bytes < req->nbytes) { -- cgit v1.2.3 From 15d4dd3594221f11a7730fcf2d5f9942b96cdd7e Mon Sep 17 00:00:00 2001 From: Uri Simchoni Date: Thu, 8 Apr 2010 19:27:02 +0300 Subject: crypto: mv_cesa - Fix situations where the src sglist spans more data than the request asks for Fix for situations where the source scatterlist spans more data than the request nbytes Signed-off-by: Uri Simchoni Signed-off-by: Herbert Xu --- drivers/crypto/mv_cesa.c | 66 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index 018a95ce0c9b..096f9ff6578a 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -143,27 +143,45 @@ static int mv_setkey_aes(struct crypto_ablkcipher *cipher, const u8 *key, return 0; } -static void setup_data_in(struct ablkcipher_request *req) +static void copy_src_to_buf(struct req_progress *p, char *dbuf, int len) { int ret; - void *buf; - - if (!cpg->p.sg_src_left) { - ret = sg_miter_next(&cpg->p.src_sg_it); - BUG_ON(!ret); - cpg->p.sg_src_left = cpg->p.src_sg_it.length; - cpg->p.src_start = 0; - } + void *sbuf; + int copied = 0; - cpg->p.crypt_len = min(cpg->p.sg_src_left, cpg->max_req_size); - - buf = cpg->p.src_sg_it.addr; - buf += cpg->p.src_start; + while (1) { + if (!p->sg_src_left) { + ret = sg_miter_next(&p->src_sg_it); + BUG_ON(!ret); + p->sg_src_left = p->src_sg_it.length; + p->src_start = 0; + } - memcpy(cpg->sram + SRAM_DATA_IN_START, buf, cpg->p.crypt_len); + sbuf = p->src_sg_it.addr + p->src_start; + + if (p->sg_src_left <= len - copied) { + memcpy(dbuf + copied, sbuf, p->sg_src_left); + copied += p->sg_src_left; + p->sg_src_left = 0; + if (copied >= len) + break; + } else { + int copy_len = len - copied; + memcpy(dbuf + copied, sbuf, copy_len); + p->src_start += copy_len; + p->sg_src_left -= copy_len; + break; + } + } +} - cpg->p.sg_src_left -= cpg->p.crypt_len; - cpg->p.src_start += cpg->p.crypt_len; +static void setup_data_in(struct ablkcipher_request *req) +{ + struct req_progress *p = &cpg->p; + p->crypt_len = + min((int)req->nbytes - p->total_req_bytes, cpg->max_req_size); + copy_src_to_buf(p, cpg->sram + SRAM_DATA_IN_START, + p->crypt_len); } static void mv_process_current_q(int first_block) @@ -289,12 +307,16 @@ static void dequeue_complete_req(void) static int count_sgs(struct scatterlist *sl, unsigned int total_bytes) { int i = 0; - - do { - total_bytes -= sl[i].length; - i++; - - } while (total_bytes > 0); + size_t cur_len; + + while (1) { + cur_len = sl[i].length; + ++i; + if (total_bytes > cur_len) + total_bytes -= cur_len; + else + break; + } return i; } -- cgit v1.2.3 From 3b61a90502481045f56c1c41a2af35ee48ca8b80 Mon Sep 17 00:00:00 2001 From: Uri Simchoni Date: Thu, 8 Apr 2010 19:27:33 +0300 Subject: crypto: mv_cesa - Enqueue generic async requests Enqueue generic async requests rather than ablkcipher requests in the driver's queue Signed-off-by: Uri Simchoni Signed-off-by: Herbert Xu --- drivers/crypto/mv_cesa.c | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index 096f9ff6578a..8891e2e703e3 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -39,6 +39,7 @@ enum engine_status { * @sg_src_left: bytes left in src to process (scatter list) * @src_start: offset to add to src start position (scatter list) * @crypt_len: length of current crypt process + * @hw_nbytes: total bytes to process in hw for this request * @sg_dst_left: bytes left dst to process in this scatter list * @dst_start: offset to add to dst start position (scatter list) * @total_req_bytes: total number of bytes processed (request). @@ -55,6 +56,7 @@ struct req_progress { int sg_src_left; int src_start; int crypt_len; + int hw_nbytes; /* dst mostly */ int sg_dst_left; int dst_start; @@ -71,7 +73,7 @@ struct crypto_priv { spinlock_t lock; struct crypto_queue queue; enum engine_status eng_st; - struct ablkcipher_request *cur_req; + struct crypto_async_request *cur_req; struct req_progress p; int max_req_size; int sram_size; @@ -175,18 +177,18 @@ static void copy_src_to_buf(struct req_progress *p, char *dbuf, int len) } } -static void setup_data_in(struct ablkcipher_request *req) +static void setup_data_in(void) { struct req_progress *p = &cpg->p; p->crypt_len = - min((int)req->nbytes - p->total_req_bytes, cpg->max_req_size); + min(p->hw_nbytes - p->total_req_bytes, cpg->max_req_size); copy_src_to_buf(p, cpg->sram + SRAM_DATA_IN_START, p->crypt_len); } static void mv_process_current_q(int first_block) { - struct ablkcipher_request *req = cpg->cur_req; + struct ablkcipher_request *req = ablkcipher_request_cast(cpg->cur_req); struct mv_ctx *ctx = crypto_tfm_ctx(req->base.tfm); struct mv_req_ctx *req_ctx = ablkcipher_request_ctx(req); struct sec_accel_config op; @@ -229,7 +231,7 @@ static void mv_process_current_q(int first_block) ENC_P_DST(SRAM_DATA_OUT_START); op.enc_key_p = SRAM_DATA_KEY_P; - setup_data_in(req); + setup_data_in(); op.enc_len = cpg->p.crypt_len; memcpy(cpg->sram + SRAM_CONFIG, &op, sizeof(struct sec_accel_config)); @@ -246,7 +248,7 @@ static void mv_process_current_q(int first_block) static void mv_crypto_algo_completion(void) { - struct ablkcipher_request *req = cpg->cur_req; + struct ablkcipher_request *req = ablkcipher_request_cast(cpg->cur_req); struct mv_req_ctx *req_ctx = ablkcipher_request_ctx(req); if (req_ctx->op != COP_AES_CBC) @@ -257,7 +259,7 @@ static void mv_crypto_algo_completion(void) static void dequeue_complete_req(void) { - struct ablkcipher_request *req = cpg->cur_req; + struct crypto_async_request *req = cpg->cur_req; void *buf; int ret; int need_copy_len = cpg->p.crypt_len; @@ -289,7 +291,7 @@ static void dequeue_complete_req(void) } while (need_copy_len > 0); BUG_ON(cpg->eng_st != ENGINE_W_DEQUEUE); - if (cpg->p.total_req_bytes < req->nbytes) { + if (cpg->p.total_req_bytes < cpg->p.hw_nbytes) { /* process next scatter list entry */ cpg->eng_st = ENGINE_BUSY; mv_process_current_q(0); @@ -299,7 +301,7 @@ static void dequeue_complete_req(void) mv_crypto_algo_completion(); cpg->eng_st = ENGINE_IDLE; local_bh_disable(); - req->base.complete(&req->base, 0); + req->complete(req, 0); local_bh_enable(); } } @@ -323,16 +325,19 @@ static int count_sgs(struct scatterlist *sl, unsigned int total_bytes) static void mv_enqueue_new_req(struct ablkcipher_request *req) { + struct req_progress *p = &cpg->p; int num_sgs; - cpg->cur_req = req; - memset(&cpg->p, 0, sizeof(struct req_progress)); + cpg->cur_req = &req->base; + memset(p, 0, sizeof(struct req_progress)); + p->hw_nbytes = req->nbytes; num_sgs = count_sgs(req->src, req->nbytes); - sg_miter_start(&cpg->p.src_sg_it, req->src, num_sgs, SG_MITER_FROM_SG); + sg_miter_start(&p->src_sg_it, req->src, num_sgs, SG_MITER_FROM_SG); num_sgs = count_sgs(req->dst, req->nbytes); - sg_miter_start(&cpg->p.dst_sg_it, req->dst, num_sgs, SG_MITER_TO_SG); + sg_miter_start(&p->dst_sg_it, req->dst, num_sgs, SG_MITER_TO_SG); + mv_process_current_q(1); } @@ -378,13 +383,13 @@ static int queue_manag(void *data) return 0; } -static int mv_handle_req(struct ablkcipher_request *req) +static int mv_handle_req(struct crypto_async_request *req) { unsigned long flags; int ret; spin_lock_irqsave(&cpg->lock, flags); - ret = ablkcipher_enqueue_request(&cpg->queue, req); + ret = crypto_enqueue_request(&cpg->queue, req); spin_unlock_irqrestore(&cpg->lock, flags); wake_up_process(cpg->queue_th); return ret; @@ -397,7 +402,7 @@ static int mv_enc_aes_ecb(struct ablkcipher_request *req) req_ctx->op = COP_AES_ECB; req_ctx->decrypt = 0; - return mv_handle_req(req); + return mv_handle_req(&req->base); } static int mv_dec_aes_ecb(struct ablkcipher_request *req) @@ -409,7 +414,7 @@ static int mv_dec_aes_ecb(struct ablkcipher_request *req) req_ctx->decrypt = 1; compute_aes_dec_key(ctx); - return mv_handle_req(req); + return mv_handle_req(&req->base); } static int mv_enc_aes_cbc(struct ablkcipher_request *req) @@ -419,7 +424,7 @@ static int mv_enc_aes_cbc(struct ablkcipher_request *req) req_ctx->op = COP_AES_CBC; req_ctx->decrypt = 0; - return mv_handle_req(req); + return mv_handle_req(&req->base); } static int mv_dec_aes_cbc(struct ablkcipher_request *req) @@ -431,7 +436,7 @@ static int mv_dec_aes_cbc(struct ablkcipher_request *req) req_ctx->decrypt = 1; compute_aes_dec_key(ctx); - return mv_handle_req(req); + return mv_handle_req(&req->base); } static int mv_cra_init(struct crypto_tfm *tfm) -- cgit v1.2.3 From 7a5f691ef03f4c01d2703b5ec4ddd4c17e645dec Mon Sep 17 00:00:00 2001 From: Uri Simchoni Date: Thu, 8 Apr 2010 19:29:16 +0300 Subject: crypto: mv_cesa - Rename a variable to a more suitable name Rename a variable to a more suitable name Signed-off-by: Uri Simchoni Signed-off-by: Herbert Xu --- drivers/crypto/mv_cesa.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index 8891e2e703e3..4262932d4a27 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -42,7 +42,7 @@ enum engine_status { * @hw_nbytes: total bytes to process in hw for this request * @sg_dst_left: bytes left dst to process in this scatter list * @dst_start: offset to add to dst start position (scatter list) - * @total_req_bytes: total number of bytes processed (request). + * @hw_processed_bytes: number of bytes processed by hw (request). * * sg helper are used to iterate over the scatterlist. Since the size of the * SRAM may be less than the scatter size, this struct struct is used to keep @@ -60,7 +60,7 @@ struct req_progress { /* dst mostly */ int sg_dst_left; int dst_start; - int total_req_bytes; + int hw_processed_bytes; }; struct crypto_priv { @@ -181,7 +181,7 @@ static void setup_data_in(void) { struct req_progress *p = &cpg->p; p->crypt_len = - min(p->hw_nbytes - p->total_req_bytes, cpg->max_req_size); + min(p->hw_nbytes - p->hw_processed_bytes, cpg->max_req_size); copy_src_to_buf(p, cpg->sram + SRAM_DATA_IN_START, p->crypt_len); } @@ -265,7 +265,7 @@ static void dequeue_complete_req(void) int need_copy_len = cpg->p.crypt_len; int sram_offset = 0; - cpg->p.total_req_bytes += cpg->p.crypt_len; + cpg->p.hw_processed_bytes += cpg->p.crypt_len; do { int dst_copy; @@ -291,7 +291,7 @@ static void dequeue_complete_req(void) } while (need_copy_len > 0); BUG_ON(cpg->eng_st != ENGINE_W_DEQUEUE); - if (cpg->p.total_req_bytes < cpg->p.hw_nbytes) { + if (cpg->p.hw_processed_bytes < cpg->p.hw_nbytes) { /* process next scatter list entry */ cpg->eng_st = ENGINE_BUSY; mv_process_current_q(0); -- cgit v1.2.3 From a58094ac5f95d6969e5c52ff096d2fd2864542af Mon Sep 17 00:00:00 2001 From: Uri Simchoni Date: Thu, 8 Apr 2010 19:30:19 +0300 Subject: crypto: mv_cesa - Execute some code via function pointers rathr than direct calls Execute some code via function pointers rathr than direct calls (to allow customization in the hashing request) Signed-off-by: Uri Simchoni Signed-off-by: Herbert Xu --- drivers/crypto/mv_cesa.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index 4262932d4a27..2b4f07aa89e8 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -51,6 +51,8 @@ enum engine_status { struct req_progress { struct sg_mapping_iter src_sg_it; struct sg_mapping_iter dst_sg_it; + void (*complete) (void); + void (*process) (int is_first); /* src mostly */ int sg_src_left; @@ -251,6 +253,9 @@ static void mv_crypto_algo_completion(void) struct ablkcipher_request *req = ablkcipher_request_cast(cpg->cur_req); struct mv_req_ctx *req_ctx = ablkcipher_request_ctx(req); + sg_miter_stop(&cpg->p.src_sg_it); + sg_miter_stop(&cpg->p.dst_sg_it); + if (req_ctx->op != COP_AES_CBC) return ; @@ -294,11 +299,9 @@ static void dequeue_complete_req(void) if (cpg->p.hw_processed_bytes < cpg->p.hw_nbytes) { /* process next scatter list entry */ cpg->eng_st = ENGINE_BUSY; - mv_process_current_q(0); + cpg->p.process(0); } else { - sg_miter_stop(&cpg->p.src_sg_it); - sg_miter_stop(&cpg->p.dst_sg_it); - mv_crypto_algo_completion(); + cpg->p.complete(); cpg->eng_st = ENGINE_IDLE; local_bh_disable(); req->complete(req, 0); @@ -331,6 +334,8 @@ static void mv_enqueue_new_req(struct ablkcipher_request *req) cpg->cur_req = &req->base; memset(p, 0, sizeof(struct req_progress)); p->hw_nbytes = req->nbytes; + p->complete = mv_crypto_algo_completion; + p->process = mv_process_current_q; num_sgs = count_sgs(req->src, req->nbytes); sg_miter_start(&p->src_sg_it, req->src, num_sgs, SG_MITER_FROM_SG); -- cgit v1.2.3 From f0d03deaad05d9cc99cd2ee0475c9ecd726c19ae Mon Sep 17 00:00:00 2001 From: Uri Simchoni Date: Thu, 8 Apr 2010 19:31:48 +0300 Subject: crypto: mv_cesa - Make the copy-back of data optional Make the copy-back of data optional (not done in hashing requests) Signed-off-by: Uri Simchoni Signed-off-by: Herbert Xu --- drivers/crypto/mv_cesa.c | 49 ++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index 2b4f07aa89e8..49a22060fb51 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -40,6 +40,7 @@ enum engine_status { * @src_start: offset to add to src start position (scatter list) * @crypt_len: length of current crypt process * @hw_nbytes: total bytes to process in hw for this request + * @copy_back: whether to copy data back (crypt) or not (hash) * @sg_dst_left: bytes left dst to process in this scatter list * @dst_start: offset to add to dst start position (scatter list) * @hw_processed_bytes: number of bytes processed by hw (request). @@ -60,6 +61,7 @@ struct req_progress { int crypt_len; int hw_nbytes; /* dst mostly */ + int copy_back; int sg_dst_left; int dst_start; int hw_processed_bytes; @@ -267,33 +269,35 @@ static void dequeue_complete_req(void) struct crypto_async_request *req = cpg->cur_req; void *buf; int ret; - int need_copy_len = cpg->p.crypt_len; - int sram_offset = 0; - cpg->p.hw_processed_bytes += cpg->p.crypt_len; - do { - int dst_copy; + if (cpg->p.copy_back) { + int need_copy_len = cpg->p.crypt_len; + int sram_offset = 0; + do { + int dst_copy; + + if (!cpg->p.sg_dst_left) { + ret = sg_miter_next(&cpg->p.dst_sg_it); + BUG_ON(!ret); + cpg->p.sg_dst_left = cpg->p.dst_sg_it.length; + cpg->p.dst_start = 0; + } - if (!cpg->p.sg_dst_left) { - ret = sg_miter_next(&cpg->p.dst_sg_it); - BUG_ON(!ret); - cpg->p.sg_dst_left = cpg->p.dst_sg_it.length; - cpg->p.dst_start = 0; - } + buf = cpg->p.dst_sg_it.addr; + buf += cpg->p.dst_start; - buf = cpg->p.dst_sg_it.addr; - buf += cpg->p.dst_start; + dst_copy = min(need_copy_len, cpg->p.sg_dst_left); - dst_copy = min(need_copy_len, cpg->p.sg_dst_left); + memcpy(buf, + cpg->sram + SRAM_DATA_OUT_START + sram_offset, + dst_copy); + sram_offset += dst_copy; + cpg->p.sg_dst_left -= dst_copy; + need_copy_len -= dst_copy; + cpg->p.dst_start += dst_copy; + } while (need_copy_len > 0); + } - memcpy(buf, - cpg->sram + SRAM_DATA_OUT_START + sram_offset, - dst_copy); - sram_offset += dst_copy; - cpg->p.sg_dst_left -= dst_copy; - need_copy_len -= dst_copy; - cpg->p.dst_start += dst_copy; - } while (need_copy_len > 0); BUG_ON(cpg->eng_st != ENGINE_W_DEQUEUE); if (cpg->p.hw_processed_bytes < cpg->p.hw_nbytes) { @@ -336,6 +340,7 @@ static void mv_enqueue_new_req(struct ablkcipher_request *req) p->hw_nbytes = req->nbytes; p->complete = mv_crypto_algo_completion; p->process = mv_process_current_q; + p->copy_back = 1; num_sgs = count_sgs(req->src, req->nbytes); sg_miter_start(&p->src_sg_it, req->src, num_sgs, SG_MITER_FROM_SG); -- cgit v1.2.3 From 0c5c6c4bae8fe9ae3d86b44c332eb1267df1ec99 Mon Sep 17 00:00:00 2001 From: Uri Simchoni Date: Thu, 8 Apr 2010 19:33:26 +0300 Subject: crypto: mv_cesa - Support processing of data from previous requests Support processing of data from previous requests (as in hashing update/final requests). Signed-off-by: Uri Simchoni Signed-off-by: Herbert Xu --- drivers/crypto/mv_cesa.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index 49a22060fb51..d0fb10e701c5 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -184,10 +184,11 @@ static void copy_src_to_buf(struct req_progress *p, char *dbuf, int len) static void setup_data_in(void) { struct req_progress *p = &cpg->p; - p->crypt_len = + int data_in_sram = min(p->hw_nbytes - p->hw_processed_bytes, cpg->max_req_size); - copy_src_to_buf(p, cpg->sram + SRAM_DATA_IN_START, - p->crypt_len); + copy_src_to_buf(p, cpg->sram + SRAM_DATA_IN_START + p->crypt_len, + data_in_sram - p->crypt_len); + p->crypt_len = data_in_sram; } static void mv_process_current_q(int first_block) @@ -298,6 +299,7 @@ static void dequeue_complete_req(void) } while (need_copy_len > 0); } + cpg->p.crypt_len = 0; BUG_ON(cpg->eng_st != ENGINE_W_DEQUEUE); if (cpg->p.hw_processed_bytes < cpg->p.hw_nbytes) { -- cgit v1.2.3 From 750052dd2400cd09e0864d75b63c2c0bf605056f Mon Sep 17 00:00:00 2001 From: Uri Simchoni Date: Thu, 8 Apr 2010 19:34:55 +0300 Subject: crypto: mv_cesa - Add sha1 and hmac(sha1) async hash drivers Add sha1 and hmac(sha1) async hash drivers Signed-off-by: Uri Simchoni Signed-off-by: Herbert Xu --- drivers/crypto/mv_cesa.c | 514 ++++++++++++++++++++++++++++++++++++++++++++++- drivers/crypto/mv_cesa.h | 40 +++- 2 files changed, 542 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index d0fb10e701c5..1cee5a937092 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -14,8 +14,14 @@ #include #include #include +#include +#include #include "mv_cesa.h" + +#define MV_CESA "MV-CESA:" +#define MAX_HW_HASH_SIZE 0xFFFF + /* * STM: * /---------------------------------------\ @@ -38,7 +44,7 @@ enum engine_status { * @dst_sg_it: sg iterator for dst * @sg_src_left: bytes left in src to process (scatter list) * @src_start: offset to add to src start position (scatter list) - * @crypt_len: length of current crypt process + * @crypt_len: length of current hw crypt/hash process * @hw_nbytes: total bytes to process in hw for this request * @copy_back: whether to copy data back (crypt) or not (hash) * @sg_dst_left: bytes left dst to process in this scatter list @@ -81,6 +87,8 @@ struct crypto_priv { struct req_progress p; int max_req_size; int sram_size; + int has_sha1; + int has_hmac_sha1; }; static struct crypto_priv *cpg; @@ -102,6 +110,31 @@ struct mv_req_ctx { int decrypt; }; +enum hash_op { + COP_SHA1, + COP_HMAC_SHA1 +}; + +struct mv_tfm_hash_ctx { + struct crypto_shash *fallback; + struct crypto_shash *base_hash; + u32 ivs[2 * SHA1_DIGEST_SIZE / 4]; + int count_add; + enum hash_op op; +}; + +struct mv_req_hash_ctx { + u64 count; + u32 state[SHA1_DIGEST_SIZE / 4]; + u8 buffer[SHA1_BLOCK_SIZE]; + int first_hash; /* marks that we don't have previous state */ + int last_chunk; /* marks that this is the 'final' request */ + int extra_bytes; /* unprocessed bytes in buffer */ + enum hash_op op; + int count_add; + struct scatterlist dummysg; +}; + static void compute_aes_dec_key(struct mv_ctx *ctx) { struct crypto_aes_ctx gen_aes_key; @@ -265,6 +298,132 @@ static void mv_crypto_algo_completion(void) memcpy(req->info, cpg->sram + SRAM_DATA_IV_BUF, 16); } +static void mv_process_hash_current(int first_block) +{ + struct ahash_request *req = ahash_request_cast(cpg->cur_req); + struct mv_req_hash_ctx *req_ctx = ahash_request_ctx(req); + struct req_progress *p = &cpg->p; + struct sec_accel_config op = { 0 }; + int is_last; + + switch (req_ctx->op) { + case COP_SHA1: + default: + op.config = CFG_OP_MAC_ONLY | CFG_MACM_SHA1; + break; + case COP_HMAC_SHA1: + op.config = CFG_OP_MAC_ONLY | CFG_MACM_HMAC_SHA1; + break; + } + + op.mac_src_p = + MAC_SRC_DATA_P(SRAM_DATA_IN_START) | MAC_SRC_TOTAL_LEN((u32) + req_ctx-> + count); + + setup_data_in(); + + op.mac_digest = + MAC_DIGEST_P(SRAM_DIGEST_BUF) | MAC_FRAG_LEN(p->crypt_len); + op.mac_iv = + MAC_INNER_IV_P(SRAM_HMAC_IV_IN) | + MAC_OUTER_IV_P(SRAM_HMAC_IV_OUT); + + is_last = req_ctx->last_chunk + && (p->hw_processed_bytes + p->crypt_len >= p->hw_nbytes) + && (req_ctx->count <= MAX_HW_HASH_SIZE); + if (req_ctx->first_hash) { + if (is_last) + op.config |= CFG_NOT_FRAG; + else + op.config |= CFG_FIRST_FRAG; + + req_ctx->first_hash = 0; + } else { + if (is_last) + op.config |= CFG_LAST_FRAG; + else + op.config |= CFG_MID_FRAG; + } + + memcpy(cpg->sram + SRAM_CONFIG, &op, sizeof(struct sec_accel_config)); + + writel(SRAM_CONFIG, cpg->reg + SEC_ACCEL_DESC_P0); + /* GO */ + writel(SEC_CMD_EN_SEC_ACCL0, cpg->reg + SEC_ACCEL_CMD); + + /* + * XXX: add timer if the interrupt does not occur for some mystery + * reason + */ +} + +static inline int mv_hash_import_sha1_ctx(const struct mv_req_hash_ctx *ctx, + struct shash_desc *desc) +{ + int i; + struct sha1_state shash_state; + + shash_state.count = ctx->count + ctx->count_add; + for (i = 0; i < 5; i++) + shash_state.state[i] = ctx->state[i]; + memcpy(shash_state.buffer, ctx->buffer, sizeof(shash_state.buffer)); + return crypto_shash_import(desc, &shash_state); +} + +static int mv_hash_final_fallback(struct ahash_request *req) +{ + const struct mv_tfm_hash_ctx *tfm_ctx = crypto_tfm_ctx(req->base.tfm); + struct mv_req_hash_ctx *req_ctx = ahash_request_ctx(req); + struct { + struct shash_desc shash; + char ctx[crypto_shash_descsize(tfm_ctx->fallback)]; + } desc; + int rc; + + desc.shash.tfm = tfm_ctx->fallback; + desc.shash.flags = CRYPTO_TFM_REQ_MAY_SLEEP; + if (unlikely(req_ctx->first_hash)) { + crypto_shash_init(&desc.shash); + crypto_shash_update(&desc.shash, req_ctx->buffer, + req_ctx->extra_bytes); + } else { + /* only SHA1 for now.... + */ + rc = mv_hash_import_sha1_ctx(req_ctx, &desc.shash); + if (rc) + goto out; + } + rc = crypto_shash_final(&desc.shash, req->result); +out: + return rc; +} + +static void mv_hash_algo_completion(void) +{ + struct ahash_request *req = ahash_request_cast(cpg->cur_req); + struct mv_req_hash_ctx *ctx = ahash_request_ctx(req); + + if (ctx->extra_bytes) + copy_src_to_buf(&cpg->p, ctx->buffer, ctx->extra_bytes); + sg_miter_stop(&cpg->p.src_sg_it); + + ctx->state[0] = readl(cpg->reg + DIGEST_INITIAL_VAL_A); + ctx->state[1] = readl(cpg->reg + DIGEST_INITIAL_VAL_B); + ctx->state[2] = readl(cpg->reg + DIGEST_INITIAL_VAL_C); + ctx->state[3] = readl(cpg->reg + DIGEST_INITIAL_VAL_D); + ctx->state[4] = readl(cpg->reg + DIGEST_INITIAL_VAL_E); + + if (likely(ctx->last_chunk)) { + if (likely(ctx->count <= MAX_HW_HASH_SIZE)) { + memcpy(req->result, cpg->sram + SRAM_DIGEST_BUF, + crypto_ahash_digestsize(crypto_ahash_reqtfm + (req))); + } else + mv_hash_final_fallback(req); + } +} + static void dequeue_complete_req(void) { struct crypto_async_request *req = cpg->cur_req; @@ -332,7 +491,7 @@ static int count_sgs(struct scatterlist *sl, unsigned int total_bytes) return i; } -static void mv_enqueue_new_req(struct ablkcipher_request *req) +static void mv_start_new_crypt_req(struct ablkcipher_request *req) { struct req_progress *p = &cpg->p; int num_sgs; @@ -353,11 +512,68 @@ static void mv_enqueue_new_req(struct ablkcipher_request *req) mv_process_current_q(1); } +static void mv_start_new_hash_req(struct ahash_request *req) +{ + struct req_progress *p = &cpg->p; + struct mv_req_hash_ctx *ctx = ahash_request_ctx(req); + const struct mv_tfm_hash_ctx *tfm_ctx = crypto_tfm_ctx(req->base.tfm); + int num_sgs, hw_bytes, old_extra_bytes, rc; + cpg->cur_req = &req->base; + memset(p, 0, sizeof(struct req_progress)); + hw_bytes = req->nbytes + ctx->extra_bytes; + old_extra_bytes = ctx->extra_bytes; + + if (unlikely(ctx->extra_bytes)) { + memcpy(cpg->sram + SRAM_DATA_IN_START, ctx->buffer, + ctx->extra_bytes); + p->crypt_len = ctx->extra_bytes; + } + + memcpy(cpg->sram + SRAM_HMAC_IV_IN, tfm_ctx->ivs, sizeof(tfm_ctx->ivs)); + + if (unlikely(!ctx->first_hash)) { + writel(ctx->state[0], cpg->reg + DIGEST_INITIAL_VAL_A); + writel(ctx->state[1], cpg->reg + DIGEST_INITIAL_VAL_B); + writel(ctx->state[2], cpg->reg + DIGEST_INITIAL_VAL_C); + writel(ctx->state[3], cpg->reg + DIGEST_INITIAL_VAL_D); + writel(ctx->state[4], cpg->reg + DIGEST_INITIAL_VAL_E); + } + + ctx->extra_bytes = hw_bytes % SHA1_BLOCK_SIZE; + if (ctx->extra_bytes != 0 + && (!ctx->last_chunk || ctx->count > MAX_HW_HASH_SIZE)) + hw_bytes -= ctx->extra_bytes; + else + ctx->extra_bytes = 0; + + num_sgs = count_sgs(req->src, req->nbytes); + sg_miter_start(&p->src_sg_it, req->src, num_sgs, SG_MITER_FROM_SG); + + if (hw_bytes) { + p->hw_nbytes = hw_bytes; + p->complete = mv_hash_algo_completion; + p->process = mv_process_hash_current; + + mv_process_hash_current(1); + } else { + copy_src_to_buf(p, ctx->buffer + old_extra_bytes, + ctx->extra_bytes - old_extra_bytes); + sg_miter_stop(&p->src_sg_it); + if (ctx->last_chunk) + rc = mv_hash_final_fallback(req); + else + rc = 0; + cpg->eng_st = ENGINE_IDLE; + local_bh_disable(); + req->base.complete(&req->base, rc); + local_bh_enable(); + } +} + static int queue_manag(void *data) { cpg->eng_st = ENGINE_IDLE; do { - struct ablkcipher_request *req; struct crypto_async_request *async_req = NULL; struct crypto_async_request *backlog; @@ -383,9 +599,18 @@ static int queue_manag(void *data) } if (async_req) { - req = container_of(async_req, - struct ablkcipher_request, base); - mv_enqueue_new_req(req); + if (async_req->tfm->__crt_alg->cra_type != + &crypto_ahash_type) { + struct ablkcipher_request *req = + container_of(async_req, + struct ablkcipher_request, + base); + mv_start_new_crypt_req(req); + } else { + struct ahash_request *req = + ahash_request_cast(async_req); + mv_start_new_hash_req(req); + } async_req = NULL; } @@ -457,6 +682,215 @@ static int mv_cra_init(struct crypto_tfm *tfm) return 0; } +static void mv_init_hash_req_ctx(struct mv_req_hash_ctx *ctx, int op, + int is_last, unsigned int req_len, + int count_add) +{ + memset(ctx, 0, sizeof(*ctx)); + ctx->op = op; + ctx->count = req_len; + ctx->first_hash = 1; + ctx->last_chunk = is_last; + ctx->count_add = count_add; +} + +static void mv_update_hash_req_ctx(struct mv_req_hash_ctx *ctx, int is_last, + unsigned req_len) +{ + ctx->last_chunk = is_last; + ctx->count += req_len; +} + +static int mv_hash_init(struct ahash_request *req) +{ + const struct mv_tfm_hash_ctx *tfm_ctx = crypto_tfm_ctx(req->base.tfm); + mv_init_hash_req_ctx(ahash_request_ctx(req), tfm_ctx->op, 0, 0, + tfm_ctx->count_add); + return 0; +} + +static int mv_hash_update(struct ahash_request *req) +{ + if (!req->nbytes) + return 0; + + mv_update_hash_req_ctx(ahash_request_ctx(req), 0, req->nbytes); + return mv_handle_req(&req->base); +} + +static int mv_hash_final(struct ahash_request *req) +{ + struct mv_req_hash_ctx *ctx = ahash_request_ctx(req); + /* dummy buffer of 4 bytes */ + sg_init_one(&ctx->dummysg, ctx->buffer, 4); + /* I think I'm allowed to do that... */ + ahash_request_set_crypt(req, &ctx->dummysg, req->result, 0); + mv_update_hash_req_ctx(ctx, 1, 0); + return mv_handle_req(&req->base); +} + +static int mv_hash_finup(struct ahash_request *req) +{ + if (!req->nbytes) + return mv_hash_final(req); + + mv_update_hash_req_ctx(ahash_request_ctx(req), 1, req->nbytes); + return mv_handle_req(&req->base); +} + +static int mv_hash_digest(struct ahash_request *req) +{ + const struct mv_tfm_hash_ctx *tfm_ctx = crypto_tfm_ctx(req->base.tfm); + mv_init_hash_req_ctx(ahash_request_ctx(req), tfm_ctx->op, 1, + req->nbytes, tfm_ctx->count_add); + return mv_handle_req(&req->base); +} + +static void mv_hash_init_ivs(struct mv_tfm_hash_ctx *ctx, const void *istate, + const void *ostate) +{ + const struct sha1_state *isha1_state = istate, *osha1_state = ostate; + int i; + for (i = 0; i < 5; i++) { + ctx->ivs[i] = cpu_to_be32(isha1_state->state[i]); + ctx->ivs[i + 5] = cpu_to_be32(osha1_state->state[i]); + } +} + +static int mv_hash_setkey(struct crypto_ahash *tfm, const u8 * key, + unsigned int keylen) +{ + int rc; + struct mv_tfm_hash_ctx *ctx = crypto_tfm_ctx(&tfm->base); + int bs, ds, ss; + + if (!ctx->base_hash) + return 0; + + rc = crypto_shash_setkey(ctx->fallback, key, keylen); + if (rc) + return rc; + + /* Can't see a way to extract the ipad/opad from the fallback tfm + so I'm basically copying code from the hmac module */ + bs = crypto_shash_blocksize(ctx->base_hash); + ds = crypto_shash_digestsize(ctx->base_hash); + ss = crypto_shash_statesize(ctx->base_hash); + + { + struct { + struct shash_desc shash; + char ctx[crypto_shash_descsize(ctx->base_hash)]; + } desc; + unsigned int i; + char ipad[ss]; + char opad[ss]; + + desc.shash.tfm = ctx->base_hash; + desc.shash.flags = crypto_shash_get_flags(ctx->base_hash) & + CRYPTO_TFM_REQ_MAY_SLEEP; + + if (keylen > bs) { + int err; + + err = + crypto_shash_digest(&desc.shash, key, keylen, ipad); + if (err) + return err; + + keylen = ds; + } else + memcpy(ipad, key, keylen); + + memset(ipad + keylen, 0, bs - keylen); + memcpy(opad, ipad, bs); + + for (i = 0; i < bs; i++) { + ipad[i] ^= 0x36; + opad[i] ^= 0x5c; + } + + rc = crypto_shash_init(&desc.shash) ? : + crypto_shash_update(&desc.shash, ipad, bs) ? : + crypto_shash_export(&desc.shash, ipad) ? : + crypto_shash_init(&desc.shash) ? : + crypto_shash_update(&desc.shash, opad, bs) ? : + crypto_shash_export(&desc.shash, opad); + + if (rc == 0) + mv_hash_init_ivs(ctx, ipad, opad); + + return rc; + } +} + +static int mv_cra_hash_init(struct crypto_tfm *tfm, const char *base_hash_name, + enum hash_op op, int count_add) +{ + const char *fallback_driver_name = tfm->__crt_alg->cra_name; + struct mv_tfm_hash_ctx *ctx = crypto_tfm_ctx(tfm); + struct crypto_shash *fallback_tfm = NULL; + struct crypto_shash *base_hash = NULL; + int err = -ENOMEM; + + ctx->op = op; + ctx->count_add = count_add; + + /* Allocate a fallback and abort if it failed. */ + fallback_tfm = crypto_alloc_shash(fallback_driver_name, 0, + CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(fallback_tfm)) { + printk(KERN_WARNING MV_CESA + "Fallback driver '%s' could not be loaded!\n", + fallback_driver_name); + err = PTR_ERR(fallback_tfm); + goto out; + } + ctx->fallback = fallback_tfm; + + if (base_hash_name) { + /* Allocate a hash to compute the ipad/opad of hmac. */ + base_hash = crypto_alloc_shash(base_hash_name, 0, + CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(base_hash)) { + printk(KERN_WARNING MV_CESA + "Base driver '%s' could not be loaded!\n", + base_hash_name); + err = PTR_ERR(fallback_tfm); + goto err_bad_base; + } + } + ctx->base_hash = base_hash; + + crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), + sizeof(struct mv_req_hash_ctx) + + crypto_shash_descsize(ctx->fallback)); + return 0; +err_bad_base: + crypto_free_shash(fallback_tfm); +out: + return err; +} + +static void mv_cra_hash_exit(struct crypto_tfm *tfm) +{ + struct mv_tfm_hash_ctx *ctx = crypto_tfm_ctx(tfm); + + crypto_free_shash(ctx->fallback); + if (ctx->base_hash) + crypto_free_shash(ctx->base_hash); +} + +static int mv_cra_hash_sha1_init(struct crypto_tfm *tfm) +{ + return mv_cra_hash_init(tfm, NULL, COP_SHA1, 0); +} + +static int mv_cra_hash_hmac_sha1_init(struct crypto_tfm *tfm) +{ + return mv_cra_hash_init(tfm, "sha1", COP_HMAC_SHA1, SHA1_BLOCK_SIZE); +} + irqreturn_t crypto_int(int irq, void *priv) { u32 val; @@ -519,6 +953,53 @@ struct crypto_alg mv_aes_alg_cbc = { }, }; +struct ahash_alg mv_sha1_alg = { + .init = mv_hash_init, + .update = mv_hash_update, + .final = mv_hash_final, + .finup = mv_hash_finup, + .digest = mv_hash_digest, + .halg = { + .digestsize = SHA1_DIGEST_SIZE, + .base = { + .cra_name = "sha1", + .cra_driver_name = "mv-sha1", + .cra_priority = 300, + .cra_flags = + CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA1_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct mv_tfm_hash_ctx), + .cra_init = mv_cra_hash_sha1_init, + .cra_exit = mv_cra_hash_exit, + .cra_module = THIS_MODULE, + } + } +}; + +struct ahash_alg mv_hmac_sha1_alg = { + .init = mv_hash_init, + .update = mv_hash_update, + .final = mv_hash_final, + .finup = mv_hash_finup, + .digest = mv_hash_digest, + .setkey = mv_hash_setkey, + .halg = { + .digestsize = SHA1_DIGEST_SIZE, + .base = { + .cra_name = "hmac(sha1)", + .cra_driver_name = "mv-hmac-sha1", + .cra_priority = 300, + .cra_flags = + CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA1_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct mv_tfm_hash_ctx), + .cra_init = mv_cra_hash_hmac_sha1_init, + .cra_exit = mv_cra_hash_exit, + .cra_module = THIS_MODULE, + } + } +}; + static int mv_probe(struct platform_device *pdev) { struct crypto_priv *cp; @@ -527,7 +1008,7 @@ static int mv_probe(struct platform_device *pdev) int ret; if (cpg) { - printk(KERN_ERR "Second crypto dev?\n"); + printk(KERN_ERR MV_CESA "Second crypto dev?\n"); return -EEXIST; } @@ -591,6 +1072,21 @@ static int mv_probe(struct platform_device *pdev) ret = crypto_register_alg(&mv_aes_alg_cbc); if (ret) goto err_unreg_ecb; + + ret = crypto_register_ahash(&mv_sha1_alg); + if (ret == 0) + cpg->has_sha1 = 1; + else + printk(KERN_WARNING MV_CESA "Could not register sha1 driver\n"); + + ret = crypto_register_ahash(&mv_hmac_sha1_alg); + if (ret == 0) { + cpg->has_hmac_sha1 = 1; + } else { + printk(KERN_WARNING MV_CESA + "Could not register hmac-sha1 driver\n"); + } + return 0; err_unreg_ecb: crypto_unregister_alg(&mv_aes_alg_ecb); @@ -615,6 +1111,10 @@ static int mv_remove(struct platform_device *pdev) crypto_unregister_alg(&mv_aes_alg_ecb); crypto_unregister_alg(&mv_aes_alg_cbc); + if (cp->has_sha1) + crypto_unregister_ahash(&mv_sha1_alg); + if (cp->has_hmac_sha1) + crypto_unregister_ahash(&mv_hmac_sha1_alg); kthread_stop(cp->queue_th); free_irq(cp->irq, cp); memset(cp->sram, 0, cp->sram_size); diff --git a/drivers/crypto/mv_cesa.h b/drivers/crypto/mv_cesa.h index c3e25d3bb171..08fcb1116d90 100644 --- a/drivers/crypto/mv_cesa.h +++ b/drivers/crypto/mv_cesa.h @@ -1,6 +1,10 @@ #ifndef __MV_CRYPTO_H__ #define DIGEST_INITIAL_VAL_A 0xdd00 +#define DIGEST_INITIAL_VAL_B 0xdd04 +#define DIGEST_INITIAL_VAL_C 0xdd08 +#define DIGEST_INITIAL_VAL_D 0xdd0c +#define DIGEST_INITIAL_VAL_E 0xdd10 #define DES_CMD_REG 0xdd58 #define SEC_ACCEL_CMD 0xde00 @@ -70,6 +74,10 @@ struct sec_accel_config { #define CFG_AES_LEN_128 (0 << 24) #define CFG_AES_LEN_192 (1 << 24) #define CFG_AES_LEN_256 (2 << 24) +#define CFG_NOT_FRAG (0 << 30) +#define CFG_FIRST_FRAG (1 << 30) +#define CFG_LAST_FRAG (2 << 30) +#define CFG_MID_FRAG (3 << 30) u32 enc_p; #define ENC_P_SRC(x) (x) @@ -90,7 +98,11 @@ struct sec_accel_config { #define MAC_SRC_TOTAL_LEN(x) ((x) << 16) u32 mac_digest; +#define MAC_DIGEST_P(x) (x) +#define MAC_FRAG_LEN(x) ((x) << 16) u32 mac_iv; +#define MAC_INNER_IV_P(x) (x) +#define MAC_OUTER_IV_P(x) ((x) << 16) }__attribute__ ((packed)); /* * /-----------\ 0 @@ -101,19 +113,37 @@ struct sec_accel_config { * | IV IN | 4 * 4 * |-----------| 0x40 (inplace) * | IV BUF | 4 * 4 - * |-----------| 0x50 + * |-----------| 0x80 * | DATA IN | 16 * x (max ->max_req_size) - * |-----------| 0x50 (inplace operation) + * |-----------| 0x80 (inplace operation) * | DATA OUT | 16 * x (max ->max_req_size) * \-----------/ SRAM size */ + + /* Hashing memory map: + * /-----------\ 0 + * | ACCEL CFG | 4 * 8 + * |-----------| 0x20 + * | Inner IV | 5 * 4 + * |-----------| 0x34 + * | Outer IV | 5 * 4 + * |-----------| 0x48 + * | Output BUF| 5 * 4 + * |-----------| 0x80 + * | DATA IN | 64 * x (max ->max_req_size) + * \-----------/ SRAM size + */ #define SRAM_CONFIG 0x00 #define SRAM_DATA_KEY_P 0x20 #define SRAM_DATA_IV 0x40 #define SRAM_DATA_IV_BUF 0x40 -#define SRAM_DATA_IN_START 0x50 -#define SRAM_DATA_OUT_START 0x50 +#define SRAM_DATA_IN_START 0x80 +#define SRAM_DATA_OUT_START 0x80 + +#define SRAM_HMAC_IV_IN 0x20 +#define SRAM_HMAC_IV_OUT 0x34 +#define SRAM_DIGEST_BUF 0x48 -#define SRAM_CFG_SPACE 0x50 +#define SRAM_CFG_SPACE 0x80 #endif -- cgit v1.2.3 From 7422f27a8ad7f6a7474e324a61e5a7f8be166c25 Mon Sep 17 00:00:00 2001 From: Ivo Clarysse Date: Thu, 8 Apr 2010 16:14:44 +0200 Subject: MXC: mxc_nand: set NFC registers after reset This patch allows the mxc_nand driver to reset the NAND flash controller. NFC registers are (re-)set after completion of the reset, as a reset will have reverted the NFC registers to their default values. Signed-off-by: Ivo Clarysse Signed-off-by: Sascha Hauer --- drivers/mtd/nand/mxc_nand.c | 90 ++++++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index b2900d8406d3..ed27d38de27a 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -542,6 +542,41 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr) } } +static void preset(struct mtd_info *mtd) +{ + struct nand_chip *nand_chip = mtd->priv; + struct mxc_nand_host *host = nand_chip->priv; + uint16_t tmp; + + /* disable interrupt, disable spare enable */ + tmp = readw(host->regs + NFC_CONFIG1); + tmp |= NFC_INT_MSK; + tmp &= ~NFC_SP_EN; + if (nand_chip->ecc.mode == NAND_ECC_HW) { + tmp |= NFC_ECC_EN; + } else { + tmp &= ~NFC_ECC_EN; + } + writew(tmp, host->regs + NFC_CONFIG1); + /* preset operation */ + + /* Unlock the internal RAM Buffer */ + writew(0x2, host->regs + NFC_CONFIG); + + /* Blocks to be unlocked */ + if (nfc_is_v21()) { + writew(0x0, host->regs + NFC_V21_UNLOCKSTART_BLKADDR); + writew(0xffff, host->regs + NFC_V21_UNLOCKEND_BLKADDR); + } else if (nfc_is_v1()) { + writew(0x0, host->regs + NFC_V1_UNLOCKSTART_BLKADDR); + writew(0x4000, host->regs + NFC_V1_UNLOCKEND_BLKADDR); + } else + BUG(); + + /* Unlock Block Command for given address range */ + writew(0x4, host->regs + NFC_WRPROT); +} + /* Used by the upper layer to write command to NAND Flash for * different operations to be carried out on NAND Flash */ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, @@ -559,6 +594,10 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, /* Command pre-processing step */ switch (command) { + case NAND_CMD_RESET: + send_cmd(host, command, false); + preset(mtd); + break; case NAND_CMD_STATUS: host->buf_start = 0; @@ -679,7 +718,6 @@ static int __init mxcnd_probe(struct platform_device *pdev) struct mxc_nand_platform_data *pdata = pdev->dev.platform_data; struct mxc_nand_host *host; struct resource *res; - uint16_t tmp; int err = 0, nr_parts = 0; struct nand_ecclayout *oob_smallpage, *oob_largepage; @@ -743,51 +781,17 @@ static int __init mxcnd_probe(struct platform_device *pdev) host->spare_len = 64; oob_smallpage = &nandv2_hw_eccoob_smallpage; oob_largepage = &nandv2_hw_eccoob_largepage; + this->ecc.bytes = 9; } else if (nfc_is_v1()) { host->regs = host->base; host->spare0 = host->base + 0x800; host->spare_len = 16; oob_smallpage = &nandv1_hw_eccoob_smallpage; oob_largepage = &nandv1_hw_eccoob_largepage; - } else - BUG(); - - /* disable interrupt and spare enable */ - tmp = readw(host->regs + NFC_CONFIG1); - tmp |= NFC_INT_MSK; - tmp &= ~NFC_SP_EN; - writew(tmp, host->regs + NFC_CONFIG1); - - init_waitqueue_head(&host->irq_waitq); - - host->irq = platform_get_irq(pdev, 0); - - err = request_irq(host->irq, mxc_nfc_irq, 0, DRIVER_NAME, host); - if (err) - goto eirq; - - /* Reset NAND */ - this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); - - /* preset operation */ - /* Unlock the internal RAM Buffer */ - writew(0x2, host->regs + NFC_CONFIG); - - /* Blocks to be unlocked */ - if (nfc_is_v21()) { - writew(0x0, host->regs + NFC_V21_UNLOCKSTART_BLKADDR); - writew(0xffff, host->regs + NFC_V21_UNLOCKEND_BLKADDR); - this->ecc.bytes = 9; - } else if (nfc_is_v1()) { - writew(0x0, host->regs + NFC_V1_UNLOCKSTART_BLKADDR); - writew(0x4000, host->regs + NFC_V1_UNLOCKEND_BLKADDR); this->ecc.bytes = 3; } else BUG(); - /* Unlock Block Command for given address range */ - writew(0x4, host->regs + NFC_WRPROT); - this->ecc.size = 512; this->ecc.layout = oob_smallpage; @@ -796,14 +800,8 @@ static int __init mxcnd_probe(struct platform_device *pdev) this->ecc.hwctl = mxc_nand_enable_hwecc; this->ecc.correct = mxc_nand_correct_data; this->ecc.mode = NAND_ECC_HW; - tmp = readw(host->regs + NFC_CONFIG1); - tmp |= NFC_ECC_EN; - writew(tmp, host->regs + NFC_CONFIG1); } else { this->ecc.mode = NAND_ECC_SOFT; - tmp = readw(host->regs + NFC_CONFIG1); - tmp &= ~NFC_ECC_EN; - writew(tmp, host->regs + NFC_CONFIG1); } /* NAND bus width determines access funtions used by upper layer */ @@ -817,6 +815,14 @@ static int __init mxcnd_probe(struct platform_device *pdev) this->options |= NAND_USE_FLASH_BBT; } + init_waitqueue_head(&host->irq_waitq); + + host->irq = platform_get_irq(pdev, 0); + + err = request_irq(host->irq, mxc_nfc_irq, 0, DRIVER_NAME, host); + if (err) + goto eirq; + /* first scan to find the device and get the page size */ if (nand_scan_ident(mtd, 1)) { err = -ENXIO; -- cgit v1.2.3 From 63f4079b6a90e2a8ee64c5900a6d4d0bcb79bc65 Mon Sep 17 00:00:00 2001 From: Ivo Clarysse Date: Thu, 8 Apr 2010 16:16:51 +0200 Subject: MXC: mxc_nand: support i.MX21 On i.MX21 SoCs, if the NFC_CONFIG1:NFC_INT_MASK bit is set, NFC_CONFIG2:NFC_INT always reads out zero, even if an operation is completed. This patch uses enable_irq and disable_irq_nosync instead of NFC_CONFIG1:NFC_INT_MASK to mask NFC interrupts. This allows NFC_CONFIG2:NFC_INT to also be used to detect operation completion on i.MX21. The i.MX21 NFC does not signal reset completion using NFC_CONFIG1:NFC_INT_MASK, so instead reset completion is tested by checking if NFC_CONFIG2 becomes 0. Signed-off-by: Ivo Clarysse Signed-off-by: Sascha Hauer --- drivers/mtd/nand/mxc_nand.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index ed27d38de27a..fb03aff8e83a 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -38,7 +38,7 @@ #define DRIVER_NAME "mxc_nand" #define nfc_is_v21() (cpu_is_mx25() || cpu_is_mx35()) -#define nfc_is_v1() (cpu_is_mx31() || cpu_is_mx27()) +#define nfc_is_v1() (cpu_is_mx31() || cpu_is_mx27() || cpu_is_mx21()) /* Addresses for NFC registers */ #define NFC_BUF_SIZE 0xE00 @@ -168,11 +168,7 @@ static irqreturn_t mxc_nfc_irq(int irq, void *dev_id) { struct mxc_nand_host *host = dev_id; - uint16_t tmp; - - tmp = readw(host->regs + NFC_CONFIG1); - tmp |= NFC_INT_MSK; /* Disable interrupt */ - writew(tmp, host->regs + NFC_CONFIG1); + disable_irq_nosync(irq); wake_up(&host->irq_waitq); @@ -184,15 +180,13 @@ static irqreturn_t mxc_nfc_irq(int irq, void *dev_id) */ static void wait_op_done(struct mxc_nand_host *host, int useirq) { - uint32_t tmp; - int max_retries = 2000; + uint16_t tmp; + int max_retries = 8000; if (useirq) { if ((readw(host->regs + NFC_CONFIG2) & NFC_INT) == 0) { - tmp = readw(host->regs + NFC_CONFIG1); - tmp &= ~NFC_INT_MSK; /* Enable interrupt */ - writew(tmp, host->regs + NFC_CONFIG1); + enable_irq(host->irq); wait_event(host->irq_waitq, readw(host->regs + NFC_CONFIG2) & NFC_INT); @@ -226,8 +220,23 @@ static void send_cmd(struct mxc_nand_host *host, uint16_t cmd, int useirq) writew(cmd, host->regs + NFC_FLASH_CMD); writew(NFC_CMD, host->regs + NFC_CONFIG2); - /* Wait for operation to complete */ - wait_op_done(host, useirq); + if (cpu_is_mx21() && (cmd == NAND_CMD_RESET)) { + int max_retries = 100; + /* Reset completion is indicated by NFC_CONFIG2 */ + /* being set to 0 */ + while (max_retries-- > 0) { + if (readw(host->regs + NFC_CONFIG2) == 0) { + break; + } + udelay(1); + } + if (max_retries < 0) + DEBUG(MTD_DEBUG_LEVEL0, "%s: RESET failed\n", + __func__); + } else { + /* Wait for operation to complete */ + wait_op_done(host, useirq); + } } /* This function sends an address (or partial address) to the @@ -548,9 +557,9 @@ static void preset(struct mtd_info *mtd) struct mxc_nand_host *host = nand_chip->priv; uint16_t tmp; - /* disable interrupt, disable spare enable */ + /* enable interrupt, disable spare enable */ tmp = readw(host->regs + NFC_CONFIG1); - tmp |= NFC_INT_MSK; + tmp &= ~NFC_INT_MSK; tmp &= ~NFC_SP_EN; if (nand_chip->ecc.mode == NAND_ECC_HW) { tmp |= NFC_ECC_EN; @@ -819,7 +828,7 @@ static int __init mxcnd_probe(struct platform_device *pdev) host->irq = platform_get_irq(pdev, 0); - err = request_irq(host->irq, mxc_nfc_irq, 0, DRIVER_NAME, host); + err = request_irq(host->irq, mxc_nfc_irq, IRQF_DISABLED, DRIVER_NAME, host); if (err) goto eirq; -- cgit v1.2.3 From 4725f6f17691f4602e3e31d785da5a461a16ccfe Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 1 Apr 2010 10:03:23 +0200 Subject: ARM: MXC: mxcmmc: misc cleanups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Be more verbose on error messages and add one debug message. Signed-off-by: Daniel Mack Cc: Sascha Hauer Cc: Dan Williams Cc: Volker Ernst Cc: Jiri Kosina Cc: MichaÅ‚ MirosÅ‚aw Signed-off-by: Sascha Hauer --- drivers/mmc/host/mxcmmc.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 2df90412abb5..44a53ee5e212 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -151,6 +151,8 @@ static void mxcmci_softreset(struct mxcmci_host *host) { int i; + dev_dbg(mmc_dev(host->mmc), "mxcmci_softreset\n"); + /* reset sequence */ writew(STR_STP_CLK_RESET, host->base + MMC_REG_STR_STP_CLK); writew(STR_STP_CLK_RESET | STR_STP_CLK_START_CLK, @@ -290,16 +292,25 @@ static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat) dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n", stat); if (stat & STATUS_CRC_READ_ERR) { + dev_err(mmc_dev(host->mmc), "%s: -EILSEQ\n", __func__); data->error = -EILSEQ; } else if (stat & STATUS_CRC_WRITE_ERR) { u32 err_code = (stat >> 9) & 0x3; - if (err_code == 2) /* No CRC response */ + if (err_code == 2) { /* No CRC response */ + dev_err(mmc_dev(host->mmc), + "%s: No CRC -ETIMEDOUT\n", __func__); data->error = -ETIMEDOUT; - else + } else { + dev_err(mmc_dev(host->mmc), + "%s: -EILSEQ\n", __func__); data->error = -EILSEQ; + } } else if (stat & STATUS_TIME_OUT_READ) { + dev_err(mmc_dev(host->mmc), + "%s: read -ETIMEDOUT\n", __func__); data->error = -ETIMEDOUT; } else { + dev_err(mmc_dev(host->mmc), "%s: -EIO\n", __func__); data->error = -EIO; } } else { @@ -433,8 +444,6 @@ static int mxcmci_transfer_data(struct mxcmci_host *host) struct scatterlist *sg; int stat, i; - host->datasize = 0; - host->data = data; host->datasize = 0; -- cgit v1.2.3 From f441b993101d4ee95222ccbaad1e0dd53ea90b64 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 1 Apr 2010 10:03:24 +0200 Subject: ARM: MXC: mxcmmc: Teach the driver SDIO operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Successfully tested on MX31 hardware using libertas SDIO peripherals. Signed-off-by: Daniel Mack Cc: Sascha Hauer Cc: Dan Williams Cc: Volker Ernst Cc: Jiri Kosina Cc: MichaÅ‚ MirosÅ‚aw Signed-off-by: Sascha Hauer --- drivers/mmc/host/mxcmmc.c | 70 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 44a53ee5e212..51e880c8f193 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -119,6 +119,7 @@ struct mxcmci_host { int detect_irq; int dma; int do_dma; + int use_sdio; unsigned int power_mode; struct imxmmc_platform_data *pdata; @@ -138,6 +139,7 @@ struct mxcmci_host { int clock; struct work_struct datawork; + spinlock_t lock; }; static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios); @@ -226,6 +228,9 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd, unsigned int cmdat) { + u32 int_cntr; + unsigned long flags; + WARN_ON(host->cmd != NULL); host->cmd = cmd; @@ -249,12 +254,16 @@ static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd, return -EINVAL; } + int_cntr = INT_END_CMD_RES_EN; + if (mxcmci_use_dma(host)) - writel(INT_READ_OP_EN | INT_WRITE_OP_DONE_EN | - INT_END_CMD_RES_EN, - host->base + MMC_REG_INT_CNTR); - else - writel(INT_END_CMD_RES_EN, host->base + MMC_REG_INT_CNTR); + int_cntr |= INT_READ_OP_EN | INT_WRITE_OP_DONE_EN; + + spin_lock_irqsave(&host->lock, flags); + if (host->use_sdio) + int_cntr |= INT_SDIO_IRQ_EN; + writel(int_cntr, host->base + MMC_REG_INT_CNTR); + spin_unlock_irqrestore(&host->lock, flags); writew(cmd->opcode, host->base + MMC_REG_CMD); writel(cmd->arg, host->base + MMC_REG_ARG); @@ -266,7 +275,14 @@ static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd, static void mxcmci_finish_request(struct mxcmci_host *host, struct mmc_request *req) { - writel(0, host->base + MMC_REG_INT_CNTR); + u32 int_cntr = 0; + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + if (host->use_sdio) + int_cntr |= INT_SDIO_IRQ_EN; + writel(int_cntr, host->base + MMC_REG_INT_CNTR); + spin_unlock_irqrestore(&host->lock, flags); host->req = NULL; host->cmd = NULL; @@ -532,15 +548,27 @@ static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat) static irqreturn_t mxcmci_irq(int irq, void *devid) { struct mxcmci_host *host = devid; + unsigned long flags; + bool sdio_irq; u32 stat; stat = readl(host->base + MMC_REG_STATUS); - writel(stat, host->base + MMC_REG_STATUS); + writel(stat & ~STATUS_SDIO_INT_ACTIVE, host->base + MMC_REG_STATUS); dev_dbg(mmc_dev(host->mmc), "%s: 0x%08x\n", __func__, stat); + spin_lock_irqsave(&host->lock, flags); + sdio_irq = (stat & STATUS_SDIO_INT_ACTIVE) && host->use_sdio; + spin_unlock_irqrestore(&host->lock, flags); + + if (sdio_irq) { + writel(STATUS_SDIO_INT_ACTIVE, host->base + MMC_REG_STATUS); + mmc_signal_sdio_irq(host->mmc); + } + if (stat & STATUS_END_CMD_RESP) mxcmci_cmd_done(host, stat); + #ifdef HAS_DMA if (mxcmci_use_dma(host) && (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE))) @@ -677,11 +705,30 @@ static int mxcmci_get_ro(struct mmc_host *mmc) return -ENOSYS; } +static void mxcmci_enable_sdio_irq(struct mmc_host *mmc, int enable) +{ + struct mxcmci_host *host = mmc_priv(mmc); + unsigned long flags; + u32 int_cntr; + + spin_lock_irqsave(&host->lock, flags); + host->use_sdio = enable; + int_cntr = readl(host->base + MMC_REG_INT_CNTR); + + if (enable) + int_cntr |= INT_SDIO_IRQ_EN; + else + int_cntr &= ~INT_SDIO_IRQ_EN; + + writel(int_cntr, host->base + MMC_REG_INT_CNTR); + spin_unlock_irqrestore(&host->lock, flags); +} static const struct mmc_host_ops mxcmci_ops = { - .request = mxcmci_request, - .set_ios = mxcmci_set_ios, - .get_ro = mxcmci_get_ro, + .request = mxcmci_request, + .set_ios = mxcmci_set_ios, + .get_ro = mxcmci_get_ro, + .enable_sdio_irq = mxcmci_enable_sdio_irq, }; static int mxcmci_probe(struct platform_device *pdev) @@ -709,7 +756,7 @@ static int mxcmci_probe(struct platform_device *pdev) } mmc->ops = &mxcmci_ops; - mmc->caps = MMC_CAP_4_BIT_DATA; + mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; /* MMC core transfer sizes tunable parameters */ mmc->max_hw_segs = 64; @@ -728,6 +775,7 @@ static int mxcmci_probe(struct platform_device *pdev) host->mmc = mmc; host->pdata = pdev->dev.platform_data; + spin_lock_init(&host->lock); if (host->pdata && host->pdata->ocr_avail) mmc->ocr_avail = host->pdata->ocr_avail; -- cgit v1.2.3 From 3fcb027d7fd749569665d34a79ce2a8e00bc2ed6 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 1 Apr 2010 10:03:25 +0200 Subject: ARM: MXC: mxcmmc: work around a bug in the SDHC busy line handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MX3 SoCs have a silicon bug which corrupts CRC calculation of multi-block transfers when connected SDIO peripheral doesn't drive the BUSY line as required by the specs. One way to prevent this is to only allow 1-bit transfers. Another way is playing tricks with the DMA engine, but this isn't mainline yet. So for now, we live with the performance drawback of 1-bit transfers until a nicer solution is found. This patch introduces a new host controller callback 'init_card' which is for now only called from mmc_sdio_init_card(). Signed-off-by: Daniel Mack Cc: Sascha Hauer Cc: Dan Williams Cc: Volker Ernst Cc: Jiri Kosina Cc: MichaÅ‚ MirosÅ‚aw Signed-off-by: Sascha Hauer --- drivers/mmc/core/sdio.c | 6 ++++++ drivers/mmc/host/mxcmmc.c | 16 ++++++++++++++++ include/linux/mmc/host.h | 3 +++ 3 files changed, 25 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 2dd4cfe7ca17..b9dee28ee7d0 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -295,6 +295,12 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, card->type = MMC_TYPE_SDIO; + /* + * Call the optional HC's init_card function to handle quirks. + */ + if (host->ops->init_card) + host->ops->init_card(host, card); + /* * For native busses: set card RCA and quit open drain mode. */ diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 51e880c8f193..2c53024ee439 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -724,11 +724,27 @@ static void mxcmci_enable_sdio_irq(struct mmc_host *mmc, int enable) spin_unlock_irqrestore(&host->lock, flags); } +static void mxcmci_init_card(struct mmc_host *host, struct mmc_card *card) +{ + /* + * MX3 SoCs have a silicon bug which corrupts CRC calculation of + * multi-block transfers when connected SDIO peripheral doesn't + * drive the BUSY line as required by the specs. + * One way to prevent this is to only allow 1-bit transfers. + */ + + if (cpu_is_mx3() && card->type == MMC_TYPE_SDIO) + host->caps &= ~MMC_CAP_4_BIT_DATA; + else + host->caps |= MMC_CAP_4_BIT_DATA; +} + static const struct mmc_host_ops mxcmci_ops = { .request = mxcmci_request, .set_ios = mxcmci_set_ios, .get_ro = mxcmci_get_ro, .enable_sdio_irq = mxcmci_enable_sdio_irq, + .init_card = mxcmci_init_card, }; static int mxcmci_probe(struct platform_device *pdev) diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 43eaf5ca5848..3196c84cc630 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -108,6 +108,9 @@ struct mmc_host_ops { int (*get_cd)(struct mmc_host *host); void (*enable_sdio_irq)(struct mmc_host *host, int enable); + + /* optional callback for HC quirks */ + void (*init_card)(struct mmc_host *host, struct mmc_card *card); }; struct mmc_card; -- cgit v1.2.3 From 4f506e07e0a3dff34427cece255a8f390a78d5a0 Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Thu, 25 Mar 2010 18:02:58 +0000 Subject: intel-iommu: Fix boot inside 64bit virtualbox with io-apic disabled Commit 074835f0143b83845af5044af2739c52c9f53808 ("intel-iommu: Fix kernel hand if interrupt remapping disabled in BIOS") is adding a check for interrupt remapping disabled and is dereferencing the dmar_tbl pointer without checking its value. Unfortunately, this value is null when booting inside a 64bit virtual box guest with io-apic disabled, leading to a crash. With a check on it, the guest is now booting. It's triggering a WARN() in clockevent_delta2ns but it's better than not booting at all and allows the user to see there's something wrong on their io-apic setup. Signed-off-by: Arnaud Patard Signed-off-by: David Woodhouse --- drivers/pci/dmar.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index edc5f002e055..7771b2dd5978 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -1466,5 +1466,7 @@ int __init dmar_ir_support(void) { struct acpi_table_dmar *dmar; dmar = (struct acpi_table_dmar *)dmar_tbl; + if (!dmar) + return 0; return dmar->flags & 0x1; } -- cgit v1.2.3 From 8d318a50b3d72e3daf94131f91e1ab799a8d5ad4 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 30 Mar 2010 15:33:42 +0200 Subject: DMAENGINE: Support for ST-Ericssons DMA40 block v3 This is a straightforward driver for the ST-Ericsson DMA40 DMA controller found in U8500, implemented akin to the existing COH 901 318 driver. Signed-off-by: Linus Walleij Acked-by: Srinidh Kasagar Cc: STEricsson_nomadik_linux@list.st.com Cc: Alessandro Rubini Signed-off-by: Andrew Morton Signed-off-by: Dan Williams --- arch/arm/plat-nomadik/include/plat/ste_dma40.h | 239 +++ drivers/dma/Kconfig | 7 + drivers/dma/Makefile | 1 + drivers/dma/ste_dma40.c | 2596 ++++++++++++++++++++++++ drivers/dma/ste_dma40_ll.c | 454 +++++ drivers/dma/ste_dma40_ll.h | 354 ++++ 6 files changed, 3651 insertions(+) create mode 100644 arch/arm/plat-nomadik/include/plat/ste_dma40.h create mode 100644 drivers/dma/ste_dma40.c create mode 100644 drivers/dma/ste_dma40_ll.c create mode 100644 drivers/dma/ste_dma40_ll.h (limited to 'drivers') diff --git a/arch/arm/plat-nomadik/include/plat/ste_dma40.h b/arch/arm/plat-nomadik/include/plat/ste_dma40.h new file mode 100644 index 000000000000..4d12ea4ca361 --- /dev/null +++ b/arch/arm/plat-nomadik/include/plat/ste_dma40.h @@ -0,0 +1,239 @@ +/* + * arch/arm/plat-nomadik/include/plat/ste_dma40.h + * + * Copyright (C) ST-Ericsson 2007-2010 + * License terms: GNU General Public License (GPL) version 2 + * Author: Per Friden + * Author: Jonas Aaberg + */ + + +#ifndef STE_DMA40_H +#define STE_DMA40_H + +#include +#include +#include +#include + +/* dev types for memcpy */ +#define STEDMA40_DEV_DST_MEMORY (-1) +#define STEDMA40_DEV_SRC_MEMORY (-1) + +/* + * Description of bitfields of channel_type variable is available in + * the info structure. + */ + +/* Priority */ +#define STEDMA40_INFO_PRIO_TYPE_POS 2 +#define STEDMA40_HIGH_PRIORITY_CHANNEL (0x1 << STEDMA40_INFO_PRIO_TYPE_POS) +#define STEDMA40_LOW_PRIORITY_CHANNEL (0x2 << STEDMA40_INFO_PRIO_TYPE_POS) + +/* Mode */ +#define STEDMA40_INFO_CH_MODE_TYPE_POS 6 +#define STEDMA40_CHANNEL_IN_PHY_MODE (0x1 << STEDMA40_INFO_CH_MODE_TYPE_POS) +#define STEDMA40_CHANNEL_IN_LOG_MODE (0x2 << STEDMA40_INFO_CH_MODE_TYPE_POS) +#define STEDMA40_CHANNEL_IN_OPER_MODE (0x3 << STEDMA40_INFO_CH_MODE_TYPE_POS) + +/* Mode options */ +#define STEDMA40_INFO_CH_MODE_OPT_POS 8 +#define STEDMA40_PCHAN_BASIC_MODE (0x1 << STEDMA40_INFO_CH_MODE_OPT_POS) +#define STEDMA40_PCHAN_MODULO_MODE (0x2 << STEDMA40_INFO_CH_MODE_OPT_POS) +#define STEDMA40_PCHAN_DOUBLE_DST_MODE (0x3 << STEDMA40_INFO_CH_MODE_OPT_POS) +#define STEDMA40_LCHAN_SRC_PHY_DST_LOG (0x1 << STEDMA40_INFO_CH_MODE_OPT_POS) +#define STEDMA40_LCHAN_SRC_LOG_DST_PHS (0x2 << STEDMA40_INFO_CH_MODE_OPT_POS) +#define STEDMA40_LCHAN_SRC_LOG_DST_LOG (0x3 << STEDMA40_INFO_CH_MODE_OPT_POS) + +/* Interrupt */ +#define STEDMA40_INFO_TIM_POS 10 +#define STEDMA40_NO_TIM_FOR_LINK (0x0 << STEDMA40_INFO_TIM_POS) +#define STEDMA40_TIM_FOR_LINK (0x1 << STEDMA40_INFO_TIM_POS) + +/* End of channel_type configuration */ + +#define STEDMA40_ESIZE_8_BIT 0x0 +#define STEDMA40_ESIZE_16_BIT 0x1 +#define STEDMA40_ESIZE_32_BIT 0x2 +#define STEDMA40_ESIZE_64_BIT 0x3 + +/* The value 4 indicates that PEN-reg shall be set to 0 */ +#define STEDMA40_PSIZE_PHY_1 0x4 +#define STEDMA40_PSIZE_PHY_2 0x0 +#define STEDMA40_PSIZE_PHY_4 0x1 +#define STEDMA40_PSIZE_PHY_8 0x2 +#define STEDMA40_PSIZE_PHY_16 0x3 + +/* + * The number of elements differ in logical and + * physical mode + */ +#define STEDMA40_PSIZE_LOG_1 STEDMA40_PSIZE_PHY_2 +#define STEDMA40_PSIZE_LOG_4 STEDMA40_PSIZE_PHY_4 +#define STEDMA40_PSIZE_LOG_8 STEDMA40_PSIZE_PHY_8 +#define STEDMA40_PSIZE_LOG_16 STEDMA40_PSIZE_PHY_16 + +enum stedma40_flow_ctrl { + STEDMA40_NO_FLOW_CTRL, + STEDMA40_FLOW_CTRL, +}; + +enum stedma40_endianess { + STEDMA40_LITTLE_ENDIAN, + STEDMA40_BIG_ENDIAN +}; + +enum stedma40_periph_data_width { + STEDMA40_BYTE_WIDTH = STEDMA40_ESIZE_8_BIT, + STEDMA40_HALFWORD_WIDTH = STEDMA40_ESIZE_16_BIT, + STEDMA40_WORD_WIDTH = STEDMA40_ESIZE_32_BIT, + STEDMA40_DOUBLEWORD_WIDTH = STEDMA40_ESIZE_64_BIT +}; + +struct stedma40_half_channel_info { + enum stedma40_endianess endianess; + enum stedma40_periph_data_width data_width; + int psize; + enum stedma40_flow_ctrl flow_ctrl; +}; + +enum stedma40_xfer_dir { + STEDMA40_MEM_TO_MEM, + STEDMA40_MEM_TO_PERIPH, + STEDMA40_PERIPH_TO_MEM, + STEDMA40_PERIPH_TO_PERIPH +}; + + +/** + * struct stedma40_chan_cfg - Structure to be filled by client drivers. + * + * @dir: MEM 2 MEM, PERIPH 2 MEM , MEM 2 PERIPH, PERIPH 2 PERIPH + * @channel_type: priority, mode, mode options and interrupt configuration. + * @src_dev_type: Src device type + * @dst_dev_type: Dst device type + * @src_info: Parameters for dst half channel + * @dst_info: Parameters for dst half channel + * @pre_transfer_data: Data to be passed on to the pre_transfer() function. + * @pre_transfer: Callback used if needed before preparation of transfer. + * Only called if device is set. size of bytes to transfer + * (in case of multiple element transfer size is size of the first element). + * + * + * This structure has to be filled by the client drivers. + * It is recommended to do all dma configurations for clients in the machine. + * + */ +struct stedma40_chan_cfg { + enum stedma40_xfer_dir dir; + unsigned int channel_type; + int src_dev_type; + int dst_dev_type; + struct stedma40_half_channel_info src_info; + struct stedma40_half_channel_info dst_info; + void *pre_transfer_data; + int (*pre_transfer) (struct dma_chan *chan, + void *data, + int size); +}; + +/** + * struct stedma40_platform_data - Configuration struct for the dma device. + * + * @dev_len: length of dev_tx and dev_rx + * @dev_tx: mapping between destination event line and io address + * @dev_rx: mapping between source event line and io address + * @memcpy: list of memcpy event lines + * @memcpy_len: length of memcpy + * @memcpy_conf_phy: default configuration of physical channel memcpy + * @memcpy_conf_log: default configuration of logical channel memcpy + * @llis_per_log: number of max linked list items per logical channel + * + */ +struct stedma40_platform_data { + u32 dev_len; + const dma_addr_t *dev_tx; + const dma_addr_t *dev_rx; + int *memcpy; + u32 memcpy_len; + struct stedma40_chan_cfg *memcpy_conf_phy; + struct stedma40_chan_cfg *memcpy_conf_log; + unsigned int llis_per_log; +}; + +/** + * setdma40_set_psize() - Used for changing the package size of an + * already configured dma channel. + * + * @chan: dmaengine handle + * @src_psize: new package side for src. (STEDMA40_PSIZE*) + * @src_psize: new package side for dst. (STEDMA40_PSIZE*) + * + * returns 0 on ok, otherwise negative error number. + */ +int stedma40_set_psize(struct dma_chan *chan, + int src_psize, + int dst_psize); + +/** + * stedma40_filter() - Provides stedma40_chan_cfg to the + * ste_dma40 dma driver via the dmaengine framework. + * does some checking of what's provided. + * + * Never directly called by client. It used by dmaengine. + * @chan: dmaengine handle. + * @data: Must be of type: struct stedma40_chan_cfg and is + * the configuration of the framework. + * + * + */ + +bool stedma40_filter(struct dma_chan *chan, void *data); + +/** + * stedma40_memcpy_sg() - extension of the dma framework, memcpy to/from + * scattergatter lists. + * + * @chan: dmaengine handle + * @sgl_dst: Destination scatter list + * @sgl_src: Source scatter list + * @sgl_len: The length of each scatterlist. Both lists must be of equal length + * and each element must match the corresponding element in the other scatter + * list. + * @flags: is actually enum dma_ctrl_flags. See dmaengine.h + */ + +struct dma_async_tx_descriptor *stedma40_memcpy_sg(struct dma_chan *chan, + struct scatterlist *sgl_dst, + struct scatterlist *sgl_src, + unsigned int sgl_len, + unsigned long flags); + +/** + * stedma40_slave_mem() - Transfers a raw data buffer to or from a slave + * (=device) + * + * @chan: dmaengine handle + * @addr: source or destination physicall address. + * @size: bytes to transfer + * @direction: direction of transfer + * @flags: is actually enum dma_ctrl_flags. See dmaengine.h + */ + +static inline struct +dma_async_tx_descriptor *stedma40_slave_mem(struct dma_chan *chan, + dma_addr_t addr, + unsigned int size, + enum dma_data_direction direction, + unsigned long flags) +{ + struct scatterlist sg; + sg_init_table(&sg, 1); + sg.dma_address = addr; + sg.length = size; + + return chan->device->device_prep_slave_sg(chan, &sg, 1, + direction, flags); +} + +#endif diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index a2fcb2ead892..1b8877922fb0 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -141,6 +141,13 @@ config COH901318 help Enable support for ST-Ericsson COH 901 318 DMA. +config STE_DMA40 + bool "ST-Ericsson DMA40 support" + depends on ARCH_U8500 + select DMA_ENGINE + help + Support for ST-Ericsson DMA40 controller + config AMCC_PPC440SPE_ADMA tristate "AMCC PPC440SPe ADMA support" depends on 440SPe || 440SP diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 40c627d8f73b..20881426c1ac 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -21,3 +21,4 @@ obj-$(CONFIG_SH_DMAE) += shdma.o obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o obj-$(CONFIG_AMCC_PPC440SPE_ADMA) += ppc4xx/ obj-$(CONFIG_TIMB_DMA) += timb_dma.o +obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c new file mode 100644 index 000000000000..e4295a27672b --- /dev/null +++ b/drivers/dma/ste_dma40.c @@ -0,0 +1,2596 @@ +/* + * driver/dma/ste_dma40.c + * + * Copyright (C) ST-Ericsson 2007-2010 + * License terms: GNU General Public License (GPL) version 2 + * Author: Per Friden + * Author: Jonas Aaberg + * + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "ste_dma40_ll.h" + +#define D40_NAME "dma40" + +#define D40_PHY_CHAN -1 + +/* For masking out/in 2 bit channel positions */ +#define D40_CHAN_POS(chan) (2 * (chan / 2)) +#define D40_CHAN_POS_MASK(chan) (0x3 << D40_CHAN_POS(chan)) + +/* Maximum iterations taken before giving up suspending a channel */ +#define D40_SUSPEND_MAX_IT 500 + +#define D40_ALLOC_FREE (1 << 31) +#define D40_ALLOC_PHY (1 << 30) +#define D40_ALLOC_LOG_FREE 0 + +/* The number of free d40_desc to keep in memory before starting + * to kfree() them */ +#define D40_DESC_CACHE_SIZE 50 + +/* Hardware designer of the block */ +#define D40_PERIPHID2_DESIGNER 0x8 + +/** + * enum 40_command - The different commands and/or statuses. + * + * @D40_DMA_STOP: DMA channel command STOP or status STOPPED, + * @D40_DMA_RUN: The DMA channel is RUNNING of the command RUN. + * @D40_DMA_SUSPEND_REQ: Request the DMA to SUSPEND as soon as possible. + * @D40_DMA_SUSPENDED: The DMA channel is SUSPENDED. + */ +enum d40_command { + D40_DMA_STOP = 0, + D40_DMA_RUN = 1, + D40_DMA_SUSPEND_REQ = 2, + D40_DMA_SUSPENDED = 3 +}; + +/** + * struct d40_lli_pool - Structure for keeping LLIs in memory + * + * @base: Pointer to memory area when the pre_alloc_lli's are not large + * enough, IE bigger than the most common case, 1 dst and 1 src. NULL if + * pre_alloc_lli is used. + * @size: The size in bytes of the memory at base or the size of pre_alloc_lli. + * @pre_alloc_lli: Pre allocated area for the most common case of transfers, + * one buffer to one buffer. + */ +struct d40_lli_pool { + void *base; + int size; + /* Space for dst and src, plus an extra for padding */ + u8 pre_alloc_lli[3 * sizeof(struct d40_phy_lli)]; +}; + +/** + * struct d40_desc - A descriptor is one DMA job. + * + * @lli_phy: LLI settings for physical channel. Both src and dst= + * points into the lli_pool, to base if lli_len > 1 or to pre_alloc_lli if + * lli_len equals one. + * @lli_log: Same as above but for logical channels. + * @lli_pool: The pool with two entries pre-allocated. + * @lli_len: Number of LLI's in lli_pool + * @lli_tcount: Number of LLIs processed in the transfer. When equals lli_len + * then this transfer job is done. + * @txd: DMA engine struct. Used for among other things for communication + * during a transfer. + * @node: List entry. + * @dir: The transfer direction of this job. + * @is_in_client_list: true if the client owns this descriptor. + * + * This descriptor is used for both logical and physical transfers. + */ + +struct d40_desc { + /* LLI physical */ + struct d40_phy_lli_bidir lli_phy; + /* LLI logical */ + struct d40_log_lli_bidir lli_log; + + struct d40_lli_pool lli_pool; + u32 lli_len; + u32 lli_tcount; + + struct dma_async_tx_descriptor txd; + struct list_head node; + + enum dma_data_direction dir; + bool is_in_client_list; +}; + +/** + * struct d40_lcla_pool - LCLA pool settings and data. + * + * @base: The virtual address of LCLA. + * @phy: Physical base address of LCLA. + * @base_size: size of lcla. + * @lock: Lock to protect the content in this struct. + * @alloc_map: Mapping between physical channel and LCLA entries. + * @num_blocks: The number of entries of alloc_map. Equals to the + * number of physical channels. + */ +struct d40_lcla_pool { + void *base; + dma_addr_t phy; + resource_size_t base_size; + spinlock_t lock; + u32 *alloc_map; + int num_blocks; +}; + +/** + * struct d40_phy_res - struct for handling eventlines mapped to physical + * channels. + * + * @lock: A lock protection this entity. + * @num: The physical channel number of this entity. + * @allocated_src: Bit mapped to show which src event line's are mapped to + * this physical channel. Can also be free or physically allocated. + * @allocated_dst: Same as for src but is dst. + * allocated_dst and allocated_src uses the D40_ALLOC* defines as well as + * event line number. Both allocated_src and allocated_dst can not be + * allocated to a physical channel, since the interrupt handler has then + * no way of figure out which one the interrupt belongs to. + */ +struct d40_phy_res { + spinlock_t lock; + int num; + u32 allocated_src; + u32 allocated_dst; +}; + +struct d40_base; + +/** + * struct d40_chan - Struct that describes a channel. + * + * @lock: A spinlock to protect this struct. + * @log_num: The logical number, if any of this channel. + * @completed: Starts with 1, after first interrupt it is set to dma engine's + * current cookie. + * @pending_tx: The number of pending transfers. Used between interrupt handler + * and tasklet. + * @busy: Set to true when transfer is ongoing on this channel. + * @phy_chan: Pointer to physical channel which this instance runs on. + * @chan: DMA engine handle. + * @tasklet: Tasklet that gets scheduled from interrupt context to complete a + * transfer and call client callback. + * @client: Cliented owned descriptor list. + * @active: Active descriptor. + * @queue: Queued jobs. + * @free: List of free descripts, ready to be reused. + * @free_len: Number of descriptors in the free list. + * @dma_cfg: The client configuration of this dma channel. + * @base: Pointer to the device instance struct. + * @src_def_cfg: Default cfg register setting for src. + * @dst_def_cfg: Default cfg register setting for dst. + * @log_def: Default logical channel settings. + * @lcla: Space for one dst src pair for logical channel transfers. + * @lcpa: Pointer to dst and src lcpa settings. + * + * This struct can either "be" a logical or a physical channel. + */ +struct d40_chan { + spinlock_t lock; + int log_num; + /* ID of the most recent completed transfer */ + int completed; + int pending_tx; + bool busy; + struct d40_phy_res *phy_chan; + struct dma_chan chan; + struct tasklet_struct tasklet; + struct list_head client; + struct list_head active; + struct list_head queue; + struct list_head free; + int free_len; + struct stedma40_chan_cfg dma_cfg; + struct d40_base *base; + /* Default register configurations */ + u32 src_def_cfg; + u32 dst_def_cfg; + struct d40_def_lcsp log_def; + struct d40_lcla_elem lcla; + struct d40_log_lli_full *lcpa; +}; + +/** + * struct d40_base - The big global struct, one for each probe'd instance. + * + * @interrupt_lock: Lock used to make sure one interrupt is handle a time. + * @execmd_lock: Lock for execute command usage since several channels share + * the same physical register. + * @dev: The device structure. + * @virtbase: The virtual base address of the DMA's register. + * @clk: Pointer to the DMA clock structure. + * @phy_start: Physical memory start of the DMA registers. + * @phy_size: Size of the DMA register map. + * @irq: The IRQ number. + * @num_phy_chans: The number of physical channels. Read from HW. This + * is the number of available channels for this driver, not counting "Secure + * mode" allocated physical channels. + * @num_log_chans: The number of logical channels. Calculated from + * num_phy_chans. + * @dma_both: dma_device channels that can do both memcpy and slave transfers. + * @dma_slave: dma_device channels that can do only do slave transfers. + * @dma_memcpy: dma_device channels that can do only do memcpy transfers. + * @phy_chans: Room for all possible physical channels in system. + * @log_chans: Room for all possible logical channels in system. + * @lookup_log_chans: Used to map interrupt number to logical channel. Points + * to log_chans entries. + * @lookup_phy_chans: Used to map interrupt number to physical channel. Points + * to phy_chans entries. + * @plat_data: Pointer to provided platform_data which is the driver + * configuration. + * @phy_res: Vector containing all physical channels. + * @lcla_pool: lcla pool settings and data. + * @lcpa_base: The virtual mapped address of LCPA. + * @phy_lcpa: The physical address of the LCPA. + * @lcpa_size: The size of the LCPA area. + */ +struct d40_base { + spinlock_t interrupt_lock; + spinlock_t execmd_lock; + struct device *dev; + void __iomem *virtbase; + struct clk *clk; + phys_addr_t phy_start; + resource_size_t phy_size; + int irq; + int num_phy_chans; + int num_log_chans; + struct dma_device dma_both; + struct dma_device dma_slave; + struct dma_device dma_memcpy; + struct d40_chan *phy_chans; + struct d40_chan *log_chans; + struct d40_chan **lookup_log_chans; + struct d40_chan **lookup_phy_chans; + struct stedma40_platform_data *plat_data; + /* Physical half channels */ + struct d40_phy_res *phy_res; + struct d40_lcla_pool lcla_pool; + void *lcpa_base; + dma_addr_t phy_lcpa; + resource_size_t lcpa_size; +}; + +/** + * struct d40_interrupt_lookup - lookup table for interrupt handler + * + * @src: Interrupt mask register. + * @clr: Interrupt clear register. + * @is_error: true if this is an error interrupt. + * @offset: start delta in the lookup_log_chans in d40_base. If equals to + * D40_PHY_CHAN, the lookup_phy_chans shall be used instead. + */ +struct d40_interrupt_lookup { + u32 src; + u32 clr; + bool is_error; + int offset; +}; + +/** + * struct d40_reg_val - simple lookup struct + * + * @reg: The register. + * @val: The value that belongs to the register in reg. + */ +struct d40_reg_val { + unsigned int reg; + unsigned int val; +}; + +static int d40_pool_lli_alloc(struct d40_desc *d40d, + int lli_len, bool is_log) +{ + u32 align; + void *base; + + if (is_log) + align = sizeof(struct d40_log_lli); + else + align = sizeof(struct d40_phy_lli); + + if (lli_len == 1) { + base = d40d->lli_pool.pre_alloc_lli; + d40d->lli_pool.size = sizeof(d40d->lli_pool.pre_alloc_lli); + d40d->lli_pool.base = NULL; + } else { + d40d->lli_pool.size = ALIGN(lli_len * 2 * align, align); + + base = kmalloc(d40d->lli_pool.size + align, GFP_NOWAIT); + d40d->lli_pool.base = base; + + if (d40d->lli_pool.base == NULL) + return -ENOMEM; + } + + if (is_log) { + d40d->lli_log.src = PTR_ALIGN((struct d40_log_lli *) base, + align); + d40d->lli_log.dst = PTR_ALIGN(d40d->lli_log.src + lli_len, + align); + } else { + d40d->lli_phy.src = PTR_ALIGN((struct d40_phy_lli *)base, + align); + d40d->lli_phy.dst = PTR_ALIGN(d40d->lli_phy.src + lli_len, + align); + + d40d->lli_phy.src_addr = virt_to_phys(d40d->lli_phy.src); + d40d->lli_phy.dst_addr = virt_to_phys(d40d->lli_phy.dst); + } + + return 0; +} + +static void d40_pool_lli_free(struct d40_desc *d40d) +{ + kfree(d40d->lli_pool.base); + d40d->lli_pool.base = NULL; + d40d->lli_pool.size = 0; + d40d->lli_log.src = NULL; + d40d->lli_log.dst = NULL; + d40d->lli_phy.src = NULL; + d40d->lli_phy.dst = NULL; + d40d->lli_phy.src_addr = 0; + d40d->lli_phy.dst_addr = 0; +} + +static dma_cookie_t d40_assign_cookie(struct d40_chan *d40c, + struct d40_desc *desc) +{ + dma_cookie_t cookie = d40c->chan.cookie; + + if (++cookie < 0) + cookie = 1; + + d40c->chan.cookie = cookie; + desc->txd.cookie = cookie; + + return cookie; +} + +static void d40_desc_reset(struct d40_desc *d40d) +{ + d40d->lli_tcount = 0; +} + +static void d40_desc_remove(struct d40_desc *d40d) +{ + list_del(&d40d->node); +} + +static struct d40_desc *d40_desc_get(struct d40_chan *d40c) +{ + struct d40_desc *desc; + struct d40_desc *d; + struct d40_desc *_d; + + if (!list_empty(&d40c->client)) { + list_for_each_entry_safe(d, _d, &d40c->client, node) + if (async_tx_test_ack(&d->txd)) { + d40_pool_lli_free(d); + d40_desc_remove(d); + desc = d; + goto out; + } + } + + if (list_empty(&d40c->free)) { + /* Alloc new desc because we're out of used ones */ + desc = kzalloc(sizeof(struct d40_desc), GFP_NOWAIT); + if (desc == NULL) + goto out; + INIT_LIST_HEAD(&desc->node); + } else { + /* Reuse an old desc. */ + desc = list_first_entry(&d40c->free, + struct d40_desc, + node); + list_del(&desc->node); + d40c->free_len--; + } +out: + return desc; +} + +static void d40_desc_free(struct d40_chan *d40c, struct d40_desc *d40d) +{ + if (d40c->free_len < D40_DESC_CACHE_SIZE) { + list_add_tail(&d40d->node, &d40c->free); + d40c->free_len++; + } else + kfree(d40d); +} + +static void d40_desc_submit(struct d40_chan *d40c, struct d40_desc *desc) +{ + list_add_tail(&desc->node, &d40c->active); +} + +static struct d40_desc *d40_first_active_get(struct d40_chan *d40c) +{ + struct d40_desc *d; + + if (list_empty(&d40c->active)) + return NULL; + + d = list_first_entry(&d40c->active, + struct d40_desc, + node); + return d; +} + +static void d40_desc_queue(struct d40_chan *d40c, struct d40_desc *desc) +{ + list_add_tail(&desc->node, &d40c->queue); +} + +static struct d40_desc *d40_first_queued(struct d40_chan *d40c) +{ + struct d40_desc *d; + + if (list_empty(&d40c->queue)) + return NULL; + + d = list_first_entry(&d40c->queue, + struct d40_desc, + node); + return d; +} + +/* Support functions for logical channels */ + +static int d40_lcla_id_get(struct d40_chan *d40c, + struct d40_lcla_pool *pool) +{ + int src_id = 0; + int dst_id = 0; + struct d40_log_lli *lcla_lidx_base = + pool->base + d40c->phy_chan->num * 1024; + int i; + int lli_per_log = d40c->base->plat_data->llis_per_log; + + if (d40c->lcla.src_id >= 0 && d40c->lcla.dst_id >= 0) + return 0; + + if (pool->num_blocks > 32) + return -EINVAL; + + spin_lock(&pool->lock); + + for (i = 0; i < pool->num_blocks; i++) { + if (!(pool->alloc_map[d40c->phy_chan->num] & (0x1 << i))) { + pool->alloc_map[d40c->phy_chan->num] |= (0x1 << i); + break; + } + } + src_id = i; + if (src_id >= pool->num_blocks) + goto err; + + for (; i < pool->num_blocks; i++) { + if (!(pool->alloc_map[d40c->phy_chan->num] & (0x1 << i))) { + pool->alloc_map[d40c->phy_chan->num] |= (0x1 << i); + break; + } + } + + dst_id = i; + if (dst_id == src_id) + goto err; + + d40c->lcla.src_id = src_id; + d40c->lcla.dst_id = dst_id; + d40c->lcla.dst = lcla_lidx_base + dst_id * lli_per_log + 1; + d40c->lcla.src = lcla_lidx_base + src_id * lli_per_log + 1; + + + spin_unlock(&pool->lock); + return 0; +err: + spin_unlock(&pool->lock); + return -EINVAL; +} + +static void d40_lcla_id_put(struct d40_chan *d40c, + struct d40_lcla_pool *pool, + int id) +{ + if (id < 0) + return; + + d40c->lcla.src_id = -1; + d40c->lcla.dst_id = -1; + + spin_lock(&pool->lock); + pool->alloc_map[d40c->phy_chan->num] &= (~(0x1 << id)); + spin_unlock(&pool->lock); +} + +static int d40_channel_execute_command(struct d40_chan *d40c, + enum d40_command command) +{ + int status, i; + void __iomem *active_reg; + int ret = 0; + unsigned long flags; + + spin_lock_irqsave(&d40c->base->execmd_lock, flags); + + if (d40c->phy_chan->num % 2 == 0) + active_reg = d40c->base->virtbase + D40_DREG_ACTIVE; + else + active_reg = d40c->base->virtbase + D40_DREG_ACTIVO; + + if (command == D40_DMA_SUSPEND_REQ) { + status = (readl(active_reg) & + D40_CHAN_POS_MASK(d40c->phy_chan->num)) >> + D40_CHAN_POS(d40c->phy_chan->num); + + if (status == D40_DMA_SUSPENDED || status == D40_DMA_STOP) + goto done; + } + + writel(command << D40_CHAN_POS(d40c->phy_chan->num), active_reg); + + if (command == D40_DMA_SUSPEND_REQ) { + + for (i = 0 ; i < D40_SUSPEND_MAX_IT; i++) { + status = (readl(active_reg) & + D40_CHAN_POS_MASK(d40c->phy_chan->num)) >> + D40_CHAN_POS(d40c->phy_chan->num); + + cpu_relax(); + /* + * Reduce the number of bus accesses while + * waiting for the DMA to suspend. + */ + udelay(3); + + if (status == D40_DMA_STOP || + status == D40_DMA_SUSPENDED) + break; + } + + if (i == D40_SUSPEND_MAX_IT) { + dev_err(&d40c->chan.dev->device, + "[%s]: unable to suspend the chl %d (log: %d) status %x\n", + __func__, d40c->phy_chan->num, d40c->log_num, + status); + dump_stack(); + ret = -EBUSY; + } + + } +done: + spin_unlock_irqrestore(&d40c->base->execmd_lock, flags); + return ret; +} + +static void d40_term_all(struct d40_chan *d40c) +{ + struct d40_desc *d40d; + struct d40_desc *d; + struct d40_desc *_d; + + /* Release active descriptors */ + while ((d40d = d40_first_active_get(d40c))) { + d40_desc_remove(d40d); + + /* Return desc to free-list */ + d40_desc_free(d40c, d40d); + } + + /* Release queued descriptors waiting for transfer */ + while ((d40d = d40_first_queued(d40c))) { + d40_desc_remove(d40d); + + /* Return desc to free-list */ + d40_desc_free(d40c, d40d); + } + + /* Release client owned descriptors */ + if (!list_empty(&d40c->client)) + list_for_each_entry_safe(d, _d, &d40c->client, node) { + d40_pool_lli_free(d); + d40_desc_remove(d); + /* Return desc to free-list */ + d40_desc_free(d40c, d40d); + } + + d40_lcla_id_put(d40c, &d40c->base->lcla_pool, + d40c->lcla.src_id); + d40_lcla_id_put(d40c, &d40c->base->lcla_pool, + d40c->lcla.dst_id); + + d40c->pending_tx = 0; + d40c->busy = false; +} + +static void d40_config_set_event(struct d40_chan *d40c, bool do_enable) +{ + u32 val; + unsigned long flags; + + if (do_enable) + val = D40_ACTIVATE_EVENTLINE; + else + val = D40_DEACTIVATE_EVENTLINE; + + spin_lock_irqsave(&d40c->phy_chan->lock, flags); + + /* Enable event line connected to device (or memcpy) */ + if ((d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) || + (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) { + u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type); + + writel((val << D40_EVENTLINE_POS(event)) | + ~D40_EVENTLINE_MASK(event), + d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SSLNK); + } + if (d40c->dma_cfg.dir != STEDMA40_PERIPH_TO_MEM) { + u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type); + + writel((val << D40_EVENTLINE_POS(event)) | + ~D40_EVENTLINE_MASK(event), + d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SDLNK); + } + + spin_unlock_irqrestore(&d40c->phy_chan->lock, flags); +} + +static bool d40_chan_has_events(struct d40_chan *d40c) +{ + u32 val = 0; + + /* If SSLNK or SDLNK is zero all events are disabled */ + if ((d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) || + (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) + val = readl(d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SSLNK); + + if (d40c->dma_cfg.dir != STEDMA40_PERIPH_TO_MEM) + val = readl(d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SDLNK); + return (bool) val; +} + +static void d40_config_enable_lidx(struct d40_chan *d40c) +{ + /* Set LIDX for lcla */ + writel((d40c->phy_chan->num << D40_SREG_ELEM_LOG_LIDX_POS) & + D40_SREG_ELEM_LOG_LIDX_MASK, + d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + D40_CHAN_REG_SDELT); + + writel((d40c->phy_chan->num << D40_SREG_ELEM_LOG_LIDX_POS) & + D40_SREG_ELEM_LOG_LIDX_MASK, + d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + D40_CHAN_REG_SSELT); +} + +static int d40_config_write(struct d40_chan *d40c) +{ + u32 addr_base; + u32 var; + int res; + + res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); + if (res) + return res; + + /* Odd addresses are even addresses + 4 */ + addr_base = (d40c->phy_chan->num % 2) * 4; + /* Setup channel mode to logical or physical */ + var = ((u32)(d40c->log_num != D40_PHY_CHAN) + 1) << + D40_CHAN_POS(d40c->phy_chan->num); + writel(var, d40c->base->virtbase + D40_DREG_PRMSE + addr_base); + + /* Setup operational mode option register */ + var = ((d40c->dma_cfg.channel_type >> STEDMA40_INFO_CH_MODE_OPT_POS) & + 0x3) << D40_CHAN_POS(d40c->phy_chan->num); + + writel(var, d40c->base->virtbase + D40_DREG_PRMOE + addr_base); + + if (d40c->log_num != D40_PHY_CHAN) { + /* Set default config for CFG reg */ + writel(d40c->src_def_cfg, + d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SSCFG); + writel(d40c->dst_def_cfg, + d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SDCFG); + + d40_config_enable_lidx(d40c); + } + return res; +} + +static void d40_desc_load(struct d40_chan *d40c, struct d40_desc *d40d) +{ + + if (d40d->lli_phy.dst && d40d->lli_phy.src) { + d40_phy_lli_write(d40c->base->virtbase, + d40c->phy_chan->num, + d40d->lli_phy.dst, + d40d->lli_phy.src); + d40d->lli_tcount = d40d->lli_len; + } else if (d40d->lli_log.dst && d40d->lli_log.src) { + u32 lli_len; + struct d40_log_lli *src = d40d->lli_log.src; + struct d40_log_lli *dst = d40d->lli_log.dst; + + src += d40d->lli_tcount; + dst += d40d->lli_tcount; + + if (d40d->lli_len <= d40c->base->plat_data->llis_per_log) + lli_len = d40d->lli_len; + else + lli_len = d40c->base->plat_data->llis_per_log; + d40d->lli_tcount += lli_len; + d40_log_lli_write(d40c->lcpa, d40c->lcla.src, + d40c->lcla.dst, + dst, src, + d40c->base->plat_data->llis_per_log); + } +} + +static dma_cookie_t d40_tx_submit(struct dma_async_tx_descriptor *tx) +{ + struct d40_chan *d40c = container_of(tx->chan, + struct d40_chan, + chan); + struct d40_desc *d40d = container_of(tx, struct d40_desc, txd); + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + + tx->cookie = d40_assign_cookie(d40c, d40d); + + d40_desc_queue(d40c, d40d); + + spin_unlock_irqrestore(&d40c->lock, flags); + + return tx->cookie; +} + +static int d40_start(struct d40_chan *d40c) +{ + int err; + + if (d40c->log_num != D40_PHY_CHAN) { + err = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); + if (err) + return err; + d40_config_set_event(d40c, true); + } + + err = d40_channel_execute_command(d40c, D40_DMA_RUN); + + return err; +} + +static struct d40_desc *d40_queue_start(struct d40_chan *d40c) +{ + struct d40_desc *d40d; + int err; + + /* Start queued jobs, if any */ + d40d = d40_first_queued(d40c); + + if (d40d != NULL) { + d40c->busy = true; + + /* Remove from queue */ + d40_desc_remove(d40d); + + /* Add to active queue */ + d40_desc_submit(d40c, d40d); + + /* Initiate DMA job */ + d40_desc_load(d40c, d40d); + + /* Start dma job */ + err = d40_start(d40c); + + if (err) + return NULL; + } + + return d40d; +} + +/* called from interrupt context */ +static void dma_tc_handle(struct d40_chan *d40c) +{ + struct d40_desc *d40d; + + if (!d40c->phy_chan) + return; + + /* Get first active entry from list */ + d40d = d40_first_active_get(d40c); + + if (d40d == NULL) + return; + + if (d40d->lli_tcount < d40d->lli_len) { + + d40_desc_load(d40c, d40d); + /* Start dma job */ + (void) d40_start(d40c); + return; + } + + if (d40_queue_start(d40c) == NULL) + d40c->busy = false; + + d40c->pending_tx++; + tasklet_schedule(&d40c->tasklet); + +} + +static void dma_tasklet(unsigned long data) +{ + struct d40_chan *d40c = (struct d40_chan *) data; + struct d40_desc *d40d_fin; + unsigned long flags; + dma_async_tx_callback callback; + void *callback_param; + + spin_lock_irqsave(&d40c->lock, flags); + + /* Get first active entry from list */ + d40d_fin = d40_first_active_get(d40c); + + if (d40d_fin == NULL) + goto err; + + d40c->completed = d40d_fin->txd.cookie; + + /* + * If terminating a channel pending_tx is set to zero. + * This prevents any finished active jobs to return to the client. + */ + if (d40c->pending_tx == 0) { + spin_unlock_irqrestore(&d40c->lock, flags); + return; + } + + /* Callback to client */ + callback = d40d_fin->txd.callback; + callback_param = d40d_fin->txd.callback_param; + + if (async_tx_test_ack(&d40d_fin->txd)) { + d40_pool_lli_free(d40d_fin); + d40_desc_remove(d40d_fin); + /* Return desc to free-list */ + d40_desc_free(d40c, d40d_fin); + } else { + d40_desc_reset(d40d_fin); + if (!d40d_fin->is_in_client_list) { + d40_desc_remove(d40d_fin); + list_add_tail(&d40d_fin->node, &d40c->client); + d40d_fin->is_in_client_list = true; + } + } + + d40c->pending_tx--; + + if (d40c->pending_tx) + tasklet_schedule(&d40c->tasklet); + + spin_unlock_irqrestore(&d40c->lock, flags); + + if (callback) + callback(callback_param); + + return; + + err: + /* Rescue manouver if receiving double interrupts */ + if (d40c->pending_tx > 0) + d40c->pending_tx--; + spin_unlock_irqrestore(&d40c->lock, flags); +} + +static irqreturn_t d40_handle_interrupt(int irq, void *data) +{ + static const struct d40_interrupt_lookup il[] = { + {D40_DREG_LCTIS0, D40_DREG_LCICR0, false, 0}, + {D40_DREG_LCTIS1, D40_DREG_LCICR1, false, 32}, + {D40_DREG_LCTIS2, D40_DREG_LCICR2, false, 64}, + {D40_DREG_LCTIS3, D40_DREG_LCICR3, false, 96}, + {D40_DREG_LCEIS0, D40_DREG_LCICR0, true, 0}, + {D40_DREG_LCEIS1, D40_DREG_LCICR1, true, 32}, + {D40_DREG_LCEIS2, D40_DREG_LCICR2, true, 64}, + {D40_DREG_LCEIS3, D40_DREG_LCICR3, true, 96}, + {D40_DREG_PCTIS, D40_DREG_PCICR, false, D40_PHY_CHAN}, + {D40_DREG_PCEIS, D40_DREG_PCICR, true, D40_PHY_CHAN}, + }; + + int i; + u32 regs[ARRAY_SIZE(il)]; + u32 tmp; + u32 idx; + u32 row; + long chan = -1; + struct d40_chan *d40c; + unsigned long flags; + struct d40_base *base = data; + + spin_lock_irqsave(&base->interrupt_lock, flags); + + /* Read interrupt status of both logical and physical channels */ + for (i = 0; i < ARRAY_SIZE(il); i++) + regs[i] = readl(base->virtbase + il[i].src); + + for (;;) { + + chan = find_next_bit((unsigned long *)regs, + BITS_PER_LONG * ARRAY_SIZE(il), chan + 1); + + /* No more set bits found? */ + if (chan == BITS_PER_LONG * ARRAY_SIZE(il)) + break; + + row = chan / BITS_PER_LONG; + idx = chan & (BITS_PER_LONG - 1); + + /* ACK interrupt */ + tmp = readl(base->virtbase + il[row].clr); + tmp |= 1 << idx; + writel(tmp, base->virtbase + il[row].clr); + + if (il[row].offset == D40_PHY_CHAN) + d40c = base->lookup_phy_chans[idx]; + else + d40c = base->lookup_log_chans[il[row].offset + idx]; + spin_lock(&d40c->lock); + + if (!il[row].is_error) + dma_tc_handle(d40c); + else + dev_err(base->dev, "[%s] IRQ chan: %ld offset %d idx %d\n", + __func__, chan, il[row].offset, idx); + + spin_unlock(&d40c->lock); + } + + spin_unlock_irqrestore(&base->interrupt_lock, flags); + + return IRQ_HANDLED; +} + + +static int d40_validate_conf(struct d40_chan *d40c, + struct stedma40_chan_cfg *conf) +{ + int res = 0; + u32 dst_event_group = D40_TYPE_TO_GROUP(conf->dst_dev_type); + u32 src_event_group = D40_TYPE_TO_GROUP(conf->src_dev_type); + bool is_log = (conf->channel_type & STEDMA40_CHANNEL_IN_OPER_MODE) + == STEDMA40_CHANNEL_IN_LOG_MODE; + + if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH && + dst_event_group == STEDMA40_DEV_DST_MEMORY) { + dev_err(&d40c->chan.dev->device, "[%s] Invalid dst\n", + __func__); + res = -EINVAL; + } + + if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM && + src_event_group == STEDMA40_DEV_SRC_MEMORY) { + dev_err(&d40c->chan.dev->device, "[%s] Invalid src\n", + __func__); + res = -EINVAL; + } + + if (src_event_group == STEDMA40_DEV_SRC_MEMORY && + dst_event_group == STEDMA40_DEV_DST_MEMORY && is_log) { + dev_err(&d40c->chan.dev->device, + "[%s] No event line\n", __func__); + res = -EINVAL; + } + + if (conf->dir == STEDMA40_PERIPH_TO_PERIPH && + (src_event_group != dst_event_group)) { + dev_err(&d40c->chan.dev->device, + "[%s] Invalid event group\n", __func__); + res = -EINVAL; + } + + if (conf->dir == STEDMA40_PERIPH_TO_PERIPH) { + /* + * DMAC HW supports it. Will be added to this driver, + * in case any dma client requires it. + */ + dev_err(&d40c->chan.dev->device, + "[%s] periph to periph not supported\n", + __func__); + res = -EINVAL; + } + + return res; +} + +static bool d40_alloc_mask_set(struct d40_phy_res *phy, bool is_src, + int log_event_line) +{ + unsigned long flags; + spin_lock_irqsave(&phy->lock, flags); + if (!log_event_line) { + /* Physical interrupts are masked per physical full channel */ + if (phy->allocated_src == D40_ALLOC_FREE && + phy->allocated_dst == D40_ALLOC_FREE) { + phy->allocated_dst = D40_ALLOC_PHY; + phy->allocated_src = D40_ALLOC_PHY; + goto found; + } else + goto not_found; + } + + /* Logical channel */ + if (is_src) { + if (phy->allocated_src == D40_ALLOC_PHY) + goto not_found; + + if (phy->allocated_src == D40_ALLOC_FREE) + phy->allocated_src = D40_ALLOC_LOG_FREE; + + if (!(phy->allocated_src & (1 << log_event_line))) { + phy->allocated_src |= 1 << log_event_line; + goto found; + } else + goto not_found; + } else { + if (phy->allocated_dst == D40_ALLOC_PHY) + goto not_found; + + if (phy->allocated_dst == D40_ALLOC_FREE) + phy->allocated_dst = D40_ALLOC_LOG_FREE; + + if (!(phy->allocated_dst & (1 << log_event_line))) { + phy->allocated_dst |= 1 << log_event_line; + goto found; + } else + goto not_found; + } + +not_found: + spin_unlock_irqrestore(&phy->lock, flags); + return false; +found: + spin_unlock_irqrestore(&phy->lock, flags); + return true; +} + +static bool d40_alloc_mask_free(struct d40_phy_res *phy, bool is_src, + int log_event_line) +{ + unsigned long flags; + bool is_free = false; + + spin_lock_irqsave(&phy->lock, flags); + if (!log_event_line) { + /* Physical interrupts are masked per physical full channel */ + phy->allocated_dst = D40_ALLOC_FREE; + phy->allocated_src = D40_ALLOC_FREE; + is_free = true; + goto out; + } + + /* Logical channel */ + if (is_src) { + phy->allocated_src &= ~(1 << log_event_line); + if (phy->allocated_src == D40_ALLOC_LOG_FREE) + phy->allocated_src = D40_ALLOC_FREE; + } else { + phy->allocated_dst &= ~(1 << log_event_line); + if (phy->allocated_dst == D40_ALLOC_LOG_FREE) + phy->allocated_dst = D40_ALLOC_FREE; + } + + is_free = ((phy->allocated_src | phy->allocated_dst) == + D40_ALLOC_FREE); + +out: + spin_unlock_irqrestore(&phy->lock, flags); + + return is_free; +} + +static int d40_allocate_channel(struct d40_chan *d40c) +{ + int dev_type; + int event_group; + int event_line; + struct d40_phy_res *phys; + int i; + int j; + int log_num; + bool is_src; + bool is_log = (d40c->dma_cfg.channel_type & STEDMA40_CHANNEL_IN_OPER_MODE) + == STEDMA40_CHANNEL_IN_LOG_MODE; + + + phys = d40c->base->phy_res; + + if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) { + dev_type = d40c->dma_cfg.src_dev_type; + log_num = 2 * dev_type; + is_src = true; + } else if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH || + d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) { + /* dst event lines are used for logical memcpy */ + dev_type = d40c->dma_cfg.dst_dev_type; + log_num = 2 * dev_type + 1; + is_src = false; + } else + return -EINVAL; + + event_group = D40_TYPE_TO_GROUP(dev_type); + event_line = D40_TYPE_TO_EVENT(dev_type); + + if (!is_log) { + if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) { + /* Find physical half channel */ + for (i = 0; i < d40c->base->num_phy_chans; i++) { + + if (d40_alloc_mask_set(&phys[i], is_src, 0)) + goto found_phy; + } + } else + for (j = 0; j < d40c->base->num_phy_chans; j += 8) { + int phy_num = j + event_group * 2; + for (i = phy_num; i < phy_num + 2; i++) { + if (d40_alloc_mask_set(&phys[i], + is_src, 0)) + goto found_phy; + } + } + return -EINVAL; +found_phy: + d40c->phy_chan = &phys[i]; + d40c->log_num = D40_PHY_CHAN; + goto out; + } + if (dev_type == -1) + return -EINVAL; + + /* Find logical channel */ + for (j = 0; j < d40c->base->num_phy_chans; j += 8) { + int phy_num = j + event_group * 2; + /* + * Spread logical channels across all available physical rather + * than pack every logical channel at the first available phy + * channels. + */ + if (is_src) { + for (i = phy_num; i < phy_num + 2; i++) { + if (d40_alloc_mask_set(&phys[i], is_src, + event_line)) + goto found_log; + } + } else { + for (i = phy_num + 1; i >= phy_num; i--) { + if (d40_alloc_mask_set(&phys[i], is_src, + event_line)) + goto found_log; + } + } + } + return -EINVAL; + +found_log: + d40c->phy_chan = &phys[i]; + d40c->log_num = log_num; +out: + + if (is_log) + d40c->base->lookup_log_chans[d40c->log_num] = d40c; + else + d40c->base->lookup_phy_chans[d40c->phy_chan->num] = d40c; + + return 0; + +} + +static int d40_config_chan(struct d40_chan *d40c, + struct stedma40_chan_cfg *info) +{ + + /* Fill in basic CFG register values */ + d40_phy_cfg(&d40c->dma_cfg, &d40c->src_def_cfg, + &d40c->dst_def_cfg, d40c->log_num != D40_PHY_CHAN); + + if (d40c->log_num != D40_PHY_CHAN) { + d40_log_cfg(&d40c->dma_cfg, + &d40c->log_def.lcsp1, &d40c->log_def.lcsp3); + + if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) + d40c->lcpa = d40c->base->lcpa_base + + d40c->dma_cfg.src_dev_type * 32; + else + d40c->lcpa = d40c->base->lcpa_base + + d40c->dma_cfg.dst_dev_type * 32 + 16; + } + + /* Write channel configuration to the DMA */ + return d40_config_write(d40c); +} + +static int d40_config_memcpy(struct d40_chan *d40c) +{ + dma_cap_mask_t cap = d40c->chan.device->cap_mask; + + if (dma_has_cap(DMA_MEMCPY, cap) && !dma_has_cap(DMA_SLAVE, cap)) { + d40c->dma_cfg = *d40c->base->plat_data->memcpy_conf_log; + d40c->dma_cfg.src_dev_type = STEDMA40_DEV_SRC_MEMORY; + d40c->dma_cfg.dst_dev_type = d40c->base->plat_data-> + memcpy[d40c->chan.chan_id]; + + } else if (dma_has_cap(DMA_MEMCPY, cap) && + dma_has_cap(DMA_SLAVE, cap)) { + d40c->dma_cfg = *d40c->base->plat_data->memcpy_conf_phy; + } else { + dev_err(&d40c->chan.dev->device, "[%s] No memcpy\n", + __func__); + return -EINVAL; + } + + return 0; +} + + +static int d40_free_dma(struct d40_chan *d40c) +{ + + int res = 0; + u32 event, dir; + struct d40_phy_res *phy = d40c->phy_chan; + bool is_src; + + /* Terminate all queued and active transfers */ + d40_term_all(d40c); + + if (phy == NULL) { + dev_err(&d40c->chan.dev->device, "[%s] phy == null\n", + __func__); + return -EINVAL; + } + + if (phy->allocated_src == D40_ALLOC_FREE && + phy->allocated_dst == D40_ALLOC_FREE) { + dev_err(&d40c->chan.dev->device, "[%s] channel already free\n", + __func__); + return -EINVAL; + } + + + res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); + if (res) { + dev_err(&d40c->chan.dev->device, "[%s] suspend\n", + __func__); + return res; + } + + if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH || + d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) { + event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type); + dir = D40_CHAN_REG_SDLNK; + is_src = false; + } else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) { + event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type); + dir = D40_CHAN_REG_SSLNK; + is_src = true; + } else { + dev_err(&d40c->chan.dev->device, + "[%s] Unknown direction\n", __func__); + return -EINVAL; + } + + if (d40c->log_num != D40_PHY_CHAN) { + /* + * Release logical channel, deactivate the event line during + * the time physical res is suspended. + */ + writel((D40_DEACTIVATE_EVENTLINE << D40_EVENTLINE_POS(event)) & + D40_EVENTLINE_MASK(event), + d40c->base->virtbase + D40_DREG_PCBASE + + phy->num * D40_DREG_PCDELTA + dir); + + d40c->base->lookup_log_chans[d40c->log_num] = NULL; + + /* + * Check if there are more logical allocation + * on this phy channel. + */ + if (!d40_alloc_mask_free(phy, is_src, event)) { + /* Resume the other logical channels if any */ + if (d40_chan_has_events(d40c)) { + res = d40_channel_execute_command(d40c, + D40_DMA_RUN); + if (res) { + dev_err(&d40c->chan.dev->device, + "[%s] Executing RUN command\n", + __func__); + return res; + } + } + return 0; + } + } else + d40_alloc_mask_free(phy, is_src, 0); + + /* Release physical channel */ + res = d40_channel_execute_command(d40c, D40_DMA_STOP); + if (res) { + dev_err(&d40c->chan.dev->device, + "[%s] Failed to stop channel\n", __func__); + return res; + } + d40c->phy_chan = NULL; + /* Invalidate channel type */ + d40c->dma_cfg.channel_type = 0; + d40c->base->lookup_phy_chans[phy->num] = NULL; + + return 0; + + +} + +static int d40_pause(struct dma_chan *chan) +{ + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + int res; + + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + + res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); + if (res == 0) { + if (d40c->log_num != D40_PHY_CHAN) { + d40_config_set_event(d40c, false); + /* Resume the other logical channels if any */ + if (d40_chan_has_events(d40c)) + res = d40_channel_execute_command(d40c, + D40_DMA_RUN); + } + } + + spin_unlock_irqrestore(&d40c->lock, flags); + return res; +} + +static bool d40_tx_is_linked(struct d40_chan *d40c) +{ + bool is_link; + + if (d40c->log_num != D40_PHY_CHAN) + is_link = readl(&d40c->lcpa->lcsp3) & D40_MEM_LCSP3_DLOS_MASK; + else + is_link = readl(d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SDLNK) & + D40_SREG_LNK_PHYS_LNK_MASK; + return is_link; +} + +static u32 d40_residue(struct d40_chan *d40c) +{ + u32 num_elt; + + if (d40c->log_num != D40_PHY_CHAN) + num_elt = (readl(&d40c->lcpa->lcsp2) & D40_MEM_LCSP2_ECNT_MASK) + >> D40_MEM_LCSP2_ECNT_POS; + else + num_elt = (readl(d40c->base->virtbase + D40_DREG_PCBASE + + d40c->phy_chan->num * D40_DREG_PCDELTA + + D40_CHAN_REG_SDELT) & + D40_SREG_ELEM_PHY_ECNT_MASK) >> D40_SREG_ELEM_PHY_ECNT_POS; + return num_elt * (1 << d40c->dma_cfg.dst_info.data_width); +} + +static int d40_resume(struct dma_chan *chan) +{ + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + int res = 0; + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + + if (d40c->log_num != D40_PHY_CHAN) { + res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); + if (res) + goto out; + + /* If bytes left to transfer or linked tx resume job */ + if (d40_residue(d40c) || d40_tx_is_linked(d40c)) { + d40_config_set_event(d40c, true); + res = d40_channel_execute_command(d40c, D40_DMA_RUN); + } + } else if (d40_residue(d40c) || d40_tx_is_linked(d40c)) + res = d40_channel_execute_command(d40c, D40_DMA_RUN); + +out: + spin_unlock_irqrestore(&d40c->lock, flags); + return res; +} + +static u32 stedma40_residue(struct dma_chan *chan) +{ + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + u32 bytes_left; + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + bytes_left = d40_residue(d40c); + spin_unlock_irqrestore(&d40c->lock, flags); + + return bytes_left; +} + +/* Public DMA functions in addition to the DMA engine framework */ + +int stedma40_set_psize(struct dma_chan *chan, + int src_psize, + int dst_psize) +{ + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + + if (d40c->log_num != D40_PHY_CHAN) { + d40c->log_def.lcsp1 &= ~D40_MEM_LCSP1_SCFG_PSIZE_MASK; + d40c->log_def.lcsp3 &= ~D40_MEM_LCSP1_SCFG_PSIZE_MASK; + d40c->log_def.lcsp1 |= src_psize << D40_MEM_LCSP1_SCFG_PSIZE_POS; + d40c->log_def.lcsp3 |= dst_psize << D40_MEM_LCSP1_SCFG_PSIZE_POS; + goto out; + } + + if (src_psize == STEDMA40_PSIZE_PHY_1) + d40c->src_def_cfg &= ~(1 << D40_SREG_CFG_PHY_PEN_POS); + else { + d40c->src_def_cfg |= 1 << D40_SREG_CFG_PHY_PEN_POS; + d40c->src_def_cfg &= ~(STEDMA40_PSIZE_PHY_16 << + D40_SREG_CFG_PSIZE_POS); + d40c->src_def_cfg |= src_psize << D40_SREG_CFG_PSIZE_POS; + } + + if (dst_psize == STEDMA40_PSIZE_PHY_1) + d40c->dst_def_cfg &= ~(1 << D40_SREG_CFG_PHY_PEN_POS); + else { + d40c->dst_def_cfg |= 1 << D40_SREG_CFG_PHY_PEN_POS; + d40c->dst_def_cfg &= ~(STEDMA40_PSIZE_PHY_16 << + D40_SREG_CFG_PSIZE_POS); + d40c->dst_def_cfg |= dst_psize << D40_SREG_CFG_PSIZE_POS; + } +out: + spin_unlock_irqrestore(&d40c->lock, flags); + return 0; +} +EXPORT_SYMBOL(stedma40_set_psize); + +struct dma_async_tx_descriptor *stedma40_memcpy_sg(struct dma_chan *chan, + struct scatterlist *sgl_dst, + struct scatterlist *sgl_src, + unsigned int sgl_len, + unsigned long flags) +{ + int res; + struct d40_desc *d40d; + struct d40_chan *d40c = container_of(chan, struct d40_chan, + chan); + unsigned long flg; + int lli_max = d40c->base->plat_data->llis_per_log; + + + spin_lock_irqsave(&d40c->lock, flg); + d40d = d40_desc_get(d40c); + + if (d40d == NULL) + goto err; + + memset(d40d, 0, sizeof(struct d40_desc)); + d40d->lli_len = sgl_len; + + d40d->txd.flags = flags; + + if (d40c->log_num != D40_PHY_CHAN) { + if (sgl_len > 1) + /* + * Check if there is space available in lcla. If not, + * split list into 1-length and run only in lcpa + * space. + */ + if (d40_lcla_id_get(d40c, + &d40c->base->lcla_pool) != 0) + lli_max = 1; + + if (d40_pool_lli_alloc(d40d, sgl_len, true) < 0) { + dev_err(&d40c->chan.dev->device, + "[%s] Out of memory\n", __func__); + goto err; + } + + (void) d40_log_sg_to_lli(d40c->lcla.src_id, + sgl_src, + sgl_len, + d40d->lli_log.src, + d40c->log_def.lcsp1, + d40c->dma_cfg.src_info.data_width, + flags & DMA_PREP_INTERRUPT, lli_max, + d40c->base->plat_data->llis_per_log); + + (void) d40_log_sg_to_lli(d40c->lcla.dst_id, + sgl_dst, + sgl_len, + d40d->lli_log.dst, + d40c->log_def.lcsp3, + d40c->dma_cfg.dst_info.data_width, + flags & DMA_PREP_INTERRUPT, lli_max, + d40c->base->plat_data->llis_per_log); + + + } else { + if (d40_pool_lli_alloc(d40d, sgl_len, false) < 0) { + dev_err(&d40c->chan.dev->device, + "[%s] Out of memory\n", __func__); + goto err; + } + + res = d40_phy_sg_to_lli(sgl_src, + sgl_len, + 0, + d40d->lli_phy.src, + d40d->lli_phy.src_addr, + d40c->src_def_cfg, + d40c->dma_cfg.src_info.data_width, + d40c->dma_cfg.src_info.psize, + true); + + if (res < 0) + goto err; + + res = d40_phy_sg_to_lli(sgl_dst, + sgl_len, + 0, + d40d->lli_phy.dst, + d40d->lli_phy.dst_addr, + d40c->dst_def_cfg, + d40c->dma_cfg.dst_info.data_width, + d40c->dma_cfg.dst_info.psize, + true); + + if (res < 0) + goto err; + + (void) dma_map_single(d40c->base->dev, d40d->lli_phy.src, + d40d->lli_pool.size, DMA_TO_DEVICE); + } + + dma_async_tx_descriptor_init(&d40d->txd, chan); + + d40d->txd.tx_submit = d40_tx_submit; + + spin_unlock_irqrestore(&d40c->lock, flg); + + return &d40d->txd; +err: + spin_unlock_irqrestore(&d40c->lock, flg); + return NULL; +} +EXPORT_SYMBOL(stedma40_memcpy_sg); + +bool stedma40_filter(struct dma_chan *chan, void *data) +{ + struct stedma40_chan_cfg *info = data; + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + int err; + + if (data) { + err = d40_validate_conf(d40c, info); + if (!err) + d40c->dma_cfg = *info; + } else + err = d40_config_memcpy(d40c); + + return err == 0; +} +EXPORT_SYMBOL(stedma40_filter); + +/* DMA ENGINE functions */ +static int d40_alloc_chan_resources(struct dma_chan *chan) +{ + int err; + unsigned long flags; + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + + spin_lock_irqsave(&d40c->lock, flags); + + d40c->completed = chan->cookie = 1; + + /* + * If no dma configuration is set (channel_type == 0) + * use default configuration + */ + if (d40c->dma_cfg.channel_type == 0) { + err = d40_config_memcpy(d40c); + if (err) + goto err_alloc; + } + + err = d40_allocate_channel(d40c); + if (err) { + dev_err(&d40c->chan.dev->device, + "[%s] Failed to allocate channel\n", __func__); + goto err_alloc; + } + + err = d40_config_chan(d40c, &d40c->dma_cfg); + if (err) { + dev_err(&d40c->chan.dev->device, + "[%s] Failed to configure channel\n", + __func__); + goto err_config; + } + + spin_unlock_irqrestore(&d40c->lock, flags); + return 0; + + err_config: + (void) d40_free_dma(d40c); + err_alloc: + spin_unlock_irqrestore(&d40c->lock, flags); + dev_err(&d40c->chan.dev->device, + "[%s] Channel allocation failed\n", __func__); + return -EINVAL; +} + +static void d40_free_chan_resources(struct dma_chan *chan) +{ + struct d40_chan *d40c = + container_of(chan, struct d40_chan, chan); + int err; + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + + err = d40_free_dma(d40c); + + if (err) + dev_err(&d40c->chan.dev->device, + "[%s] Failed to free channel\n", __func__); + spin_unlock_irqrestore(&d40c->lock, flags); +} + +static struct dma_async_tx_descriptor *d40_prep_memcpy(struct dma_chan *chan, + dma_addr_t dst, + dma_addr_t src, + size_t size, + unsigned long flags) +{ + struct d40_desc *d40d; + struct d40_chan *d40c = container_of(chan, struct d40_chan, + chan); + unsigned long flg; + int err = 0; + + spin_lock_irqsave(&d40c->lock, flg); + d40d = d40_desc_get(d40c); + + if (d40d == NULL) { + dev_err(&d40c->chan.dev->device, + "[%s] Descriptor is NULL\n", __func__); + goto err; + } + + memset(d40d, 0, sizeof(struct d40_desc)); + + d40d->txd.flags = flags; + + dma_async_tx_descriptor_init(&d40d->txd, chan); + + d40d->txd.tx_submit = d40_tx_submit; + + if (d40c->log_num != D40_PHY_CHAN) { + + if (d40_pool_lli_alloc(d40d, 1, true) < 0) { + dev_err(&d40c->chan.dev->device, + "[%s] Out of memory\n", __func__); + goto err; + } + d40d->lli_len = 1; + + d40_log_fill_lli(d40d->lli_log.src, + src, + size, + 0, + d40c->log_def.lcsp1, + d40c->dma_cfg.src_info.data_width, + true, true); + + d40_log_fill_lli(d40d->lli_log.dst, + dst, + size, + 0, + d40c->log_def.lcsp3, + d40c->dma_cfg.dst_info.data_width, + true, true); + + } else { + + if (d40_pool_lli_alloc(d40d, 1, false) < 0) { + dev_err(&d40c->chan.dev->device, + "[%s] Out of memory\n", __func__); + goto err; + } + + err = d40_phy_fill_lli(d40d->lli_phy.src, + src, + size, + d40c->dma_cfg.src_info.psize, + 0, + d40c->src_def_cfg, + true, + d40c->dma_cfg.src_info.data_width, + false); + if (err) + goto err_fill_lli; + + err = d40_phy_fill_lli(d40d->lli_phy.dst, + dst, + size, + d40c->dma_cfg.dst_info.psize, + 0, + d40c->dst_def_cfg, + true, + d40c->dma_cfg.dst_info.data_width, + false); + + if (err) + goto err_fill_lli; + + (void) dma_map_single(d40c->base->dev, d40d->lli_phy.src, + d40d->lli_pool.size, DMA_TO_DEVICE); + } + + spin_unlock_irqrestore(&d40c->lock, flg); + return &d40d->txd; + +err_fill_lli: + dev_err(&d40c->chan.dev->device, + "[%s] Failed filling in PHY LLI\n", __func__); + d40_pool_lli_free(d40d); +err: + spin_unlock_irqrestore(&d40c->lock, flg); + return NULL; +} + +static int d40_prep_slave_sg_log(struct d40_desc *d40d, + struct d40_chan *d40c, + struct scatterlist *sgl, + unsigned int sg_len, + enum dma_data_direction direction, + unsigned long flags) +{ + dma_addr_t dev_addr = 0; + int total_size; + int lli_max = d40c->base->plat_data->llis_per_log; + + if (d40_pool_lli_alloc(d40d, sg_len, true) < 0) { + dev_err(&d40c->chan.dev->device, + "[%s] Out of memory\n", __func__); + return -ENOMEM; + } + + d40d->lli_len = sg_len; + d40d->lli_tcount = 0; + + if (sg_len > 1) + /* + * Check if there is space available in lcla. + * If not, split list into 1-length and run only + * in lcpa space. + */ + if (d40_lcla_id_get(d40c, &d40c->base->lcla_pool) != 0) + lli_max = 1; + + if (direction == DMA_FROM_DEVICE) { + dev_addr = d40c->base->plat_data->dev_rx[d40c->dma_cfg.src_dev_type]; + total_size = d40_log_sg_to_dev(&d40c->lcla, + sgl, sg_len, + &d40d->lli_log, + &d40c->log_def, + d40c->dma_cfg.src_info.data_width, + d40c->dma_cfg.dst_info.data_width, + direction, + flags & DMA_PREP_INTERRUPT, + dev_addr, lli_max, + d40c->base->plat_data->llis_per_log); + } else if (direction == DMA_TO_DEVICE) { + dev_addr = d40c->base->plat_data->dev_tx[d40c->dma_cfg.dst_dev_type]; + total_size = d40_log_sg_to_dev(&d40c->lcla, + sgl, sg_len, + &d40d->lli_log, + &d40c->log_def, + d40c->dma_cfg.src_info.data_width, + d40c->dma_cfg.dst_info.data_width, + direction, + flags & DMA_PREP_INTERRUPT, + dev_addr, lli_max, + d40c->base->plat_data->llis_per_log); + } else + return -EINVAL; + if (total_size < 0) + return -EINVAL; + + return 0; +} + +static int d40_prep_slave_sg_phy(struct d40_desc *d40d, + struct d40_chan *d40c, + struct scatterlist *sgl, + unsigned int sgl_len, + enum dma_data_direction direction, + unsigned long flags) +{ + dma_addr_t src_dev_addr; + dma_addr_t dst_dev_addr; + int res; + + if (d40_pool_lli_alloc(d40d, sgl_len, false) < 0) { + dev_err(&d40c->chan.dev->device, + "[%s] Out of memory\n", __func__); + return -ENOMEM; + } + + d40d->lli_len = sgl_len; + d40d->lli_tcount = 0; + + if (direction == DMA_FROM_DEVICE) { + dst_dev_addr = 0; + src_dev_addr = d40c->base->plat_data->dev_rx[d40c->dma_cfg.src_dev_type]; + } else if (direction == DMA_TO_DEVICE) { + dst_dev_addr = d40c->base->plat_data->dev_tx[d40c->dma_cfg.dst_dev_type]; + src_dev_addr = 0; + } else + return -EINVAL; + + res = d40_phy_sg_to_lli(sgl, + sgl_len, + src_dev_addr, + d40d->lli_phy.src, + d40d->lli_phy.src_addr, + d40c->src_def_cfg, + d40c->dma_cfg.src_info.data_width, + d40c->dma_cfg.src_info.psize, + true); + if (res < 0) + return res; + + res = d40_phy_sg_to_lli(sgl, + sgl_len, + dst_dev_addr, + d40d->lli_phy.dst, + d40d->lli_phy.dst_addr, + d40c->dst_def_cfg, + d40c->dma_cfg.dst_info.data_width, + d40c->dma_cfg.dst_info.psize, + true); + if (res < 0) + return res; + + (void) dma_map_single(d40c->base->dev, d40d->lli_phy.src, + d40d->lli_pool.size, DMA_TO_DEVICE); + return 0; +} + +static struct dma_async_tx_descriptor *d40_prep_slave_sg(struct dma_chan *chan, + struct scatterlist *sgl, + unsigned int sg_len, + enum dma_data_direction direction, + unsigned long flags) +{ + struct d40_desc *d40d; + struct d40_chan *d40c = container_of(chan, struct d40_chan, + chan); + unsigned long flg; + int err; + + if (d40c->dma_cfg.pre_transfer) + d40c->dma_cfg.pre_transfer(chan, + d40c->dma_cfg.pre_transfer_data, + sg_dma_len(sgl)); + + spin_lock_irqsave(&d40c->lock, flg); + d40d = d40_desc_get(d40c); + spin_unlock_irqrestore(&d40c->lock, flg); + + if (d40d == NULL) + return NULL; + + memset(d40d, 0, sizeof(struct d40_desc)); + + if (d40c->log_num != D40_PHY_CHAN) + err = d40_prep_slave_sg_log(d40d, d40c, sgl, sg_len, + direction, flags); + else + err = d40_prep_slave_sg_phy(d40d, d40c, sgl, sg_len, + direction, flags); + if (err) { + dev_err(&d40c->chan.dev->device, + "[%s] Failed to prepare %s slave sg job: %d\n", + __func__, + d40c->log_num != D40_PHY_CHAN ? "log" : "phy", err); + return NULL; + } + + d40d->txd.flags = flags; + + dma_async_tx_descriptor_init(&d40d->txd, chan); + + d40d->txd.tx_submit = d40_tx_submit; + + return &d40d->txd; +} + +static enum dma_status d40_tx_status(struct dma_chan *chan, + dma_cookie_t cookie, + struct dma_tx_state *txstate) +{ + struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); + dma_cookie_t last_used; + dma_cookie_t last_complete; + int ret; + + last_complete = d40c->completed; + last_used = chan->cookie; + + ret = dma_async_is_complete(cookie, last_complete, last_used); + + if (txstate) { + txstate->last = last_complete; + txstate->used = last_used; + txstate->residue = stedma40_residue(chan); + } + + return ret; +} + +static void d40_issue_pending(struct dma_chan *chan) +{ + struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); + unsigned long flags; + + spin_lock_irqsave(&d40c->lock, flags); + + /* Busy means that pending jobs are already being processed */ + if (!d40c->busy) + (void) d40_queue_start(d40c); + + spin_unlock_irqrestore(&d40c->lock, flags); +} + +static int d40_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +{ + unsigned long flags; + struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); + + switch (cmd) { + case DMA_TERMINATE_ALL: + spin_lock_irqsave(&d40c->lock, flags); + d40_term_all(d40c); + spin_unlock_irqrestore(&d40c->lock, flags); + return 0; + case DMA_PAUSE: + return d40_pause(chan); + case DMA_RESUME: + return d40_resume(chan); + } + + /* Other commands are unimplemented */ + return -ENXIO; +} + +/* Initialization functions */ + +static void __init d40_chan_init(struct d40_base *base, struct dma_device *dma, + struct d40_chan *chans, int offset, + int num_chans) +{ + int i = 0; + struct d40_chan *d40c; + + INIT_LIST_HEAD(&dma->channels); + + for (i = offset; i < offset + num_chans; i++) { + d40c = &chans[i]; + d40c->base = base; + d40c->chan.device = dma; + + /* Invalidate lcla element */ + d40c->lcla.src_id = -1; + d40c->lcla.dst_id = -1; + + spin_lock_init(&d40c->lock); + + d40c->log_num = D40_PHY_CHAN; + + INIT_LIST_HEAD(&d40c->free); + INIT_LIST_HEAD(&d40c->active); + INIT_LIST_HEAD(&d40c->queue); + INIT_LIST_HEAD(&d40c->client); + + d40c->free_len = 0; + + tasklet_init(&d40c->tasklet, dma_tasklet, + (unsigned long) d40c); + + list_add_tail(&d40c->chan.device_node, + &dma->channels); + } +} + +static int __init d40_dmaengine_init(struct d40_base *base, + int num_reserved_chans) +{ + int err ; + + d40_chan_init(base, &base->dma_slave, base->log_chans, + 0, base->num_log_chans); + + dma_cap_zero(base->dma_slave.cap_mask); + dma_cap_set(DMA_SLAVE, base->dma_slave.cap_mask); + + base->dma_slave.device_alloc_chan_resources = d40_alloc_chan_resources; + base->dma_slave.device_free_chan_resources = d40_free_chan_resources; + base->dma_slave.device_prep_dma_memcpy = d40_prep_memcpy; + base->dma_slave.device_prep_slave_sg = d40_prep_slave_sg; + base->dma_slave.device_tx_status = d40_tx_status; + base->dma_slave.device_issue_pending = d40_issue_pending; + base->dma_slave.device_control = d40_control; + base->dma_slave.dev = base->dev; + + err = dma_async_device_register(&base->dma_slave); + + if (err) { + dev_err(base->dev, + "[%s] Failed to register slave channels\n", + __func__); + goto failure1; + } + + d40_chan_init(base, &base->dma_memcpy, base->log_chans, + base->num_log_chans, base->plat_data->memcpy_len); + + dma_cap_zero(base->dma_memcpy.cap_mask); + dma_cap_set(DMA_MEMCPY, base->dma_memcpy.cap_mask); + + base->dma_memcpy.device_alloc_chan_resources = d40_alloc_chan_resources; + base->dma_memcpy.device_free_chan_resources = d40_free_chan_resources; + base->dma_memcpy.device_prep_dma_memcpy = d40_prep_memcpy; + base->dma_memcpy.device_prep_slave_sg = d40_prep_slave_sg; + base->dma_memcpy.device_tx_status = d40_tx_status; + base->dma_memcpy.device_issue_pending = d40_issue_pending; + base->dma_memcpy.device_control = d40_control; + base->dma_memcpy.dev = base->dev; + /* + * This controller can only access address at even + * 32bit boundaries, i.e. 2^2 + */ + base->dma_memcpy.copy_align = 2; + + err = dma_async_device_register(&base->dma_memcpy); + + if (err) { + dev_err(base->dev, + "[%s] Failed to regsiter memcpy only channels\n", + __func__); + goto failure2; + } + + d40_chan_init(base, &base->dma_both, base->phy_chans, + 0, num_reserved_chans); + + dma_cap_zero(base->dma_both.cap_mask); + dma_cap_set(DMA_SLAVE, base->dma_both.cap_mask); + dma_cap_set(DMA_MEMCPY, base->dma_both.cap_mask); + + base->dma_both.device_alloc_chan_resources = d40_alloc_chan_resources; + base->dma_both.device_free_chan_resources = d40_free_chan_resources; + base->dma_both.device_prep_dma_memcpy = d40_prep_memcpy; + base->dma_both.device_prep_slave_sg = d40_prep_slave_sg; + base->dma_both.device_tx_status = d40_tx_status; + base->dma_both.device_issue_pending = d40_issue_pending; + base->dma_both.device_control = d40_control; + base->dma_both.dev = base->dev; + base->dma_both.copy_align = 2; + err = dma_async_device_register(&base->dma_both); + + if (err) { + dev_err(base->dev, + "[%s] Failed to register logical and physical capable channels\n", + __func__); + goto failure3; + } + return 0; +failure3: + dma_async_device_unregister(&base->dma_memcpy); +failure2: + dma_async_device_unregister(&base->dma_slave); +failure1: + return err; +} + +/* Initialization functions. */ + +static int __init d40_phy_res_init(struct d40_base *base) +{ + int i; + int num_phy_chans_avail = 0; + u32 val[2]; + int odd_even_bit = -2; + + val[0] = readl(base->virtbase + D40_DREG_PRSME); + val[1] = readl(base->virtbase + D40_DREG_PRSMO); + + for (i = 0; i < base->num_phy_chans; i++) { + base->phy_res[i].num = i; + odd_even_bit += 2 * ((i % 2) == 0); + if (((val[i % 2] >> odd_even_bit) & 3) == 1) { + /* Mark security only channels as occupied */ + base->phy_res[i].allocated_src = D40_ALLOC_PHY; + base->phy_res[i].allocated_dst = D40_ALLOC_PHY; + } else { + base->phy_res[i].allocated_src = D40_ALLOC_FREE; + base->phy_res[i].allocated_dst = D40_ALLOC_FREE; + num_phy_chans_avail++; + } + spin_lock_init(&base->phy_res[i].lock); + } + dev_info(base->dev, "%d of %d physical DMA channels available\n", + num_phy_chans_avail, base->num_phy_chans); + + /* Verify settings extended vs standard */ + val[0] = readl(base->virtbase + D40_DREG_PRTYP); + + for (i = 0; i < base->num_phy_chans; i++) { + + if (base->phy_res[i].allocated_src == D40_ALLOC_FREE && + (val[0] & 0x3) != 1) + dev_info(base->dev, + "[%s] INFO: channel %d is misconfigured (%d)\n", + __func__, i, val[0] & 0x3); + + val[0] = val[0] >> 2; + } + + return num_phy_chans_avail; +} + +static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) +{ + static const struct d40_reg_val dma_id_regs[] = { + /* Peripheral Id */ + { .reg = D40_DREG_PERIPHID0, .val = 0x0040}, + { .reg = D40_DREG_PERIPHID1, .val = 0x0000}, + /* + * D40_DREG_PERIPHID2 Depends on HW revision: + * MOP500/HREF ED has 0x0008, + * ? has 0x0018, + * HREF V1 has 0x0028 + */ + { .reg = D40_DREG_PERIPHID3, .val = 0x0000}, + + /* PCell Id */ + { .reg = D40_DREG_CELLID0, .val = 0x000d}, + { .reg = D40_DREG_CELLID1, .val = 0x00f0}, + { .reg = D40_DREG_CELLID2, .val = 0x0005}, + { .reg = D40_DREG_CELLID3, .val = 0x00b1} + }; + struct stedma40_platform_data *plat_data; + struct clk *clk = NULL; + void __iomem *virtbase = NULL; + struct resource *res = NULL; + struct d40_base *base = NULL; + int num_log_chans = 0; + int num_phy_chans; + int i; + + clk = clk_get(&pdev->dev, NULL); + + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "[%s] No matching clock found\n", + __func__); + goto failure; + } + + clk_enable(clk); + + /* Get IO for DMAC base address */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "base"); + if (!res) + goto failure; + + if (request_mem_region(res->start, resource_size(res), + D40_NAME " I/O base") == NULL) + goto failure; + + virtbase = ioremap(res->start, resource_size(res)); + if (!virtbase) + goto failure; + + /* HW version check */ + for (i = 0; i < ARRAY_SIZE(dma_id_regs); i++) { + if (dma_id_regs[i].val != + readl(virtbase + dma_id_regs[i].reg)) { + dev_err(&pdev->dev, + "[%s] Unknown hardware! Expected 0x%x at 0x%x but got 0x%x\n", + __func__, + dma_id_regs[i].val, + dma_id_regs[i].reg, + readl(virtbase + dma_id_regs[i].reg)); + goto failure; + } + } + + i = readl(virtbase + D40_DREG_PERIPHID2); + + if ((i & 0xf) != D40_PERIPHID2_DESIGNER) { + dev_err(&pdev->dev, + "[%s] Unknown designer! Got %x wanted %x\n", + __func__, i & 0xf, D40_PERIPHID2_DESIGNER); + goto failure; + } + + /* The number of physical channels on this HW */ + num_phy_chans = 4 * (readl(virtbase + D40_DREG_ICFG) & 0x7) + 4; + + dev_info(&pdev->dev, "hardware revision: %d @ 0x%x\n", + (i >> 4) & 0xf, res->start); + + plat_data = pdev->dev.platform_data; + + /* Count the number of logical channels in use */ + for (i = 0; i < plat_data->dev_len; i++) + if (plat_data->dev_rx[i] != 0) + num_log_chans++; + + for (i = 0; i < plat_data->dev_len; i++) + if (plat_data->dev_tx[i] != 0) + num_log_chans++; + + base = kzalloc(ALIGN(sizeof(struct d40_base), 4) + + (num_phy_chans + num_log_chans + plat_data->memcpy_len) * + sizeof(struct d40_chan), GFP_KERNEL); + + if (base == NULL) { + dev_err(&pdev->dev, "[%s] Out of memory\n", __func__); + goto failure; + } + + base->clk = clk; + base->num_phy_chans = num_phy_chans; + base->num_log_chans = num_log_chans; + base->phy_start = res->start; + base->phy_size = resource_size(res); + base->virtbase = virtbase; + base->plat_data = plat_data; + base->dev = &pdev->dev; + base->phy_chans = ((void *)base) + ALIGN(sizeof(struct d40_base), 4); + base->log_chans = &base->phy_chans[num_phy_chans]; + + base->phy_res = kzalloc(num_phy_chans * sizeof(struct d40_phy_res), + GFP_KERNEL); + if (!base->phy_res) + goto failure; + + base->lookup_phy_chans = kzalloc(num_phy_chans * + sizeof(struct d40_chan *), + GFP_KERNEL); + if (!base->lookup_phy_chans) + goto failure; + + if (num_log_chans + plat_data->memcpy_len) { + /* + * The max number of logical channels are event lines for all + * src devices and dst devices + */ + base->lookup_log_chans = kzalloc(plat_data->dev_len * 2 * + sizeof(struct d40_chan *), + GFP_KERNEL); + if (!base->lookup_log_chans) + goto failure; + } + base->lcla_pool.alloc_map = kzalloc(num_phy_chans * sizeof(u32), + GFP_KERNEL); + if (!base->lcla_pool.alloc_map) + goto failure; + + return base; + +failure: + if (clk) { + clk_disable(clk); + clk_put(clk); + } + if (virtbase) + iounmap(virtbase); + if (res) + release_mem_region(res->start, + resource_size(res)); + if (virtbase) + iounmap(virtbase); + + if (base) { + kfree(base->lcla_pool.alloc_map); + kfree(base->lookup_log_chans); + kfree(base->lookup_phy_chans); + kfree(base->phy_res); + kfree(base); + } + + return NULL; +} + +static void __init d40_hw_init(struct d40_base *base) +{ + + static const struct d40_reg_val dma_init_reg[] = { + /* Clock every part of the DMA block from start */ + { .reg = D40_DREG_GCC, .val = 0x0000ff01}, + + /* Interrupts on all logical channels */ + { .reg = D40_DREG_LCMIS0, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCMIS1, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCMIS2, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCMIS3, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCICR0, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCICR1, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCICR2, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCICR3, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCTIS0, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCTIS1, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCTIS2, .val = 0xFFFFFFFF}, + { .reg = D40_DREG_LCTIS3, .val = 0xFFFFFFFF} + }; + int i; + u32 prmseo[2] = {0, 0}; + u32 activeo[2] = {0xFFFFFFFF, 0xFFFFFFFF}; + u32 pcmis = 0; + u32 pcicr = 0; + + for (i = 0; i < ARRAY_SIZE(dma_init_reg); i++) + writel(dma_init_reg[i].val, + base->virtbase + dma_init_reg[i].reg); + + /* Configure all our dma channels to default settings */ + for (i = 0; i < base->num_phy_chans; i++) { + + activeo[i % 2] = activeo[i % 2] << 2; + + if (base->phy_res[base->num_phy_chans - i - 1].allocated_src + == D40_ALLOC_PHY) { + activeo[i % 2] |= 3; + continue; + } + + /* Enable interrupt # */ + pcmis = (pcmis << 1) | 1; + + /* Clear interrupt # */ + pcicr = (pcicr << 1) | 1; + + /* Set channel to physical mode */ + prmseo[i % 2] = prmseo[i % 2] << 2; + prmseo[i % 2] |= 1; + + } + + writel(prmseo[1], base->virtbase + D40_DREG_PRMSE); + writel(prmseo[0], base->virtbase + D40_DREG_PRMSO); + writel(activeo[1], base->virtbase + D40_DREG_ACTIVE); + writel(activeo[0], base->virtbase + D40_DREG_ACTIVO); + + /* Write which interrupt to enable */ + writel(pcmis, base->virtbase + D40_DREG_PCMIS); + + /* Write which interrupt to clear */ + writel(pcicr, base->virtbase + D40_DREG_PCICR); + +} + +static int __init d40_probe(struct platform_device *pdev) +{ + int err; + int ret = -ENOENT; + struct d40_base *base; + struct resource *res = NULL; + int num_reserved_chans; + u32 val; + + base = d40_hw_detect_init(pdev); + + if (!base) + goto failure; + + num_reserved_chans = d40_phy_res_init(base); + + platform_set_drvdata(pdev, base); + + spin_lock_init(&base->interrupt_lock); + spin_lock_init(&base->execmd_lock); + + /* Get IO for logical channel parameter address */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lcpa"); + if (!res) { + ret = -ENOENT; + dev_err(&pdev->dev, + "[%s] No \"lcpa\" memory resource\n", + __func__); + goto failure; + } + base->lcpa_size = resource_size(res); + base->phy_lcpa = res->start; + + if (request_mem_region(res->start, resource_size(res), + D40_NAME " I/O lcpa") == NULL) { + ret = -EBUSY; + dev_err(&pdev->dev, + "[%s] Failed to request LCPA region 0x%x-0x%x\n", + __func__, res->start, res->end); + goto failure; + } + + /* We make use of ESRAM memory for this. */ + val = readl(base->virtbase + D40_DREG_LCPA); + if (res->start != val && val != 0) { + dev_warn(&pdev->dev, + "[%s] Mismatch LCPA dma 0x%x, def 0x%x\n", + __func__, val, res->start); + } else + writel(res->start, base->virtbase + D40_DREG_LCPA); + + base->lcpa_base = ioremap(res->start, resource_size(res)); + if (!base->lcpa_base) { + ret = -ENOMEM; + dev_err(&pdev->dev, + "[%s] Failed to ioremap LCPA region\n", + __func__); + goto failure; + } + /* Get IO for logical channel link address */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lcla"); + if (!res) { + ret = -ENOENT; + dev_err(&pdev->dev, + "[%s] No \"lcla\" resource defined\n", + __func__); + goto failure; + } + + base->lcla_pool.base_size = resource_size(res); + base->lcla_pool.phy = res->start; + + if (request_mem_region(res->start, resource_size(res), + D40_NAME " I/O lcla") == NULL) { + ret = -EBUSY; + dev_err(&pdev->dev, + "[%s] Failed to request LCLA region 0x%x-0x%x\n", + __func__, res->start, res->end); + goto failure; + } + val = readl(base->virtbase + D40_DREG_LCLA); + if (res->start != val && val != 0) { + dev_warn(&pdev->dev, + "[%s] Mismatch LCLA dma 0x%x, def 0x%x\n", + __func__, val, res->start); + } else + writel(res->start, base->virtbase + D40_DREG_LCLA); + + base->lcla_pool.base = ioremap(res->start, resource_size(res)); + if (!base->lcla_pool.base) { + ret = -ENOMEM; + dev_err(&pdev->dev, + "[%s] Failed to ioremap LCLA 0x%x-0x%x\n", + __func__, res->start, res->end); + goto failure; + } + + spin_lock_init(&base->lcla_pool.lock); + + base->lcla_pool.num_blocks = base->num_phy_chans; + + base->irq = platform_get_irq(pdev, 0); + + ret = request_irq(base->irq, d40_handle_interrupt, 0, D40_NAME, base); + + if (ret) { + dev_err(&pdev->dev, "[%s] No IRQ defined\n", __func__); + goto failure; + } + + err = d40_dmaengine_init(base, num_reserved_chans); + if (err) + goto failure; + + d40_hw_init(base); + + dev_info(base->dev, "initialized\n"); + return 0; + +failure: + if (base) { + if (base->virtbase) + iounmap(base->virtbase); + if (base->lcla_pool.phy) + release_mem_region(base->lcla_pool.phy, + base->lcla_pool.base_size); + if (base->phy_lcpa) + release_mem_region(base->phy_lcpa, + base->lcpa_size); + if (base->phy_start) + release_mem_region(base->phy_start, + base->phy_size); + if (base->clk) { + clk_disable(base->clk); + clk_put(base->clk); + } + + kfree(base->lcla_pool.alloc_map); + kfree(base->lookup_log_chans); + kfree(base->lookup_phy_chans); + kfree(base->phy_res); + kfree(base); + } + + dev_err(&pdev->dev, "[%s] probe failed\n", __func__); + return ret; +} + +static struct platform_driver d40_driver = { + .driver = { + .owner = THIS_MODULE, + .name = D40_NAME, + }, +}; + +int __init stedma40_init(void) +{ + return platform_driver_probe(&d40_driver, d40_probe); +} +arch_initcall(stedma40_init); diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c new file mode 100644 index 000000000000..561fdd8a80c1 --- /dev/null +++ b/drivers/dma/ste_dma40_ll.c @@ -0,0 +1,454 @@ +/* + * driver/dma/ste_dma40_ll.c + * + * Copyright (C) ST-Ericsson 2007-2010 + * License terms: GNU General Public License (GPL) version 2 + * Author: Per Friden + * Author: Jonas Aaberg + */ + +#include +#include + +#include "ste_dma40_ll.h" + +/* Sets up proper LCSP1 and LCSP3 register for a logical channel */ +void d40_log_cfg(struct stedma40_chan_cfg *cfg, + u32 *lcsp1, u32 *lcsp3) +{ + u32 l3 = 0; /* dst */ + u32 l1 = 0; /* src */ + + /* src is mem? -> increase address pos */ + if (cfg->dir == STEDMA40_MEM_TO_PERIPH || + cfg->dir == STEDMA40_MEM_TO_MEM) + l1 |= 1 << D40_MEM_LCSP1_SCFG_INCR_POS; + + /* dst is mem? -> increase address pos */ + if (cfg->dir == STEDMA40_PERIPH_TO_MEM || + cfg->dir == STEDMA40_MEM_TO_MEM) + l3 |= 1 << D40_MEM_LCSP3_DCFG_INCR_POS; + + /* src is hw? -> master port 1 */ + if (cfg->dir == STEDMA40_PERIPH_TO_MEM || + cfg->dir == STEDMA40_PERIPH_TO_PERIPH) + l1 |= 1 << D40_MEM_LCSP1_SCFG_MST_POS; + + /* dst is hw? -> master port 1 */ + if (cfg->dir == STEDMA40_MEM_TO_PERIPH || + cfg->dir == STEDMA40_PERIPH_TO_PERIPH) + l3 |= 1 << D40_MEM_LCSP3_DCFG_MST_POS; + + l3 |= 1 << D40_MEM_LCSP3_DCFG_TIM_POS; + l3 |= 1 << D40_MEM_LCSP3_DCFG_EIM_POS; + l3 |= cfg->dst_info.psize << D40_MEM_LCSP3_DCFG_PSIZE_POS; + l3 |= cfg->dst_info.data_width << D40_MEM_LCSP3_DCFG_ESIZE_POS; + l3 |= 1 << D40_MEM_LCSP3_DTCP_POS; + + l1 |= 1 << D40_MEM_LCSP1_SCFG_EIM_POS; + l1 |= cfg->src_info.psize << D40_MEM_LCSP1_SCFG_PSIZE_POS; + l1 |= cfg->src_info.data_width << D40_MEM_LCSP1_SCFG_ESIZE_POS; + l1 |= 1 << D40_MEM_LCSP1_STCP_POS; + + *lcsp1 = l1; + *lcsp3 = l3; + +} + +/* Sets up SRC and DST CFG register for both logical and physical channels */ +void d40_phy_cfg(struct stedma40_chan_cfg *cfg, + u32 *src_cfg, u32 *dst_cfg, bool is_log) +{ + u32 src = 0; + u32 dst = 0; + + if (!is_log) { + /* Physical channel */ + if ((cfg->dir == STEDMA40_PERIPH_TO_MEM) || + (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { + /* Set master port to 1 */ + src |= 1 << D40_SREG_CFG_MST_POS; + src |= D40_TYPE_TO_EVENT(cfg->src_dev_type); + + if (cfg->src_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL) + src |= 1 << D40_SREG_CFG_PHY_TM_POS; + else + src |= 3 << D40_SREG_CFG_PHY_TM_POS; + } + if ((cfg->dir == STEDMA40_MEM_TO_PERIPH) || + (cfg->dir == STEDMA40_PERIPH_TO_PERIPH)) { + /* Set master port to 1 */ + dst |= 1 << D40_SREG_CFG_MST_POS; + dst |= D40_TYPE_TO_EVENT(cfg->dst_dev_type); + + if (cfg->dst_info.flow_ctrl == STEDMA40_NO_FLOW_CTRL) + dst |= 1 << D40_SREG_CFG_PHY_TM_POS; + else + dst |= 3 << D40_SREG_CFG_PHY_TM_POS; + } + /* Interrupt on end of transfer for destination */ + dst |= 1 << D40_SREG_CFG_TIM_POS; + + /* Generate interrupt on error */ + src |= 1 << D40_SREG_CFG_EIM_POS; + dst |= 1 << D40_SREG_CFG_EIM_POS; + + /* PSIZE */ + if (cfg->src_info.psize != STEDMA40_PSIZE_PHY_1) { + src |= 1 << D40_SREG_CFG_PHY_PEN_POS; + src |= cfg->src_info.psize << D40_SREG_CFG_PSIZE_POS; + } + if (cfg->dst_info.psize != STEDMA40_PSIZE_PHY_1) { + dst |= 1 << D40_SREG_CFG_PHY_PEN_POS; + dst |= cfg->dst_info.psize << D40_SREG_CFG_PSIZE_POS; + } + + /* Element size */ + src |= cfg->src_info.data_width << D40_SREG_CFG_ESIZE_POS; + dst |= cfg->dst_info.data_width << D40_SREG_CFG_ESIZE_POS; + + } else { + /* Logical channel */ + dst |= 1 << D40_SREG_CFG_LOG_GIM_POS; + src |= 1 << D40_SREG_CFG_LOG_GIM_POS; + } + + if (cfg->channel_type & STEDMA40_HIGH_PRIORITY_CHANNEL) { + src |= 1 << D40_SREG_CFG_PRI_POS; + dst |= 1 << D40_SREG_CFG_PRI_POS; + } + + src |= cfg->src_info.endianess << D40_SREG_CFG_LBE_POS; + dst |= cfg->dst_info.endianess << D40_SREG_CFG_LBE_POS; + + *src_cfg = src; + *dst_cfg = dst; +} + +int d40_phy_fill_lli(struct d40_phy_lli *lli, + dma_addr_t data, + u32 data_size, + int psize, + dma_addr_t next_lli, + u32 reg_cfg, + bool term_int, + u32 data_width, + bool is_device) +{ + int num_elems; + + if (psize == STEDMA40_PSIZE_PHY_1) + num_elems = 1; + else + num_elems = 2 << psize; + + /* + * Size is 16bit. data_width is 8, 16, 32 or 64 bit + * Block large than 64 KiB must be split. + */ + if (data_size > (0xffff << data_width)) + return -EINVAL; + + /* Must be aligned */ + if (!IS_ALIGNED(data, 0x1 << data_width)) + return -EINVAL; + + /* Transfer size can't be smaller than (num_elms * elem_size) */ + if (data_size < num_elems * (0x1 << data_width)) + return -EINVAL; + + /* The number of elements. IE now many chunks */ + lli->reg_elt = (data_size >> data_width) << D40_SREG_ELEM_PHY_ECNT_POS; + + /* + * Distance to next element sized entry. + * Usually the size of the element unless you want gaps. + */ + if (!is_device) + lli->reg_elt |= (0x1 << data_width) << + D40_SREG_ELEM_PHY_EIDX_POS; + + /* Where the data is */ + lli->reg_ptr = data; + lli->reg_cfg = reg_cfg; + + /* If this scatter list entry is the last one, no next link */ + if (next_lli == 0) + lli->reg_lnk = 0x1 << D40_SREG_LNK_PHY_TCP_POS; + else + lli->reg_lnk = next_lli; + + /* Set/clear interrupt generation on this link item.*/ + if (term_int) + lli->reg_cfg |= 0x1 << D40_SREG_CFG_TIM_POS; + else + lli->reg_cfg &= ~(0x1 << D40_SREG_CFG_TIM_POS); + + /* Post link */ + lli->reg_lnk |= 0 << D40_SREG_LNK_PHY_PRE_POS; + + return 0; +} + +int d40_phy_sg_to_lli(struct scatterlist *sg, + int sg_len, + dma_addr_t target, + struct d40_phy_lli *lli, + dma_addr_t lli_phys, + u32 reg_cfg, + u32 data_width, + int psize, + bool term_int) +{ + int total_size = 0; + int i; + struct scatterlist *current_sg = sg; + dma_addr_t next_lli_phys; + dma_addr_t dst; + int err = 0; + + for_each_sg(sg, current_sg, sg_len, i) { + + total_size += sg_dma_len(current_sg); + + /* If this scatter list entry is the last one, no next link */ + if (sg_len - 1 == i) + next_lli_phys = 0; + else + next_lli_phys = ALIGN(lli_phys + (i + 1) * + sizeof(struct d40_phy_lli), + D40_LLI_ALIGN); + + if (target) + dst = target; + else + dst = sg_phys(current_sg); + + err = d40_phy_fill_lli(&lli[i], + dst, + sg_dma_len(current_sg), + psize, + next_lli_phys, + reg_cfg, + !next_lli_phys, + data_width, + target == dst); + if (err) + goto err; + } + + return total_size; + err: + return err; +} + + +void d40_phy_lli_write(void __iomem *virtbase, + u32 phy_chan_num, + struct d40_phy_lli *lli_dst, + struct d40_phy_lli *lli_src) +{ + + writel(lli_src->reg_cfg, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SSCFG); + writel(lli_src->reg_elt, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SSELT); + writel(lli_src->reg_ptr, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SSPTR); + writel(lli_src->reg_lnk, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SSLNK); + + writel(lli_dst->reg_cfg, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SDCFG); + writel(lli_dst->reg_elt, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SDELT); + writel(lli_dst->reg_ptr, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SDPTR); + writel(lli_dst->reg_lnk, virtbase + D40_DREG_PCBASE + + phy_chan_num * D40_DREG_PCDELTA + D40_CHAN_REG_SDLNK); + +} + +/* DMA logical lli operations */ + +void d40_log_fill_lli(struct d40_log_lli *lli, + dma_addr_t data, u32 data_size, + u32 lli_next_off, u32 reg_cfg, + u32 data_width, + bool term_int, bool addr_inc) +{ + lli->lcsp13 = reg_cfg; + + /* The number of elements to transfer */ + lli->lcsp02 = ((data_size >> data_width) << + D40_MEM_LCSP0_ECNT_POS) & D40_MEM_LCSP0_ECNT_MASK; + /* 16 LSBs address of the current element */ + lli->lcsp02 |= data & D40_MEM_LCSP0_SPTR_MASK; + /* 16 MSBs address of the current element */ + lli->lcsp13 |= data & D40_MEM_LCSP1_SPTR_MASK; + + if (addr_inc) + lli->lcsp13 |= D40_MEM_LCSP1_SCFG_INCR_MASK; + + lli->lcsp13 |= D40_MEM_LCSP3_DTCP_MASK; + /* If this scatter list entry is the last one, no next link */ + lli->lcsp13 |= (lli_next_off << D40_MEM_LCSP1_SLOS_POS) & + D40_MEM_LCSP1_SLOS_MASK; + + if (term_int) + lli->lcsp13 |= D40_MEM_LCSP1_SCFG_TIM_MASK; + else + lli->lcsp13 &= ~D40_MEM_LCSP1_SCFG_TIM_MASK; +} + +int d40_log_sg_to_dev(struct d40_lcla_elem *lcla, + struct scatterlist *sg, + int sg_len, + struct d40_log_lli_bidir *lli, + struct d40_def_lcsp *lcsp, + u32 src_data_width, + u32 dst_data_width, + enum dma_data_direction direction, + bool term_int, dma_addr_t dev_addr, int max_len, + int llis_per_log) +{ + int total_size = 0; + struct scatterlist *current_sg = sg; + int i; + u32 next_lli_off_dst; + u32 next_lli_off_src; + + next_lli_off_src = 0; + next_lli_off_dst = 0; + + for_each_sg(sg, current_sg, sg_len, i) { + total_size += sg_dma_len(current_sg); + + /* + * If this scatter list entry is the last one or + * max length, terminate link. + */ + if (sg_len - 1 == i || ((i+1) % max_len == 0)) { + next_lli_off_src = 0; + next_lli_off_dst = 0; + } else { + if (next_lli_off_dst == 0 && + next_lli_off_src == 0) { + /* The first lli will be at next_lli_off */ + next_lli_off_dst = (lcla->dst_id * + llis_per_log + 1); + next_lli_off_src = (lcla->src_id * + llis_per_log + 1); + } else { + next_lli_off_dst++; + next_lli_off_src++; + } + } + + if (direction == DMA_TO_DEVICE) { + d40_log_fill_lli(&lli->src[i], + sg_phys(current_sg), + sg_dma_len(current_sg), + next_lli_off_src, + lcsp->lcsp1, src_data_width, + term_int && !next_lli_off_src, + true); + d40_log_fill_lli(&lli->dst[i], + dev_addr, + sg_dma_len(current_sg), + next_lli_off_dst, + lcsp->lcsp3, dst_data_width, + /* No next == terminal interrupt */ + term_int && !next_lli_off_dst, + false); + } else { + d40_log_fill_lli(&lli->dst[i], + sg_phys(current_sg), + sg_dma_len(current_sg), + next_lli_off_dst, + lcsp->lcsp3, dst_data_width, + /* No next == terminal interrupt */ + term_int && !next_lli_off_dst, + true); + d40_log_fill_lli(&lli->src[i], + dev_addr, + sg_dma_len(current_sg), + next_lli_off_src, + lcsp->lcsp1, src_data_width, + term_int && !next_lli_off_src, + false); + } + } + return total_size; +} + +int d40_log_sg_to_lli(int lcla_id, + struct scatterlist *sg, + int sg_len, + struct d40_log_lli *lli_sg, + u32 lcsp13, /* src or dst*/ + u32 data_width, + bool term_int, int max_len, int llis_per_log) +{ + int total_size = 0; + struct scatterlist *current_sg = sg; + int i; + u32 next_lli_off = 0; + + for_each_sg(sg, current_sg, sg_len, i) { + total_size += sg_dma_len(current_sg); + + /* + * If this scatter list entry is the last one or + * max length, terminate link. + */ + if (sg_len - 1 == i || ((i+1) % max_len == 0)) + next_lli_off = 0; + else { + if (next_lli_off == 0) + /* The first lli will be at next_lli_off */ + next_lli_off = lcla_id * llis_per_log + 1; + else + next_lli_off++; + } + + d40_log_fill_lli(&lli_sg[i], + sg_phys(current_sg), + sg_dma_len(current_sg), + next_lli_off, + lcsp13, data_width, + term_int && !next_lli_off, + true); + } + return total_size; +} + +void d40_log_lli_write(struct d40_log_lli_full *lcpa, + struct d40_log_lli *lcla_src, + struct d40_log_lli *lcla_dst, + struct d40_log_lli *lli_dst, + struct d40_log_lli *lli_src, + int llis_per_log) +{ + u32 slos = 0; + u32 dlos = 0; + int i; + + lcpa->lcsp0 = lli_src->lcsp02; + lcpa->lcsp1 = lli_src->lcsp13; + lcpa->lcsp2 = lli_dst->lcsp02; + lcpa->lcsp3 = lli_dst->lcsp13; + + slos = lli_src->lcsp13 & D40_MEM_LCSP1_SLOS_MASK; + dlos = lli_dst->lcsp13 & D40_MEM_LCSP3_DLOS_MASK; + + for (i = 0; (i < llis_per_log) && slos && dlos; i++) { + writel(lli_src[i+1].lcsp02, &lcla_src[i].lcsp02); + writel(lli_src[i+1].lcsp13, &lcla_src[i].lcsp13); + writel(lli_dst[i+1].lcsp02, &lcla_dst[i].lcsp02); + writel(lli_dst[i+1].lcsp13, &lcla_dst[i].lcsp13); + + slos = lli_src[i+1].lcsp13 & D40_MEM_LCSP1_SLOS_MASK; + dlos = lli_dst[i+1].lcsp13 & D40_MEM_LCSP3_DLOS_MASK; + } +} diff --git a/drivers/dma/ste_dma40_ll.h b/drivers/dma/ste_dma40_ll.h new file mode 100644 index 000000000000..2029280cb332 --- /dev/null +++ b/drivers/dma/ste_dma40_ll.h @@ -0,0 +1,354 @@ +/* + * driver/dma/ste_dma40_ll.h + * + * Copyright (C) ST-Ericsson 2007-2010 + * License terms: GNU General Public License (GPL) version 2 + * Author: Per Friden + * Author: Jonas Aaberg + */ +#ifndef STE_DMA40_LL_H +#define STE_DMA40_LL_H + +#define D40_DREG_PCBASE 0x400 +#define D40_DREG_PCDELTA (8 * 4) +#define D40_LLI_ALIGN 16 /* LLI alignment must be 16 bytes. */ + +#define D40_TYPE_TO_GROUP(type) (type / 16) +#define D40_TYPE_TO_EVENT(type) (type % 16) + +/* Most bits of the CFG register are the same in log as in phy mode */ +#define D40_SREG_CFG_MST_POS 15 +#define D40_SREG_CFG_TIM_POS 14 +#define D40_SREG_CFG_EIM_POS 13 +#define D40_SREG_CFG_LOG_INCR_POS 12 +#define D40_SREG_CFG_PHY_PEN_POS 12 +#define D40_SREG_CFG_PSIZE_POS 10 +#define D40_SREG_CFG_ESIZE_POS 8 +#define D40_SREG_CFG_PRI_POS 7 +#define D40_SREG_CFG_LBE_POS 6 +#define D40_SREG_CFG_LOG_GIM_POS 5 +#define D40_SREG_CFG_LOG_MFU_POS 4 +#define D40_SREG_CFG_PHY_TM_POS 4 +#define D40_SREG_CFG_PHY_EVTL_POS 0 + + +/* Standard channel parameters - basic mode (element register) */ +#define D40_SREG_ELEM_PHY_ECNT_POS 16 +#define D40_SREG_ELEM_PHY_EIDX_POS 0 + +#define D40_SREG_ELEM_PHY_ECNT_MASK (0xFFFF << D40_SREG_ELEM_PHY_ECNT_POS) + +/* Standard channel parameters - basic mode (Link register) */ +#define D40_SREG_LNK_PHY_TCP_POS 0 +#define D40_SREG_LNK_PHY_LMP_POS 1 +#define D40_SREG_LNK_PHY_PRE_POS 2 +/* + * Source destination link address. Contains the + * 29-bit byte word aligned address of the reload area. + */ +#define D40_SREG_LNK_PHYS_LNK_MASK 0xFFFFFFF8UL + +/* Standard basic channel logical mode */ + +/* Element register */ +#define D40_SREG_ELEM_LOG_ECNT_POS 16 +#define D40_SREG_ELEM_LOG_LIDX_POS 8 +#define D40_SREG_ELEM_LOG_LOS_POS 1 +#define D40_SREG_ELEM_LOG_TCP_POS 0 + +#define D40_SREG_ELEM_LOG_LIDX_MASK (0xFF << D40_SREG_ELEM_LOG_LIDX_POS) + +/* Link register */ +#define D40_DEACTIVATE_EVENTLINE 0x0 +#define D40_ACTIVATE_EVENTLINE 0x1 +#define D40_EVENTLINE_POS(i) (2 * i) +#define D40_EVENTLINE_MASK(i) (0x3 << D40_EVENTLINE_POS(i)) + +/* Standard basic channel logical params in memory */ + +/* LCSP0 */ +#define D40_MEM_LCSP0_ECNT_POS 16 +#define D40_MEM_LCSP0_SPTR_POS 0 + +#define D40_MEM_LCSP0_ECNT_MASK (0xFFFF << D40_MEM_LCSP0_ECNT_POS) +#define D40_MEM_LCSP0_SPTR_MASK (0xFFFF << D40_MEM_LCSP0_SPTR_POS) + +/* LCSP1 */ +#define D40_MEM_LCSP1_SPTR_POS 16 +#define D40_MEM_LCSP1_SCFG_MST_POS 15 +#define D40_MEM_LCSP1_SCFG_TIM_POS 14 +#define D40_MEM_LCSP1_SCFG_EIM_POS 13 +#define D40_MEM_LCSP1_SCFG_INCR_POS 12 +#define D40_MEM_LCSP1_SCFG_PSIZE_POS 10 +#define D40_MEM_LCSP1_SCFG_ESIZE_POS 8 +#define D40_MEM_LCSP1_SLOS_POS 1 +#define D40_MEM_LCSP1_STCP_POS 0 + +#define D40_MEM_LCSP1_SPTR_MASK (0xFFFF << D40_MEM_LCSP1_SPTR_POS) +#define D40_MEM_LCSP1_SCFG_TIM_MASK (0x1 << D40_MEM_LCSP1_SCFG_TIM_POS) +#define D40_MEM_LCSP1_SCFG_INCR_MASK (0x1 << D40_MEM_LCSP1_SCFG_INCR_POS) +#define D40_MEM_LCSP1_SCFG_PSIZE_MASK (0x3 << D40_MEM_LCSP1_SCFG_PSIZE_POS) +#define D40_MEM_LCSP1_SLOS_MASK (0x7F << D40_MEM_LCSP1_SLOS_POS) +#define D40_MEM_LCSP1_STCP_MASK (0x1 << D40_MEM_LCSP1_STCP_POS) + +/* LCSP2 */ +#define D40_MEM_LCSP2_ECNT_POS 16 + +#define D40_MEM_LCSP2_ECNT_MASK (0xFFFF << D40_MEM_LCSP2_ECNT_POS) + +/* LCSP3 */ +#define D40_MEM_LCSP3_DCFG_MST_POS 15 +#define D40_MEM_LCSP3_DCFG_TIM_POS 14 +#define D40_MEM_LCSP3_DCFG_EIM_POS 13 +#define D40_MEM_LCSP3_DCFG_INCR_POS 12 +#define D40_MEM_LCSP3_DCFG_PSIZE_POS 10 +#define D40_MEM_LCSP3_DCFG_ESIZE_POS 8 +#define D40_MEM_LCSP3_DLOS_POS 1 +#define D40_MEM_LCSP3_DTCP_POS 0 + +#define D40_MEM_LCSP3_DLOS_MASK (0x7F << D40_MEM_LCSP3_DLOS_POS) +#define D40_MEM_LCSP3_DTCP_MASK (0x1 << D40_MEM_LCSP3_DTCP_POS) + + +/* Standard channel parameter register offsets */ +#define D40_CHAN_REG_SSCFG 0x00 +#define D40_CHAN_REG_SSELT 0x04 +#define D40_CHAN_REG_SSPTR 0x08 +#define D40_CHAN_REG_SSLNK 0x0C +#define D40_CHAN_REG_SDCFG 0x10 +#define D40_CHAN_REG_SDELT 0x14 +#define D40_CHAN_REG_SDPTR 0x18 +#define D40_CHAN_REG_SDLNK 0x1C + +/* DMA Register Offsets */ +#define D40_DREG_GCC 0x000 +#define D40_DREG_PRTYP 0x004 +#define D40_DREG_PRSME 0x008 +#define D40_DREG_PRSMO 0x00C +#define D40_DREG_PRMSE 0x010 +#define D40_DREG_PRMSO 0x014 +#define D40_DREG_PRMOE 0x018 +#define D40_DREG_PRMOO 0x01C +#define D40_DREG_LCPA 0x020 +#define D40_DREG_LCLA 0x024 +#define D40_DREG_ACTIVE 0x050 +#define D40_DREG_ACTIVO 0x054 +#define D40_DREG_FSEB1 0x058 +#define D40_DREG_FSEB2 0x05C +#define D40_DREG_PCMIS 0x060 +#define D40_DREG_PCICR 0x064 +#define D40_DREG_PCTIS 0x068 +#define D40_DREG_PCEIS 0x06C +#define D40_DREG_LCMIS0 0x080 +#define D40_DREG_LCMIS1 0x084 +#define D40_DREG_LCMIS2 0x088 +#define D40_DREG_LCMIS3 0x08C +#define D40_DREG_LCICR0 0x090 +#define D40_DREG_LCICR1 0x094 +#define D40_DREG_LCICR2 0x098 +#define D40_DREG_LCICR3 0x09C +#define D40_DREG_LCTIS0 0x0A0 +#define D40_DREG_LCTIS1 0x0A4 +#define D40_DREG_LCTIS2 0x0A8 +#define D40_DREG_LCTIS3 0x0AC +#define D40_DREG_LCEIS0 0x0B0 +#define D40_DREG_LCEIS1 0x0B4 +#define D40_DREG_LCEIS2 0x0B8 +#define D40_DREG_LCEIS3 0x0BC +#define D40_DREG_STFU 0xFC8 +#define D40_DREG_ICFG 0xFCC +#define D40_DREG_PERIPHID0 0xFE0 +#define D40_DREG_PERIPHID1 0xFE4 +#define D40_DREG_PERIPHID2 0xFE8 +#define D40_DREG_PERIPHID3 0xFEC +#define D40_DREG_CELLID0 0xFF0 +#define D40_DREG_CELLID1 0xFF4 +#define D40_DREG_CELLID2 0xFF8 +#define D40_DREG_CELLID3 0xFFC + +/* LLI related structures */ + +/** + * struct d40_phy_lli - The basic configration register for each physical + * channel. + * + * @reg_cfg: The configuration register. + * @reg_elt: The element register. + * @reg_ptr: The pointer register. + * @reg_lnk: The link register. + * + * These registers are set up for both physical and logical transfers + * Note that the bit in each register means differently in logical and + * physical(standard) mode. + * + * This struct must be 16 bytes aligned, and only contain physical registers + * since it will be directly accessed by the DMA. + */ +struct d40_phy_lli { + u32 reg_cfg; + u32 reg_elt; + u32 reg_ptr; + u32 reg_lnk; +}; + +/** + * struct d40_phy_lli_bidir - struct for a transfer. + * + * @src: Register settings for src channel. + * @dst: Register settings for dst channel. + * @dst_addr: Physical destination address. + * @src_addr: Physical source address. + * + * All DMA transfers have a source and a destination. + */ + +struct d40_phy_lli_bidir { + struct d40_phy_lli *src; + struct d40_phy_lli *dst; + dma_addr_t dst_addr; + dma_addr_t src_addr; +}; + + +/** + * struct d40_log_lli - logical lli configuration + * + * @lcsp02: Either maps to register lcsp0 if src or lcsp2 if dst. + * @lcsp13: Either maps to register lcsp1 if src or lcsp3 if dst. + * + * This struct must be 8 bytes aligned since it will be accessed directy by + * the DMA. Never add any none hw mapped registers to this struct. + */ + +struct d40_log_lli { + u32 lcsp02; + u32 lcsp13; +}; + +/** + * struct d40_log_lli_bidir - For both src and dst + * + * @src: pointer to src lli configuration. + * @dst: pointer to dst lli configuration. + * + * You always have a src and a dst when doing DMA transfers. + */ + +struct d40_log_lli_bidir { + struct d40_log_lli *src; + struct d40_log_lli *dst; +}; + +/** + * struct d40_log_lli_full - LCPA layout + * + * @lcsp0: Logical Channel Standard Param 0 - Src. + * @lcsp1: Logical Channel Standard Param 1 - Src. + * @lcsp2: Logical Channel Standard Param 2 - Dst. + * @lcsp3: Logical Channel Standard Param 3 - Dst. + * + * This struct maps to LCPA physical memory layout. Must map to + * the hw. + */ +struct d40_log_lli_full { + u32 lcsp0; + u32 lcsp1; + u32 lcsp2; + u32 lcsp3; +}; + +/** + * struct d40_def_lcsp - Default LCSP1 and LCSP3 settings + * + * @lcsp3: The default configuration for dst. + * @lcsp1: The default configuration for src. + */ +struct d40_def_lcsp { + u32 lcsp3; + u32 lcsp1; +}; + +/** + * struct d40_lcla_elem - Info for one LCA element. + * + * @src_id: logical channel src id + * @dst_id: logical channel dst id + * @src: LCPA formated src parameters + * @dst: LCPA formated dst parameters + * + */ +struct d40_lcla_elem { + int src_id; + int dst_id; + struct d40_log_lli *src; + struct d40_log_lli *dst; +}; + +/* Physical channels */ + +void d40_phy_cfg(struct stedma40_chan_cfg *cfg, + u32 *src_cfg, u32 *dst_cfg, bool is_log); + +void d40_log_cfg(struct stedma40_chan_cfg *cfg, + u32 *lcsp1, u32 *lcsp2); + +int d40_phy_sg_to_lli(struct scatterlist *sg, + int sg_len, + dma_addr_t target, + struct d40_phy_lli *lli, + dma_addr_t lli_phys, + u32 reg_cfg, + u32 data_width, + int psize, + bool term_int); + +int d40_phy_fill_lli(struct d40_phy_lli *lli, + dma_addr_t data, + u32 data_size, + int psize, + dma_addr_t next_lli, + u32 reg_cfg, + bool term_int, + u32 data_width, + bool is_device); + +void d40_phy_lli_write(void __iomem *virtbase, + u32 phy_chan_num, + struct d40_phy_lli *lli_dst, + struct d40_phy_lli *lli_src); + +/* Logical channels */ + +void d40_log_fill_lli(struct d40_log_lli *lli, + dma_addr_t data, u32 data_size, + u32 lli_next_off, u32 reg_cfg, + u32 data_width, + bool term_int, bool addr_inc); + +int d40_log_sg_to_dev(struct d40_lcla_elem *lcla, + struct scatterlist *sg, + int sg_len, + struct d40_log_lli_bidir *lli, + struct d40_def_lcsp *lcsp, + u32 src_data_width, + u32 dst_data_width, + enum dma_data_direction direction, + bool term_int, dma_addr_t dev_addr, int max_len, + int llis_per_log); + +void d40_log_lli_write(struct d40_log_lli_full *lcpa, + struct d40_log_lli *lcla_src, + struct d40_log_lli *lcla_dst, + struct d40_log_lli *lli_dst, + struct d40_log_lli *lli_src, + int llis_per_log); + +int d40_log_sg_to_lli(int lcla_id, + struct scatterlist *sg, + int sg_len, + struct d40_log_lli *lli_sg, + u32 lcsp13, /* src or dst*/ + u32 data_width, + bool term_int, int max_len, int llis_per_log); + +#endif /* STE_DMA40_LLI_H */ -- cgit v1.2.3 From ec1a123afdbe6a14ee93df03e2a829ad9884693e Mon Sep 17 00:00:00 2001 From: Yegor Yefremov Date: Thu, 15 Apr 2010 14:20:53 -0700 Subject: IDE: pass IRQ flags to the IDE core This enables shared IRQs and other features to be used with platform devices Signed-off-by: Yegor Yefremov Signed-off-by: David S. Miller --- drivers/ide/ide_platform.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/ide/ide_platform.c b/drivers/ide/ide_platform.c index 42965b3e30b9..542603b394e4 100644 --- a/drivers/ide/ide_platform.c +++ b/drivers/ide/ide_platform.c @@ -95,6 +95,7 @@ static int __devinit plat_ide_probe(struct platform_device *pdev) plat_ide_setup_ports(&hw, base, alt_base, pdata, res_irq->start); hw.dev = &pdev->dev; + d.irq_flags = res_irq->flags; if (mmio) d.host_flags |= IDE_HFLAG_MMIO; -- cgit v1.2.3 From a3bcbbee83f55cbaec9b2ad748e7300c7feb2192 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Mon, 12 Apr 2010 23:33:22 +0200 Subject: pda_power: Add function callbacks for suspend and resume Add function prototypes for power management events so they can be handled and used by platform implementations. Signed-off-by: Daniel Mack Cc: Dmitry Baryshkov Cc: David Woodhouse Signed-off-by: Anton Vorontsov --- drivers/power/pda_power.c | 10 ++++++++++ include/linux/pda_power.h | 2 ++ 2 files changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c index a232de6a5703..69f8aa3a6a4b 100644 --- a/drivers/power/pda_power.c +++ b/drivers/power/pda_power.c @@ -404,6 +404,13 @@ static int usb_wakeup_enabled; static int pda_power_suspend(struct platform_device *pdev, pm_message_t state) { + if (pdata->suspend) { + int ret = pdata->suspend(state); + + if (ret) + return ret; + } + if (device_may_wakeup(&pdev->dev)) { if (ac_irq) ac_wakeup_enabled = !enable_irq_wake(ac_irq->start); @@ -423,6 +430,9 @@ static int pda_power_resume(struct platform_device *pdev) disable_irq_wake(ac_irq->start); } + if (pdata->resume) + return pdata->resume(); + return 0; } #else diff --git a/include/linux/pda_power.h b/include/linux/pda_power.h index d4cf7a2ceb3e..c9e4d814ff77 100644 --- a/include/linux/pda_power.h +++ b/include/linux/pda_power.h @@ -24,6 +24,8 @@ struct pda_power_pdata { int (*is_usb_online)(void); void (*set_charge)(int flags); void (*exit)(struct device *dev); + int (*suspend)(pm_message_t state); + int (*resume)(void); char **supplied_to; size_t num_supplicants; -- cgit v1.2.3 From 99700716a9b2e117fd50c6d3f1fd5edeef6dc6d2 Mon Sep 17 00:00:00 2001 From: Chihau Chau Date: Mon, 19 Apr 2010 21:02:41 +0800 Subject: crypto: geode-aes - Fix some code style issues This fixes some code style issues like: - Use #include instead of and #include instead of - Use "foo *bar" instead of "foo * bar" - Add a space after the for or while sentence and before the open parenthesis '(' - Don't use assignments in a if condition Signed-off-by: Chihau Chau Signed-off-by: Herbert Xu --- drivers/crypto/geode-aes.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/geode-aes.c b/drivers/crypto/geode-aes.c index c7a5a43ba691..09389dd2f96b 100644 --- a/drivers/crypto/geode-aes.c +++ b/drivers/crypto/geode-aes.c @@ -15,14 +15,14 @@ #include #include -#include -#include +#include +#include #include "geode-aes.h" /* Static structures */ -static void __iomem * _iobase; +static void __iomem *_iobase; static spinlock_t lock; /* Write a 128 bit field (either a writable key or IV) */ @@ -30,7 +30,7 @@ static inline void _writefield(u32 offset, void *value) { int i; - for(i = 0; i < 4; i++) + for (i = 0; i < 4; i++) iowrite32(((u32 *) value)[i], _iobase + offset + (i * 4)); } @@ -39,7 +39,7 @@ static inline void _readfield(u32 offset, void *value) { int i; - for(i = 0; i < 4; i++) + for (i = 0; i < 4; i++) ((u32 *) value)[i] = ioread32(_iobase + offset + (i * 4)); } @@ -59,7 +59,7 @@ do_crypt(void *src, void *dst, int len, u32 flags) do { status = ioread32(_iobase + AES_INTR_REG); cpu_relax(); - } while(!(status & AES_INTRA_PENDING) && --counter); + } while (!(status & AES_INTRA_PENDING) && --counter); /* Clear the event */ iowrite32((status & 0xFF) | AES_INTRA_PENDING, _iobase + AES_INTR_REG); @@ -317,7 +317,7 @@ geode_cbc_decrypt(struct blkcipher_desc *desc, err = blkcipher_walk_virt(desc, &walk); op->iv = walk.iv; - while((nbytes = walk.nbytes)) { + while ((nbytes = walk.nbytes)) { op->src = walk.src.virt.addr, op->dst = walk.dst.virt.addr; op->mode = AES_MODE_CBC; @@ -349,7 +349,7 @@ geode_cbc_encrypt(struct blkcipher_desc *desc, err = blkcipher_walk_virt(desc, &walk); op->iv = walk.iv; - while((nbytes = walk.nbytes)) { + while ((nbytes = walk.nbytes)) { op->src = walk.src.virt.addr, op->dst = walk.dst.virt.addr; op->mode = AES_MODE_CBC; @@ -429,7 +429,7 @@ geode_ecb_decrypt(struct blkcipher_desc *desc, blkcipher_walk_init(&walk, dst, src, nbytes); err = blkcipher_walk_virt(desc, &walk); - while((nbytes = walk.nbytes)) { + while ((nbytes = walk.nbytes)) { op->src = walk.src.virt.addr, op->dst = walk.dst.virt.addr; op->mode = AES_MODE_ECB; @@ -459,7 +459,7 @@ geode_ecb_encrypt(struct blkcipher_desc *desc, blkcipher_walk_init(&walk, dst, src, nbytes); err = blkcipher_walk_virt(desc, &walk); - while((nbytes = walk.nbytes)) { + while ((nbytes = walk.nbytes)) { op->src = walk.src.virt.addr, op->dst = walk.dst.virt.addr; op->mode = AES_MODE_ECB; @@ -518,11 +518,12 @@ static int __devinit geode_aes_probe(struct pci_dev *dev, const struct pci_device_id *id) { int ret; - - if ((ret = pci_enable_device(dev))) + ret = pci_enable_device(dev); + if (ret) return ret; - if ((ret = pci_request_regions(dev, "geode-aes"))) + ret = pci_request_regions(dev, "geode-aes"); + if (ret) goto eenable; _iobase = pci_iomap(dev, 0, 0); @@ -537,13 +538,16 @@ geode_aes_probe(struct pci_dev *dev, const struct pci_device_id *id) /* Clear any pending activity */ iowrite32(AES_INTR_PENDING | AES_INTR_MASK, _iobase + AES_INTR_REG); - if ((ret = crypto_register_alg(&geode_alg))) + ret = crypto_register_alg(&geode_alg); + if (ret) goto eiomap; - if ((ret = crypto_register_alg(&geode_ecb_alg))) + ret = crypto_register_alg(&geode_ecb_alg); + if (ret) goto ealg; - if ((ret = crypto_register_alg(&geode_cbc_alg))) + ret = crypto_register_alg(&geode_cbc_alg); + if (ret) goto eecb; printk(KERN_NOTICE "geode-aes: GEODE AES engine enabled.\n"); -- cgit v1.2.3 From edd5bdaf128e04066caac84fcb21377197ea0d64 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Wed, 14 Apr 2010 22:30:18 +0200 Subject: firewire: core: clean up config ROM related defined constants Clemens Ladisch pointed out that - BIB_IMC is not named like the field is called in the standard, - readers of the code may get worried about the magic 0x0c0083c0, - a CSR_NODE_CAPABILITIES key is there in the header but not put to good use. So let's rename BIB_IMC, add a defined constant for Node_Capabilities and a comment which reassures people that somebody thought about it and they don't have to (or if they still do, tell them where they have to look for confirmation), and prune our incomplete and arbitrary set of defined constants of CSR key IDs. And there is a nother magic number, that of Bus_Information_Block.Bus_Name, to be defined and commented. Signed-off-by: Stefan Richter --- drivers/firewire/core-card.c | 11 ++++++----- include/linux/firewire.h | 2 -- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index 5045156c5313..42cf911b73cf 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c @@ -63,7 +63,7 @@ static size_t config_rom_length = 1 + 4 + 1 + 1; #define BIB_CRC(v) ((v) << 0) #define BIB_CRC_LENGTH(v) ((v) << 16) #define BIB_INFO_LENGTH(v) ((v) << 24) - +#define BIB_BUS_NAME 0x31333934 /* "1394" */ #define BIB_LINK_SPEED(v) ((v) << 0) #define BIB_GENERATION(v) ((v) << 4) #define BIB_MAX_ROM(v) ((v) << 8) @@ -73,7 +73,8 @@ static size_t config_rom_length = 1 + 4 + 1 + 1; #define BIB_BMC ((1) << 28) #define BIB_ISC ((1) << 29) #define BIB_CMC ((1) << 30) -#define BIB_IMC ((1) << 31) +#define BIB_IRMC ((1) << 31) +#define NODE_CAPABILITIES 0x0c0083c0 /* per IEEE 1394 clause 8.3.2.6.5.2 */ static void generate_config_rom(struct fw_card *card, __be32 *config_rom) { @@ -91,18 +92,18 @@ static void generate_config_rom(struct fw_card *card, __be32 *config_rom) config_rom[0] = cpu_to_be32( BIB_CRC_LENGTH(4) | BIB_INFO_LENGTH(4) | BIB_CRC(0)); - config_rom[1] = cpu_to_be32(0x31333934); + config_rom[1] = cpu_to_be32(BIB_BUS_NAME); config_rom[2] = cpu_to_be32( BIB_LINK_SPEED(card->link_speed) | BIB_GENERATION(card->config_rom_generation++ % 14 + 2) | BIB_MAX_ROM(2) | BIB_MAX_RECEIVE(card->max_receive) | - BIB_BMC | BIB_ISC | BIB_CMC | BIB_IMC); + BIB_BMC | BIB_ISC | BIB_CMC | BIB_IRMC); config_rom[3] = cpu_to_be32(card->guid >> 32); config_rom[4] = cpu_to_be32(card->guid); /* Generate root directory. */ - config_rom[6] = cpu_to_be32(0x0c0083c0); /* node capabilities */ + config_rom[6] = cpu_to_be32(NODE_CAPABILITIES); i = 7; j = 7 + descriptor_count; diff --git a/include/linux/firewire.h b/include/linux/firewire.h index 4bd94bf5e739..a527d73f9966 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -55,13 +55,11 @@ #define CSR_DESCRIPTOR 0x01 #define CSR_VENDOR 0x03 #define CSR_HARDWARE_VERSION 0x04 -#define CSR_NODE_CAPABILITIES 0x0c #define CSR_UNIT 0x11 #define CSR_SPECIFIER_ID 0x12 #define CSR_VERSION 0x13 #define CSR_DEPENDENT_INFO 0x14 #define CSR_MODEL 0x17 -#define CSR_INSTANCE 0x18 #define CSR_DIRECTORY_ID 0x20 struct fw_csr_iterator { -- cgit v1.2.3 From 7906054f0d597246178b3154adca76de29913aa5 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 19 Apr 2010 17:29:14 +0200 Subject: firewire: core: make transaction label allocation more robust If one request is so long-lived that it does not get a response before the following 63 requests, its bit in tlabel_mask is still set when the next request tries to allocate a transaction label for that number. In this state, while the first request is not completed or timed out, no new requests can be submitted. To fix this, skip over any label still in use, and do not error out unless we have entirely run out of labels. Signed-off-by: Clemens Ladisch Signed-off-by: Stefan Richter --- drivers/firewire/core-transaction.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index 673b03f8b4ec..9882240205cd 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c @@ -229,6 +229,23 @@ static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel, packet->payload_mapped = false; } +static int allocate_tlabel(struct fw_card *card) +{ + int tlabel; + + tlabel = card->current_tlabel; + while (card->tlabel_mask & (1ULL << tlabel)) { + tlabel = (tlabel + 1) & 0x3f; + if (tlabel == card->current_tlabel) + return -EBUSY; + } + + card->current_tlabel = (tlabel + 1) & 0x3f; + card->tlabel_mask |= 1ULL << tlabel; + + return tlabel; +} + /** * This function provides low-level access to the IEEE1394 transaction * logic. Most C programs would use either fw_read(), fw_write() or @@ -290,16 +307,13 @@ void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode, spin_lock_irqsave(&card->lock, flags); - tlabel = card->current_tlabel; - if (card->tlabel_mask & (1ULL << tlabel)) { + tlabel = allocate_tlabel(card); + if (tlabel < 0) { spin_unlock_irqrestore(&card->lock, flags); callback(card, RCODE_SEND_ERROR, NULL, 0, callback_data); return; } - card->current_tlabel = (card->current_tlabel + 1) & 0x3f; - card->tlabel_mask |= (1ULL << tlabel); - t->node_id = destination_id; t->tlabel = tlabel; t->callback = callback; -- cgit v1.2.3 From e92a716240258989f19c7345e8b135e6d214431a Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 12 Jan 2010 14:17:03 -0500 Subject: ACPI: Export EDID blocks to the kernel The ACPI spec includes a provision for hardware to provide EDID via the ACPI video extension. In the KMS world it's necessary for a way to obtain this from within the kernel. Add a function that either returns the EDID for the provided ACPI display ID or the first display of the provided type. Also add support for ensuring that devices with legacy IDs are supported. Signed-off-by: Matthew Garrett Acked-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/video.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++---- include/acpi/video.h | 16 ++++++++ 2 files changed, 118 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index a0c93b321482..4b8bda1154db 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -45,6 +45,7 @@ #include #include #include +#include #define PREFIX "ACPI: " @@ -65,11 +66,6 @@ #define MAX_NAME_LEN 20 -#define ACPI_VIDEO_DISPLAY_CRT 1 -#define ACPI_VIDEO_DISPLAY_TV 2 -#define ACPI_VIDEO_DISPLAY_DVI 3 -#define ACPI_VIDEO_DISPLAY_LCD 4 - #define _COMPONENT ACPI_VIDEO_COMPONENT ACPI_MODULE_NAME("video"); @@ -1747,12 +1743,28 @@ acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id return NULL; } +static int +acpi_video_get_device_type(struct acpi_video_bus *video, + unsigned long device_id) +{ + struct acpi_video_enumerated_device *ids; + int i; + + for (i = 0; i < video->attached_count; i++) { + ids = &video->attached_array[i]; + if ((ids->value.int_val & 0xffff) == device_id) + return ids->value.int_val; + } + + return 0; +} + static int acpi_video_bus_get_one_device(struct acpi_device *device, struct acpi_video_bus *video) { unsigned long long device_id; - int status; + int status, device_type; struct acpi_video_device *data; struct acpi_video_device_attrib* attribute; @@ -1797,8 +1809,25 @@ acpi_video_bus_get_one_device(struct acpi_device *device, } if(attribute->bios_can_detect) data->flags.bios = 1; - } else - data->flags.unknown = 1; + } else { + /* Check for legacy IDs */ + device_type = acpi_video_get_device_type(video, + device_id); + /* Ignore bits 16 and 18-20 */ + switch (device_type & 0xffe2ffff) { + case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR: + data->flags.crt = 1; + break; + case ACPI_VIDEO_DISPLAY_LEGACY_PANEL: + data->flags.lcd = 1; + break; + case ACPI_VIDEO_DISPLAY_LEGACY_TV: + data->flags.tvout = 1; + break; + default: + data->flags.unknown = 1; + } + } acpi_video_device_bind(video, data); acpi_video_device_find_cap(data); @@ -2032,6 +2061,71 @@ out: return result; } +int acpi_video_get_edid(struct acpi_device *device, int type, int device_id, + void **edid) +{ + struct acpi_video_bus *video; + struct acpi_video_device *video_device; + union acpi_object *buffer = NULL; + acpi_status status; + int i, length; + + if (!device || !acpi_driver_data(device)) + return -EINVAL; + + video = acpi_driver_data(device); + + for (i = 0; i < video->attached_count; i++) { + video_device = video->attached_array[i].bind_info; + length = 256; + + if (!video_device) + continue; + + if (type) { + switch (type) { + case ACPI_VIDEO_DISPLAY_CRT: + if (!video_device->flags.crt) + continue; + break; + case ACPI_VIDEO_DISPLAY_TV: + if (!video_device->flags.tvout) + continue; + break; + case ACPI_VIDEO_DISPLAY_DVI: + if (!video_device->flags.dvi) + continue; + break; + case ACPI_VIDEO_DISPLAY_LCD: + if (!video_device->flags.lcd) + continue; + break; + } + } else if (video_device->device_id != device_id) { + continue; + } + + status = acpi_video_device_EDID(video_device, &buffer, length); + + if (ACPI_FAILURE(status) || !buffer || + buffer->type != ACPI_TYPE_BUFFER) { + length = 128; + status = acpi_video_device_EDID(video_device, &buffer, + length); + if (ACPI_FAILURE(status) || !buffer || + buffer->type != ACPI_TYPE_BUFFER) { + continue; + } + } + + *edid = buffer->buffer.pointer; + return length; + } + + return -ENODEV; +} +EXPORT_SYMBOL(acpi_video_get_edid); + static int acpi_video_bus_get_devices(struct acpi_video_bus *video, struct acpi_device *device) diff --git a/include/acpi/video.h b/include/acpi/video.h index cf7be3dd157b..551793c9b6e8 100644 --- a/include/acpi/video.h +++ b/include/acpi/video.h @@ -1,12 +1,28 @@ #ifndef __ACPI_VIDEO_H #define __ACPI_VIDEO_H +#define ACPI_VIDEO_DISPLAY_CRT 1 +#define ACPI_VIDEO_DISPLAY_TV 2 +#define ACPI_VIDEO_DISPLAY_DVI 3 +#define ACPI_VIDEO_DISPLAY_LCD 4 + +#define ACPI_VIDEO_DISPLAY_LEGACY_MONITOR 0x0100 +#define ACPI_VIDEO_DISPLAY_LEGACY_PANEL 0x0110 +#define ACPI_VIDEO_DISPLAY_LEGACY_TV 0x0200 + #if (defined CONFIG_ACPI_VIDEO || defined CONFIG_ACPI_VIDEO_MODULE) extern int acpi_video_register(void); extern void acpi_video_unregister(void); +extern int acpi_video_get_edid(struct acpi_device *device, int type, + int device_id, void **edid); #else static inline int acpi_video_register(void) { return 0; } static inline void acpi_video_unregister(void) { return; } +static inline int acpi_video_get_edid(struct acpi_device *device, int type, + int device_id, void **edid) +{ + return -ENODEV; +} #endif #endif -- cgit v1.2.3 From a63445a31a76474dd3f9e852e8bf08f81ee7437a Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Thu, 22 Apr 2010 14:00:18 -0700 Subject: drivers: video: msm: default to no It doesn't cure cancer .. Signed-off-by: Daniel Walker --- drivers/video/Kconfig | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 6e16244f3ed1..87f36efe46f3 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -2186,7 +2186,6 @@ config FB_MSM select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - default y config FB_MX3 tristate "MX3 Framebuffer support" -- cgit v1.2.3 From 63e7cf910542383591318941cb62a246ac191cfe Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Wed, 14 Apr 2010 05:50:26 +0000 Subject: pdc202xx_old: wire test_irq() method for PDC2026x In the commit e0321fbe6d34b4bb514fb6daff9e0859e5d76001 (pdc202xx_old: implement test_irq() method (take 2)) I forgot to modify 'pdc2026x_port_ops'... :-/ Signed-off-by: Sergei Shtylyov Signed-off-by: David S. Miller --- drivers/ide/pdc202xx_old.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/ide/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c index c5f3841af360..42ad794dfaae 100644 --- a/drivers/ide/pdc202xx_old.c +++ b/drivers/ide/pdc202xx_old.c @@ -241,6 +241,7 @@ static const struct ide_port_ops pdc20246_port_ops = { static const struct ide_port_ops pdc2026x_port_ops = { .set_pio_mode = pdc202xx_set_pio_mode, .set_dma_mode = pdc202xx_set_mode, + .test_irq = pdc202xx_test_irq, .cable_detect = pdc2026x_cable_detect, }; -- cgit v1.2.3 From f693be4d8a00431b53a59d74aefdb3f7ae92f662 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Wed, 14 Apr 2010 05:52:59 +0000 Subject: pdc202xx_old: ignore "FIFO empty" bit in test_irq() method The driver takes into account not only the interrupt status bit but also "FIFO empty" bit in its test_irq() method. This actually is a superfluous check since for the DMA commands calling the dma_test_irq() method further in the interrupt handler makes sure FIFO is emptied. Signed-off-by: Sergei Shtylyov Signed-off-by: David S. Miller --- drivers/ide/pdc202xx_old.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c index 42ad794dfaae..3a35ec6193d2 100644 --- a/drivers/ide/pdc202xx_old.c +++ b/drivers/ide/pdc202xx_old.c @@ -93,13 +93,13 @@ static int pdc202xx_test_irq(ide_hwif_t *hwif) * bit 7: error, bit 6: interrupting, * bit 5: FIFO full, bit 4: FIFO empty */ - return ((sc1d & 0x50) == 0x50) ? 1 : 0; + return (sc1d & 0x40) ? 1 : 0; } else { /* * bit 3: error, bit 2: interrupting, * bit 1: FIFO full, bit 0: FIFO empty */ - return ((sc1d & 0x05) == 0x05) ? 1 : 0; + return (sc1d & 0x04) ? 1 : 0; } } -- cgit v1.2.3 From 9b9ade6b612e562c4a5bd02ef38cc32e10f3f9ba Mon Sep 17 00:00:00 2001 From: Yulia Vilensky Date: Mon, 26 Apr 2010 14:05:25 +0300 Subject: ds2782_battery: Add support for ds2786 battery gas gauge Signed-off-by: Yulia Vilensky Signed-off-by: Mike Rapoport Signed-off-by: Anton Vorontsov --- drivers/power/Kconfig | 4 +- drivers/power/ds2782_battery.c | 184 ++++++++++++++++++++++++++++++----------- include/linux/ds2782_battery.h | 8 ++ 3 files changed, 146 insertions(+), 50 deletions(-) create mode 100644 include/linux/ds2782_battery.h (limited to 'drivers') diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 22f2fa912127..c59bcb7c6eb0 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -65,10 +65,10 @@ config BATTERY_DS2760 Say Y here to enable support for batteries with ds2760 chip. config BATTERY_DS2782 - tristate "DS2782 standalone gas-gauge" + tristate "DS2782/DS2786 standalone gas-gauge" depends on I2C help - Say Y here to enable support for the DS2782 standalone battery + Say Y here to enable support for the DS2782/DS2786 standalone battery gas-gauge. config BATTERY_PMU diff --git a/drivers/power/ds2782_battery.c b/drivers/power/ds2782_battery.c index ba1bd1a545be..c665e8007235 100644 --- a/drivers/power/ds2782_battery.c +++ b/drivers/power/ds2782_battery.c @@ -5,6 +5,8 @@ * * Author: Ryan Mallon * + * DS2786 added by Yulia Vilensky + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. @@ -20,12 +22,13 @@ #include #include #include +#include #define DS2782_REG_RARC 0x06 /* Remaining active relative capacity */ -#define DS2782_REG_VOLT_MSB 0x0c -#define DS2782_REG_TEMP_MSB 0x0a -#define DS2782_REG_CURRENT_MSB 0x0e +#define DS278x_REG_VOLT_MSB 0x0c +#define DS278x_REG_TEMP_MSB 0x0a +#define DS278x_REG_CURRENT_MSB 0x0e /* EEPROM Block */ #define DS2782_REG_RSNSP 0x69 /* Sense resistor value */ @@ -33,18 +36,33 @@ /* Current unit measurement in uA for a 1 milli-ohm sense resistor */ #define DS2782_CURRENT_UNITS 1563 -#define to_ds2782_info(x) container_of(x, struct ds2782_info, battery) +#define DS2786_REG_RARC 0x02 /* Remaining active relative capacity */ + +#define DS2786_CURRENT_UNITS 25 + +struct ds278x_info; + +struct ds278x_battery_ops { + int (*get_current)(struct ds278x_info *info, int *current_uA); + int (*get_voltage)(struct ds278x_info *info, int *voltage_uA); + int (*get_capacity)(struct ds278x_info *info, int *capacity_uA); + +}; + +#define to_ds278x_info(x) container_of(x, struct ds278x_info, battery) -struct ds2782_info { +struct ds278x_info { struct i2c_client *client; struct power_supply battery; + struct ds278x_battery_ops *ops; int id; + int rsns; }; static DEFINE_IDR(battery_id); static DEFINE_MUTEX(battery_lock); -static inline int ds2782_read_reg(struct ds2782_info *info, int reg, u8 *val) +static inline int ds278x_read_reg(struct ds278x_info *info, int reg, u8 *val) { int ret; @@ -58,7 +76,7 @@ static inline int ds2782_read_reg(struct ds2782_info *info, int reg, u8 *val) return 0; } -static inline int ds2782_read_reg16(struct ds2782_info *info, int reg_msb, +static inline int ds278x_read_reg16(struct ds278x_info *info, int reg_msb, s16 *val) { int ret; @@ -73,7 +91,7 @@ static inline int ds2782_read_reg16(struct ds2782_info *info, int reg_msb, return 0; } -static int ds2782_get_temp(struct ds2782_info *info, int *temp) +static int ds278x_get_temp(struct ds278x_info *info, int *temp) { s16 raw; int err; @@ -84,14 +102,14 @@ static int ds2782_get_temp(struct ds2782_info *info, int *temp) * celsius. The temperature value is stored as a 10 bit number, plus * sign in the upper bits of a 16 bit register. */ - err = ds2782_read_reg16(info, DS2782_REG_TEMP_MSB, &raw); + err = ds278x_read_reg16(info, DS278x_REG_TEMP_MSB, &raw); if (err) return err; *temp = ((raw / 32) * 125) / 100; return 0; } -static int ds2782_get_current(struct ds2782_info *info, int *current_uA) +static int ds2782_get_current(struct ds278x_info *info, int *current_uA) { int sense_res; int err; @@ -102,7 +120,7 @@ static int ds2782_get_current(struct ds2782_info *info, int *current_uA) * The units of measurement for current are dependent on the value of * the sense resistor. */ - err = ds2782_read_reg(info, DS2782_REG_RSNSP, &sense_res_raw); + err = ds278x_read_reg(info, DS2782_REG_RSNSP, &sense_res_raw); if (err) return err; if (sense_res_raw == 0) { @@ -113,14 +131,14 @@ static int ds2782_get_current(struct ds2782_info *info, int *current_uA) dev_dbg(&info->client->dev, "sense resistor = %d milli-ohms\n", sense_res); - err = ds2782_read_reg16(info, DS2782_REG_CURRENT_MSB, &raw); + err = ds278x_read_reg16(info, DS278x_REG_CURRENT_MSB, &raw); if (err) return err; *current_uA = raw * (DS2782_CURRENT_UNITS / sense_res); return 0; } -static int ds2782_get_voltage(struct ds2782_info *info, int *voltage_uA) +static int ds2782_get_voltage(struct ds278x_info *info, int *voltage_uA) { s16 raw; int err; @@ -129,36 +147,77 @@ static int ds2782_get_voltage(struct ds2782_info *info, int *voltage_uA) * Voltage is measured in units of 4.88mV. The voltage is stored as * a 10-bit number plus sign, in the upper bits of a 16-bit register */ - err = ds2782_read_reg16(info, DS2782_REG_VOLT_MSB, &raw); + err = ds278x_read_reg16(info, DS278x_REG_VOLT_MSB, &raw); if (err) return err; *voltage_uA = (raw / 32) * 4800; return 0; } -static int ds2782_get_capacity(struct ds2782_info *info, int *capacity) +static int ds2782_get_capacity(struct ds278x_info *info, int *capacity) { int err; u8 raw; - err = ds2782_read_reg(info, DS2782_REG_RARC, &raw); + err = ds278x_read_reg(info, DS2782_REG_RARC, &raw); if (err) return err; *capacity = raw; return raw; } -static int ds2782_get_status(struct ds2782_info *info, int *status) +static int ds2786_get_current(struct ds278x_info *info, int *current_uA) +{ + int err; + s16 raw; + + err = ds278x_read_reg16(info, DS278x_REG_CURRENT_MSB, &raw); + if (err) + return err; + *current_uA = (raw / 16) * (DS2786_CURRENT_UNITS / info->rsns); + return 0; +} + +static int ds2786_get_voltage(struct ds278x_info *info, int *voltage_uA) +{ + s16 raw; + int err; + + /* + * Voltage is measured in units of 1.22mV. The voltage is stored as + * a 10-bit number plus sign, in the upper bits of a 16-bit register + */ + err = ds278x_read_reg16(info, DS278x_REG_VOLT_MSB, &raw); + if (err) + return err; + *voltage_uA = (raw / 8) * 1220; + return 0; +} + +static int ds2786_get_capacity(struct ds278x_info *info, int *capacity) +{ + int err; + u8 raw; + + err = ds278x_read_reg(info, DS2786_REG_RARC, &raw); + if (err) + return err; + /* Relative capacity is displayed with resolution 0.5 % */ + *capacity = raw/2 ; + return 0; +} + +static int ds278x_get_status(struct ds278x_info *info, int *status) { int err; int current_uA; int capacity; - err = ds2782_get_current(info, ¤t_uA); + err = info->ops->get_current(info, ¤t_uA); if (err) return err; - err = ds2782_get_capacity(info, &capacity); + err = info->ops->get_capacity(info, &capacity); if (err) return err; @@ -174,32 +233,32 @@ static int ds2782_get_status(struct ds2782_info *info, int *status) return 0; } -static int ds2782_battery_get_property(struct power_supply *psy, +static int ds278x_battery_get_property(struct power_supply *psy, enum power_supply_property prop, union power_supply_propval *val) { - struct ds2782_info *info = to_ds2782_info(psy); + struct ds278x_info *info = to_ds278x_info(psy); int ret; switch (prop) { case POWER_SUPPLY_PROP_STATUS: - ret = ds2782_get_status(info, &val->intval); + ret = ds278x_get_status(info, &val->intval); break; case POWER_SUPPLY_PROP_CAPACITY: - ret = ds2782_get_capacity(info, &val->intval); + ret = info->ops->get_capacity(info, &val->intval); break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: - ret = ds2782_get_voltage(info, &val->intval); + ret = info->ops->get_voltage(info, &val->intval); break; case POWER_SUPPLY_PROP_CURRENT_NOW: - ret = ds2782_get_current(info, &val->intval); + ret = info->ops->get_current(info, &val->intval); break; case POWER_SUPPLY_PROP_TEMP: - ret = ds2782_get_temp(info, &val->intval); + ret = ds278x_get_temp(info, &val->intval); break; default: @@ -209,7 +268,7 @@ static int ds2782_battery_get_property(struct power_supply *psy, return ret; } -static enum power_supply_property ds2782_battery_props[] = { +static enum power_supply_property ds278x_battery_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_VOLTAGE_NOW, @@ -217,18 +276,18 @@ static enum power_supply_property ds2782_battery_props[] = { POWER_SUPPLY_PROP_TEMP, }; -static void ds2782_power_supply_init(struct power_supply *battery) +static void ds278x_power_supply_init(struct power_supply *battery) { battery->type = POWER_SUPPLY_TYPE_BATTERY; - battery->properties = ds2782_battery_props; - battery->num_properties = ARRAY_SIZE(ds2782_battery_props); - battery->get_property = ds2782_battery_get_property; + battery->properties = ds278x_battery_props; + battery->num_properties = ARRAY_SIZE(ds278x_battery_props); + battery->get_property = ds278x_battery_get_property; battery->external_power_changed = NULL; } -static int ds2782_battery_remove(struct i2c_client *client) +static int ds278x_battery_remove(struct i2c_client *client) { - struct ds2782_info *info = i2c_get_clientdata(client); + struct ds278x_info *info = i2c_get_clientdata(client); power_supply_unregister(&info->battery); kfree(info->battery.name); @@ -241,13 +300,36 @@ static int ds2782_battery_remove(struct i2c_client *client) return 0; } -static int ds2782_battery_probe(struct i2c_client *client, +static struct ds278x_battery_ops ds278x_ops[] = { + [0] = { + .get_current = ds2782_get_current, + .get_voltage = ds2782_get_voltage, + .get_capacity = ds2782_get_capacity, + }, + [1] = { + .get_current = ds2786_get_current, + .get_voltage = ds2786_get_voltage, + .get_capacity = ds2786_get_capacity, + } +}; + +static int ds278x_battery_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct ds2782_info *info; + struct ds278x_platform_data *pdata = client->dev.platform_data; + struct ds278x_info *info; int ret; int num; + /* + * ds2786 should have the sense resistor value set + * in the platform data + */ + if (id->driver_data == 1 && !pdata) { + dev_err(&client->dev, "missing platform data for ds2786\n"); + return -EINVAL; + } + /* Get an ID for this battery */ ret = idr_pre_get(&battery_id, GFP_KERNEL); if (ret == 0) { @@ -267,15 +349,20 @@ static int ds2782_battery_probe(struct i2c_client *client, goto fail_info; } - info->battery.name = kasprintf(GFP_KERNEL, "ds2782-%d", num); + info->battery.name = kasprintf(GFP_KERNEL, "%s-%d", client->name, num); if (!info->battery.name) { ret = -ENOMEM; goto fail_name; } + if (id->driver_data == 1) + info->rsns = pdata->rsns; + i2c_set_clientdata(client, info); info->client = client; - ds2782_power_supply_init(&info->battery); + info->id = num; + info->ops = &ds278x_ops[id->driver_data]; + ds278x_power_supply_init(&info->battery); ret = power_supply_register(&client->dev, &info->battery); if (ret) { @@ -297,31 +384,32 @@ fail_id: return ret; } -static const struct i2c_device_id ds2782_id[] = { +static const struct i2c_device_id ds278x_id[] = { {"ds2782", 0}, + {"ds2786", 1}, {}, }; -static struct i2c_driver ds2782_battery_driver = { +static struct i2c_driver ds278x_battery_driver = { .driver = { .name = "ds2782-battery", }, - .probe = ds2782_battery_probe, - .remove = ds2782_battery_remove, - .id_table = ds2782_id, + .probe = ds278x_battery_probe, + .remove = ds278x_battery_remove, + .id_table = ds278x_id, }; -static int __init ds2782_init(void) +static int __init ds278x_init(void) { - return i2c_add_driver(&ds2782_battery_driver); + return i2c_add_driver(&ds278x_battery_driver); } -module_init(ds2782_init); +module_init(ds278x_init); -static void __exit ds2782_exit(void) +static void __exit ds278x_exit(void) { - i2c_del_driver(&ds2782_battery_driver); + i2c_del_driver(&ds278x_battery_driver); } -module_exit(ds2782_exit); +module_exit(ds278x_exit); MODULE_AUTHOR("Ryan Mallon "); MODULE_DESCRIPTION("Maxim/Dallas DS2782 Stand-Alone Fuel Gauage IC driver"); diff --git a/include/linux/ds2782_battery.h b/include/linux/ds2782_battery.h new file mode 100644 index 000000000000..b4e281f65c15 --- /dev/null +++ b/include/linux/ds2782_battery.h @@ -0,0 +1,8 @@ +#ifndef __LINUX_DS2782_BATTERY_H +#define __LINUX_DS2782_BATTERY_H + +struct ds278x_platform_data { + int rsns; +}; + +#endif -- cgit v1.2.3 From fbd9b09a177a481eda256447c881f014f29034fe Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Wed, 28 Apr 2010 17:55:06 +0400 Subject: blkdev: generalize flags for blkdev_issue_fn functions The patch just convert all blkdev_issue_xxx function to common set of flags. Wait/allocation semantics preserved. Signed-off-by: Dmitry Monakhov Signed-off-by: Jens Axboe --- block/blk-barrier.c | 20 +++++++++++--------- block/ioctl.c | 2 +- drivers/block/drbd/drbd_int.h | 3 ++- drivers/block/drbd/drbd_receiver.c | 3 ++- fs/block_dev.c | 3 ++- fs/btrfs/extent-tree.c | 2 +- fs/ext3/fsync.c | 3 ++- fs/ext4/fsync.c | 6 ++++-- fs/gfs2/rgrp.c | 5 +++-- fs/jbd2/checkpoint.c | 3 ++- fs/jbd2/commit.c | 6 ++++-- fs/reiserfs/file.c | 3 ++- fs/xfs/linux-2.6/xfs_super.c | 3 ++- include/linux/blkdev.h | 18 +++++++++++------- mm/swapfile.c | 9 ++++++--- 15 files changed, 55 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/block/blk-barrier.c b/block/blk-barrier.c index 6d88544b677f..cf14311b98fc 100644 --- a/block/blk-barrier.c +++ b/block/blk-barrier.c @@ -293,19 +293,22 @@ static void bio_end_empty_barrier(struct bio *bio, int err) /** * blkdev_issue_flush - queue a flush * @bdev: blockdev to issue flush for + * @gfp_mask: memory allocation flags (for bio_alloc) * @error_sector: error sector + * @flags: BLKDEV_IFL_* flags to control behaviour * * Description: * Issue a flush for the block device in question. Caller can supply * room for storing the error offset in case of a flush error, if they * wish to. */ -int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector) +int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask, + sector_t *error_sector, unsigned long flags) { DECLARE_COMPLETION_ONSTACK(wait); struct request_queue *q; struct bio *bio; - int ret; + int ret = 0; if (bdev->bd_disk == NULL) return -ENXIO; @@ -314,7 +317,7 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector) if (!q) return -ENXIO; - bio = bio_alloc(GFP_KERNEL, 0); + bio = bio_alloc(gfp_mask, 0); bio->bi_end_io = bio_end_empty_barrier; bio->bi_private = &wait; bio->bi_bdev = bdev; @@ -330,7 +333,6 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector) if (error_sector) *error_sector = bio->bi_sector; - ret = 0; if (bio_flagged(bio, BIO_EOPNOTSUPP)) ret = -EOPNOTSUPP; else if (!bio_flagged(bio, BIO_UPTODATE)) @@ -362,17 +364,17 @@ static void blkdev_discard_end_io(struct bio *bio, int err) * @sector: start sector * @nr_sects: number of sectors to discard * @gfp_mask: memory allocation flags (for bio_alloc) - * @flags: DISCARD_FL_* flags to control behaviour + * @flags: BLKDEV_IFL_* flags to control behaviour * * Description: * Issue a discard request for the sectors in question. */ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, - sector_t nr_sects, gfp_t gfp_mask, int flags) + sector_t nr_sects, gfp_t gfp_mask, unsigned long flags) { DECLARE_COMPLETION_ONSTACK(wait); struct request_queue *q = bdev_get_queue(bdev); - int type = flags & DISCARD_FL_BARRIER ? + int type = flags & BLKDEV_IFL_BARRIER ? DISCARD_BARRIER : DISCARD_NOBARRIER; struct bio *bio; struct page *page; @@ -395,7 +397,7 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, bio->bi_sector = sector; bio->bi_end_io = blkdev_discard_end_io; bio->bi_bdev = bdev; - if (flags & DISCARD_FL_WAIT) + if (flags & BLKDEV_IFL_WAIT) bio->bi_private = &wait; /* @@ -426,7 +428,7 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, bio_get(bio); submit_bio(type, bio); - if (flags & DISCARD_FL_WAIT) + if (flags & BLKDEV_IFL_WAIT) wait_for_completion(&wait); if (bio_flagged(bio, BIO_EOPNOTSUPP)) diff --git a/block/ioctl.c b/block/ioctl.c index 8905d2a2a717..e8eb679f2f9b 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -126,7 +126,7 @@ static int blk_ioctl_discard(struct block_device *bdev, uint64_t start, if (start + len > (bdev->bd_inode->i_size >> 9)) return -EINVAL; return blkdev_issue_discard(bdev, start, len, GFP_KERNEL, - DISCARD_FL_WAIT); + BLKDEV_IFL_WAIT); } static int put_ushort(unsigned long arg, unsigned short val) diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index e5e86a781820..d6f1ae342b1d 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -2251,7 +2251,8 @@ static inline void drbd_md_flush(struct drbd_conf *mdev) if (test_bit(MD_NO_BARRIER, &mdev->flags)) return; - r = blkdev_issue_flush(mdev->ldev->md_bdev, NULL); + r = blkdev_issue_flush(mdev->ldev->md_bdev, GFP_KERNEL, NULL, + BLKDEV_IFL_WAIT); if (r) { set_bit(MD_NO_BARRIER, &mdev->flags); dev_err(DEV, "meta data flush failed with status %d, disabling md-flushes\n", r); diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index ed9f1de24a71..54f56ea8a786 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -945,7 +945,8 @@ static enum finish_epoch drbd_flush_after_epoch(struct drbd_conf *mdev, struct d int rv; if (mdev->write_ordering >= WO_bdev_flush && get_ldev(mdev)) { - rv = blkdev_issue_flush(mdev->ldev->backing_bdev, NULL); + rv = blkdev_issue_flush(mdev->ldev->backing_bdev, GFP_KERNEL, + NULL, BLKDEV_IFL_WAIT); if (rv) { dev_err(DEV, "local disk flush failed with status %d\n", rv); /* would rather check on EOPNOTSUPP, but that is not reliable. diff --git a/fs/block_dev.c b/fs/block_dev.c index ea8385ea58ab..dd769304382e 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -413,7 +413,8 @@ int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync) if (error) return error; - error = blkdev_issue_flush(bdev, NULL); + error = blkdev_issue_flush(bdev, GFP_KERNEL, NULL, + (BLKDEV_IFL_WAIT)); if (error == -EOPNOTSUPP) error = 0; return error; diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index b34d32fdaaec..c6a4f459ad76 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -1589,7 +1589,7 @@ static void btrfs_issue_discard(struct block_device *bdev, u64 start, u64 len) { blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL, - DISCARD_FL_BARRIER); + BLKDEV_IFL_WAIT | BLKDEV_IFL_BARRIER); } static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, diff --git a/fs/ext3/fsync.c b/fs/ext3/fsync.c index 8209f266e9ad..9492f6003ef9 100644 --- a/fs/ext3/fsync.c +++ b/fs/ext3/fsync.c @@ -91,7 +91,8 @@ int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync) * storage */ if (test_opt(inode->i_sb, BARRIER)) - blkdev_issue_flush(inode->i_sb->s_bdev, NULL); + blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL, + BLKDEV_IFL_WAIT); out: return ret; } diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c index 0d0c3239c1cd..ef3d980e67cb 100644 --- a/fs/ext4/fsync.c +++ b/fs/ext4/fsync.c @@ -100,9 +100,11 @@ int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync) if (ext4_should_writeback_data(inode) && (journal->j_fs_dev != journal->j_dev) && (journal->j_flags & JBD2_BARRIER)) - blkdev_issue_flush(inode->i_sb->s_bdev, NULL); + blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, + NULL, BLKDEV_IFL_WAIT); jbd2_log_wait_commit(journal, commit_tid); } else if (journal->j_flags & JBD2_BARRIER) - blkdev_issue_flush(inode->i_sb->s_bdev, NULL); + blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL, + BLKDEV_IFL_WAIT); return ret; } diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 503b842f3ba2..bf011dc63471 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -854,7 +854,8 @@ static void gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, if ((start + nr_sects) != blk) { rv = blkdev_issue_discard(bdev, start, nr_sects, GFP_NOFS, - DISCARD_FL_BARRIER); + BLKDEV_IFL_WAIT | + BLKDEV_IFL_BARRIER); if (rv) goto fail; nr_sects = 0; @@ -869,7 +870,7 @@ start_new_extent: } if (nr_sects) { rv = blkdev_issue_discard(bdev, start, nr_sects, GFP_NOFS, - DISCARD_FL_BARRIER); + BLKDEV_IFL_WAIT | BLKDEV_IFL_BARRIER); if (rv) goto fail; } diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index 30beb11ef928..076d1cc44f95 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c @@ -530,7 +530,8 @@ int jbd2_cleanup_journal_tail(journal_t *journal) */ if ((journal->j_fs_dev != journal->j_dev) && (journal->j_flags & JBD2_BARRIER)) - blkdev_issue_flush(journal->j_fs_dev, NULL); + blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL, + BLKDEV_IFL_WAIT); if (!(journal->j_flags & JBD2_ABORT)) jbd2_journal_update_superblock(journal, 1); return 0; diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 671da7fb7ffd..75716d3d2be0 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -717,7 +717,8 @@ start_journal_io: if (commit_transaction->t_flushed_data_blocks && (journal->j_fs_dev != journal->j_dev) && (journal->j_flags & JBD2_BARRIER)) - blkdev_issue_flush(journal->j_fs_dev, NULL); + blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL, + BLKDEV_IFL_WAIT); /* Done it all: now write the commit record asynchronously. */ if (JBD2_HAS_INCOMPAT_FEATURE(journal, @@ -727,7 +728,8 @@ start_journal_io: if (err) __jbd2_journal_abort_hard(journal); if (journal->j_flags & JBD2_BARRIER) - blkdev_issue_flush(journal->j_dev, NULL); + blkdev_issue_flush(journal->j_dev, GFP_KERNEL, NULL, + BLKDEV_IFL_WAIT); } err = journal_finish_inode_data_buffers(journal, commit_transaction); diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 1d9c12714c5c..9977df9f3a54 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -147,7 +147,8 @@ static int reiserfs_sync_file(struct file *filp, barrier_done = reiserfs_commit_for_inode(inode); reiserfs_write_unlock(inode->i_sb); if (barrier_done != 1 && reiserfs_barrier_flush(inode->i_sb)) - blkdev_issue_flush(inode->i_sb->s_bdev, NULL); + blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL, + BLKDEV_IFL_WAIT); if (barrier_done < 0) return barrier_done; return (err < 0) ? -EIO : 0; diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 52e06b487ced..2b177c778ba7 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -725,7 +725,8 @@ void xfs_blkdev_issue_flush( xfs_buftarg_t *buftarg) { - blkdev_issue_flush(buftarg->bt_bdev, NULL); + blkdev_issue_flush(buftarg->bt_bdev, GFP_KERNEL, NULL, + BLKDEV_IFL_WAIT); } STATIC void diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 5cf17a49ce38..59b9aed0ee7d 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -998,12 +998,16 @@ static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt, return NULL; return bqt->tag_index[tag]; } - -extern int blkdev_issue_flush(struct block_device *, sector_t *); -#define DISCARD_FL_WAIT 0x01 /* wait for completion */ -#define DISCARD_FL_BARRIER 0x02 /* issue DISCARD_BARRIER request */ -extern int blkdev_issue_discard(struct block_device *, sector_t sector, - sector_t nr_sects, gfp_t, int flags); +enum{ + BLKDEV_WAIT, /* wait for completion */ + BLKDEV_BARRIER, /*issue request with barrier */ +}; +#define BLKDEV_IFL_WAIT (1 << BLKDEV_WAIT) +#define BLKDEV_IFL_BARRIER (1 << BLKDEV_BARRIER) +extern int blkdev_issue_flush(struct block_device *, gfp_t, sector_t *, + unsigned long); +extern int blkdev_issue_discard(struct block_device *bdev, sector_t sector, + sector_t nr_sects, gfp_t gfp_mask, unsigned long flags); static inline int sb_issue_discard(struct super_block *sb, sector_t block, sector_t nr_blocks) @@ -1011,7 +1015,7 @@ static inline int sb_issue_discard(struct super_block *sb, block <<= (sb->s_blocksize_bits - 9); nr_blocks <<= (sb->s_blocksize_bits - 9); return blkdev_issue_discard(sb->s_bdev, block, nr_blocks, GFP_KERNEL, - DISCARD_FL_BARRIER); + BLKDEV_IFL_WAIT | BLKDEV_IFL_BARRIER); } extern int blk_verify_command(unsigned char *cmd, fmode_t has_write_perm); diff --git a/mm/swapfile.c b/mm/swapfile.c index 6cd0a8f90dc7..eb086e0f4dcc 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -139,7 +139,8 @@ static int discard_swap(struct swap_info_struct *si) nr_blocks = ((sector_t)se->nr_pages - 1) << (PAGE_SHIFT - 9); if (nr_blocks) { err = blkdev_issue_discard(si->bdev, start_block, - nr_blocks, GFP_KERNEL, DISCARD_FL_BARRIER); + nr_blocks, GFP_KERNEL, + BLKDEV_IFL_WAIT | BLKDEV_IFL_BARRIER); if (err) return err; cond_resched(); @@ -150,7 +151,8 @@ static int discard_swap(struct swap_info_struct *si) nr_blocks = (sector_t)se->nr_pages << (PAGE_SHIFT - 9); err = blkdev_issue_discard(si->bdev, start_block, - nr_blocks, GFP_KERNEL, DISCARD_FL_BARRIER); + nr_blocks, GFP_KERNEL, + BLKDEV_IFL_WAIT | BLKDEV_IFL_BARRIER); if (err) break; @@ -189,7 +191,8 @@ static void discard_swap_cluster(struct swap_info_struct *si, start_block <<= PAGE_SHIFT - 9; nr_blocks <<= PAGE_SHIFT - 9; if (blkdev_issue_discard(si->bdev, start_block, - nr_blocks, GFP_NOIO, DISCARD_FL_BARRIER)) + nr_blocks, GFP_NOIO, BLKDEV_IFL_WAIT | + BLKDEV_IFL_BARRIER)) break; } -- cgit v1.2.3 From 8bfe9b5c3a684fe39eb58a65e466c103d1c32c9a Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:12:26 -0700 Subject: of/flattree: Make unflatten_device_tree() safe to call from any arch This patch makes unflatten_device_tree() safe to call from any arch setup code with the following changes: - Make sure initial_boot_params actually points to a device tree blob before unflattening - Make sure the initial_boot_params->magic field is correct - If CONFIG_OF_FLATTREE is not set, then make unflatten_device_tree() an empty static inline function. This patch also adds some additional debug output to the top of unflatten_device_tree(). Signed-off-by: Grant Likely --- drivers/of/fdt.c | 15 +++++++++++++++ include/linux/of_fdt.h | 2 ++ 2 files changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index dee4fb56b094..b6987bba8556 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -556,6 +556,21 @@ void __init unflatten_device_tree(void) pr_debug(" -> unflatten_device_tree()\n"); + if (!initial_boot_params) { + pr_debug("No device tree pointer\n"); + return; + } + + pr_debug("Unflattening device tree:\n"); + pr_debug("magic: %08x\n", be32_to_cpu(initial_boot_params->magic)); + pr_debug("size: %08x\n", be32_to_cpu(initial_boot_params->totalsize)); + pr_debug("version: %08x\n", be32_to_cpu(initial_boot_params->version)); + + if (be32_to_cpu(initial_boot_params->magic) != OF_DT_HEADER) { + pr_err("Invalid device tree blob header\n"); + return; + } + /* First pass, scan for size */ start = ((unsigned long)initial_boot_params) + be32_to_cpu(initial_boot_params->off_dt_struct); diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h index f0fdd1f43688..71e1a916d3fa 100644 --- a/include/linux/of_fdt.h +++ b/include/linux/of_fdt.h @@ -99,6 +99,8 @@ extern int early_init_dt_scan_root(unsigned long node, const char *uname, /* Other Prototypes */ extern void unflatten_device_tree(void); extern void early_init_devtree(void *); +#else /* CONFIG_OF_FLATTREE */ +static inline void unflatten_device_tree(void) {} #endif /* CONFIG_OF_FLATTREE */ #endif /* __ASSEMBLY__ */ -- cgit v1.2.3 From d706c1b050274b3bf97d7cb0542c0d070c9ccb8b Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:12:28 -0700 Subject: driver-core: Add device node pointer to struct device Currently, platforms using CONFIG_OF add a 'struct device_node *of_node' to dev->archdata. However, with CONFIG_OF becoming generic for all architectures, it makes sense for commonality to move it out of archdata and into struct device proper. This patch adds a struct device_node *of_node member to struct device and updates all locations which currently write the device_node pointer into archdata to also update dev->of_node. Subsequent patches will modify callers to use the archdata location and ultimately remove the archdata member entirely. Signed-off-by: Grant Likely Acked-by: Greg Kroah-Hartman CC: Michal Simek CC: Greg Kroah-Hartman CC: Benjamin Herrenschmidt CC: "David S. Miller" CC: Stephen Rothwell CC: Jeremy Kerr CC: microblaze-uclinux@itee.uq.edu.au CC: linux-kernel@vger.kernel.org CC: linuxppc-dev@ozlabs.org CC: sparclinux@vger.kernel.org --- arch/microblaze/kernel/of_device.c | 1 + arch/powerpc/kernel/of_device.c | 1 + arch/powerpc/kernel/pci-common.c | 3 ++- arch/powerpc/kernel/vio.c | 3 ++- arch/powerpc/platforms/ps3/system-bus.c | 1 + arch/sparc/kernel/of_device_32.c | 1 + arch/sparc/kernel/of_device_64.c | 1 + arch/sparc/kernel/pci.c | 1 + drivers/of/of_mdio.c | 1 + drivers/of/of_spi.c | 1 + include/linux/device.h | 4 ++++ 11 files changed, 16 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c index 9a0f7632c47c..f6c521898ebf 100644 --- a/arch/microblaze/kernel/of_device.c +++ b/arch/microblaze/kernel/of_device.c @@ -54,6 +54,7 @@ struct of_device *of_device_alloc(struct device_node *np, dev->dev.parent = parent; dev->dev.release = of_release_dev; dev->dev.archdata.of_node = np; + dev->dev.of_node = np; if (bus_id) dev_set_name(&dev->dev, bus_id); diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index a359cb08e900..9577e6f4e3bf 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c @@ -74,6 +74,7 @@ struct of_device *of_device_alloc(struct device_node *np, dev->dev.parent = parent; dev->dev.release = of_release_dev; dev->dev.archdata.of_node = np; + dev->dev.of_node = np; if (bus_id) dev_set_name(&dev->dev, "%s", bus_id); diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 0c0567e58409..88da282047c3 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1097,8 +1097,9 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) if (dev->is_added) continue; - /* Setup OF node pointer in archdata */ + /* Setup OF node pointer in the device */ sd->of_node = pci_device_to_OF_node(dev); + dev->dev.of_node = pci_device_to_OF_node(dev); /* Fixup NUMA node as it may not be setup yet by the generic * code and is needed by the DMA init diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 82237176a2a3..d6708da114ee 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -1230,7 +1230,8 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) if (unit_address != NULL) viodev->unit_address = *unit_address; } - viodev->dev.archdata.of_node = of_node_get(of_node); + viodev->dev.of_node = of_node_get(of_node); + viodev->dev.archdata.of_node = viodev->dev.of_node; if (firmware_has_feature(FW_FEATURE_CMO)) vio_cmo_set_dma_ops(viodev); diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index 6d09f5e3e7e4..e546c86a539b 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c @@ -766,6 +766,7 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev) BUG(); }; + dev->core.of_node = NULL; dev->core.archdata.of_node = NULL; set_dev_node(&dev->core, 0); diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index da527b33ebc7..4926c1babd84 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c @@ -348,6 +348,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, sd->prom_node = dp; sd->op = op; + op->dev.of_node = dp; op->node = dp; op->clock_freq = of_getintprop_default(dp, "clock-frequency", diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index b3d4cb5d21b3..5bc74161667c 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -643,6 +643,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, sd->prom_node = dp; sd->op = op; + op->dev.of_node = dp; op->node = dp; op->clock_freq = of_getintprop_default(dp, "clock-frequency", diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 5ac539a5930f..0c920147b4ef 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -262,6 +262,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, sd->stc = &pbm->stc; sd->host_controller = pbm; sd->prom_node = node; + dev->dev.of_node = node; sd->op = op = of_find_device_by_node(node); sd->numa_node = pbm->numa_node; diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 18ecae4a4375..12090f57dc87 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -80,6 +80,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) * can be looked up later */ of_node_get(child); dev_archdata_set_node(&phy->dev.archdata, child); + phy->dev.of_node = child; /* All data is now stored in the phy struct; register it */ rc = phy_device_register(phy); diff --git a/drivers/of/of_spi.c b/drivers/of/of_spi.c index f65f48b98448..f3119a0836af 100644 --- a/drivers/of/of_spi.c +++ b/drivers/of/of_spi.c @@ -79,6 +79,7 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np) /* Store a pointer to the node in the device structure */ of_node_get(nc); + spi->dev.of_node = nc; spi->dev.archdata.of_node = nc; /* Register the new device */ diff --git a/include/linux/device.h b/include/linux/device.h index 182192892d45..7a968bdb02e2 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -34,6 +34,7 @@ struct class; struct class_private; struct bus_type; struct bus_type_private; +struct device_node; struct bus_attribute { struct attribute attr; @@ -433,6 +434,9 @@ struct device { override */ /* arch specific additions */ struct dev_archdata archdata; +#ifdef CONFIG_OF + struct device_node *of_node; +#endif dev_t devt; /* dev_t, creates the sysfs "dev" */ -- cgit v1.2.3 From d12d42f744f805a9ccc33cd76f04b237cd83ce56 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:12:28 -0700 Subject: i2c/of: Allow device node to be passed via i2c_board_info The struct device_node *of_node pointer is moving out of dev->archdata and into the struct device proper. of_i2c.c needs to set the of_node pointer before the device is registered. Since the i2c subsystem doesn't allow 2 stage allocation and registration of i2c devices, the of_node pointer needs to be passed via the i2c_board_info structure so that it is set prior to registration. This patch adds of_node to struct i2c_board_info (conditional on CONFIG_OF), sets of_node in i2c_new_device(), and modifies of_i2c.c to use the new parameter. The calling of dev_archdata_set_node() from of_i2c will be removed in a subsequent patch when of_node is removed from archdata and all users are converted over. Signed-off-by: Grant Likely --- drivers/i2c/i2c-core.c | 3 +++ drivers/of/of_i2c.c | 1 + include/linux/i2c.h | 4 ++++ 3 files changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 3202a86f420e..4099b2b8c392 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -387,6 +387,9 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) client->dev.parent = &client->adapter->dev; client->dev.bus = &i2c_bus_type; client->dev.type = &i2c_client_type; +#ifdef CONFIG_OF + client->dev.of_node = info->of_node; +#endif dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap), client->addr); diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index a3a708e590d0..e690a2aa6fef 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c @@ -43,6 +43,7 @@ void of_register_i2c_devices(struct i2c_adapter *adap, info.addr = be32_to_cpup(addr); dev_archdata_set_node(&dev_ad, node); + info.of_node = node; info.archdata = &dev_ad; request_module("%s", info.type); diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 0a5da639b327..4f37ff1de7e1 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -34,6 +34,7 @@ #include /* for struct device */ #include /* for completion */ #include +#include /* for struct device_node */ extern struct bus_type i2c_bus_type; @@ -251,6 +252,9 @@ struct i2c_board_info { unsigned short addr; void *platform_data; struct dev_archdata *archdata; +#ifdef CONFIG_OF + struct device_node *of_node; +#endif int irq; }; -- cgit v1.2.3 From abb12dfd50c7580d7dcbd581cf6265ba4d01ea7e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 1 May 2010 15:22:54 -0700 Subject: ioat: convert to circ_buf Use the common power-of-2 circular buffer macros. Signed-off-by: Dan Williams --- drivers/dma/ioat/dma_v2.c | 2 +- drivers/dma/ioat/dma_v2.h | 18 +++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index b5ae56c211e6..b6699a350989 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c @@ -553,7 +553,7 @@ bool reshape_ring(struct ioat2_dma_chan *ioat, int order) */ struct ioat_chan_common *chan = &ioat->base; struct dma_chan *c = &chan->common; - const u16 curr_size = ioat2_ring_mask(ioat) + 1; + const u16 curr_size = ioat2_ring_size(ioat); const u16 active = ioat2_ring_active(ioat); const u16 new_size = 1 << order; struct ioat_ring_ent **ring; diff --git a/drivers/dma/ioat/dma_v2.h b/drivers/dma/ioat/dma_v2.h index ef2871fd7868..d7b64f188f78 100644 --- a/drivers/dma/ioat/dma_v2.h +++ b/drivers/dma/ioat/dma_v2.h @@ -22,6 +22,7 @@ #define IOATDMA_V2_H #include +#include #include "dma.h" #include "hw.h" @@ -71,31 +72,26 @@ static inline struct ioat2_dma_chan *to_ioat2_chan(struct dma_chan *c) return container_of(chan, struct ioat2_dma_chan, base); } -static inline u16 ioat2_ring_mask(struct ioat2_dma_chan *ioat) +static inline u16 ioat2_ring_size(struct ioat2_dma_chan *ioat) { - return (1 << ioat->alloc_order) - 1; + return 1 << ioat->alloc_order; } /* count of descriptors in flight with the engine */ static inline u16 ioat2_ring_active(struct ioat2_dma_chan *ioat) { - return (ioat->head - ioat->tail) & ioat2_ring_mask(ioat); + return CIRC_CNT(ioat->head, ioat->tail, ioat2_ring_size(ioat)); } /* count of descriptors pending submission to hardware */ static inline u16 ioat2_ring_pending(struct ioat2_dma_chan *ioat) { - return (ioat->head - ioat->issued) & ioat2_ring_mask(ioat); + return CIRC_CNT(ioat->head, ioat->issued, ioat2_ring_size(ioat)); } static inline u16 ioat2_ring_space(struct ioat2_dma_chan *ioat) { - u16 num_descs = ioat2_ring_mask(ioat) + 1; - u16 active = ioat2_ring_active(ioat); - - BUG_ON(active > num_descs); - - return num_descs - active; + return ioat2_ring_size(ioat) - ioat2_ring_active(ioat); } /* assumes caller already checked space */ @@ -151,7 +147,7 @@ struct ioat_ring_ent { static inline struct ioat_ring_ent * ioat2_get_ring_ent(struct ioat2_dma_chan *ioat, u16 idx) { - return ioat->ring[idx & ioat2_ring_mask(ioat)]; + return ioat->ring[idx & (ioat2_ring_size(ioat) - 1)]; } static inline void ioat2_set_chainaddr(struct ioat2_dma_chan *ioat, u64 addr) -- cgit v1.2.3 From 074cc47679f8b0931d7d5384e95822d82768f149 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 1 May 2010 15:22:55 -0700 Subject: ioat2,3: convert to producer/consumer locking Use separate locks for the descriptor prep (producer) and descriptor cleanup (consumer) paths. Allows the producer path to run concurrently with the cleanup path. Inspired by Documentation/circular-buffer.txt. Cc: David Howells Cc: Paul E. McKenney Cc: Maciej Sosnowski Signed-off-by: Dan Williams --- drivers/dma/ioat/dma.h | 1 + drivers/dma/ioat/dma_v2.c | 182 +++++++++++++++++++++++----------------------- drivers/dma/ioat/dma_v2.h | 15 ++-- drivers/dma/ioat/dma_v3.c | 117 +++++++++-------------------- 4 files changed, 134 insertions(+), 181 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index 86b97ac8774e..0c76578e9911 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h @@ -96,6 +96,7 @@ struct ioat_chan_common { #define IOAT_COMPLETION_ACK 1 #define IOAT_RESET_PENDING 2 #define IOAT_KOBJ_INIT_FAIL 3 + #define IOAT_RESHAPE_PENDING 4 struct timer_list timer; #define COMPLETION_TIMEOUT msecs_to_jiffies(100) #define IDLE_TIMEOUT msecs_to_jiffies(2000) diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index b6699a350989..e75d0299bb82 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c @@ -56,8 +56,6 @@ void __ioat2_issue_pending(struct ioat2_dma_chan *ioat) ioat->dmacount += ioat2_ring_pending(ioat); ioat->issued = ioat->head; - /* make descriptor updates globally visible before notifying channel */ - wmb(); writew(ioat->dmacount, chan->reg_base + IOAT_CHAN_DMACOUNT_OFFSET); dev_dbg(to_dev(chan), "%s: head: %#x tail: %#x issued: %#x count: %#x\n", @@ -69,9 +67,9 @@ void ioat2_issue_pending(struct dma_chan *c) struct ioat2_dma_chan *ioat = to_ioat2_chan(c); if (ioat2_ring_pending(ioat)) { - spin_lock_bh(&ioat->ring_lock); + spin_lock_bh(&ioat->prep_lock); __ioat2_issue_pending(ioat); - spin_unlock_bh(&ioat->ring_lock); + spin_unlock_bh(&ioat->prep_lock); } } @@ -80,7 +78,7 @@ void ioat2_issue_pending(struct dma_chan *c) * @ioat: ioat2+ channel * * Check if the number of unsubmitted descriptors has exceeded the - * watermark. Called with ring_lock held + * watermark. Called with prep_lock held */ static void ioat2_update_pending(struct ioat2_dma_chan *ioat) { @@ -92,7 +90,6 @@ static void __ioat2_start_null_desc(struct ioat2_dma_chan *ioat) { struct ioat_ring_ent *desc; struct ioat_dma_descriptor *hw; - int idx; if (ioat2_ring_space(ioat) < 1) { dev_err(to_dev(&ioat->base), @@ -102,8 +99,7 @@ static void __ioat2_start_null_desc(struct ioat2_dma_chan *ioat) dev_dbg(to_dev(&ioat->base), "%s: head: %#x tail: %#x issued: %#x\n", __func__, ioat->head, ioat->tail, ioat->issued); - idx = ioat2_desc_alloc(ioat, 1); - desc = ioat2_get_ring_ent(ioat, idx); + desc = ioat2_get_ring_ent(ioat, ioat->head); hw = desc->hw; hw->ctl = 0; @@ -117,14 +113,16 @@ static void __ioat2_start_null_desc(struct ioat2_dma_chan *ioat) async_tx_ack(&desc->txd); ioat2_set_chainaddr(ioat, desc->txd.phys); dump_desc_dbg(ioat, desc); + wmb(); + ioat->head += 1; __ioat2_issue_pending(ioat); } static void ioat2_start_null_desc(struct ioat2_dma_chan *ioat) { - spin_lock_bh(&ioat->ring_lock); + spin_lock_bh(&ioat->prep_lock); __ioat2_start_null_desc(ioat); - spin_unlock_bh(&ioat->ring_lock); + spin_unlock_bh(&ioat->prep_lock); } static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete) @@ -134,15 +132,16 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete) struct ioat_ring_ent *desc; bool seen_current = false; u16 active; - int i; + int idx = ioat->tail, i; dev_dbg(to_dev(chan), "%s: head: %#x tail: %#x issued: %#x\n", __func__, ioat->head, ioat->tail, ioat->issued); active = ioat2_ring_active(ioat); for (i = 0; i < active && !seen_current; i++) { - prefetch(ioat2_get_ring_ent(ioat, ioat->tail + i + 1)); - desc = ioat2_get_ring_ent(ioat, ioat->tail + i); + smp_read_barrier_depends(); + prefetch(ioat2_get_ring_ent(ioat, idx + i + 1)); + desc = ioat2_get_ring_ent(ioat, idx + i); tx = &desc->txd; dump_desc_dbg(ioat, desc); if (tx->cookie) { @@ -158,11 +157,12 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete) if (tx->phys == phys_complete) seen_current = true; } - ioat->tail += i; + smp_mb(); /* finish all descriptor reads before incrementing tail */ + ioat->tail = idx + i; BUG_ON(active && !seen_current); /* no active descs have written a completion? */ chan->last_completion = phys_complete; - if (ioat->head == ioat->tail) { + if (active - i == 0) { dev_dbg(to_dev(chan), "%s: cancel completion timeout\n", __func__); clear_bit(IOAT_COMPLETION_PENDING, &chan->state); @@ -179,24 +179,9 @@ static void ioat2_cleanup(struct ioat2_dma_chan *ioat) struct ioat_chan_common *chan = &ioat->base; unsigned long phys_complete; - prefetch(chan->completion); - - if (!spin_trylock_bh(&chan->cleanup_lock)) - return; - - if (!ioat_cleanup_preamble(chan, &phys_complete)) { - spin_unlock_bh(&chan->cleanup_lock); - return; - } - - if (!spin_trylock_bh(&ioat->ring_lock)) { - spin_unlock_bh(&chan->cleanup_lock); - return; - } - - __cleanup(ioat, phys_complete); - - spin_unlock_bh(&ioat->ring_lock); + spin_lock_bh(&chan->cleanup_lock); + if (ioat_cleanup_preamble(chan, &phys_complete)) + __cleanup(ioat, phys_complete); spin_unlock_bh(&chan->cleanup_lock); } @@ -287,12 +272,10 @@ void ioat2_timer_event(unsigned long data) struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data); struct ioat_chan_common *chan = &ioat->base; - spin_lock_bh(&chan->cleanup_lock); if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) { unsigned long phys_complete; u64 status; - spin_lock_bh(&ioat->ring_lock); status = ioat_chansts(chan); /* when halted due to errors check for channel @@ -311,26 +294,31 @@ void ioat2_timer_event(unsigned long data) * acknowledged a pending completion once, then be more * forceful with a restart */ - if (ioat_cleanup_preamble(chan, &phys_complete)) + spin_lock_bh(&chan->cleanup_lock); + if (ioat_cleanup_preamble(chan, &phys_complete)) { __cleanup(ioat, phys_complete); - else if (test_bit(IOAT_COMPLETION_ACK, &chan->state)) + } else if (test_bit(IOAT_COMPLETION_ACK, &chan->state)) { + spin_lock_bh(&ioat->prep_lock); ioat2_restart_channel(ioat); - else { + spin_unlock_bh(&ioat->prep_lock); + } else { set_bit(IOAT_COMPLETION_ACK, &chan->state); mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT); } - spin_unlock_bh(&ioat->ring_lock); + spin_unlock_bh(&chan->cleanup_lock); } else { u16 active; /* if the ring is idle, empty, and oversized try to step * down the size */ - spin_lock_bh(&ioat->ring_lock); + spin_lock_bh(&chan->cleanup_lock); + spin_lock_bh(&ioat->prep_lock); active = ioat2_ring_active(ioat); if (active == 0 && ioat->alloc_order > ioat_get_alloc_order()) reshape_ring(ioat, ioat->alloc_order-1); - spin_unlock_bh(&ioat->ring_lock); + spin_unlock_bh(&ioat->prep_lock); + spin_unlock_bh(&chan->cleanup_lock); /* keep shrinking until we get back to our minimum * default size @@ -338,7 +326,6 @@ void ioat2_timer_event(unsigned long data) if (ioat->alloc_order > ioat_get_alloc_order()) mod_timer(&chan->timer, jiffies + IDLE_TIMEOUT); } - spin_unlock_bh(&chan->cleanup_lock); } static int ioat2_reset_hw(struct ioat_chan_common *chan) @@ -392,7 +379,7 @@ int ioat2_enumerate_channels(struct ioatdma_device *device) ioat_init_channel(device, &ioat->base, i); ioat->xfercap_log = xfercap_log; - spin_lock_init(&ioat->ring_lock); + spin_lock_init(&ioat->prep_lock); if (device->reset_hw(&ioat->base)) { i = 0; break; @@ -418,8 +405,17 @@ static dma_cookie_t ioat2_tx_submit_unlock(struct dma_async_tx_descriptor *tx) if (!test_and_set_bit(IOAT_COMPLETION_PENDING, &chan->state)) mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT); + + /* make descriptor updates visible before advancing ioat->head, + * this is purposefully not smp_wmb() since we are also + * publishing the descriptor updates to a dma device + */ + wmb(); + + ioat->head += ioat->produce; + ioat2_update_pending(ioat); - spin_unlock_bh(&ioat->ring_lock); + spin_unlock_bh(&ioat->prep_lock); return cookie; } @@ -531,13 +527,15 @@ int ioat2_alloc_chan_resources(struct dma_chan *c) if (!ring) return -ENOMEM; - spin_lock_bh(&ioat->ring_lock); + spin_lock_bh(&chan->cleanup_lock); + spin_lock_bh(&ioat->prep_lock); ioat->ring = ring; ioat->head = 0; ioat->issued = 0; ioat->tail = 0; ioat->alloc_order = order; - spin_unlock_bh(&ioat->ring_lock); + spin_unlock_bh(&ioat->prep_lock); + spin_unlock_bh(&chan->cleanup_lock); tasklet_enable(&chan->cleanup_task); ioat2_start_null_desc(ioat); @@ -653,54 +651,61 @@ bool reshape_ring(struct ioat2_dma_chan *ioat, int order) } /** - * ioat2_alloc_and_lock - common descriptor alloc boilerplate for ioat2,3 ops - * @idx: gets starting descriptor index on successful allocation + * ioat2_check_space_lock - verify space and grab ring producer lock * @ioat: ioat2,3 channel (ring) to operate on * @num_descs: allocation length */ -int ioat2_alloc_and_lock(u16 *idx, struct ioat2_dma_chan *ioat, int num_descs) +int ioat2_check_space_lock(struct ioat2_dma_chan *ioat, int num_descs) { struct ioat_chan_common *chan = &ioat->base; + bool retry; - spin_lock_bh(&ioat->ring_lock); + retry: + spin_lock_bh(&ioat->prep_lock); /* never allow the last descriptor to be consumed, we need at * least one free at all times to allow for on-the-fly ring * resizing. */ - while (unlikely(ioat2_ring_space(ioat) <= num_descs)) { - if (reshape_ring(ioat, ioat->alloc_order + 1) && - ioat2_ring_space(ioat) > num_descs) - break; - - if (printk_ratelimit()) - dev_dbg(to_dev(chan), - "%s: ring full! num_descs: %d (%x:%x:%x)\n", - __func__, num_descs, ioat->head, ioat->tail, - ioat->issued); - spin_unlock_bh(&ioat->ring_lock); - - /* progress reclaim in the allocation failure case we - * may be called under bh_disabled so we need to trigger - * the timer event directly - */ - spin_lock_bh(&chan->cleanup_lock); - if (jiffies > chan->timer.expires && - timer_pending(&chan->timer)) { - struct ioatdma_device *device = chan->device; - - mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT); - spin_unlock_bh(&chan->cleanup_lock); - device->timer_fn((unsigned long) &chan->common); - } else - spin_unlock_bh(&chan->cleanup_lock); - return -ENOMEM; + if (likely(ioat2_ring_space(ioat) > num_descs)) { + dev_dbg(to_dev(chan), "%s: num_descs: %d (%x:%x:%x)\n", + __func__, num_descs, ioat->head, ioat->tail, ioat->issued); + ioat->produce = num_descs; + return 0; /* with ioat->prep_lock held */ } + retry = test_and_set_bit(IOAT_RESHAPE_PENDING, &chan->state); + spin_unlock_bh(&ioat->prep_lock); - dev_dbg(to_dev(chan), "%s: num_descs: %d (%x:%x:%x)\n", - __func__, num_descs, ioat->head, ioat->tail, ioat->issued); + /* is another cpu already trying to expand the ring? */ + if (retry) + goto retry; - *idx = ioat2_desc_alloc(ioat, num_descs); - return 0; /* with ioat->ring_lock held */ + spin_lock_bh(&chan->cleanup_lock); + spin_lock_bh(&ioat->prep_lock); + retry = reshape_ring(ioat, ioat->alloc_order + 1); + clear_bit(IOAT_RESHAPE_PENDING, &chan->state); + spin_unlock_bh(&ioat->prep_lock); + spin_unlock_bh(&chan->cleanup_lock); + + /* if we were able to expand the ring retry the allocation */ + if (retry) + goto retry; + + if (printk_ratelimit()) + dev_dbg(to_dev(chan), "%s: ring full! num_descs: %d (%x:%x:%x)\n", + __func__, num_descs, ioat->head, ioat->tail, ioat->issued); + + /* progress reclaim in the allocation failure case we may be + * called under bh_disabled so we need to trigger the timer + * event directly + */ + if (jiffies > chan->timer.expires && timer_pending(&chan->timer)) { + struct ioatdma_device *device = chan->device; + + mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT); + device->timer_fn((unsigned long) &chan->common); + } + + return -ENOMEM; } struct dma_async_tx_descriptor * @@ -713,14 +718,11 @@ ioat2_dma_prep_memcpy_lock(struct dma_chan *c, dma_addr_t dma_dest, dma_addr_t dst = dma_dest; dma_addr_t src = dma_src; size_t total_len = len; - int num_descs; - u16 idx; - int i; + int num_descs, idx, i; num_descs = ioat2_xferlen_to_descs(ioat, len); - if (likely(num_descs) && - ioat2_alloc_and_lock(&idx, ioat, num_descs) == 0) - /* pass */; + if (likely(num_descs) && ioat2_check_space_lock(ioat, num_descs) == 0) + idx = ioat->head; else return NULL; i = 0; @@ -777,7 +779,8 @@ void ioat2_free_chan_resources(struct dma_chan *c) device->cleanup_fn((unsigned long) c); device->reset_hw(chan); - spin_lock_bh(&ioat->ring_lock); + spin_lock_bh(&chan->cleanup_lock); + spin_lock_bh(&ioat->prep_lock); descs = ioat2_ring_space(ioat); dev_dbg(to_dev(chan), "freeing %d idle descriptors\n", descs); for (i = 0; i < descs; i++) { @@ -800,7 +803,8 @@ void ioat2_free_chan_resources(struct dma_chan *c) ioat->alloc_order = 0; pci_pool_free(device->completion_pool, chan->completion, chan->completion_dma); - spin_unlock_bh(&ioat->ring_lock); + spin_unlock_bh(&ioat->prep_lock); + spin_unlock_bh(&chan->cleanup_lock); chan->last_completion = 0; chan->completion_dma = 0; diff --git a/drivers/dma/ioat/dma_v2.h b/drivers/dma/ioat/dma_v2.h index d7b64f188f78..a2c413b2b8d8 100644 --- a/drivers/dma/ioat/dma_v2.h +++ b/drivers/dma/ioat/dma_v2.h @@ -50,8 +50,9 @@ extern int ioat_ring_alloc_order; * @tail: cleanup index * @dmacount: identical to 'head' except for occasionally resetting to zero * @alloc_order: log2 of the number of allocated descriptors + * @produce: number of descriptors to produce at submit time * @ring: software ring buffer implementation of hardware ring - * @ring_lock: protects ring attributes + * @prep_lock: serializes descriptor preparation (producers) */ struct ioat2_dma_chan { struct ioat_chan_common base; @@ -61,8 +62,9 @@ struct ioat2_dma_chan { u16 tail; u16 dmacount; u16 alloc_order; + u16 produce; struct ioat_ring_ent **ring; - spinlock_t ring_lock; + spinlock_t prep_lock; }; static inline struct ioat2_dma_chan *to_ioat2_chan(struct dma_chan *c) @@ -94,13 +96,6 @@ static inline u16 ioat2_ring_space(struct ioat2_dma_chan *ioat) return ioat2_ring_size(ioat) - ioat2_ring_active(ioat); } -/* assumes caller already checked space */ -static inline u16 ioat2_desc_alloc(struct ioat2_dma_chan *ioat, u16 len) -{ - ioat->head += len; - return ioat->head - len; -} - static inline u16 ioat2_xferlen_to_descs(struct ioat2_dma_chan *ioat, size_t len) { u16 num_descs = len >> ioat->xfercap_log; @@ -164,7 +159,7 @@ int __devinit ioat2_dma_probe(struct ioatdma_device *dev, int dca); int __devinit ioat3_dma_probe(struct ioatdma_device *dev, int dca); struct dca_provider * __devinit ioat2_dca_init(struct pci_dev *pdev, void __iomem *iobase); struct dca_provider * __devinit ioat3_dca_init(struct pci_dev *pdev, void __iomem *iobase); -int ioat2_alloc_and_lock(u16 *idx, struct ioat2_dma_chan *ioat, int num_descs); +int ioat2_check_space_lock(struct ioat2_dma_chan *ioat, int num_descs); int ioat2_enumerate_channels(struct ioatdma_device *device); struct dma_async_tx_descriptor * ioat2_dma_prep_memcpy_lock(struct dma_chan *c, dma_addr_t dma_dest, diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index 6740e319c9cf..8b573fac2a25 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c @@ -260,8 +260,8 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete) struct ioat_chan_common *chan = &ioat->base; struct ioat_ring_ent *desc; bool seen_current = false; + int idx = ioat->tail, i; u16 active; - int i; dev_dbg(to_dev(chan), "%s: head: %#x tail: %#x issued: %#x\n", __func__, ioat->head, ioat->tail, ioat->issued); @@ -270,13 +270,14 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete) for (i = 0; i < active && !seen_current; i++) { struct dma_async_tx_descriptor *tx; - prefetch(ioat2_get_ring_ent(ioat, ioat->tail + i + 1)); - desc = ioat2_get_ring_ent(ioat, ioat->tail + i); + smp_read_barrier_depends(); + prefetch(ioat2_get_ring_ent(ioat, idx + i + 1)); + desc = ioat2_get_ring_ent(ioat, idx + i); dump_desc_dbg(ioat, desc); tx = &desc->txd; if (tx->cookie) { chan->completed_cookie = tx->cookie; - ioat3_dma_unmap(ioat, desc, ioat->tail + i); + ioat3_dma_unmap(ioat, desc, idx + i); tx->cookie = 0; if (tx->callback) { tx->callback(tx->callback_param); @@ -293,69 +294,30 @@ static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete) i++; } } - ioat->tail += i; + smp_mb(); /* finish all descriptor reads before incrementing tail */ + ioat->tail = idx + i; BUG_ON(active && !seen_current); /* no active descs have written a completion? */ chan->last_completion = phys_complete; - active = ioat2_ring_active(ioat); - if (active == 0) { + if (active - i == 0) { dev_dbg(to_dev(chan), "%s: cancel completion timeout\n", __func__); clear_bit(IOAT_COMPLETION_PENDING, &chan->state); mod_timer(&chan->timer, jiffies + IDLE_TIMEOUT); } /* 5 microsecond delay per pending descriptor */ - writew(min((5 * active), IOAT_INTRDELAY_MASK), + writew(min((5 * (active - i)), IOAT_INTRDELAY_MASK), chan->device->reg_base + IOAT_INTRDELAY_OFFSET); } -/* try to cleanup, but yield (via spin_trylock) to incoming submissions - * with the expectation that we will immediately poll again shortly - */ -static void ioat3_cleanup_poll(struct ioat2_dma_chan *ioat) +static void ioat3_cleanup(struct ioat2_dma_chan *ioat) { struct ioat_chan_common *chan = &ioat->base; unsigned long phys_complete; - prefetch(chan->completion); - - if (!spin_trylock_bh(&chan->cleanup_lock)) - return; - - if (!ioat_cleanup_preamble(chan, &phys_complete)) { - spin_unlock_bh(&chan->cleanup_lock); - return; - } - - if (!spin_trylock_bh(&ioat->ring_lock)) { - spin_unlock_bh(&chan->cleanup_lock); - return; - } - - __cleanup(ioat, phys_complete); - - spin_unlock_bh(&ioat->ring_lock); - spin_unlock_bh(&chan->cleanup_lock); -} - -/* run cleanup now because we already delayed the interrupt via INTRDELAY */ -static void ioat3_cleanup_sync(struct ioat2_dma_chan *ioat) -{ - struct ioat_chan_common *chan = &ioat->base; - unsigned long phys_complete; - - prefetch(chan->completion); - spin_lock_bh(&chan->cleanup_lock); - if (!ioat_cleanup_preamble(chan, &phys_complete)) { - spin_unlock_bh(&chan->cleanup_lock); - return; - } - spin_lock_bh(&ioat->ring_lock); - - __cleanup(ioat, phys_complete); - - spin_unlock_bh(&ioat->ring_lock); + if (ioat_cleanup_preamble(chan, &phys_complete)) + __cleanup(ioat, phys_complete); spin_unlock_bh(&chan->cleanup_lock); } @@ -363,7 +325,7 @@ static void ioat3_cleanup_event(unsigned long data) { struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data); - ioat3_cleanup_sync(ioat); + ioat3_cleanup(ioat); writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET); } @@ -384,12 +346,10 @@ static void ioat3_timer_event(unsigned long data) struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data); struct ioat_chan_common *chan = &ioat->base; - spin_lock_bh(&chan->cleanup_lock); if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) { unsigned long phys_complete; u64 status; - spin_lock_bh(&ioat->ring_lock); status = ioat_chansts(chan); /* when halted due to errors check for channel @@ -408,26 +368,31 @@ static void ioat3_timer_event(unsigned long data) * acknowledged a pending completion once, then be more * forceful with a restart */ + spin_lock_bh(&chan->cleanup_lock); if (ioat_cleanup_preamble(chan, &phys_complete)) __cleanup(ioat, phys_complete); - else if (test_bit(IOAT_COMPLETION_ACK, &chan->state)) + else if (test_bit(IOAT_COMPLETION_ACK, &chan->state)) { + spin_lock_bh(&ioat->prep_lock); ioat3_restart_channel(ioat); - else { + spin_unlock_bh(&ioat->prep_lock); + } else { set_bit(IOAT_COMPLETION_ACK, &chan->state); mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT); } - spin_unlock_bh(&ioat->ring_lock); + spin_unlock_bh(&chan->cleanup_lock); } else { u16 active; /* if the ring is idle, empty, and oversized try to step * down the size */ - spin_lock_bh(&ioat->ring_lock); + spin_lock_bh(&chan->cleanup_lock); + spin_lock_bh(&ioat->prep_lock); active = ioat2_ring_active(ioat); if (active == 0 && ioat->alloc_order > ioat_get_alloc_order()) reshape_ring(ioat, ioat->alloc_order-1); - spin_unlock_bh(&ioat->ring_lock); + spin_unlock_bh(&ioat->prep_lock); + spin_unlock_bh(&chan->cleanup_lock); /* keep shrinking until we get back to our minimum * default size @@ -435,7 +400,6 @@ static void ioat3_timer_event(unsigned long data) if (ioat->alloc_order > ioat_get_alloc_order()) mod_timer(&chan->timer, jiffies + IDLE_TIMEOUT); } - spin_unlock_bh(&chan->cleanup_lock); } static enum dma_status @@ -447,7 +411,7 @@ ioat3_is_complete(struct dma_chan *c, dma_cookie_t cookie, if (ioat_is_complete(c, cookie, done, used) == DMA_SUCCESS) return DMA_SUCCESS; - ioat3_cleanup_poll(ioat); + ioat3_cleanup(ioat); return ioat_is_complete(c, cookie, done, used); } @@ -460,15 +424,12 @@ ioat3_prep_memset_lock(struct dma_chan *c, dma_addr_t dest, int value, struct ioat_ring_ent *desc; size_t total_len = len; struct ioat_fill_descriptor *fill; - int num_descs; u64 src_data = (0x0101010101010101ULL) * (value & 0xff); - u16 idx; - int i; + int num_descs, idx, i; num_descs = ioat2_xferlen_to_descs(ioat, len); - if (likely(num_descs) && - ioat2_alloc_and_lock(&idx, ioat, num_descs) == 0) - /* pass */; + if (likely(num_descs) && ioat2_check_space_lock(ioat, num_descs) == 0) + idx = ioat->head; else return NULL; i = 0; @@ -513,11 +474,8 @@ __ioat3_prep_xor_lock(struct dma_chan *c, enum sum_check_flags *result, struct ioat_xor_descriptor *xor; struct ioat_xor_ext_descriptor *xor_ex = NULL; struct ioat_dma_descriptor *hw; + int num_descs, with_ext, idx, i; u32 offset = 0; - int num_descs; - int with_ext; - int i; - u16 idx; u8 op = result ? IOAT_OP_XOR_VAL : IOAT_OP_XOR; BUG_ON(src_cnt < 2); @@ -537,9 +495,8 @@ __ioat3_prep_xor_lock(struct dma_chan *c, enum sum_check_flags *result, * (legacy) descriptor to ensure all completion writes arrive in * order. */ - if (likely(num_descs) && - ioat2_alloc_and_lock(&idx, ioat, num_descs+1) == 0) - /* pass */; + if (likely(num_descs) && ioat2_check_space_lock(ioat, num_descs+1) == 0) + idx = ioat->head; else return NULL; i = 0; @@ -657,11 +614,8 @@ __ioat3_prep_pq_lock(struct dma_chan *c, enum sum_check_flags *result, struct ioat_pq_ext_descriptor *pq_ex = NULL; struct ioat_dma_descriptor *hw; u32 offset = 0; - int num_descs; - int with_ext; - int i, s; - u16 idx; u8 op = result ? IOAT_OP_PQ_VAL : IOAT_OP_PQ; + int i, s, idx, with_ext, num_descs; dev_dbg(to_dev(chan), "%s\n", __func__); /* the engine requires at least two sources (we provide @@ -687,8 +641,8 @@ __ioat3_prep_pq_lock(struct dma_chan *c, enum sum_check_flags *result, * order. */ if (likely(num_descs) && - ioat2_alloc_and_lock(&idx, ioat, num_descs+1) == 0) - /* pass */; + ioat2_check_space_lock(ioat, num_descs+1) == 0) + idx = ioat->head; else return NULL; i = 0; @@ -851,10 +805,9 @@ ioat3_prep_interrupt_lock(struct dma_chan *c, unsigned long flags) struct ioat2_dma_chan *ioat = to_ioat2_chan(c); struct ioat_ring_ent *desc; struct ioat_dma_descriptor *hw; - u16 idx; - if (ioat2_alloc_and_lock(&idx, ioat, 1) == 0) - desc = ioat2_get_ring_ent(ioat, idx); + if (ioat2_check_space_lock(ioat, 1) == 0) + desc = ioat2_get_ring_ent(ioat, ioat->head); else return NULL; -- cgit v1.2.3 From 2adfc550b6d9646301c810643bc309fa49375987 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 1 May 2010 15:22:56 -0700 Subject: ioat3: disable cacheline-unaligned transfers for raid operations There are cases where cacheline-unaligned raid operations can hang the dma channel. Simply disable these operations by increasing the alignment constraints published to async_tx. The raid456 driver always issues page aligned requests, so the only in-kernel user of the ioatdma driver that is affected by this change is dmatest. Signed-off-by: Dan Williams --- drivers/dma/ioat/dma_v3.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index 8b573fac2a25..e2a23952172d 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c @@ -1175,7 +1175,7 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) if (cap & IOAT_CAP_XOR) { is_raid_device = true; dma->max_xor = 8; - dma->xor_align = 2; + dma->xor_align = 6; dma_cap_set(DMA_XOR, dma->cap_mask); dma->device_prep_dma_xor = ioat3_prep_xor; @@ -1186,7 +1186,7 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) if (cap & IOAT_CAP_PQ) { is_raid_device = true; dma_set_maxpq(dma, 8, 0); - dma->pq_align = 2; + dma->pq_align = 6; dma_cap_set(DMA_PQ, dma->cap_mask); dma->device_prep_dma_pq = ioat3_prep_pq; @@ -1196,7 +1196,7 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) if (!(cap & IOAT_CAP_XOR)) { dma->max_xor = 8; - dma->xor_align = 2; + dma->xor_align = 6; dma_cap_set(DMA_XOR, dma->cap_mask); dma->device_prep_dma_xor = ioat3_prep_pqxor; -- cgit v1.2.3 From ab6cc8f9b716a3d0a41b42cd81d392183211a7f2 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Mon, 26 Apr 2010 22:10:52 +0400 Subject: ds2782_battery: Get rid of magic numbers in driver_data Constructions like 'if (id->driver_data == 1)' look quite weird. This patch introduces 'enum ds278x_num_id', which makes things much more understandable, i.e. 'if (id->driver_data == DS2786)'. Signed-off-by: Anton Vorontsov Acked-by: Mike Rapoport --- drivers/power/ds2782_battery.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/power/ds2782_battery.c b/drivers/power/ds2782_battery.c index c665e8007235..d762a0cbc6af 100644 --- a/drivers/power/ds2782_battery.c +++ b/drivers/power/ds2782_battery.c @@ -300,13 +300,18 @@ static int ds278x_battery_remove(struct i2c_client *client) return 0; } +enum ds278x_num_id { + DS2782 = 0, + DS2786, +}; + static struct ds278x_battery_ops ds278x_ops[] = { - [0] = { + [DS2782] = { .get_current = ds2782_get_current, .get_voltage = ds2782_get_voltage, .get_capacity = ds2782_get_capacity, }, - [1] = { + [DS2786] = { .get_current = ds2786_get_current, .get_voltage = ds2786_get_voltage, .get_capacity = ds2786_get_capacity, @@ -325,7 +330,7 @@ static int ds278x_battery_probe(struct i2c_client *client, * ds2786 should have the sense resistor value set * in the platform data */ - if (id->driver_data == 1 && !pdata) { + if (id->driver_data == DS2786 && !pdata) { dev_err(&client->dev, "missing platform data for ds2786\n"); return -EINVAL; } @@ -355,7 +360,7 @@ static int ds278x_battery_probe(struct i2c_client *client, goto fail_name; } - if (id->driver_data == 1) + if (id->driver_data == DS2786) info->rsns = pdata->rsns; i2c_set_clientdata(client, info); @@ -385,8 +390,8 @@ fail_id: } static const struct i2c_device_id ds278x_id[] = { - {"ds2782", 0}, - {"ds2786", 1}, + {"ds2782", DS2782}, + {"ds2786", DS2786}, {}, }; -- cgit v1.2.3 From c86e1401c9f2ba8d989fa1c4b33d0f0ec3ba8aaf Mon Sep 17 00:00:00 2001 From: Minskey Guo Date: Sun, 2 May 2010 12:52:35 -0700 Subject: ioat: Remove duplicated devm_kzalloc() calls for ioatdma_device The memory for ioatdma_device structure is being allocated in alloc_ioatdma() Signed-off-by: Minskey Guo Signed-off-by: Dan Williams --- drivers/dma/ioat/pci.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/ioat/pci.c b/drivers/dma/ioat/pci.c index 99ec26725bae..fab37d1cf48d 100644 --- a/drivers/dma/ioat/pci.c +++ b/drivers/dma/ioat/pci.c @@ -138,15 +138,10 @@ static int __devinit ioat_pci_probe(struct pci_dev *pdev, const struct pci_devic if (err) return err; - device = devm_kzalloc(dev, sizeof(*device), GFP_KERNEL); - if (!device) - return -ENOMEM; - - pci_set_master(pdev); - device = alloc_ioatdma(pdev, iomap[IOAT_MMIO_BAR]); if (!device) return -ENOMEM; + pci_set_master(pdev); pci_set_drvdata(pdev, device); device->version = readb(device->reg_base + IOAT_VER_OFFSET); -- cgit v1.2.3 From b1458fb57de03b19296cac70e9455b05912782b5 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sun, 2 May 2010 23:50:38 +0400 Subject: wm97xx_battery: Quieten sparse warning (bat_set_pdata not declared) This patch fixes following sparse warning: drivers/power/wm97xx_battery.c:311:6: warning: symbol 'wm97xx_bat_set_pdata' was not declared. Should it be static? Note that we can't just include linux/wm97xx_batt.h because the header is deprecated, and so this pops up: In file included from drivers/power/wm97xx_battery.c:22: include/linux/wm97xx_batt.h:6: warning: #warning This file will be removed soon, use wm97xx.h instead! Since wm97xx_bat_set_pdata() is also deprecated (in favour of pdata passed via AC97 bus), just workaround the issue by declaring the function in wm97xx_battery.c. Signed-off-by: Anton Vorontsov --- drivers/power/wm97xx_battery.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/power/wm97xx_battery.c b/drivers/power/wm97xx_battery.c index 94c70650aafc..4e8afce0c818 100644 --- a/drivers/power/wm97xx_battery.c +++ b/drivers/power/wm97xx_battery.c @@ -308,6 +308,9 @@ static void __exit wm97xx_bat_exit(void) platform_driver_unregister(&wm97xx_bat_driver); } +/* The interface is deprecated, as well as linux/wm97xx_batt.h */ +void wm97xx_bat_set_pdata(struct wm97xx_batt_info *data); + void wm97xx_bat_set_pdata(struct wm97xx_batt_info *data) { gpdata = data; -- cgit v1.2.3 From 06b9e650ce5eaf14ac1486b2f05baaf2ba22ad22 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Tue, 27 Apr 2010 17:18:22 +0400 Subject: tosa_battery: Fix build error due to direct driver_data usage The driver isn't buildable since 2.6.32 (i.e. commit b4028437 "Driver core: move dev_get/set_drvdata to drivers/base/dd.c"): CC tosa_battery.o tosa_battery.c: In function 'tosa_read_bat': tosa_battery.c:64: error: 'struct device' has no member named 'driver_data' tosa_battery.c: In function 'tosa_read_temp': tosa_battery.c:84: error: 'struct device' has no member named 'driver_data' Nowadays we must not access driver_data directly, use dev_get_drvdata() instead. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Andrew Morton Signed-off-by: Anton Vorontsov --- drivers/power/tosa_battery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/power/tosa_battery.c b/drivers/power/tosa_battery.c index 2eab35aab311..ee04936b2db5 100644 --- a/drivers/power/tosa_battery.c +++ b/drivers/power/tosa_battery.c @@ -61,7 +61,7 @@ static unsigned long tosa_read_bat(struct tosa_bat *bat) mutex_lock(&bat_lock); gpio_set_value(bat->gpio_bat, 1); msleep(5); - value = wm97xx_read_aux_adc(bat->psy.dev->parent->driver_data, + value = wm97xx_read_aux_adc(dev_get_drvdata(bat->psy.dev->parent), bat->adc_bat); gpio_set_value(bat->gpio_bat, 0); mutex_unlock(&bat_lock); @@ -81,7 +81,7 @@ static unsigned long tosa_read_temp(struct tosa_bat *bat) mutex_lock(&bat_lock); gpio_set_value(bat->gpio_temp, 1); msleep(5); - value = wm97xx_read_aux_adc(bat->psy.dev->parent->driver_data, + value = wm97xx_read_aux_adc(dev_get_drvdata(bat->psy.dev->parent), bat->adc_temp); gpio_set_value(bat->gpio_temp, 0); mutex_unlock(&bat_lock); -- cgit v1.2.3 From 8628e7c89075834fc7b44629d09ff4f9043af114 Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Mon, 3 May 2010 11:10:59 +0800 Subject: crypto: omap - sha1 & md5 driver Earlier kernel contained omap sha1 and md5 driver, which was not maintained, was not ported to new crypto APIs and removed from the source tree. - implements async crypto API using dma and cpu. - supports multiple sham instances if available - hmac - concurrent requests Signed-off-by: Dmitry Kasatkin Signed-off-by: Herbert Xu --- drivers/crypto/Kconfig | 9 + drivers/crypto/Makefile | 2 + drivers/crypto/omap-sham.c | 1259 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1270 insertions(+) create mode 100644 drivers/crypto/omap-sham.c (limited to 'drivers') diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index b08403d7d1ca..9073aa05123e 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -222,4 +222,13 @@ config CRYPTO_DEV_PPC4XX help This option allows you to have support for AMCC crypto acceleration. +config CRYPTO_DEV_OMAP_SHAM + tristate "Support for OMAP SHA1/MD5 hw accelerator" + depends on ARCH_OMAP2 || ARCH_OMAP3 + select CRYPTO_SHA1 + select CRYPTO_MD5 + help + OMAP processors have SHA1/MD5 hw accelerator. Select this if you + want to use the OMAP module for SHA1/MD5 algorithms. + endif # CRYPTO_HW diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index 6ffcb3f7f942..c9494e163402 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -6,3 +6,5 @@ obj-$(CONFIG_CRYPTO_DEV_MV_CESA) += mv_cesa.o obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/ +obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o + diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c new file mode 100644 index 000000000000..8b034337793f --- /dev/null +++ b/drivers/crypto/omap-sham.c @@ -0,0 +1,1259 @@ +/* + * Cryptographic API. + * + * Support for OMAP SHA1/MD5 HW acceleration. + * + * Copyright (c) 2010 Nokia Corporation + * Author: Dmitry Kasatkin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * Some ideas are from old omap-sha1-md5.c driver. + */ + +#define pr_fmt(fmt) "%s: " fmt, __func__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define SHA_REG_DIGEST(x) (0x00 + ((x) * 0x04)) +#define SHA_REG_DIN(x) (0x1C + ((x) * 0x04)) + +#define SHA1_MD5_BLOCK_SIZE SHA1_BLOCK_SIZE +#define MD5_DIGEST_SIZE 16 + +#define SHA_REG_DIGCNT 0x14 + +#define SHA_REG_CTRL 0x18 +#define SHA_REG_CTRL_LENGTH (0xFFFFFFFF << 5) +#define SHA_REG_CTRL_CLOSE_HASH (1 << 4) +#define SHA_REG_CTRL_ALGO_CONST (1 << 3) +#define SHA_REG_CTRL_ALGO (1 << 2) +#define SHA_REG_CTRL_INPUT_READY (1 << 1) +#define SHA_REG_CTRL_OUTPUT_READY (1 << 0) + +#define SHA_REG_REV 0x5C +#define SHA_REG_REV_MAJOR 0xF0 +#define SHA_REG_REV_MINOR 0x0F + +#define SHA_REG_MASK 0x60 +#define SHA_REG_MASK_DMA_EN (1 << 3) +#define SHA_REG_MASK_IT_EN (1 << 2) +#define SHA_REG_MASK_SOFTRESET (1 << 1) +#define SHA_REG_AUTOIDLE (1 << 0) + +#define SHA_REG_SYSSTATUS 0x64 +#define SHA_REG_SYSSTATUS_RESETDONE (1 << 0) + +#define DEFAULT_TIMEOUT_INTERVAL HZ + +#define FLAGS_FIRST 0x0001 +#define FLAGS_FINUP 0x0002 +#define FLAGS_FINAL 0x0004 +#define FLAGS_FAST 0x0008 +#define FLAGS_SHA1 0x0010 +#define FLAGS_DMA_ACTIVE 0x0020 +#define FLAGS_OUTPUT_READY 0x0040 +#define FLAGS_CLEAN 0x0080 +#define FLAGS_INIT 0x0100 +#define FLAGS_CPU 0x0200 +#define FLAGS_HMAC 0x0400 + +/* 3rd byte */ +#define FLAGS_BUSY 16 + +#define OP_UPDATE 1 +#define OP_FINAL 2 + +struct omap_sham_dev; + +struct omap_sham_reqctx { + struct omap_sham_dev *dd; + unsigned long flags; + unsigned long op; + + size_t digcnt; + u8 *buffer; + size_t bufcnt; + size_t buflen; + dma_addr_t dma_addr; + + /* walk state */ + struct scatterlist *sg; + unsigned int offset; /* offset in current sg */ + unsigned int total; /* total request */ +}; + +struct omap_sham_hmac_ctx { + struct crypto_shash *shash; + u8 ipad[SHA1_MD5_BLOCK_SIZE]; + u8 opad[SHA1_MD5_BLOCK_SIZE]; +}; + +struct omap_sham_ctx { + struct omap_sham_dev *dd; + + unsigned long flags; + + /* fallback stuff */ + struct crypto_shash *fallback; + + struct omap_sham_hmac_ctx base[0]; +}; + +#define OMAP_SHAM_QUEUE_LENGTH 1 + +struct omap_sham_dev { + struct list_head list; + unsigned long phys_base; + struct device *dev; + void __iomem *io_base; + int irq; + struct clk *iclk; + spinlock_t lock; + int dma; + int dma_lch; + struct tasklet_struct done_task; + struct tasklet_struct queue_task; + + unsigned long flags; + struct crypto_queue queue; + struct ahash_request *req; +}; + +struct omap_sham_drv { + struct list_head dev_list; + spinlock_t lock; + unsigned long flags; +}; + +static struct omap_sham_drv sham = { + .dev_list = LIST_HEAD_INIT(sham.dev_list), + .lock = __SPIN_LOCK_UNLOCKED(sham.lock), +}; + +static inline u32 omap_sham_read(struct omap_sham_dev *dd, u32 offset) +{ + return __raw_readl(dd->io_base + offset); +} + +static inline void omap_sham_write(struct omap_sham_dev *dd, + u32 offset, u32 value) +{ + __raw_writel(value, dd->io_base + offset); +} + +static inline void omap_sham_write_mask(struct omap_sham_dev *dd, u32 address, + u32 value, u32 mask) +{ + u32 val; + + val = omap_sham_read(dd, address); + val &= ~mask; + val |= value; + omap_sham_write(dd, address, val); +} + +static inline int omap_sham_wait(struct omap_sham_dev *dd, u32 offset, u32 bit) +{ + unsigned long timeout = jiffies + DEFAULT_TIMEOUT_INTERVAL; + + while (!(omap_sham_read(dd, offset) & bit)) { + if (time_is_before_jiffies(timeout)) + return -ETIMEDOUT; + } + + return 0; +} + +static void omap_sham_copy_hash(struct ahash_request *req, int out) +{ + struct omap_sham_reqctx *ctx = ahash_request_ctx(req); + u32 *hash = (u32 *)req->result; + int i; + + if (likely(ctx->flags & FLAGS_SHA1)) { + /* SHA1 results are in big endian */ + for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(u32); i++) + if (out) + hash[i] = be32_to_cpu(omap_sham_read(ctx->dd, + SHA_REG_DIGEST(i))); + else + omap_sham_write(ctx->dd, SHA_REG_DIGEST(i), + cpu_to_be32(hash[i])); + } else { + /* MD5 results are in little endian */ + for (i = 0; i < MD5_DIGEST_SIZE / sizeof(u32); i++) + if (out) + hash[i] = le32_to_cpu(omap_sham_read(ctx->dd, + SHA_REG_DIGEST(i))); + else + omap_sham_write(ctx->dd, SHA_REG_DIGEST(i), + cpu_to_le32(hash[i])); + } +} + +static int omap_sham_write_ctrl(struct omap_sham_dev *dd, size_t length, + int final, int dma) +{ + struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); + u32 val = length << 5, mask; + + if (unlikely(!ctx->digcnt)) { + + clk_enable(dd->iclk); + + if (!(dd->flags & FLAGS_INIT)) { + omap_sham_write_mask(dd, SHA_REG_MASK, + SHA_REG_MASK_SOFTRESET, SHA_REG_MASK_SOFTRESET); + + if (omap_sham_wait(dd, SHA_REG_SYSSTATUS, + SHA_REG_SYSSTATUS_RESETDONE)) + return -ETIMEDOUT; + + dd->flags |= FLAGS_INIT; + } + } else { + omap_sham_write(dd, SHA_REG_DIGCNT, ctx->digcnt); + } + + omap_sham_write_mask(dd, SHA_REG_MASK, + SHA_REG_MASK_IT_EN | (dma ? SHA_REG_MASK_DMA_EN : 0), + SHA_REG_MASK_IT_EN | SHA_REG_MASK_DMA_EN); + /* + * Setting ALGO_CONST only for the first iteration + * and CLOSE_HASH only for the last one. + */ + if (ctx->flags & FLAGS_SHA1) + val |= SHA_REG_CTRL_ALGO; + if (!ctx->digcnt) + val |= SHA_REG_CTRL_ALGO_CONST; + if (final) + val |= SHA_REG_CTRL_CLOSE_HASH; + + mask = SHA_REG_CTRL_ALGO_CONST | SHA_REG_CTRL_CLOSE_HASH | + SHA_REG_CTRL_ALGO | SHA_REG_CTRL_LENGTH; + + omap_sham_write_mask(dd, SHA_REG_CTRL, val, mask); + + return 0; +} + +static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf, + size_t length, int final) +{ + struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); + int err, count, len32; + const u32 *buffer = (const u32 *)buf; + + dev_dbg(dd->dev, "xmit_cpu: digcnt: %d, length: %d, final: %d\n", + ctx->digcnt, length, final); + + err = omap_sham_write_ctrl(dd, length, final, 0); + if (err) + return err; + + if (omap_sham_wait(dd, SHA_REG_CTRL, SHA_REG_CTRL_INPUT_READY)) + return -ETIMEDOUT; + + ctx->digcnt += length; + + if (final) + ctx->flags |= FLAGS_FINAL; /* catch last interrupt */ + + len32 = DIV_ROUND_UP(length, sizeof(u32)); + + for (count = 0; count < len32; count++) + omap_sham_write(dd, SHA_REG_DIN(count), buffer[count]); + + return -EINPROGRESS; +} + +static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr, + size_t length, int final) +{ + struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); + int err, len32; + + dev_dbg(dd->dev, "xmit_dma: digcnt: %d, length: %d, final: %d\n", + ctx->digcnt, length, final); + + /* flush cache entries related to our page */ + if (dma_addr == ctx->dma_addr) + dma_sync_single_for_device(dd->dev, dma_addr, length, + DMA_TO_DEVICE); + + len32 = DIV_ROUND_UP(length, sizeof(u32)); + + omap_set_dma_transfer_params(dd->dma_lch, OMAP_DMA_DATA_TYPE_S32, len32, + 1, OMAP_DMA_SYNC_PACKET, dd->dma, OMAP_DMA_DST_SYNC); + + omap_set_dma_src_params(dd->dma_lch, 0, OMAP_DMA_AMODE_POST_INC, + dma_addr, 0, 0); + + err = omap_sham_write_ctrl(dd, length, final, 1); + if (err) + return err; + + ctx->digcnt += length; + + if (final) + ctx->flags |= FLAGS_FINAL; /* catch last interrupt */ + + dd->flags |= FLAGS_DMA_ACTIVE; + + omap_start_dma(dd->dma_lch); + + return -EINPROGRESS; +} + +static size_t omap_sham_append_buffer(struct omap_sham_reqctx *ctx, + const u8 *data, size_t length) +{ + size_t count = min(length, ctx->buflen - ctx->bufcnt); + + count = min(count, ctx->total); + if (count <= 0) + return 0; + memcpy(ctx->buffer + ctx->bufcnt, data, count); + ctx->bufcnt += count; + + return count; +} + +static size_t omap_sham_append_sg(struct omap_sham_reqctx *ctx) +{ + size_t count; + + while (ctx->sg) { + count = omap_sham_append_buffer(ctx, + sg_virt(ctx->sg) + ctx->offset, + ctx->sg->length - ctx->offset); + if (!count) + break; + ctx->offset += count; + ctx->total -= count; + if (ctx->offset == ctx->sg->length) { + ctx->sg = sg_next(ctx->sg); + if (ctx->sg) + ctx->offset = 0; + else + ctx->total = 0; + } + } + + return 0; +} + +static int omap_sham_update_dma_slow(struct omap_sham_dev *dd) +{ + struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); + unsigned int final; + size_t count; + + if (!ctx->total) + return 0; + + omap_sham_append_sg(ctx); + + final = (ctx->flags & FLAGS_FINUP) && !ctx->total; + + dev_dbg(dd->dev, "slow: bufcnt: %u, digcnt: %d, final: %d\n", + ctx->bufcnt, ctx->digcnt, final); + + if (final || (ctx->bufcnt == ctx->buflen && ctx->total)) { + count = ctx->bufcnt; + ctx->bufcnt = 0; + return omap_sham_xmit_dma(dd, ctx->dma_addr, count, final); + } + + return 0; +} + +static int omap_sham_update_dma_fast(struct omap_sham_dev *dd) +{ + struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); + unsigned int length; + + ctx->flags |= FLAGS_FAST; + + length = min(ctx->total, sg_dma_len(ctx->sg)); + ctx->total = length; + + if (!dma_map_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE)) { + dev_err(dd->dev, "dma_map_sg error\n"); + return -EINVAL; + } + + ctx->total -= length; + + return omap_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, 1); +} + +static int omap_sham_update_cpu(struct omap_sham_dev *dd) +{ + struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); + int bufcnt; + + omap_sham_append_sg(ctx); + bufcnt = ctx->bufcnt; + ctx->bufcnt = 0; + + return omap_sham_xmit_cpu(dd, ctx->buffer, bufcnt, 1); +} + +static int omap_sham_update_dma_stop(struct omap_sham_dev *dd) +{ + struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); + + omap_stop_dma(dd->dma_lch); + if (ctx->flags & FLAGS_FAST) + dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE); + + return 0; +} + +static void omap_sham_cleanup(struct ahash_request *req) +{ + struct omap_sham_reqctx *ctx = ahash_request_ctx(req); + struct omap_sham_dev *dd = ctx->dd; + unsigned long flags; + + spin_lock_irqsave(&dd->lock, flags); + if (ctx->flags & FLAGS_CLEAN) { + spin_unlock_irqrestore(&dd->lock, flags); + return; + } + ctx->flags |= FLAGS_CLEAN; + spin_unlock_irqrestore(&dd->lock, flags); + + if (ctx->digcnt) + clk_disable(dd->iclk); + + if (ctx->dma_addr) + dma_unmap_single(dd->dev, ctx->dma_addr, ctx->buflen, + DMA_TO_DEVICE); + + if (ctx->buffer) + free_page((unsigned long)ctx->buffer); + + dev_dbg(dd->dev, "digcnt: %d, bufcnt: %d\n", ctx->digcnt, ctx->bufcnt); +} + +static int omap_sham_init(struct ahash_request *req) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct omap_sham_ctx *tctx = crypto_ahash_ctx(tfm); + struct omap_sham_reqctx *ctx = ahash_request_ctx(req); + struct omap_sham_dev *dd = NULL, *tmp; + + spin_lock_bh(&sham.lock); + if (!tctx->dd) { + list_for_each_entry(tmp, &sham.dev_list, list) { + dd = tmp; + break; + } + tctx->dd = dd; + } else { + dd = tctx->dd; + } + spin_unlock_bh(&sham.lock); + + ctx->dd = dd; + + ctx->flags = 0; + + ctx->flags |= FLAGS_FIRST; + + dev_dbg(dd->dev, "init: digest size: %d\n", + crypto_ahash_digestsize(tfm)); + + if (crypto_ahash_digestsize(tfm) == SHA1_DIGEST_SIZE) + ctx->flags |= FLAGS_SHA1; + + ctx->bufcnt = 0; + ctx->digcnt = 0; + + ctx->buflen = PAGE_SIZE; + ctx->buffer = (void *)__get_free_page( + (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? + GFP_KERNEL : GFP_ATOMIC); + if (!ctx->buffer) + return -ENOMEM; + + ctx->dma_addr = dma_map_single(dd->dev, ctx->buffer, ctx->buflen, + DMA_TO_DEVICE); + if (dma_mapping_error(dd->dev, ctx->dma_addr)) { + dev_err(dd->dev, "dma %u bytes error\n", ctx->buflen); + free_page((unsigned long)ctx->buffer); + return -EINVAL; + } + + if (tctx->flags & FLAGS_HMAC) { + struct omap_sham_hmac_ctx *bctx = tctx->base; + + memcpy(ctx->buffer, bctx->ipad, SHA1_MD5_BLOCK_SIZE); + ctx->bufcnt = SHA1_MD5_BLOCK_SIZE; + ctx->flags |= FLAGS_HMAC; + } + + return 0; + +} + +static int omap_sham_update_req(struct omap_sham_dev *dd) +{ + struct ahash_request *req = dd->req; + struct omap_sham_reqctx *ctx = ahash_request_ctx(req); + int err; + + dev_dbg(dd->dev, "update_req: total: %u, digcnt: %d, finup: %d\n", + ctx->total, ctx->digcnt, (ctx->flags & FLAGS_FINUP) != 0); + + if (ctx->flags & FLAGS_CPU) + err = omap_sham_update_cpu(dd); + else if (ctx->flags & FLAGS_FAST) + err = omap_sham_update_dma_fast(dd); + else + err = omap_sham_update_dma_slow(dd); + + /* wait for dma completion before can take more data */ + dev_dbg(dd->dev, "update: err: %d, digcnt: %d\n", err, ctx->digcnt); + + return err; +} + +static int omap_sham_final_req(struct omap_sham_dev *dd) +{ + struct ahash_request *req = dd->req; + struct omap_sham_reqctx *ctx = ahash_request_ctx(req); + int err = 0, use_dma = 1; + + if (ctx->bufcnt <= 64) + /* faster to handle last block with cpu */ + use_dma = 0; + + if (use_dma) + err = omap_sham_xmit_dma(dd, ctx->dma_addr, ctx->bufcnt, 1); + else + err = omap_sham_xmit_cpu(dd, ctx->buffer, ctx->bufcnt, 1); + + ctx->bufcnt = 0; + + if (err != -EINPROGRESS) + omap_sham_cleanup(req); + + dev_dbg(dd->dev, "final_req: err: %d\n", err); + + return err; +} + +static int omap_sham_finish_req_hmac(struct ahash_request *req) +{ + struct omap_sham_ctx *tctx = crypto_tfm_ctx(req->base.tfm); + struct omap_sham_hmac_ctx *bctx = tctx->base; + int bs = crypto_shash_blocksize(bctx->shash); + int ds = crypto_shash_digestsize(bctx->shash); + struct { + struct shash_desc shash; + char ctx[crypto_shash_descsize(bctx->shash)]; + } desc; + + desc.shash.tfm = bctx->shash; + desc.shash.flags = 0; /* not CRYPTO_TFM_REQ_MAY_SLEEP */ + + return crypto_shash_init(&desc.shash) ?: + crypto_shash_update(&desc.shash, bctx->opad, bs) ?: + crypto_shash_finup(&desc.shash, req->result, ds, req->result); +} + +static void omap_sham_finish_req(struct ahash_request *req, int err) +{ + struct omap_sham_reqctx *ctx = ahash_request_ctx(req); + + if (!err) { + omap_sham_copy_hash(ctx->dd->req, 1); + if (ctx->flags & FLAGS_HMAC) + err = omap_sham_finish_req_hmac(req); + } + + if (ctx->flags & FLAGS_FINAL) + omap_sham_cleanup(req); + + clear_bit(FLAGS_BUSY, &ctx->dd->flags); + + if (req->base.complete) + req->base.complete(&req->base, err); +} + +static int omap_sham_handle_queue(struct omap_sham_dev *dd) +{ + struct crypto_async_request *async_req, *backlog; + struct omap_sham_reqctx *ctx; + struct ahash_request *req, *prev_req; + unsigned long flags; + int err = 0; + + if (test_and_set_bit(FLAGS_BUSY, &dd->flags)) + return 0; + + spin_lock_irqsave(&dd->lock, flags); + backlog = crypto_get_backlog(&dd->queue); + async_req = crypto_dequeue_request(&dd->queue); + if (!async_req) + clear_bit(FLAGS_BUSY, &dd->flags); + spin_unlock_irqrestore(&dd->lock, flags); + + if (!async_req) + return 0; + + if (backlog) + backlog->complete(backlog, -EINPROGRESS); + + req = ahash_request_cast(async_req); + + prev_req = dd->req; + dd->req = req; + + ctx = ahash_request_ctx(req); + + dev_dbg(dd->dev, "handling new req, op: %lu, nbytes: %d\n", + ctx->op, req->nbytes); + + if (req != prev_req && ctx->digcnt) + /* request has changed - restore hash */ + omap_sham_copy_hash(req, 0); + + if (ctx->op == OP_UPDATE) { + err = omap_sham_update_req(dd); + if (err != -EINPROGRESS && (ctx->flags & FLAGS_FINUP)) + /* no final() after finup() */ + err = omap_sham_final_req(dd); + } else if (ctx->op == OP_FINAL) { + err = omap_sham_final_req(dd); + } + + if (err != -EINPROGRESS) { + /* done_task will not finish it, so do it here */ + omap_sham_finish_req(req, err); + tasklet_schedule(&dd->queue_task); + } + + dev_dbg(dd->dev, "exit, err: %d\n", err); + + return err; +} + +static int omap_sham_enqueue(struct ahash_request *req, unsigned int op) +{ + struct omap_sham_reqctx *ctx = ahash_request_ctx(req); + struct omap_sham_ctx *tctx = crypto_tfm_ctx(req->base.tfm); + struct omap_sham_dev *dd = tctx->dd; + unsigned long flags; + int err; + + ctx->op = op; + + spin_lock_irqsave(&dd->lock, flags); + err = ahash_enqueue_request(&dd->queue, req); + spin_unlock_irqrestore(&dd->lock, flags); + + omap_sham_handle_queue(dd); + + return err; +} + +static int omap_sham_update(struct ahash_request *req) +{ + struct omap_sham_reqctx *ctx = ahash_request_ctx(req); + + if (!req->nbytes) + return 0; + + ctx->total = req->nbytes; + ctx->sg = req->src; + ctx->offset = 0; + + if (ctx->flags & FLAGS_FINUP) { + if ((ctx->digcnt + ctx->bufcnt + ctx->total) < 9) { + /* + * OMAP HW accel works only with buffers >= 9 + * will switch to bypass in final() + * final has the same request and data + */ + omap_sham_append_sg(ctx); + return 0; + } else if (ctx->bufcnt + ctx->total <= 64) { + ctx->flags |= FLAGS_CPU; + } else if (!ctx->bufcnt && sg_is_last(ctx->sg)) { + /* may be can use faster functions */ + int aligned = IS_ALIGNED((u32)ctx->sg->offset, + sizeof(u32)); + + if (aligned && (ctx->flags & FLAGS_FIRST)) + /* digest: first and final */ + ctx->flags |= FLAGS_FAST; + + ctx->flags &= ~FLAGS_FIRST; + } + } else if (ctx->bufcnt + ctx->total <= ctx->buflen) { + /* if not finaup -> not fast */ + omap_sham_append_sg(ctx); + return 0; + } + + return omap_sham_enqueue(req, OP_UPDATE); +} + +static int omap_sham_shash_digest(struct crypto_shash *shash, u32 flags, + const u8 *data, unsigned int len, u8 *out) +{ + struct { + struct shash_desc shash; + char ctx[crypto_shash_descsize(shash)]; + } desc; + + desc.shash.tfm = shash; + desc.shash.flags = flags & CRYPTO_TFM_REQ_MAY_SLEEP; + + return crypto_shash_digest(&desc.shash, data, len, out); +} + +static int omap_sham_final_shash(struct ahash_request *req) +{ + struct omap_sham_ctx *tctx = crypto_tfm_ctx(req->base.tfm); + struct omap_sham_reqctx *ctx = ahash_request_ctx(req); + + return omap_sham_shash_digest(tctx->fallback, req->base.flags, + ctx->buffer, ctx->bufcnt, req->result); +} + +static int omap_sham_final(struct ahash_request *req) +{ + struct omap_sham_reqctx *ctx = ahash_request_ctx(req); + int err = 0; + + ctx->flags |= FLAGS_FINUP; + + /* OMAP HW accel works only with buffers >= 9 */ + /* HMAC is always >= 9 because of ipad */ + if ((ctx->digcnt + ctx->bufcnt) < 9) + err = omap_sham_final_shash(req); + else if (ctx->bufcnt) + return omap_sham_enqueue(req, OP_FINAL); + + omap_sham_cleanup(req); + + return err; +} + +static int omap_sham_finup(struct ahash_request *req) +{ + struct omap_sham_reqctx *ctx = ahash_request_ctx(req); + int err1, err2; + + ctx->flags |= FLAGS_FINUP; + + err1 = omap_sham_update(req); + if (err1 == -EINPROGRESS) + return err1; + /* + * final() has to be always called to cleanup resources + * even if udpate() failed, except EINPROGRESS + */ + err2 = omap_sham_final(req); + + return err1 ?: err2; +} + +static int omap_sham_digest(struct ahash_request *req) +{ + return omap_sham_init(req) ?: omap_sham_finup(req); +} + +static int omap_sham_setkey(struct crypto_ahash *tfm, const u8 *key, + unsigned int keylen) +{ + struct omap_sham_ctx *tctx = crypto_ahash_ctx(tfm); + struct omap_sham_hmac_ctx *bctx = tctx->base; + int bs = crypto_shash_blocksize(bctx->shash); + int ds = crypto_shash_digestsize(bctx->shash); + int err, i; + err = crypto_shash_setkey(tctx->fallback, key, keylen); + if (err) + return err; + + if (keylen > bs) { + err = omap_sham_shash_digest(bctx->shash, + crypto_shash_get_flags(bctx->shash), + key, keylen, bctx->ipad); + if (err) + return err; + keylen = ds; + } else { + memcpy(bctx->ipad, key, keylen); + } + + memset(bctx->ipad + keylen, 0, bs - keylen); + memcpy(bctx->opad, bctx->ipad, bs); + + for (i = 0; i < bs; i++) { + bctx->ipad[i] ^= 0x36; + bctx->opad[i] ^= 0x5c; + } + + return err; +} + +static int omap_sham_cra_init_alg(struct crypto_tfm *tfm, const char *alg_base) +{ + struct omap_sham_ctx *tctx = crypto_tfm_ctx(tfm); + const char *alg_name = crypto_tfm_alg_name(tfm); + + /* Allocate a fallback and abort if it failed. */ + tctx->fallback = crypto_alloc_shash(alg_name, 0, + CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(tctx->fallback)) { + pr_err("omap-sham: fallback driver '%s' " + "could not be loaded.\n", alg_name); + return PTR_ERR(tctx->fallback); + } + + crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), + sizeof(struct omap_sham_reqctx)); + + if (alg_base) { + struct omap_sham_hmac_ctx *bctx = tctx->base; + tctx->flags |= FLAGS_HMAC; + bctx->shash = crypto_alloc_shash(alg_base, 0, + CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(bctx->shash)) { + pr_err("omap-sham: base driver '%s' " + "could not be loaded.\n", alg_base); + crypto_free_shash(tctx->fallback); + return PTR_ERR(bctx->shash); + } + + } + + return 0; +} + +static int omap_sham_cra_init(struct crypto_tfm *tfm) +{ + return omap_sham_cra_init_alg(tfm, NULL); +} + +static int omap_sham_cra_sha1_init(struct crypto_tfm *tfm) +{ + return omap_sham_cra_init_alg(tfm, "sha1"); +} + +static int omap_sham_cra_md5_init(struct crypto_tfm *tfm) +{ + return omap_sham_cra_init_alg(tfm, "md5"); +} + +static void omap_sham_cra_exit(struct crypto_tfm *tfm) +{ + struct omap_sham_ctx *tctx = crypto_tfm_ctx(tfm); + + crypto_free_shash(tctx->fallback); + tctx->fallback = NULL; + + if (tctx->flags & FLAGS_HMAC) { + struct omap_sham_hmac_ctx *bctx = tctx->base; + crypto_free_shash(bctx->shash); + } +} + +static struct ahash_alg algs[] = { +{ + .init = omap_sham_init, + .update = omap_sham_update, + .final = omap_sham_final, + .finup = omap_sham_finup, + .digest = omap_sham_digest, + .halg.digestsize = SHA1_DIGEST_SIZE, + .halg.base = { + .cra_name = "sha1", + .cra_driver_name = "omap-sha1", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA1_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct omap_sham_ctx), + .cra_alignmask = 0, + .cra_module = THIS_MODULE, + .cra_init = omap_sham_cra_init, + .cra_exit = omap_sham_cra_exit, + } +}, +{ + .init = omap_sham_init, + .update = omap_sham_update, + .final = omap_sham_final, + .finup = omap_sham_finup, + .digest = omap_sham_digest, + .halg.digestsize = MD5_DIGEST_SIZE, + .halg.base = { + .cra_name = "md5", + .cra_driver_name = "omap-md5", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA1_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct omap_sham_ctx), + .cra_alignmask = 0, + .cra_module = THIS_MODULE, + .cra_init = omap_sham_cra_init, + .cra_exit = omap_sham_cra_exit, + } +}, +{ + .init = omap_sham_init, + .update = omap_sham_update, + .final = omap_sham_final, + .finup = omap_sham_finup, + .digest = omap_sham_digest, + .setkey = omap_sham_setkey, + .halg.digestsize = SHA1_DIGEST_SIZE, + .halg.base = { + .cra_name = "hmac(sha1)", + .cra_driver_name = "omap-hmac-sha1", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA1_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct omap_sham_ctx) + + sizeof(struct omap_sham_hmac_ctx), + .cra_alignmask = 0, + .cra_module = THIS_MODULE, + .cra_init = omap_sham_cra_sha1_init, + .cra_exit = omap_sham_cra_exit, + } +}, +{ + .init = omap_sham_init, + .update = omap_sham_update, + .final = omap_sham_final, + .finup = omap_sham_finup, + .digest = omap_sham_digest, + .setkey = omap_sham_setkey, + .halg.digestsize = MD5_DIGEST_SIZE, + .halg.base = { + .cra_name = "hmac(md5)", + .cra_driver_name = "omap-hmac-md5", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = SHA1_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct omap_sham_ctx) + + sizeof(struct omap_sham_hmac_ctx), + .cra_alignmask = 0, + .cra_module = THIS_MODULE, + .cra_init = omap_sham_cra_md5_init, + .cra_exit = omap_sham_cra_exit, + } +} +}; + +static void omap_sham_done_task(unsigned long data) +{ + struct omap_sham_dev *dd = (struct omap_sham_dev *)data; + struct ahash_request *req = dd->req; + struct omap_sham_reqctx *ctx = ahash_request_ctx(req); + int ready = 1; + + if (ctx->flags & FLAGS_OUTPUT_READY) { + ctx->flags &= ~FLAGS_OUTPUT_READY; + ready = 1; + } + + if (dd->flags & FLAGS_DMA_ACTIVE) { + dd->flags &= ~FLAGS_DMA_ACTIVE; + omap_sham_update_dma_stop(dd); + omap_sham_update_dma_slow(dd); + } + + if (ready && !(dd->flags & FLAGS_DMA_ACTIVE)) { + dev_dbg(dd->dev, "update done\n"); + /* finish curent request */ + omap_sham_finish_req(req, 0); + /* start new request */ + omap_sham_handle_queue(dd); + } +} + +static void omap_sham_queue_task(unsigned long data) +{ + struct omap_sham_dev *dd = (struct omap_sham_dev *)data; + + omap_sham_handle_queue(dd); +} + +static irqreturn_t omap_sham_irq(int irq, void *dev_id) +{ + struct omap_sham_dev *dd = dev_id; + struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); + + if (!ctx) { + dev_err(dd->dev, "unknown interrupt.\n"); + return IRQ_HANDLED; + } + + if (unlikely(ctx->flags & FLAGS_FINAL)) + /* final -> allow device to go to power-saving mode */ + omap_sham_write_mask(dd, SHA_REG_CTRL, 0, SHA_REG_CTRL_LENGTH); + + omap_sham_write_mask(dd, SHA_REG_CTRL, SHA_REG_CTRL_OUTPUT_READY, + SHA_REG_CTRL_OUTPUT_READY); + omap_sham_read(dd, SHA_REG_CTRL); + + ctx->flags |= FLAGS_OUTPUT_READY; + tasklet_schedule(&dd->done_task); + + return IRQ_HANDLED; +} + +static void omap_sham_dma_callback(int lch, u16 ch_status, void *data) +{ + struct omap_sham_dev *dd = data; + + if (likely(lch == dd->dma_lch)) + tasklet_schedule(&dd->done_task); +} + +static int omap_sham_dma_init(struct omap_sham_dev *dd) +{ + int err; + + dd->dma_lch = -1; + + err = omap_request_dma(dd->dma, dev_name(dd->dev), + omap_sham_dma_callback, dd, &dd->dma_lch); + if (err) { + dev_err(dd->dev, "Unable to request DMA channel\n"); + return err; + } + omap_set_dma_dest_params(dd->dma_lch, 0, + OMAP_DMA_AMODE_CONSTANT, + dd->phys_base + SHA_REG_DIN(0), 0, 16); + + omap_set_dma_dest_burst_mode(dd->dma_lch, + OMAP_DMA_DATA_BURST_16); + + return 0; +} + +static void omap_sham_dma_cleanup(struct omap_sham_dev *dd) +{ + if (dd->dma_lch >= 0) { + omap_free_dma(dd->dma_lch); + dd->dma_lch = -1; + } +} + +static int __devinit omap_sham_probe(struct platform_device *pdev) +{ + struct omap_sham_dev *dd; + struct device *dev = &pdev->dev; + struct resource *res; + int err, i, j; + + dd = kzalloc(sizeof(struct omap_sham_dev), GFP_KERNEL); + if (dd == NULL) { + dev_err(dev, "unable to alloc data struct.\n"); + err = -ENOMEM; + goto data_err; + } + dd->dev = dev; + platform_set_drvdata(pdev, dd); + + INIT_LIST_HEAD(&dd->list); + spin_lock_init(&dd->lock); + tasklet_init(&dd->done_task, omap_sham_done_task, (unsigned long)dd); + tasklet_init(&dd->queue_task, omap_sham_queue_task, (unsigned long)dd); + crypto_init_queue(&dd->queue, OMAP_SHAM_QUEUE_LENGTH); + + dd->irq = -1; + + /* Get the base address */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "no MEM resource info\n"); + err = -ENODEV; + goto res_err; + } + dd->phys_base = res->start; + + /* Get the DMA */ + res = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!res) { + dev_err(dev, "no DMA resource info\n"); + err = -ENODEV; + goto res_err; + } + dd->dma = res->start; + + /* Get the IRQ */ + dd->irq = platform_get_irq(pdev, 0); + if (dd->irq < 0) { + dev_err(dev, "no IRQ resource info\n"); + err = dd->irq; + goto res_err; + } + + err = request_irq(dd->irq, omap_sham_irq, + IRQF_TRIGGER_LOW, dev_name(dev), dd); + if (err) { + dev_err(dev, "unable to request irq.\n"); + goto res_err; + } + + err = omap_sham_dma_init(dd); + if (err) + goto dma_err; + + /* Initializing the clock */ + dd->iclk = clk_get(dev, "ick"); + if (!dd->iclk) { + dev_err(dev, "clock intialization failed.\n"); + err = -ENODEV; + goto clk_err; + } + + dd->io_base = ioremap(dd->phys_base, SZ_4K); + if (!dd->io_base) { + dev_err(dev, "can't ioremap\n"); + err = -ENOMEM; + goto io_err; + } + + clk_enable(dd->iclk); + dev_info(dev, "hw accel on OMAP rev %u.%u\n", + (omap_sham_read(dd, SHA_REG_REV) & SHA_REG_REV_MAJOR) >> 4, + omap_sham_read(dd, SHA_REG_REV) & SHA_REG_REV_MINOR); + clk_disable(dd->iclk); + + spin_lock(&sham.lock); + list_add_tail(&dd->list, &sham.dev_list); + spin_unlock(&sham.lock); + + for (i = 0; i < ARRAY_SIZE(algs); i++) { + err = crypto_register_ahash(&algs[i]); + if (err) + goto err_algs; + } + + return 0; + +err_algs: + for (j = 0; j < i; j++) + crypto_unregister_ahash(&algs[j]); + iounmap(dd->io_base); +io_err: + clk_put(dd->iclk); +clk_err: + omap_sham_dma_cleanup(dd); +dma_err: + if (dd->irq >= 0) + free_irq(dd->irq, dd); +res_err: + kfree(dd); + dd = NULL; +data_err: + dev_err(dev, "initialization failed.\n"); + + return err; +} + +static int __devexit omap_sham_remove(struct platform_device *pdev) +{ + static struct omap_sham_dev *dd; + int i; + + dd = platform_get_drvdata(pdev); + if (!dd) + return -ENODEV; + spin_lock(&sham.lock); + list_del(&dd->list); + spin_unlock(&sham.lock); + for (i = 0; i < ARRAY_SIZE(algs); i++) + crypto_unregister_ahash(&algs[i]); + tasklet_kill(&dd->done_task); + tasklet_kill(&dd->queue_task); + iounmap(dd->io_base); + clk_put(dd->iclk); + omap_sham_dma_cleanup(dd); + if (dd->irq >= 0) + free_irq(dd->irq, dd); + kfree(dd); + dd = NULL; + + return 0; +} + +static struct platform_driver omap_sham_driver = { + .probe = omap_sham_probe, + .remove = omap_sham_remove, + .driver = { + .name = "omap-sham", + .owner = THIS_MODULE, + }, +}; + +static int __init omap_sham_mod_init(void) +{ + pr_info("loading %s driver\n", "omap-sham"); + + if (!cpu_class_is_omap2() || + omap_type() != OMAP2_DEVICE_TYPE_SEC) { + pr_err("Unsupported cpu\n"); + return -ENODEV; + } + + return platform_driver_register(&omap_sham_driver); +} + +static void __exit omap_sham_mod_exit(void) +{ + platform_driver_unregister(&omap_sham_driver); +} + +module_init(omap_sham_mod_init); +module_exit(omap_sham_mod_exit); + +MODULE_DESCRIPTION("OMAP SHA1/MD5 hw acceleration support."); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Dmitry Kasatkin"); -- cgit v1.2.3 From 5a25ad84e01173bb225285eb50f9af48ed1a7598 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Fri, 30 Apr 2010 15:48:26 -0500 Subject: mxc: Add generic USB HW initialization for MX51 This patch adds USB HW initializiation code to /plat-mxc/ehci.c. -Sets some specific PHY settings Renames mxc_set_usbcontrol to mxc_initialize_usb_hw. Adds new register bit defines for the USB HW on Freescale SoCs. This patch applies to 2.6.34-rc6. Signed-off-by: Dinh Nguyen Reviewed-by: Daniel Mack Signed-off-by: Sascha Hauer --- arch/arm/plat-mxc/ehci.c | 100 +++++++++++++++++++++++++++++- arch/arm/plat-mxc/include/mach/mxc_ehci.h | 14 ++++- drivers/usb/host/ehci-mxc.c | 4 +- 3 files changed, 113 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/arch/arm/plat-mxc/ehci.c b/arch/arm/plat-mxc/ehci.c index cb0b63874482..2a8646173c2f 100644 --- a/arch/arm/plat-mxc/ehci.c +++ b/arch/arm/plat-mxc/ehci.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2009 Daniel Mack + * Copyright (C) 2010 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -50,7 +51,26 @@ #define MX35_H1_TLL_BIT (1 << 5) #define MX35_H1_USBTE_BIT (1 << 4) -int mxc_set_usbcontrol(int port, unsigned int flags) +#define MXC_OTG_OFFSET 0 +#define MXC_H1_OFFSET 0x200 + +/* USB_CTRL */ +#define MXC_OTG_UCTRL_OWIE_BIT (1 << 27) /* OTG wakeup intr enable */ +#define MXC_OTG_UCTRL_OPM_BIT (1 << 24) /* OTG power mask */ +#define MXC_H1_UCTRL_H1UIE_BIT (1 << 12) /* Host1 ULPI interrupt enable */ +#define MXC_H1_UCTRL_H1WIE_BIT (1 << 11) /* HOST1 wakeup intr enable */ +#define MXC_H1_UCTRL_H1PM_BIT (1 << 8) /* HOST1 power mask */ + +/* USB_PHY_CTRL_FUNC */ +#define MXC_OTG_PHYCTRL_OC_DIS_BIT (1 << 8) /* OTG Disable Overcurrent Event */ +#define MXC_H1_OC_DIS_BIT (1 << 5) /* UH1 Disable Overcurrent Event */ + +#define MXC_USBCMD_OFFSET 0x140 + +/* USBCMD */ +#define MXC_UCMD_ITC_NO_THRESHOLD_MASK (~(0xff << 16)) /* Interrupt Threshold Control */ + +int mxc_initialize_usb_hw(int port, unsigned int flags) { unsigned int v; #ifdef CONFIG_ARCH_MX3 @@ -186,9 +206,85 @@ int mxc_set_usbcontrol(int port, unsigned int flags) return 0; } #endif /* CONFIG_MACH_MX27 */ +#ifdef CONFIG_ARCH_MX51 + if (cpu_is_mx51()) { + void __iomem *usb_base; + u32 usbotg_base; + u32 usbother_base; + int ret = 0; + + usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K); + + switch (port) { + case 0: /* OTG port */ + usbotg_base = usb_base + MXC_OTG_OFFSET; + break; + case 1: /* Host 1 port */ + usbotg_base = usb_base + MXC_H1_OFFSET; + break; + default: + printk(KERN_ERR"%s no such port %d\n", __func__, port); + ret = -ENOENT; + goto error; + } + usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET; + + switch (port) { + case 0: /*OTG port */ + if (flags & MXC_EHCI_INTERNAL_PHY) { + v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET); + + if (flags & MXC_EHCI_POWER_PINS_ENABLED) + v |= (MXC_OTG_PHYCTRL_OC_DIS_BIT | MXC_OTG_UCTRL_OPM_BIT); /* OC/USBPWR is not used */ + else + v &= ~(MXC_OTG_PHYCTRL_OC_DIS_BIT | MXC_OTG_UCTRL_OPM_BIT); /* OC/USBPWR is used */ + __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET); + + v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET); + if (flags & MXC_EHCI_WAKEUP_ENABLED) + v |= MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup enable */ + else + v &= ~MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup disable */ + __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET); + } + break; + case 1: /* Host 1 */ + /*Host ULPI */ + v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET); + if (flags & MXC_EHCI_WAKEUP_ENABLED) + v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);/* HOST1 wakeup/ULPI intr disable */ + else + v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);/* HOST1 wakeup/ULPI intr disable */ + + if (flags & MXC_EHCI_POWER_PINS_ENABLED) + v &= ~MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/ + else + v |= MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/ + __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET); + + v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET); + if (flags & MXC_EHCI_POWER_PINS_ENABLED) + v &= ~MXC_H1_OC_DIS_BIT; /* OC is used */ + else + v |= MXC_H1_OC_DIS_BIT; /* OC is not used */ + __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET); + + v = __raw_readl(usbotg_base + MXC_USBCMD_OFFSET); + if (flags & MXC_EHCI_ITC_NO_THRESHOLD) + /* Interrupt Threshold Control:Immediate (no threshold) */ + v &= MXC_UCMD_ITC_NO_THRESHOLD_MASK; + __raw_writel(v, usbotg_base + MXC_USBCMD_OFFSET); + break; + } + +error: + iounmap(usb_base); + return ret; + } +#endif printk(KERN_WARNING "%s() unable to setup USBCONTROL for this CPU\n", __func__); return -EINVAL; } -EXPORT_SYMBOL(mxc_set_usbcontrol); +EXPORT_SYMBOL(mxc_initialize_usb_hw); diff --git a/arch/arm/plat-mxc/include/mach/mxc_ehci.h b/arch/arm/plat-mxc/include/mach/mxc_ehci.h index 4b9b8368c0c0..7fc5f9946199 100644 --- a/arch/arm/plat-mxc/include/mach/mxc_ehci.h +++ b/arch/arm/plat-mxc/include/mach/mxc_ehci.h @@ -25,6 +25,18 @@ #define MXC_EHCI_INTERNAL_PHY (1 << 7) #define MXC_EHCI_IPPUE_DOWN (1 << 8) #define MXC_EHCI_IPPUE_UP (1 << 9) +#define MXC_EHCI_WAKEUP_ENABLED (1 << 10) +#define MXC_EHCI_ITC_NO_THRESHOLD (1 << 11) + +#define MXC_USBCTRL_OFFSET 0 +#define MXC_USB_PHY_CTR_FUNC_OFFSET 0x8 +#define MXC_USB_PHY_CTR_FUNC2_OFFSET 0xc + +#define MX5_USBOTHER_REGS_OFFSET 0x800 + +/* USB_PHY_CTRL_FUNC2*/ +#define MX5_USB_UTMI_PHYCTRL1_PLLDIV_MASK 0x3 +#define MX5_USB_UTMI_PHYCTRL1_PLLDIV_SHIFT 0 struct mxc_usbh_platform_data { int (*init)(struct platform_device *pdev); @@ -35,7 +47,7 @@ struct mxc_usbh_platform_data { struct otg_transceiver *otg; }; -int mxc_set_usbcontrol(int port, unsigned int flags); +int mxc_initialize_usb_hw(int port, unsigned int flags); #endif /* __INCLUDE_ASM_ARCH_MXC_EHCI_H */ diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index ead59f42e69b..544ccfd7056e 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -199,8 +199,8 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) writel(pdata->portsc, hcd->regs + PORTSC_OFFSET); mdelay(10); - /* setup USBCONTROL. */ - ret = mxc_set_usbcontrol(pdev->id, pdata->flags); + /* setup specific usb hw */ + ret = mxc_initialize_usb_hw(pdev->id, pdata->flags); if (ret < 0) goto err_init; -- cgit v1.2.3 From a0c36a1f0fbab42590dab3c13c10fa7d20e6c2cd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2009 22:41:15 -0300 Subject: i7core_edac: Add an EDAC memory controller driver for Nehalem chipsets This driver is meant to support i7 core/i7core extreme desktop processors and Xeon 35xx/55xx series with integrated memory controller. It is likely that it can be expanded in the future to work with other processor series based at the same Memory Controller design. For now, it has just a few MCH status reads. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/Kconfig | 7 + drivers/edac/Makefile | 1 + drivers/edac/i7core_edac.c | 462 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/pci_ids.h | 16 ++ 4 files changed, 486 insertions(+) create mode 100644 drivers/edac/i7core_edac.c (limited to 'drivers') diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 55c9c59b3f71..391ddbfb2a34 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -166,6 +166,13 @@ config EDAC_I5400 Support for error detection and correction the Intel i5400 MCH chipset (Seaburg). +config EDAC_I7CORE + tristate "Intel i7 Core (Nehalem) processors" + depends on EDAC_MM_EDAC && PCI && X86 + help + Support for error detection and correction the Intel + i7 Core (Nehalem) Integrated Memory Controller + config EDAC_I82860 tristate "Intel 82860" depends on EDAC_MM_EDAC && PCI && X86_32 diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile index bc5dc232a0fb..b9996195b233 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_EDAC_CPC925) += cpc925_edac.o obj-$(CONFIG_EDAC_I5000) += i5000_edac.o obj-$(CONFIG_EDAC_I5100) += i5100_edac.o obj-$(CONFIG_EDAC_I5400) += i5400_edac.o +obj-$(CONFIG_EDAC_I7CORE) += i7core_edac.o obj-$(CONFIG_EDAC_E7XXX) += e7xxx_edac.o obj-$(CONFIG_EDAC_E752X) += e752x_edac.o obj-$(CONFIG_EDAC_I82443BXGX) += i82443bxgx_edac.o diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c new file mode 100644 index 000000000000..7ecf15e66a3f --- /dev/null +++ b/drivers/edac/i7core_edac.c @@ -0,0 +1,462 @@ +/* Intel 7 core Memory Controller kernel module (Nehalem) + * + * This file may be distributed under the terms of the + * GNU General Public License version 2 only. + * + * Copyright (c) 2009 by: + * Mauro Carvalho Chehab + * + * Red Hat Inc. http://www.redhat.com + * + * Forked and adapted from the i5400_edac driver + * + * Based on the following public Intel datasheets: + * Intel Core i7 Processor Extreme Edition and Intel Core i7 Processor + * Datasheet, Volume 2: + * http://download.intel.com/design/processor/datashts/320835.pdf + * Intel Xeon Processor 5500 Series Datasheet Volume 2 + * http://www.intel.com/Assets/PDF/datasheet/321322.pdf + * also available at: + * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include "edac_core.h" + + +/* + * Alter this version for the module when modifications are made + */ +#define I7CORE_REVISION " Ver: 1.0.0 " __DATE__ +#define EDAC_MOD_STR "i7core_edac" + +/* HACK: temporary, just to enable all logs, for now */ +#undef debugf0 +#define debugf0(fmt, arg...) edac_printk(KERN_INFO, "i7core", fmt, ##arg) + +/* + * Debug macros + */ +#define i7core_printk(level, fmt, arg...) \ + edac_printk(level, "i7core", fmt, ##arg) + +#define i7core_mc_printk(mci, level, fmt, arg...) \ + edac_mc_chipset_printk(mci, level, "i7core", fmt, ##arg) + +/* + * i7core Memory Controller Registers + */ + + /* OFFSETS for Device 3 Function 0 */ + +#define MC_CONTROL 0x48 +#define MC_STATUS 0x4c +#define MC_MAX_DOD 0x64 + + /* OFFSETS for Devices 4,5 and 6 Function 0 */ + +#define MC_CHANNEL_ADDR_MATCH 0xf0 + +#define MC_MASK_DIMM (1 << 41) +#define MC_MASK_RANK (1 << 40) +#define MC_MASK_BANK (1 << 39) +#define MC_MASK_PAGE (1 << 38) +#define MC_MASK_COL (1 << 37) + +/* + * i7core structs + */ + +#define NUM_CHANS 3 +#define NUM_FUNCS 1 + +struct i7core_info { + u32 mc_control; + u32 mc_status; + u32 max_dod; +}; + +struct i7core_pvt { + struct pci_dev *pci_mcr; /* Dev 3:0 */ + struct pci_dev *pci_ch[NUM_CHANS][NUM_FUNCS]; + struct i7core_info info; +}; + +/* Device name and register DID (Device ID) */ +struct i7core_dev_info { + const char *ctl_name; /* name for this device */ + u16 fsb_mapping_errors; /* DID for the branchmap,control */ +}; + +static int chan_pci_ids[NUM_CHANS] = { + PCI_DEVICE_ID_INTEL_I7_MC_CH0_CTRL, /* Dev 4 */ + PCI_DEVICE_ID_INTEL_I7_MC_CH1_CTRL, /* Dev 5 */ + PCI_DEVICE_ID_INTEL_I7_MC_CH2_CTRL, /* Dev 6 */ +}; + +/* Table of devices attributes supported by this driver */ +static const struct i7core_dev_info i7core_devs[] = { + { + .ctl_name = "i7 Core", + .fsb_mapping_errors = PCI_DEVICE_ID_INTEL_I7_MCR, + }, +}; + +static struct edac_pci_ctl_info *i7core_pci; + +/**************************************************************************** + Anciliary status routines + ****************************************************************************/ + + /* MC_CONTROL bits */ +#define CH2_ACTIVE(pvt) ((pvt)->info.mc_control & 1 << 10) +#define CH1_ACTIVE(pvt) ((pvt)->info.mc_control & 1 << 9) +#define CH0_ACTIVE(pvt) ((pvt)->info.mc_control & 1 << 8) +#define ECCx8(pvt) ((pvt)->info.mc_control & 1 << 1) + + /* MC_STATUS bits */ +#define ECC_ENABLED(pvt) ((pvt)->info.mc_status & 1 << 3) +#define CH2_DISABLED(pvt) ((pvt)->info.mc_status & 1 << 2) +#define CH1_DISABLED(pvt) ((pvt)->info.mc_status & 1 << 1) +#define CH0_DISABLED(pvt) ((pvt)->info.mc_status & 1 << 0) + + /* MC_MAX_DOD read functions */ +static inline int maxnumdimms(struct i7core_pvt *pvt) +{ + return (pvt->info.max_dod & 0x3) + 1; +} + +static inline int maxnumrank(struct i7core_pvt *pvt) +{ + static int ranks[4] = { 1, 2, 4, -EINVAL }; + + return ranks[(pvt->info.max_dod >> 2) & 0x3]; +} + +static inline int maxnumbank(struct i7core_pvt *pvt) +{ + static int banks[4] = { 4, 8, 16, -EINVAL }; + + return banks[(pvt->info.max_dod >> 4) & 0x3]; +} + +static inline int maxnumrow(struct i7core_pvt *pvt) +{ + static int rows[8] = { + 1 << 12, 1 << 13, 1 << 14, 1 << 15, + 1 << 16, -EINVAL, -EINVAL, -EINVAL, + }; + + return rows[((pvt->info.max_dod >> 6) & 0x7)]; +} + +static inline int maxnumcol(struct i7core_pvt *pvt) +{ + static int cols[8] = { + 1 << 10, 1 << 11, 1 << 12, -EINVAL, + }; + return cols[((pvt->info.max_dod >> 9) & 0x3) << 12]; +} + +/**************************************************************************** + Memory check routines + ****************************************************************************/ +static int get_dimm_config(struct mem_ctl_info *mci) +{ + struct i7core_pvt *pvt = mci->pvt_info; + + pci_read_config_dword(pvt->pci_mcr, MC_CONTROL, &pvt->info.mc_control); + pci_read_config_dword(pvt->pci_mcr, MC_STATUS, &pvt->info.mc_status); + pci_read_config_dword(pvt->pci_mcr, MC_MAX_DOD, &pvt->info.max_dod); + + debugf0("Channels active [%c][%c][%c] - enabled [%c][%c][%c]\n", + CH0_ACTIVE(pvt)?'0':'-', + CH1_ACTIVE(pvt)?'1':'-', + CH2_ACTIVE(pvt)?'2':'-', + CH0_DISABLED(pvt)?'-':'0', + CH1_DISABLED(pvt)?'-':'1', + CH2_DISABLED(pvt)?'-':'2'); + + if (ECC_ENABLED(pvt)) + debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt)?8:4); + else + debugf0("ECC disabled\n"); + + /* FIXME: need to handle the error codes */ + debugf0("DOD Maximum limits: DIMMS: %d, %d-ranked, %d-banked\n", + maxnumdimms(pvt), maxnumrank(pvt), maxnumbank(pvt)); + debugf0("DOD Maximum rows x colums = 0x%x x 0x%x\n", + maxnumrow(pvt), maxnumcol(pvt)); + + return 0; +} + +/**************************************************************************** + Device initialization routines: put/get, init/exit + ****************************************************************************/ + +/* + * i7core_put_devices 'put' all the devices that we have + * reserved via 'get' + */ +static void i7core_put_devices(struct mem_ctl_info *mci) +{ + struct i7core_pvt *pvt = mci->pvt_info; + int i, n; + + pci_dev_put(pvt->pci_mcr); + + /* Release all PCI device functions at MTR channel controllers */ + for (i = 0; i < NUM_CHANS; i++) + for (n = 0; n < NUM_FUNCS; n++) + pci_dev_put(pvt->pci_ch[i][n]); +} + +/* + * i7core_get_devices Find and perform 'get' operation on the MCH's + * device/functions we want to reference for this driver + * + * Need to 'get' device 16 func 1 and func 2 + */ +static int i7core_get_devices(struct mem_ctl_info *mci, int dev_idx) +{ + struct i7core_pvt *pvt; + struct pci_dev *pdev; + int i, n, func; + + pvt = mci->pvt_info; + memset(pvt, 0, sizeof(*pvt)); + + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7_MCR, + NULL); + if (!pdev) { + i7core_printk(KERN_ERR, + "Couldn't get PCI ID %04x:%04x function 0\n", + PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7_MCR); + return -ENODEV; + } + pvt->pci_mcr=pdev; + + /* Get dimm basic config */ + get_dimm_config(mci); + + /* Retrieve all needed functions at MTR channel controllers */ + for (i = 0; i < NUM_CHANS; i++) { + pdev = NULL; + for (n = 0; n < NUM_FUNCS; n++) { + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, + chan_pci_ids[i], pdev); + if (!pdev) { + /* End of list, leave */ + i7core_printk(KERN_ERR, + "Device not found: PCI ID %04x:%04x " + "found only %d functions " + "(broken BIOS?)\n", + PCI_VENDOR_ID_INTEL, + chan_pci_ids[i], n); + i7core_put_devices(mci); + return -ENODEV; + } + func = PCI_FUNC(pdev->devfn); + pvt->pci_ch[i][func] = pdev; + } + } + i7core_printk(KERN_INFO, "Driver loaded.\n"); + + return 0; +} + +/* + * i7core_probe Probe for ONE instance of device to see if it is + * present. + * return: + * 0 for FOUND a device + * < 0 for error code + */ +static int __devinit i7core_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + struct mem_ctl_info *mci; + struct i7core_pvt *pvt; + int rc; + int num_channels; + int num_csrows; + int num_dimms_per_channel; + int dev_idx = id->driver_data; + + if (dev_idx >= ARRAY_SIZE(i7core_devs)) + return -EINVAL; + + /* wake up device */ + rc = pci_enable_device(pdev); + if (rc == -EIO) + return rc; + + debugf0("MC: " __FILE__ ": %s(), pdev bus %u dev=0x%x fn=0x%x\n", + __func__, + pdev->bus->number, + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); + + /* We only are looking for func 0 of the set */ + if (PCI_FUNC(pdev->devfn) != 0) + return -ENODEV; + + num_channels = NUM_CHANS; + + /* FIXME: FAKE data, since we currently don't now how to get this */ + num_dimms_per_channel = 4; + num_csrows = num_dimms_per_channel; + + /* allocate a new MC control structure */ + mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0); + if (mci == NULL) + return -ENOMEM; + + debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); + + mci->dev = &pdev->dev; /* record ptr to the generic device */ + dev_set_drvdata(mci->dev, mci); + + pvt = mci->pvt_info; +// pvt->system_address = pdev; /* Record this device in our private */ +// pvt->maxch = num_channels; +// pvt->maxdimmperch = num_dimms_per_channel; + + /* 'get' the pci devices we want to reserve for our use */ + if (i7core_get_devices(mci, dev_idx)) + goto fail0; + + mci->mc_idx = 0; + mci->mtype_cap = MEM_FLAG_FB_DDR2; /* FIXME: it uses DDR3 */ + mci->edac_ctl_cap = EDAC_FLAG_NONE; + mci->edac_cap = EDAC_FLAG_NONE; + mci->mod_name = "i7core_edac.c"; + mci->mod_ver = I7CORE_REVISION; + mci->ctl_name = i7core_devs[dev_idx].ctl_name; + mci->dev_name = pci_name(pdev); + mci->ctl_page_to_phys = NULL; + + /* add this new MC control structure to EDAC's list of MCs */ + if (edac_mc_add_mc(mci)) { + debugf0("MC: " __FILE__ + ": %s(): failed edac_mc_add_mc()\n", __func__); + /* FIXME: perhaps some code should go here that disables error + * reporting if we just enabled it + */ + goto fail1; + } + + /* allocating generic PCI control info */ + i7core_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR); + if (!i7core_pci) { + printk(KERN_WARNING + "%s(): Unable to create PCI control\n", + __func__); + printk(KERN_WARNING + "%s(): PCI error report via EDAC not setup\n", + __func__); + } + + return 0; + +fail1: + i7core_put_devices(mci); + +fail0: + edac_mc_free(mci); + return -ENODEV; +} + +/* + * i7core_remove destructor for one instance of device + * + */ +static void __devexit i7core_remove(struct pci_dev *pdev) +{ + struct mem_ctl_info *mci; + + debugf0(__FILE__ ": %s()\n", __func__); + + if (i7core_pci) + edac_pci_release_generic_ctl(i7core_pci); + + mci = edac_mc_del_mc(&pdev->dev); + if (!mci) + return; + + /* retrieve references to resources, and free those resources */ + i7core_put_devices(mci); + + edac_mc_free(mci); +} + +/* + * pci_device_id table for which devices we are looking for + * + * The "E500P" device is the first device supported. + */ +static const struct pci_device_id i7core_pci_tbl[] __devinitdata = { + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7_MCR)}, + {0,} /* 0 terminated list. */ +}; + +MODULE_DEVICE_TABLE(pci, i7core_pci_tbl); + +/* + * i7core_driver pci_driver structure for this module + * + */ +static struct pci_driver i7core_driver = { + .name = "i7core_edac", + .probe = i7core_probe, + .remove = __devexit_p(i7core_remove), + .id_table = i7core_pci_tbl, +}; + +/* + * i7core_init Module entry function + * Try to initialize this module for its devices + */ +static int __init i7core_init(void) +{ + int pci_rc; + + debugf2("MC: " __FILE__ ": %s()\n", __func__); + + /* Ensure that the OPSTATE is set correctly for POLL or NMI */ + opstate_init(); + + pci_rc = pci_register_driver(&i7core_driver); + + return (pci_rc < 0) ? pci_rc : 0; +} + +/* + * i7core_exit() Module exit function + * Unregister the driver + */ +static void __exit i7core_exit(void) +{ + debugf2("MC: " __FILE__ ": %s()\n", __func__); + pci_unregister_driver(&i7core_driver); +} + +module_init(i7core_init); +module_exit(i7core_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); +MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)"); +MODULE_DESCRIPTION("MC Driver for Intel i7 Core memory controllers - " + I7CORE_REVISION); + +module_param(edac_op_state, int, 0444); +MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI"); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 9f688d243b86..c5dd0994bd7c 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2532,6 +2532,22 @@ #define PCI_DEVICE_ID_INTEL_ICH9_6 0x2930 #define PCI_DEVICE_ID_INTEL_ICH9_7 0x2916 #define PCI_DEVICE_ID_INTEL_ICH9_8 0x2918 +#define PCI_DEVICE_ID_INTEL_I7_MCR 0x2c18 +#define PCI_DEVICE_ID_INTEL_I7_MC_TAD 0x2c19 +#define PCI_DEVICE_ID_INTEL_I7_MC_RAS 0x2c1a +#define PCI_DEVICE_ID_INTEL_I7_MC_TEST 0x2c1c +#define PCI_DEVICE_ID_INTEL_I7_MC_CH0_CTRL 0x2c20 +#define PCI_DEVICE_ID_INTEL_I7_MC_CH0_ADDR 0x2c21 +#define PCI_DEVICE_ID_INTEL_I7_MC_CH0_RANK 0x2c22 +#define PCI_DEVICE_ID_INTEL_I7_MC_CH0_TC 0x2c23 +#define PCI_DEVICE_ID_INTEL_I7_MC_CH1_CTRL 0x2c28 +#define PCI_DEVICE_ID_INTEL_I7_MC_CH1_ADDR 0x2c29 +#define PCI_DEVICE_ID_INTEL_I7_MC_CH1_RANK 0x2c2a +#define PCI_DEVICE_ID_INTEL_I7_MC_CH1_TC 0x2c2b +#define PCI_DEVICE_ID_INTEL_I7_MC_CH2_CTRL 0x2c30 +#define PCI_DEVICE_ID_INTEL_I7_MC_CH2_ADDR 0x2c31 +#define PCI_DEVICE_ID_INTEL_I7_MC_CH2_RANK 0x2c32 +#define PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC 0x2c33 #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340 #define PCI_DEVICE_ID_INTEL_IOAT_TBG4 0x3429 #define PCI_DEVICE_ID_INTEL_IOAT_TBG5 0x342a -- cgit v1.2.3 From 194a40feabb7cab38911a357c86e968e98024281 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2009 22:48:28 -0300 Subject: i7core_edac: Add error insertion code for Nehalem Implements set_inject_error() with the low-level code needed to inject memory errors at Nehalem, and adds some sysfs nodes to allow error injection The next patch will add an API for error injection. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 427 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 419 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 7ecf15e66a3f..b590f8468693 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -20,7 +20,6 @@ * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf */ - #include #include #include @@ -64,12 +63,16 @@ /* OFFSETS for Devices 4,5 and 6 Function 0 */ #define MC_CHANNEL_ADDR_MATCH 0xf0 - -#define MC_MASK_DIMM (1 << 41) -#define MC_MASK_RANK (1 << 40) -#define MC_MASK_BANK (1 << 39) -#define MC_MASK_PAGE (1 << 38) -#define MC_MASK_COL (1 << 37) +#define MC_CHANNEL_ERROR_MASK 0xf8 +#define MC_CHANNEL_ERROR_INJECT 0xfc + #define INJECT_ADDR_PARITY 0x10 + #define INJECT_ECC 0x08 + #define MASK_CACHELINE 0x06 + #define MASK_FULL_CACHELINE 0x06 + #define MASK_MSB32_CACHELINE 0x04 + #define MASK_LSB32_CACHELINE 0x02 + #define NO_MASK_CACHELINE 0x00 + #define REPEAT_EN 0x01 /* * i7core structs @@ -84,10 +87,23 @@ struct i7core_info { u32 max_dod; }; + +struct i7core_inject { + int enable; + + u32 section; + u32 type; + u32 eccmask; + + /* Error address mask */ + int channel, dimm, rank, bank, page, col; +}; + struct i7core_pvt { struct pci_dev *pci_mcr; /* Dev 3:0 */ struct pci_dev *pci_ch[NUM_CHANS][NUM_FUNCS]; struct i7core_info info; + struct i7core_inject inject; }; /* Device name and register DID (Device ID) */ @@ -166,6 +182,7 @@ static inline int maxnumcol(struct i7core_pvt *pvt) return cols[((pvt->info.max_dod >> 9) & 0x3) << 12]; } + /**************************************************************************** Memory check routines ****************************************************************************/ @@ -199,6 +216,390 @@ static int get_dimm_config(struct mem_ctl_info *mci) return 0; } +/**************************************************************************** + Error insertion routines + ****************************************************************************/ + +/* The i7core has independent error injection features per channel. + However, to have a simpler code, we don't allow enabling error injection + on more than one channel. + Also, since a change at an inject parameter will be applied only at enable, + we're disabling error injection on all write calls to the sysfs nodes that + controls the error code injection. + */ +static void disable_inject(struct mem_ctl_info *mci) +{ + struct i7core_pvt *pvt = mci->pvt_info; + + pvt->inject.enable = 0; + + pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0], + MC_CHANNEL_ERROR_MASK, 0); +} + +/* + * i7core inject inject.section + * + * accept and store error injection inject.section value + * bit 0 - refers to the lower 32-byte half cacheline + * bit 1 - refers to the upper 32-byte half cacheline + */ +static ssize_t i7core_inject_section_store(struct mem_ctl_info *mci, + const char *data, size_t count) +{ + struct i7core_pvt *pvt = mci->pvt_info; + unsigned long value; + int rc; + + if (pvt->inject.enable) + disable_inject(mci); + + rc = strict_strtoul(data, 10, &value); + if ((rc < 0) || (value > 3)) + return 0; + + pvt->inject.section = (u32) value; + return count; +} + +static ssize_t i7core_inject_section_show(struct mem_ctl_info *mci, + char *data) +{ + struct i7core_pvt *pvt = mci->pvt_info; + return sprintf(data, "0x%08x\n", pvt->inject.section); +} + +/* + * i7core inject.type + * + * accept and store error injection inject.section value + * bit 0 - repeat enable - Enable error repetition + * bit 1 - inject ECC error + * bit 2 - inject parity error + */ +static ssize_t i7core_inject_type_store(struct mem_ctl_info *mci, + const char *data, size_t count) +{ + struct i7core_pvt *pvt = mci->pvt_info; + unsigned long value; + int rc; + + if (pvt->inject.enable) + disable_inject(mci); + + rc = strict_strtoul(data, 10, &value); + if ((rc < 0) || (value > 7)) + return 0; + + pvt->inject.type = (u32) value; + return count; +} + +static ssize_t i7core_inject_type_show(struct mem_ctl_info *mci, + char *data) +{ + struct i7core_pvt *pvt = mci->pvt_info; + return sprintf(data, "0x%08x\n", pvt->inject.type); +} + +/* + * i7core_inject_inject.eccmask_store + * + * The type of error (UE/CE) will depend on the inject.eccmask value: + * Any bits set to a 1 will flip the corresponding ECC bit + * Correctable errors can be injected by flipping 1 bit or the bits within + * a symbol pair (2 consecutive aligned 8-bit pairs - i.e. 7:0 and 15:8 or + * 23:16 and 31:24). Flipping bits in two symbol pairs will cause an + * uncorrectable error to be injected. + */ +static ssize_t i7core_inject_eccmask_store(struct mem_ctl_info *mci, + const char *data, size_t count) +{ + struct i7core_pvt *pvt = mci->pvt_info; + unsigned long value; + int rc; + + if (pvt->inject.enable) + disable_inject(mci); + + rc = strict_strtoul(data, 10, &value); + if (rc < 0) + return 0; + + pvt->inject.eccmask = (u32) value; + return count; +} + +static ssize_t i7core_inject_eccmask_show(struct mem_ctl_info *mci, + char *data) +{ + struct i7core_pvt *pvt = mci->pvt_info; + return sprintf(data, "0x%08x\n", pvt->inject.eccmask); +} + +/* + * i7core_addrmatch + * + * The type of error (UE/CE) will depend on the inject.eccmask value: + * Any bits set to a 1 will flip the corresponding ECC bit + * Correctable errors can be injected by flipping 1 bit or the bits within + * a symbol pair (2 consecutive aligned 8-bit pairs - i.e. 7:0 and 15:8 or + * 23:16 and 31:24). Flipping bits in two symbol pairs will cause an + * uncorrectable error to be injected. + */ +static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci, + const char *data, size_t count) +{ + struct i7core_pvt *pvt = mci->pvt_info; + char *cmd, *val; + long value; + int rc; + + if (pvt->inject.enable) + disable_inject(mci); + + do { + cmd = strsep((char **) &data, ":"); + if (!cmd) + break; + val = strsep((char **) &data, " \n\t"); + if (!val) + return cmd - data; + + if (!strcasecmp(val,"any")) + value = -1; + else { + rc = strict_strtol(val, 10, &value); + if ((rc < 0) || (value < 0)) + return cmd - data; + } + + if (!strcasecmp(cmd,"channel")) { + if (value < 3) + pvt->inject.channel = value; + else + return cmd - data; + } else if (!strcasecmp(cmd,"dimm")) { + if (value < 4) + pvt->inject.dimm = value; + else + return cmd - data; + } else if (!strcasecmp(cmd,"rank")) { + if (value < 4) + pvt->inject.rank = value; + else + return cmd - data; + } else if (!strcasecmp(cmd,"bank")) { + if (value < 4) + pvt->inject.bank = value; + else + return cmd - data; + } else if (!strcasecmp(cmd,"page")) { + if (value <= 0xffff) + pvt->inject.page = value; + else + return cmd - data; + } else if (!strcasecmp(cmd,"col") || + !strcasecmp(cmd,"column")) { + if (value <= 0x3fff) + pvt->inject.col = value; + else + return cmd - data; + } + } while (1); + + return count; +} + +static ssize_t i7core_inject_addrmatch_show(struct mem_ctl_info *mci, + char *data) +{ + struct i7core_pvt *pvt = mci->pvt_info; + char channel[4], dimm[4], bank[4], rank[4], page[7], col[7]; + + if (pvt->inject.channel < 0) + sprintf(channel, "any"); + else + sprintf(channel, "%d", pvt->inject.channel); + if (pvt->inject.dimm < 0) + sprintf(dimm, "any"); + else + sprintf(dimm, "%d", pvt->inject.dimm); + if (pvt->inject.bank < 0) + sprintf(bank, "any"); + else + sprintf(bank, "%d", pvt->inject.bank); + if (pvt->inject.rank < 0) + sprintf(rank, "any"); + else + sprintf(rank, "%d", pvt->inject.rank); + if (pvt->inject.page < 0) + sprintf(page, "any"); + else + sprintf(page, "0x%04x", pvt->inject.page); + if (pvt->inject.col < 0) + sprintf(col, "any"); + else + sprintf(col, "0x%04x", pvt->inject.col); + + return sprintf(data, "channel: %s\ndimm: %s\nbank: %s\n" + "rank: %s\npage: %s\ncolumn: %s\n", + channel, dimm, bank, rank, page, col); +} + +/* + * This routine prepares the Memory Controller for error injection. + * The error will be injected when some process tries to write to the + * memory that matches the given criteria. + * The criteria can be set in terms of a mask where dimm, rank, bank, page + * and col can be specified. + * A -1 value for any of the mask items will make the MCU to ignore + * that matching criteria for error injection. + * + * It should be noticed that the error will only happen after a write operation + * on a memory that matches the condition. if REPEAT_EN is not enabled at + * inject mask, then it will produce just one error. Otherwise, it will repeat + * until the injectmask would be cleaned. + * + * FIXME: This routine assumes that MAXNUMDIMMS value of MC_MAX_DOD + * is reliable enough to check if the MC is using the + * three channels. However, this is not clear at the datasheet. + */ +static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, + const char *data, size_t count) +{ + struct i7core_pvt *pvt = mci->pvt_info; + u32 injectmask; + u64 mask = 0; + int rc; + long enable; + + rc = strict_strtoul(data, 10, &enable); + if ((rc < 0)) + return 0; + + if (enable) { + pvt->inject.enable = 1; + } else { + disable_inject(mci); + return count; + } + + /* Sets pvt->inject.dimm mask */ + if (pvt->inject.dimm < 0) + mask |= 1l << 41; + else { + if (maxnumdimms(pvt) > 2) + mask |= (pvt->inject.dimm & 0x3l) << 35; + else + mask |= (pvt->inject.dimm & 0x1l) << 36; + } + + /* Sets pvt->inject.rank mask */ + if (pvt->inject.rank < 0) + mask |= 1l << 40; + else { + if (maxnumdimms(pvt) > 2) + mask |= (pvt->inject.rank & 0x1l) << 34; + else + mask |= (pvt->inject.rank & 0x3l) << 34; + } + + /* Sets pvt->inject.bank mask */ + if (pvt->inject.bank < 0) + mask |= 1l << 39; + else + mask |= (pvt->inject.bank & 0x15l) << 30; + + /* Sets pvt->inject.page mask */ + if (pvt->inject.page < 0) + mask |= 1l << 38; + else + mask |= (pvt->inject.page & 0xffffl) << 14; + + /* Sets pvt->inject.column mask */ + if (pvt->inject.col < 0) + mask |= 1l << 37; + else + mask |= (pvt->inject.col & 0x3fffl); + + pci_write_config_qword(pvt->pci_ch[pvt->inject.channel][0], + MC_CHANNEL_ADDR_MATCH, mask); + + pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0], + MC_CHANNEL_ERROR_MASK, pvt->inject.eccmask); + + /* + * bit 0: REPEAT_EN + * bits 1-2: MASK_HALF_CACHELINE + * bit 3: INJECT_ECC + * bit 4: INJECT_ADDR_PARITY + */ + + injectmask = (pvt->inject.type & 1) && + (pvt->inject.section & 0x3) << 1 && + (pvt->inject.type & 0x6) << (3 - 1); + + pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0], + MC_CHANNEL_ERROR_MASK, injectmask); + + + debugf0("Error inject addr match 0x%016llx, ecc 0x%08x, inject 0x%08x\n", + mask, pvt->inject.eccmask, injectmask); + + return count; +} + +static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci, + char *data) +{ + struct i7core_pvt *pvt = mci->pvt_info; + return sprintf(data, "%d\n", pvt->inject.enable); +} + +/* + * Sysfs struct + */ +static struct mcidev_sysfs_attribute i7core_inj_attrs[] = { + + { + .attr = { + .name = "inject_section", + .mode = (S_IRUGO | S_IWUSR) + }, + .show = i7core_inject_section_show, + .store = i7core_inject_section_store, + }, { + .attr = { + .name = "inject_type", + .mode = (S_IRUGO | S_IWUSR) + }, + .show = i7core_inject_type_show, + .store = i7core_inject_type_store, + }, { + .attr = { + .name = "inject_eccmask", + .mode = (S_IRUGO | S_IWUSR) + }, + .show = i7core_inject_eccmask_show, + .store = i7core_inject_eccmask_store, + }, { + .attr = { + .name = "inject_addrmatch", + .mode = (S_IRUGO | S_IWUSR) + }, + .show = i7core_inject_addrmatch_show, + .store = i7core_inject_addrmatch_store, + }, { + .attr = { + .name = "inject_enable", + .mode = (S_IRUGO | S_IWUSR) + }, + .show = i7core_inject_enable_show, + .store = i7core_inject_enable_store, + }, +}; + /**************************************************************************** Device initialization routines: put/get, init/exit ****************************************************************************/ @@ -322,10 +723,11 @@ static int __devinit i7core_probe(struct pci_dev *pdev, debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); - mci->dev = &pdev->dev; /* record ptr to the generic device */ + mci->dev = &pdev->dev; /* record ptr to the generic device */ dev_set_drvdata(mci->dev, mci); pvt = mci->pvt_info; + // pvt->system_address = pdev; /* Record this device in our private */ // pvt->maxch = num_channels; // pvt->maxdimmperch = num_dimms_per_channel; @@ -343,6 +745,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, mci->ctl_name = i7core_devs[dev_idx].ctl_name; mci->dev_name = pci_name(pdev); mci->ctl_page_to_phys = NULL; + mci->mc_driver_sysfs_attributes = i7core_inj_attrs; /* add this new MC control structure to EDAC's list of MCs */ if (edac_mc_add_mc(mci)) { @@ -365,6 +768,14 @@ static int __devinit i7core_probe(struct pci_dev *pdev, __func__); } + /* Default error mask is any memory */ + pvt->inject.channel = -1; + pvt->inject.dimm = -1; + pvt->inject.rank = -1; + pvt->inject.bank = -1; + pvt->inject.page = -1; + pvt->inject.col = -1; + return 0; fail1: -- cgit v1.2.3 From 0b2b7b7ec06ce615acd11374bf9a512e166dabb0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2009 22:48:29 -0300 Subject: i7core_edac: Add more status functions to EDAC driver This patch were co-authored with Aristeu Rozanski. Signed-off-by: Aristeu Sergio Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 114 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 95 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index b590f8468693..da40730bf9c9 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -62,6 +62,15 @@ /* OFFSETS for Devices 4,5 and 6 Function 0 */ +#define MC_CHANNEL_DIMM_INIT_PARAMS 0x58 + #define THREE_DIMMS_PRESENT (1 << 24) + #define SINGLE_QUAD_RANK_PRESENT (1 << 23) + #define QUAD_RANK_PRESENT (1 << 22) + #define REGISTERED_DIMM (1 << 15) + +#define MC_CHANNEL_RANK_PRESENT 0x7c + #define RANK_PRESENT_MASK 0xffff + #define MC_CHANNEL_ADDR_MATCH 0xf0 #define MC_CHANNEL_ERROR_MASK 0xf8 #define MC_CHANNEL_ERROR_INJECT 0xfc @@ -74,6 +83,46 @@ #define NO_MASK_CACHELINE 0x00 #define REPEAT_EN 0x01 + /* OFFSETS for Devices 4,5 and 6 Function 1 */ +#define MC_DOD_CH_DIMM0 0x48 +#define MC_DOD_CH_DIMM1 0x4c +#define MC_DOD_CH_DIMM2 0x50 + #define RANKOFFSET_MASK ((1 << 12) | (1 << 11) | (1 << 10)) + #define RANKOFFSET(x) ((x & RANKOFFSET_MASK) >> 10) + #define DIMM_PRESENT_MASK (1 << 9) + #define DIMM_PRESENT(x) (((x) & DIMM_PRESENT_MASK) >> 9) + #define NUMBANK_MASK ((1 << 8) | (1 << 7)) + #define NUMBANK(x) (((x) & NUMBANK_MASK) >> 7) + #define NUMRANK_MASK ((1 << 6) | (1 << 5)) + #define NUMRANK(x) (((x) & NUMRANK_MASK) >> 5) + #define NUMROW_MASK ((1 << 4) | (1 << 3)) + #define NUMROW(x) (((x) & NUMROW_MASK) >> 3) + #define NUMCOL_MASK 3 + #define NUMCOL(x) ((x) & NUMCOL_MASK) + +#define MC_SAG_CH_0 0x80 +#define MC_SAG_CH_1 0x84 +#define MC_SAG_CH_2 0x88 +#define MC_SAG_CH_3 0x8c +#define MC_SAG_CH_4 0x90 +#define MC_SAG_CH_5 0x94 +#define MC_SAG_CH_6 0x98 +#define MC_SAG_CH_7 0x9c + +#define MC_RIR_LIMIT_CH_0 0x40 +#define MC_RIR_LIMIT_CH_1 0x44 +#define MC_RIR_LIMIT_CH_2 0x48 +#define MC_RIR_LIMIT_CH_3 0x4C +#define MC_RIR_LIMIT_CH_4 0x50 +#define MC_RIR_LIMIT_CH_5 0x54 +#define MC_RIR_LIMIT_CH_6 0x58 +#define MC_RIR_LIMIT_CH_7 0x5C +#define MC_RIR_LIMIT_MASK ((1 << 10) - 1) + +#define MC_RIR_WAY_CH 0x80 + #define MC_RIR_WAY_OFFSET_MASK (((1 << 14) - 1) & ~0x7) + #define MC_RIR_WAY_RANK_MASK 0x7 + /* * i7core structs */ @@ -99,11 +148,17 @@ struct i7core_inject { int channel, dimm, rank, bank, page, col; }; +struct i7core_channel { + u32 ranks; + u32 dimms; +}; + struct i7core_pvt { struct pci_dev *pci_mcr; /* Dev 3:0 */ struct pci_dev *pci_ch[NUM_CHANS][NUM_FUNCS]; struct i7core_info info; struct i7core_inject inject; + struct i7core_channel channel[NUM_CHANS]; }; /* Device name and register DID (Device ID) */ @@ -133,16 +188,12 @@ static struct edac_pci_ctl_info *i7core_pci; ****************************************************************************/ /* MC_CONTROL bits */ -#define CH2_ACTIVE(pvt) ((pvt)->info.mc_control & 1 << 10) -#define CH1_ACTIVE(pvt) ((pvt)->info.mc_control & 1 << 9) -#define CH0_ACTIVE(pvt) ((pvt)->info.mc_control & 1 << 8) +#define CH_ACTIVE(pvt, ch) ((pvt)->info.mc_control & 1 << (8 + ch)) #define ECCx8(pvt) ((pvt)->info.mc_control & 1 << 1) /* MC_STATUS bits */ #define ECC_ENABLED(pvt) ((pvt)->info.mc_status & 1 << 3) -#define CH2_DISABLED(pvt) ((pvt)->info.mc_status & 1 << 2) -#define CH1_DISABLED(pvt) ((pvt)->info.mc_status & 1 << 1) -#define CH0_DISABLED(pvt) ((pvt)->info.mc_status & 1 << 0) +#define CH_DISABLED(pvt, ch) ((pvt)->info.mc_status & 1 << ch) /* MC_MAX_DOD read functions */ static inline int maxnumdimms(struct i7core_pvt *pvt) @@ -189,19 +240,12 @@ static inline int maxnumcol(struct i7core_pvt *pvt) static int get_dimm_config(struct mem_ctl_info *mci) { struct i7core_pvt *pvt = mci->pvt_info; + int i; pci_read_config_dword(pvt->pci_mcr, MC_CONTROL, &pvt->info.mc_control); pci_read_config_dword(pvt->pci_mcr, MC_STATUS, &pvt->info.mc_status); pci_read_config_dword(pvt->pci_mcr, MC_MAX_DOD, &pvt->info.max_dod); - debugf0("Channels active [%c][%c][%c] - enabled [%c][%c][%c]\n", - CH0_ACTIVE(pvt)?'0':'-', - CH1_ACTIVE(pvt)?'1':'-', - CH2_ACTIVE(pvt)?'2':'-', - CH0_DISABLED(pvt)?'-':'0', - CH1_DISABLED(pvt)?'-':'1', - CH2_DISABLED(pvt)?'-':'2'); - if (ECC_ENABLED(pvt)) debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt)?8:4); else @@ -213,6 +257,38 @@ static int get_dimm_config(struct mem_ctl_info *mci) debugf0("DOD Maximum rows x colums = 0x%x x 0x%x\n", maxnumrow(pvt), maxnumcol(pvt)); + debugf0("Memory channel configuration:\n"); + + for (i = 0; i < NUM_CHANS; i++) { + u32 data; + + if (!CH_ACTIVE(pvt, i)) { + debugf0("Channel %i is not active\n", i); + continue; + } + if (CH_DISABLED(pvt, i)) { + debugf0("Channel %i is disabled\n", i); + continue; + } + + pci_read_config_dword(pvt->pci_ch[i][0], + MC_CHANNEL_DIMM_INIT_PARAMS, &data); + + pvt->channel[i].ranks = (data & QUAD_RANK_PRESENT)? 4 : 2; + + if (data & THREE_DIMMS_PRESENT) + pvt->channel[i].dimms = 3; + else if (data & SINGLE_QUAD_RANK_PRESENT) + pvt->channel[i].dimms = 1; + else + pvt->channel[i].dimms = 2; + + debugf0("Channel %d (0x%08x): %d ranks, %d dimms " + "(%sregistered)\n", i, data, + pvt->channel[i].ranks, pvt->channel[i].dimms, + (data & REGISTERED_DIMM)? "" : "un" ); + } + return 0; } @@ -489,7 +565,7 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, if (pvt->inject.dimm < 0) mask |= 1l << 41; else { - if (maxnumdimms(pvt) > 2) + if (pvt->channel[pvt->inject.channel].dimms > 2) mask |= (pvt->inject.dimm & 0x3l) << 35; else mask |= (pvt->inject.dimm & 0x1l) << 36; @@ -499,7 +575,7 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, if (pvt->inject.rank < 0) mask |= 1l << 40; else { - if (maxnumdimms(pvt) > 2) + if (pvt->channel[pvt->inject.channel].dimms > 2) mask |= (pvt->inject.rank & 0x1l) << 34; else mask |= (pvt->inject.rank & 0x3l) << 34; @@ -646,9 +722,6 @@ static int i7core_get_devices(struct mem_ctl_info *mci, int dev_idx) } pvt->pci_mcr=pdev; - /* Get dimm basic config */ - get_dimm_config(mci); - /* Retrieve all needed functions at MTR channel controllers */ for (i = 0; i < NUM_CHANS; i++) { pdev = NULL; @@ -672,6 +745,9 @@ static int i7core_get_devices(struct mem_ctl_info *mci, int dev_idx) } i7core_printk(KERN_INFO, "Driver loaded.\n"); + /* Get dimm basic config */ + get_dimm_config(mci); + return 0; } -- cgit v1.2.3 From 8f331907578623f90a134261a559fa3249142caa Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2009 22:48:29 -0300 Subject: i7core_edac: Registers all supported MC functions Now, it will try to register on all supported Memory Controller functions. It should be noticed that dev3, function 2 is present only on chips with Registered DIMM's, according to the datasheet. So, the driver doesn't return -ENODEV is all functions but this one were successfully registered and enabled: EDAC i7core: Registered device 8086:2c18 fn=3 0 EDAC i7core: Registered device 8086:2c19 fn=3 1 EDAC i7core: Device not found: PCI ID 8086:2c1a (dev 3, func 2) EDAC i7core: Registered device 8086:2c1c fn=3 4 EDAC i7core: Registered device 8086:2c20 fn=4 0 EDAC i7core: Registered device 8086:2c21 fn=4 1 EDAC i7core: Registered device 8086:2c22 fn=4 2 EDAC i7core: Registered device 8086:2c23 fn=4 3 EDAC i7core: Registered device 8086:2c28 fn=5 0 EDAC i7core: Registered device 8086:2c29 fn=5 1 EDAC i7core: Registered device 8086:2c2a fn=5 2 EDAC i7core: Registered device 8086:2c2b fn=5 3 EDAC i7core: Registered device 8086:2c30 fn=6 0 EDAC i7core: Registered device 8086:2c31 fn=6 1 EDAC i7core: Registered device 8086:2c32 fn=6 2 EDAC i7core: Registered device 8086:2c33 fn=6 3 EDAC i7core: Driver loaded. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 217 +++++++++++++++++++++++++++------------------ 1 file changed, 131 insertions(+), 86 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index da40730bf9c9..79aa84eaa12d 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -128,7 +128,8 @@ */ #define NUM_CHANS 3 -#define NUM_FUNCS 1 +#define NUM_MCR_FUNCS 4 +#define NUM_CHAN_FUNCS 3 struct i7core_info { u32 mc_control; @@ -153,9 +154,16 @@ struct i7core_channel { u32 dimms; }; +struct pci_id_descr { + int dev; + int func; + int dev_id; + struct pci_dev *pdev; +}; + struct i7core_pvt { - struct pci_dev *pci_mcr; /* Dev 3:0 */ - struct pci_dev *pci_ch[NUM_CHANS][NUM_FUNCS]; + struct pci_dev *pci_mcr[NUM_MCR_FUNCS]; + struct pci_dev *pci_ch[NUM_CHANS][NUM_CHAN_FUNCS]; struct i7core_info info; struct i7core_inject inject; struct i7core_channel channel[NUM_CHANS]; @@ -167,11 +175,47 @@ struct i7core_dev_info { u16 fsb_mapping_errors; /* DID for the branchmap,control */ }; -static int chan_pci_ids[NUM_CHANS] = { - PCI_DEVICE_ID_INTEL_I7_MC_CH0_CTRL, /* Dev 4 */ - PCI_DEVICE_ID_INTEL_I7_MC_CH1_CTRL, /* Dev 5 */ - PCI_DEVICE_ID_INTEL_I7_MC_CH2_CTRL, /* Dev 6 */ +#define PCI_DESCR(device, function, device_id) \ + .dev = (device), \ + .func = (function), \ + .dev_id = (device_id) + +struct pci_id_descr pci_devs[] = { + /* Memory controller */ + { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) }, + { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) }, + { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_I7_MC_RAS) }, /* if RDIMM is supported */ + { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_I7_MC_TEST) }, + + /* Channel 0 */ + { PCI_DESCR(4, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH0_CTRL) }, + { PCI_DESCR(4, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH0_ADDR) }, + { PCI_DESCR(4, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH0_RANK) }, + { PCI_DESCR(4, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH0_TC) }, + + /* Channel 1 */ + { PCI_DESCR(5, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH1_CTRL) }, + { PCI_DESCR(5, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH1_ADDR) }, + { PCI_DESCR(5, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH1_RANK) }, + { PCI_DESCR(5, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH1_TC) }, + + /* Channel 2 */ + { PCI_DESCR(6, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH2_CTRL) }, + { PCI_DESCR(6, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH2_ADDR) }, + { PCI_DESCR(6, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH2_RANK) }, + { PCI_DESCR(6, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC) }, }; +#define N_DEVS ARRAY_SIZE(pci_devs) + +/* + * pci_device_id table for which devices we are looking for + * This should match the first device at pci_devs table + */ +static const struct pci_device_id i7core_pci_tbl[] __devinitdata = { + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7_MCR)}, + {0,} /* 0 terminated list. */ +}; + /* Table of devices attributes supported by this driver */ static const struct i7core_dev_info i7core_devs[] = { @@ -242,9 +286,12 @@ static int get_dimm_config(struct mem_ctl_info *mci) struct i7core_pvt *pvt = mci->pvt_info; int i; - pci_read_config_dword(pvt->pci_mcr, MC_CONTROL, &pvt->info.mc_control); - pci_read_config_dword(pvt->pci_mcr, MC_STATUS, &pvt->info.mc_status); - pci_read_config_dword(pvt->pci_mcr, MC_MAX_DOD, &pvt->info.max_dod); + if (!pvt->pci_mcr[0]) + return -ENODEV; + + pci_read_config_dword(pvt->pci_mcr[0], MC_CONTROL, &pvt->info.mc_control); + pci_read_config_dword(pvt->pci_mcr[0], MC_STATUS, &pvt->info.mc_status); + pci_read_config_dword(pvt->pci_mcr[0], MC_MAX_DOD, &pvt->info.max_dod); if (ECC_ENABLED(pvt)) debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt)?8:4); @@ -303,14 +350,19 @@ static int get_dimm_config(struct mem_ctl_info *mci) we're disabling error injection on all write calls to the sysfs nodes that controls the error code injection. */ -static void disable_inject(struct mem_ctl_info *mci) +static int disable_inject(struct mem_ctl_info *mci) { struct i7core_pvt *pvt = mci->pvt_info; pvt->inject.enable = 0; + if (!pvt->pci_ch[pvt->inject.channel][0]) + return -ENODEV; + pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0], MC_CHANNEL_ERROR_MASK, 0); + + return 0; } /* @@ -550,6 +602,9 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, int rc; long enable; + if (!pvt->pci_ch[pvt->inject.channel][0]) + return 0; + rc = strict_strtoul(data, 10, &enable); if ((rc < 0)) return 0; @@ -684,17 +739,12 @@ static struct mcidev_sysfs_attribute i7core_inj_attrs[] = { * i7core_put_devices 'put' all the devices that we have * reserved via 'get' */ -static void i7core_put_devices(struct mem_ctl_info *mci) +static void i7core_put_devices(void) { - struct i7core_pvt *pvt = mci->pvt_info; - int i, n; - - pci_dev_put(pvt->pci_mcr); + int i; - /* Release all PCI device functions at MTR channel controllers */ - for (i = 0; i < NUM_CHANS; i++) - for (n = 0; n < NUM_FUNCS; n++) - pci_dev_put(pvt->pci_ch[i][n]); + for (i = 0; i < N_DEVS; i++) + pci_dev_put(pci_devs[i].pdev); } /* @@ -703,50 +753,67 @@ static void i7core_put_devices(struct mem_ctl_info *mci) * * Need to 'get' device 16 func 1 and func 2 */ -static int i7core_get_devices(struct mem_ctl_info *mci, int dev_idx) +static int i7core_get_devices(struct mem_ctl_info *mci, struct pci_dev *mcidev) { - struct i7core_pvt *pvt; - struct pci_dev *pdev; - int i, n, func; + struct i7core_pvt *pvt = mci->pvt_info; + int rc, i,func; + struct pci_dev *pdev = NULL; pvt = mci->pvt_info; memset(pvt, 0, sizeof(*pvt)); - pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7_MCR, - NULL); - if (!pdev) { - i7core_printk(KERN_ERR, - "Couldn't get PCI ID %04x:%04x function 0\n", - PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7_MCR); - return -ENODEV; - } - pvt->pci_mcr=pdev; + for (i = 0; i < N_DEVS; i++) { + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, + pci_devs[i].dev_id, NULL); + if (!pdev) { + /* End of list, leave */ + i7core_printk(KERN_ERR, + "Device not found: PCI ID %04x:%04x " + "(dev %d, func %d)\n", + PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id, + pci_devs[i].dev,pci_devs[i].func); + if ((pci_devs[i].dev == 3) && (pci_devs[i].func == 2)) + continue; /* Only on chips with RDIMMs */ + else + i7core_put_devices(); + } + pci_devs[i].pdev = pdev; + + rc = pci_enable_device(pdev); + if (rc < 0) { + i7core_printk(KERN_ERR, + "Couldn't enable PCI ID %04x:%04x " + "(dev %d, func %d)\n", + PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id, + pci_devs[i].dev, pci_devs[i].func); + i7core_put_devices(); + return rc; + } + /* Sanity check */ + if (PCI_FUNC(pdev->devfn) != pci_devs[i].func) { + i7core_printk(KERN_ERR, + "Device PCI ID %04x:%04x " + "has function %d instead of %d\n", + PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id, + PCI_FUNC(pdev->devfn), pci_devs[i].func); + i7core_put_devices(); + return -EINVAL; + } - /* Retrieve all needed functions at MTR channel controllers */ - for (i = 0; i < NUM_CHANS; i++) { - pdev = NULL; - for (n = 0; n < NUM_FUNCS; n++) { - pdev = pci_get_device(PCI_VENDOR_ID_INTEL, - chan_pci_ids[i], pdev); - if (!pdev) { - /* End of list, leave */ - i7core_printk(KERN_ERR, - "Device not found: PCI ID %04x:%04x " - "found only %d functions " - "(broken BIOS?)\n", - PCI_VENDOR_ID_INTEL, - chan_pci_ids[i], n); - i7core_put_devices(mci); - return -ENODEV; - } - func = PCI_FUNC(pdev->devfn); - pvt->pci_ch[i][func] = pdev; + i7core_printk(KERN_INFO, + "Registered device %0x:%0x fn=%0x %0x\n", + PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id, + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); + + func = PCI_FUNC(pdev->devfn); + if (pci_devs[i].dev < 4) { + pvt->pci_mcr[func] = pdev; + } else { + pvt->pci_ch[pci_devs[i].dev - 4][func] = pdev; } } - i7core_printk(KERN_INFO, "Driver loaded.\n"); - /* Get dimm basic config */ - get_dimm_config(mci); + i7core_printk(KERN_INFO, "Driver loaded.\n"); return 0; } @@ -763,7 +830,6 @@ static int __devinit i7core_probe(struct pci_dev *pdev, { struct mem_ctl_info *mci; struct i7core_pvt *pvt; - int rc; int num_channels; int num_csrows; int num_dimms_per_channel; @@ -772,20 +838,6 @@ static int __devinit i7core_probe(struct pci_dev *pdev, if (dev_idx >= ARRAY_SIZE(i7core_devs)) return -EINVAL; - /* wake up device */ - rc = pci_enable_device(pdev); - if (rc == -EIO) - return rc; - - debugf0("MC: " __FILE__ ": %s(), pdev bus %u dev=0x%x fn=0x%x\n", - __func__, - pdev->bus->number, - PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); - - /* We only are looking for func 0 of the set */ - if (PCI_FUNC(pdev->devfn) != 0) - return -ENODEV; - num_channels = NUM_CHANS; /* FIXME: FAKE data, since we currently don't now how to get this */ @@ -808,10 +860,6 @@ static int __devinit i7core_probe(struct pci_dev *pdev, // pvt->maxch = num_channels; // pvt->maxdimmperch = num_dimms_per_channel; - /* 'get' the pci devices we want to reserve for our use */ - if (i7core_get_devices(mci, dev_idx)) - goto fail0; - mci->mc_idx = 0; mci->mtype_cap = MEM_FLAG_FB_DDR2; /* FIXME: it uses DDR3 */ mci->edac_ctl_cap = EDAC_FLAG_NONE; @@ -823,6 +871,10 @@ static int __devinit i7core_probe(struct pci_dev *pdev, mci->ctl_page_to_phys = NULL; mci->mc_driver_sysfs_attributes = i7core_inj_attrs; + /* 'get' the pci devices we want to reserve for our use */ + if (i7core_get_devices(mci, pdev)) + goto fail0; + /* add this new MC control structure to EDAC's list of MCs */ if (edac_mc_add_mc(mci)) { debugf0("MC: " __FILE__ @@ -852,10 +904,13 @@ static int __devinit i7core_probe(struct pci_dev *pdev, pvt->inject.page = -1; pvt->inject.col = -1; + /* Get dimm basic config */ + get_dimm_config(mci); + return 0; fail1: - i7core_put_devices(mci); + i7core_put_devices(); fail0: edac_mc_free(mci); @@ -880,21 +935,11 @@ static void __devexit i7core_remove(struct pci_dev *pdev) return; /* retrieve references to resources, and free those resources */ - i7core_put_devices(mci); + i7core_put_devices(); edac_mc_free(mci); } -/* - * pci_device_id table for which devices we are looking for - * - * The "E500P" device is the first device supported. - */ -static const struct pci_device_id i7core_pci_tbl[] __devinitdata = { - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7_MCR)}, - {0,} /* 0 terminated list. */ -}; - MODULE_DEVICE_TABLE(pci, i7core_pci_tbl); /* -- cgit v1.2.3 From f122a89222510e8f57e8e0b9b5cdd3ec8863fe4c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2009 22:48:29 -0300 Subject: i7core_edac: Show read/write virtual/physical channel association Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 79aa84eaa12d..09a0998e1c3f 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -68,6 +68,10 @@ #define QUAD_RANK_PRESENT (1 << 22) #define REGISTERED_DIMM (1 << 15) +#define MC_CHANNEL_MAPPER 0x60 + #define RDLCH(r, ch) ((((r) >> (3 + (ch * 6))) & 0x07) - 1) + #define WRLCH(r, ch) ((((r) >> (ch * 6)) & 0x07) - 1) + #define MC_CHANNEL_RANK_PRESENT 0x7c #define RANK_PRESENT_MASK 0xffff @@ -100,6 +104,8 @@ #define NUMCOL_MASK 3 #define NUMCOL(x) ((x) & NUMCOL_MASK) +#define MC_RANK_PRESENT 0x7c + #define MC_SAG_CH_0 0x80 #define MC_SAG_CH_1 0x84 #define MC_SAG_CH_2 0x88 @@ -135,6 +141,7 @@ struct i7core_info { u32 mc_control; u32 mc_status; u32 max_dod; + u32 ch_map; }; @@ -289,9 +296,19 @@ static int get_dimm_config(struct mem_ctl_info *mci) if (!pvt->pci_mcr[0]) return -ENODEV; - pci_read_config_dword(pvt->pci_mcr[0], MC_CONTROL, &pvt->info.mc_control); - pci_read_config_dword(pvt->pci_mcr[0], MC_STATUS, &pvt->info.mc_status); - pci_read_config_dword(pvt->pci_mcr[0], MC_MAX_DOD, &pvt->info.max_dod); + /* Device 3 function 0 reads */ + pci_read_config_dword(pvt->pci_mcr[0], MC_CONTROL, + &pvt->info.mc_control); + pci_read_config_dword(pvt->pci_mcr[0], MC_STATUS, + &pvt->info.mc_status); + pci_read_config_dword(pvt->pci_mcr[0], MC_MAX_DOD, + &pvt->info.max_dod); + pci_read_config_dword(pvt->pci_mcr[0], MC_CHANNEL_MAPPER, + &pvt->info.ch_map); + + debugf0("MC control=0x%08x status=0x%08x dod=0x%08x map=0x%08x\n", + pvt->info.mc_control, pvt->info.mc_status, + pvt->info.max_dod, pvt->info.ch_map); if (ECC_ENABLED(pvt)) debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt)?8:4); @@ -318,6 +335,7 @@ static int get_dimm_config(struct mem_ctl_info *mci) continue; } + /* Devices 4-6 function 0 */ pci_read_config_dword(pvt->pci_ch[i][0], MC_CHANNEL_DIMM_INIT_PARAMS, &data); @@ -330,10 +348,13 @@ static int get_dimm_config(struct mem_ctl_info *mci) else pvt->channel[i].dimms = 2; - debugf0("Channel %d (0x%08x): %d ranks, %d dimms " - "(%sregistered)\n", i, data, + debugf0("Ch%d (0x%08x): rd ch %d, wr ch %d, " + "%d ranks, %d %cDIMMs\n", + i, data, + RDLCH(pvt->info.ch_map, i), + WRLCH(pvt->info.ch_map, i), pvt->channel[i].ranks, pvt->channel[i].dimms, - (data & REGISTERED_DIMM)? "" : "un" ); + (data & REGISTERED_DIMM)? 'R' : 'U' ); } return 0; -- cgit v1.2.3 From 7b029d03c36e5b06e067884aaefcee2c1c62efc7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2009 22:48:29 -0300 Subject: i7core_edac: A few fixes at error injection code Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 70 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 09a0998e1c3f..0c17db673065 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -30,6 +30,8 @@ #include "edac_core.h" +/* To use the new pci_[read/write]_config_qword instead of two dword */ +#define USE_QWORD 1 /* * Alter this version for the module when modifications are made @@ -639,44 +641,71 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, /* Sets pvt->inject.dimm mask */ if (pvt->inject.dimm < 0) - mask |= 1l << 41; + mask |= 1L << 41; else { if (pvt->channel[pvt->inject.channel].dimms > 2) - mask |= (pvt->inject.dimm & 0x3l) << 35; + mask |= (pvt->inject.dimm & 0x3L) << 35; else - mask |= (pvt->inject.dimm & 0x1l) << 36; + mask |= (pvt->inject.dimm & 0x1L) << 36; } /* Sets pvt->inject.rank mask */ if (pvt->inject.rank < 0) - mask |= 1l << 40; + mask |= 1L << 40; else { if (pvt->channel[pvt->inject.channel].dimms > 2) - mask |= (pvt->inject.rank & 0x1l) << 34; + mask |= (pvt->inject.rank & 0x1L) << 34; else - mask |= (pvt->inject.rank & 0x3l) << 34; + mask |= (pvt->inject.rank & 0x3L) << 34; } /* Sets pvt->inject.bank mask */ if (pvt->inject.bank < 0) - mask |= 1l << 39; + mask |= 1L << 39; else - mask |= (pvt->inject.bank & 0x15l) << 30; + mask |= (pvt->inject.bank & 0x15L) << 30; /* Sets pvt->inject.page mask */ if (pvt->inject.page < 0) - mask |= 1l << 38; + mask |= 1L << 38; else - mask |= (pvt->inject.page & 0xffffl) << 14; + mask |= (pvt->inject.page & 0xffffL) << 14; /* Sets pvt->inject.column mask */ if (pvt->inject.col < 0) - mask |= 1l << 37; + mask |= 1L << 37; else - mask |= (pvt->inject.col & 0x3fffl); + mask |= (pvt->inject.col & 0x3fffL); +#if USE_QWORD pci_write_config_qword(pvt->pci_ch[pvt->inject.channel][0], MC_CHANNEL_ADDR_MATCH, mask); +#else + pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0], + MC_CHANNEL_ADDR_MATCH, mask); + pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0], + MC_CHANNEL_ADDR_MATCH + 4, mask >> 32L); +#endif + +#if 1 +#if USE_QWORD + u64 rdmask; + pci_read_config_qword(pvt->pci_ch[pvt->inject.channel][0], + MC_CHANNEL_ADDR_MATCH, &rdmask); + debugf0("Inject addr match write 0x%016llx, read: 0x%016llx\n", + mask, rdmask); +#else + u32 rdmask1, rdmask2; + + pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0], + MC_CHANNEL_ADDR_MATCH, &rdmask1); + pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0], + MC_CHANNEL_ADDR_MATCH + 4, &rdmask2); + + debugf0("Inject addr match write 0x%016llx, read: 0x%08x%08x\n", + mask, rdmask1, rdmask2); +#endif +#endif pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0], MC_CHANNEL_ERROR_MASK, pvt->inject.eccmask); @@ -688,17 +717,18 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, * bit 4: INJECT_ADDR_PARITY */ - injectmask = (pvt->inject.type & 1) && - (pvt->inject.section & 0x3) << 1 && + injectmask = (pvt->inject.type & 1) | + (pvt->inject.section & 0x3) << 1 | (pvt->inject.type & 0x6) << (3 - 1); pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0], MC_CHANNEL_ERROR_MASK, injectmask); - debugf0("Error inject addr match 0x%016llx, ecc 0x%08x, inject 0x%08x\n", mask, pvt->inject.eccmask, injectmask); + + return count; } @@ -706,6 +736,16 @@ static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci, char *data) { struct i7core_pvt *pvt = mci->pvt_info; + u32 injectmask; + + pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0], + MC_CHANNEL_ERROR_MASK, &injectmask); + + debugf0("Inject error read: 0x%018x\n", injectmask); + + if (injectmask & 0x0c) + pvt->inject.enable = 1; + return sprintf(data, "%d\n", pvt->inject.enable); } -- cgit v1.2.3 From 87d1d272ba25a1863e40ebb1df4bc0eed7a8fd11 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2009 22:48:29 -0300 Subject: i7core_edac: need mci->edac_check, otherwise module removal doesn't work There are some locking troubles with edac_core: if you don't declare an edac_check, module may suffer from soft lock. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 0c17db673065..190596af601a 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -879,6 +879,15 @@ static int i7core_get_devices(struct mem_ctl_info *mci, struct pci_dev *mcidev) return 0; } +/* + * i7core_check_error Retrieve and process errors reported by the + * hardware. Called by the Core module. + */ +static void i7core_check_error(struct mem_ctl_info *mci) +{ + /* FIXME: need a real code here */ +} + /* * i7core_probe Probe for ONE instance of device to see if it is * present. @@ -912,8 +921,11 @@ static int __devinit i7core_probe(struct pci_dev *pdev, debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); + /* 'get' the pci devices we want to reserve for our use */ + if (i7core_get_devices(mci, pdev)) + goto fail0; + mci->dev = &pdev->dev; /* record ptr to the generic device */ - dev_set_drvdata(mci->dev, mci); pvt = mci->pvt_info; @@ -932,9 +944,8 @@ static int __devinit i7core_probe(struct pci_dev *pdev, mci->ctl_page_to_phys = NULL; mci->mc_driver_sysfs_attributes = i7core_inj_attrs; - /* 'get' the pci devices we want to reserve for our use */ - if (i7core_get_devices(mci, pdev)) - goto fail0; + /* Set the function pointer to an actual operation function */ + mci->edac_check = i7core_check_error; /* add this new MC control structure to EDAC's list of MCs */ if (edac_mc_add_mc(mci)) { @@ -992,6 +1003,7 @@ static void __devexit i7core_remove(struct pci_dev *pdev) edac_pci_release_generic_ctl(i7core_pci); mci = edac_mc_del_mc(&pdev->dev); + if (!mci) return; -- cgit v1.2.3 From 442305b152778f07504e9fdf64815d4841279bbe Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2009 22:48:29 -0300 Subject: i7core_edac: Add a memory check routine, based on device 3 function 4 This function appears only on Xeon 5500 datasheet. Yet, testing with a Xeon 3503 showed that this is also implemented on other Nehalem processors. At the first read, MC_TEST_ERR_RCV1 and MC_TEST_ERR_RCV0 can contain any value. Modify CE error logic to update the error count only after the second read. An alternative approach would be to do a write at rcv0 and rcv1 registers, but it seemed better to keep they untouched, since BIOS might eventually assume that they are exclusive for their usage. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 115 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 108 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 190596af601a..b5dbc2b83961 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -62,6 +62,18 @@ #define MC_STATUS 0x4c #define MC_MAX_DOD 0x64 +/* + * OFFSETS for Device 3 Function 4, as inicated on Xeon 5500 datasheet: + * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf + */ + +#define MC_TEST_ERR_RCV1 0x60 + #define DIMM2_COR_ERR(r) ((r) & 0x7fff) + +#define MC_TEST_ERR_RCV0 0x64 + #define DIMM1_COR_ERR(r) (((r) >> 16) & 0x7fff) + #define DIMM0_COR_ERR(r) ((r) & 0x7fff) + /* OFFSETS for Devices 4,5 and 6 Function 0 */ #define MC_CHANNEL_DIMM_INIT_PARAMS 0x58 @@ -136,8 +148,9 @@ */ #define NUM_CHANS 3 -#define NUM_MCR_FUNCS 4 -#define NUM_CHAN_FUNCS 3 +#define MAX_DIMMS 3 /* Max DIMMS per channel */ +#define MAX_MCR_FUNC 4 +#define MAX_CHAN_FUNC 3 struct i7core_info { u32 mc_control; @@ -159,8 +172,8 @@ struct i7core_inject { }; struct i7core_channel { - u32 ranks; - u32 dimms; + u32 ranks; + u32 dimms; }; struct pci_id_descr { @@ -171,11 +184,16 @@ struct pci_id_descr { }; struct i7core_pvt { - struct pci_dev *pci_mcr[NUM_MCR_FUNCS]; - struct pci_dev *pci_ch[NUM_CHANS][NUM_CHAN_FUNCS]; + struct pci_dev *pci_mcr[MAX_MCR_FUNC + 1]; + struct pci_dev *pci_ch[NUM_CHANS][MAX_CHAN_FUNC + 1]; struct i7core_info info; struct i7core_inject inject; struct i7core_channel channel[NUM_CHANS]; + + int ce_count_available; + unsigned long ce_count[MAX_DIMMS]; /* ECC corrected errors counts per dimm */ + int last_ce_count[MAX_DIMMS]; + }; /* Device name and register DID (Device ID) */ @@ -749,6 +767,19 @@ static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci, return sprintf(data, "%d\n", pvt->inject.enable); } +static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data) +{ + struct i7core_pvt *pvt = mci->pvt_info; + + if (!pvt->ce_count_available) + return sprintf(data, "unavailable\n"); + + return sprintf(data, "dimm0: %lu\ndimm1: %lu\ndimm2: %lu\n", + pvt->ce_count[0], + pvt->ce_count[1], + pvt->ce_count[2]); +} + /* * Sysfs struct */ @@ -789,6 +820,13 @@ static struct mcidev_sysfs_attribute i7core_inj_attrs[] = { }, .show = i7core_inject_enable_show, .store = i7core_inject_enable_store, + }, { + .attr = { + .name = "corrected_error_counts", + .mode = (S_IRUGO | S_IWUSR) + }, + .show = i7core_ce_regs_show, + .store = NULL, }, }; @@ -879,13 +917,76 @@ static int i7core_get_devices(struct mem_ctl_info *mci, struct pci_dev *mcidev) return 0; } +/**************************************************************************** + Error check routines + ****************************************************************************/ + +/* This function is based on the device 3 function 4 registers as described on: + * Intel Xeon Processor 5500 Series Datasheet Volume 2 + * http://www.intel.com/Assets/PDF/datasheet/321322.pdf + * also available at: + * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf + */ +static void check_mc_test_err(struct mem_ctl_info *mci) +{ + struct i7core_pvt *pvt = mci->pvt_info; + u32 rcv1, rcv0; + int new0, new1, new2; + + if (!pvt->pci_mcr[4]) { + debugf0("%s MCR registers not found\n",__func__); + return; + } + + /* Corrected error reads */ + pci_read_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV1, &rcv1); + pci_read_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV0, &rcv0); + + /* Store the new values */ + new2 = DIMM2_COR_ERR(rcv1); + new1 = DIMM1_COR_ERR(rcv0); + new0 = DIMM0_COR_ERR(rcv0); + + debugf2("%s CE rcv1=0x%08x rcv0=0x%08x, %d %d %d\n", + (pvt->ce_count_available ? "UPDATE" : "READ"), + rcv1, rcv0, new0, new1, new2); + + /* Updates CE counters if it is not the first time here */ + if (pvt->ce_count_available) { + /* Updates CE counters */ + int add0, add1, add2; + + add2 = new2 - pvt->last_ce_count[2]; + add1 = new1 - pvt->last_ce_count[1]; + add0 = new0 - pvt->last_ce_count[0]; + + if (add2 < 0) + add2 += 0x7fff; + pvt->ce_count[2] += add2; + + if (add1 < 0) + add1 += 0x7fff; + pvt->ce_count[1] += add1; + + if (add0 < 0) + add0 += 0x7fff; + pvt->ce_count[0] += add0; + } else + pvt->ce_count_available = 1; + + /* Store the new values */ + pvt->last_ce_count[2] = new2; + pvt->last_ce_count[1] = new1; + pvt->last_ce_count[0] = new0; +} + /* * i7core_check_error Retrieve and process errors reported by the * hardware. Called by the Core module. */ static void i7core_check_error(struct mem_ctl_info *mci) { - /* FIXME: need a real code here */ + check_mc_test_err(mci); } /* -- cgit v1.2.3 From ef708b53b98f2b53d9686a9f8f0b8d437952c295 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2009 22:48:30 -0300 Subject: i7core_edac: Add additional tests for error detection Properly check the number of channels and improve probing error detection Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 199 +++++++++++++++++++++++++++++++-------------- 1 file changed, 139 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index b5dbc2b83961..bfa462f6fa0e 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -189,6 +189,7 @@ struct i7core_pvt { struct i7core_info info; struct i7core_inject inject; struct i7core_channel channel[NUM_CHANS]; + int channels; /* Number of active channels */ int ce_count_available; unsigned long ce_count[MAX_DIMMS]; /* ECC corrected errors counts per dimm */ @@ -259,12 +260,12 @@ static struct edac_pci_ctl_info *i7core_pci; ****************************************************************************/ /* MC_CONTROL bits */ -#define CH_ACTIVE(pvt, ch) ((pvt)->info.mc_control & 1 << (8 + ch)) -#define ECCx8(pvt) ((pvt)->info.mc_control & 1 << 1) +#define CH_ACTIVE(pvt, ch) ((pvt)->info.mc_control & (1 << (8 + ch))) +#define ECCx8(pvt) ((pvt)->info.mc_control & (1 << 1)) /* MC_STATUS bits */ -#define ECC_ENABLED(pvt) ((pvt)->info.mc_status & 1 << 3) -#define CH_DISABLED(pvt, ch) ((pvt)->info.mc_status & 1 << ch) +#define ECC_ENABLED(pvt) ((pvt)->info.mc_status & (1 << 3)) +#define CH_DISABLED(pvt, ch) ((pvt)->info.mc_status & (1 << ch)) /* MC_MAX_DOD read functions */ static inline int maxnumdimms(struct i7core_pvt *pvt) @@ -308,6 +309,48 @@ static inline int maxnumcol(struct i7core_pvt *pvt) /**************************************************************************** Memory check routines ****************************************************************************/ +static int i7core_get_active_channels(int *channels) +{ + struct pci_dev *pdev = NULL; + int i; + u32 status, control; + + *channels = 0; + + for (i = 0; i < N_DEVS; i++) { + if (!pci_devs[i].pdev) + continue; + + if (PCI_SLOT(pci_devs[i].pdev->devfn) == 3 && + PCI_FUNC(pci_devs[i].pdev->devfn) == 0) { + pdev = pci_devs[i].pdev; + break; + } + } + + if (!pdev) + return -ENODEV; + + /* Device 3 function 0 reads */ + pci_read_config_dword(pdev, MC_STATUS, &status); + pci_read_config_dword(pdev, MC_CONTROL, &control); + + for (i = 0; i < NUM_CHANS; i++) { + /* Check if the channel is active */ + if (!(control & (1 << (8 + i)))) + continue; + + /* Check if the channel is disabled */ + if (status & (1 << i)) { + continue; + } + + (*channels)++; + } + + return 0; +} + static int get_dimm_config(struct mem_ctl_info *mci) { struct i7core_pvt *pvt = mci->pvt_info; @@ -852,69 +895,103 @@ static void i7core_put_devices(void) * * Need to 'get' device 16 func 1 and func 2 */ -static int i7core_get_devices(struct mem_ctl_info *mci, struct pci_dev *mcidev) +static int i7core_get_devices(void) { - struct i7core_pvt *pvt = mci->pvt_info; - int rc, i,func; + int rc, i; struct pci_dev *pdev = NULL; - pvt = mci->pvt_info; - memset(pvt, 0, sizeof(*pvt)); - for (i = 0; i < N_DEVS; i++) { pdev = pci_get_device(PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id, NULL); - if (!pdev) { - /* End of list, leave */ + if (likely(pdev)) + pci_devs[i].pdev = pdev; + else { i7core_printk(KERN_ERR, "Device not found: PCI ID %04x:%04x " "(dev %d, func %d)\n", PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id, pci_devs[i].dev,pci_devs[i].func); + + /* Dev 3 function 2 only exists on chips with RDIMMs */ if ((pci_devs[i].dev == 3) && (pci_devs[i].func == 2)) - continue; /* Only on chips with RDIMMs */ - else - i7core_put_devices(); + continue; + + /* End of list, leave */ + rc = -ENODEV; + goto error; } - pci_devs[i].pdev = pdev; - rc = pci_enable_device(pdev); - if (rc < 0) { + /* Sanity check */ + if (unlikely(PCI_SLOT(pdev->devfn) != pci_devs[i].dev || + PCI_FUNC(pdev->devfn) != pci_devs[i].func)) { i7core_printk(KERN_ERR, - "Couldn't enable PCI ID %04x:%04x " - "(dev %d, func %d)\n", + "Device PCI ID %04x:%04x " + "has fn %d.%d instead of fn %d.%d\n", PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id, + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), pci_devs[i].dev, pci_devs[i].func); - i7core_put_devices(); - return rc; + rc = -EINVAL; + goto error; } - /* Sanity check */ - if (PCI_FUNC(pdev->devfn) != pci_devs[i].func) { + + /* Be sure that the device is enabled */ + rc = pci_enable_device(pdev); + if (unlikely(rc < 0)) { i7core_printk(KERN_ERR, - "Device PCI ID %04x:%04x " - "has function %d instead of %d\n", + "Couldn't enable PCI ID %04x:%04x " + "fn %d.%d\n", PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id, - PCI_FUNC(pdev->devfn), pci_devs[i].func); - i7core_put_devices(); - return -EINVAL; + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); + goto error; } i7core_printk(KERN_INFO, - "Registered device %0x:%0x fn=%0x %0x\n", + "Registered device %0x:%0x fn %d.%d\n", PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); + } + + return 0; + +error: + i7core_put_devices(); + return -EINVAL; +} + +static int mci_bind_devs(struct mem_ctl_info *mci) +{ + struct i7core_pvt *pvt = mci->pvt_info; + struct pci_dev *pdev; + int i, func, slot; + + for (i = 0; i < N_DEVS; i++) { + pdev = pci_devs[i].pdev; + if (!pdev) + continue; func = PCI_FUNC(pdev->devfn); - if (pci_devs[i].dev < 4) { + slot = PCI_SLOT(pdev->devfn); + if (slot == 3) { + if (unlikely(func > MAX_MCR_FUNC)) + goto error; pvt->pci_mcr[func] = pdev; - } else { - pvt->pci_ch[pci_devs[i].dev - 4][func] = pdev; - } + } else if (likely(slot >= 4 && slot < 4 + NUM_CHANS)) { + if (unlikely(func > MAX_CHAN_FUNC)) + goto error; + pvt->pci_ch[slot - 4][func] = pdev; + } else + goto error; + + debugf0("Associated fn %d.%d, dev = %p\n", + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), pdev); } - - i7core_printk(KERN_INFO, "Driver loaded.\n"); - return 0; + +error: + i7core_printk(KERN_ERR, "Device %d, function %d " + "is out of the expected range\n", + slot, func); + return -EINVAL; } /**************************************************************************** @@ -1001,41 +1078,38 @@ static int __devinit i7core_probe(struct pci_dev *pdev, { struct mem_ctl_info *mci; struct i7core_pvt *pvt; - int num_channels; + int num_channels = 0; int num_csrows; - int num_dimms_per_channel; int dev_idx = id->driver_data; - if (dev_idx >= ARRAY_SIZE(i7core_devs)) + if (unlikely(dev_idx >= ARRAY_SIZE(i7core_devs))) return -EINVAL; - num_channels = NUM_CHANS; + /* get the pci devices we want to reserve for our use */ + if (unlikely(i7core_get_devices() < 0)) + return -ENODEV; + + /* Check the number of active and not disabled channels */ + if (unlikely (i7core_get_active_channels(&num_channels)) < 0) + goto fail0; - /* FIXME: FAKE data, since we currently don't now how to get this */ - num_dimms_per_channel = 4; - num_csrows = num_dimms_per_channel; + /* FIXME: we currently don't know the number of csrows */ + num_csrows = num_channels; /* allocate a new MC control structure */ mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0); - if (mci == NULL) + if (unlikely (!mci)) return -ENOMEM; debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); - /* 'get' the pci devices we want to reserve for our use */ - if (i7core_get_devices(mci, pdev)) - goto fail0; - mci->dev = &pdev->dev; /* record ptr to the generic device */ pvt = mci->pvt_info; - -// pvt->system_address = pdev; /* Record this device in our private */ -// pvt->maxch = num_channels; -// pvt->maxdimmperch = num_dimms_per_channel; + memset(pvt, 0, sizeof(*pvt)); mci->mc_idx = 0; - mci->mtype_cap = MEM_FLAG_FB_DDR2; /* FIXME: it uses DDR3 */ + mci->mtype_cap = MEM_FLAG_DDR3; /* FIXME: how to handle RDDR3? */ mci->edac_ctl_cap = EDAC_FLAG_NONE; mci->edac_cap = EDAC_FLAG_NONE; mci->mod_name = "i7core_edac.c"; @@ -1044,12 +1118,18 @@ static int __devinit i7core_probe(struct pci_dev *pdev, mci->dev_name = pci_name(pdev); mci->ctl_page_to_phys = NULL; mci->mc_driver_sysfs_attributes = i7core_inj_attrs; - /* Set the function pointer to an actual operation function */ mci->edac_check = i7core_check_error; + /* Store pci devices at mci for faster access */ + if (unlikely (mci_bind_devs(mci)) < 0) + goto fail1; + + /* Get dimm basic config */ + get_dimm_config(mci); + /* add this new MC control structure to EDAC's list of MCs */ - if (edac_mc_add_mc(mci)) { + if (unlikely(edac_mc_add_mc(mci)) < 0) { debugf0("MC: " __FILE__ ": %s(): failed edac_mc_add_mc()\n", __func__); /* FIXME: perhaps some code should go here that disables error @@ -1060,7 +1140,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, /* allocating generic PCI control info */ i7core_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR); - if (!i7core_pci) { + if (unlikely (!i7core_pci)) { printk(KERN_WARNING "%s(): Unable to create PCI control\n", __func__); @@ -1070,15 +1150,14 @@ static int __devinit i7core_probe(struct pci_dev *pdev, } /* Default error mask is any memory */ - pvt->inject.channel = -1; + pvt->inject.channel = 0; pvt->inject.dimm = -1; pvt->inject.rank = -1; pvt->inject.bank = -1; pvt->inject.page = -1; pvt->inject.col = -1; - /* Get dimm basic config */ - get_dimm_config(mci); + i7core_printk(KERN_INFO, "Driver loaded.\n"); return 0; -- cgit v1.2.3 From 1c6fed808f1ccd0804786e87f6b2c907dcd730fa Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2009 22:48:30 -0300 Subject: i7core_edac: Properly fill struct csrow_info Thanks-to: Aristeu Rozanski for part of the code Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 48 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index bfa462f6fa0e..556a150e645b 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -348,13 +348,17 @@ static int i7core_get_active_channels(int *channels) (*channels)++; } + debugf0("Number of active channels: %d\n", *channels); + return 0; } static int get_dimm_config(struct mem_ctl_info *mci) { struct i7core_pvt *pvt = mci->pvt_info; - int i; + struct csrow_info *csr; + int i, csrow = 0; + enum edac_type mode; if (!pvt->pci_mcr[0]) return -ENODEV; @@ -365,7 +369,7 @@ static int get_dimm_config(struct mem_ctl_info *mci) pci_read_config_dword(pvt->pci_mcr[0], MC_STATUS, &pvt->info.mc_status); pci_read_config_dword(pvt->pci_mcr[0], MC_MAX_DOD, - &pvt->info.max_dod); + &pvt->info.max_dod); pci_read_config_dword(pvt->pci_mcr[0], MC_CHANNEL_MAPPER, &pvt->info.ch_map); @@ -373,10 +377,16 @@ static int get_dimm_config(struct mem_ctl_info *mci) pvt->info.mc_control, pvt->info.mc_status, pvt->info.max_dod, pvt->info.ch_map); - if (ECC_ENABLED(pvt)) + if (ECC_ENABLED(pvt)) { debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt)?8:4); - else + if (ECCx8(pvt)) + mode = EDAC_S8ECD8ED; + else + mode = EDAC_S4ECD4ED; + } else { debugf0("ECC disabled\n"); + mode = EDAC_NONE; + } /* FIXME: need to handle the error codes */ debugf0("DOD Maximum limits: DIMMS: %d, %d-ranked, %d-banked\n", @@ -411,13 +421,31 @@ static int get_dimm_config(struct mem_ctl_info *mci) else pvt->channel[i].dimms = 2; - debugf0("Ch%d (0x%08x): rd ch %d, wr ch %d, " - "%d ranks, %d %cDIMMs\n", - i, data, - RDLCH(pvt->info.ch_map, i), - WRLCH(pvt->info.ch_map, i), + debugf0("Ch%d phy rd%d, wr%d (0x%08x): " + "%d ranks, %d %cDIMMs, offset = %d\n", + i, + RDLCH(pvt->info.ch_map, i), WRLCH(pvt->info.ch_map, i), + data, pvt->channel[i].ranks, pvt->channel[i].dimms, - (data & REGISTERED_DIMM)? 'R' : 'U' ); + (data & REGISTERED_DIMM)? 'R' : 'U', + RANKOFFSET(data)); + + csr = &mci->csrows[csrow]; + csr->first_page = 0; + csr->last_page = 0; + csr->page_mask = 0; + csr->nr_pages = 0; + csr->grain = 0; + csr->csrow_idx = csrow; + csr->dtype = DEV_X8; /* FIXME: check this */ + + if (data & REGISTERED_DIMM) + csr->mtype = MEM_RDDR3; + else + csr->mtype = MEM_DDR3; + csr->edac_mode = mode; + + csrow++; } return 0; -- cgit v1.2.3 From b7c761512c5412eb30be567a0640060cccfc372f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2009 22:48:30 -0300 Subject: i7core_edac: Improve error handling Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 556a150e645b..62ae472c4e27 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -328,8 +328,10 @@ static int i7core_get_active_channels(int *channels) } } - if (!pdev) + if (!pdev) { + i7core_printk(KERN_ERR, "Couldn't find fn 3.0!!!\n"); return -ENODEV; + } /* Device 3 function 0 reads */ pci_read_config_dword(pdev, MC_STATUS, &status); @@ -1109,16 +1111,19 @@ static int __devinit i7core_probe(struct pci_dev *pdev, int num_channels = 0; int num_csrows; int dev_idx = id->driver_data; + int rc; if (unlikely(dev_idx >= ARRAY_SIZE(i7core_devs))) return -EINVAL; /* get the pci devices we want to reserve for our use */ - if (unlikely(i7core_get_devices() < 0)) - return -ENODEV; + rc = i7core_get_devices(); + if (unlikely(rc < 0)) + return rc; /* Check the number of active and not disabled channels */ - if (unlikely (i7core_get_active_channels(&num_channels)) < 0) + rc = i7core_get_active_channels(&num_channels); + if (unlikely (rc < 0)) goto fail0; /* FIXME: we currently don't know the number of csrows */ @@ -1126,8 +1131,10 @@ static int __devinit i7core_probe(struct pci_dev *pdev, /* allocate a new MC control structure */ mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0); - if (unlikely (!mci)) - return -ENOMEM; + if (unlikely (!mci)) { + rc = -ENOMEM; + goto fail0; + } debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); @@ -1150,19 +1157,22 @@ static int __devinit i7core_probe(struct pci_dev *pdev, mci->edac_check = i7core_check_error; /* Store pci devices at mci for faster access */ - if (unlikely (mci_bind_devs(mci)) < 0) + rc = mci_bind_devs(mci); + if (unlikely (rc < 0)) goto fail1; /* Get dimm basic config */ get_dimm_config(mci); /* add this new MC control structure to EDAC's list of MCs */ - if (unlikely(edac_mc_add_mc(mci)) < 0) { + if (unlikely(edac_mc_add_mc(mci))) { debugf0("MC: " __FILE__ ": %s(): failed edac_mc_add_mc()\n", __func__); /* FIXME: perhaps some code should go here that disables error * reporting if we just enabled it */ + + rc = -EINVAL; goto fail1; } @@ -1190,11 +1200,11 @@ static int __devinit i7core_probe(struct pci_dev *pdev, return 0; fail1: - i7core_put_devices(); + edac_mc_free(mci); fail0: - edac_mc_free(mci); - return -ENODEV; + i7core_put_devices(); + return rc; } /* -- cgit v1.2.3 From 7dd6953c5fecc44d264710e1fa158d0038215b63 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2009 22:48:30 -0300 Subject: i7core_edac: Add more information about each active dimm Thanks-to: Aristeu Rozanski for part of the code Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 62ae472c4e27..a6e798349e93 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -359,21 +359,18 @@ static int get_dimm_config(struct mem_ctl_info *mci) { struct i7core_pvt *pvt = mci->pvt_info; struct csrow_info *csr; - int i, csrow = 0; + struct pci_dev *pdev = pvt->pci_mcr[0]; + int i, j, csrow = 0; enum edac_type mode; - if (!pvt->pci_mcr[0]) + if (!pdev) return -ENODEV; /* Device 3 function 0 reads */ - pci_read_config_dword(pvt->pci_mcr[0], MC_CONTROL, - &pvt->info.mc_control); - pci_read_config_dword(pvt->pci_mcr[0], MC_STATUS, - &pvt->info.mc_status); - pci_read_config_dword(pvt->pci_mcr[0], MC_MAX_DOD, - &pvt->info.max_dod); - pci_read_config_dword(pvt->pci_mcr[0], MC_CHANNEL_MAPPER, - &pvt->info.ch_map); + pci_read_config_dword(pdev, MC_CONTROL, &pvt->info.mc_control); + pci_read_config_dword(pdev, MC_STATUS, &pvt->info.mc_status); + pci_read_config_dword(pdev, MC_MAX_DOD, &pvt->info.max_dod); + pci_read_config_dword(pdev, MC_CHANNEL_MAPPER, &pvt->info.ch_map); debugf0("MC control=0x%08x status=0x%08x dod=0x%08x map=0x%08x\n", pvt->info.mc_control, pvt->info.mc_status, @@ -399,7 +396,7 @@ static int get_dimm_config(struct mem_ctl_info *mci) debugf0("Memory channel configuration:\n"); for (i = 0; i < NUM_CHANS; i++) { - u32 data; + u32 data, value[8]; if (!CH_ACTIVE(pvt, i)) { debugf0("Channel %i is not active\n", i); @@ -424,13 +421,33 @@ static int get_dimm_config(struct mem_ctl_info *mci) pvt->channel[i].dimms = 2; debugf0("Ch%d phy rd%d, wr%d (0x%08x): " - "%d ranks, %d %cDIMMs, offset = %d\n", + "%d ranks, %d %cDIMMs, offset = %d\n\t" + "present: %i, numbank: %#x, numrank: %#x, " + "numrow: %#x, numcol: %#x\n", i, RDLCH(pvt->info.ch_map, i), WRLCH(pvt->info.ch_map, i), data, pvt->channel[i].ranks, pvt->channel[i].dimms, (data & REGISTERED_DIMM)? 'R' : 'U', - RANKOFFSET(data)); + RANKOFFSET(data), + DIMM_PRESENT(data), + NUMBANK(data), NUMRANK(data), + NUMROW(data), NUMCOL(data)); + + pci_read_config_dword(pdev, MC_SAG_CH_0, &value[0]); + pci_read_config_dword(pdev, MC_SAG_CH_1, &value[1]); + pci_read_config_dword(pdev, MC_SAG_CH_2, &value[2]); + pci_read_config_dword(pdev, MC_SAG_CH_3, &value[3]); + pci_read_config_dword(pdev, MC_SAG_CH_4, &value[4]); + pci_read_config_dword(pdev, MC_SAG_CH_5, &value[5]); + pci_read_config_dword(pdev, MC_SAG_CH_6, &value[6]); + pci_read_config_dword(pdev, MC_SAG_CH_7, &value[7]); + printk("\t[%i] DIVBY3\tREMOVED\tOFFSET\n", i); + for (j = 0; j < 8; j++) + printk("\t\t%#x\t%#x\t%#x\n", + (value[j] >> 27) & 0x1, + (value[j] >> 24) & 0x7, + (value[j] && ((1 << 24) - 1))); csr = &mci->csrows[csrow]; csr->first_page = 0; -- cgit v1.2.3 From 854d3349973a7c47bd989794037f526b74af20c4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2009 22:48:30 -0300 Subject: i7core_edac: Get more info about the memory DIMMs Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 170 ++++++++++++++++++++++++++++----------------- 1 file changed, 107 insertions(+), 63 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index a6e798349e93..483cca2e543b 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -109,14 +109,14 @@ #define RANKOFFSET(x) ((x & RANKOFFSET_MASK) >> 10) #define DIMM_PRESENT_MASK (1 << 9) #define DIMM_PRESENT(x) (((x) & DIMM_PRESENT_MASK) >> 9) - #define NUMBANK_MASK ((1 << 8) | (1 << 7)) - #define NUMBANK(x) (((x) & NUMBANK_MASK) >> 7) - #define NUMRANK_MASK ((1 << 6) | (1 << 5)) - #define NUMRANK(x) (((x) & NUMRANK_MASK) >> 5) - #define NUMROW_MASK ((1 << 4) | (1 << 3)) - #define NUMROW(x) (((x) & NUMROW_MASK) >> 3) - #define NUMCOL_MASK 3 - #define NUMCOL(x) ((x) & NUMCOL_MASK) + #define MC_DOD_NUMBANK_MASK ((1 << 8) | (1 << 7)) + #define MC_DOD_NUMBANK(x) (((x) & MC_DOD_NUMBANK_MASK) >> 7) + #define MC_DOD_NUMRANK_MASK ((1 << 6) | (1 << 5)) + #define MC_DOD_NUMRANK(x) (((x) & MC_DOD_NUMRANK_MASK) >> 5) + #define MC_DOD_NUMROW_MASK ((1 << 4) | (1 << 3)) + #define MC_DOD_NUMROW(x) (((x) & MC_DOD_NUMROW_MASK) >> 3) + #define MC_DOD_NUMCOL_MASK 3 + #define MC_DOD_NUMCOL(x) ((x) & MC_DOD_NUMCOL_MASK) #define MC_RANK_PRESENT 0x7c @@ -268,41 +268,41 @@ static struct edac_pci_ctl_info *i7core_pci; #define CH_DISABLED(pvt, ch) ((pvt)->info.mc_status & (1 << ch)) /* MC_MAX_DOD read functions */ -static inline int maxnumdimms(struct i7core_pvt *pvt) +static inline int numdimms(u32 dimms) { - return (pvt->info.max_dod & 0x3) + 1; + return (dimms & 0x3) + 1; } -static inline int maxnumrank(struct i7core_pvt *pvt) +static inline int numrank(u32 rank) { static int ranks[4] = { 1, 2, 4, -EINVAL }; - return ranks[(pvt->info.max_dod >> 2) & 0x3]; + return ranks[rank & 0x3]; } -static inline int maxnumbank(struct i7core_pvt *pvt) +static inline int numbank(u32 bank) { static int banks[4] = { 4, 8, 16, -EINVAL }; - return banks[(pvt->info.max_dod >> 4) & 0x3]; + return banks[bank & 0x3]; } -static inline int maxnumrow(struct i7core_pvt *pvt) +static inline int numrow(u32 row) { static int rows[8] = { 1 << 12, 1 << 13, 1 << 14, 1 << 15, 1 << 16, -EINVAL, -EINVAL, -EINVAL, }; - return rows[((pvt->info.max_dod >> 6) & 0x7)]; + return rows[row & 0x7]; } -static inline int maxnumcol(struct i7core_pvt *pvt) +static inline int numcol(u32 col) { static int cols[8] = { 1 << 10, 1 << 11, 1 << 12, -EINVAL, }; - return cols[((pvt->info.max_dod >> 9) & 0x3) << 12]; + return cols[col & 0x3]; } @@ -359,10 +359,13 @@ static int get_dimm_config(struct mem_ctl_info *mci) { struct i7core_pvt *pvt = mci->pvt_info; struct csrow_info *csr; - struct pci_dev *pdev = pvt->pci_mcr[0]; + struct pci_dev *pdev; int i, j, csrow = 0; enum edac_type mode; + enum mem_type mtype; + /* Get data from the MC register, function 0 */ + pdev = pvt->pci_mcr[0]; if (!pdev) return -ENODEV; @@ -388,15 +391,18 @@ static int get_dimm_config(struct mem_ctl_info *mci) } /* FIXME: need to handle the error codes */ - debugf0("DOD Maximum limits: DIMMS: %d, %d-ranked, %d-banked\n", - maxnumdimms(pvt), maxnumrank(pvt), maxnumbank(pvt)); - debugf0("DOD Maximum rows x colums = 0x%x x 0x%x\n", - maxnumrow(pvt), maxnumcol(pvt)); + debugf0("DOD Max limits: DIMMS: %d, %d-ranked, %d-banked\n", + numdimms(pvt->info.max_dod), + numrank(pvt->info.max_dod >> 2), + numbank(pvt->info.max_dod >> 4)); + debugf0("DOD Max rows x colums = 0x%x x 0x%x\n", + numrow(pvt->info.max_dod >> 6), + numcol(pvt->info.max_dod >> 9)); debugf0("Memory channel configuration:\n"); for (i = 0; i < NUM_CHANS; i++) { - u32 data, value[8]; + u32 data, dimm_dod[3], value[8]; if (!CH_ACTIVE(pvt, i)) { debugf0("Channel %i is not active\n", i); @@ -413,58 +419,96 @@ static int get_dimm_config(struct mem_ctl_info *mci) pvt->channel[i].ranks = (data & QUAD_RANK_PRESENT)? 4 : 2; + if (data & REGISTERED_DIMM) + mtype = MEM_RDDR3; + else + mtype = MEM_DDR3; +#if 0 if (data & THREE_DIMMS_PRESENT) pvt->channel[i].dimms = 3; else if (data & SINGLE_QUAD_RANK_PRESENT) pvt->channel[i].dimms = 1; else pvt->channel[i].dimms = 2; +#endif + + /* Devices 4-6 function 1 */ + pci_read_config_dword(pvt->pci_ch[i][1], + MC_DOD_CH_DIMM0, &dimm_dod[0]); + pci_read_config_dword(pvt->pci_ch[i][1], + MC_DOD_CH_DIMM1, &dimm_dod[1]); + pci_read_config_dword(pvt->pci_ch[i][1], + MC_DOD_CH_DIMM2, &dimm_dod[2]); debugf0("Ch%d phy rd%d, wr%d (0x%08x): " - "%d ranks, %d %cDIMMs, offset = %d\n\t" - "present: %i, numbank: %#x, numrank: %#x, " - "numrow: %#x, numcol: %#x\n", + "%d ranks, %cDIMMs\n", i, RDLCH(pvt->info.ch_map, i), WRLCH(pvt->info.ch_map, i), data, - pvt->channel[i].ranks, pvt->channel[i].dimms, - (data & REGISTERED_DIMM)? 'R' : 'U', - RANKOFFSET(data), - DIMM_PRESENT(data), - NUMBANK(data), NUMRANK(data), - NUMROW(data), NUMCOL(data)); - - pci_read_config_dword(pdev, MC_SAG_CH_0, &value[0]); - pci_read_config_dword(pdev, MC_SAG_CH_1, &value[1]); - pci_read_config_dword(pdev, MC_SAG_CH_2, &value[2]); - pci_read_config_dword(pdev, MC_SAG_CH_3, &value[3]); - pci_read_config_dword(pdev, MC_SAG_CH_4, &value[4]); - pci_read_config_dword(pdev, MC_SAG_CH_5, &value[5]); - pci_read_config_dword(pdev, MC_SAG_CH_6, &value[6]); - pci_read_config_dword(pdev, MC_SAG_CH_7, &value[7]); - printk("\t[%i] DIVBY3\tREMOVED\tOFFSET\n", i); - for (j = 0; j < 8; j++) - printk("\t\t%#x\t%#x\t%#x\n", - (value[j] >> 27) & 0x1, - (value[j] >> 24) & 0x7, - (value[j] && ((1 << 24) - 1))); - - csr = &mci->csrows[csrow]; - csr->first_page = 0; - csr->last_page = 0; - csr->page_mask = 0; - csr->nr_pages = 0; - csr->grain = 0; - csr->csrow_idx = csrow; - csr->dtype = DEV_X8; /* FIXME: check this */ + pvt->channel[i].ranks, + (data & REGISTERED_DIMM)? 'R' : 'U'); - if (data & REGISTERED_DIMM) - csr->mtype = MEM_RDDR3; - else - csr->mtype = MEM_DDR3; - csr->edac_mode = mode; + for (j = 0; j < 3; j++) { + u32 banks, ranks, rows, cols; + + if (!DIMM_PRESENT(dimm_dod[j])) + continue; + + banks = numbank(MC_DOD_NUMBANK(dimm_dod[j])); + ranks = numrank(MC_DOD_NUMRANK(dimm_dod[j])); + rows = numrow(MC_DOD_NUMROW(dimm_dod[j])); + cols = numcol(MC_DOD_NUMCOL(dimm_dod[j])); + + pvt->channel[i].dimms++; + + debugf0("\tdimm %d offset: %x, numbank: %#x, " + "numrank: %#x, numrow: %#x, numcol: %#x\n", + j, + RANKOFFSET(dimm_dod[j]), + banks, ranks, rows, cols); + + csr = &mci->csrows[csrow]; + csr->first_page = 0; + csr->last_page = 0; + csr->page_mask = 0; + csr->nr_pages = 0; + csr->grain = 0; + csr->csrow_idx = csrow; + + switch (banks) { + case 4: + csr->dtype = DEV_X4; + break; + case 8: + csr->dtype = DEV_X8; + break; + case 16: + csr->dtype = DEV_X16; + break; + default: + csr->dtype = DEV_UNKNOWN; + } + + csr->edac_mode = mode; + csr->mtype = mtype; + + csrow++; + } - csrow++; + pci_read_config_dword(pdev, MC_SAG_CH_0, &value[0]); + pci_read_config_dword(pdev, MC_SAG_CH_1, &value[1]); + pci_read_config_dword(pdev, MC_SAG_CH_2, &value[2]); + pci_read_config_dword(pdev, MC_SAG_CH_3, &value[3]); + pci_read_config_dword(pdev, MC_SAG_CH_4, &value[4]); + pci_read_config_dword(pdev, MC_SAG_CH_5, &value[5]); + pci_read_config_dword(pdev, MC_SAG_CH_6, &value[6]); + pci_read_config_dword(pdev, MC_SAG_CH_7, &value[7]); + printk("\t[%i] DIVBY3\tREMOVED\tOFFSET\n", i); + for (j = 0; j < 8; j++) + printk("\t\t%#x\t%#x\t%#x\n", + (value[j] >> 27) & 0x1, + (value[j] >> 24) & 0x7, + (value[j] && ((1 << 24) - 1))); } return 0; -- cgit v1.2.3 From 5566cb7c91ba4ff4447278bb27896b4a2bb7d18a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2009 22:48:31 -0300 Subject: i7core_edac: Memory info fixes and preparation for properly filling cswrow data Now, memory size is properly displayed: EDAC i7core: DOD Max limits: DIMMS: 2, 1-ranked, 8-banked EDAC i7core: DOD Max rows x colums = 0x4000 x 0x400 EDAC i7core: Memory channel configuration: EDAC i7core: Ch0 phy rd0, wr0 (0x063f7c31): 2 ranks, UDIMMs EDAC i7core: dimm 0 (0x00000288) 1024 Mb offset: 0, numbank: 8, numrank: 1, numrow: 0x4000, numcol: 0x400 EDAC i7core: dimm 1 (0x00001288) 1024 Mb offset: 4, numbank: 8, numrank: 1, numrow: 0x4000, numcol: 0x400 EDAC i7core: Ch1 phy rd1, wr1 (0x063f7c31): 2 ranks, UDIMMs EDAC i7core: dimm 0 (0x00000288) 1024 Mb offset: 0, numbank: 8, numrank: 1, numrow: 0x4000, numcol: 0x400 EDAC i7core: Ch2 phy rd3, wr3 (0x063f7c31): 2 ranks, UDIMMs EDAC i7core: dimm 0 (0x00000288) 1024 Mb offset: 0, numbank: 8, numrank: 1, numrow: 0x4000, numcol: 0x400 Still, as the way to retrieve csrows info is not known, it does a mapping of what's available to csrows basic unit at edac core. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 483cca2e543b..772219fa10be 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -113,8 +113,8 @@ #define MC_DOD_NUMBANK(x) (((x) & MC_DOD_NUMBANK_MASK) >> 7) #define MC_DOD_NUMRANK_MASK ((1 << 6) | (1 << 5)) #define MC_DOD_NUMRANK(x) (((x) & MC_DOD_NUMRANK_MASK) >> 5) - #define MC_DOD_NUMROW_MASK ((1 << 4) | (1 << 3)) - #define MC_DOD_NUMROW(x) (((x) & MC_DOD_NUMROW_MASK) >> 3) + #define MC_DOD_NUMROW_MASK ((1 << 4) | (1 << 3)| (1 << 2)) + #define MC_DOD_NUMROW(x) (((x) & MC_DOD_NUMROW_MASK) >> 2) #define MC_DOD_NUMCOL_MASK 3 #define MC_DOD_NUMCOL(x) ((x) & MC_DOD_NUMCOL_MASK) @@ -361,6 +361,7 @@ static int get_dimm_config(struct mem_ctl_info *mci) struct csrow_info *csr; struct pci_dev *pdev; int i, j, csrow = 0; + unsigned long last_page = 0; enum edac_type mode; enum mem_type mtype; @@ -380,7 +381,7 @@ static int get_dimm_config(struct mem_ctl_info *mci) pvt->info.max_dod, pvt->info.ch_map); if (ECC_ENABLED(pvt)) { - debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt)?8:4); + debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt) ?8:4); if (ECCx8(pvt)) mode = EDAC_S8ECD8ED; else @@ -450,6 +451,7 @@ static int get_dimm_config(struct mem_ctl_info *mci) for (j = 0; j < 3; j++) { u32 banks, ranks, rows, cols; + u32 size, npages; if (!DIMM_PRESENT(dimm_dod[j])) continue; @@ -459,19 +461,27 @@ static int get_dimm_config(struct mem_ctl_info *mci) rows = numrow(MC_DOD_NUMROW(dimm_dod[j])); cols = numcol(MC_DOD_NUMCOL(dimm_dod[j])); + /* DDR3 has 8 I/O banks */ + size = (rows * cols * banks * ranks) >> (20 - 3); + pvt->channel[i].dimms++; - debugf0("\tdimm %d offset: %x, numbank: %#x, " - "numrank: %#x, numrow: %#x, numcol: %#x\n", - j, + debugf0("\tdimm %d (0x%08x) %d Mb offset: %x, " + "numbank: %d,\n\t\t" + "numrank: %d, numrow: %#x, numcol: %#x\n", + j, dimm_dod[j], size, RANKOFFSET(dimm_dod[j]), banks, ranks, rows, cols); + npages = cols * rows; /* FIXME */ + csr = &mci->csrows[csrow]; - csr->first_page = 0; - csr->last_page = 0; + csr->first_page = last_page + 1; + last_page += npages; + csr->last_page = last_page; + csr->nr_pages = npages; + csr->page_mask = 0; - csr->nr_pages = 0; csr->grain = 0; csr->csrow_idx = csrow; -- cgit v1.2.3 From eb94fc402f1592dfe847b245d9109c11a99a2ea1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2009 22:48:31 -0300 Subject: i7core_edac: fill csrows edac sysfs info csrows is still fake, since we can't identify its representation with Nehalem registers. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 66 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 772219fa10be..e0a3b217c52b 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -309,25 +309,33 @@ static inline int numcol(u32 col) /**************************************************************************** Memory check routines ****************************************************************************/ -static int i7core_get_active_channels(int *channels) +static struct pci_dev *get_pdev_slot_func(int slot, int func) { - struct pci_dev *pdev = NULL; int i; - u32 status, control; - - *channels = 0; for (i = 0; i < N_DEVS; i++) { if (!pci_devs[i].pdev) continue; - if (PCI_SLOT(pci_devs[i].pdev->devfn) == 3 && - PCI_FUNC(pci_devs[i].pdev->devfn) == 0) { - pdev = pci_devs[i].pdev; - break; + if (PCI_SLOT(pci_devs[i].pdev->devfn) == slot && + PCI_FUNC(pci_devs[i].pdev->devfn) == func) { + return pci_devs[i].pdev; } } + return NULL; +} + +static int i7core_get_active_channels(int *channels, int *csrows) +{ + struct pci_dev *pdev = NULL; + int i, j; + u32 status, control; + + *channels = 0; + *csrows = 0; + + pdev = get_pdev_slot_func(3, 0); if (!pdev) { i7core_printk(KERN_ERR, "Couldn't find fn 3.0!!!\n"); return -ENODEV; @@ -338,6 +346,7 @@ static int i7core_get_active_channels(int *channels) pci_read_config_dword(pdev, MC_CONTROL, &control); for (i = 0; i < NUM_CHANS; i++) { + u32 dimm_dod[3]; /* Check if the channel is active */ if (!(control & (1 << (8 + i)))) continue; @@ -347,7 +356,27 @@ static int i7core_get_active_channels(int *channels) continue; } + pdev = get_pdev_slot_func(i + 4, 1); + if (!pdev) { + i7core_printk(KERN_ERR, "Couldn't find fn %d.%d!!!\n", + i + 4, 1); + return -ENODEV; + } + /* Devices 4-6 function 1 */ + pci_read_config_dword(pdev, + MC_DOD_CH_DIMM0, &dimm_dod[0]); + pci_read_config_dword(pdev, + MC_DOD_CH_DIMM1, &dimm_dod[1]); + pci_read_config_dword(pdev, + MC_DOD_CH_DIMM2, &dimm_dod[2]); + (*channels)++; + + for (j = 0; j < 3; j++) { + if (!DIMM_PRESENT(dimm_dod[j])) + continue; + (*csrows)++; + } } debugf0("Number of active channels: %d\n", *channels); @@ -473,7 +502,11 @@ static int get_dimm_config(struct mem_ctl_info *mci) RANKOFFSET(dimm_dod[j]), banks, ranks, rows, cols); - npages = cols * rows; /* FIXME */ +#if PAGE_SHIFT > 20 + npages = size >> (PAGE_SHIFT - 20); +#else + npages = size << (20 - PAGE_SHIFT); +#endif csr = &mci->csrows[csrow]; csr->first_page = last_page + 1; @@ -482,8 +515,12 @@ static int get_dimm_config(struct mem_ctl_info *mci) csr->nr_pages = npages; csr->page_mask = 0; - csr->grain = 0; + csr->grain = 8; csr->csrow_idx = csrow; + csr->nr_channels = 1; + + csr->channels[0].chan_idx = i; + csr->channels[0].ce_count = 0; switch (banks) { case 4: @@ -1179,7 +1216,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, { struct mem_ctl_info *mci; struct i7core_pvt *pvt; - int num_channels = 0; + int num_channels; int num_csrows; int dev_idx = id->driver_data; int rc; @@ -1193,13 +1230,10 @@ static int __devinit i7core_probe(struct pci_dev *pdev, return rc; /* Check the number of active and not disabled channels */ - rc = i7core_get_active_channels(&num_channels); + rc = i7core_get_active_channels(&num_channels, &num_csrows); if (unlikely (rc < 0)) goto fail0; - /* FIXME: we currently don't know the number of csrows */ - num_csrows = num_channels; - /* allocate a new MC control structure */ mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0); if (unlikely (!mci)) { -- cgit v1.2.3 From 41fcb7feed70d8076f1591664314ca172fcdff7b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Jun 2009 22:48:31 -0300 Subject: i7core_edac: CodingStyle fixes Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 59 +++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index e0a3b217c52b..914914759690 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -113,7 +113,7 @@ #define MC_DOD_NUMBANK(x) (((x) & MC_DOD_NUMBANK_MASK) >> 7) #define MC_DOD_NUMRANK_MASK ((1 << 6) | (1 << 5)) #define MC_DOD_NUMRANK(x) (((x) & MC_DOD_NUMRANK_MASK) >> 5) - #define MC_DOD_NUMROW_MASK ((1 << 4) | (1 << 3)| (1 << 2)) + #define MC_DOD_NUMROW_MASK ((1 << 4) | (1 << 3) | (1 << 2)) #define MC_DOD_NUMROW(x) (((x) & MC_DOD_NUMROW_MASK) >> 2) #define MC_DOD_NUMCOL_MASK 3 #define MC_DOD_NUMCOL(x) ((x) & MC_DOD_NUMCOL_MASK) @@ -352,9 +352,8 @@ static int i7core_get_active_channels(int *channels, int *csrows) continue; /* Check if the channel is disabled */ - if (status & (1 << i)) { + if (status & (1 << i)) continue; - } pdev = get_pdev_slot_func(i + 4, 1); if (!pdev) { @@ -410,7 +409,7 @@ static int get_dimm_config(struct mem_ctl_info *mci) pvt->info.max_dod, pvt->info.ch_map); if (ECC_ENABLED(pvt)) { - debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt) ?8:4); + debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt) ? 8 : 4); if (ECCx8(pvt)) mode = EDAC_S8ECD8ED; else @@ -447,7 +446,7 @@ static int get_dimm_config(struct mem_ctl_info *mci) pci_read_config_dword(pvt->pci_ch[i][0], MC_CHANNEL_DIMM_INIT_PARAMS, &data); - pvt->channel[i].ranks = (data & QUAD_RANK_PRESENT)? 4 : 2; + pvt->channel[i].ranks = (data & QUAD_RANK_PRESENT) ? 4 : 2; if (data & REGISTERED_DIMM) mtype = MEM_RDDR3; @@ -476,7 +475,7 @@ static int get_dimm_config(struct mem_ctl_info *mci) RDLCH(pvt->info.ch_map, i), WRLCH(pvt->info.ch_map, i), data, pvt->channel[i].ranks, - (data & REGISTERED_DIMM)? 'R' : 'U'); + (data & REGISTERED_DIMM) ? 'R' : 'U'); for (j = 0; j < 3; j++) { u32 banks, ranks, rows, cols; @@ -550,9 +549,9 @@ static int get_dimm_config(struct mem_ctl_info *mci) pci_read_config_dword(pdev, MC_SAG_CH_5, &value[5]); pci_read_config_dword(pdev, MC_SAG_CH_6, &value[6]); pci_read_config_dword(pdev, MC_SAG_CH_7, &value[7]); - printk("\t[%i] DIVBY3\tREMOVED\tOFFSET\n", i); + debugf0("\t[%i] DIVBY3\tREMOVED\tOFFSET\n", i); for (j = 0; j < 8; j++) - printk("\t\t%#x\t%#x\t%#x\n", + debugf0("\t\t%#x\t%#x\t%#x\n", (value[j] >> 27) & 0x1, (value[j] >> 24) & 0x7, (value[j] && ((1 << 24) - 1))); @@ -602,7 +601,7 @@ static ssize_t i7core_inject_section_store(struct mem_ctl_info *mci, int rc; if (pvt->inject.enable) - disable_inject(mci); + disable_inject(mci); rc = strict_strtoul(data, 10, &value); if ((rc < 0) || (value > 3)) @@ -635,7 +634,7 @@ static ssize_t i7core_inject_type_store(struct mem_ctl_info *mci, int rc; if (pvt->inject.enable) - disable_inject(mci); + disable_inject(mci); rc = strict_strtoul(data, 10, &value); if ((rc < 0) || (value > 7)) @@ -670,7 +669,7 @@ static ssize_t i7core_inject_eccmask_store(struct mem_ctl_info *mci, int rc; if (pvt->inject.enable) - disable_inject(mci); + disable_inject(mci); rc = strict_strtoul(data, 10, &value); if (rc < 0) @@ -706,7 +705,7 @@ static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci, int rc; if (pvt->inject.enable) - disable_inject(mci); + disable_inject(mci); do { cmd = strsep((char **) &data, ":"); @@ -716,7 +715,7 @@ static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci, if (!val) return cmd - data; - if (!strcasecmp(val,"any")) + if (!strcasecmp(val, "any")) value = -1; else { rc = strict_strtol(val, 10, &value); @@ -724,33 +723,33 @@ static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci, return cmd - data; } - if (!strcasecmp(cmd,"channel")) { + if (!strcasecmp(cmd, "channel")) { if (value < 3) pvt->inject.channel = value; else return cmd - data; - } else if (!strcasecmp(cmd,"dimm")) { + } else if (!strcasecmp(cmd, "dimm")) { if (value < 4) pvt->inject.dimm = value; else return cmd - data; - } else if (!strcasecmp(cmd,"rank")) { + } else if (!strcasecmp(cmd, "rank")) { if (value < 4) pvt->inject.rank = value; else return cmd - data; - } else if (!strcasecmp(cmd,"bank")) { + } else if (!strcasecmp(cmd, "bank")) { if (value < 4) pvt->inject.bank = value; else return cmd - data; - } else if (!strcasecmp(cmd,"page")) { + } else if (!strcasecmp(cmd, "page")) { if (value <= 0xffff) pvt->inject.page = value; else return cmd - data; - } else if (!strcasecmp(cmd,"col") || - !strcasecmp(cmd,"column")) { + } else if (!strcasecmp(cmd, "col") || + !strcasecmp(cmd, "column")) { if (value <= 0x3fff) pvt->inject.col = value; else @@ -923,7 +922,8 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0], MC_CHANNEL_ERROR_MASK, injectmask); - debugf0("Error inject addr match 0x%016llx, ecc 0x%08x, inject 0x%08x\n", + debugf0("Error inject addr match 0x%016llx, ecc 0x%08x," + " inject 0x%08x\n", mask, pvt->inject.eccmask, injectmask); @@ -1048,7 +1048,7 @@ static int i7core_get_devices(void) "Device not found: PCI ID %04x:%04x " "(dev %d, func %d)\n", PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id, - pci_devs[i].dev,pci_devs[i].func); + pci_devs[i].dev, pci_devs[i].func); /* Dev 3 function 2 only exists on chips with RDIMMs */ if ((pci_devs[i].dev == 3) && (pci_devs[i].func == 2)) @@ -1231,12 +1231,12 @@ static int __devinit i7core_probe(struct pci_dev *pdev, /* Check the number of active and not disabled channels */ rc = i7core_get_active_channels(&num_channels, &num_csrows); - if (unlikely (rc < 0)) + if (unlikely(rc < 0)) goto fail0; /* allocate a new MC control structure */ mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0); - if (unlikely (!mci)) { + if (unlikely(!mci)) { rc = -ENOMEM; goto fail0; } @@ -1249,7 +1249,12 @@ static int __devinit i7core_probe(struct pci_dev *pdev, memset(pvt, 0, sizeof(*pvt)); mci->mc_idx = 0; - mci->mtype_cap = MEM_FLAG_DDR3; /* FIXME: how to handle RDDR3? */ + /* + * FIXME: how to handle RDDR3 at MCI level? It is possible to have + * Mixed RDDR3/UDDR3 with Nehalem, provided that they are on different + * memory channels + */ + mci->mtype_cap = MEM_FLAG_DDR3; mci->edac_ctl_cap = EDAC_FLAG_NONE; mci->edac_cap = EDAC_FLAG_NONE; mci->mod_name = "i7core_edac.c"; @@ -1263,7 +1268,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, /* Store pci devices at mci for faster access */ rc = mci_bind_devs(mci); - if (unlikely (rc < 0)) + if (unlikely(rc < 0)) goto fail1; /* Get dimm basic config */ @@ -1283,7 +1288,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, /* allocating generic PCI control info */ i7core_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR); - if (unlikely (!i7core_pci)) { + if (unlikely(!i7core_pci)) { printk(KERN_WARNING "%s(): Unable to create PCI control\n", __func__); -- cgit v1.2.3 From 696e409dbd1ce325129c5030267365619364dfa0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 23 Jul 2009 06:57:45 -0300 Subject: edac_mce: Add an interface driver to report mce errors via edac edac_mce module is an interface module that gets mcelog data and forwards to any registered edac module that expects to receive data via mce. Signed-off-by: Mauro Carvalho Chehab --- arch/x86/kernel/cpu/mcheck/mce.c | 10 +++++++ drivers/edac/Kconfig | 8 +++++- drivers/edac/Makefile | 1 + drivers/edac/edac_mce.c | 58 ++++++++++++++++++++++++++++++++++++++++ include/linux/edac_mce.h | 31 +++++++++++++++++++++ 5 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 drivers/edac/edac_mce.c create mode 100644 include/linux/edac_mce.h (limited to 'drivers') diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 8a6f0afa767e..6585ff07ddf5 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -168,6 +169,15 @@ void mce_log(struct mce *mce) for (;;) { entry = rcu_dereference_check_mce(mcelog.next); for (;;) { + /* + * If edac_mce is enabled, it will check the error type + * and will process it, if it is a known error. + * Otherwise, the error will be sent through mcelog + * interface + */ + if (edac_mce_parse(mce)) + return; + /* * When the buffer fills up discard new entries. * Assume that the earlier errors are the more diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 391ddbfb2a34..5b7fbc5aec87 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -69,6 +69,9 @@ config EDAC_MM_EDAC occurred so that a particular failing memory module can be replaced. If unsure, select 'Y'. +config EDAC_MCE + tristate + config EDAC_AMD64 tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h" depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI && EDAC_DECODE_MCE @@ -169,9 +172,12 @@ config EDAC_I5400 config EDAC_I7CORE tristate "Intel i7 Core (Nehalem) processors" depends on EDAC_MM_EDAC && PCI && X86 + select EDAC_MCE help Support for error detection and correction the Intel - i7 Core (Nehalem) Integrated Memory Controller + i7 Core (Nehalem) Integrated Memory Controller that exists on + newer processors like i7 Core, i7 Core Extreme, Xeon 35xx + and Xeon 55xx processors. config EDAC_I82860 tristate "Intel 82860" diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile index b9996195b233..ca6b1bb24ccc 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_EDAC) := edac_stub.o obj-$(CONFIG_EDAC_MM_EDAC) += edac_core.o +obj-$(CONFIG_EDAC_MCE) += edac_mce.o edac_core-objs := edac_mc.o edac_device.o edac_mc_sysfs.o edac_pci_sysfs.o edac_core-objs += edac_module.o edac_device_sysfs.o diff --git a/drivers/edac/edac_mce.c b/drivers/edac/edac_mce.c new file mode 100644 index 000000000000..b1efa8e51921 --- /dev/null +++ b/drivers/edac/edac_mce.c @@ -0,0 +1,58 @@ +/* Provides edac interface to mcelog events + * + * This file may be distributed under the terms of the + * GNU General Public License version 2. + * + * Copyright (c) 2009 by: + * Mauro Carvalho Chehab + * + * Red Hat Inc. http://www.redhat.com + */ + +#include +#include +#include + +int edac_mce_enabled; +EXPORT_SYMBOL_GPL(edac_mce_enabled); + + +/* + * Extension interface + */ + +static LIST_HEAD(edac_mce_list); +static DEFINE_MUTEX(edac_mce_lock); + +int edac_mce_register(struct edac_mce *edac_mce) +{ + mutex_lock(&edac_mce_lock); + list_add_tail(&edac_mce->list, &edac_mce_list); + mutex_unlock(&edac_mce_lock); + return 0; +} +EXPORT_SYMBOL(edac_mce_register); + +void edac_mce_unregister(struct edac_mce *edac_mce) +{ + mutex_lock(&edac_mce_lock); + list_del(&edac_mce->list); + mutex_unlock(&edac_mce_lock); +} +EXPORT_SYMBOL(edac_mce_unregister); + + + +int edac_mce_queue(struct mce *mce) +{ + struct edac_mce *edac_mce; + + list_for_each_entry(edac_mce, &edac_mce_list, list) { + if (edac_mce->check_error(edac_mce->priv, mce)) + return 1; + } + + /* Nobody queued the error */ + return 0; +} +EXPORT_SYMBOL_GPL(edac_mce_queue); diff --git a/include/linux/edac_mce.h b/include/linux/edac_mce.h new file mode 100644 index 000000000000..f974fc035363 --- /dev/null +++ b/include/linux/edac_mce.h @@ -0,0 +1,31 @@ +/* Provides edac interface to mcelog events + * + * This file may be distributed under the terms of the + * GNU General Public License version 2. + * + * Copyright (c) 2009 by: + * Mauro Carvalho Chehab + * + * Red Hat Inc. http://www.redhat.com + */ + +#if defined(CONFIG_EDAC_MCE) || \ + (defined(CONFIG_EDAC_MCE_MODULE) && defined(MODULE)) + +#include +#include + +struct edac_mce { + struct list_head list; + + void *priv; + int (*check_error)(void *priv, struct mce *mce); +}; + +int edac_mce_register(struct edac_mce *edac_mce); +void edac_mce_unregister(struct edac_mce *edac_mce); +int edac_mce_parse(struct mce *mce); + +#else +#define edac_mce_parse(mce) (0) +#endif -- cgit v1.2.3 From 963c5ba35984c87963480031d1d7e2e556256ad7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 9 Jul 2009 22:04:30 -0300 Subject: edac/Kconfig: edac_mce can't be module Since mcelog is bool, edac_mce glue should also be bool, or otherwise will not work. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 5b7fbc5aec87..aedef7941b22 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -70,7 +70,7 @@ config EDAC_MM_EDAC replaced. If unsure, select 'Y'. config EDAC_MCE - tristate + bool config EDAC_AMD64 tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h" -- cgit v1.2.3 From d5381642ab01b084787925acdf26b5524d434476 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 9 Jul 2009 22:06:41 -0300 Subject: i7core_edac: Add edac_mce glue Adds a glue code to allow i7core to work with mcelog. With the glue, i7core registers itself on edac_mce. At mce, when an error is detected, it calls all registered drivers (in this case, i7core), for EDAC error handling. TODO: It currently just prints the MCE error log using about the same format as mce panic messages. The error message should be enhanced with mcelog userspace info and converted into the proper EDAC format, to feed the EDAC error counts. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/edac_mce.c | 11 +++-- drivers/edac/i7core_edac.c | 111 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 116 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/edac_mce.c b/drivers/edac/edac_mce.c index b1efa8e51921..9ccdc5b140e7 100644 --- a/drivers/edac/edac_mce.c +++ b/drivers/edac/edac_mce.c @@ -41,9 +41,7 @@ void edac_mce_unregister(struct edac_mce *edac_mce) } EXPORT_SYMBOL(edac_mce_unregister); - - -int edac_mce_queue(struct mce *mce) +int edac_mce_parse(struct mce *mce) { struct edac_mce *edac_mce; @@ -55,4 +53,9 @@ int edac_mce_queue(struct mce *mce) /* Nobody queued the error */ return 0; } -EXPORT_SYMBOL_GPL(edac_mce_queue); +EXPORT_SYMBOL_GPL(edac_mce_parse); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); +MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)"); +MODULE_DESCRIPTION("EDAC Driver for mcelog captured errors"); diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 914914759690..3c7bb5f405f6 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include "edac_core.h" @@ -195,6 +197,11 @@ struct i7core_pvt { unsigned long ce_count[MAX_DIMMS]; /* ECC corrected errors counts per dimm */ int last_ce_count[MAX_DIMMS]; + /* mcelog glue */ + struct edac_mce edac_mce; + struct mce mce_entry[MCE_LOG_LEN]; + unsigned mce_count; + spinlock_t mce_lock; }; /* Device name and register DID (Device ID) */ @@ -900,7 +907,7 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0], MC_CHANNEL_ADDR_MATCH + 4, &rdmask2); - debugf0("Inject addr match write 0x%016llx, read: 0x%08x%08x\n", + debugf0("Inject addr match write 0x%016llx, read: 0x%08x 0x%08x\n", mask, rdmask1, rdmask2); #endif #endif @@ -1162,9 +1169,11 @@ static void check_mc_test_err(struct mem_ctl_info *mci) new1 = DIMM1_COR_ERR(rcv0); new0 = DIMM0_COR_ERR(rcv0); +#if 0 debugf2("%s CE rcv1=0x%08x rcv0=0x%08x, %d %d %d\n", (pvt->ce_count_available ? "UPDATE" : "READ"), rcv1, rcv0, new0, new1, new2); +#endif /* Updates CE counters if it is not the first time here */ if (pvt->ce_count_available) { @@ -1195,15 +1204,96 @@ static void check_mc_test_err(struct mem_ctl_info *mci) pvt->last_ce_count[0] = new0; } +static void i7core_mce_output_error(struct mem_ctl_info *mci, + struct mce *m) +{ + debugf0("CPU %d: Machine Check Exception: %16Lx" + "Bank %d: %016Lx\n", + m->cpu, m->mcgstatus, m->bank, m->status); + if (m->ip) { + debugf0("RIP%s %02x:<%016Lx>\n", + !(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "", + m->cs, m->ip); + } + printk(KERN_EMERG "TSC %llx ", m->tsc); + if (m->addr) + printk("ADDR %llx ", m->addr); + if (m->misc) + printk("MISC %llx ", m->misc); + +#if 0 + snprintf(msg, sizeof(msg), + "%s (Branch=%d DRAM-Bank=%d Buffer ID = %d RDWR=%s " + "RAS=%d CAS=%d %s Err=0x%lx (%s))", + type, branch >> 1, bank, buf_id, rdwr_str(rdwr), ras, cas, + type, allErrors, error_name[errnum]); + + /* Call the helper to output message */ + edac_mc_handle_fbd_ue(mci, rank, channel, channel + 1, msg); +#endif +} + /* * i7core_check_error Retrieve and process errors reported by the * hardware. Called by the Core module. */ static void i7core_check_error(struct mem_ctl_info *mci) { + struct i7core_pvt *pvt = mci->pvt_info; + int i; + unsigned count = 0; + struct mce *m = NULL; + unsigned long flags; + + debugf0(__FILE__ ": %s()\n", __func__); + + /* Copy all mce errors into a temporary buffer */ + spin_lock_irqsave(&pvt->mce_lock, flags); + if (pvt->mce_count) { + m = kmalloc(sizeof(*m) * pvt->mce_count, GFP_ATOMIC); + if (m) { + count = pvt->mce_count; + memcpy(m, &pvt->mce_entry, sizeof(*m) * count); + } + pvt->mce_count = 0; + } + spin_unlock_irqrestore(&pvt->mce_lock, flags); + + /* proccess mcelog errors */ + for (i = 0; i < count; i++) + i7core_mce_output_error(mci, &m[i]); + + kfree(m); + + /* check memory count errors */ check_mc_test_err(mci); } +/* + * i7core_mce_check_error Replicates mcelog routine to get errors + * This routine simply queues mcelog errors, and + * return. The error itself should be handled later + * by i7core_check_error. + */ +static int i7core_mce_check_error(void *priv, struct mce *mce) +{ + struct i7core_pvt *pvt = priv; + unsigned long flags; + + debugf0(__FILE__ ": %s()\n", __func__); + + spin_lock_irqsave(&pvt->mce_lock, flags); + if (pvt->mce_count < MCE_LOG_LEN) { + memcpy(&pvt->mce_entry[pvt->mce_count], mce, sizeof(*mce)); + pvt->mce_count++; + } + spin_unlock_irqrestore(&pvt->mce_lock, flags); + + /* Advice mcelog that the error were handled */ +// return 1; + return 0; // Let's duplicate the log +} + /* * i7core_probe Probe for ONE instance of device to see if it is * present. @@ -1305,6 +1395,18 @@ static int __devinit i7core_probe(struct pci_dev *pdev, pvt->inject.page = -1; pvt->inject.col = -1; + /* Registers on edac_mce in order to receive memory errors */ + pvt->edac_mce.priv = pvt; + pvt->edac_mce.check_error = i7core_mce_check_error; + spin_lock_init(&pvt->mce_lock); + + rc = edac_mce_register(&pvt->edac_mce); + if (unlikely (rc < 0)) { + debugf0("MC: " __FILE__ + ": %s(): failed edac_mce_register()\n", __func__); + goto fail1; + } + i7core_printk(KERN_INFO, "Driver loaded.\n"); return 0; @@ -1324,17 +1426,22 @@ fail0: static void __devexit i7core_remove(struct pci_dev *pdev) { struct mem_ctl_info *mci; + struct i7core_pvt *pvt; debugf0(__FILE__ ": %s()\n", __func__); if (i7core_pci) edac_pci_release_generic_ctl(i7core_pci); - mci = edac_mc_del_mc(&pdev->dev); + mci = edac_mc_del_mc(&pdev->dev); if (!mci) return; + /* Unregisters on edac_mce in order to receive memory errors */ + pvt = mci->pvt_info; + edac_mce_unregister(&pvt->edac_mce); + /* retrieve references to resources, and free those resources */ i7core_put_devices(); -- cgit v1.2.3 From e9bd2e73793bf0f7fcd8f94b532bb8f5c5b44171 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 9 Jul 2009 22:14:35 -0300 Subject: i7core_edac: Adds write unlock to MC registers The public Intel Xeon 5500 volume 2 datasheet describes, on page 53, session 2.6.7 a register that can lock/unlock Memory Controller the configuration register, called MC_CFG_CONTROL. Adds support for it in the hope that software error injection would work. With my tests with Xeon 35xx, there's still something missing. With a program that does sequencial bit writes at dev 0.0, sometimes, it produces error injection, after unblocking the MC_CFG_CONTROL (and, sometimes, it just locks my testing machine). I'll try later to discover by trial and error what's the register that solves this issue on Xeon 35xx. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 30 +++++++++++++++++++++++++++--- include/linux/pci_ids.h | 1 + 2 files changed, 28 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 3c7bb5f405f6..26cd5c924d56 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -33,7 +33,7 @@ #include "edac_core.h" /* To use the new pci_[read/write]_config_qword instead of two dword */ -#define USE_QWORD 1 +#define USE_QWORD 0 /* * Alter this version for the module when modifications are made @@ -58,6 +58,10 @@ * i7core Memory Controller Registers */ + /* OFFSETS for Device 0 Function 0 */ + +#define MC_CFG_CONTROL 0x90 + /* OFFSETS for Device 3 Function 0 */ #define MC_CONTROL 0x48 @@ -186,6 +190,7 @@ struct pci_id_descr { }; struct i7core_pvt { + struct pci_dev *pci_noncore; struct pci_dev *pci_mcr[MAX_MCR_FUNC + 1]; struct pci_dev *pci_ch[NUM_CHANS][MAX_CHAN_FUNC + 1]; struct i7core_info info; @@ -222,6 +227,9 @@ struct pci_id_descr pci_devs[] = { { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_I7_MC_RAS) }, /* if RDIMM is supported */ { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_I7_MC_TEST) }, + /* Generic Non-core registers */ + { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_I7_NOCORE) }, + /* Channel 0 */ { PCI_DESCR(4, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH0_CTRL) }, { PCI_DESCR(4, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH0_ADDR) }, @@ -882,6 +890,16 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, else mask |= (pvt->inject.col & 0x3fffL); + /* Unlock writes to registers */ + pci_write_config_dword(pvt->pci_noncore, MC_CFG_CONTROL, 0x2); + msleep(100); + + /* Zeroes error count registers */ + pci_write_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV1, 0); + pci_write_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV0, 0); + pvt->ce_count_available = 0; + + #if USE_QWORD pci_write_config_qword(pvt->pci_ch[pvt->inject.channel][0], MC_CHANNEL_ADDR_MATCH, mask); @@ -929,12 +947,15 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0], MC_CHANNEL_ERROR_MASK, injectmask); +#if 0 + /* lock writes to registers */ + pci_write_config_dword(pvt->pci_noncore, MC_CFG_CONTROL, 0); +#endif debugf0("Error inject addr match 0x%016llx, ecc 0x%08x," " inject 0x%08x\n", mask, pvt->inject.eccmask, injectmask); - return count; } @@ -1124,12 +1145,15 @@ static int mci_bind_devs(struct mem_ctl_info *mci) if (unlikely(func > MAX_CHAN_FUNC)) goto error; pvt->pci_ch[slot - 4][func] = pdev; - } else + } else if (!slot && !func) + pvt->pci_noncore = pdev; + else goto error; debugf0("Associated fn %d.%d, dev = %p\n", PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), pdev); } + return 0; error: diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index c5dd0994bd7c..9d5bfe86ba73 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2548,6 +2548,7 @@ #define PCI_DEVICE_ID_INTEL_I7_MC_CH2_ADDR 0x2c31 #define PCI_DEVICE_ID_INTEL_I7_MC_CH2_RANK 0x2c32 #define PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC 0x2c33 +#define PCI_DEVICE_ID_INTEL_I7_NOCORE 0x2c41 #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340 #define PCI_DEVICE_ID_INTEL_IOAT_TBG4 0x3429 #define PCI_DEVICE_ID_INTEL_IOAT_TBG5 0x342a -- cgit v1.2.3 From d1fd4fb69eeeb7db0693df58b9116db498d5bfe1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 10 Jul 2009 18:39:53 -0300 Subject: i7core_edac: Add a code to probe Xeon 55xx bus This code changes the detection procedure of i7core_edac. Instead of directly probing for MC registers, it probes for another register found on Nehalem. If found, it tries to pick the first MC PCI BUS. This should work fine with Xeon 35xx, but, on Xeon 55xx, this is at bus 254 and 255 that are not properly detected by the non-legacy PCI methods. The new detection code scans specifically at buses 254 and 255 for the Xeon 55xx devices. This code has not tested yet. After working, a change at the code will be needed, since the i7core is not yet ready for working with 2 sets of MC. Signed-off-by: Mauro Carvalho Chehab --- arch/x86/pci/legacy.c | 1 + drivers/edac/i7core_edac.c | 17 +++++++++++++---- include/linux/pci.h | 1 + include/linux/pci_ids.h | 1 + 4 files changed, 16 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c index c734c277b116..d6cc2eddf339 100644 --- a/arch/x86/pci/legacy.c +++ b/arch/x86/pci/legacy.c @@ -57,6 +57,7 @@ void pcibios_scan_specific_bus(int busn) } } } +EXPORT_SYMBOL_GPL(pcibios_scan_specific_bus); int __init pci_subsys_init(void) { diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 26cd5c924d56..eec0c13c0205 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -221,15 +221,15 @@ struct i7core_dev_info { .dev_id = (device_id) struct pci_id_descr pci_devs[] = { + /* Generic Non-core registers */ + { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_I7_NOCORE) }, + /* Memory controller */ { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) }, { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) }, { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_I7_MC_RAS) }, /* if RDIMM is supported */ { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_I7_MC_TEST) }, - /* Generic Non-core registers */ - { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_I7_NOCORE) }, - /* Channel 0 */ { PCI_DESCR(4, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH0_CTRL) }, { PCI_DESCR(4, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH0_ADDR) }, @@ -255,7 +255,7 @@ struct pci_id_descr pci_devs[] = { * This should match the first device at pci_devs table */ static const struct pci_device_id i7core_pci_tbl[] __devinitdata = { - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7_MCR)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_X58_HUB_MGMT)}, {0,} /* 0 terminated list. */ }; @@ -1069,6 +1069,15 @@ static int i7core_get_devices(void) for (i = 0; i < N_DEVS; i++) { pdev = pci_get_device(PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id, NULL); + + if (!pdev && !i) { + pcibios_scan_specific_bus(254); + pcibios_scan_specific_bus(255); + + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, + pci_devs[i].dev_id, NULL); + } + if (likely(pdev)) pci_devs[i].pdev = pdev; else { diff --git a/include/linux/pci.h b/include/linux/pci.h index a788fa12ff31..5e2c7e15187d 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -621,6 +621,7 @@ void pci_fixup_cardbus(struct pci_bus *); /* Generic PCI functions used internally */ +void pcibios_scan_specific_bus(int busn); extern struct pci_bus *pci_find_bus(int domain, int busnr); void pci_bus_add_devices(const struct pci_bus *bus); struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 9d5bfe86ba73..12c3da6ef14d 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2554,6 +2554,7 @@ #define PCI_DEVICE_ID_INTEL_IOAT_TBG5 0x342a #define PCI_DEVICE_ID_INTEL_IOAT_TBG6 0x342b #define PCI_DEVICE_ID_INTEL_IOAT_TBG7 0x342c +#define PCI_DEVICE_ID_INTEL_X58_HUB_MGMT 0x342e #define PCI_DEVICE_ID_INTEL_IOAT_TBG0 0x3430 #define PCI_DEVICE_ID_INTEL_IOAT_TBG1 0x3431 #define PCI_DEVICE_ID_INTEL_IOAT_TBG2 0x3432 -- cgit v1.2.3 From 67166af4abc11d9c0deb497ebe0b562f69c71942 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 15 Jul 2009 06:56:23 -0300 Subject: i7core_edac: add support for more than one MC socket Some Nehalem architectures have more than one MC socket. Socket 0 is located at bus 255. Currently, it is using up to 2 sockets, but increasing it to a larger number is just a matter of increasing MAX_SOCKETS definition. This seems to be required for properly support of Xeon 55xx. Still needs testing with Xeon 55xx. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 326 +++++++++++++++++++++++++++++---------------- 1 file changed, 213 insertions(+), 113 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index eec0c13c0205..69eacc1b50d7 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -155,6 +155,7 @@ #define NUM_CHANS 3 #define MAX_DIMMS 3 /* Max DIMMS per channel */ +#define NUM_SOCKETS 2 /* Max number of MC sockets */ #define MAX_MCR_FUNC 4 #define MAX_CHAN_FUNC 3 @@ -169,6 +170,7 @@ struct i7core_info { struct i7core_inject { int enable; + u8 socket; u32 section; u32 type; u32 eccmask; @@ -186,21 +188,25 @@ struct pci_id_descr { int dev; int func; int dev_id; - struct pci_dev *pdev; + struct pci_dev *pdev[NUM_SOCKETS]; }; struct i7core_pvt { - struct pci_dev *pci_noncore; - struct pci_dev *pci_mcr[MAX_MCR_FUNC + 1]; - struct pci_dev *pci_ch[NUM_CHANS][MAX_CHAN_FUNC + 1]; + struct pci_dev *pci_noncore[NUM_SOCKETS]; + struct pci_dev *pci_mcr[NUM_SOCKETS][MAX_MCR_FUNC + 1]; + struct pci_dev *pci_ch[NUM_SOCKETS][NUM_CHANS][MAX_CHAN_FUNC + 1]; + struct i7core_info info; struct i7core_inject inject; - struct i7core_channel channel[NUM_CHANS]; + struct i7core_channel channel[NUM_SOCKETS][NUM_CHANS]; + + int sockets; /* Number of sockets */ int channels; /* Number of active channels */ - int ce_count_available; - unsigned long ce_count[MAX_DIMMS]; /* ECC corrected errors counts per dimm */ - int last_ce_count[MAX_DIMMS]; + int ce_count_available[NUM_SOCKETS]; + /* ECC corrected errors counts per dimm */ + unsigned long ce_count[NUM_SOCKETS][MAX_DIMMS]; + int last_ce_count[NUM_SOCKETS][MAX_DIMMS]; /* mcelog glue */ struct edac_mce edac_mce; @@ -324,24 +330,26 @@ static inline int numcol(u32 col) /**************************************************************************** Memory check routines ****************************************************************************/ -static struct pci_dev *get_pdev_slot_func(int slot, int func) +static struct pci_dev *get_pdev_slot_func(u8 socket, unsigned slot, + unsigned func) { int i; for (i = 0; i < N_DEVS; i++) { - if (!pci_devs[i].pdev) + if (!pci_devs[i].pdev[socket]) continue; - if (PCI_SLOT(pci_devs[i].pdev->devfn) == slot && - PCI_FUNC(pci_devs[i].pdev->devfn) == func) { - return pci_devs[i].pdev; + if (PCI_SLOT(pci_devs[i].pdev[socket]->devfn) == slot && + PCI_FUNC(pci_devs[i].pdev[socket]->devfn) == func) { + return pci_devs[i].pdev[socket]; } } return NULL; } -static int i7core_get_active_channels(int *channels, int *csrows) +static int i7core_get_active_channels(u8 socket, unsigned *channels, + unsigned *csrows) { struct pci_dev *pdev = NULL; int i, j; @@ -350,9 +358,10 @@ static int i7core_get_active_channels(int *channels, int *csrows) *channels = 0; *csrows = 0; - pdev = get_pdev_slot_func(3, 0); + pdev = get_pdev_slot_func(socket, 3, 0); if (!pdev) { - i7core_printk(KERN_ERR, "Couldn't find fn 3.0!!!\n"); + i7core_printk(KERN_ERR, "Couldn't find socket %d fn 3.0!!!\n", + socket); return -ENODEV; } @@ -370,10 +379,11 @@ static int i7core_get_active_channels(int *channels, int *csrows) if (status & (1 << i)) continue; - pdev = get_pdev_slot_func(i + 4, 1); + pdev = get_pdev_slot_func(socket, i + 4, 1); if (!pdev) { - i7core_printk(KERN_ERR, "Couldn't find fn %d.%d!!!\n", - i + 4, 1); + i7core_printk(KERN_ERR, "Couldn't find socket %d " + "fn %d.%d!!!\n", + socket, i + 4, 1); return -ENODEV; } /* Devices 4-6 function 1 */ @@ -393,12 +403,13 @@ static int i7core_get_active_channels(int *channels, int *csrows) } } - debugf0("Number of active channels: %d\n", *channels); + debugf0("Number of active channels on socked %d: %d\n", + socket, *channels); return 0; } -static int get_dimm_config(struct mem_ctl_info *mci) +static int get_dimm_config(struct mem_ctl_info *mci, u8 socket) { struct i7core_pvt *pvt = mci->pvt_info; struct csrow_info *csr; @@ -409,7 +420,7 @@ static int get_dimm_config(struct mem_ctl_info *mci) enum mem_type mtype; /* Get data from the MC register, function 0 */ - pdev = pvt->pci_mcr[0]; + pdev = pvt->pci_mcr[socket][0]; if (!pdev) return -ENODEV; @@ -458,10 +469,11 @@ static int get_dimm_config(struct mem_ctl_info *mci) } /* Devices 4-6 function 0 */ - pci_read_config_dword(pvt->pci_ch[i][0], + pci_read_config_dword(pvt->pci_ch[socket][i][0], MC_CHANNEL_DIMM_INIT_PARAMS, &data); - pvt->channel[i].ranks = (data & QUAD_RANK_PRESENT) ? 4 : 2; + pvt->channel[socket][i].ranks = (data & QUAD_RANK_PRESENT) ? + 4 : 2; if (data & REGISTERED_DIMM) mtype = MEM_RDDR3; @@ -477,11 +489,11 @@ static int get_dimm_config(struct mem_ctl_info *mci) #endif /* Devices 4-6 function 1 */ - pci_read_config_dword(pvt->pci_ch[i][1], + pci_read_config_dword(pvt->pci_ch[socket][i][1], MC_DOD_CH_DIMM0, &dimm_dod[0]); - pci_read_config_dword(pvt->pci_ch[i][1], + pci_read_config_dword(pvt->pci_ch[socket][i][1], MC_DOD_CH_DIMM1, &dimm_dod[1]); - pci_read_config_dword(pvt->pci_ch[i][1], + pci_read_config_dword(pvt->pci_ch[socket][i][1], MC_DOD_CH_DIMM2, &dimm_dod[2]); debugf0("Ch%d phy rd%d, wr%d (0x%08x): " @@ -489,7 +501,7 @@ static int get_dimm_config(struct mem_ctl_info *mci) i, RDLCH(pvt->info.ch_map, i), WRLCH(pvt->info.ch_map, i), data, - pvt->channel[i].ranks, + pvt->channel[socket][i].ranks, (data & REGISTERED_DIMM) ? 'R' : 'U'); for (j = 0; j < 3; j++) { @@ -507,7 +519,7 @@ static int get_dimm_config(struct mem_ctl_info *mci) /* DDR3 has 8 I/O banks */ size = (rows * cols * banks * ranks) >> (20 - 3); - pvt->channel[i].dimms++; + pvt->channel[socket][i].dimms++; debugf0("\tdimm %d (0x%08x) %d Mb offset: %x, " "numbank: %d,\n\t\t" @@ -592,15 +604,42 @@ static int disable_inject(struct mem_ctl_info *mci) pvt->inject.enable = 0; - if (!pvt->pci_ch[pvt->inject.channel][0]) + if (!pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0]) return -ENODEV; - pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0], + pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], MC_CHANNEL_ERROR_MASK, 0); return 0; } +/* + * i7core inject inject.socket + * + * accept and store error injection inject.socket value + */ +static ssize_t i7core_inject_socket_store(struct mem_ctl_info *mci, + const char *data, size_t count) +{ + struct i7core_pvt *pvt = mci->pvt_info; + unsigned long value; + int rc; + + rc = strict_strtoul(data, 10, &value); + if ((rc < 0) || (value > pvt->sockets)) + return 0; + + pvt->inject.section = (u32) value; + return count; +} + +static ssize_t i7core_inject_socket_show(struct mem_ctl_info *mci, + char *data) +{ + struct i7core_pvt *pvt = mci->pvt_info; + return sprintf(data, "%d\n", pvt->inject.socket); +} + /* * i7core inject inject.section * @@ -838,7 +877,7 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, int rc; long enable; - if (!pvt->pci_ch[pvt->inject.channel][0]) + if (!pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0]) return 0; rc = strict_strtoul(data, 10, &enable); @@ -856,7 +895,7 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, if (pvt->inject.dimm < 0) mask |= 1L << 41; else { - if (pvt->channel[pvt->inject.channel].dimms > 2) + if (pvt->channel[pvt->inject.socket][pvt->inject.channel].dimms > 2) mask |= (pvt->inject.dimm & 0x3L) << 35; else mask |= (pvt->inject.dimm & 0x1L) << 36; @@ -866,7 +905,7 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, if (pvt->inject.rank < 0) mask |= 1L << 40; else { - if (pvt->channel[pvt->inject.channel].dimms > 2) + if (pvt->channel[pvt->inject.socket][pvt->inject.channel].dimms > 2) mask |= (pvt->inject.rank & 0x1L) << 34; else mask |= (pvt->inject.rank & 0x3L) << 34; @@ -891,38 +930,41 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, mask |= (pvt->inject.col & 0x3fffL); /* Unlock writes to registers */ - pci_write_config_dword(pvt->pci_noncore, MC_CFG_CONTROL, 0x2); + pci_write_config_dword(pvt->pci_noncore[pvt->inject.socket], + MC_CFG_CONTROL, 0x2); msleep(100); /* Zeroes error count registers */ - pci_write_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV1, 0); - pci_write_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV0, 0); - pvt->ce_count_available = 0; + pci_write_config_dword(pvt->pci_mcr[pvt->inject.socket][4], + MC_TEST_ERR_RCV1, 0); + pci_write_config_dword(pvt->pci_mcr[pvt->inject.socket][4], + MC_TEST_ERR_RCV0, 0); + pvt->ce_count_available[pvt->inject.socket] = 0; #if USE_QWORD - pci_write_config_qword(pvt->pci_ch[pvt->inject.channel][0], + pci_write_config_qword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], MC_CHANNEL_ADDR_MATCH, mask); #else - pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0], + pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], MC_CHANNEL_ADDR_MATCH, mask); - pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0], + pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], MC_CHANNEL_ADDR_MATCH + 4, mask >> 32L); #endif #if 1 #if USE_QWORD u64 rdmask; - pci_read_config_qword(pvt->pci_ch[pvt->inject.channel][0], + pci_read_config_qword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], MC_CHANNEL_ADDR_MATCH, &rdmask); debugf0("Inject addr match write 0x%016llx, read: 0x%016llx\n", mask, rdmask); #else u32 rdmask1, rdmask2; - pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0], + pci_read_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], MC_CHANNEL_ADDR_MATCH, &rdmask1); - pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0], + pci_read_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], MC_CHANNEL_ADDR_MATCH + 4, &rdmask2); debugf0("Inject addr match write 0x%016llx, read: 0x%08x 0x%08x\n", @@ -930,7 +972,7 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, #endif #endif - pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0], + pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], MC_CHANNEL_ERROR_MASK, pvt->inject.eccmask); /* @@ -944,7 +986,7 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, (pvt->inject.section & 0x3) << 1 | (pvt->inject.type & 0x6) << (3 - 1); - pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0], + pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], MC_CHANNEL_ERROR_MASK, injectmask); #if 0 @@ -965,7 +1007,7 @@ static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci, struct i7core_pvt *pvt = mci->pvt_info; u32 injectmask; - pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0], + pci_read_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], MC_CHANNEL_ERROR_MASK, &injectmask); debugf0("Inject error read: 0x%018x\n", injectmask); @@ -978,23 +1020,38 @@ static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci, static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data) { + unsigned i, count, total = 0; struct i7core_pvt *pvt = mci->pvt_info; - if (!pvt->ce_count_available) - return sprintf(data, "unavailable\n"); + for (i = 0; i < pvt->sockets; i++) { + if (!pvt->ce_count_available[i]) + count = sprintf(data, "socket 0 data unavailable\n"); + else + count = sprintf(data, "socket %d, dimm0: %lu\n" + "dimm1: %lu\ndimm2: %lu\n", + i, + pvt->ce_count[i][0], + pvt->ce_count[i][1], + pvt->ce_count[i][2]); + data += count; + total += count; + } - return sprintf(data, "dimm0: %lu\ndimm1: %lu\ndimm2: %lu\n", - pvt->ce_count[0], - pvt->ce_count[1], - pvt->ce_count[2]); + return total; } /* * Sysfs struct */ static struct mcidev_sysfs_attribute i7core_inj_attrs[] = { - { + .attr = { + .name = "inject_socket", + .mode = (S_IRUGO | S_IWUSR) + }, + .show = i7core_inject_socket_show, + .store = i7core_inject_socket_store, + }, { .attr = { .name = "inject_section", .mode = (S_IRUGO | S_IWUSR) @@ -1049,10 +1106,11 @@ static struct mcidev_sysfs_attribute i7core_inj_attrs[] = { */ static void i7core_put_devices(void) { - int i; + int i, j; - for (i = 0; i < N_DEVS; i++) - pci_dev_put(pci_devs[i].pdev); + for (i = 0; i < NUM_SOCKETS; i++) + for (j = 0; j < N_DEVS; j++) + pci_dev_put(pci_devs[j].pdev[i]); } /* @@ -1065,6 +1123,8 @@ static int i7core_get_devices(void) { int rc, i; struct pci_dev *pdev = NULL; + u8 bus = 0; + u8 socket = 0; for (i = 0; i < N_DEVS; i++) { pdev = pci_get_device(PCI_VENDOR_ID_INTEL, @@ -1078,14 +1138,32 @@ static int i7core_get_devices(void) pci_devs[i].dev_id, NULL); } - if (likely(pdev)) - pci_devs[i].pdev = pdev; - else { + if (likely(pdev)) { + bus = pdev->bus->number; + + if (bus == 0x3f) + socket = 0; + else + socket = 255 - bus; + + if (socket >= NUM_SOCKETS) { + i7core_printk(KERN_ERR, + "Found unexpected socket for " + "dev %02x:%02x.%d PCI ID %04x:%04x\n", + bus, pci_devs[i].dev, pci_devs[i].func, + PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id); + + rc = -ENODEV; + goto error; + } + + pci_devs[i].pdev[socket] = pdev; + } else { i7core_printk(KERN_ERR, - "Device not found: PCI ID %04x:%04x " - "(dev %d, func %d)\n", - PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id, - pci_devs[i].dev, pci_devs[i].func); + "Device not found: " + "dev %02x:%02x.%d PCI ID %04x:%04x\n", + bus, pci_devs[i].dev, pci_devs[i].func, + PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id); /* Dev 3 function 2 only exists on chips with RDIMMs */ if ((pci_devs[i].dev == 3) && (pci_devs[i].func == 2)) @@ -1121,9 +1199,10 @@ static int i7core_get_devices(void) } i7core_printk(KERN_INFO, - "Registered device %0x:%0x fn %d.%d\n", - PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id, - PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); + "Registered socket %d " + "dev %02x:%02x.%d PCI ID %04x:%04x\n", + socket, bus, pci_devs[i].dev, pci_devs[i].func, + PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id); } return 0; @@ -1137,30 +1216,33 @@ static int mci_bind_devs(struct mem_ctl_info *mci) { struct i7core_pvt *pvt = mci->pvt_info; struct pci_dev *pdev; - int i, func, slot; + int i, j, func, slot; - for (i = 0; i < N_DEVS; i++) { - pdev = pci_devs[i].pdev; - if (!pdev) - continue; + for (i = 0; i < pvt->sockets; i++) { + for (j = 0; j < N_DEVS; j++) { + pdev = pci_devs[j].pdev[i]; + if (!pdev) + continue; - func = PCI_FUNC(pdev->devfn); - slot = PCI_SLOT(pdev->devfn); - if (slot == 3) { - if (unlikely(func > MAX_MCR_FUNC)) - goto error; - pvt->pci_mcr[func] = pdev; - } else if (likely(slot >= 4 && slot < 4 + NUM_CHANS)) { - if (unlikely(func > MAX_CHAN_FUNC)) + func = PCI_FUNC(pdev->devfn); + slot = PCI_SLOT(pdev->devfn); + if (slot == 3) { + if (unlikely(func > MAX_MCR_FUNC)) + goto error; + pvt->pci_mcr[i][func] = pdev; + } else if (likely(slot >= 4 && slot < 4 + NUM_CHANS)) { + if (unlikely(func > MAX_CHAN_FUNC)) + goto error; + pvt->pci_ch[i][slot - 4][func] = pdev; + } else if (!slot && !func) + pvt->pci_noncore[i] = pdev; + else goto error; - pvt->pci_ch[slot - 4][func] = pdev; - } else if (!slot && !func) - pvt->pci_noncore = pdev; - else - goto error; - debugf0("Associated fn %d.%d, dev = %p\n", - PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), pdev); + debugf0("Associated fn %d.%d, dev = %p, socket %d\n", + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), + pdev, i); + } } return 0; @@ -1182,20 +1264,20 @@ error: * also available at: * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf */ -static void check_mc_test_err(struct mem_ctl_info *mci) +static void check_mc_test_err(struct mem_ctl_info *mci, u8 socket) { struct i7core_pvt *pvt = mci->pvt_info; u32 rcv1, rcv0; int new0, new1, new2; - if (!pvt->pci_mcr[4]) { + if (!pvt->pci_mcr[socket][4]) { debugf0("%s MCR registers not found\n",__func__); return; } /* Corrected error reads */ - pci_read_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV1, &rcv1); - pci_read_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV0, &rcv0); + pci_read_config_dword(pvt->pci_mcr[socket][4], MC_TEST_ERR_RCV1, &rcv1); + pci_read_config_dword(pvt->pci_mcr[socket][4], MC_TEST_ERR_RCV0, &rcv0); /* Store the new values */ new2 = DIMM2_COR_ERR(rcv1); @@ -1209,32 +1291,32 @@ static void check_mc_test_err(struct mem_ctl_info *mci) #endif /* Updates CE counters if it is not the first time here */ - if (pvt->ce_count_available) { + if (pvt->ce_count_available[socket]) { /* Updates CE counters */ int add0, add1, add2; - add2 = new2 - pvt->last_ce_count[2]; - add1 = new1 - pvt->last_ce_count[1]; - add0 = new0 - pvt->last_ce_count[0]; + add2 = new2 - pvt->last_ce_count[socket][2]; + add1 = new1 - pvt->last_ce_count[socket][1]; + add0 = new0 - pvt->last_ce_count[socket][0]; if (add2 < 0) add2 += 0x7fff; - pvt->ce_count[2] += add2; + pvt->ce_count[socket][2] += add2; if (add1 < 0) add1 += 0x7fff; - pvt->ce_count[1] += add1; + pvt->ce_count[socket][1] += add1; if (add0 < 0) add0 += 0x7fff; - pvt->ce_count[0] += add0; + pvt->ce_count[socket][0] += add0; } else - pvt->ce_count_available = 1; + pvt->ce_count_available[socket] = 1; /* Store the new values */ - pvt->last_ce_count[2] = new2; - pvt->last_ce_count[1] = new1; - pvt->last_ce_count[0] = new0; + pvt->last_ce_count[socket][2] = new2; + pvt->last_ce_count[socket][1] = new1; + pvt->last_ce_count[socket][0] = new0; } static void i7core_mce_output_error(struct mem_ctl_info *mci, @@ -1299,7 +1381,8 @@ static void i7core_check_error(struct mem_ctl_info *mci) kfree(m); /* check memory count errors */ - check_mc_test_err(mci); + for (i = 0; i < pvt->sockets; i++) + check_mc_test_err(mci, i); } /* @@ -1339,10 +1422,11 @@ static int __devinit i7core_probe(struct pci_dev *pdev, { struct mem_ctl_info *mci; struct i7core_pvt *pvt; - int num_channels; - int num_csrows; + int num_channels = 0; + int num_csrows = 0; int dev_idx = id->driver_data; - int rc; + int rc, i; + u8 sockets; if (unlikely(dev_idx >= ARRAY_SIZE(i7core_devs))) return -EINVAL; @@ -1352,10 +1436,25 @@ static int __devinit i7core_probe(struct pci_dev *pdev, if (unlikely(rc < 0)) return rc; - /* Check the number of active and not disabled channels */ - rc = i7core_get_active_channels(&num_channels, &num_csrows); - if (unlikely(rc < 0)) - goto fail0; + sockets = 1; + for (i = NUM_SOCKETS - 1; i > 0; i--) + if (pci_devs[0].pdev[i]) { + sockets = i + 1; + break; + } + + for (i = 0; i < sockets; i++) { + int channels; + int csrows; + + /* Check the number of active and not disabled channels */ + rc = i7core_get_active_channels(i, &channels, &csrows); + if (unlikely(rc < 0)) + goto fail0; + + num_channels += channels; + num_csrows += csrows; + } /* allocate a new MC control structure */ mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0); @@ -1367,11 +1466,11 @@ static int __devinit i7core_probe(struct pci_dev *pdev, debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); mci->dev = &pdev->dev; /* record ptr to the generic device */ - pvt = mci->pvt_info; memset(pvt, 0, sizeof(*pvt)); - + pvt->sockets = sockets; mci->mc_idx = 0; + /* * FIXME: how to handle RDDR3 at MCI level? It is possible to have * Mixed RDDR3/UDDR3 with Nehalem, provided that they are on different @@ -1395,7 +1494,8 @@ static int __devinit i7core_probe(struct pci_dev *pdev, goto fail1; /* Get dimm basic config */ - get_dimm_config(mci); + for (i = 0; i < sockets; i++) + get_dimm_config(mci, i); /* add this new MC control structure to EDAC's list of MCs */ if (unlikely(edac_mc_add_mc(mci))) { -- cgit v1.2.3 From ba6c5c62eeb877da638e43f1282f778432142eec Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 15 Jul 2009 09:02:32 -0300 Subject: i7core_edac: maps all sockets as if ther are one MC controller Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 69eacc1b50d7..a93ebdf9c121 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -409,12 +409,12 @@ static int i7core_get_active_channels(u8 socket, unsigned *channels, return 0; } -static int get_dimm_config(struct mem_ctl_info *mci, u8 socket) +static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket) { struct i7core_pvt *pvt = mci->pvt_info; struct csrow_info *csr; struct pci_dev *pdev; - int i, j, csrow = 0; + int i, j; unsigned long last_page = 0; enum edac_type mode; enum mem_type mtype; @@ -534,7 +534,7 @@ static int get_dimm_config(struct mem_ctl_info *mci, u8 socket) npages = size << (20 - PAGE_SHIFT); #endif - csr = &mci->csrows[csrow]; + csr = &mci->csrows[*csrow]; csr->first_page = last_page + 1; last_page += npages; csr->last_page = last_page; @@ -542,7 +542,7 @@ static int get_dimm_config(struct mem_ctl_info *mci, u8 socket) csr->page_mask = 0; csr->grain = 8; - csr->csrow_idx = csrow; + csr->csrow_idx = *csrow; csr->nr_channels = 1; csr->channels[0].chan_idx = i; @@ -565,7 +565,7 @@ static int get_dimm_config(struct mem_ctl_info *mci, u8 socket) csr->edac_mode = mode; csr->mtype = mtype; - csrow++; + (*csrow)++; } pci_read_config_dword(pdev, MC_SAG_CH_0, &value[0]); @@ -1424,6 +1424,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, struct i7core_pvt *pvt; int num_channels = 0; int num_csrows = 0; + int csrow = 0; int dev_idx = id->driver_data; int rc, i; u8 sockets; @@ -1495,7 +1496,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, /* Get dimm basic config */ for (i = 0; i < sockets; i++) - get_dimm_config(mci, i); + get_dimm_config(mci, &csrow, i); /* add this new MC control structure to EDAC's list of MCs */ if (unlikely(edac_mc_add_mc(mci))) { -- cgit v1.2.3 From 8a2f118e3a023a4e8cbe56a6e51f7b78fa8c76a0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 15 Jul 2009 19:01:08 -0300 Subject: i7core_edac: decode mcelog error and send it via edac interface Enriches mcelog error by using the encoded information at MCE status and misc registers (IA32_MCx_STATUS, IA32_MCx_MISC). Some fixes are still needed here, in order to properly fill the EDAC fields. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 92 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 70 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index a93ebdf9c121..4397a3171c62 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1319,33 +1319,75 @@ static void check_mc_test_err(struct mem_ctl_info *mci, u8 socket) pvt->last_ce_count[socket][0] = new0; } +/* + * According with tables E-11 and E-12 of chapter E.3.3 of Intel 64 and IA-32 + * Architectures Software Developer’s Manual Volume 3B. + * The MCA registers are the following ones: + * struct mce field MCA Register + * m->status MSR_IA32_MC0_STATUS + * m->addr MSR_IA32_MC0_ADDR + * m->misc MSR_IA32_MC0_MISC + * m->mcgstatus MSR_IA32_MCG_STATUS + * In the case of Nehalem, the error information is masked at .status and .misc + * fields + */ static void i7core_mce_output_error(struct mem_ctl_info *mci, struct mce *m) { - debugf0("CPU %d: Machine Check Exception: %16Lx" - "Bank %d: %016Lx\n", - m->cpu, m->mcgstatus, m->bank, m->status); - if (m->ip) { - debugf0("RIP%s %02x:<%016Lx>\n", - !(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "", - m->cs, m->ip); + char *type="NON-FATAL"; + char *err, *msg; + unsigned long error = m->status & 0x1ff0000l; + u32 core_err_cnt = (m->status >> 38) && 0x7fff; + u32 dimm = (m->misc >> 16) & 0x3; + u32 channel = (m->misc >> 18) & 0x3; + u32 syndrome = m->misc >> 32; + u32 errnum = find_first_bit(&error, 32); + + switch (errnum) { + case 16: + err = "read ECC error"; + break; + case 17: + err = "RAS ECC error"; + break; + case 18: + err = "write parity error"; + break; + case 19: + err = "redundacy loss"; + break; + case 20: + err = "reserved"; + break; + case 21: + err = "memory range error"; + break; + case 22: + err = "RTID out of range"; + break; + case 23: + err = "address parity error"; + break; + case 24: + err = "byte enable parity error"; + break; + default: + err = "unknown"; } - printk(KERN_EMERG "TSC %llx ", m->tsc); - if (m->addr) - printk("ADDR %llx ", m->addr); - if (m->misc) - printk("MISC %llx ", m->misc); -#if 0 - snprintf(msg, sizeof(msg), - "%s (Branch=%d DRAM-Bank=%d Buffer ID = %d RDWR=%s " - "RAS=%d CAS=%d %s Err=0x%lx (%s))", - type, branch >> 1, bank, buf_id, rdwr_str(rdwr), ras, cas, - type, allErrors, error_name[errnum]); + msg = kasprintf(GFP_ATOMIC, + "%s (addr = 0x%08llx Bank=0x%08x, Dimm=%d, Channel=%d, " + "syndrome=0x%08x total error count=%d Err=%d (%s))\n", + type, (long long) m->addr, m->bank, dimm, channel, + syndrome, core_err_cnt,errnum, err); + + debugf0("%s", msg); /* Call the helper to output message */ - edac_mc_handle_fbd_ue(mci, rank, channel, channel + 1, msg); -#endif + edac_mc_handle_fbd_ue(mci, 0 /* FIXME: should be rank here */, + 0, 0 /* FIXME: should be channel here */, msg); + + kfree(msg); } /* @@ -1398,6 +1440,13 @@ static int i7core_mce_check_error(void *priv, struct mce *mce) debugf0(__FILE__ ": %s()\n", __func__); + /* + * Just let mcelog handle it if the error is + * outside the memory controller + */ + if (((mce->status & 0xffff) >> 7) != 1) + return 0; + spin_lock_irqsave(&pvt->mce_lock, flags); if (pvt->mce_count < MCE_LOG_LEN) { memcpy(&pvt->mce_entry[pvt->mce_count], mce, sizeof(*mce)); @@ -1406,8 +1455,7 @@ static int i7core_mce_check_error(void *priv, struct mce *mce) spin_unlock_irqrestore(&pvt->mce_lock, flags); /* Advice mcelog that the error were handled */ -// return 1; - return 0; // Let's duplicate the log + return 1; } /* -- cgit v1.2.3 From f237fcf2b7560be33386255042dc11167ca486d5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 15 Jul 2009 19:53:24 -0300 Subject: i7core_edac: some fixes at memory error parser m->bank is not related to the memory bank but, instead, to the MCA Error register bank. Fix it accordingly. While here, improves the comments for Nehalem bank. A later fix is needed, in order to get bank/rank information from MCA error log. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 4397a3171c62..67822976992e 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1322,12 +1322,13 @@ static void check_mc_test_err(struct mem_ctl_info *mci, u8 socket) /* * According with tables E-11 and E-12 of chapter E.3.3 of Intel 64 and IA-32 * Architectures Software Developer’s Manual Volume 3B. - * The MCA registers are the following ones: + * Nehalem are defined as family 0x06, model 0x1a + * + * The MCA registers used here are the following ones: * struct mce field MCA Register - * m->status MSR_IA32_MC0_STATUS - * m->addr MSR_IA32_MC0_ADDR - * m->misc MSR_IA32_MC0_MISC - * m->mcgstatus MSR_IA32_MCG_STATUS + * m->status MSR_IA32_MC8_STATUS + * m->addr MSR_IA32_MC8_ADDR + * m->misc MSR_IA32_MC8_MISC * In the case of Nehalem, the error information is masked at .status and .misc * fields */ @@ -1375,10 +1376,11 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci, err = "unknown"; } + /* FIXME: should convert addr into bank and rank information */ msg = kasprintf(GFP_ATOMIC, - "%s (addr = 0x%08llx Bank=0x%08x, Dimm=%d, Channel=%d, " - "syndrome=0x%08x total error count=%d Err=%d (%s))\n", - type, (long long) m->addr, m->bank, dimm, channel, + "%s (addr = 0x%08llx Dimm=%d, Channel=%d, " + "syndrome=0x%08x, count=%d Err=%d (%s))\n", + type, (long long) m->addr, dimm, channel, syndrome, core_err_cnt,errnum, err); debugf0("%s", msg); @@ -1447,6 +1449,10 @@ static int i7core_mce_check_error(void *priv, struct mce *mce) if (((mce->status & 0xffff) >> 7) != 1) return 0; + /* Bank 8 registers are the only ones that we know how to handle */ + if (mce->bank != 8) + return 0; + spin_lock_irqsave(&pvt->mce_lock, flags); if (pvt->mce_count < MCE_LOG_LEN) { memcpy(&pvt->mce_entry[pvt->mce_count], mce, sizeof(*mce)); -- cgit v1.2.3 From 310cbb7284fab9fc9cbb6bb893e51c414e15bba3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 17 Jul 2009 00:09:10 -0300 Subject: i7core: fix probing on Xeon55xx Xeon55xx fails to probe with this error message: EDAC DEBUG: in drivers/edac/i7core_edac.c, line at 1660: MC: drivers/edac/i7core_edac.c: i7core_init() EDAC i7core: Device not found: dev 00:00.0 PCI ID 8086:2c41 i7core_edac: probe of 0000:00:14.0 failed with error -22 This is due to the fact that, on Xeon35xx (and i7core), device 00.0 has PCI ID 8086:2c40. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 23 ++++++++++++++++++++--- include/linux/pci_ids.h | 1 + 2 files changed, 21 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 67822976992e..e2f6dfdca841 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -227,9 +227,6 @@ struct i7core_dev_info { .dev_id = (device_id) struct pci_id_descr pci_devs[] = { - /* Generic Non-core registers */ - { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_I7_NOCORE) }, - /* Memory controller */ { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) }, { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) }, @@ -253,6 +250,16 @@ struct pci_id_descr pci_devs[] = { { PCI_DESCR(6, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH2_ADDR) }, { PCI_DESCR(6, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH2_RANK) }, { PCI_DESCR(6, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC) }, + + /* Generic Non-core registers */ + /* + * This is the PCI device on i7core and on Xeon 35xx (8086:2c41) + * On Xeon 55xx, however, it has a different id (8086:2c40). So, + * the probing code needs to test for the other address in case of + * failure of this one + */ + { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_I7_NOCORE) }, + }; #define N_DEVS ARRAY_SIZE(pci_devs) @@ -1138,6 +1145,16 @@ static int i7core_get_devices(void) pci_devs[i].dev_id, NULL); } + /* + * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core regs + * is at addr 8086:2c40, instead of 8086:2c41. So, we need + * to probe for the alternate address in case of failure + */ + if (pci_devs[i].dev_id == PCI_DEVICE_ID_INTEL_I7_NOCORE + && !pdev) + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_I7_NOCORE_ALT, NULL); + if (likely(pdev)) { bus = pdev->bus->number; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 12c3da6ef14d..bf6db4814c27 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2549,6 +2549,7 @@ #define PCI_DEVICE_ID_INTEL_I7_MC_CH2_RANK 0x2c32 #define PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC 0x2c33 #define PCI_DEVICE_ID_INTEL_I7_NOCORE 0x2c41 +#define PCI_DEVICE_ID_INTEL_I7_NOCORE_ALT 0x2c40 #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340 #define PCI_DEVICE_ID_INTEL_IOAT_TBG4 0x3429 #define PCI_DEVICE_ID_INTEL_IOAT_TBG5 0x342a -- cgit v1.2.3 From c5d34528696acadc40d2ba7601dbf35d65b74ad5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 17 Jul 2009 10:28:15 -0300 Subject: i7core: check if the memory error is fatal or non-fatal Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index e2f6dfdca841..08149d5addff 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1352,7 +1352,7 @@ static void check_mc_test_err(struct mem_ctl_info *mci, u8 socket) static void i7core_mce_output_error(struct mem_ctl_info *mci, struct mce *m) { - char *type="NON-FATAL"; + char *type; char *err, *msg; unsigned long error = m->status & 0x1ff0000l; u32 core_err_cnt = (m->status >> 38) && 0x7fff; @@ -1361,6 +1361,11 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci, u32 syndrome = m->misc >> 32; u32 errnum = find_first_bit(&error, 32); + if (m->mcgstatus & 1) + type = "FATAL"; + else + type = "NON_FATAL"; + switch (errnum) { case 16: err = "read ECC error"; @@ -1454,7 +1459,8 @@ static void i7core_check_error(struct mem_ctl_info *mci) */ static int i7core_mce_check_error(void *priv, struct mce *mce) { - struct i7core_pvt *pvt = priv; + struct mem_ctl_info *mci = priv; + struct i7core_pvt *pvt = mci->pvt_info; unsigned long flags; debugf0(__FILE__ ": %s()\n", __func__); @@ -1477,6 +1483,10 @@ static int i7core_mce_check_error(void *priv, struct mce *mce) } spin_unlock_irqrestore(&pvt->mce_lock, flags); + /* Handle fatal errors immediately */ + if (mce->mcgstatus & 1) + i7core_check_error(mci); + /* Advice mcelog that the error were handled */ return 1; } @@ -1601,7 +1611,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, pvt->inject.col = -1; /* Registers on edac_mce in order to receive memory errors */ - pvt->edac_mce.priv = pvt; + pvt->edac_mce.priv = mci; pvt->edac_mce.check_error = i7core_mce_check_error; spin_lock_init(&pvt->mce_lock); -- cgit v1.2.3 From a639539fa28531924c6b5e0f3963cc63d060947d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 17 Jul 2009 10:54:23 -0300 Subject: i7core: enrich error information based on memory transaction type Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 08149d5addff..9f39d3d5502e 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1352,9 +1352,9 @@ static void check_mc_test_err(struct mem_ctl_info *mci, u8 socket) static void i7core_mce_output_error(struct mem_ctl_info *mci, struct mce *m) { - char *type; - char *err, *msg; + char *type, *optype, *err, *msg; unsigned long error = m->status & 0x1ff0000l; + u32 optypenum = (m->status >> 4) & 0x07; u32 core_err_cnt = (m->status >> 38) && 0x7fff; u32 dimm = (m->misc >> 16) & 0x3; u32 channel = (m->misc >> 18) & 0x3; @@ -1366,6 +1366,27 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci, else type = "NON_FATAL"; + switch (optypenum) { + case 0: + optype = "generic undef request"; + break; + case 1: + optype = "read error"; + break; + case 2: + optype = "write error"; + break; + case 3: + optype = "addr/cmd error"; + break; + case 4: + optype = "scrubbing error"; + break; + default: + optype = "reserved"; + break; + } + switch (errnum) { case 16: err = "read ECC error"; @@ -1400,10 +1421,11 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci, /* FIXME: should convert addr into bank and rank information */ msg = kasprintf(GFP_ATOMIC, - "%s (addr = 0x%08llx Dimm=%d, Channel=%d, " - "syndrome=0x%08x, count=%d Err=%d (%s))\n", + "%s (addr = 0x%08llx, Dimm=%d, Channel=%d, " + "syndrome=0x%08x, count=%d, Err=%08llx:%08llx (%s: %s))\n", type, (long long) m->addr, dimm, channel, - syndrome, core_err_cnt,errnum, err); + syndrome, core_err_cnt, (long long)m->status, + (long long)m->misc, optype, err); debugf0("%s", msg); -- cgit v1.2.3 From c77720b9544d8825ff5b9546d0ee038cfa4d4eb2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 18 Jul 2009 10:43:08 -0300 Subject: i7core: fix get_devices routine for Xeon55xx i7core_get_devices() were preparet to get just the first found device of each type. Due to that, on Xeon 55xx, only socket 1 were retrived. Rework i7core_get_devices() to clean it and to properly support Xeon 55xx. While here, fix a small typo. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 186 ++++++++++++++++++++++++++------------------- 1 file changed, 108 insertions(+), 78 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 9f39d3d5502e..79636b58ec52 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -410,7 +410,7 @@ static int i7core_get_active_channels(u8 socket, unsigned *channels, } } - debugf0("Number of active channels on socked %d: %d\n", + debugf0("Number of active channels on socket %d: %d\n", socket, *channels); return 0; @@ -1126,107 +1126,137 @@ static void i7core_put_devices(void) * * Need to 'get' device 16 func 1 and func 2 */ -static int i7core_get_devices(void) +int i7core_get_onedevice(struct pci_dev **prev, int devno) { - int rc, i; struct pci_dev *pdev = NULL; u8 bus = 0; u8 socket = 0; - for (i = 0; i < N_DEVS; i++) { + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, + pci_devs[devno].dev_id, *prev); + + /* + * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core pci buses + * aren't announced by acpi. So, we need to use a legacy scan probing + * to detect them + */ + if (unlikely(!pdev && !devno && !prev)) { + pcibios_scan_specific_bus(254); + pcibios_scan_specific_bus(255); + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, - pci_devs[i].dev_id, NULL); + pci_devs[devno].dev_id, *prev); + } - if (!pdev && !i) { - pcibios_scan_specific_bus(254); - pcibios_scan_specific_bus(255); + /* + * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core regs + * is at addr 8086:2c40, instead of 8086:2c41. So, we need + * to probe for the alternate address in case of failure + */ + if (pci_devs[devno].dev_id == PCI_DEVICE_ID_INTEL_I7_NOCORE && !pdev) + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_I7_NOCORE_ALT, *prev); - pdev = pci_get_device(PCI_VENDOR_ID_INTEL, - pci_devs[i].dev_id, NULL); + if (!pdev) { + if (*prev) { + *prev = pdev; + return 0; } /* - * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core regs - * is at addr 8086:2c40, instead of 8086:2c41. So, we need - * to probe for the alternate address in case of failure + * Dev 3 function 2 only exists on chips with RDIMMs + * so, it is ok to not found it */ - if (pci_devs[i].dev_id == PCI_DEVICE_ID_INTEL_I7_NOCORE - && !pdev) - pdev = pci_get_device(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_I7_NOCORE_ALT, NULL); + if ((pci_devs[devno].dev == 3) && (pci_devs[devno].func == 2)) { + *prev = pdev; + return 0; + } - if (likely(pdev)) { - bus = pdev->bus->number; + i7core_printk(KERN_ERR, + "Device not found: dev %02x.%d PCI ID %04x:%04x\n", + pci_devs[devno].dev, pci_devs[devno].func, + PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id); - if (bus == 0x3f) - socket = 0; - else - socket = 255 - bus; + /* End of list, leave */ + return -ENODEV; + } + bus = pdev->bus->number; - if (socket >= NUM_SOCKETS) { - i7core_printk(KERN_ERR, - "Found unexpected socket for " - "dev %02x:%02x.%d PCI ID %04x:%04x\n", - bus, pci_devs[i].dev, pci_devs[i].func, - PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id); + if (bus == 0x3f) + socket = 0; + else + socket = 255 - bus; + + if (socket >= NUM_SOCKETS) { + i7core_printk(KERN_ERR, + "Unexpected socket for " + "dev %02x:%02x.%d PCI ID %04x:%04x\n", + bus, pci_devs[devno].dev, pci_devs[devno].func, + PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id); + pci_dev_put(pdev); + return -ENODEV; + } - rc = -ENODEV; - goto error; - } + if (pci_devs[devno].pdev[socket]) { + i7core_printk(KERN_ERR, + "Duplicated device for " + "dev %02x:%02x.%d PCI ID %04x:%04x\n", + bus, pci_devs[devno].dev, pci_devs[devno].func, + PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id); + pci_dev_put(pdev); + return -ENODEV; + } - pci_devs[i].pdev[socket] = pdev; - } else { - i7core_printk(KERN_ERR, - "Device not found: " - "dev %02x:%02x.%d PCI ID %04x:%04x\n", - bus, pci_devs[i].dev, pci_devs[i].func, - PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id); + pci_devs[devno].pdev[socket] = pdev; + + /* Sanity check */ + if (unlikely(PCI_SLOT(pdev->devfn) != pci_devs[devno].dev || + PCI_FUNC(pdev->devfn) != pci_devs[devno].func)) { + i7core_printk(KERN_ERR, + "Device PCI ID %04x:%04x " + "has dev %02x:%02x.%d instead of dev %02x:%02x.%d\n", + PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id, + bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), + bus, pci_devs[devno].dev, pci_devs[devno].func); + return -ENODEV; + } - /* Dev 3 function 2 only exists on chips with RDIMMs */ - if ((pci_devs[i].dev == 3) && (pci_devs[i].func == 2)) - continue; + /* Be sure that the device is enabled */ + if (unlikely(pci_enable_device(pdev) < 0)) { + i7core_printk(KERN_ERR, + "Couldn't enable " + "dev %02x:%02x.%d PCI ID %04x:%04x\n", + bus, pci_devs[devno].dev, pci_devs[devno].func, + PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id); + return -ENODEV; + } - /* End of list, leave */ - rc = -ENODEV; - goto error; - } + i7core_printk(KERN_INFO, + "Registered socket %d " + "dev %02x:%02x.%d PCI ID %04x:%04x\n", + socket, bus, pci_devs[devno].dev, pci_devs[devno].func, + PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id); - /* Sanity check */ - if (unlikely(PCI_SLOT(pdev->devfn) != pci_devs[i].dev || - PCI_FUNC(pdev->devfn) != pci_devs[i].func)) { - i7core_printk(KERN_ERR, - "Device PCI ID %04x:%04x " - "has fn %d.%d instead of fn %d.%d\n", - PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id, - PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), - pci_devs[i].dev, pci_devs[i].func); - rc = -EINVAL; - goto error; - } + *prev = pdev; - /* Be sure that the device is enabled */ - rc = pci_enable_device(pdev); - if (unlikely(rc < 0)) { - i7core_printk(KERN_ERR, - "Couldn't enable PCI ID %04x:%04x " - "fn %d.%d\n", - PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id, - PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); - goto error; - } + return 0; +} - i7core_printk(KERN_INFO, - "Registered socket %d " - "dev %02x:%02x.%d PCI ID %04x:%04x\n", - socket, bus, pci_devs[i].dev, pci_devs[i].func, - PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id); - } +static int i7core_get_devices(void) +{ + int i; + struct pci_dev *pdev = NULL; + for (i = 0; i < N_DEVS; i++) { + pdev = NULL; + do { + if (i7core_get_onedevice(&pdev, i) < 0) { + i7core_put_devices(); + return -ENODEV; + } + } while (pdev); + } return 0; - -error: - i7core_put_devices(); - return -EINVAL; } static int mci_bind_devs(struct mem_ctl_info *mci) -- cgit v1.2.3 From ec6df24c15822e671801eeeb53758e14f3b28381 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 18 Jul 2009 10:44:30 -0300 Subject: i7core: better document i7core_get_active_channels() Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 79636b58ec52..bf0374062e3d 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -333,7 +333,6 @@ static inline int numcol(u32 col) return cols[col & 0x3]; } - /**************************************************************************** Memory check routines ****************************************************************************/ @@ -355,6 +354,23 @@ static struct pci_dev *get_pdev_slot_func(u8 socket, unsigned slot, return NULL; } +/** + * i7core_get_active_channels() - gets the number of channels and csrows + * @socket: Quick Path Interconnect socket + * @channels: Number of channels that will be returned + * @csrows: Number of csrows found + * + * Since EDAC core needs to know in advance the number of available channels + * and csrows, in order to allocate memory for csrows/channels, it is needed + * to run two similar steps. At the first step, implemented on this function, + * it checks the number of csrows/channels present at one socket. + * this is used in order to properly allocate the size of mci components. + * + * It should be noticed that none of the current available datasheets explain + * or even mention how csrows are seen by the memory controller. So, we need + * to add a fake description for csrows. + * So, this driver is attributing one DIMM memory for one csrow. + */ static int i7core_get_active_channels(u8 socket, unsigned *channels, unsigned *csrows) { -- cgit v1.2.3 From 3a7dde7fcd0dd50df33e0e7070d4947551d767fc Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 18 Jul 2009 12:20:04 -0300 Subject: i7core: add socket info at the debug msg Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index bf0374062e3d..5695413c2879 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1467,9 +1467,9 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci, /* FIXME: should convert addr into bank and rank information */ msg = kasprintf(GFP_ATOMIC, - "%s (addr = 0x%08llx, Dimm=%d, Channel=%d, " + "%s (addr = 0x%08llx, socket=%d, Dimm=%d, Channel=%d, " "syndrome=0x%08x, count=%d, Err=%08llx:%08llx (%s: %s))\n", - type, (long long) m->addr, dimm, channel, + type, (long long) m->addr, m->cpu, dimm, channel, syndrome, core_err_cnt, (long long)m->status, (long long)m->misc, optype, err); -- cgit v1.2.3 From 086271a0374bf0b9ce033aac9fb60530c421ad65 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 18 Jul 2009 12:22:28 -0300 Subject: i7core: remove some uneeded noisy debug messages Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 5695413c2879..fd00e0299ca1 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1494,8 +1494,6 @@ static void i7core_check_error(struct mem_ctl_info *mci) struct mce *m = NULL; unsigned long flags; - debugf0(__FILE__ ": %s()\n", __func__); - /* Copy all mce errors into a temporary buffer */ spin_lock_irqsave(&pvt->mce_lock, flags); if (pvt->mce_count) { @@ -1531,8 +1529,6 @@ static int i7core_mce_check_error(void *priv, struct mce *mce) struct i7core_pvt *pvt = mci->pvt_info; unsigned long flags; - debugf0(__FILE__ ": %s()\n", __func__); - /* * Just let mcelog handle it if the error is * outside the memory controller -- cgit v1.2.3 From 17cb7b0cf78c14913c5410eff2ce03e1d9c8d958 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 20 Jul 2009 18:48:18 -0300 Subject: i7core_edac: Some cleanups at displayed info Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index fd00e0299ca1..86af14840b88 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -453,8 +453,8 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket) pci_read_config_dword(pdev, MC_MAX_DOD, &pvt->info.max_dod); pci_read_config_dword(pdev, MC_CHANNEL_MAPPER, &pvt->info.ch_map); - debugf0("MC control=0x%08x status=0x%08x dod=0x%08x map=0x%08x\n", - pvt->info.mc_control, pvt->info.mc_status, + debugf0("QPI %d control=0x%08x status=0x%08x dod=0x%08x map=0x%08x\n", + socket, pvt->info.mc_control, pvt->info.mc_status, pvt->info.max_dod, pvt->info.ch_map); if (ECC_ENABLED(pvt)) { @@ -469,16 +469,14 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket) } /* FIXME: need to handle the error codes */ - debugf0("DOD Max limits: DIMMS: %d, %d-ranked, %d-banked\n", + debugf0("DOD Max limits: DIMMS: %d, %d-ranked, %d-banked " + "x%x x 0x%x\n", numdimms(pvt->info.max_dod), numrank(pvt->info.max_dod >> 2), numbank(pvt->info.max_dod >> 4)); - debugf0("DOD Max rows x colums = 0x%x x 0x%x\n", numrow(pvt->info.max_dod >> 6), numcol(pvt->info.max_dod >> 9)); - debugf0("Memory channel configuration:\n"); - for (i = 0; i < NUM_CHANS; i++) { u32 data, dimm_dod[3], value[8]; @@ -544,10 +542,9 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket) pvt->channel[socket][i].dimms++; - debugf0("\tdimm %d (0x%08x) %d Mb offset: %x, " - "numbank: %d,\n\t\t" - "numrank: %d, numrow: %#x, numcol: %#x\n", - j, dimm_dod[j], size, + debugf0("\tdimm %d %d Mb offset: %x, " + "bank: %d, rank: %d, row: %#x, col: %#x\n", + j, size, RANKOFFSET(dimm_dod[j]), banks, ranks, rows, cols); @@ -599,9 +596,9 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket) pci_read_config_dword(pdev, MC_SAG_CH_5, &value[5]); pci_read_config_dword(pdev, MC_SAG_CH_6, &value[6]); pci_read_config_dword(pdev, MC_SAG_CH_7, &value[7]); - debugf0("\t[%i] DIVBY3\tREMOVED\tOFFSET\n", i); + debugf1("\t[%i] DIVBY3\tREMOVED\tOFFSET\n", i); for (j = 0; j < 8; j++) - debugf0("\t\t%#x\t%#x\t%#x\n", + debugf1("\t\t%#x\t%#x\t%#x\n", (value[j] >> 27) & 0x1, (value[j] >> 24) & 0x7, (value[j] && ((1 << 24) - 1))); -- cgit v1.2.3 From 276b824c3095b09e8cb76f5709f56e9c6818ae85 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 22 Jul 2009 21:45:50 -0300 Subject: i7core_edac: some fixes at error injection code Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 104 ++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 86af14840b88..72859e87aeb2 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -32,9 +32,6 @@ #include "edac_core.h" -/* To use the new pci_[read/write]_config_qword instead of two dword */ -#define USE_QWORD 0 - /* * Alter this version for the module when modifications are made */ @@ -473,7 +470,7 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket) "x%x x 0x%x\n", numdimms(pvt->info.max_dod), numrank(pvt->info.max_dod >> 2), - numbank(pvt->info.max_dod >> 4)); + numbank(pvt->info.max_dod >> 4), numrow(pvt->info.max_dod >> 6), numcol(pvt->info.max_dod >> 9)); @@ -646,7 +643,7 @@ static ssize_t i7core_inject_socket_store(struct mem_ctl_info *mci, int rc; rc = strict_strtoul(data, 10, &value); - if ((rc < 0) || (value > pvt->sockets)) + if ((rc < 0) || (value >= pvt->sockets)) return 0; pvt->inject.section = (u32) value; @@ -803,7 +800,7 @@ static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci, else return cmd - data; } else if (!strcasecmp(cmd, "dimm")) { - if (value < 4) + if (value < 3) pvt->inject.dimm = value; else return cmd - data; @@ -813,7 +810,7 @@ static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci, else return cmd - data; } else if (!strcasecmp(cmd, "bank")) { - if (value < 4) + if (value < 32) pvt->inject.bank = value; else return cmd - data; @@ -870,6 +867,28 @@ static ssize_t i7core_inject_addrmatch_show(struct mem_ctl_info *mci, channel, dimm, bank, rank, page, col); } +static int write_and_test(struct pci_dev *dev, int where, u32 val) +{ + u32 read; + int count; + + for (count = 0; count < 10; count++) { + if (count) + msleep (100); + pci_write_config_dword(dev, where, val); + pci_read_config_dword(dev, where, &read); + + if (read == val) + return 0; + } + + debugf0("Error Injection Register 0x%02x: Tried to write 0x%08x, " + "but read: 0x%08x\n", where, val, read); + + return -EINVAL; +} + + /* * This routine prepares the Memory Controller for error injection. * The error will be injected when some process tries to write to the @@ -949,70 +968,49 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, else mask |= (pvt->inject.col & 0x3fffL); - /* Unlock writes to registers */ + /* + * bit 0: REPEAT_EN + * bits 1-2: MASK_HALF_CACHELINE + * bit 3: INJECT_ECC + * bit 4: INJECT_ADDR_PARITY + */ + + injectmask = (pvt->inject.type & 1) | + (pvt->inject.section & 0x3) << 1 | + (pvt->inject.type & 0x6) << (3 - 1); + + /* Unlock writes to registers - this register is write only */ pci_write_config_dword(pvt->pci_noncore[pvt->inject.socket], MC_CFG_CONTROL, 0x2); - msleep(100); +#if 0 /* Zeroes error count registers */ pci_write_config_dword(pvt->pci_mcr[pvt->inject.socket][4], MC_TEST_ERR_RCV1, 0); pci_write_config_dword(pvt->pci_mcr[pvt->inject.socket][4], MC_TEST_ERR_RCV0, 0); pvt->ce_count_available[pvt->inject.socket] = 0; +#endif - -#if USE_QWORD - pci_write_config_qword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], + write_and_test(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], MC_CHANNEL_ADDR_MATCH, mask); -#else - pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], - MC_CHANNEL_ADDR_MATCH, mask); - pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], + write_and_test(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], MC_CHANNEL_ADDR_MATCH + 4, mask >> 32L); -#endif -#if 1 -#if USE_QWORD - u64 rdmask; - pci_read_config_qword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], - MC_CHANNEL_ADDR_MATCH, &rdmask); - debugf0("Inject addr match write 0x%016llx, read: 0x%016llx\n", - mask, rdmask); -#else - u32 rdmask1, rdmask2; - - pci_read_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], - MC_CHANNEL_ADDR_MATCH, &rdmask1); - pci_read_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], - MC_CHANNEL_ADDR_MATCH + 4, &rdmask2); - - debugf0("Inject addr match write 0x%016llx, read: 0x%08x 0x%08x\n", - mask, rdmask1, rdmask2); -#endif -#endif - - pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], + write_and_test(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], MC_CHANNEL_ERROR_MASK, pvt->inject.eccmask); + write_and_test(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], + MC_CHANNEL_ERROR_MASK, injectmask); + /* - * bit 0: REPEAT_EN - * bits 1-2: MASK_HALF_CACHELINE - * bit 3: INJECT_ECC - * bit 4: INJECT_ADDR_PARITY + * This is something undocumented, based on my tests + * Without writing 8 to this register, errors aren't injected. Not sure + * why. */ + pci_write_config_dword(pvt->pci_noncore[pvt->inject.socket], + MC_CFG_CONTROL, 8); - injectmask = (pvt->inject.type & 1) | - (pvt->inject.section & 0x3) << 1 | - (pvt->inject.type & 0x6) << (3 - 1); - - pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], - MC_CHANNEL_ERROR_MASK, injectmask); - -#if 0 - /* lock writes to registers */ - pci_write_config_dword(pvt->pci_noncore, MC_CFG_CONTROL, 0); -#endif debugf0("Error inject addr match 0x%016llx, ecc 0x%08x," " inject 0x%08x\n", mask, pvt->inject.eccmask, injectmask); -- cgit v1.2.3 From 2068def56c09f2b24e6de04a1b84757a0fb07947 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 5 Aug 2009 19:28:27 -0300 Subject: i7core_edac: fix error codes for sysfs error injection interface Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 72859e87aeb2..ab9d26ec19d7 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -644,7 +644,7 @@ static ssize_t i7core_inject_socket_store(struct mem_ctl_info *mci, rc = strict_strtoul(data, 10, &value); if ((rc < 0) || (value >= pvt->sockets)) - return 0; + return -EIO; pvt->inject.section = (u32) value; return count; @@ -676,7 +676,7 @@ static ssize_t i7core_inject_section_store(struct mem_ctl_info *mci, rc = strict_strtoul(data, 10, &value); if ((rc < 0) || (value > 3)) - return 0; + return -EIO; pvt->inject.section = (u32) value; return count; @@ -709,7 +709,7 @@ static ssize_t i7core_inject_type_store(struct mem_ctl_info *mci, rc = strict_strtoul(data, 10, &value); if ((rc < 0) || (value > 7)) - return 0; + return -EIO; pvt->inject.type = (u32) value; return count; @@ -744,7 +744,7 @@ static ssize_t i7core_inject_eccmask_store(struct mem_ctl_info *mci, rc = strict_strtoul(data, 10, &value); if (rc < 0) - return 0; + return -EIO; pvt->inject.eccmask = (u32) value; return count; -- cgit v1.2.3 From 4157d9f55435331deef01ba8a9a47f248c042fb2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 5 Aug 2009 20:27:15 -0300 Subject: i7core_edac: fix error injection There were two stupid error injection bugs introduced by wrong cut-and-paste: one at socket store, and another at the error inject register. The last one were causing the code to not work at all. While here, adds debug messages to allow seeing what registers are being set while sending error injection. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index ab9d26ec19d7..f16aac253654 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -625,7 +625,7 @@ static int disable_inject(struct mem_ctl_info *mci) return -ENODEV; pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], - MC_CHANNEL_ERROR_MASK, 0); + MC_CHANNEL_ERROR_INJECT, 0); return 0; } @@ -646,7 +646,7 @@ static ssize_t i7core_inject_socket_store(struct mem_ctl_info *mci, if ((rc < 0) || (value >= pvt->sockets)) return -EIO; - pvt->inject.section = (u32) value; + pvt->inject.socket = (u32) value; return count; } @@ -872,6 +872,10 @@ static int write_and_test(struct pci_dev *dev, int where, u32 val) u32 read; int count; + debugf0("setting pci %02x:%02x.%x reg=%02x value=%08x\n", + dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), + where, val); + for (count = 0; count < 10; count++) { if (count) msleep (100); @@ -882,8 +886,10 @@ static int write_and_test(struct pci_dev *dev, int where, u32 val) return 0; } - debugf0("Error Injection Register 0x%02x: Tried to write 0x%08x, " - "but read: 0x%08x\n", where, val, read); + i7core_printk(KERN_ERR, "Error during set pci %02x:%02x.%x reg=%02x " + "write=%08x. Read=%08x\n", + dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), + where, val, read); return -EINVAL; } @@ -983,15 +989,6 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, pci_write_config_dword(pvt->pci_noncore[pvt->inject.socket], MC_CFG_CONTROL, 0x2); -#if 0 - /* Zeroes error count registers */ - pci_write_config_dword(pvt->pci_mcr[pvt->inject.socket][4], - MC_TEST_ERR_RCV1, 0); - pci_write_config_dword(pvt->pci_mcr[pvt->inject.socket][4], - MC_TEST_ERR_RCV0, 0); - pvt->ce_count_available[pvt->inject.socket] = 0; -#endif - write_and_test(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], MC_CHANNEL_ADDR_MATCH, mask); write_and_test(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], @@ -1001,7 +998,7 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, MC_CHANNEL_ERROR_MASK, pvt->inject.eccmask); write_and_test(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], - MC_CHANNEL_ERROR_MASK, injectmask); + MC_CHANNEL_ERROR_INJECT, injectmask); /* * This is something undocumented, based on my tests @@ -1026,7 +1023,7 @@ static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci, u32 injectmask; pci_read_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], - MC_CHANNEL_ERROR_MASK, &injectmask); + MC_CHANNEL_ERROR_INJECT, &injectmask); debugf0("Inject error read: 0x%018x\n", injectmask); -- cgit v1.2.3 From b990538a78ea84e89551ccaddf182beb5e16e6d2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 5 Aug 2009 21:36:35 -0300 Subject: i7core_edac: CodingSyle fixes/cleanups No functional changes. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 50 +++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index f16aac253654..86037a601b54 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -38,10 +38,6 @@ #define I7CORE_REVISION " Ver: 1.0.0 " __DATE__ #define EDAC_MOD_STR "i7core_edac" -/* HACK: temporary, just to enable all logs, for now */ -#undef debugf0 -#define debugf0(fmt, arg...) edac_printk(KERN_INFO, "i7core", fmt, ##arg) - /* * Debug macros */ @@ -105,6 +101,7 @@ #define REPEAT_EN 0x01 /* OFFSETS for Devices 4,5 and 6 Function 1 */ + #define MC_DOD_CH_DIMM0 0x48 #define MC_DOD_CH_DIMM1 0x4c #define MC_DOD_CH_DIMM2 0x50 @@ -227,7 +224,7 @@ struct pci_id_descr pci_devs[] = { /* Memory controller */ { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) }, { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) }, - { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_I7_MC_RAS) }, /* if RDIMM is supported */ + { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_I7_MC_RAS) }, /* if RDIMM */ { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_I7_MC_TEST) }, /* Channel 0 */ @@ -878,7 +875,7 @@ static int write_and_test(struct pci_dev *dev, int where, u32 val) for (count = 0; count < 10; count++) { if (count) - msleep (100); + msleep(100); pci_write_config_dword(dev, where, val); pci_read_config_dword(dev, where, &read); @@ -894,7 +891,6 @@ static int write_and_test(struct pci_dev *dev, int where, u32 val) return -EINVAL; } - /* * This routine prepares the Memory Controller for error injection. * The error will be injected when some process tries to write to the @@ -1326,7 +1322,7 @@ static void check_mc_test_err(struct mem_ctl_info *mci, u8 socket) int new0, new1, new2; if (!pvt->pci_mcr[socket][4]) { - debugf0("%s MCR registers not found\n",__func__); + debugf0("%s MCR registers not found\n", __func__); return; } @@ -1405,24 +1401,24 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci, type = "NON_FATAL"; switch (optypenum) { - case 0: - optype = "generic undef request"; - break; - case 1: - optype = "read error"; - break; - case 2: - optype = "write error"; - break; - case 3: - optype = "addr/cmd error"; - break; - case 4: - optype = "scrubbing error"; - break; - default: - optype = "reserved"; - break; + case 0: + optype = "generic undef request"; + break; + case 1: + optype = "read error"; + break; + case 2: + optype = "write error"; + break; + case 3: + optype = "addr/cmd error"; + break; + case 4: + optype = "scrubbing error"; + break; + default: + optype = "reserved"; + break; } switch (errnum) { @@ -1672,7 +1668,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, spin_lock_init(&pvt->mce_lock); rc = edac_mce_register(&pvt->edac_mce); - if (unlikely (rc < 0)) { + if (unlikely(rc < 0)) { debugf0("MC: " __FILE__ ": %s(): failed edac_mce_register()\n", __func__); goto fail1; -- cgit v1.2.3 From 3ef288a98307adc9d3f83321b26281567f348ec6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 2 Sep 2009 23:43:33 -0300 Subject: i7core_edac: Print an error message if pci register fails Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 86037a601b54..26205e2efecf 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1743,7 +1743,13 @@ static int __init i7core_init(void) pci_rc = pci_register_driver(&i7core_driver); - return (pci_rc < 0) ? pci_rc : 0; + if (pci_rc >= 0) + return 0; + + i7core_printk(KERN_ERR, "Failed to register device with error %d.\n", + pci_rc); + + return pci_rc; } /* -- cgit v1.2.3 From 61053fdedb2080dadc18dc37abbba90d2e74bc03 Mon Sep 17 00:00:00 2001 From: Keith Mannthey Date: Wed, 2 Sep 2009 23:46:59 -0300 Subject: i7core_edac: Fix ecc enable shift From: Keith Mannthey Simple correction to a shift value. ECC_ENABLED is bit 4 of MC_STATUS, Dev 3 Fun 0 Offset 0x4c This correctly identifies the state of the ECC at the machine. Signed-off-by: Keith Mannthey Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 26205e2efecf..87d5695f5fb0 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -286,7 +286,7 @@ static struct edac_pci_ctl_info *i7core_pci; #define ECCx8(pvt) ((pvt)->info.mc_control & (1 << 1)) /* MC_STATUS bits */ -#define ECC_ENABLED(pvt) ((pvt)->info.mc_status & (1 << 3)) +#define ECC_ENABLED(pvt) ((pvt)->info.mc_status & (1 << 4)) #define CH_DISABLED(pvt, ch) ((pvt)->info.mc_status & (1 << ch)) /* MC_MAX_DOD read functions */ -- cgit v1.2.3 From b4e8f0b6eaa1e99f1a64e539466a8ee2fb521d62 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 2 Sep 2009 23:49:59 -0300 Subject: i7core_edac: Use Device 3 function 2 to report errors with RDIMM's Nehalem and upper chipsets provide an special device that has corrected memory error counters detected with registered dimms. This device is only seen if there are registered memories plugged. After this patch, on a machine fully equiped with RDIMM's, it will use the Device 3 function 2 to count corrected errors instead on relying at mcelog. For unregistered DIMMs, it will keep the old behavior, counting errors via mcelog. This patch were developed together with Keith Mannthey Signed-off-by: Keith Mannthey Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 208 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 178 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 87d5695f5fb0..4758c208f39a 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -73,6 +73,18 @@ #define DIMM1_COR_ERR(r) (((r) >> 16) & 0x7fff) #define DIMM0_COR_ERR(r) ((r) & 0x7fff) +/* OFFSETS for Device 3 Function 2, as inicated on Xeon 5500 datasheet */ +#define MC_COR_ECC_CNT_0 0x80 +#define MC_COR_ECC_CNT_1 0x84 +#define MC_COR_ECC_CNT_2 0x88 +#define MC_COR_ECC_CNT_3 0x8c +#define MC_COR_ECC_CNT_4 0x90 +#define MC_COR_ECC_CNT_5 0x94 + +#define DIMM_TOP_COR_ERR(r) (((r) >> 16) & 0x7fff) +#define DIMM_BOT_COR_ERR(r) ((r) & 0x7fff) + + /* OFFSETS for Devices 4,5 and 6 Function 0 */ #define MC_CHANNEL_DIMM_INIT_PARAMS 0x58 @@ -194,13 +206,20 @@ struct i7core_pvt { struct i7core_inject inject; struct i7core_channel channel[NUM_SOCKETS][NUM_CHANS]; + unsigned int is_registered:1; /* true if all memories are RDIMMs */ + int sockets; /* Number of sockets */ int channels; /* Number of active channels */ int ce_count_available[NUM_SOCKETS]; - /* ECC corrected errors counts per dimm */ - unsigned long ce_count[NUM_SOCKETS][MAX_DIMMS]; - int last_ce_count[NUM_SOCKETS][MAX_DIMMS]; + int csrow_map[NUM_SOCKETS][NUM_CHANS][MAX_DIMMS]; + + /* ECC corrected errors counts per udimm */ + unsigned long udimm_ce_count[NUM_SOCKETS][MAX_DIMMS]; + int udimm_last_ce_count[NUM_SOCKETS][MAX_DIMMS]; + /* ECC corrected errors counts per rdimm */ + unsigned long rdimm_ce_count[NUM_SOCKETS][NUM_CHANS][MAX_DIMMS]; + int rdimm_last_ce_count[NUM_SOCKETS][NUM_CHANS][MAX_DIMMS]; /* mcelog glue */ struct edac_mce edac_mce; @@ -471,6 +490,8 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket) numrow(pvt->info.max_dod >> 6), numcol(pvt->info.max_dod >> 9)); + pvt->is_registered = 1; + for (i = 0; i < NUM_CHANS; i++) { u32 data, dimm_dod[3], value[8]; @@ -492,8 +513,14 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket) if (data & REGISTERED_DIMM) mtype = MEM_RDDR3; - else + else { mtype = MEM_DDR3; + /* + * FIXME: Currently, the driver will use dev 3:2 + * counter registers only if all memories are registered + */ + pvt->is_registered = 0; + } #if 0 if (data & THREE_DIMMS_PRESENT) pvt->channel[i].dimms = 3; @@ -562,6 +589,8 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket) csr->channels[0].chan_idx = i; csr->channels[0].ce_count = 0; + pvt->csrow_map[socket][i][j] = *csrow; + switch (banks) { case 4: csr->dtype = DEV_X4; @@ -1031,19 +1060,31 @@ static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci, static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data) { - unsigned i, count, total = 0; + unsigned i, j, count, total = 0; struct i7core_pvt *pvt = mci->pvt_info; for (i = 0; i < pvt->sockets; i++) { - if (!pvt->ce_count_available[i]) + if (!pvt->ce_count_available[i]) { count = sprintf(data, "socket 0 data unavailable\n"); - else + continue; + } + if (!pvt->is_registered) count = sprintf(data, "socket %d, dimm0: %lu\n" "dimm1: %lu\ndimm2: %lu\n", i, - pvt->ce_count[i][0], - pvt->ce_count[i][1], - pvt->ce_count[i][2]); + pvt->udimm_ce_count[i][0], + pvt->udimm_ce_count[i][1], + pvt->udimm_ce_count[i][2]); + else + for (j = 0; j < NUM_CHANS; j++) { + count = sprintf(data, "socket %d, channel %d" + "dimm0: %lu\n" + "dimm1: %lu\ndimm2: %lu\n", + i, j, + pvt->rdimm_ce_count[i][j][0], + pvt->rdimm_ce_count[i][j][1], + pvt->rdimm_ce_count[i][j][2]); + } data += count; total += count; } @@ -1308,6 +1349,103 @@ error: /**************************************************************************** Error check routines ****************************************************************************/ +static void i7core_rdimm_update_csrow(struct mem_ctl_info *mci, int socket, + int chan, int dimm, int add) +{ + char *msg; + struct i7core_pvt *pvt = mci->pvt_info; + int row = pvt->csrow_map[socket][chan][dimm], i; + + for (i = 0; i < add; i++) { + msg = kasprintf(GFP_KERNEL, "Corrected error " + "(Socket=%d channel=%d dimm=%d", + socket, chan, dimm); + + edac_mc_handle_fbd_ce(mci, row, 0, msg); + kfree (msg); + } +} + +static void i7core_rdimm_update_ce_count(struct mem_ctl_info *mci, + int socket, int chan, int new0, int new1, int new2) +{ + struct i7core_pvt *pvt = mci->pvt_info; + int add0 = 0, add1 = 0, add2 = 0; + /* Updates CE counters if it is not the first time here */ + if (pvt->ce_count_available[socket]) { + /* Updates CE counters */ + + add2 = new2 - pvt->rdimm_last_ce_count[socket][chan][2]; + add1 = new1 - pvt->rdimm_last_ce_count[socket][chan][1]; + add0 = new0 - pvt->rdimm_last_ce_count[socket][chan][0]; + + if (add2 < 0) + add2 += 0x7fff; + pvt->rdimm_ce_count[socket][chan][2] += add2; + + if (add1 < 0) + add1 += 0x7fff; + pvt->rdimm_ce_count[socket][chan][1] += add1; + + if (add0 < 0) + add0 += 0x7fff; + pvt->rdimm_ce_count[socket][chan][0] += add0; + } else + pvt->ce_count_available[socket] = 1; + + /* Store the new values */ + pvt->rdimm_last_ce_count[socket][chan][2] = new2; + pvt->rdimm_last_ce_count[socket][chan][1] = new1; + pvt->rdimm_last_ce_count[socket][chan][0] = new0; + + /*updated the edac core */ + if (add0 != 0) + i7core_rdimm_update_csrow(mci, socket, chan, 0, add0); + if (add1 != 0) + i7core_rdimm_update_csrow(mci, socket, chan, 1, add1); + if (add2 != 0) + i7core_rdimm_update_csrow(mci, socket, chan, 2, add2); + +} + +static void i7core_rdimm_check_mc_ecc_err(struct mem_ctl_info *mci, u8 socket) +{ + struct i7core_pvt *pvt = mci->pvt_info; + u32 rcv[3][2]; + int i, new0, new1, new2; + + /*Read DEV 3: FUN 2: MC_COR_ECC_CNT regs directly*/ + pci_read_config_dword(pvt->pci_mcr[socket][2], MC_COR_ECC_CNT_0, + &rcv[0][0]); + pci_read_config_dword(pvt->pci_mcr[socket][2], MC_COR_ECC_CNT_1, + &rcv[0][1]); + pci_read_config_dword(pvt->pci_mcr[socket][2], MC_COR_ECC_CNT_2, + &rcv[1][0]); + pci_read_config_dword(pvt->pci_mcr[socket][2], MC_COR_ECC_CNT_3, + &rcv[1][1]); + pci_read_config_dword(pvt->pci_mcr[socket][2], MC_COR_ECC_CNT_4, + &rcv[2][0]); + pci_read_config_dword(pvt->pci_mcr[socket][2], MC_COR_ECC_CNT_5, + &rcv[2][1]); + for (i = 0 ; i < 3; i++) { + debugf3("MC_COR_ECC_CNT%d = 0x%x; MC_COR_ECC_CNT%d = 0x%x\n", + (i * 2), rcv[i][0], (i * 2) + 1, rcv[i][1]); + /*if the channel has 3 dimms*/ + if (pvt->channel[socket][i].dimms > 2) { + new0 = DIMM_BOT_COR_ERR(rcv[i][0]); + new1 = DIMM_TOP_COR_ERR(rcv[i][0]); + new2 = DIMM_BOT_COR_ERR(rcv[i][1]); + } else { + new0 = DIMM_TOP_COR_ERR(rcv[i][0]) + + DIMM_BOT_COR_ERR(rcv[i][0]); + new1 = DIMM_TOP_COR_ERR(rcv[i][1]) + + DIMM_BOT_COR_ERR(rcv[i][1]); + new2 = 0; + } + + i7core_rdimm_update_ce_count(mci, socket, i, new0, new1, new2); + } +} /* This function is based on the device 3 function 4 registers as described on: * Intel Xeon Processor 5500 Series Datasheet Volume 2 @@ -1315,7 +1453,7 @@ error: * also available at: * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf */ -static void check_mc_test_err(struct mem_ctl_info *mci, u8 socket) +static void i7core_udimm_check_mc_ecc_err(struct mem_ctl_info *mci, u8 socket) { struct i7core_pvt *pvt = mci->pvt_info; u32 rcv1, rcv0; @@ -1326,7 +1464,7 @@ static void check_mc_test_err(struct mem_ctl_info *mci, u8 socket) return; } - /* Corrected error reads */ + /* Corrected test errors */ pci_read_config_dword(pvt->pci_mcr[socket][4], MC_TEST_ERR_RCV1, &rcv1); pci_read_config_dword(pvt->pci_mcr[socket][4], MC_TEST_ERR_RCV0, &rcv0); @@ -1335,39 +1473,38 @@ static void check_mc_test_err(struct mem_ctl_info *mci, u8 socket) new1 = DIMM1_COR_ERR(rcv0); new0 = DIMM0_COR_ERR(rcv0); -#if 0 - debugf2("%s CE rcv1=0x%08x rcv0=0x%08x, %d %d %d\n", - (pvt->ce_count_available ? "UPDATE" : "READ"), - rcv1, rcv0, new0, new1, new2); -#endif - /* Updates CE counters if it is not the first time here */ if (pvt->ce_count_available[socket]) { /* Updates CE counters */ int add0, add1, add2; - add2 = new2 - pvt->last_ce_count[socket][2]; - add1 = new1 - pvt->last_ce_count[socket][1]; - add0 = new0 - pvt->last_ce_count[socket][0]; + add2 = new2 - pvt->udimm_last_ce_count[socket][2]; + add1 = new1 - pvt->udimm_last_ce_count[socket][1]; + add0 = new0 - pvt->udimm_last_ce_count[socket][0]; if (add2 < 0) add2 += 0x7fff; - pvt->ce_count[socket][2] += add2; + pvt->udimm_ce_count[socket][2] += add2; if (add1 < 0) add1 += 0x7fff; - pvt->ce_count[socket][1] += add1; + pvt->udimm_ce_count[socket][1] += add1; if (add0 < 0) add0 += 0x7fff; - pvt->ce_count[socket][0] += add0; + pvt->udimm_ce_count[socket][0] += add0; + + if (add0 | add1 | add2) + i7core_printk(KERN_ERR, "New Corrected error(s): " + "dimm0: +%d, dimm1: +%d, dimm2 +%d\n", + add0, add1, add2); } else pvt->ce_count_available[socket] = 1; /* Store the new values */ - pvt->last_ce_count[socket][2] = new2; - pvt->last_ce_count[socket][1] = new1; - pvt->last_ce_count[socket][0] = new0; + pvt->udimm_last_ce_count[socket][2] = new2; + pvt->udimm_last_ce_count[socket][1] = new1; + pvt->udimm_last_ce_count[socket][0] = new0; } /* @@ -1386,6 +1523,7 @@ static void check_mc_test_err(struct mem_ctl_info *mci, u8 socket) static void i7core_mce_output_error(struct mem_ctl_info *mci, struct mce *m) { + struct i7core_pvt *pvt = mci->pvt_info; char *type, *optype, *err, *msg; unsigned long error = m->status & 0x1ff0000l; u32 optypenum = (m->status >> 4) & 0x07; @@ -1394,6 +1532,7 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci, u32 channel = (m->misc >> 18) & 0x3; u32 syndrome = m->misc >> 32; u32 errnum = find_first_bit(&error, 32); + int csrow; if (m->mcgstatus & 1) type = "FATAL"; @@ -1463,9 +1602,15 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci, debugf0("%s", msg); + csrow = pvt->csrow_map[m->cpu][channel][dimm]; + /* Call the helper to output message */ - edac_mc_handle_fbd_ue(mci, 0 /* FIXME: should be rank here */, - 0, 0 /* FIXME: should be channel here */, msg); + if (m->mcgstatus & 1) + edac_mc_handle_fbd_ue(mci, csrow, 0, + 0 /* FIXME: should be channel here */, msg); + else if (!pvt->is_registered) + edac_mc_handle_fbd_ce(mci, csrow, + 0 /* FIXME: should be channel here */, msg); kfree(msg); } @@ -1502,7 +1647,10 @@ static void i7core_check_error(struct mem_ctl_info *mci) /* check memory count errors */ for (i = 0; i < pvt->sockets; i++) - check_mc_test_err(mci, i); + if (!pvt->is_registered) + i7core_udimm_check_mc_ecc_err(mci, i); + else + i7core_rdimm_check_mc_ecc_err(mci, i); } /* -- cgit v1.2.3 From 14d2c08343eecd13f6c6ec232c98b16762b97924 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 2 Sep 2009 23:52:36 -0300 Subject: i7core: Use registered memories per processor Instead of assuming that the entire machine has either registered or unregistered memories, do it at CPU socket based. While here, fix a bug at i7core_mce_output_error(), where the we're using m->cpu directly as if it would represent a socket. Instead, the proper socket_id is given by cpu_data[m->cpu].phys_proc_id. Signed-off-by: Mauro Carvalho Chehab --- --- drivers/edac/i7core_edac.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 4758c208f39a..9f4e9d7d4dbf 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "edac_core.h" @@ -206,8 +207,6 @@ struct i7core_pvt { struct i7core_inject inject; struct i7core_channel channel[NUM_SOCKETS][NUM_CHANS]; - unsigned int is_registered:1; /* true if all memories are RDIMMs */ - int sockets; /* Number of sockets */ int channels; /* Number of active channels */ @@ -221,6 +220,8 @@ struct i7core_pvt { unsigned long rdimm_ce_count[NUM_SOCKETS][NUM_CHANS][MAX_DIMMS]; int rdimm_last_ce_count[NUM_SOCKETS][NUM_CHANS][MAX_DIMMS]; + unsigned int is_registered[NUM_SOCKETS]; + /* mcelog glue */ struct edac_mce edac_mce; struct mce mce_entry[MCE_LOG_LEN]; @@ -490,8 +491,6 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket) numrow(pvt->info.max_dod >> 6), numcol(pvt->info.max_dod >> 9)); - pvt->is_registered = 1; - for (i = 0; i < NUM_CHANS; i++) { u32 data, dimm_dod[3], value[8]; @@ -513,14 +512,8 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket) if (data & REGISTERED_DIMM) mtype = MEM_RDDR3; - else { + else mtype = MEM_DDR3; - /* - * FIXME: Currently, the driver will use dev 3:2 - * counter registers only if all memories are registered - */ - pvt->is_registered = 0; - } #if 0 if (data & THREE_DIMMS_PRESENT) pvt->channel[i].dimms = 3; @@ -1068,7 +1061,7 @@ static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data) count = sprintf(data, "socket 0 data unavailable\n"); continue; } - if (!pvt->is_registered) + if (!pvt->is_registered[i]) count = sprintf(data, "socket %d, dimm0: %lu\n" "dimm1: %lu\ndimm2: %lu\n", i, @@ -1310,7 +1303,9 @@ static int mci_bind_devs(struct mem_ctl_info *mci) struct pci_dev *pdev; int i, j, func, slot; + for (i = 0; i < pvt->sockets; i++) { + pvt->is_registered[i] = 0; for (j = 0; j < N_DEVS; j++) { pdev = pci_devs[j].pdev[i]; if (!pdev) @@ -1334,6 +1329,10 @@ static int mci_bind_devs(struct mem_ctl_info *mci) debugf0("Associated fn %d.%d, dev = %p, socket %d\n", PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), pdev, i); + + if (PCI_SLOT(pdev->devfn) == 3 && + PCI_FUNC(pdev->devfn) == 2) + pvt->is_registered[i] = 1; } } @@ -1533,6 +1532,11 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci, u32 syndrome = m->misc >> 32; u32 errnum = find_first_bit(&error, 32); int csrow; +#ifdef CONFIG_SMP + u32 socket_id = cpu_data[m->cpu].phys_proc_id; +#else + u32 socket_id = 0; +#endif if (m->mcgstatus & 1) type = "FATAL"; @@ -1596,19 +1600,22 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci, msg = kasprintf(GFP_ATOMIC, "%s (addr = 0x%08llx, socket=%d, Dimm=%d, Channel=%d, " "syndrome=0x%08x, count=%d, Err=%08llx:%08llx (%s: %s))\n", - type, (long long) m->addr, m->cpu, dimm, channel, + type, (long long) m->addr, socket_id, dimm, channel, syndrome, core_err_cnt, (long long)m->status, (long long)m->misc, optype, err); debugf0("%s", msg); - csrow = pvt->csrow_map[m->cpu][channel][dimm]; + if (socket_id < NUM_SOCKETS) + csrow = pvt->csrow_map[socket_id][channel][dimm]; + else + csrow = -1; /* Call the helper to output message */ if (m->mcgstatus & 1) edac_mc_handle_fbd_ue(mci, csrow, 0, 0 /* FIXME: should be channel here */, msg); - else if (!pvt->is_registered) + else if (!pvt->is_registered[socket_id]) edac_mc_handle_fbd_ce(mci, csrow, 0 /* FIXME: should be channel here */, msg); @@ -1647,7 +1654,7 @@ static void i7core_check_error(struct mem_ctl_info *mci) /* check memory count errors */ for (i = 0; i < pvt->sockets; i++) - if (!pvt->is_registered) + if (!pvt->is_registered[i]) i7core_udimm_check_mc_ecc_err(mci, i); else i7core_rdimm_check_mc_ecc_err(mci, i); -- cgit v1.2.3 From bc2d7245ff1c5466c877a0c32a7ec9563187a032 Mon Sep 17 00:00:00 2001 From: Keith Mannthey Date: Thu, 3 Sep 2009 00:05:05 -0300 Subject: i7core_edac: Probe on Xeons eariler On the Xeon 55XX series cpus the pci deives are not exposed via acpi so we much explicitly probe them to make the usable as a Linux PCI device. This moves the detection of this state to before pci_register_driver is called. Its present position was not working on my systems, the driver would complain about not finding a specific device. This patch allows the driver to load on my systems. Signed-off-by: Keith Mannthey Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 9f4e9d7d4dbf..9fe7ec762e68 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1158,6 +1158,23 @@ static void i7core_put_devices(void) pci_dev_put(pci_devs[j].pdev[i]); } +static void i7core_xeon_pci_fixup(void) +{ + struct pci_dev *pdev = NULL; + int i; + /* + * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core pci buses + * aren't announced by acpi. So, we need to use a legacy scan probing + * to detect them + */ + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, + pci_devs[0].dev_id, NULL); + if (unlikely(!pdev)) { + for (i = 0; i < NUM_SOCKETS; i ++) + pcibios_scan_specific_bus(255-i); + } +} + /* * i7core_get_devices Find and perform 'get' operation on the MCH's * device/functions we want to reference for this driver @@ -1173,19 +1190,6 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno) pdev = pci_get_device(PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id, *prev); - /* - * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core pci buses - * aren't announced by acpi. So, we need to use a legacy scan probing - * to detect them - */ - if (unlikely(!pdev && !devno && !prev)) { - pcibios_scan_specific_bus(254); - pcibios_scan_specific_bus(255); - - pdev = pci_get_device(PCI_VENDOR_ID_INTEL, - pci_devs[devno].dev_id, *prev); - } - /* * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core regs * is at addr 8086:2c40, instead of 8086:2c41. So, we need @@ -1896,6 +1900,8 @@ static int __init i7core_init(void) /* Ensure that the OPSTATE is set correctly for POLL or NMI */ opstate_init(); + i7core_xeon_pci_fixup(); + pci_rc = pci_register_driver(&i7core_driver); if (pci_rc >= 0) -- cgit v1.2.3 From 3a3bb4a647db4cb2468641df8da2ee9491784a9a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 3 Sep 2009 20:17:26 -0300 Subject: i7core_edac: Improve corrected_error_counts output for RDIMM Just cosmetics. instead of showing something like: socket 0, channel 2dimm0: 1 dimm1: 0 dimm2: 0 socket 1, channel 2dimm0: 0 dimm1: 0 dimm2: 0 Show: socket 0, channel 2 RDIMM0: 1 RDIMM1: 0 RDIMM2: 0 socket 0, channel 2 RDIMM0: 0 RDIMM1: 0 RDIMM2: 0 This is more synthetic and easier to parse. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 9fe7ec762e68..76f4e6d973af 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1070,9 +1070,9 @@ static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data) pvt->udimm_ce_count[i][2]); else for (j = 0; j < NUM_CHANS; j++) { - count = sprintf(data, "socket %d, channel %d" - "dimm0: %lu\n" - "dimm1: %lu\ndimm2: %lu\n", + count = sprintf(data, "socket %d, channel %d " + "RDIMM0: %lu " + "RDIMM1: %lu RDIMM2: %lu\n", i, j, pvt->rdimm_ce_count[i][j][0], pvt->rdimm_ce_count[i][j][1], -- cgit v1.2.3 From a55456f3446d19853af54b64b3840312f46b6ea5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 5 Sep 2009 00:47:21 -0300 Subject: i7core: temporary workaround to allow it to compile against 2.6.30 Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 76f4e6d973af..af222ffcfdfc 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1536,8 +1536,10 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci, u32 syndrome = m->misc >> 32; u32 errnum = find_first_bit(&error, 32); int csrow; -#ifdef CONFIG_SMP - u32 socket_id = cpu_data[m->cpu].phys_proc_id; +/* FIXME */ +//#ifdef CONFIG_SMP +#if 0 + u32 socket_id = per_cpu(cpu_data, cpu).phys_proc_id; #else u32 socket_id = 0; #endif -- cgit v1.2.3 From 66607706cee7b6901aa0509198f075859c93ec6a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 5 Sep 2009 00:52:11 -0300 Subject: Dynamically allocate memory for PCI devices Instead of using a static table assuming always 2 CPU sockets, allocate space dynamically for Nehalem PCI devs. This patch is part of a series of patches that changes i7core_edac to allow more than 2 sockets and to properly report one memory controller per socket. --- drivers/edac/i7core_edac.c | 175 +++++++++++++++++++++++++++++---------------- 1 file changed, 114 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index af222ffcfdfc..7bcb5993b501 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -192,10 +192,9 @@ struct i7core_channel { }; struct pci_id_descr { - int dev; - int func; - int dev_id; - struct pci_dev *pdev[NUM_SOCKETS]; + int dev; + int func; + int dev_id; }; struct i7core_pvt { @@ -229,6 +228,17 @@ struct i7core_pvt { spinlock_t mce_lock; }; +struct i7core_dev { + struct list_head list; + + int socket; + struct pci_dev **pdev; +}; + +/* Static vars */ +static LIST_HEAD(i7core_edac_list); +static DEFINE_MUTEX(i7core_edac_lock); + /* Device name and register DID (Device ID) */ struct i7core_dev_info { const char *ctl_name; /* name for this device */ @@ -240,7 +250,7 @@ struct i7core_dev_info { .func = (function), \ .dev_id = (device_id) -struct pci_id_descr pci_devs[] = { +struct pci_id_descr pci_dev_descr[] = { /* Memory controller */ { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) }, { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) }, @@ -275,11 +285,10 @@ struct pci_id_descr pci_devs[] = { { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_I7_NOCORE) }, }; -#define N_DEVS ARRAY_SIZE(pci_devs) +#define N_DEVS ARRAY_SIZE(pci_dev_descr) /* * pci_device_id table for which devices we are looking for - * This should match the first device at pci_devs table */ static const struct pci_device_id i7core_pci_tbl[] __devinitdata = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_X58_HUB_MGMT)}, @@ -288,7 +297,7 @@ static const struct pci_device_id i7core_pci_tbl[] __devinitdata = { /* Table of devices attributes supported by this driver */ -static const struct i7core_dev_info i7core_devs[] = { +static const struct i7core_dev_info i7core_probe_devs[] = { { .ctl_name = "i7 Core", .fsb_mapping_errors = PCI_DEVICE_ID_INTEL_I7_MCR, @@ -347,21 +356,37 @@ static inline int numcol(u32 col) return cols[col & 0x3]; } +static struct i7core_dev *get_i7core_dev(int socket) +{ + struct i7core_dev *i7core_dev; + + list_for_each_entry(i7core_dev, &i7core_edac_list, list) { + if (i7core_dev->socket == socket) + return i7core_dev; + } + + return NULL; +} + /**************************************************************************** Memory check routines ****************************************************************************/ static struct pci_dev *get_pdev_slot_func(u8 socket, unsigned slot, unsigned func) { + struct i7core_dev *i7core_dev = get_i7core_dev(socket); int i; + if (!i7core_dev) + return NULL; + for (i = 0; i < N_DEVS; i++) { - if (!pci_devs[i].pdev[socket]) + if (!i7core_dev->pdev[i]) continue; - if (PCI_SLOT(pci_devs[i].pdev[socket]->devfn) == slot && - PCI_FUNC(pci_devs[i].pdev[socket]->devfn) == func) { - return pci_devs[i].pdev[socket]; + if (PCI_SLOT(i7core_dev->pdev[i]->devfn) == slot && + PCI_FUNC(i7core_dev->pdev[i]->devfn) == func) { + return i7core_dev->pdev[i]; } } @@ -1153,9 +1178,18 @@ static void i7core_put_devices(void) { int i, j; - for (i = 0; i < NUM_SOCKETS; i++) + for (i = 0; i < NUM_SOCKETS; i++) { + struct i7core_dev *i7core_dev = get_i7core_dev(i); + if (!i7core_dev) + continue; + for (j = 0; j < N_DEVS; j++) - pci_dev_put(pci_devs[j].pdev[i]); + pci_dev_put(i7core_dev->pdev[j]); + + list_del(&i7core_dev->list); + kfree(i7core_dev->pdev); + kfree(i7core_dev); + } } static void i7core_xeon_pci_fixup(void) @@ -1168,7 +1202,7 @@ static void i7core_xeon_pci_fixup(void) * to detect them */ pdev = pci_get_device(PCI_VENDOR_ID_INTEL, - pci_devs[0].dev_id, NULL); + pci_dev_descr[0].dev_id, NULL); if (unlikely(!pdev)) { for (i = 0; i < NUM_SOCKETS; i ++) pcibios_scan_specific_bus(255-i); @@ -1183,19 +1217,21 @@ static void i7core_xeon_pci_fixup(void) */ int i7core_get_onedevice(struct pci_dev **prev, int devno) { + struct i7core_dev *i7core_dev; + struct pci_dev *pdev = NULL; u8 bus = 0; u8 socket = 0; pdev = pci_get_device(PCI_VENDOR_ID_INTEL, - pci_devs[devno].dev_id, *prev); + pci_dev_descr[devno].dev_id, *prev); /* * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core regs * is at addr 8086:2c40, instead of 8086:2c41. So, we need * to probe for the alternate address in case of failure */ - if (pci_devs[devno].dev_id == PCI_DEVICE_ID_INTEL_I7_NOCORE && !pdev) + if (pci_dev_descr[devno].dev_id == PCI_DEVICE_ID_INTEL_I7_NOCORE && !pdev) pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7_NOCORE_ALT, *prev); @@ -1209,15 +1245,15 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno) * Dev 3 function 2 only exists on chips with RDIMMs * so, it is ok to not found it */ - if ((pci_devs[devno].dev == 3) && (pci_devs[devno].func == 2)) { + if ((pci_dev_descr[devno].dev == 3) && (pci_dev_descr[devno].func == 2)) { *prev = pdev; return 0; } i7core_printk(KERN_ERR, "Device not found: dev %02x.%d PCI ID %04x:%04x\n", - pci_devs[devno].dev, pci_devs[devno].func, - PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id); + pci_dev_descr[devno].dev, pci_dev_descr[devno].func, + PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id); /* End of list, leave */ return -ENODEV; @@ -1229,37 +1265,40 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno) else socket = 255 - bus; - if (socket >= NUM_SOCKETS) { - i7core_printk(KERN_ERR, - "Unexpected socket for " - "dev %02x:%02x.%d PCI ID %04x:%04x\n", - bus, pci_devs[devno].dev, pci_devs[devno].func, - PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id); - pci_dev_put(pdev); - return -ENODEV; + i7core_dev = get_i7core_dev(socket); + if (!i7core_dev) { + i7core_dev = kzalloc(sizeof(*i7core_dev), GFP_KERNEL); + if (!i7core_dev) + return -ENOMEM; + i7core_dev->pdev = kzalloc(sizeof(*i7core_dev->pdev) * N_DEVS, + GFP_KERNEL); + if (!i7core_dev->pdev) + return -ENOMEM; + i7core_dev->socket = socket; + list_add_tail(&i7core_dev->list, &i7core_edac_list); } - if (pci_devs[devno].pdev[socket]) { + if (i7core_dev->pdev[devno]) { i7core_printk(KERN_ERR, "Duplicated device for " "dev %02x:%02x.%d PCI ID %04x:%04x\n", - bus, pci_devs[devno].dev, pci_devs[devno].func, - PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id); + bus, pci_dev_descr[devno].dev, pci_dev_descr[devno].func, + PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id); pci_dev_put(pdev); return -ENODEV; } - pci_devs[devno].pdev[socket] = pdev; + i7core_dev->pdev[devno] = pdev; /* Sanity check */ - if (unlikely(PCI_SLOT(pdev->devfn) != pci_devs[devno].dev || - PCI_FUNC(pdev->devfn) != pci_devs[devno].func)) { + if (unlikely(PCI_SLOT(pdev->devfn) != pci_dev_descr[devno].dev || + PCI_FUNC(pdev->devfn) != pci_dev_descr[devno].func)) { i7core_printk(KERN_ERR, "Device PCI ID %04x:%04x " "has dev %02x:%02x.%d instead of dev %02x:%02x.%d\n", - PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id, + PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id, bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), - bus, pci_devs[devno].dev, pci_devs[devno].func); + bus, pci_dev_descr[devno].dev, pci_dev_descr[devno].func); return -ENODEV; } @@ -1268,27 +1307,29 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno) i7core_printk(KERN_ERR, "Couldn't enable " "dev %02x:%02x.%d PCI ID %04x:%04x\n", - bus, pci_devs[devno].dev, pci_devs[devno].func, - PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id); + bus, pci_dev_descr[devno].dev, pci_dev_descr[devno].func, + PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id); return -ENODEV; } i7core_printk(KERN_INFO, "Registered socket %d " "dev %02x:%02x.%d PCI ID %04x:%04x\n", - socket, bus, pci_devs[devno].dev, pci_devs[devno].func, - PCI_VENDOR_ID_INTEL, pci_devs[devno].dev_id); + socket, bus, pci_dev_descr[devno].dev, pci_dev_descr[devno].func, + PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id); *prev = pdev; return 0; } -static int i7core_get_devices(void) +static int i7core_get_devices(u8 *sockets) { int i; struct pci_dev *pdev = NULL; + struct i7core_dev *i7core_dev = NULL; + *sockets = 0; for (i = 0; i < N_DEVS; i++) { pdev = NULL; do { @@ -1298,6 +1339,12 @@ static int i7core_get_devices(void) } } while (pdev); } + + list_for_each_entry(i7core_dev, &i7core_edac_list, list) { + if (i7core_dev->socket + 1 > *sockets) + *sockets = i7core_dev->socket + 1; + } + return 0; } @@ -1307,11 +1354,15 @@ static int mci_bind_devs(struct mem_ctl_info *mci) struct pci_dev *pdev; int i, j, func, slot; - for (i = 0; i < pvt->sockets; i++) { + struct i7core_dev *i7core_dev = get_i7core_dev(i); + + if (!i7core_dev) + continue; + pvt->is_registered[i] = 0; for (j = 0; j < N_DEVS; j++) { - pdev = pci_devs[j].pdev[i]; + pdev = i7core_dev->pdev[j]; if (!pdev) continue; @@ -1723,20 +1774,17 @@ static int __devinit i7core_probe(struct pci_dev *pdev, int rc, i; u8 sockets; - if (unlikely(dev_idx >= ARRAY_SIZE(i7core_devs))) + /* + * FIXME: All memory controllers are allocated at the first pass. + */ + if (unlikely(dev_idx >= 1)) return -EINVAL; /* get the pci devices we want to reserve for our use */ - rc = i7core_get_devices(); + mutex_lock(&i7core_edac_lock); + rc = i7core_get_devices(&sockets); if (unlikely(rc < 0)) - return rc; - - sockets = 1; - for (i = NUM_SOCKETS - 1; i > 0; i--) - if (pci_devs[0].pdev[i]) { - sockets = i + 1; - break; - } + goto fail0; for (i = 0; i < sockets; i++) { int channels; @@ -1745,7 +1793,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, /* Check the number of active and not disabled channels */ rc = i7core_get_active_channels(i, &channels, &csrows); if (unlikely(rc < 0)) - goto fail0; + goto fail1; num_channels += channels; num_csrows += csrows; @@ -1755,7 +1803,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0); if (unlikely(!mci)) { rc = -ENOMEM; - goto fail0; + goto fail1; } debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); @@ -1776,7 +1824,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, mci->edac_cap = EDAC_FLAG_NONE; mci->mod_name = "i7core_edac.c"; mci->mod_ver = I7CORE_REVISION; - mci->ctl_name = i7core_devs[dev_idx].ctl_name; + mci->ctl_name = i7core_probe_devs[dev_idx].ctl_name; mci->dev_name = pci_name(pdev); mci->ctl_page_to_phys = NULL; mci->mc_driver_sysfs_attributes = i7core_inj_attrs; @@ -1786,7 +1834,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, /* Store pci devices at mci for faster access */ rc = mci_bind_devs(mci); if (unlikely(rc < 0)) - goto fail1; + goto fail2; /* Get dimm basic config */ for (i = 0; i < sockets; i++) @@ -1801,7 +1849,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, */ rc = -EINVAL; - goto fail1; + goto fail2; } /* allocating generic PCI control info */ @@ -1832,18 +1880,21 @@ static int __devinit i7core_probe(struct pci_dev *pdev, if (unlikely(rc < 0)) { debugf0("MC: " __FILE__ ": %s(): failed edac_mce_register()\n", __func__); - goto fail1; + goto fail2; } i7core_printk(KERN_INFO, "Driver loaded.\n"); + mutex_unlock(&i7core_edac_lock); return 0; -fail1: +fail2: edac_mc_free(mci); -fail0: +fail1: i7core_put_devices(); +fail0: + mutex_unlock(&i7core_edac_lock); return rc; } @@ -1871,7 +1922,9 @@ static void __devexit i7core_remove(struct pci_dev *pdev) edac_mce_unregister(&pvt->edac_mce); /* retrieve references to resources, and free those resources */ + mutex_lock(&i7core_edac_lock); i7core_put_devices(); + mutex_unlock(&i7core_edac_lock); edac_mc_free(mci); } -- cgit v1.2.3 From f47429494fd50c0b7396fe3f8a26ea638b47c5ba Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 5 Sep 2009 02:35:08 -0300 Subject: i7core_edac: create one mc per socket/QPI Instead of creating just one memory controller, create one per socket (e. g. per Quick Link Path Interconnect). This better reflects the Nehalem architecture. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 507 ++++++++++++++++++++------------------------- 1 file changed, 228 insertions(+), 279 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 7bcb5993b501..5bc316b8e805 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -29,10 +29,20 @@ #include #include #include +#include #include #include "edac_core.h" +/* + * This is used for Nehalem-EP and Nehalem-EX devices, where the non-core + * registers start at bus 255, and are not reported by BIOS. + * We currently find devices with only 2 sockets. In order to support more QPI + * Quick Path Interconnect, just increment this number. + */ +#define MAX_SOCKET_BUSES 2 + + /* * Alter this version for the module when modifications are made */ @@ -162,7 +172,6 @@ #define NUM_CHANS 3 #define MAX_DIMMS 3 /* Max DIMMS per channel */ -#define NUM_SOCKETS 2 /* Max number of MC sockets */ #define MAX_MCR_FUNC 4 #define MAX_CHAN_FUNC 3 @@ -177,7 +186,6 @@ struct i7core_info { struct i7core_inject { int enable; - u8 socket; u32 section; u32 type; u32 eccmask; @@ -197,29 +205,37 @@ struct pci_id_descr { int dev_id; }; +struct i7core_dev { + struct list_head list; + u8 socket; + struct pci_dev **pdev; + struct mem_ctl_info *mci; +}; + struct i7core_pvt { - struct pci_dev *pci_noncore[NUM_SOCKETS]; - struct pci_dev *pci_mcr[NUM_SOCKETS][MAX_MCR_FUNC + 1]; - struct pci_dev *pci_ch[NUM_SOCKETS][NUM_CHANS][MAX_CHAN_FUNC + 1]; + struct pci_dev *pci_noncore; + struct pci_dev *pci_mcr[MAX_MCR_FUNC + 1]; + struct pci_dev *pci_ch[NUM_CHANS][MAX_CHAN_FUNC + 1]; + + struct i7core_dev *i7core_dev; struct i7core_info info; struct i7core_inject inject; - struct i7core_channel channel[NUM_SOCKETS][NUM_CHANS]; + struct i7core_channel channel[NUM_CHANS]; - int sockets; /* Number of sockets */ - int channels; /* Number of active channels */ + int channels; /* Number of active channels */ - int ce_count_available[NUM_SOCKETS]; - int csrow_map[NUM_SOCKETS][NUM_CHANS][MAX_DIMMS]; + int ce_count_available; + int csrow_map[NUM_CHANS][MAX_DIMMS]; /* ECC corrected errors counts per udimm */ - unsigned long udimm_ce_count[NUM_SOCKETS][MAX_DIMMS]; - int udimm_last_ce_count[NUM_SOCKETS][MAX_DIMMS]; + unsigned long udimm_ce_count[MAX_DIMMS]; + int udimm_last_ce_count[MAX_DIMMS]; /* ECC corrected errors counts per rdimm */ - unsigned long rdimm_ce_count[NUM_SOCKETS][NUM_CHANS][MAX_DIMMS]; - int rdimm_last_ce_count[NUM_SOCKETS][NUM_CHANS][MAX_DIMMS]; + unsigned long rdimm_ce_count[NUM_CHANS][MAX_DIMMS]; + int rdimm_last_ce_count[NUM_CHANS][MAX_DIMMS]; - unsigned int is_registered[NUM_SOCKETS]; + unsigned int is_registered; /* mcelog glue */ struct edac_mce edac_mce; @@ -228,22 +244,10 @@ struct i7core_pvt { spinlock_t mce_lock; }; -struct i7core_dev { - struct list_head list; - - int socket; - struct pci_dev **pdev; -}; - /* Static vars */ static LIST_HEAD(i7core_edac_list); static DEFINE_MUTEX(i7core_edac_lock); - -/* Device name and register DID (Device ID) */ -struct i7core_dev_info { - const char *ctl_name; /* name for this device */ - u16 fsb_mapping_errors; /* DID for the branchmap,control */ -}; +static u8 max_num_sockets; #define PCI_DESCR(device, function, device_id) \ .dev = (device), \ @@ -295,15 +299,6 @@ static const struct pci_device_id i7core_pci_tbl[] __devinitdata = { {0,} /* 0 terminated list. */ }; - -/* Table of devices attributes supported by this driver */ -static const struct i7core_dev_info i7core_probe_devs[] = { - { - .ctl_name = "i7 Core", - .fsb_mapping_errors = PCI_DEVICE_ID_INTEL_I7_MCR, - }, -}; - static struct edac_pci_ctl_info *i7core_pci; /**************************************************************************** @@ -356,7 +351,7 @@ static inline int numcol(u32 col) return cols[col & 0x3]; } -static struct i7core_dev *get_i7core_dev(int socket) +static struct i7core_dev *get_i7core_dev(u8 socket) { struct i7core_dev *i7core_dev; @@ -471,18 +466,19 @@ static int i7core_get_active_channels(u8 socket, unsigned *channels, return 0; } -static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket) +static int get_dimm_config(struct mem_ctl_info *mci, int *csrow) { struct i7core_pvt *pvt = mci->pvt_info; struct csrow_info *csr; struct pci_dev *pdev; int i, j; + u8 socket = pvt->i7core_dev->socket; unsigned long last_page = 0; enum edac_type mode; enum mem_type mtype; /* Get data from the MC register, function 0 */ - pdev = pvt->pci_mcr[socket][0]; + pdev = pvt->pci_mcr[0]; if (!pdev) return -ENODEV; @@ -529,10 +525,10 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket) } /* Devices 4-6 function 0 */ - pci_read_config_dword(pvt->pci_ch[socket][i][0], + pci_read_config_dword(pvt->pci_ch[i][0], MC_CHANNEL_DIMM_INIT_PARAMS, &data); - pvt->channel[socket][i].ranks = (data & QUAD_RANK_PRESENT) ? + pvt->channel[i].ranks = (data & QUAD_RANK_PRESENT) ? 4 : 2; if (data & REGISTERED_DIMM) @@ -549,11 +545,11 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket) #endif /* Devices 4-6 function 1 */ - pci_read_config_dword(pvt->pci_ch[socket][i][1], + pci_read_config_dword(pvt->pci_ch[i][1], MC_DOD_CH_DIMM0, &dimm_dod[0]); - pci_read_config_dword(pvt->pci_ch[socket][i][1], + pci_read_config_dword(pvt->pci_ch[i][1], MC_DOD_CH_DIMM1, &dimm_dod[1]); - pci_read_config_dword(pvt->pci_ch[socket][i][1], + pci_read_config_dword(pvt->pci_ch[i][1], MC_DOD_CH_DIMM2, &dimm_dod[2]); debugf0("Ch%d phy rd%d, wr%d (0x%08x): " @@ -561,7 +557,7 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket) i, RDLCH(pvt->info.ch_map, i), WRLCH(pvt->info.ch_map, i), data, - pvt->channel[socket][i].ranks, + pvt->channel[i].ranks, (data & REGISTERED_DIMM) ? 'R' : 'U'); for (j = 0; j < 3; j++) { @@ -579,7 +575,7 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket) /* DDR3 has 8 I/O banks */ size = (rows * cols * banks * ranks) >> (20 - 3); - pvt->channel[socket][i].dimms++; + pvt->channel[i].dimms++; debugf0("\tdimm %d %d Mb offset: %x, " "bank: %d, rank: %d, row: %#x, col: %#x\n", @@ -607,7 +603,7 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket) csr->channels[0].chan_idx = i; csr->channels[0].ce_count = 0; - pvt->csrow_map[socket][i][j] = *csrow; + pvt->csrow_map[i][j] = *csrow; switch (banks) { case 4: @@ -665,42 +661,15 @@ static int disable_inject(struct mem_ctl_info *mci) pvt->inject.enable = 0; - if (!pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0]) + if (!pvt->pci_ch[pvt->inject.channel][0]) return -ENODEV; - pci_write_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], + pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0], MC_CHANNEL_ERROR_INJECT, 0); return 0; } -/* - * i7core inject inject.socket - * - * accept and store error injection inject.socket value - */ -static ssize_t i7core_inject_socket_store(struct mem_ctl_info *mci, - const char *data, size_t count) -{ - struct i7core_pvt *pvt = mci->pvt_info; - unsigned long value; - int rc; - - rc = strict_strtoul(data, 10, &value); - if ((rc < 0) || (value >= pvt->sockets)) - return -EIO; - - pvt->inject.socket = (u32) value; - return count; -} - -static ssize_t i7core_inject_socket_show(struct mem_ctl_info *mci, - char *data) -{ - struct i7core_pvt *pvt = mci->pvt_info; - return sprintf(data, "%d\n", pvt->inject.socket); -} - /* * i7core inject inject.section * @@ -965,7 +934,7 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, int rc; long enable; - if (!pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0]) + if (!pvt->pci_ch[pvt->inject.channel][0]) return 0; rc = strict_strtoul(data, 10, &enable); @@ -983,7 +952,7 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, if (pvt->inject.dimm < 0) mask |= 1L << 41; else { - if (pvt->channel[pvt->inject.socket][pvt->inject.channel].dimms > 2) + if (pvt->channel[pvt->inject.channel].dimms > 2) mask |= (pvt->inject.dimm & 0x3L) << 35; else mask |= (pvt->inject.dimm & 0x1L) << 36; @@ -993,7 +962,7 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, if (pvt->inject.rank < 0) mask |= 1L << 40; else { - if (pvt->channel[pvt->inject.socket][pvt->inject.channel].dimms > 2) + if (pvt->channel[pvt->inject.channel].dimms > 2) mask |= (pvt->inject.rank & 0x1L) << 34; else mask |= (pvt->inject.rank & 0x3L) << 34; @@ -1029,18 +998,18 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, (pvt->inject.type & 0x6) << (3 - 1); /* Unlock writes to registers - this register is write only */ - pci_write_config_dword(pvt->pci_noncore[pvt->inject.socket], + pci_write_config_dword(pvt->pci_noncore, MC_CFG_CONTROL, 0x2); - write_and_test(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], + write_and_test(pvt->pci_ch[pvt->inject.channel][0], MC_CHANNEL_ADDR_MATCH, mask); - write_and_test(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], + write_and_test(pvt->pci_ch[pvt->inject.channel][0], MC_CHANNEL_ADDR_MATCH + 4, mask >> 32L); - write_and_test(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], + write_and_test(pvt->pci_ch[pvt->inject.channel][0], MC_CHANNEL_ERROR_MASK, pvt->inject.eccmask); - write_and_test(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], + write_and_test(pvt->pci_ch[pvt->inject.channel][0], MC_CHANNEL_ERROR_INJECT, injectmask); /* @@ -1048,7 +1017,7 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, * Without writing 8 to this register, errors aren't injected. Not sure * why. */ - pci_write_config_dword(pvt->pci_noncore[pvt->inject.socket], + pci_write_config_dword(pvt->pci_noncore, MC_CFG_CONTROL, 8); debugf0("Error inject addr match 0x%016llx, ecc 0x%08x," @@ -1065,7 +1034,7 @@ static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci, struct i7core_pvt *pvt = mci->pvt_info; u32 injectmask; - pci_read_config_dword(pvt->pci_ch[pvt->inject.socket][pvt->inject.channel][0], + pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0], MC_CHANNEL_ERROR_INJECT, &injectmask); debugf0("Inject error read: 0x%018x\n", injectmask); @@ -1078,34 +1047,30 @@ static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci, static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data) { - unsigned i, j, count, total = 0; + unsigned i, count, total = 0; struct i7core_pvt *pvt = mci->pvt_info; - for (i = 0; i < pvt->sockets; i++) { - if (!pvt->ce_count_available[i]) { - count = sprintf(data, "socket 0 data unavailable\n"); - continue; - } - if (!pvt->is_registered[i]) - count = sprintf(data, "socket %d, dimm0: %lu\n" - "dimm1: %lu\ndimm2: %lu\n", - i, - pvt->udimm_ce_count[i][0], - pvt->udimm_ce_count[i][1], - pvt->udimm_ce_count[i][2]); - else - for (j = 0; j < NUM_CHANS; j++) { - count = sprintf(data, "socket %d, channel %d " - "RDIMM0: %lu " - "RDIMM1: %lu RDIMM2: %lu\n", - i, j, - pvt->rdimm_ce_count[i][j][0], - pvt->rdimm_ce_count[i][j][1], - pvt->rdimm_ce_count[i][j][2]); - } - data += count; - total += count; + if (!pvt->ce_count_available) { + count = sprintf(data, "data unavailable\n"); + return 0; } + if (!pvt->is_registered) + count = sprintf(data, "all channels " + "UDIMM0: %lu UDIMM1: %lu UDIMM2: %lu\n", + pvt->udimm_ce_count[0], + pvt->udimm_ce_count[1], + pvt->udimm_ce_count[2]); + else + for (i = 0; i < NUM_CHANS; i++) { + count = sprintf(data, "channel %d RDIMM0: %lu " + "RDIMM1: %lu RDIMM2: %lu\n", + i, + pvt->rdimm_ce_count[i][0], + pvt->rdimm_ce_count[i][1], + pvt->rdimm_ce_count[i][2]); + } + data += count; + total += count; return total; } @@ -1115,13 +1080,6 @@ static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data) */ static struct mcidev_sysfs_attribute i7core_inj_attrs[] = { { - .attr = { - .name = "inject_socket", - .mode = (S_IRUGO | S_IWUSR) - }, - .show = i7core_inject_socket_show, - .store = i7core_inject_socket_store, - }, { .attr = { .name = "inject_section", .mode = (S_IRUGO | S_IWUSR) @@ -1178,7 +1136,7 @@ static void i7core_put_devices(void) { int i, j; - for (i = 0; i < NUM_SOCKETS; i++) { + for (i = 0; i < max_num_sockets; i++) { struct i7core_dev *i7core_dev = get_i7core_dev(i); if (!i7core_dev) continue; @@ -1204,7 +1162,7 @@ static void i7core_xeon_pci_fixup(void) pdev = pci_get_device(PCI_VENDOR_ID_INTEL, pci_dev_descr[0].dev_id, NULL); if (unlikely(!pdev)) { - for (i = 0; i < NUM_SOCKETS; i ++) + for (i = 0; i < MAX_SOCKET_BUSES; i++) pcibios_scan_specific_bus(255-i); } } @@ -1323,13 +1281,11 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno) return 0; } -static int i7core_get_devices(u8 *sockets) +static int i7core_get_devices(void) { int i; struct pci_dev *pdev = NULL; - struct i7core_dev *i7core_dev = NULL; - *sockets = 0; for (i = 0; i < N_DEVS; i++) { pdev = NULL; do { @@ -1340,55 +1296,48 @@ static int i7core_get_devices(u8 *sockets) } while (pdev); } - list_for_each_entry(i7core_dev, &i7core_edac_list, list) { - if (i7core_dev->socket + 1 > *sockets) - *sockets = i7core_dev->socket + 1; - } - return 0; } -static int mci_bind_devs(struct mem_ctl_info *mci) +static int mci_bind_devs(struct mem_ctl_info *mci, + struct i7core_dev *i7core_dev) { struct i7core_pvt *pvt = mci->pvt_info; struct pci_dev *pdev; - int i, j, func, slot; + int i, func, slot; - for (i = 0; i < pvt->sockets; i++) { - struct i7core_dev *i7core_dev = get_i7core_dev(i); + /* Associates i7core_dev and mci for future usage */ + pvt->i7core_dev = i7core_dev; + i7core_dev->mci = mci; - if (!i7core_dev) + pvt->is_registered = 0; + for (i = 0; i < N_DEVS; i++) { + pdev = i7core_dev->pdev[i]; + if (!pdev) continue; - pvt->is_registered[i] = 0; - for (j = 0; j < N_DEVS; j++) { - pdev = i7core_dev->pdev[j]; - if (!pdev) - continue; - - func = PCI_FUNC(pdev->devfn); - slot = PCI_SLOT(pdev->devfn); - if (slot == 3) { - if (unlikely(func > MAX_MCR_FUNC)) - goto error; - pvt->pci_mcr[i][func] = pdev; - } else if (likely(slot >= 4 && slot < 4 + NUM_CHANS)) { - if (unlikely(func > MAX_CHAN_FUNC)) - goto error; - pvt->pci_ch[i][slot - 4][func] = pdev; - } else if (!slot && !func) - pvt->pci_noncore[i] = pdev; - else + func = PCI_FUNC(pdev->devfn); + slot = PCI_SLOT(pdev->devfn); + if (slot == 3) { + if (unlikely(func > MAX_MCR_FUNC)) + goto error; + pvt->pci_mcr[func] = pdev; + } else if (likely(slot >= 4 && slot < 4 + NUM_CHANS)) { + if (unlikely(func > MAX_CHAN_FUNC)) goto error; + pvt->pci_ch[slot - 4][func] = pdev; + } else if (!slot && !func) + pvt->pci_noncore = pdev; + else + goto error; - debugf0("Associated fn %d.%d, dev = %p, socket %d\n", - PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), - pdev, i); + debugf0("Associated fn %d.%d, dev = %p, socket %d\n", + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), + pdev, i7core_dev->socket); - if (PCI_SLOT(pdev->devfn) == 3 && - PCI_FUNC(pdev->devfn) == 2) - pvt->is_registered[i] = 1; - } + if (PCI_SLOT(pdev->devfn) == 3 && + PCI_FUNC(pdev->devfn) == 2) + pvt->is_registered = 1; } return 0; @@ -1403,17 +1352,17 @@ error: /**************************************************************************** Error check routines ****************************************************************************/ -static void i7core_rdimm_update_csrow(struct mem_ctl_info *mci, int socket, +static void i7core_rdimm_update_csrow(struct mem_ctl_info *mci, int chan, int dimm, int add) { char *msg; struct i7core_pvt *pvt = mci->pvt_info; - int row = pvt->csrow_map[socket][chan][dimm], i; + int row = pvt->csrow_map[chan][dimm], i; for (i = 0; i < add; i++) { msg = kasprintf(GFP_KERNEL, "Corrected error " - "(Socket=%d channel=%d dimm=%d", - socket, chan, dimm); + "(Socket=%d channel=%d dimm=%d)", + pvt->i7core_dev->socket, chan, dimm); edac_mc_handle_fbd_ce(mci, row, 0, msg); kfree (msg); @@ -1421,71 +1370,71 @@ static void i7core_rdimm_update_csrow(struct mem_ctl_info *mci, int socket, } static void i7core_rdimm_update_ce_count(struct mem_ctl_info *mci, - int socket, int chan, int new0, int new1, int new2) + int chan, int new0, int new1, int new2) { struct i7core_pvt *pvt = mci->pvt_info; int add0 = 0, add1 = 0, add2 = 0; /* Updates CE counters if it is not the first time here */ - if (pvt->ce_count_available[socket]) { + if (pvt->ce_count_available) { /* Updates CE counters */ - add2 = new2 - pvt->rdimm_last_ce_count[socket][chan][2]; - add1 = new1 - pvt->rdimm_last_ce_count[socket][chan][1]; - add0 = new0 - pvt->rdimm_last_ce_count[socket][chan][0]; + add2 = new2 - pvt->rdimm_last_ce_count[chan][2]; + add1 = new1 - pvt->rdimm_last_ce_count[chan][1]; + add0 = new0 - pvt->rdimm_last_ce_count[chan][0]; if (add2 < 0) add2 += 0x7fff; - pvt->rdimm_ce_count[socket][chan][2] += add2; + pvt->rdimm_ce_count[chan][2] += add2; if (add1 < 0) add1 += 0x7fff; - pvt->rdimm_ce_count[socket][chan][1] += add1; + pvt->rdimm_ce_count[chan][1] += add1; if (add0 < 0) add0 += 0x7fff; - pvt->rdimm_ce_count[socket][chan][0] += add0; + pvt->rdimm_ce_count[chan][0] += add0; } else - pvt->ce_count_available[socket] = 1; + pvt->ce_count_available = 1; /* Store the new values */ - pvt->rdimm_last_ce_count[socket][chan][2] = new2; - pvt->rdimm_last_ce_count[socket][chan][1] = new1; - pvt->rdimm_last_ce_count[socket][chan][0] = new0; + pvt->rdimm_last_ce_count[chan][2] = new2; + pvt->rdimm_last_ce_count[chan][1] = new1; + pvt->rdimm_last_ce_count[chan][0] = new0; /*updated the edac core */ if (add0 != 0) - i7core_rdimm_update_csrow(mci, socket, chan, 0, add0); + i7core_rdimm_update_csrow(mci, chan, 0, add0); if (add1 != 0) - i7core_rdimm_update_csrow(mci, socket, chan, 1, add1); + i7core_rdimm_update_csrow(mci, chan, 1, add1); if (add2 != 0) - i7core_rdimm_update_csrow(mci, socket, chan, 2, add2); + i7core_rdimm_update_csrow(mci, chan, 2, add2); } -static void i7core_rdimm_check_mc_ecc_err(struct mem_ctl_info *mci, u8 socket) +static void i7core_rdimm_check_mc_ecc_err(struct mem_ctl_info *mci) { struct i7core_pvt *pvt = mci->pvt_info; u32 rcv[3][2]; int i, new0, new1, new2; /*Read DEV 3: FUN 2: MC_COR_ECC_CNT regs directly*/ - pci_read_config_dword(pvt->pci_mcr[socket][2], MC_COR_ECC_CNT_0, + pci_read_config_dword(pvt->pci_mcr[2], MC_COR_ECC_CNT_0, &rcv[0][0]); - pci_read_config_dword(pvt->pci_mcr[socket][2], MC_COR_ECC_CNT_1, + pci_read_config_dword(pvt->pci_mcr[2], MC_COR_ECC_CNT_1, &rcv[0][1]); - pci_read_config_dword(pvt->pci_mcr[socket][2], MC_COR_ECC_CNT_2, + pci_read_config_dword(pvt->pci_mcr[2], MC_COR_ECC_CNT_2, &rcv[1][0]); - pci_read_config_dword(pvt->pci_mcr[socket][2], MC_COR_ECC_CNT_3, + pci_read_config_dword(pvt->pci_mcr[2], MC_COR_ECC_CNT_3, &rcv[1][1]); - pci_read_config_dword(pvt->pci_mcr[socket][2], MC_COR_ECC_CNT_4, + pci_read_config_dword(pvt->pci_mcr[2], MC_COR_ECC_CNT_4, &rcv[2][0]); - pci_read_config_dword(pvt->pci_mcr[socket][2], MC_COR_ECC_CNT_5, + pci_read_config_dword(pvt->pci_mcr[2], MC_COR_ECC_CNT_5, &rcv[2][1]); for (i = 0 ; i < 3; i++) { debugf3("MC_COR_ECC_CNT%d = 0x%x; MC_COR_ECC_CNT%d = 0x%x\n", (i * 2), rcv[i][0], (i * 2) + 1, rcv[i][1]); /*if the channel has 3 dimms*/ - if (pvt->channel[socket][i].dimms > 2) { + if (pvt->channel[i].dimms > 2) { new0 = DIMM_BOT_COR_ERR(rcv[i][0]); new1 = DIMM_TOP_COR_ERR(rcv[i][0]); new2 = DIMM_BOT_COR_ERR(rcv[i][1]); @@ -1497,7 +1446,7 @@ static void i7core_rdimm_check_mc_ecc_err(struct mem_ctl_info *mci, u8 socket) new2 = 0; } - i7core_rdimm_update_ce_count(mci, socket, i, new0, new1, new2); + i7core_rdimm_update_ce_count(mci, i, new0, new1, new2); } } @@ -1507,20 +1456,20 @@ static void i7core_rdimm_check_mc_ecc_err(struct mem_ctl_info *mci, u8 socket) * also available at: * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf */ -static void i7core_udimm_check_mc_ecc_err(struct mem_ctl_info *mci, u8 socket) +static void i7core_udimm_check_mc_ecc_err(struct mem_ctl_info *mci) { struct i7core_pvt *pvt = mci->pvt_info; u32 rcv1, rcv0; int new0, new1, new2; - if (!pvt->pci_mcr[socket][4]) { + if (!pvt->pci_mcr[4]) { debugf0("%s MCR registers not found\n", __func__); return; } /* Corrected test errors */ - pci_read_config_dword(pvt->pci_mcr[socket][4], MC_TEST_ERR_RCV1, &rcv1); - pci_read_config_dword(pvt->pci_mcr[socket][4], MC_TEST_ERR_RCV0, &rcv0); + pci_read_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV1, &rcv1); + pci_read_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV0, &rcv0); /* Store the new values */ new2 = DIMM2_COR_ERR(rcv1); @@ -1528,37 +1477,37 @@ static void i7core_udimm_check_mc_ecc_err(struct mem_ctl_info *mci, u8 socket) new0 = DIMM0_COR_ERR(rcv0); /* Updates CE counters if it is not the first time here */ - if (pvt->ce_count_available[socket]) { + if (pvt->ce_count_available) { /* Updates CE counters */ int add0, add1, add2; - add2 = new2 - pvt->udimm_last_ce_count[socket][2]; - add1 = new1 - pvt->udimm_last_ce_count[socket][1]; - add0 = new0 - pvt->udimm_last_ce_count[socket][0]; + add2 = new2 - pvt->udimm_last_ce_count[2]; + add1 = new1 - pvt->udimm_last_ce_count[1]; + add0 = new0 - pvt->udimm_last_ce_count[0]; if (add2 < 0) add2 += 0x7fff; - pvt->udimm_ce_count[socket][2] += add2; + pvt->udimm_ce_count[2] += add2; if (add1 < 0) add1 += 0x7fff; - pvt->udimm_ce_count[socket][1] += add1; + pvt->udimm_ce_count[1] += add1; if (add0 < 0) add0 += 0x7fff; - pvt->udimm_ce_count[socket][0] += add0; + pvt->udimm_ce_count[0] += add0; if (add0 | add1 | add2) i7core_printk(KERN_ERR, "New Corrected error(s): " "dimm0: +%d, dimm1: +%d, dimm2 +%d\n", add0, add1, add2); } else - pvt->ce_count_available[socket] = 1; + pvt->ce_count_available = 1; /* Store the new values */ - pvt->udimm_last_ce_count[socket][2] = new2; - pvt->udimm_last_ce_count[socket][1] = new1; - pvt->udimm_last_ce_count[socket][0] = new0; + pvt->udimm_last_ce_count[2] = new2; + pvt->udimm_last_ce_count[1] = new1; + pvt->udimm_last_ce_count[0] = new0; } /* @@ -1587,13 +1536,6 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci, u32 syndrome = m->misc >> 32; u32 errnum = find_first_bit(&error, 32); int csrow; -/* FIXME */ -//#ifdef CONFIG_SMP -#if 0 - u32 socket_id = per_cpu(cpu_data, cpu).phys_proc_id; -#else - u32 socket_id = 0; -#endif if (m->mcgstatus & 1) type = "FATAL"; @@ -1655,24 +1597,21 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci, /* FIXME: should convert addr into bank and rank information */ msg = kasprintf(GFP_ATOMIC, - "%s (addr = 0x%08llx, socket=%d, Dimm=%d, Channel=%d, " + "%s (addr = 0x%08llx, cpu=%d, Dimm=%d, Channel=%d, " "syndrome=0x%08x, count=%d, Err=%08llx:%08llx (%s: %s))\n", - type, (long long) m->addr, socket_id, dimm, channel, + type, (long long) m->addr, m->cpu, dimm, channel, syndrome, core_err_cnt, (long long)m->status, (long long)m->misc, optype, err); debugf0("%s", msg); - if (socket_id < NUM_SOCKETS) - csrow = pvt->csrow_map[socket_id][channel][dimm]; - else - csrow = -1; + csrow = pvt->csrow_map[channel][dimm]; /* Call the helper to output message */ if (m->mcgstatus & 1) edac_mc_handle_fbd_ue(mci, csrow, 0, 0 /* FIXME: should be channel here */, msg); - else if (!pvt->is_registered[socket_id]) + else if (!pvt->is_registered) edac_mc_handle_fbd_ce(mci, csrow, 0 /* FIXME: should be channel here */, msg); @@ -1695,12 +1634,14 @@ static void i7core_check_error(struct mem_ctl_info *mci) spin_lock_irqsave(&pvt->mce_lock, flags); if (pvt->mce_count) { m = kmalloc(sizeof(*m) * pvt->mce_count, GFP_ATOMIC); + if (m) { count = pvt->mce_count; memcpy(m, &pvt->mce_entry, sizeof(*m) * count); } pvt->mce_count = 0; } + spin_unlock_irqrestore(&pvt->mce_lock, flags); /* proccess mcelog errors */ @@ -1710,11 +1651,10 @@ static void i7core_check_error(struct mem_ctl_info *mci) kfree(m); /* check memory count errors */ - for (i = 0; i < pvt->sockets; i++) - if (!pvt->is_registered[i]) - i7core_udimm_check_mc_ecc_err(mci, i); - else - i7core_rdimm_check_mc_ecc_err(mci, i); + if (!pvt->is_registered) + i7core_udimm_check_mc_ecc_err(mci); + else + i7core_rdimm_check_mc_ecc_err(mci); } /* @@ -1740,6 +1680,10 @@ static int i7core_mce_check_error(void *priv, struct mce *mce) if (mce->bank != 8) return 0; + /* Only handle if it is the right mc controller */ + if (cpu_data(mce->cpu).phys_proc_id != pvt->i7core_dev->socket) + return 0; + spin_lock_irqsave(&pvt->mce_lock, flags); if (pvt->mce_count < MCE_LOG_LEN) { memcpy(&pvt->mce_entry[pvt->mce_count], mce, sizeof(*mce)); @@ -1755,63 +1699,26 @@ static int i7core_mce_check_error(void *priv, struct mce *mce) return 1; } -/* - * i7core_probe Probe for ONE instance of device to see if it is - * present. - * return: - * 0 for FOUND a device - * < 0 for error code - */ -static int __devinit i7core_probe(struct pci_dev *pdev, - const struct pci_device_id *id) +static int i7core_register_mci(struct i7core_dev *i7core_dev, + int num_channels, int num_csrows) { struct mem_ctl_info *mci; struct i7core_pvt *pvt; - int num_channels = 0; - int num_csrows = 0; int csrow = 0; - int dev_idx = id->driver_data; - int rc, i; - u8 sockets; - - /* - * FIXME: All memory controllers are allocated at the first pass. - */ - if (unlikely(dev_idx >= 1)) - return -EINVAL; - - /* get the pci devices we want to reserve for our use */ - mutex_lock(&i7core_edac_lock); - rc = i7core_get_devices(&sockets); - if (unlikely(rc < 0)) - goto fail0; - - for (i = 0; i < sockets; i++) { - int channels; - int csrows; - - /* Check the number of active and not disabled channels */ - rc = i7core_get_active_channels(i, &channels, &csrows); - if (unlikely(rc < 0)) - goto fail1; - - num_channels += channels; - num_csrows += csrows; - } + int rc; /* allocate a new MC control structure */ mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0); - if (unlikely(!mci)) { - rc = -ENOMEM; - goto fail1; - } + if (unlikely(!mci)) + return -ENOMEM; debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); - mci->dev = &pdev->dev; /* record ptr to the generic device */ + /* record ptr to the generic device */ + mci->dev = &i7core_dev->pdev[0]->dev; + pvt = mci->pvt_info; memset(pvt, 0, sizeof(*pvt)); - pvt->sockets = sockets; mci->mc_idx = 0; /* @@ -1824,21 +1731,21 @@ static int __devinit i7core_probe(struct pci_dev *pdev, mci->edac_cap = EDAC_FLAG_NONE; mci->mod_name = "i7core_edac.c"; mci->mod_ver = I7CORE_REVISION; - mci->ctl_name = i7core_probe_devs[dev_idx].ctl_name; - mci->dev_name = pci_name(pdev); + mci->ctl_name = kasprintf(GFP_KERNEL, "i7 core #%d", + i7core_dev->socket); + mci->dev_name = pci_name(i7core_dev->pdev[0]); mci->ctl_page_to_phys = NULL; mci->mc_driver_sysfs_attributes = i7core_inj_attrs; /* Set the function pointer to an actual operation function */ mci->edac_check = i7core_check_error; /* Store pci devices at mci for faster access */ - rc = mci_bind_devs(mci); + rc = mci_bind_devs(mci, i7core_dev); if (unlikely(rc < 0)) - goto fail2; + goto fail; /* Get dimm basic config */ - for (i = 0; i < sockets; i++) - get_dimm_config(mci, &csrow, i); + get_dimm_config(mci, &csrow); /* add this new MC control structure to EDAC's list of MCs */ if (unlikely(edac_mc_add_mc(mci))) { @@ -1849,11 +1756,12 @@ static int __devinit i7core_probe(struct pci_dev *pdev, */ rc = -EINVAL; - goto fail2; + goto fail; } /* allocating generic PCI control info */ - i7core_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR); + i7core_pci = edac_pci_create_generic_ctl(&i7core_dev->pdev[0]->dev, + EDAC_MOD_STR); if (unlikely(!i7core_pci)) { printk(KERN_WARNING "%s(): Unable to create PCI control\n", @@ -1880,7 +1788,50 @@ static int __devinit i7core_probe(struct pci_dev *pdev, if (unlikely(rc < 0)) { debugf0("MC: " __FILE__ ": %s(): failed edac_mce_register()\n", __func__); - goto fail2; + } + +fail: + edac_mc_free(mci); + return rc; +} + +/* + * i7core_probe Probe for ONE instance of device to see if it is + * present. + * return: + * 0 for FOUND a device + * < 0 for error code + */ +static int __devinit i7core_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + int dev_idx = id->driver_data; + int rc; + struct i7core_dev *i7core_dev; + + /* + * FIXME: All memory controllers are allocated at the first pass. + */ + if (unlikely(dev_idx >= 1)) + return -EINVAL; + + /* get the pci devices we want to reserve for our use */ + mutex_lock(&i7core_edac_lock); + rc = i7core_get_devices(); + if (unlikely(rc < 0)) + goto fail0; + + list_for_each_entry(i7core_dev, &i7core_edac_list, list) { + int channels; + int csrows; + + /* Check the number of active and not disabled channels */ + rc = i7core_get_active_channels(i7core_dev->socket, + &channels, &csrows); + if (unlikely(rc < 0)) + goto fail1; + + i7core_register_mci(i7core_dev, channels, csrows); } i7core_printk(KERN_INFO, "Driver loaded.\n"); @@ -1888,9 +1839,6 @@ static int __devinit i7core_probe(struct pci_dev *pdev, mutex_unlock(&i7core_edac_lock); return 0; -fail2: - edac_mc_free(mci); - fail1: i7core_put_devices(); fail0: @@ -1926,6 +1874,7 @@ static void __devexit i7core_remove(struct pci_dev *pdev) i7core_put_devices(); mutex_unlock(&i7core_edac_lock); + kfree(mci->ctl_name); edac_mc_free(mci); } -- cgit v1.2.3 From 6c6aa3afdba2460cb668d4cb65c74dfa8eb43449 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 5 Sep 2009 03:27:04 -0300 Subject: i7core_edac: sanity check: print a warning if a mcelog is ignored In thesis, the other mc controller should handle it. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 5bc316b8e805..335d9ed02c45 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1681,8 +1681,13 @@ static int i7core_mce_check_error(void *priv, struct mce *mce) return 0; /* Only handle if it is the right mc controller */ - if (cpu_data(mce->cpu).phys_proc_id != pvt->i7core_dev->socket) + if (cpu_data(mce->cpu).phys_proc_id != pvt->i7core_dev->socket) { + debugf0("mc%d: ignoring mce log for socket %d. " + "Another mc should get it.\n", + pvt->i7core_dev->socket, + cpu_data(mce->cpu).phys_proc_id); return 0; + } spin_lock_irqsave(&pvt->mce_lock, flags); if (pvt->mce_count < MCE_LOG_LEN) { -- cgit v1.2.3 From d4c277957f4e8e6f2b626e2661cbbf9c76782e36 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 5 Sep 2009 04:12:02 -0300 Subject: i7core_edac: a few fixes for multiple mc's Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 335d9ed02c45..2c30493eae0f 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1270,11 +1270,10 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno) return -ENODEV; } - i7core_printk(KERN_INFO, - "Registered socket %d " - "dev %02x:%02x.%d PCI ID %04x:%04x\n", - socket, bus, pci_dev_descr[devno].dev, pci_dev_descr[devno].func, - PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id); + debugf0("Detected socket %d dev %02x:%02x.%d PCI ID %04x:%04x\n", + socket, bus, pci_dev_descr[devno].dev, + pci_dev_descr[devno].func, + PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id); *prev = pdev; @@ -1713,7 +1712,8 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev, int rc; /* allocate a new MC control structure */ - mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0); + mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, + i7core_dev->socket); if (unlikely(!mci)) return -ENOMEM; @@ -1724,7 +1724,6 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev, pvt = mci->pvt_info; memset(pvt, 0, sizeof(*pvt)); - mci->mc_idx = 0; /* * FIXME: how to handle RDDR3 at MCI level? It is possible to have @@ -1815,7 +1814,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, struct i7core_dev *i7core_dev; /* - * FIXME: All memory controllers are allocated at the first pass. + * All memory controllers are allocated at the first pass. */ if (unlikely(dev_idx >= 1)) return -EINVAL; @@ -1836,7 +1835,9 @@ static int __devinit i7core_probe(struct pci_dev *pdev, if (unlikely(rc < 0)) goto fail1; - i7core_register_mci(i7core_dev, channels, csrows); + rc = i7core_register_mci(i7core_dev, channels, csrows); + if (unlikely(rc < 0)) + goto fail1; } i7core_printk(KERN_INFO, "Driver loaded.\n"); @@ -1876,6 +1877,8 @@ static void __devexit i7core_remove(struct pci_dev *pdev) /* retrieve references to resources, and free those resources */ mutex_lock(&i7core_edac_lock); + + /* FIXME: This should put the devices only for this mci!!! */ i7core_put_devices(); mutex_unlock(&i7core_edac_lock); -- cgit v1.2.3 From d88b85072fa7d406f54c30ceeabcd37e5a2ec21a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 5 Sep 2009 05:10:31 -0300 Subject: i7core_edac: Fix a bug when printing error counts with RDIMMs Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 2c30493eae0f..821e8a1a09cf 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1054,13 +1054,15 @@ static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data) count = sprintf(data, "data unavailable\n"); return 0; } - if (!pvt->is_registered) + if (!pvt->is_registered) { count = sprintf(data, "all channels " "UDIMM0: %lu UDIMM1: %lu UDIMM2: %lu\n", pvt->udimm_ce_count[0], pvt->udimm_ce_count[1], pvt->udimm_ce_count[2]); - else + data += count; + total += count; + } else { for (i = 0; i < NUM_CHANS; i++) { count = sprintf(data, "channel %d RDIMM0: %lu " "RDIMM1: %lu RDIMM2: %lu\n", @@ -1068,9 +1070,10 @@ static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data) pvt->rdimm_ce_count[i][0], pvt->rdimm_ce_count[i][1], pvt->rdimm_ce_count[i][2]); - } - data += count; - total += count; + data += count; + total += count; + } + } return total; } -- cgit v1.2.3 From 13d6e9b653e6f714024c67287c7d7eac54d8417b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 5 Sep 2009 12:15:20 -0300 Subject: i7core_edac: at remove, don't remove all pci devices at once Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 821e8a1a09cf..c2266f820b0f 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1135,22 +1135,24 @@ static struct mcidev_sysfs_attribute i7core_inj_attrs[] = { * i7core_put_devices 'put' all the devices that we have * reserved via 'get' */ -static void i7core_put_devices(void) +static void i7core_put_devices(struct i7core_dev *i7core_dev) { - int i, j; + int i; - for (i = 0; i < max_num_sockets; i++) { - struct i7core_dev *i7core_dev = get_i7core_dev(i); - if (!i7core_dev) - continue; + for (i = 0; i < N_DEVS; i++) + pci_dev_put(i7core_dev->pdev[i]); - for (j = 0; j < N_DEVS; j++) - pci_dev_put(i7core_dev->pdev[j]); + list_del(&i7core_dev->list); + kfree(i7core_dev->pdev); + kfree(i7core_dev); +} - list_del(&i7core_dev->list); - kfree(i7core_dev->pdev); - kfree(i7core_dev); - } +static void i7core_put_all_devices(void) +{ + struct i7core_dev *i7core_dev; + + list_for_each_entry(i7core_dev, &i7core_edac_list, list) + i7core_put_devices(i7core_dev); } static void i7core_xeon_pci_fixup(void) @@ -1292,7 +1294,7 @@ static int i7core_get_devices(void) pdev = NULL; do { if (i7core_get_onedevice(&pdev, i) < 0) { - i7core_put_devices(); + i7core_put_all_devices(); return -ENODEV; } } while (pdev); @@ -1849,7 +1851,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, return 0; fail1: - i7core_put_devices(); + i7core_put_all_devices(); fail0: mutex_unlock(&i7core_edac_lock); return rc; @@ -1863,6 +1865,7 @@ static void __devexit i7core_remove(struct pci_dev *pdev) { struct mem_ctl_info *mci; struct i7core_pvt *pvt; + struct i7core_dev *i7core_dev; debugf0(__FILE__ ": %s()\n", __func__); @@ -1876,13 +1879,12 @@ static void __devexit i7core_remove(struct pci_dev *pdev) /* Unregisters on edac_mce in order to receive memory errors */ pvt = mci->pvt_info; + i7core_dev = pvt->i7core_dev; edac_mce_unregister(&pvt->edac_mce); /* retrieve references to resources, and free those resources */ mutex_lock(&i7core_edac_lock); - - /* FIXME: This should put the devices only for this mci!!! */ - i7core_put_devices(); + i7core_put_devices(i7core_dev); mutex_unlock(&i7core_edac_lock); kfree(mci->ctl_name); -- cgit v1.2.3 From 0f062792b48dc8389fb18cbfb9318625886644c7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 5 Sep 2009 12:16:19 -0300 Subject: i7core_edac: remove static counter for max sockets The number of sockets is now fully dynamic. Get rid of this obsolete var. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index c2266f820b0f..391348bf93d2 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -247,7 +247,6 @@ struct i7core_pvt { /* Static vars */ static LIST_HEAD(i7core_edac_list); static DEFINE_MUTEX(i7core_edac_lock); -static u8 max_num_sockets; #define PCI_DESCR(device, function, device_id) \ .dev = (device), \ -- cgit v1.2.3 From 22e6bcbdcf9279321dbe646c5a234b816db12881 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 5 Sep 2009 23:06:50 -0300 Subject: i7core_edac: change remove module strategy The old remove module stragegy didn't work on devices with multiple cores, since only one PCI device is used to open all mc's, due to Nehalem nature. Also, it were based at pdev value. However, this doesn't point to the pci device used at mci->dev. So, instead, it unregisters all devices at once, deleting them from the device list. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 55 +++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 391348bf93d2..c3fec5de3e51 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1138,11 +1138,18 @@ static void i7core_put_devices(struct i7core_dev *i7core_dev) { int i; - for (i = 0; i < N_DEVS; i++) - pci_dev_put(i7core_dev->pdev[i]); - - list_del(&i7core_dev->list); + debugf0(__FILE__ ": %s()\n", __func__); + for (i = 0; i < N_DEVS; i++) { + struct pci_dev *pdev = i7core_dev->pdev[i]; + if (!pdev) + continue; + debugf0("Removing dev %02x:%02x.%d\n", + pdev->bus->number, + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); + pci_dev_put(pdev); + } kfree(i7core_dev->pdev); + list_del(&i7core_dev->list); kfree(i7core_dev); } @@ -1863,31 +1870,39 @@ fail0: static void __devexit i7core_remove(struct pci_dev *pdev) { struct mem_ctl_info *mci; - struct i7core_pvt *pvt; - struct i7core_dev *i7core_dev; + struct i7core_dev *i7core_dev, *tmp; debugf0(__FILE__ ": %s()\n", __func__); if (i7core_pci) edac_pci_release_generic_ctl(i7core_pci); + /* + * we have a trouble here: pdev value for removal will be wrong, since + * it will point to the X58 register used to detect that the machine + * is a Nehalem or upper design. However, due to the way several PCI + * devices are grouped together to provide MC functionality, we need + * to use a different method for releasing the devices + */ - mci = edac_mc_del_mc(&pdev->dev); - if (!mci) - return; - - /* Unregisters on edac_mce in order to receive memory errors */ - pvt = mci->pvt_info; - i7core_dev = pvt->i7core_dev; - edac_mce_unregister(&pvt->edac_mce); - - /* retrieve references to resources, and free those resources */ mutex_lock(&i7core_edac_lock); - i7core_put_devices(i7core_dev); + list_for_each_entry_safe(i7core_dev, tmp, &i7core_edac_list, list) { + mci = edac_mc_del_mc(&i7core_dev->pdev[0]->dev); + if (mci) { + struct i7core_pvt *pvt = mci->pvt_info; + + i7core_dev = pvt->i7core_dev; + edac_mce_unregister(&pvt->edac_mce); + kfree(mci->ctl_name); + edac_mc_free(mci); + i7core_put_devices(i7core_dev); + } else { + i7core_printk(KERN_ERR, + "Couldn't find mci for socket %d\n", + i7core_dev->socket); + } + } mutex_unlock(&i7core_edac_lock); - - kfree(mci->ctl_name); - edac_mc_free(mci); } MODULE_DEVICE_TABLE(pci, i7core_pci_tbl); -- cgit v1.2.3 From 4253868034221db6e42dbbb61e0305fe1757f8da Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 24 Sep 2009 09:59:13 -0300 Subject: i7core_edac: We need to use list_for_each_entry_safe to avoid errors Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index c3fec5de3e51..2e4b0abf9d43 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1124,6 +1124,7 @@ static struct mcidev_sysfs_attribute i7core_inj_attrs[] = { .show = i7core_ce_regs_show, .store = NULL, }, + { .attr = { .name = NULL } } }; /**************************************************************************** @@ -1155,9 +1156,9 @@ static void i7core_put_devices(struct i7core_dev *i7core_dev) static void i7core_put_all_devices(void) { - struct i7core_dev *i7core_dev; + struct i7core_dev *i7core_dev, *tmp; - list_for_each_entry(i7core_dev, &i7core_edac_list, list) + list_for_each_entry_safe(i7core_dev, tmp, &i7core_edac_list, list) i7core_put_devices(i7core_dev); } -- cgit v1.2.3 From 4af91889e02c9933823ca8c62fc6f05dfd15f3bd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 24 Sep 2009 09:58:26 -0300 Subject: i7core_edac: Avoid printing a warning when debug is disabled Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 2e4b0abf9d43..0478cc85e920 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -471,7 +471,6 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow) struct csrow_info *csr; struct pci_dev *pdev; int i, j; - u8 socket = pvt->i7core_dev->socket; unsigned long last_page = 0; enum edac_type mode; enum mem_type mtype; @@ -488,7 +487,7 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow) pci_read_config_dword(pdev, MC_CHANNEL_MAPPER, &pvt->info.ch_map); debugf0("QPI %d control=0x%08x status=0x%08x dod=0x%08x map=0x%08x\n", - socket, pvt->info.mc_control, pvt->info.mc_status, + pvt->i7core_dev->socket, pvt->info.mc_control, pvt->info.mc_status, pvt->info.max_dod, pvt->info.ch_map); if (ECC_ENABLED(pvt)) { -- cgit v1.2.3 From 9fa2fc2e2d641df7d69dc4e06cf2552c44b58e95 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 23 Sep 2009 16:26:09 -0300 Subject: edac_core: Allow the creation of sysfs groups Currently, all sysfs nodes are stored at /sys/.*/mc. (regex) However, sometimes it is needed to create attribute groups. This patch extends edac_core to allow groups creation. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/edac_core.h | 12 ++++++- drivers/edac/edac_mc_sysfs.c | 83 ++++++++++++++++++++++++++++++-------------- 2 files changed, 67 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h index 001b2e797fb3..97071ff1d22d 100644 --- a/drivers/edac/edac_core.h +++ b/drivers/edac/edac_core.h @@ -341,12 +341,22 @@ struct csrow_info { struct channel_info *channels; }; +struct mcidev_sysfs_group { + const char *name; + struct mcidev_sysfs_attribute *mcidev_attr; + struct kobject kobj; +}; + + /* mcidev_sysfs_attribute structure * used for driver sysfs attributes and in mem_ctl_info * sysfs top level entries */ struct mcidev_sysfs_attribute { - struct attribute attr; + struct attribute attr; + + struct mcidev_sysfs_group *grp; + ssize_t (*show)(struct mem_ctl_info *,char *); ssize_t (*store)(struct mem_ctl_info *, const char *,size_t); }; diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index 418b65f1a1da..655aa1a1f4f9 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c @@ -728,26 +728,43 @@ void edac_mc_unregister_sysfs_main_kobj(struct mem_ctl_info *mci) /* * edac_create_mci_instance_attributes - * create MC driver specific attributes at the topmost level - * directory of this mci instance. + * create MC driver specific attributes bellow an specified kobj + * This routine calls itself recursively, in order to create an entire + * object tree. */ -static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci) +static int edac_create_mci_instance_attributes( + struct mcidev_sysfs_attribute *sysfs_attrib, + struct kobject *kobj) { int err; - struct mcidev_sysfs_attribute *sysfs_attrib; - /* point to the start of the array and iterate over it - * adding each attribute listed to this mci instance's kobject - */ - sysfs_attrib = mci->mc_driver_sysfs_attributes; + while (sysfs_attrib) { + if (sysfs_attrib->grp) { + struct kobject *newkobj = &sysfs_attrib->grp->kobj; + debugf0("%s() grp %s\n", __func__, + sysfs_attrib->grp->name); + + err = kobject_init_and_add(newkobj, NULL, + kobj, + sysfs_attrib->grp->name); + if (err) + return err; + + err = edac_create_mci_instance_attributes( + sysfs_attrib->grp->mcidev_attr, newkobj); + if (err) + return err; + } else if (sysfs_attrib->attr.name) { + debugf0("%s() file %s\n", __func__, + sysfs_attrib->attr.name); + + err = sysfs_create_file(kobj, &sysfs_attrib->attr); + } else + break; - while (sysfs_attrib && sysfs_attrib->attr.name) { - err = sysfs_create_file(&mci->edac_mci_kobj, - (struct attribute*) sysfs_attrib); if (err) { return err; } - sysfs_attrib++; } @@ -759,19 +776,28 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci) * remove MC driver specific attributes at the topmost level * directory of this mci instance. */ -static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci) +static void edac_remove_mci_instance_attributes( + struct mcidev_sysfs_attribute *sysfs_attrib, + struct kobject *kobj) { - struct mcidev_sysfs_attribute *sysfs_attrib; - - /* point to the start of the array and iterate over it - * adding each attribute listed to this mci instance's kobject - */ - sysfs_attrib = mci->mc_driver_sysfs_attributes; - /* loop if there are attributes and until we hit a NULL entry */ - while (sysfs_attrib && sysfs_attrib->attr.name) { - sysfs_remove_file(&mci->edac_mci_kobj, - (struct attribute *) sysfs_attrib); + while (sysfs_attrib) { + if (sysfs_attrib->grp) { + struct kobject *newkobj = &sysfs_attrib->grp->kobj; + + debugf0("%s() grp %s\n", __func__, + sysfs_attrib->grp->name); + + edac_remove_mci_instance_attributes( + sysfs_attrib->grp->mcidev_attr, newkobj); + + kobject_put(newkobj); + } else if (sysfs_attrib->attr.name) { + debugf0("%s() file %s\n", __func__, + sysfs_attrib->attr.name); + sysfs_remove_file(kobj, &sysfs_attrib->attr); + } else + break; sysfs_attrib++; } } @@ -806,7 +832,9 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) * then create them now for the driver. */ if (mci->mc_driver_sysfs_attributes) { - err = edac_create_mci_instance_attributes(mci); + err = edac_create_mci_instance_attributes( + mci->mc_driver_sysfs_attributes, + &mci->edac_mci_kobj); if (err) { debugf1("%s() failure to create mci attributes\n", __func__); @@ -841,7 +869,8 @@ fail1: } /* remove the mci instance's attributes, if any */ - edac_remove_mci_instance_attributes(mci); + edac_remove_mci_instance_attributes( + mci->mc_driver_sysfs_attributes, &mci->edac_mci_kobj); /* remove the symlink */ sysfs_remove_link(kobj_mci, EDAC_DEVICE_SYMLINK); @@ -875,8 +904,8 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) debugf0("%s() remove_mci_instance\n", __func__); /* remove this mci instance's attribtes */ - edac_remove_mci_instance_attributes(mci); - + edac_remove_mci_instance_attributes(mci->mc_driver_sysfs_attributes, + &mci->edac_mci_kobj); debugf0("%s() unregister this mci kobj\n", __func__); /* unregister this instance's kobject */ -- cgit v1.2.3 From a5538e531fc1e00ac7185dcfcebf33c37b5d742e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 23 Sep 2009 18:56:47 -0300 Subject: i7core_edac: Add support for sysfs addrmatch group Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 173 ++++++++++++++++++--------------------------- 1 file changed, 70 insertions(+), 103 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 0478cc85e920..afa5281e8df9 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -778,105 +778,59 @@ static ssize_t i7core_inject_eccmask_show(struct mem_ctl_info *mci, * 23:16 and 31:24). Flipping bits in two symbol pairs will cause an * uncorrectable error to be injected. */ -static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci, - const char *data, size_t count) -{ - struct i7core_pvt *pvt = mci->pvt_info; - char *cmd, *val; - long value; - int rc; - - if (pvt->inject.enable) - disable_inject(mci); - - do { - cmd = strsep((char **) &data, ":"); - if (!cmd) - break; - val = strsep((char **) &data, " \n\t"); - if (!val) - return cmd - data; - - if (!strcasecmp(val, "any")) - value = -1; - else { - rc = strict_strtol(val, 10, &value); - if ((rc < 0) || (value < 0)) - return cmd - data; - } - - if (!strcasecmp(cmd, "channel")) { - if (value < 3) - pvt->inject.channel = value; - else - return cmd - data; - } else if (!strcasecmp(cmd, "dimm")) { - if (value < 3) - pvt->inject.dimm = value; - else - return cmd - data; - } else if (!strcasecmp(cmd, "rank")) { - if (value < 4) - pvt->inject.rank = value; - else - return cmd - data; - } else if (!strcasecmp(cmd, "bank")) { - if (value < 32) - pvt->inject.bank = value; - else - return cmd - data; - } else if (!strcasecmp(cmd, "page")) { - if (value <= 0xffff) - pvt->inject.page = value; - else - return cmd - data; - } else if (!strcasecmp(cmd, "col") || - !strcasecmp(cmd, "column")) { - if (value <= 0x3fff) - pvt->inject.col = value; - else - return cmd - data; - } - } while (1); - return count; +#define DECLARE_ADDR_MATCH(param, limit) \ +static ssize_t i7core_inject_store_##param( \ + struct mem_ctl_info *mci, \ + const char *data, size_t count) \ +{ \ + struct i7core_pvt *pvt = mci->pvt_info; \ + long value; \ + int rc; \ + \ + if (pvt->inject.enable) \ + disable_inject(mci); \ + \ + if (!strcasecmp(data, "any")) \ + value = -1; \ + else { \ + rc = strict_strtoul(data, 10, &value); \ + if ((rc < 0) || (value >= limit)) \ + return -EIO; \ + } \ + \ + pvt->inject.param = value; \ + \ + return count; \ +} \ + \ +static ssize_t i7core_inject_show_##param( \ + struct mem_ctl_info *mci, \ + char *data) \ +{ \ + struct i7core_pvt *pvt = mci->pvt_info; \ + if (pvt->inject.param < 0) \ + return sprintf(data, "any\n"); \ + else \ + return sprintf(data, "%d\n", pvt->inject.param);\ } -static ssize_t i7core_inject_addrmatch_show(struct mem_ctl_info *mci, - char *data) -{ - struct i7core_pvt *pvt = mci->pvt_info; - char channel[4], dimm[4], bank[4], rank[4], page[7], col[7]; - - if (pvt->inject.channel < 0) - sprintf(channel, "any"); - else - sprintf(channel, "%d", pvt->inject.channel); - if (pvt->inject.dimm < 0) - sprintf(dimm, "any"); - else - sprintf(dimm, "%d", pvt->inject.dimm); - if (pvt->inject.bank < 0) - sprintf(bank, "any"); - else - sprintf(bank, "%d", pvt->inject.bank); - if (pvt->inject.rank < 0) - sprintf(rank, "any"); - else - sprintf(rank, "%d", pvt->inject.rank); - if (pvt->inject.page < 0) - sprintf(page, "any"); - else - sprintf(page, "0x%04x", pvt->inject.page); - if (pvt->inject.col < 0) - sprintf(col, "any"); - else - sprintf(col, "0x%04x", pvt->inject.col); +#define ATTR_ADDR_MATCH(param) \ + { \ + .attr = { \ + .name = #param, \ + .mode = (S_IRUGO | S_IWUSR) \ + }, \ + .show = i7core_inject_show_##param, \ + .store = i7core_inject_store_##param, \ + } - return sprintf(data, "channel: %s\ndimm: %s\nbank: %s\n" - "rank: %s\npage: %s\ncolumn: %s\n", - channel, dimm, bank, rank, page, col); -} +DECLARE_ADDR_MATCH(channel, 3); +DECLARE_ADDR_MATCH(dimm, 3); +DECLARE_ADDR_MATCH(rank, 4); +DECLARE_ADDR_MATCH(bank, 32); +DECLARE_ADDR_MATCH(page, 0x10000); +DECLARE_ADDR_MATCH(col, 0x4000); static int write_and_test(struct pci_dev *dev, int where, u32 val) { @@ -1079,7 +1033,25 @@ static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data) /* * Sysfs struct */ -static struct mcidev_sysfs_attribute i7core_inj_attrs[] = { + + +static struct mcidev_sysfs_attribute i7core_addrmatch_attrs[] = { + ATTR_ADDR_MATCH(channel), + ATTR_ADDR_MATCH(dimm), + ATTR_ADDR_MATCH(rank), + ATTR_ADDR_MATCH(bank), + ATTR_ADDR_MATCH(page), + ATTR_ADDR_MATCH(col), + { .attr = { .name = NULL } } +}; + + +static struct mcidev_sysfs_group i7core_inject_addrmatch = { + .name = "inject_addrmatch", + .mcidev_attr = i7core_addrmatch_attrs, +}; + +static struct mcidev_sysfs_attribute i7core_sysfs_attrs[] = { { .attr = { .name = "inject_section", @@ -1102,12 +1074,7 @@ static struct mcidev_sysfs_attribute i7core_inj_attrs[] = { .show = i7core_inject_eccmask_show, .store = i7core_inject_eccmask_store, }, { - .attr = { - .name = "inject_addrmatch", - .mode = (S_IRUGO | S_IWUSR) - }, - .show = i7core_inject_addrmatch_show, - .store = i7core_inject_addrmatch_store, + .grp = &i7core_inject_addrmatch, }, { .attr = { .name = "inject_enable", @@ -1750,7 +1717,7 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev, i7core_dev->socket); mci->dev_name = pci_name(i7core_dev->pdev[0]); mci->ctl_page_to_phys = NULL; - mci->mc_driver_sysfs_attributes = i7core_inj_attrs; + mci->mc_driver_sysfs_attributes = i7core_sysfs_attrs; /* Set the function pointer to an actual operation function */ mci->edac_check = i7core_check_error; -- cgit v1.2.3 From cc301b3ae3f615fe243f023e68e22b8298a6f883 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 24 Sep 2009 16:23:42 -0300 Subject: edac: store/show methods for device groups weren't working Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/edac_core.h | 2 ++ drivers/edac/edac_mc_sysfs.c | 85 ++++++++++++++++++++++++++++++++++++++++---- drivers/edac/i7core_edac.c | 10 ++++-- 3 files changed, 88 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h index 97071ff1d22d..02bbbc9696d9 100644 --- a/drivers/edac/edac_core.h +++ b/drivers/edac/edac_core.h @@ -345,6 +345,8 @@ struct mcidev_sysfs_group { const char *name; struct mcidev_sysfs_attribute *mcidev_attr; struct kobject kobj; + + struct mem_ctl_info *mci; /* the parent */ }; diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index 655aa1a1f4f9..6088ae6e8ea5 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c @@ -557,6 +557,8 @@ static ssize_t mcidev_show(struct kobject *kobj, struct attribute *attr, struct mem_ctl_info *mem_ctl_info = to_mci(kobj); struct mcidev_sysfs_attribute *mcidev_attr = to_mcidev_attr(attr); + debugf1("%s() mem_ctl_info %p\n", __func__, mem_ctl_info); + if (mcidev_attr->show) return mcidev_attr->show(mem_ctl_info, buffer); @@ -569,6 +571,8 @@ static ssize_t mcidev_store(struct kobject *kobj, struct attribute *attr, struct mem_ctl_info *mem_ctl_info = to_mci(kobj); struct mcidev_sysfs_attribute *mcidev_attr = to_mcidev_attr(attr); + debugf1("%s() mem_ctl_info %p\n", __func__, mem_ctl_info); + if (mcidev_attr->store) return mcidev_attr->store(mem_ctl_info, buffer, count); @@ -726,32 +730,97 @@ void edac_mc_unregister_sysfs_main_kobj(struct mem_ctl_info *mci) #define EDAC_DEVICE_SYMLINK "device" +#define grp_to_mci(k) (container_of(k, struct mcidev_sysfs_group, kobj)->mci) + +/* MCI show/store functions for top most object */ +static ssize_t inst_grp_show(struct kobject *kobj, struct attribute *attr, + char *buffer) +{ + struct mem_ctl_info *mem_ctl_info = grp_to_mci(kobj); + struct mcidev_sysfs_attribute *mcidev_attr = to_mcidev_attr(attr); + + debugf1("%s() mem_ctl_info %p\n", __func__, mem_ctl_info); + + if (mcidev_attr->show) + return mcidev_attr->show(mem_ctl_info, buffer); + + return -EIO; +} + +static ssize_t inst_grp_store(struct kobject *kobj, struct attribute *attr, + const char *buffer, size_t count) +{ + struct mem_ctl_info *mem_ctl_info = grp_to_mci(kobj); + struct mcidev_sysfs_attribute *mcidev_attr = to_mcidev_attr(attr); + + debugf1("%s() mem_ctl_info %p\n", __func__, mem_ctl_info); + + if (mcidev_attr->store) + return mcidev_attr->store(mem_ctl_info, buffer, count); + + return -EIO; +} + +/* No memory to release for this kobj */ +static void edac_inst_grp_release(struct kobject *kobj) +{ + struct mcidev_sysfs_group *grp; + struct mem_ctl_info *mci; + + debugf1("%s()\n", __func__); + + grp = container_of(kobj, struct mcidev_sysfs_group, kobj); + mci = grp->mci; + + kobject_put(&mci->edac_mci_kobj); +} + +/* Intermediate show/store table */ +static struct sysfs_ops inst_grp_ops = { + .show = inst_grp_show, + .store = inst_grp_store +}; + +/* the kobj_type instance for a instance group */ +static struct kobj_type ktype_inst_grp = { + .release = edac_inst_grp_release, + .sysfs_ops = &inst_grp_ops, + .default_attrs = (struct attribute **)default_csrow_attr, +}; + + /* * edac_create_mci_instance_attributes * create MC driver specific attributes bellow an specified kobj * This routine calls itself recursively, in order to create an entire * object tree. */ -static int edac_create_mci_instance_attributes( +static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci, struct mcidev_sysfs_attribute *sysfs_attrib, struct kobject *kobj) { int err; + debugf1("%s()\n", __func__); + while (sysfs_attrib) { if (sysfs_attrib->grp) { struct kobject *newkobj = &sysfs_attrib->grp->kobj; - debugf0("%s() grp %s\n", __func__, - sysfs_attrib->grp->name); + debugf0("%s() grp %s, mci %p\n", __func__, + sysfs_attrib->grp->name, mci); + + sysfs_attrib->grp->mci = mci; - err = kobject_init_and_add(newkobj, NULL, + err = kobject_init_and_add(newkobj, &ktype_inst_grp, kobj, sysfs_attrib->grp->name); if (err) return err; - err = edac_create_mci_instance_attributes( - sysfs_attrib->grp->mcidev_attr, newkobj); + err = edac_create_mci_instance_attributes(mci, + sysfs_attrib->grp->mcidev_attr, + newkobj); + if (err) return err; } else if (sysfs_attrib->attr.name) { @@ -780,6 +849,8 @@ static void edac_remove_mci_instance_attributes( struct mcidev_sysfs_attribute *sysfs_attrib, struct kobject *kobj) { + debugf1("%s()\n", __func__); + /* loop if there are attributes and until we hit a NULL entry */ while (sysfs_attrib) { if (sysfs_attrib->grp) { @@ -832,7 +903,7 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) * then create them now for the driver. */ if (mci->mc_driver_sysfs_attributes) { - err = edac_create_mci_instance_attributes( + err = edac_create_mci_instance_attributes(mci, mci->mc_driver_sysfs_attributes, &mci->edac_mci_kobj); if (err) { diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index afa5281e8df9..e013004745de 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -784,10 +784,13 @@ static ssize_t i7core_inject_store_##param( \ struct mem_ctl_info *mci, \ const char *data, size_t count) \ { \ - struct i7core_pvt *pvt = mci->pvt_info; \ + struct i7core_pvt *pvt; \ long value; \ int rc; \ \ + debugf1("%s()\n", __func__); \ + pvt = mci->pvt_info; \ + \ if (pvt->inject.enable) \ disable_inject(mci); \ \ @@ -808,7 +811,10 @@ static ssize_t i7core_inject_show_##param( \ struct mem_ctl_info *mci, \ char *data) \ { \ - struct i7core_pvt *pvt = mci->pvt_info; \ + struct i7core_pvt *pvt; \ + \ + pvt = mci->pvt_info; \ + debugf1("%s() pvt=%p\n", __func__, pvt); \ if (pvt->inject.param < 0) \ return sprintf(data, "any\n"); \ else \ -- cgit v1.2.3 From c419d921e68c54232ce6d369a3b528cd7644b2ae Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 24 Sep 2009 16:36:32 -0300 Subject: edac: Don't create csrow entries on instance groups Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/edac_mc_sysfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index 6088ae6e8ea5..f689d7d6ab46 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c @@ -785,7 +785,6 @@ static struct sysfs_ops inst_grp_ops = { static struct kobj_type ktype_inst_grp = { .release = edac_inst_grp_release, .sysfs_ops = &inst_grp_ops, - .default_attrs = (struct attribute **)default_csrow_attr, }; @@ -806,13 +805,14 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci, while (sysfs_attrib) { if (sysfs_attrib->grp) { struct kobject *newkobj = &sysfs_attrib->grp->kobj; + debugf0("%s() grp %s, mci %p\n", __func__, sysfs_attrib->grp->name, mci); sysfs_attrib->grp->mci = mci; err = kobject_init_and_add(newkobj, &ktype_inst_grp, - kobj, + &mci->edac_mci_kobj, sysfs_attrib->grp->name); if (err) return err; -- cgit v1.2.3 From f338d736910edf00e8426ee4322cfda585268d50 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 24 Sep 2009 17:25:43 -0300 Subject: i7core_edac: Convert UDIMM error counters into a proper sysfs group Instead of displaying 3 values at the same var, break it into 3 different sysfs nodes: /sys/devices/system/edac/mc/mc0/all_channel_counts/udimm0 /sys/devices/system/edac/mc/mc0/all_channel_counts/udimm1 /sys/devices/system/edac/mc/mc0/all_channel_counts/udimm2 For registered dimms, however, the error counters are already being displayed at: /sys/devices/system/edac/mc/mc0/csrow*/ce_count So, there's no need to add any extra sysfs nodes. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 81 +++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index e013004745de..97f6d1759c99 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1003,38 +1003,32 @@ static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci, return sprintf(data, "%d\n", pvt->inject.enable); } -static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data) -{ - unsigned i, count, total = 0; - struct i7core_pvt *pvt = mci->pvt_info; +#define DECLARE_COUNTER(param) \ +static ssize_t i7core_show_counter_##param( \ + struct mem_ctl_info *mci, \ + char *data) \ +{ \ + struct i7core_pvt *pvt = mci->pvt_info; \ + \ + debugf1("%s() \n", __func__); \ + if (!pvt->ce_count_available || (pvt->is_registered)) \ + return sprintf(data, "data unavailable\n"); \ + return sprintf(data, "%lu\n", \ + pvt->udimm_ce_count[param]); \ +} - if (!pvt->ce_count_available) { - count = sprintf(data, "data unavailable\n"); - return 0; - } - if (!pvt->is_registered) { - count = sprintf(data, "all channels " - "UDIMM0: %lu UDIMM1: %lu UDIMM2: %lu\n", - pvt->udimm_ce_count[0], - pvt->udimm_ce_count[1], - pvt->udimm_ce_count[2]); - data += count; - total += count; - } else { - for (i = 0; i < NUM_CHANS; i++) { - count = sprintf(data, "channel %d RDIMM0: %lu " - "RDIMM1: %lu RDIMM2: %lu\n", - i, - pvt->rdimm_ce_count[i][0], - pvt->rdimm_ce_count[i][1], - pvt->rdimm_ce_count[i][2]); - data += count; - total += count; - } +#define ATTR_COUNTER(param) \ + { \ + .attr = { \ + .name = __stringify(udimm##param), \ + .mode = (S_IRUGO | S_IWUSR) \ + }, \ + .show = i7core_show_counter_##param \ } - return total; -} +DECLARE_COUNTER(0); +DECLARE_COUNTER(1); +DECLARE_COUNTER(2); /* * Sysfs struct @@ -1051,12 +1045,22 @@ static struct mcidev_sysfs_attribute i7core_addrmatch_attrs[] = { { .attr = { .name = NULL } } }; - static struct mcidev_sysfs_group i7core_inject_addrmatch = { .name = "inject_addrmatch", .mcidev_attr = i7core_addrmatch_attrs, }; +static struct mcidev_sysfs_attribute i7core_udimm_counters_attrs[] = { + ATTR_COUNTER(0), + ATTR_COUNTER(1), + ATTR_COUNTER(2), +}; + +static struct mcidev_sysfs_group i7core_udimm_counters = { + .name = "all_channel_counts", + .mcidev_attr = i7core_udimm_counters_attrs, +}; + static struct mcidev_sysfs_attribute i7core_sysfs_attrs[] = { { .attr = { @@ -1088,14 +1092,8 @@ static struct mcidev_sysfs_attribute i7core_sysfs_attrs[] = { }, .show = i7core_inject_enable_show, .store = i7core_inject_enable_store, - }, { - .attr = { - .name = "corrected_error_counts", - .mode = (S_IRUGO | S_IWUSR) - }, - .show = i7core_ce_regs_show, - .store = NULL, }, + { .attr = { .name = NULL } }, /* Reserved for udimm counters */ { .attr = { .name = NULL } } }; @@ -1323,6 +1321,15 @@ static int mci_bind_devs(struct mem_ctl_info *mci, pvt->is_registered = 1; } + /* + * Add extra nodes to count errors on udimm + * For registered memory, this is not needed, since the counters + * are already displayed at the standard locations + */ + if (!pvt->is_registered) + i7core_sysfs_attrs[ARRAY_SIZE(i7core_sysfs_attrs)-2].grp = + &i7core_udimm_counters; + return 0; error: -- cgit v1.2.3 From b968759ee7102f86fec5f3349f7a8ab4556884a3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 25 Sep 2009 13:42:25 -0300 Subject: edac: Create an unique instance for each kobj Current code only works when there's just one memory controller, since we need one kobj for each instance. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/edac_core.h | 21 +++++++++---- drivers/edac/edac_mc_sysfs.c | 75 +++++++++++++++++++++++++++++--------------- 2 files changed, 64 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h index 02bbbc9696d9..efca9343d26a 100644 --- a/drivers/edac/edac_core.h +++ b/drivers/edac/edac_core.h @@ -342,23 +342,29 @@ struct csrow_info { }; struct mcidev_sysfs_group { - const char *name; - struct mcidev_sysfs_attribute *mcidev_attr; - struct kobject kobj; + const char *name; /* group name */ + struct mcidev_sysfs_attribute *mcidev_attr; /* group attributes */ +}; + +struct mcidev_sysfs_group_kobj { + struct list_head list; /* list for all instances within a mc */ + + struct kobject kobj; /* kobj for the group */ + struct mcidev_sysfs_group *grp; /* group description table */ struct mem_ctl_info *mci; /* the parent */ }; - /* mcidev_sysfs_attribute structure * used for driver sysfs attributes and in mem_ctl_info * sysfs top level entries */ struct mcidev_sysfs_attribute { + /* It should use either attr or grp */ struct attribute attr; + struct mcidev_sysfs_group *grp; /* Points to a group of attributes */ - struct mcidev_sysfs_group *grp; - + /* Ops for show/store values at the attribute - not used on group */ ssize_t (*show)(struct mem_ctl_info *,char *); ssize_t (*store)(struct mem_ctl_info *, const char *,size_t); }; @@ -436,6 +442,9 @@ struct mem_ctl_info { /* edac sysfs device control */ struct kobject edac_mci_kobj; + /* list for all grp instances within a mc */ + struct list_head grp_kobj_list; + /* Additional top controller level attributes, but specified * by the low level driver. * diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index f689d7d6ab46..c200c2fd43ea 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c @@ -730,7 +730,7 @@ void edac_mc_unregister_sysfs_main_kobj(struct mem_ctl_info *mci) #define EDAC_DEVICE_SYMLINK "device" -#define grp_to_mci(k) (container_of(k, struct mcidev_sysfs_group, kobj)->mci) +#define grp_to_mci(k) (container_of(k, struct mcidev_sysfs_group_kobj, kobj)->mci) /* MCI show/store functions for top most object */ static ssize_t inst_grp_show(struct kobject *kobj, struct attribute *attr, @@ -764,12 +764,12 @@ static ssize_t inst_grp_store(struct kobject *kobj, struct attribute *attr, /* No memory to release for this kobj */ static void edac_inst_grp_release(struct kobject *kobj) { - struct mcidev_sysfs_group *grp; + struct mcidev_sysfs_group_kobj *grp; struct mem_ctl_info *mci; debugf1("%s()\n", __func__); - grp = container_of(kobj, struct mcidev_sysfs_group, kobj); + grp = container_of(kobj, struct mcidev_sysfs_group_kobj, kobj); mci = grp->mci; kobject_put(&mci->edac_mci_kobj); @@ -804,22 +804,30 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci, while (sysfs_attrib) { if (sysfs_attrib->grp) { - struct kobject *newkobj = &sysfs_attrib->grp->kobj; + struct mcidev_sysfs_group_kobj *grp_kobj; + + grp_kobj = kzalloc(sizeof(*grp_kobj), GFP_KERNEL); + if (!grp_kobj) + return -ENOMEM; + + list_add_tail(&grp_kobj->list, &mci->grp_kobj_list); + + grp_kobj->grp = sysfs_attrib->grp; + grp_kobj->mci = mci; debugf0("%s() grp %s, mci %p\n", __func__, sysfs_attrib->grp->name, mci); - sysfs_attrib->grp->mci = mci; - - err = kobject_init_and_add(newkobj, &ktype_inst_grp, + err = kobject_init_and_add(&grp_kobj->kobj, + &ktype_inst_grp, &mci->edac_mci_kobj, sysfs_attrib->grp->name); if (err) return err; err = edac_create_mci_instance_attributes(mci, - sysfs_attrib->grp->mcidev_attr, - newkobj); + grp_kobj->grp->mcidev_attr, + &grp_kobj->kobj); if (err) return err; @@ -845,25 +853,27 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci, * remove MC driver specific attributes at the topmost level * directory of this mci instance. */ -static void edac_remove_mci_instance_attributes( +static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci, struct mcidev_sysfs_attribute *sysfs_attrib, - struct kobject *kobj) + struct kobject *kobj, int count) { + struct mcidev_sysfs_group_kobj *grp_kobj, *tmp; + debugf1("%s()\n", __func__); - /* loop if there are attributes and until we hit a NULL entry */ + /* + * loop if there are attributes and until we hit a NULL entry + * Remove first all the atributes + */ while (sysfs_attrib) { if (sysfs_attrib->grp) { - struct kobject *newkobj = &sysfs_attrib->grp->kobj; - - debugf0("%s() grp %s\n", __func__, - sysfs_attrib->grp->name); - - edac_remove_mci_instance_attributes( - sysfs_attrib->grp->mcidev_attr, newkobj); - - kobject_put(newkobj); - } else if (sysfs_attrib->attr.name) { + list_for_each_entry(grp_kobj, &mci->grp_kobj_list, + list) + if (grp_kobj->grp == sysfs_attrib->grp) + edac_remove_mci_instance_attributes(mci, + grp_kobj->grp->mcidev_attr, + &grp_kobj->kobj, count + 1); + } else if (sysfs_attrib->attr.name) { debugf0("%s() file %s\n", __func__, sysfs_attrib->attr.name); sysfs_remove_file(kobj, &sysfs_attrib->attr); @@ -871,6 +881,16 @@ static void edac_remove_mci_instance_attributes( break; sysfs_attrib++; } + + /* + * Now that all attributes got removed, it is save to remove all groups + */ + if (!count) + list_for_each_entry_safe(grp_kobj, tmp, &mci->grp_kobj_list, + list) { + debugf0("%s() grp %s\n", __func__, grp_kobj->grp->name); + kobject_put(&grp_kobj->kobj); + } } @@ -891,6 +911,8 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) debugf0("%s() idx=%d\n", __func__, mci->mc_idx); + INIT_LIST_HEAD(&mci->grp_kobj_list); + /* create a symlink for the device */ err = sysfs_create_link(kobj_mci, &mci->dev->kobj, EDAC_DEVICE_SYMLINK); @@ -940,8 +962,8 @@ fail1: } /* remove the mci instance's attributes, if any */ - edac_remove_mci_instance_attributes( - mci->mc_driver_sysfs_attributes, &mci->edac_mci_kobj); + edac_remove_mci_instance_attributes(mci, + mci->mc_driver_sysfs_attributes, &mci->edac_mci_kobj, 0); /* remove the symlink */ sysfs_remove_link(kobj_mci, EDAC_DEVICE_SYMLINK); @@ -975,8 +997,9 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) debugf0("%s() remove_mci_instance\n", __func__); /* remove this mci instance's attribtes */ - edac_remove_mci_instance_attributes(mci->mc_driver_sysfs_attributes, - &mci->edac_mci_kobj); + edac_remove_mci_instance_attributes(mci, + mci->mc_driver_sysfs_attributes, + &mci->edac_mci_kobj, 0); debugf0("%s() unregister this mci kobj\n", __func__); /* unregister this instance's kobject */ -- cgit v1.2.3 From ca9c90ba09ca3c9799319f46a56f397afbf617c2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 4 Oct 2009 10:15:40 -0300 Subject: i7core_edac: Use a lockless ringbuffer Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 83 ++++++++++++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 97f6d1759c99..94aeca011ac4 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -239,9 +238,16 @@ struct i7core_pvt { /* mcelog glue */ struct edac_mce edac_mce; + + /* Fifo double buffers */ struct mce mce_entry[MCE_LOG_LEN]; - unsigned mce_count; - spinlock_t mce_lock; + struct mce mce_outentry[MCE_LOG_LEN]; + + /* Fifo in/out counters */ + unsigned mce_in, mce_out; + + /* Count indicator to show errors not got */ + unsigned mce_overrun; }; /* Static vars */ @@ -1617,30 +1623,50 @@ static void i7core_check_error(struct mem_ctl_info *mci) struct i7core_pvt *pvt = mci->pvt_info; int i; unsigned count = 0; - struct mce *m = NULL; - unsigned long flags; + struct mce *m; - /* Copy all mce errors into a temporary buffer */ - spin_lock_irqsave(&pvt->mce_lock, flags); - if (pvt->mce_count) { - m = kmalloc(sizeof(*m) * pvt->mce_count, GFP_ATOMIC); + /* + * MCE first step: Copy all mce errors into a temporary buffer + * We use a double buffering here, to reduce the risk of + * loosing an error. + */ + smp_rmb(); + count = (pvt->mce_out + sizeof(mce_entry) - pvt->mce_in) + % sizeof(mce_entry); + if (!count) + return; - if (m) { - count = pvt->mce_count; - memcpy(m, &pvt->mce_entry, sizeof(*m) * count); - } - pvt->mce_count = 0; - } + m = pvt->mce_outentry; + if (pvt->mce_in + count > sizeof(mce_entry)) { + unsigned l = sizeof(mce_entry) - pvt->mce_in; - spin_unlock_irqrestore(&pvt->mce_lock, flags); + memcpy(m, &pvt->mce_entry[pvt->mce_in], sizeof(*m) * l); + smp_wmb(); + pvt->mce_in = 0; + count -= l; + m += l; + } + memcpy(m, &pvt->mce_entry[pvt->mce_in], sizeof(*m) * count); + smp_wmb(); + pvt->mce_in += count; + + smp_rmb(); + if (pvt->mce_overrun) { + i7core_printk(KERN_ERR, "Lost %d memory errors\n", + pvt->mce_overrun); + smp_wmb(); + pvt->mce_overrun = 0; + } - /* proccess mcelog errors */ + /* + * MCE second step: parse errors and display + */ for (i = 0; i < count; i++) - i7core_mce_output_error(mci, &m[i]); + i7core_mce_output_error(mci, &pvt->mce_outentry[i]); - kfree(m); - - /* check memory count errors */ + /* + * Now, let's increment CE error counts + */ if (!pvt->is_registered) i7core_udimm_check_mc_ecc_err(mci); else @@ -1657,7 +1683,6 @@ static int i7core_mce_check_error(void *priv, struct mce *mce) { struct mem_ctl_info *mci = priv; struct i7core_pvt *pvt = mci->pvt_info; - unsigned long flags; /* * Just let mcelog handle it if the error is @@ -1679,12 +1704,15 @@ static int i7core_mce_check_error(void *priv, struct mce *mce) return 0; } - spin_lock_irqsave(&pvt->mce_lock, flags); - if (pvt->mce_count < MCE_LOG_LEN) { - memcpy(&pvt->mce_entry[pvt->mce_count], mce, sizeof(*mce)); - pvt->mce_count++; + smp_rmb(); + if ((pvt->mce_out + 1) % sizeof(mce_entry) == pvt->mce_in) { + smp_wmb(); + pvt->mce_overrun++; + return 0; } - spin_unlock_irqrestore(&pvt->mce_lock, flags); + smp_wmb(); + pvt->mce_out = (pvt->mce_out + 1) % sizeof(mce_entry); + memcpy(&pvt->mce_entry[pvt->mce_out], mce, sizeof(*mce)); /* Handle fatal errors immediately */ if (mce->mcgstatus & 1) @@ -1777,7 +1805,6 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev, /* Registers on edac_mce in order to receive memory errors */ pvt->edac_mce.priv = mci; pvt->edac_mce.check_error = i7core_mce_check_error; - spin_lock_init(&pvt->mce_lock); rc = edac_mce_register(&pvt->edac_mce); if (unlikely(rc < 0)) { -- cgit v1.2.3 From 4f87fad1d32fcdda448f9eb430c9c234a1939ece Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 4 Oct 2009 11:54:56 -0300 Subject: i7core_edac: Better parse "any" addrmask Instead of accepting just "any", accept also "any\n" Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 94aeca011ac4..477b62a74dbf 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -800,7 +800,7 @@ static ssize_t i7core_inject_store_##param( \ if (pvt->inject.enable) \ disable_inject(mci); \ \ - if (!strcasecmp(data, "any")) \ + if (!strcasecmp(data, "any") || !strcasecmp(data, "any\n"))\ value = -1; \ else { \ rc = strict_strtoul(data, 10, &value); \ -- cgit v1.2.3 From 6e103be1c7c4adb50f25aaf1f1e8f828833c1719 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 5 Oct 2009 09:40:09 -0300 Subject: i7core_edac: First store, then increment Fix ringbuffer store logic. While here, add a few comments to the code and remove the undesired printk that could otherwise be called during NMI time. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 477b62a74dbf..59ec44175560 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1678,6 +1678,8 @@ static void i7core_check_error(struct mem_ctl_info *mci) * This routine simply queues mcelog errors, and * return. The error itself should be handled later * by i7core_check_error. + * WARNING: As this routine should be called at NMI time, extra care should + * be taken to avoid deadlocks, and to be as fast as possible. */ static int i7core_mce_check_error(void *priv, struct mce *mce) { @@ -1696,13 +1698,8 @@ static int i7core_mce_check_error(void *priv, struct mce *mce) return 0; /* Only handle if it is the right mc controller */ - if (cpu_data(mce->cpu).phys_proc_id != pvt->i7core_dev->socket) { - debugf0("mc%d: ignoring mce log for socket %d. " - "Another mc should get it.\n", - pvt->i7core_dev->socket, - cpu_data(mce->cpu).phys_proc_id); + if (cpu_data(mce->cpu).phys_proc_id != pvt->i7core_dev->socket) return 0; - } smp_rmb(); if ((pvt->mce_out + 1) % sizeof(mce_entry) == pvt->mce_in) { @@ -1710,9 +1707,11 @@ static int i7core_mce_check_error(void *priv, struct mce *mce) pvt->mce_overrun++; return 0; } + + /* Copy memory error at the ringbuffer */ + memcpy(&pvt->mce_entry[pvt->mce_out], mce, sizeof(*mce)); smp_wmb(); pvt->mce_out = (pvt->mce_out + 1) % sizeof(mce_entry); - memcpy(&pvt->mce_entry[pvt->mce_out], mce, sizeof(*mce)); /* Handle fatal errors immediately */ if (mce->mcgstatus & 1) -- cgit v1.2.3 From 321ece4dda32f52d4a28d6eb11f2ca2a5c93c191 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 8 Oct 2009 13:11:08 -0300 Subject: i7core_edac: Fix ringbuffer maxsize Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 59ec44175560..c2857f60ae6a 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1631,14 +1631,14 @@ static void i7core_check_error(struct mem_ctl_info *mci) * loosing an error. */ smp_rmb(); - count = (pvt->mce_out + sizeof(mce_entry) - pvt->mce_in) - % sizeof(mce_entry); + count = (pvt->mce_out + MCE_LOG_LEN - pvt->mce_in) + % MCE_LOG_LEN; if (!count) return; m = pvt->mce_outentry; - if (pvt->mce_in + count > sizeof(mce_entry)) { - unsigned l = sizeof(mce_entry) - pvt->mce_in; + if (pvt->mce_in + count > MCE_LOG_LEN) { + unsigned l = MCE_LOG_LEN - pvt->mce_in; memcpy(m, &pvt->mce_entry[pvt->mce_in], sizeof(*m) * l); smp_wmb(); @@ -1702,7 +1702,7 @@ static int i7core_mce_check_error(void *priv, struct mce *mce) return 0; smp_rmb(); - if ((pvt->mce_out + 1) % sizeof(mce_entry) == pvt->mce_in) { + if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) { smp_wmb(); pvt->mce_overrun++; return 0; @@ -1711,7 +1711,7 @@ static int i7core_mce_check_error(void *priv, struct mce *mce) /* Copy memory error at the ringbuffer */ memcpy(&pvt->mce_entry[pvt->mce_out], mce, sizeof(*mce)); smp_wmb(); - pvt->mce_out = (pvt->mce_out + 1) % sizeof(mce_entry); + pvt->mce_out = (pvt->mce_out + 1) % MCE_LOG_LEN; /* Handle fatal errors immediately */ if (mce->mcgstatus & 1) -- cgit v1.2.3 From fd3826549db7f73d22b9c9abb80e01effb95c2ba Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 14 Oct 2009 06:07:07 -0300 Subject: i7core_edac: PCI device is called NONCORE, instead of NOCORE Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 6 +++--- include/linux/pci_ids.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index c2857f60ae6a..bb538dfbdc6c 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -291,7 +291,7 @@ struct pci_id_descr pci_dev_descr[] = { * the probing code needs to test for the other address in case of * failure of this one */ - { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_I7_NOCORE) }, + { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_I7_NONCORE) }, }; #define N_DEVS ARRAY_SIZE(pci_dev_descr) @@ -1177,9 +1177,9 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno) * is at addr 8086:2c40, instead of 8086:2c41. So, we need * to probe for the alternate address in case of failure */ - if (pci_dev_descr[devno].dev_id == PCI_DEVICE_ID_INTEL_I7_NOCORE && !pdev) + if (pci_dev_descr[devno].dev_id == PCI_DEVICE_ID_INTEL_I7_NONCORE && !pdev) pdev = pci_get_device(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_I7_NOCORE_ALT, *prev); + PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT, *prev); if (!pdev) { if (*prev) { diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index bf6db4814c27..382476a8a339 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2548,8 +2548,8 @@ #define PCI_DEVICE_ID_INTEL_I7_MC_CH2_ADDR 0x2c31 #define PCI_DEVICE_ID_INTEL_I7_MC_CH2_RANK 0x2c32 #define PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC 0x2c33 -#define PCI_DEVICE_ID_INTEL_I7_NOCORE 0x2c41 -#define PCI_DEVICE_ID_INTEL_I7_NOCORE_ALT 0x2c40 +#define PCI_DEVICE_ID_INTEL_I7_NONCORE 0x2c41 +#define PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT 0x2c40 #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340 #define PCI_DEVICE_ID_INTEL_IOAT_TBG4 0x3429 #define PCI_DEVICE_ID_INTEL_IOAT_TBG5 0x342a -- cgit v1.2.3 From de06eeef5809a69ff4daaae2bd63977e5404553d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 14 Oct 2009 08:02:40 -0300 Subject: i7core_edac: Use a more generic approach for probing PCI devices Currently, only one PCI set of tables is allowed. This prevents using the driver for other devices like Lynnfield, with have a different set of PCI ID's. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 79 +++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index bb538dfbdc6c..b6fce2e38e3d 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -202,12 +202,14 @@ struct pci_id_descr { int dev; int func; int dev_id; + int optional; }; struct i7core_dev { struct list_head list; u8 socket; struct pci_dev **pdev; + int n_devs; struct mem_ctl_info *mci; }; @@ -259,11 +261,12 @@ static DEFINE_MUTEX(i7core_edac_lock); .func = (function), \ .dev_id = (device_id) -struct pci_id_descr pci_dev_descr[] = { +struct pci_id_descr pci_dev_descr_i7core[] = { /* Memory controller */ { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) }, { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) }, - { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_I7_MC_RAS) }, /* if RDIMM */ + /* Exists only for RDIMM */ + { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_I7_MC_RAS), .optional = 1 }, { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_I7_MC_TEST) }, /* Channel 0 */ @@ -294,7 +297,6 @@ struct pci_id_descr pci_dev_descr[] = { { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_I7_NONCORE) }, }; -#define N_DEVS ARRAY_SIZE(pci_dev_descr) /* * pci_device_id table for which devices we are looking for @@ -380,7 +382,7 @@ static struct pci_dev *get_pdev_slot_func(u8 socket, unsigned slot, if (!i7core_dev) return NULL; - for (i = 0; i < N_DEVS; i++) { + for (i = 0; i < i7core_dev->n_devs; i++) { if (!i7core_dev->pdev[i]) continue; @@ -1116,7 +1118,7 @@ static void i7core_put_devices(struct i7core_dev *i7core_dev) int i; debugf0(__FILE__ ": %s()\n", __func__); - for (i = 0; i < N_DEVS; i++) { + for (i = 0; i < i7core_dev->n_devs; i++) { struct pci_dev *pdev = i7core_dev->pdev[i]; if (!pdev) continue; @@ -1138,7 +1140,7 @@ static void i7core_put_all_devices(void) i7core_put_devices(i7core_dev); } -static void i7core_xeon_pci_fixup(void) +static void i7core_xeon_pci_fixup(int dev_id) { struct pci_dev *pdev = NULL; int i; @@ -1147,8 +1149,7 @@ static void i7core_xeon_pci_fixup(void) * aren't announced by acpi. So, we need to use a legacy scan probing * to detect them */ - pdev = pci_get_device(PCI_VENDOR_ID_INTEL, - pci_dev_descr[0].dev_id, NULL); + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, NULL); if (unlikely(!pdev)) { for (i = 0; i < MAX_SOCKET_BUSES; i++) pcibios_scan_specific_bus(255-i); @@ -1161,7 +1162,8 @@ static void i7core_xeon_pci_fixup(void) * * Need to 'get' device 16 func 1 and func 2 */ -int i7core_get_onedevice(struct pci_dev **prev, int devno) +int i7core_get_onedevice(struct pci_dev **prev, int devno, + struct pci_id_descr *dev_descr, unsigned n_devs) { struct i7core_dev *i7core_dev; @@ -1170,14 +1172,14 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno) u8 socket = 0; pdev = pci_get_device(PCI_VENDOR_ID_INTEL, - pci_dev_descr[devno].dev_id, *prev); + dev_descr->dev_id, *prev); /* * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core regs * is at addr 8086:2c40, instead of 8086:2c41. So, we need * to probe for the alternate address in case of failure */ - if (pci_dev_descr[devno].dev_id == PCI_DEVICE_ID_INTEL_I7_NONCORE && !pdev) + if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_I7_NONCORE && !pdev) pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT, *prev); @@ -1187,19 +1189,13 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno) return 0; } - /* - * Dev 3 function 2 only exists on chips with RDIMMs - * so, it is ok to not found it - */ - if ((pci_dev_descr[devno].dev == 3) && (pci_dev_descr[devno].func == 2)) { - *prev = pdev; + if (dev_descr->optional) return 0; - } i7core_printk(KERN_ERR, "Device not found: dev %02x.%d PCI ID %04x:%04x\n", - pci_dev_descr[devno].dev, pci_dev_descr[devno].func, - PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id); + dev_descr->dev, dev_descr->func, + PCI_VENDOR_ID_INTEL, dev_descr->dev_id); /* End of list, leave */ return -ENODEV; @@ -1216,11 +1212,12 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno) i7core_dev = kzalloc(sizeof(*i7core_dev), GFP_KERNEL); if (!i7core_dev) return -ENOMEM; - i7core_dev->pdev = kzalloc(sizeof(*i7core_dev->pdev) * N_DEVS, + i7core_dev->pdev = kzalloc(sizeof(*i7core_dev->pdev) * n_devs, GFP_KERNEL); if (!i7core_dev->pdev) return -ENOMEM; i7core_dev->socket = socket; + i7core_dev->n_devs = n_devs; list_add_tail(&i7core_dev->list, &i7core_edac_list); } @@ -1228,8 +1225,8 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno) i7core_printk(KERN_ERR, "Duplicated device for " "dev %02x:%02x.%d PCI ID %04x:%04x\n", - bus, pci_dev_descr[devno].dev, pci_dev_descr[devno].func, - PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id); + bus, dev_descr->dev, dev_descr->func, + PCI_VENDOR_ID_INTEL, dev_descr->dev_id); pci_dev_put(pdev); return -ENODEV; } @@ -1237,14 +1234,14 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno) i7core_dev->pdev[devno] = pdev; /* Sanity check */ - if (unlikely(PCI_SLOT(pdev->devfn) != pci_dev_descr[devno].dev || - PCI_FUNC(pdev->devfn) != pci_dev_descr[devno].func)) { + if (unlikely(PCI_SLOT(pdev->devfn) != dev_descr->dev || + PCI_FUNC(pdev->devfn) != dev_descr->func)) { i7core_printk(KERN_ERR, "Device PCI ID %04x:%04x " "has dev %02x:%02x.%d instead of dev %02x:%02x.%d\n", - PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id, + PCI_VENDOR_ID_INTEL, dev_descr->dev_id, bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), - bus, pci_dev_descr[devno].dev, pci_dev_descr[devno].func); + bus, dev_descr->dev, dev_descr->func); return -ENODEV; } @@ -1253,30 +1250,32 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno) i7core_printk(KERN_ERR, "Couldn't enable " "dev %02x:%02x.%d PCI ID %04x:%04x\n", - bus, pci_dev_descr[devno].dev, pci_dev_descr[devno].func, - PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id); + bus, dev_descr->dev, dev_descr->func, + PCI_VENDOR_ID_INTEL, dev_descr->dev_id); return -ENODEV; } debugf0("Detected socket %d dev %02x:%02x.%d PCI ID %04x:%04x\n", - socket, bus, pci_dev_descr[devno].dev, - pci_dev_descr[devno].func, - PCI_VENDOR_ID_INTEL, pci_dev_descr[devno].dev_id); + socket, bus, dev_descr->dev, + dev_descr->func, + PCI_VENDOR_ID_INTEL, dev_descr->dev_id); *prev = pdev; return 0; } -static int i7core_get_devices(void) +static int i7core_get_devices(struct pci_id_descr dev_descr[], unsigned n_devs) { - int i; + int i, rc; struct pci_dev *pdev = NULL; - for (i = 0; i < N_DEVS; i++) { + for (i = 0; i < n_devs; i++) { pdev = NULL; do { - if (i7core_get_onedevice(&pdev, i) < 0) { + rc = i7core_get_onedevice(&pdev, i, &dev_descr[i], + n_devs); + if (rc < 0) { i7core_put_all_devices(); return -ENODEV; } @@ -1298,7 +1297,7 @@ static int mci_bind_devs(struct mem_ctl_info *mci, i7core_dev->mci = mci; pvt->is_registered = 0; - for (i = 0; i < N_DEVS; i++) { + for (i = 0; i < i7core_dev->n_devs; i++) { pdev = i7core_dev->pdev[i]; if (!pdev) continue; @@ -1838,7 +1837,9 @@ static int __devinit i7core_probe(struct pci_dev *pdev, /* get the pci devices we want to reserve for our use */ mutex_lock(&i7core_edac_lock); - rc = i7core_get_devices(); + + rc = i7core_get_devices(pci_dev_descr_i7core, + ARRAY_SIZE(pci_dev_descr_i7core)); if (unlikely(rc < 0)) goto fail0; @@ -1937,7 +1938,7 @@ static int __init i7core_init(void) /* Ensure that the OPSTATE is set correctly for POLL or NMI */ opstate_init(); - i7core_xeon_pci_fixup(); + i7core_xeon_pci_fixup(pci_dev_descr_i7core[0].dev_id); pci_rc = pci_register_driver(&i7core_driver); -- cgit v1.2.3 From 486dd09f129da01cd02b212ba48dce987488b860 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 8 Nov 2009 01:34:27 -0200 Subject: edac: i7core_edac produces undefined behaviour on 32bit Fix the shifts up Signed-off-by: Alan Cox Acked-by: Doug Thompson Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index b6fce2e38e3d..bd7c727030a3 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -916,41 +916,41 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, /* Sets pvt->inject.dimm mask */ if (pvt->inject.dimm < 0) - mask |= 1L << 41; + mask |= 1LL << 41; else { if (pvt->channel[pvt->inject.channel].dimms > 2) - mask |= (pvt->inject.dimm & 0x3L) << 35; + mask |= (pvt->inject.dimm & 0x3LL) << 35; else - mask |= (pvt->inject.dimm & 0x1L) << 36; + mask |= (pvt->inject.dimm & 0x1LL) << 36; } /* Sets pvt->inject.rank mask */ if (pvt->inject.rank < 0) - mask |= 1L << 40; + mask |= 1LL << 40; else { if (pvt->channel[pvt->inject.channel].dimms > 2) - mask |= (pvt->inject.rank & 0x1L) << 34; + mask |= (pvt->inject.rank & 0x1LL) << 34; else - mask |= (pvt->inject.rank & 0x3L) << 34; + mask |= (pvt->inject.rank & 0x3LL) << 34; } /* Sets pvt->inject.bank mask */ if (pvt->inject.bank < 0) - mask |= 1L << 39; + mask |= 1LL << 39; else - mask |= (pvt->inject.bank & 0x15L) << 30; + mask |= (pvt->inject.bank & 0x15LL) << 30; /* Sets pvt->inject.page mask */ if (pvt->inject.page < 0) - mask |= 1L << 38; + mask |= 1LL << 38; else - mask |= (pvt->inject.page & 0xffffL) << 14; + mask |= (pvt->inject.page & 0xffff) << 14; /* Sets pvt->inject.column mask */ if (pvt->inject.col < 0) - mask |= 1L << 37; + mask |= 1LL << 37; else - mask |= (pvt->inject.col & 0x3fffL); + mask |= (pvt->inject.col & 0x3fff); /* * bit 0: REPEAT_EN -- cgit v1.2.3 From 3b918c12df4f624140456d6c6f982bada8e1f095 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 8 Nov 2009 01:36:40 -0200 Subject: edac: fix i7core build Fix build warning (missing header file) and build error when CONFIG_SMP=n. drivers/edac/i7core_edac.c:860: error: implicit declaration of function 'msleep' drivers/edac/i7core_edac.c:1700: error: 'struct cpuinfo_x86' has no member named 'phys_proc_id' Signed-off-by: Randy Dunlap Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index bd7c727030a3..e944b63d9f06 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -1696,9 +1697,11 @@ static int i7core_mce_check_error(void *priv, struct mce *mce) if (mce->bank != 8) return 0; +#ifdef CONFIG_SMP /* Only handle if it is the right mc controller */ if (cpu_data(mce->cpu).phys_proc_id != pvt->i7core_dev->socket) return 0; +#endif smp_rmb(); if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) { -- cgit v1.2.3 From 52a2e4fc3712d12888decd386d78ad526078a1fa Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 14 Oct 2009 11:21:58 -0300 Subject: i7core_edac: Add initial support for Lynnfield Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 39 +++++++++++++++++++++++++++++++++++++-- include/linux/pci_ids.h | 15 +++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index e944b63d9f06..e525d571cb25 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -299,11 +299,30 @@ struct pci_id_descr pci_dev_descr_i7core[] = { }; +struct pci_id_descr pci_dev_descr_lynnfield[] = { + { PCI_DESCR( 3, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MCR) }, + { PCI_DESCR( 3, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TAD) }, + { PCI_DESCR( 3, 4, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TEST) }, + + { PCI_DESCR( 4, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_CTRL) }, + { PCI_DESCR( 4, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_ADDR) }, + { PCI_DESCR( 4, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_RANK) }, + { PCI_DESCR( 4, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_TC) }, + + { PCI_DESCR( 4, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_CTRL) }, + { PCI_DESCR( 4, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR) }, + { PCI_DESCR( 4, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK) }, + { PCI_DESCR( 4, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC) }, + + { PCI_DESCR( 0, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE) }, +}; + /* * pci_device_id table for which devices we are looking for */ static const struct pci_device_id i7core_pci_tbl[] __devinitdata = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_X58_HUB_MGMT)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE)}, {0,} /* 0 terminated list. */ }; @@ -522,6 +541,9 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow) for (i = 0; i < NUM_CHANS; i++) { u32 data, dimm_dod[3], value[8]; + if (!pvt->pci_ch[i][0]) + continue; + if (!CH_ACTIVE(pvt, i)) { debugf0("Channel %i is not active\n", i); continue; @@ -1001,6 +1023,9 @@ static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci, struct i7core_pvt *pvt = mci->pvt_info; u32 injectmask; + if (!pvt->pci_ch[pvt->inject.channel][0]) + return 0; + pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0], MC_CHANNEL_ERROR_INJECT, &injectmask); @@ -1841,8 +1866,18 @@ static int __devinit i7core_probe(struct pci_dev *pdev, /* get the pci devices we want to reserve for our use */ mutex_lock(&i7core_edac_lock); - rc = i7core_get_devices(pci_dev_descr_i7core, - ARRAY_SIZE(pci_dev_descr_i7core)); + if (pdev->device == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE) { + printk(KERN_INFO "i7core_edac: detected a " + "Lynnfield processor\n"); + rc = i7core_get_devices(pci_dev_descr_lynnfield, + ARRAY_SIZE(pci_dev_descr_lynnfield)); + } else { + printk(KERN_INFO "i7core_edac: detected a " + "Nehalem/Nehalem-EP processor\n"); + rc = i7core_get_devices(pci_dev_descr_i7core, + ARRAY_SIZE(pci_dev_descr_i7core)); + } + if (unlikely(rc < 0)) goto fail0; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 382476a8a339..ebc0fa4c7a66 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2550,6 +2550,21 @@ #define PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC 0x2c33 #define PCI_DEVICE_ID_INTEL_I7_NONCORE 0x2c41 #define PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT 0x2c40 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE 0x2c50 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_SAD 0x2c81 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_LINK0 0x2c90 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_PHY0 0x2c91 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MCR 0x2c98 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TAD 0x2c99 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TEST 0x2c9C +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_CTRL 0x2ca0 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_ADDR 0x2ca1 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_RANK 0x2ca2 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_TC 0x2ca3 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_CTRL 0x2ca8 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR 0x2ca9 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK 0x2caa +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC 0x2cab #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340 #define PCI_DEVICE_ID_INTEL_IOAT_TBG4 0x3429 #define PCI_DEVICE_ID_INTEL_IOAT_TBG5 0x342a -- cgit v1.2.3 From f05da2f7855b3b88a831ca79e037245872549ec0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 14 Oct 2009 13:31:06 -0300 Subject: i7core: add support for Lynnfield alternate address Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 13 +++++++++++-- include/linux/pci_ids.h | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index e525d571cb25..d3f5c016c5eb 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -314,6 +314,10 @@ struct pci_id_descr pci_dev_descr_lynnfield[] = { { PCI_DESCR( 4, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK) }, { PCI_DESCR( 4, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC) }, + /* + * This is the PCI device has an alternate address on some + * processors like Core i7 860 + */ { PCI_DESCR( 0, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE) }, }; @@ -322,7 +326,7 @@ struct pci_id_descr pci_dev_descr_lynnfield[] = { */ static const struct pci_device_id i7core_pci_tbl[] __devinitdata = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_X58_HUB_MGMT)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_LINK0)}, {0,} /* 0 terminated list. */ }; @@ -1209,6 +1213,11 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno, pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT, *prev); + if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && !pdev) + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT, + *prev); + if (!pdev) { if (*prev) { *prev = pdev; @@ -1866,7 +1875,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, /* get the pci devices we want to reserve for our use */ mutex_lock(&i7core_edac_lock); - if (pdev->device == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE) { + if (pdev->device == PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_LINK0) { printk(KERN_INFO "i7core_edac: detected a " "Lynnfield processor\n"); rc = i7core_get_devices(pci_dev_descr_lynnfield, diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ebc0fa4c7a66..e67cb20b8401 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2551,6 +2551,7 @@ #define PCI_DEVICE_ID_INTEL_I7_NONCORE 0x2c41 #define PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT 0x2c40 #define PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE 0x2c50 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT 0x2c51 #define PCI_DEVICE_ID_INTEL_LYNNFIELD_SAD 0x2c81 #define PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_LINK0 0x2c90 #define PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_PHY0 0x2c91 -- cgit v1.2.3 From 508fa179f8e0da5d7241e12ad1562b96f291e800 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 14 Oct 2009 13:44:37 -0300 Subject: i7core_edac: Fix wrong device id for channel 1 devices Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index d3f5c016c5eb..4d6ecf1291b8 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -309,10 +309,10 @@ struct pci_id_descr pci_dev_descr_lynnfield[] = { { PCI_DESCR( 4, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_RANK) }, { PCI_DESCR( 4, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_TC) }, - { PCI_DESCR( 4, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_CTRL) }, - { PCI_DESCR( 4, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR) }, - { PCI_DESCR( 4, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK) }, - { PCI_DESCR( 4, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC) }, + { PCI_DESCR( 5, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_CTRL) }, + { PCI_DESCR( 5, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR) }, + { PCI_DESCR( 5, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK) }, + { PCI_DESCR( 5, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC) }, /* * This is the PCI device has an alternate address on some -- cgit v1.2.3 From 2395e463fefd4aa8b784787e926e9b84e216d14f Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 11 May 2010 09:02:55 +0200 Subject: paride: fix menu indentation Make the PARIDE menu be displayed correctly, with proper/expected indentation, by moving the GDROM kconfig symbol, which was splitting the PARIDE kconfig symbol from its dependent symbols. Signed-off-by: Randy Dunlap Signed-off-by: Jens Axboe --- drivers/block/Kconfig | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 77bfce52e9ca..de277689da61 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -76,6 +76,17 @@ config BLK_DEV_XD It's pretty unlikely that you have one of these: say N. +config GDROM + tristate "SEGA Dreamcast GD-ROM drive" + depends on SH_DREAMCAST + help + A standard SEGA Dreamcast comes with a modified CD ROM drive called a + "GD-ROM" by SEGA to signify it is capable of reading special disks + with up to 1 GB of data. This drive will also read standard CD ROM + disks. Select this option to access any disks in your GD ROM drive. + Most users will want to say "Y" here. + You can also build this as a module which will be called gdrom. + config PARIDE tristate "Parallel port IDE device support" depends on PARPORT_PC @@ -103,17 +114,6 @@ config PARIDE "MicroSolutions backpack protocol", "DataStor Commuter protocol" etc.). -config GDROM - tristate "SEGA Dreamcast GD-ROM drive" - depends on SH_DREAMCAST - help - A standard SEGA Dreamcast comes with a modified CD ROM drive called a - "GD-ROM" by SEGA to signify it is capable of reading special disks - with up to 1 GB of data. This drive will also read standard CD ROM - disks. Select this option to access any disks in your GD ROM drive. - Most users will want to say "Y" here. - You can also build this as a module which will be called gdrom. - source "drivers/block/paride/Kconfig" config BLK_CPQ_DA -- cgit v1.2.3 From a9ddabc52ce3757a4331d6c1e8bf4065333cc51b Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Tue, 11 May 2010 00:08:03 -0700 Subject: cmd640: fix kernel oops in test_irq() method When implementing the test_iqr() method, I forgot that this driver is not an ordinary PCI driver and also needs to support VLB variant of the chip. Moreover, 'hwif->dev' should be NULL, potentially causing oops in pci_read_config_byte(). Signed-off-by: Sergei Shtylyov Signed-off-by: David S. Miller --- drivers/ide/cmd640.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/cmd640.c b/drivers/ide/cmd640.c index d2b8b272bc27..cb10201a15ed 100644 --- a/drivers/ide/cmd640.c +++ b/drivers/ide/cmd640.c @@ -633,12 +633,10 @@ static void __init cmd640_init_dev(ide_drive_t *drive) static int cmd640_test_irq(ide_hwif_t *hwif) { - struct pci_dev *dev = to_pci_dev(hwif->dev); int irq_reg = hwif->channel ? ARTTIM23 : CFR; - u8 irq_stat, irq_mask = hwif->channel ? ARTTIM23_IDE23INTR : + u8 irq_mask = hwif->channel ? ARTTIM23_IDE23INTR : CFR_IDE01INTR; - - pci_read_config_byte(dev, irq_reg, &irq_stat); + u8 irq_stat = get_cmd640_reg(irq_reg); return (irq_stat & irq_mask) ? 1 : 0; } -- cgit v1.2.3 From 0b25a610c1f4e1f9632421e10a0f4c6497ea7deb Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Sat, 27 Feb 2010 17:43:22 +0100 Subject: Staging: vt6655: 80211hdr.h: Checkpatch cleanup ERROR: do not use C99 // comments +// bit type ERROR: do not use C99 // comments +// 802.11 frame related, defined as 802.11 spec ERROR: do not use C99 // comments +//#define WLAN_RATES_MAXLEN 255 ERROR: do not use C99 // comments +//#define WLAN_WEPMAX_KEYLEN 29 ERROR: do not use C99 // comments +// Frame Type ERROR: do not use C99 // comments +// Frame Subtypes ERROR: do not use C99 // comments +// Control ERROR: do not use C99 // comments +// Data ERROR: do not use C99 // comments +// GET & SET Frame Control bit ERROR: do not use C99 // comments +// Sequence Field bit ERROR: do not use C99 // comments +// Capability Field bit ERROR: do not use C99 // comments +// GET & SET Frame Control bit ERROR: do not use C99 // comments +// Sequence Field bit ERROR: do not use C99 // comments +// Capability Field bit ERROR: do not use C99 // comments +#endif //#ifdef __BIG_ENDIAN ERROR: do not use C99 // comments +// ERP Field bit ERROR: do not use C99 // comments +// Support & Basic Rates field ERROR: do not use C99 // comments +// TIM field ERROR: do not use C99 // comments +// 3-Addr & 4-Addr ERROR: do not use C99 // comments +// IEEE ADDR ERROR: do not use C99 // comments +// 802.11 Header Format ERROR: space required after that close brace '}' +}__attribute__ ((__packed__)) ERROR: space required after that close brace '}' +}__attribute__ ((__packed__)) ERROR: space required after that close brace '}' +}__attribute__ ((__packed__)) ERROR: do not use C99 // comments +#endif // __80211HDR_H__ Signed-off-by: Andrea Gelmini --- drivers/staging/vt6655/80211hdr.h | 46 +++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/80211hdr.h b/drivers/staging/vt6655/80211hdr.h index e5cee6fd0533..b7b170e19aa2 100644 --- a/drivers/staging/vt6655/80211hdr.h +++ b/drivers/staging/vt6655/80211hdr.h @@ -34,7 +34,7 @@ #include "ttype.h" /*--------------------- Export Definitions -------------------------*/ -// bit type +/* bit type */ #define BIT0 0x00000001 #define BIT1 0x00000002 #define BIT2 0x00000004 @@ -80,7 +80,7 @@ #define WLAN_HDR_ADDR4_LEN 30 #define WLAN_IEHDR_LEN 2 #define WLAN_SSID_MAXLEN 32 -//#define WLAN_RATES_MAXLEN 255 +/*#define WLAN_RATES_MAXLEN 255*/ #define WLAN_RATES_MAXLEN 16 #define WLAN_RATES_MAXLEN_11B 4 #define WLAN_RSN_MAXLEN 32 @@ -106,7 +106,7 @@ #define WLAN_WEP40_KEYLEN 5 #define WLAN_WEP104_KEYLEN 13 #define WLAN_WEP232_KEYLEN 29 -//#define WLAN_WEPMAX_KEYLEN 29 +/*#define WLAN_WEPMAX_KEYLEN 29*/ #define WLAN_WEPMAX_KEYLEN 32 #define WLAN_CHALLENGE_IE_MAXLEN 255 #define WLAN_CHALLENGE_IE_LEN 130 @@ -115,7 +115,7 @@ #define WLAN_WEP_ICV_LEN 4 #define WLAN_FRAGS_MAX 16 -// Frame Type +/* Frame Type */ #define WLAN_TYPE_MGR 0x00 #define WLAN_TYPE_CTL 0x01 #define WLAN_TYPE_DATA 0x02 @@ -125,7 +125,7 @@ #define WLAN_FTYPE_DATA 0x02 -// Frame Subtypes +/* Frame Subtypes */ #define WLAN_FSTYPE_ASSOCREQ 0x00 #define WLAN_FSTYPE_ASSOCRESP 0x01 #define WLAN_FSTYPE_REASSOCREQ 0x02 @@ -139,7 +139,7 @@ #define WLAN_FSTYPE_DEAUTHEN 0x0c #define WLAN_FSTYPE_ACTION 0x0d -// Control +/* Control */ #define WLAN_FSTYPE_PSPOLL 0x0a #define WLAN_FSTYPE_RTS 0x0b #define WLAN_FSTYPE_CTS 0x0c @@ -147,7 +147,7 @@ #define WLAN_FSTYPE_CFEND 0x0e #define WLAN_FSTYPE_CFENDCFACK 0x0f -// Data +/* Data */ #define WLAN_FSTYPE_DATAONLY 0x00 #define WLAN_FSTYPE_DATA_CFACK 0x01 #define WLAN_FSTYPE_DATA_CFPOLL 0x02 @@ -160,7 +160,7 @@ #ifdef __BIG_ENDIAN -// GET & SET Frame Control bit +/* GET & SET Frame Control bit */ #define WLAN_GET_FC_PRVER(n) ((((WORD)(n) >> 8) & (BIT0 | BIT1)) #define WLAN_GET_FC_FTYPE(n) ((((WORD)(n) >> 8) & (BIT2 | BIT3)) >> 2) #define WLAN_GET_FC_FSTYPE(n) ((((WORD)(n) >> 8) & (BIT4|BIT5|BIT6|BIT7)) >> 4) @@ -173,12 +173,12 @@ #define WLAN_GET_FC_ISWEP(n) ((((WORD)(n) << 8) & (BIT14)) >> 14) #define WLAN_GET_FC_ORDER(n) ((((WORD)(n) << 8) & (BIT15)) >> 15) -// Sequence Field bit +/* Sequence Field bit */ #define WLAN_GET_SEQ_FRGNUM(n) (((WORD)(n) >> 8) & (BIT0|BIT1|BIT2|BIT3)) #define WLAN_GET_SEQ_SEQNUM(n) ((((WORD)(n) >> 8) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4) -// Capability Field bit +/* Capability Field bit */ #define WLAN_GET_CAP_INFO_ESS(n) (((n) >> 8) & BIT0) #define WLAN_GET_CAP_INFO_IBSS(n) ((((n) >> 8) & BIT1) >> 1) #define WLAN_GET_CAP_INFO_CFPOLLABLE(n) ((((n) >> 8) & BIT2) >> 2) @@ -195,7 +195,7 @@ #else -// GET & SET Frame Control bit +/* GET & SET Frame Control bit */ #define WLAN_GET_FC_PRVER(n) (((WORD)(n)) & (BIT0 | BIT1)) #define WLAN_GET_FC_FTYPE(n) ((((WORD)(n)) & (BIT2 | BIT3)) >> 2) #define WLAN_GET_FC_FSTYPE(n) ((((WORD)(n)) & (BIT4|BIT5|BIT6|BIT7)) >> 4) @@ -209,12 +209,12 @@ #define WLAN_GET_FC_ORDER(n) ((((WORD)(n)) & (BIT15)) >> 15) -// Sequence Field bit +/* Sequence Field bit */ #define WLAN_GET_SEQ_FRGNUM(n) (((WORD)(n)) & (BIT0|BIT1|BIT2|BIT3)) #define WLAN_GET_SEQ_SEQNUM(n) ((((WORD)(n)) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4) -// Capability Field bit +/* Capability Field bit */ #define WLAN_GET_CAP_INFO_ESS(n) ((n) & BIT0) #define WLAN_GET_CAP_INFO_IBSS(n) (((n) & BIT1) >> 1) #define WLAN_GET_CAP_INFO_CFPOLLABLE(n) (((n) & BIT2) >> 2) @@ -229,7 +229,7 @@ #define WLAN_GET_CAP_INFO_GRPACK(n) (((n) & BIT14) >> 14) -#endif //#ifdef __BIG_ENDIAN +#endif /*#ifdef __BIG_ENDIAN */ #define WLAN_SET_CAP_INFO_ESS(n) (n) @@ -261,7 +261,7 @@ #define WLAN_SET_SEQ_FRGNUM(n) ((WORD)(n)) #define WLAN_SET_SEQ_SEQNUM(n) (((WORD)(n)) << 4) -// ERP Field bit +/* ERP Field bit */ #define WLAN_GET_ERP_NONERP_PRESENT(n) ((n) & BIT0) #define WLAN_GET_ERP_USE_PROTECTION(n) (((n) & BIT1) >> 1) @@ -273,19 +273,19 @@ -// Support & Basic Rates field +/* Support & Basic Rates field */ #define WLAN_MGMT_IS_BASICRATE(b) ((b) & BIT7) #define WLAN_MGMT_GET_RATE(b) ((b) & ~BIT7) -// TIM field +/* TIM field */ #define WLAN_MGMT_IS_MULTICAST_TIM(b) ((b) & BIT0) #define WLAN_MGMT_GET_TIM_OFFSET(b) (((b) & ~BIT0) >> 1) -// 3-Addr & 4-Addr +/* 3-Addr & 4-Addr */ #define WLAN_HDR_A3_DATA_PTR(p) (((PBYTE)(p)) + WLAN_HDR_ADDR3_LEN) #define WLAN_HDR_A4_DATA_PTR(p) (((PBYTE)(p)) + WLAN_HDR_ADDR4_LEN) -// IEEE ADDR +/* IEEE ADDR */ #define IEEE_ADDR_UNIVERSAL 0x02 #define IEEE_ADDR_GROUP 0x01 @@ -293,7 +293,7 @@ typedef struct { BYTE abyAddr[6]; } IEEE_ADDR, *PIEEE_ADDR; -// 802.11 Header Format +/* 802.11 Header Format */ typedef struct tagWLAN_80211HDR_A2 { @@ -302,7 +302,7 @@ typedef struct tagWLAN_80211HDR_A2 { BYTE abyAddr1[WLAN_ADDR_LEN]; BYTE abyAddr2[WLAN_ADDR_LEN]; -}__attribute__ ((__packed__)) +} __attribute__ ((__packed__)) WLAN_80211HDR_A2, *PWLAN_80211HDR_A2; typedef struct tagWLAN_80211HDR_A3 { @@ -327,7 +327,7 @@ typedef struct tagWLAN_80211HDR_A4 { WORD wSeqCtl; BYTE abyAddr4[WLAN_ADDR_LEN]; -}__attribute__ ((__packed__)) +} __attribute__ ((__packed__)) WLAN_80211HDR_A4, *PWLAN_80211HDR_A4; @@ -348,6 +348,6 @@ typedef union tagUWLAN_80211HDR { -#endif // __80211HDR_H__ +#endif /* __80211HDR_H__ */ -- cgit v1.2.3 From a88e29cfd8e59c82cf63440117bd1d61761f0f87 Mon Sep 17 00:00:00 2001 From: Graham M Howe Date: Sat, 27 Feb 2010 09:14:22 +0000 Subject: Staging: comedi: fix 80 character line issue in 8253.h This is a patch to the 8253.h file to fix 80 character line warning found by checkpatch.pl tool Signed-off-by: Graham M Howe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8253.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/8253.h b/drivers/staging/comedi/drivers/8253.h index 0bb35db4ea3b..3eb45d46e05b 100644 --- a/drivers/staging/comedi/drivers/8253.h +++ b/drivers/staging/comedi/drivers/8253.h @@ -214,7 +214,8 @@ static inline void i8253_cascade_ns_to_timer_2div(int i8253_osc_base, #ifndef CMDTEST /* i8254_load programs 8254 counter chip. It should also work for the 8253. - * base_address is the lowest io address for the chip (the address of counter 0). + * base_address is the lowest io address + * for the chip (the address of counter 0). * counter_number is the counter you want to load (0,1 or 2) * count is the number to load into the counter. * -- cgit v1.2.3 From de55a7a5a2f17212c8e7c9a391db8ab5b0187c43 Mon Sep 17 00:00:00 2001 From: Stewart Robertson Date: Sat, 27 Feb 2010 17:05:38 +0000 Subject: Staging: comedi: fix comments over 80 issue in usbduxfast.c This is a patch to the usbduxfast.c file that fixes comments over 80 warnings found by the checkpatch.pl tool Signed-off-by: Stewart Robertson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxfast.c | 44 ++++++++++++++++------------- 1 file changed, 25 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index e89b81812538..05b1973ea35f 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -177,8 +177,8 @@ struct usbduxfastsub_s { int16_t *insnBuffer; /* input buffer for single insn */ int ifnum; /* interface number */ struct usb_interface *interface; /* interface structure */ - struct comedi_device *comedidev; /* comedi device for the interrupt - context */ + /* comedi device for the interrupt context */ + struct comedi_device *comedidev; short int ai_cmd_running; /* asynchronous command is running */ short int ai_continous; /* continous aquisition */ long int ai_sample_count; /* number of samples to acquire */ @@ -271,7 +271,8 @@ static int usbduxfast_ai_stop(struct usbduxfastsub_s *udfs, int do_unlink) udfs->ai_cmd_running = 0; if (do_unlink) - ret = usbduxfastsub_unlink_InURBs(udfs); /* stop aquistion */ + /* stop aquistion */ + ret = usbduxfastsub_unlink_InURBs(udfs); return ret; } @@ -451,13 +452,15 @@ static int usbduxfastsub_start(struct usbduxfastsub_s *udfs) /* 7f92 to zero */ local_transfer_buffer[0] = 0; - ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), USBDUXFASTSUB_FIRMWARE, /* bRequest, "Firmware" */ - VENDOR_DIR_OUT, /* bmRequestType */ - USBDUXFASTSUB_CPUCS, /* Value */ - 0x0000, /* Index */ - local_transfer_buffer, /* address of the transfer buffer */ - 1, /* Length */ - EZTIMEOUT); /* Timeout */ + /* bRequest, "Firmware" */ + ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), USBDUXFASTSUB_FIRMWARE, + VENDOR_DIR_OUT, /* bmRequestType */ + USBDUXFASTSUB_CPUCS, /* Value */ + 0x0000, /* Index */ + /* address of the transfer buffer */ + local_transfer_buffer, + 1, /* Length */ + EZTIMEOUT); /* Timeout */ if (ret < 0) { printk("comedi_: usbduxfast_: control msg failed (start)\n"); return ret; @@ -473,7 +476,8 @@ static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs) /* 7f92 to one */ local_transfer_buffer[0] = 1; - ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), USBDUXFASTSUB_FIRMWARE, /* bRequest, "Firmware" */ + /* bRequest, "Firmware" */ + ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), USBDUXFASTSUB_FIRMWARE, VENDOR_DIR_OUT, /* bmRequestType */ USBDUXFASTSUB_CPUCS, /* Value */ 0x0000, /* Index */ @@ -499,13 +503,15 @@ static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs, printk(KERN_DEBUG " to addr %d, first byte=%d.\n", startAddr, local_transfer_buffer[0]); #endif - ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), USBDUXFASTSUB_FIRMWARE, /* brequest, firmware */ - VENDOR_DIR_OUT, /* bmRequestType */ - startAddr, /* value */ - 0x0000, /* index */ - local_transfer_buffer, /* our local safe buffer */ - len, /* length */ - EZTIMEOUT); /* timeout */ + /* brequest, firmware */ + ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), USBDUXFASTSUB_FIRMWARE, + VENDOR_DIR_OUT, /* bmRequestType */ + startAddr, /* value */ + 0x0000, /* index */ + /* our local safe buffer */ + local_transfer_buffer, + len, /* length */ + EZTIMEOUT); /* timeout */ #ifdef CONFIG_COMEDI_DEBUG printk(KERN_DEBUG "comedi_: usbduxfast: result=%d\n", ret); @@ -1347,7 +1353,7 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev, #define FIRMWARE_MAX_LEN 0x2000 static int firmwareUpload(struct usbduxfastsub_s *usbduxfastsub, - const u8 * firmwareBinary, int sizeFirmware) + const u8 *firmwareBinary, int sizeFirmware) { int ret; uint8_t *fwBuf; -- cgit v1.2.3 From f681d552012bc61dedc12aace8126339fcab8d7e Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Mon, 1 Mar 2010 00:28:44 +0100 Subject: Staging: rt2870: rtusb_data.c: Checkpatch cleanup drivers/staging/rt2870/common/rtusb_data.c:127: ERROR: return is not a function, parentheses are not required drivers/staging/rt2870/common/rtusb_data.c:141: ERROR: return is not a function, parentheses are not required drivers/staging/rt2870/common/rtusb_data.c:154: ERROR: space prohibited before that close parenthesis ')' drivers/staging/rt2870/common/rtusb_data.c:204: ERROR: space prohibited after that '&' (ctx:VxW) Signed-off-by: Andrea Gelmini Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2870/common/rtusb_data.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2870/common/rtusb_data.c b/drivers/staging/rt2870/common/rtusb_data.c index 4583764c78d2..69368862217c 100644 --- a/drivers/staging/rt2870/common/rtusb_data.c +++ b/drivers/staging/rt2870/common/rtusb_data.c @@ -124,7 +124,7 @@ int RTUSBFreeDescriptorRequest(struct rt_rtmp_adapter *pAd, } RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); - return (Status); + return Status; } int RTUSBFreeDescriptorRelease(struct rt_rtmp_adapter *pAd, @@ -138,7 +138,7 @@ int RTUSBFreeDescriptorRelease(struct rt_rtmp_adapter *pAd, pHTTXContext->bCurWriting = FALSE; RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); - return (NDIS_STATUS_SUCCESS); + return NDIS_STATUS_SUCCESS; } BOOLEAN RTUSBNeedQueueBackForAgg(struct rt_rtmp_adapter *pAd, u8 BulkOutPipeId) @@ -151,7 +151,7 @@ BOOLEAN RTUSBNeedQueueBackForAgg(struct rt_rtmp_adapter *pAd, u8 BulkOutPipeId) RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); if ((pHTTXContext->IRPPending == - TRUE) /*&& (pAd->TxSwQueue[BulkOutPipeId].Number == 0) */ ) { + TRUE) /*&& (pAd->TxSwQueue[BulkOutPipeId].Number == 0) */) { if ((pHTTXContext->CurWritePosition < pHTTXContext->ENextBulkOutPosition) && @@ -201,7 +201,7 @@ void RTUSBRejectPendingPackets(struct rt_rtmp_adapter *pAd) for (Index = 0; Index < 4; Index++) { NdisAcquireSpinLock(&pAd->TxSwQueueLock[Index]); while (pAd->TxSwQueue[Index].Head != NULL) { - pQueue = (struct rt_queue_header *)& (pAd->TxSwQueue[Index]); + pQueue = (struct rt_queue_header *)&(pAd->TxSwQueue[Index]); pEntry = RemoveHeadQueue(pQueue); pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); -- cgit v1.2.3 From 2c300f2a65a113440f9fbd0bce7e8d446615fb03 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Mon, 1 Mar 2010 00:28:45 +0100 Subject: Staging: rt2870: rtusb_io.c: Checkpatch cleanup drivers/staging/rt2870/common/rtusb_io.c:27: ERROR: code indent should use tabs where possible drivers/staging/rt2870/common/rtusb_io.c:404: ERROR: while should follow close brace '}' drivers/staging/rt2870/common/rtusb_io.c:459: ERROR: while should follow close brace '}' drivers/staging/rt2870/common/rtusb_io.c:655: ERROR: return is not a function, parentheses are not required drivers/staging/rt2870/common/rtusb_io.c:659: ERROR: return is not a function, parentheses are not required drivers/staging/rt2870/common/rtusb_io.c:669: ERROR: return is not a function, parentheses are not required drivers/staging/rt2870/common/rtusb_io.c:701: ERROR: return is not a function, parentheses are not required drivers/staging/rt2870/common/rtusb_io.c:729: ERROR: return is not a function, parentheses are not required drivers/staging/rt2870/common/rtusb_io.c:739: ERROR: return is not a function, parentheses are not required drivers/staging/rt2870/common/rtusb_io.c:770: ERROR: return is not a function, parentheses are not required drivers/staging/rt2870/common/rtusb_io.c:1412: ERROR: that open brace { should be on the previous line drivers/staging/rt2870/common/rtusb_io.c:1434: ERROR: that open brace { should be on the previous line Signed-off-by: Andrea Gelmini Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2870/common/rtusb_io.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2870/common/rtusb_io.c b/drivers/staging/rt2870/common/rtusb_io.c index cf0d2f5dbc6c..cde38fe7e2e5 100644 --- a/drivers/staging/rt2870/common/rtusb_io.c +++ b/drivers/staging/rt2870/common/rtusb_io.c @@ -24,7 +24,7 @@ * * ************************************************************************* - Module Name: + Module Name: rtusb_io.c Abstract: @@ -400,8 +400,7 @@ int RTUSBWriteBBPRegister(struct rt_rtmp_adapter *pAd, ("RTUSBWriteBBPRegister(BBP_CSR_CFG):retry count=%d!\n", i)); i++; - } - while ((i < RETRY_LIMIT) + } while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); if ((i == RETRY_LIMIT) @@ -455,8 +454,7 @@ int RTUSBWriteRFRegister(struct rt_rtmp_adapter *pAd, u32 Value) ("RTUSBWriteRFRegister(RF_CSR_CFG0):retry count=%d!\n", i)); i++; - } - while ((i < RETRY_LIMIT) + } while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); if ((i == RETRY_LIMIT) @@ -652,11 +650,11 @@ int RTUSBEnqueueCmdFromNdis(struct rt_rtmp_adapter *pAd, } else #endif - return (NDIS_STATUS_RESOURCES); + return NDIS_STATUS_RESOURCES; status = os_alloc_mem(pAd, (u8 **) (&cmdqelmt), sizeof(struct rt_cmdqelmt)); if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL)) - return (NDIS_STATUS_RESOURCES); + return NDIS_STATUS_RESOURCES; cmdqelmt->buffer = NULL; if (pInformationBuffer != NULL) { @@ -666,7 +664,7 @@ int RTUSBEnqueueCmdFromNdis(struct rt_rtmp_adapter *pAd, if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL)) { kfree(cmdqelmt); - return (NDIS_STATUS_RESOURCES); + return NDIS_STATUS_RESOURCES; } else { NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength); @@ -698,7 +696,7 @@ int RTUSBEnqueueCmdFromNdis(struct rt_rtmp_adapter *pAd, } else RTUSBCMDUp(pAd); - return (NDIS_STATUS_SUCCESS); + return NDIS_STATUS_SUCCESS; } /* @@ -726,7 +724,7 @@ int RTUSBEnqueueInternalCmd(struct rt_rtmp_adapter *pAd, status = os_alloc_mem(pAd, (u8 **) & cmdqelmt, sizeof(struct rt_cmdqelmt)); if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL)) - return (NDIS_STATUS_RESOURCES); + return NDIS_STATUS_RESOURCES; NdisZeroMemory(cmdqelmt, sizeof(struct rt_cmdqelmt)); if (InformationBufferLength > 0) { @@ -736,7 +734,7 @@ int RTUSBEnqueueInternalCmd(struct rt_rtmp_adapter *pAd, if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL)) { os_free_mem(pAd, cmdqelmt); - return (NDIS_STATUS_RESOURCES); + return NDIS_STATUS_RESOURCES; } else { NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength); @@ -767,7 +765,7 @@ int RTUSBEnqueueInternalCmd(struct rt_rtmp_adapter *pAd, } else RTUSBCMDUp(pAd); } - return (NDIS_STATUS_SUCCESS); + return NDIS_STATUS_SUCCESS; } /* @@ -1071,7 +1069,7 @@ void CMDHandler(struct rt_rtmp_adapter *pAd) TXRXQ_PCNT, &MACValue); if ((MACValue & 0xf00000 - /*0x800000 */ ) == 0) + /*0x800000 */) == 0) break; Index++; RTMPusecDelay(10000); @@ -1406,15 +1404,13 @@ void CMDHandler(struct rt_rtmp_adapter *pAd) /* All transfers must be aborted or cancelled before attempting to reset the pipe. */ { u32 MACValue; - { /*while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) */ if ((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG (pAd, - fRTMP_ADAPTER_NIC_NOT_EXIST))) - { + fRTMP_ADAPTER_NIC_NOT_EXIST))) { DBGPRINT_RAW (RT_DEBUG_ERROR, ("BulkIn IRP Pending!!!\n")); @@ -1424,7 +1420,6 @@ void CMDHandler(struct rt_rtmp_adapter *pAd) pAd->PendingRx = 0; } } - /* Wait 10ms before reading register. */ RTMPusecDelay(10000); ntStatus = -- cgit v1.2.3 From d24e449762facabfb00e4095247f4f027a73caf3 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Mon, 1 Mar 2010 00:28:46 +0100 Subject: Staging: rt2870:: rtusb_bulk.c: Checkpatch cleanup drivers/staging/rt2870/common/rtusb_bulk.c:45: ERROR: that open brace { should be on the previous line drivers/staging/rt2870/common/rtusb_bulk.c:175: ERROR: space required before the open parenthesis '(' drivers/staging/rt2870/common/rtusb_bulk.c:179: ERROR: space required before the open parenthesis '(' drivers/staging/rt2870/common/rtusb_bulk.c:190: ERROR: "foo * bar" should be "foo *bar" drivers/staging/rt2870/common/rtusb_bulk.c:276: ERROR: space prohibited after that '&' (ctx:VxW) drivers/staging/rt2870/common/rtusb_bulk.c:278: ERROR: space prohibited after that '&' (ctx:WxW) drivers/staging/rt2870/common/rtusb_bulk.c:313: ERROR: space prohibited before that close parenthesis ')' drivers/staging/rt2870/common/rtusb_bulk.c:329: WARNING: __func__ should be used instead of gcc specific __FUNCTION__ drivers/staging/rt2870/common/rtusb_bulk.c:337: ERROR: space prohibited after that '&' (ctx:VxW) drivers/staging/rt2870/common/rtusb_bulk.c:404: WARNING: braces {} are not necessary for single statement blocks drivers/staging/rt2870/common/rtusb_bulk.c:952: WARNING: braces {} are not necessary for single statement blocks drivers/staging/rt2870/common/rtusb_bulk.c:1017: WARNING: braces {} are not necessary for single statement blocks Signed-off-by: Andrea Gelmini Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2870/common/rtusb_bulk.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2870/common/rtusb_bulk.c b/drivers/staging/rt2870/common/rtusb_bulk.c index 379780c72b3c..625b872eccc6 100644 --- a/drivers/staging/rt2870/common/rtusb_bulk.c +++ b/drivers/staging/rt2870/common/rtusb_bulk.c @@ -172,11 +172,11 @@ void RTUSBInitRxDesc(struct rt_rtmp_adapter *pAd, struct rt_rx_context *pRxConte */ #define BULK_OUT_LOCK(pLock, IrqFlags) \ - if(1 /*!(in_interrupt() & 0xffff0000)*/) \ + if (1 /*!(in_interrupt() & 0xffff0000)*/) \ RTMP_IRQ_LOCK((pLock), IrqFlags); #define BULK_OUT_UNLOCK(pLock, IrqFlags) \ - if(1 /*!(in_interrupt() & 0xffff0000)*/) \ + if (1 /*!(in_interrupt() & 0xffff0000)*/) \ RTMP_IRQ_UNLOCK((pLock), IrqFlags); void RTUSBBulkOutDataPacket(struct rt_rtmp_adapter *pAd, @@ -187,7 +187,7 @@ void RTUSBBulkOutDataPacket(struct rt_rtmp_adapter *pAd, PURB pUrb; int ret = 0; struct rt_txinfo *pTxInfo, *pLastTxInfo = NULL; - struct rt_txwi * pTxWI; + struct rt_txwi *pTxWI; unsigned long TmpBulkEndPos, ThisBulkSize; unsigned long IrqFlags = 0, IrqFlags2 = 0; u8 *pWirelessPkt, *pAppendant; @@ -273,9 +273,9 @@ void RTUSBBulkOutDataPacket(struct rt_rtmp_adapter *pAd, } do { - pTxInfo = (struct rt_txinfo *)& pWirelessPkt[TmpBulkEndPos]; + pTxInfo = (struct rt_txinfo *)&pWirelessPkt[TmpBulkEndPos]; pTxWI = - (struct rt_txwi *) & pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE]; + (struct rt_txwi *)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE]; if (pAd->bForcePrintTX == TRUE) DBGPRINT(RT_DEBUG_TRACE, @@ -310,7 +310,7 @@ void RTUSBBulkOutDataPacket(struct rt_rtmp_adapter *pAd, pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; - } else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize & 0xfffff800) != 0)) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0)) */ ) { /* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */ + } else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize & 0xfffff800) != 0)) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0)) */) { /* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */ /* For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. */ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; @@ -326,7 +326,7 @@ void RTUSBBulkOutDataPacket(struct rt_rtmp_adapter *pAd, if (pTxInfo->QSEL != FIFO_EDCA) { DBGPRINT(RT_DEBUG_ERROR, ("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", - __FUNCTION__, pTxInfo->QSEL)); + __func__, pTxInfo->QSEL)); DBGPRINT(RT_DEBUG_ERROR, ("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, @@ -334,7 +334,7 @@ void RTUSBBulkOutDataPacket(struct rt_rtmp_adapter *pAd, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); hex_dump("Wrong QSel Pkt:", - (u8 *)& pWirelessPkt[TmpBulkEndPos], + (u8 *)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition)); } @@ -401,9 +401,8 @@ void RTUSBBulkOutDataPacket(struct rt_rtmp_adapter *pAd, } while (TRUE); /* adjust the pTxInfo->USBDMANextVLD value of last pTxInfo. */ - if (pLastTxInfo) { + if (pLastTxInfo) pLastTxInfo->USBDMANextVLD = 0; - } /* We need to copy SavedPad when following condition matched! @@ -949,9 +948,8 @@ void RTUSBKickBulkOut(struct rt_rtmp_adapter *pAd) if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX) ) { /* 2. PS-Poll frame is next */ - if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL)) { + if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL)) RTUSBBulkOutPsPoll(pAd); - } /* 5. Mlme frame is next */ else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) || (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE)) { @@ -1014,9 +1012,8 @@ void RTUSBKickBulkOut(struct rt_rtmp_adapter *pAd) } } /* 8. No data avaliable */ - else { - - } + else + ; } } -- cgit v1.2.3 From e67fdbc3ed1522c2594bf5040eaaeed5027e8ccb Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Mon, 1 Mar 2010 00:28:47 +0100 Subject: Staging: asus_oled: asus_oled.c: Checkpatch cleanup drivers/staging/asus_oled/asus_oled.c:774: ERROR: code indent should use tabs where possible Signed-off-by: Andrea Gelmini Signed-off-by: Greg Kroah-Hartman --- drivers/staging/asus_oled/asus_oled.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c index 7ebecc92c61b..5b279fb30f3f 100644 --- a/drivers/staging/asus_oled/asus_oled.c +++ b/drivers/staging/asus_oled/asus_oled.c @@ -771,7 +771,7 @@ static struct usb_driver oled_driver = { }; static CLASS_ATTR_STRING(version, S_IRUGO, - ASUS_OLED_UNDERSCORE_NAME " " ASUS_OLED_VERSION); + ASUS_OLED_UNDERSCORE_NAME " " ASUS_OLED_VERSION); static int __init asus_oled_init(void) { -- cgit v1.2.3 From adc6ffc073274770e08e15e65bca4a2ee042170f Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Mon, 1 Mar 2010 00:28:48 +0100 Subject: Staging: otus: hpfwuinit.c: Checkpatch cleanup drivers/staging/otus/hal/hpfwuinit.c:240: ERROR: spaces required around that '=' (ctx:VxV) Signed-off-by: Andrea Gelmini Signed-off-by: Greg Kroah-Hartman --- drivers/staging/otus/hal/hpfwuinit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/otus/hal/hpfwuinit.c b/drivers/staging/otus/hal/hpfwuinit.c index ed80ffafaffc..5d0dccca080c 100644 --- a/drivers/staging/otus/hal/hpfwuinit.c +++ b/drivers/staging/otus/hal/hpfwuinit.c @@ -237,4 +237,4 @@ const u32_t zcFwImage[] = { 0x45485441, 0x38731652, 0x89ACFF91, 0xEE55D178, 0xEE000D0A, }; -const u32_t zcFwImageSize=3508; +const u32_t zcFwImageSize = 3508; -- cgit v1.2.3 From 0637fd67093c9dcad988e79445b262f4a0c5d585 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Mon, 1 Mar 2010 00:28:49 +0100 Subject: Staging: otus: hpfwu.c: Checkpatch cleanup drivers/staging/otus/hal/hpfwu.c:1017: ERROR: spaces required around that '=' (ctx:VxV) Signed-off-by: Andrea Gelmini Signed-off-by: Greg Kroah-Hartman --- drivers/staging/otus/hal/hpfwu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/otus/hal/hpfwu.c b/drivers/staging/otus/hal/hpfwu.c index 2b77cbacc6d6..68fabef180af 100644 --- a/drivers/staging/otus/hal/hpfwu.c +++ b/drivers/staging/otus/hal/hpfwu.c @@ -1014,4 +1014,4 @@ const u32_t zcFwImage[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, }; -const u32_t zcFwImageSize=15936; +const u32_t zcFwImageSize = 15936; -- cgit v1.2.3 From 52628626dfcb996a5d12996a15255fbe970d6e6e Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Mon, 1 Mar 2010 00:28:50 +0100 Subject: Staging: otus: hpfwu_2k.c: Checkpatch cleanup drivers/staging/otus/hal/hpfwu_2k.c:1016: ERROR: spaces required around that '=' (ctx:VxV) Signed-off-by: Andrea Gelmini Signed-off-by: Greg Kroah-Hartman --- drivers/staging/otus/hal/hpfwu_2k.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/otus/hal/hpfwu_2k.c b/drivers/staging/otus/hal/hpfwu_2k.c index 94e2caca5369..b675d6d556b2 100644 --- a/drivers/staging/otus/hal/hpfwu_2k.c +++ b/drivers/staging/otus/hal/hpfwu_2k.c @@ -1013,4 +1013,4 @@ const u32_t zcFwImage[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }; -const u32_t zcFwImageSize=15928; +const u32_t zcFwImageSize = 15928; -- cgit v1.2.3 From ecd9fe1deddaf0cc0b8e6625659ad7e368ab5557 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Mon, 1 Mar 2010 00:28:51 +0100 Subject: Staging: otus: hpani.h: Checkpatch cleanup drivers/staging/otus/hal/hpani.h:102: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpani.h:356: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpani.h:395: ERROR: do not use C99 // comments Signed-off-by: Andrea Gelmini Signed-off-by: Greg Kroah-Hartman --- drivers/staging/otus/hal/hpani.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/otus/hal/hpani.h b/drivers/staging/otus/hal/hpani.h index 96e69af3c685..b89241371ab1 100644 --- a/drivers/staging/otus/hal/hpani.h +++ b/drivers/staging/otus/hal/hpani.h @@ -99,8 +99,8 @@ typedef enum { ZM_HAL_ANI_PHYERR_RESET, /* reset phy error stats */ } ZM_HAL_ANI_CMD; -#define AR_PHY_COUNTMAX (3 << 22) // Max counted before intr -#define ZM_HAL_PROCESS_ANI 0x00000001 /* ANI state setup */ +#define AR_PHY_COUNTMAX (3 << 22) /* Max counted before intr */ +#define ZM_HAL_PROCESS_ANI 0x00000001 /* ANI state setup */ #define ZM_RSSI_DUMMY_MARKER 0x127 /* PHY registers in ar5416, related base and register offsets @@ -353,7 +353,7 @@ typedef enum { #define AR_PHY_CCK_DETECT 0x1C6208 #define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003F #define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0 -#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0 // [12:6] settling time for antenna switch +#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0 /* [12:6] settling time for antenna switch */ #define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6 #define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000 @@ -392,7 +392,6 @@ typedef enum { #define AR_PHY_TPCRG1_PD_GAIN_2_S 18 #define AR_PHY_TPCRG1_PD_GAIN_3 0x00300000 #define AR_PHY_TPCRG1_PD_GAIN_3_S 20 -// #define AR_PHY_ANALOG_SWAP 0xa268 #define AR_PHY_SWAP_ALT_CHAIN 0x00000040 -- cgit v1.2.3 From 979315513e65efd1f4b7f57726d98fea99eb5094 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Mon, 1 Mar 2010 00:28:52 +0100 Subject: Staging: otus: hpfwu_OTUS_RC.c: Checkpatch cleanup drivers/staging/otus/hal/hpfwu_OTUS_RC.c:715: ERROR: spaces required around that '=' (ctx:VxV) Signed-off-by: Andrea Gelmini Signed-off-by: Greg Kroah-Hartman --- drivers/staging/otus/hal/hpfwu_OTUS_RC.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/otus/hal/hpfwu_OTUS_RC.c b/drivers/staging/otus/hal/hpfwu_OTUS_RC.c index 089d3e0ad853..accbec4369f7 100644 --- a/drivers/staging/otus/hal/hpfwu_OTUS_RC.c +++ b/drivers/staging/otus/hal/hpfwu_OTUS_RC.c @@ -712,4 +712,4 @@ const u32_t zcFwImage[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, }; -const u32_t zcFwImageSize=11104; +const u32_t zcFwImageSize = 11104; -- cgit v1.2.3 From 86f3b1a8e601098066222a63f0e17d5fbe7ab5bf Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Mon, 1 Mar 2010 00:28:53 +0100 Subject: Staging: otus: hpfw2.c: Checkpatch cleanup drivers/staging/otus/hal/hpfw2.c:1018: ERROR: spaces required around that '=' (ctx:VxV) Signed-off-by: Andrea Gelmini Signed-off-by: Greg Kroah-Hartman --- drivers/staging/otus/hal/hpfw2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/otus/hal/hpfw2.c b/drivers/staging/otus/hal/hpfw2.c index baceb0299765..17f405b5db17 100644 --- a/drivers/staging/otus/hal/hpfw2.c +++ b/drivers/staging/otus/hal/hpfw2.c @@ -1015,4 +1015,4 @@ const u32_t zcP2FwImage[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }; -const u32_t zcP2FwImageSize=15964; +const u32_t zcP2FwImageSize = 15964; -- cgit v1.2.3 From 91cc53b0c78596a73fa708cceb7313e7168bb146 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Mon, 1 Mar 2010 00:28:54 +0100 Subject: Staging: otus: hpreg.c: Checkpatch cleanup drivers/staging/otus/hal/hpreg.c:33: WARNING: space prohibited between function name and open parenthesis '(' drivers/staging/otus/hal/hpreg.c:33: WARNING: space prohibited between function name and open parenthesis '(' drivers/staging/otus/hal/hpreg.c:38: CHECK: if this code is redundant consider removing it drivers/staging/otus/hal/hpreg.c:81: ERROR: need consistent spacing around '|' (ctx:VxW) drivers/staging/otus/hal/hpreg.c:96: ERROR: Macros with multiple statements should be enclosed in a do - while loop drivers/staging/otus/hal/hpreg.c:98: CHECK: if this code is redundant consider removing it drivers/staging/otus/hal/hpreg.c:275: ERROR: need consistent spacing around '|' (ctx:WxV) drivers/staging/otus/hal/hpreg.c:304: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:362: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:376: ERROR: "foo* bar" should be "foo *bar" drivers/staging/otus/hal/hpreg.c:377: ERROR: "foo* bar" should be "foo *bar" drivers/staging/otus/hal/hpreg.c:402: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:402: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:413: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:413: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:434: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:496: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:497: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:501: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:526: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:529: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:531: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:539: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:539: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:544: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:663: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1335: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1336: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1345: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1345: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1346: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1346: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1347: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1347: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1355: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1355: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1355: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1355: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1355: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1355: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1355: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1355: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1355: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1355: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1355: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1355: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1355: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1355: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1356: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1356: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1356: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1356: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1356: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1356: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1356: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1356: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1356: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1356: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1356: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1356: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1356: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1356: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1357: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1357: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1365: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1365: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1365: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1365: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1365: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1365: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1365: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1365: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1365: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1365: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1365: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1365: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1365: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1365: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1366: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1366: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1366: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1366: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1366: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1366: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1366: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1366: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1366: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1366: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1366: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1366: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1366: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1366: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1367: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1367: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1375: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1375: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1375: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1375: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1375: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1375: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1375: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1375: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1375: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1375: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1375: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1375: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1375: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1375: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1376: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1376: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1376: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1376: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1376: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1376: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1376: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1376: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1376: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1376: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1376: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1376: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1376: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1376: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1377: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1377: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1378: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1378: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1387: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1387: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1388: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1388: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1395: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1395: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1395: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1395: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1395: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1395: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1395: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1395: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1395: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1395: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1395: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1395: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1395: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1395: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1396: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1396: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1396: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1396: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1396: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1396: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1396: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1396: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1396: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1396: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1396: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1396: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1396: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1396: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1397: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1397: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1398: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1398: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1398: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1398: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1405: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1405: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1405: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1405: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1405: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1405: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1405: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1405: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1405: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1405: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1405: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1405: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1405: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1405: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1406: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1406: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1406: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1406: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1406: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1406: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1406: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1406: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1406: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1406: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1406: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1406: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1406: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1406: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1407: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1407: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1408: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1408: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1415: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1415: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1415: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1415: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1416: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1416: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1416: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1416: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1416: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1416: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1432: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1432: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1432: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1435: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1435: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1435: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1436: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1436: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1436: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1442: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1442: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1442: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1445: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1445: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1445: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1446: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1446: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1446: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1455: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1455: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1455: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1455: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1456: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1456: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1456: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1456: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1456: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1456: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1465: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1465: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1465: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1465: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1466: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1466: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1466: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1466: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1466: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1466: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1475: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1475: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1475: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1475: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1476: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1476: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1476: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1476: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1476: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1476: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1476: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1476: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1485: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1485: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1485: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1485: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1485: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1486: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1486: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1486: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1486: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1486: ERROR: space required before that '-' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1557: ERROR: spaces required around that '=' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1558: ERROR: spaces required around that '=' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1560: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1560: ERROR: spaces required around that '=' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1560: ERROR: spaces required around that '=' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1560: ERROR: spaces required around that '<' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1560: ERROR: spaces required around that '&&' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1562: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1568: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1574: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1579: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1590: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1590: ERROR: spaces required around that '=' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1590: ERROR: space required after that ';' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1590: ERROR: spaces required around that '<' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1592: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1594: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1613: ERROR: spaces required around that '=' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1613: ERROR: spaces required around that '<' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1635: ERROR: "foo* bar" should be "foo *bar" drivers/staging/otus/hal/hpreg.c:1639: ERROR: spaces required around that '=' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1639: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1640: ERROR: "foo* bar" should be "foo *bar" drivers/staging/otus/hal/hpreg.c:1643: ERROR: spaces required around that '=' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1647: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1647: WARNING: suspect code indent for conditional statements (8, 8) drivers/staging/otus/hal/hpreg.c:1649: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1652: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1652: WARNING: suspect code indent for conditional statements (8, 8) drivers/staging/otus/hal/hpreg.c:1654: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1657: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1659: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1660: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1662: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1662: ERROR: else should follow close brace '}' drivers/staging/otus/hal/hpreg.c:1664: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1671: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1674: ERROR: spaces required around that '=' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1675: ERROR: spaces required around that '=' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1676: ERROR: spaces required around that '=' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1676: ERROR: space required after that ',' (ctx:VxO) drivers/staging/otus/hal/hpreg.c:1676: ERROR: space required before that '*' (ctx:OxV) drivers/staging/otus/hal/hpreg.c:1676: ERROR: spaces required around that '=' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1678: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1681: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1682: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1682: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1683: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1684: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1685: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1686: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1687: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1690: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1692: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1693: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1694: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1695: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1695: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1696: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1696: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1697: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1697: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1698: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1698: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1699: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1700: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1700: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1701: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1702: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1702: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1703: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1706: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1707: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1708: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1710: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1711: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1712: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1713: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1714: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1714: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1717: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1719: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1720: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1721: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1722: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1722: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1723: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1723: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1724: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1724: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1725: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1725: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1726: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1726: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1727: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1728: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1728: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1729: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1730: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1730: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1731: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1734: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1735: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1735: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1736: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1737: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1738: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1739: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1740: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1743: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1744: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1744: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1745: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1746: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1747: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1748: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1749: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1752: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1755: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1755: WARNING: suspect code indent for conditional statements (16, 20) drivers/staging/otus/hal/hpreg.c:1757: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1759: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1760: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1760: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1761: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1762: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1762: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1763: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1764: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1766: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1766: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1767: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1767: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1767: WARNING: suspect code indent for conditional statements (8, 12) drivers/staging/otus/hal/hpreg.c:1767: ERROR: space prohibited before that close parenthesis ')' drivers/staging/otus/hal/hpreg.c:1768: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1769: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1770: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1772: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1772: ERROR: spaces required around that '=' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1772: ERROR: space required after that ';' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1772: ERROR: spaces required around that '<' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1774: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1774: ERROR: space required after that ',' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1778: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1779: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1780: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1781: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1781: ERROR: spaces required around that '=' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1786: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1786: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1787: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1787: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1787: ERROR: spaces required around that '==' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1788: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1789: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1789: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1789: ERROR: space prohibited after that open parenthesis '(' drivers/staging/otus/hal/hpreg.c:1789: ERROR: space prohibited before that close parenthesis ')' drivers/staging/otus/hal/hpreg.c:1789: ERROR: space required before the open parenthesis '(' drivers/staging/otus/hal/hpreg.c:1790: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1791: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1792: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1793: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1794: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1795: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1796: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1797: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1798: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1799: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1799: WARNING: suspect code indent for conditional statements (40, 44) drivers/staging/otus/hal/hpreg.c:1805: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1807: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1809: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1811: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1814: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1816: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1817: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1820: ERROR: space required before the open parenthesis '(' drivers/staging/otus/hal/hpreg.c:1821: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1826: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1837: CHECK: if this code is redundant consider removing it drivers/staging/otus/hal/hpreg.c:1839: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1840: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1841: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1842: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1843: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1845: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1845: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1845: WARNING: suspect code indent for conditional statements (8, 12) drivers/staging/otus/hal/hpreg.c:1845: ERROR: spaces required around that '=' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1845: ERROR: spaces required around that '<' (ctx:VxV) drivers/staging/otus/hal/hpreg.c:1846: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1847: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1848: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1849: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1850: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1851: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1852: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1853: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1854: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1861: ERROR: "foo* bar" should be "foo *bar" drivers/staging/otus/hal/hpreg.c:1863: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1871: ERROR: "foo* bar" should be "foo *bar" drivers/staging/otus/hal/hpreg.c:1874: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1881: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1883: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1883: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1883: WARNING: suspect code indent for conditional statements (8, 12) drivers/staging/otus/hal/hpreg.c:1884: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1885: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1887: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1887: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1888: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1888: ERROR: "(foo*)" should be "(foo *)" drivers/staging/otus/hal/hpreg.c:1890: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1890: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1892: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1892: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1893: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1894: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1894: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1896: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1897: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1898: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1899: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1904: ERROR: "foo* bar" should be "foo *bar" drivers/staging/otus/hal/hpreg.c:1908: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1909: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1915: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1916: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1917: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1917: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1919: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1920: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1922: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1922: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1923: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1923: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1923: WARNING: suspect code indent for conditional statements (8, 12) drivers/staging/otus/hal/hpreg.c:1924: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1925: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1925: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1926: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1926: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1928: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1930: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1930: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1931: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1932: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1933: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1935: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1935: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1936: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1936: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1937: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1937: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1938: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1938: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1939: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1939: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1940: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1940: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1941: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1941: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1942: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1942: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1943: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1943: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1944: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1944: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1945: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1945: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1946: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1946: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1947: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1947: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1948: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1948: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1949: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1949: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1950: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1950: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1951: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1951: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1952: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1952: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1953: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1953: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1954: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1954: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1955: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1955: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1956: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1956: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1957: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1957: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1958: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1958: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1959: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1959: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1960: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1960: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1961: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1961: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1962: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1962: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1963: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1963: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1964: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1964: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1965: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1965: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1966: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1966: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1967: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1967: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1968: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1968: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1969: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1969: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1970: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1970: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1971: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1971: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1973: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1974: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1976: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:1980: ERROR: "foo* bar" should be "foo *bar" drivers/staging/otus/hal/hpreg.c:1984: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1986: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1986: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:1986: WARNING: suspect code indent for conditional statements (8, 12) drivers/staging/otus/hal/hpreg.c:1987: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1988: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1989: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:1995: ERROR: "foo* bar" should be "foo *bar" drivers/staging/otus/hal/hpreg.c:2003: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2005: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2005: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2005: WARNING: suspect code indent for conditional statements (8, 12) drivers/staging/otus/hal/hpreg.c:2006: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2007: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2008: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2009: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2032: ERROR: "foo* bar" should be "foo *bar" drivers/staging/otus/hal/hpreg.c:2035: ERROR: space required after that close brace '}' drivers/staging/otus/hal/hpreg.c:2039: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2041: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2041: WARNING: suspect code indent for conditional statements (8, 12) drivers/staging/otus/hal/hpreg.c:2042: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2045: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2047: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2048: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2050: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2050: ERROR: else should follow close brace '}' drivers/staging/otus/hal/hpreg.c:2052: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2055: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2057: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2057: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2057: WARNING: suspect code indent for conditional statements (8, 12) drivers/staging/otus/hal/hpreg.c:2058: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2059: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2060: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2061: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2061: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2062: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2063: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2064: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2065: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2066: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2067: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2073: ERROR: "foo* bar" should be "foo *bar" drivers/staging/otus/hal/hpreg.c:2079: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2081: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2081: WARNING: suspect code indent for conditional statements (8, 12) drivers/staging/otus/hal/hpreg.c:2082: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2085: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2085: ERROR: space prohibited after that open parenthesis '(' drivers/staging/otus/hal/hpreg.c:2087: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2087: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2087: WARNING: suspect code indent for conditional statements (8, 12) drivers/staging/otus/hal/hpreg.c:2088: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2089: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2090: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2091: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2093: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2093: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:2094: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2094: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:2096: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2098: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2098: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2098: WARNING: suspect code indent for conditional statements (8, 12) drivers/staging/otus/hal/hpreg.c:2099: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2100: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2101: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2102: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2103: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2105: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2111: ERROR: "foo* bar" should be "foo *bar" drivers/staging/otus/hal/hpreg.c:2117: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2119: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2119: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:2120: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2120: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2120: WARNING: suspect code indent for conditional statements (8, 12) drivers/staging/otus/hal/hpreg.c:2121: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2122: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2123: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2124: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2127: ERROR: return is not a function, parentheses are not required drivers/staging/otus/hal/hpreg.c:2130: ERROR: "foo* bar" should be "foo *bar" drivers/staging/otus/hal/hpreg.c:2140: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2142: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2142: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:2143: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2143: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2143: WARNING: suspect code indent for conditional statements (8, 12) drivers/staging/otus/hal/hpreg.c:2144: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2145: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2146: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2147: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2152: ERROR: return is not a function, parentheses are not required drivers/staging/otus/hal/hpreg.c:2155: ERROR: "foo* bar" should be "foo *bar" drivers/staging/otus/hal/hpreg.c:2160: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2162: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2162: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2162: WARNING: suspect code indent for conditional statements (8, 12) drivers/staging/otus/hal/hpreg.c:2163: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2164: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2165: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2171: ERROR: "foo* bar" should be "foo *bar" drivers/staging/otus/hal/hpreg.c:2181: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2183: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2183: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2183: WARNING: suspect code indent for conditional statements (8, 12) drivers/staging/otus/hal/hpreg.c:2184: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2185: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2185: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2186: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2187: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2187: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2187: WARNING: suspect code indent for conditional statements (16, 20) drivers/staging/otus/hal/hpreg.c:2188: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2189: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2190: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2191: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2192: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2193: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2193: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2193: ERROR: else should follow close brace '}' drivers/staging/otus/hal/hpreg.c:2194: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2195: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2195: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2195: WARNING: suspect code indent for conditional statements (16, 20) drivers/staging/otus/hal/hpreg.c:2196: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2197: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2198: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2199: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2200: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2201: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2212: ERROR: "foo* bar" should be "foo *bar" drivers/staging/otus/hal/hpreg.c:2216: ERROR: that open brace { should be on the previous line drivers/staging/otus/hal/hpreg.c:2218: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2219: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2220: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2221: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2222: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2223: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2224: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2225: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2226: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2227: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2228: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2229: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2230: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2231: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2232: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2233: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2234: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2235: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2235: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:2236: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2238: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2239: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2239: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:2240: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2242: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2243: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2244: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2245: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2246: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2247: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2248: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2249: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2250: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2251: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2252: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2253: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2254: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2255: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2256: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2257: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2258: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2259: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2260: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2260: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:2261: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2263: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2264: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2265: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2266: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2267: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2268: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2269: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2270: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2271: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2272: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2273: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2274: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2275: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2276: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2277: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2278: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2279: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2280: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2281: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2282: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2283: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2284: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2285: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2286: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2287: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2288: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2289: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2290: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2291: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2292: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2293: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2294: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2295: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2296: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2297: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2298: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2299: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2300: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2301: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2302: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2303: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2304: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2305: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2306: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2307: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2308: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2309: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2310: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2311: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2312: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2313: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2314: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2315: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2316: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2317: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2318: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2319: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2320: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2321: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2322: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2323: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2324: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2325: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2326: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2327: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2328: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2329: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2330: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2331: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2332: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2332: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:2333: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2335: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2336: ERROR: code indent should use tabs where possible drivers/staging/otus/hal/hpreg.c:2338: ERROR: do not use C99 // comments drivers/staging/otus/hal/hpreg.c:2343: ERROR: "foo* bar" should be "foo *bar" drivers/staging/otus/hal/hpreg.c:2345: ERROR: "foo* bar" should be "foo *bar" drivers/staging/otus/hal/hpreg.c:2348: ERROR: spaces required around that '=' (ctx:VxV) Signed-off-by: Andrea Gelmini Signed-off-by: Greg Kroah-Hartman --- drivers/staging/otus/hal/hpreg.c | 1586 ++++++++++++++++++-------------------- 1 file changed, 754 insertions(+), 832 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/otus/hal/hpreg.c b/drivers/staging/otus/hal/hpreg.c index 178777c09dbd..da3b77433874 100644 --- a/drivers/staging/otus/hal/hpreg.c +++ b/drivers/staging/otus/hal/hpreg.c @@ -30,7 +30,7 @@ #include "hpusb.h" /* used throughout this file... */ -#define N(a) (sizeof (a) / sizeof (a[0])) +#define N(a) (sizeof(a) / sizeof(a[0])) #define HAL_MODE_11A_TURBO HAL_MODE_108A #define HAL_MODE_11G_TURBO HAL_MODE_108G @@ -78,7 +78,7 @@ enum { }; #define MKK5GHZ_FLAG1 (DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS) -#define MKK5GHZ_FLAG2 (DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS) +#define MKK5GHZ_FLAG2 (DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS) typedef enum { DFS_UNINIT_DOMAIN = 0, /* Uninitialized dfs domain */ @@ -272,7 +272,7 @@ static REG_DMN_PAIR_MAPPING regDomainPairs[] = { /* MKK4 */ {MKK4_MKKB, MKK4, MKKA, MKK5GHZ_FLAG2, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN10 }, {MKK4_MKKA1, MKK4, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN28 }, - {MKK4_MKKA2, MKK4, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK3 |PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN11 }, + {MKK4_MKKA2, MKK4, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN11 }, {MKK4_MKKC, MKK4, MKKC, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN12 }, {MKK4_FCCA, MKK4, FCCA, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN29 }, {MKK4_MKKA, MKK4, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA, CTRY_JAPAN36 }, @@ -301,7 +301,7 @@ static REG_DMN_PAIR_MAPPING regDomainPairs[] = { {MKK8_MKKA2, MKK8, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN23 }, {MKK8_MKKC, MKK8, MKKC, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 , CTRY_JAPAN24 }, - /* MKK9 */ + /* MKK9 */ {MKK9_MKKA, MKK9, MKKA, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN34 }, {MKK9_FCCA, MKK9, FCCA, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN37 }, {MKK9_MKKA1, MKK9, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN38 }, @@ -359,7 +359,7 @@ static REG_DMN_PAIR_MAPPING regDomainPairs[] = { #define COUNTRY_CODE_MASK 0x03ff #define CF_INTERFERENCE (CHANNEL_CW_INT | CHANNEL_RADAR_INT) #define CHANNEL_14 (2484) /* 802.11g operation is not permitted on channel 14 */ -#define IS_11G_CH14(_ch,_cf) \ +#define IS_11G_CH14(_ch, _cf) \ (((_ch) == CHANNEL_14) && ((_cf) == CHANNEL_G)) #define YES TRUE @@ -373,183 +373,183 @@ enum { typedef struct { HAL_CTRY_CODE countryCode; HAL_REG_DOMAIN regDmnEnum; - const char* isoName; - const char* name; + const char *isoName; + const char *name; HAL_BOOL allow11g; HAL_BOOL allow11aTurbo; HAL_BOOL allow11gTurbo; - HAL_BOOL allow11na; /* HT-40 allowed in 5GHz? */ - HAL_BOOL allow11ng; /* HT-40 allowed in 2GHz? */ + HAL_BOOL allow11na; /* HT-40 allowed in 5GHz? */ + HAL_BOOL allow11ng; /* HT-40 allowed in 2GHz? */ u16_t outdoorChanStart; } COUNTRY_CODE_TO_ENUM_RD; static COUNTRY_CODE_TO_ENUM_RD allCountries[] = { - {CTRY_DEBUG, NO_ENUMRD, "DB", "DEBUG", YES, YES, YES, YES, YES, 7000 }, - {CTRY_DEFAULT, DEF_REGDMN, "NA", "NO_COUNTRY_SET", YES, YES, YES, YES, YES, 7000 }, - {CTRY_ALBANIA, NULL1_WORLD, "AL", "ALBANIA", YES, NO, YES, NO, YES, 7000 }, - {CTRY_ALGERIA, NULL1_WORLD, "DZ", "ALGERIA", YES, NO, YES, NO, YES, 7000 }, - {CTRY_ARGENTINA, APL3_WORLD, "AR", "ARGENTINA", YES, NO, NO, NO, NO, 7000 }, - {CTRY_ARMENIA, ETSI4_WORLD, "AM", "ARMENIA", YES, NO, YES, NO, YES, 7000 }, - {CTRY_AUSTRALIA, FCC6_WORLD, "AU", "AUSTRALIA", YES, YES, YES, YES, YES, 7000 }, - {CTRY_AUSTRIA, ETSI2_WORLD, "AT", "AUSTRIA", YES, NO, YES, YES, YES, 7000 }, - {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ", "AZERBAIJAN", YES, YES, YES, YES, YES, 7000 }, - {CTRY_BAHRAIN, APL6_WORLD, "BH", "BAHRAIN", YES, NO, YES, NO, YES, 7000 }, - {CTRY_BELARUS, ETSI1_WORLD, "BY", "BELARUS", YES, NO, YES, YES, YES, 7000 }, - {CTRY_BELGIUM, ETSI1_WORLD, "BE", "BELGIUM", YES, NO, YES, YES, YES, 7000 }, - {CTRY_BELIZE, APL1_ETSIC, "BZ", "BELIZE", YES, YES, YES, YES, YES, 7000 }, - {CTRY_BOLIVIA, APL1_ETSIC, "BO", "BOLVIA", YES, YES, YES, YES, YES, 7000 }, - {CTRY_BRAZIL, FCC3_WORLD, "BR", "BRAZIL", NO, NO, NO, NO, NO, 7000 }, - {CTRY_BRUNEI_DARUSSALAM,APL1_WORLD,"BN", "BRUNEI DARUSSALAM", YES, YES, YES, YES, YES, 7000 }, - {CTRY_BULGARIA, ETSI6_WORLD, "BG", "BULGARIA", YES, NO, YES, YES, YES, 7000 }, - {CTRY_CANADA, FCC6_FCCA, "CA", "CANADA", YES, YES, YES, YES, YES, 7000 }, - {CTRY_CHILE, APL6_WORLD, "CL", "CHILE", YES, YES, YES, YES, YES, 7000 }, - {CTRY_CHINA, APL1_WORLD, "CN", "CHINA", YES, YES, YES, YES, YES, 7000 }, - {CTRY_COLOMBIA, FCC1_FCCA, "CO", "COLOMBIA", YES, NO, YES, NO, YES, 7000 }, - {CTRY_COSTA_RICA, FCC1_WORLD, "CR", "COSTA RICA", YES, NO, YES, NO, YES, 7000 }, - {CTRY_CROATIA, ETSI3_WORLD, "HR", "CROATIA", YES, NO, YES, NO, YES, 7000 }, - {CTRY_CYPRUS, ETSI3_WORLD, "CY", "CYPRUS", YES, YES, YES, YES, YES, 7000 }, - {CTRY_CZECH, ETSI3_WORLD, "CZ", "CZECH REPUBLIC", YES, NO, YES, YES, YES, 7000 }, - {CTRY_DENMARK, ETSI1_WORLD, "DK", "DENMARK", YES, NO, YES, YES, YES, 7000 }, - {CTRY_DOMINICAN_REPUBLIC,FCC1_FCCA,"DO", "DOMINICAN REPUBLIC", YES, YES, YES, YES, YES, 7000 }, - {CTRY_ECUADOR, FCC1_WORLD, "EC", "ECUADOR", YES, NO, NO, NO, YES, 7000 }, - {CTRY_EGYPT, ETSI3_WORLD, "EG", "EGYPT", YES, NO, YES, NO, YES, 7000 }, - {CTRY_EL_SALVADOR, FCC1_WORLD, "SV", "EL SALVADOR", YES, NO, YES, NO, YES, 7000 }, - {CTRY_ESTONIA, ETSI1_WORLD, "EE", "ESTONIA", YES, NO, YES, YES, YES, 7000 }, - {CTRY_FINLAND, ETSI1_WORLD, "FI", "FINLAND", YES, NO, YES, YES, YES, 7000 }, - {CTRY_FRANCE, ETSI1_WORLD, "FR", "FRANCE", YES, NO, YES, YES, YES, 7000 }, - {CTRY_FRANCE2, ETSI3_WORLD, "F2", "FRANCE_RES", YES, NO, YES, YES, YES, 7000 }, - {CTRY_GEORGIA, ETSI4_WORLD, "GE", "GEORGIA", YES, YES, YES, YES, YES, 7000 }, - {CTRY_GERMANY, ETSI1_WORLD, "DE", "GERMANY", YES, NO, YES, YES, YES, 7000 }, - {CTRY_GREECE, ETSI1_WORLD, "GR", "GREECE", YES, NO, YES, YES, YES, 7000 }, - {CTRY_GUATEMALA, FCC1_FCCA, "GT", "GUATEMALA", YES, YES, YES, YES, YES, 7000 }, - {CTRY_HONDURAS, NULL1_WORLD, "HN", "HONDURAS", YES, NO, YES, NO, YES, 7000 }, - {CTRY_HONG_KONG, FCC2_WORLD, "HK", "HONG KONG", YES, YES, YES, YES, YES, 7000 }, - {CTRY_HUNGARY, ETSI4_WORLD, "HU", "HUNGARY", YES, NO, YES, YES, YES, 7000 }, - {CTRY_ICELAND, ETSI1_WORLD, "IS", "ICELAND", YES, NO, YES, YES, YES, 7000 }, - {CTRY_INDIA, APL6_WORLD, "IN", "INDIA", YES, NO, YES, NO, YES, 7000 }, - {CTRY_INDONESIA, APL1_WORLD, "ID", "INDONESIA", YES, NO, YES, NO, YES, 7000 }, - {CTRY_IRAN, APL1_WORLD, "IR", "IRAN", YES, YES, YES, YES, YES, 7000 }, - {CTRY_IRELAND, ETSI1_WORLD, "IE", "IRELAND", YES, NO, YES, YES, YES, 7000 }, - {CTRY_ISRAEL, ETSI3_WORLD, "IL", "ISRAEL", YES, NO, YES, NO, YES, 7000 }, - {CTRY_ISRAEL2, NULL1_ETSIB, "ISR","ISRAEL_RES", YES, NO, YES, NO, YES, 7000 }, - {CTRY_ITALY, ETSI1_WORLD, "IT", "ITALY", YES, NO, YES, YES, YES, 7000 }, - {CTRY_JAMAICA, ETSI1_WORLD, "JM", "JAMAICA", YES, NO, YES, YES, YES, 7000 }, - {CTRY_JAPAN, MKK1_MKKA, "JP", "JAPAN", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN1, MKK1_MKKB, "J1", "JAPAN1", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN2, MKK1_FCCA, "J2", "JAPAN2", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN3, MKK2_MKKA, "J3", "JAPAN3", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN4, MKK1_MKKA1, "J4", "JAPAN4", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN5, MKK1_MKKA2, "J5", "JAPAN5", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN6, MKK1_MKKC, "J6", "JAPAN6", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN7, MKK3_MKKB, "J7", "JAPAN7", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN8, MKK3_MKKA2, "J8", "JAPAN8", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN9, MKK3_MKKC, "J9", "JAPAN9", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN10, MKK4_MKKB, "J10", "JAPAN10", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN11, MKK4_MKKA2, "J11", "JAPAN11", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN12, MKK4_MKKC, "J12", "JAPAN12", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN13, MKK5_MKKB, "J13", "JAPAN13", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN14, MKK5_MKKA2, "J14", "JAPAN14", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN15, MKK5_MKKC, "J15", "JAPAN15", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN16, MKK6_MKKB, "J16", "JAPAN16", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN17, MKK6_MKKA2, "J17", "JAPAN17", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN18, MKK6_MKKC, "J18", "JAPAN18", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN19, MKK7_MKKB, "J19", "JAPAN19", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN20, MKK7_MKKA, "J20", "JAPAN20", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN21, MKK7_MKKC, "J21", "JAPAN21", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN22, MKK8_MKKB, "J22", "JAPAN22", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN23, MKK8_MKKA2, "J23", "JAPAN23", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN24, MKK8_MKKC, "J24", "JAPAN24", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN25, MKK3_MKKA, "J25", "JAPAN25", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN26, MKK3_MKKA1, "J26", "JAPAN26", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN27, MKK3_FCCA, "J27", "JAPAN27", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN28, MKK4_MKKA1, "J28", "JAPAN28", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN29, MKK4_FCCA, "J29", "JAPAN29", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN30, MKK6_MKKA1, "J30", "JAPAN30", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN31, MKK6_FCCA, "J31", "JAPAN31", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN32, MKK7_MKKA1, "J32", "JAPAN32", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN33, MKK7_FCCA, "J33", "JAPAN33", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN34, MKK9_MKKA, "J34", "JAPAN34", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN35, MKK10_MKKA, "J35", "JAPAN35", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN36, MKK4_MKKA, "J36", "JAPAN36", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN37, MKK9_FCCA, "J37", "JAPAN37", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN38, MKK9_MKKA1, "J38", "JAPAN38", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN39, MKK9_MKKC, "J39", "JAPAN39", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN40, MKK10_MKKA2, "J40", "JAPAN40", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN41, MKK10_FCCA, "J41", "JAPAN41", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN42, MKK10_MKKA1, "J42", "JAPAN42", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN43, MKK10_MKKC, "J43", "JAPAN43", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN44, MKK10_MKKA2, "J44", "JAPAN44", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN45, MKK11_MKKA, "J45", "JAPAN45", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN46, MKK11_FCCA, "J46", "JAPAN46", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN47, MKK11_MKKA1, "J47", "JAPAN47", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN48, MKK11_MKKC, "J48", "JAPAN48", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN49, MKK11_MKKA2, "J49", "JAPAN49", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN50, MKK12_MKKA, "J50", "JAPAN50", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN51, MKK12_FCCA, "J51", "JAPAN51", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN52, MKK12_MKKA1, "J52", "JAPAN52", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN53, MKK12_MKKC, "J53", "JAPAN53", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JAPAN54, MKK12_MKKA2, "J54", "JAPAN54", YES, NO, NO, NO, NO, 7000 }, - {CTRY_JORDAN, ETSI2_WORLD, "JO", "JORDAN", YES, NO, YES, NO, YES, 7000 }, - {CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ", "KAZAKHSTAN", YES, NO, YES, NO, YES, 7000 }, - {CTRY_KOREA_NORTH, APL9_WORLD, "KP", "NORTH KOREA", YES, NO, NO, YES, YES, 7000 }, - {CTRY_KOREA_ROC, APL9_WORLD, "KR", "KOREA REPUBLIC", YES, NO, NO, NO, NO, 7000 }, - {CTRY_KOREA_ROC2, APL2_APLD, "K2", "KOREA REPUBLIC2",YES, NO, NO, NO, NO, 7000 }, - {CTRY_KOREA_ROC3, APL9_WORLD, "K3", "KOREA REPUBLIC3",YES, NO, NO, NO, NO, 7000 }, - {CTRY_KUWAIT, NULL1_WORLD, "KW", "KUWAIT", YES, NO, YES, NO, YES, 7000 }, - {CTRY_LATVIA, ETSI1_WORLD, "LV", "LATVIA", YES, NO, YES, YES, YES, 7000 }, - {CTRY_LEBANON, NULL1_WORLD, "LB", "LEBANON", YES, NO, YES, NO, YES, 7000 }, - {CTRY_LIECHTENSTEIN,ETSI1_WORLD, "LI", "LIECHTENSTEIN", YES, NO, YES, YES, YES, 7000 }, - {CTRY_LITHUANIA, ETSI1_WORLD, "LT", "LITHUANIA", YES, NO, YES, YES, YES, 7000 }, - {CTRY_LUXEMBOURG, ETSI1_WORLD, "LU", "LUXEMBOURG", YES, NO, YES, YES, YES, 7000 }, - {CTRY_MACAU, FCC2_WORLD, "MO", "MACAU", YES, YES, YES, YES, YES, 7000 }, - {CTRY_MACEDONIA, NULL1_WORLD, "MK", "MACEDONIA", YES, NO, YES, NO, YES, 7000 }, - {CTRY_MALAYSIA, APL8_WORLD, "MY", "MALAYSIA", NO, NO, NO, NO, NO, 7000 }, - {CTRY_MALTA, ETSI1_WORLD, "MT", "MALTA", YES, NO, YES, YES, YES, 7000 }, - {CTRY_MEXICO, FCC1_FCCA, "MX", "MEXICO", YES, YES, YES, YES, YES, 7000 }, - {CTRY_MONACO, ETSI4_WORLD, "MC", "MONACO", YES, YES, YES, YES, YES, 7000 }, - {CTRY_MOROCCO, NULL1_WORLD, "MA", "MOROCCO", YES, NO, YES, NO, YES, 7000 }, - {CTRY_NETHERLANDS, ETSI1_WORLD, "NL", "NETHERLANDS", YES, NO, YES, YES, YES, 7000 }, - {CTRY_NETHERLANDS_ANT, ETSI1_WORLD, "AN", "NETHERLANDS-ANTILLES", YES, NO, YES, YES, YES, 7000 }, - {CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ", "NEW ZEALAND", YES, NO, YES, NO, YES, 7000 }, - {CTRY_NORWAY, ETSI1_WORLD, "NO", "NORWAY", YES, NO, YES, YES, YES, 7000 }, - {CTRY_OMAN, APL6_WORLD, "OM", "OMAN", YES, NO, YES, NO, YES, 7000 }, - {CTRY_PAKISTAN, NULL1_WORLD, "PK", "PAKISTAN", YES, NO, YES, NO, YES, 7000 }, - {CTRY_PANAMA, FCC1_FCCA, "PA", "PANAMA", YES, YES, YES, YES, YES, 7000 }, - {CTRY_PERU, APL1_WORLD, "PE", "PERU", YES, NO, YES, NO, YES, 7000 }, - {CTRY_PHILIPPINES, APL1_WORLD, "PH", "PHILIPPINES", YES, YES, YES, YES, YES, 7000 }, - {CTRY_POLAND, ETSI1_WORLD, "PL", "POLAND", YES, NO, YES, YES, YES, 7000 }, - {CTRY_PORTUGAL, ETSI1_WORLD, "PT", "PORTUGAL", YES, NO, YES, YES, YES, 7000 }, - {CTRY_PUERTO_RICO, FCC1_FCCA, "PR", "PUERTO RICO", YES, YES, YES, YES, YES, 7000 }, - {CTRY_QATAR, NULL1_WORLD, "QA", "QATAR", YES, NO, YES, NO, YES, 7000 }, - {CTRY_ROMANIA, NULL1_WORLD, "RO", "ROMANIA", YES, NO, YES, NO, YES, 7000 }, - {CTRY_RUSSIA, NULL1_WORLD, "RU", "RUSSIA", YES, NO, YES, NO, YES, 7000 }, - {CTRY_SAUDI_ARABIA,NULL1_WORLD, "SA", "SAUDI ARABIA", YES, NO, YES, NO, YES, 7000 }, - {CTRY_SERBIA_MONT, ETSI1_WORLD, "CS", "SERBIA & MONTENEGRO", YES, NO, YES, YES, YES, 7000 }, - {CTRY_SINGAPORE, APL6_WORLD, "SG", "SINGAPORE", YES, YES, YES, YES, YES, 7000 }, - {CTRY_SLOVAKIA, ETSI1_WORLD, "SK", "SLOVAK REPUBLIC",YES, NO, YES, YES, YES, 7000 }, - {CTRY_SLOVENIA, ETSI1_WORLD, "SI", "SLOVENIA", YES, NO, YES, YES, YES, 7000 }, - {CTRY_SOUTH_AFRICA,FCC3_WORLD, "ZA", "SOUTH AFRICA", YES, NO, YES, NO, YES, 7000 }, - {CTRY_SPAIN, ETSI1_WORLD, "ES", "SPAIN", YES, NO, YES, YES, YES, 7000 }, - {CTRY_SRILANKA, FCC3_WORLD, "LK", "SRI LANKA", YES, NO, YES, NO, YES, 7000 }, - {CTRY_SWEDEN, ETSI1_WORLD, "SE", "SWEDEN", YES, NO, YES, YES, YES, 7000 }, - {CTRY_SWITZERLAND, ETSI1_WORLD, "CH", "SWITZERLAND", YES, NO, YES, YES, YES, 7000 }, - {CTRY_SYRIA, NULL1_WORLD, "SY", "SYRIA", YES, NO, YES, NO, YES, 7000 }, - {CTRY_TAIWAN, APL3_FCCA, "TW", "TAIWAN", YES, YES, YES, YES, YES, 7000 }, - {CTRY_THAILAND, NULL1_WORLD, "TH", "THAILAND", YES, NO, YES, NO, YES, 7000 }, - {CTRY_TRINIDAD_Y_TOBAGO,ETSI4_WORLD,"TT", "TRINIDAD & TOBAGO", YES, NO, YES, NO, YES, 7000 }, - {CTRY_TUNISIA, ETSI3_WORLD, "TN", "TUNISIA", YES, NO, YES, NO, YES, 7000 }, - {CTRY_TURKEY, ETSI3_WORLD, "TR", "TURKEY", YES, NO, YES, NO, YES, 7000 }, - {CTRY_UKRAINE, NULL1_WORLD, "UA", "UKRAINE", YES, NO, YES, NO, YES, 7000 }, - {CTRY_UAE, NULL1_WORLD, "AE", "UNITED ARAB EMIRATES", YES, NO, YES, NO, YES, 7000 }, - {CTRY_UNITED_KINGDOM, ETSI1_WORLD,"GB", "UNITED KINGDOM", YES, NO, YES, NO, YES, 7000 }, - {CTRY_UNITED_STATES, FCC3_FCCA, "US", "UNITED STATES", YES, YES, YES, YES, YES, 5825 }, - {CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS", "UNITED STATES (PUBLIC SAFETY)", YES, YES, YES, YES, YES, 7000 }, - {CTRY_URUGUAY, FCC1_WORLD, "UY", "URUGUAY", YES, NO, YES, NO, YES, 7000 }, - {CTRY_UZBEKISTAN, FCC3_FCCA, "UZ", "UZBEKISTAN", YES, YES, YES, YES, YES, 7000 }, - {CTRY_VENEZUELA, APL2_ETSIC, "VE", "VENEZUELA", YES, NO, YES, NO, YES, 7000 }, - {CTRY_VIET_NAM, NULL1_WORLD, "VN", "VIET NAM", YES, NO, YES, NO, YES, 7000 }, - {CTRY_YEMEN, NULL1_WORLD, "YE", "YEMEN", YES, NO, YES, NO, YES, 7000 }, - {CTRY_ZIMBABWE, NULL1_WORLD, "ZW", "ZIMBABWE", YES, NO, YES, NO, YES, 7000 } + {CTRY_DEBUG, NO_ENUMRD, "DB", "DEBUG", YES, YES, YES, YES, YES, 7000 }, + {CTRY_DEFAULT, DEF_REGDMN, "NA", "NO_COUNTRY_SET", YES, YES, YES, YES, YES, 7000 }, + {CTRY_ALBANIA, NULL1_WORLD, "AL", "ALBANIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_ALGERIA, NULL1_WORLD, "DZ", "ALGERIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_ARGENTINA, APL3_WORLD, "AR", "ARGENTINA", YES, NO, NO, NO, NO, 7000 }, + {CTRY_ARMENIA, ETSI4_WORLD, "AM", "ARMENIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_AUSTRALIA, FCC6_WORLD, "AU", "AUSTRALIA", YES, YES, YES, YES, YES, 7000 }, + {CTRY_AUSTRIA, ETSI2_WORLD, "AT", "AUSTRIA", YES, NO, YES, YES, YES, 7000 }, + {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ", "AZERBAIJAN", YES, YES, YES, YES, YES, 7000 }, + {CTRY_BAHRAIN, APL6_WORLD, "BH", "BAHRAIN", YES, NO, YES, NO, YES, 7000 }, + {CTRY_BELARUS, ETSI1_WORLD, "BY", "BELARUS", YES, NO, YES, YES, YES, 7000 }, + {CTRY_BELGIUM, ETSI1_WORLD, "BE", "BELGIUM", YES, NO, YES, YES, YES, 7000 }, + {CTRY_BELIZE, APL1_ETSIC, "BZ", "BELIZE", YES, YES, YES, YES, YES, 7000 }, + {CTRY_BOLIVIA, APL1_ETSIC, "BO", "BOLVIA", YES, YES, YES, YES, YES, 7000 }, + {CTRY_BRAZIL, FCC3_WORLD, "BR", "BRAZIL", NO, NO, NO, NO, NO, 7000 }, + {CTRY_BRUNEI_DARUSSALAM, APL1_WORLD, "BN", "BRUNEI DARUSSALAM", YES, YES, YES, YES, YES, 7000 }, + {CTRY_BULGARIA, ETSI6_WORLD, "BG", "BULGARIA", YES, NO, YES, YES, YES, 7000 }, + {CTRY_CANADA, FCC6_FCCA, "CA", "CANADA", YES, YES, YES, YES, YES, 7000 }, + {CTRY_CHILE, APL6_WORLD, "CL", "CHILE", YES, YES, YES, YES, YES, 7000 }, + {CTRY_CHINA, APL1_WORLD, "CN", "CHINA", YES, YES, YES, YES, YES, 7000 }, + {CTRY_COLOMBIA, FCC1_FCCA, "CO", "COLOMBIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_COSTA_RICA, FCC1_WORLD, "CR", "COSTA RICA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_CROATIA, ETSI3_WORLD, "HR", "CROATIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_CYPRUS, ETSI3_WORLD, "CY", "CYPRUS", YES, YES, YES, YES, YES, 7000 }, + {CTRY_CZECH, ETSI3_WORLD, "CZ", "CZECH REPUBLIC", YES, NO, YES, YES, YES, 7000 }, + {CTRY_DENMARK, ETSI1_WORLD, "DK", "DENMARK", YES, NO, YES, YES, YES, 7000 }, + {CTRY_DOMINICAN_REPUBLIC, FCC1_FCCA, "DO", "DOMINICAN REPUBLIC", YES, YES, YES, YES, YES, 7000 }, + {CTRY_ECUADOR, FCC1_WORLD, "EC", "ECUADOR", YES, NO, NO, NO, YES, 7000 }, + {CTRY_EGYPT, ETSI3_WORLD, "EG", "EGYPT", YES, NO, YES, NO, YES, 7000 }, + {CTRY_EL_SALVADOR, FCC1_WORLD, "SV", "EL SALVADOR", YES, NO, YES, NO, YES, 7000 }, + {CTRY_ESTONIA, ETSI1_WORLD, "EE", "ESTONIA", YES, NO, YES, YES, YES, 7000 }, + {CTRY_FINLAND, ETSI1_WORLD, "FI", "FINLAND", YES, NO, YES, YES, YES, 7000 }, + {CTRY_FRANCE, ETSI1_WORLD, "FR", "FRANCE", YES, NO, YES, YES, YES, 7000 }, + {CTRY_FRANCE2, ETSI3_WORLD, "F2", "FRANCE_RES", YES, NO, YES, YES, YES, 7000 }, + {CTRY_GEORGIA, ETSI4_WORLD, "GE", "GEORGIA", YES, YES, YES, YES, YES, 7000 }, + {CTRY_GERMANY, ETSI1_WORLD, "DE", "GERMANY", YES, NO, YES, YES, YES, 7000 }, + {CTRY_GREECE, ETSI1_WORLD, "GR", "GREECE", YES, NO, YES, YES, YES, 7000 }, + {CTRY_GUATEMALA, FCC1_FCCA, "GT", "GUATEMALA", YES, YES, YES, YES, YES, 7000 }, + {CTRY_HONDURAS, NULL1_WORLD, "HN", "HONDURAS", YES, NO, YES, NO, YES, 7000 }, + {CTRY_HONG_KONG, FCC2_WORLD, "HK", "HONG KONG", YES, YES, YES, YES, YES, 7000 }, + {CTRY_HUNGARY, ETSI4_WORLD, "HU", "HUNGARY", YES, NO, YES, YES, YES, 7000 }, + {CTRY_ICELAND, ETSI1_WORLD, "IS", "ICELAND", YES, NO, YES, YES, YES, 7000 }, + {CTRY_INDIA, APL6_WORLD, "IN", "INDIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_INDONESIA, APL1_WORLD, "ID", "INDONESIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_IRAN, APL1_WORLD, "IR", "IRAN", YES, YES, YES, YES, YES, 7000 }, + {CTRY_IRELAND, ETSI1_WORLD, "IE", "IRELAND", YES, NO, YES, YES, YES, 7000 }, + {CTRY_ISRAEL, ETSI3_WORLD, "IL", "ISRAEL", YES, NO, YES, NO, YES, 7000 }, + {CTRY_ISRAEL2, NULL1_ETSIB, "ISR", "ISRAEL_RES", YES, NO, YES, NO, YES, 7000 }, + {CTRY_ITALY, ETSI1_WORLD, "IT", "ITALY", YES, NO, YES, YES, YES, 7000 }, + {CTRY_JAMAICA, ETSI1_WORLD, "JM", "JAMAICA", YES, NO, YES, YES, YES, 7000 }, + {CTRY_JAPAN, MKK1_MKKA, "JP", "JAPAN", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN1, MKK1_MKKB, "J1", "JAPAN1", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN2, MKK1_FCCA, "J2", "JAPAN2", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN3, MKK2_MKKA, "J3", "JAPAN3", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN4, MKK1_MKKA1, "J4", "JAPAN4", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN5, MKK1_MKKA2, "J5", "JAPAN5", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN6, MKK1_MKKC, "J6", "JAPAN6", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN7, MKK3_MKKB, "J7", "JAPAN7", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN8, MKK3_MKKA2, "J8", "JAPAN8", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN9, MKK3_MKKC, "J9", "JAPAN9", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN10, MKK4_MKKB, "J10", "JAPAN10", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN11, MKK4_MKKA2, "J11", "JAPAN11", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN12, MKK4_MKKC, "J12", "JAPAN12", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN13, MKK5_MKKB, "J13", "JAPAN13", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN14, MKK5_MKKA2, "J14", "JAPAN14", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN15, MKK5_MKKC, "J15", "JAPAN15", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN16, MKK6_MKKB, "J16", "JAPAN16", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN17, MKK6_MKKA2, "J17", "JAPAN17", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN18, MKK6_MKKC, "J18", "JAPAN18", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN19, MKK7_MKKB, "J19", "JAPAN19", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN20, MKK7_MKKA, "J20", "JAPAN20", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN21, MKK7_MKKC, "J21", "JAPAN21", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN22, MKK8_MKKB, "J22", "JAPAN22", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN23, MKK8_MKKA2, "J23", "JAPAN23", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN24, MKK8_MKKC, "J24", "JAPAN24", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN25, MKK3_MKKA, "J25", "JAPAN25", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN26, MKK3_MKKA1, "J26", "JAPAN26", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN27, MKK3_FCCA, "J27", "JAPAN27", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN28, MKK4_MKKA1, "J28", "JAPAN28", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN29, MKK4_FCCA, "J29", "JAPAN29", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN30, MKK6_MKKA1, "J30", "JAPAN30", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN31, MKK6_FCCA, "J31", "JAPAN31", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN32, MKK7_MKKA1, "J32", "JAPAN32", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN33, MKK7_FCCA, "J33", "JAPAN33", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN34, MKK9_MKKA, "J34", "JAPAN34", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN35, MKK10_MKKA, "J35", "JAPAN35", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN36, MKK4_MKKA, "J36", "JAPAN36", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN37, MKK9_FCCA, "J37", "JAPAN37", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN38, MKK9_MKKA1, "J38", "JAPAN38", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN39, MKK9_MKKC, "J39", "JAPAN39", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN40, MKK10_MKKA2, "J40", "JAPAN40", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN41, MKK10_FCCA, "J41", "JAPAN41", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN42, MKK10_MKKA1, "J42", "JAPAN42", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN43, MKK10_MKKC, "J43", "JAPAN43", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN44, MKK10_MKKA2, "J44", "JAPAN44", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN45, MKK11_MKKA, "J45", "JAPAN45", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN46, MKK11_FCCA, "J46", "JAPAN46", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN47, MKK11_MKKA1, "J47", "JAPAN47", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN48, MKK11_MKKC, "J48", "JAPAN48", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN49, MKK11_MKKA2, "J49", "JAPAN49", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN50, MKK12_MKKA, "J50", "JAPAN50", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN51, MKK12_FCCA, "J51", "JAPAN51", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN52, MKK12_MKKA1, "J52", "JAPAN52", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN53, MKK12_MKKC, "J53", "JAPAN53", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN54, MKK12_MKKA2, "J54", "JAPAN54", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JORDAN, ETSI2_WORLD, "JO", "JORDAN", YES, NO, YES, NO, YES, 7000 }, + {CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ", "KAZAKHSTAN", YES, NO, YES, NO, YES, 7000 }, + {CTRY_KOREA_NORTH, APL9_WORLD, "KP", "NORTH KOREA", YES, NO, NO, YES, YES, 7000 }, + {CTRY_KOREA_ROC, APL9_WORLD, "KR", "KOREA REPUBLIC", YES, NO, NO, NO, NO, 7000 }, + {CTRY_KOREA_ROC2, APL2_APLD, "K2", "KOREA REPUBLIC2", YES, NO, NO, NO, NO, 7000 }, + {CTRY_KOREA_ROC3, APL9_WORLD, "K3", "KOREA REPUBLIC3", YES, NO, NO, NO, NO, 7000 }, + {CTRY_KUWAIT, NULL1_WORLD, "KW", "KUWAIT", YES, NO, YES, NO, YES, 7000 }, + {CTRY_LATVIA, ETSI1_WORLD, "LV", "LATVIA", YES, NO, YES, YES, YES, 7000 }, + {CTRY_LEBANON, NULL1_WORLD, "LB", "LEBANON", YES, NO, YES, NO, YES, 7000 }, + {CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI", "LIECHTENSTEIN", YES, NO, YES, YES, YES, 7000 }, + {CTRY_LITHUANIA, ETSI1_WORLD, "LT", "LITHUANIA", YES, NO, YES, YES, YES, 7000 }, + {CTRY_LUXEMBOURG, ETSI1_WORLD, "LU", "LUXEMBOURG", YES, NO, YES, YES, YES, 7000 }, + {CTRY_MACAU, FCC2_WORLD, "MO", "MACAU", YES, YES, YES, YES, YES, 7000 }, + {CTRY_MACEDONIA, NULL1_WORLD, "MK", "MACEDONIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_MALAYSIA, APL8_WORLD, "MY", "MALAYSIA", NO, NO, NO, NO, NO, 7000 }, + {CTRY_MALTA, ETSI1_WORLD, "MT", "MALTA", YES, NO, YES, YES, YES, 7000 }, + {CTRY_MEXICO, FCC1_FCCA, "MX", "MEXICO", YES, YES, YES, YES, YES, 7000 }, + {CTRY_MONACO, ETSI4_WORLD, "MC", "MONACO", YES, YES, YES, YES, YES, 7000 }, + {CTRY_MOROCCO, NULL1_WORLD, "MA", "MOROCCO", YES, NO, YES, NO, YES, 7000 }, + {CTRY_NETHERLANDS, ETSI1_WORLD, "NL", "NETHERLANDS", YES, NO, YES, YES, YES, 7000 }, + {CTRY_NETHERLANDS_ANT, ETSI1_WORLD, "AN", "NETHERLANDS-ANTILLES", YES, NO, YES, YES, YES, 7000 }, + {CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ", "NEW ZEALAND", YES, NO, YES, NO, YES, 7000 }, + {CTRY_NORWAY, ETSI1_WORLD, "NO", "NORWAY", YES, NO, YES, YES, YES, 7000 }, + {CTRY_OMAN, APL6_WORLD, "OM", "OMAN", YES, NO, YES, NO, YES, 7000 }, + {CTRY_PAKISTAN, NULL1_WORLD, "PK", "PAKISTAN", YES, NO, YES, NO, YES, 7000 }, + {CTRY_PANAMA, FCC1_FCCA, "PA", "PANAMA", YES, YES, YES, YES, YES, 7000 }, + {CTRY_PERU, APL1_WORLD, "PE", "PERU", YES, NO, YES, NO, YES, 7000 }, + {CTRY_PHILIPPINES, APL1_WORLD, "PH", "PHILIPPINES", YES, YES, YES, YES, YES, 7000 }, + {CTRY_POLAND, ETSI1_WORLD, "PL", "POLAND", YES, NO, YES, YES, YES, 7000 }, + {CTRY_PORTUGAL, ETSI1_WORLD, "PT", "PORTUGAL", YES, NO, YES, YES, YES, 7000 }, + {CTRY_PUERTO_RICO, FCC1_FCCA, "PR", "PUERTO RICO", YES, YES, YES, YES, YES, 7000 }, + {CTRY_QATAR, NULL1_WORLD, "QA", "QATAR", YES, NO, YES, NO, YES, 7000 }, + {CTRY_ROMANIA, NULL1_WORLD, "RO", "ROMANIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_RUSSIA, NULL1_WORLD, "RU", "RUSSIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA", "SAUDI ARABIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_SERBIA_MONT, ETSI1_WORLD, "CS", "SERBIA & MONTENEGRO", YES, NO, YES, YES, YES, 7000 }, + {CTRY_SINGAPORE, APL6_WORLD, "SG", "SINGAPORE", YES, YES, YES, YES, YES, 7000 }, + {CTRY_SLOVAKIA, ETSI1_WORLD, "SK", "SLOVAK REPUBLIC", YES, NO, YES, YES, YES, 7000 }, + {CTRY_SLOVENIA, ETSI1_WORLD, "SI", "SLOVENIA", YES, NO, YES, YES, YES, 7000 }, + {CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA", "SOUTH AFRICA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_SPAIN, ETSI1_WORLD, "ES", "SPAIN", YES, NO, YES, YES, YES, 7000 }, + {CTRY_SRILANKA, FCC3_WORLD, "LK", "SRI LANKA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_SWEDEN, ETSI1_WORLD, "SE", "SWEDEN", YES, NO, YES, YES, YES, 7000 }, + {CTRY_SWITZERLAND, ETSI1_WORLD, "CH", "SWITZERLAND", YES, NO, YES, YES, YES, 7000 }, + {CTRY_SYRIA, NULL1_WORLD, "SY", "SYRIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_TAIWAN, APL3_FCCA, "TW", "TAIWAN", YES, YES, YES, YES, YES, 7000 }, + {CTRY_THAILAND, NULL1_WORLD, "TH", "THAILAND", YES, NO, YES, NO, YES, 7000 }, + {CTRY_TRINIDAD_Y_TOBAGO, ETSI4_WORLD, "TT", "TRINIDAD & TOBAGO", YES, NO, YES, NO, YES, 7000 }, + {CTRY_TUNISIA, ETSI3_WORLD, "TN", "TUNISIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_TURKEY, ETSI3_WORLD, "TR", "TURKEY", YES, NO, YES, NO, YES, 7000 }, + {CTRY_UKRAINE, NULL1_WORLD, "UA", "UKRAINE", YES, NO, YES, NO, YES, 7000 }, + {CTRY_UAE, NULL1_WORLD, "AE", "UNITED ARAB EMIRATES", YES, NO, YES, NO, YES, 7000 }, + {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB", "UNITED KINGDOM", YES, NO, YES, NO, YES, 7000 }, + {CTRY_UNITED_STATES, FCC3_FCCA, "US", "UNITED STATES", YES, YES, YES, YES, YES, 5825 }, + {CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS", "UNITED STATES (PUBLIC SAFETY)", YES, YES, YES, YES, YES, 7000 }, + {CTRY_URUGUAY, FCC1_WORLD, "UY", "URUGUAY", YES, NO, YES, NO, YES, 7000 }, + {CTRY_UZBEKISTAN, FCC3_FCCA, "UZ", "UZBEKISTAN", YES, YES, YES, YES, YES, 7000 }, + {CTRY_VENEZUELA, APL2_ETSIC, "VE", "VENEZUELA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_VIET_NAM, NULL1_WORLD, "VN", "VIET NAM", YES, NO, YES, NO, YES, 7000 }, + {CTRY_YEMEN, NULL1_WORLD, "YE", "YEMEN", YES, NO, YES, NO, YES, 7000 }, + {CTRY_ZIMBABWE, NULL1_WORLD, "ZW", "ZIMBABWE", YES, NO, YES, NO, YES, 7000 } }; typedef struct RegDmnFreqBand { @@ -660,7 +660,7 @@ enum { W1_5745_5825, W1_5500_5700, W2_5260_5320, - W2_5180_5240, + W2_5180_5240, W2_5825_5825, }; @@ -1332,8 +1332,8 @@ static REG_DOMAIN regDomains[] = { BMZERO, BMZERO, BMZERO, - BM(F2_2312_2372,F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), - BM(G2_2312_2372,G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(F2_2312_2372, F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(G2_2312_2372, G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO, BMZERO, BMZERO}, @@ -1342,9 +1342,9 @@ static REG_DOMAIN regDomains[] = { BMZERO, BMZERO, BMZERO, - BM(F1_2457_2472,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), - BM(G1_2457_2472,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), - BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(F1_2457_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(G1_2457_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO, BMZERO}, @@ -1352,9 +1352,9 @@ static REG_DOMAIN regDomains[] = { BMZERO, BMZERO, BMZERO, - BM(F1_2432_2442,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), - BM(G1_2432_2442,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), - BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(F1_2432_2442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(G1_2432_2442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO, BMZERO}, @@ -1362,9 +1362,9 @@ static REG_DOMAIN regDomains[] = { BMZERO, BMZERO, BMZERO, - BM(F3_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), - BM(G3_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), - BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(F3_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(G3_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO, BMZERO}, @@ -1372,10 +1372,10 @@ static REG_DOMAIN regDomains[] = { BMZERO, BMZERO, BMZERO, - BM(F1_2412_2462,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), - BM(G1_2412_2462,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), - BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), - BM(NG2_2422_2452,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(F1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(G1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(NG2_2422_2452, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO}, {MKKA, MKK, NO_DFS, PSCAN_MKKA | PSCAN_MKKA_G | PSCAN_MKKA1 | PSCAN_MKKA1_G | PSCAN_MKKA2 | PSCAN_MKKA2_G, DISALLOW_ADHOC_11A_TURB, @@ -1384,36 +1384,36 @@ static REG_DOMAIN regDomains[] = { BMZERO, BM(F2_2412_2462, F1_2467_2472, F2_2484_2484, -1, -1, -1, -1, -1, -1, -1, -1, -1), BM(G2_2412_2462, G1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), - BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), - BM(NG1_2422_2452,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(NG1_2422_2452, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO}, {MKKC, MKK, NO_DFS, NO_PSCAN, NO_REQ, BMZERO, BMZERO, BMZERO, - BM(F2_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), - BM(G2_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), - BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), - BM(NG1_2422_2452,-1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(NG1_2422_2452, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO}, {WORLD, ETSI, NO_DFS, NO_PSCAN, NO_REQ, BMZERO, BMZERO, BMZERO, - BM(F2_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), - BM(G2_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), - BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), - BM(NG1_2422_2452,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(NG1_2422_2452, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO}, {WOR0_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO, - BM(W1_2412_2412,W1_2437_2442,W1_2462_2462,W1_2472_2472,W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, -1, -1), - BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462,WG1_2472_2472,WG1_2417_2432,WG1_2447_2457,WG1_2467_2467, -1, -1, -1, -1, -1), + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, -1, -1), + BM(WG1_2412_2412, WG1_2437_2442, WG1_2462_2462, WG1_2472_2472, WG1_2417_2432, WG1_2447_2457, WG1_2467_2467, -1, -1, -1, -1, -1), BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO, BMZERO}, @@ -1429,21 +1429,21 @@ static REG_DOMAIN regDomains[] = { BMZERO}, {WOR02_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, - BM(W1_5260_5320, W1_5180_5240,W1_5170_5230,W1_5745_5825,W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), + BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO, - BM(W1_2412_2412,W1_2437_2442,W1_2462_2462, W1_2472_2472,W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), - BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462, WG1_2472_2472,WG1_2417_2432, WG1_2447_2457, WG1_2467_2467, -1, -1, -1, -1, -1), + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), + BM(WG1_2412_2412, WG1_2437_2442, WG1_2462_2462, WG1_2472_2472, WG1_2417_2432, WG1_2447_2457, WG1_2467_2467, -1, -1, -1, -1, -1), BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO, BMZERO}, {EU1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, - BM(W1_5260_5320, W1_5180_5240,W1_5170_5230,W1_5745_5825,W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), + BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO, - BM(W1_2412_2412,W1_2437_2442,W1_2462_2462, W2_2472_2472,W1_2417_2432, W1_2447_2457, W2_2467_2467, -1, -1, -1, -1, -1), - BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462, WG2_2472_2472,WG1_2417_2432, WG1_2447_2457, WG2_2467_2467, -1, -1, -1, -1, -1), + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W2_2472_2472, W1_2417_2432, W1_2447_2457, W2_2467_2467, -1, -1, -1, -1, -1), + BM(WG1_2412_2412, WG1_2437_2442, WG1_2462_2462, WG2_2472_2472, WG1_2417_2432, WG1_2447_2457, WG2_2467_2467, -1, -1, -1, -1, -1), BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO, BMZERO}, @@ -1452,8 +1452,8 @@ static REG_DOMAIN regDomains[] = { BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), BMZERO, BMZERO, - BM(W1_2412_2412,W1_2437_2442,W1_2462_2462,W1_2472_2472,W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, -1, -1), - BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462,WG1_2472_2472,WG1_2417_2432,WG1_2447_2457,WG1_2467_2467, -1, -1, -1, -1, -1), + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, -1, -1), + BM(WG1_2412_2412, WG1_2437_2442, WG1_2462_2462, WG1_2472_2472, WG1_2417_2432, WG1_2447_2457, WG1_2467_2467, -1, -1, -1, -1, -1), BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO, BMZERO}, @@ -1462,8 +1462,8 @@ static REG_DOMAIN regDomains[] = { BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO, - BM(W1_2412_2412,W1_2437_2442,W1_2462_2462,W1_2472_2472,W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, -1, -1), - BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462,WG1_2472_2472,WG1_2417_2432,WG1_2447_2457,WG1_2467_2467, -1, -1, -1, -1, -1), + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, -1, -1), + BM(WG1_2412_2412, WG1_2437_2442, WG1_2462_2462, WG1_2472_2472, WG1_2417_2432, WG1_2447_2457, WG1_2467_2467, -1, -1, -1, -1, -1), BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO, BMZERO}, @@ -1472,8 +1472,8 @@ static REG_DOMAIN regDomains[] = { BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1), BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO, - BM(W1_2412_2412,W1_2437_2442,W1_2462_2462,W1_2472_2472,W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), - BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462,WG1_2472_2472,WG1_2417_2432,WG1_2447_2457,WG1_2467_2467,-1, -1, -1, -1, -1), + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), + BM(WG1_2412_2412, WG1_2437_2442, WG1_2462_2462, WG1_2472_2472, WG1_2417_2432, WG1_2447_2457, WG1_2467_2467, -1, -1, -1, -1, -1), BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO, BMZERO}, @@ -1482,8 +1482,8 @@ static REG_DOMAIN regDomains[] = { BM(W2_5260_5320, W2_5180_5240, F2_5745_5805, W2_5825_5825, -1, -1, -1, -1, -1, -1, -1, -1), BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO, - BM(W1_2412_2412,W1_2437_2442,W1_2462_2462, W1_2417_2432,W1_2447_2457,-1, -1, -1, -1, -1, -1, -1), - BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462, WG1_2417_2432,WG1_2447_2457,-1, -1, -1, -1, -1, -1, -1), + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432, W1_2447_2457, -1, -1, -1, -1, -1, -1, -1), + BM(WG1_2412_2412, WG1_2437_2442, WG1_2462_2462, WG1_2417_2432, WG1_2447_2457, -1, -1, -1, -1, -1, -1, -1), BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), BMZERO, BMZERO}, @@ -1554,30 +1554,24 @@ static const struct cmode modes[] = { u8_t GetWmRD(u16_t regionCode, u16_t channelFlag, REG_DOMAIN *rd) { s16_t i, found, regDmn; - u64_t flags=NO_REQ; - REG_DMN_PAIR_MAPPING *regPair=NULL; + u64_t flags = NO_REQ; + REG_DMN_PAIR_MAPPING *regPair = NULL; - for (i=0, found=0; (iregDmn2GHz; flags = regPair->flags2GHz; - } - else - { + } else { regDmn = regPair->regDmn5GHz; flags = regPair->flags5GHz; } @@ -1587,19 +1581,16 @@ u8_t GetWmRD(u16_t regionCode, u16_t channelFlag, REG_DOMAIN *rd) * unitary reg domain of the pair */ - for (i=0;ipscan &= regPair->pscanMask; - rd->flags = (u32_t)flags; + rd->flags = (u32_t)flags; return TRUE; } @@ -1610,7 +1601,7 @@ u8_t isChanBitMaskZero(u64_t *bitmask) { u16_t i; - for (i=0; ihpPrivate; + zmw_get_wlan_dev(dev); + hpPriv = wd->hpPrivate; - zmw_declare_for_critical_section(); + zmw_declare_for_critical_section(); - if (!GetWmRD(regionCode, ~ZM_REG_FLAG_CHANNEL_2GHZ, &rd5GHz)) - { - zm_debug_msg1("couldn't find unitary 5GHz reg domain for Region Code ", regionCode); + if (!GetWmRD(regionCode, ~ZM_REG_FLAG_CHANNEL_2GHZ, &rd5GHz)) { + zm_debug_msg1("couldn't find unitary 5GHz reg domain for Region Code ", regionCode); return; } - if (!GetWmRD(regionCode, ZM_REG_FLAG_CHANNEL_2GHZ, &rd2GHz)) - { - zm_debug_msg1("couldn't find unitary 2GHz reg domain for Region Code ", regionCode); + if (!GetWmRD(regionCode, ZM_REG_FLAG_CHANNEL_2GHZ, &rd2GHz)) { + zm_debug_msg1("couldn't find unitary 2GHz reg domain for Region Code ", regionCode); return; } - if (wd->regulationTable.regionCode == regionCode) - { - zm_debug_msg1("current region code is the same with Region Code ", regionCode); - return; - } - else - { - wd->regulationTable.regionCode = regionCode; - } + if (wd->regulationTable.regionCode == regionCode) { + zm_debug_msg1("current region code is the same with Region Code ", regionCode); + return; + } else + wd->regulationTable.regionCode = regionCode; - next = 0; + next = 0; - zmw_enter_critical_section(dev); + zmw_enter_critical_section(dev); - for (cm = modes; cm < &modes[N(modes)]; cm++) - { + for (cm = modes; cm < &modes[N(modes)]; cm++) { u16_t c; - u64_t *channelBM=NULL; - REG_DOMAIN *rd=NULL; - REG_DMN_FREQ_BAND *fband=NULL,*freqs=NULL; + u64_t *channelBM = NULL; + REG_DOMAIN *rd = NULL; + REG_DMN_FREQ_BAND *fband = NULL, *freqs = NULL; - switch (cm->mode) - { + switch (cm->mode) { case HAL_MODE_TURBO: - //we don't have turbo mode so we disable it - //zm_debug_msg0("CWY - HAL_MODE_TURBO"); - channelBM = NULL; - //rd = &rd5GHz; - //channelBM = rd->chan11a_turbo; - //freqs = ®Dmn5GhzTurboFreq[0]; - //ctl = rd->conformanceTestLimit | CTL_TURBO; + /* we don't have turbo mode so we disable it + //zm_debug_msg0("CWY - HAL_MODE_TURBO"); */ + channelBM = NULL; + /* rd = &rd5GHz; + channelBM = rd->chan11a_turbo; + freqs = ®Dmn5GhzTurboFreq[0]; + ctl = rd->conformanceTestLimit | CTL_TURBO; */ break; case HAL_MODE_11A: - if ((hpPriv->OpFlags & 0x1) != 0) - { - rd = &rd5GHz; - channelBM = rd->chan11a; - freqs = ®Dmn5GhzFreq[0]; - c_lo = 4920; //from channel 184 - c_hi = 5825; //to channel 165 - //ctl = rd->conformanceTestLimit; - //zm_debug_msg2("CWY - HAL_MODE_11A, channelBM = 0x", *channelBM); - } - //else - { - //channelBM = NULL; - } + if ((hpPriv->OpFlags & 0x1) != 0) { + rd = &rd5GHz; + channelBM = rd->chan11a; + freqs = ®Dmn5GhzFreq[0]; + c_lo = 4920; /* from channel 184 */ + c_hi = 5825; /* to channel 165 */ + /* ctl = rd->conformanceTestLimit; + zm_debug_msg2("CWY - HAL_MODE_11A, channelBM = 0x", *channelBM); */ + } + /* else + channelBM = NULL; + */ break; case HAL_MODE_11B: - //Disable 11B mode because it only has difference with 11G in PowerDFS Data, - //and we don't use this now. - //zm_debug_msg0("CWY - HAL_MODE_11B"); + /* Disable 11B mode because it only has difference with 11G in PowerDFS Data, + and we don't use this now. + zm_debug_msg0("CWY - HAL_MODE_11B"); */ channelBM = NULL; - //rd = &rd2GHz; - //channelBM = rd->chan11b; - //freqs = ®Dmn2GhzFreq[0]; - //ctl = rd->conformanceTestLimit | CTL_11B; - //zm_debug_msg2("CWY - HAL_MODE_11B, channelBM = 0x", *channelBM); + /* rd = &rd2GHz; + channelBM = rd->chan11b; + freqs = ®Dmn2GhzFreq[0]; + ctl = rd->conformanceTestLimit | CTL_11B; + zm_debug_msg2("CWY - HAL_MODE_11B, channelBM = 0x", *channelBM); */ break; case HAL_MODE_11G: - if ((hpPriv->OpFlags & 0x2) != 0) - { - rd = &rd2GHz; - channelBM = rd->chan11g; - freqs = ®Dmn2Ghz11gFreq[0]; - c_lo = 2412; //from channel 1 - //c_hi = 2462; //to channel 11 - c_hi = 2472; //to channel 13 - //ctl = rd->conformanceTestLimit | CTL_11G; - //zm_debug_msg2("CWY - HAL_MODE_11G, channelBM = 0x", *channelBM); - } - //else - { - //channelBM = NULL; - } + if ((hpPriv->OpFlags & 0x2) != 0) { + rd = &rd2GHz; + channelBM = rd->chan11g; + freqs = ®Dmn2Ghz11gFreq[0]; + c_lo = 2412; /* from channel 1 */ + /* c_hi = 2462; to channel 11 */ + c_hi = 2472; /* to channel 13 */ + /* ctl = rd->conformanceTestLimit | CTL_11G; */ + /* zm_debug_msg2("CWY - HAL_MODE_11G, channelBM = 0x", *channelBM); */ + } + /* else + channelBM = NULL; + */ break; case HAL_MODE_11G_TURBO: - //we don't have turbo mode so we disable it - //zm_debug_msg0("CWY - HAL_MODE_11G_TURBO"); - channelBM = NULL; - //rd = &rd2GHz; - //channelBM = rd->chan11g_turbo; - //freqs = ®Dmn2Ghz11gTurboFreq[0]; - //ctl = rd->conformanceTestLimit | CTL_108G; + /* we don't have turbo mode so we disable it + zm_debug_msg0("CWY - HAL_MODE_11G_TURBO"); */ + channelBM = NULL; + /* rd = &rd2GHz; + channelBM = rd->chan11g_turbo; + freqs = ®Dmn2Ghz11gTurboFreq[0]; + ctl = rd->conformanceTestLimit | CTL_108G; */ break; case HAL_MODE_11A_TURBO: - //we don't have turbo mode so we disable it - //zm_debug_msg0("CWY - HAL_MODE_11A_TURBO"); - channelBM = NULL; - //rd = &rd5GHz; - //channelBM = rd->chan11a_dyn_turbo; - //freqs = ®Dmn5GhzTurboFreq[0]; - //ctl = rd->conformanceTestLimit | CTL_108G; + /* we don't have turbo mode so we disable it + zm_debug_msg0("CWY - HAL_MODE_11A_TURBO"); */ + channelBM = NULL; + /* rd = &rd5GHz; + channelBM = rd->chan11a_dyn_turbo; + freqs = ®Dmn5GhzTurboFreq[0]; + ctl = rd->conformanceTestLimit | CTL_108G; */ break; default: - zm_debug_msg1("Unkonwn HAL mode ", cm->mode); + zm_debug_msg1("Unkonwn HAL mode ", cm->mode); continue; } - if (channelBM == NULL) - { - //zm_debug_msg0("CWY - channelBM is NULL"); + + if (channelBM == NULL) { + /* zm_debug_msg0("CWY - channelBM is NULL"); */ continue; - } - if (isChanBitMaskZero(channelBM)) - { - //zm_debug_msg0("CWY - BitMask is Zero"); - continue; - } - - // RAY:Is it ok?? - if (freqs == NULL ) - { - continue; - } - - for (b=0;b<64*BMLEN; b++) - { - if (IS_BIT_SET(b,channelBM)) - { + } + + if (isChanBitMaskZero(channelBM)) { + /* zm_debug_msg0("CWY - BitMask is Zero"); */ + continue; + } + + /* RAY:Is it ok?? */ + if (freqs == NULL) + continue; + + for (b = 0 ; b < 64*BMLEN ; b++) { + if (IS_BIT_SET(b, channelBM)) { fband = &freqs[b]; - //zm_debug_msg1("CWY - lowChannel = ", fband->lowChannel); - //zm_debug_msg1("CWY - highChannel = ", fband->highChannel); - //zm_debug_msg1("CWY - channelSep = ", fband->channelSep); - for (c=fband->lowChannel; c <= fband->highChannel; - c += fband->channelSep) - { + /* zm_debug_msg1("CWY - lowChannel = ", fband->lowChannel); + zm_debug_msg1("CWY - highChannel = ", fband->highChannel); + zm_debug_msg1("CWY - channelSep = ", fband->channelSep); */ + for (c = fband->lowChannel; c <= fband->highChannel; + c += fband->channelSep) { ZM_HAL_CHANNEL icv; - //Disable all DFS channel - if ((hpPriv->disableDfsCh==0) || (!(fband->useDfs & rd->dfsMask))) - { - if( fband->channelBW < 20 ) - { - /**************************************************************/ - /* */ - /* Temporary discard channel that BW < 20MHz (5 or 10MHz) */ - /* Our architecture does not implemnt it !!! */ - /* */ - /**************************************************************/ - continue; - } - if ((c >= c_lo) && (c <= c_hi)) - { - icv.channel = c; - icv.channelFlags = cm->flags; - icv.maxRegTxPower = fband->powerDfs; - if (fband->usePassScan & rd->pscan) - icv.channelFlags |= ZM_REG_FLAG_CHANNEL_PASSIVE; - else - icv.channelFlags &= ~ZM_REG_FLAG_CHANNEL_PASSIVE; - if (fband->useDfs & rd->dfsMask) - icv.privFlags = ZM_REG_FLAG_CHANNEL_DFS; - else - icv.privFlags = 0; - - /* For now disable radar for FCC3 */ - if (fband->useDfs & rd->dfsMask & DFS_FCC3) - { - icv.privFlags &= ~ZM_REG_FLAG_CHANNEL_DFS; - icv.privFlags |= ZM_REG_FLAG_CHANNEL_DFS_CLEAR; - } - - if(rd->flags & LIMIT_FRAME_4MS) - icv.privFlags |= ZM_REG_FLAG_CHANNEL_DFS_CLEAR; - - icv.minTxPower = 0; - icv.maxTxPower = 0; - - zm_assert(next < 60); - - wd->regulationTable.allowChannel[next++] = icv; - } + /* Disable all DFS channel */ + if ((hpPriv->disableDfsCh == 0) || (!(fband->useDfs & rd->dfsMask))) { + if (fband->channelBW < 20) { + /**************************************************************/ + /* */ + /* Temporary discard channel that BW < 20MHz (5 or 10MHz) */ + /* Our architecture does not implemnt it !!! */ + /* */ + /**************************************************************/ + continue; + } + if ((c >= c_lo) && (c <= c_hi)) { + icv.channel = c; + icv.channelFlags = cm->flags; + icv.maxRegTxPower = fband->powerDfs; + if (fband->usePassScan & rd->pscan) + icv.channelFlags |= ZM_REG_FLAG_CHANNEL_PASSIVE; + else + icv.channelFlags &= ~ZM_REG_FLAG_CHANNEL_PASSIVE; + if (fband->useDfs & rd->dfsMask) + icv.privFlags = ZM_REG_FLAG_CHANNEL_DFS; + else + icv.privFlags = 0; + + /* For now disable radar for FCC3 */ + if (fband->useDfs & rd->dfsMask & DFS_FCC3) { + icv.privFlags &= ~ZM_REG_FLAG_CHANNEL_DFS; + icv.privFlags |= ZM_REG_FLAG_CHANNEL_DFS_CLEAR; + } + + if (rd->flags & LIMIT_FRAME_4MS) + icv.privFlags |= ZM_REG_FLAG_CHANNEL_DFS_CLEAR; + + icv.minTxPower = 0; + icv.maxTxPower = 0; + + zm_assert(next < 60); + + wd->regulationTable.allowChannel[next++] = icv; + } + } } } } } - } wd->regulationTable.allowChannelCnt = next; - #if 0 - { - /* debug print */ - u32_t i; - DbgPrint("\n-------------------------------------------\n"); - DbgPrint("zfHpGetRegulationTable print all channel info regincode = 0x%x\n", wd->regulationTable.regionCode); - DbgPrint("index channel channelFlags maxRegTxPower privFlags useDFS\n"); - - for (i=0; iregulationTable.allowChannelCnt; i++) - { - DbgPrint("%02d %d %04x %02d %x %x\n", - i, - wd->regulationTable.allowChannel[i].channel, - wd->regulationTable.allowChannel[i].channelFlags, - wd->regulationTable.allowChannel[i].maxRegTxPower, - wd->regulationTable.allowChannel[i].privFlags, - wd->regulationTable.allowChannel[i].privFlags & ZM_REG_FLAG_CHANNEL_DFS); - } - } - #endif - - zmw_leave_critical_section(dev); + #if 0 + { + /* debug print */ + u32_t i; + DbgPrint("\n-------------------------------------------\n"); + DbgPrint("zfHpGetRegulationTable print all channel info regincode = 0x%x\n", wd->regulationTable.regionCode); + DbgPrint("index channel channelFlags maxRegTxPower privFlags useDFS\n"); + + for (i = 0 ; i < wd->regulationTable.allowChannelCnt ; i++) { + DbgPrint("%02d %d %04x %02d %x %x\n", i, + wd->regulationTable.allowChannel[i].channel, + wd->regulationTable.allowChannel[i].channelFlags, + wd->regulationTable.allowChannel[i].maxRegTxPower, + wd->regulationTable.allowChannel[i].privFlags, + wd->regulationTable.allowChannel[i].privFlags & ZM_REG_FLAG_CHANNEL_DFS); + } + } + #endif + + zmw_leave_critical_section(dev); } -void zfHpGetRegulationTablefromRegionCode(zdev_t* dev, u16_t regionCode) +void zfHpGetRegulationTablefromRegionCode(zdev_t *dev, u16_t regionCode) { - u16_t c_lo = 2000, c_hi = 6000; //default channel is all enable - u8_t isoName[3] = {'N', 'A', 0}; + u16_t c_lo = 2000, c_hi = 6000; /* default channel is all enable */ + u8_t isoName[3] = {'N', 'A', 0}; - zfCoreSetIsoName(dev, isoName); + zfCoreSetIsoName(dev, isoName); - zfHpGetRegulationTable(dev, regionCode, c_lo, c_hi); + zfHpGetRegulationTable(dev, regionCode, c_lo, c_hi); } -void zfHpGetRegulationTablefromCountry(zdev_t* dev, u16_t CountryCode) +void zfHpGetRegulationTablefromCountry(zdev_t *dev, u16_t CountryCode) { - u16_t i; - u16_t c_lo = 2000, c_hi = 6000; //default channel is all enable - u16_t RegDomain; - - zmw_get_wlan_dev(dev); + u16_t i; + u16_t c_lo = 2000, c_hi = 6000; /* default channel is all enable */ + u16_t RegDomain; - zmw_declare_for_critical_section(); + zmw_get_wlan_dev(dev); - for (i = 0; i < N(allCountries); i++) - { - if (CountryCode == allCountries[i].countryCode) - { - RegDomain = allCountries[i].regDmnEnum; + zmw_declare_for_critical_section(); - // read the ACU country code from EEPROM - zfCoreSetIsoName(dev, (u8_t*)allCountries[i].isoName); + for (i = 0; i < N(allCountries); i++) { + if (CountryCode == allCountries[i].countryCode) { + RegDomain = allCountries[i].regDmnEnum; - //zm_debug_msg_s("CWY - Country Name = ", allCountries[i].name); + /* read the ACU country code from EEPROM */ + zfCoreSetIsoName(dev, (u8_t *)allCountries[i].isoName); - if (wd->regulationTable.regionCode != RegDomain) - { - //zm_debug_msg0("CWY - Change regulatory table"); + /* zm_debug_msg_s("CWY - Country Name = ", allCountries[i].name); */ - zfHpGetRegulationTable(dev, RegDomain, c_lo, c_hi); - } - return; - } - } - zm_debug_msg1("Invalid CountryCode = ", CountryCode); + if (wd->regulationTable.regionCode != RegDomain) { + /* zm_debug_msg0("CWY - Change regulatory table"); */ + zfHpGetRegulationTable(dev, RegDomain, c_lo, c_hi); + } + return; + } + } + zm_debug_msg1("Invalid CountryCode = ", CountryCode); } -u8_t zfHpGetRegulationTablefromISO(zdev_t* dev, u8_t *countryInfo, u8_t length) +u8_t zfHpGetRegulationTablefromISO(zdev_t *dev, u8_t *countryInfo, u8_t length) { - u16_t i; - u16_t RegDomain; - u16_t c_lo = 2000, c_hi = 6000; //default channel is all enable - //u8_t strLen = 2; - - zmw_get_wlan_dev(dev); - - zmw_declare_for_critical_section(); - - if (countryInfo[4] != 0x20) - { // with (I)ndoor/(O)utdoor info - //strLen = 3; - } - //zm_debug_msg_s("Desired iso name = ", isoName); - for (i = 0; i < N(allCountries); i++) - { - //zm_debug_msg_s("Current iso name = ", allCountries[i].isoName); - if (zfMemoryIsEqual((u8_t *)allCountries[i].isoName, (u8_t *)&countryInfo[2], length-1)) - { - //DbgPrint("Set current iso name = %s\n", allCountries[i].isoName); - //zm_debug_msg0("iso name hit!!"); - - RegDomain = allCountries[i].regDmnEnum; - - if (wd->regulationTable.regionCode != RegDomain) - { - zfHpGetRegulationTable(dev, RegDomain, c_lo, c_hi); - } - - //while (index < (countryInfo[1]+2)) - //{ - // if (countryInfo[index] <= 14) - // { - // /* calculate 2.4GHz low boundary channel frequency */ - // ch = countryInfo[index]; - // if ( ch == 14 ) - // c_lo = ZM_CH_G_14; - // else - // c_lo = ZM_CH_G_1 + (ch - 1) * 5; - // /* calculate 2.4GHz high boundary channel frequency */ - // ch = countryInfo[index] + countryInfo[index + 1] - 1; - // if ( ch == 14 ) - // c_hi = ZM_CH_G_14; - // else - // c_hi = ZM_CH_G_1 + (ch - 1) * 5; - // } - // else - // { - // /* calculate 5GHz low boundary channel frequency */ - // ch = countryInfo[index]; - // if ( (ch >= 184)&&(ch <= 196) ) - // c_lo = 4000 + ch*5; - // else - // c_lo = 5000 + ch*5; - // /* calculate 5GHz high boundary channel frequency */ - // ch = countryInfo[index] + countryInfo[index + 1] - 1; - // if ( (ch >= 184)&&(ch <= 196) ) - // c_hi = 4000 + ch*5; - // else - // c_hi = 5000 + ch*5; - // } - // - // zfHpGetRegulationTable(dev, RegDomain, c_lo, c_hi); - // - // index+=3; - //} - - return 0; - } - } - //zm_debug_msg_s("Invalid iso name = ", &countryInfo[2]); - return 1; + u16_t i; + u16_t RegDomain; + u16_t c_lo = 2000, c_hi = 6000; /* default channel is all enable */ + /* u8_t strLen = 2; */ + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + if (countryInfo[4] != 0x20) { + /* with (I)ndoor/(O)utdoor info + strLen = 3; */ + } + /* zm_debug_msg_s("Desired iso name = ", isoName); */ + for (i = 0; i < N(allCountries); i++) { + /* zm_debug_msg_s("Current iso name = ", allCountries[i].isoName); */ + if (zfMemoryIsEqual((u8_t *)allCountries[i].isoName, (u8_t *)&countryInfo[2], length-1)) { + /* DbgPrint("Set current iso name = %s\n", allCountries[i].isoName); */ + /* zm_debug_msg0("iso name hit!!"); */ + + RegDomain = allCountries[i].regDmnEnum; + + if (wd->regulationTable.regionCode != RegDomain) + zfHpGetRegulationTable(dev, RegDomain, c_lo, c_hi); + /* + while (index < (countryInfo[1]+2)) { + if (countryInfo[index] <= 14) { + // calculate 2.4GHz low boundary channel frequency + ch = countryInfo[index]; + if ( ch == 14 ) + c_lo = ZM_CH_G_14; + else + c_lo = ZM_CH_G_1 + (ch - 1) * 5; + // calculate 2.4GHz high boundary channel frequency + ch = countryInfo[index] + countryInfo[index + 1] - 1; + if ( ch == 14 ) + c_hi = ZM_CH_G_14; + else + c_hi = ZM_CH_G_1 + (ch - 1) * 5; + } else { + // calculate 5GHz low boundary channel frequency + ch = countryInfo[index]; + if ( (ch >= 184)&&(ch <= 196) ) + c_lo = 4000 + ch*5; + else + c_lo = 5000 + ch*5; + // calculate 5GHz high boundary channel frequency + ch = countryInfo[index] + countryInfo[index + 1] - 1; + if ( (ch >= 184)&&(ch <= 196) ) + c_hi = 4000 + ch*5; + else + c_hi = 5000 + ch*5; + } + + zfHpGetRegulationTable(dev, RegDomain, c_lo, c_hi); + + index+=3; + } + */ + return 0; + } + } + /* zm_debug_msg_s("Invalid iso name = ", &countryInfo[2]); */ + return 1; } -const char* zfHpGetisoNamefromregionCode(zdev_t* dev, u16_t regionCode) +const char *zfHpGetisoNamefromregionCode(zdev_t *dev, u16_t regionCode) { - u16_t i; - - for (i = 0; i < N(allCountries); i++) - { - if (allCountries[i].regDmnEnum == regionCode) - { - return allCountries[i].isoName; - } - } - /* no matching item, return default */ - return allCountries[0].isoName; + u16_t i; + + for (i = 0; i < N(allCountries); i++) { + if (allCountries[i].regDmnEnum == regionCode) + return allCountries[i].isoName; + } + /* no matching item, return default */ + return allCountries[0].isoName; } -u16_t zfHpGetRegionCodeFromIsoName(zdev_t* dev, u8_t *countryIsoName) +u16_t zfHpGetRegionCodeFromIsoName(zdev_t *dev, u8_t *countryIsoName) { - u16_t i; - u16_t regionCode; - - /* if no matching item, return default */ - regionCode = DEF_REGDMN; - - for (i = 0; i < N(allCountries); i++) - { - if (zfMemoryIsEqual((u8_t *)allCountries[i].isoName, countryIsoName, 2)) - { - regionCode = allCountries[i].regDmnEnum; - break; - } - } - - return regionCode; + u16_t i; + u16_t regionCode; + + /* if no matching item, return default */ + regionCode = DEF_REGDMN; + + for (i = 0; i < N(allCountries); i++) { + if (zfMemoryIsEqual((u8_t *)allCountries[i].isoName, countryIsoName, 2)) { + regionCode = allCountries[i].regDmnEnum; + break; + } + } + + return regionCode; } /************************************************************************/ @@ -2029,323 +1980,294 @@ u16_t zfHpGetRegionCodeFromIsoName(zdev_t* dev, u8_t *countryIsoName) /* Chao-Wen Yang ZyDAS Technology Corporation 2007.3 */ /* */ /************************************************************************/ -u16_t zfHpDeleteAllowChannel(zdev_t* dev, u16_t freq) +u16_t zfHpDeleteAllowChannel(zdev_t *dev, u16_t freq) { - u16_t i, bandIndex = 0; - u16_t dfs5GBand[][2] = {{5150, 5240}, {5260, 5350}, {5450, 5700}, {5725, 5825}}; - - zmw_get_wlan_dev(dev); - /* Find which band does this frequency belong */ - for (i = 0; i < 4; i++) - { - if ((freq >= dfs5GBand[i][0]) && (freq <= dfs5GBand[i][1])) - bandIndex = i + 1; - } - - if (bandIndex == 0) - { - /* 2.4G, don't care */ - return 0; - } - else - { - bandIndex--; - } - /* Set all channels in this band to passive scan */ - for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) - { - if ((wd->regulationTable.allowChannel[i].channel >= dfs5GBand[bandIndex][0]) && - (wd->regulationTable.allowChannel[i].channel <= dfs5GBand[bandIndex][1])) - { - /* if channel is not passive, set it to be passive and mark it */ - if ((wd->regulationTable.allowChannel[i].channelFlags & - ZM_REG_FLAG_CHANNEL_PASSIVE) == 0) - { - wd->regulationTable.allowChannel[i].channelFlags |= - (ZM_REG_FLAG_CHANNEL_PASSIVE | ZM_REG_FLAG_CHANNEL_CSA); - } - } - } - - return 0; + u16_t i, bandIndex = 0; + u16_t dfs5GBand[][2] = { {5150, 5240}, {5260, 5350}, {5450, 5700}, {5725, 5825} }; + + zmw_get_wlan_dev(dev); + /* Find which band does this frequency belong */ + for (i = 0; i < 4; i++) { + if ((freq >= dfs5GBand[i][0]) && (freq <= dfs5GBand[i][1])) + bandIndex = i + 1; + } + + if (bandIndex == 0) { + /* 2.4G, don't care */ + return 0; + } else + bandIndex--; + /* Set all channels in this band to passive scan */ + for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) { + if ((wd->regulationTable.allowChannel[i].channel >= dfs5GBand[bandIndex][0]) && + (wd->regulationTable.allowChannel[i].channel <= dfs5GBand[bandIndex][1])) { + /* if channel is not passive, set it to be passive and mark it */ + if ((wd->regulationTable.allowChannel[i].channelFlags & + ZM_REG_FLAG_CHANNEL_PASSIVE) == 0) { + wd->regulationTable.allowChannel[i].channelFlags |= + (ZM_REG_FLAG_CHANNEL_PASSIVE | ZM_REG_FLAG_CHANNEL_CSA); + } + } + } + + return 0; } -u16_t zfHpAddAllowChannel(zdev_t* dev, u16_t freq) +u16_t zfHpAddAllowChannel(zdev_t *dev, u16_t freq) { - u16_t i, j, arrayIndex; + u16_t i, j, arrayIndex; - zmw_get_wlan_dev(dev); + zmw_get_wlan_dev(dev); - for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) - { - if (wd->regulationTable.allowChannel[i].channel == freq) - break; - } + for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) { + if (wd->regulationTable.allowChannel[i].channel == freq) + break; + } - if ( i == wd->regulationTable.allowChannelCnt) - { - for (j = 0; j < wd->regulationTable.allowChannelCnt; j++) - { - if (wd->regulationTable.allowChannel[j].channel > freq) - break; - } + if (i == wd->regulationTable.allowChannelCnt) { + for (j = 0; j < wd->regulationTable.allowChannelCnt; j++) { + if (wd->regulationTable.allowChannel[j].channel > freq) + break; + } - //zm_debug_msg1("CWY - add frequency = ", freq); - //zm_debug_msg1("CWY - channel array index = ", j); + /* zm_debug_msg1("CWY - add frequency = ", freq); + zm_debug_msg1("CWY - channel array index = ", j); */ - arrayIndex = j; + arrayIndex = j; - if (arrayIndex < wd->regulationTable.allowChannelCnt) - { - for (j = wd->regulationTable.allowChannelCnt; j > arrayIndex; j--) - wd->regulationTable.allowChannel[j] = wd->regulationTable.allowChannel[j - 1]; - } - wd->regulationTable.allowChannel[arrayIndex].channel = freq; + if (arrayIndex < wd->regulationTable.allowChannelCnt) { + for (j = wd->regulationTable.allowChannelCnt; j > arrayIndex; j--) + wd->regulationTable.allowChannel[j] = wd->regulationTable.allowChannel[j - 1]; + } + wd->regulationTable.allowChannel[arrayIndex].channel = freq; - wd->regulationTable.allowChannelCnt++; - } + wd->regulationTable.allowChannelCnt++; + } - return 0; + return 0; } -u16_t zfHpIsDfsChannelNCS(zdev_t* dev, u16_t freq) +u16_t zfHpIsDfsChannelNCS(zdev_t *dev, u16_t freq) { - u8_t flag = ZM_REG_FLAG_CHANNEL_DFS; - u16_t i; - zmw_get_wlan_dev(dev); - - for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) - { - //DbgPrint("DFS:freq=%d, chan=%d", freq, wd->regulationTable.allowChannel[i].channel); - if (wd->regulationTable.allowChannel[i].channel == freq) - { - flag = wd->regulationTable.allowChannel[i].privFlags; - break; - } - } - - return (flag & (ZM_REG_FLAG_CHANNEL_DFS|ZM_REG_FLAG_CHANNEL_DFS_CLEAR)); + u8_t flag = ZM_REG_FLAG_CHANNEL_DFS; + u16_t i; + zmw_get_wlan_dev(dev); + + for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) { + /* DbgPrint("DFS:freq=%d, chan=%d", freq, wd->regulationTable.allowChannel[i].channel); */ + if (wd->regulationTable.allowChannel[i].channel == freq) { + flag = wd->regulationTable.allowChannel[i].privFlags; + break; } + } + + return flag & (ZM_REG_FLAG_CHANNEL_DFS|ZM_REG_FLAG_CHANNEL_DFS_CLEAR); } -u16_t zfHpIsDfsChannel(zdev_t* dev, u16_t freq) +u16_t zfHpIsDfsChannel(zdev_t *dev, u16_t freq) { - u8_t flag = ZM_REG_FLAG_CHANNEL_DFS; - u16_t i; - zmw_get_wlan_dev(dev); + u8_t flag = ZM_REG_FLAG_CHANNEL_DFS; + u16_t i; + zmw_get_wlan_dev(dev); - zmw_declare_for_critical_section(); + zmw_declare_for_critical_section(); - zmw_enter_critical_section(dev); + zmw_enter_critical_section(dev); - for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) - { - //DbgPrint("DFS:freq=%d, chan=%d", freq, wd->regulationTable.allowChannel[i].channel); - if (wd->regulationTable.allowChannel[i].channel == freq) - { - flag = wd->regulationTable.allowChannel[i].privFlags; - break; - } - } + for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) { + /* DbgPrint("DFS:freq=%d, chan=%d", freq, wd->regulationTable.allowChannel[i].channel); */ + if (wd->regulationTable.allowChannel[i].channel == freq) { + flag = wd->regulationTable.allowChannel[i].privFlags; + break; + } + } - zmw_leave_critical_section(dev); + zmw_leave_critical_section(dev); - return (flag & (ZM_REG_FLAG_CHANNEL_DFS|ZM_REG_FLAG_CHANNEL_DFS_CLEAR)); + return flag & (ZM_REG_FLAG_CHANNEL_DFS|ZM_REG_FLAG_CHANNEL_DFS_CLEAR); } -u16_t zfHpIsAllowedChannel(zdev_t* dev, u16_t freq) +u16_t zfHpIsAllowedChannel(zdev_t *dev, u16_t freq) { - u16_t i; - zmw_get_wlan_dev(dev); - - for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) - { - if (wd->regulationTable.allowChannel[i].channel == freq) - { - return 1; - } - } - - return 0; + u16_t i; + zmw_get_wlan_dev(dev); + + for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) { + if (wd->regulationTable.allowChannel[i].channel == freq) + return 1; + } + + return 0; } -u16_t zfHpFindFirstNonDfsChannel(zdev_t* dev, u16_t aBand) +u16_t zfHpFindFirstNonDfsChannel(zdev_t *dev, u16_t aBand) { - u16_t chan = 2412; - u16_t i; - zmw_get_wlan_dev(dev); - - zmw_declare_for_critical_section(); - - zmw_enter_critical_section(dev); - - for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) - { - if ((wd->regulationTable.allowChannel[i].privFlags & ZM_REG_FLAG_CHANNEL_DFS) != 0) - { - if (aBand) - { - if (wd->regulationTable.allowChannel[i].channel > 3000) - { - chan = wd->regulationTable.allowChannel[i].channel; - break; - } - } - else - { - if (wd->regulationTable.allowChannel[i].channel < 3000) - { - chan = wd->regulationTable.allowChannel[i].channel; - break; - } - } - } - } - - zmw_leave_critical_section(dev); - - return chan; + u16_t chan = 2412; + u16_t i; + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) { + if ((wd->regulationTable.allowChannel[i].privFlags & ZM_REG_FLAG_CHANNEL_DFS) != 0) { + if (aBand) { + if (wd->regulationTable.allowChannel[i].channel > 3000) { + chan = wd->regulationTable.allowChannel[i].channel; + break; + } + } else { + if (wd->regulationTable.allowChannel[i].channel < 3000) { + chan = wd->regulationTable.allowChannel[i].channel; + break; + } + } + } + } + + zmw_leave_critical_section(dev); + + return chan; } /* porting from ACU */ /* save RegulatoryDomain in hpriv */ -u8_t zfHpGetRegulatoryDomain(zdev_t* dev) +u8_t zfHpGetRegulatoryDomain(zdev_t *dev) { - zmw_get_wlan_dev(dev); - - switch (wd->regulationTable.regionCode) - { - case NO_ENUMRD: - return 0; - break; - case FCC1_FCCA: - case FCC1_WORLD: - case FCC4_FCCA: - case FCC5_FCCA: - case FCC2_WORLD: - case FCC2_ETSIC: - case FCC3_FCCA: - case FCC3_WORLD: - case FCC1: - case FCC2: - case FCC3: - case FCC4: - case FCC5: - case FCCA: - return 0x10;//WG_AMERICAS DOT11_REG_DOMAIN_FCC United States - break; - - case FCC2_FCCA: - return 0x20;//DOT11_REG_DOMAIN_DOC Canada - break; - - case ETSI1_WORLD: - case ETSI3_ETSIA: - case ETSI2_WORLD: - case ETSI3_WORLD: - case ETSI4_WORLD: - case ETSI4_ETSIC: - case ETSI5_WORLD: - case ETSI6_WORLD: - case ETSI_RESERVED: - case ETSI1: - case ETSI2: - case ETSI3: - case ETSI4: - case ETSI5: - case ETSI6: - case ETSIA: - case ETSIB: - case ETSIC: - return 0x30;//WG_EMEA DOT11_REG_DOMAIN_ETSI Most of Europe - break; - - case MKK1_MKKA: - case MKK1_MKKB: - case MKK2_MKKA: - case MKK1_FCCA: - case MKK1_MKKA1: - case MKK1_MKKA2: - case MKK1_MKKC: - case MKK3_MKKB: - case MKK3_MKKA2: - case MKK3_MKKC: - case MKK4_MKKB: - case MKK4_MKKA2: - case MKK4_MKKC: - case MKK5_MKKB: - case MKK5_MKKA2: - case MKK5_MKKC: - case MKK6_MKKB: - case MKK6_MKKA2: - case MKK6_MKKC: - case MKK7_MKKB: - case MKK7_MKKA: - case MKK7_MKKC: - case MKK8_MKKB: - case MKK8_MKKA2: - case MKK8_MKKC: - case MKK6_MKKA1: - case MKK6_FCCA: - case MKK7_MKKA1: - case MKK7_FCCA: - case MKK9_FCCA: - case MKK9_MKKA1: - case MKK9_MKKC: - case MKK9_MKKA2: - case MKK10_FCCA: - case MKK10_MKKA1: - case MKK10_MKKC: - case MKK10_MKKA2: - case MKK11_MKKA: - case MKK11_FCCA: - case MKK11_MKKA1: - case MKK11_MKKC: - case MKK11_MKKA2: - case MKK12_MKKA: - case MKK12_FCCA: - case MKK12_MKKA1: - case MKK12_MKKC: - case MKK12_MKKA2: - case MKK3_MKKA: - case MKK3_MKKA1: - case MKK3_FCCA: - case MKK4_MKKA: - case MKK4_MKKA1: - case MKK4_FCCA: - case MKK9_MKKA: - case MKK10_MKKA: - case MKK1: - case MKK2: - case MKK3: - case MKK4: - case MKK5: - case MKK6: - case MKK7: - case MKK8: - case MKK9: - case MKK10: - case MKK11: - case MKK12: - case MKKA: - case MKKC: - return 0x40;//WG_JAPAN DOT11_REG_DOMAIN_MKK Japan - break; - - default: - break; - } - return 0xFF;// Didn't input RegDmn by mean to distinguish by customer + zmw_get_wlan_dev(dev); + + switch (wd->regulationTable.regionCode) { + case NO_ENUMRD: + return 0; + break; + case FCC1_FCCA: + case FCC1_WORLD: + case FCC4_FCCA: + case FCC5_FCCA: + case FCC2_WORLD: + case FCC2_ETSIC: + case FCC3_FCCA: + case FCC3_WORLD: + case FCC1: + case FCC2: + case FCC3: + case FCC4: + case FCC5: + case FCCA: + return 0x10;/* WG_AMERICAS DOT11_REG_DOMAIN_FCC United States */ + break; + + case FCC2_FCCA: + return 0x20;/* DOT11_REG_DOMAIN_DOC Canada */ + break; + + case ETSI1_WORLD: + case ETSI3_ETSIA: + case ETSI2_WORLD: + case ETSI3_WORLD: + case ETSI4_WORLD: + case ETSI4_ETSIC: + case ETSI5_WORLD: + case ETSI6_WORLD: + case ETSI_RESERVED: + case ETSI1: + case ETSI2: + case ETSI3: + case ETSI4: + case ETSI5: + case ETSI6: + case ETSIA: + case ETSIB: + case ETSIC: + return 0x30;/* WG_EMEA DOT11_REG_DOMAIN_ETSI Most of Europe */ + break; + + case MKK1_MKKA: + case MKK1_MKKB: + case MKK2_MKKA: + case MKK1_FCCA: + case MKK1_MKKA1: + case MKK1_MKKA2: + case MKK1_MKKC: + case MKK3_MKKB: + case MKK3_MKKA2: + case MKK3_MKKC: + case MKK4_MKKB: + case MKK4_MKKA2: + case MKK4_MKKC: + case MKK5_MKKB: + case MKK5_MKKA2: + case MKK5_MKKC: + case MKK6_MKKB: + case MKK6_MKKA2: + case MKK6_MKKC: + case MKK7_MKKB: + case MKK7_MKKA: + case MKK7_MKKC: + case MKK8_MKKB: + case MKK8_MKKA2: + case MKK8_MKKC: + case MKK6_MKKA1: + case MKK6_FCCA: + case MKK7_MKKA1: + case MKK7_FCCA: + case MKK9_FCCA: + case MKK9_MKKA1: + case MKK9_MKKC: + case MKK9_MKKA2: + case MKK10_FCCA: + case MKK10_MKKA1: + case MKK10_MKKC: + case MKK10_MKKA2: + case MKK11_MKKA: + case MKK11_FCCA: + case MKK11_MKKA1: + case MKK11_MKKC: + case MKK11_MKKA2: + case MKK12_MKKA: + case MKK12_FCCA: + case MKK12_MKKA1: + case MKK12_MKKC: + case MKK12_MKKA2: + case MKK3_MKKA: + case MKK3_MKKA1: + case MKK3_FCCA: + case MKK4_MKKA: + case MKK4_MKKA1: + case MKK4_FCCA: + case MKK9_MKKA: + case MKK10_MKKA: + case MKK1: + case MKK2: + case MKK3: + case MKK4: + case MKK5: + case MKK6: + case MKK7: + case MKK8: + case MKK9: + case MKK10: + case MKK11: + case MKK12: + case MKKA: + case MKKC: + return 0x40;/* WG_JAPAN DOT11_REG_DOMAIN_MKK Japan */ + break; + + default: + break; + } + return 0xFF; /* Didn't input RegDmn by mean to distinguish by customer */ } - -void zfHpDisableDfsChannel(zdev_t* dev, u8_t disableFlag) +void zfHpDisableDfsChannel(zdev_t *dev, u8_t disableFlag) { - struct zsHpPriv* hpPriv; + struct zsHpPriv *hpPriv; - zmw_get_wlan_dev(dev); - hpPriv=wd->hpPrivate; - hpPriv->disableDfsCh = disableFlag; - return; + zmw_get_wlan_dev(dev); + hpPriv = wd->hpPrivate; + hpPriv->disableDfsCh = disableFlag; + return; } -- cgit v1.2.3 From 46712df6c705d2b6e4189c94b94209847e4931ab Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Mon, 1 Mar 2010 00:28:55 +0100 Subject: Staging: batman-adv: send.c: Checkpatch cleanup drivers/staging/batman-adv/send.c:137: CHECK: multiple assignments should be avoided Signed-off-by: Andrea Gelmini Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/send.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index 2a9fac8c240e..ff7b1f10684f 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -134,7 +134,8 @@ static void send_packet_to_if(struct forw_packet *forw_packet, if (batman_if->if_active != IF_ACTIVE) return; - packet_num = buff_pos = 0; + packet_num = 0; + buff_pos = 0; batman_packet = (struct batman_packet *) (forw_packet->packet_buff); -- cgit v1.2.3 From 289d4e1b17fd1e29e30929cf1941b7d3349d748f Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Mon, 1 Mar 2010 00:28:56 +0100 Subject: Staging: otus: hpfwu_BA.c: Checkpatch cleanup drivers/staging/otus/hal/hpfwu_BA.c:874: ERROR: spaces required around that '=' (ctx:VxV) Signed-off-by: Andrea Gelmini Signed-off-by: Greg Kroah-Hartman --- drivers/staging/otus/hal/hpfwu_BA.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/otus/hal/hpfwu_BA.c b/drivers/staging/otus/hal/hpfwu_BA.c index 0c741571f2b5..f89419b37431 100644 --- a/drivers/staging/otus/hal/hpfwu_BA.c +++ b/drivers/staging/otus/hal/hpfwu_BA.c @@ -871,4 +871,4 @@ const u32_t zcFwImage[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }; -const u32_t zcFwImageSize=13656; +const u32_t zcFwImageSize = 13656; -- cgit v1.2.3 From 588063a10f4e21cd3a2cc693c0c1ebb846ac4ce5 Mon Sep 17 00:00:00 2001 From: Ellwyn Cole Date: Mon, 1 Mar 2010 17:43:50 +0000 Subject: staging: comedi: Fix 80 characters limit and printk issues in skel.c This is a patch to the skel.c file that fixes the 80 characters limit and printk warnings found by the checkpatch.pl tool Signed-off-by: Ellwyn Cole Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/skel.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index aba57d93dd3d..490753b3d904 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -131,7 +131,8 @@ MODULE_DEVICE_TABLE(pci, skel_pci_table); /* this structure is for data unique to this hardware driver. If several hardware drivers keep similar information in this structure, - feel free to suggest moving the variable to the struct comedi_device struct. */ + feel free to suggest moving the variable to the struct comedi_device struct. + */ struct skel_private { int data; @@ -211,7 +212,7 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; - printk("comedi%d: skel: ", dev->minor); + pr_info("comedi%d: skel: ", dev->minor); /* * If you can probe the device to determine what device in a series @@ -282,7 +283,7 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_UNUSED; } - printk("attached\n"); + pr_info("attached\n"); return 0; } @@ -297,7 +298,7 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) */ static int skel_detach(struct comedi_device *dev) { - printk("comedi%d: skel: remove\n", dev->minor); + pr_info("comedi%d: skel: remove\n", dev->minor); return 0; } @@ -336,7 +337,7 @@ static int skel_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, if (i == TIMEOUT) { /* printk() should be used instead of printk() * whenever the code can be called from real-time. */ - printk("timeout\n"); + pr_info("timeout\n"); return -ETIMEDOUT; } @@ -397,7 +398,8 @@ static int skel_ai_cmdtest(struct comedi_device *dev, if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* step 2: make sure trigger sources are unique and mutually compatible + */ /* note that mutual compatibility is not an issue here */ if (cmd->scan_begin_src != TRIG_TIMER && @@ -529,7 +531,7 @@ static int skel_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, int i; int chan = CR_CHAN(insn->chanspec); - printk("skel_ao_winsn\n"); + pr_info("skel_ao_winsn\n"); /* Writing a list of values to an AO channel is probably not * very useful, but that's how the interface is defined. */ for (i = 0; i < insn->n; i++) { @@ -623,6 +625,7 @@ static int skel_dio_insn_config(struct comedi_device *dev, * as necessary. */ COMEDI_INITCLEANUP(driver_skel); -/* If you are writing a PCI driver you should use COMEDI_PCI_INITCLEANUP instead. -*/ +/* If you are writing a PCI driver you should use COMEDI_PCI_INITCLEANUP + * instead. + */ /* COMEDI_PCI_INITCLEANUP(driver_skel, skel_pci_table) */ -- cgit v1.2.3 From 50ee11fe383255db8e5c3307319d470015616f27 Mon Sep 17 00:00:00 2001 From: Bob Beers Date: Thu, 4 Mar 2010 08:40:46 -0500 Subject: staging: Add driver to support wanPMC-CxT1E1 card. Obviously still needs serious attention, but it compiles. Original author: Rick Dobbs Add driver to support wanPMC-CxT1E1 card. This card provides 1-4 ports of T1E1 in PMC form factor. Note, Rick doesn't want his email showing up as the "From:" author, but has given his blessing to have the code included in the kernel tree. Signed-off-by: Bob Beers Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/cxt1e1/Kconfig | 22 + drivers/staging/cxt1e1/Makefile | 19 + drivers/staging/cxt1e1/comet.c | 566 +++++++ drivers/staging/cxt1e1/comet.h | 366 +++++ drivers/staging/cxt1e1/comet_tables.c | 561 +++++++ drivers/staging/cxt1e1/comet_tables.h | 85 + drivers/staging/cxt1e1/functions.c | 366 +++++ drivers/staging/cxt1e1/hwprobe.c | 400 +++++ drivers/staging/cxt1e1/libsbew.h | 581 +++++++ drivers/staging/cxt1e1/linux.c | 1354 ++++++++++++++++ drivers/staging/cxt1e1/musycc.c | 2180 ++++++++++++++++++++++++++ drivers/staging/cxt1e1/musycc.h | 460 ++++++ drivers/staging/cxt1e1/ossiRelease.c | 39 + drivers/staging/cxt1e1/pmc93x6_eeprom.c | 559 +++++++ drivers/staging/cxt1e1/pmc93x6_eeprom.h | 60 + drivers/staging/cxt1e1/pmcc4.h | 155 ++ drivers/staging/cxt1e1/pmcc4_cpld.h | 124 ++ drivers/staging/cxt1e1/pmcc4_defs.h | 82 + drivers/staging/cxt1e1/pmcc4_drv.c | 1855 ++++++++++++++++++++++ drivers/staging/cxt1e1/pmcc4_ioctls.h | 81 + drivers/staging/cxt1e1/pmcc4_private.h | 295 ++++ drivers/staging/cxt1e1/pmcc4_sysdep.h | 62 + drivers/staging/cxt1e1/sbe_bid.h | 61 + drivers/staging/cxt1e1/sbe_promformat.h | 157 ++ drivers/staging/cxt1e1/sbecom_inline_linux.h | 310 ++++ drivers/staging/cxt1e1/sbecrc.c | 137 ++ drivers/staging/cxt1e1/sbeid.c | 217 +++ drivers/staging/cxt1e1/sbeproc.c | 358 +++++ drivers/staging/cxt1e1/sbeproc.h | 52 + drivers/staging/cxt1e1/sbew_ioc.h | 136 ++ 32 files changed, 11703 insertions(+) create mode 100644 drivers/staging/cxt1e1/Kconfig create mode 100644 drivers/staging/cxt1e1/Makefile create mode 100644 drivers/staging/cxt1e1/comet.c create mode 100644 drivers/staging/cxt1e1/comet.h create mode 100644 drivers/staging/cxt1e1/comet_tables.c create mode 100644 drivers/staging/cxt1e1/comet_tables.h create mode 100644 drivers/staging/cxt1e1/functions.c create mode 100644 drivers/staging/cxt1e1/hwprobe.c create mode 100644 drivers/staging/cxt1e1/libsbew.h create mode 100644 drivers/staging/cxt1e1/linux.c create mode 100644 drivers/staging/cxt1e1/musycc.c create mode 100644 drivers/staging/cxt1e1/musycc.h create mode 100644 drivers/staging/cxt1e1/ossiRelease.c create mode 100644 drivers/staging/cxt1e1/pmc93x6_eeprom.c create mode 100644 drivers/staging/cxt1e1/pmc93x6_eeprom.h create mode 100644 drivers/staging/cxt1e1/pmcc4.h create mode 100644 drivers/staging/cxt1e1/pmcc4_cpld.h create mode 100644 drivers/staging/cxt1e1/pmcc4_defs.h create mode 100644 drivers/staging/cxt1e1/pmcc4_drv.c create mode 100644 drivers/staging/cxt1e1/pmcc4_ioctls.h create mode 100644 drivers/staging/cxt1e1/pmcc4_private.h create mode 100644 drivers/staging/cxt1e1/pmcc4_sysdep.h create mode 100644 drivers/staging/cxt1e1/sbe_bid.h create mode 100644 drivers/staging/cxt1e1/sbe_promformat.h create mode 100644 drivers/staging/cxt1e1/sbecom_inline_linux.h create mode 100644 drivers/staging/cxt1e1/sbecrc.c create mode 100644 drivers/staging/cxt1e1/sbeid.c create mode 100644 drivers/staging/cxt1e1/sbeproc.c create mode 100644 drivers/staging/cxt1e1/sbeproc.h create mode 100644 drivers/staging/cxt1e1/sbew_ioc.h (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 7696a664f8a5..8db8632541f1 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -139,5 +139,7 @@ source "drivers/staging/dt3155/Kconfig" source "drivers/staging/crystalhd/Kconfig" +source "drivers/staging/cxt1e1/Kconfig" + endif # !STAGING_EXCLUDE_BUILD endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index ea2e70e2fed4..ab61e2601ffd 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -51,3 +51,4 @@ obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/ obj-$(CONFIG_FB_SM7XX) += sm7xx/ obj-$(CONFIG_DT3155) += dt3155/ obj-$(CONFIG_CRYSTALHD) += crystalhd/ +obj-$(CONFIG_CXT1E1) += cxt1e1/ diff --git a/drivers/staging/cxt1e1/Kconfig b/drivers/staging/cxt1e1/Kconfig new file mode 100644 index 000000000000..68e9b6d973f7 --- /dev/null +++ b/drivers/staging/cxt1e1/Kconfig @@ -0,0 +1,22 @@ +config CXT1E1 + tristate "SBE wanPMC-C[421]E1T1 hardware support" + depends on HDLC && PCI + ---help--- + This driver supports the SBE wanPMC-CxT1E1 1, 2 and 4 port T3 + channelized stream WAN adapter card which contains a HDLC/Transparent + mode controller. + + If you want to compile this driver as a module + say M here and read . + The module will be called 'cxt1e1'. + + If unsure, say N. + +config SBE_PMCC4_NCOMM + bool "SBE PMCC4 NCOMM support" + depends on CXT1E1 + ---help--- + SBE supplies optional support for NCOMM products. + + If you have purchased this optional support you must say Y or M + here to allow the driver to operate with the NCOMM product. diff --git a/drivers/staging/cxt1e1/Makefile b/drivers/staging/cxt1e1/Makefile new file mode 100644 index 000000000000..10020d7b79a8 --- /dev/null +++ b/drivers/staging/cxt1e1/Makefile @@ -0,0 +1,19 @@ +obj-$(CONFIG_CXT1E1) += cxt1e1.o + +EXTRA_CFLAGS += -DSBE_PMCC4_ENABLE +EXTRA_CFLAGS += -DSBE_ISR_TASKLET +EXTRA_CFLAGS += -DSBE_INCLUDE_SYMBOLS + +cxt1e1-objs += \ + ossiRelease.o \ + musycc.o \ + pmcc4_drv.o \ + comet.o \ + linux.o \ + functions.o \ + hwprobe.o \ + sbeproc.o \ + pmc93x6_eeprom.o \ + sbecrc.o \ + comet_tables.o \ + sbeid.o diff --git a/drivers/staging/cxt1e1/comet.c b/drivers/staging/cxt1e1/comet.c new file mode 100644 index 000000000000..b70909967038 --- /dev/null +++ b/drivers/staging/cxt1e1/comet.c @@ -0,0 +1,566 @@ +/* Copyright (C) 2003-2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include "pmcc4_sysdep.h" +#include "sbecom_inline_linux.h" +#include "libsbew.h" +#include "pmcc4.h" +#include "comet.h" +#include "comet_tables.h" + +#ifdef SBE_INCLUDE_SYMBOLS +#define STATIC +#else +#define STATIC static +#endif + + +extern int log_level; + +#define COMET_NUM_SAMPLES 24 /* Number of entries in the waveform table */ +#define COMET_NUM_UNITS 5 /* Number of points per entry in table */ + +/* forward references */ +STATIC void SetPwrLevel (comet_t * comet); +STATIC void WrtRcvEqualizerTbl (ci_t * ci, comet_t * comet, u_int32_t *table); +STATIC void WrtXmtWaveformTbl (ci_t * ci, comet_t * comet, u_int8_t table[COMET_NUM_SAMPLES][COMET_NUM_UNITS]); + + +void *TWV_table[12] = { + TWVLongHaul0DB, TWVLongHaul7_5DB, TWVLongHaul15DB, TWVLongHaul22_5DB, + TWVShortHaul0, TWVShortHaul1, TWVShortHaul2, TWVShortHaul3, TWVShortHaul4, + TWVShortHaul5, + TWV_E1_75Ohm, /** PORT POINT - 75 Ohm not supported **/ + TWV_E1_120Ohm +}; + + +static int +lbo_tbl_lkup (int t1, int lbo) +{ + if ((lbo < CFG_LBO_LH0) || (lbo > CFG_LBO_E120)) /* error switches to + * default */ + { + if (t1) + lbo = CFG_LBO_LH0; /* default T1 waveform table */ + else + lbo = CFG_LBO_E120; /* default E1 waveform table */ + } + return (lbo - 1); /* make index ZERO relative */ +} + + +void +init_comet (void *ci, comet_t * comet, u_int32_t port_mode, int clockmaster, + u_int8_t moreParams) +{ + u_int8_t isT1mode; + u_int8_t tix = CFG_LBO_LH0; /* T1 default */ + + isT1mode = IS_FRAME_ANY_T1 (port_mode); + /* T1 or E1 */ + if (isT1mode) + { + pci_write_32 ((u_int32_t *) &comet->gbl_cfg, 0xa0); /* Select T1 Mode & PIO + * output enabled */ + tix = lbo_tbl_lkup (isT1mode, CFG_LBO_LH0); /* default T1 waveform + * table */ + } else + { + pci_write_32 ((u_int32_t *) &comet->gbl_cfg, 0x81); /* Select E1 Mode & PIO + * output enabled */ + tix = lbo_tbl_lkup (isT1mode, CFG_LBO_E120); /* default E1 waveform + * table */ + } + + if (moreParams & CFG_LBO_MASK) + tix = lbo_tbl_lkup (isT1mode, moreParams & CFG_LBO_MASK); /* dial-in requested + * waveform table */ + + /* Tx line Intfc cfg ** Set for analog & no special patterns */ + pci_write_32 ((u_int32_t *) &comet->tx_line_cfg, 0x00); /* Transmit Line + * Interface Config. */ + + /* master test ** Ignore Test settings for now */ + pci_write_32 ((u_int32_t *) &comet->mtest, 0x00); /* making sure it's + * Default value */ + + /* Turn on Center (CENT) and everything else off */ + pci_write_32 ((u_int32_t *) &comet->rjat_cfg, 0x10); /* RJAT cfg */ + /* Set Jitter Attenuation to recommend T1 values */ + if (isT1mode) + { + pci_write_32 ((u_int32_t *) &comet->rjat_n1clk, 0x2F); /* RJAT Divider N1 + * Control */ + pci_write_32 ((u_int32_t *) &comet->rjat_n2clk, 0x2F); /* RJAT Divider N2 + * Control */ + } else + { + pci_write_32 ((u_int32_t *) &comet->rjat_n1clk, 0xFF); /* RJAT Divider N1 + * Control */ + pci_write_32 ((u_int32_t *) &comet->rjat_n2clk, 0xFF); /* RJAT Divider N2 + * Control */ + } + + /* Turn on Center (CENT) and everything else off */ + pci_write_32 ((u_int32_t *) &comet->tjat_cfg, 0x10); /* TJAT Config. */ + + /* Do not bypass jitter attenuation and bypass elastic store */ + pci_write_32 ((u_int32_t *) &comet->rx_opt, 0x00); /* rx opts */ + + /* TJAT ctrl & TJAT divider ctrl */ + /* Set Jitter Attenuation to recommended T1 values */ + if (isT1mode) + { + pci_write_32 ((u_int32_t *) &comet->tjat_n1clk, 0x2F); /* TJAT Divider N1 + * Control */ + pci_write_32 ((u_int32_t *) &comet->tjat_n2clk, 0x2F); /* TJAT Divider N2 + * Control */ + } else + { + pci_write_32 ((u_int32_t *) &comet->tjat_n1clk, 0xFF); /* TJAT Divider N1 + * Control */ + pci_write_32 ((u_int32_t *) &comet->tjat_n2clk, 0xFF); /* TJAT Divider N2 + * Control */ + } + + /* 1c: rx ELST cfg 20: tx ELST cfg 28&38: rx&tx data link ctrl */ + if (isT1mode) + { /* Select 193-bit frame format */ + pci_write_32 ((u_int32_t *) &comet->rx_elst_cfg, 0x00); + pci_write_32 ((u_int32_t *) &comet->tx_elst_cfg, 0x00); + } else + { /* Select 256-bit frame format */ + pci_write_32 ((u_int32_t *) &comet->rx_elst_cfg, 0x03); + pci_write_32 ((u_int32_t *) &comet->tx_elst_cfg, 0x03); + pci_write_32 ((u_int32_t *) &comet->rxce1_ctl, 0x00); /* disable T1 data link + * receive */ + pci_write_32 ((u_int32_t *) &comet->txci1_ctl, 0x00); /* disable T1 data link + * transmit */ + } + + /* the following is a default value */ + /* Enable 8 out of 10 validation */ + pci_write_32 ((u_int32_t *) &comet->t1_rboc_ena, 0x00); /* t1RBOC + * enable(BOC:BitOriented + * Code) */ + if (isT1mode) + { + + /* IBCD cfg: aka Inband Code Detection ** loopback code length set to */ + pci_write_32 ((u_int32_t *) &comet->ibcd_cfg, 0x04); /* 6 bit down, 5 bit up + * (assert) */ + pci_write_32 ((u_int32_t *) &comet->ibcd_act, 0x08); /* line loopback + * activate pattern */ + pci_write_32 ((u_int32_t *) &comet->ibcd_deact, 0x24); /* deactivate code + * pattern (i.e.001) */ + } + /* 10: CDRC cfg 28&38: rx&tx data link 1 ctrl 48: t1 frmr cfg */ + /* 50: SIGX cfg, COSS (change of signaling state) 54: XBAS cfg */ + /* 60: t1 ALMI cfg */ + /* Configure Line Coding */ + + switch (port_mode) + { + case CFG_FRAME_SF: /* 1 - T1 B8ZS */ + pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0); + pci_write_32 ((u_int32_t *) &comet->t1_frmr_cfg, 0); + pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0); + pci_write_32 ((u_int32_t *) &comet->t1_xbas_cfg, 0x20); /* 5:B8ZS */ + pci_write_32 ((u_int32_t *) &comet->t1_almi_cfg, 0); + break; + case CFG_FRAME_ESF: /* 2 - T1 B8ZS */ + pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0); + pci_write_32 ((u_int32_t *) &comet->rxce1_ctl, 0x20); /* Bit 5: T1 DataLink + * Enable */ + pci_write_32 ((u_int32_t *) &comet->txci1_ctl, 0x20); /* 5: T1 DataLink Enable */ + pci_write_32 ((u_int32_t *) &comet->t1_frmr_cfg, 0x30); /* 4:ESF 5:ESFFA */ + pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0x04); /* 2:ESF */ + pci_write_32 ((u_int32_t *) &comet->t1_xbas_cfg, 0x30); /* 4:ESF 5:B8ZS */ + pci_write_32 ((u_int32_t *) &comet->t1_almi_cfg, 0x10); /* 4:ESF */ + break; + case CFG_FRAME_E1PLAIN: /* 3 - HDB3 */ + pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0); + pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0); + pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0); + pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0x40); + break; + case CFG_FRAME_E1CAS: /* 4 - HDB3 */ + pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0); + pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0); + pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0x60); + pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0); + break; + case CFG_FRAME_E1CRC: /* 5 - HDB3 */ + pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0); + pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0); + pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0x10); + pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0xc2); + break; + case CFG_FRAME_E1CRC_CAS: /* 6 - HDB3 */ + pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0); + pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0); + pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0x70); + pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0x82); + break; + case CFG_FRAME_SF_AMI: /* 7 - T1 AMI */ + pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0x80); /* Enable AMI Line + * Decoding */ + pci_write_32 ((u_int32_t *) &comet->t1_frmr_cfg, 0); + pci_write_32 ((u_int32_t *) &comet->t1_xbas_cfg, 0); + pci_write_32 ((u_int32_t *) &comet->t1_almi_cfg, 0); + pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0); + break; + case CFG_FRAME_ESF_AMI: /* 8 - T1 AMI */ + pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0x80); /* Enable AMI Line + * Decoding */ + pci_write_32 ((u_int32_t *) &comet->rxce1_ctl, 0x20); /* 5: T1 DataLink Enable */ + pci_write_32 ((u_int32_t *) &comet->txci1_ctl, 0x20); /* 5: T1 DataLink Enable */ + pci_write_32 ((u_int32_t *) &comet->t1_frmr_cfg, 0x30); /* Bit 4:ESF 5:ESFFA */ + pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0x04); /* 2:ESF */ + pci_write_32 ((u_int32_t *) &comet->t1_xbas_cfg, 0x10); /* 4:ESF */ + pci_write_32 ((u_int32_t *) &comet->t1_almi_cfg, 0x10); /* 4:ESF */ + break; + case CFG_FRAME_E1PLAIN_AMI: /* 9 - AMI */ + pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0x80); /* Enable AMI Line + * Decoding */ + pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0); + pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0x80); + pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0x40); + break; + case CFG_FRAME_E1CAS_AMI: /* 10 - AMI */ + pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0x80); /* Enable AMI Line + * Decoding */ + pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0); + pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0xe0); + pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0); + break; + case CFG_FRAME_E1CRC_AMI: /* 11 - AMI */ + pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0x80); /* Enable AMI Line + * Decoding */ + pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0); + pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0x90); + pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0xc2); + break; + case CFG_FRAME_E1CRC_CAS_AMI: /* 12 - AMI */ + pci_write_32 ((u_int32_t *) &comet->cdrc_cfg, 0x80); /* Enable AMI Line + * Decoding */ + pci_write_32 ((u_int32_t *) &comet->sigx_cfg, 0); + pci_write_32 ((u_int32_t *) &comet->e1_tran_cfg, 0xf0); + pci_write_32 ((u_int32_t *) &comet->e1_frmr_aopts, 0x82); + break; + } /* end switch */ + + /*** + * Set Full Frame mode (NXDSO[1] = 0, NXDSO[0] = 0) + * CMODE=1: Clock slave mode with BRCLK as an input, + * DE=0: Use falling edge of BRCLK for data, + * FE=0: Use falling edge of BRCLK for frame, + * CMS=0: Use backplane freq, + * RATE[1:0]=0,0: T1 + ***/ + + + /* 0x30: "BRIF cfg"; 0x20 is 'CMODE', 0x03 is (bit) rate */ + /* note "rate bits can only be set once after reset" */ + if (clockmaster) + { /* CMODE == clockMode, 0=clock master (so + * all 3 others should be slave) */ + if (isT1mode) /* rate = 1.544 Mb/s */ + pci_write_32 ((u_int32_t *) &comet->brif_cfg, 0x00); /* Comet 0 Master + * Mode(CMODE=0) */ + else /* rate = 2.048 Mb/s */ + pci_write_32 ((u_int32_t *) &comet->brif_cfg, 0x01); /* Comet 0 Master + * Mode(CMODE=0) */ + + /* 31: BRIF frame pulse cfg 06: tx timing options */ + pci_write_32 ((u_int32_t *) &comet->brif_fpcfg, 0x00); /* Master Mode + * i.e.FPMODE=0 (@0x20) */ + if ((moreParams & CFG_CLK_PORT_MASK) == CFG_CLK_PORT_INTERNAL) + { + if (log_level >= LOG_SBEBUG12) + printk (">> init_comet: clockmaster internal clock\n"); + pci_write_32 ((u_int32_t *) &comet->tx_time, 0x0d); /* internal oscillator */ + } else /* external clock source */ + { + if (log_level >= LOG_SBEBUG12) + printk (">> init_comet: clockmaster external clock\n"); + pci_write_32 ((u_int32_t *) &comet->tx_time, 0x09); /* loop timing + * (external) */ + } + + } else /* slave */ + { + if (isT1mode) + pci_write_32 ((u_int32_t *) &comet->brif_cfg, 0x20); /* Slave Mode(CMODE=1, + * see above) */ + else + pci_write_32 ((u_int32_t *) &comet->brif_cfg, 0x21); /* Slave Mode (CMODE=1) */ + pci_write_32 ((u_int32_t *) &comet->brif_fpcfg, 0x20); /* Slave Mode i.e. + * FPMODE=1 (@0x20) */ + if (log_level >= LOG_SBEBUG12) + printk (">> init_comet: clockslave internal clock\n"); + pci_write_32 ((u_int32_t *) &comet->tx_time, 0x0d); /* oscillator timing */ + } + + /* 32: BRIF parity F-bit cfg */ + /* Totem-pole operation */ + pci_write_32 ((u_int32_t *) &comet->brif_pfcfg, 0x01); /* Receive Backplane + * Parity/F-bit */ + + /* dc: RLPS equalizer V ref */ + /* Configuration */ + if (isT1mode) + pci_write_32 ((u_int32_t *) &comet->rlps_eqvr, 0x2c); /* RLPS Equalizer + * Voltage */ + else + pci_write_32 ((u_int32_t *) &comet->rlps_eqvr, 0x34); /* RLPS Equalizer + * Voltage */ + + /* Reserved bit set and SQUELCH enabled */ + /* f8: RLPS cfg & status f9: RLPS ALOS detect/clear threshold */ + pci_write_32 ((u_int32_t *) &comet->rlps_cfgsts, 0x11); /* RLPS Configuration + * Status */ + if (isT1mode) + pci_write_32 ((u_int32_t *) &comet->rlps_alos_thresh, 0x55); /* ? */ + else + pci_write_32 ((u_int32_t *) &comet->rlps_alos_thresh, 0x22); /* ? */ + + + /* Set Full Frame mode (NXDSO[1] = 0, NXDSO[0] = 0) */ + /* CMODE=0: Clock slave mode with BTCLK as an input, DE=1: Use rising */ + /* edge of BTCLK for data, FE=1: Use rising edge of BTCLK for frame, */ + /* CMS=0: Use backplane freq, RATE[1:0]=0,0: T1 */ +/*** Transmit side is always an Input, Slave Clock*/ + /* 40: BTIF cfg 41: BTIF frame pulse cfg */ + if (isT1mode) + pci_write_32 ((u_int32_t *) &comet->btif_cfg, 0x38); /* BTIF Configuration + * Reg. */ + else + pci_write_32 ((u_int32_t *) &comet->btif_cfg, 0x39); /* BTIF Configuration + * Reg. */ + + pci_write_32 ((u_int32_t *) &comet->btif_fpcfg, 0x01); /* BTIF Frame Pulse + * Config. */ + + /* 0a: master diag 06: tx timing options */ + /* if set Comet to loop back */ + + /* Comets set to normal */ + pci_write_32 ((u_int32_t *) &comet->mdiag, 0x00); + + /* BTCLK driven by TCLKI internally (crystal driven) and Xmt Elasted */ + /* Store is enabled. */ + + WrtXmtWaveformTbl (ci, comet, TWV_table[tix]); + if (isT1mode) + WrtRcvEqualizerTbl ((ci_t *) ci, comet, &T1_Equalizer[0]); + else + WrtRcvEqualizerTbl ((ci_t *) ci, comet, &E1_Equalizer[0]); + SetPwrLevel (comet); +} + +/* +** Name: WrtXmtWaveform +** Description: Formulate the Data for the Pulse Waveform Storage +** Write register, (F2), from the sample and unit inputs. +** Write the data to the Pulse Waveform Storage Data register. +** Returns: Nothing +*/ +STATIC void +WrtXmtWaveform (ci_t * ci, comet_t * comet, u_int32_t sample, u_int32_t unit, u_int8_t data) +{ + u_int8_t WaveformAddr; + + WaveformAddr = (sample << 3) + (unit & 7); + pci_write_32 ((u_int32_t *) &comet->xlpg_pwave_addr, WaveformAddr); + pci_flush_write (ci); /* for write order preservation when + * Optimizing driver */ + pci_write_32 ((u_int32_t *) &comet->xlpg_pwave_data, 0x7F & data); +} + +/* +** Name: WrtXmtWaveformTbl +** Description: Fill in the Transmit Waveform Values +** for driving the transmitter DAC. +** Returns: Nothing +*/ +STATIC void +WrtXmtWaveformTbl (ci_t * ci, comet_t * comet, + u_int8_t table[COMET_NUM_SAMPLES][COMET_NUM_UNITS]) +{ + u_int32_t sample, unit; + + for (sample = 0; sample < COMET_NUM_SAMPLES; sample++) + { + for (unit = 0; unit < COMET_NUM_UNITS; unit++) + WrtXmtWaveform (ci, comet, sample, unit, table[sample][unit]); + } + + /* Enable transmitter and set output amplitude */ + pci_write_32 ((u_int32_t *) &comet->xlpg_cfg, table[COMET_NUM_SAMPLES][0]); +} + + +/* +** Name: WrtXmtWaveform +** Description: Fill in the Receive Equalizer RAM from the desired +** table. +** Returns: Nothing +** +** Remarks: Per PM4351 Device Errata, Receive Equalizer RAM Initialization +** is coded with early setup of indirect address. +*/ + +STATIC void +WrtRcvEqualizerTbl (ci_t * ci, comet_t * comet, u_int32_t *table) +{ + u_int32_t ramaddr; + volatile u_int32_t value; + + for (ramaddr = 0; ramaddr < 256; ramaddr++) + { + /*** the following lines are per Errata 7, 2.5 ***/ + { + pci_write_32 ((u_int32_t *) &comet->rlps_eq_rwsel, 0x80); /* Set up for a read + * operation */ + pci_flush_write (ci); /* for write order preservation when + * Optimizing driver */ + pci_write_32 ((u_int32_t *) &comet->rlps_eq_iaddr, (u_int8_t) ramaddr); /* write the addr, + * initiate a read */ + pci_flush_write (ci); /* for write order preservation when + * Optimizing driver */ + /* + * wait 3 line rate clock cycles to ensure address bits are + * captured by T1/E1 clock + */ + OS_uwait (4, "wret"); /* 683ns * 3 = 1366 ns, approx 2us (but + * use 4us) */ + } + + value = *table++; + pci_write_32 ((u_int32_t *) &comet->rlps_idata3, (u_int8_t) (value >> 24)); + pci_write_32 ((u_int32_t *) &comet->rlps_idata2, (u_int8_t) (value >> 16)); + pci_write_32 ((u_int32_t *) &comet->rlps_idata1, (u_int8_t) (value >> 8)); + pci_write_32 ((u_int32_t *) &comet->rlps_idata0, (u_int8_t) value); + pci_flush_write (ci); /* for write order preservation when + * Optimizing driver */ + + /* Storing RAM address, causes RAM to be updated */ + + pci_write_32 ((u_int32_t *) &comet->rlps_eq_rwsel, 0); /* Set up for a write + * operation */ + pci_flush_write (ci); /* for write order preservation when + * Optimizing driver */ + pci_write_32 ((u_int32_t *) &comet->rlps_eq_iaddr, (u_int8_t) ramaddr); /* write the addr, + * initiate a read */ + pci_flush_write (ci); /* for write order preservation when + * Optimizing driver */ + /* + * wait 3 line rate clock cycles to ensure address bits are captured + * by T1/E1 clock + */ + OS_uwait (4, "wret"); /* 683ns * 3 = 1366 ns, approx 2us (but + * use 4us) */ + } + + pci_write_32 ((u_int32_t *) &comet->rlps_eq_cfg, 0xCB); /* Enable Equalizer & + * set it to use 256 + * periods */ +} + + +/* +** Name: SetPwrLevel +** Description: Implement power level setting algorithm described below +** Returns: Nothing +*/ + +STATIC void +SetPwrLevel (comet_t * comet) +{ + volatile u_int32_t temp; + +/* +** Algorithm to Balance the Power Distribution of Ttip Tring +** +** Zero register F6 +** Write 0x01 to register F4 +** Write another 0x01 to register F4 +** Read register F4 +** Remove the 0x01 bit by Anding register F4 with 0xFE +** Write the resultant value to register F4 +** Repeat these steps for register F5 +** Write 0x01 to register F6 +*/ + pci_write_32 ((u_int32_t *) &comet->xlpg_fdata_sel, 0x00); /* XLPG Fuse Data Select */ + + pci_write_32 ((u_int32_t *) &comet->xlpg_atest_pctl, 0x01); /* XLPG Analog Test + * Positive control */ + pci_write_32 ((u_int32_t *) &comet->xlpg_atest_pctl, 0x01); + + temp = pci_read_32 ((u_int32_t *) &comet->xlpg_atest_pctl) & 0xfe; + pci_write_32 ((u_int32_t *) &comet->xlpg_atest_pctl, temp); + + pci_write_32 ((u_int32_t *) &comet->xlpg_atest_nctl, 0x01); /* XLPG Analog Test + * Negative control */ + pci_write_32 ((u_int32_t *) &comet->xlpg_atest_nctl, 0x01); + + temp = pci_read_32 ((u_int32_t *) &comet->xlpg_atest_nctl) & 0xfe; + pci_write_32 ((u_int32_t *) &comet->xlpg_atest_nctl, temp); + pci_write_32 ((u_int32_t *) &comet->xlpg_fdata_sel, 0x01); /* XLPG */ +} + + +/* +** Name: SetCometOps +** Description: Set up the selected Comet's clock edge drive for both +** the transmit out the analog side and receive to the +** backplane side. +** Returns: Nothing +*/ +#if 0 +STATIC void +SetCometOps (comet_t * comet) +{ + volatile u_int8_t rd_value; + + if (comet == mConfig.C4Func1Base + (COMET0_OFFSET >> 2)) + { + rd_value = (u_int8_t) pci_read_32 ((u_int32_t *) &comet->brif_cfg); /* read the BRIF + * Configuration */ + rd_value &= ~0x20; + pci_write_32 ((u_int32_t *) &comet->brif_cfg, (u_int32_t) rd_value); + + rd_value = (u_int8_t) pci_read_32 ((u_int32_t *) &comet->brif_fpcfg); /* read the BRIF Frame + * Pulse Configuration */ + rd_value &= ~0x20; + pci_write_32 ((u_int32_t *) &comet->brif_fpcfg, (u_int8_t) rd_value); + } else + { + rd_value = (u_int8_t) pci_read_32 ((u_int32_t *) &comet->brif_cfg); /* read the BRIF + * Configuration */ + rd_value |= 0x20; + pci_write_32 ((u_int32_t *) &comet->brif_cfg, (u_int32_t) rd_value); + + rd_value = (u_int8_t) pci_read_32 ((u_int32_t *) &comet->brif_fpcfg); /* read the BRIF Frame + * Pulse Configuration */ + rd_value |= 0x20; + pci_write_32 ((u_int32_t *) &comet->brif_fpcfg, (u_int8_t) rd_value); + } +} +#endif + +/*** End-of-File ***/ diff --git a/drivers/staging/cxt1e1/comet.h b/drivers/staging/cxt1e1/comet.h new file mode 100644 index 000000000000..5cb3afda0112 --- /dev/null +++ b/drivers/staging/cxt1e1/comet.h @@ -0,0 +1,366 @@ +/* + * $Id: comet.h,v 1.3 2005/09/28 00:10:07 rickd PMCC4_3_1B $ + */ + +#ifndef _INC_COMET_H_ +#define _INC_COMET_H_ + +/*----------------------------------------------------------------------------- + * comet.h - + * + * Copyright (C) 2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For further information, contact via email: support@sbei.com + * SBE, Inc. San Ramon, California U.S.A. + *----------------------------------------------------------------------------- + * RCS info: + * RCS revision: $Revision: 1.3 $ + * Last changed on $Date: 2005/09/28 00:10:07 $ + * Changed by $Author: rickd $ + *----------------------------------------------------------------------------- + * $Log: comet.h,v $ + * Revision 1.3 2005/09/28 00:10:07 rickd + * Add RCS header. Switch to structure usage. + * + * Revision 1.2 2005/04/28 23:43:03 rickd + * Add RCS tracking heading. + * + *----------------------------------------------------------------------------- + */ + +#if defined(__FreeBSD__) || defined (__NetBSD__) +#include +#else +#include +#endif + + +#define VINT32 volatile u_int32_t + +struct s_comet_reg +{ + VINT32 gbl_cfg; /* 00 Global Cfg */ + VINT32 clkmon; /* 01 Clk Monitor */ + VINT32 rx_opt; /* 02 RX Options */ + VINT32 rx_line_cfg; /* 03 RX Line Interface Cfg */ + VINT32 tx_line_cfg; /* 04 TX Line Interface Cfg */ + VINT32 tx_frpass; /* 05 TX Framing & Bypass Options */ + VINT32 tx_time; /* 06 TX Timing Options */ + VINT32 intr_1; /* 07 Intr Source #1 */ + VINT32 intr_2; /* 08 Intr Source #2 */ + VINT32 intr_3; /* 09 Intr Source #3 */ + VINT32 mdiag; /* 0A Master Diagnostics */ + VINT32 mtest; /* 0B Master Test */ + VINT32 adiag; /* 0C Analog Diagnostics */ + VINT32 rev_id; /* 0D Rev/Chip Id/Global PMON Update */ +#define pmon rev_id + VINT32 reset; /* 0E Reset */ + VINT32 prgd_phctl; /* 0F PRGD Positioning/Ctl & HDLC Ctl */ + VINT32 cdrc_cfg; /* 10 CDRC Cfg */ + VINT32 cdrc_ien; /* 11 CDRC Intr Enable */ + VINT32 cdrc_ists; /* 12 CDRC Intr Sts */ + VINT32 cdrc_alos; /* 13 CDRC Alternate Loss of Signal */ + + VINT32 rjat_ists; /* 14 RJAT Intr Sts */ + VINT32 rjat_n1clk; /* 15 RJAT Reference Clk Divisor (N1) Ctl */ + VINT32 rjat_n2clk; /* 16 RJAT Output Clk Divisor (N2) Ctl */ + VINT32 rjat_cfg; /* 17 RJAT Cfg */ + + VINT32 tjat_ists; /* 18 TJAT Intr Sts */ + VINT32 tjat_n1clk; /* 19 TJAT Reference Clk Divisor (N1) Ctl */ + VINT32 tjat_n2clk; /* 1A TJAT Output Clk Divisor (N2) Ctl */ + VINT32 tjat_cfg; /* 1B TJAT Cfg */ + + VINT32 rx_elst_cfg; /* 1C RX-ELST Cfg */ + VINT32 rx_elst_ists; /* 1D RX-ELST Intr Sts */ + VINT32 rx_elst_idle; /* 1E RX-ELST Idle Code */ + VINT32 _rx_elst_res1f; /* 1F RX-ELST Reserved */ + + VINT32 tx_elst_cfg; /* 20 TX-ELST Cfg */ + VINT32 tx_elst_ists; /* 21 TX-ELST Intr Sts */ + VINT32 _tx_elst_res22; /* 22 TX-ELST Reserved */ + VINT32 _tx_elst_res23; /* 23 TX-ELST Reserved */ + VINT32 __res24; /* 24 Reserved */ + VINT32 __res25; /* 25 Reserved */ + VINT32 __res26; /* 26 Reserved */ + VINT32 __res27; /* 27 Reserved */ + + VINT32 rxce1_ctl; /* 28 RXCE RX Data Link 1 Ctl */ + VINT32 rxce1_bits; /* 29 RXCE RX Data Link 1 Bit Select */ + VINT32 rxce2_ctl; /* 2A RXCE RX Data Link 2 Ctl */ + VINT32 rxce2_bits; /* 2B RXCE RX Data Link 2 Bit Select */ + VINT32 rxce3_ctl; /* 2C RXCE RX Data Link 3 Ctl */ + VINT32 rxce3_bits; /* 2D RXCE RX Data Link 3 Bit Select */ + VINT32 _rxce_res2E; /* 2E RXCE Reserved */ + VINT32 _rxce_res2F; /* 2F RXCE Reserved */ + + VINT32 brif_cfg; /* 30 BRIF RX Backplane Cfg */ + VINT32 brif_fpcfg; /* 31 BRIF RX Backplane Frame Pulse Cfg */ + VINT32 brif_pfcfg; /* 32 BRIF RX Backplane Parity/F-Bit Cfg */ + VINT32 brif_tsoff; /* 33 BRIF RX Backplane Time Slot Offset */ + VINT32 brif_boff; /* 34 BRIF RX Backplane Bit Offset */ + VINT32 _brif_res35; /* 35 BRIF RX Backplane Reserved */ + VINT32 _brif_res36; /* 36 BRIF RX Backplane Reserved */ + VINT32 _brif_res37; /* 37 BRIF RX Backplane Reserved */ + + VINT32 txci1_ctl; /* 38 TXCI TX Data Link 1 Ctl */ + VINT32 txci1_bits; /* 39 TXCI TX Data Link 2 Bit Select */ + VINT32 txci2_ctl; /* 3A TXCI TX Data Link 1 Ctl */ + VINT32 txci2_bits; /* 3B TXCI TX Data Link 2 Bit Select */ + VINT32 txci3_ctl; /* 3C TXCI TX Data Link 1 Ctl */ + VINT32 txci3_bits; /* 3D TXCI TX Data Link 2 Bit Select */ + VINT32 _txci_res3E; /* 3E TXCI Reserved */ + VINT32 _txci_res3F; /* 3F TXCI Reserved */ + + VINT32 btif_cfg; /* 40 BTIF TX Backplane Cfg */ + VINT32 btif_fpcfg; /* 41 BTIF TX Backplane Frame Pulse Cfg */ + VINT32 btif_pcfgsts; /* 42 BTIF TX Backplane Parity Cfg & Sts */ + VINT32 btif_tsoff; /* 43 BTIF TX Backplane Time Slot Offset */ + VINT32 btif_boff; /* 44 BTIF TX Backplane Bit Offset */ + VINT32 _btif_res45; /* 45 BTIF TX Backplane Reserved */ + VINT32 _btif_res46; /* 46 BTIF TX Backplane Reserved */ + VINT32 _btif_res47; /* 47 BTIF TX Backplane Reserved */ + VINT32 t1_frmr_cfg; /* 48 T1 FRMR Cfg */ + VINT32 t1_frmr_ien; /* 49 T1 FRMR Intr Enable */ + VINT32 t1_frmr_ists; /* 4A T1 FRMR Intr Sts */ + VINT32 __res_4B; /* 4B Reserved */ + VINT32 ibcd_cfg; /* 4C IBCD Cfg */ + VINT32 ibcd_ies; /* 4D IBCD Intr Enable/Sts */ + VINT32 ibcd_act; /* 4E IBCD Activate Code */ + VINT32 ibcd_deact; /* 4F IBCD Deactivate Code */ + + VINT32 sigx_cfg; /* 50 SIGX Cfg/Change of Signaling State */ + VINT32 sigx_acc_cos; /* 51 SIGX uP Access Sts/Change of Signaling State */ + VINT32 sigx_iac_cos; /* 52 SIGX Channel Indirect + * Addr/Ctl/Change of Signaling State */ + VINT32 sigx_idb_cos; /* 53 SIGX Channel Indirect Data + * Buffer/Change of Signaling State */ + + VINT32 t1_xbas_cfg; /* 54 T1 XBAS Cfg */ + VINT32 t1_xbas_altx; /* 55 T1 XBAS Alarm TX */ + VINT32 t1_xibc_ctl; /* 56 T1 XIBC Ctl */ + VINT32 t1_xibc_lbcode; /* 57 T1 XIBC Loopback Code */ + + VINT32 pmon_ies; /* 58 PMON Intr Enable/Sts */ + VINT32 pmon_fberr; /* 59 PMON Framing Bit Err Cnt */ + VINT32 pmon_feb_lsb; /* 5A PMON OFF/COFA/Far End Block Err Cnt (LSB) */ + VINT32 pmon_feb_msb; /* 5B PMON OFF/COFA/Far End Block Err Cnt (MSB) */ + VINT32 pmon_bed_lsb; /* 5C PMON Bit/Err/CRCE Cnt (LSB) */ + VINT32 pmon_bed_msb; /* 5D PMON Bit/Err/CRCE Cnt (MSB) */ + VINT32 pmon_lvc_lsb; /* 5E PMON LVC Cnt (LSB) */ + VINT32 pmon_lvc_msb; /* 5F PMON LVC Cnt (MSB) */ + + VINT32 t1_almi_cfg; /* 60 T1 ALMI Cfg */ + VINT32 t1_almi_ien; /* 61 T1 ALMI Intr Enable */ + VINT32 t1_almi_ists; /* 62 T1 ALMI Intr Sts */ + VINT32 t1_almi_detsts; /* 63 T1 ALMI Alarm Detection Sts */ + + VINT32 _t1_pdvd_res64; /* 64 T1 PDVD Reserved */ + VINT32 t1_pdvd_ies; /* 65 T1 PDVD Intr Enable/Sts */ + VINT32 _t1_xboc_res66; /* 66 T1 XBOC Reserved */ + VINT32 t1_xboc_code; /* 67 T1 XBOC Code */ + VINT32 _t1_xpde_res68; /* 68 T1 XPDE Reserved */ + VINT32 t1_xpde_ies; /* 69 T1 XPDE Intr Enable/Sts */ + + VINT32 t1_rboc_ena; /* 6A T1 RBOC Enable */ + VINT32 t1_rboc_sts; /* 6B T1 RBOC Code Sts */ + + VINT32 t1_tpsc_cfg; /* 6C TPSC Cfg */ + VINT32 t1_tpsc_sts; /* 6D TPSC uP Access Sts */ + VINT32 t1_tpsc_ciaddr; /* 6E TPSC Channel Indirect + * Addr/Ctl */ + VINT32 t1_tpsc_cidata; /* 6F TPSC Channel Indirect Data + * Buffer */ + VINT32 t1_rpsc_cfg; /* 70 RPSC Cfg */ + VINT32 t1_rpsc_sts; /* 71 RPSC uP Access Sts */ + VINT32 t1_rpsc_ciaddr; /* 72 RPSC Channel Indirect + * Addr/Ctl */ + VINT32 t1_rpsc_cidata; /* 73 RPSC Channel Indirect Data + * Buffer */ + VINT32 __res74; /* 74 Reserved */ + VINT32 __res75; /* 75 Reserved */ + VINT32 __res76; /* 76 Reserved */ + VINT32 __res77; /* 77 Reserved */ + + VINT32 t1_aprm_cfg; /* 78 T1 APRM Cfg/Ctl */ + VINT32 t1_aprm_load; /* 79 T1 APRM Manual Load */ + VINT32 t1_aprm_ists; /* 7A T1 APRM Intr Sts */ + VINT32 t1_aprm_1sec_2; /* 7B T1 APRM One Second Content Octet 2 */ + VINT32 t1_aprm_1sec_3; /* 7C T1 APRM One Second Content Octet 3 */ + VINT32 t1_aprm_1sec_4; /* 7D T1 APRM One Second Content Octet 4 */ + VINT32 t1_aprm_1sec_5; /* 7E T1 APRM One Second Content MSB (Octect 5) */ + VINT32 t1_aprm_1sec_6; /* 7F T1 APRM One Second Content MSB (Octect 6) */ + + VINT32 e1_tran_cfg; /* 80 E1 TRAN Cfg */ + VINT32 e1_tran_txalarm; /* 81 E1 TRAN TX Alarm/Diagnostic Ctl */ + VINT32 e1_tran_intctl; /* 82 E1 TRAN International Ctl */ + VINT32 e1_tran_extrab; /* 83 E1 TRAN Extra Bits Ctl */ + VINT32 e1_tran_ien; /* 84 E1 TRAN Intr Enable */ + VINT32 e1_tran_ists; /* 85 E1 TRAN Intr Sts */ + VINT32 e1_tran_nats; /* 86 E1 TRAN National Bit Codeword + * Select */ + VINT32 e1_tran_nat; /* 87 E1 TRAN National Bit Codeword */ + VINT32 __res88; /* 88 Reserved */ + VINT32 __res89; /* 89 Reserved */ + VINT32 __res8A; /* 8A Reserved */ + VINT32 __res8B; /* 8B Reserved */ + + VINT32 _t1_frmr_res8C; /* 8C T1 FRMR Reserved */ + VINT32 _t1_frmr_res8D; /* 8D T1 FRMR Reserved */ + VINT32 __res8E; /* 8E Reserved */ + VINT32 __res8F; /* 8F Reserved */ + + VINT32 e1_frmr_aopts; /* 90 E1 FRMR Frame Alignment Options */ + VINT32 e1_frmr_mopts; /* 91 E1 FRMR Maintenance Mode Options */ + VINT32 e1_frmr_ien; /* 92 E1 FRMR Framing Sts Intr Enable */ + VINT32 e1_frmr_mien; /* 93 E1 FRMR Maintenance/Alarm Sts Intr Enable */ + VINT32 e1_frmr_ists; /* 94 E1 FRMR Framing Sts Intr Indication */ + VINT32 e1_frmr_mists; /* 95 E1 FRMR Maintenance/Alarm Sts Indication Enable */ + VINT32 e1_frmr_sts; /* 96 E1 FRMR Framing Sts */ + VINT32 e1_frmr_masts; /* 97 E1 FRMR Maintenance/Alarm Sts */ + VINT32 e1_frmr_nat_bits; /* 98 E1 FRMR International/National Bits */ + VINT32 e1_frmr_crc_lsb; /* 99 E1 FRMR CRC Err Cnt - LSB */ + VINT32 e1_frmr_crc_msb; /* 9A E1 FRMR CRC Err Cnt - MSB */ + VINT32 e1_frmr_nat_ien; /* 9B E1 FRMR National Bit Codeword Intr Enables */ + VINT32 e1_frmr_nat_ists; /* 9C E1 FRMR National Bit Codeword Intr/Sts */ + VINT32 e1_frmr_nat; /* 9D E1 FRMR National Bit Codewords */ + VINT32 e1_frmr_fp_ien; /* 9E E1 FRMR Frame Pulse/Alarm Intr Enables */ + VINT32 e1_frmr_fp_ists; /* 9F E1 FRMR Frame Pulse/Alarm Intr/Sts */ + + VINT32 __resA0; /* A0 Reserved */ + VINT32 __resA1; /* A1 Reserved */ + VINT32 __resA2; /* A2 Reserved */ + VINT32 __resA3; /* A3 Reserved */ + VINT32 __resA4; /* A4 Reserved */ + VINT32 __resA5; /* A5 Reserved */ + VINT32 __resA6; /* A6 Reserved */ + VINT32 __resA7; /* A7 Reserved */ + + VINT32 tdpr1_cfg; /* A8 TDPR #1 Cfg */ + VINT32 tdpr1_utl; /* A9 TDPR #1 Upper TX Threshold */ + VINT32 tdpr1_ltl; /* AA TDPR #1 Lower TX Threshold */ + VINT32 tdpr1_ien; /* AB TDPR #1 Intr Enable */ + VINT32 tdpr1_ists; /* AC TDPR #1 Intr Sts/UDR Clear */ + VINT32 tdpr1_data; /* AD TDPR #1 TX Data */ + VINT32 __resAE; /* AE Reserved */ + VINT32 __resAF; /* AF Reserved */ + VINT32 tdpr2_cfg; /* B0 TDPR #2 Cfg */ + VINT32 tdpr2_utl; /* B1 TDPR #2 Upper TX Threshold */ + VINT32 tdpr2_ltl; /* B2 TDPR #2 Lower TX Threshold */ + VINT32 tdpr2_ien; /* B3 TDPR #2 Intr Enable */ + VINT32 tdpr2_ists; /* B4 TDPR #2 Intr Sts/UDR Clear */ + VINT32 tdpr2_data; /* B5 TDPR #2 TX Data */ + VINT32 __resB6; /* B6 Reserved */ + VINT32 __resB7; /* B7 Reserved1 */ + VINT32 tdpr3_cfg; /* B8 TDPR #3 Cfg */ + VINT32 tdpr3_utl; /* B9 TDPR #3 Upper TX Threshold */ + VINT32 tdpr3_ltl; /* BA TDPR #3 Lower TX Threshold */ + VINT32 tdpr3_ien; /* BB TDPR #3 Intr Enable */ + VINT32 tdpr3_ists; /* BC TDPR #3 Intr Sts/UDR Clear */ + VINT32 tdpr3_data; /* BD TDPR #3 TX Data */ + VINT32 __resBE; /* BE Reserved */ + VINT32 __resBF; /* BF Reserved */ + + VINT32 rdlc1_cfg; /* C0 RDLC #1 Cfg */ + VINT32 rdlc1_intctl; /* C1 RDLC #1 Intr Ctl */ + VINT32 rdlc1_sts; /* C2 RDLC #1 Sts */ + VINT32 rdlc1_data; /* C3 RDLC #1 Data */ + VINT32 rdlc1_paddr; /* C4 RDLC #1 Primary Addr Match */ + VINT32 rdlc1_saddr; /* C5 RDLC #1 Secondary Addr Match */ + VINT32 __resC6; /* C6 Reserved */ + VINT32 __resC7; /* C7 Reserved */ + VINT32 rdlc2_cfg; /* C8 RDLC #2 Cfg */ + VINT32 rdlc2_intctl; /* C9 RDLC #2 Intr Ctl */ + VINT32 rdlc2_sts; /* CA RDLC #2 Sts */ + VINT32 rdlc2_data; /* CB RDLC #2 Data */ + VINT32 rdlc2_paddr; /* CC RDLC #2 Primary Addr Match */ + VINT32 rdlc2_saddr; /* CD RDLC #2 Secondary Addr Match */ + VINT32 __resCE; /* CE Reserved */ + VINT32 __resCF; /* CF Reserved */ + VINT32 rdlc3_cfg; /* D0 RDLC #3 Cfg */ + VINT32 rdlc3_intctl; /* D1 RDLC #3 Intr Ctl */ + VINT32 rdlc3_sts; /* D2 RDLC #3 Sts */ + VINT32 rdlc3_data; /* D3 RDLC #3 Data */ + VINT32 rdlc3_paddr; /* D4 RDLC #3 Primary Addr Match */ + VINT32 rdlc3_saddr; /* D5 RDLC #3 Secondary Addr Match */ + + VINT32 csu_cfg; /* D6 CSU Cfg */ + VINT32 _csu_resD7; /* D7 CSU Reserved */ + + VINT32 rlps_idata3; /* D8 RLPS Indirect Data, 24-31 */ + VINT32 rlps_idata2; /* D9 RLPS Indirect Data, 16-23 */ + VINT32 rlps_idata1; /* DA RLPS Indirect Data, 8-15 */ + VINT32 rlps_idata0; /* DB RLPS Indirect Data, 0-7 */ + VINT32 rlps_eqvr; /* DC RLPS Equalizer Voltage Reference + * (E1 missing) */ + VINT32 _rlps_resDD; /* DD RLPS Reserved */ + VINT32 _rlps_resDE; /* DE RLPS Reserved */ + VINT32 _rlps_resDF; /* DF RLPS Reserved */ + + VINT32 prgd_ctl; /* E0 PRGD Ctl */ + VINT32 prgd_ies; /* E1 PRGD Intr Enable/Sts */ + VINT32 prgd_shift_len; /* E2 PRGD Shift Length */ + VINT32 prgd_tap; /* E3 PRGD Tap */ + VINT32 prgd_errin; /* E4 PRGD Err Insertion */ + VINT32 _prgd_resE5; /* E5 PRGD Reserved */ + VINT32 _prgd_resE6; /* E6 PRGD Reserved */ + VINT32 _prgd_resE7; /* E7 PRGD Reserved */ + VINT32 prgd_patin1; /* E8 PRGD Pattern Insertion #1 */ + VINT32 prgd_patin2; /* E9 PRGD Pattern Insertion #2 */ + VINT32 prgd_patin3; /* EA PRGD Pattern Insertion #3 */ + VINT32 prgd_patin4; /* EB PRGD Pattern Insertion #4 */ + VINT32 prgd_patdet1; /* EC PRGD Pattern Detector #1 */ + VINT32 prgd_patdet2; /* ED PRGD Pattern Detector #2 */ + VINT32 prgd_patdet3; /* EE PRGD Pattern Detector #3 */ + VINT32 prgd_patdet4; /* EF PRGD Pattern Detector #4 */ + + VINT32 xlpg_cfg; /* F0 XLPG Line Driver Cfg */ + VINT32 xlpg_ctlsts; /* F1 XLPG Ctl/Sts */ + VINT32 xlpg_pwave_addr; /* F2 XLPG Pulse Waveform Storage Write Addr */ + VINT32 xlpg_pwave_data; /* F3 XLPG Pulse Waveform Storage Data */ + VINT32 xlpg_atest_pctl; /* F4 XLPG Analog Test Positive Ctl */ + VINT32 xlpg_atest_nctl; /* F5 XLPG Analog Test Negative Ctl */ + VINT32 xlpg_fdata_sel; /* F6 XLPG Fuse Data Select */ + VINT32 _xlpg_resF7; /* F7 XLPG Reserved */ + + VINT32 rlps_cfgsts; /* F8 RLPS Cfg & Sts */ + VINT32 rlps_alos_thresh; /* F9 RLPS ALOS Detection/Clearance Threshold */ + VINT32 rlps_alos_dper; /* FA RLPS ALOS Detection Period */ + VINT32 rlps_alos_cper; /* FB RLPS ALOS Clearance Period */ + VINT32 rlps_eq_iaddr; /* FC RLPS Equalization Indirect Addr */ + VINT32 rlps_eq_rwsel; /* FD RLPS Equalization Read/WriteB Select */ + VINT32 rlps_eq_ctlsts; /* FE RLPS Equalizer Loop Sts & Ctl */ + VINT32 rlps_eq_cfg; /* FF RLPS Equalizer Cfg */ +}; + +typedef struct s_comet_reg comet_t; + +/* 00AH: MDIAG Register bit definitions */ +#define COMET_MDIAG_ID5 0x40 +#define COMET_MDIAG_LBMASK 0x3F +#define COMET_MDIAG_PAYLB 0x20 +#define COMET_MDIAG_LINELB 0x10 +#define COMET_MDIAG_RAIS 0x08 +#define COMET_MDIAG_DDLB 0x04 +#define COMET_MDIAG_TXMFP 0x02 +#define COMET_MDIAG_TXLOS 0x01 +#define COMET_MDIAG_LBOFF 0x00 + +#undef VINT32 + +#ifdef __KERNEL__ +extern void +init_comet (void *, comet_t *, u_int32_t, int, u_int8_t); +#endif + +#endif /* _INC_COMET_H_ */ diff --git a/drivers/staging/cxt1e1/comet_tables.c b/drivers/staging/cxt1e1/comet_tables.c new file mode 100644 index 000000000000..db1293c71a6d --- /dev/null +++ b/drivers/staging/cxt1e1/comet_tables.c @@ -0,0 +1,561 @@ +/* + * $Id: comet_tables.c,v 1.2 2005/10/17 23:55:27 rickd PMCC4_3_1B $ + */ + +/*----------------------------------------------------------------------------- + * comet_tables.c - waveform tables for the PM4351 'COMET' + * + * Copyright (C) 2003-2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For further information, contact via email: support@sbei.com + * SBE, Inc. San Ramon, California U.S.A. + *----------------------------------------------------------------------------- + * RCS info: + * RCS revision: $Revision: 1.2 $ + * Last changed on $Date: 2005/10/17 23:55:27 $ + * Changed by $Author: rickd $ + *----------------------------------------------------------------------------- + * $Log: comet_tables.c,v $ + * Revision 1.2 2005/10/17 23:55:27 rickd + * Note that 75 Ohm transmit waveform is not supported on PMCC4. + * + * Revision 1.1 2005/09/28 00:10:05 rickd + * Cosmetic alignment of tables for readability. + * + * Revision 1.0 2005/05/10 22:47:53 rickd + * Initial revision + * + *----------------------------------------------------------------------------- + */ + +char SBEid_pmcc4_comet_tblc[] = + "@(#)comet_tables.c - $Revision: 1.2 $ (c) Copyright 2004-2005 SBE, Inc."; + + +#include + +/***************************************************************************** +* +* Array names: +* +* TWVLongHaul0DB +* TWVLongHaul7_5DB +* TWVLongHaul15DB +* TWVLongHaul22_5DB +* TWVShortHaul0 +* TWVShortHaul1 +* TWVShortHaul2 +* TWVShortHaul3 +* TWVShortHaul4 +* TWVShortHaul5 +* TWV_E1_120Ohm +* TWV_E1_75Ohm +* T1_Equalizer +* E1_Equalizer +* +*****************************************************************************/ + +u_int8_t TWVLongHaul0DB[25][5] =/* T1 Long Haul 0 DB */ +{ + {0x00, 0x44, 0x00, 0x00, 0x00}, /* Sample 0 */ + {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */ + {0x20, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */ + {0x32, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */ + {0x3E, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */ + {0x3D, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */ + {0x3C, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */ + {0x3B, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */ + {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */ + {0x39, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */ + {0x39, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */ + {0x38, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */ + {0x37, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */ + {0x36, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */ + {0x34, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */ + {0x29, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */ + {0x4F, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */ + {0x4C, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */ + {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */ + {0x49, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */ + {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */ + {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */ + {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */ + {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */ + {0x0C} /* PMC's suggested value */ +/* {0x14} Output Amplitude */ +}; + +u_int8_t TWVLongHaul7_5DB[25][5] = /* T1 Long Haul 7.5 DB */ +{ + {0x00, 0x10, 0x00, 0x00, 0x00}, /* Sample 0 */ + {0x01, 0x0E, 0x00, 0x00, 0x00}, /* Sample 1 */ + {0x02, 0x0C, 0x00, 0x00, 0x00}, /* Sample 2 */ + {0x04, 0x0A, 0x00, 0x00, 0x00}, /* Sample 3 */ + {0x08, 0x08, 0x00, 0x00, 0x00}, /* Sample 4 */ + {0x0C, 0x06, 0x00, 0x00, 0x00}, /* Sample 5 */ + {0x10, 0x04, 0x00, 0x00, 0x00}, /* Sample 6 */ + {0x16, 0x02, 0x00, 0x00, 0x00}, /* Sample 7 */ + {0x1A, 0x01, 0x00, 0x00, 0x00}, /* Sample 8 */ + {0x1E, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */ + {0x22, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */ + {0x26, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */ + {0x2A, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */ + {0x2B, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */ + {0x2C, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */ + {0x2D, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */ + {0x2C, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */ + {0x28, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */ + {0x24, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */ + {0x20, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */ + {0x1C, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */ + {0x18, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */ + {0x14, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */ + {0x12, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */ + {0x07} /* PMC's suggested value */ +/* { 0x0A } Output Amplitude */ +}; + +u_int8_t TWVLongHaul15DB[25][5] = /* T1 Long Haul 15 DB */ +{ + {0x00, 0x2A, 0x09, 0x01, 0x00}, /* Sample 0 */ + {0x00, 0x28, 0x08, 0x01, 0x00}, /* Sample 1 */ + {0x00, 0x26, 0x08, 0x01, 0x00}, /* Sample 2 */ + {0x00, 0x24, 0x07, 0x01, 0x00}, /* Sample 3 */ + {0x01, 0x22, 0x07, 0x01, 0x00}, /* Sample 4 */ + {0x02, 0x20, 0x06, 0x01, 0x00}, /* Sample 5 */ + {0x04, 0x1E, 0x06, 0x01, 0x00}, /* Sample 6 */ + {0x07, 0x1C, 0x05, 0x00, 0x00}, /* Sample 7 */ + {0x0A, 0x1B, 0x05, 0x00, 0x00}, /* Sample 8 */ + {0x0D, 0x19, 0x05, 0x00, 0x00}, /* Sample 9 */ + {0x10, 0x18, 0x04, 0x00, 0x00}, /* Sample 10 */ + {0x14, 0x16, 0x04, 0x00, 0x00}, /* Sample 11 */ + {0x18, 0x15, 0x04, 0x00, 0x00}, /* Sample 12 */ + {0x1B, 0x13, 0x03, 0x00, 0x00}, /* Sample 13 */ + {0x1E, 0x12, 0x03, 0x00, 0x00}, /* Sample 14 */ + {0x21, 0x10, 0x03, 0x00, 0x00}, /* Sample 15 */ + {0x24, 0x0F, 0x03, 0x00, 0x00}, /* Sample 16 */ + {0x27, 0x0D, 0x03, 0x00, 0x00}, /* Sample 17 */ + {0x2A, 0x0D, 0x02, 0x00, 0x00}, /* Sample 18 */ + {0x2D, 0x0B, 0x02, 0x00, 0x00}, /* Sample 19 */ + {0x30, 0x0B, 0x02, 0x00, 0x00}, /* Sample 20 */ + {0x30, 0x0A, 0x02, 0x00, 0x00}, /* Sample 21 */ + {0x2E, 0x0A, 0x02, 0x00, 0x00}, /* Sample 22 */ + {0x2C, 0x09, 0x02, 0x00, 0x00}, /* Sample 23 */ + {0x03} /* Output Amplitude */ +}; + +u_int8_t TWVLongHaul22_5DB[25][5] = /* T1 Long Haul 22.5 DB */ +{ + {0x00, 0x1F, 0x16, 0x06, 0x01}, /* Sample 0 */ + {0x00, 0x20, 0x15, 0x05, 0x01}, /* Sample 1 */ + {0x00, 0x21, 0x15, 0x05, 0x01}, /* Sample 2 */ + {0x00, 0x22, 0x14, 0x05, 0x01}, /* Sample 3 */ + {0x00, 0x22, 0x13, 0x04, 0x00}, /* Sample 4 */ + {0x00, 0x23, 0x12, 0x04, 0x00}, /* Sample 5 */ + {0x01, 0x23, 0x12, 0x04, 0x00}, /* Sample 6 */ + {0x01, 0x24, 0x11, 0x03, 0x00}, /* Sample 7 */ + {0x01, 0x23, 0x10, 0x03, 0x00}, /* Sample 8 */ + {0x02, 0x23, 0x10, 0x03, 0x00}, /* Sample 9 */ + {0x03, 0x22, 0x0F, 0x03, 0x00}, /* Sample 10 */ + {0x05, 0x22, 0x0E, 0x03, 0x00}, /* Sample 11 */ + {0x07, 0x21, 0x0E, 0x02, 0x00}, /* Sample 12 */ + {0x09, 0x20, 0x0D, 0x02, 0x00}, /* Sample 13 */ + {0x0B, 0x1E, 0x0C, 0x02, 0x00}, /* Sample 14 */ + {0x0E, 0x1D, 0x0C, 0x02, 0x00}, /* Sample 15 */ + {0x10, 0x1B, 0x0B, 0x02, 0x00}, /* Sample 16 */ + {0x13, 0x1B, 0x0A, 0x02, 0x00}, /* Sample 17 */ + {0x15, 0x1A, 0x0A, 0x02, 0x00}, /* Sample 18 */ + {0x17, 0x19, 0x09, 0x01, 0x00}, /* Sample 19 */ + {0x19, 0x19, 0x08, 0x01, 0x00}, /* Sample 20 */ + {0x1B, 0x18, 0x08, 0x01, 0x00}, /* Sample 21 */ + {0x1D, 0x17, 0x07, 0x01, 0x00}, /* Sample 22 */ + {0x1E, 0x17, 0x06, 0x01, 0x00}, /* Sample 23 */ + {0x02} /* Output Amplitude */ +}; + +u_int8_t TWVShortHaul0[25][5] = /* T1 Short Haul 0 - 110 ft */ +{ + {0x00, 0x45, 0x00, 0x00, 0x00}, /* Sample 0 */ + {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */ + {0x20, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */ + {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */ + {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */ + {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */ + {0x3C, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */ + {0x3B, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */ + {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */ + {0x39, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */ + {0x39, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */ + {0x38, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */ + {0x37, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */ + {0x36, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */ + {0x34, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */ + {0x29, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */ + {0x59, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */ + {0x55, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */ + {0x50, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */ + {0x4D, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */ + {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */ + {0x48, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */ + {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */ + {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */ + {0x0C} /* Output Amplitude */ +}; + +u_int8_t TWVShortHaul1[25][5] = /* T1 Short Haul 110 - 220 ft */ +{ + {0x00, 0x44, 0x00, 0x00, 0x00}, /* Sample 0 */ + {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */ + {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */ + {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */ + {0x36, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */ + {0x34, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */ + {0x30, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */ + {0x2F, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */ + {0x2E, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */ + {0x2D, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */ + {0x2C, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */ + {0x2B, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */ + {0x2A, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */ + {0x28, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */ + {0x26, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */ + {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */ + {0x68, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */ + {0x54, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */ + {0x4F, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */ + {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */ + {0x49, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */ + {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */ + {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */ + {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */ + {0x10} /* Output Amplitude */ +}; + +u_int8_t TWVShortHaul2[25][5] = /* T1 Short Haul 220 - 330 ft */ +{ + {0x00, 0x44, 0x00, 0x00, 0x00}, /* Sample 0 */ + {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */ + {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */ + {0x3A, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */ + {0x3A, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */ + {0x38, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */ + {0x30, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */ + {0x2F, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */ + {0x2E, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */ + {0x2D, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */ + {0x2C, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */ + {0x2B, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */ + {0x2A, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */ + {0x29, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */ + {0x23, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */ + {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */ + {0x6C, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */ + {0x60, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */ + {0x4F, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */ + {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */ + {0x49, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */ + {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */ + {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */ + {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */ + {0x11} /* Output Amplitude */ +}; + +u_int8_t TWVShortHaul3[25][5] = /* T1 Short Haul 330 - 440 ft */ +{ + {0x00, 0x44, 0x00, 0x00, 0x00}, /* Sample 0 */ + {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */ + {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */ + {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */ + {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */ + {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */ + {0x2F, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */ + {0x2E, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */ + {0x2D, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */ + {0x2C, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */ + {0x2B, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */ + {0x2A, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */ + {0x29, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */ + {0x28, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */ + {0x19, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */ + {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */ + {0x7F, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */ + {0x60, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */ + {0x4F, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */ + {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */ + {0x49, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */ + {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */ + {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */ + {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */ + {0x12} /* Output Amplitude */ +}; + +u_int8_t TWVShortHaul4[25][5] = /* T1 Short Haul 440 - 550 ft */ +{ + {0x00, 0x44, 0x00, 0x00, 0x00}, /* Sample 0 */ + {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */ + {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */ + {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */ + {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */ + {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */ + {0x30, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */ + {0x2B, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */ + {0x2A, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */ + {0x29, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */ + {0x28, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */ + {0x27, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */ + {0x26, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */ + {0x26, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */ + {0x24, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */ + {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */ + {0x7F, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */ + {0x7F, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */ + {0x4F, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */ + {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */ + {0x49, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */ + {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */ + {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */ + {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */ + {0x14} /* Output Amplitude */ +}; + +u_int8_t TWVShortHaul5[25][5] = /* T1 Short Haul 550 - 660 ft */ +{ + {0x00, 0x44, 0x00, 0x00, 0x00}, /* Sample 0 */ + {0x0A, 0x44, 0x00, 0x00, 0x00}, /* Sample 1 */ + {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 2 */ + {0x3F, 0x43, 0x00, 0x00, 0x00}, /* Sample 3 */ + {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 4 */ + {0x3F, 0x42, 0x00, 0x00, 0x00}, /* Sample 5 */ + {0x3F, 0x41, 0x00, 0x00, 0x00}, /* Sample 6 */ + {0x30, 0x41, 0x00, 0x00, 0x00}, /* Sample 7 */ + {0x2A, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */ + {0x29, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */ + {0x28, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */ + {0x27, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */ + {0x26, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */ + {0x25, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */ + {0x24, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */ + {0x4A, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */ + {0x7F, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */ + {0x7F, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */ + {0x5F, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */ + {0x50, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */ + {0x49, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */ + {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */ + {0x47, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */ + {0x46, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */ + {0x15} /* Output Amplitude */ +}; + +u_int8_t TWV_E1_120Ohm[25][5] = /* E1 120 Ohm */ +{ + {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 0 */ + {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 1 */ + {0x0A, 0x00, 0x00, 0x00, 0x00}, /* Sample 2 */ + {0x3F, 0x00, 0x00, 0x00, 0x00}, /* Sample 3 */ + {0x3F, 0x00, 0x00, 0x00, 0x00}, /* Sample 4 */ + {0x39, 0x00, 0x00, 0x00, 0x00}, /* Sample 5 */ + {0x38, 0x00, 0x00, 0x00, 0x00}, /* Sample 6 */ + {0x36, 0x00, 0x00, 0x00, 0x00}, /* Sample 7 */ + {0x36, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */ + {0x35, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */ + {0x35, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */ + {0x35, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */ + {0x35, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */ + {0x35, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */ + {0x35, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */ + {0x2D, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */ + {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */ + {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */ + {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */ + {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */ + {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */ + {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */ + {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */ + {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */ + {0x0C} /* PMC's suggested value */ +/* { 0x10 } Output Amplitude */ +}; + + + +u_int8_t TWV_E1_75Ohm[25][5] = /* E1 75 Ohm */ +{ +#ifdef PMCC4_DOES_NOT_SUPPORT + {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 0 */ + {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 1 */ + {0x0A, 0x00, 0x00, 0x00, 0x00}, /* Sample 2 */ + {0x28, 0x00, 0x00, 0x00, 0x00}, /* Sample 3 */ + {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 4 */ + {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 5 */ + {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 6 */ + {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 7 */ + {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 8 */ + {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 9 */ + {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 10 */ + {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 11 */ + {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 12 */ + {0x3A, 0x00, 0x00, 0x00, 0x00}, /* Sample 13 */ + {0x32, 0x00, 0x00, 0x00, 0x00}, /* Sample 14 */ + {0x14, 0x00, 0x00, 0x00, 0x00}, /* Sample 15 */ + {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 16 */ + {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 17 */ + {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 18 */ + {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 19 */ + {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 20 */ + {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 21 */ + {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 22 */ + {0x00, 0x00, 0x00, 0x00, 0x00}, /* Sample 23 */ +#endif + {0x0C} /* Output Amplitude */ +}; + + +u_int32_t T1_Equalizer[256] = /* T1 Receiver Equalizer */ +{ + 0x03FE1840, 0x03F61840, 0x03EE1840, 0x03E61840, /* 000 - 003 */ + 0x03DE1840, 0x03D61840, 0x03D61840, 0x03D61840, /* 004 - 007 */ + 0x03CE1840, 0x03CE1840, 0x03CE1840, 0x03CE1840, /* 008 - 011 */ + 0x03C61840, 0x03C61840, 0x03C61840, 0x0BBE1840, /* 012 - 015 */ + 0x0BBE1840, 0x0BBE1840, 0x0BBE1840, 0x0BB61840, /* 016 - 019 */ + 0x0BB61840, 0x0BB61840, 0x0BB61840, 0x13AE1838, /* 020 - 023 */ + 0x13AE183C, 0x13AE1840, 0x13AE1840, 0x13AE1840, /* 024 - 027 */ + 0x13AE1840, 0x1BB618B8, 0x1BAE18B8, 0x1BAE18BC, /* 028 - 031 */ + 0x1BAE18C0, 0x1BAE18C0, 0x23A618C0, 0x23A618C0, /* 032 - 035 */ + 0x23A618C0, 0x23A618C0, 0x23A618C0, 0x239E18C0, /* 036 - 039 */ + 0x239E18C0, 0x239E18C0, 0x239E18C0, 0x239E18C0, /* 040 - 043 */ + 0x2B9618C0, 0x2B9618C0, 0x2B9618C0, 0x33961940, /* 044 - 047 */ + 0x37961940, 0x37961940, 0x37961940, 0x3F9E19C0, /* 048 - 051 */ + 0x3F9E19C0, 0x3F9E19C0, 0x3FA61A40, 0x3FA61A40, /* 052 - 055 */ + 0x3FA61A40, 0x3FA61A40, 0x3F9619C0, 0x3F9619C0, /* 056 - 059 */ + 0x3F9619C0, 0x3F9619C0, 0x479E1A40, 0x479E1A40, /* 060 - 063 */ + 0x479E1A40, 0x47961A40, 0x47961A40, 0x47961A40, /* 064 - 067 */ + 0x47961A40, 0x4F8E1A40, 0x4F8E1A40, 0x4F8E1A40, /* 068 - 071 */ + 0x4F8E1A40, 0x4F8E1A40, 0x57861A40, 0x57861A40, /* 072 - 075 */ + 0x57861A40, 0x57861A40, 0x57861A40, 0x5F861AC0, /* 076 - 079 */ + 0x5F861AC0, 0x5F861AC0, 0x5F861AC0, 0x5F861AC0, /* 080 - 083 */ + 0x5F861AC0, 0x5F7E1AC0, 0x5F7E1AC0, 0x5F7E1AC0, /* 084 - 087 */ + 0x5F7E1AC0, 0x5F7E1AC0, 0x677E2AC0, 0x677E2AC0, /* 088 - 091 */ + 0x677E2AC0, 0x677E2AC0, 0x67762AC0, 0x67762AC0, /* 092 - 095 */ + 0x67762AC0, 0x67762AC0, 0x67762AC0, 0x6F6E2AC0, /* 096 - 099 */ + 0x6F6E2AC0, 0x6F6E2AC0, 0x6F6E2AC0, 0x776E3AC0, /* 100 - 103 */ + 0x776E3AC0, 0x776E3AC0, 0x776E3AC0, 0x7F663AC0, /* 104 - 107 */ + 0x7F663AC0, 0x7F664AC0, 0x7F664AC0, 0x7F664AC0, /* 108 - 111 */ + 0x7F664AC0, 0x87665AC0, 0x87665AC0, 0x87665AC0, /* 112 - 115 */ + 0x87665AC0, 0x87665AC0, 0x875E5AC0, 0x875E5AC0, /* 116 - 119 */ + 0x875E5AC0, 0x875E5AC0, 0x875E5AC0, 0x8F5E6AC0, /* 120 - 123 */ + 0x8F5E6AC0, 0x8F5E6AC0, 0x8F5E6AC0, 0x975E7AC0, /* 124 - 127 */ + 0x975E7AC0, 0x975E7AC0, 0x975E7AC0, 0x9F5E8AC0, /* 128 - 131 */ + 0x9F5E8AC0, 0x9F5E8AC0, 0x9F5E8AC0, 0x9F5E8AC0, /* 132 - 135 */ + 0xA7569AC0, 0xA7569AC0, 0xA7569AC0, 0xA7569AC0, /* 136 - 139 */ + 0xA756AAC0, 0xA756AAC0, 0xA756AAC0, 0xAF4EAAC0, /* 140 - 143 */ + 0xAF4EAAC0, 0xAF4EAAC0, 0xAF4EAAC0, 0xAF4EAAC0, /* 144 - 147 */ + 0xB746AAC0, 0xB746AAC0, 0xB746AAC0, 0xB746AAC0, /* 148 - 151 */ + 0xB746AAC0, 0xB746AAC0, 0xB746AAC0, 0xB746BAC0, /* 152 - 155 */ + 0xB746BAC0, 0xB746BAC0, 0xBF4EBB40, 0xBF4EBB40, /* 156 - 159 */ + 0xBF4EBB40, 0xBF4EBB40, 0xBF4EBB40, 0xBF4EBB40, /* 160 - 163 */ + 0xBF4EBB40, 0xBF4EBB40, 0xBF4EBB40, 0xBE46CB40, /* 164 - 167 */ + 0xBE46CB40, 0xBE46CB40, 0xBE46CB40, 0xBE46CB40, /* 168 - 171 */ + 0xBE46CB40, 0xBE46DB40, 0xBE46DB40, 0xBE46DB40, /* 172 - 175 */ + 0xC63ECB40, 0xC63ECB40, 0xC63EDB40, 0xC63EDB40, /* 176 - 179 */ + 0xC63EDB40, 0xC644DB40, 0xC644DB40, 0xC644DB40, /* 180 - 183 */ + 0xC644DB40, 0xC63CDB40, 0xC63CDB40, 0xC63CDB40, /* 184 - 187 */ + 0xC63CDB40, 0xD634DB40, 0xD634DB40, 0xD634DB40, /* 188 - 191 */ + 0xD634DB40, 0xD634DB40, 0xDE2CDB3C, 0xDE2CDB3C, /* 192 - 195 */ + 0xDE2CDB3C, 0xE62CDB40, 0xE62CDB40, 0xE62CDB40, /* 196 - 199 */ + 0xE62CDB40, 0xE62CDB40, 0xE62CEB40, 0xE62CEB40, /* 200 - 203 */ + 0xE62CEB40, 0xEE2CFB40, 0xEE2CFB40, 0xEE2CFB40, /* 204 - 207 */ + 0xEE2D0B40, 0xEE2D0B40, 0xEE2D0B40, 0xEE2D0B40, /* 208 - 211 */ + 0xEE2D0B40, 0xF5250B38, 0xF5250B3C, 0xF5250B40, /* 212 - 215 */ + 0xF5251B40, 0xF5251B40, 0xF5251B40, 0xF5251B40, /* 216 - 219 */ + 0xF5251B40, 0xFD252B40, 0xFD252B40, 0xFD252B40, /* 220 - 223 */ + 0xFD252B40, 0xFD252740, 0xFD252740, 0xFD252740, /* 224 - 227 */ + 0xFD252340, 0xFD252340, 0xFD252340, 0xFD253340, /* 228 - 231 */ + 0xFD253340, 0xFD253340, 0xFD253340, 0xFD253340, /* 232 - 235 */ + 0xFD253340, 0xFD253340, 0xFD253340, 0xFC254340, /* 236 - 239 */ + 0xFD254340, 0xFD254340, 0xFD254344, 0xFC254348, /* 240 - 243 */ + 0xFC25434C, 0xFD2543BC, 0xFD2543C0, 0xFC2543C0, /* 244 - 247 */ + 0xFC2343C0, 0xFC2343C0, 0xFD2343C0, 0xFC2143C0, /* 248 - 251 */ + 0xFC2143C0, 0xFC2153C0, 0xFD2153C0, 0xFC2153C0 /* 252 - 255 */ +}; + + +u_int32_t E1_Equalizer[256] = /* E1 Receiver Equalizer */ +{ + 0x07DE182C, 0x07DE182C, 0x07D6182C, 0x07D6182C, /* 000 - 003 */ + 0x07D6182C, 0x07CE182C, 0x07CE182C, 0x07CE182C, /* 004 - 007 */ + 0x07C6182C, 0x07C6182C, 0x07C6182C, 0x07BE182C, /* 008 - 011 */ + 0x07BE182C, 0x07BE182C, 0x07BE182C, 0x07BE182C, /* 012 - 015 */ + 0x07B6182C, 0x07B6182C, 0x07B6182C, 0x07B6182C, /* 016 - 019 */ + 0x07B6182C, 0x07AE182C, 0x07AE182C, 0x07AE182C, /* 020 - 023 */ + 0x07AE182C, 0x07AE182C, 0x07B618AC, 0x07AE18AC, /* 024 - 027 */ + 0x07AE18AC, 0x07AE18AC, 0x07AE18AC, 0x07A618AC, /* 028 - 031 */ + 0x07A618AC, 0x07A618AC, 0x07A618AC, 0x079E18AC, /* 032 - 035 */ + 0x07A6192C, 0x07A6192C, 0x07A6192C, 0x0FA6192C, /* 036 - 039 */ + 0x0FA6192C, 0x0F9E192C, 0x0F9E192C, 0x0F9E192C, /* 040 - 043 */ + 0x179E192C, 0x17A619AC, 0x179E19AC, 0x179E19AC, /* 044 - 047 */ + 0x179619AC, 0x1F9619AC, 0x1F9619AC, 0x1F8E19AC, /* 048 - 051 */ + 0x1F8E19AC, 0x1F8E19AC, 0x278E19AC, 0x278E1A2C, /* 052 - 055 */ + 0x278E1A2C, 0x278E1A2C, 0x278E1A2C, 0x2F861A2C, /* 056 - 059 */ + 0x2F861A2C, 0x2F861A2C, 0x2F7E1A2C, 0x2F7E1A2C, /* 060 - 063 */ + 0x2F7E1A2C, 0x377E1A2C, 0x377E1AAC, 0x377E1AAC, /* 064 - 067 */ + 0x377E1AAC, 0x377E1AAC, 0x3F7E2AAC, 0x3F7E2AAC, /* 068 - 071 */ + 0x3F762AAC, 0x3F862B2C, 0x3F7E2B2C, 0x477E2B2C, /* 072 - 075 */ + 0x477E2F2C, 0x477E2F2C, 0x477E2F2C, 0x47762F2C, /* 076 - 079 */ + 0x4F762F2C, 0x4F762F2C, 0x4F6E2F2C, 0x4F6E2F2C, /* 080 - 083 */ + 0x4F6E2F2C, 0x576E2F2C, 0x576E2F2C, 0x576E3F2C, /* 084 - 087 */ + 0x576E3F2C, 0x576E3F2C, 0x5F6E3F2C, 0x5F6E4F2C, /* 088 - 091 */ + 0x5F6E4F2C, 0x5F6E4F2C, 0x5F664F2C, 0x67664F2C, /* 092 - 095 */ + 0x67664F2C, 0x675E4F2C, 0x675E4F2C, 0x67664F2C, /* 096 - 099 */ + 0x67664F2C, 0x67665F2C, 0x6F6E5F2C, 0x6F6E6F2C, /* 100 - 103 */ + 0x6F6E6F2C, 0x6F6E7F2C, 0x6F6E7F2C, 0x6F6E7F2C, /* 104 - 107 */ + 0x77667F2C, 0x77667F2C, 0x775E6F2C, 0x775E7F2C, /* 108 - 111 */ + 0x775E7F2C, 0x7F5E7F2C, 0x7F5E8F2C, 0x7F5E8F2C, /* 112 - 115 */ + 0x7F5E8F2C, 0x87568F2C, 0x87568F2C, 0x87568F2C, /* 116 - 119 */ + 0x874E8F2C, 0x874E8F2C, 0x874E8F2C, 0x8F4E9F2C, /* 120 - 123 */ + 0x8F4E9F2C, 0x8F4EAF2C, 0x8F4EAF2C, 0x8F4EAF2C, /* 124 - 127 */ + 0x974EAF2C, 0x974EAF2C, 0x974EAB2C, 0x974EAB2C, /* 128 - 131 */ + 0x974EAB2C, 0x9F4EAB2C, 0x9F4EBB2C, 0x9F4EBB2C, /* 132 - 135 */ + 0x9F4EBB2C, 0x9F4ECB2C, 0xA74ECB2C, 0xA74ECB2C, /* 136 - 139 */ + 0xA746CB2C, 0xA746CB2C, 0xA746CB2C, 0xA746DB2C, /* 140 - 143 */ + 0xAF46DB2C, 0xAF46EB2C, 0xAF46EB2C, 0xAF4EEB2C, /* 144 - 147 */ + 0xAE4EEB2C, 0xAE4EEB2C, 0xB546FB2C, 0xB554FB2C, /* 148 - 151 */ + 0xB54CEB2C, 0xB554FB2C, 0xB554FB2C, 0xBD54FB2C, /* 152 - 155 */ + 0xBD4CFB2C, 0xBD4CFB2C, 0xBD4CFB2C, 0xBD44EB2C, /* 156 - 159 */ + 0xC544FB2C, 0xC544FB2C, 0xC544FB2C, 0xC5450B2C, /* 160 - 163 */ + 0xC5450B2C, 0xC5450B2C, 0xCD450B2C, 0xCD450B2C, /* 164 - 167 */ + 0xCD3D0B2C, 0xCD3D0B2C, 0xCD3D0B2C, 0xD53D0B2C, /* 168 - 171 */ + 0xD53D0B2C, 0xD53D1B2C, 0xD53D1B2C, 0xD53D1B2C, /* 172 - 175 */ + 0xDD3D1B2C, 0xDD3D1B2C, 0xDD351B2C, 0xDD351B2C, /* 176 - 179 */ + 0xDD351B2C, 0xE5351B2C, 0xE5351B2C, 0xE52D1B2C, /* 180 - 183 */ + 0xE52D1B2C, 0xE52D3B2C, 0xED2D4B2C, 0xED2D1BA8, /* 184 - 187 */ + 0xED2D1BAC, 0xED2D17AC, 0xED2D17AC, 0xED2D27AC, /* 188 - 191 */ + 0xF52D27AC, 0xF52D27AC, 0xF52D2BAC, 0xF52D2BAC, /* 192 - 195 */ + 0xF52D2BAC, 0xFD2D2BAC, 0xFD2B2BAC, 0xFD2B2BAC, /* 196 - 199 */ + 0xFD2B2BAC, 0xFD2B2BAC, 0xFD232BAC, 0xFD232BAC, /* 200 - 203 */ + 0xFD232BAC, 0xFD212BAC, 0xFD212BAC, 0xFD292BAC, /* 204 - 207 */ + 0xFD292BAC, 0xFD2927AC, 0xFD2937AC, 0xFD2923AC, /* 208 - 211 */ + 0xFD2923AC, 0xFD2923AC, 0xFD2923AC, 0xFD2123AC, /* 212 - 215 */ + 0xFD2123AC, 0xFD2123AC, 0xFD2133AC, 0xFD2133AC, /* 216 - 219 */ + 0xFD2133AC, 0xFD2143AC, 0xFD2143AC, 0xFD2143AC, /* 220 - 223 */ + 0xFC2143AC, 0xFC2143AC, 0xFC1943AC, 0xFC1943AC, /* 224 - 227 */ + 0xFC1943AC, 0xFC1943AC, 0xFC1953AC, 0xFC1953AC, /* 228 - 231 */ + 0xFC1953AC, 0xFC1953AC, 0xFC1963AC, 0xFC1963AC, /* 232 - 235 */ + 0xFC1963AC, 0xFC1973AC, 0xFC1973AC, 0xFC1973AC, /* 236 - 239 */ + 0xFC1973AC, 0xFC1973AC, 0xFC1983AC, 0xFC1983AC, /* 240 - 243 */ + 0xFC1983AC, 0xFC1983AC, 0xFC1983AC, 0xFC1993AC, /* 244 - 247 */ + 0xFC1993AC, 0xFC1993AC, 0xFC19A3AC, 0xFC19A3AC, /* 248 - 251 */ + 0xFC19B3AC, 0xFC19B3AC, 0xFC19B3AC, 0xFC19B3AC /* 252 - 255 */ +}; + +/*** End-of-Files ***/ diff --git a/drivers/staging/cxt1e1/comet_tables.h b/drivers/staging/cxt1e1/comet_tables.h new file mode 100644 index 000000000000..80424a26a169 --- /dev/null +++ b/drivers/staging/cxt1e1/comet_tables.h @@ -0,0 +1,85 @@ +/* + * $Id: comet_tables.h,v 1.5 2006/01/02 22:37:31 rickd PMCC4_3_1B $ + */ + +#ifndef _INC_COMET_TBLS_H_ +#define _INC_COMET_TBLS_H_ + +/*----------------------------------------------------------------------------- + * comet_tables.h - Waveform Tables for the PM4351 'COMET' + * + * Copyright (C) 2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For further information, contact via email: support@sbei.com + * SBE, Inc. San Ramon, California U.S.A. + *----------------------------------------------------------------------------- + * RCS info: + * RCS revision: $Revision: 1.5 $ + * Last changed on $Date: 2006/01/02 22:37:31 $ + * Changed by $Author: rickd $ + *----------------------------------------------------------------------------- + * $Log: comet_tables.h,v $ + * Revision 1.5 2006/01/02 22:37:31 rickd + * Double indexed arrays need sizings to avoid CC errors under + * gcc 4.0.0 + * + * Revision 1.4 2005/10/17 23:55:28 rickd + * The 75 Ohm transmit waveform is not supported on PMCC4. + * + * Revision 1.3 2005/09/28 00:10:08 rickd + * Add GNU License info. Structures moved to -C- file. + * + * Revision 1.2 2005/04/28 23:43:04 rickd + * Add RCS tracking heading. + * + *----------------------------------------------------------------------------- + */ + + +/***************************************************************************** +* +* Array names: +* +* TWVLongHaul0DB +* TWVLongHaul7_5DB +* TWVLongHaul15DB +* TWVLongHaul22_5DB +* TWVShortHaul0 +* TWVShortHaul1 +* TWVShortHaul2 +* TWVShortHaul3 +* TWVShortHaul4 +* TWVShortHaul5 +* TWV_E1_120Ohm +* TWV_E1_75Ohm +* T1_Equalizer +* E1_Equalizer +* +*****************************************************************************/ + +extern u_int8_t TWVLongHaul0DB[25][5]; /* T1 Long Haul 0 DB */ +extern u_int8_t TWVLongHaul7_5DB[25][5]; /* T1 Long Haul 7.5 DB */ +extern u_int8_t TWVLongHaul15DB[25][5]; /* T1 Long Haul 15 DB */ +extern u_int8_t TWVLongHaul22_5DB[25][5]; /* T1 Long Haul 22.5 DB */ +extern u_int8_t TWVShortHaul0[25][5]; /* T1 Short Haul 0-110 ft */ +extern u_int8_t TWVShortHaul1[25][5]; /* T1 Short Haul 110-220 ft */ +extern u_int8_t TWVShortHaul2[25][5]; /* T1 Short Haul 220-330 ft */ +extern u_int8_t TWVShortHaul3[25][5]; /* T1 Short Haul 330-440 ft */ +extern u_int8_t TWVShortHaul4[25][5]; /* T1 Short Haul 440-550 ft */ +extern u_int8_t TWVShortHaul5[25][5]; /* T1 Short Haul 550-660 ft */ +extern u_int8_t TWV_E1_75Ohm[25][5]; /* E1 75 Ohm */ +extern u_int8_t TWV_E1_120Ohm[25][5]; /* E1 120 Ohm */ +extern u_int32_t T1_Equalizer[256]; /* T1 Receiver Equalizer */ +extern u_int32_t E1_Equalizer[256]; /* E1 Receiver Equalizer */ + +#endif /* _INC_COMET_TBLS_H_ */ diff --git a/drivers/staging/cxt1e1/functions.c b/drivers/staging/cxt1e1/functions.c new file mode 100644 index 000000000000..c95c62dfb04b --- /dev/null +++ b/drivers/staging/cxt1e1/functions.c @@ -0,0 +1,366 @@ +/* Copyright (C) 2003-2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include "pmcc4_sysdep.h" +#include "sbecom_inline_linux.h" +#include "libsbew.h" +#include "pmcc4.h" + + +#ifdef SBE_INCLUDE_SYMBOLS +#define STATIC +#else +#define STATIC static +#endif + +#if defined(CONFIG_SBE_HDLC_V7) || defined(CONFIG_SBE_WAN256T3_HDLC_V7) || \ + defined(CONFIG_SBE_HDLC_V7_MODULE) || defined(CONFIG_SBE_WAN256T3_HDLC_V7_MODULE) +#define _v7_hdlc_ 1 +#else +#define _v7_hdlc_ 0 +#endif + +#if _v7_hdlc_ +#define V7(x) (x ## _v7) +extern int hdlc_netif_rx_v7 (hdlc_device *, struct sk_buff *); +extern int register_hdlc_device_v7 (hdlc_device *); +extern int unregister_hdlc_device_v7 (hdlc_device *); + +#else +#define V7(x) x +#endif + + +#ifndef USE_MAX_INT_DELAY +static int dummy = 0; + +#endif + +extern int log_level; +extern int drvr_state; + + +#if 1 +u_int32_t +pci_read_32 (u_int32_t *p) +{ +#ifdef FLOW_DEBUG + u_int32_t v; + + FLUSH_PCI_READ (); + v = le32_to_cpu (*p); + if (log_level >= LOG_DEBUG) + printk ("pci_read : %x = %x\n", (u_int32_t) p, v); + return v; +#else + FLUSH_PCI_READ (); /* */ + return le32_to_cpu (*p); +#endif +} + +void +pci_write_32 (u_int32_t *p, u_int32_t v) +{ +#ifdef FLOW_DEBUG + if (log_level >= LOG_DEBUG) + printk ("pci_write: %x = %x\n", (u_int32_t) p, v); +#endif + *p = cpu_to_le32 (v); + FLUSH_PCI_WRITE (); /* This routine is called from routines + * which do multiple register writes + * which themselves need flushing between + * writes in order to guarantee write + * ordering. It is less code-cumbersome + * to flush here-in then to investigate + * and code the many other register + * writing routines. */ +} +#endif + + +void +pci_flush_write (ci_t * ci) +{ + volatile u_int32_t v; + + /* issue a PCI read to flush PCI write thru bridge */ + v = *(u_int32_t *) &ci->reg->glcd; /* any address would do */ + + /* + * return nothing, this just reads PCI bridge interface to flush + * previously written data + */ +} + + +STATIC void +watchdog_func (unsigned long arg) +{ + struct watchdog *wd = (void *) arg; + + if (drvr_state != SBE_DRVR_AVAILABLE) + { + if (log_level >= LOG_MONITOR) + printk (KERN_WARNING "watchdog_func: drvr not available (%x)\n", drvr_state); + return; + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + /* Initialize the tq entry only the first time */ + if (wd->init_tq) + { + wd->init_tq = 0; + wd->tq.routine = wd->func; + wd->tq.sync = 0; + wd->tq.data = wd->softc; + } + schedule_task (&wd->tq); +#else + schedule_work (&wd->work); +#endif + mod_timer (&wd->h, jiffies + wd->ticks); +} + +int OS_init_watchdog(struct watchdog *wdp, void (*f) (void *), void *c, int usec) +{ + wdp->func = f; + wdp->softc = c; + wdp->ticks = (HZ) * (usec / 1000) / 1000; + INIT_WORK(&wdp->work, (void *)f); + init_timer (&wdp->h); + { + ci_t *ci = (ci_t *) c; + + wdp->h.data = (unsigned long) &ci->wd; + } + wdp->h.function = watchdog_func; + return 0; +} + +void +OS_uwait (int usec, char *description) +{ + int tmp; + + if (usec >= 1000) + { + mdelay (usec / 1000); + /* now delay residual */ + tmp = (usec / 1000) * 1000; /* round */ + tmp = usec - tmp; /* residual */ + if (tmp) + { /* wait on residual */ + udelay (tmp); + } + } else + { + udelay (usec); + } +} + +/* dummy short delay routine called as a subroutine so that compiler + * does not optimize/remove its intent (a short delay) + */ + +void +OS_uwait_dummy (void) +{ +#ifndef USE_MAX_INT_DELAY + dummy++; +#else + udelay (1); +#endif +} + + +void +OS_sem_init (void *sem, int state) +{ + switch (state) + { + case SEM_TAKEN: + init_MUTEX_LOCKED ((struct semaphore *) sem); + break; + case SEM_AVAILABLE: + init_MUTEX ((struct semaphore *) sem); + break; + default: /* otherwise, set sem.count to state's + * value */ + sema_init (sem, state); + break; + } +} + + +int +sd_line_is_ok (void *user) +{ + struct net_device *ndev = (struct net_device *) user; + + return (netif_carrier_ok (ndev)); +} + +void +sd_line_is_up (void *user) +{ + struct net_device *ndev = (struct net_device *) user; + + netif_carrier_on (ndev); + return; +} + +void +sd_line_is_down (void *user) +{ + struct net_device *ndev = (struct net_device *) user; + + netif_carrier_off (ndev); + return; +} + +void +sd_disable_xmit (void *user) +{ + struct net_device *dev = (struct net_device *) user; + + netif_stop_queue (dev); + return; +} + +void +sd_enable_xmit (void *user) +{ + struct net_device *dev = (struct net_device *) user; + + netif_wake_queue (dev); + return; +} + +int +sd_queue_stopped (void *user) +{ + struct net_device *ndev = (struct net_device *) user; + + return (netif_queue_stopped (ndev)); +} + +void sd_recv_consume(void *token, size_t len, void *user) +{ + struct net_device *ndev = user; + struct sk_buff *skb = token; + + skb->dev = ndev; + skb_put (skb, len); + skb->protocol = hdlc_type_trans(skb, ndev); + netif_rx(skb); +} + + +/** + ** Read some reserved location w/in the COMET chip as a usable + ** VMETRO trigger point or other trace marking event. + **/ + +#include "comet.h" + +extern ci_t *CI; /* dummy pointer to board ZERO's data */ +void +VMETRO_TRACE (void *x) +{ + u_int32_t y = (u_int32_t) x; + + pci_write_32 ((u_int32_t *) &CI->cpldbase->leds, y); +} + + +void +VMETRO_TRIGGER (ci_t * ci, int x) +{ + comet_t *comet; + volatile u_int32_t data; + + comet = ci->port[0].cometbase; /* default to COMET # 0 */ + + switch (x) + { + default: + case 0: + data = pci_read_32 ((u_int32_t *) &comet->__res24); /* 0x90 */ + break; + case 1: + data = pci_read_32 ((u_int32_t *) &comet->__res25); /* 0x94 */ + break; + case 2: + data = pci_read_32 ((u_int32_t *) &comet->__res26); /* 0x98 */ + break; + case 3: + data = pci_read_32 ((u_int32_t *) &comet->__res27); /* 0x9C */ + break; + case 4: + data = pci_read_32 ((u_int32_t *) &comet->__res88); /* 0x220 */ + break; + case 5: + data = pci_read_32 ((u_int32_t *) &comet->__res89); /* 0x224 */ + break; + case 6: + data = pci_read_32 ((u_int32_t *) &comet->__res8A); /* 0x228 */ + break; + case 7: + data = pci_read_32 ((u_int32_t *) &comet->__res8B); /* 0x22C */ + break; + case 8: + data = pci_read_32 ((u_int32_t *) &comet->__resA0); /* 0x280 */ + break; + case 9: + data = pci_read_32 ((u_int32_t *) &comet->__resA1); /* 0x284 */ + break; + case 10: + data = pci_read_32 ((u_int32_t *) &comet->__resA2); /* 0x288 */ + break; + case 11: + data = pci_read_32 ((u_int32_t *) &comet->__resA3); /* 0x28C */ + break; + case 12: + data = pci_read_32 ((u_int32_t *) &comet->__resA4); /* 0x290 */ + break; + case 13: + data = pci_read_32 ((u_int32_t *) &comet->__resA5); /* 0x294 */ + break; + case 14: + data = pci_read_32 ((u_int32_t *) &comet->__resA6); /* 0x298 */ + break; + case 15: + data = pci_read_32 ((u_int32_t *) &comet->__resA7); /* 0x29C */ + break; + case 16: + data = pci_read_32 ((u_int32_t *) &comet->__res74); /* 0x1D0 */ + break; + case 17: + data = pci_read_32 ((u_int32_t *) &comet->__res75); /* 0x1D4 */ + break; + case 18: + data = pci_read_32 ((u_int32_t *) &comet->__res76); /* 0x1D8 */ + break; + case 19: + data = pci_read_32 ((u_int32_t *) &comet->__res77); /* 0x1DC */ + break; + } +} + + +/*** End-of-File ***/ diff --git a/drivers/staging/cxt1e1/hwprobe.c b/drivers/staging/cxt1e1/hwprobe.c new file mode 100644 index 000000000000..0f9d6539a9a6 --- /dev/null +++ b/drivers/staging/cxt1e1/hwprobe.c @@ -0,0 +1,400 @@ +/* Copyright (C) 2007 One Stop Systems + * Copyright (C) 2003-2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include "pmcc4_sysdep.h" +#include "sbecom_inline_linux.h" +#include "libsbew.h" +#include "pmcc4_private.h" +#include "pmcc4.h" +#include "pmcc4_ioctls.h" +#include "pmc93x6_eeprom.h" +#ifdef CONFIG_PROC_FS +#include "sbeproc.h" +#endif + +#ifdef SBE_INCLUDE_SYMBOLS +#define STATIC +#else +#define STATIC static +#endif + +extern int log_level; +extern int error_flag; +extern int drvr_state; + +/* forward references */ +void c4_stopwd (ci_t *); +struct net_device * __init c4_add_dev (hdw_info_t *, int, unsigned long, unsigned long, int, int); + + +struct s_hdw_info hdw_info[MAX_BOARDS]; + + +void __init +show_two (hdw_info_t * hi, int brdno) +{ + ci_t *ci; + struct pci_dev *pdev; + char *bid; + char *bp, banner[80]; + char sn[6]; + + bp = banner; + memset (banner, 0, 80); /* clear print buffer */ + + ci = (ci_t *)(netdev_priv(hi->ndev)); + bid = sbeid_get_bdname (ci); + switch (hi->promfmt) + { + case PROM_FORMAT_TYPE1: + memcpy (sn, (FLD_TYPE1 *) (hi->mfg_info.pft1.Serial), 6); + break; + case PROM_FORMAT_TYPE2: + memcpy (sn, (FLD_TYPE2 *) (hi->mfg_info.pft2.Serial), 6); + break; + default: + memset (sn, 0, 6); + break; + } + + sprintf (banner, "%s: %s S/N %06X, MUSYCC Rev %02X", + hi->devname, bid, + ((sn[3] << 16) & 0xff0000) | + ((sn[4] << 8) & 0x00ff00) | + (sn[5] & 0x0000ff), + (u_int8_t) hi->revid[0]); + + printk ("%s\n", banner); + + pdev = hi->pdev[0]; + printk ("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n", + hi->devname, "MUSYCC", + (unsigned long) hi->addr_mapped[0], hi->addr[0], + hi->pci_busno, (u_int8_t) PCI_SLOT (pdev->devfn), + (u_int8_t) PCI_FUNC (pdev->devfn), pdev->irq); + + pdev = hi->pdev[1]; + printk ("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n", + hi->devname, "EBUS ", + (unsigned long) hi->addr_mapped[1], hi->addr[1], + hi->pci_busno, (u_int8_t) PCI_SLOT (pdev->devfn), + (u_int8_t) PCI_FUNC (pdev->devfn), pdev->irq); +} + + +void __init +hdw_sn_get (hdw_info_t * hi, int brdno) +{ + /* obtain hardware EEPROM information */ + long addr; + + addr = (long) hi->addr_mapped[1] + EEPROM_OFFSET; + + /* read EEPROM with largest known format size... */ + pmc_eeprom_read_buffer (addr, 0, (char *) hi->mfg_info.data, sizeof (FLD_TYPE2)); + +#if 0 + { + unsigned char *ucp = (unsigned char *) &hi->mfg_info.data; + + printk ("eeprom[00]: %02x %02x %02x %02x %02x %02x %02x %02x\n", + *(ucp + 0), *(ucp + 1), *(ucp + 2), *(ucp + 3), *(ucp + 4), *(ucp + 5), *(ucp + 6), *(ucp + 7)); + printk ("eeprom[08]: %02x %02x %02x %02x %02x %02x %02x %02x\n", + *(ucp + 8), *(ucp + 9), *(ucp + 10), *(ucp + 11), *(ucp + 12), *(ucp + 13), *(ucp + 14), *(ucp + 15)); + printk ("eeprom[16]: %02x %02x %02x %02x %02x %02x %02x %02x\n", + *(ucp + 16), *(ucp + 17), *(ucp + 18), *(ucp + 19), *(ucp + 20), *(ucp + 21), *(ucp + 22), *(ucp + 23)); + printk ("eeprom[24]: %02x %02x %02x %02x %02x %02x %02x %02x\n", + *(ucp + 24), *(ucp + 25), *(ucp + 26), *(ucp + 27), *(ucp + 28), *(ucp + 29), *(ucp + 30), *(ucp + 31)); + printk ("eeprom[32]: %02x %02x %02x %02x %02x %02x %02x %02x\n", + *(ucp + 32), *(ucp + 33), *(ucp + 34), *(ucp + 35), *(ucp + 36), *(ucp + 37), *(ucp + 38), *(ucp + 39)); + printk ("eeprom[40]: %02x %02x %02x %02x %02x %02x %02x %02x\n", + *(ucp + 40), *(ucp + 41), *(ucp + 42), *(ucp + 43), *(ucp + 44), *(ucp + 45), *(ucp + 46), *(ucp + 47)); + } +#endif +#if 0 + printk ("sn: %x %x %x %x %x %x\n", + hi->mfg_info.Serial[0], + hi->mfg_info.Serial[1], + hi->mfg_info.Serial[2], + hi->mfg_info.Serial[3], + hi->mfg_info.Serial[4], + hi->mfg_info.Serial[5]); +#endif + + if ((hi->promfmt = pmc_verify_cksum (&hi->mfg_info.data)) == PROM_FORMAT_Unk) + { + /* bad crc, data is suspect */ + if (log_level >= LOG_WARN) + printk ("%s: EEPROM cksum error\n", hi->devname); + hi->mfg_info_sts = EEPROM_CRCERR; + } else + hi->mfg_info_sts = EEPROM_OK; +} + + +void __init +prep_hdw_info (void) +{ + hdw_info_t *hi; + int i; + + for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) + { + hi->pci_busno = 0xff; + hi->pci_slot = 0xff; + hi->pci_pin[0] = 0; + hi->pci_pin[1] = 0; + hi->ndev = 0; + hi->addr[0] = 0L; + hi->addr[1] = 0L; + hi->addr_mapped[0] = 0L; + hi->addr_mapped[1] = 0L; + } +} + +void +cleanup_ioremap (void) +{ + hdw_info_t *hi; + int i; + + for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) + { + if (hi->pci_slot == 0xff) + break; + if (hi->addr_mapped[0]) + { + iounmap ((void *) (hi->addr_mapped[0])); + release_mem_region ((long) hi->addr[0], hi->len[0]); + hi->addr_mapped[0] = 0; + } + if (hi->addr_mapped[1]) + { + iounmap ((void *) (hi->addr_mapped[1])); + release_mem_region ((long) hi->addr[1], hi->len[1]); + hi->addr_mapped[1] = 0; + } + } +} + + +void +cleanup_devs (void) +{ + hdw_info_t *hi; + int i; + + for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) + { + if (hi->pci_slot == 0xff || !hi->ndev) + break; + c4_stopwd(netdev_priv(hi->ndev)); +#ifdef CONFIG_PROC_FS + sbecom_proc_brd_cleanup(netdev_priv(hi->ndev)); +#endif + unregister_netdev (hi->ndev); + free_irq (hi->pdev[0]->irq, hi->ndev); +#ifdef CONFIG_SBE_PMCC4_NCOMM + free_irq (hi->pdev[1]->irq, hi->ndev); +#endif + OS_kfree (hi->ndev); + } +} + + +STATIC int __init +c4_hdw_init (struct pci_dev * pdev, int found) +{ + hdw_info_t *hi; + int i; + int fun, slot; + unsigned char busno = 0xff; + + /* our MUSYCC chip supports two functions, 0 & 1 */ + if ((fun = PCI_FUNC (pdev->devfn)) > 1) + { + printk (KERN_WARNING "%s: unexpected devfun: 0x%x\n", THIS_MODULE->name, pdev->devfn); + return 0; + } + if (pdev->bus) /* obtain bus number */ + busno = pdev->bus->number; + else + busno = 0; /* default for system PCI inconsistency */ + slot = pdev->devfn & ~0x07; + + /* + * Functions 0 & 1 for a given board (identified by same bus(busno) and + * slot(slot)) are placed into the same 'hardware' structure. The first + * part of the board's functionality will be placed into an unpopulated + * element, identified by "slot==(0xff)". The second part of a board's + * functionality will match the previously loaded slot/busno. + */ + for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) + { + /* + * match with board's first found interface, otherwise this is first + * found + */ + if ((hi->pci_slot == 0xff) || /* new board */ + ((hi->pci_slot == slot) && (hi->bus == pdev->bus))) + break; /* found for-loop exit */ + } + if (i == MAX_BOARDS) /* no match in above loop means MAX + * exceeded */ + { + printk (KERN_WARNING "%s: exceeded number of allowed devices (>%d)?\n", + THIS_MODULE->name, MAX_BOARDS); + return 0; + } + if (pdev->bus) + hi->pci_busno = pdev->bus->number; + else + hi->pci_busno = 0; /* default for system PCI inconsistency */ + hi->pci_slot = slot; + pci_read_config_byte (pdev, PCI_INTERRUPT_PIN, &hi->pci_pin[fun]); + pci_read_config_byte (pdev, PCI_REVISION_ID, &hi->revid[fun]); + hi->bus = pdev->bus; + hi->addr[fun] = pci_resource_start (pdev, 0); + hi->len[fun] = pci_resource_end (pdev, 0) - hi->addr[fun] + 1; + hi->pdev[fun] = pdev; + + { + /* + * create device name from module name, plus add the appropriate + * board number + */ + char *cp = hi->devname; + + strcpy (cp, THIS_MODULE->name); + cp += strlen (cp); /* reposition */ + *cp++ = '-'; + *cp++ = '0' + (found / 2); /* there are two found interfaces per + * board */ + *cp = 0; /* termination */ + } + + return 1; +} + + +status_t __init +c4hw_attach_all (void) +{ + hdw_info_t *hi; + struct pci_dev *pdev = NULL; + int found = 0, i, j; + + error_flag = 0; + prep_hdw_info (); + /*** scan PCI bus for all possible boards */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + while ((pdev = pci_get_device (PCI_VENDOR_ID_CONEXANT, + PCI_DEVICE_ID_CN8474, + pdev))) +#else + while ((pdev = pci_find_device (PCI_VENDOR_ID_CONEXANT, + PCI_DEVICE_ID_CN8474, + pdev))) +#endif + { + if (c4_hdw_init (pdev, found)) + found++; + } + if (!found) + { + printk (KERN_WARNING "%s: No boards found.\n", THIS_MODULE->name); + return ENODEV; + } + /* sanity check for consistant hardware found */ + for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) + { + if (hi->pci_slot != 0xff && (!hi->addr[0] || !hi->addr[1])) + { + printk (KERN_WARNING "%s: something very wrong with pci_get_device.\n", hi->devname); + return EIO; + } + } + /* bring board's memory regions on/line */ + for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) + { + if (hi->pci_slot == 0xff) + break; + for (j = 0; j < 2; j++) + { + if (request_mem_region (hi->addr[j], hi->len[j], hi->devname) == 0) + { + printk (KERN_WARNING "%s: memory in use, addr=0x%lx, len=0x%lx ?\n", + hi->devname, hi->addr[j], hi->len[j]); + cleanup_ioremap (); + return ENOMEM; + } + hi->addr_mapped[j] = (unsigned long) ioremap (hi->addr[j], hi->len[j]); + if (!hi->addr_mapped[j]) + { + printk (KERN_WARNING "%s: ioremap fails, addr=0x%lx, len=0x%lx ?\n", + hi->devname, hi->addr[j], hi->len[j]); + cleanup_ioremap (); + return ENOMEM; + } +#ifdef SBE_MAP_DEBUG + printk (KERN_WARNING "%s: io remapped from phys %x to virt %x\n", + hi->devname, (u_int32_t) hi->addr[j], (u_int32_t) hi->addr_mapped[j]); +#endif + } + } + + drvr_state = SBE_DRVR_AVAILABLE; + + /* Have now memory mapped all boards. Now allow board's access to system */ + for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) + { + if (hi->pci_slot == 0xff) + break; + if (pci_enable_device (hi->pdev[0]) || + pci_enable_device (hi->pdev[1])) + { + drvr_state = SBE_DRVR_DOWN; + printk (KERN_WARNING "%s: failed to enable card %d slot %d\n", + hi->devname, i, hi->pci_slot); + cleanup_devs (); + cleanup_ioremap (); + return EIO; + } + pci_set_master (hi->pdev[0]); + pci_set_master (hi->pdev[1]); + if (!(hi->ndev = c4_add_dev (hi, i, (long) hi->addr_mapped[0], + (long) hi->addr_mapped[1], + hi->pdev[0]->irq, + hi->pdev[1]->irq))) + { + drvr_state = SBE_DRVR_DOWN; + cleanup_ioremap (); + /* NOTE: c4_add_dev() does its own device cleanup */ +#if 0 + cleanup_devs (); +#endif + return error_flag; /* error_flag set w/in add_dev() */ + } + show_two (hi, i); /* displays found information */ + } + return 0; +} + +/*** End-of-File ***/ diff --git a/drivers/staging/cxt1e1/libsbew.h b/drivers/staging/cxt1e1/libsbew.h new file mode 100644 index 000000000000..5c99646cd103 --- /dev/null +++ b/drivers/staging/cxt1e1/libsbew.h @@ -0,0 +1,581 @@ +/* + * $Id: libsbew.h,v 2.1 2005/10/27 18:54:19 rickd PMCC4_3_1B $ + */ + +#ifndef _INC_LIBSBEW_H_ +#define _INC_LIBSBEW_H_ + +/*----------------------------------------------------------------------------- + * libsbew.h - common library elements, charge across mulitple boards + * + * This file contains common Ioctl structures and contents definitions. + * + * Copyright (C) 2004-2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For further information, contact via email: support@sbei.com + * SBE, Inc. San Ramon, California U.S.A. + *----------------------------------------------------------------------------- + * RCS info: + * RCS revision: $Revision: 2.1 $ + * Last changed on $Date: 2005/10/27 18:54:19 $ + * Changed by $Author: rickd $ + *----------------------------------------------------------------------------- + * $Log: libsbew.h,v $ + * Revision 2.1 2005/10/27 18:54:19 rickd + * Add E1PLAIN support. + * + * Revision 2.0 2005/09/28 00:10:08 rickd + * Customized for PMCC4 comet-per-port design. + * + * Revision 1.15 2005/03/29 00:51:31 rickd + * File imported from C1T3 port, Revision 1.15 + *----------------------------------------------------------------------------- + */ + +#ifndef __KERNEL__ +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************/ +/** set driver logging level **/ +/********************************/ + +/* routine/ioctl: wancfg_set_loglevel() - SBE_IOC_SET_LOGLEVEL */ + +#define LOG_NONE 0 +#define LOG_ERROR 1 +#define LOG_SBEBUG3 3 /* hidden, for development/debug usage */ +#define LOG_LSCHANGE 5 /* line state change logging */ +#define LOG_LSIMMEDIATE 6 /* line state change logging w/o hysterisis */ +#define LOG_WARN 8 +#define LOG_MONITOR 10 +#define LOG_SBEBUG12 12 /* hidden, for development/debug usage */ +#define LOG_MONITOR2 14 /* hidden, for development/debug usage */ +#define LOG_DEBUG 16 + + /* TEMPORARY DEFINES *//* RLD DEBUG */ +#define c4_LOG_NONE LOG_NONE +#define c4_LOG_ERROR LOG_ERROR +#define c4_LOG_WARN LOG_WARN +#define c4_LOG_sTrace LOG_MONITOR /* do some trace logging into + * functions */ +#define c4_LOG_DEBUG LOG_DEBUG +#define c4_LOG_MAX LOG_DEBUG + + + +/******************************/ +/** get driver information **/ +/******************************/ + +/* routine/ioctl: wancfg_get_drvinfo() - SBE_IOC_GET_DRVINFO */ + +#define REL_STRLEN 80 + struct sbe_drv_info + { + int rel_strlen; + char release[REL_STRLEN]; + }; + + +/*****************************/ +/** get board information **/ +/*****************************/ + +/* routine/ioctl: wancfg_get_brdinfo() - SBE_IOC_GET_BRDINFO */ + +#define CHNM_STRLEN 16 + struct sbe_brd_info + { + u_int32_t brd_id; /* SBE's unique PCI VENDOR/DEVID */ + u_int32_t brd_sn; + int brd_chan_cnt; /* number of channels being used */ + int brd_port_cnt; /* number of ports being used */ + unsigned char brdno; /* our board number */ + unsigned char brd_pci_speed; /* PCI speed, 33/66Mhz */ + u_int8_t brd_mac_addr[6]; + char first_iname[CHNM_STRLEN]; /* first assigned channel's + * interface name */ + char last_iname[CHNM_STRLEN]; /* last assigned channel's + * interface name */ + u_int8_t brd_hdw_id; /* on/board unique hdw ID */ + u_int8_t reserved8[3]; /* alignment preservation */ + u_int32_t reserved32[3]; /* size preservation */ + }; + +/* These IDs are sometimes available thru pci_ids.h, but not currently. */ + +#define PCI_VENDOR_ID_SBE 0x1176 +#define PCI_DEVICE_ID_WANPMC_C4T1E1 0x0701 /* BID 0x0X, BTYP 0x0X */ +#define PCI_DEVICE_ID_WANPTMC_C4T1E1 0x0702 /* BID 0x41 */ +#define PCI_DEVICE_ID_WANADAPT_HC4T1E1 0x0703 /* BID 0x44 */ +#define PCI_DEVICE_ID_WANPTMC_256T3_T1 0x0704 /* BID 0x42 (T1 Version) */ +#define PCI_DEVICE_ID_WANPCI_C4T1E1 0x0705 /* BID 0x1X, BTYP 0x0X */ +#define PCI_DEVICE_ID_WANPMC_C1T3 0x0706 /* BID 0x45 */ +#define PCI_DEVICE_ID_WANPCI_C2T1E1 0x0707 /* BID 0x1X, BTYP 0x2X */ +#define PCI_DEVICE_ID_WANPCI_C1T1E1 0x0708 /* BID 0x1X, BTYP 0x1X */ +#define PCI_DEVICE_ID_WANPMC_C2T1E1 0x0709 /* BID 0x0X, BTYP 0x2X */ +#define PCI_DEVICE_ID_WANPMC_C1T1E1 0x070A /* BID 0x0X, BTYP 0x1X */ +#define PCI_DEVICE_ID_WANPTMC_256T3_E1 0x070B /* BID 0x46 (E1 Version) */ +#define PCI_DEVICE_ID_WANPTMC_C24TE1 0x070C /* BID 0x47 */ +#define PCI_DEVICE_ID_WANPMC_C4T1E1_L 0x070D /* BID 0x2X, BTYPE 0x0X w/FP + * LEDs */ +#define PCI_DEVICE_ID_WANPMC_C2T1E1_L 0x070E /* BID 0x2X, BTYPE 0x2X w/FP + * LEDs */ +#define PCI_DEVICE_ID_WANPMC_C1T1E1_L 0x070F /* BID 0x2X, BTYPE 0x1X w/FP + * LEDs */ +#define PCI_DEVICE_ID_WANPMC_2SSI 0x0801 +#define PCI_DEVICE_ID_WANPCI_4SSI 0x0802 +#define PCI_DEVICE_ID_WANPMC_2T3E3 0x0900 /* BID 0x43 */ +#define SBE_BOARD_ID(v,id) ((v<<16) | id) + +#define BINFO_PCI_SPEED_unk 0 +#define BINFO_PCI_SPEED_33 1 +#define BINFO_PCI_SPEED_66 2 + +/***************************/ +/** obtain interface ID **/ +/***************************/ + +/* routine/ioctl: wancfg_get_iid() - SBE_IOC_IID_GET */ + + struct sbe_iid_info + { + u_int32_t channum; /* channel requested */ + char iname[CHNM_STRLEN]; /* channel's interface name */ + }; + +/**************************************/ +/** get board address information **/ +/**************************************/ + +/* routine/ioctl: wancfg_get_brdaddr() - SBE_IOC_BRDADDR_GET */ + + struct sbe_brd_addr + { + unsigned char func; /* select PCI address space function */ + unsigned char brdno; /* returns brdno requested */ + unsigned char irq; + unsigned char size; /* returns size of address */ +#define BRDADDR_SIZE_64 1 +#define BRDADDR_SIZE_32 2 + int reserved1; /* mod64 align, reserved for future use */ + + union + { + unsigned long virt64; /* virtual/mapped address */ + u_int32_t virt32[2]; + } v; + union + { + unsigned long phys64; /* physical bus address */ + u_int32_t phys32[2]; + } p; + int reserved2[4]; /* reserved for future use */ + }; + +/**********************************/ +/** read/write board registers **/ +/**********************************/ + +/* routine/ioctl: wancfg_read_vec() - SBE_IOC_READ_VEC */ +/* routine/ioctl: wancfg_write_vec() - SBE_IOC_WRITE_VEC */ + + struct sbecom_wrt_vec + { + u_int32_t reg; + u_int32_t data; + }; + +#define C1T3_CHIP_MSCC_32 0x01000000 +#define C1T3_CHIP_TECT3_8 0x02000000 +#define C1T3_CHIP_CPLD_8 0x03000000 +#define C1T3_CHIP_EEPROM_8 0x04000000 + +#define W256T3_CHIP_MUSYCC_32 0x02000000 +#define W256T3_CHIP_TEMUX_8 0x10000000 +#define W256T3_CHIP_T8110_8 0x20000000 +#define W256T3_CHIP_T8110_32 0x22000000 +#define W256T3_CHIP_CPLD_8 0x30000000 +#define W256T3_CHIP_EEPROM_8 0x40000000 + + +/**********************************/ +/** read write port parameters **/ +/**********************************/ + +/* routine/ioctl: wancfg_getset_port_param() - SBE_IOC_PORT_GET */ +/* routine/ioctl: wancfg_set_port_param() - SBE_IOC_PORT_SET */ + +/* NOTE: this structure supports hardware which supports individual per/port control */ + +struct sbecom_port_param +{ + u_int8_t portnum; + u_int8_t port_mode; /* variations of T1 or E1 mode */ + u_int8_t portStatus; + u_int8_t portP; /* more port parameters (clock source - 0x80; + * and LBO - 0xf; */ + /* bits 0x70 are reserved for future use ) */ +#ifdef SBE_PMCC4_ENABLE + u_int32_t hypersize; /* RLD DEBUG - add this in until I learn how to make this entry obsolete */ +#endif + int reserved[3-1]; /* reserved for future use */ + int _res[4]; +}; + +#define CFG_CLK_PORT_MASK 0x80 /* Loop timing */ +#define CFG_CLK_PORT_INTERNAL 0x80 /* Loop timing */ +#define CFG_CLK_PORT_EXTERNAL 0x00 /* Loop timing */ + +#define CFG_LBO_MASK 0x0F +#define CFG_LBO_unk 0 /* */ +#define CFG_LBO_LH0 1 /* T1 Long Haul (default) */ +#define CFG_LBO_LH7_5 2 /* T1 Long Haul */ +#define CFG_LBO_LH15 3 /* T1 Long Haul */ +#define CFG_LBO_LH22_5 4 /* T1 Long Haul */ +#define CFG_LBO_SH110 5 /* T1 Short Haul */ +#define CFG_LBO_SH220 6 /* T1 Short Haul */ +#define CFG_LBO_SH330 7 /* T1 Short Haul */ +#define CFG_LBO_SH440 8 /* T1 Short Haul */ +#define CFG_LBO_SH550 9 /* T1 Short Haul */ +#define CFG_LBO_SH660 10 /* T1 Short Haul */ +#define CFG_LBO_E75 11 /* E1 75 Ohm */ +#define CFG_LBO_E120 12 /* E1 120 Ohm (default) */ + + +/*************************************/ +/** read write channel parameters **/ +/*************************************/ + +/* routine/ioctl: wancfg_getset_chan_param() - SBE_IOC_CHAN_GET */ +/* routine/ioctl: wancfg_set_chan_param() - SBE_IOC_CHAN_SET */ + +/* NOTE: this structure supports hardware which supports individual per/channel control */ + + struct sbecom_chan_param + { + u_int32_t channum; /* 0: */ +#ifdef SBE_PMCC4_ENABLE + u_int32_t card; /* RLD DEBUG - add this in until I learn how to make this entry obsolete */ + u_int32_t port; /* RLD DEBUG - add this in until I learn how to make this entry obsolete */ + u_int8_t bitmask[32]; +#endif + u_int32_t intr_mask; /* 4: interrupt mask, specify ored + * (SS7_)INTR_* to disable */ + u_int8_t status; /* 8: channel transceiver status (TX_ENABLED, + * RX_ENABLED) */ + u_int8_t chan_mode; /* 9: protocol mode */ + u_int8_t idlecode; /* A: idle code, in (FLAG_7E, FLAG_FF, + * FLAG_00) */ + u_int8_t pad_fill_count; /* B: pad fill count (1-127), 0 - pad + * fill disabled */ + u_int8_t data_inv; /* C: channel data inversion selection */ + u_int8_t mode_56k; /* D: 56kbps mode */ + u_int8_t reserved[2 + 8]; /* E: */ + }; + +/* SS7 interrupt signals */ +#define SS7_INTR_SFILT 0x00000020 +#define SS7_INTR_SDEC 0x00000040 +#define SS7_INTR_SINC 0x00000080 +#define SS7_INTR_SUERR 0x00000100 +/* Other interrupts that can be masked */ +#define INTR_BUFF 0x00000002 +#define INTR_EOM 0x00000004 +#define INTR_MSG 0x00000008 +#define INTR_IDLE 0x00000010 + +/* transceiver status flags */ +#define TX_ENABLED 0x01 +#define RX_ENABLED 0x02 + +/* Protocol modes */ +#define CFG_CH_PROTO_TRANS 0 +#define CFG_CH_PROTO_SS7 1 +#define CFG_CH_PROTO_HDLC_FCS16 2 +#define CFG_CH_PROTO_HDLC_FCS32 3 +#define CFG_CH_PROTO_ISLP_MODE 4 + +/* Possible idle code assignments */ +#define CFG_CH_FLAG_7E 0 +#define CFG_CH_FLAG_FF 1 +#define CFG_CH_FLAG_00 2 + +/* data inversion selection */ +#define CFG_CH_DINV_NONE 0x00 +#define CFG_CH_DINV_RX 0x01 +#define CFG_CH_DINV_TX 0x02 + + +/* Posssible resettable chipsets/functions */ +#define RESET_DEV_TEMUX 1 +#define RESET_DEV_TECT3 RESET_DEV_TEMUX +#define RESET_DEV_PLL 2 + + +/*********************************************/ +/** read reset channel thruput statistics **/ +/*********************************************/ + +/* routine/ioctl: wancfg_get_chan_stats() - SBE_IOC_CHAN_GET_STAT */ +/* routine/ioctl: wancfg_del_chan_stats() - SBE_IOC_CHAN_DEL_STAT */ +/* routine/ioctl: wancfg_get_card_chan_stats() - SBE_IOC_CARD_CHAN_STAT */ + + struct sbecom_chan_stats + { + unsigned long rx_packets; /* total packets received */ + unsigned long tx_packets; /* total packets transmitted */ + unsigned long rx_bytes; /* total bytes received */ + unsigned long tx_bytes; /* total bytes transmitted */ + unsigned long rx_errors;/* bad packets received */ + unsigned long tx_errors;/* packet transmit problems */ + unsigned long rx_dropped; /* no space in linux buffers */ + unsigned long tx_dropped; /* no space available in linux */ + + /* detailed rx_errors: */ + unsigned long rx_length_errors; + unsigned long rx_over_errors; /* receiver ring buff overflow */ + unsigned long rx_crc_errors; /* recved pkt with crc error */ + unsigned long rx_frame_errors; /* recv'd frame alignment error */ + unsigned long rx_fifo_errors; /* recv'r fifo overrun */ + unsigned long rx_missed_errors; /* receiver missed packet */ + + /* detailed tx_errors */ + unsigned long tx_aborted_errors; + unsigned long tx_fifo_errors; + unsigned long tx_pending; + }; + + +/****************************************/ +/** read write card level parameters **/ +/****************************************/ + + /* NOTE: this structure supports hardware which supports per/card control */ + + struct sbecom_card_param + { + u_int8_t framing_type; /* 0: CBP or M13 */ + u_int8_t loopback; /* 1: one of LOOPBACK_* */ + u_int8_t line_build_out; /* 2: boolean */ + u_int8_t receive_eq; /* 3: boolean */ + u_int8_t transmit_ones; /* 4: boolean */ + u_int8_t clock; /* 5: 0 - internal, i>0 - external (recovered + * from framer i) */ + u_int8_t h110enable; /* 6: */ + u_int8_t disable_leds; /* 7: */ + u_int8_t reserved1; /* 8: available - old 256t3 hypersized, but + * never used */ + u_int8_t rear_io; /* 9: rear I/O off/on */ + u_int8_t disable_tx; /* A: disable TX off/on */ + u_int8_t mute_los; /* B: mute LOS off/on */ + u_int8_t los_threshold; /* C: LOS threshold norm/low + * (default: norm) */ + u_int8_t ds1_mode; /* D: DS1 mode T1/E1 (default: T1) */ + u_int8_t ds3_unchan; /* E: DS3 unchannelized mode off/on */ + u_int8_t reserved[1 + 16]; /* reserved for expansion - must be + * ZERO filled */ + }; + +/* framing types */ +#define FRAMING_M13 0 +#define FRAMING_CBP 1 + +/* card level loopback options */ +#define CFG_CARD_LOOPBACK_NONE 0x00 +#define CFG_CARD_LOOPBACK_DIAG 0x01 +#define CFG_CARD_LOOPBACK_LINE 0x02 +#define CFG_CARD_LOOPBACK_PAYLOAD 0x03 + +/* line level loopback options */ +#define CFG_LIU_LOOPBACK_NONE 0x00 +#define CFG_LIU_LOOPBACK_ANALOG 0x10 +#define CFG_LIU_LOOPBACK_DIGITAL 0x11 +#define CFG_LIU_LOOPBACK_REMOTE 0x12 + +/* card level clock options */ +#define CFG_CLK_INTERNAL 0x00 +#define CFG_CLK_EXTERNAL 0x01 + +/* legacy 256T3 loopback values */ +#define LOOPBACK_NONE 0 +#define LOOPBACK_LIU_ANALOG 1 +#define LOOPBACK_LIU_DIGITAL 2 +#define LOOPBACK_FRAMER_DS3 3 +#define LOOPBACK_FRAMER_T1 4 +#define LOOPBACK_LIU_REMOTE 5 + +/* DS1 mode */ +#define CFG_DS1_MODE_MASK 0x0f +#define CFG_DS1_MODE_T1 0x00 +#define CFG_DS1_MODE_E1 0x01 +#define CFG_DS1_MODE_CHANGE 0x80 + +/* DS3 unchannelized values */ +#define CFG_DS3_UNCHAN_MASK 0x01 +#define CFG_DS3_UNCHAN_OFF 0x00 +#define CFG_DS3_UNCHAN_ON 0x01 + + +/************************************/ +/** read write framer parameters **/ +/************************************/ + +/* routine/ioctl: wancfg_get_framer() - SBE_IOC_FRAMER_GET */ +/* routine/ioctl: wancfg_set_framer() - SBE_IOC_FRAMER_SET */ + + struct sbecom_framer_param + { + u_int8_t framer_num; + u_int8_t frame_type; /* SF, ESF, E1PLAIN, E1CAS, E1CRC, E1CRC+CAS */ + u_int8_t loopback_type; /* DIGITAL, LINE, PAYLOAD */ + u_int8_t auto_alarms;/* auto alarms */ + u_int8_t reserved[12]; /* reserved for expansion - must be + * ZERO filled */ + }; + +/* frame types */ +#define CFG_FRAME_NONE 0 +#define CFG_FRAME_SF 1 /* T1 B8ZS */ +#define CFG_FRAME_ESF 2 /* T1 B8ZS */ +#define CFG_FRAME_E1PLAIN 3 /* HDB3 w/o CAS,CRC */ +#define CFG_FRAME_E1CAS 4 /* HDB3 */ +#define CFG_FRAME_E1CRC 5 /* HDB3 */ +#define CFG_FRAME_E1CRC_CAS 6 /* HDB3 */ +#define CFG_FRAME_SF_AMI 7 /* T1 AMI */ +#define CFG_FRAME_ESF_AMI 8 /* T1 AMI */ +#define CFG_FRAME_E1PLAIN_AMI 9 /* E1 AMI w/o CAS,CRC */ +#define CFG_FRAME_E1CAS_AMI 10 /* E1 AMI */ +#define CFG_FRAME_E1CRC_AMI 11 /* E1 AMI */ +#define CFG_FRAME_E1CRC_CAS_AMI 12 /* E1 AMI */ + +#define IS_FRAME_ANY_T1(field) \ + (((field) == CFG_FRAME_NONE) || \ + ((field) == CFG_FRAME_SF) || \ + ((field) == CFG_FRAME_ESF) || \ + ((field) == CFG_FRAME_SF_AMI) || \ + ((field) == CFG_FRAME_ESF_AMI)) + +#define IS_FRAME_ANY_T1ESF(field) \ + (((field) == CFG_FRAME_ESF) || \ + ((field) == CFG_FRAME_ESF_AMI)) + +#define IS_FRAME_ANY_E1(field) \ + (((field) == CFG_FRAME_E1PLAIN) || \ + ((field) == CFG_FRAME_E1CAS) || \ + ((field) == CFG_FRAME_E1CRC) || \ + ((field) == CFG_FRAME_E1CRC_CAS) || \ + ((field) == CFG_FRAME_E1PLAIN_AMI) || \ + ((field) == CFG_FRAME_E1CAS_AMI) || \ + ((field) == CFG_FRAME_E1CRC_AMI) || \ + ((field) == CFG_FRAME_E1CRC_CAS_AMI)) + +#define IS_FRAME_ANY_AMI(field) \ + (((field) == CFG_FRAME_SF_AMI) || \ + ((field) == CFG_FRAME_ESF_AMI) || \ + ((field) == CFG_FRAME_E1PLAIN_AMI) || \ + ((field) == CFG_FRAME_E1CAS_AMI) || \ + ((field) == CFG_FRAME_E1CRC_AMI) || \ + ((field) == CFG_FRAME_E1CRC_CAS_AMI)) + +/* frame level loopback options */ +#define CFG_FRMR_LOOPBACK_NONE 0 +#define CFG_FRMR_LOOPBACK_DIAG 1 +#define CFG_FRMR_LOOPBACK_LINE 2 +#define CFG_FRMR_LOOPBACK_PAYLOAD 3 + + +/****************************************/ +/** read reset card error statistics **/ +/****************************************/ + +/* routine/ioctl: wancfg_get_card_stats() - SBE_IOC_CARD_GET_STAT */ +/* routine/ioctl: wancfg_del_card_stats() - SBE_IOC_CARD_DEL_STAT */ + + struct temux_card_stats + { + struct temux_stats + { + /* TEMUX DS3 PMON counters */ + u_int32_t lcv; + u_int32_t err_framing; + u_int32_t febe; + u_int32_t err_cpbit; + u_int32_t err_parity; + /* TEMUX DS3 FRMR status */ + u_int8_t los; + u_int8_t oof; + u_int8_t red; + u_int8_t yellow; + u_int8_t idle; + u_int8_t ais; + u_int8_t cbit; + /* TEMUX DS3 FEAC receiver */ + u_int8_t feac; + u_int8_t feac_last; + } t; + u_int32_t tx_pending; /* total */ + }; + +/**************************************************************/ + + struct wancfg + { + int cs, ds; + char *p; + }; + typedef struct wancfg wcfg_t; + + extern wcfg_t *wancfg_init (char *, char *); + extern int wancfg_card_blink (wcfg_t *, int); + extern int wancfg_ctl (wcfg_t *, int, void *, int, void *, int); + extern int wancfg_del_card_stats (wcfg_t *); + extern int wancfg_del_chan_stats (wcfg_t *, int); + extern int wancfg_enable_ports (wcfg_t *, int); + extern int wancfg_free (wcfg_t *); + extern int wancfg_get_brdaddr (wcfg_t *, struct sbe_brd_addr *); + extern int wancfg_get_brdinfo (wcfg_t *, struct sbe_brd_info *); + extern int wancfg_get_card (wcfg_t *, struct sbecom_card_param *); + extern int wancfg_get_card_chan_stats (wcfg_t *, struct sbecom_chan_stats *); + extern int wancfg_get_card_sn (wcfg_t *); + extern int wancfg_get_card_stats (wcfg_t *, struct temux_card_stats *); + extern int wancfg_get_chan (wcfg_t *, int, struct sbecom_chan_param *); + extern int wancfg_get_chan_stats (wcfg_t *, int, struct sbecom_chan_stats *); + extern int wancfg_get_drvinfo (wcfg_t *, int, struct sbe_drv_info *); + extern int wancfg_get_framer (wcfg_t *, int, struct sbecom_framer_param *); + extern int wancfg_get_iid (wcfg_t *, int, struct sbe_iid_info *); + extern int wancfg_get_sn (wcfg_t *, unsigned int *); + extern int wancfg_read (wcfg_t *, int, struct sbecom_wrt_vec *); + extern int wancfg_reset_device (wcfg_t *, int); + extern int wancfg_set_card (wcfg_t *, struct sbecom_card_param *); + extern int wancfg_set_chan (wcfg_t *, int, struct sbecom_chan_param *); + extern int wancfg_set_framer (wcfg_t *, int, struct sbecom_framer_param *); + extern int wancfg_set_loglevel (wcfg_t *, uint); + extern int wancfg_write (wcfg_t *, int, struct sbecom_wrt_vec *); + +#ifdef NOT_YET_COMMON + extern int wancfg_get_tsioc (wcfg_t *, struct wanc1t3_ts_hdr *, struct wanc1t3_ts_param *); + extern int wancfg_set_tsioc (wcfg_t *, struct wanc1t3_ts_param *); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /*** _INC_LIBSBEW_H_ ***/ diff --git a/drivers/staging/cxt1e1/linux.c b/drivers/staging/cxt1e1/linux.c new file mode 100644 index 000000000000..23e184da9723 --- /dev/null +++ b/drivers/staging/cxt1e1/linux.c @@ -0,0 +1,1354 @@ +/* Copyright (C) 2007-2008 One Stop Systems + * Copyright (C) 2003-2006 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "pmcc4_sysdep.h" +#include "sbecom_inline_linux.h" +#include "libsbew.h" +#include "pmcc4.h" +#include "pmcc4_ioctls.h" +#include "pmcc4_private.h" +#include "sbeproc.h" + +/***************************************************************************************** + * Error out early if we have compiler trouble. + * + * (This section is included from the kernel's init/main.c as a friendly + * spiderman recommendation...) + * + * Versions of gcc older than that listed below may actually compile and link + * okay, but the end product can have subtle run time bugs. To avoid associated + * bogus bug reports, we flatly refuse to compile with a gcc that is known to be + * too old from the very beginning. + */ +#if (__GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 2) +#error Sorry, your GCC is too old. It builds incorrect kernels. +#endif + +#if __GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ == 0 +#warning gcc-4.1.0 is known to miscompile the kernel. A different compiler version is recommended. +#endif + +/*****************************************************************************************/ + +#ifdef SBE_INCLUDE_SYMBOLS +#define STATIC +#else +#define STATIC static +#endif + +#define CHANNAME "hdlc" + +/*******************************************************************/ +/* forward references */ +status_t c4_chan_work_init (mpi_t *, mch_t *); +void musycc_wq_chan_restart (void *); +status_t __init c4_init (ci_t *, u_char *, u_char *); +status_t __init c4_init2 (ci_t *); +ci_t *__init c4_new (void *); +int __init c4hw_attach_all (void); +void __init hdw_sn_get (hdw_info_t *, int); + +#ifdef CONFIG_SBE_PMCC4_NCOMM +irqreturn_t c4_ebus_intr_th_handler (void *); + +#endif +int c4_frame_rw (ci_t *, struct sbecom_port_param *); +status_t c4_get_port (ci_t *, int); +int c4_loop_port (ci_t *, int, u_int8_t); +int c4_musycc_rw (ci_t *, struct c4_musycc_param *); +int c4_new_chan (ci_t *, int, int, void *); +status_t c4_set_port (ci_t *, int); +int c4_pld_rw (ci_t *, struct sbecom_port_param *); +void cleanup_devs (void); +void cleanup_ioremap (void); +status_t musycc_chan_down (ci_t *, int); +irqreturn_t musycc_intr_th_handler (void *); +int musycc_start_xmit (ci_t *, int, void *); + +extern char pmcc4_OSSI_release[]; +extern ci_t *CI; +extern struct s_hdw_info hdw_info[]; + +#if defined(CONFIG_SBE_HDLC_V7) || defined(CONFIG_SBE_WAN256T3_HDLC_V7) || \ + defined(CONFIG_SBE_HDLC_V7_MODULE) || defined(CONFIG_SBE_WAN256T3_HDLC_V7_MODULE) +#define _v7_hdlc_ 1 +#else +#define _v7_hdlc_ 0 +#endif + +#if _v7_hdlc_ +#define V7(x) (x ## _v7) +extern int hdlc_netif_rx_v7 (hdlc_device *, struct sk_buff *); +extern int register_hdlc_device_v7 (hdlc_device *); +extern int unregister_hdlc_device_v7 (hdlc_device *); + +#else +#define V7(x) x +#endif + +int error_flag; /* module load error reporting */ +int log_level = LOG_ERROR; +int log_level_default = LOG_ERROR; +module_param(log_level, int, 0444); + +int max_mru = MUSYCC_MRU; +int max_mru_default = MUSYCC_MRU; +module_param(max_mru, int, 0444); + +int max_mtu = MUSYCC_MTU; +int max_mtu_default = MUSYCC_MTU; +module_param(max_mtu, int, 0444); + +int max_txdesc_used = MUSYCC_TXDESC_MIN; +int max_txdesc_default = MUSYCC_TXDESC_MIN; +module_param(max_txdesc_used, int, 0444); + +int max_rxdesc_used = MUSYCC_RXDESC_MIN; +int max_rxdesc_default = MUSYCC_RXDESC_MIN; +module_param(max_rxdesc_used, int, 0444); + +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +void * +getuserbychan (int channum) +{ + mch_t *ch; + + ch = c4_find_chan (channum); + return ch ? ch->user : 0; +} + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#define DEV_TO_PRIV(dev) ( * (struct c4_priv **) ((hdlc_device*)(dev)+1)) +#else + +char * +get_hdlc_name (hdlc_device * hdlc) +{ + struct c4_priv *priv = hdlc->priv; + struct net_device *dev = getuserbychan (priv->channum); + + return dev->name; +} +#endif + + +static status_t +mkret (int bsd) +{ + if (bsd > 0) + return -bsd; + else + return bsd; +} + +/***************************************************************************/ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41) +#include + +/*** + * One workqueue (wq) per port (since musycc allows simultaneous group + * commands), with individual data for each channel: + * + * mpi_t -> struct workqueue_struct *wq_port; (dynamically allocated using + * create_workqueue()) + * + * With work structure (work) statically allocated for each channel: + * + * mch_t -> struct work_struct ch_work; (statically allocated using ???) + * + ***/ + + +/* + * Called by the start transmit routine when a channel TX_ENABLE is to be + * issued. This queues the transmission start request among other channels + * within a port's group. + */ +void +c4_wk_chan_restart (mch_t * ch) +{ + mpi_t *pi = ch->up; + +#ifdef RLD_RESTART_DEBUG + printk (">> c4_wk_chan_restart: queueing Port %d Chan %d, mch_t @ %p\n", pi->portnum, ch->channum, ch); +#endif + + /* create new entry w/in workqueue for this channel and let'er rip */ + + /** queue_work (struct workqueue_struct *queue, + ** struct work_struct *work); + **/ + queue_work (pi->wq_port, &ch->ch_work); +} + +status_t +c4_wk_chan_init (mpi_t * pi, mch_t * ch) +{ + /* + * this will be used to restart a stopped channel + */ + + /** INIT_WORK (struct work_struct *work, + ** void (*function)(void *), + ** void *data); + **/ + INIT_WORK(&ch->ch_work, (void *)musycc_wq_chan_restart); + return 0; /* success */ +} + +status_t +c4_wq_port_init (mpi_t * pi) +{ + + char name[16], *np; /* NOTE: name of the queue limited by system + * to 10 characters */ + + if (pi->wq_port) + return 0; /* already initialized */ + + np = name; + memset (name, 0, 16); + sprintf (np, "%s%d", pi->up->devname, pi->portnum); /* IE pmcc4-01) */ + +#ifdef RLD_RESTART_DEBUG + printk (">> c4_wq_port_init: creating workqueue <%s> for Port %d.\n", name, pi->portnum); /* RLD DEBUG */ +#endif + if (!(pi->wq_port = create_singlethread_workqueue (name))) + return ENOMEM; + return 0; /* success */ +} + +void +c4_wq_port_cleanup (mpi_t * pi) +{ + /* + * PORT POINT: cannot call this if WQ is statically allocated w/in + * structure since it calls kfree(wq); + */ + if (pi->wq_port) + { + destroy_workqueue (pi->wq_port); /* this also calls + * flush_workqueue() */ + pi->wq_port = 0; + } +} +#endif + +/***************************************************************************/ + +irqreturn_t +c4_linux_interrupt (int irq, void *dev_instance) +{ + struct net_device *ndev = dev_instance; + + return musycc_intr_th_handler(netdev_priv(ndev)); +} + + +#ifdef CONFIG_SBE_PMCC4_NCOMM +irqreturn_t +c4_ebus_interrupt (int irq, void *dev_instance) +{ + struct net_device *ndev = dev_instance; + + return c4_ebus_intr_th_handler(netdev_priv(ndev)); +} +#endif + + +static int +void_open (struct net_device * ndev) +{ + printk ("%s: trying to open master device !\n", ndev->name); + return -1; +} + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#if !defined(GENERIC_HDLC_VERSION) || (GENERIC_HDLC_VERSION < 4) + +/** Linux 2.4.18-19 **/ +STATIC int +chan_open (hdlc_device * hdlc) +{ + status_t ret; + + if ((ret = c4_chan_up (DEV_TO_PRIV (hdlc)->ci, DEV_TO_PRIV (hdlc)->channum))) + return -ret; + MOD_INC_USE_COUNT; + netif_start_queue (hdlc_to_dev (hdlc)); + return 0; /* no error = success */ +} + +#else + +/** Linux 2.4.20 and higher **/ +STATIC int +chan_open (struct net_device * ndev) +{ + hdlc_device *hdlc = dev_to_hdlc (ndev); + status_t ret; + + hdlc->proto = IF_PROTO_HDLC; + if ((ret = hdlc_open (hdlc))) + { + printk ("%s: hdlc_open failure, err %d.\n", THIS_MODULE->name, ret); + return ret; + } + if ((ret = c4_chan_up (DEV_TO_PRIV (hdlc)->ci, DEV_TO_PRIV (hdlc)->channum))) + return -ret; + MOD_INC_USE_COUNT; + netif_start_queue (hdlc_to_dev (hdlc)); + return 0; /* no error = success */ +} +#endif + +#else + +/** Linux 2.6 **/ +STATIC int +chan_open (struct net_device * ndev) +{ + hdlc_device *hdlc = dev_to_hdlc (ndev); + const struct c4_priv *priv = hdlc->priv; + int ret; + + if ((ret = hdlc_open (ndev))) + { + printk ("%s: hdlc_open failure, err %d.\n", THIS_MODULE->name, ret); + return ret; + } + if ((ret = c4_chan_up (priv->ci, priv->channum))) + return -ret; + try_module_get (THIS_MODULE); + netif_start_queue (ndev); + return 0; /* no error = success */ +} +#endif + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#if !defined(GENERIC_HDLC_VERSION) || (GENERIC_HDLC_VERSION < 4) + +/** Linux 2.4.18-19 **/ +STATIC void +chan_close (hdlc_device * hdlc) +{ + netif_stop_queue (hdlc_to_dev (hdlc)); + musycc_chan_down ((ci_t *) 0, DEV_TO_PRIV (hdlc)->channum); + MOD_DEC_USE_COUNT; +} +#else + +/** Linux 2.4.20 and higher **/ +STATIC int +chan_close (struct net_device * ndev) +{ + hdlc_device *hdlc = dev_to_hdlc (ndev); + + netif_stop_queue (hdlc_to_dev (hdlc)); + musycc_chan_down ((ci_t *) 0, DEV_TO_PRIV (hdlc)->channum); + hdlc_close (hdlc); + MOD_DEC_USE_COUNT; + return 0; +} +#endif + +#else + +/** Linux 2.6 **/ +STATIC int +chan_close (struct net_device * ndev) +{ + hdlc_device *hdlc = dev_to_hdlc (ndev); + const struct c4_priv *priv = hdlc->priv; + + netif_stop_queue (ndev); + musycc_chan_down ((ci_t *) 0, priv->channum); + hdlc_close (ndev); + module_put (THIS_MODULE); + return 0; +} +#endif + + +#if !defined(GENERIC_HDLC_VERSION) || (GENERIC_HDLC_VERSION < 4) + +/** Linux 2.4.18-19 **/ +STATIC int +chan_ioctl (hdlc_device * hdlc, struct ifreq * ifr, int cmd) +{ + if (cmd == HDLCSCLOCK) + { + ifr->ifr_ifru.ifru_ivalue = LINE_DEFAULT; + return 0; + } + return -EINVAL; +} +#endif + + +#if !defined(GENERIC_HDLC_VERSION) || (GENERIC_HDLC_VERSION < 4) +STATIC int +chan_dev_ioctl (struct net_device * hdlc, struct ifreq * ifr, int cmd) +{ + if (cmd == HDLCSCLOCK) + { + ifr->ifr_ifru.ifru_ivalue = LINE_DEFAULT; + return 0; + } + return -EINVAL; +} +#else +STATIC int +chan_dev_ioctl (struct net_device * dev, struct ifreq * ifr, int cmd) +{ + return hdlc_ioctl (dev, ifr, cmd); +} + + +STATIC int +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +chan_attach_noop (hdlc_device * hdlc, unsigned short foo_1, unsigned short foo_2) +#else +chan_attach_noop (struct net_device * ndev, unsigned short foo_1, unsigned short foo_2) +#endif +{ + return 0; /* our driver has nothing to do here, show's + * over, go home */ +} +#endif + + +STATIC struct net_device_stats * +chan_get_stats (struct net_device * ndev) +{ + mch_t *ch; + struct net_device_stats *nstats; + struct sbecom_chan_stats *stats; + int channum; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + channum = DEV_TO_PRIV (ndev)->channum; +#else + { + struct c4_priv *priv; + + priv = (struct c4_priv *) dev_to_hdlc (ndev)->priv; + channum = priv->channum; + } +#endif + + ch = c4_find_chan (channum); + if (ch == NULL) + return NULL; + + nstats = &ndev->stats; + stats = &ch->s; + + memset (nstats, 0, sizeof (struct net_device_stats)); + nstats->rx_packets = stats->rx_packets; + nstats->tx_packets = stats->tx_packets; + nstats->rx_bytes = stats->rx_bytes; + nstats->tx_bytes = stats->tx_bytes; + nstats->rx_errors = stats->rx_length_errors + + stats->rx_over_errors + + stats->rx_crc_errors + + stats->rx_frame_errors + + stats->rx_fifo_errors + + stats->rx_missed_errors; + nstats->tx_errors = stats->tx_dropped + + stats->tx_aborted_errors + + stats->tx_fifo_errors; + nstats->rx_dropped = stats->rx_dropped; + nstats->tx_dropped = stats->tx_dropped; + + nstats->rx_length_errors = stats->rx_length_errors; + nstats->rx_over_errors = stats->rx_over_errors; + nstats->rx_crc_errors = stats->rx_crc_errors; + nstats->rx_frame_errors = stats->rx_frame_errors; + nstats->rx_fifo_errors = stats->rx_fifo_errors; + nstats->rx_missed_errors = stats->rx_missed_errors; + + nstats->tx_aborted_errors = stats->tx_aborted_errors; + nstats->tx_fifo_errors = stats->tx_fifo_errors; + + return nstats; +} + + +static ci_t * +get_ci_by_dev (struct net_device * ndev) +{ + return (ci_t *)(netdev_priv(ndev)); +} + + +#if !defined(GENERIC_HDLC_VERSION) || (GENERIC_HDLC_VERSION < 4) +STATIC int +c4_linux_xmit (hdlc_device * hdlc, struct sk_buff * skb) +{ + int rval; + + rval = musycc_start_xmit (DEV_TO_PRIV (hdlc)->ci, DEV_TO_PRIV (hdlc)->channum, skb); + return -rval; +} +#else /* new */ +STATIC int +c4_linux_xmit (struct sk_buff * skb, struct net_device * ndev) +{ + const struct c4_priv *priv; + int rval; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + priv = DEV_TO_PRIV (ndev); +#else + hdlc_device *hdlc = dev_to_hdlc (ndev); + + priv = hdlc->priv; +#endif + + rval = musycc_start_xmit (priv->ci, priv->channum, skb); + return -rval; +} +#endif /* GENERIC_HDLC_VERSION */ + +static const struct net_device_ops chan_ops = { + .ndo_open = chan_open, + .ndo_stop = chan_close, + .ndo_start_xmit = c4_linux_xmit, + .ndo_do_ioctl = chan_dev_ioctl, + .ndo_get_stats = chan_get_stats, +}; + +STATIC struct net_device * +create_chan (struct net_device * ndev, ci_t * ci, + struct sbecom_chan_param * cp) +{ + hdlc_device *hdlc; + struct net_device *dev; + hdw_info_t *hi; + int ret; + + if (c4_find_chan (cp->channum)) + return 0; /* channel already exists */ + + { + struct c4_priv *priv; + + /* allocate then fill in private data structure */ + priv = OS_kmalloc (sizeof (struct c4_priv)); + if (!priv) + { + printk (KERN_WARNING "%s: no memory for net_device !\n", ci->devname); + return 0; + } + dev = alloc_hdlcdev (priv); + if (!dev) + { + printk (KERN_WARNING "%s: no memory for hdlc_device !\n", ci->devname); + OS_kfree (priv); + return 0; + } + priv->ci = ci; + priv->channum = cp->channum; + } + + hdlc = dev_to_hdlc (dev); + + dev->base_addr = 0; /* not I/O mapped */ + dev->irq = ndev->irq; + dev->type = ARPHRD_RAWHDLC; + *dev->name = 0; /* default ifconfig name = "hdlc" */ + + hi = (hdw_info_t *) ci->hdw_info; + if (hi->mfg_info_sts == EEPROM_OK) + { + switch (hi->promfmt) + { + case PROM_FORMAT_TYPE1: + memcpy (dev->dev_addr, (FLD_TYPE1 *) (hi->mfg_info.pft1.Serial), 6); + break; + case PROM_FORMAT_TYPE2: + memcpy (dev->dev_addr, (FLD_TYPE2 *) (hi->mfg_info.pft2.Serial), 6); + break; + default: + memset (dev->dev_addr, 0, 6); + break; + } + } else + { + memset (dev->dev_addr, 0, 6); + } + + hdlc->xmit = c4_linux_xmit; + + dev->netdev_ops = &chan_ops; + /* + * The native hdlc stack calls this 'attach' routine during + * hdlc_raw_ioctl(), passing parameters for line encoding and parity. + * Since hdlc_raw_ioctl() stack does not interrogate whether an 'attach' + * routine is actually registered or not, we supply a dummy routine which + * does nothing (since encoding and parity are setup for our driver via a + * special configuration application). + */ + + hdlc->attach = chan_attach_noop; + + rtnl_unlock (); /* needed due to Ioctl calling sequence */ + ret = register_hdlc_device (dev); + /* NOTE: setting must occur AFTER registration in order to "take" */ + dev->tx_queue_len = MAX_DEFAULT_IFQLEN; + + rtnl_lock (); /* needed due to Ioctl calling sequence */ + if (ret) + { + if (log_level >= LOG_WARN) + printk ("%s: create_chan[%d] registration error = %d.\n", + ci->devname, cp->channum, ret); + free_netdev (dev); /* cleanup */ + return 0; /* failed to register */ + } + return dev; +} + + +/* the idea here is to get port information and pass it back (using pointer) */ +STATIC status_t +do_get_port (struct net_device * ndev, void *data) +{ + int ret; + ci_t *ci; /* ci stands for card information */ + struct sbecom_port_param pp;/* copy data to kernel land */ + + if (copy_from_user (&pp, data, sizeof (struct sbecom_port_param))) + return -EFAULT; + if (pp.portnum >= MUSYCC_NPORTS) + return -EFAULT; + ci = get_ci_by_dev (ndev); + if (!ci) + return -EINVAL; /* get card info */ + + ret = mkret (c4_get_port (ci, pp.portnum)); + if (ret) + return ret; + if (copy_to_user (data, &ci->port[pp.portnum].p, + sizeof (struct sbecom_port_param))) + return -EFAULT; + return 0; +} + +/* this function copys the user data and then calls the real action function */ +STATIC status_t +do_set_port (struct net_device * ndev, void *data) +{ + ci_t *ci; /* ci stands for card information */ + struct sbecom_port_param pp;/* copy data to kernel land */ + + if (copy_from_user (&pp, data, sizeof (struct sbecom_port_param))) + return -EFAULT; + if (pp.portnum >= MUSYCC_NPORTS) + return -EFAULT; + ci = get_ci_by_dev (ndev); + if (!ci) + return -EINVAL; /* get card info */ + + if (pp.portnum >= ci->max_port) /* sanity check */ + return ENXIO; + + memcpy (&ci->port[pp.portnum].p, &pp, sizeof (struct sbecom_port_param)); + return mkret (c4_set_port (ci, pp.portnum)); +} + +/* work the port loopback mode as per directed */ +STATIC status_t +do_port_loop (struct net_device * ndev, void *data) +{ + struct sbecom_port_param pp; + ci_t *ci; + + if (copy_from_user (&pp, data, sizeof (struct sbecom_port_param))) + return -EFAULT; + ci = get_ci_by_dev (ndev); + if (!ci) + return -EINVAL; + return mkret (c4_loop_port (ci, pp.portnum, pp.port_mode)); +} + +/* set the specified register with the given value / or just read it */ +STATIC status_t +do_framer_rw (struct net_device * ndev, void *data) +{ + struct sbecom_port_param pp; + ci_t *ci; + int ret; + + if (copy_from_user (&pp, data, sizeof (struct sbecom_port_param))) + return -EFAULT; + ci = get_ci_by_dev (ndev); + if (!ci) + return -EINVAL; + ret = mkret (c4_frame_rw (ci, &pp)); + if (ret) + return ret; + if (copy_to_user (data, &pp, sizeof (struct sbecom_port_param))) + return -EFAULT; + return 0; +} + +/* set the specified register with the given value / or just read it */ +STATIC status_t +do_pld_rw (struct net_device * ndev, void *data) +{ + struct sbecom_port_param pp; + ci_t *ci; + int ret; + + if (copy_from_user (&pp, data, sizeof (struct sbecom_port_param))) + return -EFAULT; + ci = get_ci_by_dev (ndev); + if (!ci) + return -EINVAL; + ret = mkret (c4_pld_rw (ci, &pp)); + if (ret) + return ret; + if (copy_to_user (data, &pp, sizeof (struct sbecom_port_param))) + return -EFAULT; + return 0; +} + +/* set the specified register with the given value / or just read it */ +STATIC status_t +do_musycc_rw (struct net_device * ndev, void *data) +{ + struct c4_musycc_param mp; + ci_t *ci; + int ret; + + if (copy_from_user (&mp, data, sizeof (struct c4_musycc_param))) + return -EFAULT; + ci = get_ci_by_dev (ndev); + if (!ci) + return -EINVAL; + ret = mkret (c4_musycc_rw (ci, &mp)); + if (ret) + return ret; + if (copy_to_user (data, &mp, sizeof (struct c4_musycc_param))) + return -EFAULT; + return 0; +} + +STATIC status_t +do_get_chan (struct net_device * ndev, void *data) +{ + struct sbecom_chan_param cp; + int ret; + + if (copy_from_user (&cp, data, + sizeof (struct sbecom_chan_param))) + return -EFAULT; + + if ((ret = mkret (c4_get_chan (cp.channum, &cp)))) + return ret; + + if (copy_to_user (data, &cp, sizeof (struct sbecom_chan_param))) + return -EFAULT; + return 0; +} + +STATIC status_t +do_set_chan (struct net_device * ndev, void *data) +{ + struct sbecom_chan_param cp; + int ret; + ci_t *ci; + + if (copy_from_user (&cp, data, sizeof (struct sbecom_chan_param))) + return -EFAULT; + ci = get_ci_by_dev (ndev); + if (!ci) + return -EINVAL; + switch (ret = mkret (c4_set_chan (cp.channum, &cp))) + { + case 0: + return 0; + default: + return ret; + } +} + +STATIC status_t +do_create_chan (struct net_device * ndev, void *data) +{ + ci_t *ci; + struct net_device *dev; + struct sbecom_chan_param cp; + int ret; + + if (copy_from_user (&cp, data, sizeof (struct sbecom_chan_param))) + return -EFAULT; + ci = get_ci_by_dev (ndev); + if (!ci) + return -EINVAL; + dev = create_chan (ndev, ci, &cp); + if (!dev) + return -EBUSY; + ret = mkret (c4_new_chan (ci, cp.port, cp.channum, dev)); + if (ret) + { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + rtnl_unlock (); /* needed due to Ioctl calling sequence */ + V7 (unregister_hdlc_device) (dev_to_hdlc (dev)); + rtnl_lock (); /* needed due to Ioctl calling sequence */ + OS_kfree (DEV_TO_PRIV (dev)); + OS_kfree (dev); +#else + rtnl_unlock (); /* needed due to Ioctl calling sequence */ + unregister_hdlc_device (dev); + rtnl_lock (); /* needed due to Ioctl calling sequence */ + free_netdev (dev); +#endif + } + return ret; +} + +STATIC status_t +do_get_chan_stats (struct net_device * ndev, void *data) +{ + struct c4_chan_stats_wrap ccs; + int ret; + + if (copy_from_user (&ccs, data, + sizeof (struct c4_chan_stats_wrap))) + return -EFAULT; + switch (ret = mkret (c4_get_chan_stats (ccs.channum, &ccs.stats))) + { + case 0: + break; + default: + return ret; + } + if (copy_to_user (data, &ccs, + sizeof (struct c4_chan_stats_wrap))) + return -EFAULT; + return 0; +} +STATIC status_t +do_set_loglevel (struct net_device * ndev, void *data) +{ + unsigned int log_level; + + if (copy_from_user (&log_level, data, sizeof (int))) + return -EFAULT; + sbecom_set_loglevel (log_level); + return 0; +} + +STATIC status_t +do_deluser (struct net_device * ndev, int lockit) +{ + if (ndev->flags & IFF_UP) + return -EBUSY; + + { + ci_t *ci; + mch_t *ch; + const struct c4_priv *priv; + int channum; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + priv = DEV_TO_PRIV (ndev); +#else + priv = (struct c4_priv *) dev_to_hdlc (ndev)->priv; +#endif + ci = priv->ci; + channum = priv->channum; + + ch = c4_find_chan (channum); + if (ch == NULL) + return -ENOENT; + ch->user = 0; /* will be freed, below */ + } + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + if (lockit) + rtnl_unlock (); /* needed if Ioctl calling sequence */ + V7 (unregister_hdlc_device) (dev_to_hdlc (ndev)); + if (lockit) + rtnl_lock (); /* needed if Ioctl calling sequence */ + OS_kfree (DEV_TO_PRIV (ndev)); + OS_kfree (ndev); +#else + if (lockit) + rtnl_unlock (); /* needed if Ioctl calling sequence */ + unregister_hdlc_device (ndev); + if (lockit) + rtnl_lock (); /* needed if Ioctl calling sequence */ + free_netdev (ndev); +#endif + return 0; +} + +int +do_del_chan (struct net_device * musycc_dev, void *data) +{ + struct sbecom_chan_param cp; + char buf[sizeof (CHANNAME) + 3]; + struct net_device *dev; + int ret; + + if (copy_from_user (&cp, data, + sizeof (struct sbecom_chan_param))) + return -EFAULT; + sprintf (buf, CHANNAME "%d", cp.channum); + if (!(dev = dev_get_by_name (&init_net, buf))) + return -ENOENT; + dev_put (dev); + ret = do_deluser (dev, 1); + if (ret) + return ret; + return c4_del_chan (cp.channum); +} +int c4_reset_board (void *); + +int +do_reset (struct net_device * musycc_dev, void *data) +{ + const struct c4_priv *priv; + int i; + + for (i = 0; i < 128; i++) + { + struct net_device *ndev; + char buf[sizeof (CHANNAME) + 3]; + + sprintf (buf, CHANNAME "%d", i); + if (!(ndev = dev_get_by_name(&init_net, buf))) + continue; + priv = dev_to_hdlc (ndev)->priv; + + if ((unsigned long) (priv->ci) == + (unsigned long) (netdev_priv(musycc_dev))) + { + ndev->flags &= ~IFF_UP; + dev_put (ndev); + netif_stop_queue (ndev); + do_deluser (ndev, 1); + } else + dev_put (ndev); + } + return 0; +} + +int +do_reset_chan_stats (struct net_device * musycc_dev, void *data) +{ + struct sbecom_chan_param cp; + + if (copy_from_user (&cp, data, + sizeof (struct sbecom_chan_param))) + return -EFAULT; + return mkret (c4_del_chan_stats (cp.channum)); +} + +STATIC status_t +c4_ioctl (struct net_device * ndev, struct ifreq * ifr, int cmd) +{ + ci_t *ci; + void *data; + int iocmd, iolen; + status_t ret; + static struct data + { + union + { + u_int8_t c; + u_int32_t i; + struct sbe_brd_info bip; + struct sbe_drv_info dip; + struct sbe_iid_info iip; + struct sbe_brd_addr bap; + struct sbecom_chan_stats stats; + struct sbecom_chan_param param; + struct temux_card_stats cards; + struct sbecom_card_param cardp; + struct sbecom_framer_param frp; + } u; + } arg; + + + if (!capable (CAP_SYS_ADMIN)) + return -EPERM; + if (cmd != SIOCDEVPRIVATE + 15) + return -EINVAL; + if (!(ci = get_ci_by_dev (ndev))) + return -EINVAL; + if (ci->state != C_RUNNING) + return -ENODEV; + if (copy_from_user (&iocmd, ifr->ifr_data, sizeof (iocmd))) + return -EFAULT; +#if 0 + if (copy_from_user (&len, ifr->ifr_data + sizeof (iocmd), sizeof (len))) + return -EFAULT; +#endif + +#if 0 + printk ("c4_ioctl: iocmd %x, dir %x type %x nr %x iolen %d.\n", iocmd, + _IOC_DIR (iocmd), _IOC_TYPE (iocmd), _IOC_NR (iocmd), + _IOC_SIZE (iocmd)); +#endif + iolen = _IOC_SIZE (iocmd); + data = ifr->ifr_data + sizeof (iocmd); + if (copy_from_user (&arg, data, iolen)) + return -EFAULT; + + ret = 0; + switch (iocmd) + { + case SBE_IOC_PORT_GET: + //printk (">> SBE_IOC_PORT_GET Ioctl...\n"); + ret = do_get_port (ndev, data); + break; + case SBE_IOC_PORT_SET: + //printk (">> SBE_IOC_PORT_SET Ioctl...\n"); + ret = do_set_port (ndev, data); + break; + case SBE_IOC_CHAN_GET: + //printk (">> SBE_IOC_CHAN_GET Ioctl...\n"); + ret = do_get_chan (ndev, data); + break; + case SBE_IOC_CHAN_SET: + //printk (">> SBE_IOC_CHAN_SET Ioctl...\n"); + ret = do_set_chan (ndev, data); + break; + case C4_DEL_CHAN: + //printk (">> C4_DEL_CHAN Ioctl...\n"); + ret = do_del_chan (ndev, data); + break; + case SBE_IOC_CHAN_NEW: + ret = do_create_chan (ndev, data); + break; + case SBE_IOC_CHAN_GET_STAT: + ret = do_get_chan_stats (ndev, data); + break; + case SBE_IOC_LOGLEVEL: + ret = do_set_loglevel (ndev, data); + break; + case SBE_IOC_RESET_DEV: + ret = do_reset (ndev, data); + break; + case SBE_IOC_CHAN_DEL_STAT: + ret = do_reset_chan_stats (ndev, data); + break; + case C4_LOOP_PORT: + ret = do_port_loop (ndev, data); + break; + case C4_RW_FRMR: + ret = do_framer_rw (ndev, data); + break; + case C4_RW_MSYC: + ret = do_musycc_rw (ndev, data); + break; + case C4_RW_PLD: + ret = do_pld_rw (ndev, data); + break; + case SBE_IOC_IID_GET: + ret = (iolen == sizeof (struct sbe_iid_info)) ? c4_get_iidinfo (ci, &arg.u.iip) : -EFAULT; + if (ret == 0) /* no error, copy data */ + if (copy_to_user (data, &arg, iolen)) + return -EFAULT; + break; + default: + //printk (">> c4_ioctl: EINVAL - unknown iocmd <%x>\n", iocmd); + ret = -EINVAL; + break; + } + return mkret (ret); +} + +static const struct net_device_ops c4_ops = { + .ndo_open = void_open, + .ndo_start_xmit = c4_linux_xmit, + .ndo_do_ioctl = c4_ioctl, +}; + +static void c4_setup(struct net_device *dev) +{ + dev->type = ARPHRD_VOID; + dev->netdev_ops = &c4_ops; +} + +struct net_device *__init +c4_add_dev (hdw_info_t * hi, int brdno, unsigned long f0, unsigned long f1, + int irq0, int irq1) +{ + struct net_device *ndev; + ci_t *ci; + + ndev = alloc_netdev(sizeof(ci_t), SBE_IFACETMPL, c4_setup); + if (!ndev) + { + printk (KERN_WARNING "%s: no memory for struct net_device !\n", hi->devname); + error_flag = ENOMEM; + return 0; + } + ci = (ci_t *)(netdev_priv(ndev)); + ndev->irq = irq0; + + ci->hdw_info = hi; + ci->state = C_INIT; /* mark as hardware not available */ + ci->next = c4_list; + c4_list = ci; + ci->brdno = ci->next ? ci->next->brdno + 1 : 0; + + if (CI == 0) + CI = ci; /* DEBUG, only board 0 usage */ + + strcpy (ci->devname, hi->devname); + ci->release = &pmcc4_OSSI_release[0]; + + /* tasklet */ +#if defined(SBE_ISR_TASKLET) + tasklet_init (&ci->ci_musycc_isr_tasklet, + (void (*) (unsigned long)) musycc_intr_bh_tasklet, + (unsigned long) ci); + + if (atomic_read (&ci->ci_musycc_isr_tasklet.count) == 0) + tasklet_disable_nosync (&ci->ci_musycc_isr_tasklet); +#elif defined(SBE_ISR_IMMEDIATE) + ci->ci_musycc_isr_tq.routine = (void *) (unsigned long) musycc_intr_bh_tasklet; + ci->ci_musycc_isr_tq.data = ci; +#endif + + + if (register_netdev (ndev) || + (c4_init (ci, (u_char *) f0, (u_char *) f1) != SBE_DRVR_SUCCESS)) + { + OS_kfree (netdev_priv(ndev)); + OS_kfree (ndev); + error_flag = ENODEV; + return 0; + } + /************************************************************* + * int request_irq(unsigned int irq, + * void (*handler)(int, void *, struct pt_regs *), + * unsigned long flags, const char *dev_name, void *dev_id); + * wherein: + * irq -> The interrupt number that is being requested. + * handler -> Pointer to handling function being installed. + * flags -> A bit mask of options related to interrupt management. + * dev_name -> String used in /proc/interrupts to show owner of interrupt. + * dev_id -> Pointer (for shared interrupt lines) to point to its own + * private data area (to identify which device is interrupting). + * + * extern void free_irq(unsigned int irq, void *dev_id); + **************************************************************/ + + if (request_irq (irq0, &c4_linux_interrupt, +#if defined(SBE_ISR_TASKLET) + IRQF_DISABLED | IRQF_SHARED, +#elif defined(SBE_ISR_IMMEDIATE) + IRQF_DISABLED | IRQF_SHARED, +#elif defined(SBE_ISR_INLINE) + IRQF_SHARED, +#endif + ndev->name, ndev)) + { + printk (KERN_WARNING "%s: MUSYCC could not get irq: %d\n", + ndev->name, irq0); + unregister_netdev (ndev); + OS_kfree (netdev_priv(ndev)); + OS_kfree (ndev); + error_flag = EIO; + return 0; + } +#ifdef CONFIG_SBE_PMCC4_NCOMM + if (request_irq (irq1, &c4_ebus_interrupt, IRQF_SHARED, ndev->name, ndev)) + { + printk (KERN_WARNING "%s: EBUS could not get irq: %d\n", + hi->devname, irq1); + unregister_netdev (ndev); + free_irq (irq0, ndev); + OS_kfree (ndev->priv); + OS_kfree (ndev); + error_flag = EIO; + return 0; + } +#endif + + /* setup board identification information */ + + { + u_int32_t tmp; + + hdw_sn_get (hi, brdno); /* also sets PROM format type (promfmt) + * for later usage */ + + switch (hi->promfmt) + { + case PROM_FORMAT_TYPE1: + memcpy (ndev->dev_addr, (FLD_TYPE1 *) (hi->mfg_info.pft1.Serial), 6); + memcpy (&tmp, (FLD_TYPE1 *) (hi->mfg_info.pft1.Id), 4); /* unaligned data + * acquisition */ + ci->brd_id = cpu_to_be32 (tmp); + break; + case PROM_FORMAT_TYPE2: + memcpy (ndev->dev_addr, (FLD_TYPE2 *) (hi->mfg_info.pft2.Serial), 6); + memcpy (&tmp, (FLD_TYPE2 *) (hi->mfg_info.pft2.Id), 4); /* unaligned data + * acquisition */ + ci->brd_id = cpu_to_be32 (tmp); + break; + default: + ci->brd_id = 0; + memset (ndev->dev_addr, 0, 6); + break; + } + +#if 1 + sbeid_set_hdwbid (ci); /* requires bid to be preset */ +#else + sbeid_set_bdtype (ci); /* requires hdw_bid to be preset */ +#endif + + } + +#ifdef CONFIG_PROC_FS + sbecom_proc_brd_init (ci); +#endif +#if defined(SBE_ISR_TASKLET) + tasklet_enable (&ci->ci_musycc_isr_tasklet); +#endif + + + if ((error_flag = c4_init2 (ci)) != SBE_DRVR_SUCCESS) + { +#ifdef CONFIG_PROC_FS + sbecom_proc_brd_cleanup (ci); +#endif + unregister_netdev (ndev); + free_irq (irq1, ndev); + free_irq (irq0, ndev); + OS_kfree (netdev_priv(ndev)); + OS_kfree (ndev); + return 0; /* failure, error_flag is set */ + } + return ndev; +} + +STATIC int __init +c4_mod_init (void) +{ + int rtn; + + printk (KERN_WARNING "%s: %s\n", THIS_MODULE->name, pmcc4_OSSI_release); + if ((rtn = c4hw_attach_all ())) + return -rtn; /* installation failure - see system log */ + + /* housekeeping notifications */ + if (log_level != log_level_default) + printk (KERN_INFO "%s NOTE: driver parameter changed from default %d to %d.\n", + THIS_MODULE->name, log_level_default, log_level); + if (max_mru != max_mru_default) + printk (KERN_INFO "%s NOTE: driver parameter changed from default %d to %d.\n", + THIS_MODULE->name, max_mru_default, max_mru); + if (max_mtu != max_mtu_default) + printk (KERN_INFO "%s NOTE: driver parameter changed from default %d to %d.\n", + THIS_MODULE->name, max_mtu_default, max_mtu); + if (max_rxdesc_used != max_rxdesc_default) + { + if (max_rxdesc_used > 2000) + max_rxdesc_used = 2000; /* out-of-bounds reset */ + printk (KERN_INFO "%s NOTE: driver parameter changed from default %d to %d.\n", + THIS_MODULE->name, max_rxdesc_default, max_rxdesc_used); + } + if (max_txdesc_used != max_txdesc_default) + { + if (max_txdesc_used > 1000) + max_txdesc_used = 1000; /* out-of-bounds reset */ + printk (KERN_INFO "%s NOTE: driver parameter changed from default %d to %d.\n", + THIS_MODULE->name, max_txdesc_default, max_txdesc_used); + } + return 0; /* installation success */ +} + + + /* + * find any still allocated hdlc registrations and unregister via call to + * do_deluser() + */ + +STATIC void __exit +cleanup_hdlc (void) +{ + hdw_info_t *hi; + ci_t *ci; + struct net_device *ndev; + int i, j, k; + + for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) + { + if (hi->ndev) /* a board has been attached */ + { + ci = (ci_t *)(netdev_priv(hi->ndev)); + for (j = 0; j < ci->max_port; j++) + for (k = 0; k < MUSYCC_NCHANS; k++) + if ((ndev = ci->port[j].chan[k]->user)) + { + do_deluser (ndev, 0); + } + } + } +} + + +STATIC void __exit +c4_mod_remove (void) +{ + cleanup_hdlc (); /* delete any missed channels */ + cleanup_devs (); + c4_cleanup (); + cleanup_ioremap (); + printk (KERN_INFO "SBE %s - driver removed.\n", THIS_MODULE->name); +} + +module_init (c4_mod_init); +module_exit (c4_mod_remove); + +#ifndef SBE_INCLUDE_SYMBOLS +#ifndef CONFIG_SBE_WANC24_NCOMM +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +EXPORT_NO_SYMBOLS; +#endif +#endif +#endif + +MODULE_AUTHOR ("SBE Technical Services "); +MODULE_DESCRIPTION ("wanPCI-CxT1E1 Generic HDLC WAN Driver module"); +#ifdef MODULE_LICENSE +MODULE_LICENSE ("GPL"); +#endif + +/*** End-of-File ***/ diff --git a/drivers/staging/cxt1e1/musycc.c b/drivers/staging/cxt1e1/musycc.c new file mode 100644 index 000000000000..650c9c02f223 --- /dev/null +++ b/drivers/staging/cxt1e1/musycc.c @@ -0,0 +1,2180 @@ +/* + * $Id: musycc.c,v 2.1 2007/08/15 23:32:17 rickd PMCC4_3_1B $ + */ + +unsigned int max_intcnt = 0; +unsigned int max_bh = 0; + +/*----------------------------------------------------------------------------- + * musycc.c - + * + * Copyright (C) 2007 One Stop Systems, Inc. + * Copyright (C) 2003-2006 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For further information, contact via email: support@onestopsystems.com + * One Stop Systems, Inc. Escondido, California U.S.A. + *----------------------------------------------------------------------------- + * RCS info: + * RCS revision: $Revision: 2.1 $ + * Last changed on $Date: 2007/08/15 23:32:17 $ + * Changed by $Author: rickd $ + *----------------------------------------------------------------------------- + * $Log: musycc.c,v $ + * Revision 2.1 2007/08/15 23:32:17 rickd + * Use 'if 0' instead of GNU comment delimeter to avoid line wrap induced compiler errors. + * + * Revision 2.0 2007/08/15 22:13:20 rickd + * Update to printf pointer %p usage and correct some UINT to ULONG for + * 64bit comptibility. + * + * Revision 1.7 2006/04/21 00:56:40 rickd + * workqueue files now prefixed with prefix. + * + * Revision 1.6 2005/10/27 18:54:19 rickd + * Clean out old code. Default to HDLC_FCS16, not TRANS. + * + * Revision 1.5 2005/10/17 23:55:28 rickd + * Initial port of NCOMM support patches from original work found + * in pmc_c4t1e1 as updated by NCOMM. Ref: CONFIG_SBE_PMCC4_NCOMM. + * + * Revision 1.4 2005/10/13 20:35:25 rickd + * Cleanup warning for unused variable. + * + * Revision 1.3 2005/10/13 19:19:22 rickd + * Disable redundant driver removal cleanup code. + * + * Revision 1.2 2005/10/11 18:36:16 rickd + * Clean up warning messages caused by de-implemented some associated + * with spin_lock() removals. + * + * Revision 1.1 2005/10/05 00:45:28 rickd + * Re-enable xmit on flow-controlled and full channel to fix restart hang. + * Add some temp spin-lock debug code (rld_spin_owner). + * + * Revision 1.0 2005/09/28 00:10:06 rickd + * Initial release for C4T1E1 support. Lots of transparent + * mode updates. + * + *----------------------------------------------------------------------------- + */ + +char SBEid_pmcc4_musyccc[] = +"@(#)musycc.c - $Revision: 2.1 $ (c) Copyright 2004-2006 SBE, Inc."; + + +#include +#include "pmcc4_sysdep.h" +#include +#include +#include +#include "sbecom_inline_linux.h" +#include "libsbew.h" +#include "pmcc4_private.h" +#include "pmcc4.h" +#include "musycc.h" + +#ifdef SBE_INCLUDE_SYMBOLS +#define STATIC +#else +#define STATIC static +#endif + +#define sd_find_chan(ci,ch) c4_find_chan(ch) + + +/*******************************************************************/ +/* global driver variables */ +extern ci_t *c4_list; +extern int drvr_state; +extern int log_level; + +extern int max_mru; +extern int max_mtu; +extern int max_rxdesc_used; +extern int max_txdesc_used; +extern ci_t *CI; /* dummy pointr to board ZEROE's data - DEBUG + * USAGE */ + + +/*******************************************************************/ +/* forward references */ +void c4_fifo_free (mpi_t *, int); +void c4_wk_chan_restart (mch_t *); +void musycc_bh_tx_eom (mpi_t *, int); +int musycc_chan_up (ci_t *, int); +status_t __init musycc_init (ci_t *); +STATIC void __init musycc_init_port (mpi_t *); +void musycc_intr_bh_tasklet (ci_t *); +void musycc_serv_req (mpi_t *, u_int32_t); +void musycc_update_timeslots (mpi_t *); + +/*******************************************************************/ + +#if 1 +STATIC int +musycc_dump_rxbuffer_ring (mch_t * ch, int lockit) +{ + struct mdesc *m; + unsigned long flags = 0; + + u_int32_t status; + int n; + + if (lockit) + { + spin_lock_irqsave (&ch->ch_rxlock, flags); + } + if (ch->rxd_num == 0) + { + printk (" ZERO receive buffers allocated for this channel."); + } else + { + FLUSH_MEM_READ (); + m = &ch->mdr[ch->rxix_irq_srv]; + for (n = ch->rxd_num; n; n--) + { + status = le32_to_cpu (m->status); + { + printk ("%c %08lx[%2d]: sts %08x (%c%c%c%c:%d.) Data [%08x] Next [%08x]\n", + (m == &ch->mdr[ch->rxix_irq_srv]) ? 'F' : ' ', + (unsigned long) m, n, + status, + m->data ? (status & HOST_RX_OWNED ? 'H' : 'M') : '-', + status & POLL_DISABLED ? 'P' : '-', + status & EOBIRQ_ENABLE ? 'b' : '-', + status & EOMIRQ_ENABLE ? 'm' : '-', + status & LENGTH_MASK, + le32_to_cpu (m->data), le32_to_cpu (m->next)); +#ifdef RLD_DUMP_BUFDATA + { + u_int32_t *dp; + int len = status & LENGTH_MASK; + +#if 1 + if (m->data && (status & HOST_RX_OWNED)) +#else + if (m->data) /* always dump regardless of valid RX + * data */ +#endif + { + dp = (u_int32_t *) OS_phystov ((void *) (le32_to_cpu (m->data))); + if (len >= 0x10) + printk (" %x[%x]: %08X %08X %08X %08x\n", (u_int32_t) dp, len, + *dp, *(dp + 1), *(dp + 2), *(dp + 3)); + else if (len >= 0x08) + printk (" %x[%x]: %08X %08X\n", (u_int32_t) dp, len, + *dp, *(dp + 1)); + else + printk (" %x[%x]: %08X\n", (u_int32_t) dp, len, *dp); + } + } +#endif + } + m = m->snext; + } + } /* -for- */ + printk ("\n"); + + if (lockit) + { + spin_unlock_irqrestore (&ch->ch_rxlock, flags); + } + return 0; +} +#endif + +#if 1 +STATIC int +musycc_dump_txbuffer_ring (mch_t * ch, int lockit) +{ + struct mdesc *m; + unsigned long flags = 0; + u_int32_t status; + int n; + + if (lockit) + { + spin_lock_irqsave (&ch->ch_txlock, flags); + } + if (ch->txd_num == 0) + { + printk (" ZERO transmit buffers allocated for this channel."); + } else + { + FLUSH_MEM_READ (); + m = ch->txd_irq_srv; + for (n = ch->txd_num; n; n--) + { + status = le32_to_cpu (m->status); + { + printk ("%c%c %08lx[%2d]: sts %08x (%c%c%c%c:%d.) Data [%08x] Next [%08x]\n", + (m == ch->txd_usr_add) ? 'F' : ' ', + (m == ch->txd_irq_srv) ? 'L' : ' ', + (unsigned long) m, n, + status, + m->data ? (status & MUSYCC_TX_OWNED ? 'M' : 'H') : '-', + status & POLL_DISABLED ? 'P' : '-', + status & EOBIRQ_ENABLE ? 'b' : '-', + status & EOMIRQ_ENABLE ? 'm' : '-', + status & LENGTH_MASK, + le32_to_cpu (m->data), le32_to_cpu (m->next)); +#ifdef RLD_DUMP_BUFDATA + { + u_int32_t *dp; + int len = status & LENGTH_MASK; + + if (m->data) + { + dp = (u_int32_t *) OS_phystov ((void *) (le32_to_cpu (m->data))); + if (len >= 0x10) + printk (" %x[%x]: %08X %08X %08X %08x\n", (u_int32_t) dp, len, + *dp, *(dp + 1), *(dp + 2), *(dp + 3)); + else if (len >= 0x08) + printk (" %x[%x]: %08X %08X\n", (u_int32_t) dp, len, + *dp, *(dp + 1)); + else + printk (" %x[%x]: %08X\n", (u_int32_t) dp, len, *dp); + } + } +#endif + } + m = m->snext; + } + } /* -for- */ + printk ("\n"); + + if (lockit) + { + spin_unlock_irqrestore (&ch->ch_txlock, flags); + } + return 0; +} +#endif + + +/* + * The following supports a backdoor debug facility which can be used to + * display the state of a board's channel. + */ + +status_t +musycc_dump_ring (ci_t * ci, unsigned int chan) +{ + mch_t *ch; + + if (chan >= MAX_CHANS_USED) + { + return SBE_DRVR_FAIL; /* E2BIG */ + } + { + int bh; + + bh = atomic_read (&ci->bh_pending); + printk (">> bh_pend %d [%d] ihead %d itail %d [%d] th_cnt %d bh_cnt %d wdcnt %d note %d\n", + bh, max_bh, ci->iqp_headx, ci->iqp_tailx, max_intcnt, + ci->intlog.drvr_intr_thcount, + ci->intlog.drvr_intr_bhcount, + ci->wdcount, ci->wd_notify); + max_bh = 0; /* reset counter */ + max_intcnt = 0; /* reset counter */ + } + + if (!(ch = sd_find_chan (dummy, chan))) + { + printk (">> musycc_dump_ring: channel %d not up.\n", chan); + return ENOENT; + } + printk (">> CI %p CHANNEL %3d @ %p: state %x status/p %x/%x\n", ci, chan, ch, ch->state, + ch->status, ch->p.status); + printk ("--------------------------------\nTX Buffer Ring - Channel %d, txd_num %d. (bd/ch pend %d %d), TXD required %d, txpkt %lu\n", + chan, ch->txd_num, + (u_int32_t) atomic_read (&ci->tx_pending), (u_int32_t) atomic_read (&ch->tx_pending), ch->txd_required, ch->s.tx_packets); + printk ("++ User 0x%p IRQ_SRV 0x%p USR_ADD 0x%p QStopped %x, start_tx %x tx_full %d txd_free %d mode %x\n", + ch->user, ch->txd_irq_srv, ch->txd_usr_add, + sd_queue_stopped (ch->user), + ch->ch_start_tx, ch->tx_full, ch->txd_free, ch->p.chan_mode); + musycc_dump_txbuffer_ring (ch, 1); + printk ("RX Buffer Ring - Channel %d, rxd_num %d. IRQ_SRV[%d] 0x%p, start_rx %x rxpkt %lu\n", + chan, ch->rxd_num, ch->rxix_irq_srv, + &ch->mdr[ch->rxix_irq_srv], ch->ch_start_rx, ch->s.rx_packets); + musycc_dump_rxbuffer_ring (ch, 1); + + return SBE_DRVR_SUCCESS; +} + + +status_t +musycc_dump_rings (ci_t * ci, unsigned int start_chan) +{ + unsigned int chan; + + for (chan = start_chan; chan < (start_chan + 5); chan++) + musycc_dump_ring (ci, chan); + return SBE_DRVR_SUCCESS; +} + + +/* + * NOTE on musycc_init_mdt(): These MUSYCC writes are only operational after + * a MUSYCC GROUP_INIT command has been issued. + */ + +void +musycc_init_mdt (mpi_t * pi) +{ + u_int32_t *addr, cfg; + int i; + + /* + * This Idle Code insertion takes effect prior to channel's first + * transmitted message. After that, each message contains its own Idle + * Code information which is to be issued after the message is + * transmitted (Ref.MUSYCC 5.2.2.3: MCENBL bit in Group Configuration + * Descriptor). + */ + + addr = (u_int32_t *) ((u_long) pi->reg + MUSYCC_MDT_BASE03_ADDR); + cfg = CFG_CH_FLAG_7E << IDLE_CODE; + + for (i = 0; i < 32; addr++, i++) + { + pci_write_32 (addr, cfg); + } +} + + +/* Set TX thp to the next unprocessed md */ + +void +musycc_update_tx_thp (mch_t * ch) +{ + struct mdesc *md; + unsigned long flags; + + spin_lock_irqsave (&ch->ch_txlock, flags); + while (1) + { + md = ch->txd_irq_srv; + FLUSH_MEM_READ (); + if (!md->data) + { + /* No MDs with buffers to process */ + spin_unlock_irqrestore (&ch->ch_txlock, flags); + return; + } + if ((le32_to_cpu (md->status)) & MUSYCC_TX_OWNED) + { + /* this is the MD to restart TX with */ + break; + } + /* + * Otherwise, we have a valid, host-owned message descriptor which + * has been successfully transmitted and whose buffer can be freed, + * so... process this MD, it's owned by the host. (This might give + * as a new, updated txd_irq_srv.) + */ + musycc_bh_tx_eom (ch->up, ch->gchan); + } + md = ch->txd_irq_srv; + ch->up->regram->thp[ch->gchan] = cpu_to_le32 (OS_vtophys (md)); + FLUSH_MEM_WRITE (); + + if (ch->tx_full) + { + ch->tx_full = 0; + ch->txd_required = 0; + sd_enable_xmit (ch->user); /* re-enable to catch flow controlled + * channel */ + } + spin_unlock_irqrestore (&ch->ch_txlock, flags); + +#ifdef RLD_TRANS_DEBUG + printk ("++ musycc_update_tx_thp[%d]: setting thp = %p, sts %x\n", ch->channum, md, md->status); +#endif +} + + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41) +/* + * This is the workq task executed by the OS when our queue_work() is + * scheduled and run. It can fire off either RX or TX ACTIVATION depending + * upon the channel's ch_start_tx and ch_start_rx variables. This routine + * is implemented as a work queue so that the call to the service request is + * able to sleep, awaiting an interrupt acknowledgment response (SACK) from + * the hardware. + */ + +void +musycc_wq_chan_restart (void *arg) /* channel private structure */ +{ + mch_t *ch; + mpi_t *pi; + struct mdesc *md; +#if 0 + unsigned long flags; +#endif + + ch = container_of(arg, struct c4_chan_info, ch_work); + pi = ch->up; + +#ifdef RLD_TRANS_DEBUG + printk ("wq_chan_restart[%d]: start_RT[%d/%d] status %x\n", + ch->channum, ch->ch_start_rx, ch->ch_start_tx, ch->status); + +#endif + + /**********************************/ + /** check for RX restart request **/ + /**********************************/ + + if ((ch->ch_start_rx) && (ch->status & RX_ENABLED)) + { + + ch->ch_start_rx = 0; +#if defined(RLD_TRANS_DEBUG) || defined(RLD_RXACT_DEBUG) + { + static int hereb4 = 7; + + if (hereb4) /* RLD DEBUG */ + { + hereb4--; +#ifdef RLD_TRANS_DEBUG + md = &ch->mdr[ch->rxix_irq_srv]; + printk ("++ musycc_wq_chan_restart[%d] CHAN RX ACTIVATE: rxix_irq_srv %d, md %p sts %x, rxpkt %lu\n", + ch->channum, ch->rxix_irq_srv, md, le32_to_cpu (md->status), + ch->s.rx_packets); +#elif defined(RLD_RXACT_DEBUG) + md = &ch->mdr[ch->rxix_irq_srv]; + printk ("++ musycc_wq_chan_restart[%d] CHAN RX ACTIVATE: rxix_irq_srv %d, md %p sts %x, rxpkt %lu\n", + ch->channum, ch->rxix_irq_srv, md, le32_to_cpu (md->status), + ch->s.rx_packets); + musycc_dump_rxbuffer_ring (ch, 1); /* RLD DEBUG */ +#endif + } + } +#endif + musycc_serv_req (pi, SR_CHANNEL_ACTIVATE | SR_RX_DIRECTION | ch->gchan); + } + /**********************************/ + /** check for TX restart request **/ + /**********************************/ + + if ((ch->ch_start_tx) && (ch->status & TX_ENABLED)) + { + /* find next unprocessed message, then set TX thp to it */ + musycc_update_tx_thp (ch); + +#if 0 + spin_lock_irqsave (&ch->ch_txlock, flags); +#endif + md = ch->txd_irq_srv; + if (!md) + { +#ifdef RLD_TRANS_DEBUG + printk ("-- musycc_wq_chan_restart[%d]: WARNING, starting NULL md\n", ch->channum); +#endif +#if 0 + spin_unlock_irqrestore (&ch->ch_txlock, flags); +#endif + } else if (md->data && ((le32_to_cpu (md->status)) & MUSYCC_TX_OWNED)) + { + ch->ch_start_tx = 0; +#if 0 + spin_unlock_irqrestore (&ch->ch_txlock, flags); /* allow interrupts for service request */ +#endif +#ifdef RLD_TRANS_DEBUG + printk ("++ musycc_wq_chan_restart() CHAN TX ACTIVATE: chan %d txd_irq_srv %p = sts %x, txpkt %lu\n", + ch->channum, ch->txd_irq_srv, ch->txd_irq_srv->status, ch->s.tx_packets); +#endif + musycc_serv_req (pi, SR_CHANNEL_ACTIVATE | SR_TX_DIRECTION | ch->gchan); + } +#ifdef RLD_RESTART_DEBUG + else + { + /* retain request to start until retried and we have data to xmit */ + printk ("-- musycc_wq_chan_restart[%d]: DELAYED due to md %p sts %x data %x, start_tx %x\n", + ch->channum, md, + le32_to_cpu (md->status), + le32_to_cpu (md->data), ch->ch_start_tx); + musycc_dump_txbuffer_ring (ch, 0); +#if 0 + spin_unlock_irqrestore (&ch->ch_txlock, flags); /* allow interrupts for service request */ +#endif + } +#endif + } +} +#endif + + + /* + * Channel restart either fires of a workqueue request (2.6) or lodges a + * watchdog activation sequence (2.4). + */ + +void +musycc_chan_restart (mch_t * ch) +{ +#ifdef RLD_RESTART_DEBUG + printk ("++ musycc_chan_restart[%d]: txd_irq_srv @ %p = sts %x\n", + ch->channum, ch->txd_irq_srv, ch->txd_irq_srv->status); +#endif + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41) + /* 2.6 - find next unprocessed message, then set TX thp to it */ +#ifdef RLD_RESTART_DEBUG + printk (">> musycc_chan_restart: scheduling Chan %x workQ @ %p\n", ch->channum, &ch->ch_work); +#endif + c4_wk_chan_restart (ch); /* work queue mechanism fires off: Ref: + * musycc_wq_chan_restart () */ + +#else + + + /* 2.4 - find next unprocessed message, then set TX thp to it */ +#ifdef RLD_RESTART_DEBUG + printk (">> musycc_chan_restart: scheduling Chan %x start_tx %x\n", ch->channum, ch->ch_start_tx); +#endif + /* restart transmission from background loop */ + ch->up->up->wd_notify = WD_NOTIFY_1TX; +#endif +} + + +#if 0 +void +musycc_cleanup (ci_t * ci) +{ + mpi_t *pi; + int i, j; + + /* free up driver resources */ + ci->state = C_INIT; /* mark as hardware not available */ + + for (i = 0; i < ci->max_ports; i++) + { + pi = &ci->port[i]; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41) + c4_wq_port_cleanup (pi); +#endif + for (j = 0; j < MUSYCC_NCHANS; j++) + { + if (pi->chan[j]) + OS_kfree (pi->chan[j]); /* free mch_t struct */ + } + OS_kfree (pi->regram_saved); + } +#if 0 + /* obsolete - watchdog is now static w/in ci_t */ + OS_free_watchdog (ci->wd); +#endif + OS_kfree (ci->iqd_p_saved); + OS_kfree (ci); +} +#endif + +void +rld_put_led (mpi_t * pi, u_int32_t ledval) +{ + static u_int32_t led = 0; + + if (ledval == 0) + led = 0; + else + led |= ledval; + + pci_write_32 ((u_int32_t *) &pi->up->cpldbase->leds, led); /* RLD DEBUG TRANHANG */ +} + + +#define MUSYCC_SR_RETRY_CNT 9 + +void +musycc_serv_req (mpi_t * pi, u_int32_t req) +{ + volatile u_int32_t r; + int rcnt; + + /* + * PORT NOTE: Semaphore protect service loop guarantees only a single + * operation at a time. Per MUSYCC Manual - "Issuing service requests to + * the same channel group without first receiving ACK from each request + * may cause the host to lose track of which service request has been + * acknowledged." + */ + + SD_SEM_TAKE (&pi->sr_sem_busy, "serv"); /* only 1 thru here, per + * group */ + + if (pi->sr_last == req) + { +#ifdef RLD_TRANS_DEBUG + printk (">> same SR, Port %d Req %x\n", pi->portnum, req); +#endif + + /* + * The most likely repeated request is the channel activation command + * which follows the occurrence of a Transparent mode TX ONR or a + * BUFF error. If the previous command was a CHANNEL ACTIVATE, + * precede it with a NOOP command in order maintain coherent control + * of this current (re)ACTIVATE. + */ + + r = (pi->sr_last & ~SR_GCHANNEL_MASK); + if ((r == (SR_CHANNEL_ACTIVATE | SR_TX_DIRECTION)) || + (r == (SR_CHANNEL_ACTIVATE | SR_RX_DIRECTION))) + { +#ifdef RLD_TRANS_DEBUG + printk (">> same CHAN ACT SR, Port %d Req %x => issue SR_NOOP CMD\n", pi->portnum, req); +#endif + SD_SEM_GIVE (&pi->sr_sem_busy); /* allow this next request */ + musycc_serv_req (pi, SR_NOOP); + SD_SEM_TAKE (&pi->sr_sem_busy, "serv"); /* relock & continue w/ + * original req */ + } else if (req == SR_NOOP) + { + /* no need to issue back-to-back SR_NOOP commands at this time */ +#ifdef RLD_TRANS_DEBUG + printk (">> same Port SR_NOOP skipped, Port %d\n", pi->portnum); +#endif + SD_SEM_GIVE (&pi->sr_sem_busy); /* allow this next request */ + return; + } + } + rcnt = 0; + pi->sr_last = req; +rewrite: + pci_write_32 ((u_int32_t *) &pi->reg->srd, req); + FLUSH_MEM_WRITE (); + + /* + * Per MUSYCC Manual, Section 6.1,2 - "When writing an SCR service + * request, the host must ensure at least one PCI bus clock cycle has + * elapsed before writing another service request. To meet this minimum + * elapsed service request write timing interval, it is recommended that + * the host follow any SCR write with another operation which reads from + * the same address." + */ + r = pci_read_32 ((u_int32_t *) &pi->reg->srd); /* adhere to write + * timing imposition */ + + + if ((r != req) && (req != SR_CHIP_RESET) && (++rcnt <= MUSYCC_SR_RETRY_CNT)) + { + if (log_level >= LOG_MONITOR) + printk ("%s: %d - reissue srv req/last %x/%x (hdw reads %x), Chan %d.\n", + pi->up->devname, rcnt, req, pi->sr_last, r, + (pi->portnum * MUSYCC_NCHANS) + (req & 0x1f)); + OS_uwait_dummy (); /* this delay helps reduce reissue counts + * (reason not yet researched) */ + goto rewrite; + } + if (rcnt > MUSYCC_SR_RETRY_CNT) + { + printk (KERN_WARNING "%s: failed service request (#%d)= %x, group %d.\n", + pi->up->devname, MUSYCC_SR_RETRY_CNT, req, pi->portnum); + SD_SEM_GIVE (&pi->sr_sem_busy); /* allow any next request */ + return; + } + if (req == SR_CHIP_RESET) + { + /* + * PORT NOTE: the CHIP_RESET command is NOT ack'd by the MUSYCC, thus + * the upcoming delay is used. Though the MUSYCC documentation + * suggests a read-after-write would supply the required delay, it's + * unclear what CPU/BUS clock speeds might have been assumed when + * suggesting this 'lack of ACK' workaround. Thus the use of uwait. + */ + OS_uwait (100000, "icard"); /* 100ms */ + } else + { + FLUSH_MEM_READ (); + SD_SEM_TAKE (&pi->sr_sem_wait, "sakack"); /* sleep until SACK + * interrupt occurs */ + } + SD_SEM_GIVE (&pi->sr_sem_busy); /* allow any next request */ +} + + +#ifdef SBE_PMCC4_ENABLE +void +musycc_update_timeslots (mpi_t * pi) +{ + int i, ch; + char e1mode = IS_FRAME_ANY_E1 (pi->p.port_mode); + + for (i = 0; i < 32; i++) + { + int usedby = 0, last = 0, ts, j, bits[8]; + + u_int8_t lastval = 0; + + if (((i == 0) && e1mode) || /* disable if E1 mode */ + ((i == 16) && ((pi->p.port_mode == CFG_FRAME_E1CRC_CAS) || (pi->p.port_mode == CFG_FRAME_E1CRC_CAS_AMI))) + || ((i > 23) && (!e1mode))) /* disable if T1 mode */ + { + pi->tsm[i] = 0xff; /* make tslot unavailable for this mode */ + } else + { + pi->tsm[i] = 0x00; /* make tslot available for assignment */ + } + for (j = 0; j < 8; j++) + bits[j] = -1; + for (ch = 0; ch < MUSYCC_NCHANS; ch++) + { + if ((pi->chan[ch]->state == UP) && (pi->chan[ch]->p.bitmask[i])) + { + usedby++; + last = ch; + lastval = pi->chan[ch]->p.bitmask[i]; + for (j = 0; j < 8; j++) + if (lastval & (1 << j)) + bits[j] = ch; + pi->tsm[i] |= lastval; + } + } + if (!usedby) + ts = 0; + else if ((usedby == 1) && (lastval == 0xff)) + ts = (4 << 5) | last; + else if ((usedby == 1) && (lastval == 0x7f)) + ts = (5 << 5) | last; + else + { + int idx; + + if (bits[0] < 0) + ts = (6 << 5) | (idx = last); + else + ts = (7 << 5) | (idx = bits[0]); + for (j = 1; j < 8; j++) + { + pi->regram->rscm[idx * 8 + j] = (bits[j] < 0) ? 0 : (0x80 | bits[j]); + pi->regram->tscm[idx * 8 + j] = (bits[j] < 0) ? 0 : (0x80 | bits[j]); + } + } + pi->regram->rtsm[i] = ts; + pi->regram->ttsm[i] = ts; + } + FLUSH_MEM_WRITE (); + + musycc_serv_req (pi, SR_TIMESLOT_MAP | SR_RX_DIRECTION); + musycc_serv_req (pi, SR_TIMESLOT_MAP | SR_TX_DIRECTION); + musycc_serv_req (pi, SR_SUBCHANNEL_MAP | SR_RX_DIRECTION); + musycc_serv_req (pi, SR_SUBCHANNEL_MAP | SR_TX_DIRECTION); +} +#endif + + +#ifdef SBE_WAN256T3_ENABLE +void +musycc_update_timeslots (mpi_t * pi) +{ + mch_t *ch; + + u_int8_t ts, hmask, tsen; + int gchan; + int i; + +#ifdef SBE_PMCC4_ENABLE + hmask = (0x1f << pi->up->p.hypersize) & 0x1f; +#endif +#ifdef SBE_WAN256T3_ENABLE + hmask = (0x1f << hyperdummy) & 0x1f; +#endif + for (i = 0; i < 128; i++) + { + gchan = ((pi->portnum * MUSYCC_NCHANS) + (i & hmask)) % MUSYCC_NCHANS; + ch = pi->chan[gchan]; + if (ch->p.mode_56k) + tsen = MODE_56KBPS; + else + tsen = MODE_64KBPS; /* also the default */ + ts = ((pi->portnum % 4) == (i / 32)) ? (tsen << 5) | (i & hmask) : 0; + pi->regram->rtsm[i] = ts; + pi->regram->ttsm[i] = ts; + } + FLUSH_MEM_WRITE (); + musycc_serv_req (pi, SR_TIMESLOT_MAP | SR_RX_DIRECTION); + musycc_serv_req (pi, SR_TIMESLOT_MAP | SR_TX_DIRECTION); +} +#endif + + + /* + * This routine converts a generic library channel configuration parameter + * into a hardware specific register value (IE. MUSYCC CCD Register). + */ +u_int32_t +musycc_chan_proto (int proto) +{ + int reg; + + switch (proto) + { + case CFG_CH_PROTO_TRANS: /* 0 */ + reg = MUSYCC_CCD_TRANS; + break; + case CFG_CH_PROTO_SS7: /* 1 */ + reg = MUSYCC_CCD_SS7; + break; + default: + case CFG_CH_PROTO_ISLP_MODE: /* 4 */ + case CFG_CH_PROTO_HDLC_FCS16: /* 2 */ + reg = MUSYCC_CCD_HDLC_FCS16; + break; + case CFG_CH_PROTO_HDLC_FCS32: /* 3 */ + reg = MUSYCC_CCD_HDLC_FCS32; + break; + } + + return reg; +} + +#ifdef SBE_WAN256T3_ENABLE +STATIC void __init +musycc_init_port (mpi_t * pi) +{ + pci_write_32 ((u_int32_t *) &pi->reg->gbp, OS_vtophys (pi->regram)); + + pi->regram->grcd = + __constant_cpu_to_le32 (MUSYCC_GRCD_RX_ENABLE | + MUSYCC_GRCD_TX_ENABLE | + MUSYCC_GRCD_SF_ALIGN | + MUSYCC_GRCD_SUBCHAN_DISABLE | + MUSYCC_GRCD_OOFMP_DISABLE | + MUSYCC_GRCD_COFAIRQ_DISABLE | + MUSYCC_GRCD_MC_ENABLE | + (MUSYCC_GRCD_POLLTH_32 << MUSYCC_GRCD_POLLTH_SHIFT)); + + pi->regram->pcd = + __constant_cpu_to_le32 (MUSYCC_PCD_E1X4_MODE | + MUSYCC_PCD_TXDATA_RISING | + MUSYCC_PCD_TX_DRIVEN); + + /* Message length descriptor */ + pi->regram->mld = __constant_cpu_to_le32 (max_mru | (max_mru << 16)); + FLUSH_MEM_WRITE (); + + musycc_serv_req (pi, SR_GROUP_INIT | SR_RX_DIRECTION); + musycc_serv_req (pi, SR_GROUP_INIT | SR_TX_DIRECTION); + + musycc_init_mdt (pi); + + musycc_update_timeslots (pi); +} +#endif + + +status_t __init +musycc_init (ci_t * ci) +{ + char *regaddr; /* temp for address boundary calculations */ + int i, gchan; + + OS_sem_init (&ci->sem_wdbusy, SEM_AVAILABLE); /* watchdog exclusion */ + + /* + * Per MUSYCC manual, Section 6.3.4 - "The host must allocate a dword + * aligned memory segment for interrupt queue pointers." + */ + +#define INT_QUEUE_BOUNDARY 4 + + regaddr = OS_kmalloc ((INT_QUEUE_SIZE + 1) * sizeof (u_int32_t)); + if (regaddr == 0) + return ENOMEM; + ci->iqd_p_saved = regaddr; /* save orig value for free's usage */ + ci->iqd_p = (u_int32_t *) ((unsigned long) (regaddr + INT_QUEUE_BOUNDARY - 1) & + (~(INT_QUEUE_BOUNDARY - 1))); /* this calculates + * closest boundary */ + + for (i = 0; i < INT_QUEUE_SIZE; i++) + { + ci->iqd_p[i] = __constant_cpu_to_le32 (INT_EMPTY_ENTRY); + } + + for (i = 0; i < ci->max_port; i++) + { + mpi_t *pi = &ci->port[i]; + + /* + * Per MUSYCC manual, Section 6.3.2 - "The host must allocate a 2KB + * bound memory segment for Channel Group 0." + */ + +#define GROUP_BOUNDARY 0x800 + + regaddr = OS_kmalloc (sizeof (struct musycc_groupr) + GROUP_BOUNDARY); + if (regaddr == 0) + { + for (gchan = 0; gchan < i; gchan++) + { + pi = &ci->port[gchan]; + OS_kfree (pi->reg); + pi->reg = 0; + } + return ENOMEM; + } + pi->regram_saved = regaddr; /* save orig value for free's usage */ + pi->regram = (struct musycc_groupr *) ((unsigned long) (regaddr + GROUP_BOUNDARY - 1) & + (~(GROUP_BOUNDARY - 1))); /* this calculates + * closest boundary */ + } + + /* any board centric MUSYCC commands will use group ZERO as its "home" */ + ci->regram = ci->port[0].regram; + musycc_serv_req (&ci->port[0], SR_CHIP_RESET); + + pci_write_32 ((u_int32_t *) &ci->reg->gbp, OS_vtophys (ci->regram)); + pci_flush_write (ci); +#ifdef CONFIG_SBE_PMCC4_NCOMM + ci->regram->__glcd = __constant_cpu_to_le32 (GCD_MAGIC); +#else + /* standard driver POLLS for INTB via CPLD register */ + ci->regram->__glcd = __constant_cpu_to_le32 (GCD_MAGIC | MUSYCC_GCD_INTB_DISABLE); +#endif + + ci->regram->__iqp = cpu_to_le32 (OS_vtophys (&ci->iqd_p[0])); + ci->regram->__iql = __constant_cpu_to_le32 (INT_QUEUE_SIZE - 1); + pci_write_32 ((u_int32_t *) &ci->reg->dacbp, 0); + FLUSH_MEM_WRITE (); + + ci->state = C_RUNNING; /* mark as full interrupt processing + * available */ + + musycc_serv_req (&ci->port[0], SR_GLOBAL_INIT); /* FIRST INTERRUPT ! */ + + /* sanity check settable parameters */ + + if (max_mru > 0xffe) + { + printk (KERN_WARNING "%s: Maximum allowed MRU exceeded, resetting %d to %d.\n", + THIS_MODULE->name, max_mru, 0xffe); + max_mru = 0xffe; + } + if (max_mtu > 0xffe) + { + printk (KERN_WARNING "%s: Maximum allowed MTU exceeded, resetting %d to %d.\n", + THIS_MODULE->name, max_mtu, 0xffe); + max_mtu = 0xffe; + } +#ifdef SBE_WAN256T3_ENABLE + for (i = 0; i < MUSYCC_NPORTS; i++) + musycc_init_port (&ci->port[i]); +#endif + + return SBE_DRVR_SUCCESS; /* no error */ +} + + +void +musycc_bh_tx_eom (mpi_t * pi, int gchan) +{ + mch_t *ch; + struct mdesc *md; + +#if 0 +#ifndef SBE_ISR_INLINE + unsigned long flags; + +#endif +#endif + volatile u_int32_t status; + + ch = pi->chan[gchan]; + if (ch == 0 || ch->state != UP) + { + if (log_level >= LOG_ERROR) + printk ("%s: intr: xmit EOM on uninitialized channel %d\n", pi->up->devname, gchan); + } + if (ch == 0 || ch->mdt == 0) + return; /* note: mdt==0 implies a malloc() + * failure w/in chan_up() routine */ + +#if 0 +#ifdef SBE_ISR_INLINE + spin_lock_irq (&ch->ch_txlock); +#else + spin_lock_irqsave (&ch->ch_txlock, flags); +#endif +#endif + do + { + FLUSH_MEM_READ (); + md = ch->txd_irq_srv; + status = le32_to_cpu (md->status); + + /* + * Note: Per MUSYCC Ref 6.4.9, the host does not poll a host-owned + * Transmit Buffer Descriptor during Transparent Mode. + */ + if (status & MUSYCC_TX_OWNED) + { + int readCount, loopCount; + + /***********************************************************/ + /* HW Bug Fix */ + /* ---------- */ + /* Under certain PCI Bus loading conditions, the data */ + /* associated with an update of Shared Memory is delayed */ + /* relative to its PCI Interrupt. This is caught when */ + /* the host determines it does not yet OWN the descriptor. */ + /***********************************************************/ + + readCount = 0; + while (status & MUSYCC_TX_OWNED) + { + for (loopCount = 0; loopCount < 0x30; loopCount++) + OS_uwait_dummy (); /* use call to avoid optimization + * removal of dummy delay */ + FLUSH_MEM_READ (); + status = le32_to_cpu (md->status); + if (readCount++ > 40) + break; /* don't wait any longer */ + } + if (status & MUSYCC_TX_OWNED) + { + if (log_level >= LOG_MONITOR) + { + printk ("%s: Port %d Chan %2d - unexpected TX msg ownership intr (md %p sts %x)\n", + pi->up->devname, pi->portnum, ch->channum, md, status); + printk ("++ User 0x%p IRQ_SRV 0x%p USR_ADD 0x%p QStopped %x, start_tx %x tx_full %d txd_free %d mode %x\n", + ch->user, ch->txd_irq_srv, ch->txd_usr_add, + sd_queue_stopped (ch->user), + ch->ch_start_tx, ch->tx_full, ch->txd_free, ch->p.chan_mode); + musycc_dump_txbuffer_ring (ch, 0); + } + break; /* Not our mdesc, done */ + } else + { + if (log_level >= LOG_MONITOR) + printk ("%s: Port %d Chan %2d - recovered TX msg ownership [%d] (md %p sts %x)\n", + pi->up->devname, pi->portnum, ch->channum, readCount, md, status); + } + } + ch->txd_irq_srv = md->snext; + + md->data = 0; + if (md->mem_token != 0) + { + /* upcount channel */ + atomic_sub (OS_mem_token_tlen (md->mem_token), &ch->tx_pending); + /* upcount card */ + atomic_sub (OS_mem_token_tlen (md->mem_token), &pi->up->tx_pending); +#ifdef SBE_WAN256T3_ENABLE + if (!atomic_read (&pi->up->tx_pending)) + wan256t3_led (pi->up, LED_TX, 0); +#endif + +#ifdef CONFIG_SBE_WAN256T3_NCOMM + /* callback that our packet was sent */ + { + int hdlcnum = (pi->portnum * 32 + gchan); + + if (hdlcnum >= 228) + { + if (nciProcess_TX_complete) + (*nciProcess_TX_complete) (hdlcnum, + getuserbychan (gchan)); + } + } +#endif /*** CONFIG_SBE_WAN256T3_NCOMM ***/ + + OS_mem_token_free_irq (md->mem_token); + md->mem_token = 0; + } + md->status = 0; +#ifdef RLD_TXFULL_DEBUG + if (log_level >= LOG_MONITOR2) + printk ("~~ tx_eom: tx_full %x txd_free %d -> %d\n", ch->tx_full, ch->txd_free, ch->txd_free + 1); +#endif + ++ch->txd_free; + FLUSH_MEM_WRITE (); + + if ((ch->p.chan_mode != CFG_CH_PROTO_TRANS) && (status & EOBIRQ_ENABLE)) + { + if (log_level >= LOG_MONITOR) + printk ("%s: Mode (%x) incorrect EOB status (%x)\n", + pi->up->devname, ch->p.chan_mode, status); + if ((status & EOMIRQ_ENABLE) == 0) + break; + } + } + while ((ch->p.chan_mode != CFG_CH_PROTO_TRANS) && ((status & EOMIRQ_ENABLE) == 0)); + /* + * NOTE: (The above 'while' is coupled w/ previous 'do', way above.) Each + * Transparent data buffer has the EOB bit, and NOT the EOM bit, set and + * will furthermore have a separate IQD associated with each messages + * buffer. + */ + + FLUSH_MEM_READ (); + /* + * Smooth flow control hysterisis by maintaining task stoppage until half + * the available write buffers are available. + */ + if (ch->tx_full && (ch->txd_free >= (ch->txd_num / 2))) + { + /* + * Then, only releave task stoppage if we actually have enough + * buffers to service the last requested packet. It may require MORE + * than half the available! + */ + if (ch->txd_free >= ch->txd_required) + { + +#ifdef RLD_TXFULL_DEBUG + if (log_level >= LOG_MONITOR2) + printk ("tx_eom[%d]: enable xmit tx_full no more, txd_free %d txd_num/2 %d\n", + ch->channum, + ch->txd_free, ch->txd_num / 2); +#endif + ch->tx_full = 0; + ch->txd_required = 0; + sd_enable_xmit (ch->user); /* re-enable to catch flow controlled + * channel */ + } + } +#ifdef RLD_TXFULL_DEBUG + else if (ch->tx_full) + { + if (log_level >= LOG_MONITOR2) + printk ("tx_eom[%d]: bypass TX enable though room available? (txd_free %d txd_num/2 %d)\n", + ch->channum, + ch->txd_free, ch->txd_num / 2); + } +#endif + + FLUSH_MEM_WRITE (); +#if 0 +#ifdef SBE_ISR_INLINE + spin_unlock_irq (&ch->ch_txlock); +#else + spin_unlock_irqrestore (&ch->ch_txlock, flags); +#endif +#endif +} + + +STATIC void +musycc_bh_rx_eom (mpi_t * pi, int gchan) +{ + mch_t *ch; + void *m, *m2; + struct mdesc *md; + volatile u_int32_t status; + u_int32_t error; + + ch = pi->chan[gchan]; + if (ch == 0 || ch->state != UP) + { + if (log_level > LOG_ERROR) + printk ("%s: intr: receive EOM on uninitialized channel %d\n", pi->up->devname, gchan); + return; + } + if (ch->mdr == 0) + return; /* can this happen ? */ + + for (;;) + { + FLUSH_MEM_READ (); + md = &ch->mdr[ch->rxix_irq_srv]; + status = le32_to_cpu (md->status); + if (!(status & HOST_RX_OWNED)) + break; /* Not our mdesc, done */ + m = md->mem_token; + error = (status >> 16) & 0xf; + if (error == 0) + { +#ifdef CONFIG_SBE_WAN256T3_NCOMM + int hdlcnum = (pi->portnum * 32 + gchan); + + /* + * if the packet number belongs to NCOMM, then send it to the TMS + * driver + */ + if (hdlcnum >= 228) + { + if (nciProcess_RX_packet) + (*nciProcess_RX_packet) (hdlcnum, status & 0x3fff, m, ch->user); + } else +#endif /*** CONFIG_SBE_WAN256T3_NCOMM ***/ + + { + if ((m2 = OS_mem_token_alloc (max_mru))) + { + /* substitute the mbuf+cluster */ + md->mem_token = m2; + md->data = cpu_to_le32 (OS_vtophys (OS_mem_token_data (m2))); + + /* pass the received mbuf upward */ + sd_recv_consume (m, status & LENGTH_MASK, ch->user); + ch->s.rx_packets++; + ch->s.rx_bytes += status & LENGTH_MASK; + } else + { + ch->s.rx_dropped++; + } + } + } else if (error == ERR_FCS) + { + ch->s.rx_crc_errors++; + } else if (error == ERR_ALIGN) + { + ch->s.rx_missed_errors++; + } else if (error == ERR_ABT) + { + ch->s.rx_missed_errors++; + } else if (error == ERR_LNG) + { + ch->s.rx_length_errors++; + } else if (error == ERR_SHT) + { + ch->s.rx_length_errors++; + } + FLUSH_MEM_WRITE (); + status = max_mru; + if (ch->p.chan_mode == CFG_CH_PROTO_TRANS) + status |= EOBIRQ_ENABLE; + md->status = cpu_to_le32 (status); + + /* Check next mdesc in the ring */ + if (++ch->rxix_irq_srv >= ch->rxd_num) + ch->rxix_irq_srv = 0; + FLUSH_MEM_WRITE (); + } +} + + +irqreturn_t +musycc_intr_th_handler (void *devp) +{ + ci_t *ci = (ci_t *) devp; + volatile u_int32_t status, currInt = 0; + u_int32_t nextInt, intCnt; + + /* + * Hardware not available, potential interrupt hang. But since interrupt + * might be shared, just return. + */ + if (ci->state == C_INIT) + { + return IRQ_NONE; + } + /* + * Marked as hardware available. Don't service interrupts, just clear the + * event. + */ + + if (ci->state == C_IDLE) + { + status = pci_read_32 ((u_int32_t *) &ci->reg->isd); + + /* clear the interrupt but process nothing else */ + pci_write_32 ((u_int32_t *) &ci->reg->isd, status); + return IRQ_HANDLED; + } + FLUSH_PCI_READ (); + FLUSH_MEM_READ (); + + status = pci_read_32 ((u_int32_t *) &ci->reg->isd); + nextInt = INTRPTS_NEXTINT (status); + intCnt = INTRPTS_INTCNT (status); + ci->intlog.drvr_intr_thcount++; + + /*********************************************************/ + /* HW Bug Fix */ + /* ---------- */ + /* Under certain PCI Bus loading conditions, the */ + /* MUSYCC looses the data associated with an update */ + /* of its ISD and erroneously returns the immediately */ + /* preceding 'nextInt' value. However, the 'intCnt' */ + /* value appears to be correct. By not starting service */ + /* where the 'missing' 'nextInt' SHOULD point causes */ + /* the IQD not to be serviced - the 'not serviced' */ + /* entries then remain and continue to increase as more */ + /* incorrect ISD's are encountered. */ + /*********************************************************/ + + if (nextInt != INTRPTS_NEXTINT (ci->intlog.this_status_new)) + { + if (log_level >= LOG_MONITOR) + { + printk ("%s: note - updated ISD from %08x to %08x\n", + ci->devname, status, + (status & (~INTRPTS_NEXTINT_M)) | ci->intlog.this_status_new); + } + /* + * Replace bogus status with software corrected value. + * + * It's not known whether, during this problem occurrence, if the + * INTFULL bit is correctly reported or not. + */ + status = (status & (~INTRPTS_NEXTINT_M)) | (ci->intlog.this_status_new); + nextInt = INTRPTS_NEXTINT (status); + } + /**********************************************/ + /* Cn847x Bug Fix */ + /* -------------- */ + /* Fix for inability to write back same index */ + /* as read for a full interrupt queue. */ + /**********************************************/ + + if (intCnt == INT_QUEUE_SIZE) + { + currInt = ((intCnt - 1) + nextInt) & (INT_QUEUE_SIZE - 1); + } else + /************************************************/ + /* Interrupt Write Location Issues */ + /* ------------------------------- */ + /* When the interrupt status descriptor is */ + /* written, the interrupt line is de-asserted */ + /* by the Cn847x. In the case of MIPS */ + /* microprocessors, this must occur at the */ + /* beginning of the interrupt handler so that */ + /* the interrupt handle is not re-entered due */ + /* to interrupt dis-assertion latency. */ + /* In the case of all other processors, this */ + /* action should occur at the end of the */ + /* interrupt handler to avoid overwriting the */ + /* interrupt queue. */ + /************************************************/ + + if (intCnt) + { + currInt = (intCnt + nextInt) & (INT_QUEUE_SIZE - 1); + } else + { + /* + * NOTE: Servicing an interrupt whose ISD contains a count of ZERO + * can be indicative of a Shared Interrupt chain. Our driver can be + * called from the system's interrupt handler as a matter of the OS + * walking the chain. As the chain is walked, the interrupt will + * eventually be serviced by the correct driver/handler. + */ +#if 0 + /* chained interrupt = not ours */ + printk (">> %s: intCnt NULL, sts %x, possibly a chained interrupt!\n", + ci->devname, status); +#endif + return IRQ_NONE; + } + + ci->iqp_tailx = currInt; + + currInt <<= INTRPTS_NEXTINT_S; + ci->intlog.last_status_new = ci->intlog.this_status_new; + ci->intlog.this_status_new = currInt; + + if ((log_level >= LOG_WARN) && (status & INTRPTS_INTFULL_M)) + { + printk ("%s: Interrupt queue full condition occurred\n", ci->devname); + } + if (log_level >= LOG_DEBUG) + printk ("%s: interrupts pending, isd @ 0x%p: %x curr %d cnt %d NEXT %d\n", + ci->devname, &ci->reg->isd, + status, nextInt, intCnt, (intCnt + nextInt) & (INT_QUEUE_SIZE - 1)); + + FLUSH_MEM_WRITE (); +#if defined(SBE_ISR_TASKLET) + pci_write_32 ((u_int32_t *) &ci->reg->isd, currInt); + atomic_inc (&ci->bh_pending); + tasklet_schedule (&ci->ci_musycc_isr_tasklet); +#elif defined(SBE_ISR_IMMEDIATE) + pci_write_32 ((u_int32_t *) &ci->reg->isd, currInt); + atomic_inc (&ci->bh_pending); + queue_task (&ci->ci_musycc_isr_tq, &tq_immediate); + mark_bh (IMMEDIATE_BH); +#elif defined(SBE_ISR_INLINE) + (void) musycc_intr_bh_tasklet (ci); + pci_write_32 ((u_int32_t *) &ci->reg->isd, currInt); +#endif + return IRQ_HANDLED; +} + + +#if defined(SBE_ISR_IMMEDIATE) +unsigned long +#else +void +#endif +musycc_intr_bh_tasklet (ci_t * ci) +{ + mpi_t *pi; + mch_t *ch; + unsigned int intCnt; + volatile u_int32_t currInt = 0; + volatile unsigned int headx, tailx; + int readCount, loopCount; + int group, gchan, event, err, tx; + u_int32_t badInt = INT_EMPTY_ENTRY; + u_int32_t badInt2 = INT_EMPTY_ENTRY2; + + /* + * Hardware not available, potential interrupt hang. But since interrupt + * might be shared, just return. + */ + if ((drvr_state != SBE_DRVR_AVAILABLE) || (ci->state == C_INIT)) + { +#if defined(SBE_ISR_IMMEDIATE) + return 0L; +#else + return; +#endif + } +#if defined(SBE_ISR_TASKLET) || defined(SBE_ISR_IMMEDIATE) + if (drvr_state != SBE_DRVR_AVAILABLE) + { +#if defined(SBE_ISR_TASKLET) + return; +#elif defined(SBE_ISR_IMMEDIATE) + return 0L; +#endif + } +#elif defined(SBE_ISR_INLINE) + /* no semaphore taken, no double checks */ +#endif + + ci->intlog.drvr_intr_bhcount++; + FLUSH_MEM_READ (); + { + unsigned int bh = atomic_read (&ci->bh_pending); + + max_bh = max (bh, max_bh); + } + atomic_set (&ci->bh_pending, 0);/* if here, no longer pending */ + while ((headx = ci->iqp_headx) != (tailx = ci->iqp_tailx)) + { + intCnt = (tailx >= headx) ? (tailx - headx) : (tailx - headx + INT_QUEUE_SIZE); + currInt = le32_to_cpu (ci->iqd_p[headx]); + + max_intcnt = max (intCnt, max_intcnt); /* RLD DEBUG */ + + /**************************************************/ + /* HW Bug Fix */ + /* ---------- */ + /* The following code checks for the condition */ + /* of interrupt assertion before interrupt */ + /* queue update. This is a problem on several */ + /* PCI-Local bridge chips found on some products. */ + /**************************************************/ + + readCount = 0; + if ((currInt == badInt) || (currInt == badInt2)) + ci->intlog.drvr_int_failure++; + + while ((currInt == badInt) || (currInt == badInt2)) + { + for (loopCount = 0; loopCount < 0x30; loopCount++) + OS_uwait_dummy (); /* use call to avoid optimization removal + * of dummy delay */ + FLUSH_MEM_READ (); + currInt = le32_to_cpu (ci->iqd_p[headx]); + if (readCount++ > 20) + break; + } + + if ((currInt == badInt) || (currInt == badInt2)) /* catch failure of Bug + * Fix checking */ + { + if (log_level >= LOG_WARN) + printk ("%s: Illegal Interrupt Detected @ 0x%p, mod %d.)\n", + ci->devname, &ci->iqd_p[headx], headx); + + /* + * If the descriptor has not recovered, then leaving the EMPTY + * entry set will not signal to the MUSYCC that this descriptor + * has been serviced. The Interrupt Queue can then start loosing + * available descriptors and MUSYCC eventually encounters and + * reports the INTFULL condition. Per manual, changing any bit + * marks descriptor as available, thus the use of different + * EMPTY_ENTRY values. + */ + + if (currInt == badInt) + { + ci->iqd_p[headx] = __constant_cpu_to_le32 (INT_EMPTY_ENTRY2); + } else + { + ci->iqd_p[headx] = __constant_cpu_to_le32 (INT_EMPTY_ENTRY); + } + ci->iqp_headx = (headx + 1) & (INT_QUEUE_SIZE - 1); /* insure wrapness */ + FLUSH_MEM_WRITE (); + FLUSH_MEM_READ (); + continue; + } + group = INTRPT_GRP (currInt); + gchan = INTRPT_CH (currInt); + event = INTRPT_EVENT (currInt); + err = INTRPT_ERROR (currInt); + tx = currInt & INTRPT_DIR_M; + + ci->iqd_p[headx] = __constant_cpu_to_le32 (INT_EMPTY_ENTRY); + FLUSH_MEM_WRITE (); + + if (log_level >= LOG_DEBUG) + { + if (err != 0) + printk (" %08x -> err: %2d,", currInt, err); + + printk ("+ interrupt event: %d, grp: %d, chan: %2d, side: %cX\n", + event, group, gchan, tx ? 'T' : 'R'); + } + pi = &ci->port[group]; /* notice that here we assume 1-1 group - + * port mapping */ + ch = pi->chan[gchan]; + switch (event) + { + case EVE_SACK: /* Service Request Acknowledge */ + if (log_level >= LOG_DEBUG) + { + volatile u_int32_t r; + + r = pci_read_32 ((u_int32_t *) &pi->reg->srd); + printk ("- SACK cmd: %08x (hdw= %08x)\n", pi->sr_last, r); + } + SD_SEM_GIVE (&pi->sr_sem_wait); /* wake up waiting process */ + break; + case EVE_CHABT: /* Change To Abort Code (0x7e -> 0xff) */ + case EVE_CHIC: /* Change To Idle Code (0xff -> 0x7e) */ + break; + case EVE_EOM: /* End Of Message */ + case EVE_EOB: /* End Of Buffer (Transparent mode) */ + if (tx) + { + musycc_bh_tx_eom (pi, gchan); + } else + { + musycc_bh_rx_eom (pi, gchan); + } +#if 0 + break; +#else + /* + * MUSYCC Interrupt Descriptor section states that EOB and EOM + * can be combined with the NONE error (as well as others). So + * drop thru to catch this... + */ +#endif + case EVE_NONE: + if (err == ERR_SHT) + { + ch->s.rx_length_errors++; + } + break; + default: + if (log_level >= LOG_WARN) + printk ("%s: unexpected interrupt event: %d, iqd[%d]: %08x, port: %d\n", ci->devname, + event, headx, currInt, group); + break; + } /* switch on event */ + + + /* + * Per MUSYCC Manual, Section 6.4.8.3 [Transmit Errors], TX errors + * are service-affecting and require action to resume normal + * bit-level processing. + */ + + switch (err) + { + case ERR_ONR: + /* + * Per MUSYCC manual, Section 6.4.8.3 [Transmit Errors], this + * error requires Transmit channel reactivation. + * + * Per MUSYCC manual, Section 6.4.8.4 [Receive Errors], this error + * requires Receive channel reactivation. + */ + if (tx) + { + + /* + * TX ONR Error only occurs when channel is configured for + * Transparent Mode. However, this code will catch and + * re-activate on ANY TX ONR error. + */ + + /* + * Set flag to re-enable on any next transmit attempt. + */ + ch->ch_start_tx = CH_START_TX_ONR; + + { +#ifdef RLD_TRANS_DEBUG + if (1 || log_level >= LOG_MONITOR) +#else + if (log_level >= LOG_MONITOR) +#endif + { + printk ("%s: TX buffer underflow [ONR] on channel %d, mode %x QStopped %x free %d\n", + ci->devname, ch->channum, ch->p.chan_mode, sd_queue_stopped (ch->user), ch->txd_free); +#ifdef RLD_DEBUG + if (ch->p.chan_mode == 2) /* problem = ONR on HDLC + * mode */ + { + printk ("++ Failed Last %x Next %x QStopped %x, start_tx %x tx_full %d txd_free %d mode %x\n", + (u_int32_t) ch->txd_irq_srv, (u_int32_t) ch->txd_usr_add, + sd_queue_stopped (ch->user), + ch->ch_start_tx, ch->tx_full, ch->txd_free, ch->p.chan_mode); + musycc_dump_txbuffer_ring (ch, 0); + } +#endif + } + } + } else /* RX buffer overrun */ + { + /* + * Per MUSYCC manual, Section 6.4.8.4 [Receive Errors], + * channel recovery for this RX ONR error IS required. It is + * also suggested to increase the number of receive buffers + * for this channel. Receive channel reactivation IS + * required, and data has been lost. + */ + ch->s.rx_over_errors++; + ch->ch_start_rx = CH_START_RX_ONR; + + if (log_level >= LOG_WARN) + { + printk ("%s: RX buffer overflow [ONR] on channel %d, mode %x\n", + ci->devname, ch->channum, ch->p.chan_mode); + //musycc_dump_rxbuffer_ring (ch, 0); /* RLD DEBUG */ + } + } + musycc_chan_restart (ch); + break; + case ERR_BUF: + if (tx) + { + ch->s.tx_fifo_errors++; + ch->ch_start_tx = CH_START_TX_BUF; + /* + * Per MUSYCC manual, Section 6.4.8.3 [Transmit Errors], + * this BUFF error requires Transmit channel reactivation. + */ + if (log_level >= LOG_MONITOR) + printk ("%s: TX buffer underrun [BUFF] on channel %d, mode %x\n", + ci->devname, ch->channum, ch->p.chan_mode); + } else /* RX buffer overrun */ + { + ch->s.rx_over_errors++; + /* + * Per MUSYCC manual, Section 6.4.8.4 [Receive Errors], HDLC + * mode requires NO recovery for this RX BUFF error is + * required. It is suggested to increase the FIFO buffer + * space for this channel. Receive channel reactivation is + * not required, but data has been lost. + */ + if (log_level >= LOG_WARN) + printk ("%s: RX buffer overrun [BUFF] on channel %d, mode %x\n", + ci->devname, ch->channum, ch->p.chan_mode); + /* + * Per MUSYCC manual, Section 6.4.9.4 [Receive Errors], + * Transparent mode DOES require recovery for the RX BUFF + * error. It is suggested to increase the FIFO buffer space + * for this channel. Receive channel reactivation IS + * required and data has been lost. + */ + if (ch->p.chan_mode == CFG_CH_PROTO_TRANS) + ch->ch_start_rx = CH_START_RX_BUF; + } + + if (tx || (ch->p.chan_mode == CFG_CH_PROTO_TRANS)) + musycc_chan_restart (ch); + break; + default: + break; + } /* switch on err */ + + /* Check for interrupt lost condition */ + if ((currInt & INTRPT_ILOST_M) && (log_level >= LOG_ERROR)) + { + printk ("%s: Interrupt queue overflow - ILOST asserted\n", + ci->devname); + } + ci->iqp_headx = (headx + 1) & (INT_QUEUE_SIZE - 1); /* insure wrapness */ + FLUSH_MEM_WRITE (); + FLUSH_MEM_READ (); + } /* while */ + if ((log_level >= LOG_MONITOR2) && (ci->iqp_headx != ci->iqp_tailx)) + { + int bh; + + bh = atomic_read (&CI->bh_pending); + printk ("_bh_: late arrivals, head %d != tail %d, pending %d\n", + ci->iqp_headx, ci->iqp_tailx, bh); + } +#if defined(SBE_ISR_IMMEDIATE) + return 0L; +#endif + /* else, nothing returned */ +} + +#if 0 +int __init +musycc_new_chan (ci_t * ci, int channum, void *user) +{ + mch_t *ch; + + ch = ci->port[channum / MUSYCC_NCHANS].chan[channum % MUSYCC_NCHANS]; + + if (ch->state != UNASSIGNED) + return EEXIST; + /* NOTE: mch_t already cleared during OS_kmalloc() */ + ch->state = DOWN; + ch->user = user; +#if 0 + ch->status = 0; + ch->p.status = 0; + ch->p.intr_mask = 0; +#endif + ch->p.chan_mode = CFG_CH_PROTO_HDLC_FCS16; + ch->p.idlecode = CFG_CH_FLAG_7E; + ch->p.pad_fill_count = 2; + spin_lock_init (&ch->ch_rxlock); + spin_lock_init (&ch->ch_txlock); + + return 0; +} +#endif + + +#ifdef SBE_PMCC4_ENABLE +status_t +musycc_chan_down (ci_t * dummy, int channum) +{ + mpi_t *pi; + mch_t *ch; + int i, gchan; + + if (!(ch = sd_find_chan (dummy, channum))) + return EINVAL; + pi = ch->up; + gchan = ch->gchan; + + /* Deactivate the channel */ + musycc_serv_req (pi, SR_CHANNEL_DEACTIVATE | SR_RX_DIRECTION | gchan); + ch->ch_start_rx = 0; + musycc_serv_req (pi, SR_CHANNEL_DEACTIVATE | SR_TX_DIRECTION | gchan); + ch->ch_start_tx = 0; + + if (ch->state == DOWN) + return 0; + ch->state = DOWN; + + pi->regram->thp[gchan] = 0; + pi->regram->tmp[gchan] = 0; + pi->regram->rhp[gchan] = 0; + pi->regram->rmp[gchan] = 0; + FLUSH_MEM_WRITE (); + for (i = 0; i < ch->txd_num; i++) + { + if (ch->mdt[i].mem_token != 0) + OS_mem_token_free (ch->mdt[i].mem_token); + } + + for (i = 0; i < ch->rxd_num; i++) + { + if (ch->mdr[i].mem_token != 0) + OS_mem_token_free (ch->mdr[i].mem_token); + } + + OS_kfree (ch->mdr); + ch->mdr = 0; + ch->rxd_num = 0; + OS_kfree (ch->mdt); + ch->mdt = 0; + ch->txd_num = 0; + + musycc_update_timeslots (pi); + c4_fifo_free (pi, ch->gchan); + + pi->openchans--; + return 0; +} +#endif + + +int +musycc_del_chan (ci_t * ci, int channum) +{ + mch_t *ch; + + if ((channum < 0) || (channum >= (MUSYCC_NPORTS * MUSYCC_NCHANS))) /* sanity chk param */ + return ECHRNG; + if (!(ch = sd_find_chan (ci, channum))) + return ENOENT; + if (ch->state == UP) + musycc_chan_down (ci, channum); + ch->state = UNASSIGNED; + return 0; +} + + +int +musycc_del_chan_stats (ci_t * ci, int channum) +{ + mch_t *ch; + + if (channum < 0 || channum >= (MUSYCC_NPORTS * MUSYCC_NCHANS)) /* sanity chk param */ + return ECHRNG; + if (!(ch = sd_find_chan (ci, channum))) + return ENOENT; + + memset (&ch->s, 0, sizeof (struct sbecom_chan_stats)); + return 0; +} + + +int +musycc_start_xmit (ci_t * ci, int channum, void *mem_token) +{ + mch_t *ch; + struct mdesc *md; + void *m2; +#if 0 + unsigned long flags; +#endif + int txd_need_cnt; + u_int32_t len; + + if (!(ch = sd_find_chan (ci, channum))) + return ENOENT; + + if (ci->state != C_RUNNING) /* full interrupt processing available */ + return EINVAL; + if (ch->state != UP) + return EINVAL; + + if (!(ch->status & TX_ENABLED)) + return EROFS; /* how else to flag unwritable state ? */ + +#ifdef RLD_TRANS_DEBUGx + if (1 || log_level >= LOG_MONITOR2) +#else + if (log_level >= LOG_MONITOR2) +#endif + { + printk ("++ start_xmt[%d]: state %x start %x full %d free %d required %d stopped %x\n", + channum, ch->state, ch->ch_start_tx, ch->tx_full, + ch->txd_free, ch->txd_required, sd_queue_stopped (ch->user)); + } + /***********************************************/ + /** Determine total amount of data to be sent **/ + /***********************************************/ + m2 = mem_token; + txd_need_cnt = 0; + for (len = OS_mem_token_tlen (m2); len > 0; + m2 = (void *) OS_mem_token_next (m2)) + { + if (!OS_mem_token_len (m2)) + continue; + txd_need_cnt++; + len -= OS_mem_token_len (m2); + } + + if (txd_need_cnt == 0) + { + if (log_level >= LOG_MONITOR2) + printk ("%s channel %d: no TX data in User buffer\n", ci->devname, channum); + OS_mem_token_free (mem_token); + return 0; /* no data to send */ + } + /*************************************************/ + /** Are there sufficient descriptors available? **/ + /*************************************************/ + if (txd_need_cnt > ch->txd_num) /* never enough descriptors for this + * large a buffer */ + { + if (log_level >= LOG_DEBUG) + { + printk ("start_xmit: discarding buffer, insufficient descriptor cnt %d, need %d.\n", + ch->txd_num, txd_need_cnt + 1); + } + ch->s.tx_dropped++; + OS_mem_token_free (mem_token); + return 0; + } +#if 0 + spin_lock_irqsave (&ch->ch_txlock, flags); +#endif + /************************************************************/ + /** flow control the line if not enough descriptors remain **/ + /************************************************************/ + if (txd_need_cnt > ch->txd_free) + { + if (log_level >= LOG_MONITOR2) + { + printk ("start_xmit[%d]: EBUSY - need more descriptors, have %d of %d need %d\n", + channum, ch->txd_free, ch->txd_num, txd_need_cnt); + } + ch->tx_full = 1; + ch->txd_required = txd_need_cnt; + sd_disable_xmit (ch->user); +#if 0 + spin_unlock_irqrestore (&ch->ch_txlock, flags); +#endif + return EBUSY; /* tell user to try again later */ + } + /**************************************************/ + /** Put the user data into MUSYCC data buffer(s) **/ + /**************************************************/ + m2 = mem_token; + md = ch->txd_usr_add; /* get current available descriptor */ + + for (len = OS_mem_token_tlen (m2); len > 0; m2 = OS_mem_token_next (m2)) + { + int u = OS_mem_token_len (m2); + + if (!u) + continue; + len -= u; + + /* + * Enable following chunks, yet wait to enable the FIRST chunk until + * after ALL subsequent chunks are setup. + */ + if (md != ch->txd_usr_add) /* not first chunk */ + u |= MUSYCC_TX_OWNED; /* transfer ownership from HOST to MUSYCC */ + + if (len) /* not last chunk */ + u |= EOBIRQ_ENABLE; + else if (ch->p.chan_mode == CFG_CH_PROTO_TRANS) + { + /* + * Per MUSYCC Ref 6.4.9 for Transparent Mode, the host must + * always clear EOMIRQ_ENABLE in every Transmit Buffer Descriptor + * (IE. don't set herein). + */ + u |= EOBIRQ_ENABLE; + } else + u |= EOMIRQ_ENABLE; /* EOM, last HDLC chunk */ + + + /* last chunk in hdlc mode */ + u |= (ch->p.idlecode << IDLE_CODE); + if (ch->p.pad_fill_count) + { +#if 0 + /* NOOP NOTE: u_int8_t cannot be > 0xFF */ + /* sanitize pad_fill_count for maximums allowed by hardware */ + if (ch->p.pad_fill_count > EXTRA_FLAGS_MASK) + ch->p.pad_fill_count = EXTRA_FLAGS_MASK; +#endif + u |= (PADFILL_ENABLE | (ch->p.pad_fill_count << EXTRA_FLAGS)); + } + md->mem_token = len ? 0 : mem_token; /* Fill in mds on last + * segment, others set ZERO + * so that entire token is + * removed ONLY when ALL + * segments have been + * transmitted. */ + + md->data = cpu_to_le32 (OS_vtophys (OS_mem_token_data (m2))); + FLUSH_MEM_WRITE (); + md->status = cpu_to_le32 (u); + --ch->txd_free; + md = md->snext; + } + FLUSH_MEM_WRITE (); + + + /* + * Now transfer ownership of first chunk from HOST to MUSYCC in order to + * fire-off this XMIT. + */ + ch->txd_usr_add->status |= __constant_cpu_to_le32 (MUSYCC_TX_OWNED); + FLUSH_MEM_WRITE (); + ch->txd_usr_add = md; + + len = OS_mem_token_tlen (mem_token); + atomic_add (len, &ch->tx_pending); + atomic_add (len, &ci->tx_pending); + ch->s.tx_packets++; + ch->s.tx_bytes += len; +#if 0 + spin_unlock_irqrestore (&ch->ch_txlock, flags); /* allow pending + * interrupt to sneak + * thru */ +#endif + + /* + * If an ONR was seen, then channel requires poking to restart + * transmission. + */ + if (ch->ch_start_tx) + { +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,41) + SD_SEM_TAKE (&ci->sem_wdbusy, "_wd_"); /* only 1 thru here, per + * board */ + if ((ch->ch_start_tx == CH_START_TX_ONR) && (ch->p.chan_mode == CFG_CH_PROTO_TRANS)) + { + /* ONR restart transmission from background loop */ + ci->wd_notify = WD_NOTIFY_ONR; /* enabled global watchdog + * scan-thru */ + } else + { + /* start first transmission from background loop */ + ci->wd_notify = WD_NOTIFY_1TX; /* enabled global watchdog + * scan-thru */ + } + musycc_chan_restart (ch); + SD_SEM_GIVE (&ci->sem_wdbusy); +#else + musycc_chan_restart (ch); +#endif + } +#ifdef SBE_WAN256T3_ENABLE + wan256t3_led (ci, LED_TX, LEDV_G); +#endif + return 0; +} + + +#if 0 +int +musycc_set_chan (ci_t * ci, int channum, struct sbecom_chan_param * p) +{ + mch_t *ch; + int rok = 0; + int n = 0; + + if (channum < 0 || channum >= (MUSYCC_NPORTS * MUSYCC_NCHANS)) /* sanity chk param */ + return ECHRNG; + if (!(ch = sd_find_chan (ci, channum))) + return ENOENT; + if (ch->channum != p->channum) + return EINVAL; + if (sd_line_is_ok (ch->user)) + { + rok = 1; + sd_line_is_down (ch->user); + } + if (ch->state == UP && /* bring down in current configuration */ + (ch->p.status != p->status || + ch->p.chan_mode != p->chan_mode || + ch->p.intr_mask != p->intr_mask || + ch->txd_free < ch->txd_num)) + { + if ((n = musycc_chan_down (ci, channum))) + return n; + if (ch->p.mode_56k != p->mode_56k) + { + ch->p = *p; /* copy in new parameters */ + musycc_update_timeslots (&ci->port[ch->channum / MUSYCC_NCHANS]); + } else + ch->p = *p; /* copy in new parameters */ + if ((n = musycc_chan_up (ci, channum))) + return n; + sd_enable_xmit (ch->user); /* re-enable to catch flow controlled + * channel */ + } else + { + if (ch->p.mode_56k != p->mode_56k) + { + ch->p = *p; /* copy in new parameters */ + musycc_update_timeslots (&ci->port[ch->channum / MUSYCC_NCHANS]); + } else + ch->p = *p; /* copy in new parameters */ + } + + if (rok) + sd_line_is_up (ch->user); + return 0; +} +#endif + + +int +musycc_get_chan (ci_t * ci, int channum, struct sbecom_chan_param * p) +{ + mch_t *ch; + +#if 0 + if (channum < 0 || channum >= (MUSYCC_NPORTS * MUSYCC_NCHANS)) /* sanity chk param */ + return ECHRNG; +#endif + if (!(ch = sd_find_chan (ci, channum))) + return ENOENT; + *p = ch->p; + return 0; +} + + +int +musycc_get_chan_stats (ci_t * ci, int channum, struct sbecom_chan_stats * p) +{ + mch_t *ch; + + if (channum < 0 || channum >= (MUSYCC_NPORTS * MUSYCC_NCHANS)) /* sanity chk param */ + return ECHRNG; + if (!(ch = sd_find_chan (ci, channum))) + return ENOENT; + *p = ch->s; + p->tx_pending = atomic_read (&ch->tx_pending); + return 0; +} + + + +#ifdef SBE_WAN256T3_ENABLE +int +musycc_chan_down (ci_t * ci, int channum) +{ + mch_t *ch; + mpi_t *pi; + int i, gchan; + + if (!(ch = sd_find_chan (ci, channum))) + return EINVAL; + pi = ch->up; + gchan = ch->gchan; + + /* Deactivate the channel */ + musycc_serv_req (pi, SR_CHANNEL_DEACTIVATE | SR_RX_DIRECTION | gchan); + ch->ch_start_rx = 0; + musycc_serv_req (pi, SR_CHANNEL_DEACTIVATE | SR_TX_DIRECTION | gchan); + ch->ch_start_tx = 0; + + if (ch->state == DOWN) + return 0; + ch->state = DOWN; + + pi->regram->thp[gchan] = 0; + pi->regram->tmp[gchan] = 0; + pi->regram->rhp[gchan] = 0; + pi->regram->rmp[gchan] = 0; + FLUSH_MEM_WRITE (); + for (i = 0; i < ch->txd_num; i++) + { + if (ch->mdt[i].mem_token != 0) + OS_mem_token_free (ch->mdt[i].mem_token); + } + + for (i = 0; i < ch->rxd_num; i++) + { + if (ch->mdr[i].mem_token != 0) + OS_mem_token_free (ch->mdr[i].mem_token); + } + + OS_kfree (ch->mdt); + ch->mdt = 0; + OS_kfree (ch->mdr); + ch->mdr = 0; + + return 0; +} +#endif + +/*** End-of-File ***/ diff --git a/drivers/staging/cxt1e1/musycc.h b/drivers/staging/cxt1e1/musycc.h new file mode 100644 index 000000000000..d2c91ef686d1 --- /dev/null +++ b/drivers/staging/cxt1e1/musycc.h @@ -0,0 +1,460 @@ +/* + * $Id: musycc.h,v 1.3 2005/09/28 00:10:08 rickd PMCC4_3_1B $ + */ + +#ifndef _INC_MUSYCC_H_ +#define _INC_MUSYCC_H_ + +/*----------------------------------------------------------------------------- + * musycc.h - Multichannel Synchronous Communications Controller + * CN8778/8474A/8472A/8471A + * + * Copyright (C) 2002-2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For further information, contact via email: support@sbei.com + * SBE, Inc. San Ramon, California U.S.A. + *----------------------------------------------------------------------------- + * RCS info: + * RCS revision: $Revision: 1.3 $ + * Last changed on $Date: 2005/09/28 00:10:08 $ + * Changed by $Author: rickd $ + *----------------------------------------------------------------------------- + * $Log: musycc.h,v $ + * Revision 1.3 2005/09/28 00:10:08 rickd + * Add GNU license info. Add PMCC4 PCI/DevIDs. Implement new + * musycc reg&bits namings. Use PORTMAP_0 GCD grouping. + * + * Revision 1.2 2005/04/28 23:43:04 rickd + * Add RCS tracking heading. + * + *----------------------------------------------------------------------------- + */ + +#if defined (__FreeBSD__) || defined (__NetBSD__) +#include +#else +#include +#endif + +#define VINT8 volatile u_int8_t +#define VINT32 volatile u_int32_t + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "pmcc4_defs.h" + + +/*------------------------------------------------------------------------ +// Vendor, Board Identification definitions +//------------------------------------------------------------------------ +*/ + +#define PCI_VENDOR_ID_CONEXANT 0x14f1 +#define PCI_DEVICE_ID_CN8471 0x8471 +#define PCI_DEVICE_ID_CN8472 0x8472 +#define PCI_DEVICE_ID_CN8474 0x8474 +#define PCI_DEVICE_ID_CN8478 0x8478 +#define PCI_DEVICE_ID_CN8500 0x8500 +#define PCI_DEVICE_ID_CN8501 0x8501 +#define PCI_DEVICE_ID_CN8502 0x8502 +#define PCI_DEVICE_ID_CN8503 0x8503 + +#define INT_QUEUE_SIZE MUSYCC_NIQD + +/* RAM image of MUSYCC registers layed out as a C structure */ + struct musycc_groupr + { + VINT32 thp[32]; /* Transmit Head Pointer [5-29] */ + VINT32 tmp[32]; /* Transmit Message Pointer [5-30] */ + VINT32 rhp[32]; /* Receive Head Pointer [5-29] */ + VINT32 rmp[32]; /* Receive Message Pointer [5-30] */ + VINT8 ttsm[128]; /* Time Slot Map [5-22] */ + VINT8 tscm[256]; /* Subchannel Map [5-24] */ + VINT32 tcct[32]; /* Channel Configuration [5-26] */ + VINT8 rtsm[128]; /* Time Slot Map [5-22] */ + VINT8 rscm[256]; /* Subchannel Map [5-24] */ + VINT32 rcct[32]; /* Channel Configuration [5-26] */ + VINT32 __glcd; /* Global Configuration Descriptor [5-10] */ + VINT32 __iqp; /* Interrupt Queue Pointer [5-36] */ + VINT32 __iql; /* Interrupt Queue Length [5-36] */ + VINT32 grcd; /* Group Configuration Descriptor [5-16] */ + VINT32 mpd; /* Memory Protection Descriptor [5-18] */ + VINT32 mld; /* Message Length Descriptor [5-20] */ + VINT32 pcd; /* Port Configuration Descriptor [5-19] */ + }; + +/* hardware MUSYCC registers layed out as a C structure */ + struct musycc_globalr + { + VINT32 gbp; /* Group Base Pointer */ + VINT32 dacbp; /* Dual Address Cycle Base Pointer */ + VINT32 srd; /* Service Request Descriptor */ + VINT32 isd; /* Interrupt Service Descriptor */ + /* + * adjust __thp due to above 4 registers, which are not contained + * within musycc_groupr[]. All __XXX[] are just place holders, + * anyhow. + */ + VINT32 __thp[32 - 4]; /* Transmit Head Pointer [5-29] */ + VINT32 __tmp[32]; /* Transmit Message Pointer [5-30] */ + VINT32 __rhp[32]; /* Receive Head Pointer [5-29] */ + VINT32 __rmp[32]; /* Receive Message Pointer [5-30] */ + VINT8 ttsm[128]; /* Time Slot Map [5-22] */ + VINT8 tscm[256]; /* Subchannel Map [5-24] */ + VINT32 tcct[32]; /* Channel Configuration [5-26] */ + VINT8 rtsm[128]; /* Time Slot Map [5-22] */ + VINT8 rscm[256]; /* Subchannel Map [5-24] */ + VINT32 rcct[32]; /* Channel Configuration [5-26] */ + VINT32 glcd; /* Global Configuration Descriptor [5-10] */ + VINT32 iqp; /* Interrupt Queue Pointer [5-36] */ + VINT32 iql; /* Interrupt Queue Length [5-36] */ + VINT32 grcd; /* Group Configuration Descriptor [5-16] */ + VINT32 mpd; /* Memory Protection Descriptor [5-18] */ + VINT32 mld; /* Message Length Descriptor [5-20] */ + VINT32 pcd; /* Port Configuration Descriptor [5-19] */ + VINT32 rbist; /* Receive BIST status [5-4] */ + VINT32 tbist; /* Receive BIST status [5-4] */ + }; + +/* Global Config Descriptor bit macros */ +#define MUSYCC_GCD_ECLK_ENABLE 0x00000800 /* EBUS clock enable */ +#define MUSYCC_GCD_INTEL_SELECT 0x00000400 /* MPU type select */ +#define MUSYCC_GCD_INTA_DISABLE 0x00000008 /* PCI INTA disable */ +#define MUSYCC_GCD_INTB_DISABLE 0x00000004 /* PCI INTB disable */ +#define MUSYCC_GCD_BLAPSE 12 /* Position index for BLAPSE bit + * field */ +#define MUSYCC_GCD_ALAPSE 8 /* Position index for ALAPSE bit + * field */ +#define MUSYCC_GCD_ELAPSE 4 /* Position index for ELAPSE bit + * field */ +#define MUSYCC_GCD_PORTMAP_3 3 /* Reserved */ +#define MUSYCC_GCD_PORTMAP_2 2 /* Port 0=>Grp 0,1,2,3; Port 1=>Grp + * 4,5,6,7 */ +#define MUSYCC_GCD_PORTMAP_1 1 /* Port 0=>Grp 0,1; Port 1=>Grp 2,3, + * etc... */ +#define MUSYCC_GCD_PORTMAP_0 0 /* Port 0=>Grp 0; Port 1=>Grp 2, + * etc... */ + +/* and board specific assignments... */ +#ifdef SBE_WAN256T3_ENABLE +#define BLAPSE_VAL 0 +#define ALAPSE_VAL 0 +#define ELAPSE_VAL 7 +#define PORTMAP_VAL MUSYCC_GCD_PORTMAP_2 +#endif + +#ifdef SBE_PMCC4_ENABLE +#define BLAPSE_VAL 7 +#define ALAPSE_VAL 3 +#define ELAPSE_VAL 7 +#define PORTMAP_VAL MUSYCC_GCD_PORTMAP_0 +#endif + +#define GCD_MAGIC (((BLAPSE_VAL)<<(MUSYCC_GCD_BLAPSE)) | \ + ((ALAPSE_VAL)<<(MUSYCC_GCD_ALAPSE)) | \ + ((ELAPSE_VAL)<<(MUSYCC_GCD_ELAPSE)) | \ + (MUSYCC_GCD_ECLK_ENABLE) | PORTMAP_VAL) + +/* Group Config Descriptor bit macros */ +#define MUSYCC_GRCD_RX_ENABLE 0x00000001 /* Enable receive processing */ +#define MUSYCC_GRCD_TX_ENABLE 0x00000002 /* Enable transmit processing */ +#define MUSYCC_GRCD_SUBCHAN_DISABLE 0x00000004 /* Master disable for + * subchanneling */ +#define MUSYCC_GRCD_OOFMP_DISABLE 0x00000008 /* Out of Frame message + * processing disabled all + * channels */ +#define MUSYCC_GRCD_OOFIRQ_DISABLE 0x00000010 /* Out of Frame/In Frame irqs + * disabled */ +#define MUSYCC_GRCD_COFAIRQ_DISABLE 0x00000020 /* Change of Frame Alignment + * irq disabled */ +#define MUSYCC_GRCD_INHRBSD 0x00000100 /* Receive Buffer Status + * overwrite disabled */ +#define MUSYCC_GRCD_INHTBSD 0x00000200 /* Transmit Buffer Status + * overwrite disabled */ +#define MUSYCC_GRCD_SF_ALIGN 0x00008000 /* External frame sync */ +#define MUSYCC_GRCD_MC_ENABLE 0x00000040 /* Message configuration bits + * copy enable. Conexant sez + * turn this on */ +#define MUSYCC_GRCD_POLLTH_16 0x00000001 /* Poll every 16th frame */ +#define MUSYCC_GRCD_POLLTH_32 0x00000002 /* Poll every 32nd frame */ +#define MUSYCC_GRCD_POLLTH_64 0x00000003 /* Poll every 64th frame */ +#define MUSYCC_GRCD_POLLTH_SHIFT 10 /* Position index for poll throttle + * bit field */ +#define MUSYCC_GRCD_SUERM_THRESH_SHIFT 16 /* Position index for SUERM + * count threshold */ + +/* Port Config Descriptor bit macros */ +#define MUSYCC_PCD_E1X2_MODE 2 /* Port mode in bits 0-2. T1 and E1 */ +#define MUSYCC_PCD_E1X4_MODE 3 /* are defined in cn847x.h */ +#define MUSYCC_PCD_NX64_MODE 4 +#define MUSYCC_PCD_TXDATA_RISING 0x00000010 /* Sample Tx data on TCLK + * rising edge */ +#define MUSYCC_PCD_TXSYNC_RISING 0x00000020 /* Sample Tx frame sync on + * TCLK rising edge */ +#define MUSYCC_PCD_RXDATA_RISING 0x00000040 /* Sample Rx data on RCLK + * rising edge */ +#define MUSYCC_PCD_RXSYNC_RISING 0x00000080 /* Sample Rx frame sync on + * RCLK rising edge */ +#define MUSYCC_PCD_ROOF_RISING 0x00000100 /* Sample Rx Out Of Frame + * signal on RCLK rising edge */ +#define MUSYCC_PCD_TX_DRIVEN 0x00000200 /* No mapped timeslots causes + * logic 1 on output, else + * tristate */ +#define MUSYCC_PCD_PORTMODE_MASK 0xfffffff8 /* For changing the port mode + * between E1 and T1 */ + +/* Time Slot Descriptor bit macros */ +#define MUSYCC_TSD_MODE_64KBPS 4 +#define MUSYCC_TSD_MODE_56KBPS 5 +#define MUSYCC_TSD_SUBCHANNEL_WO_FIRST 6 +#define MUSYCC_TSD_SUBCHANNEL_WITH_FIRST 7 + +/* Message Descriptor bit macros */ +#define MUSYCC_MDT_BASE03_ADDR 0x00006000 + +/* Channel Config Descriptor bit macros */ +#define MUSYCC_CCD_BUFIRQ_DISABLE 0x00000002 /* BUFF and ONR irqs disabled */ +#define MUSYCC_CCD_EOMIRQ_DISABLE 0x00000004 /* EOM irq disabled */ +#define MUSYCC_CCD_MSGIRQ_DISABLE 0x00000008 /* LNG, FCS, ALIGN, and ABT + * irqs disabled */ +#define MUSYCC_CCD_IDLEIRQ_DISABLE 0x00000010 /* CHABT, CHIC, and SHT irqs + * disabled */ +#define MUSYCC_CCD_FILTIRQ_DISABLE 0x00000020 /* SFILT irq disabled */ +#define MUSYCC_CCD_SDECIRQ_DISABLE 0x00000040 /* SDEC irq disabled */ +#define MUSYCC_CCD_SINCIRQ_DISABLE 0x00000080 /* SINC irq disabled */ +#define MUSYCC_CCD_SUERIRQ_DISABLE 0x00000100 /* SUERR irq disabled */ +#define MUSYCC_CCD_FCS_XFER 0x00000200 /* Propagate FCS along with + * received data */ +#define MUSYCC_CCD_PROTO_SHIFT 12 /* Position index for protocol bit + * field */ +#define MUSYCC_CCD_TRANS 0 /* Protocol mode in bits 12-14 */ +#define MUSYCC_CCD_SS7 1 +#define MUSYCC_CCD_HDLC_FCS16 2 +#define MUSYCC_CCD_HDLC_FCS32 3 +#define MUSYCC_CCD_EOPIRQ_DISABLE 0x00008000 /* EOP irq disabled */ +#define MUSYCC_CCD_INVERT_DATA 0x00800000 /* Invert data */ +#define MUSYCC_CCD_MAX_LENGTH 10 /* Position index for max length bit + * field */ +#define MUSYCC_CCD_BUFFER_LENGTH 16 /* Position index for internal data + * buffer length */ +#define MUSYCC_CCD_BUFFER_LOC 24 /* Position index for internal data + * buffer starting location */ + +/**************************************************************************** + * Interrupt Descriptor Information */ + +#define INT_EMPTY_ENTRY 0xfeedface +#define INT_EMPTY_ENTRY2 0xdeadface + +/**************************************************************************** + * Interrupt Status Descriptor + * + * NOTE: One must first fetch the value of the interrupt status descriptor + * into a local variable, then pass that value into the read macros. This + * is required to avoid race conditions. + ***/ + +#define INTRPTS_NEXTINT_M 0x7FFF0000 +#define INTRPTS_NEXTINT_S 16 +#define INTRPTS_NEXTINT(x) ((x & INTRPTS_NEXTINT_M) >> INTRPTS_NEXTINT_S) + +#define INTRPTS_INTFULL_M 0x00008000 +#define INTRPTS_INTFULL_S 15 +#define INTRPTS_INTFULL(x) ((x & INTRPTS_INTFULL_M) >> INTRPTS_INTFULL_S) + +#define INTRPTS_INTCNT_M 0x00007FFF +#define INTRPTS_INTCNT_S 0 +#define INTRPTS_INTCNT(x) ((x & INTRPTS_INTCNT_M) >> INTRPTS_INTCNT_S) + + +/**************************************************************************** + * Interrupt Descriptor + ***/ + +#define INTRPT_DIR_M 0x80000000 +#define INTRPT_DIR_S 31 +#define INTRPT_DIR(x) ((x & INTRPT_DIR_M) >> INTRPT_DIR_S) + +#define INTRPT_GRP_M 0x60000000 +#define INTRPT_GRP_MSB_M 0x00004000 +#define INTRPT_GRP_S 29 +#define INTRPT_GRP_MSB_S 12 +#define INTRPT_GRP(x) (((x & INTRPT_GRP_M) >> INTRPT_GRP_S) | \ + ((x & INTRPT_GRP_MSB_M) >> INTRPT_GRP_MSB_S)) + +#define INTRPT_CH_M 0x1F000000 +#define INTRPT_CH_S 24 +#define INTRPT_CH(x) ((x & INTRPT_CH_M) >> INTRPT_CH_S) + +#define INTRPT_EVENT_M 0x00F00000 +#define INTRPT_EVENT_S 20 +#define INTRPT_EVENT(x) ((x & INTRPT_EVENT_M) >> INTRPT_EVENT_S) + +#define INTRPT_ERROR_M 0x000F0000 +#define INTRPT_ERROR_S 16 +#define INTRPT_ERROR(x) ((x & INTRPT_ERROR_M) >> INTRPT_ERROR_S) + +#define INTRPT_ILOST_M 0x00008000 +#define INTRPT_ILOST_S 15 +#define INTRPT_ILOST(x) ((x & INTRPT_ILOST_M) >> INTRPT_ILOST_S) + +#define INTRPT_PERR_M 0x00004000 +#define INTRPT_PERR_S 14 +#define INTRPT_PERR(x) ((x & INTRPT_PERR_M) >> INTRPT_PERR_S) + +#define INTRPT_BLEN_M 0x00003FFF +#define INTRPT_BLEN_S 0 +#define INTRPT_BLEN(x) ((x & INTRPT_BLEN_M) >> INTRPT_BLEN_S) + + +/* Buffer Descriptor bit macros */ +#define OWNER_BIT 0x80000000 /* Set for MUSYCC owner on xmit, host + * owner on receive */ +#define HOST_TX_OWNED 0x00000000 /* Host owns descriptor */ +#define MUSYCC_TX_OWNED 0x80000000 /* MUSYCC owns descriptor */ +#define HOST_RX_OWNED 0x80000000 /* Host owns descriptor */ +#define MUSYCC_RX_OWNED 0x00000000 /* MUSYCC owns descriptor */ + +#define POLL_DISABLED 0x40000000 /* MUSYCC not allowed to poll buffer + * for ownership */ +#define EOMIRQ_ENABLE 0x20000000 /* This buffer contains the end of + * the message */ +#define EOBIRQ_ENABLE 0x10000000 /* EOB irq enabled */ +#define PADFILL_ENABLE 0x01000000 /* Enable padfill */ +#define REPEAT_BIT 0x00008000 /* Bit on for FISU descriptor */ +#define LENGTH_MASK 0X3fff /* This part of status descriptor is + * length */ +#define IDLE_CODE 25 /* Position index for idle code (2 + * bits) */ +#define EXTRA_FLAGS 16 /* Position index for minimum flags + * between messages (8 bits) */ +#define IDLE_CODE_MASK 0x03 /* Gets rid of garbage before the + * pattern is OR'd in */ +#define EXTRA_FLAGS_MASK 0xff /* Gets rid of garbage before the + * pattern is OR'd in */ +#define PCI_PERMUTED_OWNER_BIT 0x00000080 /* For flipping the bit on + * the polled mode descriptor */ + +/* Service Request Descriptor bit macros */ +#define SREQ 8 /* Position index for service request bit + * field */ +#define SR_NOOP (0<<(SREQ)) /* No Operation. Generates SACK */ +#define SR_CHIP_RESET (1<<(SREQ)) /* Soft chip reset */ +#define SR_GROUP_RESET (2<<(SREQ)) /* Group reset */ +#define SR_GLOBAL_INIT (4<<(SREQ)) /* Global init: read global + * config deswc and interrupt + * queue desc */ +#define SR_GROUP_INIT (5<<(SREQ)) /* Group init: read Timeslot + * and Subchannel maps, + * Channel Config, */ + /* + * Group Config, Memory Protect, Message Length, and Port Config + * Descriptors + */ +#define SR_CHANNEL_ACTIVATE (8<<(SREQ)) /* Init channel, read Head + * Pointer, process first + * Message Descriptor */ +#define SR_GCHANNEL_MASK 0x001F /* channel portion (gchan) */ +#define SR_CHANNEL_DEACTIVATE (9<<(SREQ)) /* Stop channel processing */ +#define SR_JUMP (10<<(SREQ)) /* a: Process new Message + * List */ +#define SR_CHANNEL_CONFIG (11<<(SREQ)) /* b: Read channel + * Configuration Descriptor */ +#define SR_GLOBAL_CONFIG (16<<(SREQ)) /* 10: Read Global + * Configuration Descriptor */ +#define SR_INTERRUPT_Q (17<<(SREQ)) /* 11: Read Interrupt Queue + * Descriptor */ +#define SR_GROUP_CONFIG (18<<(SREQ)) /* 12: Read Group + * Configuration Descriptor */ +#define SR_MEMORY_PROTECT (19<<(SREQ)) /* 13: Read Memory Protection + * Descriptor */ +#define SR_MESSAGE_LENGTH (20<<(SREQ)) /* 14: Read Message Length + * Descriptor */ +#define SR_PORT_CONFIG (21<<(SREQ)) /* 15: Read Port + * Configuration Descriptor */ +#define SR_TIMESLOT_MAP (24<<(SREQ)) /* 18: Read Timeslot Map */ +#define SR_SUBCHANNEL_MAP (25<<(SREQ)) /* 19: Read Subchannel Map */ +#define SR_CHAN_CONFIG_TABLE (26<<(SREQ)) /* 20: Read Channel + * Configuration Table for + * the group */ +#define SR_TX_DIRECTION 0x00000020 /* Transmit direction bit. + * Bit off indicates receive + * direction */ +#define SR_RX_DIRECTION 0x00000000 + +/* Interrupt Descriptor bit macros */ +#define GROUP10 29 /* Position index for the 2 LS group + * bits */ +#define CHANNEL 24 /* Position index for channel bits */ +#define INT_IQD_TX 0x80000000 +#define INT_IQD_GRP 0x60000000 +#define INT_IQD_CHAN 0x1f000000 +#define INT_IQD_EVENT 0x00f00000 +#define INT_IQD_ERROR 0x000f0000 +#define INT_IQD_ILOST 0x00008000 +#define INT_IQD_PERR 0x00004000 +#define INT_IQD_BLEN 0x00003fff + +/* Interrupt Descriptor Events */ +#define EVE_EVENT 20 /* Position index for event bits */ +#define EVE_NONE 0 /* No event to report in this + * interrupt */ +#define EVE_SACK 1 /* Service Request acknowledge */ +#define EVE_EOB 2 /* End of Buffer */ +#define EVE_EOM 3 /* End of Message */ +#define EVE_EOP 4 /* End of Padfill */ +#define EVE_CHABT 5 /* Change to Abort Code */ +#define EVE_CHIC 6 /* Change to Idle Code */ +#define EVE_FREC 7 /* Frame Recovery */ +#define EVE_SINC 8 /* MTP2 SUERM Increment */ +#define EVE_SDEC 9 /* MTP2 SUERM Decrement */ +#define EVE_SFILT 10 /* MTP2 SUERM Filtered Message */ +/* Interrupt Descriptor Errors */ +#define ERR_ERRORS 16 /* Position index for error bits */ +#define ERR_BUF 1 /* Buffer Error */ +#define ERR_COFA 2 /* Change of Frame Alignment Error */ +#define ERR_ONR 3 /* Owner Bit Error */ +#define ERR_PROT 4 /* Memory Protection Error */ +#define ERR_OOF 8 /* Out of Frame Error */ +#define ERR_FCS 9 /* FCS Error */ +#define ERR_ALIGN 10 /* Octet Alignment Error */ +#define ERR_ABT 11 /* Abort Termination */ +#define ERR_LNG 12 /* Long Message Error */ +#define ERR_SHT 13 /* Short Message Error */ +#define ERR_SUERR 14 /* SUERM threshold exceeded */ +#define ERR_PERR 15 /* PCI Parity Error */ +/* Other Stuff */ +#define TRANSMIT_DIRECTION 0x80000000 /* Transmit direction bit. Bit off + * indicates receive direction */ +#define ILOST 0x00008000 /* Interrupt Lost */ +#define GROUPMSB 0x00004000 /* Group number MSB */ +#define SACK_IMAGE 0x00100000 /* Used in IRQ for semaphore test */ +#define INITIAL_STATUS 0x10000 /* IRQ status should be this after + * reset */ + +/* This must be defined on an entire channel group (Port) basis */ +#define SUERM_THRESHOLD 0x1f + +#ifdef __cplusplus +} +#endif + +#undef VINT32 +#undef VINT8 + +#endif /*** _INC_MUSYCC_H_ ***/ + +/*** End-of-File ***/ diff --git a/drivers/staging/cxt1e1/ossiRelease.c b/drivers/staging/cxt1e1/ossiRelease.c new file mode 100644 index 000000000000..a56029866c2d --- /dev/null +++ b/drivers/staging/cxt1e1/ossiRelease.c @@ -0,0 +1,39 @@ +/* + * $Id: ossiRelease.c,v 1.2 2008/05/08 20:14:03 rdobbs PMCC4_3_1B $ + */ + +/*----------------------------------------------------------------------------- + * ossiRelease.c - + * + * This string will be embedded into the executable and will track the + * release. The embedded string may be displayed using the following: + * + * strings | grep \$Rel + * + * Copyright (C) 2002-2008 One Stop Systems, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For further information, contact via email: support@onestopsystems.com + * One Stop Systems, Inc. Escondido, California U.S.A. + * + *----------------------------------------------------------------------------- + * RCS info: + * RCS revision: $Revision: 1.2 $ + * Last changed on $Date: 2008/05/08 20:14:03 $ + * Changed by $Author: rdobbs $ + *----------------------------------------------------------------------------- + */ + + +char pmcc4_OSSI_release[] = "$Release: PMCC4_3_1B, Copyright (c) 2008 One Stop Systems$"; + +/*** End-of-File ***/ diff --git a/drivers/staging/cxt1e1/pmc93x6_eeprom.c b/drivers/staging/cxt1e1/pmc93x6_eeprom.c new file mode 100644 index 000000000000..02c829b318b4 --- /dev/null +++ b/drivers/staging/cxt1e1/pmc93x6_eeprom.c @@ -0,0 +1,559 @@ +/* pmc93x6_eeprom.c - PMC's 93LC46 EEPROM Device + * + * The 93LC46 is a low-power, serial Electrically Erasable and + * Programmable Read Only Memory organized as 128 8-bit bytes. + * + * Accesses to the 93LC46 are done in a bit serial stream, organized + * in a 3 wire format. Writes are internally timed by the device + * (the In data bit is pulled low until the write is complete and + * then is pulled high) and take about 6 milliseconds. + * + * Copyright (C) 2003-2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "pmcc4_sysdep.h" +#include "sbecom_inline_linux.h" +#include "pmcc4.h" +#include "sbe_promformat.h" + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +#ifdef SBE_INCLUDE_SYMBOLS +#define STATIC +#else +#define STATIC static +#endif + + +/*------------------------------------------------------------------------ + * EEPROM address definitions + *------------------------------------------------------------------------ + * + * The offset in the definitions below allows the test to skip over + * areas of the EEPROM that other programs (such a VxWorks) are + * using. + */ + +#define EE_MFG (long)0 /* Index to manufacturing record */ +#define EE_FIRST 0x28 /* Index to start testing at */ +#define EE_LIMIT 128 /* Index to end testing at */ + + +/* Bit Ordering for Instructions +** +** A0, A1, A2, A3, A4, A5, A6, OP0, OP1, SB (lsb, or 1st bit out) +** +*/ + +#define EPROM_EWEN 0x0019 /* Erase/Write enable (reversed) */ +#define EPROM_EWDS 0x0001 /* Erase/Write disable (reversed) */ +#define EPROM_READ 0x0003 /* Read (reversed) */ +#define EPROM_WRITE 0x0005 /* Write (reversed) */ +#define EPROM_ERASE 0x0007 /* Erase (reversed) */ +#define EPROM_ERAL 0x0009 /* Erase All (reversed) */ +#define EPROM_WRAL 0x0011 /* Write All (reversed) */ + +#define EPROM_ADR_SZ 7 /* Number of bits in offset address */ +#define EPROM_OP_SZ 3 /* Number of bits in command */ +#define SIZE_ADDR_OP (EPROM_ADR_SZ + EPROM_OP_SZ) +#define LC46A_MAX_OPS 10 /* Number of bits in Instruction */ +#define NUM_OF_BITS 8 /* Number of bits in data */ + + +/* EEPROM signal bits */ +#define EPROM_ACTIVE_OUT_BIT 0x0001 /* Out data bit */ +#define EPROM_ACTIVE_IN_BIT 0x0002 /* In data bit */ +#define ACTIVE_IN_BIT_SHIFT 0x0001 /* Shift In data bit to LSB */ +#define EPROM_ENCS 0x0004 /* Set EEPROM CS during operation */ + + +/*------------------------------------------------------------------------ + * The ByteReverse table is used to reverses the 8 bits within a byte + *------------------------------------------------------------------------ + */ + +static unsigned char ByteReverse[256]; +static int ByteReverseBuilt = FALSE; + + +/*------------------------------------------------------------------------ + * mfg_template - initial serial EEPROM data structure + *------------------------------------------------------------------------ + */ + +short mfg_template[sizeof (FLD_TYPE2)] = +{ + PROM_FORMAT_TYPE2, /* type; */ + 0x00, 0x1A, /* length[2]; */ + 0x00, 0x00, 0x00, 0x00, /* Crc32[4]; */ + 0x11, 0x76, /* Id[2]; */ + 0x07, 0x05, /* SubId[2] E1; */ + 0x00, 0xA0, 0xD6, 0x00, 0x00, 0x00, /* Serial[6]; */ + 0x00, 0x00, 0x00, 0x00, /* CreateTime[4]; */ + 0x00, 0x00, 0x00, 0x00, /* HeatRunTime[4]; */ + 0x00, 0x00, 0x00, 0x00, /* HeatRunIterations[4]; */ + 0x00, 0x00, 0x00, 0x00, /* HeatRunErrors[4]; */ +}; + + +/*------------------------------------------------------------------------ + * BuildByteReverse - build the 8-bit reverse table + *------------------------------------------------------------------------ + * + * The 'ByteReverse' table reverses the 8 bits within a byte + * (the MSB becomes the LSB etc.). + */ + +STATIC void +BuildByteReverse (void) +{ + long half; /* Used to build by powers to 2 */ + int i; + + ByteReverse[0] = 0; + + for (half = 1; half < sizeof (ByteReverse); half <<= 1) + for (i = 0; i < half; i++) + ByteReverse[half + i] = (char) (ByteReverse[i] | (0x80 / half)); + + ByteReverseBuilt = TRUE; +} + + +/*------------------------------------------------------------------------ + * eeprom_delay - small delay for EEPROM timing + *------------------------------------------------------------------------ + */ + +STATIC void +eeprom_delay (void) +{ + int timeout; + + for (timeout = 20; timeout; --timeout) + { + OS_uwait_dummy (); + } +} + + +/*------------------------------------------------------------------------ + * eeprom_put_byte - Send a byte to the EEPROM serially + *------------------------------------------------------------------------ + * + * Given the PCI address and the data, this routine serially sends + * the data to the EEPROM. + */ + +void +eeprom_put_byte (long addr, long data, int count) +{ + u_int32_t output; + + while (--count >= 0) + { + output = (data & EPROM_ACTIVE_OUT_BIT) ? 1 : 0; /* Get next data bit */ + output |= EPROM_ENCS; /* Add Chip Select */ + data >>= 1; + + eeprom_delay (); + pci_write_32 ((u_int32_t *) addr, output); /* Output it */ + } +} + + +/*------------------------------------------------------------------------ + * eeprom_get_byte - Receive a byte from the EEPROM serially + *------------------------------------------------------------------------ + * + * Given the PCI address, this routine serially fetches the data + * from the EEPROM. + */ + +u_int32_t +eeprom_get_byte (long addr) +{ + u_int32_t input; + u_int32_t data; + int count; + +/* Start the Reading of DATA +** +** The first read is a dummy as the data is latched in the +** EPLD and read on the next read access to the EEPROM. +*/ + + input = pci_read_32 ((u_int32_t *) addr); + + data = 0; + count = NUM_OF_BITS; + while (--count >= 0) + { + eeprom_delay (); + input = pci_read_32 ((u_int32_t *) addr); + + data <<= 1; /* Shift data over */ + data |= (input & EPROM_ACTIVE_IN_BIT) ? 1 : 0; + + } + + return data; +} + + +/*------------------------------------------------------------------------ + * disable_pmc_eeprom - Disable writes to the EEPROM + *------------------------------------------------------------------------ + * + * Issue the EEPROM command to disable writes. + */ + +STATIC void +disable_pmc_eeprom (long addr) +{ + eeprom_put_byte (addr, EPROM_EWDS, SIZE_ADDR_OP); + + pci_write_32 ((u_int32_t *) addr, 0); /* this removes Chip Select + * from EEPROM */ +} + + +/*------------------------------------------------------------------------ + * enable_pmc_eeprom - Enable writes to the EEPROM + *------------------------------------------------------------------------ + * + * Issue the EEPROM command to enable writes. + */ + +STATIC void +enable_pmc_eeprom (long addr) +{ + eeprom_put_byte (addr, EPROM_EWEN, SIZE_ADDR_OP); + + pci_write_32 ((u_int32_t *) addr, 0); /* this removes Chip Select + * from EEPROM */ +} + + +/*------------------------------------------------------------------------ + * pmc_eeprom_read - EEPROM location read + *------------------------------------------------------------------------ + * + * Given a EEPROM PCI address and location offset, this routine returns + * the contents of the specified location to the calling routine. + */ + +u_int32_t +pmc_eeprom_read (long addr, long mem_offset) +{ + u_int32_t data; /* Data from chip */ + + if (!ByteReverseBuilt) + BuildByteReverse (); + + mem_offset = ByteReverse[0x7F & mem_offset]; /* Reverse address */ + /* + * NOTE: The max offset address is 128 or half the reversal table. So the + * LSB is always zero and counts as a built in shift of one bit. So even + * though we need to shift 3 bits to make room for the command, we only + * need to shift twice more because of the built in shift. + */ + mem_offset <<= 2; /* Shift for command */ + mem_offset |= EPROM_READ; /* Add command */ + + eeprom_put_byte (addr, mem_offset, SIZE_ADDR_OP); /* Output chip address */ + + data = eeprom_get_byte (addr); /* Read chip data */ + + pci_write_32 ((u_int32_t *) addr, 0); /* Remove Chip Select from + * EEPROM */ + + return (data & 0x000000FF); +} + + +/*------------------------------------------------------------------------ + * pmc_eeprom_write - EEPROM location write + *------------------------------------------------------------------------ + * + * Given a EEPROM PCI address, location offset and value, this + * routine writes the value to the specified location. + * + * Note: it is up to the caller to determine if the write + * operation succeeded. + */ + +int +pmc_eeprom_write (long addr, long mem_offset, u_int32_t data) +{ + volatile u_int32_t temp; + int count; + + if (!ByteReverseBuilt) + BuildByteReverse (); + + mem_offset = ByteReverse[0x7F & mem_offset]; /* Reverse address */ + /* + * NOTE: The max offset address is 128 or half the reversal table. So the + * LSB is always zero and counts as a built in shift of one bit. So even + * though we need to shift 3 bits to make room for the command, we only + * need to shift twice more because of the built in shift. + */ + mem_offset <<= 2; /* Shift for command */ + mem_offset |= EPROM_WRITE; /* Add command */ + + eeprom_put_byte (addr, mem_offset, SIZE_ADDR_OP); /* Output chip address */ + + data = ByteReverse[0xFF & data];/* Reverse data */ + eeprom_put_byte (addr, data, NUM_OF_BITS); /* Output chip data */ + + pci_write_32 ((u_int32_t *) addr, 0); /* Remove Chip Select from + * EEPROM */ + +/* +** Must see Data In at a low state before completing this transaction. +** +** Afterwards, the data bit will return to a high state, ~6 ms, terminating +** the operation. +*/ + pci_write_32 ((u_int32_t *) addr, EPROM_ENCS); /* Re-enable Chip Select */ + temp = pci_read_32 ((u_int32_t *) addr); /* discard first read */ + temp = pci_read_32 ((u_int32_t *) addr); + if (temp & EPROM_ACTIVE_IN_BIT) + { + temp = pci_read_32 ((u_int32_t *) addr); + if (temp & EPROM_ACTIVE_IN_BIT) + { + pci_write_32 ((u_int32_t *) addr, 0); /* Remove Chip Select + * from EEPROM */ + return (1); + } + } + count = 1000; + while (count--) + { + for (temp = 0; temp < 0x10; temp++) + OS_uwait_dummy (); + + if (pci_read_32 ((u_int32_t *) addr) & EPROM_ACTIVE_IN_BIT) + break; + } + + if (count == -1) + return (2); + + return (0); +} + + +/*------------------------------------------------------------------------ + * pmcGetBuffValue - read the specified value from buffer + *------------------------------------------------------------------------ + */ + +long +pmcGetBuffValue (char *ptr, int size) +{ + long value = 0; + int index; + + for (index = 0; index < size; ++index) + { + value <<= 8; + value |= ptr[index] & 0xFF; + } + + return value; +} + + +/*------------------------------------------------------------------------ + * pmcSetBuffValue - save the specified value to buffer + *------------------------------------------------------------------------ + */ + +void +pmcSetBuffValue (char *ptr, long value, int size) +{ + int index = size; + + while (--index >= 0) + { + ptr[index] = (char) (value & 0xFF); + value >>= 8; + } +} + + +/*------------------------------------------------------------------------ + * pmc_eeprom_read_buffer - read EEPROM data into specified buffer + *------------------------------------------------------------------------ + */ + +void +pmc_eeprom_read_buffer (long addr, long mem_offset, char *dest_ptr, int size) +{ + while (--size >= 0) + *dest_ptr++ = (char) pmc_eeprom_read (addr, mem_offset++); +} + + +/*------------------------------------------------------------------------ + * pmc_eeprom_write_buffer - write EEPROM data from specified buffer + *------------------------------------------------------------------------ + */ + +void +pmc_eeprom_write_buffer (long addr, long mem_offset, char *dest_ptr, int size) +{ + enable_pmc_eeprom (addr); + + while (--size >= 0) + pmc_eeprom_write (addr, mem_offset++, *dest_ptr++); + + disable_pmc_eeprom (addr); +} + + +/*------------------------------------------------------------------------ + * pmcCalcCrc - calculate the CRC for the serial EEPROM structure + *------------------------------------------------------------------------ + */ + +u_int32_t +pmcCalcCrc_T01 (void *bufp) +{ + FLD_TYPE2 *buf = bufp; + u_int32_t crc; /* CRC of the structure */ + + /* Calc CRC for type and length fields */ + sbeCrc ( + (u_int8_t *) &buf->type, + (u_int32_t) STRUCT_OFFSET (FLD_TYPE1, Crc32), + (u_int32_t) 0, + (u_int32_t *) &crc); + +#ifdef EEPROM_TYPE_DEBUG + printk ("sbeCrc: crc 1 calculated as %08x\n", crc); /* RLD DEBUG */ +#endif + return ~crc; +} + +u_int32_t +pmcCalcCrc_T02 (void *bufp) +{ + FLD_TYPE2 *buf = bufp; + u_int32_t crc; /* CRC of the structure */ + + /* Calc CRC for type and length fields */ + sbeCrc ( + (u_int8_t *) &buf->type, + (u_int32_t) STRUCT_OFFSET (FLD_TYPE2, Crc32), + (u_int32_t) 0, + (u_int32_t *) &crc); + + /* Calc CRC for remaining fields */ + sbeCrc ( + (u_int8_t *) &buf->Id[0], + (u_int32_t) (sizeof (FLD_TYPE2) - STRUCT_OFFSET (FLD_TYPE2, Id)), + (u_int32_t) crc, + (u_int32_t *) &crc); + +#ifdef EEPROM_TYPE_DEBUG + printk ("sbeCrc: crc 2 calculated as %08x\n", crc); /* RLD DEBUG */ +#endif + return crc; +} + + +/*------------------------------------------------------------------------ + * pmc_init_seeprom - initialize the serial EEPROM structure + *------------------------------------------------------------------------ + * + * At the front of the serial EEPROM there is a record that contains + * manufacturing information. If the info does not already exist, it + * is created. The only field modifiable by the operator is the + * serial number field. + */ + +void +pmc_init_seeprom (u_int32_t addr, u_int32_t serialNum) +{ + PROMFORMAT buffer; /* Memory image of structure */ + u_int32_t crc; /* CRC of structure */ + time_t createTime; + int i; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + createTime = CURRENT_TIME; +#else + createTime = get_seconds (); +#endif + + /* use template data */ + for (i = 0; i < sizeof (FLD_TYPE2); ++i) + buffer.bytes[i] = mfg_template[i]; + + /* Update serial number field in buffer */ + pmcSetBuffValue (&buffer.fldType2.Serial[3], serialNum, 3); + + /* Update create time field in buffer */ + pmcSetBuffValue (&buffer.fldType2.CreateTime[0], createTime, 4); + + /* Update CRC field in buffer */ + crc = pmcCalcCrc_T02 (&buffer); + pmcSetBuffValue (&buffer.fldType2.Crc32[0], crc, 4); + +#ifdef DEBUG + for (i = 0; i < sizeof (FLD_TYPE2); ++i) + printk ("[%02X] = %02X\n", i, buffer.bytes[i] & 0xFF); +#endif + + /* Write structure to serial EEPROM */ + pmc_eeprom_write_buffer (addr, EE_MFG, (char *) &buffer, sizeof (FLD_TYPE2)); +} + + +char +pmc_verify_cksum (void *bufp) +{ + FLD_TYPE1 *buf1 = bufp; + FLD_TYPE2 *buf2 = bufp; + u_int32_t crc1, crc2; /* CRC read from EEPROM */ + + /* Retrieve contents of CRC field */ + crc1 = pmcGetBuffValue (&buf1->Crc32[0], sizeof (buf1->Crc32)); +#ifdef EEPROM_TYPE_DEBUG + printk ("EEPROM: chksum 1 reads as %08x\n", crc1); /* RLD DEBUG */ +#endif + if ((buf1->type == PROM_FORMAT_TYPE1) && + (pmcCalcCrc_T01 ((void *) buf1) == crc1)) + return PROM_FORMAT_TYPE1; /* checksum type 1 verified */ + + crc2 = pmcGetBuffValue (&buf2->Crc32[0], sizeof (buf2->Crc32)); +#ifdef EEPROM_TYPE_DEBUG + printk ("EEPROM: chksum 2 reads as %08x\n", crc2); /* RLD DEBUG */ +#endif + if ((buf2->type == PROM_FORMAT_TYPE2) && + (pmcCalcCrc_T02 ((void *) buf2) == crc2)) + return PROM_FORMAT_TYPE2; /* checksum type 2 verified */ + + return PROM_FORMAT_Unk; /* failed to validate */ +} + + +/*** End-of-File ***/ diff --git a/drivers/staging/cxt1e1/pmc93x6_eeprom.h b/drivers/staging/cxt1e1/pmc93x6_eeprom.h new file mode 100644 index 000000000000..c3ada87efd26 --- /dev/null +++ b/drivers/staging/cxt1e1/pmc93x6_eeprom.h @@ -0,0 +1,60 @@ +/* + * $Id: pmc93x6_eeprom.h,v 1.1 2005/09/28 00:10:08 rickd PMCC4_3_1B $ + */ + +#ifndef _INC_PMC93X6_EEPROM_H_ +#define _INC_PMC93X6_EEPROM_H_ + +/*----------------------------------------------------------------------------- + * pmc93x6_eeprom.h - + * + * Copyright (C) 2002-2004 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For further information, contact via email: support@sbei.com + * SBE, Inc. San Ramon, California U.S.A. + *----------------------------------------------------------------------------- + * RCS info: + *----------------------------------------------------------------------------- + * $Log: pmc93x6_eeprom.h,v $ + * Revision 1.1 2005/09/28 00:10:08 rickd + * pmc_verify_cksum return value is char. + * + * Revision 1.0 2005/05/04 17:20:51 rickd + * Initial revision + * + * Revision 1.0 2005/04/22 23:48:48 rickd + * Initial revision + * + *----------------------------------------------------------------------------- + */ + +#if defined (__FreeBSD__) || defined (__NetBSD__) +#include +#else +#include +#endif + +#ifdef __KERNEL__ + +#include "pmcc4_private.h" + +void pmc_eeprom_read_buffer (long, long, char *, int); +void pmc_eeprom_write_buffer (long, long, char *, int); +void pmc_init_seeprom (u_int32_t, u_int32_t); +char pmc_verify_cksum (void *); + +#endif /*** __KERNEL__ ***/ + +#endif + +/*** End-of-File ***/ diff --git a/drivers/staging/cxt1e1/pmcc4.h b/drivers/staging/cxt1e1/pmcc4.h new file mode 100644 index 000000000000..26c1f0ea72e9 --- /dev/null +++ b/drivers/staging/cxt1e1/pmcc4.h @@ -0,0 +1,155 @@ +/* + * $Id: pmcc4.h,v 1.4 2005/11/01 19:24:48 rickd PMCC4_3_1B $ + */ + +#ifndef _INC_PMCC4_H_ +#define _INC_PMCC4_H_ + +/*----------------------------------------------------------------------------- + * pmcc4.h - + * + * Copyright (C) 2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For further information, contact via email: support@sbei.com + * SBE, Inc. San Ramon, California U.S.A. + *----------------------------------------------------------------------------- + * RCS info: + * RCS revision: $Revision: 1.4 $ + * Last changed on $Date: 2005/11/01 19:24:48 $ + * Changed by $Author: rickd $ + *----------------------------------------------------------------------------- + * $Log: pmcc4.h,v $ + * Revision 1.4 2005/11/01 19:24:48 rickd + * Remove de-implement function prototypes. Several to + * changes for consistant usage of same. + * + * Revision 1.3 2005/09/28 00:10:08 rickd + * Add GNU license info. Use config params from libsbew.h + * + * Revision 1.2 2005/04/28 23:43:03 rickd + * Add RCS tracking heading. + * + *----------------------------------------------------------------------------- + */ + + +#if defined(__FreeBSD__) || defined(__NetBSD__) +#include +#else +#ifndef __KERNEL__ +#include +#else +#include +#endif +#endif + + + +typedef int status_t; + +#define SBE_DRVR_FAIL 0 +#define SBE_DRVR_SUCCESS 1 + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/********************/ +/* PMCC4 memory Map */ +/********************/ + +#define COMET_OFFSET(x) (0x80000+(x)*0x10000) +#define EEPROM_OFFSET 0xC0000 +#define CPLD_OFFSET 0xD0000 + + struct pmcc4_timeslot_param + { + u_int8_t card; /* the card number */ + u_int8_t port; /* the port number */ + u_int8_t _reserved1; + u_int8_t _reserved2; + + /* + * each byte in bitmask below represents one timeslot (bitmask[0] is + * for timeslot 0 and so on), each bit in the byte selects timeslot + * bits for this channel (0xff - whole timeslot, 0x7f - 56kbps mode) + */ + u_int8_t bitmask[32]; + }; + + struct c4_musycc_param + { + u_int8_t RWportnum; + u_int16_t offset; + u_int32_t value; + }; + +/*Alarm values */ +#define sbeE1RMAI 0x100 +#define sbeYelAlm 0x04 +#define sbeRedAlm 0x02 +#define sbeAISAlm 0x01 + +#define sbeE1errSMF 0x02 +#define sbeE1CRC 0x01 + +#ifdef __cplusplus +} +#endif + +#ifdef __KERNEL__ + +/* + * Device Driver interface, routines are for internal use only. + */ + +#include "pmcc4_private.h" + +#if !(LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +char *get_hdlc_name (hdlc_device *); + +#endif + + +/* + * external interface + */ + +void c4_cleanup (void); +status_t c4_chan_up (ci_t *, int channum); +status_t c4_del_chan_stats (int channum); +status_t c4_del_chan (int channum); +status_t c4_get_iidinfo (ci_t * ci, struct sbe_iid_info * iip); +int c4_is_chan_up (int channum); + +void *getuserbychan (int channum); +void pci_flush_write (ci_t * ci); +void sbecom_set_loglevel (int debuglevel); +char *sbeid_get_bdname (ci_t * ci); +void sbeid_set_bdtype (ci_t * ci); +void sbeid_set_hdwbid (ci_t * ci); +u_int32_t sbeCrc (u_int8_t *, u_int32_t, u_int32_t, u_int32_t *); + +void VMETRO_TRACE (void *); /* put data into 8 LEDs */ +void VMETRO_TRIGGER (ci_t *, int); /* Note: int = 0(default) + * thru 15 */ + +#if defined (SBE_ISR_TASKLET) +void musycc_intr_bh_tasklet (ci_t *); + +#endif + +#endif /*** __KERNEL __ ***/ +#endif /* _INC_PMCC4_H_ */ diff --git a/drivers/staging/cxt1e1/pmcc4_cpld.h b/drivers/staging/cxt1e1/pmcc4_cpld.h new file mode 100644 index 000000000000..6d8f0337aa3e --- /dev/null +++ b/drivers/staging/cxt1e1/pmcc4_cpld.h @@ -0,0 +1,124 @@ +/* + * $Id: pmcc4_cpld.h,v 1.0 2005/09/28 00:10:08 rickd PMCC4_3_1B $ + */ + +#ifndef _INC_PMCC4_CPLD_H_ +#define _INC_PMCC4_CPLD_H_ + +/*----------------------------------------------------------------------------- + * pmcc4_cpld.h - + * + * Copyright (C) 2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For further information, contact via email: support@sbei.com + * SBE, Inc. San Ramon, California U.S.A. + *----------------------------------------------------------------------------- + * RCS info: + * RCS revision: $Revision: 1.0 $ + * Last changed on $Date: 2005/09/28 00:10:08 $ + * Changed by $Author: rickd $ + *----------------------------------------------------------------------------- + * $Log: pmcc4_cpld.h,v $ + * Revision 1.0 2005/09/28 00:10:08 rickd + * Initial revision + * + *----------------------------------------------------------------------------- + */ + + +#if defined(__FreeBSD__) || defined(__NetBSD__) +#include +#else +#ifndef __KERNEL__ +#include +#else +#include +#endif +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/********************************/ +/* iSPLD control chip registers */ +/********************************/ + +#if 0 +#define CPLD_MCSR 0x0 +#define CPLD_MCLK 0x1 +#define CPLD_LEDS 0x2 +#define CPLD_INTR 0x3 +#endif + + struct c4_cpld + { + volatile u_int32_t mcsr;/* r/w: Master Clock Source Register */ + volatile u_int32_t mclk;/* r/w: Master Clock Register */ + volatile u_int32_t leds;/* r/w: LED Register */ + volatile u_int32_t intr;/* r: Interrupt Register */ + }; + + typedef struct c4_cpld c4cpld_t; + +/* mcsr note: sourcing COMET must be initialized to Master Mode */ +#define PMCC4_CPLD_MCSR_IND 0 /* ports used individual BP Clk as + * source, no slaves */ +#define PMCC4_CPLD_MCSR_CMT_1 1 /* COMET 1 BP Clk is source, 2,3,4 + * are Clk slaves */ +#define PMCC4_CPLD_MCSR_CMT_2 2 /* COMET 2 BP Clk is source, 1,3,4 + * are Clk slaves */ +#define PMCC4_CPLD_MCSR_CMT_3 3 /* COMET 3 BP Clk is source, 1,2,4 + * are Clk slaves */ +#define PMCC4_CPLD_MCSR_CMT_4 4 /* COMET 4 BP Clk is source, 1,2,3 + * are Clk slaves */ + +#define PMCC4_CPLD_MCLK_MASK 0x0f +#define PMCC4_CPLD_MCLK_P1 0x1 +#define PMCC4_CPLD_MCLK_P2 0x2 +#define PMCC4_CPLD_MCLK_P3 0x4 +#define PMCC4_CPLD_MCLK_P4 0x8 +#define PMCC4_CPLD_MCLK_T1 0x00 +#define PMCC4_CPLD_MCLK_P1_E1 0x01 +#define PMCC4_CPLD_MCLK_P2_E1 0x02 +#define PMCC4_CPLD_MCLK_P3_E1 0x04 +#define PMCC4_CPLD_MCLK_P4_E1 0x08 + +#define PMCC4_CPLD_LED_OFF 0 +#define PMCC4_CPLD_LED_ON 1 +#define PMCC4_CPLD_LED_GP0 0x01 /* port 0, green */ +#define PMCC4_CPLD_LED_YP0 0x02 /* port 0, yellow */ +#define PMCC4_CPLD_LED_GP1 0x04 /* port 1, green */ +#define PMCC4_CPLD_LED_YP1 0x08 /* port 1, yellow */ +#define PMCC4_CPLD_LED_GP2 0x10 /* port 2, green */ +#define PMCC4_CPLD_LED_YP2 0x20 /* port 2, yellow */ +#define PMCC4_CPLD_LED_GP3 0x40 /* port 3, green */ +#define PMCC4_CPLD_LED_YP3 0x80 /* port 3, yellow */ +#define PMCC4_CPLD_LED_GREEN (PMCC4_CPLD_LED_GP0 | PMCC4_CPLD_LED_GP1 | \ + PMCC4_CPLD_LED_GP2 | PMCC4_CPLD_LED_GP3 ) +#define PMCC4_CPLD_LED_YELLOW (PMCC4_CPLD_LED_YP0 | PMCC4_CPLD_LED_YP1 | \ + PMCC4_CPLD_LED_YP2 | PMCC4_CPLD_LED_YP3) + +#define PMCC4_CPLD_INTR_MASK 0x0f +#define PMCC4_CPLD_INTR_CMT_1 0x01 +#define PMCC4_CPLD_INTR_CMT_2 0x02 +#define PMCC4_CPLD_INTR_CMT_3 0x04 +#define PMCC4_CPLD_INTR_CMT_4 0x08 + +#ifdef __cplusplus +} +#endif + +#endif /* _INC_PMCC4_CPLD_H_ */ diff --git a/drivers/staging/cxt1e1/pmcc4_defs.h b/drivers/staging/cxt1e1/pmcc4_defs.h new file mode 100644 index 000000000000..186347b8d565 --- /dev/null +++ b/drivers/staging/cxt1e1/pmcc4_defs.h @@ -0,0 +1,82 @@ +/* + * $Id: pmcc4_defs.h,v 1.0 2005/09/28 00:10:09 rickd PMCC4_3_1B $ + */ + +#ifndef _INC_PMCC4_DEFS_H_ +#define _INC_PMCC4_DEFS_H_ + +/*----------------------------------------------------------------------------- + * c4_defs.h - + * + * Implementation elements of the wanPMC-C4T1E1 device driver + * + * Copyright (C) 2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For further information, contact via email: support@sbei.com + * SBE, Inc. San Ramon, California U.S.A. + *----------------------------------------------------------------------------- + * RCS info: + * RCS revision: $Revision: 1.0 $ + * Last changed on $Date: 2005/09/28 00:10:09 $ + * Changed by $Author: rickd $ + *----------------------------------------------------------------------------- + * $Log: pmcc4_defs.h,v $ + * Revision 1.0 2005/09/28 00:10:09 rickd + * Initial revision + * + *----------------------------------------------------------------------------- + */ + + +#define MAX_BOARDS 8 +#define MAX_CHANS_USED 128 + +#ifdef SBE_PMCC4_ENABLE +#define MUSYCC_NPORTS 4 /* CN8474 */ +#endif +#ifdef SBE_WAN256T3_ENABLE +#define MUSYCC_NPORTS 8 /* CN8478 */ +#endif +#define MUSYCC_NCHANS 32 /* actually, chans per port */ + +#define MUSYCC_NIQD 0x1000 /* power of 2 */ +#define MUSYCC_MRU 2048 /* default */ +#define MUSYCC_MTU 2048 /* default */ +#define MUSYCC_TXDESC_MIN 10 /* HDLC mode default */ +#define MUSYCC_RXDESC_MIN 18 /* HDLC mode default */ +#define MUSYCC_TXDESC_TRANS 4 /* Transparent mode minumum # of TX descriptors */ +#define MUSYCC_RXDESC_TRANS 12 /* Transparent mode minumum # of RX descriptors */ + +#define MAX_DEFAULT_IFQLEN 32 /* network qlen */ + + +#define SBE_IFACETMPL "pmcc4-%d" +#ifdef IFNAMSIZ +#define SBE_IFACETMPL_SIZE IFNAMSIZ +#else +#define SBE_IFACETMPL_SIZE 16 +#endif + +/* we want the PMCC4 watchdog to fire off every 250ms */ +#define WATCHDOG_TIMEOUT 250000 + +/* if we restart the watchdog every 250ms, then we'll time out + * an additional 300ms later */ +#define WATCHDOG_UTIMEOUT (WATCHDOG_TIMEOUT+300000) + +#if !defined(SBE_ISR_TASKLET) && !defined(SBE_ISR_IMMEDIATE) && !defined(SBE_ISR_INLINE) +#define SBE_ISR_TASKLET +#endif + +#endif /*** _INC_PMCC4_DEFS_H_ ***/ + diff --git a/drivers/staging/cxt1e1/pmcc4_drv.c b/drivers/staging/cxt1e1/pmcc4_drv.c new file mode 100644 index 000000000000..ada80d0b6059 --- /dev/null +++ b/drivers/staging/cxt1e1/pmcc4_drv.c @@ -0,0 +1,1855 @@ +/* + * $Id: pmcc4_drv.c,v 3.1 2007/08/15 23:32:17 rickd PMCC4_3_1B $ + */ + + +/*----------------------------------------------------------------------------- + * pmcc4_drv.c - + * + * Copyright (C) 2007 One Stop Systems, Inc. + * Copyright (C) 2002-2006 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For further information, contact via email: support@onestopsystems.com + * One Stop Systems, Inc. Escondido, California U.S.A. + *----------------------------------------------------------------------------- + * RCS info: + * RCS revision: $Revision: 3.1 $ + * Last changed on $Date: 2007/08/15 23:32:17 $ + * Changed by $Author: rickd $ + *----------------------------------------------------------------------------- + * $Log: pmcc4_drv.c,v $ + * Revision 3.1 2007/08/15 23:32:17 rickd + * Use 'if 0' instead of GNU comment delimeter to avoid line wrap induced compiler errors. + * + * Revision 3.0 2007/08/15 22:19:55 rickd + * Correct sizeof() castings and pi->regram to support 64bit compatibility. + * + * Revision 2.10 2006/04/21 00:56:40 rickd + * workqueue files now prefixed with prefix. + * + * Revision 2.9 2005/11/01 19:22:49 rickd + * Add sanity checks against max_port for ioctl functions. + * + * Revision 2.8 2005/10/27 18:59:25 rickd + * Code cleanup. Default channel config to HDLC_FCS16. + * + * Revision 2.7 2005/10/18 18:16:30 rickd + * Further NCOMM code repairs - (1) interrupt matrix usage inconsistant + * for indexing into nciInterrupt[][], code missing double parameters. + * (2) check input of ncomm interrupt registration cardID for correct + * boundary values. + * + * Revision 2.6 2005/10/17 23:55:28 rickd + * Initial port of NCOMM support patches from original work found + * in pmc_c4t1e1 as updated by NCOMM. Ref: CONFIG_SBE_PMCC4_NCOMM. + * Corrected NCOMMs wanpmcC4T1E1_getBaseAddress() to correctly handle + * multiple boards. + * + * Revision 2.5 2005/10/13 23:01:28 rickd + * Correct panic for illegal address reference w/in get_brdinfo on + * first_if/last_if name acquistion under Linux 2.6 + * + * Revision 2.4 2005/10/13 21:20:19 rickd + * Correction of c4_cleanup() wherein next should be acquired before + * ci_t structure is free'd. + * + * Revision 2.3 2005/10/13 19:20:10 rickd + * Correct driver removal cleanup code for multiple boards. + * + * Revision 2.2 2005/10/11 18:34:04 rickd + * New routine added to determine number of ports (comets) on board. + * + * Revision 2.1 2005/10/05 00:48:13 rickd + * Add some RX activation trace code. + * + * Revision 2.0 2005/09/28 00:10:06 rickd + * Implement 2.6 workqueue for TX/RX restart. Correction to + * hardware register boundary checks allows expanded access of MUSYCC. + * Implement new musycc reg&bits namings. + * + *----------------------------------------------------------------------------- + */ + +char OSSIid_pmcc4_drvc[] = +"@(#)pmcc4_drv.c - $Revision: 3.1 $ (c) Copyright 2002-2007 One Stop Systems, Inc."; + + +#if defined (__FreeBSD__) || defined (__NetBSD__) +#include +#include +#include +#else +#include +#include "pmcc4_sysdep.h" +#include +#include +#include /* include for timer */ +#include /* include for timer */ +#include +#include +#endif + +#include "sbecom_inline_linux.h" +#include "libsbew.h" +#include "pmcc4_private.h" +#include "pmcc4.h" +#include "pmcc4_ioctls.h" +#include "musycc.h" +#include "comet.h" +#include "sbe_bid.h" + +#ifdef SBE_INCLUDE_SYMBOLS +#define STATIC +#else +#define STATIC static +#endif + + +#define KERN_WARN KERN_WARNING + +/* forward references */ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41) +status_t c4_wk_chan_init (mpi_t *, mch_t *); +void c4_wq_port_cleanup (mpi_t *); +status_t c4_wq_port_init (mpi_t *); + +#endif +int c4_loop_port (ci_t *, int, u_int8_t); +status_t c4_set_port (ci_t *, int); +status_t musycc_chan_down (ci_t *, int); + +u_int32_t musycc_chan_proto (int); +status_t musycc_dump_ring (ci_t *, unsigned int); +status_t __init musycc_init (ci_t *); +void musycc_init_mdt (mpi_t *); +void musycc_serv_req (mpi_t *, u_int32_t); +void musycc_update_timeslots (mpi_t *); + +extern void musycc_update_tx_thp (mch_t *); +extern int log_level; +extern int max_mru; +extern int max_mtu; +extern int max_rxdesc_used, max_rxdesc_default; +extern int max_txdesc_used, max_txdesc_default; + +#if defined (__powerpc__) +extern void *memset (void *s, int c, size_t n); + +#endif + +int drvr_state = SBE_DRVR_INIT; +ci_t *c4_list = 0; +ci_t *CI; /* dummy pointer to board ZEROE's data - + * DEBUG USAGE */ + + +void +sbecom_set_loglevel (int d) +{ + /* + * The code within the following -if- clause is a backdoor debug facility + * which can be used to display the state of a board's channel. + */ + if (d > LOG_DEBUG) + { + unsigned int channum = d - (LOG_DEBUG + 1); /* convert to ZERO + * relativity */ + + (void) musycc_dump_ring ((ci_t *) CI, channum); /* CI implies support + * for card 0 only */ + } else + { + if (log_level != d) + { + printk ("%s: log level changed from %d to %d\n", THIS_MODULE->name, log_level, d); + log_level = d; /* set new */ + } else + printk ("%s: log level is %d\n", THIS_MODULE->name, log_level); + } +} + + +mch_t * +c4_find_chan (int channum) +{ + ci_t *ci; + mch_t *ch; + int portnum, gchan; + + for (ci = c4_list; ci; ci = ci->next) + for (portnum = 0; portnum < ci->max_port; portnum++) + for (gchan = 0; gchan < MUSYCC_NCHANS; gchan++) + { + if ((ch = ci->port[portnum].chan[gchan])) + { + if ((ch->state != UNASSIGNED) && + (ch->channum == channum)) + return (ch); + } + } + return 0; +} + + +ci_t *__init +c4_new (void *hi) +{ + ci_t *ci; + +#ifdef SBE_MAP_DEBUG + printk (KERN_WARNING "%s: c4_new() entered, ci needs %u.\n", + THIS_MODULE->name, (unsigned int) sizeof (ci_t)); +#endif + + ci = (ci_t *) OS_kmalloc (sizeof (ci_t)); + if (ci) + { + ci->hdw_info = hi; + ci->state = C_INIT; /* mark as hardware not available */ + ci->next = c4_list; + c4_list = ci; + ci->brdno = ci->next ? ci->next->brdno + 1 : 0; + } else + printk (KERN_WARNING "%s: failed CI malloc, size %u.\n", + THIS_MODULE->name, (unsigned int) sizeof (ci_t)); + + if (CI == 0) + CI = ci; /* DEBUG, only board 0 usage */ + return ci; +} + + +/*** + * Check port state and set LED states using watchdog or ioctl... + * also check for in-band SF loopback commands (& cause results if they are there) + * + * Alarm function depends on comet bits indicating change in + * link status (linkMask) to keep the link status indication straight. + * + * Indications are only LED and system log -- except when ioctl is invoked. + * + * "alarmed" record (a.k.a. copyVal, in some cases below) decodes as: + * + * RMAI (E1 only) 0x100 + * alarm LED on 0x80 + * link LED on 0x40 + * link returned 0x20 (link was down, now it's back and 'port get' hasn't run) + * change in LED 0x10 (update LED register because value has changed) + * link is down 0x08 + * YelAlm(RAI) 0x04 + * RedAlm 0x02 + * AIS(blue)Alm 0x01 + * + * note "link has returned" indication is reset on read + * (e.g. by use of the c4_control port get command) + */ + +#define sbeLinkMask 0x41 /* change in signal status (lost/recovered) + + * state */ +#define sbeLinkChange 0x40 +#define sbeLinkDown 0x01 +#define sbeAlarmsMask 0x07 /* red / yellow / blue alarm conditions */ +#define sbeE1AlarmsMask 0x107 /* alarm conditions */ + +#define COMET_LBCMD_READ 0x80 /* read only (do not set, return read value) */ + +void +checkPorts (ci_t * ci) +{ +#ifndef CONFIG_SBE_PMCC4_NCOMM + /* + * PORT POINT - NCOMM needs to avoid this code since the polling of + * alarms conflicts with NCOMM's interrupt servicing implementation. + */ + + comet_t *comet; + volatile u_int32_t value; + u_int32_t copyVal, LEDval; + + u_int8_t portnum; + + LEDval = 0; + for (portnum = 0; portnum < ci->max_port; portnum++) + { + copyVal = 0x12f & (ci->alarmed[portnum]); /* port's alarm record */ + comet = ci->port[portnum].cometbase; + value = pci_read_32 ((u_int32_t *) &comet->cdrc_ists) & sbeLinkMask; /* link loss reg */ + + if (value & sbeLinkChange) /* is there a change in the link stuff */ + { + /* if there's been a change (above) and yet it's the same (below) */ + if (!(((copyVal >> 3) & sbeLinkDown) ^ (value & sbeLinkDown))) + { + if (value & sbeLinkDown) + printk (KERN_WARN "%s: Port %d momentarily recovered.\n", + ci->devname, portnum); + else + printk (KERN_WARN + "%s: Warning: Port %d link was briefly down.\n", + ci->devname, portnum); + } else if (value & sbeLinkDown) + printk (KERN_WARN "%s: Warning: Port %d link is down.\n", + ci->devname, portnum); + else + { + printk (KERN_WARN "%s: Port %d link has recovered.\n", + ci->devname, portnum); + copyVal |= 0x20; /* record link transition to up */ + } + copyVal |= 0x10; /* change (link) --> update LEDs */ + } + copyVal &= 0x137; /* clear LED & link old history bits & + * save others */ + if (value & sbeLinkDown) + copyVal |= 0x08; /* record link status (now) */ + else + { /* if link is up, do this */ + copyVal |= 0x40; /* LED indicate link is up */ + /* Alarm things & the like ... first if E1, then if T1 */ + if (IS_FRAME_ANY_E1 (ci->port[portnum].p.port_mode)) + { + /* + * first check Codeword (SaX) changes & CRC and + * sub-multi-frame errors + */ + /* + * note these errors are printed every time they are detected + * vs. alarms + */ + value = pci_read_32 ((u_int32_t *) &comet->e1_frmr_nat_ists); /* codeword */ + if (value & 0x1f) + { /* if errors (crc or smf only) */ + if (value & 0x10) + printk (KERN_WARN + "%s: E1 Port %d Codeword Sa4 change detected.\n", + ci->devname, portnum); + if (value & 0x08) + printk (KERN_WARN + "%s: E1 Port %d Codeword Sa5 change detected.\n", + ci->devname, portnum); + if (value & 0x04) + printk (KERN_WARN + "%s: E1 Port %d Codeword Sa6 change detected.\n", + ci->devname, portnum); + if (value & 0x02) + printk (KERN_WARN + "%s: E1 Port %d Codeword Sa7 change detected.\n", + ci->devname, portnum); + if (value & 0x01) + printk (KERN_WARN + "%s: E1 Port %d Codeword Sa8 change detected.\n", + ci->devname, portnum); + } + value = pci_read_32 ((u_int32_t *) &comet->e1_frmr_mists); /* crc & smf */ + if (value & 0x3) + { /* if errors (crc or smf only) */ + if (value & sbeE1CRC) + printk (KERN_WARN "%s: E1 Port %d CRC-4 error(s) detected.\n", + ci->devname, portnum); + if (value & sbeE1errSMF) /* error in sub-multiframe */ + printk (KERN_WARN "%s: E1 Port %d received errored SMF.\n", + ci->devname, portnum); + } + value = pci_read_32 ((u_int32_t *) &comet->e1_frmr_masts) & 0xcc; /* alarms */ + /* + * pack alarms together (bitmiser), and construct similar to + * T1 + */ + /* RAI,RMAI,.,.,LOF,AIS,.,. ==> RMAI,.,.,.,.,.,RAI,LOF,AIS */ + /* see 0x97 */ + value = (value >> 2); + if (value & 0x30) + { + if (value & 0x20) + value |= 0x40; /* RAI */ + if (value & 0x10) + value |= 0x100; /* RMAI */ + value &= ~0x30; + } /* finished packing alarm in handy order */ + if (value != (copyVal & sbeE1AlarmsMask)) + { /* if alarms changed */ + copyVal |= 0x10;/* change LED status */ + if ((copyVal & sbeRedAlm) && !(value & sbeRedAlm)) + { + copyVal &= ~sbeRedAlm; + printk (KERN_WARN "%s: E1 Port %d LOF alarm ended.\n", + ci->devname, portnum); + } else if (!(copyVal & sbeRedAlm) && (value & sbeRedAlm)) + { + copyVal |= sbeRedAlm; + printk (KERN_WARN "%s: E1 Warning: Port %d LOF alarm.\n", + ci->devname, portnum); + } else if ((copyVal & sbeYelAlm) && !(value & sbeYelAlm)) + { + copyVal &= ~sbeYelAlm; + printk (KERN_WARN "%s: E1 Port %d RAI alarm ended.\n", + ci->devname, portnum); + } else if (!(copyVal & sbeYelAlm) && (value & sbeYelAlm)) + { + copyVal |= sbeYelAlm; + printk (KERN_WARN "%s: E1 Warning: Port %d RAI alarm.\n", + ci->devname, portnum); + } else if ((copyVal & sbeE1RMAI) && !(value & sbeE1RMAI)) + { + copyVal &= ~sbeE1RMAI; + printk (KERN_WARN "%s: E1 Port %d RMAI alarm ended.\n", + ci->devname, portnum); + } else if (!(copyVal & sbeE1RMAI) && (value & sbeE1RMAI)) + { + copyVal |= sbeE1RMAI; + printk (KERN_WARN "%s: E1 Warning: Port %d RMAI alarm.\n", + ci->devname, portnum); + } else if ((copyVal & sbeAISAlm) && !(value & sbeAISAlm)) + { + copyVal &= ~sbeAISAlm; + printk (KERN_WARN "%s: E1 Port %d AIS alarm ended.\n", + ci->devname, portnum); + } else if (!(copyVal & sbeAISAlm) && (value & sbeAISAlm)) + { + copyVal |= sbeAISAlm; + printk (KERN_WARN "%s: E1 Warning: Port %d AIS alarm.\n", + ci->devname, portnum); + } + } + /* end of E1 alarm code */ + } else + { /* if a T1 mode */ + value = pci_read_32 ((u_int32_t *) &comet->t1_almi_ists); /* alarms */ + value &= sbeAlarmsMask; + if (value != (copyVal & sbeAlarmsMask)) + { /* if alarms changed */ + copyVal |= 0x10;/* change LED status */ + if ((copyVal & sbeRedAlm) && !(value & sbeRedAlm)) + { + copyVal &= ~sbeRedAlm; + printk (KERN_WARN "%s: Port %d red alarm ended.\n", + ci->devname, portnum); + } else if (!(copyVal & sbeRedAlm) && (value & sbeRedAlm)) + { + copyVal |= sbeRedAlm; + printk (KERN_WARN "%s: Warning: Port %d red alarm.\n", + ci->devname, portnum); + } else if ((copyVal & sbeYelAlm) && !(value & sbeYelAlm)) + { + copyVal &= ~sbeYelAlm; + printk (KERN_WARN "%s: Port %d yellow (RAI) alarm ended.\n", + ci->devname, portnum); + } else if (!(copyVal & sbeYelAlm) && (value & sbeYelAlm)) + { + copyVal |= sbeYelAlm; + printk (KERN_WARN "%s: Warning: Port %d yellow (RAI) alarm.\n", + ci->devname, portnum); + } else if ((copyVal & sbeAISAlm) && !(value & sbeAISAlm)) + { + copyVal &= ~sbeAISAlm; + printk (KERN_WARN "%s: Port %d blue (AIS) alarm ended.\n", + ci->devname, portnum); + } else if (!(copyVal & sbeAISAlm) && (value & sbeAISAlm)) + { + copyVal |= sbeAISAlm; + printk (KERN_WARN "%s: Warning: Port %d blue (AIS) alarm.\n", + ci->devname, portnum); + } + } + } /* end T1 mode alarm checks */ + } + if (copyVal & sbeAlarmsMask) + copyVal |= 0x80; /* if alarm turn yel LED on */ + if (copyVal & 0x10) + LEDval |= 0x100; /* tag if LED values have changed */ + LEDval |= ((copyVal & 0xc0) >> (6 - (portnum * 2))); + + ci->alarmed[portnum] &= 0xfffff000; /* out with the old (it's fff + * ... foo) */ + ci->alarmed[portnum] |= (copyVal); /* in with the new */ + + /* + * enough with the alarms and LED's, now let's check for loopback + * requests + */ + + if (IS_FRAME_ANY_T1 (ci->port[portnum].p.port_mode)) + { /* if a T1 mode */ + /* + * begin in-band (SF) loopback code detection -- start by reading + * command + */ + value = pci_read_32 ((u_int32_t *) &comet->ibcd_ies); /* detect reg. */ + value &= 0x3; /* trim to handy bits */ + if (value & 0x2) + { /* activate loopback (sets for deactivate + * code length) */ + copyVal = c4_loop_port (ci, portnum, COMET_LBCMD_READ); /* read line loopback + * mode */ + if (copyVal != COMET_MDIAG_LINELB) /* don't do it again if + * already in that mode */ + c4_loop_port (ci, portnum, COMET_MDIAG_LINELB); /* put port in line + * loopback mode */ + } + if (value & 0x1) + { /* deactivate loopback (sets for activate + * code length) */ + copyVal = c4_loop_port (ci, portnum, COMET_LBCMD_READ); /* read line loopback + * mode */ + if (copyVal != COMET_MDIAG_LBOFF) /* don't do it again if + * already in that mode */ + c4_loop_port (ci, portnum, COMET_MDIAG_LBOFF); /* take port out of any + * loopback mode */ + } + } + if (IS_FRAME_ANY_T1ESF (ci->port[portnum].p.port_mode)) + { /* if a T1 ESF mode */ + /* begin ESF loopback code */ + value = pci_read_32 ((u_int32_t *) &comet->t1_rboc_sts) & 0x3f; /* read command */ + if (value == 0x07) + c4_loop_port (ci, portnum, COMET_MDIAG_LINELB); /* put port in line + * loopback mode */ + if (value == 0x0a) + c4_loop_port (ci, portnum, COMET_MDIAG_PAYLB); /* put port in payload + * loopbk mode */ + if ((value == 0x1c) || (value == 0x19) || (value == 0x12)) + c4_loop_port (ci, portnum, COMET_MDIAG_LBOFF); /* take port out of any + * loopbk mode */ + if (log_level >= LOG_DEBUG) + if (value != 0x3f) + printk (KERN_WARN "%s: BOC value = %x on Port %d\n", + ci->devname, value, portnum); + /* end ESF loopback code */ + } + } + + /* if something is new, update LED's */ + if (LEDval & 0x100) + pci_write_32 ((u_int32_t *) &ci->cpldbase->leds, LEDval & 0xff); +#endif /*** CONFIG_SBE_PMCC4_NCOMM ***/ +} + + +STATIC void +c4_watchdog (ci_t * ci) +{ +#if 0 + //unsigned long flags; +#endif + + if (drvr_state != SBE_DRVR_AVAILABLE) + { + if (log_level >= LOG_MONITOR) + printk ("%s: drvr not available (%x)\n", THIS_MODULE->name, drvr_state); + return; + } +#if 0 + SD_SEM_TAKE (&ci->sem_wdbusy, "_wd_"); /* only 1 thru here, per + * board */ +#endif + + ci->wdcount++; + checkPorts (ci); +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,41) + if (ci->wd_notify) + { /* is there a state change to search for */ + int port, gchan; + + ci->wd_notify = 0; /* reset notification */ + for (gchan = 0; gchan < MUSYCC_NCHANS; gchan++) + { + for (port = 0; port < ci->max_port; port++) + { + mch_t *ch = ci->port[port].chan[gchan]; + + if (!ch || ci->state != C_RUNNING) /* state changed while + * acquiring semaphore */ + break; + if (ch->state == UP)/* channel must be set up */ + { +#if 0 +#ifdef RLD_TRANS_DEBUG + if (1 || log_level >= LOG_MONITOR) +#else + if (log_level >= LOG_MONITOR) +#endif + printk ("%s: watchdog reviving Port %d Channel %d [%d] sts %x/%x, start_TX %x free %x start_RX %x\n", + ci->devname, ch->channum, port, gchan, ch->channum, + ch->p.status, ch->status, + ch->ch_start_tx, ch->txd_free, ch->ch_start_rx); +#endif + + /**********************************/ + /** check for RX restart request **/ + /**********************************/ + + if (ch->ch_start_rx && + (ch->status & RX_ENABLED)) /* requires start on + * enabled RX */ + { + ch->ch_start_rx = 0; /* we are restarting RX... */ +#ifdef RLD_TRANS_DEBUG + printk ("++ c4_watchdog() CHAN RX ACTIVATE: chan %d\n", ch->channum); +#endif +#ifdef RLD_RXACT_DEBUG + { + struct mdesc *md; + static int hereb4 = 7; + + if (hereb4) + { + hereb4--; + md = &ch->mdr[ch->rxix_irq_srv]; + printk ("++ c4_watchdog[%d] CHAN RX ACTIVATE: rxix_irq_srv %d, md %p sts %x, rxpkt %lu\n", + ch->channum, ch->rxix_irq_srv, md, le32_to_cpu (md->status), ch->s.rx_packets); + musycc_dump_rxbuffer_ring (ch, 1); /* RLD DEBUG */ + } + } +#endif + musycc_serv_req (ch->up, SR_CHANNEL_ACTIVATE | SR_RX_DIRECTION | gchan); + } + /**********************************/ + /** check for TX restart request **/ + /**********************************/ + + if (ch->ch_start_tx && + (ch->status & TX_ENABLED)) /* requires start on + * enabled TX */ + { + struct mdesc *md; + + /* + * find next unprocessed message, then set TX thp to + * it + */ + musycc_update_tx_thp (ch); + +#if 0 + spin_lock_irqsave (&ch->ch_txlock, flags); +#endif + md = ch->txd_irq_srv; + if (!md) + { + printk ("-- c4_watchdog[%d]: WARNING, starting NULL md\n", ch->channum); + printk ("-- chan %d txd_irq_srv %p sts %x usr_add %p sts %x, txpkt %lu\n", + ch->channum, ch->txd_irq_srv, le32_to_cpu ((struct mdesc *) (ch->txd_irq_srv)->status), + ch->txd_usr_add, le32_to_cpu ((struct mdesc *) (ch->txd_usr_add)->status), + ch->s.tx_packets); +#if 0 + spin_unlock_irqrestore (&ch->ch_txlock, flags); +#endif + } else if (md->data && ((le32_to_cpu (md->status)) & MUSYCC_TX_OWNED)) + { +#ifdef RLD_TRANS_DEBUG + printk ("++ c4_watchdog[%d] CHAN TX ACTIVATE: start_tx %x\n", ch->channum, ch->ch_start_tx); +#endif + ch->ch_start_tx = 0; /* we are restarting + * TX... */ +#if 0 + spin_unlock_irqrestore (&ch->ch_txlock, flags); /* allow interrupts for + * service request */ +#endif + musycc_serv_req (ch->up, SR_CHANNEL_ACTIVATE | SR_TX_DIRECTION | gchan); +#ifdef RLD_TRANS_DEBUG + if (1 || log_level >= LOG_MONITOR) +#else + if (log_level >= LOG_MONITOR) +#endif + printk ("++ SACK[P%d/C%d] ack'd, continuing...\n", ch->up->portnum, ch->channum); + } + } + } + } + } + } +#else + ci->wd_notify = 0; +#endif +#if 0 + SD_SEM_GIVE (&ci->sem_wdbusy);/* release per-board hold */ +#endif +} + + +void +c4_cleanup (void) +{ + ci_t *ci, *next; + mpi_t *pi; + int portnum, j; + + ci = c4_list; + while (ci) + { + next = ci->next; /* protect from upcoming */ + pci_write_32 ((u_int32_t *) &ci->cpldbase->leds, PMCC4_CPLD_LED_OFF); + for (portnum = 0; portnum < ci->max_port; portnum++) + { + pi = &ci->port[portnum]; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41) + c4_wq_port_cleanup (pi); +#endif + for (j = 0; j < MUSYCC_NCHANS; j++) + { + if (pi->chan[j]) + OS_kfree (pi->chan[j]); /* free mch_t struct */ + } + OS_kfree (pi->regram_saved); + } +#if 0 + /* obsolete - watchdog is now static w/in ci_t */ + OS_free_watchdog (ci->wd); +#endif + OS_kfree (ci->iqd_p_saved); + OS_kfree (ci); + ci = next; /* cleanup next board, if any */ + } +} + + +/* + * This function issues a write to all comet chips and expects the same data + * to be returned from the subsequent read. This determines the board build + * to be a 1-port, 2-port, or 4-port build. The value returned represents a + * bit-mask of the found ports. Only certain configurations are considered + * VALID or LEGAL builds. + */ + +int +c4_get_portcfg (ci_t * ci) +{ + comet_t *comet; + int portnum, mask; + u_int32_t wdata, rdata; + + wdata = COMET_MDIAG_LBOFF; /* take port out of any loopback mode */ + + mask = 0; + for (portnum = 0; portnum < MUSYCC_NPORTS; portnum++) + { + comet = ci->port[portnum].cometbase; + pci_write_32 ((u_int32_t *) &comet->mdiag, wdata); + rdata = pci_read_32 ((u_int32_t *) &comet->mdiag) & COMET_MDIAG_LBMASK; + if (wdata == rdata) + mask |= 1 << portnum; + } + return mask; +} + + +/* nothing herein should generate interrupts */ + +status_t __init +c4_init (ci_t * ci, u_char *func0, u_char *func1) +{ + mpi_t *pi; + mch_t *ch; + static u_int32_t count = 0; + int portnum, j; + + ci->state = C_INIT; + ci->brdno = count++; + ci->intlog.this_status_new = 0; + atomic_set (&ci->bh_pending, 0); + + ci->reg = (struct musycc_globalr *) func0; + ci->eeprombase = (u_int32_t *) (func1 + EEPROM_OFFSET); + ci->cpldbase = (c4cpld_t *) ((u_int32_t *) (func1 + ISPLD_OFFSET)); + + /*** PORT POINT - the following is the first access of any type to the hardware ***/ +#ifdef CONFIG_SBE_PMCC4_NCOMM + /* NCOMM driver uses INTB interrupt to monitor CPLD register */ + pci_write_32 ((u_int32_t *) &ci->reg->glcd, GCD_MAGIC); +#else + /* standard driver POLLS for INTB via CPLD register */ + pci_write_32 ((u_int32_t *) &ci->reg->glcd, GCD_MAGIC | MUSYCC_GCD_INTB_DISABLE); +#endif + + { + int pmsk; + + /* need comet addresses available for determination of hardware build */ + for (portnum = 0; portnum < MUSYCC_NPORTS; portnum++) + { + pi = &ci->port[portnum]; + pi->cometbase = (comet_t *) ((u_int32_t *) (func1 + COMET_OFFSET (portnum))); + pi->reg = (struct musycc_globalr *) ((u_char *) ci->reg + (portnum * 0x800)); + pi->portnum = portnum; + pi->p.portnum = portnum; + pi->openchans = 0; +#ifdef SBE_MAP_DEBUG + printk ("Comet-%d: addr = %p\n", portnum, pi->cometbase); +#endif + } + pmsk = c4_get_portcfg (ci); + switch (pmsk) + { + case 0x1: + ci->max_port = 1; + break; + case 0x3: + ci->max_port = 2; + break; +#if 0 + case 0x7: /* not built, but could be... */ + ci->max_port = 3; + break; +#endif + case 0xf: + ci->max_port = 4; + break; + default: + ci->max_port = 0; + printk (KERN_WARNING "%s: illegal port configuration (%x)\n", ci->devname, pmsk); + return SBE_DRVR_FAIL; + } +#ifdef SBE_MAP_DEBUG + printk (">> %s: c4_get_build - pmsk %x max_port %x\n", ci->devname, pmsk, ci->max_port); +#endif + } + + for (portnum = 0; portnum < ci->max_port; portnum++) + { + pi = &ci->port[portnum]; + pi->up = ci; + pi->sr_last = 0xffffffff; + pi->p.port_mode = CFG_FRAME_SF; /* T1 B8ZS, the default */ + pi->p.portP = (CFG_CLK_PORT_EXTERNAL | CFG_LBO_LH0); /* T1 defaults */ + + OS_sem_init (&pi->sr_sem_busy, SEM_AVAILABLE); + OS_sem_init (&pi->sr_sem_wait, SEM_TAKEN); + + for (j = 0; j < 32; j++) + { + pi->fifomap[j] = -1; + pi->tsm[j] = 0; /* no assignments, all available */ + } + + /* allocate channel structures for this port */ + for (j = 0; j < MUSYCC_NCHANS; j++) + { + ch = OS_kmalloc (sizeof (mch_t)); + if (ch) + { + pi->chan[j] = ch; + ch->state = UNASSIGNED; + ch->up = pi; + ch->gchan = (-1); /* channel assignment not yet known */ + ch->channum = (-1); /* channel assignment not yet known */ + ch->p.card = ci->brdno; + ch->p.port = portnum; + ch->p.channum = (-1); /* channel assignment not yet known */ + ch->p.mode_56k = 0; /* default is 64kbps mode */ + } else + { + printk (KERN_WARNING "%s: failed mch_t malloc, port %d channel %d size %u.\n", + THIS_MODULE->name, portnum, j, (unsigned int) sizeof (mch_t)); + break; + } + } + } + + + { + /* + * Set LEDs through their paces to supply visual proof that LEDs are + * functional and not burnt out nor broken. + * + * YELLOW + GREEN -> OFF. + */ + + pci_write_32 ((u_int32_t *) &ci->cpldbase->leds, + PMCC4_CPLD_LED_GREEN | PMCC4_CPLD_LED_YELLOW); + OS_uwait (750000, "leds"); + pci_write_32 ((u_int32_t *) &ci->cpldbase->leds, PMCC4_CPLD_LED_OFF); + } + + OS_init_watchdog (&ci->wd, (void (*) (void *)) c4_watchdog, ci, WATCHDOG_TIMEOUT); + return SBE_DRVR_SUCCESS; +} + + +/* better be fully setup to handle interrupts when you call this */ + +status_t __init +c4_init2 (ci_t * ci) +{ + status_t ret; + + /* PORT POINT: this routine generates first interrupt */ + if ((ret = musycc_init (ci)) != SBE_DRVR_SUCCESS) + return ret; + +#if 0 + ci->p.framing_type = FRAMING_CBP; + ci->p.h110enable = 1; +#if 0 + ci->p.hypersize = 0; +#else + hyperdummy = 0; +#endif + ci->p.clock = 0; /* Use internal clocking until set to + * external */ + c4_card_set_params (ci, &ci->p); +#endif + OS_start_watchdog (&ci->wd); + return SBE_DRVR_SUCCESS; +} + + +/* This function sets the loopback mode (or clears it, as the case may be). */ + +int +c4_loop_port (ci_t * ci, int portnum, u_int8_t cmd) +{ + comet_t *comet; + volatile u_int32_t loopValue; + + comet = ci->port[portnum].cometbase; + loopValue = pci_read_32 ((u_int32_t *) &comet->mdiag) & COMET_MDIAG_LBMASK; + + if (cmd & COMET_LBCMD_READ) + return loopValue; /* return the read value */ + + if (loopValue != cmd) + { + switch (cmd) + { + case COMET_MDIAG_LINELB: + /* set(SF)loopback down (turn off) code length to 6 bits */ + pci_write_32 ((u_int32_t *) &comet->ibcd_cfg, 0x05); + break; + case COMET_MDIAG_LBOFF: + /* set (SF) loopback up (turn on) code length to 5 bits */ + pci_write_32 ((u_int32_t *) &comet->ibcd_cfg, 0x00); + break; + } + + pci_write_32 ((u_int32_t *) &comet->mdiag, cmd); + if (log_level >= LOG_WARN) + printk ("%s: loopback mode changed to %2x from %2x on Port %d\n", + ci->devname, cmd, loopValue, portnum); + loopValue = pci_read_32 ((u_int32_t *) &comet->mdiag) & COMET_MDIAG_LBMASK; + if (loopValue != cmd) + { + if (log_level >= LOG_ERROR) + printk ("%s: write to loop register failed, unknown state for Port %d\n", + ci->devname, portnum); + } + } else + { + if (log_level >= LOG_WARN) + printk ("%s: loopback already in that mode (%2x)\n", ci->devname, loopValue); + } + return 0; +} + + +/* c4_frame_rw: read or write the comet register specified + * (modifies use of port_param to non-standard use of struct) + * Specifically: + * pp.portnum (one guess) + * pp.port_mode offset of register + * pp.portP write (or not, i.e. read) + * pp.portStatus write value + * BTW: + * pp.portStatus also used to return read value + * pp.portP also used during write, to return old reg value + */ + +status_t +c4_frame_rw (ci_t * ci, struct sbecom_port_param * pp) +{ + comet_t *comet; + volatile u_int32_t data; + + if (pp->portnum >= ci->max_port)/* sanity check */ + return ENXIO; + + comet = ci->port[pp->portnum].cometbase; + data = pci_read_32 ((u_int32_t *) comet + pp->port_mode) & 0xff; + + if (pp->portP) + { /* control says this is a register + * _write_ */ + if (pp->portStatus == data) + printk ("%s: Port %d already that value! Writing again anyhow.\n", + ci->devname, pp->portnum); + pp->portP = (u_int8_t) data; + pci_write_32 ((u_int32_t *) comet + pp->port_mode, + pp->portStatus); + data = pci_read_32 ((u_int32_t *) comet + pp->port_mode) & 0xff; + } + pp->portStatus = (u_int8_t) data; + return 0; +} + + +/* c4_pld_rw: read or write the pld register specified + * (modifies use of port_param to non-standard use of struct) + * Specifically: + * pp.port_mode offset of register + * pp.portP write (or not, i.e. read) + * pp.portStatus write value + * BTW: + * pp.portStatus also used to return read value + * pp.portP also used during write, to return old reg value + */ + +status_t +c4_pld_rw (ci_t * ci, struct sbecom_port_param * pp) +{ + volatile u_int32_t *regaddr; + volatile u_int32_t data; + int regnum = pp->port_mode; + + regaddr = (u_int32_t *) ci->cpldbase + regnum; + data = pci_read_32 ((u_int32_t *) regaddr) & 0xff; + + if (pp->portP) + { /* control says this is a register + * _write_ */ + pp->portP = (u_int8_t) data; + pci_write_32 ((u_int32_t *) regaddr, pp->portStatus); + data = pci_read_32 ((u_int32_t *) regaddr) & 0xff; + } + pp->portStatus = (u_int8_t) data; + return 0; +} + +/* c4_musycc_rw: read or write the musycc register specified + * (modifies use of port_param to non-standard use of struct) + * Specifically: + * mcp.RWportnum port number and write indication bit (0x80) + * mcp.offset offset of register + * mcp.value write value going in and read value returning + */ + +/* PORT POINT: TX Subchannel Map registers are write-only + * areas within the MUSYCC and always return FF */ +/* PORT POINT: regram and reg structures are minorly different and ioctl + * settings are aligned with the struct musycc_globalr{} usage. + * Also, regram is separately allocated shared memory, allocated for each port. + * PORT POINT: access offsets of 0x6000 for Msg Cfg Desc Tbl are for 4-port MUSYCC + * only. (An 8-port MUSYCC has 0x16000 offsets for accessing its upper 4 tables.) + */ + +status_t +c4_musycc_rw (ci_t * ci, struct c4_musycc_param * mcp) +{ + mpi_t *pi; + volatile u_int32_t *dph; /* hardware implemented register */ + u_int32_t *dpr = 0; /* RAM image of registers for group command + * usage */ + int offset = mcp->offset % 0x800; /* group relative address + * offset, mcp->portnum is + * not used */ + int portnum, ramread = 0; + volatile u_int32_t data; + + /* + * Sanity check hardware accessibility. The 0x6000 portion handles port + * numbers associated with Msg Descr Tbl decoding. + */ + portnum = (mcp->offset % 0x6000) / 0x800; + if (portnum >= ci->max_port) + return ENXIO; + pi = &ci->port[portnum]; + if (mcp->offset >= 0x6000) + offset += 0x6000; /* put back in MsgCfgDesc address offset */ + dph = (u_int32_t *) ((u_long) pi->reg + offset); + + /* read of TX are from RAM image, since hardware returns FF */ + dpr = (u_int32_t *) ((u_long) pi->regram + offset); + if (mcp->offset < 0x6000) /* non MsgDesc Tbl accesses might require + * RAM access */ + { + if (offset >= 0x200 && offset < 0x380) + ramread = 1; + if (offset >= 0x10 && offset < 0x200) + ramread = 1; + } + /* read register from RAM or hardware, depending... */ + if (ramread) + { + data = *dpr; + //printk ("c4_musycc_rw: RAM addr %p read data %x (portno %x offset %x RAM ramread %x)\n", dpr, data, portnum, offset, ramread); /* RLD DEBUG */ + } else + { + data = pci_read_32 ((u_int32_t *) dph); + //printk ("c4_musycc_rw: REG addr %p read data %x (portno %x offset %x RAM ramread %x)\n", dph, data, portnum, offset, ramread); /* RLD DEBUG */ + } + + + if (mcp->RWportnum & 0x80) + { /* control says this is a register + * _write_ */ + if (mcp->value == data) + printk ("%s: musycc grp%d already that value! writing again anyhow.\n", + ci->devname, (mcp->RWportnum & 0x7)); + /* write register RAM */ + if (ramread) + *dpr = mcp->value; + /* write hardware register */ + pci_write_32 ((u_int32_t *) dph, mcp->value); + } + mcp->value = data; /* return the read value (or the 'old + * value', if is write) */ + return 0; +} + +status_t +c4_get_port (ci_t * ci, int portnum) +{ + if (portnum >= ci->max_port) /* sanity check */ + return ENXIO; + + SD_SEM_TAKE (&ci->sem_wdbusy, "_wd_"); /* only 1 thru here, per + * board */ + checkPorts (ci); + ci->port[portnum].p.portStatus = (u_int8_t) ci->alarmed[portnum]; + ci->alarmed[portnum] &= 0xdf; + SD_SEM_GIVE (&ci->sem_wdbusy); /* release per-board hold */ + return 0; +} + +status_t +c4_set_port (ci_t * ci, int portnum) +{ + mpi_t *pi; + struct sbecom_port_param *pp; + int e1mode; + u_int8_t clck; + int i; + + if (portnum >= ci->max_port) /* sanity check */ + return ENXIO; + + pi = &ci->port[portnum]; + pp = &ci->port[portnum].p; + e1mode = IS_FRAME_ANY_E1 (pp->port_mode); + if (log_level >= LOG_MONITOR2) + { + printk ("%s: c4_set_port[%d]: entered, e1mode = %x, openchans %d.\n", + ci->devname, + portnum, e1mode, pi->openchans); + } + if (pi->openchans) + return EBUSY; /* group needs initialization only for + * first channel of a group */ + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41) + { + status_t ret; + + if ((ret = c4_wq_port_init (pi))) /* create/init + * workqueue_struct */ + return (ret); + } +#endif + + init_comet (ci, pi->cometbase, pp->port_mode, 1 /* clockmaster == true */ , pp->portP); + clck = pci_read_32 ((u_int32_t *) &ci->cpldbase->mclk) & PMCC4_CPLD_MCLK_MASK; + if (e1mode) + clck |= 1 << portnum; + else + clck &= 0xf ^ (1 << portnum); + + pci_write_32 ((u_int32_t *) &ci->cpldbase->mclk, clck); + pci_write_32 ((u_int32_t *) &ci->cpldbase->mcsr, PMCC4_CPLD_MCSR_IND); + pci_write_32 ((u_int32_t *) &pi->reg->gbp, OS_vtophys (pi->regram)); + + /*********************************************************************/ + /* ERRATA: If transparent mode is used, do not set OOFMP_DISABLE bit */ + /*********************************************************************/ + + pi->regram->grcd = + __constant_cpu_to_le32 (MUSYCC_GRCD_RX_ENABLE | + MUSYCC_GRCD_TX_ENABLE | + MUSYCC_GRCD_OOFMP_DISABLE | + MUSYCC_GRCD_SF_ALIGN | /* per MUSYCC ERRATA, + * for T1 * fix */ + MUSYCC_GRCD_COFAIRQ_DISABLE | + MUSYCC_GRCD_MC_ENABLE | + (MUSYCC_GRCD_POLLTH_32 << MUSYCC_GRCD_POLLTH_SHIFT)); + + pi->regram->pcd = + __constant_cpu_to_le32 ((e1mode ? 1 : 0) | + MUSYCC_PCD_TXSYNC_RISING | + MUSYCC_PCD_RXSYNC_RISING | + MUSYCC_PCD_RXDATA_RISING); + + /* Message length descriptor */ + pi->regram->mld = __constant_cpu_to_le32 (max_mru | (max_mru << 16)); + + /* tsm algorithm */ + for (i = 0; i < 32; i++) + { + + /*** ASSIGNMENT NOTES: ***/ + /*** Group's channel ZERO unavailable if E1. ***/ + /*** Group's channel 16 unavailable if E1 CAS. ***/ + /*** Group's channels 24-31 unavailable if T1. ***/ + + if (((i == 0) && e1mode) || + ((i == 16) && ((pp->port_mode == CFG_FRAME_E1CRC_CAS) || (pp->port_mode == CFG_FRAME_E1CRC_CAS_AMI))) + || ((i > 23) && (!e1mode))) + { + pi->tsm[i] = 0xff; /* make tslot unavailable for this mode */ + } else + { + pi->tsm[i] = 0x00; /* make tslot available for assignment */ + } + } + for (i = 0; i < MUSYCC_NCHANS; i++) + { + pi->regram->ttsm[i] = 0; + pi->regram->rtsm[i] = 0; + } + FLUSH_MEM_WRITE (); + musycc_serv_req (pi, SR_GROUP_INIT | SR_RX_DIRECTION); + musycc_serv_req (pi, SR_GROUP_INIT | SR_TX_DIRECTION); + + musycc_init_mdt (pi); + + pi->group_is_set = 1; + pi->p = *pp; + return 0; +} + + +unsigned int max_int = 0; + +status_t +c4_new_chan (ci_t * ci, int portnum, int channum, void *user) +{ + mpi_t *pi; + mch_t *ch; + int gchan; + + if (c4_find_chan (channum)) /* a new channel shouldn't already exist */ + return EEXIST; + + if (portnum >= ci->max_port) /* sanity check */ + return ENXIO; + + pi = &(ci->port[portnum]); + /* find any available channel within this port */ + for (gchan = 0; gchan < MUSYCC_NCHANS; gchan++) + { + ch = pi->chan[gchan]; + if (ch && ch->state == UNASSIGNED) /* no assignment is good! */ + break; + } + if (gchan == MUSYCC_NCHANS) /* exhausted table, all were assigned */ + return ENFILE; + + ch->up = pi; + + /* NOTE: mch_t already cleared during OS_kmalloc() */ + ch->state = DOWN; + ch->user = user; + ch->gchan = gchan; + ch->channum = channum; /* mark our channel assignment */ + ch->p.channum = channum; +#if 1 + ch->p.card = ci->brdno; + ch->p.port = portnum; +#endif + ch->p.chan_mode = CFG_CH_PROTO_HDLC_FCS16; + ch->p.idlecode = CFG_CH_FLAG_7E; + ch->p.pad_fill_count = 2; + spin_lock_init (&ch->ch_rxlock); + spin_lock_init (&ch->ch_txlock); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41) + { + status_t ret; + + if ((ret = c4_wk_chan_init (pi, ch))) + return ret; + } +#endif + + /* save off interface assignments which bound a board */ + if (ci->first_if == 0) /* first channel registered is assumed to + * be the lowest channel */ + { + ci->first_if = ci->last_if = user; + ci->first_channum = ci->last_channum = channum; + } else + { + ci->last_if = user; + if (ci->last_channum < channum) /* higher number channel found */ + ci->last_channum = channum; + } + return 0; +} + +status_t +c4_del_chan (int channum) +{ + mch_t *ch; + + if (!(ch = c4_find_chan (channum))) + return ENOENT; + if (ch->state == UP) + musycc_chan_down ((ci_t *) 0, channum); + ch->state = UNASSIGNED; + ch->gchan = (-1); + ch->channum = (-1); + ch->p.channum = (-1); + return 0; +} + +status_t +c4_del_chan_stats (int channum) +{ + mch_t *ch; + + if (!(ch = c4_find_chan (channum))) + return ENOENT; + + memset (&ch->s, 0, sizeof (struct sbecom_chan_stats)); + return 0; +} + + +status_t +c4_set_chan (int channum, struct sbecom_chan_param * p) +{ + mch_t *ch; + int i, x = 0; + + if (!(ch = c4_find_chan (channum))) + return ENOENT; + +#if 1 + if (ch->p.card != p->card || + ch->p.port != p->port || + ch->p.channum != p->channum) + return EINVAL; +#endif + + if (!(ch->up->group_is_set)) + { + return EIO; /* out of order, SET_PORT command + * required prior to first group's + * SET_CHAN command */ + } + /* + * Check for change of parameter settings in order to invoke closing of + * channel prior to hardware poking. + */ + + if (ch->p.status != p->status || ch->p.chan_mode != p->chan_mode || + ch->p.data_inv != p->data_inv || ch->p.intr_mask != p->intr_mask || + ch->txd_free < ch->txd_num) /* to clear out queued messages */ + x = 1; /* we have a change requested */ + for (i = 0; i < 32; i++) /* check for timeslot mapping changes */ + if (ch->p.bitmask[i] != p->bitmask[i]) + x = 1; /* we have a change requested */ + ch->p = *p; + if (x && (ch->state == UP)) /* if change request and channel is + * open... */ + { + status_t ret; + + if ((ret = musycc_chan_down ((ci_t *) 0, channum))) + return ret; + if ((ret = c4_chan_up (ch->up->up, channum))) + return ret; + sd_enable_xmit (ch->user); /* re-enable to catch flow controlled + * channel */ + } + return 0; +} + + +status_t +c4_get_chan (int channum, struct sbecom_chan_param * p) +{ + mch_t *ch; + + if (!(ch = c4_find_chan (channum))) + return ENOENT; + *p = ch->p; + return 0; +} + +status_t +c4_get_chan_stats (int channum, struct sbecom_chan_stats * p) +{ + mch_t *ch; + + if (!(ch = c4_find_chan (channum))) + return ENOENT; + *p = ch->s; + p->tx_pending = atomic_read (&ch->tx_pending); + return 0; +} + +STATIC int +c4_fifo_alloc (mpi_t * pi, int chan, int *len) +{ + int i, l = 0, start = 0, max = 0, maxstart = 0; + + for (i = 0; i < 32; i++) + { + if (pi->fifomap[i] != -1) + { + l = 0; + start = i + 1; + continue; + } + ++l; + if (l > max) + { + max = l; + maxstart = start; + } + if (max == *len) + break; + } + if (max != *len) + { + if (log_level >= LOG_WARN) + printk ( + "%s: wanted to allocate %d fifo space, but got only %d\n", + pi->up->devname, *len, max); + *len = max; + } + if (log_level >= LOG_DEBUG) + printk ("%s: allocated %d fifo at %d for channel %d/%d\n", + pi->up->devname, max, start, chan, pi->p.portnum); + for (i = maxstart; i < (maxstart + max); i++) + pi->fifomap[i] = chan; + return start; +} + +void +c4_fifo_free (mpi_t * pi, int chan) +{ + int i; + + if (log_level >= LOG_DEBUG) + printk ("%s: deallocated fifo for channel %d/%d\n", + pi->up->devname, chan, pi->p.portnum); + for (i = 0; i < 32; i++) + if (pi->fifomap[i] == chan) + pi->fifomap[i] = -1; +} + + +status_t +c4_chan_up (ci_t * ci, int channum) +{ + mpi_t *pi; + mch_t *ch; + struct mbuf *m; + struct mdesc *md; + int nts, nbuf, txnum, rxnum; + int addr, i, j, gchan; + u_int32_t tmp; /* for optimizing conversion across BE + * platform */ + + if (!(ch = c4_find_chan (channum))) + return ENOENT; + if (ch->state == UP) + { + if (log_level >= LOG_MONITOR) + printk ("%s: channel already UP, graceful early exit\n", ci->devname); + return 0; + } + pi = ch->up; + gchan = ch->gchan; + /* find nts ('number of timeslots') */ + nts = 0; + for (i = 0; i < 32; i++) + { + if (ch->p.bitmask[i] & pi->tsm[i]) + { + if (1 || log_level >= LOG_WARN) + { + printk ("%s: c4_chan_up[%d] EINVAL (attempt to cfg in-use or unavailable TimeSlot[%d])\n", + ci->devname, channum, i); + printk ("+ ask4 %x, currently %x\n", ch->p.bitmask[i], pi->tsm[i]); + } + return EINVAL; + } + for (j = 0; j < 8; j++) + if (ch->p.bitmask[i] & (1 << j)) + nts++; + } + + nbuf = nts / 8 ? nts / 8 : 1; + if (!nbuf) + { + /* if( log_level >= LOG_WARN) */ + printk ("%s: c4_chan_up[%d] ENOBUFS (no TimeSlots assigned)\n", ci->devname, channum); + return ENOBUFS; /* this should not happen */ + } + addr = c4_fifo_alloc (pi, gchan, &nbuf); + ch->state = UP; + + /* Setup the Time Slot Map */ + musycc_update_timeslots (pi); + + /* ch->tx_limit = nts; */ + ch->s.tx_pending = 0; + + /* Set Channel Configuration Descriptors */ + { + u_int32_t ccd; + + ccd = musycc_chan_proto (ch->p.chan_mode) << MUSYCC_CCD_PROTO_SHIFT; + if ((ch->p.chan_mode == CFG_CH_PROTO_ISLP_MODE) || + (ch->p.chan_mode == CFG_CH_PROTO_TRANS)) + { + ccd |= MUSYCC_CCD_FCS_XFER; /* Non FSC Mode */ + } + ccd |= 2 << MUSYCC_CCD_MAX_LENGTH; /* Select second MTU */ + ccd |= ch->p.intr_mask; + ccd |= addr << MUSYCC_CCD_BUFFER_LOC; + if (ch->p.chan_mode == CFG_CH_PROTO_TRANS) + ccd |= (nbuf) << MUSYCC_CCD_BUFFER_LENGTH; + else + ccd |= (nbuf - 1) << MUSYCC_CCD_BUFFER_LENGTH; + + if (ch->p.data_inv & CFG_CH_DINV_TX) + ccd |= MUSYCC_CCD_INVERT_DATA; /* Invert data */ + pi->regram->tcct[gchan] = cpu_to_le32 (ccd); + + if (ch->p.data_inv & CFG_CH_DINV_RX) + ccd |= MUSYCC_CCD_INVERT_DATA; /* Invert data */ + else + ccd &= ~MUSYCC_CCD_INVERT_DATA; /* take away data inversion */ + pi->regram->rcct[gchan] = cpu_to_le32 (ccd); + FLUSH_MEM_WRITE (); + } + + /* Reread the Channel Configuration Descriptor for this channel */ + musycc_serv_req (pi, SR_CHANNEL_CONFIG | SR_RX_DIRECTION | gchan); + musycc_serv_req (pi, SR_CHANNEL_CONFIG | SR_TX_DIRECTION | gchan); + + /* + * Figure out how many buffers we want. If the customer has changed from + * the defaults, then use the changed values. Otherwise, use Transparent + * mode's specific minimum default settings. + */ + if (ch->p.chan_mode == CFG_CH_PROTO_TRANS) + { + if (max_rxdesc_used == max_rxdesc_default) /* use default setting */ + max_rxdesc_used = MUSYCC_RXDESC_TRANS; + if (max_txdesc_used == max_txdesc_default) /* use default setting */ + max_txdesc_used = MUSYCC_TXDESC_TRANS; + } + /* + * Increase counts when hyperchanneling, since this implies an increase + * in throughput per channel + */ + rxnum = max_rxdesc_used + (nts / 4); + txnum = max_txdesc_used + (nts / 4); + +#if 0 + /* DEBUG INFO */ + if (log_level >= LOG_MONITOR) + printk ("%s: mode %x rxnum %d (rxused %d def %d) txnum %d (txused %d def %d)\n", + ci->devname, ch->p.chan_mode, + rxnum, max_rxdesc_used, max_rxdesc_default, + txnum, max_txdesc_used, max_txdesc_default); +#endif + + ch->rxd_num = rxnum; + ch->txd_num = txnum; + ch->rxix_irq_srv = 0; + + ch->mdr = OS_kmalloc (sizeof (struct mdesc) * rxnum); + ch->mdt = OS_kmalloc (sizeof (struct mdesc) * txnum); + if (ch->p.chan_mode == CFG_CH_PROTO_TRANS) + tmp = __constant_cpu_to_le32 (max_mru | EOBIRQ_ENABLE); + else + tmp = __constant_cpu_to_le32 (max_mru); + + for (i = 0, md = ch->mdr; i < rxnum; i++, md++) + { + if (i == (rxnum - 1)) + { + md->snext = &ch->mdr[0];/* wrapness */ + } else + { + md->snext = &ch->mdr[i + 1]; + } + md->next = cpu_to_le32 (OS_vtophys (md->snext)); + + if (!(m = OS_mem_token_alloc (max_mru))) + { + if (log_level >= LOG_MONITOR) + printk ("%s: c4_chan_up[%d] - token alloc failure, size = %d.\n", ci->devname, channum, max_mru); + goto errfree; + } + md->mem_token = m; + md->data = cpu_to_le32 (OS_vtophys (OS_mem_token_data (m))); + md->status = tmp | MUSYCC_RX_OWNED; /* MUSYCC owns RX descriptor ** + * CODING NOTE: + * MUSYCC_RX_OWNED = 0 so no + * need to byteSwap */ + } + + for (i = 0, md = ch->mdt; i < txnum; i++, md++) + { + md->status = HOST_TX_OWNED; /* Host owns TX descriptor ** CODING + * NOTE: HOST_TX_OWNED = 0 so no need to + * byteSwap */ + md->mem_token = 0; + md->data = 0; + if (i == (txnum - 1)) + { + md->snext = &ch->mdt[0];/* wrapness */ + } else + { + md->snext = &ch->mdt[i + 1]; + } + md->next = cpu_to_le32 (OS_vtophys (md->snext)); + } + ch->txd_irq_srv = ch->txd_usr_add = &ch->mdt[0]; + ch->txd_free = txnum; + ch->tx_full = 0; + ch->txd_required = 0; + + /* Configure it into the chip */ + tmp = cpu_to_le32 (OS_vtophys (&ch->mdt[0])); + pi->regram->thp[gchan] = tmp; + pi->regram->tmp[gchan] = tmp; + + tmp = cpu_to_le32 (OS_vtophys (&ch->mdr[0])); + pi->regram->rhp[gchan] = tmp; + pi->regram->rmp[gchan] = tmp; + + /* Activate the Channel */ + FLUSH_MEM_WRITE (); + if (ch->p.status & RX_ENABLED) + { +#ifdef RLD_TRANS_DEBUG + printk ("++ c4_chan_up() CHAN RX ACTIVATE: chan %d\n", ch->channum); +#endif + ch->ch_start_rx = 0; /* we are restarting RX... */ + musycc_serv_req (pi, SR_CHANNEL_ACTIVATE | SR_RX_DIRECTION | gchan); + } + if (ch->p.status & TX_ENABLED) + { +#ifdef RLD_TRANS_DEBUG + printk ("++ c4_chan_up() CHAN TX ACTIVATE: chan %d \n", ch->channum); +#endif + ch->ch_start_tx = CH_START_TX_1ST; /* we are delaying start + * until receipt from user of + * first packet to transmit. */ + } + ch->status = ch->p.status; + pi->openchans++; + return 0; + +errfree: + while (i > 0) + { + /* Don't leak all the previously allocated mbufs in this loop */ + i--; + OS_mem_token_free (ch->mdr[i].mem_token); + } + OS_kfree (ch->mdt); + ch->mdt = 0; + ch->txd_num = 0; + OS_kfree (ch->mdr); + ch->mdr = 0; + ch->rxd_num = 0; + ch->state = DOWN; + return ENOBUFS; +} + +/* stop the hardware from servicing & interrupting */ + +void +c4_stopwd (ci_t * ci) +{ + OS_stop_watchdog (&ci->wd); + SD_SEM_TAKE (&ci->sem_wdbusy, "_stop_"); /* ensure WD not running */ + SD_SEM_GIVE (&ci->sem_wdbusy); +} + + +void +sbecom_get_brdinfo (ci_t * ci, struct sbe_brd_info * bip, u_int8_t *bsn) +{ + char *np; + u_int32_t sn = 0; + int i; + + bip->brdno = ci->brdno; /* our board number */ + bip->brd_id = ci->brd_id; + bip->brd_hdw_id = ci->hdw_bid; + bip->brd_chan_cnt = MUSYCC_NCHANS * ci->max_port; /* number of channels + * being used */ + bip->brd_port_cnt = ci->max_port; /* number of ports being used */ + bip->brd_pci_speed = BINFO_PCI_SPEED_unk; /* PCI speed not yet + * determinable */ + + if (ci->first_if) + { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + np = (char *) hdlc_to_name (ci->first_if); +#else + { + struct net_device *dev; + + dev = (struct net_device *) ci->first_if; + np = (char *) dev->name; + } +#endif + strncpy (bip->first_iname, np, CHNM_STRLEN - 1); + } else + strcpy (bip->first_iname, ""); + if (ci->last_if) + { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + np = (char *) hdlc_to_name (ci->last_if); +#else + { + struct net_device *dev; + + dev = (struct net_device *) ci->last_if; + np = (char *) dev->name; + } +#endif + strncpy (bip->last_iname, np, CHNM_STRLEN - 1); + } else + strcpy (bip->last_iname, ""); + + if (bsn) + { + for (i = 0; i < 3; i++) + { + bip->brd_mac_addr[i] = *bsn++; + } + for (; i < 6; i++) + { + bip->brd_mac_addr[i] = *bsn; + sn = (sn << 8) | *bsn++; + } + } else + { + for (i = 0; i < 6; i++) + bip->brd_mac_addr[i] = 0; + } + bip->brd_sn = sn; +} + + +status_t +c4_get_iidinfo (ci_t * ci, struct sbe_iid_info * iip) +{ + struct net_device *dev; + char *np; + + if (!(dev = getuserbychan (iip->channum))) + return ENOENT; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + np = (char *) hdlc_to_name (dev_to_hdlc (dev)); +#else + np = dev->name; +#endif + strncpy (iip->iname, np, CHNM_STRLEN - 1); + return 0; +} + + +#ifdef CONFIG_SBE_PMCC4_NCOMM +void (*nciInterrupt[MAX_BOARDS][4]) (void); +extern void wanpmcC4T1E1_hookInterrupt (int cardID, int deviceID, void *handler); + +void +wanpmcC4T1E1_hookInterrupt (int cardID, int deviceID, void *handler) +{ + if (cardID < MAX_BOARDS) /* sanity check */ + nciInterrupt[cardID][deviceID] = handler; +} + +irqreturn_t +c4_ebus_intr_th_handler (void *devp) +{ + ci_t *ci = (ci_t *) devp; + volatile u_int32_t ists; + int handled = 0; + int brdno; + + /* which COMET caused the interrupt */ + brdno = ci->brdno; + ists = pci_read_32 ((u_int32_t *) &ci->cpldbase->intr); + if (ists & PMCC4_CPLD_INTR_CMT_1) + { + handled = 0x1; + if (nciInterrupt[brdno][0] != NULL) + (*nciInterrupt[brdno][0]) (); + } + if (ists & PMCC4_CPLD_INTR_CMT_2) + { + handled |= 0x2; + if (nciInterrupt[brdno][1] != NULL) + (*nciInterrupt[brdno][1]) (); + } + if (ists & PMCC4_CPLD_INTR_CMT_3) + { + handled |= 0x4; + if (nciInterrupt[brdno][2] != NULL) + (*nciInterrupt[brdno][2]) (); + } + if (ists & PMCC4_CPLD_INTR_CMT_4) + { + handled |= 0x8; + if (nciInterrupt[brdno][3] != NULL) + (*nciInterrupt[brdno][3]) (); + } +#if 0 + /*** Test code just de-implements the asserted interrupt. Alternate + vendor will supply COMET interrupt handling code herein or such. + ***/ + pci_write_32 ((u_int32_t *) &ci->reg->glcd, GCD_MAGIC | MUSYCC_GCD_INTB_DISABLE); +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,20) + return; +#else + return IRQ_RETVAL (handled); +#endif +} + + +unsigned long +wanpmcC4T1E1_getBaseAddress (int cardID, int deviceID) +{ + ci_t *ci; + unsigned long base = 0; + + ci = c4_list; + while (ci) + { + if (ci->brdno == cardID) /* found valid device */ + { + if (deviceID < ci->max_port) /* comet is supported */ + base = ((unsigned long) ci->port[deviceID].cometbase); + break; + } + ci = ci->next; /* next board, if any */ + } + return (base); +} + +#endif /*** CONFIG_SBE_PMCC4_NCOMM ***/ + + +/*** End-of-File ***/ diff --git a/drivers/staging/cxt1e1/pmcc4_ioctls.h b/drivers/staging/cxt1e1/pmcc4_ioctls.h new file mode 100644 index 000000000000..6b8d65673c78 --- /dev/null +++ b/drivers/staging/cxt1e1/pmcc4_ioctls.h @@ -0,0 +1,81 @@ +/* RCSid: $Header: /home/rickd/projects/pmcc4/include/pmcc4_ioctls.h,v 2.0 2005/09/28 00:10:09 rickd PMCC4_3_1B $ + */ + +#ifndef _INC_PMCC4_IOCTLS_H_ +#define _INC_PMCC4_IOCTLS_H_ + +/*----------------------------------------------------------------------------- + * pmcc4_ioctls.h - + * + * Copyright (C) 2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For further information, contact via email: support@sbei.com + * SBE, Inc. San Ramon, California U.S.A. + *----------------------------------------------------------------------------- + * RCS info: + * RCS revision: $Revision: 2.0 $ + * Last changed on $Date: 2005/09/28 00:10:09 $ + * Changed by $Author: rickd $ + *----------------------------------------------------------------------------- + * $Log: pmcc4_ioctls.h,v $ + * Revision 2.0 2005/09/28 00:10:09 rickd + * Add GNU license info. Switch Ioctls to sbe_ioc.h usage. + * + * Revision 1.2 2005/04/28 23:43:03 rickd + * Add RCS tracking heading. + * + *----------------------------------------------------------------------------- + */ + +#include "sbew_ioc.h" + +enum +{ + // C4_GET_PORT = 0, + // C4_SET_PORT, + // C4_GET_CHAN, + // C4_SET_CHAN, + C4_DEL_CHAN = 0, + // C4_CREATE_CHAN, + // C4_GET_CHAN_STATS, + // C4_RESET, + // C4_DEBUG, + C4_RESET_STATS, + C4_LOOP_PORT, + C4_RW_FRMR, + C4_RW_MSYC, + C4_RW_PLD +}; + +#define C4_GET_PORT SBE_IOC_PORT_GET +#define C4_SET_PORT SBE_IOC_PORT_SET +#define C4_GET_CHAN SBE_IOC_CHAN_GET +#define C4_SET_CHAN SBE_IOC_CHAN_SET +// #define C4_DEL_CHAN XXX +#define C4_CREATE_CHAN SBE_IOC_CHAN_NEW +#define C4_GET_CHAN_STATS SBE_IOC_CHAN_GET_STAT +#define C4_RESET SBE_IOC_RESET_DEV +#define C4_DEBUG SBE_IOC_LOGLEVEL +// #define C4_RESET_STATS XXX +// #define C4_LOOP_PORT XXX +// #define C4_RW_FRMR XXX +// #define C4_RW_MSYC XXX +// #define C4_RW_PLD XXX + +struct c4_chan_stats_wrap +{ + int channum; + struct sbecom_chan_stats stats; +}; + +#endif /* _INC_PMCC4_IOCTLS_H_ */ diff --git a/drivers/staging/cxt1e1/pmcc4_private.h b/drivers/staging/cxt1e1/pmcc4_private.h new file mode 100644 index 000000000000..0ae18c444a75 --- /dev/null +++ b/drivers/staging/cxt1e1/pmcc4_private.h @@ -0,0 +1,295 @@ +#ifndef _INC_PMCC4_PRIVATE_H_ +#define _INC_PMCC4_PRIVATE_H_ + +/*----------------------------------------------------------------------------- + * pmcc4_private.h - + * + * Copyright (C) 2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#include +#include +#include +#include /* support for tasklets */ +#include /* support for timer */ +#include +#include + +#include "libsbew.h" +#include "pmcc4_defs.h" +#include "pmcc4_cpld.h" +#include "musycc.h" +#include "sbe_promformat.h" +#include "comet.h" + + +/* driver state */ +#define SBE_DRVR_INIT 0x0 +#define SBE_DRVR_AVAILABLE 0x69734F4E +#define SBE_DRVR_DOWN 0x1 + +/****************************************************************************** + * MUSYCC Message Descriptor - coupled to hardware implementation, the first + * three u_int32 must not be reordered. + */ + +struct mdesc +{ + volatile u_int32_t status; /* Buffer Descriptor */ + u_int32_t data; /* Data Pointer */ + u_int32_t next; /* MUSYCC view of Next Pointer */ + void *mem_token; /* Data */ + struct mdesc *snext; +}; + + +/************************************************************************* + * Private driver data structures, internal use only. + */ + +struct c4_chan_info +{ + int gchan; /* channel number within group/port 0-31 */ + int channum; /* absolute channel number 0-128 */ + u_int8_t status; +#define TX_RECOVERY_MASK 0x0f +#define TX_ONR_RECOVERY 0x01 +#define TX_BUFF_RECOVERY 0x02 +#define RX_RECOVERY_MASK 0xf0 +#define RX_ONR_RECOVERY 0x10 + + unsigned char ch_start_rx; +#define CH_START_RX_NOW 1 +#define CH_START_RX_ONR 2 +#define CH_START_RX_BUF 3 + + unsigned char ch_start_tx; +#define CH_START_TX_1ST 1 +#define CH_START_TX_ONR 2 +#define CH_START_TX_BUF 3 + + char tx_full; /* boolean */ + short txd_free; /* count of TX Desc available */ + short txd_required; /* count of TX Desc needed by mesg */ + unsigned short rxd_num; /* must support range up to 2000 */ + unsigned short txd_num; /* must support range up to 1000 */ + int rxix_irq_srv; + + enum + { + UNASSIGNED, /* AVAILABLE, NOTINUSE */ + DOWN, /* ASSIGNED, NOTINUSE */ + UP /* ASSIGNED and INUSE */ + } state; + + struct c4_port_info *up; + void *user; + + struct work_struct ch_work; + struct mdesc *mdt; + struct mdesc *mdr; + struct mdesc *txd_irq_srv; + struct mdesc *txd_usr_add; + +#if 0 + /* + * FUTURE CODE MIGHT SEPARATE TIMESLOT MAP SETUPS INTO SINGLE IOCTL and + * REMOVE MAPS FROM CHANNEL PARAMETER STRUCTURE + */ + /* + * each byte in bitmask below represents one timeslot (bitmask[0] is for + * timeslot 0 and so on), each bit in the byte selects timeslot bits for + * this channel (0xff - whole timeslot, 0x7f - 56kbps mode) + */ + + u_int8_t ts_bitmask[32]; +#endif + spinlock_t ch_rxlock; + spinlock_t ch_txlock; + atomic_t tx_pending; + + struct sbecom_chan_stats s; + struct sbecom_chan_param p; +}; +typedef struct c4_chan_info mch_t; + +struct c4_port_info +{ + + struct musycc_globalr *reg; + struct musycc_groupr *regram; + void *regram_saved; /* Original malloc value may have non-2KB + * boundary. Need to save for use when + * freeing. */ + comet_t *cometbase; + struct sbe_card_info *up; + + /* + * The workqueue is used for TX restart of ONR'd channels when in + * Transparent mode. + */ + + struct workqueue_struct *wq_port; /* chan restart work queue */ + struct semaphore sr_sem_busy; /* service request exclusion + * semaphore */ + struct semaphore sr_sem_wait; /* service request handshake + * semaphore */ + u_int32_t sr_last; + short openchans; + char portnum; + char group_is_set; /* GROUP_INIT command issued to MUSYCC, + * otherwise SET_CHAN Ioctl fails */ + + mch_t *chan[MUSYCC_NCHANS]; + struct sbecom_port_param p; + + /* + * The MUSYCC timeslot mappings are maintained within the driver and are + * modified and reloaded as each of a group's channels are configured. + */ + u_int8_t tsm[32]; /* tsm (time slot map) */ + int fifomap[32]; +}; +typedef struct c4_port_info mpi_t; + + +#define COMET_OFFSET(x) (0x80000+(x)*0x10000) +#define EEPROM_OFFSET 0xC0000 +#define ISPLD_OFFSET 0xD0000 + +/* iSPLD control chip registers */ +#define ISPLD_MCSR 0x0 +#define ISPLD_MCLK 0x1 +#define ISPLD_LEDS 0x2 +#define ISPLD_INTR 0x3 +#define ISPLD_MAX 0x3 + +struct sbe_card_info +{ + struct musycc_globalr *reg; + struct musycc_groupr *regram; + u_int32_t *iqd_p; /* pointer to dword aligned interrupt queue + * descriptors */ + void *iqd_p_saved; /* Original malloc value may have non-dword + * aligned boundary. Need to save for use + * when freeing. */ + unsigned int iqp_headx, iqp_tailx; + + struct semaphore sem_wdbusy;/* watchdog exclusion semaphore */ + struct watchdog wd; /* statically allocated watchdog structure */ + atomic_t bh_pending; /* bh queued, but not yet running */ + u_int32_t brd_id; /* unique PCI ID */ + u_int16_t hdw_bid; /* on/board hardware ID */ + unsigned short wdcount; + unsigned char max_port; + unsigned char brdno; /* our board number */ + unsigned char wd_notify; +#define WD_NOTIFY_1TX 1 +#define WD_NOTIFY_BUF 2 +#define WD_NOTIFY_ONR 4 + enum /* state as regards interrupt processing */ + { + C_INIT, /* of-board-address not configured or are in + * process of being removed, don't access + * hardware */ + C_IDLE, /* off-board-addresses are configured, but + * don't service interrupts, just clear them + * from hardware */ + C_RUNNING /* life is good, service away */ + } state; + + struct sbe_card_info *next; + u_int32_t *eeprombase; /* mapped address of board's EEPROM */ + c4cpld_t *cpldbase; /* mapped address of board's CPLD hardware */ + char *release; /* SBE ID string w/in sbeRelease.c */ + void *hdw_info; +#ifdef CONFIG_PROC_FS + struct proc_dir_entry *dir_dev; +#endif + + /* saved off interface assignments which bound a board */ + hdlc_device *first_if; + hdlc_device *last_if; + short first_channum, last_channum; + + struct intlog + { + u_int32_t this_status_new; + u_int32_t last_status_new; + u_int32_t drvr_intr_thcount; + u_int32_t drvr_intr_bhcount; + u_int32_t drvr_int_failure; + } intlog; + + mpi_t port[MUSYCC_NPORTS]; + char devname[SBE_IFACETMPL_SIZE + 1]; + atomic_t tx_pending; + u_int32_t alarmed[4]; /* dpm211 */ + +#if defined(SBE_ISR_TASKLET) + struct tasklet_struct ci_musycc_isr_tasklet; +#elif defined(SBE_ISR_IMMEDIATE) + struct tq_struct ci_musycc_isr_tq; +#endif +}; +typedef struct sbe_card_info ci_t; + +struct s_hdw_info +{ + u_int8_t pci_busno; + u_int8_t pci_slot; + u_int8_t pci_pin[2]; + u_int8_t revid[2]; + u_int8_t mfg_info_sts; +#define EEPROM_OK 0x00 +#define EEPROM_CRCERR 0x01 + char promfmt; /* prom type, from sbe_promformat.h */ + + char devname[SBE_IFACETMPL_SIZE]; + struct pci_bus *bus; + struct net_device *ndev; + struct pci_dev *pdev[2]; + + unsigned long addr[2]; + unsigned long addr_mapped[2]; + unsigned long len[2]; + + union + { + char data[128]; + FLD_TYPE1 pft1; /* prom field, type #1 */ + FLD_TYPE2 pft2; /* prom field, type #2 */ + } mfg_info; +}; +typedef struct s_hdw_info hdw_info_t; + +/*****************************************************************/ + +struct c4_priv +{ + int channum; + struct sbe_card_info *ci; +}; + + +/*****************************************************************/ + +extern ci_t *c4_list; + +mch_t *c4_find_chan (int); +int c4_set_chan (int channum, struct sbecom_chan_param *); +int c4_get_chan (int channum, struct sbecom_chan_param *); +int c4_get_chan_stats (int channum, struct sbecom_chan_stats *); + +#endif /* _INC_PMCC4_PRIVATE_H_ */ diff --git a/drivers/staging/cxt1e1/pmcc4_sysdep.h b/drivers/staging/cxt1e1/pmcc4_sysdep.h new file mode 100644 index 000000000000..697f1943670f --- /dev/null +++ b/drivers/staging/cxt1e1/pmcc4_sysdep.h @@ -0,0 +1,62 @@ +#ifndef _INC_PMCC4_SYSDEP_H_ +#define _INC_PMCC4_SYSDEP_H_ + +/*----------------------------------------------------------------------------- + * pmcc4_sysdep.h - + * + * Copyright (C) 2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* reduce multiple autoconf entries to a single definition */ + +#ifdef CONFIG_SBE_PMCC4_HDLC_V7_MODULE +#undef CONFIG_SBE_PMCC4_HDLC_V7 +#define CONFIG_SBE_PMCC4_HDLC_V7 1 +#endif + +#ifdef CONFIG_SBE_PMCC4_NCOMM_MODULE +#undef CONFIG_SBE_PMCC4_NCOMM +#define CONFIG_SBE_PMCC4_NCOMM 1 +#endif + + +/* FLUSH MACROS - if using ioremap_nocache(), then these can be NOOPS, + * otherwise a memory barrier needs to be inserted. + */ + +#define FLUSH_PCI_READ() rmb() +#define FLUSH_PCI_WRITE() wmb() +#define FLUSH_MEM_READ() rmb() +#define FLUSH_MEM_WRITE() wmb() + + +/* + * System dependent callbacks routines, not inlined... + * For inlined system dependent routines, see include/sbecom_inlinux_linux.h + */ + +/* + * passes received memory token back to the system, is parameter from + * sd_new_chan() used to create the channel which the data arrived on + */ + +void sd_recv_consume(void *token, size_t len, void *user); + +void sd_disable_xmit (void *user); +void sd_enable_xmit (void *user); +int sd_line_is_ok (void *user); +void sd_line_is_up (void *user); +void sd_line_is_down (void *user); +int sd_queue_stopped (void *user); + +#endif /*** _INC_PMCC4_SYSDEP_H_ ***/ diff --git a/drivers/staging/cxt1e1/sbe_bid.h b/drivers/staging/cxt1e1/sbe_bid.h new file mode 100644 index 000000000000..1f49b4061fb7 --- /dev/null +++ b/drivers/staging/cxt1e1/sbe_bid.h @@ -0,0 +1,61 @@ +/* + * $Id: sbe_bid.h,v 1.0 2005/09/28 00:10:09 rickd PMCC4_3_1B $ + */ + +#ifndef _INC_SBEBID_H_ +#define _INC_SBEBID_H_ + +/*----------------------------------------------------------------------------- + * sbe_bid.h - + * + * Copyright (C) 2004-2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For further information, contact via email: support@sbei.com + * SBE, Inc. San Ramon, California U.S.A. + * + *----------------------------------------------------------------------------- + * RCS info: + * RCS revision: $Revision: 1.0 $ + * Last changed on $Date: 2005/09/28 00:10:09 $ + * Changed by $Author: rickd $ + *----------------------------------------------------------------------------- + * $Log: sbe_bid.h,v $ + * Revision 1.0 2005/09/28 00:10:09 rickd + * Initial revision + * + *----------------------------------------------------------------------------- + */ + +#define SBE_BID_REG 0x00000000 /* Board ID Register */ + +#define SBE_BID_256T3_E1 0x46 /* SBE wanPTMC-256T3 (E1 Version) */ +#define SBE_BID_256T3_T1 0x42 /* SBE wanPTMC-256T3 (T1 Version) */ +#define SBE_BID_2T3E3 0x43 /* SBE wanPMC-2T3E3 */ +#define SBE_BID_C1T3 0x45 /* SBE wanPMC-C1T3 */ +#define SBE_BID_C24TE1 0x47 /* SBE wanPTMC-C24TE1 */ +#define SBE_BID_C24TE1_RTM_24 0x48 /* C24TE1 RTM (24 Port) */ +#define SBE_BID_C24TE1_RTM_12 0x49 /* C24TE1 RTM (12 Port) */ +#define SBE_BID_C24TE1_RTM_12DSU 0x4A /* C24TE1 RTM (12 Port/DSU) */ +#define SBE_BID_C24TE1_RTM_T3 0x4B /* C24TE1 RTM (T3) */ +#define SBE_BID_C4T1E1 0x41 /* SBE wanPTMC-C4T1E1 */ +#define SBE_BID_HC4T1E1 0x44 /* SBE wanADAPT-HC4T1E1 */ + +/* bogus temporary usage values */ +#define SBE_BID_PMC_C4T1E1 0xC4 /* SBE wanPMC-C4T1E1 (4 Port) */ +#define SBE_BID_PMC_C2T1E1 0xC2 /* SBE wanPMC-C2T1E1 (2 Port) */ +#define SBE_BID_PMC_C1T1E1 0xC1 /* SBE wanPMC-C1T1E1 (1 Port) */ +#define SBE_BID_PCI_C4T1E1 0x04 /* SBE wanPCI-C4T1E1 (4 Port) */ +#define SBE_BID_PCI_C2T1E1 0x02 /* SBE wanPCI-C2T1E1 (2 Port) */ +#define SBE_BID_PCI_C1T1E1 0x01 /* SBE wanPCI-C1T1E1 (1 Port) */ + +#endif /*** _INC_SBEBID_H_ ***/ diff --git a/drivers/staging/cxt1e1/sbe_promformat.h b/drivers/staging/cxt1e1/sbe_promformat.h new file mode 100644 index 000000000000..746f81b15c73 --- /dev/null +++ b/drivers/staging/cxt1e1/sbe_promformat.h @@ -0,0 +1,157 @@ +/* + * $Id: sbe_promformat.h,v 2.2 2005/09/28 00:10:09 rickd PMCC4_3_1B $ + */ + +#ifndef _INC_SBE_PROMFORMAT_H_ +#define _INC_SBE_PROMFORMAT_H_ + +/*----------------------------------------------------------------------------- + * sbe_promformat.h - Contents of seeprom used by dvt and manufacturing tests + * + * Copyright (C) 2002-2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For further information, contact via email: support@sbei.com + * SBE, Inc. San Ramon, California U.S.A. + * + *----------------------------------------------------------------------------- + * RCS info: + * RCS revision: $Revision: 2.2 $ + * Last changed on $Date: 2005/09/28 00:10:09 $ + * Changed by $Author: rickd $ + *----------------------------------------------------------------------------- + * $Log: sbe_promformat.h,v $ + * Revision 2.2 2005/09/28 00:10:09 rickd + * Add EEPROM sample from C4T1E1 board. + * + * Revision 2.1 2005/05/04 17:18:24 rickd + * Initial CI. + * + *----------------------------------------------------------------------------- + */ + + +/*** + * PMCC4 SAMPLE EEPROM IMAGE + * + * eeprom[00]: 01 11 76 07 01 00 a0 d6 + * eeprom[08]: 22 34 56 3e 5b c1 1c 3e + * eeprom[16]: 5b e1 b6 00 00 00 01 00 + * eeprom[24]: 00 08 46 d3 7b 5e a8 fb + * eeprom[32]: f7 ef df bf 7f 55 00 01 + * eeprom[40]: 02 04 08 10 20 40 80 ff + * eeprom[48]: fe fd fb f7 ef df bf 7f + * + ***/ + + +/*------------------------------------------------------------------------ + * Type 1 Format + * byte: + * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 + * ------------------------------------------------------------------------- + * 01 11 76 SS SS 00 0A D6 + * SBE SUB SERIAL # (BCD) (time_t) (time_t) + * ID VENDOR (format) (format) + * + * 19 20 21 22 23 24 25 26 + * Heat Run Heat Run + * Iterations Errors + *------------------------------------------------------------------------ + * + * + * + * Type 2 Format - Added length, CRC in fixed position + * byte: + * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + * ------------------------------------------------------------------------- + * 02 00 1A CC CC CC CC 11 76 07 03 00 0A D6 + * Payload SBE Crc32 SUB System System SERIAL/MAC + * Length VENDOR ID ID + * + * 17 18 19 20 21 22 23 24 25 26 27 28 29 39 31 32 + * -------------------------------------------------------------------------- + * Heat Run Heat Run + * (time_t) (time_t) Iterations Errors + * + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + + +#define STRUCT_OFFSET(type, symbol) ((long)&(((type *)0)->symbol)) + +/*------------------------------------------------------------------------ + * Historically different Prom format types. + * + * For diagnostic and failure purposes, do not create a type 0x00 or a + * type 0xff + *------------------------------------------------------------------------ + */ +#define PROM_FORMAT_Unk (-1) +#define PROM_FORMAT_TYPE1 1 +#define PROM_FORMAT_TYPE2 2 + + +/****** bit fields for a type 1 formatted seeprom **************************/ + typedef struct + { + char type; /* 0x00 */ + char Id[2]; /* 0x01-0x02 */ + char SubId[2]; /* 0x03-0x04 */ + char Serial[6]; /* 0x05-0x0a */ + char CreateTime[4]; /* 0x0b-0x0e */ + char HeatRunTime[4]; /* 0x0f-0x12 */ + char HeatRunIterations[4]; /* 0x13-0x16 */ + char HeatRunErrors[4]; /* 0x17-0x1a */ + char Crc32[4]; /* 0x1b-0x1e */ + } FLD_TYPE1; + + +/****** bit fields for a type 2 formatted seeprom **************************/ + typedef struct + { + char type; /* 0x00 */ + char length[2]; /* 0x01-0x02 */ + char Crc32[4]; /* 0x03-0x06 */ + char Id[2]; /* 0x07-0x08 */ + char SubId[2]; /* 0x09-0x0a */ + char Serial[6]; /* 0x0b-0x10 */ + char CreateTime[4]; /* 0x11-0x14 */ + char HeatRunTime[4]; /* 0x15-0x18 */ + char HeatRunIterations[4]; /* 0x19-0x1c */ + char HeatRunErrors[4]; /* 0x1d-0x20 */ + } FLD_TYPE2; + + + +/***** this union allows us to access the seeprom as an array of bytes ***/ +/***** or as individual fields ***/ + +#define SBE_EEPROM_SIZE 128 +#define SBE_MFG_INFO_SIZE sizeof(FLD_TYPE2) + + typedef union + { + char bytes[128]; + FLD_TYPE1 fldType1; + FLD_TYPE2 fldType2; + } PROMFORMAT; + +#ifdef __cplusplus +} +#endif + +#endif /*** _INC_SBE_PROMFORMAT_H_ ***/ diff --git a/drivers/staging/cxt1e1/sbecom_inline_linux.h b/drivers/staging/cxt1e1/sbecom_inline_linux.h new file mode 100644 index 000000000000..2ab1eb12ed38 --- /dev/null +++ b/drivers/staging/cxt1e1/sbecom_inline_linux.h @@ -0,0 +1,310 @@ +/* + * $Id: sbecom_inline_linux.h,v 1.2 2007/08/15 22:51:35 rickd PMCC4_3_1B $ + */ + +#ifndef _INC_SBECOM_INLNX_H_ +#define _INC_SBECOM_INLNX_H_ + +/*----------------------------------------------------------------------------- + * sbecom_inline_linux.h - SBE common Linux inlined routines + * + * Copyright (C) 2007 One Stop Systems, Inc. + * Copyright (C) 2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For further information, contact via email: support@onestopsystems.com + * One Stop Systems, Inc. Escondido, California U.S.A. + *----------------------------------------------------------------------------- + * RCS info: + * RCS revision: $Revision: 1.2 $ + * Last changed on $Date: 2007/08/15 22:51:35 $ + * Changed by $Author: rickd $ + *----------------------------------------------------------------------------- + * $Log: sbecom_inline_linux.h,v $ + * Revision 1.2 2007/08/15 22:51:35 rickd + * Remove duplicate version.h entry. + * + * Revision 1.1 2007/08/15 22:50:29 rickd + * Update linux/config for 2.6.18 and later. + * + * Revision 1.0 2005/09/28 00:10:09 rickd + * Initial revision + * + *----------------------------------------------------------------------------- + */ + + +#if defined (__FreeBSD__) || defined (__NetBSD__) +#include +#else +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) +#include +#endif +#if defined(CONFIG_SMP) && ! defined(__SMP__) +#define __SMP__ +#endif +#if defined(CONFIG_MODVERSIONS) && defined(MODULE) && ! defined(MODVERSIONS) +#define MODVERSIONS +#endif + +#ifdef MODULE +#ifdef MODVERSIONS +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#include +#else +#include +#endif +#endif +#include +#endif +#endif + +#include /* resolves kmalloc references */ +#include /* resolves skb references */ +#include /* resolves dev_kree_skb_any */ +#include /* resolves cpu_to_le32 */ + +#if 0 + +/*** PORT POINT WARNING + *** + *** Under Linux 2.6 it has been found that compiler is re-ordering + *** in-lined pci_write_32() functions to the detrement of correct + *** hardware setup. Therefore, inlining of PCI accesses has been + *** de-implemented, and subroutine calls have been implemented. + ***/ + +static inline u_int32_t +pci_read_32 (u_int32_t *p) +{ +#ifdef FLOW_DEBUG + u_int32_t v; + + FLUSH_PCI_READ (); + v = le32_to_cpu (*p); + if (log_level >= LOG_DEBUG) + printk ("pci_read : %x = %x\n", (u_int32_t) p, v); + return v; +#else + FLUSH_PCI_READ (); /* */ + return le32_to_cpu (*p); +#endif +} + +static inline void +pci_write_32 (u_int32_t *p, u_int32_t v) +{ +#ifdef FLOW_DEBUG + if (log_level >= LOG_DEBUG) + printk ("pci_write: %x = %x\n", (u_int32_t) p, v); +#endif + *p = cpu_to_le32 (v); + FLUSH_PCI_WRITE (); /* This routine is called from routines + * which do multiple register writes + * which themselves need flushing between + * writes in order to guarantee write + * ordering. It is less code-cumbersome + * to flush here-in then to investigate + * and code the many other register + * writing routines. */ +} +#else +/* forward reference */ +u_int32_t pci_read_32 (u_int32_t *p); +void pci_write_32 (u_int32_t *p, u_int32_t v); + +#endif + + +/* + * system dependent callbacks + */ + +/**********/ +/* malloc */ +/**********/ + +static inline void * +OS_kmalloc (size_t size) +{ + char *ptr = kmalloc (size, GFP_KERNEL | GFP_DMA); + + if (ptr) + memset (ptr, 0, size); + return ptr; +} + +static inline void +OS_kfree (void *x) +{ + kfree (x); +} + + +/****************/ +/* memory token */ +/****************/ + +static inline void * +OS_mem_token_alloc (size_t size) +{ + struct sk_buff *skb; + + skb = dev_alloc_skb (size); + if (!skb) + { + //printk (KERN_WARNING "no mem in OS_mem_token_alloc !"); + return 0; + } + return skb; +} + + +static inline void +OS_mem_token_free (void *token) +{ + dev_kfree_skb_any (token); +} + + +static inline void +OS_mem_token_free_irq (void *token) +{ + dev_kfree_skb_irq (token); +} + + +static inline void * +OS_mem_token_data (void *token) +{ + return ((struct sk_buff *) token)->data; +} + + +static inline void * +OS_mem_token_next (void *token) +{ + return 0; +} + + +static inline int +OS_mem_token_len (void *token) +{ + return ((struct sk_buff *) token)->len; +} + + +static inline int +OS_mem_token_tlen (void *token) +{ + return ((struct sk_buff *) token)->len; +} + + +/***************************************/ +/* virtual to physical addr conversion */ +/***************************************/ + +static inline u_long +OS_phystov (void *addr) +{ + return (u_long) __va (addr); +} + + +static inline u_long +OS_vtophys (void *addr) +{ + return __pa (addr); +} + + +/**********/ +/* semops */ +/**********/ + +void OS_sem_init (void *, int); + + +static inline void +OS_sem_free (void *sem) +{ + /* + * NOOP - since semaphores structures predeclared w/in structures, no + * longer malloc'd + */ +} + +#define SD_SEM_TAKE(sem,desc) down(sem) +#define SD_SEM_GIVE(sem) up(sem) +#define SEM_AVAILABLE 1 +#define SEM_TAKEN 0 + + +/**********************/ +/* watchdog functions */ +/**********************/ + +struct watchdog +{ + struct timer_list h; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + struct tq_struct tq; +#else + struct work_struct work; +#endif + void *softc; + void (*func) (void *softc); + int ticks; + int init_tq; +}; + + +static inline int +OS_start_watchdog (struct watchdog * wd) +{ + wd->h.expires = jiffies + wd->ticks; + add_timer (&wd->h); + return 0; +} + + +static inline int +OS_stop_watchdog (struct watchdog * wd) +{ + del_timer_sync (&wd->h); + return 0; +} + + +static inline int +OS_free_watchdog (struct watchdog * wd) +{ + OS_stop_watchdog (wd); + OS_kfree (wd); + return 0; +} + + +/* sleep in microseconds */ +void OS_uwait (int usec, char *description); +void OS_uwait_dummy (void); + + +/* watchdog functions */ +int OS_init_watchdog(struct watchdog *wdp, void (*f) (void *), void *ci, int usec); + + +#endif /*** _INC_SBECOM_INLNX_H_ ***/ diff --git a/drivers/staging/cxt1e1/sbecrc.c b/drivers/staging/cxt1e1/sbecrc.c new file mode 100644 index 000000000000..51232948091f --- /dev/null +++ b/drivers/staging/cxt1e1/sbecrc.c @@ -0,0 +1,137 @@ +/* Based on "File Verification Using CRC" by Mark R. Nelson in Dr. Dobbs' + * Journal, May 1992, pp. 64-67. This algorithm generates the same CRC + * values as ZMODEM and PKZIP + * + * Copyright (C) 2002-2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "pmcc4_sysdep.h" +#include "sbecom_inline_linux.h" +#include "sbe_promformat.h" + +/* defines */ +#define CRC32_POLYNOMIAL 0xEDB88320L +#define CRC_TABLE_ENTRIES 256 + + + +static u_int32_t crcTableInit; + +#ifdef STATIC_CRC_TABLE +static u_int32_t CRCTable[CRC_TABLE_ENTRIES]; + +#endif + + +/*************************************************************************** +* +* genCrcTable - fills in CRCTable, as used by sbeCrc() +* +* RETURNS: N/A +* +* ERRNO: N/A +***************************************************************************/ + +static void +genCrcTable (u_int32_t *CRCTable) +{ + int ii, jj; + u_int32_t crc; + + for (ii = 0; ii < CRC_TABLE_ENTRIES; ii++) + { + crc = ii; + for (jj = 8; jj > 0; jj--) + { + if (crc & 1) + crc = (crc >> 1) ^ CRC32_POLYNOMIAL; + else + crc >>= 1; + } + CRCTable[ii] = crc; + } + + crcTableInit++; +} + + +/*************************************************************************** +* +* sbeCrc - generates a CRC on a given buffer, and initial CRC +* +* This routine calculates the CRC for a buffer of data using the +* table lookup method. It accepts an original value for the crc, +* and returns the updated value. This permits "catenation" of +* discontiguous buffers. An original value of 0 for the "first" +* buffer is the norm. +* +* Based on "File Verification Using CRC" by Mark R. Nelson in Dr. Dobb's +* Journal, May 1992, pp. 64-67. This algorithm generates the same CRC +* values as ZMODEM and PKZIP. +* +* RETURNS: calculated crc of block +* +*/ + +void +sbeCrc (u_int8_t *buffer, /* data buffer to crc */ + u_int32_t count, /* length of block in bytes */ + u_int32_t initialCrc, /* starting CRC */ + u_int32_t *result) +{ + u_int32_t *tbl = 0; + u_int32_t temp1, temp2, crc; + + /* + * if table not yet created, do so. Don't care about "extra" time + * checking this everytime sbeCrc() is called, since CRC calculations are + * already time consuming + */ + if (!crcTableInit) + { +#ifdef STATIC_CRC_TABLE + tbl = &CRCTable; + genCrcTable (tbl); +#else + tbl = (u_int32_t *) OS_kmalloc (CRC_TABLE_ENTRIES * sizeof (u_int32_t)); + if (tbl == 0) + { + *result = 0; /* dummy up return value due to malloc + * failure */ + return; + } + genCrcTable (tbl); +#endif + } + /* inverting bits makes ZMODEM & PKZIP compatible */ + crc = initialCrc ^ 0xFFFFFFFFL; + + while (count-- != 0) + { + temp1 = (crc >> 8) & 0x00FFFFFFL; + temp2 = tbl[((int) crc ^ *buffer++) & 0xff]; + crc = temp1 ^ temp2; + } + + crc ^= 0xFFFFFFFFL; + + *result = crc; + +#ifndef STATIC_CRC_TABLE + crcTableInit = 0; + OS_kfree (tbl); +#endif +} + +/*** End-of-File ***/ diff --git a/drivers/staging/cxt1e1/sbeid.c b/drivers/staging/cxt1e1/sbeid.c new file mode 100644 index 000000000000..a2243b10ef05 --- /dev/null +++ b/drivers/staging/cxt1e1/sbeid.c @@ -0,0 +1,217 @@ +/* Copyright (C) 2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "pmcc4_sysdep.h" +#include "sbecom_inline_linux.h" +#include "libsbew.h" +#include "pmcc4_private.h" +#include "pmcc4.h" +#include "sbe_bid.h" + +#ifdef SBE_INCLUDE_SYMBOLS +#define STATIC +#else +#define STATIC static +#endif + + +char * +sbeid_get_bdname (ci_t * ci) +{ + char *np = 0; + + switch (ci->brd_id) + { + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1): + np = "wanPTMC-256T3 "; + break; + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1): + np = "wanPTMC-256T3 "; + break; + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1): + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L): + np = "wanPMC-C4T1E1"; + break; + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1): + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L): + np = "wanPMC-C2T1E1"; + break; + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1): + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L): + np = "wanPMC-C1T1E1"; + break; + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1): + np = "wanPCI-C4T1E1"; + break; + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1): + np = "wanPCI-C2T1E1"; + break; + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1): + np = "wanPCI-C1T1E1"; + break; + default: + /*** np = ""; ***/ + np = "wanPCI-CxT1E1"; + break; + } + + return np; +} + + +/* given the presetting of brd_id, set the corresponding hdw_id */ + +void +sbeid_set_hdwbid (ci_t * ci) +{ + /* + * set SBE's unique hardware identification (for legacy boards might not + * have this register implemented) + */ + + switch (ci->brd_id) + { + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1): + ci->hdw_bid = SBE_BID_256T3_E1; /* 0x46 - SBE wanPTMC-256T3 (E1 + * Version) */ + break; + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1): + ci->hdw_bid = SBE_BID_256T3_T1; /* 0x42 - SBE wanPTMC-256T3 (T1 + * Version) */ + break; + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1): + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L): + /* + * This Board ID is a generic identification. Use the found number + * of ports to further define this hardware. + */ + switch (ci->max_port) + { + default: /* shouldn't need a default, but have one + * anyway */ + case 4: + ci->hdw_bid = SBE_BID_PMC_C4T1E1; /* 0xC4 - SBE wanPMC-C4T1E1 */ + break; + case 2: + ci->hdw_bid = SBE_BID_PMC_C2T1E1; /* 0xC2 - SBE wanPMC-C2T1E1 */ + ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1); + break; + case 1: + ci->hdw_bid = SBE_BID_PMC_C1T1E1; /* 0xC1 - SBE wanPMC-C1T1E1 */ + ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1); + break; + } + break; + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1): + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L): + ci->hdw_bid = SBE_BID_PMC_C2T1E1; /* 0xC2 - SBE wanPMC-C2T1E1 */ + break; + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1): + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L): + ci->hdw_bid = SBE_BID_PMC_C1T1E1; /* 0xC1 - SBE wanPMC-C1T1E1 */ + break; +#ifdef SBE_PMCC4_ENABLE + /* + * This case is entered as a result of the inability to obtain the + * from the board's EEPROM. Assume a PCI board and set + * according to the number ofr found ports. + */ + case 0: + /* start by assuming 4-port for ZERO casing */ + ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1); + /* drop thru to set hdw_bid and alternate PCI CxT1E1 settings */ +#endif + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1): + /* + * This Board ID is a generic identification. Use the number of + * found ports to further define this hardware. + */ + switch (ci->max_port) + { + default: /* shouldn't need a default, but have one + * anyway */ + case 4: + ci->hdw_bid = SBE_BID_PCI_C4T1E1; /* 0x04 - SBE wanPCI-C4T1E1 */ + break; + case 2: + ci->hdw_bid = SBE_BID_PCI_C2T1E1; /* 0x02 - SBE wanPCI-C2T1E1 */ + ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1); + break; + case 1: + ci->hdw_bid = SBE_BID_PCI_C1T1E1; /* 0x01 - SBE wanPCI-C1T1E1 */ + ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1); + break; + } + break; + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1): + ci->hdw_bid = SBE_BID_PCI_C2T1E1; /* 0x02 - SBE wanPCI-C2T1E1 */ + break; + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1): + ci->hdw_bid = SBE_BID_PCI_C1T1E1; /* 0x01 - SBE wanPCI-C1T1E1 */ + break; + default: + /*** bid = ""; ***/ + ci->hdw_bid = SBE_BID_PMC_C4T1E1; /* 0x41 - SBE wanPTMC-C4T1E1 */ + break; + } +} + +/* given the presetting of hdw_bid, set the corresponding brd_id */ + +void +sbeid_set_bdtype (ci_t * ci) +{ + /* set SBE's unique PCI VENDOR/DEVID */ + switch (ci->hdw_bid) + { + case SBE_BID_C1T3: /* SBE wanPMC-C1T3 */ + ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3); + break; + case SBE_BID_C24TE1: /* SBE wanPTMC-C24TE1 */ + ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1); + break; + case SBE_BID_256T3_E1: /* SBE wanPTMC-256T3 E1 Version */ + ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1); + break; + case SBE_BID_256T3_T1: /* SBE wanPTMC-256T3 T1 Version */ + ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1); + break; + case SBE_BID_PMC_C4T1E1: /* 0xC4 - SBE wanPMC-C4T1E1 */ + ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1); + break; + case SBE_BID_PMC_C2T1E1: /* 0xC2 - SBE wanPMC-C2T1E1 */ + ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1); + break; + case SBE_BID_PMC_C1T1E1: /* 0xC1 - SBE wanPMC-C1T1E1 */ + ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1); + break; + case SBE_BID_PCI_C4T1E1: /* 0x04 - SBE wanPCI-C4T1E1 */ + ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1); + break; + case SBE_BID_PCI_C2T1E1: /* 0x02 - SBE wanPCI-C2T1E1 */ + ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1); + break; + case SBE_BID_PCI_C1T1E1: /* 0x01 - SBE wanPCI-C1T1E1 */ + ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1); + break; + + default: + /*** hdw_bid = ""; ***/ + ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1); + break; + } +} + + +/*** End-of-File ***/ diff --git a/drivers/staging/cxt1e1/sbeproc.c b/drivers/staging/cxt1e1/sbeproc.c new file mode 100644 index 000000000000..61ca639c184f --- /dev/null +++ b/drivers/staging/cxt1e1/sbeproc.c @@ -0,0 +1,358 @@ +/* Copyright (C) 2004-2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "pmcc4_sysdep.h" +#include "sbecom_inline_linux.h" +#include "pmcc4_private.h" +#include "sbeproc.h" + +/* forwards */ +void sbecom_get_brdinfo (ci_t *, struct sbe_brd_info *, u_int8_t *); +extern struct s_hdw_info hdw_info[MAX_BOARDS]; + +#ifdef CONFIG_PROC_FS + +/********************************************************************/ +/* procfs stuff */ +/********************************************************************/ + + +void +sbecom_proc_brd_cleanup (ci_t * ci) +{ + if (ci->dir_dev) + { + char dir[7 + SBE_IFACETMPL_SIZE + 1]; + snprintf(dir, sizeof(dir), "driver/%s", ci->devname); + remove_proc_entry("info", ci->dir_dev); + remove_proc_entry(dir, NULL); + ci->dir_dev = NULL; + } +} + + +static int +sbecom_proc_get_sbe_info (char *buffer, char **start, off_t offset, + int length, int *eof, void *priv) +{ + ci_t *ci = (ci_t *) priv; + int len = 0; + char *spd; + struct sbe_brd_info *bip; + + if (!(bip = OS_kmalloc (sizeof (struct sbe_brd_info)))) + { + return -ENOMEM; + } +#if 0 + /** RLD DEBUG **/ + printk (">> sbecom_proc_get_sbe_info: entered, offset %d. length %d.\n", + (int) offset, (int) length); +#endif + + { + hdw_info_t *hi = &hdw_info[ci->brdno]; + + u_int8_t *bsn = 0; + + switch (hi->promfmt) + { + case PROM_FORMAT_TYPE1: + bsn = (u_int8_t *) hi->mfg_info.pft1.Serial; + break; + case PROM_FORMAT_TYPE2: + bsn = (u_int8_t *) hi->mfg_info.pft2.Serial; + break; + } + + sbecom_get_brdinfo (ci, bip, bsn); + } + +#if 0 + /** RLD DEBUG **/ + printk (">> sbecom_get_brdinfo: returned, first_if %p <%s> last_if %p <%s>\n", + (char *) &bip->first_iname, (char *) &bip->first_iname, + (char *) &bip->last_iname, (char *) &bip->last_iname); +#endif + len += sprintf (buffer + len, "Board Type: "); + switch (bip->brd_id) + { + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3): + len += sprintf (buffer + len, "wanPMC-C1T3"); + break; + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1): + len += sprintf (buffer + len, "wanPTMC-256T3 "); + break; + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1): + len += sprintf (buffer + len, "wanPTMC-256T3 "); + break; + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1): + len += sprintf (buffer + len, "wanPTMC-C24TE1"); + break; + + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1): + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L): + len += sprintf (buffer + len, "wanPMC-C4T1E1"); + break; + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1): + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L): + len += sprintf (buffer + len, "wanPMC-C2T1E1"); + break; + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1): + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L): + len += sprintf (buffer + len, "wanPMC-C1T1E1"); + break; + + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1): + len += sprintf (buffer + len, "wanPCI-C4T1E1"); + break; + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1): + len += sprintf (buffer + len, "wanPCI-C2T1E1"); + break; + case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1): + len += sprintf (buffer + len, "wanPCI-C1T1E1"); + break; + + default: + len += sprintf (buffer + len, "unknown"); + break; + } + len += sprintf (buffer + len, " [%08X]\n", bip->brd_id); + + len += sprintf (buffer + len, "Board Number: %d\n", bip->brdno); + len += sprintf (buffer + len, "Hardware ID: 0x%02X\n", ci->hdw_bid); + len += sprintf (buffer + len, "Board SN: %06X\n", bip->brd_sn); + len += sprintf (buffer + len, "Board MAC: %02X-%02X-%02X-%02X-%02X-%02X\n", + bip->brd_mac_addr[0], bip->brd_mac_addr[1], bip->brd_mac_addr[2], + bip->brd_mac_addr[3], bip->brd_mac_addr[4], bip->brd_mac_addr[5]); + len += sprintf (buffer + len, "Ports: %d\n", ci->max_port); + len += sprintf (buffer + len, "Channels: %d\n", bip->brd_chan_cnt); +#if 1 + len += sprintf (buffer + len, "Interface: %s -> %s\n", + (char *) &bip->first_iname, (char *) &bip->last_iname); +#else + len += sprintf (buffer + len, "Interface: 1st %p lst %p\n", + (char *) &bip->first_iname, (char *) &bip->last_iname); +#endif + + switch (bip->brd_pci_speed) + { + case BINFO_PCI_SPEED_33: + spd = "33Mhz"; + break; + case BINFO_PCI_SPEED_66: + spd = "66Mhz"; + break; + default: + spd = ""; + break; + } + len += sprintf (buffer + len, "PCI Bus Speed: %s\n", spd); + len += sprintf (buffer + len, "Release: %s\n", ci->release); + +#ifdef SBE_PMCC4_ENABLE + { + extern int max_mru; +#if 0 + extern int max_chans_used; + extern int max_mtu; +#endif + extern int max_rxdesc_used, max_txdesc_used; + + len += sprintf (buffer + len, "\nmax_mru: %d\n", max_mru); +#if 0 + len += sprintf (buffer + len, "\nmax_chans_used: %d\n", max_chans_used); + len += sprintf (buffer + len, "max_mtu: %d\n", max_mtu); +#endif + len += sprintf (buffer + len, "max_rxdesc_used: %d\n", max_rxdesc_used); + len += sprintf (buffer + len, "max_txdesc_used: %d\n", max_txdesc_used); + } +#endif + + OS_kfree (bip); /* cleanup */ + + /*** + * How to be a proc read function + * ------------------------------ + * Prototype: + * int f(char *buffer, char **start, off_t offset, + * int count, int *peof, void *dat) + * + * Assume that the buffer is "count" bytes in size. + * + * If you know you have supplied all the data you + * have, set *peof. + * + * You have three ways to return data: + * 0) Leave *start = NULL. (This is the default.) + * Put the data of the requested offset at that + * offset within the buffer. Return the number (n) + * of bytes there are from the beginning of the + * buffer up to the last byte of data. If the + * number of supplied bytes (= n - offset) is + * greater than zero and you didn't signal eof + * and the reader is prepared to take more data + * you will be called again with the requested + * offset advanced by the number of bytes + * absorbed. This interface is useful for files + * no larger than the buffer. + * 1) Set *start = an unsigned long value less than + * the buffer address but greater than zero. + * Put the data of the requested offset at the + * beginning of the buffer. Return the number of + * bytes of data placed there. If this number is + * greater than zero and you didn't signal eof + * and the reader is prepared to take more data + * you will be called again with the requested + * offset advanced by *start. This interface is + * useful when you have a large file consisting + * of a series of blocks which you want to count + * and return as wholes. + * (Hack by Paul.Russell@rustcorp.com.au) + * 2) Set *start = an address within the buffer. + * Put the data of the requested offset at *start. + * Return the number of bytes of data placed there. + * If this number is greater than zero and you + * didn't signal eof and the reader is prepared to + * take more data you will be called again with the + * requested offset advanced by the number of bytes + * absorbed. + */ + +#if 1 + /* #4 - intepretation of above = set EOF, return len */ + *eof = 1; +#endif + +#if 0 + /* + * #1 - from net/wireless/atmel.c RLD NOTE -there's something wrong with + * this plagarized code which results in this routine being called TWICE. + * The second call returns ZERO, resulting in hidden failure, but at + * least only a single message set is being displayed. + */ + if (len <= offset + length) + *eof = 1; + *start = buffer + offset; + len -= offset; + if (len > length) + len = length; + if (len < 0) + len = 0; +#endif + +#if 0 /* #2 from net/tokenring/olympic.c + + * lanstreamer.c */ + { + off_t begin = 0; + int size = 0; + off_t pos = 0; + + size = len; + pos = begin + size; + if (pos < offset) + { + len = 0; + begin = pos; + } + *start = buffer + (offset - begin); /* Start of wanted data */ + len -= (offset - begin); /* Start slop */ + if (len > length) + len = length; /* Ending slop */ + } +#endif + +#if 0 /* #3 from + * char/ftape/lowlevel/ftape-proc.c */ + len = strlen (buffer); + *start = NULL; + if (offset + length >= len) + *eof = 1; + else + *eof = 0; +#endif + +#if 0 + printk (">> proc_fs: returned len = %d., start %p\n", len, start); /* RLD DEBUG */ +#endif + +/*** + using NONE: returns = 314.314.314. + using #1 : returns = 314, 0. + using #2 : returns = 314, 0, 0. + using #3 : returns = 314, 314. + using #4 : returns = 314, 314. +***/ + + return len; +} + +/* initialize the /proc subsystem for the specific SBE driver */ + +int __init +sbecom_proc_brd_init (ci_t * ci) +{ + struct proc_dir_entry *e; + char dir[7 + SBE_IFACETMPL_SIZE + 1]; + + /* create a directory in the root procfs */ + snprintf(dir, sizeof(dir), "driver/%s", ci->devname); + ci->dir_dev = proc_mkdir(dir, NULL); + if (!ci->dir_dev) + { + printk (KERN_ERR "%s: Unable to create directory /proc/driver/%s\n", + THIS_MODULE->name, ci->devname); + goto fail; + } + e = create_proc_read_entry ("info", S_IFREG | S_IRUGO, + ci->dir_dev, sbecom_proc_get_sbe_info, ci); + if (!e) + { + printk (KERN_ERR "%s: Unable to create entry /proc/driver/%s/info\n", + THIS_MODULE->name, ci->devname); + goto fail; + } + return 0; + +fail: + sbecom_proc_brd_cleanup (ci); + return 1; +} + +#else /*** ! CONFIG_PROC_FS ***/ + +/* stubbed off dummy routines */ + +void +sbecom_proc_brd_cleanup (ci_t * ci) +{ +} + +int __init +sbecom_proc_brd_init (ci_t * ci) +{ + return 0; +} + +#endif /*** CONFIG_PROC_FS ***/ + + +/*** End-of-File ***/ diff --git a/drivers/staging/cxt1e1/sbeproc.h b/drivers/staging/cxt1e1/sbeproc.h new file mode 100644 index 000000000000..4aa53f44ec0b --- /dev/null +++ b/drivers/staging/cxt1e1/sbeproc.h @@ -0,0 +1,52 @@ +/* + * $Id: sbeproc.h,v 1.2 2005/10/17 23:55:28 rickd PMCC4_3_1B $ + */ + +#ifndef _INC_SBEPROC_H_ +#define _INC_SBEPROC_H_ + +/*----------------------------------------------------------------------------- + * sbeproc.h - + * + * Copyright (C) 2004-2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For further information, contact via email: support@sbei.com + * SBE, Inc. San Ramon, California U.S.A. + *----------------------------------------------------------------------------- + * RCS info: + * RCS revision: $Revision: 1.2 $ + * Last changed on $Date: 2005/10/17 23:55:28 $ + * Changed by $Author: rickd $ + *----------------------------------------------------------------------------- + * $Log: sbeproc.h,v $ + * Revision 1.2 2005/10/17 23:55:28 rickd + * sbecom_proc_brd_init() is an declared an __init function. + * + * Revision 1.1 2005/09/28 00:10:09 rickd + * Remove unneeded inclusion of c4_private.h. + * + * Revision 1.0 2005/05/10 22:21:46 rickd + * Initial check-in. + * + *----------------------------------------------------------------------------- + */ + + +#ifdef CONFIG_PROC_FS +#ifdef __KERNEL__ +void sbecom_proc_brd_cleanup (ci_t *); +int __init sbecom_proc_brd_init (ci_t *); + +#endif /*** __KERNEL__ ***/ +#endif /*** CONFIG_PROC_FS ***/ +#endif /*** _INC_SBEPROC_H_ ***/ diff --git a/drivers/staging/cxt1e1/sbew_ioc.h b/drivers/staging/cxt1e1/sbew_ioc.h new file mode 100644 index 000000000000..14d371904d1f --- /dev/null +++ b/drivers/staging/cxt1e1/sbew_ioc.h @@ -0,0 +1,136 @@ +/* + * $Id: sbew_ioc.h,v 1.0 2005/09/28 00:10:10 rickd PMCC4_3_1B $ + */ + +#ifndef _INC_SBEWIOC_H_ +#define _INC_SBEWIOC_H_ + +/*----------------------------------------------------------------------------- + * sbew_ioc.h - + * + * Copyright (C) 2002-2005 SBE, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For further information, contact via email: support@sbei.com + * SBE, Inc. San Ramon, California U.S.A. + * + *----------------------------------------------------------------------------- + * RCS info: + * RCS revision: $Revision: 1.0 $ + * Last changed on $Date: 2005/09/28 00:10:10 $ + * Changed by $Author: rickd $ + *----------------------------------------------------------------------------- + * $Log: sbew_ioc.h,v $ + * Revision 1.0 2005/09/28 00:10:10 rickd + * Initial revision + * + * Revision 1.6 2005/01/11 18:41:01 rickd + * Add BRDADDR_GET Ioctl. + * + * Revision 1.5 2004/09/16 18:55:59 rickd + * Start setting up for generic framer configuration Ioctl by switch + * from tect3_framer_param[] to sbecom_framer_param[]. + * + * Revision 1.4 2004/06/28 17:58:15 rickd + * Rename IOC_TSMAP_[GS] to IOC_TSIOC_[GS] to support need for + * multiple formats of data when setting up TimeSlots. + * + * Revision 1.3 2004/06/22 21:18:13 rickd + * read_vec now() ONLY handles a single common wrt_vec array. + * + * Revision 1.1 2004/06/10 18:11:34 rickd + * Add IID_GET Ioctl reference. + * + * Revision 1.0 2004/06/08 22:59:38 rickd + * Initial revision + * + * Revision 2.0 2004/06/07 17:49:47 rickd + * Initial library release following merge of wanc1t3/wan256 into + * common elements for lib. + * + *----------------------------------------------------------------------------- + */ + +#ifndef __KERNEL__ +#include +#endif +#ifdef SunOS +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define SBE_LOCKFILE "/tmp/.sbewan.LCK" + +#define SBE_IOC_COOKIE 0x19780926 +#define SBE_IOC_MAGIC ('s') + +/* IOW write - data has to go into driver from application */ +/* IOR read - data has to be returned to application from driver */ + +/* + * Note: for an IOWR Ioctl, the read and write data do not have to + * be the same size, but the entity declared within the IOC must be + * the larger of the two. + */ + +#define SBE_IOC_LOGLEVEL _IOW(SBE_IOC_MAGIC, 0x00, int) +#define SBE_IOC_CHAN_NEW _IOW(SBE_IOC_MAGIC, 0x01,int) /* unused */ +#define SBE_IOC_CHAN_UP _IOW(SBE_IOC_MAGIC, 0x02,int) /* unused */ +#define SBE_IOC_CHAN_DOWN _IOW(SBE_IOC_MAGIC, 0x03,int) /* unused */ +#define SBE_IOC_CHAN_GET _IOWR(SBE_IOC_MAGIC,0x04, struct sbecom_chan_param) +#define SBE_IOC_CHAN_SET _IOW(SBE_IOC_MAGIC, 0x05, struct sbecom_chan_param) +#define SBE_IOC_CHAN_GET_STAT _IOWR(SBE_IOC_MAGIC,0x06, struct sbecom_chan_stats) +#define SBE_IOC_CHAN_DEL_STAT _IOW(SBE_IOC_MAGIC, 0x07, int) +#define SBE_IOC_PORTS_ENABLE _IOW(SBE_IOC_MAGIC, 0x0A, int) +#define SBE_IOC_PORT_GET _IOWR(SBE_IOC_MAGIC,0x0C, struct sbecom_port_param) +#define SBE_IOC_PORT_SET _IOW(SBE_IOC_MAGIC, 0x0D, struct sbecom_port_param) +#define SBE_IOC_READ_VEC _IOWR(SBE_IOC_MAGIC,0x10, struct sbecom_wrt_vec) +#define SBE_IOC_WRITE_VEC _IOWR(SBE_IOC_MAGIC,0x11, struct sbecom_wrt_vec) +#define SBE_IOC_GET_SN _IOR(SBE_IOC_MAGIC, 0x12, u_int32_t) +#define SBE_IOC_RESET_DEV _IOW(SBE_IOC_MAGIC, 0x13, int) +#define SBE_IOC_FRAMER_GET _IOWR(SBE_IOC_MAGIC,0x14, struct sbecom_framer_param) +#define SBE_IOC_FRAMER_SET _IOW(SBE_IOC_MAGIC, 0x15, struct sbecom_framer_param) +#define SBE_IOC_CARD_GET _IOR(SBE_IOC_MAGIC, 0x20, struct sbecom_card_param) +#define SBE_IOC_CARD_SET _IOW(SBE_IOC_MAGIC, 0x21, struct sbecom_card_param) +#define SBE_IOC_CARD_GET_STAT _IOR(SBE_IOC_MAGIC, 0x22, struct temux_card_stats) +#define SBE_IOC_CARD_DEL_STAT _IO(SBE_IOC_MAGIC, 0x23) +#define SBE_IOC_CARD_CHAN_STAT _IOR(SBE_IOC_MAGIC, 0x24, struct sbecom_chan_stats) +#define SBE_IOC_CARD_BLINK _IOW(SBE_IOC_MAGIC, 0x30, int) +#define SBE_IOC_DRVINFO_GET _IOWR(SBE_IOC_MAGIC,0x31, struct sbe_drv_info) +#define SBE_IOC_BRDINFO_GET _IOR(SBE_IOC_MAGIC, 0x32, struct sbe_brd_info) +#define SBE_IOC_IID_GET _IOWR(SBE_IOC_MAGIC,0x33, struct sbe_iid_info) +#define SBE_IOC_BRDADDR_GET _IOWR(SBE_IOC_MAGIC, 0x34, struct sbe_brd_addr) + +#ifdef NOT_YET_COMMON +#define SBE_IOC_TSIOC_GET _IOWR(SBE_IOC_MAGIC,0x16, struct wanc1t3_ts_param) +#define SBE_IOC_TSIOC_SET _IOW(SBE_IOC_MAGIC, 0x17, struct wanc1t3_ts_param) +#endif + +/* + * Restrict SBE_IOC_WRITE_VEC & READ_VEC to a single parameter pair, application + * then must issue multiple Ioctls for large blocks of contiguous data. + */ + +#define SBE_IOC_MAXVEC 1 + + +#ifdef __cplusplus +} +#endif + +#endif /*** _INC_SBEWIOC_H_ ***/ -- cgit v1.2.3 From d607c7811279b51fb1a7dbbe01533f7acf26ab23 Mon Sep 17 00:00:00 2001 From: Maurice Dawson Date: Wed, 17 Mar 2010 13:40:11 +0000 Subject: Staging: comedi: fix indent coding style issue in adl_pci9118.c Patch to the adl_pci9118.c that fixes, ERROR: code indent should use tabs where possible, found by the checkpatch.pl tool Signed-off-by: Maurice Dawson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9118.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 944f20ae5a6a..bed7e41445aa 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -44,20 +44,20 @@ c) If isn't used DMA then you can use only mode where Configuration options: [0] - PCI bus of device (optional) [1] - PCI slot of device (optional) - If bus/slot is not specified, then first available PCI - card will be used. + If bus/slot is not specified, then first available PCI + card will be used. [2] - 0= standard 8 DIFF/16 SE channels configuration - n= external multiplexer connected, 1<=n<=256 + n = external multiplexer connected, 1 <= n <= 256 [3] - 0=autoselect DMA or EOC interrupts operation - 1=disable DMA mode - 3=disable DMA and INT, only insn interface will work + 1 = disable DMA mode + 3 = disable DMA and INT, only insn interface will work [4] - sample&hold signal - card can generate signal for external S&H board - 0=use SSHO (pin 45) signal is generated in onboard hardware S&H logic - 0!=use ADCHN7 (pin 23) signal is generated from driver, number - say how long delay is requested in ns and sign polarity of the hold - (in this case external multiplexor can serve only 128 channels) + 0 = use SSHO(pin 45) signal is generated in onboard hardware S&H logic + 0 != use ADCHN7(pin 23) signal is generated from driver, number say how + long delay is requested in ns and sign polarity of the hold + (in this case external multiplexor can serve only 128 channels) [5] - 0=stop measure on all hardware errors - 2|=ignore ADOR - A/D Overrun status + 2 | = ignore ADOR - A/D Overrun status 8|=ignore Bover - A/D Burst Mode Overrun status 256|=ignore nFull - A/D FIFO Full status -- cgit v1.2.3 From 242467bd058f09ec05985bb09201a9cd0b1d89e5 Mon Sep 17 00:00:00 2001 From: Maurice Dawson Date: Thu, 18 Mar 2010 14:46:37 +0000 Subject: Staging: comedi: fix 80 character coding style issue in adl_pci9118.c Fixes all over 80 character warnings in the adl_pci9118.c file found by the checkpatch.pl tool Signed-off-by: Maurice Dawson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9118.c | 778 ++++++++++++++++++--------- 1 file changed, 530 insertions(+), 248 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index bed7e41445aa..4f9fd7dd0cf2 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -75,9 +75,15 @@ Configuration options: #include "comedi_fc.h" /* paranoid checks are broken */ -#undef PCI9118_PARANOIDCHECK /* if defined, then is used code which control correct channel number on every 12 bit sample */ +#undef PCI9118_PARANOIDCHECK /* + * if defined, then is used code which control + * correct channel number on every 12 bit sample + */ -#undef PCI9118_EXTDEBUG /* if defined then driver prints a lot of messages */ +#undef PCI9118_EXTDEBUG /* + * if defined then driver prints + * a lot of messages + */ #undef DPRINTK #ifdef PCI9118_EXTDEBUG @@ -87,7 +93,10 @@ Configuration options: #endif #define IORANGE_9118 64 /* I hope */ -#define PCI9118_CHANLEN 255 /* len of chanlist, some source say 256, but reality looks like 255 :-( */ +#define PCI9118_CHANLEN 255 /* + * len of chanlist, some source say 256, + * but reality looks like 255 :-( + */ #define PCI9118_CNT0 0x00 /* R/W: 8254 counter 0 */ #define PCI9118_CNT1 0x04 /* R/W: 8254 counter 0 */ @@ -113,20 +122,47 @@ Configuration options: #define AdControl_UniP 0x80 /* 1=bipolar, 0=unipolar */ #define AdControl_Diff 0x40 /* 1=differential, 0= single end inputs */ #define AdControl_SoftG 0x20 /* 1=8254 counter works, 0=counter stops */ -#define AdControl_ExtG 0x10 /* 1=8254 countrol controlled by TGIN(pin 46), 0=controled by SoftG */ -#define AdControl_ExtM 0x08 /* 1=external hardware trigger (pin 44), 0=internal trigger */ -#define AdControl_TmrTr 0x04 /* 1=8254 is iternal trigger source, 0=software trigger is source (register PCI9118_SOFTTRG) */ +#define AdControl_ExtG 0x10 /* + * 1=8254 countrol controlled by TGIN(pin 46), + * 0=controlled by SoftG + */ +#define AdControl_ExtM 0x08 /* + * 1=external hardware trigger (pin 44), + * 0=internal trigger + */ +#define AdControl_TmrTr 0x04 /* + * 1=8254 is iternal trigger source, + * 0=software trigger is source + * (register PCI9118_SOFTTRG) + */ #define AdControl_Int 0x02 /* 1=enable INT, 0=disable */ #define AdControl_Dma 0x01 /* 1=enable DMA, 0=disable */ /* bits from A/D function register (PCI9118_ADFUNC) */ -#define AdFunction_PDTrg 0x80 /* 1=positive, 0=negative digital trigger (only positive is correct) */ -#define AdFunction_PETrg 0x40 /* 1=positive, 0=negative external trigger (only positive is correct) */ +#define AdFunction_PDTrg 0x80 /* + * 1=positive, + * 0=negative digital trigger + * (only positive is correct) + */ +#define AdFunction_PETrg 0x40 /* + * 1=positive, + * 0=negative external trigger + * (only positive is correct) + */ #define AdFunction_BSSH 0x20 /* 1=with sample&hold, 0=without */ #define AdFunction_BM 0x10 /* 1=burst mode, 0=normal mode */ -#define AdFunction_BS 0x08 /* 1=burst mode start, 0=burst mode stop */ -#define AdFunction_PM 0x04 /* 1=post trigger mode, 0=not post trigger */ -#define AdFunction_AM 0x02 /* 1=about trigger mode, 0=not about trigger */ +#define AdFunction_BS 0x08 /* + * 1=burst mode start, + * 0=burst mode stop + */ +#define AdFunction_PM 0x04 /* + * 1=post trigger mode, + * 0=not post trigger + */ +#define AdFunction_AM 0x02 /* + * 1=about trigger mode, + * 0=not about trigger + */ #define AdFunction_Start 0x01 /* 1=trigger start, 0=trigger stop */ /* bits from A/D status register (PCI9118_ADSTAT) */ @@ -178,30 +214,39 @@ static const struct comedi_lrange range_pci9118hg = { 8, { } }; -#define PCI9118_BIPOLAR_RANGES 4 /* used for test on mixture of BIP/UNI ranges */ +#define PCI9118_BIPOLAR_RANGES 4 /* + * used for test on mixture + * of BIP/UNI ranges + */ static int pci9118_attach(struct comedi_device *dev, struct comedi_devconfig *it); static int pci9118_detach(struct comedi_device *dev); struct boardtype { - const char *name; /* board name */ - int vendor_id; /* PCI vendor a device ID of card */ + const char *name; /* board name */ + int vendor_id; /* PCI vendor a device ID of card */ int device_id; - int iorange_amcc; /* iorange for own S5933 region */ - int iorange_9118; /* pass thru card region size */ - int n_aichan; /* num of A/D chans */ - int n_aichand; /* num of A/D chans in diff mode */ - int mux_aichan; /* num of A/D chans with external multiplexor */ - int n_aichanlist; /* len of chanlist */ - int n_aochan; /* num of D/A chans */ - int ai_maxdata; /* resolution of A/D */ - int ao_maxdata; /* resolution of D/A */ - const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */ - const struct comedi_lrange *rangelist_ao; /* rangelist for D/A */ - unsigned int ai_ns_min; /* max sample speed of card v ns */ - unsigned int ai_pacer_min; /* minimal pacer value (c1*c2 or c1 in burst) */ - int half_fifo_size; /* size of FIFO/2 */ + int iorange_amcc; /* iorange for own S5933 region */ + int iorange_9118; /* pass thru card region size */ + int n_aichan; /* num of A/D chans */ + int n_aichand; /* num of A/D chans in diff mode */ + int mux_aichan; /* + * num of A/D chans with + * external multiplexor + */ + int n_aichanlist; /* len of chanlist */ + int n_aochan; /* num of D/A chans */ + int ai_maxdata; /* resolution of A/D */ + int ao_maxdata; /* resolution of D/A */ + const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */ + const struct comedi_lrange *rangelist_ao; /* rangelist for D/A */ + unsigned int ai_ns_min; /* max sample speed of card v ns */ + unsigned int ai_pacer_min; /* + * minimal pacer value + * (c1*c2 or c1 in burst) + */ + int half_fifo_size; /* size of FIFO/2 */ }; @@ -246,63 +291,113 @@ static struct comedi_driver driver_pci9118 = { COMEDI_PCI_INITCLEANUP(driver_pci9118, pci9118_pci_table); struct pci9118_private { - unsigned long iobase_a; /* base+size for AMCC chip */ - unsigned int master; /* master capable */ - struct pci_dev *pcidev; /* ptr to actual pcidev */ - unsigned int usemux; /* we want to use external multiplexor! */ + unsigned long iobase_a; /* base+size for AMCC chip */ + unsigned int master; /* master capable */ + struct pci_dev *pcidev; /* ptr to actual pcidev */ + unsigned int usemux; /* we want to use external multiplexor! */ #ifdef PCI9118_PARANOIDCHECK - unsigned short chanlist[PCI9118_CHANLEN + 1]; /* list of scaned channel */ - unsigned char chanlistlen; /* number of scanlist */ + unsigned short chanlist[PCI9118_CHANLEN + 1]; /* + * list of + * scanned channel + */ + unsigned char chanlistlen; /* number of scanlist */ #endif - unsigned char AdControlReg; /* A/D control register */ - unsigned char IntControlReg; /* Interrupt control register */ - unsigned char AdFunctionReg; /* A/D function register */ - char valid; /* driver is ok */ - char ai_neverending; /* we do unlimited AI */ - unsigned int i8254_osc_base; /* frequence of onboard oscilator */ - unsigned int ai_do; /* what do AI? 0=nothing, 1 to 4 mode */ - unsigned int ai_act_scan; /* how many scans we finished */ - unsigned int ai_buf_ptr; /* data buffer ptr in samples */ - unsigned int ai_n_chan; /* how many channels is measured */ - unsigned int ai_n_scanlen; /* len of actual scanlist */ - unsigned int ai_n_realscanlen; /* what we must transfer for one outgoing scan include front/back adds */ - unsigned int ai_act_dmapos; /* position in actual real stream */ - unsigned int ai_add_front; /* how many channels we must add before scan to satisfy S&H? */ - unsigned int ai_add_back; /* how many channels we must add before scan to satisfy DMA? */ - unsigned int *ai_chanlist; /* actaul chanlist */ + unsigned char AdControlReg; /* A/D control register */ + unsigned char IntControlReg; /* Interrupt control register */ + unsigned char AdFunctionReg; /* A/D function register */ + char valid; /* driver is ok */ + char ai_neverending; /* we do unlimited AI */ + unsigned int i8254_osc_base; /* frequence of onboard oscilator */ + unsigned int ai_do; /* what do AI? 0=nothing, 1 to 4 mode */ + unsigned int ai_act_scan; /* how many scans we finished */ + unsigned int ai_buf_ptr; /* data buffer ptr in samples */ + unsigned int ai_n_chan; /* how many channels is measured */ + unsigned int ai_n_scanlen; /* len of actual scanlist */ + unsigned int ai_n_realscanlen; /* + * what we must transfer for one + * outgoing scan include front/back adds + */ + unsigned int ai_act_dmapos; /* position in actual real stream */ + unsigned int ai_add_front; /* + * how many channels we must add + * before scan to satisfy S&H? + */ + unsigned int ai_add_back; /* + * how many channels we must add + * before scan to satisfy DMA? + */ + unsigned int *ai_chanlist; /* actual chanlist */ unsigned int ai_timer1; unsigned int ai_timer2; unsigned int ai_flags; - char ai12_startstop; /* measure can start/stop on external trigger */ - unsigned int ai_divisor1, ai_divisor2; /* divisors for start of measure on external start */ + char ai12_startstop; /* + * measure can start/stop + * on external trigger + */ + unsigned int ai_divisor1, ai_divisor2; /* + * divisors for start of measure + * on external start + */ unsigned int ai_data_len; short *ai_data; - short ao_data[2]; /* data output buffer */ - unsigned int ai_scans; /* number of scans to do */ - char dma_doublebuf; /* we can use double buffring */ - unsigned int dma_actbuf; /* which buffer is used now */ - short *dmabuf_virt[2]; /* pointers to begin of DMA buffer */ - unsigned long dmabuf_hw[2]; /* hw address of DMA buff */ - unsigned int dmabuf_size[2]; /* size of dma buffer in bytes */ - unsigned int dmabuf_use_size[2]; /* which size we may now used for transfer */ - unsigned int dmabuf_used_size[2]; /* which size was trully used */ + short ao_data[2]; /* data output buffer */ + unsigned int ai_scans; /* number of scans to do */ + char dma_doublebuf; /* we can use double buffring */ + unsigned int dma_actbuf; /* which buffer is used now */ + short *dmabuf_virt[2]; /* + * pointers to begin of + * DMA buffer + */ + unsigned long dmabuf_hw[2]; /* hw address of DMA buff */ + unsigned int dmabuf_size[2]; /* + * size of dma buffer in bytes + */ + unsigned int dmabuf_use_size[2]; /* + * which size we may now use + * for transfer + */ + unsigned int dmabuf_used_size[2]; /* which size was truly used */ unsigned int dmabuf_panic_size[2]; - unsigned int dmabuf_samples[2]; /* size in samples */ - int dmabuf_pages[2]; /* number of pages in buffer */ - unsigned char cnt0_users; /* bit field of 8254 CNT0 users (0-unused, 1-AO, 2-DI, 3-DO) */ - unsigned char exttrg_users; /* bit field of external trigger users (0-AI, 1-AO, 2-DI, 3-DO) */ - unsigned int cnt0_divisor; /* actual CNT0 divisor */ - void (*int_ai_func) (struct comedi_device *, struct comedi_subdevice *, unsigned short, unsigned int, unsigned short); /* ptr to actual interrupt AI function */ - unsigned char ai16bits; /* =1 16 bit card */ - unsigned char usedma; /* =1 use DMA transfer and not INT */ - unsigned char useeoshandle; /* =1 change WAKE_EOS DMA transfer to fit on every second */ - unsigned char usessh; /* =1 turn on S&H support */ - int softsshdelay; /* >0 use software S&H, numer is requested delay in ns */ - unsigned char softsshsample; /* polarity of S&H signal in sample state */ - unsigned char softsshhold; /* polarity of S&H signal in hold state */ - unsigned int ai_maskerr; /* which warning was printed */ - unsigned int ai_maskharderr; /* on which error bits stops */ - unsigned int ai_inttrig_start; /* TRIG_INT for start */ + unsigned int dmabuf_samples[2]; /* size in samples */ + int dmabuf_pages[2]; /* number of pages in buffer */ + unsigned char cnt0_users; /* + * bit field of 8254 CNT0 users + * (0-unused, 1-AO, 2-DI, 3-DO) + */ + unsigned char exttrg_users; /* + * bit field of external trigger + * users(0-AI, 1-AO, 2-DI, 3-DO) + */ + unsigned int cnt0_divisor; /* actual CNT0 divisor */ + void (*int_ai_func) (struct comedi_device *, struct comedi_subdevice *, + unsigned short, + unsigned int, + unsigned short); /* + * ptr to actual interrupt + * AI function + */ + unsigned char ai16bits; /* =1 16 bit card */ + unsigned char usedma; /* =1 use DMA transfer and not INT */ + unsigned char useeoshandle; /* + * =1 change WAKE_EOS DMA transfer + * to fit on every second + */ + unsigned char usessh; /* =1 turn on S&H support */ + int softsshdelay; /* + * >0 use software S&H, + * numer is requested delay in ns + */ + unsigned char softsshsample; /* + * polarity of S&H signal + * in sample state + */ + unsigned char softsshhold; /* + * polarity of S&H signal + * in hold state + */ + unsigned int ai_maskerr; /* which warning was printed */ + unsigned int ai_maskharderr; /* on which error bits stops */ + unsigned int ai_inttrig_start; /* TRIG_INT for start */ }; #define devpriv ((struct pci9118_private *)dev->private) @@ -346,12 +441,19 @@ static int pci9118_insn_read_ai(struct comedi_device *dev, devpriv->AdControlReg = AdControl_Int & 0xff; devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg; - outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); /* positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop */ + outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); + /* + * positive triggers, no S&H, + * no burst, burst stop, + * no post trigger, + * no about trigger, + * trigger stop + */ if (!setup_channel_list(dev, s, 1, &insn->chanspec, 0, 0, 0, 0, 0)) return -EINVAL; - outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ + outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ for (n = 0; n < insn->n; n++) { outw(0, dev->iobase + PCI9118_SOFTTRG); /* start conversion */ @@ -365,7 +467,7 @@ static int pci9118_insn_read_ai(struct comedi_device *dev, comedi_error(dev, "A/D insn timeout"); data[n] = 0; - outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ + outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ return -ETIME; conv_finish: @@ -379,7 +481,7 @@ conv_finish: } } - outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ + outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ return n; } @@ -590,11 +692,13 @@ static void interrupt_pci9118_ai_onesample(struct comedi_device *dev, #ifdef PCI9118_PARANOIDCHECK if (devpriv->ai16bits == 0) { - if ((sampl & 0x000f) != devpriv->chanlist[s->async->cur_chan]) { /* data dropout! */ + if ((sampl & 0x000f) != devpriv->chanlist[s->async->cur_chan]) { + /* data dropout! */ printk - ("comedi: A/D SAMPL - data dropout: received channel %d, expected %d!\n", - sampl & 0x000f, - devpriv->chanlist[s->async->cur_chan]); + ("comedi: A/D SAMPL - data dropout: " + "received channel %d, expected %d!\n", + sampl & 0x000f, + devpriv->chanlist[s->async->cur_chan]); s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; pci9118_ai_cancel(dev, s); comedi_event(dev, s); @@ -604,11 +708,13 @@ static void interrupt_pci9118_ai_onesample(struct comedi_device *dev, #endif cfc_write_to_buffer(s, sampl); s->async->cur_chan++; - if (s->async->cur_chan >= devpriv->ai_n_scanlen) { /* one scan done */ + if (s->async->cur_chan >= devpriv->ai_n_scanlen) { + /* one scan done */ s->async->cur_chan %= devpriv->ai_n_scanlen; devpriv->ai_act_scan++; if (!(devpriv->ai_neverending)) - if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */ + if (devpriv->ai_act_scan >= devpriv->ai_scans) { + /* all data sampled */ pci9118_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA; } @@ -650,10 +756,14 @@ static void interrupt_pci9118_ai_dma(struct comedi_device *dev, if (pci9118_decode_error_status(dev, s, int_adstat)) return; - samplesinbuf = devpriv->dmabuf_use_size[devpriv->dma_actbuf] >> 1; /* number of received real samples */ + samplesinbuf = devpriv->dmabuf_use_size[devpriv->dma_actbuf] >> 1; + /* number of received real samples */ /* DPRINTK("dma_actbuf=%d\n",devpriv->dma_actbuf); */ - if (devpriv->dma_doublebuf) { /* switch DMA buffers if is used double buffering */ + if (devpriv->dma_doublebuf) { /* + * switch DMA buffers if is used + * double buffering + */ next_dma_buf = 1 - devpriv->dma_actbuf; outl(devpriv->dmabuf_hw[next_dma_buf], devpriv->iobase_a + AMCC_OP_REG_MWAR); @@ -666,25 +776,32 @@ static void interrupt_pci9118_ai_dma(struct comedi_device *dev, } if (samplesinbuf) { - m = devpriv->ai_data_len >> 1; /* how many samples is to end of buffer */ -/* DPRINTK("samps=%d m=%d %d %d\n",samplesinbuf,m,s->async->buf_int_count,s->async->buf_int_ptr); */ + m = devpriv->ai_data_len >> 1; /* + * how many samples is to + * end of buffer + */ +/* + * DPRINTK("samps=%d m=%d %d %d\n", + * samplesinbuf,m,s->async->buf_int_count,s->async->buf_int_ptr); + */ sampls = m; move_block_from_dma(dev, s, devpriv->dmabuf_virt[devpriv->dma_actbuf], samplesinbuf); - m = m - sampls; /* m= how many samples was transfered */ + m = m - sampls; /* m= how many samples was transfered */ } /* DPRINTK("YYY\n"); */ if (!devpriv->ai_neverending) - if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */ + if (devpriv->ai_act_scan >= devpriv->ai_scans) { + /* all data sampled */ pci9118_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA; } - if (devpriv->dma_doublebuf) { /* switch dma buffers */ + if (devpriv->dma_doublebuf) { /* switch dma buffers */ devpriv->dma_actbuf = 1 - devpriv->dma_actbuf; - } else { /* restart DMA if is not used double buffering */ + } else { /* restart DMA if is not used double buffering */ outl(devpriv->dmabuf_hw[0], devpriv->iobase_a + AMCC_OP_REG_MWAR); outl(devpriv->dmabuf_use_size[0], @@ -705,39 +822,62 @@ static irqreturn_t interrupt_pci9118(int irq, void *d) unsigned int int_daq = 0, int_amcc, int_adstat; if (!dev->attached) - return IRQ_NONE; /* not fully initialized */ + return IRQ_NONE; /* not fully initialized */ - int_daq = inl(dev->iobase + PCI9118_INTSRC) & 0xf; /* get IRQ reasons from card */ - int_amcc = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR); /* get INT register from AMCC chip */ + int_daq = inl(dev->iobase + PCI9118_INTSRC) & 0xf; + /* get IRQ reasons from card */ + int_amcc = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR); + /* get INT register from AMCC chip */ -/* DPRINTK("INT daq=0x%01x amcc=0x%08x MWAR=0x%08x MWTC=0x%08x ADSTAT=0x%02x ai_do=%d\n", int_daq, int_amcc, inl(devpriv->iobase_a+AMCC_OP_REG_MWAR), inl(devpriv->iobase_a+AMCC_OP_REG_MWTC), inw(dev->iobase+PCI9118_ADSTAT)&0x1ff,devpriv->ai_do); */ +/* + * DPRINTK("INT daq=0x%01x amcc=0x%08x MWAR=0x%08x + * MWTC=0x%08x ADSTAT=0x%02x ai_do=%d\n", + * int_daq, int_amcc, inl(devpriv->iobase_a+AMCC_OP_REG_MWAR), + * inl(devpriv->iobase_a+AMCC_OP_REG_MWTC), + * inw(dev->iobase+PCI9118_ADSTAT)&0x1ff,devpriv->ai_do); + */ if ((!int_daq) && (!(int_amcc & ANY_S593X_INT))) - return IRQ_NONE; /* interrupt from other source */ + return IRQ_NONE; /* interrupt from other source */ - outl(int_amcc | 0x00ff0000, devpriv->iobase_a + AMCC_OP_REG_INTCSR); /* shutdown IRQ reasons in AMCC */ + outl(int_amcc | 0x00ff0000, devpriv->iobase_a + AMCC_OP_REG_INTCSR); + /* shutdown IRQ reasons in AMCC */ - int_adstat = inw(dev->iobase + PCI9118_ADSTAT) & 0x1ff; /* get STATUS register */ + int_adstat = inw(dev->iobase + PCI9118_ADSTAT) & 0x1ff; + /* get STATUS register */ if (devpriv->ai_do) { if (devpriv->ai12_startstop) - if ((int_adstat & AdStatus_DTH) && (int_daq & Int_DTrg)) { /* start stop of measure */ + if ((int_adstat & AdStatus_DTH) && + (int_daq & Int_DTrg)) { + /* start stop of measure */ if (devpriv->ai12_startstop & START_AI_EXT) { devpriv->ai12_startstop &= ~START_AI_EXT; if (!(devpriv->ai12_startstop & - STOP_AI_EXT)) - pci9118_exttrg_del(dev, EXTTRG_AI); /* deactivate EXT trigger */ - start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1, devpriv->ai_divisor2); /* start pacer */ + STOP_AI_EXT)) + pci9118_exttrg_del + (dev, EXTTRG_AI); + /* deactivate EXT trigger */ + start_pacer(dev, devpriv->ai_do, + devpriv->ai_divisor1, + devpriv->ai_divisor2); + /* start pacer */ outl(devpriv->AdControlReg, - dev->iobase + PCI9118_ADCNTRL); + dev->iobase + PCI9118_ADCNTRL); } else { if (devpriv->ai12_startstop & - STOP_AI_EXT) { + STOP_AI_EXT) { devpriv->ai12_startstop &= - ~STOP_AI_EXT; - pci9118_exttrg_del(dev, EXTTRG_AI); /* deactivate EXT trigger */ - devpriv->ai_neverending = 0; /* well, on next interrupt from DMA/EOC measure will stop */ + ~STOP_AI_EXT; + pci9118_exttrg_del + (dev, EXTTRG_AI); + /* deactivate EXT trigger */ + devpriv->ai_neverending = 0; + /* + * well, on next interrupt from + * DMA/EOC measure will stop + */ } } } @@ -821,7 +961,11 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* + * step 2: + * make sure trigger sources are + * unique and mutually compatible + */ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT) { @@ -1026,7 +1170,7 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, if (cmd->chanlist) if (!check_channel_list(dev, s, cmd->chanlist_len, cmd->chanlist, 0, 0)) - return 5; /* incorrect channels list */ + return 5; /* incorrect channels list */ return 0; } @@ -1043,88 +1187,101 @@ static int Compute_and_setup_dma(struct comedi_device *dev) dmalen1 = devpriv->dmabuf_size[1]; DPRINTK("1 dmalen0=%d dmalen1=%d ai_data_len=%d\n", dmalen0, dmalen1, devpriv->ai_data_len); - /* isn't output buff smaller that our DMA buff? */ + /* isn't output buff smaller that our DMA buff? */ if (dmalen0 > (devpriv->ai_data_len)) { - dmalen0 = devpriv->ai_data_len & ~3L; /* allign to 32bit down */ + dmalen0 = devpriv->ai_data_len & ~3L; /* + * align to 32bit down + */ } if (dmalen1 > (devpriv->ai_data_len)) { - dmalen1 = devpriv->ai_data_len & ~3L; /* allign to 32bit down */ + dmalen1 = devpriv->ai_data_len & ~3L; /* + * align to 32bit down + */ } DPRINTK("2 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1); - /* we want wake up every scan? */ + /* we want wake up every scan? */ if (devpriv->ai_flags & TRIG_WAKE_EOS) { if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) { - /* uff, too short DMA buffer, disable EOS support! */ + /* uff, too short DMA buffer, disable EOS support! */ devpriv->ai_flags &= (~TRIG_WAKE_EOS); printk - ("comedi%d: WAR: DMA0 buf too short, cann't support TRIG_WAKE_EOS (%d<%d)\n", + ("comedi%d: WAR: DMA0 buf too short, can't " + "support TRIG_WAKE_EOS (%d<%d)\n", dev->minor, dmalen0, devpriv->ai_n_realscanlen << 1); } else { - /* short first DMA buffer to one scan */ + /* short first DMA buffer to one scan */ dmalen0 = devpriv->ai_n_realscanlen << 1; DPRINTK - ("21 dmalen0=%d ai_n_realscanlen=%d useeoshandle=%d\n", - dmalen0, devpriv->ai_n_realscanlen, - devpriv->useeoshandle); + ("21 dmalen0=%d ai_n_realscanlen=%d " + "useeoshandle=%d\n", + dmalen0, devpriv->ai_n_realscanlen, + devpriv->useeoshandle); if (devpriv->useeoshandle) dmalen0 += 2; if (dmalen0 < 4) { printk - ("comedi%d: ERR: DMA0 buf len bug? (%d<4)\n", - dev->minor, dmalen0); + ("comedi%d: ERR: DMA0 buf len bug? " + "(%d<4)\n", + dev->minor, dmalen0); dmalen0 = 4; } } } if (devpriv->ai_flags & TRIG_WAKE_EOS) { if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) { - /* uff, too short DMA buffer, disable EOS support! */ + /* uff, too short DMA buffer, disable EOS support! */ devpriv->ai_flags &= (~TRIG_WAKE_EOS); printk - ("comedi%d: WAR: DMA1 buf too short, cann't support TRIG_WAKE_EOS (%d<%d)\n", + ("comedi%d: WAR: DMA1 buf too short, " + "can't support TRIG_WAKE_EOS (%d<%d)\n", dev->minor, dmalen1, devpriv->ai_n_realscanlen << 1); } else { - /* short second DMA buffer to one scan */ + /* short second DMA buffer to one scan */ dmalen1 = devpriv->ai_n_realscanlen << 1; DPRINTK - ("22 dmalen1=%d ai_n_realscanlen=%d useeoshandle=%d\n", + ("22 dmalen1=%d ai_n_realscanlen=%d " + "useeoshandle=%d\n", dmalen1, devpriv->ai_n_realscanlen, devpriv->useeoshandle); if (devpriv->useeoshandle) dmalen1 -= 2; if (dmalen1 < 4) { printk - ("comedi%d: ERR: DMA1 buf len bug? (%d<4)\n", - dev->minor, dmalen1); + ("comedi%d: ERR: DMA1 buf len bug? " + "(%d<4)\n", + dev->minor, dmalen1); dmalen1 = 4; } } } DPRINTK("3 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1); - /* transfer without TRIG_WAKE_EOS */ + /* transfer without TRIG_WAKE_EOS */ if (!(devpriv->ai_flags & TRIG_WAKE_EOS)) { - /* if it's possible then allign DMA buffers to length of scan */ + /* if it's possible then allign DMA buffers to length of scan */ i = dmalen0; dmalen0 = (dmalen0 / (devpriv->ai_n_realscanlen << 1)) * (devpriv->ai_n_realscanlen << 1); dmalen0 &= ~3L; if (!dmalen0) - dmalen0 = i; /* uff. very long scan? */ + dmalen0 = i; /* uff. very long scan? */ i = dmalen1; dmalen1 = (dmalen1 / (devpriv->ai_n_realscanlen << 1)) * (devpriv->ai_n_realscanlen << 1); dmalen1 &= ~3L; if (!dmalen1) - dmalen1 = i; /* uff. very long scan? */ - /* if measure isn't neverending then test, if it whole fits into one or two DMA buffers */ + dmalen1 = i; /* uff. very long scan? */ + /* + * if measure isn't neverending then test, if it fits whole + * into one or two DMA buffers + */ if (!devpriv->ai_neverending) { - /* fits whole measure into one DMA buffer? */ + /* fits whole measure into one DMA buffer? */ if (dmalen0 > ((devpriv->ai_n_realscanlen << 1) * devpriv->ai_scans)) { @@ -1138,7 +1295,10 @@ static int Compute_and_setup_dma(struct comedi_device *dev) DPRINTK("3.1 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1); dmalen0 &= ~3L; - } else { /* fits whole measure into two DMA buffer? */ + } else { /* + * fits whole measure into + * two DMA buffer? + */ if (dmalen1 > ((devpriv->ai_n_realscanlen << 1) * devpriv->ai_scans - dmalen0)) @@ -1154,7 +1314,7 @@ static int Compute_and_setup_dma(struct comedi_device *dev) DPRINTK("4 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1); - /* these DMA buffer size we'll be used */ + /* these DMA buffer size will be used */ devpriv->dma_actbuf = 0; devpriv->dmabuf_use_size[0] = dmalen0; devpriv->dmabuf_use_size[1] = dmalen1; @@ -1176,10 +1336,11 @@ static int Compute_and_setup_dma(struct comedi_device *dev) } #endif - outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS), devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */ + outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS), + devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */ outl(devpriv->dmabuf_hw[0], devpriv->iobase_a + AMCC_OP_REG_MWAR); outl(devpriv->dmabuf_use_size[0], devpriv->iobase_a + AMCC_OP_REG_MWTC); - /* init DMA transfer */ + /* init DMA transfer */ outl(0x00000000 | AINT_WRITE_COMPL, devpriv->iobase_a + AMCC_OP_REG_INTCSR); /* outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR); */ @@ -1187,7 +1348,9 @@ static int Compute_and_setup_dma(struct comedi_device *dev) outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) | RESET_A2P_FLAGS | A2P_HI_PRIORITY | EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_MCSR); - outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_INTCSR); /* allow bus mastering */ + outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS, + devpriv->iobase_a + AMCC_OP_REG_INTCSR); + /* allow bus mastering */ DPRINTK("adl_pci9118 EDBG: END: Compute_and_setup_dma()\n"); return 0; @@ -1220,17 +1383,21 @@ static int pci9118_ai_docmd_sampl(struct comedi_device *dev, return -EIO; }; - devpriv->int_ai_func = interrupt_pci9118_ai_onesample; /* transfer function */ + devpriv->int_ai_func = interrupt_pci9118_ai_onesample; + /* transfer function */ if (devpriv->ai12_startstop) - pci9118_exttrg_add(dev, EXTTRG_AI); /* activate EXT trigger */ + pci9118_exttrg_add(dev, EXTTRG_AI); + /* activate EXT trigger */ if ((devpriv->ai_do == 1) || (devpriv->ai_do == 2)) devpriv->IntControlReg |= Int_Timer; devpriv->AdControlReg |= AdControl_Int; - outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, devpriv->iobase_a + AMCC_OP_REG_INTCSR); /* allow INT in AMCC */ + outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, + devpriv->iobase_a + AMCC_OP_REG_INTCSR); + /* allow INT in AMCC */ if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) { outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); @@ -1296,10 +1463,12 @@ static int pci9118_ai_docmd_dma(struct comedi_device *dev, }; if (devpriv->ai12_startstop) { - pci9118_exttrg_add(dev, EXTTRG_AI); /* activate EXT trigger */ + pci9118_exttrg_add(dev, EXTTRG_AI); + /* activate EXT trigger */ } - devpriv->int_ai_func = interrupt_pci9118_ai_dma; /* transfer function */ + devpriv->int_ai_func = interrupt_pci9118_ai_dma; + /* transfer function */ outl(0x02000000 | AINT_WRITE_COMPL, devpriv->iobase_a + AMCC_OP_REG_INTCSR); @@ -1342,7 +1511,7 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_add_back = 0; devpriv->ai_maskerr = 0x10e; - /* prepare for start/stop conditions */ + /* prepare for start/stop conditions */ if (cmd->start_src == TRIG_EXT) devpriv->ai12_startstop |= START_AI_EXT; if (cmd->stop_src == TRIG_EXT) { @@ -1369,10 +1538,10 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_scans = 0; } - /* use sample&hold signal? */ + /* use sample&hold signal? */ if (cmd->convert_src == TRIG_NOW) { devpriv->usessh = 1; - } /* yes */ + } /* yes */ else { devpriv->usessh = 0; } /* no */ @@ -1381,7 +1550,10 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_neverending, devpriv->ai_scans, devpriv->usessh, devpriv->ai12_startstop); - /* use additional sample at end of every scan to satisty DMA 32 bit transfer? */ + /* + * use additional sample at end of every scan + * to satisty DMA 32 bit transfer? + */ devpriv->ai_add_front = 0; devpriv->ai_add_back = 0; devpriv->useeoshandle = 0; @@ -1393,27 +1565,44 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_add_back = 1; } if (cmd->convert_src == TRIG_TIMER) { - devpriv->usedma = 0; /* use INT transfer if scanlist have only one channel */ + devpriv->usedma = 0; + /* + * use INT transfer if scanlist + * have only one channel + */ } } if ((cmd->flags & TRIG_WAKE_EOS) && (devpriv->ai_n_scanlen & 1) && (devpriv->ai_n_scanlen > 1)) { if (cmd->scan_begin_src == TRIG_FOLLOW) { - /* vpriv->useeoshandle=1; // change DMA transfer block to fit EOS on every second call */ - devpriv->usedma = 0; /* XXX maybe can be corrected to use 16 bit DMA */ - } else { /* well, we must insert one sample to end of EOS to meet 32 bit transfer */ + /* + * vpriv->useeoshandle=1; // change DMA transfer + * block to fit EOS on every second call + */ + devpriv->usedma = 0; + /* + * XXX maybe can be corrected to use 16 bit DMA + */ + } else { /* + * well, we must insert one sample + * to end of EOS to meet 32 bit transfer + */ devpriv->ai_add_back = 1; } } - } else { /* interrupt transfer don't need any correction */ + } else { /* interrupt transfer don't need any correction */ devpriv->usedma = 0; } - /* we need software S&H signal? It add two samples before every scan as minimum */ + /* + * we need software S&H signal? + * It adds two samples before every scan as minimum + */ if (devpriv->usessh && devpriv->softsshdelay) { devpriv->ai_add_front = 2; - if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) { /* move it to front */ + if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) { + /* move it to front */ devpriv->ai_add_front++; devpriv->ai_add_back = 0; } @@ -1422,17 +1611,22 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) addchans = devpriv->softsshdelay / cmd->convert_arg; if (devpriv->softsshdelay % cmd->convert_arg) addchans++; - if (addchans > (devpriv->ai_add_front - 1)) { /* uff, still short :-( */ + if (addchans > (devpriv->ai_add_front - 1)) { + /* uff, still short */ devpriv->ai_add_front = addchans + 1; if (devpriv->usedma == 1) if ((devpriv->ai_add_front + devpriv->ai_n_chan + devpriv->ai_add_back) & 1) - devpriv->ai_add_front++; /* round up to 32 bit */ + devpriv->ai_add_front++; + /* round up to 32 bit */ } } - /* well, we now know what must be all added */ - devpriv->ai_n_realscanlen = /* what we must take from card in real to have ai_n_scanlen on output? */ + /* well, we now know what must be all added */ + devpriv->ai_n_realscanlen = /* + * what we must take from card in real + * to have ai_n_scanlen on output? + */ (devpriv->ai_add_front + devpriv->ai_n_chan + devpriv->ai_add_back) * (devpriv->ai_n_scanlen / devpriv->ai_n_chan); @@ -1443,7 +1637,7 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_n_chan, devpriv->ai_add_back, devpriv->ai_n_scanlen); - /* check and setup channel list */ + /* check and setup channel list */ if (!check_channel_list(dev, s, devpriv->ai_n_chan, devpriv->ai_chanlist, devpriv->ai_add_front, devpriv->ai_add_back)) @@ -1454,9 +1648,16 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->useeoshandle)) return -EINVAL; - /* compute timers settings */ - /* simplest way, fr=4Mhz/(tim1*tim2), channel manipulation without timers effect */ - if (((cmd->scan_begin_src == TRIG_FOLLOW) || (cmd->scan_begin_src == TRIG_EXT) || (cmd->scan_begin_src == TRIG_INT)) && (cmd->convert_src == TRIG_TIMER)) { /* both timer is used for one time */ + /* compute timers settings */ + /* + * simplest way, fr=4Mhz/(tim1*tim2), + * channel manipulation without timers effect + */ + if (((cmd->scan_begin_src == TRIG_FOLLOW) || + (cmd->scan_begin_src == TRIG_EXT) || + (cmd->scan_begin_src == TRIG_INT)) && + (cmd->convert_src == TRIG_TIMER)) { + /* both timer is used for one time */ if (cmd->scan_begin_src == TRIG_EXT) { devpriv->ai_do = 4; } else { @@ -1472,10 +1673,14 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_timer2 = cmd->convert_arg; } - if ((cmd->scan_begin_src == TRIG_TIMER) && ((cmd->convert_src == TRIG_TIMER) || (cmd->convert_src == TRIG_NOW))) { /* double timed action */ + if ((cmd->scan_begin_src == TRIG_TIMER) && + ((cmd->convert_src == TRIG_TIMER) || + (cmd->convert_src == TRIG_NOW))) { + /* double timed action */ if (!devpriv->usedma) { comedi_error(dev, - "cmd->scan_begin_src=TRIG_TIMER works only with bus mastering!"); + "cmd->scan_begin_src=TRIG_TIMER works " + "only with bus mastering!"); return -EIO; } @@ -1496,15 +1701,27 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_do = 3; } - start_pacer(dev, -1, 0, 0); /* stop pacer */ + start_pacer(dev, -1, 0, 0); /* stop pacer */ - devpriv->AdControlReg = 0; /* bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable DMA */ + devpriv->AdControlReg = 0; /* + * bipolar, S.E., use 8254, stop 8354, + * internal trigger, soft trigger, + * disable DMA + */ outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); - devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg; /* positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop */ + devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg; + /* + * positive triggers, no S&H, no burst, + * burst stop, no post trigger, + * no about trigger, trigger stop + */ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); udelay(1); - outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ - inl(dev->iobase + PCI9118_ADSTAT); /* flush A/D and INT status register */ + outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ + inl(dev->iobase + PCI9118_ADSTAT); /* + * flush A/D and INT + * status register + */ inl(dev->iobase + PCI9118_INTSRC); devpriv->ai_act_scan = 0; @@ -1537,33 +1754,37 @@ static int check_channel_list(struct comedi_device *dev, } if ((frontadd + n_chan + backadd) > s->len_chanlist) { printk - ("comedi%d: range/channel list is too long for actual configuration (%d>%d)!", + ("comedi%d: range/channel list is too long for " + "actual configuration (%d>%d)!", dev->minor, n_chan, s->len_chanlist - frontadd - backadd); return 0; } if (CR_AREF(chanlist[0]) == AREF_DIFF) - differencial = 1; /* all input must be diff */ + differencial = 1; /* all input must be diff */ if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES) - bipolar = 1; /* all input must be bipolar */ + bipolar = 1; /* all input must be bipolar */ if (n_chan > 1) - for (i = 1; i < n_chan; i++) { /* check S.E/diff */ + for (i = 1; i < n_chan; i++) { /* check S.E/diff */ if ((CR_AREF(chanlist[i]) == AREF_DIFF) != (differencial)) { comedi_error(dev, - "Differencial and single ended inputs cann't be mixtured!"); + "Differencial and single ended " + "inputs can't be mixtured!"); return 0; } if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) != (bipolar)) { comedi_error(dev, - "Bipolar and unipolar ranges cann't be mixtured!"); + "Bipolar and unipolar ranges " + "can't be mixtured!"); return 0; } if ((!devpriv->usemux) & (differencial) & (CR_CHAN(chanlist[i]) >= this_board->n_aichand)) { comedi_error(dev, - "If AREF_DIFF is used then is available only first 8 channels!"); + "If AREF_DIFF is used then is " + "available only first 8 channels!"); return 0; } } @@ -1583,7 +1804,8 @@ static int setup_channel_list(struct comedi_device *dev, unsigned int scanquad, gain, ssh = 0x00; DPRINTK - ("adl_pci9118 EDBG: BGN: setup_channel_list(%d,.,%d,.,%d,%d,%d,%d)\n", + ("adl_pci9118 EDBG: BGN: setup_channel_list" + "(%d,.,%d,.,%d,%d,%d,%d)\n", dev->minor, n_chan, rot, frontadd, backadd, usedma); if (usedma == 1) { @@ -1592,27 +1814,33 @@ static int setup_channel_list(struct comedi_device *dev, } if (CR_AREF(chanlist[0]) == AREF_DIFF) - differencial = 1; /* all input must be diff */ + differencial = 1; /* all input must be diff */ if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES) - bipolar = 1; /* all input must be bipolar */ + bipolar = 1; /* all input must be bipolar */ - /* All is ok, so we can setup channel/range list */ + /* All is ok, so we can setup channel/range list */ if (!bipolar) { - devpriv->AdControlReg |= AdControl_UniP; /* set unibipolar */ + devpriv->AdControlReg |= AdControl_UniP; + /* set unibipolar */ } else { - devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff); /* enable bipolar */ + devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff); + /* enable bipolar */ } if (differencial) { - devpriv->AdControlReg |= AdControl_Diff; /* enable diff inputs */ + devpriv->AdControlReg |= AdControl_Diff; + /* enable diff inputs */ } else { - devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff); /* set single ended inputs */ + devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff); + /* set single ended inputs */ } - outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); /* setup mode */ + outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); + /* setup mode */ - outl(2, dev->iobase + PCI9118_SCANMOD); /* gods know why this sequence! */ + outl(2, dev->iobase + PCI9118_SCANMOD); + /* gods know why this sequence! */ outl(0, dev->iobase + PCI9118_SCANMOD); outl(1, dev->iobase + PCI9118_SCANMOD); @@ -1622,12 +1850,15 @@ static int setup_channel_list(struct comedi_device *dev, devpriv->chanlist[i] = 0x55aa; #endif - if (frontadd) { /* insert channels for S&H */ + if (frontadd) { /* insert channels for S&H */ ssh = devpriv->softsshsample; DPRINTK("FA: %04x: ", ssh); - for (i = 0; i < frontadd; i++) { /* store range list to card */ - scanquad = CR_CHAN(chanlist[0]); /* get channel number; */ - gain = CR_RANGE(chanlist[0]); /* get gain number */ + for (i = 0; i < frontadd; i++) { + /* store range list to card */ + scanquad = CR_CHAN(chanlist[0]); + /* get channel number; */ + gain = CR_RANGE(chanlist[0]); + /* get gain number */ scanquad |= ((gain & 0x03) << 8); outl(scanquad | ssh, dev->iobase + PCI9118_GAIN); DPRINTK("%02x ", scanquad | ssh); @@ -1637,23 +1868,24 @@ static int setup_channel_list(struct comedi_device *dev, } DPRINTK("SL: ", ssh); - for (i = 0; i < n_chan; i++) { /* store range list to card */ - scanquad = CR_CHAN(chanlist[i]); /* get channel number; */ + for (i = 0; i < n_chan; i++) { /* store range list to card */ + scanquad = CR_CHAN(chanlist[i]); /* get channel number */ #ifdef PCI9118_PARANOIDCHECK devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot; #endif - gain = CR_RANGE(chanlist[i]); /* get gain number */ + gain = CR_RANGE(chanlist[i]); /* get gain number */ scanquad |= ((gain & 0x03) << 8); outl(scanquad | ssh, dev->iobase + PCI9118_GAIN); DPRINTK("%02x ", scanquad | ssh); } DPRINTK("\n "); - if (backadd) { /* insert channels for fit onto 32bit DMA */ + if (backadd) { /* insert channels for fit onto 32bit DMA */ DPRINTK("BA: %04x: ", ssh); - for (i = 0; i < backadd; i++) { /* store range list to card */ - scanquad = CR_CHAN(chanlist[0]); /* get channel number; */ - gain = CR_RANGE(chanlist[0]); /* get gain number */ + for (i = 0; i < backadd; i++) { /* store range list to card */ + scanquad = CR_CHAN(chanlist[0]); + /* get channel number */ + gain = CR_RANGE(chanlist[0]); /* get gain number */ scanquad |= ((gain & 0x03) << 8); outl(scanquad | ssh, dev->iobase + PCI9118_GAIN); DPRINTK("%02x ", scanquad | ssh); @@ -1661,13 +1893,16 @@ static int setup_channel_list(struct comedi_device *dev, DPRINTK("\n "); } #ifdef PCI9118_PARANOIDCHECK - devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma]; /* for 32bit oerations */ + devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma]; + /* for 32bit operations */ if (useeos) { - for (i = 1; i < n_chan; i++) { /* store range list to card */ + for (i = 1; i < n_chan; i++) { /* store range list to card */ devpriv->chanlist[(n_chan + i) ^ usedma] = (CR_CHAN(chanlist[i]) & 0xf) << rot; } - devpriv->chanlist[(2 * n_chan) ^ usedma] = devpriv->chanlist[0 ^ usedma]; /* for 32bit oerations */ + devpriv->chanlist[(2 * n_chan) ^ usedma] = + devpriv->chanlist[0 ^ usedma]; + /* for 32bit operations */ useeos = 2; } else { useeos = 1; @@ -1680,11 +1915,11 @@ static int setup_channel_list(struct comedi_device *dev, DPRINTK("\n "); #endif #endif - outl(0, dev->iobase + PCI9118_SCANMOD); /* close scan queue */ -/* udelay(100); important delay, or first sample will be cripled */ + outl(0, dev->iobase + PCI9118_SCANMOD); /* close scan queue */ + /* udelay(100); important delay, or first sample will be crippled */ DPRINTK("adl_pci9118 EDBG: END: setup_channel_list()\n"); - return 1; /* we can serve this with scan logic */ + return 1; /* we can serve this with scan logic */ } /* @@ -1699,7 +1934,8 @@ static void pci9118_calc_divisors(char mode, struct comedi_device *dev, char usessh, unsigned int chnsshfront) { DPRINTK - ("adl_pci9118 EDBG: BGN: pci9118_calc_divisors(%d,%d,.,%u,%u,%u,%d,.,.,,%u,%u)\n", + ("adl_pci9118 EDBG: BGN: pci9118_calc_divisors" + "(%d,%d,.,%u,%u,%u,%d,.,.,,%u,%u)\n", mode, dev->minor, *tim1, *tim2, flags, chans, usessh, chnsshfront); switch (mode) { case 1: @@ -1716,17 +1952,18 @@ static void pci9118_calc_divisors(char mode, struct comedi_device *dev, *tim2 = this_board->ai_ns_min; DPRINTK("1 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, *tim1, *tim2); - *div1 = *tim2 / devpriv->i8254_osc_base; /* convert timer (burst) */ + *div1 = *tim2 / devpriv->i8254_osc_base; + /* convert timer (burst) */ DPRINTK("2 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, *tim1, *tim2); if (*div1 < this_board->ai_pacer_min) *div1 = this_board->ai_pacer_min; DPRINTK("3 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, *tim1, *tim2); - *div2 = *tim1 / devpriv->i8254_osc_base; /* scan timer */ + *div2 = *tim1 / devpriv->i8254_osc_base; /* scan timer */ DPRINTK("4 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, *tim1, *tim2); - *div2 = *div2 / *div1; /* major timer is c1*c2 */ + *div2 = *div2 / *div1; /* major timer is c1*c2 */ DPRINTK("5 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, *tim1, *tim2); if (*div2 < chans) @@ -1734,9 +1971,10 @@ static void pci9118_calc_divisors(char mode, struct comedi_device *dev, DPRINTK("6 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, *tim1, *tim2); - *tim2 = *div1 * devpriv->i8254_osc_base; /* real convert timer */ + *tim2 = *div1 * devpriv->i8254_osc_base; + /* real convert timer */ - if (usessh & (chnsshfront == 0)) /* use BSSH signal */ + if (usessh & (chnsshfront == 0)) /* use BSSH signal */ if (*div2 < (chans + 2)) *div2 = chans + 2; @@ -1776,11 +2014,13 @@ static void start_pacer(struct comedi_device *dev, int mode, static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source) { if (source > 3) - return -1; /* incorrect source */ + return -1; /* incorrect source */ devpriv->exttrg_users |= (1 << source); devpriv->IntControlReg |= Int_DTrg; outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); - outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, devpriv->iobase_a + AMCC_OP_REG_INTCSR); /* allow INT in AMCC */ + outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, + devpriv->iobase_a + AMCC_OP_REG_INTCSR); + /* allow INT in AMCC */ return 0; } @@ -1790,12 +2030,15 @@ static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source) static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source) { if (source > 3) - return -1; /* incorrect source */ + return -1; /* incorrect source */ devpriv->exttrg_users &= ~(1 << source); - if (!devpriv->exttrg_users) { /* shutdown ext trg intterrupts */ + if (!devpriv->exttrg_users) { /* shutdown ext trg intterrupts */ devpriv->IntControlReg &= ~Int_DTrg; - if (!devpriv->IntControlReg) /* all IRQ disabled */ - outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) & (~0x00001f00), devpriv->iobase_a + AMCC_OP_REG_INTCSR); /* disable int in AMCC */ + if (!devpriv->IntControlReg) /* all IRQ disabled */ + outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) & + (~0x00001f00), + devpriv->iobase_a + AMCC_OP_REG_INTCSR); + /* disable int in AMCC */ outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); } return 0; @@ -1808,17 +2051,29 @@ static int pci9118_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { if (devpriv->usedma) - outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS), devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */ + outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & + (~EN_A2P_TRANSFERS), + devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */ pci9118_exttrg_del(dev, EXTTRG_AI); - start_pacer(dev, 0, 0, 0); /* stop 8254 counters */ + start_pacer(dev, 0, 0, 0); /* stop 8254 counters */ devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg; - outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); /* positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop */ + outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); + /* + * positive triggers, no S&H, no burst, + * burst stop, no post trigger, + * no about trigger, trigger stop + */ devpriv->AdControlReg = 0x00; - outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); /* bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable INT and DMA */ + outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); + /* + * bipolar, S.E., use 8254, stop 8354, + * internal trigger, soft trigger, + * disable INT and DMA + */ outl(0, dev->iobase + PCI9118_BURST); outl(1, dev->iobase + PCI9118_SCANMOD); - outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */ - outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ + outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */ + outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ devpriv->ai_do = 0; devpriv->usedma = 0; @@ -1832,7 +2087,9 @@ static int pci9118_ai_cancel(struct comedi_device *dev, devpriv->dma_actbuf = 0; if (!devpriv->IntControlReg) - outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, devpriv->iobase_a + AMCC_OP_REG_INTCSR); /* allow INT in AMCC */ + outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, + devpriv->iobase_a + AMCC_OP_REG_INTCSR); + /* allow INT in AMCC */ return 0; } @@ -1845,31 +2102,52 @@ static int pci9118_reset(struct comedi_device *dev) devpriv->IntControlReg = 0; devpriv->exttrg_users = 0; inl(dev->iobase + PCI9118_INTCTRL); - outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); /* disable interrupts source */ + outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); + /* disable interrupts source */ outl(0x30, dev->iobase + PCI9118_CNTCTRL); /* outl(0xb4, dev->iobase + PCI9118_CNTCTRL); */ - start_pacer(dev, 0, 0, 0); /* stop 8254 counters */ + start_pacer(dev, 0, 0, 0); /* stop 8254 counters */ devpriv->AdControlReg = 0; - outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); /* bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable INT and DMA */ + outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); + /* + * bipolar, S.E., use 8254, + * stop 8354, internal trigger, + * soft trigger, + * disable INT and DMA + */ outl(0, dev->iobase + PCI9118_BURST); outl(1, dev->iobase + PCI9118_SCANMOD); - outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */ + outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */ devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg; - outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); /* positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop */ + outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); + /* + * positive triggers, no S&H, + * no burst, burst stop, + * no post trigger, + * no about trigger, + * trigger stop + */ devpriv->ao_data[0] = 2047; devpriv->ao_data[1] = 2047; - outl(devpriv->ao_data[0], dev->iobase + PCI9118_DA1); /* reset A/D outs to 0V */ + outl(devpriv->ao_data[0], dev->iobase + PCI9118_DA1); + /* reset A/D outs to 0V */ outl(devpriv->ao_data[1], dev->iobase + PCI9118_DA2); - outl(0, dev->iobase + PCI9118_DO); /* reset digi outs to L */ + outl(0, dev->iobase + PCI9118_DO); /* reset digi outs to L */ udelay(10); inl(dev->iobase + PCI9118_AD_DATA); - outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ - outl(0, dev->iobase + PCI9118_INTSRC); /* remove INT requests */ - inl(dev->iobase + PCI9118_ADSTAT); /* flush A/D status register */ - inl(dev->iobase + PCI9118_INTSRC); /* flush INT requests */ + outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ + outl(0, dev->iobase + PCI9118_INTSRC); /* remove INT requests */ + inl(dev->iobase + PCI9118_ADSTAT); /* flush A/D status register */ + inl(dev->iobase + PCI9118_INTSRC); /* flush INT requests */ devpriv->AdControlReg = 0; - outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); /* bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable INT and DMA */ + outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); + /* + * bipolar, S.E., use 8254, + * stop 8354, internal trigger, + * soft trigger, + * disable INT and DMA + */ devpriv->cnt0_users = 0; devpriv->exttrg_users = 0; @@ -1899,7 +2177,7 @@ static int pci9118_attach(struct comedi_device *dev, opt_bus = it->options[0]; opt_slot = it->options[1]; if (it->options[3] & 1) { - master = 0; /* user don't want use bus master */ + master = 0; /* user don't want use bus master */ } else { master = 1; } @@ -1968,7 +2246,7 @@ static int pci9118_attach(struct comedi_device *dev, pci9118_reset(dev); if (it->options[3] & 2) - irq = 0; /* user don't want use IRQ */ + irq = 0; /* user don't want use IRQ */ if (irq > 0) { if (request_irq(irq, interrupt_pci9118, IRQF_SHARED, "ADLink PCI-9118", dev)) { @@ -1984,7 +2262,7 @@ static int pci9118_attach(struct comedi_device *dev, dev->irq = irq; - if (master) { /* alloc DMA buffers */ + if (master) { /* alloc DMA buffers */ devpriv->dma_doublebuf = 0; for (i = 0; i < 2; i++) { for (pages = 4; pages >= 0; pages--) { @@ -2024,16 +2302,18 @@ static int pci9118_attach(struct comedi_device *dev, if (it->options[2] > 0) { devpriv->usemux = it->options[2]; if (devpriv->usemux > 256) - devpriv->usemux = 256; /* max 256 channels! */ + devpriv->usemux = 256; /* max 256 channels! */ if (it->options[4] > 0) if (devpriv->usemux > 128) { - devpriv->usemux = 128; /* max 128 channels with softare S&H! */ + devpriv->usemux = 128; + /* max 128 channels with softare S&H! */ } printk(", ext. mux %d channels", devpriv->usemux); } devpriv->softsshdelay = it->options[4]; - if (devpriv->softsshdelay < 0) { /* select sample&hold signal polarity */ + if (devpriv->softsshdelay < 0) { + /* select sample&hold signal polarity */ devpriv->softsshdelay = -devpriv->softsshdelay; devpriv->softsshsample = 0x80; devpriv->softsshhold = 0x00; @@ -2045,7 +2325,8 @@ static int pci9118_attach(struct comedi_device *dev, printk(".\n"); pci_read_config_word(devpriv->pcidev, PCI_COMMAND, &u16w); - pci_write_config_word(devpriv->pcidev, PCI_COMMAND, u16w | 64); /* Enable parity check for parity error */ + pci_write_config_word(devpriv->pcidev, PCI_COMMAND, u16w | 64); + /* Enable parity check for parity error */ ret = alloc_subdevices(dev, 4); if (ret < 0) @@ -2103,9 +2384,10 @@ static int pci9118_attach(struct comedi_device *dev, s->insn_bits = pci9118_insn_bits_do; devpriv->valid = 1; - devpriv->i8254_osc_base = 250; /* 250ns=4MHz */ - devpriv->ai_maskharderr = 0x10a; /* default measure crash condition */ - if (it->options[5]) /* disable some requested */ + devpriv->i8254_osc_base = 250; /* 250ns=4MHz */ + devpriv->ai_maskharderr = 0x10a; + /* default measure crash condition */ + if (it->options[5]) /* disable some requested */ devpriv->ai_maskharderr &= ~it->options[5]; switch (this_board->ai_maxdata) { -- cgit v1.2.3 From cf8d3af5aed0d7bc40e8966b45aeced7c7bf1bef Mon Sep 17 00:00:00 2001 From: Maurice Dawson Date: Fri, 19 Mar 2010 14:20:10 +0000 Subject: Staging: comedi: fix KERN_facility level coding style issue in adl_pci9118.c This is a patch to the adl_pci9118.c file that fixes WARNING: printk() should include KERN_facility level found by the checkpatch.pl tool Signed-off-by: Maurice Dawson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9118.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 4f9fd7dd0cf2..2205113ee435 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -750,9 +750,8 @@ static void interrupt_pci9118_ai_dma(struct comedi_device *dev, comedi_event(dev, s); return; } - if (int_adstat & devpriv->ai_maskerr) -/* if (int_adstat & 0x106) */ + /* if (int_adstat & 0x106) */ if (pci9118_decode_error_status(dev, s, int_adstat)) return; @@ -2215,10 +2214,10 @@ static int pci9118_attach(struct comedi_device *dev, if (!pcidev) { if (opt_bus || opt_slot) { - printk(" - Card at b:s %d:%d %s\n", + printk(KERN_ERR " - Card at b:s %d:%d %s\n", opt_bus, opt_slot, errstr); } else { - printk(" - Card %s\n", errstr); + printk(KERN_ERR " - Card %s\n", errstr); } return -EIO; } @@ -2234,8 +2233,8 @@ static int pci9118_attach(struct comedi_device *dev, iobase_a = pci_resource_start(pcidev, 0); iobase_9 = pci_resource_start(pcidev, 2); - printk(", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", pci_bus, pci_slot, - pci_func, iobase_9, iobase_a); + printk(KERN_ERR ", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", pci_bus, + pci_slot, pci_func, iobase_9, iobase_a); dev->iobase = iobase_9; dev->board_name = this_board->name; -- cgit v1.2.3 From af6ddd57f2e811561ca57a98b4c7a2bb1db6a270 Mon Sep 17 00:00:00 2001 From: Maurice Dawson Date: Tue, 30 Mar 2010 12:24:14 +0100 Subject: Staging: comedi: fix brace, print(k) and over 80 character coding style issues in adv_pci1723.c This is a Patch to the adv_pci1723.c file that fixes up brace, print(k) and over 80 character warnings found by the checkpatch.pl tool Signed-off-by: Maurice Dawson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1723.c | 149 ++++++++++++++++----------- 1 file changed, 87 insertions(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 6b0b7eda3be8..1644490ed0ad 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -60,35 +60,57 @@ TODO: #define IORANGE_1723 0x2A /* all the registers for the pci1723 board */ -#define PCI1723_DA(N) ((N)<<1) /* W: D/A register N (0 to 7) */ - -#define PCI1723_SYN_SET 0x12 /*synchronized set register */ -#define PCI1723_ALL_CHNNELE_SYN_STROBE 0x12 /*synchronized status register */ - -#define PCI1723_RANGE_CALIBRATION_MODE 0x14 /* range and calibration mode */ -#define PCI1723_RANGE_CALIBRATION_STATUS 0x14 /* range and calibration status */ - -#define PCI1723_CONTROL_CMD_CALIBRATION_FUN 0x16 /* SADC control command for calibration function */ -#define PCI1723_STATUS_CMD_CALIBRATION_FUN 0x16 /* SADC control status for calibration function */ - -#define PCI1723_CALIBRATION_PARA_STROBE 0x18 /* Calibration parameter strobe */ +#define PCI1723_DA(N) ((N)<<1) /* W: D/A register N (0 to 7) */ + +#define PCI1723_SYN_SET 0x12 /* synchronized set register */ +#define PCI1723_ALL_CHNNELE_SYN_STROBE 0x12 + /* synchronized status register */ + +#define PCI1723_RANGE_CALIBRATION_MODE 0x14 + /* range and calibration mode */ +#define PCI1723_RANGE_CALIBRATION_STATUS 0x14 + /* range and calibration status */ + +#define PCI1723_CONTROL_CMD_CALIBRATION_FUN 0x16 + /* + * SADC control command for + * calibration function + */ +#define PCI1723_STATUS_CMD_CALIBRATION_FUN 0x16 + /* + * SADC control status for + * calibration function + */ + +#define PCI1723_CALIBRATION_PARA_STROBE 0x18 + /* Calibration parameter strobe */ #define PCI1723_DIGITAL_IO_PORT_SET 0x1A /* Digital I/O port setting */ #define PCI1723_DIGITAL_IO_PORT_MODE 0x1A /* Digital I/O port mode */ -#define PCI1723_WRITE_DIGITAL_OUTPUT_CMD 0x1C /* Write digital output command */ +#define PCI1723_WRITE_DIGITAL_OUTPUT_CMD 0x1C + /* Write digital output command */ #define PCI1723_READ_DIGITAL_INPUT_DATA 0x1C /* Read digital input data */ -#define PCI1723_WRITE_CAL_CMD 0x1E /* Write calibration command */ -#define PCI1723_READ_CAL_STATUS 0x1E /* Read calibration status */ +#define PCI1723_WRITE_CAL_CMD 0x1E /* Write calibration command */ +#define PCI1723_READ_CAL_STATUS 0x1E /* Read calibration status */ -#define PCI1723_SYN_STROBE 0x20 /* Synchronized strobe */ +#define PCI1723_SYN_STROBE 0x20 /* Synchronized strobe */ -#define PCI1723_RESET_ALL_CHN_STROBE 0x22 /* Reset all D/A channels strobe */ +#define PCI1723_RESET_ALL_CHN_STROBE 0x22 + /* Reset all D/A channels strobe */ -#define PCI1723_RESET_CAL_CONTROL_STROBE 0x24 /* Reset the calibration controller strobe */ +#define PCI1723_RESET_CAL_CONTROL_STROBE 0x24 + /* + * Reset the calibration + * controller strobe + */ -#define PCI1723_CHANGE_CHA_OUTPUT_TYPE_STROBE 0x26 /* Change D/A channels output type strobe */ +#define PCI1723_CHANGE_CHA_OUTPUT_TYPE_STROBE 0x26 + /* + * Change D/A channels output + * type strobe + */ #define PCI1723_SELECT_CALIBRATION 0x28 /* Select the calibration Ref_V */ @@ -104,14 +126,14 @@ static const struct comedi_lrange range_pci1723 = { 1, { */ struct pci1723_board { const char *name; - int vendor_id; /* PCI vendor a device ID of card */ + int vendor_id; /* PCI vendor a device ID of card */ int device_id; int iorange; char cardtype; - int n_aochan; /* num of D/A chans */ - int n_diochan; /* num of DIO chans */ - int ao_maxdata; /* resolution of D/A */ - const struct comedi_lrange *rangelist_ao; /* rangelist for D/A */ + int n_aochan; /* num of D/A chans */ + int n_diochan; /* num of DIO chans */ + int ao_maxdata; /* resolution of D/A */ + const struct comedi_lrange *rangelist_ao; /* rangelist for D/A */ }; static const struct pci1723_board boardtypes[] = { @@ -128,8 +150,10 @@ static const struct pci1723_board boardtypes[] = { }, }; -/* This is used by modprobe to translate PCI IDs to drivers. Should - * only be used for PCI and ISA-PnP devices */ +/* + * This is used by modprobe to translate PCI IDs to drivers. + * Should only be used for PCI and ISA-PnP devices + */ static DEFINE_PCI_DEVICE_TABLE(pci1723_pci_table) = { { PCI_VENDOR_ID_ADVANTECH, 0x1723, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { @@ -157,47 +181,47 @@ static struct comedi_driver driver_pci1723 = { .detach = pci1723_detach, }; -/* this structure is for data unique to this hardware driver. */ +/* This structure is for data unique to this hardware driver. */ struct pci1723_private { int valid; /* card is usable; */ struct pci_dev *pcidev; - unsigned char da_range[8]; /* D/A output range for each channel */ + unsigned char da_range[8]; /* D/A output range for each channel */ - short ao_data[8]; /* data output buffer */ + short ao_data[8]; /* data output buffer */ }; -/*the following macro to make it easy to -* access the private structure. -*/ +/* The following macro to make it easy to access the private structure. */ #define devpriv ((struct pci1723_private *)dev->private) #define this_board boardtypes /* - * the pci1723 card reset; + * The pci1723 card reset; */ static int pci1723_reset(struct comedi_device *dev) { int i; DPRINTK("adv_pci1723 EDBG: BGN: pci1723_reset(...)\n"); - outw(0x01, dev->iobase + PCI1723_SYN_SET); /* set synchronous output mode */ + outw(0x01, dev->iobase + PCI1723_SYN_SET); + /* set synchronous output mode */ for (i = 0; i < 8; i++) { - /* set all outputs to 0V */ + /* set all outputs to 0V */ devpriv->ao_data[i] = 0x8000; outw(devpriv->ao_data[i], dev->iobase + PCI1723_DA(i)); - /* set all ranges to +/- 10V */ + /* set all ranges to +/- 10V */ devpriv->da_range[i] = 0; outw(((devpriv->da_range[i] << 4) | i), PCI1723_RANGE_CALIBRATION_MODE); } - outw(0, dev->iobase + PCI1723_CHANGE_CHA_OUTPUT_TYPE_STROBE); /* update ranges */ - outw(0, dev->iobase + PCI1723_SYN_STROBE); /* update outputs */ + outw(0, dev->iobase + PCI1723_CHANGE_CHA_OUTPUT_TYPE_STROBE); + /* update ranges */ + outw(0, dev->iobase + PCI1723_SYN_STROBE); /* update outputs */ - /* set asynchronous output mode */ + /* set asynchronous output mode */ outw(0, dev->iobase + PCI1723_SYN_SET); DPRINTK("adv_pci1723 EDBG: END: pci1723_reset(...)\n"); @@ -251,11 +275,11 @@ static int pci1723_dio_insn_config(struct comedi_device *dev, unsigned short dio_mode; mask = 1 << CR_CHAN(insn->chanspec); - if (mask & 0x00FF) { + if (mask & 0x00FF) bits = 0x00FF; - } else { + else bits = 0xFF00; - } + switch (data[0]) { case INSN_CONFIG_DIO_INPUT: s->io_bits &= ~bits; @@ -270,12 +294,12 @@ static int pci1723_dio_insn_config(struct comedi_device *dev, return -EINVAL; } - /* update hardware DIO mode */ - dio_mode = 0x0000; /* low byte output, high byte output */ + /* update hardware DIO mode */ + dio_mode = 0x0000; /* low byte output, high byte output */ if ((s->io_bits & 0x00FF) == 0) - dio_mode |= 0x0001; /* low byte input */ + dio_mode |= 0x0001; /* low byte input */ if ((s->io_bits & 0xFF00) == 0) - dio_mode |= 0x0002; /* high byte input */ + dio_mode |= 0x0002; /* high byte input */ outw(dio_mode, dev->iobase + PCI1723_DIGITAL_IO_PORT_SET); return 1; } @@ -311,7 +335,8 @@ static int pci1723_attach(struct comedi_device *dev, int opt_bus, opt_slot; const char *errstr; - printk("comedi%d: adv_pci1723: board=%s", dev->minor, this_board->name); + printk(KERN_ERR "comedi%d: adv_pci1723: board=%s", + dev->minor, this_board->name); opt_bus = it->options[0]; opt_slot = it->options[1]; @@ -349,10 +374,10 @@ static int pci1723_attach(struct comedi_device *dev, if (!pcidev) { if (opt_bus || opt_slot) { - printk(" - Card at b:s %d:%d %s\n", - opt_bus, opt_slot, errstr); + printk(KERN_ERR " - Card at b:s %d:%d %s\n", + opt_bus, opt_slot, errstr); } else { - printk(" - Card %s\n", errstr); + printk(KERN_ERR " - Card %s\n", errstr); } return -EIO; } @@ -362,8 +387,8 @@ static int pci1723_attach(struct comedi_device *dev, pci_func = PCI_FUNC(pcidev->devfn); iobase = pci_resource_start(pcidev, 2); - printk(", b:s:f=%d:%d:%d, io=0x%4x", pci_bus, pci_slot, pci_func, - iobase); + printk(KERN_ERR ", b:s:f=%d:%d:%d, io=0x%4x", + pci_bus, pci_slot, pci_func, iobase); dev->iobase = iobase; @@ -398,22 +423,23 @@ static int pci1723_attach(struct comedi_device *dev, s->insn_write = pci1723_ao_write_winsn; s->insn_read = pci1723_insn_read_ao; - /* read DIO config */ - switch (inw(dev->iobase + PCI1723_DIGITAL_IO_PORT_MODE) & 0x03) { - case 0x00: /* low byte output, high byte output */ + /* read DIO config */ + switch (inw(dev->iobase + PCI1723_DIGITAL_IO_PORT_MODE) + & 0x03) { + case 0x00: /* low byte output, high byte output */ s->io_bits = 0xFFFF; break; - case 0x01: /* low byte input, high byte output */ + case 0x01: /* low byte input, high byte output */ s->io_bits = 0xFF00; break; - case 0x02: /* low byte output, high byte input */ + case 0x02: /* low byte output, high byte input */ s->io_bits = 0x00FF; break; - case 0x03: /* low byte input, high byte input */ + case 0x03: /* low byte input, high byte input */ s->io_bits = 0x0000; break; } - /* read DIO port state */ + /* read DIO port state */ s->state = inw(dev->iobase + PCI1723_READ_DIGITAL_INPUT_DATA); subdev++; @@ -450,16 +476,15 @@ static int pci1723_attach(struct comedi_device *dev, */ static int pci1723_detach(struct comedi_device *dev) { - printk("comedi%d: pci1723: remove\n", dev->minor); + printk(KERN_ERR "comedi%d: pci1723: remove\n", dev->minor); if (dev->private) { if (devpriv->valid) pci1723_reset(dev); if (devpriv->pcidev) { - if (dev->iobase) { + if (dev->iobase) comedi_pci_disable(devpriv->pcidev); - } pci_dev_put(devpriv->pcidev); } } -- cgit v1.2.3 From 24d2d8be91e83d6eb40240180da46b3dbd440dd5 Mon Sep 17 00:00:00 2001 From: Maurice Dawson Date: Thu, 8 Apr 2010 13:13:20 +0100 Subject: Staging: comedi: fix print(k) coding style issue in aio_aio12_8.c This is a patch to the aio_aio12_8.c that fixes up print(k) warnings found by the checkpatch.pl tool Signed-off-by: Maurice Dawson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/aio_aio12_8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c index c4cac66db12e..7a1c636df5be 100644 --- a/drivers/staging/comedi/drivers/aio_aio12_8.c +++ b/drivers/staging/comedi/drivers/aio_aio12_8.c @@ -110,7 +110,7 @@ static int aio_aio12_8_ai_read(struct comedi_device *dev, while (timeout && !(inb(dev->iobase + AIO12_8_STATUS) & STATUS_ADC_EOC)) { timeout--; - printk("timeout %d\n", timeout); + printk(KERN_ERR "timeout %d\n", timeout); udelay(1); } if (timeout == 0) { @@ -172,7 +172,7 @@ static int aio_aio12_8_attach(struct comedi_device *dev, iobase = it->options[0]; if (!request_region(iobase, 24, "aio_aio12_8")) { - printk("I/O port conflict"); + printk(KERN_ERR "I/O port conflict"); return -EIO; } -- cgit v1.2.3 From 6764cbd72ac5295f8dfc96a38696553cecb452a8 Mon Sep 17 00:00:00 2001 From: Vijay Kumar Date: Sun, 7 Mar 2010 07:54:45 +0530 Subject: Staging: Remove staging/poch Remove staging/poch. Reasons for removal are -- The driver has serious cache issues, that I couldn't fix. The card vendor is working on a better replacement for the driver. The driver has been delayed a lot and development has come to a stand still. Signed-off-by: Vijay Kumar B. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/poch/Kconfig | 6 - drivers/staging/poch/Makefile | 1 - drivers/staging/poch/README | 136 ---- drivers/staging/poch/poch.c | 1443 ----------------------------------------- drivers/staging/poch/poch.h | 35 - 7 files changed, 1624 deletions(-) delete mode 100644 drivers/staging/poch/Kconfig delete mode 100644 drivers/staging/poch/Makefile delete mode 100644 drivers/staging/poch/README delete mode 100644 drivers/staging/poch/poch.c delete mode 100644 drivers/staging/poch/poch.h (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 8db8632541f1..5999259922e8 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -57,8 +57,6 @@ source "drivers/staging/wlan-ng/Kconfig" source "drivers/staging/echo/Kconfig" -source "drivers/staging/poch/Kconfig" - source "drivers/staging/otus/Kconfig" source "drivers/staging/rt2860/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index ab61e2601ffd..55ff30f8bd2a 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_USB_IP_COMMON) += usbip/ obj-$(CONFIG_W35UND) += winbond/ obj-$(CONFIG_PRISM2_USB) += wlan-ng/ obj-$(CONFIG_ECHO) += echo/ -obj-$(CONFIG_POCH) += poch/ obj-$(CONFIG_OTUS) += otus/ obj-$(CONFIG_RT2860) += rt2860/ obj-$(CONFIG_RT2870) += rt2870/ diff --git a/drivers/staging/poch/Kconfig b/drivers/staging/poch/Kconfig deleted file mode 100644 index b3b33b984a57..000000000000 --- a/drivers/staging/poch/Kconfig +++ /dev/null @@ -1,6 +0,0 @@ -config POCH - tristate "Redrapids Pocket Change CardBus support" - depends on PCI && UIO - default N - ---help--- - Enable support for Redrapids Pocket Change CardBus devices. diff --git a/drivers/staging/poch/Makefile b/drivers/staging/poch/Makefile deleted file mode 100644 index d2b96805cb9e..000000000000 --- a/drivers/staging/poch/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_POCH) += poch.o diff --git a/drivers/staging/poch/README b/drivers/staging/poch/README deleted file mode 100644 index ac76ff969a2f..000000000000 --- a/drivers/staging/poch/README +++ /dev/null @@ -1,136 +0,0 @@ -TODO: - - Rx block size is limited to < 2048, hardware bug? - - Group size is limited to < page size, kernel alloc/mmap API issues - - test whether Tx is transmitting data from provided buffers - - handle device unplug case - - handle temperature above threshold - - use bus address instead of physical address for DMA - - support for snapshot mode - - audit userspace interfaces - - get reserved major/minor if needed - -Sample Code: - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -struct pconsume { - uint32_t * offsets; - uint32_t nfetch; - uint32_t nflush; -}; - -uint32_t offsets[10]; - -void process_group(unsigned char *buf, uint32_t size) -{ - uint16_t *buf16 = (uint16_t *)buf; - - printf("RX: %p %u %04x %04x %04x %04x %04x %04x\n", buf, size, - buf16[0], buf16[1], buf16[2], buf16[3], buf16[4], buf16[5]); -} - -int main() -{ - struct sysfs_attribute *attr; - char *path; - int ret; - unsigned long mmap_size; - int fd; - unsigned char *cbuf; - - uint32_t nflush; - struct pollfd poll_fds; - int count = 0; - int i; - - path = "/sys/class/pocketchange/poch0/ch0/block_size"; - attr = sysfs_open_attribute(path); - ret = sysfs_write_attribute(attr, "256", strlen("256")); - if (ret == -1) - error(1, errno, "error writing attribute %s", path); - sysfs_close_attribute(attr); - - path = "/sys/class/pocketchange/poch0/ch0/group_size"; - attr = sysfs_open_attribute(path); - ret = sysfs_write_attribute(attr, "4096", strlen("4096")); - if (ret == -1) - error(1, errno, "error writing attribute %s", path); - sysfs_close_attribute(attr); - - path = "/sys/class/pocketchange/poch0/ch0/group_count"; - attr = sysfs_open_attribute(path); - ret = sysfs_write_attribute(attr, "64", strlen("64")); - if (ret == -1) - error(1, errno, "error writing attribute %s", path); - sysfs_close_attribute(attr); - - fd = open("/dev/ch0", O_RDWR); - if (fd == -1) - error(1, errno, "error opening device node"); - - path = "/sys/class/pocketchange/poch0/ch0/mmap_size"; - attr = sysfs_open_attribute(path); - ret = sysfs_read_attribute(attr); - if (ret == -1) - error(1, errno, "error reading attribute %s", path); - printf("%s", attr->value); - sscanf(attr->value, "%lu", &mmap_size); - sysfs_close_attribute(attr); - - cbuf = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, - MAP_PRIVATE, fd, 0); - if (cbuf == MAP_FAILED) - error(1, errno, "error mapping DMA buffers"); - - ret = ioctl(fd, POCH_IOC_TRANSFER_START, 0); - if (ret == -1) - error(1, errno, "error starting transfer"); - - nflush = 0; - while (1) { - struct pconsume consume; - - consume.offsets = offsets; - consume.nfetch = 10; - consume.nflush = nflush; - - ret = ioctl(fd, POCH_IOC_CONSUME, &consume); - if (ret == -1) - error(1, errno, "error consuming groups"); - - nflush = consume.nfetch; - - for (i = 0; i < nflush; i++) { - process_group(cbuf + consume.offsets[i], 4096); - - count++; - if (count == 1000) - break; - } - - if (count == 1000) - break; - } - - ret = ioctl(fd, POCH_IOC_TRANSFER_STOP, 0); - if (ret == -1) - error(1, errno, "error starting transfer"); - - return 0; -} - -Please send patches to Greg Kroah-Hartman and -Vijay Kumar and Jaya Kumar diff --git a/drivers/staging/poch/poch.c b/drivers/staging/poch/poch.c deleted file mode 100644 index f940a34c1a0c..000000000000 --- a/drivers/staging/poch/poch.c +++ /dev/null @@ -1,1443 +0,0 @@ -/* - * User-space DMA and UIO based Redrapids Pocket Change CardBus driver - * - * Copyright 2008 Vijay Kumar - * - * Licensed under GPL version 2 only. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "poch.h" - -#include - -#ifndef PCI_VENDOR_ID_RRAPIDS -#define PCI_VENDOR_ID_RRAPIDS 0x17D2 -#endif - -#ifndef PCI_DEVICE_ID_RRAPIDS_POCKET_CHANGE -#define PCI_DEVICE_ID_RRAPIDS_POCKET_CHANGE 0x0351 -#endif - -#define POCH_NCHANNELS 2 - -#define MAX_POCH_CARDS 8 -#define MAX_POCH_DEVICES (MAX_POCH_CARDS * POCH_NCHANNELS) - -#define DRV_NAME "poch" -#define PFX DRV_NAME ": " - -/* - * BAR0 Bridge Register Definitions - */ - -#define BRIDGE_REV_REG 0x0 -#define BRIDGE_INT_MASK_REG 0x4 -#define BRIDGE_INT_STAT_REG 0x8 - -#define BRIDGE_INT_ACTIVE (0x1 << 31) -#define BRIDGE_INT_FPGA (0x1 << 2) -#define BRIDGE_INT_TEMP_FAIL (0x1 << 1) -#define BRIDGE_INT_TEMP_WARN (0x1 << 0) - -#define BRIDGE_FPGA_RESET_REG 0xC - -#define BRIDGE_CARD_POWER_REG 0x10 -#define BRIDGE_CARD_POWER_EN (0x1 << 0) -#define BRIDGE_CARD_POWER_PROG_DONE (0x1 << 31) - -#define BRIDGE_JTAG_REG 0x14 -#define BRIDGE_DMA_GO_REG 0x18 -#define BRIDGE_STAT_0_REG 0x1C -#define BRIDGE_STAT_1_REG 0x20 -#define BRIDGE_STAT_2_REG 0x24 -#define BRIDGE_STAT_3_REG 0x28 -#define BRIDGE_TEMP_STAT_REG 0x2C -#define BRIDGE_TEMP_THRESH_REG 0x30 -#define BRIDGE_EEPROM_REVSEL_REG 0x34 -#define BRIDGE_CIS_STRUCT_REG 0x100 -#define BRIDGE_BOARDREV_REG 0x124 - -/* - * BAR1 FPGA Register Definitions - */ - -#define FPGA_IFACE_REV_REG 0x0 -#define FPGA_RX_BLOCK_SIZE_REG 0x8 -#define FPGA_TX_BLOCK_SIZE_REG 0xC -#define FPGA_RX_BLOCK_COUNT_REG 0x10 -#define FPGA_TX_BLOCK_COUNT_REG 0x14 -#define FPGA_RX_CURR_DMA_BLOCK_REG 0x18 -#define FPGA_TX_CURR_DMA_BLOCK_REG 0x1C -#define FPGA_RX_GROUP_COUNT_REG 0x20 -#define FPGA_TX_GROUP_COUNT_REG 0x24 -#define FPGA_RX_CURR_GROUP_REG 0x28 -#define FPGA_TX_CURR_GROUP_REG 0x2C -#define FPGA_RX_CURR_PCI_REG 0x38 -#define FPGA_TX_CURR_PCI_REG 0x3C -#define FPGA_RX_GROUP0_START_REG 0x40 -#define FPGA_TX_GROUP0_START_REG 0xC0 -#define FPGA_DMA_DESC_1_REG 0x140 -#define FPGA_DMA_DESC_2_REG 0x144 -#define FPGA_DMA_DESC_3_REG 0x148 -#define FPGA_DMA_DESC_4_REG 0x14C - -#define FPGA_DMA_INT_STAT_REG 0x150 -#define FPGA_DMA_INT_MASK_REG 0x154 -#define FPGA_DMA_INT_RX (1 << 0) -#define FPGA_DMA_INT_TX (1 << 1) - -#define FPGA_RX_GROUPS_PER_INT_REG 0x158 -#define FPGA_TX_GROUPS_PER_INT_REG 0x15C -#define FPGA_DMA_ADR_PAGE_REG 0x160 -#define FPGA_FPGA_REV_REG 0x200 - -#define FPGA_ADC_CLOCK_CTL_REG 0x204 -#define FPGA_ADC_CLOCK_CTL_OSC_EN (0x1 << 3) -#define FPGA_ADC_CLOCK_LOCAL_CLK (0x1 | FPGA_ADC_CLOCK_CTL_OSC_EN) -#define FPGA_ADC_CLOCK_EXT_SAMP_CLK 0X0 - -#define FPGA_ADC_DAC_EN_REG 0x208 -#define FPGA_ADC_DAC_EN_DAC_OFF (0x1 << 1) -#define FPGA_ADC_DAC_EN_ADC_OFF (0x1 << 0) - -#define FPGA_INT_STAT_REG 0x20C -#define FPGA_INT_MASK_REG 0x210 -#define FPGA_INT_PLL_UNLOCKED (0x1 << 9) -#define FPGA_INT_DMA_CORE (0x1 << 8) -#define FPGA_INT_TX_FF_EMPTY (0x1 << 7) -#define FPGA_INT_RX_FF_EMPTY (0x1 << 6) -#define FPGA_INT_TX_FF_OVRFLW (0x1 << 3) -#define FPGA_INT_RX_FF_OVRFLW (0x1 << 2) -#define FPGA_INT_TX_ACQ_DONE (0x1 << 1) -#define FPGA_INT_RX_ACQ_DONE (0x1) - -#define FPGA_RX_CTL_REG 0x214 -#define FPGA_RX_CTL_FIFO_FLUSH (0x1 << 9) -#define FPGA_RX_CTL_SYNTH_DATA (0x1 << 8) -#define FPGA_RX_CTL_CONT_CAP (0x0 << 1) -#define FPGA_RX_CTL_SNAP_CAP (0x1 << 1) - -#define FPGA_RX_ARM_REG 0x21C - -#define FPGA_DOM_REG 0x224 -#define FPGA_DOM_DCM_RESET (0x1 << 5) -#define FPGA_DOM_SOFT_RESET (0x1 << 4) -#define FPGA_DOM_DUAL_M_SG_DMA (0x0) -#define FPGA_DOM_TARGET_ACCESS (0x1) - -#define FPGA_TX_CTL_REG 0x228 -#define FPGA_TX_CTL_FIFO_FLUSH (0x1 << 9) -#define FPGA_TX_CTL_OUTPUT_ZERO (0x0 << 2) -#define FPGA_TX_CTL_OUTPUT_CARDBUS (0x1 << 2) -#define FPGA_TX_CTL_OUTPUT_ADC (0x2 << 2) -#define FPGA_TX_CTL_OUTPUT_SNAPSHOT (0x3 << 2) -#define FPGA_TX_CTL_LOOPBACK (0x1 << 0) - -#define FPGA_ENDIAN_MODE_REG 0x22C -#define FPGA_RX_FIFO_COUNT_REG 0x28C -#define FPGA_TX_ENABLE_REG 0x298 -#define FPGA_TX_TRIGGER_REG 0x29C -#define FPGA_TX_DATAMEM_COUNT_REG 0x2A8 -#define FPGA_CAP_FIFO_REG 0x300 -#define FPGA_TX_SNAPSHOT_REG 0x8000 - -/* - * Channel Index Definitions - */ - -enum { - CHNO_RX_CHANNEL, - CHNO_TX_CHANNEL, -}; - -struct poch_dev; - -enum channel_dir { - CHANNEL_DIR_RX, - CHANNEL_DIR_TX, -}; - -struct poch_group_info { - struct page *pg; - dma_addr_t dma_addr; - unsigned long user_offset; -}; - -struct channel_info { - unsigned int chno; - - atomic_t sys_block_size; - atomic_t sys_group_size; - atomic_t sys_group_count; - - enum channel_dir dir; - - unsigned long block_size; - unsigned long group_size; - unsigned long group_count; - - /* Contains the DMA address and VM offset of each group. */ - struct poch_group_info *groups; - - /* Contains the header and circular buffer exported to userspace. */ - spinlock_t group_offsets_lock; - - /* Last group consumed by user space. */ - unsigned int consumed; - /* Last group indicated as 'complete' to user space. */ - unsigned int transfer; - - wait_queue_head_t wq; - - union { - unsigned int data_available; - unsigned int space_available; - }; - - void __iomem *bridge_iomem; - void __iomem *fpga_iomem; - spinlock_t *iomem_lock; - - atomic_t free; - atomic_t inited; - - /* Error counters */ - struct poch_counters counters; - spinlock_t counters_lock; - - struct device *dev; -}; - -struct poch_dev { - struct uio_info uio; - struct pci_dev *pci_dev; - unsigned int nchannels; - struct channel_info channels[POCH_NCHANNELS]; - struct cdev cdev; - - /* Counts the no. of channels that have been opened. On first - * open, the card is powered on. On last channel close, the - * card is powered off. - */ - atomic_t usage; - - void __iomem *bridge_iomem; - void __iomem *fpga_iomem; - spinlock_t iomem_lock; - - struct device *dev; -}; - -static int synth_rx; -module_param(synth_rx, bool, 0600); -MODULE_PARM_DESC(synth_rx, - "Synthesize received values using a counter. Default: No"); - -static int loopback; -module_param(loopback, bool, 0600); -MODULE_PARM_DESC(loopback, - "Enable hardware loopback of trasnmitted data. Default: No"); - -static dev_t poch_first_dev; -static struct class *poch_cls; -static DEFINE_IDR(poch_ids); - -static ssize_t store_block_size(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct channel_info *channel = dev_get_drvdata(dev); - unsigned long block_size; - - sscanf(buf, "%lu", &block_size); - atomic_set(&channel->sys_block_size, block_size); - - return count; -} -static DEVICE_ATTR(block_size, S_IWUSR|S_IWGRP, NULL, store_block_size); - -static ssize_t store_group_size(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct channel_info *channel = dev_get_drvdata(dev); - unsigned long group_size; - - sscanf(buf, "%lu", &group_size); - atomic_set(&channel->sys_group_size, group_size); - - return count; -} -static DEVICE_ATTR(group_size, S_IWUSR|S_IWGRP, NULL, store_group_size); - -static ssize_t store_group_count(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct channel_info *channel = dev_get_drvdata(dev); - unsigned long group_count; - - sscanf(buf, "%lu", &group_count); - atomic_set(&channel->sys_group_count, group_count); - - return count; -} -static DEVICE_ATTR(group_count, S_IWUSR|S_IWGRP, NULL, store_group_count); - -static ssize_t show_direction(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct channel_info *channel = dev_get_drvdata(dev); - int len; - - len = sprintf(buf, "%s\n", (channel->dir ? "tx" : "rx")); - return len; -} -static DEVICE_ATTR(dir, S_IRUSR|S_IRGRP, show_direction, NULL); - -static unsigned long npages(unsigned long bytes) -{ - if (bytes % PAGE_SIZE == 0) - return bytes / PAGE_SIZE; - else - return (bytes / PAGE_SIZE) + 1; -} - -static ssize_t show_mmap_size(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct channel_info *channel = dev_get_drvdata(dev); - int len; - unsigned long mmap_size; - unsigned long group_pages; - unsigned long total_group_pages; - - group_pages = npages(channel->group_size); - total_group_pages = group_pages * channel->group_count; - - mmap_size = total_group_pages * PAGE_SIZE; - len = sprintf(buf, "%lu\n", mmap_size); - return len; -} -static DEVICE_ATTR(mmap_size, S_IRUSR|S_IRGRP, show_mmap_size, NULL); - -static struct device_attribute *poch_class_attrs[] = { - &dev_attr_block_size, - &dev_attr_group_size, - &dev_attr_group_count, - &dev_attr_dir, - &dev_attr_mmap_size, -}; - -static void poch_channel_free_groups(struct channel_info *channel) -{ - unsigned long i; - - for (i = 0; i < channel->group_count; i++) { - struct poch_group_info *group; - unsigned int order; - - group = &channel->groups[i]; - order = get_order(channel->group_size); - if (group->pg) - __free_pages(group->pg, order); - } -} - -static int poch_channel_alloc_groups(struct channel_info *channel) -{ - unsigned long i; - unsigned long group_pages; - - group_pages = npages(channel->group_size); - - for (i = 0; i < channel->group_count; i++) { - struct poch_group_info *group; - unsigned int order; - gfp_t gfp_mask; - - group = &channel->groups[i]; - order = get_order(channel->group_size); - - /* - * __GFP_COMP is required here since we are going to - * perform non-linear mapping to userspace. For more - * information read the vm_insert_page() function - * comments. - */ - - gfp_mask = GFP_KERNEL | GFP_DMA32 | __GFP_ZERO; - group->pg = alloc_pages(gfp_mask, order); - if (!group->pg) { - poch_channel_free_groups(channel); - return -ENOMEM; - } - - /* FIXME: This is the physical address not the bus - * address! This won't work in architectures that - * have an IOMMU. Can we use pci_map_single() for - * this? - */ - group->dma_addr = page_to_pfn(group->pg) * PAGE_SIZE; - group->user_offset = (i * group_pages) * PAGE_SIZE; - - printk(KERN_INFO PFX "%ld: user_offset: 0x%lx\n", i, - group->user_offset); - } - - return 0; -} - -static int channel_latch_attr(struct channel_info *channel) -{ - channel->group_count = atomic_read(&channel->sys_group_count); - channel->group_size = atomic_read(&channel->sys_group_size); - channel->block_size = atomic_read(&channel->sys_block_size); - - if (channel->group_count == 0) { - printk(KERN_ERR PFX "invalid group count %lu", - channel->group_count); - return -EINVAL; - } - - if (channel->group_size == 0 || - channel->group_size < channel->block_size) { - printk(KERN_ERR PFX "invalid group size %lu", - channel->group_size); - return -EINVAL; - } - - if (channel->block_size == 0 || (channel->block_size % 8) != 0) { - printk(KERN_ERR PFX "invalid block size %lu", - channel->block_size); - return -EINVAL; - } - - if (channel->group_size % channel->block_size != 0) { - printk(KERN_ERR PFX - "group size should be multiple of block size"); - return -EINVAL; - } - - return 0; -} - -/* - * Configure DMA group registers - */ -static void channel_dma_init(struct channel_info *channel) -{ - void __iomem *fpga = channel->fpga_iomem; - u32 group_regs_base; - u32 group_reg; - unsigned int page; - unsigned int group_in_page; - unsigned long i; - u32 block_size_reg; - u32 block_count_reg; - u32 group_count_reg; - u32 groups_per_int_reg; - u32 curr_pci_reg; - - if (channel->chno == CHNO_RX_CHANNEL) { - group_regs_base = FPGA_RX_GROUP0_START_REG; - block_size_reg = FPGA_RX_BLOCK_SIZE_REG; - block_count_reg = FPGA_RX_BLOCK_COUNT_REG; - group_count_reg = FPGA_RX_GROUP_COUNT_REG; - groups_per_int_reg = FPGA_RX_GROUPS_PER_INT_REG; - curr_pci_reg = FPGA_RX_CURR_PCI_REG; - } else { - group_regs_base = FPGA_TX_GROUP0_START_REG; - block_size_reg = FPGA_TX_BLOCK_SIZE_REG; - block_count_reg = FPGA_TX_BLOCK_COUNT_REG; - group_count_reg = FPGA_TX_GROUP_COUNT_REG; - groups_per_int_reg = FPGA_TX_GROUPS_PER_INT_REG; - curr_pci_reg = FPGA_TX_CURR_PCI_REG; - } - - printk(KERN_WARNING "block_size, group_size, group_count\n"); - /* - * Block size is represented in no. of 64 bit transfers. - */ - iowrite32(channel->block_size / 8, fpga + block_size_reg); - iowrite32(channel->group_size / channel->block_size, - fpga + block_count_reg); - iowrite32(channel->group_count, fpga + group_count_reg); - /* FIXME: Hardcoded groups per int. Get it from sysfs? */ - iowrite32(16, fpga + groups_per_int_reg); - - /* Unlock PCI address? Not defined in the data sheet, but used - * in the reference code by Redrapids. - */ - iowrite32(0x1, fpga + curr_pci_reg); - - /* The DMA address page register is shared between the RX and - * TX channels, so acquire lock. - */ - for (i = 0; i < channel->group_count; i++) { - page = i / 32; - group_in_page = i % 32; - - group_reg = group_regs_base + (group_in_page * 4); - - spin_lock(channel->iomem_lock); - iowrite32(page, fpga + FPGA_DMA_ADR_PAGE_REG); - iowrite32(channel->groups[i].dma_addr, fpga + group_reg); - spin_unlock(channel->iomem_lock); - } - - for (i = 0; i < channel->group_count; i++) { - page = i / 32; - group_in_page = i % 32; - - group_reg = group_regs_base + (group_in_page * 4); - - spin_lock(channel->iomem_lock); - iowrite32(page, fpga + FPGA_DMA_ADR_PAGE_REG); - printk(KERN_INFO PFX "%ld: read dma_addr: 0x%x\n", i, - ioread32(fpga + group_reg)); - spin_unlock(channel->iomem_lock); - } - -} - -static void __poch_channel_clear_counters(struct channel_info *channel) -{ - channel->counters.pll_unlock = 0; - channel->counters.fifo_empty = 0; - channel->counters.fifo_overflow = 0; -} - -static int poch_channel_init(struct channel_info *channel, - struct poch_dev *poch_dev) -{ - struct pci_dev *pdev = poch_dev->pci_dev; - struct device *dev = &pdev->dev; - unsigned long alloc_size; - int ret; - - printk(KERN_WARNING "channel_latch_attr\n"); - - ret = channel_latch_attr(channel); - if (ret != 0) - goto out; - - channel->consumed = 0; - channel->transfer = 0; - - /* Allocate memory to hold group information. */ - alloc_size = channel->group_count * sizeof(struct poch_group_info); - channel->groups = kzalloc(alloc_size, GFP_KERNEL); - if (!channel->groups) { - dev_err(dev, "error allocating memory for group info\n"); - ret = -ENOMEM; - goto out; - } - - printk(KERN_WARNING "poch_channel_alloc_groups\n"); - - ret = poch_channel_alloc_groups(channel); - if (ret) { - dev_err(dev, "error allocating groups of order %d\n", - get_order(channel->group_size)); - goto out_free_group_info; - } - - channel->fpga_iomem = poch_dev->fpga_iomem; - channel->bridge_iomem = poch_dev->bridge_iomem; - channel->iomem_lock = &poch_dev->iomem_lock; - spin_lock_init(&channel->counters_lock); - - __poch_channel_clear_counters(channel); - - return 0; - - out_free_group_info: - kfree(channel->groups); - out: - return ret; -} - -static int poch_wait_fpga_prog(void __iomem *bridge) -{ - unsigned long total_wait; - const unsigned long wait_period = 100; - /* FIXME: Get the actual timeout */ - const unsigned long prog_timeo = 10000; /* 10 Seconds */ - u32 card_power; - - printk(KERN_WARNING "poch_wait_fpg_prog\n"); - - printk(KERN_INFO PFX "programming fpga ...\n"); - total_wait = 0; - while (1) { - msleep(wait_period); - total_wait += wait_period; - - card_power = ioread32(bridge + BRIDGE_CARD_POWER_REG); - if (card_power & BRIDGE_CARD_POWER_PROG_DONE) { - printk(KERN_INFO PFX "programming done\n"); - return 0; - } - if (total_wait > prog_timeo) { - printk(KERN_ERR PFX - "timed out while programming FPGA\n"); - return -EIO; - } - } -} - -static void poch_card_power_off(struct poch_dev *poch_dev) -{ - void __iomem *bridge = poch_dev->bridge_iomem; - u32 card_power; - - iowrite32(0, bridge + BRIDGE_INT_MASK_REG); - iowrite32(0, bridge + BRIDGE_DMA_GO_REG); - - card_power = ioread32(bridge + BRIDGE_CARD_POWER_REG); - iowrite32(card_power & ~BRIDGE_CARD_POWER_EN, - bridge + BRIDGE_CARD_POWER_REG); -} - -enum clk_src { - CLK_SRC_ON_BOARD, - CLK_SRC_EXTERNAL -}; - -static void poch_card_clock_on(void __iomem *fpga) -{ - /* FIXME: Get this data through sysfs? */ - enum clk_src clk_src = CLK_SRC_ON_BOARD; - - if (clk_src == CLK_SRC_ON_BOARD) { - iowrite32(FPGA_ADC_CLOCK_LOCAL_CLK | FPGA_ADC_CLOCK_CTL_OSC_EN, - fpga + FPGA_ADC_CLOCK_CTL_REG); - } else if (clk_src == CLK_SRC_EXTERNAL) { - iowrite32(FPGA_ADC_CLOCK_EXT_SAMP_CLK, - fpga + FPGA_ADC_CLOCK_CTL_REG); - } -} - -static int poch_card_power_on(struct poch_dev *poch_dev) -{ - void __iomem *bridge = poch_dev->bridge_iomem; - void __iomem *fpga = poch_dev->fpga_iomem; - - iowrite32(BRIDGE_CARD_POWER_EN, bridge + BRIDGE_CARD_POWER_REG); - - if (poch_wait_fpga_prog(bridge) != 0) { - poch_card_power_off(poch_dev); - return -EIO; - } - - poch_card_clock_on(fpga); - - /* Sync to new clock, reset state machines, set DMA mode. */ - iowrite32(FPGA_DOM_DCM_RESET | FPGA_DOM_SOFT_RESET - | FPGA_DOM_DUAL_M_SG_DMA, fpga + FPGA_DOM_REG); - - /* FIXME: The time required for sync. needs to be tuned. */ - msleep(1000); - - return 0; -} - -static void poch_channel_analog_on(struct channel_info *channel) -{ - void __iomem *fpga = channel->fpga_iomem; - u32 adc_dac_en; - - spin_lock(channel->iomem_lock); - adc_dac_en = ioread32(fpga + FPGA_ADC_DAC_EN_REG); - switch (channel->chno) { - case CHNO_RX_CHANNEL: - iowrite32(adc_dac_en & ~FPGA_ADC_DAC_EN_ADC_OFF, - fpga + FPGA_ADC_DAC_EN_REG); - break; - case CHNO_TX_CHANNEL: - iowrite32(adc_dac_en & ~FPGA_ADC_DAC_EN_DAC_OFF, - fpga + FPGA_ADC_DAC_EN_REG); - break; - } - spin_unlock(channel->iomem_lock); -} - -static int poch_open(struct inode *inode, struct file *filp) -{ - struct poch_dev *poch_dev; - struct channel_info *channel; - void __iomem *bridge; - void __iomem *fpga; - int chno; - int usage; - int ret; - - poch_dev = container_of(inode->i_cdev, struct poch_dev, cdev); - bridge = poch_dev->bridge_iomem; - fpga = poch_dev->fpga_iomem; - - chno = iminor(inode) % poch_dev->nchannels; - channel = &poch_dev->channels[chno]; - - if (!atomic_dec_and_test(&channel->free)) { - atomic_inc(&channel->free); - ret = -EBUSY; - goto out; - } - - usage = atomic_inc_return(&poch_dev->usage); - - printk(KERN_WARNING "poch_card_power_on\n"); - - if (usage == 1) { - ret = poch_card_power_on(poch_dev); - if (ret) - goto out_dec_usage; - } - - printk(KERN_INFO "CardBus Bridge Revision: %x\n", - ioread32(bridge + BRIDGE_REV_REG)); - printk(KERN_INFO "CardBus Interface Revision: %x\n", - ioread32(fpga + FPGA_IFACE_REV_REG)); - - channel->chno = chno; - filp->private_data = channel; - - printk(KERN_WARNING "poch_channel_init\n"); - - ret = poch_channel_init(channel, poch_dev); - if (ret) - goto out_power_off; - - poch_channel_analog_on(channel); - - printk(KERN_WARNING "channel_dma_init\n"); - - channel_dma_init(channel); - - printk(KERN_WARNING "poch_channel_analog_on\n"); - - if (usage == 1) { - printk(KERN_WARNING "setting up DMA\n"); - - /* Initialize DMA Controller. */ - iowrite32(FPGA_CAP_FIFO_REG, bridge + BRIDGE_STAT_2_REG); - iowrite32(FPGA_DMA_DESC_1_REG, bridge + BRIDGE_STAT_3_REG); - - ioread32(fpga + FPGA_DMA_INT_STAT_REG); - ioread32(fpga + FPGA_INT_STAT_REG); - ioread32(bridge + BRIDGE_INT_STAT_REG); - - /* Initialize Interrupts. FIXME: Enable temperature - * handling We are enabling both Tx and Rx channel - * interrupts here. Do we need to enable interrupts - * only for the current channel? Anyways we won't get - * the interrupt unless the DMA is activated. - */ - iowrite32(BRIDGE_INT_FPGA, bridge + BRIDGE_INT_MASK_REG); - iowrite32(FPGA_INT_DMA_CORE - | FPGA_INT_PLL_UNLOCKED - | FPGA_INT_TX_FF_EMPTY - | FPGA_INT_RX_FF_EMPTY - | FPGA_INT_TX_FF_OVRFLW - | FPGA_INT_RX_FF_OVRFLW, - fpga + FPGA_INT_MASK_REG); - iowrite32(FPGA_DMA_INT_RX | FPGA_DMA_INT_TX, - fpga + FPGA_DMA_INT_MASK_REG); - } - - if (channel->dir == CHANNEL_DIR_TX) { - /* Flush TX FIFO and output data from cardbus. */ - u32 ctl_val = 0; - - ctl_val |= FPGA_TX_CTL_FIFO_FLUSH; - ctl_val |= FPGA_TX_CTL_OUTPUT_CARDBUS; - if (loopback) - ctl_val |= FPGA_TX_CTL_LOOPBACK; - - iowrite32(ctl_val, fpga + FPGA_TX_CTL_REG); - } else { - /* Flush RX FIFO and output data to cardbus. */ - u32 ctl_val = FPGA_RX_CTL_CONT_CAP | FPGA_RX_CTL_FIFO_FLUSH; - if (synth_rx) - ctl_val |= FPGA_RX_CTL_SYNTH_DATA; - - iowrite32(ctl_val, fpga + FPGA_RX_CTL_REG); - } - - atomic_inc(&channel->inited); - - return 0; - - out_power_off: - if (usage == 1) - poch_card_power_off(poch_dev); - out_dec_usage: - atomic_dec(&poch_dev->usage); - atomic_inc(&channel->free); - out: - return ret; -} - -static int poch_release(struct inode *inode, struct file *filp) -{ - struct channel_info *channel = filp->private_data; - struct poch_dev *poch_dev; - int usage; - - poch_dev = container_of(inode->i_cdev, struct poch_dev, cdev); - - usage = atomic_dec_return(&poch_dev->usage); - if (usage == 0) { - printk(KERN_WARNING "poch_card_power_off\n"); - poch_card_power_off(poch_dev); - } - - atomic_dec(&channel->inited); - poch_channel_free_groups(channel); - kfree(channel->groups); - atomic_inc(&channel->free); - - return 0; -} - -/* - * Map the the group buffers, to user space. - */ -static int poch_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct channel_info *channel = filp->private_data; - - unsigned long start; - unsigned long size; - - unsigned long group_pages; - unsigned long total_group_pages; - - int pg_num; - struct page *pg; - - int i; - int ret; - - printk(KERN_WARNING "poch_mmap\n"); - - if (vma->vm_pgoff) { - printk(KERN_WARNING PFX "page offset: %lu\n", vma->vm_pgoff); - return -EINVAL; - } - - group_pages = npages(channel->group_size); - total_group_pages = group_pages * channel->group_count; - - size = vma->vm_end - vma->vm_start; - if (size != total_group_pages * PAGE_SIZE) { - printk(KERN_WARNING PFX "required %lu bytes\n", size); - return -EINVAL; - } - - start = vma->vm_start; - - for (i = 0; i < channel->group_count; i++) { - pg = channel->groups[i].pg; - for (pg_num = 0; pg_num < group_pages; pg_num++, pg++) { - printk(KERN_DEBUG PFX "%d: group %d: 0x%lx\n", - pg_num, i, start); - ret = vm_insert_page(vma, start, pg); - if (ret) { - printk(KERN_DEBUG PFX - "vm_insert 2 failed at %d\n", pg_num); - return ret; - } - start += PAGE_SIZE; - } - } - - return 0; -} - -/* - * Check whether there is some group that the user space has not - * consumed yet. When the user space consumes a group, it sets it to - * -1. Cosuming could be reading data in case of RX and filling a - * buffer in case of TX. - */ -static int poch_channel_available(struct channel_info *channel) -{ - int available = 0; - - spin_lock_irq(&channel->group_offsets_lock); - - if (channel->consumed != channel->transfer) - available = 1; - - spin_unlock_irq(&channel->group_offsets_lock); - - return available; -} - -static unsigned int poch_poll(struct file *filp, poll_table *pt) -{ - struct channel_info *channel = filp->private_data; - unsigned int ret = 0; - - poll_wait(filp, &channel->wq, pt); - - if (poch_channel_available(channel)) { - if (channel->dir == CHANNEL_DIR_RX) - ret = POLLIN | POLLRDNORM; - else - ret = POLLOUT | POLLWRNORM; - } - - return ret; -} - -static int poch_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - struct channel_info *channel = filp->private_data; - void __iomem *fpga = channel->fpga_iomem; - void __iomem *bridge = channel->bridge_iomem; - void __user *argp = (void __user *)arg; - struct vm_area_struct *vms; - struct poch_counters counters; - int ret; - - switch (cmd) { - case POCH_IOC_TRANSFER_START: - switch (channel->chno) { - case CHNO_TX_CHANNEL: - printk(KERN_INFO PFX "ioctl: Tx start\n"); - iowrite32(0x1, fpga + FPGA_TX_TRIGGER_REG); - iowrite32(0x1, fpga + FPGA_TX_ENABLE_REG); - - /* FIXME: Does it make sense to do a DMA GO - * twice, once in Tx and once in Rx. - */ - iowrite32(0x1, bridge + BRIDGE_DMA_GO_REG); - break; - case CHNO_RX_CHANNEL: - printk(KERN_INFO PFX "ioctl: Rx start\n"); - iowrite32(0x1, fpga + FPGA_RX_ARM_REG); - iowrite32(0x1, bridge + BRIDGE_DMA_GO_REG); - break; - } - break; - case POCH_IOC_TRANSFER_STOP: - switch (channel->chno) { - case CHNO_TX_CHANNEL: - printk(KERN_INFO PFX "ioctl: Tx stop\n"); - iowrite32(0x0, fpga + FPGA_TX_ENABLE_REG); - iowrite32(0x0, fpga + FPGA_TX_TRIGGER_REG); - iowrite32(0x0, bridge + BRIDGE_DMA_GO_REG); - break; - case CHNO_RX_CHANNEL: - printk(KERN_INFO PFX "ioctl: Rx stop\n"); - iowrite32(0x0, fpga + FPGA_RX_ARM_REG); - iowrite32(0x0, bridge + BRIDGE_DMA_GO_REG); - break; - } - break; - case POCH_IOC_CONSUME: - { - int available; - int nfetch; - unsigned int from; - unsigned int count; - unsigned int i, j; - struct poch_consume consume; - struct poch_consume *uconsume; - - uconsume = argp; - ret = copy_from_user(&consume, uconsume, sizeof(consume)); - if (ret) - return ret; - - spin_lock_irq(&channel->group_offsets_lock); - - channel->consumed += consume.nflush; - channel->consumed %= channel->group_count; - - available = channel->transfer - channel->consumed; - if (available < 0) - available += channel->group_count; - - from = channel->consumed; - - spin_unlock_irq(&channel->group_offsets_lock); - - nfetch = consume.nfetch; - count = min(available, nfetch); - - for (i = 0; i < count; i++) { - j = (from + i) % channel->group_count; - ret = put_user(channel->groups[j].user_offset, - &consume.offsets[i]); - if (ret) - return -EFAULT; - } - - ret = put_user(count, &uconsume->nfetch); - if (ret) - return -EFAULT; - - break; - } - case POCH_IOC_GET_COUNTERS: - if (!access_ok(VERIFY_WRITE, argp, sizeof(struct poch_counters))) - return -EFAULT; - - spin_lock_irq(&channel->counters_lock); - counters = channel->counters; - __poch_channel_clear_counters(channel); - spin_unlock_irq(&channel->counters_lock); - - ret = copy_to_user(argp, &counters, - sizeof(struct poch_counters)); - if (ret) - return ret; - - break; - case POCH_IOC_SYNC_GROUP_FOR_USER: - case POCH_IOC_SYNC_GROUP_FOR_DEVICE: - vms = find_vma(current->mm, arg); - if (!vms) - /* Address not mapped. */ - return -EINVAL; - if (vms->vm_file != filp) - /* Address mapped from different device/file. */ - return -EINVAL; - - flush_cache_range(vms, arg, arg + channel->group_size); - break; - } - return 0; -} - -static struct file_operations poch_fops = { - .owner = THIS_MODULE, - .open = poch_open, - .release = poch_release, - .ioctl = poch_ioctl, - .poll = poch_poll, - .mmap = poch_mmap -}; - -static void poch_irq_dma(struct channel_info *channel) -{ - u32 prev_transfer; - u32 curr_transfer; - long groups_done; - unsigned long i, j; - struct poch_group_info *groups; - u32 curr_group_reg; - - if (!atomic_read(&channel->inited)) - return; - - prev_transfer = channel->transfer; - - if (channel->chno == CHNO_RX_CHANNEL) - curr_group_reg = FPGA_RX_CURR_GROUP_REG; - else - curr_group_reg = FPGA_TX_CURR_GROUP_REG; - - curr_transfer = ioread32(channel->fpga_iomem + curr_group_reg); - - groups_done = curr_transfer - prev_transfer; - /* Check wrap over, and handle it. */ - if (groups_done <= 0) - groups_done += channel->group_count; - - groups = channel->groups; - - spin_lock(&channel->group_offsets_lock); - - for (i = 0; i < groups_done; i++) { - j = (prev_transfer + i) % channel->group_count; - - channel->transfer += 1; - channel->transfer %= channel->group_count; - - if (channel->transfer == channel->consumed) { - channel->consumed += 1; - channel->consumed %= channel->group_count; - } - } - - spin_unlock(&channel->group_offsets_lock); - - wake_up_interruptible(&channel->wq); -} - -static irqreturn_t poch_irq_handler(int irq, void *p) -{ - struct poch_dev *poch_dev = p; - void __iomem *bridge = poch_dev->bridge_iomem; - void __iomem *fpga = poch_dev->fpga_iomem; - struct channel_info *channel_rx = &poch_dev->channels[CHNO_RX_CHANNEL]; - struct channel_info *channel_tx = &poch_dev->channels[CHNO_TX_CHANNEL]; - u32 bridge_stat; - u32 fpga_stat; - u32 dma_stat; - - bridge_stat = ioread32(bridge + BRIDGE_INT_STAT_REG); - fpga_stat = ioread32(fpga + FPGA_INT_STAT_REG); - dma_stat = ioread32(fpga + FPGA_DMA_INT_STAT_REG); - - ioread32(fpga + FPGA_DMA_INT_STAT_REG); - ioread32(fpga + FPGA_INT_STAT_REG); - ioread32(bridge + BRIDGE_INT_STAT_REG); - - if (bridge_stat & BRIDGE_INT_FPGA) { - if (fpga_stat & FPGA_INT_DMA_CORE) { - if (dma_stat & FPGA_DMA_INT_RX) - poch_irq_dma(channel_rx); - if (dma_stat & FPGA_DMA_INT_TX) - poch_irq_dma(channel_tx); - } - if (fpga_stat & FPGA_INT_PLL_UNLOCKED) { - channel_tx->counters.pll_unlock++; - channel_rx->counters.pll_unlock++; - if (printk_ratelimit()) - printk(KERN_WARNING PFX "PLL unlocked\n"); - } - if (fpga_stat & FPGA_INT_TX_FF_EMPTY) - channel_tx->counters.fifo_empty++; - if (fpga_stat & FPGA_INT_TX_FF_OVRFLW) - channel_tx->counters.fifo_overflow++; - if (fpga_stat & FPGA_INT_RX_FF_EMPTY) - channel_rx->counters.fifo_empty++; - if (fpga_stat & FPGA_INT_RX_FF_OVRFLW) - channel_rx->counters.fifo_overflow++; - - /* - * FIXME: These errors should be notified through the - * poll interface as POLLERR. - */ - - /* Re-enable interrupts. */ - iowrite32(BRIDGE_INT_FPGA, bridge + BRIDGE_INT_MASK_REG); - - return IRQ_HANDLED; - } - - return IRQ_NONE; -} - -static void poch_class_dev_unregister(struct poch_dev *poch_dev, int id) -{ - int i, j; - int nattrs; - struct channel_info *channel; - dev_t devno; - - if (poch_dev->dev == NULL) - return; - - for (i = 0; i < poch_dev->nchannels; i++) { - channel = &poch_dev->channels[i]; - devno = poch_first_dev + (id * poch_dev->nchannels) + i; - - if (!channel->dev) - continue; - - nattrs = sizeof(poch_class_attrs)/sizeof(poch_class_attrs[0]); - for (j = 0; j < nattrs; j++) - device_remove_file(channel->dev, poch_class_attrs[j]); - - device_unregister(channel->dev); - } - - device_unregister(poch_dev->dev); -} - -static int __devinit poch_class_dev_register(struct poch_dev *poch_dev, - int id) -{ - struct device *dev = &poch_dev->pci_dev->dev; - int i, j; - int nattrs; - int ret; - struct channel_info *channel; - dev_t devno; - - poch_dev->dev = device_create(poch_cls, &poch_dev->pci_dev->dev, - MKDEV(0, 0), NULL, "poch%d", id); - if (IS_ERR(poch_dev->dev)) { - dev_err(dev, "error creating parent class device"); - ret = PTR_ERR(poch_dev->dev); - poch_dev->dev = NULL; - return ret; - } - - for (i = 0; i < poch_dev->nchannels; i++) { - channel = &poch_dev->channels[i]; - - devno = poch_first_dev + (id * poch_dev->nchannels) + i; - channel->dev = device_create(poch_cls, poch_dev->dev, devno, - NULL, "ch%d", i); - if (IS_ERR(channel->dev)) { - dev_err(dev, "error creating channel class device"); - ret = PTR_ERR(channel->dev); - channel->dev = NULL; - poch_class_dev_unregister(poch_dev, id); - return ret; - } - - dev_set_drvdata(channel->dev, channel); - nattrs = sizeof(poch_class_attrs)/sizeof(poch_class_attrs[0]); - for (j = 0; j < nattrs; j++) { - ret = device_create_file(channel->dev, - poch_class_attrs[j]); - if (ret) { - dev_err(dev, "error creating attribute file"); - poch_class_dev_unregister(poch_dev, id); - return ret; - } - } - } - - return 0; -} - -static int __devinit poch_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *pci_id) -{ - struct device *dev = &pdev->dev; - struct poch_dev *poch_dev; - struct uio_info *uio; - int ret; - int id; - int i; - - poch_dev = kzalloc(sizeof(struct poch_dev), GFP_KERNEL); - if (!poch_dev) { - dev_err(dev, "error allocating priv. data memory\n"); - return -ENOMEM; - } - - poch_dev->pci_dev = pdev; - uio = &poch_dev->uio; - - pci_set_drvdata(pdev, poch_dev); - - spin_lock_init(&poch_dev->iomem_lock); - - poch_dev->nchannels = POCH_NCHANNELS; - poch_dev->channels[CHNO_RX_CHANNEL].dir = CHANNEL_DIR_RX; - poch_dev->channels[CHNO_TX_CHANNEL].dir = CHANNEL_DIR_TX; - - for (i = 0; i < poch_dev->nchannels; i++) { - init_waitqueue_head(&poch_dev->channels[i].wq); - atomic_set(&poch_dev->channels[i].free, 1); - atomic_set(&poch_dev->channels[i].inited, 0); - } - - ret = pci_enable_device(pdev); - if (ret) { - dev_err(dev, "error enabling device\n"); - goto out_free; - } - - ret = pci_request_regions(pdev, "poch"); - if (ret) { - dev_err(dev, "error requesting resources\n"); - goto out_disable; - } - - uio->mem[0].addr = pci_resource_start(pdev, 1); - if (!uio->mem[0].addr) { - dev_err(dev, "invalid BAR1\n"); - ret = -ENODEV; - goto out_release; - } - - uio->mem[0].size = pci_resource_len(pdev, 1); - uio->mem[0].memtype = UIO_MEM_PHYS; - - uio->name = "poch"; - uio->version = "0.0.1"; - uio->irq = -1; - ret = uio_register_device(dev, uio); - if (ret) { - dev_err(dev, "error register UIO device: %d\n", ret); - goto out_release; - } - - poch_dev->bridge_iomem = ioremap(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - if (poch_dev->bridge_iomem == NULL) { - dev_err(dev, "error mapping bridge (bar0) registers\n"); - ret = -ENOMEM; - goto out_uio_unreg; - } - - poch_dev->fpga_iomem = ioremap(pci_resource_start(pdev, 1), - pci_resource_len(pdev, 1)); - if (poch_dev->fpga_iomem == NULL) { - dev_err(dev, "error mapping fpga (bar1) registers\n"); - ret = -ENOMEM; - goto out_bar0_unmap; - } - - ret = request_irq(pdev->irq, poch_irq_handler, IRQF_SHARED, - dev_name(dev), poch_dev); - if (ret) { - dev_err(dev, "error requesting IRQ %u\n", pdev->irq); - ret = -ENOMEM; - goto out_bar1_unmap; - } - - if (!idr_pre_get(&poch_ids, GFP_KERNEL)) { - dev_err(dev, "error allocating memory ids\n"); - ret = -ENOMEM; - goto out_free_irq; - } - - idr_get_new(&poch_ids, poch_dev, &id); - if (id >= MAX_POCH_CARDS) { - dev_err(dev, "minors exhausted\n"); - ret = -EBUSY; - goto out_free_irq; - } - - cdev_init(&poch_dev->cdev, &poch_fops); - poch_dev->cdev.owner = THIS_MODULE; - ret = cdev_add(&poch_dev->cdev, - poch_first_dev + (id * poch_dev->nchannels), - poch_dev->nchannels); - if (ret) { - dev_err(dev, "error register character device\n"); - goto out_idr_remove; - } - - ret = poch_class_dev_register(poch_dev, id); - if (ret) - goto out_cdev_del; - - return 0; - - out_cdev_del: - cdev_del(&poch_dev->cdev); - out_idr_remove: - idr_remove(&poch_ids, id); - out_free_irq: - free_irq(pdev->irq, poch_dev); - out_bar1_unmap: - iounmap(poch_dev->fpga_iomem); - out_bar0_unmap: - iounmap(poch_dev->bridge_iomem); - out_uio_unreg: - uio_unregister_device(uio); - out_release: - pci_release_regions(pdev); - out_disable: - pci_disable_device(pdev); - out_free: - kfree(poch_dev); - return ret; -} - -/* - * FIXME: We are yet to handle the hot unplug case. - */ -static void poch_pci_remove(struct pci_dev *pdev) -{ - struct poch_dev *poch_dev = pci_get_drvdata(pdev); - struct uio_info *uio = &poch_dev->uio; - unsigned int minor = MINOR(poch_dev->cdev.dev); - unsigned int id = minor / poch_dev->nchannels; - - poch_class_dev_unregister(poch_dev, id); - cdev_del(&poch_dev->cdev); - idr_remove(&poch_ids, id); - free_irq(pdev->irq, poch_dev); - iounmap(poch_dev->fpga_iomem); - iounmap(poch_dev->bridge_iomem); - uio_unregister_device(uio); - pci_release_regions(pdev); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); - iounmap(uio->mem[0].internal_addr); - - kfree(poch_dev); -} - -static const struct pci_device_id poch_pci_ids[] /* __devinitconst */ = { - { PCI_DEVICE(PCI_VENDOR_ID_RRAPIDS, - PCI_DEVICE_ID_RRAPIDS_POCKET_CHANGE) }, - { 0, } -}; - -static struct pci_driver poch_pci_driver = { - .name = DRV_NAME, - .id_table = poch_pci_ids, - .probe = poch_pci_probe, - .remove = poch_pci_remove, -}; - -static int __init poch_init_module(void) -{ - int ret = 0; - - ret = alloc_chrdev_region(&poch_first_dev, 0, - MAX_POCH_DEVICES, DRV_NAME); - if (ret) { - printk(KERN_ERR PFX "error allocating device no."); - return ret; - } - - poch_cls = class_create(THIS_MODULE, "pocketchange"); - if (IS_ERR(poch_cls)) { - ret = PTR_ERR(poch_cls); - goto out_unreg_chrdev; - } - - ret = pci_register_driver(&poch_pci_driver); - if (ret) { - printk(KERN_ERR PFX "error register PCI device"); - goto out_class_destroy; - } - - return 0; - - out_class_destroy: - class_destroy(poch_cls); - - out_unreg_chrdev: - unregister_chrdev_region(poch_first_dev, MAX_POCH_DEVICES); - - return ret; -} - -static void __exit poch_exit_module(void) -{ - pci_unregister_driver(&poch_pci_driver); - class_destroy(poch_cls); - unregister_chrdev_region(poch_first_dev, MAX_POCH_DEVICES); -} - -module_init(poch_init_module); -module_exit(poch_exit_module); - -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/poch/poch.h b/drivers/staging/poch/poch.h deleted file mode 100644 index 8b08385861fd..000000000000 --- a/drivers/staging/poch/poch.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * User-space DMA and UIO based Redrapids Pocket Change CardBus driver - * - * Copyright 2008 Vijay Kumar - * - * Part of userspace API. Should be moved to a header file in - * include/linux for final version. - * - */ - -#include - -struct poch_counters { - __u32 fifo_empty; - __u32 fifo_overflow; - __u32 pll_unlock; -}; - -struct poch_consume { - __u32 __user *offsets; - __u32 nfetch; - __u32 nflush; -}; - -#define POCH_IOC_NUM '9' - -#define POCH_IOC_TRANSFER_START _IO(POCH_IOC_NUM, 0) -#define POCH_IOC_TRANSFER_STOP _IO(POCH_IOC_NUM, 1) -#define POCH_IOC_GET_COUNTERS _IOR(POCH_IOC_NUM, 2, \ - struct poch_counters) -#define POCH_IOC_SYNC_GROUP_FOR_USER _IO(POCH_IOC_NUM, 3) -#define POCH_IOC_SYNC_GROUP_FOR_DEVICE _IO(POCH_IOC_NUM, 4) - -#define POCH_IOC_CONSUME _IOWR(POCH_IOC_NUM, 5, \ - struct poch_consume) -- cgit v1.2.3 From 173f3463804dbd583887de9871e85408942f90ee Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Thu, 4 Mar 2010 17:46:28 +0000 Subject: staging: hv: Remove Ringbuffer from TODO line Remove Ringbuffer work line item from TODO file. The ring buffer in the Hyper-V Linux drivers is used to communicate with the parent partition running Windows Server 2008 Hyper-V. The ring buffer functionality on the Hyper-V Linux drivers is written to be functionally compatible with the ring buffer functionality on the Hyper-V Server. Consequently, it is not possible to make any changes that might break the compatibility with server side ring buffer implementation. Signed-off-by: Hank Janssen Signed-off-by: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/TODO | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/TODO b/drivers/staging/hv/TODO index dbfbde937a66..efe8ce90ff4c 100644 --- a/drivers/staging/hv/TODO +++ b/drivers/staging/hv/TODO @@ -1,7 +1,6 @@ TODO: - fix remaining checkpatch warnings and errors - use of /** when it is not a kerneldoc header - - remove RingBuffer.c to us in-kernel ringbuffer functions instead. - audit the vmbus to verify it is working properly with the driver model - convert vmbus driver interface function pointer tables -- cgit v1.2.3 From 3e18951955797872558dad615851a4ca63b2770e Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Thu, 4 Mar 2010 22:11:00 +0000 Subject: staging: hv: Corrected all header comment formats kernel-doc format Removed kerneldoc /** from functions that should not have them. Added proper kerneldoc headers to functions that should have them. This includes fixes as pointed out by Randy Dunlap and Joe Perches. Cc: Joe Perches Acked-by: Randy Dunlap Signed-off-by: Hank Janssen Signed-off-by: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Channel.c | 49 ++++++++++++++------------ drivers/staging/hv/ChannelMgmt.c | 33 +++++++++--------- drivers/staging/hv/Connection.c | 14 ++++---- drivers/staging/hv/Hv.c | 18 +++++----- drivers/staging/hv/NetVsc.c | 8 ++--- drivers/staging/hv/StorVsc.c | 10 +++--- drivers/staging/hv/TODO | 1 - drivers/staging/hv/Vmbus.c | 26 +++++++------- drivers/staging/hv/VmbusApi.h | 18 ++++++++++ drivers/staging/hv/blkvsc_drv.c | 6 ++-- drivers/staging/hv/netvsc_drv.c | 7 ++-- drivers/staging/hv/osd.c | 70 +++++++++++++++++++++++++++++++++++++ drivers/staging/hv/storvsc_drv.c | 14 ++++---- drivers/staging/hv/vmbus_drv.c | 74 +++++++++++++++++++++++++++------------- 14 files changed, 234 insertions(+), 114 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/Channel.c index e69e9ee704ac..328d3a0d0bd8 100644 --- a/drivers/staging/hv/Channel.c +++ b/drivers/staging/hv/Channel.c @@ -65,8 +65,9 @@ static void DumpMonitorPage(struct hv_monitor_page *MonitorPage) } #endif -/** - * VmbusChannelSetEvent - Trigger an event notification on the specified channel. +/* + * VmbusChannelSetEvent - Trigger an event notification on the specified + * channel. */ static void VmbusChannelSetEvent(struct vmbus_channel *Channel) { @@ -120,7 +121,7 @@ static void VmbusChannelClearEvent(struct vmbus_channel *channel) } #endif -/** +/* * VmbusChannelGetDebugInfo -Retrieve various channel debug info */ void VmbusChannelGetDebugInfo(struct vmbus_channel *Channel, @@ -165,7 +166,7 @@ void VmbusChannelGetDebugInfo(struct vmbus_channel *Channel, RingBufferGetDebugInfo(&Channel->Outbound, &DebugInfo->Outbound); } -/** +/* * VmbusChannelOpen - Open the specified channel. */ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, @@ -283,8 +284,9 @@ Cleanup: return 0; } -/** - * DumpGpadlBody - Dump the gpadl body message to the console for debugging purposes. +/* + * DumpGpadlBody - Dump the gpadl body message to the console for + * debugging purposes. */ static void DumpGpadlBody(struct vmbus_channel_gpadl_body *Gpadl, u32 Len) { @@ -300,8 +302,9 @@ static void DumpGpadlBody(struct vmbus_channel_gpadl_body *Gpadl, u32 Len) i, Gpadl->Pfn[i]); } -/** - * DumpGpadlHeader - Dump the gpadl header message to the console for debugging purposes. +/* + * DumpGpadlHeader - Dump the gpadl header message to the console for + * debugging purposes. */ static void DumpGpadlHeader(struct vmbus_channel_gpadl_header *Gpadl) { @@ -325,7 +328,7 @@ static void DumpGpadlHeader(struct vmbus_channel_gpadl_header *Gpadl) } } -/** +/* * VmbusChannelCreateGpadlHeader - Creates a gpadl for the specified buffer */ static int VmbusChannelCreateGpadlHeader(void *Kbuffer, u32 Size, @@ -441,7 +444,7 @@ static int VmbusChannelCreateGpadlHeader(void *Kbuffer, u32 Size, return 0; } -/** +/* * VmbusChannelEstablishGpadl - Estabish a GPADL for the specified buffer * * @Channel: a channel @@ -545,7 +548,7 @@ Cleanup: return ret; } -/** +/* * VmbusChannelTeardownGpadl -Teardown the specified GPADL handle */ int VmbusChannelTeardownGpadl(struct vmbus_channel *Channel, u32 GpadlHandle) @@ -598,7 +601,7 @@ int VmbusChannelTeardownGpadl(struct vmbus_channel *Channel, u32 GpadlHandle) return ret; } -/** +/* * VmbusChannelClose - Close the specified channel */ void VmbusChannelClose(struct vmbus_channel *Channel) @@ -663,7 +666,7 @@ void VmbusChannelClose(struct vmbus_channel *Channel) DPRINT_EXIT(VMBUS); } -/** +/* * VmbusChannelSendPacket - Send the specified buffer on the given channel */ int VmbusChannelSendPacket(struct vmbus_channel *Channel, const void *Buffer, @@ -709,8 +712,9 @@ int VmbusChannelSendPacket(struct vmbus_channel *Channel, const void *Buffer, return ret; } -/** - * VmbusChannelSendPacketPageBuffer - Send a range of single-page buffer packets using a GPADL Direct packet type. +/* + * VmbusChannelSendPacketPageBuffer - Send a range of single-page buffer + * packets using a GPADL Direct packet type. */ int VmbusChannelSendPacketPageBuffer(struct vmbus_channel *Channel, struct hv_page_buffer PageBuffers[], @@ -774,8 +778,9 @@ int VmbusChannelSendPacketPageBuffer(struct vmbus_channel *Channel, return ret; } -/** - * VmbusChannelSendPacketMultiPageBuffer - Send a multi-page buffer packet using a GPADL Direct packet type. +/* + * VmbusChannelSendPacketMultiPageBuffer - Send a multi-page buffer packet + * using a GPADL Direct packet type. */ int VmbusChannelSendPacketMultiPageBuffer(struct vmbus_channel *Channel, struct hv_multipage_buffer *MultiPageBuffer, @@ -843,7 +848,7 @@ int VmbusChannelSendPacketMultiPageBuffer(struct vmbus_channel *Channel, return ret; } -/** +/* * VmbusChannelRecvPacket - Retrieve the user packet on the specified channel */ /* TODO: Do we ever receive a gpa direct packet other than the ones we send ? */ @@ -909,7 +914,7 @@ int VmbusChannelRecvPacket(struct vmbus_channel *Channel, void *Buffer, return 0; } -/** +/* * VmbusChannelRecvPacketRaw - Retrieve the raw packet on the specified channel */ int VmbusChannelRecvPacketRaw(struct vmbus_channel *Channel, void *Buffer, @@ -972,7 +977,7 @@ int VmbusChannelRecvPacketRaw(struct vmbus_channel *Channel, void *Buffer, return 0; } -/** +/* * VmbusChannelOnChannelEvent - Channel event callback */ void VmbusChannelOnChannelEvent(struct vmbus_channel *Channel) @@ -985,7 +990,7 @@ void VmbusChannelOnChannelEvent(struct vmbus_channel *Channel) mod_timer(&Channel->poll_timer, jiffies + usecs_to_jiffies(100)); } -/** +/* * VmbusChannelOnTimer - Timer event callback */ void VmbusChannelOnTimer(unsigned long data) @@ -996,7 +1001,7 @@ void VmbusChannelOnTimer(unsigned long data) channel->OnChannelCallback(channel->ChannelCallbackContext); } -/** +/* * DumpVmbusChannel - Dump vmbus channel info to the console */ static void DumpVmbusChannel(struct vmbus_channel *Channel) diff --git a/drivers/staging/hv/ChannelMgmt.c b/drivers/staging/hv/ChannelMgmt.c index 5f92c2102ab4..43f28f23c317 100644 --- a/drivers/staging/hv/ChannelMgmt.c +++ b/drivers/staging/hv/ChannelMgmt.c @@ -71,7 +71,7 @@ static const struct hv_guid }, }; -/** +/* * AllocVmbusChannel - Allocate and initialize a vmbus channel object */ struct vmbus_channel *AllocVmbusChannel(void) @@ -97,7 +97,7 @@ struct vmbus_channel *AllocVmbusChannel(void) return channel; } -/** +/* * ReleaseVmbusChannel - Release the vmbus channel object itself */ static inline void ReleaseVmbusChannel(void *context) @@ -115,7 +115,7 @@ static inline void ReleaseVmbusChannel(void *context) DPRINT_EXIT(VMBUS); } -/** +/* * FreeVmbusChannel - Release the resources used by the vmbus channel object */ void FreeVmbusChannel(struct vmbus_channel *Channel) @@ -131,7 +131,7 @@ void FreeVmbusChannel(struct vmbus_channel *Channel) Channel); } -/** +/* * VmbusChannelProcessOffer - Process the offer by creating a channel/device associated with this offer */ static void VmbusChannelProcessOffer(void *context) @@ -213,7 +213,7 @@ static void VmbusChannelProcessOffer(void *context) DPRINT_EXIT(VMBUS); } -/** +/* * VmbusChannelProcessRescindOffer - Rescind the offer by initiating a device removal */ static void VmbusChannelProcessRescindOffer(void *context) @@ -225,7 +225,7 @@ static void VmbusChannelProcessRescindOffer(void *context) DPRINT_EXIT(VMBUS); } -/** +/* * VmbusChannelOnOffer - Handler for channel offers from vmbus in parent partition. * * We ignore all offers except network and storage offers. For each network and @@ -308,7 +308,7 @@ static void VmbusChannelOnOffer(struct vmbus_channel_message_header *hdr) DPRINT_EXIT(VMBUS); } -/** +/* * VmbusChannelOnOfferRescind - Rescind offer handler. * * We queue a work item to process this offer synchronously @@ -335,7 +335,7 @@ static void VmbusChannelOnOfferRescind(struct vmbus_channel_message_header *hdr) DPRINT_EXIT(VMBUS); } -/** +/* * VmbusChannelOnOffersDelivered - This is invoked when all offers have been delivered. * * Nothing to do here. @@ -347,7 +347,7 @@ static void VmbusChannelOnOffersDelivered( DPRINT_EXIT(VMBUS); } -/** +/* * VmbusChannelOnOpenResult - Open result handler. * * This is invoked when we received a response to our channel open request. @@ -395,7 +395,7 @@ static void VmbusChannelOnOpenResult(struct vmbus_channel_message_header *hdr) DPRINT_EXIT(VMBUS); } -/** +/* * VmbusChannelOnGpadlCreated - GPADL created handler. * * This is invoked when we received a response to our gpadl create request. @@ -447,7 +447,7 @@ static void VmbusChannelOnGpadlCreated(struct vmbus_channel_message_header *hdr) DPRINT_EXIT(VMBUS); } -/** +/* * VmbusChannelOnGpadlTorndown - GPADL torndown handler. * * This is invoked when we received a response to our gpadl teardown request. @@ -495,7 +495,7 @@ static void VmbusChannelOnGpadlTorndown( DPRINT_EXIT(VMBUS); } -/** +/* * VmbusChannelOnVersionResponse - Version response handler * * This is invoked when we received a response to our initiate contact request. @@ -558,7 +558,7 @@ static struct vmbus_channel_message_table_entry {ChannelMessageUnload, NULL}, }; -/** +/* * VmbusOnChannelMessage - Handler for channel protocol messages. * * This is invoked in the vmbus worker thread context. @@ -597,7 +597,7 @@ void VmbusOnChannelMessage(void *Context) DPRINT_EXIT(VMBUS); } -/** +/* * VmbusChannelRequestOffers - Send a request to get all our pending offers. */ int VmbusChannelRequestOffers(void) @@ -651,8 +651,9 @@ Cleanup: return ret; } -/** - * VmbusChannelReleaseUnattachedChannels - Release channels that are unattached/unconnected ie (no drivers associated) +/* + * VmbusChannelReleaseUnattachedChannels - Release channels that are + * unattached/unconnected ie (no drivers associated) */ void VmbusChannelReleaseUnattachedChannels(void) { diff --git a/drivers/staging/hv/Connection.c b/drivers/staging/hv/Connection.c index e0ea9cf90f03..cf9c416e4b16 100644 --- a/drivers/staging/hv/Connection.c +++ b/drivers/staging/hv/Connection.c @@ -34,7 +34,7 @@ struct VMBUS_CONNECTION gVmbusConnection = { .NextGpadlHandle = ATOMIC_INIT(0xE1E10), }; -/** +/* * VmbusConnect - Sends a connect request on the partition service connection */ int VmbusConnect(void) @@ -180,7 +180,7 @@ Cleanup: return ret; } -/** +/* * VmbusDisconnect - Sends a disconnect request on the partition service connection */ int VmbusDisconnect(void) @@ -218,7 +218,7 @@ Cleanup: return ret; } -/** +/* * GetChannelFromRelId - Get the channel object given its child relative id (ie channel id) */ struct vmbus_channel *GetChannelFromRelId(u32 relId) @@ -239,7 +239,7 @@ struct vmbus_channel *GetChannelFromRelId(u32 relId) return foundChannel; } -/** +/* * VmbusProcessChannelEvent - Process a channel event notification */ static void VmbusProcessChannelEvent(void *context) @@ -267,7 +267,7 @@ static void VmbusProcessChannelEvent(void *context) } } -/** +/* * VmbusOnEvents - Handler for events */ void VmbusOnEvents(void) @@ -308,7 +308,7 @@ void VmbusOnEvents(void) return; } -/** +/* * VmbusPostMessage - Send a msg on the vmbus's message connection */ int VmbusPostMessage(void *buffer, size_t bufferLen) @@ -320,7 +320,7 @@ int VmbusPostMessage(void *buffer, size_t bufferLen) return HvPostMessage(connId, 1, buffer, bufferLen); } -/** +/* * VmbusSetEvent - Send an event notification to the parent */ int VmbusSetEvent(u32 childRelId) diff --git a/drivers/staging/hv/Hv.c b/drivers/staging/hv/Hv.c index 5d53889fb4a4..bfcb75008bf5 100644 --- a/drivers/staging/hv/Hv.c +++ b/drivers/staging/hv/Hv.c @@ -35,7 +35,7 @@ struct hv_context gHvContext = { .SignalEventBuffer = NULL, }; -/** +/* * HvQueryHypervisorPresence - Query the cpuid for presense of windows hypervisor */ static int HvQueryHypervisorPresence(void) @@ -56,7 +56,7 @@ static int HvQueryHypervisorPresence(void) return ecx & HV_PRESENT_BIT; } -/** +/* * HvQueryHypervisorInfo - Get version info of the windows hypervisor */ static int HvQueryHypervisorInfo(void) @@ -125,7 +125,7 @@ static int HvQueryHypervisorInfo(void) return maxLeaf; } -/** +/* * HvDoHypercall - Invoke the specified hypercall */ static u64 HvDoHypercall(u64 Control, void *Input, void *Output) @@ -180,7 +180,7 @@ static u64 HvDoHypercall(u64 Control, void *Input, void *Output) #endif /* !x86_64 */ } -/** +/* * HvInit - Main initialization routine. * * This routine must be called before any other routines in here are called @@ -294,7 +294,7 @@ Cleanup: return ret; } -/** +/* * HvCleanup - Cleanup routine. * * This routine is called normally during driver unloading or exiting. @@ -321,7 +321,7 @@ void HvCleanup(void) DPRINT_EXIT(VMBUS); } -/** +/* * HvPostMessage - Post a message using the hypervisor message IPC. * * This involves a hypercall. @@ -362,7 +362,7 @@ u16 HvPostMessage(union hv_connection_id connectionId, } -/** +/* * HvSignalEvent - Signal an event on the specified connection using the hypervisor event IPC. * * This involves a hypercall. @@ -376,7 +376,7 @@ u16 HvSignalEvent(void) return status; } -/** +/* * HvSynicInit - Initialize the Synthethic Interrupt Controller. * * If it is already initialized by another entity (ie x2v shim), we need to @@ -482,7 +482,7 @@ Cleanup: return; } -/** +/* * HvSynicCleanup - Cleanup routine for HvSynicInit(). */ void HvSynicCleanup(void *arg) diff --git a/drivers/staging/hv/NetVsc.c b/drivers/staging/hv/NetVsc.c index e4bf82297504..e1ca343119d7 100644 --- a/drivers/staging/hv/NetVsc.c +++ b/drivers/staging/hv/NetVsc.c @@ -167,7 +167,7 @@ static struct netvsc_device *ReleaseInboundNetDevice(struct hv_device *Device) return netDevice; } -/** +/* * NetVscInitialize - Main entry point */ int NetVscInitialize(struct hv_driver *drv) @@ -705,7 +705,7 @@ static void NetVscDisconnectFromVsp(struct netvsc_device *NetDevice) DPRINT_EXIT(NETVSC); } -/** +/* * NetVscOnDeviceAdd - Callback when the device belonging to this driver is added */ static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) @@ -807,7 +807,7 @@ Cleanup: return ret; } -/** +/* * NetVscOnDeviceRemove - Callback when the root bus device is removed */ static int NetVscOnDeviceRemove(struct hv_device *Device) @@ -864,7 +864,7 @@ static int NetVscOnDeviceRemove(struct hv_device *Device) return 0; } -/** +/* * NetVscOnCleanup - Perform any cleanup when the driver is removed */ static void NetVscOnCleanup(struct hv_driver *drv) diff --git a/drivers/staging/hv/StorVsc.c b/drivers/staging/hv/StorVsc.c index e426a23ca537..3592ba2a44b1 100644 --- a/drivers/staging/hv/StorVsc.c +++ b/drivers/staging/hv/StorVsc.c @@ -533,7 +533,7 @@ static int StorVscConnectToVsp(struct hv_device *Device) return ret; } -/** +/* * StorVscOnDeviceAdd - Callback when the device belonging to this driver is added */ static int StorVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) @@ -585,7 +585,7 @@ Cleanup: return ret; } -/** +/* * StorVscOnDeviceRemove - Callback when the our device is being removed */ static int StorVscOnDeviceRemove(struct hv_device *Device) @@ -683,7 +683,7 @@ Cleanup: return ret; } -/** +/* * StorVscOnIORequest - Callback to initiate an I/O request */ static int StorVscOnIORequest(struct hv_device *Device, @@ -783,7 +783,7 @@ static int StorVscOnIORequest(struct hv_device *Device, return ret; } -/** +/* * StorVscOnCleanup - Perform any cleanup when the driver is removed */ static void StorVscOnCleanup(struct hv_driver *Driver) @@ -792,7 +792,7 @@ static void StorVscOnCleanup(struct hv_driver *Driver) DPRINT_EXIT(STORVSC); } -/** +/* * StorVscInitialize - Main entry point */ int StorVscInitialize(struct hv_driver *Driver) diff --git a/drivers/staging/hv/TODO b/drivers/staging/hv/TODO index efe8ce90ff4c..01d4bd052cf5 100644 --- a/drivers/staging/hv/TODO +++ b/drivers/staging/hv/TODO @@ -1,6 +1,5 @@ TODO: - fix remaining checkpatch warnings and errors - - use of /** when it is not a kerneldoc header - audit the vmbus to verify it is working properly with the driver model - convert vmbus driver interface function pointer tables diff --git a/drivers/staging/hv/Vmbus.c b/drivers/staging/hv/Vmbus.c index 2f84bf7c0a9f..90b14beec3aa 100644 --- a/drivers/staging/hv/Vmbus.c +++ b/drivers/staging/hv/Vmbus.c @@ -52,7 +52,7 @@ static const struct hv_guid gVmbusDeviceId = { static struct hv_driver *gDriver; /* vmbus driver object */ static struct hv_device *gDevice; /* vmbus root device */ -/** +/* * VmbusGetChannelOffers - Retrieve the channel offers from the parent partition */ static void VmbusGetChannelOffers(void) @@ -62,7 +62,7 @@ static void VmbusGetChannelOffers(void) DPRINT_EXIT(VMBUS); } -/** +/* * VmbusGetChannelInterface - Get the channel interface */ static void VmbusGetChannelInterface(struct vmbus_channel_interface *Interface) @@ -70,7 +70,7 @@ static void VmbusGetChannelInterface(struct vmbus_channel_interface *Interface) GetChannelInterface(Interface); } -/** +/* * VmbusGetChannelInfo - Get the device info for the specified device object */ static void VmbusGetChannelInfo(struct hv_device *DeviceObject, @@ -79,7 +79,7 @@ static void VmbusGetChannelInfo(struct hv_device *DeviceObject, GetChannelInfo(DeviceObject, DeviceInfo); } -/** +/* * VmbusCreateChildDevice - Creates the child device on the bus that represents the channel offer */ struct hv_device *VmbusChildDeviceCreate(struct hv_guid *DeviceType, @@ -92,7 +92,7 @@ struct hv_device *VmbusChildDeviceCreate(struct hv_guid *DeviceType, Context); } -/** +/* * VmbusChildDeviceAdd - Registers the child device with the vmbus */ int VmbusChildDeviceAdd(struct hv_device *ChildDevice) @@ -102,7 +102,7 @@ int VmbusChildDeviceAdd(struct hv_device *ChildDevice) return vmbusDriver->OnChildDeviceAdd(gDevice, ChildDevice); } -/** +/* * VmbusChildDeviceRemove Unregisters the child device from the vmbus */ void VmbusChildDeviceRemove(struct hv_device *ChildDevice) @@ -112,7 +112,7 @@ void VmbusChildDeviceRemove(struct hv_device *ChildDevice) vmbusDriver->OnChildDeviceRemove(ChildDevice); } -/** +/* * VmbusOnDeviceAdd - Callback when the root bus device is added */ static int VmbusOnDeviceAdd(struct hv_device *dev, void *AdditionalInfo) @@ -141,7 +141,7 @@ static int VmbusOnDeviceAdd(struct hv_device *dev, void *AdditionalInfo) return ret; } -/** +/* * VmbusOnDeviceRemove - Callback when the root bus device is removed */ static int VmbusOnDeviceRemove(struct hv_device *dev) @@ -157,7 +157,7 @@ static int VmbusOnDeviceRemove(struct hv_device *dev) return ret; } -/** +/* * VmbusOnCleanup - Perform any cleanup when the driver is removed */ static void VmbusOnCleanup(struct hv_driver *drv) @@ -169,7 +169,7 @@ static void VmbusOnCleanup(struct hv_driver *drv) DPRINT_EXIT(VMBUS); } -/** +/* * VmbusOnMsgDPC - DPC routine to handle messages from the hypervisior */ static void VmbusOnMsgDPC(struct hv_driver *drv) @@ -217,7 +217,7 @@ static void VmbusOnMsgDPC(struct hv_driver *drv) } } -/** +/* * VmbusOnEventDPC - DPC routine to handle events from the hypervisior */ static void VmbusOnEventDPC(struct hv_driver *drv) @@ -226,7 +226,7 @@ static void VmbusOnEventDPC(struct hv_driver *drv) VmbusOnEvents(); } -/** +/* * VmbusOnISR - ISR routine */ static int VmbusOnISR(struct hv_driver *drv) @@ -264,7 +264,7 @@ static int VmbusOnISR(struct hv_driver *drv) return ret; } -/** +/* * VmbusInitialize - Main entry point */ int VmbusInitialize(struct hv_driver *drv) diff --git a/drivers/staging/hv/VmbusApi.h b/drivers/staging/hv/VmbusApi.h index d089bb193e7d..4275be3292ce 100644 --- a/drivers/staging/hv/VmbusApi.h +++ b/drivers/staging/hv/VmbusApi.h @@ -84,6 +84,24 @@ struct hv_device_info { struct hv_dev_port_info Outbound; }; +/** + * struct vmbus_channel_interface - Contains member functions for vmbus channel + * @Open: Open the channel + * @Close: Close the channel + * @SendPacket: Send a packet over the channel + * @SendPacketPageBuffer: Send a single page buffer over the channel + * @SendPacketMultiPageBuffer: Send a multiple page buffers + * @RecvPacket: Receive packet + * @RecvPacketRaw: Receive Raw packet + * @EstablishGpadl: Set up GPADL for ringbuffer + * @TeardownGpadl: Teardown GPADL for ringbuffer + * @GetInfo: Get info about the channel + * + * This structure contains function pointer to control vmbus channel + * behavior. None of these functions is externally callable, but they + * are used for normal vmbus channel internal behavior. + * Only used by Hyper-V drivers. + */ struct vmbus_channel_interface { int (*Open)(struct hv_device *Device, u32 SendBufferSize, u32 RecvRingBufferSize, void *UserData, u32 UserDataLen, diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 8f1fda3256ad..e80cae78b269 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -165,7 +165,7 @@ static struct block_device_operations block_ops = { .ioctl = blkvsc_ioctl, }; -/** +/* * blkvsc_drv_init - BlkVsc driver initialization. */ static int blkvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) @@ -245,7 +245,7 @@ static void blkvsc_drv_exit(void) return; } -/** +/* * blkvsc_probe - Add a new device for this driver */ static int blkvsc_probe(struct device *device) @@ -733,7 +733,7 @@ static int blkvsc_do_read_capacity16(struct block_device_context *blkdev) return 0; } -/** +/* * blkvsc_remove() - Callback when our device is removed */ static int blkvsc_remove(struct device *device) diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 2ccb6b93fe47..5ed6e6e7db67 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -266,7 +266,7 @@ retry_send: return ret; } -/** +/* * netvsc_linkstatus_callback - Link up/down notification */ static void netvsc_linkstatus_callback(struct hv_device *device_obj, @@ -293,8 +293,9 @@ static void netvsc_linkstatus_callback(struct hv_device *device_obj, DPRINT_EXIT(NETVSC_DRV); } -/** - * netvsc_recv_callback - Callback when we receive a packet from the "wire" on the specified device. +/* + * netvsc_recv_callback - Callback when we receive a packet from the + * "wire" on the specified device. */ static int netvsc_recv_callback(struct hv_device *device_obj, struct hv_netvsc_packet *packet) diff --git a/drivers/staging/hv/osd.c b/drivers/staging/hv/osd.c index 9aea31067295..8c3eb278a81f 100644 --- a/drivers/staging/hv/osd.c +++ b/drivers/staging/hv/osd.c @@ -59,6 +59,15 @@ void *osd_VirtualAllocExec(unsigned int size) #endif } +/** + * osd_PageAlloc() - Allocate pages + * @count: Total number of Kernel pages you want to allocate + * + * Tries to allocate @count number of consecutive free kernel pages. + * And if successful, it will set the pages to 0 before returning. + * If successfull it will return pointer to the @count pages. + * Mainly used by Hyper-V drivers. + */ void *osd_PageAlloc(unsigned int count) { void *p; @@ -78,6 +87,14 @@ void *osd_PageAlloc(unsigned int count) } EXPORT_SYMBOL_GPL(osd_PageAlloc); +/** + * osd_PageFree() - Free pages + * @page: Pointer to the first page to be freed + * @count: Total number of Kernel pages you free + * + * Frees the pages allocated by osd_PageAlloc() + * Mainly used by Hyper-V drivers. + */ void osd_PageFree(void *page, unsigned int count) { free_pages((unsigned long)page, get_order(count * PAGE_SIZE)); @@ -86,6 +103,17 @@ void osd_PageFree(void *page, unsigned int count) } EXPORT_SYMBOL_GPL(osd_PageFree); +/** + * osd_WaitEventCreate() - Create the event queue + * + * Allocates memory for a &struct osd_waitevent. And then calls + * init_waitqueue_head to set up the wait queue for the event. + * This structure is usually part of a another structure that contains + * the actual Hyper-V device driver structure. + * + * Returns pointer to &struct osd_waitevent + * Mainly used by Hyper-V drivers. + */ struct osd_waitevent *osd_WaitEventCreate(void) { struct osd_waitevent *wait = kmalloc(sizeof(struct osd_waitevent), @@ -99,6 +127,19 @@ struct osd_waitevent *osd_WaitEventCreate(void) } EXPORT_SYMBOL_GPL(osd_WaitEventCreate); + +/** + * osd_WaitEventSet() - Wake up the process + * @waitEvent: Structure to event to be woken up + * + * @waitevent is of type &struct osd_waitevent + * + * Wake up the sleeping process so it can do some work. + * And set condition indicator in &struct osd_waitevent to indicate + * the process is in a woken state. + * + * Only used by Network and Storage Hyper-V drivers. + */ void osd_WaitEventSet(struct osd_waitevent *waitEvent) { waitEvent->condition = 1; @@ -106,6 +147,20 @@ void osd_WaitEventSet(struct osd_waitevent *waitEvent) } EXPORT_SYMBOL_GPL(osd_WaitEventSet); +/** + * osd_WaitEventWait() - Wait for event till condition is true + * @waitEvent: Structure to event to be put to sleep + * + * @waitevent is of type &struct osd_waitevent + * + * Set up the process to sleep until waitEvent->condition get true. + * And set condition indicator in &struct osd_waitevent to indicate + * the process is in a sleeping state. + * + * Returns the status of 'wait_event_interruptible()' system call + * + * Mainly used by Hyper-V drivers. + */ int osd_WaitEventWait(struct osd_waitevent *waitEvent) { int ret = 0; @@ -117,6 +172,21 @@ int osd_WaitEventWait(struct osd_waitevent *waitEvent) } EXPORT_SYMBOL_GPL(osd_WaitEventWait); +/** + * osd_WaitEventWaitEx() - Wait for event or timeout for process wakeup + * @waitEvent: Structure to event to be put to sleep + * @TimeoutInMs: Total number of Milliseconds to wait before waking up + * + * @waitevent is of type &struct osd_waitevent + * Set up the process to sleep until @waitEvent->condition get true or + * @TimeoutInMs (Time out in Milliseconds) has been reached. + * And set condition indicator in &struct osd_waitevent to indicate + * the process is in a sleeping state. + * + * Returns the status of 'wait_event_interruptible_timeout()' system call + * + * Mainly used by Hyper-V drivers. + */ int osd_WaitEventWaitEx(struct osd_waitevent *waitEvent, u32 TimeoutInMs) { int ret = 0; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 8a58272b8039..63360b27f5c3 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -130,7 +130,7 @@ static struct scsi_host_template scsi_driver = { }; -/** +/* * storvsc_drv_init - StorVsc driver initialization. */ static int storvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) @@ -223,7 +223,7 @@ static void storvsc_drv_exit(void) return; } -/** +/* * storvsc_probe - Add a new device for this driver */ static int storvsc_probe(struct device *device) @@ -319,7 +319,7 @@ static int storvsc_probe(struct device *device) return ret; } -/** +/* * storvsc_remove - Callback when our device is removed */ static int storvsc_remove(struct device *device) @@ -372,7 +372,7 @@ static int storvsc_remove(struct device *device) return ret; } -/** +/* * storvsc_commmand_completion - Command completion processing */ static void storvsc_commmand_completion(struct hv_storvsc_request *request) @@ -623,7 +623,7 @@ static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl, return total_copied; } -/** +/* * storvsc_queuecommand - Initiate command processing */ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, @@ -824,7 +824,7 @@ static int storvsc_merge_bvec(struct request_queue *q, return bvec->bv_len; } -/** +/* * storvsc_device_configure - Configure the specified scsi device */ static int storvsc_device_alloc(struct scsi_device *sdevice) @@ -863,7 +863,7 @@ static int storvsc_device_configure(struct scsi_device *sdevice) return 0; } -/** +/* * storvsc_host_reset_handler - Reset the scsi HBA */ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 3397ef08e0aa..2ff61b862015 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -129,7 +129,7 @@ static struct vmbus_driver_context g_vmbus_drv = { .bus.dev_attrs = vmbus_device_attrs, }; -/** +/* * vmbus_show_device_attr - Show the device attribute in sysfs. * * This is invoked when user does a @@ -233,7 +233,7 @@ static ssize_t vmbus_show_device_attr(struct device *dev, } } -/** +/* * vmbus_bus_init -Main vmbus driver initialization routine. * * Here, we @@ -362,7 +362,7 @@ cleanup: return ret; } -/** +/* * vmbus_bus_exit - Terminate the vmbus driver. * * This routine is opposite of vmbus_bus_init() @@ -398,8 +398,18 @@ static void vmbus_bus_exit(void) return; } + /** - * vmbus_child_driver_register - Register a vmbus's child driver + * vmbus_child_driver_register() - Register a vmbus's child driver + * @driver_ctx: Pointer to driver structure you want to register + * + * @driver_ctx is of type &struct driver_context + * + * Registers the given driver with Linux through the 'driver_register()' call + * And sets up the hyper-v vmbus handling for this driver. + * It will return the state of the 'driver_register()' call. + * + * Mainly used by Hyper-V drivers. */ int vmbus_child_driver_register(struct driver_context *driver_ctx) { @@ -425,7 +435,15 @@ int vmbus_child_driver_register(struct driver_context *driver_ctx) EXPORT_SYMBOL(vmbus_child_driver_register); /** - * vmbus_child_driver_unregister Unregister a vmbus's child driver + * vmbus_child_driver_unregister() - Unregister a vmbus's child driver + * @driver_ctx: Pointer to driver structure you want to un-register + * + * @driver_ctx is of type &struct driver_context + * + * Un-register the given driver with Linux through the 'driver_unregister()' + * call. And ungegisters the driver from the Hyper-V vmbus handler. + * + * Mainly used by Hyper-V drivers. */ void vmbus_child_driver_unregister(struct driver_context *driver_ctx) { @@ -443,9 +461,15 @@ void vmbus_child_driver_unregister(struct driver_context *driver_ctx) EXPORT_SYMBOL(vmbus_child_driver_unregister); /** - * vmbus_get_interface - Get the vmbus channel interface. + * vmbus_get_interface() - Get the vmbus channel interface. + * @interface: Pointer to channel interface structure + * + * Get the Hyper-V channel used for the driver. + * + * @interface is of type &struct vmbus_channel_interface + * This is invoked by child/client driver that sits above vmbus. * - * This is invoked by child/client driver that sits above vmbus + * Mainly used by Hyper-V drivers. */ void vmbus_get_interface(struct vmbus_channel_interface *interface) { @@ -455,7 +479,7 @@ void vmbus_get_interface(struct vmbus_channel_interface *interface) } EXPORT_SYMBOL(vmbus_get_interface); -/** +/* * vmbus_child_device_get_info - Get the vmbus child device info. * * This is invoked to display various device attributes in sysfs. @@ -468,8 +492,9 @@ static void vmbus_child_device_get_info(struct hv_device *device_obj, vmbus_drv_obj->GetChannelInfo(device_obj, device_info); } -/** - * vmbus_child_device_create - Creates and registers a new child device on the vmbus. +/* + * vmbus_child_device_create - Creates and registers a new child device + * on the vmbus. */ static struct hv_device *vmbus_child_device_create(struct hv_guid *type, struct hv_guid *instance, @@ -523,7 +548,7 @@ static struct hv_device *vmbus_child_device_create(struct hv_guid *type, return child_device_obj; } -/** +/* * vmbus_child_device_register - Register the child device on the specified bus */ static int vmbus_child_device_register(struct hv_device *root_device_obj, @@ -571,8 +596,9 @@ static int vmbus_child_device_register(struct hv_device *root_device_obj, return ret; } -/** - * vmbus_child_device_unregister - Remove the specified child device from the vmbus. +/* + * vmbus_child_device_unregister - Remove the specified child device + * from the vmbus. */ static void vmbus_child_device_unregister(struct hv_device *device_obj) { @@ -595,7 +621,7 @@ static void vmbus_child_device_unregister(struct hv_device *device_obj) DPRINT_EXIT(VMBUS_DRV); } -/** +/* * vmbus_child_device_destroy - Destroy the specified child device on the vmbus. */ static void vmbus_child_device_destroy(struct hv_device *device_obj) @@ -605,7 +631,7 @@ static void vmbus_child_device_destroy(struct hv_device *device_obj) DPRINT_EXIT(VMBUS_DRV); } -/** +/* * vmbus_uevent - add uevent for our device * * This routine is invoked when a device is added or removed on the vmbus to @@ -684,7 +710,7 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) return 0; } -/** +/* * vmbus_match - Attempt to match the specified device to the specified driver */ static int vmbus_match(struct device *device, struct device_driver *driver) @@ -719,7 +745,7 @@ static int vmbus_match(struct device *device, struct device_driver *driver) return match; } -/** +/* * vmbus_probe_failed_cb - Callback when a driver probe failed in vmbus_probe() * * We need a callback because we cannot invoked device_unregister() inside @@ -742,7 +768,7 @@ static void vmbus_probe_failed_cb(struct work_struct *context) DPRINT_EXIT(VMBUS_DRV); } -/** +/* * vmbus_probe - Add the new vmbus's child device */ static int vmbus_probe(struct device *child_device) @@ -778,7 +804,7 @@ static int vmbus_probe(struct device *child_device) return ret; } -/** +/* * vmbus_remove - Remove a vmbus device */ static int vmbus_remove(struct device *child_device) @@ -820,7 +846,7 @@ static int vmbus_remove(struct device *child_device) return 0; } -/** +/* * vmbus_shutdown - Shutdown a vmbus device */ static void vmbus_shutdown(struct device *child_device) @@ -856,7 +882,7 @@ static void vmbus_shutdown(struct device *child_device) return; } -/** +/* * vmbus_bus_release - Final callback release of the vmbus root device */ static void vmbus_bus_release(struct device *device) @@ -870,7 +896,7 @@ static void vmbus_bus_release(struct device *device) DPRINT_EXIT(VMBUS_DRV); } -/** +/* * vmbus_device_release - Final callback release of the vmbus child device */ static void vmbus_device_release(struct device *device) @@ -888,7 +914,7 @@ static void vmbus_device_release(struct device *device) return; } -/** +/* * vmbus_msg_dpc - Tasklet routine to handle hypervisor messages */ static void vmbus_msg_dpc(unsigned long data) @@ -905,7 +931,7 @@ static void vmbus_msg_dpc(unsigned long data) DPRINT_EXIT(VMBUS_DRV); } -/** +/* * vmbus_msg_dpc - Tasklet routine to handle hypervisor events */ static void vmbus_event_dpc(unsigned long data) -- cgit v1.2.3 From 6f2dfb3101bb431ae9adc827fa8526d699e9dbd0 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 2 Mar 2010 13:35:35 +0000 Subject: staging: IIO: Fix uses of spinlocks prior to init in ring implementations Some confusion was caused by the ___iio_init_ring_buffer and equivalent in ring_sw handling both init of spin locks etc and allocation and of the actual buffer. This resulted in ring->use_lock being held before it was initialized and actually during the initialization. Some of the recent cleanups in the spin lock code seem to have triggered the bug actually causing traceable crashes. The following patch should fix this but hasn't been extensively tested as of yet and there may well be some side effects I haven't thought of. Just wanted to get this out there before anyone else runs into it! Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/industrialio-ring.c | 2 ++ drivers/staging/iio/ring_generic.h | 8 +++----- drivers/staging/iio/ring_sw.c | 18 +++++++++++------- 3 files changed, 16 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c index e53e214bfeb0..5f48632e4258 100644 --- a/drivers/staging/iio/industrialio-ring.c +++ b/drivers/staging/iio/industrialio-ring.c @@ -266,6 +266,8 @@ void iio_ring_buffer_init(struct iio_ring_buffer *ring, ring->indio_dev = dev_info; ring->ev_int.private = ring; ring->access_handler.private = ring; + ring->shared_ev_pointer.ev_p = 0; + spin_lock_init(&ring->shared_ev_pointer.lock); } EXPORT_SYMBOL(iio_ring_buffer_init); diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h index 09044adf7327..75e0fc078d68 100644 --- a/drivers/staging/iio/ring_generic.h +++ b/drivers/staging/iio/ring_generic.h @@ -134,19 +134,17 @@ void iio_ring_buffer_init(struct iio_ring_buffer *ring, struct iio_dev *dev_info); /** - * __iio_init_ring_buffer() - initialize common elements of ring buffers + * __iio_update_ring_buffer() - update common elements of ring buffers * @ring: ring buffer that is the event source * @bytes_per_datum: size of individual datum including timestamp * @length: number of datums in ring **/ -static inline void __iio_init_ring_buffer(struct iio_ring_buffer *ring, - int bytes_per_datum, int length) +static inline void __iio_update_ring_buffer(struct iio_ring_buffer *ring, + int bytes_per_datum, int length) { ring->bpd = bytes_per_datum; ring->length = length; ring->loopcount = 0; - ring->shared_ev_pointer.ev_p = 0; - spin_lock_init(&ring->shared_ev_pointer.lock); } /** diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c index b104c3d9c35e..851a97edd1d4 100644 --- a/drivers/staging/iio/ring_sw.c +++ b/drivers/staging/iio/ring_sw.c @@ -14,14 +14,12 @@ #include #include "ring_sw.h" -static inline int __iio_init_sw_ring_buffer(struct iio_sw_ring_buffer *ring, - int bytes_per_datum, int length) +static inline int __iio_allocate_sw_ring_buffer(struct iio_sw_ring_buffer *ring, + int bytes_per_datum, int length) { if ((length == 0) || (bytes_per_datum == 0)) return -EINVAL; - - __iio_init_ring_buffer(&ring->buf, bytes_per_datum, length); - spin_lock_init(&ring->use_lock); + __iio_update_ring_buffer(&ring->buf, bytes_per_datum, length); ring->data = kmalloc(length*ring->buf.bpd, GFP_KERNEL); ring->read_p = 0; ring->write_p = 0; @@ -30,6 +28,11 @@ static inline int __iio_init_sw_ring_buffer(struct iio_sw_ring_buffer *ring, return ring->data ? 0 : -ENOMEM; } +static inline void __iio_init_sw_ring_buffer(struct iio_sw_ring_buffer *ring) +{ + spin_lock_init(&ring->use_lock); +} + static inline void __iio_free_sw_ring_buffer(struct iio_sw_ring_buffer *ring) { kfree(ring->data); @@ -320,7 +323,8 @@ int iio_request_update_sw_rb(struct iio_ring_buffer *r) goto error_ret; } __iio_free_sw_ring_buffer(ring); - ret = __iio_init_sw_ring_buffer(ring, ring->buf.bpd, ring->buf.length); + ret = __iio_allocate_sw_ring_buffer(ring, ring->buf.bpd, + ring->buf.length); error_ret: spin_unlock(&ring->use_lock); return ret; @@ -411,8 +415,8 @@ struct iio_ring_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev) if (!ring) return 0; buf = &ring->buf; - iio_ring_buffer_init(buf, indio_dev); + __iio_init_sw_ring_buffer(ring); buf->dev.type = &iio_sw_ring_type; device_initialize(&buf->dev); buf->dev.parent = &indio_dev->dev; -- cgit v1.2.3 From 7264fcd129b939fc1faa8ccfee043f843285161b Mon Sep 17 00:00:00 2001 From: John Sheehan Date: Thu, 4 Mar 2010 14:24:40 +0000 Subject: staging: arlan: fix errors reported by checkpatch.pl tool fix all but one of the errors reported by checkpatch.pl tool. Errors included wayward braces, white space issues(trailing and prohibited), C99 issues, and foo* issues Signed-off-by: John Sheehan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/arlan/arlan-main.c | 935 ++++++++++++++++--------------------- 1 file changed, 409 insertions(+), 526 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/arlan/arlan-main.c b/drivers/staging/arlan/arlan-main.c index 88fdd53cf5d3..58deb96e1a37 100644 --- a/drivers/staging/arlan/arlan-main.c +++ b/drivers/staging/arlan/arlan-main.c @@ -80,15 +80,14 @@ static int arlan_open(struct net_device *dev); static netdev_tx_t arlan_tx(struct sk_buff *skb, struct net_device *dev); static irqreturn_t arlan_interrupt(int irq, void *dev_id); static int arlan_close(struct net_device *dev); -static struct net_device_stats * - arlan_statistics (struct net_device *dev); -static void arlan_set_multicast (struct net_device *dev); -static int arlan_hw_tx (struct net_device* dev, char *buf, int length ); -static int arlan_hw_config (struct net_device * dev); -static void arlan_tx_done_interrupt (struct net_device * dev, int status); -static void arlan_rx_interrupt (struct net_device * dev, u_char rxStatus, u_short, u_short); -static void arlan_process_interrupt (struct net_device * dev); -static void arlan_tx_timeout (struct net_device *dev); +static struct net_device_stats *arlan_statistics(struct net_device *dev); +static void arlan_set_multicast(struct net_device *dev); +static int arlan_hw_tx(struct net_device *dev, char *buf, int length); +static int arlan_hw_config(struct net_device *dev); +static void arlan_tx_done_interrupt(struct net_device *dev, int status); +static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short, u_short); +static void arlan_process_interrupt(struct net_device *dev); +static void arlan_tx_timeout(struct net_device *dev); static inline long us2ticks(int us) { @@ -102,14 +101,14 @@ static inline long us2ticks(int us) struct timeval timev;\ do_gettimeofday(&timev);\ if (arlan_entry_debug || arlan_entry_and_exit_debug)\ - printk("--->>>" name " %ld " "\n",((long int) timev.tv_sec * 1000000 + timev.tv_usec));\ + printk("--->>>" name " %ld " "\n", ((long int) timev.tv_sec * 1000000 + timev.tv_usec));\ } #define ARLAN_DEBUG_EXIT(name) \ {\ struct timeval timev;\ do_gettimeofday(&timev);\ if (arlan_exit_debug || arlan_entry_and_exit_debug)\ - printk("<<<---" name " %ld " "\n",((long int) timev.tv_sec * 1000000 + timev.tv_usec) );\ + printk("<<<---" name " %ld " "\n", ((long int) timev.tv_sec * 1000000 + timev.tv_usec));\ } #else #define ARLAN_DEBUG_ENTRY(name) @@ -118,8 +117,8 @@ static inline long us2ticks(int us) #define arlan_interrupt_ack(dev)\ - clearClearInterrupt(dev);\ - setClearInterrupt(dev); + clearClearInterrupt(dev);\ + setClearInterrupt(dev); static inline int arlan_drop_tx(struct net_device *dev) { @@ -127,18 +126,15 @@ static inline int arlan_drop_tx(struct net_device *dev) dev->stats.tx_errors++; if (priv->Conf->tx_delay_ms) - { priv->tx_done_delayed = jiffies + priv->Conf->tx_delay_ms * HZ / 1000 + 1; - } - else - { + else { priv->waiting_command_mask &= ~ARLAN_COMMAND_TX; TXHEAD(dev).offset = 0; TXTAIL(dev).offset = 0; priv->txLast = 0; priv->bad = 0; if (!priv->under_reset && !priv->under_config) - netif_wake_queue (dev); + netif_wake_queue(dev); } return 1; } @@ -169,13 +165,11 @@ int arlan_command(struct net_device *dev, int command_p) if (time_after(jiffies, priv->lastReset + 5 * HZ)) priv->waiting_command_mask &= ~ARLAN_COMMAND_RESET; - if (priv->waiting_command_mask & ARLAN_COMMAND_INT_ACK) - { + if (priv->waiting_command_mask & ARLAN_COMMAND_INT_ACK) { arlan_interrupt_ack(dev); priv->waiting_command_mask &= ~ARLAN_COMMAND_INT_ACK; } - if (priv->waiting_command_mask & ARLAN_COMMAND_INT_ENABLE) - { + if (priv->waiting_command_mask & ARLAN_COMMAND_INT_ENABLE) { setInterruptEnable(dev); priv->waiting_command_mask &= ~ARLAN_COMMAND_INT_ENABLE; } @@ -185,12 +179,10 @@ int arlan_command(struct net_device *dev, int command_p) /* Check cards status and waiting */ - if (priv->waiting_command_mask & (ARLAN_COMMAND_LONG_WAIT_NOW | ARLAN_COMMAND_WAIT_NOW)) - { - while (priv->waiting_command_mask & (ARLAN_COMMAND_LONG_WAIT_NOW | ARLAN_COMMAND_WAIT_NOW)) - { + if (priv->waiting_command_mask & (ARLAN_COMMAND_LONG_WAIT_NOW | ARLAN_COMMAND_WAIT_NOW)) { + while (priv->waiting_command_mask & (ARLAN_COMMAND_LONG_WAIT_NOW | ARLAN_COMMAND_WAIT_NOW)) { if (READSHMB(arlan->resetFlag) || - READSHMB(arlan->commandByte)) /* || + READSHMB(arlan->commandByte)) /* || (readControlRegister(dev) & ARLAN_ACCESS)) */ udelay(40); @@ -199,27 +191,20 @@ int arlan_command(struct net_device *dev, int command_p) udelayed++; - if (priv->waiting_command_mask & ARLAN_COMMAND_LONG_WAIT_NOW) - { - if (udelayed * 40 > 1000000) - { + if (priv->waiting_command_mask & ARLAN_COMMAND_LONG_WAIT_NOW) { + if (udelayed * 40 > 1000000) { printk(KERN_ERR "%s long wait too long \n", dev->name); priv->waiting_command_mask |= ARLAN_COMMAND_RESET; break; } - } - else if (priv->waiting_command_mask & ARLAN_COMMAND_WAIT_NOW) - { - if (udelayed * 40 > 1000) - { + } else if (priv->waiting_command_mask & ARLAN_COMMAND_WAIT_NOW) { + if (udelayed * 40 > 1000) { printk(KERN_ERR "%s short wait too long \n", dev->name); goto bad_end; } } } - } - else - { + } else { i = 0; while ((READSHMB(arlan->resetFlag) || READSHMB(arlan->commandByte)) && @@ -230,9 +215,7 @@ int arlan_command(struct net_device *dev, int command_p) if ((READSHMB(arlan->resetFlag) || READSHMB(arlan->commandByte)) && !(priv->waiting_command_mask & ARLAN_COMMAND_RESET)) - { goto card_busy_end; - } } if (priv->waiting_command_mask & ARLAN_COMMAND_RESET) priv->under_reset = 1; @@ -241,55 +224,43 @@ int arlan_command(struct net_device *dev, int command_p) /* Issuing command */ arlan_lock_card_access(dev); - if (priv->waiting_command_mask & ARLAN_COMMAND_POWERUP) - { - // if (readControlRegister(dev) & (ARLAN_ACCESS && ARLAN_POWER)) + if (priv->waiting_command_mask & ARLAN_COMMAND_POWERUP) { + /* if (readControlRegister(dev) & (ARLAN_ACCESS && ARLAN_POWER)) */ setPowerOn(dev); arlan_interrupt_lancpu(dev); priv->waiting_command_mask &= ~ARLAN_COMMAND_POWERUP; priv->waiting_command_mask |= ARLAN_COMMAND_RESET; priv->card_polling_interval = HZ / 10; - } - else if (priv->waiting_command_mask & ARLAN_COMMAND_ACTIVATE) - { + } else if (priv->waiting_command_mask & ARLAN_COMMAND_ACTIVATE) { WRITESHMB(arlan->commandByte, ARLAN_COM_ACTIVATE); arlan_interrupt_lancpu(dev); priv->waiting_command_mask &= ~ARLAN_COMMAND_ACTIVATE; priv->card_polling_interval = HZ / 10; - } - else if (priv->waiting_command_mask & ARLAN_COMMAND_RX_ABORT) - { - if (priv->rx_command_given) - { + } else if (priv->waiting_command_mask & ARLAN_COMMAND_RX_ABORT) { + if (priv->rx_command_given) { WRITESHMB(arlan->commandByte, ARLAN_COM_RX_ABORT); arlan_interrupt_lancpu(dev); priv->rx_command_given = 0; } priv->waiting_command_mask &= ~ARLAN_COMMAND_RX_ABORT; priv->card_polling_interval = 1; - } - else if (priv->waiting_command_mask & ARLAN_COMMAND_TX_ABORT) - { - if (priv->tx_command_given) - { + } else if (priv->waiting_command_mask & ARLAN_COMMAND_TX_ABORT) { + if (priv->tx_command_given) { WRITESHMB(arlan->commandByte, ARLAN_COM_TX_ABORT); arlan_interrupt_lancpu(dev); priv->tx_command_given = 0; } priv->waiting_command_mask &= ~ARLAN_COMMAND_TX_ABORT; priv->card_polling_interval = 1; - } - else if (priv->waiting_command_mask & ARLAN_COMMAND_RESET) - { - priv->under_reset=1; - netif_stop_queue (dev); + } else if (priv->waiting_command_mask & ARLAN_COMMAND_RESET) { + priv->under_reset = 1; + netif_stop_queue(dev); arlan_drop_tx(dev); if (priv->tx_command_given || priv->rx_command_given) - { printk(KERN_ERR "%s: Reset under tx or rx command \n", dev->name); - } - netif_stop_queue (dev); + + netif_stop_queue(dev); if (arlan_debug & ARLAN_DEBUG_RESET) printk(KERN_ERR "%s: Doing chip reset\n", dev->name); priv->lastReset = jiffies; @@ -303,11 +274,9 @@ int arlan_command(struct net_device *dev, int command_p) priv->card_polling_interval = HZ / 4; priv->waiting_command_mask &= ~ARLAN_COMMAND_RESET; priv->waiting_command_mask |= ARLAN_COMMAND_INT_RACK; -// priv->waiting_command_mask |= ARLAN_COMMAND_INT_RENABLE; -// priv->waiting_command_mask |= ARLAN_COMMAND_RX; - } - else if (priv->waiting_command_mask & ARLAN_COMMAND_INT_RACK) - { + /* priv->waiting_command_mask |= ARLAN_COMMAND_INT_RENABLE; */ + /* priv->waiting_command_mask |= ARLAN_COMMAND_RX; */ + } else if (priv->waiting_command_mask & ARLAN_COMMAND_INT_RACK) { clearHardwareReset(dev); clearClearInterrupt(dev); setClearInterrupt(dev); @@ -316,126 +285,94 @@ int arlan_command(struct net_device *dev, int command_p) priv->waiting_command_mask |= ARLAN_COMMAND_CONF; priv->under_config = 1; priv->under_reset = 0; - } - else if (priv->waiting_command_mask & ARLAN_COMMAND_INT_RENABLE) - { + } else if (priv->waiting_command_mask & ARLAN_COMMAND_INT_RENABLE) { setInterruptEnable(dev); priv->waiting_command_mask &= ~ARLAN_COMMAND_INT_RENABLE; - } - else if (priv->waiting_command_mask & ARLAN_COMMAND_CONF) - { + } else if (priv->waiting_command_mask & ARLAN_COMMAND_CONF) { if (priv->tx_command_given || priv->rx_command_given) - { printk(KERN_ERR "%s: Reset under tx or rx command \n", dev->name); - } + arlan_drop_tx(dev); setInterruptEnable(dev); arlan_hw_config(dev); arlan_interrupt_lancpu(dev); priv->waiting_command_mask &= ~ARLAN_COMMAND_CONF; priv->card_polling_interval = HZ / 10; -// priv->waiting_command_mask |= ARLAN_COMMAND_INT_RACK; -// priv->waiting_command_mask |= ARLAN_COMMAND_INT_ENABLE; + /* priv->waiting_command_mask |= ARLAN_COMMAND_INT_RACK; */ + /* priv->waiting_command_mask |= ARLAN_COMMAND_INT_ENABLE; */ priv->waiting_command_mask |= ARLAN_COMMAND_CONF_WAIT; - } - else if (priv->waiting_command_mask & ARLAN_COMMAND_CONF_WAIT) - { + } else if (priv->waiting_command_mask & ARLAN_COMMAND_CONF_WAIT) { if (READSHMB(arlan->configuredStatusFlag) != 0 && - READSHMB(arlan->diagnosticInfo) == 0xff) - { + READSHMB(arlan->diagnosticInfo) == 0xff) { priv->waiting_command_mask &= ~ARLAN_COMMAND_CONF_WAIT; priv->waiting_command_mask |= ARLAN_COMMAND_RX; priv->waiting_command_mask |= ARLAN_COMMAND_TBUSY_CLEAR; priv->card_polling_interval = HZ / 10; priv->tx_command_given = 0; priv->under_config = 0; - } - else - { + } else { priv->card_polling_interval = 1; if (arlan_debug & ARLAN_DEBUG_TIMING) printk(KERN_ERR "configure delayed \n"); } - } - else if (priv->waiting_command_mask & ARLAN_COMMAND_RX) - { - if (!registrationBad(dev)) - { + } else if (priv->waiting_command_mask & ARLAN_COMMAND_RX) { + if (!registrationBad(dev)) { setInterruptEnable(dev); memset_io(arlan->commandParameter, 0, 0xf); WRITESHMB(arlan->commandByte, ARLAN_COM_INT | ARLAN_COM_RX_ENABLE); WRITESHMB(arlan->commandParameter[0], conf->rxParameter); arlan_interrupt_lancpu(dev); - priv->rx_command_given = 0; // mnjah, bad + priv->rx_command_given = 0; /* mnjah, bad */ priv->waiting_command_mask &= ~ARLAN_COMMAND_RX; priv->card_polling_interval = 1; - } - else + } else priv->card_polling_interval = 2; - } - else if (priv->waiting_command_mask & ARLAN_COMMAND_TBUSY_CLEAR) - { - if ( !registrationBad(dev) && - (netif_queue_stopped(dev) || !netif_running(dev)) ) - { + } else if (priv->waiting_command_mask & ARLAN_COMMAND_TBUSY_CLEAR) { + if (!registrationBad(dev) && + (netif_queue_stopped(dev) || !netif_running(dev))) { priv->waiting_command_mask &= ~ARLAN_COMMAND_TBUSY_CLEAR; - netif_wake_queue (dev); + netif_wake_queue(dev); } - } - else if (priv->waiting_command_mask & ARLAN_COMMAND_TX) - { - if (!test_and_set_bit(0, (void *) &priv->tx_command_given)) - { - if (time_after(jiffies, + } else if (priv->waiting_command_mask & ARLAN_COMMAND_TX) { + if (!test_and_set_bit(0, (void *) &priv->tx_command_given)) { + if (time_after(jiffies, priv->tx_last_sent + us2ticks(conf->rx_tweak1)) || time_before(jiffies, - priv->last_rx_int_ack_time + us2ticks(conf->rx_tweak2))) - { + priv->last_rx_int_ack_time + us2ticks(conf->rx_tweak2))) { setInterruptEnable(dev); memset_io(arlan->commandParameter, 0, 0xf); WRITESHMB(arlan->commandByte, ARLAN_COM_TX_ENABLE | ARLAN_COM_INT); memcpy_toio(arlan->commandParameter, &TXLAST(dev), 14); -// for ( i=1 ; i < 15 ; i++) printk("%02x:",READSHMB(arlan->commandParameter[i])); + /* for ( i=1 ; i < 15 ; i++) printk("%02x:",READSHMB(arlan->commandParameter[i])); */ priv->tx_last_sent = jiffies; arlan_interrupt_lancpu(dev); priv->tx_command_given = 1; priv->waiting_command_mask &= ~ARLAN_COMMAND_TX; priv->card_polling_interval = 1; - } - else - { + } else { priv->tx_command_given = 0; priv->card_polling_interval = 1; } - } - else if (arlan_debug & ARLAN_DEBUG_CHAIN_LOCKS) + } else if (arlan_debug & ARLAN_DEBUG_CHAIN_LOCKS) printk(KERN_ERR "tx command when tx chain locked \n"); - } - else if (priv->waiting_command_mask & ARLAN_COMMAND_NOOPINT) - { + } else if (priv->waiting_command_mask & ARLAN_COMMAND_NOOPINT) { { WRITESHMB(arlan->commandByte, ARLAN_COM_NOP | ARLAN_COM_INT); } arlan_interrupt_lancpu(dev); priv->waiting_command_mask &= ~ARLAN_COMMAND_NOOPINT; priv->card_polling_interval = HZ / 3; - } - else if (priv->waiting_command_mask & ARLAN_COMMAND_NOOP) - { + } else if (priv->waiting_command_mask & ARLAN_COMMAND_NOOP) { WRITESHMB(arlan->commandByte, ARLAN_COM_NOP); arlan_interrupt_lancpu(dev); priv->waiting_command_mask &= ~ARLAN_COMMAND_NOOP; priv->card_polling_interval = HZ / 3; - } - else if (priv->waiting_command_mask & ARLAN_COMMAND_SLOW_POLL) - { + } else if (priv->waiting_command_mask & ARLAN_COMMAND_SLOW_POLL) { WRITESHMB(arlan->commandByte, ARLAN_COM_GOTO_SLOW_POLL); arlan_interrupt_lancpu(dev); priv->waiting_command_mask &= ~ARLAN_COMMAND_SLOW_POLL; priv->card_polling_interval = HZ / 3; - } - else if (priv->waiting_command_mask & ARLAN_COMMAND_POWERDOWN) - { + } else if (priv->waiting_command_mask & ARLAN_COMMAND_POWERDOWN) { setPowerOff(dev); if (arlan_debug & ARLAN_DEBUG_CARD_STATE) printk(KERN_WARNING "%s: Arlan Going Standby\n", dev->name); @@ -478,10 +415,8 @@ static inline void arlan_command_process(struct net_device *dev) struct arlan_private *priv = netdev_priv(dev); int times = 0; - while (priv->waiting_command_mask && times < 8) - { - if (priv->waiting_command_mask) - { + while (priv->waiting_command_mask && times < 8) { + if (priv->waiting_command_mask) { if (arlan_command(dev, 0)) break; times++; @@ -500,24 +435,17 @@ static inline void arlan_retransmit_now(struct net_device *dev) ARLAN_DEBUG_ENTRY("arlan_retransmit_now"); - if (TXLAST(dev).offset == 0) - { - if (TXHEAD(dev).offset) - { + if (TXLAST(dev).offset == 0) { + if (TXHEAD(dev).offset) { priv->txLast = 0; IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_DEBUG "TX buff switch to head \n"); - - } - else if (TXTAIL(dev).offset) - { + } else if (TXTAIL(dev).offset) { IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_DEBUG "TX buff switch to tail \n"); priv->txLast = 1; - } - else + } else IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_ERR "ReTransmit buff empty"); - netif_wake_queue (dev); + netif_wake_queue(dev); return; - } arlan_command(dev, ARLAN_COMMAND_TX); @@ -540,78 +468,71 @@ static void arlan_registration_timer(unsigned long data) long lostTime = ((long)jiffies - (long)priv->registrationLastSeen) * (1000/HZ); - if (registrationBad(dev)) - { + if (registrationBad(dev)) { priv->registrationLostCount++; if (lostTime > 7000 && lostTime < 7200) - { printk(KERN_NOTICE "%s registration Lost \n", dev->name); - } + if (lostTime / priv->reRegisterExp > 2000) arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_CONF); if (lostTime / (priv->reRegisterExp) > 3500) arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET); if (priv->reRegisterExp < 400) priv->reRegisterExp += 2; - if (lostTime > 7200) - { + if (lostTime > 7200) { next_tick = HZ; arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET); } - } - else - { + } else { if (priv->Conf->registrationMode && lostTime > 10000 && - priv->registrationLostCount) - { + priv->registrationLostCount) { printk(KERN_NOTICE "%s registration is back after %ld milliseconds\n", dev->name, lostTime); } priv->registrationLastSeen = jiffies; priv->registrationLostCount = 0; priv->reRegisterExp = 1; - if (!netif_running(dev) ) + if (!netif_running(dev)) netif_wake_queue(dev); - if (time_after(priv->tx_last_sent,priv->tx_last_cleared) && - time_after(jiffies, priv->tx_last_sent * 5*HZ) ){ - arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET); + if (time_after(priv->tx_last_sent, priv->tx_last_cleared) && + time_after(jiffies, priv->tx_last_sent * 5*HZ)) { + arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET); priv->tx_last_cleared = jiffies; } } - if (!registrationBad(dev) && priv->ReTransmitRequested) - { + if (!registrationBad(dev) && priv->ReTransmitRequested) { IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_ERR "Retransmit from timer \n"); priv->ReTransmitRequested = 0; arlan_retransmit_now(dev); } + if (!registrationBad(dev) && time_after(jiffies, priv->tx_done_delayed) && - priv->tx_done_delayed != 0) - { + priv->tx_done_delayed != 0) { TXLAST(dev).offset = 0; + if (priv->txLast) priv->txLast = 0; else if (TXTAIL(dev).offset) priv->txLast = 1; - if (TXLAST(dev).offset) - { + if (TXLAST(dev).offset) { arlan_retransmit_now(dev); dev->trans_start = jiffies; } + if (!(TXHEAD(dev).offset && TXTAIL(dev).offset)) - { - netif_wake_queue (dev); - } + netif_wake_queue(dev); + priv->tx_done_delayed = 0; bh_mark_needed = 1; } + if (bh_mark_needed) - { - netif_wake_queue (dev); - } + netif_wake_queue(dev); + arlan_process_interrupt(dev); if (next_tick < priv->card_polling_interval) @@ -672,8 +593,7 @@ static int arlan_hw_tx(struct net_device *dev, char *buf, int length) tailStarts = 0x800 - (((TXTAIL(dev).offset - offsetof(struct arlan_shmem, txBuffer)) / 64) + 2) * 64; - if (!TXHEAD(dev).offset && length < tailStarts) - { + if (!TXHEAD(dev).offset && length < tailStarts) { IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_ERR "TXHEAD insert, tailStart %d\n", tailStarts); @@ -687,9 +607,7 @@ static int arlan_hw_tx(struct net_device *dev, char *buf, int length) TXHEAD(dev).routing = conf->txRouting; TXHEAD(dev).scrambled = conf->txScrambled; memcpy_toio((char __iomem *)arlan + TXHEAD(dev).offset, buf + ARLAN_FAKE_HDR_LEN, TXHEAD(dev).length); - } - else if (!TXTAIL(dev).offset && length < (0x800 - headEnds)) - { + } else if (!TXTAIL(dev).offset && length < (0x800 - headEnds)) { IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_ERR "TXTAIL insert, headEnd %d\n", headEnds); @@ -703,10 +621,8 @@ static int arlan_hw_tx(struct net_device *dev, char *buf, int length) TXTAIL(dev).routing = conf->txRouting; TXTAIL(dev).scrambled = conf->txScrambled; memcpy_toio(((char __iomem *)arlan + TXTAIL(dev).offset), buf + ARLAN_FAKE_HDR_LEN, TXTAIL(dev).length); - } - else - { - netif_stop_queue (dev); + } else { + netif_stop_queue(dev); IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_ERR "TX TAIL & HEAD full, return, tailStart %d headEnd %d\n", tailStarts, headEnds); return -1; @@ -715,26 +631,23 @@ static int arlan_hw_tx(struct net_device *dev, char *buf, int length) priv->out_bytes10 += length; if (conf->measure_rate < 1) conf->measure_rate = 1; - if (time_after(jiffies, priv->out_time + conf->measure_rate * HZ)) - { + if (time_after(jiffies, priv->out_time + conf->measure_rate * HZ)) { conf->out_speed = priv->out_bytes / conf->measure_rate; priv->out_bytes = 0; priv->out_time = jiffies; } - if (time_after(jiffies, priv->out_time10 + conf->measure_rate * 10*HZ)) - { + + if (time_after(jiffies, priv->out_time10 + conf->measure_rate * 10*HZ)) { conf->out_speed10 = priv->out_bytes10 / (10 * conf->measure_rate); priv->out_bytes10 = 0; priv->out_time10 = jiffies; } - if (TXHEAD(dev).offset && TXTAIL(dev).offset) - { - netif_stop_queue (dev); - return 0; - } - else - netif_start_queue (dev); + if (TXHEAD(dev).offset && TXTAIL(dev).offset) { + netif_stop_queue(dev); + return 0; + } else + netif_start_queue(dev); IFDEBUG(ARLAN_DEBUG_HEADER_DUMP) printk(KERN_WARNING "%s Transmit t %2x:%2x:%2x:%2x:%2x:%2x f %2x:%2x:%2x:%2x:%2x:%2x \n", dev->name, @@ -817,11 +730,11 @@ static int arlan_hw_config(struct net_device *dev) WRITESHMB(arlan->commandByte, ARLAN_COM_INT | ARLAN_COM_CONF); /* do configure */ memset_io(arlan->commandParameter, 0, 0xf); /* 0xf */ memset_io(arlan->commandParameter + 1, 0, 2); - if (conf->writeEEPROM) - { - memset_io(arlan->commandParameter, conf->writeEEPROM, 1); -// conf->writeEEPROM=0; + if (conf->writeEEPROM) { + memset_io(arlan->commandParameter, conf->writeEEPROM, 1); + /* conf->writeEEPROM=0; */ } + if (conf->registrationMode && conf->registrationInterrupts) memset_io(arlan->commandParameter + 3, 1, 1); else @@ -847,47 +760,46 @@ static int arlan_read_card_configuration(struct net_device *dev) ARLAN_DEBUG_ENTRY("arlan_read_card_configuration"); - if (radioNodeId == radioNodeIdUNKNOWN) - { + + if (radioNodeId == radioNodeIdUNKNOWN) { + /* multiline macro, cannot remove braces */ READSHM(conf->radioNodeId, arlan->radioNodeId, u_short); - } - else + } else conf->radioNodeId = radioNodeId; - - if (SID == SIDUNKNOWN) - { + + if (SID == SIDUNKNOWN) { + /* multiline macro, cannot remove braces */ READSHM(conf->SID, arlan->SID, u_int); - } - else conf->SID = SID; - - if (spreadingCode == spreadingCodeUNKNOWN) - { - READSHM(conf->spreadingCode, arlan->spreadingCode, u_char); - } - else + } else + conf->SID = SID; + + if (spreadingCode == spreadingCodeUNKNOWN) { + /* multiline macro, cannot remove braces */ + READSHM(conf->spreadingCode, arlan->spreadingCode, u_char); + } else conf->spreadingCode = spreadingCode; - - if (channelSet == channelSetUNKNOWN) - { + + if (channelSet == channelSetUNKNOWN) { + /* multiline macro, cannot remove braces */ READSHM(conf->channelSet, arlan->channelSet, u_char); - } - else conf->channelSet = channelSet; + } else + conf->channelSet = channelSet; - if (channelNumber == channelNumberUNKNOWN) - { + if (channelNumber == channelNumberUNKNOWN) { + /* multiline macro, cannot remove braces */ READSHM(conf->channelNumber, arlan->channelNumber, u_char); - } - else conf->channelNumber = channelNumber; - + } else + conf->channelNumber = channelNumber; + READSHM(conf->scramblingDisable, arlan->scramblingDisable, u_char); READSHM(conf->txAttenuation, arlan->txAttenuation, u_char); - - if (systemId == systemIdUNKNOWN) - { + + if (systemId == systemIdUNKNOWN) { + /* multiline macro, cannot remove braces */ READSHM(conf->systemId, arlan->systemId, u_int); - } - else conf->systemId = systemId; - + } else + conf->systemId = systemId; + READSHM(conf->maxDatagramSize, arlan->maxDatagramSize, u_short); READSHM(conf->maxFrameSize, arlan->maxFrameSize, u_short); READSHM(conf->maxRetries, arlan->maxRetries, u_char); @@ -895,18 +807,18 @@ static int arlan_read_card_configuration(struct net_device *dev) READSHM(conf->priority, arlan->priority, u_char); READSHM(conf->rootOrRepeater, arlan->rootOrRepeater, u_char); - if (SID == SIDUNKNOWN) - { + if (SID == SIDUNKNOWN) { + /* multiline macro, cannot remove braces */ READSHM(conf->SID, arlan->SID, u_int); - } - else conf->SID = SID; - - if (registrationMode == registrationModeUNKNOWN) - { + } else + conf->SID = SID; + + if (registrationMode == registrationModeUNKNOWN) { + /* multiline macro, cannot remove braces */ READSHM(conf->registrationMode, arlan->registrationMode, u_char); - } - else conf->registrationMode = registrationMode; - + } else + conf->registrationMode = registrationMode; + READSHM(conf->registrationFill, arlan->registrationFill, u_char); READSHM(conf->localTalkAddress, arlan->localTalkAddress, u_char); READSHM(conf->codeFormat, arlan->codeFormat, u_char); @@ -921,16 +833,16 @@ static int arlan_read_card_configuration(struct net_device *dev) READSHM(conf->headerSize, arlan->headerSize, u_short); READSHM(conf->hardwareType, arlan->hardwareType, u_char); READSHM(conf->radioType, arlan->radioModule, u_char); - + if (conf->radioType == 0) conf->radioType = 0xc; WRITESHM(arlan->configStatus, 0xA5, u_char); READSHM(tlx415, arlan->configStatus, u_char); - + if (tlx415 != 0xA5) printk(KERN_INFO "%s tlx415 chip \n", dev->name); - + conf->txClear = 0; conf->txRetries = 1; conf->txRouting = 1; @@ -973,7 +885,7 @@ static int __init arlan_check_fingerprint(unsigned long memaddr) ARLAN_DEBUG_ENTRY("arlan_check_fingerprint"); if (!request_mem_region(paddr, ARLAN_SHMEM_SIZE, "arlan")) { - // printk(KERN_WARNING "arlan: memory region %lx excluded from probing \n",paddr); + /* printk(KERN_WARNING "arlan: memory region %lx excluded from probing \n",paddr); */ return -ENODEV; } @@ -981,12 +893,12 @@ static int __init arlan_check_fingerprint(unsigned long memaddr) tempBuf[30] = 0; /* check for card at this address */ - if (0 != strncmp(tempBuf, probeText, 29)){ - release_mem_region(paddr, ARLAN_SHMEM_SIZE); + if (0 != strncmp(tempBuf, probeText, 29)) { + release_mem_region(paddr, ARLAN_SHMEM_SIZE); return -ENODEV; } -// printk(KERN_INFO "arlan found at 0x%x \n",memaddr); + /* printk(KERN_INFO "arlan found at 0x%x \n",memaddr); */ ARLAN_DEBUG_EXIT("arlan_check_fingerprint"); return 0; @@ -1054,7 +966,7 @@ static int __init arlan_setup_device(struct net_device *dev, int num) dev->tx_queue_len = tx_queue_len; dev->netdev_ops = &arlan_netdev_ops; dev->watchdog_timeo = 3*HZ; - + ap->irq_test_done = 0; ap->Conf = &arlan_conf[num]; @@ -1065,7 +977,7 @@ static int __init arlan_setup_device(struct net_device *dev, int num) err = register_netdev(dev); if (err) { - release_mem_region(virt_to_phys((void *) dev->mem_start), + release_mem_region(virt_to_phys((void *) dev->mem_start), ARLAN_SHMEM_SIZE); free_netdev(dev); return err; @@ -1075,7 +987,7 @@ static int __init arlan_setup_device(struct net_device *dev, int num) return 0; } -static int __init arlan_probe_here(struct net_device *dev, +static int __init arlan_probe_here(struct net_device *dev, unsigned long memaddr) { struct arlan_private *ap = netdev_priv(dev); @@ -1085,15 +997,15 @@ static int __init arlan_probe_here(struct net_device *dev, if (arlan_check_fingerprint(memaddr)) return -ENODEV; - printk(KERN_NOTICE "%s: Arlan found at %llx, \n ", dev->name, - (u64) virt_to_phys((void*)memaddr)); + printk(KERN_NOTICE "%s: Arlan found at %llx, \n ", dev->name, + (u64) virt_to_phys((void *)memaddr)); ap->card = (void *) memaddr; dev->mem_start = memaddr; dev->mem_end = memaddr + ARLAN_SHMEM_SIZE-1; - if (dev->irq < 2) - { + if (dev->irq < 2) { + /* multiline macro, cannot remove braces */ READSHM(dev->irq, ap->card->irqLevel, u_char); } else if (dev->irq == 2) dev->irq = 9; @@ -1114,14 +1026,12 @@ static int arlan_open(struct net_device *dev) ARLAN_DEBUG_ENTRY("arlan_open"); ret = request_irq(dev->irq, &arlan_interrupt, 0, dev->name, dev); - if (ret) - { + if (ret) { printk(KERN_ERR "%s: unable to get IRQ %d .\n", dev->name, dev->irq); return ret; } - priv->bad = 0; priv->lastReset = 0; priv->reset = 0; @@ -1131,14 +1041,14 @@ static int arlan_open(struct net_device *dev) priv->interrupt_processing_active = 0; spin_lock_init(&priv->lock); - netif_start_queue (dev); + netif_start_queue(dev); priv->registrationLostCount = 0; priv->registrationLastSeen = jiffies; priv->txLast = 0; priv->tx_command_given = 0; priv->rx_command_given = 0; - + priv->reRegisterExp = 1; priv->tx_last_sent = jiffies - 1; priv->tx_last_cleared = jiffies; @@ -1159,13 +1069,13 @@ static int arlan_open(struct net_device *dev) } -static void arlan_tx_timeout (struct net_device *dev) +static void arlan_tx_timeout(struct net_device *dev) { printk(KERN_ERR "%s: arlan transmit timed out, kernel decided\n", dev->name); /* Try to restart the adaptor. */ arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET); - // dev->trans_start = jiffies; - // netif_start_queue (dev); + /* dev->trans_start = jiffies; */ + /* netif_start_queue (dev); */ } @@ -1175,13 +1085,13 @@ static netdev_tx_t arlan_tx(struct sk_buff *skb, struct net_device *dev) unsigned char *buf; ARLAN_DEBUG_ENTRY("arlan_tx"); - + length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; buf = skb->data; if (length + 0x12 > 0x800) { printk(KERN_ERR "TX RING overflow \n"); - netif_stop_queue (dev); + netif_stop_queue(dev); } if (arlan_hw_tx(dev, buf, length) == -1) @@ -1197,7 +1107,7 @@ static netdev_tx_t arlan_tx(struct sk_buff *skb, struct net_device *dev) bad_end: arlan_process_interrupt(dev); - netif_stop_queue (dev); + netif_stop_queue(dev); ARLAN_DEBUG_EXIT("arlan_tx"); return NETDEV_TX_BUSY; } @@ -1229,9 +1139,8 @@ static inline void arlan_queue_retransmit(struct net_device *dev) ARLAN_DEBUG_ENTRY("arlan_queue_retransmit"); if (DoNotWaitReTransmitCrap(dev)) - { - arlan_drop_tx(dev); - } else + arlan_drop_tx(dev); + else priv->ReTransmitRequested++; ARLAN_DEBUG_EXIT("arlan_queue_retransmit"); @@ -1245,14 +1154,11 @@ static inline void RetryOrFail(struct net_device *dev) if (priv->retransmissions > priv->Conf->retries || DoNotReTransmitCrap(dev)) - { arlan_drop_tx(dev); - } else if (priv->bad <= priv->Conf->fastReTransCount) - { arlan_retransmit_now(dev); - } - else arlan_queue_retransmit(dev); + else + arlan_queue_retransmit(dev); ARLAN_DEBUG_EXIT("RetryOrFail"); } @@ -1266,131 +1172,126 @@ static void arlan_tx_done_interrupt(struct net_device *dev, int status) priv->tx_last_cleared = jiffies; priv->tx_command_given = 0; - switch (status) + switch (status) { + case 1: { - case 1: - { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk("arlan intr: transmit OK\n"); - dev->stats.tx_packets++; - priv->bad = 0; - priv->reset = 0; - priv->retransmissions = 0; - if (priv->Conf->tx_delay_ms) - { - priv->tx_done_delayed = jiffies + (priv->Conf->tx_delay_ms * HZ) / 1000 + 1; - } - else - { - TXLAST(dev).offset = 0; - if (priv->txLast) - priv->txLast = 0; - else if (TXTAIL(dev).offset) - priv->txLast = 1; - if (TXLAST(dev).offset) - { - arlan_retransmit_now(dev); - dev->trans_start = jiffies; - } - if (!TXHEAD(dev).offset || !TXTAIL(dev).offset) - { - netif_wake_queue (dev); - } + IFDEBUG(ARLAN_DEBUG_TX_CHAIN) + printk("arlan intr: transmit OK\n"); + dev->stats.tx_packets++; + priv->bad = 0; + priv->reset = 0; + priv->retransmissions = 0; + if (priv->Conf->tx_delay_ms) + priv->tx_done_delayed = jiffies + (priv->Conf->tx_delay_ms * HZ) / 1000 + 1; + else { + TXLAST(dev).offset = 0; + if (priv->txLast) + priv->txLast = 0; + else if (TXTAIL(dev).offset) + priv->txLast = 1; + + if (TXLAST(dev).offset) { + arlan_retransmit_now(dev); + dev->trans_start = jiffies; } - } - break; - - case 2: - { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk("arlan intr: transmit timed out\n"); - priv->bad += 1; - //arlan_queue_retransmit(dev); - RetryOrFail(dev); - } - break; - case 3: - { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk("arlan intr: transmit max retries\n"); - priv->bad += 1; - priv->reset = 0; - //arlan_queue_retransmit(dev); - RetryOrFail(dev); + if (!TXHEAD(dev).offset || !TXTAIL(dev).offset) + netif_wake_queue(dev); } - break; - - case 4: - { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk("arlan intr: transmit aborted\n"); - priv->bad += 1; - arlan_queue_retransmit(dev); - //RetryOrFail(dev); - } - break; + } + break; - case 5: - { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk("arlan intr: transmit not registered\n"); - priv->bad += 1; - //debug=101; - arlan_queue_retransmit(dev); - } - break; + case 2: + { + IFDEBUG(ARLAN_DEBUG_TX_CHAIN) + printk("arlan intr: transmit timed out\n"); + priv->bad += 1; + /* arlan_queue_retransmit(dev); */ + RetryOrFail(dev); + } + break; - case 6: - { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk("arlan intr: transmit destination full\n"); - priv->bad += 1; - priv->reset = 0; - //arlan_drop_tx(dev); - arlan_queue_retransmit(dev); - } - break; + case 3: + { + IFDEBUG(ARLAN_DEBUG_TX_CHAIN) + printk("arlan intr: transmit max retries\n"); + priv->bad += 1; + priv->reset = 0; + /* arlan_queue_retransmit(dev); */ + RetryOrFail(dev); + } + break; - case 7: - { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk("arlan intr: transmit unknown ack\n"); - priv->bad += 1; - priv->reset = 0; - arlan_queue_retransmit(dev); - } - break; - - case 8: - { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk("arlan intr: transmit dest mail box full\n"); - priv->bad += 1; - priv->reset = 0; - //arlan_drop_tx(dev); - arlan_queue_retransmit(dev); - } - break; + case 4: + { + IFDEBUG(ARLAN_DEBUG_TX_CHAIN) + printk("arlan intr: transmit aborted\n"); + priv->bad += 1; + arlan_queue_retransmit(dev); + /* RetryOrFail(dev); */ + } + break; - case 9: - { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk("arlan intr: transmit root dest not reg.\n"); - priv->bad += 1; - priv->reset = 1; - //arlan_drop_tx(dev); - arlan_queue_retransmit(dev); - } - break; + case 5: + { + IFDEBUG(ARLAN_DEBUG_TX_CHAIN) + printk("arlan intr: transmit not registered\n"); + priv->bad += 1; + /* debug=101; */ + arlan_queue_retransmit(dev); + } + break; - default: - { - printk(KERN_ERR "arlan intr: transmit status unknown\n"); - priv->bad += 1; - priv->reset = 1; - arlan_drop_tx(dev); - } + case 6: + { + IFDEBUG(ARLAN_DEBUG_TX_CHAIN) + printk("arlan intr: transmit destination full\n"); + priv->bad += 1; + priv->reset = 0; + /* arlan_drop_tx(dev); */ + arlan_queue_retransmit(dev); + } + break; + + case 7: + { + IFDEBUG(ARLAN_DEBUG_TX_CHAIN) + printk("arlan intr: transmit unknown ack\n"); + priv->bad += 1; + priv->reset = 0; + arlan_queue_retransmit(dev); + } + break; + + case 8: + { + IFDEBUG(ARLAN_DEBUG_TX_CHAIN) + printk("arlan intr: transmit dest mail box full\n"); + priv->bad += 1; + priv->reset = 0; + /* arlan_drop_tx(dev); */ + arlan_queue_retransmit(dev); + } + break; + + case 9: + { + IFDEBUG(ARLAN_DEBUG_TX_CHAIN) + printk("arlan intr: transmit root dest not reg.\n"); + priv->bad += 1; + priv->reset = 1; + /* arlan_drop_tx(dev); */ + arlan_queue_retransmit(dev); + } + break; + + default: + { + printk(KERN_ERR "arlan intr: transmit status unknown\n"); + priv->bad += 1; + priv->reset = 1; + arlan_drop_tx(dev); + } } ARLAN_DEBUG_EXIT("arlan_tx_done_interrupt"); @@ -1408,134 +1309,126 @@ static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short ARLAN_DEBUG_ENTRY("arlan_rx_interrupt"); - // by spec, not WRITESHMB(arlan->rxStatus,0x00); - // prohibited here arlan_command(dev, ARLAN_COMMAND_RX); + /* by spec, not WRITESHMB(arlan->rxStatus,0x00); */ + /* prohibited here arlan_command(dev, ARLAN_COMMAND_RX); */ - if (pkt_len < 10 || pkt_len > 2048) - { + if (pkt_len < 10 || pkt_len > 2048) { printk(KERN_WARNING "%s: got too short or long packet, len %d \n", dev->name, pkt_len); return; } - if (rxOffset + pkt_len > 0x2000) - { + if (rxOffset + pkt_len > 0x2000) { printk("%s: got too long packet, len %d offset %x\n", dev->name, pkt_len, rxOffset); return; } + priv->in_bytes += pkt_len; priv->in_bytes10 += pkt_len; if (conf->measure_rate < 1) conf->measure_rate = 1; - if (time_after(jiffies, priv->in_time + conf->measure_rate * HZ)) - { + if (time_after(jiffies, priv->in_time + conf->measure_rate * HZ)) { conf->in_speed = priv->in_bytes / conf->measure_rate; priv->in_bytes = 0; priv->in_time = jiffies; } - if (time_after(jiffies, priv->in_time10 + conf->measure_rate * 10*HZ)) - { + if (time_after(jiffies, priv->in_time10 + conf->measure_rate * 10*HZ)) { conf->in_speed10 = priv->in_bytes10 / (10 * conf->measure_rate); priv->in_bytes10 = 0; priv->in_time10 = jiffies; } DEBUGSHM(1, "arlan rcv pkt rxStatus= %d ", arlan->rxStatus, u_char); - switch (rxStatus) + switch (rxStatus) { + case 1: + case 2: + case 3: { - case 1: - case 2: - case 3: - { - /* Malloc up new buffer. */ - struct sk_buff *skb; + /* Malloc up new buffer. */ + struct sk_buff *skb; - DEBUGSHM(50, "arlan recv pkt offs=%d\n", arlan->rxOffset, u_short); - DEBUGSHM(1, "arlan rxFrmType = %d \n", arlan->rxFrmType, u_char); - DEBUGSHM(1, KERN_INFO "arlan rx scrambled = %d \n", arlan->scrambled, u_char); + DEBUGSHM(50, "arlan recv pkt offs=%d\n", arlan->rxOffset, u_short); + DEBUGSHM(1, "arlan rxFrmType = %d \n", arlan->rxFrmType, u_char); + DEBUGSHM(1, KERN_INFO "arlan rx scrambled = %d \n", arlan->scrambled, u_char); - /* here we do multicast filtering to avoid slow 8-bit memcopy */ + /* here we do multicast filtering to avoid slow 8-bit memcopy */ #ifdef ARLAN_MULTICAST - if (!(dev->flags & IFF_ALLMULTI) && - !(dev->flags & IFF_PROMISC) && - !netdev_mc_empty(dev)) - { - char hw_dst_addr[6]; - struct dev_mc_list *dmi; - int i; - - memcpy_fromio(hw_dst_addr, arlan->ultimateDestAddress, 6); - if (hw_dst_addr[0] == 0x01) - { - if (mdebug) - if (hw_dst_addr[1] == 0x00) - printk(KERN_ERR "%s mcast 0x0100 \n", dev->name); - else if (hw_dst_addr[1] == 0x40) - printk(KERN_ERR "%s m/bcast 0x0140 \n", dev->name); - netdev_for_each_mc_entry(dmi, dev) { - if (arlan_debug & ARLAN_DEBUG_HEADER_DUMP) - printk(KERN_ERR "%s mcl %pM\n", - dev->name, dmi->dmi_addr); - for (i = 0; i < 6; i++) - if (dmi->dmi_addr[i] != hw_dst_addr[i]) - break; - if (i == 6) + if (!(dev->flags & IFF_ALLMULTI) && + !(dev->flags & IFF_PROMISC) && + !netdev_mc_empty(dev)) { + char hw_dst_addr[6]; + struct dev_mc_list *dmi; + int i; + + memcpy_fromio(hw_dst_addr, arlan->ultimateDestAddress, 6); + if (hw_dst_addr[0] == 0x01) { + if (mdebug) + if (hw_dst_addr[1] == 0x00) + printk(KERN_ERR "%s mcast 0x0100 \n", dev->name); + else if (hw_dst_addr[1] == 0x40) + printk(KERN_ERR "%s m/bcast 0x0140 \n", dev->name); + netdev_for_each_mc_entry(dmi, dev) { + if (arlan_debug & ARLAN_DEBUG_HEADER_DUMP) + printk(KERN_ERR "%s mcl %pM\n", + dev->name, dmi->dmi_addr); + for (i = 0; i < 6; i++) + if (dmi->dmi_addr[i] != hw_dst_addr[i]) break; - } - /* we reach here if multicast filtering is on and packet - * is multicast and not for receive */ - goto end_of_interrupt; + if (i == 6) + break; } + /* we reach here if multicast filtering is on and packet */ + /* is multicast and not for receive */ + goto end_of_interrupt; } -#endif // ARLAN_MULTICAST - /* multicast filtering ends here */ - pkt_len += ARLAN_FAKE_HDR_LEN; - - skb = dev_alloc_skb(pkt_len + 4); - if (skb == NULL) - { - printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name); - dev->stats.rx_dropped++; - break; - } - skb_reserve(skb, 2); - skbtmp = skb_put(skb, pkt_len); + } +#endif /* ARLAN_MULTICAST */ + /* multicast filtering ends here */ + pkt_len += ARLAN_FAKE_HDR_LEN; + + skb = dev_alloc_skb(pkt_len + 4); + if (skb == NULL) { + printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name); + dev->stats.rx_dropped++; + break; + } + skb_reserve(skb, 2); + skbtmp = skb_put(skb, pkt_len); - memcpy_fromio(skbtmp + ARLAN_FAKE_HDR_LEN, ((char __iomem *) arlan) + rxOffset, pkt_len - ARLAN_FAKE_HDR_LEN); - memcpy_fromio(skbtmp, arlan->ultimateDestAddress, 6); - memcpy_fromio(skbtmp + 6, arlan->rxSrc, 6); - WRITESHMB(arlan->rxStatus, 0x00); - arlan_command(dev, ARLAN_COMMAND_RX); + memcpy_fromio(skbtmp + ARLAN_FAKE_HDR_LEN, ((char __iomem *) arlan) + rxOffset, pkt_len - ARLAN_FAKE_HDR_LEN); + memcpy_fromio(skbtmp, arlan->ultimateDestAddress, 6); + memcpy_fromio(skbtmp + 6, arlan->rxSrc, 6); + WRITESHMB(arlan->rxStatus, 0x00); + arlan_command(dev, ARLAN_COMMAND_RX); - IFDEBUG(ARLAN_DEBUG_HEADER_DUMP) - { - char immedDestAddress[6]; - char immedSrcAddress[6]; - memcpy_fromio(immedDestAddress, arlan->immedDestAddress, 6); - memcpy_fromio(immedSrcAddress, arlan->immedSrcAddress, 6); - - printk(KERN_WARNING "%s t %pM f %pM imd %pM ims %pM\n", - dev->name, skbtmp, - &skbtmp[6], - immedDestAddress, - immedSrcAddress); - } - skb->protocol = eth_type_trans(skb, dev); - IFDEBUG(ARLAN_DEBUG_HEADER_DUMP) - if (skb->protocol != 0x608 && skb->protocol != 0x8) - { - for (i = 0; i <= 22; i++) - printk("%02x:", (u_char) skbtmp[i + 12]); - printk(KERN_ERR "\n"); - printk(KERN_WARNING "arlan kernel pkt type trans %x \n", skb->protocol); - } - netif_rx(skb); - dev->stats.rx_packets++; - dev->stats.rx_bytes += pkt_len; + IFDEBUG(ARLAN_DEBUG_HEADER_DUMP) + { + char immedDestAddress[6]; + char immedSrcAddress[6]; + memcpy_fromio(immedDestAddress, arlan->immedDestAddress, 6); + memcpy_fromio(immedSrcAddress, arlan->immedSrcAddress, 6); + + printk(KERN_WARNING "%s t %pM f %pM imd %pM ims %pM\n", + dev->name, skbtmp, + &skbtmp[6], + immedDestAddress, + immedSrcAddress); } + skb->protocol = eth_type_trans(skb, dev); + IFDEBUG(ARLAN_DEBUG_HEADER_DUMP) + if (skb->protocol != 0x608 && skb->protocol != 0x8) { + for (i = 0; i <= 22; i++) + printk("%02x:", (u_char) skbtmp[i + 12]); + printk(KERN_ERR "\n"); + printk(KERN_WARNING "arlan kernel pkt type trans %x \n", skb->protocol); + } + netif_rx(skb); + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; + } + break; + + default: + printk(KERN_ERR "arlan intr: received unknown status\n"); + dev->stats.rx_crc_errors++; break; - - default: - printk(KERN_ERR "arlan intr: received unknown status\n"); - dev->stats.rx_crc_errors++; - break; } ARLAN_DEBUG_EXIT("arlan_rx_interrupt"); } @@ -1552,30 +1445,26 @@ static void arlan_process_interrupt(struct net_device *dev) ARLAN_DEBUG_ENTRY("arlan_process_interrupt"); - if (test_and_set_bit(0, (void *) &priv->interrupt_processing_active)) - { + if (test_and_set_bit(0, (void *) &priv->interrupt_processing_active)) { if (arlan_debug & ARLAN_DEBUG_CHAIN_LOCKS) printk(KERN_ERR "interrupt chain reentering \n"); goto end_int_process; } while ((rxStatus || txStatus || priv->interrupt_ack_requested) - && (interrupt_count < 5)) - { + && (interrupt_count < 5)) { if (rxStatus) priv->last_rx_int_ack_time = jiffies; arlan_command(dev, ARLAN_COMMAND_INT_ACK); arlan_command(dev, ARLAN_COMMAND_INT_ENABLE); - + IFDEBUG(ARLAN_DEBUG_INTERRUPT) printk(KERN_ERR "%s: got IRQ rx %x tx %x comm %x rxOff %x rxLen %x \n", dev->name, rxStatus, txStatus, READSHMB(arlan->commandByte), rxOffset, pkt_len); - if (rxStatus == 0 && txStatus == 0) - { - if (priv->irq_test_done) - { + if (rxStatus == 0 && txStatus == 0) { + if (priv->irq_test_done) { if (!registrationBad(dev)) IFDEBUG(ARLAN_DEBUG_INTERRUPT) printk(KERN_ERR "%s unknown interrupt(nop? regLost ?) reason tx %d rx %d ", dev->name, txStatus, rxStatus); @@ -1587,35 +1476,35 @@ static void arlan_process_interrupt(struct net_device *dev) priv->interrupt_ack_requested = 0; goto ends; } - if (txStatus != 0) - { + + if (txStatus != 0) { WRITESHMB(arlan->txStatus, 0x00); arlan_tx_done_interrupt(dev, txStatus); goto ends; } - if (rxStatus == 1 || rxStatus == 2) - { /* a packet waiting */ + + if (rxStatus == 1 || rxStatus == 2) { + /* a packet waiting */ arlan_rx_interrupt(dev, rxStatus, rxOffset, pkt_len); goto ends; } - if (rxStatus > 2 && rxStatus < 0xff) - { + + if (rxStatus > 2 && rxStatus < 0xff) { WRITESHMB(arlan->rxStatus, 0x00); printk(KERN_ERR "%s unknown rxStatus reason tx %d rx %d ", dev->name, txStatus, rxStatus); goto ends; } - if (rxStatus == 0xff) - { + + if (rxStatus == 0xff) { WRITESHMB(arlan->rxStatus, 0x00); arlan_command(dev, ARLAN_COMMAND_RX); if (registrationBad(dev)) netif_device_detach(dev); - if (!registrationBad(dev)) - { + if (!registrationBad(dev)) { priv->registrationLastSeen = jiffies; if (!netif_queue_stopped(dev) && !priv->under_reset && !priv->under_config) - netif_wake_queue (dev); + netif_wake_queue(dev); } goto ends; } @@ -1657,7 +1546,7 @@ static irqreturn_t arlan_interrupt(int irq, void *dev_id) priv->interrupt_ack_requested++; arlan_process_interrupt(dev); - + priv->irq_test_done = 1; ARLAN_DEBUG_EXIT("arlan_interrupt"); @@ -1687,7 +1576,7 @@ static int arlan_close(struct net_device *dev) } #ifdef ARLAN_DEBUGGING -static long alignLong(volatile u_char * ptr) +static long alignLong(volatile u_char *ptr) { long ret; memcpy_fromio(&ret, (void *) ptr, 4); @@ -1740,16 +1629,13 @@ static void arlan_set_multicast(struct net_device *dev) ARLAN_DEBUG_ENTRY("arlan_set_multicast"); - if (dev->flags & IFF_PROMISC) - { + if (dev->flags & IFF_PROMISC) { unsigned char recMode; READSHM(recMode, arlan->receiveMode, u_char); conf->receiveMode = (ARLAN_RCV_PROMISC | ARLAN_RCV_CONTROL); if (conf->receiveMode != recMode) board_conf_needed = 1; - } - else - { + } else { /* turn off promiscuous mode */ unsigned char recMode; READSHM(recMode, arlan->receiveMode, u_char); @@ -1757,6 +1643,7 @@ static void arlan_set_multicast(struct net_device *dev) if (conf->receiveMode != recMode) board_conf_needed = 1; } + if (board_conf_needed) arlan_command(dev, ARLAN_COMMAND_CONF); @@ -1775,7 +1662,7 @@ struct net_device * __init arlan_probe(int unit) if (arlans_found == MAX_ARLANS) return ERR_PTR(-ENODEV); - /* + /* * Reserve space for local data and a copy of the shared memory * that is used by the /proc interface. */ @@ -1787,23 +1674,20 @@ struct net_device * __init arlan_probe(int unit) if (unit >= 0) { sprintf(dev->name, "eth%d", unit); netdev_boot_setup_check(dev); - + if (dev->mem_start) { if (arlan_probe_here(dev, dev->mem_start) == 0) goto found; goto not_found; } - } - for (m = (int)phys_to_virt(lastFoundAt) + ARLAN_SHMEM_SIZE; - m <= (int)phys_to_virt(0xDE000); - m += ARLAN_SHMEM_SIZE) - { - if (arlan_probe_here(dev, m) == 0) - { - lastFoundAt = (int)virt_to_phys((void*)m); + for (m = (int)phys_to_virt(lastFoundAt) + ARLAN_SHMEM_SIZE; + m <= (int)phys_to_virt(0xDE000); + m += ARLAN_SHMEM_SIZE) { + if (arlan_probe_here(dev, m) == 0) { + lastFoundAt = (int)virt_to_phys((void *)m); goto found; } } @@ -1825,7 +1709,7 @@ struct net_device * __init arlan_probe(int unit) return dev; } -#ifdef MODULE +#ifdef MODULE int __init init_module(void) { int i = 0; @@ -1838,7 +1722,7 @@ int __init init_module(void) for (i = 0; i < MAX_ARLANS; i++) { struct net_device *dev = arlan_probe(i); - if (IS_ERR(dev)) + if (IS_ERR(dev)) return PTR_ERR(dev); } init_arlan_proc(); @@ -1860,14 +1744,13 @@ void __exit cleanup_module(void) cleanup_arlan_proc(); - for (i = 0; i < MAX_ARLANS; i++) - { + for (i = 0; i < MAX_ARLANS; i++) { dev = arlan_device[i]; if (dev) { - arlan_command(dev, ARLAN_COMMAND_POWERDOWN ); + arlan_command(dev, ARLAN_COMMAND_POWERDOWN); unregister_netdev(dev); - release_mem_region(virt_to_phys((void *) dev->mem_start), + release_mem_region(virt_to_phys((void *) dev->mem_start), ARLAN_SHMEM_SIZE); free_netdev(dev); arlan_device[i] = NULL; -- cgit v1.2.3 From b4c84c298bd3a2383dadceb64d2b5f23dc2adc61 Mon Sep 17 00:00:00 2001 From: Michael Tate Date: Sat, 6 Mar 2010 15:03:57 +0400 Subject: staging: et131x: Fix brace coding style issues. This revised patch fixes 2 brace coding style issues reported by checkpatch.pl One warning line > 80 chars not resolved on maintainers advice. Signed-off-by: Michael Tate Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x_isr.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/et131x/et131x_isr.c b/drivers/staging/et131x/et131x_isr.c index cb7f6775ce0a..36f68fe3e8c9 100644 --- a/drivers/staging/et131x/et131x_isr.c +++ b/drivers/staging/et131x/et131x_isr.c @@ -253,14 +253,12 @@ void et131x_isr_handler(struct work_struct *work) * exit. */ /* Handle all the completed Transmit interrupts */ - if (status & ET_INTR_TXDMA_ISR) { + if (status & ET_INTR_TXDMA_ISR) et131x_handle_send_interrupt(etdev); - } /* Handle all the completed Receives interrupts */ - if (status & ET_INTR_RXDMA_XFR_DONE) { + if (status & ET_INTR_RXDMA_XFR_DONE) et131x_handle_recv_interrupt(etdev); - } status &= 0xffffffd7; -- cgit v1.2.3 From e3133b282af36665593b2802eaa591538ebe5f11 Mon Sep 17 00:00:00 2001 From: Florian Schilhabel Date: Sat, 6 Mar 2010 20:44:33 +0100 Subject: staging: rtl8192su: move to EEPROM_93CX this is basically a port of Larry Fingers Patch for rtl8187se to rtl8192su. also removed some dead code. plus cosmetics. Signed-off-by: Florian Schilhabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192su/Kconfig | 1 + drivers/staging/rtl8192su/Makefile | 1 - drivers/staging/rtl8192su/r8180_93cx6.c | 146 -------------------------------- drivers/staging/rtl8192su/r8180_93cx6.h | 40 --------- drivers/staging/rtl8192su/r8192U.h | 6 ++ drivers/staging/rtl8192su/r8192U_core.c | 113 ++++++++++++++---------- 6 files changed, 74 insertions(+), 233 deletions(-) delete mode 100644 drivers/staging/rtl8192su/r8180_93cx6.c delete mode 100644 drivers/staging/rtl8192su/r8180_93cx6.h (limited to 'drivers') diff --git a/drivers/staging/rtl8192su/Kconfig b/drivers/staging/rtl8192su/Kconfig index b72a96206f58..b422ea1ecf9c 100644 --- a/drivers/staging/rtl8192su/Kconfig +++ b/drivers/staging/rtl8192su/Kconfig @@ -3,5 +3,6 @@ config RTL8192SU depends on PCI && WLAN && USB select WIRELESS_EXT select WEXT_PRIV + select EEPROM_93CX6 default N ---help--- diff --git a/drivers/staging/rtl8192su/Makefile b/drivers/staging/rtl8192su/Makefile index c8b4332d108c..9374a0179e5b 100644 --- a/drivers/staging/rtl8192su/Makefile +++ b/drivers/staging/rtl8192su/Makefile @@ -9,7 +9,6 @@ EXTRA_CFLAGS += -DTHOMAS_BEACON #EXTRA_CFLAGS += -DMUTIPLE_BULK_OUT r8192s_usb-objs := \ - r8180_93cx6.o \ r8192U_wx.o \ r8192S_phy.o \ r8192S_rtl6052.o \ diff --git a/drivers/staging/rtl8192su/r8180_93cx6.c b/drivers/staging/rtl8192su/r8180_93cx6.c deleted file mode 100644 index 8878cfeb0fbb..000000000000 --- a/drivers/staging/rtl8192su/r8180_93cx6.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - This files contains card eeprom (93c46 or 93c56) programming routines, - memory is addressed by 16 bits words. - - This is part of rtl8180 OpenSource driver. - Copyright (C) Andrea Merello 2004 - Released under the terms of GPL (General Public Licence) - - Parts of this driver are based on the GPL part of the - official realtek driver. - - Parts of this driver are based on the rtl8180 driver skeleton - from Patric Schenke & Andres Salomon. - - Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. - - We want to tanks the Authors of those projects and the Ndiswrapper - project Authors. -*/ - -#include "r8180_93cx6.h" - -void eprom_cs(struct net_device *dev, short bit) -{ - if(bit) - write_nic_byte_E(dev, EPROM_CMD, - (1<epromtype==EPROM_93c56){ - addr_str[7]=addr & 1; - addr_str[6]=addr & (1<<1); - addr_str[5]=addr & (1<<2); - addr_str[4]=addr & (1<<3); - addr_str[3]=addr & (1<<4); - addr_str[2]=addr & (1<<5); - addr_str[1]=addr & (1<<6); - addr_str[0]=addr & (1<<7); - addr_len=8; - }else{ - addr_str[5]=addr & 1; - addr_str[4]=addr & (1<<1); - addr_str[3]=addr & (1<<2); - addr_str[2]=addr & (1<<3); - addr_str[1]=addr & (1<<4); - addr_str[0]=addr & (1<<5); - addr_len=6; - } - eprom_cs(dev, 1); - eprom_ck_cycle(dev); - eprom_send_bits_string(dev, read_cmd, 3); - eprom_send_bits_string(dev, addr_str, addr_len); - - //keep chip pin D to low state while reading. - //I'm unsure if it is necessary, but anyway shouldn't hurt - eprom_w(dev, 0); - - for(i=0;i<16;i++){ - //eeprom needs a clk cycle between writing opcode&adr - //and reading data. (eeprom outs a dummy 0) - eprom_ck_cycle(dev); - ret |= (eprom_r(dev)<<(15-i)); - } - - eprom_cs(dev, 0); - eprom_ck_cycle(dev); - - //disable EPROM programming - write_nic_byte_E(dev, EPROM_CMD, - (EPROM_CMD_NORMAL< - Released under the terms of GPL (General Public Licence) - - Parts of this driver are based on the GPL part of the official realtek driver - Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon - Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - - We want to tanks the Authors of such projects and the Ndiswrapper project Authors. -*/ - -/*This files contains card eeprom (93c46 or 93c56) programming routines*/ -/*memory is addressed by WORDS*/ - -#include "r8192U.h" -#include "r8192S_hw.h" - -#define EPROM_DELAY 10 - -#define EPROM_ANAPARAM_ADDRLWORD 0xd -#define EPROM_ANAPARAM_ADDRHWORD 0xe - -#define EPROM_RFCHIPID 0x6 -#define EPROM_TXPW_BASE 0x05 -#define EPROM_RFCHIPID_RTL8225U 5 -#define EPROM_RF_PARAM 0x4 -#define EPROM_CONFIG2 0xc - -#define EPROM_VERSION 0x1E -#define MAC_ADR 0x7 - -#define CIS 0x18 - -#define EPROM_TXPW0 0x16 -#define EPROM_TXPW2 0x1b -#define EPROM_TXPW1 0x3d - - -u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word diff --git a/drivers/staging/rtl8192su/r8192U.h b/drivers/staging/rtl8192su/r8192U.h index ba87623f32ee..830625253293 100644 --- a/drivers/staging/rtl8192su/r8192U.h +++ b/drivers/staging/rtl8192su/r8192U.h @@ -44,6 +44,12 @@ #include "r8192S_firmware.h" +/* EEPROM defs for use with linux/eeprom_93cx6.h */ +#define RTL819X_EEPROM_CMD_READ (1 << 0) +#define RTL819X_EEPROM_CMD_WRITE (1 << 1) +#define RTL819X_EEPROM_CMD_CK (1 << 2) +#define RTL819X_EEPROM_CMD_CS (1 << 3) + //#define RTL8192U #define RTL819xU_MODULE_NAME "rtl819xU" //added for HW security, john.0629 diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index e16256fe595a..791cd51cfdd0 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c @@ -26,6 +26,7 @@ #include #include +#include #undef LOOP_TEST #undef DUMP_RX @@ -54,7 +55,6 @@ #include #include "r8192U.h" -#include "r8180_93cx6.h" /* Card EEPROM */ #include "r8192U_wx.h" #include "r8192S_rtl8225.h" @@ -214,6 +214,36 @@ static CHANNEL_LIST ChannelPlan[] = { {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14} //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626 }; +static void rtl819x_eeprom_register_read(struct eeprom_93cx6 *eeprom) +{ + struct net_device *dev = eeprom->data; + u8 reg = read_nic_byte(dev, EPROM_CMD); + + eeprom->reg_data_in = reg & RTL819X_EEPROM_CMD_WRITE; + eeprom->reg_data_out = reg & RTL819X_EEPROM_CMD_READ; + eeprom->reg_data_clock = reg & RTL819X_EEPROM_CMD_CK; + eeprom->reg_chip_select = reg & RTL819X_EEPROM_CMD_CS; +} + +static void rtl819x_eeprom_register_write(struct eeprom_93cx6 *eeprom) +{ + struct net_device *dev = eeprom->data; + u8 reg = 2 << 6; + + if (eeprom->reg_data_in) + reg |= RTL819X_EEPROM_CMD_WRITE; + if (eeprom->reg_data_out) + reg |= RTL819X_EEPROM_CMD_READ; + if (eeprom->reg_data_clock) + reg |= RTL819X_EEPROM_CMD_CK; + if (eeprom->reg_chip_select) + reg |= RTL819X_EEPROM_CMD_CS; + + write_nic_byte(dev, EPROM_CMD, reg); + read_nic_byte(dev, EPROM_CMD); + udelay(10); +} + static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv) { int i, max_chan=-1, min_chan=-1; @@ -1152,15 +1182,6 @@ void tx_timeout(struct net_device *dev) //DMESG("TXTIMEOUT"); } - -/* this is only for debug */ -void dump_eprom(struct net_device *dev) -{ - int i; - for(i=0; i<63; i++) - RT_TRACE(COMP_EPROM, "EEPROM addr %x : %x", i, eprom_read(dev,i)); -} - /* this is only for debug */ void rtl8192_dump_reg(struct net_device *dev) { @@ -3531,26 +3552,32 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev) // // Created by Roger, 2008.10.21. // -void -rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev) +void rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev) { - struct r8192_priv *priv = ieee80211_priv(dev); - u16 i,usValue; - u8 tmpU1b, tempval; - u16 EEPROMId; - u8 hwinfo[HWSET_MAX_SIZE_92S]; - u8 rf_path, index; // For EEPROM/EFUSE After V0.6_1117 - + struct r8192_priv *priv = ieee80211_priv(dev); + u16 i; + u8 tmpU1b, tempval; + u16 EEPROMId; + u8 hwinfo[HWSET_MAX_SIZE_92S]; + u8 rf_path, index; // For EEPROM/EFUSE After V0.6_1117 + struct eeprom_93cx6 eeprom; + u16 eeprom_val; + + eeprom.data = dev; + eeprom.register_read = rtl819x_eeprom_register_read; + eeprom.register_write = rtl819x_eeprom_register_write; + if (priv->epromtype == EPROM_93c46) + eeprom.width = PCI_EEPROM_WIDTH_93C46; + else + eeprom.width = PCI_EEPROM_WIDTH_93C56; RT_TRACE(COMP_INIT, "====> ReadAdapterInfo8192SUsb\n"); - // - // The following operation are prevent Efuse leakage by turn on 2.5V. - // 2008.11.25. - // + /* + * The following operation are prevent Efuse leakage by turn on 2.5V.. + */ tmpU1b = read_nic_byte(dev, EFUSE_TEST+3); write_nic_byte(dev, EFUSE_TEST+3, tmpU1b|0x80); - //PlatformStallExecution(1000); mdelay(10); write_nic_byte(dev, EFUSE_TEST+3, (tmpU1b&(~BIT7))); @@ -3558,21 +3585,20 @@ rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev) priv->card_8192_version = (VERSION_8192S)((read_nic_dword(dev, PMC_FSM)>>16)&0xF); RT_TRACE(COMP_INIT, "Chip Version ID: 0x%2x\n", priv->card_8192_version); - switch(priv->card_8192_version) - { - case 0: - RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_ACUT.\n"); - break; - case 1: - RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_BCUT.\n"); - break; - case 2: - RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_CCUT.\n"); - break; - default: - RT_TRACE(COMP_INIT, "Unknown Chip Version!!\n"); - priv->card_8192_version = VERSION_8192S_BCUT; - break; + switch (priv->card_8192_version) { + case 0: + RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_ACUT.\n"); + break; + case 1: + RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_BCUT.\n"); + break; + case 2: + RT_TRACE(COMP_INIT, "Chip Version ID: VERSION_8192S_CCUT.\n"); + break; + default: + RT_TRACE(COMP_INIT, "Unknown Chip Version!!\n"); + priv->card_8192_version = VERSION_8192S_BCUT; + break; } //if (IS_BOOT_FROM_EEPROM(Adapter)) @@ -3585,8 +3611,8 @@ rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev) // Read all Content from EEPROM or EFUSE. for(i = 0; i < HWSET_MAX_SIZE_92S; i += 2) { - usValue = eprom_read(dev, (u16) (i>>1)); - *((u16*)(&hwinfo[i])) = usValue; + eeprom_93cx6_read(&eeprom, (u16) (i>>1), &eeprom_val); + *((u16 *)(&hwinfo[i])) = eeprom_val; } } else if (!(priv->EepromOrEfuse)) @@ -4138,11 +4164,6 @@ short rtl8192_init(struct net_device *dev) init_timer(&priv->watch_dog_timer); priv->watch_dog_timer.data = (unsigned long)dev; priv->watch_dog_timer.function = watch_dog_timer_callback; - - //rtl8192_adapter_start(dev); -#ifdef DEBUG_EPROM - dump_eprom(dev); -#endif return 0; } -- cgit v1.2.3 From 4ab372408208b7c92e986b1a283072c43b17bde5 Mon Sep 17 00:00:00 2001 From: Florian Schilhabel Date: Sat, 6 Mar 2010 20:44:54 +0100 Subject: staging: rtl8192su: remove re-declaration of counter i variable i is declared integer in rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail. a few lines down it is re-declared u8. removed the re-declaration. plus cosmetics Signed-off-by: Florian Schilhabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192su/r8192U_core.c | 91 +++++++++++++++------------------ 1 file changed, 42 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index 791cd51cfdd0..6a87a43dfc5e 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c @@ -3427,34 +3427,28 @@ void update_hal_variables(struct r8192_priv *priv) } } -// -// Description: -// Config HW adapter information into initial value. -// -// Assumption: -// 1. After Auto load fail(i.e, check CR9346 fail) -// -// Created by Roger, 2008.10.21. -// -void -rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev) +/* + * Description: + * Config HW adapter information into initial value. + * + * Assumption: + * 1. After Auto load fail(i.e, check CR9346 fail) + * + */ +void rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device *dev) { - struct r8192_priv *priv = ieee80211_priv(dev); - //u16 i,usValue; - //u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00}; - u8 rf_path; // For EEPROM/EFUSE After V0.6_1117 - int i; + struct r8192_priv *priv = ieee80211_priv(dev); + u8 rf_path; /* For EEPROM/EFUSE After V0.6_1117 */ + int i; RT_TRACE(COMP_INIT, "====> ConfigAdapterInfo8192SForAutoLoadFail\n"); - write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader - //PlatformStallExecution(10000); + /* Isolation signals from Loader */ + write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8); mdelay(10); - write_nic_byte(dev, PMC_FSM, 0x02); // Enable Loader Data Keep - - //RT_ASSERT(priv->AutoloadFailFlag==TRUE, ("ReadAdapterInfo8192SEEPROM(): AutoloadFailFlag !=TRUE\n")); + write_nic_byte(dev, PMC_FSM, 0x02); /* Enable Loader Data Keep */ - // Initialize IC Version && Channel Plan + /* Initialize IC Version && Channel Plan */ priv->eeprom_vid = 0; priv->eeprom_pid = 0; priv->card_8192_version = 0; @@ -3465,12 +3459,14 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev) RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid); RT_TRACE(COMP_INIT, "EEPROM PID = 0x%4x\n", priv->eeprom_pid); - RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID); - RT_TRACE(COMP_INIT, "EEPROM SubCustomer ID: 0x%2x\n", priv->eeprom_SubCustomerID); - RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n", priv->eeprom_ChannelPlan); - RT_TRACE(COMP_INIT, "IgnoreDiffRateTxPowerOffset = %d\n", priv->bIgnoreDiffRateTxPowerOffset); - - + RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n", + priv->eeprom_CustomerID); + RT_TRACE(COMP_INIT, "EEPROM SubCustomer ID: 0x%2x\n", + priv->eeprom_SubCustomerID); + RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n", + priv->eeprom_ChannelPlan); + RT_TRACE(COMP_INIT, "IgnoreDiffRateTxPowerOffset = %d\n", + priv->bIgnoreDiffRateTxPowerOffset); priv->EEPROMUsbOption = EEPROM_USB_Default_OPTIONAL_FUNC; RT_TRACE(COMP_INIT, "USB Option = %#x\n", priv->EEPROMUsbOption); @@ -3478,19 +3474,15 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev) for(i=0; i<5; i++) priv->EEPROMUsbPhyParam[i] = EEPROM_USB_Default_PHY_PARAM; - //RT_PRINT_DATA(COMP_INIT|COMP_EFUSE, DBG_LOUD, ("EFUSE USB PHY Param: \n"), priv->EEPROMUsbPhyParam, 5); - { - // In this case, we random assigh MAC address here. 2008.10.15. + /* + * In this case, we randomly assign a MAC address here. + */ static u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00}; - u8 i; - - //sMacAddr[5] = (u8)GetRandomNumber(1, 254); - for(i = 0; i < 6; i++) dev->dev_addr[i] = sMacAddr[i]; } - //NicIFSetMacAddress(Adapter, Adapter->PermanentAddress); + /* NicIFSetMacAddress(Adapter, Adapter->PermanentAddress); */ write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]); write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]); @@ -3499,7 +3491,7 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev) dev->dev_addr); priv->EEPROMBoardType = EEPROM_Default_BoardType; - priv->rf_type = RF_1T2R; //RF_2T2R + priv->rf_type = RF_1T2R; /* RF_2T2R */ priv->EEPROMTxPowerDiff = EEPROM_Default_PwDiff; priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter; priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap; @@ -3508,13 +3500,11 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev) priv->EEPROMTSSI_B = EEPROM_Default_TSSI; priv->EEPROMTxPwrTkMode = EEPROM_Default_TxPwrTkMode; - - for (rf_path = 0; rf_path < 2; rf_path++) { for (i = 0; i < 3; i++) { - // Read CCK RF A & B Tx power + /* Read CCK RF A & B Tx power */ priv->RfCckChnlAreaTxPwr[rf_path][i] = priv->RfOfdmChnlAreaTxPwr1T[rf_path][i] = priv->RfOfdmChnlAreaTxPwr2T[rf_path][i] = @@ -3524,22 +3514,25 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev) update_hal_variables(priv); - // - // Update remained HAL variables. - // + /* + * Update remaining HAL variables. + */ priv->TSSI_13dBm = priv->EEPROMThermalMeter *100; - priv->LegacyHTTxPowerDiff = priv->EEPROMTxPowerDiff;//new + priv->LegacyHTTxPowerDiff = priv->EEPROMTxPowerDiff; /* new */ priv->TxPowerDiff = priv->EEPROMTxPowerDiff; - //priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);// Antenna B gain offset to antenna A, bit0~3 - //priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);// Antenna C gain offset to antenna A, bit4~7 - priv->CrystalCap = priv->EEPROMCrystalCap; // CrystalCap, bit12~15 - priv->ThermalMeter[0] = priv->EEPROMThermalMeter;// ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2 + /* Antenna B gain offset to antenna A, bit0~3 */ + /* priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf); */ + /* Antenna C gain offset to antenna A, bit4~7 */ + /* priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4); */ + /* CrystalCap, bit12~15 */ + priv->CrystalCap = priv->EEPROMCrystalCap; + /* ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2 */ + priv->ThermalMeter[0] = priv->EEPROMThermalMeter; priv->LedStrategy = SW_LED_MODE0; init_rate_adaptive(dev); RT_TRACE(COMP_INIT, "<==== ConfigAdapterInfo8192SForAutoLoadFail\n"); - } // -- cgit v1.2.3 From 458659e2ada5c21aedae2b647588150ee90177b0 Mon Sep 17 00:00:00 2001 From: Florian Schilhabel Date: Sat, 6 Mar 2010 20:45:11 +0100 Subject: staging: rtl8192su: remove extern keyword, remove static declaration removed extern keyword from rtl819x_watchdog_wqcallback. removed static declaration from variable check_reset_cnt. changed NumRxOkInPeriod and NumTxOkInPeriod comparison in function rtl819x_watchdog_wqcallback to 666; we're not on windows. plus cosmetics. Signed-off-by: Florian Schilhabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192su/r8192U_core.c | 126 +++++++++++++++++--------------- 1 file changed, 67 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index 6a87a43dfc5e..7fe1cedb3e9a 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c @@ -5524,85 +5524,93 @@ void rtl819x_update_rxcounts( } } -extern void rtl819x_watchdog_wqcallback(struct work_struct *work) -{ - struct delayed_work *dwork = container_of(work,struct delayed_work,work); - struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq); - struct net_device *dev = priv->ieee80211->dev; +void rtl819x_watchdog_wqcallback(struct work_struct *work) +{ + struct delayed_work *dwork = container_of(work, + struct delayed_work, + work); + struct r8192_priv *priv = container_of(dwork, + struct r8192_priv, + watch_dog_wq); + struct net_device *dev = priv->ieee80211->dev; struct ieee80211_device* ieee = priv->ieee80211; - RESET_TYPE ResetType = RESET_TYPE_NORESET; - static u8 check_reset_cnt=0; + RESET_TYPE ResetType = RESET_TYPE_NORESET; + u8 check_reset_cnt = 0; bool bBusyTraffic = false; if(!priv->up) return; hal_dm_watchdog(dev); - {//to get busy traffic condition - if(ieee->state == IEEE80211_LINKED) - { - //windows mod 666 to 100. - //if( ieee->LinkDetectInfo.NumRxOkInPeriod> 666 || - // ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) { - if( ieee->LinkDetectInfo.NumRxOkInPeriod> 100 || - ieee->LinkDetectInfo.NumTxOkInPeriod> 100 ) { + /* to get busy traffic condition */ + if (ieee->state == IEEE80211_LINKED) { + if (ieee->LinkDetectInfo.NumRxOkInPeriod > 666 || + ieee->LinkDetectInfo.NumTxOkInPeriod > 666) bBusyTraffic = true; - } - ieee->LinkDetectInfo.NumRxOkInPeriod = 0; - ieee->LinkDetectInfo.NumTxOkInPeriod = 0; - ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic; - } - } - //added by amy for AP roaming - { - if(priv->ieee80211->state == IEEE80211_LINKED && priv->ieee80211->iw_mode == IW_MODE_INFRA) - { - u32 TotalRxBcnNum = 0; - u32 TotalRxDataNum = 0; - rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum); - if((TotalRxBcnNum+TotalRxDataNum) == 0) - { - #ifdef TODO - if(rfState == eRfOff) - RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__); - #endif - printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__); - // Dot11d_Reset(dev); - priv->ieee80211->state = IEEE80211_ASSOCIATING; - notify_wx_assoc_event(priv->ieee80211); - RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid); - ieee->is_roaming = true; - priv->ieee80211->link_change(dev); - queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq); - } + ieee->LinkDetectInfo.NumRxOkInPeriod = 0; + ieee->LinkDetectInfo.NumTxOkInPeriod = 0; + ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic; + } + + if (priv->ieee80211->state == IEEE80211_LINKED && + priv->ieee80211->iw_mode == IW_MODE_INFRA) { + u32 TotalRxBcnNum = 0; + u32 TotalRxDataNum = 0; + rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum); + if ((TotalRxBcnNum + TotalRxDataNum) == 0) { + #ifdef TODO + if (rfState == eRfOff) + RT_TRACE(COMP_ERR, "========>%s()\n", + __func__); + #endif + RT_TRACE(COMP_ERR, "=>%s(): AP is power off," + "connect another one\n", __func__); + /* Dot11d_Reset(dev); */ + priv->ieee80211->state = IEEE80211_ASSOCIATING; + notify_wx_assoc_event(priv->ieee80211); + RemovePeerTS(priv->ieee80211, + priv->ieee80211->current_network.bssid); + + ieee->is_roaming = true; + priv->ieee80211->link_change(dev); + queue_work(priv->ieee80211->wq, + &priv->ieee80211->associate_procedure_wq); } - priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod=0; - priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod=0; } -// CAM_read_entry(dev,4); - //check if reset the driver - if(check_reset_cnt++ >= 3 && !ieee->is_roaming) - { - ResetType = rtl819x_ifcheck_resetornot(dev); + priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod = 0; + priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod = 0; + + /* + * CAM_read_entry(dev,4); + * check if reset the driver + */ + if (check_reset_cnt++ >= 3 && !ieee->is_roaming) { + ResetType = rtl819x_ifcheck_resetornot(dev); check_reset_cnt = 3; - //DbgPrint("Start to check silent reset\n"); } - // RT_TRACE(COMP_RESET,"%s():priv->force_reset is %d,priv->ResetProgress is %d, priv->bForcedSilentReset is %d,priv->bDisableNormalResetCheck is %d,ResetType is %d\n",__FUNCTION__,priv->force_reset,priv->ResetProgress,priv->bForcedSilentReset,priv->bDisableNormalResetCheck,ResetType); -#if 1 - if( (priv->force_reset) || (priv->ResetProgress==RESET_TYPE_NORESET && + if ((priv->force_reset) || (priv->ResetProgress == RESET_TYPE_NORESET && (priv->bForcedSilentReset || - (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT)))) // This is control by OID set in Pomelo - { - RT_TRACE(COMP_RESET,"%s():priv->force_reset is %d,priv->ResetProgress is %d, priv->bForcedSilentReset is %d,priv->bDisableNormalResetCheck is %d,ResetType is %d\n",__FUNCTION__,priv->force_reset,priv->ResetProgress,priv->bForcedSilentReset,priv->bDisableNormalResetCheck,ResetType); + (!priv->bDisableNormalResetCheck && + /* This is control by OID set in Pomelo */ + ResetType == RESET_TYPE_SILENT)))) { + RT_TRACE(COMP_RESET, "%s():priv->force_reset is %d," + "priv->ResetProgress is %d, " + "priv->bForcedSilentReset is %d, " + "priv->bDisableNormalResetCheck is %d, " + "ResetType is %d\n", + __func__, + priv->force_reset, + priv->ResetProgress, + priv->bForcedSilentReset, + priv->bDisableNormalResetCheck, + ResetType); rtl819x_ifsilentreset(dev); } -#endif priv->force_reset = false; priv->bForcedSilentReset = false; priv->bResetInProgress = false; RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n"); - } void watch_dog_timer_callback(unsigned long data) -- cgit v1.2.3 From 8dba599d89711b4f731fcc1d135de5ffd69eb360 Mon Sep 17 00:00:00 2001 From: Florian Schilhabel Date: Sat, 6 Mar 2010 20:45:25 +0100 Subject: staging: rtl8192su: cleanup of r819xU_cmdpkt.c, r819xU_cmdpkt.c Signed-off-by: Florian Schilhabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192su/r819xU_cmdpkt.c | 658 ++++++++++-------------------- drivers/staging/rtl8192su/r819xU_cmdpkt.h | 366 ++++++++--------- 2 files changed, 399 insertions(+), 625 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192su/r819xU_cmdpkt.c b/drivers/staging/rtl8192su/r819xU_cmdpkt.c index 3ebfe79bb663..9b377bae47b4 100644 --- a/drivers/staging/rtl8192su/r819xU_cmdpkt.c +++ b/drivers/staging/rtl8192su/r819xU_cmdpkt.c @@ -1,384 +1,250 @@ -/****************************************************************************** - - (c) Copyright 2008, RealTEK Technologies Inc. All Rights Reserved. - - Module: r819xusb_cmdpkt.c (RTL8190 TX/RX command packet handler Source C File) - - Note: The module is responsible for handling TX and RX command packet. - 1. TX : Send set and query configuration command packet. - 2. RX : Receive tx feedback, beacon state, query configuration - command packet. - - Function: - - Export: - - Abbrev: - - History: - Data Who Remark - - 05/06/2008 amy Create initial version porting from windows driver. - -******************************************************************************/ +/* + * (c) Copyright 2008, RealTEK Technologies Inc. All Rights Reserved. + * + * Module: r819xusb_cmdpkt.c + * (RTL8190 TX/RX command packet handler Source C File) + * + * Note: The module is responsible for handling TX and RX command packet. + * 1.TX: Send set and query configuration command packet. + * 2.RX: Receive tx feedback, beacon state, query configuration, command packet. + */ #include "r8192U.h" #include "r819xU_cmdpkt.h" -/*---------------------------Define Local Constant---------------------------*/ -/* Debug constant*/ -#define CMPK_DEBOUNCE_CNT 1 -/* 2007/10/24 MH Add for printing a range of data. */ -#define CMPK_PRINT(Address)\ -{\ - unsigned char i;\ - u32 temp[10];\ - \ - memcpy(temp, Address, 40);\ - for (i = 0; i <40; i+=4)\ - printk("\r\n %08x", temp[i]);\ -}\ -/*---------------------------Define functions---------------------------------*/ - -bool -SendTxCommandPacket( - struct net_device *dev, - void* pData, - u32 DataLen - ) + +bool SendTxCommandPacket(struct net_device *dev, void *pData, u32 DataLen) { bool rtStatus = true; struct r8192_priv *priv = ieee80211_priv(dev); struct sk_buff *skb; cb_desc *tcb_desc; unsigned char *ptr_buf; - //bool bLastInitPacket = false; - //PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); + /* PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK); */ - //Get TCB and local buffer from common pool. (It is shared by CmdQ, MgntQ, and USB coalesce DataQ) + /* + * Get TCB and local buffer from common pool. + * (It is shared by CmdQ, MgntQ, and USB coalesce DataQ) + */ skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + DataLen + 4); - memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev)); - tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE); + memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); + tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); tcb_desc->queue_index = TXCMD_QUEUE; tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_NORMAL; tcb_desc->bLastIniPkt = 0; skb_reserve(skb, USB_HWDESC_HEADER_LEN); ptr_buf = skb_put(skb, DataLen); - memset(ptr_buf,0,DataLen); - memcpy(ptr_buf,pData,DataLen); - tcb_desc->txbuf_size= (u16)DataLen; - - if(!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index)|| - (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index]))||\ - (priv->ieee80211->queue_stop) ) { - RT_TRACE(COMP_FIRMWARE,"===================NULL packet==================================> tx full!\n"); + memset(ptr_buf, 0, DataLen); + memcpy(ptr_buf, pData, DataLen); + tcb_desc->txbuf_size = (u16)DataLen; + + if (!priv->ieee80211->check_nic_enough_desc(dev, tcb_desc->queue_index) || + (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index])) || + (priv->ieee80211->queue_stop)) { + RT_TRACE(COMP_FIRMWARE, "NULL packet => tx full\n"); skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb); } else { - priv->ieee80211->softmac_hard_start_xmit(skb,dev); + priv->ieee80211->softmac_hard_start_xmit(skb, dev); } //PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK); return rtStatus; } -/*----------------------------------------------------------------------------- +/* * Function: cmpk_message_handle_tx() * * Overview: Driver internal module can call the API to send message to - * firmware side. For example, you can send a debug command packet. - * Or you can send a request for FW to modify RLX4181 LBUS HW bank. - * Otherwise, you can change MAC/PHT/RF register by firmware at - * run time. We do not support message more than one segment now. + * firmware side. For example, you can send a debug command packet. + * Or you can send a request for FW to modify RLX4181 LBUS HW bank. + * Otherwise, you can change MAC/PHT/RF register by firmware at + * run time. We do not support message more than one segment now. * * Input: NONE * * Output: NONE * * Return: NONE - * - * Revised History: - * When Who Remark - * 05/06/2008 amy porting from windows code. - * - *---------------------------------------------------------------------------*/ + */ extern bool cmpk_message_handle_tx( struct net_device *dev, - u8* codevirtualaddress, + u8 *codevirtualaddress, u32 packettype, u32 buffer_len) { - - bool rt_status = true; + bool rt_status = true; return rt_status; -} /* CMPK_Message_Handle_Tx */ +} -/*----------------------------------------------------------------------------- - * Function: cmpk_counttxstatistic() - * - * Overview: - * - * Input: PADAPTER pAdapter - . - * CMPK_TXFB_T *psTx_FB - . - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 05/12/2008 amy Create Version 0 porting from windows code. - * - *---------------------------------------------------------------------------*/ +/* + * Function: cmpk_counttxstatistic() + */ static void -cmpk_count_txstatistic( - struct net_device *dev, - cmpk_txfb_t *pstx_fb) +cmpk_count_txstatistic(struct net_device *dev, cmpk_txfb_t *pstx_fb) { struct r8192_priv *priv = ieee80211_priv(dev); #ifdef ENABLE_PS - RT_RF_POWER_STATE rtState; + RT_RF_POWER_STATE rtState; - pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState)); + pAdapter->HalFunc.GetHwRegHandler(pAdapter, + HW_VAR_RF_STATE, + (pu1Byte)(&rtState)); - // When RF is off, we should not count the packet for hw/sw synchronize - // reason, ie. there may be a duration while sw switch is changed and hw - // switch is being changed. 2006.12.04, by shien chang. + /* + * When RF is off, we should not count the packet for hw/sw synchronize + * reason, ie. there may be a duration while sw switch is changed and hw + * switch is being changed. + */ if (rtState == eRfOff) - { return; - } #endif #ifdef TODO - if(pAdapter->bInHctTest) + if (pAdapter->bInHctTest) return; #endif - /* We can not know the packet length and transmit type: broadcast or uni - or multicast. So the relative statistics must be collected in tx - feedback info. */ - if (pstx_fb->tok) - { + /* + * We can not know the packet length and transmit type: + * broadcast or uni or multicast. + * So the relative statistics must be collected in tx feedback info + */ + if (pstx_fb->tok) { priv->stats.txfeedbackok++; priv->stats.txoktotal++; priv->stats.txokbytestotal += pstx_fb->pkt_length; priv->stats.txokinperiod++; - /* We can not make sure broadcast/multicast or unicast mode. */ - if (pstx_fb->pkt_type == PACKET_MULTICAST) - { + if (pstx_fb->pkt_type == PACKET_MULTICAST) { priv->stats.txmulticast++; priv->stats.txbytesmulticast += pstx_fb->pkt_length; - } - else if (pstx_fb->pkt_type == PACKET_BROADCAST) - { + } else if (pstx_fb->pkt_type == PACKET_BROADCAST) { priv->stats.txbroadcast++; priv->stats.txbytesbroadcast += pstx_fb->pkt_length; - } - else - { + } else { priv->stats.txunicast++; priv->stats.txbytesunicast += pstx_fb->pkt_length; } - } - else - { + } else { priv->stats.txfeedbackfail++; priv->stats.txerrtotal++; priv->stats.txerrbytestotal += pstx_fb->pkt_length; - /* We can not make sure broadcast/multicast or unicast mode. */ if (pstx_fb->pkt_type == PACKET_MULTICAST) - { priv->stats.txerrmulticast++; - } else if (pstx_fb->pkt_type == PACKET_BROADCAST) - { priv->stats.txerrbroadcast++; - } else - { priv->stats.txerrunicast++; - } } - priv->stats.txretrycount += pstx_fb->retry_cnt; priv->stats.txfeedbackretry += pstx_fb->retry_cnt; +} -} /* cmpk_CountTxStatistic */ - - - -/*----------------------------------------------------------------------------- +/* * Function: cmpk_handle_tx_feedback() * * Overview: The function is responsible for extract the message inside TX - * feedbck message from firmware. It will contain dedicated info in - * ws-06-0063-rtl8190-command-packet-specification. Please - * refer to chapter "TX Feedback Element". We have to read 20 bytes - * in the command packet. + * feedbck message from firmware. It will contain dedicated info in + * ws-06-0063-rtl8190-command-packet-specification. Please + * refer to chapter "TX Feedback Element". We have to read 20 bytes + * in the command packet. * * Input: struct net_device * dev - * u8 * pmsg - Msg Ptr of the command packet. + * u8 *pmsg - Msg Ptr of the command packet. * * Output: NONE * * Return: NONE - * - * Revised History: - * When Who Remark - * 05/08/2008 amy Create Version 0 porting from windows code. - * - *---------------------------------------------------------------------------*/ -static void -cmpk_handle_tx_feedback( - struct net_device *dev, - u8 * pmsg) + */ +static void cmpk_handle_tx_feedback(struct net_device *dev, u8 *pmsg) { struct r8192_priv *priv = ieee80211_priv(dev); - cmpk_txfb_t rx_tx_fb; /* */ + cmpk_txfb_t rx_tx_fb; priv->stats.txfeedback++; - /* 0. Display received message. */ - //cmpk_Display_Message(CMPK_RX_TX_FB_SIZE, pMsg); - /* 1. Extract TX feedback info from RFD to temp structure buffer. */ + memcpy((u8 *)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t)); - /* 2007/07/05 MH Use pointer to transfer structure memory. */ - //memcpy((UINT8 *)&rx_tx_fb, pMsg, sizeof(CMPK_TXFB_T)); - memcpy((u8*)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t)); /* 2. Use tx feedback info to count TX statistics. */ cmpk_count_txstatistic(dev, &rx_tx_fb); +} - /* 2007/01/17 MH Comment previous method for TX statistic function. */ - /* Collect info TX feedback packet to fill TCB. */ - /* We can not know the packet length and transmit type: broadcast or uni - or multicast. */ - //CountTxStatistics( pAdapter, &tcb ); - -} /* cmpk_Handle_Tx_Feedback */ - -void -cmdpkt_beacontimerinterrupt_819xusb( - struct net_device *dev -) +void cmdpkt_beacontimerinterrupt_819xusb(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); u16 tx_rate; - { - // - // 070117, rcnjko: 87B have to S/W beacon for DTM encryption_cmn. - // - if(priv->ieee80211->current_network.mode == IEEE_A || - priv->ieee80211->current_network.mode == IEEE_N_5G || - (priv->ieee80211->current_network.mode == IEEE_N_24G && (!priv->ieee80211->pHTInfo->bCurSuppCCK))) - { - tx_rate = 60; - DMESG("send beacon frame tx rate is 6Mbpm\n"); - } - else - { - tx_rate =10; - DMESG("send beacon frame tx rate is 1Mbpm\n"); - } - - rtl819xusb_beacon_tx(dev,tx_rate); // HW Beacon + if (priv->ieee80211->current_network.mode == IEEE_A || + priv->ieee80211->current_network.mode == IEEE_N_5G || + (priv->ieee80211->current_network.mode == IEEE_N_24G && + (!priv->ieee80211->pHTInfo->bCurSuppCCK))) { + tx_rate = 60; + DMESG("send beacon frame tx rate is 6Mbpm\n"); + } else { + tx_rate = 10; + DMESG("send beacon frame tx rate is 1Mbpm\n"); } - + rtl819xusb_beacon_tx(dev, tx_rate); /* HW Beacon */ } - - - -/*----------------------------------------------------------------------------- +/* * Function: cmpk_handle_interrupt_status() * * Overview: The function is responsible for extract the message from - * firmware. It will contain dedicated info in - * ws-07-0063-v06-rtl819x-command-packet-specification-070315.doc. - * Please refer to chapter "Interrupt Status Element". + * firmware. It will contain dedicated info in + * ws-07-0063-v06-rtl819x-command-packet-specification-070315.doc. + * Please refer to chapter "Interrupt Status Element". * * Input: struct net_device *dev, - * u8* pmsg - Message Pointer of the command packet. + * u8* pmsg - Message Pointer of the command packet. * * Output: NONE * * Return: NONE - * - * Revised History: - * When Who Remark - * 05/12/2008 amy Add this for rtl8192 porting from windows code. - * - *---------------------------------------------------------------------------*/ -static void -cmpk_handle_interrupt_status( - struct net_device *dev, - u8* pmsg) + */ +static void cmpk_handle_interrupt_status(struct net_device *dev, u8 *pmsg) { cmpk_intr_sta_t rx_intr_status; /* */ struct r8192_priv *priv = ieee80211_priv(dev); DMESG("---> cmpk_Handle_Interrupt_Status()\n"); - /* 0. Display received message. */ - //cmpk_Display_Message(CMPK_RX_BEACON_STATE_SIZE, pMsg); - /* 1. Extract TX feedback info from RFD to temp structure buffer. */ - /* It seems that FW use big endian(MIPS) and DRV use little endian in - windows OS. So we have to read the content byte by byte or transfer - endian type before copy the message copy. */ - //rx_bcn_state.Element_ID = pMsg[0]; - //rx_bcn_state.Length = pMsg[1]; rx_intr_status.length = pmsg[1]; - if (rx_intr_status.length != (sizeof(cmpk_intr_sta_t) - 2)) - { + if (rx_intr_status.length != (sizeof(cmpk_intr_sta_t) - 2)) { DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n"); return; } - - - // Statistics of beacon for ad-hoc mode. - if( priv->ieee80211->iw_mode == IW_MODE_ADHOC) - { + /* Statistics of beacon for ad-hoc mode. */ + if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) { //2 maybe need endian transform? rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4)); //rx_intr_status.InterruptStatus = N2H4BYTE(*((UINT32 *)(pMsg + 4))); DMESG("interrupt status = 0x%x\n", rx_intr_status.interrupt_status); - if (rx_intr_status.interrupt_status & ISR_TxBcnOk) - { + if (rx_intr_status.interrupt_status & ISR_TxBcnOk) { priv->ieee80211->bibsscoordinator = true; priv->stats.txbeaconokint++; - } - else if (rx_intr_status.interrupt_status & ISR_TxBcnErr) - { + } else if (rx_intr_status.interrupt_status & ISR_TxBcnErr) { priv->ieee80211->bibsscoordinator = false; priv->stats.txbeaconerr++; } if (rx_intr_status.interrupt_status & ISR_BcnTimerIntr) - { cmdpkt_beacontimerinterrupt_819xusb(dev); - } - } - - // Other informations in interrupt status we need? - - + /* Other informations in interrupt status we need? */ DMESG("<---- cmpk_handle_interrupt_status()\n"); +} -} /* cmpk_handle_interrupt_status */ - - -/*----------------------------------------------------------------------------- +/* * Function: cmpk_handle_query_config_rx() * * Overview: The function is responsible for extract the message from * firmware. It will contain dedicated info in - * ws-06-0063-rtl8190-command-packet-specification. Please - * refer to chapter "Beacon State Element". + * ws-06-0063-rtl8190-command-packet-specification + * Please refer to chapter "Beacon State Element". * * Input: u8 * pmsg - Message Pointer of the command packet. * @@ -386,44 +252,28 @@ cmpk_handle_interrupt_status( * * Return: NONE * - * Revised History: - * When Who Remark - * 05/12/2008 amy Create Version 0 porting from windows code. - * - *---------------------------------------------------------------------------*/ -static void -cmpk_handle_query_config_rx( - struct net_device *dev, - u8* pmsg) + */ +static void cmpk_handle_query_config_rx(struct net_device *dev, u8 *pmsg) { - cmpk_query_cfg_t rx_query_cfg; /* */ - - /* 0. Display received message. */ - //cmpk_Display_Message(CMPK_RX_BEACON_STATE_SIZE, pMsg); + cmpk_query_cfg_t rx_query_cfg; + /* + * Extract TX feedback info from RFD to temp structure buffer. + */ + rx_query_cfg.cfg_action = (pmsg[4] & 0x80000000) >> 31; + rx_query_cfg.cfg_type = (pmsg[4] & 0x60) >> 5; + rx_query_cfg.cfg_size = (pmsg[4] & 0x18) >> 3; + rx_query_cfg.cfg_page = (pmsg[6] & 0x0F) >> 0; + rx_query_cfg.cfg_offset = pmsg[7]; + rx_query_cfg.value = (pmsg[8] << 24) | (pmsg[9] << 16) | + (pmsg[10] << 8) | (pmsg[11] << 0); + rx_query_cfg.mask = (pmsg[12] << 24) | (pmsg[13] << 16) | + (pmsg[14] << 8) | (pmsg[15] << 0); +} - /* 1. Extract TX feedback info from RFD to temp structure buffer. */ - /* It seems that FW use big endian(MIPS) and DRV use little endian in - windows OS. So we have to read the content byte by byte or transfer - endian type before copy the message copy. */ - //rx_query_cfg.Element_ID = pMsg[0]; - //rx_query_cfg.Length = pMsg[1]; - rx_query_cfg.cfg_action = (pmsg[4] & 0x80000000)>>31; - rx_query_cfg.cfg_type = (pmsg[4] & 0x60) >> 5; - rx_query_cfg.cfg_size = (pmsg[4] & 0x18) >> 3; - rx_query_cfg.cfg_page = (pmsg[6] & 0x0F) >> 0; - rx_query_cfg.cfg_offset = pmsg[7]; - rx_query_cfg.value = (pmsg[8] << 24) | (pmsg[9] << 16) | - (pmsg[10] << 8) | (pmsg[11] << 0); - rx_query_cfg.mask = (pmsg[12] << 24) | (pmsg[13] << 16) | - (pmsg[14] << 8) | (pmsg[15] << 0); - -} /* cmpk_Handle_Query_Config_Rx */ - - -/*----------------------------------------------------------------------------- +/* * Function: cmpk_count_tx_status() * - * Overview: Count aggregated tx status from firmwar of one type rx command + * Overview: Count aggregated tx status from firmware of one type rx command * packet element id = RX_TX_STATUS. * * Input: NONE @@ -431,14 +281,9 @@ cmpk_handle_query_config_rx( * Output: NONE * * Return: NONE - * - * Revised History: - * When Who Remark - * 05/12/2008 amy Create Version 0 porting from windows code. - * - *---------------------------------------------------------------------------*/ -static void cmpk_count_tx_status( struct net_device *dev, - cmpk_tx_status_t *pstx_status) + */ +static void cmpk_count_tx_status(struct net_device *dev, + cmpk_tx_status_t *pstx_status) { struct r8192_priv *priv = ieee80211_priv(dev); @@ -448,13 +293,13 @@ static void cmpk_count_tx_status( struct net_device *dev, pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState)); - // When RF is off, we should not count the packet for hw/sw synchronize - // reason, ie. there may be a duration while sw switch is changed and hw - // switch is being changed. 2006.12.04, by shien chang. + /* + * When RF is off, we should not count the packet for hw/sw synchronize + * reason, ie. there may be a duration while sw switch is changed and hw + * switch is being changed. + */ if (rtState == eRfOff) - { return; - } #endif priv->stats.txfeedbackok += pstx_status->txok; @@ -463,15 +308,11 @@ static void cmpk_count_tx_status( struct net_device *dev, priv->stats.txfeedbackfail += pstx_status->txfail; priv->stats.txerrtotal += pstx_status->txfail; - priv->stats.txretrycount += pstx_status->txretry; + priv->stats.txretrycount += pstx_status->txretry; priv->stats.txfeedbackretry += pstx_status->txretry; - //pAdapter->TxStats.NumTxOkBytesTotal += psTx_FB->pkt_length; - //pAdapter->TxStats.NumTxErrBytesTotal += psTx_FB->pkt_length; - //pAdapter->MgntInfo.LinkDetectInfo.NumTxOkInPeriod++; - - priv->stats.txmulticast += pstx_status->txmcok; - priv->stats.txbroadcast += pstx_status->txbcok; + priv->stats.txmulticast += pstx_status->txmcok; + priv->stats.txbroadcast += pstx_status->txbcok; priv->stats.txunicast += pstx_status->txucok; priv->stats.txerrmulticast += pstx_status->txmcfail; @@ -480,14 +321,12 @@ static void cmpk_count_tx_status( struct net_device *dev, priv->stats.txbytesmulticast += pstx_status->txmclength; priv->stats.txbytesbroadcast += pstx_status->txbclength; - priv->stats.txbytesunicast += pstx_status->txuclength; - - priv->stats.last_packet_rate = pstx_status->rate; -} /* cmpk_CountTxStatus */ - + priv->stats.txbytesunicast += pstx_status->txuclength; + priv->stats.last_packet_rate = pstx_status->rate; +} -/*----------------------------------------------------------------------------- +/* * Function: cmpk_handle_tx_status() * * Overview: Firmware add a new tx feedback status to reduce rx command @@ -498,27 +337,18 @@ static void cmpk_count_tx_status( struct net_device *dev, * Output: NONE * * Return: NONE - * - * Revised History: - * When Who Remark - * 05/12/2008 amy Create Version 0 porting from windows code. - * - *---------------------------------------------------------------------------*/ + */ static void -cmpk_handle_tx_status( - struct net_device *dev, - u8* pmsg) +cmpk_handle_tx_status(struct net_device *dev, u8 *pmsg) { - cmpk_tx_status_t rx_tx_sts; /* */ + cmpk_tx_status_t rx_tx_sts; - memcpy((void*)&rx_tx_sts, (void*)pmsg, sizeof(cmpk_tx_status_t)); + memcpy((void *)&rx_tx_sts, (void *)pmsg, sizeof(cmpk_tx_status_t)); /* 2. Use tx feedback info to count TX statistics. */ cmpk_count_tx_status(dev, &rx_tx_sts); +} -} /* cmpk_Handle_Tx_Status */ - - -/*----------------------------------------------------------------------------- +/* * Function: cmpk_handle_tx_rate_history() * * Overview: Firmware add a new tx rate history @@ -528,117 +358,90 @@ cmpk_handle_tx_status( * Output: NONE * * Return: NONE - * - * Revised History: - * When Who Remark - * 05/12/2008 amy Create Version 0 porting from windows code. - * - *---------------------------------------------------------------------------*/ -static void -cmpk_handle_tx_rate_history( - struct net_device *dev, - u8* pmsg) + */ +static void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg) { cmpk_tx_rahis_t *ptxrate; -// RT_RF_POWER_STATE rtState; - u8 i, j; - u16 length = sizeof(cmpk_tx_rahis_t); - u32 *ptemp; + u8 i, j; + u16 length = sizeof(cmpk_tx_rahis_t); + u32 *ptemp; struct r8192_priv *priv = ieee80211_priv(dev); - #ifdef ENABLE_PS - pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState)); - - // When RF is off, we should not count the packet for hw/sw synchronize - // reason, ie. there may be a duration while sw switch is changed and hw - // switch is being changed. 2006.12.04, by shien chang. + pAdapter->HalFunc.GetHwRegHandler(pAdapter, + HW_VAR_RF_STATE, + (pu1Byte)(&rtState)); + /* + * When RF is off, we should not count the packet for hw/sw synchronize + * reason, ie. there may be a duration while sw switch is changed and hw + * switch is being changed. + */ if (rtState == eRfOff) - { return; - } #endif - ptemp = (u32 *)pmsg; - // - // Do endian transfer to word alignment(16 bits) for windows system. - // You must do different endian transfer for linux and MAC OS - // - for (i = 0; i < (length/4); i++) - { - u16 temp1, temp2; - - temp1 = ptemp[i]&0x0000FFFF; - temp2 = ptemp[i]>>16; - ptemp[i] = (temp1<<16)|temp2; + /* + * Do endian transfer to word alignment(16 bits) for windows system. + * You must do different endian transfer for linux and MAC OS + */ + for (i = 0; i < (length/4); i++) { + u16 temp1, temp2; + temp1 = ptemp[i] & 0x0000FFFF; + temp2 = ptemp[i] >> 16; + ptemp[i] = (temp1 << 16) | temp2; } ptxrate = (cmpk_tx_rahis_t *)pmsg; - if (ptxrate == NULL ) - { + if (ptxrate == NULL) return; - } - for (i = 0; i < 16; i++) - { - // Collect CCK rate packet num + for (i = 0; i < 16; i++) { + /* Collect CCK rate packet num */ if (i < 4) priv->stats.txrate.cck[i] += ptxrate->cck[i]; - - // Collect OFDM rate packet num - if (i< 8) + /* Collect OFDM rate packet num */ + if (i < 8) priv->stats.txrate.ofdm[i] += ptxrate->ofdm[i]; - for (j = 0; j < 4; j++) priv->stats.txrate.ht_mcs[j][i] += ptxrate->ht_mcs[j][i]; } -} /* cmpk_Handle_Tx_Rate_History */ - +} -/*----------------------------------------------------------------------------- +/* * Function: cmpk_message_handle_rx() * * Overview: In the function, we will capture different RX command packet - * info. Every RX command packet element has different message - * length and meaning in content. We only support three type of RX - * command packet now. Please refer to document - * ws-06-0063-rtl8190-command-packet-specification. + * info. Every RX command packet element has different message + * length and meaning in content. We only support three type of RX + * command packet now. Please refer to document + * ws-06-0063-rtl8190-command-packet-specification. * * Input: NONE * * Output: NONE * * Return: NONE - * - * Revised History: - * When Who Remark - * 05/06/2008 amy Create Version 0 porting from windows code. - * - *---------------------------------------------------------------------------*/ + */ extern u32 cmpk_message_handle_rx( struct net_device *dev, struct ieee80211_rx_stats *pstats) { -// u32 debug_level = DBG_LOUD; struct r8192_priv *priv = ieee80211_priv(dev); int total_length; u8 cmd_length, exe_cnt = 0; u8 element_id; u8 *pcmd_buff; - /* 0. Check inpt arguments. If is is a command queue message or pointer is - null. */ - if (/*(prfd->queue_id != CMPK_RX_QUEUE_ID) || */(pstats== NULL)) - { - /* Print error message. */ - /*RT_TRACE(COMP_SEND, DebugLevel, - ("\n\r[CMPK]-->Err queue id or pointer"));*/ + /* + * 0. Check input arguments. + * If is is a command queue message or pointer is null + */ + if ((pstats == NULL)) return 0; /* This is not a command packet. */ - } /* 1. Read received command packet message length from RFD. */ total_length = pstats->Length; @@ -648,70 +451,49 @@ cmpk_message_handle_rx( /* 3. Read command pakcet element id and length. */ element_id = pcmd_buff[0]; - /*RT_TRACE(COMP_SEND, DebugLevel, - ("\n\r[CMPK]-->element ID=%d Len=%d", element_id, total_length));*/ - - /* 4. Check every received command packet conent according to different - element type. Because FW may aggregate RX command packet to minimize - transmit time between DRV and FW.*/ - // Add a counter to prevent to locked in the loop too long - while (total_length > 0 || exe_cnt++ >100) - { - /* 2007/01/17 MH We support aggregation of different cmd in the same packet. */ - element_id = pcmd_buff[0]; - switch(element_id) - { - case RX_TX_FEEDBACK: - cmpk_handle_tx_feedback (dev, pcmd_buff); - cmd_length = CMPK_RX_TX_FB_SIZE; - break; - - case RX_INTERRUPT_STATUS: - cmpk_handle_interrupt_status(dev, pcmd_buff); - cmd_length = sizeof(cmpk_intr_sta_t); - break; - - case BOTH_QUERY_CONFIG: - cmpk_handle_query_config_rx(dev, pcmd_buff); - cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE; - break; - - case RX_TX_STATUS: - cmpk_handle_tx_status(dev, pcmd_buff); - cmd_length = CMPK_RX_TX_STS_SIZE; - break; - - case RX_TX_PER_PKT_FEEDBACK: - // You must at lease add a switch case element here, - // Otherwise, we will jump to default case. - //DbgPrint("CCX Test\r\n"); - cmd_length = CMPK_RX_TX_FB_SIZE; - break; - - case RX_TX_RATE_HISTORY: - //DbgPrint(" rx tx rate history\r\n"); - cmpk_handle_tx_rate_history(dev, pcmd_buff); - cmd_length = CMPK_TX_RAHIS_SIZE; - break; - - default: - - RT_TRACE(COMP_ERR, "---->cmpk_message_handle_rx():unknown CMD Element\n"); - return 1; /* This is a command packet. */ - } - // 2007/01/22 MH Display received rx command packet info. - //cmpk_Display_Message(cmd_length, pcmd_buff); + /* + * 4. Check every received command packet conent according to different + * element type. Because FW may aggregate RX command packet to minimize + * transmit time between DRV and FW. + */ - // 2007/01/22 MH Add to display tx statistic. - //cmpk_DisplayTxStatistic(pAdapter); - - /* 2007/03/09 MH Collect sidderent cmd element pkt num. */ + /* Add a counter to prevent to locked in the loop too long */ + while (total_length > 0 || exe_cnt++ > 100) { + /* We support aggregation of different cmd in the same packet */ + element_id = pcmd_buff[0]; + switch (element_id) { + case RX_TX_FEEDBACK: + cmpk_handle_tx_feedback(dev, pcmd_buff); + cmd_length = CMPK_RX_TX_FB_SIZE; + break; + case RX_INTERRUPT_STATUS: + cmpk_handle_interrupt_status(dev, pcmd_buff); + cmd_length = sizeof(cmpk_intr_sta_t); + break; + case BOTH_QUERY_CONFIG: + cmpk_handle_query_config_rx(dev, pcmd_buff); + cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE; + break; + case RX_TX_STATUS: + cmpk_handle_tx_status(dev, pcmd_buff); + cmd_length = CMPK_RX_TX_STS_SIZE; + break; + case RX_TX_PER_PKT_FEEDBACK: + cmd_length = CMPK_RX_TX_FB_SIZE; + break; + case RX_TX_RATE_HISTORY: + cmpk_handle_tx_rate_history(dev, pcmd_buff); + cmd_length = CMPK_TX_RAHIS_SIZE; + break; + default: + RT_TRACE(COMP_ERR, "(%s): unknown CMD Element\n", + __func__); + return 1; /* This is a command packet. */ + } priv->stats.rxcmdpkt[element_id]++; - total_length -= cmd_length; pcmd_buff += cmd_length; - } /* while (total_length > 0) */ - return 1; /* This is a command packet. */ - -} /* CMPK_Message_Handle_Rx */ + } + return 1; /* This is a command packet. */ +} diff --git a/drivers/staging/rtl8192su/r819xU_cmdpkt.h b/drivers/staging/rtl8192su/r819xU_cmdpkt.h index cced8e0d2788..d3c561551880 100644 --- a/drivers/staging/rtl8192su/r819xU_cmdpkt.h +++ b/drivers/staging/rtl8192su/r819xU_cmdpkt.h @@ -1,199 +1,191 @@ #ifndef R819XUSB_CMDPKT_H #define R819XUSB_CMDPKT_H -/* Different command packet have dedicated message length and definition. */ -#define CMPK_RX_TX_FB_SIZE sizeof(cmpk_txfb_t) //20 -#define CMPK_TX_SET_CONFIG_SIZE sizeof(cmpk_set_cfg_t) //16 -#define CMPK_BOTH_QUERY_CONFIG_SIZE sizeof(cmpk_set_cfg_t) //16 -#define CMPK_RX_TX_STS_SIZE sizeof(cmpk_tx_status_t)// -#define CMPK_RX_DBG_MSG_SIZE sizeof(cmpk_rx_dbginfo_t)// -#define CMPK_TX_RAHIS_SIZE sizeof(cmpk_tx_rahis_t) - -/* 2008/05/08 amy For USB constant. */ -#define ISR_TxBcnOk BIT27 // Transmit Beacon OK -#define ISR_TxBcnErr BIT26 // Transmit Beacon Error -#define ISR_BcnTimerIntr BIT13 // Beacon Timer Interrupt - -/* Define element ID of command packet. */ - -/*------------------------------Define structure----------------------------*/ -/* Define different command packet structure. */ -/* 1. RX side: TX feedback packet. */ -typedef struct tag_cmd_pkt_tx_feedback -{ - // DWORD 0 - u8 element_id; /* Command packet type. */ - u8 length; /* Command packet length. */ - /* 2007/07/05 MH Change tx feedback info field. */ - /*------TX Feedback Info Field */ - u8 TID:4; /* */ - u8 fail_reason:3; /* */ - u8 tok:1; /* Transmit ok. */ - u8 reserve1:4; /* */ - u8 pkt_type:2; /* */ - u8 bandwidth:1; /* */ - u8 qos_pkt:1; /* */ - - // DWORD 1 - u8 reserve2; /* */ - /*------TX Feedback Info Field */ - u8 retry_cnt; /* */ - u16 pkt_id; /* */ - - // DWORD 3 - u16 seq_num; /* */ - u8 s_rate; /* Start rate. */ - u8 f_rate; /* Final rate. */ - - // DWORD 4 - u8 s_rts_rate; /* */ - u8 f_rts_rate; /* */ - u16 pkt_length; /* */ - - // DWORD 5 - u16 reserve3; /* */ - u16 duration; /* */ -}cmpk_txfb_t; - -/* 2. RX side: Interrupt status packet. It includes Beacon State, - Beacon Timer Interrupt and other useful informations in MAC ISR Reg. */ -typedef struct tag_cmd_pkt_interrupt_status -{ - u8 element_id; /* Command packet type. */ - u8 length; /* Command packet length. */ - u16 reserve; - u32 interrupt_status; /* Interrupt Status. */ -}cmpk_intr_sta_t; - - -/* 3. TX side: Set configuration packet. */ -typedef struct tag_cmd_pkt_set_configuration -{ - u8 element_id; /* Command packet type. */ - u8 length; /* Command packet length. */ - u16 reserve1; /* */ - u8 cfg_reserve1:3; - u8 cfg_size:2; /* Configuration info. */ - u8 cfg_type:2; /* Configuration info. */ - u8 cfg_action:1; /* Configuration info. */ - u8 cfg_reserve2; /* Configuration info. */ - u8 cfg_page:4; /* Configuration info. */ - u8 cfg_reserve3:4; /* Configuration info. */ - u8 cfg_offset; /* Configuration info. */ - u32 value; /* */ - u32 mask; /* */ -}cmpk_set_cfg_t; - -/* 4. Both side : TX/RX query configuraton packet. The query structure is the - same as set configuration. */ -#define cmpk_query_cfg_t cmpk_set_cfg_t -/* 5. Multi packet feedback status. */ -typedef struct tag_tx_stats_feedback // PJ quick rxcmd 09042007 -{ - // For endian transfer --> Driver will not the same as firmware structure. - // DW 0 +/* + * Different command packets have dedicated message length and definition. + */ +#define CMPK_RX_TX_FB_SIZE sizeof(cmpk_txfb_t) /* 20 */ +#define CMPK_TX_SET_CONFIG_SIZE sizeof(cmpk_set_cfg_t) /* 16 */ +#define CMPK_BOTH_QUERY_CONFIG_SIZE sizeof(cmpk_set_cfg_t) /* 16 */ +#define CMPK_RX_TX_STS_SIZE sizeof(cmpk_tx_status_t) +#define CMPK_RX_DBG_MSG_SIZE sizeof(cmpk_rx_dbginfo_t) +#define CMPK_TX_RAHIS_SIZE sizeof(cmpk_tx_rahis_t) + +/* For USB constant. */ +#define ISR_TxBcnOk BIT27 /* Transmit Beacon OK */ +#define ISR_TxBcnErr BIT26 /* Transmit Beacon Error */ +#define ISR_BcnTimerIntr BIT13 /* Beacon Timer Interrupt */ + +/* + * Define different command packet structures + * + * 1. RX side: TX feedback packet. + */ +typedef struct tag_cmd_pkt_tx_feedback { + /* DWORD 0 */ + u8 element_id; /* Command packet type. */ + u8 length; /* Command packet length. */ + /* TX Feedback Info Field */ + u8 TID:4; + u8 fail_reason:3; + u8 tok:1; /* Transmit ok. */ + u8 reserve1:4; + u8 pkt_type:2; + u8 bandwidth:1; + u8 qos_pkt:1; + + /* DWORD 1 */ + u8 reserve2; + /* TX Feedback Info Field */ + u8 retry_cnt; + u16 pkt_id; + + /* DWORD 3 */ + u16 seq_num; + u8 s_rate; /* Start rate. */ + u8 f_rate; /* Final rate. */ + + /* DWORD 4 */ + u8 s_rts_rate; + u8 f_rts_rate; + u16 pkt_length; + + /* DWORD 5 */ + u16 reserve3; + u16 duration; +} cmpk_txfb_t; + +/* + * 2. RX side: Interrupt status packet. + * It includes Beacon State, Beacon Timer Interrupt + * and other useful informations in MAC ISR Reg. + */ +typedef struct tag_cmd_pkt_interrupt_status { + u8 element_id; /* Command packet type. */ + u8 length; /* Command packet length. */ + u16 reserve; + u32 interrupt_status; /* Interrupt Status. */ +} cmpk_intr_sta_t; + + +/* + * 3. TX side: Set configuration packet. + */ +typedef struct tag_cmd_pkt_set_configuration { + u8 element_id; /* Command packet type. */ + u8 length; /* Command packet length. */ u16 reserve1; - u8 length; // Command packet length - u8 element_id; // Command packet type - - // DW 1 - u16 txfail; // Tx Fail count - u16 txok; // Tx ok count - - // DW 2 - u16 txmcok; // tx multicast - u16 txretry; // Tx Retry count - - // DW 3 - u16 txucok; // tx unicast - u16 txbcok; // tx broadcast - - // DW 4 - u16 txbcfail; // - u16 txmcfail; // - - // DW 5 - u16 reserve2; // - u16 txucfail; // - - // DW 6-8 - u32 txmclength; - u32 txbclength; - u32 txuclength; - - // DW 9 - u16 reserve3_23; - u8 reserve3_1; - u8 rate; -}__attribute__((packed)) cmpk_tx_status_t; - -/* 6. Debug feedback message. */ -/* 2007/10/23 MH Define RX debug message */ -typedef struct tag_rx_debug_message_feedback -{ - // For endian transfer --> for driver - // DW 0 - u16 reserve1; - u8 length; // Command packet length - u8 element_id; // Command packet type - - // DW 1-?? - // Variable debug message. - -}cmpk_rx_dbginfo_t; - -/* 2008/03/20 MH Define transmit rate history. For big endian format. */ -typedef struct tag_tx_rate_history -{ - // For endian transfer --> for driver - // DW 0 - u8 element_id; // Command packet type - u8 length; // Command packet length - u16 reserved1; - - // DW 1-2 CCK rate counter - u16 cck[4]; - - // DW 3-6 - u16 ofdm[8]; - - // DW 7-14 - //UINT16 MCS_BW0_SG0[16]; - - // DW 15-22 - //UINT16 MCS_BW1_SG0[16]; - - // DW 23-30 - //UINT16 MCS_BW0_SG1[16]; - - // DW 31-38 - //UINT16 MCS_BW1_SG1[16]; - - // DW 7-14 BW=0 SG=0 - // DW 15-22 BW=1 SG=0 - // DW 23-30 BW=0 SG=1 - // DW 31-38 BW=1 SG=1 - u16 ht_mcs[4][16]; - -}__attribute__((packed)) cmpk_tx_rahis_t; + u8 cfg_reserve1:3; + u8 cfg_size:2; /* Configuration info. */ + u8 cfg_type:2; /* Configuration info. */ + u8 cfg_action:1; /* Configuration info. */ + u8 cfg_reserve2; /* Configuration info. */ + u8 cfg_page:4; /* Configuration info. */ + u8 cfg_reserve3:4; /* Configuration info. */ + u8 cfg_offset; /* Configuration info. */ + u32 value; + u32 mask; +} cmpk_set_cfg_t; + +/* + * 4. Both side : TX/RX query configuraton packet. + * The query structure is the same as set configuration. + */ +#define cmpk_query_cfg_t cmpk_set_cfg_t -typedef enum tag_command_packet_directories -{ +/* + * 5. Multi packet feedback status. + */ +typedef struct tag_tx_stats_feedback { + /* + * For endian transfer + * Driver will not the same as firmware structure. + */ + /* DW 0 */ + u16 reserve1; + u8 length; /* Command packet length */ + u8 element_id; /* Command packet type */ + + /* DW 1 */ + u16 txfail; /* Tx Fail count */ + u16 txok; /* Tx ok count */ + + /* DW 2 */ + u16 txmcok; /* tx multicast */ + u16 txretry; /* Tx Retry count */ + + /* DW 3 */ + u16 txucok; /* tx unicast */ + u16 txbcok; /* tx broadcast */ + + /* DW 4 */ + u16 txbcfail; + u16 txmcfail; + + /* DW 5 */ + u16 reserve2; + u16 txucfail; + + /* DW 6-8 */ + u32 txmclength; + u32 txbclength; + u32 txuclength; + + /* DW 9 */ + u16 reserve3_23; + u8 reserve3_1; + u8 rate; +} __attribute__((packed)) cmpk_tx_status_t; + +/* + * 6. Debug feedback message. + */ +typedef struct tag_rx_debug_message_feedback { + /* For endian transfer --> for driver */ + /* DW 0 */ + u16 reserve1; + u8 length; /* Command packet length */ + u8 element_id; /* Command packet type */ +} cmpk_rx_dbginfo_t; + +/* + * Define transmit rate history. For big endian format. + */ +typedef struct tag_tx_rate_history { + /* For endian transfer --> for driver */ + /* DW 0 */ + u8 element_id; /* Command packet type */ + u8 length; /* Command packet length */ + u16 reserved1; + /* DW 1-2 CCK rate counter */ + u16 cck[4]; + /* DW 3-6 */ + u16 ofdm[8]; + u16 ht_mcs[4][16]; +} __attribute__((packed)) cmpk_tx_rahis_t; + +typedef enum tag_command_packet_directories { RX_TX_FEEDBACK = 0, - RX_INTERRUPT_STATUS = 1, - TX_SET_CONFIG = 2, - BOTH_QUERY_CONFIG = 3, - RX_TX_STATUS = 4, - RX_DBGINFO_FEEDBACK = 5, - RX_TX_PER_PKT_FEEDBACK = 6, - RX_TX_RATE_HISTORY = 7, + RX_INTERRUPT_STATUS = 1, + TX_SET_CONFIG = 2, + BOTH_QUERY_CONFIG = 3, + RX_TX_STATUS = 4, + RX_DBGINFO_FEEDBACK = 5, + RX_TX_PER_PKT_FEEDBACK = 6, + RX_TX_RATE_HISTORY = 7, RX_CMD_ELE_MAX -}cmpk_element_e; +} cmpk_element_e; -extern bool cmpk_message_handle_tx(struct net_device *dev, u8* codevirtualaddress, u32 packettype, u32 buffer_len); +extern bool cmpk_message_handle_tx(struct net_device *dev, + u8 *codevirtualaddress, + u32 packettype, + u32 buffer_len); -extern u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats * pstats); -extern bool SendTxCommandPacket( struct net_device *dev, void* pData, u32 DataLen); +extern u32 cmpk_message_handle_rx(struct net_device *dev, + struct ieee80211_rx_stats *pstats); +extern bool SendTxCommandPacket(struct net_device *dev, + void *pData, + u32 DataLen); #endif -- cgit v1.2.3 From 1e1d25cb0d248d58ac8e586ebb23bf2f6dc55c0b Mon Sep 17 00:00:00 2001 From: Michael Tate Date: Sun, 7 Mar 2010 18:19:39 +0400 Subject: staging: frontier: Fix coding style issues in 2 files. This patch removes unecessary whitespace before quoted newlines in two files. One warning in each file remains unresolved. Signed-off-by: Michael Tate Signed-off-by: Greg Kroah-Hartman --- drivers/staging/frontier/alphatrack.c | 6 +++--- drivers/staging/frontier/tranzport.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/frontier/alphatrack.c b/drivers/staging/frontier/alphatrack.c index a50a21518a8e..ce4d663a3e54 100644 --- a/drivers/staging/frontier/alphatrack.c +++ b/drivers/staging/frontier/alphatrack.c @@ -238,7 +238,7 @@ static void usb_alphatrack_interrupt_in_callback(struct urb *urb) if (urb->actual_length != INPUT_CMD_SIZE) { dev_warn(&dev->intf->dev, "Urb length was %d bytes!!" - "Do something intelligent \n", urb->actual_length); + "Do something intelligent\n", urb->actual_length); } else { alphatrack_ocmd_info(&dev->intf->dev, &(*dev->ring_buffer)[dev->ring_tail].cmd, @@ -599,7 +599,7 @@ static ssize_t usb_alphatrack_write(struct file *file, } if (dev->interrupt_out_endpoint == NULL) { - err("Endpoint should not be be null! \n"); + err("Endpoint should not be be null!\n"); goto unlock_exit; } @@ -771,7 +771,7 @@ static int usb_alphatrack_probe(struct usb_interface *intf, kmalloc(sizeof(struct alphatrack_ocmd) * true_size, GFP_KERNEL); if (!dev->write_buffer) { - dev_err(&intf->dev, "Couldn't allocate write_buffer \n"); + dev_err(&intf->dev, "Couldn't allocate write_buffer\n"); goto error; } diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c index 2f03f43f3a2e..1f91001b1347 100644 --- a/drivers/staging/frontier/tranzport.c +++ b/drivers/staging/frontier/tranzport.c @@ -255,7 +255,7 @@ static void usb_tranzport_interrupt_in_callback(struct urb *urb) if (urb->actual_length != 8) { dev_warn(&dev->intf->dev, "Urb length was %d bytes!!" - "Do something intelligent \n", + "Do something intelligent\n", urb->actual_length); } else { dbg_info(&dev->intf->dev, @@ -724,7 +724,7 @@ static ssize_t usb_tranzport_write(struct file *file, } if (dev->interrupt_out_endpoint == NULL) { - err("Endpoint should not be be null! \n"); + err("Endpoint should not be be null!\n"); goto unlock_exit; } -- cgit v1.2.3 From 4dbb8e57c1ef23e5822b85a646b4ba31a98b9864 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 8 Mar 2010 16:39:24 +0300 Subject: staging: rt2860: off by one errors The code is trying to say that if the offset is higher than the max it should be set to the max, but there is an off by one bug and it sets it one passed the end of the array. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/sta_ioctl.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/sta_ioctl.c b/drivers/staging/rt2860/sta_ioctl.c index de4b6277baee..33a6939cf2ae 100644 --- a/drivers/staging/rt2860/sta_ioctl.c +++ b/drivers/staging/rt2860/sta_ioctl.c @@ -1047,8 +1047,7 @@ int rt_ioctl_giwscan(struct net_device *dev, if (tmpRate == 0x6c && pAdapter->ScanTab.BssEntry[i].HtCapabilityLen > 0) { - int rate_count = - sizeof(ralinkrate) / sizeof(__s32); + int rate_count = ARRAY_SIZE(ralinkrate); struct rt_ht_cap_info capInfo = pAdapter->ScanTab.BssEntry[i].HtCapability. HtCapInfo; @@ -1061,10 +1060,11 @@ int rt_ioctl_giwscan(struct net_device *dev, int rate_index = 12 + ((u8)capInfo.ChannelWidth * 24) + ((u8)shortGI * 48) + ((u8)maxMCS); + if (rate_index < 0) rate_index = 0; - if (rate_index > rate_count) - rate_index = rate_count; + if (rate_index >= rate_count) + rate_index = rate_count - 1; iwe.u.bitrate.value = ralinkrate[rate_index] * 500000; } @@ -2338,7 +2338,7 @@ int rt_ioctl_giwrate(struct net_device *dev, */ GET_PAD_FROM_NET_DEV(pAd, dev); - rate_count = sizeof(ralinkrate) / sizeof(__s32); + rate_count = ARRAY_SIZE(ralinkrate); /*check if the interface is down */ if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); @@ -2369,8 +2369,8 @@ int rt_ioctl_giwrate(struct net_device *dev, if (rate_index < 0) rate_index = 0; - if (rate_index > rate_count) - rate_index = rate_count; + if (rate_index >= rate_count) + rate_index = rate_count - 1; wrqu->bitrate.value = ralinkrate[rate_index] * 500000; wrqu->bitrate.disabled = 0; -- cgit v1.2.3 From 76ce24f3e58b3d158f3eca88c339170c05bbefa2 Mon Sep 17 00:00:00 2001 From: Jason Date: Mon, 8 Mar 2010 02:36:21 -0800 Subject: staging: wavelan: fix coding style of first 1000 lines in wavelan.c Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wavelan/wavelan.c | 198 +++++++++++++++++++++----------------- 1 file changed, 108 insertions(+), 90 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wavelan/wavelan.c b/drivers/staging/wavelan/wavelan.c index 54ca63196fdd..37ede43bbbe7 100644 --- a/drivers/staging/wavelan/wavelan.c +++ b/drivers/staging/wavelan/wavelan.c @@ -36,7 +36,7 @@ static u8 wv_irq_to_psa(int irq) /*------------------------------------------------------------------*/ /* - * Translate PSA irq parameter to irq number + * Translate PSA irq parameter to irq number */ static int __init wv_psa_to_irq(u8 irqval) { @@ -55,7 +55,7 @@ static int __init wv_psa_to_irq(u8 irqval) * * One major difference with the PCMCIA hardware (except the port mapping) * is that we have to keep the state of the Host Control Register - * because of the interrupt enable & bus size flags. + *because of the interrupt enable & bus size flags. */ /*------------------------------------------------------------------*/ @@ -64,7 +64,7 @@ static int __init wv_psa_to_irq(u8 irqval) */ static inline u16 hasr_read(unsigned long ioaddr) { - return (inw(HASR(ioaddr))); + return inw(HASR(ioaddr)); } /* hasr_read */ /*------------------------------------------------------------------*/ @@ -132,11 +132,11 @@ static inline void wv_16_on(unsigned long ioaddr, u16 hacr) * Disable interrupts on the WaveLAN hardware. * (called by wv_82586_stop()) */ -static inline void wv_ints_off(struct net_device * dev) +static inline void wv_ints_off(struct net_device *dev) { net_local *lp = netdev_priv(dev); unsigned long ioaddr = dev->base_addr; - + lp->hacr &= ~HACR_INTRON; hacr_write(ioaddr, lp->hacr); } /* wv_ints_off */ @@ -146,7 +146,7 @@ static inline void wv_ints_off(struct net_device * dev) * Enable interrupts on the WaveLAN hardware. * (called by wv_hw_reset()) */ -static inline void wv_ints_on(struct net_device * dev) +static inline void wv_ints_on(struct net_device *dev) { net_local *lp = netdev_priv(dev); unsigned long ioaddr = dev->base_addr; @@ -167,9 +167,11 @@ static inline void wv_ints_on(struct net_device * dev) /* * Read bytes from the PSA. */ -static void psa_read(unsigned long ioaddr, u16 hacr, int o, /* offset in PSA */ - u8 * b, /* buffer to fill */ - int n) +static void psa_read(unsigned long ioaddr, + u16 hacr, + int o, /* offset in PSA */ + u8 *b, /*buffer to fill */ + int n) { /* size to read */ wv_16_off(ioaddr, hacr); @@ -186,9 +188,11 @@ static void psa_read(unsigned long ioaddr, u16 hacr, int o, /* offset in PSA */ /* * Write the Parameter Storage Area to the WaveLAN card's memory. */ -static void psa_write(unsigned long ioaddr, u16 hacr, int o, /* Offset in PSA */ - u8 * b, /* Buffer in memory */ - int n) +static void psa_write(unsigned long ioaddr, + u16 hacr, + int o, /* Offset in PSA */ + u8 *b, /*buffer in memory */ + int n) { /* Length of buffer */ int count = 0; @@ -203,8 +207,8 @@ static void psa_write(unsigned long ioaddr, u16 hacr, int o, /* Offset in PSA */ /* Wait for the memory to finish its write cycle */ count = 0; - while ((count++ < 100) && - (hasr_read(ioaddr) & HASR_PSA_BUSY)) mdelay(1); + while ((count++ < 100) && (hasr_read(ioaddr) & HASR_PSA_BUSY)) + mdelay(1); } wv_16_on(ioaddr, hacr); @@ -221,8 +225,8 @@ static void psa_write(unsigned long ioaddr, u16 hacr, int o, /* Offset in PSA */ * The Windows drivers don't use the CRC, but the AP and the PtP tool * depend on it. */ -static u16 psa_crc(u8 * psa, /* The PSA */ - int size) +static u16 psa_crc(u8 *psa, /* The PSA */ + int size) { /* Number of short for CRC */ int byte_cnt; /* Loop on the PSA */ u16 crc_bytes = 0; /* Data in the PSA */ @@ -247,7 +251,9 @@ static u16 psa_crc(u8 * psa, /* The PSA */ /* * update the checksum field in the Wavelan's PSA */ -static void update_psa_checksum(struct net_device * dev, unsigned long ioaddr, u16 hacr) +static void update_psa_checksum(struct net_device *dev, + unsigned long ioaddr, + u16 hacr) { #ifdef SET_PSA_CRC psa_t psa; @@ -279,7 +285,8 @@ static void update_psa_checksum(struct net_device * dev, unsigned long ioaddr, u if (crc != 0) printk(KERN_WARNING - "%s: update_psa_checksum(): CRC does not agree with PSA data (even after recalculating)\n", + "%s: update_psa_checksum(): CRC does not \ + agree with PSA data (even after recalculating)\n", dev->name); #endif /* DEBUG_IOCTL_INFO */ #endif /* SET_PSA_CRC */ @@ -305,7 +312,7 @@ static void mmc_out(unsigned long ioaddr, u16 o, u8 d) * Routine to write bytes to the Modem Management Controller. * We start at the end because it is the way it should be! */ -static void mmc_write(unsigned long ioaddr, u8 o, u8 * b, int n) +static void mmc_write(unsigned long ioaddr, u8 o, u8 *b, int n) { o += n; b += n; @@ -340,7 +347,7 @@ static u8 mmc_in(unsigned long ioaddr, u16 o) * (code has just been moved in the above function) * We start at the end because it is the way it should be! */ -static inline void mmc_read(unsigned long ioaddr, u8 o, u8 * b, int n) +static inline void mmc_read(unsigned long ioaddr, u8 o, u8 *b, int n) { o += n; b += n; @@ -369,15 +376,16 @@ static inline int mmc_encr(unsigned long ioaddr) * Wait for the frequency EEPROM to complete a command. * I hope this one will be optimally inlined. */ -static inline void fee_wait(unsigned long ioaddr, /* I/O port of the card */ - int delay, /* Base delay to wait for */ +static inline void fee_wait(unsigned long ioaddr, /* I/O port of the card */ + int delay, /*base delay to wait for */ int number) { /* Number of time to wait */ int count = 0; /* Wait only a limited time */ while ((count++ < number) && (mmc_in(ioaddr, mmroff(0, mmr_fee_status)) & - MMR_FEE_STATUS_BUSY)) udelay(delay); + MMR_FEE_STATUS_BUSY)) + udelay(delay); } /*------------------------------------------------------------------*/ @@ -386,7 +394,7 @@ static inline void fee_wait(unsigned long ioaddr, /* I/O port of the card */ */ static void fee_read(unsigned long ioaddr, /* I/O port of the card */ u16 o, /* destination offset */ - u16 * b, /* data buffer */ + u16 *b, /* data buffer */ int n) { /* number of registers */ b += n; /* Position at the end of the area */ @@ -414,12 +422,12 @@ static void fee_read(unsigned long ioaddr, /* I/O port of the card */ /* * Write bytes from the Frequency EEPROM (frequency select cards). * This is a bit complicated, because the frequency EEPROM has to - * be unprotected and the write enabled. + *be unprotected and the write enabled. * Jean II */ static void fee_write(unsigned long ioaddr, /* I/O port of the card */ u16 o, /* destination offset */ - u16 * b, /* data buffer */ + u16 *b, /* data buffer */ int n) { /* number of registers */ b += n; /* Position at the end of the area. */ @@ -473,7 +481,9 @@ static void fee_write(unsigned long ioaddr, /* I/O port of the card */ mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WRITE); - /* WaveLAN documentation says to wait at least 10 ms for EEBUSY = 0 */ + /* WaveLAN documentation says to + * wait at least 10 ms for EEBUSY = 0 + */ mdelay(10); fee_wait(ioaddr, 10, 100); } @@ -504,7 +514,7 @@ static void fee_write(unsigned long ioaddr, /* I/O port of the card */ * Why does inlining this function make it fail? */ static /*inline */ void obram_read(unsigned long ioaddr, - u16 o, u8 * b, int n) + u16 o, u8 *b, int n) { outw(o, PIOR1(ioaddr)); insw(PIOP1(ioaddr), (unsigned short *) b, (n + 1) >> 1); @@ -514,7 +524,7 @@ static /*inline */ void obram_read(unsigned long ioaddr, /* * Write bytes to the on-board RAM. */ -static inline void obram_write(unsigned long ioaddr, u16 o, u8 * b, int n) +static inline void obram_write(unsigned long ioaddr, u16 o, u8 *b, int n) { outw(o, PIOR1(ioaddr)); outsw(PIOP1(ioaddr), (unsigned short *) b, (n + 1) >> 1); @@ -524,7 +534,7 @@ static inline void obram_write(unsigned long ioaddr, u16 o, u8 * b, int n) /* * Acknowledge the reading of the status issued by the i82586. */ -static void wv_ack(struct net_device * dev) +static void wv_ack(struct net_device *dev) { net_local *lp = netdev_priv(dev); unsigned long ioaddr = dev->base_addr; @@ -566,7 +576,7 @@ static void wv_ack(struct net_device * dev) * Set channel attention bit and busy wait until command has * completed, then acknowledge completion of the command. */ -static int wv_synchronous_cmd(struct net_device * dev, const char *str) +static int wv_synchronous_cmd(struct net_device *dev, const char *str) { net_local *lp = netdev_priv(dev); unsigned long ioaddr = dev->base_addr; @@ -613,7 +623,7 @@ static int wv_synchronous_cmd(struct net_device * dev, const char *str) * Check if done, and if OK. */ static int -wv_config_complete(struct net_device * dev, unsigned long ioaddr, net_local * lp) +wv_config_complete(struct net_device *dev, unsigned long ioaddr, net_local * lp) { unsigned short mcs_addr; unsigned short status; @@ -641,7 +651,8 @@ wv_config_complete(struct net_device * dev, unsigned long ioaddr, net_local * lp /* Check mc_config command */ if ((status & AC_SFLD_OK) != AC_SFLD_OK) printk(KERN_INFO - "%s: wv_config_complete(): set_multicast_address failed; status = 0x%x\n", + "%s: wv_config_complete(): \ + set_multicast_address failed; status = 0x%x\n", dev->name, status); /* check ia-config command */ @@ -650,7 +661,8 @@ wv_config_complete(struct net_device * dev, unsigned long ioaddr, net_local * lp (unsigned char *) &status, sizeof(status)); if ((status & AC_SFLD_OK) != AC_SFLD_OK) printk(KERN_INFO - "%s: wv_config_complete(): set_MAC_address failed; status = 0x%x\n", + "%s: wv_config_complete(): set_MAC_address \ + failed; status = 0x%x\n", dev->name, status); /* Check config command. */ @@ -659,7 +671,8 @@ wv_config_complete(struct net_device * dev, unsigned long ioaddr, net_local * lp (unsigned char *) &status, sizeof(status)); if ((status & AC_SFLD_OK) != AC_SFLD_OK) printk(KERN_INFO - "%s: wv_config_complete(): configure failed; status = 0x%x\n", + "%s: wv_config_complete(): configure failed; \ + status = 0x%x\n", dev->name, status); #endif /* DEBUG_CONFIG_ERROR */ @@ -680,7 +693,9 @@ wv_config_complete(struct net_device * dev, unsigned long ioaddr, net_local * lp * (called in wavelan_interrupt()). * Note : the spinlock is already grabbed for us. */ -static int wv_complete(struct net_device * dev, unsigned long ioaddr, net_local * lp) +static int wv_complete(struct net_device *dev, + unsigned long ioaddr, + net_local *lp) { int nreaped = 0; @@ -722,9 +737,8 @@ if (lp->tx_n_in_use > 0) /* Next one in the chain */ lp->tx_first_in_use += TXBLOCKZ; if (lp->tx_first_in_use >= - OFFSET_CU + - NTXBLOCKS * TXBLOCKZ) lp->tx_first_in_use -= - NTXBLOCKS * TXBLOCKZ; + OFFSET_CU + NTXBLOCKS * TXBLOCKZ) + lp->tx_first_in_use -= NTXBLOCKS * TXBLOCKZ; } /* Hack for reconfiguration */ @@ -741,7 +755,8 @@ if (lp->tx_n_in_use > 0) #ifdef DEBUG_TX_INFO if (ncollisions > 0) printk(KERN_DEBUG - "%s: wv_complete(): tx completed after %d collisions.\n", + "%s: wv_complete(): tx completed after \ + %d collisions.\n", dev->name, ncollisions); #endif } else { @@ -758,7 +773,8 @@ if (lp->tx_n_in_use > 0) dev->stats.tx_carrier_errors++; #ifdef DEBUG_TX_FAIL printk(KERN_DEBUG - "%s: wv_complete(): tx error: lost CTS.\n", + "%s: wv_complete(): tx error: \ + lost CTS.\n", dev->name); #endif } @@ -766,7 +782,8 @@ if (lp->tx_n_in_use > 0) dev->stats.tx_fifo_errors++; #ifdef DEBUG_TX_FAIL printk(KERN_DEBUG - "%s: wv_complete(): tx error: slow DMA.\n", + "%s: wv_complete(): tx error: \ + slow DMA.\n", dev->name); #endif } @@ -774,7 +791,8 @@ if (lp->tx_n_in_use > 0) dev->stats.tx_heartbeat_errors++; #ifdef DEBUG_TX_FAIL printk(KERN_DEBUG - "%s: wv_complete(): tx error: heart beat.\n", + "%s: wv_complete(): tx error: \ + heart beat.\n", dev->name); #endif } @@ -782,7 +800,8 @@ if (lp->tx_n_in_use > 0) dev->stats.tx_aborted_errors++; #ifdef DEBUG_TX_FAIL printk(KERN_DEBUG - "%s: wv_complete(): tx error: too many collisions.\n", + "%s: wv_complete(): tx error: \ + too many collisions.\n", dev->name); #endif } @@ -804,9 +823,9 @@ if (lp->tx_n_in_use > 0) /* * Inform upper layers. */ - if (lp->tx_n_in_use < NTXBLOCKS - 1) { + if (lp->tx_n_in_use < NTXBLOCKS - 1) netif_wake_queue(dev); - } + #ifdef DEBUG_INTERRUPT_TRACE printk(KERN_DEBUG "%s: <-wv_complete()\n", dev->name); #endif @@ -816,13 +835,13 @@ if (lp->tx_n_in_use > 0) /*------------------------------------------------------------------*/ /* * Reconfigure the i82586, or at least ask for it. - * Because wv_82586_config uses a transmission buffer, we must do it + *because wv_82586_config uses a transmission buffer, we must do it * when we are sure that there is one left, so we do it now * or in wavelan_packet_xmit() (I can't find any better place, * wavelan_interrupt is not an option), so you may experience * delays sometimes. */ -static void wv_82586_reconfig(struct net_device * dev) +static void wv_82586_reconfig(struct net_device *dev) { net_local *lp = netdev_priv(dev); unsigned long flags; @@ -831,13 +850,12 @@ static void wv_82586_reconfig(struct net_device * dev) lp->reconfig_82586 = 1; /* Check if we can do it now ! */ - if((netif_running(dev)) && !(netif_queue_stopped(dev))) { + if ((netif_running(dev)) && !(netif_queue_stopped(dev))) { spin_lock_irqsave(&lp->spinlock, flags); /* May fail */ wv_82586_config(dev); spin_unlock_irqrestore(&lp->spinlock, flags); - } - else { + } else { #ifdef DEBUG_CONFIG_INFO printk(KERN_DEBUG "%s: wv_82586_reconfig(): delayed (state = %lX)\n", @@ -857,7 +875,7 @@ static void wv_82586_reconfig(struct net_device * dev) /* * Print the formatted contents of the Parameter Storage Area. */ -static void wv_psa_show(psa_t * p) +static void wv_psa_show(psa_t *p) { printk(KERN_DEBUG "##### WaveLAN PSA contents: #####\n"); printk(KERN_DEBUG "psa_io_base_addr_1: 0x%02X %02X %02X %02X\n", @@ -919,13 +937,13 @@ static void wv_psa_show(psa_t * p) * Print the formatted status of the Modem Management Controller. * This function needs to be completed. */ -static void wv_mmc_show(struct net_device * dev) +static void wv_mmc_show(struct net_device *dev) { unsigned long ioaddr = dev->base_addr; net_local *lp = netdev_priv(dev); mmr_t m; - /* Basic check */ + /*basic check */ if (hasr_read(ioaddr) & HASR_NO_CLK) { printk(KERN_WARNING "%s: wv_mmc_show: modem not connected\n", @@ -935,7 +953,7 @@ static void wv_mmc_show(struct net_device * dev) /* Read the mmc */ mmc_out(ioaddr, mmwoff(0, mmw_freeze), 1); - mmc_read(ioaddr, 0, (u8 *) & m, sizeof(m)); + mmc_read(ioaddr, 0, (u8 *) &m, sizeof(m)); mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0); /* Don't forget to update statistics */ @@ -1100,7 +1118,7 @@ static void wv_scb_show(unsigned long ioaddr) /* * Print the formatted status of the i82586's receive unit. */ -static void wv_ru_show(struct net_device * dev) +static void wv_ru_show(struct net_device *dev) { printk(KERN_DEBUG "##### WaveLAN i82586 receiver unit status: #####\n"); @@ -1115,7 +1133,7 @@ static void wv_ru_show(struct net_device * dev) /* * Display info about one control block of the i82586 memory. */ -static void wv_cu_show_one(struct net_device * dev, net_local * lp, int i, u16 p) +static void wv_cu_show_one(struct net_device *dev, net_local * lp, int i, u16 p) { unsigned long ioaddr; ac_tx_t actx; @@ -1144,7 +1162,7 @@ static void wv_cu_show_one(struct net_device * dev, net_local * lp, int i, u16 p /* * Print status of the command unit of the i82586. */ -static void wv_cu_show(struct net_device * dev) +static void wv_cu_show(struct net_device *dev) { net_local *lp = netdev_priv(dev); unsigned int i; @@ -1170,7 +1188,7 @@ static void wv_cu_show(struct net_device * dev) /* * Print the formatted status of the WaveLAN PCMCIA device driver. */ -static void wv_dev_show(struct net_device * dev) +static void wv_dev_show(struct net_device *dev) { printk(KERN_DEBUG "dev:"); printk(" state=%lX,", dev->state); @@ -1184,7 +1202,7 @@ static void wv_dev_show(struct net_device * dev) * Print the formatted status of the WaveLAN PCMCIA device driver's * private information. */ -static void wv_local_show(struct net_device * dev) +static void wv_local_show(struct net_device *dev) { net_local *lp; @@ -1245,7 +1263,7 @@ static inline void wv_packet_info(u8 * p, /* Packet to dump */ * This is the information which is displayed by the driver at startup. * There are lots of flags for configuring it to your liking. */ -static void wv_init_info(struct net_device * dev) +static void wv_init_info(struct net_device *dev) { short ioaddr = dev->base_addr; net_local *lp = netdev_priv(dev); @@ -1355,7 +1373,7 @@ static void wv_init_info(struct net_device * dev) * num_addrs > 0 Multicast mode, receive normal and MC packets, * and do best-effort filtering. */ -static void wavelan_set_multicast_list(struct net_device * dev) +static void wavelan_set_multicast_list(struct net_device *dev) { net_local *lp = netdev_priv(dev); @@ -1425,7 +1443,7 @@ static void wavelan_set_multicast_list(struct net_device * dev) * (Note : it was a nice way to test the reconfigure stuff...) */ #ifdef SET_MAC_ADDRESS -static int wavelan_set_mac_address(struct net_device * dev, void *addr) +static int wavelan_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr *mac = addr; @@ -1614,7 +1632,7 @@ static int wv_set_frequency(unsigned long ioaddr, /* I/O port of the card */ return 0; } else - return -EINVAL; /* Bah, never get there... */ + return -EINVAL; /*bah, never get there... */ } /*------------------------------------------------------------------*/ @@ -1663,7 +1681,7 @@ static int wv_frequency_list(unsigned long ioaddr, /* I/O port of the card */ * address with our list, and if they match, get the statistics. * Sorry, but this function really needs the wireless extensions. */ -static inline void wl_spy_gather(struct net_device * dev, +static inline void wl_spy_gather(struct net_device *dev, u8 * mac, /* MAC address */ u8 * stats) /* Statistics to gather */ { @@ -1689,7 +1707,7 @@ static inline void wl_spy_gather(struct net_device * dev, * With this histogram you may detect if one WaveLAN is really weak, * or you may also calculate the mean and standard deviation of the level. */ -static inline void wl_his_gather(struct net_device * dev, u8 * stats) +static inline void wl_his_gather(struct net_device *dev, u8 * stats) { /* Statistics to gather */ net_local *lp = netdev_priv(dev); u8 level = stats[0] & MMR_SIGNAL_LVL; @@ -1981,7 +1999,7 @@ static int wavelan_set_encode(struct net_device *dev, } if(!ret) { - /* Basic checking... */ + /*basic checking... */ if (wrqu->encoding.length == 8) { /* Copy the key in the driver */ memcpy(psa.psa_encryption_key, extra, @@ -2319,7 +2337,7 @@ static const iw_handler wavelan_handler[] = NULL, /* SIOCGIWTXPOW */ NULL, /* SIOCSIWRETRY */ NULL, /* SIOCGIWRETRY */ - /* Bummer ! Why those are only at the end ??? */ + /*bummer ! Why those are only at the end ??? */ wavelan_set_encode, /* SIOCSIWENCODE */ wavelan_get_encode, /* SIOCGIWENCODE */ }; @@ -2358,7 +2376,7 @@ static const struct iw_handler_def wavelan_handler_def = * Get wireless statistics. * Called by /proc/net/wireless */ -static iw_stats *wavelan_get_wireless_stats(struct net_device * dev) +static iw_stats *wavelan_get_wireless_stats(struct net_device *dev) { unsigned long ioaddr = dev->base_addr; net_local *lp = netdev_priv(dev); @@ -2434,7 +2452,7 @@ static iw_stats *wavelan_get_wireless_stats(struct net_device * dev) * (called by wv_packet_rcv()) */ static void -wv_packet_read(struct net_device * dev, u16 buf_off, int sksize) +wv_packet_read(struct net_device *dev, u16 buf_off, int sksize) { net_local *lp = netdev_priv(dev); unsigned long ioaddr = dev->base_addr; @@ -2527,7 +2545,7 @@ wv_packet_read(struct net_device * dev, u16 buf_off, int sksize) * (called in wavelan_interrupt()). * Note : the spinlock is already grabbed for us. */ -static void wv_receive(struct net_device * dev) +static void wv_receive(struct net_device *dev) { unsigned long ioaddr = dev->base_addr; net_local *lp = netdev_priv(dev); @@ -2710,7 +2728,7 @@ static void wv_receive(struct net_device * dev) * * (called in wavelan_packet_xmit()) */ -static int wv_packet_write(struct net_device * dev, void *buf, short length) +static int wv_packet_write(struct net_device *dev, void *buf, short length) { net_local *lp = netdev_priv(dev); unsigned long ioaddr = dev->base_addr; @@ -2842,7 +2860,7 @@ static int wv_packet_write(struct net_device * dev, void *buf, short length) * to send the packet. */ static netdev_tx_t wavelan_packet_xmit(struct sk_buff *skb, - struct net_device * dev) + struct net_device *dev) { net_local *lp = netdev_priv(dev); unsigned long flags; @@ -2854,7 +2872,7 @@ static netdev_tx_t wavelan_packet_xmit(struct sk_buff *skb, #endif /* - * Block a timer-based transmit from overlapping. + *block a timer-based transmit from overlapping. * In other words, prevent reentering this routine. */ netif_stop_queue(dev); @@ -2905,7 +2923,7 @@ static netdev_tx_t wavelan_packet_xmit(struct sk_buff *skb, * Routine to initialize the Modem Management Controller. * (called by wv_hw_reset()) */ -static int wv_mmc_init(struct net_device * dev) +static int wv_mmc_init(struct net_device *dev) { unsigned long ioaddr = dev->base_addr; net_local *lp = netdev_priv(dev); @@ -3077,7 +3095,7 @@ static int wv_mmc_init(struct net_device * dev) * Start the receive unit. * (called by wv_hw_reset()) */ -static int wv_ru_start(struct net_device * dev) +static int wv_ru_start(struct net_device *dev) { net_local *lp = netdev_priv(dev); unsigned long ioaddr = dev->base_addr; @@ -3159,8 +3177,8 @@ static int wv_ru_start(struct net_device * dev) * self-loop of the first transmit block. * * Here we create the list of send buffers used to transmit packets - * between the PC and the command unit. For each buffer, we create a - * buffer descriptor (pointing on the buffer), a transmit command + *between the PC and the command unit. For each buffer, we create a + *buffer descriptor (pointing on the buffer), a transmit command * (pointing to the buffer descriptor) and a NOP command. * The transmit command is linked to the NOP, and the NOP to itself. * When we will have finished executing the transmit command, we will @@ -3169,7 +3187,7 @@ static int wv_ru_start(struct net_device * dev) * * (called by wv_hw_reset()) */ -static int wv_cu_start(struct net_device * dev) +static int wv_cu_start(struct net_device *dev) { net_local *lp = netdev_priv(dev); unsigned long ioaddr = dev->base_addr; @@ -3270,7 +3288,7 @@ static int wv_cu_start(struct net_device * dev) * * (called by wv_hw_reset()) */ -static int wv_82586_start(struct net_device * dev) +static int wv_82586_start(struct net_device *dev) { net_local *lp = netdev_priv(dev); unsigned long ioaddr = dev->base_addr; @@ -3402,7 +3420,7 @@ static int wv_82586_start(struct net_device * dev) * * (called by wv_hw_reset(), wv_82586_reconfig(), wavelan_packet_xmit()) */ -static void wv_82586_config(struct net_device * dev) +static void wv_82586_config(struct net_device *dev) { net_local *lp = netdev_priv(dev); unsigned long ioaddr = dev->base_addr; @@ -3449,7 +3467,7 @@ static void wv_82586_config(struct net_device * dev) tx_addr = txblock; nop_addr = tx_addr + sizeof(tx); tbd_addr = nop_addr + sizeof(nop); - cfg_addr = tbd_addr + sizeof(tbd_t); /* beginning of the buffer */ + cfg_addr = tbd_addr + sizeof(tbd_t); /*beginning of the buffer */ ias_addr = cfg_addr + sizeof(cfg); mcs_addr = ias_addr + sizeof(ias); @@ -3578,7 +3596,7 @@ static void wv_82586_config(struct net_device * dev) * WaveLAN controller (i82586). * (called by wavelan_close()) */ -static void wv_82586_stop(struct net_device * dev) +static void wv_82586_stop(struct net_device *dev) { net_local *lp = netdev_priv(dev); unsigned long ioaddr = dev->base_addr; @@ -3615,7 +3633,7 @@ static void wv_82586_stop(struct net_device * dev) * 5. Start the LAN controller's receive unit * (called by wavelan_interrupt(), wavelan_watchdog() & wavelan_open()) */ -static int wv_hw_reset(struct net_device * dev) +static int wv_hw_reset(struct net_device *dev) { net_local *lp = netdev_priv(dev); unsigned long ioaddr = dev->base_addr; @@ -3939,7 +3957,7 @@ static void wavelan_watchdog(struct net_device * dev) * Configure and start up the WaveLAN PCMCIA adaptor. * Called by NET3 when it "opens" the device. */ -static int wavelan_open(struct net_device * dev) +static int wavelan_open(struct net_device *dev) { net_local *lp = netdev_priv(dev); unsigned long flags; @@ -3994,7 +4012,7 @@ static int wavelan_open(struct net_device * dev) * Shut down the WaveLAN ISA card. * Called by NET3 when it "closes" the device. */ -static int wavelan_close(struct net_device * dev) +static int wavelan_close(struct net_device *dev) { net_local *lp = netdev_priv(dev); unsigned long flags; @@ -4040,7 +4058,7 @@ static const struct net_device_ops wavelan_netdev_ops = { /*------------------------------------------------------------------*/ /* * Probe an I/O address, and if the WaveLAN is there configure the - * device structure + *device structure * (called by wavelan_probe() and via init_module()). */ static int __init wavelan_config(struct net_device *dev, unsigned short ioaddr) @@ -4114,7 +4132,7 @@ static int __init wavelan_config(struct net_device *dev, unsigned short ioaddr) memset(netdev_priv(dev), 0, sizeof(net_local)); lp = netdev_priv(dev); - /* Back link to the device structure. */ + /*back link to the device structure. */ lp->dev = dev; /* Add the device at the beginning of the linked list. */ lp->next = wavelan_list; @@ -4377,7 +4395,7 @@ MODULE_LICENSE("GPL"); * * Please send bug reports, updates, comments to: * - * Bruce Janson Email: bruce@cs.usyd.edu.au - * Basser Department of Computer Science Phone: +61-2-9351-3423 + *bruce Janson Email: bruce@cs.usyd.edu.au + *basser Department of Computer Science Phone: +61-2-9351-3423 * University of Sydney, N.S.W., 2006, AUSTRALIA Fax: +61-2-9351-3838 */ -- cgit v1.2.3 From 631c8dec075c16b60c3e0a334c027196b07252b8 Mon Sep 17 00:00:00 2001 From: Edgardo Hames Date: Mon, 8 Mar 2010 17:02:37 -0800 Subject: Staging: wlan-ng: fix coding style in hfa834x_usb.c This is a patch in hfa834x_usb.c to fix typedef declarations and long lines. Signed-off-by: Edgardo Hames Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/hfa384x_usb.c | 159 +++++++++++++++++----------------- 1 file changed, 81 insertions(+), 78 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c index 5df56f0238d6..2400242e2d87 100644 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -62,9 +62,9 @@ * * hfa384x_drvr_xxxconfig An example of the drvr level abstraction. These * functions are wrappers for the RID get/set -* sequence. They call copy_[to|from]_bap() and -* cmd_access(). These functions operate on the -* RIDs and buffers without validation. The caller +* sequence. They call copy_[to|from]_bap() and +* cmd_access(). These functions operate on the +* RIDs and buffers without validation. The caller * is responsible for that. * * API wrapper functions: @@ -144,7 +144,6 @@ enum cmd_mode { DOWAIT = 0, DOASYNC }; -typedef enum cmd_mode CMD_MODE; #define THROTTLE_JIFFIES (HZ/8) #define URB_ASYNC_UNLINK 0 @@ -206,12 +205,11 @@ static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx); struct usbctlx_completor { int (*complete) (struct usbctlx_completor *); }; -typedef struct usbctlx_completor usbctlx_completor_t; static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx, - usbctlx_completor_t *completor); + struct usbctlx_completor *completor); static int unlocked_usbctlx_cancel_async(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx); @@ -232,13 +230,13 @@ usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp, /* Low level req/resp CTLX formatters and submitters */ static int hfa384x_docmd(hfa384x_t *hw, - CMD_MODE mode, + enum cmd_mode mode, hfa384x_metacmd_t *cmd, ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data); static int hfa384x_dorrid(hfa384x_t *hw, - CMD_MODE mode, + enum cmd_mode mode, u16 rid, void *riddata, unsigned int riddatalen, @@ -246,7 +244,7 @@ hfa384x_dorrid(hfa384x_t *hw, static int hfa384x_dowrid(hfa384x_t *hw, - CMD_MODE mode, + enum cmd_mode mode, u16 rid, void *riddata, unsigned int riddatalen, @@ -254,7 +252,7 @@ hfa384x_dowrid(hfa384x_t *hw, static int hfa384x_dormem(hfa384x_t *hw, - CMD_MODE mode, + enum cmd_mode mode, u16 page, u16 offset, void *data, @@ -263,7 +261,7 @@ hfa384x_dormem(hfa384x_t *hw, static int hfa384x_dowmem(hfa384x_t *hw, - CMD_MODE mode, + enum cmd_mode mode, u16 page, u16 offset, void *data, @@ -351,7 +349,8 @@ static int submit_rx_urb(hfa384x_t *hw, gfp_t memflags) hw->rx_urb_skb = skb; result = -ENOLINK; - if (!hw->wlandev->hwremoved && !test_bit(WORK_RX_HALT, &hw->usb_flags)) { + if (!hw->wlandev->hwremoved && + !test_bit(WORK_RX_HALT, &hw->usb_flags)) { result = SUBMIT_URB(&hw->rx_urb, memflags); /* Check whether we need to reset the RX pipe */ @@ -451,7 +450,7 @@ static void hfa384x_usb_defer(struct work_struct *data) if (test_bit(WORK_RX_HALT, &hw->usb_flags)) { int ret; - usb_kill_urb(&hw->rx_urb); /* Cannot be holding spinlock! */ + usb_kill_urb(&hw->rx_urb); /* Cannot be holding spinlock! */ ret = usb_clear_halt(hw->usb, hw->endp_in); if (ret != 0) { @@ -668,26 +667,26 @@ usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp, * when processing a CTLX that returns a hfa384x_cmdresult_t structure. ----------------------------------------------------------------*/ struct usbctlx_cmd_completor { - usbctlx_completor_t head; + struct usbctlx_completor head; const hfa384x_usb_cmdresp_t *cmdresp; hfa384x_cmdresult_t *result; }; -typedef struct usbctlx_cmd_completor usbctlx_cmd_completor_t; -static int usbctlx_cmd_completor_fn(usbctlx_completor_t *head) +static inline int usbctlx_cmd_completor_fn(struct usbctlx_completor *head) { - usbctlx_cmd_completor_t *complete = (usbctlx_cmd_completor_t *) head; + struct usbctlx_cmd_completor *complete; + + complete = (struct usbctlx_cmd_completor *) head; return usbctlx_get_status(complete->cmdresp, complete->result); } -static inline usbctlx_completor_t *init_cmd_completor(usbctlx_cmd_completor_t * - completor, - const - hfa384x_usb_cmdresp_t * - cmdresp, - hfa384x_cmdresult_t * - result) +static inline struct usbctlx_completor *init_cmd_completor( + struct usbctlx_cmd_completor + *completor, + const hfa384x_usb_cmdresp_t + *cmdresp, + hfa384x_cmdresult_t *result) { completor->head.complete = usbctlx_cmd_completor_fn; completor->cmdresp = cmdresp; @@ -701,19 +700,19 @@ static inline usbctlx_completor_t *init_cmd_completor(usbctlx_cmd_completor_t * * when processing a CTLX that reads a RID. ----------------------------------------------------------------*/ struct usbctlx_rrid_completor { - usbctlx_completor_t head; + struct usbctlx_completor head; const hfa384x_usb_rridresp_t *rridresp; void *riddata; unsigned int riddatalen; }; -typedef struct usbctlx_rrid_completor usbctlx_rrid_completor_t; -static int usbctlx_rrid_completor_fn(usbctlx_completor_t *head) +static int usbctlx_rrid_completor_fn(struct usbctlx_completor *head) { - usbctlx_rrid_completor_t *complete = (usbctlx_rrid_completor_t *) head; + struct usbctlx_rrid_completor *complete; hfa384x_rridresult_t rridresult; + complete = (struct usbctlx_rrid_completor *) head; usbctlx_get_rridresult(complete->rridresp, &rridresult); /* Validate the length, note body len calculation in bytes */ @@ -729,12 +728,13 @@ static int usbctlx_rrid_completor_fn(usbctlx_completor_t *head) return 0; } -static inline usbctlx_completor_t *init_rrid_completor(usbctlx_rrid_completor_t - *completor, - const - hfa384x_usb_rridresp_t * - rridresp, void *riddata, - unsigned int riddatalen) +static inline struct usbctlx_completor *init_rrid_completor( + struct usbctlx_rrid_completor + *completor, + const hfa384x_usb_rridresp_t + *rridresp, + void *riddata, + unsigned int riddatalen) { completor->head.complete = usbctlx_rrid_completor_fn; completor->rridresp = rridresp; @@ -747,14 +747,14 @@ static inline usbctlx_completor_t *init_rrid_completor(usbctlx_rrid_completor_t * Completor object: * Interprets the results of a synchronous RID-write ----------------------------------------------------------------*/ -typedef usbctlx_cmd_completor_t usbctlx_wrid_completor_t; +typedef struct usbctlx_cmd_completor usbctlx_wrid_completor_t; #define init_wrid_completor init_cmd_completor /*---------------------------------------------------------------- * Completor object: * Interprets the results of a synchronous memory-write ----------------------------------------------------------------*/ -typedef usbctlx_cmd_completor_t usbctlx_wmem_completor_t; +typedef struct usbctlx_cmd_completor usbctlx_wmem_completor_t; #define init_wmem_completor init_cmd_completor /*---------------------------------------------------------------- @@ -762,7 +762,7 @@ typedef usbctlx_cmd_completor_t usbctlx_wmem_completor_t; * Interprets the results of a synchronous memory-read ----------------------------------------------------------------*/ struct usbctlx_rmem_completor { - usbctlx_completor_t head; + struct usbctlx_completor head; const hfa384x_usb_rmemresp_t *rmemresp; void *data; @@ -770,7 +770,7 @@ struct usbctlx_rmem_completor { }; typedef struct usbctlx_rmem_completor usbctlx_rmem_completor_t; -static int usbctlx_rmem_completor_fn(usbctlx_completor_t *head) +static int usbctlx_rmem_completor_fn(struct usbctlx_completor *head) { usbctlx_rmem_completor_t *complete = (usbctlx_rmem_completor_t *) head; @@ -779,11 +779,13 @@ static int usbctlx_rmem_completor_fn(usbctlx_completor_t *head) return 0; } -static inline usbctlx_completor_t *init_rmem_completor(usbctlx_rmem_completor_t - *completor, - hfa384x_usb_rmemresp_t - *rmemresp, void *data, - unsigned int len) +static inline struct usbctlx_completor *init_rmem_completor( + usbctlx_rmem_completor_t + *completor, + hfa384x_usb_rmemresp_t + *rmemresp, + void *data, + unsigned int len) { completor->head.complete = usbctlx_rmem_completor_fn; completor->rmemresp = rmemresp; @@ -1226,7 +1228,7 @@ int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis) * * Arguments: * hw device structure -* ctlx CTLX ptr +* ctlx CTLX ptr * completor functor object to decide what to * do with the CTLX's result. * @@ -1244,7 +1246,7 @@ int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis) ----------------------------------------------------------------*/ static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx, - usbctlx_completor_t *completor) + struct usbctlx_completor *completor) { unsigned long flags; int result; @@ -1359,7 +1361,7 @@ cleanup: ----------------------------------------------------------------*/ static int hfa384x_docmd(hfa384x_t *hw, - CMD_MODE mode, + enum cmd_mode mode, hfa384x_metacmd_t *cmd, ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data) { @@ -1394,7 +1396,7 @@ hfa384x_docmd(hfa384x_t *hw, if (result != 0) { kfree(ctlx); } else if (mode == DOWAIT) { - usbctlx_cmd_completor_t completor; + struct usbctlx_cmd_completor completor; result = hfa384x_usbctlx_complete_sync(hw, ctlx, @@ -1448,7 +1450,7 @@ done: ----------------------------------------------------------------*/ static int hfa384x_dorrid(hfa384x_t *hw, - CMD_MODE mode, + enum cmd_mode mode, u16 rid, void *riddata, unsigned int riddatalen, @@ -1481,7 +1483,7 @@ hfa384x_dorrid(hfa384x_t *hw, if (result != 0) { kfree(ctlx); } else if (mode == DOWAIT) { - usbctlx_rrid_completor_t completor; + struct usbctlx_rrid_completor completor; result = hfa384x_usbctlx_complete_sync(hw, ctlx, @@ -1506,7 +1508,7 @@ done: * * Arguments: * hw device structure -* CMD_MODE DOWAIT or DOASYNC +* enum cmd_mode DOWAIT or DOASYNC * rid RID code * riddata Data portion of RID formatted for MAC * riddatalen Length of the data portion in bytes @@ -1529,7 +1531,7 @@ done: ----------------------------------------------------------------*/ static int hfa384x_dowrid(hfa384x_t *hw, - CMD_MODE mode, + enum cmd_mode mode, u16 rid, void *riddata, unsigned int riddatalen, @@ -1616,7 +1618,7 @@ done: ----------------------------------------------------------------*/ static int hfa384x_dormem(hfa384x_t *hw, - CMD_MODE mode, + enum cmd_mode mode, u16 page, u16 offset, void *data, @@ -1707,7 +1709,7 @@ done: ----------------------------------------------------------------*/ static int hfa384x_dowmem(hfa384x_t *hw, - CMD_MODE mode, + enum cmd_mode mode, u16 page, u16 offset, void *data, @@ -2075,12 +2077,9 @@ int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len) (j * HFA384x_USB_RWMEM_MAXLEN); writepage = HFA384x_ADDR_CMD_MKPAGE(dlbufaddr + - (j * - HFA384x_USB_RWMEM_MAXLEN)); - writeoffset = - HFA384x_ADDR_CMD_MKOFF(dlbufaddr + - (j * - HFA384x_USB_RWMEM_MAXLEN)); + (j * HFA384x_USB_RWMEM_MAXLEN)); + writeoffset = HFA384x_ADDR_CMD_MKOFF(dlbufaddr + + (j * HFA384x_USB_RWMEM_MAXLEN)); writelen = burnlen - (j * HFA384x_USB_RWMEM_MAXLEN); writelen = writelen > HFA384x_USB_RWMEM_MAXLEN ? @@ -2133,7 +2132,7 @@ exit_proc: * 0 success * >0 f/w reported error - f/w status code * <0 driver reported error -* -ENODATA length mismatch between argument and retrieved +* -ENODATA length mismatch between argument and retrieved * record. * * Side effects: @@ -2451,7 +2450,9 @@ int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len) currpage = HFA384x_ADDR_CMD_MKPAGE(pdaloc[i].cardaddr); curroffset = HFA384x_ADDR_CMD_MKOFF(pdaloc[i].cardaddr); - result = hfa384x_dormem_wait(hw, currpage, curroffset, buf, len); /* units of bytes */ + /* units of bytes */ + result = hfa384x_dormem_wait(hw, currpage, curroffset, buf, + len); if (result) { printk(KERN_WARNING @@ -2611,20 +2612,19 @@ int hfa384x_drvr_start(hfa384x_t *hw) if (result1 != 0) { if (result2 != 0) { printk(KERN_ERR - "cmd_initialize() failed on two attempts, results %d and %d\n", - result1, result2); + "cmd_initialize() failed on two attempts," + " results %d and %d\n", result1, result2); usb_kill_urb(&hw->rx_urb); goto done; } else { pr_debug("First cmd_initialize() failed (result %d),\n", result1); - pr_debug - ("but second attempt succeeded. All should be ok\n"); + pr_debug("but second attempt succeeded." + " All should be ok\n"); } } else if (result2 != 0) { - printk(KERN_WARNING - "First cmd_initialize() succeeded, but second attempt failed (result=%d)\n", - result2); + printk(KERN_WARNING "First cmd_initialize() succeeded," + " but second attempt failed (result=%d)\n", result2); printk(KERN_WARNING "Most likely the card will be functional\n"); goto done; @@ -3382,8 +3382,9 @@ retry: * our request has been acknowledged. Odd, * but our OUT URB is still alive... */ - pr_debug - ("Causality violation: please reboot Universe, or email linux-wlan-devel@lists.linux-wlan.com\n"); + pr_debug("Causality violation: " + "please reboot Universe, or email " + "linux-wlan-devel@lists.linux-wlan.com\n"); ctlx->state = CTLX_RESP_COMPLETE; break; @@ -3442,7 +3443,7 @@ static void hfa384x_usbin_txcompl(wlandevice_t *wlandev, { u16 status; - status = le16_to_cpu(usbin->type); /* yeah I know it says type... */ + status = le16_to_cpu(usbin->type); /* yeah I know it says type... */ /* Was there an error? */ if (HFA384x_TXSTATUS_ISERROR(status)) @@ -3583,7 +3584,7 @@ static void hfa384x_int_rxmonitor(wlandevice_t *wlandev, struct sk_buff *skb; hfa384x_t *hw = wlandev->priv; - /* Don't forget the status, time, and data_len fields are in host order */ + /* Remember the status, time, and data_len fields are in host order */ /* Figure out how big the frame is */ fc = le16_to_cpu(rxdesc->frame_control); hdrlen = p80211_headerlen(fc); @@ -3632,7 +3633,8 @@ static void hfa384x_int_rxmonitor(wlandevice_t *wlandev, caphdr->encoding = htonl(1); /* cck */ } - /* Copy the 802.11 header to the skb (ctl frames may be less than a full header) */ + /* Copy the 802.11 header to the skb + (ctl frames may be less than a full header) */ datap = skb_put(skb, hdrlen); memcpy(datap, &(rxdesc->frame_control), hdrlen); @@ -3644,7 +3646,8 @@ static void hfa384x_int_rxmonitor(wlandevice_t *wlandev, /* check for unencrypted stuff if WEP bit set. */ if (*(datap - hdrlen + 1) & 0x40) /* wep set */ if ((*(datap) == 0xaa) && (*(datap + 1) == 0xaa)) - *(datap - hdrlen + 1) &= 0xbf; /* clear wep; it's the 802.2 header! */ + /* clear wep; it's the 802.2 header! */ + *(datap - hdrlen + 1) &= 0xbf; } if (hw->sniff_fcs) { @@ -3845,10 +3848,10 @@ retry: default: /* This is NOT a valid CTLX "success" state! */ - printk(KERN_ERR - "Illegal CTLX[%d] success state(%s, %d) in OUT URB\n", - le16_to_cpu(ctlx->outbuf.type), - ctlxstr(ctlx->state), urb->status); + printk(KERN_ERR "Illegal CTLX[%d]" + " success state(%s, %d) in OUT URB\n", + le16_to_cpu(ctlx->outbuf.type), + ctlxstr(ctlx->state), urb->status); break; } /* switch */ } else { -- cgit v1.2.3 From 69121fa8dc596a574a6c652c1717861eacc8dd8b Mon Sep 17 00:00:00 2001 From: Jaakko Niemelä Date: Mon, 8 Mar 2010 23:24:44 +0200 Subject: Staging: comedi: fix space before tabs coding style issue in adl_pci6208.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a patch to the adl_pci6208.c file that fixes up a space before tabs warning found by checkpatch.pl tool. Signed-off-by: Jaakko Niemelä Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci6208.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 6925faaf5293..712b9e0788b6 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -54,7 +54,7 @@ References: #include "../comedidev.h" #include "comedi_pci.h" -#define PCI6208_DRIVER_NAME "adl_pci6208" +#define PCI6208_DRIVER_NAME "adl_pci6208" /* Board descriptions */ struct pci6208_board { @@ -134,10 +134,10 @@ static int pci6208_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); /* static int pci6208_dio_insn_bits (struct comedi_device *dev, - * struct comedi_subdevice *s, */ + * struct comedi_subdevice *s, */ /* struct comedi_insn *insn,unsigned int *data); */ /* static int pci6208_dio_insn_config(struct comedi_device *dev, - * struct comedi_subdevice *s, */ + * struct comedi_subdevice *s, */ /* struct comedi_insn *insn,unsigned int *data); */ /* @@ -268,7 +268,7 @@ static int pci6208_ao_rinsn(struct comedi_device *dev, * This allows packed reading/writing of the DIO channels. The * comedi core can convert between insn_bits and insn_read/write */ /* static int pci6208_dio_insn_bits(struct comedi_device *dev, - * struct comedi_subdevice *s, */ + * struct comedi_subdevice *s, */ /* struct comedi_insn *insn,unsigned int *data) */ /* { */ /* if(insn->n!=2)return -EINVAL; */ @@ -293,7 +293,7 @@ static int pci6208_ao_rinsn(struct comedi_device *dev, /* } */ /* static int pci6208_dio_insn_config(struct comedi_device *dev, - * struct comedi_subdevice *s, */ + * struct comedi_subdevice *s, */ /* struct comedi_insn *insn,unsigned int *data) */ /* { */ /* int chan=CR_CHAN(insn->chanspec); */ -- cgit v1.2.3 From b9eafe438051f4dfde53227e609c932642d6dc8f Mon Sep 17 00:00:00 2001 From: Eli Lindsey Date: Tue, 9 Mar 2010 00:15:32 -0600 Subject: staging: frontier: switch to strict_strtoul in tranzport.c This is a patch to tranzport.c that changes a use of simple_strtoul to strict_strtoul at the suggestion of checkpatch.pl Signed-off-by: Eli Lindsey Signed-off-by: Greg Kroah-Hartman --- drivers/staging/frontier/tranzport.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c index 1f91001b1347..f9ab4f32daa8 100644 --- a/drivers/staging/frontier/tranzport.c +++ b/drivers/staging/frontier/tranzport.c @@ -198,7 +198,9 @@ static void usb_tranzport_abort_transfers(struct usb_tranzport *dev) { \ struct usb_interface *intf = to_usb_interface(dev); \ struct usb_tranzport *t = usb_get_intfdata(intf); \ - int temp = simple_strtoul(buf, NULL, 10); \ + unsigned long temp; \ + if (strict_strtoul(buf, 10, &temp)) \ + return -EINVAL; \ t->value = temp; \ return count; \ } \ -- cgit v1.2.3 From 3504e0c87892c272d9784e12918910d74077da0d Mon Sep 17 00:00:00 2001 From: Eli Lindsey Date: Tue, 9 Mar 2010 00:15:33 -0600 Subject: staging: frontier: switch semaphores to mutexes This patch changes the use of semaphores in alphatrack.c and tranzport.c to mutexes at the suggestion of checkpatch.pl Signed-off-by: Eli Lindsey Signed-off-by: Greg Kroah-Hartman --- drivers/staging/frontier/alphatrack.c | 28 ++++++++++++++-------------- drivers/staging/frontier/tranzport.c | 28 ++++++++++++++-------------- 2 files changed, 28 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/frontier/alphatrack.c b/drivers/staging/frontier/alphatrack.c index ce4d663a3e54..4e52105e6070 100644 --- a/drivers/staging/frontier/alphatrack.c +++ b/drivers/staging/frontier/alphatrack.c @@ -134,7 +134,7 @@ MODULE_PARM_DESC(min_interrupt_out_interval, /* Structure to hold all of our device specific stuff */ struct usb_alphatrack { - struct semaphore sem; /* locks this structure */ + struct mutex mtx; /* locks this structure */ struct usb_interface *intf; /* save off the usb interface pointer */ int open_count; /* number of times this port has been opened */ @@ -347,7 +347,7 @@ static int usb_alphatrack_open(struct inode *inode, struct file *file) } /* lock this device */ - if (down_interruptible(&dev->sem)) { + if (mutex_lock_interruptible(&dev->mtx)) { retval = -ERESTARTSYS; goto unlock_disconnect_exit; } @@ -390,7 +390,7 @@ static int usb_alphatrack_open(struct inode *inode, struct file *file) file->private_data = dev; unlock_exit: - up(&dev->sem); + mutex_unlock(&dev->mtx); unlock_disconnect_exit: mutex_unlock(&disconnect_mutex); @@ -413,7 +413,7 @@ static int usb_alphatrack_release(struct inode *inode, struct file *file) goto exit; } - if (down_interruptible(&dev->sem)) { + if (mutex_lock_interruptible(&dev->mtx)) { retval = -ERESTARTSYS; goto exit; } @@ -425,7 +425,7 @@ static int usb_alphatrack_release(struct inode *inode, struct file *file) if (dev->intf == NULL) { /* the device was unplugged before the file was released */ - up(&dev->sem); + mutex_unlock(&dev->mtx); /* unlock here as usb_alphatrack_delete frees dev */ usb_alphatrack_delete(dev); retval = -ENODEV; @@ -441,7 +441,7 @@ static int usb_alphatrack_release(struct inode *inode, struct file *file) dev->open_count = 0; unlock_exit: - up(&dev->sem); + mutex_unlock(&dev->mtx); exit: return retval; @@ -486,7 +486,7 @@ static ssize_t usb_alphatrack_read(struct file *file, char __user *buffer, goto exit; /* lock this object */ - if (down_interruptible(&dev->sem)) { + if (mutex_lock_interruptible(&dev->mtx)) { retval = -ERESTARTSYS; goto exit; } @@ -532,7 +532,7 @@ static ssize_t usb_alphatrack_read(struct file *file, char __user *buffer, unlock_exit: /* unlock the device */ - up(&dev->sem); + mutex_unlock(&dev->mtx); exit: return retval; @@ -556,7 +556,7 @@ static ssize_t usb_alphatrack_write(struct file *file, goto exit; /* lock this object */ - if (down_interruptible(&dev->sem)) { + if (mutex_lock_interruptible(&dev->mtx)) { retval = -ERESTARTSYS; goto exit; } @@ -627,7 +627,7 @@ static ssize_t usb_alphatrack_write(struct file *file, unlock_exit: /* unlock the device */ - up(&dev->sem); + mutex_unlock(&dev->mtx); exit: return retval; @@ -678,7 +678,7 @@ static int usb_alphatrack_probe(struct usb_interface *intf, dev_err(&intf->dev, "Out of memory\n"); goto exit; } - init_MUTEX(&dev->sem); + mutex_init(&dev->mtx); dev->intf = intf; init_waitqueue_head(&dev->read_wait); init_waitqueue_head(&dev->write_wait); @@ -835,7 +835,7 @@ static void usb_alphatrack_disconnect(struct usb_interface *intf) dev = usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); - down(&dev->sem); + mutex_lock(&dev->mtx); minor = intf->minor; @@ -844,11 +844,11 @@ static void usb_alphatrack_disconnect(struct usb_interface *intf) /* if the device is not opened, then we clean up right now */ if (!dev->open_count) { - up(&dev->sem); + mutex_unlock(&dev->mtx); usb_alphatrack_delete(dev); } else { dev->intf = NULL; - up(&dev->sem); + mutex_unlock(&dev->mtx); } atomic_set(&dev->writes_pending, 0); diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c index f9ab4f32daa8..eed74f0fe0b6 100644 --- a/drivers/staging/frontier/tranzport.c +++ b/drivers/staging/frontier/tranzport.c @@ -123,7 +123,7 @@ struct tranzport_cmd { /* Structure to hold all of our device specific stuff */ struct usb_tranzport { - struct semaphore sem; /* locks this structure */ + struct mutex mtx; /* locks this structure */ struct usb_interface *intf; /* save off the usb interface pointer */ int open_count; /* number of times this port opened */ struct tranzport_cmd (*ring_buffer)[RING_BUFFER_SIZE]; @@ -367,7 +367,7 @@ static int usb_tranzport_open(struct inode *inode, struct file *file) } /* lock this device */ - if (down_interruptible(&dev->sem)) { + if (mutex_lock_interruptible(&dev->mtx)) { retval = -ERESTARTSYS; goto unlock_disconnect_exit; } @@ -411,7 +411,7 @@ static int usb_tranzport_open(struct inode *inode, struct file *file) file->private_data = dev; unlock_exit: - up(&dev->sem); + mutex_unlock(&dev->mtx); unlock_disconnect_exit: mutex_unlock(&disconnect_mutex); @@ -434,7 +434,7 @@ static int usb_tranzport_release(struct inode *inode, struct file *file) goto exit; } - if (down_interruptible(&dev->sem)) { + if (mutex_lock_interruptible(&dev->mtx)) { retval = -ERESTARTSYS; goto exit; } @@ -446,7 +446,7 @@ static int usb_tranzport_release(struct inode *inode, struct file *file) if (dev->intf == NULL) { /* the device was unplugged before the file was released */ - up(&dev->sem); + mutex_unlock(&dev->mtx); /* unlock here as usb_tranzport_delete frees dev */ usb_tranzport_delete(dev); retval = -ENODEV; @@ -462,7 +462,7 @@ static int usb_tranzport_release(struct inode *inode, struct file *file) dev->open_count = 0; unlock_exit: - up(&dev->sem); + mutex_unlock(&dev->mtx); exit: return retval; @@ -512,7 +512,7 @@ static ssize_t usb_tranzport_read(struct file *file, char __user *buffer, goto exit; /* lock this object */ - if (down_interruptible(&dev->sem)) { + if (mutex_lock_interruptible(&dev->mtx)) { retval = -ERESTARTSYS; goto exit; } @@ -660,7 +660,7 @@ retval = 8; unlock_exit: /* unlock the device */ -up(&dev->sem); +mutex_unlock(&dev->mtx); exit: return retval; @@ -684,7 +684,7 @@ static ssize_t usb_tranzport_write(struct file *file, goto exit; /* lock this object */ - if (down_interruptible(&dev->sem)) { + if (mutex_lock_interruptible(&dev->mtx)) { retval = -ERESTARTSYS; goto exit; } @@ -753,7 +753,7 @@ static ssize_t usb_tranzport_write(struct file *file, unlock_exit: /* unlock the device */ - up(&dev->sem); + mutex_unlock(&dev->mtx); exit: return retval; @@ -802,7 +802,7 @@ static int usb_tranzport_probe(struct usb_interface *intf, dev_err(&intf->dev, "Out of memory\n"); goto exit; } - init_MUTEX(&dev->sem); + mutex_init(&dev->mtx); dev->intf = intf; init_waitqueue_head(&dev->read_wait); init_waitqueue_head(&dev->write_wait); @@ -942,18 +942,18 @@ static void usb_tranzport_disconnect(struct usb_interface *intf) mutex_lock(&disconnect_mutex); dev = usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); - down(&dev->sem); + mutex_lock(&dev->mtx); minor = intf->minor; /* give back our minor */ usb_deregister_dev(intf, &usb_tranzport_class); /* if the device is not opened, then we clean up right now */ if (!dev->open_count) { - up(&dev->sem); + mutex_unlock(&dev->mtx); usb_tranzport_delete(dev); } else { dev->intf = NULL; - up(&dev->sem); + mutex_unlock(&dev->mtx); } mutex_unlock(&disconnect_mutex); -- cgit v1.2.3 From ff13209b00dd4f67f676dd8567a9e95f13f4388c Mon Sep 17 00:00:00 2001 From: Ossama Othman Date: Mon, 15 Mar 2010 16:23:56 -0700 Subject: staging: Intel Restricted Access Region Handler The Intel Restricted Access Region Handler provides a buffer allocation mechanism to RAR users. Since the intended usage model is to lock out CPU access to RAR (the CPU will not be able to access RAR memory), this driver does not access RAR memory, and merely keeps track of what areas of RAR memory are in use. It has it's own simple allocator that does not rely on existing kernel allocators (SLAB, etc) since those allocators are too tightly coupled with the paging mechanism, which isn't needed for the intended RAR use cases. An mmap() implementation is provided for debugging purposes to simplify RAR memory access from the user space. However, it will effectively be a no-op when RAR access control is enabled since the CPU will not be able to access RAR. This driver should not be confused with the rar_register driver. That driver exposes an interface to access RAR registers on the Moorestown platform. The RAR handler driver relies on the rar_register driver for low level RAR register reads and writes. This patch was generated and built against the latest linux-2.6 master branch. Signed-off-by: Ossama Othman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/memrar/Kconfig | 15 + drivers/staging/memrar/Makefile | 2 + drivers/staging/memrar/TODO | 43 ++ drivers/staging/memrar/memrar.h | 155 +++++ drivers/staging/memrar/memrar_allocator.c | 432 ++++++++++++++ drivers/staging/memrar/memrar_allocator.h | 149 +++++ drivers/staging/memrar/memrar_handler.c | 937 ++++++++++++++++++++++++++++++ 9 files changed, 1736 insertions(+) create mode 100644 drivers/staging/memrar/Kconfig create mode 100644 drivers/staging/memrar/Makefile create mode 100644 drivers/staging/memrar/TODO create mode 100644 drivers/staging/memrar/memrar.h create mode 100644 drivers/staging/memrar/memrar_allocator.c create mode 100644 drivers/staging/memrar/memrar_allocator.h create mode 100644 drivers/staging/memrar/memrar_handler.c (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 5999259922e8..597e10987476 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -109,6 +109,8 @@ source "drivers/staging/vme/Kconfig" source "drivers/staging/rar_register/Kconfig" +source "drivers/staging/memrar/Kconfig" + source "drivers/staging/sep/Kconfig" source "drivers/staging/iio/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 55ff30f8bd2a..6edd9b09c2d0 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_FB_UDL) += udlfb/ obj-$(CONFIG_HYPERV) += hv/ obj-$(CONFIG_VME_BUS) += vme/ obj-$(CONFIG_RAR_REGISTER) += rar_register/ +obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/ obj-$(CONFIG_DX_SEP) += sep/ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_RAMZSWAP) += ramzswap/ diff --git a/drivers/staging/memrar/Kconfig b/drivers/staging/memrar/Kconfig new file mode 100644 index 000000000000..a5598a86f668 --- /dev/null +++ b/drivers/staging/memrar/Kconfig @@ -0,0 +1,15 @@ +config MRST_RAR_HANDLER + tristate "RAR handler driver for Intel Moorestown platform" + select RAR_REGISTER + ---help--- + This driver provides a memory management interface to + restricted access regions (RAR) available on the Intel + Moorestown platform. + + Once locked down, restricted access regions are only + accessible by specific hardware on the platform. The x86 + CPU is typically not one of those platforms. As such this + driver does not access RAR, and only provides a buffer + allocation/bookkeeping mechanism. + + If unsure, say N. diff --git a/drivers/staging/memrar/Makefile b/drivers/staging/memrar/Makefile new file mode 100644 index 000000000000..a3336c00cc5f --- /dev/null +++ b/drivers/staging/memrar/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_MRST_RAR_HANDLER) += memrar.o +memrar-y := memrar_allocator.o memrar_handler.o diff --git a/drivers/staging/memrar/TODO b/drivers/staging/memrar/TODO new file mode 100644 index 000000000000..0087447d5034 --- /dev/null +++ b/drivers/staging/memrar/TODO @@ -0,0 +1,43 @@ +RAR Handler (memrar) Driver TODO Items +====================================== + +Maintainer: Ossama Othman + +memrar.h +-------- +1. This header exposes the driver's user space and kernel space + interfaces. It should be moved to , or + something along those lines, when this memrar driver is moved out + of `staging'. + a. It would be ideal if staging/rar_register/rar_register.h was + moved to the same directory. + +memrar_allocator.[ch] +--------------------- +1. Address potential fragmentation issues with the memrar_allocator. + +2. Hide struct memrar_allocator details/fields. They need not be + exposed to the user. + a. Forward declare struct memrar_allocator. + b. Move all three struct definitions to `memrar_allocator.c' + source file. + c. Add a memrar_allocator_largest_free_area() function, or + something like that to get access to the value of the struct + memrar_allocator "largest_free_area" field. This allows the + struct memrar_allocator fields to be completely hidden from + the user. The memrar_handler code really only needs this for + statistic gathering on-demand. + d. Do the same for the "capacity" field as the + "largest_free_area" field. + +3. Move memrar_allocator.* to kernel `lib' directory since it is HW + neutral. + a. Alternatively, use lib/genalloc.c instead. + b. A kernel port of Doug Lea's malloc() implementation may also + be an option. + +memrar_handler.c +---------------- +1. Split user space interface (ioctl code) from core/kernel code, + e.g.: + memrar_handler.c -> memrar_core.c, memrar_user.c diff --git a/drivers/staging/memrar/memrar.h b/drivers/staging/memrar/memrar.h new file mode 100644 index 000000000000..0b735b827c09 --- /dev/null +++ b/drivers/staging/memrar/memrar.h @@ -0,0 +1,155 @@ +/* + * RAR Handler (/dev/memrar) internal driver API. + * Copyright (C) 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General + * Public License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * The full GNU General Public License is included in this + * distribution in the file called COPYING. + */ + + +#ifndef _MEMRAR_H +#define _MEMRAR_H + +#include +#include + + +/** + * struct RAR_stat - RAR statistics structure + * @type: Type of RAR memory (e.g., audio vs. video) + * @capacity: Total size of RAR memory region. + * @largest_block_size: Size of the largest reservable block. + * + * This structure is used for RAR_HANDLER_STAT ioctl and for the + * RAR_get_stat() user space wrapper function. + */ +struct RAR_stat { + __u32 type; + __u32 capacity; + __u32 largest_block_size; +}; + + +/** + * struct RAR_block_info - user space struct that describes RAR buffer + * @type: Type of RAR memory (e.g., audio vs. video) + * @size: Requested size of a block to be reserved in RAR. + * @handle: Handle that can be used to refer to reserved block. + * + * This is the basic structure exposed to the user space that + * describes a given RAR buffer. The buffer's underlying bus address + * is not exposed to the user. User space code refers to the buffer + * entirely by "handle". + */ +struct RAR_block_info { + __u32 type; + __u32 size; + __u32 handle; +}; + + +#define RAR_IOCTL_BASE 0xE0 + +/* Reserve RAR block. */ +#define RAR_HANDLER_RESERVE _IOWR(RAR_IOCTL_BASE, 0x00, struct RAR_block_info) + +/* Release previously reserved RAR block. */ +#define RAR_HANDLER_RELEASE _IOW(RAR_IOCTL_BASE, 0x01, __u32) + +/* Get RAR stats. */ +#define RAR_HANDLER_STAT _IOWR(RAR_IOCTL_BASE, 0x02, struct RAR_stat) + + +#ifdef __KERNEL__ + +/* -------------------------------------------------------------- */ +/* Kernel Side RAR Handler Interface */ +/* -------------------------------------------------------------- */ + +/** + * struct RAR_buffer - kernel space struct that describes RAR buffer + * @info: structure containing base RAR buffer information + * @bus_address: buffer bus address + * + * Structure that contains all information related to a given block of + * memory in RAR. It is generally only used when retrieving RAR + * related bus addresses. + * + * Note: This structure is used only by RAR-enabled drivers, and is + * not intended to be exposed to the user space. + */ +struct RAR_buffer { + struct RAR_block_info info; + dma_addr_t bus_address; +}; + +/** + * rar_reserve() - reserve RAR buffers + * @buffers: array of RAR_buffers where type and size of buffers to + * reserve are passed in, handle and bus address are + * passed out + * @count: number of RAR_buffers in the "buffers" array + * + * This function will reserve buffers in the restricted access regions + * of given types. + * + * It returns the number of successfully reserved buffers. Successful + * buffer reservations will have the corresponding bus_address field + * set to a non-zero value in the given buffers vector. + */ +extern size_t rar_reserve(struct RAR_buffer *buffers, + size_t count); + +/** + * rar_release() - release RAR buffers + * @buffers: array of RAR_buffers where handles to buffers to be + * released are passed in + * @count: number of RAR_buffers in the "buffers" array + * + * This function will release RAR buffers that were retrieved through + * a call to rar_reserve() or rar_handle_to_bus() by decrementing the + * reference count. The RAR buffer will be reclaimed when the + * reference count drops to zero. + * + * It returns the number of successfully released buffers. Successful + * releases will have their handle field set to zero in the given + * buffers vector. + */ +extern size_t rar_release(struct RAR_buffer *buffers, + size_t count); + +/** + * rar_handle_to_bus() - convert a vector of RAR handles to bus addresses + * @buffers: array of RAR_buffers containing handles to be + * converted to bus_addresses + * @count: number of RAR_buffers in the "buffers" array + + * This function will retrieve the RAR buffer bus addresses, type and + * size corresponding to the RAR handles provided in the buffers + * vector. + * + * It returns the number of successfully converted buffers. The bus + * address will be set to 0 for unrecognized handles. + * + * The reference count for each corresponding buffer in RAR will be + * incremented. Call rar_release() when done with the buffers. + */ +extern size_t rar_handle_to_bus(struct RAR_buffer *buffers, + size_t count); + + +#endif /* __KERNEL__ */ + +#endif /* _MEMRAR_H */ diff --git a/drivers/staging/memrar/memrar_allocator.c b/drivers/staging/memrar/memrar_allocator.c new file mode 100644 index 000000000000..a4f8c5846a00 --- /dev/null +++ b/drivers/staging/memrar/memrar_allocator.c @@ -0,0 +1,432 @@ +/* + * memrar_allocator 1.0: An allocator for Intel RAR. + * + * Copyright (C) 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General + * Public License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * The full GNU General Public License is included in this + * distribution in the file called COPYING. + * + * + * ------------------------------------------------------------------ + * + * This simple allocator implementation provides a + * malloc()/free()-like interface for reserving space within a + * previously reserved block of memory. It is not specific to + * any hardware, nor is it coupled with the lower level paging + * mechanism. + * + * The primary goal of this implementation is to provide a means + * to partition an arbitrary block of memory without actually + * accessing the memory or incurring any hardware side-effects + * (e.g. paging). It is, in effect, a bookkeeping mechanism for + * buffers. + */ + + +#include "memrar_allocator.h" +#include +#include +#include + + +struct memrar_allocator *memrar_create_allocator(unsigned long base, + size_t capacity, + size_t block_size) +{ + struct memrar_allocator *allocator = NULL; + struct memrar_address_ranges *first_node = NULL; + + /* + * Make sure the base address is aligned on a block_size + * boundary. + * + * @todo Is this necessary? + */ + /* base = ALIGN(base, block_size); */ + + /* Validate parameters. + * + * Make sure we can allocate the entire memory space. Zero + * capacity or block size are obviously invalid. + */ + if (base == 0 + || capacity == 0 + || block_size == 0 + || ULONG_MAX - capacity < base + || capacity < block_size) + return allocator; + + /* + * There isn't much point in creating a memory allocator that + * is only capable of holding one block but we'll allow it, + * and issue a diagnostic. + */ + WARN(capacity < block_size * 2, + "memrar: Only one block available to allocator.\n"); + + allocator = kmalloc(sizeof(*allocator), GFP_KERNEL); + + if (allocator == NULL) + return allocator; + + mutex_init(&allocator->lock); + allocator->base = base; + + /* Round the capacity down to a multiple of block_size. */ + allocator->capacity = (capacity / block_size) * block_size; + + allocator->block_size = block_size; + + allocator->largest_free_area = allocator->capacity; + + /* Initialize the handle and free lists. */ + INIT_LIST_HEAD(&allocator->allocated_list.list); + INIT_LIST_HEAD(&allocator->free_list.list); + + first_node = kmalloc(sizeof(*first_node), GFP_KERNEL); + if (first_node == NULL) { + kfree(allocator); + allocator = NULL; + } else { + /* Full range of blocks is available. */ + first_node->range.begin = base; + first_node->range.end = base + allocator->capacity; + list_add(&first_node->list, + &allocator->free_list.list); + } + + return allocator; +} + +void memrar_destroy_allocator(struct memrar_allocator *allocator) +{ + /* + * Assume that the memory allocator lock isn't held at this + * point in time. Caller must ensure that. + */ + + struct memrar_address_ranges *pos = NULL; + struct memrar_address_ranges *n = NULL; + + if (allocator == NULL) + return; + + mutex_lock(&allocator->lock); + + /* Reclaim free list resources. */ + list_for_each_entry_safe(pos, + n, + &allocator->free_list.list, + list) { + list_del(&pos->list); + kfree(pos); + } + + mutex_unlock(&allocator->lock); + + kfree(allocator); +} + +unsigned long memrar_allocator_alloc(struct memrar_allocator *allocator, + size_t size) +{ + struct memrar_address_ranges *pos = NULL; + + size_t num_blocks; + unsigned long reserved_bytes; + + /* + * Address of allocated buffer. We assume that zero is not a + * valid address. + */ + unsigned long addr = 0; + + if (allocator == NULL || size == 0) + return addr; + + /* Reserve enough blocks to hold the amount of bytes requested. */ + num_blocks = DIV_ROUND_UP(size, allocator->block_size); + + reserved_bytes = num_blocks * allocator->block_size; + + mutex_lock(&allocator->lock); + + if (reserved_bytes > allocator->largest_free_area) { + mutex_unlock(&allocator->lock); + return addr; + } + + /* + * Iterate through the free list to find a suitably sized + * range of free contiguous memory blocks. + * + * We also take the opportunity to reset the size of the + * largest free area size statistic. + */ + list_for_each_entry(pos, &allocator->free_list.list, list) { + struct memrar_address_range * const fr = &pos->range; + size_t const curr_size = fr->end - fr->begin; + + if (curr_size >= reserved_bytes && addr == 0) { + struct memrar_address_range *range = NULL; + struct memrar_address_ranges * const new_node = + kmalloc(sizeof(*new_node), GFP_KERNEL); + + if (new_node == NULL) + break; + + list_add(&new_node->list, + &allocator->allocated_list.list); + + /* + * Carve out area of memory from end of free + * range. + */ + range = &new_node->range; + range->end = fr->end; + fr->end -= reserved_bytes; + range->begin = fr->end; + addr = range->begin; + + /* + * Check if largest area has decreased in + * size. We'll need to continue scanning for + * the next largest area if it has. + */ + if (curr_size == allocator->largest_free_area) + allocator->largest_free_area -= + reserved_bytes; + else + break; + } + + /* + * Reset largest free area size statistic as needed, + * but only if we've actually allocated memory. + */ + if (addr != 0 + && curr_size > allocator->largest_free_area) { + allocator->largest_free_area = curr_size; + break; + } + } + + mutex_unlock(&allocator->lock); + + return addr; +} + +long memrar_allocator_free(struct memrar_allocator *allocator, + unsigned long addr) +{ + struct list_head *pos = NULL; + struct list_head *tmp = NULL; + struct list_head *dst = NULL; + + struct memrar_address_ranges *allocated = NULL; + struct memrar_address_range const *handle = NULL; + + unsigned long old_end = 0; + unsigned long new_chunk_size = 0; + + if (allocator == NULL) + return -EINVAL; + + if (addr == 0) + return 0; /* Ignore "free(0)". */ + + mutex_lock(&allocator->lock); + + /* Find the corresponding handle. */ + list_for_each_entry(allocated, + &allocator->allocated_list.list, + list) { + if (allocated->range.begin == addr) { + handle = &allocated->range; + break; + } + } + + /* No such buffer created by this allocator. */ + if (handle == NULL) { + mutex_unlock(&allocator->lock); + return -EFAULT; + } + + /* + * Coalesce adjacent chunks of memory if possible. + * + * @note This isn't full blown coalescing since we're only + * coalescing at most three chunks of memory. + */ + list_for_each_safe(pos, tmp, &allocator->free_list.list) { + /* @todo O(n) performance. Optimize. */ + + struct memrar_address_range * const chunk = + &list_entry(pos, + struct memrar_address_ranges, + list)->range; + + /* Extend size of existing free adjacent chunk. */ + if (chunk->end == handle->begin) { + /* + * Chunk "less than" than the one we're + * freeing is adjacent. + * + * Before: + * + * +-----+------+ + * |chunk|handle| + * +-----+------+ + * + * After: + * + * +------------+ + * | chunk | + * +------------+ + */ + + struct memrar_address_ranges const * const next = + list_entry(pos->next, + struct memrar_address_ranges, + list); + + chunk->end = handle->end; + + /* + * Now check if next free chunk is adjacent to + * the current extended free chunk. + * + * Before: + * + * +------------+----+ + * | chunk |next| + * +------------+----+ + * + * After: + * + * +-----------------+ + * | chunk | + * +-----------------+ + */ + if (!list_is_singular(pos) + && chunk->end == next->range.begin) { + chunk->end = next->range.end; + list_del(pos->next); + kfree(next); + } + + list_del(&allocated->list); + + new_chunk_size = chunk->end - chunk->begin; + + goto exit_memrar_free; + + } else if (handle->end == chunk->begin) { + /* + * Chunk "greater than" than the one we're + * freeing is adjacent. + * + * +------+-----+ + * |handle|chunk| + * +------+-----+ + * + * After: + * + * +------------+ + * | chunk | + * +------------+ + */ + + struct memrar_address_ranges const * const prev = + list_entry(pos->prev, + struct memrar_address_ranges, + list); + + chunk->begin = handle->begin; + + /* + * Now check if previous free chunk is + * adjacent to the current extended free + * chunk. + * + * + * Before: + * + * +----+------------+ + * |prev| chunk | + * +----+------------+ + * + * After: + * + * +-----------------+ + * | chunk | + * +-----------------+ + */ + if (!list_is_singular(pos) + && prev->range.end == chunk->begin) { + chunk->begin = prev->range.begin; + list_del(pos->prev); + kfree(prev); + } + + list_del(&allocated->list); + + new_chunk_size = chunk->end - chunk->begin; + + goto exit_memrar_free; + + } else if (chunk->end < handle->begin + && chunk->end > old_end) { + /* Keep track of where the entry could be + * potentially moved from the "allocated" list + * to the "free" list if coalescing doesn't + * occur, making sure the "free" list remains + * sorted. + */ + old_end = chunk->end; + dst = pos; + } + } + + /* + * Nothing to coalesce. + * + * Move the entry from the "allocated" list to the "free" + * list. + */ + list_move(&allocated->list, dst); + new_chunk_size = handle->end - handle->begin; + allocated = NULL; + +exit_memrar_free: + + if (new_chunk_size > allocator->largest_free_area) + allocator->largest_free_area = new_chunk_size; + + mutex_unlock(&allocator->lock); + + kfree(allocated); + + return 0; +} + + + +/* + Local Variables: + c-file-style: "linux" + End: +*/ diff --git a/drivers/staging/memrar/memrar_allocator.h b/drivers/staging/memrar/memrar_allocator.h new file mode 100644 index 000000000000..0b80dead710f --- /dev/null +++ b/drivers/staging/memrar/memrar_allocator.h @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General + * Public License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * The full GNU General Public License is included in this + * distribution in the file called COPYING. + */ + +#ifndef MEMRAR_ALLOCATOR_H +#define MEMRAR_ALLOCATOR_H + + +#include +#include +#include +#include + + +/** + * struct memrar_address_range - struct that describes a memory range + * @begin: Beginning of available address range. + * @end: End of available address range, one past the end, + * i.e. [begin, end). + */ +struct memrar_address_range { +/* private: internal use only */ + unsigned long begin; + unsigned long end; +}; + +/** + * struct memrar_address_ranges - list of areas of memory. + * @list: Linked list of address ranges. + * @range: Memory address range corresponding to given list node. + */ +struct memrar_address_ranges { +/* private: internal use only */ + struct list_head list; + struct memrar_address_range range; +}; + +/** + * struct memrar_allocator - encapsulation of the memory allocator state + * @lock: Lock used to synchronize access to the memory + * allocator state. + * @base: Base (start) address of the allocator memory + * space. + * @capacity: Size of the allocator memory space in bytes. + * @block_size: The size in bytes of individual blocks within + * the allocator memory space. + * @largest_free_area: Largest free area of memory in the allocator + * in bytes. + * @allocated_list: List of allocated memory block address + * ranges. + * @free_list: List of free address ranges. + * + * This structure contains all memory allocator state, including the + * base address, capacity, free list, lock, etc. + */ +struct memrar_allocator { +/* private: internal use only */ + struct mutex lock; + unsigned long base; + size_t capacity; + size_t block_size; + size_t largest_free_area; + struct memrar_address_ranges allocated_list; + struct memrar_address_ranges free_list; +}; + +/** + * memrar_create_allocator() - create a memory allocator + * @base: Address at which the memory allocator begins. + * @capacity: Desired size of the memory allocator. This value must + * be larger than the block_size, ideally more than twice + * as large since there wouldn't be much point in using a + * memory allocator otherwise. + * @block_size: The size of individual blocks within the memory + * allocator. This value must smaller than the + * capacity. + * + * Create a memory allocator with the given capacity and block size. + * The capacity will be reduced to be a multiple of the block size, if + * necessary. + * + * Returns an instance of the memory allocator, if creation succeeds, + * otherwise zero if creation fails. Failure may occur if not enough + * kernel memory exists to create the memrar_allocator instance + * itself, or if the capacity and block_size arguments are not + * compatible or make sense. + */ +struct memrar_allocator *memrar_create_allocator(unsigned long base, + size_t capacity, + size_t block_size); + +/** + * memrar_destroy_allocator() - destroy allocator + * @allocator: The allocator being destroyed. + * + * Reclaim resources held by the memory allocator. The caller must + * explicitly free all memory reserved by memrar_allocator_alloc() + * prior to calling this function. Otherwise leaks will occur. + */ +void memrar_destroy_allocator(struct memrar_allocator *allocator); + +/** + * memrar_allocator_alloc() - reserve an area of memory of given size + * @allocator: The allocator instance being used to reserve buffer. + * @size: The size in bytes of the buffer to allocate. + * + * This functions reserves an area of memory managed by the given + * allocator. It returns zero if allocation was not possible. + * Failure may occur if the allocator no longer has space available. + */ +unsigned long memrar_allocator_alloc(struct memrar_allocator *allocator, + size_t size); + +/** + * memrar_allocator_free() - release buffer starting at given address + * @allocator: The allocator instance being used to release the buffer. + * @address: The address of the buffer being released. + * + * Release an area of memory starting at the given address. Failure + * could occur if the given address is not in the address space + * managed by the allocator. Returns zero on success or an errno + * (negative value) on failure. + */ +long memrar_allocator_free(struct memrar_allocator *allocator, + unsigned long address); + +#endif /* MEMRAR_ALLOCATOR_H */ + + +/* + Local Variables: + c-file-style: "linux" + End: +*/ diff --git a/drivers/staging/memrar/memrar_handler.c b/drivers/staging/memrar/memrar_handler.c new file mode 100644 index 000000000000..4bbf66f4223d --- /dev/null +++ b/drivers/staging/memrar/memrar_handler.c @@ -0,0 +1,937 @@ +/* + * memrar_handler 1.0: An Intel restricted access region handler device + * + * Copyright (C) 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General + * Public License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * The full GNU General Public License is included in this + * distribution in the file called COPYING. + * + * ------------------------------------------------------------------- + * + * Moorestown restricted access regions (RAR) provide isolated + * areas of main memory that are only acceessible by authorized + * devices. + * + * The Intel Moorestown RAR handler module exposes a kernel space + * RAR memory management mechanism. It is essentially a + * RAR-specific allocator. + * + * Besides providing RAR buffer management, the RAR handler also + * behaves in many ways like an OS virtual memory manager. For + * example, the RAR "handles" created by the RAR handler are + * analogous to user space virtual addresses. + * + * RAR memory itself is never accessed directly by the RAR + * handler. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../rar_register/rar_register.h" + +#include "memrar.h" +#include "memrar_allocator.h" + + +#define MEMRAR_VER "1.0" + +/* + * Moorestown supports three restricted access regions. + * + * We only care about the first two, video and audio. The third, + * reserved for Chaabi and the P-unit, will be handled by their + * respective drivers. + */ +#define MRST_NUM_RAR 2 + +/* ---------------- -------------------- ------------------- */ + +/** + * struct memrar_buffer_info - struct that keeps track of all RAR buffers + * @list: Linked list of memrar_buffer_info objects. + * @buffer: Core RAR buffer information. + * @refcount: Reference count. + * @owner: File handle corresponding to process that reserved the + * block of memory in RAR. This will be zero for buffers + * allocated by other drivers instead of by a user space + * process. + * + * This structure encapsulates a link list of RAR buffers, as well as + * other characteristics specific to a given list node, such as the + * reference count on the corresponding RAR buffer. + */ +struct memrar_buffer_info { + struct list_head list; + struct RAR_buffer buffer; + struct kref refcount; + struct file *owner; +}; + +/** + * struct memrar_rar_info - characteristics of a given RAR + * @base: Base bus address of the RAR. + * @length: Length of the RAR. + * @iobase: Virtual address of RAR mapped into kernel. + * @allocator: Allocator associated with the RAR. Note the allocator + * "capacity" may be smaller than the RAR length if the + * length is not a multiple of the configured allocator + * block size. + * @buffers: Table that keeps track of all reserved RAR buffers. + * @lock: Lock used to synchronize access to RAR-specific data + * structures. + * + * Each RAR has an associated memrar_rar_info structure that describes + * where in memory the RAR is located, how large it is, and a list of + * reserved RAR buffers inside that RAR. Each RAR also has a mutex + * associated with it to reduce lock contention when operations on + * multiple RARs are performed in parallel. + */ +struct memrar_rar_info { + dma_addr_t base; + unsigned long length; + void __iomem *iobase; + struct memrar_allocator *allocator; + struct memrar_buffer_info buffers; + struct mutex lock; +}; + +/* + * Array of RAR characteristics. + */ +static struct memrar_rar_info memrars[MRST_NUM_RAR]; + +/* ---------------- -------------------- ------------------- */ + +/* Validate RAR type. */ +static inline int memrar_is_valid_rar_type(u32 type) +{ + return type == RAR_TYPE_VIDEO || type == RAR_TYPE_AUDIO; +} + +/* Check if an address/handle falls with the given RAR memory range. */ +static inline int memrar_handle_in_range(struct memrar_rar_info *rar, + u32 vaddr) +{ + unsigned long const iobase = (unsigned long) (rar->iobase); + return (vaddr >= iobase && vaddr < iobase + rar->length); +} + +/* Retrieve RAR information associated with the given handle. */ +static struct memrar_rar_info *memrar_get_rar_info(u32 vaddr) +{ + int i; + for (i = 0; i < MRST_NUM_RAR; ++i) { + struct memrar_rar_info * const rar = &memrars[i]; + if (memrar_handle_in_range(rar, vaddr)) + return rar; + } + + return NULL; +} + +/* + * Retrieve bus address from given handle. + * + * Returns address corresponding to given handle. Zero if handle is + * invalid. + */ +static dma_addr_t memrar_get_bus_address( + struct memrar_rar_info *rar, + u32 vaddr) +{ + unsigned long const iobase = (unsigned long) (rar->iobase); + + if (!memrar_handle_in_range(rar, vaddr)) + return 0; + + /* + * An assumption is made that the virtual address offset is + * the same as the bus address offset, at least based on the + * way this driver is implemented. For example, vaddr + 2 == + * baddr + 2. + * + * @todo Is that a valid assumption? + */ + return rar->base + (vaddr - iobase); +} + +/* + * Retrieve physical address from given handle. + * + * Returns address corresponding to given handle. Zero if handle is + * invalid. + */ +static dma_addr_t memrar_get_physical_address( + struct memrar_rar_info *rar, + u32 vaddr) +{ + /* + * @todo This assumes that the bus address and physical + * address are the same. That is true for Moorestown + * but not necessarily on other platforms. This + * deficiency should be addressed at some point. + */ + return memrar_get_bus_address(rar, vaddr); +} + +/* + * Core block release code. + * + * Note: This code removes the node from a list. Make sure any list + * iteration is performed using list_for_each_safe(). + */ +static void memrar_release_block_i(struct kref *ref) +{ + /* + * Last reference is being released. Remove from the table, + * and reclaim resources. + */ + + struct memrar_buffer_info * const node = + container_of(ref, struct memrar_buffer_info, refcount); + + struct RAR_block_info * const user_info = + &node->buffer.info; + + struct memrar_allocator * const allocator = + memrars[user_info->type].allocator; + + list_del(&node->list); + + memrar_allocator_free(allocator, user_info->handle); + + kfree(node); +} + +/* + * Initialize RAR parameters, such as bus addresses, etc. + */ +static int memrar_init_rar_resources(char const *devname) +{ + /* ---- Sanity Checks ---- + * 1. RAR bus addresses in both Lincroft and Langwell RAR + * registers should be the same. + * a. There's no way we can do this through IA. + * + * 2. Secure device ID in Langwell RAR registers should be set + * appropriately, e.g. only LPE DMA for the audio RAR, and + * security for the other Langwell based RAR registers. + * a. There's no way we can do this through IA. + * + * 3. Audio and video RAR registers and RAR access should be + * locked down. If not, enable RAR access control. Except + * for debugging purposes, there is no reason for them to + * be unlocked. + * a. We can only do this for the Lincroft (IA) side. + * + * @todo Should the RAR handler driver even be aware of audio + * and video RAR settings? + */ + + /* + * RAR buffer block size. + * + * We choose it to be the size of a page to simplify the + * /dev/memrar mmap() implementation and usage. Otherwise + * paging is not involved once an RAR is locked down. + */ + static size_t const RAR_BLOCK_SIZE = PAGE_SIZE; + + int z; + int found_rar = 0; + + BUG_ON(MRST_NUM_RAR != ARRAY_SIZE(memrars)); + + for (z = 0; z != MRST_NUM_RAR; ++z) { + dma_addr_t low, high; + struct memrar_rar_info * const rar = &memrars[z]; + + BUG_ON(!memrar_is_valid_rar_type(z)); + + mutex_init(&rar->lock); + + /* + * Initialize the process table before we reach any + * code that exit on failure since the finalization + * code requires an initialized list. + */ + INIT_LIST_HEAD(&rar->buffers.list); + + if (rar_get_address(z, &low, &high) != 0) { + /* No RAR is available. */ + break; + } else if (low == 0 || high == 0) { + /* + * We don't immediately break out of the loop + * since the next type of RAR may be enabled. + */ + rar->base = 0; + rar->length = 0; + rar->iobase = NULL; + rar->allocator = NULL; + continue; + } + + /* + * @todo Verify that LNC and LNW RAR register contents + * addresses, security, etc are compatible and + * consistent). + */ + + rar->length = high - low + 1; + + /* Claim RAR memory as our own. */ + if (request_mem_region(low, rar->length, devname) == NULL) { + rar->length = 0; + + pr_err("%s: Unable to claim RAR[%d] memory.\n", + devname, + z); + pr_err("%s: RAR[%d] disabled.\n", devname, z); + + /* + * Rather than break out of the loop by + * returning -EBUSY, for example, we may be + * able to claim memory of the next RAR region + * as our own. + */ + continue; + } + + rar->base = low; + + /* + * Now map it into the kernel address space. + * + * Note that the RAR memory may only be accessed by IA + * when debugging. Otherwise attempts to access the + * RAR memory when it is locked down will result in + * behavior similar to writing to /dev/null and + * reading from /dev/zero. This behavior is enforced + * by the hardware. Even if we don't access the + * memory, mapping it into the kernel provides us with + * a convenient RAR handle to bus address mapping. + */ + rar->iobase = ioremap_nocache(rar->base, rar->length); + if (rar->iobase == NULL) { + pr_err("%s: Unable to map RAR memory.\n", + devname); + return -ENOMEM; + } + + /* Initialize corresponding memory allocator. */ + rar->allocator = memrar_create_allocator( + (unsigned long) rar->iobase, + rar->length, + RAR_BLOCK_SIZE); + if (rar->allocator == NULL) + return -1; + + /* + * ------------------------------------------------- + * Make sure all RARs handled by us are locked down. + * ------------------------------------------------- + */ + + /* Enable RAR protection on the Lincroft side. */ + if (0) { + /* + * This is mostly a sanity check since the + * vendor should have locked down RAR in the + * SMIP header RAR configuration. + */ + rar_lock(z); + } else { + pr_warning("%s: LNC RAR[%d] no lock sanity check.\n", + devname, + z); + } + + /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ + /* |||||||||||||||||||||||||||||||||||||||||||||||||| */ + + /* + * It would be nice if we could verify that RAR + * protection on the Langwell side is enabled, but + * there is no way to do that from here. The + * necessary Langwell RAR registers are not accessible + * from the Lincroft (IA) side. + * + * Hopefully the ODM did the right thing and enabled + * Langwell side RAR protection in the integrated + * firmware SMIP header. + */ + + pr_info("%s: BRAR[%d] bus address range = " + "[0x%lx, 0x%lx]\n", + devname, + z, + (unsigned long) low, + (unsigned long) high); + + pr_info("%s: BRAR[%d] size = %u KiB\n", + devname, + z, + rar->allocator->capacity / 1024); + + found_rar = 1; + } + + if (!found_rar) { + /* + * No RAR support. Don't bother continuing. + * + * Note that this is not a failure. + */ + pr_info("%s: No Moorestown RAR support available.\n", + devname); + return -ENODEV; + } + + return 0; +} + +/* + * Finalize RAR resources. + */ +static void memrar_fini_rar_resources(void) +{ + int z; + struct memrar_buffer_info *pos; + struct memrar_buffer_info *tmp; + + /* + * @todo Do we need to hold a lock at this point in time? + * (module initialization failure or exit?) + */ + + for (z = MRST_NUM_RAR; z-- != 0; ) { + struct memrar_rar_info * const rar = &memrars[z]; + + /* Clean up remaining resources. */ + + list_for_each_entry_safe(pos, + tmp, + &rar->buffers.list, + list) { + kref_put(&pos->refcount, memrar_release_block_i); + } + + memrar_destroy_allocator(rar->allocator); + rar->allocator = NULL; + + iounmap(rar->iobase); + rar->iobase = NULL; + + release_mem_region(rar->base, rar->length); + rar->base = 0; + + rar->length = 0; + } +} + +static long memrar_reserve_block(struct RAR_buffer *request, + struct file *filp) +{ + struct RAR_block_info * const rinfo = &request->info; + struct RAR_buffer *buffer; + struct memrar_buffer_info *buffer_info; + u32 handle; + struct memrar_rar_info *rar = NULL; + + /* Prevent array overflow. */ + if (!memrar_is_valid_rar_type(rinfo->type)) + return -EINVAL; + + rar = &memrars[rinfo->type]; + + /* Reserve memory in RAR. */ + handle = memrar_allocator_alloc(rar->allocator, rinfo->size); + if (handle == 0) + return -ENOMEM; + + buffer_info = kmalloc(sizeof(*buffer_info), GFP_KERNEL); + + if (buffer_info == NULL) { + memrar_allocator_free(rar->allocator, handle); + return -ENOMEM; + } + + buffer = &buffer_info->buffer; + buffer->info.type = rinfo->type; + buffer->info.size = rinfo->size; + + /* Memory handle corresponding to the bus address. */ + buffer->info.handle = handle; + buffer->bus_address = memrar_get_bus_address(rar, handle); + + /* + * Keep track of owner so that we can later cleanup if + * necessary. + */ + buffer_info->owner = filp; + + kref_init(&buffer_info->refcount); + + mutex_lock(&rar->lock); + list_add(&buffer_info->list, &rar->buffers.list); + mutex_unlock(&rar->lock); + + rinfo->handle = buffer->info.handle; + request->bus_address = buffer->bus_address; + + return 0; +} + +static long memrar_release_block(u32 addr) +{ + struct memrar_buffer_info *pos; + struct memrar_buffer_info *tmp; + struct memrar_rar_info * const rar = memrar_get_rar_info(addr); + long result = -EINVAL; + + if (rar == NULL) + return -EFAULT; + + mutex_lock(&rar->lock); + + /* + * Iterate through the buffer list to find the corresponding + * buffer to be released. + */ + list_for_each_entry_safe(pos, + tmp, + &rar->buffers.list, + list) { + struct RAR_block_info * const info = + &pos->buffer.info; + + /* + * Take into account handle offsets that may have been + * added to the base handle, such as in the following + * scenario: + * + * u32 handle = base + offset; + * rar_handle_to_bus(handle); + * rar_release(handle); + */ + if (addr >= info->handle + && addr < (info->handle + info->size) + && memrar_is_valid_rar_type(info->type)) { + kref_put(&pos->refcount, memrar_release_block_i); + result = 0; + break; + } + } + + mutex_unlock(&rar->lock); + + return result; +} + +static long memrar_get_stat(struct RAR_stat *r) +{ + long result = -EINVAL; + + if (likely(r != NULL) && memrar_is_valid_rar_type(r->type)) { + struct memrar_allocator * const allocator = + memrars[r->type].allocator; + + BUG_ON(allocator == NULL); + + /* + * Allocator capacity doesn't change over time. No + * need to synchronize. + */ + r->capacity = allocator->capacity; + + mutex_lock(&allocator->lock); + + r->largest_block_size = allocator->largest_free_area; + + mutex_unlock(&allocator->lock); + + result = 0; + } + + return result; +} + +static long memrar_ioctl(struct file *filp, + unsigned int cmd, + unsigned long arg) +{ + void __user *argp = (void __user *)arg; + long result = 0; + + struct RAR_buffer buffer; + struct RAR_block_info * const request = &buffer.info; + struct RAR_stat rar_info; + u32 rar_handle; + + switch (cmd) { + case RAR_HANDLER_RESERVE: + if (copy_from_user(request, + argp, + sizeof(*request))) + return -EFAULT; + + result = memrar_reserve_block(&buffer, filp); + if (result != 0) + return result; + + return copy_to_user(argp, request, sizeof(*request)); + + case RAR_HANDLER_RELEASE: + if (copy_from_user(&rar_handle, + argp, + sizeof(rar_handle))) + return -EFAULT; + + return memrar_release_block(rar_handle); + + case RAR_HANDLER_STAT: + if (copy_from_user(&rar_info, + argp, + sizeof(rar_info))) + return -EFAULT; + + /* + * Populate the RAR_stat structure based on the RAR + * type given by the user + */ + if (memrar_get_stat(&rar_info) != 0) + return -EINVAL; + + /* + * @todo Do we need to verify destination pointer + * "argp" is non-zero? Is that already done by + * copy_to_user()? + */ + return copy_to_user(argp, + &rar_info, + sizeof(rar_info)) ? -EFAULT : 0; + + default: + return -ENOTTY; + } + + return 0; +} + +static int memrar_mmap(struct file *filp, struct vm_area_struct *vma) +{ + /* + * This mmap() implementation is predominantly useful for + * debugging since the CPU will be prevented from accessing + * RAR memory by the hardware when RAR is properly locked + * down. + * + * In order for this implementation to be useful RAR memory + * must be not be locked down. However, we only want to do + * that when debugging. DO NOT leave RAR memory unlocked in a + * deployed device that utilizes RAR. + */ + + size_t const size = vma->vm_end - vma->vm_start; + + /* Users pass the RAR handle as the mmap() offset parameter. */ + unsigned long const handle = vma->vm_pgoff << PAGE_SHIFT; + + struct memrar_rar_info * const rar = memrar_get_rar_info(handle); + + unsigned long pfn; + + /* Invalid RAR handle or size passed to mmap(). */ + if (rar == NULL + || handle == 0 + || size > (handle - (unsigned long) rar->iobase)) + return -EINVAL; + + /* + * Retrieve physical address corresponding to the RAR handle, + * and convert it to a page frame. + */ + pfn = memrar_get_physical_address(rar, handle) >> PAGE_SHIFT; + + + pr_debug("memrar: mapping RAR range [0x%lx, 0x%lx) into user space.\n", + handle, + handle + size); + + /* + * Map RAR memory into user space. This is really only useful + * for debugging purposes since the memory won't be + * accessible, i.e. reads return zero and writes are ignored, + * when RAR access control is enabled. + */ + if (remap_pfn_range(vma, + vma->vm_start, + pfn, + size, + vma->vm_page_prot)) + return -EAGAIN; + + /* vma->vm_ops = &memrar_mem_ops; */ + + return 0; +} + +static int memrar_open(struct inode *inode, struct file *filp) +{ + /* Nothing to do yet. */ + + return 0; +} + +static int memrar_release(struct inode *inode, struct file *filp) +{ + /* Free all regions associated with the given file handle. */ + + struct memrar_buffer_info *pos; + struct memrar_buffer_info *tmp; + int z; + + for (z = 0; z != MRST_NUM_RAR; ++z) { + struct memrar_rar_info * const rar = &memrars[z]; + + mutex_lock(&rar->lock); + + list_for_each_entry_safe(pos, + tmp, + &rar->buffers.list, + list) { + if (filp == pos->owner) + kref_put(&pos->refcount, + memrar_release_block_i); + } + + mutex_unlock(&rar->lock); + } + + return 0; +} + +/* + * This function is part of the kernel space memrar driver API. + */ +size_t rar_reserve(struct RAR_buffer *buffers, size_t count) +{ + struct RAR_buffer * const end = + (buffers == NULL ? buffers : buffers + count); + struct RAR_buffer *i; + + size_t reserve_count = 0; + + for (i = buffers; i != end; ++i) { + if (memrar_reserve_block(i, NULL) == 0) + ++reserve_count; + else + i->bus_address = 0; + } + + return reserve_count; +} +EXPORT_SYMBOL(rar_reserve); + +/* + * This function is part of the kernel space memrar driver API. + */ +size_t rar_release(struct RAR_buffer *buffers, size_t count) +{ + struct RAR_buffer * const end = + (buffers == NULL ? buffers : buffers + count); + struct RAR_buffer *i; + + size_t release_count = 0; + + for (i = buffers; i != end; ++i) { + u32 * const handle = &i->info.handle; + if (memrar_release_block(*handle) == 0) { + /* + * @todo We assume we should do this each time + * the ref count is decremented. Should + * we instead only do this when the ref + * count has dropped to zero, and the + * buffer has been completely + * released/unmapped? + */ + *handle = 0; + ++release_count; + } + } + + return release_count; +} +EXPORT_SYMBOL(rar_release); + +/* + * This function is part of the kernel space driver API. + */ +size_t rar_handle_to_bus(struct RAR_buffer *buffers, size_t count) +{ + struct RAR_buffer * const end = + (buffers == NULL ? buffers : buffers + count); + struct RAR_buffer *i; + struct memrar_buffer_info *pos; + + size_t conversion_count = 0; + + /* + * Find all bus addresses corresponding to the given handles. + * + * @todo Not liking this nested loop. Optimize. + */ + for (i = buffers; i != end; ++i) { + struct memrar_rar_info * const rar = + memrar_get_rar_info(i->info.handle); + + /* + * Check if we have a bogus handle, and then continue + * with remaining buffers. + */ + if (rar == NULL) { + i->bus_address = 0; + continue; + } + + mutex_lock(&rar->lock); + + list_for_each_entry(pos, &rar->buffers.list, list) { + struct RAR_block_info * const user_info = + &pos->buffer.info; + + /* + * Take into account handle offsets that may + * have been added to the base handle, such as + * in the following scenario: + * + * u32 handle = base + offset; + * rar_handle_to_bus(handle); + */ + + if (i->info.handle >= user_info->handle + && i->info.handle < (user_info->handle + + user_info->size)) { + u32 const offset = + i->info.handle - user_info->handle; + + i->info.type = user_info->type; + i->info.size = user_info->size - offset; + i->bus_address = + pos->buffer.bus_address + + offset; + + /* Increment the reference count. */ + kref_get(&pos->refcount); + + ++conversion_count; + break; + } else { + i->bus_address = 0; + } + } + + mutex_unlock(&rar->lock); + } + + return conversion_count; +} +EXPORT_SYMBOL(rar_handle_to_bus); + +static const struct file_operations memrar_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = memrar_ioctl, + .mmap = memrar_mmap, + .open = memrar_open, + .release = memrar_release, +}; + +static struct miscdevice memrar_miscdev = { + .minor = MISC_DYNAMIC_MINOR, /* dynamic allocation */ + .name = "memrar", /* /dev/memrar */ + .fops = &memrar_fops +}; + +static char const banner[] __initdata = + KERN_INFO + "Intel RAR Handler: " MEMRAR_VER " initialized.\n"; + +static int memrar_registration_callback(void *ctx) +{ + /* + * We initialize the RAR parameters early on so that we can + * discontinue memrar device initialization and registration + * if suitably configured RARs are not available. + */ + int result = memrar_init_rar_resources(memrar_miscdev.name); + + if (result != 0) + return result; + + result = misc_register(&memrar_miscdev); + + if (result != 0) { + pr_err("%s: misc_register() failed.\n", + memrar_miscdev.name); + + /* Clean up resources previously reserved. */ + memrar_fini_rar_resources(); + } + + return result; +} + +static int __init memrar_init(void) +{ + printk(banner); + + return register_rar(&memrar_registration_callback, 0); +} + +static void __exit memrar_exit(void) +{ + memrar_fini_rar_resources(); + + misc_deregister(&memrar_miscdev); +} + + +module_init(memrar_init); +module_exit(memrar_exit); + + +MODULE_AUTHOR("Ossama Othman "); +MODULE_DESCRIPTION("Intel Restricted Access Region Handler"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(MISC_DYNAMIC_MINOR); +MODULE_VERSION(MEMRAR_VER); + + + +/* + Local Variables: + c-file-style: "linux" + End: +*/ -- cgit v1.2.3 From b852fdcefc782b6751f96a8ea09471efd844b6bf Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 9 Mar 2010 17:42:33 -0800 Subject: Staging: hv: use network device stats The network device structure has space already reserved for statistics. Compile tested only. Signed-off-by: Stephen Hemminger Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/TODO | 1 - drivers/staging/hv/netvsc_drv.c | 31 +++++++++---------------------- 2 files changed, 9 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/TODO b/drivers/staging/hv/TODO index 01d4bd052cf5..66a89c809dd3 100644 --- a/drivers/staging/hv/TODO +++ b/drivers/staging/hv/TODO @@ -7,7 +7,6 @@ TODO: - see if the vmbus can be merged with the other virtual busses in the kernel - audit the network driver - - use existing net_device_stats struct in network device - checking for carrier inside open is wrong, network device API confusion?? - audit the block driver diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 5ed6e6e7db67..e87a7c205d85 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -43,7 +43,6 @@ struct net_device_context { /* point back to our device context */ struct vm_device *device_ctx; - struct net_device_stats stats; }; struct netvsc_driver_context { @@ -58,13 +57,6 @@ static int netvsc_ringbuffer_size = NETVSC_DEVICE_RING_BUFFER_SIZE; /* The one and only one */ static struct netvsc_driver_context g_netvsc_drv; -static struct net_device_stats *netvsc_get_stats(struct net_device *net) -{ - struct net_device_context *net_device_ctx = netdev_priv(net); - - return &net_device_ctx->stats; -} - static void netvsc_set_multicast_list(struct net_device *net) { } @@ -78,9 +70,6 @@ static int netvsc_open(struct net_device *net) DPRINT_ENTER(NETVSC_DRV); if (netif_carrier_ok(net)) { - memset(&net_device_ctx->stats, 0, - sizeof(struct net_device_stats)); - /* Open up the device */ ret = RndisFilterOnOpen(device_obj); if (ret != 0) { @@ -224,8 +213,8 @@ retry_send: if (ret == 0) { ret = NETDEV_TX_OK; - net_device_ctx->stats.tx_bytes += skb->len; - net_device_ctx->stats.tx_packets++; + net->stats.tx_bytes += skb->len; + net->stats.tx_packets++; } else { retries++; if (retries < 4) { @@ -241,7 +230,7 @@ retry_send: DPRINT_INFO(NETVSC_DRV, "net device (%p) stopping", net); ret = NETDEV_TX_BUSY; - net_device_ctx->stats.tx_dropped++; + net->stats.tx_dropped++; netif_stop_queue(net); @@ -259,8 +248,8 @@ retry_send: } DPRINT_DBG(NETVSC_DRV, "# of xmits %lu total size %lu", - net_device_ctx->stats.tx_packets, - net_device_ctx->stats.tx_bytes); + net->stats.tx_packets, + net->stats.tx_bytes); DPRINT_EXIT(NETVSC_DRV); return ret; @@ -360,17 +349,16 @@ static int netvsc_recv_callback(struct hv_device *device_obj, switch (ret) { case NET_RX_DROP: - net_device_ctx->stats.rx_dropped++; + net->stats.rx_dropped++; break; default: - net_device_ctx->stats.rx_packets++; - net_device_ctx->stats.rx_bytes += skb->len; + net->stats.rx_packets++; + net->stats.rx_bytes += skb->len; break; } DPRINT_DBG(NETVSC_DRV, "# of recvs %lu total size %lu", - net_device_ctx->stats.rx_packets, - net_device_ctx->stats.rx_bytes); + net->stats.rx_packets, net->stats.rx_bytes); DPRINT_EXIT(NETVSC_DRV); @@ -381,7 +369,6 @@ static const struct net_device_ops device_ops = { .ndo_open = netvsc_open, .ndo_stop = netvsc_close, .ndo_start_xmit = netvsc_start_xmit, - .ndo_get_stats = netvsc_get_stats, .ndo_set_multicast_list = netvsc_set_multicast_list, }; -- cgit v1.2.3 From 9495c282baf53ec7bfffcb9dd9f40cb10d4240e0 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 9 Mar 2010 17:42:17 -0800 Subject: Staging: hv: handle skb allocation failure Some fixes to receive handling: * Dieing with assertion failure when running out of memory is not ok * Use newer alloc function to get aligned skb * Dropped statistic is supposed to be incremented only by driver it was responsible for the drop. Compile tested only. Signed-off-by: Stephen Hemminger Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/netvsc_drv.c | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index e87a7c205d85..51a56e2b43c1 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -294,7 +294,6 @@ static int netvsc_recv_callback(struct hv_device *device_obj, struct net_device_context *net_device_ctx; struct sk_buff *skb; void *data; - int ret; int i; unsigned long flags; @@ -308,12 +307,12 @@ static int netvsc_recv_callback(struct hv_device *device_obj, net_device_ctx = netdev_priv(net); - /* Allocate a skb - TODO preallocate this */ - /* Pad 2-bytes to align IP header to 16 bytes */ - skb = dev_alloc_skb(packet->TotalDataBufferLength + 2); - ASSERT(skb); - skb_reserve(skb, 2); - skb->dev = net; + /* Allocate a skb - TODO direct I/O to pages? */ + skb = netdev_alloc_skb_ip_align(net, packet->TotalDataBufferLength); + if (unlikely(!skb)) { + ++net->stats.rx_dropped; + return 0; + } /* for kmap_atomic */ local_irq_save(flags); @@ -338,25 +337,18 @@ static int netvsc_recv_callback(struct hv_device *device_obj, local_irq_restore(flags); skb->protocol = eth_type_trans(skb, net); - skb->ip_summed = CHECKSUM_NONE; + net->stats.rx_packets++; + net->stats.rx_bytes += skb->len; + /* * Pass the skb back up. Network stack will deallocate the skb when it - * is done + * is done. + * TODO - use NAPI? */ - ret = netif_rx(skb); - - switch (ret) { - case NET_RX_DROP: - net->stats.rx_dropped++; - break; - default: - net->stats.rx_packets++; - net->stats.rx_bytes += skb->len; - break; + netif_rx(skb); - } DPRINT_DBG(NETVSC_DRV, "# of recvs %lu total size %lu", net->stats.rx_packets, net->stats.rx_bytes); -- cgit v1.2.3 From 177d42821e2d662fda5bb57d31d33d215fb74fd0 Mon Sep 17 00:00:00 2001 From: Aseem Sethi Date: Wed, 10 Mar 2010 00:04:36 +0530 Subject: Staging: comedi: fix missing KERN_facility level in ni_labpc.c This is a patch to fix the "missing KERN_facility level" error found when running the checkpatch.pl script Signed-off-by: Aseem Sethi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_labpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 558e525fed37..9b840a96bafa 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -536,7 +536,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, printk("\n"); if (iobase == 0) { - printk("io base address is zero!\n"); + printk(KERN_ERR "io base address is zero!\n"); return -EINVAL; } /* request io regions for isa boards */ -- cgit v1.2.3 From b7e7031aea1215da499b51fea0ade6b92f1232af Mon Sep 17 00:00:00 2001 From: "Prashant P. Shah" Date: Tue, 9 Mar 2010 20:16:44 +0530 Subject: Staging: netwave: fixed trailing whitespace style issue in netwave_cs.c This is a patch to the netwave_cs.c file that fixes up all the trailing whitespace errors found by the checkpatch.pl tool. Signed-off-by: Prashant P. Shah Signed-off-by: Greg Kroah-Hartman --- drivers/staging/netwave/netwave_cs.c | 248 +++++++++++++++++------------------ 1 file changed, 124 insertions(+), 124 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/netwave/netwave_cs.c b/drivers/staging/netwave/netwave_cs.c index 3875a722d12b..7b3162101ecd 100644 --- a/drivers/staging/netwave/netwave_cs.c +++ b/drivers/staging/netwave/netwave_cs.c @@ -1,5 +1,5 @@ /********************************************************************* - * + * * Filename: netwave_cs.c * Version: 0.4.1 * Description: Netwave AirSurfer Wireless LAN PC Card driver @@ -10,27 +10,27 @@ * Created at: A long time ago! * Modified at: Mon Nov 10 11:54:37 1997 * Modified by: Dag Brattli - * + * * Copyright (c) 1997 University of Tromsø, Norway * * Revision History: * * 08-Nov-97 15:14:47 John Markus Bjørndalen - * - Fixed some bugs in netwave_rx and cleaned it up a bit. + * - Fixed some bugs in netwave_rx and cleaned it up a bit. * (One of the bugs would have destroyed packets when receiving - * multiple packets per interrupt). - * - Cleaned up parts of newave_hw_xmit. - * - A few general cleanups. + * multiple packets per interrupt). + * - Cleaned up parts of newave_hw_xmit. + * - A few general cleanups. * 24-Oct-97 13:17:36 Dag Brattli * - Fixed netwave_rx receive function (got updated docs) * Others: - * - Changed name from xircnw to netwave, take a look at + * - Changed name from xircnw to netwave, take a look at * http://www.netwave-wireless.com * - Some reorganizing of the code * - Removed possible race condition between interrupt handler and transmit * function * - Started to add wireless extensions, but still needs some coding - * - Added watchdog for better handling of transmission timeouts + * - Added watchdog for better handling of transmission timeouts * (hopefully this works better) ********************************************************************/ @@ -101,7 +101,7 @@ /* * Commands used in the extended command buffer - * NETWAVE_EREG_CB (0x100-0x10F) + * NETWAVE_EREG_CB (0x100-0x10F) */ #define NETWAVE_CMD_NOP 0x00 #define NETWAVE_CMD_SRC 0x01 @@ -133,7 +133,7 @@ static const unsigned int corConfIENA = 0x01; /* Interrupt enable */ static const unsigned int corConfLVLREQ = 0x40; /* Keep high */ static const unsigned int rxConfRxEna = 0x80; /* Receive Enable */ -static const unsigned int rxConfMAC = 0x20; /* MAC host receive mode*/ +static const unsigned int rxConfMAC = 0x20; /* MAC host receive mode*/ static const unsigned int rxConfPro = 0x10; /* Promiscuous */ static const unsigned int rxConfAMP = 0x08; /* Accept Multicast Packets */ static const unsigned int rxConfBcast = 0x04; /* Accept Broadcast Packets */ @@ -152,15 +152,15 @@ static const unsigned int txConfLoop = 0x01; /* Loopback mode */ /* Choose the domain, default is 0x100 */ static u_int domain = 0x100; -/* Scramble key, range from 0x0 to 0xffff. - * 0x0 is no scrambling. +/* Scramble key, range from 0x0 to 0xffff. + * 0x0 is no scrambling. */ static u_int scramble_key = 0x0; -/* Shared memory speed, in ns. The documentation states that - * the card should not be read faster than every 400ns. - * This timing should be provided by the HBA. If it becomes a - * problem, try setting mem_speed to 400. +/* Shared memory speed, in ns. The documentation states that + * the card should not be read faster than every 400ns. + * This timing should be provided by the HBA. If it becomes a + * problem, try setting mem_speed to 400. */ static int mem_speed; @@ -229,7 +229,7 @@ struct site_survey { u_short length; u_char struct_revision; u_char roaming_state; - + u_char sp_existsFlag; u_char sp_link_quality; u_char sp_max_link_quality; @@ -239,12 +239,12 @@ struct site_survey { u_char sp_goodness; u_char sp_hotheadcount; u_char roaming_condition; - + net_addr sp; u_char numAPs; net_addr nearByAccessPoints[MAX_ESA]; -}; - +}; + typedef struct netwave_private { struct pcmcia_device *p_dev; spinlock_t spinlock; /* Serialize access to the hardware (SMP) */ @@ -261,7 +261,7 @@ typedef struct netwave_private { * The Netwave card is little-endian, so won't work for big endian * systems. */ -static inline unsigned short get_uint16(u_char __iomem *staddr) +static inline unsigned short get_uint16(u_char __iomem *staddr) { return readw(staddr); /* Return only 16 bits */ } @@ -271,38 +271,38 @@ static inline short get_int16(u_char __iomem * staddr) return readw(staddr); } -/* - * Wait until the WOC (Write Operation Complete) bit in the - * ASR (Adapter Status Register) is asserted. - * This should have aborted if it takes too long time. +/* + * Wait until the WOC (Write Operation Complete) bit in the + * ASR (Adapter Status Register) is asserted. + * This should have aborted if it takes too long time. */ static inline void wait_WOC(unsigned int iobase) { /* Spin lock */ - while ((inb(iobase + NETWAVE_REG_ASR) & 0x8) != 0x8) ; + while ((inb(iobase + NETWAVE_REG_ASR) & 0x8) != 0x8) ; } -static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase, +static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase, unsigned int iobase) { u_short resultBuffer; - /* if time since last snapshot is > 1 sec. (100 jiffies?) then take - * new snapshot, else return cached data. This is the recommended rate. + /* if time since last snapshot is > 1 sec. (100 jiffies?) then take + * new snapshot, else return cached data. This is the recommended rate. */ - if ( jiffies - priv->lastExec > 100) { - /* Take site survey snapshot */ + if ( jiffies - priv->lastExec > 100) { + /* Take site survey snapshot */ /*printk( KERN_DEBUG "Taking new snapshot. %ld\n", jiffies - priv->lastExec); */ - wait_WOC(iobase); - writeb(NETWAVE_CMD_SSS, ramBase + NETWAVE_EREG_CB + 0); - writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1); - wait_WOC(iobase); - - /* Get result and copy to cach */ - resultBuffer = readw(ramBase + NETWAVE_EREG_CRBP); - copy_from_pc( &priv->nss, ramBase+resultBuffer, - sizeof(struct site_survey)); - } + wait_WOC(iobase); + writeb(NETWAVE_CMD_SSS, ramBase + NETWAVE_EREG_CB + 0); + writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1); + wait_WOC(iobase); + + /* Get result and copy to cach */ + resultBuffer = readw(ramBase + NETWAVE_EREG_CRBP); + copy_from_pc( &priv->nss, ramBase+resultBuffer, + sizeof(struct site_survey)); + } } /* @@ -312,21 +312,21 @@ static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase, * */ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev) -{ +{ unsigned long flags; unsigned int iobase = dev->base_addr; netwave_private *priv = netdev_priv(dev); u_char __iomem *ramBase = priv->ramBase; struct iw_statistics* wstats; - + wstats = &priv->iw_stats; spin_lock_irqsave(&priv->spinlock, flags); - + netwave_snapshot( priv, ramBase, iobase); wstats->status = priv->nss.roaming_state; - wstats->qual.qual = readb( ramBase + NETWAVE_EREG_SPCQ); + wstats->qual.qual = readb( ramBase + NETWAVE_EREG_SPCQ); wstats->qual.level = readb( ramBase + NETWAVE_EREG_ISPLQ); wstats->qual.noise = readb( ramBase + NETWAVE_EREG_SPU) & 0x3f; wstats->discard.nwid = 0L; @@ -334,7 +334,7 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev) wstats->discard.misc = 0L; spin_unlock_irqrestore(&priv->spinlock, flags); - + return &priv->iw_stats; } @@ -352,8 +352,8 @@ static const struct net_device_ops netwave_netdev_ops = { /* * Function netwave_attach (void) * - * Creates an "instance" of the driver, allocating local data - * structures for one device. The device is registered with Card + * Creates an "instance" of the driver, allocating local data + * structures for one device. The device is registered with Card * Services. * * The dev_link structure is initialized, but we don't actually @@ -378,14 +378,14 @@ static int netwave_probe(struct pcmcia_device *link) /* The io structure describes IO port mapping */ link->io.NumPorts1 = 16; link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - /* link->io.NumPorts2 = 16; + /* link->io.NumPorts2 = 16; link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; */ link->io.IOAddrLines = 5; - + /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; link->irq.Handler = &netwave_interrupt; - + /* General socket configuration */ link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; @@ -457,7 +457,7 @@ static int netwave_set_nwid(struct net_device *dev, if(!wrqu->nwid.disabled) { domain = wrqu->nwid.value; - printk( KERN_DEBUG "Setting domain to 0x%x%02x\n", + printk( KERN_DEBUG "Setting domain to 0x%x%02x\n", (domain >> 8) & 0x01, domain & 0xff); wait_WOC(iobase); writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0); @@ -468,7 +468,7 @@ static int netwave_set_nwid(struct net_device *dev, /* ReEnable interrupts & restore flags */ spin_unlock_irqrestore(&priv->spinlock, flags); - + return 0; } @@ -511,7 +511,7 @@ static int netwave_set_scramble(struct net_device *dev, /* ReEnable interrupts & restore flags */ spin_unlock_irqrestore(&priv->spinlock, flags); - + return 0; } @@ -566,19 +566,19 @@ static int netwave_get_range(struct net_device *dev, /* Set the Wireless Extension versions */ range->we_version_compiled = WIRELESS_EXT; range->we_version_source = 9; /* Nothing for us in v10 and v11 */ - + /* Set information in the range struct */ range->throughput = 450 * 1000; /* don't argue on this ! */ range->min_nwid = 0x0000; range->max_nwid = 0x01FF; range->num_channels = range->num_frequency = 0; - + range->sensitivity = 0x3F; range->max_qual.qual = 255; range->max_qual.level = 255; range->max_qual.noise = 0; - + range->num_bitrates = 1; range->bitrate[0] = 1000000; /* 1 Mb/s */ @@ -614,7 +614,7 @@ static int netwave_get_snap(struct net_device *dev, /* ReEnable interrupts & restore flags */ spin_unlock_irqrestore(&priv->spinlock, flags); - + return(0); } @@ -625,8 +625,8 @@ static int netwave_get_snap(struct net_device *dev, static const struct iw_priv_args netwave_private_args[] = { /*{ cmd, set_args, get_args, name } */ - { SIOCGIPSNAP, 0, - IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof(struct site_survey), + { SIOCGIPSNAP, 0, + IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof(struct site_survey), "getsitesurvey" }, }; @@ -698,9 +698,9 @@ static const struct iw_handler_def netwave_handler_def = /* * Function netwave_pcmcia_config (link) * - * netwave_pcmcia_config() is scheduled to run after a CARD_INSERTION + * netwave_pcmcia_config() is scheduled to run after a CARD_INSERTION * event is received, to configure the PCMCIA socket, and to make the - * device available to the system. + * device available to the system. * */ @@ -758,7 +758,7 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { ret = pcmcia_request_window(link, &req, &link->win); if (ret) goto failed; - mem.CardOffset = 0x20000; mem.Page = 0; + mem.CardOffset = 0x20000; mem.Page = 0; ret = pcmcia_map_mem_page(link, link->win, &mem); if (ret) goto failed; @@ -783,7 +783,7 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { netwave_doreset(dev->base_addr, ramBase); /* Read the ethernet address and fill in the Netwave registers. */ - for (i = 0; i < 6; i++) + for (i = 0; i < 6; i++) dev->dev_addr[i] = readb(ramBase + NETWAVE_EREG_PA + i); printk(KERN_INFO "%s: Netwave: port %#3lx, irq %d, mem %lx, " @@ -795,7 +795,7 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { dev->dev_addr); /* get revision words */ - printk(KERN_DEBUG "Netwave_reset: revision %04x %04x\n", + printk(KERN_DEBUG "Netwave_reset: revision %04x %04x\n", get_uint16(ramBase + NETWAVE_EREG_ARW), get_uint16(ramBase + NETWAVE_EREG_ARW+2)); return 0; @@ -864,7 +864,7 @@ static void netwave_doreset(unsigned int ioBase, u_char __iomem *ramBase) /* * Function netwave_reset (dev) * - * Reset and restore all of the netwave registers + * Reset and restore all of the netwave registers */ static void netwave_reset(struct net_device *dev) { /* u_char state; */ @@ -879,24 +879,24 @@ static void netwave_reset(struct net_device *dev) { /* Reset card */ netwave_doreset(iobase, ramBase); printk(KERN_DEBUG "netwave_reset: Done with hardware reset\n"); - + /* Write a NOP to check the card */ wait_WOC(iobase); writeb(NETWAVE_CMD_NOP, ramBase + NETWAVE_EREG_CB + 0); writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1); - + /* Set receive conf */ wait_WOC(iobase); writeb(NETWAVE_CMD_SRC, ramBase + NETWAVE_EREG_CB + 0); writeb(rxConfRxEna + rxConfBcast, ramBase + NETWAVE_EREG_CB + 1); writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2); - + /* Set transmit conf */ wait_WOC(iobase); writeb(NETWAVE_CMD_STC, ramBase + NETWAVE_EREG_CB + 0); writeb(txConfTxEna, ramBase + NETWAVE_EREG_CB + 1); writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2); - + /* Now set the MU Domain */ printk(KERN_DEBUG "Setting domain to 0x%x%02x\n", (domain >> 8) & 0x01, domain & 0xff); wait_WOC(iobase); @@ -904,7 +904,7 @@ static void netwave_reset(struct net_device *dev) { writeb(domain & 0xff, ramBase + NETWAVE_EREG_CB + 1); writeb((domain>>8) & 0x01, ramBase + NETWAVE_EREG_CB + 2); writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3); - + /* Set scramble key */ printk(KERN_DEBUG "Setting scramble key to 0x%x\n", scramble_key); wait_WOC(iobase); @@ -914,8 +914,8 @@ static void netwave_reset(struct net_device *dev) { writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3); /* Enable interrupts, bit 4 high to keep unused - * source from interrupting us, bit 2 high to - * set interrupt enable, 567 to enable TxDN, + * source from interrupting us, bit 2 high to + * set interrupt enable, 567 to enable TxDN, * RxErr and RxRdy */ wait_WOC(iobase); @@ -926,29 +926,29 @@ static void netwave_reset(struct net_device *dev) { * skriv 80 til d000:3688 * sjekk om det ble 80 */ - + /* Enable Receiver */ wait_WOC(iobase); writeb(NETWAVE_CMD_ER, ramBase + NETWAVE_EREG_CB + 0); writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1); - + /* Set the IENA bit in COR */ wait_WOC(iobase); outb(corConfIENA + corConfLVLREQ, iobase + NETWAVE_REG_COR); } /* - * Function netwave_hw_xmit (data, len, dev) + * Function netwave_hw_xmit (data, len, dev) */ static int netwave_hw_xmit(unsigned char* data, int len, struct net_device* dev) { unsigned long flags; unsigned int TxFreeList, curBuff, - MaxData, + MaxData, DataOffset; - int tmpcount; - + int tmpcount; + netwave_private *priv = netdev_priv(dev); u_char __iomem * ramBase = priv->ramBase; unsigned int iobase = dev->base_addr; @@ -979,23 +979,23 @@ static int netwave_hw_xmit(unsigned char* data, int len, TxFreeList = get_uint16(ramBase + NETWAVE_EREG_TDP); MaxData = get_uint16(ramBase + NETWAVE_EREG_TDP+2); DataOffset = get_uint16(ramBase + NETWAVE_EREG_TDP+4); - + pr_debug("TxFreeList %x, MaxData %x, DataOffset %x\n", TxFreeList, MaxData, DataOffset); /* Copy packet to the adapter fragment buffers */ - curBuff = TxFreeList; - tmpcount = 0; + curBuff = TxFreeList; + tmpcount = 0; while (tmpcount < len) { - int tmplen = len - tmpcount; - copy_to_pc(ramBase + curBuff + DataOffset, data + tmpcount, + int tmplen = len - tmpcount; + copy_to_pc(ramBase + curBuff + DataOffset, data + tmpcount, (tmplen < MaxData) ? tmplen : MaxData); tmpcount += MaxData; - + /* Advance to next buffer */ curBuff = get_uint16(ramBase + curBuff); } - + /* Now issue transmit list */ wait_WOC(iobase); writeb(NETWAVE_CMD_TL, ramBase + NETWAVE_EREG_CB + 0); @@ -1020,7 +1020,7 @@ static netdev_tx_t netwave_start_xmit(struct sk_buff *skb, { short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; unsigned char* buf = skb->data; - + if (netwave_hw_xmit( buf, length, dev) == 1) { /* Some error, let's make them call us another time? */ netif_start_queue(dev); @@ -1028,7 +1028,7 @@ static netdev_tx_t netwave_start_xmit(struct sk_buff *skb, dev->trans_start = jiffies; } dev_kfree_skb(skb); - + return NETDEV_TX_OK; } /* netwave_start_xmit */ @@ -1036,7 +1036,7 @@ static netdev_tx_t netwave_start_xmit(struct sk_buff *skb, * Function netwave_interrupt (irq, dev_id) * * This function is the interrupt handler for the Netwave card. This - * routine will be called whenever: + * routine will be called whenever: * 1. A packet is received. * 2. A packet has successfully been transferred and the unit is * ready to transmit another packet. @@ -1050,29 +1050,29 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id) struct netwave_private *priv = netdev_priv(dev); struct pcmcia_device *link = priv->p_dev; int i; - + if (!netif_device_present(dev)) return IRQ_NONE; - + iobase = dev->base_addr; ramBase = priv->ramBase; - + /* Now find what caused the interrupt, check while interrupts ready */ for (i = 0; i < 10; i++) { u_char status; - - wait_WOC(iobase); + + wait_WOC(iobase); if (!(inb(iobase+NETWAVE_REG_CCSR) & 0x02)) break; /* None of the interrupt sources asserted (normal exit) */ - + status = inb(iobase + NETWAVE_REG_ASR); - + if (!pcmcia_dev_present(link)) { pr_debug("netwave_interrupt: Interrupt with status 0x%x " "from removed or suspended card!\n", status); break; } - + /* RxRdy */ if (status & 0x80) { netwave_rx(dev); @@ -1082,24 +1082,24 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id) /* RxErr */ if (status & 0x40) { u_char rser; - - rser = readb(ramBase + NETWAVE_EREG_RSER); - + + rser = readb(ramBase + NETWAVE_EREG_RSER); + if (rser & 0x04) { ++dev->stats.rx_dropped; ++dev->stats.rx_crc_errors; } if (rser & 0x02) ++dev->stats.rx_frame_errors; - + /* Clear the RxErr bit in RSER. RSER+4 is the - * write part. Also clear the RxCRC (0x04) and + * write part. Also clear the RxCRC (0x04) and * RxBig (0x02) bits if present */ wait_WOC(iobase); writeb(0x40 | (rser & 0x06), ramBase + NETWAVE_EREG_RSER + 4); /* Write bit 6 high to ASCC to clear RxErr in ASR, - * WOC must be set first! + * WOC must be set first! */ wait_WOC(iobase); writeb(0x40, ramBase + NETWAVE_EREG_ASCC); @@ -1114,31 +1114,31 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id) txStatus = readb(ramBase + NETWAVE_EREG_TSER); pr_debug("Transmit done. TSER = %x id %x\n", txStatus, readb(ramBase + NETWAVE_EREG_TSER + 1)); - + if (txStatus & 0x20) { /* Transmitting was okay, clear bits */ wait_WOC(iobase); writeb(0x2f, ramBase + NETWAVE_EREG_TSER + 4); ++dev->stats.tx_packets; } - + if (txStatus & 0xd0) { if (txStatus & 0x80) { ++dev->stats.collisions; /* Because of /proc/net/dev*/ /* ++dev->stats.tx_aborted_errors; */ /* printk("Collision. %ld\n", jiffies - dev->trans_start); */ } - if (txStatus & 0x40) + if (txStatus & 0x40) ++dev->stats.tx_carrier_errors; /* 0x80 TxGU Transmit giveup - nine times and no luck * 0x40 TxNOAP No access point. Discarded packet. - * 0x10 TxErr Transmit error. Always set when + * 0x10 TxErr Transmit error. Always set when * TxGU and TxNOAP is set. (Those are the only ones * to set TxErr). */ pr_debug("netwave_interrupt: TxDN with error status %x\n", txStatus); - + /* Clear out TxGU, TxNOAP, TxErr and TxTrys */ wait_WOC(iobase); writeb(0xdf & txStatus, ramBase+NETWAVE_EREG_TSER+4); @@ -1190,31 +1190,31 @@ static int netwave_rx(struct net_device *dev) int dataCount, dataOffset; int i; u_char *ptr; - + pr_debug("xinw_rx: Receiving ... \n"); /* Receive max 10 packets for now. */ for (i = 0; i < 10; i++) { /* Any packets? */ wait_WOC(iobase); - rxStatus = readb(ramBase + NETWAVE_EREG_RSER); + rxStatus = readb(ramBase + NETWAVE_EREG_RSER); if ( !( rxStatus & 0x80)) /* No more packets */ break; - + /* Check if multicast/broadcast or other */ /* multicast = (rxStatus & 0x20); */ - + /* The receive list pointer and length of the packet */ wait_WOC(iobase); rcvLen = get_int16( ramBase + NETWAVE_EREG_RDP); rcvList = get_uint16( ramBase + NETWAVE_EREG_RDP + 2); - + if (rcvLen < 0) { - printk(KERN_DEBUG "netwave_rx: Receive packet with len %d\n", + printk(KERN_DEBUG "netwave_rx: Receive packet with len %d\n", rcvLen); return 0; } - + skb = dev_alloc_skb(rcvLen+5); if (skb == NULL) { pr_debug("netwave_rx: Could not allocate an sk_buff of " @@ -1233,21 +1233,21 @@ static int netwave_rx(struct net_device *dev) /* Copy packet fragments to the skb data area */ ptr = (u_char*) skb->data; curBuffer = rcvList; - tmpcount = 0; + tmpcount = 0; while ( tmpcount < rcvLen) { /* Get length and offset of current buffer */ dataCount = get_uint16( ramBase+curBuffer+2); dataOffset = get_uint16( ramBase+curBuffer+4); - + copy_from_pc( ptr + tmpcount, ramBase+curBuffer+dataOffset, dataCount); tmpcount += dataCount; - + /* Point to next buffer */ curBuffer = get_uint16(ramBase + curBuffer); } - + skb->protocol = eth_type_trans(skb,dev); /* Queue packet for network layer */ netif_rx(skb); @@ -1269,7 +1269,7 @@ static int netwave_open(struct net_device *dev) { struct pcmcia_device *link = priv->p_dev; dev_dbg(&link->dev, "netwave_open: starting.\n"); - + if (!pcmcia_dev_present(link)) return -ENODEV; @@ -1277,7 +1277,7 @@ static int netwave_open(struct net_device *dev) { netif_start_queue(dev); netwave_reset(dev); - + return 0; } @@ -1336,7 +1336,7 @@ static void set_multicast_list(struct net_device *dev) netwave_private *priv = netdev_priv(dev); u_char __iomem * ramBase = priv->ramBase; u_char rcvMode = 0; - + #ifdef PCMCIA_DEBUG { xstatic int old; @@ -1347,7 +1347,7 @@ static void set_multicast_list(struct net_device *dev) } } #endif - + if (!netdev_mc_empty(dev) || (dev->flags & IFF_ALLMULTI)) { /* Multicast Mode */ rcvMode = rxConfRxEna + rxConfAMP + rxConfBcast; @@ -1358,7 +1358,7 @@ static void set_multicast_list(struct net_device *dev) /* Normal mode */ rcvMode = rxConfRxEna + rxConfBcast; } - + /* printk("netwave set_multicast_list: rcvMode to %x\n", rcvMode);*/ /* Now set receive mode */ wait_WOC(iobase); -- cgit v1.2.3 From 8d1fe5eaa3b796609a8e2b7dad2480e623c19819 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 9 Mar 2010 22:14:58 +0100 Subject: Staging: otus: drop redundant memset The region set by the call to memset is immediately overwritten by the subsequent call to memcpy. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression e1,e2,e3,e4; @@ - memset(e1,e2,e3); memcpy(e1,e4,e3); // Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/staging/otus/wwrap.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/otus/wwrap.c b/drivers/staging/otus/wwrap.c index a74f7eea56e4..b02eb42cd796 100644 --- a/drivers/staging/otus/wwrap.c +++ b/drivers/staging/otus/wwrap.c @@ -956,7 +956,6 @@ int zfLnxCencSendMsg(struct sock *netlink_sk, u_int8_t *msg, int len) /*ÌîдÊý¾Ý±¨Ïà¹ØÐÅÏ¢*/ nlh = NLMSG_PUT(skb, 0, 0, WAI_K_MSG, size-sizeof(*nlh)); pos = NLMSG_DATA(nlh); - memset(pos, 0, len); /*´«Êäµ½Óû§¿Õ¼äµÄÊý¾Ý*/ memcpy(pos, msg, len); -- cgit v1.2.3 From 347fd7dbdb6ca771f59996ae3c75a2dfde66c3d7 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Tue, 9 Mar 2010 21:51:24 +0100 Subject: Staging: rt2860: fixed coding-style issues in pci_main_dev.c fixed a bunch of coding-style issues generated from checkpatch.pl Signed-off-by: Henrik Hautakoski Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/pci_main_dev.c | 37 +++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/pci_main_dev.c b/drivers/staging/rt2860/pci_main_dev.c index e665d862281c..321facd6b0ab 100644 --- a/drivers/staging/rt2860/pci_main_dev.c +++ b/drivers/staging/rt2860/pci_main_dev.c @@ -107,13 +107,13 @@ MODULE_VERSION(STA_DRIVER_VERSION); /* Our PCI driver structure */ /* */ static struct pci_driver rt2860_driver = { -name: "rt2860", -id_table:rt2860_pci_tbl, -probe: rt2860_probe, -remove:__devexit_p(rt2860_remove_one), +name: "rt2860", +id_table : rt2860_pci_tbl, +probe : rt2860_probe, +remove : __devexit_p(rt2860_remove_one), #ifdef CONFIG_PM -suspend:rt2860_suspend, -resume:rt2860_resume, +suspend : rt2860_suspend, +resume : rt2860_resume, #endif }; @@ -211,9 +211,9 @@ static int rt2860_resume(struct pci_dev *pci_dev) DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_resume()\n")); - if (net_dev == NULL) { + if (net_dev == NULL) DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n")); - } else + else GET_PAD_FROM_NET_DEV(pAd, net_dev); if (pAd != NULL) { @@ -281,7 +281,9 @@ static int __devinit rt2860_probe(IN struct pci_dev *pci_dev, /*PCIDevInit============================================== */ /* wake up and enable device */ - if ((rv = pci_enable_device(pci_dev)) != 0) { + rv = pci_enable_device(pci_dev); + + if (rv != 0) { DBGPRINT(RT_DEBUG_ERROR, ("Enable PCI device failed, errno=%d!\n", rv)); return rv; @@ -289,7 +291,9 @@ static int __devinit rt2860_probe(IN struct pci_dev *pci_dev, print_name = (char *)pci_name(pci_dev); - if ((rv = pci_request_regions(pci_dev, print_name)) != 0) { + rv = pci_request_regions(pci_dev, print_name); + + if (rv != 0) { DBGPRINT(RT_DEBUG_ERROR, ("Request PCI resource failed, errno=%d!\n", rv)); goto err_out; @@ -490,9 +494,8 @@ static void RTMPInitPCIeDevice(struct pci_dev *pci_dev, struct rt_rtmp_adapter * /* Support advanced power save after 2892/2790. */ /* MAC version at offset 0x1000 is 0x2872XXXX/0x2870XXXX(PCIe, USB, SDIO). */ - if ((MacCsr0 & 0xffff0000) != 0x28600000) { + if ((MacCsr0 & 0xffff0000) != 0x28600000) OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PCIE_DEVICE); - } } } @@ -900,9 +903,9 @@ void RTMPPCIeLinkCtrlValueRestore(struct rt_rtmp_adapter *pAd, u8 Level) if ((Configuration != 0) && (Configuration != 0xFFFF)) { Configuration &= 0xfefc; /* If call from interface down, restore to orginial setting. */ - if (Level == RESTORE_CLOSE) { + if (Level == RESTORE_CLOSE) Configuration |= pAd->HostLnkCtrlConfiguration; - } else + else Configuration |= 0x0; PCI_REG_WIRTE_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, @@ -1100,13 +1103,13 @@ void RTMPrt3xSetPCIePowerLinkCtrl(struct rt_rtmp_adapter *pAd) /* Find PCI-to-PCI Bridge Express Capability Offset */ pos = pci_find_capability(pObj->parent_pci_dev, PCI_CAP_ID_EXP); - if (pos != 0) { + if (pos != 0) pAd->HostLnkCtrlOffset = pos + PCI_EXP_LNKCTL; - } + /* If configurared to turn on L1. */ HostConfiguration = 0; if (pAd->StaCfg.PSControl.field.rt30xxForceASPMTest == 1) { - DBGPRINT(RT_DEBUG_TRACE, ("Enter,PSM : Force ASPM \n")); + DBGPRINT(RT_DEBUG_TRACE, ("Enter,PSM : Force ASPM\n")); /* Skip non-exist deice right away */ if ((pAd->HostLnkCtrlOffset != 0)) { -- cgit v1.2.3 From 8f18604e6f0975fa852f43f90d5556efd67efadc Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 9 Mar 2010 22:15:21 +0100 Subject: Staging: drop redundant memset The region set by the call to memset is immediately overwritten by the subsequent call to memcpy. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression e1,e2,e3,e4; @@ - memset(e1,e2,e3); memcpy(e1,e4,e3); // Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/sta/assoc.c | 1 - drivers/staging/rt2860/sta_ioctl.c | 1 - drivers/staging/rtl8192su/r819xU_cmdpkt.c | 1 - drivers/staging/rtl8192u/r819xU_cmdpkt.c | 1 - drivers/staging/vt6655/iwctl.c | 2 -- drivers/staging/vt6656/iwctl.c | 2 -- 6 files changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/sta/assoc.c b/drivers/staging/rt2860/sta/assoc.c index 7055f229e511..6e85d5e6554b 100644 --- a/drivers/staging/rt2860/sta/assoc.c +++ b/drivers/staging/rt2860/sta/assoc.c @@ -1596,7 +1596,6 @@ BOOLEAN StaAddMacTableEntry(struct rt_rtmp_adapter *pAd, union iwreq_data wrqu; wext_notify_event_assoc(pAd); - memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN); memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN); wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL); diff --git a/drivers/staging/rt2860/sta_ioctl.c b/drivers/staging/rt2860/sta_ioctl.c index 33a6939cf2ae..112da7a6c417 100644 --- a/drivers/staging/rt2860/sta_ioctl.c +++ b/drivers/staging/rt2860/sta_ioctl.c @@ -608,7 +608,6 @@ int rt_ioctl_siwap(struct net_device *dev, /* Prevent to connect AP again in STAMlmePeriodicExec */ pAdapter->MlmeAux.AutoReconnectSsidLen = 32; - memset(Bssid, 0, MAC_ADDR_LEN); memcpy(Bssid, ap_addr->sa_data, MAC_ADDR_LEN); MlmeEnqueue(pAdapter, MLME_CNTL_STATE_MACHINE, diff --git a/drivers/staging/rtl8192su/r819xU_cmdpkt.c b/drivers/staging/rtl8192su/r819xU_cmdpkt.c index 9b377bae47b4..43b68a02d0c1 100644 --- a/drivers/staging/rtl8192su/r819xU_cmdpkt.c +++ b/drivers/staging/rtl8192su/r819xU_cmdpkt.c @@ -33,7 +33,6 @@ bool SendTxCommandPacket(struct net_device *dev, void *pData, u32 DataLen) tcb_desc->bLastIniPkt = 0; skb_reserve(skb, USB_HWDESC_HEADER_LEN); ptr_buf = skb_put(skb, DataLen); - memset(ptr_buf, 0, DataLen); memcpy(ptr_buf, pData, DataLen); tcb_desc->txbuf_size = (u16)DataLen; diff --git a/drivers/staging/rtl8192u/r819xU_cmdpkt.c b/drivers/staging/rtl8192u/r819xU_cmdpkt.c index fd19a85297a9..0cb28c776c49 100644 --- a/drivers/staging/rtl8192u/r819xU_cmdpkt.c +++ b/drivers/staging/rtl8192u/r819xU_cmdpkt.c @@ -63,7 +63,6 @@ SendTxCommandPacket( tcb_desc->bLastIniPkt = 0; skb_reserve(skb, USB_HWDESC_HEADER_LEN); ptr_buf = skb_put(skb, DataLen); - memset(ptr_buf,0,DataLen); memcpy(ptr_buf,pData,DataLen); tcb_desc->txbuf_size= (u16)DataLen; diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c index 78b49830a255..824466d5a659 100644 --- a/drivers/staging/vt6655/iwctl.c +++ b/drivers/staging/vt6655/iwctl.c @@ -699,7 +699,6 @@ if (pMgmt->eScanState == WMAC_IS_SCANNING) { if (wrq->sa_family != ARPHRD_ETHER) rc = -EINVAL; else { - memset(pMgmt->abyDesireBSSID, 0xFF, 6); memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6); //2008-0409-05, by Einsn Liu if((pDevice->bLinkPass == TRUE) && @@ -889,7 +888,6 @@ if (pMgmt->eScanState == WMAC_IS_SCANNING) { BYTE abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; UINT ii , uSameBssidNum=0; - memset(abyTmpDesireSSID,0,sizeof(abyTmpDesireSSID)); memcpy(abyTmpDesireSSID,pMgmt->abyDesireSSID,sizeof(abyTmpDesireSSID)); pCurr = BSSpSearchBSSList(pDevice, NULL, diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index b7c6a22fe321..d7ed3b456339 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -758,7 +758,6 @@ int iwctl_siwap(struct net_device *dev, if (wrq->sa_family != ARPHRD_ETHER) rc = -EINVAL; else { - memset(pMgmt->abyDesireBSSID, 0xFF, 6); memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6); //mike :add @@ -936,7 +935,6 @@ int iwctl_siwessid(struct net_device *dev, BYTE abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; UINT ii , uSameBssidNum=0; - memset(abyTmpDesireSSID,0,sizeof(abyTmpDesireSSID)); memcpy(abyTmpDesireSSID,pMgmt->abyDesireSSID,sizeof(abyTmpDesireSSID)); pCurr = BSSpSearchBSSList(pDevice, NULL, -- cgit v1.2.3 From 3f3ba29c78c4039a9fd746065ff89afec8bbc19a Mon Sep 17 00:00:00 2001 From: Felipe de Oliveira Tanus Date: Wed, 10 Mar 2010 02:03:49 -0300 Subject: Staging: comedi: cleanup dt2814.c This patch cleans up the dt2814.c driver file from issues found by checkpatch.pl tool. Signed-off-by: Felipe de Oliveira Tanus Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt2814.c | 38 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c index e1b73752f607..16fde066d266 100644 --- a/drivers/staging/comedi/drivers/dt2814.c +++ b/drivers/staging/comedi/drivers/dt2814.c @@ -99,13 +99,13 @@ static int dt2814_ai_insn_read(struct comedi_device *dev, outb(chan, dev->iobase + DT2814_CSR); for (i = 0; i < DT2814_TIMEOUT; i++) { status = inb(dev->iobase + DT2814_CSR); - printk("dt2814: status: %02x\n", status); + printk(KERN_INFO "dt2814: status: %02x\n", status); udelay(10); if (status & DT2814_FINISH) break; } if (i >= DT2814_TIMEOUT) { - printk("dt2814: status: %02x\n", status); + printk(KERN_INFO "dt2814: status: %02x\n", status); return -ETIMEDOUT; } @@ -173,7 +173,8 @@ static int dt2814_ai_cmdtest(struct comedi_device *dev, if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* step 2: make sure trigger sources are + * unique and mutually compatible */ /* note that mutual compatibility is not an issue here */ if (cmd->stop_src != TRIG_TIMER && cmd->stop_src != TRIG_EXT) @@ -256,9 +257,9 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned long iobase; iobase = it->options[0]; - printk("comedi%d: dt2814: 0x%04lx ", dev->minor, iobase); + printk(KERN_INFO "comedi%d: dt2814: 0x%04lx ", dev->minor, iobase); if (!request_region(iobase, DT2814_SIZE, "dt2814")) { - printk("I/O port conflict\n"); + printk(KERN_ERR "I/O port conflict\n"); return -EIO; } dev->iobase = iobase; @@ -267,7 +268,7 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) outb(0, dev->iobase + DT2814_CSR); udelay(100); if (inb(dev->iobase + DT2814_CSR) & DT2814_ERR) { - printk("reset error (fatal)\n"); + printk(KERN_ERR "reset error (fatal)\n"); return -EIO; } i = inb(dev->iobase + DT2814_DATA); @@ -286,9 +287,9 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) irq = probe_irq_off(irqs); restore_flags(flags); - if (inb(dev->iobase + DT2814_CSR) & DT2814_ERR) { - printk("error probing irq (bad) \n"); - } + if (inb(dev->iobase + DT2814_CSR) & DT2814_ERR) + printk(KERN_DEBUG "error probing irq (bad)\n"); + i = inb(dev->iobase + DT2814_DATA); i = inb(dev->iobase + DT2814_DATA); @@ -297,18 +298,18 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->irq = 0; if (irq > 0) { if (request_irq(irq, dt2814_interrupt, 0, "dt2814", dev)) { - printk("(irq %d unavailable)\n", irq); + printk(KERN_WARNING "(irq %d unavailable)\n", irq); } else { - printk("( irq = %d )\n", irq); + printk(KERN_INFO "( irq = %d )\n", irq); dev->irq = irq; } } else if (irq == 0) { - printk("(no irq)\n"); + printk(KERN_WARNING "(no irq)\n"); } else { #if 0 - printk("(probe returned multiple irqs--bad)\n"); + printk(KERN_DEBUG "(probe returned multiple irqs--bad)\n"); #else - printk("(irq probe not implemented)\n"); + printk(KERN_WARNING "(irq probe not implemented)\n"); #endif } @@ -337,14 +338,13 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) static int dt2814_detach(struct comedi_device *dev) { - printk("comedi%d: dt2814: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: dt2814: remove\n", dev->minor); - if (dev->irq) { + if (dev->irq) free_irq(dev->irq, dev); - } - if (dev->iobase) { + + if (dev->iobase) release_region(dev->iobase, DT2814_SIZE); - } return 0; } -- cgit v1.2.3 From 2306d9b1ee065d0dfb56af4cd05195ec61d69256 Mon Sep 17 00:00:00 2001 From: Rich Folsom Date: Tue, 9 Mar 2010 23:36:45 -0600 Subject: Staging: comedi: fix brace coding style issue in adl_pci9111.c This is a patch to the adl_pci9111.c to fix up a brace warnging found by the checkpatch.pl tool Signed-off-by: Rich Folsom Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9111.c | 30 ++++++++++------------------ 1 file changed, 11 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index da172a553d15..bbe0e332dae8 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -585,19 +585,17 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev, (cmd->scan_begin_src != TRIG_EXT)) error++; - if ((cmd->convert_src != TRIG_TIMER) && (cmd->convert_src != TRIG_EXT)) { + if ((cmd->convert_src != TRIG_TIMER) && (cmd->convert_src != TRIG_EXT)) error++; - } if ((cmd->convert_src == TRIG_TIMER) && !((cmd->scan_begin_src == TRIG_TIMER) || - (cmd->scan_begin_src == TRIG_FOLLOW))) { + (cmd->scan_begin_src == TRIG_FOLLOW))) error++; - } if ((cmd->convert_src == TRIG_EXT) && !((cmd->scan_begin_src == TRIG_EXT) || - (cmd->scan_begin_src == TRIG_FOLLOW))) { + (cmd->scan_begin_src == TRIG_FOLLOW))) error++; - } + if (cmd->scan_end_src != TRIG_COUNT) error++; @@ -1067,9 +1065,8 @@ static int pci9111_ai_insn_read(struct comedi_device *dev, pci9111_ai_channel_set(CR_CHAN((&insn->chanspec)[0])); - if ((pci9111_ai_range_get()) != CR_RANGE((&insn->chanspec)[0])) { + if ((pci9111_ai_range_get()) != CR_RANGE((&insn->chanspec)[0])) pci9111_ai_range_set(CR_RANGE((&insn->chanspec)[0])); - } pci9111_fifo_reset(); @@ -1090,11 +1087,10 @@ static int pci9111_ai_insn_read(struct comedi_device *dev, conversion_done: - if (resolution == PCI9111_HR_AI_RESOLUTION) { + if (resolution == PCI9111_HR_AI_RESOLUTION) data[i] = pci9111_hr_ai_get_data(); - } else { + else data[i] = pci9111_ai_get_data(); - } } #ifdef AI_INSN_DEBUG @@ -1131,9 +1127,8 @@ static int pci9111_ao_insn_read(struct comedi_device *dev, { int i; - for (i = 0; i < insn->n; i++) { + for (i = 0; i < insn->n; i++) data[i] = dev_private->ao_readback & PCI9111_AO_RESOLUTION_MASK; - } return i; } @@ -1222,9 +1217,8 @@ static int pci9111_attach(struct comedi_device *dev, int error, i; const struct pci9111_board *board; - if (alloc_private(dev, sizeof(struct pci9111_private_data)) < 0) { + if (alloc_private(dev, sizeof(struct pci9111_private_data)) < 0) return -ENOMEM; - } /* Probe the device to determine what device in the series it is. */ printk("comedi%d: " PCI9111_DRIVER_NAME " driver\n", dev->minor); @@ -1394,14 +1388,12 @@ static int pci9111_detach(struct comedi_device *dev) } /* Release previously allocated irq */ - if (dev->irq != 0) { + if (dev->irq != 0) free_irq(dev->irq, dev); - } if (dev_private != 0 && dev_private->pci_device != 0) { - if (dev->iobase) { + if (dev->iobase) comedi_pci_disable(dev_private->pci_device); - } pci_dev_put(dev_private->pci_device); } -- cgit v1.2.3 From 20617f22b006e12b81602d80d85f8f3f7efdef45 Mon Sep 17 00:00:00 2001 From: Pieter De Praetere Date: Wed, 10 Mar 2010 09:47:44 +0100 Subject: Staging: comedi: fix whitespace coding style issues in comedi_fops.c Solves warnings found by the checkpatch.pl tool: spaces before tabs. Signed-off-by: Pieter De Praetere Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 39 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index aca96747e5e2..287a1af3d013 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -598,19 +598,19 @@ copyback: static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data, void *file); /* - * COMEDI_INSNLIST - * synchronous instructions + * COMEDI_INSNLIST + * synchronous instructions * - * arg: - * pointer to sync cmd structure + * arg: + * pointer to sync cmd structure * - * reads: - * sync cmd struct at arg - * instruction list - * data (for writes) + * reads: + * sync cmd struct at arg + * instruction list + * data (for writes) * - * writes: - * data (for reads) + * writes: + * data (for reads) */ /* arbitrary limits */ #define MAX_SAMPLES 256 @@ -894,18 +894,18 @@ out: } /* - * COMEDI_INSN - * synchronous instructions + * COMEDI_INSN + * synchronous instructions * - * arg: - * pointer to insn + * arg: + * pointer to insn * - * reads: - * struct comedi_insn struct at arg - * data (for writes) + * reads: + * struct comedi_insn struct at arg + * data (for writes) * - * writes: - * data (for reads) + * writes: + * data (for reads) */ static int do_insn_ioctl(struct comedi_device *dev, void *arg, void *file) { @@ -2105,6 +2105,7 @@ int comedi_alloc_board_minor(struct device *hardware_device) kfree(info->device); kfree(info); printk(KERN_ERR + "comedi: error: ran out of minor numbers for board device files.\n"); return -EBUSY; } -- cgit v1.2.3 From 767700c454301058188fe6561c3d0213f6991e81 Mon Sep 17 00:00:00 2001 From: Jason Wong Date: Wed, 10 Mar 2010 16:58:55 +0800 Subject: Staging: comedi: amplc_pci224: fixed multiple brace coding style issue Fixed multiple coding style issue. Signed-off-by: Jason Wong Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 114 +++++++++++++------------- 1 file changed, 57 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index c54cca8b2565..8af156dca17e 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -496,9 +496,9 @@ pci224_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, /* Writing a list of values to an AO channel is probably not * very useful, but that's how the interface is defined. */ - for (i = 0; i < insn->n; i++) { + for (i = 0; i < insn->n; i++) pci224_ao_set_data(dev, chan, range, data[i]); - } + return i; } @@ -519,9 +519,9 @@ pci224_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, chan = CR_CHAN(insn->chanspec); - for (i = 0; i < insn->n; i++) { + for (i = 0; i < insn->n; i++) data[i] = devpriv->ao_readback[chan]; - } + return i; } @@ -544,9 +544,9 @@ static void pci224_ao_stop(struct comedi_device *dev, { unsigned long flags; - if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state)) { + if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state)) return; - } + spin_lock_irqsave(&devpriv->ao_spinlock, flags); /* Kill the interrupts. */ @@ -597,11 +597,11 @@ static void pci224_ao_start(struct comedi_device *dev, } else { /* Enable interrupts. */ spin_lock_irqsave(&devpriv->ao_spinlock, flags); - if (cmd->stop_src == TRIG_EXT) { + if (cmd->stop_src == TRIG_EXT) devpriv->intsce = PCI224_INTR_EXT | PCI224_INTR_DAC; - } else { + else devpriv->intsce = PCI224_INTR_DAC; - } + outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE); spin_unlock_irqrestore(&devpriv->ao_spinlock, flags); } @@ -630,9 +630,9 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, num_scans = comedi_buf_read_n_available(s->async) / bytes_per_scan; if (!devpriv->ao_stop_continuous) { /* Fixed number of scans. */ - if (num_scans > devpriv->ao_stop_count) { + if (num_scans > devpriv->ao_stop_count) num_scans = devpriv->ao_stop_count; - } + } /* Determine how much room is in the FIFO (in samples). */ @@ -669,13 +669,13 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, } } /* Determine how many new scans can be put in the FIFO. */ - if (cmd->chanlist_len) { + if (cmd->chanlist_len) room /= cmd->chanlist_len; - } + /* Determine how many scans to process. */ - if (num_scans > room) { + if (num_scans > room) num_scans = room; - } + /* Process scans. */ for (n = 0; n < num_scans; n++) { cfc_read_array_from_buffer(s, &devpriv->ao_scan_vals[0], @@ -718,19 +718,19 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, trig = PCI224_DACCON_TRIG_Z2CT0; } else { /* cmd->scan_begin_src == TRIG_EXT */ - if (cmd->scan_begin_arg & CR_INVERT) { + if (cmd->scan_begin_arg & CR_INVERT) trig = PCI224_DACCON_TRIG_EXTN; - } else { + else trig = PCI224_DACCON_TRIG_EXTP; - } + } devpriv->daccon = COMBINE(devpriv->daccon, trig, PCI224_DACCON_TRIG_MASK); outw(devpriv->daccon, dev->iobase + PCI224_DACCON); } - if (s->async->events) { + if (s->async->events) comedi_event(dev, s); - } + } /* @@ -855,9 +855,9 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, err++; } tmp = cmd->chanlist_len * CONVERT_PERIOD; - if (tmp < MIN_SCAN_PERIOD) { + if (tmp < MIN_SCAN_PERIOD) tmp = MIN_SCAN_PERIOD; - } + if (cmd->scan_begin_arg < tmp) { cmd->scan_begin_arg = tmp; err++; @@ -966,9 +966,9 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, devpriv->cached_div1 = div1; devpriv->cached_div2 = div2; } - if (tmp != cmd->scan_begin_arg) { + if (tmp != cmd->scan_begin_arg) err++; - } + } if (err) @@ -994,13 +994,13 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, tmp = 0; for (n = 0; n < cmd->chanlist_len; n++) { ch = CR_CHAN(cmd->chanlist[n]); - if (tmp & (1U << ch)) { + if (tmp & (1U << ch)) errors |= dupchan_err; - } + tmp |= (1U << ch); - if (CR_RANGE(cmd->chanlist[n]) != range) { + if (CR_RANGE(cmd->chanlist[n]) != range) errors |= range_err; - } + } if (errors) { if (errors & dupchan_err) { @@ -1038,9 +1038,9 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) unsigned long flags; /* Cannot handle null/empty chanlist. */ - if (cmd->chanlist == NULL || cmd->chanlist_len == 0) { + if (cmd->chanlist == NULL || cmd->chanlist_len == 0) return -EINVAL; - } + /* Determine which channels are enabled and their load order. */ devpriv->ao_enab = 0; @@ -1050,9 +1050,9 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ao_enab |= 1U << ch; rank = 0; for (j = 0; j < cmd->chanlist_len; j++) { - if (CR_CHAN(cmd->chanlist[j]) < ch) { + if (CR_CHAN(cmd->chanlist[j]) < ch) rank++; - } + } devpriv->ao_scan_order[rank] = i; } @@ -1221,9 +1221,9 @@ pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s, offset = 32768; } /* Munge the data. */ - for (i = 0; i < length; i++) { + for (i = 0; i < length; i++) array[i] = (array[i] << shift) - offset; - } + } /* @@ -1254,15 +1254,15 @@ static irqreturn_t pci224_interrupt(int irq, void *d) cmd = &s->async->cmd; if (valid_intstat & PCI224_INTR_EXT) { devpriv->intsce &= ~PCI224_INTR_EXT; - if (cmd->start_src == TRIG_EXT) { + if (cmd->start_src == TRIG_EXT) pci224_ao_start(dev, s); - } else if (cmd->stop_src == TRIG_EXT) { + else if (cmd->stop_src == TRIG_EXT) pci224_ao_stop(dev, s); - } + } - if (valid_intstat & PCI224_INTR_DAC) { + if (valid_intstat & PCI224_INTR_DAC) pci224_ao_handle_fifo(dev, s); - } + } /* Reenable interrupt sources. */ spin_lock_irqsave(&devpriv->ao_spinlock, flags); @@ -1381,23 +1381,23 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Allocate readback buffer for AO channels. */ devpriv->ao_readback = kmalloc(sizeof(devpriv->ao_readback[0]) * thisboard->ao_chans, GFP_KERNEL); - if (!devpriv->ao_readback) { + if (!devpriv->ao_readback) return -ENOMEM; - } + /* Allocate buffer to hold values for AO channel scan. */ devpriv->ao_scan_vals = kmalloc(sizeof(devpriv->ao_scan_vals[0]) * thisboard->ao_chans, GFP_KERNEL); - if (!devpriv->ao_scan_vals) { + if (!devpriv->ao_scan_vals) return -ENOMEM; - } + /* Allocate buffer to hold AO channel scan order. */ devpriv->ao_scan_order = kmalloc(sizeof(devpriv->ao_scan_order[0]) * thisboard->ao_chans, GFP_KERNEL); - if (!devpriv->ao_scan_order) { + if (!devpriv->ao_scan_order) return -ENOMEM; - } + /* Disable interrupt sources. */ devpriv->intsce = 0; @@ -1445,9 +1445,9 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->range_table_list = range_table_list = kmalloc(sizeof(struct comedi_lrange *) * s->n_chan, GFP_KERNEL); - if (!s->range_table_list) { + if (!s->range_table_list) return -ENOMEM; - } + for (n = 2; n < 3 + s->n_chan; n++) { if (it->options[n] < 0 || it->options[n] > 1) { printk(KERN_WARNING "comedi%d: %s: warning! " @@ -1459,11 +1459,11 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) for (n = 0; n < s->n_chan; n++) { if (n < COMEDI_NDEVCONFOPTS - 3 && it->options[3 + n] == 1) { - if (it->options[2] == 1) { + if (it->options[2] == 1) range_table_list[n] = &range_pci234_ext; - } else { + else range_table_list[n] = &range_bipolar5; - } + } else { if (it->options[2] == 1) { range_table_list[n] = @@ -1506,11 +1506,11 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name); printk("(pci %s) ", pci_name(pci_dev)); - if (irq) { + if (irq) printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE")); - } else { + else printk("(no irq) "); - } + printk("attached\n"); @@ -1529,9 +1529,9 @@ static int pci224_detach(struct comedi_device *dev) { printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor, DRIVER_NAME); - if (dev->irq) { + if (dev->irq) free_irq(dev->irq, dev); - } + if (dev->subdevices) { struct comedi_subdevice *s; @@ -1544,9 +1544,9 @@ static int pci224_detach(struct comedi_device *dev) kfree(devpriv->ao_scan_vals); kfree(devpriv->ao_scan_order); if (devpriv->pci_dev) { - if (dev->iobase) { + if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); - } + pci_dev_put(devpriv->pci_dev); } } -- cgit v1.2.3 From 67a7b3788cd2b9f63a6cfe68e9e937c25709f053 Mon Sep 17 00:00:00 2001 From: Patrick Rooney Date: Wed, 10 Mar 2010 08:46:30 +0000 Subject: Staging: wlan-ng: Fixed 80-character line coding style issues in p80211req.c This is a patch for p80211req.c. An 'if' statement that spanned 80 characters has been split onto 2 lines and one of the tabs preceding a comment has been removed. Signed-off-by: Patrick Rooney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211req.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/p80211req.c b/drivers/staging/wlan-ng/p80211req.c index e1e7bf1bf27c..207f080cfc9e 100644 --- a/drivers/staging/wlan-ng/p80211req.c +++ b/drivers/staging/wlan-ng/p80211req.c @@ -107,7 +107,8 @@ int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf) } /* Check Permissions */ - if (!capable(CAP_NET_ADMIN) && (msg->msgcode != DIDmsg_dot11req_mibget)) { + if (!capable(CAP_NET_ADMIN) && + (msg->msgcode != DIDmsg_dot11req_mibget)) { printk(KERN_ERR "%s: only dot11req_mibget allowed for non-root.\n", wlandev->name); @@ -128,7 +129,7 @@ int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf) wlandev->mlmerequest(wlandev, msg); clear_bit(1, &(wlandev->request_pending)); - return result; /* if result==0, msg->status still may contain an err */ + return result; /* if result==0, msg->status still may contain an err */ } /*---------------------------------------------------------------- -- cgit v1.2.3 From f3fd4cd59132ff81be9507762d00afa9445827b6 Mon Sep 17 00:00:00 2001 From: Michael Sprecher Date: Wed, 10 Mar 2010 13:15:35 +0100 Subject: Staging: et131x: fix most coding style issues in et131x This is a patch to the et131x driver that fixes up almost all coding style issues Signed-off-by: Michael Sprecher Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et1310_address_map.h | 7 ++-- drivers/staging/et131x/et1310_eeprom.c | 8 ++--- drivers/staging/et131x/et1310_phy.c | 2 +- drivers/staging/et131x/et1310_rx.c | 53 ++++++++++++++--------------- drivers/staging/et131x/et1310_rx.h | 5 ++- drivers/staging/et131x/et131x_initpci.c | 12 +++++-- drivers/staging/et131x/et131x_netdev.c | 14 +++----- 7 files changed, 50 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/et131x/et1310_address_map.h b/drivers/staging/et131x/et1310_address_map.h index ea746ba41faf..e6c8cb3828e9 100644 --- a/drivers/staging/et131x/et1310_address_map.h +++ b/drivers/staging/et131x/et1310_address_map.h @@ -117,7 +117,7 @@ /* * Software reset reg at address 0x0028 - * 0: txdma_sw_reset + * 0: txdma_sw_reset * 1: rxdma_sw_reset * 2: txmac_sw_reset * 3: rxmac_sw_reset @@ -1052,7 +1052,7 @@ typedef struct _RXMAC_t { /* Location: */ * 4-0: register */ -#define MII_ADDR(phy,reg) ((phy) << 8 | (reg)) +#define MII_ADDR(phy, reg) ((phy) << 8 | (reg)) /* * structure for MII Management Control reg in mac address map. @@ -1249,8 +1249,7 @@ typedef struct _MAC_t { /* Location: */ /* * MAC STATS Module of JAGCore Address Mapping */ -struct macstat_regs -{ /* Location: */ +struct macstat_regs { /* Location: */ u32 pad[32]; /* 0x6000 - 607C */ /* Tx/Rx 0-64 Byte Frame Counter */ diff --git a/drivers/staging/et131x/et1310_eeprom.c b/drivers/staging/et131x/et1310_eeprom.c index e4d095b0b52a..5a8e6b913dab 100644 --- a/drivers/staging/et131x/et1310_eeprom.c +++ b/drivers/staging/et131x/et1310_eeprom.c @@ -302,7 +302,7 @@ static int eeprom_read(struct et131x_adapter *etdev, u32 addr, u8 *pdata) err = eeprom_wait_ready(pdev, NULL); if (err) return err; - /* + /* * Write to the LBCIF Control Register: bit 7=1, bit 6=0, bit 3=0, * and bits 1:0 both =0. Bit 5 should be set according to the type * of EEPROM being accessed (1=two byte addressing, 0=one byte @@ -383,9 +383,9 @@ int et131x_init_eeprom(struct et131x_adapter *etdev) /* This error could mean that there was an error * reading the eeprom or that the eeprom doesn't exist. - * We will treat each case the same and not try to gather - * additional information that normally would come from the - * eeprom, like MAC Address + * We will treat each case the same and not try to + * gather additional information that normally would + * come from the eeprom, like MAC Address */ etdev->has_eeprom = 0; return -EIO; diff --git a/drivers/staging/et131x/et1310_phy.c b/drivers/staging/et131x/et1310_phy.c index 34cd5d1b586a..a6d9f29ff49c 100644 --- a/drivers/staging/et131x/et1310_phy.c +++ b/drivers/staging/et131x/et1310_phy.c @@ -344,7 +344,7 @@ static void ET1310_PhyDuplexMode(struct et131x_adapter *etdev, u16 duplex) static void ET1310_PhySpeedSelect(struct et131x_adapter *etdev, u16 speed) { u16 data; - static const u16 bits[3]={0x0000, 0x2000, 0x0040}; + static const u16 bits[3] = {0x0000, 0x2000, 0x0040}; /* Read the PHY control register */ MiRead(etdev, PHY_CONTROL, &data); diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c index 54686e2ace69..8f5dcebda76a 100644 --- a/drivers/staging/et131x/et1310_rx.c +++ b/drivers/staging/et131x/et1310_rx.c @@ -344,7 +344,7 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) "Cannot alloc memory for Packet Status Ring\n"); return -ENOMEM; } - printk("PSR %lx\n", (unsigned long) rx_ring->pPSRingPa); + printk(KERN_INFO "PSR %lx\n", (unsigned long) rx_ring->pPSRingPa); /* * NOTE : pci_alloc_consistent(), used above to alloc DMA regions, @@ -363,7 +363,7 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) return -ENOMEM; } rx_ring->NumRfd = NIC_DEFAULT_NUM_RFD; - printk("PRS %lx\n", (unsigned long)rx_ring->rx_status_bus); + printk(KERN_INFO "PRS %lx\n", (unsigned long)rx_ring->rx_status_bus); /* Recv * pci_pool_create initializes a lookaside list. After successful @@ -445,10 +445,10 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) rx_ring->pFbr1RingVa - rx_ring->Fbr1offset); bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr1NumEntries) - + 0xfff; + + 0xfff; pci_free_consistent(adapter->pdev, bufsize, - rx_ring->pFbr1RingVa, rx_ring->pFbr1RingPa); + rx_ring->pFbr1RingVa, rx_ring->pFbr1RingPa); rx_ring->pFbr1RingVa = NULL; } @@ -478,7 +478,7 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) rx_ring->pFbr0RingVa - rx_ring->Fbr0offset); bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr0NumEntries) - + 0xfff; + + 0xfff; pci_free_consistent(adapter->pdev, bufsize, @@ -504,7 +504,7 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) pci_free_consistent(adapter->pdev, sizeof(struct rx_status_block), rx_ring->rx_status_block, rx_ring->rx_status_bus); - rx_ring->rx_status_block = NULL; + rx_ring->rx_status_block = NULL; } /* Free receive buffer pool */ @@ -713,7 +713,7 @@ void SetRxDmaTimer(struct et131x_adapter *etdev) */ void et131x_rx_dma_disable(struct et131x_adapter *etdev) { - u32 csr; + u32 csr; /* Setup the receive dma configuration register */ writel(0x00002001, &etdev->regs->rxdma.csr); csr = readl(&etdev->regs->rxdma.csr); @@ -743,9 +743,9 @@ void et131x_rx_dma_enable(struct et131x_adapter *etdev) else if (etdev->rx_ring.Fbr1BufferSize == 16384) csr |= 0x1800; #ifdef USE_FBR0 - csr |= 0x0400; /* FBR0 enable */ + csr |= 0x0400; /* FBR0 enable */ if (etdev->rx_ring.Fbr0BufferSize == 256) - csr |= 0x0100; + csr |= 0x0100; else if (etdev->rx_ring.Fbr0BufferSize == 512) csr |= 0x0200; else if (etdev->rx_ring.Fbr0BufferSize == 1024) @@ -757,7 +757,7 @@ void et131x_rx_dma_enable(struct et131x_adapter *etdev) if ((csr & 0x00020000) != 0) { udelay(5); csr = readl(&etdev->regs->rxdma.csr); - if ((csr & 0x00020000) != 0) { + if ((csr & 0x00020000) != 0) { dev_err(&etdev->pdev->dev, "RX Dma failed to exit halt state. CSR 0x%08x\n", csr); @@ -841,8 +841,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) (rindex == 1 && bindex > rx_local->Fbr1NumEntries - 1)) #else - if (rindex != 1 || - bindex > rx_local->Fbr1NumEntries - 1) + if (rindex != 1 || bindex > rx_local->Fbr1NumEntries - 1) #endif { /* Illegal buffer or ring index cannot be used by S/W*/ @@ -1063,20 +1062,20 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev) static inline u32 bump_fbr(u32 *fbr, u32 limit) { - u32 v = *fbr; - v++; - /* This works for all cases where limit < 1024. The 1023 case - works because 1023++ is 1024 which means the if condition is not - taken but the carry of the bit into the wrap bit toggles the wrap - value correctly */ - if ((v & ET_DMA10_MASK) > limit) { - v &= ~ET_DMA10_MASK; - v ^= ET_DMA10_WRAP; - } - /* For the 1023 case */ - v &= (ET_DMA10_MASK|ET_DMA10_WRAP); - *fbr = v; - return v; + u32 v = *fbr; + v++; + /* This works for all cases where limit < 1024. The 1023 case + works because 1023++ is 1024 which means the if condition is not + taken but the carry of the bit into the wrap bit toggles the wrap + value correctly */ + if ((v & ET_DMA10_MASK) > limit) { + v &= ~ET_DMA10_MASK; + v ^= ET_DMA10_WRAP; + } + /* For the 1023 case */ + v &= (ET_DMA10_MASK|ET_DMA10_WRAP); + *fbr = v; + return v; } /** @@ -1105,7 +1104,7 @@ void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD rfd) if (ri == 1) { struct fbr_desc *next = (struct fbr_desc *) (rx_local->pFbr1RingVa) + - INDEX10(rx_local->local_Fbr1_full); + INDEX10(rx_local->local_Fbr1_full); /* Handle the Free Buffer Ring advancement here. Write * the PA / Buffer Index for the returned buffer into diff --git a/drivers/staging/et131x/et1310_rx.h b/drivers/staging/et131x/et1310_rx.h index ca84a9146d69..e8c653d37a76 100644 --- a/drivers/staging/et131x/et1310_rx.h +++ b/drivers/staging/et131x/et1310_rx.h @@ -91,8 +91,7 @@ #define ALCATEL_BROADCAST_PKT 0x02000000 /* typedefs for Free Buffer Descriptors */ -struct fbr_desc -{ +struct fbr_desc { u32 addr_lo; u32 addr_hi; u32 word2; /* Bits 10-31 reserved, 0-9 descriptor */ @@ -117,7 +116,7 @@ struct fbr_desc * 9: jp Jumbo Packet * 10: vp VLAN Packet * 11-15: unused - * 16: asw_prev_pkt_dropped e.g. IFG too small on previous + * 16: asw_prev_pkt_dropped e.g. IFG too small on previous * 17: asw_RX_DV_event short receive event detected * 18: asw_false_carrier_event bad carrier since last good packet * 19: asw_code_err one or more nibbles signalled as errors diff --git a/drivers/staging/et131x/et131x_initpci.c b/drivers/staging/et131x/et131x_initpci.c index 1dd5fa5b888b..47baab3e6ea8 100644 --- a/drivers/staging/et131x/et131x_initpci.c +++ b/drivers/staging/et131x/et131x_initpci.c @@ -113,7 +113,13 @@ static u32 et131x_speed_set; module_param(et131x_speed_set, uint, 0); MODULE_PARM_DESC(et131x_speed_set, - "Set Link speed and dublex manually (0-5) [0] \n 1 : 10Mb Half-Duplex \n 2 : 10Mb Full-Duplex \n 3 : 100Mb Half-Duplex \n 4 : 100Mb Full-Duplex \n 5 : 1000Mb Full-Duplex \n 0 : Auto Speed Auto Dublex"); + "Set Link speed and dublex manually (0-5) [0]\n \ + 1 : 10Mb Half-Duplex\n \ + 2 : 10Mb Full-Duplex\n \ + 3 : 100Mb Half-Duplex\n \ + 4 : 100Mb Full-Duplex\n \ + 5 : 1000Mb Full-Duplex\n \ + 0 : Auto Speed Auto Dublex"); /** * et131x_hwaddr_init - set up the MAC Address on the ET1310 @@ -558,7 +564,7 @@ static struct et131x_adapter *et131x_adapter_init(struct net_device *netdev, /* Parse configuration parameters into the private adapter struct */ if (et131x_speed_set) dev_info(&etdev->pdev->dev, - "Speed set manually to : %d \n", et131x_speed_set); + "Speed set manually to : %d\n", et131x_speed_set); etdev->SpeedDuplex = et131x_speed_set; etdev->RegistryJumboPacket = 1514; /* 1514-9216 */ @@ -820,7 +826,7 @@ static int __init et131x_init_module(void) if (et131x_speed_set < PARM_SPEED_DUPLEX_MIN || et131x_speed_set > PARM_SPEED_DUPLEX_MAX) { printk(KERN_WARNING "et131x: invalid speed setting ignored.\n"); - et131x_speed_set = 0; + et131x_speed_set = 0; } return pci_register_driver(&et131x_driver); } diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c index ab047f2ff72c..535a9d014e70 100644 --- a/drivers/staging/et131x/et131x_netdev.c +++ b/drivers/staging/et131x/et131x_netdev.c @@ -426,26 +426,22 @@ void et131x_multicast(struct net_device *netdev) * accordingly */ - if (netdev->flags & IFF_PROMISC) { + if (netdev->flags & IFF_PROMISC) adapter->PacketFilter |= ET131X_PACKET_TYPE_PROMISCUOUS; - } else { + else adapter->PacketFilter &= ~ET131X_PACKET_TYPE_PROMISCUOUS; - } - if (netdev->flags & IFF_ALLMULTI) { + if (netdev->flags & IFF_ALLMULTI) adapter->PacketFilter |= ET131X_PACKET_TYPE_ALL_MULTICAST; - } - if (netdev_mc_count(netdev) > NIC_MAX_MCAST_LIST) { + if (netdev_mc_count(netdev) > NIC_MAX_MCAST_LIST) adapter->PacketFilter |= ET131X_PACKET_TYPE_ALL_MULTICAST; - } if (netdev_mc_count(netdev) < 1) { adapter->PacketFilter &= ~ET131X_PACKET_TYPE_ALL_MULTICAST; adapter->PacketFilter &= ~ET131X_PACKET_TYPE_MULTICAST; - } else { + } else adapter->PacketFilter |= ET131X_PACKET_TYPE_MULTICAST; - } /* Set values in the private adapter struct */ i = 0; -- cgit v1.2.3 From 6e26b0154c63b5c0e7aae5155652d1b4daed703a Mon Sep 17 00:00:00 2001 From: Tomas Dabasinskas Date: Wed, 10 Mar 2010 19:51:01 +1000 Subject: Staging: crystalhd: fixed white spaces and brace coding in crystalhd_hw.c This is a patch to the crystalhd_hw.c file that fixes up a white space and brace warnings found by the checkpatch.pl tool Signed-off-by: Tomas Dabasinskas Acked-by: Jarod Wilson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/crystalhd/crystalhd_hw.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/crystalhd/crystalhd_hw.c b/drivers/staging/crystalhd/crystalhd_hw.c index c438c489aa92..56d1e42bbad6 100644 --- a/drivers/staging/crystalhd/crystalhd_hw.c +++ b/drivers/staging/crystalhd/crystalhd_hw.c @@ -432,7 +432,7 @@ static void crystalhd_hw_delete_ioqs(struct crystalhd_hw *hw) if (!hw) return; - BCMLOG(BCMLOG_DBG, "Deleting IOQs \n"); + BCMLOG(BCMLOG_DBG, "Deleting IOQs\n"); crystalhd_hw_delete_ioq(hw->adp, hw->tx_actq); crystalhd_hw_delete_ioq(hw->adp, hw->tx_freeq); crystalhd_hw_delete_ioq(hw->adp, hw->rx_actq); @@ -570,7 +570,7 @@ static bool crystalhd_tx_list0_handler(struct crystalhd_hw *hw, uint32_t err_sts if (!(err_sts & err_mask)) return false; - BCMLOG_ERR("Error on Tx-L0 %x \n", err_sts); + BCMLOG_ERR("Error on Tx-L0 %x\n", err_sts); tmp = err_mask; @@ -602,7 +602,7 @@ static bool crystalhd_tx_list1_handler(struct crystalhd_hw *hw, uint32_t err_sts if (!(err_sts & err_mask)) return false; - BCMLOG_ERR("Error on Tx-L1 %x \n", err_sts); + BCMLOG_ERR("Error on Tx-L1 %x\n", err_sts); tmp = err_mask; @@ -635,9 +635,9 @@ static void crystalhd_tx_isr(struct crystalhd_hw *hw, uint32_t int_sts) BC_STS_SUCCESS); if (!(int_sts & (INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_MASK | - INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_MASK))) { - /* No error mask set.. */ - return; + INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_MASK))) { + /* No error mask set.. */ + return; } /* Handle Tx errors. */ @@ -1134,33 +1134,29 @@ static void crystalhd_stop_rx_dma_engine(struct crystalhd_hw *hw) if (l0y) { l0y = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST0); l0y &= DMA_START_BIT; - if (!l0y) { + if (!l0y) hw->rx_list_sts[0] &= ~rx_waiting_y_intr; - } } if (l1y) { l1y = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST1); l1y &= DMA_START_BIT; - if (!l1y) { + if (!l1y) hw->rx_list_sts[1] &= ~rx_waiting_y_intr; - } } if (l0uv) { l0uv = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST0); l0uv &= DMA_START_BIT; - if (!l0uv) { + if (!l0uv) hw->rx_list_sts[0] &= ~rx_waiting_uv_intr; - } } if (l1uv) { l1uv = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST1); l1uv &= DMA_START_BIT; - if (!l1uv) { + if (!l1uv) hw->rx_list_sts[1] &= ~rx_waiting_uv_intr; - } } msleep_interruptible(100); count--; @@ -1432,9 +1428,8 @@ static bool crystalhd_rx_list1_handler(struct crystalhd_hw *hw, uint32_t int_sts /* UV1 - DMA */ tmp = uv_err_sts & GET_UV1_ERR_MSK; - if (int_sts & INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_MASK) { + if (int_sts & INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_MASK) hw->rx_list_sts[1] &= ~rx_waiting_uv_intr; - } if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK) { hw->rx_list_sts[1] &= ~rx_waiting_uv_intr; @@ -1740,7 +1735,7 @@ BC_STATUS crystalhd_do_fw_cmd(struct crystalhd_hw *hw, BC_FW_CMD *fw_cmd) res_buff = fw_cmd->rsp; if (!cmd_buff || !res_buff) { - BCMLOG_ERR("Invalid Parameters for F/W Command \n"); + BCMLOG_ERR("Invalid Parameters for F/W Command\n"); return BC_STS_INV_ARG; } -- cgit v1.2.3 From ed57d08b9f500f6553d8fa755d90ec710757d74b Mon Sep 17 00:00:00 2001 From: Patrick Rooney Date: Wed, 10 Mar 2010 09:37:45 +0000 Subject: Staging: sm7xx: Fixed space-before-tab coding style issues in smtcfb.c Patch for smtcfb.c that removes spaces before tabs in the comments at the beginning of the file. Signed-off-by: Patrick Rooney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm7xx/smtcfb.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c index 8d7261c052eb..e817a20d1bdd 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xx/smtcfb.c @@ -3,7 +3,7 @@ * * Copyright (C) 2006 Silicon Motion Technology Corp. * Authors: Ge Wang, gewang@siliconmotion.com - * Boyod boyod.yang@siliconmotion.com.cn + * Boyod boyod.yang@siliconmotion.com.cn * * Copyright (C) 2009 Lemote, Inc. * Author: Wu Zhangjin, wuzhangjin@gmail.com @@ -13,17 +13,17 @@ * more details. * * Version 0.10.26192.21.01 - * - Add PowerPC/Big endian support - * - Add 2D support for Lynx - * - Verified on2.6.19.2 Boyod.yang + * - Add PowerPC/Big endian support + * - Add 2D support for Lynx + * - Verified on2.6.19.2 Boyod.yang * * Version 0.09.2621.00.01 - * - Only support Linux Kernel's version 2.6.21. + * - Only support Linux Kernel's version 2.6.21. * Boyod.yang * * Version 0.09 - * - Only support Linux Kernel's version 2.6.12. - * Boyod.yang + * - Only support Linux Kernel's version 2.6.12. + * Boyod.yang */ #ifndef __KERNEL__ -- cgit v1.2.3 From 64ff4044a8d99ea0ae858d2a0f1128ef82047f9c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 10 Mar 2010 12:54:30 +0300 Subject: Staging: rt2860: clean up & => && a4_exists is an integer used as a boolean type so the original code works. But all the other conditions use && and this makes it consistent. Signed-off-by: Dan Carpenter Cc: Bartlomiej Zolnierkiewicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/common/cmm_aes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/common/cmm_aes.c b/drivers/staging/rt2860/common/cmm_aes.c index 250357c5cd65..1d159ff82fd2 100644 --- a/drivers/staging/rt2860/common/cmm_aes.c +++ b/drivers/staging/rt2860/common/cmm_aes.c @@ -281,7 +281,7 @@ void construct_mic_header2(unsigned char *mic_header2, mic_header2[6] = mpdu[22] & 0x0f; /* SC */ mic_header2[7] = 0x00; /* mpdu[23]; */ - if ((!qc_exists) & a4_exists) { + if ((!qc_exists) && a4_exists) { for (i = 0; i < 6; i++) mic_header2[8 + i] = mpdu[24 + i]; /* A4 */ -- cgit v1.2.3 From b1facee664ab3b6b27715aec60653659f12182bd Mon Sep 17 00:00:00 2001 From: Mike Sheldon Date: Wed, 10 Mar 2010 13:32:01 +0000 Subject: Staging: winbond: Replace C99 comments with C89. This patches mds.c to replace all the C99 style comments (//) with C89 style (/* ... */), as reported by checkpatch.pl. Signed-off-by: Mike Sheldon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mds.c | 310 +++++++++++++++++++++--------------------- 1 file changed, 155 insertions(+), 155 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c index 37e0c185d113..65063c33618d 100644 --- a/drivers/staging/winbond/mds.c +++ b/drivers/staging/winbond/mds.c @@ -43,53 +43,53 @@ static void Mds_DurationSet(struct wbsoft_priv *adapter, struct wb35_descriptor pT01 = (PT01_DESCRIPTOR)(buffer+4); pNextT00 = (PT00_DESCRIPTOR)(buffer+OffsetSize); - if( buffer[ DOT_11_DA_OFFSET+8 ] & 0x1 ) // +8 for USB hdr + if( buffer[ DOT_11_DA_OFFSET+8 ] & 0x1 ) /* +8 for USB hdr */ boGroupAddr = true; - //======================================== - // Set RTS/CTS mechanism - //======================================== + /****************************************** + * Set RTS/CTS mechanism + ******************************************/ if (!boGroupAddr) { - //NOTE : If the protection mode is enabled and the MSDU will be fragmented, - // the tx rates of MPDUs will all be DSSS rates. So it will not use - // CTS-to-self in this case. CTS-To-self will only be used when without - // fragmentation. -- 20050112 - BodyLen = (u16)pT00->T00_frame_length; //include 802.11 header - BodyLen += 4; //CRC + /* NOTE : If the protection mode is enabled and the MSDU will be fragmented, + * the tx rates of MPDUs will all be DSSS rates. So it will not use + * CTS-to-self in this case. CTS-To-self will only be used when without + * fragmentation. -- 20050112 */ + BodyLen = (u16)pT00->T00_frame_length; /* include 802.11 header */ + BodyLen += 4; /* CRC */ if( BodyLen >= CURRENT_RTS_THRESHOLD ) - RTS_on = true; // Using RTS + RTS_on = true; /* Using RTS */ else { - if( pT01->T01_modulation_type ) // Is using OFDM + if( pT01->T01_modulation_type ) /* Is using OFDM */ { - if( CURRENT_PROTECT_MECHANISM ) // Is using protect - CTS_on = true; // Using CTS + if( CURRENT_PROTECT_MECHANISM ) /* Is using protect */ + CTS_on = true; /* Using CTS */ } } } if( RTS_on || CTS_on ) { - if( pT01->T01_modulation_type) // Is using OFDM + if( pT01->T01_modulation_type) /* Is using OFDM */ { - //CTS duration - // 2 SIFS + DATA transmit time + 1 ACK - // ACK Rate : 24 Mega bps - // ACK frame length = 14 bytes + /* CTS duration + * 2 SIFS + DATA transmit time + 1 ACK + * ACK Rate : 24 Mega bps + * ACK frame length = 14 bytes */ Duration = 2*DEFAULT_SIFSTIME + 2*PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION + ((BodyLen*8 + 22 + Rate*4 - 1)/(Rate*4))*Tsym + ((112 + 22 + 95)/96)*Tsym; } - else //DSSS + else /* DSSS */ { - //CTS duration - // 2 SIFS + DATA transmit time + 1 ACK - // Rate : ?? Mega bps - // ACK frame length = 14 bytes - if( pT01->T01_plcp_header_length ) //long preamble + /* CTS duration + * 2 SIFS + DATA transmit time + 1 ACK + * Rate : ?? Mega bps + * ACK frame length = 14 bytes */ + if( pT01->T01_plcp_header_length ) /* long preamble */ Duration = LONG_PREAMBLE_PLUS_PLCPHEADER_TIME*2; else Duration = SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME*2; @@ -100,21 +100,21 @@ static void Mds_DurationSet(struct wbsoft_priv *adapter, struct wb35_descriptor if( RTS_on ) { - if( pT01->T01_modulation_type ) // Is using OFDM + if( pT01->T01_modulation_type ) /* Is using OFDM */ { - //CTS + 1 SIFS + CTS duration - //CTS Rate : 24 Mega bps - //CTS frame length = 14 bytes + /* CTS + 1 SIFS + CTS duration + * CTS Rate : 24 Mega bps + * CTS frame length = 14 bytes */ Duration += (DEFAULT_SIFSTIME + PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION + ((112 + 22 + 95)/96)*Tsym); } else { - //CTS + 1 SIFS + CTS duration - //CTS Rate : ?? Mega bps - //CTS frame length = 14 bytes - if( pT01->T01_plcp_header_length ) //long preamble + /* CTS + 1 SIFS + CTS duration + * CTS Rate : ?? Mega bps + * CTS frame length = 14 bytes */ + if( pT01->T01_plcp_header_length ) /* long preamble */ Duration += LONG_PREAMBLE_PLUS_PLCPHEADER_TIME; else Duration += SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME; @@ -123,15 +123,15 @@ static void Mds_DurationSet(struct wbsoft_priv *adapter, struct wb35_descriptor } } - // Set the value into USB descriptor + /* Set the value into USB descriptor */ pT01->T01_add_rts = RTS_on ? 1 : 0; pT01->T01_add_cts = CTS_on ? 1 : 0; pT01->T01_rts_cts_duration = Duration; } - //===================================== - // Fill the more fragment descriptor - //===================================== + /****************************************** + * Fill the more fragment descriptor + ******************************************/ if( boGroupAddr ) Duration = 0; else @@ -139,14 +139,14 @@ static void Mds_DurationSet(struct wbsoft_priv *adapter, struct wb35_descriptor for( i=pDes->FragmentCount-1; i>0; i-- ) { NextBodyLen = (u16)pNextT00->T00_frame_length; - NextBodyLen += 4; //CRC + NextBodyLen += 4; /* CRC */ if( pT01->T01_modulation_type ) { - //OFDM - // data transmit time + 3 SIFS + 2 ACK - // Rate : ??Mega bps - // ACK frame length = 14 bytes, tx rate = 24M + /* OFDM + * data transmit time + 3 SIFS + 2 ACK + * Rate : ??Mega bps + * ACK frame length = 14 bytes, tx rate = 24M */ Duration = PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION * 3; Duration += (((NextBodyLen*8 + 22 + Rate*4 - 1)/(Rate*4)) * Tsym + (((2*14)*8 + 22 + 95)/96)*Tsym + @@ -154,12 +154,12 @@ static void Mds_DurationSet(struct wbsoft_priv *adapter, struct wb35_descriptor } else { - //DSSS - // data transmit time + 2 ACK + 3 SIFS - // Rate : ??Mega bps - // ACK frame length = 14 bytes - //TODO : - if( pT01->T01_plcp_header_length ) //long preamble + /* DSSS + * data transmit time + 2 ACK + 3 SIFS + * Rate : ??Mega bps + * ACK frame length = 14 bytes + * TODO : */ + if( pT01->T01_plcp_header_length ) /* long preamble */ Duration = LONG_PREAMBLE_PLUS_PLCPHEADER_TIME*3; else Duration = SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME*3; @@ -168,39 +168,39 @@ static void Mds_DurationSet(struct wbsoft_priv *adapter, struct wb35_descriptor DEFAULT_SIFSTIME*3 ); } - ((u16 *)buffer)[5] = cpu_to_le16(Duration);// 4 USHOR for skip 8B USB, 2USHORT=FC + Duration + ((u16 *)buffer)[5] = cpu_to_le16(Duration); /* 4 USHOR for skip 8B USB, 2USHORT=FC + Duration */ - //----20061009 add by anson's endian + /* ----20061009 add by anson's endian */ pNextT00->value = cpu_to_le32(pNextT00->value); pT01->value = cpu_to_le32( pT01->value ); - //----end 20061009 add by anson's endian + /* ----end 20061009 add by anson's endian */ buffer += OffsetSize; pT01 = (PT01_DESCRIPTOR)(buffer+4); - if (i != 1) //The last fragment will not have the next fragment + if (i != 1) /* The last fragment will not have the next fragment */ pNextT00 = (PT00_DESCRIPTOR)(buffer+OffsetSize); } - //===================================== - // Fill the last fragment descriptor - //===================================== + /******************************************* + * Fill the last fragment descriptor + *******************************************/ if( pT01->T01_modulation_type ) { - //OFDM - // 1 SIFS + 1 ACK - // Rate : 24 Mega bps - // ACK frame length = 14 bytes + /* OFDM + * 1 SIFS + 1 ACK + * Rate : 24 Mega bps + * ACK frame length = 14 bytes */ Duration = PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION; - //The Tx rate of ACK use 24M + /* The Tx rate of ACK use 24M */ Duration += (((112 + 22 + 95)/96)*Tsym + DEFAULT_SIFSTIME ); } else { - // DSSS - // 1 ACK + 1 SIFS - // Rate : ?? Mega bps - // ACK frame length = 14 bytes(112 bits) - if( pT01->T01_plcp_header_length ) //long preamble + /* DSSS + * 1 ACK + 1 SIFS + * Rate : ?? Mega bps + * ACK frame length = 14 bytes(112 bits) */ + if( pT01->T01_plcp_header_length ) /* long preamble */ Duration = LONG_PREAMBLE_PLUS_PLCPHEADER_TIME; else Duration = SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME; @@ -209,14 +209,14 @@ static void Mds_DurationSet(struct wbsoft_priv *adapter, struct wb35_descriptor } } - ((u16 *)buffer)[5] = cpu_to_le16(Duration);// 4 USHOR for skip 8B USB, 2USHORT=FC + Duration + ((u16 *)buffer)[5] = cpu_to_le16(Duration); /* 4 USHOR for skip 8B USB, 2USHORT=FC + Duration */ pT00->value = cpu_to_le32(pT00->value); pT01->value = cpu_to_le32(pT01->value); - //--end 20061009 add + /* --end 20061009 add */ } -// The function return the 4n size of usb pk +/* The function return the 4n size of usb pk */ static u16 Mds_BodyCopy(struct wbsoft_priv *adapter, struct wb35_descriptor *pDes, u8 *TargetBuffer) { PT00_DESCRIPTOR pT00; @@ -229,8 +229,8 @@ static u16 Mds_BodyCopy(struct wbsoft_priv *adapter, struct wb35_descriptor *pDe u8 buf_index, FragmentCount = 0; - // Copy fragment body - buffer = TargetBuffer; // shift 8B usb + 24B 802.11 + /* Copy fragment body */ + buffer = TargetBuffer; /* shift 8B usb + 24B 802.11 */ SizeLeft = pDes->buffer_total_size; buf_index = pDes->buffer_start_index; @@ -240,35 +240,35 @@ static u16 Mds_BodyCopy(struct wbsoft_priv *adapter, struct wb35_descriptor *pDe CopySize = SizeLeft; if (SizeLeft > pDes->FragmentThreshold) { CopySize = pDes->FragmentThreshold; - pT00->T00_frame_length = 24 + CopySize;//Set USB length + pT00->T00_frame_length = 24 + CopySize; /* Set USB length */ } else - pT00->T00_frame_length = 24 + SizeLeft;//Set USB length + pT00->T00_frame_length = 24 + SizeLeft; /* Set USB length */ SizeLeft -= CopySize; - // 1 Byte operation + /* 1 Byte operation */ pctmp = (u8 *)( buffer + 8 + DOT_11_SEQUENCE_OFFSET ); *pctmp &= 0xf0; - *pctmp |= FragmentCount;//931130.5.m + *pctmp |= FragmentCount; /* 931130.5.m */ if( !FragmentCount ) pT00->T00_first_mpdu = 1; - buffer += 32; // 8B usb + 24B 802.11 header + buffer += 32; /* 8B usb + 24B 802.11 header */ Size += 32; - // Copy into buffer + /* Copy into buffer */ stmp = CopySize + 3; - stmp &= ~0x03;//4n Alignment - Size += stmp;// Current 4n offset of mpdu + stmp &= ~0x03; /* 4n Alignment */ + Size += stmp; /* Current 4n offset of mpdu */ while (CopySize) { - // Copy body + /* Copy body */ src_buffer = pDes->buffer_address[buf_index]; CopyLeft = CopySize; if (CopySize >= pDes->buffer_size[buf_index]) { CopyLeft = pDes->buffer_size[buf_index]; - // Get the next buffer of descriptor + /* Get the next buffer of descriptor */ buf_index++; buf_index %= MAX_DESCRIPTOR_BUFFER_INDEX; } else { @@ -283,14 +283,14 @@ static u16 Mds_BodyCopy(struct wbsoft_priv *adapter, struct wb35_descriptor *pDe CopySize -= CopyLeft; } - // 931130.5.n + /* 931130.5.n */ if (pMds->MicAdd) { if (!SizeLeft) { pMds->MicWriteAddress[ pMds->MicWriteIndex ] = buffer - pMds->MicAdd; pMds->MicWriteSize[ pMds->MicWriteIndex ] = pMds->MicAdd; pMds->MicAdd = 0; } - else if( SizeLeft < 8 ) //931130.5.p + else if( SizeLeft < 8 ) /* 931130.5.p */ { pMds->MicAdd = SizeLeft; pMds->MicWriteAddress[ pMds->MicWriteIndex ] = buffer - ( 8 - SizeLeft ); @@ -299,10 +299,10 @@ static u16 Mds_BodyCopy(struct wbsoft_priv *adapter, struct wb35_descriptor *pDe } } - // Does it need to generate the new header for next mpdu? + /* Does it need to generate the new header for next mpdu? */ if (SizeLeft) { - buffer = TargetBuffer + Size; // Get the next 4n start address - memcpy( buffer, TargetBuffer, 32 );//Copy 8B USB +24B 802.11 + buffer = TargetBuffer + Size; /* Get the next 4n start address */ + memcpy( buffer, TargetBuffer, 32 ); /* Copy 8B USB +24B 802.11 */ pT00 = (PT00_DESCRIPTOR)buffer; pT00->T00_first_mpdu = 0; } @@ -312,16 +312,16 @@ static u16 Mds_BodyCopy(struct wbsoft_priv *adapter, struct wb35_descriptor *pDe pT00->T00_last_mpdu = 1; pT00->T00_IsLastMpdu = 1; - buffer = (u8 *)pT00 + 8; // +8 for USB hdr - buffer[1] &= ~0x04; // Clear more frag bit of 802.11 frame control - pDes->FragmentCount = FragmentCount; // Update the correct fragment number + buffer = (u8 *)pT00 + 8; /* +8 for USB hdr */ + buffer[1] &= ~0x04; /* Clear more frag bit of 802.11 frame control */ + pDes->FragmentCount = FragmentCount; /* Update the correct fragment number */ return Size; } static void Mds_HeaderCopy(struct wbsoft_priv * adapter, struct wb35_descriptor *pDes, u8 *TargetBuffer) { struct wb35_mds *pMds = &adapter->Mds; - u8 *src_buffer = pDes->buffer_address[0];//931130.5.g + u8 *src_buffer = pDes->buffer_address[0]; /* 931130.5.g */ PT00_DESCRIPTOR pT00; PT01_DESCRIPTOR pT01; u16 stmp; @@ -330,44 +330,44 @@ static void Mds_HeaderCopy(struct wbsoft_priv * adapter, struct wb35_descriptor stmp = pDes->buffer_total_size; - // - // Set USB header 8 byte - // + /* + * Set USB header 8 byte + */ pT00 = (PT00_DESCRIPTOR)TargetBuffer; TargetBuffer += 4; pT01 = (PT01_DESCRIPTOR)TargetBuffer; TargetBuffer += 4; - pT00->value = 0;// Clear - pT01->value = 0;// Clear + pT00->value = 0; /* Clear */ + pT01->value = 0; /* Clear */ - pT00->T00_tx_packet_id = pDes->Descriptor_ID;// Set packet ID - pT00->T00_header_length = 24;// Set header length - pT01->T01_retry_abort_ebable = 1;//921013 931130.5.h + pT00->T00_tx_packet_id = pDes->Descriptor_ID; /* Set packet ID */ + pT00->T00_header_length = 24; /* Set header length */ + pT01->T01_retry_abort_ebable = 1; /* 921013 931130.5.h */ - // Key ID setup + /* Key ID setup */ pT01->T01_wep_id = 0; - FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD; //Do not fragment - // Copy full data, the 1'st buffer contain all the data 931130.5.j - memcpy( TargetBuffer, src_buffer, DOT_11_MAC_HEADER_SIZE );// Copy header + FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD; /* Do not fragment */ + /* Copy full data, the 1'st buffer contain all the data 931130.5.j */ + memcpy( TargetBuffer, src_buffer, DOT_11_MAC_HEADER_SIZE ); /* Copy header */ pDes->buffer_address[0] = src_buffer + DOT_11_MAC_HEADER_SIZE; pDes->buffer_total_size -= DOT_11_MAC_HEADER_SIZE; pDes->buffer_size[0] = pDes->buffer_total_size; - // Set fragment threshold + /* Set fragment threshold */ FragmentThreshold -= (DOT_11_MAC_HEADER_SIZE + 4); pDes->FragmentThreshold = FragmentThreshold; - // Set more frag bit - TargetBuffer[1] |= 0x04;// Set more frag bit + /* Set more frag bit */ + TargetBuffer[1] |= 0x04; /* Set more frag bit */ - // - // Set tx rate - // - stmp = *(u16 *)(TargetBuffer+30); // 2n alignment address + /* + * Set tx rate + */ + stmp = *(u16 *)(TargetBuffer+30); /* 2n alignment address */ - //Use basic rate + /* Use basic rate */ ctmp1 = ctmpf = CURRENT_TX_RATE_FOR_MNG; pDes->TxRate = ctmp1; @@ -381,10 +381,10 @@ static void Mds_HeaderCopy(struct wbsoft_priv * adapter, struct wb35_descriptor if( i == 1 ) ctmp1 = ctmpf; - pMds->TxRate[pDes->Descriptor_ID][i] = ctmp1; // backup the ta rate and fall back rate + pMds->TxRate[pDes->Descriptor_ID][i] = ctmp1; /* backup the ta rate and fall back rate */ if( ctmp1 == 108) ctmp2 = 7; - else if( ctmp1 == 96 ) ctmp2 = 6; // Rate convert for USB + else if( ctmp1 == 96 ) ctmp2 = 6; /* Rate convert for USB */ else if( ctmp1 == 72 ) ctmp2 = 5; else if( ctmp1 == 48 ) ctmp2 = 4; else if( ctmp1 == 36 ) ctmp2 = 3; @@ -394,7 +394,7 @@ static void Mds_HeaderCopy(struct wbsoft_priv * adapter, struct wb35_descriptor else if( ctmp1 == 22 ) ctmp2 = 3; else if( ctmp1 == 11 ) ctmp2 = 2; else if( ctmp1 == 4 ) ctmp2 = 1; - else ctmp2 = 0; // if( ctmp1 == 2 ) or default + else ctmp2 = 0; /* if( ctmp1 == 2 ) or default */ if( i == 0 ) pT01->T01_transmit_rate = ctmp2; @@ -402,14 +402,14 @@ static void Mds_HeaderCopy(struct wbsoft_priv * adapter, struct wb35_descriptor pT01->T01_fall_back_rate = ctmp2; } - // - // Set preamble type - // - if ((pT01->T01_modulation_type == 0) && (pT01->T01_transmit_rate == 0)) // RATE_1M + /* + * Set preamble type + */ + if ((pT01->T01_modulation_type == 0) && (pT01->T01_transmit_rate == 0)) /* RATE_1M */ pDes->PreambleMode = WLAN_PREAMBLE_TYPE_LONG; else pDes->PreambleMode = CURRENT_PREAMBLE_MODE; - pT01->T01_plcp_header_length = pDes->PreambleMode; // Set preamble + pT01->T01_plcp_header_length = pDes->PreambleMode; /* Set preamble */ } @@ -431,21 +431,21 @@ Mds_Tx(struct wbsoft_priv * adapter) if (!hal_driver_init_OK(pHwData)) return; - //Only one thread can be run here + /* Only one thread can be run here */ if (atomic_inc_return(&pMds->TxThreadCount) != 1) goto cleanup; - // Start to fill the data + /* Start to fill the data */ do { FillIndex = pMds->TxFillIndex; - if (pMds->TxOwner[FillIndex]) { // Is owned by software 0:Yes 1:No + if (pMds->TxOwner[FillIndex]) { /* Is owned by software 0:Yes 1:No */ #ifdef _PE_TX_DUMP_ printk("[Mds_Tx] Tx Owner is H/W.\n"); #endif break; } - XmitBufAddress = pMds->pTxBuffer + (MAX_USB_TX_BUFFER * FillIndex); //Get buffer + XmitBufAddress = pMds->pTxBuffer + (MAX_USB_TX_BUFFER * FillIndex); /* Get buffer */ XmitBufSize = 0; FillCount = 0; do { @@ -453,37 +453,37 @@ Mds_Tx(struct wbsoft_priv * adapter) if (!PacketSize) break; - //For Check the buffer resource + /* For Check the buffer resource */ FragmentThreshold = CURRENT_FRAGMENT_THRESHOLD; - //931130.5.b + /* 931130.5.b */ FragmentCount = PacketSize/FragmentThreshold + 1; - stmp = PacketSize + FragmentCount*32 + 8;//931130.5.c 8:MIC + stmp = PacketSize + FragmentCount*32 + 8; /* 931130.5.c 8:MIC */ if ((XmitBufSize + stmp) >= MAX_USB_TX_BUFFER) { printk("[Mds_Tx] Excess max tx buffer.\n"); - break; // buffer is not enough + break; /* buffer is not enough */ } - // - // Start transmitting - // + /* + * Start transmitting + */ BufferFilled = true; /* Leaves first u8 intact */ memset((u8 *)pTxDes + 1, 0, sizeof(struct wb35_descriptor) - 1); - TxDesIndex = pMds->TxDesIndex;//Get the current ID + TxDesIndex = pMds->TxDesIndex; /* Get the current ID */ pTxDes->Descriptor_ID = TxDesIndex; - pMds->TxDesFrom[ TxDesIndex ] = 2;//Storing the information of source comming from + pMds->TxDesFrom[ TxDesIndex ] = 2; /* Storing the information of source comming from */ pMds->TxDesIndex++; pMds->TxDesIndex %= MAX_USB_TX_DESCRIPTOR; MLME_GetNextPacket( adapter, pTxDes ); - // Copy header. 8byte USB + 24byte 802.11Hdr. Set TxRate, Preamble type + /* Copy header. 8byte USB + 24byte 802.11Hdr. Set TxRate, Preamble type */ Mds_HeaderCopy( adapter, pTxDes, XmitBufAddress ); - // For speed up Key setting + /* For speed up Key setting */ if (pTxDes->EapFix) { #ifdef _PE_TX_DUMP_ printk("35: EPA 4th frame detected. Size = %d\n", PacketSize); @@ -491,41 +491,41 @@ Mds_Tx(struct wbsoft_priv * adapter) pHwData->IsKeyPreSet = 1; } - // Copy (fragment) frame body, and set USB, 802.11 hdr flag + /* Copy (fragment) frame body, and set USB, 802.11 hdr flag */ CurrentSize = Mds_BodyCopy(adapter, pTxDes, XmitBufAddress); - // Set RTS/CTS and Normal duration field into buffer + /* Set RTS/CTS and Normal duration field into buffer */ Mds_DurationSet(adapter, pTxDes, XmitBufAddress); - //Shift to the next address + /* Shift to the next address */ XmitBufSize += CurrentSize; XmitBufAddress += CurrentSize; #ifdef _IBSS_BEACON_SEQ_STICK_ - if ((XmitBufAddress[ DOT_11_DA_OFFSET+8 ] & 0xfc) != MAC_SUBTYPE_MNGMNT_PROBE_REQUEST) // +8 for USB hdr + if ((XmitBufAddress[ DOT_11_DA_OFFSET+8 ] & 0xfc) != MAC_SUBTYPE_MNGMNT_PROBE_REQUEST) /* +8 for USB hdr */ #endif pMds->TxToggle = true; - // Get packet to transmit completed, 1:TESTSTA 2:MLME 3: Ndis data + /* Get packet to transmit completed, 1:TESTSTA 2:MLME 3: Ndis data */ MLME_SendComplete(adapter, 0, true); - // Software TSC count 20060214 + /* Software TSC count 20060214 */ pMds->TxTsc++; if (pMds->TxTsc == 0) pMds->TxTsc_2++; - FillCount++; // 20060928 - } while (HAL_USB_MODE_BURST(pHwData)); // End of multiple MSDU copy loop. false = single true = multiple sending + FillCount++; /* 20060928 */ + } while (HAL_USB_MODE_BURST(pHwData)); /* End of multiple MSDU copy loop. false = single true = multiple sending */ - // Move to the next one, if necessary + /* Move to the next one, if necessary */ if (BufferFilled) { - // size setting + /* size setting */ pMds->TxBufferSize[ FillIndex ] = XmitBufSize; - // 20060928 set Tx count + /* 20060928 set Tx count */ pMds->TxCountInBuffer[FillIndex] = FillCount; - // Set owner flag + /* Set owner flag */ pMds->TxOwner[FillIndex] = 1; pMds->TxFillIndex++; @@ -534,14 +534,14 @@ Mds_Tx(struct wbsoft_priv * adapter) } else break; - if (!PacketSize) // No more pk for transmitting + if (!PacketSize) /* No more pk for transmitting */ break; } while(true); - // - // Start to send by lower module - // + /* + * Start to send by lower module + */ if (!pHwData->IsKeyPreSet) Wb35Tx_start(adapter); @@ -558,20 +558,20 @@ Mds_SendComplete(struct wbsoft_priv * adapter, PT02_DESCRIPTOR pT02) unsigned char SendOK = true; u8 RetryCount, TxRate; - if (pT02->T02_IgnoreResult) // Don't care the result + if (pT02->T02_IgnoreResult) /* Don't care the result */ return; if (pT02->T02_IsLastMpdu) { - //TODO: DTO -- get the retry count and fragment count - // Tx rate + /* TODO: DTO -- get the retry count and fragment count */ + /* Tx rate */ TxRate = pMds->TxRate[ PacketId ][ 0 ]; RetryCount = (u8)pT02->T02_MPDU_Cnt; if (pT02->value & FLAG_ERROR_TX_MASK) { SendOK = false; if (pT02->T02_transmit_abort || pT02->T02_out_of_MaxTxMSDULiftTime) { - //retry error + /* retry error */ pHwData->dto_tx_retry_count += (RetryCount+1); - //[for tx debug] + /* [for tx debug] */ if (RetryCount<7) pHwData->tx_retry_count[RetryCount] += RetryCount; else @@ -583,7 +583,7 @@ Mds_SendComplete(struct wbsoft_priv * adapter, PT02_DESCRIPTOR pT02) } pHwData->dto_tx_frag_count += (RetryCount+1); - //[for tx debug] + /* [for tx debug] */ if (pT02->T02_transmit_abort_due_to_TBTT) pHwData->tx_TBTT_start_count++; if (pT02->T02_transmit_without_encryption_due_to_wep_on_false) @@ -596,7 +596,7 @@ Mds_SendComplete(struct wbsoft_priv * adapter, PT02_DESCRIPTOR pT02) MTO_SetTxCount(adapter, TxRate, RetryCount); } - // Clear send result buffer + /* Clear send result buffer */ pMds->TxResult[ PacketId ] = 0; } else pMds->TxResult[ PacketId ] |= ((u16)(pT02->value & 0x0ffff)); -- cgit v1.2.3 From 15df6385d940ad5486b4c2de8ab45979b13349fe Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 11 Mar 2010 18:22:51 +0200 Subject: Staging: crystalhd: fix device_create() return value check Use IS_ERR() instead of comparing to NULL. Signed-off-by: Jani Nikula Cc: Jarod Wilson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/crystalhd/crystalhd_lnx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c index 54bad652c0c5..3c562f0f86b3 100644 --- a/drivers/staging/crystalhd/crystalhd_lnx.c +++ b/drivers/staging/crystalhd/crystalhd_lnx.c @@ -376,7 +376,7 @@ static int __devinit chd_dec_init_chdev(struct crystalhd_adp *adp) dev = device_create(crystalhd_class, NULL, MKDEV(adp->chd_dec_major, 0), NULL, "crystalhd"); - if (!dev) { + if (IS_ERR(dev)) { BCMLOG_ERR("failed to create device\n"); goto device_create_fail; } -- cgit v1.2.3 From 641b63f9981a082eeefab3b395203a54dcd6e93b Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Thu, 11 Mar 2010 00:21:20 +0100 Subject: Staging: crystalhd: Whitespace fixes, indentation fixes and 3 changed #includes These patches fixes some whitspace and indentation warnings from checkpatch.pl Also these changed #includes: bc_dts_glob_lnx.h:43: WARNING: Use #include instead of rystalhd_lnx.h:45: WARNING: Use #include instead of crystalhd_lnx.h:49: WARNING: Use #include instead of It all compiles fine, but I don't have the hardware to test with.. Signed-off-by: Lars Lindley Cc: Jarod Wilson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/crystalhd/bc_dts_glob_lnx.h | 2 +- drivers/staging/crystalhd/bc_dts_types.h | 2 +- drivers/staging/crystalhd/bcm_70012_regs.h | 24 ++++++++++++------------ drivers/staging/crystalhd/crystalhd_cmds.c | 20 ++++++++++---------- drivers/staging/crystalhd/crystalhd_cmds.h | 2 +- drivers/staging/crystalhd/crystalhd_lnx.c | 26 +++++++++++++------------- drivers/staging/crystalhd/crystalhd_lnx.h | 4 ++-- drivers/staging/crystalhd/crystalhd_misc.c | 18 +++++++++--------- 8 files changed, 49 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/crystalhd/bc_dts_glob_lnx.h b/drivers/staging/crystalhd/bc_dts_glob_lnx.h index b3125e3e0372..0fd34e20dc88 100644 --- a/drivers/staging/crystalhd/bc_dts_glob_lnx.h +++ b/drivers/staging/crystalhd/bc_dts_glob_lnx.h @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/staging/crystalhd/bc_dts_types.h b/drivers/staging/crystalhd/bc_dts_types.h index ac0c81717385..95a2f875f1e7 100644 --- a/drivers/staging/crystalhd/bc_dts_types.h +++ b/drivers/staging/crystalhd/bc_dts_types.h @@ -25,7 +25,7 @@ #ifndef _BC_DTS_TYPES_H_ #define _BC_DTS_TYPES_H_ -#ifdef __LINUX_USER__ // Don't include these for KERNEL.. +#ifdef __LINUX_USER__ /* Don't include these for KERNEL.. */ #include #endif diff --git a/drivers/staging/crystalhd/bcm_70012_regs.h b/drivers/staging/crystalhd/bcm_70012_regs.h index 6922f54e432f..f3ab3146cd90 100644 --- a/drivers/staging/crystalhd/bcm_70012_regs.h +++ b/drivers/staging/crystalhd/bcm_70012_regs.h @@ -25,22 +25,22 @@ * m = memory, c = core, r = register, f = field, d = data. */ #if !defined(GET_FIELD) && !defined(SET_FIELD) -#define BRCM_ALIGN(c,r,f) c##_##r##_##f##_ALIGN -#define BRCM_BITS(c,r,f) c##_##r##_##f##_BITS -#define BRCM_MASK(c,r,f) c##_##r##_##f##_MASK -#define BRCM_SHIFT(c,r,f) c##_##r##_##f##_SHIFT +#define BRCM_ALIGN(c, r, f) c##_##r##_##f##_ALIGN +#define BRCM_BITS(c, r, f) c##_##r##_##f##_BITS +#define BRCM_MASK(c, r, f) c##_##r##_##f##_MASK +#define BRCM_SHIFT(c, r, f) c##_##r##_##f##_SHIFT -#define GET_FIELD(m,c,r,f) \ - ((((m) & BRCM_MASK(c,r,f)) >> BRCM_SHIFT(c,r,f)) << BRCM_ALIGN(c,r,f)) +#define GET_FIELD(m, c, r, f) \ + ((((m) & BRCM_MASK(c, r, f)) >> BRCM_SHIFT(c, r, f)) << BRCM_ALIGN(c, r, f)) -#define SET_FIELD(m,c,r,f,d) \ - ((m) = (((m) & ~BRCM_MASK(c,r,f)) | ((((d) >> BRCM_ALIGN(c,r,f)) << \ - BRCM_SHIFT(c,r,f)) & BRCM_MASK(c,r,f))) \ +#define SET_FIELD(m, c, r, f, d) \ + ((m) = (((m) & ~BRCM_MASK(c, r, f)) | ((((d) >> BRCM_ALIGN(c, r, f)) << \ + BRCM_SHIFT(c, r, f)) & BRCM_MASK(c, r, f))) \ ) -#define SET_TYPE_FIELD(m,c,r,f,d) SET_FIELD(m,c,r,f,c##_##d) -#define SET_NAME_FIELD(m,c,r,f,d) SET_FIELD(m,c,r,f,c##_##r##_##f##_##d) -#define SET_VALUE_FIELD(m,c,r,f,d) SET_FIELD(m,c,r,f,d) +#define SET_TYPE_FIELD(m, c, r, f, d) SET_FIELD(m, c, r, f, c##_##d) +#define SET_NAME_FIELD(m, c, r, f, d) SET_FIELD(m, c, r, f, c##_##r##_##f##_##d) +#define SET_VALUE_FIELD(m, c, r, f, d) SET_FIELD(m, c, r, f, d) #endif /* GET & SET */ diff --git a/drivers/staging/crystalhd/crystalhd_cmds.c b/drivers/staging/crystalhd/crystalhd_cmds.c index 26145a8d0f78..d826715809df 100644 --- a/drivers/staging/crystalhd/crystalhd_cmds.c +++ b/drivers/staging/crystalhd/crystalhd_cmds.c @@ -88,7 +88,7 @@ static BC_STATUS bc_cproc_notify_mode(struct crystalhd_cmd *ctx, return BC_STS_SUCCESS; } if (ctx->state != BC_LINK_INVALID) { - BCMLOG_ERR("Link invalid state %d \n", ctx->state); + BCMLOG_ERR("Link invalid state %d\n", ctx->state); return BC_STS_ERR_USAGE; } /* Check for duplicate playback sessions..*/ @@ -301,7 +301,7 @@ static BC_STATUS bc_cproc_download_fw(struct crystalhd_cmd *ctx, } if (ctx->state != BC_LINK_INVALID) { - BCMLOG_ERR("Link invalid state %d \n", ctx->state); + BCMLOG_ERR("Link invalid state %d\n", ctx->state); return BC_STS_ERR_USAGE; } @@ -309,7 +309,7 @@ static BC_STATUS bc_cproc_download_fw(struct crystalhd_cmd *ctx, idata->add_cdata_sz); if (sts != BC_STS_SUCCESS) { - BCMLOG_ERR("Firmware Download Failure!! - %d\n", sts); + BCMLOG_ERR("Firmware Download Failure!! - %d\n", sts) } else ctx->state |= BC_LINK_INIT; @@ -335,7 +335,7 @@ static BC_STATUS bc_cproc_do_fw_cmd(struct crystalhd_cmd *ctx, crystalhd_ioctl_d uint32_t *cmd; if (!(ctx->state & BC_LINK_INIT)) { - BCMLOG_ERR("Link invalid state %d \n", ctx->state); + BCMLOG_ERR("Link invalid state %d\n", ctx->state); return BC_STS_ERR_USAGE; } @@ -379,7 +379,7 @@ static void bc_proc_in_completion(crystalhd_dio_req *dio_hnd, return; } if (sts == BC_STS_IO_USER_ABORT) - return; + return; dio_hnd->uinfo.comp_sts = sts; dio_hnd->uinfo.ev_sts = 1; @@ -452,7 +452,7 @@ static BC_STATUS bc_cproc_hw_txdma(struct crystalhd_cmd *ctx, if (!rc) { return dio->uinfo.comp_sts; } else if (rc == -EBUSY) { - BCMLOG(BCMLOG_DBG, "_tx_post() T/O \n"); + BCMLOG(BCMLOG_DBG, "_tx_post() T/O\n"); sts = BC_STS_TIMEOUT; } else if (rc == -EINTR) { BCMLOG(BCMLOG_DBG, "Tx Wait Signal int.\n"); @@ -482,7 +482,7 @@ static BC_STATUS bc_cproc_check_inbuffs(bool pin, void *ubuff, uint32_t ub_sz, /* Check for alignment */ if (((uintptr_t)ubuff) & 0x03) { - BCMLOG_ERR("%s-->Un-aligned address not implemented yet.. %p \n", + BCMLOG_ERR("%s-->Un-aligned address not implemented yet.. %p\n", ((pin) ? "TX" : "RX"), ubuff); return BC_STS_NOT_IMPL; } @@ -523,7 +523,7 @@ static BC_STATUS bc_cproc_proc_input(struct crystalhd_cmd *ctx, crystalhd_ioctl_ sts = crystalhd_map_dio(ctx->adp, ubuff, ub_sz, 0, 0, 1, &dio_hnd); if (sts != BC_STS_SUCCESS) { - BCMLOG_ERR("dio map - %d \n", sts); + BCMLOG_ERR("dio map - %d\n", sts); return sts; } @@ -563,7 +563,7 @@ static BC_STATUS bc_cproc_add_cap_buff(struct crystalhd_cmd *ctx, sts = crystalhd_map_dio(ctx->adp, ubuff, ub_sz, uv_off, en_422, 0, &dio_hnd); if (sts != BC_STS_SUCCESS) { - BCMLOG_ERR("dio map - %d \n", sts); + BCMLOG_ERR("dio map - %d\n", sts); return sts; } @@ -1026,7 +1026,7 @@ crystalhd_cmd_proc crystalhd_get_cmd_proc(struct crystalhd_cmd *ctx, uint32_t cm if (g_crystalhd_cproc_tbl[i].cmd_id == cmd) { if ((uc->mode == DTS_MONITOR_MODE) && (g_crystalhd_cproc_tbl[i].block_mon)) { - BCMLOG(BCMLOG_INFO, "Blocking cmd %d \n", cmd); + BCMLOG(BCMLOG_INFO, "Blocking cmd %d\n", cmd); break; } cproc = g_crystalhd_cproc_tbl[i].cmd_proc; diff --git a/drivers/staging/crystalhd/crystalhd_cmds.h b/drivers/staging/crystalhd/crystalhd_cmds.h index 6b290aed8e0b..9989038b5c1b 100644 --- a/drivers/staging/crystalhd/crystalhd_cmds.h +++ b/drivers/staging/crystalhd/crystalhd_cmds.h @@ -66,7 +66,7 @@ struct crystalhd_cmd { struct crystalhd_hw hw_ctx; }; -typedef BC_STATUS (*crystalhd_cmd_proc)(struct crystalhd_cmd *, crystalhd_ioctl_data *); +typedef BC_STATUS(*crystalhd_cmd_proc)(struct crystalhd_cmd *, crystalhd_ioctl_data *); typedef struct _crystalhd_cmd_tbl { uint32_t cmd_id; diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c index 3c562f0f86b3..58fd91af0912 100644 --- a/drivers/staging/crystalhd/crystalhd_lnx.c +++ b/drivers/staging/crystalhd/crystalhd_lnx.c @@ -51,7 +51,7 @@ static int chd_dec_enable_int(struct crystalhd_adp *adp) rc = request_irq(adp->pdev->irq, chd_dec_isr, IRQF_SHARED, adp->name, (void *)adp); if (rc) { - BCMLOG_ERR("Interrupt request failed.. \n"); + BCMLOG_ERR("Interrupt request failed..\n"); pci_disable_msi(adp->pdev); } @@ -112,7 +112,7 @@ static inline int crystalhd_user_data(unsigned long ud, void *dr, int size, int int rc; if (!ud || !dr) { - BCMLOG_ERR("Invalid arg \n"); + BCMLOG_ERR("Invalid arg\n"); return -EINVAL; } @@ -122,7 +122,7 @@ static inline int crystalhd_user_data(unsigned long ud, void *dr, int size, int rc = copy_from_user(dr, (void *)ud, size); if (rc) { - BCMLOG_ERR("Invalid args for command \n"); + BCMLOG_ERR("Invalid args for command\n"); rc = -EFAULT; } @@ -206,7 +206,7 @@ static int chd_dec_proc_user_data(struct crystalhd_adp *adp, rc = crystalhd_user_data(ua, &io->udata, sizeof(io->udata), set); if (rc) { - BCMLOG_ERR("failed to %s iodata \n", (set ? "set" : "get")); + BCMLOG_ERR("failed to %s iodata\n", (set ? "set" : "get")); return rc; } @@ -308,7 +308,7 @@ static int chd_dec_open(struct inode *in, struct file *fd) sts = crystalhd_user_open(&adp->cmds, &uc); if (sts != BC_STS_SUCCESS) { - BCMLOG_ERR("cmd_user_open - %d \n", sts); + BCMLOG_ERR("cmd_user_open - %d\n", sts); rc = -EBUSY; } @@ -326,7 +326,7 @@ static int chd_dec_close(struct inode *in, struct file *fd) BCMLOG_ENTER; if (!adp) { - BCMLOG_ERR("Invalid adp \n"); + BCMLOG_ERR("Invalid adp\n"); return -EINVAL; } @@ -521,7 +521,7 @@ static void __devexit chd_dec_pci_remove(struct pci_dev *pdev) sts = crystalhd_delete_cmd_context(&pinfo->cmds); if (sts != BC_STS_SUCCESS) - BCMLOG_ERR("cmd delete :%d \n", sts); + BCMLOG_ERR("cmd delete :%d\n", sts); chd_dec_release_chdev(pinfo); @@ -581,7 +581,7 @@ static int __devinit chd_dec_pci_probe(struct pci_dev *pdev, chd_dec_init_chdev(pinfo); rc = chd_dec_enable_int(pinfo); if (rc) { - BCMLOG_ERR("_enable_int err:%d \n", rc); + BCMLOG_ERR("_enable_int err:%d\n", rc); pci_disable_device(pdev); return -ENODEV; } @@ -601,7 +601,7 @@ static int __devinit chd_dec_pci_probe(struct pci_dev *pdev, sts = crystalhd_setup_cmd_context(&pinfo->cmds, pinfo); if (sts != BC_STS_SUCCESS) { - BCMLOG_ERR("cmd setup :%d \n", sts); + BCMLOG_ERR("cmd setup :%d\n", sts); pci_disable_device(pdev); return -ENODEV; } @@ -675,7 +675,7 @@ int chd_dec_pci_resume(struct pci_dev *pdev) rc = chd_dec_enable_int(adp); if (rc) { - BCMLOG_ERR("_enable_int err:%d \n", rc); + BCMLOG_ERR("_enable_int err:%d\n", rc); pci_disable_device(pdev); return -ENODEV; } @@ -738,13 +738,13 @@ static int __init chd_dec_module_init(void) int rc; chd_set_log_level(NULL, "debug"); - BCMLOG(BCMLOG_DATA, "Loading crystalhd %d.%d.%d \n", + BCMLOG(BCMLOG_DATA, "Loading crystalhd %d.%d.%d\n", crystalhd_kmod_major, crystalhd_kmod_minor, crystalhd_kmod_rev); rc = pci_register_driver(&bc_chd_70012_driver); if (rc < 0) - BCMLOG_ERR("Could not find any devices. err:%d \n", rc); + BCMLOG_ERR("Could not find any devices. err:%d\n", rc); return rc; } @@ -752,7 +752,7 @@ module_init(chd_dec_module_init); static void __exit chd_dec_module_cleanup(void) { - BCMLOG(BCMLOG_DATA, "unloading crystalhd %d.%d.%d \n", + BCMLOG(BCMLOG_DATA, "unloading crystalhd %d.%d.%d\n", crystalhd_kmod_major, crystalhd_kmod_minor, crystalhd_kmod_rev); pci_unregister_driver(&bc_chd_70012_driver); diff --git a/drivers/staging/crystalhd/crystalhd_lnx.h b/drivers/staging/crystalhd/crystalhd_lnx.h index d338ae97a4cf..eee4926f04ea 100644 --- a/drivers/staging/crystalhd/crystalhd_lnx.h +++ b/drivers/staging/crystalhd/crystalhd_lnx.h @@ -42,11 +42,11 @@ #include #include -#include +#include #include #include #include -#include +#include #include "crystalhd_cmds.h" diff --git a/drivers/staging/crystalhd/crystalhd_misc.c b/drivers/staging/crystalhd/crystalhd_misc.c index 73593b078b33..d1346672531f 100644 --- a/drivers/staging/crystalhd/crystalhd_misc.c +++ b/drivers/staging/crystalhd/crystalhd_misc.c @@ -237,7 +237,7 @@ BC_STATUS crystalhd_mem_rd(struct crystalhd_adp *adp, uint32_t start_off, if (!adp || !rd_buff || (bc_chk_dram_range(adp, start_off, dw_cnt) != BC_STS_SUCCESS)) { - BCMLOG_ERR("Invalid arg \n"); + BCMLOG_ERR("Invalid arg\n"); return BC_STS_INV_ARG; } for (ix = 0; ix < dw_cnt; ix++) @@ -265,7 +265,7 @@ BC_STATUS crystalhd_mem_wr(struct crystalhd_adp *adp, uint32_t start_off, if (!adp || !wr_buff || (bc_chk_dram_range(adp, start_off, dw_cnt) != BC_STS_SUCCESS)) { - BCMLOG_ERR("Invalid arg \n"); + BCMLOG_ERR("Invalid arg\n"); return BC_STS_INV_ARG; } @@ -293,7 +293,7 @@ BC_STATUS crystalhd_pci_cfg_rd(struct crystalhd_adp *adp, uint32_t off, int rc = 0; if (!adp || !val) { - BCMLOG_ERR("Invalid arg \n"); + BCMLOG_ERR("Invalid arg\n"); return BC_STS_INV_ARG; } @@ -338,7 +338,7 @@ BC_STATUS crystalhd_pci_cfg_wr(struct crystalhd_adp *adp, uint32_t off, int rc = 0; if (!adp || !val) { - BCMLOG_ERR("Invalid arg \n"); + BCMLOG_ERR("Invalid arg\n"); return BC_STS_INV_ARG; } @@ -685,7 +685,7 @@ BC_STATUS crystalhd_map_dio(struct crystalhd_adp *adp, void *ubuff, int i = 0, rw = 0, res = 0, nr_pages = 0, skip_fb_sg = 0; if (!adp || !ubuff || !ubuff_sz || !dio_hnd) { - BCMLOG_ERR("Invalid arg \n"); + BCMLOG_ERR("Invalid arg\n"); return BC_STS_INV_ARG; } /* Compute pages */ @@ -791,7 +791,7 @@ BC_STATUS crystalhd_map_dio(struct crystalhd_adp *adp, void *ubuff, dio->sg_cnt = pci_map_sg(adp->pdev, dio->sg, dio->page_cnt, dio->direction); if (dio->sg_cnt <= 0) { - BCMLOG_ERR("sg map %d-%d \n", dio->sg_cnt, dio->page_cnt); + BCMLOG_ERR("sg map %d-%d\n", dio->sg_cnt, dio->page_cnt); crystalhd_unmap_dio(adp, dio); return BC_STS_ERROR; } @@ -826,7 +826,7 @@ BC_STATUS crystalhd_unmap_dio(struct crystalhd_adp *adp, crystalhd_dio_req *dio) int j = 0; if (!adp || !dio) { - BCMLOG_ERR("Invalid arg \n"); + BCMLOG_ERR("Invalid arg\n"); return BC_STS_INV_ARG; } @@ -947,7 +947,7 @@ void crystalhd_destroy_dio_pool(struct crystalhd_adp *adp) adp->fill_byte_pool = NULL; } - BCMLOG(BCMLOG_DBG, "Released dio pool %d \n", count); + BCMLOG(BCMLOG_DBG, "Released dio pool %d\n", count); } /** @@ -973,7 +973,7 @@ int __devinit crystalhd_create_elem_pool(struct crystalhd_adp *adp, for (i = 0; i < pool_size; i++) { temp = kzalloc(sizeof(*temp), GFP_KERNEL); if (!temp) { - BCMLOG_ERR("kalloc failed \n"); + BCMLOG_ERR("kalloc failed\n"); return -ENOMEM; } crystalhd_free_elem(adp, temp); -- cgit v1.2.3 From 63f63d236b14b5afbac882a1a47d936fbb14c5b4 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Fri, 12 Mar 2010 21:05:41 +0800 Subject: Staging: wlan-ng: remove duplicated #include Remove duplicated #include('s) in drivers/staging/wlan-ng/p80211wext.c Signed-off-by: Huang Weiyi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211wext.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/p80211wext.c b/drivers/staging/wlan-ng/p80211wext.c index 83f1d6cd7991..dc72661f0661 100644 --- a/drivers/staging/wlan-ng/p80211wext.c +++ b/drivers/staging/wlan-ng/p80211wext.c @@ -49,7 +49,6 @@ #include #include #include -#include #include "p80211types.h" #include "p80211hdr.h" -- cgit v1.2.3 From 773cde9a496f1f2db6612927863d649bda2dc8da Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Fri, 12 Mar 2010 22:13:43 +0800 Subject: Staging: remove unused #include Remove unused #include ('s) in drivers/staging/dt3155/allocator.c drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c drivers/staging/vme/boards/vme_vmivme7805.c Signed-off-by: Huang Weiyi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dt3155/allocator.c | 1 - drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c | 1 - drivers/staging/vme/boards/vme_vmivme7805.c | 1 - 3 files changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dt3155/allocator.c b/drivers/staging/dt3155/allocator.c index db382ef90217..6fbd0507288c 100644 --- a/drivers/staging/dt3155/allocator.c +++ b/drivers/staging/dt3155/allocator.c @@ -45,7 +45,6 @@ # define MODULE #endif -#include #include #include diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c index 48537d948945..81aa2ed226ac 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/vme/boards/vme_vmivme7805.c b/drivers/staging/vme/boards/vme_vmivme7805.c index 843c9edde555..80eaa0c4fe1c 100644 --- a/drivers/staging/vme/boards/vme_vmivme7805.c +++ b/drivers/staging/vme/boards/vme_vmivme7805.c @@ -10,7 +10,6 @@ * option) any later version. */ -#include #include #include #include -- cgit v1.2.3 From 09a3c4aeb108dcc2ee89370c511e263dbcc94563 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Fri, 12 Mar 2010 21:05:26 +0800 Subject: Staging: sep: remove duplicated #include Remove duplicated #include('s) in drivers/staging/sep/sep_driver.c Signed-off-by: Huang Weiyi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index 88880734921a..0332c370fd82 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From 59200df52cf7d4bfb93aeb30289a8e9d2af3058d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Apr 2010 22:01:31 -0500 Subject: Staging: dt3155: fix wait_ibsyclr function The wait_ibsyclr function is supposed to return the status of the I2C cycle. Currently it will always return FALSE because the IIC_CSR2 register is not re-read in order to update the cached register value. This results in the NEW_CYCLE bit still being 1. The current code actually works correctly only because the return value of {Read|Write}I2C is not checked in the driver. Fix wait_ibsyclr by actually reading the IIC_CSR2 register to get the updated status. While here, change the return type to be an actual errno instead of the private TRUE/FALSE define and remove the now obvious comments about the return value. Also, remove the local variable 'writestat' in WriteI2C and just return the result of wait_ibsyclr. Signed-off-by: H Hartley Sweeten Cc: Scott Smedley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dt3155/dt3155_io.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dt3155/dt3155_io.c b/drivers/staging/dt3155/dt3155_io.c index 6b9c68501a61..7792e712d16e 100644 --- a/drivers/staging/dt3155/dt3155_io.c +++ b/drivers/staging/dt3155/dt3155_io.c @@ -74,23 +74,22 @@ u8 i2c_pm_lut_data; * wait_ibsyclr() * * This function handles read/write timing and r/w timeout error - * - * Returns TRUE if NEW_CYCLE clears - * Returns FALSE if NEW_CYCLE doesn't clear in roughly 3 msecs, otherwise - * returns 0 */ static int wait_ibsyclr(u8 *lpReg) { /* wait 100 microseconds */ udelay(100L); /* __delay(loops_per_sec/10000); */ + + ReadMReg(lpReg + IIC_CSR2, iic_csr2_r.reg); if (iic_csr2_r.fld.NEW_CYCLE) { /* if NEW_CYCLE didn't clear */ /* TIMEOUT ERROR */ dt3155_errno = DT_ERR_I2C_TIMEOUT; - return FALSE; - } else - return TRUE; /* no error */ + return -ETIMEDOUT; + } + + return 0; /* no error */ } /* @@ -101,14 +100,9 @@ static int wait_ibsyclr(u8 *lpReg) * 1st parameter is pointer to 32-bit register base address * 2nd parameter is reg. index; * 3rd is value to be written - * - * Returns TRUE - Successful completion - * FALSE - Timeout error - cycle did not complete! */ int WriteI2C(u8 *lpReg, u_short wIregIndex, u8 byVal) { - int writestat; /* status for return */ - /* read 32 bit IIC_CSR2 register data into union */ ReadMReg((lpReg + IIC_CSR2), iic_csr2_r.reg); @@ -126,8 +120,7 @@ int WriteI2C(u8 *lpReg, u_short wIregIndex, u8 byVal) WriteMReg((lpReg + IIC_CSR2), iic_csr2_r.reg); /* wait for IIC cycle to finish */ - writestat = wait_ibsyclr(lpReg); - return writestat; + return wait_ibsyclr(lpReg); } /* @@ -138,9 +131,6 @@ int WriteI2C(u8 *lpReg, u_short wIregIndex, u8 byVal) * 1st parameter is pointer to 32-bit register base address * 2nd parameter is reg. index; * 3rd is adrs of value to be read - * - * Returns TRUE - Successful completion - * FALSE - Timeout error - cycle did not complete! */ int ReadI2C(u8 *lpReg, u_short wIregIndex, u8 *byVal) { -- cgit v1.2.3 From b1f2ac07636aadee5cb077fc7e830908b00fcaae Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 27 Apr 2010 20:15:07 +0200 Subject: Staging: push down BKL into ioctl functions Signed-off-by: Arnd Bergmann Cc: Frederic Weisbecker Signed-off-by: Greg Kroah-Hartman --- drivers/staging/crystalhd/crystalhd_lnx.c | 13 +++++++++---- drivers/staging/dt3155/dt3155_drv.c | 24 ++++++++++++++++++------ drivers/staging/vme/devices/vme_user.c | 18 +++++++++++++++--- 3 files changed, 42 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c index 58fd91af0912..6090a1d59549 100644 --- a/drivers/staging/crystalhd/crystalhd_lnx.c +++ b/drivers/staging/crystalhd/crystalhd_lnx.c @@ -16,6 +16,7 @@ ***************************************************************************/ #include +#include #include #include "crystalhd_lnx.h" @@ -261,12 +262,12 @@ static int chd_dec_api_cmd(struct crystalhd_adp *adp, unsigned long ua, } /* API interfaces */ -static int chd_dec_ioctl(struct inode *in, struct file *fd, - unsigned int cmd, unsigned long ua) +static long chd_dec_ioctl(struct file *fd, unsigned int cmd, unsigned long ua) { struct crystalhd_adp *adp = chd_get_adp(); crystalhd_cmd_proc cproc; struct crystalhd_user *uc; + int ret; if (!adp || !fd) { BCMLOG_ERR("Invalid adp\n"); @@ -279,13 +280,17 @@ static int chd_dec_ioctl(struct inode *in, struct file *fd, return -ENODATA; } + lock_kernel(); cproc = crystalhd_get_cmd_proc(&adp->cmds, cmd, uc); if (!cproc) { BCMLOG_ERR("Unhandled command: %d\n", cmd); + unlock_kernel(); return -EINVAL; } - return chd_dec_api_cmd(adp, ua, uc->uid, cmd, cproc); + ret = chd_dec_api_cmd(adp, ua, uc->uid, cmd, cproc); + unlock_kernel(); + return ret; } static int chd_dec_open(struct inode *in, struct file *fd) @@ -345,7 +350,7 @@ static int chd_dec_close(struct inode *in, struct file *fd) static const struct file_operations chd_dec_fops = { .owner = THIS_MODULE, - .ioctl = chd_dec_ioctl, + .unlocked_ioctl = chd_dec_ioctl, .open = chd_dec_open, .release = chd_dec_close, }; diff --git a/drivers/staging/dt3155/dt3155_drv.c b/drivers/staging/dt3155/dt3155_drv.c index e2c44ec6fc45..7e6095f43f16 100644 --- a/drivers/staging/dt3155/dt3155_drv.c +++ b/drivers/staging/dt3155/dt3155_drv.c @@ -63,6 +63,7 @@ extern void printques(int); #include #include #include +#include #include #include @@ -835,6 +836,17 @@ static unsigned int dt3155_poll (struct file * filp, poll_table *wait) return 0; } +static long +dt3155_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = dt3155_ioctl(file->f_path.dentry->d_inode, file, cmd, arg); + unlock_kernel(); + + return ret; +} /***************************************************** * file operations supported by DT3155 driver @@ -842,12 +854,12 @@ static unsigned int dt3155_poll (struct file * filp, poll_table *wait) * register_chrdev *****************************************************/ static struct file_operations dt3155_fops = { - read: dt3155_read, - ioctl: dt3155_ioctl, - mmap: dt3155_mmap, - poll: dt3155_poll, - open: dt3155_open, - release: dt3155_close + .read = dt3155_read, + .unlocked_ioctl = dt3155_unlocked_ioctl, + .mmap = dt3155_mmap, + .poll = dt3155_poll, + .open = dt3155_open, + .release = dt3155_close }; diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index 1ab9a985dfb9..bc16fc070fd3 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -130,8 +131,7 @@ static int vme_user_release(struct inode *, struct file *); static ssize_t vme_user_read(struct file *, char *, size_t, loff_t *); static ssize_t vme_user_write(struct file *, const char *, size_t, loff_t *); static loff_t vme_user_llseek(struct file *, loff_t, int); -static int vme_user_ioctl(struct inode *, struct file *, unsigned int, - unsigned long); +static long vme_user_unlocked_ioctl(struct file *, unsigned int, unsigned long); static int __init vme_user_probe(struct device *, int, int); static int __exit vme_user_remove(struct device *, int, int); @@ -142,7 +142,7 @@ static struct file_operations vme_user_fops = { .read = vme_user_read, .write = vme_user_write, .llseek = vme_user_llseek, - .ioctl = vme_user_ioctl, + .unlocked_ioctl = vme_user_unlocked_ioctl, }; @@ -555,6 +555,18 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, return -EINVAL; } +static long +vme_user_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = vme_user_ioctl(file->f_path.dentry->d_inode, file, cmd, arg); + unlock_kernel(); + + return ret; +} + /* * Unallocate a previously allocated buffer -- cgit v1.2.3 From 25f1a98bfd0b2a097c8477e4b7bdf6dccf3886b6 Mon Sep 17 00:00:00 2001 From: Jason Wong Date: Sat, 13 Mar 2010 00:32:33 +0800 Subject: Staging: comedi: amplc_pci230: fix brace coding style issue Fixed multiple brace coding style issue. Signed-off-by: Jason Wong Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 132 +++++++++++++------------- 1 file changed, 66 insertions(+), 66 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 091a1a5822a8..7fffd967d47e 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -669,9 +669,9 @@ static short pci230_ai_read(struct comedi_device *dev) /* If a bipolar range was specified, mangle it (twos * complement->straight binary). */ - if (devpriv->ai_bipolar) { + if (devpriv->ai_bipolar) data ^= 1 << (thisboard->ai_bits - 1); - } + return data; } @@ -680,9 +680,9 @@ static inline unsigned short pci230_ao_mangle_datum(struct comedi_device *dev, { /* If a bipolar range was specified, mangle it (straight binary->twos * complement). */ - if (devpriv->ao_bipolar) { + if (devpriv->ao_bipolar) datum ^= 1 << (thisboard->ao_bits - 1); - } + /* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower * four bits reserved for expansion). */ @@ -734,9 +734,9 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Allocate the private structure area using alloc_private(). * Macro defined in comedidev.h - memsets struct fields to 0. */ - if ((alloc_private(dev, sizeof(struct pci230_private))) < 0) { + if ((alloc_private(dev, sizeof(struct pci230_private))) < 0) return -ENOMEM; - } + spin_lock_init(&devpriv->isr_spinlock); spin_lock_init(&devpriv->res_spinlock); spin_lock_init(&devpriv->ai_stop_spinlock); @@ -991,9 +991,9 @@ static int pci230_detach(struct comedi_device *dev) if (devpriv) { if (devpriv->pci_dev) { - if (dev->iobase) { + if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); - } + pci_dev_put(devpriv->pci_dev); } } @@ -1055,9 +1055,9 @@ static void put_resources(struct comedi_device *dev, unsigned int res_mask, && (res_mask != 0); b <<= 1, i++) { if ((res_mask & b) != 0) { res_mask &= ~b; - if (devpriv->res_owner[i] == owner) { + if (devpriv->res_owner[i] == owner) devpriv->res_owner[i] = OWNER_NONE; - } + } } spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags); @@ -1132,11 +1132,11 @@ static int pci230_ai_rinsn(struct comedi_device *dev, } devpriv->adcg = (devpriv->adcg & ~(3 << gainshift)) | (pci230_ai_gain[range] << gainshift); - if (devpriv->ai_bipolar) { + if (devpriv->ai_bipolar) adccon |= PCI230_ADC_IR_BIP; - } else { + else adccon |= PCI230_ADC_IR_UNI; - } + /* Enable only this channel in the scan list - otherwise by default * we'll get one sample from each channel. */ @@ -1408,13 +1408,13 @@ static int pci230_ao_cmdtest(struct comedi_device *dev, chan = CR_CHAN(cmd->chanlist[n]); range = CR_RANGE(cmd->chanlist[n]); /* Channel numbers must strictly increase. */ - if (chan < prev_chan) { + if (chan < prev_chan) errors |= seq_err; - } + /* Ranges must be the same. */ - if (range != first_range) { + if (range != first_range) errors |= range_err; - } + prev_chan = chan; } if (errors != 0) { @@ -1583,9 +1583,9 @@ static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (cmd->scan_begin_src == TRIG_TIMER) { /* Claim Z2-CT1. */ - if (!get_one_resource(dev, RES_Z2CT1, OWNER_AOCMD)) { + if (!get_one_resource(dev, RES_Z2CT1, OWNER_AOCMD)) return -EBUSY; - } + } /* Get number of scans required. */ @@ -1609,9 +1609,9 @@ static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) unsigned int i; dacen = 0; - for (i = 0; i < cmd->chanlist_len; i++) { + for (i = 0; i < cmd->chanlist_len; i++) dacen |= 1 << CR_CHAN(cmd->chanlist[i]); - } + /* Set channel scan list. */ outw(dacen, dev->iobase + PCI230P2_DACEN); /* @@ -1656,9 +1656,9 @@ static int pci230_ai_check_scan_period(struct comedi_cmd *cmd) int err = 0; chanlist_len = cmd->chanlist_len; - if (cmd->chanlist_len == 0) { + if (cmd->chanlist_len == 0) chanlist_len = 1; - } + min_scan_period = chanlist_len * cmd->convert_arg; if ((min_scan_period < chanlist_len) || (min_scan_period < cmd->convert_arg)) { @@ -1777,11 +1777,11 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, * single-ended or pseudo-differential. */ if (cmd->chanlist && (cmd->chanlist_len > 0)) { /* Peek analogue reference of first channel. */ - if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF) { + if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF) max_speed_ai = MAX_SPEED_AI_DIFF; - } else { + else max_speed_ai = MAX_SPEED_AI_SE; - } + } else { /* No channel list. Assume single-ended. */ max_speed_ai = MAX_SPEED_AI_SE; @@ -1871,9 +1871,9 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, } } else if (cmd->scan_begin_src == TRIG_TIMER) { /* N.B. cmd->convert_arg is also TRIG_TIMER */ - if (!pci230_ai_check_scan_period(cmd)) { + if (!pci230_ai_check_scan_period(cmd)) err++; - } + } else { if (cmd->scan_begin_arg != 0) { cmd->scan_begin_arg = 0; @@ -1961,13 +1961,13 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, errors |= seq_err; } /* Channels must have same AREF. */ - if (aref != prev_aref) { + if (aref != prev_aref) errors |= aref_err; - } + /* Channel ranges must have same polarity. */ - if (polarity != prev_polarity) { + if (polarity != prev_polarity) errors |= polarity_err; - } + /* Single-ended channel pairs must have same * range. */ if ((aref != AREF_DIFF) @@ -1987,9 +1987,9 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, } /* If channel list is a repeating subsequence, need a whole * number of repeats. */ - if ((n % subseq_len) != 0) { + if ((n % subseq_len) != 0) errors |= seq_err; - } + if ((devpriv->hwver > 0) && (devpriv->hwver < 4)) { /* * Buggy PCI230+ or PCI260+ requires channel 0 to be @@ -2228,9 +2228,9 @@ static void pci230_ai_start(struct comedi_device *dev, devpriv->adccon = (devpriv->adccon & ~PCI230_ADC_TRIG_MASK) | conv; outw(devpriv->adccon, dev->iobase + PCI230_ADCCON); - if (cmd->convert_src == TRIG_INT) { + if (cmd->convert_src == TRIG_INT) async->inttrig = pci230_ai_inttrig_convert; - } + /* Update FIFO interrupt trigger level, which is currently * set to "full". */ pci230_ai_update_fifo_trigger_level(dev, s); @@ -2345,9 +2345,9 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) } } /* Claim resources. */ - if (!get_resources(dev, res_mask, OWNER_AICMD)) { + if (!get_resources(dev, res_mask, OWNER_AICMD)) return -EBUSY; - } + /* Get number of scans required. */ if (cmd->stop_src == TRIG_COUNT) { @@ -2392,11 +2392,11 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) range = CR_RANGE(cmd->chanlist[0]); devpriv->ai_bipolar = pci230_ai_bipolar[range]; - if (devpriv->ai_bipolar) { + if (devpriv->ai_bipolar) adccon |= PCI230_ADC_IR_BIP; - } else { + else adccon |= PCI230_ADC_IR_UNI; - } + for (i = 0; i < cmd->chanlist_len; i++) { unsigned int gainshift; @@ -2543,9 +2543,9 @@ static unsigned int pci230_choose_clk_count(uint64_t ns, unsigned int *count, for (clk_src = CLK_10MHZ;; clk_src++) { cnt = divide_ns(ns, pci230_timebase[clk_src], round_mode); - if ((cnt <= 65536) || (clk_src == CLK_1KHZ)) { + if ((cnt <= 65536) || (clk_src == CLK_1KHZ)) break; - } + } *count = cnt; return clk_src; @@ -2575,9 +2575,9 @@ static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct, /* Program clock source. */ outb(CLK_CONFIG(ct, clk_src), devpriv->iobase1 + PCI230_ZCLK_SCE); /* Set initial count. */ - if (count >= 65536) { + if (count >= 65536) count = 0; - } + i8254_write(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, count); } @@ -2599,9 +2599,9 @@ static irqreturn_t pci230_interrupt(int irq, void *d) /* Read interrupt status/enable register. */ status_int = inb(devpriv->iobase1 + PCI230_INT_STAT); - if (status_int == PCI230_INT_DISABLE) { + if (status_int == PCI230_INT_DISABLE) return IRQ_NONE; - } + spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); valid_status_int = devpriv->int_en & status_int; @@ -2660,9 +2660,9 @@ static void pci230_handle_ao_nofifo(struct comedi_device *dev, struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; - if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0)) { + if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0)) return; - } + for (i = 0; i < cmd->chanlist_len; i++) { /* Read sample from Comedi's circular buffer. */ @@ -2711,9 +2711,9 @@ static int pci230_handle_ao_fifo(struct comedi_device *dev, num_scans = comedi_buf_read_n_available(async) / bytes_per_scan; if (!devpriv->ao_continuous) { /* Fixed number of scans. */ - if (num_scans > devpriv->ao_scan_count) { + if (num_scans > devpriv->ao_scan_count) num_scans = devpriv->ao_scan_count; - } + if (devpriv->ao_scan_count == 0) { /* End of acquisition. */ events |= COMEDI_CB_EOA; @@ -2736,21 +2736,21 @@ static int pci230_handle_ao_fifo(struct comedi_device *dev, } if (events == 0) { /* Determine how much room is in the FIFO (in samples). */ - if ((dacstat & PCI230P2_DAC_FIFO_FULL) != 0) { + if ((dacstat & PCI230P2_DAC_FIFO_FULL) != 0) room = PCI230P2_DAC_FIFOROOM_FULL; - } else if ((dacstat & PCI230P2_DAC_FIFO_HALF) != 0) { + else if ((dacstat & PCI230P2_DAC_FIFO_HALF) != 0) room = PCI230P2_DAC_FIFOROOM_HALFTOFULL; - } else if ((dacstat & PCI230P2_DAC_FIFO_EMPTY) != 0) { + else if ((dacstat & PCI230P2_DAC_FIFO_EMPTY) != 0) room = PCI230P2_DAC_FIFOROOM_EMPTY; - } else { + else room = PCI230P2_DAC_FIFOROOM_ONETOHALF; - } + /* Convert room to number of scans that can be added. */ room /= cmd->chanlist_len; /* Determine number of scans to process. */ - if (num_scans > room) { + if (num_scans > room) num_scans = room; - } + /* Process scans. */ for (n = 0; n < num_scans; n++) { for (i = 0; i < cmd->chanlist_len; i++) { @@ -2817,14 +2817,14 @@ static void pci230_handle_ai(struct comedi_device *dev, } else { todo = (devpriv->ai_scan_count * scanlen) - devpriv->ai_scan_pos; - if (todo > PCI230_ADC_FIFOLEVEL_HALFFULL) { + if (todo > PCI230_ADC_FIFOLEVEL_HALFFULL) todo = PCI230_ADC_FIFOLEVEL_HALFFULL; - } + } - if (todo == 0) { + if (todo == 0) return; - } + fifoamount = 0; for (i = 0; i < todo; i++) { @@ -2906,9 +2906,9 @@ static void pci230_ao_stop(struct comedi_device *dev, spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags); started = test_and_clear_bit(AO_CMD_STARTED, &devpriv->state); spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags); - if (!started) { + if (!started) return; - } + cmd = &s->async->cmd; if (cmd->scan_begin_src == TRIG_TIMER) { @@ -2968,9 +2968,9 @@ static void pci230_ai_stop(struct comedi_device *dev, spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags); started = test_and_clear_bit(AI_CMD_STARTED, &devpriv->state); spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags); - if (!started) { + if (!started) return; - } + cmd = &s->async->cmd; if (cmd->convert_src == TRIG_TIMER) { -- cgit v1.2.3 From 0686e4f4a2e6f33c418c8d57d9a4fc82b89557b2 Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Thu, 11 Mar 2010 23:51:23 +0100 Subject: Staging: hv: trivial whitespace fixes found by checkpatch.pl Signed-off-by: Lars Lindley Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Connection.c | 4 ++-- drivers/staging/hv/NetVsc.c | 4 ++-- drivers/staging/hv/RingBuffer.c | 2 +- drivers/staging/hv/StorVsc.c | 4 ++-- drivers/staging/hv/VersionInfo.h | 4 ++-- drivers/staging/hv/blkvsc_drv.c | 10 +++++----- drivers/staging/hv/rndis.h | 2 +- drivers/staging/hv/storvsc_drv.c | 4 ++-- drivers/staging/hv/vmbus_drv.c | 14 +++++++------- 9 files changed, 24 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/Connection.c b/drivers/staging/hv/Connection.c index cf9c416e4b16..dbf00560e0ac 100644 --- a/drivers/staging/hv/Connection.c +++ b/drivers/staging/hv/Connection.c @@ -259,8 +259,8 @@ static void VmbusProcessChannelEvent(void *context) VmbusChannelOnChannelEvent(channel); /* * WorkQueueQueueWorkItem(channel->dataWorkQueue, - * VmbusChannelOnChannelEvent, - * (void*)channel); + * VmbusChannelOnChannelEvent, + * (void*)channel); */ } else { DPRINT_ERR(VMBUS, "channel not found for relid - %d.", relId); diff --git a/drivers/staging/hv/NetVsc.c b/drivers/staging/hv/NetVsc.c index e1ca343119d7..f84942df3bbf 100644 --- a/drivers/staging/hv/NetVsc.c +++ b/drivers/staging/hv/NetVsc.c @@ -1087,7 +1087,7 @@ static void NetVscOnReceive(struct hv_device *Device, } /* Remove the 1st packet to represent the xfer page packet itself */ - xferpagePacket = (struct xferpage_packet*)listHead.next; + xferpagePacket = (struct xferpage_packet *)listHead.next; list_del(&xferpagePacket->ListEntry); /* This is how much we can satisfy */ @@ -1103,7 +1103,7 @@ static void NetVscOnReceive(struct hv_device *Device, /* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */ for (i = 0; i < (count - 1); i++) { - netvscPacket = (struct hv_netvsc_packet*)listHead.next; + netvscPacket = (struct hv_netvsc_packet *)listHead.next; list_del(&netvscPacket->ListEntry); /* Initialize the netvsc packet */ diff --git a/drivers/staging/hv/RingBuffer.c b/drivers/staging/hv/RingBuffer.c index 80b8a2c7784f..08b3c5567e9c 100644 --- a/drivers/staging/hv/RingBuffer.c +++ b/drivers/staging/hv/RingBuffer.c @@ -32,7 +32,7 @@ /* Amount of space to write to */ -#define BYTES_AVAIL_TO_WRITE(r, w, z) ((w) >= (r))?((z) - ((w) - (r))):((r) - (w)) +#define BYTES_AVAIL_TO_WRITE(r, w, z) ((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w)) /*++ diff --git a/drivers/staging/hv/StorVsc.c b/drivers/staging/hv/StorVsc.c index 3592ba2a44b1..7372317fe836 100644 --- a/drivers/staging/hv/StorVsc.c +++ b/drivers/staging/hv/StorVsc.c @@ -554,7 +554,7 @@ static int StorVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) /* Save the channel properties to our storvsc channel */ /* props = (struct vmstorage_channel_properties *) - * channel->offerMsg.Offer.u.Standard.UserDefined; */ + * channel->offerMsg.Offer.u.Standard.UserDefined; */ /* FIXME: */ /* @@ -717,7 +717,7 @@ static int StorVscOnIORequest(struct hv_device *Device, } /* print_hex_dump_bytes("", DUMP_PREFIX_NONE, Request->Cdb, - * Request->CdbLen); */ + * Request->CdbLen); */ requestExtension->Request = Request; requestExtension->Device = Device; diff --git a/drivers/staging/hv/VersionInfo.h b/drivers/staging/hv/VersionInfo.h index 10d7b19a485f..82e74b1ab150 100644 --- a/drivers/staging/hv/VersionInfo.h +++ b/drivers/staging/hv/VersionInfo.h @@ -29,11 +29,11 @@ * * Definition of versioning is as follows; * - * Major Number Changes for these scenarios; + * Major Number Changes for these scenarios; * 1. When a new version of Windows Hyper-V * is released. * 2. A Major change has occurred in the - * Linux IC's. + * Linux IC's. * (For example the merge for the first time * into the kernel) Every time the Major Number * changes, the Revision number is reset to 0. diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index e80cae78b269..8f8637e51d9e 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -555,7 +555,7 @@ static int blkvsc_do_inquiry(struct block_device_context *blkdev) blkdev->device_type = UNKNOWN_DEV_TYPE; } - DPRINT_DBG(BLKVSC_DRV, "device type %d \n", device_type); + DPRINT_DBG(BLKVSC_DRV, "device type %d\n", device_type); blkdev->device_id_len = buf[7]; if (blkdev->device_id_len > 64) @@ -940,7 +940,7 @@ static int blkvsc_do_request(struct block_device_context *blkdev, int pending = 0; struct blkvsc_request_group *group = NULL; - DPRINT_DBG(BLKVSC_DRV, "blkdev %p req %p sect %lu \n", blkdev, req, + DPRINT_DBG(BLKVSC_DRV, "blkdev %p req %p sect %lu\n", blkdev, req, (unsigned long)blk_rq_pos(req)); /* Create a group to tie req to list of blkvsc_reqs */ @@ -1144,7 +1144,7 @@ static void blkvsc_request_completion(struct hv_storvsc_request *request) &blkvsc_req->group->blkvsc_req_list, req_entry) { DPRINT_DBG(BLKVSC_DRV, "completing blkvsc_req %p " - "sect_start %lu sect_count %ld \n", + "sect_start %lu sect_count %ld\n", comp_req, (unsigned long)comp_req->sector_start, comp_req->sector_count); @@ -1198,7 +1198,7 @@ static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev) &pend_req->group->blkvsc_req_list, req_entry) { DPRINT_DBG(BLKVSC_DRV, "completing blkvsc_req %p " - "sect_start %lu sect_count %ld \n", + "sect_start %lu sect_count %ld\n", comp_req, (unsigned long) comp_req->sector_start, comp_req->sector_count); @@ -1276,7 +1276,7 @@ static void blkvsc_request(struct request_queue *queue) struct request *req; int ret = 0; - DPRINT_DBG(BLKVSC_DRV, "- enter \n"); + DPRINT_DBG(BLKVSC_DRV, "- enter\n"); while ((req = blk_peek_request(queue)) != NULL) { DPRINT_DBG(BLKVSC_DRV, "- req %p\n", req); diff --git a/drivers/staging/hv/rndis.h b/drivers/staging/hv/rndis.h index 7c73277c1f9a..723e1f15b90d 100644 --- a/drivers/staging/hv/rndis.h +++ b/drivers/staging/hv/rndis.h @@ -622,7 +622,7 @@ struct rndis_message { /* get the size of an RNDIS message. Pass in the message type, */ /* struct rndis_set_request, struct rndis_packet for example */ #define RNDIS_MESSAGE_SIZE(Message) \ - (sizeof(Message) + (sizeof(struct rndis_message) - \ + (sizeof(Message) + (sizeof(struct rndis_message) - \ sizeof(union rndis_message_container))) /* get pointer to info buffer with message pointer */ diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 63360b27f5c3..5e28e4c36434 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -112,7 +112,7 @@ static struct scsi_host_template scsi_driver = { .slave_configure = storvsc_device_configure, .cmd_per_lun = 1, /* 64 max_queue * 1 target */ - .can_queue = STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS, + .can_queue = STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS, .this_id = -1, /* no use setting to 0 since ll_blk_rw reset it to 1 */ /* currently 32 */ @@ -767,7 +767,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, request->DataBuffer.Offset = sgl[0].offset; for (i = 0; i < scsi_sg_count(scmnd); i++) { - DPRINT_DBG(STORVSC_DRV, "sgl[%d] len %d offset %d \n", + DPRINT_DBG(STORVSC_DRV, "sgl[%d] len %d offset %d\n", i, sgl[i].length, sgl[i].offset); request->DataBuffer.PfnArray[i] = page_to_pfn(sg_page((&sgl[i]))); diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 2ff61b862015..d2a82aa3bbd8 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -237,13 +237,13 @@ static ssize_t vmbus_show_device_attr(struct device *dev, * vmbus_bus_init -Main vmbus driver initialization routine. * * Here, we - * - initialize the vmbus driver context - * - setup various driver entry points - * - invoke the vmbus hv main init routine - * - get the irq resource - * - invoke the vmbus to add the vmbus root device - * - setup the vmbus root device - * - retrieve the channel offers + * - initialize the vmbus driver context + * - setup various driver entry points + * - invoke the vmbus hv main init routine + * - get the irq resource + * - invoke the vmbus to add the vmbus root device + * - setup the vmbus root device + * - retrieve the channel offers */ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv)) { -- cgit v1.2.3 From 2a613e41ec7684ba863d54a9df3d964e2c7aa4c1 Mon Sep 17 00:00:00 2001 From: Wouter Van Rooy Date: Thu, 11 Mar 2010 20:51:14 +0100 Subject: Staging: cx25821 fixed C99 comments, white spaces and unnecessary braces This patch fixes some C99 style comments, trailing white spaces and some unnecessary 'if' braces found by checkpatch.pl Signed-off-by: Wouter Van Rooy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/cx25821/cx25821-alsa.c | 72 ++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/cx25821/cx25821-alsa.c b/drivers/staging/cx25821/cx25821-alsa.c index 061add30ba8a..f5a7719b9b9c 100644 --- a/drivers/staging/cx25821/cx25821-alsa.c +++ b/drivers/staging/cx25821/cx25821-alsa.c @@ -42,10 +42,10 @@ #define AUDIO_SRAM_CHANNEL SRAM_CH08 -#define dprintk(level,fmt, arg...) if (debug >= level) \ +#define dprintk(level, fmt, arg...) if (debug >= level) \ printk(KERN_INFO "%s/1: " fmt, chip->dev->name , ## arg) -#define dprintk_core(level,fmt, arg...) if (debug >= level) \ +#define dprintk_core(level, fmt, arg...) if (debug >= level) \ printk(KERN_DEBUG "%s/1: " fmt, chip->dev->name , ## arg) /**************************************************************************** @@ -105,7 +105,7 @@ MODULE_PARM_DESC(index, "Index value for cx25821 capture interface(s)."); MODULE_DESCRIPTION("ALSA driver module for cx25821 based capture cards"); MODULE_AUTHOR("Hiep Huynh"); MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{Conexant,25821}"); //"{{Conexant,23881}," +MODULE_SUPPORTED_DEVICE("{{Conexant,25821}"); /*"{{Conexant,23881},"*/ static unsigned int debug; module_param(debug, int, 0644); @@ -135,7 +135,7 @@ MODULE_PARM_DESC(debug, "enable debug messages"); * BOARD Specific: Sets audio DMA */ -static int _cx25821_start_audio_dma(snd_cx25821_card_t * chip) +static int _cx25821_start_audio_dma(snd_cx25821_card_t *chip) { struct cx25821_buffer *buf = chip->buf; struct cx25821_dev *dev = chip->dev; @@ -143,7 +143,7 @@ static int _cx25821_start_audio_dma(snd_cx25821_card_t * chip) &cx25821_sram_channels[AUDIO_SRAM_CHANNEL]; u32 tmp = 0; - // enable output on the GPIO 0 for the MCLK ADC (Audio) + /* enable output on the GPIO 0 for the MCLK ADC (Audio) */ cx25821_set_gpiopin_direction(chip->dev, 0, 0); /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */ @@ -158,18 +158,22 @@ static int _cx25821_start_audio_dma(snd_cx25821_card_t * chip) cx_write(AUD_A_LNGTH, buf->bpl); /* reset counter */ - cx_write(AUD_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET); //GP_COUNT_CONTROL_RESET = 0x3 + cx_write(AUD_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET); + /* GP_COUNT_CONTROL_RESET = 0x3 */ + atomic_set(&chip->count, 0); - //Set the input mode to 16-bit + /* Set the input mode to 16-bit */ tmp = cx_read(AUD_A_CFG); cx_write(AUD_A_CFG, tmp | FLD_AUD_DST_PK_MODE | FLD_AUD_DST_ENABLE | FLD_AUD_CLK_ENABLE); - //printk(KERN_INFO "DEBUG: Start audio DMA, %d B/line, cmds_start(0x%x)= %d lines/FIFO, %d periods, %d " - // "byte buffer\n", buf->bpl, audio_ch->cmds_start, cx_read(audio_ch->cmds_start + 12)>>1, - // chip->num_periods, buf->bpl * chip->num_periods); + /*printk(KERN_INFO "DEBUG: Start audio DMA, %d B/line, " + "cmds_start(0x%x)= %d lines/FIFO, %d periods, %d " + "byte buffer\n", buf->bpl, audio_ch->cmds_start, " + "cx_read(audio_ch->cmds_start + 12)>>1, + chip->num_periods, buf->bpl * chip->num_periods);*/ /* Enables corresponding bits at AUD_INT_STAT */ cx_write(AUD_A_INT_MSK, @@ -182,7 +186,7 @@ static int _cx25821_start_audio_dma(snd_cx25821_card_t * chip) /* enable audio irqs */ cx_set(PCI_INT_MSK, chip->dev->pci_irqmask | PCI_MSK_AUD_INT); - // Turn on audio downstream fifo and risc enable 0x101 + /* Turn on audio downstream fifo and risc enable 0x101 */ tmp = cx_read(AUD_INT_DMA_CTL); cx_set(AUD_INT_DMA_CTL, tmp | (FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN)); @@ -194,7 +198,7 @@ static int _cx25821_start_audio_dma(snd_cx25821_card_t * chip) /* * BOARD Specific: Resets audio DMA */ -static int _cx25821_stop_audio_dma(snd_cx25821_card_t * chip) +static int _cx25821_stop_audio_dma(snd_cx25821_card_t *chip) { struct cx25821_dev *dev = chip->dev; @@ -232,13 +236,12 @@ static char *cx25821_aud_irqs[32] = { /* * BOARD Specific: Threats IRQ audio specific calls */ -static void cx25821_aud_irq(snd_cx25821_card_t * chip, u32 status, u32 mask) +static void cx25821_aud_irq(snd_cx25821_card_t *chip, u32 status, u32 mask) { struct cx25821_dev *dev = chip->dev; - if (0 == (status & mask)) { + if (0 == (status & mask)) return; - } cx_write(AUD_A_INT_STAT, status); if (debug > 1 || (status & mask & ~0xff)) @@ -318,11 +321,11 @@ static irqreturn_t cx25821_irq(int irq, void *dev_id) if (handled) cx_write(PCI_INT_STAT, pci_status); - out: +out: return IRQ_RETVAL(handled); } -static int dsp_buffer_free(snd_cx25821_card_t * chip) +static int dsp_buffer_free(snd_cx25821_card_t *chip) { BUG_ON(!chip->dma_size); @@ -363,7 +366,8 @@ static struct snd_pcm_hardware snd_cx25821_digital_hw = { .period_bytes_max = DEFAULT_FIFO_SIZE / 3, .periods_min = 1, .periods_max = AUDIO_LINE_SIZE, - .buffer_bytes_max = (AUDIO_LINE_SIZE * AUDIO_LINE_SIZE), //128*128 = 16384 = 1024 * 16 + .buffer_bytes_max = (AUDIO_LINE_SIZE * AUDIO_LINE_SIZE), + /* 128*128 = 16384 = 1024 * 16 */ }; /* @@ -393,18 +397,20 @@ static int snd_cx25821_pcm_open(struct snd_pcm_substream *substream) if (cx25821_sram_channels[AUDIO_SRAM_CHANNEL].fifo_size != DEFAULT_FIFO_SIZE) { - bpl = cx25821_sram_channels[AUDIO_SRAM_CHANNEL].fifo_size / 3; //since there are 3 audio Clusters + /* since there are 3 audio Clusters */ + bpl = cx25821_sram_channels[AUDIO_SRAM_CHANNEL].fifo_size / 3; + bpl &= ~7; /* must be multiple of 8 */ - if (bpl > AUDIO_LINE_SIZE) { + if (bpl > AUDIO_LINE_SIZE) bpl = AUDIO_LINE_SIZE; - } + runtime->hw.period_bytes_min = bpl; runtime->hw.period_bytes_max = bpl; } return 0; - _error: +_error: dprintk(1, "Error opening PCM!\n"); return err; } @@ -445,9 +451,9 @@ static int snd_cx25821_hw_params(struct snd_pcm_substream *substream, if (NULL == buf) return -ENOMEM; - if (chip->period_size > AUDIO_LINE_SIZE) { + if (chip->period_size > AUDIO_LINE_SIZE) chip->period_size = AUDIO_LINE_SIZE; - } + buf->vb.memory = V4L2_MEMORY_MMAP; buf->vb.field = V4L2_FIELD_NONE; @@ -474,7 +480,7 @@ static int snd_cx25821_hw_params(struct snd_pcm_substream *substream, buf->vb.width, buf->vb.height, 1); if (ret < 0) { printk(KERN_INFO - "DEBUG: ERROR after cx25821_risc_databuffer_audio() \n"); + "DEBUG: ERROR after cx25821_risc_databuffer_audio()\n"); goto error; } @@ -494,7 +500,7 @@ static int snd_cx25821_hw_params(struct snd_pcm_substream *substream, return 0; - error: +error: kfree(buf); return ret; } @@ -593,10 +599,10 @@ static struct snd_pcm_ops snd_cx25821_pcm_ops = { }; /* - * ALSA create a PCM device: Called when initializing the board. Sets up the name and hooks up - * the callbacks + * ALSA create a PCM device: Called when initializing the board. + * Sets up the name and hooks up the callbacks */ -static int snd_cx25821_pcm(snd_cx25821_card_t * chip, int device, char *name) +static int snd_cx25821_pcm(snd_cx25821_card_t *chip, int device, char *name) { struct snd_pcm *pcm; int err; @@ -655,7 +661,7 @@ static void snd_cx25821_dev_free(struct snd_card *card) { snd_cx25821_card_t *chip = card->private_data; - //snd_cx25821_free(chip); + /*snd_cx25821_free(chip);*/ snd_card_free(chip->card); } @@ -671,13 +677,13 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev) if (devno >= SNDRV_CARDS) { printk(KERN_INFO "DEBUG ERROR: devno >= SNDRV_CARDS %s\n", __func__); - return (-ENODEV); + return -ENODEV; } if (!enable[devno]) { ++devno; printk(KERN_INFO "DEBUG ERROR: !enable[devno] %s\n", __func__); - return (-ENOENT); + return -ENOENT; } err = snd_card_create(index[devno], id[devno], THIS_MODULE, @@ -741,7 +747,7 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev) devno++; return 0; - error: +error: snd_card_free(card); return err; } -- cgit v1.2.3 From ee21350fae9333acc11e3b1b77c887fd94e450f5 Mon Sep 17 00:00:00 2001 From: Robert Babilon Date: Thu, 11 Mar 2010 13:45:35 -0600 Subject: Staging: comedi: fix export symbol warnings in ni_daq_700.c This is a patch to the ni_daq_700.c file that fixes several EXPORT_SYMBOL warnings found by the checkpatch.pl tool Signed-off-by: Robert Babilon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_700.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 7ea64538e055..7844203c1ed7 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -145,6 +145,7 @@ void subdev_700_interrupt(struct comedi_device *dev, struct comedi_subdevice *s) comedi_event(dev, s); } +EXPORT_SYMBOL(subdev_700_interrupt); static int subdev_700_cb(int dir, int port, int data, unsigned long arg) { @@ -326,6 +327,7 @@ int subdev_700_init(struct comedi_device *dev, struct comedi_subdevice *s, return 0; } +EXPORT_SYMBOL(subdev_700_init); int subdev_700_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, int (*cb) (int, int, int, unsigned long), @@ -345,6 +347,7 @@ int subdev_700_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, return 0; } +EXPORT_SYMBOL(subdev_700_init_irq); void subdev_700_cleanup(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -353,11 +356,7 @@ void subdev_700_cleanup(struct comedi_device *dev, struct comedi_subdevice *s) kfree(s->private); } - -EXPORT_SYMBOL(subdev_700_init); -EXPORT_SYMBOL(subdev_700_init_irq); EXPORT_SYMBOL(subdev_700_cleanup); -EXPORT_SYMBOL(subdev_700_interrupt); static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) { -- cgit v1.2.3 From 1b2e434e1b46c0414e9645cce6179e0fef5e388b Mon Sep 17 00:00:00 2001 From: John Sheehan Date: Thu, 11 Mar 2010 17:32:33 +0000 Subject: Staging: comedi: fix coding style in range.c add missing space before closing brace Signed-off-by: John Sheehan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/range.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c index 8313dfcb6732..188c47948033 100644 --- a/drivers/staging/comedi/range.c +++ b/drivers/staging/comedi/range.c @@ -29,7 +29,7 @@ const struct comedi_lrange range_bipolar5 = { 1, {BIP_RANGE(5)} }; const struct comedi_lrange range_bipolar2_5 = { 1, {BIP_RANGE(2.5)} }; const struct comedi_lrange range_unipolar10 = { 1, {UNI_RANGE(10)} }; const struct comedi_lrange range_unipolar5 = { 1, {UNI_RANGE(5)} }; -const struct comedi_lrange range_unknown = { 1, {{0, 1000000, UNIT_none}} }; +const struct comedi_lrange range_unknown = { 1, {{0, 1000000, UNIT_none} } }; /* COMEDI_RANGEINFO -- cgit v1.2.3 From 585f7682f975deb8c5a81e49257a315819913511 Mon Sep 17 00:00:00 2001 From: Andre Silva Date: Fri, 12 Mar 2010 15:28:15 +0000 Subject: Staging: arlan: fixed coding style issues in arlan-proc.c This is a patch to the arlan-proc.c file that fixes up multiple coding style errors and warnings found by the checkpatch.pl tool Signed-off-by: Andre Silva Signed-off-by: Greg Kroah-Hartman --- drivers/staging/arlan/arlan-proc.c | 623 ++++++++++++++++++------------------- 1 file changed, 306 insertions(+), 317 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/arlan/arlan-proc.c b/drivers/staging/arlan/arlan-proc.c index b22983e6c0cf..62cd1d0b59ef 100644 --- a/drivers/staging/arlan/arlan-proc.c +++ b/drivers/staging/arlan/arlan-proc.c @@ -9,48 +9,55 @@ -#define ARLAN_STR_SIZE 0x2ff0 -#define DEV_ARLAN_INFO 1 -#define DEV_ARLAN 1 -#define SARLG(type,var) {\ - pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x%x\n", #var, READSHMB(priva->card->var)); \ +#define ARLAN_STR_SIZE 0x2ff0 +#define DEV_ARLAN_INFO 1 +#define DEV_ARLAN 1 +#define SARLG(type, var) {\ + pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x%x\n", #var,\ + READSHMB(priva->card->var));\ } -#define SARLBN(type,var,nn) {\ - pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x",#var);\ - for (i=0; i < nn; i++ ) pos += sprintf(arlan_drive_info+pos, "%02x",READSHMB(priva->card->var[i]));\ - pos += sprintf(arlan_drive_info+pos, "\n"); \ +#define SARLBN(type, var, nn) {\ + pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x", #var);\ + for (i = 0; i < nn; i++)\ + pos += sprintf(arlan_drive_info+pos, "%02x",\ + READSHMB(priva->card->var[i]));\ + pos += sprintf(arlan_drive_info+pos, "\n");\ } -#define SARLBNpln(type,var,nn) {\ - for (i=0; i < nn; i++ ) pos += sprintf(arlan_drive_info+pos, "%02x",READSHMB(priva->card->var[i]));\ +#define SARLBNpln(type, var, nn) {\ + for (i = 0; i < nn; i++)\ + pos += sprintf(arlan_drive_info+pos, "%02x",\ + READSHMB(priva->card->var[i]));\ } -#define SARLSTR(var,nn) {\ +#define SARLSTR(var, nn) {\ char tmpStr[400];\ int tmpLn = nn;\ - if (nn > 399 ) tmpLn = 399; \ - memcpy(tmpStr,(char *) priva->conf->var,tmpLn);\ + if (nn > 399)\ + tmpLn = 399;\ + memcpy(tmpStr, (char *) priva->conf->var, tmpLn);\ tmpStr[tmpLn] = 0; \ - pos += sprintf(arlan_drive_info+pos, "%s\t=\t%s \n",#var,priva->conf->var);\ + pos += sprintf(arlan_drive_info+pos, "%s\t=\t%s\n",\ + #var, priva->conf->var);\ } -#define SARLUC(var) SARLG(u_char, var) -#define SARLUCN(var,nn) SARLBN(u_char,var, nn) +#define SARLUC(var) SARLG(u_char, var) +#define SARLUCN(var, nn) SARLBN(u_char, var, nn) #define SARLUS(var) SARLG(u_short, var) -#define SARLUSN(var,nn) SARLBN(u_short,var, nn) +#define SARLUSN(var, nn) SARLBN(u_short, var, nn) #define SARLUI(var) SARLG(u_int, var) #define SARLUSA(var) {\ u_short tmpVar;\ - memcpy(&tmpVar, (short *) priva->conf->var,2); \ - pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x%x\n",#var, tmpVar);\ + memcpy(&tmpVar, (short *) priva->conf->var, 2); \ + pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x%x\n", #var, tmpVar);\ } #define SARLUIA(var) {\ u_int tmpVar;\ - memcpy(&tmpVar, (int* )priva->conf->var,4); \ - pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x%x\n",#var, tmpVar);\ + memcpy(&tmpVar, (int *)priva->conf->var, 4); \ + pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x%x\n", #var, tmpVar);\ } @@ -63,51 +70,51 @@ static const char *arlan_diagnostic_info_string(struct net_device *dev) READSHM(diagnosticInfo, arlan->diagnosticInfo, u_char); - switch (diagnosticInfo) - { - case 0xFF: + switch (diagnosticInfo) { + + case 0xFF: return "Diagnostic info is OK"; - case 0xFE: - return "ERROR EPROM Checksum error "; - case 0xFD: - return "ERROR Local Ram Test Failed "; - case 0xFC: - return "ERROR SCC failure "; - case 0xFB: - return "ERROR BackBone failure "; - case 0xFA: - return "ERROR transceiver not found "; - case 0xF9: - return "ERROR no more address space "; - case 0xF8: - return "ERROR Checksum error "; - case 0xF7: - return "ERROR Missing SS Code"; - case 0xF6: - return "ERROR Invalid config format"; - case 0xF5: - return "ERROR Reserved errorcode F5"; - case 0xF4: - return "ERROR Invalid spreading code/channel number"; - case 0xF3: - return "ERROR Load Code Error"; - case 0xF2: - return "ERROR Reserver errorcode F2 "; - case 0xF1: - return "ERROR Invalid command receivec by LAN card "; - case 0xF0: - return "ERROR Invalid parameter found in command "; - case 0xEF: - return "ERROR On-chip timer failure "; - case 0xEE: - return "ERROR T410 timer failure "; - case 0xED: - return "ERROR Too Many TxEnable commands "; - case 0xEC: - return "ERROR EEPROM error on radio module "; - default: - return "ERROR unknown Diagnostic info reply code "; - } + case 0xFE: + return "ERROR EPROM Checksum error "; + case 0xFD: + return "ERROR Local Ram Test Failed "; + case 0xFC: + return "ERROR SCC failure "; + case 0xFB: + return "ERROR BackBone failure "; + case 0xFA: + return "ERROR transceiver not found "; + case 0xF9: + return "ERROR no more address space "; + case 0xF8: + return "ERROR Checksum error "; + case 0xF7: + return "ERROR Missing SS Code"; + case 0xF6: + return "ERROR Invalid config format"; + case 0xF5: + return "ERROR Reserved errorcode F5"; + case 0xF4: + return "ERROR Invalid spreading code/channel number"; + case 0xF3: + return "ERROR Load Code Error"; + case 0xF2: + return "ERROR Reserver errorcode F2 "; + case 0xF1: + return "ERROR Invalid command receivec by LAN card "; + case 0xF0: + return "ERROR Invalid parameter found in command "; + case 0xEF: + return "ERROR On-chip timer failure "; + case 0xEE: + return "ERROR T410 timer failure "; + case 0xED: + return "ERROR Too Many TxEnable commands "; + case 0xEC: + return "ERROR EEPROM error on radio module "; + default: + return "ERROR unknown Diagnostic info reply code "; + } } static const char *arlan_hardware_type_string(struct net_device *dev) @@ -117,70 +124,69 @@ static const char *arlan_hardware_type_string(struct net_device *dev) volatile struct arlan_shmem __iomem *arlan = priv->card; READSHM(hardwareType, arlan->hardwareType, u_char); - switch (hardwareType) - { - case 0x00: - return "type A450"; - case 0x01: - return "type A650 "; - case 0x04: - return "type TMA coproc"; - case 0x0D: - return "type A650E "; - case 0x18: - return "type TMA coproc Australian"; - case 0x19: - return "type A650A "; - case 0x26: - return "type TMA coproc European"; - case 0x2E: - return "type A655 "; - case 0x2F: - return "type A655A "; - case 0x30: - return "type A655E "; - case 0x0B: - return "type A670 "; - case 0x0C: - return "type A670E "; - case 0x2D: - return "type A670A "; - case 0x0F: - return "type A411T"; - case 0x16: - return "type A411TA"; - case 0x1B: - return "type A440T"; - case 0x1C: - return "type A412T"; - case 0x1E: - return "type A412TA"; - case 0x22: - return "type A411TE"; - case 0x24: - return "type A412TE"; - case 0x27: - return "type A671T "; - case 0x29: - return "type A671TA "; - case 0x2B: - return "type A671TE "; - case 0x31: - return "type A415T "; - case 0x33: - return "type A415TA "; - case 0x35: - return "type A415TE "; - case 0x37: - return "type A672"; - case 0x39: - return "type A672A "; - case 0x3B: - return "type A672T"; - case 0x6B: - return "type IC2200"; - default: - return "type A672T"; + switch (hardwareType) { + case 0x00: + return "type A450"; + case 0x01: + return "type A650 "; + case 0x04: + return "type TMA coproc"; + case 0x0D: + return "type A650E "; + case 0x18: + return "type TMA coproc Australian"; + case 0x19: + return "type A650A "; + case 0x26: + return "type TMA coproc European"; + case 0x2E: + return "type A655 "; + case 0x2F: + return "type A655A "; + case 0x30: + return "type A655E "; + case 0x0B: + return "type A670 "; + case 0x0C: + return "type A670E "; + case 0x2D: + return "type A670A "; + case 0x0F: + return "type A411T"; + case 0x16: + return "type A411TA"; + case 0x1B: + return "type A440T"; + case 0x1C: + return "type A412T"; + case 0x1E: + return "type A412TA"; + case 0x22: + return "type A411TE"; + case 0x24: + return "type A412TE"; + case 0x27: + return "type A671T "; + case 0x29: + return "type A671TA "; + case 0x2B: + return "type A671TE "; + case 0x31: + return "type A415T "; + case 0x33: + return "type A415TA "; + case 0x35: + return "type A415TE "; + case 0x37: + return "type A672"; + case 0x39: + return "type A672A "; + case 0x3B: + return "type A672T"; + case 0x6B: + return "type IC2200"; + default: + return "type A672T"; } } #ifdef ARLAN_DEBUGGING @@ -193,12 +199,12 @@ static void arlan_print_diagnostic_info(struct net_device *dev) struct arlan_private *priv = netdev_priv(dev); volatile struct arlan_shmem __iomem *arlan = priv->card; - // ARLAN_DEBUG_ENTRY("arlan_print_diagnostic_info"); + /* ARLAN_DEBUG_ENTRY("arlan_print_diagnostic_info"); */ if (READSHMB(arlan->configuredStatusFlag) == 0) - printk("Arlan: Card NOT configured\n"); + printk(KERN_WARNING "Arlan: Card NOT configured\n"); else - printk("Arlan: Card is configured\n"); + printk(KERN_INFO "Arlan: Card is configured\n"); READSHM(diagnosticInfo, arlan->diagnosticInfo, u_char); READSHM(diagnosticOffset, arlan->diagnosticOffset, u_short); @@ -206,14 +212,15 @@ static void arlan_print_diagnostic_info(struct net_device *dev) printk(KERN_INFO "%s\n", arlan_diagnostic_info_string(dev)); if (diagnosticInfo != 0xff) - printk("%s arlan: Diagnostic Offset %d \n", dev->name, diagnosticOffset); + printk(KERN_INFO "%s arlan: Diagnostic Offset %d\n",\ + dev->name, diagnosticOffset); - printk("arlan: LAN CODE ID = "); + printk(KERN_INFO "arlan: LAN CODE ID = "); for (i = 0; i < 6; i++) DEBUGSHM(1, "%03d:", arlan->lanCardNodeId[i], u_char); printk("\n"); - printk("arlan: Arlan BroadCast address = "); + printk(KERN_INFO "arlan: Arlan BroadCast address = "); for (i = 0; i < 6; i++) DEBUGSHM(1, "%03d:", arlan->broadcastAddress[i], u_char); printk("\n"); @@ -229,13 +236,13 @@ static void arlan_print_diagnostic_info(struct net_device *dev) DEBUGSHM(1, "arlan: SID =%d\n", arlan->SID, u_short); DEBUGSHM(1, "arlan: rxOffset=%d\n", arlan->rxOffset, u_short); - DEBUGSHM(1, "arlan: registration mode is %d\n", arlan->registrationMode, u_char); + DEBUGSHM(1, "arlan: registration mode is %d\n",\ + arlan->registrationMode, u_char); - printk("arlan: name= "); + printk(KERN_INFO "arlan: name= "); IFDEBUG(1) - - for (i = 0; i < 16; i++) - { + + for (i = 0; i < 16; i++) { char c; READSHM(c, arlan->name[i], char); if (c) @@ -243,18 +250,19 @@ static void arlan_print_diagnostic_info(struct net_device *dev) } printk("\n"); -// ARLAN_DEBUG_EXIT("arlan_print_diagnostic_info"); + /* ARLAN_DEBUG_EXIT("arlan_print_diagnostic_info"); */ } -/****************************** TEST MEMORY **************/ +/****************************** TEST MEMORY **************/ static int arlan_hw_test_memory(struct net_device *dev) { u_char *ptr; int i; - int memlen = sizeof(struct arlan_shmem) - 0xF; /* avoid control register */ + int memlen = sizeof(struct arlan_shmem) - 0xF; /* avoid + control register */ volatile char *arlan_mem = (char *) (dev->mem_start); struct arlan_private *priv = netdev_priv(dev); volatile struct arlan_shmem __iomem *arlan = priv->card; @@ -271,13 +279,11 @@ static int arlan_hw_test_memory(struct net_device *dev) WRITESHM(arlan_mem[i], ((u_char) pattern++), u_char); pattern = 0; - for (i = 0; i < memlen; i++) - { + for (i = 0; i < memlen; i++) { char res; READSHM(res, arlan_mem[i], char); - if (res != pattern++) - { - printk(KERN_ERR "Arlan driver memory test 1 failed \n"); + if (res != pattern++) { + printk(KERN_ERR "Arlan driver memory test 1 failed\n"); return -1; } } @@ -287,13 +293,11 @@ static int arlan_hw_test_memory(struct net_device *dev) WRITESHM(arlan_mem[i], ~(pattern++), char); pattern = 0; - for (i = 0; i < memlen; i++) - { + for (i = 0; i < memlen; i++) { char res; READSHM(res, arlan_mem[i], char); - if (res != ~(pattern++)) - { - printk(KERN_ERR "Arlan driver memory test 2 failed \n"); + if (res != ~(pattern++)) { + printk(KERN_ERR "Arlan driver memory test 2 failed\n"); return -1; } } @@ -311,9 +315,9 @@ static int arlan_hw_test_memory(struct net_device *dev) clearHardwareReset(dev); /* wait for reset flag to become zero, we'll wait for two seconds */ - if (arlan_command(dev, ARLAN_COMMAND_LONG_WAIT_NOW)) - { - printk(KERN_ERR "%s arlan: failed to come back from memory test\n", dev->name); + if (arlan_command(dev, ARLAN_COMMAND_LONG_WAIT_NOW)) { + printk(KERN_ERR "%s arlan: failed to come\ + back from memory test\n", dev->name); return -1; } return 0; @@ -325,29 +329,32 @@ static int arlan_setup_card_by_book(struct net_device *dev) struct arlan_private *priv = netdev_priv(dev); volatile struct arlan_shmem __iomem *arlan = priv->card; -// ARLAN_DEBUG_ENTRY("arlan_setup_card"); + /* ARLAN_DEBUG_ENTRY("arlan_setup_card"); */ READSHM(configuredStatusFlag, arlan->configuredStatusFlag, u_char); IFDEBUG(10) if (configuredStatusFlag != 0) - IFDEBUG(10) printk("arlan: CARD IS CONFIGURED\n"); + IFDEBUG(10) printk(KERN_INFO "arlan: CARD IS CONFIGURED\n"); else - IFDEBUG(10) printk("arlan: card is NOT configured\n"); + IFDEBUG(10) printk(KERN_WARNING\ + "arlan: card is NOT configured\n"); if (testMemory || (READSHMB(arlan->diagnosticInfo) != 0xff)) if (arlan_hw_test_memory(dev)) return -1; - DEBUGSHM(4, "arlan configuredStatus = %d \n", arlan->configuredStatusFlag, u_char); - DEBUGSHM(4, "arlan driver diagnostic: 0x%2x\n", arlan->diagnosticInfo, u_char); + DEBUGSHM(4, "arlan configuredStatus = %d\n",\ + arlan->configuredStatusFlag, u_char); + DEBUGSHM(4, "arlan driver diagnostic: 0x%2x\n",\ + arlan->diagnosticInfo, u_char); /* issue nop command - no interrupt */ arlan_command(dev, ARLAN_COMMAND_NOOP); if (arlan_command(dev, ARLAN_COMMAND_WAIT_NOW) != 0) return -1; - IFDEBUG(50) printk("1st Noop successfully executed !!\n"); + IFDEBUG(50) printk(KERN_INFO "1st Noop successfully executed !!\n"); /* try to turn on the arlan interrupts */ clearClearInterrupt(dev); @@ -361,18 +368,18 @@ static int arlan_setup_card_by_book(struct net_device *dev) return -1; - IFDEBUG(50) printk("2nd Noop successfully executed !!\n"); + IFDEBUG(50) printk(KERN_INFO "2nd Noop successfully executed !!\n"); READSHM(irqLevel, arlan->irqLevel, u_char) - - if (irqLevel != dev->irq) - { - IFDEBUG(1) printk(KERN_WARNING "arlan dip switches set irq to %d\n", irqLevel); - printk(KERN_WARNING "device driver irq set to %d - does not match\n", dev->irq); + + if (irqLevel != dev->irq) { + IFDEBUG(1) printk(KERN_WARNING "arlan dip switches\ + set irq to %d\n", irqLevel); + printk(KERN_WARNING "device driver irq set to %d-\ + does not match\n", dev->irq); dev->irq = irqLevel; - } - else - IFDEBUG(2) printk("irq level is OK\n"); + } else + IFDEBUG(2) printk(KERN_INFO "irq level is OK\n"); IFDEBUG(3) arlan_print_diagnostic_info(dev); @@ -380,8 +387,7 @@ static int arlan_setup_card_by_book(struct net_device *dev) arlan_command(dev, ARLAN_COMMAND_CONF); READSHM(configuredStatusFlag, arlan->configuredStatusFlag, u_char); - if (configuredStatusFlag == 0) - { + if (configuredStatusFlag == 0) { printk(KERN_WARNING "arlan configure failed\n"); return -1; } @@ -391,7 +397,7 @@ static int arlan_setup_card_by_book(struct net_device *dev) printk(KERN_NOTICE "%s: arlan driver version %s loaded\n", dev->name, arlan_version); -// ARLAN_DEBUG_EXIT("arlan_setup_card"); + /* ARLAN_DEBUG_EXIT("arlan_setup_card"); */ return 0; /* no errors */ } @@ -402,7 +408,7 @@ static int arlan_setup_card_by_book(struct net_device *dev) static char arlan_drive_info[ARLAN_STR_SIZE] = "A655\n\0"; -static int arlan_sysctl_info(ctl_table * ctl, int write, +static int arlan_sysctl_info(ctl_table *ctl, int write, void __user *buffer, size_t * lenp, loff_t *ppos) { int i; @@ -410,35 +416,30 @@ static int arlan_sysctl_info(ctl_table * ctl, int write, struct arlan_private *priva = NULL; struct net_device *dev; pos = 0; - if (write) - { - printk("wrirte: "); + if (write) { + printk(KERN_INFO "wrirte: "); for (i = 0; i < 100; i++) - printk("adi %x \n", arlan_drive_info[i]); + printk("adi %x\n", arlan_drive_info[i]); } - if (ctl->procname == NULL || arlan_drive_info == NULL) - { - printk(KERN_WARNING " procname is NULL in sysctl_table or arlan_drive_info is NULL \n at arlan module\n "); + if (ctl->procname == NULL || arlan_drive_info == NULL) { + printk(KERN_WARNING " procname is NULL in sysctl_table or arlan_drive_info is NULL\n at arlan module\n "); return -1; } devnum = ctl->procname[5] - '0'; - if (devnum < 0 || devnum > MAX_ARLANS - 1) - { + if (devnum < 0 || devnum > MAX_ARLANS - 1) { printk(KERN_WARNING "too strange devnum in procfs parse\n "); return -1; - } - else if (arlan_device[devnum] == NULL) - { + } else if (arlan_device[devnum] == NULL) { if (ctl->procname) - pos += sprintf(arlan_drive_info + pos, "\t%s\n\n", ctl->procname); - pos += sprintf(arlan_drive_info + pos, "No device found here \n"); + pos += sprintf(arlan_drive_info + pos,\ + "\t%s\n\n", ctl->procname); + pos += sprintf(arlan_drive_info + pos,\ + "No device found here\n"); goto final; - } - else + } else priva = netdev_priv(arlan_device[devnum]); - if (priva == NULL) - { + if (priva == NULL) { printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n "); return -1; } @@ -446,17 +447,19 @@ static int arlan_sysctl_info(ctl_table * ctl, int write, memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem)); - pos = sprintf(arlan_drive_info, "Arlan info \n"); + pos = sprintf(arlan_drive_info, "Arlan info\n"); /* Header Signature */ SARLSTR(textRegion, 48); SARLUC(resetFlag); - pos += sprintf(arlan_drive_info + pos, "diagnosticInfo\t=\t%s \n", arlan_diagnostic_info_string(dev)); + pos += sprintf(arlan_drive_info + pos,\ + "diagnosticInfo\t=\t%s\n", arlan_diagnostic_info_string(dev)); SARLUC(diagnosticInfo); SARLUS(diagnosticOffset); SARLUCN(_1, 12); SARLUCN(lanCardNodeId, 6); SARLUCN(broadcastAddress, 6); - pos += sprintf(arlan_drive_info + pos, "hardwareType =\t %s \n", arlan_hardware_type_string(dev)); + pos += sprintf(arlan_drive_info + pos,\ + "hardwareType =\t %s\n", arlan_hardware_type_string(dev)); SARLUC(hardwareType); SARLUC(majorHardwareVersion); SARLUC(minorHardwareVersion); @@ -602,17 +605,18 @@ static int arlan_sysctl_info(ctl_table * ctl, int write, SARLUCN(dumpPtr, 4); SARLUC(dumpVal); SARLUC(wireTest); - + /* next 4 seems too long for procfs, over single page ? SARLUCN( _17, 0x86); SARLUCN( txBuffer, 0x800); - SARLUCN( rxBuffer, 0x800); + SARLUCN( rxBuffer, 0x800); SARLUCN( _18, 0x0bff); */ pos += sprintf(arlan_drive_info + pos, "rxRing\t=\t0x"); for (i = 0; i < 0x50; i++) - pos += sprintf(arlan_drive_info + pos, "%02x", ((char *) priva->conf)[priva->conf->rxOffset + i]); + pos += sprintf(arlan_drive_info + pos, "%02x",\ + ((char *) priva->conf)[priva->conf->rxOffset + i]); pos += sprintf(arlan_drive_info + pos, "\n"); SARLUC(configStatus); @@ -624,14 +628,14 @@ static int arlan_sysctl_info(ctl_table * ctl, int write, pos += sprintf(arlan_drive_info + pos, " total %d chars\n", pos); if (ctl) if (ctl->procname) - pos += sprintf(arlan_drive_info + pos, " driver name : %s\n", ctl->procname); + pos += sprintf(arlan_drive_info + pos,\ + " driver name : %s\n", ctl->procname); final: *lenp = pos; if (!write) retv = proc_dostring(ctl, write, buffer, lenp, ppos); - else - { + else { *lenp = 0; return -1; } @@ -639,7 +643,7 @@ final: } -static int arlan_sysctl_info161719(ctl_table * ctl, int write, +static int arlan_sysctl_info161719(ctl_table *ctl, int write, void __user *buffer, size_t * lenp, loff_t *ppos) { int i; @@ -648,16 +652,16 @@ static int arlan_sysctl_info161719(ctl_table * ctl, int write, pos = 0; devnum = ctl->procname[5] - '0'; - if (arlan_device[devnum] == NULL) - { - pos += sprintf(arlan_drive_info + pos, "No device found here \n"); + if (arlan_device[devnum] == NULL) { + pos += sprintf(arlan_drive_info + pos,\ + "No device found here\n"); goto final; - } - else + } else priva = netdev_priv(arlan_device[devnum]); - if (priva == NULL) - { - printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n "); + + if (priva == NULL) { + printk(KERN_WARNING " Could not find the device\ + private in arlan procsys, bad\n "); return -1; } memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem)); @@ -673,7 +677,7 @@ final: return retv; } -static int arlan_sysctl_infotxRing(ctl_table * ctl, int write, +static int arlan_sysctl_infotxRing(ctl_table *ctl, int write, void __user *buffer, size_t * lenp, loff_t *ppos) { int i; @@ -682,15 +686,14 @@ static int arlan_sysctl_infotxRing(ctl_table * ctl, int write, pos = 0; devnum = ctl->procname[5] - '0'; - if (arlan_device[devnum] == NULL) - { - pos += sprintf(arlan_drive_info + pos, "No device found here \n"); - goto final; - } - else + if (arlan_device[devnum] == NULL) { + pos += sprintf(arlan_drive_info + pos,\ + "No device found here\n"); + goto final; + } else priva = netdev_priv(arlan_device[devnum]); - if (priva == NULL) - { + + if (priva == NULL) { printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n "); return -1; } @@ -702,7 +705,7 @@ final: return retv; } -static int arlan_sysctl_inforxRing(ctl_table * ctl, int write, +static int arlan_sysctl_inforxRing(ctl_table *ctl, int write, void __user *buffer, size_t * lenp, loff_t *ppos) { int i; @@ -711,14 +714,13 @@ static int arlan_sysctl_inforxRing(ctl_table * ctl, int write, pos = 0; devnum = ctl->procname[5] - '0'; - if (arlan_device[devnum] == NULL) - { - pos += sprintf(arlan_drive_info + pos, "No device found here \n"); - goto final; + if (arlan_device[devnum] == NULL) { + pos += sprintf(arlan_drive_info + pos,\ + "No device found here\n"); + goto final; } else priva = netdev_priv(arlan_device[devnum]); - if (priva == NULL) - { + if (priva == NULL) { printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n "); return -1; } @@ -730,7 +732,7 @@ final: return retv; } -static int arlan_sysctl_info18(ctl_table * ctl, int write, +static int arlan_sysctl_info18(ctl_table *ctl, int write, void __user *buffer, size_t * lenp, loff_t *ppos) { int i; @@ -739,18 +741,18 @@ static int arlan_sysctl_info18(ctl_table * ctl, int write, pos = 0; devnum = ctl->procname[5] - '0'; - if (arlan_device[devnum] == NULL) - { - pos += sprintf(arlan_drive_info + pos, "No device found here \n"); + if (arlan_device[devnum] == NULL) { + pos += sprintf(arlan_drive_info + pos,\ + "No device found here\n"); goto final; - } - else + } else priva = netdev_priv(arlan_device[devnum]); - if (priva == NULL) - { + + if (priva == NULL) { printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n "); return -1; } + memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem)); SARLBNpln(u_char, _18, 0x800); @@ -766,74 +768,73 @@ final: static char conf_reset_result[200]; -static int arlan_configure(ctl_table * ctl, int write, +static int arlan_configure(ctl_table *ctl, int write, void __user *buffer, size_t * lenp, loff_t *ppos) { int pos = 0; int devnum = ctl->procname[6] - '0'; struct arlan_private *priv; - if (devnum < 0 || devnum > MAX_ARLANS - 1) - { - printk(KERN_WARNING "too strange devnum in procfs parse\n "); + if (devnum < 0 || devnum > MAX_ARLANS - 1) { + printk(KERN_WARNING "too strange devnum in procfs parse\n"); return -1; - } - else if (arlan_device[devnum] != NULL) - { - priv = netdev_priv(arlan_device[devnum]); - - arlan_command(arlan_device[devnum], ARLAN_COMMAND_CLEAN_AND_CONF); - } - else + } else if (arlan_device[devnum] != NULL) { + priv = netdev_priv(arlan_device[devnum]); + arlan_command(arlan_device[devnum],\ + ARLAN_COMMAND_CLEAN_AND_CONF); + } else return -1; *lenp = pos; return proc_dostring(ctl, write, buffer, lenp, ppos); } -static int arlan_sysctl_reset(ctl_table * ctl, int write, +static int arlan_sysctl_reset(ctl_table *ctl, int write, void __user *buffer, size_t * lenp, loff_t *ppos) { int pos = 0; int devnum = ctl->procname[5] - '0'; struct arlan_private *priv; - if (devnum < 0 || devnum > MAX_ARLANS - 1) - { - printk(KERN_WARNING "too strange devnum in procfs parse\n "); + if (devnum < 0 || devnum > MAX_ARLANS - 1) { + printk(KERN_WARNING "too strange devnum in procfs parse\n"); return -1; - } - else if (arlan_device[devnum] != NULL) - { + + } else if (arlan_device[devnum] != NULL) { priv = netdev_priv(arlan_device[devnum]); - arlan_command(arlan_device[devnum], ARLAN_COMMAND_CLEAN_AND_RESET); + arlan_command(arlan_device[devnum], \ + ARLAN_COMMAND_CLEAN_AND_RESET); } else return -1; + *lenp = pos + 3; return proc_dostring(ctl, write, buffer, lenp, ppos); } /* Place files in /proc/sys/dev/arlan */ -#define CTBLN(card,nam) \ - { .procname = #nam,\ - .data = &(arlan_conf[card].nam),\ - .maxlen = sizeof(int), .mode = 0600, .proc_handler = proc_dointvec} +#define CTBLN(card, nam) \ + { .procname = #nam,\ + .data = &(arlan_conf[card].nam),\ + .maxlen = sizeof(int), .mode = 0600, .proc_handler = proc_dointvec} #ifdef ARLAN_DEBUGGING -#define ARLAN_PROC_DEBUG_ENTRIES \ - { .procname = "entry_exit_debug",\ - .data = &arlan_entry_and_exit_debug,\ - .maxlen = sizeof(int), .mode = 0600, .proc_handler = proc_dointvec},\ +#define ARLAN_PROC_DEBUG_ENTRIES do {\ + + { .procname = "entry_exit_debug",\ + .data = &arlan_entry_and_exit_debug,\ + .maxlen = sizeof(int), .mode = 0600, .proc_handler = proc_dointvec},\ { .procname = "debug", .data = &arlan_debug,\ - .maxlen = sizeof(int), .mode = 0600, .proc_handler = proc_dointvec}, -#else + .maxlen = sizeof(int), .mode = 0600, .proc_handler = proc_dointvec}, + + } while (0) +#else #define ARLAN_PROC_DEBUG_ENTRIES #endif #define ARLAN_SYSCTL_TABLE_TOTAL(cardNo)\ - CTBLN(cardNo,spreadingCode),\ + CTBLN(cardNo, spreadingCode),\ CTBLN(cardNo, channelNumber),\ CTBLN(cardNo, scramblingDisable),\ CTBLN(cardNo, txAttenuation),\ @@ -861,43 +862,40 @@ static int arlan_sysctl_reset(ctl_table * ctl, int write, CTBLN(cardNo, rxParameter),\ CTBLN(cardNo, txTimeoutMs),\ CTBLN(cardNo, waitCardTimeout),\ - CTBLN(cardNo, channelSet), \ + CTBLN(cardNo, channelSet),\ { .procname = "name",\ .data = arlan_conf[cardNo].siteName,\ - .maxlen = 16, .mode = 0600, .proc_handler = proc_dostring},\ - CTBLN(cardNo,waitTime),\ - CTBLN(cardNo,lParameter),\ - CTBLN(cardNo,_15),\ - CTBLN(cardNo,headerSize),\ - CTBLN(cardNo,tx_delay_ms),\ - CTBLN(cardNo,retries),\ - CTBLN(cardNo,ReTransmitPacketMaxSize),\ - CTBLN(cardNo,waitReTransmitPacketMaxSize),\ - CTBLN(cardNo,fastReTransCount),\ - CTBLN(cardNo,driverRetransmissions),\ - CTBLN(cardNo,txAckTimeoutMs),\ - CTBLN(cardNo,registrationInterrupts),\ - CTBLN(cardNo,hardwareType),\ - CTBLN(cardNo,radioType),\ - CTBLN(cardNo,writeEEPROM),\ - CTBLN(cardNo,writeRadioType),\ + .maxlen = 16, .mode = 0600, .proc_handler = proc_dostring },\ + CTBLN(cardNo, waitTime),\ + CTBLN(cardNo, lParameter),\ + CTBLN(cardNo, _15),\ + CTBLN(cardNo, headerSize),\ + CTBLN(cardNo, tx_delay_ms),\ + CTBLN(cardNo, retries),\ + CTBLN(cardNo, ReTransmitPacketMaxSize),\ + CTBLN(cardNo, waitReTransmitPacketMaxSize),\ + CTBLN(cardNo, fastReTransCount),\ + CTBLN(cardNo, driverRetransmissions),\ + CTBLN(cardNo, txAckTimeoutMs),\ + CTBLN(cardNo, registrationInterrupts),\ + CTBLN(cardNo, hardwareType),\ + CTBLN(cardNo, radioType),\ + CTBLN(cardNo, writeEEPROM),\ + CTBLN(cardNo, writeRadioType),\ ARLAN_PROC_DEBUG_ENTRIES\ - CTBLN(cardNo,in_speed),\ - CTBLN(cardNo,out_speed),\ - CTBLN(cardNo,in_speed10),\ - CTBLN(cardNo,out_speed10),\ - CTBLN(cardNo,in_speed_max),\ - CTBLN(cardNo,out_speed_max),\ - CTBLN(cardNo,measure_rate),\ - CTBLN(cardNo,pre_Command_Wait),\ - CTBLN(cardNo,rx_tweak1),\ - CTBLN(cardNo,rx_tweak2),\ - CTBLN(cardNo,tx_queue_len),\ - - - -static ctl_table arlan_conf_table0[] = -{ + CTBLN(cardNo, in_speed),\ + CTBLN(cardNo, out_speed),\ + CTBLN(cardNo, in_speed10),\ + CTBLN(cardNo, out_speed10),\ + CTBLN(cardNo, in_speed_max),\ + CTBLN(cardNo, out_speed_max),\ + CTBLN(cardNo, measure_rate),\ + CTBLN(cardNo, pre_Command_Wait),\ + CTBLN(cardNo, rx_tweak1),\ + CTBLN(cardNo, rx_tweak2),\ + CTBLN(cardNo, tx_queue_len),\ + +static ctl_table arlan_conf_table0[] = { ARLAN_SYSCTL_TABLE_TOTAL(0) #ifdef ARLAN_PROC_SHM_DUMP @@ -954,8 +952,7 @@ static ctl_table arlan_conf_table0[] = { } }; -static ctl_table arlan_conf_table1[] = -{ +static ctl_table arlan_conf_table1[] = { ARLAN_SYSCTL_TABLE_TOTAL(1) @@ -1013,8 +1010,7 @@ static ctl_table arlan_conf_table1[] = { } }; -static ctl_table arlan_conf_table2[] = -{ +static ctl_table arlan_conf_table2[] = { ARLAN_SYSCTL_TABLE_TOTAL(2) @@ -1072,8 +1068,7 @@ static ctl_table arlan_conf_table2[] = { } }; -static ctl_table arlan_conf_table3[] = -{ +static ctl_table arlan_conf_table3[] = { ARLAN_SYSCTL_TABLE_TOTAL(3) @@ -1133,8 +1128,7 @@ static ctl_table arlan_conf_table3[] = -static ctl_table arlan_table[] = -{ +static ctl_table arlan_table[] = { { .procname = "arlan0", .maxlen = 0, @@ -1164,17 +1158,15 @@ static ctl_table arlan_table[] = #else -static ctl_table arlan_table[] = -{ +static ctl_table arlan_table[] = { { } }; #endif -// static int mmtu = 1234; +/* static int mmtu = 1234; */ -static ctl_table arlan_root_table[] = -{ +static ctl_table arlan_root_table[] = { { .procname = "arlan", .maxlen = 0, @@ -1189,8 +1181,6 @@ static struct ctl_table_header *arlan_device_sysctl_header; int __init init_arlan_proc(void) { - - int i = 0; if (arlan_device_sysctl_header) return 0; arlan_device_sysctl_header = register_sysctl_table(arlan_root_table); @@ -1198,7 +1188,6 @@ int __init init_arlan_proc(void) return -1; return 0; - } void __exit cleanup_arlan_proc(void) -- cgit v1.2.3 From b9e2af544d4fe1a74006a68c744fbdaea13f1665 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sat, 13 Mar 2010 12:17:59 +0100 Subject: Staging: dream: fix gpio_input compilation gpio_* drivers still need drivers in staging. Yes, that will need to be fixed, but at least fix compilation for now. Signed-off-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dream/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/dream/Makefile b/drivers/staging/dream/Makefile index 2b7915197078..43d1eec8e257 100644 --- a/drivers/staging/dream/Makefile +++ b/drivers/staging/dream/Makefile @@ -1,3 +1,4 @@ +EXTRA_CFLAGS=-Idrivers/staging/dream/include obj-$(CONFIG_MSM_ADSP) += qdsp5/ smd/ obj-$(CONFIG_MSM_CAMERA) += camera/ obj-$(CONFIG_INPUT_GPIO) += gpio_axis.o gpio_event.o gpio_input.o gpio_matrix.o gpio_output.o -- cgit v1.2.3 From 251211c3fa0d218e90f1fb4ce3b475213df467d2 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sat, 13 Mar 2010 09:22:39 +0100 Subject: Staging: dream: Kconfig fix for non-HTC hardware > All of the Kconfig menu items under "config DREAM" should be listed > indented under the 'DREAM' symbol, but they are not. (using xconfig) > In menuconfig, the DREAM symbol isn't listed (since it depends on BROKEN), > but the other (subordinate) symbols are still listed. Ok, this should fix it ... or at least make it better an non-issue for people with non-HTC hardware. Signed-off-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dream/Kconfig | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dream/Kconfig b/drivers/staging/dream/Kconfig index 4afa081c870c..707cc71a8a6a 100644 --- a/drivers/staging/dream/Kconfig +++ b/drivers/staging/dream/Kconfig @@ -1,16 +1,14 @@ config DREAM - tristate "HTC Dream support" - depends on BROKEN + tristate "HTC Dream support" + depends on MACH_TROUT +if DREAM source "drivers/staging/dream/smd/Kconfig" source "drivers/staging/dream/camera/Kconfig" - config INPUT_GPIO tristate "GPIO driver support" help Say Y here if you want to support gpio based keys, wheels etc... - - - +endif -- cgit v1.2.3 From 2d1cbb77db089df3d70c2f921ea4b3cf8b9695e9 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sat, 13 Mar 2010 09:53:25 +0100 Subject: Staging: dream: remove last bits of earlysuspend support Remove last bits of earlysuspend support. Signed-off-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dream/TODO | 1 - drivers/staging/dream/qdsp5/audio_out.c | 9 --------- drivers/staging/dream/smd/smd_rpcrouter_servers.c | 4 ---- 3 files changed, 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dream/TODO b/drivers/staging/dream/TODO index c07c8803f07c..dcd3ba808655 100644 --- a/drivers/staging/dream/TODO +++ b/drivers/staging/dream/TODO @@ -1,4 +1,3 @@ -* remove support for wakelocks since those are not in mainline * camera driver uses old V4L API diff --git a/drivers/staging/dream/qdsp5/audio_out.c b/drivers/staging/dream/qdsp5/audio_out.c index fe7809dd4401..76d7fa5667d5 100644 --- a/drivers/staging/dream/qdsp5/audio_out.c +++ b/drivers/staging/dream/qdsp5/audio_out.c @@ -182,9 +182,6 @@ struct audio { int stopped; /* set when stopped, cleared on flush */ unsigned volume; - struct wake_lock wakelock; - struct wake_lock idlelock; - int adrc_enable; struct adrc_filter adrc; @@ -198,14 +195,10 @@ struct audio { static void audio_prevent_sleep(struct audio *audio) { printk(KERN_INFO "++++++++++++++++++++++++++++++\n"); - wake_lock(&audio->wakelock); - wake_lock(&audio->idlelock); } static void audio_allow_sleep(struct audio *audio) { - wake_unlock(&audio->wakelock); - wake_unlock(&audio->idlelock); printk(KERN_INFO "------------------------------\n"); } @@ -840,8 +833,6 @@ static int __init audio_init(void) mutex_init(&the_audio.write_lock); spin_lock_init(&the_audio.dsp_lock); init_waitqueue_head(&the_audio.wait); - wake_lock_init(&the_audio.wakelock, WAKE_LOCK_SUSPEND, "audio_pcm"); - wake_lock_init(&the_audio.idlelock, WAKE_LOCK_IDLE, "audio_pcm_idle"); return (misc_register(&audio_misc) || misc_register(&audpp_misc)); } diff --git a/drivers/staging/dream/smd/smd_rpcrouter_servers.c b/drivers/staging/dream/smd/smd_rpcrouter_servers.c index 1b152abb2783..bec3ee9371b3 100644 --- a/drivers/staging/dream/smd/smd_rpcrouter_servers.c +++ b/drivers/staging/dream/smd/smd_rpcrouter_servers.c @@ -42,7 +42,6 @@ static struct msm_rpc_endpoint *endpoint; static LIST_HEAD(rpc_server_list); static DEFINE_MUTEX(rpc_server_list_lock); static int rpc_servers_active; -static struct wake_lock rpc_servers_wake_lock; static void rpc_server_register(struct msm_rpc_server *server) { @@ -136,10 +135,8 @@ static int rpc_servers_thread(void *data) int rc; for (;;) { - wake_unlock(&rpc_servers_wake_lock); rc = wait_event_interruptible(endpoint->wait_q, !list_empty(&endpoint->read_q)); - wake_lock(&rpc_servers_wake_lock); rc = msm_rpc_read(endpoint, &buffer, -1, -1); if (rc < 0) { printk(KERN_ERR "%s: could not read: %d\n", @@ -219,7 +216,6 @@ static struct platform_driver rpcservers_driver = { static int __init rpc_servers_init(void) { - wake_lock_init(&rpc_servers_wake_lock, WAKE_LOCK_SUSPEND, "rpc_server"); return platform_driver_register(&rpcservers_driver); } -- cgit v1.2.3 From d4a505e81bffe8c41b3b701f8fa7b47c902fb149 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sat, 13 Mar 2010 12:20:05 +0100 Subject: Staging: windbond: camelCase should be fixed (BTW, winbond/README alias winbond/TODO doesn't mention it, but another (trivial) step is going to be to change variable names and function names from CamelCase to lower_case spelling.) Signed-off-by: Pavel Machek Acked-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/README | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/winbond/README b/drivers/staging/winbond/README index cb944e4bf174..27710241fc14 100644 --- a/drivers/staging/winbond/README +++ b/drivers/staging/winbond/README @@ -2,6 +2,7 @@ TODO: - sparse cleanups - checkpatch cleanups - kerneldoc cleanups + - fix severeCamelCaseInfestation - remove typedefs - remove unused ioctls - use cfg80211 for regulatory stuff -- cgit v1.2.3 From f4af2361dfb750c746047e21d186df8705d1fd5d Mon Sep 17 00:00:00 2001 From: Stefan Schick Date: Sat, 13 Mar 2010 13:47:09 +0100 Subject: Staging: comedi: dt3000: fixed some coding style issues Fixed some coding style issues Signed-off-by: Stefan Schick Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt3000.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index bbbef790c8f6..ca687890fc12 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -314,9 +314,8 @@ static int dt3k_send_cmd(struct comedi_device *dev, unsigned int cmd) break; udelay(1); } - if ((status & DT3000_COMPLETION_MASK) == DT3000_NOERROR) { + if ((status & DT3000_COMPLETION_MASK) == DT3000_NOERROR) return 0; - } printk("dt3k_send_cmd() timeout/error status=0x%04x\n", status); @@ -359,9 +358,8 @@ static irqreturn_t dt3k_interrupt(int irq, void *d) struct comedi_subdevice *s; unsigned int status; - if (!dev->attached) { + if (!dev->attached) return IRQ_NONE; - } s = dev->subdevices + 0; status = readw(devpriv->io_addr + DPR_Intr_Flag); @@ -374,9 +372,8 @@ static irqreturn_t dt3k_interrupt(int irq, void *d) s->async->events |= COMEDI_CB_BLOCK; } - if (status & (DT3000_ADSWERR | DT3000_ADHWERR)) { + if (status & (DT3000_ADSWERR | DT3000_ADHWERR)) s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - } debug_n_ints++; if (debug_n_ints >= 10) { @@ -399,9 +396,8 @@ static void debug_intr_flags(unsigned int flags) int i; printk("dt3k: intr_flags:"); for (i = 0; i < 8; i++) { - if (flags & (1 << i)) { + if (flags & (1 << i)) printk(" %s", intr_flags[i]); - } } printk("\n"); } @@ -690,9 +686,8 @@ static int dt3k_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s, /* XXX docs don't explain how to select aref */ aref = CR_AREF(insn->chanspec); - for (i = 0; i < insn->n; i++) { + for (i = 0; i < insn->n; i++) data[i] = dt3k_readsingle(dev, SUBS_AI, chan, gain); - } return i; } @@ -720,9 +715,8 @@ static int dt3k_ao_insn_read(struct comedi_device *dev, unsigned int chan; chan = CR_CHAN(insn->chanspec); - for (i = 0; i < insn->n; i++) { + for (i = 0; i < insn->n; i++) data[i] = devpriv->ao_readback[chan]; - } return i; } @@ -911,9 +905,8 @@ static int dt3000_detach(struct comedi_device *dev) if (devpriv) { if (devpriv->pci_dev) { - if (devpriv->phys_addr) { + if (devpriv->phys_addr) comedi_pci_disable(devpriv->pci_dev); - } pci_dev_put(devpriv->pci_dev); } if (devpriv->io_addr) -- cgit v1.2.3 From a41aec1be2b3b21c08b84fb1e70e23aab29c5820 Mon Sep 17 00:00:00 2001 From: Jason Wong Date: Sat, 27 Mar 2010 09:48:38 +0800 Subject: Staging: comedi: adl_pci9118: fixed multiple brace coding style issues Fixed multiple coding style issues Signed-off-by: Jason Wong Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9118.c | 42 ++++++++++++++-------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 2205113ee435..c7cba9579d07 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -496,11 +496,11 @@ static int pci9118_insn_write_ao(struct comedi_device *dev, int n, chanreg, ch; ch = CR_CHAN(insn->chanspec); - if (ch) { + if (ch) chanreg = PCI9118_DA2; - } else { + else chanreg = PCI9118_DA1; - } + for (n = 0; n < insn->n; n++) { outl(data[n], dev->iobase + chanreg); @@ -663,11 +663,11 @@ static void pci9118_ai_munge(struct comedi_device *dev, for (i = 0; i < num_samples; i++) { if (devpriv->usedma) array[i] = be16_to_cpu(array[i]); - if (devpriv->ai16bits) { + if (devpriv->ai16bits) array[i] ^= 0x8000; - } else { + else array[i] = (array[i] >> 4) & 0x0fff; - } + } } @@ -930,20 +930,20 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, err++; tmp = cmd->scan_begin_src; - if (devpriv->master) { + if (devpriv->master) cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW; - } else { + else cmd->scan_begin_src &= TRIG_FOLLOW; - } + if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) err++; tmp = cmd->convert_src; - if (devpriv->master) { + if (devpriv->master) cmd->convert_src &= TRIG_TIMER | TRIG_EXT | TRIG_NOW; - } else { + else cmd->convert_src &= TRIG_TIMER | TRIG_EXT; - } + if (!cmd->convert_src || tmp != cmd->convert_src) err++; @@ -1908,9 +1908,9 @@ static int setup_channel_list(struct comedi_device *dev, } #ifdef PCI9118_EXTDEBUG DPRINTK("CHL: "); - for (i = 0; i <= (useeos * n_chan); i++) { + for (i = 0; i <= (useeos * n_chan); i++) DPRINTK("%04x ", devpriv->chanlist[i]); - } + DPRINTK("\n "); #endif #endif @@ -2222,9 +2222,9 @@ static int pci9118_attach(struct comedi_device *dev, return -EIO; } - if (master) { + if (master) pci_set_master(pcidev); - } + pci_bus = pcidev->bus->number; pci_slot = PCI_SLOT(pcidev->devfn); @@ -2335,11 +2335,11 @@ static int pci9118_attach(struct comedi_device *dev, dev->read_subdev = s; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; - if (devpriv->usemux) { + if (devpriv->usemux) s->n_chan = devpriv->usemux; - } else { + else s->n_chan = this_board->n_aichan; - } + s->maxdata = this_board->ai_maxdata; s->len_chanlist = this_board->n_aichanlist; s->range_table = this_board->rangelist_ai; @@ -2411,9 +2411,9 @@ static int pci9118_detach(struct comedi_device *dev) if (dev->irq) free_irq(dev->irq, dev); if (devpriv->pcidev) { - if (dev->iobase) { + if (dev->iobase) comedi_pci_disable(devpriv->pcidev); - } + pci_dev_put(devpriv->pcidev); } if (devpriv->dmabuf_virt[0]) -- cgit v1.2.3 From 402a01ae2370e33aa67c483d136ca475756260f5 Mon Sep 17 00:00:00 2001 From: Jason Wong Date: Sat, 27 Mar 2010 09:48:40 +0800 Subject: Staging: comedi: adv_pci_dio: fixed multiple brace coding style issues Fixed multiple coding style issues. Signed-off-by: Jason Wong Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci_dio.c | 34 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 61d35fe64350..dbfeef8c5bc8 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -367,9 +367,9 @@ static int pci_dio_insn_bits_di_b(struct comedi_device *dev, int i; data[1] = 0; - for (i = 0; i < d->regs; i++) { + for (i = 0; i < d->regs; i++) data[1] |= inb(dev->iobase + d->addr + i) << (8 * i); - } + return 2; } @@ -882,9 +882,9 @@ static int CheckAndAllocCard(struct comedi_device *dev, struct pci_dio_private *pr, *prev; for (pr = pci_priv, prev = NULL; pr != NULL; prev = pr, pr = pr->next) { - if (pr->pcidev == pcidev) { + if (pr->pcidev == pcidev) return 0; /* this card is used, look for another */ - } + } if (prev) { @@ -1040,22 +1040,22 @@ static int pci_dio_detach(struct comedi_device *dev) int subdev; if (dev->private) { - if (devpriv->valid) { + if (devpriv->valid) pci_dio_reset(dev); - } + /* This shows the silliness of using this kind of * scheme for numbering subdevices. Don't do it. --ds */ subdev = 0; for (i = 0; i < MAX_DI_SUBDEVS; i++) { - if (this_board->sdi[i].chans) { + if (this_board->sdi[i].chans) subdev++; - } + } for (i = 0; i < MAX_DO_SUBDEVS; i++) { - if (this_board->sdo[i].chans) { + if (this_board->sdo[i].chans) subdev++; - } + } for (i = 0; i < MAX_DIO_SUBDEVG; i++) { for (j = 0; j < this_board->sdio[i].regs; j++) { @@ -1071,20 +1071,20 @@ static int pci_dio_detach(struct comedi_device *dev) } if (devpriv->pcidev) { - if (dev->iobase) { + if (dev->iobase) comedi_pci_disable(devpriv->pcidev); - } + pci_dev_put(devpriv->pcidev); } - if (devpriv->prev) { + if (devpriv->prev) devpriv->prev->next = devpriv->next; - } else { + else pci_priv = devpriv->next; - } - if (devpriv->next) { + + if (devpriv->next) devpriv->next->prev = devpriv->prev; - } + } return 0; -- cgit v1.2.3 From ec14016e751106499ef237efc1000a424f53e372 Mon Sep 17 00:00:00 2001 From: Jason Wong Date: Sat, 27 Mar 2010 09:48:39 +0800 Subject: Staging: comedi: adv_pci1710: fixed multiple brace coding style issues Fixed multiple coding style issues. Signed-off-by: Jason Wong Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 394d2ea19c2e..f5bb286bfbd7 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -657,9 +657,9 @@ static void interrupt_pci1710_every_sample(void *d) #endif ++s->async->cur_chan; - if (s->async->cur_chan >= devpriv->ai_n_chan) { + if (s->async->cur_chan >= devpriv->ai_n_chan) s->async->cur_chan = 0; - } + if (s->async->cur_chan == 0) { /* one scan done */ devpriv->ai_act_scan++; @@ -863,12 +863,12 @@ static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev, devpriv->ai_eos = 0; } - if ((devpriv->ai_scans == 0) || (devpriv->ai_scans == -1)) { + if ((devpriv->ai_scans == 0) || (devpriv->ai_scans == -1)) devpriv->neverending_ai = 1; - } /* well, user want neverending */ - else { + /* well, user want neverending */ + else devpriv->neverending_ai = 0; - } + switch (mode) { case 1: case 2: @@ -1109,11 +1109,11 @@ static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_timer1 = 0; devpriv->ai_timer2 = 0; - if (cmd->stop_src == TRIG_COUNT) { + if (cmd->stop_src == TRIG_COUNT) devpriv->ai_scans = cmd->stop_arg; - } else { + else devpriv->ai_scans = 0; - } + if (cmd->scan_begin_src == TRIG_FOLLOW) { /* mode 1, 2, 3 */ if (cmd->convert_src == TRIG_TIMER) { /* mode 1 and 2 */ @@ -1593,9 +1593,9 @@ static int pci1710_detach(struct comedi_device *dev) if (dev->irq) free_irq(dev->irq, dev); if (devpriv->pcidev) { - if (dev->iobase) { + if (dev->iobase) comedi_pci_disable(devpriv->pcidev); - } + pci_dev_put(devpriv->pcidev); } } -- cgit v1.2.3 From 7b8f2d1a2ece4180ac5fe418bf915efe728583a8 Mon Sep 17 00:00:00 2001 From: Jason Wong Date: Sat, 27 Mar 2010 09:48:41 +0800 Subject: Staging: comedi: cb_das16_cs: fixed multiple brace coding style issues Fixed multiple coding style issues Signed-off-by: Jason Wong Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 5632991760af..68bd5caa5e40 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -175,16 +175,16 @@ static int das16cs_attach(struct comedi_device *dev, printk("I/O base=0x%04lx ", dev->iobase); printk("fingerprint:\n"); - for (i = 0; i < 48; i += 2) { + for (i = 0; i < 48; i += 2) printk("%04x ", inw(dev->iobase + i)); - } + printk("\n"); ret = request_irq(link->irq.AssignedIRQ, das16cs_interrupt, IRQF_SHARED, "cb_das16_cs", dev); - if (ret < 0) { + if (ret < 0) return ret; - } + dev->irq = link->irq.AssignedIRQ; printk("irq=%u ", dev->irq); @@ -262,9 +262,9 @@ static int das16cs_detach(struct comedi_device *dev) { printk("comedi%d: das16cs: remove\n", dev->minor); - if (dev->irq) { + if (dev->irq) free_irq(dev->irq, dev); - } + return 0; } -- cgit v1.2.3 From 90cae7944011b7a09b2d248e85ee11e987cc25f8 Mon Sep 17 00:00:00 2001 From: Jason Wong Date: Sat, 27 Mar 2010 09:48:42 +0800 Subject: Staging: comedi: cb_pcidas64: fixed multiple brace coding style issues Fixed multiple coding style issues. Signed-off-by: Jason Wong Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 40 ++++++++++++++-------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 82295e0f07f9..1d43d0d6f07d 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1621,9 +1621,9 @@ int alloc_and_init_dma_members(struct comedi_device *dev) priv(dev)->ai_buffer[i] = pci_alloc_consistent(priv(dev)->hw_dev, DMA_BUFFER_SIZE, &priv(dev)->ai_buffer_bus_addr[i]); - if (priv(dev)->ai_buffer[i] == NULL) { + if (priv(dev)->ai_buffer[i] == NULL) return -ENOMEM; - } + } for (i = 0; i < AO_DMA_RING_COUNT; i++) { if (ao_cmd_is_supported(board(dev))) { @@ -1632,9 +1632,9 @@ int alloc_and_init_dma_members(struct comedi_device *dev) DMA_BUFFER_SIZE, &priv(dev)-> ao_buffer_bus_addr[i]); - if (priv(dev)->ao_buffer[i] == NULL) { + if (priv(dev)->ao_buffer[i] == NULL) return -ENOMEM; - } + } } /* allocate dma descriptors */ @@ -1643,9 +1643,9 @@ int alloc_and_init_dma_members(struct comedi_device *dev) sizeof(struct plx_dma_desc) * ai_dma_ring_count(board(dev)), &priv(dev)->ai_dma_desc_bus_addr); - if (priv(dev)->ai_dma_desc == NULL) { + if (priv(dev)->ai_dma_desc == NULL) return -ENOMEM; - } + DEBUG_PRINT("ai dma descriptors start at bus addr 0x%x\n", priv(dev)->ai_dma_desc_bus_addr); if (ao_cmd_is_supported(board(dev))) { @@ -1654,9 +1654,9 @@ int alloc_and_init_dma_members(struct comedi_device *dev) sizeof(struct plx_dma_desc) * AO_DMA_RING_COUNT, &priv(dev)->ao_dma_desc_bus_addr); - if (priv(dev)->ao_dma_desc == NULL) { + if (priv(dev)->ao_dma_desc == NULL) return -ENOMEM; - } + DEBUG_PRINT("ao dma descriptors start at bus addr 0x%x\n", priv(dev)->ao_dma_desc_bus_addr); } @@ -1848,9 +1848,9 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) printk(" irq %u\n", dev->irq); retval = setup_subdevices(dev); - if (retval < 0) { + if (retval < 0) return retval; - } + return 0; } @@ -1919,9 +1919,9 @@ static int detach(struct comedi_device *dev) priv(dev)->ao_dma_desc, priv(dev)-> ao_dma_desc_bus_addr); - if (priv(dev)->main_phys_iobase) { + if (priv(dev)->main_phys_iobase) comedi_pci_disable(priv(dev)->hw_dev); - } + pci_dev_put(priv(dev)->hw_dev); } } @@ -2902,9 +2902,9 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) if (cmd->stop_src == TRIG_COUNT) { if (priv(dev)->ai_count == 0) break; - if (num_samples > priv(dev)->ai_count) { + if (num_samples > priv(dev)->ai_count) num_samples = priv(dev)->ai_count; - } + priv(dev)->ai_count -= num_samples; } @@ -2943,9 +2943,9 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev) readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; if (cmd->stop_src == TRIG_COUNT) { - if (max_transfer > priv(dev)->ai_count) { + if (max_transfer > priv(dev)->ai_count) max_transfer = priv(dev)->ai_count; - } + } for (i = 0; read_code != write_code && i < max_transfer;) { fifo_data = readl(priv(dev)->dio_counter_iobase + ADC_FIFO_REG); @@ -2964,9 +2964,9 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev) /* empty fifo */ static void pio_drain_ai_fifo(struct comedi_device *dev) { - if (board(dev)->layout == LAYOUT_4020) { + if (board(dev)->layout == LAYOUT_4020) pio_drain_ai_fifo_32(dev); - } else + else pio_drain_ai_fifo_16(dev); } @@ -3038,9 +3038,9 @@ void handle_ai_interrupt(struct comedi_device *dev, unsigned short status, priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG); DEBUG_PRINT("dma1 status 0x%x\n", dma1_status); - if (dma1_status & PLX_DMA_EN_BIT) { + if (dma1_status & PLX_DMA_EN_BIT) drain_dma_buffers(dev, 1); - } + DEBUG_PRINT(" cleared dma ch1 interrupt\n"); } spin_unlock_irqrestore(&dev->spinlock, flags); -- cgit v1.2.3 From 003b3e9408425b6bd0b807108ee4cff5498125d3 Mon Sep 17 00:00:00 2001 From: Jason Wong Date: Sat, 27 Mar 2010 09:48:43 +0800 Subject: Staging: comedi: cb_pcidas64: fixed a coding style missed in the previous patch Fixed a coding style issue. Signed-off-by: Jason Wong Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 1d43d0d6f07d..f17cb09acb28 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1921,7 +1921,7 @@ static int detach(struct comedi_device *dev) ao_dma_desc_bus_addr); if (priv(dev)->main_phys_iobase) comedi_pci_disable(priv(dev)->hw_dev); - + pci_dev_put(priv(dev)->hw_dev); } } -- cgit v1.2.3 From a5729c005c35ce5b7b8cdbe407c0d0dedf4991dd Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Tue, 16 Mar 2010 17:24:47 +0200 Subject: Staging: hv: fix spaces coding style issue in vstorage.h This is a patch to the vstorage.h file that fixed up a TAB and spaces Errors found by the checkpatch.pl tools, like spaces required around that ':' (ctx:VxV) Signed-off-by: Ruslan Pisarev Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vstorage.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/vstorage.h b/drivers/staging/hv/vstorage.h index 6d160a53914e..4ea597d7a7d7 100644 --- a/drivers/staging/hv/vstorage.h +++ b/drivers/staging/hv/vstorage.h @@ -28,7 +28,7 @@ #define REVISION_STRING(REVISION_) #REVISION_ #define FILL_VMSTOR_REVISION(RESULT_LVALUE_) \ { \ - char *revisionString = REVISION_STRING($Revision: 6 $) + 11; \ + char *revisionString = REVISION_STRING($Revision : 6 $) + 11; \ RESULT_LVALUE_ = 0; \ while (*revisionString >= '0' && *revisionString <= '9') { \ RESULT_LVALUE_ *= 10; \ -- cgit v1.2.3 From c6fcf0baa6367fecd3e025253700b64ccff8c1eb Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Tue, 27 Apr 2010 16:23:47 -0400 Subject: Staging: hv: don't use dynamic sized array NetVscOnChannelCallback() used a dynamic sized array that also made the frame size over 2048. Replace it with a buffer allocated from kzalloc. Signed-off-by: Bill Pemberton Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/NetVsc.c | 25 ++++++++++++++++--------- drivers/staging/hv/NetVsc.h | 1 + 2 files changed, 17 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/NetVsc.c b/drivers/staging/hv/NetVsc.c index f84942df3bbf..a48e6376ce21 100644 --- a/drivers/staging/hv/NetVsc.c +++ b/drivers/staging/hv/NetVsc.c @@ -1288,28 +1288,33 @@ static void NetVscOnReceiveCompletion(void *Context) void NetVscOnChannelCallback(void *Context) { - const int netPacketSize = 2048; int ret; struct hv_device *device = Context; struct netvsc_device *netDevice; u32 bytesRecvd; u64 requestId; - unsigned char packet[netPacketSize]; + unsigned char *packet; struct vmpacket_descriptor *desc; - unsigned char *buffer = packet; - int bufferlen = netPacketSize; + unsigned char *buffer; + int bufferlen = NETVSC_PACKET_SIZE; DPRINT_ENTER(NETVSC); ASSERT(device); + packet = kzalloc(NETVSC_PACKET_SIZE * sizeof(unsigned char), + GFP_KERNEL); + if (!packet) + return; + buffer = packet; + netDevice = GetInboundNetDevice(device); if (!netDevice) { DPRINT_ERR(NETVSC, "net device (%p) shutting down..." "ignoring inbound packets", netDevice); DPRINT_EXIT(NETVSC); - return; + goto out; } do { @@ -1341,17 +1346,17 @@ void NetVscOnChannelCallback(void *Context) } /* reset */ - if (bufferlen > netPacketSize) { + if (bufferlen > NETVSC_PACKET_SIZE) { kfree(buffer); buffer = packet; - bufferlen = netPacketSize; + bufferlen = NETVSC_PACKET_SIZE; } } else { /* reset */ - if (bufferlen > netPacketSize) { + if (bufferlen > NETVSC_PACKET_SIZE) { kfree(buffer); buffer = packet; - bufferlen = netPacketSize; + bufferlen = NETVSC_PACKET_SIZE; } break; @@ -1375,5 +1380,7 @@ void NetVscOnChannelCallback(void *Context) PutNetDevice(device); DPRINT_EXIT(NETVSC); +out: + kfree(buffer); return; } diff --git a/drivers/staging/hv/NetVsc.h b/drivers/staging/hv/NetVsc.h index 6e0e03494126..a6264db8388a 100644 --- a/drivers/staging/hv/NetVsc.h +++ b/drivers/staging/hv/NetVsc.h @@ -289,6 +289,7 @@ struct nvsp_message { /* Preallocated receive packets */ #define NETVSC_RECEIVE_PACKETLIST_COUNT 256 +#define NETVSC_PACKET_SIZE 2048 /* Per netvsc channel-specific */ struct netvsc_device { -- cgit v1.2.3 From 81b571b77134aed29b9725f161dec6a37b48db68 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Tue, 27 Apr 2010 16:23:48 -0400 Subject: Staging: hv: declare NetVscOnChannelCallback() static NetVscOnChannelCallback() was prototyped as static, but the actual declartion of the function was not static. Signed-off-by: Bill Pemberton Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/NetVsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/NetVsc.c b/drivers/staging/hv/NetVsc.c index a48e6376ce21..27516d40b6ed 100644 --- a/drivers/staging/hv/NetVsc.c +++ b/drivers/staging/hv/NetVsc.c @@ -1286,7 +1286,7 @@ static void NetVscOnReceiveCompletion(void *Context) DPRINT_EXIT(NETVSC); } -void NetVscOnChannelCallback(void *Context) +static void NetVscOnChannelCallback(void *Context) { int ret; struct hv_device *device = Context; -- cgit v1.2.3 From 1bf2ee4ea19d3ebeb8fe35c03dd44cb1d851e19f Mon Sep 17 00:00:00 2001 From: David Binderman Date: Fri, 19 Mar 2010 09:28:07 +0000 Subject: Staging: comedi: das1800: fix kfree coding style issue Signed-off-by: David Binderman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das1800.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 3c3e0455c7c4..d91c2d9d595b 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -797,10 +797,8 @@ static int das1800_detach(struct comedi_device *dev) free_dma(devpriv->dma0); if (devpriv->dma1) free_dma(devpriv->dma1); - if (devpriv->ai_buf0) - kfree(devpriv->ai_buf0); - if (devpriv->ai_buf1) - kfree(devpriv->ai_buf1); + kfree(devpriv->ai_buf0); + kfree(devpriv->ai_buf1); } printk("comedi%d: %s: remove\n", dev->minor, -- cgit v1.2.3 From 8487d0e93a24de43c847b923f7bbbd9097e59d47 Mon Sep 17 00:00:00 2001 From: Stephen Palmateer Date: Tue, 23 Mar 2010 21:32:14 -0400 Subject: Staging: comedi: comedi_parport: added KERN_ facility levels to printk messages. This is a patch to the comedi_parport.c file that fixes the KERN_ facility warnings found by the checkpatch.pl tool Signed-off-by: Stephen Palmateer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_parport.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index 043afe4439c7..fcd7721c5537 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -309,18 +309,18 @@ static int parport_attach(struct comedi_device *dev, iobase = it->options[0]; printk(KERN_INFO "comedi%d: parport: 0x%04lx ", dev->minor, iobase); if (!request_region(iobase, PARPORT_SIZE, "parport (comedi)")) { - printk("I/O port conflict\n"); + printk(KERN_ERR "I/O port conflict\n"); return -EIO; } dev->iobase = iobase; irq = it->options[1]; if (irq) { - printk(" irq=%u", irq); + printk(KERN_INFO " irq=%u", irq); ret = request_irq(irq, parport_interrupt, 0, "comedi_parport", dev); if (ret < 0) { - printk(" irq not available\n"); + printk(KERN_ERR " irq not available\n"); return -EINVAL; } dev->irq = irq; @@ -380,13 +380,13 @@ static int parport_attach(struct comedi_device *dev, devpriv->c_data = 0; outb(devpriv->c_data, dev->iobase + PARPORT_C); - printk("\n"); + printk(KERN_INFO "\n"); return 1; } static int parport_detach(struct comedi_device *dev) { - printk("comedi%d: parport: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: parport: remove\n", dev->minor); if (dev->iobase) release_region(dev->iobase, PARPORT_SIZE); -- cgit v1.2.3 From 4ca62584a495f97869c1cbc5a61a140a38c8f375 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 28 Mar 2010 14:48:34 +0300 Subject: Staging: comedi: dt2801.c: off by one issue "dac_range_table" has 5 elements. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt2801.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c index 3f365aee4822..83fb6e56c3e9 100644 --- a/drivers/staging/comedi/drivers/dt2801.c +++ b/drivers/staging/comedi/drivers/dt2801.c @@ -472,7 +472,7 @@ static const struct comedi_lrange *dac_range_table[] = { static const struct comedi_lrange *dac_range_lkup(int opt) { - if (opt < 0 || opt > 5) + if (opt < 0 || opt >= 5) return &range_unknown; return dac_range_table[opt]; } -- cgit v1.2.3 From 48fe6039452cac9b98f2b4e1313e35765c2769df Mon Sep 17 00:00:00 2001 From: Gorskin Ilya Date: Sat, 3 Apr 2010 12:18:25 +0600 Subject: Staging: comedi: fix coding style issue in comedi.h This is a patch to the comedi.h files that fixes up errors found by the checkpatch.pl tool Signed-off-by: Gorskin Ilya Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi.h | 55 +++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index b559a9c2f857..1251e074cb2b 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -490,7 +490,8 @@ I8254_BINARY = 0 }; - static inline unsigned NI_USUAL_PFI_SELECT(unsigned pfi_channel) { + static inline unsigned NI_USUAL_PFI_SELECT(unsigned pfi_channel) + { if (pfi_channel < 10) return 0x1 + pfi_channel; else @@ -590,14 +591,17 @@ NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS = 0x20000000, /* divide source by 8 */ NI_GPCT_INVERT_CLOCK_SRC_BIT = 0x80000000 }; - static inline unsigned NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(unsigned n) { + static inline unsigned NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(unsigned n) + { /* NI 660x-specific */ return 0x10 + n; } - static inline unsigned NI_GPCT_RTSI_CLOCK_SRC_BITS(unsigned n) { + static inline unsigned NI_GPCT_RTSI_CLOCK_SRC_BITS(unsigned n) + { return 0x18 + n; } - static inline unsigned NI_GPCT_PFI_CLOCK_SRC_BITS(unsigned n) { + static inline unsigned NI_GPCT_PFI_CLOCK_SRC_BITS(unsigned n) + { /* no pfi on NI 660x */ return 0x20 + n; } @@ -625,16 +629,20 @@ May be bitwise-or'd with CR_EDGE or CR_INVERT. */ we should add them here with an offset of 0x300 when known. */ NI_GPCT_DISABLED_GATE_SELECT = 0x8000, }; - static inline unsigned NI_GPCT_GATE_PIN_GATE_SELECT(unsigned n) { + static inline unsigned NI_GPCT_GATE_PIN_GATE_SELECT(unsigned n) + { return 0x102 + n; } - static inline unsigned NI_GPCT_RTSI_GATE_SELECT(unsigned n) { + static inline unsigned NI_GPCT_RTSI_GATE_SELECT(unsigned n) + { return NI_USUAL_RTSI_SELECT(n); } - static inline unsigned NI_GPCT_PFI_GATE_SELECT(unsigned n) { + static inline unsigned NI_GPCT_PFI_GATE_SELECT(unsigned n) + { return NI_USUAL_PFI_SELECT(n); } - static inline unsigned NI_GPCT_UP_DOWN_PIN_GATE_SELECT(unsigned n) { + static inline unsigned NI_GPCT_UP_DOWN_PIN_GATE_SELECT(unsigned n) + { return 0x202 + n; } @@ -650,7 +658,8 @@ INSN_CONFIG_SET_OTHER_SRC when using NI general-purpose counters. */ /* Still unknown, probably only need NI_GPCT_PFI_OTHER_SELECT */ NI_GPCT_DISABLED_OTHER_SELECT = 0x8000, }; - static inline unsigned NI_GPCT_PFI_OTHER_SELECT(unsigned n) { + static inline unsigned NI_GPCT_PFI_OTHER_SELECT(unsigned n) + { return NI_USUAL_PFI_SELECT(n); } @@ -699,7 +708,8 @@ INSN_CONFIG_ARM */ NI_MIO_PLL_PXI10_CLOCK = 3, NI_MIO_PLL_RTSI0_CLOCK = 4 }; - static inline unsigned NI_MIO_PLL_RTSI_CLOCK(unsigned rtsi_channel) { + static inline unsigned NI_MIO_PLL_RTSI_CLOCK(unsigned rtsi_channel) + { return NI_MIO_PLL_RTSI0_CLOCK + rtsi_channel; } @@ -719,7 +729,8 @@ INSN_CONFIG_ARM */ NI_RTSI_OUTPUT_RTSI_OSC = 12 /* pre-m-series always have RTSI clock on line 7 */ }; - static inline unsigned NI_RTSI_OUTPUT_RTSI_BRD(unsigned n) { + static inline unsigned NI_RTSI_OUTPUT_RTSI_BRD(unsigned n) + { return NI_RTSI_OUTPUT_RTSI_BRD_0 + n; } @@ -754,7 +765,8 @@ INSN_CONFIG_ARM */ NI_PFI_OUTPUT_CDI_SAMPLE = 29, NI_PFI_OUTPUT_CDO_UPDATE = 30 }; - static inline unsigned NI_PFI_OUTPUT_RTSI(unsigned rtsi_channel) { + static inline unsigned NI_PFI_OUTPUT_RTSI(unsigned rtsi_channel) + { return NI_PFI_OUTPUT_RTSI0 + rtsi_channel; } @@ -772,10 +784,12 @@ INSN_CONFIG_ARM */ /* NI External Trigger lines. These values are not arbitrary, but are related * to the bits required to program the board (offset by 1 for historical * reasons). */ - static inline unsigned NI_EXT_PFI(unsigned pfi_channel) { + static inline unsigned NI_EXT_PFI(unsigned pfi_channel) + { return NI_USUAL_PFI_SELECT(pfi_channel) - 1; } - static inline unsigned NI_EXT_RTSI(unsigned rtsi_channel) { + static inline unsigned NI_EXT_RTSI(unsigned rtsi_channel) + { return NI_USUAL_RTSI_SELECT(rtsi_channel) - 1; } @@ -801,21 +815,24 @@ INSN_CONFIG_ARM */ NI_CDIO_SCAN_BEGIN_SRC_FREQ_OUT = 32, NI_CDIO_SCAN_BEGIN_SRC_DIO_CHANGE_DETECT_IRQ = 33 }; - static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel) { + static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel) + { return NI_USUAL_PFI_SELECT(pfi_channel); } - static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_RTSI(unsigned - rtsi_channel) { + static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel) + { return NI_USUAL_RTSI_SELECT(rtsi_channel); } /* scan_begin_src for scan_begin_arg==TRIG_EXT with analog output command on NI * boards. These scan begin sources can also be bitwise-or'd with CR_INVERT to * change polarity. */ - static inline unsigned NI_AO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel) { + static inline unsigned NI_AO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel) + { return NI_USUAL_PFI_SELECT(pfi_channel); } - static inline unsigned NI_AO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel) { + static inline unsigned NI_AO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel) + { return NI_USUAL_RTSI_SELECT(rtsi_channel); } -- cgit v1.2.3 From c76a326f9256e1779dc676781faf19f3a534c147 Mon Sep 17 00:00:00 2001 From: David Fernández Date: Mon, 12 Apr 2010 15:19:23 -0400 Subject: Staging: comedi: add new driver for Adlink PCI-7230 devices Signed-off-by: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/Makefile | 1 + drivers/staging/comedi/drivers/adl_pci7230.c | 206 +++++++++++++++++++++++++++ 2 files changed, 207 insertions(+) create mode 100644 drivers/staging/comedi/drivers/adl_pci7230.c (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index df2854d543cc..be995144e20d 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_3120.o obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_3501.o obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_3xxx.o obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci6208.o +obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci7230.o obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci7296.o obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci7432.o obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci8164.o diff --git a/drivers/staging/comedi/drivers/adl_pci7230.c b/drivers/staging/comedi/drivers/adl_pci7230.c new file mode 100644 index 000000000000..24a82eb9d153 --- /dev/null +++ b/drivers/staging/comedi/drivers/adl_pci7230.c @@ -0,0 +1,206 @@ +/* + comedi/drivers/adl_pci7230.c + + Hardware comedi driver fot PCI7230 Adlink card + Copyright (C) 2010 David Fernandez + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +/* +Driver: adl_pci7230 +Description: Driver for the Adlink PCI-7230 32 ch. isolated digital io board +Devices: [ADLink] PCI-7230 (adl_pci7230) +Author: David Fernandez +Status: experimental +Updated: Mon, 14 Apr 2008 15:08:14 +0100 + +Configuration Options: + [0] - PCI bus of device (optional) + [1] - PCI slot of device (optional) + If bus/slot is not specified, the first supported + PCI device found will be used. +*/ + +#include "../comedidev.h" +#include +#include "comedi_pci.h" + +#define PCI7230_DI 0x00 +#define PCI7230_DO 0x00 + +#define PCI_DEVICE_ID_PCI7230 0x7230 + +static DEFINE_PCI_DEVICE_TABLE(adl_pci7230_pci_table) = { + { + PCI_VENDOR_ID_ADLINK, + PCI_DEVICE_ID_PCI7230, + PCI_ANY_ID, + PCI_ANY_ID, + 0, + 0, + 0 + }, + {0} +}; + +MODULE_DEVICE_TABLE(pci, adl_pci7230_pci_table); + +struct adl_pci7230_private { + int data; + struct pci_dev *pci_dev; +}; + +#define devpriv ((struct adl_pci7230_private *)dev->private) + +static int adl_pci7230_attach(struct comedi_device *dev, + struct comedi_devconfig *it); +static int adl_pci7230_detach(struct comedi_device *dev); +static struct comedi_driver driver_adl_pci7230 = { + .driver_name = "adl_pci7230", + .module = THIS_MODULE, + .attach = adl_pci7230_attach, + .detach = adl_pci7230_detach, +}; + +/* Digital IO */ + +static int adl_pci7230_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data); + +static int adl_pci7230_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data); + +static int adl_pci7230_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct pci_dev *pcidev; + struct comedi_subdevice *s; + int bus, slot; + + printk(KERN_INFO "comedi%d: adl_pci7230\n", dev->minor); + + dev->board_name = "pci7230"; + bus = it->options[0]; + slot = it->options[1]; + + if (alloc_private(dev, sizeof(struct adl_pci7230_private)) < 0) + return -ENOMEM; + + if (alloc_subdevices(dev, 2) < 0) + return -ENOMEM; + + for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); + pcidev != NULL; + pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) { + + if (pcidev->vendor == PCI_VENDOR_ID_ADLINK && + pcidev->device == PCI_DEVICE_ID_PCI7230) { + if (bus || slot) { + /* requested particular bus/slot */ + if (pcidev->bus->number != bus || + PCI_SLOT(pcidev->devfn) != slot) { + continue; + } + } + devpriv->pci_dev = pcidev; + break; + } + } + if (pcidev == NULL) { + printk(KERN_ERR "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", + dev->minor, bus, slot); + return -EIO; + } + if (comedi_pci_enable(pcidev, "adl_pci7230") < 0) { + printk(KERN_ERR "comedi%d: Failed to enable PCI device and request regions\n", + dev->minor); + return -EIO; + } + dev->iobase = pci_resource_start(pcidev, 2); + printk(KERN_DEBUG "comedi: base addr %4lx\n", dev->iobase); + + s = dev->subdevices + 0; + /* Isolated do */ + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 16; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = adl_pci7230_do_insn_bits; + + s = dev->subdevices + 1; + /* Isolated di */ + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 16; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = adl_pci7230_di_insn_bits; + + printk(KERN_DEBUG "comedi: attached\n"); + + return 1; +} + +static int adl_pci7230_detach(struct comedi_device *dev) +{ + printk(KERN_DEBUG "comedi%d: pci7230: remove\n", dev->minor); + + if (devpriv && devpriv->pci_dev) { + if (dev->iobase) + comedi_pci_disable(devpriv->pci_dev); + pci_dev_put(devpriv->pci_dev); + } + + return 0; +} + +static int adl_pci7230_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + if (insn->n != 2) + return -EINVAL; + + if (data[0]) { + s->state &= ~data[0]; + s->state |= (data[0] & data[1]); + + outl((s->state << 16) & 0xffffffff, dev->iobase + PCI7230_DO); + } + + return 2; +} + +static int adl_pci7230_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + if (insn->n != 2) + return -EINVAL; + + data[1] = inl(dev->iobase + PCI7230_DI) & 0xffffffff; + + return 2; +} + +COMEDI_PCI_INITCLEANUP(driver_adl_pci7230, adl_pci7230_pci_table); -- cgit v1.2.3 From 3c0d681e7d31fe747a2cbed0a93dd92049521683 Mon Sep 17 00:00:00 2001 From: Gustavo Silva Date: Wed, 21 Apr 2010 00:34:35 -0500 Subject: Staging: comedi: drivers: fix coding style issues in das16.c This is a patch to the das16.c file that fixes up the following issues found by the checkpatch.pl tool. WARNING: line over 80 characters x 23 ERROR: spaces required around that '?' (ctx:VxV) x 2 ERROR: spaces required around that ':' (ctx:VxV) x 2 WARNING: printk() should include KERN_ facility level x 17 WARNING: braces {} are not necessary for single statement blocks x 8 Signed-off-by: Gustavo Silva Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das16.c | 159 +++++++++++++++++++-------------- 1 file changed, 90 insertions(+), 69 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index f2aadda9b241..ccee4f1802d6 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -74,7 +74,8 @@ Keithley Manuals: 4922.PDF (das-1400) 4923.PDF (das1200, 1400, 1600) -Computer boards manuals also available from their website www.measurementcomputing.com +Computer boards manuals also available from their website +www.measurementcomputing.com */ @@ -92,7 +93,8 @@ Computer boards manuals also available from their website www.measurementcomputi /* #define DEBUG */ #ifdef DEBUG -#define DEBUG_PRINT(format, args...) printk("das16: " format, ## args) +#define DEBUG_PRINT(format, args...) \ + printk(KERN_DEBUG "das16: " format, ## args) #else #define DEBUG_PRINT(format, args...) #endif @@ -186,15 +188,16 @@ Computer boards manuals also available from their website www.measurementcomputi */ -static const int sample_size = 2; /* size in bytes of a sample from board */ +/* size in bytes of a sample from board */ +static const int sample_size = 2; #define DAS16_TRIG 0 #define DAS16_AI_LSB 0 #define DAS16_AI_MSB 1 #define DAS16_MUX 2 #define DAS16_DIO 3 -#define DAS16_AO_LSB(x) ((x)?6:4) -#define DAS16_AO_MSB(x) ((x)?7:5) +#define DAS16_AO_LSB(x) ((x) ? 6 : 4) +#define DAS16_AO_MSB(x) ((x) ? 7 : 5) #define DAS16_STATUS 8 #define BUSY (1<<7) #define UNIPOLAR (1<<6) @@ -271,7 +274,7 @@ static const struct comedi_lrange range_das1x02_unip = { 4, { }; static const struct comedi_lrange range_das16jr = { 9, { - /* also used by 16/330 */ + /* also used by 16/330 */ BIP_RANGE(10), BIP_RANGE(5), BIP_RANGE(2.5), @@ -547,7 +550,8 @@ static const struct das16_board das16_boards[] = { .id = 0x20, }, { - .name = "das-1401", /* 4919.pdf and 4922.pdf (keithley user's manual) */ + /* 4919.pdf and 4922.pdf (keithley user's manual) */ + .name = "das-1401", .ai = das16_ai_rinsn, .ai_nbits = 12, .ai_speed = 10000, @@ -558,10 +562,11 @@ static const struct das16_board das16_boards[] = { .i8255_offset = 0x0, .i8254_offset = 0x0c, .size = 0x408, - .id = 0xc0 /* 4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0 */ + .id = 0xc0 /* 4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0 */ }, { - .name = "das-1402", /* 4919.pdf and 4922.pdf (keithley user's manual) */ + /* 4919.pdf and 4922.pdf (keithley user's manual) */ + .name = "das-1402", .ai = das16_ai_rinsn, .ai_nbits = 12, .ai_speed = 10000, @@ -572,7 +577,7 @@ static const struct das16_board das16_boards[] = { .i8255_offset = 0x0, .i8254_offset = 0x0c, .size = 0x408, - .id = 0xc0 /* 4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0 */ + .id = 0xc0 /* 4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0 */ }, { .name = "das-1601", /* 4919.pdf */ @@ -704,7 +709,8 @@ static const struct das16_board das16_boards[] = { .name = "das16/jr/ctr5", /* ? */ }, { - .name = "cio-das16/m1/16", /* cio-das16_m1_16.pdf, this board is a bit quirky, no dma */ + /* cio-das16_m1_16.pdf, this board is a bit quirky, no dma */ + .name = "cio-das16/m1/16", }, #endif }; @@ -736,14 +742,19 @@ struct das16_private_struct { unsigned int clockbase; /* master clock speed in ns */ volatile unsigned int control_state; /* dma, interrupt and trigger control bits */ volatile unsigned long adc_byte_count; /* number of bytes remaining */ - unsigned int divisor1; /* divisor dividing master clock to get conversion frequency */ - unsigned int divisor2; /* divisor dividing master clock to get conversion frequency */ + /* divisor dividing master clock to get conversion frequency */ + unsigned int divisor1; + /* divisor dividing master clock to get conversion frequency */ + unsigned int divisor2; unsigned int dma_chan; /* dma channel */ uint16_t *dma_buffer[2]; dma_addr_t dma_buffer_addr[2]; unsigned int current_buffer; volatile unsigned int dma_transfer_size; /* target number of bytes to transfer per dma shot */ - /* user-defined analog input and output ranges defined from config options */ + /** + * user-defined analog input and output ranges + * defined from config options + */ struct comedi_lrange *user_ai_range_table; struct comedi_lrange *user_ao_range_table; @@ -798,7 +809,10 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /** + * step 2: make sure trigger sources are unique and + * mutually compatible + */ if (cmd->scan_begin_src != TRIG_TIMER && cmd->scan_begin_src != TRIG_EXT && cmd->scan_begin_src != TRIG_FOLLOW) @@ -893,12 +907,15 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, if (CR_CHAN(cmd->chanlist[i]) != (start_chan + i) % s->n_chan) { comedi_error(dev, - "entries in chanlist must be consecutive channels, counting upwards\n"); + "entries in chanlist must be " + "consecutive channels, " + "counting upwards\n"); err++; } if (CR_RANGE(cmd->chanlist[i]) != gain) { comedi_error(dev, - "entries in chanlist must all have the same gain\n"); + "entries in chanlist must all " + "have the same gain\n"); err++; } } @@ -920,12 +937,13 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) if (devpriv->dma_chan == 0 || (dev->irq == 0 && devpriv->timer_mode == 0)) { comedi_error(dev, - "irq (or use of 'timer mode') dma required to execute comedi_cmd"); + "irq (or use of 'timer mode') dma required to " + "execute comedi_cmd"); return -1; } if (cmd->flags & TRIG_RT) { - comedi_error(dev, - "isa dma transfers cannot be performed with TRIG_RT, aborting"); + comedi_error(dev, "isa dma transfers cannot be performed with " + "TRIG_RT, aborting"); return -1; } @@ -933,16 +951,17 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) cmd->stop_arg * cmd->chanlist_len * sizeof(uint16_t); /* disable conversions for das1600 mode */ - if (thisboard->size > 0x400) { + if (thisboard->size > 0x400) outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV); - } + /* set scan limits */ byte = CR_CHAN(cmd->chanlist[0]); byte |= CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]) << 4; outb(byte, dev->iobase + DAS16_MUX); /* set gain (this is also burst rate register but according to - * computer boards manual, burst rate does nothing, even on keithley cards) */ + * computer boards manual, burst rate does nothing, even on + * keithley cards) */ if (thisboard->ai_pg != das16_pg_none) { range = CR_RANGE(cmd->chanlist[0]); outb((das16_gainlists[thisboard->ai_pg])[range], @@ -1005,9 +1024,9 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) outb(devpriv->control_state, dev->iobase + DAS16_CONTROL); /* Enable conversions if using das1600 mode */ - if (thisboard->size > 0x400) { + if (thisboard->size > 0x400) outb(0, dev->iobase + DAS1600_CONV); - } + return 0; } @@ -1030,9 +1049,9 @@ static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s) } /* disable burst mode */ - if (thisboard->size > 0x400) { + if (thisboard->size > 0x400) outb(0, dev->iobase + DAS1600_BURST); - } + spin_unlock_irqrestore(&dev->spinlock, flags); @@ -1085,11 +1104,11 @@ static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, } msb = inb(dev->iobase + DAS16_AI_MSB); lsb = inb(dev->iobase + DAS16_AI_LSB); - if (thisboard->ai_nbits == 12) { + if (thisboard->ai_nbits == 12) data[n] = ((lsb >> 4) & 0xf) | (msb << 4); - } else { + else data[n] = lsb | (msb << 8); - } + } return n; @@ -1207,8 +1226,8 @@ static int disable_dma_on_even(struct comedi_device *dev) residue = get_dma_residue(devpriv->dma_chan); } if (i == disable_limit) { - comedi_error(dev, - "failed to get an even dma transfer, could be trouble."); + comedi_error(dev, "failed to get an even dma transfer, " + "could be trouble."); } return residue; } @@ -1254,7 +1273,8 @@ static void das16_interrupt(struct comedi_device *dev) } else num_bytes = devpriv->dma_transfer_size - residue; - if (cmd->stop_src == TRIG_COUNT && num_bytes >= devpriv->adc_byte_count) { + if (cmd->stop_src == TRIG_COUNT && + num_bytes >= devpriv->adc_byte_count) { num_bytes = devpriv->adc_byte_count; async->events |= COMEDI_CB_EOA; } @@ -1275,9 +1295,9 @@ static void das16_interrupt(struct comedi_device *dev) set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size); enable_dma(devpriv->dma_chan); /* reenable conversions for das1600 mode, (stupid hardware) */ - if (thisboard->size > 0x400 && devpriv->timer_mode == 0) { + if (thisboard->size > 0x400 && devpriv->timer_mode == 0) outb(0x00, dev->iobase + DAS1600_CONV); - } + } release_dma_lock(dma_flags); @@ -1330,25 +1350,25 @@ static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it) status = inb(dev->iobase + DAS16_STATUS); - if ((status & UNIPOLAR)) { + if ((status & UNIPOLAR)) devpriv->ai_unipolar = 1; - } else { + else devpriv->ai_unipolar = 0; - } - if ((status & DAS16_MUXBIT)) { + + if ((status & DAS16_MUXBIT)) devpriv->ai_singleended = 1; - } else { + else devpriv->ai_singleended = 0; - } + /* diobits indicates boards */ diobits = inb(dev->iobase + DAS16_DIO) & 0xf0; - printk(" id bits are 0x%02x\n", diobits); + printk(KERN_INFO " id bits are 0x%02x\n", diobits); if (thisboard->id != diobits) { - printk(" requested board's id bits are 0x%x (ignore)\n", + printk(KERN_INFO " requested board's id bits are 0x%x (ignore)\n", thisboard->id); } @@ -1363,10 +1383,10 @@ static int das1600_mode_detect(struct comedi_device *dev) if (status & DAS1600_CLK_10MHZ) { devpriv->clockbase = 100; - printk(" 10MHz pacer clock\n"); + printk(KERN_INFO " 10MHz pacer clock\n"); } else { devpriv->clockbase = 1000; - printk(" 1MHz pacer clock\n"); + printk(KERN_INFO " 1MHz pacer clock\n"); } reg_dump(dev); @@ -1406,14 +1426,15 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (timer_mode) irq = 0; - printk("comedi%d: das16:", dev->minor); + printk(KERN_INFO "comedi%d: das16:", dev->minor); /* check that clock setting is valid */ if (it->options[3]) { if (it->options[3] != 0 && it->options[3] != 1 && it->options[3] != 10) { printk - ("\n Invalid option. Master clock must be set to 1 or 10 (MHz)\n"); + ("\n Invalid option. Master clock must be set " + "to 1 or 10 (MHz)\n"); return -EINVAL; } } @@ -1425,23 +1446,23 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (thisboard->size < 0x400) { printk(" 0x%04lx-0x%04lx\n", iobase, iobase + thisboard->size); if (!request_region(iobase, thisboard->size, "das16")) { - printk(" I/O port conflict\n"); + printk(KERN_ERR " I/O port conflict\n"); return -EIO; } } else { - printk(" 0x%04lx-0x%04lx 0x%04lx-0x%04lx\n", + printk(KERN_INFO " 0x%04lx-0x%04lx 0x%04lx-0x%04lx\n", iobase, iobase + 0x0f, iobase + 0x400, iobase + 0x400 + (thisboard->size & 0x3ff)); if (!request_region(iobase, 0x10, "das16")) { - printk(" I/O port conflict: 0x%04lx-0x%04lx\n", + printk(KERN_ERR " I/O port conflict: 0x%04lx-0x%04lx\n", iobase, iobase + 0x0f); return -EIO; } if (!request_region(iobase + 0x400, thisboard->size & 0x3ff, "das16")) { release_region(iobase, 0x10); - printk(" I/O port conflict: 0x%04lx-0x%04lx\n", + printk(KERN_ERR " I/O port conflict: 0x%04lx-0x%04lx\n", iobase + 0x400, iobase + 0x400 + (thisboard->size & 0x3ff)); return -EIO; @@ -1452,7 +1473,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* probe id bits to make sure they are consistent */ if (das16_probe(dev, it)) { - printk(" id bits do not match selected board, aborting\n"); + printk(KERN_ERR " id bits do not match selected board, aborting\n"); return -EINVAL; } dev->board_name = thisboard->name; @@ -1474,7 +1495,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret < 0) return ret; dev->irq = irq; - printk(" ( irq = %u )", irq); + printk(KERN_INFO " ( irq = %u )", irq); } else if (irq == 0) { printk(" ( no irq )"); } else { @@ -1488,16 +1509,15 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* allocate dma buffers */ int i; for (i = 0; i < 2; i++) { - devpriv->dma_buffer[i] = pci_alloc_consistent(NULL, - DAS16_DMA_SIZE, - &devpriv-> - dma_buffer_addr - [i]); + devpriv->dma_buffer[i] = pci_alloc_consistent( + NULL, DAS16_DMA_SIZE, + &devpriv->dma_buffer_addr[i]); + if (devpriv->dma_buffer[i] == NULL) return -ENOMEM; } if (request_dma(dma_chan, "das16")) { - printk(" failed to allocate dma channel %i\n", + printk(KERN_ERR " failed to allocate dma channel %i\n", dma_chan); return -EINVAL; } @@ -1506,11 +1526,11 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) disable_dma(devpriv->dma_chan); set_dma_mode(devpriv->dma_chan, DMA_MODE_READ); release_dma_lock(flags); - printk(" ( dma = %u)\n", dma_chan); + printk(KERN_INFO " ( dma = %u)\n", dma_chan); } else if (dma_chan == 0) { - printk(" ( no dma )\n"); + printk(KERN_INFO " ( no dma )\n"); } else { - printk(" invalid dma channel\n"); + printk(KERN_ERR " invalid dma channel\n"); return -EINVAL; } @@ -1569,7 +1589,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->subdev_flags |= SDF_DIFF; } s->maxdata = (1 << thisboard->ai_nbits) - 1; - if (devpriv->user_ai_range_table) { /* user defined ai range */ + if (devpriv->user_ai_range_table) { /* user defined ai range */ s->range_table = devpriv->user_ai_range_table; } else if (devpriv->ai_unipolar) { s->range_table = das16_ai_uni_lranges[thisboard->ai_pg]; @@ -1592,11 +1612,12 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->subdev_flags = SDF_WRITABLE; s->n_chan = 2; s->maxdata = (1 << thisboard->ao_nbits) - 1; - if (devpriv->user_ao_range_table) { /* user defined ao range */ + /* user defined ao range */ + if (devpriv->user_ao_range_table) s->range_table = devpriv->user_ao_range_table; - } else { + else s->range_table = &range_unknown; - } + s->insn_write = thisboard->ao; } else { s->type = COMEDI_SUBD_UNUSED; @@ -1656,7 +1677,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) static int das16_detach(struct comedi_device *dev) { - printk("comedi%d: das16: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: das16: remove\n", dev->minor); das16_reset(dev); @@ -1750,8 +1771,8 @@ static void das16_ai_munge(struct comedi_device *dev, for (i = 0; i < num_samples; i++) { data[i] = le16_to_cpu(data[i]); - if (thisboard->ai_nbits == 12) { + if (thisboard->ai_nbits == 12) data[i] = (data[i] >> 4) & 0xfff; - } + } } -- cgit v1.2.3 From b4ae23ce014d25af6c09bf3e82b4fd94b0cd2cb9 Mon Sep 17 00:00:00 2001 From: Gustavo Silva Date: Mon, 19 Apr 2010 01:21:10 -0500 Subject: Staging: comedi: drivers: fix coding style issues in das08.c This is a patch to the das08.c file that fixes up the following issues found by the checkpatch.pl tool. WARNING: line over 80 characters x 6 ERROR: code indent should use tabs where possible x 3 ERROR: spaces required around that '?' (ctx:VxV) x 4 ERROR: spaces required around that ':' (ctx:VxV) x 4 ERROR: that open brace { should be on the previous line x 1 WARNING: printk() should include KERN_ facility level x 9 WARNING: braces {} are not necessary for single statement blocks x 1 WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable x 2 Signed-off-by: Gustavo Silva Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das08.c | 156 +++++++++++++++++---------------- 1 file changed, 82 insertions(+), 74 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index f4258334532c..9cb144f7e70c 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -1,55 +1,55 @@ /* - comedi/drivers/das08.c - DAS08 driver - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 2000 David A. Schleef - Copyright (C) 2001,2002,2003 Frank Mori Hess - Copyright (C) 2004 Salvador E. Tropea - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -***************************************************************** + * comedi/drivers/das08.c + * DAS08 driver + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 2000 David A. Schleef + * Copyright (C) 2001,2002,2003 Frank Mori Hess + * Copyright (C) 2004 Salvador E. Tropea + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + ***************************************************************** + */ -*/ /* -Driver: das08 -Description: DAS-08 compatible boards -Author: Warren Jasper, ds, Frank Hess -Devices: [Keithley Metrabyte] DAS08 (isa-das08), [ComputerBoards] DAS08 (isa-das08), - DAS08-PGM (das08-pgm), - DAS08-PGH (das08-pgh), DAS08-PGL (das08-pgl), DAS08-AOH (das08-aoh), - DAS08-AOL (das08-aol), DAS08-AOM (das08-aom), DAS08/JR-AO (das08/jr-ao), - DAS08/JR-16-AO (das08jr-16-ao), PCI-DAS08 (das08), - PC104-DAS08 (pc104-das08), DAS08/JR/16 (das08jr/16) -Status: works - -This is a rewrite of the das08 and das08jr drivers. - -Options (for ISA cards): - [0] - base io address - -Options (for pci-das08): - [0] - bus (optional) - [1] = slot (optional) - -The das08 driver doesn't support asynchronous commands, since -the cheap das08 hardware doesn't really support them. The -comedi_rt_timer driver can be used to emulate commands for this -driver. -*/ + * Driver: das08 + * Description: DAS-08 compatible boards + * Author: Warren Jasper, ds, Frank Hess + * Devices: [Keithley Metrabyte] DAS08 (isa-das08), + * [ComputerBoards] DAS08 (isa-das08), DAS08-PGM (das08-pgm), + * DAS08-PGH (das08-pgh), DAS08-PGL (das08-pgl), DAS08-AOH (das08-aoh), + * DAS08-AOL (das08-aol), DAS08-AOM (das08-aom), DAS08/JR-AO (das08/jr-ao), + * DAS08/JR-16-AO (das08jr-16-ao), PCI-DAS08 (das08), + * PC104-DAS08 (pc104-das08), DAS08/JR/16 (das08jr/16) + * Status: works + * + * This is a rewrite of the das08 and das08jr drivers. + * + * Options (for ISA cards): + * [0] - base io address + * + * Options (for pci-das08): + * [0] - bus (optional) + * [1] = slot (optional) + * + * The das08 driver doesn't support asynchronous commands, since + * the cheap das08 hardware doesn't really support them. The + * comedi_rt_timer driver can be used to emulate commands for this + * driver. + */ #include "../comedidev.h" @@ -122,8 +122,8 @@ driver. */ #define DAS08JR_DIO 3 -#define DAS08JR_AO_LSB(x) ((x)?6:4) -#define DAS08JR_AO_MSB(x) ((x)?7:5) +#define DAS08JR_AO_LSB(x) ((x) ? 6 : 4) +#define DAS08JR_AO_MSB(x) ((x) ? 7 : 5) /* cio-das08_aox.pdf @@ -148,8 +148,8 @@ driver. #define DAS08AO_GAIN_CONTROL 3 #define DAS08AO_GAIN_STATUS 3 -#define DAS08AO_AO_LSB(x) ((x)?0xa:8) -#define DAS08AO_AO_MSB(x) ((x)?0xb:9) +#define DAS08AO_AO_LSB(x) ((x) ? 0xa : 8) +#define DAS08AO_AO_MSB(x) ((x) ? 0xb : 9) #define DAS08AO_AO_UPDATE 8 /* gainlist same as _pgx_ below */ @@ -239,8 +239,9 @@ static const struct comedi_lrange *const das08_ai_lranges[] = { &range_das08_pgm, }; -static const int das08_pgh_gainlist[] = - { 8, 0, 10, 2, 12, 4, 14, 6, 1, 3, 5, 7 }; +static const int das08_pgh_gainlist[] = { + 8, 0, 10, 2, 12, 4, 14, 6, 1, 3, 5, 7 +}; static const int das08_pgl_gainlist[] = { 8, 0, 2, 4, 6, 1, 3, 5, 7 }; static const int das08_pgm_gainlist[] = { 8, 0, 10, 12, 14, 9, 11, 13, 15 }; @@ -535,7 +536,8 @@ static int das08_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, inb(dev->iobase + DAS08_MSB); /* set multiplexer */ - spin_lock(&dev->spinlock); /* lock to prevent race with digital output */ + /* lock to prevent race with digital output */ + spin_lock(&dev->spinlock); devpriv->do_mux_bits &= ~DAS08_MUX_MASK; devpriv->do_mux_bits |= DAS08_MUX(chan); outb(devpriv->do_mux_bits, dev->iobase + DAS08_CONTROL); @@ -552,7 +554,7 @@ static int das08_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, /* clear over-range bits for 16-bit boards */ if (thisboard->ai_nbits == 16) if (inb(dev->iobase + DAS08_MSB) & 0x80) - printk("das08: over-range\n"); + printk(KERN_INFO "das08: over-range\n"); /* trigger conversion */ outb_p(0, dev->iobase + DAS08_TRIG_12BIT); @@ -562,7 +564,7 @@ static int das08_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, break; } if (i == TIMEOUT) { - printk("das08: timeout\n"); + printk(KERN_ERR "das08: timeout\n"); return -ETIME; } msb = inb(dev->iobase + DAS08_MSB); @@ -607,7 +609,8 @@ static int das08_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, /* set new bit values */ wbits |= data[0] & data[1]; /* remember digital output bits */ - spin_lock(&dev->spinlock); /* prevent race with setting of analog input mux */ + /* prevent race with setting of analog input mux */ + spin_lock(&dev->spinlock); devpriv->do_mux_bits &= ~DAS08_DO_MASK; devpriv->do_mux_bits |= DAS08_OP(wbits); outb(devpriv->do_mux_bits, dev->iobase + DAS08_CONTROL); @@ -860,9 +863,9 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) /* allocate ioports for non-pcmcia, non-pci boards */ if ((thisboard->bustype != pcmcia) && (thisboard->bustype != pci)) { - printk(" iobase 0x%lx\n", iobase); + printk(KERN_INFO " iobase 0x%lx\n", iobase); if (!request_region(iobase, thisboard->iosize, DRV_NAME)) { - printk(" I/O port conflict\n"); + printk(KERN_ERR " I/O port conflict\n"); return -EIO; } } @@ -878,8 +881,11 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) /* ai */ if (thisboard->ai) { s->type = COMEDI_SUBD_AI; - /* XXX some boards actually have differential inputs instead of single ended. - * The driver does nothing with arefs though, so it's no big deal. */ + /* XXX some boards actually have differential + * inputs instead of single ended. + * The driver does nothing with arefs though, + * so it's no big deal. + */ s->subdev_flags = SDF_READABLE | SDF_GROUND; s->n_chan = 8; s->maxdata = (1 << thisboard->ai_nbits) - 1; @@ -966,6 +972,7 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) return 0; } +EXPORT_SYMBOL_GPL(das08_common_attach); static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -980,7 +987,7 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret < 0) return ret; - printk("comedi%d: das08: ", dev->minor); + printk(KERN_INFO "comedi%d: das08: ", dev->minor); /* deal with a pci board */ if (thisboard->bustype == pci) { #ifdef CONFIG_COMEDI_PCI @@ -1007,20 +1014,21 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) } } if (!pdev) { - printk("No pci das08 cards found\n"); + printk(KERN_ERR "No pci das08 cards found\n"); return -EIO; } devpriv->pdev = pdev; /* enable PCI device and reserve I/O spaces */ if (comedi_pci_enable(pdev, DRV_NAME)) { - printk - (" Error enabling PCI device and requesting regions\n"); + printk(KERN_ERR " Error enabling PCI device and " + "requesting regions\n"); return -EIO; } /* read base addresses */ pci_iobase = pci_resource_start(pdev, 1); iobase = pci_resource_start(pdev, 2); - printk("pcibase 0x%lx iobase 0x%lx\n", pci_iobase, iobase); + printk(KERN_INFO "pcibase 0x%lx iobase 0x%lx\n", + pci_iobase, iobase); devpriv->pci_iobase = pci_iobase; #if 0 /* We could enable to pci-das08's interrupt here to make it possible @@ -1034,17 +1042,18 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) outw(INTR1_ENABLE | PCI_INTR_ENABLE, pci_iobase + INTCSR); #endif #else /* CONFIG_COMEDI_PCI */ - printk("this driver has not been built with PCI support.\n"); + printk(KERN_ERR "this driver has not been built with PCI support.\n"); return -EINVAL; #endif /* CONFIG_COMEDI_PCI */ } else { iobase = it->options[0]; } - printk("\n"); + printk(KERN_INFO "\n"); return das08_common_attach(dev, iobase); } + int das08_common_detach(struct comedi_device *dev) { printk(KERN_INFO "comedi%d: das08: remove\n", dev->minor); @@ -1060,9 +1069,9 @@ int das08_common_detach(struct comedi_device *dev) #ifdef CONFIG_COMEDI_PCI if (devpriv) { if (devpriv->pdev) { - if (devpriv->pci_iobase) { + if (devpriv->pci_iobase) comedi_pci_disable(devpriv->pdev); - } + pci_dev_put(devpriv->pdev); } } @@ -1070,6 +1079,7 @@ int das08_common_detach(struct comedi_device *dev) return 0; } +EXPORT_SYMBOL_GPL(das08_common_detach); #ifdef CONFIG_COMEDI_PCI COMEDI_PCI_INITCLEANUP(driver_das08, das08_pci_table); @@ -1077,8 +1087,6 @@ COMEDI_PCI_INITCLEANUP(driver_das08, das08_pci_table); COMEDI_INITCLEANUP(driver_das08); #endif -EXPORT_SYMBOL_GPL(das08_common_attach); -EXPORT_SYMBOL_GPL(das08_common_detach); #ifdef CONFIG_COMEDI_PCMCIA EXPORT_SYMBOL_GPL(das08_cs_boards); #endif -- cgit v1.2.3 From 06033fced289985294e5a3f694646014d80b48cc Mon Sep 17 00:00:00 2001 From: Darren Armstrong Date: Sun, 25 Apr 2010 02:49:49 +0100 Subject: Staging: comedi: ssc_dnp: Fixed coding style issues Fixed coding style issues: 80-char width limit, KERN_ facility level Signed-off-by: Darren Armstrong Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ssv_dnp.c | 86 +++++++++++++++++--------------- 1 file changed, 45 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c index 17c92a57b0dd..18b0a83c4bbc 100644 --- a/drivers/staging/comedi/drivers/ssv_dnp.c +++ b/drivers/staging/comedi/drivers/ssv_dnp.c @@ -41,14 +41,14 @@ Status: unknown /* 0..3 remain unchanged! For details about Port C Mode Register see */ /* the remarks in dnp_insn_config() below. */ -#define CSCIR 0x22 /* Chip Setup and Control Index Register */ -#define CSCDR 0x23 /* Chip Setup and Control Data Register */ -#define PAMR 0xa5 /* Port A Mode Register */ -#define PADR 0xa9 /* Port A Data Register */ -#define PBMR 0xa4 /* Port B Mode Register */ -#define PBDR 0xa8 /* Port B Data Register */ -#define PCMR 0xa3 /* Port C Mode Register */ -#define PCDR 0xa7 /* Port C Data Register */ +#define CSCIR 0x22 /* Chip Setup and Control Index Register */ +#define CSCDR 0x23 /* Chip Setup and Control Data Register */ +#define PAMR 0xa5 /* Port A Mode Register */ +#define PADR 0xa9 /* Port A Data Register */ +#define PBMR 0xa4 /* Port B Mode Register */ +#define PBDR 0xa8 /* Port B Data Register */ +#define PCMR 0xa3 /* Port C Mode Register */ +#define PCDR 0xa7 /* Port C Data Register */ /* This data structure holds information about the supported boards -------- */ @@ -59,8 +59,9 @@ struct dnp_board { int have_dio; }; -static const struct dnp_board dnp_boards[] = { /* we only support one DNP 'board' */ - { /* variant at the moment */ +/* We only support one DNP 'board' variant at the moment */ +static const struct dnp_board dnp_boards[] = { +{ .name = "dnp-1486", .ai_chans = 16, .ai_bits = 12, @@ -80,9 +81,9 @@ struct dnp_private_data { #define devpriv ((dnp_private *)dev->private) /* ------------------------------------------------------------------------- */ -/* The struct comedi_driver structure tells the Comedi core module which functions */ -/* to call to configure/deconfigure (attach/detach) the board, and also */ -/* about the kernel module that contains the device code. */ +/* The struct comedi_driver structure tells the Comedi core module which */ +/* functions to call to configure/deconfigure (attach/detach) the board, and */ +/* also about the kernel module that contains the device code. */ /* */ /* In the following section we define the API of this driver. */ /* ------------------------------------------------------------------------- */ @@ -97,7 +98,7 @@ static struct comedi_driver driver_dnp = { .detach = dnp_detach, .board_name = &dnp_boards[0].name, /* only necessary for non-PnP devs */ - .offset = sizeof(struct dnp_board), /* like ISA-PnP, PCI or PCMCIA. */ + .offset = sizeof(struct dnp_board), /* like ISA-PnP, PCI or PCMCIA */ .num_names = ARRAY_SIZE(dnp_boards), }; @@ -122,28 +123,30 @@ static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; - printk("comedi%d: dnp: ", dev->minor); + printk(KERN_INFO "comedi%d: dnp: ", dev->minor); - /* Autoprobing: this should find out which board we have. Currently only */ - /* the 1486 board is supported and autoprobing is not implemented :-) */ + /* Autoprobing: this should find out which board we have. Currently */ + /* only the 1486 board is supported and autoprobing is not */ + /* implemented :-) */ /* dev->board_ptr = dnp_probe(dev); */ - /* Initialize the name of the board. We can use the "thisboard" macro now. */ + /* Initialize the name of the board. */ + /* We can use the "thisboard" macro now. */ dev->board_name = thisboard->name; - /* Allocate the private structure area. alloc_private() is a convenient */ - /* macro defined in comedidev.h. */ + /* Allocate the private structure area. alloc_private() is a */ + /* convenient macro defined in comedidev.h. */ if (alloc_private(dev, sizeof(struct dnp_private_data)) < 0) return -ENOMEM; - /* Allocate the subdevice structures. alloc_subdevice() is a convenient */ - /* macro defined in comedidev.h. */ + /* Allocate the subdevice structures. alloc_subdevice() is a */ + /* convenient macro defined in comedidev.h. */ if (alloc_subdevices(dev, 1) < 0) return -ENOMEM; s = dev->subdevices + 0; - /* digital i/o subdevice */ + /* digital i/o subdevice */ s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 20; @@ -158,7 +161,7 @@ static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) * allocated for the primary 8259, so we don't need to allocate them * ourselves. */ - /* configure all ports as input (default) */ + /* configure all ports as input (default) */ outb(PAMR, CSCIR); outb(0x00, CSCDR); outb(PBMR, CSCIR); @@ -181,7 +184,7 @@ static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) static int dnp_detach(struct comedi_device *dev) { - /* configure all ports as input (default) */ + /* configure all ports as input (default) */ outb(PAMR, CSCIR); outb(0x00, CSCDR); outb(PBMR, CSCIR); @@ -189,8 +192,8 @@ static int dnp_detach(struct comedi_device *dev) outb(PCMR, CSCIR); outb((inb(CSCDR) & 0xAA), CSCDR); - /* announce that we are finished */ - printk("comedi%d: dnp: remove\n", dev->minor); + /* announce that we are finished */ + printk(KERN_INFO "comedi%d: dnp: remove\n", dev->minor); return 0; @@ -210,12 +213,12 @@ static int dnp_dio_insn_bits(struct comedi_device *dev, if (insn->n != 2) return -EINVAL; /* insn uses data[0] and data[1] */ - /* The insn data is a mask in data[0] and the new data in data[1], each */ - /* channel cooresponding to a bit. */ + /* The insn data is a mask in data[0] and the new data in data[1], */ + /* each channel cooresponding to a bit. */ - /* Ports A and B are straight forward: each bit corresponds to an output */ - /* pin with the same order. Port C is different: bits 0...3 correspond to */ - /* bits 4...7 of the output register (PCDR). */ + /* Ports A and B are straight forward: each bit corresponds to an */ + /* output pin with the same order. Port C is different: bits 0...3 */ + /* correspond to bits 4...7 of the output register (PCDR). */ if (data[0]) { @@ -235,7 +238,7 @@ static int dnp_dio_insn_bits(struct comedi_device *dev, | (u8) ((data[1] & 0x0F0000) >> 12), CSCDR); } - /* on return, data[1] contains the value of the digital input lines. */ + /* on return, data[1] contains the value of the digital input lines. */ outb(PADR, CSCIR); data[0] = inb(CSCDR); outb(PBDR, CSCIR); @@ -260,7 +263,8 @@ static int dnp_dio_insn_config(struct comedi_device *dev, u8 register_buffer; - int chan = CR_CHAN(insn->chanspec); /* reduces chanspec to lower 16 bits */ + /* reduces chanspec to lower 16 bits */ + int chan = CR_CHAN(insn->chanspec); switch (data[0]) { case INSN_CONFIG_DIO_OUTPUT: @@ -275,11 +279,11 @@ static int dnp_dio_insn_config(struct comedi_device *dev, return -EINVAL; break; } - /* Test: which port does the channel belong to? */ + /* Test: which port does the channel belong to? */ - /* We have to pay attention with port C: this is the meaning of PCMR: */ - /* Bit in PCMR: 7 6 5 4 3 2 1 0 */ - /* Corresponding port C pin: d 3 d 2 d 1 d 0 d= don't touch */ + /* We have to pay attention with port C: this is the meaning of PCMR: */ + /* Bit in PCMR: 7 6 5 4 3 2 1 0 */ + /* Corresponding port C pin: d 3 d 2 d 1 d 0 d= don't touch */ if ((chan >= 0) && (chan <= 7)) { /* this is port A */ @@ -289,8 +293,8 @@ static int dnp_dio_insn_config(struct comedi_device *dev, chan -= 8; outb(PBMR, CSCIR); } else if ((chan >= 16) && (chan <= 19)) { - /* this is port C; multiplication with 2 brings bits into correct */ - /* position for PCMR! */ + /* this is port C; multiplication with 2 brings bits into */ + /* correct position for PCMR! */ chan -= 16; chan *= 2; outb(PCMR, CSCIR); @@ -298,7 +302,7 @@ static int dnp_dio_insn_config(struct comedi_device *dev, return -EINVAL; } - /* read 'old' direction of the port and set bits (out=1, in=0) */ + /* read 'old' direction of the port and set bits (out=1, in=0) */ register_buffer = inb(CSCDR); if (data[0] == COMEDI_OUTPUT) register_buffer |= (1 << chan); -- cgit v1.2.3 From a2936e0d243d58bbfb3aa048a00ed0bdd2e24307 Mon Sep 17 00:00:00 2001 From: Stewart Robertson Date: Thu, 22 Apr 2010 20:33:48 +0100 Subject: Staging: comedi: add missing KERN_INFO in ni_at_ao.c This is a patch to the ni_at_ao.c file that adds the missing KERN_INFO requested by the checkpatch.pl tool. Signed-off-by: Stewart Robertson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_at_ao.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c index 3778565c1f6b..ce60224bb7bf 100644 --- a/drivers/staging/comedi/drivers/ni_at_ao.c +++ b/drivers/staging/comedi/drivers/ni_at_ao.c @@ -226,7 +226,7 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) iobase = 0x1c0; ao_unipolar = it->options[3]; - printk("comedi%d: ni_at_ao: 0x%04lx", dev->minor, iobase); + printk(KERN_INFO "comedi%d: ni_at_ao: 0x%04lx", dev->minor, iobase); if (!request_region(iobase, ATAO_SIZE, "ni_at_ao")) { printk(" I/O port conflict\n"); @@ -283,14 +283,14 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) atao_reset(dev); - printk("\n"); + printk(KERN_INFO "\n"); return 0; } static int atao_detach(struct comedi_device *dev) { - printk("comedi%d: atao: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: atao: remove\n", dev->minor); if (dev->iobase) release_region(dev->iobase, ATAO_SIZE); -- cgit v1.2.3 From ac4898a0f81d3b3c218cb4d17bac1750ef82e456 Mon Sep 17 00:00:00 2001 From: Zachary Richey Date: Mon, 26 Apr 2010 07:49:37 -0400 Subject: Staging: comedi: fixed coding style issues in drivers.c This patch fixes coding style issues found by checkpatch.pl, and doesnt line break string literals. Signed-off-by: Zachary Richey Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 44d6b62c230d..4b69d06ca735 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -102,7 +102,7 @@ static void __comedi_device_detach(struct comedi_device *dev) if (dev->driver) dev->driver->detach(dev); else - printk("BUG: dev->driver=NULL in comedi_device_detach()\n"); + printk(KERN_WARNING "BUG: dev->driver=NULL in comedi_device_detach()\n"); cleanup_device(dev); } @@ -124,7 +124,7 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) for (driv = comedi_drivers; driv; driv = driv->next) { if (!try_module_get(driv->module)) { printk - ("comedi: failed to increment module count, skipping\n"); + (KERN_INFO "comedi: failed to increment module count, skipping\n"); continue; } if (driv->num_names) { @@ -139,7 +139,8 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) continue; } } - /* initialize dev->driver here so comedi_error() can be called from attach */ + /* initialize dev->driver here so + * comedi_error() can be called from attach */ dev->driver = driv; ret = driv->attach(dev, it); if (ret < 0) { @@ -154,7 +155,7 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* report valid board names before returning error */ for (driv = comedi_drivers; driv; driv = driv->next) { if (!try_module_get(driv->module)) { - printk("comedi: failed to increment module count\n"); + printk(KERN_INFO "comedi: failed to increment module count\n"); continue; } comedi_report_boards(driv); @@ -172,7 +173,7 @@ attached: } if (!dev->board_name) { - printk("BUG: dev->board_name=<%p>\n", dev->board_name); + printk(KERN_WARNING "BUG: dev->board_name=<%p>\n", dev->board_name); dev->board_name = "BUG"; } smp_wmb(); @@ -208,7 +209,7 @@ int comedi_driver_unregister(struct comedi_driver *driver) if (dev->attached && dev->driver == driver) { if (dev->use_count) printk - ("BUG! detaching device with use_count=%d\n", + (KERN_WARNING "BUG! detaching device with use_count=%d\n", dev->use_count); comedi_device_detach(dev); } @@ -253,7 +254,7 @@ static int postconfig(struct comedi_device *dev) async = kzalloc(sizeof(struct comedi_async), GFP_KERNEL); if (async == NULL) { - printk("failed to allocate async struct\n"); + printk(KERN_INFO "failed to allocate async struct\n"); return -ENOMEM; } init_waitqueue_head(&async->wait_head); @@ -268,7 +269,7 @@ static int postconfig(struct comedi_device *dev) async->prealloc_buf = NULL; async->prealloc_bufsz = 0; if (comedi_buf_alloc(dev, s, DEFAULT_BUF_SIZE) < 0) { - printk("Buffer allocation failed\n"); + printk(KERN_INFO "Buffer allocation failed\n"); return -ENOMEM; } if (s->buf_change) { @@ -303,7 +304,8 @@ static int postconfig(struct comedi_device *dev) return 0; } -/* generic recognize function for drivers that register their supported board names */ +/* generic recognize function for drivers + * that register their supported board names */ void *comedi_recognize(struct comedi_driver *driv, const char *name) { unsigned i; @@ -324,17 +326,17 @@ void comedi_report_boards(struct comedi_driver *driv) unsigned int i; const char *const *name_ptr; - printk("comedi: valid board names for %s driver are:\n", + printk(KERN_INFO "comedi: valid board names for %s driver are:\n", driv->driver_name); name_ptr = driv->board_name; for (i = 0; i < driv->num_names; i++) { - printk(" %s\n", *name_ptr); + printk(KERN_INFO " %s\n", *name_ptr); name_ptr = (const char **)((char *)name_ptr + driv->offset); } if (driv->num_names == 0) - printk(" %s\n", driv->driver_name); + printk(KERN_INFO " %s\n", driv->driver_name); } static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s) @@ -568,7 +570,7 @@ unsigned int comedi_buf_munge(struct comedi_async *async, block_size = num_bytes - count; if (block_size < 0) { - printk("%s: %s: bug! block_size is negative\n", + printk(KERN_WARNING "%s: %s: bug! block_size is negative\n", __FILE__, __func__); break; } @@ -579,7 +581,8 @@ unsigned int comedi_buf_munge(struct comedi_async *async, s->munge(s->device, s, async->prealloc_buf + async->munge_ptr, block_size, async->munge_chan); - smp_wmb(); /* barrier insures data is munged in buffer before munge_count is incremented */ + smp_wmb(); /* barrier insures data is munged in buffer + * before munge_count is incremented */ async->munge_chan += block_size / num_sample_bytes; async->munge_chan %= async->cmd.chanlist_len; @@ -649,7 +652,7 @@ unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes) if ((int)(async->buf_write_count + nbytes - async->buf_write_alloc_count) > 0) { printk - ("comedi: attempted to write-free more bytes than have been write-allocated.\n"); + (KERN_INFO "comedi: attempted to write-free more bytes than have been write-allocated.\n"); nbytes = async->buf_write_alloc_count - async->buf_write_count; } async->buf_write_count += nbytes; @@ -678,7 +681,8 @@ unsigned comedi_buf_read_alloc(struct comedi_async *async, unsigned nbytes) /* transfers control of a chunk from reader to free buffer space */ unsigned comedi_buf_read_free(struct comedi_async *async, unsigned int nbytes) { - /* barrier insures data has been read out of buffer before read count is incremented */ + /* barrier insures data has been read out of + * buffer before read count is incremented */ smp_mb(); if ((int)(async->buf_read_count + nbytes - async->buf_read_alloc_count) > 0) { -- cgit v1.2.3 From 04607c9e6573451bd994e21699c82190dd9b4530 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Thu, 8 Apr 2010 19:49:45 +0800 Subject: Staging: rtl8192u: remove unused #include Remove unused #include ('s) in drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c Signed-off-by: Huang Weiyi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c index 750e94e17114..4d5348e6c104 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c @@ -30,7 +30,6 @@ ******************************************************************************/ #include -#include #include #include #include -- cgit v1.2.3 From b6595dd110a033f9c8fba0d01fd366d95120b997 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Thu, 8 Apr 2010 19:49:36 +0800 Subject: Staging: crystalhd: remove unused #include Remove unused #include ('s) in drivers/staging/crystalhd/crystalhd_lnx.c Signed-off-by: Huang Weiyi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/crystalhd/crystalhd_lnx.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c index 6090a1d59549..141a3e38a835 100644 --- a/drivers/staging/crystalhd/crystalhd_lnx.c +++ b/drivers/staging/crystalhd/crystalhd_lnx.c @@ -15,7 +15,6 @@ along with this driver. If not, see . ***************************************************************************/ -#include #include #include -- cgit v1.2.3 From 484d3be1bded596a404ac99401652c7728be2f24 Mon Sep 17 00:00:00 2001 From: Gorskin Ilya Date: Sun, 14 Mar 2010 00:35:17 +0500 Subject: Staging: dt3155: fix coding style issue in dt3155_isr.c This is a patch to the dt3155_isr.c file that fixes up a coding style warning and errors found by the checkpatch.pl tool Signed-off-by: Gorskin Ilya Acked-by: Simon Horman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dt3155/dt3155_isr.c | 295 ++++++++++++++++++------------------ 1 file changed, 144 insertions(+), 151 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dt3155/dt3155_isr.c b/drivers/staging/dt3155/dt3155_isr.c index 09d7d9b8272d..1ebcec0c3091 100644 --- a/drivers/staging/dt3155/dt3155_isr.c +++ b/drivers/staging/dt3155/dt3155_isr.c @@ -1,7 +1,7 @@ /* Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, - Jason Lapenta, Scott Smedley, Greg Sharp + Jason Lapenta, Scott Smedley, Greg Sharp This file is part of the DT3155 Device Driver. @@ -22,7 +22,7 @@ MA 02111-1307 USA File: dt3155_isr.c Purpose: Buffer management routines, and other routines for the ISR - (the actual isr is in dt3155_drv.c) + (the actual isr is in dt3155_drv.c) -- Changes -- @@ -30,16 +30,16 @@ Purpose: Buffer management routines, and other routines for the ISR ------------------------------------------------------------------- 03-Jul-2000 JML n/a 02-Apr-2002 SS Mods to make work with separate allocator - module; Merged John Roll's mods to make work with - multiple boards. + module; Merged John Roll's mods to make work with + multiple boards. 10-Jul-2002 GCS Complete rewrite of setup_buffers to disallow - buffers which span a 4MB boundary. + buffers which span a 4MB boundary. 24-Jul-2002 SS GPL licence. 30-Jul-2002 NJC Added support for buffer loop. 31-Jul-2002 NJC Complete rewrite of buffer management 02-Aug-2002 NJC Including slab.h instead of malloc.h (no warning). - Also, allocator_init() now returns allocator_max - so cleaned up allocate_buffers() accordingly. + Also, allocator_init() now returns allocator_max + so cleaned up allocate_buffers() accordingly. 08-Aug-2005 SS port to 2.6 kernel. */ @@ -77,9 +77,9 @@ struct dt3155_fbuffer_s *dt3155_fbuffer[MAXBOARDS] = {NULL * are_empty_buffers * m is minor # of device ***************************/ -inline bool are_empty_buffers( int m ) +inline bool are_empty_buffers(int m) { - return ( dt3155_fbuffer[ m ]->empty_len ); + return dt3155_fbuffer[m]->empty_len; } /************************** @@ -92,56 +92,56 @@ inline bool are_empty_buffers( int m ) * given by dt3155_fbuffer[m]->empty_buffers[0]. * empty_buffers should never fill up, though this is not checked. **************************/ -inline void push_empty( int index, int m ) +inline void push_empty(int index, int m) { - dt3155_fbuffer[m]->empty_buffers[ dt3155_fbuffer[m]->empty_len ] = index; + dt3155_fbuffer[m]->empty_buffers[dt3155_fbuffer[m]->empty_len] = index; dt3155_fbuffer[m]->empty_len++; } /************************** - * pop_empty( m ) + * pop_empty(m) * m is minor # of device **************************/ -inline int pop_empty( int m ) +inline int pop_empty(int m) { dt3155_fbuffer[m]->empty_len--; - return dt3155_fbuffer[m]->empty_buffers[ dt3155_fbuffer[m]->empty_len ]; + return dt3155_fbuffer[m]->empty_buffers[dt3155_fbuffer[m]->empty_len]; } /************************* - * is_ready_buf_empty( m ) + * is_ready_buf_empty(m) * m is minor # of device *************************/ -inline bool is_ready_buf_empty( int m ) +inline bool is_ready_buf_empty(int m) { - return ((dt3155_fbuffer[ m ]->ready_len) == 0); + return ((dt3155_fbuffer[m]->ready_len) == 0); } /************************* - * is_ready_buf_full( m ) + * is_ready_buf_full(m) * m is minor # of device * this should *never* be true if there are any active, locked or empty * buffers, since it corresponds to nbuffers ready buffers!! * 7/31/02: total rewrite. --NJC *************************/ -inline bool is_ready_buf_full( int m ) +inline bool is_ready_buf_full(int m) { - return ( dt3155_fbuffer[ m ]->ready_len == dt3155_fbuffer[ m ]->nbuffers ); + return dt3155_fbuffer[m]->ready_len == dt3155_fbuffer[m]->nbuffers; } /***************************************************** - * push_ready( m, buffer ) + * push_ready(m, buffer) * m is minor # of device * *****************************************************/ -inline void push_ready( int m, int index ) +inline void push_ready(int m, int index) { int head = dt3155_fbuffer[m]->ready_head; - dt3155_fbuffer[ m ]->ready_que[ head ] = index; - dt3155_fbuffer[ m ]->ready_head = ( (head + 1) % - (dt3155_fbuffer[ m ]->nbuffers) ); - dt3155_fbuffer[ m ]->ready_len++; + dt3155_fbuffer[m]->ready_que[head] = index; + dt3155_fbuffer[m]->ready_head = ((head + 1) % + (dt3155_fbuffer[m]->nbuffers)); + dt3155_fbuffer[m]->ready_len++; } @@ -151,12 +151,12 @@ inline void push_ready( int m, int index ) * * Simply comptutes the tail given the head and the length. *****************************************************/ -static inline int get_tail( int m ) +static inline int get_tail(int m) { - return ((dt3155_fbuffer[ m ]->ready_head - - dt3155_fbuffer[ m ]->ready_len + - dt3155_fbuffer[ m ]->nbuffers)% - (dt3155_fbuffer[ m ]->nbuffers)); + return (dt3155_fbuffer[m]->ready_head - + dt3155_fbuffer[m]->ready_len + + dt3155_fbuffer[m]->nbuffers)% + (dt3155_fbuffer[m]->nbuffers); } @@ -168,12 +168,12 @@ static inline int get_tail( int m ) * This assumes that there is a ready buffer ready... should * be checked (e.g. with is_ready_buf_empty() prior to call. *****************************************************/ -inline int pop_ready( int m ) +inline int pop_ready(int m) { int tail; tail = get_tail(m); - dt3155_fbuffer[ m ]->ready_len--; - return dt3155_fbuffer[ m ]->ready_que[ tail ]; + dt3155_fbuffer[m]->ready_len--; + return dt3155_fbuffer[m]->ready_que[tail]; } @@ -181,35 +181,33 @@ inline int pop_ready( int m ) * printques * m is minor # of device *****************************************************/ -inline void printques( int m ) +inline void printques(int m) { - int head = dt3155_fbuffer[ m ]->ready_head; + int head = dt3155_fbuffer[m]->ready_head; int tail; - int num = dt3155_fbuffer[ m ]->nbuffers; + int num = dt3155_fbuffer[m]->nbuffers; int frame_index; int index; tail = get_tail(m); printk("\n R:"); - for ( index = tail; index != head; index++, index = index % (num) ) - { - frame_index = dt3155_fbuffer[ m ]->ready_que[ index ]; - printk(" %d ", frame_index ); + for (index = tail; index != head; index++, index = index % (num)) { + frame_index = dt3155_fbuffer[m]->ready_que[index]; + printk(" %d ", frame_index); } printk("\n E:"); - for ( index = 0; index < dt3155_fbuffer[ m ]->empty_len; index++ ) - { - frame_index = dt3155_fbuffer[ m ]->empty_buffers[ index ]; - printk(" %d ", frame_index ); + for (index = 0; index < dt3155_fbuffer[m]->empty_len; index++) { + frame_index = dt3155_fbuffer[m]->empty_buffers[index]; + printk(" %d ", frame_index); } - frame_index = dt3155_fbuffer[ m ]->active_buf; + frame_index = dt3155_fbuffer[m]->active_buf; printk("\n A: %d", frame_index); - frame_index = dt3155_fbuffer[ m ]->locked_buf; - printk("\n L: %d \n", frame_index ); + frame_index = dt3155_fbuffer[m]->locked_buf; + printk("\n L: %d\n", frame_index); } @@ -220,11 +218,12 @@ inline void printques( int m ) * the start address up to the beginning of the * next 4MB chunk (assuming bufsize < 4MB). *****************************************************/ -u32 adjust_4MB (u32 buf_addr, u32 bufsize) { - if (((buf_addr+bufsize) & UPPER_10_BITS) != (buf_addr & UPPER_10_BITS)) - return (buf_addr+bufsize) & UPPER_10_BITS; - else - return buf_addr; +u32 adjust_4MB(u32 buf_addr, u32 bufsize) +{ + if (((buf_addr+bufsize) & UPPER_10_BITS) != (buf_addr & UPPER_10_BITS)) + return (buf_addr+bufsize) & UPPER_10_BITS; + else + return buf_addr; } @@ -235,7 +234,7 @@ u32 adjust_4MB (u32 buf_addr, u32 bufsize) { * buffers. If there is not enough free space * try for less memory. *****************************************************/ -void allocate_buffers (u32 *buf_addr, u32* total_size_kbs, +void allocate_buffers(u32 *buf_addr, u32* total_size_kbs, u32 bufsize) { /* Compute the minimum amount of memory guaranteed to hold all @@ -268,15 +267,15 @@ void allocate_buffers (u32 *buf_addr, u32* total_size_kbs, printk("DT3155: ...but need at least: %d KB\n", min_size_kbs); printk("DT3155: ...the allocator has: %d KB\n", allocator_max); size_kbs = (full_size_kbs <= allocator_max ? full_size_kbs : allocator_max); - if (size_kbs > min_size_kbs) { - if ((*buf_addr = allocator_allocate_dma (size_kbs, GFP_KERNEL)) != 0) { - printk("DT3155: Managed to allocate: %d KB\n", size_kbs); - *total_size_kbs = size_kbs; - return; + if (size_kbs > min_size_kbs) { + if ((*buf_addr = allocator_allocate_dma(size_kbs, GFP_KERNEL)) != 0) { + printk("DT3155: Managed to allocate: %d KB\n", size_kbs); + *total_size_kbs = size_kbs; + return; + } } - } /* If we got here, the allocation failed */ - printk ("DT3155: Allocator failed!\n"); + printk("DT3155: Allocator failed!\n"); *buf_addr = 0; *total_size_kbs = 0; return; @@ -312,28 +311,26 @@ u32 dt3155_setup_buffers(u32 *allocatorAddr) int m; /* minor # of device, looped for all devs */ /* zero the fbuffer status and address structure */ - for ( m = 0; m < ndevices; m++) - { - dt3155_fbuffer[ m ] = &(dt3155_status[ m ].fbuffer); + for (m = 0; m < ndevices; m++) { + dt3155_fbuffer[m] = &(dt3155_status[m].fbuffer); /* Make sure the buffering variables are consistent */ { - u8 *ptr = (u8 *) dt3155_fbuffer[ m ]; - for( index = 0; index < sizeof(struct dt3155_fbuffer_s); index++) - *(ptr++)=0; + u8 *ptr = (u8 *) dt3155_fbuffer[m]; + for (index = 0; index < sizeof(struct dt3155_fbuffer_s); index++) + *(ptr++) = 0; } } /* allocate a large contiguous chunk of RAM */ - allocate_buffers (&rambuff_addr, &rambuff_size, bufsize); + allocate_buffers(&rambuff_addr, &rambuff_size, bufsize); printk("DT3155: mem info\n"); - printk(" - rambuf_addr = 0x%x \n", rambuff_addr); - printk(" - length (kb) = %u \n", rambuff_size); - if( rambuff_addr == 0 ) - { - printk( KERN_INFO - "DT3155: Error setup_buffers() allocator dma failed \n" ); - return -ENOMEM; + printk(" - rambuf_addr = 0x%x\n", rambuff_addr); + printk(" - length (kb) = %u\n", rambuff_size); + if (rambuff_addr == 0) { + printk(KERN_INFO + "DT3155: Error setup_buffers() allocator dma failed\n"); + return -ENOMEM; } *allocatorAddr = rambuff_addr; rambuff_end = rambuff_addr + 1024 * rambuff_size; @@ -341,70 +338,68 @@ u32 dt3155_setup_buffers(u32 *allocatorAddr) /* after allocation, we need to count how many useful buffers there are so we can give an equal number to each device */ rambuff_acm = rambuff_addr; - for ( index = 0; index < MAXBUFFERS; index++) { - rambuff_acm = adjust_4MB (rambuff_acm, bufsize);/*avoid spanning 4MB bdry*/ - if (rambuff_acm + bufsize > rambuff_end) - break; - rambuff_acm += bufsize; - } + for (index = 0; index < MAXBUFFERS; index++) { + rambuff_acm = adjust_4MB(rambuff_acm, bufsize);/*avoid spanning 4MB bdry*/ + if (rambuff_acm + bufsize > rambuff_end) + break; + rambuff_acm += bufsize; + } /* Following line is OK, will waste buffers if index * not evenly divisible by ndevices -NJC*/ numbufs = index / ndevices; printk(" - numbufs = %u\n", numbufs); - if (numbufs < 2) { - printk( KERN_INFO - "DT3155: Error setup_buffers() couldn't allocate 2 bufs/board\n" ); - return -ENOMEM; - } + if (numbufs < 2) { + printk(KERN_INFO + "DT3155: Error setup_buffers() couldn't allocate 2 bufs/board\n"); + return -ENOMEM; + } /* now that we have board memory we spit it up */ /* between the boards and the buffers */ - rambuff_acm = rambuff_addr; - for ( m = 0; m < ndevices; m ++) - { - rambuff_acm = adjust_4MB (rambuff_acm, bufsize); - - /* Save the start of this boards buffer space (for mmap). */ - dt3155_status[ m ].mem_addr = rambuff_acm; - - for (index = 0; index < numbufs; index++) - { - rambuff_acm = adjust_4MB (rambuff_acm, bufsize); - if (rambuff_acm + bufsize > rambuff_end) { - /* Should never happen */ - printk ("DT3155 PROGRAM ERROR (GCS)\n" - "Error distributing allocated buffers\n"); - return -ENOMEM; - } - - dt3155_fbuffer[ m ]->frame_info[ index ].addr = rambuff_acm; - push_empty( index, m ); - /* printk(" - Buffer : %lx\n", - * dt3155_fbuffer[ m ]->frame_info[ index ].addr ); - */ - dt3155_fbuffer[ m ]->nbuffers += 1; - rambuff_acm += bufsize; + rambuff_acm = rambuff_addr; + for (m = 0; m < ndevices; m++) { + rambuff_acm = adjust_4MB(rambuff_acm, bufsize); + + /* Save the start of this boards buffer space (for mmap). */ + dt3155_status[m].mem_addr = rambuff_acm; + + for (index = 0; index < numbufs; index++) { + rambuff_acm = adjust_4MB(rambuff_acm, bufsize); + if (rambuff_acm + bufsize > rambuff_end) { + /* Should never happen */ + printk("DT3155 PROGRAM ERROR (GCS)\n" + "Error distributing allocated buffers\n"); + return -ENOMEM; + } + + dt3155_fbuffer[m]->frame_info[index].addr = rambuff_acm; + push_empty(index, m); + /* printk(" - Buffer : %lx\n", + * dt3155_fbuffer[m]->frame_info[index].addr); + */ + dt3155_fbuffer[m]->nbuffers += 1; + rambuff_acm += bufsize; } - /* Make sure there is an active buffer there. */ - dt3155_fbuffer[ m ]->active_buf = pop_empty( m ); - dt3155_fbuffer[ m ]->even_happened = 0; - dt3155_fbuffer[ m ]->even_stopped = 0; + /* Make sure there is an active buffer there. */ + dt3155_fbuffer[m]->active_buf = pop_empty(m); + dt3155_fbuffer[m]->even_happened = 0; + dt3155_fbuffer[m]->even_stopped = 0; - /* make sure there is no locked_buf JML 2/28/00 */ - dt3155_fbuffer[ m ]->locked_buf = -1; + /* make sure there is no locked_buf JML 2/28/00 */ + dt3155_fbuffer[m]->locked_buf = -1; - dt3155_status[ m ].mem_size = - rambuff_acm - dt3155_status[ m ].mem_addr; + dt3155_status[m].mem_size = + rambuff_acm - dt3155_status[m].mem_addr; - /* setup the ready queue */ - dt3155_fbuffer[ m ]->ready_head = 0; - dt3155_fbuffer[ m ]->ready_len = 0; - printk("Available buffers for device %d: %d\n", - m, dt3155_fbuffer[ m ]->nbuffers); + /* setup the ready queue */ + dt3155_fbuffer[m]->ready_head = 0; + dt3155_fbuffer[m]->ready_len = 0; + printk("Available buffers for device %d: %d\n", + m, dt3155_fbuffer[m]->nbuffers); } - return 1; + return 1; } /***************************************************** @@ -415,13 +410,12 @@ u32 dt3155_setup_buffers(u32 *allocatorAddr) * * m is minor number of device *****************************************************/ -static inline void internal_release_locked_buffer( int m ) +static inline void internal_release_locked_buffer(int m) { /* Pointer into global structure for handling buffers */ - if ( dt3155_fbuffer[ m ]->locked_buf >= 0 ) - { - push_empty( dt3155_fbuffer[ m ]->locked_buf, m ); - dt3155_fbuffer[ m ]->locked_buf = -1; + if (dt3155_fbuffer[m]->locked_buf >= 0) { + push_empty(dt3155_fbuffer[m]->locked_buf, m); + dt3155_fbuffer[m]->locked_buf = -1; } } @@ -433,7 +427,7 @@ static inline void internal_release_locked_buffer( int m ) * The user function of the above. * *****************************************************/ -inline void dt3155_release_locked_buffer( int m ) +inline void dt3155_release_locked_buffer(int m) { unsigned long int flags; local_save_flags(flags); @@ -448,28 +442,28 @@ inline void dt3155_release_locked_buffer( int m ) * m is minor # of device * *****************************************************/ -inline int dt3155_flush( int m ) +inline int dt3155_flush(int m) { int index; unsigned long int flags; local_save_flags(flags); local_irq_disable(); - internal_release_locked_buffer( m ); - dt3155_fbuffer[ m ]->empty_len = 0; + internal_release_locked_buffer(m); + dt3155_fbuffer[m]->empty_len = 0; - for ( index = 0; index < dt3155_fbuffer[ m ]->nbuffers; index++ ) - push_empty( index, m ); + for (index = 0; index < dt3155_fbuffer[m]->nbuffers; index++) + push_empty(index, m); /* Make sure there is an active buffer there. */ - dt3155_fbuffer[ m ]->active_buf = pop_empty( m ); + dt3155_fbuffer[m]->active_buf = pop_empty(m); - dt3155_fbuffer[ m ]->even_happened = 0; - dt3155_fbuffer[ m ]->even_stopped = 0; + dt3155_fbuffer[m]->even_happened = 0; + dt3155_fbuffer[m]->even_stopped = 0; /* setup the ready queue */ - dt3155_fbuffer[ m ]->ready_head = 0; - dt3155_fbuffer[ m ]->ready_len = 0; + dt3155_fbuffer[m]->ready_head = 0; + dt3155_fbuffer[m]->ready_len = 0; local_irq_restore(flags); @@ -485,7 +479,7 @@ inline int dt3155_flush( int m ) * If the user has a buffer locked it will unlock * that buffer before returning the new one. *****************************************************/ -inline int dt3155_get_ready_buffer( int m ) +inline int dt3155_get_ready_buffer(int m) { int frame_index; unsigned long int flags; @@ -493,21 +487,20 @@ inline int dt3155_get_ready_buffer( int m ) local_irq_disable(); #ifdef DEBUG_QUES_A - printques( m ); + printques(m); #endif - internal_release_locked_buffer( m ); + internal_release_locked_buffer(m); - if (is_ready_buf_empty( m )) - frame_index = -1; - else - { - frame_index = pop_ready( m ); - dt3155_fbuffer[ m ]->locked_buf = frame_index; + if (is_ready_buf_empty(m)) + frame_index = -1; + else { + frame_index = pop_ready(m); + dt3155_fbuffer[m]->locked_buf = frame_index; } #ifdef DEBUG_QUES_B - printques( m ); + printques(m); #endif local_irq_restore(flags); -- cgit v1.2.3 From d241fd58e407cd3943cabd61217a0ae32c795c1d Mon Sep 17 00:00:00 2001 From: Jason Baldus Date: Sun, 28 Mar 2010 09:59:37 -0400 Subject: Staging: dt3155: fix parentheses and bracket spacing style issues This is a patch to the dt3155_drv.c file that removes spaces after open parentheses and brackets and before close parentheses and brackets. Signed-off-by: Jason Baldus Reviewed-by: Simon Horman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dt3155/dt3155_drv.c | 338 ++++++++++++++++++------------------ 1 file changed, 169 insertions(+), 169 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dt3155/dt3155_drv.c b/drivers/staging/dt3155/dt3155_drv.c index 7e6095f43f16..91ebfadba9a7 100644 --- a/drivers/staging/dt3155/dt3155_drv.c +++ b/drivers/staging/dt3155/dt3155_drv.c @@ -95,7 +95,7 @@ int dt3155_errno = 0; #endif /* wait queue for interrupts */ -wait_queue_head_t dt3155_read_wait_queue[ MAXBOARDS ]; +wait_queue_head_t dt3155_read_wait_queue[MAXBOARDS]; #define DT_3155_SUCCESS 0 #define DT_3155_FAILURE -EIO @@ -112,10 +112,10 @@ int dt3155_major = 0; /* Global structures and variables */ /* Status of each device */ -struct dt3155_status_s dt3155_status[ MAXBOARDS ]; +struct dt3155_status_s dt3155_status[MAXBOARDS]; /* kernel logical address of the board */ -u8 *dt3155_lbase[ MAXBOARDS ] = { NULL +u8 *dt3155_lbase[MAXBOARDS] = { NULL #if MAXBOARDS == 2 , NULL #endif @@ -123,7 +123,7 @@ u8 *dt3155_lbase[ MAXBOARDS ] = { NULL /* DT3155 registers */ u8 *dt3155_bbase = NULL; /* kernel logical address of the * * buffer region */ -u32 dt3155_dev_open[ MAXBOARDS ] = {0 +u32 dt3155_dev_open[MAXBOARDS] = {0 #if MAXBOARDS == 2 , 0 #endif @@ -142,17 +142,17 @@ static void quick_stop (int minor) { // TODO: scott was here #if 1 - ReadMReg((dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg); + ReadMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg); /* disable interrupts */ int_csr_r.fld.FLD_END_EVE_EN = 0; int_csr_r.fld.FLD_END_ODD_EN = 0; - WriteMReg((dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg ); + WriteMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg); - dt3155_status[ minor ].state &= ~(DT3155_STATE_STOP|0xff); + dt3155_status[minor].state &= ~(DT3155_STATE_STOP|0xff); /* mark the system stopped: */ - dt3155_status[ minor ].state |= DT3155_STATE_IDLE; - dt3155_fbuffer[ minor ]->stop_acquire = 0; - dt3155_fbuffer[ minor ]->even_stopped = 0; + dt3155_status[minor].state |= DT3155_STATE_IDLE; + dt3155_fbuffer[minor]->stop_acquire = 0; + dt3155_fbuffer[minor]->even_stopped = 0; #else dt3155_status[minor].state |= DT3155_STATE_STOP; dt3155_status[minor].fbuffer.stop_acquire = 1; @@ -168,7 +168,7 @@ static void quick_stop (int minor) * - Assumes irq's are disabled, via SA_INTERRUPT flag * being set in request_irq() call from init_module() *****************************************************/ -static inline void dt3155_isr( int irq, void *dev_id, struct pt_regs *regs ) +static inline void dt3155_isr(int irq, void *dev_id, struct pt_regs *regs) { int minor = -1; int index; @@ -176,8 +176,8 @@ static inline void dt3155_isr( int irq, void *dev_id, struct pt_regs *regs ) u32 buffer_addr; /* find out who issued the interrupt */ - for ( index = 0; index < ndevices; index++ ) { - if( dev_id == (void*) &dt3155_status[ index ]) + for (index = 0; index < ndevices; index++) { + if(dev_id == (void*) &dt3155_status[index]) { minor = index; break; @@ -185,15 +185,15 @@ static inline void dt3155_isr( int irq, void *dev_id, struct pt_regs *regs ) } /* hopefully we should not get here */ - if ( minor < 0 || minor >= MAXBOARDS ) { + if (minor < 0 || minor >= MAXBOARDS) { printk(KERN_ERR "dt3155_isr called with invalid dev_id\n"); return; } /* Check for corruption and set a flag if so */ - ReadMReg( (dt3155_lbase[ minor ] + CSR1), csr1_r.reg ); + ReadMReg((dt3155_lbase[minor] + CSR1), csr1_r.reg); - if ( (csr1_r.fld.FLD_CRPT_EVE) || (csr1_r.fld.FLD_CRPT_ODD) ) + if ((csr1_r.fld.FLD_CRPT_EVE) || (csr1_r.fld.FLD_CRPT_ODD)) { /* TODO: this should probably stop acquisition */ /* and set some flags so that dt3155_read */ @@ -203,27 +203,27 @@ static inline void dt3155_isr( int irq, void *dev_id, struct pt_regs *regs ) return; } - ReadMReg((dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg); + ReadMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg); /* Handle the even field ... */ if (int_csr_r.fld.FLD_END_EVE) { - if ( (dt3155_status[ minor ].state & DT3155_STATE_MODE) == - DT3155_STATE_FLD ) + if ((dt3155_status[minor].state & DT3155_STATE_MODE) == + DT3155_STATE_FLD) { - dt3155_fbuffer[ minor ]->frame_count++; + dt3155_fbuffer[minor]->frame_count++; } - ReadI2C(dt3155_lbase[ minor ], EVEN_CSR, &i2c_even_csr.reg); + ReadI2C(dt3155_lbase[minor], EVEN_CSR, &i2c_even_csr.reg); /* Clear the interrupt? */ int_csr_r.fld.FLD_END_EVE = 1; /* disable the interrupt if last field */ - if (dt3155_fbuffer[ minor ]->stop_acquire) + if (dt3155_fbuffer[minor]->stop_acquire) { printk("dt3155: even stopped.\n"); - dt3155_fbuffer[ minor ]->even_stopped = 1; + dt3155_fbuffer[minor]->even_stopped = 1; if (i2c_even_csr.fld.SNGL_EVE) { int_csr_r.fld.FLD_END_EVE_EN = 0; @@ -234,75 +234,75 @@ static inline void dt3155_isr( int irq, void *dev_id, struct pt_regs *regs ) } } - WriteMReg( (dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg ); + WriteMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg); /* Set up next DMA if we are doing FIELDS */ - if ( (dt3155_status[ minor ].state & DT3155_STATE_MODE ) == + if ((dt3155_status[minor].state & DT3155_STATE_MODE) == DT3155_STATE_FLD) { /* GCS (Aug 2, 2002) -- In field mode, dma the odd field into the lower half of the buffer */ - const u32 stride = dt3155_status[ minor ].config.cols; - buffer_addr = dt3155_fbuffer[ minor ]-> - frame_info[ dt3155_fbuffer[ minor ]->active_buf ].addr + const u32 stride = dt3155_status[minor].config.cols; + buffer_addr = dt3155_fbuffer[minor]-> + frame_info[dt3155_fbuffer[minor]->active_buf].addr + (DT3155_MAX_ROWS / 2) * stride; local_save_flags(flags); local_irq_disable(); - wake_up_interruptible( &dt3155_read_wait_queue[ minor ] ); + wake_up_interruptible(&dt3155_read_wait_queue[minor]); /* Set up the DMA address for the next field */ local_irq_restore(flags); - WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_START), buffer_addr); + WriteMReg((dt3155_lbase[minor] + ODD_DMA_START), buffer_addr); } /* Check for errors. */ i2c_even_csr.fld.DONE_EVE = 1; - if ( i2c_even_csr.fld.ERROR_EVE ) + if (i2c_even_csr.fld.ERROR_EVE) dt3155_errno = DT_ERR_OVERRUN; - WriteI2C( dt3155_lbase[ minor ], EVEN_CSR, i2c_even_csr.reg ); + WriteI2C(dt3155_lbase[minor], EVEN_CSR, i2c_even_csr.reg); /* Note that we actually saw an even field meaning */ /* that subsequent odd field complete the frame */ - dt3155_fbuffer[ minor ]->even_happened = 1; + dt3155_fbuffer[minor]->even_happened = 1; /* recording the time that the even field finished, this should be */ /* about time in the middle of the frame */ - do_gettimeofday( &(dt3155_fbuffer[ minor ]-> - frame_info[ dt3155_fbuffer[ minor ]-> - active_buf ].time) ); + do_gettimeofday(&(dt3155_fbuffer[minor]-> + frame_info[dt3155_fbuffer[minor]-> + active_buf].time)); return; } /* ... now handle the odd field */ - if ( int_csr_r.fld.FLD_END_ODD ) + if (int_csr_r.fld.FLD_END_ODD) { - ReadI2C( dt3155_lbase[ minor ], ODD_CSR, &i2c_odd_csr.reg ); + ReadI2C(dt3155_lbase[minor], ODD_CSR, &i2c_odd_csr.reg); /* Clear the interrupt? */ int_csr_r.fld.FLD_END_ODD = 1; - if (dt3155_fbuffer[ minor ]->even_happened || - (dt3155_status[ minor ].state & DT3155_STATE_MODE) == + if (dt3155_fbuffer[minor]->even_happened || + (dt3155_status[minor].state & DT3155_STATE_MODE) == DT3155_STATE_FLD) { - dt3155_fbuffer[ minor ]->frame_count++; + dt3155_fbuffer[minor]->frame_count++; } - if ( dt3155_fbuffer[ minor ]->stop_acquire && - dt3155_fbuffer[ minor ]->even_stopped ) + if (dt3155_fbuffer[minor]->stop_acquire && + dt3155_fbuffer[minor]->even_stopped) { printk(KERN_DEBUG "dt3155: stopping odd..\n"); - if ( i2c_odd_csr.fld.SNGL_ODD ) + if (i2c_odd_csr.fld.SNGL_ODD) { /* disable interrupts */ int_csr_r.fld.FLD_END_ODD_EN = 0; - dt3155_status[ minor ].state &= ~(DT3155_STATE_STOP|0xff); + dt3155_status[minor].state &= ~(DT3155_STATE_STOP|0xff); /* mark the system stopped: */ - dt3155_status[ minor ].state |= DT3155_STATE_IDLE; - dt3155_fbuffer[ minor ]->stop_acquire = 0; - dt3155_fbuffer[ minor ]->even_stopped = 0; + dt3155_status[minor].state |= DT3155_STATE_IDLE; + dt3155_fbuffer[minor]->stop_acquire = 0; + dt3155_fbuffer[minor]->even_stopped = 0; printk(KERN_DEBUG "dt3155: state is now %x\n", dt3155_status[minor].state); @@ -313,104 +313,104 @@ static inline void dt3155_isr( int irq, void *dev_id, struct pt_regs *regs ) } } - WriteMReg( (dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg ); + WriteMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg); /* if the odd field has been acquired, then */ /* change the next dma location for both fields */ /* and wake up the process if sleeping */ - if ( dt3155_fbuffer[ minor ]->even_happened || - (dt3155_status[ minor ].state & DT3155_STATE_MODE) == - DT3155_STATE_FLD ) + if (dt3155_fbuffer[minor]->even_happened || + (dt3155_status[minor].state & DT3155_STATE_MODE) == + DT3155_STATE_FLD) { local_save_flags(flags); local_irq_disable(); #ifdef DEBUG_QUES_B - printques( minor ); + printques(minor); #endif - if ( dt3155_fbuffer[ minor ]->nbuffers > 2 ) + if (dt3155_fbuffer[minor]->nbuffers > 2) { - if ( !are_empty_buffers( minor ) ) + if (!are_empty_buffers(minor)) { /* The number of active + locked buffers is * at most 2, and since there are none empty, there * must be at least nbuffers-2 ready buffers. * This is where we 'drop frames', oldest first. */ - push_empty( pop_ready( minor ), minor ); + push_empty(pop_ready(minor), minor); } /* The ready_que can't be full, since we know * there is one active buffer right now, so it's safe * to push the active buf on the ready_que. */ - push_ready( minor, dt3155_fbuffer[ minor ]->active_buf ); + push_ready(minor, dt3155_fbuffer[minor]->active_buf); /* There's at least 1 empty -- make it active */ - dt3155_fbuffer[ minor ]->active_buf = pop_empty( minor ); - dt3155_fbuffer[ minor ]-> - frame_info[ dt3155_fbuffer[ minor ]-> - active_buf ].tag = ++unique_tag; + dt3155_fbuffer[minor]->active_buf = pop_empty(minor); + dt3155_fbuffer[minor]-> + frame_info[dt3155_fbuffer[minor]-> + active_buf].tag = ++unique_tag; } else /* nbuffers == 2, special case */ { /* There is 1 active buffer. * If there is a locked buffer, keep the active buffer * the same -- that means we drop a frame. */ - if ( dt3155_fbuffer[ minor ]->locked_buf < 0 ) + if (dt3155_fbuffer[minor]->locked_buf < 0) { - push_ready( minor, - dt3155_fbuffer[ minor ]->active_buf ); - if (are_empty_buffers( minor ) ) + push_ready(minor, + dt3155_fbuffer[minor]->active_buf); + if (are_empty_buffers(minor)) { - dt3155_fbuffer[ minor ]->active_buf = - pop_empty( minor ); + dt3155_fbuffer[minor]->active_buf = + pop_empty(minor); } else { /* no empty or locked buffers, so use a readybuf */ - dt3155_fbuffer[ minor ]->active_buf = - pop_ready( minor ); + dt3155_fbuffer[minor]->active_buf = + pop_ready(minor); } } } #ifdef DEBUG_QUES_B - printques( minor ); + printques(minor); #endif - dt3155_fbuffer[ minor ]->even_happened = 0; + dt3155_fbuffer[minor]->even_happened = 0; - wake_up_interruptible( &dt3155_read_wait_queue[ minor ] ); + wake_up_interruptible(&dt3155_read_wait_queue[minor]); local_irq_restore(flags); } /* Set up the DMA address for the next frame/field */ - buffer_addr = dt3155_fbuffer[ minor ]-> - frame_info[ dt3155_fbuffer[ minor ]->active_buf ].addr; - if ( (dt3155_status[ minor ].state & DT3155_STATE_MODE) == - DT3155_STATE_FLD ) + buffer_addr = dt3155_fbuffer[minor]-> + frame_info[dt3155_fbuffer[minor]->active_buf].addr; + if ((dt3155_status[minor].state & DT3155_STATE_MODE) == + DT3155_STATE_FLD) { - WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_START), buffer_addr); + WriteMReg((dt3155_lbase[minor] + EVEN_DMA_START), buffer_addr); } else { - WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_START), buffer_addr); + WriteMReg((dt3155_lbase[minor] + EVEN_DMA_START), buffer_addr); - WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_START), buffer_addr - + dt3155_status[ minor ].config.cols); + WriteMReg((dt3155_lbase[minor] + ODD_DMA_START), buffer_addr + + dt3155_status[minor].config.cols); } /* Do error checking */ i2c_odd_csr.fld.DONE_ODD = 1; - if ( i2c_odd_csr.fld.ERROR_ODD ) + if (i2c_odd_csr.fld.ERROR_ODD) dt3155_errno = DT_ERR_OVERRUN; - WriteI2C(dt3155_lbase[ minor ], ODD_CSR, i2c_odd_csr.reg ); + WriteI2C(dt3155_lbase[minor], ODD_CSR, i2c_odd_csr.reg); return; } /* If we get here, the Odd Field wasn't it either... */ - printk( "neither even nor odd. shared perhaps?\n"); + printk("neither even nor odd. shared perhaps?\n"); } /***************************************************** @@ -421,22 +421,22 @@ static inline void dt3155_isr( int irq, void *dev_id, struct pt_regs *regs ) *****************************************************/ static void dt3155_init_isr(int minor) { - const u32 stride = dt3155_status[ minor ].config.cols; + const u32 stride = dt3155_status[minor].config.cols; - switch (dt3155_status[ minor ].state & DT3155_STATE_MODE) + switch (dt3155_status[minor].state & DT3155_STATE_MODE) { case DT3155_STATE_FLD: { - even_dma_start_r = dt3155_status[ minor ]. - fbuffer.frame_info[ dt3155_status[ minor ].fbuffer.active_buf ].addr; + even_dma_start_r = dt3155_status[minor]. + fbuffer.frame_info[dt3155_status[minor].fbuffer.active_buf].addr; even_dma_stride_r = 0; odd_dma_stride_r = 0; - WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_START), + WriteMReg((dt3155_lbase[minor] + EVEN_DMA_START), even_dma_start_r); - WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_STRIDE), + WriteMReg((dt3155_lbase[minor] + EVEN_DMA_STRIDE), even_dma_stride_r); - WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_STRIDE), + WriteMReg((dt3155_lbase[minor] + ODD_DMA_STRIDE), odd_dma_stride_r); break; } @@ -444,19 +444,19 @@ static void dt3155_init_isr(int minor) case DT3155_STATE_FRAME: default: { - even_dma_start_r = dt3155_status[ minor ]. - fbuffer.frame_info[ dt3155_status[ minor ].fbuffer.active_buf ].addr; + even_dma_start_r = dt3155_status[minor]. + fbuffer.frame_info[dt3155_status[minor].fbuffer.active_buf].addr; odd_dma_start_r = even_dma_start_r + stride; even_dma_stride_r = stride; odd_dma_stride_r = stride; - WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_START), + WriteMReg((dt3155_lbase[minor] + EVEN_DMA_START), even_dma_start_r); - WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_START), + WriteMReg((dt3155_lbase[minor] + ODD_DMA_START), odd_dma_start_r); - WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_STRIDE), + WriteMReg((dt3155_lbase[minor] + EVEN_DMA_STRIDE), even_dma_stride_r); - WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_STRIDE), + WriteMReg((dt3155_lbase[minor] + ODD_DMA_STRIDE), odd_dma_stride_r); break; } @@ -465,9 +465,9 @@ static void dt3155_init_isr(int minor) /* 50/60 Hz should be set before this point but let's make sure it is */ /* right anyway */ - ReadI2C(dt3155_lbase[ minor ], CONFIG, &i2c_csr2.reg); + ReadI2C(dt3155_lbase[minor], CONFIG, &i2c_csr2.reg); i2c_csr2.fld.HZ50 = FORMAT50HZ; - WriteI2C(dt3155_lbase[ minor ], CONFIG, i2c_config.reg); + WriteI2C(dt3155_lbase[minor], CONFIG, i2c_config.reg); /* enable busmaster chip, clear flags */ @@ -487,7 +487,7 @@ static void dt3155_init_isr(int minor) csr1_r.fld.FLD_CRPT_EVE = 1; /* writing a 1 clears flags */ csr1_r.fld.FLD_CRPT_ODD = 1; - WriteMReg((dt3155_lbase[ minor ] + CSR1),csr1_r.reg); + WriteMReg((dt3155_lbase[minor] + CSR1),csr1_r.reg); /* Enable interrupts at the end of each field */ @@ -496,14 +496,14 @@ static void dt3155_init_isr(int minor) int_csr_r.fld.FLD_END_ODD_EN = 1; int_csr_r.fld.FLD_START_EN = 0; - WriteMReg((dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg); + WriteMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg); /* start internal BUSY bits */ - ReadI2C(dt3155_lbase[ minor ], CSR2, &i2c_csr2.reg); + ReadI2C(dt3155_lbase[minor], CSR2, &i2c_csr2.reg); i2c_csr2.fld.BUSY_ODD = 1; i2c_csr2.fld.BUSY_EVE = 1; - WriteI2C(dt3155_lbase[ minor ], CSR2, i2c_csr2.reg); + WriteI2C(dt3155_lbase[minor], CSR2, i2c_csr2.reg); /* Now its up to the interrupt routine!! */ @@ -522,7 +522,7 @@ static int dt3155_ioctl(struct inode *inode, { int minor = MINOR(inode->i_rdev); /* What device are we ioctl()'ing? */ - if ( minor >= MAXBOARDS || minor < 0 ) + if (minor >= MAXBOARDS || minor < 0) return -ENODEV; /* make sure it is valid command */ @@ -566,7 +566,7 @@ static int dt3155_ioctl(struct inode *inode, case DT3155_GET_CONFIG: { if (copy_to_user((void *) arg, (void *) &dt3155_status[minor], - sizeof(dt3155_status_t) )) + sizeof(dt3155_status_t))) return -EFAULT; return 0; } @@ -610,7 +610,7 @@ static int dt3155_ioctl(struct inode *inode, } dt3155_init_isr(minor); - if (copy_to_user( (void *) arg, (void *) &dt3155_status[minor], + if (copy_to_user((void *) arg, (void *) &dt3155_status[minor], sizeof(dt3155_status_t))) return -EFAULT; return 0; @@ -682,36 +682,36 @@ static int dt3155_mmap (struct file * file, struct vm_area_struct * vma) * MOD_INC_USE_COUNT make sure that the driver memory is not freed * while the device is in use. *****************************************************/ -static int dt3155_open( struct inode* inode, struct file* filep) +static int dt3155_open(struct inode* inode, struct file* filep) { int minor = MINOR(inode->i_rdev); /* what device are we opening? */ - if (dt3155_dev_open[ minor ]) { + if (dt3155_dev_open[minor]) { printk ("DT3155: Already opened by another process.\n"); return -EBUSY; } - if (dt3155_status[ minor ].device_installed==0) + if (dt3155_status[minor].device_installed==0) { printk("DT3155 Open Error: No such device dt3155 minor number %d\n", minor); return -EIO; } - if (dt3155_status[ minor ].state != DT3155_STATE_IDLE) { + if (dt3155_status[minor].state != DT3155_STATE_IDLE) { printk ("DT3155: Not in idle state (state = %x)\n", - dt3155_status[ minor ].state); + dt3155_status[minor].state); return -EBUSY; } printk("DT3155: Device opened.\n"); - dt3155_dev_open[ minor ] = 1 ; + dt3155_dev_open[minor] = 1 ; - dt3155_flush( minor ); + dt3155_flush(minor); /* Disable ALL interrupts */ int_csr_r.reg = 0; - WriteMReg( (dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg ); + WriteMReg((dt3155_lbase[minor] + INT_CSR), int_csr_r.reg); init_waitqueue_head(&(dt3155_read_wait_queue[minor])); @@ -725,20 +725,20 @@ static int dt3155_open( struct inode* inode, struct file* filep) * Now decrement the use count. * *****************************************************/ -static int dt3155_close( struct inode *inode, struct file *filep) +static int dt3155_close(struct inode *inode, struct file *filep) { int minor; minor = MINOR(inode->i_rdev); /* which device are we closing */ - if (!dt3155_dev_open[ minor ]) + if (!dt3155_dev_open[minor]) { printk("DT3155: attempt to CLOSE a not OPEN device\n"); } else { - dt3155_dev_open[ minor ] = 0; + dt3155_dev_open[minor] = 0; - if (dt3155_status[ minor ].state != DT3155_STATE_IDLE) + if (dt3155_status[minor].state != DT3155_STATE_IDLE) { quick_stop(minor); } @@ -782,7 +782,7 @@ static ssize_t dt3155_read(struct file *filep, char __user *buf, if (filep->f_flags & O_NDELAY) { if ((frame_index = dt3155_get_ready_buffer(minor)) < 0) { - /*printk( "dt3155: no buffers available (?)\n");*/ + /*printk("dt3155: no buffers available (?)\n");*/ /* printques(minor); */ return -EAGAIN; } @@ -814,7 +814,7 @@ static ssize_t dt3155_read(struct file *filep, char __user *buf, put_user(offset, (unsigned int *) buf); buf += sizeof(u32); - put_user( dt3155_status[minor].fbuffer.frame_count, (unsigned int *) buf); + put_user(dt3155_status[minor].fbuffer.frame_count, (unsigned int *) buf); buf += sizeof(u32); put_user(dt3155_status[minor].state, (unsigned int *) buf); buf += sizeof(u32); @@ -901,7 +901,7 @@ static int find_PCI (void) /* Now, just go out and make sure that this/these device(s) is/are actually mapped into the kernel address space */ - if ((error = pci_read_config_dword( pci_dev, PCI_BASE_ADDRESS_0, + if ((error = pci_read_config_dword(pci_dev, PCI_BASE_ADDRESS_0, (u32 *) &base))) { printk("DT3155: Was not able to find device \n"); @@ -913,26 +913,26 @@ static int find_PCI (void) /* Remap the base address to a logical address through which we * can access it. */ - dt3155_lbase[ pci_index - 1 ] = ioremap(base,PCI_PAGE_SIZE); - dt3155_status[ pci_index - 1 ].reg_addr = base; + dt3155_lbase[pci_index - 1] = ioremap(base,PCI_PAGE_SIZE); + dt3155_status[pci_index - 1].reg_addr = base; DT_3155_DEBUG_MSG("DT3155: New logical address is %p \n", dt3155_lbase[pci_index-1]); - if ( !dt3155_lbase[pci_index-1] ) + if (!dt3155_lbase[pci_index-1]) { printk("DT3155: Unable to remap control registers\n"); goto err; } - if ( (error = pci_read_config_byte( pci_dev, PCI_INTERRUPT_LINE, &irq)) ) + if ((error = pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &irq))) { printk("DT3155: Was not able to find device \n"); goto err; } DT_3155_DEBUG_MSG("DT3155: IRQ is %d \n",irq); - dt3155_status[ pci_index-1 ].irq = irq; + dt3155_status[pci_index-1].irq = irq; /* Set flag: kth device found! */ - dt3155_status[ pci_index-1 ].device_installed = 1; + dt3155_status[pci_index-1].device_installed = 1; printk("DT3155: Installing device %d w/irq %d and address %p\n", pci_index, dt3155_status[pci_index-1].irq, @@ -957,89 +957,89 @@ int init_module(void) { int index; int rcode = 0; - char *devname[ MAXBOARDS ]; + char *devname[MAXBOARDS]; - devname[ 0 ] = "dt3155a"; + devname[0] = "dt3155a"; #if MAXBOARDS == 2 - devname[ 1 ] = "dt3155b"; + devname[1] = "dt3155b"; #endif printk("DT3155: Loading module...\n"); /* Register the device driver */ - rcode = register_chrdev( dt3155_major, "dt3155", &dt3155_fops ); - if( rcode < 0 ) + rcode = register_chrdev(dt3155_major, "dt3155", &dt3155_fops); + if(rcode < 0) { - printk( KERN_INFO "DT3155: register_chrdev failed \n"); + printk(KERN_INFO "DT3155: register_chrdev failed \n"); return rcode; } - if( dt3155_major == 0 ) + if(dt3155_major == 0) dt3155_major = rcode; /* dynamic */ /* init the status variables. */ /* DMA memory is taken care of in setup_buffers() */ - for ( index = 0; index < MAXBOARDS; index++ ) + for (index = 0; index < MAXBOARDS; index++) { - dt3155_status[ index ].config.acq_mode = DT3155_MODE_FRAME; - dt3155_status[ index ].config.continuous = DT3155_ACQ; - dt3155_status[ index ].config.cols = DT3155_MAX_COLS; - dt3155_status[ index ].config.rows = DT3155_MAX_ROWS; - dt3155_status[ index ].state = DT3155_STATE_IDLE; + dt3155_status[index].config.acq_mode = DT3155_MODE_FRAME; + dt3155_status[index].config.continuous = DT3155_ACQ; + dt3155_status[index].config.cols = DT3155_MAX_COLS; + dt3155_status[index].config.rows = DT3155_MAX_ROWS; + dt3155_status[index].state = DT3155_STATE_IDLE; /* find_PCI() will check if devices are installed; */ /* first assume they're not: */ - dt3155_status[ index ].mem_addr = 0; - dt3155_status[ index ].mem_size = 0; - dt3155_status[ index ].state = DT3155_STATE_IDLE; - dt3155_status[ index ].device_installed = 0; + dt3155_status[index].mem_addr = 0; + dt3155_status[index].mem_size = 0; + dt3155_status[index].state = DT3155_STATE_IDLE; + dt3155_status[index].device_installed = 0; } /* Now let's find the hardware. find_PCI() will set ndevices to the * number of cards found in this machine. */ { - if ( (rcode = find_PCI()) != DT_3155_SUCCESS ) + if ((rcode = find_PCI()) != DT_3155_SUCCESS) { printk("DT3155 error: find_PCI() failed to find dt3155 board(s)\n"); - unregister_chrdev( dt3155_major, "dt3155" ); + unregister_chrdev(dt3155_major, "dt3155"); return rcode; } } /* Ok, time to setup the frame buffers */ - if( (rcode = dt3155_setup_buffers(&allocatorAddr)) < 0 ) + if((rcode = dt3155_setup_buffers(&allocatorAddr)) < 0) { printk("DT3155: Error: setting up buffer not large enough."); - unregister_chrdev( dt3155_major, "dt3155" ); + unregister_chrdev(dt3155_major, "dt3155"); return rcode; } /* If we are this far, then there is enough RAM */ /* for the buffers: Print the configuration. */ - for( index = 0; index < ndevices; index++ ) + for( index = 0; index < ndevices; index++) { printk("DT3155: Device = %d; acq_mode = %d; " "continuous = %d; cols = %d; rows = %d;\n", index , - dt3155_status[ index ].config.acq_mode, - dt3155_status[ index ].config.continuous, - dt3155_status[ index ].config.cols, - dt3155_status[ index ].config.rows); + dt3155_status[index].config.acq_mode, + dt3155_status[index].config.continuous, + dt3155_status[index].config.cols, + dt3155_status[index].config.rows); printk("DT3155: m_addr = 0x%x; m_size = %ld; " "state = %d; device_installed = %d\n", - dt3155_status[ index ].mem_addr, - (long int)dt3155_status[ index ].mem_size, - dt3155_status[ index ].state, - dt3155_status[ index ].device_installed); + dt3155_status[index].mem_addr, + (long int)dt3155_status[index].mem_size, + dt3155_status[index].state, + dt3155_status[index].device_installed); } /* Disable ALL interrupts */ int_csr_r.reg = 0; - for( index = 0; index < ndevices; index++ ) + for( index = 0; index < ndevices; index++) { - WriteMReg( (dt3155_lbase[ index ] + INT_CSR), int_csr_r.reg ); - if( dt3155_status[ index ].device_installed ) + WriteMReg((dt3155_lbase[index] + INT_CSR), int_csr_r.reg); + if(dt3155_status[index].device_installed) { /* * This driver *looks* like it can handle sharing interrupts, @@ -1048,14 +1048,14 @@ int init_module(void) * as a reminder in case any problems arise. (SS) */ /* in older kernels flags are: SA_SHIRQ | SA_INTERRUPT */ - rcode = request_irq( dt3155_status[ index ].irq, (void *)dt3155_isr, - IRQF_SHARED | IRQF_DISABLED, devname[ index ], + rcode = request_irq(dt3155_status[index].irq, (void *)dt3155_isr, + IRQF_SHARED | IRQF_DISABLED, devname[index], (void*) &dt3155_status[index]); - if( rcode < 0 ) + if(rcode < 0) { printk("DT3155: minor %d request_irq failed for IRQ %d\n", index, dt3155_status[index].irq); - unregister_chrdev( dt3155_major, "dt3155" ); + unregister_chrdev(dt3155_major, "dt3155"); return rcode; } } @@ -1084,15 +1084,15 @@ void cleanup_module(void) allocator_cleanup(); #endif - unregister_chrdev( dt3155_major, "dt3155" ); + unregister_chrdev(dt3155_major, "dt3155"); - for( index = 0; index < ndevices; index++ ) + for(index = 0; index < ndevices; index++) { - if( dt3155_status[ index ].device_installed == 1 ) + if(dt3155_status[index].device_installed == 1) { - printk( "DT3155: Freeing irq %d for device %d\n", - dt3155_status[ index ].irq, index ); - free_irq( dt3155_status[ index ].irq, (void*)&dt3155_status[index] ); + printk("DT3155: Freeing irq %d for device %d\n", + dt3155_status[index].irq, index); + free_irq(dt3155_status[index].irq, (void*)&dt3155_status[index]); } } } -- cgit v1.2.3 From 7d4984d8424182eba2774755ae2ae8145651e788 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 29 Mar 2010 00:34:29 -0700 Subject: Staging: dt3155: allocator.c: sparse cleanups Make prototypes match implementation Use gfp_t flags not int prio Still a couple of sparse warnings left Signed-off-by: Joe Perches Cc: Simon Horman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dt3155/allocator.c | 15 ++++++++------- drivers/staging/dt3155/allocator.h | 4 ++-- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dt3155/allocator.c b/drivers/staging/dt3155/allocator.c index 6fbd0507288c..bd5adbc2a238 100644 --- a/drivers/staging/dt3155/allocator.c +++ b/drivers/staging/dt3155/allocator.c @@ -58,6 +58,8 @@ #include +#include "allocator.h" + /*#define ALL_DEBUG*/ #define ALL_MSG "allocator: " @@ -83,9 +85,9 @@ /*#define PDEBUGG(fmt, args...) printk( KERN_DEBUG ALL_MSG fmt, ## args)*/ -int allocator_himem = 1; /* 0 = probe, pos. = megs, neg. = disable */ -int allocator_step = 1; /* This is the step size in MB */ -int allocator_probe = 1; /* This is a flag -- 1=probe, 0=don't probe */ +static int allocator_himem = 1; /* 0 = probe, pos. = megs, neg. = disable */ +static int allocator_step = 1; /* This is the step size in MB */ +static int allocator_probe = 1; /* This is a flag -- 1=probe, 0=don't probe */ static unsigned long allocator_buffer; /* physical address */ static unsigned long allocator_buffer_size; /* kilobytes */ @@ -101,8 +103,7 @@ struct allocator_struct { struct allocator_struct *next; }; -struct allocator_struct *allocator_list; - +static struct allocator_struct *allocator_list; #ifdef ALL_DEBUG static int dump_list(void) @@ -124,7 +125,7 @@ static int dump_list(void) * be used straight ahead for DMA, but needs remapping for program use). */ -unsigned long allocator_allocate_dma(unsigned long kilobytes, int prio) +unsigned long allocator_allocate_dma(unsigned long kilobytes, gfp_t flags) { struct allocator_struct *ptr = allocator_list, *newptr; unsigned long bytes = kilobytes << 10; @@ -147,7 +148,7 @@ unsigned long allocator_allocate_dma(unsigned long kilobytes, int prio) PDEBUG("alloc failed\n"); return 0; /* end of list */ } - newptr = kmalloc(sizeof(struct allocator_struct), prio); + newptr = kmalloc(sizeof(struct allocator_struct), flags); if (!newptr) return 0; diff --git a/drivers/staging/dt3155/allocator.h b/drivers/staging/dt3155/allocator.h index bdf3268ca52d..425b70fcd500 100644 --- a/drivers/staging/dt3155/allocator.h +++ b/drivers/staging/dt3155/allocator.h @@ -22,7 +22,7 @@ * */ -void allocator_free_dma(unsigned long address); -unsigned long allocator_allocate_dma(unsigned long kilobytes, int priority); +int allocator_free_dma(unsigned long address); +unsigned long allocator_allocate_dma(unsigned long kilobytes, gfp_t flags); int allocator_init(u32 *); void allocator_cleanup(void); -- cgit v1.2.3 From e43a0edcb066935268b60c3444e30423bfee664c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 27 Apr 2010 16:04:13 -0700 Subject: Staging: dt3155.h: remove #ifdef We are in the kernel now, don't check to see if we are not. Cc: H Hartley Sweeten Cc: Scott Smedley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dt3155/dt3155.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dt3155/dt3155.h b/drivers/staging/dt3155/dt3155.h index 1bf786364eec..37d9fc6d0636 100644 --- a/drivers/staging/dt3155/dt3155.h +++ b/drivers/staging/dt3155/dt3155.h @@ -34,15 +34,8 @@ MA 02111-1307 USA #ifndef _DT3155_INC #define _DT3155_INC -#ifdef __KERNEL__ #include #include /* struct timeval */ -#else -#include -#include -#include -#include -#endif #define TRUE 1 -- cgit v1.2.3 From ffefea471134987fc647f0a7502540bb6e5ae71f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 27 Apr 2010 16:06:14 -0700 Subject: Staging: dt3155: remove TRUE/FALSE These aren't needed in the kernel, so remove them. Cc: H Hartley Sweeten Cc: Scott Smedley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dt3155/dt3155.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dt3155/dt3155.h b/drivers/staging/dt3155/dt3155.h index 37d9fc6d0636..453686e8064c 100644 --- a/drivers/staging/dt3155/dt3155.h +++ b/drivers/staging/dt3155/dt3155.h @@ -38,9 +38,6 @@ MA 02111-1307 USA #include /* struct timeval */ -#define TRUE 1 -#define FALSE 0 - /* Uncomment this for 50Hz CCIR */ #define CCIR 1 @@ -55,11 +52,11 @@ MA 02111-1307 USA #ifdef CCIR #define DT3155_MAX_ROWS 576 #define DT3155_MAX_COLS 768 -#define FORMAT50HZ TRUE +#define FORMAT50HZ 1 #else #define DT3155_MAX_ROWS 480 #define DT3155_MAX_COLS 640 -#define FORMAT50HZ FALSE +#define FORMAT50HZ 0 #endif /* Configuration structure */ -- cgit v1.2.3 From 7f76c52fb0f4c7dfbe7dba1e80691fef957242b6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 27 Apr 2010 16:45:27 -0700 Subject: Staging: dt3155: remove frame_info_t The typedef is not needed. Cc: H Hartley Sweeten Cc: Scott Smedley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dt3155/dt3155.h | 8 ++++---- drivers/staging/dt3155/dt3155_drv.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dt3155/dt3155.h b/drivers/staging/dt3155/dt3155.h index 453686e8064c..93ee663f033f 100644 --- a/drivers/staging/dt3155/dt3155.h +++ b/drivers/staging/dt3155/dt3155.h @@ -68,11 +68,11 @@ struct dt3155_config_s { /* hold data for each frame */ -typedef struct { +struct frame_info { u32 addr; /* address of the buffer with the frame */ u32 tag; /* unique number for the frame */ struct timeval time; /* time that capture took place */ -} frame_info_t; +}; /* * Structure for interrupt and buffer handling. @@ -81,7 +81,7 @@ typedef struct { struct dt3155_fbuffer_s { int nbuffers; - frame_info_t frame_info[BOARD_MAX_BUFFS]; + struct frame_info frame_info[BOARD_MAX_BUFFS]; int empty_buffers[BOARD_MAX_BUFFS]; /* indexes empty frames */ int empty_len; /* Number of empty buffers */ @@ -155,7 +155,7 @@ typedef struct dt3155_read_s { u32 frame_seq; u32 state; - frame_info_t frame_info; + struct frame_info frame_info; } dt3155_read_t; #endif /* _DT3155_inc */ diff --git a/drivers/staging/dt3155/dt3155_drv.c b/drivers/staging/dt3155/dt3155_drv.c index 91ebfadba9a7..cd674e1c6d0f 100644 --- a/drivers/staging/dt3155/dt3155_drv.c +++ b/drivers/staging/dt3155/dt3155_drv.c @@ -757,7 +757,7 @@ static ssize_t dt3155_read(struct file *filep, char __user *buf, int minor = MINOR(filep->f_dentry->d_inode->i_rdev); u32 offset; int frame_index; - frame_info_t *frame_info_p; + struct frame_info *frame_info; /* TODO: this should check the error flag and */ /* return an error on hardware failures */ @@ -807,10 +807,10 @@ static ssize_t dt3155_read(struct file *filep, char __user *buf, } } - frame_info_p = &dt3155_status[minor].fbuffer.frame_info[frame_index]; + frame_info = &dt3155_status[minor].fbuffer.frame_info[frame_index]; /* make this an offset */ - offset = frame_info_p->addr - dt3155_status[minor].mem_addr; + offset = frame_info->addr - dt3155_status[minor].mem_addr; put_user(offset, (unsigned int *) buf); buf += sizeof(u32); @@ -818,7 +818,7 @@ static ssize_t dt3155_read(struct file *filep, char __user *buf, buf += sizeof(u32); put_user(dt3155_status[minor].state, (unsigned int *) buf); buf += sizeof(u32); - if (copy_to_user(buf, frame_info_p, sizeof(frame_info_t))) + if (copy_to_user(buf, frame_info, sizeof(*frame_info))) return -EFAULT; return sizeof(dt3155_read_t); -- cgit v1.2.3 From 923c1244fc27dc1623d95b6b3a29bc305a18bac5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 27 Apr 2010 16:47:55 -0700 Subject: Staging: dt3155: remove dt3155_status_t The typedef is not needed. Cc: H Hartley Sweeten Cc: Scott Smedley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dt3155/dt3155.h | 8 ++++---- drivers/staging/dt3155/dt3155_drv.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dt3155/dt3155.h b/drivers/staging/dt3155/dt3155.h index 93ee663f033f..6546b60b9b89 100644 --- a/drivers/staging/dt3155/dt3155.h +++ b/drivers/staging/dt3155/dt3155.h @@ -110,7 +110,7 @@ struct dt3155_fbuffer_s { #define DT3155_ACQ 2 /* There is one status structure for each card. */ -typedef struct dt3155_status_s { +struct dt3155_status { int fixed_mode; /* if 1, we are in fixed frame mode */ u32 reg_addr; /* Register address for a single card */ u32 mem_addr; /* Buffer start addr for this card */ @@ -120,10 +120,10 @@ typedef struct dt3155_status_s { struct dt3155_fbuffer_s fbuffer; /* frame buffer state struct */ u32 state; /* this card's state */ u32 device_installed; /* Flag if installed. 1=installed */ -} dt3155_status_t; +}; /* Reference to global status structure */ -extern struct dt3155_status_s dt3155_status[MAXBOARDS]; +extern struct dt3155_status dt3155_status[MAXBOARDS]; #define DT3155_STATE_IDLE 0x00 #define DT3155_STATE_FRAME 0x01 @@ -135,7 +135,7 @@ extern struct dt3155_status_s dt3155_status[MAXBOARDS]; #define DT3155_IOC_MAGIC '!' #define DT3155_SET_CONFIG _IOW(DT3155_IOC_MAGIC, 1, struct dt3155_config_s) -#define DT3155_GET_CONFIG _IOR(DT3155_IOC_MAGIC, 2, struct dt3155_status_s) +#define DT3155_GET_CONFIG _IOR(DT3155_IOC_MAGIC, 2, struct dt3155_status) #define DT3155_STOP _IO(DT3155_IOC_MAGIC, 3) #define DT3155_START _IO(DT3155_IOC_MAGIC, 4) #define DT3155_FLUSH _IO(DT3155_IOC_MAGIC, 5) diff --git a/drivers/staging/dt3155/dt3155_drv.c b/drivers/staging/dt3155/dt3155_drv.c index cd674e1c6d0f..5c567e4a88a2 100644 --- a/drivers/staging/dt3155/dt3155_drv.c +++ b/drivers/staging/dt3155/dt3155_drv.c @@ -112,7 +112,7 @@ int dt3155_major = 0; /* Global structures and variables */ /* Status of each device */ -struct dt3155_status_s dt3155_status[MAXBOARDS]; +struct dt3155_status dt3155_status[MAXBOARDS]; /* kernel logical address of the board */ u8 *dt3155_lbase[MAXBOARDS] = { NULL @@ -566,7 +566,7 @@ static int dt3155_ioctl(struct inode *inode, case DT3155_GET_CONFIG: { if (copy_to_user((void *) arg, (void *) &dt3155_status[minor], - sizeof(dt3155_status_t))) + sizeof(struct dt3155_status))) return -EFAULT; return 0; } @@ -587,7 +587,7 @@ static int dt3155_ioctl(struct inode *inode, quick_stop(minor); if (copy_to_user((void *) arg, (void *) &dt3155_status[minor], - sizeof(dt3155_status_t))) + sizeof(struct dt3155_status))) return -EFAULT; return 0; } @@ -611,7 +611,7 @@ static int dt3155_ioctl(struct inode *inode, dt3155_init_isr(minor); if (copy_to_user((void *) arg, (void *) &dt3155_status[minor], - sizeof(dt3155_status_t))) + sizeof(struct dt3155_status))) return -EFAULT; return 0; } -- cgit v1.2.3 From 5019d2848c6773ee5815291e6d3fcc33d0f5345c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 27 Apr 2010 16:49:23 -0700 Subject: Staging: dt3155: remove dt3155_read_t The typedef is not needed. Cc: H Hartley Sweeten Cc: Scott Smedley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dt3155/dt3155.h | 4 ++-- drivers/staging/dt3155/dt3155_drv.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dt3155/dt3155.h b/drivers/staging/dt3155/dt3155.h index 6546b60b9b89..74a71f6a8ebc 100644 --- a/drivers/staging/dt3155/dt3155.h +++ b/drivers/staging/dt3155/dt3155.h @@ -150,12 +150,12 @@ extern struct dt3155_status dt3155_status[MAXBOARDS]; #define DT_ERR_MASK 0xff0000/* not used but it might be one day */ /* User code will probably want to declare one of these for each card */ -typedef struct dt3155_read_s { +struct dt3155_read { u32 offset; u32 frame_seq; u32 state; struct frame_info frame_info; -} dt3155_read_t; +}; #endif /* _DT3155_inc */ diff --git a/drivers/staging/dt3155/dt3155_drv.c b/drivers/staging/dt3155/dt3155_drv.c index 5c567e4a88a2..3e8ceac3d9b9 100644 --- a/drivers/staging/dt3155/dt3155_drv.c +++ b/drivers/staging/dt3155/dt3155_drv.c @@ -761,7 +761,7 @@ static ssize_t dt3155_read(struct file *filep, char __user *buf, /* TODO: this should check the error flag and */ /* return an error on hardware failures */ - if (count != sizeof(dt3155_read_t)) + if (count != sizeof(struct dt3155_read)) { printk("DT3155 ERROR (NJC): count is not right\n"); return -EINVAL; @@ -821,7 +821,7 @@ static ssize_t dt3155_read(struct file *filep, char __user *buf, if (copy_to_user(buf, frame_info, sizeof(*frame_info))) return -EFAULT; - return sizeof(dt3155_read_t); + return sizeof(struct dt3155_read); } static unsigned int dt3155_poll (struct file * filp, poll_table *wait) -- cgit v1.2.3 From 8b692e69c76592fd91ebfbb0e59faea3b6fda256 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 27 Apr 2010 16:51:50 -0700 Subject: Staging: dt3155: rename dt3155_config_s Drop the "_s", as it's not needed. Now, dt3155.h is checkpatch.pl clean. Cc: H Hartley Sweeten Cc: Scott Smedley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dt3155/dt3155.h | 6 +++--- drivers/staging/dt3155/dt3155_drv.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dt3155/dt3155.h b/drivers/staging/dt3155/dt3155.h index 74a71f6a8ebc..b99b5271d158 100644 --- a/drivers/staging/dt3155/dt3155.h +++ b/drivers/staging/dt3155/dt3155.h @@ -60,7 +60,7 @@ MA 02111-1307 USA #endif /* Configuration structure */ -struct dt3155_config_s { +struct dt3155_config { u32 acq_mode; u32 cols, rows; u32 continuous; @@ -116,7 +116,7 @@ struct dt3155_status { u32 mem_addr; /* Buffer start addr for this card */ u32 mem_size; /* This is the amount of mem available */ u32 irq; /* this card's irq */ - struct dt3155_config_s config; /* configuration struct */ + struct dt3155_config config; /* configuration struct */ struct dt3155_fbuffer_s fbuffer; /* frame buffer state struct */ u32 state; /* this card's state */ u32 device_installed; /* Flag if installed. 1=installed */ @@ -134,7 +134,7 @@ extern struct dt3155_status dt3155_status[MAXBOARDS]; #define DT3155_IOC_MAGIC '!' -#define DT3155_SET_CONFIG _IOW(DT3155_IOC_MAGIC, 1, struct dt3155_config_s) +#define DT3155_SET_CONFIG _IOW(DT3155_IOC_MAGIC, 1, struct dt3155_config) #define DT3155_GET_CONFIG _IOR(DT3155_IOC_MAGIC, 2, struct dt3155_status) #define DT3155_STOP _IO(DT3155_IOC_MAGIC, 3) #define DT3155_START _IO(DT3155_IOC_MAGIC, 4) diff --git a/drivers/staging/dt3155/dt3155_drv.c b/drivers/staging/dt3155/dt3155_drv.c index 3e8ceac3d9b9..789d47ae3e03 100644 --- a/drivers/staging/dt3155/dt3155_drv.c +++ b/drivers/staging/dt3155/dt3155_drv.c @@ -546,7 +546,7 @@ static int dt3155_ioctl(struct inode *inode, return -EBUSY; { - struct dt3155_config_s tmp; + struct dt3155_config tmp; if (copy_from_user((void *)&tmp, (void *) arg, sizeof(tmp))) return -EFAULT; /* check for valid settings */ -- cgit v1.2.3 From e802b4b79d2b25c47736c135a709b6c31e95fc39 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 27 Apr 2010 16:53:59 -0700 Subject: Staging: dt3155: rename dt3155_fbuffer_s drop the "_s" as it's not needed. Cc: H Hartley Sweeten Cc: Scott Smedley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dt3155/dt3155.h | 4 ++-- drivers/staging/dt3155/dt3155_isr.c | 4 ++-- drivers/staging/dt3155/dt3155_isr.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dt3155/dt3155.h b/drivers/staging/dt3155/dt3155.h index b99b5271d158..793e2fcf4466 100644 --- a/drivers/staging/dt3155/dt3155.h +++ b/drivers/staging/dt3155/dt3155.h @@ -78,7 +78,7 @@ struct frame_info { * Structure for interrupt and buffer handling. * This is the setup for 1 card */ -struct dt3155_fbuffer_s { +struct dt3155_fbuffer { int nbuffers; struct frame_info frame_info[BOARD_MAX_BUFFS]; @@ -117,7 +117,7 @@ struct dt3155_status { u32 mem_size; /* This is the amount of mem available */ u32 irq; /* this card's irq */ struct dt3155_config config; /* configuration struct */ - struct dt3155_fbuffer_s fbuffer; /* frame buffer state struct */ + struct dt3155_fbuffer fbuffer; /* frame buffer state struct */ u32 state; /* this card's state */ u32 device_installed; /* Flag if installed. 1=installed */ }; diff --git a/drivers/staging/dt3155/dt3155_isr.c b/drivers/staging/dt3155/dt3155_isr.c index 1ebcec0c3091..61f74b6a70f9 100644 --- a/drivers/staging/dt3155/dt3155_isr.c +++ b/drivers/staging/dt3155/dt3155_isr.c @@ -60,7 +60,7 @@ Purpose: Buffer management routines, and other routines for the ISR /* Pointer into global structure for handling buffers */ -struct dt3155_fbuffer_s *dt3155_fbuffer[MAXBOARDS] = {NULL +struct dt3155_fbuffer *dt3155_fbuffer[MAXBOARDS] = {NULL #if MAXBOARDS == 2 , NULL #endif @@ -317,7 +317,7 @@ u32 dt3155_setup_buffers(u32 *allocatorAddr) /* Make sure the buffering variables are consistent */ { u8 *ptr = (u8 *) dt3155_fbuffer[m]; - for (index = 0; index < sizeof(struct dt3155_fbuffer_s); index++) + for (index = 0; index < sizeof(struct dt3155_fbuffer); index++) *(ptr++) = 0; } } diff --git a/drivers/staging/dt3155/dt3155_isr.h b/drivers/staging/dt3155/dt3155_isr.h index 7595cb16c988..7d474cf743d8 100644 --- a/drivers/staging/dt3155/dt3155_isr.h +++ b/drivers/staging/dt3155/dt3155_isr.h @@ -36,7 +36,7 @@ MA 02111-1307 USA #ifndef DT3155_ISR_H #define DT3155_ISR_H -extern struct dt3155_fbuffer_s *dt3155_fbuffer[MAXBOARDS]; +extern struct dt3155_fbuffer *dt3155_fbuffer[MAXBOARDS]; /* User functions for buffering */ /* Initialize the buffering system. This should */ -- cgit v1.2.3 From e8afd402cc37aa2e6134c2f6e866f4a330d2da80 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 27 Apr 2010 17:04:16 -0700 Subject: Staging: dt3155: remove "inline" usage It was wrong, and not doing what anyone would think it would do. Cc: H Hartley Sweeten Cc: Scott Smedley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dt3155/dt3155_drv.c | 2 +- drivers/staging/dt3155/dt3155_isr.c | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dt3155/dt3155_drv.c b/drivers/staging/dt3155/dt3155_drv.c index 789d47ae3e03..f31309bf52b0 100644 --- a/drivers/staging/dt3155/dt3155_drv.c +++ b/drivers/staging/dt3155/dt3155_drv.c @@ -168,7 +168,7 @@ static void quick_stop (int minor) * - Assumes irq's are disabled, via SA_INTERRUPT flag * being set in request_irq() call from init_module() *****************************************************/ -static inline void dt3155_isr(int irq, void *dev_id, struct pt_regs *regs) +static void dt3155_isr(int irq, void *dev_id, struct pt_regs *regs) { int minor = -1; int index; diff --git a/drivers/staging/dt3155/dt3155_isr.c b/drivers/staging/dt3155/dt3155_isr.c index 61f74b6a70f9..33ddc9c057ff 100644 --- a/drivers/staging/dt3155/dt3155_isr.c +++ b/drivers/staging/dt3155/dt3155_isr.c @@ -77,7 +77,7 @@ struct dt3155_fbuffer *dt3155_fbuffer[MAXBOARDS] = {NULL * are_empty_buffers * m is minor # of device ***************************/ -inline bool are_empty_buffers(int m) +bool are_empty_buffers(int m) { return dt3155_fbuffer[m]->empty_len; } @@ -92,7 +92,7 @@ inline bool are_empty_buffers(int m) * given by dt3155_fbuffer[m]->empty_buffers[0]. * empty_buffers should never fill up, though this is not checked. **************************/ -inline void push_empty(int index, int m) +void push_empty(int index, int m) { dt3155_fbuffer[m]->empty_buffers[dt3155_fbuffer[m]->empty_len] = index; dt3155_fbuffer[m]->empty_len++; @@ -102,7 +102,7 @@ inline void push_empty(int index, int m) * pop_empty(m) * m is minor # of device **************************/ -inline int pop_empty(int m) +int pop_empty(int m) { dt3155_fbuffer[m]->empty_len--; return dt3155_fbuffer[m]->empty_buffers[dt3155_fbuffer[m]->empty_len]; @@ -112,7 +112,7 @@ inline int pop_empty(int m) * is_ready_buf_empty(m) * m is minor # of device *************************/ -inline bool is_ready_buf_empty(int m) +bool is_ready_buf_empty(int m) { return ((dt3155_fbuffer[m]->ready_len) == 0); } @@ -124,7 +124,7 @@ inline bool is_ready_buf_empty(int m) * buffers, since it corresponds to nbuffers ready buffers!! * 7/31/02: total rewrite. --NJC *************************/ -inline bool is_ready_buf_full(int m) +bool is_ready_buf_full(int m) { return dt3155_fbuffer[m]->ready_len == dt3155_fbuffer[m]->nbuffers; } @@ -134,7 +134,7 @@ inline bool is_ready_buf_full(int m) * m is minor # of device * *****************************************************/ -inline void push_ready(int m, int index) +void push_ready(int m, int index) { int head = dt3155_fbuffer[m]->ready_head; @@ -151,7 +151,7 @@ inline void push_ready(int m, int index) * * Simply comptutes the tail given the head and the length. *****************************************************/ -static inline int get_tail(int m) +static int get_tail(int m) { return (dt3155_fbuffer[m]->ready_head - dt3155_fbuffer[m]->ready_len + @@ -168,7 +168,7 @@ static inline int get_tail(int m) * This assumes that there is a ready buffer ready... should * be checked (e.g. with is_ready_buf_empty() prior to call. *****************************************************/ -inline int pop_ready(int m) +int pop_ready(int m) { int tail; tail = get_tail(m); @@ -181,7 +181,7 @@ inline int pop_ready(int m) * printques * m is minor # of device *****************************************************/ -inline void printques(int m) +void printques(int m) { int head = dt3155_fbuffer[m]->ready_head; int tail; @@ -410,7 +410,7 @@ u32 dt3155_setup_buffers(u32 *allocatorAddr) * * m is minor number of device *****************************************************/ -static inline void internal_release_locked_buffer(int m) +static void internal_release_locked_buffer(int m) { /* Pointer into global structure for handling buffers */ if (dt3155_fbuffer[m]->locked_buf >= 0) { @@ -427,7 +427,7 @@ static inline void internal_release_locked_buffer(int m) * The user function of the above. * *****************************************************/ -inline void dt3155_release_locked_buffer(int m) +void dt3155_release_locked_buffer(int m) { unsigned long int flags; local_save_flags(flags); @@ -442,7 +442,7 @@ inline void dt3155_release_locked_buffer(int m) * m is minor # of device * *****************************************************/ -inline int dt3155_flush(int m) +int dt3155_flush(int m) { int index; unsigned long int flags; @@ -479,7 +479,7 @@ inline int dt3155_flush(int m) * If the user has a buffer locked it will unlock * that buffer before returning the new one. *****************************************************/ -inline int dt3155_get_ready_buffer(int m) +int dt3155_get_ready_buffer(int m) { int frame_index; unsigned long int flags; -- cgit v1.2.3 From c1989b36df51b08a59b858920b4c84c392a63d12 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Sun, 14 Mar 2010 17:03:04 +0200 Subject: Staging: pohmelfs: fix spaces and TAB coding style issue in net.c This is a patch to the net.c file that fixed up a TAB and spaces Errors found by the checkpatch.pl tools, like ERROR: switch and case should be at the same indent and spaces required around that '=' (ctx:VxV) Signed-off-by: Ruslan Pisarev Acked-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/pohmelfs/net.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/pohmelfs/net.c b/drivers/staging/pohmelfs/net.c index 4a86f0b1ea88..9279897ff161 100644 --- a/drivers/staging/pohmelfs/net.c +++ b/drivers/staging/pohmelfs/net.c @@ -713,8 +713,8 @@ static int pohmelfs_crypto_cap_response(struct netfs_state *st) dprintk("%s: cipher '%s': %s, hash: '%s': %s.\n", __func__, - psb->cipher_string, (cap->cipher_strlen)?"SUPPORTED":"NOT SUPPORTED", - psb->hash_string, (cap->hash_strlen)?"SUPPORTED":"NOT SUPPORTED"); + psb->cipher_string, (cap->cipher_strlen) ? "SUPPORTED" : "NOT SUPPORTED", + psb->hash_string, (cap->hash_strlen) ? "SUPPORTED" : "NOT SUPPORTED"); if (!cap->hash_strlen) { if (psb->hash_strlen && psb->crypto_fail_unsupported) @@ -748,11 +748,11 @@ static int pohmelfs_capabilities_response(struct netfs_state *st) return err; switch (cmd->id) { - case POHMELFS_CRYPTO_CAPABILITIES: + case POHMELFS_CRYPTO_CAPABILITIES: return pohmelfs_crypto_cap_response(st); - case POHMELFS_ROOT_CAPABILITIES: + case POHMELFS_ROOT_CAPABILITIES: return pohmelfs_root_cap_response(st); - default: + default: break; } return -EINVAL; @@ -774,7 +774,7 @@ static int pohmelfs_getxattr_response(struct netfs_state *st) m = pohmelfs_mcache_search(psb, cmd->id); dprintk("%s: id: %llu, gen: %llu, err: %d.\n", - __func__, cmd->id, (m)?m->gen:0, error); + __func__, cmd->id, (m) ? m->gen : 0, error); if (!m) { printk("%s: failed to find getxattr cache entry: id: %llu.\n", __func__, cmd->id); @@ -824,7 +824,7 @@ int pohmelfs_data_lock_response(struct netfs_state *st) m = pohmelfs_mcache_search(psb, id); dprintk("%s: id: %llu, gen: %llu, err: %d.\n", - __func__, cmd->id, (m)?m->gen:0, err); + __func__, cmd->id, (m) ? m->gen : 0, err); if (!m) { pohmelfs_data_recv(st, st->data, cmd->size); @@ -915,7 +915,7 @@ static int pohmelfs_recv(void *data) unsigned char *hash = e->data; dprintk("%s: received hash: ", __func__); - for (i=0; icsize; ++i) + for (i = 0; i < cmd->csize; ++i) printk("%02x ", hash[i]); printk("\n"); @@ -933,37 +933,37 @@ static int pohmelfs_recv(void *data) } switch (cmd->cmd) { - case NETFS_READ_PAGE: + case NETFS_READ_PAGE: err = pohmelfs_read_page_response(st); break; - case NETFS_READDIR: + case NETFS_READDIR: err = pohmelfs_readdir_response(st); break; - case NETFS_LOOKUP: + case NETFS_LOOKUP: err = pohmelfs_lookup_response(st); break; - case NETFS_CREATE: + case NETFS_CREATE: err = pohmelfs_create_response(st); break; - case NETFS_REMOVE: + case NETFS_REMOVE: err = pohmelfs_remove_response(st); break; - case NETFS_TRANS: + case NETFS_TRANS: err = pohmelfs_transaction_response(st); break; - case NETFS_PAGE_CACHE: + case NETFS_PAGE_CACHE: err = pohmelfs_page_cache_response(st); break; - case NETFS_CAPABILITIES: + case NETFS_CAPABILITIES: err = pohmelfs_capabilities_response(st); break; - case NETFS_LOCK: + case NETFS_LOCK: err = pohmelfs_data_lock_response(st); break; - case NETFS_XATTR_GET: + case NETFS_XATTR_GET: err = pohmelfs_getxattr_response(st); break; - default: + default: printk("%s: wrong cmd: %u, id: %llu, start: %llu, size: %u, ext: %u.\n", __func__, cmd->cmd, cmd->id, cmd->start, cmd->size, cmd->ext); netfs_state_reset(st); -- cgit v1.2.3 From e3f052f2b84f66fcaa9b9149e1e0b4930d78c307 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Sun, 14 Mar 2010 17:25:09 +0200 Subject: Staging: pohmelfs: fix spaces and TAB coding style issue in crypto.c This is a patch to the crypto.c file that fixed up a TAB and spaces Errors found by the checkpatch.pl tools, like ERROR: switch and case should be at the same indent and spaces required around that '=' (ctx:VxV) Signed-off-by: Ruslan Pisarev Acked-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/pohmelfs/crypto.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/pohmelfs/crypto.c b/drivers/staging/pohmelfs/crypto.c index 884183c0913a..2fdb3e01460d 100644 --- a/drivers/staging/pohmelfs/crypto.c +++ b/drivers/staging/pohmelfs/crypto.c @@ -170,17 +170,17 @@ static int pohmelfs_crypto_process(struct ablkcipher_request *req, err = crypto_ablkcipher_decrypt(req); switch (err) { - case -EINPROGRESS: - case -EBUSY: - err = wait_for_completion_interruptible_timeout(&complete.complete, + case -EINPROGRESS: + case -EBUSY: + err = wait_for_completion_interruptible_timeout(&complete.complete, timeout); - if (!err) - err = -ETIMEDOUT; - else if (err > 0) - err = complete.error; - break; - default: - break; + if (!err) + err = -ETIMEDOUT; + else if (err > 0) + err = complete.error; + break; + default: + break; } return err; @@ -196,7 +196,7 @@ int pohmelfs_crypto_process_input_data(struct pohmelfs_crypto_engine *e, u64 cmd return 0; dprintk("%s: eng: %p, iv: %llx, data: %p, page: %p/%lu, size: %u.\n", - __func__, e, cmd_iv, data, page, (page)?page->index:0, size); + __func__, e, cmd_iv, data, page, (page) ? page->index : 0, size); if (data) { sg_init_one(&sg, data, size); @@ -247,7 +247,7 @@ int pohmelfs_crypto_process_input_data(struct pohmelfs_crypto_engine *e, u64 cmd dprintk("%s: eng: %p, hash: %p, cipher: %p: iv : %llx, hash mismatch (recv/calc): ", __func__, e, e->hash, e->cipher, cmd_iv); - for (i=0; ihash); ++i) { + for (i = 0; i < crypto_hash_digestsize(e->hash); ++i) { #if 0 dprintka("%02x ", recv[i]); if (recv[i] != calc[i]) { @@ -279,7 +279,7 @@ err_out_exit: } static int pohmelfs_trans_iter(struct netfs_trans *t, struct pohmelfs_crypto_engine *e, - int (* iterator) (struct pohmelfs_crypto_engine *e, + int (*iterator) (struct pohmelfs_crypto_engine *e, struct scatterlist *dst, struct scatterlist *src)) { @@ -319,7 +319,7 @@ static int pohmelfs_trans_iter(struct netfs_trans *t, struct pohmelfs_crypto_eng return 0; dpage_idx = 0; - for (i=0; ipage_num; ++i) { + for (i = 0; i < t->page_num; ++i) { struct page *page = t->pages[i]; struct page *dpage = e->pages[dpage_idx]; @@ -402,7 +402,7 @@ static int pohmelfs_hash(struct pohmelfs_crypto_thread *tc) { unsigned int i; dprintk("%s: ", __func__); - for (i=0; ipsb->crypto_attached_size; ++i) + for (i = 0; i < tc->psb->crypto_attached_size; ++i) dprintka("%02x ", dst[i]); dprintka("\n"); } @@ -414,7 +414,7 @@ static void pohmelfs_crypto_pages_free(struct pohmelfs_crypto_engine *e) { unsigned int i; - for (i=0; ipage_num; ++i) + for (i = 0; i < e->page_num; ++i) __free_page(e->pages[i]); kfree(e->pages); } @@ -427,7 +427,7 @@ static int pohmelfs_crypto_pages_alloc(struct pohmelfs_crypto_engine *e, struct if (!e->pages) return -ENOMEM; - for (i=0; itrans_max_pages; ++i) { + for (i = 0; i < psb->trans_max_pages; ++i) { e->pages[i] = alloc_page(GFP_KERNEL); if (!e->pages[i]) break; @@ -612,7 +612,7 @@ static int pohmelfs_sys_crypto_init(struct pohmelfs_sb *psb) __func__, st, &st->eng, &st->eng.hash, &st->eng.cipher); } - for (i=0; icrypto_thread_num; ++i) { + for (i = 0; i < psb->crypto_thread_num; ++i) { err = -ENOMEM; t = kzalloc(sizeof(struct pohmelfs_crypto_thread), GFP_KERNEL); if (!t) @@ -780,7 +780,7 @@ int pohmelfs_crypto_init(struct pohmelfs_sb *psb) } static int pohmelfs_crypto_thread_get(struct pohmelfs_sb *psb, - int (* action)(struct pohmelfs_crypto_thread *t, void *data), void *data) + int (*action)(struct pohmelfs_crypto_thread *t, void *data), void *data) { struct pohmelfs_crypto_thread *t = NULL; int err; -- cgit v1.2.3 From 5ac7af8942a4e7aca1eebee9b0b4ebc14c8cda89 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Sun, 14 Mar 2010 17:11:03 +0200 Subject: Staging: pohmelfs: fix spaces and TAB coding style issue in config.c This is a patch to the config.c file that fixed up a TAB and spaces Errors found by the checkpatch.pl tools, like: ERROR: switch and case should be at the same indent Signed-off-by: Ruslan Pisarev Acked-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/pohmelfs/config.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c index eed0e5545a55..6571a6ae05a5 100644 --- a/drivers/staging/pohmelfs/config.c +++ b/drivers/staging/pohmelfs/config.c @@ -509,13 +509,13 @@ static int pohmelfs_cn_crypto(struct cn_msg *msg) } switch (crypto->type) { - case POHMELFS_CRYPTO_HASH: + case POHMELFS_CRYPTO_HASH: err = pohmelfs_crypto_hash_init(g, crypto); break; - case POHMELFS_CRYPTO_CIPHER: + case POHMELFS_CRYPTO_CIPHER: err = pohmelfs_crypto_cipher_init(g, crypto); break; - default: + default: err = -ENOTSUPP; break; } @@ -536,24 +536,24 @@ static void pohmelfs_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *n return; switch (msg->flags) { - case POHMELFS_FLAGS_ADD: - case POHMELFS_FLAGS_DEL: - case POHMELFS_FLAGS_MODIFY: + case POHMELFS_FLAGS_ADD: + case POHMELFS_FLAGS_DEL: + case POHMELFS_FLAGS_MODIFY: err = pohmelfs_cn_ctl(msg, msg->flags); break; - case POHMELFS_FLAGS_FLUSH: + case POHMELFS_FLAGS_FLUSH: err = pohmelfs_cn_flush(msg); break; - case POHMELFS_FLAGS_SHOW: + case POHMELFS_FLAGS_SHOW: err = pohmelfs_cn_disp(msg); break; - case POHMELFS_FLAGS_DUMP: + case POHMELFS_FLAGS_DUMP: err = pohmelfs_cn_dump(msg); break; - case POHMELFS_FLAGS_CRYPTO: + case POHMELFS_FLAGS_CRYPTO: err = pohmelfs_cn_crypto(msg); break; - default: + default: err = -ENOSYS; break; } -- cgit v1.2.3 From 3420bc94e5c569a3385e781bf65c7d86c3053342 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Sun, 14 Mar 2010 17:39:46 +0200 Subject: Staging: pohmelfs: fix spaces and TAB coding style issue in dir.c This is a patch to the dir.c file that fixed up a TAB and spaces Errors found by the checkpatch.pl tools, like ERROR: spaces required around that '=' (ctx:VxV) Signed-off-by: Ruslan Pisarev Acked-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/pohmelfs/dir.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/pohmelfs/dir.c b/drivers/staging/pohmelfs/dir.c index 79819f07bfb9..059e9d2ddf6b 100644 --- a/drivers/staging/pohmelfs/dir.c +++ b/drivers/staging/pohmelfs/dir.c @@ -105,7 +105,7 @@ static struct pohmelfs_name *pohmelfs_insert_hash(struct pohmelfs_inode *pi, if (ret) { printk("%s: exist: parent: %llu, ino: %llu, hash: %x, len: %u, data: '%s', " - "new: ino: %llu, hash: %x, len: %u, data: '%s'.\n", + "new: ino: %llu, hash: %x, len: %u, data: '%s'.\n", __func__, pi->ino, ret->ino, ret->hash, ret->len, ret->data, new->ino, new->hash, new->len, new->data); @@ -234,7 +234,7 @@ struct pohmelfs_inode *pohmelfs_new_inode(struct pohmelfs_sb *psb, int err = -EEXIST; dprintk("%s: creating inode: parent: %llu, ino: %llu, str: %p.\n", - __func__, (parent)?parent->ino:0, info->ino, str); + __func__, (parent) ? parent->ino : 0, info->ino, str); err = -ENOMEM; new = iget_locked(psb->sb, info->ino); @@ -265,8 +265,8 @@ struct pohmelfs_inode *pohmelfs_new_inode(struct pohmelfs_sb *psb, s.len = 2; s.hash = jhash(s.name, s.len, 0); - err = pohmelfs_add_dir(psb, npi, (parent)?parent:npi, &s, - (parent)?parent->vfs_inode.i_mode:npi->vfs_inode.i_mode, 0); + err = pohmelfs_add_dir(psb, npi, (parent) ? parent : npi, &s, + (parent) ? parent->vfs_inode.i_mode : npi->vfs_inode.i_mode, 0); if (err) goto err_out_put; } @@ -277,7 +277,7 @@ struct pohmelfs_inode *pohmelfs_new_inode(struct pohmelfs_sb *psb, err = pohmelfs_add_dir(psb, parent, npi, str, info->mode, link); dprintk("%s: %s inserted name: '%s', new_offset: %llu, ino: %llu, parent: %llu.\n", - __func__, (err)?"unsuccessfully":"successfully", + __func__, (err) ? "unsuccessfully" : "successfully", str->name, parent->total_len, info->ino, parent->ino); if (err && err != -EEXIST) @@ -605,7 +605,7 @@ struct pohmelfs_inode *pohmelfs_create_entry_local(struct pohmelfs_sb *psb, if (!start) info.ino = pohmelfs_new_ino(psb); - info.nlink = S_ISDIR(mode)?2:1; + info.nlink = S_ISDIR(mode) ? 2 : 1; info.uid = current_fsuid(); info.gid = current_fsgid(); info.size = 0; @@ -849,7 +849,7 @@ static int pohmelfs_create_link(struct pohmelfs_inode *parent, struct qstr *obj, } dprintk("%s: parent: %llu, obj: '%s', target_inode: %llu, target_str: '%s', full: '%s'.\n", - __func__, parent->ino, obj->name, (target)?target->ino:0, (tstr)?tstr->name:NULL, + __func__, parent->ino, obj->name, (target) ? target->ino : 0, (tstr) ? tstr->name : NULL, (char *)data); cmd->cmd = NETFS_LINK; -- cgit v1.2.3 From 9b835ea87b43354d6bd053fba7f79cc84b588a3d Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Sun, 14 Mar 2010 18:00:08 +0200 Subject: Staging: pohmelfs: fix comments, spaces and TAB coding style issue in netfs.h This is a patch to the netfs.h file that fixed up a TAB and spaces Errors found by the checkpatch.pl tools, like ERROR: spaces required around that '=' (ctx:VxV) and ERROR: do not use C99 // comments Signed-off-by: Ruslan Pisarev Acked-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/pohmelfs/netfs.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/pohmelfs/netfs.h b/drivers/staging/pohmelfs/netfs.h index 01cba006e07a..35c898a3a9dd 100644 --- a/drivers/staging/pohmelfs/netfs.h +++ b/drivers/staging/pohmelfs/netfs.h @@ -305,7 +305,7 @@ struct pohmelfs_inode { }; struct netfs_trans; -typedef int (* netfs_trans_complete_t)(struct page **pages, unsigned int page_num, +typedef int (*netfs_trans_complete_t)(struct page **pages, unsigned int page_num, void *private, int err); struct netfs_state; @@ -911,7 +911,8 @@ static inline void pohmelfs_mcache_put(struct pohmelfs_sb *psb, pohmelfs_mcache_free(psb, m); } -//#define POHMELFS_TRUNCATE_ON_INODE_FLUSH +/*#define POHMELFS_TRUNCATE_ON_INODE_FLUSH + */ #endif /* __KERNEL__*/ -- cgit v1.2.3 From 75cc5d9c648f6af2362ae4da54f5d237d0cc75ee Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Sun, 14 Mar 2010 18:08:05 +0200 Subject: Staging: pohmelfs: fix spaces and TAB coding style issue in netfs.h This is a patch to the netfs.h file that fixed up a TAB and spaces WARNING found by the checkpatch.pl tools, like WARNING: please, no space before tabs Signed-off-by: Ruslan Pisarev Acked-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/pohmelfs/netfs.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/pohmelfs/netfs.h b/drivers/staging/pohmelfs/netfs.h index 35c898a3a9dd..63391d2c25a4 100644 --- a/drivers/staging/pohmelfs/netfs.h +++ b/drivers/staging/pohmelfs/netfs.h @@ -489,7 +489,7 @@ void pohmelfs_crypto_thread_make_ready(struct pohmelfs_crypto_thread *th); struct netfs_state { struct mutex __state_lock; /* Can not allow to use the same socket simultaneously */ struct mutex __state_send_lock; - struct netfs_cmd cmd; /* Cached command */ + struct netfs_cmd cmd; /* Cached command */ struct netfs_inode_info info; /* Cached inode info */ void *data; /* Cached some data */ @@ -500,9 +500,9 @@ struct netfs_state { struct task_struct *thread; /* Async receiving thread */ /* Waiting/polling machinery */ - wait_queue_t wait; - wait_queue_head_t *whead; - wait_queue_head_t thread_wait; + wait_queue_t wait; + wait_queue_head_t *whead; + wait_queue_head_t thread_wait; struct mutex trans_lock; struct rb_root trans_root; @@ -620,8 +620,8 @@ struct pohmelfs_sb { /* * Timed checks: stale transactions, inodes to be freed and so on. */ - struct delayed_work dwork; - struct delayed_work drop_dwork; + struct delayed_work dwork; + struct delayed_work drop_dwork; struct super_block *sb; -- cgit v1.2.3 From 5d6892b3c6811cfd20e3d71d89fa77f4b6bd089b Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Sun, 14 Mar 2010 17:50:20 +0200 Subject: Staging: pohmelfs: fix spaces and TAB coding style issue in inode.c This is a patch to the inode.c file that fixed up a TAB and spaces Errors found by the checkpatch.pl tools, like ERROR: spaces required around that '=' (ctx:VxV) Signed-off-by: Ruslan Pisarev Acked-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/pohmelfs/inode.c | 64 ++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c index 63275529ff55..9286e863b0e7 100644 --- a/drivers/staging/pohmelfs/inode.c +++ b/drivers/staging/pohmelfs/inode.c @@ -685,7 +685,7 @@ static int pohmelfs_readpages_trans_complete(struct page **__pages, unsigned int goto err_out_free; } - for (i=0; iidx = option; - break; - case pohmelfs_opt_trans_scan_timeout: - psb->trans_scan_timeout = msecs_to_jiffies(option); - break; - case pohmelfs_opt_drop_scan_timeout: - psb->drop_scan_timeout = msecs_to_jiffies(option); - break; - case pohmelfs_opt_wait_on_page_timeout: - psb->wait_on_page_timeout = msecs_to_jiffies(option); - break; - case pohmelfs_opt_mcache_timeout: - psb->mcache_timeout = msecs_to_jiffies(option); - break; - case pohmelfs_opt_trans_retries: - psb->trans_retries = option; - break; - case pohmelfs_opt_crypto_thread_num: - psb->crypto_thread_num = option; - break; - case pohmelfs_opt_trans_max_pages: - psb->trans_max_pages = option; - break; - case pohmelfs_opt_crypto_fail_unsupported: - psb->crypto_fail_unsupported = 1; - break; - default: - return -EINVAL; + case pohmelfs_opt_idx: + psb->idx = option; + break; + case pohmelfs_opt_trans_scan_timeout: + psb->trans_scan_timeout = msecs_to_jiffies(option); + break; + case pohmelfs_opt_drop_scan_timeout: + psb->drop_scan_timeout = msecs_to_jiffies(option); + break; + case pohmelfs_opt_wait_on_page_timeout: + psb->wait_on_page_timeout = msecs_to_jiffies(option); + break; + case pohmelfs_opt_mcache_timeout: + psb->mcache_timeout = msecs_to_jiffies(option); + break; + case pohmelfs_opt_trans_retries: + psb->trans_retries = option; + break; + case pohmelfs_opt_crypto_thread_num: + psb->crypto_thread_num = option; + break; + case pohmelfs_opt_trans_max_pages: + psb->trans_max_pages = option; + break; + case pohmelfs_opt_crypto_fail_unsupported: + psb->crypto_fail_unsupported = 1; + break; + default: + return -EINVAL; } } @@ -1777,7 +1777,7 @@ static int pohmelfs_show_stats(struct seq_file *m, struct vfsmount *mnt) seq_printf(m, "%pi6:%u", &sin->sin6_addr, ntohs(sin->sin6_port)); } else { unsigned int i; - for (i=0; iaddrlen; ++i) + for (i = 0; i < ctl->addrlen; ++i) seq_printf(m, "%02x.", ctl->addr.addr[i]); } @@ -2035,7 +2035,7 @@ err_out_exit: static void __exit exit_pohmel_fs(void) { - unregister_filesystem(&pohmel_fs_type); + unregister_filesystem(&pohmel_fs_type); pohmelfs_destroy_inodecache(); pohmelfs_mcache_exit(); pohmelfs_config_exit(); -- cgit v1.2.3 From 9fd453c981b07f8cd501a938085b901b0c8c0bf5 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 29 Mar 2010 01:24:45 +0100 Subject: Staging: rt28xx: Make PCI_{MAP,UNMAP}_SINGLE type-safe To avoid recurrence of bugs such as , change the type of the first parameter to linux_pci_{map,unmap}_single() from void * to struct rt_rtmp_adapter *. Also do not define the macros PCI_{MAP,UNMAP}_SINGLE() when building the rt2870sta driver; they are not used and if they were that would be a bug. Signed-off-by: Ben Hutchings Cc: Bartlomiej Zolnierkiewicz , Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/rt_linux.h | 14 +++++--------- drivers/staging/rt2860/rt_pci_rbus.c | 12 ++++-------- 2 files changed, 9 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/rt_linux.h b/drivers/staging/rt2860/rt_linux.h index a7c540f8e3e3..b370fb21e423 100644 --- a/drivers/staging/rt2860/rt_linux.h +++ b/drivers/staging/rt2860/rt_linux.h @@ -455,10 +455,11 @@ void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen); * Device DMA Access related definitions and data structures. **********************************************************************************/ #ifdef RTMP_MAC_PCI -dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, - int sd_idx, int direction); -void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, - int direction); +struct rt_rtmp_adapter; +dma_addr_t linux_pci_map_single(struct rt_rtmp_adapter *pAd, void *ptr, + size_t size, int sd_idx, int direction); +void linux_pci_unmap_single(struct rt_rtmp_adapter *pAd, dma_addr_t dma_addr, + size_t size, int direction); #define PCI_MAP_SINGLE(_handle, _ptr, _size, _sd_idx, _dir) \ linux_pci_map_single(_handle, _ptr, _size, _sd_idx, _dir) @@ -475,11 +476,6 @@ void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, #define DEV_ALLOC_SKB(_length) \ dev_alloc_skb(_length) #endif /* RTMP_MAC_PCI // */ -#ifdef RTMP_MAC_USB -#define PCI_MAP_SINGLE(_handle, _ptr, _size, _dir) (unsigned long)0 - -#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir) -#endif /* RTMP_MAC_USB // */ /* * unsigned long diff --git a/drivers/staging/rt2860/rt_pci_rbus.c b/drivers/staging/rt2860/rt_pci_rbus.c index e0a0aeeb17a2..acdf09f148e8 100644 --- a/drivers/staging/rt2860/rt_pci_rbus.c +++ b/drivers/staging/rt2860/rt_pci_rbus.c @@ -790,10 +790,9 @@ IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance) * invaild or writeback cache * and convert virtual address to physical address */ -dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, - int sd_idx, int direction) +dma_addr_t linux_pci_map_single(struct rt_rtmp_adapter *pAd, void *ptr, + size_t size, int sd_idx, int direction) { - struct rt_rtmp_adapter *pAd; struct os_cookie *pObj; /* @@ -812,7 +811,6 @@ dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, sd_idx = -1 */ - pAd = (struct rt_rtmp_adapter *)handle; pObj = (struct os_cookie *)pAd->OS_Cookie; if (sd_idx == 1) { @@ -826,13 +824,11 @@ dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, } -void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, - int direction) +void linux_pci_unmap_single(struct rt_rtmp_adapter *pAd, dma_addr_t dma_addr, + size_t size, int direction) { - struct rt_rtmp_adapter *pAd; struct os_cookie *pObj; - pAd = (struct rt_rtmp_adapter *)handle; pObj = (struct os_cookie *)pAd->OS_Cookie; pci_unmap_single(pObj->pci_dev, dma_addr, size, direction); -- cgit v1.2.3 From cc9b5222f225d03d8815a4d7225f0cbf01755ef3 Mon Sep 17 00:00:00 2001 From: Gorskin Ilya Date: Thu, 18 Mar 2010 14:56:47 +0500 Subject: Staging: rt2860: fix coding style issue in rt_linux.c Signed-off-by: Gorskin Ilya Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/rt_linux.c | 42 +++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c index fd9a2072139b..bfda187d2fbb 100644 --- a/drivers/staging/rt2860/rt_linux.c +++ b/drivers/staging/rt2860/rt_linux.c @@ -82,7 +82,7 @@ char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = { }; /* timeout -- ms */ -void RTMP_SetPeriodicTimer(struct timer_list * pTimer, +void RTMP_SetPeriodicTimer(struct timer_list *pTimer, IN unsigned long timeout) { timeout = ((timeout * OS_HZ) / 1000); @@ -92,7 +92,7 @@ void RTMP_SetPeriodicTimer(struct timer_list * pTimer, /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */ void RTMP_OS_Init_Timer(struct rt_rtmp_adapter *pAd, - struct timer_list * pTimer, + struct timer_list *pTimer, IN TIMER_FUNCTION function, void *data) { init_timer(pTimer); @@ -100,7 +100,7 @@ void RTMP_OS_Init_Timer(struct rt_rtmp_adapter *pAd, pTimer->function = function; } -void RTMP_OS_Add_Timer(struct timer_list * pTimer, +void RTMP_OS_Add_Timer(struct timer_list *pTimer, IN unsigned long timeout) { if (timer_pending(pTimer)) @@ -111,14 +111,14 @@ void RTMP_OS_Add_Timer(struct timer_list * pTimer, add_timer(pTimer); } -void RTMP_OS_Mod_Timer(struct timer_list * pTimer, +void RTMP_OS_Mod_Timer(struct timer_list *pTimer, IN unsigned long timeout) { timeout = ((timeout * OS_HZ) / 1000); mod_timer(pTimer, jiffies + timeout); } -void RTMP_OS_Del_Timer(struct timer_list * pTimer, +void RTMP_OS_Del_Timer(struct timer_list *pTimer, OUT BOOLEAN * pCancelled) { if (timer_pending(pTimer)) { @@ -146,7 +146,7 @@ void RTMPusecDelay(unsigned long usec) udelay(usec % 50); } -void RTMP_GetCurrentSystemTime(LARGE_INTEGER * time) +void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time) { time->u.LowPart = jiffies; } @@ -156,9 +156,9 @@ int os_alloc_mem(struct rt_rtmp_adapter *pAd, u8 ** mem, unsigned long size) { *mem = (u8 *)kmalloc(size, GFP_ATOMIC); if (*mem) - return (NDIS_STATUS_SUCCESS); + return NDIS_STATUS_SUCCESS; else - return (NDIS_STATUS_FAILURE); + return NDIS_STATUS_FAILURE; } /* pAd MUST allow to be NULL */ @@ -167,7 +167,7 @@ int os_free_mem(struct rt_rtmp_adapter *pAd, void *mem) ASSERT(mem); kfree(mem); - return (NDIS_STATUS_SUCCESS); + return NDIS_STATUS_SUCCESS; } void *RtmpOSNetPktAlloc(struct rt_rtmp_adapter *pAd, IN int size) @@ -176,7 +176,7 @@ void *RtmpOSNetPktAlloc(struct rt_rtmp_adapter *pAd, IN int size) /* Add 2 more bytes for ip header alignment */ skb = dev_alloc_skb(size + 2); - return ((void *)skb); + return (void *)skb; } void *RTMP_AllocateFragPacketBuffer(struct rt_rtmp_adapter *pAd, @@ -201,7 +201,7 @@ void *RTMP_AllocateFragPacketBuffer(struct rt_rtmp_adapter *pAd, void *RTMP_AllocateTxPacketBuffer(struct rt_rtmp_adapter *pAd, unsigned long Length, IN BOOLEAN Cached, - void ** VirtualAddress) + void **VirtualAddress) { struct sk_buff *pkt; @@ -271,7 +271,7 @@ void RTMPFreeAdapter(struct rt_rtmp_adapter *pAd) BOOLEAN OS_Need_Clone_Packet(void) { - return (FALSE); + return FALSE; } /* @@ -299,7 +299,7 @@ BOOLEAN OS_Need_Clone_Packet(void) int RTMPCloneNdisPacket(struct rt_rtmp_adapter *pAd, IN BOOLEAN pInsAMSDUHdr, void *pInPacket, - void ** ppOutPacket) + void **ppOutPacket) { struct sk_buff *pkt; @@ -328,7 +328,7 @@ int RTMPCloneNdisPacket(struct rt_rtmp_adapter *pAd, /* the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket() */ int RTMPAllocateNdisPacket(struct rt_rtmp_adapter *pAd, - void ** ppPacket, + void **ppPacket, u8 *pHeader, u32 HeaderLen, u8 *pData, u32 DataLen) @@ -391,7 +391,7 @@ int Sniff2BytesFromNdisBuffer(char *pFirstBuffer, void RTMP_QueryPacketInfo(void *pPacket, struct rt_packet_info *pPacketInfo, - u8 ** pSrcBufVA, u32 * pSrcBufLen) + u8 **pSrcBufVA, u32 * pSrcBufLen) { pPacketInfo->BufferCount = 1; pPacketInfo->pFirstBuffer = (char *)GET_OS_PKT_DATAPTR(pPacket); @@ -402,9 +402,9 @@ void RTMP_QueryPacketInfo(void *pPacket, *pSrcBufLen = GET_OS_PKT_LEN(pPacket); } -void RTMP_QueryNextPacketInfo(void ** ppPacket, +void RTMP_QueryNextPacketInfo(void **ppPacket, struct rt_packet_info *pPacketInfo, - u8 ** pSrcBufVA, u32 * pSrcBufLen) + u8 **pSrcBufVA, u32 * pSrcBufLen) { void *pPacket = NULL; @@ -589,7 +589,7 @@ rt_get_sg_list_from_packet(void *pPacket, struct rt_rtmp_sg_list *sg) sg->NumberOfElements = 1; sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket); sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket); - return (sg); + return sg; } void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen) @@ -1062,7 +1062,7 @@ void RtmpOSTaskCustomize(struct rt_rtmp_os_task *pTask) #ifndef KTHREAD_SUPPORT - daemonize((char *)& pTask->taskName[0] /*"%s",pAd->net_dev->name */ ); + daemonize((char *)&pTask->taskName[0] /*"%s",pAd->net_dev->name */); allow_signal(SIGTERM); allow_signal(SIGKILL); @@ -1247,7 +1247,7 @@ void RtmpOSNetDevFree(struct net_device *pNetDev) free_netdev(pNetDev); } -int RtmpOSNetDevAlloc(struct net_device ** new_dev_p, u32 privDataSize) +int RtmpOSNetDevAlloc(struct net_device **new_dev_p, u32 privDataSize) { /* assign it as null first. */ *new_dev_p = NULL; @@ -1344,7 +1344,7 @@ struct net_device *RtmpOSNetDevCreate(struct rt_rtmp_adapter *pAd, int status; /* allocate a new network device */ - status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize */ ); + status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize */); if (status != NDIS_STATUS_SUCCESS) { /* allocation fail, exit */ DBGPRINT(RT_DEBUG_ERROR, -- cgit v1.2.3 From 52acccb144ef698577a372b60a17e56b686fa064 Mon Sep 17 00:00:00 2001 From: Gorskin Ilya Date: Fri, 19 Mar 2010 22:57:50 +0500 Subject: Staging: rt2860: fix coding style issue in rt_main_dev.c This is a patch to the rt_main_dev.c file that fixes up errors found by the checkpatch.pl tool Signed-off-by: Gorskin Ilya Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/rt_main_dev.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/rt_main_dev.c b/drivers/staging/rt2860/rt_main_dev.c index fbddb00cfedd..ad60ceaf4b88 100644 --- a/drivers/staging/rt2860/rt_main_dev.c +++ b/drivers/staging/rt2860/rt_main_dev.c @@ -439,13 +439,13 @@ int rt28xx_open(struct net_device *dev) RTMPInitPCIeLinkCtrlValue(pAd); #endif /* RTMP_MAC_PCI // */ - return (retval); + return retval; err: /*+++Add by shiang, move from rt28xx_init() to here. */ RtmpOSIRQRelease(net_dev); /*---Add by shiang, move from rt28xx_init() to here. */ - return (-1); + return -1; } /* End of rt28xx_open */ static const struct net_device_ops rt2860_netdev_ops = { @@ -534,7 +534,7 @@ int rt28xx_packet_xmit(struct sk_buff *skb) } RTMP_SET_PACKET_5VT(pPacket, 0); - STASendPackets((void *)pAd, (void **)& pPacket, 1); + STASendPackets((void *)pAd, (void **)&pPacket, 1); status = NETDEV_TX_OK; done: @@ -571,7 +571,7 @@ static int rt28xx_send_packets(IN struct sk_buff *skb_p, return NETDEV_TX_OK; } - NdisZeroMemory((u8 *)& skb_p->cb[CB_OFF], 15); + NdisZeroMemory((u8 *)&skb_p->cb[CB_OFF], 15); RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID); return rt28xx_packet_xmit(skb_p); @@ -628,13 +628,13 @@ void tbtt_tasklet(unsigned long data) ======================================================================== Routine Description: - return ethernet statistics counter + return ethernet statistics counter Arguments: - net_dev Pointer to net_device + net_dev Pointer to net_device Return Value: - net_device_stats* + net_device_stats* Note: @@ -728,9 +728,9 @@ int AdapterBlockAllocateMemory(void *handle, void ** ppAd) if (*ppAd) { NdisZeroMemory(*ppAd, sizeof(struct rt_rtmp_adapter)); - ((struct rt_rtmp_adapter *)* ppAd)->OS_Cookie = handle; - return (NDIS_STATUS_SUCCESS); + ((struct rt_rtmp_adapter *)*ppAd)->OS_Cookie = handle; + return NDIS_STATUS_SUCCESS; } else { - return (NDIS_STATUS_FAILURE); + return NDIS_STATUS_FAILURE; } } -- cgit v1.2.3 From 015ffcbeb3a95bd67fd9851a6428508a2e48837f Mon Sep 17 00:00:00 2001 From: Gorskin Ilya Date: Fri, 19 Mar 2010 23:10:32 +0500 Subject: Staging: rt2860: fix coding style issue in rt_pci_rbus.c This is a patch to the rt_pci_rbus.c file that fixes up errors found by the checkpatch.pl tool Signed-off-by: Gorskin Ilya Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/rt_pci_rbus.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/rt_pci_rbus.c b/drivers/staging/rt2860/rt_pci_rbus.c index acdf09f148e8..3004be6da003 100644 --- a/drivers/staging/rt2860/rt_pci_rbus.c +++ b/drivers/staging/rt2860/rt_pci_rbus.c @@ -81,7 +81,7 @@ void RTMP_AllocateTxDescMemory(struct rt_rtmp_adapter *pAd, u32 Index, unsigned long Length, IN BOOLEAN Cached, - void ** VirtualAddress, + void **VirtualAddress, dma_addr_t *PhysicalAddress) { struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; @@ -96,7 +96,7 @@ void RTMP_AllocateTxDescMemory(struct rt_rtmp_adapter *pAd, void RTMP_AllocateMgmtDescMemory(struct rt_rtmp_adapter *pAd, unsigned long Length, IN BOOLEAN Cached, - void ** VirtualAddress, + void **VirtualAddress, dma_addr_t *PhysicalAddress) { struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; @@ -111,7 +111,7 @@ void RTMP_AllocateMgmtDescMemory(struct rt_rtmp_adapter *pAd, void RTMP_AllocateRxDescMemory(struct rt_rtmp_adapter *pAd, unsigned long Length, IN BOOLEAN Cached, - void ** VirtualAddress, + void **VirtualAddress, dma_addr_t *PhysicalAddress) { struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; @@ -139,7 +139,7 @@ void RTMP_AllocateFirstTxBuffer(struct rt_rtmp_adapter *pAd, u32 Index, unsigned long Length, IN BOOLEAN Cached, - void ** VirtualAddress, + void **VirtualAddress, dma_addr_t *PhysicalAddress) { struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; @@ -173,7 +173,7 @@ void RTMP_FreeFirstTxBuffer(struct rt_rtmp_adapter *pAd, void RTMP_AllocateSharedMemory(struct rt_rtmp_adapter *pAd, unsigned long Length, IN BOOLEAN Cached, - void ** VirtualAddress, + void **VirtualAddress, dma_addr_t *PhysicalAddress) { struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie; @@ -197,7 +197,7 @@ void RTMP_AllocateSharedMemory(struct rt_rtmp_adapter *pAd, void *RTMP_AllocateRxPacketBuffer(struct rt_rtmp_adapter *pAd, unsigned long Length, IN BOOLEAN Cached, - void ** VirtualAddress, + void **VirtualAddress, OUT dma_addr_t * PhysicalAddress) { -- cgit v1.2.3 From 3d401c96e08c8e942306387d6ae82be0cc4de12f Mon Sep 17 00:00:00 2001 From: Gorskin Ilya Date: Fri, 19 Mar 2010 23:22:41 +0500 Subject: Staging: rt2860: fix coding style issue in rt_usb.c This is a patch to the rt_usb.c file that fixes up errors found by the checkpatch.pl tool Signed-off-by: Gorskin Ilya Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/rt_usb.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/rt_usb.c b/drivers/staging/rt2860/rt_usb.c index 01a7eb4e8ba8..bcfc0f54d2aa 100644 --- a/drivers/staging/rt2860/rt_usb.c +++ b/drivers/staging/rt2860/rt_usb.c @@ -233,8 +233,7 @@ static void rtusb_dataout_complete(unsigned long data) FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext); /*RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */ - } else /* STATUS_OTHER */ - { + } else { /* STATUS_OTHER */ u8 *pBuf; pAd->BulkOutCompleteOther++; @@ -316,8 +315,7 @@ static void rtusb_null_frame_done_tasklet(unsigned long data) RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); - } else /* STATUS_OTHER */ - { + } else { /* STATUS_OTHER */ if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && @@ -362,8 +360,7 @@ static void rtusb_rts_frame_done_tasklet(unsigned long data) if (Status == USB_ST_NOERROR) { RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); - } else /* STATUS_OTHER */ - { + } else { /* STATUS_OTHER */ if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && @@ -410,8 +407,7 @@ static void rtusb_pspoll_frame_done_tasklet(unsigned long data) if (Status == USB_ST_NOERROR) { RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); - } else /* STATUS_OTHER */ - { + } else { /* STATUS_OTHER */ if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && @@ -473,14 +469,12 @@ static void rx_done_tasklet(unsigned long data) if (Status == USB_ST_NOERROR) { pAd->BulkInComplete++; pAd->NextRxBulkInPosition = 0; - if (pRxContext->BulkInOffset) /* As jan's comment, it may bulk-in success but size is zero. */ - { + if (pRxContext->BulkInOffset) { /* As jan's comment, it may bulk-in success but size is zero. */ pRxContext->Readable = TRUE; INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE); } RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); - } else /* STATUS_OTHER */ - { + } else { /* STATUS_OTHER */ pAd->BulkInCompleteFail++; /* Still read this packet although it may comtain wrong bytes. */ pRxContext->Readable = FALSE; @@ -584,7 +578,7 @@ static void rtusb_mgmt_dma_done_tasklet(unsigned long data) /* The protectioon of rest bulk should be in BulkOut routine */ if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE - /* pMLMEContext->bWaitingBulkOut == TRUE */ ) { + /* pMLMEContext->bWaitingBulkOut == TRUE */) { RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); } RTUSBKickBulkOut(pAd); -- cgit v1.2.3 From 1995dbabd44a5540a9950512c8b87e888a399c2a Mon Sep 17 00:00:00 2001 From: Gorskin Ilya Date: Sat, 20 Mar 2010 01:18:51 +0500 Subject: Staging: rt2860: fix coding style issue in rt3070.c, rt3090.c, rt30xx.c This is a patch to the rt3070.c, rt3090.c, rt30xx.c files that fixes up errors found by the checkpatch.pl tool Signed-off-by: Gorskin Ilya Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/chips/rt3070.c | 4 ++-- drivers/staging/rt2860/chips/rt3090.c | 4 ++-- drivers/staging/rt2860/chips/rt30xx.c | 9 +++------ 3 files changed, 7 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/chips/rt3070.c b/drivers/staging/rt2860/chips/rt3070.c index 627bad943a3c..3a17fd10ec1f 100644 --- a/drivers/staging/rt2860/chips/rt3070.c +++ b/drivers/staging/rt2860/chips/rt3070.c @@ -56,7 +56,7 @@ void NICInitRT3070RFRegisters(struct rt_rtmp_adapter *pAd) u32 RfReg = 0; u32 data; - RT30xxReadRFRegister(pAd, RF_R30, (u8 *)& RfReg); + RT30xxReadRFRegister(pAd, RF_R30, (u8 *)&RfReg); RfReg |= 0x80; RT30xxWriteRFRegister(pAd, RF_R30, (u8)RfReg); RTMPusecDelay(1000); @@ -84,7 +84,7 @@ void NICInitRT3070RFRegisters(struct rt_rtmp_adapter *pAd) } } else if (IS_RT3071(pAd)) { /* Driver should set RF R6 bit6 on before init RF registers */ - RT30xxReadRFRegister(pAd, RF_R06, (u8 *)& RfReg); + RT30xxReadRFRegister(pAd, RF_R06, (u8 *)&RfReg); RfReg |= 0x40; RT30xxWriteRFRegister(pAd, RF_R06, (u8)RfReg); diff --git a/drivers/staging/rt2860/chips/rt3090.c b/drivers/staging/rt2860/chips/rt3090.c index 5927ba4c5a9b..c2933c69bc04 100644 --- a/drivers/staging/rt2860/chips/rt3090.c +++ b/drivers/staging/rt2860/chips/rt3090.c @@ -53,7 +53,7 @@ void NICInitRT3090RFRegisters(struct rt_rtmp_adapter *pAd) /* Driver should toggle RF R30 bit7 before init RF registers */ u32 RfReg = 0, data; - RT30xxReadRFRegister(pAd, RF_R30, (u8 *)& RfReg); + RT30xxReadRFRegister(pAd, RF_R30, (u8 *)&RfReg); RfReg |= 0x80; RT30xxWriteRFRegister(pAd, RF_R30, (u8)RfReg); RTMPusecDelay(1000); @@ -90,7 +90,7 @@ void NICInitRT3090RFRegisters(struct rt_rtmp_adapter *pAd) } /* Driver should set RF R6 bit6 on before calibration */ - RT30xxReadRFRegister(pAd, RF_R06, (u8 *)& RfReg); + RT30xxReadRFRegister(pAd, RF_R06, (u8 *)&RfReg); RfReg |= 0x40; RT30xxWriteRFRegister(pAd, RF_R06, (u8)RfReg); diff --git a/drivers/staging/rt2860/chips/rt30xx.c b/drivers/staging/rt2860/chips/rt30xx.c index 6e684a3ccf0e..4367a196aeff 100644 --- a/drivers/staging/rt2860/chips/rt30xx.c +++ b/drivers/staging/rt2860/chips/rt30xx.c @@ -170,8 +170,7 @@ void RTMPFilterCalibration(struct rt_rtmp_adapter *pAd) pAd->Mlme.CaliBW40RfR24 = 0x2F; /*Bit[5] must be 1 for BW 40 */ do { - if (loop == 1) /*BandWidth = 40 MHz */ - { + if (loop == 1) { /*BandWidth = 40 MHz */ /* Write 0x27 to RF_R24 to program filter */ RF_R24_Value = 0x27; RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); @@ -190,8 +189,7 @@ void RTMPFilterCalibration(struct rt_rtmp_adapter *pAd) RT30xxReadRFRegister(pAd, RF_R31, &value); value |= 0x20; RT30xxWriteRFRegister(pAd, RF_R31, value); - } else /*BandWidth = 20 MHz */ - { + } else { /*BandWidth = 20 MHz */ /* Write 0x07 to RF_R24 to program filter */ RF_R24_Value = 0x07; RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); @@ -353,8 +351,7 @@ void RT30xxLoadRFNormalModeSetup(struct rt_rtmp_adapter *pAd) RT30xxReadRFRegister(pAd, RF_R27, &RFValue); /* TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F). */ /* Raising RF voltage is no longer needed for RT3070(F) */ - if (IS_RT3090(pAd)) /* RT309x and RT3071/72 */ - { + if (IS_RT3090(pAd)) { /* RT309x and RT3071/72 */ if ((pAd->MACVersion & 0xffff) < 0x0211) RFValue = (RFValue & (~0x77)) | 0x3; else -- cgit v1.2.3 From 5d9ffae0828fd6c74d7e2fe79c94a7cef90fe435 Mon Sep 17 00:00:00 2001 From: Gorskin Ilya Date: Sat, 3 Apr 2010 14:29:13 +0600 Subject: Staging: rt2860: fix coding style issue in mac_pci.h, mac_usb.h, rtmp_mac.h, rtmp_phy.h This is a patch to the mac_pci.h, mac_usb.h, rtmp_mac.h, rtmp_phy.h files that fixes up errors found by the checkpatch.pl tool Signed-off-by: Gorskin Ilya Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/chip/mac_pci.h | 41 ++-- drivers/staging/rt2860/chip/mac_usb.h | 55 +++--- drivers/staging/rt2860/chip/rtmp_mac.h | 52 ++--- drivers/staging/rt2860/chip/rtmp_phy.h | 338 +++++++++++++++------------------ 4 files changed, 221 insertions(+), 265 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/chip/mac_pci.h b/drivers/staging/rt2860/chip/mac_pci.h index bc704acaa3d7..9f25ef047f59 100644 --- a/drivers/staging/rt2860/chip/mac_pci.h +++ b/drivers/staging/rt2860/chip/mac_pci.h @@ -147,13 +147,12 @@ typedef union _TX_ATTENUATION_CTRL_STRUC { /* ----------------- Frimware Related MACRO ----------------- */ #define RTMP_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen) \ - do{ \ + do { \ unsigned long _i, _firm; \ RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x10000); \ \ - for(_i=0; _i<_FwLen; _i+=4) \ - { \ - _firm = _pFwImage[_i] + \ + for (_i = 0; _i < _FwLen; _i += 4) { \ + _firm = _pFwImage[_i] + \ (_pFwImage[_i+3] << 24) + \ (_pFwImage[_i+2] << 16) + \ (_pFwImage[_i+1] << 8); \ @@ -165,19 +164,19 @@ typedef union _TX_ATTENUATION_CTRL_STRUC { /* initialize BBP R/W access agent */ \ RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, 0); \ RTMP_IO_WRITE32(_pAd, H2M_MAILBOX_CSR, 0); \ - }while(0) + } while (0) /* ----------------- TX Related MACRO ----------------- */ -#define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags) do{}while(0) -#define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags) do{}while(0) +#define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags) do {} while (0) +#define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags) do {} while (0) #define RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \ ((freeNum) >= (unsigned long)(pTxBlk->TotalFragNum + RTMP_GET_PACKET_FRAGMENTS(pPacket) + 3)) /* rough estimate we will use 3 more descriptor. */ -#define RTMP_RELEASE_DESC_RESOURCE(pAd, QueIdx) \ - do{}while(0) +#define RTMP_RELEASE_DESC_RESOURCE(pAd, QueIdx) do {} while (0) #define NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, freeNum, _TxFrameType) \ - (((freeNum != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 0)) || (freeNum<3)) + (((freeNum != (TX_RING_SIZE-1)) && \ + (pAd->TxSwQueue[QueIdx].Number == 0)) || (freeNum < 3)) #define HAL_KickOutMgmtTx(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen) \ RtmpPCIMgmtKickOut(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen) @@ -185,19 +184,19 @@ typedef union _TX_ATTENUATION_CTRL_STRUC { #define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \ /* RtmpPCI_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) */ -#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber) \ +#define HAL_WriteTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \ RtmpPCI_WriteSingleTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) #define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \ RtmpPCI_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) -#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber) \ +#define HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber) \ RtmpPCI_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber) #define HAL_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx) \ RtmpPCI_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx) -#define HAL_LastTxIdx(_pAd, _QueIdx,_LastTxIdx) \ +#define HAL_LastTxIdx(_pAd, _QueIdx, _LastTxIdx) \ /*RtmpPCIDataLastTxIdx(_pAd, _QueIdx,_LastTxIdx) */ #define HAL_KickOutTx(_pAd, _pTxBlk, _QueIdx) \ @@ -259,24 +258,24 @@ typedef union _TX_ATTENUATION_CTRL_STRUC { /* Insert the BA bitmap to ASIC for the Wcid entry */ #define RTMP_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID) \ - do{ \ + do { \ u32 _Value = 0, _Offset; \ _Offset = MAC_WCID_BASE + (_Aid) * HW_WCID_ENTRY_SIZE + 4; \ RTMP_IO_READ32((_pAd), _Offset, &_Value);\ _Value |= (0x10000<<(_TID)); \ RTMP_IO_WRITE32((_pAd), _Offset, _Value);\ - }while(0) + } while (0) /* Remove the BA bitmap from ASIC for the Wcid entry */ /* bitmap field starts at 0x10000 in ASIC WCID table */ #define RTMP_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID) \ - do{ \ + do { \ u32 _Value = 0, _Offset; \ _Offset = MAC_WCID_BASE + (_Wcid) * HW_WCID_ENTRY_SIZE + 4; \ RTMP_IO_READ32((_pAd), _Offset, &_Value); \ _Value &= (~(0x10000 << (_TID))); \ RTMP_IO_WRITE32((_pAd), _Offset, _Value); \ - }while(0) + } while (0) /* ----------------- Interface Related MACRO ----------------- */ @@ -285,16 +284,16 @@ typedef union _TX_ATTENUATION_CTRL_STRUC { /* Since it use ADAPTER structure, it have to be put after structure definition. */ /* */ #define RTMP_ASIC_INTERRUPT_DISABLE(_pAd) \ - do{ \ + do { \ RTMP_IO_WRITE32((_pAd), INT_MASK_CSR, 0x0); /* 0: disable */ \ RTMP_CLEAR_FLAG((_pAd), fRTMP_ADAPTER_INTERRUPT_ACTIVE); \ - }while(0) + } while (0) #define RTMP_ASIC_INTERRUPT_ENABLE(_pAd)\ - do{ \ + do { \ RTMP_IO_WRITE32((_pAd), INT_MASK_CSR, (_pAd)->int_enable_reg /*DELAYINTMASK*/); /* 1:enable */ \ RTMP_SET_FLAG((_pAd), fRTMP_ADAPTER_INTERRUPT_ACTIVE); \ - }while(0) + } while (0) #define RTMP_IRQ_INIT(pAd) \ { pAd->int_enable_reg = ((DELAYINTMASK) | \ diff --git a/drivers/staging/rt2860/chip/mac_usb.h b/drivers/staging/rt2860/chip/mac_usb.h index 0b67c0b1de03..ed0c0b43b05e 100644 --- a/drivers/staging/rt2860/chip/mac_usb.h +++ b/drivers/staging/rt2860/chip/mac_usb.h @@ -25,7 +25,7 @@ ************************************************************************* Module Name: - mac_usb.h + mac_usb.h Abstract: @@ -46,7 +46,7 @@ #define USB_CYC_CFG 0x02a4 #define BEACON_RING_SIZE 2 -#define MGMTPIPEIDX 0 /* EP6 is highest priority */ +#define MGMTPIPEIDX 0 /* EP6 is highest priority */ #define RTMP_PKT_TAIL_PADDING 11 /* 3(max 4 byte padding) + 4 (last packet padding) + 4 (MaxBulkOutsize align padding) */ @@ -220,53 +220,51 @@ struct rt_rx_context { ******************************************************************************/ #define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags) \ - do{ \ + do { \ RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \ - if (pAd->DeQueueRunning[QueIdx]) \ - { \ - RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\ + if (pAd->DeQueueRunning[QueIdx]) { \ + RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \ DBGPRINT(RT_DEBUG_OFF, ("DeQueueRunning[%d]= TRUE!\n", QueIdx)); \ continue; \ - } \ - else \ - { \ + } else { \ pAd->DeQueueRunning[QueIdx] = TRUE; \ RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\ } \ - }while(0) + } while (0) #define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags) \ - do{ \ + do { \ RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \ pAd->DeQueueRunning[QueIdx] = FALSE; \ RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \ - }while(0) + } while (0) #define RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \ (RTUSBFreeDescriptorRequest(pAd, pTxBlk->QueIdx, (pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))) == NDIS_STATUS_SUCCESS) #define RTMP_RELEASE_DESC_RESOURCE(pAd, QueIdx) \ - do{}while(0) + do {} while (0) #define NEED_QUEUE_BACK_FOR_AGG(_pAd, _QueIdx, _freeNum, _TxFrameType) \ - ((_TxFrameType == TX_RALINK_FRAME) && (RTUSBNeedQueueBackForAgg(_pAd, _QueIdx))) + ((_TxFrameType == TX_RALINK_FRAME) && \ + (RTUSBNeedQueueBackForAgg(_pAd, _QueIdx))) #define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \ - RtmpUSB_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) + RtmpUSB_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) -#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber) \ - RtmpUSB_WriteSingleTxResource(pAd, pTxBlk,bIsLast, pFreeNumber) +#define HAL_WriteTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \ + RtmpUSB_WriteSingleTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) #define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \ - RtmpUSB_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) + RtmpUSB_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) -#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber) \ - RtmpUSB_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber) +#define HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber) \ + RtmpUSB_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber) #define HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx) \ - RtmpUSB_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx) + RtmpUSB_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx) -#define HAL_LastTxIdx(pAd, QueIdx,TxIdx) \ +#define HAL_LastTxIdx(pAd, QueIdx, TxIdx) \ /*RtmpUSBDataLastTxIdx(pAd, QueIdx,TxIdx) */ #define HAL_KickOutTx(pAd, pTxBlk, QueIdx) \ @@ -286,8 +284,8 @@ struct rt_rx_context { /* * Device Hardware Interface Related MACRO */ -#define RTMP_IRQ_INIT(pAd) do{}while(0) -#define RTMP_IRQ_ENABLE(pAd) do{}while(0) +#define RTMP_IRQ_INIT(pAd) do {} while (0) +#define RTMP_IRQ_ENABLE(pAd) do {} while (0) /* * MLME Related MACRO @@ -305,8 +303,8 @@ struct rt_rx_context { RTUSBMlmeUp(pAd); } #define RTMP_MLME_RESET_STATE_MACHINE(pAd) \ - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_RESET_CONF, 0, NULL); \ - RTUSBMlmeUp(pAd); + { MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_RESET_CONF, 0, NULL); \ + RTUSBMlmeUp(pAd); } #define RTMP_HANDLE_COUNTER_MEASURE(_pAd, _pEntry) \ { RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_802_11_COUNTER_MEASURE, _pEntry, sizeof(struct rt_mac_table_entry)); \ @@ -330,12 +328,11 @@ struct rt_rx_context { {\ if ((_pAd)->StaCfg.WindowsPowerMode == Ndis802_11PowerModeFast_PSP) \ MlmeSetPsmBit(_pAd, _val);\ - else \ - { \ + else { \ u16 _psm_val; \ _psm_val = _val; \ RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_SET_PSM_BIT, &(_psm_val), sizeof(u16)); \ - }\ + } \ } #define RTMP_MLME_RADIO_ON(pAd) \ diff --git a/drivers/staging/rt2860/chip/rtmp_mac.h b/drivers/staging/rt2860/chip/rtmp_mac.h index f6a72581d3bd..e8f7172ce42a 100644 --- a/drivers/staging/rt2860/chip/rtmp_mac.h +++ b/drivers/staging/rt2860/chip/rtmp_mac.h @@ -154,7 +154,7 @@ typedef union _INT_SOURCE_CSR_STRUC { u32 GPTimer:1; u32 RxCoherent:1; /*bit16 */ u32 TxCoherent:1; - u32 : 14; + u32: 14; } field; u32 word; } INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC; @@ -175,7 +175,7 @@ typedef union _INT_MASK_CSR_STRUC { u32 HccaDmaDone:1; u32 MgmtDmaDone:1; u32 MCUCommandINT:1; - u32 : 20; + u32: 20; u32 RxCoherent:1; u32 TxCoherent:1; } field; @@ -209,7 +209,7 @@ typedef union _WPDMA_RST_IDX_STRUC { u32 RST_DTX_IDX5:1; u32 rsv:10; u32 RST_DRX_IDX0:1; - u32 : 15; + u32: 15; } field; u32 word; } WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC; @@ -448,7 +448,7 @@ typedef union _BBP_CSR_CFG_STRUC { u32 Busy:1; /* 1: ASIC is busy execute BBP programming. */ u32 BBP_PAR_DUR:1; /* 0: 4 MAC clock cycles 1: 8 MAC clock cycles */ u32 BBP_RW_MODE:1; /* 0: use serial mode 1:parallel */ - u32 : 12; + u32: 12; } field; u32 word; } BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC; @@ -494,7 +494,7 @@ typedef union _LED_CFG_STRUC { u32 GLedMode:2; /* green Led Mode */ u32 YLedMode:2; /* yellow Led Mode */ u32 LedPolar:1; /* Led Polarity. 0: active low1: active high */ - u32 : 1; + u32: 1; } field; u32 word; } LED_CFG_STRUC, *PLED_CFG_STRUC; @@ -533,7 +533,7 @@ typedef union _BCN_TIME_CFG_STRUC { u32 TsfSyncMode:2; /* Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode */ u32 bTBTTEnable:1; u32 bBeaconGen:1; /* Enable beacon generator */ - u32 : 3; + u32: 3; u32 TxTimestampCompensate:8; } field; u32 word; @@ -560,7 +560,7 @@ typedef union _AUTO_WAKEUP_STRUC { u32 AutoLeadTime:8; u32 NumofSleepingTbtt:7; /* ForceWake has high privilege than PutToSleep when both set */ u32 EnableAutoWakeup:1; /* 0:sleep, 1:awake */ - u32 : 16; + u32: 16; } field; u32 word; } AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC; @@ -578,7 +578,7 @@ typedef union _EDCA_AC_CFG_STRUC { u32 Aifsn:4; /* # of slot time */ u32 Cwmin:4; /* */ u32 Cwmax:4; /*unit power of 2 */ - u32 : 12; /* */ + u32: 12; /* */ } field; u32 word; } EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC; @@ -751,7 +751,7 @@ typedef union _AUTO_RSP_CFG_STRUC { u32 rsv:1; /* Power bit value in conrtrol frame */ u32 DualCTSEn:1; /* Power bit value in conrtrol frame */ u32 AckCtsPsmBit:1; /* Power bit value in conrtrol frame */ - u32 : 24; + u32: 24; } field; u32 word; } AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC; @@ -981,21 +981,21 @@ typedef union _MPDU_DEN_CNT_STRUC { typedef union _SHAREDKEY_MODE_STRUC { struct { u32 Bss0Key0CipherAlg:3; - u32 : 1; + u32: 1; u32 Bss0Key1CipherAlg:3; - u32 : 1; + u32: 1; u32 Bss0Key2CipherAlg:3; - u32 : 1; + u32: 1; u32 Bss0Key3CipherAlg:3; - u32 : 1; + u32: 1; u32 Bss1Key0CipherAlg:3; - u32 : 1; + u32: 1; u32 Bss1Key1CipherAlg:3; - u32 : 1; + u32: 1; u32 Bss1Key2CipherAlg:3; - u32 : 1; + u32: 1; u32 Bss1Key3CipherAlg:3; - u32 : 1; + u32: 1; } field; u32 word; } SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC; @@ -1103,7 +1103,7 @@ typedef union _RX_FILTR_CFG_STRUC { u32 DropBAR:1; /* */ u32 DropRsvCntlType:1; - u32 : 15; + u32: 15; } field; u32 word; } RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC; @@ -1128,21 +1128,21 @@ typedef union _PHY_CSR4_STRUC { typedef union _SEC_CSR5_STRUC { struct { u32 Bss2Key0CipherAlg:3; - u32 : 1; + u32: 1; u32 Bss2Key1CipherAlg:3; - u32 : 1; + u32: 1; u32 Bss2Key2CipherAlg:3; - u32 : 1; + u32: 1; u32 Bss2Key3CipherAlg:3; - u32 : 1; + u32: 1; u32 Bss3Key0CipherAlg:3; - u32 : 1; + u32: 1; u32 Bss3Key1CipherAlg:3; - u32 : 1; + u32: 1; u32 Bss3Key2CipherAlg:3; - u32 : 1; + u32: 1; u32 Bss3Key3CipherAlg:3; - u32 : 1; + u32: 1; } field; u32 word; } SEC_CSR5_STRUC, *PSEC_CSR5_STRUC; diff --git a/drivers/staging/rt2860/chip/rtmp_phy.h b/drivers/staging/rt2860/chip/rtmp_phy.h index 8b8b0f47f03b..9f924ea6ca35 100644 --- a/drivers/staging/rt2860/chip/rtmp_phy.h +++ b/drivers/staging/rt2860/chip/rtmp_phy.h @@ -177,8 +177,7 @@ #ifdef RTMP_MAC_PCI #define RTMP_RF_IO_WRITE32(_A, _V) \ { \ - if ((_A)->bPCIclkOff == FALSE) \ - { \ + if ((_A)->bPCIclkOff == FALSE) { \ PHY_CSR4_STRUC _value; \ unsigned long _busyCnt = 0; \ \ @@ -187,9 +186,8 @@ if (_value.field.Busy == IDLE) \ break; \ _busyCnt++; \ - }while (_busyCnt < MAX_BUSY_COUNT); \ - if(_busyCnt < MAX_BUSY_COUNT) \ - { \ + } while (_busyCnt < MAX_BUSY_COUNT); \ + if (_busyCnt < MAX_BUSY_COUNT) { \ RTMP_IO_WRITE32((_A), RF_CSR_CFG0, (_V)); \ } \ } \ @@ -218,52 +216,46 @@ _bViaMCU: if we need access the bbp via the MCU. */ #define RTMP_BBP_IO_READ8(_pAd, _bbpID, _pV, _bViaMCU) \ - do{ \ - BBP_CSR_CFG_STRUC BbpCsr; \ - int _busyCnt, _secCnt, _regID; \ - \ - _regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG); \ - for (_busyCnt=0; _busyCntBbpWriteLatch[_bbpID]; \ - if ((_bViaMCU) == TRUE) \ - { \ + if ((_bViaMCU) == TRUE) { \ RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \ BbpCsr.field.Busy = 0; \ RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word); \ } \ } \ - }while(0) + } while (0) /* This marco used for the BBP read operation which didn't need via MCU. @@ -283,42 +275,35 @@ int i, k; \ BOOLEAN brc; \ BbpCsr.field.Busy = IDLE; \ - if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \ + if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) \ + && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \ && ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE) \ && ((_A)->bPCIclkOff == FALSE) \ - && ((_A)->brt30xxBanMcuCmd == FALSE)) \ - { \ - for (i=0; ibrt30xxBanMcuCmd == FALSE)) { \ + for (i = 0; i < MAX_BUSY_COUNT; i++) { \ + RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \ + if (BbpCsr.field.Busy == BUSY) { \ + continue; \ + } \ + BbpCsr.word = 0; \ + BbpCsr.field.fRead = 1; \ + BbpCsr.field.BBP_RW_MODE = 1; \ + BbpCsr.field.Busy = 1; \ + BbpCsr.field.RegNum = _I; \ + RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \ + brc = AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \ + if (brc == TRUE) { \ + for (k = 0; k < MAX_BUSY_COUNT; k++) { \ + RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \ + if (BbpCsr.field.Busy == IDLE) \ + break; \ + } \ + if ((BbpCsr.field.Busy == IDLE) && \ + (BbpCsr.field.RegNum == _I)) { \ + *(_pV) = (u8)BbpCsr.field.Value; \ + break; \ + } \ + } else { \ BbpCsr.field.Busy = 0; \ RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \ } \ @@ -326,46 +311,38 @@ } \ else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \ && ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)) \ - && ((_A)->bPCIclkOff == FALSE)) \ - { \ - for (i=0; ibPCIclkOff == FALSE)) { \ + for (i = 0; i < MAX_BUSY_COUNT; i++) { \ + RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \ + if (BbpCsr.field.Busy == BUSY) { \ + continue; \ + } \ + BbpCsr.word = 0; \ + BbpCsr.field.fRead = 1; \ + BbpCsr.field.BBP_RW_MODE = 1; \ + BbpCsr.field.Busy = 1; \ + BbpCsr.field.RegNum = _I; \ + RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \ + AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \ + for (k = 0; k < MAX_BUSY_COUNT; k++) { \ + RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \ + if (BbpCsr.field.Busy == IDLE) \ + break; \ + } \ + if ((BbpCsr.field.Busy == IDLE) && \ + (BbpCsr.field.RegNum == _I)) { \ + *(_pV) = (u8)BbpCsr.field.Value; \ + break; \ + } \ + } \ + } else { \ DBGPRINT_ERR((" , brt30xxBanMcuCmd = %d, Read BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I))); \ - *(_pV) = (_A)->BbpWriteLatch[_I]; \ - } \ - if ((BbpCsr.field.Busy == BUSY) || ((_A)->bPCIclkOff == TRUE)) \ - { \ - DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", _I, BbpCsr.word)); \ - *(_pV) = (_A)->BbpWriteLatch[_I]; \ - } \ + *(_pV) = (_A)->BbpWriteLatch[_I]; \ + } \ + if ((BbpCsr.field.Busy == BUSY) || ((_A)->bPCIclkOff == TRUE)) { \ + DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", _I, BbpCsr.word)); \ + *(_pV) = (_A)->BbpWriteLatch[_I]; \ + } \ } /* @@ -376,43 +353,39 @@ _bViaMCU: if we need access the bbp via the MCU. */ #define RTMP_BBP_IO_WRITE8(_pAd, _bbpID, _pV, _bViaMCU) \ - do{ \ + do { \ BBP_CSR_CFG_STRUC BbpCsr; \ - int _busyCnt, _regID; \ - \ + int _busyCnt, _regID; \ + \ _regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG); \ - for (_busyCnt=0; _busyCntOpMode == OPMODE_AP) \ - RTMPusecDelay(1000); \ - } \ - (_pAd)->BbpWriteLatch[_bbpID] = _pV; \ - break; \ - } \ - if (_busyCnt == MAX_BUSY_COUNT) \ - { \ - DBGPRINT_ERR(("BBP write R%d fail\n", _bbpID)); \ - if((_bViaMCU) == TRUE) \ - { \ + if (BbpCsr.field.Busy == BUSY) \ + continue; \ + BbpCsr.word = 0; \ + BbpCsr.field.fRead = 0; \ + BbpCsr.field.BBP_RW_MODE = 1; \ + BbpCsr.field.Busy = 1; \ + BbpCsr.field.Value = _pV; \ + BbpCsr.field.RegNum = _bbpID; \ + RTMP_IO_WRITE32((_pAd), BBP_CSR_CFG, BbpCsr.word); \ + if ((_bViaMCU) == TRUE) { \ + AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0); \ + if ((_pAd)->OpMode == OPMODE_AP) \ + RTMPusecDelay(1000); \ + } \ + (_pAd)->BbpWriteLatch[_bbpID] = _pV; \ + break; \ + } \ + if (_busyCnt == MAX_BUSY_COUNT) { \ + DBGPRINT_ERR(("BBP write R%d fail\n", _bbpID)); \ + if ((_bViaMCU) == TRUE) { \ RTMP_IO_READ32(_pAd, H2M_BBP_AGENT, &BbpCsr.word); \ - BbpCsr.field.Busy = 0; \ + BbpCsr.field.Busy = 0; \ RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, BbpCsr.word); \ - } \ - } \ - }while(0) + } \ + } \ + } while (0) /* This marco used for the BBP write operation which didn't need via MCU. @@ -426,25 +399,22 @@ will use this function too and didn't access the bbp register via the MCU. */ /* Write BBP register by register's ID & value */ -#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) \ -{ \ - BBP_CSR_CFG_STRUC BbpCsr; \ - int BusyCnt = 0; \ +#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) \ +{ \ + BBP_CSR_CFG_STRUC BbpCsr; \ + int BusyCnt = 0; \ BOOLEAN brc; \ - if (_I < MAX_NUM_OF_BBP_LATCH) \ - { \ - if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \ + if (_I < MAX_NUM_OF_BBP_LATCH) { \ + if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) \ + && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \ && ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE) \ && ((_A)->bPCIclkOff == FALSE) \ - && ((_A)->brt30xxBanMcuCmd == FALSE)) \ - { \ - if (_A->AccessBBPFailCount > 20) \ - { \ - AsicResetBBPAgent(_A); \ - _A->AccessBBPFailCount = 0; \ - } \ - for (BusyCnt=0; BusyCntbrt30xxBanMcuCmd == FALSE)) { \ + if (_A->AccessBBPFailCount > 20) { \ + AsicResetBBPAgent(_A); \ + _A->AccessBBPFailCount = 0; \ + } \ + for (BusyCnt = 0; BusyCnt < MAX_BUSY_COUNT; BusyCnt++) { \ RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \ if (BbpCsr.field.Busy == BUSY) \ continue; \ @@ -456,29 +426,24 @@ BbpCsr.field.RegNum = _I; \ RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \ brc = AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \ - if (brc == TRUE) \ - { \ + if (brc == TRUE) { \ (_A)->BbpWriteLatch[_I] = _V; \ - } \ - else \ - { \ + } else { \ BbpCsr.field.Busy = 0; \ RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \ } \ break; \ } \ } \ - else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \ + else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) \ + && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \ && ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)) \ - && ((_A)->bPCIclkOff == FALSE)) \ - { \ - if (_A->AccessBBPFailCount > 20) \ - { \ - AsicResetBBPAgent(_A); \ - _A->AccessBBPFailCount = 0; \ - } \ - for (BusyCnt=0; BusyCntbPCIclkOff == FALSE)) { \ + if (_A->AccessBBPFailCount > 20) { \ + AsicResetBBPAgent(_A); \ + _A->AccessBBPFailCount = 0; \ + } \ + for (BusyCnt = 0; BusyCnt < MAX_BUSY_COUNT; BusyCnt++) { \ RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \ if (BbpCsr.field.Busy == BUSY) \ continue; \ @@ -493,20 +458,15 @@ (_A)->BbpWriteLatch[_I] = _V; \ break; \ } \ - } \ - else \ - { \ + } else { \ DBGPRINT_ERR((" brt30xxBanMcuCmd = %d. Write BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I))); \ } \ - if ((BusyCnt == MAX_BUSY_COUNT) || ((_A)->bPCIclkOff == TRUE)) \ - { \ - if (BusyCnt == MAX_BUSY_COUNT) \ + if ((BusyCnt == MAX_BUSY_COUNT) || ((_A)->bPCIclkOff == TRUE)) { \ + if (BusyCnt == MAX_BUSY_COUNT) \ (_A)->AccessBBPFailCount++; \ - DBGPRINT_ERR(("BBP write R%d=0x%x fail. BusyCnt= %d.bPCIclkOff = %d. \n", _I, BbpCsr.word, BusyCnt, (_A)->bPCIclkOff )); \ + DBGPRINT_ERR(("BBP write R%d=0x%x fail. BusyCnt= %d.bPCIclkOff = %d. \n", _I, BbpCsr.word, BusyCnt, (_A)->bPCIclkOff)); \ } \ - } \ - else \ - { \ + } else { \ DBGPRINT_ERR(("****** BBP_Write_Latch Buffer exceeds max boundry ****** \n")); \ } \ } @@ -522,7 +482,7 @@ #ifdef RT30xx #define RTMP_ASIC_MMPS_DISABLE(_pAd) \ - do{ \ + do { \ u32 _macData; \ u8 _bbpData = 0; \ /* disable MMPS BBP control register */ \ @@ -534,10 +494,10 @@ RTMP_IO_READ32(_pAd, 0x1210, &_macData); \ _macData &= ~(0x09); /*bit 0, 3*/ \ RTMP_IO_WRITE32(_pAd, 0x1210, _macData); \ - }while(0) + } while (0) #define RTMP_ASIC_MMPS_ENABLE(_pAd) \ - do{ \ + do { \ u32 _macData; \ u8 _bbpData = 0; \ /* enable MMPS BBP control register */ \ @@ -549,7 +509,7 @@ RTMP_IO_READ32(_pAd, 0x1210, &_macData); \ _macData |= (0x09); /*bit 0, 3*/ \ RTMP_IO_WRITE32(_pAd, 0x1210, _macData); \ - }while(0) + } while (0) #endif /* RT30xx // */ -- cgit v1.2.3 From a3327f07987468794f4afc602790aca6856e1a5a Mon Sep 17 00:00:00 2001 From: Trey Evans Date: Mon, 19 Apr 2010 16:15:37 -0400 Subject: Staging: rt2860: fix usb_main_dev.c style errors Correct several style errors related to pointers in usb_main_dev.c. Signed-off-by: Trey Evans Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/usb_main_dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/usb_main_dev.c b/drivers/staging/rt2860/usb_main_dev.c index 1873a79bb033..abe9f241ff93 100644 --- a/drivers/staging/rt2860/usb_main_dev.c +++ b/drivers/staging/rt2860/usb_main_dev.c @@ -153,7 +153,7 @@ static void rt2870_disconnect(struct usb_device *dev, struct rt_rtmp_adapter *pA static int __devinit rt2870_probe(IN struct usb_interface *intf, IN struct usb_device *usb_dev, IN const struct usb_device_id *dev_id, - struct rt_rtmp_adapter ** ppAd); + struct rt_rtmp_adapter **ppAd); #ifndef PF_NOFREEZE #define PF_NOFREEZE 0 @@ -801,7 +801,7 @@ static void rt2870_disconnect(struct usb_device *dev, struct rt_rtmp_adapter *pA static int __devinit rt2870_probe(IN struct usb_interface *intf, IN struct usb_device *usb_dev, IN const struct usb_device_id *dev_id, - struct rt_rtmp_adapter ** ppAd) + struct rt_rtmp_adapter **ppAd) { struct net_device *net_dev = NULL; struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)NULL; -- cgit v1.2.3 From fdb2fd14c71e51472e1025d58b0322f75503f8c3 Mon Sep 17 00:00:00 2001 From: Neil Munro Date: Tue, 20 Apr 2010 01:06:33 +0100 Subject: Staging: rt2860: rtmp.h: Fixed all bar one error. All simple errors have been removed, including +80 line character limits and various pointer syntax isues. Signed-off-by: Neil Munro Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/rtmp.h | 410 ++++++++++++++++++++---------------------- 1 file changed, 197 insertions(+), 213 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/rtmp.h b/drivers/staging/rt2860/rtmp.h index 4401a55bda67..ab525ee15042 100644 --- a/drivers/staging/rt2860/rtmp.h +++ b/drivers/staging/rt2860/rtmp.h @@ -181,8 +181,7 @@ struct rt_queue_header { (QueueHeader)->Head; \ { \ struct rt_queue_entry *pNext; \ - if ((QueueHeader)->Head != NULL) \ - { \ + if ((QueueHeader)->Head != NULL) { \ pNext = (QueueHeader)->Head->Next; \ (QueueHeader)->Head->Next = NULL; \ (QueueHeader)->Head = pNext; \ @@ -242,9 +241,9 @@ struct rt_queue_header { #define OPSTATUS_CLEAR_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags &= ~(_F)) #define OPSTATUS_TEST_FLAG(_pAd, _F) (((_pAd)->CommonCfg.OpStatusFlags & (_F)) != 0) -#define CLIENT_STATUS_SET_FLAG(_pEntry,_F) ((_pEntry)->ClientStatusFlags |= (_F)) -#define CLIENT_STATUS_CLEAR_FLAG(_pEntry,_F) ((_pEntry)->ClientStatusFlags &= ~(_F)) -#define CLIENT_STATUS_TEST_FLAG(_pEntry,_F) (((_pEntry)->ClientStatusFlags & (_F)) != 0) +#define CLIENT_STATUS_SET_FLAG(_pEntry, _F) ((_pEntry)->ClientStatusFlags |= (_F)) +#define CLIENT_STATUS_CLEAR_FLAG(_pEntry, _F) ((_pEntry)->ClientStatusFlags &= ~(_F)) +#define CLIENT_STATUS_TEST_FLAG(_pEntry, _F) (((_pEntry)->ClientStatusFlags & (_F)) != 0) #define RX_FILTER_SET_FLAG(_pAd, _F) ((_pAd)->CommonCfg.PacketFilter |= (_F)) #define RX_FILTER_CLEAR_FLAG(_pAd, _F) ((_pAd)->CommonCfg.PacketFilter &= ~(_F)) @@ -279,13 +278,13 @@ struct rt_queue_header { _pAd->StaActive.SupportedHtPhy.RecomWidth = _pAd->MlmeAux.AddHtInfo.AddHtInfo.RecomWidth; \ _pAd->StaActive.SupportedHtPhy.OperaionMode = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode; \ _pAd->StaActive.SupportedHtPhy.NonGfPresent = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent; \ - NdisMoveMemory((_pAd)->MacTab.Content[BSSID_WCID].HTCapability.MCSSet, (_pAd)->StaActive.SupportedPhyInfo.MCSSet, sizeof(u8)* 16);\ + NdisMoveMemory((_pAd)->MacTab.Content[BSSID_WCID].HTCapability.MCSSet, (_pAd)->StaActive.SupportedPhyInfo.MCSSet, sizeof(u8) * 16);\ } #define COPY_AP_HTSETTINGS_FROM_BEACON(_pAd, _pHtCapability) \ { \ _pAd->MacTab.Content[BSSID_WCID].AMsduSize = (u8)(_pHtCapability->HtCapInfo.AMsduSize); \ - _pAd->MacTab.Content[BSSID_WCID].MmpsMode= (u8)(_pHtCapability->HtCapInfo.MimoPs); \ + _pAd->MacTab.Content[BSSID_WCID].MmpsMode = (u8)(_pHtCapability->HtCapInfo.MimoPs); \ _pAd->MacTab.Content[BSSID_WCID].MaxRAmpduFactor = (u8)(_pHtCapability->HtCapParm.MaxRAmpduFactor); \ } @@ -349,17 +348,14 @@ struct rt_rtmp_sg_list { /* if orginal Ethernet frame contains no LLC/SNAP, then an extra LLC/SNAP encap is required */ #define EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(_pBufVA, _pExtraLlcSnapEncap) \ { \ - if (((*(_pBufVA + 12) << 8) + *(_pBufVA + 13)) > 1500) \ - { \ + if (((*(_pBufVA + 12) << 8) + *(_pBufVA + 13)) > 1500) { \ _pExtraLlcSnapEncap = SNAP_802_1H; \ if (NdisEqualMemory(IPX, _pBufVA + 12, 2) || \ - NdisEqualMemory(APPLE_TALK, _pBufVA + 12, 2)) \ - { \ + NdisEqualMemory(APPLE_TALK, _pBufVA + 12, 2)) { \ _pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL; \ } \ } \ - else \ - { \ + else { \ _pExtraLlcSnapEncap = NULL; \ } \ } @@ -367,17 +363,14 @@ struct rt_rtmp_sg_list { /* New Define for new Tx Path. */ #define EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(_pBufVA, _pExtraLlcSnapEncap) \ { \ - if (((*(_pBufVA) << 8) + *(_pBufVA + 1)) > 1500) \ - { \ + if (((*(_pBufVA) << 8) + *(_pBufVA + 1)) > 1500) { \ _pExtraLlcSnapEncap = SNAP_802_1H; \ if (NdisEqualMemory(IPX, _pBufVA, 2) || \ - NdisEqualMemory(APPLE_TALK, _pBufVA, 2)) \ - { \ + NdisEqualMemory(APPLE_TALK, _pBufVA, 2)) { \ _pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL; \ } \ } \ - else \ - { \ + else { \ _pExtraLlcSnapEncap = NULL; \ } \ } @@ -399,33 +392,29 @@ struct rt_rtmp_sg_list { #define CONVERT_TO_802_3(_p8023hdr, _pDA, _pSA, _pData, _DataSize, _pRemovedLLCSNAP) \ { \ char LLC_Len[2]; \ - \ + \ _pRemovedLLCSNAP = NULL; \ if (NdisEqualMemory(SNAP_802_1H, _pData, 6) || \ - NdisEqualMemory(SNAP_BRIDGE_TUNNEL, _pData, 6)) \ - { \ - u8 *pProto = _pData + 6; \ - \ - if ((NdisEqualMemory(IPX, pProto, 2) || NdisEqualMemory(APPLE_TALK, pProto, 2)) && \ - NdisEqualMemory(SNAP_802_1H, _pData, 6)) \ - { \ - LLC_Len[0] = (u8)(_DataSize / 256); \ - LLC_Len[1] = (u8)(_DataSize % 256); \ - MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len); \ - } \ - else \ - { \ - MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, pProto); \ - _pRemovedLLCSNAP = _pData; \ - _DataSize -= LENGTH_802_1_H; \ - _pData += LENGTH_802_1_H; \ - } \ + NdisEqualMemory(SNAP_BRIDGE_TUNNEL, _pData, 6)) { \ + u8 *pProto = _pData + 6; \ + \ + if ((NdisEqualMemory(IPX, pProto, 2) || NdisEqualMemory(APPLE_TALK, pProto, 2)) && \ + NdisEqualMemory(SNAP_802_1H, _pData, 6)) { \ + LLC_Len[0] = (u8)(_DataSize / 256); \ + LLC_Len[1] = (u8)(_DataSize % 256); \ + MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len); \ + } \ + else { \ + MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, pProto); \ + _pRemovedLLCSNAP = _pData; \ + _DataSize -= LENGTH_802_1_H; \ + _pData += LENGTH_802_1_H; \ + } \ } \ - else \ - { \ - LLC_Len[0] = (u8)(_DataSize / 256); \ - LLC_Len[1] = (u8)(_DataSize % 256); \ - MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len); \ + else { \ + LLC_Len[0] = (u8)(_DataSize / 256); \ + LLC_Len[1] = (u8)(_DataSize % 256); \ + MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len); \ } \ } @@ -438,19 +427,19 @@ struct rt_rtmp_sg_list { u32 High32TSF, Low32TSF; \ RTMP_IO_READ32(_pAd, TSF_TIMER_DW1, &High32TSF); \ RTMP_IO_READ32(_pAd, TSF_TIMER_DW0, &Low32TSF); \ - MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (u8)_Rssi0, (u8)_Rssi1,(u8)_Rssi2,_FrameSize, _pFrame, (u8)_PlcpSignal); \ + MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (u8)_Rssi0, (u8)_Rssi1, (u8)_Rssi2, _FrameSize, _pFrame, (u8)_PlcpSignal); \ } #endif /* RTMP_MAC_PCI // */ #ifdef RTMP_MAC_USB #define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _PlcpSignal) \ { \ - u32 High32TSF=0, Low32TSF=0; \ - MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (u8)_Rssi0, (u8)_Rssi1,(u8)_Rssi2,_FrameSize, _pFrame, (u8)_PlcpSignal); \ + u32 High32TSF = 0, Low32TSF = 0; \ + MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (u8)_Rssi0, (u8)_Rssi1, (u8)_Rssi2, _FrameSize, _pFrame, (u8)_PlcpSignal); \ } #endif /* RTMP_MAC_USB // */ -#define MAC_ADDR_EQUAL(pAddr1,pAddr2) RTMPEqualMemory((void *)(pAddr1), (void *)(pAddr2), MAC_ADDR_LEN) -#define SSID_EQUAL(ssid1, len1, ssid2, len2) ((len1==len2) && (RTMPEqualMemory(ssid1, ssid2, len1))) +#define MAC_ADDR_EQUAL(pAddr1, pAddr2) RTMPEqualMemory((void *)(pAddr1), (void *)(pAddr2), MAC_ADDR_LEN) +#define SSID_EQUAL(ssid1, len1, ssid2, len2) ((len1 == len2) && (RTMPEqualMemory(ssid1, ssid2, len1))) /* */ /* Check if it is Japan W53(ch52,56,60,64) channel. */ @@ -1054,7 +1043,7 @@ typedef union _BACAP_STRUC { u32 MMPSmode:2; /* MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable */ u32 bHtAdhoc:1; /* adhoc can use ht rate. */ u32 b2040CoexistScanSup:1; /*As Sta, support do 2040 coexistence scan for AP. As Ap, support monitor trigger event to check if can use BW 40MHz. */ - u32 : 4; + u32: 4; } field; u32 word; } BACAP_STRUC, *PBACAP_STRUC; @@ -1334,7 +1323,7 @@ struct rt_common_config { BOOLEAN PSPXlink; /* 0: Disable. 1: Enable */ -#if defined(RT305x)||defined(RT30xx) +#if defined(RT305x) || defined(RT30xx) /* request by Gary, for High Power issue */ u8 HighPowerPatchDisabled; #endif @@ -2169,8 +2158,8 @@ struct rt_rtmp_adapter { **************************************************************************/ struct rt_rx_blk { RT28XX_RXD_STRUC RxD; - struct rt_rxwi * pRxWI; - struct rt_header_802_11 * pHeader; + struct rt_rxwi *pRxWI; + struct rt_header_802_11 *pHeader; void *pRxPacket; u8 *pData; u16 DataSize; @@ -2268,7 +2257,7 @@ struct rt_tx_blk { * Other static inline function definitions **************************************************************************/ static inline void ConvertMulticastIP2MAC(u8 *pIpAddr, - u8 ** ppMacAddr, + u8 **ppMacAddr, u16 ProtoType) { if (pIpAddr == NULL) @@ -2310,7 +2299,7 @@ char *GetBW(int BW); /* Private routines in rtmp_init.c */ /* */ int RTMPAllocAdapterBlock(void *handle, - struct rt_rtmp_adapter * * ppAdapter); + struct rt_rtmp_adapter **ppAdapter); int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd); @@ -2431,11 +2420,11 @@ void ORIBATimerTimeout(struct rt_rtmp_adapter *pAd); void SendRefreshBAR(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry); void ActHeaderInit(struct rt_rtmp_adapter *pAd, - struct rt_header_802_11 * pHdr80211, + struct rt_header_802_11 *pHdr80211, u8 *Addr1, u8 *Addr2, u8 *Addr3); void BarHeaderInit(struct rt_rtmp_adapter *pAd, - struct rt_frame_bar * pCntlBar, u8 *pDA, u8 *pSA); + struct rt_frame_bar *pCntlBar, u8 *pDA, u8 *pSA); void InsertActField(struct rt_rtmp_adapter *pAd, u8 *pFrameBuf, @@ -2443,7 +2432,7 @@ void InsertActField(struct rt_rtmp_adapter *pAd, BOOLEAN CntlEnqueueForRecv(struct rt_rtmp_adapter *pAd, unsigned long Wcid, - unsigned long MsgLen, struct rt_frame_ba_req * pMsg); + unsigned long MsgLen, struct rt_frame_ba_req *pMsg); /* */ /* Private routines in rtmp_data.c */ @@ -2511,7 +2500,7 @@ int MlmeDataHardTransmit(struct rt_rtmp_adapter *pAd, u8 QueIdx, void *pPacket); void RTMPWriteTxDescriptor(struct rt_rtmp_adapter *pAd, - struct rt_txd * pTxD, IN BOOLEAN bWIV, u8 QSEL); + struct rt_txd *pTxD, IN BOOLEAN bWIV, u8 QSEL); #endif /* RTMP_MAC_PCI // */ u16 RTMPCalcDuration(struct rt_rtmp_adapter *pAd, u8 Rate, unsigned long Size); @@ -2527,10 +2516,10 @@ void RTMPWriteTxWI(struct rt_rtmp_adapter *pAd, struct rt_txwi * pTxWI, IN BOOLE IN BOOLEAN CfAck, IN HTTRANSMIT_SETTING * pTransmit); void RTMPWriteTxWI_Data(struct rt_rtmp_adapter *pAd, - struct rt_txwi * pTxWI, struct rt_tx_blk *pTxBlk); + struct rt_txwi *pTxWI, struct rt_tx_blk *pTxBlk); void RTMPWriteTxWI_Cache(struct rt_rtmp_adapter *pAd, - struct rt_txwi * pTxWI, struct rt_tx_blk *pTxBlk); + struct rt_txwi *pTxWI, struct rt_tx_blk *pTxBlk); void RTMPSuspendMsduTransmission(struct rt_rtmp_adapter *pAd); @@ -2573,10 +2562,10 @@ void WpaStaGroupKeySetting(struct rt_rtmp_adapter *pAd); int RTMPCloneNdisPacket(struct rt_rtmp_adapter *pAd, IN BOOLEAN pInsAMSDUHdr, void *pInPacket, - void ** ppOutPacket); + void **ppOutPacket); int RTMPAllocateNdisPacket(struct rt_rtmp_adapter *pAd, - void ** pPacket, + void **pPacket, u8 *pHeader, u32 HeaderLen, u8 *pData, u32 DataLen); @@ -2717,7 +2706,7 @@ BOOLEAN AsicCheckCommanOk(struct rt_rtmp_adapter *pAd, u8 Command); void MacAddrRandomBssid(struct rt_rtmp_adapter *pAd, u8 *pAddr); void MgtMacHeaderInit(struct rt_rtmp_adapter *pAd, - struct rt_header_802_11 * pHdr80211, + struct rt_header_802_11 *pHdr80211, u8 SubType, u8 ToDs, u8 *pDA, u8 *pBssid); @@ -2796,7 +2785,7 @@ void MlmeQueueDestroy(struct rt_mlme_queue *Queue); BOOLEAN MlmeEnqueue(struct rt_rtmp_adapter *pAd, unsigned long Machine, - unsigned long MsgType, unsigned long MsgLen, void * Msg); + unsigned long MsgType, unsigned long MsgLen, void *Msg); BOOLEAN MlmeEnqueueForRecv(struct rt_rtmp_adapter *pAd, unsigned long Wcid, @@ -2807,7 +2796,7 @@ BOOLEAN MlmeEnqueueForRecv(struct rt_rtmp_adapter *pAd, u8 Rssi2, unsigned long MsgLen, void *Msg, u8 Signal); -BOOLEAN MlmeDequeue(struct rt_mlme_queue *Queue, struct rt_mlme_queue_elem ** Elem); +BOOLEAN MlmeDequeue(struct rt_mlme_queue *Queue, struct rt_mlme_queue_elem **Elem); void MlmeRestartStateMachine(struct rt_rtmp_adapter *pAd); @@ -2816,8 +2805,8 @@ BOOLEAN MlmeQueueEmpty(struct rt_mlme_queue *Queue); BOOLEAN MlmeQueueFull(struct rt_mlme_queue *Queue); BOOLEAN MsgTypeSubst(struct rt_rtmp_adapter *pAd, - struct rt_frame_802_11 * pFrame, - int * Machine, int * MsgType); + struct rt_frame_802_11 *pFrame, + int *Machine, int *MsgType); void StateMachineInit(struct rt_state_machine *Sm, IN STATE_MACHINE_FUNC Trans[], @@ -2895,8 +2884,8 @@ void AssocPostProc(struct rt_rtmp_adapter *pAd, u8 ExtRate[], u8 ExtRateLen, struct rt_edca_parm *pEdcaParm, - struct rt_ht_capability_ie * pHtCapability, - u8 HtCapabilityLen, struct rt_add_ht_info_ie * pAddHtInfo); + struct rt_ht_capability_ie *pHtCapability, + u8 HtCapabilityLen, struct rt_add_ht_info_ie *pAddHtInfo); void AuthStateMachineInit(struct rt_rtmp_adapter *pAd, struct rt_state_machine *sm, OUT STATE_MACHINE_FUNC Trans[]); @@ -2928,7 +2917,7 @@ void AuthRspStateMachineInit(struct rt_rtmp_adapter *pAd, void PeerDeauthAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem); void PeerAuthSimpleRspGenAndSend(struct rt_rtmp_adapter *pAd, - struct rt_header_802_11 * pHdr80211, + struct rt_header_802_11 *pHdr80211, u16 Alg, u16 Seq, u16 Reason, u16 Status); @@ -3054,133 +3043,133 @@ void ScanNextChannel(struct rt_rtmp_adapter *pAd); unsigned long MakeIbssBeacon(struct rt_rtmp_adapter *pAd); BOOLEAN MlmeScanReqSanity(struct rt_rtmp_adapter *pAd, - void * Msg, + void *Msg, unsigned long MsgLen, - u8 * BssType, + u8 *BssType, char ssid[], - u8 * SsidLen, u8 * ScanType); + u8 *SsidLen, u8 *ScanType); BOOLEAN PeerBeaconAndProbeRspSanity(struct rt_rtmp_adapter *pAd, - void * Msg, + void *Msg, unsigned long MsgLen, u8 MsgChannel, u8 *pAddr2, u8 *pBssid, char Ssid[], - u8 * pSsidLen, - u8 * pBssType, - u16 * pBeaconPeriod, - u8 * pChannel, - u8 * pNewChannel, + u8 *pSsidLen, + u8 *pBssType, + u16 *pBeaconPeriod, + u8 *pChannel, + u8 *pNewChannel, OUT LARGE_INTEGER * pTimestamp, - struct rt_cf_parm * pCfParm, - u16 * pAtimWin, - u16 * pCapabilityInfo, - u8 * pErp, - u8 * pDtimCount, - u8 * pDtimPeriod, - u8 * pBcastFlag, - u8 * pMessageToMe, + struct rt_cf_parm *pCfParm, + u16 *pAtimWin, + u16 *pCapabilityInfo, + u8 *pErp, + u8 *pDtimCount, + u8 *pDtimPeriod, + u8 *pBcastFlag, + u8 *pMessageToMe, u8 SupRate[], - u8 * pSupRateLen, + u8 *pSupRateLen, u8 ExtRate[], - u8 * pExtRateLen, - u8 * pCkipFlag, - u8 * pAironetCellPowerLimit, + u8 *pExtRateLen, + u8 *pCkipFlag, + u8 *pAironetCellPowerLimit, struct rt_edca_parm *pEdcaParm, struct rt_qbss_load_parm *pQbssLoad, struct rt_qos_capability_parm *pQosCapability, - unsigned long * pRalinkIe, - u8 * pHtCapabilityLen, - u8 * pPreNHtCapabilityLen, - struct rt_ht_capability_ie * pHtCapability, - u8 * AddHtInfoLen, - struct rt_add_ht_info_ie * AddHtInfo, - u8 * NewExtChannel, - u16 * LengthVIE, + unsigned long *pRalinkIe, + u8 *pHtCapabilityLen, + u8 *pPreNHtCapabilityLen, + struct rt_ht_capability_ie *pHtCapability, + u8 *AddHtInfoLen, + struct rt_add_ht_info_ie *AddHtInfo, + u8 *NewExtChannel, + u16 *LengthVIE, struct rt_ndis_802_11_variable_ies *pVIE); BOOLEAN PeerAddBAReqActionSanity(struct rt_rtmp_adapter *pAd, - void * pMsg, + void *pMsg, unsigned long MsgLen, u8 *pAddr2); BOOLEAN PeerAddBARspActionSanity(struct rt_rtmp_adapter *pAd, - void * pMsg, unsigned long MsgLen); + void *pMsg, unsigned long MsgLen); BOOLEAN PeerDelBAActionSanity(struct rt_rtmp_adapter *pAd, - u8 Wcid, void * pMsg, unsigned long MsgLen); + u8 Wcid, void *pMsg, unsigned long MsgLen); BOOLEAN MlmeAssocReqSanity(struct rt_rtmp_adapter *pAd, - void * Msg, + void *Msg, unsigned long MsgLen, u8 *pApAddr, - u16 * CapabilityInfo, - unsigned long * Timeout, u16 * ListenIntv); + u16 *CapabilityInfo, + unsigned long *Timeout, u16 *ListenIntv); BOOLEAN MlmeAuthReqSanity(struct rt_rtmp_adapter *pAd, - void * Msg, + void *Msg, unsigned long MsgLen, u8 *pAddr, - unsigned long * Timeout, u16 * Alg); + unsigned long *Timeout, u16 *Alg); BOOLEAN MlmeStartReqSanity(struct rt_rtmp_adapter *pAd, - void * Msg, + void *Msg, unsigned long MsgLen, - char Ssid[], u8 * Ssidlen); + char Ssid[], u8 *Ssidlen); BOOLEAN PeerAuthSanity(struct rt_rtmp_adapter *pAd, - void * Msg, + void *Msg, unsigned long MsgLen, u8 *pAddr, - u16 * Alg, - u16 * Seq, - u16 * Status, char ChlgText[]); + u16 *Alg, + u16 *Seq, + u16 *Status, char ChlgText[]); -BOOLEAN PeerAssocRspSanity(struct rt_rtmp_adapter *pAd, void * pMsg, unsigned long MsgLen, u8 *pAddr2, u16 * pCapabilityInfo, u16 * pStatus, u16 * pAid, u8 SupRate[], u8 * pSupRateLen, u8 ExtRate[], u8 * pExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo, /* AP might use this additional ht info IE */ - u8 * pHtCapabilityLen, - u8 * pAddHtInfoLen, - u8 * pNewExtChannelOffset, - struct rt_edca_parm *pEdcaParm, u8 * pCkipFlag); +BOOLEAN PeerAssocRspSanity(struct rt_rtmp_adapter *pAd, void *pMsg, unsigned long MsgLen, u8 *pAddr2, u16 *pCapabilityInfo, u16 *pStatus, u16 *pAid, u8 SupRate[], u8 *pSupRateLen, u8 ExtRate[], u8 *pExtRateLen, struct rt_ht_capability_ie *pHtCapability, struct rt_add_ht_info_ie *pAddHtInfo, /* AP might use this additional ht info IE */ + u8 *pHtCapabilityLen, + u8 *pAddHtInfoLen, + u8 *pNewExtChannelOffset, + struct rt_edca_parm *pEdcaParm, u8 *pCkipFlag); BOOLEAN PeerDisassocSanity(struct rt_rtmp_adapter *pAd, - void * Msg, + void *Msg, unsigned long MsgLen, - u8 *pAddr2, u16 * Reason); + u8 *pAddr2, u16 *Reason); BOOLEAN PeerWpaMessageSanity(struct rt_rtmp_adapter *pAd, - struct rt_eapol_packet * pMsg, + struct rt_eapol_packet *pMsg, unsigned long MsgLen, u8 MsgType, struct rt_mac_table_entry *pEntry); BOOLEAN PeerDeauthSanity(struct rt_rtmp_adapter *pAd, - void * Msg, + void *Msg, unsigned long MsgLen, - u8 *pAddr2, u16 * Reason); + u8 *pAddr2, u16 *Reason); BOOLEAN PeerProbeReqSanity(struct rt_rtmp_adapter *pAd, - void * Msg, + void *Msg, unsigned long MsgLen, u8 *pAddr2, - char Ssid[], u8 * pSsidLen); + char Ssid[], u8 *pSsidLen); -BOOLEAN GetTimBit(char * Ptr, +BOOLEAN GetTimBit(char *Ptr, u16 Aid, - u8 * TimLen, - u8 * BcastFlag, - u8 * DtimCount, - u8 * DtimPeriod, u8 * MessageToMe); + u8 *TimLen, + u8 *BcastFlag, + u8 *DtimCount, + u8 *DtimPeriod, u8 *MessageToMe); u8 ChannelSanity(struct rt_rtmp_adapter *pAd, u8 channel); NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(struct rt_bss_entry *pBss); BOOLEAN MlmeDelBAReqSanity(struct rt_rtmp_adapter *pAd, - void * Msg, unsigned long MsgLen); + void *Msg, unsigned long MsgLen); BOOLEAN MlmeAddBAReqSanity(struct rt_rtmp_adapter *pAd, - void * Msg, unsigned long MsgLen, u8 *pAddr2); + void *Msg, unsigned long MsgLen, u8 *pAddr2); -unsigned long MakeOutgoingFrame(u8 * Buffer, unsigned long * Length, ...); +unsigned long MakeOutgoingFrame(u8 *Buffer, unsigned long *Length, ...); void LfsrInit(struct rt_rtmp_adapter *pAd, unsigned long Seed); @@ -3215,7 +3204,7 @@ void MlmeSetTxRate(struct rt_rtmp_adapter *pAd, void MlmeSelectTxRateTable(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry, - u8 ** ppTable, + u8 **ppTable, u8 *pTableSize, u8 *pInitTxRateIdx); void MlmeCalculateChannelQuality(struct rt_rtmp_adapter *pAd, @@ -3235,15 +3224,15 @@ void MlmeUpdateTxRates(struct rt_rtmp_adapter *pAd, void MlmeUpdateHtTxRates(struct rt_rtmp_adapter *pAd, u8 apidx); void RTMPCheckRates(struct rt_rtmp_adapter *pAd, - IN u8 SupRate[], IN u8 * SupRateLen); + IN u8 SupRate[], IN u8 *SupRateLen); BOOLEAN RTMPCheckChannel(struct rt_rtmp_adapter *pAd, u8 CentralChannel, u8 Channel); BOOLEAN RTMPCheckHt(struct rt_rtmp_adapter *pAd, u8 Wcid, - struct rt_ht_capability_ie * pHtCapability, - struct rt_add_ht_info_ie * pAddHtInfo); + struct rt_ht_capability_ie *pHtCapability, + struct rt_add_ht_info_ie *pAddHtInfo); void StaQuickResponeForRateUpExec(void *SystemSpecific1, void *FunctionContext, @@ -3268,7 +3257,7 @@ int set_eFusedump_Proc(struct rt_rtmp_adapter *pAd, char *arg); void eFusePhysicalReadRegisters(struct rt_rtmp_adapter *pAd, u16 Offset, - u16 Length, u16 * pData); + u16 Length, u16 *pData); int RtmpEfuseSupportCheck(struct rt_rtmp_adapter *pAd); @@ -3391,7 +3380,7 @@ int RT_CfgSetWepKey(struct rt_rtmp_adapter *pAd, int RT_CfgSetWPAPSKKey(struct rt_rtmp_adapter *pAd, char *keyString, - u8 * pHashStr, + u8 *pHashStr, int hashStrLen, u8 *pPMKBuf); /* */ @@ -3402,9 +3391,9 @@ void RTMPWPARemoveAllKeys(struct rt_rtmp_adapter *pAd); void RTMPSetPhyMode(struct rt_rtmp_adapter *pAd, unsigned long phymode); void RTMPUpdateHTIE(struct rt_ht_capability *pRtHt, - u8 * pMcsSet, - struct rt_ht_capability_ie * pHtCapability, - struct rt_add_ht_info_ie * pAddHtInfo); + u8 *pMcsSet, + struct rt_ht_capability_ie *pHtCapability, + struct rt_add_ht_info_ie *pAddHtInfo); void RTMPAddWcidAttributeEntry(struct rt_rtmp_adapter *pAd, u8 BssIdx, @@ -3436,22 +3425,22 @@ void RTMPToWirelessSta(struct rt_rtmp_adapter *pAd, u32 DataLen, IN BOOLEAN bClearFrame); void WpaDerivePTK(struct rt_rtmp_adapter *pAd, - u8 * PMK, - u8 * ANonce, - u8 * AA, - u8 * SNonce, - u8 * SA, u8 * output, u32 len); + u8 *PMK, + u8 *ANonce, + u8 *AA, + u8 *SNonce, + u8 *SA, u8 *output, u32 len); -void GenRandom(struct rt_rtmp_adapter *pAd, u8 * macAddr, u8 * random); +void GenRandom(struct rt_rtmp_adapter *pAd, u8 *macAddr, u8 *random); BOOLEAN RTMPCheckWPAframe(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry, u8 *pData, unsigned long DataByteCount, u8 FromWhichBSSID); -void AES_GTK_KEY_UNWRAP(u8 * key, - u8 * plaintext, - u32 c_len, u8 * ciphertext); +void AES_GTK_KEY_UNWRAP(u8 *key, + u8 *plaintext, + u32 c_len, u8 *ciphertext); BOOLEAN RTMPParseEapolKeyData(struct rt_rtmp_adapter *pAd, u8 *pKeyData, @@ -3464,11 +3453,11 @@ void ConstructEapolMsg(struct rt_mac_table_entry *pEntry, u8 GroupKeyWepStatus, u8 MsgType, u8 DefaultKeyIdx, - u8 * KeyNonce, - u8 * TxRSC, - u8 * GTK, - u8 * RSNIE, - u8 RSNIE_Len, struct rt_eapol_packet * pMsg); + u8 *KeyNonce, + u8 *TxRSC, + u8 *GTK, + u8 *RSNIE, + u8 RSNIE_Len, struct rt_eapol_packet *pMsg); int RTMPSoftDecryptBroadCastData(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk, @@ -3515,66 +3504,66 @@ void PeerGroupMsg1Action(struct rt_rtmp_adapter *pAd, void PeerGroupMsg2Action(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry, - void * Msg, u32 MsgLen); + void *Msg, u32 MsgLen); -void WpaDeriveGTK(u8 * PMK, - u8 * GNonce, - u8 * AA, u8 * output, u32 len); +void WpaDeriveGTK(u8 *PMK, + u8 *GNonce, + u8 *AA, u8 *output, u32 len); -void AES_GTK_KEY_WRAP(u8 * key, - u8 * plaintext, - u32 p_len, u8 * ciphertext); +void AES_GTK_KEY_WRAP(u8 *key, + u8 *plaintext, + u32 p_len, u8 *ciphertext); /*typedef void (*TIMER_FUNCTION)(unsigned long); */ /* timeout -- ms */ -void RTMP_SetPeriodicTimer(struct timer_list * pTimer, +void RTMP_SetPeriodicTimer(struct timer_list *pTimer, IN unsigned long timeout); void RTMP_OS_Init_Timer(struct rt_rtmp_adapter *pAd, - struct timer_list * pTimer, + struct timer_list *pTimer, IN TIMER_FUNCTION function, void *data); -void RTMP_OS_Add_Timer(struct timer_list * pTimer, +void RTMP_OS_Add_Timer(struct timer_list *pTimer, IN unsigned long timeout); -void RTMP_OS_Mod_Timer(struct timer_list * pTimer, +void RTMP_OS_Mod_Timer(struct timer_list *pTimer, IN unsigned long timeout); -void RTMP_OS_Del_Timer(struct timer_list * pTimer, - OUT BOOLEAN * pCancelled); +void RTMP_OS_Del_Timer(struct timer_list *pTimer, + OUT BOOLEAN *pCancelled); void RTMP_OS_Release_Packet(struct rt_rtmp_adapter *pAd, struct rt_queue_entry *pEntry); void RTMPusecDelay(unsigned long usec); int os_alloc_mem(struct rt_rtmp_adapter *pAd, - u8 ** mem, unsigned long size); + u8 **mem, unsigned long size); int os_free_mem(struct rt_rtmp_adapter *pAd, void *mem); void RTMP_AllocateSharedMemory(struct rt_rtmp_adapter *pAd, unsigned long Length, IN BOOLEAN Cached, - void ** VirtualAddress, + void **VirtualAddress, dma_addr_t *PhysicalAddress); void RTMPFreeTxRxRingMemory(struct rt_rtmp_adapter *pAd); -int AdapterBlockAllocateMemory(void *handle, void ** ppAd); +int AdapterBlockAllocateMemory(void *handle, void **ppAd); void RTMP_AllocateTxDescMemory(struct rt_rtmp_adapter *pAd, u32 Index, unsigned long Length, IN BOOLEAN Cached, - void ** VirtualAddress, + void **VirtualAddress, dma_addr_t *PhysicalAddress); void RTMP_AllocateFirstTxBuffer(struct rt_rtmp_adapter *pAd, u32 Index, unsigned long Length, IN BOOLEAN Cached, - void ** VirtualAddress, + void **VirtualAddress, dma_addr_t *PhysicalAddress); void RTMP_FreeFirstTxBuffer(struct rt_rtmp_adapter *pAd, @@ -3586,13 +3575,13 @@ void RTMP_FreeFirstTxBuffer(struct rt_rtmp_adapter *pAd, void RTMP_AllocateMgmtDescMemory(struct rt_rtmp_adapter *pAd, unsigned long Length, IN BOOLEAN Cached, - void ** VirtualAddress, + void **VirtualAddress, dma_addr_t *PhysicalAddress); void RTMP_AllocateRxDescMemory(struct rt_rtmp_adapter *pAd, unsigned long Length, IN BOOLEAN Cached, - void ** VirtualAddress, + void **VirtualAddress, dma_addr_t *PhysicalAddress); void RTMP_FreeDescMemory(struct rt_rtmp_adapter *pAd, @@ -3605,30 +3594,29 @@ void *RtmpOSNetPktAlloc(struct rt_rtmp_adapter *pAd, IN int size); void *RTMP_AllocateRxPacketBuffer(struct rt_rtmp_adapter *pAd, unsigned long Length, IN BOOLEAN Cached, - void ** VirtualAddress, - OUT dma_addr_t * - PhysicalAddress); + void **VirtualAddress, + OUT dma_addr_t *PhysicalAddress); void *RTMP_AllocateTxPacketBuffer(struct rt_rtmp_adapter *pAd, unsigned long Length, IN BOOLEAN Cached, - void ** VirtualAddress); + void **VirtualAddress); void *RTMP_AllocateFragPacketBuffer(struct rt_rtmp_adapter *pAd, unsigned long Length); void RTMP_QueryPacketInfo(void *pPacket, struct rt_packet_info *pPacketInfo, - u8 ** pSrcBufVA, u32 * pSrcBufLen); + u8 **pSrcBufVA, u32 *pSrcBufLen); -void RTMP_QueryNextPacketInfo(void ** ppPacket, +void RTMP_QueryNextPacketInfo(void **ppPacket, struct rt_packet_info *pPacketInfo, - u8 ** pSrcBufVA, u32 * pSrcBufLen); + u8 **pSrcBufVA, u32 *pSrcBufLen); BOOLEAN RTMP_FillTxBlkInfo(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk); -struct rt_rtmp_sg_list * -rt_get_sg_list_from_packet(void *pPacket, struct rt_rtmp_sg_list *sg); +struct rt_rtmp_sg_list *rt_get_sg_list_from_packet(void *pPacket, + struct rt_rtmp_sg_list *sg); void announce_802_3_packet(struct rt_rtmp_adapter *pAd, void *pPacket); @@ -3717,23 +3705,19 @@ void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd, { \ u8 *_pRemovedLLCSNAP = NULL, *_pDA, *_pSA; \ \ - if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_MESH)) \ - { \ + if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_MESH)) { \ _pDA = _pRxBlk->pHeader->Addr3; \ _pSA = (u8 *)_pRxBlk->pHeader + sizeof(struct rt_header_802_11); \ } \ - else \ - { \ - if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_INFRA)) \ - { \ + else {\ + if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_INFRA)) {\ _pDA = _pRxBlk->pHeader->Addr1; \ if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_DLS)) \ _pSA = _pRxBlk->pHeader->Addr2; \ else \ _pSA = _pRxBlk->pHeader->Addr3; \ } \ - else \ - { \ + else { \ _pDA = _pRxBlk->pHeader->Addr1; \ _pSA = _pRxBlk->pHeader->Addr2; \ } \ @@ -3771,8 +3755,8 @@ void Update_Rssi_Sample(struct rt_rtmp_adapter *pAd, void *GetPacketFromRxRing(struct rt_rtmp_adapter *pAd, OUT PRT28XX_RXD_STRUC pSaveRxD, - OUT BOOLEAN * pbReschedule, - IN u32 * pRxPending); + OUT BOOLEAN *pbReschedule, + IN u32 *pRxPending); void *RTMPDeFragmentDataFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk); @@ -3919,24 +3903,24 @@ BOOLEAN RtmpRaDevCtrlExit(struct rt_rtmp_adapter *pAd); /* */ u16 RtmpPCI_WriteTxResource(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk, - IN BOOLEAN bIsLast, u16 * FreeNumber); + IN BOOLEAN bIsLast, u16 *FreeNumber); u16 RtmpPCI_WriteSingleTxResource(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk, IN BOOLEAN bIsLast, - u16 * FreeNumber); + u16 *FreeNumber); u16 RtmpPCI_WriteMultiTxResource(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk, - u8 frameNum, u16 * FreeNumber); + u8 frameNum, u16 *FreeNumber); u16 RtmpPCI_WriteFragTxResource(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk, - u8 fragNum, u16 * FreeNumber); + u8 fragNum, u16 *FreeNumber); u16 RtmpPCI_WriteSubTxResource(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk, - IN BOOLEAN bIsLast, u16 * FreeNumber); + IN BOOLEAN bIsLast, u16 *FreeNumber); void RtmpPCI_FinalWriteTxResource(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk, @@ -3955,8 +3939,8 @@ int RtmpPCIMgmtKickOut(struct rt_rtmp_adapter *pAd, u8 *pSrcBufVA, u32 SrcBufLen); int RTMPCheckRxError(struct rt_rtmp_adapter *pAd, - struct rt_header_802_11 * pHeader, - struct rt_rxwi * pRxWI, IN PRT28XX_RXD_STRUC pRxD); + struct rt_header_802_11 *pHeader, + struct rt_rxwi *pRxWI, IN PRT28XX_RXD_STRUC pRxD); BOOLEAN RT28xxPciAsicRadioOff(struct rt_rtmp_adapter *pAd, u8 Level, u16 TbttNumToNextWakeUp); @@ -4138,15 +4122,15 @@ void append_pkt(struct rt_rtmp_adapter *pAd, u8 *pHeader802_3, u32 HdrLen, u8 *pData, - unsigned long DataSize, void ** ppPacket); + unsigned long DataSize, void **ppPacket); u32 deaggregate_AMSDU_announce(struct rt_rtmp_adapter *pAd, void *pPacket, u8 *pData, unsigned long DataSize); int RTMPCheckRxError(struct rt_rtmp_adapter *pAd, - struct rt_header_802_11 * pHeader, - struct rt_rxwi * pRxWI, + struct rt_header_802_11 *pHeader, + struct rt_rxwi *pRxWI, IN PRT28XX_RXD_STRUC pRxINFO); void RTUSBMlmeHardTransmit(struct rt_rtmp_adapter *pAd, struct rt_mgmt *pMgmt); @@ -4173,20 +4157,20 @@ void RTMPWriteTxInfo(struct rt_rtmp_adapter *pAd, /* */ u16 RtmpUSB_WriteSubTxResource(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk, - IN BOOLEAN bIsLast, u16 * FreeNumber); + IN BOOLEAN bIsLast, u16 *FreeNumber); u16 RtmpUSB_WriteSingleTxResource(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk, IN BOOLEAN bIsLast, - u16 * FreeNumber); + u16 *FreeNumber); u16 RtmpUSB_WriteFragTxResource(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk, - u8 fragNum, u16 * FreeNumber); + u8 fragNum, u16 *FreeNumber); u16 RtmpUSB_WriteMultiTxResource(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk, - u8 frameNum, u16 * FreeNumber); + u8 frameNum, u16 *FreeNumber); void RtmpUSB_FinalWriteTxResource(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk, @@ -4205,7 +4189,7 @@ int RtmpUSBMgmtKickOut(struct rt_rtmp_adapter *pAd, void RtmpUSBNullFrameKickOut(struct rt_rtmp_adapter *pAd, u8 QueIdx, - u8 * pNullFrame, u32 frameLen); + u8 *pNullFrame, u32 frameLen); void RtmpUsbStaAsicForceWakeupTimeout(void *SystemSpecific1, void *FunctionContext, @@ -4245,9 +4229,9 @@ void AsicStaBbpTuning(struct rt_rtmp_adapter *pAd); BOOLEAN StaAddMacTableEntry(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry, u8 MaxSupportedRateIn500Kbps, - struct rt_ht_capability_ie * pHtCapability, + struct rt_ht_capability_ie *pHtCapability, u8 HtCapabilityLen, - struct rt_add_ht_info_ie * pAddHtInfo, + struct rt_add_ht_info_ie *pAddHtInfo, u8 AddHtInfoLen, u16 CapabilityInfo); BOOLEAN AUTH_ReqSend(struct rt_rtmp_adapter *pAd, @@ -4313,7 +4297,7 @@ void RtmpOSNetDevClose(struct net_device *pNetDev); void RtmpOSNetDevDetach(struct net_device *pNetDev); -int RtmpOSNetDevAlloc(struct net_device ** pNewNetDev, u32 privDataSize); +int RtmpOSNetDevAlloc(struct net_device **pNewNetDev, u32 privDataSize); void RtmpOSNetDevFree(struct net_device *pNetDev); -- cgit v1.2.3 From cd20decf7ef49983e973ebd6a76a0000cd26cd2a Mon Sep 17 00:00:00 2001 From: Steven Harms Date: Sun, 14 Mar 2010 11:56:00 -0400 Subject: Staging: otus: Remove mix of tabs and spaces with just tabs in ioctl.c Previously defines had a mix of both tabs and spaces, causing an error in the checkpatch tool. These tabs and spaces have been consolidated to only tabs. Signed-off-by: Steven Harms Acked-by: Simon Horman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/otus/ioctl.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/otus/ioctl.c b/drivers/staging/otus/ioctl.c index 84be4b2cd692..b9dd943e07a1 100644 --- a/drivers/staging/otus/ioctl.c +++ b/drivers/staging/otus/ioctl.c @@ -30,34 +30,34 @@ #include "usbdrv.h" -#define ZD_IOCTL_WPA (SIOCDEVPRIVATE + 1) -#define ZD_IOCTL_PARAM (SIOCDEVPRIVATE + 2) -#define ZD_IOCTL_GETWPAIE (SIOCDEVPRIVATE + 3) +#define ZD_IOCTL_WPA (SIOCDEVPRIVATE + 1) +#define ZD_IOCTL_PARAM (SIOCDEVPRIVATE + 2) +#define ZD_IOCTL_GETWPAIE (SIOCDEVPRIVATE + 3) #ifdef ZM_ENABLE_CENC -#define ZM_IOCTL_CENC (SIOCDEVPRIVATE + 4) +#define ZM_IOCTL_CENC (SIOCDEVPRIVATE + 4) #endif /* ZM_ENABLE_CENC */ -#define ZD_PARAM_ROAMING 0x0001 -#define ZD_PARAM_PRIVACY 0x0002 -#define ZD_PARAM_WPA 0x0003 +#define ZD_PARAM_ROAMING 0x0001 +#define ZD_PARAM_PRIVACY 0x0002 +#define ZD_PARAM_WPA 0x0003 #define ZD_PARAM_COUNTERMEASURES 0x0004 #define ZD_PARAM_DROPUNENCRYPTED 0x0005 -#define ZD_PARAM_AUTH_ALGS 0x0006 -#define ZD_PARAM_WPS_FILTER 0x0007 +#define ZD_PARAM_AUTH_ALGS 0x0006 +#define ZD_PARAM_WPS_FILTER 0x0007 #ifdef ZM_ENABLE_CENC #define P80211_PACKET_CENCFLAG 0x0001 #endif /* ZM_ENABLE_CENC */ -#define P80211_PACKET_SETKEY 0x0003 +#define P80211_PACKET_SETKEY 0x0003 #define ZD_CMD_SET_ENCRYPT_KEY 0x0001 -#define ZD_CMD_SET_MLME 0x0002 -#define ZD_CMD_SCAN_REQ 0x0003 +#define ZD_CMD_SET_MLME 0x0002 +#define ZD_CMD_SCAN_REQ 0x0003 #define ZD_CMD_SET_GENERIC_ELEMENT 0x0004 -#define ZD_CMD_GET_TSC 0x0005 +#define ZD_CMD_GET_TSC 0x0005 #define ZD_CRYPT_ALG_NAME_LEN 16 -#define ZD_MAX_KEY_SIZE 32 -#define ZD_MAX_GENERIC_SIZE 64 +#define ZD_MAX_KEY_SIZE 32 +#define ZD_MAX_GENERIC_SIZE 64 #include -- cgit v1.2.3 From 263974d918474d17b5963d0b22fbc81729ce0479 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 28 Mar 2010 14:48:10 +0300 Subject: Staging: otus: hpani: using the wrong variable We're updating the "HpPriv->ani" array here so we should use that to determine the end of the for loop. "HpPriv->ani" has 50 elements and "wd->regulationTable.allowChannel" has 59 elements. Signed-off-by: Dan Carpenter Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/otus/hal/hpani.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/otus/hal/hpani.c b/drivers/staging/otus/hal/hpani.c index 0afecd8c2de4..d401504f2004 100644 --- a/drivers/staging/otus/hal/hpani.c +++ b/drivers/staging/otus/hal/hpani.c @@ -96,7 +96,7 @@ void zfHpAniAttach(zdev_t* dev) HpPriv->hasHwPhyCounters = 1; memset((char *)&HpPriv->ani, 0, sizeof(HpPriv->ani)); - for (i = 0; i < N(wd->regulationTable.allowChannel); i++) + for (i = 0; i < ARRAY_SIZE(HpPriv->ani); i++) { /* New ANI stuff */ HpPriv->ani[i].ofdmTrigHigh = ZM_HAL_ANI_OFDM_TRIG_HIGH; -- cgit v1.2.3 From b4001982bcd79e9685bc09f68a05526f8c5887c7 Mon Sep 17 00:00:00 2001 From: Vikram Dhillon Date: Sun, 4 Apr 2010 01:22:53 -0400 Subject: Staging: Otus: Hal: hpani.c Fixed some style issues Fixed some style issues in accordance with checkpatch.pl Signed-by: Vikram Dhillon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/otus/hal/hpani.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/otus/hal/hpani.c b/drivers/staging/otus/hal/hpani.c index d401504f2004..f53e483b394d 100644 --- a/drivers/staging/otus/hal/hpani.c +++ b/drivers/staging/otus/hal/hpani.c @@ -18,8 +18,8 @@ #include "hpusb.h" -extern u16_t zfDelayWriteInternalReg(zdev_t* dev, u32_t addr, u32_t val); -extern u16_t zfFlushDelayWrite(zdev_t* dev); +extern u16_t zfDelayWriteInternalReg(zdev_t *dev, u32_t addr, u32_t val); +extern u16_t zfFlushDelayWrite(zdev_t *dev); /* * Anti noise immunity support. We track phy errors and react @@ -52,13 +52,13 @@ extern u16_t zfFlushDelayWrite(zdev_t* dev); #define ZM_HAL_EP_RND(x, mul) \ ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) -s32_t BEACON_RSSI(zdev_t* dev) +s32_t BEACON_RSSI(zdev_t *dev) { s32_t rssi; struct zsHpPriv *HpPriv; zmw_get_wlan_dev(dev); - HpPriv = (struct zsHpPriv*)wd->hpPrivate; + HpPriv = (struct zsHpPriv *)wd->hpPrivate; rssi = ZM_HAL_EP_RND(HpPriv->stats.ast_nodestats.ns_avgbrssi, ZM_HAL_RSSI_EP_MULTIPLIER); @@ -70,7 +70,7 @@ s32_t BEACON_RSSI(zdev_t* dev) * resets the channel statistics */ -void zfHpAniAttach(zdev_t* dev) +void zfHpAniAttach(zdev_t *dev) { #define N(a) (sizeof(a) / sizeof(a[0])) u32_t i; @@ -82,11 +82,10 @@ void zfHpAniAttach(zdev_t* dev) const int firpwr[] = { -78, -78, -78, -78, -80 }; zmw_get_wlan_dev(dev); - HpPriv = (struct zsHpPriv*)wd->hpPrivate; + HpPriv = (struct zsHpPriv *)wd->hpPrivate; - for (i = 0; i < 5; i++) - { - HpPriv->totalSizeDesired[i] = totalSizeDesired[i]; + for (i = 0; i < 5; i++) { + HpPriv->totalSizeDesired[i] = totalSizeDesired[i]; HpPriv->coarseHigh[i] = coarseHigh[i]; HpPriv->coarseLow[i] = coarseLow[i]; HpPriv->firpwr[i] = firpwr[i]; @@ -96,8 +95,7 @@ void zfHpAniAttach(zdev_t* dev) HpPriv->hasHwPhyCounters = 1; memset((char *)&HpPriv->ani, 0, sizeof(HpPriv->ani)); - for (i = 0; i < ARRAY_SIZE(HpPriv->ani); i++) - { + for (i = 0; i < ARRAY_SIZE(HpPriv->ani); i++) { /* New ANI stuff */ HpPriv->ani[i].ofdmTrigHigh = ZM_HAL_ANI_OFDM_TRIG_HIGH; HpPriv->ani[i].ofdmTrigLow = ZM_HAL_ANI_OFDM_TRIG_LOW; @@ -109,14 +107,12 @@ void zfHpAniAttach(zdev_t* dev) HpPriv->ani[i].cckWeakSigThreshold = ZM_HAL_ANI_CCK_WEAK_SIG_THR; HpPriv->ani[i].spurImmunityLevel = ZM_HAL_ANI_SPUR_IMMUNE_LVL; HpPriv->ani[i].firstepLevel = ZM_HAL_ANI_FIRSTEP_LVL; - if (HpPriv->hasHwPhyCounters) - { + if (HpPriv->hasHwPhyCounters) { HpPriv->ani[i].ofdmPhyErrBase = 0;//AR_PHY_COUNTMAX - ZM_HAL_ANI_OFDM_TRIG_HIGH; HpPriv->ani[i].cckPhyErrBase = 0;//AR_PHY_COUNTMAX - ZM_HAL_ANI_CCK_TRIG_HIGH; } } - if (HpPriv->hasHwPhyCounters) - { + if (HpPriv->hasHwPhyCounters) { //zm_debug_msg2("Setting OfdmErrBase = 0x", HpPriv->ani[0].ofdmPhyErrBase); //zm_debug_msg2("Setting cckErrBase = 0x", HpPriv->ani[0].cckPhyErrBase); //OS_REG_WRITE(ah, AR_PHY_ERR_1, HpPriv->ani[0].ofdmPhyErrBase); @@ -135,7 +131,7 @@ void zfHpAniAttach(zdev_t* dev) /* * Control Adaptive Noise Immunity Parameters */ -u8_t zfHpAniControl(zdev_t* dev, ZM_HAL_ANI_CMD cmd, int param) +u8_t zfHpAniControl(zdev_t *dev, ZM_HAL_ANI_CMD cmd, int param) { #define N(a) (sizeof(a)/sizeof(a[0])) typedef s32_t TABLE[]; @@ -143,7 +139,7 @@ u8_t zfHpAniControl(zdev_t* dev, ZM_HAL_ANI_CMD cmd, int param) struct zsAniState *aniState; zmw_get_wlan_dev(dev); - HpPriv = (struct zsHpPriv*)wd->hpPrivate; + HpPriv = (struct zsHpPriv *)wd->hpPrivate; aniState = HpPriv->curani; switch (cmd) @@ -152,8 +148,7 @@ u8_t zfHpAniControl(zdev_t* dev, ZM_HAL_ANI_CMD cmd, int param) { u32_t level = param; - if (level >= N(HpPriv->totalSizeDesired)) - { + if (level >= N(HpPriv->totalSizeDesired)) { zm_debug_msg1("level out of range, desired level : ", level); zm_debug_msg1("max level : ", N(HpPriv->totalSizeDesired)); return FALSE; -- cgit v1.2.3 From f4d52b072d35ad2cc3720af65853e6fcc9d8414f Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Tue, 27 Apr 2010 00:34:49 +0200 Subject: Staging: otus: Add null check and fix coding style issue This patch removes mixing of declarations and code and adds a null-test after a kmalloc. Signed-off-by: Peter Huewe Acked-by: Simon Horman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/otus/ioctl.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/otus/ioctl.c b/drivers/staging/otus/ioctl.c index b9dd943e07a1..a48c8e4a9ea7 100644 --- a/drivers/staging/otus/ioctl.c +++ b/drivers/staging/otus/ioctl.c @@ -867,6 +867,7 @@ int usbdrvwext_giwscan(struct net_device *dev, char *current_ev = extra; char *end_buf; int i; + struct zsBssListV1 *pBssList; /* BssList = wd->sta.pBssList; */ /* zmw_get_wlan_dev(dev); */ @@ -874,8 +875,10 @@ int usbdrvwext_giwscan(struct net_device *dev, return 0; /* struct zsBssList BssList; */ - struct zsBssListV1 *pBssList = kmalloc(sizeof(struct zsBssListV1), - GFP_KERNEL); + pBssList = kmalloc(sizeof(struct zsBssListV1), GFP_KERNEL); + if (pBssList == NULL) + return -ENOMEM; + if (data->length == 0) end_buf = extra + IW_SCAN_MAX_DATA; else -- cgit v1.2.3 From ec8f002e6dbd6a55b79544f72ea5760ca69e225e Mon Sep 17 00:00:00 2001 From: Steven Harms Date: Thu, 18 Mar 2010 10:15:59 -0400 Subject: Staging: vt6655: Convert C99 style comments, remove spaces between function definitions and parenthesis Converted C99 style comments to kernel style guideline complianet comments. Removed spaces between function definitions and parenthesis. These were indicated as problems by checkpatch tool. Fixed typo found by Gabor Stefanik Signed-off-by: Steven Harms Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/srom.c | 50 +++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/srom.c b/drivers/staging/vt6655/srom.c index 5a7c6ca724b3..fb7a6468cab8 100644 --- a/drivers/staging/vt6655/srom.c +++ b/drivers/staging/vt6655/srom.c @@ -85,15 +85,15 @@ BYTE SROMbyReadEmbedded(DWORD_PTR dwIoBase, BYTE byContntOffset) byData = 0xFF; VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg); - // turn off hardware retry for getting NACK + /* turn off hardware retry for getting NACK */ VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg & (~I2MCFG_NORETRY))); for (wNoACK = 0; wNoACK < W_MAX_I2CRETRY; wNoACK++) { VNSvOutPortB(dwIoBase + MAC_REG_I2MTGID, EEP_I2C_DEV_ID); VNSvOutPortB(dwIoBase + MAC_REG_I2MTGAD, byContntOffset); - // issue read command + /* issue read command */ VNSvOutPortB(dwIoBase + MAC_REG_I2MCSR, I2MCSR_EEMR); - // wait DONE be set + /* wait DONE be set */ for (wDelay = 0; wDelay < W_MAX_TIMEOUT; wDelay++) { VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait); if (byWait & (I2MCSR_DONE | I2MCSR_NACK)) @@ -125,7 +125,7 @@ BYTE SROMbyReadEmbedded(DWORD_PTR dwIoBase, BYTE byContntOffset) * Return Value: TRUE if succeeded; FALSE if failed. * */ -BOOL SROMbWriteEmbedded (DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byData) +BOOL SROMbWriteEmbedded(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byData) { WORD wDelay, wNoACK; BYTE byWait; @@ -133,16 +133,16 @@ BOOL SROMbWriteEmbedded (DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byData) BYTE byOrg; VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg); - // turn off hardware retry for getting NACK + /* turn off hardware retry for getting NACK */ VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg & (~I2MCFG_NORETRY))); for (wNoACK = 0; wNoACK < W_MAX_I2CRETRY; wNoACK++) { VNSvOutPortB(dwIoBase + MAC_REG_I2MTGID, EEP_I2C_DEV_ID); VNSvOutPortB(dwIoBase + MAC_REG_I2MTGAD, byContntOffset); VNSvOutPortB(dwIoBase + MAC_REG_I2MDOPT, byData); - // issue write command + /* issue write command */ VNSvOutPortB(dwIoBase + MAC_REG_I2MCSR, I2MCSR_EEMW); - // wait DONE be set + /* wait DONE be set */ for (wDelay = 0; wDelay < W_MAX_TIMEOUT; wDelay++) { VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait); if (byWait & (I2MCSR_DONE | I2MCSR_NACK)) @@ -178,7 +178,7 @@ BOOL SROMbWriteEmbedded (DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byData) * Return Value: none * */ -void SROMvRegBitsOn (DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byBits) +void SROMvRegBitsOn(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byBits) { BYTE byOrgData; @@ -199,7 +199,7 @@ void SROMvRegBitsOn (DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byBits) * none * */ -void SROMvRegBitsOff (DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byBits) +void SROMvRegBitsOff(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byBits) { BYTE byOrgData; @@ -222,7 +222,7 @@ void SROMvRegBitsOff (DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byBits) * Return Value: TRUE if all test bits on; otherwise FALSE * */ -BOOL SROMbIsRegBitsOn (DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byTestBits) +BOOL SROMbIsRegBitsOn(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byTestBits) { BYTE byOrgData; @@ -245,7 +245,7 @@ BOOL SROMbIsRegBitsOn (DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byTestBits) * Return Value: TRUE if all test bits off; otherwise FALSE * */ -BOOL SROMbIsRegBitsOff (DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byTestBits) +BOOL SROMbIsRegBitsOff(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byTestBits) { BYTE byOrgData; @@ -266,11 +266,11 @@ BOOL SROMbIsRegBitsOff (DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byTestBits * Return Value: none * */ -void SROMvReadAllContents (DWORD_PTR dwIoBase, PBYTE pbyEepromRegs) +void SROMvReadAllContents(DWORD_PTR dwIoBase, PBYTE pbyEepromRegs) { int ii; - // ii = Rom Address + /* ii = Rom Address */ for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) { *pbyEepromRegs = SROMbyReadEmbedded(dwIoBase,(BYTE) ii); pbyEepromRegs++; @@ -291,11 +291,11 @@ void SROMvReadAllContents (DWORD_PTR dwIoBase, PBYTE pbyEepromRegs) * Return Value: none * */ -void SROMvWriteAllContents (DWORD_PTR dwIoBase, PBYTE pbyEepromRegs) +void SROMvWriteAllContents(DWORD_PTR dwIoBase, PBYTE pbyEepromRegs) { int ii; - // ii = Rom Address + /* ii = Rom Address */ for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) { SROMbWriteEmbedded(dwIoBase,(BYTE) ii, *pbyEepromRegs); pbyEepromRegs++; @@ -315,11 +315,11 @@ void SROMvWriteAllContents (DWORD_PTR dwIoBase, PBYTE pbyEepromRegs) * Return Value: none * */ -void SROMvReadEtherAddress (DWORD_PTR dwIoBase, PBYTE pbyEtherAddress) +void SROMvReadEtherAddress(DWORD_PTR dwIoBase, PBYTE pbyEtherAddress) { BYTE ii; - // ii = Rom Address + /* ii = Rom Address */ for (ii = 0; ii < U_ETHER_ADDR_LEN; ii++) { *pbyEtherAddress = SROMbyReadEmbedded(dwIoBase, ii); pbyEtherAddress++; @@ -340,11 +340,11 @@ void SROMvReadEtherAddress (DWORD_PTR dwIoBase, PBYTE pbyEtherAddress) * Return Value: none * */ -void SROMvWriteEtherAddress (DWORD_PTR dwIoBase, PBYTE pbyEtherAddress) +void SROMvWriteEtherAddress(DWORD_PTR dwIoBase, PBYTE pbyEtherAddress) { BYTE ii; - // ii = Rom Address + /* ii = Rom Address */ for (ii = 0; ii < U_ETHER_ADDR_LEN; ii++) { SROMbWriteEmbedded(dwIoBase, ii, *pbyEtherAddress); pbyEtherAddress++; @@ -364,15 +364,15 @@ void SROMvWriteEtherAddress (DWORD_PTR dwIoBase, PBYTE pbyEtherAddress) * Return Value: none * */ -void SROMvReadSubSysVenId (DWORD_PTR dwIoBase, PDWORD pdwSubSysVenId) +void SROMvReadSubSysVenId(DWORD_PTR dwIoBase, PDWORD pdwSubSysVenId) { PBYTE pbyData; pbyData = (PBYTE)pdwSubSysVenId; - // sub vendor + /* sub vendor */ *pbyData = SROMbyReadEmbedded(dwIoBase, 6); *(pbyData+1) = SROMbyReadEmbedded(dwIoBase, 7); - // sub system + /* sub system */ *(pbyData+2) = SROMbyReadEmbedded(dwIoBase, 8); *(pbyData+3) = SROMbyReadEmbedded(dwIoBase, 9); } @@ -389,7 +389,7 @@ void SROMvReadSubSysVenId (DWORD_PTR dwIoBase, PDWORD pdwSubSysVenId) * Return Value: TRUE if success; otherwise FALSE * */ -BOOL SROMbAutoLoad (DWORD_PTR dwIoBase) +BOOL SROMbAutoLoad(DWORD_PTR dwIoBase) { BYTE byWait; int ii; @@ -397,12 +397,12 @@ BOOL SROMbAutoLoad (DWORD_PTR dwIoBase) BYTE byOrg; VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg); - // turn on hardware retry + /* turn on hardware retry */ VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg | I2MCFG_NORETRY)); MACvRegBitsOn(dwIoBase, MAC_REG_I2MCSR, I2MCSR_AUTOLD); - // ii = Rom Address + /* ii = Rom Address */ for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) { MACvTimer0MicroSDelay(dwIoBase, CB_EEPROM_READBYTE_WAIT); VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait); -- cgit v1.2.3 From 646755ad9156eae5d19af5fd0e1a068f1f9d064c Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Mon, 22 Mar 2010 22:36:20 +0100 Subject: Staging: vt6655: CGI/CSI confusion in device_ioctl() The wrong messages were printed Signed-off-by: Roel Kluin Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index e40a2e990f4f..fde352bc4792 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -3328,7 +3328,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { break; case SIOCSIWTXPOW: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWTXPOW \n"); rc = -EOPNOTSUPP; break; @@ -3406,7 +3406,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { // Get the spy list case SIOCGIWSPY: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSPY \n"); rc = -EOPNOTSUPP; break; -- cgit v1.2.3 From 7c2c2eb7b2ea83e759d75bf362b161c264b98081 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 24 Mar 2010 22:16:55 -0700 Subject: Staging: cx25821: Hoist assign from if Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/cx25821/cx25821-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/cx25821/cx25821-core.c b/drivers/staging/cx25821/cx25821-core.c index 9e9b8c3c9311..eee4dc7b1941 100644 --- a/drivers/staging/cx25821/cx25821-core.c +++ b/drivers/staging/cx25821/cx25821-core.c @@ -1299,7 +1299,8 @@ int cx25821_risc_databuffer_audio(struct pci_dev *pci, instructions = 1 + (bpl * lines) / PAGE_SIZE + lines; instructions += 1; - if ((rc = btcx_riscmem_alloc(pci, risc, instructions * 12)) < 0) + rc = btcx_riscmem_alloc(pci, risc, instructions * 12); + if (rc < 0) return rc; /* write risc instructions */ -- cgit v1.2.3 From 92363b529f2ee08ee3fa14d590058e492ad49a1c Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 24 Mar 2010 22:16:57 -0700 Subject: Staging: otus: 80211core: Hoist assign from if Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/otus/80211core/cagg.c | 34 ++++--- drivers/staging/otus/80211core/ccmd.c | 3 +- drivers/staging/otus/80211core/cfunc.c | 3 +- drivers/staging/otus/80211core/cic.c | 9 +- drivers/staging/otus/80211core/cinit.c | 3 +- drivers/staging/otus/80211core/cmm.c | 144 ++++++++++++++++++++---------- drivers/staging/otus/80211core/cmmap.c | 103 +++++++++++++-------- drivers/staging/otus/80211core/cmmsta.c | 123 ++++++++++++++++--------- drivers/staging/otus/80211core/coid.c | 3 +- drivers/staging/otus/80211core/cpsmgr.c | 3 +- drivers/staging/otus/80211core/ctxrx.c | 81 +++++++++++------ drivers/staging/otus/80211core/queue.c | 5 +- drivers/staging/otus/80211core/ratectrl.c | 3 +- 13 files changed, 339 insertions(+), 178 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/otus/80211core/cagg.c b/drivers/staging/otus/80211core/cagg.c index f9514c06c14c..c3cef1a02aa4 100644 --- a/drivers/staging/otus/80211core/cagg.c +++ b/drivers/staging/otus/80211core/cagg.c @@ -2485,7 +2485,7 @@ void zfAggTxRetransmit(zdev_t* dev, struct bufInfo *buf_info, struct aggControl BAW->insert(dev, buf_info->buf, tid_tx->bar_ssn >> 4, aggControl->tid_baw, buf_info->baw_retransmit, &header_r); }*/ - if ((err = zfHpSend(dev, + err = zfHpSend(dev, buf_info->baw_header->header, buf_info->baw_header->headerLen, buf_info->baw_header->snap, @@ -2496,7 +2496,8 @@ void zfAggTxRetransmit(zdev_t* dev, struct bufInfo *buf_info, struct aggControl buf_info->baw_header->removeLen, ZM_EXTERNAL_ALLOC_BUF, (u8_t)tid_tx->ac, - buf_info->baw_header->keyIdx)) != ZM_SUCCESS) + buf_info->baw_header->keyIdx); + if (err != ZM_SUCCESS) { goto zlError; } @@ -2797,9 +2798,10 @@ u16_t zfAggTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, u16_t bufType, u8_t f BAW->insert(dev, buf, tid_tx->bar_ssn >> 4, aggControl->tid_baw, 0, &header_r); }*/ - if ((err = zfHpSend(dev, header, headerLen, snap, snapLen, + err = zfHpSend(dev, header, headerLen, snap, snapLen, mic, micLen, frag.buf[i], removeLen, - frag.bufType[i], zcUpToAc[up&0x7], keyIdx)) != ZM_SUCCESS) + frag.bufType[i], zcUpToAc[up&0x7], keyIdx); + if (err != ZM_SUCCESS) { goto zlError; } @@ -2849,7 +2851,8 @@ u16_t zfAggSendAddbaRequest(zdev_t* dev, u16_t *dst, u16_t ac, u16_t up) /* * TBD : Maximum size of management frame */ - if ((buf = zfwBufAllocate(dev, 1024)) == NULL) + buf = zfwBufAllocate(dev, 1024); + if (buf == NULL) { zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!"); return ZM_SUCCESS; @@ -2892,8 +2895,9 @@ u16_t zfAggSendAddbaRequest(zdev_t* dev, u16_t *dst, u16_t ac, u16_t up) //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data); #if 0 - if ((err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0, - ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS) + err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0, + ZM_INTERNAL_ALLOC_BUF, 0, 0xff); + if (err != ZM_SUCCESS) { goto zlError; } @@ -3290,7 +3294,8 @@ u16_t zfAggSendAddbaResponse(zdev_t* dev, struct aggBaFrameParameter *bf) /* * TBD : Maximum size of management frame */ - if ((buf = zfwBufAllocate(dev, 1024)) == NULL) + buf = zfwBufAllocate(dev, 1024); + if (buf == NULL) { zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!"); return ZM_SUCCESS; @@ -3337,8 +3342,9 @@ u16_t zfAggSendAddbaResponse(zdev_t* dev, struct aggBaFrameParameter *bf) //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data); #if 0 - if ((err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0, - ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS) + err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0, + ZM_INTERNAL_ALLOC_BUF, 0, 0xff); + if (err != ZM_SUCCESS) { goto zlError; } @@ -3443,7 +3449,8 @@ u16_t zfAggSendBar(zdev_t* dev, TID_TX tid_tx, struct aggBarControl *aggBarCon /* * TBD : Maximum size of management frame */ - if ((buf = zfwBufAllocate(dev, 1024)) == NULL) + buf = zfwBufAllocate(dev, 1024); + if (buf == NULL) { zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!"); return ZM_SUCCESS; @@ -3486,8 +3493,9 @@ u16_t zfAggSendBar(zdev_t* dev, TID_TX tid_tx, struct aggBarControl *aggBarCon //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data); #if 0 - if ((err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0, - ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS) + err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0, + ZM_INTERNAL_ALLOC_BUF, 0, 0xff); + if (err != ZM_SUCCESS) { goto zlError; } diff --git a/drivers/staging/otus/80211core/ccmd.c b/drivers/staging/otus/80211core/ccmd.c index 3e3d9b500f65..ab300df02014 100644 --- a/drivers/staging/otus/80211core/ccmd.c +++ b/drivers/staging/otus/80211core/ccmd.c @@ -1436,7 +1436,8 @@ u16_t zfiWlanDeauth(zdev_t *dev, u16_t *macAddr, u16_t reason) */ /* - if ((id = zfApFindSta(dev, macAddr)) != 0xffff) + id = zfApFindSta(dev, macAddr); + if (id != 0xffff) { u32_t key[8]; u16_t nullAddr[3] = { 0x0, 0x0, 0x0 }; diff --git a/drivers/staging/otus/80211core/cfunc.c b/drivers/staging/otus/80211core/cfunc.c index e0a9f383c755..3b9341b13c02 100644 --- a/drivers/staging/otus/80211core/cfunc.c +++ b/drivers/staging/otus/80211core/cfunc.c @@ -1072,7 +1072,8 @@ u16_t zfFindCleanFrequency(zdev_t* dev, u32_t adhocMode) zmw_get_wlan_dev(dev); - if ((pBssInfo = wd->sta.bssList.head) == NULL) + pBssInfo = wd->sta.bssList.head; + if (pBssInfo == NULL) { if( adhocMode == ZM_ADHOCBAND_B || adhocMode == ZM_ADHOCBAND_G || adhocMode == ZM_ADHOCBAND_BG || adhocMode == ZM_ADHOCBAND_ABG ) diff --git a/drivers/staging/otus/80211core/cic.c b/drivers/staging/otus/80211core/cic.c index c84f079e3d84..53c09a0935fc 100644 --- a/drivers/staging/otus/80211core/cic.c +++ b/drivers/staging/otus/80211core/cic.c @@ -329,7 +329,8 @@ void zfCoreEvent(zdev_t* dev, u16_t event, u8_t* rsp) if (wd->wlanMode == ZM_MODE_AP) { zmw_enter_critical_section(dev); - if ((i=zfApFindSta(dev, (u16_t*)rsp)) != 0xffff) + i = zfApFindSta(dev, (u16_t*)rsp); + if (i != 0xffff) { zfRateCtrlTxFailEvent(dev, &wd->ap.staTable[i].rcCell, 0,(u32_t)zfPhyCtrlToRate(retryRate)); } @@ -357,7 +358,8 @@ void zfCoreEvent(zdev_t* dev, u16_t event, u8_t* rsp) if (wd->wlanMode == ZM_MODE_AP) { zmw_enter_critical_section(dev); - if ((i=zfApFindSta(dev, (u16_t*)rsp)) != 0xffff) + i = zfApFindSta(dev, (u16_t*)rsp); + if (i != 0xffff) { zfRateCtrlTxFailEvent(dev, &wd->ap.staTable[i].rcCell, 0,(u32_t)zfPhyCtrlToRate(retryRate)); } @@ -387,7 +389,8 @@ void zfCoreEvent(zdev_t* dev, u16_t event, u8_t* rsp) if (wd->wlanMode == ZM_MODE_AP) { zmw_enter_critical_section(dev); - if ((i=zfApFindSta(dev, (u16_t*)rsp)) != 0xffff) + i = zfApFindSta(dev, (u16_t*)rsp); + if (i != 0xffff) { zfRateCtrlTxSuccessEvent(dev, &wd->ap.staTable[i].rcCell, zfPhyCtrlToRate(retryRate)); } diff --git a/drivers/staging/otus/80211core/cinit.c b/drivers/staging/otus/80211core/cinit.c index 5f853ce79309..11823311e9ce 100644 --- a/drivers/staging/otus/80211core/cinit.c +++ b/drivers/staging/otus/80211core/cinit.c @@ -622,7 +622,8 @@ u16_t zfTxGenWlanHeader(zdev_t* dev, zbuf_t* buf, u16_t* header, u16_t seq, phyCtrl = 0xc0001; //PHY control L /* WDS port checking */ - if ((wdsPort = (port - 0x20)) >= ZM_MAX_WDS_SUPPORT) + wdsPort = port - 0x20; + if (wdsPort >= ZM_MAX_WDS_SUPPORT) { wdsPort = 0; } diff --git a/drivers/staging/otus/80211core/cmm.c b/drivers/staging/otus/80211core/cmm.c index 484e753df358..007ef3b606a5 100644 --- a/drivers/staging/otus/80211core/cmm.c +++ b/drivers/staging/otus/80211core/cmm.c @@ -83,7 +83,8 @@ u16_t zfFindElement(zdev_t* dev, zbuf_t* buf, u8_t eid) /* Get offset of first element */ subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4); - if ((offset = zgElementOffsetTable[subType]) == 0xff) + offset = zgElementOffsetTable[subType]; + if (offset == 0xff) { zm_assert(0); } @@ -107,10 +108,12 @@ u16_t zfFindElement(zdev_t* dev, zbuf_t* buf, u8_t eid) while ((offset+2)(bufLen - offset)) + elen = zmw_rx_buf_readb(dev, buf, offset+1); + if (elen > bufLen - offset) { /* Element length error */ return 0xffff; @@ -151,7 +154,8 @@ u16_t zfFindElement(zdev_t* dev, zbuf_t* buf, u8_t eid) #if 1 elen = zmw_rx_buf_readb(dev, buf, offset+1); #else - if ((elen = zmw_rx_buf_readb(dev, buf, offset+1)) == 0) + elen = zmw_rx_buf_readb(dev, buf, offset+1); + if (elen == 0) { return 0xffff; } @@ -194,7 +198,8 @@ u16_t zfFindWifiElement(zdev_t* dev, zbuf_t* buf, u8_t type, u8_t subtype) /* Get offset of first element */ subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4); - if ((offset = zgElementOffsetTable[subType]) == 0xff) + offset = zgElementOffsetTable[subType]; + if (offset == 0xff) { zm_assert(0); } @@ -207,10 +212,12 @@ u16_t zfFindWifiElement(zdev_t* dev, zbuf_t* buf, u8_t type, u8_t subtype) while ((offset+2)(bufLen - offset)) + elen = zmw_rx_buf_readb(dev, buf, offset+1); + if (elen > bufLen - offset) { /* Element length error */ return 0xffff; @@ -229,7 +236,8 @@ u16_t zfFindWifiElement(zdev_t* dev, zbuf_t* buf, u8_t type, u8_t subtype) { if ( subtype != 0xff ) { - if ( (tmp = zmw_rx_buf_readb(dev, buf, offset+6)) == subtype ) + tmp = zmw_rx_buf_readb(dev, buf, offset+6); + if (tmp == subtype) { return offset; } @@ -241,7 +249,8 @@ u16_t zfFindWifiElement(zdev_t* dev, zbuf_t* buf, u8_t type, u8_t subtype) } } /* Advance to next element */ - if ((elen = zmw_rx_buf_readb(dev, buf, offset+1)) == 0) + elen = zmw_rx_buf_readb(dev, buf, offset+1); + if (elen == 0) { return 0xffff; } @@ -348,7 +357,8 @@ u16_t zfFindSuperGElement(zdev_t* dev, zbuf_t* buf, u8_t type) /* Get offset of first element */ subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4); - if ((offset = zgElementOffsetTable[subType]) == 0xff) + offset = zgElementOffsetTable[subType]; + if (offset == 0xff) { zm_assert(0); } @@ -361,10 +371,12 @@ u16_t zfFindSuperGElement(zdev_t* dev, zbuf_t* buf, u8_t type) while ((offset+2)(bufLen - offset)) + elen = zmw_rx_buf_readb(dev, buf, offset+1); + if (elen > bufLen - offset) { /* Element length error */ return 0xffff; @@ -389,7 +401,8 @@ u16_t zfFindSuperGElement(zdev_t* dev, zbuf_t* buf, u8_t type) #if 1 elen = zmw_rx_buf_readb(dev, buf, offset+1); #else - if ((elen = zmw_rx_buf_readb(dev, buf, offset+1)) == 0) + elen = zmw_rx_buf_readb(dev, buf, offset+1); + if (elen == 0) { return 0xffff; } @@ -411,7 +424,8 @@ u16_t zfFindXRElement(zdev_t* dev, zbuf_t* buf, u8_t type) /* Get offset of first element */ subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4); - if ((offset = zgElementOffsetTable[subType]) == 0xff) + offset = zgElementOffsetTable[subType]; + if (offset == 0xff) { zm_assert(0); } @@ -424,10 +438,12 @@ u16_t zfFindXRElement(zdev_t* dev, zbuf_t* buf, u8_t type) while ((offset+2)(bufLen - offset)) + elen = zmw_rx_buf_readb(dev, buf, offset+1); + if (elen > bufLen - offset) { /* Element length error */ return 0xffff; @@ -447,7 +463,8 @@ u16_t zfFindXRElement(zdev_t* dev, zbuf_t* buf, u8_t type) #if 1 elen = zmw_rx_buf_readb(dev, buf, offset+1); #else - if ((elen = zmw_rx_buf_readb(dev, buf, offset+1)) == 0) + elen = zmw_rx_buf_readb(dev, buf, offset+1); + if (elen == 0) { return 0xffff; } @@ -868,7 +885,8 @@ void zfSendMmFrame(zdev_t* dev, u8_t frameType, u16_t* dst, zm_msg2_mm(ZM_LV_2, "Send mm frame, type=", frameType); /* TBD : Maximum size of management frame */ - if ((buf = zfwBufAllocate(dev, 1024)) == NULL) + buf = zfwBufAllocate(dev, 1024); + if (buf == NULL) { zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!"); return; @@ -1257,7 +1275,8 @@ void zfSendMmFrame(zdev_t* dev, u8_t frameType, u16_t* dst, { vap = (u16_t) p3; - if ((aid = zfApFindSta(dev, dst)) != 0xffff) + aid = zfApFindSta(dev, dst); + if (aid != 0xffff) { zmw_enter_critical_section(dev); /* Clear STA table */ @@ -1303,8 +1322,9 @@ void zfSendMmFrame(zdev_t* dev, u8_t frameType, u16_t* dst, //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data); #if 0 - if ((err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0, - ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS) + err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0, + ZM_INTERNAL_ALLOC_BUF, 0, 0xff); + if (err != ZM_SUCCESS) { goto zlError; } @@ -1366,7 +1386,8 @@ void zfProcessManagement(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInf if ((ra[0] & 0x1) != 1) { /* AP : Find virtual AP */ - if ((index = zfApFindSta(dev, ta)) != 0xffff) + index = zfApFindSta(dev, ta); + if (index != 0xffff) { vap = wd->ap.staTable[index].vap; } @@ -1534,7 +1555,8 @@ void zfProcessProbeReq(zdev_t* dev, zbuf_t* buf, u16_t* src) } /* check SSID */ - if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID)) == 0xffff) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID); + if (offset == 0xffff) { zm_msg0_mm(ZM_LV_3, "probe req SSID not found"); return; @@ -1561,8 +1583,8 @@ void zfProcessProbeReq(zdev_t* dev, zbuf_t* buf, u16_t* src) { for (j=0; jap.ssid[i][j]) + ch = zmw_rx_buf_readb(dev, buf, offset+2+j); + if (ch != wd->ap.ssid[i][j]) { break; } @@ -1814,7 +1836,8 @@ u16_t zfFindATHExtCap(zdev_t* dev, zbuf_t* buf, u8_t type, u8_t subtype) /* Get offset of first element */ subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4); - if ((offset = zgElementOffsetTable[subType]) == 0xff) + offset = zgElementOffsetTable[subType]; + if (offset == 0xff) { zm_assert(0); } @@ -1828,10 +1851,12 @@ u16_t zfFindATHExtCap(zdev_t* dev, zbuf_t* buf, u8_t type, u8_t subtype) while ((offset+2)(bufLen - offset)) + elen = zmw_rx_buf_readb(dev, buf, offset+1); + if (elen > bufLen - offset) { /* Element length error */ return 0xffff; @@ -1850,7 +1875,8 @@ u16_t zfFindATHExtCap(zdev_t* dev, zbuf_t* buf, u8_t type, u8_t subtype) { if ( subtype != 0xff ) { - if ( (tmp = zmw_rx_buf_readb(dev, buf, offset+6)) == subtype ) + tmp = zmw_rx_buf_readb(dev, buf, offset+6); + if (tmp == subtype ) { return offset; } @@ -1863,7 +1889,8 @@ u16_t zfFindATHExtCap(zdev_t* dev, zbuf_t* buf, u8_t type, u8_t subtype) } /* Advance to next element */ - if ((elen = zmw_rx_buf_readb(dev, buf, offset+1)) == 0) + elen = zmw_rx_buf_readb(dev, buf, offset+1); + if (elen == 0) { return 0xffff; } @@ -1884,7 +1911,8 @@ u16_t zfFindBrdcmMrvlRlnkExtCap(zdev_t* dev, zbuf_t* buf) /* Get offset of first element */ subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4); - if ((offset = zgElementOffsetTable[subType]) == 0xff) + offset = zgElementOffsetTable[subType]; + if (offset == 0xff) { zm_assert(0); } @@ -1898,10 +1926,12 @@ u16_t zfFindBrdcmMrvlRlnkExtCap(zdev_t* dev, zbuf_t* buf) while ((offset+2)(bufLen - offset)) + elen = zmw_rx_buf_readb(dev, buf, offset+1); + if (elen > bufLen - offset) { /* Element length error */ return 0xffff; @@ -1930,7 +1960,8 @@ u16_t zfFindBrdcmMrvlRlnkExtCap(zdev_t* dev, zbuf_t* buf) else if ((id = zmw_rx_buf_readb(dev, buf, offset)) == 0x7F) { /* Bingo */ - if ((elen = zmw_rx_buf_readb(dev, buf, offset+1))>(bufLen - offset)) + elen = zmw_rx_buf_readb(dev, buf, offset+1); + if (elen > bufLen - offset) { /* Element length error */ return 0xffff; @@ -1941,7 +1972,8 @@ u16_t zfFindBrdcmMrvlRlnkExtCap(zdev_t* dev, zbuf_t* buf) return 0xffff; } - if ((tmp = zmw_rx_buf_readb(dev, buf, offset+2)) == 0x01) + tmp = zmw_rx_buf_readb(dev, buf, offset+2); + if (tmp == 0x01) { return offset; @@ -1949,7 +1981,8 @@ u16_t zfFindBrdcmMrvlRlnkExtCap(zdev_t* dev, zbuf_t* buf) } /* Advance to next element */ - if ((elen = zmw_rx_buf_readb(dev, buf, offset+1)) == 0) + elen = zmw_rx_buf_readb(dev, buf, offset+1); + if (elen == 0) { return 0xffff; } @@ -1970,7 +2003,8 @@ u16_t zfFindMarvelExtCap(zdev_t* dev, zbuf_t* buf) /* Get offset of first element */ subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4); - if ((offset = zgElementOffsetTable[subType]) == 0xff) + offset = zgElementOffsetTable[subType]; + if (offset == 0xff) { zm_assert(0); } @@ -1984,10 +2018,12 @@ u16_t zfFindMarvelExtCap(zdev_t* dev, zbuf_t* buf) while ((offset+2)(bufLen - offset)) + elen = zmw_rx_buf_readb(dev, buf, offset+1); + if (elen>(bufLen - offset)) { /* Element length error */ return 0xffff; @@ -2008,7 +2044,8 @@ u16_t zfFindMarvelExtCap(zdev_t* dev, zbuf_t* buf) } /* Advance to next element */ - if ((elen = zmw_rx_buf_readb(dev, buf, offset+1)) == 0) + elen = zmw_rx_buf_readb(dev, buf, offset+1); + if (elen == 0) { return 0xffff; } @@ -2029,7 +2066,8 @@ u16_t zfFindBroadcomExtCap(zdev_t* dev, zbuf_t* buf) /* Get offset of first element */ subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4); - if ((offset = zgElementOffsetTable[subType]) == 0xff) + offset = zgElementOffsetTable[subType]; + if (offset == 0xff) { zm_assert(0); } @@ -2043,10 +2081,12 @@ u16_t zfFindBroadcomExtCap(zdev_t* dev, zbuf_t* buf) while((offset+2) < bufLen) // including element ID and length (2bytes) { /* Search target element */ - if ((id = zmw_rx_buf_readb(dev, buf, offset)) == ZM_WLAN_EID_WIFI_IE) + id = zmw_rx_buf_readb(dev, buf, offset); + if (id == ZM_WLAN_EID_WIFI_IE) { /* Bingo */ - if ((elen = zmw_rx_buf_readb(dev, buf, offset+1)) > (bufLen - offset)) + elen = zmw_rx_buf_readb(dev, buf, offset+1); + if (elen > (bufLen - offset)) { /* Element length error */ return 0xffff; @@ -2066,7 +2106,8 @@ u16_t zfFindBroadcomExtCap(zdev_t* dev, zbuf_t* buf) } /* Advance to next element */ - if ((elen = zmw_rx_buf_readb(dev, buf, offset+1)) == 0) + elen = zmw_rx_buf_readb(dev, buf, offset+1); + if (elen == 0) { return 0xffff; } @@ -2089,7 +2130,8 @@ u16_t zfFindRlnkExtCap(zdev_t* dev, zbuf_t* buf) /* Get offset of first element */ subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4); - if ((offset = zgElementOffsetTable[subType]) == 0xff) + offset = zgElementOffsetTable[subType]; + if (offset == 0xff) { zm_assert(0); } @@ -2103,10 +2145,12 @@ u16_t zfFindRlnkExtCap(zdev_t* dev, zbuf_t* buf) while((offset+2) < bufLen) // including element ID and length (2bytes) { /* Search target element */ - if ((id = zmw_rx_buf_readb(dev, buf, offset)) == 0x7F) + id = zmw_rx_buf_readb(dev, buf, offset); + if (id == 0x7F) { /* Bingo */ - if ((elen = zmw_rx_buf_readb(dev, buf, offset+1)) > (bufLen - offset)) + elen = zmw_rx_buf_readb(dev, buf, offset+1); + if (elen > bufLen - offset) { /* Element length error */ return 0xffff; @@ -2117,7 +2161,8 @@ u16_t zfFindRlnkExtCap(zdev_t* dev, zbuf_t* buf) return 0xffff; } - if ((tmp = zmw_rx_buf_readb(dev, buf, offset+2)) == 0x01) + tmp = zmw_rx_buf_readb(dev, buf, offset+2); + if (tmp == 0x01) { return offset; @@ -2125,7 +2170,8 @@ u16_t zfFindRlnkExtCap(zdev_t* dev, zbuf_t* buf) } /* Advance to next element */ - if ((elen = zmw_rx_buf_readb(dev, buf, offset+1)) == 0) + elen = zmw_rx_buf_readb(dev, buf, offset+1); + if (elen == 0) { return 0xffff; } diff --git a/drivers/staging/otus/80211core/cmmap.c b/drivers/staging/otus/80211core/cmmap.c index 7f09fded459e..8ec3830e8439 100644 --- a/drivers/staging/otus/80211core/cmmap.c +++ b/drivers/staging/otus/80211core/cmmap.c @@ -141,7 +141,8 @@ u16_t zfApGetSTAInfo(zdev_t* dev, u16_t* addr, u16_t* state, u8_t* vap) zmw_enter_critical_section(dev); - if ((id = zfApFindSta(dev, addr)) != 0xffff) + id = zfApFindSta(dev, addr); + if (id != 0xffff) { *vap = wd->ap.staTable[id].vap; *state = wd->ap.staTable[id++].state; @@ -163,7 +164,8 @@ void zfApGetStaQosType(zdev_t* dev, u16_t* addr, u8_t* qosType) zmw_enter_critical_section(dev); - if ((id = zfApFindSta(dev, addr)) != 0xffff) + id = zfApFindSta(dev, addr); + if (id != 0xffff) { *qosType = wd->ap.staTable[id].qosType; } @@ -189,7 +191,8 @@ void zfApGetStaTxRateAndQosType(zdev_t* dev, u16_t* addr, u32_t* phyCtrl, zmw_enter_critical_section(dev); - if ((id = zfApFindSta(dev, addr)) != 0xffff) + id = zfApFindSta(dev, addr); + if (id != 0xffff) { rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->ap.staTable[id].rcCell, rcProbingFlag); #ifdef ZM_AP_DEBUG @@ -234,7 +237,8 @@ void zfApGetStaEncryType(zdev_t* dev, u16_t* addr, u8_t* encryType) zmw_enter_critical_section(dev); - if ((id = zfApFindSta(dev, addr)) != 0xffff) + id = zfApFindSta(dev, addr); + if (id != 0xffff) { *encryType = wd->ap.staTable[id].encryMode; } @@ -260,7 +264,8 @@ void zfApGetStaWpaIv(zdev_t* dev, u16_t* addr, u16_t* iv16, u32_t* iv32) zmw_enter_critical_section(dev); - if ((id = zfApFindSta(dev, addr)) != 0xffff) + id = zfApFindSta(dev, addr); + if (id != 0xffff) { *iv16 = wd->ap.staTable[id].iv16; *iv32 = wd->ap.staTable[id].iv32; @@ -289,7 +294,8 @@ void zfApSetStaWpaIv(zdev_t* dev, u16_t* addr, u16_t iv16, u32_t iv32) zmw_enter_critical_section(dev); - if ((id = zfApFindSta(dev, addr)) != 0xffff) + id = zfApFindSta(dev, addr); + if (id != 0xffff) { wd->ap.staTable[id].iv16 = iv16; wd->ap.staTable[id].iv32 = iv32; @@ -321,7 +327,8 @@ void zfApClearStaKey(zdev_t* dev, u16_t* addr) zmw_enter_critical_section(dev); - if ((id = zfApFindSta(dev, addr)) != 0xffff) + id = zfApFindSta(dev, addr); + if (id != 0xffff) { /* Turn off STA's key information */ zfHpRemoveKey(dev, id+1); @@ -348,7 +355,8 @@ void zfApGetStaCencIvAndKeyIdx(zdev_t* dev, u16_t* addr, u32_t *iv, u8_t *keyIdx zmw_enter_critical_section(dev); - if ((id = zfApFindSta(dev, addr)) != 0xffff) + id = zfApFindSta(dev, addr); + if (id != 0xffff) { *iv++ = wd->ap.staTable[id].txiv[0]; *iv++ = wd->ap.staTable[id].txiv[1]; @@ -379,7 +387,8 @@ void zfApSetStaCencIv(zdev_t* dev, u16_t* addr, u32_t *iv) zmw_enter_critical_section(dev); - if ((id = zfApFindSta(dev, addr)) != 0xffff) + id = zfApFindSta(dev, addr); + if (id != 0xffff) { wd->ap.staTable[id].txiv[0] = *iv++; wd->ap.staTable[id].txiv[1] = *iv++; @@ -539,7 +548,8 @@ u16_t zfApBufferPsFrame(zdev_t* dev, zbuf_t* buf, u16_t port) { zmw_enter_critical_section(dev); - if ((id = zfApFindSta(dev, addr)) != 0xffff) + id = zfApFindSta(dev, addr); + if (id != 0xffff) { if (wd->ap.staTable[id].psMode == 1) { @@ -603,7 +613,8 @@ u16_t zfApGetSTAInfoAndUpdatePs(zdev_t* dev, u16_t* addr, u16_t* state, //psMode=0; #endif - if ((id = zfApFindSta(dev, addr)) != 0xffff) + id = zfApFindSta(dev, addr); + if (id != 0xffff) { if (psMode != 0) { @@ -648,7 +659,8 @@ u16_t zfApGetSTAInfoAndUpdatePs(zdev_t* dev, u16_t* addr, u16_t* state, while (1) { - if ((psBuf = zfQueueGetWithMac(dev, wd->ap.uapsdQ, (u8_t*)addr, &mb)) != NULL) + psBuf = zfQueueGetWithMac(dev, wd->ap.uapsdQ, (u8_t*)addr, &mb); + if (psBuf != NULL) { zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, 0); } @@ -730,7 +742,8 @@ u16_t zfApAddSta(zdev_t* dev, u16_t* addr, u16_t state, u16_t apId, u8_t type, zmw_enter_critical_section(dev); - if ((index = zfApFindSta(dev, addr)) != 0xffff) + index = zfApFindSta(dev, addr); + if (index != 0xffff) { zm_msg0_mm(ZM_LV_2, "found"); /* Update STA state */ @@ -963,7 +976,8 @@ void zfApProcessBeacon(zdev_t* dev, zbuf_t* buf) zm_msg0_mm(ZM_LV_3, "Rx beacon"); /* update Non-ERP flag(wd->ap.nonErpObss) */ - if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP)) == 0xffff) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP); + if (offset == 0xffff) { /* 11b OBSS */ wd->ap.protectedObss++; @@ -1046,7 +1060,8 @@ void zfApProcessAuth(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId) if (seq == 1) { /* AP : update STA to auth */ - if ((ret = zfApAddSta(dev, src, ZM_STATE_AUTH, apId, 0, 0, 0)) != 0xffff) + ret = zfApAddSta(dev, src, ZM_STATE_AUTH, apId, 0, 0, 0); + if (ret != 0xffff) { /* AP : call zfwAuthNotify() for host to judge */ //zfwAuthNotify(dev, src); @@ -1177,12 +1192,14 @@ void zfApProcessAsocReq(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId) zmw_get_wlan_dev(dev); /* AP : check SSID */ - if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID)) != 0xffff) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID); + if (offset != 0xffff) { k = 0; for (j = 0; j < wd->ap.vapNumber; j++) { - if ((tmp = zmw_buf_readb(dev, buf, offset+1)) + tmp = zmw_buf_readb(dev, buf, offset+1); + if (tmp != wd->ap.ssidLen[j]) { k++; @@ -1198,7 +1215,8 @@ void zfApProcessAsocReq(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId) { for (i=0; iap.ssidLen[j]; i++) { - if ((tmp = zmw_buf_readb(dev, buf, offset+2+i)) + tmp = zmw_buf_readb(dev, buf, offset+2+i); + if (tmp != wd->ap.ssid[j][i]) { break; @@ -1222,13 +1240,15 @@ void zfApProcessAsocReq(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId) /* TODO : check capability */ /* AP : check support rate */ - if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE)) != 0xffff) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE); + if (offset != 0xffff) { /* 11g STA */ staType = 1; } //CWYang(+) - if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY)) != 0xffff) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY); + if (offset != 0xffff) { /* 11n STA */ staType = 2; @@ -1251,7 +1271,8 @@ void zfApProcessAsocReq(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId) /* AP : check 11h */ /* AP : check WME */ - if ((offset = zfFindWifiElement(dev, buf, 2, 0)) != 0xffff) + offset = zfFindWifiElement(dev, buf, 2, 0); + if (offset != 0xffff) { /* WME STA */ qosType = 1; @@ -1265,7 +1286,8 @@ void zfApProcessAsocReq(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId) if (wd->ap.wpaSupport[apId] == 1) { - if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_WPA_IE)) != 0xffff ) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_WPA_IE); + if (offset != 0xffff) { /* get WPA IE */ u8_t length = zmw_rx_buf_readb(dev, buf, offset+1); @@ -1406,12 +1428,14 @@ void zfApStoreAsocReqIe(zdev_t* dev, zbuf_t* buf, u16_t aid) offset = 28; /* supported rates */ - if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_SUPPORT_RATE)) == 0xffff) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_SUPPORT_RATE); + if (offset == 0xffff) return; length = zmw_rx_buf_readb(dev, buf, offset + 1); /* extended supported rates */ - if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE)) == 0xffff) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE); + if (offset == 0xffff) return; length = zmw_rx_buf_readb(dev, buf, offset + 1); @@ -1426,7 +1450,8 @@ void zfApStoreAsocReqIe(zdev_t* dev, zbuf_t* buf, u16_t aid) /* QoS */ /* HT capabilities: 28 octets */ - if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY)) != 0xffff) { + offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY); + if (offset != 0xffff) { /* atheros pre n */ htcap = (u8_t *)&wd->ap.ie[aid].HtCap; htcap[0] = zmw_rx_buf_readb(dev, buf, offset); @@ -1479,7 +1504,8 @@ void zfApProcessDeauth(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId) zmw_enter_critical_section(dev); /* AP : if SA=associated STA then deauthenticate STA */ - if ((aid = zfApFindSta(dev, src)) != 0xffff) + aid = zfApFindSta(dev, src); + if (aid != 0xffff) { /* Clear STA table */ wd->ap.staTable[aid].valid = 0; @@ -1500,7 +1526,8 @@ void zfApProcessDisasoc(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId) zmw_enter_critical_section(dev); /* AP : if SA=associated STA then deauthenticate STA */ - if ((aid = zfApFindSta(dev, src)) != 0xffff) + aid = zfApFindSta(dev, src); + if (aid != 0xffff) { /* Clear STA table */ wd->ap.staTable[aid].valid = 0; @@ -1674,7 +1701,8 @@ u16_t zfApAddIeTim(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap) dst[0] = zmw_tx_buf_readh(dev, psBuf, 0); dst[1] = zmw_tx_buf_readh(dev, psBuf, 2); dst[2] = zmw_tx_buf_readh(dev, psBuf, 4); - if ((aid = zfApFindSta(dev, dst)) != 0xffff) + aid = zfApFindSta(dev, dst); + if (aid != 0xffff) { if (wd->ap.staTable[aid].psMode != 0) { @@ -1896,7 +1924,8 @@ void zfApSendBeacon(zdev_t* dev) zm_msg1_mm(ZM_LV_2, "Send beacon, vap=", vap); /* TBD : Maximum size of beacon */ - if ((buf = zfwBufAllocate(dev, 1024)) == NULL) + buf = zfwBufAllocate(dev, 1024); + if (buf == NULL) { zm_msg0_mm(ZM_LV_0, "Alloc beacon buf Fail!"); return; @@ -2101,8 +2130,8 @@ u16_t zfIntrabssForward(zdev_t* dev, zbuf_t* buf, u8_t srcVap) if ((asocFlag == 1) || ((dst[0]&0x1) == 0x1)) { /* Allocate frame */ - if ((txBuf = zfwBufAllocate(dev, ZM_RX_FRAME_SIZE)) - == NULL) + txBuf = zfwBufAllocate(dev, ZM_RX_FRAME_SIZE); + if (txBuf == NULL) { zm_msg0_rx(ZM_LV_1, "Alloc intra-bss buf Fail!"); goto zlAllocError; @@ -2133,7 +2162,8 @@ u16_t zfIntrabssForward(zdev_t* dev, zbuf_t* buf, u8_t srcVap) /* Transmit frame */ /* Return error if port is disabled */ - if ((err = zfTxPortControl(dev, txBuf, vap)) == ZM_PORT_DISABLED) + err = zfTxPortControl(dev, txBuf, vap); + if (err == ZM_PORT_DISABLED) { err = ZM_ERR_TX_PORT_DISABLED; goto zlTxError; @@ -2141,7 +2171,8 @@ u16_t zfIntrabssForward(zdev_t* dev, zbuf_t* buf, u8_t srcVap) #if 1 /* AP : Buffer frame for power saving STA */ - if ((ret = zfApBufferPsFrame(dev, txBuf, vap)) == 0) + ret = zfApBufferPsFrame(dev, txBuf, vap); + if (ret == 0) { /* forward frame if not been buffered */ #if 1 @@ -2177,7 +2208,8 @@ struct zsMicVar* zfApGetRxMicKey(zdev_t* dev, zbuf_t* buf) macAddr[1] = sa[2] + (sa[3] << 8); macAddr[2] = sa[4] + (sa[5] << 8); - if ((id = zfApFindSta(dev, macAddr)) != 0xffff) + id = zfApFindSta(dev, macAddr); + if (id != 0xffff) return (&wd->ap.staTable[id].rxMicKey); return NULL; @@ -2369,7 +2401,8 @@ void zfApSendFailure(zdev_t* dev, u8_t* addr) staAddr[1] = addr[2] + (((u16_t)addr[3])<<8); staAddr[2] = addr[4] + (((u16_t)addr[5])<<8); zmw_enter_critical_section(dev); - if ((id = zfApFindSta(dev, staAddr)) != 0xffff) + id = zfApFindSta(dev, staAddr); + if (id != 0xffff) { /* Send failture : Add 3 minutes to inactive time that will */ /* will make STA been kicked out soon */ diff --git a/drivers/staging/otus/80211core/cmmsta.c b/drivers/staging/otus/80211core/cmmsta.c index c3fd47529c14..0fda30d05ed2 100644 --- a/drivers/staging/otus/80211core/cmmsta.c +++ b/drivers/staging/otus/80211core/cmmsta.c @@ -602,7 +602,8 @@ void zfStaProtErpMonitor(zdev_t* dev, zbuf_t* buf) if (zfRxBufferEqualToStr(dev, buf, bssid, ZM_WLAN_HEADER_A2_OFFSET, 6)) { - if ( (offset=zfFindElement(dev, buf, ZM_WLAN_EID_ERP)) != 0xffff ) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP); + if (offset != 0xffff) { erp = zmw_rx_buf_readb(dev, buf, offset+2); @@ -628,7 +629,8 @@ void zfStaProtErpMonitor(zdev_t* dev, zbuf_t* buf) } //Check the existence of Non-N AP //Follow the check the "pBssInfo->EnableHT" - if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY)) != 0xffff) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY); + if (offset != 0xffff) {} else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTCAPABILITY)) != 0xffff) {} @@ -658,9 +660,11 @@ void zfStaUpdateWmeParameter(zdev_t* dev, zbuf_t* buf) if (wd->sta.wmeConnected != 0) { /* Find WME parameter element */ - if ((offset = zfFindWifiElement(dev, buf, 2, 1)) != 0xffff) + offset = zfFindWifiElement(dev, buf, 2, 1); + if (offset != 0xffff) { - if ((len = zmw_rx_buf_readb(dev, buf, offset+1)) >= 7) + len = zmw_rx_buf_readb(dev, buf, offset+1); + if (len >= 7) { rxWmeParameterSetCount=zmw_rx_buf_readb(dev, buf, offset+8); if (rxWmeParameterSetCount != wd->sta.wmeParameterSetCount) @@ -741,7 +745,8 @@ void zfStaUpdateDot11HDFS(zdev_t* dev, zbuf_t* buf) */ /* get EID(Channel Switch Announcement) */ - if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_CHANNEL_SWITCH_ANNOUNCE)) == 0xffff ) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_CHANNEL_SWITCH_ANNOUNCE); + if (offset == 0xffff) { //zm_debug_msg0("EID(Channel Switch Announcement) not found"); return; @@ -1216,7 +1221,8 @@ void zfStaSendBeacon(zdev_t* dev) //zm_debug_msg0("\n"); /* TBD : Maximum size of beacon */ - if ((buf = zfwBufAllocate(dev, 1024)) == NULL) + buf = zfwBufAllocate(dev, 1024); + if (buf == NULL) { zm_debug_msg0("Allocate beacon buffer failed"); return; @@ -1370,7 +1376,8 @@ struct zsBssInfo* zfStaFindBssInfo(zdev_t* dev, zbuf_t* buf, struct zsWlanProbeR zmw_get_wlan_dev(dev); - if ((pBssInfo = wd->sta.bssList.head) == NULL) + pBssInfo = wd->sta.bssList.head; + if (pBssInfo == NULL) { return NULL; } @@ -1420,8 +1427,10 @@ struct zsBssInfo* zfStaFindBssInfo(zdev_t* dev, zbuf_t* buf, struct zsWlanProbeR /* Check channel */ /* Add check channel to solve the bug #31222 */ if (isMatched) { - if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_DS)) != 0xffff) { - if ((length = zmw_rx_buf_readb(dev, buf, offset+1)) == 1) { + offset = zfFindElement(dev, buf, ZM_WLAN_EID_DS); + if (offset != 0xffff) { + length = zmw_rx_buf_readb(dev, buf, offset+1); + if (length == 1) { channel = zmw_rx_buf_readb(dev, buf, offset+2); if (zfHpIsAllowedChannel(dev, zfChNumToFreq(dev, channel, 0)) == 0) { frequency = 0; @@ -1473,7 +1482,8 @@ u8_t zfStaInitBssInfo(zdev_t* dev, zbuf_t* buf, } /* get SSID */ - if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID)) == 0xffff ) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID); + if (offset == 0xffff) { zm_debug_msg0("EID(SSID) not found"); goto zlError; @@ -1506,7 +1516,8 @@ u8_t zfStaInitBssInfo(zdev_t* dev, zbuf_t* buf, zfCopyFromRxBuffer(dev, buf, pBssInfo->ssid, offset, length+2); /* get DS parameter */ - if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_DS)) != 0xffff ) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_DS); + if (offset != 0xffff) { length = zmw_rx_buf_readb(dev, buf, offset+1); if ( length != 1 ) @@ -1590,7 +1601,8 @@ u8_t zfStaInitBssInfo(zdev_t* dev, zbuf_t* buf, pBssInfo->frameBodysize = accumulateLen; /* get supported rates */ - if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_SUPPORT_RATE)) == 0xffff ) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_SUPPORT_RATE); + if (offset == 0xffff) { zm_debug_msg0("EID(supported rates) not found"); goto zlError; @@ -1607,7 +1619,8 @@ u8_t zfStaInitBssInfo(zdev_t* dev, zbuf_t* buf, /* get Country information */ - if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_COUNTRY)) != 0xffff ) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_COUNTRY); + if (offset != 0xffff) { length = zmw_rx_buf_readb(dev, buf, offset+1); if (length > ZM_MAX_COUNTRY_INFO_SIZE) @@ -1625,13 +1638,15 @@ u8_t zfStaInitBssInfo(zdev_t* dev, zbuf_t* buf, } /* get ERP information */ - if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP)) != 0xffff ) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP); + if (offset != 0xffff) { pBssInfo->erp = zmw_rx_buf_readb(dev, buf, offset+2); } /* get extended supported rates */ - if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE)) != 0xffff ) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE); + if (offset != 0xffff) { length = zmw_rx_buf_readb(dev, buf, offset+1); if (length > ZM_MAX_SUPP_RATES_IE_SIZE) @@ -1648,7 +1663,8 @@ u8_t zfStaInitBssInfo(zdev_t* dev, zbuf_t* buf, } /* get WPA IE */ - if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_WPA_IE)) != 0xffff ) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_WPA_IE); + if (offset != 0xffff) { length = zmw_rx_buf_readb(dev, buf, offset+1); if (length > ZM_MAX_IE_SIZE) @@ -1664,7 +1680,8 @@ u8_t zfStaInitBssInfo(zdev_t* dev, zbuf_t* buf, } /* get WPS IE */ - if ((offset = zfFindWifiElement(dev, buf, 4, 0xff)) != 0xffff) + offset = zfFindWifiElement(dev, buf, 4, 0xff); + if (offset != 0xffff) { length = zmw_rx_buf_readb(dev, buf, offset+1); if (length > ZM_MAX_WPS_IE_SIZE ) @@ -1679,19 +1696,22 @@ u8_t zfStaInitBssInfo(zdev_t* dev, zbuf_t* buf, } /* get SuperG IE */ - if ((offset = zfFindSuperGElement(dev, buf, ZM_WLAN_EID_VENDOR_PRIVATE)) != 0xffff) + offset = zfFindSuperGElement(dev, buf, ZM_WLAN_EID_VENDOR_PRIVATE); + if (offset != 0xffff) { pBssInfo->apCap |= ZM_SuperG_AP; } /* get XR IE */ - if ((offset = zfFindXRElement(dev, buf, ZM_WLAN_EID_VENDOR_PRIVATE)) != 0xffff) + offset = zfFindXRElement(dev, buf, ZM_WLAN_EID_VENDOR_PRIVATE); + if (offset != 0xffff) { pBssInfo->apCap |= ZM_XR_AP; } /* get RSN IE */ - if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_RSN_IE)) != 0xffff ) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_RSN_IE); + if (offset != 0xffff) { length = zmw_rx_buf_readb(dev, buf, offset+1); if (length > ZM_MAX_IE_SIZE) @@ -1707,7 +1727,8 @@ u8_t zfStaInitBssInfo(zdev_t* dev, zbuf_t* buf, } #ifdef ZM_ENABLE_CENC /* get CENC IE */ - if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_CENC_IE)) != 0xffff ) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_CENC_IE); + if (offset != 0xffff) { length = zmw_rx_buf_readb(dev, buf, offset+1); if (length > ZM_MAX_IE_SIZE ) @@ -1726,7 +1747,8 @@ u8_t zfStaInitBssInfo(zdev_t* dev, zbuf_t* buf, /* get WME Parameter IE, probe rsp may contain WME parameter element */ //if ( wd->bQoSEnable ) { - if ((offset = zfFindWifiElement(dev, buf, 2, 1)) != 0xffff) + offset = zfFindWifiElement(dev, buf, 2, 1); + if (offset != 0xffff) { apQosInfo = zmw_rx_buf_readb(dev, buf, offset+8) & 0x80; pBssInfo->wmeSupport = 1 | apQosInfo; @@ -1742,7 +1764,8 @@ u8_t zfStaInitBssInfo(zdev_t* dev, zbuf_t* buf, } } //CWYang(+) - if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY)) != 0xffff) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY); + if (offset != 0xffff) { /* 11n AP */ pBssInfo->EnableHT = 1; @@ -1792,7 +1815,8 @@ u8_t zfStaInitBssInfo(zdev_t* dev, zbuf_t* buf, pBssInfo->EnableHT = 0; } /* HT information */ - if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY)) != 0xffff) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY); + if (offset != 0xffff) { /* atheros pre n */ pBssInfo->extChOffset = zmw_rx_buf_readb(dev, buf, offset+2) & 0x03; @@ -1848,7 +1872,8 @@ u8_t zfStaInitBssInfo(zdev_t* dev, zbuf_t* buf, } /* get Marvel Extended Capability */ - if ((offset = zfFindMarvelExtCap(dev, buf)) != 0xffff) + offset = zfFindMarvelExtCap(dev, buf); + if (offset != 0xffff) { pBssInfo->marvelAp = 1; } @@ -1858,7 +1883,8 @@ u8_t zfStaInitBssInfo(zdev_t* dev, zbuf_t* buf, } /* get ATIM window */ - if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_IBSS)) != 0xffff ) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_IBSS); + if (offset != 0xffff ) { pBssInfo->atimWindow = zmw_rx_buf_readh(dev, buf,offset+2); } @@ -2017,7 +2043,8 @@ zlUpdateRssi: pBssInfo->tick = wd->tick; /* Update ERP information */ - if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP)) != 0xffff ) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP); + if (offset != 0xffff) { pBssInfo->erp = zmw_rx_buf_readb(dev, buf, offset+2); } @@ -2116,7 +2143,8 @@ void zfStaProcessBeacon(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo #if 0 else if ( wd->sta.oppositeCount == 0 ) { /* IBSS merge if SSID matched */ - if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID)) != 0xffff ) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID); + if (offset != 0xffff) { if ( (wd->sta.ssidLen == zmw_buf_readb(dev, buf, offset+1))&& (zfRxBufferEqualToStr(dev, buf, wd->sta.ssid, @@ -2410,7 +2438,8 @@ void zfStaProcessAsocRsp(zdev_t* dev, zbuf_t* buf) if ((wd->sta.wmeEnabled & ZM_STA_WME_ENABLE_BIT) != 0) //WME enabled { /* Asoc rsp may contain WME parameter element */ - if ((offset = zfFindWifiElement(dev, buf, 2, 1)) != 0xffff) + offset = zfFindWifiElement(dev, buf, 2, 1); + if (offset != 0xffff) { zm_debug_msg0("WME enable"); wd->sta.wmeConnected = 1; @@ -2605,7 +2634,8 @@ void zfStaStoreAsocRspIe(zdev_t* dev, zbuf_t* buf) return; } - if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY)) != 0xffff) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY); + if (offset != 0xffff) { /* atheros pre n */ zm_debug_msg0("atheros pre n"); @@ -2645,7 +2675,8 @@ void zfStaStoreAsocRspIe(zdev_t* dev, zbuf_t* buf) asocBw40 = (u8_t)((wd->sta.ie.HtCap.HtCapInfo & HTCAP_SupChannelWidthSet) >> 1); /* HT information */ - if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY)) != 0xffff) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY); + if (offset != 0xffff) { /* atheros pre n */ zm_debug_msg0("atheros pre n HTINFO"); @@ -2815,7 +2846,8 @@ void zfStaProcessProbeReq(zdev_t* dev, zbuf_t* buf, u16_t* src) } /* check SSID */ - if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID)) == 0xffff) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID); + if (offset == 0xffff) { zm_msg0_mm(ZM_LV_3, "probe req SSID not found"); return; @@ -3774,7 +3806,8 @@ static struct zsBssInfo* zfInfraFindAPToConnect(zdev_t* dev, } /* Skip if AP in blocking list */ - if ((ret = zfStaIsApInBlockingList(dev, pBssInfo->bssid)) == TRUE) + ret = zfStaIsApInBlockingList(dev, pBssInfo->bssid); + if (ret == TRUE) { zm_msg0_mm(ZM_LV_0, "Candidate AP in blocking List, skip if there's stilla choice!"); pNowBssInfo = pBssInfo; @@ -5007,7 +5040,8 @@ void zfSendNullData(zdev_t* dev, u8_t type) zmw_get_wlan_dev(dev); - if ((buf = zfwBufAllocate(dev, 1024)) == NULL) + buf = zfwBufAllocate(dev, 1024); + if (buf == NULL) { zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!"); return; @@ -5056,8 +5090,9 @@ void zfSendNullData(zdev_t* dev, u8_t type) /*increase unicast frame counter*/ wd->commTally.txUnicastFrm++; - if ((err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0, - ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS) + err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0, + ZM_INTERNAL_ALLOC_BUF, 0, 0xff); + if (err != ZM_SUCCESS) { goto zlError; } @@ -5083,7 +5118,8 @@ void zfSendPSPoll(zdev_t* dev) zmw_get_wlan_dev(dev); - if ((buf = zfwBufAllocate(dev, 1024)) == NULL) + buf = zfwBufAllocate(dev, 1024); + if (buf == NULL) { zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!"); return; @@ -5107,8 +5143,9 @@ void zfSendPSPoll(zdev_t* dev) // goto zlError; //} - if ((err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0, - ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS) + err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0, + ZM_INTERNAL_ALLOC_BUF, 0, 0xff); + if (err != ZM_SUCCESS) { goto zlError; } @@ -5134,7 +5171,8 @@ void zfSendBA(zdev_t* dev, u16_t start_seq, u8_t *bitmap) zmw_get_wlan_dev(dev); - if ((buf = zfwBufAllocate(dev, 1024)) == NULL) + buf = zfwBufAllocate(dev, 1024); + if (buf == NULL) { zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!"); return; @@ -5166,8 +5204,9 @@ void zfSendBA(zdev_t* dev, u16_t start_seq, u8_t *bitmap) offset++; } - if ((err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0, - ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS) + err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0, + ZM_INTERNAL_ALLOC_BUF, 0, 0xff); + if (err != ZM_SUCCESS) { goto zlError; } diff --git a/drivers/staging/otus/80211core/coid.c b/drivers/staging/otus/80211core/coid.c index 0524e1f36f0d..229aed8f889e 100644 --- a/drivers/staging/otus/80211core/coid.c +++ b/drivers/staging/otus/80211core/coid.c @@ -553,7 +553,8 @@ u8_t zfiWlanSetKey(zdev_t* dev, struct zsKeyInfo keyInfo) if (keyInfo.flag & ZM_KEY_FLAG_PK) { /* Find STA's information */ - if ((id = zfApFindSta(dev, keyInfo.macAddr)) == 0xffff) + id = zfApFindSta(dev, keyInfo.macAddr); + if (id == 0xffff) { /* Can't STA in the staTable */ return ZM_STATUS_FAILURE; diff --git a/drivers/staging/otus/80211core/cpsmgr.c b/drivers/staging/otus/80211core/cpsmgr.c index 98e1f0cc0727..32313beba78d 100644 --- a/drivers/staging/otus/80211core/cpsmgr.c +++ b/drivers/staging/otus/80211core/cpsmgr.c @@ -602,7 +602,8 @@ void zfPowerSavingMgrProcessBeacon(zdev_t* dev, zbuf_t* buf) wd->sta.psMgr.isSleepAllowed = 1; - if ( (offset=zfFindElement(dev, buf, ZM_WLAN_EID_TIM)) != 0xffff ) + offset = zfFindElement(dev, buf, ZM_WLAN_EID_TIM); + if (offset != 0xffff) { length = zmw_rx_buf_readb(dev, buf, offset+1); diff --git a/drivers/staging/otus/80211core/ctxrx.c b/drivers/staging/otus/80211core/ctxrx.c index 4e7f4bd86f47..a127196260e6 100644 --- a/drivers/staging/otus/80211core/ctxrx.c +++ b/drivers/staging/otus/80211core/ctxrx.c @@ -109,7 +109,8 @@ void zfGetRxIvIcvLength(zdev_t* dev, zbuf_t* buf, u8_t vap, u16_t* pIvLen, addr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+4); /* Find STA's information */ - if ((id = zfApFindSta(dev, addr)) != 0xffff) + id = zfApFindSta(dev, addr); + if (id != 0xffff) { if (wd->ap.staTable[id].encryMode == ZM_TKIP) { @@ -132,7 +133,8 @@ void zfGetRxIvIcvLength(zdev_t* dev, zbuf_t* buf, u8_t vap, u16_t* pIvLen, } } /* WDS port checking */ - if ((wdsPort = vap - 0x20) >= ZM_MAX_WDS_SUPPORT) + wdsPort = vap - 0x20; + if (wdsPort >= ZM_MAX_WDS_SUPPORT) { wdsPort = 0; } @@ -741,8 +743,9 @@ u16_t zfiTxSend80211Mgmt(zdev_t* dev, zbuf_t* buf, u16_t port) zfwBufRemoveHead(dev, buf, 24); - if ((err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0, - ZM_EXTERNAL_ALLOC_BUF, 0, 0)) != ZM_SUCCESS) + err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0, + ZM_EXTERNAL_ALLOC_BUF, 0, 0); + if (err != ZM_SUCCESS) { goto zlError; } @@ -799,7 +802,8 @@ u16_t zfiTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port) ZM_PERFORMANCE_TX_MSDU(dev, wd->tick); zm_msg1_tx(ZM_LV_2, "zfiTxSendEth(), port=", port); /* Return error if port is disabled */ - if ((err = zfTxPortControl(dev, buf, port)) == ZM_PORT_DISABLED) + err = zfTxPortControl(dev, buf, port); + if (err == ZM_PORT_DISABLED) { err = ZM_ERR_TX_PORT_DISABLED; goto zlError; @@ -809,7 +813,8 @@ u16_t zfiTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port) if ((wd->wlanMode == ZM_MODE_AP) && (port < 0x20)) { /* AP : Buffer frame for power saving STA */ - if ((ret = zfApBufferPsFrame(dev, buf, port)) == 1) + ret = zfApBufferPsFrame(dev, buf, port); + if (ret == 1) { return ZM_SUCCESS; } @@ -1119,7 +1124,8 @@ u16_t zfTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, u16_t bufType, u16_t fla i = 0; while( frameLen > 0 ) { - if ((frag.buf[i] = zfwBufAllocate(dev, fragLen+32)) != NULL) + frag.buf[i] = zfwBufAllocate(dev, fragLen+32); + if (frag.buf[i] != NULL) { frag.bufType[i] = ZM_INTERNAL_ALLOC_BUF; frag.seq[i] = frag.seq[0] + i; @@ -1276,7 +1282,8 @@ void zfCoreRecv(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo) bssid[2] = zmw_buf_readh(dev, buf, 20); /* Validate Rx frame */ - if ((ret = zfWlanRxValidate(dev, buf)) != ZM_SUCCESS) + ret = zfWlanRxValidate(dev, buf); + if (ret != ZM_SUCCESS) { zm_msg1_rx(ZM_LV_1, "Rx invalid:", ret); goto zlError; @@ -1301,7 +1308,8 @@ void zfCoreRecv(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo) #endif /* Filter Rx frame */ - if ((ret = zfWlanRxFilter(dev, buf)) != ZM_SUCCESS) + ret = zfWlanRxFilter(dev, buf); + if (ret != ZM_SUCCESS) { zm_msg1_rx(ZM_LV_1, "Rx duplicated:", ret); goto zlError; @@ -2086,7 +2094,8 @@ void zfiRecv80211(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo) //zm_msg0_rx(ZM_LV_0, "Rx data"); if (wd->wlanMode == ZM_MODE_AP) { - if ((ret = zfApUpdatePsBit(dev, buf, &vap, &uapsdTrig)) != ZM_SUCCESS) + ret = zfApUpdatePsBit(dev, buf, &vap, &uapsdTrig); + if (ret != ZM_SUCCESS) { zfwBufFree(dev, buf, 0); return; @@ -2115,7 +2124,8 @@ void zfiRecv80211(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo) for (ii=0; iiap.uapsdQ)) != NULL) - if ((psBuf = zfQueueGetWithMac(dev, wd->ap.uapsdQ, src, &mb)) != NULL) + psBuf = zfQueueGetWithMac(dev, wd->ap.uapsdQ, src, &mb); + if (psBuf != NULL) { if ((ii+1) == pktNum) { @@ -2232,7 +2242,8 @@ void zfiRecv80211(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo) } else { - if ( (buf = zfDefragment(dev, buf, &bIsDefrag, addInfo)) == NULL ) + buf = zfDefragment(dev, buf, &bIsDefrag, addInfo); + if (buf == NULL) { /* In this case, the buffer has been freed in zfDefragment */ return; @@ -2836,7 +2847,8 @@ void zfiRecv80211(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo) zfwBufRemoveHead(dev, buf, 18+offset); #endif // ZM_ENABLE_NATIVE_WIFI #if 1 - if ((ret = zfIntrabssForward(dev, buf, vap)) == 1) + ret = zfIntrabssForward(dev, buf, vap); + if (ret == 1) { /* Free Rx buffer if intra-BSS unicast frame */ zm_msg0_rx(ZM_LV_2, "Free intra-BSS unicast frame"); @@ -3037,7 +3049,8 @@ u16_t zfWlanRxValidate(zdev_t* dev, zbuf_t* buf) } else if ( wd->wlanMode != ZM_MODE_PSEUDO ) { - if ( (ret=zfStaRxValidateFrame(dev, buf))!=ZM_SUCCESS ) + ret = zfStaRxValidateFrame(dev, buf); + if (ret != ZM_SUCCESS) { //zm_debug_msg1("discard frame, code = ", ret); return ret; @@ -3787,12 +3800,14 @@ void zfPushVtxq(zdev_t* dev) /* 2006.12.20, Serve Management queue */ while( zfHpGetFreeTxdCount(dev) > 0 ) { - if ((buf = zfGetVmmq(dev)) != 0) + buf = zfGetVmmq(dev); + if (buf != 0) { txed = 1; //zm_debug_msg2("send buf = ", buf); - if ((err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0, - ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS) + err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0, + ZM_INTERNAL_ALLOC_BUF, 0, 0xff); + if (err != ZM_SUCCESS) { zfwBufFree(dev, buf, 0); } @@ -3831,9 +3846,11 @@ void zfPushVtxq(zdev_t* dev) /* Service VTxQ[3] */ for (i=0; i<4; i++) { - if ((freeTxd = zfHpGetFreeTxdCount(dev)) >= 3) + freeTxd = zfHpGetFreeTxdCount(dev); + if (freeTxd >= 3) { - if ((buf = zfGetVtxq(dev, 3)) != 0) + buf = zfGetVtxq(dev, 3); + if (buf != 0) { txed = 1; //zm_debug_msg2("send buf = ", buf); @@ -3850,9 +3867,11 @@ void zfPushVtxq(zdev_t* dev) /* Service VTxQ[2] */ for (i=0; i<3; i++) { - if ((freeTxd = zfHpGetFreeTxdCount(dev)) >= (zfHpGetMaxTxdCount(dev)*1/4)) + freeTxd = zfHpGetFreeTxdCount(dev); + if (freeTxd >= (zfHpGetMaxTxdCount(dev)*1/4)) { - if ((buf = zfGetVtxq(dev, 2)) != 0) + buf = zfGetVtxq(dev, 2); + if (buf != 0) { txed = 1; zfTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0); @@ -3860,7 +3879,8 @@ void zfPushVtxq(zdev_t* dev) } if (wd->sta.ac0PriorityHigherThanAc2 == 1) { - if ((buf = zfGetVtxq(dev, 0)) != 0) + buf = zfGetVtxq(dev, 0); + if (buf != 0) { txed = 1; zfTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0); @@ -3877,9 +3897,11 @@ void zfPushVtxq(zdev_t* dev) /* Service VTxQ[0] */ for (i=0; i<2; i++) { - if ((freeTxd = zfHpGetFreeTxdCount(dev)) >= (zfHpGetMaxTxdCount(dev)*2/4)) + freeTxd = zfHpGetFreeTxdCount(dev); + if (freeTxd >= (zfHpGetMaxTxdCount(dev)*2/4)) { - if ((buf = zfGetVtxq(dev, 0)) != 0) + buf = zfGetVtxq(dev, 0); + if (buf != 0) { txed = 1; zfTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0); @@ -3894,9 +3916,11 @@ void zfPushVtxq(zdev_t* dev) } /* Service VTxQ[1] */ - if ((freeTxd = zfHpGetFreeTxdCount(dev)) >= (zfHpGetMaxTxdCount(dev)*3/4)) + freeTxd = zfHpGetFreeTxdCount(dev); + if (freeTxd >= (zfHpGetMaxTxdCount(dev)*3/4)) { - if ((buf = zfGetVtxq(dev, 1)) != 0) + buf = zfGetVtxq(dev, 1); + if (buf != 0) { txed = 1; zfTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0); @@ -3983,9 +4007,10 @@ void zf80211FrameSend(zdev_t* dev, zbuf_t* buf, u16_t* header, u16_t snapLen, } wd->ledStruct.txTraffic++; - if ((err = zfHpSend(dev, header, headerLen, snap, snapLen, + err = zfHpSend(dev, header, headerLen, snap, snapLen, tail, tailLen, buf, offset, - bufType, ac, keyIdx)) != ZM_SUCCESS) + bufType, ac, keyIdx); + if (err != ZM_SUCCESS) { if (bufType == ZM_EXTERNAL_ALLOC_BUF) { diff --git a/drivers/staging/otus/80211core/queue.c b/drivers/staging/otus/80211core/queue.c index d294831b5c36..29be4bdb40a4 100644 --- a/drivers/staging/otus/80211core/queue.c +++ b/drivers/staging/otus/80211core/queue.c @@ -31,8 +31,9 @@ struct zsQueue* zfQueueCreate(zdev_t* dev, u16_t size) { struct zsQueue* q; - if ((q = (struct zsQueue*)zfwMemAllocate(dev, sizeof(struct zsQueue) - + (sizeof(struct zsQueueCell)*(size-1)))) != NULL) + q = (struct zsQueue*)zfwMemAllocate(dev, sizeof(struct zsQueue) + + (sizeof(struct zsQueueCell)*(size-1))); + if (q != NULL) { q->size = size; q->sizeMask = size-1; diff --git a/drivers/staging/otus/80211core/ratectrl.c b/drivers/staging/otus/80211core/ratectrl.c index a43104cd7f51..a1abe2f4f342 100644 --- a/drivers/staging/otus/80211core/ratectrl.c +++ b/drivers/staging/otus/80211core/ratectrl.c @@ -538,7 +538,8 @@ u16_t zfRateCtrlGetTxRate(zdev_t* dev, struct zsRcCell* rcCell, u16_t* probing) ((rcCell->currentRate <= 16) && ((wd->PER[rcCell->currentRate]/2) <= ZM_RATE_PROBING_THRESHOLD))) { - if ((newRate=zfRateCtrlGetHigherRate(rcCell)) != rcCell->currentRate) + newRate = zfRateCtrlGetHigherRate(rcCell); + if (newRate != rcCell->currentRate) { *probing = 1; wd->probeCount++; -- cgit v1.2.3 From 62fa452648d3098896bf5a8d78af4f058b355aa0 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 24 Mar 2010 22:16:58 -0700 Subject: Staging: otus: Hoist assign from if Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/otus/hal/hpmain.c | 30 ++++++++++++++++++------------ drivers/staging/otus/usbdrv.c | 6 ++++-- drivers/staging/otus/zdusb.c | 3 ++- 3 files changed, 24 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/otus/hal/hpmain.c b/drivers/staging/otus/hal/hpmain.c index 8dff5b97dfe3..5f412e020457 100644 --- a/drivers/staging/otus/hal/hpmain.c +++ b/drivers/staging/otus/hal/hpmain.c @@ -142,8 +142,9 @@ u16_t zfHpInit(zdev_t* dev, u32_t frequency) if (wd->modeMDKEnable) { /* download the MDK firmware */ - if ((ret = zfFirmwareDownload(dev, (u32_t*)zcDKFwImage, - (u32_t)zcDKFwImageSize, ZM_FIRMWARE_WLAN_ADDR)) != ZM_SUCCESS) + ret = zfFirmwareDownload(dev, (u32_t*)zcDKFwImage, + (u32_t)zcDKFwImageSize, ZM_FIRMWARE_WLAN_ADDR); + if (ret != ZM_SUCCESS) { /* TODO : exception handling */ //return 1; @@ -153,8 +154,9 @@ u16_t zfHpInit(zdev_t* dev, u32_t frequency) { #ifndef ZM_OTUS_LINUX_PHASE_2 /* download the normal firmware */ - if ((ret = zfFirmwareDownload(dev, (u32_t*)zcFwImage, - (u32_t)zcFwImageSize, ZM_FIRMWARE_WLAN_ADDR)) != ZM_SUCCESS) + ret = zfFirmwareDownload(dev, (u32_t*)zcFwImage, + (u32_t)zcFwImageSize, ZM_FIRMWARE_WLAN_ADDR); + if (ret != ZM_SUCCESS) { /* TODO : exception handling */ //return 1; @@ -162,16 +164,18 @@ u16_t zfHpInit(zdev_t* dev, u32_t frequency) #else // 1-PH fw: ReadMac() store some global variable - if ((ret = zfFirmwareDownloadNotJump(dev, (u32_t*)zcFwBufImage, - (u32_t)zcFwBufImageSize, 0x102800)) != ZM_SUCCESS) + ret = zfFirmwareDownloadNotJump(dev, (u32_t*)zcFwBufImage, + (u32_t)zcFwBufImageSize, 0x102800); + if (ret != ZM_SUCCESS) { DbgPrint("Dl zcFwBufImage failed!"); } zfwSleep(dev, 1000); - if ((ret = zfFirmwareDownload(dev, (u32_t*)zcFwImage, - (u32_t)zcFwImageSize, ZM_FIRMWARE_WLAN_ADDR)) != ZM_SUCCESS) + ret = zfFirmwareDownload(dev, (u32_t*)zcFwImage, + (u32_t)zcFwImageSize, ZM_FIRMWARE_WLAN_ADDR); + if (ret != ZM_SUCCESS) { DbgPrint("Dl zcFwBufImage failed!"); } @@ -249,15 +253,17 @@ u16_t zfHpReinit(zdev_t* dev, u32_t frequency) #ifndef ZM_OTUS_LINUX_PHASE_2 /* Download firmware */ - if ((ret = zfFirmwareDownload(dev, (u32_t*)zcFwImage, - (u32_t)zcFwImageSize, ZM_FIRMWARE_WLAN_ADDR)) != ZM_SUCCESS) + ret = zfFirmwareDownload(dev, (u32_t*)zcFwImage, + (u32_t)zcFwImageSize, ZM_FIRMWARE_WLAN_ADDR); + if (ret != ZM_SUCCESS) { /* TODO : exception handling */ //return 1; } #else - if ((ret = zfFirmwareDownload(dev, (u32_t*)zcP2FwImage, - (u32_t)zcP2FwImageSize, ZM_FIRMWARE_WLAN_ADDR)) != ZM_SUCCESS) + ret = zfFirmwareDownload(dev, (u32_t*)zcP2FwImage, + (u32_t)zcP2FwImageSize, ZM_FIRMWARE_WLAN_ADDR); + if (ret != ZM_SUCCESS) { /* TODO : exception handling */ //return 1; diff --git a/drivers/staging/otus/usbdrv.c b/drivers/staging/otus/usbdrv.c index 0ce65b5b9456..165a82b9ab85 100644 --- a/drivers/staging/otus/usbdrv.c +++ b/drivers/staging/otus/usbdrv.c @@ -350,7 +350,8 @@ int usbdrv_open(struct net_device *dev) } size = zfiGlobalDataSize(dev); - if ((mem = kmalloc(size, GFP_KERNEL)) == NULL) + mem = kmalloc(size, GFP_KERNEL); + if (mem == NULL) { rc = -EBUSY; goto exit; @@ -698,7 +699,8 @@ void usbdrv_remove1(struct pci_dev *pcid) struct net_device *dev; struct usbdrv_private *macp; - if (!(dev = (struct net_device *) pci_get_drvdata(pcid))) + dev = (struct net_device *)pci_get_drvdata(pcid); + if (!dev) return; macp = dev->ml_priv; diff --git a/drivers/staging/otus/zdusb.c b/drivers/staging/otus/zdusb.c index bb89d85a4c7c..6509bc565e65 100644 --- a/drivers/staging/otus/zdusb.c +++ b/drivers/staging/otus/zdusb.c @@ -95,7 +95,8 @@ static int zfLnxProbe(struct usb_interface *interface, printk(KERN_NOTICE "USB 1.1 Host\n"); #endif - if (!(macp = kmalloc(sizeof(struct usbdrv_private), GFP_KERNEL))) + macp = kmalloc(sizeof(struct usbdrv_private), GFP_KERNEL); + if (!macp) { printk(KERN_ERR "out of memory allocating device structure\n"); result = -ENOMEM; -- cgit v1.2.3 From 6aed5295ae93fc7947ee50eb2789655b88f6c941 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 24 Mar 2010 22:16:59 -0700 Subject: Staging: rt2860: Hoist assign from if Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/common/cmm_data.c | 6 ++++-- drivers/staging/rt2860/common/cmm_wpa.c | 18 ++++++++---------- drivers/staging/rt2860/common/spectrum.c | 7 ++++--- drivers/staging/rt2860/rt_linux.c | 7 ++++--- 4 files changed, 20 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/common/cmm_data.c b/drivers/staging/rt2860/common/cmm_data.c index 68263cee7952..65b00e685eb2 100644 --- a/drivers/staging/rt2860/common/cmm_data.c +++ b/drivers/staging/rt2860/common/cmm_data.c @@ -773,7 +773,8 @@ void RTMPDeQueuePacket(struct rt_rtmp_adapter *pAd, IN BOOLEAN bIntContext, u8 Q /* probe the Queue Head */ pQueue = &pAd->TxSwQueue[QueIdx]; - if ((pEntry = pQueue->Head) == NULL) { + pEntry = pQueue->Head; + if (pEntry == NULL) { DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags); break; @@ -824,7 +825,8 @@ void RTMPDeQueuePacket(struct rt_rtmp_adapter *pAd, IN BOOLEAN bIntContext, u8 Q } do { - if ((pEntry = pQueue->Head) == NULL) + pEntry = pQueue->Head; + if (pEntry == NULL) break; /* For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation. */ diff --git a/drivers/staging/rt2860/common/cmm_wpa.c b/drivers/staging/rt2860/common/cmm_wpa.c index 94e119faaa71..c16f3763cca6 100644 --- a/drivers/staging/rt2860/common/cmm_wpa.c +++ b/drivers/staging/rt2860/common/cmm_wpa.c @@ -2928,25 +2928,23 @@ void WpaShowAllsuite(u8 *rsnie, u32 rsnie_len) hex_dump("RSNIE", rsnie, rsnie_len); /* group cipher */ - if ((pSuite = - GetSuiteFromRSNIE(rsnie, rsnie_len, GROUP_SUITE, - &count)) != NULL) { + pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, GROUP_SUITE, &count); + if (pSuite != NULL) { hex_dump("group cipher", pSuite, 4 * count); } /* pairwise cipher */ - if ((pSuite = - GetSuiteFromRSNIE(rsnie, rsnie_len, PAIRWISE_SUITE, - &count)) != NULL) { + pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PAIRWISE_SUITE, &count); + if (pSuite != NULL) { hex_dump("pairwise cipher", pSuite, 4 * count); } /* AKM */ - if ((pSuite = - GetSuiteFromRSNIE(rsnie, rsnie_len, AKM_SUITE, &count)) != NULL) { + pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, AKM_SUITE, &count); + if (pSuite != NULL) { hex_dump("AKM suite", pSuite, 4 * count); } /* PMKID */ - if ((pSuite = - GetSuiteFromRSNIE(rsnie, rsnie_len, PMKID_LIST, &count)) != NULL) { + pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PMKID_LIST, &count); + if (pSuite != NULL) { hex_dump("PMKID", pSuite, LEN_PMKID); } diff --git a/drivers/staging/rt2860/common/spectrum.c b/drivers/staging/rt2860/common/spectrum.c index 51e38d809333..2d5f847e6cc6 100644 --- a/drivers/staging/rt2860/common/spectrum.c +++ b/drivers/staging/rt2860/common/spectrum.c @@ -1900,8 +1900,8 @@ static void PeerMeasureReportAction(struct rt_rtmp_adapter *pAd, /* if (pAd->CommonCfg.bIEEE80211H != TRUE) */ /* return; */ - if ((pMeasureReportInfo = - kmalloc(sizeof(struct rt_measure_rpi_report), GFP_ATOMIC)) == NULL) { + pMeasureReportInfo = kmalloc(sizeof(struct rt_measure_rpi_report), GFP_ATOMIC); + if (pMeasureReportInfo == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%zu).\n", __func__, sizeof(struct rt_measure_rpi_report))); @@ -2016,7 +2016,8 @@ static void PeerTpcRepAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_e NdisZeroMemory(&TpcRepInfo, sizeof(struct rt_tpc_report_info)); if (PeerTpcRepSanity (pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &TpcRepInfo)) { - if ((pEntry = TpcReqLookUp(pAd, DialogToken)) != NULL) { + pEntry = TpcReqLookUp(pAd, DialogToken); + if (pEntry != NULL) { TpcReqDelete(pAd, pEntry->DialogToken); DBGPRINT(RT_DEBUG_TRACE, ("%s: DialogToken=%x, TxPwr=%d, LinkMargin=%d\n", diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c index bfda187d2fbb..27b78102f4bd 100644 --- a/drivers/staging/rt2860/rt_linux.c +++ b/drivers/staging/rt2860/rt_linux.c @@ -463,8 +463,8 @@ void *duplicate_pkt(struct rt_rtmp_adapter *pAd, struct sk_buff *skb; void *pPacket = NULL; - if ((skb = - __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL) { + skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG); + if (skb != NULL) { skb_reserve(skb, 2); NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen); skb_put(skb, HdrLen); @@ -673,7 +673,8 @@ void RTMPSendWirelessEvent(struct rt_rtmp_adapter *pAd, return; } /*Allocate memory and copy the msg. */ - if ((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL) { + pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC); + if (pBuf != NULL) { /*Prepare the payload */ memset(pBuf, 0, IW_CUSTOM_MAX_LEN); -- cgit v1.2.3 From 699910dd756d782a9d281414d20c89ef94302177 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 24 Mar 2010 22:17:00 -0700 Subject: Staging: rt2870: Hoist assign from if Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2870/common/rtusb_bulk.c | 15 ++++++++++----- drivers/staging/rt2870/common/rtusb_io.c | 10 +++++----- 2 files changed, 15 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2870/common/rtusb_bulk.c b/drivers/staging/rt2870/common/rtusb_bulk.c index 625b872eccc6..d2746f8732e6 100644 --- a/drivers/staging/rt2870/common/rtusb_bulk.c +++ b/drivers/staging/rt2870/common/rtusb_bulk.c @@ -474,7 +474,8 @@ void RTUSBBulkOutDataPacket(struct rt_rtmp_adapter *pAd, (usb_complete_t) RTUSBBulkOutDataPacketComplete); pUrb = pHTTXContext->pUrb; - if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) { + ret = RTUSB_SUBMIT_URB(pUrb); + if (ret != 0) { DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret)); @@ -572,7 +573,8 @@ void RTUSBBulkOutNullFrame(struct rt_rtmp_adapter *pAd) (usb_complete_t) RTUSBBulkOutNullFrameComplete); pUrb = pNullContext->pUrb; - if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) { + ret = RTUSB_SUBMIT_URB(pUrb); + if (ret != 0) { RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); pAd->BulkOutPending[0] = FALSE; pAd->watchDogTxPendingCnt[0] = 0; @@ -666,7 +668,8 @@ void RTUSBBulkOutMLMEPacket(struct rt_rtmp_adapter *pAd, u8 Index) pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP); pUrb = pMLMEContext->pUrb; - if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) { + ret = RTUSB_SUBMIT_URB(pUrb); + if (ret != 0) { DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", ret)); @@ -741,7 +744,8 @@ void RTUSBBulkOutPsPoll(struct rt_rtmp_adapter *pAd) (usb_complete_t) RTUSBBulkOutPsPollComplete); pUrb = pPsPollContext->pUrb; - if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) { + ret = RTUSB_SUBMIT_URB(pUrb); + if (ret != 0) { RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags); pAd->BulkOutPending[0] = FALSE; pAd->watchDogTxPendingCnt[0] = 0; @@ -798,7 +802,8 @@ void DoBulkIn(struct rt_rtmp_adapter *pAd) RTUSBInitRxDesc(pAd, pRxContext); pUrb = pRxContext->pUrb; - if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) { /* fail */ + ret = RTUSB_SUBMIT_URB(pUrb); + if (ret != 0) { /* fail */ RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); pRxContext->InUse = FALSE; diff --git a/drivers/staging/rt2870/common/rtusb_io.c b/drivers/staging/rt2870/common/rtusb_io.c index cde38fe7e2e5..6b9ca24bbee9 100644 --- a/drivers/staging/rt2870/common/rtusb_io.c +++ b/drivers/staging/rt2870/common/rtusb_io.c @@ -1167,11 +1167,10 @@ void CMDHandler(struct rt_rtmp_adapter *pAd) (usb_complete_t) RTUSBBulkOutDataPacketComplete); - if ((ret = - RTUSB_SUBMIT_URB + ret = RTUSB_SUBMIT_URB (pHTTXContext-> - pUrb)) != - 0) { + pUrb); + if (ret != 0) { RTMP_INT_LOCK (&pAd-> BulkOutLock @@ -1540,7 +1539,8 @@ void CMDHandler(struct rt_rtmp_adapter *pAd) RTUSBInitRxDesc(pAd, pRxContext); pUrb = pRxContext->pUrb; - if ((ret = RTUSB_SUBMIT_URB(pUrb)) != 0) { /* fail */ + ret = RTUSB_SUBMIT_URB(pUrb); + if (ret != 0) { /* fail */ RTMP_IRQ_LOCK (&pAd-> -- cgit v1.2.3 From 53756de3831fb9aac83e4766221aac3bf6f6cfe7 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 24 Mar 2010 22:17:01 -0700 Subject: Staging: rtl8187se: Hoist assign from if Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c | 3 ++- drivers/staging/rtl8187se/r8180_core.c | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index be2d17f60c35..5fdb8f3df0a7 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c @@ -1555,7 +1555,8 @@ ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb) //IEEE80211DMESG("Rx probe"); ieee->softmac_stats.rx_auth_rq++; - if ((status = auth_rq_parse(skb, dest))!= -1){ + status = auth_rq_parse(skb, dest); + if (status != -1) { ieee80211_resp_to_auth(ieee, status, dest); } //DMESG("Dest is "MACSTR, MAC2STR(dest)); diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 55d12e3271de..88fe6232a47d 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -403,7 +403,8 @@ short buffer_add(struct buffer **buffer, u32 *buf, dma_addr_t dma, tmp=*buffer; while(tmp->next!=(*buffer)) tmp=tmp->next; - if ((tmp->next= kmalloc(sizeof(struct buffer),GFP_KERNEL)) == NULL){ + tmp->next = kmalloc(sizeof(struct buffer),GFP_KERNEL); + if (tmp->next == NULL) { DMESGE("Failed to kmalloc TX/RX struct"); return -1; } @@ -1155,7 +1156,8 @@ short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count) tmp=desc; for (i = 0; i < count; i++) { - if ((buf= kmalloc(bufsize * sizeof(u8),GFP_ATOMIC)) == NULL){ + buf = kmalloc(bufsize * sizeof(u8),GFP_ATOMIC); + if (buf == NULL) { DMESGE("Failed to kmalloc RX buffer"); return -1; } -- cgit v1.2.3 From d6d42dfbdf9148dbc69c6345b6cdf9132782f7b5 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 24 Mar 2010 22:17:02 -0700 Subject: Staging: rtl8192e: Hoist assign from if Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c | 3 ++- drivers/staging/rtl8192e/r8192E_core.c | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index d1d7b0866755..b4beb2073919 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -1934,7 +1934,8 @@ ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb) //IEEE80211DMESG("Rx probe"); ieee->softmac_stats.rx_auth_rq++; - if ((status = auth_rq_parse(skb, dest))!= -1){ + status = auth_rq_parse(skb, dest); + if (status != -1) { ieee80211_resp_to_auth(ieee, status, dest); } //DMESG("Dest is "MACSTR, MAC2STR(dest)); diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index bb7e1ef28d3b..0b0506d22928 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -1864,13 +1864,15 @@ static short rtl8192_pci_initdescring(struct net_device *dev) /* general process for other queue */ for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) { - if ((ret = rtl8192_alloc_tx_desc_ring(dev, i, priv->txringcount))) + ret = rtl8192_alloc_tx_desc_ring(dev, i, priv->txringcount); + if (ret) goto err_free_rings; } #if 0 /* specific process for hardware beacon process */ - if ((ret = rtl8192_alloc_tx_desc_ring(dev, MAX_TX_QUEUE_COUNT - 1, 2))) + ret = rtl8192_alloc_tx_desc_ring(dev, MAX_TX_QUEUE_COUNT - 1, 2); + if (ret) goto err_free_rings; #endif -- cgit v1.2.3 From 810ba6a25b390f8c72a65cc0141fa94a216f8a7a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 24 Mar 2010 22:17:03 -0700 Subject: Staging: rtl8192su: Hoist assign from if Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c index 84a4e23b60b3..3cf5fdf8a8cb 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c @@ -1691,7 +1691,8 @@ ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb) //IEEE80211DMESG("Rx probe"); ieee->softmac_stats.rx_auth_rq++; - if ((status = auth_rq_parse(skb, dest))!= -1){ + status = auth_rq_parse(skb, dest); + if (status != -1) { ieee80211_resp_to_auth(ieee, status, dest); } //DMESG("Dest is "MACSTR, MAC2STR(dest)); -- cgit v1.2.3 From d10219fcae91199284e990cbb1e23b5ec3a81db9 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 24 Mar 2010 22:17:04 -0700 Subject: Staging: rtl8192u: Hoist assign from if Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index d54e3a77423f..148424a9ac1c 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -1713,7 +1713,8 @@ ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb) //IEEE80211DMESG("Rx probe"); ieee->softmac_stats.rx_auth_rq++; - if ((status = auth_rq_parse(skb, dest))!= -1){ + status = auth_rq_parse(skb, dest); + if (status != -1) { ieee80211_resp_to_auth(ieee, status, dest); } //DMESG("Dest is "MACSTR, MAC2STR(dest)); -- cgit v1.2.3 From d2c6170bd1c4796ce5017de2987808a6db879483 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 24 Mar 2010 22:17:05 -0700 Subject: Staging: vt6655: Hoist assign from if Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/desc.h | 6 ++++-- drivers/staging/vt6655/device.h | 6 ++++-- drivers/staging/vt6655/device_main.c | 3 ++- drivers/staging/vt6655/iwctl.c | 3 ++- 4 files changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/desc.h b/drivers/staging/vt6655/desc.h index b573ef77abe1..0e119492d717 100644 --- a/drivers/staging/vt6655/desc.h +++ b/drivers/staging/vt6655/desc.h @@ -232,7 +232,8 @@ typedef struct tagDEVICE_RD_INFO { /* static inline PDEVICE_RD_INFO alloc_rd_info(void) { PDEVICE_RD_INFO ptr; - if ((ptr = kmalloc(sizeof(DEVICE_RD_INFO), GFP_ATOMIC)) == NULL) + ptr = kmalloc(sizeof(DEVICE_RD_INFO), GFP_ATOMIC); + if (ptr == NULL) return NULL; else { memset(ptr,0,sizeof(DEVICE_RD_INFO)); @@ -361,7 +362,8 @@ typedef struct tagDEVICE_TD_INFO{ /* static inline PDEVICE_TD_INFO alloc_td_info(void) { PDEVICE_TD_INFO ptr; - if ((ptr = kmalloc(sizeof(DEVICE_TD_INFO),GFP_ATOMIC))==NULL) + ptr = kmalloc(sizeof(DEVICE_TD_INFO),GFP_ATOMIC); + if (ptr == NULL) return NULL; else { memset(ptr,0,sizeof(DEVICE_TD_INFO)); diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index cde44d21b75c..7a9f40695f2d 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -898,7 +898,8 @@ inline static BOOL device_get_ip(PSDevice pInfo) { static inline PDEVICE_RD_INFO alloc_rd_info(void) { PDEVICE_RD_INFO ptr; - if ((ptr = (PDEVICE_RD_INFO)kmalloc((int)sizeof(DEVICE_RD_INFO), (int)GFP_ATOMIC)) == NULL) + ptr = (PDEVICE_RD_INFO)kmalloc((int)sizeof(DEVICE_RD_INFO), (int)GFP_ATOMIC); + if (ptr == NULL) return NULL; else { memset(ptr,0,sizeof(DEVICE_RD_INFO)); @@ -908,7 +909,8 @@ static inline PDEVICE_RD_INFO alloc_rd_info(void) { static inline PDEVICE_TD_INFO alloc_td_info(void) { PDEVICE_TD_INFO ptr; - if ((ptr = (PDEVICE_TD_INFO)kmalloc((int)sizeof(DEVICE_TD_INFO), (int)GFP_ATOMIC))==NULL) + ptr = (PDEVICE_TD_INFO)kmalloc((int)sizeof(DEVICE_TD_INFO), (int)GFP_ATOMIC); + if (ptr == NULL) return NULL; else { memset(ptr,0,sizeof(DEVICE_TD_INFO)); diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index fde352bc4792..50f02ee0b112 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -638,7 +638,8 @@ byValue1 = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA); //2008-8-4 by chester //zonetype initial pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE]; - if((zonetype=Config_FileOperation(pDevice,FALSE,NULL)) >= 0) { //read zonetype file ok! + zonetype = Config_FileOperation(pDevice,FALSE,NULL); + if (zonetype >= 0) { //read zonetype file ok! if ((zonetype == 0)&& (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] !=0x00)){ //for USA pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0; diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c index 824466d5a659..7fa5842238b8 100644 --- a/drivers/staging/vt6655/iwctl.c +++ b/drivers/staging/vt6655/iwctl.c @@ -1700,7 +1700,8 @@ int iwctl_giwpower(struct net_device *dev, DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER \n"); - if ((wrq->disabled = (mode == WMAC_POWER_CAM))) + wrq->disabled = (mode == WMAC_POWER_CAM); + if (wrq->disabled) return 0; if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { -- cgit v1.2.3 From bfbfeecca6957d749b95540626a6c348dc8d9301 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 24 Mar 2010 22:17:06 -0700 Subject: Staging: vt6656: Hoist assign from if Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/main_usb.c | 12 ++++++++---- drivers/staging/vt6656/usbpipe.c | 21 ++++++++++++++------- 2 files changed, 22 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index a8e1adbc9592..f15e7b48fe0d 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -1434,7 +1434,8 @@ static int Config_FileGetParameter(UCHAR *string, UCHAR *dest,UCHAR *source) source+=strlen(buf1); //find target string start point - if((start_p = kstrstr(source,buf1))==NULL) + start_p = kstrstr(source,buf1); + if (start_p == NULL) return FALSE; //check if current config line is marked by "#" ?? @@ -1446,7 +1447,8 @@ for(ii=1;;ii++) { } //find target string end point - if((end_p = kstrstr(start_p,"\n"))==NULL) { //cann't find "\n",but don't care + end_p = kstrstr(start_p,"\n"); + if (end_p == NULL) { //can't find "\n",but don't care end_p=start_p+strlen(start_p); //no include "\n" } @@ -1455,7 +1457,8 @@ for(ii=1;;ii++) { buf2[end_p-start_p]='\0'; //find value - if((start_p = kstrstr(buf2,"="))==NULL) + start_p = kstrstr(buf2,"="); + if (start_p == NULL) return FALSE; memset(buf1,0,100); strcpy(buf1,start_p+1); @@ -1548,7 +1551,8 @@ static int Read_config_file(PSDevice pDevice) { pDevice->config_file.eAuthenMode = -1; pDevice->config_file.eEncryptionStatus = -1; - if((buffer=Config_FileOperation(pDevice)) ==NULL) { + buffer = Config_FileOperation(pDevice); + if (buffer == NULL) { result =-1; return result; } diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c index 65e91a332a66..cd1da33cff7a 100644 --- a/drivers/staging/vt6656/usbpipe.c +++ b/drivers/staging/vt6656/usbpipe.c @@ -193,7 +193,8 @@ PIPEnsControlOut( usb_sndctrlpipe(pDevice->usb , 0), (char *) &pDevice->sUsbCtlRequest, pbyBuffer, wLength, s_nsControlInUsbIoCompleteWrite, pDevice); - if ((ntStatus = usb_submit_urb(pDevice->pControlURB, GFP_ATOMIC)) != 0) { + ntStatus = usb_submit_urb(pDevice->pControlURB, GFP_ATOMIC); + if (ntStatus != 0) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control send request submission failed: %d\n", ntStatus); return STATUS_FAILURE; } @@ -251,7 +252,8 @@ PIPEnsControlIn( usb_rcvctrlpipe(pDevice->usb , 0), (char *) &pDevice->sUsbCtlRequest, pbyBuffer, wLength, s_nsControlInUsbIoCompleteRead, pDevice); - if ((ntStatus = usb_submit_urb(pDevice->pControlURB, GFP_ATOMIC)) != 0) { + ntStatus = usb_submit_urb(pDevice->pControlURB, GFP_ATOMIC); + if (ntStatus != 0) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control request submission failed: %d\n", ntStatus); }else { MP_SET_FLAG(pDevice, fMP_CONTROL_READS); @@ -414,7 +416,8 @@ usb_fill_bulk_urb(pDevice->pInterruptURB, #endif #endif - if ((ntStatus = usb_submit_urb(pDevice->pInterruptURB, GFP_ATOMIC)) != 0) { + ntStatus = usb_submit_urb(pDevice->pInterruptURB, GFP_ATOMIC); + if (ntStatus != 0) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus); } @@ -494,7 +497,8 @@ s_nsInterruptUsbIoCompleteRead( if (pDevice->fKillEventPollingThread != TRUE) { #if 0 //reserve int URB submit - if ((ntStatus = usb_submit_urb(urb, GFP_ATOMIC)) != 0) { + ntStatus = usb_submit_urb(urb, GFP_ATOMIC); + if (ntStatus != 0) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Re-Submit int URB failed %d\n", ntStatus); } #else //replace int URB submit by bulk transfer @@ -507,7 +511,8 @@ s_nsInterruptUsbIoCompleteRead( s_nsInterruptUsbIoCompleteRead, pDevice); - if ((ntStatus = usb_submit_urb(pDevice->pInterruptURB, GFP_ATOMIC)) != 0) { + ntStatus = usb_submit_urb(pDevice->pInterruptURB, GFP_ATOMIC); + if (ntStatus != 0) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus); } @@ -572,7 +577,8 @@ PIPEnsBulkInUsbRead( s_nsBulkInUsbIoCompleteRead, pRCB); - if((ntStatus = usb_submit_urb(pUrb, GFP_ATOMIC)) != 0){ + ntStatus = usb_submit_urb(pUrb, GFP_ATOMIC); + if (ntStatus != 0) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit Rx URB failed %d\n", ntStatus); return STATUS_FAILURE ; } @@ -718,7 +724,8 @@ PIPEnsSendBulkOut( s_nsBulkOutIoCompleteWrite, pContext); - if((status = usb_submit_urb(pUrb, GFP_ATOMIC))!=0) + status = usb_submit_urb(pUrb, GFP_ATOMIC); + if (status != 0) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit Tx URB failed %d\n", status); return STATUS_FAILURE; -- cgit v1.2.3 From 491dbc8d1ae56199ad199830d16c77c8317aa987 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 24 Mar 2010 22:17:07 -0700 Subject: Staging: wlags49_h2: Hoist assign from if Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/hcf.c | 15 ++++++++++----- drivers/staging/wlags49_h2/wl_main.c | 3 ++- drivers/staging/wlags49_h2/wl_netdev.c | 12 ++++++++---- drivers/staging/wlags49_h2/wl_priv.c | 9 ++++++--- drivers/staging/wlags49_h2/wl_sysfs.c | 3 ++- 5 files changed, 28 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlags49_h2/hcf.c b/drivers/staging/wlags49_h2/hcf.c index 6e39f5081e27..390628c6c1eb 100644 --- a/drivers/staging/wlags49_h2/hcf.c +++ b/drivers/staging/wlags49_h2/hcf.c @@ -990,7 +990,8 @@ int rc = HCF_ERR_INCOMP_FW; ifbp->IFB_CntlOpt |= DMA_ENABLED; HCFASSERT( NT_ASSERT, NEVER_TESTED ) // make the entire rx descriptor chain DMA-owned, so the DMA engine can (re-)use it. - if ( ( p = ifbp->IFB_FirstDesc[DMA_RX] ) != NULL ) { //;? Think this over again in the light of the new chaining strategy + p = ifbp->IFB_FirstDesc[DMA_RX]; + if (p != NULL) { //;? Think this over again in the light of the new chaining strategy if ( 1 ) { //begin alternative HCFASSERT( NT_ASSERT, NEVER_TESTED ) put_frame_lst( ifbp, ifbp->IFB_FirstDesc[DMA_RX], DMA_RX ); @@ -2087,7 +2088,8 @@ wci_bufp pt; //pointer with the "right" type, just to help ease writing macr OPW( HREG_AUX_OFFSET, (hcf_16)(PLUG_DATA_OFFSET & 0x7E) ); io_port = ifbp->IFB_IOBase + HREG_AUX_DATA; //to prevent side effects of the MSF-defined macro p = ltvp->val; //destination char pointer (in LTV record) - if ( ( i = len - 1 ) > 0 ) { + i = len - 1; + if (i > 0 ) { pt = (wci_bufp)p; //just to help ease writing macros with embedded assembly IN_PORT_STRING_8_16( io_port, pt, i ); //space used by T: -1 } @@ -2674,7 +2676,8 @@ hcf_16 fid = 0; #if (HCF_EXT) & HCF_EXT_TX_CONT // Continuous transmit test if ( tx_cntl == HFS_TX_CNTL_TX_CONT ) { - if ( ( fid = get_fid( ifbp ) ) != 0 ) { + fid = get_fid(ifbp); + if (fid != 0 ) { //setup BAP to begin of TxFS (void)setup_bap( ifbp, fid, 0, IO_OUT ); //copy all the fragments in a transparent fashion @@ -2700,7 +2703,8 @@ hcf_16 fid = 0; #if (HCF_TYPE) & HCF_TYPE_WPA tx_cntl |= ifbp->IFB_MICTxCntl; #endif // HCF_TYPE_WPA - if ( (fid = ifbp->IFB_TxFID) == 0 && ( fid = get_fid( ifbp ) ) != 0 ) /* 4 */ + fid = ifbp->IFB_TxFID; + if (fid == 0 && ( fid = get_fid( ifbp ) ) != 0 ) /* 4 */ /* skip the next compound statement if: - pre-put message or - no fid available (which should never occur if the MSF adheres to the WCI) @@ -4860,7 +4864,8 @@ PROT_CNT_INI int rc; HCFTRACE( ifbp, HCF_TRACE_STRIO ); - if ( ( rc = ifbp->IFB_DefunctStat ) == HCF_SUCCESS ) { /*2*/ + rc = ifbp->IFB_DefunctStat; + if (rc == HCF_SUCCESS) { /*2*/ OPW( HREG_SELECT_1, fid ); /*4*/ OPW( HREG_OFFSET_1, offset ); if ( type == IO_IN ) { diff --git a/drivers/staging/wlags49_h2/wl_main.c b/drivers/staging/wlags49_h2/wl_main.c index cf0c38468b20..88d0d472142f 100644 --- a/drivers/staging/wlags49_h2/wl_main.c +++ b/drivers/staging/wlags49_h2/wl_main.c @@ -3591,7 +3591,8 @@ int scull_read_procmem(char *buf, char **start, off_t offset, int len, int *eof, len=0; - if ( ( lp = ((struct net_device *)data)->priv ) == NULL ) { + lp = ((struct net_device *)data)->priv; + if (lp == NULL) { len += sprintf(buf+len,"No wl_private in scull_read_procmem\n" ); } else if ( lp->wlags49_type == 0 ){ ifbp = &lp->hcfCtx; diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c index 1db73ebcae28..1cfaee3a2350 100644 --- a/drivers/staging/wlags49_h2/wl_netdev.c +++ b/drivers/staging/wlags49_h2/wl_netdev.c @@ -930,8 +930,10 @@ int wl_rx(struct net_device *dev) port = ( hfs_stat >> 8 ) & 0x0007; DBG_RX( DbgInfo, "Rx frame for port %d\n", port ); - if(( pktlen = lp->hcfCtx.IFB_RxLen ) != 0 ) { - if(( skb = ALLOC_SKB( pktlen )) != NULL ) { + pktlen = lp->hcfCtx.IFB_RxLen; + if (pktlen != 0) { + skb = ALLOC_SKB(pktlen); + if (skb != NULL) { /* Set the netdev based on the port */ switch( port ) { #ifdef USE_WDS @@ -1995,8 +1997,10 @@ int wl_rx_dma( struct net_device *dev ) port = ( hfs_stat >> 8 ) & 0x0007; DBG_RX( DbgInfo, "Rx frame for port %d\n", port ); - if(( pktlen = GET_BUF_CNT( desc_next )) != 0 ) { - if(( skb = ALLOC_SKB( pktlen )) != NULL ) { + pktlen = GET_BUF_CNT(desc_next); + if (pktlen != 0) { + skb = ALLOC_SKB(pktlen); + if (skb != NULL) { switch( port ) { #ifdef USE_WDS case 1: diff --git a/drivers/staging/wlags49_h2/wl_priv.c b/drivers/staging/wlags49_h2/wl_priv.c index 727ea8a483af..a67ff529d359 100644 --- a/drivers/staging/wlags49_h2/wl_priv.c +++ b/drivers/staging/wlags49_h2/wl_priv.c @@ -503,7 +503,8 @@ int wvlan_uil_send_diag_msg( struct uilreq *urq, struct wl_private *lp ) return result; } - if ((data = kmalloc(urq->len, GFP_KERNEL)) != NULL) { + data = kmalloc(urq->len, GFP_KERNEL); + if (data != NULL) { memset( Descp, 0, sizeof( DESC_STRCT )); memcpy( data, urq->data, urq->len ); @@ -617,7 +618,8 @@ int wvlan_uil_put_info( struct uilreq *urq, struct wl_private *lp ) LTV record, try to allocate it from the kernel stack. Otherwise, we just use our local LTV record. */ if( urq->len > sizeof( lp->ltvRecord )) { - if(( pLtv = (ltv_t *)kmalloc( urq->len, GFP_KERNEL )) != NULL ) { + pLtv = (ltv_t *)kmalloc( urq->len, GFP_KERNEL ); + if (pLtv != NULL) { ltvAllocated = TRUE; } else { DBG_ERROR( DbgInfo, "Alloc FAILED\n" ); @@ -1296,7 +1298,8 @@ int wvlan_uil_get_info( struct uilreq *urq, struct wl_private *lp ) LTV record, try to allocate it from the kernel stack. Otherwise, we just use our local LTV record. */ if( urq->len > sizeof( lp->ltvRecord )) { - if(( pLtv = (ltv_t *)kmalloc( urq->len, GFP_KERNEL )) != NULL ) { + pLtv = (ltv_t *)kmalloc( urq->len, GFP_KERNEL ); + if (pLtv != NULL) { ltvAllocated = TRUE; /* Copy the command/length information into the new buffer. */ diff --git a/drivers/staging/wlags49_h2/wl_sysfs.c b/drivers/staging/wlags49_h2/wl_sysfs.c index 864e01a736c8..e4c8804ac37d 100644 --- a/drivers/staging/wlags49_h2/wl_sysfs.c +++ b/drivers/staging/wlags49_h2/wl_sysfs.c @@ -46,7 +46,8 @@ static ssize_t show_tallies(struct device *d, struct device_attribute *attr, if (dev_isalive(dev)) { wl_lock(lp, &flags); - if ((ret = wl_get_tallies(lp, &tallies)) == 0) { + ret = wl_get_tallies(lp, &tallies); + if (ret == 0) { wl_unlock(lp, &flags); ret = snprintf(buf, PAGE_SIZE, "TxUnicastFrames: %u\n" -- cgit v1.2.3 From b761cbb56ec8f4a1ad0b68a6d457d9e506c12037 Mon Sep 17 00:00:00 2001 From: Vikram Dhillon Date: Sun, 14 Mar 2010 20:39:30 -0400 Subject: Staging: arlan: arlan.h: Fixed some style issues Fixed some style issues in accordance with checkpatch.pl. Before the patch contained "total: 2 errors, 186 warnings, 535 lines checked" and now it has: total: 0 errors, 170 warnings. Most of the warnings that remain now are the line over 80 chars ones. Signed-off-by: Vikram Dhillon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/arlan/arlan.h | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/arlan/arlan.h b/drivers/staging/arlan/arlan.h index ffcd3ea048aa..3974acf076b9 100644 --- a/drivers/staging/arlan/arlan.h +++ b/drivers/staging/arlan/arlan.h @@ -318,7 +318,7 @@ extern struct arlan_conf_stru arlan_conf[MAX_ARLANS]; struct TxParam { volatile short offset; volatile short length; - volatile u_char dest[6]; + volatile u_char dest[6]; volatile unsigned char clear; volatile unsigned char retries; volatile unsigned char routing; @@ -354,37 +354,37 @@ struct arlan_private { unsigned long tx_last_sent; unsigned long tx_last_cleared; unsigned long retransmissions; - unsigned long interrupt_ack_requested; + unsigned long interrupt_ack_requested; spinlock_t lock; unsigned long waiting_command_mask; - unsigned long card_polling_interval; - unsigned long last_command_buff_free_time; + unsigned long card_polling_interval; + unsigned long last_command_buff_free_time; - int under_reset; - int under_config; - int rx_command_given; - int tx_command_given; + int under_reset; + int under_config; + int rx_command_given; + int tx_command_given; unsigned long interrupt_processing_active; unsigned long last_rx_int_ack_time; unsigned long in_bytes; - unsigned long out_bytes; + unsigned long out_bytes; unsigned long in_time; unsigned long out_time; unsigned long in_time10; unsigned long out_time10; unsigned long in_bytes10; - unsigned long out_bytes10; + unsigned long out_bytes10; int init_etherdev_alloc; }; #define ARLAN_CLEAR 0x00 -#define ARLAN_RESET 0x01 +#define ARLAN_RESET 0x01 #define ARLAN_CHANNEL_ATTENTION 0x02 -#define ARLAN_INTERRUPT_ENABLE 0x04 -#define ARLAN_CLEAR_INTERRUPT 0x08 -#define ARLAN_POWER 0x40 +#define ARLAN_INTERRUPT_ENABLE 0x04 +#define ARLAN_CLEAR_INTERRUPT 0x08 +#define ARLAN_POWER 0x40 #define ARLAN_ACCESS 0x80 #define ARLAN_COM_CONF 0x01 @@ -445,8 +445,8 @@ struct arlan_private { #define registrationBad(dev)\ - (( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationMode) > 0) && \ - ( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationStatus) == 0)) + ((READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationMode) > 0) && \ + (READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationStatus) == 0)) #define readControlRegister(dev)\ @@ -461,9 +461,9 @@ struct arlan_private { int cr; \ \ cr = readControlRegister(dev);\ - if (cr & ARLAN_CHANNEL_ATTENTION) { \ + if (cr & ARLAN_CHANNEL_ATTENTION) \ writeControlRegister(dev, (cr & ~ARLAN_CHANNEL_ATTENTION));\ - } else \ + else \ writeControlRegister(dev, (cr | ARLAN_CHANNEL_ATTENTION));\ } @@ -504,8 +504,8 @@ struct arlan_private { #define ARLAN_COMMAND_RX_ABORT 0x000080 #define ARLAN_COMMAND_POWERDOWN 0x000100 #define ARLAN_COMMAND_POWERUP 0x000200 -#define ARLAN_COMMAND_SLOW_POLL 0x000400 -#define ARLAN_COMMAND_ACTIVATE 0x000800 +#define ARLAN_COMMAND_SLOW_POLL 0x000400 +#define ARLAN_COMMAND_ACTIVATE 0x000800 #define ARLAN_COMMAND_INT_ACK 0x001000 #define ARLAN_COMMAND_INT_ENABLE 0x002000 #define ARLAN_COMMAND_WAIT_NOW 0x004000 -- cgit v1.2.3 From 17e7b137df499a9d6c9c69dd28d427e6117aa17c Mon Sep 17 00:00:00 2001 From: Chihau Chau Date: Mon, 15 Mar 2010 00:44:54 -0300 Subject: Staging: dream: smd: smd_qmi: fix code style issues This fixes some code style issues about to #include instead of and some not necessary braces {}. Signed-off-by: Chihau Chau Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dream/smd/smd_qmi.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dream/smd/smd_qmi.c b/drivers/staging/dream/smd/smd_qmi.c index 687db142904c..9e9067fb271b 100644 --- a/drivers/staging/dream/smd/smd_qmi.c +++ b/drivers/staging/dream/smd/smd_qmi.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include #define QMI_CTL 0x00 @@ -643,11 +643,10 @@ static int qmi_print_state(struct qmi_ctxt *ctxt, char *buf, int max) } i = scnprintf(buf, max, "STATE=%s\n", statename); - i += scnprintf(buf + i, max - i, "CID=%d\n",ctxt->wds_client_id); + i += scnprintf(buf + i, max - i, "CID=%d\n", ctxt->wds_client_id); - if (ctxt->state != STATE_ONLINE){ + if (ctxt->state != STATE_ONLINE) return i; - } i += scnprintf(buf + i, max - i, "ADDR=%d.%d.%d.%d\n", ctxt->addr[0], ctxt->addr[1], ctxt->addr[2], ctxt->addr[3]); -- cgit v1.2.3 From 593a961649226aae13705dc066ee277f112b8397 Mon Sep 17 00:00:00 2001 From: Chihau Chau Date: Mon, 15 Mar 2010 00:29:02 -0300 Subject: Staging: dream: smd: smd_private: fix code style issues This put open braces '{' following structs on the same line. Signed-off-by: Chihau Chau Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dream/smd/smd_private.h | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dream/smd/smd_private.h b/drivers/staging/dream/smd/smd_private.h index c0eb3de1be54..1b2e1c89ea2e 100644 --- a/drivers/staging/dream/smd/smd_private.h +++ b/drivers/staging/dream/smd/smd_private.h @@ -16,24 +16,21 @@ #ifndef _ARCH_ARM_MACH_MSM_MSM_SMD_PRIVATE_H_ #define _ARCH_ARM_MACH_MSM_MSM_SMD_PRIVATE_H_ -struct smem_heap_info -{ +struct smem_heap_info { unsigned initialized; unsigned free_offset; unsigned heap_remaining; unsigned reserved; }; -struct smem_heap_entry -{ +struct smem_heap_entry { unsigned allocated; unsigned offset; unsigned size; unsigned reserved; }; -struct smem_proc_comm -{ +struct smem_proc_comm { unsigned command; unsigned status; unsigned data1; @@ -49,22 +46,19 @@ struct smem_proc_comm #define VERSION_APPS 8 #define VERSION_MODEM 9 -struct smem_shared -{ +struct smem_shared { struct smem_proc_comm proc_comm[4]; unsigned version[32]; struct smem_heap_info heap_info; struct smem_heap_entry heap_toc[128]; }; -struct smsm_shared -{ +struct smsm_shared { unsigned host; unsigned state; }; -struct smsm_interrupt_info -{ +struct smsm_interrupt_info { uint32_t aArm_en_mask; uint32_t aArm_interrupts_pending; uint32_t aArm_wakeup_reason; @@ -108,8 +102,7 @@ void smsm_print_sleep_info(void); #define SMEM_NUM_SMD_CHANNELS 64 -typedef enum -{ +typedef enum { /* fixed items */ SMEM_PROC_COMM = 0, SMEM_HEAP_INFO, -- cgit v1.2.3 From 5ff0dd18267efc0e7b0352fe54b74114b58535ae Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 20 Mar 2010 15:13:00 +0100 Subject: Staging: dream: fix dangling i2c pointers Fix I2C-drivers which missed setting clientdata to NULL before freeing the structure it points to. Also fix drivers which do this _after_ the structure was freed already. Signed-off-by: Wolfram Sang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dream/synaptics_i2c_rmi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/dream/synaptics_i2c_rmi.c b/drivers/staging/dream/synaptics_i2c_rmi.c index d2ca116a1c25..ae2f72ca7351 100644 --- a/drivers/staging/dream/synaptics_i2c_rmi.c +++ b/drivers/staging/dream/synaptics_i2c_rmi.c @@ -535,6 +535,7 @@ err_input_register_device_failed: err_input_dev_alloc_failed: err_detect_failed: err_power_failed: + i2c_set_clientdata(client, NULL); kfree(ts); err_alloc_data_failed: err_check_functionality_failed: @@ -552,6 +553,7 @@ static int synaptics_ts_remove(struct i2c_client *client) else hrtimer_cancel(&ts->timer); input_unregister_device(ts->input_dev); + i2c_set_clientdata(client, NULL); kfree(ts); return 0; } -- cgit v1.2.3 From 665752e528c32e40d9f5c684abd53ebd2f1ae724 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 20 Mar 2010 15:13:01 +0100 Subject: Staging: go7007: fix dangling i2c pointers Fix I2C-drivers which missed setting clientdata to NULL before freeing the structure it points to. Also fix drivers which do this _after_ the structure was freed already. Signed-off-by: Wolfram Sang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/go7007/wis-saa7113.c | 1 + drivers/staging/go7007/wis-saa7115.c | 1 + drivers/staging/go7007/wis-tw9903.c | 1 + 3 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/go7007/wis-saa7113.c b/drivers/staging/go7007/wis-saa7113.c index 5c12b4d38459..bd925457f8b7 100644 --- a/drivers/staging/go7007/wis-saa7113.c +++ b/drivers/staging/go7007/wis-saa7113.c @@ -289,6 +289,7 @@ static int wis_saa7113_probe(struct i2c_client *client, if (write_regs(client, initial_registers) < 0) { printk(KERN_ERR "wis-saa7113: error initializing SAA7113\n"); + i2c_set_clientdata(client, NULL); kfree(dec); return -ENODEV; } diff --git a/drivers/staging/go7007/wis-saa7115.c b/drivers/staging/go7007/wis-saa7115.c index 73f2283a8803..b2eb804c1954 100644 --- a/drivers/staging/go7007/wis-saa7115.c +++ b/drivers/staging/go7007/wis-saa7115.c @@ -422,6 +422,7 @@ static int wis_saa7115_probe(struct i2c_client *client, if (write_regs(client, initial_registers) < 0) { printk(KERN_ERR "wis-saa7115: error initializing SAA7115\n"); + i2c_set_clientdata(client, NULL); kfree(dec); return -ENODEV; } diff --git a/drivers/staging/go7007/wis-tw9903.c b/drivers/staging/go7007/wis-tw9903.c index 3ac6f785c4ad..2afea09091b9 100644 --- a/drivers/staging/go7007/wis-tw9903.c +++ b/drivers/staging/go7007/wis-tw9903.c @@ -294,6 +294,7 @@ static int wis_tw9903_probe(struct i2c_client *client, if (write_regs(client, initial_registers) < 0) { printk(KERN_ERR "wis-tw9903: error initializing TW9903\n"); + i2c_set_clientdata(client, NULL); kfree(dec); return -ENODEV; } -- cgit v1.2.3 From cf1b02d0b8f5415c776d1de548bbf720fc782740 Mon Sep 17 00:00:00 2001 From: Hemanth V Date: Thu, 1 Apr 2010 18:46:19 +0530 Subject: Staging: dream: Synaptic: Remove non-standard multi touch support Signed-off-by: Hemanth V Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dream/synaptics_i2c_rmi.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dream/synaptics_i2c_rmi.c b/drivers/staging/dream/synaptics_i2c_rmi.c index ae2f72ca7351..e34d11fac2be 100644 --- a/drivers/staging/dream/synaptics_i2c_rmi.c +++ b/drivers/staging/dream/synaptics_i2c_rmi.c @@ -109,9 +109,7 @@ static void decode_report(struct synaptics_ts_data *ts, u8 *buf) int f, a; int base = 2; int z = buf[1]; - int w = buf[0] >> 4; int finger = buf[0] & 7; - int finger2_pressed; for (f = 0; f < 2; f++) { u32 flip_flag = SYNAPTICS_FLIP_X; @@ -151,14 +149,7 @@ static void decode_report(struct synaptics_ts_data *ts, u8 *buf) input_report_abs(ts->input_dev, ABS_Y, pos[0][1]); } input_report_abs(ts->input_dev, ABS_PRESSURE, z); - input_report_abs(ts->input_dev, ABS_TOOL_WIDTH, w); input_report_key(ts->input_dev, BTN_TOUCH, finger); - finger2_pressed = finger > 1 && finger != 7; - input_report_key(ts->input_dev, BTN_2, finger2_pressed); - if (finger2_pressed) { - input_report_abs(ts->input_dev, ABS_HAT0X, pos[1][0]); - input_report_abs(ts->input_dev, ABS_HAT0Y, pos[1][1]); - } input_sync(ts->input_dev); } @@ -347,11 +338,6 @@ static void compute_areas(struct synaptics_ts_data *ts, -inactive_area_top, max_y + inactive_area_bottom, fuzz_y, 0); input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, fuzz_p, 0); - input_set_abs_params(ts->input_dev, ABS_TOOL_WIDTH, 0, 15, fuzz_w, 0); - input_set_abs_params(ts->input_dev, ABS_HAT0X, -inactive_area_left, - max_x + inactive_area_right, fuzz_x, 0); - input_set_abs_params(ts->input_dev, ABS_HAT0Y, -inactive_area_top, - max_y + inactive_area_bottom, fuzz_y, 0); } static struct synaptics_i2c_rmi_platform_data fake_pdata; @@ -487,7 +473,6 @@ static int __devinit synaptics_ts_probe( __set_bit(EV_SYN, ts->input_dev->evbit); __set_bit(EV_KEY, ts->input_dev->evbit); __set_bit(BTN_TOUCH, ts->input_dev->keybit); - __set_bit(BTN_2, ts->input_dev->keybit); __set_bit(EV_ABS, ts->input_dev->evbit); compute_areas(ts, pdata, max_x, max_y); -- cgit v1.2.3 From 97dcc7c6fc52fe64f15b431397e44fba398b1768 Mon Sep 17 00:00:00 2001 From: Hemanth V Date: Thu, 1 Apr 2010 18:46:27 +0530 Subject: Staging: dream: Synaptic: Add threaded IRQ support Signed-off-by: Hemanth V Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dream/synaptics_i2c_rmi.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dream/synaptics_i2c_rmi.c b/drivers/staging/dream/synaptics_i2c_rmi.c index e34d11fac2be..1f020dad6234 100644 --- a/drivers/staging/dream/synaptics_i2c_rmi.c +++ b/drivers/staging/dream/synaptics_i2c_rmi.c @@ -199,8 +199,6 @@ static void synaptics_ts_work_func(struct work_struct *work) decode_report(ts, buf); } - if (ts->use_irq) - enable_irq(ts->client->irq); } static enum hrtimer_restart synaptics_ts_timer_func(struct hrtimer *timer) @@ -218,8 +216,7 @@ static irqreturn_t synaptics_ts_irq_handler(int irq, void *dev_id) { struct synaptics_ts_data *ts = dev_id; - disable_irq_nosync(ts->client->irq); - queue_work(synaptics_wq, &ts->work); + synaptics_ts_work_func(&ts->work); return IRQ_HANDLED; } @@ -485,8 +482,10 @@ static int __devinit synaptics_ts_probe( goto err_input_register_device_failed; } if (client->irq) { - ret = request_irq(client->irq, synaptics_ts_irq_handler, - 0, client->name, ts); + ret = request_threaded_irq(client->irq, NULL, + synaptics_ts_irq_handler, + IRQF_TRIGGER_LOW|IRQF_ONESHOT, + client->name, ts); if (ret == 0) { ret = i2c_set(ts, 0xf1, 0x01, "enable abs int"); if (ret) -- cgit v1.2.3 From eb450e894524f912941b121ff036dae14b83d53d Mon Sep 17 00:00:00 2001 From: Chihau Chau Date: Sat, 10 Apr 2010 15:14:38 -0400 Subject: Staging: dream: pmem: fix some code style issues This fixes some code style issues like prohibited spaces after that open parenthesis '(' and before that close parenthesis ')', and lines over 80 characters. Signed-off-by: Chihau Chau Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dream/pmem.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dream/pmem.c b/drivers/staging/dream/pmem.c index 6edfdd4ef804..dbd2b1d14c4f 100644 --- a/drivers/staging/dream/pmem.c +++ b/drivers/staging/dream/pmem.c @@ -38,17 +38,17 @@ * the file should not be released until put_pmem_file is called */ #define PMEM_FLAGS_BUSY 0x1 /* indicates that this is a suballocation of a larger master range */ -#define PMEM_FLAGS_CONNECTED ( 0x1 << 1 ) +#define PMEM_FLAGS_CONNECTED (0x1 << 1) /* indicates this is a master and not a sub allocation and that it is mmaped */ -#define PMEM_FLAGS_MASTERMAP ( 0x1 << 2 ) +#define PMEM_FLAGS_MASTERMAP (0x1 << 2) /* submap and unsubmap flags indicate: * 00: subregion has never been mmaped * 10: subregion has been mmaped, reference to the mm was taken * 11: subretion has ben released, refernece to the mm still held * 01: subretion has been released, reference to the mm has been released */ -#define PMEM_FLAGS_SUBMAP ( 0x1 << 3 ) -#define PMEM_FLAGS_UNSUBMAP ( 0x1 << 4 ) +#define PMEM_FLAGS_SUBMAP (0x1 << 3) +#define PMEM_FLAGS_UNSUBMAP (0x1 << 4) struct pmem_data { @@ -153,7 +153,7 @@ struct pmem_info { static struct pmem_info pmem[PMEM_MAX_DEVICES]; static int id_count; -#define PMEM_IS_FREE(id, index) ( !(pmem[id].bitmap[index].allocated) ) +#define PMEM_IS_FREE(id, index) (!(pmem[id].bitmap[index].allocated)) #define PMEM_ORDER(id, index) pmem[id].bitmap[index].order #define PMEM_BUDDY_INDEX(id, index) (index ^ (1 << PMEM_ORDER(id, index))) #define PMEM_NEXT_INDEX(id, index) (index + (1 << PMEM_ORDER(id, index))) @@ -845,8 +845,8 @@ static int pmem_connect(unsigned long connect, struct file *file) src_data = (struct pmem_data *)src_file->private_data; if (has_allocation(file) && (data->index != src_data->index)) { - printk(KERN_INFO "pmem: file is already mapped but doesn't match this" - " src_file!\n"); + printk(KERN_INFO "pmem: file is already mapped but doesn't " + "match this src_file!\n"); ret = -EINVAL; goto err_bad_file; } @@ -935,8 +935,8 @@ int pmem_remap(struct pmem_region *region, struct file *file, if (unlikely(!PMEM_IS_PAGE_ALIGNED(region->offset) || !PMEM_IS_PAGE_ALIGNED(region->len))) { #if PMEM_DEBUG - printk(KERN_DEBUG "pmem: request for unaligned pmem suballocation " - "%lx %lx\n", region->offset, region->len); + printk(KERN_DEBUG "pmem: request for unaligned pmem " + "suballocation %lx %lx\n", region->offset, region->len); #endif return -EINVAL; } @@ -1086,8 +1086,8 @@ static long pmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) region.offset = pmem_start_addr(id, data); region.len = pmem_len(id, data); } - printk(KERN_INFO "pmem: request for physical address of pmem region " - "from process %d.\n", current->pid); + printk(KERN_INFO "pmem: request for physical address " + "of pmem region from process %d.\n", current->pid); if (copy_to_user((void __user *)arg, ®ion, sizeof(struct pmem_region))) return -EFAULT; -- cgit v1.2.3 From 41f8b96e3d1a25e328ae77727fefa4e3c780f8a4 Mon Sep 17 00:00:00 2001 From: Chihau Chau Date: Thu, 15 Apr 2010 17:01:37 -0400 Subject: Staging: dream: smd: smd_qmi: fix code style issues This fixes some code style issues detected with the checkpatch.pl script, like not necessary braces {} in some if and else statements and include a KERN_INFO facility level in a printk() function. Signed-off-by: Chihau Chau Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dream/smd/smd_qmi.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dream/smd/smd_qmi.c b/drivers/staging/dream/smd/smd_qmi.c index 9e9067fb271b..76fce5142d9e 100644 --- a/drivers/staging/dream/smd/smd_qmi.c +++ b/drivers/staging/dream/smd/smd_qmi.c @@ -211,11 +211,10 @@ static int qmi_send(struct qmi_ctxt *ctxt, struct qmi_msg *msg) qmi_dump_msg(msg, "send"); - if (msg->service == QMI_CTL) { + if (msg->service == QMI_CTL) hlen = QMUX_HEADER - 1; - } else { + else hlen = QMUX_HEADER; - } /* QMUX length is total header + total payload - IFC selector */ len = hlen + msg->size - 1; @@ -248,11 +247,10 @@ static int qmi_send(struct qmi_ctxt *ctxt, struct qmi_msg *msg) /* len + 1 takes the interface selector into account */ r = smd_write(ctxt->ch, msg->tlv - hlen, len + 1); - if (r != len) { + if (r != len) return -1; - } else { + else return 0; - } } static void qmi_process_ctl_msg(struct qmi_ctxt *ctxt, struct qmi_msg *msg) @@ -376,7 +374,7 @@ static void qmi_process_broadcast_wds_msg(struct qmi_ctxt *ctxt, static void qmi_process_wds_msg(struct qmi_ctxt *ctxt, struct qmi_msg *msg) { - printk("wds: %04x @ %02x\n", msg->type, msg->client_id); + printk(KERN_INFO "wds: %04x @ %02x\n", msg->type, msg->client_id); if (msg->client_id == ctxt->wds_client_id) { qmi_process_unicast_wds_msg(ctxt, msg); } else if (msg->client_id == 0xff) { @@ -504,9 +502,8 @@ static void qmi_notify(void *priv, unsigned event) case SMD_EVENT_DATA: { int sz; sz = smd_cur_packet_size(ctxt->ch); - if ((sz > 0) && (sz <= smd_read_avail(ctxt->ch))) { + if ((sz > 0) && (sz <= smd_read_avail(ctxt->ch))) queue_work(qmi_wq, &ctxt->read_work); - } break; } case SMD_EVENT_OPEN: -- cgit v1.2.3 From 1bd3302c383e8179423d15a53891c49663a06e23 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Mon, 15 Mar 2010 17:00:57 +0200 Subject: Staging: usbip: fix space before tab in usbip_common.h This is a patch to the usbip_common.h fix space before tab warning found by the checkpatch.pl tools Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/usbip_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h index 6f1dcb197d13..e1bbd1287e28 100644 --- a/drivers/staging/usbip/usbip_common.h +++ b/drivers/staging/usbip/usbip_common.h @@ -182,7 +182,7 @@ struct usbip_header_basic { __u32 devid; #define USBIP_DIR_OUT 0 -#define USBIP_DIR_IN 1 +#define USBIP_DIR_IN 1 __u32 direction; __u32 ep; /* endpoint number */ } __attribute__ ((packed)); -- cgit v1.2.3 From 005126872a3a605d6f7fc2f739f5d4234f9df92c Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Mon, 15 Mar 2010 17:06:44 +0200 Subject: Staging: usbip: fix space before tab in vhci_hcd.c This is a patch to the vhci_hcd.c fix space before tab warning found by the checkpatch.pl tools Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/vhci_hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index 0b1766122d38..be5d8db98165 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -1072,7 +1072,7 @@ static struct hc_driver vhci_hc_driver = { .flags = HCD_USB2, .start = vhci_start, - .stop = vhci_stop, + .stop = vhci_stop, .urb_enqueue = vhci_urb_enqueue, .urb_dequeue = vhci_urb_dequeue, -- cgit v1.2.3 From acc4e4168f87c05be31c3259ee0cb6262473c8ea Mon Sep 17 00:00:00 2001 From: Michael Sprecher Date: Wed, 17 Mar 2010 21:15:44 +0100 Subject: staging: usbip: fix coding style issues in the usbip driver This is a patch to the usbip driver that fixes up some coding style issues found by the checkpack.pl tool Signed-off-by: Michael Sprecher Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/vhci_tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/usbip/vhci_tx.c b/drivers/staging/usbip/vhci_tx.c index b71b4c2fbd86..e1c1f716a1c2 100644 --- a/drivers/staging/usbip/vhci_tx.c +++ b/drivers/staging/usbip/vhci_tx.c @@ -179,7 +179,7 @@ static int vhci_send_cmd_unlink(struct vhci_device *vdev) memset(&msg, 0, sizeof(msg)); memset(&iov, 0, sizeof(iov)); - usbip_dbg_vhci_tx("setup cmd unlink, %lu \n", unlink->seqnum); + usbip_dbg_vhci_tx("setup cmd unlink, %lu\n", unlink->seqnum); /* 1. setup usbip_header */ -- cgit v1.2.3 From 013659f558d90369d1a555ae3c39cc42a6c3cb74 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Thu, 25 Mar 2010 18:22:37 +0100 Subject: Staging: iio: Documentation/lis3l02dqbuffersimple.c: duplicated include drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c: dirent.h is included more than once. Signed-off-by: Andrea Gelmini Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c b/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c index 2b5cfc58d78d..6a8fa0c9372e 100644 --- a/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c +++ b/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c @@ -19,7 +19,6 @@ #include #include -#include #include "iio_util.h" static const char *ring_access = "/dev/iio/lis3l02dq_ring_access"; -- cgit v1.2.3 From ceb0525c9e4f7e6a3ec762deb0960be3522030dc Mon Sep 17 00:00:00 2001 From: Barry Song <21cnbao@gmail.com> Date: Mon, 26 Apr 2010 12:19:01 +0800 Subject: Staging: iio: fix typo in userspace example codes and document Signed-off-by: Barry Song <21cnbao@gmail.com> Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c | 2 +- drivers/staging/iio/Documentation/userspace.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c b/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c index 6a8fa0c9372e..08e012fa8460 100644 --- a/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c +++ b/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c @@ -19,7 +19,7 @@ #include #include -#include "iio_util.h" +#include "iio_utils.h" static const char *ring_access = "/dev/iio/lis3l02dq_ring_access"; static const char *ring_event = "/dev/iio/lis3l02dq_ring_event"; diff --git a/drivers/staging/iio/Documentation/userspace.txt b/drivers/staging/iio/Documentation/userspace.txt index 661015a0b866..4838818f65ef 100644 --- a/drivers/staging/iio/Documentation/userspace.txt +++ b/drivers/staging/iio/Documentation/userspace.txt @@ -56,5 +56,5 @@ KERNEL="ring_event_line*", ID="spi1.0", DRIVER="lis3l02dq", NAME="iio/lis3l02dq_ KERNEL="event_line*", ID="spi1.0", DRIVER="lis3l02dq", NAME="iio/lis3l02dq_event" KERNEL="ring_access*", ID="spi1.0", DRIVER="lis3l02dq", NAME="iio/lis3l02dq_ring_access" -The files, lis3l02dqbuffersimple.c and iio_util.h in this directory provide an example +The files, lis3l02dqbuffersimple.c and iio_utils.h in this directory provide an example of how to use the ring buffer and event interfaces. -- cgit v1.2.3 From a05d7ce36c55bc6496e1085584c9df901b899ab2 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 26 Apr 2010 10:36:36 +0200 Subject: Staging: iio: iio-trig-gpio: Remove redundant gpio_request Remove redundant gpio_request: The GPIO used as trigger IRQ, is also requested as gpio, but actually never read. Use platform resource facility to get IRQs numbers and flags. Make sure this driver can be used with any system IRQ, not necessarily limited to GPIO-IRQs. Use dev_err(dev...) and friends instead of printk(KERN_ERR...) Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/trigger/iio-trig-gpio.c | 127 +++++++++++++--------------- 1 file changed, 61 insertions(+), 66 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-gpio.c index 0c3bad3187f5..e40099ff6230 100644 --- a/drivers/staging/iio/trigger/iio-trig-gpio.c +++ b/drivers/staging/iio/trigger/iio-trig-gpio.c @@ -13,7 +13,6 @@ * TODO: * * Add board config elements to allow specification of startup settings. - * Add configuration settings (irq type etc) */ #include @@ -31,7 +30,7 @@ DEFINE_MUTEX(iio_gpio_trigger_list_lock); struct iio_gpio_trigger_info { struct mutex in_use; - int gpio; + unsigned int irq; }; /* * Need to reference count these triggers and only enable gpio interrupts @@ -58,78 +57,77 @@ static const struct attribute_group iio_gpio_trigger_attr_group = { .attrs = iio_gpio_trigger_attrs, }; -static int iio_gpio_trigger_probe(struct platform_device *dev) +static int iio_gpio_trigger_probe(struct platform_device *pdev) { - int *pdata = dev->dev.platform_data; struct iio_gpio_trigger_info *trig_info; struct iio_trigger *trig, *trig2; - int i, irq, ret = 0; - if (!pdata) { - printk(KERN_ERR "No IIO gpio trigger platform data found\n"); - goto error_ret; - } - for (i = 0;; i++) { - if (!gpio_is_valid(pdata[i])) - break; - trig = iio_allocate_trigger(); - if (!trig) { - ret = -ENOMEM; - goto error_free_completed_registrations; - } + unsigned long irqflags; + struct resource *irq_res; + int irq, ret = 0, irq_res_cnt = 0; - trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL); - if (!trig_info) { - ret = -ENOMEM; - goto error_put_trigger; - } - trig->control_attrs = &iio_gpio_trigger_attr_group; - trig->private_data = trig_info; - trig_info->gpio = pdata[i]; - trig->owner = THIS_MODULE; - trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL); - if (!trig->name) { - ret = -ENOMEM; - goto error_free_trig_info; + do { + irq_res = platform_get_resource(pdev, + IORESOURCE_IRQ, irq_res_cnt); + + if (irq_res == NULL) { + if (irq_res_cnt == 0) + dev_err(&pdev->dev, "No GPIO IRQs specified"); + break; } - snprintf((char *)trig->name, - IIO_TRIGGER_NAME_LENGTH, - "gpiotrig%d", - pdata[i]); - ret = gpio_request(trig_info->gpio, trig->name); - if (ret) - goto error_free_name; - - ret = gpio_direction_input(trig_info->gpio); - if (ret) - goto error_release_gpio; - - irq = gpio_to_irq(trig_info->gpio); - if (irq < 0) { - ret = irq; - goto error_release_gpio; + irqflags = (irq_res->flags & IRQF_TRIGGER_MASK) | IRQF_SHARED; + + for (irq = irq_res->start; irq <= irq_res->end; irq++) { + + trig = iio_allocate_trigger(); + if (!trig) { + ret = -ENOMEM; + goto error_free_completed_registrations; + } + + trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL); + if (!trig_info) { + ret = -ENOMEM; + goto error_put_trigger; + } + trig->control_attrs = &iio_gpio_trigger_attr_group; + trig->private_data = trig_info; + trig_info->irq = irq; + trig->owner = THIS_MODULE; + trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, + GFP_KERNEL); + if (!trig->name) { + ret = -ENOMEM; + goto error_free_trig_info; + } + snprintf((char *)trig->name, + IIO_TRIGGER_NAME_LENGTH, + "irqtrig%d", irq); + + ret = request_irq(irq, iio_gpio_trigger_poll, + irqflags, trig->name, trig); + if (ret) { + dev_err(&pdev->dev, + "request IRQ-%d failed", irq); + goto error_free_name; + } + + ret = iio_trigger_register(trig); + if (ret) + goto error_release_irq; + + list_add_tail(&trig->alloc_list, + &iio_gpio_trigger_list); } - ret = request_irq(irq, iio_gpio_trigger_poll, - IRQF_TRIGGER_RISING, - trig->name, - trig); - if (ret) - goto error_release_gpio; + irq_res_cnt++; + } while (irq_res != NULL); - ret = iio_trigger_register(trig); - if (ret) - goto error_release_irq; - list_add_tail(&trig->alloc_list, &iio_gpio_trigger_list); - - } return 0; /* First clean up the partly allocated trigger */ error_release_irq: free_irq(irq, trig); -error_release_gpio: - gpio_free(trig_info->gpio); error_free_name: kfree(trig->name); error_free_trig_info: @@ -143,18 +141,16 @@ error_free_completed_registrations: &iio_gpio_trigger_list, alloc_list) { trig_info = trig->private_data; - free_irq(gpio_to_irq(trig_info->gpio), trig); - gpio_free(trig_info->gpio); + free_irq(gpio_to_irq(trig_info->irq), trig); kfree(trig->name); kfree(trig_info); iio_trigger_unregister(trig); } -error_ret: return ret; } -static int iio_gpio_trigger_remove(struct platform_device *dev) +static int iio_gpio_trigger_remove(struct platform_device *pdev) { struct iio_trigger *trig, *trig2; struct iio_gpio_trigger_info *trig_info; @@ -166,8 +162,7 @@ static int iio_gpio_trigger_remove(struct platform_device *dev) alloc_list) { trig_info = trig->private_data; iio_trigger_unregister(trig); - free_irq(gpio_to_irq(trig_info->gpio), trig); - gpio_free(trig_info->gpio); + free_irq(trig_info->irq, trig); kfree(trig->name); kfree(trig_info); iio_put_trigger(trig); -- cgit v1.2.3 From 7c327857016116eba1595c67c25d0314d1385e85 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 26 Apr 2010 10:49:10 +0200 Subject: Staging: iio: iio_trigger_find_by_name: Skip trailing newline if available Skip trailing newline if available. Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/industrialio-trigger.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c index 35ec80ba444f..3c8f6ffab584 100644 --- a/drivers/staging/iio/industrialio-trigger.c +++ b/drivers/staging/iio/industrialio-trigger.c @@ -156,6 +156,9 @@ struct iio_trigger *iio_trigger_find_by_name(const char *name, size_t len) struct iio_trigger *trig; bool found = false; + if (len && name[len - 1] == '\n') + len--; + mutex_lock(&iio_trigger_list_lock); list_for_each_entry(trig, &iio_trigger_list, list) { if (strncmp(trig->name, name, len) == 0) { -- cgit v1.2.3 From cebb7e83361aba7ff05ec5cfb1bd1d5c8d983eed Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Mon, 15 Mar 2010 14:24:21 +0200 Subject: Staging: wavelan: fix spaces and TAB coding style issue in i82586.h This is a patch to the i82586.h file that fixed up a TAB and spaces Errors found by the checkpatch.pl tools, like ERROR: spaces required around that '=' (ctx:VxV) and ERROR: space required before the open brace '{' Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wavelan/i82586.h | 58 +++++++++++++++------------------------- 1 file changed, 21 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wavelan/i82586.h b/drivers/staging/wavelan/i82586.h index 5f65b250646f..27f832498139 100644 --- a/drivers/staging/wavelan/i82586.h +++ b/drivers/staging/wavelan/i82586.h @@ -30,14 +30,13 @@ #define ADDR_LEN 6 #define I82586NULL 0xFFFF -#define toff(t,p,f) (unsigned short)((void *)(&((t *)((void *)0 + (p)))->f) - (void *)0) +#define toff(t, p, f) (unsigned short)((void *)(&((t *)((void *)0 + (p)))->f) - (void *)0) /* * System Configuration Pointer (SCP). */ typedef struct scp_t scp_t; -struct scp_t -{ +struct scp_t { unsigned short scp_sysbus; /* 82586 bus width: */ #define SCP_SY_16BBUS (0x0 << 0) /* 16 bits */ #define SCP_SY_8BBUS (0x1 << 0) /* 8 bits. */ @@ -50,8 +49,7 @@ struct scp_t * Intermediate System Configuration Pointer (ISCP). */ typedef struct iscp_t iscp_t; -struct iscp_t -{ +struct iscp_t { unsigned short iscp_busy; /* set by CPU before first CA, */ /* cleared by 82586 after read. */ unsigned short iscp_offset; /* offset of SCB */ @@ -67,8 +65,7 @@ struct iscp_t * then issues a Channel Attention (CA) to alert the 82586. */ typedef struct scb_t scb_t; -struct scb_t -{ +struct scb_t { unsigned short scb_status; /* Status of 82586 */ #define SCB_ST_INT (0xF << 12) /* Some of: */ #define SCB_ST_CX (0x1 << 15) /* Cmd completed */ @@ -118,14 +115,13 @@ struct scb_t unsigned short scb_ovrnerrs; /* Frames lost due to slow bus */ }; -#define scboff(p,f) toff(scb_t, p, f) +#define scboff(p, f) toff(scb_t, p, f) /* * The eight Action Commands. */ typedef enum acmd_e acmd_e; -enum acmd_e -{ +enum acmd_e { acmd_nop = 0, /* Do nothing */ acmd_ia_setup = 1, /* Load an (ethernet) address into the */ /* 82586 */ @@ -143,8 +139,7 @@ enum acmd_e * Generic Action Command header. */ typedef struct ach_t ach_t; -struct ach_t -{ +struct ach_t { unsigned short ac_status; /* Command status: */ #define AC_SFLD_C (0x1 << 15) /* Command completed */ #define AC_SFLD_B (0x1 << 14) /* Busy executing */ @@ -172,14 +167,13 @@ struct ach_t unsigned short ac_link; /* Next Action Command */ }; -#define acoff(p,f) toff(ach_t, p, f) +#define acoff(p, f) toff(ach_t, p, f) /* * The Nop Action Command. */ typedef struct ac_nop_t ac_nop_t; -struct ac_nop_t -{ +struct ac_nop_t { ach_t nop_h; }; @@ -187,8 +181,7 @@ struct ac_nop_t * The IA-Setup Action Command. */ typedef struct ac_ias_t ac_ias_t; -struct ac_ias_t -{ +struct ac_ias_t { ach_t ias_h; unsigned char ias_addr[ADDR_LEN]; /* The (ethernet) address */ }; @@ -197,8 +190,7 @@ struct ac_ias_t * The Configure Action Command. */ typedef struct ac_cfg_t ac_cfg_t; -struct ac_cfg_t -{ +struct ac_cfg_t { ach_t cfg_h; unsigned char cfg_byte_cnt; /* Size foll data: 4-12 */ #define AC_CFG_BYTE_CNT(v) (((v) & 0xF) << 0) @@ -255,8 +247,7 @@ struct ac_cfg_t * The MC-Setup Action Command. */ typedef struct ac_mcs_t ac_mcs_t; -struct ac_mcs_t -{ +struct ac_mcs_t { ach_t mcs_h; unsigned short mcs_cnt; /* No. of bytes of MC addresses */ #if 0 @@ -271,8 +262,7 @@ struct ac_mcs_t * The Transmit Action Command. */ typedef struct ac_tx_t ac_tx_t; -struct ac_tx_t -{ +struct ac_tx_t { ach_t tx_h; unsigned short tx_tbd_offset; /* Address of list of buffers. */ #if 0 @@ -290,8 +280,7 @@ ac_cfg_t action command. * The Time Domain Reflectometer Action Command. */ typedef struct ac_tdr_t ac_tdr_t; -struct ac_tdr_t -{ +struct ac_tdr_t { ach_t tdr_h; unsigned short tdr_result; /* Result. */ #define AC_TDR_LNK_OK (0x1 << 15) /* No link problem */ @@ -307,8 +296,7 @@ struct ac_tdr_t * The Dump Action Command. */ typedef struct ac_dmp_t ac_dmp_t; -struct ac_dmp_t -{ +struct ac_dmp_t { ach_t dmp_h; unsigned short dmp_offset; /* Result. */ }; @@ -322,8 +310,7 @@ struct ac_dmp_t * The Diagnose Action Command. */ typedef struct ac_dgn_t ac_dgn_t; -struct ac_dgn_t -{ +struct ac_dgn_t { ach_t dgn_h; }; @@ -331,8 +318,7 @@ struct ac_dgn_t * Transmit Buffer Descriptor (TBD). */ typedef struct tbd_t tbd_t; -struct tbd_t -{ +struct tbd_t { unsigned short tbd_status; /* Written by the CPU */ #define TBD_STATUS_EOF (0x1 << 15) /* This TBD is the */ /* last for this frame */ @@ -347,8 +333,7 @@ struct tbd_t * Receive Buffer Descriptor (RBD). */ typedef struct rbd_t rbd_t; -struct rbd_t -{ +struct rbd_t { unsigned short rbd_status; /* Written by the 82586 */ #define RBD_STATUS_EOF (0x1 << 15) /* This RBD is the */ /* last for this frame */ @@ -365,14 +350,13 @@ struct rbd_t /* buffer can hold */ }; -#define rbdoff(p,f) toff(rbd_t, p, f) +#define rbdoff(p, f) toff(rbd_t, p, f) /* * Frame Descriptor (FD). */ typedef struct fd_t fd_t; -struct fd_t -{ +struct fd_t { unsigned short fd_status; /* Written by the 82586 */ #define FD_STATUS_C (0x1 << 15) /* Completed storing frame */ #define FD_STATUS_B (0x1 << 14) /* FD was consumed by RU */ @@ -403,7 +387,7 @@ in case, we leave the space. /* Written by 82586 */ }; -#define fdoff(p,f) toff(fd_t, p, f) +#define fdoff(p, f) toff(fd_t, p, f) /* * This software may only be used and distributed -- cgit v1.2.3 From a0ec96206192a58ec1c429aa1436717d2a351d0c Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Mon, 15 Mar 2010 14:45:27 +0200 Subject: Staging: wavelan: fix spaces and TAB coding style issue in wavelan.h This is a patch to the wavelan.h file that fixed up a TAB and spaces Errors found by the checkpatch.pl tools, like ERROR: spaces required around that '=' (ctx:VxV) and ERROR: space required before the open brace '{' Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wavelan/wavelan.h | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wavelan/wavelan.h b/drivers/staging/wavelan/wavelan.h index 9ab360558ffd..1ebae10b8696 100644 --- a/drivers/staging/wavelan/wavelan.h +++ b/drivers/staging/wavelan/wavelan.h @@ -26,8 +26,7 @@ * product (OEM, like DEC RoamAbout, Digital Ocean, or Epson), * you might need to modify this part to accommodate your hardware. */ -static const char MAC_ADDRESSES[][3] = -{ +static const char MAC_ADDRESSES[][3] = { { 0x08, 0x00, 0x0E }, /* AT&T WaveLAN (standard) & DEC RoamAbout */ { 0x08, 0x00, 0x6A }, /* AT&T WaveLAN (alternate) */ { 0x00, 0x00, 0xE1 }, /* Hitachi Wavelan */ @@ -67,8 +66,7 @@ static const int fixed_bands[] = { 915e6, 2.425e8, 2.46e8, 2.484e8, 2.4305e8 }; * (base is board port address). */ typedef union hacs_u hacs_u; -union hacs_u -{ +union hacs_u { unsigned short hu_command; /* Command register */ #define HACR_RESET 0x0001 /* Reset board */ #define HACR_CA 0x0002 /* Set Channel Attention for 82586 */ @@ -88,8 +86,7 @@ union hacs_u } __attribute__ ((packed)); typedef struct ha_t ha_t; -struct ha_t -{ +struct ha_t { hacs_u ha_cs; /* Command and status registers */ #define ha_command ha_cs.hu_command #define ha_status ha_cs.hu_status @@ -104,7 +101,7 @@ struct ha_t #define HA_SIZE 16 -#define hoff(p,f) (unsigned short)((void *)(&((ha_t *)((void *)0 + (p)))->f) - (void *)0) +#define hoff(p, f) (unsigned short)((void *)(&((ha_t *)((void *)0 + (p)))->f) - (void *)0) #define HACR(p) hoff(p, ha_command) #define HASR(p) hoff(p, ha_status) #define MMCR(p) hoff(p, ha_mmcr) @@ -127,7 +124,7 @@ struct ha_t #define PARAM_ACCESS_PIO 3 /* Mode 4: LAN parameter access mode */ /* Parameter access. */ #define PIO_MASK 3 /* register mask */ -#define PIOM(cmd,piono) ((u_short)cmd << 10 << (piono * 2)) +#define PIOM(cmd, piono) ((u_short)cmd << 10 << (piono * 2)) #define HACR_DEFAULT (HACR_OUT0 | HACR_OUT1 | HACR_16BITS | PIOM(STATIC_PIO, 0) | PIOM(AUTOINCR_PIO, 1) | PIOM(PARAM_ACCESS_PIO, 2)) #define HACR_INTRON (HACR_82586_INT_ENABLE | HACR_MMC_INT_ENABLE | HACR_INTR_CLR_ENABLE) @@ -156,8 +153,7 @@ struct ha_t * Parameter Storage Area (PSA). */ typedef struct psa_t psa_t; -struct psa_t -{ +struct psa_t { unsigned char psa_io_base_addr_1; /* [0x00] Base address 1 ??? */ unsigned char psa_io_base_addr_2; /* [0x01] Base address 2 */ unsigned char psa_io_base_addr_3; /* [0x02] Base address 3 */ @@ -208,7 +204,7 @@ struct psa_t /* Calculate offset of a field in the above structure. * Warning: only even addresses are used. */ -#define psaoff(p,f) ((unsigned short) ((void *)(&((psa_t *) ((void *) NULL + (p)))->f) - (void *) NULL)) +#define psaoff(p, f) ((unsigned short) ((void *)(&((psa_t *) ((void *) NULL + (p)))->f) - (void *) NULL)) /******************** MODEM MANAGEMENT INTERFACE ********************/ @@ -216,8 +212,7 @@ struct psa_t * Modem Management Controller (MMC) write structure. */ typedef struct mmw_t mmw_t; -struct mmw_t -{ +struct mmw_t { unsigned char mmw_encr_key[8]; /* encryption key */ unsigned char mmw_encr_enable; /* Enable or disable encryption. */ #define MMW_ENCR_ENABLE_MODE 0x02 /* mode of security option */ @@ -296,14 +291,13 @@ struct mmw_t #define MMW_SIZE 37 -#define mmwoff(p,f) (unsigned short)((void *)(&((mmw_t *)((void *)0 + (p)))->f) - (void *)0) +#define mmwoff(p, f) (unsigned short)((void *)(&((mmw_t *)((void *)0 + (p)))->f) - (void *)0) /* * Modem Management Controller (MMC) read structure. */ typedef struct mmr_t mmr_t; -struct mmr_t -{ +struct mmr_t { unsigned char mmr_unused0[8]; /* unused */ unsigned char mmr_des_status; /* encryption status */ unsigned char mmr_des_avail; /* encryption available (0x55 read) */ @@ -351,11 +345,10 @@ struct mmr_t #define MMR_SIZE 36 -#define mmroff(p,f) (unsigned short)((void *)(&((mmr_t *)((void *)0 + (p)))->f) - (void *)0) +#define mmroff(p, f) (unsigned short)((void *)(&((mmr_t *)((void *)0 + (p)))->f) - (void *)0) /* Make the two above structures one */ -typedef union mm_t -{ +typedef union mm_t { struct mmw_t w; /* Write to the mmc */ struct mmr_t r; /* Read from the mmc */ } mm_t; -- cgit v1.2.3 From 604ef85819ec42c3ec8faca62eee8deb534b89c9 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Mon, 15 Mar 2010 14:58:01 +0200 Subject: Staging: wavelan: fix spaces and TAB coding style and macros issue in wavelan.p.h This is a patch to the wavelan.h file that fixed up a TAB and spaces Errors found by the checkpatch.pl tools, like ERROR: spaces required around that '=' (ctx:VxV) and ERROR: space required before the open brace '{' and Macros with complex values should be enclosed in parenthesis Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wavelan/wavelan.p.h | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wavelan/wavelan.p.h b/drivers/staging/wavelan/wavelan.p.h index dbe8de6e5f52..d5f322c68d05 100644 --- a/drivers/staging/wavelan/wavelan.p.h +++ b/drivers/staging/wavelan/wavelan.p.h @@ -125,7 +125,7 @@ * writing a WaveLAN ISA driver for the Mach microkernel. Girish * Welling had also worked on it. * Keith Moore modified this for the PCMCIA hardware. - * + * * Robert Morris ported these two drivers to BSDI * and added specific PCMCIA support (there is currently no equivalent * of the PCMCIA package under BSD). @@ -451,17 +451,18 @@ static const char *version = "wavelan.c : v24 (SMP + wireless extensions) 11/12/ /* ------------------------ PRIVATE IOCTL ------------------------ */ #define SIOCSIPQTHR SIOCIWFIRSTPRIV /* Set quality threshold */ -#define SIOCGIPQTHR SIOCIWFIRSTPRIV + 1 /* Get quality threshold */ +#define SIOCGIPQTHR (SIOCIWFIRSTPRIV + 1) /* Get quality threshold */ -#define SIOCSIPHISTO SIOCIWFIRSTPRIV + 2 /* Set histogram ranges */ -#define SIOCGIPHISTO SIOCIWFIRSTPRIV + 3 /* Get histogram values */ +#define SIOCSIPHISTO (SIOCIWFIRSTPRIV + 2) /* Set histogram ranges */ +#define SIOCGIPHISTO (SIOCIWFIRSTPRIV + 3) /* Get histogram values */ /****************************** TYPES ******************************/ /* Shortcuts */ typedef struct iw_statistics iw_stats; typedef struct iw_quality iw_qual; -typedef struct iw_freq iw_freq;typedef struct net_local net_local; +typedef struct iw_freq iw_freq; +typedef struct net_local net_local; typedef struct timer_list timer_list; /* Basic types */ @@ -474,10 +475,9 @@ typedef u_char mac_addr[WAVELAN_ADDR_SIZE]; /* Hardware address */ * keeps the generic data (same format for everybody) and "net_local" keeps * additional specific data. */ -struct net_local -{ - net_local * next; /* linked list of the devices */ - struct net_device * dev; /* reverse link */ +struct net_local { + net_local *next; /* linked list of the devices */ + struct net_device *dev; /* reverse link */ spinlock_t spinlock; /* Serialize access to the hardware (SMP) */ int nresets; /* number of hardware resets */ u_char reconfig_82586; /* We need to reconfigure the controller. */ @@ -534,7 +534,7 @@ static void int, /* offset in PSA */ u_char *, /* buffer to fill */ int), /* size to read */ - psa_write(u_long, /* Write to the PSA. */ + psa_write(u_long, /* Write to the PSA. */ u_short, /* hacr */ int, /* offset in PSA */ u_char *, /* buffer in memory */ @@ -654,8 +654,7 @@ static net_local * wavelan_list = (net_local *) NULL; * This table is used to translate the PSA value to IRQ number * and vice versa. */ -static u_char irqvals[] = -{ +static u_char irqvals[] = { 0, 0, 0, 0x01, 0x02, 0x04, 0, 0x08, 0, 0, 0x10, 0x20, @@ -665,8 +664,7 @@ static u_char irqvals[] = /* * Table of the available I/O addresses (base addresses) for WaveLAN */ -static unsigned short iobase[] = -{ +static unsigned short iobase[] = { #if 0 /* Leave out 0x3C0 for now -- seems to clash with some video * controllers. -- cgit v1.2.3 From b2561f212210a7c31b4d1c7d7136c38724719fa8 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Mon, 15 Mar 2010 15:21:30 +0200 Subject: Staging: wavelan: fix spaces and TAB coding style issue in wavelan_cs.h This is a patch to the wavelan.h file that fixed up a TAB and spaces Errors found by the checkpatch.pl tools, like ERROR: spaces required around that '=' (ctx:VxV) and ERROR: space required before the open brace '{' Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wavelan/wavelan_cs.h | 37 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wavelan/wavelan_cs.h b/drivers/staging/wavelan/wavelan_cs.h index 2e4bfe4147c6..42e268dbae98 100644 --- a/drivers/staging/wavelan/wavelan_cs.h +++ b/drivers/staging/wavelan/wavelan_cs.h @@ -18,7 +18,7 @@ */ /* - * Definitions for the AT&T GIS (formerly NCR) WaveLAN PCMCIA card: + * Definitions for the AT&T GIS (formerly NCR) WaveLAN PCMCIA card: * An Ethernet-like radio transceiver controlled by an Intel 82593 * coprocessor. * @@ -37,7 +37,7 @@ * in supporting documentation that copying and distribution is * by permission of M.I.T. M.I.T. makes no representations about * the suitability of this software for any purpose. It is pro- - * vided "as is" without express or implied warranty. + * vided "as is" without express or implied warranty. **************************************************************************** * * @@ -62,8 +62,7 @@ * like DEC RoamAbout, or Digital Ocean, Epson, ...), you must modify this * part to accommodate your hardware... */ -static const unsigned char MAC_ADDRESSES[][3] = -{ +static const unsigned char MAC_ADDRESSES[][3] = { { 0x08, 0x00, 0x0E }, /* AT&T Wavelan (standard) & DEC RoamAbout */ { 0x08, 0x00, 0x6A }, /* AT&T Wavelan (alternate) */ { 0x00, 0x00, 0xE1 }, /* Hitachi Wavelan */ @@ -171,8 +170,7 @@ static const int fixed_bands[] = { 915e6, 2.425e8, 2.46e8, 2.484e8, 2.4305e8 }; * Parameter Storage Area (PSA). */ typedef struct psa_t psa_t; -struct psa_t -{ +struct psa_t { /* For the PCMCIA Adapter, locations 0x00-0x0F are unused and fixed at 00 */ unsigned char psa_io_base_addr_1; /* [0x00] Base address 1 ??? */ unsigned char psa_io_base_addr_2; /* [0x01] Base address 2 */ @@ -191,14 +189,14 @@ struct psa_t #define PSA_UNIVERSAL 0 /* Universal (factory) */ #define PSA_LOCAL 1 /* Local */ unsigned char psa_comp_number; /* [0x1D] Compatability Number: */ -#define PSA_COMP_PC_AT_915 0 /* PC-AT 915 MHz */ -#define PSA_COMP_PC_MC_915 1 /* PC-MC 915 MHz */ -#define PSA_COMP_PC_AT_2400 2 /* PC-AT 2.4 GHz */ -#define PSA_COMP_PC_MC_2400 3 /* PC-MC 2.4 GHz */ -#define PSA_COMP_PCMCIA_915 4 /* PCMCIA 915 MHz or 2.0 */ +#define PSA_COMP_PC_AT_915 0 /* PC-AT 915 MHz */ +#define PSA_COMP_PC_MC_915 1 /* PC-MC 915 MHz */ +#define PSA_COMP_PC_AT_2400 2 /* PC-AT 2.4 GHz */ +#define PSA_COMP_PC_MC_2400 3 /* PC-MC 2.4 GHz */ +#define PSA_COMP_PCMCIA_915 4 /* PCMCIA 915 MHz or 2.0 */ unsigned char psa_thr_pre_set; /* [0x1E] Modem Threshold Preset */ unsigned char psa_feature_select; /* [0x1F] Call code required (1=on) */ -#define PSA_FEATURE_CALL_CODE 0x01 /* Call code required (Japan) */ +#define PSA_FEATURE_CALL_CODE 0x01 /* Call code required (Japan) */ unsigned char psa_subband; /* [0x20] Subband */ #define PSA_SUBBAND_915 0 /* 915 MHz or 2.0 */ #define PSA_SUBBAND_2425 1 /* 2425 MHz */ @@ -225,7 +223,7 @@ struct psa_t /* Calculate offset of a field in the above structure * Warning : only even addresses are used */ -#define psaoff(p,f) ((unsigned short) ((void *)(&((psa_t *) ((void *) NULL + (p)))->f) - (void *) NULL)) +#define psaoff(p, f) ((unsigned short) ((void *)(&((psa_t *) ((void *) NULL + (p)))->f) - (void *) NULL)) /******************** MODEM MANAGEMENT INTERFACE ********************/ @@ -233,8 +231,7 @@ struct psa_t * Modem Management Controller (MMC) write structure. */ typedef struct mmw_t mmw_t; -struct mmw_t -{ +struct mmw_t { unsigned char mmw_encr_key[8]; /* encryption key */ unsigned char mmw_encr_enable; /* enable/disable encryption */ #define MMW_ENCR_ENABLE_MODE 0x02 /* Mode of security option */ @@ -315,15 +312,14 @@ struct mmw_t #define MMW_SIZE 37 /* Calculate offset of a field in the above structure */ -#define mmwoff(p,f) (unsigned short)((void *)(&((mmw_t *)((void *)0 + (p)))->f) - (void *)0) +#define mmwoff(p, f) (unsigned short)((void *)(&((mmw_t *)((void *)0 + (p)))->f) - (void *)0) /* * Modem Management Controller (MMC) read structure. */ typedef struct mmr_t mmr_t; -struct mmr_t -{ +struct mmr_t { unsigned char mmr_unused0[8]; /* unused */ unsigned char mmr_des_status; /* encryption status */ unsigned char mmr_des_avail; /* encryption available (0x55 read) */ @@ -373,12 +369,11 @@ struct mmr_t #define MMR_SIZE 36 /* Calculate offset of a field in the above structure */ -#define mmroff(p,f) (unsigned short)((void *)(&((mmr_t *)((void *)0 + (p)))->f) - (void *)0) +#define mmroff(p, f) (unsigned short)((void *)(&((mmr_t *)((void *)0 + (p)))->f) - (void *)0) /* Make the two above structures one */ -typedef union mm_t -{ +typedef union mm_t { struct mmw_t w; /* Write to the mmc */ struct mmr_t r; /* Read from the mmc */ } mm_t; -- cgit v1.2.3 From fb549675ffc09afecea771229ce48a33c7ea604e Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Mon, 15 Mar 2010 16:05:09 +0200 Subject: Staging: wavelan: fix macros, spaces and TAB coding style issue in wavelan_cs.p.h This is a patch to the wavelan.h file that fixed up a TAB and spaces Errors found by the checkpatch.pl tools, like ERROR: spaces required around that '=' (ctx:VxV) and ERROR: space required before the open brace '{' and Macros complex expr -> (complex expr) Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wavelan/wavelan_cs.p.h | 38 +++++++++++++++------------------- 1 file changed, 17 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wavelan/wavelan_cs.p.h b/drivers/staging/wavelan/wavelan_cs.p.h index 8fbfaa8a5a67..9427eb2727a1 100644 --- a/drivers/staging/wavelan/wavelan_cs.p.h +++ b/drivers/staging/wavelan/wavelan_cs.p.h @@ -123,7 +123,7 @@ * writing a Wavelan ISA driver for the MACH microkernel. Girish * Welling had also worked on it. * Keith Moore modify this for the Pcmcia hardware. - * + * * Robert Morris port these two drivers to BSDI * and add specific Pcmcia support (there is currently no equivalent * of the PCMCIA package under BSD...). @@ -283,7 +283,7 @@ * Changes made in sixth release (2.9.1a) : * -------------------------------------- * - Change the detection code for multi manufacturer code support - * - Correct bug (hang kernel) in init when we were "rejecting" a card + * - Correct bug (hang kernel) in init when we were "rejecting" a card * * Changes made in seventh release (2.9.1b) : * ---------------------------------------- @@ -514,12 +514,12 @@ static const char *version = "wavelan_cs.c : v24 (SMP + wireless extensions) 11/ /* ------------------------ PRIVATE IOCTL ------------------------ */ #define SIOCSIPQTHR SIOCIWFIRSTPRIV /* Set quality threshold */ -#define SIOCGIPQTHR SIOCIWFIRSTPRIV + 1 /* Get quality threshold */ -#define SIOCSIPROAM SIOCIWFIRSTPRIV + 2 /* Set roaming state */ -#define SIOCGIPROAM SIOCIWFIRSTPRIV + 3 /* Get roaming state */ +#define SIOCGIPQTHR (SIOCIWFIRSTPRIV + 1) /* Get quality threshold */ +#define SIOCSIPROAM (SIOCIWFIRSTPRIV + 2) /* Set roaming state */ +#define SIOCGIPROAM (SIOCIWFIRSTPRIV + 3) /* Get roaming state */ -#define SIOCSIPHISTO SIOCIWFIRSTPRIV + 4 /* Set histogram ranges */ -#define SIOCGIPHISTO SIOCIWFIRSTPRIV + 5 /* Get histogram values */ +#define SIOCSIPHISTO (SIOCIWFIRSTPRIV + 4) /* Set histogram ranges */ +#define SIOCGIPHISTO (SIOCIWFIRSTPRIV + 5) /* Get histogram values */ /*************************** WaveLAN Roaming **************************/ #ifdef WAVELAN_ROAMING /* Conditional compile, see above in options */ @@ -532,17 +532,16 @@ static const char *version = "wavelan_cs.c : v24 (SMP + wireless extensions) 11/ #define SEARCH_THRESH_LOW 10 /* SNR to enter cell search */ #define SEARCH_THRESH_HIGH 13 /* SNR to leave cell search */ #define WAVELAN_ROAMING_DELTA 1 /* Hysteresis value (+/- SNR) */ -#define CELL_TIMEOUT 2*HZ /* in jiffies */ +#define CELL_TIMEOUT (2*HZ) /* in jiffies */ #define FAST_CELL_SEARCH 1 /* Boolean values... */ #define NWID_PROMISC 1 /* for code clarity. */ -typedef struct wavepoint_beacon -{ +typedef struct wavepoint_beacon { unsigned char dsap, /* Unused */ ssap, /* Unused */ ctrl, /* Unused */ - O,U,I, /* Unused */ + O, U, I, /* Unused */ spec_id1, /* Unused */ spec_id2, /* Unused */ pdu_type, /* Unused */ @@ -551,8 +550,7 @@ typedef struct wavepoint_beacon nwid; /* WavePoint NWID */ } wavepoint_beacon; -typedef struct wavepoint_history -{ +typedef struct wavepoint_history { unsigned short nwid; /* WavePoint's NWID */ int average_slow; /* SNR running average */ int average_fast; /* SNR running average */ @@ -564,8 +562,7 @@ typedef struct wavepoint_history unsigned long last_seen; /* Time of last beacon recvd, jiffies */ } wavepoint_history; -struct wavepoint_table -{ +struct wavepoint_table { wavepoint_history *head; /* Start of ringbuffer */ int num_wavepoints; /* No. of WavePoints visible */ unsigned char locked; /* Table lock */ @@ -592,12 +589,11 @@ typedef u_char mac_addr[WAVELAN_ADDR_SIZE]; /* Hardware address */ * keep the generic data (same format for everybody) and "net_local" keep * the additional specific data. */ -struct net_local -{ +struct net_local { dev_node_t node; /* ???? What is this stuff ???? */ - struct net_device * dev; /* Reverse link... */ + struct net_device *dev; /* Reverse link... */ spinlock_t spinlock; /* Serialize access to the hardware (SMP) */ - struct pcmcia_device * link; /* pcmcia structure */ + struct pcmcia_device *link; /* pcmcia structure */ int nresets; /* Number of hw resets */ u_char configured; /* If it is configured */ u_char reconfig_82593; /* Need to reconfigure the controller */ @@ -623,7 +619,7 @@ struct net_local u_long domain_id; /* Domain ID we lock on for roaming */ int filter_domains; /* Check Domain ID of beacon found */ struct wavepoint_table wavepoint_table; /* Table of visible WavePoints*/ - wavepoint_history * curr_point; /* Current wavepoint */ + wavepoint_history *curr_point; /* Current wavepoint */ int cell_search; /* Searching for new cell? */ struct timer_list cell_timer; /* Garbage collection */ #endif /* WAVELAN_ROAMING */ @@ -673,7 +669,7 @@ static void int); /* number of registers */ /* ---------------------- I82593 SUBROUTINES ----------------------- */ static int - wv_82593_cmd(struct net_device *, /* synchronously send a command to i82593 */ + wv_82593_cmd(struct net_device *, /* synchronously send a command to i82593 */ char *, int, int); -- cgit v1.2.3 From 8eb3e22e56ee35a6a65c956bd2862c8247443cbd Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Mon, 15 Mar 2010 16:13:04 +0200 Subject: Staging: wavelan: fix initialise statics to 0 in wavelan_cs.p.h This is a patch to the wavelan_cs.p.h fix initialise statics to 0 Errors found by the checkpatch.pl tools, like ERROR: do not initialise statics to 0 or NULL Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wavelan/wavelan_cs.p.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wavelan/wavelan_cs.p.h b/drivers/staging/wavelan/wavelan_cs.p.h index 9427eb2727a1..7196267976f0 100644 --- a/drivers/staging/wavelan/wavelan_cs.p.h +++ b/drivers/staging/wavelan/wavelan_cs.p.h @@ -745,14 +745,14 @@ static void */ /* Shared memory speed, in ns */ -static int mem_speed = 0; +static int mem_speed; /* New module interface */ module_param(mem_speed, int, 0); #ifdef WAVELAN_ROAMING /* Conditional compile, see above in options */ /* Enable roaming mode ? No ! Please keep this to 0 */ -static int do_roaming = 0; +static int do_roaming; module_param(do_roaming, bool, 0); #endif /* WAVELAN_ROAMING */ -- cgit v1.2.3 From 0970305a9f36e24e841f2bd79caab4fa0cb56662 Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Wed, 17 Mar 2010 22:33:27 +0100 Subject: Staging: winbond: phy_calibration.h coding style cleanup. I fixed all checkpatch.pl problems, removed versioning comments and "commented away" code. Signed-off-by: Lars Lindley Acked-by: Pavel Machek Acked-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/phy_calibration.h | 177 +++++++++++++----------------- 1 file changed, 77 insertions(+), 100 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/phy_calibration.h b/drivers/staging/winbond/phy_calibration.h index 51c8fde81e2b..303203148839 100644 --- a/drivers/staging/winbond/phy_calibration.h +++ b/drivers/staging/winbond/phy_calibration.h @@ -3,105 +3,82 @@ #include "wbhal_f.h" -// 20031229 Turbo add -#define REG_AGC_CTRL1 0x1000 -#define REG_AGC_CTRL2 0x1004 -#define REG_AGC_CTRL3 0x1008 -#define REG_AGC_CTRL4 0x100C -#define REG_AGC_CTRL5 0x1010 -#define REG_AGC_CTRL6 0x1014 -#define REG_AGC_CTRL7 0x1018 -#define REG_AGC_CTRL8 0x101C -#define REG_AGC_CTRL9 0x1020 -#define REG_AGC_CTRL10 0x1024 -#define REG_CCA_CTRL 0x1028 -#define REG_A_ACQ_CTRL 0x102C -#define REG_B_ACQ_CTRL 0x1030 -#define REG_A_TXRX_CTRL 0x1034 -#define REG_B_TXRX_CTRL 0x1038 -#define REG_A_TX_COEF3 0x103C -#define REG_A_TX_COEF2 0x1040 -#define REG_A_TX_COEF1 0x1044 -#define REG_B_TX_COEF2 0x1048 -#define REG_B_TX_COEF1 0x104C -#define REG_MODE_CTRL 0x1050 -#define REG_CALIB_DATA 0x1054 -#define REG_IQ_ALPHA 0x1058 -#define REG_DC_CANCEL 0x105C -#define REG_WTO_READ 0x1060 -#define REG_OFFSET_READ 0x1064 -#define REG_CALIB_READ1 0x1068 -#define REG_CALIB_READ2 0x106C -#define REG_A_FREQ_EST 0x1070 - - - - -// 20031101 Turbo add -#define MASK_AMER_OFF_REG BIT(31) - -#define MASK_BMER_OFF_REG BIT(31) - -#define MASK_LNA_FIX_GAIN (BIT(3)|BIT(4)) -#define MASK_AGC_FIX BIT(1) - -#define MASK_AGC_FIX_GAIN 0xFF00 - -#define MASK_ADC_DC_CAL_STR BIT(10) -#define MASK_CALIB_START BIT(4) -#define MASK_IQCAL_TONE_SEL (BIT(3)|BIT(2)) -#define MASK_IQCAL_MODE (BIT(1)|BIT(0)) - -#define MASK_TX_CAL_0 0xF0000000 -#define TX_CAL_0_SHIFT 28 -#define MASK_TX_CAL_1 0x0F000000 -#define TX_CAL_1_SHIFT 24 -#define MASK_TX_CAL_2 0x00F00000 -#define TX_CAL_2_SHIFT 20 -#define MASK_TX_CAL_3 0x000F0000 -#define TX_CAL_3_SHIFT 16 -#define MASK_RX_CAL_0 0x0000F000 -#define RX_CAL_0_SHIFT 12 -#define MASK_RX_CAL_1 0x00000F00 -#define RX_CAL_1_SHIFT 8 -#define MASK_RX_CAL_2 0x000000F0 -#define RX_CAL_2_SHIFT 4 -#define MASK_RX_CAL_3 0x0000000F -#define RX_CAL_3_SHIFT 0 - -#define MASK_CANCEL_DC_I 0x3E0 -#define CANCEL_DC_I_SHIFT 5 -#define MASK_CANCEL_DC_Q 0x01F -#define CANCEL_DC_Q_SHIFT 0 - -// LA20040210 kevin -//#define MASK_ADC_DC_CAL_I(x) (((x)&0x1FE00)>>9) -//#define MASK_ADC_DC_CAL_Q(x) ((x)&0x1FF) -#define MASK_ADC_DC_CAL_I(x) (((x)&0x0003FE00)>>9) -#define MASK_ADC_DC_CAL_Q(x) ((x)&0x000001FF) - -// LA20040210 kevin (Turbo has wrong definition) -//#define MASK_IQCAL_TONE_I 0x7FFC000 -//#define SHIFT_IQCAL_TONE_I(x) ((x)>>13) -//#define MASK_IQCAL_TONE_Q 0x1FFF -//#define SHIFT_IQCAL_TONE_Q(x) ((x)>>0) -#define MASK_IQCAL_TONE_I 0x00001FFF -#define SHIFT_IQCAL_TONE_I(x) ((x)>>0) -#define MASK_IQCAL_TONE_Q 0x03FFE000 -#define SHIFT_IQCAL_TONE_Q(x) ((x)>>13) - -// LA20040210 kevin (Turbo has wrong definition) -//#define MASK_IQCAL_IMAGE_I 0x7FFC000 -//#define SHIFT_IQCAL_IMAGE_I(x) ((x)>>13) -//#define MASK_IQCAL_IMAGE_Q 0x1FFF -//#define SHIFT_IQCAL_IMAGE_Q(x) ((x)>>0) - -//#define MASK_IQCAL_IMAGE_I 0x00001FFF -//#define SHIFT_IQCAL_IMAGE_I(x) ((x)>>0) -//#define MASK_IQCAL_IMAGE_Q 0x03FFE000 -//#define SHIFT_IQCAL_IMAGE_Q(x) ((x)>>13) - -void phy_set_rf_data( struct hw_data * pHwData, u32 index, u32 value ); -#define phy_init_rf( _A ) //RFSynthesizer_initial( _A ) +#define REG_AGC_CTRL1 0x1000 +#define REG_AGC_CTRL2 0x1004 +#define REG_AGC_CTRL3 0x1008 +#define REG_AGC_CTRL4 0x100C +#define REG_AGC_CTRL5 0x1010 +#define REG_AGC_CTRL6 0x1014 +#define REG_AGC_CTRL7 0x1018 +#define REG_AGC_CTRL8 0x101C +#define REG_AGC_CTRL9 0x1020 +#define REG_AGC_CTRL10 0x1024 +#define REG_CCA_CTRL 0x1028 +#define REG_A_ACQ_CTRL 0x102C +#define REG_B_ACQ_CTRL 0x1030 +#define REG_A_TXRX_CTRL 0x1034 +#define REG_B_TXRX_CTRL 0x1038 +#define REG_A_TX_COEF3 0x103C +#define REG_A_TX_COEF2 0x1040 +#define REG_A_TX_COEF1 0x1044 +#define REG_B_TX_COEF2 0x1048 +#define REG_B_TX_COEF1 0x104C +#define REG_MODE_CTRL 0x1050 +#define REG_CALIB_DATA 0x1054 +#define REG_IQ_ALPHA 0x1058 +#define REG_DC_CANCEL 0x105C +#define REG_WTO_READ 0x1060 +#define REG_OFFSET_READ 0x1064 +#define REG_CALIB_READ1 0x1068 +#define REG_CALIB_READ2 0x106C +#define REG_A_FREQ_EST 0x1070 + + +#define MASK_AMER_OFF_REG BIT(31) + +#define MASK_BMER_OFF_REG BIT(31) + +#define MASK_LNA_FIX_GAIN (BIT(3) | BIT(4)) +#define MASK_AGC_FIX BIT(1) + +#define MASK_AGC_FIX_GAIN 0xFF00 + +#define MASK_ADC_DC_CAL_STR BIT(10) +#define MASK_CALIB_START BIT(4) +#define MASK_IQCAL_TONE_SEL (BIT(3) | BIT(2)) +#define MASK_IQCAL_MODE (BIT(1) | BIT(0)) + +#define MASK_TX_CAL_0 0xF0000000 +#define TX_CAL_0_SHIFT 28 +#define MASK_TX_CAL_1 0x0F000000 +#define TX_CAL_1_SHIFT 24 +#define MASK_TX_CAL_2 0x00F00000 +#define TX_CAL_2_SHIFT 20 +#define MASK_TX_CAL_3 0x000F0000 +#define TX_CAL_3_SHIFT 16 +#define MASK_RX_CAL_0 0x0000F000 +#define RX_CAL_0_SHIFT 12 +#define MASK_RX_CAL_1 0x00000F00 +#define RX_CAL_1_SHIFT 8 +#define MASK_RX_CAL_2 0x000000F0 +#define RX_CAL_2_SHIFT 4 +#define MASK_RX_CAL_3 0x0000000F +#define RX_CAL_3_SHIFT 0 + +#define MASK_CANCEL_DC_I 0x3E0 +#define CANCEL_DC_I_SHIFT 5 +#define MASK_CANCEL_DC_Q 0x01F +#define CANCEL_DC_Q_SHIFT 0 + +#define MASK_ADC_DC_CAL_I(x) (((x) & 0x0003FE00) >> 9) +#define MASK_ADC_DC_CAL_Q(x) ((x) & 0x000001FF) + +#define MASK_IQCAL_TONE_I 0x00001FFF +#define SHIFT_IQCAL_TONE_I(x) ((x) >> 0) +#define MASK_IQCAL_TONE_Q 0x03FFE000 +#define SHIFT_IQCAL_TONE_Q(x) ((x) >> 13) + +void phy_set_rf_data(struct hw_data *pHwData, u32 index, u32 value); +#define phy_init_rf(_A) /* RFSynthesizer_initial(_A) */ #endif -- cgit v1.2.3 From e7b10ba8c7152e3c888355656d38e19732b98bf1 Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Thu, 18 Mar 2010 09:54:53 +0100 Subject: Staging: winbond: mds_f.h whitespace and CamelCase corrections. I fixed the whitespaces, the C99 comment and the CamelCase parameter names. Signed-off-by: Lars Lindley Acked-by: Pekka Enberg Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mds_f.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/mds_f.h b/drivers/staging/winbond/mds_f.h index e09dd4b879d4..20e97bfe01e9 100644 --- a/drivers/staging/winbond/mds_f.h +++ b/drivers/staging/winbond/mds_f.h @@ -4,17 +4,17 @@ #include "wbhal_s.h" #include "core.h" -unsigned char Mds_initial( struct wbsoft_priv *adapter ); -void Mds_Destroy( struct wbsoft_priv *adapter ); -void Mds_Tx( struct wbsoft_priv *adapter ); -void Mds_SendComplete( struct wbsoft_priv *adapter, PT02_DESCRIPTOR pT02 ); -void Mds_MpduProcess( struct wbsoft_priv *adapter, struct wb35_descriptor *pRxDes ); +unsigned char Mds_initial(struct wbsoft_priv *adapter); +void Mds_Destroy(struct wbsoft_priv *adapter); +void Mds_Tx(struct wbsoft_priv *adapter); +void Mds_SendComplete(struct wbsoft_priv *adapter, PT02_DESCRIPTOR pt02); +void Mds_MpduProcess(struct wbsoft_priv *adapter, struct wb35_descriptor *prxdes); extern void DataDmp(u8 *pdata, u32 len, u32 offset); -// For data frame sending 20060802 -u16 MDS_GetPacketSize( struct wbsoft_priv *adapter ); -void MDS_GetNextPacket( struct wbsoft_priv *adapter, struct wb35_descriptor *pDes ); -void MDS_GetNextPacketComplete( struct wbsoft_priv *adapter, struct wb35_descriptor *pDes ); -void MDS_SendResult( struct wbsoft_priv *adapter, u8 PacketId, unsigned char SendOK ); +/* For data frame sending */ +u16 MDS_GetPacketSize(struct wbsoft_priv *adapter); +void MDS_GetNextPacket(struct wbsoft_priv *adapter, struct wb35_descriptor *pdes); +void MDS_GetNextPacketComplete(struct wbsoft_priv *adapter, struct wb35_descriptor *pdes); +void MDS_SendResult(struct wbsoft_priv *adapter, u8 packetid, unsigned char sendok); #endif -- cgit v1.2.3 From 5ea0525500f7cd3c09d4ee7beb66079d6abef8ab Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Thu, 18 Mar 2010 15:43:36 +0100 Subject: Staging: winbond: mds_s.h coding style fixes. I fixed all problems reported by checkpatch.pl except some long lines. Signed-off-by: Lars Lindley Acked-by: Pekka Enberg Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mds_s.h | 173 ++++++++++++++++++++-------------------- 1 file changed, 86 insertions(+), 87 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/mds_s.h b/drivers/staging/winbond/mds_s.h index 217ff0819a93..89328c5dbdad 100644 --- a/drivers/staging/winbond/mds_s.h +++ b/drivers/staging/winbond/mds_s.h @@ -15,122 +15,121 @@ enum { WLAN_PREAMBLE_TYPE_LONG, }; -//////////////////////////////////////////////////////////////////////////////////////////////////////// -#define MAX_USB_TX_DESCRIPTOR 15 // IS89C35 ability -#define MAX_USB_TX_BUFFER_NUMBER 4 // Virtual pre-buffer number of MAX_USB_TX_BUFFER -#define MAX_USB_TX_BUFFER 4096 // IS89C35 ability 4n alignment is required for hardware +/*****************************************************************************/ +#define MAX_USB_TX_DESCRIPTOR 15 /* IS89C35 ability */ +#define MAX_USB_TX_BUFFER_NUMBER 4 /* Virtual pre-buffer number of MAX_USB_TX_BUFFER */ +#define MAX_USB_TX_BUFFER 4096 /* IS89C35 ability 4n alignment is required for hardware */ -#define AUTH_REQUEST_PAIRWISE_ERROR 0 // _F flag setting -#define AUTH_REQUEST_GROUP_ERROR 1 // _F flag setting +#define AUTH_REQUEST_PAIRWISE_ERROR 0 /* _F flag setting */ +#define AUTH_REQUEST_GROUP_ERROR 1 /* _F flag setting */ -#define CURRENT_FRAGMENT_THRESHOLD (adapter->Mds.TxFragmentThreshold & ~0x1) -#define CURRENT_PREAMBLE_MODE psLOCAL->boShortPreamble?WLAN_PREAMBLE_TYPE_SHORT:WLAN_PREAMBLE_TYPE_LONG -#define CURRENT_TX_RATE_FOR_MNG adapter->sLocalPara.CurrentTxRateForMng -#define CURRENT_PROTECT_MECHANISM psLOCAL->boProtectMechanism -#define CURRENT_RTS_THRESHOLD adapter->Mds.TxRTSThreshold +#define CURRENT_FRAGMENT_THRESHOLD (adapter->Mds.TxFragmentThreshold & ~0x1) +#define CURRENT_PREAMBLE_MODE (psLOCAL->boShortPreamble ? WLAN_PREAMBLE_TYPE_SHORT : WLAN_PREAMBLE_TYPE_LONG) +#define CURRENT_TX_RATE_FOR_MNG (adapter->sLocalPara.CurrentTxRateForMng) +#define CURRENT_PROTECT_MECHANISM (psLOCAL->boProtectMechanism) +#define CURRENT_RTS_THRESHOLD (adapter->Mds.TxRTSThreshold) -#define MIB_GS_XMIT_OK_INC adapter->sLocalPara.GS_XMIT_OK++ -#define MIB_GS_RCV_OK_INC adapter->sLocalPara.GS_RCV_OK++ -#define MIB_GS_XMIT_ERROR_INC adapter->sLocalPara.GS_XMIT_ERROR +#define MIB_GS_XMIT_OK_INC (adapter->sLocalPara.GS_XMIT_OK++) +#define MIB_GS_RCV_OK_INC (adapter->sLocalPara.GS_RCV_OK++) +#define MIB_GS_XMIT_ERROR_INC (adapter->sLocalPara.GS_XMIT_ERROR) -//---------- TX ----------------------------------- +/* ---------- TX ----------------------------------- */ #define ETHERNET_TX_DESCRIPTORS MAX_USB_TX_BUFFER_NUMBER -//---------- RX ------------------------------------ -#define ETHERNET_RX_DESCRIPTORS 8 //It's not necessary to allocate more than 2 in sync indicate - -//================================================================ -// Configration default value -//================================================================ -#define DEFAULT_MULTICASTLISTMAX 32 // standard -#define DEFAULT_TX_BURSTLENGTH 3 // 32 Longwords -#define DEFAULT_RX_BURSTLENGTH 3 // 32 Longwords -#define DEFAULT_TX_THRESHOLD 0 // Full Packet -#define DEFAULT_RX_THRESHOLD 0 // Full Packet -#define DEFAULT_MAXTXRATE 6 // 11 Mbps (Long) -#define DEFAULT_CHANNEL 3 // Chennel 3 -#define DEFAULT_RTSThreshold 2347 // Disable RTS -//#define DEFAULT_PME 1 // Enable -#define DEFAULT_PME 0 // Disable -#define DEFAULT_SIFSTIME 10 -#define DEFAULT_ACKTIME_1ML 304 // 148+44+112 911220 by LCC -#define DEFAULT_ACKTIME_2ML 248 // 148+44+56 911220 by LCC -#define DEFAULT_FRAGMENT_THRESHOLD 2346 // No fragment -#define DEFAULT_PREAMBLE_LENGTH 72 +/* ---------- RX ----------------------------------- */ +#define ETHERNET_RX_DESCRIPTORS 8 /* It's not necessary to allocate more than 2 in sync indicate */ + +/* + * ================================================================ + * Configration default value + * ================================================================ + */ +#define DEFAULT_MULTICASTLISTMAX 32 /* standard */ +#define DEFAULT_TX_BURSTLENGTH 3 /* 32 Longwords */ +#define DEFAULT_RX_BURSTLENGTH 3 /* 32 Longwords */ +#define DEFAULT_TX_THRESHOLD 0 /* Full Packet */ +#define DEFAULT_RX_THRESHOLD 0 /* Full Packet */ +#define DEFAULT_MAXTXRATE 6 /* 11 Mbps (Long) */ +#define DEFAULT_CHANNEL 3 /* Chennel 3 */ +#define DEFAULT_RTSThreshold 2347 /* Disable RTS */ +#define DEFAULT_PME 0 /* Disable */ +#define DEFAULT_SIFSTIME 10 +#define DEFAULT_ACKTIME_1ML 304 /* 148 + 44 + 112 */ +#define DEFAULT_ACKTIME_2ML 248 /* 148 + 44 + 56 */ +#define DEFAULT_FRAGMENT_THRESHOLD 2346 /* No fragment */ +#define DEFAULT_PREAMBLE_LENGTH 72 #define DEFAULT_PLCPHEADERTIME_LENGTH 24 -/*------------------------------------------------------------------------ - 0.96 sec since time unit of the R03 for the current, W89C32 is about 60ns - instead of 960 ns. This shall be fixed in the future W89C32 - -------------------------------------------------------------------------*/ -#define DEFAULT_MAX_RECEIVE_TIME 16440000 +/* + * ------------------------------------------------------------------------ + * 0.96 sec since time unit of the R03 for the current, W89C32 is about 60ns + * instead of 960 ns. This shall be fixed in the future W89C32 + * ------------------------------------------------------------------------- + */ +#define DEFAULT_MAX_RECEIVE_TIME 16440000 -#define RX_BUF_SIZE 2352 // 600 // For 301 must be multiple of 8 -#define MAX_RX_DESCRIPTORS 18 // Rx Layer 2 +#define RX_BUF_SIZE 2352 /* 600 - For 301 must be multiple of 8 */ +#define MAX_RX_DESCRIPTORS 18 /* Rx Layer 2 */ +/* For brand-new rx system */ +#define MDS_ID_IGNORE ETHERNET_RX_DESCRIPTORS -// For brand-new rx system -#define MDS_ID_IGNORE ETHERNET_RX_DESCRIPTORS - -// For Tx Packet status classify -#define PACKET_FREE_TO_USE 0 -#define PACKET_COME_FROM_NDIS 0x08 -#define PACKET_COME_FROM_MLME 0x80 -#define PACKET_SEND_COMPLETE 0xff +/* For Tx Packet status classify */ +#define PACKET_FREE_TO_USE 0 +#define PACKET_COME_FROM_NDIS 0x08 +#define PACKET_COME_FROM_MLME 0x80 +#define PACKET_SEND_COMPLETE 0xff struct wb35_mds { - // For Tx usage - u8 TxOwner[ ((MAX_USB_TX_BUFFER_NUMBER + 3) & ~0x03) ]; + /* For Tx usage */ + u8 TxOwner[((MAX_USB_TX_BUFFER_NUMBER + 3) & ~0x03)]; u8 *pTxBuffer; - u16 TxBufferSize[ ((MAX_USB_TX_BUFFER_NUMBER + 1) & ~0x01) ]; - u8 TxDesFrom[ ((MAX_USB_TX_DESCRIPTOR + 3) & ~0x03) ];//931130.4.u // 1: MLME 2: NDIS control 3: NDIS data - u8 TxCountInBuffer[ ((MAX_USB_TX_DESCRIPTOR + 3) & ~0x03) ]; // 20060928 + u16 TxBufferSize[((MAX_USB_TX_BUFFER_NUMBER + 1) & ~0x01)]; + u8 TxDesFrom[((MAX_USB_TX_DESCRIPTOR + 3) & ~0x03)];/* 1: MLME 2: NDIS control 3: NDIS data */ + u8 TxCountInBuffer[((MAX_USB_TX_DESCRIPTOR + 3) & ~0x03)]; - u8 TxFillIndex;//the next index of TxBuffer can be used - u8 TxDesIndex;//The next index of TxDes can be used - u8 ScanTxPause; //data Tx pause because the scanning is progressing, but probe request Tx won't. - u8 TxPause;//For pause the Mds_Tx modult + u8 TxFillIndex; /* the next index of TxBuffer can be used */ + u8 TxDesIndex; /* The next index of TxDes can be used */ + u8 ScanTxPause; /* data Tx pause because the scanning is progressing, but probe request Tx won't. */ + u8 TxPause; /*For pause the Mds_Tx modult */ - atomic_t TxThreadCount;//For thread counting 931130.4.v -//950301 delete due to HW -// atomic_t TxConcurrentCount;//931130.4.w + atomic_t TxThreadCount; /* For thread counting */ - u16 TxResult[ ((MAX_USB_TX_DESCRIPTOR + 1) & ~0x01) ];//Collect the sending result of Mpdu + u16 TxResult[((MAX_USB_TX_DESCRIPTOR + 1) & ~0x01)];/* Collect the sending result of Mpdu */ - u8 MicRedundant[8]; // For tmp use - u8 *MicWriteAddress[2]; //The start address to fill the Mic, use 2 point due to Mic maybe fragment + u8 MicRedundant[8]; /* For tmp use */ + u8 *MicWriteAddress[2]; /* The start address to fill the Mic, use 2 point due to Mic maybe fragment */ - u16 MicWriteSize[2]; //931130.4.x + u16 MicWriteSize[2]; - u16 MicAdd; // If want to add the Mic, this variable equal to 8 - u16 MicWriteIndex;//The number of MicWriteAddress 931130.4.y + u16 MicAdd; /* If want to add the Mic, this variable equal to 8 */ + u16 MicWriteIndex; /* The number of MicWriteAddress */ - u8 TxRate[ ((MAX_USB_TX_DESCRIPTOR+1)&~0x01) ][2]; // [0] current tx rate, [1] fall back rate - u8 TxInfo[ ((MAX_USB_TX_DESCRIPTOR+1)&~0x01) ]; //Store information for callback function + u8 TxRate[((MAX_USB_TX_DESCRIPTOR + 1) & ~0x01)][2]; /* [0] current tx rate, [1] fall back rate */ + u8 TxInfo[((MAX_USB_TX_DESCRIPTOR + 1) & ~0x01)]; /*Store information for callback function */ - //WKCHEN added for scanning mechanism - u8 TxToggle; //It is TRUE if there are tx activities in some time interval + /* for scanning mechanism */ + u8 TxToggle; /* It is TRUE if there are tx activities in some time interval */ u8 Reserved_[3]; - //---------- for Tx Parameter - u16 TxFragmentThreshold; // For frame body only + /* ---- for Tx Parameter */ + u16 TxFragmentThreshold; /* For frame body only */ u16 TxRTSThreshold; - u32 MaxReceiveTime;//911220.3 Add - - // depend on OS, - u32 MulticastListNo; - u32 PacketFilter; // Setting by NDIS, the current packet filter in use. - u8 MulticastAddressesArray[DEFAULT_MULTICASTLISTMAX][MAC_ADDR_LENGTH]; + u32 MaxReceiveTime; - //COUNTERMEASURE - u8 bMICfailCount; - u8 boCounterMeasureBlock; - u8 reserved_4[2]; + /* depend on OS, */ + u32 MulticastListNo; + u32 PacketFilter; /* Setting by NDIS, the current packet filter in use. */ + u8 MulticastAddressesArray[DEFAULT_MULTICASTLISTMAX][MAC_ADDR_LENGTH]; - u32 TxTsc; // 20060214 - u32 TxTsc_2; // 20060214 + /* COUNTERMEASURE */ + u8 bMICfailCount; + u8 boCounterMeasureBlock; + u8 reserved_4[2]; + u32 TxTsc; + u32 TxTsc_2; }; #endif -- cgit v1.2.3 From 1a48ba148c45052efc2e1505e28198b725a23e95 Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Thu, 18 Mar 2010 16:45:06 +0100 Subject: Staging: winbond: mlme_s.h Coding style fixes I fixed all problems found by checkpatch.pl except typedefs. Signed-off-by: Lars Lindley Acked-by: Pekka Enberg Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mlme_s.h | 288 +++++++++++++++++++-------------------- 1 file changed, 140 insertions(+), 148 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/mlme_s.h b/drivers/staging/winbond/mlme_s.h index 1217a1c025e5..a7ef3c78022e 100644 --- a/drivers/staging/winbond/mlme_s.h +++ b/drivers/staging/winbond/mlme_s.h @@ -7,28 +7,29 @@ #include "mac_structures.h" #include "mds_s.h" -//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// Mlme.h -// Define the related definitions of MLME module -// history -- 01/14/03' created -// -//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -#define AUTH_REJECT_REASON_CHALLENGE_FAIL 1 - -//====== the state of MLME module -#define INACTIVE 0x0 -#define IDLE_SCAN 0x1 - -//====== the state of MLME/ESS module -#define STATE_1 0x2 -#define AUTH_REQ 0x3 -#define AUTH_WEP 0x4 -#define STATE_2 0x5 -#define ASSOC_REQ 0x6 -#define STATE_3 0x7 - -//====== the state of MLME/IBSS module +/* + * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * Mlme.h + * Define the related definitions of MLME module + * + * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + */ + +#define AUTH_REJECT_REASON_CHALLENGE_FAIL 1 + +/* the state of MLME module */ +#define INACTIVE 0x0 +#define IDLE_SCAN 0x1 + +/* the state of MLME/ESS module */ +#define STATE_1 0x2 +#define AUTH_REQ 0x3 +#define AUTH_WEP 0x4 +#define STATE_2 0x5 +#define ASSOC_REQ 0x6 +#define STATE_3 0x7 + +/* the state of MLME/IBSS module */ #define IBSS_JOIN_SYNC 0x8 #define IBSS_AUTH_REQ 0x9 #define IBSS_AUTH_CHANLGE 0xa @@ -38,159 +39,150 @@ -//========================================= -//depend on D5C(MAC timing control 03 register): MaxTxMSDULifeTime default 0x80000us -#define AUTH_FAIL_TIMEOUT 550 -#define ASSOC_FAIL_TIMEOUT 550 +/* + * ========================================= + * depend on D5C(MAC timing control 03 register): + * MaxTxMSDULifeTime default 0x80000us + */ +#define AUTH_FAIL_TIMEOUT 550 +#define ASSOC_FAIL_TIMEOUT 550 #define REASSOC_FAIL_TIMEOUT 550 - - -// -// MLME task global CONSTANTS, STRUCTURE, variables -// - - -///////////////////////////////////////////////////////////// -// enum_ResultCode -- -// Result code returned from MLME to SME. -// -///////////////////////////////////////////////////////////// -// PD43 20030829 Modifiled -//#define SUCCESS 0 -#define MLME_SUCCESS 0 //follow spec. -#define INVALID_PARAMETERS 1 //Not following spec. -#define NOT_SUPPPORTED 2 -#define TIMEOUT 3 -#define TOO_MANY_SIMULTANEOUS_REQUESTS 4 -#define REFUSED 5 -#define BSS_ALREADY_STARTED_OR_JOINED 6 -#define TRANSMIT_FRAME_FAIL 7 -#define NO_BSS_FOUND 8 -#define RETRY 9 -#define GIVE_UP 10 - - -#define OPEN_AUTH 0 -#define SHARE_AUTH 1 -#define ANY_AUTH 2 -#define WPA_AUTH 3 //for WPA -#define WPAPSK_AUTH 4 -#define WPANONE_AUTH 5 -///////////////////////////////////////////// added by ws 04/19/04 +/* MLME task global CONSTANTS, STRUCTURE, variables */ + +/* ========================================= + * enum_ResultCode -- + * Result code returned from MLME to SME. + * ========================================= + */ +#define MLME_SUCCESS 0 /* follow spec. */ +#define INVALID_PARAMETERS 1 /* Not following spec. */ +#define NOT_SUPPPORTED 2 +#define TIMEOUT 3 +#define TOO_MANY_SIMULTANEOUS_REQUESTS 4 +#define REFUSED 5 +#define BSS_ALREADY_STARTED_OR_JOINED 6 +#define TRANSMIT_FRAME_FAIL 7 +#define NO_BSS_FOUND 8 +#define RETRY 9 +#define GIVE_UP 10 + + +#define OPEN_AUTH 0 +#define SHARE_AUTH 1 +#define ANY_AUTH 2 +#define WPA_AUTH 3 /* for WPA */ +#define WPAPSK_AUTH 4 +#define WPANONE_AUTH 5 #ifdef _WPA2_ -#define WPA2_AUTH 6//for WPA2 -#define WPA2PSK_AUTH 7 -#endif //end def _WPA2_ - -////////////////////////////////////////////////////////////////// -//define the msg type of MLME module -////////////////////////////////////////////////////////////////// -//-------------------------------------------------------- -//from SME - -#define MLMEMSG_AUTH_REQ 0x0b -#define MLMEMSG_DEAUTH_REQ 0x0c -#define MLMEMSG_ASSOC_REQ 0x0d -#define MLMEMSG_REASSOC_REQ 0x0e -#define MLMEMSG_DISASSOC_REQ 0x0f -#define MLMEMSG_START_IBSS_REQ 0x10 -#define MLMEMSG_IBSS_NET_CFM 0x11 - -//from RX : -#define MLMEMSG_RCV_MLMEFRAME 0x20 -#define MLMEMSG_RCV_ASSOCRSP 0x22 -#define MLMEMSG_RCV_REASSOCRSP 0x24 -#define MLMEMSG_RCV_DISASSOC 0x2b -#define MLMEMSG_RCV_AUTH 0x2c -#define MLMEMSG_RCV_DEAUTH 0x2d - - -//from TX callback -#define MLMEMSG_TX_CALLBACK 0x40 -#define MLMEMSG_ASSOCREQ_CALLBACK 0x41 -#define MLMEMSG_REASSOCREQ_CALLBACK 0x43 -#define MLMEMSG_DISASSOC_CALLBACK 0x4a -#define MLMEMSG_AUTH_CALLBACK 0x4c -#define MLMEMSG_DEAUTH_CALLBACK 0x4d - -//#define MLMEMSG_JOIN_FAIL 4 -//#define MLMEMSG_AUTHEN_FAIL 18 -#define MLMEMSG_TIMEOUT 0x50 - -/////////////////////////////////////////////////////////////////////////// -//Global data structures -#define MAX_NUM_TX_MMPDU 2 -#define MAX_MMPDU_SIZE 1512 -#define MAX_NUM_RX_MMPDU 6 - - -/////////////////////////////////////////////////////////////////////////// -//MACRO -#define boMLME_InactiveState(_AA_) (_AA_->wState==INACTIVE) -#define boMLME_IdleScanState(_BB_) (_BB_->wState==IDLE_SCAN) -#define boMLME_FoundSTAinfo(_CC_) (_CC_->wState>=IDLE_SCAN) - -typedef struct _MLME_FRAME -{ - //NDIS_PACKET MLME_Packet; - s8 * pMMPDU; - u16 len; - u8 DataType; - u8 IsInUsed; +#define WPA2_AUTH 6 /* for WPA2 */ +#define WPA2PSK_AUTH 7 +#endif /* end def _WPA2_ */ + +/* + * ========================================= + * define the msg type of MLME module + * ========================================= + */ + +/* from SME */ +#define MLMEMSG_AUTH_REQ 0x0b +#define MLMEMSG_DEAUTH_REQ 0x0c +#define MLMEMSG_ASSOC_REQ 0x0d +#define MLMEMSG_REASSOC_REQ 0x0e +#define MLMEMSG_DISASSOC_REQ 0x0f +#define MLMEMSG_START_IBSS_REQ 0x10 +#define MLMEMSG_IBSS_NET_CFM 0x11 + +/* from RX */ +#define MLMEMSG_RCV_MLMEFRAME 0x20 +#define MLMEMSG_RCV_ASSOCRSP 0x22 +#define MLMEMSG_RCV_REASSOCRSP 0x24 +#define MLMEMSG_RCV_DISASSOC 0x2b +#define MLMEMSG_RCV_AUTH 0x2c +#define MLMEMSG_RCV_DEAUTH 0x2d + + +/* from TX callback */ +#define MLMEMSG_TX_CALLBACK 0x40 +#define MLMEMSG_ASSOCREQ_CALLBACK 0x41 +#define MLMEMSG_REASSOCREQ_CALLBACK 0x43 +#define MLMEMSG_DISASSOC_CALLBACK 0x4a +#define MLMEMSG_AUTH_CALLBACK 0x4c +#define MLMEMSG_DEAUTH_CALLBACK 0x4d + +#define MLMEMSG_TIMEOUT 0x50 + +/* + * ============================================== + * Global data structures + * ============================================== + */ +#define MAX_NUM_TX_MMPDU 2 +#define MAX_MMPDU_SIZE 1512 +#define MAX_NUM_RX_MMPDU 6 + + +/* + * ============================================== + * MACRO + * ============================================== + */ +#define boMLME_InactiveState(_AA_) (_AA_->wState == INACTIVE) +#define boMLME_IdleScanState(_BB_) (_BB_->wState == IDLE_SCAN) +#define boMLME_FoundSTAinfo(_CC_) (_CC_->wState >= IDLE_SCAN) + +typedef struct _MLME_FRAME { + s8 *pMMPDU; + u16 len; + u8 DataType; + u8 IsInUsed; spinlock_t MLMESpinLock; - u8 TxMMPDU[MAX_NUM_TX_MMPDU][MAX_MMPDU_SIZE]; - u8 TxMMPDUInUse[ (MAX_NUM_TX_MMPDU+3) & ~0x03 ]; + u8 TxMMPDU[MAX_NUM_TX_MMPDU][MAX_MMPDU_SIZE]; + u8 TxMMPDUInUse[(MAX_NUM_TX_MMPDU + 3) & ~0x03]; u16 wNumTxMMPDU; u16 wNumTxMMPDUDiscarded; - u8 RxMMPDU[MAX_NUM_RX_MMPDU][MAX_MMPDU_SIZE]; - u8 SaveRxBufSlotInUse[ (MAX_NUM_RX_MMPDU+3) & ~0x03 ]; + u8 RxMMPDU[MAX_NUM_RX_MMPDU][MAX_MMPDU_SIZE]; + u8 SaveRxBufSlotInUse[(MAX_NUM_RX_MMPDU + 3) & ~0x03]; u16 wNumRxMMPDU; u16 wNumRxMMPDUDiscarded; - u16 wNumRxMMPDUInMLME; // Number of the Rx MMPDU - u16 reserved_1; // in MLME. - // excluding the discarded + u16 wNumRxMMPDUInMLME; /* Number of the Rx MMPDU */ + u16 reserved_1; /* in MLME. */ + /* excluding the discarded */ } MLME_FRAME, *psMLME_FRAME; typedef struct _AUTHREQ { - u8 peerMACaddr[MAC_ADDR_LENGTH]; - u16 wAuthAlgorithm; - + u8 peerMACaddr[MAC_ADDR_LENGTH]; + u16 wAuthAlgorithm; } MLME_AUTHREQ_PARA, *psMLME_AUTHREQ_PARA; typedef struct _ASSOCREQ { - u8 PeerSTAAddr[MAC_ADDR_LENGTH]; - u16 CapabilityInfo; - u16 ListenInterval; - -}__attribute__ ((packed)) MLME_ASSOCREQ_PARA, *psMLME_ASSOCREQ_PARA; + u8 PeerSTAAddr[MAC_ADDR_LENGTH]; + u16 CapabilityInfo; + u16 ListenInterval; +} __attribute__ ((packed)) MLME_ASSOCREQ_PARA, *psMLME_ASSOCREQ_PARA; typedef struct _REASSOCREQ { - u8 NewAPAddr[MAC_ADDR_LENGTH]; - u16 CapabilityInfo; - u16 ListenInterval; - -}__attribute__ ((packed)) MLME_REASSOCREQ_PARA, *psMLME_REASSOCREQ_PARA; + u8 NewAPAddr[MAC_ADDR_LENGTH]; + u16 CapabilityInfo; + u16 ListenInterval; +} __attribute__ ((packed)) MLME_REASSOCREQ_PARA, *psMLME_REASSOCREQ_PARA; typedef struct _MLMECALLBACK { - - u8 *psFramePtr; - u8 bResult; - + u8 *psFramePtr; + u8 bResult; } MLME_TXCALLBACK, *psMLME_TXCALLBACK; -typedef struct _RXDATA -{ +typedef struct _RXDATA { s32 FrameLength; - u8 __attribute__ ((packed)) *pbFramePtr; - -}__attribute__ ((packed)) RXDATA, *psRXDATA; + u8 __attribute__ ((packed)) *pbFramePtr; +} __attribute__ ((packed)) RXDATA, *psRXDATA; #endif -- cgit v1.2.3 From 649f0650acae35ff301b81159820bf8eecf7f68e Mon Sep 17 00:00:00 2001 From: Sankar P Date: Sat, 20 Mar 2010 02:10:59 +0530 Subject: Staging: winbond: Convert typedef struct _PMKID to struct pmkid This patch converts the definition typedef struct _PMKID to struct pmkid and also the part where the typedef was used. Signed-off-by: Sankar P Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mac_structures.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/mac_structures.h b/drivers/staging/winbond/mac_structures.h index 0d1619601c0b..350299026d48 100644 --- a/drivers/staging/winbond/mac_structures.h +++ b/drivers/staging/winbond/mac_structures.h @@ -505,10 +505,10 @@ struct RSN_Capability_Element }__attribute__ ((packed)) ; #ifdef _WPA2_ -typedef struct _PMKID +struct pmkid { u8 pValue[16]; -}PMKID; +}; struct WPA2_RSN_Information_Element { @@ -531,7 +531,7 @@ struct WPA2_RSN_Auth_Sub_Information_Element struct PMKID_Information_Element { u16 PMKID_Count; - PMKID pmkid [16] ; + struct pmkid pmkid[16]; }__attribute__ ((packed)); #endif //enddef _WPA2_ -- cgit v1.2.3 From ef1566e2bb23bc4d7384c27fe973f4d16c2f3c25 Mon Sep 17 00:00:00 2001 From: Sankar P Date: Sat, 20 Mar 2010 02:11:00 +0530 Subject: Staging: winbond: Remove unused enum enum_PowerManagementMode Signed-off-by: Sankar P Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mac_structures.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/mac_structures.h b/drivers/staging/winbond/mac_structures.h index 350299026d48..44c1aaf211af 100644 --- a/drivers/staging/winbond/mac_structures.h +++ b/drivers/staging/winbond/mac_structures.h @@ -116,13 +116,6 @@ #define WLAN_MAX_PAIRWISE_CIPHER_SUITE_COUNT ((u16) 6) #define WLAN_MAX_AUTH_KEY_MGT_SUITE_LIST_COUNT ((u16) 2) -//======================================================== -typedef enum enum_PowerManagementMode -{ - ACTIVE = 0, - POWER_SAVE -} WB_PM_Mode, *PWB_PM_MODE; - //=================================================================== // Reason Code (Table 18): indicate the reason of DisAssoc, DeAuthen // length of ReasonCode is 2 Octs. -- cgit v1.2.3 From 2de975336fbcf5a7b76703b00276668d0f932ebe Mon Sep 17 00:00:00 2001 From: Sankar P Date: Sat, 20 Mar 2010 02:11:01 +0530 Subject: Staging: winbond: Convert typedef struct _STRUCT_SELECTOR This patch converts the declaration typedef struct _STRUCT_SELECTOR to struct struct_selector and also the places where it was used. Signed-off-by: Sankar P Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mac_structures.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/mac_structures.h b/drivers/staging/winbond/mac_structures.h index 44c1aaf211af..f24dbb955bfe 100644 --- a/drivers/staging/winbond/mac_structures.h +++ b/drivers/staging/winbond/mac_structures.h @@ -436,7 +436,7 @@ struct Extended_Supported_Rates_Element #define OUI_CIPHER_CCMP 0x04 #define OUI_CIPHER_WEP_104 0x05 -typedef struct _SUITE_SELECTOR_ +struct suite_selector { union { @@ -447,23 +447,23 @@ typedef struct _SUITE_SELECTOR_ u8 Type; }SuitSelector; }; -}SUITE_SELECTOR; +}; //-- WPA -- struct RSN_Information_Element { u8 Element_ID; u8 Length; - SUITE_SELECTOR OuiWPAAdditional;//WPA version 2.0 additional field, and should be 00:50:F2:01 + struct suite_selector OuiWPAAdditional; /* WPA version 2.0 additional field, and should be 00:50:F2:01 */ u16 Version; - SUITE_SELECTOR GroupKeySuite; + struct suite_selector GroupKeySuite; u16 PairwiseKeySuiteCount; - SUITE_SELECTOR PairwiseKeySuite[1]; + struct suite_selector PairwiseKeySuite[1]; }__attribute__ ((packed)); struct RSN_Auth_Sub_Information_Element { u16 AuthKeyMngtSuiteCount; - SUITE_SELECTOR AuthKeyMngtSuite[1]; + struct suite_selector AuthKeyMngtSuite[1]; }__attribute__ ((packed)); //-- WPA2 -- @@ -508,16 +508,16 @@ struct WPA2_RSN_Information_Element u8 Element_ID; u8 Length; u16 Version; - SUITE_SELECTOR GroupKeySuite; + struct suite_selector GroupKeySuite; u16 PairwiseKeySuiteCount; - SUITE_SELECTOR PairwiseKeySuite[1]; + struct suite_selector PairwiseKeySuite[1]; }__attribute__ ((packed)); struct WPA2_RSN_Auth_Sub_Information_Element { u16 AuthKeyMngtSuiteCount; - SUITE_SELECTOR AuthKeyMngtSuite[1]; + struct suite_selector AuthKeyMngtSuite[1]; }__attribute__ ((packed)); -- cgit v1.2.3 From 20dbe695c37e832ad48352ebfdd6234086620608 Mon Sep 17 00:00:00 2001 From: Sankar P Date: Sat, 20 Mar 2010 02:11:02 +0530 Subject: Staging: winbond: Remove typedef for standard types Remove the typedef named "fixed" used for the standard type s32 Signed-off-by: Sankar P Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/phy_calibration.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/phy_calibration.c b/drivers/staging/winbond/phy_calibration.c index 8c56962ab80c..78935865df19 100644 --- a/drivers/staging/winbond/phy_calibration.c +++ b/drivers/staging/winbond/phy_calibration.c @@ -25,10 +25,7 @@ #define FIXED(X) ((s32)((X) * 32768.0)) #define DEG2RAD(X) 0.017453 * (X) -/****************** LOCAL TYPE DEFINITION SECTION ***************************/ -typedef s32 fixed; /* 16.16 fixed-point */ - -static const fixed Angles[]= +static const s32 Angles[] = { FIXED(DEG2RAD(45.0)), FIXED(DEG2RAD(26.565)), FIXED(DEG2RAD(14.0362)), FIXED(DEG2RAD(7.12502)), FIXED(DEG2RAD(3.57633)), FIXED(DEG2RAD(1.78991)), @@ -300,7 +297,7 @@ u32 _sqrt(u32 sqsum) /****************************************************************************/ void _sin_cos(s32 angle, s32 *sin, s32 *cos) { - fixed X, Y, TargetAngle, CurrAngle; + s32 X, Y, TargetAngle, CurrAngle; unsigned Step; X=FIXED(AG_CONST); // AG_CONST * cos(0) @@ -310,7 +307,7 @@ void _sin_cos(s32 angle, s32 *sin, s32 *cos) for (Step=0; Step < 12; Step++) { - fixed NewX; + s32 NewX; if(TargetAngle > CurrAngle) { -- cgit v1.2.3 From 75df20e0385198e80439bfc33c001fcecf094622 Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Fri, 19 Mar 2010 21:43:25 +0100 Subject: Staging: winbond: mto.h Coding style fixes I fixed all problems reported by checkpatch.pl except for a couple of long lines. I also removed version comments and removed "commented away" code. Signed-off-by: Lars Lindley Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mto.h | 179 +++++++++++++++++++----------------------- 1 file changed, 82 insertions(+), 97 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/mto.h b/drivers/staging/winbond/mto.h index fb4781d5781b..a0f659cf99ff 100644 --- a/drivers/staging/winbond/mto.h +++ b/drivers/staging/winbond/mto.h @@ -1,13 +1,10 @@ -//================================================================== -// MTO.H -// -// Revision history -//================================= -// 20030110 UN20 Pete Chao -// Initial Release -// -// Copyright (c) 2003 Winbond Electronics Corp. All rights reserved. -//================================================================== +/* + * ================================================================== + * MTO.H + * + * Copyright (c) 2003 Winbond Electronics Corp. All rights reserved. + * ================================================================== + */ #ifndef __MTO_H__ #define __MTO_H__ @@ -15,115 +12,104 @@ struct wbsoft_priv; -// LA20040210_DTO kevin -//#define MTO_PREAMBLE_LONG 0 -//#define MTO_PREAMBLE_SHORT 1 #define MTO_PREAMBLE_LONG WLAN_PREAMBLE_TYPE_LONG #define MTO_PREAMBLE_SHORT WLAN_PREAMBLE_TYPE_SHORT -//============================================================================ -// struct _MTOParameters -- -// -// Defines the parameters used in the MAC Throughput Optimization algorithm -//============================================================================ +/* Defines the parameters used in the MAC Throughput Optimization algorithm */ struct wb35_mto_params { - //--------- wkchen added ------------- - u32 TxFlowCount; //to judge what kind the tx flow(sparse or busy) is - //------------------------------------------------ + u32 TxFlowCount; /* to judge what kind the tx flow(sparse or busy) is */ - //--------- DTO threshold parameters ------------- - u16 DTO_PeriodicCheckCycle; - u16 DTO_RssiThForAntDiv; + /* --------- DTO threshold parameters ------------- */ + u16 DTO_PeriodicCheckCycle; + u16 DTO_RssiThForAntDiv; - u16 DTO_TxCountThForCalcNewRate; - u16 DTO_TxRateIncTh; + u16 DTO_TxCountThForCalcNewRate; + u16 DTO_TxRateIncTh; - u16 DTO_TxRateDecTh; - u16 DTO_TxRateEqTh; + u16 DTO_TxRateDecTh; + u16 DTO_TxRateEqTh; - u16 DTO_TxRateBackOff; - u16 DTO_TxRetryRateReduce; + u16 DTO_TxRateBackOff; + u16 DTO_TxRetryRateReduce; - u16 DTO_TxPowerIndex; //0 ~ 31 - u16 reserved_1; - //------------------------------------------------ + u16 DTO_TxPowerIndex; /* 0 ~ 31 */ + u16 reserved_1; + /* ------------------------------------------------ */ - u8 PowerChangeEnable; - u8 AntDiversityEnable; - u8 CCA_Mode; - u8 CCA_Mode_Setup; - u8 Preamble_Type; - u8 PreambleChangeEnable; + u8 PowerChangeEnable; + u8 AntDiversityEnable; + u8 CCA_Mode; + u8 CCA_Mode_Setup; + u8 Preamble_Type; + u8 PreambleChangeEnable; - u8 DataRateLevel; - u8 DataRateChangeEnable; - u8 FragThresholdLevel; - u8 FragThresholdChangeEnable; + u8 DataRateLevel; + u8 DataRateChangeEnable; + u8 FragThresholdLevel; + u8 FragThresholdChangeEnable; - u16 RTSThreshold; - u16 RTSThreshold_Setup; + u16 RTSThreshold; + u16 RTSThreshold_Setup; - u32 AvgIdleSlot; - u32 Pr_Interf; - u32 AvgGapBtwnInterf; + u32 AvgIdleSlot; + u32 Pr_Interf; + u32 AvgGapBtwnInterf; - u8 RTSChangeEnable; - u8 Ant_sel; - u8 aging_timeout; - u8 reserved_2; + u8 RTSChangeEnable; + u8 Ant_sel; + u8 aging_timeout; + u8 reserved_2; - u32 Cnt_Ant[2]; - u32 SQ_Ant[2]; + u32 Cnt_Ant[2]; + u32 SQ_Ant[2]; -// 20040510 remove from globe vairable - u8 FallbackRateLevel; - u8 OfdmRateLevel; + u8 FallbackRateLevel; + u8 OfdmRateLevel; - u8 RatePolicy; - u8 reserved_3[3]; - - // For RSSI turning - s32 RSSI_high; - s32 RSSI_low; + u8 RatePolicy; + u8 reserved_3[3]; + /* For RSSI turning */ + s32 RSSI_high; + s32 RSSI_low; }; -#define MTO_DATA() (adapter->sMtoPara) -#define MTO_HAL() (&adapter->sHwData) -#define MTO_SET_PREAMBLE_TYPE(x) // 20040511 Turbo mark LM_PREAMBLE_TYPE(&pcore_data->lm_data) = (x) -#define MTO_ENABLE (adapter->sLocalPara.TxRateMode == RATE_AUTO) -#define MTO_TXPOWER_FROM_EEPROM (adapter->sHwData.PowerIndexFromEEPROM) -#define LOCAL_ANTENNA_NO() (adapter->sLocalPara.bAntennaNo) -#define LOCAL_IS_CONNECTED() (adapter->sLocalPara.wConnectedSTAindex != 0) -#define MTO_INITTXRATE_MODE (adapter->sHwData.SoftwareSet&0x2) //bit 1 +#define MTO_DATA() (adapter->sMtoPara) +#define MTO_HAL() (&adapter->sHwData) +#define MTO_SET_PREAMBLE_TYPE(x) /* Turbo mark LM_PREAMBLE_TYPE(&pcore_data->lm_data) = (x) */ +#define MTO_ENABLE (adapter->sLocalPara.TxRateMode == RATE_AUTO) +#define MTO_TXPOWER_FROM_EEPROM (adapter->sHwData.PowerIndexFromEEPROM) +#define LOCAL_ANTENNA_NO() (adapter->sLocalPara.bAntennaNo) +#define LOCAL_IS_CONNECTED() (adapter->sLocalPara.wConnectedSTAindex != 0) +#define MTO_INITTXRATE_MODE (adapter->sHwData.SoftwareSet&0x2) /* bit 1 */ -#define MTO_POWER_CHANGE_ENABLE() MTO_DATA().PowerChangeEnable -#define MTO_CCA_MODE() MTO_DATA().CCA_Mode -#define MTO_CCA_MODE_SETUP() MTO_DATA().CCA_Mode_Setup -#define MTO_PREAMBLE_TYPE() MTO_DATA().Preamble_Type -#define MTO_PREAMBLE_CHANGE_ENABLE() MTO_DATA().PreambleChangeEnable +#define MTO_POWER_CHANGE_ENABLE() MTO_DATA().PowerChangeEnable +#define MTO_CCA_MODE() MTO_DATA().CCA_Mode +#define MTO_CCA_MODE_SETUP() MTO_DATA().CCA_Mode_Setup +#define MTO_PREAMBLE_TYPE() MTO_DATA().Preamble_Type +#define MTO_PREAMBLE_CHANGE_ENABLE() MTO_DATA().PreambleChangeEnable -#define MTO_RATE_LEVEL() MTO_DATA().DataRateLevel +#define MTO_RATE_LEVEL() MTO_DATA().DataRateLevel #define MTO_OFDM_RATE_LEVEL() MTO_DATA().OfdmRateLevel -#define MTO_RATE_CHANGE_ENABLE() MTO_DATA().DataRateChangeEnable -#define MTO_FRAG_TH_LEVEL() MTO_DATA().FragThresholdLevel -#define MTO_FRAG_CHANGE_ENABLE() MTO_DATA().FragThresholdChangeEnable -#define MTO_RTS_THRESHOLD() MTO_DATA().RTSThreshold -#define MTO_RTS_CHANGE_ENABLE() MTO_DATA().RTSChangeEnable -#define MTO_RTS_THRESHOLD_SETUP() MTO_DATA().RTSThreshold_Setup +#define MTO_RATE_CHANGE_ENABLE() MTO_DATA().DataRateChangeEnable +#define MTO_FRAG_TH_LEVEL() MTO_DATA().FragThresholdLevel +#define MTO_FRAG_CHANGE_ENABLE() MTO_DATA().FragThresholdChangeEnable +#define MTO_RTS_THRESHOLD() MTO_DATA().RTSThreshold +#define MTO_RTS_CHANGE_ENABLE() MTO_DATA().RTSChangeEnable +#define MTO_RTS_THRESHOLD_SETUP() MTO_DATA().RTSThreshold_Setup -#define MTO_AVG_IDLE_SLOT() MTO_DATA().AvgIdleSlot -#define MTO_PR_INTERF() MTO_DATA().Pr_Interf -#define MTO_AVG_GAP_BTWN_INTERF() MTO_DATA().AvgGapBtwnInterf +#define MTO_AVG_IDLE_SLOT() MTO_DATA().AvgIdleSlot +#define MTO_PR_INTERF() MTO_DATA().Pr_Interf +#define MTO_AVG_GAP_BTWN_INTERF() MTO_DATA().AvgGapBtwnInterf -#define MTO_CNT_ANT(x) MTO_DATA().Cnt_Ant[(x)] -#define MTO_SQ_ANT(x) MTO_DATA().SQ_Ant[(x)] -#define MTO_AGING_TIMEOUT() MTO_DATA().aging_timeout +#define MTO_CNT_ANT(x) MTO_DATA().Cnt_Ant[(x)] +#define MTO_SQ_ANT(x) MTO_DATA().SQ_Ant[(x)] +#define MTO_AGING_TIMEOUT() MTO_DATA().aging_timeout +#define MTO_TXFLOWCOUNT() MTO_DATA().TxFlowCount -#define MTO_TXFLOWCOUNT() MTO_DATA().TxFlowCount -//--------- DTO threshold parameters ------------- +/* --------- DTO threshold parameters ------------- */ #define MTOPARA_PERIODIC_CHECK_CYCLE() MTO_DATA().DTO_PeriodicCheckCycle #define MTOPARA_RSSI_TH_FOR_ANTDIV() MTO_DATA().DTO_RssiThForAntDiv #define MTOPARA_TXCOUNT_TH_FOR_CALC_RATE() MTO_DATA().DTO_TxCountThForCalcNewRate @@ -133,13 +119,13 @@ struct wb35_mto_params { #define MTOPARA_TXRATE_BACKOFF() MTO_DATA().DTO_TxRateBackOff #define MTOPARA_TXRETRYRATE_REDUCE() MTO_DATA().DTO_TxRetryRateReduce #define MTOPARA_TXPOWER_INDEX() MTO_DATA().DTO_TxPowerIndex -//------------------------------------------------ +/* ------------------------------------------------ */ -extern u16 MTO_Frag_Th_Tbl[]; +extern u16 MTO_Frag_Th_Tbl[]; -#define MTO_DATA_RATE() MTO_Data_Rate_Tbl[MTO_RATE_LEVEL()] -#define MTO_FRAG_TH() MTO_Frag_Th_Tbl[MTO_FRAG_TH_LEVEL()] +#define MTO_DATA_RATE() MTO_Data_Rate_Tbl[MTO_RATE_LEVEL()] +#define MTO_FRAG_TH() MTO_Frag_Th_Tbl[MTO_FRAG_TH_LEVEL()] extern void MTO_Init(struct wbsoft_priv *); extern void MTO_PeriodicTimerExpired(struct wbsoft_priv *); @@ -148,6 +134,5 @@ extern u8 MTO_GetTxRate(struct wbsoft_priv *adapter, u32 fpdu_len); extern u8 MTO_GetTxFallbackRate(struct wbsoft_priv *adapter); extern void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 t0, u8 index); -#endif //__MTO_H__ - +#endif /* __MTO_H__ */ -- cgit v1.2.3 From f9a4191cfbe86c5f96a6c6d340ab8bb65fa5c211 Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Sat, 20 Mar 2010 00:26:45 +0100 Subject: Staging: winbond: mto.c Coding style fixes I changed all things reported by checkpatch.pl except some long lines and the use of externs in a .c file. I also removed revision comments and "commented out" code. Signed-off-by: Lars Lindley Acked-by: Pekka Enberg Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mto.c | 299 ++++++++++++++++++------------------------ 1 file changed, 129 insertions(+), 170 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/mto.c b/drivers/staging/winbond/mto.c index 5e7fa1cd0aea..9cd212783d61 100644 --- a/drivers/staging/winbond/mto.c +++ b/drivers/staging/winbond/mto.c @@ -1,222 +1,181 @@ -//============================================================================ -// MTO.C - -// -// Description: -// MAC Throughput Optimization for W89C33 802.11g WLAN STA. -// -// The following MIB attributes or internal variables will be affected -// while the MTO is being executed: -// dot11FragmentationThreshold, -// dot11RTSThreshold, -// transmission rate and PLCP preamble type, -// CCA mode, -// antenna diversity. -// -// Revision history: -// -------------------------------------------------------------------------- -// 20031227 UN20 Pete Chao -// First draft -// 20031229 Turbo copy from PD43 -// 20040210 Kevin revised -// Copyright (c) 2003 Winbond Electronics Corp. All rights reserved. -//============================================================================ - -// LA20040210_DTO kevin +/* + * ============================================================================ + * MTO.C - + * + * Description: + * MAC Throughput Optimization for W89C33 802.11g WLAN STA. + * + * The following MIB attributes or internal variables will be affected + * while the MTO is being executed: + * dot11FragmentationThreshold, + * dot11RTSThreshold, + * transmission rate and PLCP preamble type, + * CCA mode, + * antenna diversity. + * + * Copyright (c) 2003 Winbond Electronics Corp. All rights reserved. + * ============================================================================ + */ + #include "sysdef.h" #include "sme_api.h" #include "wbhal_f.h" -// Declare SQ3 to rate and fragmentation threshold table -// Declare fragmentation thresholds table -#define MTO_MAX_FRAG_TH_LEVELS 5 -#define MTO_MAX_DATA_RATE_LEVELS 12 +/* Declare SQ3 to rate and fragmentation threshold table */ +/* Declare fragmentation thresholds table */ +#define MTO_MAX_FRAG_TH_LEVELS 5 +#define MTO_MAX_DATA_RATE_LEVELS 12 -u16 MTO_Frag_Th_Tbl[MTO_MAX_FRAG_TH_LEVELS] = -{ - 256, 384, 512, 768, 1536 +u16 MTO_Frag_Th_Tbl[MTO_MAX_FRAG_TH_LEVELS] = { + 256, 384, 512, 768, 1536 }; -// Declare data rate table -//The following table will be changed at anytime if the opration rate supported by AP don't -//match the table +/* + * Declare data rate table: + * The following table will be changed at anytime if the opration rate + * supported by AP don't match the table + */ static u8 MTO_Data_Rate_Tbl[MTO_MAX_DATA_RATE_LEVELS] = { - 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 + 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 }; -static int TotalTxPkt = 0; -static int TotalTxPktRetry = 0; -static int retryrate_rec[MTO_MAX_DATA_RATE_LEVELS];//this record the retry rate at different data rate +static int TotalTxPkt; +static int TotalTxPktRetry; +/* this record the retry rate at different data rate */ +static int retryrate_rec[MTO_MAX_DATA_RATE_LEVELS]; -static int PeriodTotalTxPkt = 0; -static int PeriodTotalTxPktRetry = 0; +static int PeriodTotalTxPkt; +static int PeriodTotalTxPktRetry; -static u8 boSparseTxTraffic = false; +static u8 boSparseTxTraffic; void MTO_Init(struct wbsoft_priv *adapter); void TxRateReductionCtrl(struct wbsoft_priv *adapter); -/** 1.1.31.1000 Turbo modify */ void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 t0, u8 index); void MTO_TxFailed(struct wbsoft_priv *adapter); void hal_get_dto_para(struct wbsoft_priv *adapter, char *buffer); -//=========================================================================== -// MTO_Init -- -// -// Description: -// Initialize MTO parameters. -// -// This function should be invoked during system initialization. -// -// Arguments: -// adapter - The pointer to the Miniport adapter Context -// -// Return Value: -// None -//============================================================================ +/* + * =========================================================================== + * MTO_Init -- + * + * Description: + * Initialize MTO parameters. + * + * This function should be invoked during system initialization. + * + * Arguments: + * adapter - The pointer to the Miniport adapter Context + * =========================================================================== + */ void MTO_Init(struct wbsoft_priv *adapter) { - int i; - - //[WKCHEN]MTO_CCA_MODE_SETUP()= (u8) hal_get_cca_mode(MTO_HAL()); - //[WKCHEN]MTO_CCA_MODE() = MTO_CCA_MODE_SETUP(); - - //MTO_PREAMBLE_TYPE() = MTO_PREAMBLE_LONG; - MTO_PREAMBLE_TYPE() = MTO_PREAMBLE_SHORT; // for test - - MTO_CNT_ANT(0) = 0; - MTO_CNT_ANT(1) = 0; - MTO_SQ_ANT(0) = 0; - MTO_SQ_ANT(1) = 0; - - MTO_AGING_TIMEOUT() = 0; - - // The following parameters should be initialized to the values set by user - // - //MTO_RATE_LEVEL() = 10; - MTO_RATE_LEVEL() = 0; - MTO_FRAG_TH_LEVEL() = 4; - /** 1.1.23.1000 Turbo modify from -1 to +1 - MTO_RTS_THRESHOLD() = MTO_FRAG_TH() - 1; - MTO_RTS_THRESHOLD_SETUP() = MTO_FRAG_TH() - 1; - */ - MTO_RTS_THRESHOLD() = MTO_FRAG_TH() + 1; - MTO_RTS_THRESHOLD_SETUP() = MTO_FRAG_TH() + 1; - // 1.1.23.1000 Turbo add for mto change preamble from 0 to 1 - MTO_RATE_CHANGE_ENABLE() = 1; - MTO_FRAG_CHANGE_ENABLE() = 0; // 1.1.29.1000 Turbo add don't support frag - //The default valud of ANTDIV_DEFAULT_ON will be decided by EEPROM - //#ifdef ANTDIV_DEFAULT_ON - //#else - //#endif - MTO_POWER_CHANGE_ENABLE() = 1; - MTO_PREAMBLE_CHANGE_ENABLE()= 1; - MTO_RTS_CHANGE_ENABLE() = 0; // 1.1.29.1000 Turbo add don't support frag - // 20040512 Turbo add - //old_antenna[0] = 1; - //old_antenna[1] = 0; - //old_antenna[2] = 1; - //old_antenna[3] = 0; - for (i=0;iphy_type) - { - case RF_AIROHA_2230: - case RF_AIROHA_2230S: // 20060420 Add this - MTOPARA_TXPOWER_INDEX() = 46; // MAX-8 // @@ Only for AL 2230 - break; - case RF_AIROHA_7230: - MTOPARA_TXPOWER_INDEX() = 49; - break; - case RF_WB_242: - MTOPARA_TXPOWER_INDEX() = 10; - break; - case RF_WB_242_1: - MTOPARA_TXPOWER_INDEX() = 24; // ->10 20060316.1 modify - break; + /* --------- DTO threshold parameters ------------- */ + MTOPARA_PERIODIC_CHECK_CYCLE() = 10; + MTOPARA_RSSI_TH_FOR_ANTDIV() = 10; + MTOPARA_TXCOUNT_TH_FOR_CALC_RATE() = 50; + MTOPARA_TXRATE_INC_TH() = 10; + MTOPARA_TXRATE_DEC_TH() = 30; + MTOPARA_TXRATE_EQ_TH() = 40; + MTOPARA_TXRATE_BACKOFF() = 12; + MTOPARA_TXRETRYRATE_REDUCE() = 6; + if (MTO_TXPOWER_FROM_EEPROM == 0xff) { + switch (MTO_HAL()->phy_type) { + case RF_AIROHA_2230: + case RF_AIROHA_2230S: + MTOPARA_TXPOWER_INDEX() = 46; /* MAX-8 @@ Only for AL 2230 */ + break; + case RF_AIROHA_7230: + MTOPARA_TXPOWER_INDEX() = 49; + break; + case RF_WB_242: + MTOPARA_TXPOWER_INDEX() = 10; + break; + case RF_WB_242_1: + MTOPARA_TXPOWER_INDEX() = 24; + break; } - } - else //follow the setting from EEPROM + } else { /* follow the setting from EEPROM */ MTOPARA_TXPOWER_INDEX() = MTO_TXPOWER_FROM_EEPROM; - RFSynthesizer_SetPowerIndex(MTO_HAL(), (u8)MTOPARA_TXPOWER_INDEX()); - //------------------------------------------------ + } + RFSynthesizer_SetPowerIndex(MTO_HAL(), (u8) MTOPARA_TXPOWER_INDEX()); + /* ------------------------------------------------ */ - // For RSSI turning 20060808.4 Cancel load from EEPROM + /* For RSSI turning -- Cancel load from EEPROM */ MTO_DATA().RSSI_high = -41; MTO_DATA().RSSI_low = -60; } -//=========================================================================== -// Description: -// If we enable DTO, we will ignore the tx count with different tx rate from -// DTO rate. This is because when we adjust DTO tx rate, there could be some -// packets in the tx queue with previous tx rate +/* =========================================================================== + * Description: + * If we enable DTO, we will ignore the tx count with different tx rate + * from DTO rate. This is because when we adjust DTO tx rate, there could + * be some packets in the tx queue with previous tx rate + */ + void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 tx_rate, u8 index) { MTO_TXFLOWCOUNT()++; - if ((MTO_ENABLE==1) && (MTO_RATE_CHANGE_ENABLE()==1)) - { - if(tx_rate == MTO_DATA_RATE()) - { - if (index == 0) - { + if ((MTO_ENABLE == 1) && (MTO_RATE_CHANGE_ENABLE() == 1)) { + if (tx_rate == MTO_DATA_RATE()) { + if (index == 0) { if (boSparseTxTraffic) MTO_HAL()->dto_tx_frag_count += MTOPARA_PERIODIC_CHECK_CYCLE(); else MTO_HAL()->dto_tx_frag_count += 1; - } - else - { - if (index<8) - { + } else { + if (index < 8) { MTO_HAL()->dto_tx_retry_count += index; - MTO_HAL()->dto_tx_frag_count += (index+1); - } - else - { + MTO_HAL()->dto_tx_frag_count += (index + 1); + } else { MTO_HAL()->dto_tx_retry_count += 7; MTO_HAL()->dto_tx_frag_count += 7; } } - } - else if(MTO_DATA_RATE()>48 && tx_rate ==48) - {//ALFRED - if (index<3) //for reduciing data rate scheme , - //do not calcu different data rate - //3 is the reducing data rate at retry - { + } else if (MTO_DATA_RATE() > 48 && tx_rate == 48) { + /* for reducing data rate scheme, do not calculate different data rate. 3 is the reducing data rate at retry. */ + if (index < 3) { MTO_HAL()->dto_tx_retry_count += index; - MTO_HAL()->dto_tx_frag_count += (index+1); - } - else - { + MTO_HAL()->dto_tx_frag_count += (index + 1); + } else { MTO_HAL()->dto_tx_retry_count += 3; MTO_HAL()->dto_tx_frag_count += 3; } } - } - else - { + } else { MTO_HAL()->dto_tx_retry_count += index; - MTO_HAL()->dto_tx_frag_count += (index+1); + MTO_HAL()->dto_tx_frag_count += (index + 1); } - TotalTxPkt ++; - TotalTxPktRetry += (index+1); + TotalTxPkt++; + TotalTxPktRetry += (index + 1); - PeriodTotalTxPkt ++; - PeriodTotalTxPktRetry += (index+1); + PeriodTotalTxPkt++; + PeriodTotalTxPktRetry += (index + 1); } -- cgit v1.2.3 From 5dcf8f668c330e72bf3a1de9e8b9451912a68ccd Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Sat, 20 Mar 2010 15:37:21 +0200 Subject: Staging: winbond: fix comments coding style issue in core.h This is a patch to the core.h file that fixed up a TAB and spaces Errors found by the checkpatch.pl tools, like do not use C99 // comments Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/core.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/core.h b/drivers/staging/winbond/core.h index 0a2060bf4f94..b87d6c07600f 100644 --- a/drivers/staging/winbond/core.h +++ b/drivers/staging/winbond/core.h @@ -12,14 +12,16 @@ #define WB_MAX_LINK_NAME_LEN 40 struct wbsoft_priv { - u32 adapterIndex; // 20060703.4 Add for using padapterContext global adapter point + u32 adapterIndex; /* 20060703.4 Add for using padapterContext + global adapter point */ - struct wb_local_para sLocalPara; // Myself connected parameters + struct wb_local_para sLocalPara; /* Myself connected + parameters */ - MLME_FRAME sMlmeFrame; // connect to peerSTA parameters + MLME_FRAME sMlmeFrame; /* connect to peerSTA parameters */ - struct wb35_mto_params sMtoPara; // MTO_struct ... - struct hw_data sHwData; //For HAL + struct wb35_mto_params sMtoPara; /* MTO_struct ... */ + struct hw_data sHwData; /*For HAL */ struct wb35_mds Mds; spinlock_t SpinLock; @@ -30,7 +32,7 @@ struct wbsoft_priv { u32 TxByteCount; struct sk_buff *packet_return; - s32 netif_state_stop; // 1: stop 0: normal + s32 netif_state_stop; /* 1: stop 0: normal */ struct iw_statistics iw_stats; u8 LinkName[WB_MAX_LINK_NAME_LEN]; -- cgit v1.2.3 From 03a4389c808a552abb734483310b52140491ed00 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Sat, 20 Mar 2010 16:29:01 +0200 Subject: Staging: winbond: fix comments coding style issue in mac_structures.h This is a patch to the mac_structures.h file that fixed up a comments Errors found by the checkpatch.pl tool Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mac_structures.h | 156 +++++++++++++++---------------- 1 file changed, 78 insertions(+), 78 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/mac_structures.h b/drivers/staging/winbond/mac_structures.h index f24dbb955bfe..80d7e4a88997 100644 --- a/drivers/staging/winbond/mac_structures.h +++ b/drivers/staging/winbond/mac_structures.h @@ -1,4 +1,4 @@ -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // MAC_Structures.h // // This file contains the definitions and data structures used by SW-MAC. @@ -16,24 +16,24 @@ // Deleted some unused. // 20021129 PD43 Austin // 20030617 increase the 802.11g definition -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ #ifndef _MAC_Structures_H_ #define _MAC_Structures_H_ #include -//========================================================= +/*========================================================= // Some miscellaneous definitions -//----- +//-----*/ #define MAX_CHANNELS 30 #define MAC_ADDR_LENGTH 6 -#define MAX_WEP_KEY_SIZE 16 // 128 bits -#define MAX_802_11_FRAGMENT_NUMBER 10 // By spec +#define MAX_WEP_KEY_SIZE 16 /* 128 bits */ +#define MAX_802_11_FRAGMENT_NUMBER 10 /* By spec */ -//======================================================== +/* ======================================================== // 802.11 Frame define -//----- +//----- */ #define MASK_PROTOCOL_VERSION_TYPE 0x0F #define MASK_FRAGMENT_NUMBER 0x000F #define SEQUENCE_NUMBER_SHIFT 4 @@ -41,8 +41,8 @@ #define DOT_11_MAC_HEADER_SIZE 24 #define DOT_11_SNAP_SIZE 6 #define DOT_11_DURATION_OFFSET 2 -#define DOT_11_SEQUENCE_OFFSET 22 //Sequence control offset -#define DOT_11_TYPE_OFFSET 30 //The start offset of 802.11 Frame// +#define DOT_11_SEQUENCE_OFFSET 22 /* Sequence control offset */ +#define DOT_11_TYPE_OFFSET 30 /* The start offset of 802.11 Frame// */ #define DOT_11_DATA_OFFSET 24 #define DOT_11_DA_OFFSET 4 #define DOT_3_TYPE_ARP 0x80F3 @@ -54,7 +54,7 @@ #define MAX_ETHERNET_PACKET_SIZE 1514 -//----- management : Type of Bits (2, 3) and Subtype of Bits (4, 5, 6, 7) +/* ----- management : Type of Bits (2, 3) and Subtype of Bits (4, 5, 6, 7) */ #define MAC_SUBTYPE_MNGMNT_ASSOC_REQUEST 0x00 #define MAC_SUBTYPE_MNGMNT_ASSOC_RESPONSE 0x10 #define MAC_SUBTYPE_MNGMNT_REASSOC_REQUEST 0x20 @@ -67,7 +67,7 @@ #define MAC_SUBTYPE_MNGMNT_AUTHENTICATION 0xB0 #define MAC_SUBTYPE_MNGMNT_DEAUTHENTICATION 0xC0 -//----- control : Type of Bits (2, 3) and Subtype of Bits (4, 5, 6, 7) +/* ----- control : Type of Bits (2, 3) and Subtype of Bits (4, 5, 6, 7) */ #define MAC_SUBTYPE_CONTROL_PSPOLL 0xA4 #define MAC_SUBTYPE_CONTROL_RTS 0xB4 #define MAC_SUBTYPE_CONTROL_CTS 0xC4 @@ -75,7 +75,7 @@ #define MAC_SUBTYPE_CONTROL_CFEND 0xE4 #define MAC_SUBTYPE_CONTROL_CFEND_CFACK 0xF4 -//----- data : Type of Bits (2, 3) and Subtype of Bits (4, 5, 6, 7) +/* ----- data : Type of Bits (2, 3) and Subtype of Bits (4, 5, 6, 7) */ #define MAC_SUBTYPE_DATA 0x08 #define MAC_SUBTYPE_DATA_CFACK 0x18 #define MAC_SUBTYPE_DATA_CFPOLL 0x28 @@ -85,12 +85,12 @@ #define MAC_SUBTYPE_DATA_CFPOLL_NULL 0x68 #define MAC_SUBTYPE_DATA_CFACK_CFPOLL_NULL 0x78 -//----- Frame Type of Bits (2, 3) +/* ----- Frame Type of Bits (2, 3) */ #define MAC_TYPE_MANAGEMENT 0x00 #define MAC_TYPE_CONTROL 0x04 #define MAC_TYPE_DATA 0x08 -//----- definitions for Management Frame Element ID (1 BYTE) +/* ----- definitions for Management Frame Element ID (1 BYTE) */ #define ELEMENT_ID_SSID 0 #define ELEMENT_ID_SUPPORTED_RATES 1 #define ELEMENT_ID_FH_PARAMETER_SET 2 @@ -130,7 +130,7 @@ #define REASON_CLASS3_FRAME_FROM_NONASSO_STA 7 #define DISASS_REASON_LEFT_BSS 8 #define REASON_NOT_AUTH_YET 9 -//802.11i define +/* 802.11i define */ #define REASON_INVALID_IE 13 #define REASON_MIC_ERROR 14 #define REASON_4WAY_HANDSHAKE_TIMEOUT 15 @@ -175,11 +175,11 @@ enum enum_MMPDUResultCode } WB_MMPDURESULTCODE, *PWB_MMPDURESULTCODE; */ -//=========================================================== +/*=========================================================== // enum_TxRate -- // Define the transmission constants based on W89C32 MAC // target specification. -//=========================================================== +//===========================================================*/ typedef enum enum_TxRate { TXRATE_1M = 0, @@ -189,7 +189,7 @@ typedef enum enum_TxRate TXRATE_55MSHORT = 5, TXRATE_11MLONG = 6, TXRATE_11MSHORT = 7, - TXRATE_AUTO = 255 // PD43 20021108 + TXRATE_AUTO = 255 /* PD43 20021108 */ } WB_TXRATE, *PWB_TXRATE; @@ -225,7 +225,7 @@ typedef enum enum_TxRate #define RATE_54M 108 #define RATE_MAX 255 -//CAPABILITY +/* CAPABILITY */ #define CAPABILITY_ESS_BIT 0x0001 #define CAPABILITY_IBSS_BIT 0x0002 #define CAPABILITY_CF_POLL_BIT 0x0004 @@ -243,10 +243,10 @@ struct Capability_Information_Element union { u16 __attribute__ ((packed)) wValue; - #ifdef _BIG_ENDIAN_ //20060926 add by anson's endian + #ifdef _BIG_ENDIAN_ /* 20060926 add by anson's endian */ struct _Capability { - //-- 11G -- + /* -- 11G -- */ u8 Reserved3 : 2; u8 DSSS_OFDM : 1; u8 Reserved2 : 2; @@ -273,7 +273,7 @@ struct Capability_Information_Element u8 PBCC : 1; u8 Channel_Agility : 1; u8 Reserved1 : 2; - //-- 11G -- + /* -- 11G -- */ u8 Short_Slot_Time : 1; u8 Reserved2 : 2; u8 DSSS_OFDM : 1; @@ -320,8 +320,8 @@ struct CF_Parameter_Set_Element u8 Length; u8 CFP_Count; u8 CFP_Period; - u8 CFP_MaxDuration[2]; // in Time Units - u8 CFP_DurRemaining[2]; // in time units + u8 CFP_MaxDuration[2]; /* in Time Units */ + u8 CFP_DurRemaining[2]; /* in time units */ }; struct TIM_Element @@ -350,8 +350,8 @@ struct Challenge_Text_Element struct PHY_Parameter_Set_Element { -// int aSlotTime; -// int aSifsTime; +/* int aSlotTime; */ +/* int aSifsTime; */ s32 aCCATime; s32 aRxTxTurnaroundTime; s32 aTxPLCPDelay; @@ -367,17 +367,17 @@ struct PHY_Parameter_Set_Element s32 aPLCPHeaderLength; s32 aMPDUDurationFactor; s32 aMPDUMaxLength; -// int aCWmin; -// int aCWmax; +/* int aCWmin; */ +/* int aCWmax; */ }; -//-- 11G -- +/* -- 11G -- */ struct ERP_Information_Element { u8 Element_ID; u8 Length; - #ifdef _BIG_ENDIAN_ //20060926 add by anson's endian - u8 Reserved:5; //20060926 add by anson + #ifdef _BIG_ENDIAN_ /* 20060926 add by anson's endian */ + u8 Reserved:5; /* 20060926 add by anson */ u8 Barker_Preamble_Mode:1; u8 Use_Protection:1; u8 NonERP_Present:1; @@ -396,41 +396,41 @@ struct Extended_Supported_Rates_Element u8 ExtendedSupportedRates[255]; }__attribute__ ((packed)); -//WPA(802.11i draft 3.0) +/* WPA(802.11i draft 3.0) */ #define VERSION_WPA 1 #ifdef _WPA2_ #define VERSION_WPA2 1 -#endif //end def _WPA2_ -#define OUI_WPA 0x00F25000 //WPA2.0 OUI=00:50:F2, the MSB is reserved for suite type +#endif /* end def _WPA2_ */ +#define OUI_WPA 0x00F25000 /* WPA2.0 OUI=00:50:F2, the MSB is reserved for suite type */ #ifdef _WPA2_ -#define OUI_WPA2 0x00AC0F00 // for wpa2 change to 0x00ACOF04 by Ws 26/04/04 -#endif //end def _WPA2_ +#define OUI_WPA2 0x00AC0F00 /* for wpa2 change to 0x00ACOF04 by Ws 26/04/04 */ +#endif /* end def _WPA2_ */ #define OUI_WPA_ADDITIONAL 0x01 -#define WLAN_MIN_RSN_WPA_LENGTH 6 //added by ws 09/10/04 +#define WLAN_MIN_RSN_WPA_LENGTH 6 /* added by ws 09/10/04 */ #ifdef _WPA2_ -#define WLAN_MIN_RSN_WPA2_LENGTH 2 // Fix to 2 09/14/05 -#endif //end def _WPA2_ +#define WLAN_MIN_RSN_WPA2_LENGTH 2 /* Fix to 2 09/14/05 */ +#endif /* end def _WPA2_ */ #define oui_wpa (u32)(OUI_WPA|OUI_WPA_ADDITIONAL) -#define WPA_OUI_BIG ((u32) 0x01F25000)//added by ws 09/23/04 -#define WPA_OUI_LITTLE ((u32) 0x01F25001)//added by ws 09/23/04 +#define WPA_OUI_BIG ((u32) 0x01F25000)/* added by ws 09/23/04 */ +#define WPA_OUI_LITTLE ((u32) 0x01F25001)/* added by ws 09/23/04 */ -#define WPA_WPS_OUI cpu_to_le32(0x04F25000) // 20061108 For WPS. It's little endian. Big endian is 0x0050F204 +#define WPA_WPS_OUI cpu_to_le32(0x04F25000) /* 20061108 For WPS. It's little endian. Big endian is 0x0050F204 */ -//-----WPA2----- +/* -----WPA2----- */ #ifdef _WPA2_ #define WPA2_OUI_BIG ((u32)0x01AC0F00) #define WPA2_OUI_LITTLE ((u32)0x01AC0F01) -#endif //end def _WPA2_ +#endif /* end def _WPA2_ */ -//Authentication suite -#define OUI_AUTH_WPA_NONE 0x00 //for WPA_NONE +/* Authentication suite */ +#define OUI_AUTH_WPA_NONE 0x00 /* for WPA_NONE */ #define OUI_AUTH_8021X 0x01 #define OUI_AUTH_PSK 0x02 -//Cipher suite -#define OUI_CIPHER_GROUP_KEY 0x00 //added by ws 05/21/04 +/* Cipher suite */ +#define OUI_CIPHER_GROUP_KEY 0x00 /* added by ws 05/21/04 */ #define OUI_CIPHER_WEP_40 0x01 #define OUI_CIPHER_TKIP 0x02 #define OUI_CIPHER_CCMP 0x04 @@ -466,16 +466,16 @@ struct RSN_Auth_Sub_Information_Element struct suite_selector AuthKeyMngtSuite[1]; }__attribute__ ((packed)); -//-- WPA2 -- +/* -- WPA2 -- */ struct RSN_Capability_Element { union { u16 __attribute__ ((packed)) wValue; - #ifdef _BIG_ENDIAN_ //20060927 add by anson's endian + #ifdef _BIG_ENDIAN_ /* 20060927 add by anson's endian */ struct _RSN_Capability { - u16 __attribute__ ((packed)) Reserved2 : 8; // 20051201 + u16 __attribute__ ((packed)) Reserved2 : 8; /* 20051201 */ u16 __attribute__ ((packed)) Reserved1 : 2; u16 __attribute__ ((packed)) GTK_Replay_Counter : 2; u16 __attribute__ ((packed)) PTK_Replay_Counter : 2; @@ -490,7 +490,7 @@ struct RSN_Capability_Element u16 __attribute__ ((packed)) PTK_Replay_Counter : 2; u16 __attribute__ ((packed)) GTK_Replay_Counter : 2; u16 __attribute__ ((packed)) Reserved1 : 2; - u16 __attribute__ ((packed)) Reserved2 : 8; // 20051201 + u16 __attribute__ ((packed)) Reserved2 : 8; /* 20051201 */ }__attribute__ ((packed)) RSN_Capability; #endif @@ -527,14 +527,14 @@ struct PMKID_Information_Element struct pmkid pmkid[16]; }__attribute__ ((packed)); -#endif //enddef _WPA2_ -//============================================================ +#endif /* enddef _WPA2_ */ +/*============================================================ // MAC Frame structure (different type) and subfield structure -//============================================================ +//============================================================*/ struct MAC_frame_control { - u8 mac_frame_info; // a combination of the [Protocol Version, Control Type, Control Subtype] - #ifdef _BIG_ENDIAN_ //20060927 add by anson's endian + u8 mac_frame_info; /* a combination of the [Protocol Version, Control Type, Control Subtype]*/ + #ifdef _BIG_ENDIAN_ /* 20060927 add by anson's endian */ u8 order:1; u8 WEP:1; u8 more_data:1; @@ -556,19 +556,19 @@ struct MAC_frame_control } __attribute__ ((packed)); struct Management_Frame { - struct MAC_frame_control frame_control; // 2B, ToDS,FromDS,MoreFrag,MoreData,Order=0 + struct MAC_frame_control frame_control; /* 2B, ToDS,FromDS,MoreFrag,MoreData,Order=0 */ u16 duration; - u8 DA[MAC_ADDR_LENGTH]; // Addr1 - u8 SA[MAC_ADDR_LENGTH]; // Addr2 - u8 BSSID[MAC_ADDR_LENGTH]; // Addr3 + u8 DA[MAC_ADDR_LENGTH]; /* Addr1 */ + u8 SA[MAC_ADDR_LENGTH]; /* Addr2 */ + u8 BSSID[MAC_ADDR_LENGTH]; /* Addr3 */ u16 Sequence_Control; - // Management Frame Body <= 325 bytes - // FCS 4 bytes + /* Management Frame Body <= 325 bytes */ + /* FCS 4 bytes */ }__attribute__ ((packed)); -// SW-MAC don't Tx/Rx Control-Frame, HW-MAC do it. +/* SW-MAC don't Tx/Rx Control-Frame, HW-MAC do it. */ struct Control_Frame { - struct MAC_frame_control frame_control; // ToDS,FromDS,MoreFrag,Retry,MoreData,WEP,Order=0 + struct MAC_frame_control frame_control; /* ToDS,FromDS,MoreFrag,Retry,MoreData,WEP,Order=0 */ u16 duration; u8 RA[MAC_ADDR_LENGTH]; u8 TA[MAC_ADDR_LENGTH]; @@ -582,9 +582,9 @@ struct Data_Frame { u8 Addr2[MAC_ADDR_LENGTH]; u8 Addr3[MAC_ADDR_LENGTH]; u16 Sequence_Control; - u8 Addr4[MAC_ADDR_LENGTH]; // only exist when ToDS=FromDS=1 - // Data Frame Body <= 2312 - // FCS + u8 Addr4[MAC_ADDR_LENGTH]; /* only exist when ToDS=FromDS=1 */ + /* Data Frame Body <= 2312 */ + /* FCS */ }__attribute__ ((packed)); struct Disassociation_Frame_Body @@ -596,9 +596,9 @@ struct Association_Request_Frame_Body { u16 capability_information; u16 listenInterval; - u8 Current_AP_Address[MAC_ADDR_LENGTH];//for reassociation only - // SSID (2+32 bytes) - // Supported_Rates (2+8 bytes) + u8 Current_AP_Address[MAC_ADDR_LENGTH];/* for reassociation only */ + /* SSID (2+32 bytes) */ + /* Supported_Rates (2+8 bytes) */ }__attribute__ ((packed)); struct Association_Response_Frame_Body @@ -617,7 +617,7 @@ struct Association_Response_Frame_Body // SSID (2+32 bytes) // Supported_Rates (2+8 bytes) };*/ -// eliminated by WS 07/22/04 comboined with associateion request frame. +/* eliminated by WS 07/22/04 comboined with associateion request frame. */ struct Reassociation_Response_Frame_Body { @@ -638,11 +638,11 @@ struct Probe_Response_Frame_Body u16 Timestamp; u16 Beacon_Interval; u16 Capability_Information; - // SSID + /* SSID // Supported_Rates // PHY parameter Set (DS Parameters) // CF parameter Set - // IBSS parameter Set + // IBSS parameter Set */ }__attribute__ ((packed)); struct Authentication_Frame_Body @@ -650,11 +650,11 @@ struct Authentication_Frame_Body u16 algorithmNumber; u16 sequenceNumber; u16 statusCode; - // NB: don't include ChallengeText in this structure - // struct Challenge_Text_Element sChallengeTextElement; // wkchen added + /* NB: don't include ChallengeText in this structure + // struct Challenge_Text_Element sChallengeTextElement; // wkchen added */ }__attribute__ ((packed)); -#endif // _MAC_Structure_H_ +#endif /* _MAC_Structure_H_ */ -- cgit v1.2.3 From d20279d7d45e3428b2202385e488ea57fbc4ab39 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Sat, 20 Mar 2010 16:46:35 +0200 Subject: Staging: winbond: fix brace and space coding style issue in mac_structures.h This is a patch to the mac_structures.h file that fixed up a brace and space Errors found by the checkpatch.pl tool. Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mac_structures.h | 159 +++++++++++++------------------ 1 file changed, 68 insertions(+), 91 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/mac_structures.h b/drivers/staging/winbond/mac_structures.h index 80d7e4a88997..7441015cb187 100644 --- a/drivers/staging/winbond/mac_structures.h +++ b/drivers/staging/winbond/mac_structures.h @@ -180,8 +180,7 @@ enum enum_MMPDUResultCode // Define the transmission constants based on W89C32 MAC // target specification. //===========================================================*/ -typedef enum enum_TxRate -{ +typedef enum enum_TxRate { TXRATE_1M = 0, TXRATE_2MLONG = 2, TXRATE_2MSHORT = 3, @@ -238,53 +237,48 @@ typedef enum enum_TxRate #define CAPABILITY_DSSS_OFDM_BIT 0x2000 -struct Capability_Information_Element -{ - union - { - u16 __attribute__ ((packed)) wValue; +struct Capability_Information_Element { + union { + u16 __attribute__ ((packed)) wValue; #ifdef _BIG_ENDIAN_ /* 20060926 add by anson's endian */ - struct _Capability - { - /* -- 11G -- */ - u8 Reserved3 : 2; - u8 DSSS_OFDM : 1; - u8 Reserved2 : 2; - u8 Short_Slot_Time : 1; - u8 Reserved1 : 2; - u8 Channel_Agility : 1; - u8 PBCC : 1; - u8 ShortPreamble : 1; - u8 CF_Privacy : 1; - u8 CF_Poll_Request : 1; - u8 CF_Pollable : 1; - u8 IBSS : 1; - u8 ESS : 1; + struct _Capability { + /* -- 11G -- */ + u8 Reserved3:2; + u8 DSSS_OFDM:1; + u8 Reserved2:2; + u8 Short_Slot_Time:1; + u8 Reserved1:2; + u8 Channel_Agility:1; + u8 PBCC:1; + u8 ShortPreamble:1; + u8 CF_Privacy:1; + u8 CF_Poll_Request:1; + u8 CF_Pollable:1; + u8 IBSS:1; + u8 ESS:1; } __attribute__ ((packed)) Capability; #else - struct _Capability - { - u8 ESS : 1; - u8 IBSS : 1; - u8 CF_Pollable : 1; - u8 CF_Poll_Request : 1; - u8 CF_Privacy : 1; - u8 ShortPreamble : 1; - u8 PBCC : 1; - u8 Channel_Agility : 1; - u8 Reserved1 : 2; + struct _Capability { + u8 ESS:1; + u8 IBSS:1; + u8 CF_Pollable:1; + u8 CF_Poll_Request:1; + u8 CF_Privacy:1; + u8 ShortPreamble:1; + u8 PBCC:1; + u8 Channel_Agility:1; + u8 Reserved1:2; /* -- 11G -- */ - u8 Short_Slot_Time : 1; - u8 Reserved2 : 2; - u8 DSSS_OFDM : 1; - u8 Reserved3 : 2; + u8 Short_Slot_Time:1; + u8 Reserved2:2; + u8 DSSS_OFDM:1; + u8 Reserved3:2; } __attribute__ ((packed)) Capability; #endif - }__attribute__ ((packed)) ; -}__attribute__ ((packed)); + } __attribute__ ((packed)) ; +} __attribute__ ((packed)); -struct FH_Parameter_Set_Element -{ +struct FH_Parameter_Set_Element { u8 Element_ID; u8 Length; u8 Dwell_Time[2]; @@ -293,29 +287,25 @@ struct FH_Parameter_Set_Element u8 Hop_Index; }; -struct DS_Parameter_Set_Element -{ +struct DS_Parameter_Set_Element { u8 Element_ID; u8 Length; u8 Current_Channel; }; -struct Supported_Rates_Element -{ +struct Supported_Rates_Element { u8 Element_ID; u8 Length; u8 SupportedRates[8]; -}__attribute__ ((packed)); +} __attribute__ ((packed)); -struct SSID_Element -{ +struct SSID_Element { u8 Element_ID; u8 Length; u8 SSID[32]; -}__attribute__ ((packed)) ; +} __attribute__ ((packed)) ; -struct CF_Parameter_Set_Element -{ +struct CF_Parameter_Set_Element { u8 Element_ID; u8 Length; u8 CFP_Count; @@ -324,8 +314,7 @@ struct CF_Parameter_Set_Element u8 CFP_DurRemaining[2]; /* in time units */ }; -struct TIM_Element -{ +struct TIM_Element { u8 Element_ID; u8 Length; u8 DTIM_Count; @@ -334,22 +323,19 @@ struct TIM_Element u8 Partial_Virtual_Bitmap[251]; }; -struct IBSS_Parameter_Set_Element -{ +struct IBSS_Parameter_Set_Element { u8 Element_ID; u8 Length; u8 ATIM_Window[2]; }; -struct Challenge_Text_Element -{ +struct Challenge_Text_Element { u8 Element_ID; u8 Length; u8 Challenge_Text[253]; }; -struct PHY_Parameter_Set_Element -{ +struct PHY_Parameter_Set_Element { /* int aSlotTime; */ /* int aSifsTime; */ s32 aCCATime; @@ -372,13 +358,12 @@ struct PHY_Parameter_Set_Element }; /* -- 11G -- */ -struct ERP_Information_Element -{ +struct ERP_Information_Element { u8 Element_ID; u8 Length; #ifdef _BIG_ENDIAN_ /* 20060926 add by anson's endian */ - u8 Reserved:5; /* 20060926 add by anson */ - u8 Barker_Preamble_Mode:1; + u8 Reserved:5; /* 20060926 add by anson */ + u8 Barker_Preamble_Mode:1; u8 Use_Protection:1; u8 NonERP_Present:1; #else @@ -389,12 +374,11 @@ struct ERP_Information_Element #endif }; -struct Extended_Supported_Rates_Element -{ +struct Extended_Supported_Rates_Element { u8 Element_ID; u8 Length; u8 ExtendedSupportedRates[255]; -}__attribute__ ((packed)); +} __attribute__ ((packed)); /* WPA(802.11i draft 3.0) */ #define VERSION_WPA 1 @@ -564,7 +548,7 @@ struct Management_Frame { u16 Sequence_Control; /* Management Frame Body <= 325 bytes */ /* FCS 4 bytes */ -}__attribute__ ((packed)); +} __attribute__ ((packed)); /* SW-MAC don't Tx/Rx Control-Frame, HW-MAC do it. */ struct Control_Frame { @@ -573,7 +557,7 @@ struct Control_Frame { u8 RA[MAC_ADDR_LENGTH]; u8 TA[MAC_ADDR_LENGTH]; u16 FCS; -}__attribute__ ((packed)); +} __attribute__ ((packed)); struct Data_Frame { struct MAC_frame_control frame_control; @@ -585,29 +569,26 @@ struct Data_Frame { u8 Addr4[MAC_ADDR_LENGTH]; /* only exist when ToDS=FromDS=1 */ /* Data Frame Body <= 2312 */ /* FCS */ -}__attribute__ ((packed)); +} __attribute__ ((packed)); -struct Disassociation_Frame_Body -{ +struct Disassociation_Frame_Body { u16 reasonCode; -}__attribute__ ((packed)); +} __attribute__ ((packed)); -struct Association_Request_Frame_Body -{ +struct Association_Request_Frame_Body { u16 capability_information; u16 listenInterval; u8 Current_AP_Address[MAC_ADDR_LENGTH];/* for reassociation only */ /* SSID (2+32 bytes) */ /* Supported_Rates (2+8 bytes) */ -}__attribute__ ((packed)); +} __attribute__ ((packed)); -struct Association_Response_Frame_Body -{ +struct Association_Response_Frame_Body { u16 capability_information; u16 statusCode; u16 Association_ID; struct Supported_Rates_Element supportedRates; -}__attribute__ ((packed)); +} __attribute__ ((packed)); /*struct Reassociation_Request_Frame_Body { @@ -619,22 +600,19 @@ struct Association_Response_Frame_Body };*/ /* eliminated by WS 07/22/04 comboined with associateion request frame. */ -struct Reassociation_Response_Frame_Body -{ +struct Reassociation_Response_Frame_Body { u16 capability_information; u16 statusCode; u16 Association_ID; struct Supported_Rates_Element supportedRates; -}__attribute__ ((packed)); +} __attribute__ ((packed)); -struct Deauthentication_Frame_Body -{ +struct Deauthentication_Frame_Body { u16 reasonCode; -}__attribute__ ((packed)); +} __attribute__ ((packed)); -struct Probe_Response_Frame_Body -{ +struct Probe_Response_Frame_Body { u16 Timestamp; u16 Beacon_Interval; u16 Capability_Information; @@ -643,16 +621,15 @@ struct Probe_Response_Frame_Body // PHY parameter Set (DS Parameters) // CF parameter Set // IBSS parameter Set */ -}__attribute__ ((packed)); +} __attribute__ ((packed)); -struct Authentication_Frame_Body -{ +struct Authentication_Frame_Body { u16 algorithmNumber; u16 sequenceNumber; u16 statusCode; /* NB: don't include ChallengeText in this structure // struct Challenge_Text_Element sChallengeTextElement; // wkchen added */ -}__attribute__ ((packed)); +} __attribute__ ((packed)); #endif /* _MAC_Structure_H_ */ -- cgit v1.2.3 From 152f1bc0517f95f6866046f00c7ef7aff1ca58cd Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Sat, 20 Mar 2010 20:43:59 +0100 Subject: Staging: winbond: scan_s.h Coding style fixes. I fixed all things reported by checkpatch.pl except a couple of long lines and typedefs. I also removed "commented away" code and a history comment. Signed-off-by: Lars Lindley Acked-by: Pavel Machek Acked-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/scan_s.h | 152 ++++++++++++++++++--------------------- 1 file changed, 71 insertions(+), 81 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/scan_s.h b/drivers/staging/winbond/scan_s.h index 209717f5d47d..85e7523196d0 100644 --- a/drivers/staging/winbond/scan_s.h +++ b/drivers/staging/winbond/scan_s.h @@ -4,117 +4,107 @@ #include #include "localpara.h" -// -// SCAN task global CONSTANTS, STRUCTURES, variables -// - -////////////////////////////////////////////////////////////////////////// -//define the msg type of SCAN module -#define SCANMSG_SCAN_REQ 0x01 -#define SCANMSG_BEACON 0x02 +/* + * SCAN task global CONSTANTS, STRUCTURES, variables + */ + +/* define the msg type of SCAN module */ +#define SCANMSG_SCAN_REQ 0x01 +#define SCANMSG_BEACON 0x02 #define SCANMSG_PROBE_RESPONSE 0x03 -#define SCANMSG_TIMEOUT 0x04 +#define SCANMSG_TIMEOUT 0x04 #define SCANMSG_TXPROBE_FAIL 0x05 #define SCANMSG_ENABLE_BGSCAN 0x06 -#define SCANMSG_STOP_SCAN 0x07 +#define SCANMSG_STOP_SCAN 0x07 -// BSS Type =>conform to -// IBSS : ToDS/FromDS = 00 -// Infrastructure : ToDS/FromDS = 01 +/* + * BSS Type =>conform to + * IBSS : ToDS/FromDS = 00 + * Infrastructure : ToDS/FromDS = 01 + */ #define IBSS_NET 0 #define ESS_NET 1 #define ANYBSS_NET 2 -// Scan Type +/* Scan Type */ #define ACTIVE_SCAN 0 -#define PASSIVE_SCAN 1 +#define PASSIVE_SCAN 1 + +/* Global data structures, Initial Scan & Background Scan */ +typedef struct _SCAN_REQ_PARA { /* mandatory parameters for SCAN request */ -/////////////////////////////////////////////////////////////////////////// -//Global data structures, Initial Scan & Background Scan -typedef struct _SCAN_REQ_PARA //mandatory parameters for SCAN request -{ - u32 ScanType; //passive/active scan + u32 ScanType; /* passive/active scan */ u8 reserved_1[2]; - struct SSID_Element sSSID; // 34B. scan only for this SSID + struct SSID_Element sSSID; /* 34B. scan only for this SSID */ u8 reserved_2[2]; } SCAN_REQ_PARA, *psSCAN_REQ_PARA; -typedef struct _SCAN_PARAMETERS -{ - u16 wState; - u16 iCurrentChannelIndex; +typedef struct _SCAN_PARAMETERS { + u16 wState; + u16 iCurrentChannelIndex; SCAN_REQ_PARA sScanReq; - u8 BSSID[MAC_ADDR_LENGTH + 2]; //scan only for this BSSID + u8 BSSID[MAC_ADDR_LENGTH + 2]; /* scan only for this BSSID */ - u32 BssType; //scan only for this BSS type + u32 BssType; /* scan only for this BSS type */ - //struct SSID_Element sSSID; //scan only for this SSID - u16 ProbeDelay; - u16 MinChannelTime; + u16 ProbeDelay; + u16 MinChannelTime; - u16 MaxChannelTime; - u16 reserved_1; + u16 MaxChannelTime; + u16 reserved_1; - s32 iBgScanPeriod; // XP: 5 sec + s32 iBgScanPeriod; /* XP: 5 sec */ - u8 boBgScan; // Wb: enable BG scan, For XP, this value must be FALSE - u8 boFastScan; // Wb: reserved - u8 boCCAbusy; // Wb: HWMAC CCA busy status - u8 reserved_2; + u8 boBgScan; /* Wb: enable BG scan, For XP, this value must be FALSE */ + u8 boFastScan; /* Wb: reserved */ + u8 boCCAbusy; /* Wb: HWMAC CCA busy status */ + u8 reserved_2; struct timer_list timer; - u32 ScanTimeStamp; //Increase 1 per background scan(1 minute) - u32 BssTimeStamp; //Increase 1 per connect status check - u32 RxNumPerAntenna[2]; // - - u8 AntennaToggle; // - u8 boInTimerHandler; - u8 boTimerActive; // Wb: reserved - u8 boSave; + u32 ScanTimeStamp; /* Increase 1 per background scan(1 minute) */ + u32 BssTimeStamp; /* Increase 1 per connect status check */ + u32 RxNumPerAntenna[2]; - u32 BScanEnable; // Background scan enable. Default is On + u8 AntennaToggle; + u8 boInTimerHandler; + u8 boTimerActive; /* Wb: reserved */ + u8 boSave; + u32 BScanEnable; /* Background scan enable. Default is On */ } SCAN_PARAMETERS, *psSCAN_PARAMETERS; -// Encapsulate 'adapter' data structure -#define psSCAN (&(adapter->sScanPara)) -#define psSCANREQ (&(adapter->sScanPara.sScanReq)) - -//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// scan.h -// Define the related definitions of scan module -// history -- 01/14/03' created -// -//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -//Define the state of scan module -#define SCAN_INACTIVE 0 -#define WAIT_PROBE_DELAY 1 -#define WAIT_RESPONSE_MIN 2 -#define WAIT_RESPONSE_MAX_ACTIVE 3 -#define WAIT_BEACON_MAX_PASSIVE 4 -#define SCAN_COMPLETE 5 -#define BG_SCAN 6 -#define BG_SCANNING 7 - - -// The value will load from EEPROM -// If 0xff is set in EEPOM, the driver will use SCAN_MAX_CHNL_TIME instead. -// The definition is in WbHal.h -// #define SCAN_MAX_CHNL_TIME (50) - - - -// static functions - -//static void ScanTimerHandler(struct wbsoft_priv * adapter); -//static void vScanTimerStart(struct wbsoft_priv * adapter, int timeout_value); -//static void vScanTimerStop(struct wbsoft_priv * adapter); - +/* Encapsulate 'adapter' data structure */ +#define psSCAN (&(adapter->sScanPara)) +#define psSCANREQ (&(adapter->sScanPara.sScanReq)) + +/* + * =========================================================== + * scan.h + * Define the related definitions of scan module + * + * =========================================================== + */ + +/* Define the state of scan module */ +#define SCAN_INACTIVE 0 +#define WAIT_PROBE_DELAY 1 +#define WAIT_RESPONSE_MIN 2 +#define WAIT_RESPONSE_MAX_ACTIVE 3 +#define WAIT_BEACON_MAX_PASSIVE 4 +#define SCAN_COMPLETE 5 +#define BG_SCAN 6 +#define BG_SCANNING 7 + + +/* + * The value will load from EEPROM + * If 0xff is set in EEPOM, the driver will use SCAN_MAX_CHNL_TIME instead. + * The definition is in WbHal.h + */ #endif -- cgit v1.2.3 From fa6896f2c5416c773f7c6f13bb7db140f8208c71 Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Sun, 21 Mar 2010 17:50:42 +0100 Subject: Staging: winbond: reg.c Coding style fixes I fixed all problems reported by checkpatch.pl except some (a lot of) long lines and some printk:s. I removed "commented away" code and version comments. Signed-off-by: Lars Lindley Acked-by: Pekka Enberg Acked-by: Pavel Machek Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/reg.c | 3985 +++++++++++++++++++---------------------- 1 file changed, 1847 insertions(+), 2138 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/reg.c b/drivers/staging/winbond/reg.c index 5f5048af26a5..d9a8128b21f0 100644 --- a/drivers/staging/winbond/reg.c +++ b/drivers/staging/winbond/reg.c @@ -1,514 +1,452 @@ #include "sysdef.h" #include "wbhal_f.h" -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Original Phy.h -//***************************************************************************** - -/***************************************************************************** -; For MAXIM2825/6/7 Ver. 331 or more -; Edited by Tiger, Sep-17-2003 -; revised by Ben, Sep-18-2003 - -0x00 0x000a2 -0x01 0x21cc0 -;0x02 0x13802 -0x02 0x1383a - -;channe1 01 ; 0x03 0x30142 ; 0x04 0x0b333; -;channe1 02 ;0x03 0x32141 ;0x04 0x08444; -;channe1 03 ;0x03 0x32143 ;0x04 0x0aeee; -;channe1 04 ;0x03 0x32142 ;0x04 0x0b333; -;channe1 05 ;0x03 0x31141 ;0x04 0x08444; -;channe1 06 ; -0x03 0x31143; -0x04 0x0aeee; -;channe1 07 ;0x03 0x31142 ;0x04 0x0b333; -;channe1 08 ;0x03 0x33141 ;0x04 0x08444; -;channe1 09 ;0x03 0x33143 ;0x04 0x0aeee; -;channe1 10 ;0x03 0x33142 ;0x04 0x0b333; -;channe1 11 ;0x03 0x30941 ;0x04 0x08444; -;channe1 12 ;0x03 0x30943 ;0x04 0x0aeee; -;channe1 13 ;0x03 0x30942 ;0x04 0x0b333; - -0x05 0x28986 -0x06 0x18008 -0x07 0x38400 -0x08 0x05100; 100 Hz DC -;0x08 0x05900; 30 KHz DC -0x09 0x24f08 -0x0a 0x17e00, 0x17ea0 -0x0b 0x37d80 -0x0c 0x0c900 // 0x0ca00 (lager power 9db than 0x0c000), 0x0c000 -*****************************************************************************/ -// MAX2825 (pure b/g) -u32 max2825_rf_data[] = -{ - (0x00<<18)|0x000a2, - (0x01<<18)|0x21cc0, - (0x02<<18)|0x13806, - (0x03<<18)|0x30142, - (0x04<<18)|0x0b333, - (0x05<<18)|0x289A6, - (0x06<<18)|0x18008, - (0x07<<18)|0x38000, - (0x08<<18)|0x05100, - (0x09<<18)|0x24f08, - (0x0A<<18)|0x14000, - (0x0B<<18)|0x37d80, - (0x0C<<18)|0x0c100 // 11a: 0x0c300, 11g: 0x0c100 -}; +/* + * ==================================================== + * Original Phy.h + * ==================================================== + */ -u32 max2825_channel_data_24[][3] = -{ - {(0x03<<18)|0x30142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 01 - {(0x03<<18)|0x32141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 02 - {(0x03<<18)|0x32143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 03 - {(0x03<<18)|0x32142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 04 - {(0x03<<18)|0x31141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 05 - {(0x03<<18)|0x31143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 06 - {(0x03<<18)|0x31142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 07 - {(0x03<<18)|0x33141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 08 - {(0x03<<18)|0x33143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 09 - {(0x03<<18)|0x33142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 10 - {(0x03<<18)|0x30941, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 11 - {(0x03<<18)|0x30943, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 12 - {(0x03<<18)|0x30942, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 13 - {(0x03<<18)|0x32941, (0x04<<18)|0x09999, (0x05<<18)|0x289A6} // 14 (2484MHz) hhmodify +/* + * ==================================================== + * For MAXIM2825/6/7 Ver. 331 or more + * + * 0x00 0x000a2 + * 0x01 0x21cc0 + * 0x02 0x13802 + * 0x02 0x1383a + * + * channe1 01 ; 0x03 0x30142 ; 0x04 0x0b333; + * channe1 02 ; 0x03 0x32141 ; 0x04 0x08444; + * channe1 03 ; 0x03 0x32143 ; 0x04 0x0aeee; + * channe1 04 ; 0x03 0x32142 ; 0x04 0x0b333; + * channe1 05 ; 0x03 0x31141 ; 0x04 0x08444; + * channe1 06 ; 0x03 0x31143 ; 0x04 0x0aeee; + * channe1 07 ; 0x03 0x31142 ; 0x04 0x0b333; + * channe1 08 ; 0x03 0x33141 ; 0x04 0x08444; + * channe1 09 ; 0x03 0x33143 ; 0x04 0x0aeee; + * channe1 10 ; 0x03 0x33142 ; 0x04 0x0b333; + * channe1 11 ; 0x03 0x30941 ; 0x04 0x08444; + * channe1 12 ; 0x03 0x30943 ; 0x04 0x0aeee; + * channe1 13 ; 0x03 0x30942 ; 0x04 0x0b333; + * + * 0x05 0x28986 + * 0x06 0x18008 + * 0x07 0x38400 + * 0x08 0x05100; 100 Hz DC + * 0x08 0x05900; 30 KHz DC + * 0x09 0x24f08 + * 0x0a 0x17e00, 0x17ea0 + * 0x0b 0x37d80 + * 0x0c 0x0c900 -- 0x0ca00 (lager power 9db than 0x0c000), 0x0c000 + */ + +/* MAX2825 (pure b/g) */ +u32 max2825_rf_data[] = { + (0x00<<18) | 0x000a2, + (0x01<<18) | 0x21cc0, + (0x02<<18) | 0x13806, + (0x03<<18) | 0x30142, + (0x04<<18) | 0x0b333, + (0x05<<18) | 0x289A6, + (0x06<<18) | 0x18008, + (0x07<<18) | 0x38000, + (0x08<<18) | 0x05100, + (0x09<<18) | 0x24f08, + (0x0A<<18) | 0x14000, + (0x0B<<18) | 0x37d80, + (0x0C<<18) | 0x0c100 /* 11a: 0x0c300, 11g: 0x0c100 */ }; -u32 max2825_power_data_24[] = {(0x0C<<18)|0x0c000, (0x0C<<18)|0x0c100}; - -/****************************************************************************/ -// MAX2827 (a/b/g) -u32 max2827_rf_data[] = -{ - (0x00<<18)|0x000a2, - (0x01<<18)|0x21cc0, - (0x02<<18)|0x13806, - (0x03<<18)|0x30142, - (0x04<<18)|0x0b333, - (0x05<<18)|0x289A6, - (0x06<<18)|0x18008, - (0x07<<18)|0x38000, - (0x08<<18)|0x05100, - (0x09<<18)|0x24f08, - (0x0A<<18)|0x14000, - (0x0B<<18)|0x37d80, - (0x0C<<18)|0x0c100 // 11a: 0x0c300, 11g: 0x0c100 +u32 max2825_channel_data_24[][3] = { + {(0x03 << 18) | 0x30142, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}, /* channel 01 */ + {(0x03 << 18) | 0x32141, (0x04 << 18) | 0x08444, (0x05 << 18) | 0x289A6}, /* channel 02 */ + {(0x03 << 18) | 0x32143, (0x04 << 18) | 0x0aeee, (0x05 << 18) | 0x289A6}, /* channel 03 */ + {(0x03 << 18) | 0x32142, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}, /* channel 04 */ + {(0x03 << 18) | 0x31141, (0x04 << 18) | 0x08444, (0x05 << 18) | 0x289A6}, /* channel 05 */ + {(0x03 << 18) | 0x31143, (0x04 << 18) | 0x0aeee, (0x05 << 18) | 0x289A6}, /* channel 06 */ + {(0x03 << 18) | 0x31142, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}, /* channel 07 */ + {(0x03 << 18) | 0x33141, (0x04 << 18) | 0x08444, (0x05 << 18) | 0x289A6}, /* channel 08 */ + {(0x03 << 18) | 0x33143, (0x04 << 18) | 0x0aeee, (0x05 << 18) | 0x289A6}, /* channel 09 */ + {(0x03 << 18) | 0x33142, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}, /* channel 10 */ + {(0x03 << 18) | 0x30941, (0x04 << 18) | 0x08444, (0x05 << 18) | 0x289A6}, /* channel 11 */ + {(0x03 << 18) | 0x30943, (0x04 << 18) | 0x0aeee, (0x05 << 18) | 0x289A6}, /* channel 12 */ + {(0x03 << 18) | 0x30942, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}, /* channel 13 */ + {(0x03 << 18) | 0x32941, (0x04 << 18) | 0x09999, (0x05 << 18) | 0x289A6} /* channel 14 (2484MHz) */ }; -u32 max2827_channel_data_24[][3] = -{ - {(0x03<<18)|0x30142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 01 - {(0x03<<18)|0x32141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 02 - {(0x03<<18)|0x32143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 03 - {(0x03<<18)|0x32142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 04 - {(0x03<<18)|0x31141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 05 - {(0x03<<18)|0x31143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 06 - {(0x03<<18)|0x31142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 07 - {(0x03<<18)|0x33141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 08 - {(0x03<<18)|0x33143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 09 - {(0x03<<18)|0x33142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 10 - {(0x03<<18)|0x30941, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 11 - {(0x03<<18)|0x30943, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 12 - {(0x03<<18)|0x30942, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 13 - {(0x03<<18)|0x32941, (0x04<<18)|0x09999, (0x05<<18)|0x289A6} // 14 (2484MHz) hhmodify +u32 max2825_power_data_24[] = {(0x0C << 18) | 0x0c000, (0x0C << 18) | 0x0c100}; + +/* ========================================== */ +/* MAX2827 (a/b/g) */ +u32 max2827_rf_data[] = { + (0x00 << 18) | 0x000a2, + (0x01 << 18) | 0x21cc0, + (0x02 << 18) | 0x13806, + (0x03 << 18) | 0x30142, + (0x04 << 18) | 0x0b333, + (0x05 << 18) | 0x289A6, + (0x06 << 18) | 0x18008, + (0x07 << 18) | 0x38000, + (0x08 << 18) | 0x05100, + (0x09 << 18) | 0x24f08, + (0x0A << 18) | 0x14000, + (0x0B << 18) | 0x37d80, + (0x0C << 18) | 0x0c100 /* 11a: 0x0c300, 11g: 0x0c100 */ }; -u32 max2827_channel_data_50[][3] = -{ - {(0x03<<18)|0x33cc3, (0x04<<18)|0x08ccc, (0x05<<18)|0x2A9A6}, // channel 36 - {(0x03<<18)|0x302c0, (0x04<<18)|0x08000, (0x05<<18)|0x2A9A6}, // channel 40 - {(0x03<<18)|0x302c2, (0x04<<18)|0x0b333, (0x05<<18)|0x2A9A6}, // channel 44 - {(0x03<<18)|0x322c1, (0x04<<18)|0x09999, (0x05<<18)|0x2A9A6}, // channel 48 - {(0x03<<18)|0x312c1, (0x04<<18)|0x0a666, (0x05<<18)|0x2A9A6}, // channel 52 - {(0x03<<18)|0x332c3, (0x04<<18)|0x08ccc, (0x05<<18)|0x2A9A6}, // channel 56 - {(0x03<<18)|0x30ac0, (0x04<<18)|0x08000, (0x05<<18)|0x2A9A6}, // channel 60 - {(0x03<<18)|0x30ac2, (0x04<<18)|0x0b333, (0x05<<18)|0x2A9A6} // channel 64 +u32 max2827_channel_data_24[][3] = { + {(0x03 << 18) | 0x30142, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}, /* channe1 01 */ + {(0x03 << 18) | 0x32141, (0x04 << 18) | 0x08444, (0x05 << 18) | 0x289A6}, /* channe1 02 */ + {(0x03 << 18) | 0x32143, (0x04 << 18) | 0x0aeee, (0x05 << 18) | 0x289A6}, /* channe1 03 */ + {(0x03 << 18) | 0x32142, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}, /* channe1 04 */ + {(0x03 << 18) | 0x31141, (0x04 << 18) | 0x08444, (0x05 << 18) | 0x289A6}, /* channe1 05 */ + {(0x03 << 18) | 0x31143, (0x04 << 18) | 0x0aeee, (0x05 << 18) | 0x289A6}, /* channe1 06 */ + {(0x03 << 18) | 0x31142, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}, /* channe1 07 */ + {(0x03 << 18) | 0x33141, (0x04 << 18) | 0x08444, (0x05 << 18) | 0x289A6}, /* channe1 08 */ + {(0x03 << 18) | 0x33143, (0x04 << 18) | 0x0aeee, (0x05 << 18) | 0x289A6}, /* channe1 09 */ + {(0x03 << 18) | 0x33142, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}, /* channe1 10 */ + {(0x03 << 18) | 0x30941, (0x04 << 18) | 0x08444, (0x05 << 18) | 0x289A6}, /* channe1 11 */ + {(0x03 << 18) | 0x30943, (0x04 << 18) | 0x0aeee, (0x05 << 18) | 0x289A6}, /* channe1 12 */ + {(0x03 << 18) | 0x30942, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}, /* channe1 13 */ + {(0x03 << 18) | 0x32941, (0x04 << 18) | 0x09999, (0x05 << 18) | 0x289A6} /* channel 14 (2484MHz) */ }; -u32 max2827_power_data_24[] = {(0x0C<<18)|0x0C000, (0x0C<<18)|0x0D600, (0x0C<<18)|0x0C100}; -u32 max2827_power_data_50[] = {(0x0C<<18)|0x0C400, (0x0C<<18)|0x0D500, (0x0C<<18)|0x0C300}; - -/****************************************************************************/ -// MAX2828 (a/b/g) -u32 max2828_rf_data[] = -{ - (0x00<<18)|0x000a2, - (0x01<<18)|0x21cc0, - (0x02<<18)|0x13806, - (0x03<<18)|0x30142, - (0x04<<18)|0x0b333, - (0x05<<18)|0x289A6, - (0x06<<18)|0x18008, - (0x07<<18)|0x38000, - (0x08<<18)|0x05100, - (0x09<<18)|0x24f08, - (0x0A<<18)|0x14000, - (0x0B<<18)|0x37d80, - (0x0C<<18)|0x0c100 // 11a: 0x0c300, 11g: 0x0c100 +u32 max2827_channel_data_50[][3] = { + {(0x03 << 18) | 0x33cc3, (0x04 << 18) | 0x08ccc, (0x05 << 18) | 0x2A9A6}, /* channel 36 */ + {(0x03 << 18) | 0x302c0, (0x04 << 18) | 0x08000, (0x05 << 18) | 0x2A9A6}, /* channel 40 */ + {(0x03 << 18) | 0x302c2, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x2A9A6}, /* channel 44 */ + {(0x03 << 18) | 0x322c1, (0x04 << 18) | 0x09999, (0x05 << 18) | 0x2A9A6}, /* channel 48 */ + {(0x03 << 18) | 0x312c1, (0x04 << 18) | 0x0a666, (0x05 << 18) | 0x2A9A6}, /* channel 52 */ + {(0x03 << 18) | 0x332c3, (0x04 << 18) | 0x08ccc, (0x05 << 18) | 0x2A9A6}, /* channel 56 */ + {(0x03 << 18) | 0x30ac0, (0x04 << 18) | 0x08000, (0x05 << 18) | 0x2A9A6}, /* channel 60 */ + {(0x03 << 18) | 0x30ac2, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x2A9A6} /* channel 64 */ }; -u32 max2828_channel_data_24[][3] = -{ - {(0x03<<18)|0x30142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 01 - {(0x03<<18)|0x32141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 02 - {(0x03<<18)|0x32143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 03 - {(0x03<<18)|0x32142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 04 - {(0x03<<18)|0x31141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 05 - {(0x03<<18)|0x31143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 06 - {(0x03<<18)|0x31142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 07 - {(0x03<<18)|0x33141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 08 - {(0x03<<18)|0x33143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 09 - {(0x03<<18)|0x33142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 10 - {(0x03<<18)|0x30941, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 11 - {(0x03<<18)|0x30943, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 12 - {(0x03<<18)|0x30942, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 13 - {(0x03<<18)|0x32941, (0x04<<18)|0x09999, (0x05<<18)|0x289A6} // 14 (2484MHz) hhmodify +u32 max2827_power_data_24[] = {(0x0C << 18) | 0x0C000, (0x0C << 18) | 0x0D600, (0x0C << 18) | 0x0C100}; +u32 max2827_power_data_50[] = {(0x0C << 18) | 0x0C400, (0x0C << 18) | 0x0D500, (0x0C << 18) | 0x0C300}; + +/* ======================================================= */ +/* MAX2828 (a/b/g) */ +u32 max2828_rf_data[] = { + (0x00 << 18) | 0x000a2, + (0x01 << 18) | 0x21cc0, + (0x02 << 18) | 0x13806, + (0x03 << 18) | 0x30142, + (0x04 << 18) | 0x0b333, + (0x05 << 18) | 0x289A6, + (0x06 << 18) | 0x18008, + (0x07 << 18) | 0x38000, + (0x08 << 18) | 0x05100, + (0x09 << 18) | 0x24f08, + (0x0A << 18) | 0x14000, + (0x0B << 18) | 0x37d80, + (0x0C << 18) | 0x0c100 /* 11a: 0x0c300, 11g: 0x0c100 */ }; -u32 max2828_channel_data_50[][3] = -{ - {(0x03<<18)|0x33cc3, (0x04<<18)|0x08ccc, (0x05<<18)|0x289A6}, // channel 36 - {(0x03<<18)|0x302c0, (0x04<<18)|0x08000, (0x05<<18)|0x289A6}, // channel 40 - {(0x03<<18)|0x302c2, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channel 44 - {(0x03<<18)|0x322c1, (0x04<<18)|0x09999, (0x05<<18)|0x289A6}, // channel 48 - {(0x03<<18)|0x312c1, (0x04<<18)|0x0a666, (0x05<<18)|0x289A6}, // channel 52 - {(0x03<<18)|0x332c3, (0x04<<18)|0x08ccc, (0x05<<18)|0x289A6}, // channel 56 - {(0x03<<18)|0x30ac0, (0x04<<18)|0x08000, (0x05<<18)|0x289A6}, // channel 60 - {(0x03<<18)|0x30ac2, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6} // channel 64 +u32 max2828_channel_data_24[][3] = { + {(0x03 << 18) | 0x30142, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}, /* channe1 01 */ + {(0x03 << 18) | 0x32141, (0x04 << 18) | 0x08444, (0x05 << 18) | 0x289A6}, /* channe1 02 */ + {(0x03 << 18) | 0x32143, (0x04 << 18) | 0x0aeee, (0x05 << 18) | 0x289A6}, /* channe1 03 */ + {(0x03 << 18) | 0x32142, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}, /* channe1 04 */ + {(0x03 << 18) | 0x31141, (0x04 << 18) | 0x08444, (0x05 << 18) | 0x289A6}, /* channe1 05 */ + {(0x03 << 18) | 0x31143, (0x04 << 18) | 0x0aeee, (0x05 << 18) | 0x289A6}, /* channe1 06 */ + {(0x03 << 18) | 0x31142, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}, /* channe1 07 */ + {(0x03 << 18) | 0x33141, (0x04 << 18) | 0x08444, (0x05 << 18) | 0x289A6}, /* channe1 08 */ + {(0x03 << 18) | 0x33143, (0x04 << 18) | 0x0aeee, (0x05 << 18) | 0x289A6}, /* channe1 09 */ + {(0x03 << 18) | 0x33142, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}, /* channe1 10 */ + {(0x03 << 18) | 0x30941, (0x04 << 18) | 0x08444, (0x05 << 18) | 0x289A6}, /* channe1 11 */ + {(0x03 << 18) | 0x30943, (0x04 << 18) | 0x0aeee, (0x05 << 18) | 0x289A6}, /* channe1 12 */ + {(0x03 << 18) | 0x30942, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}, /* channe1 13 */ + {(0x03 << 18) | 0x32941, (0x04 << 18) | 0x09999, (0x05 << 18) | 0x289A6} /* channel 14 (2484MHz) */ }; -u32 max2828_power_data_24[] = {(0x0C<<18)|0x0c000, (0x0C<<18)|0x0c100}; -u32 max2828_power_data_50[] = {(0x0C<<18)|0x0c000, (0x0C<<18)|0x0c100}; - -/****************************************************************************/ -// LA20040728 kevin -// MAX2829 (a/b/g) -u32 max2829_rf_data[] = -{ - (0x00<<18)|0x000a2, - (0x01<<18)|0x23520, - (0x02<<18)|0x13802, - (0x03<<18)|0x30142, - (0x04<<18)|0x0b333, - (0x05<<18)|0x28906, - (0x06<<18)|0x18008, - (0x07<<18)|0x3B500, - (0x08<<18)|0x05100, - (0x09<<18)|0x24f08, - (0x0A<<18)|0x14000, - (0x0B<<18)|0x37d80, - (0x0C<<18)|0x0F300 //TXVGA=51, (MAX-6 dB) +u32 max2828_channel_data_50[][3] = { + {(0x03 << 18) | 0x33cc3, (0x04 << 18) | 0x08ccc, (0x05 << 18) | 0x289A6}, /* channel 36 */ + {(0x03 << 18) | 0x302c0, (0x04 << 18) | 0x08000, (0x05 << 18) | 0x289A6}, /* channel 40 */ + {(0x03 << 18) | 0x302c2, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6}, /* channel 44 */ + {(0x03 << 18) | 0x322c1, (0x04 << 18) | 0x09999, (0x05 << 18) | 0x289A6}, /* channel 48 */ + {(0x03 << 18) | 0x312c1, (0x04 << 18) | 0x0a666, (0x05 << 18) | 0x289A6}, /* channel 52 */ + {(0x03 << 18) | 0x332c3, (0x04 << 18) | 0x08ccc, (0x05 << 18) | 0x289A6}, /* channel 56 */ + {(0x03 << 18) | 0x30ac0, (0x04 << 18) | 0x08000, (0x05 << 18) | 0x289A6}, /* channel 60 */ + {(0x03 << 18) | 0x30ac2, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x289A6} /* channel 64 */ }; -u32 max2829_channel_data_24[][3] = -{ - {(3<<18)|0x30142, (4<<18)|0x0b333, (5<<18)|0x289C6}, // 01 (2412MHz) - {(3<<18)|0x32141, (4<<18)|0x08444, (5<<18)|0x289C6}, // 02 (2417MHz) - {(3<<18)|0x32143, (4<<18)|0x0aeee, (5<<18)|0x289C6}, // 03 (2422MHz) - {(3<<18)|0x32142, (4<<18)|0x0b333, (5<<18)|0x289C6}, // 04 (2427MHz) - {(3<<18)|0x31141, (4<<18)|0x08444, (5<<18)|0x289C6}, // 05 (2432MHz) - {(3<<18)|0x31143, (4<<18)|0x0aeee, (5<<18)|0x289C6}, // 06 (2437MHz) - {(3<<18)|0x31142, (4<<18)|0x0b333, (5<<18)|0x289C6}, // 07 (2442MHz) - {(3<<18)|0x33141, (4<<18)|0x08444, (5<<18)|0x289C6}, // 08 (2447MHz) - {(3<<18)|0x33143, (4<<18)|0x0aeee, (5<<18)|0x289C6}, // 09 (2452MHz) - {(3<<18)|0x33142, (4<<18)|0x0b333, (5<<18)|0x289C6}, // 10 (2457MHz) - {(3<<18)|0x30941, (4<<18)|0x08444, (5<<18)|0x289C6}, // 11 (2462MHz) - {(3<<18)|0x30943, (4<<18)|0x0aeee, (5<<18)|0x289C6}, // 12 (2467MHz) - {(3<<18)|0x30942, (4<<18)|0x0b333, (5<<18)|0x289C6}, // 13 (2472MHz) - {(3<<18)|0x32941, (4<<18)|0x09999, (5<<18)|0x289C6}, // 14 (2484MHz) hh-modify +u32 max2828_power_data_24[] = {(0x0C << 18) | 0x0c000, (0x0C << 18) | 0x0c100}; +u32 max2828_power_data_50[] = {(0x0C << 18) | 0x0c000, (0x0C << 18) | 0x0c100}; + +/* ========================================================== */ +/* MAX2829 (a/b/g) */ +u32 max2829_rf_data[] = { + (0x00 << 18) | 0x000a2, + (0x01 << 18) | 0x23520, + (0x02 << 18) | 0x13802, + (0x03 << 18) | 0x30142, + (0x04 << 18) | 0x0b333, + (0x05 << 18) | 0x28906, + (0x06 << 18) | 0x18008, + (0x07 << 18) | 0x3B500, + (0x08 << 18) | 0x05100, + (0x09 << 18) | 0x24f08, + (0x0A << 18) | 0x14000, + (0x0B << 18) | 0x37d80, + (0x0C << 18) | 0x0F300 /* TXVGA=51, (MAX-6 dB) */ }; -u32 max2829_channel_data_50[][4] = -{ - {36, (3<<18)|0x33cc3, (4<<18)|0x08ccc, (5<<18)|0x2A946}, // 36 (5.180GHz) - {40, (3<<18)|0x302c0, (4<<18)|0x08000, (5<<18)|0x2A946}, // 40 (5.200GHz) - {44, (3<<18)|0x302c2, (4<<18)|0x0b333, (5<<18)|0x2A946}, // 44 (5.220GHz) - {48, (3<<18)|0x322c1, (4<<18)|0x09999, (5<<18)|0x2A946}, // 48 (5.240GHz) - {52, (3<<18)|0x312c1, (4<<18)|0x0a666, (5<<18)|0x2A946}, // 52 (5.260GHz) - {56, (3<<18)|0x332c3, (4<<18)|0x08ccc, (5<<18)|0x2A946}, // 56 (5.280GHz) - {60, (3<<18)|0x30ac0, (4<<18)|0x08000, (5<<18)|0x2A946}, // 60 (5.300GHz) - {64, (3<<18)|0x30ac2, (4<<18)|0x0b333, (5<<18)|0x2A946}, // 64 (5.320GHz) - - {100, (3<<18)|0x30ec0, (4<<18)|0x08000, (5<<18)|0x2A9C6}, // 100 (5.500GHz) - {104, (3<<18)|0x30ec2, (4<<18)|0x0b333, (5<<18)|0x2A9C6}, // 104 (5.520GHz) - {108, (3<<18)|0x32ec1, (4<<18)|0x09999, (5<<18)|0x2A9C6}, // 108 (5.540GHz) - {112, (3<<18)|0x31ec1, (4<<18)|0x0a666, (5<<18)|0x2A9C6}, // 112 (5.560GHz) - {116, (3<<18)|0x33ec3, (4<<18)|0x08ccc, (5<<18)|0x2A9C6}, // 116 (5.580GHz) - {120, (3<<18)|0x301c0, (4<<18)|0x08000, (5<<18)|0x2A9C6}, // 120 (5.600GHz) - {124, (3<<18)|0x301c2, (4<<18)|0x0b333, (5<<18)|0x2A9C6}, // 124 (5.620GHz) - {128, (3<<18)|0x321c1, (4<<18)|0x09999, (5<<18)|0x2A9C6}, // 128 (5.640GHz) - {132, (3<<18)|0x311c1, (4<<18)|0x0a666, (5<<18)|0x2A9C6}, // 132 (5.660GHz) - {136, (3<<18)|0x331c3, (4<<18)|0x08ccc, (5<<18)|0x2A9C6}, // 136 (5.680GHz) - {140, (3<<18)|0x309c0, (4<<18)|0x08000, (5<<18)|0x2A9C6}, // 140 (5.700GHz) - - {149, (3<<18)|0x329c2, (4<<18)|0x0b333, (5<<18)|0x2A9C6}, // 149 (5.745GHz) - {153, (3<<18)|0x319c1, (4<<18)|0x09999, (5<<18)|0x2A9C6}, // 153 (5.765GHz) - {157, (3<<18)|0x339c1, (4<<18)|0x0a666, (5<<18)|0x2A9C6}, // 157 (5.785GHz) - {161, (3<<18)|0x305c3, (4<<18)|0x08ccc, (5<<18)|0x2A9C6}, // 161 (5.805GHz) - - // Japan - { 184, (3<<18)|0x308c2, (4<<18)|0x0b333, (5<<18)|0x2A946}, // 184 (4.920GHz) - { 188, (3<<18)|0x328c1, (4<<18)|0x09999, (5<<18)|0x2A946}, // 188 (4.940GHz) - { 192, (3<<18)|0x318c1, (4<<18)|0x0a666, (5<<18)|0x2A946}, // 192 (4.960GHz) - { 196, (3<<18)|0x338c3, (4<<18)|0x08ccc, (5<<18)|0x2A946}, // 196 (4.980GHz) - { 8, (3<<18)|0x324c1, (4<<18)|0x09999, (5<<18)|0x2A946}, // 8 (5.040GHz) - { 12, (3<<18)|0x314c1, (4<<18)|0x0a666, (5<<18)|0x2A946}, // 12 (5.060GHz) - { 16, (3<<18)|0x334c3, (4<<18)|0x08ccc, (5<<18)|0x2A946}, // 16 (5.080GHz) - { 34, (3<<18)|0x31cc2, (4<<18)|0x0b333, (5<<18)|0x2A946}, // 34 (5.170GHz) - { 38, (3<<18)|0x33cc1, (4<<18)|0x09999, (5<<18)|0x2A946}, // 38 (5.190GHz) - { 42, (3<<18)|0x302c1, (4<<18)|0x0a666, (5<<18)|0x2A946}, // 42 (5.210GHz) - { 46, (3<<18)|0x322c3, (4<<18)|0x08ccc, (5<<18)|0x2A946}, // 46 (5.230GHz) +u32 max2829_channel_data_24[][3] = { + {(3 << 18) | 0x30142, (4 << 18) | 0x0b333, (5 << 18) | 0x289C6}, /* 01 (2412MHz) */ + {(3 << 18) | 0x32141, (4 << 18) | 0x08444, (5 << 18) | 0x289C6}, /* 02 (2417MHz) */ + {(3 << 18) | 0x32143, (4 << 18) | 0x0aeee, (5 << 18) | 0x289C6}, /* 03 (2422MHz) */ + {(3 << 18) | 0x32142, (4 << 18) | 0x0b333, (5 << 18) | 0x289C6}, /* 04 (2427MHz) */ + {(3 << 18) | 0x31141, (4 << 18) | 0x08444, (5 << 18) | 0x289C6}, /* 05 (2432MHz) */ + {(3 << 18) | 0x31143, (4 << 18) | 0x0aeee, (5 << 18) | 0x289C6}, /* 06 (2437MHz) */ + {(3 << 18) | 0x31142, (4 << 18) | 0x0b333, (5 << 18) | 0x289C6}, /* 07 (2442MHz) */ + {(3 << 18) | 0x33141, (4 << 18) | 0x08444, (5 << 18) | 0x289C6}, /* 08 (2447MHz) */ + {(3 << 18) | 0x33143, (4 << 18) | 0x0aeee, (5 << 18) | 0x289C6}, /* 09 (2452MHz) */ + {(3 << 18) | 0x33142, (4 << 18) | 0x0b333, (5 << 18) | 0x289C6}, /* 10 (2457MHz) */ + {(3 << 18) | 0x30941, (4 << 18) | 0x08444, (5 << 18) | 0x289C6}, /* 11 (2462MHz) */ + {(3 << 18) | 0x30943, (4 << 18) | 0x0aeee, (5 << 18) | 0x289C6}, /* 12 (2467MHz) */ + {(3 << 18) | 0x30942, (4 << 18) | 0x0b333, (5 << 18) | 0x289C6}, /* 13 (2472MHz) */ + {(3 << 18) | 0x32941, (4 << 18) | 0x09999, (5 << 18) | 0x289C6}, /* 14 (2484MHz) */ }; -/***************************************************************************** -; For MAXIM2825/6/7 Ver. 317 or less -; Edited by Tiger, Sep-17-2003 for 2.4Ghz channels -; Updated by Tiger, Sep-22-2003 for 5.0Ghz channels -; Corrected by Tiger, Sep-23-2003, for 0x03 and 0x04 of 5.0Ghz channels - -0x00 0x00080 -0x01 0x214c0 -0x02 0x13802 - -;2.4GHz Channels -;channe1 01 (2.412GHz); 0x03 0x30143 ;0x04 0x0accc -;channe1 02 (2.417GHz); 0x03 0x32140 ;0x04 0x09111 -;channe1 03 (2.422GHz); 0x03 0x32142 ;0x04 0x0bbbb -;channe1 04 (2.427GHz); 0x03 0x32143 ;0x04 0x0accc -;channe1 05 (2.432GHz); 0x03 0x31140 ;0x04 0x09111 -;channe1 06 (2.437GHz); 0x03 0x31142 ;0x04 0x0bbbb -;channe1 07 (2.442GHz); 0x03 0x31143 ;0x04 0x0accc -;channe1 08 (2.447GHz); 0x03 0x33140 ;0x04 0x09111 -;channe1 09 (2.452GHz); 0x03 0x33142 ;0x04 0x0bbbb -;channe1 10 (2.457GHz); 0x03 0x33143 ;0x04 0x0accc -;channe1 11 (2.462GHz); 0x03 0x30940 ;0x04 0x09111 -;channe1 12 (2.467GHz); 0x03 0x30942 ;0x04 0x0bbbb -;channe1 13 (2.472GHz); 0x03 0x30943 ;0x04 0x0accc - -;5.0Ghz Channels -;channel 36 (5.180GHz); 0x03 0x33cc0 ;0x04 0x0b333 -;channel 40 (5.200GHz); 0x03 0x302c0 ;0x04 0x08000 -;channel 44 (5.220GHz); 0x03 0x302c2 ;0x04 0x0b333 -;channel 48 (5.240GHz); 0x03 0x322c1 ;0x04 0x09999 -;channel 52 (5.260GHz); 0x03 0x312c1 ;0x04 0x0a666 -;channel 56 (5.280GHz); 0x03 0x332c3 ;0x04 0x08ccc -;channel 60 (5.300GHz); 0x03 0x30ac0 ;0x04 0x08000 -;channel 64 (5.320GHz); 0x03 0x30ac2 ;0x04 0x08333 - -;2.4GHz band ;0x05 0x28986; -;5.0GHz band -0x05 0x2a986 - -0x06 0x18008 -0x07 0x38400 -0x08 0x05108 -0x09 0x27ff8 -0x0a 0x14000 -0x0b 0x37f99 -0x0c 0x0c000 -*****************************************************************************/ -u32 maxim_317_rf_data[] = -{ - (0x00<<18)|0x000a2, - (0x01<<18)|0x214c0, - (0x02<<18)|0x13802, - (0x03<<18)|0x30143, - (0x04<<18)|0x0accc, - (0x05<<18)|0x28986, - (0x06<<18)|0x18008, - (0x07<<18)|0x38400, - (0x08<<18)|0x05108, - (0x09<<18)|0x27ff8, - (0x0A<<18)|0x14000, - (0x0B<<18)|0x37f99, - (0x0C<<18)|0x0c000 +u32 max2829_channel_data_50[][4] = { + {36, (3 << 18) | 0x33cc3, (4 << 18) | 0x08ccc, (5 << 18) | 0x2A946}, /* 36 (5.180GHz) */ + {40, (3 << 18) | 0x302c0, (4 << 18) | 0x08000, (5 << 18) | 0x2A946}, /* 40 (5.200GHz) */ + {44, (3 << 18) | 0x302c2, (4 << 18) | 0x0b333, (5 << 18) | 0x2A946}, /* 44 (5.220GHz) */ + {48, (3 << 18) | 0x322c1, (4 << 18) | 0x09999, (5 << 18) | 0x2A946}, /* 48 (5.240GHz) */ + {52, (3 << 18) | 0x312c1, (4 << 18) | 0x0a666, (5 << 18) | 0x2A946}, /* 52 (5.260GHz) */ + {56, (3 << 18) | 0x332c3, (4 << 18) | 0x08ccc, (5 << 18) | 0x2A946}, /* 56 (5.280GHz) */ + {60, (3 << 18) | 0x30ac0, (4 << 18) | 0x08000, (5 << 18) | 0x2A946}, /* 60 (5.300GHz) */ + {64, (3 << 18) | 0x30ac2, (4 << 18) | 0x0b333, (5 << 18) | 0x2A946}, /* 64 (5.320GHz) */ + + {100, (3 << 18) | 0x30ec0, (4 << 18) | 0x08000, (5 << 18) | 0x2A9C6}, /* 100 (5.500GHz) */ + {104, (3 << 18) | 0x30ec2, (4 << 18) | 0x0b333, (5 << 18) | 0x2A9C6}, /* 104 (5.520GHz) */ + {108, (3 << 18) | 0x32ec1, (4 << 18) | 0x09999, (5 << 18) | 0x2A9C6}, /* 108 (5.540GHz) */ + {112, (3 << 18) | 0x31ec1, (4 << 18) | 0x0a666, (5 << 18) | 0x2A9C6}, /* 112 (5.560GHz) */ + {116, (3 << 18) | 0x33ec3, (4 << 18) | 0x08ccc, (5 << 18) | 0x2A9C6}, /* 116 (5.580GHz) */ + {120, (3 << 18) | 0x301c0, (4 << 18) | 0x08000, (5 << 18) | 0x2A9C6}, /* 120 (5.600GHz) */ + {124, (3 << 18) | 0x301c2, (4 << 18) | 0x0b333, (5 << 18) | 0x2A9C6}, /* 124 (5.620GHz) */ + {128, (3 << 18) | 0x321c1, (4 << 18) | 0x09999, (5 << 18) | 0x2A9C6}, /* 128 (5.640GHz) */ + {132, (3 << 18) | 0x311c1, (4 << 18) | 0x0a666, (5 << 18) | 0x2A9C6}, /* 132 (5.660GHz) */ + {136, (3 << 18) | 0x331c3, (4 << 18) | 0x08ccc, (5 << 18) | 0x2A9C6}, /* 136 (5.680GHz) */ + {140, (3 << 18) | 0x309c0, (4 << 18) | 0x08000, (5 << 18) | 0x2A9C6}, /* 140 (5.700GHz) */ + + {149, (3 << 18) | 0x329c2, (4 << 18) | 0x0b333, (5 << 18) | 0x2A9C6}, /* 149 (5.745GHz) */ + {153, (3 << 18) | 0x319c1, (4 << 18) | 0x09999, (5 << 18) | 0x2A9C6}, /* 153 (5.765GHz) */ + {157, (3 << 18) | 0x339c1, (4 << 18) | 0x0a666, (5 << 18) | 0x2A9C6}, /* 157 (5.785GHz) */ + {161, (3 << 18) | 0x305c3, (4 << 18) | 0x08ccc, (5 << 18) | 0x2A9C6}, /* 161 (5.805GHz) */ + + /* Japan */ + { 184, (3 << 18) | 0x308c2, (4 << 18) | 0x0b333, (5 << 18) | 0x2A946}, /* 184 (4.920GHz) */ + { 188, (3 << 18) | 0x328c1, (4 << 18) | 0x09999, (5 << 18) | 0x2A946}, /* 188 (4.940GHz) */ + { 192, (3 << 18) | 0x318c1, (4 << 18) | 0x0a666, (5 << 18) | 0x2A946}, /* 192 (4.960GHz) */ + { 196, (3 << 18) | 0x338c3, (4 << 18) | 0x08ccc, (5 << 18) | 0x2A946}, /* 196 (4.980GHz) */ + { 8, (3 << 18) | 0x324c1, (4 << 18) | 0x09999, (5 << 18) | 0x2A946}, /* 8 (5.040GHz) */ + { 12, (3 << 18) | 0x314c1, (4 << 18) | 0x0a666, (5 << 18) | 0x2A946}, /* 12 (5.060GHz) */ + { 16, (3 << 18) | 0x334c3, (4 << 18) | 0x08ccc, (5 << 18) | 0x2A946}, /* 16 (5.080GHz) */ + { 34, (3 << 18) | 0x31cc2, (4 << 18) | 0x0b333, (5 << 18) | 0x2A946}, /* 34 (5.170GHz) */ + { 38, (3 << 18) | 0x33cc1, (4 << 18) | 0x09999, (5 << 18) | 0x2A946}, /* 38 (5.190GHz) */ + { 42, (3 << 18) | 0x302c1, (4 << 18) | 0x0a666, (5 << 18) | 0x2A946}, /* 42 (5.210GHz) */ + { 46, (3 << 18) | 0x322c3, (4 << 18) | 0x08ccc, (5 << 18) | 0x2A946}, /* 46 (5.230GHz) */ }; -u32 maxim_317_channel_data_24[][3] = -{ - {(0x03<<18)|0x30143, (0x04<<18)|0x0accc, (0x05<<18)|0x28986}, // channe1 01 - {(0x03<<18)|0x32140, (0x04<<18)|0x09111, (0x05<<18)|0x28986}, // channe1 02 - {(0x03<<18)|0x32142, (0x04<<18)|0x0bbbb, (0x05<<18)|0x28986}, // channe1 03 - {(0x03<<18)|0x32143, (0x04<<18)|0x0accc, (0x05<<18)|0x28986}, // channe1 04 - {(0x03<<18)|0x31140, (0x04<<18)|0x09111, (0x05<<18)|0x28986}, // channe1 05 - {(0x03<<18)|0x31142, (0x04<<18)|0x0bbbb, (0x05<<18)|0x28986}, // channe1 06 - {(0x03<<18)|0x31143, (0x04<<18)|0x0accc, (0x05<<18)|0x28986}, // channe1 07 - {(0x03<<18)|0x33140, (0x04<<18)|0x09111, (0x05<<18)|0x28986}, // channe1 08 - {(0x03<<18)|0x33142, (0x04<<18)|0x0bbbb, (0x05<<18)|0x28986}, // channe1 09 - {(0x03<<18)|0x33143, (0x04<<18)|0x0accc, (0x05<<18)|0x28986}, // channe1 10 - {(0x03<<18)|0x30940, (0x04<<18)|0x09111, (0x05<<18)|0x28986}, // channe1 11 - {(0x03<<18)|0x30942, (0x04<<18)|0x0bbbb, (0x05<<18)|0x28986}, // channe1 12 - {(0x03<<18)|0x30943, (0x04<<18)|0x0accc, (0x05<<18)|0x28986} // channe1 13 +/* + * ==================================================================== + * For MAXIM2825/6/7 Ver. 317 or less + * + * 0x00 0x00080 + * 0x01 0x214c0 + * 0x02 0x13802 + * + * 2.4GHz Channels + * channe1 01 (2.412GHz); 0x03 0x30143 ;0x04 0x0accc + * channe1 02 (2.417GHz); 0x03 0x32140 ;0x04 0x09111 + * channe1 03 (2.422GHz); 0x03 0x32142 ;0x04 0x0bbbb + * channe1 04 (2.427GHz); 0x03 0x32143 ;0x04 0x0accc + * channe1 05 (2.432GHz); 0x03 0x31140 ;0x04 0x09111 + * channe1 06 (2.437GHz); 0x03 0x31142 ;0x04 0x0bbbb + * channe1 07 (2.442GHz); 0x03 0x31143 ;0x04 0x0accc + * channe1 08 (2.447GHz); 0x03 0x33140 ;0x04 0x09111 + * channe1 09 (2.452GHz); 0x03 0x33142 ;0x04 0x0bbbb + * channe1 10 (2.457GHz); 0x03 0x33143 ;0x04 0x0accc + * channe1 11 (2.462GHz); 0x03 0x30940 ;0x04 0x09111 + * channe1 12 (2.467GHz); 0x03 0x30942 ;0x04 0x0bbbb + * channe1 13 (2.472GHz); 0x03 0x30943 ;0x04 0x0accc + * + * 5.0Ghz Channels + * channel 36 (5.180GHz); 0x03 0x33cc0 ;0x04 0x0b333 + * channel 40 (5.200GHz); 0x03 0x302c0 ;0x04 0x08000 + * channel 44 (5.220GHz); 0x03 0x302c2 ;0x04 0x0b333 + * channel 48 (5.240GHz); 0x03 0x322c1 ;0x04 0x09999 + * channel 52 (5.260GHz); 0x03 0x312c1 ;0x04 0x0a666 + * channel 56 (5.280GHz); 0x03 0x332c3 ;0x04 0x08ccc + * channel 60 (5.300GHz); 0x03 0x30ac0 ;0x04 0x08000 + * channel 64 (5.320GHz); 0x03 0x30ac2 ;0x04 0x08333 + * + * 2.4GHz band ; 0x05 0x28986; + * 5.0GHz band ; 0x05 0x2a986 + * 0x06 0x18008 + * 0x07 0x38400 + * 0x08 0x05108 + * 0x09 0x27ff8 + * 0x0a 0x14000 + * 0x0b 0x37f99 + * 0x0c 0x0c000 + * ==================================================================== + */ +u32 maxim_317_rf_data[] = { + (0x00 << 18) | 0x000a2, + (0x01 << 18) | 0x214c0, + (0x02 << 18) | 0x13802, + (0x03 << 18) | 0x30143, + (0x04 << 18) | 0x0accc, + (0x05 << 18) | 0x28986, + (0x06 << 18) | 0x18008, + (0x07 << 18) | 0x38400, + (0x08 << 18) | 0x05108, + (0x09 << 18) | 0x27ff8, + (0x0A << 18) | 0x14000, + (0x0B << 18) | 0x37f99, + (0x0C << 18) | 0x0c000 }; -u32 maxim_317_channel_data_50[][3] = -{ - {(0x03<<18)|0x33cc0, (0x04<<18)|0x0b333, (0x05<<18)|0x2a986}, // channel 36 - {(0x03<<18)|0x302c0, (0x04<<18)|0x08000, (0x05<<18)|0x2a986}, // channel 40 - {(0x03<<18)|0x302c3, (0x04<<18)|0x0accc, (0x05<<18)|0x2a986}, // channel 44 - {(0x03<<18)|0x322c1, (0x04<<18)|0x09666, (0x05<<18)|0x2a986}, // channel 48 - {(0x03<<18)|0x312c2, (0x04<<18)|0x09999, (0x05<<18)|0x2a986}, // channel 52 - {(0x03<<18)|0x332c0, (0x04<<18)|0x0b333, (0x05<<18)|0x2a99e}, // channel 56 - {(0x03<<18)|0x30ac0, (0x04<<18)|0x08000, (0x05<<18)|0x2a99e}, // channel 60 - {(0x03<<18)|0x30ac3, (0x04<<18)|0x0accc, (0x05<<18)|0x2a99e} // channel 64 +u32 maxim_317_channel_data_24[][3] = { + {(0x03 << 18) | 0x30143, (0x04 << 18) | 0x0accc, (0x05 << 18) | 0x28986}, /* channe1 01 */ + {(0x03 << 18) | 0x32140, (0x04 << 18) | 0x09111, (0x05 << 18) | 0x28986}, /* channe1 02 */ + {(0x03 << 18) | 0x32142, (0x04 << 18) | 0x0bbbb, (0x05 << 18) | 0x28986}, /* channe1 03 */ + {(0x03 << 18) | 0x32143, (0x04 << 18) | 0x0accc, (0x05 << 18) | 0x28986}, /* channe1 04 */ + {(0x03 << 18) | 0x31140, (0x04 << 18) | 0x09111, (0x05 << 18) | 0x28986}, /* channe1 05 */ + {(0x03 << 18) | 0x31142, (0x04 << 18) | 0x0bbbb, (0x05 << 18) | 0x28986}, /* channe1 06 */ + {(0x03 << 18) | 0x31143, (0x04 << 18) | 0x0accc, (0x05 << 18) | 0x28986}, /* channe1 07 */ + {(0x03 << 18) | 0x33140, (0x04 << 18) | 0x09111, (0x05 << 18) | 0x28986}, /* channe1 08 */ + {(0x03 << 18) | 0x33142, (0x04 << 18) | 0x0bbbb, (0x05 << 18) | 0x28986}, /* channe1 09 */ + {(0x03 << 18) | 0x33143, (0x04 << 18) | 0x0accc, (0x05 << 18) | 0x28986}, /* channe1 10 */ + {(0x03 << 18) | 0x30940, (0x04 << 18) | 0x09111, (0x05 << 18) | 0x28986}, /* channe1 11 */ + {(0x03 << 18) | 0x30942, (0x04 << 18) | 0x0bbbb, (0x05 << 18) | 0x28986}, /* channe1 12 */ + {(0x03 << 18) | 0x30943, (0x04 << 18) | 0x0accc, (0x05 << 18) | 0x28986} /* channe1 13 */ }; -u32 maxim_317_power_data_24[] = {(0x0C<<18)|0x0c000, (0x0C<<18)|0x0c100}; -u32 maxim_317_power_data_50[] = {(0x0C<<18)|0x0c000, (0x0C<<18)|0x0c100}; - -/***************************************************************************** -;;AL2230 MP (Mass Production Version) -;;RF Registers Setting for Airoha AL2230 silicon after June 1st, 2004 -;;Updated by Tiger Huang (June 1st, 2004) -;;20-bit length and LSB first - -;;Ch01 (2412MHz) ;0x00 0x09EFC ;0x01 0x8CCCC; -;;Ch02 (2417MHz) ;0x00 0x09EFC ;0x01 0x8CCCD; -;;Ch03 (2422MHz) ;0x00 0x09E7C ;0x01 0x8CCCC; -;;Ch04 (2427MHz) ;0x00 0x09E7C ;0x01 0x8CCCD; -;;Ch05 (2432MHz) ;0x00 0x05EFC ;0x01 0x8CCCC; -;;Ch06 (2437MHz) ;0x00 0x05EFC ;0x01 0x8CCCD; -;;Ch07 (2442MHz) ;0x00 0x05E7C ;0x01 0x8CCCC; -;;Ch08 (2447MHz) ;0x00 0x05E7C ;0x01 0x8CCCD; -;;Ch09 (2452MHz) ;0x00 0x0DEFC ;0x01 0x8CCCC; -;;Ch10 (2457MHz) ;0x00 0x0DEFC ;0x01 0x8CCCD; -;;Ch11 (2462MHz) ;0x00 0x0DE7C ;0x01 0x8CCCC; -;;Ch12 (2467MHz) ;0x00 0x0DE7C ;0x01 0x8CCCD; -;;Ch13 (2472MHz) ;0x00 0x03EFC ;0x01 0x8CCCC; -;;Ch14 (2484Mhz) ;0x00 0x03E7C ;0x01 0x86666; - -0x02 0x401D8; RXDCOC BW 100Hz for RXHP low -;;0x02 0x481DC; RXDCOC BW 30Khz for RXHP low - -0x03 0xCFFF0 -0x04 0x23800 -0x05 0xA3B72 -0x06 0x6DA01 -0x07 0xE1688 -0x08 0x11600 -0x09 0x99E02 -0x0A 0x5DDB0 -0x0B 0xD9900 -0x0C 0x3FFBD -0x0D 0xB0000 -0x0F 0xF00A0 - -;RF Calibration for Airoha AL2230 -;Edit by Ben Chang (01/30/04) -;Updated by Tiger Huang (03/03/04) -0x0f 0xf00a0 ; Initial Setting -0x0f 0xf00b0 ; Activate TX DCC -0x0f 0xf02a0 ; Activate Phase Calibration -0x0f 0xf00e0 ; Activate Filter RC Calibration -0x0f 0xf00a0 ; Restore Initial Setting -*****************************************************************************/ - -u32 al2230_rf_data[] = -{ - (0x00<<20)|0x09EFC, - (0x01<<20)|0x8CCCC, - (0x02<<20)|0x40058,// 20060627 Anson 0x401D8, - (0x03<<20)|0xCFFF0, - (0x04<<20)|0x24100,// 20060627 Anson 0x23800, - (0x05<<20)|0xA3B2F,// 20060627 Anson 0xA3B72 - (0x06<<20)|0x6DA01, - (0x07<<20)|0xE3628,// 20060627 Anson 0xE1688, - (0x08<<20)|0x11600, - (0x09<<20)|0x9DC02,// 20060627 Anosn 0x97602,//0x99E02, //0x9AE02 - (0x0A<<20)|0x5ddb0, // 941206 For QCOM interference 0x588b0,//0x5DDB0, 940601 adj 0x5aa30 for bluetooth - (0x0B<<20)|0xD9900, - (0x0C<<20)|0x3FFBD, - (0x0D<<20)|0xB0000, - (0x0F<<20)|0xF01A0 // 20060627 Anson 0xF00A0 +u32 maxim_317_channel_data_50[][3] = { + {(0x03 << 18) | 0x33cc0, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x2a986}, /* channel 36 */ + {(0x03 << 18) | 0x302c0, (0x04 << 18) | 0x08000, (0x05 << 18) | 0x2a986}, /* channel 40 */ + {(0x03 << 18) | 0x302c3, (0x04 << 18) | 0x0accc, (0x05 << 18) | 0x2a986}, /* channel 44 */ + {(0x03 << 18) | 0x322c1, (0x04 << 18) | 0x09666, (0x05 << 18) | 0x2a986}, /* channel 48 */ + {(0x03 << 18) | 0x312c2, (0x04 << 18) | 0x09999, (0x05 << 18) | 0x2a986}, /* channel 52 */ + {(0x03 << 18) | 0x332c0, (0x04 << 18) | 0x0b333, (0x05 << 18) | 0x2a99e}, /* channel 56 */ + {(0x03 << 18) | 0x30ac0, (0x04 << 18) | 0x08000, (0x05 << 18) | 0x2a99e}, /* channel 60 */ + {(0x03 << 18) | 0x30ac3, (0x04 << 18) | 0x0accc, (0x05 << 18) | 0x2a99e} /* channel 64 */ }; -u32 al2230s_rf_data[] = -{ - (0x00<<20)|0x09EFC, - (0x01<<20)|0x8CCCC, - (0x02<<20)|0x40058,// 20060419 0x401D8, - (0x03<<20)|0xCFFF0, - (0x04<<20)|0x24100,// 20060419 0x23800, - (0x05<<20)|0xA3B2F,// 20060419 0xA3B72, - (0x06<<20)|0x6DA01, - (0x07<<20)|0xE3628,// 20060419 0xE1688, - (0x08<<20)|0x11600, - (0x09<<20)|0x9DC02,// 20060419 0x97602,//0x99E02, //0x9AE02 - (0x0A<<20)|0x5DDB0,// 941206 For QCOM interference 0x588b0,//0x5DDB0, 940601 adj 0x5aa30 for bluetooth - (0x0B<<20)|0xD9900, - (0x0C<<20)|0x3FFBD, - (0x0D<<20)|0xB0000, - (0x0F<<20)|0xF01A0 // 20060419 0xF00A0 +u32 maxim_317_power_data_24[] = {(0x0C << 18) | 0x0c000, (0x0C << 18) | 0x0c100}; +u32 maxim_317_power_data_50[] = {(0x0C << 18) | 0x0c000, (0x0C << 18) | 0x0c100}; + +/* + * =================================================================== + * AL2230 MP (Mass Production Version) + * RF Registers Setting for Airoha AL2230 silicon after June 1st, 2004 + * 20-bit length and LSB first + * + * Ch01 (2412MHz) ;0x00 0x09EFC ;0x01 0x8CCCC; + * Ch02 (2417MHz) ;0x00 0x09EFC ;0x01 0x8CCCD; + * Ch03 (2422MHz) ;0x00 0x09E7C ;0x01 0x8CCCC; + * Ch04 (2427MHz) ;0x00 0x09E7C ;0x01 0x8CCCD; + * Ch05 (2432MHz) ;0x00 0x05EFC ;0x01 0x8CCCC; + * Ch06 (2437MHz) ;0x00 0x05EFC ;0x01 0x8CCCD; + * Ch07 (2442MHz) ;0x00 0x05E7C ;0x01 0x8CCCC; + * Ch08 (2447MHz) ;0x00 0x05E7C ;0x01 0x8CCCD; + * Ch09 (2452MHz) ;0x00 0x0DEFC ;0x01 0x8CCCC; + * Ch10 (2457MHz) ;0x00 0x0DEFC ;0x01 0x8CCCD; + * Ch11 (2462MHz) ;0x00 0x0DE7C ;0x01 0x8CCCC; + * Ch12 (2467MHz) ;0x00 0x0DE7C ;0x01 0x8CCCD; + * Ch13 (2472MHz) ;0x00 0x03EFC ;0x01 0x8CCCC; + * Ch14 (2484Mhz) ;0x00 0x03E7C ;0x01 0x86666; + * + * 0x02 0x401D8; RXDCOC BW 100Hz for RXHP low + * 0x02 0x481DC; RXDCOC BW 30Khz for RXHP low + * + * 0x03 0xCFFF0 + * 0x04 0x23800 + * 0x05 0xA3B72 + * 0x06 0x6DA01 + * 0x07 0xE1688 + * 0x08 0x11600 + * 0x09 0x99E02 + * 0x0A 0x5DDB0 + * 0x0B 0xD9900 + * 0x0C 0x3FFBD + * 0x0D 0xB0000 + * 0x0F 0xF00A0 + * + * RF Calibration for Airoha AL2230 + * + * 0x0f 0xf00a0 ; Initial Setting + * 0x0f 0xf00b0 ; Activate TX DCC + * 0x0f 0xf02a0 ; Activate Phase Calibration + * 0x0f 0xf00e0 ; Activate Filter RC Calibration + * 0x0f 0xf00a0 ; Restore Initial Setting + * ================================================================== + */ +u32 al2230_rf_data[] = { + (0x00 << 20) | 0x09EFC, + (0x01 << 20) | 0x8CCCC, + (0x02 << 20) | 0x40058, + (0x03 << 20) | 0xCFFF0, + (0x04 << 20) | 0x24100, + (0x05 << 20) | 0xA3B2F, + (0x06 << 20) | 0x6DA01, + (0x07 << 20) | 0xE3628, + (0x08 << 20) | 0x11600, + (0x09 << 20) | 0x9DC02, + (0x0A << 20) | 0x5ddb0, + (0x0B << 20) | 0xD9900, + (0x0C << 20) | 0x3FFBD, + (0x0D << 20) | 0xB0000, + (0x0F << 20) | 0xF01A0 }; -u32 al2230_channel_data_24[][2] = -{ - {(0x00<<20)|0x09EFC, (0x01<<20)|0x8CCCC}, // channe1 01 - {(0x00<<20)|0x09EFC, (0x01<<20)|0x8CCCD}, // channe1 02 - {(0x00<<20)|0x09E7C, (0x01<<20)|0x8CCCC}, // channe1 03 - {(0x00<<20)|0x09E7C, (0x01<<20)|0x8CCCD}, // channe1 04 - {(0x00<<20)|0x05EFC, (0x01<<20)|0x8CCCC}, // channe1 05 - {(0x00<<20)|0x05EFC, (0x01<<20)|0x8CCCD}, // channe1 06 - {(0x00<<20)|0x05E7C, (0x01<<20)|0x8CCCC}, // channe1 07 - {(0x00<<20)|0x05E7C, (0x01<<20)|0x8CCCD}, // channe1 08 - {(0x00<<20)|0x0DEFC, (0x01<<20)|0x8CCCC}, // channe1 09 - {(0x00<<20)|0x0DEFC, (0x01<<20)|0x8CCCD}, // channe1 10 - {(0x00<<20)|0x0DE7C, (0x01<<20)|0x8CCCC}, // channe1 11 - {(0x00<<20)|0x0DE7C, (0x01<<20)|0x8CCCD}, // channe1 12 - {(0x00<<20)|0x03EFC, (0x01<<20)|0x8CCCC}, // channe1 13 - {(0x00<<20)|0x03E7C, (0x01<<20)|0x86666} // channe1 14 +u32 al2230s_rf_data[] = { + (0x00 << 20) | 0x09EFC, + (0x01 << 20) | 0x8CCCC, + (0x02 << 20) | 0x40058, + (0x03 << 20) | 0xCFFF0, + (0x04 << 20) | 0x24100, + (0x05 << 20) | 0xA3B2F, + (0x06 << 20) | 0x6DA01, + (0x07 << 20) | 0xE3628, + (0x08 << 20) | 0x11600, + (0x09 << 20) | 0x9DC02, + (0x0A << 20) | 0x5DDB0, + (0x0B << 20) | 0xD9900, + (0x0C << 20) | 0x3FFBD, + (0x0D << 20) | 0xB0000, + (0x0F << 20) | 0xF01A0 }; -// Current setting. u32 airoha_power_data_24[] = {(0x09<<20)|0x90202, (0x09<<20)|0x96602, (0x09<<20)|0x97602}; -#define AIROHA_TXVGA_LOW_INDEX 31 // Index for 0x90202 -#define AIROHA_TXVGA_MIDDLE_INDEX 12 // Index for 0x96602 -#define AIROHA_TXVGA_HIGH_INDEX 8 // Index for 0x97602 1.0.24.0 1.0.28.0 -/* -u32 airoha_power_data_24[] = -{ - 0x9FE02, // Max - 0 dB - 0x9BE02, // Max - 1 dB - 0x9DE02, // Max - 2 dB - 0x99E02, // Max - 3 dB - 0x9EE02, // Max - 4 dB - 0x9AE02, // Max - 5 dB - 0x9CE02, // Max - 6 dB - 0x98E02, // Max - 7 dB - 0x97602, // Max - 8 dB - 0x93602, // Max - 9 dB - 0x95602, // Max - 10 dB - 0x91602, // Max - 11 dB - 0x96602, // Max - 12 dB - 0x92602, // Max - 13 dB - 0x94602, // Max - 14 dB - 0x90602, // Max - 15 dB - 0x97A02, // Max - 16 dB - 0x93A02, // Max - 17 dB - 0x95A02, // Max - 18 dB - 0x91A02, // Max - 19 dB - 0x96A02, // Max - 20 dB - 0x92A02, // Max - 21 dB - 0x94A02, // Max - 22 dB - 0x90A02, // Max - 23 dB - 0x97202, // Max - 24 dB - 0x93202, // Max - 25 dB - 0x95202, // Max - 26 dB - 0x91202, // Max - 27 dB - 0x96202, // Max - 28 dB - 0x92202, // Max - 29 dB - 0x94202, // Max - 30 dB - 0x90202 // Max - 31 dB +u32 al2230_channel_data_24[][2] = { + {(0x00 << 20) | 0x09EFC, (0x01 << 20) | 0x8CCCC}, /* channe1 01 */ + {(0x00 << 20) | 0x09EFC, (0x01 << 20) | 0x8CCCD}, /* channe1 02 */ + {(0x00 << 20) | 0x09E7C, (0x01 << 20) | 0x8CCCC}, /* channe1 03 */ + {(0x00 << 20) | 0x09E7C, (0x01 << 20) | 0x8CCCD}, /* channe1 04 */ + {(0x00 << 20) | 0x05EFC, (0x01 << 20) | 0x8CCCC}, /* channe1 05 */ + {(0x00 << 20) | 0x05EFC, (0x01 << 20) | 0x8CCCD}, /* channe1 06 */ + {(0x00 << 20) | 0x05E7C, (0x01 << 20) | 0x8CCCC}, /* channe1 07 */ + {(0x00 << 20) | 0x05E7C, (0x01 << 20) | 0x8CCCD}, /* channe1 08 */ + {(0x00 << 20) | 0x0DEFC, (0x01 << 20) | 0x8CCCC}, /* channe1 09 */ + {(0x00 << 20) | 0x0DEFC, (0x01 << 20) | 0x8CCCD}, /* channe1 10 */ + {(0x00 << 20) | 0x0DE7C, (0x01 << 20) | 0x8CCCC}, /* channe1 11 */ + {(0x00 << 20) | 0x0DE7C, (0x01 << 20) | 0x8CCCD}, /* channe1 12 */ + {(0x00 << 20) | 0x03EFC, (0x01 << 20) | 0x8CCCC}, /* channe1 13 */ + {(0x00 << 20) | 0x03E7C, (0x01 << 20) | 0x86666} /* channe1 14 */ }; -*/ -// 20040927 1.1.69.1000 ybjiang -// from John -u32 al2230_txvga_data[][2] = -{ - //value , index +/* Current setting. u32 airoha_power_data_24[] = {(0x09 << 20) | 0x90202, (0x09 << 20) | 0x96602, (0x09 << 20) | 0x97602}; */ +#define AIROHA_TXVGA_LOW_INDEX 31 /* Index for 0x90202 */ +#define AIROHA_TXVGA_MIDDLE_INDEX 12 /* Index for 0x96602 */ +#define AIROHA_TXVGA_HIGH_INDEX 8 /* Index for 0x97602 1.0.24.0 1.0.28.0 */ + +u32 al2230_txvga_data[][2] = { + /* value , index */ {0x090202, 0}, {0x094202, 2}, {0x092202, 4}, @@ -551,263 +489,242 @@ u32 al2230_txvga_data[][2] = {0x09FE02, 63} }; -//-------------------------------- -// For Airoha AL7230, 2.4Ghz band -// Edit by Tiger, (March, 9, 2005) -// 24bit, MSB first - -//channel independent registers: -u32 al7230_rf_data_24[] = -{ - (0x00<<24)|0x003790, - (0x01<<24)|0x133331, - (0x02<<24)|0x841FF2, - (0x03<<24)|0x3FDFA3, - (0x04<<24)|0x7FD784, - (0x05<<24)|0x802B55, - (0x06<<24)|0x56AF36, - (0x07<<24)|0xCE0207, - (0x08<<24)|0x6EBC08, - (0x09<<24)|0x221BB9, - (0x0A<<24)|0xE0000A, - (0x0B<<24)|0x08071B, - (0x0C<<24)|0x000A3C, - (0x0D<<24)|0xFFFFFD, - (0x0E<<24)|0x00000E, - (0x0F<<24)|0x1ABA8F +/* + * ========================================== + * For Airoha AL7230, 2.4Ghz band + * 24bit, MSB first + */ + +/* channel independent registers: */ +u32 al7230_rf_data_24[] = { + (0x00 << 24) | 0x003790, + (0x01 << 24) | 0x133331, + (0x02 << 24) | 0x841FF2, + (0x03 << 24) | 0x3FDFA3, + (0x04 << 24) | 0x7FD784, + (0x05 << 24) | 0x802B55, + (0x06 << 24) | 0x56AF36, + (0x07 << 24) | 0xCE0207, + (0x08 << 24) | 0x6EBC08, + (0x09 << 24) | 0x221BB9, + (0x0A << 24) | 0xE0000A, + (0x0B << 24) | 0x08071B, + (0x0C << 24) | 0x000A3C, + (0x0D << 24) | 0xFFFFFD, + (0x0E << 24) | 0x00000E, + (0x0F << 24) | 0x1ABA8F }; -u32 al7230_channel_data_24[][2] = -{ - {(0x00<<24)|0x003790, (0x01<<24)|0x133331}, // channe1 01 - {(0x00<<24)|0x003790, (0x01<<24)|0x1B3331}, // channe1 02 - {(0x00<<24)|0x003790, (0x01<<24)|0x033331}, // channe1 03 - {(0x00<<24)|0x003790, (0x01<<24)|0x0B3331}, // channe1 04 - {(0x00<<24)|0x0037A0, (0x01<<24)|0x133331}, // channe1 05 - {(0x00<<24)|0x0037A0, (0x01<<24)|0x1B3331}, // channe1 06 - {(0x00<<24)|0x0037A0, (0x01<<24)|0x033331}, // channe1 07 - {(0x00<<24)|0x0037A0, (0x01<<24)|0x0B3331}, // channe1 08 - {(0x00<<24)|0x0037B0, (0x01<<24)|0x133331}, // channe1 09 - {(0x00<<24)|0x0037B0, (0x01<<24)|0x1B3331}, // channe1 10 - {(0x00<<24)|0x0037B0, (0x01<<24)|0x033331}, // channe1 11 - {(0x00<<24)|0x0037B0, (0x01<<24)|0x0B3331}, // channe1 12 - {(0x00<<24)|0x0037C0, (0x01<<24)|0x133331}, // channe1 13 - {(0x00<<24)|0x0037C0, (0x01<<24)|0x066661} // channel 14 +u32 al7230_channel_data_24[][2] = { + {(0x00 << 24) | 0x003790, (0x01 << 24) | 0x133331}, /* channe1 01 */ + {(0x00 << 24) | 0x003790, (0x01 << 24) | 0x1B3331}, /* channe1 02 */ + {(0x00 << 24) | 0x003790, (0x01 << 24) | 0x033331}, /* channe1 03 */ + {(0x00 << 24) | 0x003790, (0x01 << 24) | 0x0B3331}, /* channe1 04 */ + {(0x00 << 24) | 0x0037A0, (0x01 << 24) | 0x133331}, /* channe1 05 */ + {(0x00 << 24) | 0x0037A0, (0x01 << 24) | 0x1B3331}, /* channe1 06 */ + {(0x00 << 24) | 0x0037A0, (0x01 << 24) | 0x033331}, /* channe1 07 */ + {(0x00 << 24) | 0x0037A0, (0x01 << 24) | 0x0B3331}, /* channe1 08 */ + {(0x00 << 24) | 0x0037B0, (0x01 << 24) | 0x133331}, /* channe1 09 */ + {(0x00 << 24) | 0x0037B0, (0x01 << 24) | 0x1B3331}, /* channe1 10 */ + {(0x00 << 24) | 0x0037B0, (0x01 << 24) | 0x033331}, /* channe1 11 */ + {(0x00 << 24) | 0x0037B0, (0x01 << 24) | 0x0B3331}, /* channe1 12 */ + {(0x00 << 24) | 0x0037C0, (0x01 << 24) | 0x133331}, /* channe1 13 */ + {(0x00 << 24) | 0x0037C0, (0x01 << 24) | 0x066661} /* channel 14 */ }; -//channel independent registers: -u32 al7230_rf_data_50[] = -{ - (0x00<<24)|0x0FF520, - (0x01<<24)|0x000001, - (0x02<<24)|0x451FE2, - (0x03<<24)|0x5FDFA3, - (0x04<<24)|0x6FD784, - (0x05<<24)|0x853F55, - (0x06<<24)|0x56AF36, - (0x07<<24)|0xCE0207, - (0x08<<24)|0x6EBC08, - (0x09<<24)|0x221BB9, - (0x0A<<24)|0xE0600A, - (0x0B<<24)|0x08044B, - (0x0C<<24)|0x00143C, - (0x0D<<24)|0xFFFFFD, - (0x0E<<24)|0x00000E, - (0x0F<<24)|0x12BACF //5Ghz default state +/* channel independent registers: */ +u32 al7230_rf_data_50[] = { + (0x00 << 24) | 0x0FF520, + (0x01 << 24) | 0x000001, + (0x02 << 24) | 0x451FE2, + (0x03 << 24) | 0x5FDFA3, + (0x04 << 24) | 0x6FD784, + (0x05 << 24) | 0x853F55, + (0x06 << 24) | 0x56AF36, + (0x07 << 24) | 0xCE0207, + (0x08 << 24) | 0x6EBC08, + (0x09 << 24) | 0x221BB9, + (0x0A << 24) | 0xE0600A, + (0x0B << 24) | 0x08044B, + (0x0C << 24) | 0x00143C, + (0x0D << 24) | 0xFFFFFD, + (0x0E << 24) | 0x00000E, + (0x0F << 24) | 0x12BACF /* 5Ghz default state */ }; -u32 al7230_channel_data_5[][4] = -{ - //channel dependent registers: 0x00, 0x01 and 0x04 - //11J =========== - {184, (0x00<<24)|0x0FF520, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 184 - {188, (0x00<<24)|0x0FF520, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 188 - {192, (0x00<<24)|0x0FF530, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 192 - {196, (0x00<<24)|0x0FF530, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 196 - {8, (0x00<<24)|0x0FF540, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 008 - {12, (0x00<<24)|0x0FF540, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 012 - {16, (0x00<<24)|0x0FF550, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 016 - {34, (0x00<<24)|0x0FF560, (0x01<<24)|0x055551, (0x04<<24)|0x77F784}, // channel 034 - {38, (0x00<<24)|0x0FF570, (0x01<<24)|0x100001, (0x04<<24)|0x77F784}, // channel 038 - {42, (0x00<<24)|0x0FF570, (0x01<<24)|0x1AAAA1, (0x04<<24)|0x77F784}, // channel 042 - {46, (0x00<<24)|0x0FF570, (0x01<<24)|0x055551, (0x04<<24)|0x77F784}, // channel 046 - //11 A/H ========= - {36, (0x00<<24)|0x0FF560, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 036 - {40, (0x00<<24)|0x0FF570, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 040 - {44, (0x00<<24)|0x0FF570, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 044 - {48, (0x00<<24)|0x0FF570, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 048 - {52, (0x00<<24)|0x0FF580, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 052 - {56, (0x00<<24)|0x0FF580, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 056 - {60, (0x00<<24)|0x0FF580, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 060 - {64, (0x00<<24)|0x0FF590, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 064 - {100, (0x00<<24)|0x0FF5C0, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 100 - {104, (0x00<<24)|0x0FF5C0, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 104 - {108, (0x00<<24)|0x0FF5C0, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 108 - {112, (0x00<<24)|0x0FF5D0, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 112 - {116, (0x00<<24)|0x0FF5D0, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 116 - {120, (0x00<<24)|0x0FF5D0, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 120 - {124, (0x00<<24)|0x0FF5E0, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 124 - {128, (0x00<<24)|0x0FF5E0, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 128 - {132, (0x00<<24)|0x0FF5E0, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 132 - {136, (0x00<<24)|0x0FF5F0, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 136 - {140, (0x00<<24)|0x0FF5F0, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 140 - {149, (0x00<<24)|0x0FF600, (0x01<<24)|0x180001, (0x04<<24)|0x77F784}, // channel 149 - {153, (0x00<<24)|0x0FF600, (0x01<<24)|0x02AAA1, (0x04<<24)|0x77F784}, // channel 153 - {157, (0x00<<24)|0x0FF600, (0x01<<24)|0x0D5551, (0x04<<24)|0x77F784}, // channel 157 - {161, (0x00<<24)|0x0FF610, (0x01<<24)|0x180001, (0x04<<24)|0x77F784}, // channel 161 - {165, (0x00<<24)|0x0FF610, (0x01<<24)|0x02AAA1, (0x04<<24)|0x77F784} // channel 165 +u32 al7230_channel_data_5[][4] = { + /* channel dependent registers: 0x00, 0x01 and 0x04 */ + /* 11J =========== */ + {184, (0x00 << 24) | 0x0FF520, (0x01 << 24) | 0x000001, (0x04 << 24) | 0x67F784}, /* channel 184 */ + {188, (0x00 << 24) | 0x0FF520, (0x01 << 24) | 0x0AAAA1, (0x04 << 24) | 0x77F784}, /* channel 188 */ + {192, (0x00 << 24) | 0x0FF530, (0x01 << 24) | 0x155551, (0x04 << 24) | 0x77F784}, /* channel 192 */ + {196, (0x00 << 24) | 0x0FF530, (0x01 << 24) | 0x000001, (0x04 << 24) | 0x67F784}, /* channel 196 */ + {8, (0x00 << 24) | 0x0FF540, (0x01 << 24) | 0x000001, (0x04 << 24) | 0x67F784}, /* channel 008 */ + {12, (0x00 << 24) | 0x0FF540, (0x01 << 24) | 0x0AAAA1, (0x04 << 24) | 0x77F784}, /* channel 012 */ + {16, (0x00 << 24) | 0x0FF550, (0x01 << 24) | 0x155551, (0x04 << 24) | 0x77F784}, /* channel 016 */ + {34, (0x00 << 24) | 0x0FF560, (0x01 << 24) | 0x055551, (0x04 << 24) | 0x77F784}, /* channel 034 */ + {38, (0x00 << 24) | 0x0FF570, (0x01 << 24) | 0x100001, (0x04 << 24) | 0x77F784}, /* channel 038 */ + {42, (0x00 << 24) | 0x0FF570, (0x01 << 24) | 0x1AAAA1, (0x04 << 24) | 0x77F784}, /* channel 042 */ + {46, (0x00 << 24) | 0x0FF570, (0x01 << 24) | 0x055551, (0x04 << 24) | 0x77F784}, /* channel 046 */ + /* 11 A/H ========= */ + {36, (0x00 << 24) | 0x0FF560, (0x01 << 24) | 0x0AAAA1, (0x04 << 24) | 0x77F784}, /* channel 036 */ + {40, (0x00 << 24) | 0x0FF570, (0x01 << 24) | 0x155551, (0x04 << 24) | 0x77F784}, /* channel 040 */ + {44, (0x00 << 24) | 0x0FF570, (0x01 << 24) | 0x000001, (0x04 << 24) | 0x67F784}, /* channel 044 */ + {48, (0x00 << 24) | 0x0FF570, (0x01 << 24) | 0x0AAAA1, (0x04 << 24) | 0x77F784}, /* channel 048 */ + {52, (0x00 << 24) | 0x0FF580, (0x01 << 24) | 0x155551, (0x04 << 24) | 0x77F784}, /* channel 052 */ + {56, (0x00 << 24) | 0x0FF580, (0x01 << 24) | 0x000001, (0x04 << 24) | 0x67F784}, /* channel 056 */ + {60, (0x00 << 24) | 0x0FF580, (0x01 << 24) | 0x0AAAA1, (0x04 << 24) | 0x77F784}, /* channel 060 */ + {64, (0x00 << 24) | 0x0FF590, (0x01 << 24) | 0x155551, (0x04 << 24) | 0x77F784}, /* channel 064 */ + {100, (0x00 << 24) | 0x0FF5C0, (0x01 << 24) | 0x155551, (0x04 << 24) | 0x77F784}, /* channel 100 */ + {104, (0x00 << 24) | 0x0FF5C0, (0x01 << 24) | 0x000001, (0x04 << 24) | 0x67F784}, /* channel 104 */ + {108, (0x00 << 24) | 0x0FF5C0, (0x01 << 24) | 0x0AAAA1, (0x04 << 24) | 0x77F784}, /* channel 108 */ + {112, (0x00 << 24) | 0x0FF5D0, (0x01 << 24) | 0x155551, (0x04 << 24) | 0x77F784}, /* channel 112 */ + {116, (0x00 << 24) | 0x0FF5D0, (0x01 << 24) | 0x000001, (0x04 << 24) | 0x67F784}, /* channel 116 */ + {120, (0x00 << 24) | 0x0FF5D0, (0x01 << 24) | 0x0AAAA1, (0x04 << 24) | 0x77F784}, /* channel 120 */ + {124, (0x00 << 24) | 0x0FF5E0, (0x01 << 24) | 0x155551, (0x04 << 24) | 0x77F784}, /* channel 124 */ + {128, (0x00 << 24) | 0x0FF5E0, (0x01 << 24) | 0x000001, (0x04 << 24) | 0x67F784}, /* channel 128 */ + {132, (0x00 << 24) | 0x0FF5E0, (0x01 << 24) | 0x0AAAA1, (0x04 << 24) | 0x77F784}, /* channel 132 */ + {136, (0x00 << 24) | 0x0FF5F0, (0x01 << 24) | 0x155551, (0x04 << 24) | 0x77F784}, /* channel 136 */ + {140, (0x00 << 24) | 0x0FF5F0, (0x01 << 24) | 0x000001, (0x04 << 24) | 0x67F784}, /* channel 140 */ + {149, (0x00 << 24) | 0x0FF600, (0x01 << 24) | 0x180001, (0x04 << 24) | 0x77F784}, /* channel 149 */ + {153, (0x00 << 24) | 0x0FF600, (0x01 << 24) | 0x02AAA1, (0x04 << 24) | 0x77F784}, /* channel 153 */ + {157, (0x00 << 24) | 0x0FF600, (0x01 << 24) | 0x0D5551, (0x04 << 24) | 0x77F784}, /* channel 157 */ + {161, (0x00 << 24) | 0x0FF610, (0x01 << 24) | 0x180001, (0x04 << 24) | 0x77F784}, /* channel 161 */ + {165, (0x00 << 24) | 0x0FF610, (0x01 << 24) | 0x02AAA1, (0x04 << 24) | 0x77F784} /* channel 165 */ }; -//; RF Calibration <=== Register 0x0F -//0x0F 0x1ABA8F; start from 2.4Ghz default state -//0x0F 0x9ABA8F; TXDC compensation -//0x0F 0x3ABA8F; RXFIL adjustment -//0x0F 0x1ABA8F; restore 2.4Ghz default state - -//;TXVGA Mapping Table <=== Register 0x0B -u32 al7230_txvga_data[][2] = -{ - {0x08040B, 0}, //TXVGA=0; - {0x08041B, 1}, //TXVGA=1; - {0x08042B, 2}, //TXVGA=2; - {0x08043B, 3}, //TXVGA=3; - {0x08044B, 4}, //TXVGA=4; - {0x08045B, 5}, //TXVGA=5; - {0x08046B, 6}, //TXVGA=6; - {0x08047B, 7}, //TXVGA=7; - {0x08048B, 8}, //TXVGA=8; - {0x08049B, 9}, //TXVGA=9; - {0x0804AB, 10}, //TXVGA=10; - {0x0804BB, 11}, //TXVGA=11; - {0x0804CB, 12}, //TXVGA=12; - {0x0804DB, 13}, //TXVGA=13; - {0x0804EB, 14}, //TXVGA=14; - {0x0804FB, 15}, //TXVGA=15; - {0x08050B, 16}, //TXVGA=16; - {0x08051B, 17}, //TXVGA=17; - {0x08052B, 18}, //TXVGA=18; - {0x08053B, 19}, //TXVGA=19; - {0x08054B, 20}, //TXVGA=20; - {0x08055B, 21}, //TXVGA=21; - {0x08056B, 22}, //TXVGA=22; - {0x08057B, 23}, //TXVGA=23; - {0x08058B, 24}, //TXVGA=24; - {0x08059B, 25}, //TXVGA=25; - {0x0805AB, 26}, //TXVGA=26; - {0x0805BB, 27}, //TXVGA=27; - {0x0805CB, 28}, //TXVGA=28; - {0x0805DB, 29}, //TXVGA=29; - {0x0805EB, 30}, //TXVGA=30; - {0x0805FB, 31}, //TXVGA=31; - {0x08060B, 32}, //TXVGA=32; - {0x08061B, 33}, //TXVGA=33; - {0x08062B, 34}, //TXVGA=34; - {0x08063B, 35}, //TXVGA=35; - {0x08064B, 36}, //TXVGA=36; - {0x08065B, 37}, //TXVGA=37; - {0x08066B, 38}, //TXVGA=38; - {0x08067B, 39}, //TXVGA=39; - {0x08068B, 40}, //TXVGA=40; - {0x08069B, 41}, //TXVGA=41; - {0x0806AB, 42}, //TXVGA=42; - {0x0806BB, 43}, //TXVGA=43; - {0x0806CB, 44}, //TXVGA=44; - {0x0806DB, 45}, //TXVGA=45; - {0x0806EB, 46}, //TXVGA=46; - {0x0806FB, 47}, //TXVGA=47; - {0x08070B, 48}, //TXVGA=48; - {0x08071B, 49}, //TXVGA=49; - {0x08072B, 50}, //TXVGA=50; - {0x08073B, 51}, //TXVGA=51; - {0x08074B, 52}, //TXVGA=52; - {0x08075B, 53}, //TXVGA=53; - {0x08076B, 54}, //TXVGA=54; - {0x08077B, 55}, //TXVGA=55; - {0x08078B, 56}, //TXVGA=56; - {0x08079B, 57}, //TXVGA=57; - {0x0807AB, 58}, //TXVGA=58; - {0x0807BB, 59}, //TXVGA=59; - {0x0807CB, 60}, //TXVGA=60; - {0x0807DB, 61}, //TXVGA=61; - {0x0807EB, 62}, //TXVGA=62; - {0x0807FB, 63}, //TXVGA=63; +/* + * RF Calibration <=== Register 0x0F + * 0x0F 0x1ABA8F; start from 2.4Ghz default state + * 0x0F 0x9ABA8F; TXDC compensation + * 0x0F 0x3ABA8F; RXFIL adjustment + * 0x0F 0x1ABA8F; restore 2.4Ghz default state + */ + +/* TXVGA Mapping Table <=== Register 0x0B */ +u32 al7230_txvga_data[][2] = { + {0x08040B, 0}, /* TXVGA = 0; */ + {0x08041B, 1}, /* TXVGA = 1; */ + {0x08042B, 2}, /* TXVGA = 2; */ + {0x08043B, 3}, /* TXVGA = 3; */ + {0x08044B, 4}, /* TXVGA = 4; */ + {0x08045B, 5}, /* TXVGA = 5; */ + {0x08046B, 6}, /* TXVGA = 6; */ + {0x08047B, 7}, /* TXVGA = 7; */ + {0x08048B, 8}, /* TXVGA = 8; */ + {0x08049B, 9}, /* TXVGA = 9; */ + {0x0804AB, 10}, /* TXVGA = 10; */ + {0x0804BB, 11}, /* TXVGA = 11; */ + {0x0804CB, 12}, /* TXVGA = 12; */ + {0x0804DB, 13}, /* TXVGA = 13; */ + {0x0804EB, 14}, /* TXVGA = 14; */ + {0x0804FB, 15}, /* TXVGA = 15; */ + {0x08050B, 16}, /* TXVGA = 16; */ + {0x08051B, 17}, /* TXVGA = 17; */ + {0x08052B, 18}, /* TXVGA = 18; */ + {0x08053B, 19}, /* TXVGA = 19; */ + {0x08054B, 20}, /* TXVGA = 20; */ + {0x08055B, 21}, /* TXVGA = 21; */ + {0x08056B, 22}, /* TXVGA = 22; */ + {0x08057B, 23}, /* TXVGA = 23; */ + {0x08058B, 24}, /* TXVGA = 24; */ + {0x08059B, 25}, /* TXVGA = 25; */ + {0x0805AB, 26}, /* TXVGA = 26; */ + {0x0805BB, 27}, /* TXVGA = 27; */ + {0x0805CB, 28}, /* TXVGA = 28; */ + {0x0805DB, 29}, /* TXVGA = 29; */ + {0x0805EB, 30}, /* TXVGA = 30; */ + {0x0805FB, 31}, /* TXVGA = 31; */ + {0x08060B, 32}, /* TXVGA = 32; */ + {0x08061B, 33}, /* TXVGA = 33; */ + {0x08062B, 34}, /* TXVGA = 34; */ + {0x08063B, 35}, /* TXVGA = 35; */ + {0x08064B, 36}, /* TXVGA = 36; */ + {0x08065B, 37}, /* TXVGA = 37; */ + {0x08066B, 38}, /* TXVGA = 38; */ + {0x08067B, 39}, /* TXVGA = 39; */ + {0x08068B, 40}, /* TXVGA = 40; */ + {0x08069B, 41}, /* TXVGA = 41; */ + {0x0806AB, 42}, /* TXVGA = 42; */ + {0x0806BB, 43}, /* TXVGA = 43; */ + {0x0806CB, 44}, /* TXVGA = 44; */ + {0x0806DB, 45}, /* TXVGA = 45; */ + {0x0806EB, 46}, /* TXVGA = 46; */ + {0x0806FB, 47}, /* TXVGA = 47; */ + {0x08070B, 48}, /* TXVGA = 48; */ + {0x08071B, 49}, /* TXVGA = 49; */ + {0x08072B, 50}, /* TXVGA = 50; */ + {0x08073B, 51}, /* TXVGA = 51; */ + {0x08074B, 52}, /* TXVGA = 52; */ + {0x08075B, 53}, /* TXVGA = 53; */ + {0x08076B, 54}, /* TXVGA = 54; */ + {0x08077B, 55}, /* TXVGA = 55; */ + {0x08078B, 56}, /* TXVGA = 56; */ + {0x08079B, 57}, /* TXVGA = 57; */ + {0x0807AB, 58}, /* TXVGA = 58; */ + {0x0807BB, 59}, /* TXVGA = 59; */ + {0x0807CB, 60}, /* TXVGA = 60; */ + {0x0807DB, 61}, /* TXVGA = 61; */ + {0x0807EB, 62}, /* TXVGA = 62; */ + {0x0807FB, 63}, /* TXVGA = 63; */ }; -//-------------------------------- - +/* ============================================= */ -//; W89RF242 RFIC SPI programming initial data -//; Winbond WLAN 11g RFIC BB-SPI register -- version FA5976A rev 1.3b -//; Update Date: Ocotber 3, 2005 by PP10 Hsiang-Te Ho -//; -//; Version 1.3b revision items: (Oct. 1, 2005 by HTHo) for FA5976A -u32 w89rf242_rf_data[] = -{ - (0x00<<24)|0xF86100, // 20060721 0xF86100, //; 3E184; MODA (0x00) -- Normal mode ; calibration off - (0x01<<24)|0xEFFFC2, //; 3BFFF; MODB (0x01) -- turn off RSSI, and other circuits are turned on - (0x02<<24)|0x102504, //; 04094; FSET (0x02) -- default 20MHz crystal ; Icmp=1.5mA - (0x03<<24)|0x026286, //; 0098A; FCHN (0x03) -- default CH7, 2442MHz - (0x04<<24)|0x000208, // 20060612.1.a 0x0002C8, // 20050818 // 20050816 0x000388 - //; 02008; FCAL (0x04) -- XTAL Freq Trim=001000 (socket board#1); FA5976AYG_v1.3C - (0x05<<24)|0x24C60A, // 20060612.1.a 0x24C58A, // 941003 0x24C48A, // 20050818.2 0x24848A, // 20050818 // 20050816 0x24C48A - //; 09316; GANA (0x05) -- TX VGA default (TXVGA=0x18(12)) & TXGPK=110 ; FA5976A_1.3D - (0x06<<24)|0x3432CC, // 941003 0x26C34C, // 20050818 0x06B40C - //; 0D0CB; GANB (0x06) -- RXDC(DC offset) on; LNA=11; RXVGA=001011(11) ; RXFLSW=11(010001); RXGPK=00; RXGCF=00; -50dBm input - (0x07<<24)|0x0C68CE, // 20050818.2 0x0C66CE, // 20050818 // 20050816 0x0C68CE - //; 031A3; FILT (0x07) -- TX/RX filter with auto-tuning; TFLBW=011; RFLBW=100 - (0x08<<24)|0x100010, //; 04000; TCAL (0x08) -- //for LO - (0x09<<24)|0x004012, // 20060612.1.a 0x6E4012, // 0x004012, - //; 1B900; RCALA (0x09) -- FASTS=11; HPDE=01 (100nsec); SEHP=1 (select B0 pin=RXHP); RXHP=1 (Turn on RXHP function)(FA5976A_1.3C) - (0x0A<<24)|0x704014, //; 1C100; RCALB (0x0A) - (0x0B<<24)|0x18BDD6, // 941003 0x1805D6, // 20050818.2 0x1801D6, // 20050818 // 20050816 0x1805D6 - //; 062F7; IQCAL (0x0B) -- Turn on LO phase tuner=0111 & RX-LO phase = 0111; FA5976A_1.3B (2005/09/29) - (0x0C<<24)|0x575558, // 20050818.2 0x555558, // 20050818 // 20050816 0x575558 - //; 15D55 ; IBSA (0x0C) -- IFPre =11 ; TC5376A_v1.3A for corner - (0x0D<<24)|0x55545A, // 20060612.1.a 0x55555A, - //; 15555 ; IBSB (0x0D) - (0x0E<<24)|0x5557DC, // 20060612.1.a 0x55555C, // 941003 0x5557DC, - //; 1555F ; IBSC (0x0E) -- IRLNA & IRLNB (PTAT & Const current)=01/01; FA5976B_1.3F (2005/11/25) - (0x10<<24)|0x000C20, // 941003 0x000020, // 20050818 - //; 00030 ; TMODA (0x10) -- LNA_gain_step=0011 ; LNA=15/16dB - (0x11<<24)|0x0C0022, // 941003 0x030022 // 20050818.2 0x030022 // 20050818 // 20050816 0x0C0022 - //; 03000 ; TMODB (0x11) -- Turn ON RX-Q path Test Switch; To improve IQ path group delay (FA5976A_1.3C) - (0x12<<24)|0x000024 // 20060612.1.a 0x001824 // 941003 add - //; TMODC (0x12) -- Turn OFF Tempearure sensor +/* + * W89RF242 RFIC SPI programming initial data + * Winbond WLAN 11g RFIC BB-SPI register -- version FA5976A rev 1.3b + */ +u32 w89rf242_rf_data[] = { + (0x00 << 24) | 0xF86100, /* 3E184; MODA (0x00) -- Normal mode ; calibration off */ + (0x01 << 24) | 0xEFFFC2, /* 3BFFF; MODB (0x01) -- turn off RSSI, and other circuits are turned on */ + (0x02 << 24) | 0x102504, /* 04094; FSET (0x02) -- default 20MHz crystal ; Icmp=1.5mA */ + (0x03 << 24) | 0x026286, /* 0098A; FCHN (0x03) -- default CH7, 2442MHz */ + (0x04 << 24) | 0x000208, /* 02008; FCAL (0x04) -- XTAL Freq Trim=001000 (socket board#1); FA5976AYG_v1.3C */ + (0x05 << 24) | 0x24C60A, /* 09316; GANA (0x05) -- TX VGA default (TXVGA=0x18(12)) & TXGPK=110 ; FA5976A_1.3D */ + (0x06 << 24) | 0x3432CC, /* 0D0CB; GANB (0x06) -- RXDC(DC offset) on; LNA=11; RXVGA=001011(11) ; RXFLSW=11(010001); RXGPK=00; RXGCF=00; -50dBm input */ + (0x07 << 24) | 0x0C68CE, /* 031A3; FILT (0x07) -- TX/RX filter with auto-tuning; TFLBW=011; RFLBW=100 */ + (0x08 << 24) | 0x100010, /* 04000; TCAL (0x08) -- for LO */ + (0x09 << 24) | 0x004012, /* 1B900; RCALA (0x09) -- FASTS=11; HPDE=01 (100nsec); SEHP=1 (select B0 pin=RXHP); RXHP=1 (Turn on RXHP function)(FA5976A_1.3C) */ + (0x0A << 24) | 0x704014, /* 1C100; RCALB (0x0A) */ + (0x0B << 24) | 0x18BDD6, /* 062F7; IQCAL (0x0B) -- Turn on LO phase tuner=0111 & RX-LO phase = 0111; FA5976A_1.3B */ + (0x0C << 24) | 0x575558, /* 15D55 ; IBSA (0x0C) -- IFPre =11 ; TC5376A_v1.3A for corner */ + (0x0D << 24) | 0x55545A, /* 15555 ; IBSB (0x0D) */ + (0x0E << 24) | 0x5557DC, /* 1555F ; IBSC (0x0E) -- IRLNA & IRLNB (PTAT & Const current)=01/01; FA5976B_1.3F */ + (0x10 << 24) | 0x000C20, /* 00030 ; TMODA (0x10) -- LNA_gain_step=0011 ; LNA=15/16dB */ + (0x11 << 24) | 0x0C0022, /* 03000 ; TMODB (0x11) -- Turn ON RX-Q path Test Switch; To improve IQ path group delay (FA5976A_1.3C) */ + (0x12 << 24) | 0x000024 /* TMODC (0x12) -- Turn OFF Tempearure sensor */ }; -u32 w89rf242_channel_data_24[][2] = -{ - {(0x03<<24)|0x025B06, (0x04<<24)|0x080408}, // channe1 01 - {(0x03<<24)|0x025C46, (0x04<<24)|0x080408}, // channe1 02 - {(0x03<<24)|0x025D86, (0x04<<24)|0x080408}, // channe1 03 - {(0x03<<24)|0x025EC6, (0x04<<24)|0x080408}, // channe1 04 - {(0x03<<24)|0x026006, (0x04<<24)|0x080408}, // channe1 05 - {(0x03<<24)|0x026146, (0x04<<24)|0x080408}, // channe1 06 - {(0x03<<24)|0x026286, (0x04<<24)|0x080408}, // channe1 07 - {(0x03<<24)|0x0263C6, (0x04<<24)|0x080408}, // channe1 08 - {(0x03<<24)|0x026506, (0x04<<24)|0x080408}, // channe1 09 - {(0x03<<24)|0x026646, (0x04<<24)|0x080408}, // channe1 10 - {(0x03<<24)|0x026786, (0x04<<24)|0x080408}, // channe1 11 - {(0x03<<24)|0x0268C6, (0x04<<24)|0x080408}, // channe1 12 - {(0x03<<24)|0x026A06, (0x04<<24)|0x080408}, // channe1 13 - {(0x03<<24)|0x026D06, (0x04<<24)|0x080408} // channe1 14 +u32 w89rf242_channel_data_24[][2] = { + {(0x03 << 24) | 0x025B06, (0x04 << 24) | 0x080408}, /* channe1 01 */ + {(0x03 << 24) | 0x025C46, (0x04 << 24) | 0x080408}, /* channe1 02 */ + {(0x03 << 24) | 0x025D86, (0x04 << 24) | 0x080408}, /* channe1 03 */ + {(0x03 << 24) | 0x025EC6, (0x04 << 24) | 0x080408}, /* channe1 04 */ + {(0x03 << 24) | 0x026006, (0x04 << 24) | 0x080408}, /* channe1 05 */ + {(0x03 << 24) | 0x026146, (0x04 << 24) | 0x080408}, /* channe1 06 */ + {(0x03 << 24) | 0x026286, (0x04 << 24) | 0x080408}, /* channe1 07 */ + {(0x03 << 24) | 0x0263C6, (0x04 << 24) | 0x080408}, /* channe1 08 */ + {(0x03 << 24) | 0x026506, (0x04 << 24) | 0x080408}, /* channe1 09 */ + {(0x03 << 24) | 0x026646, (0x04 << 24) | 0x080408}, /* channe1 10 */ + {(0x03 << 24) | 0x026786, (0x04 << 24) | 0x080408}, /* channe1 11 */ + {(0x03 << 24) | 0x0268C6, (0x04 << 24) | 0x080408}, /* channe1 12 */ + {(0x03 << 24) | 0x026A06, (0x04 << 24) | 0x080408}, /* channe1 13 */ + {(0x03 << 24) | 0x026D06, (0x04 << 24) | 0x080408} /* channe1 14 */ }; -u32 w89rf242_power_data_24[] = {(0x05<<24)|0x24C48A, (0x05<<24)|0x24C48A, (0x05<<24)|0x24C48A}; +u32 w89rf242_power_data_24[] = {(0x05 << 24) | 0x24C48A, (0x05 << 24) | 0x24C48A, (0x05 << 24) | 0x24C48A}; -// 20060315.6 Enlarge for new scale -// 20060316.6 20060619.2.a add mapping array -u32 w89rf242_txvga_old_mapping[][2] = -{ - {0, 0} , // New <-> Old +u32 w89rf242_txvga_old_mapping[][2] = { + {0, 0} , /* New <-> Old */ {1, 1} , {2, 2} , {3, 3} , {4, 4} , {6, 5} , - {8, 6 }, - {10, 7 }, - {12, 8 }, - {14, 9 }, + {8, 6}, + {10, 7}, + {12, 8}, + {14, 9}, {16, 10}, {18, 11}, {20, 12}, @@ -818,1704 +735,1514 @@ u32 w89rf242_txvga_old_mapping[][2] = {30, 17}, {32, 18}, {34, 19}, +}; +u32 w89rf242_txvga_data[][5] = { + /* low gain mode */ + {(0x05 << 24) | 0x24C00A, 0, 0x00292315, 0x0800FEFF, 0x52523131}, /* min gain */ + {(0x05 << 24) | 0x24C80A, 1, 0x00292315, 0x0800FEFF, 0x52523131}, + {(0x05 << 24) | 0x24C04A, 2, 0x00292315, 0x0800FEFF, 0x52523131}, /* (default) +14dBm (ANT) */ + {(0x05 << 24) | 0x24C84A, 3, 0x00292315, 0x0800FEFF, 0x52523131}, -}; + /* TXVGA=0x10 */ + {(0x05 << 24) | 0x24C40A, 4, 0x00292315, 0x0800FEFF, 0x60603838}, + {(0x05 << 24) | 0x24C40A, 5, 0x00262114, 0x0700FEFF, 0x65653B3B}, -// 20060619.3 modify from Bruce's mail -u32 w89rf242_txvga_data[][5] = -{ - //low gain mode - { (0x05<<24)|0x24C00A, 0, 0x00292315, 0x0800FEFF, 0x52523131 },// ; min gain - { (0x05<<24)|0x24C80A, 1, 0x00292315, 0x0800FEFF, 0x52523131 }, - { (0x05<<24)|0x24C04A, 2, 0x00292315, 0x0800FEFF, 0x52523131 },// (default) +14dBm (ANT) - { (0x05<<24)|0x24C84A, 3, 0x00292315, 0x0800FEFF, 0x52523131 }, - - //TXVGA=0x10 - { (0x05<<24)|0x24C40A, 4, 0x00292315, 0x0800FEFF, 0x60603838 }, - { (0x05<<24)|0x24C40A, 5, 0x00262114, 0x0700FEFF, 0x65653B3B }, - - //TXVGA=0x11 - { (0x05<<24)|0x24C44A, 6, 0x00241F13, 0x0700FFFF, 0x58583333 }, - { (0x05<<24)|0x24C44A, 7, 0x00292315, 0x0800FEFF, 0x5E5E3737 }, - - //TXVGA=0x12 - { (0x05<<24)|0x24C48A, 8, 0x00262114, 0x0700FEFF, 0x53533030 }, - { (0x05<<24)|0x24C48A, 9, 0x00241F13, 0x0700FFFF, 0x59593434 }, - - //TXVGA=0x13 - { (0x05<<24)|0x24C4CA, 10, 0x00292315, 0x0800FEFF, 0x52523030 }, - { (0x05<<24)|0x24C4CA, 11, 0x00262114, 0x0700FEFF, 0x56563232 }, - - //TXVGA=0x14 - { (0x05<<24)|0x24C50A, 12, 0x00292315, 0x0800FEFF, 0x54543131 }, - { (0x05<<24)|0x24C50A, 13, 0x00262114, 0x0700FEFF, 0x58583434 }, - - //TXVGA=0x15 - { (0x05<<24)|0x24C54A, 14, 0x00292315, 0x0800FEFF, 0x54543131 }, - { (0x05<<24)|0x24C54A, 15, 0x00262114, 0x0700FEFF, 0x59593434 }, - - //TXVGA=0x16 - { (0x05<<24)|0x24C58A, 16, 0x00292315, 0x0800FEFF, 0x55553131 }, - { (0x05<<24)|0x24C58A, 17, 0x00292315, 0x0800FEFF, 0x5B5B3535 }, - - //TXVGA=0x17 - { (0x05<<24)|0x24C5CA, 18, 0x00262114, 0x0700FEFF, 0x51512F2F }, - { (0x05<<24)|0x24C5CA, 19, 0x00241F13, 0x0700FFFF, 0x55553131 }, - - //TXVGA=0x18 - { (0x05<<24)|0x24C60A, 20, 0x00292315, 0x0800FEFF, 0x4F4F2E2E }, - { (0x05<<24)|0x24C60A, 21, 0x00262114, 0x0700FEFF, 0x53533030 }, - - //TXVGA=0x19 - { (0x05<<24)|0x24C64A, 22, 0x00292315, 0x0800FEFF, 0x4E4E2D2D }, - { (0x05<<24)|0x24C64A, 23, 0x00262114, 0x0700FEFF, 0x53533030 }, - - //TXVGA=0x1A - { (0x05<<24)|0x24C68A, 24, 0x00292315, 0x0800FEFF, 0x50502E2E }, - { (0x05<<24)|0x24C68A, 25, 0x00262114, 0x0700FEFF, 0x55553131 }, - - //TXVGA=0x1B - { (0x05<<24)|0x24C6CA, 26, 0x00262114, 0x0700FEFF, 0x53533030 }, - { (0x05<<24)|0x24C6CA, 27, 0x00292315, 0x0800FEFF, 0x5A5A3434 }, - - //TXVGA=0x1C - { (0x05<<24)|0x24C70A, 28, 0x00292315, 0x0800FEFF, 0x55553131 }, - { (0x05<<24)|0x24C70A, 29, 0x00292315, 0x0800FEFF, 0x5D5D3636 }, - - //TXVGA=0x1D - { (0x05<<24)|0x24C74A, 30, 0x00292315, 0x0800FEFF, 0x5F5F3737 }, - { (0x05<<24)|0x24C74A, 31, 0x00262114, 0x0700FEFF, 0x65653B3B }, - - //TXVGA=0x1E - { (0x05<<24)|0x24C78A, 32, 0x00292315, 0x0800FEFF, 0x66663B3B }, - { (0x05<<24)|0x24C78A, 33, 0x00262114, 0x0700FEFF, 0x70704141 }, - - //TXVGA=0x1F - { (0x05<<24)|0x24C7CA, 34, 0x00292315, 0x0800FEFF, 0x72724242 } + /* TXVGA=0x11 */ + { (0x05 << 24) | 0x24C44A, 6, 0x00241F13, 0x0700FFFF, 0x58583333}, + { (0x05 << 24) | 0x24C44A, 7, 0x00292315, 0x0800FEFF, 0x5E5E3737}, + + /* TXVGA=0x12 */ + {(0x05 << 24) | 0x24C48A, 8, 0x00262114, 0x0700FEFF, 0x53533030}, + {(0x05 << 24) | 0x24C48A, 9, 0x00241F13, 0x0700FFFF, 0x59593434}, + + /* TXVGA=0x13 */ + {(0x05 << 24) | 0x24C4CA, 10, 0x00292315, 0x0800FEFF, 0x52523030}, + {(0x05 << 24) | 0x24C4CA, 11, 0x00262114, 0x0700FEFF, 0x56563232}, + + /* TXVGA=0x14 */ + {(0x05 << 24) | 0x24C50A, 12, 0x00292315, 0x0800FEFF, 0x54543131}, + {(0x05 << 24) | 0x24C50A, 13, 0x00262114, 0x0700FEFF, 0x58583434}, + + /* TXVGA=0x15 */ + {(0x05 << 24) | 0x24C54A, 14, 0x00292315, 0x0800FEFF, 0x54543131}, + {(0x05 << 24) | 0x24C54A, 15, 0x00262114, 0x0700FEFF, 0x59593434}, + + /* TXVGA=0x16 */ + {(0x05 << 24) | 0x24C58A, 16, 0x00292315, 0x0800FEFF, 0x55553131}, + {(0x05 << 24) | 0x24C58A, 17, 0x00292315, 0x0800FEFF, 0x5B5B3535}, + + /* TXVGA=0x17 */ + {(0x05 << 24) | 0x24C5CA, 18, 0x00262114, 0x0700FEFF, 0x51512F2F}, + {(0x05 << 24) | 0x24C5CA, 19, 0x00241F13, 0x0700FFFF, 0x55553131}, + + /* TXVGA=0x18 */ + {(0x05 << 24) | 0x24C60A, 20, 0x00292315, 0x0800FEFF, 0x4F4F2E2E}, + {(0x05 << 24) | 0x24C60A, 21, 0x00262114, 0x0700FEFF, 0x53533030}, + + /* TXVGA=0x19 */ + {(0x05 << 24) | 0x24C64A, 22, 0x00292315, 0x0800FEFF, 0x4E4E2D2D}, + {(0x05 << 24) | 0x24C64A, 23, 0x00262114, 0x0700FEFF, 0x53533030}, + + /* TXVGA=0x1A */ + {(0x05 << 24) | 0x24C68A, 24, 0x00292315, 0x0800FEFF, 0x50502E2E}, + {(0x05 << 24) | 0x24C68A, 25, 0x00262114, 0x0700FEFF, 0x55553131}, + + /* TXVGA=0x1B */ + {(0x05 << 24) | 0x24C6CA, 26, 0x00262114, 0x0700FEFF, 0x53533030}, + {(0x05 << 24) | 0x24C6CA, 27, 0x00292315, 0x0800FEFF, 0x5A5A3434}, + + /* TXVGA=0x1C */ + {(0x05 << 24) | 0x24C70A, 28, 0x00292315, 0x0800FEFF, 0x55553131}, + {(0x05 << 24) | 0x24C70A, 29, 0x00292315, 0x0800FEFF, 0x5D5D3636}, + + /* TXVGA=0x1D */ + {(0x05 << 24) | 0x24C74A, 30, 0x00292315, 0x0800FEFF, 0x5F5F3737}, + {(0x05 << 24) | 0x24C74A, 31, 0x00262114, 0x0700FEFF, 0x65653B3B}, + + /* TXVGA=0x1E */ + {(0x05 << 24) | 0x24C78A, 32, 0x00292315, 0x0800FEFF, 0x66663B3B}, + {(0x05 << 24) | 0x24C78A, 33, 0x00262114, 0x0700FEFF, 0x70704141}, + + /* TXVGA=0x1F */ + {(0x05 << 24) | 0x24C7CA, 34, 0x00292315, 0x0800FEFF, 0x72724242} }; -/////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////// - - - -//============================================================================================================= -// Uxx_ReadEthernetAddress -- -// -// Routine Description: -// Reads in the Ethernet address from the IC. -// -// Arguments: -// pHwData - The pHwData structure -// -// Return Value: -// -// The address is stored in EthernetIDAddr. -//============================================================================================================= -void -Uxx_ReadEthernetAddress( struct hw_data * pHwData ) +/* ================================================================================================== */ + + + +/* + * ============================================================================================================= + * Uxx_ReadEthernetAddress -- + * + * Routine Description: + * Reads in the Ethernet address from the IC. + * + * Arguments: + * pHwData - The pHwData structure + * + * Return Value: + * + * The address is stored in EthernetIDAddr. + * ============================================================================================================= + */ +void Uxx_ReadEthernetAddress(struct hw_data *pHwData) { u32 ltmp; - // Reading Ethernet address from EEPROM and set into hardware due to MAC address maybe change. - // Only unplug and plug again can make hardware read EEPROM again. 20060727 - Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08000000 ); // Start EEPROM access + Read + address(0x0d) - Wb35Reg_ReadSync( pHwData, 0x03b4, <mp ); - *(u16 *)pHwData->PermanentMacAddress = cpu_to_le16((u16)ltmp); //20060926 anson's endian - Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08010000 ); // Start EEPROM access + Read + address(0x0d) - Wb35Reg_ReadSync( pHwData, 0x03b4, <mp ); - *(u16 *)(pHwData->PermanentMacAddress + 2) = cpu_to_le16((u16)ltmp); //20060926 anson's endian - Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08020000 ); // Start EEPROM access + Read + address(0x0d) - Wb35Reg_ReadSync( pHwData, 0x03b4, <mp ); - *(u16 *)(pHwData->PermanentMacAddress + 4) = cpu_to_le16((u16)ltmp); //20060926 anson's endian + /* + * Reading Ethernet address from EEPROM and set into hardware due to MAC address maybe change. + * Only unplug and plug again can make hardware read EEPROM again. + */ + Wb35Reg_WriteSync(pHwData, 0x03b4, 0x08000000); /* Start EEPROM access + Read + address(0x0d) */ + Wb35Reg_ReadSync(pHwData, 0x03b4, <mp); + *(u16 *)pHwData->PermanentMacAddress = cpu_to_le16((u16) ltmp); + Wb35Reg_WriteSync(pHwData, 0x03b4, 0x08010000); /* Start EEPROM access + Read + address(0x0d) */ + Wb35Reg_ReadSync(pHwData, 0x03b4, <mp); + *(u16 *)(pHwData->PermanentMacAddress + 2) = cpu_to_le16((u16) ltmp); + Wb35Reg_WriteSync(pHwData, 0x03b4, 0x08020000); /* Start EEPROM access + Read + address(0x0d) */ + Wb35Reg_ReadSync(pHwData, 0x03b4, <mp); + *(u16 *)(pHwData->PermanentMacAddress + 4) = cpu_to_le16((u16) ltmp); *(u16 *)(pHwData->PermanentMacAddress + 6) = 0; - Wb35Reg_WriteSync( pHwData, 0x03e8, cpu_to_le32(*(u32 *)pHwData->PermanentMacAddress) ); //20060926 anson's endian - Wb35Reg_WriteSync( pHwData, 0x03ec, cpu_to_le32(*(u32 *)(pHwData->PermanentMacAddress+4)) ); //20060926 anson's endian + Wb35Reg_WriteSync(pHwData, 0x03e8, cpu_to_le32(*(u32 *)pHwData->PermanentMacAddress)); + Wb35Reg_WriteSync(pHwData, 0x03ec, cpu_to_le32(*(u32 *)(pHwData->PermanentMacAddress + 4))); } -//=============================================================================================================== -// CardGetMulticastBit -- -// Description: -// For a given multicast address, returns the byte and bit in the card multicast registers that it hashes to. -// Calls CardComputeCrc() to determine the CRC value. -// Arguments: -// Address - the address -// Byte - the byte that it hashes to -// Value - will have a 1 in the relevant bit -// Return Value: -// None. -//============================================================================================================== -void CardGetMulticastBit( u8 Address[ETH_ALEN], u8 *Byte, u8 *Value ) +/* + * =============================================================================================================== + * CardGetMulticastBit -- + * Description: + * For a given multicast address, returns the byte and bit in the card multicast registers that it hashes to. + * Calls CardComputeCrc() to determine the CRC value. + * Arguments: + * Address - the address + * Byte - the byte that it hashes to + * Value - will have a 1 in the relevant bit + * Return Value: + * None. + * ============================================================================================================== + */ +void CardGetMulticastBit(u8 Address[ETH_ALEN], u8 *Byte, u8 *Value) { - u32 Crc; - u32 BitNumber; + u32 Crc; + u32 BitNumber; - // First compute the CRC. - Crc = CardComputeCrc(Address, ETH_ALEN); + /* First compute the CRC. */ + Crc = CardComputeCrc(Address, ETH_ALEN); - // The computed CRC is bit0~31 from left to right - //At first we should do right shift 25bits, and read 7bits by using '&', 2^7=128 + /* The computed CRC is bit0~31 from left to right */ + /* At first we should do right shift 25bits, and read 7bits by using '&', 2^7=128 */ BitNumber = (u32) ((Crc >> 26) & 0x3f); - *Byte = (u8) (BitNumber >> 3);// 900514 original (BitNumber / 8) - *Value = (u8) ((u8)1 << (BitNumber % 8)); + *Byte = (u8) (BitNumber >> 3); /* 900514 original (BitNumber / 8) */ + *Value = (u8) ((u8) 1 << (BitNumber % 8)); } -void Uxx_power_on_procedure( struct hw_data * pHwData ) +void Uxx_power_on_procedure(struct hw_data *pHwData) { u32 ltmp, loop; - if( pHwData->phy_type <= RF_MAXIM_V1 ) - Wb35Reg_WriteSync( pHwData, 0x03d4, 0xffffff38 ); - else - { - Wb35Reg_WriteSync( pHwData, 0x03f4, 0xFF5807FF );// 20060721 For NEW IC 0xFF5807FF - - // 20060511.1 Fix the following 4 steps for Rx of RF 2230 initial fail - Wb35Reg_WriteSync( pHwData, 0x03d4, 0x80 );// regulator on only - msleep(10); // Modify 20051221.1.b - Wb35Reg_WriteSync( pHwData, 0x03d4, 0xb8 );// REG_ON RF_RSTN on, and - msleep(10); // Modify 20051221.1.b - + if (pHwData->phy_type <= RF_MAXIM_V1) + Wb35Reg_WriteSync(pHwData, 0x03d4, 0xffffff38); + else { + Wb35Reg_WriteSync(pHwData, 0x03f4, 0xFF5807FF); + Wb35Reg_WriteSync(pHwData, 0x03d4, 0x80); /* regulator on only */ + msleep(10); + Wb35Reg_WriteSync(pHwData, 0x03d4, 0xb8); /* REG_ON RF_RSTN on, and */ + msleep(10); ltmp = 0x4968; - if( (pHwData->phy_type == RF_WB_242) || - (RF_WB_242_1 == pHwData->phy_type) ) // 20060619.5 Add + if ((pHwData->phy_type == RF_WB_242) || + (RF_WB_242_1 == pHwData->phy_type)) ltmp = 0x4468; - Wb35Reg_WriteSync( pHwData, 0x03d0, ltmp ); - Wb35Reg_WriteSync( pHwData, 0x03d4, 0xa0 );// PLL_PD REF_PD set to 0 + Wb35Reg_WriteSync(pHwData, 0x03d0, ltmp); + Wb35Reg_WriteSync(pHwData, 0x03d4, 0xa0); /* PLL_PD REF_PD set to 0 */ - msleep(20); // Modify 20051221.1.b - Wb35Reg_ReadSync( pHwData, 0x03d0, <mp ); - loop = 500; // Wait for 5 second 20061101 - while( !(ltmp & 0x20) && loop-- ) - { - msleep(10); // Modify 20051221.1.b - if( !Wb35Reg_ReadSync( pHwData, 0x03d0, <mp ) ) + msleep(20); + Wb35Reg_ReadSync(pHwData, 0x03d0, <mp); + loop = 500; /* Wait for 5 second */ + while (!(ltmp & 0x20) && loop--) { + msleep(10); + if (!Wb35Reg_ReadSync(pHwData, 0x03d0, <mp)) break; } - Wb35Reg_WriteSync( pHwData, 0x03d4, 0xe0 );// MLK_EN + Wb35Reg_WriteSync(pHwData, 0x03d4, 0xe0); /* MLK_EN */ } - Wb35Reg_WriteSync( pHwData, 0x03b0, 1 );// Reset hardware first - msleep(10); // Add this 20051221.1.b + Wb35Reg_WriteSync(pHwData, 0x03b0, 1); /* Reset hardware first */ + msleep(10); - // Set burst write delay - Wb35Reg_WriteSync( pHwData, 0x03f8, 0x7ff ); + /* Set burst write delay */ + Wb35Reg_WriteSync(pHwData, 0x03f8, 0x7ff); } -void Set_ChanIndep_RfData_al7230_24( struct hw_data * pHwData, u32 *pltmp ,char number) +void Set_ChanIndep_RfData_al7230_24(struct hw_data *pHwData, u32 *pltmp , char number) { u8 i; - for( i=0; iphy_para[i] = al7230_rf_data_24[i]; - pltmp[i] = (1 << 31) | (0 << 30) | (24 << 24) | (al7230_rf_data_24[i]&0xffffff); + pltmp[i] = (1 << 31) | (0 << 30) | (24 << 24) | (al7230_rf_data_24[i] & 0xffffff); } } -void Set_ChanIndep_RfData_al7230_50( struct hw_data * pHwData, u32 *pltmp, char number) +void Set_ChanIndep_RfData_al7230_50(struct hw_data *pHwData, u32 *pltmp, char number) { u8 i; - for( i=0; iphy_para[i] = al7230_rf_data_50[i]; - pltmp[i] = (1 << 31) | (0 << 30) | (24 << 24) | (al7230_rf_data_50[i]&0xffffff); + pltmp[i] = (1 << 31) | (0 << 30) | (24 << 24) | (al7230_rf_data_50[i] & 0xffffff); } } -//============================================================================================================= -// RFSynthesizer_initial -- -//============================================================================================================= -void -RFSynthesizer_initial(struct hw_data * pHwData) +/* + * ============================================================================================================= + * RFSynthesizer_initial -- + * ============================================================================================================= + */ +void RFSynthesizer_initial(struct hw_data *pHwData) { u32 altmp[32]; - u32 * pltmp = altmp; + u32 *pltmp = altmp; u32 ltmp; - u8 number=0x00; // The number of register vale + u8 number = 0x00; /* The number of register vale */ u8 i; - // - // bit[31] SPI Enable. - // 1=perform synthesizer program operation. This bit will - // cleared automatically after the operation is completed. - // bit[30] SPI R/W Control - // 0=write, 1=read - // bit[29:24] SPI Data Format Length - // bit[17:4 ] RF Data bits. - // bit[3 :0 ] RF address. - switch( pHwData->phy_type ) - { + /* + * bit[31] SPI Enable. + * 1=perform synthesizer program operation. This bit will + * cleared automatically after the operation is completed. + * bit[30] SPI R/W Control + * 0=write, 1=read + * bit[29:24] SPI Data Format Length + * bit[17:4 ] RF Data bits. + * bit[3 :0 ] RF address. + */ + switch (pHwData->phy_type) { case RF_MAXIM_2825: - case RF_MAXIM_V1: // 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331) - number = sizeof(max2825_rf_data)/sizeof(max2825_rf_data[0]); - for( i=0; iphy_para[i] = max2825_rf_data[i];// Backup Rf parameter - pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2825_rf_data[i], 18); + case RF_MAXIM_V1: /* 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331) */ + number = sizeof(max2825_rf_data) / sizeof(max2825_rf_data[0]); + for (i = 0; i < number; i++) { + pHwData->phy_para[i] = max2825_rf_data[i]; /* Backup Rf parameter */ + pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(max2825_rf_data[i], 18); } break; - case RF_MAXIM_2827: - number = sizeof(max2827_rf_data)/sizeof(max2827_rf_data[0]); - for( i=0; iphy_para[i] = max2827_rf_data[i]; - pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2827_rf_data[i], 18); + pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(max2827_rf_data[i], 18); } break; - case RF_MAXIM_2828: - number = sizeof(max2828_rf_data)/sizeof(max2828_rf_data[0]); - for( i=0; iphy_para[i] = max2828_rf_data[i]; - pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2828_rf_data[i], 18); + pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(max2828_rf_data[i], 18); } break; - case RF_MAXIM_2829: - number = sizeof(max2829_rf_data)/sizeof(max2829_rf_data[0]); - for( i=0; iphy_para[i] = max2829_rf_data[i]; - pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2829_rf_data[i], 18); + pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(max2829_rf_data[i], 18); } break; - case RF_AIROHA_2230: - number = sizeof(al2230_rf_data)/sizeof(al2230_rf_data[0]); - for( i=0; iphy_para[i] = al2230_rf_data[i]; - pltmp[i] = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( al2230_rf_data[i], 20); + pltmp[i] = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse(al2230_rf_data[i], 20); } break; - case RF_AIROHA_2230S: - number = sizeof(al2230s_rf_data)/sizeof(al2230s_rf_data[0]); - for( i=0; iphy_para[i] = al2230s_rf_data[i]; - pltmp[i] = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( al2230s_rf_data[i], 20); + pltmp[i] = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse(al2230s_rf_data[i], 20); } break; - case RF_AIROHA_7230: - - //Start to fill RF parameters, PLL_ON should be pulled low. - Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000000 ); -#ifdef _PE_STATE_DUMP_ + /* Start to fill RF parameters, PLL_ON should be pulled low. */ + Wb35Reg_WriteSync(pHwData, 0x03dc, 0x00000000); + #ifdef _PE_STATE_DUMP_ printk("* PLL_ON low\n"); -#endif - - number = sizeof(al7230_rf_data_24)/sizeof(al7230_rf_data_24[0]); + #endif + number = sizeof(al7230_rf_data_24) / sizeof(al7230_rf_data_24[0]); Set_ChanIndep_RfData_al7230_24(pHwData, pltmp, number); break; - case RF_WB_242: - case RF_WB_242_1: // 20060619.5 Add - number = sizeof(w89rf242_rf_data)/sizeof(w89rf242_rf_data[0]); - for( i=0; iVCO_trim<<4; + if (i == 4) { /* Update the VCO trim from EEPROM */ + ltmp &= ~0xff0; /* Mask bit4 ~bit11 */ + ltmp |= pHwData->VCO_trim << 4; } pHwData->phy_para[i] = ltmp; - pltmp[i] = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( ltmp, 24); + pltmp[i] = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse(ltmp, 24); } break; } pHwData->phy_number = number; - // The 16 is the maximum capability of hardware. Here use 12 - if( number > 12 ) { - //Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 12, NO_INCREMENT ); - for( i=0; i<12; i++ ) // For Al2230 - Wb35Reg_WriteSync( pHwData, 0x0864, pltmp[i] ); + /* The 16 is the maximum capability of hardware. Here use 12 */ + if (number > 12) { + for (i = 0; i < 12; i++) /* For Al2230 */ + Wb35Reg_WriteSync(pHwData, 0x0864, pltmp[i]); pltmp += 12; number -= 12; } - // Write to register. number must less and equal than 16 - for( i=0; iCalOneTime ) + /* Calibration only 1 time */ + if (pHwData->CalOneTime) return; pHwData->CalOneTime = 1; - switch( pHwData->phy_type ) - { - case RF_AIROHA_2230: - - // 20060511.1 --- Modifying the follow step for Rx issue----------------- - ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( (0x07<<20)|0xE168E, 20); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - msleep(10); - ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( al2230_rf_data[7], 20); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - msleep(10); - - case RF_AIROHA_2230S: // 20060420 Add this - - // 20060511.1 --- Modifying the follow step for Rx issue----------------- - Wb35Reg_WriteSync( pHwData, 0x03d4, 0x80 );// regulator on only - msleep(10); // Modify 20051221.1.b - - Wb35Reg_WriteSync( pHwData, 0x03d4, 0xa0 );// PLL_PD REF_PD set to 0 - msleep(10); // Modify 20051221.1.b - - Wb35Reg_WriteSync( pHwData, 0x03d4, 0xe0 );// MLK_EN - Wb35Reg_WriteSync( pHwData, 0x03b0, 1 );// Reset hardware first - msleep(10); // Add this 20051221.1.b - //------------------------------------------------------------------------ - - // The follow code doesn't use the burst-write mode - //phy_set_rf_data(phw_data, 0x0F, (0x0F<<20) | 0xF01A0); //Raise Initial Setting - ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( (0x0F<<20) | 0xF01A0, 20); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - - ltmp = pHwData->reg.BB5C & 0xfffff000; - Wb35Reg_WriteSync( pHwData, 0x105c, ltmp ); - pHwData->reg.BB50 |= 0x13;//(MASK_IQCAL_MODE|MASK_CALIB_START);//20060315.1 modify - Wb35Reg_WriteSync(pHwData, 0x1050, pHwData->reg.BB50); - msleep(5); - - //phy_set_rf_data(phw_data, 0x0F, (0x0F<<20) | 0xF01B0); //Activate Filter Cal. - ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( (0x0F<<20) | 0xF01B0, 20); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - msleep(5); - - //phy_set_rf_data(phw_data, 0x0F, (0x0F<<20) | 0xF01e0); //Activate TX DCC - ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( (0x0F<<20) | 0xF01E0, 20); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - msleep(5); - - //phy_set_rf_data(phw_data, 0x0F, (0x0F<<20) | 0xF01A0); //Resotre Initial Setting - ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( (0x0F<<20) | 0xF01A0, 20); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - -// //Force TXI(Q)P(N) to normal control - Wb35Reg_WriteSync( pHwData, 0x105c, pHwData->reg.BB5C ); - pHwData->reg.BB50 &= ~0x13;//(MASK_IQCAL_MODE|MASK_CALIB_START); - Wb35Reg_WriteSync( pHwData, 0x1050, pHwData->reg.BB50); - break; - - case RF_AIROHA_7230: - - //RF parameters have filled completely, PLL_ON should be - //pulled high - Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000080 ); - #ifdef _PE_STATE_DUMP_ - printk("* PLL_ON high\n"); - #endif - - //2.4GHz - //ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x1ABA8F; - //Wb35Reg_WriteSync pHwData, 0x0864, ltmp ); - //msleep(1); // Sleep 1 ms - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x9ABA8F; - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - msleep(5); - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x3ABA8F; - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - msleep(5); - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x1ABA8F; - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - msleep(5); - - //5GHz - Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000000 ); - #ifdef _PE_STATE_DUMP_ - printk("* PLL_ON low\n"); - #endif - - number = sizeof(al7230_rf_data_50)/sizeof(al7230_rf_data_50[0]); - Set_ChanIndep_RfData_al7230_50(pHwData, pltmp, number); - // Write to register. number must less and equal than 16 - for( i=0; ireg.BB5C & 0xfffff000; - Wb35Reg_WriteSync( pHwData, 0x105c, ltmp ); - Wb35Reg_WriteSync( pHwData, 0x1058, 0 ); - pHwData->reg.BB50 |= 0x3;//(MASK_IQCAL_MODE|MASK_CALIB_START);//20060630 - Wb35Reg_WriteSync(pHwData, 0x1050, pHwData->reg.BB50); - - //----- Calibration (1). VCO frequency calibration - //Calibration (1a.0). Synthesizer reset (HTHo corrected 2005/05/10) - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x0F<<24) | 0x00101E, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - msleep(5); // Sleep 5ms - //Calibration (1a). VCO frequency calibration mode ; waiting 2msec VCO calibration time - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFE69c0, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - msleep(2); // Sleep 2ms - - //----- Calibration (2). TX baseband Gm-C filter auto-tuning - //Calibration (2a). turn off ENCAL signal - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xF8EBC0, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - //Calibration (2b.0). TX filter auto-tuning BW: TFLBW=101 (TC5376A default) - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x07<<24) | 0x0C68CE, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - //Calibration (2b). send TX reset signal (HTHo corrected May 10, 2005) - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x0F<<24) | 0x00201E, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - //Calibration (2c). turn-on TX Gm-C filter auto-tuning - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFCEBC0, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - udelay(150); // Sleep 150 us - //turn off ENCAL signal - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xF8EBC0, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - - //----- Calibration (3). RX baseband Gm-C filter auto-tuning - //Calibration (3a). turn off ENCAL signal - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - //Calibration (3b.0). RX filter auto-tuning BW: RFLBW=100 (TC5376A+corner default; July 26, 2005) - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x07<<24) | 0x0C68CE, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - //Calibration (3b). send RX reset signal (HTHo corrected May 10, 2005) - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x0F<<24) | 0x00401E, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - //Calibration (3c). turn-on RX Gm-C filter auto-tuning - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFEEDC0, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - udelay(150); // Sleep 150 us - //Calibration (3e). turn off ENCAL signal - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - - //----- Calibration (4). TX LO leakage calibration - //Calibration (4a). TX LO leakage calibration - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFD6BC0, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - udelay(150); // Sleep 150 us - - //----- Calibration (5). RX DC offset calibration - //Calibration (5a). turn off ENCAL signal and set to RX SW DC caliration mode - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - //Calibration (5b). turn off AGC servo-loop & RSSI - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x01<<24) | 0xEBFFC2, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - - //; for LNA=11 -------- - //Calibration (5c-h). RX DC offset current bias ON; & LNA=11; RXVGA=111111 - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x06<<24) | 0x343FCC, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - //Calibration (5d). turn on RX DC offset cal function; and waiting 2 msec cal time - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFF6DC0, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - msleep(2); // Sleep 2ms - //Calibration (5f). turn off ENCAL signal - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - - //; for LNA=10 -------- - //Calibration (5c-m). RX DC offset current bias ON; & LNA=10; RXVGA=111111 - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x06<<24) | 0x342FCC, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - //Calibration (5d). turn on RX DC offset cal function; and waiting 2 msec cal time - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFF6DC0, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - msleep(2); // Sleep 2ms - //Calibration (5f). turn off ENCAL signal - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - - //; for LNA=01 -------- - //Calibration (5c-m). RX DC offset current bias ON; & LNA=01; RXVGA=111111 - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x06<<24) | 0x341FCC, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - //Calibration (5d). turn on RX DC offset cal function; and waiting 2 msec cal time - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFF6DC0, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - msleep(2); // Sleep 2ms - //Calibration (5f). turn off ENCAL signal - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - - //; for LNA=00 -------- - //Calibration (5c-l). RX DC offset current bias ON; & LNA=00; RXVGA=111111 - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x06<<24) | 0x340FCC, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - //Calibration (5d). turn on RX DC offset cal function; and waiting 2 msec cal time - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFF6DC0, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - msleep(2); // Sleep 2ms - //Calibration (5f). turn off ENCAL signal - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - //Calibration (5g). turn on AGC servo-loop - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x01<<24) | 0xEFFFC2, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - - //; ----- Calibration (7). Switch RF chip to normal mode - //0x00 0xF86100 ; 3E184 ; Switch RF chip to normal mode -// msleep(10); // @@ 20060721 - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xF86100, 24); - Wb35Reg_WriteSync( pHwData, 0x0864, ltmp ); - msleep(5); // Sleep 5 ms - -// //write back -// Wb35Reg_WriteSync(pHwData, 0x105c, pHwData->reg.BB5C); -// pHwData->reg.BB50 &= ~0x13;//(MASK_IQCAL_MODE|MASK_CALIB_START); // 20060315.1 fix -// Wb35Reg_WriteSync(pHwData, 0x1050, pHwData->reg.BB50); -// msleep(1); // Sleep 1 ms - break; + switch (pHwData->phy_type) { + case RF_AIROHA_2230: + ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse((0x07 << 20) | 0xE168E, 20); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + msleep(10); + ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse(al2230_rf_data[7], 20); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + msleep(10); + case RF_AIROHA_2230S: + Wb35Reg_WriteSync(pHwData, 0x03d4, 0x80); /* regulator on only */ + msleep(10); + Wb35Reg_WriteSync(pHwData, 0x03d4, 0xa0); /* PLL_PD REF_PD set to 0 */ + msleep(10); + Wb35Reg_WriteSync(pHwData, 0x03d4, 0xe0); /* MLK_EN */ + Wb35Reg_WriteSync(pHwData, 0x03b0, 1); /* Reset hardware first */ + msleep(10); + /* ========================================================= */ + + /* The follow code doesn't use the burst-write mode */ + ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse((0x0F<<20) | 0xF01A0, 20); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + + ltmp = pHwData->reg.BB5C & 0xfffff000; + Wb35Reg_WriteSync(pHwData, 0x105c, ltmp); + pHwData->reg.BB50 |= 0x13; /* (MASK_IQCAL_MODE|MASK_CALIB_START) */ + Wb35Reg_WriteSync(pHwData, 0x1050, pHwData->reg.BB50); + msleep(5); + + ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse((0x0F << 20) | 0xF01B0, 20); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + msleep(5); + + ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse((0x0F << 20) | 0xF01E0, 20); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + msleep(5); + + ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse((0x0F << 20) | 0xF01A0, 20); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp) ; + + Wb35Reg_WriteSync(pHwData, 0x105c, pHwData->reg.BB5C); + pHwData->reg.BB50 &= ~0x13; /* (MASK_IQCAL_MODE|MASK_CALIB_START); */ + Wb35Reg_WriteSync(pHwData, 0x1050, pHwData->reg.BB50); + break; + case RF_AIROHA_7230: + /* RF parameters have filled completely, PLL_ON should be pulled high */ + Wb35Reg_WriteSync(pHwData, 0x03dc, 0x00000080); + #ifdef _PE_STATE_DUMP_ + printk("* PLL_ON high\n"); + #endif + + /* 2.4GHz */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x9ABA8F; + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + msleep(5); + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x3ABA8F; + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + msleep(5); + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x1ABA8F; + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + msleep(5); + + /* 5GHz */ + Wb35Reg_WriteSync(pHwData, 0x03dc, 0x00000000); + #ifdef _PE_STATE_DUMP_ + printk("* PLL_ON low\n"); + #endif + + number = sizeof(al7230_rf_data_50) / sizeof(al7230_rf_data_50[0]); + Set_ChanIndep_RfData_al7230_50(pHwData, pltmp, number); + /* Write to register. number must less and equal than 16 */ + for (i = 0; i < number; i++) + Wb35Reg_WriteSync(pHwData, 0x0864, pltmp[i]); + msleep(5); + + Wb35Reg_WriteSync(pHwData, 0x03dc, 0x00000080); + #ifdef _PE_STATE_DUMP_ + printk("* PLL_ON high\n"); + #endif + + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x9ABA8F; + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + msleep(5); + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x3ABA8F; + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + msleep(5); + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x12BACF; + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + msleep(5); + break; + case RF_WB_242: + case RF_WB_242_1: + /* for FA5976A */ + ltmp = pHwData->reg.BB5C & 0xfffff000; + Wb35Reg_WriteSync(pHwData, 0x105c, ltmp); + Wb35Reg_WriteSync(pHwData, 0x1058, 0); + pHwData->reg.BB50 |= 0x3; /* (MASK_IQCAL_MODE|MASK_CALIB_START); */ + Wb35Reg_WriteSync(pHwData, 0x1050, pHwData->reg.BB50); + + /* ----- Calibration (1). VCO frequency calibration */ + /* Calibration (1a.0). Synthesizer reset */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x0F<<24) | 0x00101E, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + msleep(5); + /* Calibration (1a). VCO frequency calibration mode ; waiting 2msec VCO calibration time */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x00<<24) | 0xFE69c0, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + msleep(2); + + /* ----- Calibration (2). TX baseband Gm-C filter auto-tuning */ + /* Calibration (2a). turn off ENCAL signal */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x00<<24) | 0xF8EBC0, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + /* Calibration (2b.0). TX filter auto-tuning BW: TFLBW=101 (TC5376A default) */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x07<<24) | 0x0C68CE, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + /* Calibration (2b). send TX reset signal */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x0F<<24) | 0x00201E, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + /* Calibration (2c). turn-on TX Gm-C filter auto-tuning */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x00<<24) | 0xFCEBC0, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + udelay(150); /* Sleep 150 us */ + /* turn off ENCAL signal */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x00<<24) | 0xF8EBC0, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + + /* ----- Calibration (3). RX baseband Gm-C filter auto-tuning */ + /* Calibration (3a). turn off ENCAL signal */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x00<<24) | 0xFAEDC0, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + /* Calibration (3b.0). RX filter auto-tuning BW: RFLBW=100 (TC5376A+corner default;) */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x07<<24) | 0x0C68CE, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + /* Calibration (3b). send RX reset signal */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x0F<<24) | 0x00401E, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + /* Calibration (3c). turn-on RX Gm-C filter auto-tuning */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x00<<24) | 0xFEEDC0, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + udelay(150); /* Sleep 150 us */ + /* Calibration (3e). turn off ENCAL signal */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x00<<24) | 0xFAEDC0, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + + /* ----- Calibration (4). TX LO leakage calibration */ + /* Calibration (4a). TX LO leakage calibration */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x00<<24) | 0xFD6BC0, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + udelay(150); /* Sleep 150 us */ + + /* ----- Calibration (5). RX DC offset calibration */ + /* Calibration (5a). turn off ENCAL signal and set to RX SW DC calibration mode */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x00<<24) | 0xFAEDC0, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + /* Calibration (5b). turn off AGC servo-loop & RSSI */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x01<<24) | 0xEBFFC2, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + + /* for LNA=11 -------- */ + /* Calibration (5c-h). RX DC offset current bias ON; & LNA=11; RXVGA=111111 */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x06<<24) | 0x343FCC, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + /* Calibration (5d). turn on RX DC offset cal function; and waiting 2 msec cal time */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x00<<24) | 0xFF6DC0, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + msleep(2); + /* Calibration (5f). turn off ENCAL signal */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x00<<24) | 0xFAEDC0, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + + /* for LNA=10 -------- */ + /* Calibration (5c-m). RX DC offset current bias ON; & LNA=10; RXVGA=111111 */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x06<<24) | 0x342FCC, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + /* Calibration (5d). turn on RX DC offset cal function; and waiting 2 msec cal time */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x00<<24) | 0xFF6DC0, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + msleep(2); + /* Calibration (5f). turn off ENCAL signal */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x00<<24) | 0xFAEDC0, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + + /* for LNA=01 -------- */ + /* Calibration (5c-m). RX DC offset current bias ON; & LNA=01; RXVGA=111111 */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x06<<24) | 0x341FCC, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + /* Calibration (5d). turn on RX DC offset cal function; and waiting 2 msec cal time */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x00<<24) | 0xFF6DC0, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + msleep(2); + /* Calibration (5f). turn off ENCAL signal */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x00<<24) | 0xFAEDC0, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + + /* for LNA=00 -------- */ + /* Calibration (5c-l). RX DC offset current bias ON; & LNA=00; RXVGA=111111 */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x06<<24) | 0x340FCC, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + /* Calibration (5d). turn on RX DC offset cal function; and waiting 2 msec cal time */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x00<<24) | 0xFF6DC0, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + msleep(2); + /* Calibration (5f). turn off ENCAL signal */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x00<<24) | 0xFAEDC0, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + /* Calibration (5g). turn on AGC servo-loop */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x01<<24) | 0xEFFFC2, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + + /* ----- Calibration (7). Switch RF chip to normal mode */ + /* 0x00 0xF86100 ; 3E184 ; Switch RF chip to normal mode */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse((0x00<<24) | 0xF86100, 24); + Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); + msleep(5); + break; } } -void BBProcessor_AL7230_2400( struct hw_data * pHwData) +void BBProcessor_AL7230_2400(struct hw_data *pHwData) { struct wb35_reg *reg = &pHwData->reg; u32 pltmp[12]; - pltmp[0] = 0x16A8337A; // 0x16a5215f; // 0x1000 AGC_Ctrl1 - pltmp[1] = 0x9AFF9AA6; // 0x9aff9ca6; // 0x1004 AGC_Ctrl2 - pltmp[2] = 0x55D00A04; // 0x55d00a04; // 0x1008 AGC_Ctrl3 - pltmp[3] = 0xFFF72031; // 0xFfFf2138; // 0x100c AGC_Ctrl4 + pltmp[0] = 0x16A8337A; /* 0x1000 AGC_Ctrl1 */ + pltmp[1] = 0x9AFF9AA6; /* 0x1004 AGC_Ctrl2 */ + pltmp[2] = 0x55D00A04; /* 0x1008 AGC_Ctrl3 */ + pltmp[3] = 0xFFF72031; /* 0x100c AGC_Ctrl4 */ reg->BB0C = 0xFFF72031; - pltmp[4] = 0x0FacDCC5; // 0x1010 AGC_Ctrl5 // 20050927 0x0FacDCB7 - pltmp[5] = 0x00CAA333; // 0x00eaa333; // 0x1014 AGC_Ctrl6 - pltmp[6] = 0xF2211111; // 0x11111111; // 0x1018 AGC_Ctrl7 - pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8 - pltmp[8] = 0x06443440; // 0x1020 AGC_Ctrl9 - pltmp[9] = 0xA8002A79; // 0xa9002A79; // 0x1024 AGC_Ctrl10 - pltmp[10] = 0x40000528; // 20050927 0x40000228 - pltmp[11] = 0x232D7F30; // 0x23457f30;// 0x102c A_ACQ_Ctrl + pltmp[4] = 0x0FacDCC5; /* 0x1010 AGC_Ctrl5 */ + pltmp[5] = 0x00CAA333; /* 0x1014 AGC_Ctrl6 */ + pltmp[6] = 0xF2211111; /* 0x1018 AGC_Ctrl7 */ + pltmp[7] = 0x0FA3F0ED; /* 0x101c AGC_Ctrl8 */ + pltmp[8] = 0x06443440; /* 0x1020 AGC_Ctrl9 */ + pltmp[9] = 0xA8002A79; /* 0x1024 AGC_Ctrl10 */ + pltmp[10] = 0x40000528; + pltmp[11] = 0x232D7F30; /* 0x102c A_ACQ_Ctrl */ reg->BB2C = 0x232D7F30; - Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT ); + Wb35Reg_BurstWrite(pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT); - pltmp[0] = 0x00002c54; // 0x1030 B_ACQ_Ctrl + pltmp[0] = 0x00002c54; /* 0x1030 B_ACQ_Ctrl */ reg->BB30 = 0x00002c54; - pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl - pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl - pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter + pltmp[1] = 0x00C0D6C5; /* 0x1034 A_TXRX_Ctrl */ + pltmp[2] = 0x5B2C8769; /* 0x1038 B_TXRX_Ctrl */ + pltmp[3] = 0x00000000; /* 0x103c 11a TX LS filter */ reg->BB3C = 0x00000000; - pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter - pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter - pltmp[6] = 0x00332C1B; // 0x00453B24; // 0x1048 11b TX RC filter - pltmp[7] = 0x0A00FEFF; // 0x0E00FEFF; // 0x104c 11b TX RC filter - pltmp[8] = 0x2B106208; // 0x1050 MODE_Ctrl + pltmp[4] = 0x00003F29; /* 0x1040 11a TX LS filter */ + pltmp[5] = 0x0EFEFBFE; /* 0x1044 11a TX LS filter */ + pltmp[6] = 0x00332C1B; /* 0x1048 11b TX RC filter */ + pltmp[7] = 0x0A00FEFF; /* 0x104c 11b TX RC filter */ + pltmp[8] = 0x2B106208; /* 0x1050 MODE_Ctrl */ reg->BB50 = 0x2B106208; - pltmp[9] = 0; // 0x1054 + pltmp[9] = 0; /* 0x1054 */ reg->BB54 = 0x00000000; - pltmp[10] = 0x52524242; // 0x64645252; // 0x1058 IQ_Alpha + pltmp[10] = 0x52524242; /* 0x1058 IQ_Alpha */ reg->BB58 = 0x52524242; - pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel - Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT ); - + pltmp[11] = 0xAA0AC000; /* 0x105c DC_Cancel */ + Wb35Reg_BurstWrite(pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT); } -void BBProcessor_AL7230_5000( struct hw_data * pHwData) +void BBProcessor_AL7230_5000(struct hw_data *pHwData) { struct wb35_reg *reg = &pHwData->reg; u32 pltmp[12]; - pltmp[0] = 0x16AA6678; // 0x1000 AGC_Ctrl1 - pltmp[1] = 0x9AFFA0B2; // 0x1004 AGC_Ctrl2 - pltmp[2] = 0x55D00A04; // 0x1008 AGC_Ctrl3 - pltmp[3] = 0xEFFF233E; // 0x100c AGC_Ctrl4 + pltmp[0] = 0x16AA6678; /* 0x1000 AGC_Ctrl1 */ + pltmp[1] = 0x9AFFA0B2; /* 0x1004 AGC_Ctrl2 */ + pltmp[2] = 0x55D00A04; /* 0x1008 AGC_Ctrl3 */ + pltmp[3] = 0xEFFF233E; /* 0x100c AGC_Ctrl4 */ reg->BB0C = 0xEFFF233E; - pltmp[4] = 0x0FacDCC5; // 0x1010 AGC_Ctrl5 // 20050927 0x0FacDCB7 - pltmp[5] = 0x00CAA333; // 0x1014 AGC_Ctrl6 - pltmp[6] = 0xF2432111; // 0x1018 AGC_Ctrl7 - pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8 - pltmp[8] = 0x05C43440; // 0x1020 AGC_Ctrl9 - pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10 - pltmp[10] = 0x40000528; // 20050927 0x40000228 - pltmp[11] = 0x232FDF30;// 0x102c A_ACQ_Ctrl + pltmp[4] = 0x0FacDCC5; /* 0x1010 AGC_Ctrl5 */ + pltmp[5] = 0x00CAA333; /* 0x1014 AGC_Ctrl6 */ + pltmp[6] = 0xF2432111; /* 0x1018 AGC_Ctrl7 */ + pltmp[7] = 0x0FA3F0ED; /* 0x101c AGC_Ctrl8 */ + pltmp[8] = 0x05C43440; /* 0x1020 AGC_Ctrl9 */ + pltmp[9] = 0x00002A79; /* 0x1024 AGC_Ctrl10 */ + pltmp[10] = 0x40000528; + pltmp[11] = 0x232FDF30;/* 0x102c A_ACQ_Ctrl */ reg->BB2C = 0x232FDF30; - Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT ); + Wb35Reg_BurstWrite(pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT); - pltmp[0] = 0x80002C7C; // 0x1030 B_ACQ_Ctrl - pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl - pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl - pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter + pltmp[0] = 0x80002C7C; /* 0x1030 B_ACQ_Ctrl */ + pltmp[1] = 0x00C0D6C5; /* 0x1034 A_TXRX_Ctrl */ + pltmp[2] = 0x5B2C8769; /* 0x1038 B_TXRX_Ctrl */ + pltmp[3] = 0x00000000; /* 0x103c 11a TX LS filter */ reg->BB3C = 0x00000000; - pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter - pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter - pltmp[6] = 0x00332C1B; // 0x1048 11b TX RC filter - pltmp[7] = 0x0A00FEFF; // 0x104c 11b TX RC filter - pltmp[8] = 0x2B107208; // 0x1050 MODE_Ctrl + pltmp[4] = 0x00003F29; /* 0x1040 11a TX LS filter */ + pltmp[5] = 0x0EFEFBFE; /* 0x1044 11a TX LS filter */ + pltmp[6] = 0x00332C1B; /* 0x1048 11b TX RC filter */ + pltmp[7] = 0x0A00FEFF; /* 0x104c 11b TX RC filter */ + pltmp[8] = 0x2B107208; /* 0x1050 MODE_Ctrl */ reg->BB50 = 0x2B107208; - pltmp[9] = 0; // 0x1054 + pltmp[9] = 0; /* 0x1054 */ reg->BB54 = 0x00000000; - pltmp[10] = 0x52524242; // 0x1058 IQ_Alpha + pltmp[10] = 0x52524242; /* 0x1058 IQ_Alpha */ reg->BB58 = 0x52524242; - pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel - Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT ); - + pltmp[11] = 0xAA0AC000; /* 0x105c DC_Cancel */ + Wb35Reg_BurstWrite(pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT); } -//============================================================================================================= -// BBProcessorPowerupInit -- -// -// Description: -// Initialize the Baseband processor. -// -// Arguments: -// pHwData - Handle of the USB Device. -// -// Return values: -// None. -//============================================================================================================= -void -BBProcessor_initial( struct hw_data * pHwData ) +/* + * =========================================================================== + * BBProcessorPowerupInit -- + * + * Description: + * Initialize the Baseband processor. + * + * Arguments: + * pHwData - Handle of the USB Device. + * + * Return values: + * None. + *============================================================================ + */ +void BBProcessor_initial(struct hw_data *pHwData) { struct wb35_reg *reg = &pHwData->reg; u32 i, pltmp[12]; - switch( pHwData->phy_type ) - { - case RF_MAXIM_V1: // Initializng the Winbond 2nd BB(with Phy board (v1) + Maxim 331) - - pltmp[0] = 0x16F47E77; // 0x1000 AGC_Ctrl1 - pltmp[1] = 0x9AFFAEA4; // 0x1004 AGC_Ctrl2 - pltmp[2] = 0x55D00A04; // 0x1008 AGC_Ctrl3 - pltmp[3] = 0xEFFF1A34; // 0x100c AGC_Ctrl4 - reg->BB0C = 0xEFFF1A34; - pltmp[4] = 0x0FABE0B7; // 0x1010 AGC_Ctrl5 - pltmp[5] = 0x00CAA332; // 0x1014 AGC_Ctrl6 - pltmp[6] = 0xF6632111; // 0x1018 AGC_Ctrl7 - pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8 - pltmp[8] = 0x04CC3640; // 0x1020 AGC_Ctrl9 - pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10 - pltmp[10] = (pHwData->phy_type==3) ? 0x40000a28 : 0x40000228; // 0x1028 MAXIM_331(b31=0) + WBRF_V1(b11=1) : MAXIM_331(b31=0) + WBRF_V2(b11=0) - pltmp[11] = 0x232FDF30; // 0x102c A_ACQ_Ctrl - reg->BB2C = 0x232FDF30; //Modify for 33's 1.0.95.xxx version, antenna 1 - Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT ); - - pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl - reg->BB30 = 0x00002C54; - pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl - pltmp[2] = 0x5B6C8769; // 0x1038 B_TXRX_Ctrl - pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter - reg->BB3C = 0x00000000; - pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter - pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter - pltmp[6] = 0x00453B24; // 0x1048 11b TX RC filter - pltmp[7] = 0x0E00FEFF; // 0x104c 11b TX RC filter - pltmp[8] = 0x27106208; // 0x1050 MODE_Ctrl - reg->BB50 = 0x27106208; - pltmp[9] = 0; // 0x1054 - reg->BB54 = 0x00000000; - pltmp[10] = 0x64646464; // 0x1058 IQ_Alpha - reg->BB58 = 0x64646464; - pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel - Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT ); - - Wb35Reg_Write( pHwData, 0x1070, 0x00000045 ); - break; - - //------------------------------------------------------------------ - //[20040722 WK] - //Only for baseband version 2 -// case RF_MAXIM_317: - case RF_MAXIM_2825: - case RF_MAXIM_2827: - case RF_MAXIM_2828: - - pltmp[0] = 0x16b47e77; // 0x1000 AGC_Ctrl1 - pltmp[1] = 0x9affaea4; // 0x1004 AGC_Ctrl2 - pltmp[2] = 0x55d00a04; // 0x1008 AGC_Ctrl3 - pltmp[3] = 0xefff1a34; // 0x100c AGC_Ctrl4 - reg->BB0C = 0xefff1a34; - pltmp[4] = 0x0fabe0b7; // 0x1010 AGC_Ctrl5 - pltmp[5] = 0x00caa332; // 0x1014 AGC_Ctrl6 - pltmp[6] = 0xf6632111; // 0x1018 AGC_Ctrl7 - pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8 - pltmp[8] = 0x04CC3640; // 0x1020 AGC_Ctrl9 - pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10 - pltmp[10] = 0x40000528; // 0x40000128; Modify for 33's 1.0.95 - pltmp[11] = 0x232fdf30; // 0x102c A_ACQ_Ctrl - reg->BB2C = 0x232fdf30; //Modify for 33's 1.0.95.xxx version, antenna 1 - Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT ); - - pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl - reg->BB30 = 0x00002C54; - pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl - pltmp[2] = 0x5B6C8769; // 0x1038 B_TXRX_Ctrl - pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter - reg->BB3C = 0x00000000; - pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter - pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter - pltmp[6] = 0x00453B24; // 0x1048 11b TX RC filter - pltmp[7] = 0x0D00FDFF; // 0x104c 11b TX RC filter - pltmp[8] = 0x27106208; // 0x1050 MODE_Ctrl - reg->BB50 = 0x27106208; - pltmp[9] = 0; // 0x1054 - reg->BB54 = 0x00000000; - pltmp[10] = 0x64646464; // 0x1058 IQ_Alpha - reg->BB58 = 0x64646464; - pltmp[11] = 0xAA28C000; // 0x105c DC_Cancel - Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT ); - - Wb35Reg_Write( pHwData, 0x1070, 0x00000045 ); - break; - - case RF_MAXIM_2829: - - pltmp[0] = 0x16b47e77; // 0x1000 AGC_Ctrl1 - pltmp[1] = 0x9affaea4; // 0x1004 AGC_Ctrl2 - pltmp[2] = 0x55d00a04; // 0x1008 AGC_Ctrl3 - pltmp[3] = 0xf4ff1632; // 0xefff1a34; // 0x100c AGC_Ctrl4 Modify for 33's 1.0.95 - reg->BB0C = 0xf4ff1632; // 0xefff1a34; Modify for 33's 1.0.95 - pltmp[4] = 0x0fabe0b7; // 0x1010 AGC_Ctrl5 - pltmp[5] = 0x00caa332; // 0x1014 AGC_Ctrl6 - pltmp[6] = 0xf8632112; // 0xf6632111; // 0x1018 AGC_Ctrl7 Modify for 33's 1.0.95 - pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8 - pltmp[8] = 0x04CC3640; // 0x1020 AGC_Ctrl9 - pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10 - pltmp[10] = 0x40000528; // 0x40000128; modify for 33's 1.0.95 - pltmp[11] = 0x232fdf30; // 0x102c A_ACQ_Ctrl - reg->BB2C = 0x232fdf30; //Modify for 33's 1.0.95.xxx version, antenna 1 - Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT ); - - pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl - reg->BB30 = 0x00002C54; - pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl - pltmp[2] = 0x5b2c8769; // 0x5B6C8769; // 0x1038 B_TXRX_Ctrl Modify for 33's 1.0.95 - pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter - reg->BB3C = 0x00000000; - pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter - pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter - pltmp[6] = 0x002c2617; // 0x00453B24; // 0x1048 11b TX RC filter Modify for 33's 1.0.95 - pltmp[7] = 0x0800feff; // 0x0D00FDFF; // 0x104c 11b TX RC filter Modify for 33's 1.0.95 - pltmp[8] = 0x27106208; // 0x1050 MODE_Ctrl - reg->BB50 = 0x27106208; - pltmp[9] = 0; // 0x1054 - reg->BB54 = 0x00000000; - pltmp[10] = 0x64644a4a; // 0x64646464; // 0x1058 IQ_Alpha Modify for 33's 1.0.95 - reg->BB58 = 0x64646464; - pltmp[11] = 0xAA28C000; // 0x105c DC_Cancel - Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT ); - - Wb35Reg_Write( pHwData, 0x1070, 0x00000045 ); - break; - - case RF_AIROHA_2230: - - pltmp[0] = 0X16764A77; // 0x1000 AGC_Ctrl1 //0x16765A77 - pltmp[1] = 0x9affafb2; // 0x1004 AGC_Ctrl2 - pltmp[2] = 0x55d00a04; // 0x1008 AGC_Ctrl3 - pltmp[3] = 0xFFFd203c; // 0xFFFb203a; // 0x100c AGC_Ctrl4 Modify for 33's 1.0.95.xxx version - reg->BB0C = 0xFFFd203c; - pltmp[4] = 0X0FBFDCc5; // 0X0FBFDCA0; // 0x1010 AGC_Ctrl5 //0x0FB2E0B7 Modify for 33's 1.0.95.xxx version - pltmp[5] = 0x00caa332; // 0x00caa333; // 0x1014 AGC_Ctrl6 Modify for 33's 1.0.95.xxx version - pltmp[6] = 0XF6632111; // 0XF1632112; // 0x1018 AGC_Ctrl7 //0xf6632112 Modify for 33's 1.0.95.xxx version - pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8 - pltmp[8] = 0x04C43640; // 0x1020 AGC_Ctrl9 - pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10 - pltmp[10] = 0X40000528; //0x40000228 - pltmp[11] = 0x232dfF30; // 0x232A9F30; // 0x102c A_ACQ_Ctrl //0x232a9730 - reg->BB2C = 0x232dfF30; //Modify for 33's 1.0.95.xxx version, antenna 1 - Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT ); - - pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl - reg->BB30 = 0x00002C54; - pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl - pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl //0x5B6C8769 - pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter - reg->BB3C = 0x00000000; - pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter - pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter - pltmp[6] = BB48_DEFAULT_AL2230_11G; // 0x1048 11b TX RC filter 20060613.2 - reg->BB48 = BB48_DEFAULT_AL2230_11G; // 20051221 ch14 20060613.2 - pltmp[7] = BB4C_DEFAULT_AL2230_11G; // 0x104c 11b TX RC filter 20060613.2 - reg->BB4C = BB4C_DEFAULT_AL2230_11G; // 20060613.1 20060613.2 - pltmp[8] = 0x27106200; // 0x1050 MODE_Ctrl - reg->BB50 = 0x27106200; - pltmp[9] = 0; // 0x1054 - reg->BB54 = 0x00000000; - pltmp[10] = 0x52524242; // 0x1058 IQ_Alpha - reg->BB58 = 0x52524242; - pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel - Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT ); - - Wb35Reg_Write( pHwData, 0x1070, 0x00000045 ); - break; + switch (pHwData->phy_type) { + case RF_MAXIM_V1: /* Initializng the Winbond 2nd BB(with Phy board (v1) + Maxim 331) */ + pltmp[0] = 0x16F47E77; /* 0x1000 AGC_Ctrl1 */ + pltmp[1] = 0x9AFFAEA4; /* 0x1004 AGC_Ctrl2 */ + pltmp[2] = 0x55D00A04; /* 0x1008 AGC_Ctrl3 */ + pltmp[3] = 0xEFFF1A34; /* 0x100c AGC_Ctrl4 */ + reg->BB0C = 0xEFFF1A34; + pltmp[4] = 0x0FABE0B7; /* 0x1010 AGC_Ctrl5 */ + pltmp[5] = 0x00CAA332; /* 0x1014 AGC_Ctrl6 */ + pltmp[6] = 0xF6632111; /* 0x1018 AGC_Ctrl7 */ + pltmp[7] = 0x0FA3F0ED; /* 0x101c AGC_Ctrl8 */ + pltmp[8] = 0x04CC3640; /* 0x1020 AGC_Ctrl9 */ + pltmp[9] = 0x00002A79; /* 0x1024 AGC_Ctrl10 */ + pltmp[10] = (pHwData->phy_type == 3) ? 0x40000a28 : 0x40000228; /* 0x1028 MAXIM_331(b31=0) + WBRF_V1(b11=1) : MAXIM_331(b31=0) + WBRF_V2(b11=0) */ + pltmp[11] = 0x232FDF30; /* 0x102c A_ACQ_Ctrl */ + reg->BB2C = 0x232FDF30; /* Modify for 33's 1.0.95.xxx version, antenna 1 */ + Wb35Reg_BurstWrite(pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT); + + pltmp[0] = 0x00002C54; /* 0x1030 B_ACQ_Ctrl */ + reg->BB30 = 0x00002C54; + pltmp[1] = 0x00C0D6C5; /* 0x1034 A_TXRX_Ctrl */ + pltmp[2] = 0x5B6C8769; /* 0x1038 B_TXRX_Ctrl */ + pltmp[3] = 0x00000000; /* 0x103c 11a TX LS filter */ + reg->BB3C = 0x00000000; + pltmp[4] = 0x00003F29; /* 0x1040 11a TX LS filter */ + pltmp[5] = 0x0EFEFBFE; /* 0x1044 11a TX LS filter */ + pltmp[6] = 0x00453B24; /* 0x1048 11b TX RC filter */ + pltmp[7] = 0x0E00FEFF; /* 0x104c 11b TX RC filter */ + pltmp[8] = 0x27106208; /* 0x1050 MODE_Ctrl */ + reg->BB50 = 0x27106208; + pltmp[9] = 0; /* 0x1054 */ + reg->BB54 = 0x00000000; + pltmp[10] = 0x64646464; /* 0x1058 IQ_Alpha */ + reg->BB58 = 0x64646464; + pltmp[11] = 0xAA0AC000; /* 0x105c DC_Cancel */ + Wb35Reg_BurstWrite(pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT); + + Wb35Reg_Write(pHwData, 0x1070, 0x00000045); + break; - case RF_AIROHA_2230S: // 20060420 Add this - - pltmp[0] = 0X16764A77; // 0x1000 AGC_Ctrl1 //0x16765A77 - pltmp[1] = 0x9affafb2; // 0x1004 AGC_Ctrl2 - pltmp[2] = 0x55d00a04; // 0x1008 AGC_Ctrl3 - pltmp[3] = 0xFFFd203c; // 0xFFFb203a; // 0x100c AGC_Ctrl4 Modify for 33's 1.0.95.xxx version - reg->BB0C = 0xFFFd203c; - pltmp[4] = 0X0FBFDCc5; // 0X0FBFDCA0; // 0x1010 AGC_Ctrl5 //0x0FB2E0B7 Modify for 33's 1.0.95.xxx version - pltmp[5] = 0x00caa332; // 0x00caa333; // 0x1014 AGC_Ctrl6 Modify for 33's 1.0.95.xxx version - pltmp[6] = 0XF6632111; // 0XF1632112; // 0x1018 AGC_Ctrl7 //0xf6632112 Modify for 33's 1.0.95.xxx version - pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8 - pltmp[8] = 0x04C43640; // 0x1020 AGC_Ctrl9 - pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10 - pltmp[10] = 0X40000528; //0x40000228 - pltmp[11] = 0x232dfF30; // 0x232A9F30; // 0x102c A_ACQ_Ctrl //0x232a9730 - reg->BB2C = 0x232dfF30; //Modify for 33's 1.0.95.xxx version, antenna 1 - Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT ); - - pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl - reg->BB30 = 0x00002C54; - pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl - pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl //0x5B6C8769 - pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter - reg->BB3C = 0x00000000; - pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter - pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter - pltmp[6] = BB48_DEFAULT_AL2230_11G; // 0x1048 11b TX RC filter 20060613.2 - reg->BB48 = BB48_DEFAULT_AL2230_11G; // 20051221 ch14 20060613.2 - pltmp[7] = BB4C_DEFAULT_AL2230_11G; // 0x104c 11b TX RC filter 20060613.2 - reg->BB4C = BB4C_DEFAULT_AL2230_11G; // 20060613.1 - pltmp[8] = 0x27106200; // 0x1050 MODE_Ctrl - reg->BB50 = 0x27106200; - pltmp[9] = 0; // 0x1054 - reg->BB54 = 0x00000000; - pltmp[10] = 0x52523232; // 20060419 0x52524242; // 0x1058 IQ_Alpha - reg->BB58 = 0x52523232; // 20060419 0x52524242; - pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel - Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT ); - - Wb35Reg_Write( pHwData, 0x1070, 0x00000045 ); - break; + case RF_MAXIM_2825: + case RF_MAXIM_2827: + case RF_MAXIM_2828: + pltmp[0] = 0x16b47e77; /* 0x1000 AGC_Ctrl1 */ + pltmp[1] = 0x9affaea4; /* 0x1004 AGC_Ctrl2 */ + pltmp[2] = 0x55d00a04; /* 0x1008 AGC_Ctrl3 */ + pltmp[3] = 0xefff1a34; /* 0x100c AGC_Ctrl4 */ + reg->BB0C = 0xefff1a34; + pltmp[4] = 0x0fabe0b7; /* 0x1010 AGC_Ctrl5 */ + pltmp[5] = 0x00caa332; /* 0x1014 AGC_Ctrl6 */ + pltmp[6] = 0xf6632111; /* 0x1018 AGC_Ctrl7 */ + pltmp[7] = 0x0FA3F0ED; /* 0x101c AGC_Ctrl8 */ + pltmp[8] = 0x04CC3640; /* 0x1020 AGC_Ctrl9 */ + pltmp[9] = 0x00002A79; /* 0x1024 AGC_Ctrl10 */ + pltmp[10] = 0x40000528; + pltmp[11] = 0x232fdf30; /* 0x102c A_ACQ_Ctrl */ + reg->BB2C = 0x232fdf30; /* antenna 1 */ + Wb35Reg_BurstWrite(pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT); + + pltmp[0] = 0x00002C54; /* 0x1030 B_ACQ_Ctrl */ + reg->BB30 = 0x00002C54; + pltmp[1] = 0x00C0D6C5; /* 0x1034 A_TXRX_Ctrl */ + pltmp[2] = 0x5B6C8769; /* 0x1038 B_TXRX_Ctrl */ + pltmp[3] = 0x00000000; /* 0x103c 11a TX LS filter */ + reg->BB3C = 0x00000000; + pltmp[4] = 0x00003F29; /* 0x1040 11a TX LS filter */ + pltmp[5] = 0x0EFEFBFE; /* 0x1044 11a TX LS filter */ + pltmp[6] = 0x00453B24; /* 0x1048 11b TX RC filter */ + pltmp[7] = 0x0D00FDFF; /* 0x104c 11b TX RC filter */ + pltmp[8] = 0x27106208; /* 0x1050 MODE_Ctrl */ + reg->BB50 = 0x27106208; + pltmp[9] = 0; /* 0x1054 */ + reg->BB54 = 0x00000000; + pltmp[10] = 0x64646464; /* 0x1058 IQ_Alpha */ + reg->BB58 = 0x64646464; + pltmp[11] = 0xAA28C000; /* 0x105c DC_Cancel */ + Wb35Reg_BurstWrite(pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT); + + Wb35Reg_Write(pHwData, 0x1070, 0x00000045); + break; - case RF_AIROHA_7230: -/* - pltmp[0] = 0x16a84a77; // 0x1000 AGC_Ctrl1 - pltmp[1] = 0x9affafb2; // 0x1004 AGC_Ctrl2 - pltmp[2] = 0x55d00a04; // 0x1008 AGC_Ctrl3 - pltmp[3] = 0xFFFb203a; // 0x100c AGC_Ctrl4 - reg->BB0c = 0xFFFb203a; - pltmp[4] = 0x0FBFDCB7; // 0x1010 AGC_Ctrl5 - pltmp[5] = 0x00caa333; // 0x1014 AGC_Ctrl6 - pltmp[6] = 0xf6632112; // 0x1018 AGC_Ctrl7 - pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8 - pltmp[8] = 0x04C43640; // 0x1020 AGC_Ctrl9 - pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10 - pltmp[10] = 0x40000228; - pltmp[11] = 0x232A9F30;// 0x102c A_ACQ_Ctrl - reg->BB2c = 0x232A9F30; - Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT ); - - pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl - reg->BB30 = 0x00002C54; - pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl - pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl - pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter - reg->BB3c = 0x00000000; - pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter - pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter - pltmp[6] = 0x00453B24; // 0x1048 11b TX RC filter - pltmp[7] = 0x0E00FEFF; // 0x104c 11b TX RC filter - pltmp[8] = 0x27106200; // 0x1050 MODE_Ctrl - reg->BB50 = 0x27106200; - pltmp[9] = 0; // 0x1054 - reg->BB54 = 0x00000000; - pltmp[10] = 0x64645252; // 0x1058 IQ_Alpha - reg->BB58 = 0x64645252; - pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel - Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT ); -*/ - BBProcessor_AL7230_2400( pHwData ); - - Wb35Reg_Write( pHwData, 0x1070, 0x00000045 ); - break; + case RF_MAXIM_2829: + pltmp[0] = 0x16b47e77; /* 0x1000 AGC_Ctrl1 */ + pltmp[1] = 0x9affaea4; /* 0x1004 AGC_Ctrl2 */ + pltmp[2] = 0x55d00a04; /* 0x1008 AGC_Ctrl3 */ + pltmp[3] = 0xf4ff1632; /* 0x100c AGC_Ctrl4 */ + reg->BB0C = 0xf4ff1632; + pltmp[4] = 0x0fabe0b7; /* 0x1010 AGC_Ctrl5 */ + pltmp[5] = 0x00caa332; /* 0x1014 AGC_Ctrl6 */ + pltmp[6] = 0xf8632112; /* 0x1018 AGC_Ctrl7 */ + pltmp[7] = 0x0FA3F0ED; /* 0x101c AGC_Ctrl8 */ + pltmp[8] = 0x04CC3640; /* 0x1020 AGC_Ctrl9 */ + pltmp[9] = 0x00002A79; /* 0x1024 AGC_Ctrl10 */ + pltmp[10] = 0x40000528; + pltmp[11] = 0x232fdf30; /* 0x102c A_ACQ_Ctrl */ + reg->BB2C = 0x232fdf30; /* antenna 1 */ + Wb35Reg_BurstWrite(pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT); + + pltmp[0] = 0x00002C54; /* 0x1030 B_ACQ_Ctrl */ + reg->BB30 = 0x00002C54; + pltmp[1] = 0x00C0D6C5; /* 0x1034 A_TXRX_Ctrl */ + pltmp[2] = 0x5b2c8769; /* 0x1038 B_TXRX_Ctrl */ + pltmp[3] = 0x00000000; /* 0x103c 11a TX LS filter */ + reg->BB3C = 0x00000000; + pltmp[4] = 0x00003F29; /* 0x1040 11a TX LS filter */ + pltmp[5] = 0x0EFEFBFE; /* 0x1044 11a TX LS filter */ + pltmp[6] = 0x002c2617; /* 0x1048 11b TX RC filter */ + pltmp[7] = 0x0800feff; /* 0x104c 11b TX RC filter */ + pltmp[8] = 0x27106208; /* 0x1050 MODE_Ctrl */ + reg->BB50 = 0x27106208; + pltmp[9] = 0; /* 0x1054 */ + reg->BB54 = 0x00000000; + pltmp[10] = 0x64644a4a; /* 0x1058 IQ_Alpha */ + reg->BB58 = 0x64646464; + pltmp[11] = 0xAA28C000; /* 0x105c DC_Cancel */ + Wb35Reg_BurstWrite(pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT); + Wb35Reg_Write(pHwData, 0x1070, 0x00000045); + break; + case RF_AIROHA_2230: + pltmp[0] = 0X16764A77; /* 0x1000 AGC_Ctrl1 */ + pltmp[1] = 0x9affafb2; /* 0x1004 AGC_Ctrl2 */ + pltmp[2] = 0x55d00a04; /* 0x1008 AGC_Ctrl3 */ + pltmp[3] = 0xFFFd203c; /* 0x100c AGC_Ctrl4 */ + reg->BB0C = 0xFFFd203c; + pltmp[4] = 0X0FBFDCc5; /* 0x1010 AGC_Ctrl5 */ + pltmp[5] = 0x00caa332; /* 0x1014 AGC_Ctrl6 */ + pltmp[6] = 0XF6632111; /* 0x1018 AGC_Ctrl7 */ + pltmp[7] = 0x0FA3F0ED; /* 0x101c AGC_Ctrl8 */ + pltmp[8] = 0x04C43640; /* 0x1020 AGC_Ctrl9 */ + pltmp[9] = 0x00002A79; /* 0x1024 AGC_Ctrl10 */ + pltmp[10] = 0X40000528; + pltmp[11] = 0x232dfF30; /* 0x102c A_ACQ_Ctrl */ + reg->BB2C = 0x232dfF30; /* antenna 1 */ + Wb35Reg_BurstWrite(pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT); + + pltmp[0] = 0x00002C54; /* 0x1030 B_ACQ_Ctrl */ + reg->BB30 = 0x00002C54; + pltmp[1] = 0x00C0D6C5; /* 0x1034 A_TXRX_Ctrl */ + pltmp[2] = 0x5B2C8769; /* 0x1038 B_TXRX_Ctrl */ + pltmp[3] = 0x00000000; /* 0x103c 11a TX LS filter */ + reg->BB3C = 0x00000000; + pltmp[4] = 0x00003F29; /* 0x1040 11a TX LS filter */ + pltmp[5] = 0x0EFEFBFE; /* 0x1044 11a TX LS filter */ + pltmp[6] = BB48_DEFAULT_AL2230_11G; /* 0x1048 11b TX RC filter */ + reg->BB48 = BB48_DEFAULT_AL2230_11G; /* 20051221 ch14 */ + pltmp[7] = BB4C_DEFAULT_AL2230_11G; /* 0x104c 11b TX RC filter */ + reg->BB4C = BB4C_DEFAULT_AL2230_11G; + pltmp[8] = 0x27106200; /* 0x1050 MODE_Ctrl */ + reg->BB50 = 0x27106200; + pltmp[9] = 0; /* 0x1054 */ + reg->BB54 = 0x00000000; + pltmp[10] = 0x52524242; /* 0x1058 IQ_Alpha */ + reg->BB58 = 0x52524242; + pltmp[11] = 0xAA0AC000; /* 0x105c DC_Cancel */ + Wb35Reg_BurstWrite(pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT); + + Wb35Reg_Write(pHwData, 0x1070, 0x00000045); + break; + case RF_AIROHA_2230S: + pltmp[0] = 0X16764A77; /* 0x1000 AGC_Ctrl1 */ + pltmp[1] = 0x9affafb2; /* 0x1004 AGC_Ctrl2 */ + pltmp[2] = 0x55d00a04; /* 0x1008 AGC_Ctrl3 */ + pltmp[3] = 0xFFFd203c; /* 0x100c AGC_Ctrl4 */ + reg->BB0C = 0xFFFd203c; + pltmp[4] = 0X0FBFDCc5; /* 0x1010 AGC_Ctrl5 */ + pltmp[5] = 0x00caa332; /* 0x1014 AGC_Ctrl6 */ + pltmp[6] = 0XF6632111; /* 0x1018 AGC_Ctrl7 */ + pltmp[7] = 0x0FA3F0ED; /* 0x101c AGC_Ctrl8 */ + pltmp[8] = 0x04C43640; /* 0x1020 AGC_Ctrl9 */ + pltmp[9] = 0x00002A79; /* 0x1024 AGC_Ctrl10 */ + pltmp[10] = 0X40000528; + pltmp[11] = 0x232dfF30; /* 0x102c A_ACQ_Ctrl */ + reg->BB2C = 0x232dfF30; /* antenna 1 */ + Wb35Reg_BurstWrite(pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT); + + pltmp[0] = 0x00002C54; /* 0x1030 B_ACQ_Ctrl */ + reg->BB30 = 0x00002C54; + pltmp[1] = 0x00C0D6C5; /* 0x1034 A_TXRX_Ctrl */ + pltmp[2] = 0x5B2C8769; /* 0x1038 B_TXRX_Ctrl */ + pltmp[3] = 0x00000000; /* 0x103c 11a TX LS filter */ + reg->BB3C = 0x00000000; + pltmp[4] = 0x00003F29; /* 0x1040 11a TX LS filter */ + pltmp[5] = 0x0EFEFBFE; /* 0x1044 11a TX LS filter */ + pltmp[6] = BB48_DEFAULT_AL2230_11G; /* 0x1048 11b TX RC filter */ + reg->BB48 = BB48_DEFAULT_AL2230_11G; /* ch14 */ + pltmp[7] = BB4C_DEFAULT_AL2230_11G; /* 0x104c 11b TX RC filter */ + reg->BB4C = BB4C_DEFAULT_AL2230_11G; + pltmp[8] = 0x27106200; /* 0x1050 MODE_Ctrl */ + reg->BB50 = 0x27106200; + pltmp[9] = 0; /* 0x1054 */ + reg->BB54 = 0x00000000; + pltmp[10] = 0x52523232; /* 0x1058 IQ_Alpha */ + reg->BB58 = 0x52523232; + pltmp[11] = 0xAA0AC000; /* 0x105c DC_Cancel */ + Wb35Reg_BurstWrite(pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT); + + Wb35Reg_Write(pHwData, 0x1070, 0x00000045); + break; + case RF_AIROHA_7230: + BBProcessor_AL7230_2400(pHwData); - case RF_WB_242: - case RF_WB_242_1: // 20060619.5 Add - - pltmp[0] = 0x16A8525D; // 0x1000 AGC_Ctrl1 - pltmp[1] = 0x9AFF9ABA; // 0x1004 AGC_Ctrl2 - pltmp[2] = 0x55D00A04; // 0x1008 AGC_Ctrl3 - pltmp[3] = 0xEEE91C32; // 0x100c AGC_Ctrl4 - reg->BB0C = 0xEEE91C32; - pltmp[4] = 0x0FACDCC5; // 0x1010 AGC_Ctrl5 - pltmp[5] = 0x000AA344; // 0x1014 AGC_Ctrl6 - pltmp[6] = 0x22222221; // 0x1018 AGC_Ctrl7 - pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8 - pltmp[8] = 0x04CC3440; // 20051018 0x03CB3440; // 0x1020 AGC_Ctrl9 20051014 0x03C33440 - pltmp[9] = 0xA9002A79; // 0x1024 AGC_Ctrl10 - pltmp[10] = 0x40000528; // 0x1028 - pltmp[11] = 0x23457F30; // 0x102c A_ACQ_Ctrl - reg->BB2C = 0x23457F30; - Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT ); - - pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl - reg->BB30 = 0x00002C54; - pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl - pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl - pltmp[3] = pHwData->BB3c_cal; // 0x103c 11a TX LS filter - reg->BB3C = pHwData->BB3c_cal; - pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter - pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter - pltmp[6] = BB48_DEFAULT_WB242_11G; // 0x1048 11b TX RC filter 20060613.2 - reg->BB48 = BB48_DEFAULT_WB242_11G; // 20060613.1 20060613.2 - pltmp[7] = BB4C_DEFAULT_WB242_11G; // 0x104c 11b TX RC filter 20060613.2 - reg->BB4C = BB4C_DEFAULT_WB242_11G; // 20060613.1 20060613.2 - pltmp[8] = 0x27106208; // 0x1050 MODE_Ctrl - reg->BB50 = 0x27106208; - pltmp[9] = pHwData->BB54_cal; // 0x1054 - reg->BB54 = pHwData->BB54_cal; - pltmp[10] = 0x52523131; // 0x1058 IQ_Alpha - reg->BB58 = 0x52523131; - pltmp[11] = 0xAA0AC000; // 20060825 0xAA2AC000; // 0x105c DC_Cancel - Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT ); - - Wb35Reg_Write( pHwData, 0x1070, 0x00000045 ); - break; - } + Wb35Reg_Write(pHwData, 0x1070, 0x00000045); + break; + case RF_WB_242: + case RF_WB_242_1: + pltmp[0] = 0x16A8525D; /* 0x1000 AGC_Ctrl1 */ + pltmp[1] = 0x9AFF9ABA; /* 0x1004 AGC_Ctrl2 */ + pltmp[2] = 0x55D00A04; /* 0x1008 AGC_Ctrl3 */ + pltmp[3] = 0xEEE91C32; /* 0x100c AGC_Ctrl4 */ + reg->BB0C = 0xEEE91C32; + pltmp[4] = 0x0FACDCC5; /* 0x1010 AGC_Ctrl5 */ + pltmp[5] = 0x000AA344; /* 0x1014 AGC_Ctrl6 */ + pltmp[6] = 0x22222221; /* 0x1018 AGC_Ctrl7 */ + pltmp[7] = 0x0FA3F0ED; /* 0x101c AGC_Ctrl8 */ + pltmp[8] = 0x04CC3440; /* 0x1020 AGC_Ctrl9 */ + pltmp[9] = 0xA9002A79; /* 0x1024 AGC_Ctrl10 */ + pltmp[10] = 0x40000528; /* 0x1028 */ + pltmp[11] = 0x23457F30; /* 0x102c A_ACQ_Ctrl */ + reg->BB2C = 0x23457F30; + Wb35Reg_BurstWrite(pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT); + + pltmp[0] = 0x00002C54; /* 0x1030 B_ACQ_Ctrl */ + reg->BB30 = 0x00002C54; + pltmp[1] = 0x00C0D6C5; /* 0x1034 A_TXRX_Ctrl */ + pltmp[2] = 0x5B2C8769; /* 0x1038 B_TXRX_Ctrl */ + pltmp[3] = pHwData->BB3c_cal; /* 0x103c 11a TX LS filter */ + reg->BB3C = pHwData->BB3c_cal; + pltmp[4] = 0x00003F29; /* 0x1040 11a TX LS filter */ + pltmp[5] = 0x0EFEFBFE; /* 0x1044 11a TX LS filter */ + pltmp[6] = BB48_DEFAULT_WB242_11G; /* 0x1048 11b TX RC filter */ + reg->BB48 = BB48_DEFAULT_WB242_11G; + pltmp[7] = BB4C_DEFAULT_WB242_11G; /* 0x104c 11b TX RC filter */ + reg->BB4C = BB4C_DEFAULT_WB242_11G; + pltmp[8] = 0x27106208; /* 0x1050 MODE_Ctrl */ + reg->BB50 = 0x27106208; + pltmp[9] = pHwData->BB54_cal; /* 0x1054 */ + reg->BB54 = pHwData->BB54_cal; + pltmp[10] = 0x52523131; /* 0x1058 IQ_Alpha */ + reg->BB58 = 0x52523131; + pltmp[11] = 0xAA0AC000; /* 0x105c DC_Cancel */ + Wb35Reg_BurstWrite(pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT); + + Wb35Reg_Write(pHwData, 0x1070, 0x00000045); + break; + } - // Fill the LNA table - reg->LNAValue[0] = (u8)(reg->BB0C & 0xff); + /* Fill the LNA table */ + reg->LNAValue[0] = (u8) (reg->BB0C & 0xff); reg->LNAValue[1] = 0; - reg->LNAValue[2] = (u8)((reg->BB0C & 0xff00)>>8); + reg->LNAValue[2] = (u8) ((reg->BB0C & 0xff00) >> 8); reg->LNAValue[3] = 0; - // Fill SQ3 table - for( i=0; iSQ3_filter[i] = 0x2f; // half of Bit 0 ~ 6 + /* Fill SQ3 table */ + for (i = 0; i < MAX_SQ3_FILTER_SIZE; i++) + reg->SQ3_filter[i] = 0x2f; /* half of Bit 0 ~ 6 */ } -void set_tx_power_per_channel_max2829( struct hw_data * pHwData, struct chan_info Channel) +void set_tx_power_per_channel_max2829(struct hw_data *pHwData, struct chan_info Channel) { - RFSynthesizer_SetPowerIndex( pHwData, 100 ); // 20060620.1 Modify + RFSynthesizer_SetPowerIndex(pHwData, 100); } -void set_tx_power_per_channel_al2230( struct hw_data * pHwData, struct chan_info Channel ) +void set_tx_power_per_channel_al2230(struct hw_data *pHwData, struct chan_info Channel) { u8 index = 100; - if (pHwData->TxVgaFor24[Channel.ChanNo - 1] != 0xff) // 20060620.1 Add + if (pHwData->TxVgaFor24[Channel.ChanNo - 1] != 0xff) index = pHwData->TxVgaFor24[Channel.ChanNo - 1]; - RFSynthesizer_SetPowerIndex( pHwData, index ); + RFSynthesizer_SetPowerIndex(pHwData, index); } -void set_tx_power_per_channel_al7230( struct hw_data * pHwData, struct chan_info Channel) +void set_tx_power_per_channel_al7230(struct hw_data *pHwData, struct chan_info Channel) { u8 i, index = 100; - switch ( Channel.band ) - { - case BAND_TYPE_DSSS: - case BAND_TYPE_OFDM_24: - { - if (pHwData->TxVgaFor24[Channel.ChanNo - 1] != 0xff) - index = pHwData->TxVgaFor24[Channel.ChanNo - 1]; - } - break; - case BAND_TYPE_OFDM_5: - { - for (i =0; i<35; i++) - { - if (Channel.ChanNo == pHwData->TxVgaFor50[i].ChanNo) - { - if (pHwData->TxVgaFor50[i].TxVgaValue != 0xff) - index = pHwData->TxVgaFor50[i].TxVgaValue; - break; - } - } + switch (Channel.band) { + case BAND_TYPE_DSSS: + case BAND_TYPE_OFDM_24: + if (pHwData->TxVgaFor24[Channel.ChanNo - 1] != 0xff) + index = pHwData->TxVgaFor24[Channel.ChanNo - 1]; + break; + case BAND_TYPE_OFDM_5: + for (i = 0; i < 35; i++) { + if (Channel.ChanNo == pHwData->TxVgaFor50[i].ChanNo) { + if (pHwData->TxVgaFor50[i].TxVgaValue != 0xff) + index = pHwData->TxVgaFor50[i].TxVgaValue; + break; } - break; + } + break; } - RFSynthesizer_SetPowerIndex( pHwData, index ); + RFSynthesizer_SetPowerIndex(pHwData, index); } -void set_tx_power_per_channel_wb242( struct hw_data * pHwData, struct chan_info Channel) +void set_tx_power_per_channel_wb242(struct hw_data *pHwData, struct chan_info Channel) { u8 index = 100; - switch ( Channel.band ) - { - case BAND_TYPE_DSSS: - case BAND_TYPE_OFDM_24: - { - if (pHwData->TxVgaFor24[Channel.ChanNo - 1] != 0xff) - index = pHwData->TxVgaFor24[Channel.ChanNo - 1]; - } - break; - case BAND_TYPE_OFDM_5: - break; + switch (Channel.band) { + case BAND_TYPE_DSSS: + case BAND_TYPE_OFDM_24: + if (pHwData->TxVgaFor24[Channel.ChanNo - 1] != 0xff) + index = pHwData->TxVgaFor24[Channel.ChanNo - 1]; + break; + case BAND_TYPE_OFDM_5: + break; } - RFSynthesizer_SetPowerIndex( pHwData, index ); + RFSynthesizer_SetPowerIndex(pHwData, index); } -//============================================================================================================= -// RFSynthesizer_SwitchingChannel -- -// -// Description: -// Swithch the RF channel. -// -// Arguments: -// pHwData - Handle of the USB Device. -// Channel - The channel no. -// -// Return values: -// None. -//============================================================================================================= -void -RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, struct chan_info Channel ) +/* + * ========================================================================== + * RFSynthesizer_SwitchingChannel -- + * + * Description: + * Swithch the RF channel. + * + * Arguments: + * pHwData - Handle of the USB Device. + * Channel - The channel no. + * + * Return values: + * None. + * =========================================================================== + */ +void RFSynthesizer_SwitchingChannel(struct hw_data *pHwData, struct chan_info Channel) { struct wb35_reg *reg = &pHwData->reg; - u32 pltmp[16]; // The 16 is the maximum capability of hardware + u32 pltmp[16]; /* The 16 is the maximum capability of hardware */ u32 count, ltmp; u8 i, j, number; u8 ChnlTmp; - switch( pHwData->phy_type ) - { - case RF_MAXIM_2825: - case RF_MAXIM_V1: // 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331) - - if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 13 - { - for( i=0; i<3; i++ ) - pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2825_channel_data_24[Channel.ChanNo-1][i], 18); - Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT ); - } - RFSynthesizer_SetPowerIndex( pHwData, 100 ); - break; - - case RF_MAXIM_2827: - - if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 13 - { - for( i=0; i<3; i++ ) - pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2827_channel_data_24[Channel.ChanNo-1][i], 18); - Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT ); - } - else if( Channel.band == BAND_TYPE_OFDM_5 ) // channel 36 ~ 64 - { - ChnlTmp = (Channel.ChanNo - 36) / 4; - for( i=0; i<3; i++ ) - pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2827_channel_data_50[ChnlTmp][i], 18); - Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT ); - } - RFSynthesizer_SetPowerIndex( pHwData, 100 ); - break; - - case RF_MAXIM_2828: - - if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 13 - { - for( i=0; i<3; i++ ) - pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2828_channel_data_24[Channel.ChanNo-1][i], 18); - Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT ); - } - else if( Channel.band == BAND_TYPE_OFDM_5 ) // channel 36 ~ 64 - { - ChnlTmp = (Channel.ChanNo - 36) / 4; - for ( i = 0; i < 3; i++) - pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2828_channel_data_50[ChnlTmp][i], 18); - Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT ); - } - RFSynthesizer_SetPowerIndex( pHwData, 100 ); - break; - - case RF_MAXIM_2829: + switch (pHwData->phy_type) { + case RF_MAXIM_2825: + case RF_MAXIM_V1: /* 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331) */ - if( Channel.band <= BAND_TYPE_OFDM_24) - { - for( i=0; i<3; i++ ) - pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2829_channel_data_24[Channel.ChanNo-1][i], 18); - Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT ); - } - else if( Channel.band == BAND_TYPE_OFDM_5 ) - { - count = sizeof(max2829_channel_data_50) / sizeof(max2829_channel_data_50[0]); - - for( i=0; iband) { + if (Channel.band <= BAND_TYPE_OFDM_24) { + /* Update BB register */ + BBProcessor_AL7230_2400(pHwData); + + number = sizeof(al7230_rf_data_24) / sizeof(al7230_rf_data_24[0]); + Set_ChanIndep_RfData_al7230_24(pHwData, pltmp, number); + } else { + /* Update BB register */ + BBProcessor_AL7230_5000(pHwData); + + number = sizeof(al7230_rf_data_50) / sizeof(al7230_rf_data_50[0]); + Set_ChanIndep_RfData_al7230_50(pHwData, pltmp, number); } - set_tx_power_per_channel_al2230( pHwData, Channel ); - break; - case RF_AIROHA_7230: - - //Start to fill RF parameters, PLL_ON should be pulled low. - //Wb35Reg_Write( pHwData, 0x03dc, 0x00000000 ); - //printk("* PLL_ON low\n"); - - //Channel independent registers - if( Channel.band != pHwData->band) - { - if (Channel.band <= BAND_TYPE_OFDM_24) - { - //Update BB register - BBProcessor_AL7230_2400(pHwData); - - number = sizeof(al7230_rf_data_24)/sizeof(al7230_rf_data_24[0]); - Set_ChanIndep_RfData_al7230_24(pHwData, pltmp, number); - } - else - { - //Update BB register - BBProcessor_AL7230_5000(pHwData); - - number = sizeof(al7230_rf_data_50)/sizeof(al7230_rf_data_50[0]); - Set_ChanIndep_RfData_al7230_50(pHwData, pltmp, number); - } - - // Write to register. number must less and equal than 16 - Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, number, NO_INCREMENT ); - #ifdef _PE_STATE_DUMP_ - printk("Band changed\n"); - #endif - } + /* Write to register. number must less and equal than 16 */ + Wb35Reg_BurstWrite(pHwData, 0x0864, pltmp, number, NO_INCREMENT); + #ifdef _PE_STATE_DUMP_ + printk("Band changed\n"); + #endif + } - if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 14 - { - for( i=0; i<2; i++ ) - pltmp[i] = (1 << 31) | (0 << 30) | (24 << 24) | (al7230_channel_data_24[Channel.ChanNo-1][i]&0xffffff); - Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 2, NO_INCREMENT ); + if (Channel.band <= BAND_TYPE_OFDM_24) { /* channel 1 ~ 14 */ + for (i = 0; i < 2; i++) + pltmp[i] = (1 << 31) | (0 << 30) | (24 << 24) | (al7230_channel_data_24[Channel.ChanNo-1][i]&0xffffff); + Wb35Reg_BurstWrite(pHwData, 0x0864, pltmp, 2, NO_INCREMENT); + } else if (Channel.band == BAND_TYPE_OFDM_5) { + /* Update Reg12 */ + if ((Channel.ChanNo > 64) && (Channel.ChanNo <= 165)) { + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x00143c; + Wb35Reg_Write(pHwData, 0x0864, ltmp); + } else { /* reg12 = 0x00147c at Channel 4920 ~ 5320 */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x00147c; + Wb35Reg_Write(pHwData, 0x0864, ltmp); } - else if( Channel.band == BAND_TYPE_OFDM_5 ) - { - //Update Reg12 - if ((Channel.ChanNo > 64) && (Channel.ChanNo <= 165)) - { - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x00143c; - Wb35Reg_Write( pHwData, 0x0864, ltmp ); - } - else //reg12 = 0x00147c at Channel 4920 ~ 5320 - { - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x00147c; - Wb35Reg_Write( pHwData, 0x0864, ltmp ); - } - count = sizeof(al7230_channel_data_5) / sizeof(al7230_channel_data_5[0]); + count = sizeof(al7230_channel_data_5) / sizeof(al7230_channel_data_5[0]); - for (i=0; iBB50 &= ~(BIT(11)|BIT(12)); - Wb35Reg_Write( pHwData, 0x1050, reg->BB50 ); // MODE_Ctrl - // MAC: select 2.4 GHz, bit[5]=0 + if (Channel.band <= BAND_TYPE_OFDM_24) { + /* BB: select 2.4 GHz, bit[12-11]=00 */ + reg->BB50 &= ~(BIT(11) | BIT(12)); + Wb35Reg_Write(pHwData, 0x1050, reg->BB50); /* MODE_Ctrl */ + /* MAC: select 2.4 GHz, bit[5]=0 */ reg->M78_ERPInformation &= ~BIT(5); - Wb35Reg_Write( pHwData, 0x0878, reg->M78_ERPInformation ); - // enable 11b Baseband + Wb35Reg_Write(pHwData, 0x0878, reg->M78_ERPInformation); + /* enable 11b Baseband */ reg->BB30 &= ~BIT(31); - Wb35Reg_Write( pHwData, 0x1030, reg->BB30 ); - } - else if( (Channel.band == BAND_TYPE_OFDM_5) ) - { - // BB: select 5 GHz - reg->BB50 &= ~(BIT(11)|BIT(12)); - if (Channel.ChanNo <=64 ) - reg->BB50 |= BIT(12); // 10-5.25GHz + Wb35Reg_Write(pHwData, 0x1030, reg->BB30); + } else if (Channel.band == BAND_TYPE_OFDM_5) { + /* BB: select 5 GHz */ + reg->BB50 &= ~(BIT(11) | BIT(12)); + if (Channel.ChanNo <= 64) + reg->BB50 |= BIT(12); /* 10-5.25GHz */ else if ((Channel.ChanNo >= 100) && (Channel.ChanNo <= 124)) - reg->BB50 |= BIT(11); // 01-5.48GHz - else if ((Channel.ChanNo >=128) && (Channel.ChanNo <= 161)) - reg->BB50 |= (BIT(12)|BIT(11)); // 11-5.775GHz - else //Chan 184 ~ 196 will use bit[12-11] = 10 in version sh-src-1.2.25 + reg->BB50 |= BIT(11); /* 01-5.48GHz */ + else if ((Channel.ChanNo >= 128) && (Channel.ChanNo <= 161)) + reg->BB50 |= (BIT(12) | BIT(11)); /* 11-5.775GHz */ + else /* Chan 184 ~ 196 will use bit[12-11] = 10 in version sh-src-1.2.25 */ reg->BB50 |= BIT(12); - Wb35Reg_Write( pHwData, 0x1050, reg->BB50 ); // MODE_Ctrl + Wb35Reg_Write(pHwData, 0x1050, reg->BB50); /* MODE_Ctrl */ - //(1) M78 should alway use 2.4G setting when using RF_AIROHA_7230 - //(2) BB30 has been updated previously. - if (pHwData->phy_type != RF_AIROHA_7230) - { - // MAC: select 5 GHz, bit[5]=1 + /* (1) M78 should alway use 2.4G setting when using RF_AIROHA_7230 */ + /* (2) BB30 has been updated previously. */ + if (pHwData->phy_type != RF_AIROHA_7230) { + /* MAC: select 5 GHz, bit[5]=1 */ reg->M78_ERPInformation |= BIT(5); - Wb35Reg_Write( pHwData, 0x0878, reg->M78_ERPInformation ); + Wb35Reg_Write(pHwData, 0x0878, reg->M78_ERPInformation); - // disable 11b Baseband + /* disable 11b Baseband */ reg->BB30 |= BIT(31); - Wb35Reg_Write( pHwData, 0x1030, reg->BB30 ); + Wb35Reg_Write(pHwData, 0x1030, reg->BB30); } } } -//Set the tx power directly from DUT GUI, not from the EEPROM. Return the current setting -u8 RFSynthesizer_SetPowerIndex( struct hw_data * pHwData, u8 PowerIndex ) +/* + * Set the tx power directly from DUT GUI, not from the EEPROM. + * Return the current setting + */ +u8 RFSynthesizer_SetPowerIndex(struct hw_data *pHwData, u8 PowerIndex) { u32 Band = pHwData->band; - u8 index=0; + u8 index = 0; - if( pHwData->power_index == PowerIndex ) // 20060620.1 Add + if (pHwData->power_index == PowerIndex) return PowerIndex; - if (RF_MAXIM_2825 == pHwData->phy_type) - { - // Channel 1 - 13 - index = RFSynthesizer_SetMaxim2825Power( pHwData, PowerIndex ); - } - else if (RF_MAXIM_2827 == pHwData->phy_type) - { - if( Band <= BAND_TYPE_OFDM_24 ) // Channel 1 - 13 - index = RFSynthesizer_SetMaxim2827_24Power( pHwData, PowerIndex ); - else// if( Band == BAND_TYPE_OFDM_5 ) // Channel 36 - 64 - index = RFSynthesizer_SetMaxim2827_50Power( pHwData, PowerIndex ); - } - else if (RF_MAXIM_2828 == pHwData->phy_type) - { - if( Band <= BAND_TYPE_OFDM_24 ) // Channel 1 - 13 - index = RFSynthesizer_SetMaxim2828_24Power( pHwData, PowerIndex ); - else// if( Band == BAND_TYPE_OFDM_5 ) // Channel 36 - 64 - index = RFSynthesizer_SetMaxim2828_50Power( pHwData, PowerIndex ); - } - else if( RF_AIROHA_2230 == pHwData->phy_type ) - { - //Power index: 0 ~ 63 // Channel 1 - 14 - index = RFSynthesizer_SetAiroha2230Power( pHwData, PowerIndex ); - index = (u8)al2230_txvga_data[index][1]; - } - else if( RF_AIROHA_2230S == pHwData->phy_type ) // 20060420 Add this - { - //Power index: 0 ~ 63 // Channel 1 - 14 - index = RFSynthesizer_SetAiroha2230Power( pHwData, PowerIndex ); - index = (u8)al2230_txvga_data[index][1]; - } - else if( RF_AIROHA_7230 == pHwData->phy_type ) - { - //Power index: 0 ~ 63 - index = RFSynthesizer_SetAiroha7230Power( pHwData, PowerIndex ); + if (RF_MAXIM_2825 == pHwData->phy_type) { + /* Channel 1 - 13 */ + index = RFSynthesizer_SetMaxim2825Power(pHwData, PowerIndex); + } else if (RF_MAXIM_2827 == pHwData->phy_type) { + if (Band <= BAND_TYPE_OFDM_24) /* Channel 1 - 13 */ + index = RFSynthesizer_SetMaxim2827_24Power(pHwData, PowerIndex); + else /* Channel 36 - 64 */ + index = RFSynthesizer_SetMaxim2827_50Power(pHwData, PowerIndex); + } else if (RF_MAXIM_2828 == pHwData->phy_type) { + if (Band <= BAND_TYPE_OFDM_24) /* Channel 1 - 13 */ + index = RFSynthesizer_SetMaxim2828_24Power(pHwData, PowerIndex); + else /* Channel 36 - 64 */ + index = RFSynthesizer_SetMaxim2828_50Power(pHwData, PowerIndex); + } else if (RF_AIROHA_2230 == pHwData->phy_type) { + /* Power index: 0 ~ 63 --- Channel 1 - 14 */ + index = RFSynthesizer_SetAiroha2230Power(pHwData, PowerIndex); + index = (u8) al2230_txvga_data[index][1]; + } else if (RF_AIROHA_2230S == pHwData->phy_type) { + /* Power index: 0 ~ 63 --- Channel 1 - 14 */ + index = RFSynthesizer_SetAiroha2230Power(pHwData, PowerIndex); + index = (u8) al2230_txvga_data[index][1]; + } else if (RF_AIROHA_7230 == pHwData->phy_type) { + /* Power index: 0 ~ 63 */ + index = RFSynthesizer_SetAiroha7230Power(pHwData, PowerIndex); index = (u8)al7230_txvga_data[index][1]; - } - else if( (RF_WB_242 == pHwData->phy_type) || - (RF_WB_242_1 == pHwData->phy_type) ) // 20060619.5 Add - { - //Power index: 0 ~ 19 for original. New range is 0 ~ 33 - index = RFSynthesizer_SetWinbond242Power( pHwData, PowerIndex ); + } else if ((RF_WB_242 == pHwData->phy_type) || + (RF_WB_242_1 == pHwData->phy_type)) { + /* Power index: 0 ~ 19 for original. New range is 0 ~ 33 */ + index = RFSynthesizer_SetWinbond242Power(pHwData, PowerIndex); index = (u8)w89rf242_txvga_data[index][1]; } - pHwData->power_index = index; // Backup current + pHwData->power_index = index; /* Backup current */ return index; } -//-- Sub function -u8 RFSynthesizer_SetMaxim2828_24Power( struct hw_data * pHwData, u8 index ) +/* -- Sub function */ +u8 RFSynthesizer_SetMaxim2828_24Power(struct hw_data *pHwData, u8 index) { - u32 PowerData; - if( index > 1 ) index = 1; - PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2828_power_data_24[index], 18); - Wb35Reg_Write( pHwData, 0x0864, PowerData ); + u32 PowerData; + if (index > 1) + index = 1; + PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(max2828_power_data_24[index], 18); + Wb35Reg_Write(pHwData, 0x0864, PowerData); return index; } -//-- -u8 RFSynthesizer_SetMaxim2828_50Power( struct hw_data * pHwData, u8 index ) + +u8 RFSynthesizer_SetMaxim2828_50Power(struct hw_data *pHwData, u8 index) { - u32 PowerData; - if( index > 1 ) index = 1; - PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2828_power_data_50[index], 18); - Wb35Reg_Write( pHwData, 0x0864, PowerData ); + u32 PowerData; + if (index > 1) + index = 1; + PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(max2828_power_data_50[index], 18); + Wb35Reg_Write(pHwData, 0x0864, PowerData); return index; } -//-- -u8 RFSynthesizer_SetMaxim2827_24Power( struct hw_data * pHwData, u8 index ) + +u8 RFSynthesizer_SetMaxim2827_24Power(struct hw_data *pHwData, u8 index) { - u32 PowerData; - if( index > 1 ) index = 1; - PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2827_power_data_24[index], 18); - Wb35Reg_Write( pHwData, 0x0864, PowerData ); + u32 PowerData; + if (index > 1) + index = 1; + PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(max2827_power_data_24[index], 18); + Wb35Reg_Write(pHwData, 0x0864, PowerData); return index; } -//-- -u8 RFSynthesizer_SetMaxim2827_50Power( struct hw_data * pHwData, u8 index ) + +u8 RFSynthesizer_SetMaxim2827_50Power(struct hw_data *pHwData, u8 index) { - u32 PowerData; - if( index > 1 ) index = 1; - PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2827_power_data_50[index], 18); - Wb35Reg_Write( pHwData, 0x0864, PowerData ); + u32 PowerData; + if (index > 1) + index = 1; + PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(max2827_power_data_50[index], 18); + Wb35Reg_Write(pHwData, 0x0864, PowerData); return index; } -//-- -u8 RFSynthesizer_SetMaxim2825Power( struct hw_data * pHwData, u8 index ) + +u8 RFSynthesizer_SetMaxim2825Power(struct hw_data *pHwData, u8 index) { - u32 PowerData; - if( index > 1 ) index = 1; - PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2825_power_data_24[index], 18); - Wb35Reg_Write( pHwData, 0x0864, PowerData ); + u32 PowerData; + if (index > 1) + index = 1; + PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(max2825_power_data_24[index], 18); + Wb35Reg_Write(pHwData, 0x0864, PowerData); return index; } -//-- -u8 RFSynthesizer_SetAiroha2230Power( struct hw_data * pHwData, u8 index ) + +u8 RFSynthesizer_SetAiroha2230Power(struct hw_data *pHwData, u8 index) { - u32 PowerData; - u8 i,count; + u32 PowerData; + u8 i, count; count = sizeof(al2230_txvga_data) / sizeof(al2230_txvga_data[0]); - for (i=0; i= index) break; } if (i == count) i--; - PowerData = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( al2230_txvga_data[i][0], 20); - Wb35Reg_Write( pHwData, 0x0864, PowerData ); + PowerData = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse(al2230_txvga_data[i][0], 20); + Wb35Reg_Write(pHwData, 0x0864, PowerData); return i; } -//-- -u8 RFSynthesizer_SetAiroha7230Power( struct hw_data * pHwData, u8 index ) + +u8 RFSynthesizer_SetAiroha7230Power(struct hw_data *pHwData, u8 index) { - u32 PowerData; - u8 i,count; + u32 PowerData; + u8 i, count; - //PowerData = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( airoha_power_data_24[index], 20); count = sizeof(al7230_txvga_data) / sizeof(al7230_txvga_data[0]); - for (i=0; i= index) break; } if (i == count) i--; - PowerData = (1 << 31) | (0 << 30) | (24 << 24) | (al7230_txvga_data[i][0]&0xffffff); - Wb35Reg_Write( pHwData, 0x0864, PowerData ); + PowerData = (1 << 31) | (0 << 30) | (24 << 24) | (al7230_txvga_data[i][0] & 0xffffff); + Wb35Reg_Write(pHwData, 0x0864, PowerData); return i; } -u8 RFSynthesizer_SetWinbond242Power( struct hw_data * pHwData, u8 index ) +u8 RFSynthesizer_SetWinbond242Power(struct hw_data *pHwData, u8 index) { - u32 PowerData; - u8 i,count; + u32 PowerData; + u8 i, count; count = sizeof(w89rf242_txvga_data) / sizeof(w89rf242_txvga_data[0]); - for (i=0; i= index) break; } if (i == count) i--; - // Set TxVga into RF - PowerData = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( w89rf242_txvga_data[i][0], 24); - Wb35Reg_Write( pHwData, 0x0864, PowerData ); - - // Update BB48 BB4C BB58 for high precision txvga - Wb35Reg_Write( pHwData, 0x1048, w89rf242_txvga_data[i][2] ); - Wb35Reg_Write( pHwData, 0x104c, w89rf242_txvga_data[i][3] ); - Wb35Reg_Write( pHwData, 0x1058, w89rf242_txvga_data[i][4] ); - -// Rf vga 0 ~ 3 for temperature compensate. It will affect the scan Bss. -// The i value equals to 8 or 7 usually. So It's not necessary to setup this RF register. -// if( i <= 3 ) -// PowerData = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( 0x000024, 24 ); -// else -// PowerData = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( 0x001824, 24 ); -// Wb35Reg_Write( pHwData, 0x0864, PowerData ); + /* Set TxVga into RF */ + PowerData = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse(w89rf242_txvga_data[i][0], 24); + Wb35Reg_Write(pHwData, 0x0864, PowerData); + + /* Update BB48 BB4C BB58 for high precision txvga */ + Wb35Reg_Write(pHwData, 0x1048, w89rf242_txvga_data[i][2]); + Wb35Reg_Write(pHwData, 0x104c, w89rf242_txvga_data[i][3]); + Wb35Reg_Write(pHwData, 0x1058, w89rf242_txvga_data[i][4]); + return i; } -//=========================================================================================================== -// Dxx_initial -- -// Mxx_initial -- - // -// Routine Description: -// Initial the hardware setting and module variable - // -//=========================================================================================================== -void Dxx_initial( struct hw_data * pHwData ) +/* + * =========================================================================== + * Dxx_initial -- + * Mxx_initial -- + * + * Routine Description: + * Initial the hardware setting and module variable + * =========================================================================== + */ +void Dxx_initial(struct hw_data *pHwData) { struct wb35_reg *reg = &pHwData->reg; - // Old IC:Single mode only. - // New IC: operation decide by Software set bit[4]. 1:multiple 0: single - reg->D00_DmaControl = 0xc0000004; //Txon, Rxon, multiple Rx for new 4k DMA - //Txon, Rxon, single Rx for old 8k ASIC - if( !HAL_USB_MODE_BURST( pHwData ) ) - reg->D00_DmaControl = 0xc0000000;//Txon, Rxon, single Rx for new 4k DMA + /* + * Old IC: Single mode only. + * New IC: operation decide by Software set bit[4]. 1:multiple 0: single + */ + reg->D00_DmaControl = 0xc0000004; /* Txon, Rxon, multiple Rx for new 4k DMA */ + /* Txon, Rxon, single Rx for old 8k ASIC */ + if (!HAL_USB_MODE_BURST(pHwData)) + reg->D00_DmaControl = 0xc0000000; /* Txon, Rxon, single Rx for new 4k DMA */ - Wb35Reg_WriteSync( pHwData, 0x0400, reg->D00_DmaControl ); + Wb35Reg_WriteSync(pHwData, 0x0400, reg->D00_DmaControl); } -void Mxx_initial( struct hw_data * pHwData ) +void Mxx_initial(struct hw_data *pHwData) { struct wb35_reg *reg = &pHwData->reg; - u32 tmp; - u32 pltmp[11]; + u32 tmp; + u32 pltmp[11]; u16 i; - //====================================================== - // Initial Mxx register - //====================================================== + /* + * ====================================================== + * Initial Mxx register + * ====================================================== + */ - // M00 bit set -#ifdef _IBSS_BEACON_SEQ_STICK_ - reg->M00_MacControl = 0; // Solve beacon sequence number stop by software -#else - reg->M00_MacControl = 0x80000000; // Solve beacon sequence number stop by hardware -#endif + /* M00 bit set */ + #ifdef _IBSS_BEACON_SEQ_STICK_ + reg->M00_MacControl = 0; /* Solve beacon sequence number stop by software */ + #else + reg->M00_MacControl = 0x80000000; /* Solve beacon sequence number stop by hardware */ + #endif - // M24 disable enter power save, BB RxOn and enable NAV attack + /* M24 disable enter power save, BB RxOn and enable NAV attack */ reg->M24_MacControl = 0x08040042; pltmp[0] = reg->M24_MacControl; - pltmp[1] = 0; // Skip M28, because no initialize value is required. + pltmp[1] = 0; /* Skip M28, because no initialize value is required. */ - // M2C CWmin and CWmax setting + /* M2C CWmin and CWmax setting */ pHwData->cwmin = DEFAULT_CWMIN; pHwData->cwmax = DEFAULT_CWMAX; reg->M2C_MacControl = DEFAULT_CWMIN << 10; reg->M2C_MacControl |= DEFAULT_CWMAX; pltmp[2] = reg->M2C_MacControl; - // M30 BSSID + /* M30 BSSID */ pltmp[3] = *(u32 *)pHwData->bssid; - // M34 + /* M34 */ pHwData->AID = DEFAULT_AID; - tmp = *(u16 *)(pHwData->bssid+4); + tmp = *(u16 *) (pHwData->bssid + 4); tmp |= DEFAULT_AID << 16; pltmp[4] = tmp; - // M38 - reg->M38_MacControl = (DEFAULT_RATE_RETRY_LIMIT<<8) | (DEFAULT_LONG_RETRY_LIMIT << 4) | DEFAULT_SHORT_RETRY_LIMIT; + /* M38 */ + reg->M38_MacControl = (DEFAULT_RATE_RETRY_LIMIT << 8) | (DEFAULT_LONG_RETRY_LIMIT << 4) | DEFAULT_SHORT_RETRY_LIMIT; pltmp[5] = reg->M38_MacControl; - // M3C + /* M3C */ tmp = (DEFAULT_PIFST << 26) | (DEFAULT_EIFST << 16) | (DEFAULT_DIFST << 8) | (DEFAULT_SIFST << 4) | DEFAULT_OSIFST ; reg->M3C_MacControl = tmp; pltmp[6] = tmp; - // M40 + /* M40 */ pHwData->slot_time_select = DEFAULT_SLOT_TIME; tmp = (DEFAULT_ATIMWD << 16) | DEFAULT_SLOT_TIME; reg->M40_MacControl = tmp; pltmp[7] = tmp; - // M44 - tmp = DEFAULT_MAX_TX_MSDU_LIFE_TIME << 10; // *1024 + /* M44 */ + tmp = DEFAULT_MAX_TX_MSDU_LIFE_TIME << 10; /* *1024 */ reg->M44_MacControl = tmp; pltmp[8] = tmp; - // M48 + /* M48 */ pHwData->BeaconPeriod = DEFAULT_BEACON_INTERVAL; pHwData->ProbeDelay = DEFAULT_PROBE_DELAY_TIME; tmp = (DEFAULT_BEACON_INTERVAL << 16) | DEFAULT_PROBE_DELAY_TIME; reg->M48_MacControl = tmp; pltmp[9] = tmp; - //M4C + /* M4C */ reg->M4C_MacStatus = (DEFAULT_PROTOCOL_VERSION << 30) | (DEFAULT_MAC_POWER_STATE << 28) | (DEFAULT_DTIM_ALERT_TIME << 24); pltmp[10] = reg->M4C_MacStatus; - // Burst write - //Wb35Reg_BurstWrite( pHwData, 0x0824, pltmp, 11, AUTO_INCREMENT ); - for( i=0; i<11; i++ ) - Wb35Reg_WriteSync( pHwData, 0x0824 + i*4, pltmp[i] ); + for (i = 0; i < 11; i++) + Wb35Reg_WriteSync(pHwData, 0x0824 + i * 4, pltmp[i]); - // M60 - Wb35Reg_WriteSync( pHwData, 0x0860, 0x12481248 ); + /* M60 */ + Wb35Reg_WriteSync(pHwData, 0x0860, 0x12481248); reg->M60_MacControl = 0x12481248; - // M68 - Wb35Reg_WriteSync( pHwData, 0x0868, 0x00050900 ); // 20051018 0x000F0F00 ); // 940930 0x00131300 + /* M68 */ + Wb35Reg_WriteSync(pHwData, 0x0868, 0x00050900); reg->M68_MacControl = 0x00050900; - // M98 - Wb35Reg_WriteSync( pHwData, 0x0898, 0xffff8888 ); + /* M98 */ + Wb35Reg_WriteSync(pHwData, 0x0898, 0xffff8888); reg->M98_MacControl = 0xffff8888; } -void Uxx_power_off_procedure( struct hw_data * pHwData ) +void Uxx_power_off_procedure(struct hw_data *pHwData) { - // SW, PMU reset and turn off clock - Wb35Reg_WriteSync( pHwData, 0x03b0, 3 ); - Wb35Reg_WriteSync( pHwData, 0x03f0, 0xf9 ); + /* SW, PMU reset and turn off clock */ + Wb35Reg_WriteSync(pHwData, 0x03b0, 3); + Wb35Reg_WriteSync(pHwData, 0x03f0, 0xf9); } -//Decide the TxVga of every channel -void GetTxVgaFromEEPROM( struct hw_data * pHwData ) +/*Decide the TxVga of every channel */ +void GetTxVgaFromEEPROM(struct hw_data *pHwData) { - u32 i, j, ltmp; - u16 Value[MAX_TXVGA_EEPROM]; - u8 *pctmp; - u8 ctmp=0; - - // Get the entire TxVga setting in EEPROM - for( i=0; iphy_type == RF_WB_242 ) - { - for( i=0; i<4; i++ ) // Only 2412 2437 2462 2484 case must be modified - { - for( j=0; j<(sizeof(w89rf242_txvga_old_mapping)/sizeof(w89rf242_txvga_old_mapping[0])); j++ ) - { - if( pctmp[i] < (u8)w89rf242_txvga_old_mapping[j][1] ) - { - pctmp[i] = (u8)w89rf242_txvga_old_mapping[j][0]; + /* Adjust WB_242 to WB_242_1 TxVga scale */ + if (pHwData->phy_type == RF_WB_242) { + for (i = 0; i < 4; i++) { /* Only 2412 2437 2462 2484 case must be modified */ + for (j = 0; j < (sizeof(w89rf242_txvga_old_mapping) / sizeof(w89rf242_txvga_old_mapping[0])); j++) { + if (pctmp[i] < (u8) w89rf242_txvga_old_mapping[j][1]) { + pctmp[i] = (u8) w89rf242_txvga_old_mapping[j][0]; break; } } - if( j == (sizeof(w89rf242_txvga_old_mapping)/sizeof(w89rf242_txvga_old_mapping[0])) ) + if (j == (sizeof(w89rf242_txvga_old_mapping) / sizeof(w89rf242_txvga_old_mapping[0]))) pctmp[i] = (u8)w89rf242_txvga_old_mapping[j-1][0]; } } - // 20060621 Add - memcpy( pHwData->TxVgaSettingInEEPROM, pctmp, MAX_TXVGA_EEPROM*2 ); //MAX_TXVGA_EEPROM is u16 count - EEPROMTxVgaAdjust( pHwData ); + memcpy(pHwData->TxVgaSettingInEEPROM, pctmp, MAX_TXVGA_EEPROM * 2); /* MAX_TXVGA_EEPROM is u16 count */ + EEPROMTxVgaAdjust(pHwData); } -// This function will affect the TxVga parameter in HAL. If hal_set_current_channel -// or RFSynthesizer_SetPowerIndex be called, new TxVga will take effect. -// TxVgaSettingInEEPROM of sHwData is an u8 array point to EEPROM contain for IS89C35 -// This function will use default TxVgaSettingInEEPROM data to calculate new TxVga. -void EEPROMTxVgaAdjust( struct hw_data * pHwData ) // 20060619.5 Add +/* + * This function will affect the TxVga parameter in HAL. If hal_set_current_channel + * or RFSynthesizer_SetPowerIndex be called, new TxVga will take effect. + * TxVgaSettingInEEPROM of sHwData is an u8 array point to EEPROM contain for IS89C35 + * This function will use default TxVgaSettingInEEPROM data to calculate new TxVga. + */ +void EEPROMTxVgaAdjust(struct hw_data *pHwData) { - u8 * pTxVga = pHwData->TxVgaSettingInEEPROM; - s16 i, stmp; + u8 *pTxVga = pHwData->TxVgaSettingInEEPROM; + s16 i, stmp; - //-- 2.4G -- 20060704.2 Request from Tiger - //channel 1 ~ 5 + /* -- 2.4G -- */ + /* channel 1 ~ 5 */ stmp = pTxVga[1] - pTxVga[0]; - for( i=0; i<5; i++ ) - pHwData->TxVgaFor24[i] = pTxVga[0] + stmp*i/4; - //channel 6 ~ 10 + for (i = 0; i < 5; i++) + pHwData->TxVgaFor24[i] = pTxVga[0] + stmp * i / 4; + /* channel 6 ~ 10 */ stmp = pTxVga[2] - pTxVga[1]; - for( i=5; i<10; i++ ) - pHwData->TxVgaFor24[i] = pTxVga[1] + stmp*(i-5)/4; - //channel 11 ~ 13 + for (i = 5; i < 10; i++) + pHwData->TxVgaFor24[i] = pTxVga[1] + stmp * (i - 5) / 4; + /* channel 11 ~ 13 */ stmp = pTxVga[3] - pTxVga[2]; - for( i=10; i<13; i++ ) - pHwData->TxVgaFor24[i] = pTxVga[2] + stmp*(i-10)/2; - //channel 14 + for (i = 10; i < 13; i++) + pHwData->TxVgaFor24[i] = pTxVga[2] + stmp * (i - 10) / 2; + /* channel 14 */ pHwData->TxVgaFor24[13] = pTxVga[3]; - //-- 5G -- - if( pHwData->phy_type == RF_AIROHA_7230 ) - { - //channel 184 + /* -- 5G -- */ + if (pHwData->phy_type == RF_AIROHA_7230) { + /* channel 184 */ pHwData->TxVgaFor50[0].ChanNo = 184; pHwData->TxVgaFor50[0].TxVgaValue = pTxVga[4]; - //channel 196 + /* channel 196 */ pHwData->TxVgaFor50[3].ChanNo = 196; pHwData->TxVgaFor50[3].TxVgaValue = pTxVga[5]; - //interpolate + /* interpolate */ pHwData->TxVgaFor50[1].ChanNo = 188; pHwData->TxVgaFor50[2].ChanNo = 192; stmp = pTxVga[5] - pTxVga[4]; - pHwData->TxVgaFor50[2].TxVgaValue = pTxVga[5] - stmp/3; - pHwData->TxVgaFor50[1].TxVgaValue = pTxVga[5] - stmp*2/3; + pHwData->TxVgaFor50[2].TxVgaValue = pTxVga[5] - stmp / 3; + pHwData->TxVgaFor50[1].TxVgaValue = pTxVga[5] - stmp * 2 / 3; - //channel 16 + /* channel 16 */ pHwData->TxVgaFor50[6].ChanNo = 16; pHwData->TxVgaFor50[6].TxVgaValue = pTxVga[6]; pHwData->TxVgaFor50[4].ChanNo = 8; @@ -2523,7 +2250,7 @@ void EEPROMTxVgaAdjust( struct hw_data * pHwData ) // 20060619.5 Add pHwData->TxVgaFor50[5].ChanNo = 12; pHwData->TxVgaFor50[5].TxVgaValue = pTxVga[6]; - //channel 36 + /* channel 36 */ pHwData->TxVgaFor50[8].ChanNo = 36; pHwData->TxVgaFor50[8].TxVgaValue = pTxVga[7]; pHwData->TxVgaFor50[7].ChanNo = 34; @@ -2531,153 +2258,135 @@ void EEPROMTxVgaAdjust( struct hw_data * pHwData ) // 20060619.5 Add pHwData->TxVgaFor50[9].ChanNo = 38; pHwData->TxVgaFor50[9].TxVgaValue = pTxVga[7]; - //channel 40 + /* channel 40 */ pHwData->TxVgaFor50[10].ChanNo = 40; pHwData->TxVgaFor50[10].TxVgaValue = pTxVga[8]; - //channel 48 + /* channel 48 */ pHwData->TxVgaFor50[14].ChanNo = 48; pHwData->TxVgaFor50[14].TxVgaValue = pTxVga[9]; - //interpolate + /* interpolate */ pHwData->TxVgaFor50[11].ChanNo = 42; pHwData->TxVgaFor50[12].ChanNo = 44; pHwData->TxVgaFor50[13].ChanNo = 46; stmp = pTxVga[9] - pTxVga[8]; - pHwData->TxVgaFor50[13].TxVgaValue = pTxVga[9] - stmp/4; - pHwData->TxVgaFor50[12].TxVgaValue = pTxVga[9] - stmp*2/4; - pHwData->TxVgaFor50[11].TxVgaValue = pTxVga[9] - stmp*3/4; + pHwData->TxVgaFor50[13].TxVgaValue = pTxVga[9] - stmp / 4; + pHwData->TxVgaFor50[12].TxVgaValue = pTxVga[9] - stmp * 2 / 4; + pHwData->TxVgaFor50[11].TxVgaValue = pTxVga[9] - stmp * 3 / 4; - //channel 52 + /* channel 52 */ pHwData->TxVgaFor50[15].ChanNo = 52; pHwData->TxVgaFor50[15].TxVgaValue = pTxVga[10]; - //channel 64 + /* channel 64 */ pHwData->TxVgaFor50[18].ChanNo = 64; pHwData->TxVgaFor50[18].TxVgaValue = pTxVga[11]; - //interpolate + /* interpolate */ pHwData->TxVgaFor50[16].ChanNo = 56; pHwData->TxVgaFor50[17].ChanNo = 60; stmp = pTxVga[11] - pTxVga[10]; - pHwData->TxVgaFor50[17].TxVgaValue = pTxVga[11] - stmp/3; - pHwData->TxVgaFor50[16].TxVgaValue = pTxVga[11] - stmp*2/3; + pHwData->TxVgaFor50[17].TxVgaValue = pTxVga[11] - stmp / 3; + pHwData->TxVgaFor50[16].TxVgaValue = pTxVga[11] - stmp * 2 / 3; - //channel 100 + /* channel 100 */ pHwData->TxVgaFor50[19].ChanNo = 100; pHwData->TxVgaFor50[19].TxVgaValue = pTxVga[12]; - //channel 112 + /* channel 112 */ pHwData->TxVgaFor50[22].ChanNo = 112; pHwData->TxVgaFor50[22].TxVgaValue = pTxVga[13]; - //interpolate + /* interpolate */ pHwData->TxVgaFor50[20].ChanNo = 104; pHwData->TxVgaFor50[21].ChanNo = 108; stmp = pTxVga[13] - pTxVga[12]; - pHwData->TxVgaFor50[21].TxVgaValue = pTxVga[13] - stmp/3; - pHwData->TxVgaFor50[20].TxVgaValue = pTxVga[13] - stmp*2/3; + pHwData->TxVgaFor50[21].TxVgaValue = pTxVga[13] - stmp / 3; + pHwData->TxVgaFor50[20].TxVgaValue = pTxVga[13] - stmp * 2 / 3; - //channel 128 + /* channel 128 */ pHwData->TxVgaFor50[26].ChanNo = 128; pHwData->TxVgaFor50[26].TxVgaValue = pTxVga[14]; - //interpolate + /* interpolate */ pHwData->TxVgaFor50[23].ChanNo = 116; pHwData->TxVgaFor50[24].ChanNo = 120; pHwData->TxVgaFor50[25].ChanNo = 124; stmp = pTxVga[14] - pTxVga[13]; - pHwData->TxVgaFor50[25].TxVgaValue = pTxVga[14] - stmp/4; - pHwData->TxVgaFor50[24].TxVgaValue = pTxVga[14] - stmp*2/4; - pHwData->TxVgaFor50[23].TxVgaValue = pTxVga[14] - stmp*3/4; + pHwData->TxVgaFor50[25].TxVgaValue = pTxVga[14] - stmp / 4; + pHwData->TxVgaFor50[24].TxVgaValue = pTxVga[14] - stmp * 2 / 4; + pHwData->TxVgaFor50[23].TxVgaValue = pTxVga[14] - stmp * 3 / 4; - //channel 140 + /* channel 140 */ pHwData->TxVgaFor50[29].ChanNo = 140; pHwData->TxVgaFor50[29].TxVgaValue = pTxVga[15]; - //interpolate + /* interpolate */ pHwData->TxVgaFor50[27].ChanNo = 132; pHwData->TxVgaFor50[28].ChanNo = 136; stmp = pTxVga[15] - pTxVga[14]; - pHwData->TxVgaFor50[28].TxVgaValue = pTxVga[15] - stmp/3; - pHwData->TxVgaFor50[27].TxVgaValue = pTxVga[15] - stmp*2/3; + pHwData->TxVgaFor50[28].TxVgaValue = pTxVga[15] - stmp / 3; + pHwData->TxVgaFor50[27].TxVgaValue = pTxVga[15] - stmp * 2 / 3; - //channel 149 + /* channel 149 */ pHwData->TxVgaFor50[30].ChanNo = 149; pHwData->TxVgaFor50[30].TxVgaValue = pTxVga[16]; - //channel 165 + /* channel 165 */ pHwData->TxVgaFor50[34].ChanNo = 165; pHwData->TxVgaFor50[34].TxVgaValue = pTxVga[17]; - //interpolate + /* interpolate */ pHwData->TxVgaFor50[31].ChanNo = 153; pHwData->TxVgaFor50[32].ChanNo = 157; pHwData->TxVgaFor50[33].ChanNo = 161; stmp = pTxVga[17] - pTxVga[16]; - pHwData->TxVgaFor50[33].TxVgaValue = pTxVga[17] - stmp/4; - pHwData->TxVgaFor50[32].TxVgaValue = pTxVga[17] - stmp*2/4; - pHwData->TxVgaFor50[31].TxVgaValue = pTxVga[17] - stmp*3/4; + pHwData->TxVgaFor50[33].TxVgaValue = pTxVga[17] - stmp / 4; + pHwData->TxVgaFor50[32].TxVgaValue = pTxVga[17] - stmp * 2 / 4; + pHwData->TxVgaFor50[31].TxVgaValue = pTxVga[17] - stmp * 3 / 4; } #ifdef _PE_STATE_DUMP_ - printk(" TxVgaFor24 : \n"); - DataDmp((u8 *)pHwData->TxVgaFor24, 14 ,0); - printk(" TxVgaFor50 : \n"); - DataDmp((u8 *)pHwData->TxVgaFor50, 70 ,0); + printk(" TxVgaFor24 :\n"); + DataDmp((u8 *)pHwData->TxVgaFor24, 14 , 0); + printk(" TxVgaFor50 :\n"); + DataDmp((u8 *)pHwData->TxVgaFor50, 70 , 0); #endif } -void BBProcessor_RateChanging( struct hw_data * pHwData, u8 rate ) // 20060613.1 +void BBProcessor_RateChanging(struct hw_data *pHwData, u8 rate) { struct wb35_reg *reg = &pHwData->reg; - unsigned char Is11bRate; + unsigned char Is11bRate; Is11bRate = (rate % 6) ? 1 : 0; - switch( pHwData->phy_type ) - { - case RF_AIROHA_2230: - case RF_AIROHA_2230S: // 20060420 Add this - if( Is11bRate ) - { - if( (reg->BB48 != BB48_DEFAULT_AL2230_11B) && - (reg->BB4C != BB4C_DEFAULT_AL2230_11B) ) - { - Wb35Reg_Write( pHwData, 0x1048, BB48_DEFAULT_AL2230_11B ); - Wb35Reg_Write( pHwData, 0x104c, BB4C_DEFAULT_AL2230_11B ); - } + switch (pHwData->phy_type) { + case RF_AIROHA_2230: + case RF_AIROHA_2230S: + if (Is11bRate) { + if ((reg->BB48 != BB48_DEFAULT_AL2230_11B) && + (reg->BB4C != BB4C_DEFAULT_AL2230_11B)) { + Wb35Reg_Write(pHwData, 0x1048, BB48_DEFAULT_AL2230_11B); + Wb35Reg_Write(pHwData, 0x104c, BB4C_DEFAULT_AL2230_11B); } - else - { - if( (reg->BB48 != BB48_DEFAULT_AL2230_11G) && - (reg->BB4C != BB4C_DEFAULT_AL2230_11G) ) - { - Wb35Reg_Write( pHwData, 0x1048, BB48_DEFAULT_AL2230_11G ); - Wb35Reg_Write( pHwData, 0x104c, BB4C_DEFAULT_AL2230_11G ); - } + } else { + if ((reg->BB48 != BB48_DEFAULT_AL2230_11G) && + (reg->BB4C != BB4C_DEFAULT_AL2230_11G)) { + Wb35Reg_Write(pHwData, 0x1048, BB48_DEFAULT_AL2230_11G); + Wb35Reg_Write(pHwData, 0x104c, BB4C_DEFAULT_AL2230_11G); } - break; - - case RF_WB_242: // 20060623 The fix only for old TxVGA setting - if( Is11bRate ) - { - if( (reg->BB48 != BB48_DEFAULT_WB242_11B) && - (reg->BB4C != BB4C_DEFAULT_WB242_11B) ) - { - reg->BB48 = BB48_DEFAULT_WB242_11B; - reg->BB4C = BB4C_DEFAULT_WB242_11B; - Wb35Reg_Write( pHwData, 0x1048, BB48_DEFAULT_WB242_11B ); - Wb35Reg_Write( pHwData, 0x104c, BB4C_DEFAULT_WB242_11B ); - } + } + break; + case RF_WB_242: + if (Is11bRate) { + if ((reg->BB48 != BB48_DEFAULT_WB242_11B) && + (reg->BB4C != BB4C_DEFAULT_WB242_11B)) { + reg->BB48 = BB48_DEFAULT_WB242_11B; + reg->BB4C = BB4C_DEFAULT_WB242_11B; + Wb35Reg_Write(pHwData, 0x1048, BB48_DEFAULT_WB242_11B); + Wb35Reg_Write(pHwData, 0x104c, BB4C_DEFAULT_WB242_11B); } - else - { - if( (reg->BB48 != BB48_DEFAULT_WB242_11G) && - (reg->BB4C != BB4C_DEFAULT_WB242_11G) ) - { - reg->BB48 = BB48_DEFAULT_WB242_11G; - reg->BB4C = BB4C_DEFAULT_WB242_11G; - Wb35Reg_Write( pHwData, 0x1048, BB48_DEFAULT_WB242_11G ); - Wb35Reg_Write( pHwData, 0x104c, BB4C_DEFAULT_WB242_11G ); - } + } else { + if ((reg->BB48 != BB48_DEFAULT_WB242_11G) && + (reg->BB4C != BB4C_DEFAULT_WB242_11G)) { + reg->BB48 = BB48_DEFAULT_WB242_11G; + reg->BB4C = BB4C_DEFAULT_WB242_11G; + Wb35Reg_Write(pHwData, 0x1048, BB48_DEFAULT_WB242_11G); + Wb35Reg_Write(pHwData, 0x104c, BB4C_DEFAULT_WB242_11G); } - break; + } + break; } } - - - - - - -- cgit v1.2.3 From c64ba207ddcb7ea426032ae7166b5f666ea1d3c5 Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Sun, 21 Mar 2010 17:55:03 +0100 Subject: Staging: winbond: sme_api.h Coding style fixes. I fixed the things reported by checkpatch.pl except one long line and a __inline. I also removed commented away code and versioning comments. Signed-off-by: Lars Lindley Pavel Machek Acked-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/sme_api.h | 211 +++++++++++++------------------------- 1 file changed, 71 insertions(+), 140 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/sme_api.h b/drivers/staging/winbond/sme_api.h index b5898294eb8a..8f4596c9e9b3 100644 --- a/drivers/staging/winbond/sme_api.h +++ b/drivers/staging/winbond/sme_api.h @@ -2,12 +2,6 @@ * sme_api.h * * Copyright(C) 2002 Winbond Electronics Corp. - * - * modification history - * --------------------------------------------------------------------------- - * 1.00.001, 2003-04-21, Kevin created - * 1.00.002, 2003-05-14, PD43 & PE20 modified - * */ #ifndef __SME_API_H__ @@ -18,42 +12,42 @@ #include "localpara.h" /****************** CONSTANT AND MACRO SECTION ******************************/ -#define _INLINE __inline +#define _INLINE __inline -#define MEDIA_STATE_DISCONNECTED 0 -#define MEDIA_STATE_CONNECTED 1 +#define MEDIA_STATE_DISCONNECTED 0 +#define MEDIA_STATE_CONNECTED 1 -//ARRAY CHECK -#define MAX_POWER_TO_DB 32 +/* ARRAY CHECK */ +#define MAX_POWER_TO_DB 32 /****************** TYPE DEFINITION SECTION *********************************/ /****************** EXPORTED FUNCTION DECLARATION SECTION *******************/ -// OID_802_11_BSSID +/* OID_802_11_BSSID */ s8 sme_get_bssid(void *pcore_data, u8 *pbssid); -s8 sme_get_desired_bssid(void *pcore_data, u8 *pbssid);//Not use +s8 sme_get_desired_bssid(void *pcore_data, u8 *pbssid); /* Not use */ s8 sme_set_desired_bssid(void *pcore_data, u8 *pbssid); -// OID_802_11_SSID +/* OID_802_11_SSID */ s8 sme_get_ssid(void *pcore_data, u8 *pssid, u8 *pssid_len); -s8 sme_get_desired_ssid(void *pcore_data, u8 *pssid, u8 *pssid_len);// Not use +s8 sme_get_desired_ssid(void *pcore_data, u8 *pssid, u8 *pssid_len);/* Not use */ s8 sme_set_desired_ssid(void *pcore_data, u8 *pssid, u8 ssid_len); -// OID_802_11_INFRASTRUCTURE_MODE +/* OID_802_11_INFRASTRUCTURE_MODE */ s8 sme_get_bss_type(void *pcore_data, u8 *pbss_type); -s8 sme_get_desired_bss_type(void *pcore_data, u8 *pbss_type);//Not use +s8 sme_get_desired_bss_type(void *pcore_data, u8 *pbss_type); /* Not use */ s8 sme_set_desired_bss_type(void *pcore_data, u8 bss_type); -// OID_802_11_FRAGMENTATION_THRESHOLD +/* OID_802_11_FRAGMENTATION_THRESHOLD */ s8 sme_get_fragment_threshold(void *pcore_data, u32 *pthreshold); s8 sme_set_fragment_threshold(void *pcore_data, u32 threshold); -// OID_802_11_RTS_THRESHOLD +/* OID_802_11_RTS_THRESHOLD */ s8 sme_get_rts_threshold(void *pcore_data, u32 *pthreshold); s8 sme_set_rts_threshold(void *pcore_data, u32 threshold); -// OID_802_11_CONFIGURATION +/* OID_802_11_CONFIGURATION */ s8 sme_get_beacon_period(void *pcore_data, u16 *pbeacon_period); s8 sme_set_beacon_period(void *pcore_data, u16 beacon_period); @@ -64,116 +58,69 @@ s8 sme_get_current_channel(void *pcore_data, u8 *pcurrent_channel); s8 sme_get_current_band(void *pcore_data, u8 *pcurrent_band); s8 sme_set_current_channel(void *pcore_data, u8 current_channel); -// OID_802_11_BSSID_LIST +/* OID_802_11_BSSID_LIST */ s8 sme_get_scan_bss_count(void *pcore_data, u8 *pcount); s8 sme_get_scan_bss(void *pcore_data, u8 index, void **ppbss); s8 sme_get_connected_bss(void *pcore_data, void **ppbss_now); -// OID_802_11_AUTHENTICATION_MODE +/* OID_802_11_AUTHENTICATION_MODE */ s8 sme_get_auth_mode(void *pcore_data, u8 *pauth_mode); s8 sme_set_auth_mode(void *pcore_data, u8 auth_mode); -// OID_802_11_WEP_STATUS / OID_802_11_ENCRYPTION_STATUS +/* OID_802_11_WEP_STATUS / OID_802_11_ENCRYPTION_STATUS */ s8 sme_get_wep_mode(void *pcore_data, u8 *pwep_mode); s8 sme_set_wep_mode(void *pcore_data, u8 wep_mode); -//s8 sme_get_encryption_status(void *pcore_data, u8 *pstatus); -//s8 sme_set_encryption_status(void *pcore_data, u8 status); - -// ??????????????????????????????????????? -// OID_GEN_VENDOR_ID -// OID_802_3_PERMANENT_ADDRESS +/* OID_GEN_VENDOR_ID */ +/* OID_802_3_PERMANENT_ADDRESS */ s8 sme_get_permanent_mac_addr(void *pcore_data, u8 *pmac_addr); -// OID_802_3_CURRENT_ADDRESS +/* OID_802_3_CURRENT_ADDRESS */ s8 sme_get_current_mac_addr(void *pcore_data, u8 *pmac_addr); -// OID_802_11_NETWORK_TYPE_IN_USE +/* OID_802_11_NETWORK_TYPE_IN_USE */ s8 sme_get_network_type_in_use(void *pcore_data, u8 *ptype); s8 sme_set_network_type_in_use(void *pcore_data, u8 type); -// OID_802_11_SUPPORTED_RATES +/* OID_802_11_SUPPORTED_RATES */ s8 sme_get_supported_rate(void *pcore_data, u8 *prates); -// OID_802_11_ADD_WEP -//12/29/03' wkchen +/* OID_802_11_ADD_WEP */ s8 sme_set_add_wep(void *pcore_data, u32 key_index, u32 key_len, u8 *Address, u8 *key); -// OID_802_11_REMOVE_WEP +/* OID_802_11_REMOVE_WEP */ s8 sme_set_remove_wep(void *pcre_data, u32 key_index); -// OID_802_11_DISASSOCIATE +/* OID_802_11_DISASSOCIATE */ s8 sme_set_disassociate(void *pcore_data); -// OID_802_11_POWER_MODE +/* OID_802_11_POWER_MODE */ s8 sme_get_power_mode(void *pcore_data, u8 *pmode); s8 sme_set_power_mode(void *pcore_data, u8 mode); -// OID_802_11_BSSID_LIST_SCAN +/* OID_802_11_BSSID_LIST_SCAN */ s8 sme_set_bssid_list_scan(void *pcore_data, void *pscan_para); -// OID_802_11_RELOAD_DEFAULTS +/* OID_802_11_RELOAD_DEFAULTS */ s8 sme_set_reload_defaults(void *pcore_data, u8 reload_type); -// The following SME API functions are used for WPA -// -// Mandatory OIDs for WPA -// - -// OID_802_11_ADD_KEY -//s8 sme_set_add_key(void *pcore_data, NDIS_802_11_KEY *pkey); - -// OID_802_11_REMOVE_KEY -//s8 sme_set_remove_key(void *pcore_data, NDIS_802_11_REMOVE_KEY *pkey); - -// OID_802_11_ASSOCIATION_INFORMATION -//s8 sme_set_association_information(void *pcore_data, -// NDIS_802_11_ASSOCIATION_INFORMATION *pinfo); - -// OID_802_11_TEST -//s8 sme_set_test(void *pcore_data, NDIS_802_11_TEST *ptest_data); - -//--------------------------------------------------------------------------// -/* -// The left OIDs - -// OID_802_11_NETWORK_TYPES_SUPPORTED -// OID_802_11_TX_POWER_LEVEL -// OID_802_11_RSSI_TRIGGER -// OID_802_11_NUMBER_OF_ANTENNAS -// OID_802_11_RX_ANTENNA_SELECTED -// OID_802_11_TX_ANTENNA_SELECTED -// OID_802_11_STATISTICS -// OID_802_11_DESIRED_RATES -// OID_802_11_PRIVACY_FILTER - -*/ - /*------------------------- none-standard ----------------------------------*/ s8 sme_get_connect_status(void *pcore_data, u8 *pstatus); - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -//s8 sme_get_scan_type(void *pcore_data, u8 *pscan_type); -//s8 sme_set_scan_type(void *pcore_data, u8 scan_type); - -//s8 sme_get_scan_channel_list(void *pcore_data, u8 *pscan_type); -//s8 sme_set_scan_channel_list(void *pcore_data, u8 scan_type); - +/*--------------------------------------------------------------------------*/ void sme_get_encryption_status(void *pcore_data, u8 *EncryptStatus); void sme_set_encryption_status(void *pcore_data, u8 EncryptStatus); -s8 sme_add_key(void *pcore_data, - u32 key_index, - u8 key_len, - u8 key_type, - u8 *key_bssid, - //u8 *key_rsc, - u8 *ptx_tsc, - u8 *prx_tsc, - u8 *key_material); +s8 sme_add_key(void *pcore_data, + u32 key_index, + u8 key_len, + u8 key_type, + u8 *key_bssid, + u8 *ptx_tsc, + u8 *prx_tsc, + u8 *key_material); void sme_remove_default_key(void *pcore_data, int index); void sme_remove_mapping_key(void *pcore_data, u8 *pmac_addr); void sme_clear_all_mapping_key(void *pcore_data); @@ -202,60 +149,44 @@ u8 sme_set_rx_antenna(void *pcore_data, u32 RxAntenna); void sme_get_tx_antenna(void *pcore_data, u32 *TxAntenna); s8 sme_set_tx_antenna(void *pcore_data, u32 TxAntenna); s8 sme_set_IBSS_chan(void *pcore_data, struct chan_info chan); - -//20061108 WPS s8 sme_set_IE_append(void *pcore_data, u8 *buffer, u16 buf_len); - - - -//================== Local functions ====================== -//#ifdef _HSINCHU -//void drv_translate_rssi(); // HW RSSI bit -> NDIS RSSI representation -//void drv_translate_bss_description(); // Local bss desc -> NDIS bss desc -//void drv_translate_channel(u8 NetworkType, u8 ChannelNumber, u32 *freq); // channel number -> channel /freq. -//#endif _HSINCHU -// -static const u32 PowerDbToMw[] = -{ - 56, //mW, MAX - 0, 17.5 dbm - 40, //mW, MAX - 1, 16.0 dbm - 30, //mW, MAX - 2, 14.8 dbm - 20, //mW, MAX - 3, 13.0 dbm - 15, //mW, MAX - 4, 11.8 dbm - 12, //mW, MAX - 5, 10.6 dbm - 9, //mW, MAX - 6, 9.4 dbm - 7, //mW, MAX - 7, 8.3 dbm - 5, //mW, MAX - 8, 6.4 dbm - 4, //mW, MAX - 9, 5.3 dbm - 3, //mW, MAX - 10, 4.0 dbm - 2, //mW, MAX - 11, ? dbm - 2, //mW, MAX - 12, ? dbm - 2, //mW, MAX - 13, ? dbm - 2, //mW, MAX - 14, ? dbm - 2, //mW, MAX - 15, ? dbm - 2, //mW, MAX - 16, ? dbm - 2, //mW, MAX - 17, ? dbm - 2, //mW, MAX - 18, ? dbm - 1, //mW, MAX - 19, ? dbm - 1, //mW, MAX - 20, ? dbm - 1, //mW, MAX - 21, ? dbm - 1, //mW, MAX - 22, ? dbm - 1, //mW, MAX - 23, ? dbm - 1, //mW, MAX - 24, ? dbm - 1, //mW, MAX - 25, ? dbm - 1, //mW, MAX - 26, ? dbm - 1, //mW, MAX - 27, ? dbm - 1, //mW, MAX - 28, ? dbm - 1, //mW, MAX - 29, ? dbm - 1, //mW, MAX - 30, ? dbm - 1 //mW, MAX - 31, ? dbm +/* ================== Local functions ====================== */ +static const u32 PowerDbToMw[] = { + 56, /* mW, MAX - 0, 17.5 dbm */ + 40, /* mW, MAX - 1, 16.0 dbm */ + 30, /* mW, MAX - 2, 14.8 dbm */ + 20, /* mW, MAX - 3, 13.0 dbm */ + 15, /* mW, MAX - 4, 11.8 dbm */ + 12, /* mW, MAX - 5, 10.6 dbm */ + 9, /* mW, MAX - 6, 9.4 dbm */ + 7, /* mW, MAX - 7, 8.3 dbm */ + 5, /* mW, MAX - 8, 6.4 dbm */ + 4, /* mW, MAX - 9, 5.3 dbm */ + 3, /* mW, MAX - 10, 4.0 dbm */ + 2, /* mW, MAX - 11, ? dbm */ + 2, /* mW, MAX - 12, ? dbm */ + 2, /* mW, MAX - 13, ? dbm */ + 2, /* mW, MAX - 14, ? dbm */ + 2, /* mW, MAX - 15, ? dbm */ + 2, /* mW, MAX - 16, ? dbm */ + 2, /* mW, MAX - 17, ? dbm */ + 2, /* mW, MAX - 18, ? dbm */ + 1, /* mW, MAX - 19, ? dbm */ + 1, /* mW, MAX - 20, ? dbm */ + 1, /* mW, MAX - 21, ? dbm */ + 1, /* mW, MAX - 22, ? dbm */ + 1, /* mW, MAX - 23, ? dbm */ + 1, /* mW, MAX - 24, ? dbm */ + 1, /* mW, MAX - 25, ? dbm */ + 1, /* mW, MAX - 26, ? dbm */ + 1, /* mW, MAX - 27, ? dbm */ + 1, /* mW, MAX - 28, ? dbm */ + 1, /* mW, MAX - 29, ? dbm */ + 1, /* mW, MAX - 30, ? dbm */ + 1 /* mW, MAX - 31, ? dbm */ }; - - - - #endif /* __SME_API_H__ */ -- cgit v1.2.3 From 89343a0e058c26965696c74321248768a1292f12 Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Sun, 21 Mar 2010 22:31:30 +0100 Subject: Staging: winbond: sysdef.h Coding style fixes. I fixed the C99 comments and removed commented away code. Signed-off-by: Lars Lindley Acked-by: Pavel Machek Acked-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/sysdef.h | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/sysdef.h b/drivers/staging/winbond/sysdef.h index 251b9c553b6c..9195adf98e14 100644 --- a/drivers/staging/winbond/sysdef.h +++ b/drivers/staging/winbond/sysdef.h @@ -1,31 +1,19 @@ +/* Winbond WLAN System Configuration defines */ - -// -// Winbond WLAN System Configuration defines -// - -//===================================================================== -// Current directory is Linux -// The definition WB_LINUX is a keyword for this OS -//===================================================================== #ifndef SYS_DEF_H #define SYS_DEF_H #define WB_LINUX #define WB_LINUX_WPA_PSK - -//#define _IBSS_BEACON_SEQ_STICK_ #define _USE_FALLBACK_RATE_ -//#define ANTDIV_DEFAULT_ON - -#define _WPA2_ // 20061122 It's needed for current Linux driver +#define _WPA2_ #ifndef _WPA_PSK_DEBUG #undef _WPA_PSK_DEBUG #endif -// debug print options, mark what debug you don't need +/* debug print options, mark what debug you don't need */ #ifdef FULL_DEBUG #define _PE_STATE_DUMP_ -- cgit v1.2.3 From d4279a9f2cfd349b8e308770b826ae09f3f5b86d Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Mon, 22 Mar 2010 11:55:30 +0100 Subject: Staging: winbond: wb35reg_f.h Coding style fixes. I fixed the checkpatch things except a couple of long lines. I also removed hungarian notation and CamelCase from the argument names and some "commented away" code. Signed-off-by: Lars Lindley Acked-by: Pavel Machek Acked-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wb35reg_f.h | 104 +++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/wb35reg_f.h b/drivers/staging/winbond/wb35reg_f.h index d352bce5c171..bf23c1084199 100644 --- a/drivers/staging/winbond/wb35reg_f.h +++ b/drivers/staging/winbond/wb35reg_f.h @@ -3,59 +3,63 @@ #include "wbhal_s.h" -//==================================== -// Interface function declare -//==================================== -unsigned char Wb35Reg_initial( struct hw_data * pHwData ); -void Uxx_power_on_procedure( struct hw_data * pHwData ); -void Uxx_power_off_procedure( struct hw_data * pHwData ); -void Uxx_ReadEthernetAddress( struct hw_data * pHwData ); -void Dxx_initial( struct hw_data * pHwData ); -void Mxx_initial( struct hw_data * pHwData ); -void RFSynthesizer_initial( struct hw_data * pHwData ); -//void RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, s8 Channel ); -void RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, struct chan_info Channel ); -void BBProcessor_initial( struct hw_data * pHwData ); -void BBProcessor_RateChanging( struct hw_data * pHwData, u8 rate ); // 20060613.1 -//void RF_RateChanging( struct hw_data * pHwData, u8 rate ); // 20060626.5.c Add -u8 RFSynthesizer_SetPowerIndex( struct hw_data * pHwData, u8 PowerIndex ); -u8 RFSynthesizer_SetMaxim2828_24Power( struct hw_data *, u8 index ); -u8 RFSynthesizer_SetMaxim2828_50Power( struct hw_data *, u8 index ); -u8 RFSynthesizer_SetMaxim2827_24Power( struct hw_data *, u8 index ); -u8 RFSynthesizer_SetMaxim2827_50Power( struct hw_data *, u8 index ); -u8 RFSynthesizer_SetMaxim2825Power( struct hw_data *, u8 index ); -u8 RFSynthesizer_SetAiroha2230Power( struct hw_data *, u8 index ); -u8 RFSynthesizer_SetAiroha7230Power( struct hw_data *, u8 index ); -u8 RFSynthesizer_SetWinbond242Power( struct hw_data *, u8 index ); -void GetTxVgaFromEEPROM( struct hw_data * pHwData ); -void EEPROMTxVgaAdjust( struct hw_data * pHwData ); // 20060619.5 Add - -#define RFWriteControlData( _A, _V ) Wb35Reg_Write( _A, 0x0864, _V ) - -void Wb35Reg_destroy( struct hw_data * pHwData ); - -unsigned char Wb35Reg_Read( struct hw_data * pHwData, u16 RegisterNo, u32 * pRegisterValue ); -unsigned char Wb35Reg_ReadSync( struct hw_data * pHwData, u16 RegisterNo, u32 * pRegisterValue ); -unsigned char Wb35Reg_Write( struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue ); -unsigned char Wb35Reg_WriteSync( struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue ); -unsigned char Wb35Reg_WriteWithCallbackValue( struct hw_data * pHwData, - u16 RegisterNo, - u32 RegisterValue, - s8 *pValue, - s8 Len); -unsigned char Wb35Reg_BurstWrite( struct hw_data * pHwData, u16 RegisterNo, u32 * pRegisterData, u8 NumberOfData, u8 Flag ); - -void Wb35Reg_EP0VM( struct hw_data * pHwData ); -void Wb35Reg_EP0VM_start( struct hw_data * pHwData ); +/* + * ==================================== + * Interface function declare + * ==================================== + */ +unsigned char Wb35Reg_initial(struct hw_data *hw_data); +void Uxx_power_on_procedure(struct hw_data *hw_data); +void Uxx_power_off_procedure(struct hw_data *hw_data); +void Uxx_ReadEthernetAddress(struct hw_data *hw_data); +void Dxx_initial(struct hw_data *hw_data); +void Mxx_initial(struct hw_data *hw_data); +void RFSynthesizer_initial(struct hw_data *hw_data); +void RFSynthesizer_SwitchingChannel(struct hw_data *hw_data, struct chan_info channel); +void BBProcessor_initial(struct hw_data *hw_data); +void BBProcessor_RateChanging(struct hw_data *hw_data, u8 rate); +u8 RFSynthesizer_SetPowerIndex(struct hw_data *hw_data, u8 power_index); +u8 RFSynthesizer_SetMaxim2828_24Power(struct hw_data *, u8 index); +u8 RFSynthesizer_SetMaxim2828_50Power(struct hw_data *, u8 index); +u8 RFSynthesizer_SetMaxim2827_24Power(struct hw_data *, u8 index); +u8 RFSynthesizer_SetMaxim2827_50Power(struct hw_data *, u8 index); +u8 RFSynthesizer_SetMaxim2825Power(struct hw_data *, u8 index); +u8 RFSynthesizer_SetAiroha2230Power(struct hw_data *, u8 index); +u8 RFSynthesizer_SetAiroha7230Power(struct hw_data *, u8 index); +u8 RFSynthesizer_SetWinbond242Power(struct hw_data *, u8 index); +void GetTxVgaFromEEPROM(struct hw_data *hw_data); +void EEPROMTxVgaAdjust(struct hw_data *hw_data); + +#define RFWriteControlData(_A, _V) Wb35Reg_Write(_A, 0x0864, _V) + +void Wb35Reg_destroy(struct hw_data *hw_data); + +unsigned char Wb35Reg_Read(struct hw_data *hw_data, u16 register_no, u32 *register_value); +unsigned char Wb35Reg_ReadSync(struct hw_data *hw_data, u16 register_no, u32 *register_value); +unsigned char Wb35Reg_Write(struct hw_data *hw_data, u16 register_no, u32 register_value); +unsigned char Wb35Reg_WriteSync(struct hw_data *hw_data, u16 register_no, u32 register_value); +unsigned char Wb35Reg_WriteWithCallbackValue(struct hw_data *hw_data, + u16 register_no, + u32 register_value, + s8 *value, + s8 len); +unsigned char Wb35Reg_BurstWrite(struct hw_data *hw_data, + u16 register_no, + u32 *register_data, + u8 number_of_data, + u8 flag); + +void Wb35Reg_EP0VM(struct hw_data *hw_data); +void Wb35Reg_EP0VM_start(struct hw_data *hw_data); void Wb35Reg_EP0VM_complete(struct urb *urb); -u32 BitReverse( u32 dwData, u32 DataLength); +u32 BitReverse(u32 data, u32 data_length); -void CardGetMulticastBit( u8 Address[MAC_ADDR_LENGTH], u8 *Byte, u8 *Value ); -u32 CardComputeCrc( u8 * Buffer, u32 Length ); +void CardGetMulticastBit(u8 address[MAC_ADDR_LENGTH], u8 *byte, u8 *value); +u32 CardComputeCrc(u8 *buffer, u32 length); -void Wb35Reg_phy_calibration( struct hw_data * pHwData ); -void Wb35Reg_Update( struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue ); -unsigned char adjust_TXVGA_for_iq_mag( struct hw_data * pHwData ); +void Wb35Reg_phy_calibration(struct hw_data *hw_data); +void Wb35Reg_Update(struct hw_data *hw_data, u16 register_no, u32 register_value); +unsigned char adjust_TXVGA_for_iq_mag(struct hw_data *hw_data); #endif -- cgit v1.2.3 From 25e47dfc863406a29d7e66c4d673cc712647b50f Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Mon, 22 Mar 2010 18:59:58 +0100 Subject: Staging: winbond: wb35reg_s.h Coding styls fixes. I fixed all problems reported by checkpatch.pl except some long lines. I also removed commented away code and revision comments. Checked for regressions with Dan Carpenters strip_whitespace.pl and diff. Signed-off-by: Lars Lindley Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wb35reg_s.h | 221 ++++++++++++++++++------------------ 1 file changed, 110 insertions(+), 111 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/wb35reg_s.h b/drivers/staging/winbond/wb35reg_s.h index 32ef4b8a2d2a..4eff009444b8 100644 --- a/drivers/staging/winbond/wb35reg_s.h +++ b/drivers/staging/winbond/wb35reg_s.h @@ -5,98 +5,100 @@ #include #include -//======================================================================================= -/* - HAL setting function - - ======================================== - |Uxx| |Dxx| |Mxx| |BB| |RF| - ======================================== - | | - Wb35Reg_Read Wb35Reg_Write - - ---------------------------------------- - WbUsb_CallUSBDASync supplied By WbUsb module -*/ -//======================================================================================= - -#define GetBit( dwData, i) ( dwData & (0x00000001 << i)) -#define SetBit( dwData, i) ( dwData | (0x00000001 << i)) -#define ClearBit( dwData, i) ( dwData & ~(0x00000001 << i)) - -#define IGNORE_INCREMENT 0 -#define AUTO_INCREMENT 0 -#define NO_INCREMENT 1 -#define REG_DIRECTION(_x,_y) ((_y)->DIRECT ==0 ? usb_rcvctrlpipe(_x,0) : usb_sndctrlpipe(_x,0)) -#define REG_BUF_SIZE(_x) ((_x)->bRequest== 0x04 ? cpu_to_le16((_x)->wLength) : 4) - -// 20060613.2 Add the follow definition +/* ========================================================================= + * + * HAL setting function + * + * ======================================== + * |Uxx| |Dxx| |Mxx| |BB| |RF| + * ======================================== + * | | + * Wb35Reg_Read Wb35Reg_Write + * + * ---------------------------------------- + * WbUsb_CallUSBDASync supplied By WbUsb module + * ========================================================================== + */ +#define GetBit(dwData, i) (dwData & (0x00000001 << i)) +#define SetBit(dwData, i) (dwData | (0x00000001 << i)) +#define ClearBit(dwData, i) (dwData & ~(0x00000001 << i)) + +#define IGNORE_INCREMENT 0 +#define AUTO_INCREMENT 0 +#define NO_INCREMENT 1 +#define REG_DIRECTION(_x, _y) ((_y)->DIRECT == 0 ? usb_rcvctrlpipe(_x, 0) : usb_sndctrlpipe(_x, 0)) +#define REG_BUF_SIZE(_x) ((_x)->bRequest == 0x04 ? cpu_to_le16((_x)->wLength) : 4) + #define BB48_DEFAULT_AL2230_11B 0x0033447c #define BB4C_DEFAULT_AL2230_11B 0x0A00FEFF #define BB48_DEFAULT_AL2230_11G 0x00332C1B #define BB4C_DEFAULT_AL2230_11G 0x0A00FEFF -#define BB48_DEFAULT_WB242_11B 0x00292315 //backoff 2dB -#define BB4C_DEFAULT_WB242_11B 0x0800FEFF //backoff 2dB -//#define BB48_DEFAULT_WB242_11B 0x00201B11 //backoff 4dB -//#define BB4C_DEFAULT_WB242_11B 0x0600FF00 //backoff 4dB +#define BB48_DEFAULT_WB242_11B 0x00292315 /* backoff 2dB */ +#define BB4C_DEFAULT_WB242_11B 0x0800FEFF /* backoff 2dB */ #define BB48_DEFAULT_WB242_11G 0x00453B24 #define BB4C_DEFAULT_WB242_11G 0x0E00FEFF -//==================================== -// Default setting for Mxx -//==================================== -#define DEFAULT_CWMIN 31 //(M2C) CWmin. Its value is in the range 0-31. -#define DEFAULT_CWMAX 1023 //(M2C) CWmax. Its value is in the range 0-1023. -#define DEFAULT_AID 1 //(M34) AID. Its value is in the range 1-2007. +/* + * ==================================== + * Default setting for Mxx + * ==================================== + */ +#define DEFAULT_CWMIN 31 /* (M2C) CWmin. Its value is in the range 0-31. */ +#define DEFAULT_CWMAX 1023 /* (M2C) CWmax. Its value is in the range 0-1023. */ +#define DEFAULT_AID 1 /* (M34) AID. Its value is in the range 1-2007. */ #ifdef _USE_FALLBACK_RATE_ -#define DEFAULT_RATE_RETRY_LIMIT 2 //(M38) as named +#define DEFAULT_RATE_RETRY_LIMIT 2 /* (M38) as named */ #else -#define DEFAULT_RATE_RETRY_LIMIT 7 //(M38) as named +#define DEFAULT_RATE_RETRY_LIMIT 7 /* (M38) as named */ #endif -#define DEFAULT_LONG_RETRY_LIMIT 7 //(M38) LongRetryLimit. Its value is in the range 0-15. -#define DEFAULT_SHORT_RETRY_LIMIT 7 //(M38) ShortRetryLimit. Its value is in the range 0-15. -#define DEFAULT_PIFST 25 //(M3C) PIFS Time. Its value is in the range 0-65535. -#define DEFAULT_EIFST 354 //(M3C) EIFS Time. Its value is in the range 0-1048575. -#define DEFAULT_DIFST 45 //(M3C) DIFS Time. Its value is in the range 0-65535. -#define DEFAULT_SIFST 5 //(M3C) SIFS Time. Its value is in the range 0-65535. -#define DEFAULT_OSIFST 10 //(M3C) Original SIFS Time. Its value is in the range 0-15. -#define DEFAULT_ATIMWD 0 //(M40) ATIM Window. Its value is in the range 0-65535. -#define DEFAULT_SLOT_TIME 20 //(M40) ($) SlotTime. Its value is in the range 0-255. -#define DEFAULT_MAX_TX_MSDU_LIFE_TIME 512 //(M44) MaxTxMSDULifeTime. Its value is in the range 0-4294967295. -#define DEFAULT_BEACON_INTERVAL 500 //(M48) Beacon Interval. Its value is in the range 0-65535. -#define DEFAULT_PROBE_DELAY_TIME 200 //(M48) Probe Delay Time. Its value is in the range 0-65535. -#define DEFAULT_PROTOCOL_VERSION 0 //(M4C) -#define DEFAULT_MAC_POWER_STATE 2 //(M4C) 2: MAC at power active -#define DEFAULT_DTIM_ALERT_TIME 0 +#define DEFAULT_LONG_RETRY_LIMIT 7 /* (M38) LongRetryLimit. Its value is in the range 0-15. */ +#define DEFAULT_SHORT_RETRY_LIMIT 7 /* (M38) ShortRetryLimit. Its value is in the range 0-15. */ +#define DEFAULT_PIFST 25 /* (M3C) PIFS Time. Its value is in the range 0-65535. */ +#define DEFAULT_EIFST 354 /* (M3C) EIFS Time. Its value is in the range 0-1048575. */ +#define DEFAULT_DIFST 45 /* (M3C) DIFS Time. Its value is in the range 0-65535. */ +#define DEFAULT_SIFST 5 /* (M3C) SIFS Time. Its value is in the range 0-65535. */ +#define DEFAULT_OSIFST 10 /* (M3C) Original SIFS Time. Its value is in the range 0-15. */ +#define DEFAULT_ATIMWD 0 /* (M40) ATIM Window. Its value is in the range 0-65535. */ +#define DEFAULT_SLOT_TIME 20 /* (M40) ($) SlotTime. Its value is in the range 0-255. */ +#define DEFAULT_MAX_TX_MSDU_LIFE_TIME 512 /* (M44) MaxTxMSDULifeTime. Its value is in the range 0-4294967295. */ +#define DEFAULT_BEACON_INTERVAL 500 /* (M48) Beacon Interval. Its value is in the range 0-65535. */ +#define DEFAULT_PROBE_DELAY_TIME 200 /* (M48) Probe Delay Time. Its value is in the range 0-65535. */ +#define DEFAULT_PROTOCOL_VERSION 0 /* (M4C) */ +#define DEFAULT_MAC_POWER_STATE 2 /* (M4C) 2: MAC at power active */ +#define DEFAULT_DTIM_ALERT_TIME 0 struct wb35_reg_queue { - struct urb *urb; + struct urb *urb; void *pUsbReq; void *Next; union { u32 VALUE; u32 *pBuffer; }; - u8 RESERVED[4]; // space reserved for communication - u16 INDEX; // For storing the register index - u8 RESERVED_VALID; // Indicate whether the RESERVED space is valid at this command. - u8 DIRECT; // 0:In 1:Out + u8 RESERVED[4]; /* space reserved for communication */ + u16 INDEX; /* For storing the register index */ + u8 RESERVED_VALID; /* Indicate whether the RESERVED space is valid at this command. */ + u8 DIRECT; /* 0:In 1:Out */ }; -//==================================== -// Internal variable for module -//==================================== +/* + * ==================================== + * Internal variable for module + * ==================================== + */ #define MAX_SQ3_FILTER_SIZE 5 struct wb35_reg { - //============================ - // Register Bank backup - //============================ - u32 U1B0; //bit16 record the h/w radio on/off status + /* + * ============================ + * Register Bank backup + * ============================ + */ + u32 U1B0; /* bit16 record the h/w radio on/off status */ u32 U1BC_LEDConfigure; u32 D00_DmaControl; u32 M00_MacControl; @@ -105,68 +107,65 @@ struct wb35_reg { u32 M04_MulticastAddress1; u32 M08_MulticastAddress2; }; - u8 Multicast[8]; // contents of card multicast registers + u8 Multicast[8]; /* contents of card multicast registers */ }; u32 M24_MacControl; u32 M28_MacControl; u32 M2C_MacControl; u32 M38_MacControl; - u32 M3C_MacControl; // 20060214 backup only + u32 M3C_MacControl; u32 M40_MacControl; - u32 M44_MacControl; // 20060214 backup only - u32 M48_MacControl; // 20060214 backup only + u32 M44_MacControl; + u32 M48_MacControl; u32 M4C_MacStatus; - u32 M60_MacControl; // 20060214 backup only - u32 M68_MacControl; // 20060214 backup only - u32 M70_MacControl; // 20060214 backup only - u32 M74_MacControl; // 20060214 backup only - u32 M78_ERPInformation;//930206.2.b - u32 M7C_MacControl; // 20060214 backup only - u32 M80_MacControl; // 20060214 backup only - u32 M84_MacControl; // 20060214 backup only - u32 M88_MacControl; // 20060214 backup only - u32 M98_MacControl; // 20060214 backup only - - //[20040722 WK] - //Baseband register - u32 BB0C; // Used for LNA calculation - u32 BB2C; // - u32 BB30; //11b acquisition control register + u32 M60_MacControl; + u32 M68_MacControl; + u32 M70_MacControl; + u32 M74_MacControl; + u32 M78_ERPInformation; + u32 M7C_MacControl; + u32 M80_MacControl; + u32 M84_MacControl; + u32 M88_MacControl; + u32 M98_MacControl; + + /* Baseband register */ + u32 BB0C; /* Used for LNA calculation */ + u32 BB2C; + u32 BB30; /* 11b acquisition control register */ u32 BB3C; - u32 BB48; // 20051221.1.a 20060613.1 Fix OBW issue of 11b/11g rate - u32 BB4C; // 20060613.1 Fix OBW issue of 11b/11g rate - u32 BB50; //mode control register + u32 BB48; + u32 BB4C; + u32 BB50; /* mode control register */ u32 BB54; - u32 BB58; //IQ_ALPHA - u32 BB5C; // For test - u32 BB60; // for WTO read value - - //------------------- - // VM - //------------------- - spinlock_t EP0VM_spin_lock; // 4B - u32 EP0VM_status;//$$ + u32 BB58; /* IQ_ALPHA */ + u32 BB5C; /* For test */ + u32 BB60; /* for WTO read value */ + + /* VM */ + spinlock_t EP0VM_spin_lock; /* 4B */ + u32 EP0VM_status; /* $$ */ struct wb35_reg_queue *reg_first; struct wb35_reg_queue *reg_last; - atomic_t RegFireCount; + atomic_t RegFireCount; - // Hardware status + /* Hardware status */ u8 EP0vm_state; u8 mac_power_save; - u8 EEPROMPhyType; // 0 ~ 15 for Maxim (0 Ä„V MAX2825, 1 Ä„V MAX2827, 2 Ä„V MAX2828, 3 Ä„V MAX2829), - // 16 ~ 31 for Airoha (16 Ä„V AL2230, 11 - AL7230) - // 32 ~ Reserved - // 33 ~ 47 For WB242 ( 33 - WB242, 34 - WB242 with new Txvga 0.5 db step) - // 48 ~ 255 ARE RESERVED. - u8 EEPROMRegion; //Region setting in EEPROM - - u32 SyncIoPause; // If user use the Sync Io to access Hw, then pause the async access - - u8 LNAValue[4]; //Table for speed up running + u8 EEPROMPhyType; /* + * 0 ~ 15 for Maxim (0 Ä„V MAX2825, 1 Ä„V MAX2827, 2 Ä„V MAX2828, 3 Ä„V MAX2829), + * 16 ~ 31 for Airoha (16 Ä„V AL2230, 11 - AL7230) + * 32 ~ Reserved + * 33 ~ 47 For WB242 ( 33 - WB242, 34 - WB242 with new Txvga 0.5 db step) + * 48 ~ 255 ARE RESERVED. + */ + u8 EEPROMRegion; /* Region setting in EEPROM */ + + u32 SyncIoPause; /* If user use the Sync Io to access Hw, then pause the async access */ + + u8 LNAValue[4]; /* Table for speed up running */ u32 SQ3_filter[MAX_SQ3_FILTER_SIZE]; u32 SQ3_index; - }; - #endif -- cgit v1.2.3 From 4095aef6dc485545ebbd96d23eac0b11b729e765 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Mon, 22 Mar 2010 20:41:44 +0200 Subject: Staging: winbond: fix brace, comments and space coding style issue in mlmetxrx.c This is a patch to the mlmetxrx.c file that fixed up a brace, comments and space Errors found by the checkpatch.pl tool. Signed-off-by: Ruslan Pisarev Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mlmetxrx.c | 62 +++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/mlmetxrx.c b/drivers/staging/winbond/mlmetxrx.c index f856b94a7810..dcd8a11b5d03 100644 --- a/drivers/staging/winbond/mlmetxrx.c +++ b/drivers/staging/winbond/mlmetxrx.c @@ -1,26 +1,26 @@ -//============================================================================ -// Module Name: -// MLMETxRx.C -// -// Description: -// The interface between MDS (MAC Data Service) and MLME. -// -// Revision History: -// -------------------------------------------------------------------------- -// 200209 UN20 Jennifer Xu -// Initial Release -// 20021108 PD43 Austin Liu -// 20030117 PD43 Austin Liu -// Deleted MLMEReturnPacket and MLMEProcThread() -// -// Copyright (c) 1996-2002 Winbond Electronics Corp. All Rights Reserved. -//============================================================================ +/* ============================================================================ + Module Name: + MLMETxRx.C + + Description: + The interface between MDS (MAC Data Service) and MLME. + + Revision History: + -------------------------------------------------------------------------- + 200209 UN20 Jennifer Xu + Initial Release + 20021108 PD43 Austin Liu + 20030117 PD43 Austin Liu + Deleted MLMEReturnPacket and MLMEProcThread() + + Copyright (c) 1996-2002 Winbond Electronics Corp. All Rights Reserved. +============================================================================ */ #include "sysdef.h" #include "mds_f.h" -//============================================================================= -u8 MLMESendFrame(struct wbsoft_priv * adapter, u8 *pMMPDU, u16 len, u8 DataType) +/* ============================================================================= */ +u8 MLMESendFrame(struct wbsoft_priv *adapter, u8 *pMMPDU, u16 len, u8 DataType) /* DataType : FRAME_TYPE_802_11_MANAGEMENT, FRAME_TYPE_802_11_MANAGEMENT_CHALLENGE, FRAME_TYPE_802_11_DATA */ { @@ -30,17 +30,17 @@ u8 MLMESendFrame(struct wbsoft_priv * adapter, u8 *pMMPDU, u16 len, u8 DataType) } adapter->sMlmeFrame.IsInUsed = PACKET_COME_FROM_MLME; - // Keep information for sending + /* Keep information for sending */ adapter->sMlmeFrame.pMMPDU = pMMPDU; adapter->sMlmeFrame.DataType = DataType; - // len must be the last setting due to QUERY_SIZE_SECOND of Mds + /* len must be the last setting due to QUERY_SIZE_SECOND of Mds */ adapter->sMlmeFrame.len = len; adapter->sMlmeFrame.wNumTxMMPDU++; - // H/W will enter power save by set the register. S/W don't send null frame - //with PWRMgt bit enbled to enter power save now. + /* H/W will enter power save by set the register. S/W don't send null frame + with PWRMgt bit enbled to enter power save now. */ - // Transmit NDIS packet + /* Transmit NDIS packet */ Mds_Tx(adapter); return true; } @@ -60,7 +60,7 @@ static void MLMEfreeMMPDUBuffer(struct wbsoft_priv *adapter, s8 *pData) { int i; - // Reclaim the data buffer + /* Reclaim the data buffer */ for (i = 0; i < MAX_NUM_TX_MMPDU; i++) { if (pData == (s8 *)&(adapter->sMlmeFrame.TxMMPDU[i])) break; @@ -68,24 +68,24 @@ static void MLMEfreeMMPDUBuffer(struct wbsoft_priv *adapter, s8 *pData) if (adapter->sMlmeFrame.TxMMPDUInUse[i]) adapter->sMlmeFrame.TxMMPDUInUse[i] = false; else { - // Something wrong - // PD43 Add debug code here??? + /* Something wrong + PD43 Add debug code here??? */ } } void -MLME_SendComplete(struct wbsoft_priv * adapter, u8 PacketID, unsigned char SendOK) +MLME_SendComplete(struct wbsoft_priv *adapter, u8 PacketID, unsigned char SendOK) { MLME_TXCALLBACK TxCallback; - // Reclaim the data buffer + /* Reclaim the data buffer */ adapter->sMlmeFrame.len = 0; - MLMEfreeMMPDUBuffer( adapter, adapter->sMlmeFrame.pMMPDU ); + MLMEfreeMMPDUBuffer(adapter, adapter->sMlmeFrame.pMMPDU); TxCallback.bResult = MLME_SUCCESS; - // Return resource + /* Return resource */ adapter->sMlmeFrame.IsInUsed = PACKET_FREE_TO_USE; } -- cgit v1.2.3 From b08585fc584f5e090cf94535171be3ffc6549d98 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Mon, 22 Mar 2010 20:47:48 +0200 Subject: Staging: winbond: fix comments and space coding style issue in mlmetxrx_f.h This is a patch to the mlmetxrx_f.h file that fixed up a comments and space Errors found by the checkpatch.pl tools. Signed-off-by: Ruslan Pisarev Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mlmetxrx_f.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/mlmetxrx_f.h b/drivers/staging/winbond/mlmetxrx_f.h index 6c04e3e03e31..d1aa2617d24b 100644 --- a/drivers/staging/winbond/mlmetxrx_f.h +++ b/drivers/staging/winbond/mlmetxrx_f.h @@ -1,10 +1,10 @@ -//================================================================ +/* ================================================================ // MLMETxRx.H -- // // Functions defined in MLMETxRx.c. // // Copyright (c) 2002 Winbond Electrics Corp. All Rights Reserved. -//================================================================ +//================================================================ */ #ifndef _MLMETXRX_H #define _MLMETXRX_H @@ -12,7 +12,7 @@ void MLME_GetNextPacket(struct wbsoft_priv *adapter, struct wb35_descriptor *pDes); u8 MLMESendFrame(struct wbsoft_priv *adapter, - u8 * pMMPDU, u16 len, u8 DataType); + u8 *pMMPDU, u16 len, u8 DataType); void MLME_SendComplete(struct wbsoft_priv *adapter, u8 PacketID, -- cgit v1.2.3 From fa448c1f41712ac0f6640006582befb6296c19fc Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Thu, 25 Mar 2010 14:44:53 +0100 Subject: Staging: winbond: wb35reg.c Coding style fixes I fixed the problems reported by checkpatch.pl excetp for long lines, a couple of printks and some warnings about usb_free_urb(NULL). I checked for regressions with Dan Carpenters strip_whitespace.pl and diff and everything looks good. Generated .o is identical to master. This is a new patch against master where I fixed up a switch-statement after comments from Pavel Machek. Signed-off-by: Lars Lindley Acked-by: Pavel Machek Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wb35reg.c | 618 +++++++++++++++++++------------------- 1 file changed, 305 insertions(+), 313 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/wb35reg.c b/drivers/staging/winbond/wb35reg.c index 1b93547ff5bc..770722385eeb 100644 --- a/drivers/staging/winbond/wb35reg.c +++ b/drivers/staging/winbond/wb35reg.c @@ -6,60 +6,61 @@ extern void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency); -// true : read command process successfully -// false : register not support -// RegisterNo : start base -// pRegisterData : data point -// NumberOfData : number of register data -// Flag : AUTO_INCREMENT - RegisterNo will auto increment 4 -// NO_INCREMENT - Function will write data into the same register -unsigned char -Wb35Reg_BurstWrite(struct hw_data * pHwData, u16 RegisterNo, u32 * pRegisterData, u8 NumberOfData, u8 Flag) +/* + * true : read command process successfully + * false : register not support + * RegisterNo : start base + * pRegisterData : data point + * NumberOfData : number of register data + * Flag : AUTO_INCREMENT - RegisterNo will auto increment 4 + * NO_INCREMENT - Function will write data into the same register + */ +unsigned char Wb35Reg_BurstWrite(struct hw_data *pHwData, u16 RegisterNo, u32 *pRegisterData, u8 NumberOfData, u8 Flag) { - struct wb35_reg *reg = &pHwData->reg; - struct urb *urb = NULL; - struct wb35_reg_queue *reg_queue = NULL; - u16 UrbSize; - struct usb_ctrlrequest *dr; - u16 i, DataSize = NumberOfData*4; - - // Module shutdown + struct wb35_reg *reg = &pHwData->reg; + struct urb *urb = NULL; + struct wb35_reg_queue *reg_queue = NULL; + u16 UrbSize; + struct usb_ctrlrequest *dr; + u16 i, DataSize = NumberOfData * 4; + + /* Module shutdown */ if (pHwData->SurpriseRemove) return false; - // Trying to use burst write function if use new hardware + /* Trying to use burst write function if use new hardware */ UrbSize = sizeof(struct wb35_reg_queue) + DataSize + sizeof(struct usb_ctrlrequest); reg_queue = kzalloc(UrbSize, GFP_ATOMIC); urb = usb_alloc_urb(0, GFP_ATOMIC); - if( urb && reg_queue ) { - reg_queue->DIRECT = 2;// burst write register + if (urb && reg_queue) { + reg_queue->DIRECT = 2; /* burst write register */ reg_queue->INDEX = RegisterNo; reg_queue->pBuffer = (u32 *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue)); - memcpy( reg_queue->pBuffer, pRegisterData, DataSize ); - //the function for reversing register data from little endian to big endian - for( i=0; ipBuffer[i] = cpu_to_le32( reg_queue->pBuffer[i] ); + memcpy(reg_queue->pBuffer, pRegisterData, DataSize); + /* the function for reversing register data from little endian to big endian */ + for (i = 0; i < NumberOfData ; i++) + reg_queue->pBuffer[i] = cpu_to_le32(reg_queue->pBuffer[i]); dr = (struct usb_ctrlrequest *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue) + DataSize); dr->bRequestType = USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE; - dr->bRequest = 0x04; // USB or vendor-defined request code, burst mode - dr->wValue = cpu_to_le16( Flag ); // 0: Register number auto-increment, 1: No auto increment - dr->wIndex = cpu_to_le16( RegisterNo ); - dr->wLength = cpu_to_le16( DataSize ); + dr->bRequest = 0x04; /* USB or vendor-defined request code, burst mode */ + dr->wValue = cpu_to_le16(Flag); /* 0: Register number auto-increment, 1: No auto increment */ + dr->wIndex = cpu_to_le16(RegisterNo); + dr->wLength = cpu_to_le16(DataSize); reg_queue->Next = NULL; reg_queue->pUsbReq = dr; reg_queue->urb = urb; - spin_lock_irq( ®->EP0VM_spin_lock ); + spin_lock_irq(®->EP0VM_spin_lock); if (reg->reg_first == NULL) reg->reg_first = reg_queue; else reg->reg_last->Next = reg_queue; reg->reg_last = reg_queue; - spin_unlock_irq( ®->EP0VM_spin_lock ); + spin_unlock_irq(®->EP0VM_spin_lock); - // Start EP0VM + /* Start EP0VM */ Wb35Reg_EP0VM_start(pHwData); return true; @@ -73,8 +74,7 @@ Wb35Reg_BurstWrite(struct hw_data * pHwData, u16 RegisterNo, u32 * pRegisterData return false; } -void -Wb35Reg_Update(struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue) +void Wb35Reg_Update(struct hw_data *pHwData, u16 RegisterNo, u32 RegisterValue) { struct wb35_reg *reg = &pHwData->reg; switch (RegisterNo) { @@ -116,97 +116,96 @@ Wb35Reg_Update(struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue) } } -// true : read command process successfully -// false : register not support -unsigned char -Wb35Reg_WriteSync( struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue ) +/* + * true : read command process successfully + * false : register not support + */ +unsigned char Wb35Reg_WriteSync(struct hw_data *pHwData, u16 RegisterNo, u32 RegisterValue) { struct wb35_reg *reg = &pHwData->reg; int ret = -1; - // Module shutdown + /* Module shutdown */ if (pHwData->SurpriseRemove) return false; RegisterValue = cpu_to_le32(RegisterValue); - // update the register by send usb message------------------------------------ + /* update the register by send usb message */ reg->SyncIoPause = 1; - // 20060717.5 Wait until EP0VM stop + /* Wait until EP0VM stop */ while (reg->EP0vm_state != VM_STOP) msleep(10); - // Sync IoCallDriver + /* Sync IoCallDriver */ reg->EP0vm_state = VM_RUNNING; - ret = usb_control_msg( pHwData->WbUsb.udev, - usb_sndctrlpipe( pHwData->WbUsb.udev, 0 ), + ret = usb_control_msg(pHwData->WbUsb.udev, + usb_sndctrlpipe(pHwData->WbUsb.udev, 0), 0x03, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - 0x0,RegisterNo, &RegisterValue, 4, HZ*100 ); + 0x0, RegisterNo, &RegisterValue, 4, HZ * 100); reg->EP0vm_state = VM_STOP; reg->SyncIoPause = 0; Wb35Reg_EP0VM_start(pHwData); if (ret < 0) { - #ifdef _PE_REG_DUMP_ +#ifdef _PE_REG_DUMP_ printk("EP0 Write register usb message sending error\n"); - #endif - - pHwData->SurpriseRemove = 1; // 20060704.2 +#endif + pHwData->SurpriseRemove = 1; return false; } - return true; } -// true : read command process successfully -// false : register not support -unsigned char -Wb35Reg_Write( struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue ) +/* + * true : read command process successfully + * false : register not support + */ +unsigned char Wb35Reg_Write(struct hw_data *pHwData, u16 RegisterNo, u32 RegisterValue) { - struct wb35_reg *reg = &pHwData->reg; - struct usb_ctrlrequest *dr; - struct urb *urb = NULL; - struct wb35_reg_queue *reg_queue = NULL; - u16 UrbSize; - + struct wb35_reg *reg = &pHwData->reg; + struct usb_ctrlrequest *dr; + struct urb *urb = NULL; + struct wb35_reg_queue *reg_queue = NULL; + u16 UrbSize; - // Module shutdown + /* Module shutdown */ if (pHwData->SurpriseRemove) return false; - // update the register by send urb request------------------------------------ + /* update the register by send urb request */ UrbSize = sizeof(struct wb35_reg_queue) + sizeof(struct usb_ctrlrequest); reg_queue = kzalloc(UrbSize, GFP_ATOMIC); urb = usb_alloc_urb(0, GFP_ATOMIC); if (urb && reg_queue) { - reg_queue->DIRECT = 1;// burst write register + reg_queue->DIRECT = 1; /* burst write register */ reg_queue->INDEX = RegisterNo; reg_queue->VALUE = cpu_to_le32(RegisterValue); reg_queue->RESERVED_VALID = false; dr = (struct usb_ctrlrequest *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue)); - dr->bRequestType = USB_TYPE_VENDOR|USB_DIR_OUT |USB_RECIP_DEVICE; - dr->bRequest = 0x03; // USB or vendor-defined request code, burst mode + dr->bRequestType = USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE; + dr->bRequest = 0x03; /* USB or vendor-defined request code, burst mode */ dr->wValue = cpu_to_le16(0x0); dr->wIndex = cpu_to_le16(RegisterNo); dr->wLength = cpu_to_le16(4); - // Enter the sending queue + /* Enter the sending queue */ reg_queue->Next = NULL; reg_queue->pUsbReq = dr; reg_queue->urb = urb; - spin_lock_irq(®->EP0VM_spin_lock ); + spin_lock_irq(®->EP0VM_spin_lock); if (reg->reg_first == NULL) reg->reg_first = reg_queue; else reg->reg_last->Next = reg_queue; reg->reg_last = reg_queue; - spin_unlock_irq( ®->EP0VM_spin_lock ); + spin_unlock_irq(®->EP0VM_spin_lock); - // Start EP0VM + /* Start EP0VM */ Wb35Reg_EP0VM_start(pHwData); return true; @@ -218,56 +217,60 @@ Wb35Reg_Write( struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue ) } } -//This command will be executed with a user defined value. When it completes, -//this value is useful. For example, hal_set_current_channel will use it. -// true : read command process successfully -// false : register not support -unsigned char -Wb35Reg_WriteWithCallbackValue( struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue, - s8 *pValue, s8 Len) +/* + * This command will be executed with a user defined value. When it completes, + * this value is useful. For example, hal_set_current_channel will use it. + * true : read command process successfully + * false : register not support + */ +unsigned char Wb35Reg_WriteWithCallbackValue(struct hw_data *pHwData, + u16 RegisterNo, + u32 RegisterValue, + s8 *pValue, + s8 Len) { - struct wb35_reg *reg = &pHwData->reg; - struct usb_ctrlrequest *dr; - struct urb *urb = NULL; - struct wb35_reg_queue *reg_queue = NULL; - u16 UrbSize; + struct wb35_reg *reg = &pHwData->reg; + struct usb_ctrlrequest *dr; + struct urb *urb = NULL; + struct wb35_reg_queue *reg_queue = NULL; + u16 UrbSize; - // Module shutdown + /* Module shutdown */ if (pHwData->SurpriseRemove) return false; - // update the register by send urb request------------------------------------ + /* update the register by send urb request */ UrbSize = sizeof(struct wb35_reg_queue) + sizeof(struct usb_ctrlrequest); reg_queue = kzalloc(UrbSize, GFP_ATOMIC); urb = usb_alloc_urb(0, GFP_ATOMIC); if (urb && reg_queue) { - reg_queue->DIRECT = 1;// burst write register + reg_queue->DIRECT = 1; /* burst write register */ reg_queue->INDEX = RegisterNo; reg_queue->VALUE = cpu_to_le32(RegisterValue); - //NOTE : Users must guarantee the size of value will not exceed the buffer size. + /* NOTE : Users must guarantee the size of value will not exceed the buffer size. */ memcpy(reg_queue->RESERVED, pValue, Len); reg_queue->RESERVED_VALID = true; dr = (struct usb_ctrlrequest *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue)); - dr->bRequestType = USB_TYPE_VENDOR|USB_DIR_OUT |USB_RECIP_DEVICE; - dr->bRequest = 0x03; // USB or vendor-defined request code, burst mode + dr->bRequestType = USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE; + dr->bRequest = 0x03; /* USB or vendor-defined request code, burst mode */ dr->wValue = cpu_to_le16(0x0); dr->wIndex = cpu_to_le16(RegisterNo); dr->wLength = cpu_to_le16(4); - // Enter the sending queue + /* Enter the sending queue */ reg_queue->Next = NULL; reg_queue->pUsbReq = dr; reg_queue->urb = urb; - spin_lock_irq (®->EP0VM_spin_lock ); - if( reg->reg_first == NULL ) + spin_lock_irq(®->EP0VM_spin_lock); + if (reg->reg_first == NULL) reg->reg_first = reg_queue; else reg->reg_last->Next = reg_queue; reg->reg_last = reg_queue; - spin_unlock_irq ( ®->EP0VM_spin_lock ); + spin_unlock_irq(®->EP0VM_spin_lock); - // Start EP0VM + /* Start EP0VM */ Wb35Reg_EP0VM_start(pHwData); return true; } else { @@ -278,115 +281,114 @@ Wb35Reg_WriteWithCallbackValue( struct hw_data * pHwData, u16 RegisterNo, u32 Re } } -// true : read command process successfully -// false : register not support -// pRegisterValue : It must be a resident buffer due to asynchronous read register. -unsigned char -Wb35Reg_ReadSync( struct hw_data * pHwData, u16 RegisterNo, u32 * pRegisterValue ) +/* + * true : read command process successfully + * false : register not support + * pRegisterValue : It must be a resident buffer due to + * asynchronous read register. + */ +unsigned char Wb35Reg_ReadSync(struct hw_data *pHwData, u16 RegisterNo, u32 *pRegisterValue) { struct wb35_reg *reg = &pHwData->reg; - u32 * pltmp = pRegisterValue; - int ret = -1; + u32 *pltmp = pRegisterValue; + int ret = -1; - // Module shutdown + /* Module shutdown */ if (pHwData->SurpriseRemove) return false; - // Read the register by send usb message------------------------------------ - + /* Read the register by send usb message */ reg->SyncIoPause = 1; - // 20060717.5 Wait until EP0VM stop + /* Wait until EP0VM stop */ while (reg->EP0vm_state != VM_STOP) msleep(10); reg->EP0vm_state = VM_RUNNING; - ret = usb_control_msg( pHwData->WbUsb.udev, + ret = usb_control_msg(pHwData->WbUsb.udev, usb_rcvctrlpipe(pHwData->WbUsb.udev, 0), - 0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN, - 0x0, RegisterNo, pltmp, 4, HZ*100 ); + 0x01, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + 0x0, RegisterNo, pltmp, 4, HZ * 100); *pRegisterValue = cpu_to_le32(*pltmp); reg->EP0vm_state = VM_STOP; - Wb35Reg_Update( pHwData, RegisterNo, *pRegisterValue ); + Wb35Reg_Update(pHwData, RegisterNo, *pRegisterValue); reg->SyncIoPause = 0; - Wb35Reg_EP0VM_start( pHwData ); + Wb35Reg_EP0VM_start(pHwData); if (ret < 0) { - #ifdef _PE_REG_DUMP_ +#ifdef _PE_REG_DUMP_ printk("EP0 Read register usb message sending error\n"); - #endif - - pHwData->SurpriseRemove = 1; // 20060704.2 +#endif + pHwData->SurpriseRemove = 1; return false; } - return true; } -// true : read command process successfully -// false : register not support -// pRegisterValue : It must be a resident buffer due to asynchronous read register. -unsigned char -Wb35Reg_Read(struct hw_data * pHwData, u16 RegisterNo, u32 * pRegisterValue ) +/* + * true : read command process successfully + * false : register not support + * pRegisterValue : It must be a resident buffer due to + * asynchronous read register. + */ +unsigned char Wb35Reg_Read(struct hw_data *pHwData, u16 RegisterNo, u32 *pRegisterValue) { - struct wb35_reg *reg = &pHwData->reg; - struct usb_ctrlrequest * dr; - struct urb *urb; - struct wb35_reg_queue *reg_queue; - u16 UrbSize; + struct wb35_reg *reg = &pHwData->reg; + struct usb_ctrlrequest *dr; + struct urb *urb; + struct wb35_reg_queue *reg_queue; + u16 UrbSize; - // Module shutdown + /* Module shutdown */ if (pHwData->SurpriseRemove) return false; - // update the variable by send Urb to read register ------------------------------------ + /* update the variable by send Urb to read register */ UrbSize = sizeof(struct wb35_reg_queue) + sizeof(struct usb_ctrlrequest); reg_queue = kzalloc(UrbSize, GFP_ATOMIC); urb = usb_alloc_urb(0, GFP_ATOMIC); - if( urb && reg_queue ) - { - reg_queue->DIRECT = 0;// read register + if (urb && reg_queue) { + reg_queue->DIRECT = 0; /* read register */ reg_queue->INDEX = RegisterNo; reg_queue->pBuffer = pRegisterValue; dr = (struct usb_ctrlrequest *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue)); - dr->bRequestType = USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN; - dr->bRequest = 0x01; // USB or vendor-defined request code, burst mode + dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN; + dr->bRequest = 0x01; /* USB or vendor-defined request code, burst mode */ dr->wValue = cpu_to_le16(0x0); - dr->wIndex = cpu_to_le16 (RegisterNo); - dr->wLength = cpu_to_le16 (4); + dr->wIndex = cpu_to_le16(RegisterNo); + dr->wLength = cpu_to_le16(4); - // Enter the sending queue + /* Enter the sending queue */ reg_queue->Next = NULL; reg_queue->pUsbReq = dr; reg_queue->urb = urb; - spin_lock_irq ( ®->EP0VM_spin_lock ); - if( reg->reg_first == NULL ) + spin_lock_irq(®->EP0VM_spin_lock); + if (reg->reg_first == NULL) reg->reg_first = reg_queue; else reg->reg_last->Next = reg_queue; reg->reg_last = reg_queue; - spin_unlock_irq( ®->EP0VM_spin_lock ); + spin_unlock_irq(®->EP0VM_spin_lock); - // Start EP0VM - Wb35Reg_EP0VM_start( pHwData ); + /* Start EP0VM */ + Wb35Reg_EP0VM_start(pHwData); return true; } else { if (urb) - usb_free_urb( urb ); + usb_free_urb(urb); kfree(reg_queue); return false; } } -void -Wb35Reg_EP0VM_start( struct hw_data * pHwData ) +void Wb35Reg_EP0VM_start(struct hw_data *pHwData) { struct wb35_reg *reg = &pHwData->reg; @@ -397,15 +399,14 @@ Wb35Reg_EP0VM_start( struct hw_data * pHwData ) atomic_dec(®->RegFireCount); } -void -Wb35Reg_EP0VM(struct hw_data * pHwData ) +void Wb35Reg_EP0VM(struct hw_data *pHwData) { - struct wb35_reg *reg = &pHwData->reg; - struct urb *urb; - struct usb_ctrlrequest *dr; - u32 * pBuffer; + struct wb35_reg *reg = &pHwData->reg; + struct urb *urb; + struct usb_ctrlrequest *dr; + u32 *pBuffer; int ret = -1; - struct wb35_reg_queue *reg_queue; + struct wb35_reg_queue *reg_queue; if (reg->SyncIoPause) @@ -414,27 +415,27 @@ Wb35Reg_EP0VM(struct hw_data * pHwData ) if (pHwData->SurpriseRemove) goto cleanup; - // Get the register data and send to USB through Irp - spin_lock_irq( ®->EP0VM_spin_lock ); + /* Get the register data and send to USB through Irp */ + spin_lock_irq(®->EP0VM_spin_lock); reg_queue = reg->reg_first; - spin_unlock_irq( ®->EP0VM_spin_lock ); + spin_unlock_irq(®->EP0VM_spin_lock); if (!reg_queue) goto cleanup; - // Get an Urb, send it + /* Get an Urb, send it */ urb = (struct urb *)reg_queue->urb; dr = reg_queue->pUsbReq; urb = reg_queue->urb; pBuffer = reg_queue->pBuffer; - if (reg_queue->DIRECT == 1) // output + if (reg_queue->DIRECT == 1) /* output */ pBuffer = ®_queue->VALUE; - usb_fill_control_urb( urb, pHwData->WbUsb.udev, - REG_DIRECTION(pHwData->WbUsb.udev,reg_queue), - (u8 *)dr,pBuffer,cpu_to_le16(dr->wLength), - Wb35Reg_EP0VM_complete, (void*)pHwData); + usb_fill_control_urb(urb, pHwData->WbUsb.udev, + REG_DIRECTION(pHwData->WbUsb.udev, reg_queue), + (u8 *)dr, pBuffer, cpu_to_le16(dr->wLength), + Wb35Reg_EP0VM_complete, (void *)pHwData); reg->EP0vm_state = VM_RUNNING; @@ -446,7 +447,6 @@ Wb35Reg_EP0VM(struct hw_data * pHwData ) #endif goto cleanup; } - return; cleanup: @@ -455,29 +455,28 @@ Wb35Reg_EP0VM(struct hw_data * pHwData ) } -void -Wb35Reg_EP0VM_complete(struct urb *urb) +void Wb35Reg_EP0VM_complete(struct urb *urb) { - struct hw_data * pHwData = (struct hw_data *)urb->context; - struct wb35_reg *reg = &pHwData->reg; - struct wb35_reg_queue *reg_queue; + struct hw_data *pHwData = (struct hw_data *)urb->context; + struct wb35_reg *reg = &pHwData->reg; + struct wb35_reg_queue *reg_queue; - // Variable setting + /* Variable setting */ reg->EP0vm_state = VM_COMPLETED; reg->EP0VM_status = urb->status; - if (pHwData->SurpriseRemove) { // Let WbWlanHalt to handle surprise remove + if (pHwData->SurpriseRemove) { /* Let WbWlanHalt to handle surprise remove */ reg->EP0vm_state = VM_STOP; atomic_dec(®->RegFireCount); } else { - // Complete to send, remove the URB from the first - spin_lock_irq( ®->EP0VM_spin_lock ); + /* Complete to send, remove the URB from the first */ + spin_lock_irq(®->EP0VM_spin_lock); reg_queue = reg->reg_first; if (reg_queue == reg->reg_last) reg->reg_last = NULL; reg->reg_first = reg->reg_first->Next; - spin_unlock_irq( ®->EP0VM_spin_lock ); + spin_unlock_irq(®->EP0VM_spin_lock); if (reg->EP0VM_status) { #ifdef _PE_REG_DUMP_ @@ -486,37 +485,35 @@ Wb35Reg_EP0VM_complete(struct urb *urb) reg->EP0vm_state = VM_STOP; pHwData->SurpriseRemove = 1; } else { - // Success. Update the result + /* Success. Update the result */ - // Start the next send + /* Start the next send */ Wb35Reg_EP0VM(pHwData); } - kfree(reg_queue); + kfree(reg_queue); } usb_free_urb(urb); } -void -Wb35Reg_destroy(struct hw_data * pHwData) +void Wb35Reg_destroy(struct hw_data *pHwData) { - struct wb35_reg *reg = &pHwData->reg; - struct urb *urb; - struct wb35_reg_queue *reg_queue; - + struct wb35_reg *reg = &pHwData->reg; + struct urb *urb; + struct wb35_reg_queue *reg_queue; Uxx_power_off_procedure(pHwData); - // Wait for Reg operation completed + /* Wait for Reg operation completed */ do { - msleep(10); // Delay for waiting function enter 940623.1.a + msleep(10); /* Delay for waiting function enter */ } while (reg->EP0vm_state != VM_STOP); - msleep(10); // Delay for waiting function enter 940623.1.b + msleep(10); /* Delay for waiting function enter */ - // Release all the data in RegQueue - spin_lock_irq( ®->EP0VM_spin_lock ); + /* Release all the data in RegQueue */ + spin_lock_irq(®->EP0VM_spin_lock); reg_queue = reg->reg_first; while (reg_queue) { if (reg_queue == reg->reg_last) @@ -524,84 +521,88 @@ Wb35Reg_destroy(struct hw_data * pHwData) reg->reg_first = reg->reg_first->Next; urb = reg_queue->urb; - spin_unlock_irq( ®->EP0VM_spin_lock ); + spin_unlock_irq(®->EP0VM_spin_lock); if (urb) { usb_free_urb(urb); kfree(reg_queue); } else { - #ifdef _PE_REG_DUMP_ +#ifdef _PE_REG_DUMP_ printk("EP0 queue release error\n"); - #endif +#endif } - spin_lock_irq( ®->EP0VM_spin_lock ); + spin_lock_irq(®->EP0VM_spin_lock); reg_queue = reg->reg_first; } - spin_unlock_irq( ®->EP0VM_spin_lock ); + spin_unlock_irq(®->EP0VM_spin_lock); } -//==================================================================================== -// The function can be run in passive-level only. -//==================================================================================== -unsigned char Wb35Reg_initial(struct hw_data * pHwData) +/* + * ======================================================================= + * The function can be run in passive-level only. + * ========================================================================= + */ +unsigned char Wb35Reg_initial(struct hw_data *pHwData) { - struct wb35_reg *reg=&pHwData->reg; + struct wb35_reg *reg = &pHwData->reg; u32 ltmp; u32 SoftwareSet, VCO_trim, TxVga, Region_ScanInterval; - // Spin lock is acquired for read and write IRP command - spin_lock_init( ®->EP0VM_spin_lock ); - - // Getting RF module type from EEPROM ------------------------------------ - Wb35Reg_WriteSync( pHwData, 0x03b4, 0x080d0000 ); // Start EEPROM access + Read + address(0x0d) - Wb35Reg_ReadSync( pHwData, 0x03b4, <mp ); - - //Update RF module type and determine the PHY type by inf or EEPROM - reg->EEPROMPhyType = (u8)( ltmp & 0xff ); - // 0 V MAX2825, 1 V MAX2827, 2 V MAX2828, 3 V MAX2829 - // 16V AL2230, 17 - AL7230, 18 - AL2230S - // 32 Reserved - // 33 - W89RF242(TxVGA 0~19), 34 - W89RF242(TxVGA 0~34) + /* Spin lock is acquired for read and write IRP command */ + spin_lock_init(®->EP0VM_spin_lock); + + /* Getting RF module type from EEPROM */ + Wb35Reg_WriteSync(pHwData, 0x03b4, 0x080d0000); /* Start EEPROM access + Read + address(0x0d) */ + Wb35Reg_ReadSync(pHwData, 0x03b4, <mp); + + /* Update RF module type and determine the PHY type by inf or EEPROM */ + reg->EEPROMPhyType = (u8)(ltmp & 0xff); + /* + * 0 V MAX2825, 1 V MAX2827, 2 V MAX2828, 3 V MAX2829 + * 16V AL2230, 17 - AL7230, 18 - AL2230S + * 32 Reserved + * 33 - W89RF242(TxVGA 0~19), 34 - W89RF242(TxVGA 0~34) + */ if (reg->EEPROMPhyType != RF_DECIDE_BY_INF) { - if( (reg->EEPROMPhyType == RF_MAXIM_2825) || + if ((reg->EEPROMPhyType == RF_MAXIM_2825) || (reg->EEPROMPhyType == RF_MAXIM_2827) || (reg->EEPROMPhyType == RF_MAXIM_2828) || (reg->EEPROMPhyType == RF_MAXIM_2829) || (reg->EEPROMPhyType == RF_MAXIM_V1) || (reg->EEPROMPhyType == RF_AIROHA_2230) || - (reg->EEPROMPhyType == RF_AIROHA_2230S) || + (reg->EEPROMPhyType == RF_AIROHA_2230S) || (reg->EEPROMPhyType == RF_AIROHA_7230) || - (reg->EEPROMPhyType == RF_WB_242) || + (reg->EEPROMPhyType == RF_WB_242) || (reg->EEPROMPhyType == RF_WB_242_1)) pHwData->phy_type = reg->EEPROMPhyType; } - // Power On procedure running. The relative parameter will be set according to phy_type - Uxx_power_on_procedure( pHwData ); + /* Power On procedure running. The relative parameter will be set according to phy_type */ + Uxx_power_on_procedure(pHwData); - // Reading MAC address - Uxx_ReadEthernetAddress( pHwData ); + /* Reading MAC address */ + Uxx_ReadEthernetAddress(pHwData); - // Read VCO trim for RF parameter - Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08200000 ); - Wb35Reg_ReadSync( pHwData, 0x03b4, &VCO_trim ); + /* Read VCO trim for RF parameter */ + Wb35Reg_WriteSync(pHwData, 0x03b4, 0x08200000); + Wb35Reg_ReadSync(pHwData, 0x03b4, &VCO_trim); - // Read Antenna On/Off of software flag - Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08210000 ); - Wb35Reg_ReadSync( pHwData, 0x03b4, &SoftwareSet ); + /* Read Antenna On/Off of software flag */ + Wb35Reg_WriteSync(pHwData, 0x03b4, 0x08210000); + Wb35Reg_ReadSync(pHwData, 0x03b4, &SoftwareSet); - // Read TXVGA - Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08100000 ); - Wb35Reg_ReadSync( pHwData, 0x03b4, &TxVga ); + /* Read TXVGA */ + Wb35Reg_WriteSync(pHwData, 0x03b4, 0x08100000); + Wb35Reg_ReadSync(pHwData, 0x03b4, &TxVga); - // Get Scan interval setting from EEPROM offset 0x1c - Wb35Reg_WriteSync( pHwData, 0x03b4, 0x081d0000 ); - Wb35Reg_ReadSync( pHwData, 0x03b4, &Region_ScanInterval ); + /* Get Scan interval setting from EEPROM offset 0x1c */ + Wb35Reg_WriteSync(pHwData, 0x03b4, 0x081d0000); + Wb35Reg_ReadSync(pHwData, 0x03b4, &Region_ScanInterval); - // Update Ethernet address - memcpy( pHwData->CurrentMacAddress, pHwData->PermanentMacAddress, ETH_ALEN ); + /* Update Ethernet address */ + memcpy(pHwData->CurrentMacAddress, pHwData->PermanentMacAddress, ETH_ALEN); - // Update software variable + /* Update software variable */ pHwData->SoftwareSet = (u16)(SoftwareSet & 0xffff); TxVga &= 0x000000ff; pHwData->PowerIndexFromEEPROM = (u8)TxVga; @@ -609,22 +610,22 @@ unsigned char Wb35Reg_initial(struct hw_data * pHwData) if (pHwData->VCO_trim == 0xff) pHwData->VCO_trim = 0x28; - reg->EEPROMRegion = (u8)(Region_ScanInterval>>8); // 20060720 - if( reg->EEPROMRegion<1 || reg->EEPROMRegion>6 ) + reg->EEPROMRegion = (u8)(Region_ScanInterval >> 8); + if (reg->EEPROMRegion < 1 || reg->EEPROMRegion > 6) reg->EEPROMRegion = REGION_AUTO; - //For Get Tx VGA from EEPROM 20060315.5 move here - GetTxVgaFromEEPROM( pHwData ); + /* For Get Tx VGA from EEPROM */ + GetTxVgaFromEEPROM(pHwData); - // Set Scan Interval + /* Set Scan Interval */ pHwData->Scan_Interval = (u8)(Region_ScanInterval & 0xff) * 10; - if ((pHwData->Scan_Interval == 2550) || (pHwData->Scan_Interval < 10)) // Is default setting 0xff * 10 + if ((pHwData->Scan_Interval == 2550) || (pHwData->Scan_Interval < 10)) /* Is default setting 0xff * 10 */ pHwData->Scan_Interval = SCAN_MAX_CHNL_TIME; - // Initial register + /* Initial register */ RFSynthesizer_initial(pHwData); - BBProcessor_initial(pHwData); // Async write, must wait until complete + BBProcessor_initial(pHwData); /* Async write, must wait until complete */ Wb35Reg_phy_calibration(pHwData); @@ -634,113 +635,104 @@ unsigned char Wb35Reg_initial(struct hw_data * pHwData) if (pHwData->SurpriseRemove) return false; else - return true; // Initial fail + return true; /* Initial fail */ } -//=================================================================================== -// CardComputeCrc -- -// -// Description: -// Runs the AUTODIN II CRC algorithm on buffer Buffer of length, Length. -// -// Arguments: -// Buffer - the input buffer -// Length - the length of Buffer -// -// Return Value: -// The 32-bit CRC value. -// -// Note: -// This is adapted from the comments in the assembly language -// version in _GENREQ.ASM of the DWB NE1000/2000 driver. -//================================================================================== -u32 -CardComputeCrc(u8 * Buffer, u32 Length) +/* + * ================================================================ + * CardComputeCrc -- + * + * Description: + * Runs the AUTODIN II CRC algorithm on buffer Buffer of length, Length. + * + * Arguments: + * Buffer - the input buffer + * Length - the length of Buffer + * + * Return Value: + * The 32-bit CRC value. + * =================================================================== + */ +u32 CardComputeCrc(u8 *Buffer, u32 Length) { - u32 Crc, Carry; - u32 i, j; - u8 CurByte; - - Crc = 0xffffffff; - - for (i = 0; i < Length; i++) { - - CurByte = Buffer[i]; - - for (j = 0; j < 8; j++) { - - Carry = ((Crc & 0x80000000) ? 1 : 0) ^ (CurByte & 0x01); - Crc <<= 1; - CurByte >>= 1; - - if (Carry) { - Crc =(Crc ^ 0x04c11db6) | Carry; - } - } - } - - return Crc; + u32 Crc, Carry; + u32 i, j; + u8 CurByte; + + Crc = 0xffffffff; + + for (i = 0; i < Length; i++) { + CurByte = Buffer[i]; + for (j = 0; j < 8; j++) { + Carry = ((Crc & 0x80000000) ? 1 : 0) ^ (CurByte & 0x01); + Crc <<= 1; + CurByte >>= 1; + if (Carry) + Crc = (Crc ^ 0x04c11db6) | Carry; + } + } + return Crc; } -//================================================================== -// BitReverse -- -// Reverse the bits in the input argument, dwData, which is -// regarded as a string of bits with the length, DataLength. -// -// Arguments: -// dwData : -// DataLength : -// -// Return: -// The converted value. -//================================================================== -u32 BitReverse( u32 dwData, u32 DataLength) +/* + * ================================================================== + * BitReverse -- + * Reverse the bits in the input argument, dwData, which is + * regarded as a string of bits with the length, DataLength. + * + * Arguments: + * dwData : + * DataLength : + * + * Return: + * The converted value. + * ================================================================== + */ +u32 BitReverse(u32 dwData, u32 DataLength) { - u32 HalfLength, i, j; - u32 BitA, BitB; + u32 HalfLength, i, j; + u32 BitA, BitB; - if ( DataLength <= 0) return 0; // No conversion is done. + if (DataLength <= 0) + return 0; /* No conversion is done. */ dwData = dwData & (0xffffffff >> (32 - DataLength)); HalfLength = DataLength / 2; - for ( i = 0, j = DataLength-1 ; i < HalfLength; i++, j--) - { - BitA = GetBit( dwData, i); - BitB = GetBit( dwData, j); + for (i = 0, j = DataLength - 1; i < HalfLength; i++, j--) { + BitA = GetBit(dwData, i); + BitB = GetBit(dwData, j); if (BitA && !BitB) { - dwData = ClearBit( dwData, i); - dwData = SetBit( dwData, j); + dwData = ClearBit(dwData, i); + dwData = SetBit(dwData, j); } else if (!BitA && BitB) { - dwData = SetBit( dwData, i); - dwData = ClearBit( dwData, j); - } else - { - // Do nothing since these two bits are of the save values. + dwData = SetBit(dwData, i); + dwData = ClearBit(dwData, j); + } else { + /* Do nothing since these two bits are of the save values. */ } } - return dwData; } -void Wb35Reg_phy_calibration( struct hw_data * pHwData ) +void Wb35Reg_phy_calibration(struct hw_data *pHwData) { - u32 BB3c, BB54; + u32 BB3c, BB54; if ((pHwData->phy_type == RF_WB_242) || (pHwData->phy_type == RF_WB_242_1)) { - phy_calibration_winbond ( pHwData, 2412 ); // Sync operation - Wb35Reg_ReadSync( pHwData, 0x103c, &BB3c ); - Wb35Reg_ReadSync( pHwData, 0x1054, &BB54 ); + phy_calibration_winbond(pHwData, 2412); /* Sync operation */ + Wb35Reg_ReadSync(pHwData, 0x103c, &BB3c); + Wb35Reg_ReadSync(pHwData, 0x1054, &BB54); pHwData->BB3c_cal = BB3c; pHwData->BB54_cal = BB54; RFSynthesizer_initial(pHwData); - BBProcessor_initial(pHwData); // Async operation + BBProcessor_initial(pHwData); /* Async operation */ - Wb35Reg_WriteSync( pHwData, 0x103c, BB3c ); - Wb35Reg_WriteSync( pHwData, 0x1054, BB54 ); + Wb35Reg_WriteSync(pHwData, 0x103c, BB3c); + Wb35Reg_WriteSync(pHwData, 0x1054, BB54); } } -- cgit v1.2.3 From 42cb2945a9fbfb1602e50c802f6b379244820a6a Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Sun, 28 Mar 2010 08:57:55 +0200 Subject: Staging: winbond: wb35tx_f.h Coding style fixes. I fixed the checkpatch.pl problems and converted the function arguments away from CamelCase and hungarian notation. Signed-off-by: Lars Lindley Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wb35tx_f.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/wb35tx_f.h b/drivers/staging/winbond/wb35tx_f.h index a7af9cbe202a..1d3b515f83bc 100644 --- a/drivers/staging/winbond/wb35tx_f.h +++ b/drivers/staging/winbond/wb35tx_f.h @@ -4,18 +4,20 @@ #include "core.h" #include "wbhal_f.h" -//==================================== -// Interface function declare -//==================================== -unsigned char Wb35Tx_initial( struct hw_data * pHwData ); -void Wb35Tx_destroy( struct hw_data * pHwData ); -unsigned char Wb35Tx_get_tx_buffer( struct hw_data * pHwData, u8 **pBuffer ); +/* + * ==================================== + * Interface function declare + * ==================================== + */ +unsigned char Wb35Tx_initial(struct hw_data *hw_data); +void Wb35Tx_destroy(struct hw_data *hw_data); +unsigned char Wb35Tx_get_tx_buffer(struct hw_data *hw_data, u8 **buffer); void Wb35Tx_EP2VM_start(struct wbsoft_priv *adapter); void Wb35Tx_start(struct wbsoft_priv *adapter); -void Wb35Tx_stop( struct hw_data * pHwData ); +void Wb35Tx_stop(struct hw_data *hw_data); -void Wb35Tx_CurrentTime(struct wbsoft_priv *adapter, u32 TimeCount); +void Wb35Tx_CurrentTime(struct wbsoft_priv *adapter, u32 time_count); #endif -- cgit v1.2.3 From 6112fd6ebbdc8901b40b43940908fa09f8af7cc4 Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Sun, 28 Mar 2010 08:38:57 +0200 Subject: Staging: winbond: wb35rx.c Coding style fixes v2. New patch that fixes an unclear comment too. I fixed checkpatch issues except for long lines and printk:s. I also removed version comments and the () in a return statement. Generated .o is identical to master and i checked the code with Dan Carpenters strip_whitespace.pl and diff. Signed-off-by: Lars Lindley Acked-by: Dan Carpenter Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wb35rx.c | 258 +++++++++++++++++++-------------------- 1 file changed, 123 insertions(+), 135 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/wb35rx.c b/drivers/staging/winbond/wb35rx.c index d7b57e62db08..efe82b141c10 100644 --- a/drivers/staging/winbond/wb35rx.c +++ b/drivers/staging/winbond/wb35rx.c @@ -1,13 +1,15 @@ -//============================================================================ -// Copyright (c) 1996-2002 Winbond Electronic Corporation -// -// Module Name: -// Wb35Rx.c -// -// Abstract: -// Processing the Rx message from down layer -// -//============================================================================ +/* + * ============================================================================ + * Copyright (c) 1996-2002 Winbond Electronic Corporation + * + * Module Name: + * Wb35Rx.c + * + * Abstract: + * Processing the Rx message from down layer + * + * ============================================================================ + */ #include #include @@ -30,16 +32,7 @@ static void packet_came(struct ieee80211_hw *hw, char *pRxBufferAddress, int Pac return; } - memcpy(skb_put(skb, PacketSize), - pRxBufferAddress, - PacketSize); - -/* - rx_status.rate = 10; - rx_status.channel = 1; - rx_status.freq = 12345; - rx_status.phymode = MODE_IEEE80211B; -*/ + memcpy(skb_put(skb, PacketSize), pRxBufferAddress, PacketSize); memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); ieee80211_rx_irqsafe(hw, skb); @@ -47,7 +40,7 @@ static void packet_came(struct ieee80211_hw *hw, char *pRxBufferAddress, int Pac static void Wb35Rx_adjust(struct wb35_descriptor *pRxDes) { - u32 * pRxBufferAddress; + u32 *pRxBufferAddress; u32 DecryptionMethod; u32 i; u16 BufferSize; @@ -56,81 +49,80 @@ static void Wb35Rx_adjust(struct wb35_descriptor *pRxDes) pRxBufferAddress = pRxDes->buffer_address[0]; BufferSize = pRxDes->buffer_size[0]; - // Adjust the last part of data. Only data left - BufferSize -= 4; // For CRC-32 + /* Adjust the last part of data. Only data left */ + BufferSize -= 4; /* For CRC-32 */ if (DecryptionMethod) BufferSize -= 4; - if (DecryptionMethod == 3) // For CCMP + if (DecryptionMethod == 3) /* For CCMP */ BufferSize -= 4; - // Adjust the IV field which after 802.11 header and ICV field. - if (DecryptionMethod == 1) // For WEP - { - for( i=6; i>0; i-- ) - pRxBufferAddress[i] = pRxBufferAddress[i-1]; + /* Adjust the IV field which after 802.11 header and ICV field. */ + if (DecryptionMethod == 1) { /* For WEP */ + for (i = 6; i > 0; i--) + pRxBufferAddress[i] = pRxBufferAddress[i - 1]; pRxDes->buffer_address[0] = pRxBufferAddress + 1; - BufferSize -= 4; // 4 byte for IV - } - else if( DecryptionMethod ) // For TKIP and CCMP - { - for (i=7; i>1; i--) - pRxBufferAddress[i] = pRxBufferAddress[i-2]; - pRxDes->buffer_address[0] = pRxBufferAddress + 2;//Update the descriptor, shift 8 byte - BufferSize -= 8; // 8 byte for IV + ICV + BufferSize -= 4; /* 4 byte for IV */ + } else if (DecryptionMethod) { /* For TKIP and CCMP */ + for (i = 7; i > 1; i--) + pRxBufferAddress[i] = pRxBufferAddress[i - 2]; + pRxDes->buffer_address[0] = pRxBufferAddress + 2; /* Update the descriptor, shift 8 byte */ + BufferSize -= 8; /* 8 byte for IV + ICV */ } pRxDes->buffer_size[0] = BufferSize; } static u16 Wb35Rx_indicate(struct ieee80211_hw *hw) { - struct wbsoft_priv *priv = hw->priv; - struct hw_data * pHwData = &priv->sHwData; + struct wbsoft_priv *priv = hw->priv; + struct hw_data *pHwData = &priv->sHwData; struct wb35_descriptor RxDes; - struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; - u8 * pRxBufferAddress; - u16 PacketSize; - u16 stmp, BufferSize, stmp2 = 0; - u32 RxBufferId; + struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; + u8 *pRxBufferAddress; + u16 PacketSize; + u16 stmp, BufferSize, stmp2 = 0; + u32 RxBufferId; - // Only one thread be allowed to run into the following + /* Only one thread be allowed to run into the following */ do { RxBufferId = pWb35Rx->RxProcessIndex; - if (pWb35Rx->RxOwner[ RxBufferId ]) //Owner by VM + if (pWb35Rx->RxOwner[RxBufferId]) /* Owner by VM */ break; pWb35Rx->RxProcessIndex++; pWb35Rx->RxProcessIndex %= MAX_USB_RX_BUFFER_NUMBER; pRxBufferAddress = pWb35Rx->pDRx; - BufferSize = pWb35Rx->RxBufferSize[ RxBufferId ]; + BufferSize = pWb35Rx->RxBufferSize[RxBufferId]; - // Parse the bulkin buffer + /* Parse the bulkin buffer */ while (BufferSize >= 4) { - if ((cpu_to_le32(*(u32 *)pRxBufferAddress) & 0x0fffffff) == RX_END_TAG) //Is ending? 921002.9.a + if ((cpu_to_le32(*(u32 *)pRxBufferAddress) & 0x0fffffff) == RX_END_TAG) /* Is ending? */ break; - // Get the R00 R01 first + /* Get the R00 R01 first */ RxDes.R00.value = le32_to_cpu(*(u32 *)pRxBufferAddress); PacketSize = (u16)RxDes.R00.R00_receive_byte_count; - RxDes.R01.value = le32_to_cpu(*((u32 *)(pRxBufferAddress+4))); - // For new DMA 4k + RxDes.R01.value = le32_to_cpu(*((u32 *)(pRxBufferAddress + 4))); + /* For new DMA 4k */ if ((PacketSize & 0x03) > 0) PacketSize -= 4; - // Basic check for Rx length. Is length valid? + /* Basic check for Rx length. Is length valid? */ if (PacketSize > MAX_PACKET_SIZE) { - #ifdef _PE_RX_DUMP_ +#ifdef _PE_RX_DUMP_ printk("Serious ERROR : Rx data size too long, size =%d\n", PacketSize); - #endif +#endif pWb35Rx->EP3vm_state = VM_STOP; pWb35Rx->Ep3ErrorCount2++; break; } - // Start to process Rx buffer -// RxDes.Descriptor_ID = RxBufferId; // Due to synchronous indicate, the field doesn't necessary to use. - BufferSize -= 8; //subtract 8 byte for 35's USB header length + /* + * Wb35Rx_indicate() is called synchronously so it isn't + * necessary to set "RxDes.Desctriptor_ID = RxBufferID;" + */ + BufferSize -= 8; /* subtract 8 byte for 35's USB header length */ pRxBufferAddress += 8; RxDes.buffer_address[0] = pRxBufferAddress; @@ -142,18 +134,17 @@ static u16 Wb35Rx_indicate(struct ieee80211_hw *hw) packet_came(hw, pRxBufferAddress, PacketSize); - // Move RxBuffer point to the next + /* Move RxBuffer point to the next */ stmp = PacketSize + 3; - stmp &= ~0x03; // 4n alignment + stmp &= ~0x03; /* 4n alignment */ pRxBufferAddress += stmp; BufferSize -= stmp; stmp2 += stmp; } - // Reclaim resource - pWb35Rx->RxOwner[ RxBufferId ] = 1; + /* Reclaim resource */ + pWb35Rx->RxOwner[RxBufferId] = 1; } while (true); - return stmp2; } @@ -161,112 +152,110 @@ static void Wb35Rx(struct ieee80211_hw *hw); static void Wb35Rx_Complete(struct urb *urb) { - struct ieee80211_hw *hw = urb->context; - struct wbsoft_priv *priv = hw->priv; - struct hw_data * pHwData = &priv->sHwData; - struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; - u8 * pRxBufferAddress; - u32 SizeCheck; - u16 BulkLength; - u32 RxBufferId; - R00_DESCRIPTOR R00; - - // Variable setting + struct ieee80211_hw *hw = urb->context; + struct wbsoft_priv *priv = hw->priv; + struct hw_data *pHwData = &priv->sHwData; + struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; + u8 *pRxBufferAddress; + u32 SizeCheck; + u16 BulkLength; + u32 RxBufferId; + R00_DESCRIPTOR R00; + + /* Variable setting */ pWb35Rx->EP3vm_state = VM_COMPLETED; - pWb35Rx->EP3VM_status = urb->status;//Store the last result of Irp + pWb35Rx->EP3VM_status = urb->status; /* Store the last result of Irp */ RxBufferId = pWb35Rx->CurrentRxBufferId; pRxBufferAddress = pWb35Rx->pDRx; BulkLength = (u16)urb->actual_length; - // The IRP is completed + /* The IRP is completed */ pWb35Rx->EP3vm_state = VM_COMPLETED; - if (pHwData->SurpriseRemove || pHwData->HwStop) // Must be here, or RxBufferId is invalid + if (pHwData->SurpriseRemove || pHwData->HwStop) /* Must be here, or RxBufferId is invalid */ goto error; if (pWb35Rx->rx_halt) goto error; - // Start to process the data only in successful condition - pWb35Rx->RxOwner[ RxBufferId ] = 0; // Set the owner to driver + /* Start to process the data only in successful condition */ + pWb35Rx->RxOwner[RxBufferId] = 0; /* Set the owner to driver */ R00.value = le32_to_cpu(*(u32 *)pRxBufferAddress); - // The URB is completed, check the result + /* The URB is completed, check the result */ if (pWb35Rx->EP3VM_status != 0) { - #ifdef _PE_USB_STATE_DUMP_ +#ifdef _PE_USB_STATE_DUMP_ printk("EP3 IoCompleteRoutine return error\n"); - #endif +#endif pWb35Rx->EP3vm_state = VM_STOP; goto error; } - // 20060220 For recovering. check if operating in single USB mode + /* For recovering. check if operating in single USB mode */ if (!HAL_USB_MODE_BURST(pHwData)) { - SizeCheck = R00.R00_receive_byte_count; //20060926 anson's endian + SizeCheck = R00.R00_receive_byte_count; if ((SizeCheck & 0x03) > 0) SizeCheck -= 4; SizeCheck = (SizeCheck + 3) & ~0x03; - SizeCheck += 12; // 8 + 4 badbeef + SizeCheck += 12; /* 8 + 4 badbeef */ if ((BulkLength > 1600) || (SizeCheck > 1600) || (BulkLength != SizeCheck) || - (BulkLength == 0)) { // Add for fail Urb + (BulkLength == 0)) { /* Add for fail Urb */ pWb35Rx->EP3vm_state = VM_STOP; pWb35Rx->Ep3ErrorCount2++; } } - // Indicating the receiving data + /* Indicating the receiving data */ pWb35Rx->ByteReceived += BulkLength; - pWb35Rx->RxBufferSize[ RxBufferId ] = BulkLength; + pWb35Rx->RxBufferSize[RxBufferId] = BulkLength; - if (!pWb35Rx->RxOwner[ RxBufferId ]) + if (!pWb35Rx->RxOwner[RxBufferId]) Wb35Rx_indicate(hw); kfree(pWb35Rx->pDRx); - // Do the next receive + /* Do the next receive */ Wb35Rx(hw); return; error: - pWb35Rx->RxOwner[ RxBufferId ] = 1; // Set the owner to hardware + pWb35Rx->RxOwner[RxBufferId] = 1; /* Set the owner to hardware */ atomic_dec(&pWb35Rx->RxFireCounter); pWb35Rx->EP3vm_state = VM_STOP; } -// This function cannot reentrain +/* This function cannot reentrain */ static void Wb35Rx(struct ieee80211_hw *hw) { - struct wbsoft_priv *priv = hw->priv; - struct hw_data * pHwData = &priv->sHwData; - struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; - u8 * pRxBufferAddress; - struct urb *urb = pWb35Rx->RxUrb; - int retv; - u32 RxBufferId; - - // - // Issuing URB - // + struct wbsoft_priv *priv = hw->priv; + struct hw_data *pHwData = &priv->sHwData; + struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; + u8 *pRxBufferAddress; + struct urb *urb = pWb35Rx->RxUrb; + int retv; + u32 RxBufferId; + + /* Issuing URB */ if (pHwData->SurpriseRemove || pHwData->HwStop) goto error; if (pWb35Rx->rx_halt) goto error; - // Get RxBuffer's ID + /* Get RxBuffer's ID */ RxBufferId = pWb35Rx->RxBufferId; if (!pWb35Rx->RxOwner[RxBufferId]) { - // It's impossible to run here. - #ifdef _PE_RX_DUMP_ + /* It's impossible to run here. */ +#ifdef _PE_RX_DUMP_ printk("Rx driver fifo unavailable\n"); - #endif +#endif goto error; } - // Update buffer point, then start to bulkin the data from USB + /* Update buffer point, then start to bulkin the data from USB */ pWb35Rx->RxBufferId++; pWb35Rx->RxBufferId %= MAX_USB_RX_BUFFER_NUMBER; @@ -295,18 +284,18 @@ static void Wb35Rx(struct ieee80211_hw *hw) return; error: - // VM stop + /* VM stop */ pWb35Rx->EP3vm_state = VM_STOP; atomic_dec(&pWb35Rx->RxFireCounter); } void Wb35Rx_start(struct ieee80211_hw *hw) { - struct wbsoft_priv *priv = hw->priv; - struct hw_data * pHwData = &priv->sHwData; - struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; + struct wbsoft_priv *priv = hw->priv; + struct hw_data *pHwData = &priv->sHwData; + struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; - // Allow only one thread to run into the Wb35Rx() function + /* Allow only one thread to run into the Wb35Rx() function */ if (atomic_inc_return(&pWb35Rx->RxFireCounter) == 1) { pWb35Rx->EP3vm_state = VM_RUNNING; Wb35Rx(hw); @@ -314,11 +303,10 @@ void Wb35Rx_start(struct ieee80211_hw *hw) atomic_dec(&pWb35Rx->RxFireCounter); } -//===================================================================================== -static void Wb35Rx_reset_descriptor( struct hw_data * pHwData ) +static void Wb35Rx_reset_descriptor(struct hw_data *pHwData) { - struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; - u32 i; + struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; + u32 i; pWb35Rx->ByteReceived = 0; pWb35Rx->RxProcessIndex = 0; @@ -326,49 +314,49 @@ static void Wb35Rx_reset_descriptor( struct hw_data * pHwData ) pWb35Rx->EP3vm_state = VM_STOP; pWb35Rx->rx_halt = 0; - // Initial the Queue. The last buffer is reserved for used if the Rx resource is unavailable. - for( i=0; iRxOwner[i] = 1; } -unsigned char Wb35Rx_initial(struct hw_data * pHwData) +unsigned char Wb35Rx_initial(struct hw_data *pHwData) { struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; - // Initial the Buffer Queue - Wb35Rx_reset_descriptor( pHwData ); + /* Initial the Buffer Queue */ + Wb35Rx_reset_descriptor(pHwData); pWb35Rx->RxUrb = usb_alloc_urb(0, GFP_ATOMIC); - return (!!pWb35Rx->RxUrb); + return !!pWb35Rx->RxUrb; } -void Wb35Rx_stop(struct hw_data * pHwData) +void Wb35Rx_stop(struct hw_data *pHwData) { struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; - // Canceling the Irp if already sends it out. + /* Canceling the Irp if already sends it out. */ if (pWb35Rx->EP3vm_state == VM_RUNNING) { - usb_unlink_urb( pWb35Rx->RxUrb ); // Only use unlink, let Wb35Rx_destroy to free them - #ifdef _PE_RX_DUMP_ + usb_unlink_urb(pWb35Rx->RxUrb); /* Only use unlink, let Wb35Rx_destroy to free them */ +#ifdef _PE_RX_DUMP_ printk("EP3 Rx stop\n"); - #endif +#endif } } -// Needs process context -void Wb35Rx_destroy(struct hw_data * pHwData) +/* Needs process context */ +void Wb35Rx_destroy(struct hw_data *pHwData) { struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx; do { - msleep(10); // Delay for waiting function enter 940623.1.a + msleep(10); /* Delay for waiting function enter */ } while (pWb35Rx->EP3vm_state != VM_STOP); - msleep(10); // Delay for waiting function exit 940623.1.b + msleep(10); /* Delay for waiting function exit */ if (pWb35Rx->RxUrb) - usb_free_urb( pWb35Rx->RxUrb ); - #ifdef _PE_RX_DUMP_ + usb_free_urb(pWb35Rx->RxUrb); +#ifdef _PE_RX_DUMP_ printk("Wb35Rx_destroy OK\n"); - #endif +#endif } -- cgit v1.2.3 From b66e65e2fea9392bdccc27b14b00c26b286eb248 Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Sun, 28 Mar 2010 19:10:59 +0200 Subject: Staging: winbond: wbhal_f.h Coding style fixes. I fixed all checkpatch problems and also converted the function arguments from hungarian notation and CamelCase. Signed-off-by: Lars Lindley Acked-by: Dan Carpenter Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wbhal_f.h | 137 ++++++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/wbhal_f.h b/drivers/staging/winbond/wbhal_f.h index 64a008db30f4..401c024bead8 100644 --- a/drivers/staging/winbond/wbhal_f.h +++ b/drivers/staging/winbond/wbhal_f.h @@ -1,70 +1,91 @@ -//===================================================================== -// Device related include -//===================================================================== +/* + * ===================================================================== + * Device related include + * ===================================================================== +*/ #include "wb35reg_f.h" #include "wb35tx_f.h" #include "wb35rx_f.h" #include "core.h" -//==================================================================================== -// Function declaration -//==================================================================================== -void hal_remove_mapping_key( struct hw_data * pHwData, u8 *pmac_addr ); -void hal_remove_default_key( struct hw_data * pHwData, u32 index ); -unsigned char hal_set_mapping_key( struct hw_data * adapter, u8 *pmac_addr, u8 null_key, u8 wep_on, u8 *ptx_tsc, u8 *prx_tsc, u8 key_type, u8 key_len, u8 *pkey_data ); -unsigned char hal_set_default_key( struct hw_data * adapter, u8 index, u8 null_key, u8 wep_on, u8 *ptx_tsc, u8 *prx_tsc, u8 key_type, u8 key_len, u8 *pkey_data ); -void hal_clear_all_default_key( struct hw_data * pHwData ); -void hal_clear_all_group_key( struct hw_data * pHwData ); -void hal_clear_all_mapping_key( struct hw_data * pHwData ); -void hal_clear_all_key( struct hw_data * pHwData ); -void hal_set_power_save_mode( struct hw_data * pHwData, unsigned char power_save, unsigned char wakeup, unsigned char dtim ); -void hal_get_power_save_mode( struct hw_data * pHwData, u8 *pin_pwr_save ); -void hal_set_slot_time( struct hw_data * pHwData, u8 type ); -#define hal_set_atim_window( _A, _ATM ) -void hal_start_bss( struct hw_data * pHwData, u8 mac_op_mode ); -void hal_join_request( struct hw_data * pHwData, u8 bss_type ); // 0:BSS STA 1:IBSS STA// -void hal_stop_sync_bss( struct hw_data * pHwData ); -void hal_resume_sync_bss( struct hw_data * pHwData); -void hal_set_aid( struct hw_data * pHwData, u16 aid ); -void hal_set_bssid( struct hw_data * pHwData, u8 *pbssid ); -void hal_get_bssid( struct hw_data * pHwData, u8 *pbssid ); -void hal_set_listen_interval( struct hw_data * pHwData, u16 listen_interval ); -void hal_set_cap_info( struct hw_data * pHwData, u16 capability_info ); -void hal_set_ssid( struct hw_data * pHwData, u8 *pssid, u8 ssid_len ); -void hal_start_tx0( struct hw_data * pHwData ); -#define hal_get_cwmin( _A ) ( (_A)->cwmin ) -void hal_set_cwmax( struct hw_data * pHwData, u16 cwin_max ); -#define hal_get_cwmax( _A ) ( (_A)->cwmax ) -void hal_set_rsn_wpa( struct hw_data * pHwData, u32 * RSN_IE_Bitmap , u32 * RSN_OUI_type , unsigned char bDesiredAuthMode); -void hal_set_connect_info( struct hw_data * pHwData, unsigned char boConnect ); -u8 hal_get_est_sq3( struct hw_data * pHwData, u8 Count ); -void hal_descriptor_indicate( struct hw_data * pHwData, struct wb35_descriptor *pDes ); -u8 hal_get_antenna_number( struct hw_data * pHwData ); -u32 hal_get_bss_pk_cnt( struct hw_data * pHwData ); -#define hal_get_region_from_EEPROM( _A ) ( (_A)->reg.EEPROMRegion ) -#define hal_get_tx_buffer( _A, _B ) Wb35Tx_get_tx_buffer( _A, _B ) -#define hal_software_set( _A ) (_A->SoftwareSet) -#define hal_driver_init_OK( _A ) (_A->IsInitOK) -#define hal_rssi_boundary_high( _A ) (_A->RSSI_high) -#define hal_rssi_boundary_low( _A ) (_A->RSSI_low) -#define hal_scan_interval( _A ) (_A->Scan_Interval) - -#define PHY_DEBUG( msg, args... ) - -#define hal_get_time_count( _P ) (_P->time_count/10) // return 100ms count -#define hal_detect_error( _P ) (_P->WbUsb.DetectCount) - -//------------------------------------------------------------------------- -// The follow function is unused for IS89C35 -//------------------------------------------------------------------------- +/* ===================================================================== + * Function declaration + * ===================================================================== + */ +void hal_remove_mapping_key(struct hw_data *hw_data, u8 *mac_addr); +void hal_remove_default_key(struct hw_data *hw_data, u32 index); +unsigned char hal_set_mapping_key(struct hw_data *adapter, u8 *mac_addr, + u8 null_key, u8 wep_on, u8 *tx_tsc, + u8 *rx_tsc, u8 key_type, u8 key_len, + u8 *key_data); +unsigned char hal_set_default_key(struct hw_data *adapter, u8 index, + u8 null_key, u8 wep_on, u8 *tx_tsc, + u8 *rx_tsc, u8 key_type, u8 key_len, + u8 *key_data); +void hal_clear_all_default_key(struct hw_data *hw_data); +void hal_clear_all_group_key(struct hw_data *hw_data); +void hal_clear_all_mapping_key(struct hw_data *hw_data); +void hal_clear_all_key(struct hw_data *hw_data); +void hal_set_power_save_mode(struct hw_data *hw_data, unsigned char power_save, + unsigned char wakeup, unsigned char dtim); +void hal_get_power_save_mode(struct hw_data *hw_data, u8 *in_pwr_save); +void hal_set_slot_time(struct hw_data *hw_data, u8 type); + +#define hal_set_atim_window(_A, _ATM) + +void hal_start_bss(struct hw_data *hw_data, u8 mac_op_mode); + +/* 0:BSS STA 1:IBSS STA */ +void hal_join_request(struct hw_data *hw_data, u8 bss_type); + +void hal_stop_sync_bss(struct hw_data *hw_data); +void hal_resume_sync_bss(struct hw_data *hw_data); +void hal_set_aid(struct hw_data *hw_data, u16 aid); +void hal_set_bssid(struct hw_data *hw_data, u8 *bssid); +void hal_get_bssid(struct hw_data *hw_data, u8 *bssid); +void hal_set_listen_interval(struct hw_data *hw_data, u16 listen_interval); +void hal_set_cap_info(struct hw_data *hw_data, u16 capability_info); +void hal_set_ssid(struct hw_data *hw_data, u8 *ssid, u8 ssid_len); +void hal_start_tx0(struct hw_data *hw_data); + +#define hal_get_cwmin(_A) ((_A)->cwmin) + +void hal_set_cwmax(struct hw_data *hw_data, u16 cwin_max); + +#define hal_get_cwmax(_A) ((_A)->cwmax) + +void hal_set_rsn_wpa(struct hw_data *hw_data, u32 *rsn_ie_bitmap, + u32 *rsn_oui_type , unsigned char desired_auth_mode); +void hal_set_connect_info(struct hw_data *hw_data, unsigned char bo_connect); +u8 hal_get_est_sq3(struct hw_data *hw_data, u8 count); +void hal_descriptor_indicate(struct hw_data *hw_data, + struct wb35_descriptor *des); +u8 hal_get_antenna_number(struct hw_data *hw_data); +u32 hal_get_bss_pk_cnt(struct hw_data *hw_data); + +#define hal_get_region_from_EEPROM(_A) ((_A)->reg.EEPROMRegion) +#define hal_get_tx_buffer(_A, _B) Wb35Tx_get_tx_buffer(_A, _B) +#define hal_software_set(_A) (_A->SoftwareSet) +#define hal_driver_init_OK(_A) (_A->IsInitOK) +#define hal_rssi_boundary_high(_A) (_A->RSSI_high) +#define hal_rssi_boundary_low(_A) (_A->RSSI_low) +#define hal_scan_interval(_A) (_A->Scan_Interval) + +#define PHY_DEBUG(msg, args...) + +/* return 100ms count */ +#define hal_get_time_count(_P) (_P->time_count / 10) +#define hal_detect_error(_P) (_P->WbUsb.DetectCount) + +/* The follow function is unused for IS89C35 */ #define hal_disable_interrupt(_A) #define hal_enable_interrupt(_A) -#define hal_get_interrupt_type( _A) +#define hal_get_interrupt_type(_A) #define hal_get_clear_interrupt(_A) -#define hal_ibss_disconnect(_A) hal_stop_sync_bss(_A) +#define hal_ibss_disconnect(_A) (hal_stop_sync_bss(_A)) #define hal_join_request_stop(_A) -#define hw_get_cxx_reg( _A, _B, _C ) -#define hw_set_cxx_reg( _A, _B, _C ) +#define hw_get_cxx_reg(_A, _B, _C) +#define hw_set_cxx_reg(_A, _B, _C) -- cgit v1.2.3 From 5a7df3c449e7db7cf4b7807862e11f11c47c2331 Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Sun, 28 Mar 2010 21:52:37 +0200 Subject: Staging: winbond: wbhal_s.h Coding style fixes. I fixed checkpatch warnings except some long lines and typedefs. I also removed versioning comments. Signed-off-by: Lars Lindley Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wbhal_s.h | 502 ++++++++++++++++++-------------------- 1 file changed, 242 insertions(+), 260 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/wbhal_s.h b/drivers/staging/winbond/wbhal_s.h index 372a05e3021a..33457c2e39be 100644 --- a/drivers/staging/winbond/wbhal_s.h +++ b/drivers/staging/winbond/wbhal_s.h @@ -4,179 +4,166 @@ #include #include /* for ETH_ALEN */ -//[20040722 WK] -#define HAL_LED_SET_MASK 0x001c //20060901 Extend -#define HAL_LED_SET_SHIFT 2 +#define HAL_LED_SET_MASK 0x001c +#define HAL_LED_SET_SHIFT 2 -//supported RF type +/* supported RF type */ #define RF_MAXIM_2825 0 #define RF_MAXIM_2827 1 #define RF_MAXIM_2828 2 #define RF_MAXIM_2829 3 -#define RF_MAXIM_V1 15 +#define RF_MAXIM_V1 15 #define RF_AIROHA_2230 16 #define RF_AIROHA_7230 17 -#define RF_AIROHA_2230S 18 // 20060420 Add this -// #define RF_RFMD_2959 32 // 20060626 Remove all about RFMD -#define RF_WB_242 33 -#define RF_WB_242_1 34 // 20060619.5 Add +#define RF_AIROHA_2230S 18 +#define RF_WB_242 33 +#define RF_WB_242_1 34 #define RF_DECIDE_BY_INF 255 -//---------------------------------------------------------------- -// The follow define connect to upper layer -// User must modify for connection between HAL and upper layer -//---------------------------------------------------------------- - - - - -///////////////////////////////////////////////////////////////////////////////////////////////////// -//================================================================================================ -// Common define -//================================================================================================ -#define HAL_USB_MODE_BURST( _H ) (_H->SoftwareSet & 0x20 ) // Bit 5 20060901 Modify - -// Scan interval -#define SCAN_MAX_CHNL_TIME (50) - -// For TxL2 Frame typr recognise +/* + * ---------------------------------------------------------------- + * The follow define connect to upper layer + * User must modify for connection between HAL and upper layer + * ---------------------------------------------------------------- + */ + +/* + * ============================== + * Common define + * ============================== + */ +/* Bit 5 */ +#define HAL_USB_MODE_BURST(_H) (_H->SoftwareSet & 0x20) + +/* Scan interval */ +#define SCAN_MAX_CHNL_TIME (50) + +/* For TxL2 Frame typr recognise */ #define FRAME_TYPE_802_3_DATA 0 #define FRAME_TYPE_802_11_MANAGEMENT 1 -#define FRAME_TYPE_802_11_MANAGEMENT_CHALLENGE 2 +#define FRAME_TYPE_802_11_MANAGEMENT_CHALLENGE 2 #define FRAME_TYPE_802_11_CONTROL 3 #define FRAME_TYPE_802_11_DATA 4 #define FRAME_TYPE_PROMISCUOUS 5 -// The follow definition is used for convert the frame-------------------- -#define DOT_11_SEQUENCE_OFFSET 22 //Sequence control offset +/* The follow definition is used for convert the frame------------ */ +#define DOT_11_SEQUENCE_OFFSET 22 /* Sequence control offset */ #define DOT_3_TYPE_OFFSET 12 -#define DOT_11_MAC_HEADER_SIZE 24 +#define DOT_11_MAC_HEADER_SIZE 24 #define DOT_11_SNAP_SIZE 6 -#define DOT_11_TYPE_OFFSET 30 //The start offset of 802.11 Frame. Type encapsulatuin. +#define DOT_11_TYPE_OFFSET 30 /* The start offset of 802.11 Frame. Type encapsulation. */ #define DEFAULT_SIFSTIME 10 -#define DEFAULT_FRAGMENT_THRESHOLD 2346 // No fragment +#define DEFAULT_FRAGMENT_THRESHOLD 2346 /* No fragment */ #define DEFAULT_MSDU_LIFE_TIME 0xffff -#define LONG_PREAMBLE_PLUS_PLCPHEADER_TIME (144+48) -#define SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME (72+24) -#define PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION (16+4+6) -#define Tsym 4 +#define LONG_PREAMBLE_PLUS_PLCPHEADER_TIME (144 + 48) +#define SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME (72 + 24) +#define PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION (16 + 4 + 6) +#define Tsym 4 -// Frame Type of Bits (2, 3)--------------------------------------------- +/* Frame Type of Bits (2, 3)----------------------------------- */ #define MAC_TYPE_MANAGEMENT 0x00 #define MAC_TYPE_CONTROL 0x04 #define MAC_TYPE_DATA 0x08 -#define MASK_FRAGMENT_NUMBER 0x000F -#define SEQUENCE_NUMBER_SHIFT 4 +#define MASK_FRAGMENT_NUMBER 0x000F +#define SEQUENCE_NUMBER_SHIFT 4 #define HAL_WOL_TYPE_WAKEUP_FRAME 0x01 #define HAL_WOL_TYPE_MAGIC_PACKET 0x02 -// 20040106 ADDED -#define HAL_KEYTYPE_WEP40 0 -#define HAL_KEYTYPE_WEP104 1 -#define HAL_KEYTYPE_TKIP 2 // 128 bit key -#define HAL_KEYTYPE_AES_CCMP 3 // 128 bit key +#define HAL_KEYTYPE_WEP40 0 +#define HAL_KEYTYPE_WEP104 1 +#define HAL_KEYTYPE_TKIP 2 /* 128 bit key */ +#define HAL_KEYTYPE_AES_CCMP 3 /* 128 bit key */ -// For VM state +/* For VM state */ enum { VM_STOP = 0, VM_RUNNING, VM_COMPLETED }; -//----------------------------------------------------- -// Normal Key table format -//----------------------------------------------------- -// The order of KEY index is MAPPING_KEY_START_INDEX > GROUP_KEY_START_INDEX -#define MAX_KEY_TABLE 24 // 24 entry for storing key data +/* + * ================================ + * Normal Key table format + * ================================ + */ + +/* The order of KEY index is MAPPING_KEY_START_INDEX > GROUP_KEY_START_INDEX */ +#define MAX_KEY_TABLE 24 /* 24 entry for storing key data */ #define GROUP_KEY_START_INDEX 4 #define MAPPING_KEY_START_INDEX 8 -//-------------------------------------------------------- -// Descriptor -//-------------------------------------------------------- -#define MAX_DESCRIPTOR_BUFFER_INDEX 8 // Have to multiple of 2 -//#define FLAG_ERROR_TX_MASK cpu_to_le32(0x000000bf) //20061009 marked by anson's endian -#define FLAG_ERROR_TX_MASK 0x000000bf //20061009 anson's endian -//#define FLAG_ERROR_RX_MASK 0x00000c3f -//#define FLAG_ERROR_RX_MASK cpu_to_le32(0x0000083f) //20061009 marked by anson's endian - //Don't care replay error, - //it is handled by S/W -#define FLAG_ERROR_RX_MASK 0x0000083f //20060926 anson's endian - -#define FLAG_BAND_RX_MASK 0x10000000 //Bit 28 - -typedef struct _R00_DESCRIPTOR -{ - union - { +/* + * ========================================= + * Descriptor + * ========================================= + */ +#define MAX_DESCRIPTOR_BUFFER_INDEX 8 /* Have to multiple of 2 */ +#define FLAG_ERROR_TX_MASK 0x000000bf +#define FLAG_ERROR_RX_MASK 0x0000083f + +#define FLAG_BAND_RX_MASK 0x10000000 /* Bit 28 */ + +typedef struct _R00_DESCRIPTOR { + union { u32 value; - #ifdef _BIG_ENDIAN_ //20060926 anson's endian - struct - { +#ifdef _BIG_ENDIAN_ + struct { u32 R00_packet_or_buffer_status:1; u32 R00_packet_in_fifo:1; u32 R00_RESERVED:2; u32 R00_receive_byte_count:12; u32 R00_receive_time_index:16; }; - #else - struct - { +#else + struct { u32 R00_receive_time_index:16; u32 R00_receive_byte_count:12; u32 R00_RESERVED:2; u32 R00_packet_in_fifo:1; u32 R00_packet_or_buffer_status:1; }; - #endif +#endif }; } R00_DESCRIPTOR, *PR00_DESCRIPTOR; -typedef struct _T00_DESCRIPTOR -{ - union - { +typedef struct _T00_DESCRIPTOR { + union { u32 value; - #ifdef _BIG_ENDIAN_ //20061009 anson's endian - struct - { - u32 T00_first_mpdu:1; // for hardware use - u32 T00_last_mpdu:1; // for hardware use - u32 T00_IsLastMpdu:1;// 0: not 1:Yes for software used - u32 T00_IgnoreResult:1;// The same mechanism with T00 setting. 050111 Modify for TS - u32 T00_RESERVED_ID:2;//3 bit ID reserved - u32 T00_tx_packet_id:4;//930519.4.e 930810.3.c +#ifdef _BIG_ENDIAN_ + struct { + u32 T00_first_mpdu:1; /* for hardware use */ + u32 T00_last_mpdu:1; /* for hardware use */ + u32 T00_IsLastMpdu:1;/* 0:not 1:Yes for software used */ + u32 T00_IgnoreResult:1;/* The same mechanism with T00 setting. */ + u32 T00_RESERVED_ID:2;/* 3 bit ID reserved */ + u32 T00_tx_packet_id:4; u32 T00_RESERVED:4; u32 T00_header_length:6; u32 T00_frame_length:12; }; - #else - struct - { +#else + struct { u32 T00_frame_length:12; u32 T00_header_length:6; u32 T00_RESERVED:4; - u32 T00_tx_packet_id:4;//930519.4.e 930810.3.c - u32 T00_RESERVED_ID:2;//3 bit ID reserved - u32 T00_IgnoreResult:1;// The same mechanism with T00 setting. 050111 Modify for TS - u32 T00_IsLastMpdu:1;// 0: not 1:Yes for software used - u32 T00_last_mpdu:1; // for hardware use - u32 T00_first_mpdu:1; // for hardware use + u32 T00_tx_packet_id:4; + u32 T00_RESERVED_ID:2; /* 3 bit ID reserved */ + u32 T00_IgnoreResult:1; /* The same mechanism with T00 setting. */ + u32 T00_IsLastMpdu:1; /* 0:not 1:Yes for software used */ + u32 T00_last_mpdu:1; /* for hardware use */ + u32 T00_first_mpdu:1; /* for hardware use */ }; - #endif +#endif }; } T00_DESCRIPTOR, *PT00_DESCRIPTOR; -typedef struct _R01_DESCRIPTOR -{ - union - { +typedef struct _R01_DESCRIPTOR { + union { u32 value; - #ifdef _BIG_ENDIAN_ //20060926 add by anson's endian - struct - { +#ifdef _BIG_ENDIAN_ + struct { u32 R01_RESERVED:3; u32 R01_mod_type:1; u32 R01_pre_type:1; @@ -197,9 +184,8 @@ typedef struct _R01_DESCRIPTOR u32 R01_icv_error:1; u32 R01_crc_error:1; }; - #else - struct - { +#else + struct { u32 R01_crc_error:1; u32 R01_icv_error:1; u32 R01_null_key_to_authentication_frame:1; @@ -220,18 +206,15 @@ typedef struct _R01_DESCRIPTOR u32 R01_mod_type:1; u32 R01_RESERVED:3; }; - #endif +#endif }; } R01_DESCRIPTOR, *PR01_DESCRIPTOR; -typedef struct _T01_DESCRIPTOR -{ - union - { +typedef struct _T01_DESCRIPTOR { + union { u32 value; - #ifdef _BIG_ENDIAN_ //20061009 anson's endian - struct - { +#ifdef _BIG_ENDIAN_ + struct { u32 T01_rts_cts_duration:16; u32 T01_fall_back_rate:3; u32 T01_add_rts:1; @@ -245,9 +228,8 @@ typedef struct _T01_DESCRIPTOR u32 T01_loop_back_wep_mode:1; u32 T01_retry_abort_ebable:1; }; - #else - struct - { +#else + struct { u32 T01_retry_abort_ebable:1; u32 T01_loop_back_wep_mode:1; u32 T01_inhibit_crc:1; @@ -261,21 +243,18 @@ typedef struct _T01_DESCRIPTOR u32 T01_fall_back_rate:3; u32 T01_rts_cts_duration:16; }; - #endif +#endif }; } T01_DESCRIPTOR, *PT01_DESCRIPTOR; -typedef struct _T02_DESCRIPTOR -{ - union - { +typedef struct _T02_DESCRIPTOR { + union { u32 value; - #ifdef _BIG_ENDIAN_ //20061009 add by anson's endian - struct - { - u32 T02_IsLastMpdu:1;// The same mechanism with T00 setting - u32 T02_IgnoreResult:1;// The same mechanism with T00 setting. 050111 Modify for TS - u32 T02_RESERVED_ID:2;// The same mechanism with T00 setting +#ifdef _BIG_ENDIAN_ + struct { + u32 T02_IsLastMpdu:1; /* The same mechanism with T00 setting */ + u32 T02_IgnoreResult:1; /* The same mechanism with T00 setting. */ + u32 T02_RESERVED_ID:2; /* The same mechanism with T00 setting */ u32 T02_Tx_PktID:4; u32 T02_MPDU_Cnt:4; u32 T02_RTS_Cnt:4; @@ -290,9 +269,8 @@ typedef struct _T02_DESCRIPTOR u32 T02_transmit_abort:1; u32 T02_transmit_fail:1; }; - #else - struct - { +#else + struct { u32 T02_transmit_fail:1; u32 T02_transmit_abort:1; u32 T02_out_of_MaxTxMSDULiftTime:1; @@ -306,122 +284,120 @@ typedef struct _T02_DESCRIPTOR u32 T02_RTS_Cnt:4; u32 T02_MPDU_Cnt:4; u32 T02_Tx_PktID:4; - u32 T02_RESERVED_ID:2;// The same mechanism with T00 setting - u32 T02_IgnoreResult:1;// The same mechanism with T00 setting. 050111 Modify for TS - u32 T02_IsLastMpdu:1;// The same mechanism with T00 setting + u32 T02_RESERVED_ID:2; /* The same mechanism with T00 setting */ + u32 T02_IgnoreResult:1; /* The same mechanism with T00 setting. */ + u32 T02_IsLastMpdu:1; /* The same mechanism with T00 setting */ }; - #endif +#endif }; } T02_DESCRIPTOR, *PT02_DESCRIPTOR; -struct wb35_descriptor { // Skip length = 8 DWORD - // ID for descriptor ---, The field doesn't be cleard in the operation of Descriptor definition +struct wb35_descriptor { /* Skip length = 8 DWORD */ + /* ID for descriptor ---, The field doesn't be cleard in the operation of Descriptor definition */ u8 Descriptor_ID; - //----------------------The above region doesn't be cleared by DESCRIPTOR_RESET------ + /* ----------------------The above region doesn't be cleared by DESCRIPTOR_RESET------ */ u8 RESERVED[3]; u16 FragmentThreshold; - u8 InternalUsed;//Only can be used by operation of descriptor definition - u8 Type;// 0: 802.3 1:802.11 data frame 2:802.11 management frame + u8 InternalUsed; /* Only can be used by operation of descriptor definition */ + u8 Type; /* 0: 802.3 1:802.11 data frame 2:802.11 management frame */ - u8 PreambleMode;// 0: short 1:long + u8 PreambleMode;/* 0: short 1:long */ u8 TxRate; u8 FragmentCount; - u8 EapFix; // For speed up key install + u8 EapFix; /* For speed up key install */ - // For R00 and T00 ---------------------------------------------- - union - { + /* For R00 and T00 ------------------------------ */ + union { R00_DESCRIPTOR R00; T00_DESCRIPTOR T00; }; - // For R01 and T01 ---------------------------------------------- - union - { + /* For R01 and T01 ------------------------------ */ + union { R01_DESCRIPTOR R01; T01_DESCRIPTOR T01; }; - // For R02 and T02 ---------------------------------------------- - union - { - u32 R02; + /* For R02 and T02 ------------------------------ */ + union { + u32 R02; T02_DESCRIPTOR T02; }; - // For R03 and T03 ---------------------------------------------- - // For software used - union - { + /* For R03 and T03 ------------------------------ */ + /* For software used */ + union { u32 R03; u32 T03; - struct - { + struct { u8 buffer_number; u8 buffer_start_index; u16 buffer_total_size; }; }; - // For storing the buffer - u16 buffer_size[ MAX_DESCRIPTOR_BUFFER_INDEX ]; - void* buffer_address[ MAX_DESCRIPTOR_BUFFER_INDEX ];//931130.4.q - + /* For storing the buffer */ + u16 buffer_size[MAX_DESCRIPTOR_BUFFER_INDEX]; + void *buffer_address[MAX_DESCRIPTOR_BUFFER_INDEX]; }; -#define DEFAULT_NULL_PACKET_COUNT 180000 //20060828.1 Add. 180 seconds +#define DEFAULT_NULL_PACKET_COUNT 180000 /* 180 seconds */ -#define MAX_TXVGA_EEPROM 9 //How many word(u16) of EEPROM will be used for TxVGA -#define MAX_RF_PARAMETER 32 +#define MAX_TXVGA_EEPROM 9 /* How many word(u16) of EEPROM will be used for TxVGA */ +#define MAX_RF_PARAMETER 32 typedef struct _TXVGA_FOR_50 { - u8 ChanNo; - u8 TxVgaValue; + u8 ChanNo; + u8 TxVgaValue; } TXVGA_FOR_50; -//===================================================================== -// Device related include -//===================================================================== +/* + * ============================================== + * Device related include + * ============================================== + */ #include "wbusb_s.h" #include "wb35reg_s.h" #include "wb35tx_s.h" #include "wb35rx_s.h" -// For Hal using ================================================================== +/* For Hal using ============================================ */ struct hw_data { - // For compatible with 33 + /* For compatible with 33 */ u32 revision; - u32 BB3c_cal; // The value for Tx calibration comes from EEPROM - u32 BB54_cal; // The value for Rx calibration comes from EEPROM + u32 BB3c_cal; /* The value for Tx calibration comes from EEPROM */ + u32 BB54_cal; /* The value for Rx calibration comes from EEPROM */ - - // For surprise remove - u32 SurpriseRemove; // 0: Normal 1: Surprise remove + /* For surprise remove */ + u32 SurpriseRemove; /* 0: Normal 1: Surprise remove */ u8 IsKeyPreSet; - u8 CalOneTime; // 20060630.1 + u8 CalOneTime; u8 VCO_trim; - // For Fix 1'st DMA bug u32 FragCount; - u32 DMAFix; //V1_DMA_FIX The variable can be removed if driver want to save mem space for V2. - - //=============================================== - // Definition for MAC address - //=============================================== - u8 PermanentMacAddress[ETH_ALEN + 2]; // The Enthernet addr that are stored in EEPROM. + 2 to 8-byte alignment - u8 CurrentMacAddress[ETH_ALEN + 2]; // The Enthernet addr that are in used. + 2 to 8-byte alignment - - //===================================================================== - // Definition for 802.11 - //===================================================================== - u8 *bssid_pointer; // Used by hal_get_bssid for return value - u8 bssid[8];// Only 6 byte will be used. 8 byte is required for read buffer - u8 ssid[32];// maximum ssid length is 32 byte + u32 DMAFix; /* V1_DMA_FIX The variable can be removed if driver want to save mem space for V2. */ + + /* + * =============================================== + * Definition for MAC address + * =============================================== + */ + u8 PermanentMacAddress[ETH_ALEN + 2]; /* The Ethernet addr that are stored in EEPROM. + 2 to 8-byte alignment */ + u8 CurrentMacAddress[ETH_ALEN + 2]; /* The Enthernet addr that are in used. + 2 to 8-byte alignment */ + + /* + * ========================================= + * Definition for 802.11 + * ========================================= + */ + u8 *bssid_pointer; /* Used by hal_get_bssid for return value */ + u8 bssid[8]; /* Only 6 byte will be used. 8 byte is required for read buffer */ + u8 ssid[32]; /* maximum ssid length is 32 byte */ u16 AID; u8 ssid_length; @@ -433,112 +409,118 @@ struct hw_data { u16 BeaconPeriod; u16 ProbeDelay; - u8 bss_type;// 0: IBSS_NET or 1:ESS_NET - u8 preamble;// 0: short preamble, 1: long preamble - u8 slot_time_select;// 9 or 20 value - u8 phy_type;// Phy select + u8 bss_type;/* 0: IBSS_NET or 1:ESS_NET */ + u8 preamble;/* 0: short preamble, 1: long preamble */ + u8 slot_time_select; /* 9 or 20 value */ + u8 phy_type; /* Phy select */ u32 phy_para[MAX_RF_PARAMETER]; u32 phy_number; - u32 CurrentRadioSw; // 20060320.2 0:On 1:Off - u32 CurrentRadioHw; // 20060825 0:On 1:Off + u32 CurrentRadioSw; /* 0:On 1:Off */ + u32 CurrentRadioHw; /* 0:On 1:Off */ - u8 *power_save_point; // Used by hal_get_power_save_mode for return value + u8 *power_save_point; /* Used by hal_get_power_save_mode for return value */ u8 cwmin; u8 desired_power_save; - u8 dtim;// Is running dtim - u8 mapping_key_replace_index;//In Key table, the next index be replaced 931130.4.r + u8 dtim; /* Is running dtim */ + u8 mapping_key_replace_index; /* In Key table, the next index be replaced */ u16 MaxReceiveLifeTime; u16 FragmentThreshold; u16 FragmentThreshold_tmp; u16 cwmax; - u8 Key_slot[MAX_KEY_TABLE][8]; //Ownership record for key slot. For Alignment - u32 Key_content[MAX_KEY_TABLE][12]; // 10DW for each entry + 2 for burst command( Off and On valid bit) + u8 Key_slot[MAX_KEY_TABLE][8]; /* Ownership record for key slot. For Alignment */ + u32 Key_content[MAX_KEY_TABLE][12]; /* 10DW for each entry + 2 for burst command (Off and On valid bit) */ u8 CurrentDefaultKeyIndex; u32 CurrentDefaultKeyLength; - //======================================================================== - // Variable for each module - //======================================================================== - struct wb_usb WbUsb; // Need WbUsb.h - struct wb35_reg reg; // Need Wb35Reg.h - struct wb35_tx Wb35Tx; // Need Wb35Tx.h - struct wb35_rx Wb35Rx; // Need Wb35Rx.h + /* + * ================================================== + * Variable for each module + * ================================================== + */ + struct wb_usb WbUsb; /* Need WbUsb.h */ + struct wb35_reg reg; /* Need Wb35Reg.h */ + struct wb35_tx Wb35Tx; /* Need Wb35Tx.h */ + struct wb35_rx Wb35Rx; /* Need Wb35Rx.h */ - struct timer_list LEDTimer;// For LED + struct timer_list LEDTimer; /* For LED */ - u32 LEDpoint;// For LED + u32 LEDpoint; /* For LED */ - u32 dto_tx_retry_count; // LA20040210_DTO kevin - u32 dto_tx_frag_count; // LA20040210_DTO kevin - u32 rx_ok_count[13]; // index=0: total rx ok - //u32 rx_ok_bytes[13]; // index=0, total rx ok bytes - u32 rx_err_count[13]; // index=0: total rx err + u32 dto_tx_retry_count; + u32 dto_tx_frag_count; + u32 rx_ok_count[13]; /* index=0: total rx ok */ + u32 rx_err_count[13]; /* index=0: total rx err */ - //for Tx debug + /* for Tx debug */ u32 tx_TBTT_start_count; u32 tx_ETR_count; u32 tx_WepOn_false_count; u32 tx_Null_key_count; u32 tx_retry_count[8]; - u8 PowerIndexFromEEPROM; // For 2412MHz - u8 power_index; - u8 IsWaitJoinComplete; // TRUE: set join request - u8 band; + u8 PowerIndexFromEEPROM; /* For 2412MHz */ + u8 power_index; + u8 IsWaitJoinComplete; /* TRUE: set join request */ + u8 band; - u16 SoftwareSet; - u16 Reserved_s; + u16 SoftwareSet; + u16 Reserved_s; - u32 IsInitOK; // 0: Driver starting 1: Driver init OK + u32 IsInitOK; /* 0: Driver starting 1: Driver init OK */ - // For Phy calibration - s32 iq_rsdl_gain_tx_d2; - s32 iq_rsdl_phase_tx_d2; - u32 txvga_setting_for_cal; // 20060703.1 Add + /* For Phy calibration */ + s32 iq_rsdl_gain_tx_d2; + s32 iq_rsdl_phase_tx_d2; + u32 txvga_setting_for_cal; - u8 TxVgaSettingInEEPROM[ (((MAX_TXVGA_EEPROM*2)+3) & ~0x03) ]; // 20060621 For backup EEPROM value - u8 TxVgaFor24[16]; // Max is 14, 2 for alignment - TXVGA_FOR_50 TxVgaFor50[36]; // 35 channels in 5G. 35x2 = 70 byte. 2 for alignments + u8 TxVgaSettingInEEPROM[(((MAX_TXVGA_EEPROM * 2) + 3) & ~0x03)]; /* For EEPROM value */ + u8 TxVgaFor24[16]; /* Max is 14, 2 for alignment */ + TXVGA_FOR_50 TxVgaFor50[36]; /* 35 channels in 5G. 35x2 = 70 byte. 2 for alignments */ - u16 Scan_Interval; - u16 RESERVED6; + u16 Scan_Interval; + u16 RESERVED6; - // LED control + /* LED control */ u32 LED_control; - // LED_control 4 byte: Gray_Led_1[3] Gray_Led_0[2] Led[1] Led[0] - // Gray_Led - // For Led gray setting - // Led - // 0: normal control, LED behavior will decide by EEPROM setting - // 1: Turn off specific LED - // 2: Always on specific LED - // 3: slow blinking specific LED - // 4: fast blinking specific LED - // 5: WPS led control is set. Led0 is Red, Led1 id Green - // Led[1] is parameter for WPS LED mode - // // 1:InProgress 2: Error 3: Session overlap 4: Success 20061108 control - - u32 LED_LinkOn; //Turn LED on control - u32 LED_Scanning; // Let LED in scan process control - u32 LED_Blinking; // Temp variable for shining + /* + * LED_control 4 byte: Gray_Led_1[3] Gray_Led_0[2] Led[1] Led[0] + * Gray_Led + * For Led gray setting + * Led + * 0: normal control, + * LED behavior will decide by EEPROM setting + * 1: Turn off specific LED + * 2: Always on specific LED + * 3: slow blinking specific LED + * 4: fast blinking specific LED + * 5: WPS led control is set. Led0 is Red, Led1 id Green + * + * Led[1] is parameter for WPS LED mode + * 1:InProgress + * 2: Error + * 3: Session overlap + * 4: Success control + */ + u32 LED_LinkOn; /* Turn LED on control */ + u32 LED_Scanning; /* Let LED in scan process control */ + u32 LED_Blinking; /* Temp variable for shining */ u32 RxByteCountLast; u32 TxByteCountLast; atomic_t SurpriseRemoveCount; - // For global timer - u32 time_count;//TICK_TIME_100ms 1 = 100ms + /* For global timer */ + u32 time_count; /* TICK_TIME_100ms 1 = 100ms */ - // For error recover + /* For error recover */ u32 HwStop; - // 20060828.1 for avoid AP disconnect + /* For avoid AP disconnect */ u32 NullPacketCount; - }; #endif -- cgit v1.2.3 From 83ad993d65738b6058a019b9c20ee65a57b0eecf Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Sun, 28 Mar 2010 22:00:13 +0200 Subject: Staging: winbond: wblinux_f.h Coding style fixes v2. I fixed whitespace and comments. Signed-off-by: Lars Lindley Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wblinux_f.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/wblinux_f.h b/drivers/staging/winbond/wblinux_f.h index 868e87727240..0a9d214f7187 100644 --- a/drivers/staging/winbond/wblinux_f.h +++ b/drivers/staging/winbond/wblinux_f.h @@ -4,13 +4,14 @@ #include "core.h" #include "mds_s.h" -//========================================================================= -// Copyright (c) 1996-2004 Winbond Electronic Corporation -// -// wblinux_f.h -// -int wb35_start_xmit(struct sk_buff *skb, struct net_device *netdev ); -void wb35_set_multicast( struct net_device *netdev ); -struct net_device_stats * wb35_netdev_stats( struct net_device *netdev ); - +/* + * ==================================================================== + * Copyright (c) 1996-2004 Winbond Electronic Corporation + * + * wblinux_f.h + * ==================================================================== + */ +int wb35_start_xmit(struct sk_buff *skb, struct net_device *netdev); +void wb35_set_multicast(struct net_device *netdev); +struct net_device_stats *wb35_netdev_stats(struct net_device *netdev); #endif -- cgit v1.2.3 From 912457fa4f63d69625653c6ca8d92c564907d14b Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Sun, 28 Mar 2010 22:05:32 +0200 Subject: Staging: winbond: wbusb_s.h Coding style fixes. I fixed comments and some spacing. Signed-off-by: Lars Lindley Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wbusb_s.h | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/wbusb_s.h b/drivers/staging/winbond/wbusb_s.h index 0c7e6a383f2d..8961ae594c4e 100644 --- a/drivers/staging/winbond/wbusb_s.h +++ b/drivers/staging/winbond/wbusb_s.h @@ -1,16 +1,10 @@ -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// Copyright (c) 1996-2004 Winbond Electronic Corporation -// -// Module Name: -// wbusb_s.h -// -// Abstract: -// Linux driver. -// -// Author: -// -//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - +/* ========================================================= + * Copyright (c) 1996-2004 Winbond Electronic Corporation + * + * Module Name: + * wbusb_s.h + * ========================================================= + */ #ifndef __WINBOND_WBUSB_S_H #define __WINBOND_WBUSB_S_H @@ -18,8 +12,7 @@ struct wb_usb { u32 IsUsb20; - struct usb_device *udev; + struct usb_device *udev; u32 DetectCount; }; - #endif -- cgit v1.2.3 From e5851c205d7d1920389ab4368f6f374d3594b93d Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Fri, 2 Apr 2010 10:57:35 +0200 Subject: Staging: winbond: wbusb.c Coding style fixes. I fixed the reported checkpatch.pl problems except for a bunch of long lines and some printk:s. I also removed versioning comments. Signed-off-by: Lars Lindley Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wbusb.c | 187 ++++++++++++++++++---------------------- 1 file changed, 84 insertions(+), 103 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index 3482eec18651..d7694e6a37a1 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c @@ -142,19 +142,17 @@ static void hal_set_radio_mode(struct hw_data *pHwData, unsigned char radio_off) if (pHwData->SurpriseRemove) return; - if (radio_off) //disable Baseband receive off - { - pHwData->CurrentRadioSw = 1; // off + if (radio_off) { /* disable Baseband receive off */ + pHwData->CurrentRadioSw = 1; /* off */ reg->M24_MacControl &= 0xffffffbf; } else { - pHwData->CurrentRadioSw = 0; // on + pHwData->CurrentRadioSw = 0; /* on */ reg->M24_MacControl |= 0x00000040; } Wb35Reg_Write(pHwData, 0x0824, reg->M24_MacControl); } -static void -hal_set_current_channel_ex(struct hw_data *pHwData, struct chan_info channel) +static void hal_set_current_channel_ex(struct hw_data *pHwData, struct chan_info channel) { struct wb35_reg *reg = &pHwData->reg; @@ -163,17 +161,18 @@ hal_set_current_channel_ex(struct hw_data *pHwData, struct chan_info channel) printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo); - RFSynthesizer_SwitchingChannel(pHwData, channel); // Switch channel + RFSynthesizer_SwitchingChannel(pHwData, channel); /* Switch channel */ pHwData->Channel = channel.ChanNo; pHwData->band = channel.band; #ifdef _PE_STATE_DUMP_ printk("Set channel is %d, band =%d\n", pHwData->Channel, pHwData->band); #endif - reg->M28_MacControl &= ~0xff; // Clean channel information field + reg->M28_MacControl &= ~0xff; /* Clean channel information field */ reg->M28_MacControl |= channel.ChanNo; Wb35Reg_WriteWithCallbackValue(pHwData, 0x0828, reg->M28_MacControl, - (s8 *) & channel, sizeof(struct chan_info)); + (s8 *) &channel, + sizeof(struct chan_info)); } static void hal_set_current_channel(struct hw_data *pHwData, struct chan_info channel) @@ -188,21 +187,22 @@ static void hal_set_accept_broadcast(struct hw_data *pHwData, u8 enable) if (pHwData->SurpriseRemove) return; - reg->M00_MacControl &= ~0x02000000; //The HW value + reg->M00_MacControl &= ~0x02000000; /* The HW value */ if (enable) - reg->M00_MacControl |= 0x02000000; //The HW value + reg->M00_MacControl |= 0x02000000; /* The HW value */ Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl); } -//for wep key error detection, we need to accept broadcast packets to be received temporary. +/* For wep key error detection, we need to accept broadcast packets to be received temporary. */ static void hal_set_accept_promiscuous(struct hw_data *pHwData, u8 enable) { struct wb35_reg *reg = &pHwData->reg; if (pHwData->SurpriseRemove) return; + if (enable) { reg->M00_MacControl |= 0x00400000; Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl); @@ -219,9 +219,9 @@ static void hal_set_accept_multicast(struct hw_data *pHwData, u8 enable) if (pHwData->SurpriseRemove) return; - reg->M00_MacControl &= ~0x01000000; //The HW value + reg->M00_MacControl &= ~0x01000000; /* The HW value */ if (enable) - reg->M00_MacControl |= 0x01000000; //The HW value + reg->M00_MacControl |= 0x01000000; /* The HW value */ Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl); } @@ -232,13 +232,12 @@ static void hal_set_accept_beacon(struct hw_data *pHwData, u8 enable) if (pHwData->SurpriseRemove) return; - // 20040108 debug - if (!enable) //Due to SME and MLME are not suitable for 35 + if (!enable) /* Due to SME and MLME are not suitable for 35 */ return; - reg->M00_MacControl &= ~0x04000000; //The HW value + reg->M00_MacControl &= ~0x04000000; /* The HW value */ if (enable) - reg->M00_MacControl |= 0x04000000; //The HW value + reg->M00_MacControl |= 0x04000000; /* The HW value */ Wb35Reg_Write(pHwData, 0x0800, reg->M00_MacControl); } @@ -283,8 +282,7 @@ static const struct ieee80211_ops wbsoft_ops = { .get_tsf = wbsoft_get_tsf, }; -static void -hal_set_ethernet_address(struct hw_data *pHwData, u8 * current_address) +static void hal_set_ethernet_address(struct hw_data *pHwData, u8 *current_address) { u32 ltmp[2]; @@ -294,14 +292,12 @@ hal_set_ethernet_address(struct hw_data *pHwData, u8 * current_address) memcpy(pHwData->CurrentMacAddress, current_address, ETH_ALEN); ltmp[0] = cpu_to_le32(*(u32 *) pHwData->CurrentMacAddress); - ltmp[1] = - cpu_to_le32(*(u32 *) (pHwData->CurrentMacAddress + 4)) & 0xffff; + ltmp[1] = cpu_to_le32(*(u32 *) (pHwData->CurrentMacAddress + 4)) & 0xffff; Wb35Reg_BurstWrite(pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT); } -static void -hal_get_permanent_address(struct hw_data *pHwData, u8 * pethernet_address) +static void hal_get_permanent_address(struct hw_data *pHwData, u8 *pethernet_address) { if (pHwData->SurpriseRemove) return; @@ -319,7 +315,7 @@ static void hal_stop(struct hw_data *pHwData) pHwData->Wb35Tx.tx_halt = 1; Wb35Tx_stop(pHwData); - reg->D00_DmaControl &= ~0xc0000000; //Tx Off, Rx Off + reg->D00_DmaControl &= ~0xc0000000; /* Tx Off, Rx Off */ Wb35Reg_Write(pHwData, 0x0400, reg->D00_DmaControl); } @@ -346,14 +342,14 @@ u8 hal_get_antenna_number(struct hw_data *pHwData) } /* 0 : radio on; 1: radio off */ -static u8 hal_get_hw_radio_off(struct hw_data * pHwData) +static u8 hal_get_hw_radio_off(struct hw_data *pHwData) { struct wb35_reg *reg = &pHwData->reg; if (pHwData->SurpriseRemove) return 1; - //read the bit16 of register U1B0 + /* read the bit16 of register U1B0 */ Wb35Reg_Read(pHwData, 0x3b0, ®->U1B0); if ((reg->U1B0 & 0x00010000)) { pHwData->CurrentRadioHw = 1; @@ -387,104 +383,98 @@ static void hal_led_control(unsigned long data) if (pHwData->LED_control) { ltmp2 = pHwData->LED_control & 0xff; - if (ltmp2 == 5) // 5 is WPS mode - { + if (ltmp2 == 5) { /* 5 is WPS mode */ TimeInterval = 100; ltmp2 = (pHwData->LED_control >> 8) & 0xff; switch (ltmp2) { - case 1: // [0.2 On][0.1 Off]... + case 1: /* [0.2 On][0.1 Off]... */ pHwData->LED_Blinking %= 3; - ltmp = 0x1010; // Led 1 & 0 Green and Red - if (pHwData->LED_Blinking == 2) // Turn off + ltmp = 0x1010; /* Led 1 & 0 Green and Red */ + if (pHwData->LED_Blinking == 2) /* Turn off */ ltmp = 0; break; - case 2: // [0.1 On][0.1 Off]... + case 2: /* [0.1 On][0.1 Off]... */ pHwData->LED_Blinking %= 2; - ltmp = 0x0010; // Led 0 red color - if (pHwData->LED_Blinking) // Turn off + ltmp = 0x0010; /* Led 0 red color */ + if (pHwData->LED_Blinking) /* Turn off */ ltmp = 0; break; - case 3: // [0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.5 Off]... + case 3: /* [0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.5 Off]... */ pHwData->LED_Blinking %= 15; - ltmp = 0x0010; // Led 0 red color - if ((pHwData->LED_Blinking >= 9) || (pHwData->LED_Blinking % 2)) // Turn off 0.6 sec + ltmp = 0x0010; /* Led 0 red color */ + if ((pHwData->LED_Blinking >= 9) || (pHwData->LED_Blinking % 2)) /* Turn off 0.6 sec */ ltmp = 0; break; - case 4: // [300 On][ off ] - ltmp = 0x1000; // Led 1 Green color + case 4: /* [300 On][ off ] */ + ltmp = 0x1000; /* Led 1 Green color */ if (pHwData->LED_Blinking >= 3000) - ltmp = 0; // led maybe on after 300sec * 32bit counter overlap. + ltmp = 0; /* led maybe on after 300sec * 32bit counter overlap. */ break; } pHwData->LED_Blinking++; reg->U1BC_LEDConfigure = ltmp; - if (LEDSet != 7) // Only 111 mode has 2 LEDs on PCB. - { - reg->U1BC_LEDConfigure |= (ltmp & 0xff) << 8; // Copy LED result to each LED control register + if (LEDSet != 7) { /* Only 111 mode has 2 LEDs on PCB. */ + reg->U1BC_LEDConfigure |= (ltmp & 0xff) << 8; /* Copy LED result to each LED control register */ reg->U1BC_LEDConfigure |= (ltmp & 0xff00) >> 8; } Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); } - } else if (pHwData->CurrentRadioSw || pHwData->CurrentRadioHw) // If radio off - { + } else if (pHwData->CurrentRadioSw || pHwData->CurrentRadioHw) { /* If radio off */ if (reg->U1BC_LEDConfigure & 0x1010) { reg->U1BC_LEDConfigure &= ~0x1010; Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); } } else { switch (LEDSet) { - case 4: // [100] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing - if (!pHwData->LED_LinkOn) // Blink only if not Link On - { - // Blinking if scanning is on progress + case 4: /* [100] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing */ + if (!pHwData->LED_LinkOn) { /* Blink only if not Link On */ + /* Blinking if scanning is on progress */ if (pHwData->LED_Scanning) { if (pHwData->LED_Blinking == 0) { reg->U1BC_LEDConfigure |= 0x10; - Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 On + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 On */ pHwData->LED_Blinking = 1; TimeInterval = 300; } else { reg->U1BC_LEDConfigure &= ~0x10; - Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */ pHwData->LED_Blinking = 0; TimeInterval = 300; } } else { - //Turn Off LED_0 + /* Turn Off LED_0 */ if (reg->U1BC_LEDConfigure & 0x10) { reg->U1BC_LEDConfigure &= ~0x10; - Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */ } } } else { - // Turn On LED_0 + /* Turn On LED_0 */ if ((reg->U1BC_LEDConfigure & 0x10) == 0) { reg->U1BC_LEDConfigure |= 0x10; - Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */ } } break; - - case 6: // [110] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing - if (!pHwData->LED_LinkOn) // Blink only if not Link On - { - // Blinking if scanning is on progress + case 6: /* [110] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing */ + if (!pHwData->LED_LinkOn) { /* Blink only if not Link On */ + /* Blinking if scanning is on progress */ if (pHwData->LED_Scanning) { if (pHwData->LED_Blinking == 0) { reg->U1BC_LEDConfigure &= ~0xf; reg->U1BC_LEDConfigure |= 0x10; - Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 On + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 On */ pHwData->LED_Blinking = 1; TimeInterval = 300; } else { reg->U1BC_LEDConfigure &= ~0x1f; - Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */ pHwData->LED_Blinking = 0; TimeInterval = 300; } } else { - // 20060901 Gray blinking if in disconnect state and not scanning + /* Gray blinking if in disconnect state and not scanning */ ltmp = reg->U1BC_LEDConfigure; reg->U1BC_LEDConfigure &= ~0x1f; if (LED_GRAY2[(pHwData->LED_Blinking % 30)]) { @@ -494,85 +484,78 @@ static void hal_led_control(unsigned long data) } pHwData->LED_Blinking++; if (reg->U1BC_LEDConfigure != ltmp) - Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */ TimeInterval = 100; } } else { - // Turn On LED_0 + /* Turn On LED_0 */ if ((reg->U1BC_LEDConfigure & 0x10) == 0) { reg->U1BC_LEDConfigure |= 0x10; - Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_0 Off + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_0 Off */ } } break; - - case 5: // [101] Only 1 Led be placed on PCB and use LED_1 for showing - if (!pHwData->LED_LinkOn) // Blink only if not Link On - { - // Blinking if scanning is on progress + case 5: /* [101] Only 1 Led be placed on PCB and use LED_1 for showing */ + if (!pHwData->LED_LinkOn) { /* Blink only if not Link On */ + /* Blinking if scanning is on progress */ if (pHwData->LED_Scanning) { if (pHwData->LED_Blinking == 0) { - reg->U1BC_LEDConfigure |= - 0x1000; - Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 On + reg->U1BC_LEDConfigure |= 0x1000; + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 On */ pHwData->LED_Blinking = 1; TimeInterval = 300; } else { - reg->U1BC_LEDConfigure &= - ~0x1000; - Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 Off + reg->U1BC_LEDConfigure &= ~0x1000; + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 Off */ pHwData->LED_Blinking = 0; TimeInterval = 300; } } else { - //Turn Off LED_1 + /* Turn Off LED_1 */ if (reg->U1BC_LEDConfigure & 0x1000) { - reg->U1BC_LEDConfigure &= - ~0x1000; - Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 Off + reg->U1BC_LEDConfigure &= ~0x1000; + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 Off */ } } } else { - // Is transmitting/receiving ?? + /* Is transmitting/receiving ?? */ if ((adapter->RxByteCount != pHwData->RxByteCountLast) || (adapter->TxByteCount != pHwData->TxByteCountLast)) { if ((reg->U1BC_LEDConfigure & 0x3000) != 0x3000) { - reg->U1BC_LEDConfigure |= - 0x3000; - Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 On + reg->U1BC_LEDConfigure |= 0x3000; + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 On */ } - // Update variable + /* Update variable */ pHwData->RxByteCountLast = adapter->RxByteCount; pHwData->TxByteCountLast = adapter->TxByteCount; TimeInterval = 200; } else { - // Turn On LED_1 and blinking if transmitting/receiving + /* Turn On LED_1 and blinking if transmitting/receiving */ if ((reg->U1BC_LEDConfigure & 0x3000) != 0x1000) { reg->U1BC_LEDConfigure &= ~0x3000; reg->U1BC_LEDConfigure |= 0x1000; - Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); // LED_1 On + Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); /* LED_1 On */ } } } break; - - default: // Default setting. 2 LED be placed on PCB. LED_0: Link On LED_1 Active + default: /* Default setting. 2 LED be placed on PCB. LED_0: Link On LED_1 Active */ if ((reg->U1BC_LEDConfigure & 0x3000) != 0x3000) { - reg->U1BC_LEDConfigure |= 0x3000; // LED_1 is always on and event enable + reg->U1BC_LEDConfigure |= 0x3000; /* LED_1 is always on and event enable */ Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); } if (pHwData->LED_Blinking) { - // Gray blinking + /* Gray blinking */ reg->U1BC_LEDConfigure &= ~0x0f; reg->U1BC_LEDConfigure |= 0x10; reg->U1BC_LEDConfigure |= @@ -584,7 +567,7 @@ static void hal_led_control(unsigned long data) if (pHwData->LED_Blinking < 40) TimeInterval = 100; else { - pHwData->LED_Blinking = 0; // Stop blinking + pHwData->LED_Blinking = 0; /* Stop blinking */ reg->U1BC_LEDConfigure &= ~0x0f; Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); @@ -593,16 +576,14 @@ static void hal_led_control(unsigned long data) } if (pHwData->LED_LinkOn) { - if (!(reg->U1BC_LEDConfigure & 0x10)) // Check the LED_0 - { - //Try to turn ON LED_0 after gray blinking + if (!(reg->U1BC_LEDConfigure & 0x10)) { /* Check the LED_0 */ + /* Try to turn ON LED_0 after gray blinking */ reg->U1BC_LEDConfigure |= 0x10; - pHwData->LED_Blinking = 1; //Start blinking + pHwData->LED_Blinking = 1; /* Start blinking */ TimeInterval = 50; } } else { - if (reg->U1BC_LEDConfigure & 0x10) // Check the LED_0 - { + if (reg->U1BC_LEDConfigure & 0x10) { /* Check the LED_0 */ reg->U1BC_LEDConfigure &= ~0x10; Wb35Reg_Write(pHwData, 0x03bc, reg->U1BC_LEDConfigure); @@ -611,7 +592,7 @@ static void hal_led_control(unsigned long data) break; } - //20060828.1 Active send null packet to avoid AP disconnect + /* Active send null packet to avoid AP disconnect */ if (pHwData->LED_LinkOn) { pHwData->NullPacketCount += TimeInterval; if (pHwData->NullPacketCount >= @@ -622,7 +603,7 @@ static void hal_led_control(unsigned long data) } pHwData->time_count += TimeInterval; - Wb35Tx_CurrentTime(adapter, pHwData->time_count); // 20060928 add + Wb35Tx_CurrentTime(adapter, pHwData->time_count); pHwData->LEDTimer.expires = jiffies + msecs_to_jiffies(TimeInterval); add_timer(&pHwData->LEDTimer); } @@ -654,7 +635,7 @@ static int hal_init_hardware(struct ieee80211_hw *hw) SoftwareSet = hal_software_set(pHwData); #ifdef Vendor2 - // Try to make sure the EEPROM contain + /* Try to make sure the EEPROM contain */ SoftwareSet >>= 8; if (SoftwareSet != 0x82) return false; -- cgit v1.2.3 From 5813b6243cf02b89c6e6a6a8debc10477e5ce3a8 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Mon, 15 Mar 2010 21:27:42 +0200 Subject: Staging: wlan-ng: fix spaces coding style issue in p80211conv.c This is a patch to the p80211conv.c file that fixed up a TAB and spaces Errors found by the checkpatch.pl tools, like spaces required around that '&' (ctx:VxV) Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211conv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c index a1605fbc8092..71c3595fe830 100644 --- a/drivers/staging/wlan-ng/p80211conv.c +++ b/drivers/staging/wlan-ng/p80211conv.c @@ -208,7 +208,7 @@ int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv, p80211_wep->data = kmalloc(skb->len, GFP_ATOMIC); foo = wep_encrypt(wlandev, skb->data, p80211_wep->data, skb->len, - (wlandev->hostwep &HOSTWEP_DEFAULTKEY_MASK), + (wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK), p80211_wep->iv, p80211_wep->icv); if (foo) { printk(KERN_WARNING -- cgit v1.2.3 From 4ffab688827361bcdaca6ac83bbda195c53bd098 Mon Sep 17 00:00:00 2001 From: Edgardo Hames Date: Mon, 15 Mar 2010 23:00:40 -0300 Subject: Staging: wlan-ng: rework code style after feedback This patch includes the feedback received from Richard Kennedy. Signed-off-by: Edgardo Hames Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/hfa384x_usb.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c index 2400242e2d87..a41db5dc8c7c 100644 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -2612,19 +2612,18 @@ int hfa384x_drvr_start(hfa384x_t *hw) if (result1 != 0) { if (result2 != 0) { printk(KERN_ERR - "cmd_initialize() failed on two attempts," - " results %d and %d\n", result1, result2); + "cmd_initialize() failed on two attempts, results %d and %d\n", + result1, result2); usb_kill_urb(&hw->rx_urb); goto done; } else { pr_debug("First cmd_initialize() failed (result %d),\n", result1); - pr_debug("but second attempt succeeded." - " All should be ok\n"); + pr_debug("but second attempt succeeded. All should be ok\n"); } } else if (result2 != 0) { - printk(KERN_WARNING "First cmd_initialize() succeeded," - " but second attempt failed (result=%d)\n", result2); + printk(KERN_WARNING "First cmd_initialize() succeeded, but second attempt failed (result=%d)\n", + result2); printk(KERN_WARNING "Most likely the card will be functional\n"); goto done; @@ -3382,9 +3381,7 @@ retry: * our request has been acknowledged. Odd, * but our OUT URB is still alive... */ - pr_debug("Causality violation: " - "please reboot Universe, or email " - "linux-wlan-devel@lists.linux-wlan.com\n"); + pr_debug("Causality violation: please reboot Universe\n"); ctlx->state = CTLX_RESP_COMPLETE; break; @@ -3848,8 +3845,8 @@ retry: default: /* This is NOT a valid CTLX "success" state! */ - printk(KERN_ERR "Illegal CTLX[%d]" - " success state(%s, %d) in OUT URB\n", + printk(KERN_ERR + "Illegal CTLX[%d] success state(%s, %d) in OUT URB\n", le16_to_cpu(ctlx->outbuf.type), ctlxstr(ctlx->state), urb->status); break; -- cgit v1.2.3 From 9d3b3bb0b5807b9305e8c9e2688603f785ead0cd Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Wed, 17 Mar 2010 14:40:55 +0000 Subject: Staging: wlan-ng: tidy up iw_handler Use array initialisation technique copied from ipw2200.c. This should always get the function pointers in the correct place, without the needed for endless counting, skipping blanks etc. Signed-off-by: Richard Kennedy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211wext.c | 98 ++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 56 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/p80211wext.c b/drivers/staging/wlan-ng/p80211wext.c index dc72661f0661..936be55a5ffb 100644 --- a/drivers/staging/wlan-ng/p80211wext.c +++ b/drivers/staging/wlan-ng/p80211wext.c @@ -1680,64 +1680,50 @@ static int p80211_wext_get_iwauth(struct net_device *dev, return result; } +#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT] + static iw_handler p80211wext_handlers[] = { - (iw_handler) p80211wext_siwcommit, /* SIOCSIWCOMMIT */ - (iw_handler) p80211wext_giwname, /* SIOCGIWNAME */ - (iw_handler) NULL, /* SIOCSIWNWID */ - (iw_handler) NULL, /* SIOCGIWNWID */ - (iw_handler) p80211wext_siwfreq, /* SIOCSIWFREQ */ - (iw_handler) p80211wext_giwfreq, /* SIOCGIWFREQ */ - (iw_handler) p80211wext_siwmode, /* SIOCSIWMODE */ - (iw_handler) p80211wext_giwmode, /* SIOCGIWMODE */ - (iw_handler) NULL, /* SIOCSIWSENS */ - (iw_handler) NULL, /* SIOCGIWSENS */ - (iw_handler) NULL, /* not used *//* SIOCSIWRANGE */ - (iw_handler) p80211wext_giwrange, /* SIOCGIWRANGE */ - (iw_handler) NULL, /* not used *//* SIOCSIWPRIV */ - (iw_handler) NULL, /* kernel code *//* SIOCGIWPRIV */ - (iw_handler) NULL, /* not used *//* SIOCSIWSTATS */ - (iw_handler) NULL, /* kernel code *//* SIOCGIWSTATS */ - (iw_handler) p80211wext_siwspy, /* SIOCSIWSPY */ - (iw_handler) p80211wext_giwspy, /* SIOCGIWSPY */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* SIOCSIWAP */ - (iw_handler) p80211wext_giwap, /* SIOCGIWAP */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* SIOCGIWAPLIST */ - (iw_handler) p80211wext_siwscan, /* SIOCSIWSCAN */ - (iw_handler) p80211wext_giwscan, /* SIOCGIWSCAN */ - (iw_handler) p80211wext_siwessid, /* SIOCSIWESSID */ - (iw_handler) p80211wext_giwessid, /* SIOCGIWESSID */ - (iw_handler) NULL, /* SIOCSIWNICKN */ - (iw_handler) p80211wext_giwessid, /* SIOCGIWNICKN */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* SIOCSIWRATE */ - (iw_handler) p80211wext_giwrate, /* SIOCGIWRATE */ - (iw_handler) p80211wext_siwrts, /* SIOCSIWRTS */ - (iw_handler) p80211wext_giwrts, /* SIOCGIWRTS */ - (iw_handler) p80211wext_siwfrag, /* SIOCSIWFRAG */ - (iw_handler) p80211wext_giwfrag, /* SIOCGIWFRAG */ - (iw_handler) p80211wext_siwtxpow, /* SIOCSIWTXPOW */ - (iw_handler) p80211wext_giwtxpow, /* SIOCGIWTXPOW */ - (iw_handler) p80211wext_siwretry, /* SIOCSIWRETRY */ - (iw_handler) p80211wext_giwretry, /* SIOCGIWRETRY */ - (iw_handler) p80211wext_siwencode, /* SIOCSIWENCODE */ - (iw_handler) p80211wext_giwencode, /* SIOCGIWENCODE */ - (iw_handler) NULL, /* SIOCSIWPOWER */ - (iw_handler) NULL, /* SIOCGIWPOWER */ + IW_IOCTL(SIOCSIWCOMMIT) = (iw_handler) p80211wext_siwcommit, + IW_IOCTL(SIOCGIWNAME) = (iw_handler) p80211wext_giwname, +/* SIOCSIWNWID,SIOCGIWNWID */ + IW_IOCTL(SIOCSIWFREQ) = (iw_handler) p80211wext_siwfreq, + IW_IOCTL(SIOCGIWFREQ) = (iw_handler) p80211wext_giwfreq, + IW_IOCTL(SIOCSIWMODE) = (iw_handler) p80211wext_siwmode, + IW_IOCTL(SIOCGIWMODE) = (iw_handler) p80211wext_giwmode, +/* SIOCSIWSENS,SIOCGIWSENS,SIOCSIWRANGE */ + IW_IOCTL(SIOCGIWRANGE) = (iw_handler) p80211wext_giwrange, +/* SIOCSIWPRIV,SIOCGIWPRIV,SIOCSIWSTATS,SIOCGIWSTATS */ + IW_IOCTL(SIOCSIWSPY) = (iw_handler) p80211wext_siwspy, + IW_IOCTL(SIOCGIWSPY) = (iw_handler) p80211wext_giwspy, +/* SIOCSIWAP */ + IW_IOCTL(SIOCGIWAP) = (iw_handler) p80211wext_giwap, +/* SIOCGIWAPLIST */ + IW_IOCTL(SIOCSIWSCAN) = (iw_handler) p80211wext_siwscan, + IW_IOCTL(SIOCGIWSCAN) = (iw_handler) p80211wext_giwscan, + IW_IOCTL(SIOCSIWESSID) = (iw_handler) p80211wext_siwessid, + IW_IOCTL(SIOCGIWESSID) = (iw_handler) p80211wext_giwessid, +/* SIOCSIWNICKN */ + IW_IOCTL(SIOCGIWNICKN) = (iw_handler) p80211wext_giwessid, +/* SIOCSIWRATE */ + IW_IOCTL(SIOCGIWRATE) = (iw_handler) p80211wext_giwrate, + IW_IOCTL(SIOCSIWRTS) = (iw_handler) p80211wext_siwrts, + IW_IOCTL(SIOCGIWRTS) = (iw_handler) p80211wext_giwrts, + IW_IOCTL(SIOCSIWFRAG) = (iw_handler) p80211wext_siwfrag, + IW_IOCTL(SIOCGIWFRAG) = (iw_handler) p80211wext_giwfrag, + IW_IOCTL(SIOCSIWTXPOW) = (iw_handler) p80211wext_siwtxpow, + IW_IOCTL(SIOCGIWTXPOW) = (iw_handler) p80211wext_giwtxpow, + IW_IOCTL(SIOCSIWRETRY) = (iw_handler) p80211wext_siwretry, + IW_IOCTL(SIOCGIWRETRY) = (iw_handler) p80211wext_giwretry, + IW_IOCTL(SIOCSIWENCODE) = (iw_handler) p80211wext_siwencode, + IW_IOCTL(SIOCGIWENCODE) = (iw_handler) p80211wext_giwencode, +/* SIOCSIWPOWER,SIOCGIWPOWER */ /* WPA operations */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* SIOCSIWGENIE set generic IE */ - (iw_handler) NULL, /* SIOCGIWGENIE get generic IE */ - (iw_handler) p80211_wext_set_iwauth, /* SIOCSIWAUTH set authentication mode params */ - (iw_handler) p80211_wext_get_iwauth, /* SIOCGIWAUTH get authentication mode params */ - - (iw_handler) p80211wext_set_encodeext, /* SIOCSIWENCODEEXT set encoding token & mode */ - (iw_handler) p80211wext_get_encodeext, /* SIOCGIWENCODEEXT get encoding token & mode */ - (iw_handler) NULL, /* SIOCSIWPMKSA PMKSA cache operation */ +/* SIOCSIWGENIE,SIOCGIWGENIE generic IE */ + IW_IOCTL(SIOCSIWAUTH) = (iw_handler) p80211_wext_set_iwauth, /*set authentication mode params */ + IW_IOCTL(SIOCGIWAUTH) = (iw_handler) p80211_wext_get_iwauth, /*get authentication mode params */ + IW_IOCTL(SIOCSIWENCODEEXT) = (iw_handler) p80211wext_set_encodeext, /*set encoding token & mode */ + IW_IOCTL(SIOCGIWENCODEEXT) = (iw_handler) p80211wext_get_encodeext, /*get encoding token & mode */ +/* SIOCSIWPMKSA PMKSA cache operation */ }; struct iw_handler_def p80211wext_handler_def = { -- cgit v1.2.3 From 044bc96bef5e78d4bb9b5c7ad12814afafb901cf Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Wed, 17 Mar 2010 14:40:56 +0000 Subject: Staging: wlan-ng: fix p80211wext_mhz_to_channel for channel 14 Channel 14 is 2484 Mhz (cf p80211wext_channel_to_mhz) so this patch corrects what seems to be just a typo. Signed-off-by: Richard Kennedy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211wext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/p80211wext.c b/drivers/staging/wlan-ng/p80211wext.c index 936be55a5ffb..e1b54094d954 100644 --- a/drivers/staging/wlan-ng/p80211wext.c +++ b/drivers/staging/wlan-ng/p80211wext.c @@ -73,7 +73,7 @@ static u8 p80211_mhz_to_channel(u16 mhz) if (mhz >= 5000) return (mhz - 5000) / 5; - if (mhz == 2482) + if (mhz == 2484) return 14; if (mhz >= 2407) -- cgit v1.2.3 From 51b2a028699c5a1f05e130d2e4d0773332f0f45e Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Wed, 17 Mar 2010 14:40:57 +0000 Subject: Staging: wlan-ng: refactor p80211wext.c to reduce text size. Refactor the wext interface to reduce lines of code & module text size. - add a helper function p80211wext_getmib - rename p80211wext_dorequest to p80211wext_setmib - refactor wext to call the get/set mib helpers and so reduce repeated code. size reported text reduction :- text data bss dec hex filename 8343 720 0 9063 2367 p80211wext.o.patch 9907 720 0 10631 2987 p80211wext.o.orig Tested on x86_32 laptop, everything works correctly using NetworkManager, and iwconfig & iwlist return sensible results when reading from the card. Signed-off-by: Richard Kennedy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211wext.c | 298 ++++++++++++++--------------------- 1 file changed, 116 insertions(+), 182 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/p80211wext.c b/drivers/staging/wlan-ng/p80211wext.c index e1b54094d954..387194d4a6eb 100644 --- a/drivers/staging/wlan-ng/p80211wext.c +++ b/drivers/staging/wlan-ng/p80211wext.c @@ -125,18 +125,38 @@ static int qual_as_percent(int snr) return 100; } -static int p80211wext_dorequest(wlandevice_t *wlandev, u32 did, u32 data) +static int p80211wext_setmib(wlandevice_t *wlandev, u32 did, u32 data) { p80211msg_dot11req_mibset_t msg; - p80211item_uint32_t mibitem; + p80211item_uint32_t *mibitem = + (p80211item_uint32_t *)&msg.mibattribute.data; int result; msg.msgcode = DIDmsg_dot11req_mibset; - memset(&mibitem, 0, sizeof(mibitem)); - mibitem.did = did; - mibitem.data = data; - memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + memset(mibitem, 0, sizeof(*mibitem)); + mibitem->did = did; + mibitem->data = data; + result = p80211req_dorequest(wlandev, (u8 *) &msg); + + return result; +} + +/* + * get a 32 bit mib value + */ +static int p80211wext_getmib(wlandevice_t *wlandev, u32 did, u32 *data) +{ + p80211msg_dot11req_mibset_t msg; + p80211item_uint32_t *mibitem = + (p80211item_uint32_t *)&msg.mibattribute.data; + int result; + + msg.msgcode = DIDmsg_dot11req_mibget; + memset(mibitem, 0, sizeof(*mibitem)); + mibitem->did = did; result = p80211req_dorequest(wlandev, (u8 *) &msg); + if (!result) + *data = mibitem->data; return result; } @@ -262,32 +282,26 @@ static int p80211wext_giwfreq(netdevice_t *dev, struct iw_freq *freq, char *extra) { wlandevice_t *wlandev = dev->ml_priv; - p80211item_uint32_t mibitem; - p80211msg_dot11req_mibset_t msg; int result; int err = 0; + unsigned int value; - msg.msgcode = DIDmsg_dot11req_mibget; - memset(&mibitem, 0, sizeof(mibitem)); - mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel; - memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) &msg); - + result = p80211wext_getmib(wlandev, + DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel, + &value); if (result) { err = -EFAULT; goto exit; } - memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); - - if (mibitem.data > NUM_CHANNELS) { + if (value > NUM_CHANNELS) { err = -EFAULT; goto exit; } /* convert into frequency instead of a channel */ freq->e = 1; - freq->m = p80211_channel_to_mhz(mibitem.data, 0) * 100000; + freq->m = p80211_channel_to_mhz(value, 0) * 100000; exit: return err; @@ -298,28 +312,23 @@ static int p80211wext_siwfreq(netdevice_t *dev, struct iw_freq *freq, char *extra) { wlandevice_t *wlandev = dev->ml_priv; - p80211item_uint32_t mibitem; - p80211msg_dot11req_mibset_t msg; int result; int err = 0; + unsigned int value; if (!wlan_wext_write) { - err = (-EOPNOTSUPP); + err = -EOPNOTSUPP; goto exit; } - msg.msgcode = DIDmsg_dot11req_mibset; - memset(&mibitem, 0, sizeof(mibitem)); - mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel; - mibitem.status = P80211ENUM_msgitem_status_data_ok; - if ((freq->e == 0) && (freq->m <= 1000)) - mibitem.data = freq->m; + value = freq->m; else - mibitem.data = p80211_mhz_to_channel(freq->m); + value = p80211_mhz_to_channel(freq->m); - memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) &msg); + result = p80211wext_setmib(wlandev, + DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel, + value); if (result) { err = -EFAULT; @@ -359,13 +368,11 @@ static int p80211wext_siwmode(netdevice_t *dev, __u32 *mode, char *extra) { wlandevice_t *wlandev = dev->ml_priv; - p80211item_uint32_t mibitem; - p80211msg_dot11req_mibset_t msg; int result; int err = 0; if (!wlan_wext_write) { - err = (-EOPNOTSUPP); + err = -EOPNOTSUPP; goto exit; } @@ -396,16 +403,11 @@ static int p80211wext_siwmode(netdevice_t *dev, } /* Set Operation mode to the PORT TYPE RID */ - msg.msgcode = DIDmsg_dot11req_mibset; - memset(&mibitem, 0, sizeof(mibitem)); - mibitem.did = DIDmib_p2_p2Static_p2CnfPortType; - mibitem.data = (*mode == IW_MODE_ADHOC) ? 0 : 1; - memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) &msg); - + result = p80211wext_setmib(wlandev, + DIDmib_p2_p2Static_p2CnfPortType, + (*mode == IW_MODE_ADHOC) ? 0 : 1); if (result) err = -EFAULT; - exit: return err; } @@ -562,9 +564,9 @@ static int p80211wext_siwencode(netdevice_t *dev, /* Set current key number only if no keys are given */ if (erq->flags & IW_ENCODE_NOKEY) { result = - p80211wext_dorequest(wlandev, - DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, - i); + p80211wext_setmib(wlandev, + DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, + i); if (result) { err = -EFAULT; @@ -586,7 +588,6 @@ static int p80211wext_siwencode(netdevice_t *dev, -------------------------------------------------------------*/ if (erq->length > 0) { - /* copy the key from the driver cache as the keys are read-only MIBs */ wlandev->wep_keylens[i] = erq->length; memcpy(wlandev->wep_keys[i], key, erq->length); @@ -636,12 +637,12 @@ static int p80211wext_siwencode(netdevice_t *dev, /* Check the PrivacyInvoked flag */ if (erq->flags & IW_ENCODE_DISABLED) { result = - p80211wext_dorequest(wlandev, + p80211wext_setmib(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false); } else { result = - p80211wext_dorequest(wlandev, + p80211wext_setmib(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true); } @@ -660,12 +661,12 @@ static int p80211wext_siwencode(netdevice_t *dev, */ if (erq->flags & IW_ENCODE_RESTRICTED) { result = - p80211wext_dorequest(wlandev, + p80211wext_setmib(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_true); } else if (erq->flags & IW_ENCODE_OPEN) { result = - p80211wext_dorequest(wlandev, + p80211wext_setmib(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_false); } @@ -767,24 +768,16 @@ static int p80211wext_giwrate(netdevice_t *dev, struct iw_param *rrq, char *extra) { wlandevice_t *wlandev = dev->ml_priv; - p80211item_uint32_t mibitem; - p80211msg_dot11req_mibset_t msg; int result; int err = 0; + unsigned int value; - msg.msgcode = DIDmsg_dot11req_mibget; - memset(&mibitem, 0, sizeof(mibitem)); - mibitem.did = DIDmib_p2_p2MAC_p2CurrentTxRate; - memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) &msg); - + result = p80211wext_getmib(wlandev, DIDmib_p2_p2MAC_p2CurrentTxRate, &value); if (result) { err = -EFAULT; goto exit; } - memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); - rrq->fixed = 0; /* can it change? */ rrq->disabled = 0; rrq->value = 0; @@ -794,7 +787,7 @@ static int p80211wext_giwrate(netdevice_t *dev, #define HFA384x_RATEBIT_5dot5 ((u16)4) #define HFA384x_RATEBIT_11 ((u16)8) - switch (mibitem.data) { + switch (value) { case HFA384x_RATEBIT_1: rrq->value = 1000000; break; @@ -819,25 +812,19 @@ static int p80211wext_giwrts(netdevice_t *dev, struct iw_param *rts, char *extra) { wlandevice_t *wlandev = dev->ml_priv; - p80211item_uint32_t mibitem; - p80211msg_dot11req_mibset_t msg; int result; int err = 0; + unsigned int value; - msg.msgcode = DIDmsg_dot11req_mibget; - memset(&mibitem, 0, sizeof(mibitem)); - mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold; - memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) &msg); - + result = p80211wext_getmib(wlandev, + DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold, + &value); if (result) { err = -EFAULT; goto exit; } - memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); - - rts->value = mibitem.data; + rts->value = value; rts->disabled = (rts->value == 2347); rts->fixed = 1; @@ -850,27 +837,23 @@ static int p80211wext_siwrts(netdevice_t *dev, struct iw_param *rts, char *extra) { wlandevice_t *wlandev = dev->ml_priv; - p80211item_uint32_t mibitem; - p80211msg_dot11req_mibset_t msg; int result; int err = 0; + unsigned int value; if (!wlan_wext_write) { - err = (-EOPNOTSUPP); + err = -EOPNOTSUPP; goto exit; } - msg.msgcode = DIDmsg_dot11req_mibget; - memset(&mibitem, 0, sizeof(mibitem)); - mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold; if (rts->disabled) - mibitem.data = 2347; + value = 2347; else - mibitem.data = rts->value; - - memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) &msg); + value = rts->value; + result = p80211wext_setmib(wlandev, + DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold, + value); if (result) { err = -EFAULT; goto exit; @@ -885,26 +868,19 @@ static int p80211wext_giwfrag(netdevice_t *dev, struct iw_param *frag, char *extra) { wlandevice_t *wlandev = dev->ml_priv; - p80211item_uint32_t mibitem; - p80211msg_dot11req_mibset_t msg; int result; int err = 0; + unsigned int value; - msg.msgcode = DIDmsg_dot11req_mibget; - memset(&mibitem, 0, sizeof(mibitem)); - mibitem.did = - DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold; - memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) &msg); - + result = p80211wext_getmib(wlandev, + DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold, + &value); if (result) { err = -EFAULT; goto exit; } - memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); - - frag->value = mibitem.data; + frag->value = value; frag->disabled = (frag->value == 2346); frag->fixed = 1; @@ -917,28 +893,23 @@ static int p80211wext_siwfrag(netdevice_t *dev, struct iw_param *frag, char *extra) { wlandevice_t *wlandev = dev->ml_priv; - p80211item_uint32_t mibitem; - p80211msg_dot11req_mibset_t msg; int result; int err = 0; + int value; if (!wlan_wext_write) { err = (-EOPNOTSUPP); goto exit; } - msg.msgcode = DIDmsg_dot11req_mibset; - memset(&mibitem, 0, sizeof(mibitem)); - mibitem.did = - DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold; - if (frag->disabled) - mibitem.data = 2346; + value = 2346; else - mibitem.data = frag->value; + value = frag->value; - memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) &msg); + result = p80211wext_setmib(wlandev, + DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold, + value); if (result) { err = -EFAULT; @@ -962,56 +933,40 @@ static int p80211wext_giwretry(netdevice_t *dev, struct iw_param *rrq, char *extra) { wlandevice_t *wlandev = dev->ml_priv; - p80211item_uint32_t mibitem; - p80211msg_dot11req_mibset_t msg; int result; int err = 0; u16 shortretry, longretry, lifetime; + unsigned int value; - msg.msgcode = DIDmsg_dot11req_mibget; - memset(&mibitem, 0, sizeof(mibitem)); - mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit; - - memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) &msg); - + result = p80211wext_getmib(wlandev, + DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit, + &value); if (result) { err = -EFAULT; goto exit; } - memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); - - shortretry = mibitem.data; - - mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit; - - memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) &msg); + shortretry = value; + result = p80211wext_getmib(wlandev, + DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit, + &value); if (result) { err = -EFAULT; goto exit; } - memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); - - longretry = mibitem.data; - - mibitem.did = - DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime; - - memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) &msg); + longretry = value; + result = p80211wext_getmib(wlandev, + DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime, + &value); if (result) { err = -EFAULT; goto exit; } - memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); - - lifetime = mibitem.data; + lifetime = value; rrq->disabled = 0; @@ -1044,8 +999,7 @@ static int p80211wext_siwretry(netdevice_t *dev, p80211msg_dot11req_mibset_t msg; int result; int err = 0; - - memset(&mibitem, 0, sizeof(mibitem)); + unsigned int value; if (!wlan_wext_write) { err = (-EOPNOTSUPP); @@ -1060,26 +1014,20 @@ static int p80211wext_siwretry(netdevice_t *dev, msg.msgcode = DIDmsg_dot11req_mibset; if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { - mibitem.did = - DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime; - mibitem.data = rrq->value /= 1024; - - memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) &msg); + value = rrq->value /= 1024; + result = p80211wext_setmib(wlandev, + DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime, + value); if (result) { err = -EFAULT; goto exit; } } else { if (rrq->flags & IW_RETRY_LONG) { - mibitem.did = - DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit; - mibitem.data = rrq->value; - - memcpy(&msg.mibattribute.data, &mibitem, - sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) &msg); + result = p80211wext_setmib(wlandev, + DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit, + rrq->value); if (result) { err = -EFAULT; @@ -1088,13 +1036,9 @@ static int p80211wext_siwretry(netdevice_t *dev, } if (rrq->flags & IW_RETRY_SHORT) { - mibitem.did = - DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit; - mibitem.data = rrq->value; - - memcpy(&msg.mibattribute.data, &mibitem, - sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) &msg); + result = p80211wext_setmib(wlandev, + DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit, + rrq->value); if (result) { err = -EFAULT; @@ -1117,22 +1061,20 @@ static int p80211wext_siwtxpow(netdevice_t *dev, p80211msg_dot11req_mibset_t msg; int result; int err = 0; + unsigned int value; if (!wlan_wext_write) { err = (-EOPNOTSUPP); goto exit; } - msg.msgcode = DIDmsg_dot11req_mibset; - memset(&mibitem, 0, sizeof(mibitem)); - mibitem.did = - DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel; if (rrq->fixed == 0) - mibitem.data = 30; + value = 30; else - mibitem.data = rrq->value; - memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) &msg); + value = rrq->value; + result = p80211wext_setmib(wlandev, + DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel, + value); if (result) { err = -EFAULT; @@ -1148,33 +1090,25 @@ static int p80211wext_giwtxpow(netdevice_t *dev, struct iw_param *rrq, char *extra) { wlandevice_t *wlandev = dev->ml_priv; - p80211item_uint32_t mibitem; - p80211msg_dot11req_mibset_t msg; int result; int err = 0; + unsigned int value; - msg.msgcode = DIDmsg_dot11req_mibget; - - memset(&mibitem, 0, sizeof(mibitem)); - mibitem.did = - DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel; - - memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); - result = p80211req_dorequest(wlandev, (u8 *) &msg); + result = p80211wext_getmib(wlandev, + DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel, + &value); if (result) { err = -EFAULT; goto exit; } - memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); - /* XXX handle OFF by setting disabled = 1; */ rrq->flags = 0; /* IW_TXPOW_DBM; */ rrq->disabled = 0; rrq->fixed = 0; - rrq->value = mibitem.data; + rrq->value = value; exit: return err; @@ -1479,7 +1413,7 @@ static int p80211wext_set_encodeext(struct net_device *dev, } pr_debug("setting default key (%d)\n", idx); result = - p80211wext_dorequest(wlandev, + p80211wext_setmib(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, idx); if (result) @@ -1599,12 +1533,12 @@ static int p80211_wext_set_iwauth(struct net_device *dev, pr_debug("drop_unencrypted %d\n", param->value); if (param->value) result = - p80211wext_dorequest(wlandev, + p80211wext_setmib(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_true); else result = - p80211wext_dorequest(wlandev, + p80211wext_setmib(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_false); break; @@ -1613,12 +1547,12 @@ static int p80211_wext_set_iwauth(struct net_device *dev, pr_debug("privacy invoked %d\n", param->value); if (param->value) result = - p80211wext_dorequest(wlandev, + p80211wext_setmib(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true); else result = - p80211wext_dorequest(wlandev, + p80211wext_setmib(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false); -- cgit v1.2.3 From b93634c4e38e3fbe476b53b1e68ec391ad0ecc86 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Mon, 15 Mar 2010 22:46:24 +0200 Subject: Staging: wlags49_h2: fix spaces, macros and comments coding style issue in debug.h This is a patch to the debug.h file that fixed up a TAB and spaces Errors found by the checkpatch.pl tools, like spaces required around that '&' (ctx:VxV) and ERROR: Invalid UTF-8, patch and commit message should be encoded in UTF-8 and do not use C99 // comments and Macros with complex values should be enclosed in parenthesis Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/debug.h | 104 +++++++++++++++++++++---------------- 1 file changed, 59 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlags49_h2/debug.h b/drivers/staging/wlags49_h2/debug.h index 0b52e17b3011..2c3dd140a35f 100644 --- a/drivers/staging/wlags49_h2/debug.h +++ b/drivers/staging/wlags49_h2/debug.h @@ -22,7 +22,7 @@ * software indicates your acceptance of these terms and conditions. If you do * not agree with these terms and conditions, do not use the software. * - * Copyright © 2003 Agere Systems Inc. + * Copyright (c) 2003 Agere Systems Inc. * All rights reserved. * * Redistribution and use in source or binary forms, with or without @@ -70,7 +70,7 @@ #else #undef DBG #define DBG 1 -#endif //DBG +#endif /* DBG */ @@ -84,7 +84,7 @@ #ifndef DBG_LVL #define DBG_LVL 5 /* yields nothing via init_module, original value of 5 yields DBG_TRACE_ON and DBG_VERBOSE_ON */ -#endif // DBG_LVL +#endif /* DBG_LVL*/ #define DBG_ERROR_ON 0x00000001L @@ -100,80 +100,94 @@ #define DBG_DEFAULTS (DBG_ERROR_ON | DBG_WARNING_ON | DBG_BREAK_ON) -#define DBG_FLAGS(A) (A)->DebugFlag -#define DBG_NAME(A) (A)->dbgName -#define DBG_LEVEL(A) (A)->dbgLevel +#define DBG_FLAGS(A) ((A)->DebugFlag) +#define DBG_NAME(A) ((A)->dbgName) +#define DBG_LEVEL(A) ((A)->dbgLevel) #ifndef PRINTK # define PRINTK(S...) printk(S) -#endif // PRINTK +#endif /* PRINTK */ #ifndef DBG_PRINT # define DBG_PRINT(S...) PRINTK(KERN_DEBUG S) -#endif // DBG_PRINT +#endif /* DBG_PRINT */ #ifndef DBG_PRINTC # define DBG_PRINTC(S...) PRINTK(S) -#endif // DBG_PRINTC +#endif /* DBG_PRINTC */ #ifndef DBG_TRAP # define DBG_TRAP {} -#endif // DBG_TRAP +#endif /* DBG_TRAP */ #define _ENTER_STR ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" #define _LEAVE_STR "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" -#define _DBG_ENTER(A) DBG_PRINT("%s:%.*s:%s\n",DBG_NAME(A),++DBG_LEVEL(A),_ENTER_STR,__FUNC__) -#define _DBG_LEAVE(A) DBG_PRINT("%s:%.*s:%s\n",DBG_NAME(A),DBG_LEVEL(A)--,_LEAVE_STR,__FUNC__) +#define _DBG_ENTER(A) DBG_PRINT("%s:%.*s:%s\n", DBG_NAME(A), ++DBG_LEVEL(A), _ENTER_STR, __FUNC__) +#define _DBG_LEAVE(A) DBG_PRINT("%s:%.*s:%s\n", DBG_NAME(A), DBG_LEVEL(A)--, _LEAVE_STR, __FUNC__) #define DBG_FUNC(F) static const char *__FUNC__ = F; -#define DBG_ENTER(A) {if (DBG_FLAGS(A) & DBG_TRACE_ON) _DBG_ENTER(A);} +#define DBG_ENTER(A) {if (DBG_FLAGS(A) & DBG_TRACE_ON) \ + _DBG_ENTER(A); } -#define DBG_LEAVE(A) {if (DBG_FLAGS(A) & DBG_TRACE_ON) _DBG_LEAVE(A);} +#define DBG_LEAVE(A) {if (DBG_FLAGS(A) & DBG_TRACE_ON) \ + _DBG_LEAVE(A); } -#define DBG_PARAM(A,N,F,S...) {if (DBG_FLAGS(A) & DBG_PARAM_ON) \ - DBG_PRINT(" %s -- "F"\n",N,S);} +#define DBG_PARAM(A, N, F, S...) {if (DBG_FLAGS(A) & DBG_PARAM_ON) \ + DBG_PRINT(" %s -- "F"\n", N, S); } -#define DBG_ERROR(A,S...) {if (DBG_FLAGS(A) & DBG_ERROR_ON) \ - {DBG_PRINT("%s:ERROR:%s ",DBG_NAME(A),__FUNC__);DBG_PRINTC(S);DBG_TRAP;}} +#define DBG_ERROR(A, S...) {if (DBG_FLAGS(A) & DBG_ERROR_ON) {\ + DBG_PRINT("%s:ERROR:%s ", DBG_NAME(A), __FUNC__);\ + DBG_PRINTC(S); \ + DBG_TRAP; \ + } \ + } -#define DBG_WARNING(A,S...) {if (DBG_FLAGS(A) & DBG_WARNING_ON) \ - {DBG_PRINT("%s:WARNING:%s ",DBG_NAME(A),__FUNC__);DBG_PRINTC(S);}} +#define DBG_WARNING(A, S...) {if (DBG_FLAGS(A) & DBG_WARNING_ON) {\ + DBG_PRINT("%s:WARNING:%s ", DBG_NAME(A), __FUNC__);\ + DBG_PRINTC(S); } } -#define DBG_NOTICE(A,S...) {if (DBG_FLAGS(A) & DBG_NOTICE_ON) \ - {DBG_PRINT("%s:NOTICE:%s ",DBG_NAME(A),__FUNC__);DBG_PRINTC(S);}} +#define DBG_NOTICE(A, S...) {if (DBG_FLAGS(A) & DBG_NOTICE_ON) {\ + DBG_PRINT("%s:NOTICE:%s ", DBG_NAME(A), __FUNC__);\ + DBG_PRINTC(S); \ + } \ + } -#define DBG_TRACE(A,S...) do {if (DBG_FLAGS(A) & DBG_TRACE_ON) \ - {DBG_PRINT("%s:%s ",DBG_NAME(A),__FUNC__);DBG_PRINTC(S);}} while (0) +#define DBG_TRACE(A, S...) do {if (DBG_FLAGS(A) & DBG_TRACE_ON) {\ + DBG_PRINT("%s:%s ", DBG_NAME(A), __FUNC__);\ + DBG_PRINTC(S); } } while (0) -#define DBG_RX(A,S...) {if (DBG_FLAGS(A) & DBG_RX_ON) \ - {DBG_PRINT(S);}} +#define DBG_RX(A, S...) {if (DBG_FLAGS(A) & DBG_RX_ON) {\ + DBG_PRINT(S); } } -#define DBG_TX(A,S...) {if (DBG_FLAGS(A) & DBG_TX_ON) \ - {DBG_PRINT(S);}} +#define DBG_TX(A, S...) {if (DBG_FLAGS(A) & DBG_TX_ON) {\ + DBG_PRINT(S); } } -#define DBG_DS(A,S...) {if (DBG_FLAGS(A) & DBG_DS_ON) \ - {DBG_PRINT(S);}} +#define DBG_DS(A, S...) {if (DBG_FLAGS(A) & DBG_DS_ON) {\ + DBG_PRINT(S); } } -#define DBG_ASSERT(C) {if (!(C)) \ - {DBG_PRINT("ASSERT(%s) -- %s#%d (%s)\n", \ - #C,__FILE__,__LINE__,__FUNC__); \ - DBG_TRAP;}} +#define DBG_ASSERT(C) { \ + if (!(C)) {\ + DBG_PRINT("ASSERT(%s) -- %s#%d (%s)\n", \ + #C, __FILE__, __LINE__, __FUNC__); \ + DBG_TRAP; \ + } \ + } typedef struct { char *dbgName; @@ -183,7 +197,7 @@ typedef struct { /****************************************************************************/ -#else // DBG +#else /* DBG */ /****************************************************************************/ #define DBG_DEFN @@ -192,21 +206,21 @@ typedef struct { #define DBG_PRINT(S...) #define DBG_ENTER(A) #define DBG_LEAVE(A) -#define DBG_PARAM(A,N,F,S...) -#define DBG_ERROR(A,S...) -#define DBG_WARNING(A,S...) -#define DBG_NOTICE(A,S...) -#define DBG_TRACE(A,S...) -#define DBG_RX(A,S...) -#define DBG_TX(A,S...) -#define DBG_DS(A,S...) +#define DBG_PARAM(A, N, F, S...) +#define DBG_ERROR(A, S...) +#define DBG_WARNING(A, S...) +#define DBG_NOTICE(A, S...) +#define DBG_TRACE(A, S...) +#define DBG_RX(A, S...) +#define DBG_TX(A, S...) +#define DBG_DS(A, S...) #define DBG_ASSERT(C) -#endif // DBG +#endif /* DBG */ /****************************************************************************/ -#endif // _DEBUG_H +#endif /* _DEBUG_H */ -- cgit v1.2.3 From 0a13dfdffcef1e72cd4edf9bb9b03d8a3f5fea70 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Mon, 15 Mar 2010 23:29:02 +0200 Subject: Staging: wlags49_h2: fix comments coding style issue in ap_h2.c This is a patch to the ap_h2.c file that fixed up a TAB and spaces Errors found by the checkpatch.pl tools, like do not use C99 // comments Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/ap_h2.c | 70 +++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlags49_h2/ap_h2.c b/drivers/staging/wlags49_h2/ap_h2.c index f5123d2cb4c1..e31149813891 100644 --- a/drivers/staging/wlags49_h2/ap_h2.c +++ b/drivers/staging/wlags49_h2/ap_h2.c @@ -25,10 +25,10 @@ */ -#include "hcfcfg.h" // to get hcf_16 etc defined as well as - // possible settings which inluence mdd.h or dhf.h -#include "mdd.h" //to get COMP_ID_STA etc defined -#include "dhf.h" //used to be "fhfmem.h", to get memblock,plugrecord, +#include "hcfcfg.h" /* to get hcf_16 etc defined as well as */ + /* possible settings which inluence mdd.h or dhf.h */ +#include "mdd.h" /* to get COMP_ID_STA etc defined */ +#include "dhf.h" /* used to be "fhfmem.h", to get memblock,plugrecord, */ static const hcf_8 fw_image_1_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -3241,56 +3241,56 @@ static const CFG_IDENTITY_STRCT fw_image_infoidentity[] = { sizeof( CFG_IDENTITY_STRCT ) / sizeof(hcf_16) - 1, CFG_FW_IDENTITY, COMP_ID_FW_AP, - 2, //Variant - 2, //Major - 36 //Minor + 2, /* Variant / + 2, /* Major */ + 36 /* Minor */ }, - { 0000, 0000, 0000, 0000, 0000, 0000 } //endsentinel + { 0000, 0000, 0000, 0000, 0000, 0000 } /* endsentinel */ }; static const CFG_PROG_STRCT fw_image_code[] = { { 8, CFG_PROG, - CFG_PROG_VOLATILE, // mode - 0x0146, // sizeof(fw_image_1_data), - 0x00000060, // Target address in NIC Memory - 0x0000, // CRC: yes/no TYPE: primary/station/tertiary + CFG_PROG_VOLATILE, /* mode */ + 0x0146, /* sizeof(fw_image_1_data), */ + 0x00000060, /* Target address in NIC Memory */ + 0x0000, /* CRC: yes/no TYPE: primary/station/tertiary */ (hcf_8 FAR *) fw_image_1_data }, { 8, CFG_PROG, - CFG_PROG_VOLATILE, // mode - 0x1918, // sizeof(fw_image_2_data), - 0x00000C16, // Target address in NIC Memory - 0x0000, // CRC: yes/no TYPE: primary/station/tertiary + CFG_PROG_VOLATILE, /* mode */ + 0x1918, /* sizeof(fw_image_2_data), */ + 0x00000C16, /* Target address in NIC Memory */ + 0x0000, /* CRC: yes/no TYPE: primary/station/tertiary */ (hcf_8 FAR *) fw_image_2_data }, { 8, CFG_PROG, - CFG_PROG_VOLATILE, // mode - 0x01bc, // sizeof(fw_image_3_data), - 0x001E252E, // Target address in NIC Memory - 0x0000, // CRC: yes/no TYPE: primary/station/tertiary + CFG_PROG_VOLATILE, /* mode */ + 0x01bc, /* sizeof(fw_image_3_data), */ + 0x001E252E, /* Target address in NIC Memory */ + 0x0000, /* CRC: yes/no TYPE: primary/station/tertiary */ (hcf_8 FAR *) fw_image_3_data }, { 8, CFG_PROG, - CFG_PROG_VOLATILE, // mode - 0xab28, // sizeof(fw_image_4_data), - 0x001F4000, // Target address in NIC Memory - 0x0000, // CRC: yes/no TYPE: primary/station/tertiary + CFG_PROG_VOLATILE, /* mode */ + 0xab28, /* sizeof(fw_image_4_data), */ + 0x001F4000, /* Target address in NIC Memory */ + 0x0000, /* CRC: yes/no TYPE: primary/station/tertiary */ (hcf_8 FAR *) fw_image_4_data }, { 5, CFG_PROG, - CFG_PROG_STOP, // mode + CFG_PROG_STOP, /* mode*/ 0000, - 0x000F1297, // Start execution address + 0x000F1297, /* Start execution address */ }, { 0000, 0000, 0000, 0000, 00000000, 0000, 00000000} }; @@ -3301,7 +3301,7 @@ static const CFG_RANGE20_STRCT fw_image_infocompat[] = { COMP_ROLE_SUPL, COMP_ID_APF, { - { 2, 2, 4 } //variant, bottom, top + { 2, 2, 4 } /* variant, bottom, top */ } }, { 3 + ((20 * sizeof(CFG_RANGE_SPEC_STRCT)) / sizeof(hcf_16)), @@ -3309,9 +3309,9 @@ static const CFG_RANGE20_STRCT fw_image_infocompat[] = { COMP_ROLE_ACT, COMP_ID_MFI, { - { 4, 6, 7 }, //variant, bottom, top - { 5, 6, 7 }, //variant, bottom, top - { 6, 6, 7 } //variant, bottom, top + { 4, 6, 7 }, /* variant, bottom, top */ + { 5, 6, 7 }, /* variant, bottom, top */ + { 6, 6, 7 } /* variant, bottom, top */ } }, { 3 + ((20 * sizeof(CFG_RANGE_SPEC_STRCT)) / sizeof(hcf_16)), @@ -3319,18 +3319,18 @@ static const CFG_RANGE20_STRCT fw_image_infocompat[] = { COMP_ROLE_ACT, COMP_ID_CFI, { - { 2, 1, 2 } //variant, bottom, top + { 2, 1, 2 } /* variant, bottom, top */ } }, - { 0000, 0000, 0000, 0000, { { 0000, 0000, 0000 } } } //endsentinel + { 0000, 0000, 0000, 0000, { { 0000, 0000, 0000 } } } /* endsentinel */ }; memimage fw_image = { - "FUPU7D37dhfwci\001C", //signature, , C/Bin type + "FUPU7D37dhfwci\001C", /* signature, , C/Bin type */ (CFG_PROG_STRCT *) fw_image_code, 0x000F1297, - 00000000, //(dummy) pdaplug - 00000000, //(dummy) priplug + 00000000, /* (dummy) pdaplug */ + 00000000, /* (dummy) priplug */ (CFG_RANGE20_STRCT *) fw_image_infocompat, (CFG_IDENTITY_STRCT *) fw_image_infoidentity, }; -- cgit v1.2.3 From 01ce33545f2ef939ef73a93974b89c92a27e5522 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Tue, 16 Mar 2010 00:05:34 +0200 Subject: Staging: wlags49_h2: fix TAB and space coding style issue in ap_h2.c This is a patch to the p80211conv.c file that fixed up a TAB and spaces Errors found by the checkpatch.pl tools Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/ap_h2.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlags49_h2/ap_h2.c b/drivers/staging/wlags49_h2/ap_h2.c index e31149813891..eb8244c4d6f0 100644 --- a/drivers/staging/wlags49_h2/ap_h2.c +++ b/drivers/staging/wlags49_h2/ap_h2.c @@ -26,7 +26,7 @@ #include "hcfcfg.h" /* to get hcf_16 etc defined as well as */ - /* possible settings which inluence mdd.h or dhf.h */ + /* possible settings which inluence mdd.h or dhf.h */ #include "mdd.h" /* to get COMP_ID_STA etc defined */ #include "dhf.h" /* used to be "fhfmem.h", to get memblock,plugrecord, */ @@ -3238,7 +3238,7 @@ static const hcf_8 fw_image_4_data[] = { static const CFG_IDENTITY_STRCT fw_image_infoidentity[] = { { - sizeof( CFG_IDENTITY_STRCT ) / sizeof(hcf_16) - 1, + sizeof(CFG_IDENTITY_STRCT) / sizeof(hcf_16) - 1, CFG_FW_IDENTITY, COMP_ID_FW_AP, 2, /* Variant / @@ -3256,7 +3256,7 @@ static const CFG_PROG_STRCT fw_image_code[] = { 0x0146, /* sizeof(fw_image_1_data), */ 0x00000060, /* Target address in NIC Memory */ 0x0000, /* CRC: yes/no TYPE: primary/station/tertiary */ - (hcf_8 FAR *) fw_image_1_data + (hcf_8 FAR *) fw_image_1_data }, { 8, @@ -3265,7 +3265,7 @@ static const CFG_PROG_STRCT fw_image_code[] = { 0x1918, /* sizeof(fw_image_2_data), */ 0x00000C16, /* Target address in NIC Memory */ 0x0000, /* CRC: yes/no TYPE: primary/station/tertiary */ - (hcf_8 FAR *) fw_image_2_data + (hcf_8 FAR *) fw_image_2_data }, { 8, @@ -3274,7 +3274,7 @@ static const CFG_PROG_STRCT fw_image_code[] = { 0x01bc, /* sizeof(fw_image_3_data), */ 0x001E252E, /* Target address in NIC Memory */ 0x0000, /* CRC: yes/no TYPE: primary/station/tertiary */ - (hcf_8 FAR *) fw_image_3_data + (hcf_8 FAR *) fw_image_3_data }, { 8, @@ -3283,14 +3283,14 @@ static const CFG_PROG_STRCT fw_image_code[] = { 0xab28, /* sizeof(fw_image_4_data), */ 0x001F4000, /* Target address in NIC Memory */ 0x0000, /* CRC: yes/no TYPE: primary/station/tertiary */ - (hcf_8 FAR *) fw_image_4_data + (hcf_8 FAR *) fw_image_4_data }, { 5, CFG_PROG, CFG_PROG_STOP, /* mode*/ 0000, - 0x000F1297, /* Start execution address */ + 0x000F1297, /* Start execution address */ }, { 0000, 0000, 0000, 0000, 00000000, 0000, 00000000} }; -- cgit v1.2.3 From fd547f1fead33e55190a1c670575fea467ee24ee Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Tue, 16 Mar 2010 21:48:11 +0200 Subject: Staging: wlags49_h2: fix comments coding style issue in dhf.c This is a patch to the dhf.c file that fixed up a TAB and spaces Errors found by the checkpatch.pl tools, like do not use C99 // comments Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/dhf.c | 74 ++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlags49_h2/dhf.c b/drivers/staging/wlags49_h2/dhf.c index b6f5834b1aff..8997980671f8 100644 --- a/drivers/staging/wlags49_h2/dhf.c +++ b/drivers/staging/wlags49_h2/dhf.c @@ -1,5 +1,5 @@ -// vim:tw=110:ts=4: +/* vim:tw=110:ts=4: */ /************************************************************************************************************** * * FILE : DHF.C @@ -97,7 +97,7 @@ #include "dhf.h" #include "mmd.h" -//to distinguish MMD from HCF asserts by means of line number +/* to distinguish MMD from HCF asserts by means of line number */ #undef FILE_NAME_OFFSET #define FILE_NAME_OFFSET MMD_FILE_NAME_OFFSET /*----------------------------------------------------------------------------- @@ -106,18 +106,18 @@ * *---------------------------------------------------------------------------*/ -// 12345678901234 +/* 12345678901234 */ char signature[14] = "FUPU7D37dhfwci"; -//The binary download function "relocates" the image using constructions like: -// fw->identity = (CFG_IDENTITY_STRCT FAR *)((char FAR *)fw->identity + (hcf_32)fw ); -//under some of the memory models under MSVC 1.52 these constructions degrade to 16-bits pointer arithmetic. -//fw->identity is limited, such that adding it to fw, does not need to carry over from offset to segment. -//However the segment is not set at all. -//As a workaround the PSEUDO_CHARP macro is introduced which is a char pointer except for MSVC 1.52, in -//which case we know that a 32-bit quantity is adequate as a pointer. -//Note that other platforms may experience comparable problems when using the binary download feature. -#if defined(_MSC_VER) && _MSC_VER == 800 // Visual C++ 1.5 +/* The binary download function "relocates" the image using constructions like: + fw->identity = (CFG_IDENTITY_STRCT FAR *)((char FAR *)fw->identity + (hcf_32)fw ); + under some of the memory models under MSVC 1.52 these constructions degrade to 16-bits pointer arithmetic. + fw->identity is limited, such that adding it to fw, does not need to carry over from offset to segment. + However the segment is not set at all. + As a workaround the PSEUDO_CHARP macro is introduced which is a char pointer except for MSVC 1.52, in + which case we know that a 32-bit quantity is adequate as a pointer. + Note that other platforms may experience comparable problems when using the binary download feature. */ +#if defined(_MSC_VER) && _MSC_VER == 800 /* Visual C++ 1.5 */ #define PSEUDO_CHARP hcf_32 #else #define PSEUDO_CHARP hcf_8* @@ -132,12 +132,12 @@ char signature[14] = "FUPU7D37dhfwci"; * *---------------------------------------------------------------------------*/ -// for USB/H1 we needed a smaller value than the CFG_DL_BUF_STRCT reported 8192 -// for the time being it seems simpler to always use 2000 for USB/H1 as well as all other cases rather than -// using the "fixed anyway" CFG_DL_BUF_STRCT. +/* for USB/H1 we needed a smaller value than the CFG_DL_BUF_STRCT reported 8192 + for the time being it seems simpler to always use 2000 for USB/H1 as well as all other cases rather than + using the "fixed anyway" CFG_DL_BUF_STRCT. */ #define DL_SIZE 2000 -//CFG_IDENTITY_STRCT pri_identity = { LOF(CFG_IDENTITY_STRCT), CFG_PRI_IDENTITY }; +/* CFG_IDENTITY_STRCT pri_identity = { LOF(CFG_IDENTITY_STRCT), CFG_PRI_IDENTITY }; */ CFG_SUP_RANGE_STRCT mfi_sup = { LOF(CFG_SUP_RANGE_STRCT), CFG_NIC_MFI_SUP_RANGE }; CFG_SUP_RANGE_STRCT cfi_sup = { LOF(CFG_SUP_RANGE_STRCT), CFG_NIC_CFI_SUP_RANGE }; /* Note: could be used rather than the above explained and defined DL_SIZE if need arises @@ -192,41 +192,41 @@ int rc = HCF_SUCCESS; CFG_RANGE_SPEC_STRCT* i; switch( fw->identity->typ ) { - case CFG_FW_IDENTITY: //Station F/W - case COMP_ID_FW_AP_FAKE: //;?is this useful (used to be: CFG_AP_IDENTITY) + case CFG_FW_IDENTITY: /* Station F/W */ + case COMP_ID_FW_AP_FAKE: /* ;?is this useful (used to be: CFG_AP_IDENTITY) */ break; default: - MMDASSERT( DO_ASSERT, fw->identity->typ ) //unknown/unsupported firmware_type: + MMDASSERT( DO_ASSERT, fw->identity->typ ) /* unknown/unsupported firmware_type: */ rc = DHF_ERR_INCOMP_FW; - return rc; /* ;? how useful is this anyway, + return rc; /* ;? how useful is this anyway, * till that is sorted out might as well violate my own single exit principle */ } p = fw->compat; i = NULL; - while( p->len && i == NULL ) { // check the MFI ranges + while( p->len && i == NULL ) { /* check the MFI ranges */ if ( p->typ == CFG_MFI_ACT_RANGES_STA ) { i = mmd_check_comp( (void*)p, &mfi_sup ); } p++; } - MMDASSERT( i, 0 ) //MFI: NIC Supplier not compatible with F/W image Actor + MMDASSERT( i, 0 ) /* MFI: NIC Supplier not compatible with F/W image Actor */ if ( i ) { p = fw->compat; i = NULL; - while ( p->len && i == NULL ) { // check the CFI ranges + while ( p->len && i == NULL ) { /* check the CFI ranges */ if ( p->typ == CFG_CFI_ACT_RANGES_STA ) { i = mmd_check_comp( (void*)p, &cfi_sup ); } p++; } - MMDASSERT( i, 0 ) //CFI: NIC Supplier not compatible with F/W image Actor + MMDASSERT( i, 0 ) /* CFI: NIC Supplier not compatible with F/W image Actor */ } if ( i == NULL ) { rc = DHF_ERR_INCOMP_FW; } return rc; -} // check_comp_fw +} /* check_comp_fw */ @@ -277,13 +277,13 @@ int rc = HCF_SUCCESS; CFG_PROG_STRCT *p; int i; - //validate the image - for ( i = 0; i < sizeof(signature) && fw->signature[i] == signature[i]; i++ ) /*NOP*/; + /* validate the image */ + for ( i = 0; i < sizeof(signature) && fw->signature[i] == signature[i]; i++ ) /* NOP */; if ( i != sizeof(signature) || fw->signature[i] != 0x01 || - //test for Little/Big Endian Binary flag - fw->signature[i+1] != ( /*HCF_BIG_ENDIAN ? 'B' : */ 'L' ) ) rc = DHF_ERR_INCOMP_FW; - else { //Little Endian Binary format + /* test for Little/Big Endian Binary flag */ + fw->signature[i+1] != ( /* HCF_BIG_ENDIAN ? 'B' : */ 'L' ) ) rc = DHF_ERR_INCOMP_FW; + else { /* Little Endian Binary format */ fw->codep = (CFG_PROG_STRCT FAR *)((PSEUDO_CHARP)fw->codep + (hcf_32)fw ); fw->identity = (CFG_IDENTITY_STRCT FAR *)((PSEUDO_CHARP)fw->identity + (hcf_32)fw ); fw->compat = (CFG_RANGE20_STRCT FAR *)((PSEUDO_CHARP)fw->compat + (hcf_32)fw ); @@ -295,7 +295,7 @@ int i; } } return rc; -} // dhf_download_binary +} /* dhf_download_binary */ /************************************************************************************************************* @@ -360,17 +360,17 @@ LTVP ltvp; int i; MMDASSERT( fw != NULL, 0 ) - //validate the image - for ( i = 0; i < sizeof(signature) && fw->signature[i] == signature[i]; i++ ) /*NOP*/; + /* validate the image */ + for ( i = 0; i < sizeof(signature) && fw->signature[i] == signature[i]; i++ ) /* NOP */; if ( i != sizeof(signature) || fw->signature[i] != 0x01 || - //check for binary image + /* check for binary image */ ( fw->signature[i+1] != 'C' && fw->signature[i+1] != ( /*HCF_BIG_ENDIAN ? 'B' : */ 'L' ) ) ) rc = DHF_ERR_INCOMP_FW; -// Retrieve all information needed for download from the NIC +/* Retrieve all information needed for download from the NIC */ while ( ( rc == HCF_SUCCESS ) && ( ( ltvp = pp->ltvp) != NULL ) ) { - ltvp->len = pp++->len; // Set len to original len. This len is changed to real len by GET_INFO() + ltvp->len = pp++->len; /* Set len to original len. This len is changed to real len by GET_INFO() */ rc = GET_INFO( ltvp ); MMDASSERT( rc == HCF_SUCCESS, rc ) MMDASSERT( rc == HCF_SUCCESS, ltvp->typ ) @@ -385,6 +385,6 @@ int i; } MMDASSERT( rc == HCF_SUCCESS, rc ) return rc; -} // dhf_download_fw +} /* dhf_download_fw */ -- cgit v1.2.3 From ccc75a583d993c4d51e2b62ae340cebb23ae886f Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Tue, 16 Mar 2010 21:59:22 +0200 Subject: Staging: wlags49_h2: fix copyright style issue in dhf.c This is a patch to the dhf.c file that fixed up a copyright style Errors found by the checkpatch.pl tools Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/dhf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlags49_h2/dhf.c b/drivers/staging/wlags49_h2/dhf.c index 8997980671f8..369036412c68 100644 --- a/drivers/staging/wlags49_h2/dhf.c +++ b/drivers/staging/wlags49_h2/dhf.c @@ -54,8 +54,8 @@ * software indicates your acceptance of these terms and conditions. If you do * not agree with these terms and conditions, do not use the software. * -* COPYRIGHT © 1999 - 2000 by Lucent Technologies. All Rights Reserved -* COPYRIGHT © 2001 - 2004 by Agere Systems Inc. All Rights Reserved +* COPYRIGHT (C) 1999 - 2000 by Lucent Technologies. All Rights Reserved +* COPYRIGHT (C) 2001 - 2004 by Agere Systems Inc. All Rights Reserved * All rights reserved. * * Redistribution and use in source or binary forms, with or without -- cgit v1.2.3 From 068b561c3c96e7a52a4974da457fb8591064d40b Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Wed, 17 Mar 2010 10:14:34 +0200 Subject: Staging: wlags49_h2: fix TAB and space coding style issue dhf.c This is a patch to the dhf.c file that fixed up a TAB and spaces Errors found by the checkpatch.pl tools Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/dhf.c | 88 ++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlags49_h2/dhf.c b/drivers/staging/wlags49_h2/dhf.c index 369036412c68..3af43988b953 100644 --- a/drivers/staging/wlags49_h2/dhf.c +++ b/drivers/staging/wlags49_h2/dhf.c @@ -120,7 +120,7 @@ char signature[14] = "FUPU7D37dhfwci"; #if defined(_MSC_VER) && _MSC_VER == 800 /* Visual C++ 1.5 */ #define PSEUDO_CHARP hcf_32 #else -#define PSEUDO_CHARP hcf_8* +#define PSEUDO_CHARP (hcf_8 *) #endif /*----------------------------------------------------------------------------- @@ -164,7 +164,7 @@ LTV_INFO_STRUCT ltv_info[] = { /***********************************************************************************************************/ /*************************************** PROTOTYPES ******************************************************/ /***********************************************************************************************************/ -static int check_comp_fw( memimage *fw ); +static int check_comp_fw(memimage *fw); /************************************************************************************************************ @@ -185,44 +185,44 @@ static int check_comp_fw( memimage *fw ); *.ENDDOC END DOCUMENTATION *************************************************************************************************************/ int -check_comp_fw( memimage *fw ) +check_comp_fw(memimage *fw) { CFG_RANGE20_STRCT *p; int rc = HCF_SUCCESS; -CFG_RANGE_SPEC_STRCT* i; +CFG_RANGE_SPEC_STRCT *i; - switch( fw->identity->typ ) { - case CFG_FW_IDENTITY: /* Station F/W */ - case COMP_ID_FW_AP_FAKE: /* ;?is this useful (used to be: CFG_AP_IDENTITY) */ + switch (fw->identity->typ) { + case CFG_FW_IDENTITY: /* Station F/W */ + case COMP_ID_FW_AP_FAKE: /* ;?is this useful (used to be: CFG_AP_IDENTITY) */ break; - default: - MMDASSERT( DO_ASSERT, fw->identity->typ ) /* unknown/unsupported firmware_type: */ + default: + MMDASSERT(DO_ASSERT, fw->identity->typ) /* unknown/unsupported firmware_type: */ rc = DHF_ERR_INCOMP_FW; - return rc; /* ;? how useful is this anyway, + return rc; /* ;? how useful is this anyway, * till that is sorted out might as well violate my own single exit principle */ } p = fw->compat; i = NULL; - while( p->len && i == NULL ) { /* check the MFI ranges */ - if ( p->typ == CFG_MFI_ACT_RANGES_STA ) { - i = mmd_check_comp( (void*)p, &mfi_sup ); + while (p->len && i == NULL) { /* check the MFI ranges */ + if (p->typ == CFG_MFI_ACT_RANGES_STA) { + i = mmd_check_comp((void *)p, &mfi_sup); } p++; } - MMDASSERT( i, 0 ) /* MFI: NIC Supplier not compatible with F/W image Actor */ - if ( i ) { + MMDASSERT(i, 0) /* MFI: NIC Supplier not compatible with F/W image Actor */ + if (i) { p = fw->compat; i = NULL; - while ( p->len && i == NULL ) { /* check the CFI ranges */ - if ( p->typ == CFG_CFI_ACT_RANGES_STA ) { - i = mmd_check_comp( (void*)p, &cfi_sup ); + while (p->len && i == NULL) { /* check the CFI ranges */ + if (p->typ == CFG_CFI_ACT_RANGES_STA) { + i = mmd_check_comp((void *)p, &cfi_sup); } p++; } - MMDASSERT( i, 0 ) /* CFI: NIC Supplier not compatible with F/W image Actor */ + MMDASSERT(i, 0) /* CFI: NIC Supplier not compatible with F/W image Actor */ } - if ( i == NULL ) { + if (i == NULL) { rc = DHF_ERR_INCOMP_FW; } return rc; @@ -271,25 +271,25 @@ CFG_RANGE_SPEC_STRCT* i; *.ENDDOC END DOCUMENTATION *************************************************************************************************************/ int -dhf_download_binary( memimage *fw ) +dhf_download_binary(memimage *fw) { int rc = HCF_SUCCESS; CFG_PROG_STRCT *p; int i; /* validate the image */ - for ( i = 0; i < sizeof(signature) && fw->signature[i] == signature[i]; i++ ) /* NOP */; - if ( i != sizeof(signature) || + for (i = 0; i < sizeof(signature) && fw->signature[i] == signature[i]; i++); /* NOP */ + if (i != sizeof(signature) || fw->signature[i] != 0x01 || /* test for Little/Big Endian Binary flag */ - fw->signature[i+1] != ( /* HCF_BIG_ENDIAN ? 'B' : */ 'L' ) ) rc = DHF_ERR_INCOMP_FW; + fw->signature[i+1] != (/* HCF_BIG_ENDIAN ? 'B' : */ 'L')) rc = DHF_ERR_INCOMP_FW; else { /* Little Endian Binary format */ - fw->codep = (CFG_PROG_STRCT FAR *)((PSEUDO_CHARP)fw->codep + (hcf_32)fw ); - fw->identity = (CFG_IDENTITY_STRCT FAR *)((PSEUDO_CHARP)fw->identity + (hcf_32)fw ); - fw->compat = (CFG_RANGE20_STRCT FAR *)((PSEUDO_CHARP)fw->compat + (hcf_32)fw ); - for ( i = 0; fw->p[i]; i++ ) fw->p[i] = ((PSEUDO_CHARP)fw->p[i] + (hcf_32)fw ); + fw->codep = (CFG_PROG_STRCT FAR*)((PSEUDO_CHARP)fw->codep + (hcf_32)fw); + fw->identity = (CFG_IDENTITY_STRCT FAR*)((PSEUDO_CHARP)fw->identity + (hcf_32)fw); + fw->compat = (CFG_RANGE20_STRCT FAR*)((PSEUDO_CHARP)fw->compat + (hcf_32)fw); + for (i = 0; fw->p[i]; i++) fw->p[i] = ((PSEUDO_CHARP)fw->p[i] + (hcf_32)fw); p = fw->codep; - while ( p->len ) { + while (p->len) { p->host_addr = (PSEUDO_CHARP)p->host_addr + (hcf_32)fw; p++; } @@ -351,7 +351,7 @@ int i; *.ENDDOC END DOCUMENTATION *************************************************************************************************************/ int -dhf_download_fw( void *ifbp, memimage *fw ) +dhf_download_fw(void *ifbp, memimage *fw) { int rc = HCF_SUCCESS; LTV_INFO_STRUCT_PTR pp = ltv_info; @@ -359,31 +359,31 @@ CFG_PROG_STRCT *p = fw->codep; LTVP ltvp; int i; - MMDASSERT( fw != NULL, 0 ) + MMDASSERT(fw != NULL, 0) /* validate the image */ - for ( i = 0; i < sizeof(signature) && fw->signature[i] == signature[i]; i++ ) /* NOP */; - if ( i != sizeof(signature) || + for (i = 0; i < sizeof(signature) && fw->signature[i] == signature[i]; i++) /* NOP */; + if (i != sizeof(signature) || fw->signature[i] != 0x01 || /* check for binary image */ - ( fw->signature[i+1] != 'C' && fw->signature[i+1] != ( /*HCF_BIG_ENDIAN ? 'B' : */ 'L' ) ) ) + (fw->signature[i+1] != 'C' && fw->signature[i+1] != (/*HCF_BIG_ENDIAN ? 'B' : */ 'L'))) rc = DHF_ERR_INCOMP_FW; /* Retrieve all information needed for download from the NIC */ - while ( ( rc == HCF_SUCCESS ) && ( ( ltvp = pp->ltvp) != NULL ) ) { + while ((rc == HCF_SUCCESS) && ((ltvp = pp->ltvp) != NULL)) { ltvp->len = pp++->len; /* Set len to original len. This len is changed to real len by GET_INFO() */ - rc = GET_INFO( ltvp ); - MMDASSERT( rc == HCF_SUCCESS, rc ) - MMDASSERT( rc == HCF_SUCCESS, ltvp->typ ) - MMDASSERT( rc == HCF_SUCCESS, ltvp->len ) + rc = GET_INFO(ltvp); + MMDASSERT(rc == HCF_SUCCESS, rc) + MMDASSERT(rc == HCF_SUCCESS, ltvp->typ) + MMDASSERT(rc == HCF_SUCCESS, ltvp->len) } - if ( rc == HCF_SUCCESS ) rc = check_comp_fw( fw ); - if ( rc == HCF_SUCCESS ) { - while ( rc == HCF_SUCCESS && p->len ) { - rc = PUT_INFO( p ); + if (rc == HCF_SUCCESS) rc = check_comp_fw(fw); + if (rc == HCF_SUCCESS) { + while (rc == HCF_SUCCESS && p->len) { + rc = PUT_INFO(p); p++; } } - MMDASSERT( rc == HCF_SUCCESS, rc ) + MMDASSERT(rc == HCF_SUCCESS, rc) return rc; } /* dhf_download_fw */ -- cgit v1.2.3 From 437de951eca9c831dc69a47b58603b1d8d9cbf82 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Wed, 17 Mar 2010 11:02:49 +0200 Subject: Staging: wlags49_h2: fix trailing statements coding style issue in dhf.c This is a patch to the dhf.c file that fixed up a trailing statements Errors found by the checkpatch.pl tools, like trailing statements should be on next line Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/dhf.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlags49_h2/dhf.c b/drivers/staging/wlags49_h2/dhf.c index 3af43988b953..d5fb1a97e855 100644 --- a/drivers/staging/wlags49_h2/dhf.c +++ b/drivers/staging/wlags49_h2/dhf.c @@ -278,16 +278,19 @@ CFG_PROG_STRCT *p; int i; /* validate the image */ - for (i = 0; i < sizeof(signature) && fw->signature[i] == signature[i]; i++); /* NOP */ + for (i = 0; i < sizeof(signature) && fw->signature[i] == signature[i]; i++) + ; /* NOP */ if (i != sizeof(signature) || fw->signature[i] != 0x01 || /* test for Little/Big Endian Binary flag */ - fw->signature[i+1] != (/* HCF_BIG_ENDIAN ? 'B' : */ 'L')) rc = DHF_ERR_INCOMP_FW; + fw->signature[i+1] != (/* HCF_BIG_ENDIAN ? 'B' : */ 'L')) + rc = DHF_ERR_INCOMP_FW; else { /* Little Endian Binary format */ fw->codep = (CFG_PROG_STRCT FAR*)((PSEUDO_CHARP)fw->codep + (hcf_32)fw); fw->identity = (CFG_IDENTITY_STRCT FAR*)((PSEUDO_CHARP)fw->identity + (hcf_32)fw); fw->compat = (CFG_RANGE20_STRCT FAR*)((PSEUDO_CHARP)fw->compat + (hcf_32)fw); - for (i = 0; fw->p[i]; i++) fw->p[i] = ((PSEUDO_CHARP)fw->p[i] + (hcf_32)fw); + for (i = 0; fw->p[i]; i++) + fw->p[i] = ((PSEUDO_CHARP)fw->p[i] + (hcf_32)fw); p = fw->codep; while (p->len) { p->host_addr = (PSEUDO_CHARP)p->host_addr + (hcf_32)fw; @@ -361,7 +364,8 @@ int i; MMDASSERT(fw != NULL, 0) /* validate the image */ - for (i = 0; i < sizeof(signature) && fw->signature[i] == signature[i]; i++) /* NOP */; + for (i = 0; i < sizeof(signature) && fw->signature[i] == signature[i]; i++) + ; /* NOP */ if (i != sizeof(signature) || fw->signature[i] != 0x01 || /* check for binary image */ @@ -376,7 +380,8 @@ int i; MMDASSERT(rc == HCF_SUCCESS, ltvp->typ) MMDASSERT(rc == HCF_SUCCESS, ltvp->len) } - if (rc == HCF_SUCCESS) rc = check_comp_fw(fw); + if (rc == HCF_SUCCESS) + rc = check_comp_fw(fw); if (rc == HCF_SUCCESS) { while (rc == HCF_SUCCESS && p->len) { rc = PUT_INFO(p); -- cgit v1.2.3 From 7adea182f1fcaac3c0f37007a15d27f80ef56b85 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Sat, 20 Mar 2010 09:24:44 +0200 Subject: Staging: wlags49_h2: fix copyright and space style issue in dhf.h This is a patch to the dhf.h file that fixed up a copyright anf space style Errors found by the checkpatch.pl tools Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/dhf.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlags49_h2/dhf.h b/drivers/staging/wlags49_h2/dhf.h index c071f342a655..13abcdd6282e 100644 --- a/drivers/staging/wlags49_h2/dhf.h +++ b/drivers/staging/wlags49_h2/dhf.h @@ -38,9 +38,9 @@ * software indicates your acceptance of these terms and conditions. If you do * not agree with these terms and conditions, do not use the software. * -* COPYRIGHT © 1994 - 1995 by AT&T. All Rights Reserved -* COPYRIGHT © 1999 - 2000 by Lucent Technologies. All Rights Reserved -* COPYRIGHT © 2001 - 2004 by Agere Systems Inc. All Rights Reserved +* COPYRIGHT (C) 1994 - 1995 by AT&T. All Rights Reserved +* COPYRIGHT (C) 1999 - 2000 by Lucent Technologies. All Rights Reserved +* COPYRIGHT (C) 2001 - 2004 by Agere Systems Inc. All Rights Reserved * All rights reserved. * * Redistribution and use in source or binary forms, with or without @@ -85,11 +85,11 @@ #include "hcf.h" // includes HCFCFG.H too #ifdef DHF_UIL -#define GET_INFO( pp ) uil_get_info( (LTVP)pp ) -#define PUT_INFO( pp ) uil_put_info( (LTVP)pp ) +#define GET_INFO(pp) uil_get_info((LTVP)pp) +#define PUT_INFO(pp) uil_put_info((LTVP)pp) #else -#define GET_INFO( pp ) hcf_get_info( ifbp, (LTVP)pp ) -#define PUT_INFO( pp ) hcf_put_info( ifbp, (LTVP)pp ) +#define GET_INFO(pp) hcf_get_info(ifbp, (LTVP)pp) +#define PUT_INFO(pp) hcf_put_info(ifbp, (LTVP)pp) #endif @@ -189,9 +189,9 @@ typedef struct { */ typedef struct { char signature[14+1+1]; // signature (see DHF.C) + C/LE-Bin/BE-Bin-flag + format version - CFG_PROG_STRCT FAR *codep; // + CFG_PROG_STRCT FAR * codep; // hcf_32 execution; // Execution address of the firmware - void FAR *place_holder_1; + void FAR * place_holder_1; void FAR *place_holder_2; CFG_RANGE20_STRCT FAR *compat; // Pointer to the compatibility info records CFG_IDENTITY_STRCT FAR *identity; // Pointer to the identity info records @@ -209,8 +209,8 @@ typedef struct { * *---------------------------------------------------------------------------*/ -EXTERN_C int dhf_download_fw( void *ifbp, memimage *fw ); // ifbp, ignored when using the UIL -EXTERN_C int dhf_download_binary( memimage *fw ); +EXTERN_C int dhf_download_fw(void *ifbp, memimage *fw); // ifbp, ignored when using the UIL +EXTERN_C int dhf_download_binary(memimage *fw); /*----------------------------------------------------------------------------- @@ -220,7 +220,7 @@ EXTERN_C int dhf_download_binary( memimage *fw ); *---------------------------------------------------------------------------*/ // defined in DHF.C; see there for comments -EXTERN_C hcf_16 *find_record_in_pda( hcf_16 *pdap, hcf_16 code ); +EXTERN_C hcf_16 *find_record_in_pda(hcf_16 *pdap, hcf_16 code); #endif // DHF_H -- cgit v1.2.3 From 1ef61183ceaf2ebb59df817834c0cc755d99c634 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Sat, 20 Mar 2010 09:24:57 +0200 Subject: Staging: wlags49_h2: fix space and comments style issue in dhf.h This is a patch to the dhf.c file that fixed up a space and comments style Errors found by the checkpatch.pl tools Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/dhf.h | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlags49_h2/dhf.h b/drivers/staging/wlags49_h2/dhf.h index 13abcdd6282e..dbe0611fd032 100644 --- a/drivers/staging/wlags49_h2/dhf.h +++ b/drivers/staging/wlags49_h2/dhf.h @@ -1,5 +1,5 @@ -// vim:tw=110:ts=4: +/* vim:tw=110:ts=4: */ #ifndef DHF_H #define DHF_H @@ -82,7 +82,7 @@ #include #endif -#include "hcf.h" // includes HCFCFG.H too +#include "hcf.h" /* includes HCFCFG.H too */ #ifdef DHF_UIL #define GET_INFO(pp) uil_get_info((LTVP)pp) @@ -94,15 +94,15 @@ /*---- Defines --------------------------------------------------------------*/ -#define CODEMASK 0x0000FFFFL // Codemask for plug records +#define CODEMASK 0x0000FFFFL /* Codemask for plug records */ /*---- Error numbers --------------------------------------------------------*/ -#define DHF_ERR_INCOMP_FW 0x40 //Image not compatible with NIC +#define DHF_ERR_INCOMP_FW 0x40 /* Image not compatible with NIC */ /*---- Type definitions -----------------------------------------------------*/ -//* needed by dhf_wrap.c -// +/* needed by dhf_wrap.c */ + typedef struct { LTVP ltvp; hcf_16 len; @@ -119,9 +119,9 @@ typedef struct { */ typedef struct { - hcf_32 code; // Code to plug - hcf_32 addr; // Address within the memory image to plug it in - hcf_32 len; // The # of bytes which are available to store it + hcf_32 code; /* Code to plug */ + hcf_32 addr; /* Address within the memory image to plug it in */ + hcf_32 len; /* The # of bytes which are available to store it */ } plugrecord; /* @@ -159,7 +159,7 @@ typedef struct { char str[MAX_DEBUGEXPORT_LEN]; } exportrecord; -// Offsets in memimage array p[] +/* Offsets in memimage array p[] */ #define FWSTRINGS_FUNCTION 0 #define FWEXPORTS_FUNCTION 1 @@ -188,13 +188,13 @@ typedef struct { * The end of the array is indicated by a plug record of which all fields are zero. */ typedef struct { - char signature[14+1+1]; // signature (see DHF.C) + C/LE-Bin/BE-Bin-flag + format version - CFG_PROG_STRCT FAR * codep; // - hcf_32 execution; // Execution address of the firmware - void FAR * place_holder_1; + char signature[14+1+1]; /* signature (see DHF.C) + C/LE-Bin/BE-Bin-flag + format version */ + CFG_PROG_STRCT FAR *codep; /* */ + hcf_32 execution; /* Execution address of the firmware */ + void FAR *place_holder_1; void FAR *place_holder_2; - CFG_RANGE20_STRCT FAR *compat; // Pointer to the compatibility info records - CFG_IDENTITY_STRCT FAR *identity; // Pointer to the identity info records + CFG_RANGE20_STRCT FAR *compat; /* Pointer to the compatibility info records */ + CFG_IDENTITY_STRCT FAR *identity; /* Pointer to the identity info records */ void FAR *p[2]; /* (Up to 9) pointers for (future) expansion * currently in use: * - F/W printf information @@ -209,7 +209,7 @@ typedef struct { * *---------------------------------------------------------------------------*/ -EXTERN_C int dhf_download_fw(void *ifbp, memimage *fw); // ifbp, ignored when using the UIL +EXTERN_C int dhf_download_fw(void *ifbp, memimage *fw); /* ifbp, ignored when using the UIL */ EXTERN_C int dhf_download_binary(memimage *fw); @@ -219,8 +219,8 @@ EXTERN_C int dhf_download_binary(memimage *fw); * *---------------------------------------------------------------------------*/ -// defined in DHF.C; see there for comments +/* defined in DHF.C; see there for comments */ EXTERN_C hcf_16 *find_record_in_pda(hcf_16 *pdap, hcf_16 code); -#endif // DHF_H +#endif /* DHF_H */ -- cgit v1.2.3 From fa51929f66ce7953714df1193b13750c39871065 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Sat, 20 Mar 2010 09:36:15 +0200 Subject: Staging: wlags49_h2: fix copyright and comments style issue in dhfcfg.h This is a patch to the dhfcfg.h file that fixed up a copyright and commets style Errors found by the checkpatch.pl tools Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/dhfcfg.h | 118 ++++++++++++++++++------------------ 1 file changed, 59 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlags49_h2/dhfcfg.h b/drivers/staging/wlags49_h2/dhfcfg.h index a0c26c678c59..75c279f268ae 100644 --- a/drivers/staging/wlags49_h2/dhfcfg.h +++ b/drivers/staging/wlags49_h2/dhfcfg.h @@ -22,7 +22,7 @@ * software indicates your acceptance of these terms and conditions. If you do * not agree with these terms and conditions, do not use the software. * - * Copyright © 2003 Agere Systems Inc. + * Copyright (c) 2003 Agere Systems Inc. * All rights reserved. * * Redistribution and use in source or binary forms, with or without @@ -77,82 +77,82 @@ *---------------------------------------------------------------------------*/ -// Define DHF_WCI if you want to use the WCI to access the ORiNOCO card. -// Define DHF_UIL if you want to use the UIL to access the ORiNOCO card. -// You must define either DHF_WCI or DHF_UIL. If neither of the two is defined -// or both a compile error is generated. +/* Define DHF_WCI if you want to use the WCI to access the ORiNOCO card. + Define DHF_UIL if you want to use the UIL to access the ORiNOCO card. + You must define either DHF_WCI or DHF_UIL. If neither of the two is defined + or both a compile error is generated. */ #define DHF_WCI -//!!!#define DHF_UIL +/* !!!#define DHF_UIL */ -// Define DHF_BIG_ENDIAN if you are working on a big endian platform. -// Define DHF_LITTLE_ENDIAN if you are working on a little endian platform. -// You must define either DHF_BIG_ENDIAN or DHF_LITTLE_ENDIAN. If neither of -// the two is defined or both a compile error is generated. +/* Define DHF_BIG_ENDIAN if you are working on a big endian platform. + Define DHF_LITTLE_ENDIAN if you are working on a little endian platform. + You must define either DHF_BIG_ENDIAN or DHF_LITTLE_ENDIAN. If neither of + the two is defined or both a compile error is generated. */ #ifdef USE_BIG_ENDIAN #define DHF_BIG_ENDIAN #else #define DHF_LITTLE_ENDIAN #endif /* USE_BIG_ENDIAN */ -// Define DHF_WIN if you are working on Windows platform. -// Define DHF_DOS if you are working on DOS. -// You must define either DHF_WIN or DHF_DOS. If neither of -// the two is defined or both a compile error is generated. -//!!!#define DHF_WIN -//!!!#define DHF_DOS +/* Define DHF_WIN if you are working on Windows platform. + Define DHF_DOS if you are working on DOS. + You must define either DHF_WIN or DHF_DOS. If neither of + the two is defined or both a compile error is generated. + !!!#define DHF_WIN + !!!#define DHF_DOS */ -// Define if you want the DHF to users. Not defining DHF_GET_RES_MSG -// leads to a decrease in code size as message strings are not included. -//!!!#define DHF_GET_RES_MSG +/* Define if you want the DHF to users. Not defining DHF_GET_RES_MSG + leads to a decrease in code size as message strings are not included. + !!!#define DHF_GET_RES_MSG */ -// Linux driver specific -// Prevent inclusion of stdlib.h and string.h +/* Linux driver specific + Prevent inclusion of stdlib.h and string.h */ #define _INC_STDLIB #define _INC_STRING -//----------------------------------------------------------------------------- -// Define one or more of the following DSF #defines if you want to implement -// the related DSF-function. Function dsf_callback must allways be implemented. -// See file DHF.H for prototypes of the functions. - -// Define DSF_ALLOC if you want to manage memory allocation and de-allocation -// for the DHF. If DSF_ALLOC is defined you must implement dsf_alloc and dsf_free. -//!!!#define DSF_ALLOC - -// Define DSF_CONFIRM if you want the DHF to ask the user for confirmation in a -// number of situations. If DSF_CONFIRM is defined you must implement dsf_confirm. -// Not defining DSF_CONFIRM leads to a decrease in code size as confirmation -// strings are not included. -//!!!#define DSF_CONFIRM - -// Define DSF_DEBUG_MESSAGE if you want debug messages added to your output. -// If you define DSF_DEBUG_MESSAGE then you must implement function -// dsf_debug_message. -//#define DSF_DEBUG_MESSAGE - -// Define DSF_ASSERT if you want asserts to be activated. -// If you define DSF_ASSERT then you must implement function dsf_assert. -//#define DBG 1 -//#define DSF_ASSERT - -// Define DSF_DBWIN if you want asserts and debug messages to be send to a debug -// window like SOFTICE or DebugView from SysInternals. -//!!!#define DSF_DBWIN -//!!! Not implemented yet! - -// Define DSF_VOLATILE_ONLY if you only wants to use valatile functions -// This is a typical setting for a AP and a driver. +/*----------------------------------------------------------------------------- + Define one or more of the following DSF #defines if you want to implement + the related DSF-function. Function dsf_callback must allways be implemented. + See file DHF.H for prototypes of the functions. */ + +/* Define DSF_ALLOC if you want to manage memory allocation and de-allocation + for the DHF. If DSF_ALLOC is defined you must implement dsf_alloc and dsf_free. + !!!#define DSF_ALLOC */ + +/* Define DSF_CONFIRM if you want the DHF to ask the user for confirmation in a + number of situations. If DSF_CONFIRM is defined you must implement dsf_confirm. + Not defining DSF_CONFIRM leads to a decrease in code size as confirmation + strings are not included. + !!!#define DSF_CONFIRM */ + +/* Define DSF_DEBUG_MESSAGE if you want debug messages added to your output. + If you define DSF_DEBUG_MESSAGE then you must implement function + dsf_debug_message. + #define DSF_DEBUG_MESSAGE */ + +/* Define DSF_ASSERT if you want asserts to be activated. + If you define DSF_ASSERT then you must implement function dsf_assert. + #define DBG 1 + #define DSF_ASSERT */ + +/* Define DSF_DBWIN if you want asserts and debug messages to be send to a debug + window like SOFTICE or DebugView from SysInternals. + !!!#define DSF_DBWIN + !!! Not implemented yet! */ + +/* Define DSF_VOLATILE_ONLY if you only wants to use valatile functions + This is a typical setting for a AP and a driver. */ #define DSF_VOLATILE_ONLY -// Define DSF_HERMESII if you want to use the DHF for the Hermes-II +/* Define DSF_HERMESII if you want to use the DHF for the Hermes-II */ #ifdef HERMES2 #define DSF_HERMESII #else #undef DSF_HERMESII -#endif // HERMES2 +#endif /* HERMES2 */ -// Define DSF_BINARY_FILE if you want to use the DHF in combination with -// reading the Firmware from a separate binary file. -//!!!#define DSF_BINARY_FILE +/* Define DSF_BINARY_FILE if you want to use the DHF in combination with + reading the Firmware from a separate binary file. + !!!#define DSF_BINARY_FILE */ -#endif // DHFCFG_H +#endif /* DHFCFG_H */ -- cgit v1.2.3 From 33f84a8f2110afbb819c8336cb73d517fc0b2891 Mon Sep 17 00:00:00 2001 From: Jonas Lundqvist Date: Tue, 16 Mar 2010 15:41:09 +0100 Subject: Staging: phison: fix incorrect tabs in phison.c This patch fixes two incorrect tab warnings found by the checkpatch.pl tool Signed-off-by: Jonas Lundqvist Signed-off-by: Greg Kroah-Hartman --- drivers/staging/phison/phison.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/phison/phison.c b/drivers/staging/phison/phison.c index 0c495eacb75b..42783d7367e3 100644 --- a/drivers/staging/phison/phison.c +++ b/drivers/staging/phison/phison.c @@ -23,7 +23,7 @@ #define PHISON_DEBUG #define DRV_NAME "phison_e-box" /* #0003 */ -#define DRV_VERSION "0.91" /* #0003 */ +#define DRV_VERSION "0.91" /* #0003 */ #define PCI_VENDOR_ID_PHISON 0x1987 #define PCI_DEVICE_ID_PS5000 0x5000 @@ -56,7 +56,7 @@ static int phison_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = ATA_UDMA5, + .udma_mask = ATA_UDMA5, .port_ops = &phison_ops, }; -- cgit v1.2.3 From 8dbe821edfbce4ad3cad2076b32745f0aa08a77e Mon Sep 17 00:00:00 2001 From: Florian Schilhabel Date: Thu, 18 Mar 2010 15:16:47 +0100 Subject: Staging: rtl8192su: refactored EnableHWSecurityConfig8192 and setKey refactored EnableHWSecurityConfig8192 and setKey a bit by replacing if...else if... else with switch...case plus cosmetics Signed-off-by: Florian Schilhabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192su/r8192U_core.c | 119 ++++++++++++++++++-------------- 1 file changed, 68 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index 7fe1cedb3e9a..ca3524c850ff 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c @@ -7612,96 +7612,113 @@ void rtl8192_try_wake_queue(struct net_device *dev, int pri) void EnableHWSecurityConfig8192(struct net_device *dev) { - u8 SECR_value = 0x0; + u8 SECR_value = 0x0; struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - struct ieee80211_device* ieee = priv->ieee80211; + struct ieee80211_device *ieee = priv->ieee80211; SECR_value = SCR_TxEncEnable | SCR_RxDecEnable; -#if 1 - if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2)) - { - SECR_value |= SCR_RxUseDK; - SECR_value |= SCR_TxUseDK; - } - else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP))) - { - SECR_value |= SCR_RxUseDK; - SECR_value |= SCR_TxUseDK; + switch (ieee->pairwise_key_type) { + case KEY_TYPE_WEP40: + case KEY_TYPE_WEP104: + if (priv->ieee80211->auth_mode != 2) { + SECR_value |= SCR_RxUseDK; + SECR_value |= SCR_TxUseDK; + } + break; + case KEY_TYPE_TKIP: + case KEY_TYPE_CCMP: + if (ieee->iw_mode == IW_MODE_ADHOC) { + SECR_value |= SCR_RxUseDK; + SECR_value |= SCR_TxUseDK; + } + break; + default: + break; } -#endif - //add HWSec active enable here. -//default using hwsec. when peer AP is in N mode only and pairwise_key_type is none_aes(which HT_IOT_ACT_PURE_N_MODE indicates it), use software security. when peer AP is in b,g,n mode mixed and pairwise_key_type is none_aes, use g mode hw security. WB on 2008.7.4 + /* + * add HWSec active enable here. + * default using hwsec. + * when peer AP is in N mode only and pairwise_key_type is none_aes + * (which HT_IOT_ACT_PURE_N_MODE indicates it), + * use software security. + * when peer AP is in b,g,n mode mixed and pairwise_key_type is none_aes + * use g mode hw security. + */ ieee->hwsec_active = 1; - if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep)//!ieee->hwsec_support) //add hwsec_support flag to totol control hw_sec on/off - { + /* add hwsec_support flag to totol control hw_sec on/off */ + if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep) { ieee->hwsec_active = 0; SECR_value &= ~SCR_RxDecEnable; } - RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \ - ieee->hwsec_active, ieee->pairwise_key_type, SECR_value); - { - write_nic_byte(dev, SECR, SECR_value);//SECR_value | SCR_UseDK ); - } + RT_TRACE(COMP_SEC, "%s(): hwsec: %d, pairwise_key: %d, " + "SECR_value: %x", + __func__, ieee->hwsec_active, + ieee->pairwise_key_type, SECR_value); + + write_nic_byte(dev, SECR, SECR_value); /* SECR_value | SCR_UseDK ); */ } -void setKey( struct net_device *dev, +void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, u8 *MacAddr, u8 DefaultKey, - u32 *KeyContent ) + u32 *KeyContent) { u32 TargetCommand = 0; u32 TargetContent = 0; u16 usConfig = 0; u8 i; + if (EntryNo >= TOTAL_CAM_ENTRY) - RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n"); + RT_TRACE(COMP_ERR, "%s(): cam entry exceeds TOTAL_CAM_ENTRY", + __func__); - RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr); + RT_TRACE(COMP_SEC, "%s(): dev: %p, EntryNo: %d, " + "KeyIndex: %d, KeyType: %d, MacAddr: %pM", + __func__, dev, EntryNo, + KeyIndex, KeyType, MacAddr); if (DefaultKey) - usConfig |= BIT15 | (KeyType<<2); + usConfig |= BIT15 | (KeyType << 2); else - usConfig |= BIT15 | (KeyType<<2) | KeyIndex; -// usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex; - + usConfig |= BIT15 | (KeyType << 2) | KeyIndex; - for(i=0 ; i Date: Thu, 18 Mar 2010 15:17:29 +0100 Subject: Staging: rtl8192su: refactored FirmwareDownload92S added a new function: FirmwareRequest92S This function(instead of FirmwareDownload92S) is now responsible for requesting the firmware. FirmwareDownload92S is now easier to read, smaller and follows kernel coding style. plus cosmetics. Signed-off-by: Florian Schilhabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192su/r8192S_firmware.c | 236 +++++++++++++++------------- 1 file changed, 126 insertions(+), 110 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192su/r8192S_firmware.c b/drivers/staging/rtl8192su/r8192S_firmware.c index 752a3f1fb3f5..b6ae8543c5ca 100644 --- a/drivers/staging/rtl8192su/r8192S_firmware.c +++ b/drivers/staging/rtl8192su/r8192S_firmware.c @@ -338,143 +338,159 @@ void FirmwareHeaderPriveUpdate(struct net_device *dev, PRT_8192S_FIRMWARE_PRIV pFwPriv->rf_config = FirmwareHeaderMapRfType(dev); } +bool FirmwareRequest92S(struct net_device *dev, rt_firmware *pFirmware) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + bool rtStatus = true; + const char *pFwImageFileName[1] = {"RTL8192SU/rtl8192sfw.bin"}; + u8 *pucMappedFile = NULL; + u32 ulInitStep = 0; + u8 FwHdrSize = RT_8192S_FIRMWARE_HDR_SIZE; + PRT_8192S_FIRMWARE_HDR pFwHdr = NULL; + u32 file_length = 0; + int rc; + const struct firmware *fw_entry; + + rc = request_firmware(&fw_entry, + pFwImageFileName[ulInitStep], + &priv->udev->dev); + if (rc < 0) + goto RequestFirmware_Fail; + + if (fw_entry->size > sizeof(pFirmware->szFwTmpBuffer)) { + RT_TRACE(COMP_ERR, "%s(): image file too large" + "for container buffer", __func__); + release_firmware(fw_entry); + goto RequestFirmware_Fail; + } + + memcpy(pFirmware->szFwTmpBuffer, fw_entry->data, fw_entry->size); + pFirmware->szFwTmpBufferLen = fw_entry->size; + release_firmware(fw_entry); + + pucMappedFile = pFirmware->szFwTmpBuffer; + file_length = pFirmware->szFwTmpBufferLen; + + /* Retrieve FW header. */ + pFirmware->pFwHeader = (PRT_8192S_FIRMWARE_HDR) pucMappedFile; + pFwHdr = pFirmware->pFwHeader; + + RT_TRACE(COMP_FIRMWARE, "%s(): signature: %x, version: %x, " + "size: %x, imemsize: %x, sram size: %x", + __func__, pFwHdr->Signature, pFwHdr->Version, + pFwHdr->DMEMSize, pFwHdr->IMG_IMEM_SIZE, + pFwHdr->IMG_SRAM_SIZE); + + pFirmware->FirmwareVersion = byte(pFwHdr->Version , 0); + + if ((pFwHdr->IMG_IMEM_SIZE == 0) || + (pFwHdr->IMG_IMEM_SIZE > sizeof(pFirmware->FwIMEM))) { + RT_TRACE(COMP_ERR, "%s(): memory for data image is less than" + " IMEM requires", __func__); + goto RequestFirmware_Fail; + } else { + pucMappedFile += FwHdrSize; + /* Retrieve IMEM image. */ + memcpy(pFirmware->FwIMEM, pucMappedFile, pFwHdr->IMG_IMEM_SIZE); + pFirmware->FwIMEMLen = pFwHdr->IMG_IMEM_SIZE; + } + + if (pFwHdr->IMG_SRAM_SIZE > sizeof(pFirmware->FwEMEM)) { + RT_TRACE(COMP_ERR, "%s(): memory for data image is less than" + " EMEM requires", __func__); + goto RequestFirmware_Fail; + } else { + pucMappedFile += pFirmware->FwIMEMLen; + /* Retriecve EMEM image */ + memcpy(pFirmware->FwEMEM, pucMappedFile, pFwHdr->IMG_SRAM_SIZE); + pFirmware->FwEMEMLen = pFwHdr->IMG_SRAM_SIZE; + } + return rtStatus; +RequestFirmware_Fail: + RT_TRACE(COMP_ERR, "%s(): failed with TCR-Status: %x\n", + __func__, read_nic_word(dev, TCR)); + rtStatus = false; + return rtStatus; +} bool FirmwareDownload92S(struct net_device *dev) { - struct r8192_priv *priv = ieee80211_priv(dev); - bool rtStatus = true; - const char *pFwImageFileName[1] = {"RTL8192SU/rtl8192sfw.bin"}; - u8 *pucMappedFile = NULL; - u32 ulFileLength, ulInitStep = 0; - u8 FwHdrSize = RT_8192S_FIRMWARE_HDR_SIZE; - rt_firmware *pFirmware = priv->pFirmware; - u8 FwStatus = FW_STATUS_INIT; - PRT_8192S_FIRMWARE_HDR pFwHdr = NULL; - PRT_8192S_FIRMWARE_PRIV pFwPriv = NULL; - int rc; - const struct firmware *fw_entry; - u32 file_length = 0; + struct r8192_priv *priv = ieee80211_priv(dev); + bool rtStatus = true; + u8 *pucMappedFile = NULL; + u32 ulFileLength; + u8 FwHdrSize = RT_8192S_FIRMWARE_HDR_SIZE; + rt_firmware *pFirmware = priv->pFirmware; + u8 FwStatus = FW_STATUS_INIT; + PRT_8192S_FIRMWARE_HDR pFwHdr = NULL; + PRT_8192S_FIRMWARE_PRIV pFwPriv = NULL; pFirmware->FWStatus = FW_STATUS_INIT; - - RT_TRACE(COMP_FIRMWARE, " --->FirmwareDownload92S()\n"); - -/* -* Load the firmware from RTL8192SU/rtl8192sfw.bin -*/ - if(pFirmware->szFwTmpBufferLen == 0) - { - rc = request_firmware(&fw_entry, pFwImageFileName[ulInitStep],&priv->udev->dev); - if(rc < 0 ) { - RT_TRACE(COMP_ERR, "request firmware fail!\n"); - goto DownloadFirmware_Fail; - } - - if(fw_entry->size > sizeof(pFirmware->szFwTmpBuffer)) { - RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n"); - release_firmware(fw_entry); - goto DownloadFirmware_Fail; - } - - memcpy(pFirmware->szFwTmpBuffer,fw_entry->data,fw_entry->size); - pFirmware->szFwTmpBufferLen = fw_entry->size; - release_firmware(fw_entry); - - pucMappedFile = pFirmware->szFwTmpBuffer; - file_length = pFirmware->szFwTmpBufferLen; - - /* Retrieve FW header. */ - pFirmware->pFwHeader = (PRT_8192S_FIRMWARE_HDR) pucMappedFile; - pFwHdr = pFirmware->pFwHeader; - RT_TRACE(COMP_FIRMWARE,"signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n", \ - pFwHdr->Signature, pFwHdr->Version, pFwHdr->DMEMSize, \ - pFwHdr->IMG_IMEM_SIZE, pFwHdr->IMG_SRAM_SIZE); - pFirmware->FirmwareVersion = byte(pFwHdr->Version ,0); - if ((pFwHdr->IMG_IMEM_SIZE==0) || (pFwHdr->IMG_IMEM_SIZE > sizeof(pFirmware->FwIMEM))) { - RT_TRACE(COMP_ERR, "%s: memory for data image is less than IMEM required\n",\ - __FUNCTION__); - goto DownloadFirmware_Fail; - } else { - pucMappedFile+=FwHdrSize; - /* Retrieve IMEM image. */ - memcpy(pFirmware->FwIMEM, pucMappedFile, pFwHdr->IMG_IMEM_SIZE); - pFirmware->FwIMEMLen = pFwHdr->IMG_IMEM_SIZE; - } - - if (pFwHdr->IMG_SRAM_SIZE > sizeof(pFirmware->FwEMEM)) { - RT_TRACE(COMP_ERR, "%s: memory for data image is less than EMEM required\n",\ - __FUNCTION__); - goto DownloadFirmware_Fail; - } else { - pucMappedFile += pFirmware->FwIMEMLen; - /* Retriecve EMEM image */ - memcpy(pFirmware->FwEMEM, pucMappedFile, pFwHdr->IMG_SRAM_SIZE);//===>6 - pFirmware->FwEMEMLen = pFwHdr->IMG_SRAM_SIZE; - } + /* + * Load the firmware from RTL8192SU/rtl8192sfw.bin if necessary + */ + if (pFirmware->szFwTmpBufferLen == 0) { + if (FirmwareRequest92S(dev, pFirmware) != true) + goto DownloadFirmware_Fail; } - FwStatus = FirmwareGetNextStatus(pFirmware->FWStatus); - while(FwStatus!= FW_STATUS_READY) - { - // Image buffer redirection. - switch(FwStatus) - { - case FW_STATUS_LOAD_IMEM: - pucMappedFile = pFirmware->FwIMEM; - ulFileLength = pFirmware->FwIMEMLen; - break; + while (FwStatus != FW_STATUS_READY) { + /* Image buffer redirection. */ + switch (FwStatus) { + case FW_STATUS_LOAD_IMEM: + pucMappedFile = pFirmware->FwIMEM; + ulFileLength = pFirmware->FwIMEMLen; + break; - case FW_STATUS_LOAD_EMEM: - pucMappedFile = pFirmware->FwEMEM; - ulFileLength = pFirmware->FwEMEMLen; - break; + case FW_STATUS_LOAD_EMEM: + pucMappedFile = pFirmware->FwEMEM; + ulFileLength = pFirmware->FwEMEMLen; + break; - case FW_STATUS_LOAD_DMEM: - /* Partial update the content of header private. 2008.12.18 */ - pFwHdr = pFirmware->pFwHeader; - pFwPriv = (PRT_8192S_FIRMWARE_PRIV)&pFwHdr->FWPriv; - FirmwareHeaderPriveUpdate(dev, pFwPriv); - pucMappedFile = (u8*)(pFirmware->pFwHeader)+RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE; - ulFileLength = FwHdrSize-RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE; - break; + case FW_STATUS_LOAD_DMEM: + /* Partial update the content of private header */ + pFwHdr = pFirmware->pFwHeader; + pFwPriv = (PRT_8192S_FIRMWARE_PRIV)&pFwHdr->FWPriv; + FirmwareHeaderPriveUpdate(dev, pFwPriv); + pucMappedFile = (u8 *)(pFirmware->pFwHeader) + + RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE; - default: - RT_TRACE(COMP_ERR, "Unexpected Download step!!\n"); - goto DownloadFirmware_Fail; - break; + ulFileLength = FwHdrSize - + RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE; + break; + + default: + RT_TRACE(COMP_ERR, "Unexpected Download step!!\n"); + goto DownloadFirmware_Fail; + break; } - //3// - //3// <2> Download image file - //3 // - rtStatus = FirmwareDownloadCode(dev, pucMappedFile, ulFileLength); + /* <2> Download image file */ + + rtStatus = FirmwareDownloadCode(dev, + pucMappedFile, + ulFileLength); if(rtStatus != true) - { - RT_TRACE(COMP_ERR, "FirmwareDownloadCode() fail ! \n" ); goto DownloadFirmware_Fail; - } - //3// - //3// <3> Check whether load FW process is ready - //3 // + /* <3> Check whether load FW process is ready */ + rtStatus = FirmwareCheckReady(dev, FwStatus); if(rtStatus != true) - { - RT_TRACE(COMP_ERR, "FirmwareDownloadCode() fail ! \n"); goto DownloadFirmware_Fail; - } FwStatus = FirmwareGetNextStatus(pFirmware->FWStatus); } - RT_TRACE(COMP_FIRMWARE, "Firmware Download Success!!\n"); + RT_TRACE(COMP_FIRMWARE, "%s(): Firmware Download Success", __func__); return rtStatus; - DownloadFirmware_Fail: - RT_TRACE(COMP_ERR, "Firmware Download Fail!!%x\n",read_nic_word(dev, TCR)); +DownloadFirmware_Fail: + RT_TRACE(COMP_ERR, "%s(): failed with TCR-Status: %x\n", + __func__, read_nic_word(dev, TCR)); rtStatus = false; return rtStatus; } -- cgit v1.2.3 From 8e399b0332374bb18ff8b899b1288397b52f9394 Mon Sep 17 00:00:00 2001 From: Florian Schilhabel Date: Thu, 18 Mar 2010 15:18:12 +0100 Subject: Staging: rtl8192su: removed 2 printks in rtl8192SU_link_change Signed-off-by: Florian Schilhabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192su/r8192U_core.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index ca3524c850ff..09b9edd14da7 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c @@ -2595,30 +2595,20 @@ void rtl8192SU_update_ratr_table(struct net_device* dev) void rtl8192SU_link_change(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); - struct ieee80211_device* ieee = priv->ieee80211; - //unsigned long flags; + struct ieee80211_device *ieee = priv->ieee80211; u32 reg = 0; - printk("=====>%s 1\n", __func__); reg = read_nic_dword(dev, RCR); - - if (ieee->state == IEEE80211_LINKED) - { - + if (ieee->state == IEEE80211_LINKED) { rtl8192SU_net_update(dev); rtl8192SU_update_ratr_table(dev); ieee->SetFwCmdHandler(dev, FW_CMD_HIGH_PWR_ENABLE); priv->ReceiveConfig = reg |= RCR_CBSSID; - }else{ + } else priv->ReceiveConfig = reg &= ~RCR_CBSSID; - - } - write_nic_dword(dev, RCR, reg); rtl8192_update_msr(dev); - - printk("<=====%s 2\n", __func__); } static struct ieee80211_qos_parameters def_qos_parameters = { -- cgit v1.2.3 From df35bf66eef8bf7237c12190a131a656b0b5af7d Mon Sep 17 00:00:00 2001 From: Florian Schilhabel Date: Thu, 18 Mar 2010 15:18:34 +0100 Subject: Staging: rtl8192su: some work on SetBWModeCallback8192SUsbWorkItem mostly cosmetics. Signed-off-by: Florian Schilhabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192su/r8192S_phy.c | 185 ++++++++++++++------------------- 1 file changed, 80 insertions(+), 105 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192su/r8192S_phy.c b/drivers/staging/rtl8192su/r8192S_phy.c index 63d4e5fd7b18..83c8aaaccd60 100644 --- a/drivers/staging/rtl8192su/r8192S_phy.c +++ b/drivers/staging/rtl8192su/r8192S_phy.c @@ -3607,128 +3607,103 @@ void SetBWModeCallback8192SUsb(struct net_device *dev) RT_TRACE(COMP_SCAN, "<==SetBWMode8190Pci()" ); } -// -// Callback routine of the work item for set bandwidth mode. -// -// use in phy only (in win it's work) +/* + * Callback routine of the work item for set bandwidth mode. + * + * use in phy only (in win it's work) + */ void SetBWModeCallback8192SUsbWorkItem(struct net_device *dev) { - struct r8192_priv *priv = ieee80211_priv(dev); - u8 regBwOpMode; - - // Added it for 20/40 mhz switch time evaluation by guangan 070531 - //u32 NowL, NowH; - //u8Byte BeginTime, EndTime; - u8 regRRSR_RSC; + struct r8192_priv *priv = ieee80211_priv(dev); + u8 regBwOpMode; + u8 regRRSR_RSC; - RT_TRACE(COMP_SCAN, "==>SetBWModeCallback8192SUsbWorkItem() Switch to %s bandwidth\n", \ - priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz"); + RT_TRACE(COMP_SCAN, "%s(): Switch to %s bandwidth", __func__, + priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ? "20MHz" : "40MHz"); - if(priv->rf_chip == RF_PSEUDO_11N) - { + if (priv->rf_chip == RF_PSEUDO_11N) { priv->SetBWModeInProgress= FALSE; return; } - if(!priv->up) return; - - // Added it for 20/40 mhz switch time evaluation by guangan 070531 - //NowL = read_nic_dword(dev, TSFR); - //NowH = read_nic_dword(dev, TSFR+4); - //BeginTime = ((u8Byte)NowH << 32) + NowL; - - //3<1>Set MAC register + /* Set MAC register */ regBwOpMode = read_nic_byte(dev, BW_OPMODE); regRRSR_RSC = read_nic_byte(dev, RRSR+2); - - switch(priv->CurrentChannelBW) - { - case HT_CHANNEL_WIDTH_20: - regBwOpMode |= BW_OPMODE_20MHZ; - // 2007/02/07 Mark by Emily becasue we have not verify whether this register works - write_nic_byte(dev, BW_OPMODE, regBwOpMode); - break; - - case HT_CHANNEL_WIDTH_20_40: - regBwOpMode &= ~BW_OPMODE_20MHZ; - // 2007/02/07 Mark by Emily becasue we have not verify whether this register works - write_nic_byte(dev, BW_OPMODE, regBwOpMode); - regRRSR_RSC = (regRRSR_RSC&0x90) |(priv->nCur40MhzPrimeSC<<5); - write_nic_byte(dev, RRSR+2, regRRSR_RSC); - - break; - - default: - RT_TRACE(COMP_DBG, "SetBWModeCallback8192SUsbWorkItem(): unknown Bandwidth: %#X\n", - priv->CurrentChannelBW); - break; + switch (priv->CurrentChannelBW) { + case HT_CHANNEL_WIDTH_20: + regBwOpMode |= BW_OPMODE_20MHZ; + /* we have not verified whether this register works */ + write_nic_byte(dev, BW_OPMODE, regBwOpMode); + break; + case HT_CHANNEL_WIDTH_20_40: + regBwOpMode &= ~BW_OPMODE_20MHZ; + /* we have not verified whether this register works */ + write_nic_byte(dev, BW_OPMODE, regBwOpMode); + regRRSR_RSC = (regRRSR_RSC&0x90) | (priv->nCur40MhzPrimeSC<<5); + write_nic_byte(dev, RRSR+2, regRRSR_RSC); + break; + default: + RT_TRACE(COMP_DBG, "%s(): unknown Bandwidth: %#X", __func__, + priv->CurrentChannelBW); + break; } - - //3 <2>Set PHY related register - switch(priv->CurrentChannelBW) - { - case HT_CHANNEL_WIDTH_20: - rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0); - rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0); - - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x58); - - break; - case HT_CHANNEL_WIDTH_20_40: - rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1); - rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1); - - // Set Control channel to upper or lower. These settings are required only for 40MHz - rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1)); - rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC); - - rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x18); - - break; - - - default: - RT_TRACE(COMP_DBG, "SetBWModeCallback8192SUsbWorkItem(): unknown Bandwidth: %#X\n"\ - ,priv->CurrentChannelBW); - break; + /* Set PHY related register */ + switch (priv->CurrentChannelBW) { + case HT_CHANNEL_WIDTH_20: + rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0); + rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0); + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x58); + break; + case HT_CHANNEL_WIDTH_20_40: + rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1); + rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1); + /* + * Set Control channel to upper or lower. + * These settings are required only for 40MHz + */ + rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, + (priv->nCur40MhzPrimeSC>>1)); + rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, + priv->nCur40MhzPrimeSC); + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x18); + break; + default: + RT_TRACE(COMP_DBG, "%s(): unknown Bandwidth: %#X", __func__, + priv->CurrentChannelBW); + break; } - //Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315 - - //3<3>Set RF related register - switch( priv->rf_chip ) - { - case RF_8225: - PHY_SetRF8225Bandwidth(dev, priv->CurrentChannelBW); - break; - - case RF_8256: - // Please implement this function in Hal8190PciPhy8256.c - //PHY_SetRF8256Bandwidth(dev, priv->CurrentChannelBW); - break; - - case RF_6052: - PHY_RF6052SetBandwidth(dev, priv->CurrentChannelBW); - break; - - case RF_8258: - // Please implement this function in Hal8190PciPhy8258.c - // PHY_SetRF8258Bandwidth(); - break; - - case RF_PSEUDO_11N: - // Do Nothing - break; + /* + * Skip over setting of J-mode in BB register here. + * Default value is "None J mode". + */ - default: - //RT_ASSERT(FALSE, ("Unknown rf_chip: %d\n", priv->rf_chip)); - break; + /* Set RF related register */ + switch (priv->rf_chip) { + case RF_8225: + PHY_SetRF8225Bandwidth(dev, priv->CurrentChannelBW); + break; + case RF_8256: + /* Please implement this function in Hal8190PciPhy8256.c */ + /* PHY_SetRF8256Bandwidth(dev, priv->CurrentChannelBW); */ + break; + case RF_6052: + PHY_RF6052SetBandwidth(dev, priv->CurrentChannelBW); + break; + case RF_8258: + /* Please implement this function in Hal8190PciPhy8258.c */ + /* PHY_SetRF8258Bandwidth(); */ + break; + case RF_PSEUDO_11N: + /* Do Nothing */ + break; + default: + RT_TRACE(COMP_DBG, "%s(): unknown rf_chip: %d", __func__, + priv->rf_chip); + break; } - priv->SetBWModeInProgress= FALSE; - - RT_TRACE(COMP_SCAN, "<==SetBWModeCallback8192SUsbWorkItem()" ); } //--------------------------Move to oter DIR later-------------------------------*/ -- cgit v1.2.3 From ebbfda1e656b9dd69bd606b1dbba28cd53dd227e Mon Sep 17 00:00:00 2001 From: Florian Schilhabel Date: Thu, 18 Mar 2010 15:18:56 +0100 Subject: Staging: rtl8192su: changed check_reset_cnt to be static again variable check_reset_cnt in rtl819x_watchdog_wqcallback is now static again. also, little cosmetics. Signed-off-by: Florian Schilhabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192su/r8192U_core.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index 09b9edd14da7..efba60826adf 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c @@ -5525,13 +5525,14 @@ void rtl819x_watchdog_wqcallback(struct work_struct *work) struct net_device *dev = priv->ieee80211->dev; struct ieee80211_device* ieee = priv->ieee80211; RESET_TYPE ResetType = RESET_TYPE_NORESET; - u8 check_reset_cnt = 0; + static u8 check_reset_cnt; + u32 TotalRxBcnNum = 0; + u32 TotalRxDataNum = 0; bool bBusyTraffic = false; if(!priv->up) return; hal_dm_watchdog(dev); - /* to get busy traffic condition */ if (ieee->state == IEEE80211_LINKED) { if (ieee->LinkDetectInfo.NumRxOkInPeriod > 666 || @@ -5545,23 +5546,15 @@ void rtl819x_watchdog_wqcallback(struct work_struct *work) if (priv->ieee80211->state == IEEE80211_LINKED && priv->ieee80211->iw_mode == IW_MODE_INFRA) { - u32 TotalRxBcnNum = 0; - u32 TotalRxDataNum = 0; rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum); if ((TotalRxBcnNum + TotalRxDataNum) == 0) { - #ifdef TODO - if (rfState == eRfOff) - RT_TRACE(COMP_ERR, "========>%s()\n", - __func__); - #endif - RT_TRACE(COMP_ERR, "=>%s(): AP is power off," + RT_TRACE(COMP_ERR, "%s(): AP is powered off," "connect another one\n", __func__); /* Dot11d_Reset(dev); */ priv->ieee80211->state = IEEE80211_ASSOCIATING; notify_wx_assoc_event(priv->ieee80211); RemovePeerTS(priv->ieee80211, priv->ieee80211->current_network.bssid); - ieee->is_roaming = true; priv->ieee80211->link_change(dev); queue_work(priv->ieee80211->wq, @@ -5584,11 +5577,11 @@ void rtl819x_watchdog_wqcallback(struct work_struct *work) (!priv->bDisableNormalResetCheck && /* This is control by OID set in Pomelo */ ResetType == RESET_TYPE_SILENT)))) { - RT_TRACE(COMP_RESET, "%s():priv->force_reset is %d," + RT_TRACE(COMP_RESET, "%s(): priv->force_reset is %d," "priv->ResetProgress is %d, " "priv->bForcedSilentReset is %d, " "priv->bDisableNormalResetCheck is %d, " - "ResetType is %d\n", + "ResetType is %d", __func__, priv->force_reset, priv->ResetProgress, @@ -5600,7 +5593,6 @@ void rtl819x_watchdog_wqcallback(struct work_struct *work) priv->force_reset = false; priv->bForcedSilentReset = false; priv->bResetInProgress = false; - RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n"); } void watch_dog_timer_callback(unsigned long data) -- cgit v1.2.3 From 48d9356e7750d3efa3156eb3a76e7a4439774b12 Mon Sep 17 00:00:00 2001 From: Martyn Welch Date: Mon, 22 Mar 2010 14:58:50 +0000 Subject: Staging: vme: Use dev_err rather than printk Replace instances of printk with dev_err where possible. Signed-off-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/bridges/vme_ca91cx42.c | 95 ++++++++------ drivers/staging/vme/bridges/vme_tsi148.c | 202 ++++++++++++++++------------- 2 files changed, 171 insertions(+), 126 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c index b159ea58adf7..589664c4d24e 100644 --- a/drivers/staging/vme/bridges/vme_ca91cx42.c +++ b/drivers/staging/vme/bridges/vme_ca91cx42.c @@ -94,31 +94,35 @@ static u32 ca91cx42_IACK_irqhandler(struct ca91cx42_driver *bridge) return CA91CX42_LINT_SW_IACK; } -static u32 ca91cx42_VERR_irqhandler(struct ca91cx42_driver *bridge) +static u32 ca91cx42_VERR_irqhandler(struct vme_bridge *ca91cx42_bridge) { int val; + struct ca91cx42_driver *bridge; + + bridge = ca91cx42_bridge->driver_priv; val = ioread32(bridge->base + DGCS); if (!(val & 0x00000800)) { - printk(KERN_ERR "ca91c042: ca91cx42_VERR_irqhandler DMA Read " - "Error DGCS=%08X\n", val); + dev_err(ca91cx42_bridge->parent, "ca91cx42_VERR_irqhandler DMA " + "Read Error DGCS=%08X\n", val); } return CA91CX42_LINT_VERR; } -static u32 ca91cx42_LERR_irqhandler(struct ca91cx42_driver *bridge) +static u32 ca91cx42_LERR_irqhandler(struct vme_bridge *ca91cx42_bridge) { int val; + struct ca91cx42_driver *bridge; - val = ioread32(bridge->base + DGCS); + bridge = ca91cx42_bridge->driver_priv; - if (!(val & 0x00000800)) { - printk(KERN_ERR "ca91c042: ca91cx42_LERR_irqhandler DMA Read " - "Error DGCS=%08X\n", val); + val = ioread32(bridge->base + DGCS); - } + if (!(val & 0x00000800)) + dev_err(ca91cx42_bridge->parent, "ca91cx42_LERR_irqhandler DMA " + "Read Error DGCS=%08X\n", val); return CA91CX42_LINT_LERR; } @@ -176,9 +180,9 @@ static irqreturn_t ca91cx42_irqhandler(int irq, void *ptr) if (stat & CA91CX42_LINT_SW_IACK) serviced |= ca91cx42_IACK_irqhandler(bridge); if (stat & CA91CX42_LINT_VERR) - serviced |= ca91cx42_VERR_irqhandler(bridge); + serviced |= ca91cx42_VERR_irqhandler(ca91cx42_bridge); if (stat & CA91CX42_LINT_LERR) - serviced |= ca91cx42_LERR_irqhandler(bridge); + serviced |= ca91cx42_LERR_irqhandler(ca91cx42_bridge); if (stat & (CA91CX42_LINT_VIRQ1 | CA91CX42_LINT_VIRQ2 | CA91CX42_LINT_VIRQ3 | CA91CX42_LINT_VIRQ4 | CA91CX42_LINT_VIRQ5 | CA91CX42_LINT_VIRQ6 | @@ -326,9 +330,12 @@ int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled, unsigned int i, addr = 0, granularity; unsigned int temp_ctl = 0; unsigned int vme_bound, pci_offset; + struct vme_bridge *ca91cx42_bridge; struct ca91cx42_driver *bridge; - bridge = image->parent->driver_priv; + ca91cx42_bridge = image->parent; + + bridge = ca91cx42_bridge->driver_priv; i = image->number; @@ -353,7 +360,7 @@ int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled, case VME_USER3: case VME_USER4: default: - printk(KERN_ERR "Invalid address space\n"); + dev_err(ca91cx42_bridge->parent, "Invalid address space\n"); return -EINVAL; break; } @@ -371,15 +378,18 @@ int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled, granularity = 0x10000; if (vme_base & (granularity - 1)) { - printk(KERN_ERR "Invalid VME base alignment\n"); + dev_err(ca91cx42_bridge->parent, "Invalid VME base " + "alignment\n"); return -EINVAL; } if (vme_bound & (granularity - 1)) { - printk(KERN_ERR "Invalid VME bound alignment\n"); + dev_err(ca91cx42_bridge->parent, "Invalid VME bound " + "alignment\n"); return -EINVAL; } if (pci_offset & (granularity - 1)) { - printk(KERN_ERR "Invalid PCI Offset alignment\n"); + dev_err(ca91cx42_bridge->parent, "Invalid PCI Offset " + "alignment\n"); return -EINVAL; } @@ -491,7 +501,7 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image, /* Find pci_dev container of dev */ if (ca91cx42_bridge->parent == NULL) { - printk(KERN_ERR "Dev entry NULL\n"); + dev_err(ca91cx42_bridge->parent, "Dev entry NULL\n"); return -EINVAL; } pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev); @@ -515,8 +525,8 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image, if (image->bus_resource.name == NULL) { image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL); if (image->bus_resource.name == NULL) { - printk(KERN_ERR "Unable to allocate memory for resource" - " name\n"); + dev_err(ca91cx42_bridge->parent, "Unable to allocate " + "memory for resource name\n"); retval = -ENOMEM; goto err_name; } @@ -533,8 +543,8 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image, &(image->bus_resource), size, size, PCIBIOS_MIN_MEM, 0, NULL, NULL); if (retval) { - printk(KERN_ERR "Failed to allocate mem resource for " - "window %d size 0x%lx start 0x%lx\n", + dev_err(ca91cx42_bridge->parent, "Failed to allocate mem " + "resource for window %d size 0x%lx start 0x%lx\n", image->number, (unsigned long)size, (unsigned long)image->bus_resource.start); goto err_resource; @@ -543,7 +553,7 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image, image->kern_base = ioremap_nocache( image->bus_resource.start, size); if (image->kern_base == NULL) { - printk(KERN_ERR "Failed to remap resource\n"); + dev_err(ca91cx42_bridge->parent, "Failed to remap resource\n"); retval = -ENOMEM; goto err_remap; } @@ -582,9 +592,12 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled, unsigned int i, granularity = 0; unsigned int temp_ctl = 0; unsigned long long pci_bound, vme_offset, pci_base; + struct vme_bridge *ca91cx42_bridge; struct ca91cx42_driver *bridge; - bridge = image->parent->driver_priv; + ca91cx42_bridge = image->parent; + + bridge = ca91cx42_bridge->driver_priv; i = image->number; @@ -595,12 +608,14 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled, /* Verify input data */ if (vme_base & (granularity - 1)) { - printk(KERN_ERR "Invalid VME Window alignment\n"); + dev_err(ca91cx42_bridge->parent, "Invalid VME Window " + "alignment\n"); retval = -EINVAL; goto err_window; } if (size & (granularity - 1)) { - printk(KERN_ERR "Invalid VME Window alignment\n"); + dev_err(ca91cx42_bridge->parent, "Invalid VME Window " + "alignment\n"); retval = -EINVAL; goto err_window; } @@ -614,8 +629,8 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled, retval = ca91cx42_alloc_resource(image, size); if (retval) { spin_unlock(&(image->lock)); - printk(KERN_ERR "Unable to allocate memory for resource " - "name\n"); + dev_err(ca91cx42_bridge->parent, "Unable to allocate memory " + "for resource name\n"); retval = -ENOMEM; goto err_res; } @@ -658,7 +673,7 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled, break; default: spin_unlock(&(image->lock)); - printk(KERN_ERR "Invalid data width\n"); + dev_err(ca91cx42_bridge->parent, "Invalid data width\n"); retval = -EINVAL; goto err_dwidth; break; @@ -690,7 +705,7 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled, case VME_USER4: default: spin_unlock(&(image->lock)); - printk(KERN_ERR "Invalid address space\n"); + dev_err(ca91cx42_bridge->parent, "Invalid address space\n"); retval = -EINVAL; goto err_aspace; break; @@ -921,12 +936,15 @@ int ca91cx42_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, struct vme_dma_vme *vme_attr; dma_addr_t desc_ptr; int retval = 0; + struct device *dev; + + dev = list->parent->parent->parent; /* XXX descriptor must be aligned on 64-bit boundaries */ entry = (struct ca91cx42_dma_entry *) kmalloc(sizeof(struct ca91cx42_dma_entry), GFP_KERNEL); if (entry == NULL) { - printk(KERN_ERR "Failed to allocate memory for dma resource " + dev_err(dev, "Failed to allocate memory for dma resource " "structure\n"); retval = -ENOMEM; goto err_mem; @@ -934,7 +952,7 @@ int ca91cx42_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, /* Test descriptor alignment */ if ((unsigned long)&(entry->descriptor) & CA91CX42_DCPP_M) { - printk("Descriptor not aligned to 16 byte boundary as " + dev_err(dev, "Descriptor not aligned to 16 byte boundary as " "required: %p\n", &(entry->descriptor)); retval = -EINVAL; goto err_align; @@ -955,7 +973,7 @@ int ca91cx42_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, if ((vme_attr->aspace & ~(VME_A16 | VME_A24 | VME_A32 | VME_USER1 | VME_USER2)) != 0) { - printk(KERN_ERR "Unsupported cycle type\n"); + dev_err(dev, "Unsupported cycle type\n"); retval = -EINVAL; goto err_aspace; } @@ -963,7 +981,7 @@ int ca91cx42_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, if ((vme_attr->cycle & ~(VME_SCT | VME_BLT | VME_SUPER | VME_USER | VME_PROG | VME_DATA)) != 0) { - printk(KERN_ERR "Unsupported cycle type\n"); + dev_err(dev, "Unsupported cycle type\n"); retval = -EINVAL; goto err_cycle; } @@ -972,7 +990,7 @@ int ca91cx42_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, if (!(((src->type == VME_DMA_PCI) && (dest->type == VME_DMA_VME)) || ((src->type == VME_DMA_VME) && (dest->type == VME_DMA_PCI)))) { - printk(KERN_ERR "Cannot perform transfer with this " + dev_err(dev, "Cannot perform transfer with this " "source-destination combination\n"); retval = -EINVAL; goto err_direct; @@ -997,7 +1015,7 @@ int ca91cx42_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D64; break; default: - printk(KERN_ERR "Invalid data width\n"); + dev_err(dev, "Invalid data width\n"); return -EINVAL; } @@ -1019,7 +1037,7 @@ int ca91cx42_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, entry->descriptor.dctl |= CA91CX42_DCTL_VAS_USER2; break; default: - printk(KERN_ERR "Invalid address space\n"); + dev_err(dev, "Invalid address space\n"); return -EINVAL; break; } @@ -1079,12 +1097,13 @@ int ca91cx42_dma_list_exec(struct vme_dma_list *list) int retval = 0; dma_addr_t bus_addr; u32 val; - + struct device *dev; struct ca91cx42_driver *bridge; ctrlr = list->parent; bridge = ctrlr->parent->driver_priv; + dev = ctrlr->parent->parent; mutex_lock(&(ctrlr->mtx)); @@ -1140,7 +1159,7 @@ int ca91cx42_dma_list_exec(struct vme_dma_list *list) if (val & (CA91CX42_DGCS_LERR | CA91CX42_DGCS_VERR | CA91CX42_DGCS_PERR)) { - printk(KERN_ERR "ca91c042: DMA Error. DGCS=%08X\n", val); + dev_err(dev, "ca91c042: DMA Error. DGCS=%08X\n", val); val = ioread32(bridge->base + DCTL); } diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index 68f24425977f..fa0dc4a869e9 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -137,16 +137,20 @@ static u32 tsi148_LM_irqhandler(struct tsi148_driver *bridge, u32 stat) * * XXX This functionality is not exposed up though API. */ -static u32 tsi148_MB_irqhandler(struct tsi148_driver *bridge, u32 stat) +static u32 tsi148_MB_irqhandler(struct vme_bridge *tsi148_bridge, u32 stat) { int i; u32 val; u32 serviced = 0; + struct tsi148_driver *bridge; + + bridge = tsi148_bridge->driver_priv; for (i = 0; i < 4; i++) { if(stat & TSI148_LCSR_INTS_MBS[i]) { val = ioread32be(bridge->base + TSI148_GCSR_MBOX[i]); - printk("VME Mailbox %d received: 0x%x\n", i, val); + dev_err(tsi148_bridge->parent, "VME Mailbox %d received" + ": 0x%x\n", i, val); serviced |= TSI148_LCSR_INTC_MBC[i]; } } @@ -157,19 +161,22 @@ static u32 tsi148_MB_irqhandler(struct tsi148_driver *bridge, u32 stat) /* * Display error & status message when PERR (PCI) exception interrupt occurs. */ -static u32 tsi148_PERR_irqhandler(struct tsi148_driver *bridge) +static u32 tsi148_PERR_irqhandler(struct vme_bridge *tsi148_bridge) { - printk(KERN_ERR - "PCI Exception at address: 0x%08x:%08x, attributes: %08x\n", + struct tsi148_driver *bridge; + + bridge = tsi148_bridge->driver_priv; + + dev_err(tsi148_bridge->parent, "PCI Exception at address: 0x%08x:%08x, " + "attributes: %08x\n", ioread32be(bridge->base + TSI148_LCSR_EDPAU), ioread32be(bridge->base + TSI148_LCSR_EDPAL), - ioread32be(bridge->base + TSI148_LCSR_EDPAT) - ); - printk(KERN_ERR - "PCI-X attribute reg: %08x, PCI-X split completion reg: %08x\n", + ioread32be(bridge->base + TSI148_LCSR_EDPAT)); + + dev_err(tsi148_bridge->parent, "PCI-X attribute reg: %08x, PCI-X split " + "completion reg: %08x\n", ioread32be(bridge->base + TSI148_LCSR_EDPXA), - ioread32be(bridge->base + TSI148_LCSR_EDPXS) - ); + ioread32be(bridge->base + TSI148_LCSR_EDPXS)); iowrite32be(TSI148_LCSR_EDPAT_EDPCL, bridge->base + TSI148_LCSR_EDPAT); @@ -197,7 +204,8 @@ static u32 tsi148_VERR_irqhandler(struct vme_bridge *tsi148_bridge) /* Check for exception register overflow (we have lost error data) */ if(error_attrib & TSI148_LCSR_VEAT_VEOF) { - printk(KERN_ERR "VME Bus Exception Overflow Occurred\n"); + dev_err(tsi148_bridge->parent, "VME Bus Exception Overflow " + "Occurred\n"); } error = (struct vme_bus_error *)kmalloc(sizeof (struct vme_bus_error), @@ -207,11 +215,10 @@ static u32 tsi148_VERR_irqhandler(struct vme_bridge *tsi148_bridge) error->attributes = error_attrib; list_add_tail(&(error->list), &(tsi148_bridge->vme_errors)); } else { - printk(KERN_ERR - "Unable to alloc memory for VMEbus Error reporting\n"); - printk(KERN_ERR - "VME Bus Error at address: 0x%llx, attributes: %08x\n", - error_addr, error_attrib); + dev_err(tsi148_bridge->parent, "Unable to alloc memory for " + "VMEbus Error reporting\n"); + dev_err(tsi148_bridge->parent, "VME Bus Error at address: " + "0x%llx, attributes: %08x\n", error_addr, error_attrib); } /* Clear Status */ @@ -298,11 +305,11 @@ static irqreturn_t tsi148_irqhandler(int irq, void *ptr) /* Mail box irqs */ if (stat & (TSI148_LCSR_INTS_MB3S | TSI148_LCSR_INTS_MB2S | TSI148_LCSR_INTS_MB1S | TSI148_LCSR_INTS_MB0S)) - serviced |= tsi148_MB_irqhandler(bridge, stat); + serviced |= tsi148_MB_irqhandler(tsi148_bridge, stat); /* PCI bus error */ if (stat & TSI148_LCSR_INTS_PERRS) - serviced |= tsi148_PERR_irqhandler(bridge); + serviced |= tsi148_PERR_irqhandler(tsi148_bridge); /* VME bus error */ if (stat & TSI148_LCSR_INTS_VERRS) @@ -346,8 +353,8 @@ static int tsi148_irq_init(struct vme_bridge *tsi148_bridge) IRQF_SHARED, driver_name, tsi148_bridge); if (result) { - dev_err(&pdev->dev, "Can't get assigned pci irq vector %02X\n", - pdev->irq); + dev_err(tsi148_bridge->parent, "Can't get assigned pci irq " + "vector %02X\n", pdev->irq); return result; } @@ -568,9 +575,11 @@ int tsi148_slave_set(struct vme_slave_resource *image, int enabled, unsigned int vme_bound_low, vme_bound_high; unsigned int pci_offset_low, pci_offset_high; unsigned long long vme_bound, pci_offset; + struct vme_bridge *tsi148_bridge; struct tsi148_driver *bridge; - bridge = image->parent->driver_priv; + tsi148_bridge = image->parent; + bridge = tsi148_bridge->driver_priv; i = image->number; @@ -597,7 +606,7 @@ int tsi148_slave_set(struct vme_slave_resource *image, int enabled, case VME_USER3: case VME_USER4: default: - printk("Invalid address space\n"); + dev_err(tsi148_bridge->parent, "Invalid address space\n"); return -EINVAL; break; } @@ -615,15 +624,16 @@ int tsi148_slave_set(struct vme_slave_resource *image, int enabled, reg_split(pci_offset, &pci_offset_high, &pci_offset_low); if (vme_base_low & (granularity - 1)) { - printk("Invalid VME base alignment\n"); + dev_err(tsi148_bridge->parent, "Invalid VME base alignment\n"); return -EINVAL; } if (vme_bound_low & (granularity - 1)) { - printk("Invalid VME bound alignment\n"); + dev_err(tsi148_bridge->parent, "Invalid VME bound alignment\n"); return -EINVAL; } if (pci_offset_low & (granularity - 1)) { - printk("Invalid PCI Offset alignment\n"); + dev_err(tsi148_bridge->parent, "Invalid PCI Offset " + "alignment\n"); return -EINVAL; } @@ -815,12 +825,7 @@ static int tsi148_alloc_resource(struct vme_master_resource *image, tsi148_bridge = image->parent; - /* Find pci_dev container of dev */ - if (tsi148_bridge->parent == NULL) { - printk("Dev entry NULL\n"); - return -EINVAL; - } - pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev); + pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev); existing_size = (unsigned long long)(image->bus_resource.end - image->bus_resource.start); @@ -846,8 +851,8 @@ static int tsi148_alloc_resource(struct vme_master_resource *image, if (image->bus_resource.name == NULL) { image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL); if (image->bus_resource.name == NULL) { - printk(KERN_ERR "Unable to allocate memory for resource" - " name\n"); + dev_err(tsi148_bridge->parent, "Unable to allocate " + "memory for resource name\n"); retval = -ENOMEM; goto err_name; } @@ -864,8 +869,8 @@ static int tsi148_alloc_resource(struct vme_master_resource *image, &(image->bus_resource), size, size, PCIBIOS_MIN_MEM, 0, NULL, NULL); if (retval) { - printk(KERN_ERR "Failed to allocate mem resource for " - "window %d size 0x%lx start 0x%lx\n", + dev_err(tsi148_bridge->parent, "Failed to allocate mem " + "resource for window %d size 0x%lx start 0x%lx\n", image->number, (unsigned long)size, (unsigned long)image->bus_resource.start); goto err_resource; @@ -874,7 +879,7 @@ static int tsi148_alloc_resource(struct vme_master_resource *image, image->kern_base = ioremap_nocache( image->bus_resource.start, size); if (image->kern_base == NULL) { - printk(KERN_ERR "Failed to remap resource\n"); + dev_err(tsi148_bridge->parent, "Failed to remap resource\n"); retval = -ENOMEM; goto err_remap; } @@ -918,19 +923,24 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled, unsigned int pci_bound_low, pci_bound_high; unsigned int vme_offset_low, vme_offset_high; unsigned long long pci_bound, vme_offset, pci_base; + struct vme_bridge *tsi148_bridge; struct tsi148_driver *bridge; - bridge = image->parent->driver_priv; + tsi148_bridge = image->parent; + + bridge = tsi148_bridge->driver_priv; /* Verify input data */ if (vme_base & 0xFFFF) { - printk(KERN_ERR "Invalid VME Window alignment\n"); + dev_err(tsi148_bridge->parent, "Invalid VME Window " + "alignment\n"); retval = -EINVAL; goto err_window; } if ((size == 0) && (enabled != 0)) { - printk(KERN_ERR "Size must be non-zero for enabled windows\n"); + dev_err(tsi148_bridge->parent, "Size must be non-zero for " + "enabled windows\n"); retval = -EINVAL; goto err_window; } @@ -944,7 +954,7 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled, retval = tsi148_alloc_resource(image, size); if (retval) { spin_unlock(&(image->lock)); - printk(KERN_ERR "Unable to allocate memory for " + dev_err(tsi148_bridge->parent, "Unable to allocate memory for " "resource\n"); goto err_res; } @@ -971,19 +981,20 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled, if (pci_base_low & 0xFFFF) { spin_unlock(&(image->lock)); - printk(KERN_ERR "Invalid PCI base alignment\n"); + dev_err(tsi148_bridge->parent, "Invalid PCI base alignment\n"); retval = -EINVAL; goto err_gran; } if (pci_bound_low & 0xFFFF) { spin_unlock(&(image->lock)); - printk(KERN_ERR "Invalid PCI bound alignment\n"); + dev_err(tsi148_bridge->parent, "Invalid PCI bound alignment\n"); retval = -EINVAL; goto err_gran; } if (vme_offset_low & 0xFFFF) { spin_unlock(&(image->lock)); - printk(KERN_ERR "Invalid VME Offset alignment\n"); + dev_err(tsi148_bridge->parent, "Invalid VME Offset " + "alignment\n"); retval = -EINVAL; goto err_gran; } @@ -1029,8 +1040,8 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled, temp_ctl |= TSI148_LCSR_OTAT_TM_2eSST; } if (cycle & VME_2eSSTB) { - printk(KERN_WARNING "Currently not setting Broadcast Select " - "Registers\n"); + dev_warn(tsi148_bridge->parent, "Currently not setting " + "Broadcast Select Registers\n"); temp_ctl &= ~TSI148_LCSR_OTAT_TM_M; temp_ctl |= TSI148_LCSR_OTAT_TM_2eSSTB; } @@ -1046,7 +1057,7 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled, break; default: spin_unlock(&(image->lock)); - printk(KERN_ERR "Invalid data width\n"); + dev_err(tsi148_bridge->parent, "Invalid data width\n"); retval = -EINVAL; goto err_dwidth; } @@ -1083,7 +1094,7 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled, break; default: spin_unlock(&(image->lock)); - printk(KERN_ERR "Invalid address space\n"); + dev_err(tsi148_bridge->parent, "Invalid address space\n"); retval = -EINVAL; goto err_aspace; break; @@ -1353,8 +1364,8 @@ ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf, vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset, count); if(vme_err != NULL) { - printk("First VME write error detected an at address 0x%llx\n", - vme_err->address); + dev_warn(tsi148_bridge->parent, "First VME write error detected" + " an at address 0x%llx\n", vme_err->address); retval = vme_err->address - (vme_base + offset); /* Clear down save errors in this address range */ tsi148_clear_errors(tsi148_bridge, aspace, vme_base + offset, @@ -1428,8 +1439,8 @@ unsigned int tsi148_master_rmw(struct vme_master_resource *image, return result; } -static int tsi148_dma_set_vme_src_attributes (u32 *attr, vme_address_t aspace, - vme_cycle_t cycle, vme_width_t dwidth) +static int tsi148_dma_set_vme_src_attributes(struct device *dev, u32 *attr, + vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth) { /* Setup 2eSST speeds */ switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) { @@ -1461,7 +1472,8 @@ static int tsi148_dma_set_vme_src_attributes (u32 *attr, vme_address_t aspace, *attr |= TSI148_LCSR_DSAT_TM_2eSST; } if (cycle & VME_2eSSTB) { - printk("Currently not setting Broadcast Select Registers\n"); + dev_err(dev, "Currently not setting Broadcast Select " + "Registers\n"); *attr |= TSI148_LCSR_DSAT_TM_2eSSTB; } @@ -1474,7 +1486,7 @@ static int tsi148_dma_set_vme_src_attributes (u32 *attr, vme_address_t aspace, *attr |= TSI148_LCSR_DSAT_DBW_32; break; default: - printk("Invalid data width\n"); + dev_err(dev, "Invalid data width\n"); return -EINVAL; } @@ -1508,7 +1520,7 @@ static int tsi148_dma_set_vme_src_attributes (u32 *attr, vme_address_t aspace, *attr |= TSI148_LCSR_DSAT_AMODE_USER4; break; default: - printk("Invalid address space\n"); + dev_err(dev, "Invalid address space\n"); return -EINVAL; break; } @@ -1521,8 +1533,8 @@ static int tsi148_dma_set_vme_src_attributes (u32 *attr, vme_address_t aspace, return 0; } -static int tsi148_dma_set_vme_dest_attributes(u32 *attr, vme_address_t aspace, - vme_cycle_t cycle, vme_width_t dwidth) +static int tsi148_dma_set_vme_dest_attributes(struct device *dev, u32 *attr, + vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth) { /* Setup 2eSST speeds */ switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) { @@ -1554,7 +1566,8 @@ static int tsi148_dma_set_vme_dest_attributes(u32 *attr, vme_address_t aspace, *attr |= TSI148_LCSR_DDAT_TM_2eSST; } if (cycle & VME_2eSSTB) { - printk("Currently not setting Broadcast Select Registers\n"); + dev_err(dev, "Currently not setting Broadcast Select " + "Registers\n"); *attr |= TSI148_LCSR_DDAT_TM_2eSSTB; } @@ -1567,7 +1580,7 @@ static int tsi148_dma_set_vme_dest_attributes(u32 *attr, vme_address_t aspace, *attr |= TSI148_LCSR_DDAT_DBW_32; break; default: - printk("Invalid data width\n"); + dev_err(dev, "Invalid data width\n"); return -EINVAL; } @@ -1601,7 +1614,7 @@ static int tsi148_dma_set_vme_dest_attributes(u32 *attr, vme_address_t aspace, *attr |= TSI148_LCSR_DDAT_AMODE_USER4; break; default: - printk("Invalid address space\n"); + dev_err(dev, "Invalid address space\n"); return -EINVAL; break; } @@ -1627,21 +1640,25 @@ int tsi148_dma_list_add (struct vme_dma_list *list, struct vme_dma_attr *src, struct vme_dma_vme *vme_attr; dma_addr_t desc_ptr; int retval = 0; + struct vme_bridge *tsi148_bridge; + + tsi148_bridge = list->parent->parent; /* Descriptor must be aligned on 64-bit boundaries */ entry = (struct tsi148_dma_entry *)kmalloc( sizeof(struct tsi148_dma_entry), GFP_KERNEL); if (entry == NULL) { - printk("Failed to allocate memory for dma resource " - "structure\n"); + dev_err(tsi148_bridge->parent, "Failed to allocate memory for " + "dma resource structure\n"); retval = -ENOMEM; goto err_mem; } /* Test descriptor alignment */ if ((unsigned long)&(entry->descriptor) & 0x7) { - printk("Descriptor not aligned to 8 byte boundary as " - "required: %p\n", &(entry->descriptor)); + dev_err(tsi148_bridge->parent, "Descriptor not aligned to 8 " + "byte boundary as required: %p\n", + &(entry->descriptor)); retval = -EINVAL; goto err_align; } @@ -1686,13 +1703,13 @@ int tsi148_dma_list_add (struct vme_dma_list *list, struct vme_dma_attr *src, entry->descriptor.dsat = TSI148_LCSR_DSAT_TYP_VME; retval = tsi148_dma_set_vme_src_attributes( - &(entry->descriptor.dsat), vme_attr->aspace, - vme_attr->cycle, vme_attr->dwidth); + tsi148_bridge->parent, &(entry->descriptor.dsat), + vme_attr->aspace, vme_attr->cycle, vme_attr->dwidth); if(retval < 0 ) goto err_source; break; default: - printk("Invalid source type\n"); + dev_err(tsi148_bridge->parent, "Invalid source type\n"); retval = -EINVAL; goto err_source; break; @@ -1724,13 +1741,13 @@ int tsi148_dma_list_add (struct vme_dma_list *list, struct vme_dma_attr *src, entry->descriptor.ddat = TSI148_LCSR_DDAT_TYP_VME; retval = tsi148_dma_set_vme_dest_attributes( - &(entry->descriptor.ddat), vme_attr->aspace, - vme_attr->cycle, vme_attr->dwidth); + tsi148_bridge->parent, &(entry->descriptor.ddat), + vme_attr->aspace, vme_attr->cycle, vme_attr->dwidth); if(retval < 0 ) goto err_dest; break; default: - printk("Invalid destination type\n"); + dev_err(tsi148_bridge->parent, "Invalid destination type\n"); retval = -EINVAL; goto err_dest; break; @@ -1795,11 +1812,14 @@ int tsi148_dma_list_exec(struct vme_dma_list *list) dma_addr_t bus_addr; u32 bus_addr_high, bus_addr_low; u32 val, dctlreg = 0; + struct vme_bridge *tsi148_bridge; struct tsi148_driver *bridge; ctrlr = list->parent; - bridge = ctrlr->parent->driver_priv; + tsi148_bridge = ctrlr->parent; + + bridge = tsi148_bridge->driver_priv; mutex_lock(&(ctrlr->mtx)); @@ -1847,7 +1867,7 @@ int tsi148_dma_list_exec(struct vme_dma_list *list) TSI148_LCSR_OFFSET_DSTA); if (val & TSI148_LCSR_DSTA_VBE) { - printk(KERN_ERR "tsi148: DMA Error. DSTA=%08X\n", val); + dev_err(tsi148_bridge->parent, "DMA Error. DSTA=%08X\n", val); retval = -EIO; } @@ -1891,9 +1911,12 @@ int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, { u32 lm_base_high, lm_base_low, lm_ctl = 0; int i; + struct vme_bridge *tsi148_bridge; struct tsi148_driver *bridge; - bridge = lm->parent->driver_priv; + tsi148_bridge = lm->parent; + + bridge = tsi148_bridge->driver_priv; mutex_lock(&(lm->mtx)); @@ -1901,8 +1924,8 @@ int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, for (i = 0; i < lm->monitors; i++) { if (bridge->lm_callback[i] != NULL) { mutex_unlock(&(lm->mtx)); - printk("Location monitor callback attached, can't " - "reset\n"); + dev_err(tsi148_bridge->parent, "Location monitor " + "callback attached, can't reset\n"); return -EBUSY; } } @@ -1922,7 +1945,7 @@ int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, break; default: mutex_unlock(&(lm->mtx)); - printk("Invalid address space\n"); + dev_err(tsi148_bridge->parent, "Invalid address space\n"); return -EINVAL; break; } @@ -2005,9 +2028,12 @@ int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor, void (*callback)(int)) { u32 lm_ctl, tmp; + struct vme_bridge *tsi148_bridge; struct tsi148_driver *bridge; - bridge = lm->parent->driver_priv; + tsi148_bridge = lm->parent; + + bridge = tsi148_bridge->driver_priv; mutex_lock(&(lm->mtx)); @@ -2015,14 +2041,15 @@ int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor, lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT); if ((lm_ctl & (TSI148_LCSR_LMAT_PGM | TSI148_LCSR_LMAT_DATA)) == 0) { mutex_unlock(&(lm->mtx)); - printk("Location monitor not properly configured\n"); + dev_err(tsi148_bridge->parent, "Location monitor not properly " + "configured\n"); return -EINVAL; } /* Check that a callback isn't already attached */ if (bridge->lm_callback[monitor] != NULL) { mutex_unlock(&(lm->mtx)); - printk("Existing callback attached\n"); + dev_err(tsi148_bridge->parent, "Existing callback attached\n"); return -EBUSY; } @@ -2139,8 +2166,8 @@ static int tsi148_crcsr_init(struct vme_bridge *tsi148_bridge, bridge->crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE, &(bridge->crcsr_bus)); if (bridge->crcsr_kernel == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for CR/CSR " - "image\n"); + dev_err(tsi148_bridge->parent, "Failed to allocate memory for " + "CR/CSR image\n"); return -ENOMEM; } @@ -2159,18 +2186,18 @@ static int tsi148_crcsr_init(struct vme_bridge *tsi148_bridge, if (cbar != vstat) { cbar = vstat; - dev_info(&pdev->dev, "Setting CR/CSR offset\n"); + dev_info(tsi148_bridge->parent, "Setting CR/CSR offset\n"); iowrite32be(cbar<<3, bridge->base + TSI148_CBAR); } - dev_info(&pdev->dev, "CR/CSR Offset: %d\n", cbar); + dev_info(tsi148_bridge->parent, "CR/CSR Offset: %d\n", cbar); crat = ioread32be(bridge->base + TSI148_LCSR_CRAT); if (crat & TSI148_LCSR_CRAT_EN) { - dev_info(&pdev->dev, "Enabling CR/CSR space\n"); + dev_info(tsi148_bridge->parent, "Enabling CR/CSR space\n"); iowrite32be(crat | TSI148_LCSR_CRAT_EN, bridge->base + TSI148_LCSR_CRAT); } else - dev_info(&pdev->dev, "CR/CSR already enabled\n"); + dev_info(tsi148_bridge->parent, "CR/CSR already enabled\n"); /* If we want flushed, error-checked writes, set up a window * over the CR/CSR registers. We read from here to safely flush @@ -2181,7 +2208,8 @@ static int tsi148_crcsr_init(struct vme_bridge *tsi148_bridge, (vstat * 0x80000), 0x80000, VME_CRCSR, VME_SCT, VME_D16); if (retval) - dev_err(&pdev->dev, "Configuring flush image failed\n"); + dev_err(tsi148_bridge->parent, "Configuring flush image" + " failed\n"); } return 0; @@ -2623,8 +2651,6 @@ static void tsi148_remove(struct pci_dev *pdev) static void __exit tsi148_exit(void) { pci_unregister_driver(&tsi148_driver); - - printk(KERN_DEBUG "Driver removed.\n"); } MODULE_PARM_DESC(err_chk, "Check for VME errors on reads and writes"); -- cgit v1.2.3 From 7946328faf1dca9bfadf98f4579f95aafffaba0f Mon Sep 17 00:00:00 2001 From: Martyn Welch Date: Mon, 22 Mar 2010 14:58:57 +0000 Subject: Staging: vme: Correct checkpatch errors Correct numerous checkpatch errors in the vme driver. Signed-off-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/bridges/vme_ca91cx42.c | 9 +- drivers/staging/vme/bridges/vme_tsi148.c | 186 +++++++++++++---------------- drivers/staging/vme/bridges/vme_tsi148.h | 26 ++-- 3 files changed, 102 insertions(+), 119 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c index 589664c4d24e..b9f986b856eb 100644 --- a/drivers/staging/vme/bridges/vme_ca91cx42.c +++ b/drivers/staging/vme/bridges/vme_ca91cx42.c @@ -26,9 +26,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include "../vme.h" #include "../vme_bridge.h" @@ -1684,9 +1684,8 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) dev_info(&pdev->dev, "Slot ID is %d\n", ca91cx42_slot_get(ca91cx42_bridge)); - if (ca91cx42_crcsr_init(ca91cx42_bridge, pdev)) { + if (ca91cx42_crcsr_init(ca91cx42_bridge, pdev)) dev_err(&pdev->dev, "CR/CSR configuration failed.\n"); - } /* Need to save ca91cx42_bridge pointer locally in link list for use in * ca91cx42_remove() diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index fa0dc4a869e9..25987d4069f2 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -26,9 +26,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include "../vme.h" #include "../vme_bridge.h" @@ -40,27 +40,6 @@ static void tsi148_remove(struct pci_dev *); static void __exit tsi148_exit(void); -int tsi148_slave_set(struct vme_slave_resource *, int, unsigned long long, - unsigned long long, dma_addr_t, vme_address_t, vme_cycle_t); -int tsi148_slave_get(struct vme_slave_resource *, int *, unsigned long long *, - unsigned long long *, dma_addr_t *, vme_address_t *, vme_cycle_t *); - -int tsi148_master_get(struct vme_master_resource *, int *, unsigned long long *, - unsigned long long *, vme_address_t *, vme_cycle_t *, vme_width_t *); -int tsi148_master_set(struct vme_master_resource *, int, unsigned long long, - unsigned long long, vme_address_t, vme_cycle_t, vme_width_t); -ssize_t tsi148_master_read(struct vme_master_resource *, void *, size_t, - loff_t); -ssize_t tsi148_master_write(struct vme_master_resource *, void *, size_t, - loff_t); -unsigned int tsi148_master_rmw(struct vme_master_resource *, unsigned int, - unsigned int, unsigned int, loff_t); -int tsi148_dma_list_add (struct vme_dma_list *, struct vme_dma_attr *, - struct vme_dma_attr *, size_t); -int tsi148_dma_list_exec(struct vme_dma_list *); -int tsi148_dma_list_empty(struct vme_dma_list *); -int tsi148_generate_irq(int, int); - /* Module parameter */ static int err_chk; static int geoid; @@ -122,7 +101,7 @@ static u32 tsi148_LM_irqhandler(struct tsi148_driver *bridge, u32 stat) u32 serviced = 0; for (i = 0; i < 4; i++) { - if(stat & TSI148_LCSR_INTS_LMS[i]) { + if (stat & TSI148_LCSR_INTS_LMS[i]) { /* We only enable interrupts if the callback is set */ bridge->lm_callback[i](i); serviced |= TSI148_LCSR_INTC_LMC[i]; @@ -147,7 +126,7 @@ static u32 tsi148_MB_irqhandler(struct vme_bridge *tsi148_bridge, u32 stat) bridge = tsi148_bridge->driver_priv; for (i = 0; i < 4; i++) { - if(stat & TSI148_LCSR_INTS_MBS[i]) { + if (stat & TSI148_LCSR_INTS_MBS[i]) { val = ioread32be(bridge->base + TSI148_GCSR_MBOX[i]); dev_err(tsi148_bridge->parent, "VME Mailbox %d received" ": 0x%x\n", i, val); @@ -203,13 +182,12 @@ static u32 tsi148_VERR_irqhandler(struct vme_bridge *tsi148_bridge) reg_join(error_addr_high, error_addr_low, &error_addr); /* Check for exception register overflow (we have lost error data) */ - if(error_attrib & TSI148_LCSR_VEAT_VEOF) { + if (error_attrib & TSI148_LCSR_VEAT_VEOF) { dev_err(tsi148_bridge->parent, "VME Bus Exception Overflow " "Occurred\n"); } - error = (struct vme_bus_error *)kmalloc(sizeof (struct vme_bus_error), - GFP_ATOMIC); + error = kmalloc(sizeof(struct vme_bus_error), GFP_ATOMIC); if (error) { error->address = error_addr; error->attributes = error_attrib; @@ -251,10 +229,9 @@ static u32 tsi148_VIRQ_irqhandler(struct vme_bridge *tsi148_bridge, for (i = 7; i > 0; i--) { if (stat & (1 << i)) { /* - * Note: Even though the registers are defined - * as 32-bits in the spec, we only want to issue - * 8-bit IACK cycles on the bus, read from offset - * 3. + * Note: Even though the registers are defined as + * 32-bits in the spec, we only want to issue 8-bit + * IACK cycles on the bus, read from offset 3. */ vec = ioread8(bridge->base + TSI148_LCSR_VIACK[i] + 3); @@ -288,9 +265,8 @@ static irqreturn_t tsi148_irqhandler(int irq, void *ptr) /* Only look at unmasked interrupts */ stat &= enable; - if (unlikely(!stat)) { + if (unlikely(!stat)) return IRQ_NONE; - } /* Call subhandlers as appropriate */ /* DMA irqs */ @@ -522,7 +498,9 @@ static struct vme_bus_error *tsi148_find_error(struct vme_bridge *tsi148_bridge, /* Iterate through errors */ list_for_each(err_pos, &(tsi148_bridge->vme_errors)) { vme_err = list_entry(err_pos, struct vme_bus_error, list); - if((vme_err->address >= address) && (vme_err->address < bound)){ + if ((vme_err->address >= address) && + (vme_err->address < bound)) { + valid = vme_err; break; } @@ -555,7 +533,9 @@ static void tsi148_clear_errors(struct vme_bridge *tsi148_bridge, list_for_each_safe(err_pos, temp, &(tsi148_bridge->vme_errors)) { vme_err = list_entry(err_pos, struct vme_bus_error, list); - if((vme_err->address >= address) && (vme_err->address < bound)){ + if ((vme_err->address >= address) && + (vme_err->address < bound)) { + list_del(err_pos); kfree(vme_err); } @@ -844,9 +824,8 @@ static int tsi148_alloc_resource(struct vme_master_resource *image, } /* Exit here if size is zero */ - if (size == 0) { + if (size == 0) return 0; - } if (image->bus_resource.name == NULL) { image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL); @@ -912,7 +891,7 @@ static void tsi148_free_resource(struct vme_master_resource *image) /* * Set the attributes of an outbound window. */ -int tsi148_master_set( struct vme_master_resource *image, int enabled, +int tsi148_master_set(struct vme_master_resource *image, int enabled, unsigned long long vme_base, unsigned long long size, vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth) { @@ -1148,7 +1127,7 @@ err_window: * * XXX Not parsing prefetch information. */ -int __tsi148_master_get( struct vme_master_resource *image, int *enabled, +int __tsi148_master_get(struct vme_master_resource *image, int *enabled, unsigned long long *vme_base, unsigned long long *size, vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth) { @@ -1225,17 +1204,17 @@ int __tsi148_master_get( struct vme_master_resource *image, int *enabled, *cycle |= VME_2eSST320; /* Setup cycle types */ - if ((ctl & TSI148_LCSR_OTAT_TM_M ) == TSI148_LCSR_OTAT_TM_SCT) + if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_SCT) *cycle |= VME_SCT; - if ((ctl & TSI148_LCSR_OTAT_TM_M ) == TSI148_LCSR_OTAT_TM_BLT) + if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_BLT) *cycle |= VME_BLT; - if ((ctl & TSI148_LCSR_OTAT_TM_M ) == TSI148_LCSR_OTAT_TM_MBLT) + if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_MBLT) *cycle |= VME_MBLT; - if ((ctl & TSI148_LCSR_OTAT_TM_M ) == TSI148_LCSR_OTAT_TM_2eVME) + if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_2eVME) *cycle |= VME_2eVME; - if ((ctl & TSI148_LCSR_OTAT_TM_M ) == TSI148_LCSR_OTAT_TM_2eSST) + if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_2eSST) *cycle |= VME_2eSST; - if ((ctl & TSI148_LCSR_OTAT_TM_M ) == TSI148_LCSR_OTAT_TM_2eSSTB) + if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_2eSSTB) *cycle |= VME_2eSSTB; if (ctl & TSI148_LCSR_OTAT_SUP) @@ -1258,7 +1237,7 @@ int __tsi148_master_get( struct vme_master_resource *image, int *enabled, } -int tsi148_master_get( struct vme_master_resource *image, int *enabled, +int tsi148_master_get(struct vme_master_resource *image, int *enabled, unsigned long long *vme_base, unsigned long long *size, vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth) { @@ -1300,7 +1279,7 @@ ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf, vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset, count); - if(vme_err != NULL) { + if (vme_err != NULL) { dev_err(image->parent->parent, "First VME read error detected " "an at address 0x%llx\n", vme_err->address); retval = vme_err->address - (vme_base + offset); @@ -1363,7 +1342,7 @@ ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf, vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset, count); - if(vme_err != NULL) { + if (vme_err != NULL) { dev_warn(tsi148_bridge->parent, "First VME write error detected" " an at address 0x%llx\n", vme_err->address); retval = vme_err->address - (vme_base + offset); @@ -1456,21 +1435,21 @@ static int tsi148_dma_set_vme_src_attributes(struct device *dev, u32 *attr, } /* Setup cycle types */ - if (cycle & VME_SCT) { + if (cycle & VME_SCT) *attr |= TSI148_LCSR_DSAT_TM_SCT; - } - if (cycle & VME_BLT) { + + if (cycle & VME_BLT) *attr |= TSI148_LCSR_DSAT_TM_BLT; - } - if (cycle & VME_MBLT) { + + if (cycle & VME_MBLT) *attr |= TSI148_LCSR_DSAT_TM_MBLT; - } - if (cycle & VME_2eVME) { + + if (cycle & VME_2eVME) *attr |= TSI148_LCSR_DSAT_TM_2eVME; - } - if (cycle & VME_2eSST) { + + if (cycle & VME_2eSST) *attr |= TSI148_LCSR_DSAT_TM_2eSST; - } + if (cycle & VME_2eSSTB) { dev_err(dev, "Currently not setting Broadcast Select " "Registers\n"); @@ -1550,21 +1529,21 @@ static int tsi148_dma_set_vme_dest_attributes(struct device *dev, u32 *attr, } /* Setup cycle types */ - if (cycle & VME_SCT) { + if (cycle & VME_SCT) *attr |= TSI148_LCSR_DDAT_TM_SCT; - } - if (cycle & VME_BLT) { + + if (cycle & VME_BLT) *attr |= TSI148_LCSR_DDAT_TM_BLT; - } - if (cycle & VME_MBLT) { + + if (cycle & VME_MBLT) *attr |= TSI148_LCSR_DDAT_TM_MBLT; - } - if (cycle & VME_2eVME) { + + if (cycle & VME_2eVME) *attr |= TSI148_LCSR_DDAT_TM_2eVME; - } - if (cycle & VME_2eSST) { + + if (cycle & VME_2eSST) *attr |= TSI148_LCSR_DDAT_TM_2eSST; - } + if (cycle & VME_2eSSTB) { dev_err(dev, "Currently not setting Broadcast Select " "Registers\n"); @@ -1630,7 +1609,7 @@ static int tsi148_dma_set_vme_dest_attributes(struct device *dev, u32 *attr, /* * Add a link list descriptor to the list */ -int tsi148_dma_list_add (struct vme_dma_list *list, struct vme_dma_attr *src, +int tsi148_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, struct vme_dma_attr *dest, size_t count) { struct tsi148_dma_entry *entry, *prev; @@ -1645,8 +1624,7 @@ int tsi148_dma_list_add (struct vme_dma_list *list, struct vme_dma_attr *src, tsi148_bridge = list->parent->parent; /* Descriptor must be aligned on 64-bit boundaries */ - entry = (struct tsi148_dma_entry *)kmalloc( - sizeof(struct tsi148_dma_entry), GFP_KERNEL); + entry = kmalloc(sizeof(struct tsi148_dma_entry), GFP_KERNEL); if (entry == NULL) { dev_err(tsi148_bridge->parent, "Failed to allocate memory for " "dma resource structure\n"); @@ -1676,13 +1654,13 @@ int tsi148_dma_list_add (struct vme_dma_list *list, struct vme_dma_attr *src, entry->descriptor.dsal = pattern_attr->pattern; entry->descriptor.dsat = TSI148_LCSR_DSAT_TYP_PAT; /* Default behaviour is 32 bit pattern */ - if (pattern_attr->type & VME_DMA_PATTERN_BYTE) { + if (pattern_attr->type & VME_DMA_PATTERN_BYTE) entry->descriptor.dsat |= TSI148_LCSR_DSAT_PSZ; - } + /* It seems that the default behaviour is to increment */ - if ((pattern_attr->type & VME_DMA_PATTERN_INCREMENT) == 0) { + if ((pattern_attr->type & VME_DMA_PATTERN_INCREMENT) == 0) entry->descriptor.dsat |= TSI148_LCSR_DSAT_NIN; - } + break; case VME_DMA_PCI: pci_attr = (struct vme_dma_pci *)src->private; @@ -1705,7 +1683,7 @@ int tsi148_dma_list_add (struct vme_dma_list *list, struct vme_dma_attr *src, retval = tsi148_dma_set_vme_src_attributes( tsi148_bridge->parent, &(entry->descriptor.dsat), vme_attr->aspace, vme_attr->cycle, vme_attr->dwidth); - if(retval < 0 ) + if (retval < 0) goto err_source; break; default: @@ -1743,7 +1721,7 @@ int tsi148_dma_list_add (struct vme_dma_list *list, struct vme_dma_attr *src, retval = tsi148_dma_set_vme_dest_attributes( tsi148_bridge->parent, &(entry->descriptor.ddat), vme_attr->aspace, vme_attr->cycle, vme_attr->dwidth); - if(retval < 0 ) + if (retval < 0) goto err_dest; break; default: @@ -1760,7 +1738,7 @@ int tsi148_dma_list_add (struct vme_dma_list *list, struct vme_dma_attr *src, list_add_tail(&(entry->list), &(list->entries)); /* Fill out previous descriptors "Next Address" */ - if(entry->list.prev != &(list->entries)){ + if (entry->list.prev != &(list->entries)) { prev = list_entry(entry->list.prev, struct tsi148_dma_entry, list); /* We need the bus address for the pointer */ @@ -1825,7 +1803,7 @@ int tsi148_dma_list_exec(struct vme_dma_list *list) channel = ctrlr->number; - if (! list_empty(&(ctrlr->running))) { + if (!list_empty(&(ctrlr->running))) { /* * XXX We have an active DMA transfer and currently haven't * sorted out the mechanism for "pending" DMA transfers. @@ -1887,7 +1865,7 @@ int tsi148_dma_list_exec(struct vme_dma_list *list) int tsi148_dma_list_empty(struct vme_dma_list *list) { struct list_head *pos, *temp; - struct tsi148_dma_entry *entry; + struct tsi148_dma_entry *entry; /* detach and free each entry */ list_for_each_safe(pos, temp, &(list->entries)) { @@ -1896,7 +1874,7 @@ int tsi148_dma_list_empty(struct vme_dma_list *list) kfree(entry); } - return (0); + return 0; } /* @@ -1992,18 +1970,18 @@ int tsi148_lm_get(struct vme_lm_resource *lm, unsigned long long *lm_base, if (lm_ctl & TSI148_LCSR_LMAT_EN) enabled = 1; - if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A16) { + if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A16) *aspace |= VME_A16; - } - if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A24) { + + if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A24) *aspace |= VME_A24; - } - if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A32) { + + if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A32) *aspace |= VME_A32; - } - if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A64) { + + if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A64) *aspace |= VME_A64; - } + if (lm_ctl & TSI148_LCSR_LMAT_SUPR) *cycle |= VME_SUPER; @@ -2121,7 +2099,7 @@ int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor) */ int tsi148_slot_get(struct vme_bridge *tsi148_bridge) { - u32 slot = 0; + u32 slot = 0; struct tsi148_driver *bridge; bridge = tsi148_bridge->driver_priv; @@ -2203,7 +2181,7 @@ static int tsi148_crcsr_init(struct vme_bridge *tsi148_bridge, * over the CR/CSR registers. We read from here to safely flush * through VME writes. */ - if(err_chk) { + if (err_chk) { retval = tsi148_master_set(bridge->flush_image, 1, (vstat * 0x80000), 0x80000, VME_CRCSR, VME_SCT, VME_D16); @@ -2252,8 +2230,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* If we want to support more than one of each bridge, we need to * dynamically generate this so we get one per device */ - tsi148_bridge = (struct vme_bridge *)kmalloc(sizeof(struct vme_bridge), - GFP_KERNEL); + tsi148_bridge = kmalloc(sizeof(struct vme_bridge), GFP_KERNEL); if (tsi148_bridge == NULL) { dev_err(&pdev->dev, "Failed to allocate memory for device " "structure\n"); @@ -2329,7 +2306,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) * hence have one less master window resource available. */ master_num = TSI148_MAX_MASTER; - if(err_chk){ + if (err_chk) { master_num--; tsi148_device->flush_image = (struct vme_master_resource *) @@ -2359,8 +2336,8 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* Add master windows to list */ INIT_LIST_HEAD(&(tsi148_bridge->master_resources)); for (i = 0; i < master_num; i++) { - master_image = (struct vme_master_resource *)kmalloc( - sizeof(struct vme_master_resource), GFP_KERNEL); + master_image = kmalloc(sizeof(struct vme_master_resource), + GFP_KERNEL); if (master_image == NULL) { dev_err(&pdev->dev, "Failed to allocate memory for " "master resource structure\n"); @@ -2388,8 +2365,8 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* Add slave windows to list */ INIT_LIST_HEAD(&(tsi148_bridge->slave_resources)); for (i = 0; i < TSI148_MAX_SLAVE; i++) { - slave_image = (struct vme_slave_resource *)kmalloc( - sizeof(struct vme_slave_resource), GFP_KERNEL); + slave_image = kmalloc(sizeof(struct vme_slave_resource), + GFP_KERNEL); if (slave_image == NULL) { dev_err(&pdev->dev, "Failed to allocate memory for " "slave resource structure\n"); @@ -2414,8 +2391,8 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* Add dma engines to list */ INIT_LIST_HEAD(&(tsi148_bridge->dma_resources)); for (i = 0; i < TSI148_MAX_DMA; i++) { - dma_ctrlr = (struct vme_dma_resource *)kmalloc( - sizeof(struct vme_dma_resource), GFP_KERNEL); + dma_ctrlr = kmalloc(sizeof(struct vme_dma_resource), + GFP_KERNEL); if (dma_ctrlr == NULL) { dev_err(&pdev->dev, "Failed to allocate memory for " "dma resource structure\n"); @@ -2472,7 +2449,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT); dev_info(&pdev->dev, "Board is%s the VME system controller\n", - (data & TSI148_LCSR_VSTAT_SCONS)? "" : " not"); + (data & TSI148_LCSR_VSTAT_SCONS) ? "" : " not"); if (!geoid) dev_info(&pdev->dev, "VME geographical address is %d\n", data & TSI148_LCSR_VSTAT_GA_M); @@ -2531,7 +2508,8 @@ err_slave: err_master: /* resources are stored in link list */ list_for_each(pos, &(tsi148_bridge->master_resources)) { - master_image = list_entry(pos, struct vme_master_resource, list); + master_image = list_entry(pos, struct vme_master_resource, + list); list_del(pos); kfree(master_image); } diff --git a/drivers/staging/vme/bridges/vme_tsi148.h b/drivers/staging/vme/bridges/vme_tsi148.h index 9e5f7fa1d744..bda64ef85754 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.h +++ b/drivers/staging/vme/bridges/vme_tsi148.h @@ -579,7 +579,7 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, /* * Memory Base Address Lower Reg (CRG + $010) */ -#define TSI148_PCFS_MBARL_BASEL_M (0xFFFFF<<12) /* Base Addr Lower Mask */ +#define TSI148_PCFS_MBARL_BASEL_M (0xFFFFF<<12) /* Base Addr Lower Mask */ #define TSI148_PCFS_MBARL_PRE (1<<3) /* Prefetch */ #define TSI148_PCFS_MBARL_MTYPE_M (3<<1) /* Memory Type Mask */ #define TSI148_PCFS_MBARL_IOMEM (1<<0) /* I/O Space Indicator */ @@ -615,7 +615,8 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, */ #define TSI148_PCFS_PCIXSTAT_RSCEM (1<<29) /* Recieved Split Comp Error */ #define TSI148_PCFS_PCIXSTAT_DMCRS_M (7<<26) /* max Cumulative Read Size */ -#define TSI148_PCFS_PCIXSTAT_DMOST_M (7<<23) /* max outstanding Split Trans */ +#define TSI148_PCFS_PCIXSTAT_DMOST_M (7<<23) /* max outstanding Split Trans + */ #define TSI148_PCFS_PCIXSTAT_DMMRC_M (3<<21) /* max mem read byte count */ #define TSI148_PCFS_PCIXSTAT_DC (1<<20) /* Device Complexity */ #define TSI148_PCFS_PCIXSTAT_USC (1<<19) /* Unexpected Split comp */ @@ -703,7 +704,8 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, #define TSI148_LCSR_VMCTRL_RMWEN (1<<20) /* RMW Enable */ -#define TSI148_LCSR_VMCTRL_ATO_M (7<<16) /* Master Access Time-out Mask */ +#define TSI148_LCSR_VMCTRL_ATO_M (7<<16) /* Master Access Time-out Mask + */ #define TSI148_LCSR_VMCTRL_ATO_32 (0<<16) /* 32 us */ #define TSI148_LCSR_VMCTRL_ATO_128 (1<<16) /* 128 us */ #define TSI148_LCSR_VMCTRL_ATO_512 (2<<16) /* 512 us */ @@ -733,14 +735,16 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, #define TSI148_LCSR_VMCTRL_VTON_256 (6<<8) /* 256us */ #define TSI148_LCSR_VMCTRL_VTON_512 (7<<8) /* 512us */ -#define TSI148_LCSR_VMCTRL_VREL_M (3<<3) /* VMEbus Master Rel Mode Mask */ +#define TSI148_LCSR_VMCTRL_VREL_M (3<<3) /* VMEbus Master Rel Mode Mask + */ #define TSI148_LCSR_VMCTRL_VREL_T_D (0<<3) /* Time on or Done */ #define TSI148_LCSR_VMCTRL_VREL_T_R_D (1<<3) /* Time on and REQ or Done */ #define TSI148_LCSR_VMCTRL_VREL_T_B_D (2<<3) /* Time on and BCLR or Done */ #define TSI148_LCSR_VMCTRL_VREL_T_D_R (3<<3) /* Time on or Done and REQ */ #define TSI148_LCSR_VMCTRL_VFAIR (1<<2) /* VMEbus Master Fair Mode */ -#define TSI148_LCSR_VMCTRL_VREQL_M (3<<0) /* VMEbus Master Req Level Mask */ +#define TSI148_LCSR_VMCTRL_VREQL_M (3<<0) /* VMEbus Master Req Level Mask + */ /* * VMEbus Control Register CRG+$238 @@ -762,7 +766,8 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, #define TSI148_LCSR_VCTRL_DLT_16384 (0xB<<24) /* 16384 VCLKS */ #define TSI148_LCSR_VCTRL_DLT_32768 (0xC<<24) /* 32768 VCLKS */ -#define TSI148_LCSR_VCTRL_NERBB (1<<20) /* No Early Release of Bus Busy */ +#define TSI148_LCSR_VCTRL_NERBB (1<<20) /* No Early Release of Bus Busy + */ #define TSI148_LCSR_VCTRL_SRESET (1<<17) /* System Reset */ #define TSI148_LCSR_VCTRL_LRESET (1<<16) /* Local Reset */ @@ -773,7 +778,8 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, #define TSI148_LCSR_VCTRL_ATOEN (1<<7) /* Arbiter Time-out Enable */ #define TSI148_LCSR_VCTRL_ROBIN (1<<6) /* VMEbus Round Robin */ -#define TSI148_LCSR_VCTRL_GTO_M (7<<0) /* VMEbus Global Time-out Mask */ +#define TSI148_LCSR_VCTRL_GTO_M (7<<0) /* VMEbus Global Time-out Mask + */ #define TSI148_LCSR_VCTRL_GTO_8 (0<<0) /* 8 us */ #define TSI148_LCSR_VCTRL_GTO_16 (1<<0) /* 16 us */ #define TSI148_LCSR_VCTRL_GTO_32 (2<<0) /* 32 us */ @@ -794,7 +800,7 @@ static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, #define TSI148_LCSR_VSTAT_ACFAILS (1<<9) /* AC fail status */ #define TSI148_LCSR_VSTAT_SCONS (1<<8) /* System Cont Status */ #define TSI148_LCSR_VSTAT_GAP (1<<5) /* Geographic Addr Parity */ -#define TSI148_LCSR_VSTAT_GA_M (0x1F<<0) /* Geographic Addr Mask */ +#define TSI148_LCSR_VSTAT_GA_M (0x1F<<0) /* Geographic Addr Mask */ /* * PCI Configuration Status Register CRG+$240 @@ -1341,7 +1347,7 @@ static const int TSI148_LCSR_INTC_MBC[4] = { TSI148_LCSR_INTC_MB0C, * DMA Next Link Address Lower */ #define TSI148_LCSR_DNLAL_DNLAL_M (0x3FFFFFF<<6) /* Address Mask */ -#define TSI148_LCSR_DNLAL_LLA (1<<0) /* Last Link Address Indicator */ +#define TSI148_LCSR_DNLAL_LLA (1<<0) /* Last Link Address Indicator */ /* * DMA 2eSST Broadcast Select @@ -1371,7 +1377,7 @@ static const int TSI148_LCSR_INTC_MBC[4] = { TSI148_LCSR_INTC_MB0C, #define TSI148_GCSR_GCTRL_MBI0S (1<<0) /* Mail box 0 Int Status */ #define TSI148_GCSR_GAP (1<<5) /* Geographic Addr Parity */ -#define TSI148_GCSR_GA_M (0x1F<<0) /* Geographic Address Mask */ +#define TSI148_GCSR_GA_M (0x1F<<0) /* Geographic Address Mask */ /* * CR/CSR Register Group -- cgit v1.2.3 From 1fe923ec740ad8d87e616afc50f5b00d88a75ed2 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 28 Apr 2010 16:40:10 -0400 Subject: Staging: vme: declare vme_bus_num_mtx static Signed-off-by: Bill Pemberton Cc: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/vme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c index 934283a19ca5..58aa276764f3 100644 --- a/drivers/staging/vme/vme.c +++ b/drivers/staging/vme/vme.c @@ -36,7 +36,7 @@ /* Bitmask and mutex to keep track of bridge numbers */ static unsigned int vme_bus_numbers; -DEFINE_MUTEX(vme_bus_num_mtx); +static DEFINE_MUTEX(vme_bus_num_mtx); static void __exit vme_exit(void); static int __init vme_init(void); -- cgit v1.2.3 From b1a5fad4c36117b1399ed65899088fcb907e2cbd Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 28 Apr 2010 16:40:11 -0400 Subject: Staging: vme: declare vme_calc_slot() as static vme_calc_slot() is not used anywhere other than vme.c so it should be declared as static. Signed-off-by: Bill Pemberton Cc: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/vme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c index 58aa276764f3..093fbffbf557 100644 --- a/drivers/staging/vme/vme.c +++ b/drivers/staging/vme/vme.c @@ -1408,7 +1408,7 @@ EXPORT_SYMBOL(vme_unregister_driver); /* - Bus Registration ------------------------------------------------------ */ -int vme_calc_slot(struct device *dev) +static int vme_calc_slot(struct device *dev) { struct vme_bridge *bridge; int num; -- cgit v1.2.3 From c98aaf85550e314228781ba134c68bb5ca33ab6a Mon Sep 17 00:00:00 2001 From: Johan Meiring Date: Sun, 28 Mar 2010 21:36:09 +0200 Subject: Staging: line6: rewrote inline comments in control.h This is a patch to control.h that presents certain inline comments in a neater way, and which eliminates the 80 character error found by the checkpatch.pl tool. Signed-off-by: Johan Meiring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/control.h | 166 +++++++++++++++++++++++++++++----------- 1 file changed, 123 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/line6/control.h b/drivers/staging/line6/control.h index 2f19665d95a9..47e18ab6d5b0 100644 --- a/drivers/staging/line6/control.h +++ b/drivers/staging/line6/control.h @@ -22,24 +22,44 @@ enum { POD_tweak = 1, POD_wah_position = 4, - POD_compression_gain = 5, /* device: LINE6_BITS_PODXTALL */ + + /* device: LINE6_BITS_PODXTALL */ + POD_compression_gain = 5, + POD_vol_pedal_position = 7, POD_compression_threshold = 9, POD_pan = 10, POD_amp_model_setup = 11, - POD_amp_model = 12, /* firmware: 2.0 */ + POD_amp_model = 12, /* firmware: 2.0 */ POD_drive = 13, POD_bass = 14, - POD_mid = 15, /* device: LINE6_BITS_PODXTALL */ - POD_lowmid = 15, /* device: LINE6_BITS_BASSPODXTALL */ - POD_treble = 16, /* device: LINE6_BITS_PODXTALL */ - POD_highmid = 16, /* device: LINE6_BITS_BASSPODXTALL */ + + /* device: LINE6_BITS_PODXTALL */ + POD_mid = 15, + + /* device: LINE6_BITS_BASSPODXTALL */ + POD_lowmid = 15, + + /* device: LINE6_BITS_PODXTALL */ + POD_treble = 16, + + /* device: LINE6_BITS_BASSPODXTALL */ + POD_highmid = 16, + POD_chan_vol = 17, - POD_reverb_mix = 18, /* device: LINE6_BITS_PODXTALL */ + + /* device: LINE6_BITS_PODXTALL */ + POD_reverb_mix = 18, + POD_effect_setup = 19, POD_band_1_frequency = 20, /* firmware: 2.0 */ - POD_presence = 21, /* device: LINE6_BITS_PODXTALL */ - POD_treble__bass = 21, /* device: LINE6_BITS_BASSPODXTALL */ + + /* device: LINE6_BITS_PODXTALL */ + POD_presence = 21, + + /* device: LINE6_BITS_BASSPODXTALL */ + POD_treble__bass = 21, + POD_noise_gate_enable = 22, POD_gate_threshold = 23, POD_gate_decay_time = 24, @@ -50,78 +70,137 @@ enum { POD_mod_param_1 = 29, POD_delay_param_1 = 30, POD_delay_param_1_note_value = 31, - POD_band_2_frequency__bass = 32, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ + + /* device: LINE6_BITS_BASSPODXTALL */ + POD_band_2_frequency__bass = 32, /* firmware: 2.0 */ + POD_delay_param_2 = 33, POD_delay_volume_mix = 34, POD_delay_param_3 = 35, - POD_reverb_enable = 36, /* device: LINE6_BITS_PODXTALL */ - POD_reverb_type = 37, /* device: LINE6_BITS_PODXTALL */ - POD_reverb_decay = 38, /* device: LINE6_BITS_PODXTALL */ - POD_reverb_tone = 39, /* device: LINE6_BITS_PODXTALL */ - POD_reverb_pre_delay = 40, /* device: LINE6_BITS_PODXTALL */ - POD_reverb_pre_post = 41, /* device: LINE6_BITS_PODXTALL */ - POD_band_2_frequency = 42, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */ - POD_band_3_frequency__bass = 42, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ + + /* device: LINE6_BITS_PODXTALL */ + POD_reverb_enable = 36, + POD_reverb_type = 37, + POD_reverb_decay = 38, + POD_reverb_tone = 39, + POD_reverb_pre_delay = 40, + POD_reverb_pre_post = 41, + POD_band_2_frequency = 42, + + /* device: LINE6_BITS_BASSPODXTALL */ + POD_band_3_frequency__bass = 42, /* firmware: 2.0 */ + POD_wah_enable = 43, - POD_modulation_lo_cut = 44, /* device: LINE6_BITS_BASSPODXTALL */ - POD_delay_reverb_lo_cut = 45, /* device: LINE6_BITS_BASSPODXTALL */ - POD_volume_pedal_minimum = 46, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */ - POD_eq_pre_post = 46, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ + + /* device: LINE6_BITS_BASSPODXTALL */ + POD_modulation_lo_cut = 44, + POD_delay_reverb_lo_cut = 45, + + /* device: LINE6_BITS_PODXTALL */ + POD_volume_pedal_minimum = 46, /* firmware: 2.0 */ + + /* device: LINE6_BITS_BASSPODXTALL */ + POD_eq_pre_post = 46, /* firmware: 2.0 */ + POD_volume_pre_post = 47, - POD_di_model = 48, /* device: LINE6_BITS_BASSPODXTALL */ - POD_di_delay = 49, /* device: LINE6_BITS_BASSPODXTALL */ + + /* device: LINE6_BITS_BASSPODXTALL */ + POD_di_model = 48, + POD_di_delay = 49, + POD_mod_enable = 50, POD_mod_param_1_note_value = 51, POD_mod_param_2 = 52, POD_mod_param_3 = 53, POD_mod_param_4 = 54, - POD_mod_param_5 = 55, /* device: LINE6_BITS_BASSPODXTALL */ + + /* device: LINE6_BITS_BASSPODXTALL */ + POD_mod_param_5 = 55, + POD_mod_volume_mix = 56, POD_mod_pre_post = 57, POD_modulation_model = 58, - POD_band_3_frequency = 60, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */ - POD_band_4_frequency__bass = 60, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ + + /* device: LINE6_BITS_PODXTALL */ + POD_band_3_frequency = 60, /* firmware: 2.0 */ + + /* device: LINE6_BITS_BASSPODXTALL */ + POD_band_4_frequency__bass = 60, /* firmware: 2.0 */ + POD_mod_param_1_double_precision = 61, POD_delay_param_1_double_precision = 62, POD_eq_enable = 63, /* firmware: 2.0 */ POD_tap = 64, POD_volume_tweak_pedal_assign = 65, - POD_band_5_frequency = 68, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ + + /* device: LINE6_BITS_BASSPODXTALL */ + POD_band_5_frequency = 68, /* firmware: 2.0 */ + POD_tuner = 69, POD_mic_selection = 70, POD_cabinet_model = 71, POD_stomp_model = 75, POD_roomlevel = 76, - POD_band_4_frequency = 77, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */ - POD_band_6_frequency = 77, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ + + /* device: LINE6_BITS_PODXTALL */ + POD_band_4_frequency = 77, /* firmware: 2.0 */ + + /* device: LINE6_BITS_BASSPODXTALL */ + POD_band_6_frequency = 77, /* firmware: 2.0 */ + POD_stomp_param_1_note_value = 78, POD_stomp_param_2 = 79, POD_stomp_param_3 = 80, POD_stomp_param_4 = 81, POD_stomp_param_5 = 82, POD_stomp_param_6 = 83, - POD_amp_switch_select = 84, /* device: LINE6_BITS_LIVE */ + + /* device: LINE6_BITS_LIVE */ + POD_amp_switch_select = 84, + POD_delay_param_4 = 85, POD_delay_param_5 = 86, POD_delay_pre_post = 87, - POD_delay_model = 88, /* device: LINE6_BITS_PODXTALL */ - POD_delay_verb_model = 88, /* device: LINE6_BITS_BASSPODXTALL */ + + /* device: LINE6_BITS_PODXTALL */ + POD_delay_model = 88, + + /* device: LINE6_BITS_BASSPODXTALL */ + POD_delay_verb_model = 88, + POD_tempo_msb = 89, POD_tempo_lsb = 90, POD_wah_model = 91, /* firmware: 3.0 */ POD_bypass_volume = 105, /* firmware: 2.14 */ - POD_fx_loop_on_off = 107, /* device: LINE6_BITS_PRO */ + + /* device: LINE6_BITS_PRO */ + POD_fx_loop_on_off = 107, + POD_tweak_param_select = 108, POD_amp1_engage = 111, POD_band_1_gain = 114, /* firmware: 2.0 */ - POD_band_2_gain__bass = 115, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ - POD_band_2_gain = 116, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */ - POD_band_3_gain__bass = 116, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ - POD_band_3_gain = 117, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */ - POD_band_4_gain__bass = 117, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ - POD_band_5_gain__bass = 118, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ - POD_band_4_gain = 119, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */ - POD_band_6_gain__bass = 119 /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */ + + /* device: LINE6_BITS_BASSPODXTALL */ + POD_band_2_gain__bass = 115, /* firmware: 2.0 */ + + /* device: LINE6_BITS_PODXTALL */ + POD_band_2_gain = 116, /* firmware: 2.0 */ + + /* device: LINE6_BITS_BASSPODXTALL */ + POD_band_3_gain__bass = 116, /* firmware: 2.0 */ + + /* device: LINE6_BITS_PODXTALL */ + POD_band_3_gain = 117, /* firmware: 2.0 */ + + /* device: LINE6_BITS_BASSPODXTALL */ + POD_band_4_gain__bass = 117, /* firmware: 2.0 */ + POD_band_5_gain__bass = 118, /* firmware: 2.0 */ + + /* device: LINE6_BITS_PODXTALL */ + POD_band_4_gain = 119, /* firmware: 2.0 */ + + /* device: LINE6_BITS_BASSPODXTALL */ + POD_band_6_gain__bass = 119 /* firmware: 2.0 */ }; /** @@ -139,7 +218,8 @@ enum { VARIAX_pickup2_position = 23, /* type: 24 bit float */ VARIAX_pickup2_angle = 26, /* type: 24 bit float */ VARIAX_pickup2_level = 29, /* type: 24 bit float */ - VARIAX_pickup_phase = 32, /* 0: in phase, 1: out of phase */ + VARIAX_pickup_phase = 32, /* 0: in phase, + 1: out of phase */ VARIAX_capacitance = 33, /* type: 24 bit float */ VARIAX_tone_resistance = 36, /* type: 24 bit float */ VARIAX_volume_resistance = 39, /* type: 24 bit float */ -- cgit v1.2.3 From 69d5b4919f53900860e91a89599d2347827dc805 Mon Sep 17 00:00:00 2001 From: Daniel Kenji Toyama Date: Mon, 29 Mar 2010 22:26:46 +1100 Subject: Staging: vt6656: rc4.c: Fixed coding style issues Replaced all indentation by spaces by tabs. Signed-off-by: Daniel Kenji Toyama Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/rc4.c | 78 ++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/rc4.c b/drivers/staging/vt6656/rc4.c index e6c61312fd28..64c419df9321 100644 --- a/drivers/staging/vt6656/rc4.c +++ b/drivers/staging/vt6656/rc4.c @@ -34,54 +34,54 @@ VOID rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len) { - UINT ust1, ust2; - UINT keyindex; - UINT stateindex; - PBYTE pbyst; - UINT idx; + UINT ust1, ust2; + UINT keyindex; + UINT stateindex; + PBYTE pbyst; + UINT idx; - pbyst = pRC4->abystate; - pRC4->ux = 0; - pRC4->uy = 0; - for (idx = 0; idx < 256; idx++) - pbyst[idx] = (BYTE)idx; - keyindex = 0; - stateindex = 0; - for (idx = 0; idx < 256; idx++) { - ust1 = pbyst[idx]; - stateindex = (stateindex + pbyKey[keyindex] + ust1) & 0xff; - ust2 = pbyst[stateindex]; - pbyst[stateindex] = (BYTE)ust1; - pbyst[idx] = (BYTE)ust2; - if (++keyindex >= cbKey_len) - keyindex = 0; - } + pbyst = pRC4->abystate; + pRC4->ux = 0; + pRC4->uy = 0; + for (idx = 0; idx < 256; idx++) + pbyst[idx] = (BYTE)idx; + keyindex = 0; + stateindex = 0; + for (idx = 0; idx < 256; idx++) { + ust1 = pbyst[idx]; + stateindex = (stateindex + pbyKey[keyindex] + ust1) & 0xff; + ust2 = pbyst[stateindex]; + pbyst[stateindex] = (BYTE)ust1; + pbyst[idx] = (BYTE)ust2; + if (++keyindex >= cbKey_len) + keyindex = 0; + } } UINT rc4_byte(PRC4Ext pRC4) { - UINT ux; - UINT uy; - UINT ustx, usty; - PBYTE pbyst; + UINT ux; + UINT uy; + UINT ustx, usty; + PBYTE pbyst; - pbyst = pRC4->abystate; - ux = (pRC4->ux + 1) & 0xff; - ustx = pbyst[ux]; - uy = (ustx + pRC4->uy) & 0xff; - usty = pbyst[uy]; - pRC4->ux = ux; - pRC4->uy = uy; - pbyst[uy] = (BYTE)ustx; - pbyst[ux] = (BYTE)usty; + pbyst = pRC4->abystate; + ux = (pRC4->ux + 1) & 0xff; + ustx = pbyst[ux]; + uy = (ustx + pRC4->uy) & 0xff; + usty = pbyst[uy]; + pRC4->ux = ux; + pRC4->uy = uy; + pbyst[uy] = (BYTE)ustx; + pbyst[ux] = (BYTE)usty; - return pbyst[(ustx + usty) & 0xff]; + return pbyst[(ustx + usty) & 0xff]; } VOID rc4_encrypt(PRC4Ext pRC4, PBYTE pbyDest, - PBYTE pbySrc, UINT cbData_len) + PBYTE pbySrc, UINT cbData_len) { - UINT ii; - for (ii = 0; ii < cbData_len; ii++) - pbyDest[ii] = (BYTE)(pbySrc[ii] ^ rc4_byte(pRC4)); + UINT ii; + for (ii = 0; ii < cbData_len; ii++) + pbyDest[ii] = (BYTE)(pbySrc[ii] ^ rc4_byte(pRC4)); } -- cgit v1.2.3 From f9ea02af482727d79e241dc28d69522f56f2c1a3 Mon Sep 17 00:00:00 2001 From: Daniel Kenji Toyama Date: Mon, 29 Mar 2010 22:40:54 +1100 Subject: Staging: vt6656: control.c: Fixed coding style issues Replaced lots of spaces by real tabs and fixed some 80+ lines. Signed-off-by: Daniel Kenji Toyama Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/control.c | 87 ++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/control.c b/drivers/staging/vt6656/control.c index 7dba7710e593..8aab6718ff47 100644 --- a/drivers/staging/vt6656/control.c +++ b/drivers/staging/vt6656/control.c @@ -30,11 +30,13 @@ * CONTROLnsRequestIn - Read variable length bytes from MEM/BB/MAC/EEPROM * ControlvWriteByte - Write one byte to MEM/BB/MAC/EEPROM * ControlvReadByte - Read one byte from MEM/BB/MAC/EEPROM - * ControlvMaskByte - Read one byte from MEM/BB/MAC/EEPROM and clear/set some bits in the same address + * ControlvMaskByte - Read one byte from MEM/BB/MAC/EEPROM and clear/set + * some bits in the same address * * Revision History: * 04-05-2004 Jerry Chen: Initial release - * 11-24-2004 Warren Hsu: Add ControlvWriteByte,ControlvReadByte,ControlvMaskByte + * 11-24-2004 Warren Hsu: Add ControlvWriteByte, ControlvReadByte, + * ControlvMaskByte * */ @@ -42,8 +44,8 @@ #include "rndis.h" /*--------------------- Static Definitions -------------------------*/ -//static int msglevel =MSG_LEVEL_INFO; -//static int msglevel =MSG_LEVEL_DEBUG; +/* static int msglevel =MSG_LEVEL_INFO; */ +/* static int msglevel =MSG_LEVEL_DEBUG; */ /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ @@ -54,56 +56,43 @@ /*--------------------- Export Functions --------------------------*/ - -void ControlvWriteByte(PSDevice pDevice, BYTE byRegType, BYTE byRegOfs, BYTE byData) +void ControlvWriteByte(PSDevice pDevice, BYTE byRegType, BYTE byRegOfs, + BYTE byData) { -BYTE byData1; - - byData1 = byData; - - CONTROLnsRequestOut(pDevice, - MESSAGE_TYPE_WRITE, - byRegOfs, - byRegType, - 1, - &byData1 - ); - + BYTE byData1; + byData1 = byData; + CONTROLnsRequestOut(pDevice, + MESSAGE_TYPE_WRITE, + byRegOfs, + byRegType, + 1, + &byData1); } - -void ControlvReadByte(PSDevice pDevice, BYTE byRegType, BYTE byRegOfs, PBYTE pbyData) +void ControlvReadByte(PSDevice pDevice, BYTE byRegType, BYTE byRegOfs, + PBYTE pbyData) { -NTSTATUS ntStatus; -BYTE byData1; - - - ntStatus = CONTROLnsRequestIn(pDevice, - MESSAGE_TYPE_READ, - byRegOfs, - byRegType, - 1, - &byData1); - - *pbyData = byData1; - + NTSTATUS ntStatus; + BYTE byData1; + ntStatus = CONTROLnsRequestIn(pDevice, + MESSAGE_TYPE_READ, + byRegOfs, + byRegType, + 1, + &byData1); + *pbyData = byData1; } - - -void ControlvMaskByte(PSDevice pDevice, BYTE byRegType, BYTE byRegOfs, BYTE byMask, BYTE byData) +void ControlvMaskByte(PSDevice pDevice, BYTE byRegType, BYTE byRegOfs, + BYTE byMask, BYTE byData) { -BYTE pbyData[2]; - - pbyData[0] = byData; - pbyData[1] = byMask; - - CONTROLnsRequestOut(pDevice, - MESSAGE_TYPE_WRITE_MASK, - byRegOfs, - byRegType, - 2, - pbyData - ); - + BYTE pbyData[2]; + pbyData[0] = byData; + pbyData[1] = byMask; + CONTROLnsRequestOut(pDevice, + MESSAGE_TYPE_WRITE_MASK, + byRegOfs, + byRegType, + 2, + pbyData); } -- cgit v1.2.3 From 183cd2956225ea6f83d2c46574df4607adeb3b91 Mon Sep 17 00:00:00 2001 From: Daniel Kenji Toyama Date: Mon, 29 Mar 2010 23:20:36 +1100 Subject: Staging: vt6656: michael.c: Fixed coding style issues Replaced lots of spaces by real tabs and resolved other minor issues. Signed-off-by: Daniel Kenji Toyama Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/michael.c | 177 +++++++++++++++++++-------------------- 1 file changed, 86 insertions(+), 91 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/michael.c b/drivers/staging/vt6656/michael.c index c930e0cdb853..d4c08209a17f 100644 --- a/drivers/staging/vt6656/michael.c +++ b/drivers/staging/vt6656/michael.c @@ -48,20 +48,23 @@ /*--------------------- Static Functions --------------------------*/ /* -static DWORD s_dwGetUINT32(BYTE * p); // Get DWORD from 4 bytes LSByte first -static VOID s_vPutUINT32(BYTE* p, DWORD val); // Put DWORD into 4 bytes LSByte first -*/ -static VOID s_vClear(void); // Clear the internal message, - // resets the object to the state just after construction. + * static DWORD s_dwGetUINT32(BYTE * p); Get DWORD from + * 4 bytes LSByte first + * static VOID s_vPutUINT32(BYTE* p, DWORD val); Put DWORD into + * 4 bytes LSByte first + */ +static VOID s_vClear(void); /* Clear the internal message, + * resets the object to the + * state just after construction. */ static VOID s_vSetKey(DWORD dwK0, DWORD dwK1); -static VOID s_vAppendByte(BYTE b); // Add a single byte to the internal message +static VOID s_vAppendByte(BYTE b); /* Add a single byte to the internal + * message */ /*--------------------- Export Variables --------------------------*/ -static DWORD L, R; // Current state - -static DWORD K0, K1; // Key -static DWORD M; // Message accumulator (single word) -static UINT nBytesInM; // # bytes in M +static DWORD L, R; /* Current state */ +static DWORD K0, K1; /* Key */ +static DWORD M; /* Message accumulator (single word) */ +static UINT nBytesInM; /* # bytes in M */ /*--------------------- Export Functions --------------------------*/ @@ -69,113 +72,105 @@ static UINT nBytesInM; // # bytes in M static DWORD s_dwGetUINT32 (BYTE * p) // Convert from BYTE[] to DWORD in a portable way { - DWORD res = 0; - UINT i; - for(i=0; i<4; i++ ) - { - res |= (*p++) << (8*i); - } - return res; + DWORD res = 0; + UINT i; + for(i=0; i<4; i++ ) + res |= (*p++) << (8*i); + return res; } static VOID s_vPutUINT32 (BYTE* p, DWORD val) // Convert from DWORD to BYTE[] in a portable way { - UINT i; - for(i=0; i<4; i++ ) - { - *p++ = (BYTE) (val & 0xff); - val >>= 8; - } + UINT i; + for(i=0; i<4; i++ ) { + *p++ = (BYTE) (val & 0xff); + val >>= 8; + } } */ -static VOID s_vClear (void) +static VOID s_vClear(void) { - // Reset the state to the empty message. - L = K0; - R = K1; - nBytesInM = 0; - M = 0; + /* Reset the state to the empty message. */ + L = K0; + R = K1; + nBytesInM = 0; + M = 0; } -static VOID s_vSetKey (DWORD dwK0, DWORD dwK1) +static VOID s_vSetKey(DWORD dwK0, DWORD dwK1) { - // Set the key - K0 = dwK0; - K1 = dwK1; - // and reset the message - s_vClear(); + /* Set the key */ + K0 = dwK0; + K1 = dwK1; + /* and reset the message */ + s_vClear(); } -static VOID s_vAppendByte (BYTE b) +static VOID s_vAppendByte(BYTE b) { - // Append the byte to our word-sized buffer - M |= b << (8*nBytesInM); - nBytesInM++; - // Process the word if it is full. - if( nBytesInM >= 4 ) - { - L ^= M; - R ^= ROL32( L, 17 ); - L += R; - R ^= ((L & 0xff00ff00) >> 8) | ((L & 0x00ff00ff) << 8); - L += R; - R ^= ROL32( L, 3 ); - L += R; - R ^= ROR32( L, 2 ); - L += R; - // Clear the buffer - M = 0; - nBytesInM = 0; - } + /* Append the byte to our word-sized buffer */ + M |= b << (8*nBytesInM); + nBytesInM++; + /* Process the word if it is full. */ + if (nBytesInM >= 4) { + L ^= M; + R ^= ROL32(L, 17); + L += R; + R ^= ((L & 0xff00ff00) >> 8) | ((L & 0x00ff00ff) << 8); + L += R; + R ^= ROL32(L, 3); + L += R; + R ^= ROR32(L, 2); + L += R; + /* Clear the buffer */ + M = 0; + nBytesInM = 0; + } } -VOID MIC_vInit (DWORD dwK0, DWORD dwK1) +VOID MIC_vInit(DWORD dwK0, DWORD dwK1) { - // Set the key - s_vSetKey(dwK0, dwK1); + /* Set the key */ + s_vSetKey(dwK0, dwK1); } -VOID MIC_vUnInit (void) +VOID MIC_vUnInit(void) { - // Wipe the key material - K0 = 0; - K1 = 0; + /* Wipe the key material */ + K0 = 0; + K1 = 0; - // And the other fields as well. - //Note that this sets (L,R) to (K0,K1) which is just fine. - s_vClear(); + /* And the other fields as well. */ + /* Note that this sets (L,R) to (K0,K1) which is just fine. */ + s_vClear(); } -VOID MIC_vAppend (PBYTE src, UINT nBytes) +VOID MIC_vAppend(PBYTE src, UINT nBytes) { - // This is simple - while (nBytes > 0) - { - s_vAppendByte(*src++); - nBytes--; - } + /* This is simple */ + while (nBytes > 0) { + s_vAppendByte(*src++); + nBytes--; + } } -VOID MIC_vGetMIC (PDWORD pdwL, PDWORD pdwR) +VOID MIC_vGetMIC(PDWORD pdwL, PDWORD pdwR) { - // Append the minimum padding - s_vAppendByte(0x5a); - s_vAppendByte(0); - s_vAppendByte(0); - s_vAppendByte(0); - s_vAppendByte(0); - // and then zeroes until the length is a multiple of 4 - while( nBytesInM != 0 ) - { - s_vAppendByte(0); - } - // The s_vAppendByte function has already computed the result. - *pdwL = L; - *pdwR = R; - // Reset to the empty message. - s_vClear(); + /* Append the minimum padding */ + s_vAppendByte(0x5a); + s_vAppendByte(0); + s_vAppendByte(0); + s_vAppendByte(0); + s_vAppendByte(0); + /* and then zeroes until the length is a multiple of 4 */ + while (nBytesInM != 0) + s_vAppendByte(0); + /* The s_vAppendByte function has already computed the result. */ + *pdwL = L; + *pdwR = R; + /* Reset to the empty message. */ + s_vClear(); } - -- cgit v1.2.3 From b77694be7547d371c2f2e1be077bffcdbfcf7b82 Mon Sep 17 00:00:00 2001 From: Daniel Kenji Toyama Date: Mon, 29 Mar 2010 23:28:33 +1100 Subject: Staging: vt6656: tether.c: Fixed coding style issues Fixed some indentation and spacing issues. Signed-off-by: Daniel Kenji Toyama Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/tether.c | 45 ++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/tether.c b/drivers/staging/vt6656/tether.c index c90b469ad545..ab1368a08389 100644 --- a/drivers/staging/vt6656/tether.c +++ b/drivers/staging/vt6656/tether.c @@ -61,25 +61,25 @@ * Return Value: Hash value * */ -BYTE ETHbyGetHashIndexByCrc32 (PBYTE pbyMultiAddr) +BYTE ETHbyGetHashIndexByCrc32(PBYTE pbyMultiAddr) { - int ii; - BYTE byTmpHash; - BYTE byHash = 0; + int ii; + BYTE byTmpHash; + BYTE byHash = 0; - // get the least 6-bits from CRC generator - byTmpHash = (BYTE)(CRCdwCrc32(pbyMultiAddr, U_ETHER_ADDR_LEN, - 0xFFFFFFFFL) & 0x3F); - // reverse most bit to least bit - for (ii = 0; ii < (sizeof(byTmpHash) * 8); ii++) { - byHash <<= 1; - if (byTmpHash & 0x01) - byHash |= 1; - byTmpHash >>= 1; - } + /* get the least 6-bits from CRC generator */ + byTmpHash = (BYTE)(CRCdwCrc32(pbyMultiAddr, U_ETHER_ADDR_LEN, + 0xFFFFFFFFL) & 0x3F); + /* reverse most bit to least bit */ + for (ii = 0; ii < (sizeof(byTmpHash) * 8); ii++) { + byHash <<= 1; + if (byTmpHash & 0x01) + byHash |= 1; + byTmpHash >>= 1; + } - // adjust 6-bits to the right most - return (byHash >> 2); + /* adjust 6-bits to the right most */ + return byHash >> 2; } @@ -96,14 +96,13 @@ BYTE ETHbyGetHashIndexByCrc32 (PBYTE pbyMultiAddr) * Return Value: TRUE if ok; FALSE if error. * */ -BOOL ETHbIsBufferCrc32Ok (PBYTE pbyBuffer, UINT cbFrameLength) +BOOL ETHbIsBufferCrc32Ok(PBYTE pbyBuffer, UINT cbFrameLength) { - DWORD dwCRC; + DWORD dwCRC; - dwCRC = CRCdwGetCrc32(pbyBuffer, cbFrameLength - 4); - if (cpu_to_le32(*((PDWORD)(pbyBuffer + cbFrameLength - 4))) != dwCRC) { - return FALSE; - } - return TRUE; + dwCRC = CRCdwGetCrc32(pbyBuffer, cbFrameLength - 4); + if (cpu_to_le32(*((PDWORD)(pbyBuffer + cbFrameLength - 4))) != dwCRC) + return FALSE; + return TRUE; } -- cgit v1.2.3 From 6dde1c6c8e2bcc8e97210d0b6388340a7cbd2afe Mon Sep 17 00:00:00 2001 From: Daniel Kenji Toyama Date: Mon, 29 Mar 2010 23:19:20 +1100 Subject: Staging: vt6656: tcrc.c: Fixed coding style issues Fixed minor problems with indentation. Signed-off-by: Daniel Kenji Toyama Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/tcrc.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/tcrc.c b/drivers/staging/vt6656/tcrc.c index 5f0c74763f87..3464801ede57 100644 --- a/drivers/staging/vt6656/tcrc.c +++ b/drivers/staging/vt6656/tcrc.c @@ -41,7 +41,7 @@ /*--------------------- Static Variables --------------------------*/ -// 32-bit CRC table +/* 32-bit CRC table */ static const DWORD s_adwCrc32Table[256] = { 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, @@ -132,17 +132,18 @@ static const DWORD s_adwCrc32Table[256] = { * Return Value: CRC-32 * -*/ -DWORD CRCdwCrc32 (PBYTE pbyData, UINT cbByte, DWORD dwCrcSeed) +DWORD CRCdwCrc32(PBYTE pbyData, UINT cbByte, DWORD dwCrcSeed) { - DWORD dwCrc; + DWORD dwCrc; - dwCrc = dwCrcSeed; - while (cbByte--) { - dwCrc = s_adwCrc32Table[(BYTE)((dwCrc ^ (*pbyData)) & 0xFF)] ^ (dwCrc >> 8); - pbyData++; - } + dwCrc = dwCrcSeed; + while (cbByte--) { + dwCrc = s_adwCrc32Table[(BYTE)((dwCrc ^ (*pbyData)) & 0xFF)] ^ + (dwCrc >> 8); + pbyData++; + } - return dwCrc; + return dwCrc; } @@ -164,7 +165,7 @@ DWORD CRCdwCrc32 (PBYTE pbyData, UINT cbByte, DWORD dwCrcSeed) * Return Value: CRC-32 * -*/ -DWORD CRCdwGetCrc32 (PBYTE pbyData, UINT cbByte) +DWORD CRCdwGetCrc32(PBYTE pbyData, UINT cbByte) { return ~CRCdwCrc32(pbyData, cbByte, 0xFFFFFFFFL); } -- cgit v1.2.3 From ff8041bb7ca15bc5c6048e8598a896819cbec417 Mon Sep 17 00:00:00 2001 From: Daniel Kenji Toyama Date: Tue, 30 Mar 2010 00:28:19 +1100 Subject: Staging: vt6656: int.c: Fixed Coding Style issues Fixed almost all the issues given by checkpatch.pl except for one warning about an 81 character line, which cannot really be decomposed (the code is a bit too nested there). Signed-off-by: Daniel Kenji Toyama Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/int.c | 250 ++++++++++++++++++++++++------------------- 1 file changed, 141 insertions(+), 109 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/int.c b/drivers/staging/vt6656/int.c index 35053be6900d..824c67de0ea9 100644 --- a/drivers/staging/vt6656/int.c +++ b/drivers/staging/vt6656/int.c @@ -41,8 +41,8 @@ #include "usbpipe.h" /*--------------------- Static Definitions -------------------------*/ -//static int msglevel =MSG_LEVEL_DEBUG; -static int msglevel =MSG_LEVEL_INFO; +/* static int msglevel = MSG_LEVEL_DEBUG; */ +static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Classes ----------------------------*/ @@ -74,120 +74,152 @@ static int msglevel =MSG_LEVEL_INFO; * * Notes: * - * USB reads are by nature 'Blocking', and when in a read, the device looks like it's - * in a 'stall' condition, so we deliberately time out every second if we've gotten no data + * USB reads are by nature 'Blocking', and when in a read, the device looks + * like it's in a 'stall' condition, so we deliberately time out every second + * if we've gotten no data * -*/ VOID -INTvWorkItem( - PVOID Context - ) +INTvWorkItem(PVOID Context) { - PSDevice pDevice = (PSDevice) Context; - NTSTATUS ntStatus; + PSDevice pDevice = (PSDevice) Context; + NTSTATUS ntStatus; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Interrupt Polling Thread\n"); - - spin_lock_irq(&pDevice->lock); - if (pDevice->fKillEventPollingThread != TRUE) { - ntStatus = PIPEnsInterruptRead(pDevice); - } - spin_unlock_irq(&pDevice->lock); - - } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Interrupt Polling Thread\n"); + spin_lock_irq(&pDevice->lock); + if (pDevice->fKillEventPollingThread != TRUE) + ntStatus = PIPEnsInterruptRead(pDevice); + spin_unlock_irq(&pDevice->lock); +} NTSTATUS -INTnsProcessData( - IN PSDevice pDevice - ) +INTnsProcessData(IN PSDevice pDevice) { - NTSTATUS status = STATUS_SUCCESS; - PSINTData pINTData; - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - struct net_device_stats* pStats = &pDevice->stats; - - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsInterruptProcessData\n"); - - pINTData = (PSINTData) pDevice->intBuf.pDataBuf; - if (pINTData->byTSR0 & TSR_VALID) { - STAvUpdateTDStatCounter (&(pDevice->scStatistic), (BYTE) (pINTData->byPkt0 & 0x0F), (BYTE) (pINTData->byPkt0>>4), pINTData->byTSR0); - BSSvUpdateNodeTxCounter (pDevice, &(pDevice->scStatistic), pINTData->byTSR0, pINTData->byPkt0); - //DBG_PRN_GRP01(("TSR0 %02x\n", pINTData->byTSR0)); - } - if (pINTData->byTSR1 & TSR_VALID) { - STAvUpdateTDStatCounter (&(pDevice->scStatistic), (BYTE) (pINTData->byPkt1 & 0x0F), (BYTE) (pINTData->byPkt1>>4), pINTData->byTSR1); - BSSvUpdateNodeTxCounter (pDevice, &(pDevice->scStatistic), pINTData->byTSR1, pINTData->byPkt1); - //DBG_PRN_GRP01(("TSR1 %02x\n", pINTData->byTSR1)); - } - if (pINTData->byTSR2 & TSR_VALID) { - STAvUpdateTDStatCounter (&(pDevice->scStatistic), (BYTE) (pINTData->byPkt2 & 0x0F), (BYTE) (pINTData->byPkt2>>4), pINTData->byTSR2); - BSSvUpdateNodeTxCounter (pDevice, &(pDevice->scStatistic), pINTData->byTSR2, pINTData->byPkt2); - //DBG_PRN_GRP01(("TSR2 %02x\n", pINTData->byTSR2)); - } - if (pINTData->byTSR3 & TSR_VALID) { - STAvUpdateTDStatCounter (&(pDevice->scStatistic), (BYTE) (pINTData->byPkt3 & 0x0F), (BYTE) (pINTData->byPkt3>>4), pINTData->byTSR3); - BSSvUpdateNodeTxCounter (pDevice, &(pDevice->scStatistic), pINTData->byTSR3, pINTData->byPkt3); - //DBG_PRN_GRP01(("TSR3 %02x\n", pINTData->byTSR3)); - } - if ( pINTData->byISR0 != 0 ) { - if (pINTData->byISR0 & ISR_BNTX) { - - if (pDevice->eOPMode == OP_MODE_AP) { - if(pMgmt->byDTIMCount > 0) { - pMgmt->byDTIMCount --; - pMgmt->sNodeDBTable[0].bRxPSPoll = FALSE; - } else if(pMgmt->byDTIMCount == 0) { - // check if mutltcast tx bufferring - pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1; - pMgmt->sNodeDBTable[0].bRxPSPoll = TRUE; - if (pMgmt->sNodeDBTable[0].bPSEnable) { - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL); - } - } - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_BECON_SEND, NULL); - } // if (pDevice->eOPMode == OP_MODE_AP) - - pDevice->bBeaconSent = TRUE; - } else { - pDevice->bBeaconSent = FALSE; - } - if (pINTData->byISR0 & ISR_TBTT) { - if ( pDevice->bEnablePSMode ) { - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_TBTT_WAKEUP, NULL); - } - if ( pDevice->bChannelSwitch ) { - pDevice->byChannelSwitchCount--; - if ( pDevice->byChannelSwitchCount == 0 ) { - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_11H_CHSW, NULL); - } - } - } - LODWORD(pDevice->qwCurrTSF) = pINTData->dwLoTSF; - HIDWORD(pDevice->qwCurrTSF) = pINTData->dwHiTSF; - //DBG_PRN_GRP01(("ISR0 = %02x ,LoTsf = %08x,HiTsf = %08x\n", pINTData->byISR0, pINTData->dwLoTSF,pINTData->dwHiTSF)); - - STAvUpdate802_11Counter(&pDevice->s802_11Counter, &pDevice->scStatistic, pINTData->byRTSSuccess, - pINTData->byRTSFail, pINTData->byACKFail, pINTData->byFCSErr ); - STAvUpdateIsrStatCounter(&pDevice->scStatistic, pINTData->byISR0, pINTData->byISR1); - - } - - if ( pINTData->byISR1 != 0 ) { - if (pINTData->byISR1 & ISR_GPIO3) { - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_RADIO, NULL); - } - } - pDevice->intBuf.uDataLen = 0; - pDevice->intBuf.bInUse = FALSE; - - pStats->tx_packets = pDevice->scStatistic.ullTsrOK; - pStats->tx_bytes = pDevice->scStatistic.ullTxDirectedBytes + - pDevice->scStatistic.ullTxMulticastBytes + - pDevice->scStatistic.ullTxBroadcastBytes; - pStats->tx_errors = pDevice->scStatistic.dwTsrErr; - pStats->tx_dropped = pDevice->scStatistic.dwTsrErr; - - return status; + NTSTATUS status = STATUS_SUCCESS; + PSINTData pINTData; + PSMgmtObject pMgmt = &(pDevice->sMgmtObj); + struct net_device_stats *pStats = &pDevice->stats; + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsInterruptProcessData\n"); + + pINTData = (PSINTData) pDevice->intBuf.pDataBuf; + if (pINTData->byTSR0 & TSR_VALID) { + STAvUpdateTDStatCounter(&(pDevice->scStatistic), + (BYTE) (pINTData->byPkt0 & 0x0F), + (BYTE) (pINTData->byPkt0>>4), + pINTData->byTSR0); + BSSvUpdateNodeTxCounter(pDevice, + &(pDevice->scStatistic), + pINTData->byTSR0, + pINTData->byPkt0); + /*DBG_PRN_GRP01(("TSR0 %02x\n", pINTData->byTSR0));*/ + } + if (pINTData->byTSR1 & TSR_VALID) { + STAvUpdateTDStatCounter(&(pDevice->scStatistic), + (BYTE) (pINTData->byPkt1 & 0x0F), + (BYTE) (pINTData->byPkt1>>4), + pINTData->byTSR1); + BSSvUpdateNodeTxCounter(pDevice, + &(pDevice->scStatistic), + pINTData->byTSR1, + pINTData->byPkt1); + /*DBG_PRN_GRP01(("TSR1 %02x\n", pINTData->byTSR1));*/ + } + if (pINTData->byTSR2 & TSR_VALID) { + STAvUpdateTDStatCounter(&(pDevice->scStatistic), + (BYTE) (pINTData->byPkt2 & 0x0F), + (BYTE) (pINTData->byPkt2>>4), + pINTData->byTSR2); + BSSvUpdateNodeTxCounter(pDevice, + &(pDevice->scStatistic), + pINTData->byTSR2, + pINTData->byPkt2); + /*DBG_PRN_GRP01(("TSR2 %02x\n", pINTData->byTSR2));*/ + } + if (pINTData->byTSR3 & TSR_VALID) { + STAvUpdateTDStatCounter(&(pDevice->scStatistic), + (BYTE) (pINTData->byPkt3 & 0x0F), + (BYTE) (pINTData->byPkt3>>4), + pINTData->byTSR3); + BSSvUpdateNodeTxCounter(pDevice, + &(pDevice->scStatistic), + pINTData->byTSR3, + pINTData->byPkt3); + /*DBG_PRN_GRP01(("TSR3 %02x\n", pINTData->byTSR3));*/ + } + if (pINTData->byISR0 != 0) { + if (pINTData->byISR0 & ISR_BNTX) { + if (pDevice->eOPMode == OP_MODE_AP) { + if (pMgmt->byDTIMCount > 0) { + pMgmt->byDTIMCount--; + pMgmt->sNodeDBTable[0].bRxPSPoll = + FALSE; + } else if (pMgmt->byDTIMCount == 0) { + /* check if mutltcast tx bufferring */ + pMgmt->byDTIMCount = + pMgmt->byDTIMPeriod-1; + pMgmt->sNodeDBTable[0].bRxPSPoll = TRUE; + if (pMgmt->sNodeDBTable[0].bPSEnable) + bScheduleCommand((HANDLE)pDevice, + WLAN_CMD_RX_PSPOLL, + NULL); + } + bScheduleCommand((HANDLE)pDevice, + WLAN_CMD_BECON_SEND, + NULL); + } /* if (pDevice->eOPMode == OP_MODE_AP) */ + pDevice->bBeaconSent = TRUE; + } else { + pDevice->bBeaconSent = FALSE; + } + if (pINTData->byISR0 & ISR_TBTT) { + if (pDevice->bEnablePSMode) + bScheduleCommand((HANDLE) pDevice, + WLAN_CMD_TBTT_WAKEUP, + NULL); + if (pDevice->bChannelSwitch) { + pDevice->byChannelSwitchCount--; + if (pDevice->byChannelSwitchCount == 0) + bScheduleCommand((HANDLE) pDevice, + WLAN_CMD_11H_CHSW, + NULL); + } + } + LODWORD(pDevice->qwCurrTSF) = pINTData->dwLoTSF; + HIDWORD(pDevice->qwCurrTSF) = pINTData->dwHiTSF; + /*DBG_PRN_GRP01(("ISR0 = %02x , + LoTsf = %08x, + HiTsf = %08x\n", + pINTData->byISR0, + pINTData->dwLoTSF, + pINTData->dwHiTSF)); */ + + STAvUpdate802_11Counter(&pDevice->s802_11Counter, + &pDevice->scStatistic, + pINTData->byRTSSuccess, + pINTData->byRTSFail, + pINTData->byACKFail, + pINTData->byFCSErr); + STAvUpdateIsrStatCounter(&pDevice->scStatistic, + pINTData->byISR0, + pINTData->byISR1); + } + + if (pINTData->byISR1 != 0) + if (pINTData->byISR1 & ISR_GPIO3) + bScheduleCommand((HANDLE) pDevice, + WLAN_CMD_RADIO, + NULL); + pDevice->intBuf.uDataLen = 0; + pDevice->intBuf.bInUse = FALSE; + + pStats->tx_packets = pDevice->scStatistic.ullTsrOK; + pStats->tx_bytes = pDevice->scStatistic.ullTxDirectedBytes + + pDevice->scStatistic.ullTxMulticastBytes + + pDevice->scStatistic.ullTxBroadcastBytes; + pStats->tx_errors = pDevice->scStatistic.dwTsrErr; + pStats->tx_dropped = pDevice->scStatistic.dwTsrErr; + + return status; } -- cgit v1.2.3 From d82f139b5865f26b005852cd38119681fe70b0dc Mon Sep 17 00:00:00 2001 From: Javier Muñoz Mellid Date: Mon, 29 Mar 2010 19:35:24 +0200 Subject: Staging: sm7xx: Fixed coding style issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed a format issue Signed-off-by: Javier Muñoz Mellid Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm7xx/smtcfb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/sm7xx/smtcfb.h b/drivers/staging/sm7xx/smtcfb.h index 7ee565c2c952..0c113835b85c 100644 --- a/drivers/staging/sm7xx/smtcfb.h +++ b/drivers/staging/sm7xx/smtcfb.h @@ -3,7 +3,7 @@ * * Copyright (C) 2006 Silicon Motion Technology Corp. * Authors: Ge Wang, gewang@siliconmotion.com - * Boyod boyod.yang@siliconmotion.com.cn + * Boyod boyod.yang@siliconmotion.com.cn * * Copyright (C) 2009 Lemote, Inc. * Author: Wu Zhangjin, wuzhangjin@gmail.com -- cgit v1.2.3 From 933025b60836a80f415bb458f3880519fc24606e Mon Sep 17 00:00:00 2001 From: Ossama Othman Date: Fri, 26 Mar 2010 15:11:11 -0700 Subject: Staging: add initial memrar ABI document Signed-off-by: Ossama Othman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/memrar/memrar-abi | 89 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 drivers/staging/memrar/memrar-abi (limited to 'drivers') diff --git a/drivers/staging/memrar/memrar-abi b/drivers/staging/memrar/memrar-abi new file mode 100644 index 000000000000..98a6bb158baf --- /dev/null +++ b/drivers/staging/memrar/memrar-abi @@ -0,0 +1,89 @@ +What: /dev/memrar +Date: March 2010 +KernelVersion: Kernel version this feature first showed up in. +Contact: Ossama Othman +Description: The Intel Moorestown Restricted Access Region (RAR) + Handler driver exposes an ioctl() based interface that + allows a user to reserve and release blocks of RAR + memory. + + Note: A sysfs based one was not appropriate for the + RAR handler's usage model. + + ========================================================= + ioctl() Requests + ========================================================= + RAR_HANDLER_RESERVE + ------------------- + Description: Reserve RAR block. + Type: struct RAR_block_info + Direction: in/out + Errors: EINVAL (invalid RAR type or size) + ENOMEM (not enough RAR memory) + + RAR_HANDLER_STAT + ---------------- + Description: Get RAR statistics. + Type: struct RAR_stat + Direction: in/out + Errors: EINVAL (invalid RAR type) + + RAR_HANDLER_RELEASE + ------------------- + Description: Release previously reserved RAR block. + Type: 32 bit unsigned integer + (e.g. uint32_t), i.e the RAR "handle". + Direction: in + Errors: EINVAL (invalid RAR handle) + + + ========================================================= + ioctl() Request Parameter Types + ========================================================= + The structures referred to above are defined as + follows: + + /** + * struct RAR_block_info - user space struct that + * describes RAR buffer + * @type: Type of RAR memory (e.g., + * RAR_TYPE_VIDEO or RAR_TYPE_AUDIO) [in] + * @size: Requested size of a block in bytes to + * be reserved in RAR. [in] + * @handle: Handle that can be used to refer to + * reserved block. [out] + * + * This is the basic structure exposed to the user + * space that describes a given RAR buffer. It used + * as the parameter for the RAR_HANDLER_RESERVE ioctl. + * The buffer's underlying bus address is not exposed + * to the user. User space code refers to the buffer + * entirely by "handle". + */ + struct RAR_block_info { + __u32 type; + __u32 size; + __u32 handle; + }; + + /** + * struct RAR_stat - RAR statistics structure + * @type: Type of RAR memory (e.g., + * RAR_TYPE_VIDEO or + * RAR_TYPE_AUDIO) [in] + * @capacity: Total size of RAR memory + * region. [out] + * @largest_block_size: Size of the largest reservable + * block. [out] + * + * This structure is used for RAR_HANDLER_STAT ioctl. + */ + struct RAR_stat { + __u32 type; + __u32 capacity; + __u32 largest_block_size; + }; + + Lastly, the RAR_HANDLER_RELEASE ioctl expects a + "handle" to the RAR block of memory. It is a 32 bit + unsigned integer. -- cgit v1.2.3 From 08db6c59a2d4d8162d7544ffaa9aa7d27ce9e50a Mon Sep 17 00:00:00 2001 From: Soeren Moeller Date: Tue, 30 Mar 2010 20:11:12 +0000 Subject: Staging: quatech_usb2: fix coding style issues This is a patch to the file quatech_usb2.c that fixes two space before tabular and one line of more than 80 characters warnings found by checkpatch.pl Signed-off-by: Soeren Moeller Signed-off-by: Greg Kroah-Hartman --- drivers/staging/quatech_usb2/quatech_usb2.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/quatech_usb2/quatech_usb2.c b/drivers/staging/quatech_usb2/quatech_usb2.c index 1561f74a413b..ecd73135b319 100644 --- a/drivers/staging/quatech_usb2/quatech_usb2.c +++ b/drivers/staging/quatech_usb2/quatech_usb2.c @@ -57,7 +57,7 @@ static int debug; #define QT2_HW_FLOW_CONTROL_MASK 0xc5 #define QT2_SW_FLOW_CONTROL_MASK 0xc6 #define QT2_SW_FLOW_CONTROL_DISABLE 0xc7 -#define QT2_BREAK_CONTROL 0xc8 +#define QT2_BREAK_CONTROL 0xc8 #define QT2_STOP_RECEIVE 0xe0 #define QT2_FLUSH_DEVICE 0xc4 #define QT2_GET_SET_QMCR 0xe1 @@ -207,7 +207,7 @@ struct quatech2_dev { bool ReadBulkStopped; char open_ports; struct usb_serial_port *current_port; - int buffer_size; + int buffer_size; }; /* structure which holds line and modem status flags */ @@ -1648,10 +1648,10 @@ __func__); } /*endif*/ if (tty_st && urb->actual_length) { tty_buffer_request_room(tty_st, 1); - tty_insert_flip_string(tty_st, - &((unsigned char *)(urb->transfer_buffer) - )[i], - 1); + tty_insert_flip_string(tty_st, &( + (unsigned char *) + (urb->transfer_buffer) + )[i], 1); } } /*endfor*/ tty_flip_buffer_push(tty_st); -- cgit v1.2.3 From 593ef41c95c82a7c8d09c28db4893f4dd2ff0134 Mon Sep 17 00:00:00 2001 From: Olimpiu Pascariu Date: Thu, 1 Apr 2010 23:48:14 +0300 Subject: Staging: rtl8187se: fixed checkpatch.pl warnings and errors in r8180_rtl8225z2.c This is a patch to the r8180_rtl8225z2.c file that fixes up errors and warnings found by the checkpatch.pl tool Signed-off-by: Olimpiu Pascariu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_rtl8225z2.c | 129 +++++++++++++++++----------- 1 file changed, 78 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8187se/r8180_rtl8225z2.c b/drivers/staging/rtl8187se/r8180_rtl8225z2.c index 6edf5a46fa40..2a2afd51cf42 100644 --- a/drivers/staging/rtl8187se/r8180_rtl8225z2.c +++ b/drivers/staging/rtl8187se/r8180_rtl8225z2.c @@ -1,14 +1,13 @@ /* - This is part of the rtl8180-sa2400 driver - released under the GPL (See file COPYING for details). - Copyright (c) 2005 Andrea Merello - - This files contains programming code for the rtl8225 - radio frontend. - - *Many* thanks to Realtek Corp. for their great support! - -*/ + * This is part of the rtl8180-sa2400 driver + * released under the GPL (See file COPYING for details). + * Copyright (c) 2005 Andrea Merello + * + * This files contains programming code for the rtl8225 + * radio frontend. + * + * *Many* thanks to Realtek Corp. for their great support! + */ #include "r8180_hw.h" #include "r8180_rtl8225.h" @@ -225,7 +224,7 @@ static void rtl8225_SetTXPowerLevel(struct net_device *dev, short ch) } static const u8 rtl8225z2_threshold[] = { - 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd, + 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd, }; static const u8 rtl8225z2_gain_bg[] = { @@ -307,7 +306,7 @@ static u32 read_rtl8225(struct net_device *dev, u8 adr) u32 data2Write = ((u32)(adr & 0x1f)) << 27; u32 dataRead; u32 mask; - u16 oval,oval2,oval3,tmp; + u16 oval, oval2, oval3, tmp; int i; short bit, rw; u8 wLength = 6; @@ -325,9 +324,11 @@ static u32 read_rtl8225(struct net_device *dev, u8 adr) oval &= ~0xf; - write_nic_word(dev, RFPinsOutput, oval | BB_HOST_BANG_EN ); udelay(4); + write_nic_word(dev, RFPinsOutput, oval | BB_HOST_BANG_EN); + udelay(4); - write_nic_word(dev, RFPinsOutput, oval ); udelay(5); + write_nic_word(dev, RFPinsOutput, oval); + udelay(5); rw = 0; @@ -335,31 +336,45 @@ static u32 read_rtl8225(struct net_device *dev, u8 adr) for (i = 0; i < wLength/2; i++) { bit = ((data2Write&mask) != 0) ? 1 : 0; - write_nic_word(dev, RFPinsOutput, bit|oval | rw); udelay(1); + write_nic_word(dev, RFPinsOutput, bit | oval | rw); + udelay(1); - write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2); - write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2); + write_nic_word(dev, RFPinsOutput, + bit | oval | BB_HOST_BANG_CLK | rw); + udelay(2); + write_nic_word(dev, RFPinsOutput, + bit | oval | BB_HOST_BANG_CLK | rw); + udelay(2); - mask = (low2high) ? (mask<<1): (mask>>1); + mask = (low2high) ? (mask<<1) : (mask>>1); if (i == 2) { rw = BB_HOST_BANG_RW; - write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2); - write_nic_word(dev, RFPinsOutput, bit|oval | rw); udelay(2); + write_nic_word(dev, RFPinsOutput, + bit | oval | BB_HOST_BANG_CLK | rw); + udelay(2); + write_nic_word(dev, RFPinsOutput, bit | oval | rw); + udelay(2); break; } - bit = ((data2Write&mask) != 0) ? 1: 0; + bit = ((data2Write&mask) != 0) ? 1 : 0; - write_nic_word(dev, RFPinsOutput, oval|bit|rw| BB_HOST_BANG_CLK); udelay(2); - write_nic_word(dev, RFPinsOutput, oval|bit|rw| BB_HOST_BANG_CLK); udelay(2); + write_nic_word(dev, RFPinsOutput, + oval | bit | rw | BB_HOST_BANG_CLK); + udelay(2); + write_nic_word(dev, RFPinsOutput, + oval | bit | rw | BB_HOST_BANG_CLK); + udelay(2); - write_nic_word(dev, RFPinsOutput, oval| bit |rw); udelay(1); + write_nic_word(dev, RFPinsOutput, oval | bit | rw); + udelay(1); mask = (low2high) ? (mask<<1) : (mask>>1); } - write_nic_word(dev, RFPinsOutput, rw|oval); udelay(2); + write_nic_word(dev, RFPinsOutput, rw|oval); + udelay(2); mask = (low2high) ? 0x01 : (((u32)0x01) << (12-1)); /* @@ -371,9 +386,12 @@ static u32 read_rtl8225(struct net_device *dev, u8 adr) for (i = 0; i < rLength; i++) { write_nic_word(dev, RFPinsOutput, rw|oval); udelay(1); - write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2); - write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2); - write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2); + write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); + udelay(2); + write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); + udelay(2); + write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); + udelay(2); tmp = read_nic_word(dev, RFPinsInput); dataRead |= (tmp & BB_HOST_BANG_CLK ? mask : 0); @@ -383,7 +401,9 @@ static u32 read_rtl8225(struct net_device *dev, u8 adr) mask = (low2high) ? (mask<<1) : (mask>>1); } - write_nic_word(dev, RFPinsOutput, BB_HOST_BANG_EN|BB_HOST_BANG_RW|oval); udelay(2); + write_nic_word(dev, RFPinsOutput, + BB_HOST_BANG_EN | BB_HOST_BANG_RW | oval); + udelay(2); write_nic_word(dev, RFPinsEnable, oval2); write_nic_word(dev, RFPinsSelect, oval3); /* Set To SW Switch */ @@ -426,7 +446,7 @@ void rtl8225z2_rf_close(struct net_device *dev) s8 DbmToTxPwrIdx(struct r8180_priv *priv, WIRELESS_MODE WirelessMode, s32 PowerInDbm) { - bool bUseDefault = true; + bool bUseDefault = true; s8 TxPwrIdx = 0; /* @@ -486,8 +506,10 @@ void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch) if (IS_DOT11D_ENABLE(priv->ieee80211) && IS_DOT11D_STATE_DONE(priv->ieee80211)) { u8 MaxTxPwrInDbm = DOT11D_GetMaxTxPwrInDbm(priv->ieee80211, ch); - u8 CckMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_B, MaxTxPwrInDbm); - u8 OfdmMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_G, MaxTxPwrInDbm); + u8 CckMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_B, + MaxTxPwrInDbm); + u8 OfdmMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_G, + MaxTxPwrInDbm); if (cck_power_level > CckMaxPwrIdx) cck_power_level = CckMaxPwrIdx; @@ -524,7 +546,7 @@ void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch) if (ofdm_power_level <= 11) { write_phy_ofdm(dev, 0x07, 0x5c); write_phy_ofdm(dev, 0x09, 0x5c); - } + } if (ofdm_power_level <= 17) { write_phy_ofdm(dev, 0x07, 0x54); @@ -613,7 +635,7 @@ void rtl8225z2_rf_init(struct net_device *dev) int i; short channel = 1; u16 brsr; - u32 data,addr; + u32 data, addr; priv->chan = channel; @@ -740,7 +762,7 @@ void rtl8225z2_rf_init(struct net_device *dev) write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); write_phy_ofdm(dev, 0x27, 0x88); mdelay(1); - rtl8225z2_set_gain(dev,4); + rtl8225z2_set_gain(dev, 4); write_phy_cck(dev, 0x0, 0x98); mdelay(1); write_phy_cck(dev, 0x3, 0x20); mdelay(1); @@ -803,12 +825,12 @@ void rtl8225z2_rf_set_mode(struct net_device *dev) write_phy_ofdm(dev, 0xf, 0x20); write_phy_ofdm(dev, 0x11, 0x7); - rtl8225z2_set_gain(dev,4); + rtl8225z2_set_gain(dev, 4); - write_phy_ofdm(dev,0x15, 0x40); - write_phy_ofdm(dev,0x17, 0x40); + write_phy_ofdm(dev, 0x15, 0x40); + write_phy_ofdm(dev, 0x17, 0x40); - write_nic_dword(dev, 0x94,0x10000000); + write_nic_dword(dev, 0x94, 0x10000000); } else { write_rtl8225(dev, 0x5, 0x1864); write_nic_dword(dev, RF_PARA, 0x10044); @@ -819,18 +841,18 @@ void rtl8225z2_rf_set_mode(struct net_device *dev) write_phy_ofdm(dev, 0xf, 0x20); write_phy_ofdm(dev, 0x11, 0x7); - rtl8225z2_set_gain(dev,4); + rtl8225z2_set_gain(dev, 4); - write_phy_ofdm(dev,0x15, 0x40); - write_phy_ofdm(dev,0x17, 0x40); + write_phy_ofdm(dev, 0x15, 0x40); + write_phy_ofdm(dev, 0x17, 0x40); - write_nic_dword(dev, 0x94,0x04000002); + write_nic_dword(dev, 0x94, 0x04000002); } } -#define MAX_DOZE_WAITING_TIMES_85B 20 -#define MAX_POLLING_24F_TIMES_87SE 10 -#define LPS_MAX_SLEEP_WAITING_TIMES_87SE 5 +#define MAX_DOZE_WAITING_TIMES_85B 20 +#define MAX_POLLING_24F_TIMES_87SE 10 +#define LPS_MAX_SLEEP_WAITING_TIMES_87SE 5 bool SetZebraRFPowerState8185(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) @@ -882,12 +904,14 @@ bool SetZebraRFPowerState8185(struct net_device *dev, break; case eRfSleep: for (QueueID = 0, i = 0; QueueID < 6;) { - if (get_curr_tx_free_desc(dev, QueueID) == priv->txringcount) { + if (get_curr_tx_free_desc(dev, QueueID) == + priv->txringcount) { QueueID++; continue; } else { priv->TxPollingTimes++; - if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) { + if (priv->TxPollingTimes >= + LPS_MAX_SLEEP_WAITING_TIMES_87SE) { bActionAllowed = false; break; } else @@ -915,7 +939,8 @@ bool SetZebraRFPowerState8185(struct net_device *dev, while (true) { u8 tmp24F = read_nic_byte(dev, 0x24f); - if ((tmp24F == 0x01) || (tmp24F == 0x09)) { + if ((tmp24F == 0x01) || + (tmp24F == 0x09)) { bTurnOffBB = true; break; } else { @@ -935,7 +960,8 @@ bool SetZebraRFPowerState8185(struct net_device *dev, if (bTurnOffBB) { /* turn off BB */ u1bTmp = read_nic_byte(dev, 0x24E); - write_nic_byte(dev, 0x24E, (u1bTmp | BIT5 | BIT6)); + write_nic_byte(dev, 0x24E, + (u1bTmp | BIT5 | BIT6)); /* turn off AFE PLL */ write_nic_byte(dev, 0x54, 0xFC); @@ -945,7 +971,8 @@ bool SetZebraRFPowerState8185(struct net_device *dev, break; case eRfOff: for (QueueID = 0, i = 0; QueueID < 6;) { - if (get_curr_tx_free_desc(dev, QueueID) == priv->txringcount) { + if (get_curr_tx_free_desc(dev, QueueID) == + priv->txringcount) { QueueID++; continue; } else { -- cgit v1.2.3 From 3b7b31fa7df01576cc401dff512a6a84cb3753ed Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sat, 3 Apr 2010 07:00:37 +0200 Subject: Staging: udlfb: minor cleanups This cleans up udlfb a tiny bit. Signed-off-by: Pavel Machek Cc: Bernie Thompson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/udlfb/udlfb.c | 58 +++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/udlfb/udlfb.c b/drivers/staging/udlfb/udlfb.c index a78ade0dc687..12444f2014e4 100644 --- a/drivers/staging/udlfb/udlfb.c +++ b/drivers/staging/udlfb/udlfb.c @@ -58,17 +58,17 @@ static struct usb_device_id id_table[] = { MODULE_DEVICE_TABLE(usb, id_table); #ifndef CONFIG_FB_DEFERRED_IO -#warning message "kernel FB_DEFFERRED_IO option to support generic fbdev apps" +#warning Please set CONFIG_FB_DEFFERRED_IO option to support generic fbdev apps #endif #ifndef CONFIG_FB_SYS_IMAGEBLIT #ifndef CONFIG_FB_SYS_IMAGEBLIT_MODULE -#warning message "FB_SYS_* in kernel or module option to support fb console" +#warning Please set CONFIG_FB_SYS_IMAGEBLIT option to support fb console #endif #endif #ifndef CONFIG_FB_MODE_HELPERS -#warning message "kernel FB_MODE_HELPERS required. Expect build break" +#warning CONFIG_FB_MODE_HELPERS required. Expect build break #endif /* dlfb keeps a list of urbs for efficient bulk transfers */ @@ -366,32 +366,32 @@ static int dlfb_trim_hline(const u8 *bback, const u8 **bfront, int *width_bytes) } /* -Render a command stream for an encoded horizontal line segment of pixels. - -A command buffer holds several commands. -It always begins with a fresh command header -(the protocol doesn't require this, but we enforce it to allow -multiple buffers to be potentially encoded and sent in parallel). -A single command encodes one contiguous horizontal line of pixels - -The function relies on the client to do all allocation, so that -rendering can be done directly to output buffers (e.g. USB URBs). -The function fills the supplied command buffer, providing information -on where it left off, so the client may call in again with additional -buffers if the line will take several buffers to complete. - -A single command can transmit a maximum of 256 pixels, -regardless of the compression ratio (protocol design limit). -To the hardware, 0 for a size byte means 256 - -Rather than 256 pixel commands which are either rl or raw encoded, -the rlx command simply assumes alternating raw and rl spans within one cmd. -This has a slightly larger header overhead, but produces more even results. -It also processes all data (read and write) in a single pass. -Performance benchmarks of common cases show it having just slightly better -compression than 256 pixel raw -or- rle commands, with similar CPU consumpion. -But for very rl friendly data, will compress not quite as well. -*/ + * Render a command stream for an encoded horizontal line segment of pixels. + * + * A command buffer holds several commands. + * It always begins with a fresh command header + * (the protocol doesn't require this, but we enforce it to allow + * multiple buffers to be potentially encoded and sent in parallel). + * A single command encodes one contiguous horizontal line of pixels + * + * The function relies on the client to do all allocation, so that + * rendering can be done directly to output buffers (e.g. USB URBs). + * The function fills the supplied command buffer, providing information + * on where it left off, so the client may call in again with additional + * buffers if the line will take several buffers to complete. + * + * A single command can transmit a maximum of 256 pixels, + * regardless of the compression ratio (protocol design limit). + * To the hardware, 0 for a size byte means 256 + * + * Rather than 256 pixel commands which are either rl or raw encoded, + * the rlx command simply assumes alternating raw and rl spans within one cmd. + * This has a slightly larger header overhead, but produces more even results. + * It also processes all data (read and write) in a single pass. + * Performance benchmarks of common cases show it having just slightly better + * compression than 256 pixel raw -or- rle commands, with similar CPU consumpion. + * But for very rl friendly data, will compress not quite as well. + */ static void dlfb_compress_hline( const uint16_t **pixel_start_ptr, const uint16_t *const pixel_end, -- cgit v1.2.3 From b46966ee8f7c75fcff9e7390d29b1f62650b0784 Mon Sep 17 00:00:00 2001 From: Ng Kian Yong Date: Sat, 3 Apr 2010 17:09:34 +0800 Subject: Staging: vt6655: fix brace coding style issue in ioctl.c This is a patch to the ioctl.c file that fixes up a brace warning found by the checkpatch.pl tool Signed-off-by: Ng Kian Yong Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c index d9a5fd21ab31..38577ca841ea 100644 --- a/drivers/staging/vt6655/ioctl.c +++ b/drivers/staging/vt6655/ioctl.c @@ -83,7 +83,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) { pReq->wResult = 0; - switch(pReq->wCmdCode) { + switch (pReq->wCmdCode) { case WLAN_CMD_BSS_SCAN: -- cgit v1.2.3 From 3eec314fb26fc0e75c6f5d20f9b3d528ebf342d7 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Sat, 10 Apr 2010 00:33:17 +0200 Subject: Staging: rtl8187se: Do not autoconnect based on probe response Getting a probe response after sending a probe request to a specific SSID doesnt mean we're trying to associate with this SSID. wpa_supplicant should be the only one deciding when to join an SSID, not the kernel. Signed-off-by: Samuel Ortiz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c index 2b7080cc2c05..3a724496e748 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c @@ -1489,8 +1489,6 @@ inline void ieee80211_process_probe_response( memcpy(target, &network, sizeof(*target)); list_add_tail(&target->list, &ieee->network_list); - if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) - ieee80211_softmac_new_net(ieee,&network); } else { IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n", escape_essid(target->ssid, @@ -1516,8 +1514,6 @@ inline void ieee80211_process_probe_response( renew = 1; //YJ,add,080819,for hidden ap,end update_network(target, &network); - if(renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)) - ieee80211_softmac_new_net(ieee,&network); } spin_unlock_irqrestore(&ieee->lock, flags); -- cgit v1.2.3 From 592010bb71901d991cd758f6294db2db47e8efa1 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Sat, 10 Apr 2010 00:33:19 +0200 Subject: Staging: rtl8187se: Do not send NULL BSSID events when not associated If we're not associated, we should not send wireless events to let userspace know that we just left an ESSID, simply because we havent yet joined it. If we keep on doing that, wpa_supplicant could receive such events while actually trying to join an ESSID, and thus decide to stop trying. This leads to a lot of connection failures as this driver seems to be sending GIWAP events quite a lot. Signed-off-by: Samuel Ortiz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index 5fdb8f3df0a7..e099a5fa0494 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c @@ -2322,9 +2322,11 @@ void ieee80211_disassociate(struct ieee80211_device *ieee) if(IS_DOT11D_ENABLE(ieee)) Dot11d_Reset(ieee); - ieee->state = IEEE80211_NOLINK; + ieee->link_change(ieee->dev); - notify_wx_assoc_event(ieee); + if (ieee->state == IEEE80211_LINKED) + notify_wx_assoc_event(ieee); + ieee->state = IEEE80211_NOLINK; } void ieee80211_associate_retry_wq(struct work_struct *work) -- cgit v1.2.3 From a5e135b1f510e2d65f01190d7f292c298f337fc9 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Sat, 10 Apr 2010 00:33:18 +0200 Subject: Staging: rtl8187se: Do not mess with carrier settings while scanning Toggling the link carrier is a non sense and is the grossest locking I can think of. Moreover, it's giving a completely inaccurate status to userspace who could for example decide to turn the interface down on carrier off detection. Signed-off-by: Samuel Ortiz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c index ad42bcdc9374..e46ff2ffa09b 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c @@ -277,8 +277,6 @@ void ieee80211_wx_sync_scan_wq(struct work_struct *work) chan = ieee->current_network.channel; - netif_carrier_off(ieee->dev); - if (ieee->data_hard_stop) ieee->data_hard_stop(ieee->dev); @@ -300,8 +298,6 @@ void ieee80211_wx_sync_scan_wq(struct work_struct *work) if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER) ieee80211_start_send_beacons(ieee); - netif_carrier_on(ieee->dev); - //YJ,add,080828, In prevent of lossing ping packet during scanning //ieee80211_sta_ps_send_null_frame(ieee, false); //YJ,add,080828,end -- cgit v1.2.3 From cb73da2524df912ddec4aed0b6df1c0374f4ffc1 Mon Sep 17 00:00:00 2001 From: John Church Date: Thu, 8 Apr 2010 16:04:17 -0500 Subject: Staging: rtl8187se: fix coding style issues in r8180_core.c Signed-off-by: Larry Finger Signed-off-by: John Church Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_core.c | 98 +++++++++++++++++----------------- 1 file changed, 49 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 88fe6232a47d..84a745bb9ca0 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -44,24 +44,24 @@ #include "ieee80211/dot11d.h" static struct pci_device_id rtl8180_pci_id_tbl[] __devinitdata = { - { - .vendor = PCI_VENDOR_ID_REALTEK, - .device = 0x8199, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = 0, - }, - { - .vendor = 0, - .device = 0, - .subvendor = 0, - .subdevice = 0, - .driver_data = 0, - } + { + .vendor = PCI_VENDOR_ID_REALTEK, + .device = 0x8199, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = 0, + }, + { + .vendor = 0, + .device = 0, + .subvendor = 0, + .subdevice = 0, + .driver_data = 0, + } }; -static char* ifname = "wlan%d"; +static char *ifname = "wlan%d"; static int hwseqnum = 0; static int hwwep = 0; static int channels = 0x3fff; @@ -168,34 +168,34 @@ static struct pci_driver rtl8180_pci_driver = { u8 read_nic_byte(struct net_device *dev, int x) { - return 0xff&readb((u8*)dev->mem_start +x); + return 0xff&readb((u8 *)dev->mem_start + x); } u32 read_nic_dword(struct net_device *dev, int x) { - return readl((u8*)dev->mem_start +x); + return readl((u8 *)dev->mem_start + x); } u16 read_nic_word(struct net_device *dev, int x) { - return readw((u8*)dev->mem_start +x); + return readw((u8 *)dev->mem_start + x); } void write_nic_byte(struct net_device *dev, int x,u8 y) { - writeb(y,(u8*)dev->mem_start +x); + writeb(y, (u8 *)dev->mem_start + x); udelay(20); } void write_nic_dword(struct net_device *dev, int x,u32 y) { - writel(y,(u8*)dev->mem_start +x); + writel(y, (u8 *)dev->mem_start + x); udelay(20); } void write_nic_word(struct net_device *dev, int x,u16 y) { - writew(y,(u8*)dev->mem_start +x); + writew(y, (u8 *)dev->mem_start + x); udelay(20); } @@ -313,7 +313,7 @@ void rtl8180_proc_module_init(void) void rtl8180_proc_module_remove(void) { - remove_proc_entry(RTL8180_MODULE_NAME, init_net.proc_net); + remove_proc_entry(RTL8180_MODULE_NAME, init_net.proc_net); } void rtl8180_proc_remove_one(struct net_device *dev) @@ -383,7 +383,7 @@ void rtl8180_proc_init_one(struct net_device *dev) short buffer_add(struct buffer **buffer, u32 *buf, dma_addr_t dma, struct buffer **bufferhead) { - struct buffer *tmp; + struct buffer *tmp; if(! *buffer){ @@ -1429,7 +1429,7 @@ void rtl8180_rx(struct net_device *dev) u32 RXAGC = 0; long RxAGC_dBm = 0; u8 LNA=0, BB=0; - u8 LNA_gain[4]={02, 17, 29, 39}; + u8 LNA_gain[4] = {02, 17, 29, 39}; u8 Antenna = 0; struct ieee80211_hdr_4addr *hdr; u16 fc,type; @@ -1531,7 +1531,7 @@ void rtl8180_rx(struct net_device *dev) }else { padding = 0; } - padding = 0; + padding = 0; priv->rx_prevlen+=len; if(priv->rx_prevlen > MAX_FRAG_THRESHOLD + 100){ @@ -1624,7 +1624,7 @@ void rtl8180_rx(struct net_device *dev) bICV = ((*(priv->rxringtail)) & (0x00001000)) >> 12; hdr = (struct ieee80211_hdr_4addr *)priv->rxbuffer->buf; fc = le16_to_cpu(hdr->frame_ctl); - type = WLAN_FC_GET_TYPE(fc); + type = WLAN_FC_GET_TYPE(fc); if((IEEE80211_FTYPE_CTL != type) && (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3)) @@ -1948,11 +1948,11 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, u8 bUseShortPreamble = 0; u8 bCTSEnable = 0; u8 bRTSEnable = 0; - u16 Duration = 0; + u16 Duration = 0; u16 RtsDur = 0; u16 ThisFrameTime = 0; u16 TxDescDuration = 0; - u8 ownbit_flag = false; + u8 ownbit_flag = false; switch(priority) { case MANAGE_PRIORITY: @@ -2000,7 +2000,7 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, default: return -1; break; - } + } memcpy(&dest, frag_hdr->addr1, ETH_ALEN); if (is_multicast_ether_addr(dest) || @@ -2151,8 +2151,8 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, if(morefrag) *tail = (*tail) | (1<<17); // more fragment if(!remain) *tail = (*tail) | (1<<28); // last segment of frame - *(tail+5) = *(tail+5)|(2<<27); - *(tail+7) = *(tail+7)|(1<<4); + *(tail+5) = *(tail+5)|(2<<27); + *(tail+7) = *(tail+7)|(1<<4); wmb(); if(ownbit_flag) @@ -2289,13 +2289,13 @@ void rtl8180_hw_wakeup(struct net_device *dev) void rtl8180_hw_sleep_down(struct net_device *dev) { - unsigned long flags; - struct r8180_priv *priv = ieee80211_priv(dev); + unsigned long flags; + struct r8180_priv *priv = ieee80211_priv(dev); - spin_lock_irqsave(&priv->ps_lock,flags); - if(priv->rf_sleep) - priv->rf_sleep(dev); - spin_unlock_irqrestore(&priv->ps_lock,flags); + spin_lock_irqsave(&priv->ps_lock, flags); + if (priv->rf_sleep) + priv->rf_sleep(dev); + spin_unlock_irqrestore(&priv->ps_lock, flags); } void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl) @@ -2786,7 +2786,7 @@ short rtl8180_init(struct net_device *dev) priv->ieee80211->data_hard_stop = rtl8180_data_hard_stop; priv->ieee80211->data_hard_resume = rtl8180_data_hard_resume; - priv->ieee80211->init_wmmparam_flag = 0; + priv->ieee80211->init_wmmparam_flag = 0; priv->ieee80211->start_send_beacons = rtl8180_start_tx_beacon; priv->ieee80211->stop_send_beacons = rtl8180_beacon_tx_disable; @@ -2956,8 +2956,8 @@ short rtl8180_init(struct net_device *dev) return -ENOMEM; if(request_irq(dev->irq, (void *)rtl8180_interrupt, IRQF_SHARED, dev->name, dev)){ - DMESGE("Error allocating IRQ %d",dev->irq); - return -1; + DMESGE("Error allocating IRQ %d", dev->irq); + return -1; }else{ priv->irq=dev->irq; DMESG("IRQ %d",dev->irq); @@ -3102,7 +3102,7 @@ void rtl8185_set_rate(struct net_device *dev) void rtl8180_adapter_start(struct net_device *dev) { - struct r8180_priv *priv = ieee80211_priv(dev); + struct r8180_priv *priv = ieee80211_priv(dev); rtl8180_rtx_disable(dev); rtl8180_reset(dev); @@ -3196,7 +3196,7 @@ void rtl8180_start_tx_beacon(struct net_device *dev) rtl8180_set_mode(dev, EPROM_CMD_NORMAL); - rtl8185b_irq_enable(dev); + rtl8185b_irq_enable(dev); } static struct net_device_stats *rtl8180_stats(struct net_device *dev) @@ -3252,9 +3252,9 @@ void rtl8180_hw_sleep_wq (struct work_struct *work) { struct delayed_work *dwork = to_delayed_work(work); struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq); - struct net_device *dev = ieee->dev; + struct net_device *dev = ieee->dev; - rtl8180_hw_sleep_down(dev); + rtl8180_hw_sleep_down(dev); } static void MgntLinkKeepAlive(struct r8180_priv *priv ) @@ -3373,7 +3373,7 @@ int _rtl8180_up(struct net_device *dev) } timer_rate_adaptive((unsigned long)dev); watch_dog_adaptive((unsigned long)dev); - if(priv->bSwAntennaDiverity) + if (priv->bSwAntennaDiverity) SwAntennaDiversityTimerCallback(dev); ieee80211_softmac_start_protocol(priv->ieee80211); return 0; @@ -3614,10 +3614,10 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev, dev->watchdog_timeo = HZ*3; if (dev_alloc_name(dev, ifname) < 0){ - DMESG("Oops: devname already taken! Trying wlan%%d...\n"); + DMESG("Oops: devname already taken! Trying wlan%%d...\n"); ifname = "wlan%d"; dev_alloc_name(dev, ifname); - } + } if(rtl8180_init(dev)!=0){ DMESG("Initialization failed"); @@ -4091,10 +4091,10 @@ void GPIOChangeRFWorkItemCallBack(struct work_struct *work) u8 btPSR; u8 btConfig0; RT_RF_POWER_STATE eRfPowerStateToSet; - bool bActuallySet=false; + bool bActuallySet = false; char *argv[3]; - static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh"; + static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh"; static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL}; static int readf_count = 0; -- cgit v1.2.3 From 1695eb36bf4616c6ec062d2dc2c3abe54d3aa313 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Sun, 11 Apr 2010 13:22:53 +0300 Subject: Staging: serqt_usb2: fix space coding style issue in serqt_usb2.c This is a patch to the serqt_usb2.c files that fixed space error and warning found by the checkpatch.pl tools. Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/serqt_usb2/serqt_usb2.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 44f2d4eaf84b..27841ef6a568 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -413,7 +413,7 @@ static void qt_read_bulk_callback(struct urb *urb) case 0x01: /* Modem status status change 4th byte must follow */ - dbg("Modem status status. \n"); + dbg("Modem status status.\n"); if (i > (RxCount - 4)) { dbg("Illegal escape sequences in received data\n"); break; @@ -424,7 +424,7 @@ static void qt_read_bulk_callback(struct urb *urb) flag = 1; break; case 0xff: - dbg("No status sequence. \n"); + dbg("No status sequence.\n"); if (tty) { ProcessRxChar(tty, port, data[i]); @@ -738,7 +738,7 @@ static int qt_startup(struct usb_serial *serial) if (!qt_port) { dbg("%s: kmalloc for quatech_port (%d) failed!.", __func__, i); - for(--i; i >= 0; i--) { + for (--i; i >= 0; i--) { port = serial->port[i]; kfree(usb_get_serial_port_data(port)); usb_set_serial_port_data(port, NULL); @@ -963,11 +963,11 @@ static int qt_open(struct tty_struct *tty, } - dbg("port number is %d \n", port->number); - dbg("serial number is %d \n", port->serial->minor); - dbg("Bulkin endpoint is %d \n", port->bulk_in_endpointAddress); - dbg("BulkOut endpoint is %d \n", port->bulk_out_endpointAddress); - dbg("Interrupt endpoint is %d \n", port->interrupt_in_endpointAddress); + dbg("port number is %d\n", port->number); + dbg("serial number is %d\n", port->serial->minor); + dbg("Bulkin endpoint is %d\n", port->bulk_in_endpointAddress); + dbg("BulkOut endpoint is %d\n", port->bulk_out_endpointAddress); + dbg("Interrupt endpoint is %d\n", port->interrupt_in_endpointAddress); dbg("port's number in the device is %d\n", quatech_port->port_num); quatech_port->read_urb = port->read_urb; @@ -1470,7 +1470,7 @@ static int qt_tiocmget(struct tty_struct *tty, struct file *file) int retval = -ENODEV; unsigned long flags; - dbg("In %s \n", __func__); + dbg("In %s\n", __func__); if (!serial) return -ENODEV; @@ -1496,14 +1496,14 @@ static int qt_tiocmset(struct tty_struct *tty, struct file *file, unsigned long flags; int retval = -ENODEV; - dbg("In %s \n", __func__); + dbg("In %s\n", __func__); if (!serial) return -ENODEV; spin_lock_irqsave(&qt_port->lock, flags); - dbg("%s - port %d \n", __func__, port->number); + dbg("%s - port %d\n", __func__, port->number); dbg("%s - qt_port->RxHolding = %d\n", __func__, qt_port->RxHolding); retval = qt_real_tiocmset(tty, port, file, serial, set); @@ -1584,9 +1584,9 @@ static int qt_calc_num_ports(struct usb_serial *serial) { int num_ports; - dbg("numberofendpoints: %d \n", + dbg("numberofendpoints: %d\n", (int)serial->interface->cur_altsetting->desc.bNumEndpoints); - dbg("numberofendpoints: %d \n", + dbg("numberofendpoints: %d\n", (int)serial->interface->altsetting->desc.bNumEndpoints); num_ports = -- cgit v1.2.3 From 1fc5af161f09da027d442a691de67644b66fd012 Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Sun, 11 Apr 2010 13:39:47 +0300 Subject: Staging: rtl8192u: fix comments and space coding style issue in dot11d.h This is a patch to the dot11d.h file that fixed up a comments and space Errors found by the checkpatch.pl tools Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/dot11d.h | 52 +++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192u/dot11d.h b/drivers/staging/rtl8192u/dot11d.h index 15b7a4ba37b6..0851b9db17a6 100644 --- a/drivers/staging/rtl8192u/dot11d.h +++ b/drivers/staging/rtl8192u/dot11d.h @@ -4,44 +4,44 @@ #ifdef ENABLE_DOT11D #include "ieee80211.h" -//#define ENABLE_DOT11D - -//#define DOT11D_MAX_CHNL_NUM 83 typedef struct _CHNL_TXPOWER_TRIPLE { u8 FirstChnl; u8 NumChnls; u8 MaxTxPowerInDbm; -}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE; +} CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE; typedef enum _DOT11D_STATE { DOT11D_STATE_NONE = 0, DOT11D_STATE_LEARNED, DOT11D_STATE_DONE, -}DOT11D_STATE; +} DOT11D_STATE; typedef struct _RT_DOT11D_INFO { - //DECLARE_RT_OBJECT(RT_DOT11D_INFO); + /* DECLARE_RT_OBJECT(RT_DOT11D_INFO); */ - bool bEnabled; // dot11MultiDomainCapabilityEnabled + bool bEnabled; /* dot11MultiDomainCapabilityEnabled */ - u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element. + u16 CountryIeLen; /* > 0 if CountryIeBuf[] contains valid country information element. */ u8 CountryIeBuf[MAX_IE_LEN]; - u8 CountryIeSrcAddr[6]; // Source AP of the country IE. + u8 CountryIeSrcAddr[6]; /* Source AP of the country IE. */ u8 CountryIeWatchdog; - u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) - //u8 ChnlListLen; // #Bytes valid in ChnlList[]. - //u8 ChnlList[DOT11D_MAX_CHNL_NUM]; + u8 channel_map[MAX_CHANNEL_NUMBER+1]; /* !Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) */ u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1]; DOT11D_STATE State; -}RT_DOT11D_INFO, *PRT_DOT11D_INFO; -#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 ) -#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5]) +} RT_DOT11D_INFO, *PRT_DOT11D_INFO; +#define eqMacAddr(a, b) (((a)[0] == (b)[0] && \ + (a)[1] == (b)[1] && (a)[2] == (b)[2] && (a)[3] == (b)[3] && \ + (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1 : 0) +#define cpMacAddr(des, src) ((des)[0] = (src)[0], \ + (des)[1] = (src)[1], (des)[2] = (src)[2], \ + (des)[3] = (src)[3], (des)[4] = (src)[4], \ + (des)[5] = (src)[5]) #define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo)) -#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled +#define IS_DOT11D_ENABLE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->bEnabled) #define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0) #define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) @@ -53,9 +53,9 @@ typedef struct _RT_DOT11D_INFO { (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length))) #define CIE_WATCHDOG_TH 1 -#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog +#define GET_CIE_WATCHDOG(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog) #define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0 -#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev) +#define UPDATE_CIE_WATCHDOG(__pIeeeDev) (++GET_CIE_WATCHDOG(__pIeeeDev)) #define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE) @@ -73,9 +73,9 @@ Dot11d_Reset( void Dot11d_UpdateCountryIe( struct ieee80211_device *dev, - u8 * pTaddr, - u16 CoutryIeLen, - u8 * pCoutryIe + u8 *pTaddr, + u16 CoutryIeLen, + u8 *pCoutryIe ); u8 @@ -86,17 +86,17 @@ DOT11D_GetMaxTxPwrInDbm( void DOT11D_ScanComplete( - struct ieee80211_device * dev + struct ieee80211_device *dev ); int IsLegalChannel( - struct ieee80211_device * dev, + struct ieee80211_device *dev, u8 channel ); int ToLegalChannel( - struct ieee80211_device * dev, + struct ieee80211_device *dev, u8 channel ); -#endif //ENABLE_DOT11D -#endif // #ifndef __INC_DOT11D_H +#endif /* ENABLE_DOT11D */ +#endif /* #ifndef __INC_DOT11D_H */ -- cgit v1.2.3 From 9271ff10480023953bebe2f897af8128b5334f7a Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Sun, 11 Apr 2010 15:05:39 +0300 Subject: Staging: rtl8192u: ix brace, comments and space coding style issue in ieee80211.h This is a patch to the ieee80211.h file that fixed up a brace, comments and space Errors found by the checkpatch.pl tools. Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211.h | 548 ++++++++++++++++------------------- 1 file changed, 254 insertions(+), 294 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192u/ieee80211.h b/drivers/staging/rtl8192u/ieee80211.h index 9d05ed6791ee..ef9e941f4967 100644 --- a/drivers/staging/rtl8192u/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211.h @@ -58,12 +58,12 @@ * */ #define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) + const typeof(((type *)0)->member) (*__mptr = (ptr)); \ + (type *)((char *)__mptr - offsetof(type, member)); }) #endif #define KEY_TYPE_NA 0x0 -#define KEY_TYPE_WEP40 0x1 +#define KEY_TYPE_WEP40 0x1 #define KEY_TYPE_TKIP 0x2 #define KEY_TYPE_CCMP 0x4 #define KEY_TYPE_WEP104 0x5 @@ -71,9 +71,9 @@ /* added for rtl819x tx procedure */ #define MAX_QUEUE_SIZE 0x10 -// -// 8190 queue mapping -// +/* + * 8190 queue mapping + */ #define BK_QUEUE 0 #define BE_QUEUE 1 #define VI_QUEUE 2 @@ -87,13 +87,13 @@ #define LOW_QUEUE BE_QUEUE #define NORMAL_QUEUE MGNT_QUEUE -//added by amy for ps +/* added by amy for ps */ #define SWRF_TIMEOUT 50 -//added by amy for LEAP related -#define IE_CISCO_FLAG_POSITION 0x08 // Flag byte: byte 8, numbered from 0. -#define SUPPORT_CKIP_MIC 0x08 // bit3 -#define SUPPORT_CKIP_PK 0x10 // bit4 +/* added by amy for LEAP related */ +#define IE_CISCO_FLAG_POSITION 0x08 /* Flag byte: byte 8, numbered from 0. */ +#define SUPPORT_CKIP_MIC 0x08 /* bit3 */ +#define SUPPORT_CKIP_PK 0x10 /* bit4 */ /* defined for skb cb field */ /* At most 28 byte */ typedef struct cb_desc { @@ -105,7 +105,7 @@ typedef struct cb_desc { u8 bEncrypt:1; u8 bTxDisableRateFallBack:1; u8 bTxUseDriverAssingedRate:1; - u8 bHwSec:1; //indicate whether use Hw security. WB + u8 bHwSec:1; /* indicate whether use Hw security. WB */ u8 reserved1; @@ -125,17 +125,13 @@ typedef struct cb_desc { u8 bRTSUseShortGI:1; u8 bMulticast:1; u8 bBroadcast:1; - //u8 reserved2:2; u8 drv_agg_enable:1; u8 reserved2:1; /* Tx Desc related element(12-19) */ u8 rata_index; u8 queue_index; - //u8 reserved3; - //u8 reserved4; u16 txbuf_size; - //u8 reserved5; u8 RATRIndex; u8 reserved6; u8 reserved7; @@ -146,13 +142,10 @@ typedef struct cb_desc { u8 rts_rate; u8 ampdu_factor; u8 ampdu_density; - //u8 reserved9; - //u8 reserved10; - //u8 reserved11; u8 DrvAggrNum; u16 pkt_size; u8 reserved12; -}cb_desc, *pcb_desc; +} cb_desc, *pcb_desc; /*--------------------------Define -------------------------------------------*/ #define MGN_1M 0x02 @@ -186,9 +179,9 @@ typedef struct cb_desc { #define MGN_MCS14 0x8e #define MGN_MCS15 0x8f -//---------------------------------------------------------------------------- -// 802.11 Management frame Reason Code field -//---------------------------------------------------------------------------- +/* + * 802.11 Management frame Reason Code field + */ enum _ReasonCode{ unspec_reason = 0x1, auth_not_valid = 0x2, @@ -200,11 +193,11 @@ enum _ReasonCode{ disas_lv_ss = 0x8, asoc_not_auth = 0x9, - //----MIC_CHECK + /* ----MIC_CHECK */ mic_failure = 0xe, - //----END MIC_CHECK + /* ----END MIC_CHECK */ - // Reason code defined in 802.11i D10.0 p.28. + /* Reason code defined in 802.11i D10.0 p.28. */ invalid_IE = 0x0d, four_way_tmout = 0x0f, two_way_tmout = 0x10, @@ -214,27 +207,29 @@ enum _ReasonCode{ invalid_AKMP = 0x14, unsup_RSNIEver = 0x15, invalid_RSNIE = 0x16, - auth_802_1x_fail= 0x17, + auth_802_1x_fail = 0x17, ciper_reject = 0x18, - // Reason code defined in 7.3.1.7, 802.1e D13.0, p.42. Added by Annie, 2005-11-15. - QoS_unspec = 0x20, // 32 - QAP_bandwidth = 0x21, // 33 - poor_condition = 0x22, // 34 - no_facility = 0x23, // 35 - // Where is 36??? - req_declined = 0x25, // 37 - invalid_param = 0x26, // 38 - req_not_honored= 0x27, // 39 - TS_not_created = 0x2F, // 47 - DL_not_allowed = 0x30, // 48 - dest_not_exist = 0x31, // 49 - dest_not_QSTA = 0x32, // 50 + /* Reason code defined in 7.3.1.7, 802.1e D13.0, p.42. */ + QoS_unspec = 0x20, /* 32 */ + QAP_bandwidth = 0x21, /* 33 */ + poor_condition = 0x22, /* 34 */ + no_facility = 0x23, /* 35 */ + /* Where is 36??? */ + req_declined = 0x25, /* 37 */ + invalid_param = 0x26, /* 38 */ + req_not_honored = 0x27, /* 39 */ + TS_not_created = 0x2F, /* 47 */ + DL_not_allowed = 0x30, /* 48 */ + dest_not_exist = 0x31, /* 49 */ + dest_not_QSTA = 0x32, /* 50 */ }; -#define aSifsTime ((priv->ieee80211->current_network.mode == IEEE_A)||(priv->ieee80211->current_network.mode == IEEE_N_24G)||(priv->ieee80211->current_network.mode == IEEE_N_5G))? 16 : 10 +#define aSifsTime ((priv->ieee80211->current_network.mode == IEEE_A) || \ + (priv->ieee80211->current_network.mode == IEEE_N_24G) || \ + (priv->ieee80211->current_network.mode == IEEE_N_5G)) ? 16 : 10 #define MGMT_QUEUE_NUM 5 @@ -249,15 +244,12 @@ enum _ReasonCode{ #define IEEE_PARAM_PRIVACY_INVOKED 4 #define IEEE_PARAM_AUTH_ALGS 5 #define IEEE_PARAM_IEEE_802_1X 6 -//It should consistent with the driver_XXX.c -// David, 2006.9.26 +/* It should consistent with the driver_XXX.c */ #define IEEE_PARAM_WPAX_SELECT 7 -//Added for notify the encryption type selection -// David, 2006.9.26 +/* Added for notify the encryption type selection */ #define IEEE_PROTO_WPA 1 #define IEEE_PROTO_RSN 2 -//Added for notify the encryption type selection -// David, 2006.9.26 +/* Added for notify the encryption type selection */ #define IEEE_WPAX_USEGROUP 0 #define IEEE_WPAX_WEP40 1 #define IEEE_WPAX_TKIP 2 @@ -284,7 +276,7 @@ enum _ReasonCode{ #define MAX_IE_LEN 0xff -// added for kernel conflict +/* added for kernel conflict */ #define ieee80211_crypt_deinit_entries ieee80211_crypt_deinit_entries_rsl #define ieee80211_crypt_deinit_handler ieee80211_crypt_deinit_handler_rsl #define ieee80211_crypt_delayed_deinit ieee80211_crypt_delayed_deinit_rsl @@ -385,7 +377,7 @@ typedef struct ieee_param { u8 key[0]; } crypt; } u; -}ieee_param; +} ieee_param; #if WIRELESS_EXT < 17 @@ -398,7 +390,7 @@ typedef struct ieee_param { #endif -// linux under 2.6.9 release may not support it, so modify it for common use +/* linux under 2.6.9 release may not support it, so modify it for common use */ #define MSECS(t) msecs_to_jiffies(t) #define msleep_interruptible_rsl msleep_interruptible @@ -432,7 +424,7 @@ typedef struct ieee_param { #define IEEE80211_FCTL_FRAMETYPE 0x00fc #define IEEE80211_FCTL_TODS 0x0100 #define IEEE80211_FCTL_FROMDS 0x0200 -#define IEEE80211_FCTL_DSTODS 0x0300 //added by david +#define IEEE80211_FCTL_DSTODS 0x0300 #define IEEE80211_FCTL_MOREFRAGS 0x0400 #define IEEE80211_FCTL_RETRY 0x0800 #define IEEE80211_FCTL_PM 0x1000 @@ -476,7 +468,7 @@ typedef struct ieee_param { #define IEEE80211_STYPE_CFACK 0x0050 #define IEEE80211_STYPE_CFPOLL 0x0060 #define IEEE80211_STYPE_CFACKPOLL 0x0070 -#define IEEE80211_STYPE_QOS_DATA 0x0080 //added for WMM 2006/8/2 +#define IEEE80211_STYPE_QOS_DATA 0x0080 #define IEEE80211_STYPE_QOS_NULL 0x00C0 #define IEEE80211_SCTL_FRAG 0x000F @@ -486,12 +478,12 @@ typedef struct ieee_param { #define IEEE80211_QCTL_TID 0x000F #define FC_QOS_BIT BIT7 -#define IsDataFrame(pdu) ( ((pdu[0] & 0x0C)==0x08) ? true : false ) -#define IsLegacyDataFrame(pdu) (IsDataFrame(pdu) && (!(pdu[0]&FC_QOS_BIT)) ) -//added by wb. Is this right? -#define IsQoSDataFrame(pframe) ((*(u16*)pframe&(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) == (IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) -#define Frame_Order(pframe) (*(u16*)pframe&IEEE80211_FCTL_ORDER) -#define SN_LESS(a, b) (((a-b)&0x800)!=0) +#define IsDataFrame(pdu) (((pdu[0] & 0x0C) == 0x08) ? true : false) +#define IsLegacyDataFrame(pdu) (IsDataFrame(pdu) && (!(pdu[0]&FC_QOS_BIT))) + +#define IsQoSDataFrame(pframe) ((*(u16 *)pframe&(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) == (IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) +#define Frame_Order(pframe) (*(u16 *)pframe&IEEE80211_FCTL_ORDER) +#define SN_LESS(a, b) (((a-b)&0x800) != 0) #define SN_EQUAL(a, b) (a == b) #define MAX_DEV_ADDR_SIZE 8 typedef enum _ACT_CATEGORY{ @@ -516,10 +508,10 @@ typedef enum _BA_ACTION{ } BA_ACTION, *PBA_ACTION; typedef enum _InitialGainOpType{ - IG_Backup=0, + IG_Backup = 0, IG_Restore, IG_Max -}InitialGainOpType; +} InitialGainOpType; /* debug macros */ #define CONFIG_IEEE80211_DEBUG @@ -528,25 +520,26 @@ extern u32 ieee80211_debug_level; #define IEEE80211_DEBUG(level, fmt, args...) \ do { if (ieee80211_debug_level & (level)) \ printk(KERN_DEBUG "ieee80211: " fmt, ## args); } while (0) -//wb added to debug out data buf -//if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA +/* wb added to debug out data buf + * if you want print DATA buffer related BA, please set ieee80211_debug_level + * to DATA|BA + */ #define IEEE80211_DEBUG_DATA(level, data, datalen) \ - do{ if ((ieee80211_debug_level & (level)) == (level)) \ - { \ + do { if ((ieee80211_debug_level & (level)) == (level)) { \ int i; \ - u8* pdata = (u8*) data; \ + u8* pdata = (u8 *) data; \ printk(KERN_DEBUG "ieee80211: %s()\n", __FUNCTION__); \ - for(i=0; i<(int)(datalen); i++) \ - { \ + for (i = 0; i < (int)(datalen); i++) { \ printk("%2x ", pdata[i]); \ - if ((i+1)%16 == 0) printk("\n"); \ - } \ + if ((i+1)%16 == 0) \ + printk("\n"); \ + } \ printk("\n"); \ } \ } while (0) #else #define IEEE80211_DEBUG(level, fmt, args...) do {} while (0) -#define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while(0) +#define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while (0) #endif /* CONFIG_IEEE80211_DEBUG */ /* debug macros not dependent on CONFIG_IEEE80211_DEBUG */ @@ -589,16 +582,16 @@ do { if (ieee80211_debug_level & (level)) \ #define IEEE80211_DL_TX (1<<8) #define IEEE80211_DL_RX (1<<9) -#define IEEE80211_DL_HT (1<<10) //HT -#define IEEE80211_DL_BA (1<<11) //ba -#define IEEE80211_DL_TS (1<<12) //TS +#define IEEE80211_DL_HT (1<<10) /* HT */ +#define IEEE80211_DL_BA (1<<11) /* ba */ +#define IEEE80211_DL_TS (1<<12) /* TS */ #define IEEE80211_DL_QOS (1<<13) #define IEEE80211_DL_REORDER (1<<14) #define IEEE80211_DL_IOT (1<<15) #define IEEE80211_DL_IPS (1<<16) -#define IEEE80211_DL_TRACE (1<<29) //trace function, need to user net_ratelimit() together in order not to print too much to the screen -#define IEEE80211_DL_DATA (1<<30) //use this flag to control whether print data buf out. -#define IEEE80211_DL_ERR (1<<31) //always open +#define IEEE80211_DL_TRACE (1<<29) /* trace function, need to user net_ratelimit() together in order not to print too much to the screen */ +#define IEEE80211_DL_DATA (1<<30) /* use this flag to control whether print data buf out. */ +#define IEEE80211_DL_ERR (1<<31) /* always open */ #define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a) #define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a) #define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a) @@ -618,18 +611,17 @@ do { if (ieee80211_debug_level & (level)) \ /* Added by Annie, 2005-11-22. */ #define MAX_STR_LEN 64 /* I want to see ASCII 33 to 126 only. Otherwise, I print '?'. Annie, 2005-11-22.*/ -#define PRINTABLE(_ch) (_ch>'!' && _ch<'~') +#define PRINTABLE(_ch) (_ch > '!' && _ch < '~') #define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len) \ - if((_Comp) & level) \ - { \ + if ((_Comp) & level) { \ int __i; \ u8 buffer[MAX_STR_LEN]; \ - int length = (_Len /* ARPHRD_ETHER */ #ifndef WIRELESS_SPY -#define WIRELESS_SPY // enable iwspy support +#define WIRELESS_SPY /* enable iwspy support */ #endif -#include // new driver API +#include /* new driver API */ #ifndef ETH_P_PAE #define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ @@ -873,29 +865,28 @@ struct ieee80211_rx_stats { u32 beacon_time; u8 nic_type; u16 Length; - // u8 DataRate; // In 0.5 Mbps - u8 SignalQuality; // in 0-100 index. - s32 RecvSignalPower; // Real power in dBm for this packet, no beautification and aggregation. - s8 RxPower; // in dBm Translate from PWdB - u8 SignalStrength; // in 0-100 index. + u8 SignalQuality; /* in 0-100 index. */ + s32 RecvSignalPower; /* Real power in dBm for this packet, no beautification and aggregation. */ + s8 RxPower; /* in dBm Translate from PWdB */ + u8 SignalStrength; /* in 0-100 index. */ u16 bHwError:1; u16 bCRC:1; u16 bICV:1; u16 bShortPreamble:1; - u16 Antenna:1; //for rtl8185 - u16 Decrypted:1; //for rtl8185, rtl8187 - u16 Wakeup:1; //for rtl8185 - u16 Reserved0:1; //for rtl8185 + u16 Antenna:1; /* for rtl8185 */ + u16 Decrypted:1; /* for rtl8185, rtl8187 */ + u16 Wakeup:1; /* for rtl8185 */ + u16 Reserved0:1; /* for rtl8185 */ u8 AGC; u32 TimeStampLow; u32 TimeStampHigh; bool bShift; - bool bIsQosData; // Added by Annie, 2005-12-22. + bool bIsQosData; u8 UserPriority; - //1!!!!!!!!!!!!!!!!!!!!!!!!!!! - //1Attention Please!!!<11n or 8190 specific code should be put below this line> - //1!!!!!!!!!!!!!!!!!!!!!!!!!!! + /* + * 1Attention Please!!!<11n or 8190 specific code should be put below this line> + */ u8 RxDrvInfoSize; u8 RxBufShift; @@ -904,21 +895,20 @@ struct ieee80211_rx_stats { bool bContainHTC; bool RxIs40MHzPacket; u32 RxPWDBAll; - u8 RxMIMOSignalStrength[4]; // in 0~100 index + u8 RxMIMOSignalStrength[4]; /* in 0~100 index */ s8 RxMIMOSignalQuality[2]; bool bPacketMatchBSSID; bool bIsCCK; bool bPacketToSelf; - //added by amy - u8* virtual_address; - u16 packetlength; // Total packet length: Must equal to sum of all FragLength - u16 fraglength; // FragLength should equal to PacketLength in non-fragment case - u16 fragoffset; // Data offset for this fragment + u8 *virtual_address; + u16 packetlength; /* Total packet length: Must equal to sum of all FragLength */ + u16 fraglength; /* FragLength should equal to PacketLength in non-fragment case */ + u16 fragoffset; /* Data offset for this fragment */ u16 ntotalfrag; bool bisrxaggrsubframe; - bool bPacketBeacon; //cosa add for rssi - bool bToSelfBA; //cosa add for rssi - char cck_adc_pwdb[4]; //cosa add for rx path selection + bool bPacketBeacon; /* cosa add for rssi */ + bool bToSelfBA; /* cosa add for rssi */ + char cck_adc_pwdb[4]; /* cosa add for rx path selection */ u16 Seq_Num; }; @@ -1045,9 +1035,9 @@ enum ieee80211_mfie { MFIE_TYPE_ERP = 42, MFIE_TYPE_RSN = 48, MFIE_TYPE_RATES_EX = 50, - MFIE_TYPE_HT_CAP= 45, - MFIE_TYPE_HT_INFO= 61, - MFIE_TYPE_AIRONET=133, + MFIE_TYPE_HT_CAP = 45, + MFIE_TYPE_HT_INFO = 61, + MFIE_TYPE_AIRONET = 133, MFIE_TYPE_GENERIC = 221, MFIE_TYPE_QOS_PARAMETER = 222, }; @@ -1199,7 +1189,7 @@ struct ieee80211_txb { struct ieee80211_drv_agg_txb { u8 nr_drv_agg_frames; struct sk_buff *tx_agg_frames[MAX_TX_AGG_COUNT]; -}__attribute__((packed)); +} __attribute__((packed)); #define MAX_SUBFRAME_COUNT 64 struct ieee80211_rxb { @@ -1207,7 +1197,7 @@ struct ieee80211_rxb { struct sk_buff *subframes[MAX_SUBFRAME_COUNT]; u8 dst[ETH_ALEN]; u8 src[ETH_ALEN]; -}__attribute__((packed)); +} __attribute__((packed)); typedef union _frameqos { u16 shortdata; @@ -1218,8 +1208,8 @@ typedef union _frameqos { u16 ack_policy:2; u16 reserved:1; u16 txop:8; - }field; -}frameqos,*pframeqos; + } field; +} frameqos, *pframeqos; /* SWEEP TABLE ENTRIES NUMBER*/ #define MAX_SWEEP_TAB_ENTRIES 42 @@ -1234,7 +1224,7 @@ typedef union _frameqos { #define MAX_CHANNEL_NUMBER 161 #define IEEE80211_SOFTMAC_SCAN_TIME 100 -//(HZ / 2) +/* (HZ / 2) */ #define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2) #define CRC_LENGTH 4U @@ -1310,7 +1300,6 @@ struct ieee80211_tim_parameters { u8 tim_period; } __attribute__ ((packed)); -//#else struct ieee80211_wmm_ac_param { u8 ac_aci_acm_aifsn; u8 ac_ecwmin_ecwmax; @@ -1340,7 +1329,7 @@ struct ieee80211_wmm_tspec_elem { u32 min_phy_rate; u16 surp_band_allow; u16 medium_time; -}__attribute__((packed)); +} __attribute__((packed)); enum eap_type { EAP_PACKET = 0, EAPOL_START, @@ -1361,17 +1350,15 @@ static inline const char *eap_get_type(int type) { return ((u32)type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type]; } -//added by amy for reorder -static inline u8 Frame_QoSTID(u8* buf) +static inline u8 Frame_QoSTID(u8 *buf) { struct ieee80211_hdr_3addr *hdr; u16 fc; hdr = (struct ieee80211_hdr_3addr *)buf; fc = le16_to_cpu(hdr->frame_ctl); - return (u8)((frameqos*)(buf + (((fc & IEEE80211_FCTL_TODS)&&(fc & IEEE80211_FCTL_FROMDS))? 30 : 24)))->field.tid; + return (u8)((frameqos *)(buf + (((fc & IEEE80211_FCTL_TODS) && (fc & IEEE80211_FCTL_FROMDS)) ? 30 : 24)))->field.tid; } -//added by amy for reorder struct eapol { u8 snap[6]; @@ -1429,7 +1416,7 @@ struct ieee80211_info_element_hdr { */ #define IEEE80211_DEFAULT_TX_ESSID "Penguin" -#define IEEE80211_DEFAULT_BASIC_RATE 2 //1Mbps +#define IEEE80211_DEFAULT_BASIC_RATE 2 /* 1Mbps */ enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame}; #define MAX_SP_Len (WMM_all_frame << 4) @@ -1445,8 +1432,7 @@ enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame}; #define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST #define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST -//added by David for QoS 2006/6/30 -//#define WMM_Hang_8187 + #ifdef WMM_Hang_8187 #undef WMM_Hang_8187 #endif @@ -1461,15 +1447,14 @@ enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame}; #define MAX_RECEIVE_BUFFER_SIZE 9100 -//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP -//#define UP2AC(up) ((up<3) ? ((up==0)?1:0) : (up>>1)) +/* UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP */ #define UP2AC(up) ( \ ((up) < 1) ? WME_AC_BE : \ ((up) < 3) ? WME_AC_BK : \ ((up) < 4) ? WME_AC_BE : \ ((up) < 6) ? WME_AC_VI : \ WME_AC_VO) -//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue +/* AC Mapping to UP, using in Tx part for selecting the corresponding TX queue */ #define AC2UP(_ac) ( \ ((_ac) == WME_AC_VO) ? 6 : \ ((_ac) == WME_AC_VI) ? 5 : \ @@ -1496,19 +1481,19 @@ typedef struct _bss_ht{ bool support_ht; - // HT related elements + /* HT related elements */ u8 ht_cap_buf[32]; u16 ht_cap_len; u8 ht_info_buf[32]; u16 ht_info_len; HT_SPEC_VER ht_spec_ver; - //HT_CAPABILITY_ELE bdHTCapEle; - //HT_INFORMATION_ELE bdHTInfoEle; + /* HT_CAPABILITY_ELE bdHTCapEle; */ + /* HT_INFORMATION_ELE bdHTInfoEle; */ bool aggregation; bool long_slot_time; -}bss_ht, *pbss_ht; +} bss_ht, *pbss_ht; typedef enum _erp_t{ ERP_NonERPpresent = 0x01, @@ -1525,16 +1510,15 @@ struct ieee80211_network { u8 ssid[IW_ESSID_MAX_SIZE + 1]; u8 ssid_len; struct ieee80211_qos_data qos_data; - //added by amy for LEAP bool bWithAironetIE; bool bCkipSupported; bool bCcxRmEnable; u16 CcxRmState[2]; - // CCXv4 S59, MBSSID. + /* CCXv4 S59, MBSSID. */ bool bMBssidValid; u8 MBssidMask; u8 MBssid[6]; - // CCX 2 S38, WLAN Device Version Number element. Annie, 2006-08-20. + /* CCX 2 S38, WLAN Device Version Number element. */ bool bWithCcxVerNum; u8 BssCcxVerNumber; /* These are network statistics */ @@ -1563,29 +1547,28 @@ struct ieee80211_network { u8 dtim_data; u32 last_dtim_sta_time[2]; - //appeded for QoS + /* appeded for QoS */ u8 wmm_info; struct ieee80211_wmm_ac_param wmm_param[4]; u8 QoS_Enable; #ifdef THOMAS_TURBO - u8 Turbo_Enable;//enable turbo mode, added by thomas + u8 Turbo_Enable;/* enable turbo mode, added by thomas */ #endif #ifdef ENABLE_DOT11D u16 CountryIeLen; u8 CountryIeBuf[MAX_IE_LEN]; #endif - // HT Related, by amy, 2008.04.29 + /* HT Related */ BSS_HT bssht; - // Add to handle broadcom AP management frame CCK rate. + /* Add to handle broadcom AP management frame CCK rate. */ bool broadcom_cap_exist; bool ralink_cap_exist; bool atheros_cap_exist; bool cisco_cap_exist; bool unknown_cap_exist; -// u8 berp_info; bool berp_info_valid; bool buseprotection; - //put at the end of the structure. + /* put at the end of the structure. */ struct list_head list; }; @@ -1650,75 +1633,66 @@ enum ieee80211_state { typedef struct tx_pending_t{ int frag; struct ieee80211_txb *txb; -}tx_pending_t; +} tx_pending_t; -typedef struct _bandwidth_autoswitch -{ +typedef struct _bandwidth_autoswitch { long threshold_20Mhzto40Mhz; long threshold_40Mhzto20Mhz; bool bforced_tx20Mhz; bool bautoswitch_enable; -}bandwidth_autoswitch,*pbandwidth_autoswitch; +} bandwidth_autoswitch, *pbandwidth_autoswitch; -//added by amy for order #define REORDER_WIN_SIZE 128 #define REORDER_ENTRY_NUM 128 -typedef struct _RX_REORDER_ENTRY -{ +typedef struct _RX_REORDER_ENTRY { struct list_head List; u16 SeqNum; - struct ieee80211_rxb* prxb; + struct ieee80211_rxb *prxb; } RX_REORDER_ENTRY, *PRX_REORDER_ENTRY; -//added by amy for order -typedef enum _Fsync_State{ + +typedef enum _Fsync_State { Default_Fsync, HW_Fsync, SW_Fsync -}Fsync_State; +} Fsync_State; -// Power save mode configured. -typedef enum _RT_PS_MODE -{ - eActive, // Active/Continuous access. - eMaxPs, // Max power save mode. - eFastPs // Fast power save mode. -}RT_PS_MODE; +/* Power save mode configured. */ +typedef enum _RT_PS_MODE { + eActive, /* Active/Continuous access. */ + eMaxPs, /* Max power save mode. */ + eFastPs /* Fast power save mode. */ +} RT_PS_MODE; -typedef enum _IPS_CALLBACK_FUNCION -{ +typedef enum _IPS_CALLBACK_FUNCION { IPS_CALLBACK_NONE = 0, IPS_CALLBACK_MGNT_LINK_REQUEST = 1, IPS_CALLBACK_JOIN_REQUEST = 2, -}IPS_CALLBACK_FUNCION; +} IPS_CALLBACK_FUNCION; -typedef enum _RT_JOIN_ACTION{ +typedef enum _RT_JOIN_ACTION { RT_JOIN_INFRA = 1, RT_JOIN_IBSS = 2, RT_START_IBSS = 3, RT_NO_ACTION = 4, -}RT_JOIN_ACTION; +} RT_JOIN_ACTION; -typedef struct _IbssParms{ +typedef struct _IbssParms { u16 atimWin; -}IbssParms, *PIbssParms; -#define MAX_NUM_RATES 264 // Max num of support rates element: 8, Max num of ext. support rate: 255. 061122, by rcnjko. +} IbssParms, *PIbssParms; +#define MAX_NUM_RATES 264 /* Max num of support rates element: 8, Max num of ext. support rate: 255. 061122, by rcnjko. */ -// RF state. -typedef enum _RT_RF_POWER_STATE -{ +/* RF state. */ +typedef enum _RT_RF_POWER_STATE { eRfOn, eRfSleep, eRfOff -}RT_RF_POWER_STATE; +} RT_RF_POWER_STATE; -typedef struct _RT_POWER_SAVE_CONTROL -{ +typedef struct _RT_POWER_SAVE_CONTROL { - // - // Inactive Power Save(IPS) : Disable RF when disconnected - // + /* Inactive Power Save(IPS) : Disable RF when disconnected */ bool bInactivePs; bool bIPSModeBackup; bool bSwRfProcessing; @@ -1726,15 +1700,15 @@ typedef struct _RT_POWER_SAVE_CONTROL struct work_struct InactivePsWorkItem; struct timer_list InactivePsTimer; - // Return point for join action + /* Return point for join action */ IPS_CALLBACK_FUNCION ReturnPoint; - // Recored Parameters for rescheduled JoinRequest + /* Recored Parameters for rescheduled JoinRequest */ bool bTmpBssDesc; RT_JOIN_ACTION tmpJoinAction; struct ieee80211_network tmpBssDesc; - // Recored Parameters for rescheduled MgntLinkRequest + /* Recored Parameters for rescheduled MgntLinkRequest */ bool bTmpScanOnly; bool bTmpActiveScan; bool bTmpFilterHiddenAP; @@ -1753,23 +1727,20 @@ typedef struct _RT_POWER_SAVE_CONTROL IbssParms tmpIbpm; bool bTmpIbpm; - // - // Leisre Poswer Save : Disable RF if connected but traffic is not busy - // + /* Leisre Poswer Save : Disable RF if connected but traffic is not busy */ bool bLeisurePs; -}RT_POWER_SAVE_CONTROL,*PRT_POWER_SAVE_CONTROL; +} RT_POWER_SAVE_CONTROL, *PRT_POWER_SAVE_CONTROL; typedef u32 RT_RF_CHANGE_SOURCE; #define RF_CHANGE_BY_SW BIT31 #define RF_CHANGE_BY_HW BIT30 #define RF_CHANGE_BY_PS BIT29 #define RF_CHANGE_BY_IPS BIT28 -#define RF_CHANGE_BY_INIT 0 // Do not change the RFOff reason. Defined by Bruce, 2008-01-17. +#define RF_CHANGE_BY_INIT 0 /* Do not change the RFOff reason. */ #ifdef ENABLE_DOT11D -typedef enum -{ +typedef enum { COUNTRY_CODE_FCC = 0, COUNTRY_CODE_IC = 1, COUNTRY_CODE_ETSI = 2, @@ -1781,84 +1752,78 @@ typedef enum COUNTRY_CODE_TELEC, COUNTRY_CODE_MIC, COUNTRY_CODE_GLOBAL_DOMAIN -}country_code_type_t; +} country_code_type_t; #endif #define RT_MAX_LD_SLOT_NUM 10 -typedef struct _RT_LINK_DETECT_T{ +typedef struct _RT_LINK_DETECT_T { u32 NumRecvBcnInPeriod; u32 NumRecvDataInPeriod; - u32 RxBcnNum[RT_MAX_LD_SLOT_NUM]; // number of Rx beacon / CheckForHang_period to determine link status - u32 RxDataNum[RT_MAX_LD_SLOT_NUM]; // number of Rx data / CheckForHang_period to determine link status - u16 SlotNum; // number of CheckForHang period to determine link status + u32 RxBcnNum[RT_MAX_LD_SLOT_NUM]; /* number of Rx beacon / CheckForHang_period to determine link status */ + u32 RxDataNum[RT_MAX_LD_SLOT_NUM]; /* number of Rx data / CheckForHang_period to determine link status */ + u16 SlotNum; /* number of CheckForHang period to determine link status */ u16 SlotIndex; u32 NumTxOkInPeriod; u32 NumRxOkInPeriod; bool bBusyTraffic; -}RT_LINK_DETECT_T, *PRT_LINK_DETECT_T; +} RT_LINK_DETECT_T, *PRT_LINK_DETECT_T; struct ieee80211_device { struct net_device *dev; struct ieee80211_security sec; - //hw security related -// u8 hwsec_support; //support? - u8 hwsec_active; //hw security active. + /* hw security related */ + u8 hwsec_active; /* hw security active. */ bool is_silent_reset; bool ieee_up; - //added by amy bool bSupportRemoteWakeUp; - RT_PS_MODE dot11PowerSaveMode; // Power save mode configured. + RT_PS_MODE dot11PowerSaveMode; /* Power save mode configured. */ bool actscanning; bool beinretry; RT_RF_POWER_STATE eRFPowerState; RT_RF_CHANGE_SOURCE RfOffReason; bool is_set_key; - //11n spec related I wonder if These info structure need to be moved out of ieee80211_device + /* 11n spec related I wonder if These info structure need to be moved out of ieee80211_device */ - //11n HT below + /* 11n HT below */ PRT_HIGH_THROUGHPUT pHTInfo; - //struct timer_list SwBwTimer; -// spinlock_t chnlop_spinlock; spinlock_t bw_spinlock; spinlock_t reorder_spinlock; - // for HT operation rate set. we use this one for HT data rate to seperate different descriptors - //the way fill this is the same as in the IE - u8 Regdot11HTOperationalRateSet[16]; //use RATR format - u8 dot11HTOperationalRateSet[16]; //use RATR format + /* for HT operation rate set. we use this one for HT data rate to + * seperate different descriptors + * the way fill this is the same as in the IE + */ + u8 Regdot11HTOperationalRateSet[16]; /* use RATR format */ + u8 dot11HTOperationalRateSet[16]; /* use RATR format */ u8 RegHTSuppRateSet[16]; u8 HTCurrentOperaRate; u8 HTHighestOperaRate; - //wb added for rate operation mode to firmware + /* wb added for rate operation mode to firmware */ u8 bTxDisableRateFallBack; u8 bTxUseDriverAssingedRate; atomic_t atm_chnlop; atomic_t atm_swbw; -// u8 HTHighestOperaRate; -// u8 HTCurrentOperaRate; - // 802.11e and WMM Traffic Stream Info (TX) + /* 802.11e and WMM Traffic Stream Info (TX) */ struct list_head Tx_TS_Admit_List; struct list_head Tx_TS_Pending_List; struct list_head Tx_TS_Unused_List; TX_TS_RECORD TxTsRecord[TOTAL_TS_NUM]; - // 802.11e and WMM Traffic Stream Info (RX) + /* 802.11e and WMM Traffic Stream Info (RX) */ struct list_head Rx_TS_Admit_List; struct list_head Rx_TS_Pending_List; struct list_head Rx_TS_Unused_List; RX_TS_RECORD RxTsRecord[TOTAL_TS_NUM]; -//#ifdef TO_DO_LIST RX_REORDER_ENTRY RxReorderEntry[128]; struct list_head RxReorder_Unused_List; -//#endif - // Qos related. Added by Annie, 2005-11-01. -// PSTA_QOS pStaQos; - u8 ForcedPriority; // Force per-packet priority 1~7. (default: 0, not to force it.) + /* Qos related. */ +/* PSTA_QOS pStaQos; */ + u8 ForcedPriority; /* Force per-packet priority 1~7. (default: 0, not to force it.) */ /* Bookkeeping structures */ @@ -1925,7 +1890,7 @@ struct ieee80211_device { * with RX of broad/multicast frames */ /* Fragmentation structures */ - // each streaming contain a entry + /* each streaming contain a entry */ struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN]; unsigned int frag_next_idx[17]; u16 fts; /* Fragmentation Threshold */ @@ -1967,16 +1932,16 @@ struct ieee80211_device { u16 prev_seq_ctl; /* used to drop duplicate frames */ /* map of allowed channels. 0 is dummy */ - // FIXME: remeber to default to a basic channel plan depending of the PHY type + /* FIXME: remeber to default to a basic channel plan depending of the PHY type */ #ifdef ENABLE_DOT11D - void* pDot11dInfo; + void *pDot11dInfo; bool bGlobalDomain; #else int channel_map[MAX_CHANNEL_NUMBER+1]; #endif int rate; /* current rate */ int basic_rate; - //FIXME: pleace callback, see if redundant with softmac_features + /* FIXME: pleace callback, see if redundant with softmac_features */ short active_scan; /* this contains flags for selectively enable softmac support */ @@ -2017,8 +1982,8 @@ struct ieee80211_device { short wap_set; short ssid_set; - u8 wpax_type_set; //{added by David, 2006.9.28} - u32 wpax_type_notify; //{added by David, 2006.9.26} + u8 wpax_type_set; + u32 wpax_type_notify; /* QoS related flag */ char init_wmmparam_flag; @@ -2040,7 +2005,7 @@ struct ieee80211_device { struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM]; int mgmt_queue_head; int mgmt_queue_tail; -//{ added for rtl819x +/* added for rtl819x */ #define IEEE80211_QUEUE_LIMIT 128 u8 AsocRetryCount; unsigned int hw_header; @@ -2049,12 +2014,12 @@ struct ieee80211_device { struct sk_buff_head skb_drv_aggQ[MAX_QUEUE_SIZE]; u32 sta_edca_param[4]; bool aggregation; - // Enable/Disable Rx immediate BA capability. + /* Enable/Disable Rx immediate BA capability. */ bool enable_rx_imm_BA; bool bibsscoordinator; - //+by amy for DM ,080515 - //Dynamic Tx power for near/far range enable/Disable , by amy , 2008-05-15 + /*+by amy for DM ,080515 */ + /* Dynamic Tx power for near/far range enable/Disable */ bool bdynamic_txpower_enable; bool bCTSToSelfEnable; @@ -2065,21 +2030,20 @@ struct ieee80211_device { u8 fsync_rssi_threshold; bool bfsync_enable; - u8 fsync_multiple_timeinterval; // FsyncMultipleTimeInterval * FsyncTimeInterval - u32 fsync_firstdiff_ratethreshold; // low threshold - u32 fsync_seconddiff_ratethreshold; // decrease threshold + u8 fsync_multiple_timeinterval; /* FsyncMultipleTimeInterval * FsyncTimeInterval */ + u32 fsync_firstdiff_ratethreshold; /* low threshold */ + u32 fsync_seconddiff_ratethreshold; /* decrease threshold */ Fsync_State fsync_state; bool bis_any_nonbepkts; - //20Mhz 40Mhz AutoSwitch Threshold + /* 20Mhz 40Mhz AutoSwitch Threshold */ bandwidth_autoswitch bandwidth_auto_switch; - //for txpower tracking + /* for txpower tracking */ bool FwRWRF; - //added by amy for AP roaming + /* added by amy for AP roaming */ RT_LINK_DETECT_T LinkDetectInfo; - //added by amy for ps + /* added by amy for ps */ RT_POWER_SAVE_CONTROL PowerSaveControl; -//} /* used if IEEE_SOFTMAC_TX_QUEUE is set */ struct tx_pending_t tx_pending; @@ -2095,11 +2059,8 @@ struct ieee80211_device { struct delayed_work start_ibss_wq; struct work_struct wx_sync_scan_wq; struct workqueue_struct *wq; - // Qos related. Added by Annie, 2005-11-01. - //STA_QOS StaQos; - - //u32 STA_EDCA_PARAM[4]; - //CHANNEL_ACCESS_SETTING ChannelAccessSetting; + /* Qos related. Added by Annie, 2005-11-01. */ + /* STA_QOS StaQos; */ /* Callback functions */ @@ -2114,10 +2075,10 @@ struct ieee80211_device { struct net_device *dev); int (*reset_port)(struct net_device *dev); - int (*is_queue_full) (struct net_device * dev, int pri); + int (*is_queue_full) (struct net_device *dev, int pri); - int (*handle_management) (struct net_device * dev, - struct ieee80211_network * network, u16 type); + int (*handle_management) (struct net_device *dev, + struct ieee80211_network *network, u16 type); int (*is_qos_active) (struct net_device *dev, struct sk_buff *skb); /* Softmac-generated frames (mamagement) are TXed via this @@ -2137,7 +2098,7 @@ struct ieee80211_device { * This function can't sleep. */ void (*softmac_data_hard_start_xmit)(struct sk_buff *skb, - struct net_device *dev,int rate); + struct net_device *dev, int rate); /* stops the HW queue for DATA frames. Useful to avoid * waste time to TX data frame when we are reassociating @@ -2152,7 +2113,7 @@ struct ieee80211_device { * This function can sleep. the driver should ensure * the radio has been swithced before return. */ - void (*set_chan)(struct net_device *dev,short ch); + void (*set_chan)(struct net_device *dev, short ch); /* These are not used if the ieee stack takes care of * scanning (IEEE_SOFTMAC_SCAN feature set). @@ -2186,7 +2147,7 @@ struct ieee80211_device { * stop_send_bacons is NOT guaranteed to be called only * after start_send_beacons. */ - void (*start_send_beacons) (struct net_device *dev,u16 tx_rate); + void (*start_send_beacons) (struct net_device *dev, u16 tx_rate); void (*stop_send_beacons) (struct net_device *dev); /* power save mode related */ @@ -2194,19 +2155,17 @@ struct ieee80211_device { void (*ps_request_tx_ack) (struct net_device *dev); void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl); short (*ps_is_queue_empty) (struct net_device *dev); - int (*handle_beacon) (struct net_device * dev, struct ieee80211_beacon * beacon, struct ieee80211_network * network); - int (*handle_assoc_response) (struct net_device * dev, struct ieee80211_assoc_response_frame * resp, struct ieee80211_network * network); + int (*handle_beacon) (struct net_device *dev, struct ieee80211_beacon *beacon, struct ieee80211_network *network); + int (*handle_assoc_response) (struct net_device *dev, struct ieee80211_assoc_response_frame *resp, struct ieee80211_network *network); /* check whether Tx hw resouce available */ short (*check_nic_enough_desc)(struct net_device *dev, int queue_index); - //added by wb for HT related -// void (*SwChnlByTimerHandler)(struct net_device *dev, int channel); + /* added by wb for HT related */ void (*SetBWModeHandler)(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); -// void (*UpdateHalRATRTableHandler)(struct net_device* dev, u8* pMcsRate); - bool (*GetNmodeSupportBySecCfg)(struct net_device* dev); - void (*SetWirelessMode)(struct net_device* dev, u8 wireless_mode); - bool (*GetHalfNmodeSupportByAPsHandler)(struct net_device* dev); + bool (*GetNmodeSupportBySecCfg)(struct net_device *dev); + void (*SetWirelessMode)(struct net_device *dev, u8 wireless_mode); + bool (*GetHalfNmodeSupportByAPsHandler)(struct net_device *dev); void (*InitialGainHandler)(struct net_device *dev, u8 Operation); /* This must be the last item so that it points to the data @@ -2307,7 +2266,7 @@ extern inline int ieee80211_get_hdrlen(u16 fc) case IEEE80211_FTYPE_DATA: if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS)) hdrlen = IEEE80211_4ADDR_LEN; /* Addr4 */ - if(IEEE80211_QOS_HAS_SEQ(fc)) + if (IEEE80211_QOS_HAS_SEQ(fc)) hdrlen += 2; /* QOS ctrl*/ break; case IEEE80211_FTYPE_CTL: @@ -2408,10 +2367,10 @@ extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee, #if WIRELESS_EXT >= 18 extern int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee, struct iw_request_info *info, - union iwreq_data* wrqu, char *extra); + union iwreq_data *wrqu, char *extra); extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, struct iw_request_info *info, - union iwreq_data* wrqu, char *extra); + union iwreq_data *wrqu, char *extra); extern int ieee80211_wx_set_auth(struct ieee80211_device *ieee, struct iw_request_info *info, struct iw_param *data, char *extra); @@ -2477,7 +2436,9 @@ extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee, union iwreq_data *awrq, char *extra); -extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b); +extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b); extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee, struct iw_request_info *info, @@ -2506,7 +2467,6 @@ extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_reques extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a, union iwreq_data *wrqu, char *b); -//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee); extern void ieee80211_wx_sync_scan_wq(struct work_struct *work); @@ -2533,54 +2493,53 @@ extern int ieee80211_wx_set_rts(struct ieee80211_device *ieee, extern int ieee80211_wx_get_rts(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); -//HT -#define MAX_RECEIVE_BUFFER_SIZE 9100 // -extern void HTDebugHTCapability(u8* CapIE, u8* TitleString ); -extern void HTDebugHTInfo(u8* InfoIE, u8* TitleString); - -void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); -extern void HTUpdateDefaultSetting(struct ieee80211_device* ieee); -extern void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 isEncrypt); -extern void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 isEncrypt); -extern void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len); +/* HT */ +#define MAX_RECEIVE_BUFFER_SIZE 9100 +extern void HTDebugHTCapability(u8 *CapIE, u8 *TitleString); +extern void HTDebugHTInfo(u8 *InfoIE, u8 *TitleString); + +void HTSetConnectBwMode(struct ieee80211_device *ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); +extern void HTUpdateDefaultSetting(struct ieee80211_device *ieee); +extern void HTConstructCapabilityElement(struct ieee80211_device *ieee, u8 *posHTCap, u8 *len, u8 isEncrypt); +extern void HTConstructInfoElement(struct ieee80211_device *ieee, u8 *posHTInfo, u8 *len, u8 isEncrypt); +extern void HTConstructRT2RTAggElement(struct ieee80211_device *ieee, u8 *posRT2RTAgg, u8 *len); extern void HTOnAssocRsp(struct ieee80211_device *ieee); -extern void HTInitializeHTInfo(struct ieee80211_device* ieee); +extern void HTInitializeHTInfo(struct ieee80211_device *ieee); extern void HTInitializeBssDesc(PBSS_HT pBssHT); -extern void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork); -extern void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork); -extern u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter); +extern void HTResetSelfAndSavePeerSetting(struct ieee80211_device *ieee, struct ieee80211_network *pNetwork); +extern void HTUpdateSelfAndPeerSetting(struct ieee80211_device *ieee, struct ieee80211_network *pNetwork); +extern u8 HTGetHighestMCSRate(struct ieee80211_device *ieee, u8 *pMCSRateSet, u8 *pMCSFilter); extern u8 MCS_FILTER_ALL[]; extern u16 MCS_DATA_RATE[2][2][77] ; -extern u8 HTCCheck(struct ieee80211_device* ieee, u8* pFrame); -//extern void HTSetConnectBwModeCallback(unsigned long data); +extern u8 HTCCheck(struct ieee80211_device *ieee, u8 *pFrame); extern void HTResetIOTSetting(PRT_HIGH_THROUGHPUT pHTInfo); -extern bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee); -extern u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee, u8 nMcsRate); -extern u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate); -extern u16 TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate); -//function in BAPROC.c -extern int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb); -extern int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb); -extern int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb); -extern void TsInitAddBA( struct ieee80211_device* ieee, PTX_TS_RECORD pTS, u8 Policy, u8 bOverwritePending); -extern void TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect); +extern bool IsHTHalfNmodeAPs(struct ieee80211_device *ieee); +extern u16 HTHalfMcsToDataRate(struct ieee80211_device *ieee, u8 nMcsRate); +extern u16 HTMcsToDataRate(struct ieee80211_device *ieee, u8 nMcsRate); +extern u16 TxCountToDataRate(struct ieee80211_device *ieee, u8 nDataRate); +/* function in BAPROC.c */ +extern int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee, struct sk_buff *skb); +extern int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee, struct sk_buff *skb); +extern int ieee80211_rx_DELBA(struct ieee80211_device *ieee, struct sk_buff *skb); +extern void TsInitAddBA(struct ieee80211_device *ieee, PTX_TS_RECORD pTS, u8 Policy, u8 bOverwritePending); +extern void TsInitDelBA(struct ieee80211_device *ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect); extern void BaSetupTimeOut(unsigned long data); extern void TxBaInactTimeout(unsigned long data); extern void RxBaInactTimeout(unsigned long data); -extern void ResetBaEntry( PBA_RECORD pBA); -//function in TS.c +extern void ResetBaEntry(PBA_RECORD pBA); +/* function in TS.c */ extern bool GetTs( - struct ieee80211_device* ieee, - PTS_COMMON_INFO *ppTS, - u8* Addr, + struct ieee80211_device *ieee, + PTS_COMMON_INFO *ppTS, + u8 *Addr, u8 TID, - TR_SELECT TxRxSelect, //Rx:1, Tx:0 + TR_SELECT TxRxSelect, /* Rx:1, Tx:0 */ bool bAddNewTs ); extern void TSInitialize(struct ieee80211_device *ieee); -extern void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD pTxTS); -extern void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr); -extern void RemoveAllTS(struct ieee80211_device* ieee); +extern void TsStartAddBaProcess(struct ieee80211_device *ieee, PTX_TS_RECORD pTxTS); +extern void RemovePeerTS(struct ieee80211_device *ieee, u8 *Addr); +extern void RemoveAllTS(struct ieee80211_device *ieee); void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee); extern const long ieee80211_wlan_frequencies[]; @@ -2595,7 +2554,8 @@ extern inline int ieee80211_get_scans(struct ieee80211_device *ieee) return ieee->scans; } -static inline const char *escape_essid(const char *essid, u8 essid_len) { +static inline const char *escape_essid(const char *essid, u8 essid_len) +{ static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; const char *s = essid; char *d = escaped; @@ -2630,6 +2590,6 @@ extern int ieee80211_parse_info_param(struct ieee80211_device *ieee, struct ieee80211_network *network, struct ieee80211_rx_stats *stats); -void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8 index); +void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb **prxbIndicateArray, u8 index); #define RT_ASOC_RETRY_LIMIT 5 #endif /* IEEE80211_H */ -- cgit v1.2.3 From 3dc1536b217182b6aeaca815d26cf0dfb71fb80c Mon Sep 17 00:00:00 2001 From: Ruslan Pisarev Date: Sun, 11 Apr 2010 15:05:51 +0300 Subject: Staging: rtl8192u: fix space coding style issue in ieee80211_crypt.h This is a patch to the ieee80211_crypt.h file that fixed up a space Errors found by the checkpatch.pl tools Signed-off-by: Ruslan Pisarev Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211_crypt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192u/ieee80211_crypt.h b/drivers/staging/rtl8192u/ieee80211_crypt.h index b58a3bcc0dc0..0b4ea431982d 100644 --- a/drivers/staging/rtl8192u/ieee80211_crypt.h +++ b/drivers/staging/rtl8192u/ieee80211_crypt.h @@ -77,7 +77,7 @@ struct ieee80211_crypt_data { int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops); int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops); -struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name); +struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name); void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int); void ieee80211_crypt_deinit_handler(unsigned long); void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, -- cgit v1.2.3 From bd2de3585e919cbee635f4cc317b8cca864daf24 Mon Sep 17 00:00:00 2001 From: Andres More Date: Sun, 11 Apr 2010 15:59:01 -0300 Subject: staging: vt6656: cleared checkpatch.pl findings in 80211hdr.h Code cleanup in: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git Findings were: do not use C99 // comments space required after that close brace '}' line over 80 characters Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/80211hdr.h | 83 ++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/80211hdr.h b/drivers/staging/vt6656/80211hdr.h index e5cee6fd0533..15c6ef1a635c 100644 --- a/drivers/staging/vt6656/80211hdr.h +++ b/drivers/staging/vt6656/80211hdr.h @@ -16,16 +16,13 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * * File: 80211hdr.h * * Purpose: 802.11 MAC headers related pre-defines and macros. * - * * Author: Lyndon Chen * * Date: Apr 8, 2002 - * */ #ifndef __80211HDR_H__ @@ -34,7 +31,8 @@ #include "ttype.h" /*--------------------- Export Definitions -------------------------*/ -// bit type + +/* bit type */ #define BIT0 0x00000001 #define BIT1 0x00000002 #define BIT2 0x00000004 @@ -68,7 +66,7 @@ #define BIT30 0x40000000 #define BIT31 0x80000000 -// 802.11 frame related, defined as 802.11 spec +/* 802.11 frame related, defined as 802.11 spec */ #define WLAN_ADDR_LEN 6 #define WLAN_CRC_LEN 4 #define WLAN_CRC32_LEN 4 @@ -80,13 +78,14 @@ #define WLAN_HDR_ADDR4_LEN 30 #define WLAN_IEHDR_LEN 2 #define WLAN_SSID_MAXLEN 32 -//#define WLAN_RATES_MAXLEN 255 +/* #define WLAN_RATES_MAXLEN 255 */ #define WLAN_RATES_MAXLEN 16 #define WLAN_RATES_MAXLEN_11B 4 #define WLAN_RSN_MAXLEN 32 #define WLAN_DATA_MAXLEN 2312 -#define WLAN_A3FR_MAXLEN (WLAN_HDR_ADDR3_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) - +#define WLAN_A3FR_MAXLEN (WLAN_HDR_ADDR3_LEN \ + + WLAN_DATA_MAXLEN \ + + WLAN_CRC_LEN) #define WLAN_BEACON_FR_MAXLEN WLAN_A3FR_MAXLEN #define WLAN_ATIM_FR_MAXLEN (WLAN_HDR_ADDR3_LEN + 0) @@ -101,12 +100,11 @@ #define WLAN_AUTHEN_FR_MAXLEN WLAN_A3FR_MAXLEN #define WLAN_DEAUTHEN_FR_MAXLEN (WLAN_HDR_ADDR3_LEN + 2) - #define WLAN_WEP_NKEYS 4 #define WLAN_WEP40_KEYLEN 5 #define WLAN_WEP104_KEYLEN 13 #define WLAN_WEP232_KEYLEN 29 -//#define WLAN_WEPMAX_KEYLEN 29 +/* #define WLAN_WEPMAX_KEYLEN 29 */ #define WLAN_WEPMAX_KEYLEN 32 #define WLAN_CHALLENGE_IE_MAXLEN 255 #define WLAN_CHALLENGE_IE_LEN 130 @@ -115,7 +113,7 @@ #define WLAN_WEP_ICV_LEN 4 #define WLAN_FRAGS_MAX 16 -// Frame Type +/* Frame Type */ #define WLAN_TYPE_MGR 0x00 #define WLAN_TYPE_CTL 0x01 #define WLAN_TYPE_DATA 0x02 @@ -124,8 +122,7 @@ #define WLAN_FTYPE_CTL 0x01 #define WLAN_FTYPE_DATA 0x02 - -// Frame Subtypes +/* Frame Subtypes */ #define WLAN_FSTYPE_ASSOCREQ 0x00 #define WLAN_FSTYPE_ASSOCRESP 0x01 #define WLAN_FSTYPE_REASSOCREQ 0x02 @@ -139,7 +136,7 @@ #define WLAN_FSTYPE_DEAUTHEN 0x0c #define WLAN_FSTYPE_ACTION 0x0d -// Control +/* Control */ #define WLAN_FSTYPE_PSPOLL 0x0a #define WLAN_FSTYPE_RTS 0x0b #define WLAN_FSTYPE_CTS 0x0c @@ -147,7 +144,7 @@ #define WLAN_FSTYPE_CFEND 0x0e #define WLAN_FSTYPE_CFENDCFACK 0x0f -// Data +/* Data */ #define WLAN_FSTYPE_DATAONLY 0x00 #define WLAN_FSTYPE_DATA_CFACK 0x01 #define WLAN_FSTYPE_DATA_CFPOLL 0x02 @@ -157,13 +154,13 @@ #define WLAN_FSTYPE_CFPOLL 0x06 #define WLAN_FSTYPE_CFACK_CFPOLL 0x07 - #ifdef __BIG_ENDIAN -// GET & SET Frame Control bit +/* GET & SET Frame Control bit */ #define WLAN_GET_FC_PRVER(n) ((((WORD)(n) >> 8) & (BIT0 | BIT1)) #define WLAN_GET_FC_FTYPE(n) ((((WORD)(n) >> 8) & (BIT2 | BIT3)) >> 2) -#define WLAN_GET_FC_FSTYPE(n) ((((WORD)(n) >> 8) & (BIT4|BIT5|BIT6|BIT7)) >> 4) +#define WLAN_GET_FC_FSTYPE(n) ((((WORD)(n) >> 8) \ + & (BIT4|BIT5|BIT6|BIT7)) >> 4) #define WLAN_GET_FC_TODS(n) ((((WORD)(n) << 8) & (BIT8)) >> 8) #define WLAN_GET_FC_FROMDS(n) ((((WORD)(n) << 8) & (BIT9)) >> 9) #define WLAN_GET_FC_MOREFRAG(n) ((((WORD)(n) << 8) & (BIT10)) >> 10) @@ -173,12 +170,12 @@ #define WLAN_GET_FC_ISWEP(n) ((((WORD)(n) << 8) & (BIT14)) >> 14) #define WLAN_GET_FC_ORDER(n) ((((WORD)(n) << 8) & (BIT15)) >> 15) -// Sequence Field bit +/* Sequence Field bit */ #define WLAN_GET_SEQ_FRGNUM(n) (((WORD)(n) >> 8) & (BIT0|BIT1|BIT2|BIT3)) -#define WLAN_GET_SEQ_SEQNUM(n) ((((WORD)(n) >> 8) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4) - +#define WLAN_GET_SEQ_SEQNUM(n) ((((WORD)(n) >> 8) \ + & (~(BIT0|BIT1|BIT2|BIT3))) >> 4) -// Capability Field bit +/* Capability Field bit */ #define WLAN_GET_CAP_INFO_ESS(n) (((n) >> 8) & BIT0) #define WLAN_GET_CAP_INFO_IBSS(n) ((((n) >> 8) & BIT1) >> 1) #define WLAN_GET_CAP_INFO_CFPOLLABLE(n) ((((n) >> 8) & BIT2) >> 2) @@ -192,10 +189,9 @@ #define WLAN_GET_CAP_INFO_DSSSOFDM(n) ((((n)) & BIT13) >> 13) #define WLAN_GET_CAP_INFO_GRPACK(n) ((((n)) & BIT14) >> 14) - #else -// GET & SET Frame Control bit +/* GET & SET Frame Control bit */ #define WLAN_GET_FC_PRVER(n) (((WORD)(n)) & (BIT0 | BIT1)) #define WLAN_GET_FC_FTYPE(n) ((((WORD)(n)) & (BIT2 | BIT3)) >> 2) #define WLAN_GET_FC_FSTYPE(n) ((((WORD)(n)) & (BIT4|BIT5|BIT6|BIT7)) >> 4) @@ -208,13 +204,11 @@ #define WLAN_GET_FC_ISWEP(n) ((((WORD)(n)) & (BIT14)) >> 14) #define WLAN_GET_FC_ORDER(n) ((((WORD)(n)) & (BIT15)) >> 15) - -// Sequence Field bit +/* Sequence Field bit */ #define WLAN_GET_SEQ_FRGNUM(n) (((WORD)(n)) & (BIT0|BIT1|BIT2|BIT3)) #define WLAN_GET_SEQ_SEQNUM(n) ((((WORD)(n)) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4) - -// Capability Field bit +/* Capability Field bit */ #define WLAN_GET_CAP_INFO_ESS(n) ((n) & BIT0) #define WLAN_GET_CAP_INFO_IBSS(n) (((n) & BIT1) >> 1) #define WLAN_GET_CAP_INFO_CFPOLLABLE(n) (((n) & BIT2) >> 2) @@ -228,9 +222,7 @@ #define WLAN_GET_CAP_INFO_DSSSOFDM(n) (((n) & BIT13) >> 13) #define WLAN_GET_CAP_INFO_GRPACK(n) (((n) & BIT14) >> 14) - -#endif //#ifdef __BIG_ENDIAN - +#endif /* #ifdef __BIG_ENDIAN */ #define WLAN_SET_CAP_INFO_ESS(n) (n) #define WLAN_SET_CAP_INFO_IBSS(n) ((n) << 1) @@ -245,7 +237,6 @@ #define WLAN_SET_CAP_INFO_DSSSOFDM(n) ((n) << 13) #define WLAN_SET_CAP_INFO_GRPACK(n) ((n) << 14) - #define WLAN_SET_FC_PRVER(n) ((WORD)(n)) #define WLAN_SET_FC_FTYPE(n) (((WORD)(n)) << 2) #define WLAN_SET_FC_FSTYPE(n) (((WORD)(n)) << 4) @@ -261,7 +252,7 @@ #define WLAN_SET_SEQ_FRGNUM(n) ((WORD)(n)) #define WLAN_SET_SEQ_SEQNUM(n) (((WORD)(n)) << 4) -// ERP Field bit +/* ERP Field bit */ #define WLAN_GET_ERP_NONERP_PRESENT(n) ((n) & BIT0) #define WLAN_GET_ERP_USE_PROTECTION(n) (((n) & BIT1) >> 1) @@ -271,21 +262,19 @@ #define WLAN_SET_ERP_USE_PROTECTION(n) ((n) << 1) #define WLAN_SET_ERP_BARKER_MODE(n) ((n) << 2) - - -// Support & Basic Rates field +/* Support & Basic Rates field */ #define WLAN_MGMT_IS_BASICRATE(b) ((b) & BIT7) #define WLAN_MGMT_GET_RATE(b) ((b) & ~BIT7) -// TIM field +/* TIM field */ #define WLAN_MGMT_IS_MULTICAST_TIM(b) ((b) & BIT0) #define WLAN_MGMT_GET_TIM_OFFSET(b) (((b) & ~BIT0) >> 1) -// 3-Addr & 4-Addr +/* 3-Addr & 4-Addr */ #define WLAN_HDR_A3_DATA_PTR(p) (((PBYTE)(p)) + WLAN_HDR_ADDR3_LEN) #define WLAN_HDR_A4_DATA_PTR(p) (((PBYTE)(p)) + WLAN_HDR_ADDR4_LEN) -// IEEE ADDR +/* IEEE ADDR */ #define IEEE_ADDR_UNIVERSAL 0x02 #define IEEE_ADDR_GROUP 0x01 @@ -293,7 +282,7 @@ typedef struct { BYTE abyAddr[6]; } IEEE_ADDR, *PIEEE_ADDR; -// 802.11 Header Format +/* 802.11 Header Format */ typedef struct tagWLAN_80211HDR_A2 { @@ -302,7 +291,7 @@ typedef struct tagWLAN_80211HDR_A2 { BYTE abyAddr1[WLAN_ADDR_LEN]; BYTE abyAddr2[WLAN_ADDR_LEN]; -}__attribute__ ((__packed__)) +} __attribute__ ((__packed__)) WLAN_80211HDR_A2, *PWLAN_80211HDR_A2; typedef struct tagWLAN_80211HDR_A3 { @@ -314,7 +303,7 @@ typedef struct tagWLAN_80211HDR_A3 { BYTE abyAddr3[WLAN_ADDR_LEN]; WORD wSeqCtl; -}__attribute__ ((__packed__)) +} __attribute__ ((__packed__)) WLAN_80211HDR_A3, *PWLAN_80211HDR_A3; typedef struct tagWLAN_80211HDR_A4 { @@ -327,10 +316,9 @@ typedef struct tagWLAN_80211HDR_A4 { WORD wSeqCtl; BYTE abyAddr4[WLAN_ADDR_LEN]; -}__attribute__ ((__packed__)) +} __attribute__ ((__packed__)) WLAN_80211HDR_A4, *PWLAN_80211HDR_A4; - typedef union tagUWLAN_80211HDR { WLAN_80211HDR_A2 sA2; @@ -339,15 +327,10 @@ typedef union tagUWLAN_80211HDR { } UWLAN_80211HDR, *PUWLAN_80211HDR; - /*--------------------- Export Classes ----------------------------*/ /*--------------------- Export Variables --------------------------*/ /*--------------------- Export Functions --------------------------*/ - - -#endif // __80211HDR_H__ - - +#endif /* __80211HDR_H__ */ -- cgit v1.2.3 From fb2a8c88bf87b47169218f15ab21f1c089f7fe17 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Sun, 11 Apr 2010 22:27:13 -0700 Subject: Staging: rt2870: Allow building on ARM Signed-off-by: Howard Chu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2870/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/rt2870/Kconfig b/drivers/staging/rt2870/Kconfig index 6ea172b433e9..e988680b5be4 100644 --- a/drivers/staging/rt2870/Kconfig +++ b/drivers/staging/rt2870/Kconfig @@ -1,6 +1,6 @@ config RT2870 tristate "Ralink 2870/3070 wireless support" - depends on USB && X86 && WLAN + depends on USB && (X86 || ARM) && WLAN select WIRELESS_EXT select WEXT_PRIV select CRC_CCITT -- cgit v1.2.3 From 53618cc1e51e1f406a467eca9d1dd2675f3ad88e Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Thu, 8 Apr 2010 13:16:53 -0500 Subject: Staging: sources for ST core Texas Instruments BT, FM and GPS combo chips/drivers make use of a single TTY to communicate with the chip. This module constitutes the core logic, TTY ldisc driver and the exported symbols for registering/unregistering of the protocol drivers such as BT/FM/GPS. Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ti-st/st_core.c | 1062 +++++++++++++++++++++++++++++++++++++++ drivers/staging/ti-st/st_core.h | 98 ++++ 2 files changed, 1160 insertions(+) create mode 100644 drivers/staging/ti-st/st_core.c create mode 100644 drivers/staging/ti-st/st_core.h (limited to 'drivers') diff --git a/drivers/staging/ti-st/st_core.c b/drivers/staging/ti-st/st_core.c new file mode 100644 index 000000000000..4e93694e1c21 --- /dev/null +++ b/drivers/staging/ti-st/st_core.c @@ -0,0 +1,1062 @@ +/* + * Shared Transport Line discipline driver Core + * This hooks up ST KIM driver and ST LL driver + * Copyright (C) 2009 Texas Instruments + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define pr_fmt(fmt) "(stc): " fmt +#include +#include +#include +#include + +/* understand BT, FM and GPS for now */ +#include +#include +#include +#include "fm.h" +/* + * packet formats for fm and gps + * #include "gps.h" + */ +#include "st_core.h" +#include "st_kim.h" +#include "st_ll.h" +#include "st.h" + +#ifdef DEBUG +/* strings to be used for rfkill entries and by + * ST Core to be used for sysfs debug entry + */ +#define PROTO_ENTRY(type, name) name +const unsigned char *protocol_strngs[] = { + PROTO_ENTRY(ST_BT, "Bluetooth"), + PROTO_ENTRY(ST_FM, "FM"), + PROTO_ENTRY(ST_GPS, "GPS"), +}; +#endif +/* function pointer pointing to either, + * st_kim_recv during registration to receive fw download responses + * st_int_recv after registration to receive proto stack responses + */ +void (*st_recv) (void*, const unsigned char*, long); + +/********************************************************************/ +#if 0 +/* internal misc functions */ +bool is_protocol_list_empty(void) +{ + unsigned char i = 0; + pr_info(" %s ", __func__); + for (i = 0; i < ST_MAX; i++) { + if (st_gdata->list[i] != NULL) + return ST_NOTEMPTY; + /* not empty */ + } + /* list empty */ + return ST_EMPTY; +} +#endif +/* can be called in from + * -- KIM (during fw download) + * -- ST Core (during st_write) + * + * This is the internal write function - a wrapper + * to tty->ops->write + */ +int st_int_write(struct st_data_s *st_gdata, + const unsigned char *data, int count) +{ +#ifdef VERBOSE /* for debug */ + int i; +#endif + struct tty_struct *tty; + if (unlikely(st_gdata == NULL || st_gdata->tty == NULL)) { + pr_err("tty unavailable to perform write"); + return ST_ERR_FAILURE; + } + tty = st_gdata->tty; +#ifdef VERBOSE + printk(KERN_ERR "start data..\n"); + for (i = 0; i < count; i++) /* no newlines for each datum */ + printk(" %x", data[i]); + printk(KERN_ERR "\n ..end data\n"); +#endif + return tty->ops->write(tty, data, count); + +} + +/* + * push the skb received to relevant + * protocol stacks + */ +void st_send_frame(enum proto_type protoid, struct st_data_s *st_gdata) +{ + pr_info(" %s(prot:%d) ", __func__, protoid); + + if (unlikely + (st_gdata == NULL || st_gdata->rx_skb == NULL + || st_gdata->list[protoid] == NULL)) { + pr_err("protocol %d not registered, no data to send?", + protoid); + kfree_skb(st_gdata->rx_skb); + return; + } + /* this cannot fail + * this shouldn't take long + * - should be just skb_queue_tail for the + * protocol stack driver + */ + if (likely(st_gdata->list[protoid]->recv != NULL)) { + if (unlikely(st_gdata->list[protoid]->recv(st_gdata->rx_skb) + != ST_SUCCESS)) { + pr_err(" proto stack %d's ->recv failed", protoid); + kfree_skb(st_gdata->rx_skb); + return; + } + } else { + pr_err(" proto stack %d's ->recv null", protoid); + kfree_skb(st_gdata->rx_skb); + } + pr_info(" done %s", __func__); + return; +} + +/* + * to call registration complete callbacks + * of all protocol stack drivers + */ +void st_reg_complete(struct st_data_s *st_gdata, char err) +{ + unsigned char i = 0; + pr_info(" %s ", __func__); + for (i = 0; i < ST_MAX; i++) { + if (likely(st_gdata != NULL && st_gdata->list[i] != NULL && + st_gdata->list[i]->reg_complete_cb != NULL)) + st_gdata->list[i]->reg_complete_cb(err); + } +} + +static inline int st_check_data_len(struct st_data_s *st_gdata, + int protoid, int len) +{ + register int room = skb_tailroom(st_gdata->rx_skb); + + pr_info("len %d room %d", len, room); + + if (!len) { + /* Received packet has only packet header and + * has zero length payload. So, ask ST CORE to + * forward the packet to protocol driver (BT/FM/GPS) + */ + st_send_frame(protoid, st_gdata); + + } else if (len > room) { + /* Received packet's payload length is larger. + * We can't accommodate it in created skb. + */ + pr_err("Data length is too large len %d room %d", len, + room); + kfree_skb(st_gdata->rx_skb); + } else { + /* Packet header has non-zero payload length and + * we have enough space in created skb. Lets read + * payload data */ + st_gdata->rx_state = ST_BT_W4_DATA; + st_gdata->rx_count = len; + return len; + } + + /* Change ST state to continue to process next + * packet */ + st_gdata->rx_state = ST_W4_PACKET_TYPE; + st_gdata->rx_skb = NULL; + st_gdata->rx_count = 0; + + return 0; +} + +/* internal function for action when wake-up ack + * received + */ +static inline void st_wakeup_ack(struct st_data_s *st_gdata, + unsigned char cmd) +{ + register struct sk_buff *waiting_skb; + unsigned long flags = 0; + + spin_lock_irqsave(&st_gdata->lock, flags); + /* de-Q from waitQ and Q in txQ now that the + * chip is awake + */ + while ((waiting_skb = skb_dequeue(&st_gdata->tx_waitq))) + skb_queue_tail(&st_gdata->txq, waiting_skb); + + /* state forwarded to ST LL */ + st_ll_sleep_state(st_gdata, (unsigned long)cmd); + spin_unlock_irqrestore(&st_gdata->lock, flags); + + /* wake up to send the recently copied skbs from waitQ */ + st_tx_wakeup(st_gdata); +} + +/* Decodes received RAW data and forwards to corresponding + * client drivers (Bluetooth,FM,GPS..etc). + * + */ +void st_int_recv(void *disc_data, + const unsigned char *data, long count) +{ + register char *ptr; + struct hci_event_hdr *eh; + struct hci_acl_hdr *ah; + struct hci_sco_hdr *sh; + struct fm_event_hdr *fm; + struct gps_event_hdr *gps; + register int len = 0, type = 0, dlen = 0; + static enum proto_type protoid = ST_MAX; + struct st_data_s *st_gdata = (struct st_data_s *)disc_data; + + ptr = (char *)data; + /* tty_receive sent null ? */ + if (unlikely(ptr == NULL) || (st_gdata == NULL)) { + pr_err(" received null from TTY "); + return; + } + + pr_info("count %ld rx_state %ld" + "rx_count %ld", count, st_gdata->rx_state, + st_gdata->rx_count); + + /* Decode received bytes here */ + while (count) { + if (st_gdata->rx_count) { + len = min_t(unsigned int, st_gdata->rx_count, count); + memcpy(skb_put(st_gdata->rx_skb, len), ptr, len); + st_gdata->rx_count -= len; + count -= len; + ptr += len; + + if (st_gdata->rx_count) + continue; + + /* Check ST RX state machine , where are we? */ + switch (st_gdata->rx_state) { + + /* Waiting for complete packet ? */ + case ST_BT_W4_DATA: + pr_info("Complete pkt received"); + + /* Ask ST CORE to forward + * the packet to protocol driver */ + st_send_frame(protoid, st_gdata); + + st_gdata->rx_state = ST_W4_PACKET_TYPE; + st_gdata->rx_skb = NULL; + protoid = ST_MAX; /* is this required ? */ + continue; + + /* Waiting for Bluetooth event header ? */ + case ST_BT_W4_EVENT_HDR: + eh = (struct hci_event_hdr *)st_gdata->rx_skb-> + data; + + pr_info("Event header: evt 0x%2.2x" + "plen %d", eh->evt, eh->plen); + + st_check_data_len(st_gdata, protoid, eh->plen); + continue; + + /* Waiting for Bluetooth acl header ? */ + case ST_BT_W4_ACL_HDR: + ah = (struct hci_acl_hdr *)st_gdata->rx_skb-> + data; + dlen = __le16_to_cpu(ah->dlen); + + pr_info("ACL header: dlen %d", dlen); + + st_check_data_len(st_gdata, protoid, dlen); + continue; + + /* Waiting for Bluetooth sco header ? */ + case ST_BT_W4_SCO_HDR: + sh = (struct hci_sco_hdr *)st_gdata->rx_skb-> + data; + + pr_info("SCO header: dlen %d", sh->dlen); + + st_check_data_len(st_gdata, protoid, sh->dlen); + continue; + case ST_FM_W4_EVENT_HDR: + fm = (struct fm_event_hdr *)st_gdata->rx_skb-> + data; + pr_info("FM Header: "); + st_check_data_len(st_gdata, ST_FM, fm->plen); + continue; + /* TODO : Add GPS packet machine logic here */ + case ST_GPS_W4_EVENT_HDR: + /* [0x09 pkt hdr][R/W byte][2 byte len] */ + gps = (struct gps_event_hdr *)st_gdata->rx_skb-> + data; + pr_info("GPS Header: "); + st_check_data_len(st_gdata, ST_GPS, gps->plen); + continue; + } /* end of switch rx_state */ + } + + /* end of if rx_count */ + /* Check first byte of packet and identify module + * owner (BT/FM/GPS) */ + switch (*ptr) { + + /* Bluetooth event packet? */ + case HCI_EVENT_PKT: + pr_info("Event packet"); + st_gdata->rx_state = ST_BT_W4_EVENT_HDR; + st_gdata->rx_count = HCI_EVENT_HDR_SIZE; + type = HCI_EVENT_PKT; + protoid = ST_BT; + break; + + /* Bluetooth acl packet? */ + case HCI_ACLDATA_PKT: + pr_info("ACL packet"); + st_gdata->rx_state = ST_BT_W4_ACL_HDR; + st_gdata->rx_count = HCI_ACL_HDR_SIZE; + type = HCI_ACLDATA_PKT; + protoid = ST_BT; + break; + + /* Bluetooth sco packet? */ + case HCI_SCODATA_PKT: + pr_info("SCO packet"); + st_gdata->rx_state = ST_BT_W4_SCO_HDR; + st_gdata->rx_count = HCI_SCO_HDR_SIZE; + type = HCI_SCODATA_PKT; + protoid = ST_BT; + break; + + /* Channel 8(FM) packet? */ + case ST_FM_CH8_PKT: + pr_info("FM CH8 packet"); + type = ST_FM_CH8_PKT; + st_gdata->rx_state = ST_FM_W4_EVENT_HDR; + st_gdata->rx_count = FM_EVENT_HDR_SIZE; + protoid = ST_FM; + break; + + /* Channel 9(GPS) packet? */ + case 0x9: /*ST_LL_GPS_CH9_PKT */ + pr_info("GPS CH9 packet"); + type = 0x9; /* ST_LL_GPS_CH9_PKT; */ + protoid = ST_GPS; + st_gdata->rx_state = ST_GPS_W4_EVENT_HDR; + st_gdata->rx_count = 3; /* GPS_EVENT_HDR_SIZE -1*/ + break; + case LL_SLEEP_IND: + case LL_SLEEP_ACK: + case LL_WAKE_UP_IND: + pr_info("PM packet"); + /* this takes appropriate action based on + * sleep state received -- + */ + st_ll_sleep_state(st_gdata, *ptr); + ptr++; + count--; + continue; + case LL_WAKE_UP_ACK: + pr_info("PM packet"); + /* wake up ack received */ + st_wakeup_ack(st_gdata, *ptr); + ptr++; + count--; + continue; + /* Unknow packet? */ + default: + pr_err("Unknown packet type %2.2x", (__u8) *ptr); + ptr++; + count--; + continue; + }; + ptr++; + count--; + + switch (protoid) { + case ST_BT: + /* Allocate new packet to hold received data */ + st_gdata->rx_skb = + bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC); + if (!st_gdata->rx_skb) { + pr_err("Can't allocate mem for new packet"); + st_gdata->rx_state = ST_W4_PACKET_TYPE; + st_gdata->rx_count = 0; + return; + } + bt_cb(st_gdata->rx_skb)->pkt_type = type; + break; + case ST_FM: /* for FM */ + st_gdata->rx_skb = + alloc_skb(FM_MAX_FRAME_SIZE, GFP_ATOMIC); + if (!st_gdata->rx_skb) { + pr_err("Can't allocate mem for new packet"); + st_gdata->rx_state = ST_W4_PACKET_TYPE; + st_gdata->rx_count = 0; + return; + } + /* place holder 0x08 */ + skb_reserve(st_gdata->rx_skb, 1); + st_gdata->rx_skb->cb[0] = ST_FM_CH8_PKT; + break; + case ST_GPS: + /* for GPS */ + st_gdata->rx_skb = + alloc_skb(100 /*GPS_MAX_FRAME_SIZE */ , GFP_ATOMIC); + if (!st_gdata->rx_skb) { + pr_err("Can't allocate mem for new packet"); + st_gdata->rx_state = ST_W4_PACKET_TYPE; + st_gdata->rx_count = 0; + return; + } + /* place holder 0x09 */ + skb_reserve(st_gdata->rx_skb, 1); + st_gdata->rx_skb->cb[0] = 0x09; /*ST_GPS_CH9_PKT; */ + break; + case ST_MAX: + break; + } + } + pr_info("done %s", __func__); + return; +} + +/* internal de-Q function + * -- return previous in-completely written skb + * or return the skb in the txQ + */ +struct sk_buff *st_int_dequeue(struct st_data_s *st_gdata) +{ + struct sk_buff *returning_skb; + + pr_info("%s", __func__); + /* if the previous skb wasn't written completely + */ + if (st_gdata->tx_skb != NULL) { + returning_skb = st_gdata->tx_skb; + st_gdata->tx_skb = NULL; + return returning_skb; + } + + /* de-Q from the txQ always if previous write is complete */ + return skb_dequeue(&st_gdata->txq); +} + +/* internal Q-ing function + * will either Q the skb to txq or the tx_waitq + * depending on the ST LL state + * + * lock the whole func - since ll_getstate and Q-ing should happen + * in one-shot + */ +void st_int_enqueue(struct st_data_s *st_gdata, struct sk_buff *skb) +{ + unsigned long flags = 0; + + pr_info("%s", __func__); + /* this function can be invoked in more then one context. + * so have a lock */ + spin_lock_irqsave(&st_gdata->lock, flags); + + switch (st_ll_getstate(st_gdata)) { + case ST_LL_AWAKE: + pr_info("ST LL is AWAKE, sending normally"); + skb_queue_tail(&st_gdata->txq, skb); + break; + case ST_LL_ASLEEP_TO_AWAKE: + skb_queue_tail(&st_gdata->tx_waitq, skb); + break; + case ST_LL_AWAKE_TO_ASLEEP: /* host cannot be in this state */ + pr_err("ST LL is illegal state(%ld)," + "purging received skb.", st_ll_getstate(st_gdata)); + kfree_skb(skb); + break; + + case ST_LL_ASLEEP: + /* call a function of ST LL to put data + * in tx_waitQ and wake_ind in txQ + */ + skb_queue_tail(&st_gdata->tx_waitq, skb); + st_ll_wakeup(st_gdata); + break; + default: + pr_err("ST LL is illegal state(%ld)," + "purging received skb.", st_ll_getstate(st_gdata)); + kfree_skb(skb); + break; + } + spin_unlock_irqrestore(&st_gdata->lock, flags); + pr_info("done %s", __func__); + return; +} + +/* + * internal wakeup function + * called from either + * - TTY layer when write's finished + * - st_write (in context of the protocol stack) + */ +void st_tx_wakeup(struct st_data_s *st_data) +{ + struct sk_buff *skb; + unsigned long flags; /* for irq save flags */ + pr_info("%s", __func__); + /* check for sending & set flag sending here */ + if (test_and_set_bit(ST_TX_SENDING, &st_data->tx_state)) { + pr_info("ST already sending"); + /* keep sending */ + set_bit(ST_TX_WAKEUP, &st_data->tx_state); + return; + /* TX_WAKEUP will be checked in another + * context + */ + } + do { /* come back if st_tx_wakeup is set */ + /* woke-up to write */ + clear_bit(ST_TX_WAKEUP, &st_data->tx_state); + while ((skb = st_int_dequeue(st_data))) { + int len; + spin_lock_irqsave(&st_data->lock, flags); + /* enable wake-up from TTY */ + set_bit(TTY_DO_WRITE_WAKEUP, &st_data->tty->flags); + len = st_int_write(st_data, skb->data, skb->len); + skb_pull(skb, len); + /* if skb->len = len as expected, skb->len=0 */ + if (skb->len) { + /* would be the next skb to be sent */ + st_data->tx_skb = skb; + spin_unlock_irqrestore(&st_data->lock, flags); + break; + } + kfree_skb(skb); + spin_unlock_irqrestore(&st_data->lock, flags); + } + /* if wake-up is set in another context- restart sending */ + } while (test_bit(ST_TX_WAKEUP, &st_data->tx_state)); + + /* clear flag sending */ + clear_bit(ST_TX_SENDING, &st_data->tx_state); +} + +/********************************************************************/ +/* functions called from ST KIM +*/ +void kim_st_list_protocols(struct st_data_s *st_gdata, char *buf) +{ + unsigned long flags = 0; +#ifdef DEBUG + unsigned char i = ST_MAX; +#endif + spin_lock_irqsave(&st_gdata->lock, flags); +#ifdef DEBUG /* more detailed log */ + for (i = 0; i < ST_MAX; i++) { + if (i == 0) { + sprintf(buf, "%s is %s", protocol_strngs[i], + st_gdata->list[i] != + NULL ? "Registered" : "Unregistered"); + } else { + sprintf(buf, "%s\n%s is %s", buf, protocol_strngs[i], + st_gdata->list[i] != + NULL ? "Registered" : "Unregistered"); + } + } + sprintf(buf, "%s\n", buf); +#else /* limited info */ + sprintf(buf, "BT=%c\nFM=%c\nGPS=%c\n", + st_gdata->list[ST_BT] != NULL ? 'R' : 'U', + st_gdata->list[ST_FM] != NULL ? 'R' : 'U', + st_gdata->list[ST_GPS] != NULL ? 'R' : 'U'); +#endif + spin_unlock_irqrestore(&st_gdata->lock, flags); +} + +/********************************************************************/ +/* + * functions called from protocol stack drivers + * to be EXPORT-ed + */ +long st_register(struct st_proto_s *new_proto) +{ + struct st_data_s *st_gdata; + long err = ST_SUCCESS; + unsigned long flags = 0; + + st_kim_ref(&st_gdata); + pr_info("%s(%d) ", __func__, new_proto->type); + if (st_gdata == NULL || new_proto == NULL || new_proto->recv == NULL + || new_proto->reg_complete_cb == NULL) { + pr_err("gdata/new_proto/recv or reg_complete_cb not ready"); + return ST_ERR_FAILURE; + } + + if (new_proto->type < ST_BT || new_proto->type >= ST_MAX) { + pr_err("protocol %d not supported", new_proto->type); + return ST_ERR_NOPROTO; + } + + if (st_gdata->list[new_proto->type] != NULL) { + pr_err("protocol %d already registered", new_proto->type); + return ST_ERR_ALREADY; + } + + /* can be from process context only */ + spin_lock_irqsave(&st_gdata->lock, flags); + + if (test_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state)) { + pr_info(" ST_REG_IN_PROGRESS:%d ", new_proto->type); + /* fw download in progress */ + st_kim_chip_toggle(new_proto->type, KIM_GPIO_ACTIVE); + + st_gdata->list[new_proto->type] = new_proto; + new_proto->write = st_write; + + set_bit(ST_REG_PENDING, &st_gdata->st_state); + spin_unlock_irqrestore(&st_gdata->lock, flags); + return ST_ERR_PENDING; + } else if (st_gdata->protos_registered == ST_EMPTY) { + pr_info(" protocol list empty :%d ", new_proto->type); + set_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); + st_recv = st_kim_recv; + + /* release lock previously held - re-locked below */ + spin_unlock_irqrestore(&st_gdata->lock, flags); + + /* enable the ST LL - to set default chip state */ + st_ll_enable(st_gdata); + /* this may take a while to complete + * since it involves BT fw download + */ + err = st_kim_start(); + if (err != ST_SUCCESS) { + clear_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); + if ((st_gdata->protos_registered != ST_EMPTY) && + (test_bit(ST_REG_PENDING, &st_gdata->st_state))) { + pr_err(" KIM failure complete callback "); + st_reg_complete(st_gdata, ST_ERR_FAILURE); + } + + return ST_ERR_FAILURE; + } + + /* the protocol might require other gpios to be toggled + */ + st_kim_chip_toggle(new_proto->type, KIM_GPIO_ACTIVE); + + clear_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); + st_recv = st_int_recv; + + /* this is where all pending registration + * are signalled to be complete by calling callback functions + */ + if ((st_gdata->protos_registered != ST_EMPTY) && + (test_bit(ST_REG_PENDING, &st_gdata->st_state))) { + pr_info(" call reg complete callback "); + st_gdata->protos_registered++; + st_reg_complete(st_gdata, ST_SUCCESS); + } + clear_bit(ST_REG_PENDING, &st_gdata->st_state); + + /* check for already registered once more, + * since the above check is old + */ + if (st_gdata->list[new_proto->type] != NULL) { + pr_err(" proto %d already registered ", + new_proto->type); + return ST_ERR_ALREADY; + } + + spin_lock_irqsave(&st_gdata->lock, flags); + st_gdata->list[new_proto->type] = new_proto; + new_proto->write = st_write; + spin_unlock_irqrestore(&st_gdata->lock, flags); + return err; + } + /* if fw is already downloaded & new stack registers protocol */ + else { + switch (new_proto->type) { + case ST_BT: + /* do nothing */ + break; + case ST_FM: + case ST_GPS: + st_kim_chip_toggle(new_proto->type, KIM_GPIO_ACTIVE); + break; + case ST_MAX: + default: + pr_err("%d protocol not supported", + new_proto->type); + err = ST_ERR_NOPROTO; + /* something wrong */ + break; + } + st_gdata->list[new_proto->type] = new_proto; + new_proto->write = st_write; + + /* lock already held before entering else */ + spin_unlock_irqrestore(&st_gdata->lock, flags); + return err; + } + pr_info("done %s(%d) ", __func__, new_proto->type); +} +EXPORT_SYMBOL_GPL(st_register); + +/* to unregister a protocol - + * to be called from protocol stack driver + */ +long st_unregister(enum proto_type type) +{ + long err = ST_SUCCESS; + unsigned long flags = 0; + struct st_data_s *st_gdata; + + pr_info("%s: %d ", __func__, type); + + st_kim_ref(&st_gdata); + if (type < ST_BT || type >= ST_MAX) { + pr_err(" protocol %d not supported", type); + return ST_ERR_NOPROTO; + } + + spin_lock_irqsave(&st_gdata->lock, flags); + + if (st_gdata->list[type] == NULL) { + pr_err(" protocol %d not registered", type); + spin_unlock_irqrestore(&st_gdata->lock, flags); + return ST_ERR_NOPROTO; + } + + st_gdata->protos_registered--; + st_gdata->list[type] = NULL; + + /* kim ignores BT in the below function + * and handles the rest, BT is toggled + * only in kim_start and kim_stop + */ + st_kim_chip_toggle(type, KIM_GPIO_INACTIVE); + spin_unlock_irqrestore(&st_gdata->lock, flags); + + if ((st_gdata->protos_registered == ST_EMPTY) && + (!test_bit(ST_REG_PENDING, &st_gdata->st_state))) { + pr_info(" all protocols unregistered "); + + /* stop traffic on tty */ + if (st_gdata->tty) { + tty_ldisc_flush(st_gdata->tty); + stop_tty(st_gdata->tty); + } + + /* all protocols now unregistered */ + st_kim_stop(); + /* disable ST LL */ + st_ll_disable(st_gdata); + } + return err; +} + +/* + * called in protocol stack drivers + * via the write function pointer + */ +long st_write(struct sk_buff *skb) +{ + struct st_data_s *st_gdata; +#ifdef DEBUG + enum proto_type protoid = ST_MAX; +#endif + long len; + + st_kim_ref(&st_gdata); + if (unlikely(skb == NULL || st_gdata == NULL + || st_gdata->tty == NULL)) { + pr_err("data/tty unavailable to perform write"); + return ST_ERR_FAILURE; + } +#ifdef DEBUG /* open-up skb to read the 1st byte */ + switch (skb->data[0]) { + case HCI_COMMAND_PKT: + case HCI_ACLDATA_PKT: + case HCI_SCODATA_PKT: + protoid = ST_BT; + break; + case ST_FM_CH8_PKT: + protoid = ST_FM; + break; + case 0x09: + protoid = ST_GPS; + break; + } + if (unlikely(st_gdata->list[protoid] == NULL)) { + pr_err(" protocol %d not registered, and writing? ", + protoid); + return ST_ERR_FAILURE; + } +#endif + pr_info("%d to be written", skb->len); + len = skb->len; + + /* st_ll to decide where to enqueue the skb */ + st_int_enqueue(st_gdata, skb); + /* wake up */ + st_tx_wakeup(st_gdata); + + /* return number of bytes written */ + return len; +} + +/* for protocols making use of shared transport */ +EXPORT_SYMBOL_GPL(st_unregister); + +/********************************************************************/ +/* + * functions called from TTY layer + */ +static int st_tty_open(struct tty_struct *tty) +{ + int err = ST_SUCCESS; + struct st_data_s *st_gdata; + pr_info("%s ", __func__); + + st_kim_ref(&st_gdata); + st_gdata->tty = tty; + tty->disc_data = st_gdata; + + /* don't do an wakeup for now */ + clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); + + /* mem already allocated + */ + tty->receive_room = 65536; + /* Flush any pending characters in the driver and discipline. */ + tty_ldisc_flush(tty); + tty_driver_flush_buffer(tty); + /* + * signal to UIM via KIM that - + * installation of N_TI_WL ldisc is complete + */ + st_kim_complete(); + pr_info("done %s", __func__); + return err; +} + +static void st_tty_close(struct tty_struct *tty) +{ + unsigned char i = ST_MAX; + unsigned long flags = 0; + struct st_data_s *st_gdata = tty->disc_data; + + pr_info("%s ", __func__); + + /* TODO: + * if a protocol has been registered & line discipline + * un-installed for some reason - what should be done ? + */ + spin_lock_irqsave(&st_gdata->lock, flags); + for (i = ST_BT; i < ST_MAX; i++) { + if (st_gdata->list[i] != NULL) + pr_err("%d not un-registered", i); + st_gdata->list[i] = NULL; + } + spin_unlock_irqrestore(&st_gdata->lock, flags); + /* + * signal to UIM via KIM that - + * N_TI_WL ldisc is un-installed + */ + st_kim_complete(); + st_gdata->tty = NULL; + /* Flush any pending characters in the driver and discipline. */ + tty_ldisc_flush(tty); + tty_driver_flush_buffer(tty); + + spin_lock_irqsave(&st_gdata->lock, flags); + /* empty out txq and tx_waitq */ + skb_queue_purge(&st_gdata->txq); + skb_queue_purge(&st_gdata->tx_waitq); + /* reset the TTY Rx states of ST */ + st_gdata->rx_count = 0; + st_gdata->rx_state = ST_W4_PACKET_TYPE; + kfree_skb(st_gdata->rx_skb); + st_gdata->rx_skb = NULL; + spin_unlock_irqrestore(&st_gdata->lock, flags); + + pr_info("%s: done ", __func__); +} + +static void st_tty_receive(struct tty_struct *tty, const unsigned char *data, + char *tty_flags, int count) +{ + +#ifdef VERBOSE + long i; + printk(KERN_ERR "incoming data...\n"); + for (i = 0; i < count; i++) + printk(" %x", data[i]); + printk(KERN_ERR "\n.. data end\n"); +#endif + + /* + * if fw download is in progress then route incoming data + * to KIM for validation + */ + st_recv(tty->disc_data, data, count); + pr_info("done %s", __func__); +} + +/* wake-up function called in from the TTY layer + * inside the internal wakeup function will be called + */ +static void st_tty_wakeup(struct tty_struct *tty) +{ + struct st_data_s *st_gdata = tty->disc_data; + pr_info("%s ", __func__); + /* don't do an wakeup for now */ + clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); + + /* call our internal wakeup */ + st_tx_wakeup((void *)st_gdata); +} + +static void st_tty_flush_buffer(struct tty_struct *tty) +{ + struct st_data_s *st_gdata = tty->disc_data; + pr_info("%s ", __func__); + + kfree_skb(st_gdata->tx_skb); + st_gdata->tx_skb = NULL; + + tty->ops->flush_buffer(tty); + return; +} + +/********************************************************************/ +int st_core_init(struct st_data_s **core_data) +{ + struct st_data_s *st_gdata; + long err; + static struct tty_ldisc_ops *st_ldisc_ops; + + /* populate and register to TTY line discipline */ + st_ldisc_ops = kzalloc(sizeof(*st_ldisc_ops), GFP_KERNEL); + if (!st_ldisc_ops) { + pr_err("no mem to allocate"); + return -ENOMEM; + } + + st_ldisc_ops->magic = TTY_LDISC_MAGIC; + st_ldisc_ops->name = "n_st"; /*"n_hci"; */ + st_ldisc_ops->open = st_tty_open; + st_ldisc_ops->close = st_tty_close; + st_ldisc_ops->receive_buf = st_tty_receive; + st_ldisc_ops->write_wakeup = st_tty_wakeup; + st_ldisc_ops->flush_buffer = st_tty_flush_buffer; + st_ldisc_ops->owner = THIS_MODULE; + + err = tty_register_ldisc(N_TI_WL, st_ldisc_ops); + if (err) { + pr_err("error registering %d line discipline %ld", + N_TI_WL, err); + kfree(st_ldisc_ops); + return err; + } + pr_info("registered n_shared line discipline"); + + st_gdata = kzalloc(sizeof(struct st_data_s), GFP_KERNEL); + if (!st_gdata) { + pr_err("memory allocation failed"); + err = tty_unregister_ldisc(N_TI_WL); + if (err) + pr_err("unable to un-register ldisc %ld", err); + kfree(st_ldisc_ops); + err = -ENOMEM; + return err; + } + + /* Initialize ST TxQ and Tx waitQ queue head. All BT/FM/GPS module skb's + * will be pushed in this queue for actual transmission. + */ + skb_queue_head_init(&st_gdata->txq); + skb_queue_head_init(&st_gdata->tx_waitq); + + /* Locking used in st_int_enqueue() to avoid multiple execution */ + spin_lock_init(&st_gdata->lock); + + /* ldisc_ops ref to be only used in __exit of module */ + st_gdata->ldisc_ops = st_ldisc_ops; + +#if 0 + err = st_kim_init(); + if (err) { + pr_err("error during kim initialization(%ld)", err); + kfree(st_gdata); + err = tty_unregister_ldisc(N_TI_WL); + if (err) + pr_err("unable to un-register ldisc"); + kfree(st_ldisc_ops); + return -1; + } +#endif + + err = st_ll_init(st_gdata); + if (err) { + pr_err("error during st_ll initialization(%ld)", err); + kfree(st_gdata); + err = tty_unregister_ldisc(N_TI_WL); + if (err) + pr_err("unable to un-register ldisc"); + kfree(st_ldisc_ops); + return -1; + } + *core_data = st_gdata; + return 0; +} + +void st_core_exit(struct st_data_s *st_gdata) +{ + long err; + /* internal module cleanup */ + err = st_ll_deinit(st_gdata); + if (err) + pr_err("error during deinit of ST LL %ld", err); +#if 0 + err = st_kim_deinit(); + if (err) + pr_err("error during deinit of ST KIM %ld", err); +#endif + if (st_gdata != NULL) { + /* Free ST Tx Qs and skbs */ + skb_queue_purge(&st_gdata->txq); + skb_queue_purge(&st_gdata->tx_waitq); + kfree_skb(st_gdata->rx_skb); + kfree_skb(st_gdata->tx_skb); + /* TTY ldisc cleanup */ + err = tty_unregister_ldisc(N_TI_WL); + if (err) + pr_err("unable to un-register ldisc %ld", err); + kfree(st_gdata->ldisc_ops); + /* free the global data pointer */ + kfree(st_gdata); + } +} + + diff --git a/drivers/staging/ti-st/st_core.h b/drivers/staging/ti-st/st_core.h new file mode 100644 index 000000000000..f271c88a8087 --- /dev/null +++ b/drivers/staging/ti-st/st_core.h @@ -0,0 +1,98 @@ +/* + * Shared Transport Core header file + * + * Copyright (C) 2009 Texas Instruments + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef ST_CORE_H +#define ST_CORE_H + +#include +#include "st.h" + +/* states of protocol list */ +#define ST_NOTEMPTY 1 +#define ST_EMPTY 0 + +/* + * possible st_states + */ +#define ST_INITIALIZING 1 +#define ST_REG_IN_PROGRESS 2 +#define ST_REG_PENDING 3 +#define ST_WAITING_FOR_RESP 4 + +/* + * local data required for ST/KIM/ST-HCI-LL + */ +struct st_data_s { + unsigned long st_state; +/* + * an instance of tty_struct & ldisc ops to move around + */ + struct tty_struct *tty; + struct tty_ldisc_ops *ldisc_ops; +/* + * the tx skb - + * if the skb is already dequeued and the tty failed to write the same + * maintain the skb to write in the next transaction + */ + struct sk_buff *tx_skb; +#define ST_TX_SENDING 1 +#define ST_TX_WAKEUP 2 + unsigned long tx_state; +/* + * list of protocol registered + */ + struct st_proto_s *list[ST_MAX]; +/* + * lock + */ + unsigned long rx_state; + unsigned long rx_count; + struct sk_buff *rx_skb; + struct sk_buff_head txq, tx_waitq; + spinlock_t lock; /* ST LL state lock */ + unsigned char protos_registered; + unsigned long ll_state; /* ST LL power state */ +}; + +/* point this to tty->driver->write or tty->ops->write + * depending upon the kernel version + */ +int st_int_write(struct st_data_s*, const unsigned char*, int); +/* internal write function, passed onto protocol drivers + * via the write function ptr of protocol struct + */ +long st_write(struct sk_buff *); +/* function to be called from ST-LL + */ +void st_ll_send_frame(enum proto_type, struct sk_buff *); +/* internal wake up function */ +void st_tx_wakeup(struct st_data_s *st_data); + +int st_core_init(struct st_data_s **); +void st_core_exit(struct st_data_s *); +void st_kim_ref(struct st_data_s **); + +#define GPS_STUB_TEST +#ifdef GPS_STUB_TEST +int gps_chrdrv_stub_write(const unsigned char*, int); +void gps_chrdrv_stub_init(void); +#endif + +#endif /*ST_CORE_H */ -- cgit v1.2.3 From d0088ce183ad111b203adc94dcc7dde2a590a198 Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Thu, 8 Apr 2010 13:16:54 -0500 Subject: Staging: sources for Init manager module Kernel Space Init-Manager works along with User-Mode Init Manager daemon running to maintain the UART state. Communication between user-space daemon and this module can be 1. Via the pid written onto sysfs entry 2. Via the rfkill subsystem It also is a platform driver with a relevant platform device in the board-*.c along with the list of BT/FM/GPS chip enable gpio configuration Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ti-st/st_kim.c | 754 +++++++++++++++++++++++++++++++++++++++++ drivers/staging/ti-st/st_kim.h | 150 ++++++++ 2 files changed, 904 insertions(+) create mode 100644 drivers/staging/ti-st/st_kim.c create mode 100644 drivers/staging/ti-st/st_kim.h (limited to 'drivers') diff --git a/drivers/staging/ti-st/st_kim.c b/drivers/staging/ti-st/st_kim.c new file mode 100644 index 000000000000..98cbabba3844 --- /dev/null +++ b/drivers/staging/ti-st/st_kim.c @@ -0,0 +1,754 @@ +/* + * Shared Transport Line discipline driver Core + * Init Manager module responsible for GPIO control + * and firmware download + * Copyright (C) 2009 Texas Instruments + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define pr_fmt(fmt) "(stk) :" fmt +#include +#include +#include +#include +#include +#include + +#include + +#include "st_kim.h" +/* understand BT events for fw response */ +#include +#include +#include + + +static int kim_probe(struct platform_device *pdev); +static int kim_remove(struct platform_device *pdev); + +/* KIM platform device driver structure */ +static struct platform_driver kim_platform_driver = { + .probe = kim_probe, + .remove = kim_remove, + /* TODO: ST driver power management during suspend/resume ? + */ +#if 0 + .suspend = kim_suspend, + .resume = kim_resume, +#endif + .driver = { + .name = "kim", + .owner = THIS_MODULE, + }, +}; + +#ifndef LEGACY_RFKILL_SUPPORT +static ssize_t show_pid(struct device *dev, struct device_attribute + *attr, char *buf); +static ssize_t store_pid(struct device *dev, struct device_attribute + *devattr, char *buf, size_t count); +static ssize_t show_list(struct device *dev, struct device_attribute + *attr, char *buf); + +/* structures specific for sysfs entries */ +static struct kobj_attribute pid_attr = +__ATTR(pid, 0644, (void *)show_pid, (void *)store_pid); + +static struct kobj_attribute list_protocols = +__ATTR(protocols, 0444, (void *)show_list, NULL); + +static struct attribute *uim_attrs[] = { + &pid_attr.attr, + /* add more debug sysfs entries */ + &list_protocols.attr, + NULL, +}; + +static struct attribute_group uim_attr_grp = { + .attrs = uim_attrs, +}; +#else +static int kim_toggle_radio(void*, bool); +static const struct rfkill_ops kim_rfkill_ops = { + .set_block = kim_toggle_radio, +}; +#endif /* LEGACY_RFKILL_SUPPORT */ + +/* strings to be used for rfkill entries and by + * ST Core to be used for sysfs debug entry + */ +#define PROTO_ENTRY(type, name) name +const unsigned char *protocol_names[] = { + PROTO_ENTRY(ST_BT, "Bluetooth"), + PROTO_ENTRY(ST_FM, "FM"), + PROTO_ENTRY(ST_GPS, "GPS"), +}; + +struct kim_data_s *kim_gdata; + +/**********************************************************************/ +/* internal functions */ + +/* + * function to return whether the firmware response was proper + * in case of error don't complete so that waiting for proper + * response times out + */ +void validate_firmware_response(struct sk_buff *skb) +{ + if (unlikely(skb->data[5] != 0)) { + pr_err("no proper response during fw download"); + pr_err("data6 %x", skb->data[5]); + return; /* keep waiting for the proper response */ + } + /* becos of all the script being downloaded */ + complete_all(&kim_gdata->kim_rcvd); + kfree_skb(skb); +} + +/* check for data len received inside kim_int_recv + * most often hit the last case to update state to waiting for data + */ +static inline int kim_check_data_len(int len) +{ + register int room = skb_tailroom(kim_gdata->rx_skb); + + pr_info("len %d room %d", len, room); + + if (!len) { + validate_firmware_response(kim_gdata->rx_skb); + } else if (len > room) { + /* Received packet's payload length is larger. + * We can't accommodate it in created skb. + */ + pr_err("Data length is too large len %d room %d", len, + room); + kfree_skb(kim_gdata->rx_skb); + } else { + /* Packet header has non-zero payload length and + * we have enough space in created skb. Lets read + * payload data */ + kim_gdata->rx_state = ST_BT_W4_DATA; + kim_gdata->rx_count = len; + return len; + } + + /* Change ST LL state to continue to process next + * packet */ + kim_gdata->rx_state = ST_W4_PACKET_TYPE; + kim_gdata->rx_skb = NULL; + kim_gdata->rx_count = 0; + + return 0; +} + +/* receive function called during firmware download + * - firmware download responses on different UART drivers + * have been observed to come in bursts of different + * tty_receive and hence the logic + */ +void kim_int_recv(const unsigned char *data, long count) +{ + register char *ptr; + struct hci_event_hdr *eh; + register int len = 0, type = 0; + + pr_info("%s", __func__); + /* Decode received bytes here */ + ptr = (char *)data; + if (unlikely(ptr == NULL)) { + pr_err(" received null from TTY "); + return; + } + while (count) { + if (kim_gdata->rx_count) { + len = min_t(unsigned int, kim_gdata->rx_count, count); + memcpy(skb_put(kim_gdata->rx_skb, len), ptr, len); + kim_gdata->rx_count -= len; + count -= len; + ptr += len; + + if (kim_gdata->rx_count) + continue; + + /* Check ST RX state machine , where are we? */ + switch (kim_gdata->rx_state) { + /* Waiting for complete packet ? */ + case ST_BT_W4_DATA: + pr_info("Complete pkt received"); + validate_firmware_response(kim_gdata->rx_skb); + kim_gdata->rx_state = ST_W4_PACKET_TYPE; + kim_gdata->rx_skb = NULL; + continue; + /* Waiting for Bluetooth event header ? */ + case ST_BT_W4_EVENT_HDR: + eh = (struct hci_event_hdr *)kim_gdata-> + rx_skb->data; + pr_info("Event header: evt 0x%2.2x" + "plen %d", eh->evt, eh->plen); + kim_check_data_len(eh->plen); + continue; + } /* end of switch */ + } /* end of if rx_state */ + switch (*ptr) { + /* Bluetooth event packet? */ + case HCI_EVENT_PKT: + pr_info("Event packet"); + kim_gdata->rx_state = ST_BT_W4_EVENT_HDR; + kim_gdata->rx_count = HCI_EVENT_HDR_SIZE; + type = HCI_EVENT_PKT; + break; + default: + pr_info("unknown packet"); + ptr++; + count--; + continue; + } /* end of switch *ptr */ + ptr++; + count--; + kim_gdata->rx_skb = + bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC); + if (!kim_gdata->rx_skb) { + pr_err("can't allocate mem for new packet"); + kim_gdata->rx_state = ST_W4_PACKET_TYPE; + kim_gdata->rx_count = 0; + return; + } /* not necessary in this case */ + bt_cb(kim_gdata->rx_skb)->pkt_type = type; + } /* end of while count */ + pr_info("done %s", __func__); + return; +} + +static long read_local_version(char *bts_scr_name) +{ + unsigned short version = 0, chip = 0, min_ver = 0, maj_ver = 0; + char read_ver_cmd[] = { 0x01, 0x01, 0x10, 0x00 }; + + pr_info("%s", __func__); + + INIT_COMPLETION(kim_gdata->kim_rcvd); + if (4 != st_int_write(kim_gdata->core_data, read_ver_cmd, 4)) { + pr_err("kim: couldn't write 4 bytes"); + return ST_ERR_FAILURE; + } + + if (!wait_for_completion_timeout + (&kim_gdata->kim_rcvd, msecs_to_jiffies(CMD_RESP_TIME))) { + pr_err(" waiting for ver info- timed out "); + return ST_ERR_FAILURE; + } + + version = + MAKEWORD(kim_gdata->resp_buffer[13], kim_gdata->resp_buffer[14]); + chip = (version & 0x7C00) >> 10; + min_ver = (version & 0x007F); + maj_ver = (version & 0x0380) >> 7; + + if (version & 0x8000) + maj_ver |= 0x0008; + + sprintf(bts_scr_name, "TIInit_%d.%d.%d.bts", chip, maj_ver, min_ver); + pr_info("%s", bts_scr_name); + return ST_SUCCESS; +} + +/* internal function which parses through the .bts firmware script file + * intreprets SEND, DELAY actions only as of now + */ +static long download_firmware(void) +{ + long err = ST_SUCCESS; + long len = 0; + register unsigned char *ptr = NULL; + register unsigned char *action_ptr = NULL; + unsigned char bts_scr_name[30] = { 0 }; /* 30 char long bts scr name? */ + + pr_info("%s", __func__); + + err = read_local_version(bts_scr_name); + if (err != ST_SUCCESS) { + pr_err("kim: failed to read local ver"); + return err; + } + err = + request_firmware(&kim_gdata->fw_entry, bts_scr_name, + &kim_gdata->kim_pdev->dev); + if (unlikely((err != 0) || (kim_gdata->fw_entry->data == NULL) || + (kim_gdata->fw_entry->size == 0))) { + pr_err(" request_firmware failed(errno %ld) for %s", err, + bts_scr_name); + return ST_ERR_FAILURE; + } + ptr = (void *)kim_gdata->fw_entry->data; + len = kim_gdata->fw_entry->size; + /* bts_header to remove out magic number and + * version + */ + ptr += sizeof(struct bts_header); + len -= sizeof(struct bts_header); + + while (len > 0 && ptr) { + pr_info(" action size %d, type %d ", + ((struct bts_action *)ptr)->size, + ((struct bts_action *)ptr)->type); + + switch (((struct bts_action *)ptr)->type) { + case ACTION_SEND_COMMAND: /* action send */ + action_ptr = &(((struct bts_action *)ptr)->data[0]); + if (unlikely + (((struct hci_command *)action_ptr)->opcode == + 0xFF36)) { + /* ignore remote change + * baud rate HCI VS command */ + pr_err + (" change remote baud\ + rate command in firmware"); + break; + } + + INIT_COMPLETION(kim_gdata->kim_rcvd); + err = st_int_write(kim_gdata->core_data, + ((struct bts_action_send *)action_ptr)->data, + ((struct bts_action *)ptr)->size); + if (unlikely(err < 0)) { + release_firmware(kim_gdata->fw_entry); + return ST_ERR_FAILURE; + } + if (!wait_for_completion_timeout + (&kim_gdata->kim_rcvd, + msecs_to_jiffies(CMD_RESP_TIME))) { + pr_err + (" response timeout during fw download "); + /* timed out */ + release_firmware(kim_gdata->fw_entry); + return ST_ERR_FAILURE; + } + break; + case ACTION_DELAY: /* sleep */ + pr_info("sleep command in scr"); + action_ptr = &(((struct bts_action *)ptr)->data[0]); + mdelay(((struct bts_action_delay *)action_ptr)->msec); + break; + } + len = + len - (sizeof(struct bts_action) + + ((struct bts_action *)ptr)->size); + ptr = + ptr + sizeof(struct bts_action) + + ((struct bts_action *)ptr)->size; + } + /* fw download complete */ + release_firmware(kim_gdata->fw_entry); + return ST_SUCCESS; +} + +/**********************************************************************/ +/* functions called from ST core */ + +/* function to toggle the GPIO + * needs to know whether the GPIO is active high or active low + */ +void st_kim_chip_toggle(enum proto_type type, enum kim_gpio_state state) +{ + pr_info(" %s ", __func__); + + if (kim_gdata->gpios[type] == -1) { + pr_info(" gpio not requested for protocol %s", + protocol_names[type]); + return; + } + switch (type) { + case ST_BT: + /*Do Nothing */ + break; + + case ST_FM: + if (state == KIM_GPIO_ACTIVE) + gpio_set_value(kim_gdata->gpios[ST_FM], GPIO_LOW); + else + gpio_set_value(kim_gdata->gpios[ST_FM], GPIO_HIGH); + break; + + case ST_GPS: + if (state == KIM_GPIO_ACTIVE) + gpio_set_value(kim_gdata->gpios[ST_GPS], GPIO_HIGH); + else + gpio_set_value(kim_gdata->gpios[ST_GPS], GPIO_LOW); + break; + + case ST_MAX: + default: + break; + } + + return; +} + +/* called from ST Core, when REG_IN_PROGRESS (registration in progress) + * can be because of + * 1. response to read local version + * 2. during send/recv's of firmware download + */ +void st_kim_recv(void *disc_data, const unsigned char *data, long count) +{ + pr_info(" %s ", __func__); + /* copy to local buffer */ + if (unlikely(data[4] == 0x01 && data[5] == 0x10 && data[0] == 0x04)) { + /* must be the read_ver_cmd */ + memcpy(kim_gdata->resp_buffer, data, count); + complete_all(&kim_gdata->kim_rcvd); + return; + } else { + kim_int_recv(data, count); + /* either completes or times out */ + } + return; +} + +/* to signal completion of line discipline installation + * called from ST Core, upon tty_open + */ +void st_kim_complete(void) +{ + complete(&kim_gdata->ldisc_installed); +} + +/* called from ST Core upon 1st registration +*/ +long st_kim_start(void) +{ + long err = ST_SUCCESS; + long retry = POR_RETRY_COUNT; + pr_info(" %s", __func__); + + do { +#ifdef LEGACY_RFKILL_SUPPORT + /* TODO: this is only because rfkill sub-system + * doesn't send events to user-space if the state + * isn't changed + */ + rfkill_set_hw_state(kim_gdata->rfkill[ST_BT], 1); +#endif + /* Configure BT nShutdown to HIGH state */ + gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_LOW); + mdelay(5); /* FIXME: a proper toggle */ + gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_HIGH); + mdelay(100); + /* re-initialize the completion */ + INIT_COMPLETION(kim_gdata->ldisc_installed); +#ifndef LEGACY_RFKILL_SUPPORT + /* send signal to UIM */ + err = kill_pid(find_get_pid(kim_gdata->uim_pid), SIGUSR2, 0); + if (err != 0) { + pr_info(" sending SIGUSR2 to uim failed %ld", err); + err = ST_ERR_FAILURE; + continue; + } +#else + /* unblock and send event to UIM via /dev/rfkill */ + rfkill_set_hw_state(kim_gdata->rfkill[ST_BT], 0); +#endif + /* wait for ldisc to be installed */ + err = wait_for_completion_timeout(&kim_gdata->ldisc_installed, + msecs_to_jiffies(LDISC_TIME)); + if (!err) { /* timeout */ + pr_err("line disc installation timed out "); + err = ST_ERR_FAILURE; + continue; + } else { + /* ldisc installed now */ + pr_info(" line discipline installed "); + err = download_firmware(); + if (err != ST_SUCCESS) { + pr_err("download firmware failed"); + continue; + } else { /* on success don't retry */ + break; + } + } + } while (retry--); + return err; +} + +/* called from ST Core, on the last un-registration +*/ +long st_kim_stop(void) +{ + long err = ST_SUCCESS; + + INIT_COMPLETION(kim_gdata->ldisc_installed); +#ifndef LEGACY_RFKILL_SUPPORT + /* send signal to UIM */ + err = kill_pid(find_get_pid(kim_gdata->uim_pid), SIGUSR2, 1); + if (err != 0) { + pr_err("sending SIGUSR2 to uim failed %ld", err); + return ST_ERR_FAILURE; + } +#else + /* set BT rfkill to be blocked */ + err = rfkill_set_hw_state(kim_gdata->rfkill[ST_BT], 1); +#endif + + /* wait for ldisc to be un-installed */ + err = wait_for_completion_timeout(&kim_gdata->ldisc_installed, + msecs_to_jiffies(LDISC_TIME)); + if (!err) { /* timeout */ + pr_err(" timed out waiting for ldisc to be un-installed"); + return ST_ERR_FAILURE; + } + + /* By default configure BT nShutdown to LOW state */ + gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_LOW); + mdelay(1); + gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_HIGH); + mdelay(1); + gpio_set_value(kim_gdata->gpios[ST_BT], GPIO_LOW); + return err; +} + +/**********************************************************************/ +/* functions called from subsystems */ + +#ifndef LEGACY_RFKILL_SUPPORT +/* called when sysfs entry is written to */ +static ssize_t store_pid(struct device *dev, struct device_attribute + *devattr, char *buf, size_t count) +{ + pr_info("%s: pid %s ", __func__, buf); + sscanf(buf, "%ld", &kim_gdata->uim_pid); + /* to be made use by kim_start to signal SIGUSR2 + */ + return strlen(buf); +} + +/* called when sysfs entry is read from */ +static ssize_t show_pid(struct device *dev, struct device_attribute + *attr, char *buf) +{ + sprintf(buf, "%ld", kim_gdata->uim_pid); + return strlen(buf); +} + +/* called when sysfs entry is read from */ +static ssize_t show_list(struct device *dev, struct device_attribute + *attr, char *buf) +{ + kim_st_list_protocols(kim_gdata->core_data, buf); + return strlen(buf); +} + +#else /* LEGACY_RFKILL_SUPPORT */ + +/* function called from rfkill subsystem, when someone from + * user space would write 0/1 on the sysfs entry + * /sys/class/rfkill/rfkill0,1,3/state + */ +static int kim_toggle_radio(void *data, bool blocked) +{ + enum proto_type type = *((enum proto_type *)data); + pr_info(" %s: %d ", __func__, type); + + switch (type) { + case ST_BT: + /* do nothing */ + break; + case ST_FM: + case ST_GPS: + if (blocked) + st_kim_chip_toggle(type, KIM_GPIO_INACTIVE); + else + st_kim_chip_toggle(type, KIM_GPIO_ACTIVE); + break; + case ST_MAX: + pr_err(" wrong proto type "); + break; + } + return ST_SUCCESS; +} + +#endif /* LEGACY_RFKILL_SUPPORT */ + +void st_kim_ref(struct st_data_s **core_data) +{ + *core_data = kim_gdata->core_data; +} + +/**********************************************************************/ +/* functions called from platform device driver subsystem + * need to have a relevant platform device entry in the platform's + * board-*.c file + */ + +static int kim_probe(struct platform_device *pdev) +{ + long status; + long proto; + long *gpios = pdev->dev.platform_data; + + status = st_core_init(&kim_gdata->core_data); + if (status != 0) { + pr_err(" ST core init failed"); + return ST_ERR_FAILURE; + } + + for (proto = 0; proto < ST_MAX; proto++) { + kim_gdata->gpios[proto] = gpios[proto]; + pr_info(" %ld gpio to be requested", gpios[proto]); + } + + for (proto = 0; (proto < ST_MAX) && (gpios[proto] != -1); proto++) { + /* Claim the Bluetooth/FM/GPIO + * nShutdown gpio from the system + */ + status = gpio_request(gpios[proto], "kim"); + if (unlikely(status)) { + pr_err(" gpio %ld request failed ", gpios[proto]); + proto -= 1; + while (proto >= 0) { + if (gpios[proto] != -1) + gpio_free(gpios[proto]); + } + return status; + } + + /* Configure nShutdown GPIO as output=0 */ + status = + gpio_direction_output(gpios[proto], 0); + if (unlikely(status)) { + pr_err(" unable to configure gpio %ld", + gpios[proto]); + proto -= 1; + while (proto >= 0) { + if (gpios[proto] != -1) + gpio_free(gpios[proto]); + } + return status; + } + } +#ifndef LEGACY_RFKILL_SUPPORT + /* pdev to contain BT, FM and GPS enable/N-Shutdown GPIOs + * execute request_gpio, set output direction + */ + kim_gdata->kim_kobj = kobject_create_and_add("uim", NULL); + /* create the sysfs entry for UIM to put in pid */ + if (sysfs_create_group(kim_gdata->kim_kobj, &uim_attr_grp)) { + pr_err(" sysfs entry creation failed"); + kobject_put(kim_gdata->kim_kobj); + /* free requested GPIOs and fail probe */ + for (proto = ST_BT; proto < ST_MAX; proto++) { + if (gpios[proto] != -1) + gpio_free(gpios[proto]); + } + return -1; /* fail insmod */ + } + pr_info(" sysfs entry created "); +#endif + /* get reference of pdev for request_firmware + */ + kim_gdata->kim_pdev = pdev; + init_completion(&kim_gdata->kim_rcvd); + init_completion(&kim_gdata->ldisc_installed); +#ifdef LEGACY_RFKILL_SUPPORT + for (proto = 0; (proto < ST_MAX) && (gpios[proto] != -1); proto++) { + /* TODO: should all types be rfkill_type_bt ? */ + kim_gdata->rf_protos[proto] = proto; + kim_gdata->rfkill[proto] = rfkill_alloc(protocol_names[proto], + &pdev->dev, RFKILL_TYPE_BLUETOOTH, + &kim_rfkill_ops, &kim_gdata->rf_protos[proto]); + if (kim_gdata->rfkill[proto] == NULL) { + pr_err("cannot create rfkill entry for gpio %ld", + gpios[proto]); + continue; + } + /* block upon creation */ + rfkill_init_sw_state(kim_gdata->rfkill[proto], 1); + status = rfkill_register(kim_gdata->rfkill[proto]); + if (unlikely(status)) { + pr_err("rfkill registration failed for gpio %ld", + gpios[proto]); + rfkill_unregister(kim_gdata->rfkill[proto]); + continue; + } + pr_info("rfkill entry created for %ld", gpios[proto]); + } +#endif + return ST_SUCCESS; +} + +static int kim_remove(struct platform_device *pdev) +{ + /* free the GPIOs requested + */ + long *gpios = pdev->dev.platform_data; + long proto; + + for (proto = 0; (proto < ST_MAX) && (gpios[proto] != -1); proto++) { + /* Claim the Bluetooth/FM/GPIO + * nShutdown gpio from the system + */ + gpio_free(gpios[proto]); +#ifdef LEGACY_RFKILL_SUPPORT + rfkill_unregister(kim_gdata->rfkill[proto]); + rfkill_destroy(kim_gdata->rfkill[proto]); + kim_gdata->rfkill[proto] = NULL; +#endif + } + pr_info("kim: GPIO Freed"); +#ifndef LEGACY_RFKILL_SUPPORT + /* delete the sysfs entries */ + sysfs_remove_group(kim_gdata->kim_kobj, &uim_attr_grp); + kobject_put(kim_gdata->kim_kobj); +#endif + kim_gdata->kim_pdev = NULL; + st_core_exit(kim_gdata->core_data); + return ST_SUCCESS; +} + +/**********************************************************************/ +/* entry point for ST KIM module, called in from ST Core */ + +static int __init st_kim_init(void) +{ + long ret = ST_SUCCESS; + kim_gdata = kzalloc(sizeof(struct kim_data_s), GFP_ATOMIC); + if (!kim_gdata) { + pr_err("no mem to allocate"); + return -ENOMEM; + } + + ret = platform_driver_register(&kim_platform_driver); + if (ret != 0) { + pr_err("platform drv registration failed"); + return ST_ERR_FAILURE; + } + return ST_SUCCESS; +} + +static void __exit st_kim_deinit(void) +{ + /* the following returns void */ + platform_driver_unregister(&kim_platform_driver); + kfree(kim_gdata); + kim_gdata = NULL; +} + + +module_init(st_kim_init); +module_exit(st_kim_deinit); +MODULE_AUTHOR("Pavan Savoy "); +MODULE_DESCRIPTION("Shared Transport Driver for TI BT/FM/GPS combo chips "); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/ti-st/st_kim.h b/drivers/staging/ti-st/st_kim.h new file mode 100644 index 000000000000..ff3270ec7847 --- /dev/null +++ b/drivers/staging/ti-st/st_kim.h @@ -0,0 +1,150 @@ +/* + * Shared Transport Line discipline driver Core + * Init Manager Module header file + * Copyright (C) 2009 Texas Instruments + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef ST_KIM_H +#define ST_KIM_H + +#include +#include "st.h" +#include "st_core.h" +#include "st_ll.h" +#include + +/* time in msec to wait for + * line discipline to be installed + */ +#define LDISC_TIME 500 +#define CMD_RESP_TIME 500 +#define MAKEWORD(a, b) ((unsigned short)(((unsigned char)(a)) \ + | ((unsigned short)((unsigned char)(b))) << 8)) + +#define GPIO_HIGH 1 +#define GPIO_LOW 0 + +/* the Power-On-Reset logic, requires to attempt + * to download firmware onto chip more than once + * since the self-test for chip takes a while + */ +#define POR_RETRY_COUNT 5 +/* + * legacy rfkill support where-in 3 rfkill + * devices are created for the 3 gpios + * that ST has requested + */ +#define LEGACY_RFKILL_SUPPORT +/* + * header file for ST provided by KIM + */ +struct kim_data_s { + long uim_pid; + struct platform_device *kim_pdev; + struct completion kim_rcvd, ldisc_installed; + /* MAX len of the .bts firmware script name */ + char resp_buffer[30]; + const struct firmware *fw_entry; + long gpios[ST_MAX]; + struct kobject *kim_kobj; +/* used by kim_int_recv to validate fw response */ + unsigned long rx_state; + unsigned long rx_count; + struct sk_buff *rx_skb; +#ifdef LEGACY_RFKILL_SUPPORT + struct rfkill *rfkill[ST_MAX]; + enum proto_type rf_protos[ST_MAX]; +#endif + struct st_data_s *core_data; +}; + +long st_kim_start(void); +long st_kim_stop(void); +/* + * called from st_tty_receive to authenticate fw_download + */ +void st_kim_recv(void *, const unsigned char *, long count); + +void st_kim_chip_toggle(enum proto_type, enum kim_gpio_state); + +void st_kim_complete(void); + +/* function called from ST KIM to ST Core, to + * list out the protocols registered + */ +void kim_st_list_protocols(struct st_data_s *, char *); + +/* + * BTS headers + */ +#define ACTION_SEND_COMMAND 1 +#define ACTION_WAIT_EVENT 2 +#define ACTION_SERIAL 3 +#define ACTION_DELAY 4 +#define ACTION_RUN_SCRIPT 5 +#define ACTION_REMARKS 6 + +/* + * * BRF Firmware header + * */ +struct bts_header { + uint32_t magic; + uint32_t version; + uint8_t future[24]; + uint8_t actions[0]; +} __attribute__ ((packed)); + +/* + * * BRF Actions structure + * */ +struct bts_action { + uint16_t type; + uint16_t size; + uint8_t data[0]; +} __attribute__ ((packed)); + +struct bts_action_send { + uint8_t data[0]; +} __attribute__ ((packed)); + +struct bts_action_wait { + uint32_t msec; + uint32_t size; + uint8_t data[0]; +} __attribute__ ((packed)); + +struct bts_action_delay { + uint32_t msec; +} __attribute__ ((packed)); + +struct bts_action_serial { + uint32_t baud; + uint32_t flow_control; +} __attribute__ ((packed)); + +/* for identifying the change speed HCI VS + * command + */ +struct hci_command { + uint8_t prefix; + uint16_t opcode; + uint8_t plen; + uint32_t speed; +} __attribute__ ((packed)); + + +#endif /* ST_KIM_H */ -- cgit v1.2.3 From 1d065ab683f954d864a9366927d83bfc88b2f585 Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Thu, 8 Apr 2010 13:16:55 -0500 Subject: Staging: sources for HCI LL PM protocol Texas Instruments BT, FM and GPS combo chips/drivers make use of a single TTY to communicate with the chip. This module constitutes the proprietary power management protocol from TI for the BT/FM/GPS combo chips Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ti-st/st_ll.c | 147 ++++++++++++++++++++++++++++++++++++++++++ drivers/staging/ti-st/st_ll.h | 62 ++++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 drivers/staging/ti-st/st_ll.c create mode 100644 drivers/staging/ti-st/st_ll.h (limited to 'drivers') diff --git a/drivers/staging/ti-st/st_ll.c b/drivers/staging/ti-st/st_ll.c new file mode 100644 index 000000000000..0685a100db6a --- /dev/null +++ b/drivers/staging/ti-st/st_ll.c @@ -0,0 +1,147 @@ +/* + * Shared Transport driver + * HCI-LL module responsible for TI proprietary HCI_LL protocol + * Copyright (C) 2009 Texas Instruments + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define pr_fmt(fmt) "(stll) :" fmt +#include "st_ll.h" + +/**********************************************************************/ +/* internal functions */ +static void send_ll_cmd(struct st_data_s *st_data, + unsigned char cmd) +{ + + pr_info("%s: writing %x", __func__, cmd); + st_int_write(st_data, &cmd, 1); + return; +} + +static void ll_device_want_to_sleep(struct st_data_s *st_data) +{ + pr_info("%s", __func__); + /* sanity check */ + if (st_data->ll_state != ST_LL_AWAKE) + pr_err("ERR hcill: ST_LL_GO_TO_SLEEP_IND" + "in state %ld", st_data->ll_state); + + send_ll_cmd(st_data, LL_SLEEP_ACK); + /* update state */ + st_data->ll_state = ST_LL_ASLEEP; +} + +static void ll_device_want_to_wakeup(struct st_data_s *st_data) +{ + /* diff actions in diff states */ + switch (st_data->ll_state) { + case ST_LL_ASLEEP: + send_ll_cmd(st_data, LL_WAKE_UP_ACK); /* send wake_ack */ + break; + case ST_LL_ASLEEP_TO_AWAKE: + /* duplicate wake_ind */ + pr_err("duplicate wake_ind while waiting for Wake ack"); + break; + case ST_LL_AWAKE: + /* duplicate wake_ind */ + pr_err("duplicate wake_ind already AWAKE"); + break; + case ST_LL_AWAKE_TO_ASLEEP: + /* duplicate wake_ind */ + pr_err("duplicate wake_ind"); + break; + } + /* update state */ + st_data->ll_state = ST_LL_AWAKE; +} + +/**********************************************************************/ +/* functions invoked by ST Core */ + +/* called when ST Core wants to + * enable ST LL */ +void st_ll_enable(struct st_data_s *ll) +{ + ll->ll_state = ST_LL_AWAKE; +} + +/* called when ST Core /local module wants to + * disable ST LL */ +void st_ll_disable(struct st_data_s *ll) +{ + ll->ll_state = ST_LL_INVALID; +} + +/* called when ST Core wants to update the state */ +void st_ll_wakeup(struct st_data_s *ll) +{ + if (likely(ll->ll_state != ST_LL_AWAKE)) { + send_ll_cmd(ll, LL_WAKE_UP_IND); /* WAKE_IND */ + ll->ll_state = ST_LL_ASLEEP_TO_AWAKE; + } else { + /* don't send the duplicate wake_indication */ + pr_err(" Chip already AWAKE "); + } +} + +/* called when ST Core wants the state */ +unsigned long st_ll_getstate(struct st_data_s *ll) +{ + pr_info(" returning state %ld", ll->ll_state); + return ll->ll_state; +} + +/* called from ST Core, when a PM related packet arrives */ +unsigned long st_ll_sleep_state(struct st_data_s *st_data, + unsigned char cmd) +{ + switch (cmd) { + case LL_SLEEP_IND: /* sleep ind */ + pr_info("sleep indication recvd"); + ll_device_want_to_sleep(st_data); + break; + case LL_SLEEP_ACK: /* sleep ack */ + pr_err("sleep ack rcvd: host shouldn't"); + break; + case LL_WAKE_UP_IND: /* wake ind */ + pr_info("wake indication recvd"); + ll_device_want_to_wakeup(st_data); + break; + case LL_WAKE_UP_ACK: /* wake ack */ + pr_info("wake ack rcvd"); + st_data->ll_state = ST_LL_AWAKE; + break; + default: + pr_err(" unknown input/state "); + return ST_ERR_FAILURE; + } + return ST_SUCCESS; +} + +/* Called from ST CORE to initialize ST LL */ +long st_ll_init(struct st_data_s *ll) +{ + /* set state to invalid */ + ll->ll_state = ST_LL_INVALID; + return 0; +} + +/* Called from ST CORE to de-initialize ST LL */ +long st_ll_deinit(struct st_data_s *ll) +{ + return 0; +} diff --git a/drivers/staging/ti-st/st_ll.h b/drivers/staging/ti-st/st_ll.h new file mode 100644 index 000000000000..77dfbf07e7b8 --- /dev/null +++ b/drivers/staging/ti-st/st_ll.h @@ -0,0 +1,62 @@ +/* + * Shared Transport Low Level (ST LL) + * + * Copyright (C) 2009 Texas Instruments + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef ST_LL_H +#define ST_LL_H + +#include +#include "st.h" +#include "st_core.h" + +/* ST LL receiver states */ +#define ST_W4_PACKET_TYPE 0 +#define ST_BT_W4_EVENT_HDR 1 +#define ST_BT_W4_ACL_HDR 2 +#define ST_BT_W4_SCO_HDR 3 +#define ST_BT_W4_DATA 4 +#define ST_FM_W4_EVENT_HDR 5 +#define ST_GPS_W4_EVENT_HDR 6 + +/* ST LL state machines */ +#define ST_LL_ASLEEP 0 +#define ST_LL_ASLEEP_TO_AWAKE 1 +#define ST_LL_AWAKE 2 +#define ST_LL_AWAKE_TO_ASLEEP 3 +#define ST_LL_INVALID 4 + +#define LL_SLEEP_IND 0x30 +#define LL_SLEEP_ACK 0x31 +#define LL_WAKE_UP_IND 0x32 +#define LL_WAKE_UP_ACK 0x33 + +/* initialize and de-init ST LL */ +long st_ll_init(struct st_data_s *); +long st_ll_deinit(struct st_data_s *); + +/* enable/disable ST LL along with KIM start/stop + * called by ST Core + */ +void st_ll_enable(struct st_data_s *); +void st_ll_disable(struct st_data_s *); + +unsigned long st_ll_getstate(struct st_data_s *); +unsigned long st_ll_sleep_state(struct st_data_s *, unsigned char); +void st_ll_wakeup(struct st_data_s *); +#endif /* ST_LL_H */ -- cgit v1.2.3 From 69f6e06db92dd7e2e87be58a4e2ab3a8104f8ce6 Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Thu, 8 Apr 2010 13:16:56 -0500 Subject: Staging: sources for ST header file Texas Instruments BT, FM and GPS combo chips/drivers make use of a single TTY to communicate with the chip. This is the common header file for both the ST driver and the protocol drivers which intend to use ST as their mode of transport. Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ti-st/fm.h | 13 +++++++ drivers/staging/ti-st/st.h | 90 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 drivers/staging/ti-st/fm.h create mode 100644 drivers/staging/ti-st/st.h (limited to 'drivers') diff --git a/drivers/staging/ti-st/fm.h b/drivers/staging/ti-st/fm.h new file mode 100644 index 000000000000..be41453649ed --- /dev/null +++ b/drivers/staging/ti-st/fm.h @@ -0,0 +1,13 @@ +struct fm_event_hdr { + unsigned char plen; +} __attribute__ ((packed)); + +#define FM_MAX_FRAME_SIZE 0xFF /* TODO: */ +#define FM_EVENT_HDR_SIZE 1 /* size of fm_event_hdr */ +#define ST_FM_CH8_PKT 0x8 + +/* gps stuff */ +struct gps_event_hdr { +unsigned char opcode; +unsigned short plen; +} __attribute__ ((packed)); diff --git a/drivers/staging/ti-st/st.h b/drivers/staging/ti-st/st.h new file mode 100644 index 000000000000..e8fc97e32c94 --- /dev/null +++ b/drivers/staging/ti-st/st.h @@ -0,0 +1,90 @@ +/* + * Shared Transport Header file + * To be included by the protocol stack drivers for + * Texas Instruments BT,FM and GPS combo chip drivers + * + * Copyright (C) 2009 Texas Instruments + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef ST_H +#define ST_H + +#include +/* + * st.h + */ + +/* TODO: + * Move the following to tty.h upon acceptance + */ +#define N_TI_WL 20 /* Ldisc for TI's WL BT, FM, GPS combo chips */ + +/* some gpios have active high, others like fm have + * active low + */ +enum kim_gpio_state { + KIM_GPIO_INACTIVE, + KIM_GPIO_ACTIVE, +}; +/* + * the list of protocols on chip + */ +enum proto_type { + ST_BT, + ST_FM, + ST_GPS, + ST_MAX, +}; + +enum { + ST_ERR_FAILURE = -1, /* check struct */ + ST_SUCCESS, + ST_ERR_PENDING = -5, /* to call reg_complete_cb */ + ST_ERR_ALREADY, /* already registered */ + ST_ERR_INPROGRESS, + ST_ERR_NOPROTO, /* protocol not supported */ +}; + +/* per protocol structure + * for BT/FM and GPS + */ +struct st_proto_s { + enum proto_type type; +/* + * to be called by ST when data arrives + */ + long (*recv) (struct sk_buff *); +/* + * for future use, logic now to be in ST + */ + unsigned char (*match_packet) (const unsigned char *data); +/* + * subsequent registration return PENDING, + * signalled complete by this callback function + */ + void (*reg_complete_cb) (char data); +/* + * write function, sent in as NULL and to be returned to + * protocol drivers + */ + long (*write) (struct sk_buff *skb); +}; + +extern long st_register(struct st_proto_s *new_proto); +extern long st_unregister(enum proto_type type); + +#endif /* ST_H */ -- cgit v1.2.3 From dfcbb616e8dd98a0121fba4c9f9aa65f40f6f268 Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Thu, 8 Apr 2010 13:16:58 -0500 Subject: Staging: add TODO and ABI to ti-st A TODO file and a ABI to list the things to be done, and user-space/kernel-space interface for this ldisc. Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ti-st/TODO | 19 +++++++++++++++++++ drivers/staging/ti-st/sysfs-uim | 16 ++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 drivers/staging/ti-st/TODO create mode 100644 drivers/staging/ti-st/sysfs-uim (limited to 'drivers') diff --git a/drivers/staging/ti-st/TODO b/drivers/staging/ti-st/TODO new file mode 100644 index 000000000000..2c4fe583901d --- /dev/null +++ b/drivers/staging/ti-st/TODO @@ -0,0 +1,19 @@ +TODO: + +1. A per-device/tty port context required to support multiple devices +on same platform. + +2. REMOVE the sysfs entry PID passing mechanism, since there should +be a better way to request user-space to install line discipline. + +3. Re-view/Re-work on the locking. + +4. Re-structure to make the ldisc driver more generic for chipsets which mux +multiple connectivity (BT, FM, GPS) upon 1 TTY port. + +5. Step up and maintain this driver to ensure that it continues +to work. Having the hardware for this is pretty much a +requirement. If this does not happen, the will be removed in +the 2.6.35 kernel release. + +Please send patches to Greg Kroah-Hartman . diff --git a/drivers/staging/ti-st/sysfs-uim b/drivers/staging/ti-st/sysfs-uim new file mode 100644 index 000000000000..10311afcbd45 --- /dev/null +++ b/drivers/staging/ti-st/sysfs-uim @@ -0,0 +1,16 @@ +What: /sys/class/rfkill/rfkill%d/ +Date: March 22 +Contact: Pavan Savoy +Description: + Creates the rfkill entries for Radio apps like + BT app, FM app or GPS app to toggle corresponding + cores of the chip + +What: /dev/rfkill +Date: March 22 +Contact: Pavan Savoy +Description: + A daemon which maintains the ldisc installation and + uninstallation would be ppolling on this device and listening + on events which would suggest either to install or un-install + line discipline -- cgit v1.2.3 From 70ddf80ac4a32fa1d5e3faba52385a9ab691b16b Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Thu, 8 Apr 2010 13:16:59 -0500 Subject: Staging: bluetooth: BT driver using ST for TI combo devices This is BlueZ driver making use of Shared Transport line discipline to communicate with the chip. Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ti-st/bt_drv.c | 502 +++++++++++++++++++++++++++++++++++++++++ drivers/staging/ti-st/bt_drv.h | 61 +++++ 2 files changed, 563 insertions(+) create mode 100644 drivers/staging/ti-st/bt_drv.c create mode 100644 drivers/staging/ti-st/bt_drv.h (limited to 'drivers') diff --git a/drivers/staging/ti-st/bt_drv.c b/drivers/staging/ti-st/bt_drv.c new file mode 100644 index 000000000000..d8420b5c91fa --- /dev/null +++ b/drivers/staging/ti-st/bt_drv.c @@ -0,0 +1,502 @@ +/* + * Texas Instrument's Bluetooth Driver For Shared Transport. + * + * Bluetooth Driver acts as interface between HCI CORE and + * TI Shared Transport Layer. + * + * Copyright (C) 2009 Texas Instruments + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include + +#include "st.h" +#include "bt_drv.h" + +/* Define this macro to get debug msg */ +#undef DEBUG + +#ifdef DEBUG +#define BT_DRV_DBG(fmt, arg...) printk(KERN_INFO "(btdrv):"fmt"\n" , ## arg) +#define BTDRV_API_START() printk(KERN_INFO "(btdrv): %s Start\n", \ + __func__) +#define BTDRV_API_EXIT(errno) printk(KERN_INFO "(btdrv): %s Exit(%d)\n", \ + __func__, errno) +#else +#define BT_DRV_DBG(fmt, arg...) +#define BTDRV_API_START() +#define BTDRV_API_EXIT(errno) +#endif + +#define BT_DRV_ERR(fmt, arg...) printk(KERN_ERR "(btdrv):"fmt"\n" , ## arg) + +static int reset; +static struct hci_st *hst; + +/* Increments HCI counters based on pocket ID (cmd,acl,sco) */ +static inline void hci_st_tx_complete(struct hci_st *hst, int pkt_type) +{ + struct hci_dev *hdev; + + BTDRV_API_START(); + + hdev = hst->hdev; + + /* Update HCI stat counters */ + switch (pkt_type) { + case HCI_COMMAND_PKT: + hdev->stat.cmd_tx++; + break; + + case HCI_ACLDATA_PKT: + hdev->stat.acl_tx++; + break; + + case HCI_SCODATA_PKT: + hdev->stat.cmd_tx++; + break; + } + + BTDRV_API_EXIT(0); +} + +/* ------- Interfaces to Shared Transport ------ */ + +/* Called by ST layer to indicate protocol registration completion + * status.hci_st_open() function will wait for signal from this + * API when st_register() function returns ST_PENDING. + */ +static void hci_st_registration_completion_cb(char data) +{ + BTDRV_API_START(); + + /* hci_st_open() function needs value of 'data' to know + * the registration status(success/fail),So have a back + * up of it. + */ + hst->streg_cbdata = data; + + /* Got a feedback from ST for BT driver registration + * request.Wackup hci_st_open() function to continue + * it's open operation. + */ + complete(&hst->wait_for_btdrv_reg_completion); + + BTDRV_API_EXIT(0); +} + +/* Called by Shared Transport layer when receive data is + * available */ +static long hci_st_receive(struct sk_buff *skb) +{ + int err; + int len; + + BTDRV_API_START(); + + err = 0; + len = 0; + + if (skb == NULL) { + BT_DRV_ERR("Invalid SKB received from ST"); + BTDRV_API_EXIT(-EFAULT); + return -EFAULT; + } + if (!hst) { + kfree_skb(skb); + BT_DRV_ERR("Invalid hci_st memory,freeing SKB"); + BTDRV_API_EXIT(-EFAULT); + return -EFAULT; + } + if (!test_bit(BT_DRV_RUNNING, &hst->flags)) { + kfree_skb(skb); + BT_DRV_ERR("Device is not running,freeing SKB"); + BTDRV_API_EXIT(-EINVAL); + return -EINVAL; + } + + len = skb->len; + skb->dev = (struct net_device *)hst->hdev; + + /* Forward skb to HCI CORE layer */ + err = hci_recv_frame(skb); + if (err) { + kfree_skb(skb); + BT_DRV_ERR("Unable to push skb to HCI CORE(%d),freeing SKB", + err); + BTDRV_API_EXIT(err); + return err; + } + hst->hdev->stat.byte_rx += len; + + BTDRV_API_EXIT(0); + return 0; +} + +/* ------- Interfaces to HCI layer ------ */ + +/* Called from HCI core to initialize the device */ +static int hci_st_open(struct hci_dev *hdev) +{ + static struct st_proto_s hci_st_proto; + unsigned long timeleft; + int err; + + BTDRV_API_START(); + + err = 0; + + BT_DRV_DBG("%s %p", hdev->name, hdev); + + /* Already registered with ST ? */ + if (test_bit(BT_ST_REGISTERED, &hst->flags)) { + BT_DRV_ERR("Registered with ST already,open called again?"); + BTDRV_API_EXIT(0); + return 0; + } + + /* Populate BT driver info required by ST */ + memset(&hci_st_proto, 0, sizeof(hci_st_proto)); + + /* BT driver ID */ + hci_st_proto.type = ST_BT; + + /* Receive function which called from ST */ + hci_st_proto.recv = hci_st_receive; + + /* Packet match function may used in future */ + hci_st_proto.match_packet = NULL; + + /* Callback to be called when registration is pending */ + hci_st_proto.reg_complete_cb = hci_st_registration_completion_cb; + + /* This is write function pointer of ST. BT driver will make use of this + * for sending any packets to chip. ST will assign and give to us, so + * make it as NULL */ + hci_st_proto.write = NULL; + + /* Register with ST layer */ + err = st_register(&hci_st_proto); + if (err == ST_ERR_PENDING) { + /* Prepare wait-for-completion handler data structures. + * Needed to syncronize this and st_registration_completion_cb() + * functions. + */ + init_completion(&hst->wait_for_btdrv_reg_completion); + + /* Reset ST registration callback status flag , this value + * will be updated in hci_st_registration_completion_cb() + * function whenever it called from ST driver. + */ + hst->streg_cbdata = -EINPROGRESS; + + /* ST is busy with other protocol registration(may be busy with + * firmware download).So,Wait till the registration callback + * (passed as a argument to st_register() function) getting + * called from ST. + */ + BT_DRV_DBG(" %s waiting for reg completion signal from ST", + __func__); + + timeleft = + wait_for_completion_timeout + (&hst->wait_for_btdrv_reg_completion, + msecs_to_jiffies(BT_REGISTER_TIMEOUT)); + if (!timeleft) { + BT_DRV_ERR("Timeout(%ld sec),didn't get reg" + "completion signal from ST", + BT_REGISTER_TIMEOUT / 1000); + BTDRV_API_EXIT(-ETIMEDOUT); + return -ETIMEDOUT; + } + + /* Is ST registration callback called with ERROR value? */ + if (hst->streg_cbdata != 0) { + BT_DRV_ERR("ST reg completion CB called with invalid" + "status %d", hst->streg_cbdata); + BTDRV_API_EXIT(-EAGAIN); + return -EAGAIN; + } + err = 0; + } else if (err == ST_ERR_FAILURE) { + BT_DRV_ERR("st_register failed %d", err); + BTDRV_API_EXIT(-EAGAIN); + return -EAGAIN; + } + + /* Do we have proper ST write function? */ + if (hci_st_proto.write != NULL) { + /* We need this pointer for sending any Bluetooth pkts */ + hst->st_write = hci_st_proto.write; + } else { + BT_DRV_ERR("failed to get ST write func pointer"); + + /* Undo registration with ST */ + err = st_unregister(ST_BT); + if (err < 0) + BT_DRV_ERR("st_unregister failed %d", err); + + hst->st_write = NULL; + BTDRV_API_EXIT(-EAGAIN); + return -EAGAIN; + } + + /* Registration with ST layer is completed successfully, + * now chip is ready to accept commands from HCI CORE. + * Mark HCI Device flag as RUNNING + */ + set_bit(HCI_RUNNING, &hdev->flags); + + /* Registration with ST successful */ + set_bit(BT_ST_REGISTERED, &hst->flags); + + BTDRV_API_EXIT(err); + return err; +} + +/* Close device */ +static int hci_st_close(struct hci_dev *hdev) +{ + int err; + + BTDRV_API_START(); + + err = 0; + + /* Unregister from ST layer */ + if (test_and_clear_bit(BT_ST_REGISTERED, &hst->flags)) { + err = st_unregister(ST_BT); + if (err != ST_SUCCESS) { + BT_DRV_ERR("st_unregister failed %d", err); + BTDRV_API_EXIT(-EBUSY); + return -EBUSY; + } + } + + hst->st_write = NULL; + + /* ST layer would have moved chip to inactive state. + * So,clear HCI device RUNNING flag. + */ + if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) { + BTDRV_API_EXIT(0); + return 0; + } + + BTDRV_API_EXIT(err); + return err; +} + +/* Called from HCI CORE , Sends frames to Shared Transport */ +static int hci_st_send_frame(struct sk_buff *skb) +{ + struct hci_dev *hdev; + struct hci_st *hst; + long len; + + BTDRV_API_START(); + + if (skb == NULL) { + BT_DRV_ERR("Invalid skb received from HCI CORE"); + BTDRV_API_EXIT(-ENOMEM); + return -ENOMEM; + } + hdev = (struct hci_dev *)skb->dev; + if (!hdev) { + BT_DRV_ERR("SKB received for invalid HCI Device (hdev=NULL)"); + BTDRV_API_EXIT(-ENODEV); + return -ENODEV; + } + if (!test_bit(HCI_RUNNING, &hdev->flags)) { + BT_DRV_ERR("Device is not running"); + BTDRV_API_EXIT(-EBUSY); + return -EBUSY; + } + + hst = (struct hci_st *)hdev->driver_data; + + /* Prepend skb with frame type */ + memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); + + BT_DRV_DBG(" %s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, + skb->len); + + /* Insert skb to shared transport layer's transmit queue. + * Freeing skb memory is taken care in shared transport layer, + * so don't free skb memory here. + */ + if (!hst->st_write) { + kfree_skb(skb); + BT_DRV_ERR(" Can't write to ST, st_write null?"); + BTDRV_API_EXIT(-EAGAIN); + return -EAGAIN; + } + len = hst->st_write(skb); + if (len < 0) { + /* Something went wrong in st write , free skb memory */ + kfree_skb(skb); + BT_DRV_ERR(" ST write failed (%ld)", len); + BTDRV_API_EXIT(-EAGAIN); + return -EAGAIN; + } + + /* ST accepted our skb. So, Go ahead and do rest */ + hdev->stat.byte_tx += len; + hci_st_tx_complete(hst, bt_cb(skb)->pkt_type); + + BTDRV_API_EXIT(0); + return 0; +} + +static void hci_st_destruct(struct hci_dev *hdev) +{ + BTDRV_API_START(); + + if (!hdev) { + BT_DRV_ERR("Destruct called with invalid HCI Device" + "(hdev=NULL)"); + BTDRV_API_EXIT(0); + return; + } + + BT_DRV_DBG("%s", hdev->name); + + /* free hci_st memory */ + if (hdev->driver_data != NULL) + kfree(hdev->driver_data); + + BTDRV_API_EXIT(0); + return; +} + +/* Creates new HCI device */ +static int hci_st_register_dev(struct hci_st *hst) +{ + struct hci_dev *hdev; + + BTDRV_API_START(); + + /* Initialize and register HCI device */ + hdev = hci_alloc_dev(); + if (!hdev) { + BT_DRV_ERR("Can't allocate HCI device"); + BTDRV_API_EXIT(-ENOMEM); + return -ENOMEM; + } + BT_DRV_DBG(" HCI device allocated. hdev= %p", hdev); + + hst->hdev = hdev; + hdev->bus = HCI_UART; + hdev->driver_data = hst; + hdev->open = hci_st_open; + hdev->close = hci_st_close; + hdev->flush = NULL; + hdev->send = hci_st_send_frame; + hdev->destruct = hci_st_destruct; + hdev->owner = THIS_MODULE; + + if (reset) + set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); + + if (hci_register_dev(hdev) < 0) { + BT_DRV_ERR("Can't register HCI device"); + hci_free_dev(hdev); + BTDRV_API_EXIT(-ENODEV); + return -ENODEV; + } + + BT_DRV_DBG(" HCI device registered. hdev= %p", hdev); + BTDRV_API_EXIT(0); + return 0; +} + +/* ------- Module Init interface ------ */ + +static int __init bt_drv_init(void) +{ + int err; + + BTDRV_API_START(); + + err = 0; + + BT_DRV_DBG(" Bluetooth Driver Version %s", VERSION); + + /* Allocate local resource memory */ + hst = kzalloc(sizeof(struct hci_st), GFP_KERNEL); + if (!hst) { + BT_DRV_ERR("Can't allocate control structure"); + BTDRV_API_EXIT(-ENFILE); + return -ENFILE; + } + + /* Expose "hciX" device to user space */ + err = hci_st_register_dev(hst); + if (err) { + /* Release local resource memory */ + kfree(hst); + + BT_DRV_ERR("Unable to expose hci0 device(%d)", err); + BTDRV_API_EXIT(err); + return err; + } + set_bit(BT_DRV_RUNNING, &hst->flags); + + BTDRV_API_EXIT(err); + return err; +} + +/* ------- Module Exit interface ------ */ + +static void __exit bt_drv_exit(void) +{ + BTDRV_API_START(); + + /* Deallocate local resource's memory */ + if (hst) { + struct hci_dev *hdev = hst->hdev; + + if (hdev == NULL) { + BT_DRV_ERR("Invalid hdev memory"); + kfree(hst); + } else { + hci_st_close(hdev); + if (test_and_clear_bit(BT_DRV_RUNNING, &hst->flags)) { + /* Remove HCI device (hciX) created + * in module init. + */ + hci_unregister_dev(hdev); + + /* Free HCI device memory */ + hci_free_dev(hdev); + } + } + } + BTDRV_API_EXIT(0); +} + +module_init(bt_drv_init); +module_exit(bt_drv_exit); + +/* ------ Module Info ------ */ + +module_param(reset, bool, 0644); +MODULE_PARM_DESC(reset, "Send HCI reset command on initialization"); +MODULE_AUTHOR("Raja Mani "); +MODULE_DESCRIPTION("Bluetooth Driver for TI Shared Transport" VERSION); +MODULE_VERSION(VERSION); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/ti-st/bt_drv.h b/drivers/staging/ti-st/bt_drv.h new file mode 100644 index 000000000000..a0beebec8465 --- /dev/null +++ b/drivers/staging/ti-st/bt_drv.h @@ -0,0 +1,61 @@ +/* + * Texas Instrument's Bluetooth Driver For Shared Transport. + * + * Bluetooth Driver acts as interface between HCI CORE and + * TI Shared Transport Layer. + * + * Copyright (C) 2009 Texas Instruments + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _BT_DRV_H +#define _BT_DRV_H + +/* Bluetooth Driver Version */ +#define VERSION "1.0" + +/* Defines number of seconds to wait for reg completion + * callback getting called from ST (in case,registration + * with ST returns PENDING status) + */ +#define BT_REGISTER_TIMEOUT msecs_to_jiffies(6000) /* 6 sec */ + +/* BT driver's local status */ +#define BT_DRV_RUNNING 0 +#define BT_ST_REGISTERED 1 + +/* BT driver operation structure */ +struct hci_st { + + /* hci device pointer which binds to bt driver */ + struct hci_dev *hdev; + + /* used locally,to maintain various BT driver status */ + unsigned long flags; + + /* to hold ST registration callback status */ + char streg_cbdata; + + /* write function pointer of ST driver */ + long (*st_write) (struct sk_buff *); + + /* Wait on comepletion handler needed to synchronize + * hci_st_open() and hci_st_registration_completion_cb() + * functions.*/ + struct completion wait_for_btdrv_reg_completion; +}; + +#endif -- cgit v1.2.3 From 2f6aee5646f4f0ac2a83b0e95eff055364142a24 Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Thu, 8 Apr 2010 13:16:57 -0500 Subject: Staging: Kconfig, Makefile for TI's ST ldisc This change adds the Kconfig and Make file for TI's ST line discipline driver and the BlueZ driver for BT core of the TI BT/FM/GPS combo chip. Signed-off-by: Pavan Savoy --- drivers/staging/Kconfig | 2 ++ drivers/staging/Makefile | 1 + drivers/staging/ti-st/Kconfig | 24 ++++++++++++++++++++++++ drivers/staging/ti-st/Makefile | 7 +++++++ 4 files changed, 34 insertions(+) create mode 100644 drivers/staging/ti-st/Kconfig create mode 100644 drivers/staging/ti-st/Makefile (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 597e10987476..d97e46e60d91 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -141,5 +141,7 @@ source "drivers/staging/crystalhd/Kconfig" source "drivers/staging/cxt1e1/Kconfig" +source "drivers/staging/ti-st/Kconfig" + endif # !STAGING_EXCLUDE_BUILD endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 6edd9b09c2d0..23e353a411d7 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -52,3 +52,4 @@ obj-$(CONFIG_FB_SM7XX) += sm7xx/ obj-$(CONFIG_DT3155) += dt3155/ obj-$(CONFIG_CRYSTALHD) += crystalhd/ obj-$(CONFIG_CXT1E1) += cxt1e1/ +obj-$(CONFIG_TI_ST) += ti-st/ diff --git a/drivers/staging/ti-st/Kconfig b/drivers/staging/ti-st/Kconfig new file mode 100644 index 000000000000..120e8db1368b --- /dev/null +++ b/drivers/staging/ti-st/Kconfig @@ -0,0 +1,24 @@ +# +# TI's shared transport line discipline and the protocol +# drivers (BT, FM and GPS) +# +menu "Texas Instruments shared transport line discipline" +config TI_ST + tristate "shared transport core driver" + select FW_LOADER + help + This enables the shared transport core driver for TI + BT / FM and GPS combo chips. This enables protocol drivers + to register themselves with core and send data, the responses + are returned to relevant protocol drivers based on their + packet types. + +config ST_BT + tristate "BlueZ bluetooth driver for ST" + depends on BT + select TI_ST + help + This enables the Bluetooth driver for TI BT/FM/GPS combo devices. + This makes use of shared transport line discipline core driver to + communicate with the BT core of the combo chip. +endmenu diff --git a/drivers/staging/ti-st/Makefile b/drivers/staging/ti-st/Makefile new file mode 100644 index 000000000000..0167d1d2c255 --- /dev/null +++ b/drivers/staging/ti-st/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for TI's shared transport line discipline +# and its protocol drivers (BT, FM, GPS) +# +obj-$(CONFIG_TI_ST) += st_drv.o +st_drv-objs := st_core.o st_kim.o st_ll.o +obj-$(CONFIG_ST_BT) += bt_drv.o -- cgit v1.2.3 From 26e5b65b0794a1970ab09b65ef39beb9058ec952 Mon Sep 17 00:00:00 2001 From: Andres More Date: Tue, 13 Apr 2010 19:43:07 -0300 Subject: Staging: vt6656: struct usb_driver cleanup Code cleanup following other USB drivers: - Renamed driver struct and callbacks to vt6656_* - Added __init/__exit like directives - Resolved checkpatch.pl findings on those lines Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/main_usb.c | 72 +++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index f15e7b48fe0d..ea6c94d6a99f 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -26,7 +26,7 @@ * * Functions: * - * vntwusb_found1 - module initial (insmod) driver entry + * vt6656_probe - module initial (insmod) driver entry * device_remove1 - module remove entry * device_open - allocate dma/descripter resource & initial mac/bbp function * device_xmit - asynchrous data tx function @@ -222,15 +222,11 @@ DEVICE_PARAM(b80211hEnable, "802.11h mode"); // Static vars definitions // - - -static struct usb_device_id vntwusb_table[] = { +static struct usb_device_id vt6656_table[] __devinitdata = { {USB_DEVICE(VNT_USB_VENDOR_ID, VNT_USB_PRODUCT_ID)}, {} }; - - // Frequency list (map channels to frequencies) /* static const long frequency_list[] = { @@ -250,15 +246,17 @@ static const long frequency_list[] = { static const struct iw_handler_def iwctl_handler_def; */ +/*--------------------- Static Functions --------------------------*/ +static int vt6656_probe(struct usb_interface *intf, + const struct usb_device_id *id); +static void vt6656_disconnect(struct usb_interface *intf); -/*--------------------- Static Functions --------------------------*/ -static int vntwusb_found1(struct usb_interface *intf, const struct usb_device_id *id); -static void vntwusb_disconnect(struct usb_interface *intf); #ifdef CONFIG_PM /* Minimal support for suspend and resume */ -static int vntwusb_suspend(struct usb_interface *intf, pm_message_t message); -static int vntwusb_resume(struct usb_interface *intf); -#endif +static int vt6656_suspend(struct usb_interface *intf, pm_message_t message); +static int vt6656_resume(struct usb_interface *intf); +#endif /* CONFIG_PM */ + static struct net_device_stats *device_get_stats(struct net_device *dev); static int device_open(struct net_device *dev); static int device_xmit(struct sk_buff *skb, struct net_device *dev); @@ -712,7 +710,8 @@ static BOOL device_release_WPADEV(PSDevice pDevice) } #ifdef CONFIG_PM /* Minimal support for suspend and resume */ -static int vntwusb_suspend(struct usb_interface *intf, pm_message_t message) + +static int vt6656_suspend(struct usb_interface *intf, pm_message_t message) { PSDevice pDevice = usb_get_intfdata(intf); struct net_device *dev = pDevice->dev; @@ -727,7 +726,7 @@ if(dev != NULL) { return 0; } -static int vntwusb_resume(struct usb_interface *intf) +static int vt6656_resume(struct usb_interface *intf) { PSDevice pDevice = usb_get_intfdata(intf); struct net_device *dev = pDevice->dev; @@ -742,8 +741,8 @@ static int vntwusb_resume(struct usb_interface *intf) } return 0; } -#endif +#endif /* CONFIG_PM */ static const struct net_device_ops device_netdev_ops = { .ndo_open = device_open, @@ -755,8 +754,8 @@ static const struct net_device_ops device_netdev_ops = { }; -static int -vntwusb_found1(struct usb_interface *intf, const struct usb_device_id *id) +static int __devinit +vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id) { BYTE fake_mac[U_ETHER_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01};//fake MAC address struct usb_device *udev = interface_to_usbdev(intf); @@ -1285,8 +1284,7 @@ device_release_WPADEV(pDevice); } -static void vntwusb_disconnect(struct usb_interface *intf) - +static void __devexit vt6656_disconnect(struct usb_interface *intf) { PSDevice pDevice = usb_get_intfdata(intf); @@ -2157,35 +2155,29 @@ static int ethtool_ioctl(struct net_device *dev, void *useraddr) /*------------------------------------------------------------------*/ +MODULE_DEVICE_TABLE(usb, vt6656_table); -MODULE_DEVICE_TABLE(usb, vntwusb_table); - - -static struct usb_driver vntwusb_driver = { - .name = DEVICE_NAME, - .probe = vntwusb_found1, - .disconnect = vntwusb_disconnect, - .id_table = vntwusb_table, - -//2008-0920-01by MikeLiu -//for supporting S3 & S4 function +static struct usb_driver vt6656_driver = { + .name = DEVICE_NAME, + .probe = vt6656_probe, + .disconnect = vt6656_disconnect, + .id_table = vt6656_table, #ifdef CONFIG_PM - .suspend = vntwusb_suspend, - .resume = vntwusb_resume, -#endif + .suspend = vt6656_suspend, + .resume = vt6656_resume, +#endif /* CONFIG_PM */ }; -static int __init vntwusb_init_module(void) +static int __init vt6656_init_module(void) { printk(KERN_NOTICE DEVICE_FULL_DRV_NAM " " DEVICE_VERSION); - return usb_register(&vntwusb_driver); + return usb_register(&vt6656_driver); } -static void __exit vntwusb_cleanup_module(void) +static void __exit vt6656_cleanup_module(void) { - usb_deregister(&vntwusb_driver); + usb_deregister(&vt6656_driver); } -module_init(vntwusb_init_module); -module_exit(vntwusb_cleanup_module); - +module_init(vt6656_init_module); +module_exit(vt6656_cleanup_module); -- cgit v1.2.3 From 9a0e756c5280750c23bd44d2b855a1f5442ea7b4 Mon Sep 17 00:00:00 2001 From: Andres More Date: Tue, 13 Apr 2010 21:54:48 -0300 Subject: Staging: vt6656: incorporated ETH_ALEN macro instead of custom one Replaced custom U_ETHER_ADDR_LEN by ETH_ALEN from . Resolved checkpatch findings on the changed lines, mostly indentation. Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/aes_ccmp.c | 11 +- drivers/staging/vt6656/desc.h | 6 +- drivers/staging/vt6656/device.h | 22 ++-- drivers/staging/vt6656/dpc.c | 85 ++++++++------- drivers/staging/vt6656/ioctl.c | 4 +- drivers/staging/vt6656/key.c | 4 +- drivers/staging/vt6656/key.h | 2 +- drivers/staging/vt6656/main_usb.c | 41 +++---- drivers/staging/vt6656/mib.c | 19 ++-- drivers/staging/vt6656/mib.h | 4 +- drivers/staging/vt6656/rxtx.c | 218 ++++++++++++++++++++++++-------------- drivers/staging/vt6656/rxtx.h | 6 +- drivers/staging/vt6656/tether.c | 2 +- drivers/staging/vt6656/tether.h | 22 ++-- drivers/staging/vt6656/wctl.c | 6 +- drivers/staging/vt6656/wmgr.c | 52 +++++---- drivers/staging/vt6656/wpa2.c | 31 +++--- drivers/staging/vt6656/wpactl.c | 2 +- 18 files changed, 310 insertions(+), 227 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/aes_ccmp.c b/drivers/staging/vt6656/aes_ccmp.c index 401a7d267c90..a1beaa93b333 100644 --- a/drivers/staging/vt6656/aes_ccmp.c +++ b/drivers/staging/vt6656/aes_ccmp.c @@ -277,7 +277,7 @@ int ii,jj,kk; pbyPayload = pbyIV + 8; //IV-length abyNonce[0] = 0x00; //now is 0, if Qos here will be priority - memcpy(&(abyNonce[1]), pMACHeader->abyAddr2, U_ETHER_ADDR_LEN); + memcpy(&(abyNonce[1]), pMACHeader->abyAddr2, ETH_ALEN); abyNonce[7] = pbyIV[7]; abyNonce[8] = pbyIV[6]; abyNonce[9] = pbyIV[5]; @@ -299,16 +299,17 @@ int ii,jj,kk; byTmp = (BYTE)(pMACHeader->wFrameCtl >> 8); byTmp &= 0x87; MIC_HDR1[3] = byTmp | 0x40; - memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, U_ETHER_ADDR_LEN); - memcpy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, U_ETHER_ADDR_LEN); + memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, ETH_ALEN); + memcpy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, ETH_ALEN); //MIC_HDR2 - memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, U_ETHER_ADDR_LEN); + memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, ETH_ALEN); byTmp = (BYTE)(pMACHeader->wSeqCtl & 0xff); MIC_HDR2[6] = byTmp & 0x0f; MIC_HDR2[7] = 0; + if ( bA4 ) { - memcpy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, U_ETHER_ADDR_LEN); + memcpy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, ETH_ALEN); } else { MIC_HDR2[8] = 0x00; MIC_HDR2[9] = 0x00; diff --git a/drivers/staging/vt6656/desc.h b/drivers/staging/vt6656/desc.h index f10530fcc99b..c87ea6b4d864 100644 --- a/drivers/staging/vt6656/desc.h +++ b/drivers/staging/vt6656/desc.h @@ -206,8 +206,8 @@ typedef const SRrvTime_atim *PCSRrvTime_atim; typedef struct tagSRTSData { WORD wFrameControl; WORD wDurationID; - BYTE abyRA[U_ETHER_ADDR_LEN]; - BYTE abyTA[U_ETHER_ADDR_LEN]; + BYTE abyRA[ETH_ALEN]; + BYTE abyTA[ETH_ALEN]; }__attribute__ ((__packed__)) SRTSData, *PSRTSData; typedef const SRTSData *PCSRTSData; @@ -282,7 +282,7 @@ typedef const SRTS_a_FB *PCSRTS_a_FB; typedef struct tagSCTSData { WORD wFrameControl; WORD wDurationID; - BYTE abyRA[U_ETHER_ADDR_LEN]; + BYTE abyRA[ETH_ALEN]; WORD wReserved; }__attribute__ ((__packed__)) SCTSData, *PSCTSData; diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index 8b541d1d0e23..29bb5977541c 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -107,7 +107,7 @@ #define MAC_MAX_CONTEXT_REG (256+128) #define MAX_MULTICAST_ADDRESS_NUM 32 -#define MULTICAST_ADDRESS_LIST_SIZE (MAX_MULTICAST_ADDRESS_NUM * U_ETHER_ADDR_LEN) +#define MULTICAST_ADDRESS_LIST_SIZE (MAX_MULTICAST_ADDRESS_NUM * ETH_ALEN) //#define OP_MODE_INFRASTRUCTURE 0 @@ -369,7 +369,7 @@ typedef struct tagSQuietControl { // The receive duplicate detection cache entry typedef struct tagSCacheEntry{ WORD wFmSequence; - BYTE abyAddr2[U_ETHER_ADDR_LEN]; + BYTE abyAddr2[ETH_ALEN]; WORD wFrameCtl; } SCacheEntry, *PSCacheEntry; @@ -387,7 +387,7 @@ typedef struct tagSDeFragControlBlock { WORD wSequence; WORD wFragNum; - BYTE abyAddr2[U_ETHER_ADDR_LEN]; + BYTE abyAddr2[ETH_ALEN]; UINT uLifetime; struct sk_buff* skb; PBYTE pbyRxBuffer; @@ -547,10 +547,10 @@ typedef struct __device_info { BYTE byOriginalZonetype; BOOL bLinkPass; // link status: OK or fail - BYTE abyCurrentNetAddr[U_ETHER_ADDR_LEN]; - BYTE abyPermanentNetAddr[U_ETHER_ADDR_LEN]; + BYTE abyCurrentNetAddr[ETH_ALEN]; + BYTE abyPermanentNetAddr[ETH_ALEN]; // SW network address -// BYTE abySoftwareNetAddr[U_ETHER_ADDR_LEN]; + /* u8 abySoftwareNetAddr[ETH_ALEN]; */ BOOL bExistSWNetAddr; // Adapter statistics @@ -671,8 +671,8 @@ typedef struct __device_info { CARD_OP_MODE eOPMode; BOOL bBSSIDFilter; WORD wMaxTransmitMSDULifetime; - BYTE abyBSSID[U_ETHER_ADDR_LEN]; - BYTE abyDesireBSSID[U_ETHER_ADDR_LEN]; + BYTE abyBSSID[ETH_ALEN]; + BYTE abyDesireBSSID[ETH_ALEN]; WORD wCTSDuration; // update while speed change WORD wACKDuration; // update while speed change WORD wRTSTransmitLen; // update while speed change @@ -826,9 +826,9 @@ typedef struct __device_info { SEthernetHeader sTxEthHeader; SEthernetHeader sRxEthHeader; - BYTE abyBroadcastAddr[U_ETHER_ADDR_LEN]; - BYTE abySNAP_RFC1042[U_ETHER_ADDR_LEN]; - BYTE abySNAP_Bridgetunnel[U_ETHER_ADDR_LEN]; + BYTE abyBroadcastAddr[ETH_ALEN]; + BYTE abySNAP_RFC1042[ETH_ALEN]; + BYTE abySNAP_Bridgetunnel[ETH_ALEN]; // Pre-Authentication & PMK cache SPMKID gsPMKID; diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index 835c6d6967bf..9e833bb08e38 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -234,11 +234,11 @@ s_vProcessRxMACHeader ( } } - cbHeaderSize -= (U_ETHER_ADDR_LEN * 2); + cbHeaderSize -= (ETH_ALEN * 2); pbyRxBuffer = (PBYTE) (pbyRxBufferAddr + cbHeaderSize); - for(ii=0;iisRxEthHeader.abyDstAddr[ii]; - for(ii=0;iisRxEthHeader.abySrcAddr[ii]; *pcbHeadSize = cbHeaderSize; @@ -267,43 +267,48 @@ s_vGetDASA ( OUT PSEthernetHeader psEthHeader ) { - UINT cbHeaderSize = 0; - PS802_11Header pMACHeader; - int ii; - - pMACHeader = (PS802_11Header) (pbyRxBufferAddr + cbHeaderSize); - - if ((pMACHeader->wFrameCtl & FC_TODS) == 0) { - if (pMACHeader->wFrameCtl & FC_FROMDS) { - for(ii=0;iiabyDstAddr[ii] = pMACHeader->abyAddr1[ii]; - psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr3[ii]; - } - } - else { - // IBSS mode - for(ii=0;iiabyDstAddr[ii] = pMACHeader->abyAddr1[ii]; - psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii]; - } - } - } - else { - // Is AP mode.. - if (pMACHeader->wFrameCtl & FC_FROMDS) { - for(ii=0;iiabyDstAddr[ii] = pMACHeader->abyAddr3[ii]; - psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr4[ii]; - cbHeaderSize += 6; - } - } - else { - for(ii=0;iiabyDstAddr[ii] = pMACHeader->abyAddr3[ii]; - psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii]; - } - } - }; + UINT cbHeaderSize = 0; + PS802_11Header pMACHeader; + int ii; + + pMACHeader = (PS802_11Header) (pbyRxBufferAddr + cbHeaderSize); + + if ((pMACHeader->wFrameCtl & FC_TODS) == 0) { + if (pMACHeader->wFrameCtl & FC_FROMDS) { + for (ii = 0; ii < ETH_ALEN; ii++) { + psEthHeader->abyDstAddr[ii] = + pMACHeader->abyAddr1[ii]; + psEthHeader->abySrcAddr[ii] = + pMACHeader->abyAddr3[ii]; + } + } else { + /* IBSS mode */ + for (ii = 0; ii < ETH_ALEN; ii++) { + psEthHeader->abyDstAddr[ii] = + pMACHeader->abyAddr1[ii]; + psEthHeader->abySrcAddr[ii] = + pMACHeader->abyAddr2[ii]; + } + } + } else { + /* Is AP mode.. */ + if (pMACHeader->wFrameCtl & FC_FROMDS) { + for (ii = 0; ii < ETH_ALEN; ii++) { + psEthHeader->abyDstAddr[ii] = + pMACHeader->abyAddr3[ii]; + psEthHeader->abySrcAddr[ii] = + pMACHeader->abyAddr4[ii]; + cbHeaderSize += 6; + } + } else { + for (ii = 0; ii < ETH_ALEN; ii++) { + psEthHeader->abyDstAddr[ii] = + pMACHeader->abyAddr3[ii]; + psEthHeader->abySrcAddr[ii] = + pMACHeader->abyAddr2[ii]; + } + } + }; *pcbHeaderSize = cbHeaderSize; } diff --git a/drivers/staging/vt6656/ioctl.c b/drivers/staging/vt6656/ioctl.c index 6f33005a615f..d7a78f2f9f05 100644 --- a/drivers/staging/vt6656/ioctl.c +++ b/drivers/staging/vt6656/ioctl.c @@ -480,7 +480,9 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) { }; if (sValue.dwValue == 1) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "up wpadev\n"); - memcpy(pDevice->wpadev->dev_addr, pDevice->dev->dev_addr, U_ETHER_ADDR_LEN); + memcpy(pDevice->wpadev->dev_addr, + pDevice->dev->dev_addr, + ETH_ALEN); pDevice->bWPADEVUp = TRUE; } else { diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c index 13fc69a1a084..0cd2751d67d5 100644 --- a/drivers/staging/vt6656/key.c +++ b/drivers/staging/vt6656/key.c @@ -312,7 +312,7 @@ BOOL KeybSetKey ( } } if (j < (MAX_KEY_TABLE-1)) { - memcpy(pTable->KeyTable[j].abyBSSID,pbyBSSID,U_ETHER_ADDR_LEN); + memcpy(pTable->KeyTable[j].abyBSSID, pbyBSSID, ETH_ALEN); pTable->KeyTable[j].bInUse = TRUE; if ((dwKeyIndex & PAIRWISE_KEY) != 0) { // Pairwise key @@ -700,7 +700,7 @@ BOOL KeybSetDefaultKey ( } pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = TRUE; - for(ii=0;iiKeyTable[MAX_KEY_TABLE-1].abyBSSID[ii] = 0xFF; // Group key diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h index b15a64cb3868..da8dfe09cf3c 100644 --- a/drivers/staging/vt6656/key.h +++ b/drivers/staging/vt6656/key.h @@ -71,7 +71,7 @@ typedef struct tagSKeyItem typedef struct tagSKeyTable { - BYTE abyBSSID[U_ETHER_ADDR_LEN]; //6 + BYTE abyBSSID[ETH_ALEN]; /* 6 */ BYTE byReserved0[2]; //8 SKeyItem PairwiseKey; SKeyItem GroupKey[MAX_GROUP_KEY]; //64*5 = 320, 320+8=328 diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index ea6c94d6a99f..c0bad4f43ee9 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -295,14 +295,13 @@ static void usb_device_reset(PSDevice pDevice); static void device_set_options(PSDevice pDevice) { - BYTE abyBroadcastAddr[U_ETHER_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - BYTE abySNAP_RFC1042[U_ETHER_ADDR_LEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; - BYTE abySNAP_Bridgetunnel[U_ETHER_ADDR_LEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8}; + BYTE abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + BYTE abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; + u8 abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8}; - - memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, U_ETHER_ADDR_LEN); - memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, U_ETHER_ADDR_LEN); - memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, U_ETHER_ADDR_LEN); + memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN); + memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN); + memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, ETH_ALEN); pDevice->cbTD = TX_DESC_DEF0; pDevice->cbRD = RX_DESC_DEF0; @@ -359,9 +358,9 @@ static VOID device_init_diversity_timer(PSDevice pDevice) { static BOOL device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType) { - BYTE abyBroadcastAddr[U_ETHER_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - BYTE abySNAP_RFC1042[U_ETHER_ADDR_LEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; - BYTE abySNAP_Bridgetunnel[U_ETHER_ADDR_LEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8}; + u8 abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + u8 abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; + u8 abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8}; BYTE byAntenna; UINT ii; CMD_CARD_INIT sInitCmd; @@ -375,10 +374,12 @@ static BOOL device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType) DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---->INIbInitAdapter. [%d][%d]\n", InitType, pDevice->byPacketType); spin_lock_irq(&pDevice->lock); - if (InitType == DEVICE_INIT_COLD) { - memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, U_ETHER_ADDR_LEN); - memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, U_ETHER_ADDR_LEN); - memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, U_ETHER_ADDR_LEN); + if (InitType == DEVICE_INIT_COLD) { + memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN); + memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN); + memcpy(pDevice->abySNAP_Bridgetunnel, + abySNAP_Bridgetunnel, + ETH_ALEN); if ( !FIRMWAREbCheckVersion(pDevice) ) { if (FIRMWAREbDownload(pDevice) == TRUE) { @@ -603,7 +604,9 @@ static BOOL device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType) // get Permanent network address memcpy(pDevice->abyPermanentNetAddr,&(sInitRsp.byNetAddr[0]),6); - memcpy(pDevice->abyCurrentNetAddr, pDevice->abyPermanentNetAddr, U_ETHER_ADDR_LEN); + memcpy(pDevice->abyCurrentNetAddr, + pDevice->abyPermanentNetAddr, + ETH_ALEN); // if exist SW network address, use SW network address. @@ -757,7 +760,7 @@ static const struct net_device_ops device_netdev_ops = { static int __devinit vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id) { - BYTE fake_mac[U_ETHER_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01};//fake MAC address + u8 fake_mac[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; struct usb_device *udev = interface_to_usbdev(intf); int rc = 0; struct net_device *netdev = NULL; @@ -798,7 +801,7 @@ vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id) //2007-0821-01by MikeLiu usb_set_intfdata(intf, pDevice); SET_NETDEV_DEV(netdev, &intf->dev); - memcpy(pDevice->dev->dev_addr, fake_mac, U_ETHER_ADDR_LEN); //use fake mac address + memcpy(pDevice->dev->dev_addr, fake_mac, ETH_ALEN); rc = register_netdev(netdev); if (rc != 0) { printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n"); @@ -1101,8 +1104,8 @@ static int device_open(struct net_device *dev) { // Init for Key Management KeyvInitTable(pDevice,&pDevice->sKey); - memcpy(pDevice->sMgmtObj.abyMACAddr, pDevice->abyCurrentNetAddr, U_ETHER_ADDR_LEN); - memcpy(pDevice->dev->dev_addr, pDevice->abyCurrentNetAddr, U_ETHER_ADDR_LEN); + memcpy(pDevice->sMgmtObj.abyMACAddr, pDevice->abyCurrentNetAddr, ETH_ALEN); + memcpy(pDevice->dev->dev_addr, pDevice->abyCurrentNetAddr, ETH_ALEN); pDevice->bStopTx0Pkt = FALSE; pDevice->bStopDataPkt = FALSE; pDevice->bRoaming = FALSE; //DavidWang diff --git a/drivers/staging/vt6656/mib.c b/drivers/staging/vt6656/mib.c index 910e610b7cc0..b6f138efb472 100644 --- a/drivers/staging/vt6656/mib.c +++ b/drivers/staging/vt6656/mib.c @@ -156,18 +156,17 @@ void STAvUpdateRDStatCounter (PSStatCounter pStatistic, BYTE byRSR, BYTE byNewRSR, BYTE byRxSts, BYTE byRxRate, PBYTE pbyBuffer, UINT cbFrameLength) { - //need change - PS802_11Header pHeader = (PS802_11Header)pbyBuffer; + /* need change */ + PS802_11Header pHeader = (PS802_11Header)pbyBuffer; - if (byRSR & RSR_ADDROK) - pStatistic->dwRsrADDROk++; - if (byRSR & RSR_CRCOK) { - pStatistic->dwRsrCRCOk++; + if (byRSR & RSR_ADDROK) + pStatistic->dwRsrADDROk++; + if (byRSR & RSR_CRCOK) { + pStatistic->dwRsrCRCOk++; + pStatistic->ullRsrOK++; - pStatistic->ullRsrOK++; - - if (cbFrameLength >= U_ETHER_ADDR_LEN) { - // update counters in case that successful transmit + if (cbFrameLength >= ETH_ALEN) { + /* update counters in case of successful transmission */ if (byRSR & RSR_ADDRBROAD) { pStatistic->ullRxBroadcastFrames++; pStatistic->ullRxBroadcastBytes += (ULONGLONG)cbFrameLength; diff --git a/drivers/staging/vt6656/mib.h b/drivers/staging/vt6656/mib.h index ac996d2cd911..d1d781774ca8 100644 --- a/drivers/staging/vt6656/mib.h +++ b/drivers/staging/vt6656/mib.h @@ -91,7 +91,7 @@ typedef struct tagSMib2Counter { LONG ifType; LONG ifMtu; DWORD ifSpeed; - BYTE ifPhysAddress[U_ETHER_ADDR_LEN]; + BYTE ifPhysAddress[ETH_ALEN]; LONG ifAdminStatus; LONG ifOperStatus; DWORD ifLastChange; @@ -231,7 +231,7 @@ typedef struct tagSTxPktInfo { BYTE byBroadMultiUni; WORD wLength; WORD wFIFOCtl; - BYTE abyDestAddr[U_ETHER_ADDR_LEN]; + BYTE abyDestAddr[ETH_ALEN]; } STxPktInfo, *PSTxPktInfo; diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index d9fa36c95230..03b8b4decf09 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -322,7 +322,9 @@ s_vSaveTxPktInfo(PSDevice pDevice, BYTE byPktNum, PBYTE pbyDestAddr, WORD wPktLe pStatistic->abyTxPktInfo[byPktNum].wLength = wPktLength; pStatistic->abyTxPktInfo[byPktNum].wFIFOCtl = wFIFOCtl; - memcpy(pStatistic->abyTxPktInfo[byPktNum].abyDestAddr, pbyDestAddr, U_ETHER_ADDR_LEN); + memcpy(pStatistic->abyTxPktInfo[byPktNum].abyDestAddr, + pbyDestAddr, + ETH_ALEN); } @@ -1026,18 +1028,27 @@ s_vFillRTSHead ( pBuf->Data.wDurationID = pBuf->wDuration_aa; //Get RTS Frame body pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 - if ((pDevice->eOPMode == OP_MODE_ADHOC) || - (pDevice->eOPMode == OP_MODE_AP)) { - memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); - } + + if ((pDevice->eOPMode == OP_MODE_ADHOC) || + (pDevice->eOPMode == OP_MODE_AP)) { + memcpy(&(pBuf->Data.abyRA[0]), + &(psEthHeader->abyDstAddr[0]), + ETH_ALEN); + } else { - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); - } - if (pDevice->eOPMode == OP_MODE_AP) { - memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); - } + memcpy(&(pBuf->Data.abyRA[0]), + &(pDevice->abyBSSID[0]), + ETH_ALEN); + } + if (pDevice->eOPMode == OP_MODE_AP) { + memcpy(&(pBuf->Data.abyTA[0]), + &(pDevice->abyBSSID[0]), + ETH_ALEN); + } else { - memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyTA[0]), + &(psEthHeader->abySrcAddr[0]), + ETH_ALEN); } } else { @@ -1063,19 +1074,27 @@ s_vFillRTSHead ( //Get RTS Frame body pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 - if ((pDevice->eOPMode == OP_MODE_ADHOC) || - (pDevice->eOPMode == OP_MODE_AP)) { - memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); - } + if ((pDevice->eOPMode == OP_MODE_ADHOC) || + (pDevice->eOPMode == OP_MODE_AP)) { + memcpy(&(pBuf->Data.abyRA[0]), + &(psEthHeader->abyDstAddr[0]), + ETH_ALEN); + } else { - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyRA[0]), + &(pDevice->abyBSSID[0]), + ETH_ALEN); } - if (pDevice->eOPMode == OP_MODE_AP) { - memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); - } + if (pDevice->eOPMode == OP_MODE_AP) { + memcpy(&(pBuf->Data.abyTA[0]), + &(pDevice->abyBSSID[0]), + ETH_ALEN); + } else { - memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyTA[0]), + &(psEthHeader->abySrcAddr[0]), + ETH_ALEN); } } // if (byFBOption == AUTO_FB_NONE) @@ -1094,20 +1113,26 @@ s_vFillRTSHead ( //Get RTS Frame body pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 - if ((pDevice->eOPMode == OP_MODE_ADHOC) || - (pDevice->eOPMode == OP_MODE_AP)) { - memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); - } - else { - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); - } - - if (pDevice->eOPMode == OP_MODE_AP) { - memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); - } - else { - memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); - } + if ((pDevice->eOPMode == OP_MODE_ADHOC) || + (pDevice->eOPMode == OP_MODE_AP)) { + memcpy(&(pBuf->Data.abyRA[0]), + &(psEthHeader->abyDstAddr[0]), + ETH_ALEN); + } else { + memcpy(&(pBuf->Data.abyRA[0]), + &(pDevice->abyBSSID[0]), + ETH_ALEN); + } + + if (pDevice->eOPMode == OP_MODE_AP) { + memcpy(&(pBuf->Data.abyTA[0]), + &(pDevice->abyBSSID[0]), + ETH_ALEN); + } else { + memcpy(&(pBuf->Data.abyTA[0]), + &(psEthHeader->abySrcAddr[0]), + ETH_ALEN); + } } else { @@ -1125,19 +1150,25 @@ s_vFillRTSHead ( //Get RTS Frame body pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 - if ((pDevice->eOPMode == OP_MODE_ADHOC) || - (pDevice->eOPMode == OP_MODE_AP)) { - memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); - } - else { - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); - } - if (pDevice->eOPMode == OP_MODE_AP) { - memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); - } - else { - memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); - } + if ((pDevice->eOPMode == OP_MODE_ADHOC) || + (pDevice->eOPMode == OP_MODE_AP)) { + memcpy(&(pBuf->Data.abyRA[0]), + &(psEthHeader->abyDstAddr[0]), + ETH_ALEN); + } else { + memcpy(&(pBuf->Data.abyRA[0]), + &(pDevice->abyBSSID[0]), + ETH_ALEN); + } + if (pDevice->eOPMode == OP_MODE_AP) { + memcpy(&(pBuf->Data.abyTA[0]), + &(pDevice->abyBSSID[0]), + ETH_ALEN); + } else { + memcpy(&(pBuf->Data.abyTA[0]), + &(psEthHeader->abySrcAddr[0]), + ETH_ALEN); + } } } else if (byPktType == PK_TYPE_11B) { @@ -1153,20 +1184,26 @@ s_vFillRTSHead ( //Get RTS Frame body pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 - - if ((pDevice->eOPMode == OP_MODE_ADHOC) || + if ((pDevice->eOPMode == OP_MODE_ADHOC) || (pDevice->eOPMode == OP_MODE_AP)) { - memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyRA[0]), + &(psEthHeader->abyDstAddr[0]), + ETH_ALEN); } else { - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyRA[0]), + &(pDevice->abyBSSID[0]), + ETH_ALEN); } if (pDevice->eOPMode == OP_MODE_AP) { - memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); - } - else { - memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyTA[0]), + &(pDevice->abyBSSID[0]), + ETH_ALEN); + } else { + memcpy(&(pBuf->Data.abyTA[0]), + &(psEthHeader->abySrcAddr[0]), + ETH_ALEN); } } } @@ -1222,7 +1259,9 @@ s_vFillCTSHead ( pBuf->Data.wDurationID = pBuf->wDuration_ba; pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4 pBuf->Data.wReserved = 0x0000; - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyRA[0]), + &(pDevice->abyCurrentNetAddr[0]), + ETH_ALEN); } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) PSCTS pBuf = (PSCTS)pvCTS; //Get SignalField,ServiceField,Length @@ -1239,16 +1278,13 @@ s_vFillCTSHead ( pBuf->Data.wDurationID = pBuf->wDuration_ba; pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4 pBuf->Data.wReserved = 0x0000; - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyRA[0]), + &(pDevice->abyCurrentNetAddr[0]), + ETH_ALEN); } } } - - - - - /*+ * * Description: @@ -1843,21 +1879,35 @@ s_vGenerateMACHeader ( } if (pDevice->eOPMode == OP_MODE_AP) { - memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); - memcpy(&(pMACHeader->abyAddr2[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); - memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); + memcpy(&(pMACHeader->abyAddr1[0]), + &(psEthHeader->abyDstAddr[0]), + ETH_ALEN); + memcpy(&(pMACHeader->abyAddr2[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); + memcpy(&(pMACHeader->abyAddr3[0]), + &(psEthHeader->abySrcAddr[0]), + ETH_ALEN); pMACHeader->wFrameCtl |= FC_FROMDS; - } - else { - if (pDevice->eOPMode == OP_MODE_ADHOC) { - memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); - memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); - memcpy(&(pMACHeader->abyAddr3[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); - } - else { - memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); - memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); - memcpy(&(pMACHeader->abyAddr1[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); + } else { + if (pDevice->eOPMode == OP_MODE_ADHOC) { + memcpy(&(pMACHeader->abyAddr1[0]), + &(psEthHeader->abyDstAddr[0]), + ETH_ALEN); + memcpy(&(pMACHeader->abyAddr2[0]), + &(psEthHeader->abySrcAddr[0]), + ETH_ALEN); + memcpy(&(pMACHeader->abyAddr3[0]), + &(pDevice->abyBSSID[0]), + ETH_ALEN); + } else { + memcpy(&(pMACHeader->abyAddr3[0]), + &(psEthHeader->abyDstAddr[0]), + ETH_ALEN); + memcpy(&(pMACHeader->abyAddr2[0]), + &(psEthHeader->abySrcAddr[0]), + ETH_ALEN); + memcpy(&(pMACHeader->abyAddr1[0]), + &(pDevice->abyBSSID[0]), + ETH_ALEN); pMACHeader->wFrameCtl |= FC_TODS; } } @@ -2089,8 +2139,12 @@ CMD_STATUS csMgmt_xmit( memset((PVOID)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); - memcpy(&(sEthHeader.abyDstAddr[0]), &(pPacket->p80211Header->sA3.abyAddr1[0]), U_ETHER_ADDR_LEN); - memcpy(&(sEthHeader.abySrcAddr[0]), &(pPacket->p80211Header->sA3.abyAddr2[0]), U_ETHER_ADDR_LEN); + memcpy(&(sEthHeader.abyDstAddr[0]), + &(pPacket->p80211Header->sA3.abyAddr1[0]), + ETH_ALEN); + memcpy(&(sEthHeader.abySrcAddr[0]), + &(pPacket->p80211Header->sA3.abyAddr2[0]), + ETH_ALEN); //========================= // No Fragmentation //========================= @@ -2521,8 +2575,12 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb) { cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab); } memset((PVOID)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); - memcpy(&(sEthHeader.abyDstAddr[0]), &(p80211Header->sA3.abyAddr1[0]), U_ETHER_ADDR_LEN); - memcpy(&(sEthHeader.abySrcAddr[0]), &(p80211Header->sA3.abyAddr2[0]), U_ETHER_ADDR_LEN); + memcpy(&(sEthHeader.abyDstAddr[0]), + &(p80211Header->sA3.abyAddr1[0]), + ETH_ALEN); + memcpy(&(sEthHeader.abySrcAddr[0]), + &(p80211Header->sA3.abyAddr2[0]), + ETH_ALEN); //========================= // No Fragmentation //========================= diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h index 6bc22d371c1e..133f47520621 100644 --- a/drivers/staging/vt6656/rxtx.h +++ b/drivers/staging/vt6656/rxtx.h @@ -43,8 +43,8 @@ typedef struct tagSRTSDataF { WORD wFrameControl; WORD wDurationID; - BYTE abyRA[U_ETHER_ADDR_LEN]; - BYTE abyTA[U_ETHER_ADDR_LEN]; + BYTE abyRA[ETH_ALEN]; + BYTE abyTA[ETH_ALEN]; } SRTSDataF, *PSRTSDataF; // @@ -53,7 +53,7 @@ typedef struct tagSRTSDataF { typedef struct tagSCTSDataF { WORD wFrameControl; WORD wDurationID; - BYTE abyRA[U_ETHER_ADDR_LEN]; + BYTE abyRA[ETH_ALEN]; WORD wReserved; } SCTSDataF, *PSCTSDataF; diff --git a/drivers/staging/vt6656/tether.c b/drivers/staging/vt6656/tether.c index ab1368a08389..a7c716f174da 100644 --- a/drivers/staging/vt6656/tether.c +++ b/drivers/staging/vt6656/tether.c @@ -68,7 +68,7 @@ BYTE ETHbyGetHashIndexByCrc32(PBYTE pbyMultiAddr) BYTE byHash = 0; /* get the least 6-bits from CRC generator */ - byTmpHash = (BYTE)(CRCdwCrc32(pbyMultiAddr, U_ETHER_ADDR_LEN, + byTmpHash = (BYTE)(CRCdwCrc32(pbyMultiAddr, ETH_ALEN, 0xFFFFFFFFL) & 0x3F); /* reverse most bit to least bit */ for (ii = 0; ii < (sizeof(byTmpHash) * 8); ii++) { diff --git a/drivers/staging/vt6656/tether.h b/drivers/staging/vt6656/tether.h index 5a3c326436c6..af119dd82b24 100644 --- a/drivers/staging/vt6656/tether.h +++ b/drivers/staging/vt6656/tether.h @@ -29,17 +29,17 @@ #ifndef __TETHER_H__ #define __TETHER_H__ +#include #include "ttype.h" /*--------------------- Export Definitions -------------------------*/ // // constants // -#define U_ETHER_ADDR_LEN 6 // Ethernet address length #define U_TYPE_LEN 2 // #define U_CRC_LEN 4 // -#define U_HEADER_LEN (U_ETHER_ADDR_LEN * 2 + U_TYPE_LEN) -#define U_ETHER_ADDR_STR_LEN (U_ETHER_ADDR_LEN * 2 + 1) +#define U_HEADER_LEN (ETH_ALEN * 2 + U_TYPE_LEN) +#define U_ETHER_ADDR_STR_LEN (ETH_ALEN * 2 + 1) // Ethernet address string length #define MIN_DATA_LEN 46 // min data length @@ -167,8 +167,8 @@ // Ethernet packet // typedef struct tagSEthernetHeader { - BYTE abyDstAddr[U_ETHER_ADDR_LEN]; - BYTE abySrcAddr[U_ETHER_ADDR_LEN]; + BYTE abyDstAddr[ETH_ALEN]; + BYTE abySrcAddr[ETH_ALEN]; WORD wType; }__attribute__ ((__packed__)) SEthernetHeader, *PSEthernetHeader; @@ -178,8 +178,8 @@ SEthernetHeader, *PSEthernetHeader; // 802_3 packet // typedef struct tagS802_3Header { - BYTE abyDstAddr[U_ETHER_ADDR_LEN]; - BYTE abySrcAddr[U_ETHER_ADDR_LEN]; + BYTE abyDstAddr[ETH_ALEN]; + BYTE abySrcAddr[ETH_ALEN]; WORD wLen; }__attribute__ ((__packed__)) S802_3Header, *PS802_3Header; @@ -190,11 +190,11 @@ S802_3Header, *PS802_3Header; typedef struct tagS802_11Header { WORD wFrameCtl; WORD wDurationID; - BYTE abyAddr1[U_ETHER_ADDR_LEN]; - BYTE abyAddr2[U_ETHER_ADDR_LEN]; - BYTE abyAddr3[U_ETHER_ADDR_LEN]; + BYTE abyAddr1[ETH_ALEN]; + BYTE abyAddr2[ETH_ALEN]; + BYTE abyAddr3[ETH_ALEN]; WORD wSeqCtl; - BYTE abyAddr4[U_ETHER_ADDR_LEN]; + BYTE abyAddr4[ETH_ALEN]; }__attribute__ ((__packed__)) S802_11Header, *PS802_11Header; diff --git a/drivers/staging/vt6656/wctl.c b/drivers/staging/vt6656/wctl.c index 40986da1e4a2..956add694227 100644 --- a/drivers/staging/vt6656/wctl.c +++ b/drivers/staging/vt6656/wctl.c @@ -91,7 +91,7 @@ BOOL WCTLbIsDuplicate (PSCache pCache, PS802_11Header pMACHeader) /* Not fount in cache - insert */ pCacheEntry = &pCache->asCacheEntry[pCache->uInPtr]; pCacheEntry->wFmSequence = pMACHeader->wSeqCtl; - memcpy(&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0]), U_ETHER_ADDR_LEN); + memcpy(&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0]), ETH_ALEN); pCacheEntry->wFrameCtl = pMACHeader->wFrameCtl; ADD_ONE_WITH_WRAP_AROUND(pCache->uInPtr, DUPLICATE_RX_CACHE_LENGTH); return FALSE; @@ -154,7 +154,9 @@ UINT ii; pDevice->sRxDFCB[ii].bInUse = TRUE; pDevice->sRxDFCB[ii].wSequence = (pMACHeader->wSeqCtl >> 4); pDevice->sRxDFCB[ii].wFragNum = (pMACHeader->wSeqCtl & 0x000F); - memcpy(&(pDevice->sRxDFCB[ii].abyAddr2[0]), &(pMACHeader->abyAddr2[0]), U_ETHER_ADDR_LEN); + memcpy(&(pDevice->sRxDFCB[ii].abyAddr2[0]), + &(pMACHeader->abyAddr2[0]), + ETH_ALEN); return(ii); } } diff --git a/drivers/staging/vt6656/wmgr.c b/drivers/staging/vt6656/wmgr.c index 330aea69d231..9b4ff79912a9 100644 --- a/drivers/staging/vt6656/wmgr.c +++ b/drivers/staging/vt6656/wmgr.c @@ -3773,13 +3773,17 @@ s_MgrMakeAssocRequest( pwPMKID = (PWORD)pbyRSN; // Point to PMKID count *pwPMKID = 0; // Initialize PMKID count pbyRSN += 2; // Point to PMKID list - for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) { - if ( !memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, U_ETHER_ADDR_LEN)) { - (*pwPMKID) ++; - memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16); - pbyRSN += 16; - } - } + for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) { + if (!memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], + pMgmt->abyCurrBSSID, + ETH_ALEN)) { + (*pwPMKID)++; + memcpy(pbyRSN, + pDevice->gsPMKID.BSSIDInfo[ii].PMKID, + 16); + pbyRSN += 16; + } + } if (*pwPMKID != 0) { sFrame.pRSN->len += (2 + (*pwPMKID)*16); } @@ -4030,10 +4034,14 @@ s_MgrMakeReAssocRequest( *pwPMKID = 0; // Initialize PMKID count pbyRSN += 2; // Point to PMKID list for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) { - if ( !memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, U_ETHER_ADDR_LEN)) { - (*pwPMKID) ++; - memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16); - pbyRSN += 16; + if (!memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], + pMgmt->abyCurrBSSID, + ETH_ALEN)) { + (*pwPMKID)++; + memcpy(pbyRSN, + pDevice->gsPMKID.BSSIDInfo[ii].PMKID, + 16); + pbyRSN += 16; } } if (*pwPMKID != 0) { @@ -4057,8 +4065,6 @@ s_MgrMakeReAssocRequest( return pTxPacket; } - - /*+ * * Routine Description: @@ -4070,7 +4076,6 @@ s_MgrMakeReAssocRequest( * -*/ - PSTxMgmtPacket s_MgrMakeAssocResponse( IN PSDevice pDevice, @@ -4745,13 +4750,16 @@ bAdd_PMKID_Candidate ( // Update Old Candidate for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) { - pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii]; - if ( !memcmp(pCandidateList->BSSID, pbyBSSID, U_ETHER_ADDR_LEN)) { - if ((psRSNCapObj->bRSNCapExist == TRUE) && (psRSNCapObj->wRSNCap & BIT0)) { - pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; - } else { - pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); - } + pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii]; + if (!memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) { + if ((psRSNCapObj->bRSNCapExist == TRUE) + && (psRSNCapObj->wRSNCap & BIT0)) { + pCandidateList->Flags |= + NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; + } else { + pCandidateList->Flags &= + ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); + } return TRUE; } } @@ -4763,7 +4771,7 @@ bAdd_PMKID_Candidate ( } else { pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); } - memcpy(pCandidateList->BSSID, pbyBSSID, U_ETHER_ADDR_LEN); + memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN); pDevice->gsPMKIDCandidate.NumCandidates++; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates); return TRUE; diff --git a/drivers/staging/vt6656/wpa2.c b/drivers/staging/vt6656/wpa2.c index fa3aeedfb278..f8be30df69c0 100644 --- a/drivers/staging/vt6656/wpa2.c +++ b/drivers/staging/vt6656/wpa2.c @@ -337,20 +337,25 @@ WPA2uSetIEs( } pRSNIEs->len +=2; - if ((pMgmt->gsPMKIDCache.BSSIDInfoCount > 0) && - (pMgmt->bRoaming == TRUE) && + if ((pMgmt->gsPMKIDCache.BSSIDInfoCount > 0) && + (pMgmt->bRoaming == TRUE) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) { - // RSN PMKID - pwPMKID = (PWORD)(&pRSNIEs->abyRSN[18]); // Point to PMKID count - *pwPMKID = 0; // Initialize PMKID count - pbyBuffer = &pRSNIEs->abyRSN[20]; // Point to PMKID list - for (ii = 0; ii < pMgmt->gsPMKIDCache.BSSIDInfoCount; ii++) { - if ( !memcmp(&pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyBSSID[0], pMgmt->abyCurrBSSID, U_ETHER_ADDR_LEN)) { - (*pwPMKID) ++; - memcpy(pbyBuffer, pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyPMKID, 16); - pbyBuffer += 16; - } - } + /* RSN PMKID, pointer to PMKID count */ + pwPMKID = (PWORD)(&pRSNIEs->abyRSN[18]); + *pwPMKID = 0; /* Initialize PMKID count */ + pbyBuffer = &pRSNIEs->abyRSN[20]; /* Point to PMKID list */ + for (ii = 0; ii < pMgmt->gsPMKIDCache.BSSIDInfoCount; ii++) { + if (!memcmp(&pMgmt-> + gsPMKIDCache.BSSIDInfo[ii].abyBSSID[0], + pMgmt->abyCurrBSSID, + ETH_ALEN)) { + (*pwPMKID)++; + memcpy(pbyBuffer, + pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyPMKID, + 16); + pbyBuffer += 16; + } + } if (*pwPMKID != 0) { pRSNIEs->len += (2 + (*pwPMKID)*16); } else { diff --git a/drivers/staging/vt6656/wpactl.c b/drivers/staging/vt6656/wpactl.c index 4555bc0448b9..25b784c26e8f 100644 --- a/drivers/staging/vt6656/wpactl.c +++ b/drivers/staging/vt6656/wpactl.c @@ -103,7 +103,7 @@ static int wpa_init_wpadev(PSDevice pDevice) wpadev_priv = netdev_priv(pDevice->wpadev); *wpadev_priv = *pDevice; - memcpy(pDevice->wpadev->dev_addr, dev->dev_addr, U_ETHER_ADDR_LEN); + memcpy(pDevice->wpadev->dev_addr, dev->dev_addr, ETH_ALEN); pDevice->wpadev->base_addr = dev->base_addr; pDevice->wpadev->irq = dev->irq; pDevice->wpadev->mem_start = dev->mem_start; -- cgit v1.2.3 From c30d7973f22ea3f8b3e5d1d7215b3f2ff8f5e934 Mon Sep 17 00:00:00 2001 From: Forest Bond Date: Sat, 17 Apr 2010 11:03:38 -0400 Subject: Staging: vt6656: Rename hostap_set_hostapd, hostap_iotctl. The functions hostap_set_hostapd, hostap_iotctl clashed with functions of the same name with CONFIG_HOSTAP=y and/or CONFIG_VT6655=y. Signed-off-by: Forest Bond Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/hostap.c | 8 ++++---- drivers/staging/vt6656/hostap.h | 4 ++-- drivers/staging/vt6656/ioctl.c | 4 ++-- drivers/staging/vt6656/main_usb.c | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/hostap.c b/drivers/staging/vt6656/hostap.c index 1078d616c497..ca007c30e0ab 100644 --- a/drivers/staging/vt6656/hostap.c +++ b/drivers/staging/vt6656/hostap.c @@ -178,7 +178,7 @@ static int hostap_disable_hostapd(PSDevice pDevice, int rtnl_locked) * */ -int hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked) +int vt6656_hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked) { if (val < 0 || val > 1) return -EINVAL; @@ -744,7 +744,7 @@ static int hostap_get_encryption(PSDevice pDevice, /* * Description: - * hostap_ioctl main function supported for hostap deamon. + * vt6656_hostap_ioctl main function supported for hostap deamon. * * Parameters: * In: @@ -756,7 +756,7 @@ static int hostap_get_encryption(PSDevice pDevice, * */ -int hostap_ioctl(PSDevice pDevice, struct iw_point *p) +int vt6656_hostap_ioctl(PSDevice pDevice, struct iw_point *p) { struct viawget_hostapd_param *param; int ret = 0; @@ -844,7 +844,7 @@ int hostap_ioctl(PSDevice pDevice, struct iw_point *p) return -EOPNOTSUPP; default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_ioctl: unknown cmd=%d\n", + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vt6656_hostap_ioctl: unknown cmd=%d\n", (int)param->cmd); return -EOPNOTSUPP; break; diff --git a/drivers/staging/vt6656/hostap.h b/drivers/staging/vt6656/hostap.h index 8fd667b542be..9e366dca7a63 100644 --- a/drivers/staging/vt6656/hostap.h +++ b/drivers/staging/vt6656/hostap.h @@ -61,8 +61,8 @@ #define ARPHRD_IEEE80211 801 #endif -int hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked); -int hostap_ioctl(PSDevice pDevice, struct iw_point *p); +int vt6656_hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked); +int vt6656_hostap_ioctl(PSDevice pDevice, struct iw_point *p); #endif // __HOSTAP_H__ diff --git a/drivers/staging/vt6656/ioctl.c b/drivers/staging/vt6656/ioctl.c index d7a78f2f9f05..08d5429db26a 100644 --- a/drivers/staging/vt6656/ioctl.c +++ b/drivers/staging/vt6656/ioctl.c @@ -412,7 +412,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) { break; }; if (sValue.dwValue == 1) { - if (hostap_set_hostapd(pDevice, 1, 1) == 0){ + if (vt6656_hostap_set_hostapd(pDevice, 1, 1) == 0){ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HOSTAP\n"); } else { @@ -421,7 +421,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) { } } else { - hostap_set_hostapd(pDevice, 0, 1); + vt6656_hostap_set_hostapd(pDevice, 0, 1); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HOSTAP\n"); } diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index c0bad4f43ee9..ebd7a1ebce8c 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -2069,7 +2069,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { rc = 0; } - rc = hostap_ioctl(pDevice, &wrq->u.data); + rc = vt6656_hostap_ioctl(pDevice, &wrq->u.data); break; case IOCTL_CMD_WPA: -- cgit v1.2.3 From ecf739e695d5aa404326100c0ba93c211e87a0fe Mon Sep 17 00:00:00 2001 From: Forest Bond Date: Sat, 17 Apr 2010 11:03:47 -0400 Subject: Staging: vt6655: Rename hostap_set_hostapd, hostap_iotctl. The functions hostap_set_hostapd, hostap_iotctl clashed with functions of the same name with CONFIG_HOSTAP=y and/or CONFIG_VT6656=y. Signed-off-by: Forest Bond Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 4 ++-- drivers/staging/vt6655/hostap.c | 8 ++++---- drivers/staging/vt6655/hostap.h | 4 ++-- drivers/staging/vt6655/ioctl.c | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 50f02ee0b112..f1d70e133d16 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -1243,7 +1243,7 @@ device_release_WPADEV(pDevice); } #ifdef HOSTAP if (dev) - hostap_set_hostapd(pDevice, 0, 0); + vt6655_hostap_set_hostapd(pDevice, 0, 0); #endif if (dev) unregister_netdev(dev); @@ -3524,7 +3524,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { case IOCTL_CMD_HOSTAPD: - rc = hostap_ioctl(pDevice, &wrq->u.data); + rc = vt6655_hostap_ioctl(pDevice, &wrq->u.data); break; case IOCTL_CMD_WPA: diff --git a/drivers/staging/vt6655/hostap.c b/drivers/staging/vt6655/hostap.c index 58abf44c76a6..9e07a40480fd 100644 --- a/drivers/staging/vt6655/hostap.c +++ b/drivers/staging/vt6655/hostap.c @@ -183,7 +183,7 @@ KeyvInitTable(&pDevice->sKey,pDevice->PortOffset); * */ -int hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked) +int vt6655_hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked) { if (val < 0 || val > 1) return -EINVAL; @@ -746,7 +746,7 @@ static int hostap_get_encryption(PSDevice pDevice, /* * Description: - * hostap_ioctl main function supported for hostap deamon. + * vt6655_hostap_ioctl main function supported for hostap deamon. * * Parameters: * In: @@ -758,7 +758,7 @@ static int hostap_get_encryption(PSDevice pDevice, * */ -int hostap_ioctl(PSDevice pDevice, struct iw_point *p) +int vt6655_hostap_ioctl(PSDevice pDevice, struct iw_point *p) { struct viawget_hostapd_param *param; int ret = 0; @@ -846,7 +846,7 @@ int hostap_ioctl(PSDevice pDevice, struct iw_point *p) return -EOPNOTSUPP; default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_ioctl: unknown cmd=%d\n", + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vt6655_hostap_ioctl: unknown cmd=%d\n", (int)param->cmd); return -EOPNOTSUPP; break; diff --git a/drivers/staging/vt6655/hostap.h b/drivers/staging/vt6655/hostap.h index 8fd667b542be..55db55524d96 100644 --- a/drivers/staging/vt6655/hostap.h +++ b/drivers/staging/vt6655/hostap.h @@ -61,8 +61,8 @@ #define ARPHRD_IEEE80211 801 #endif -int hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked); -int hostap_ioctl(PSDevice pDevice, struct iw_point *p); +int vt6655_hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked); +int vt6655_hostap_ioctl(PSDevice pDevice, struct iw_point *p); #endif // __HOSTAP_H__ diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c index 38577ca841ea..37928e844010 100644 --- a/drivers/staging/vt6655/ioctl.c +++ b/drivers/staging/vt6655/ioctl.c @@ -429,7 +429,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) { break; }; if (sValue.dwValue == 1) { - if (hostap_set_hostapd(pDevice, 1, 1) == 0){ + if (vt6655_hostap_set_hostapd(pDevice, 1, 1) == 0){ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HOSTAP\n"); } else { @@ -438,7 +438,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) { } } else { - hostap_set_hostapd(pDevice, 0, 1); + vt6655_hostap_set_hostapd(pDevice, 0, 1); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HOSTAP\n"); } -- cgit v1.2.3 From 592ccfebb3d7ae6d2fa367b97f080790befa3c6c Mon Sep 17 00:00:00 2001 From: Andres More Date: Sat, 17 Apr 2010 12:07:42 -0300 Subject: Staging: vt6656: Removed IN definition Code cleanup, removed empty IN definition used to denote input parameters. Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/80211mgr.c | 44 ++-- drivers/staging/vt6656/80211mgr.h | 44 ++-- drivers/staging/vt6656/baseband.c | 24 +- drivers/staging/vt6656/baseband.h | 24 +- drivers/staging/vt6656/bssdb.c | 136 +++++------ drivers/staging/vt6656/bssdb.h | 124 +++++----- drivers/staging/vt6656/card.c | 12 +- drivers/staging/vt6656/card.h | 8 +- drivers/staging/vt6656/channel.c | 2 +- drivers/staging/vt6656/channel.h | 2 +- drivers/staging/vt6656/control.h | 26 +- drivers/staging/vt6656/datarate.c | 26 +- drivers/staging/vt6656/datarate.h | 22 +- drivers/staging/vt6656/dpc.c | 115 +++++---- drivers/staging/vt6656/dpc.h | 10 +- drivers/staging/vt6656/firmware.c | 6 +- drivers/staging/vt6656/firmware.h | 6 +- drivers/staging/vt6656/int.c | 2 +- drivers/staging/vt6656/int.h | 2 +- drivers/staging/vt6656/ioctl.h | 8 +- drivers/staging/vt6656/key.c | 14 +- drivers/staging/vt6656/key.h | 14 +- drivers/staging/vt6656/power.c | 18 +- drivers/staging/vt6656/power.h | 22 +- drivers/staging/vt6656/rf.c | 24 +- drivers/staging/vt6656/rf.h | 24 +- drivers/staging/vt6656/rxtx.c | 394 +++++++++++++++---------------- drivers/staging/vt6656/rxtx.h | 22 +- drivers/staging/vt6656/ttype.h | 4 - drivers/staging/vt6656/usbpipe.c | 66 +++--- drivers/staging/vt6656/usbpipe.h | 46 ++-- drivers/staging/vt6656/wcmd.c | 48 ++-- drivers/staging/vt6656/wcmd.h | 12 +- drivers/staging/vt6656/wmgr.c | 484 +++++++++++++++++++------------------- drivers/staging/vt6656/wmgr.h | 54 ++--- drivers/staging/vt6656/wpa.c | 10 +- drivers/staging/vt6656/wpa.h | 10 +- drivers/staging/vt6656/wpa2.c | 8 +- drivers/staging/vt6656/wpa2.h | 8 +- 39 files changed, 960 insertions(+), 965 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/80211mgr.c b/drivers/staging/vt6656/80211mgr.c index 8fa1a8e5a21a..b9dc7b1d9387 100644 --- a/drivers/staging/vt6656/80211mgr.c +++ b/drivers/staging/vt6656/80211mgr.c @@ -91,7 +91,7 @@ static int msglevel =MSG_LEVEL_INFO; VOID vMgrEncodeBeacon( - IN PWLAN_FR_BEACON pFrame + PWLAN_FR_BEACON pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -123,7 +123,7 @@ vMgrEncodeBeacon( VOID vMgrDecodeBeacon( - IN PWLAN_FR_BEACON pFrame + PWLAN_FR_BEACON pFrame ) { PWLAN_IE pItem; @@ -244,7 +244,7 @@ vMgrDecodeBeacon( VOID vMgrEncodeIBSSATIM( - IN PWLAN_FR_IBSSATIM pFrame + PWLAN_FR_IBSSATIM pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -267,7 +267,7 @@ vMgrEncodeIBSSATIM( VOID vMgrDecodeIBSSATIM( - IN PWLAN_FR_IBSSATIM pFrame + PWLAN_FR_IBSSATIM pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -289,7 +289,7 @@ vMgrDecodeIBSSATIM( VOID vMgrEncodeDisassociation( - IN PWLAN_FR_DISASSOC pFrame + PWLAN_FR_DISASSOC pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -317,7 +317,7 @@ vMgrEncodeDisassociation( VOID vMgrDecodeDisassociation( - IN PWLAN_FR_DISASSOC pFrame + PWLAN_FR_DISASSOC pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -343,7 +343,7 @@ vMgrDecodeDisassociation( VOID vMgrEncodeAssocRequest( - IN PWLAN_FR_ASSOCREQ pFrame + PWLAN_FR_ASSOCREQ pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -370,7 +370,7 @@ vMgrEncodeAssocRequest( VOID vMgrDecodeAssocRequest( - IN PWLAN_FR_ASSOCREQ pFrame + PWLAN_FR_ASSOCREQ pFrame ) { PWLAN_IE pItem; @@ -436,7 +436,7 @@ vMgrDecodeAssocRequest( VOID vMgrEncodeAssocResponse( - IN PWLAN_FR_ASSOCRESP pFrame + PWLAN_FR_ASSOCRESP pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -468,7 +468,7 @@ vMgrEncodeAssocResponse( VOID vMgrDecodeAssocResponse( - IN PWLAN_FR_ASSOCRESP pFrame + PWLAN_FR_ASSOCRESP pFrame ) { PWLAN_IE pItem; @@ -514,7 +514,7 @@ vMgrDecodeAssocResponse( VOID vMgrEncodeReassocRequest( - IN PWLAN_FR_REASSOCREQ pFrame + PWLAN_FR_REASSOCREQ pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -546,7 +546,7 @@ vMgrEncodeReassocRequest( VOID vMgrDecodeReassocRequest( - IN PWLAN_FR_REASSOCREQ pFrame + PWLAN_FR_REASSOCREQ pFrame ) { PWLAN_IE pItem; @@ -618,7 +618,7 @@ vMgrDecodeReassocRequest( VOID vMgrEncodeProbeRequest( - IN PWLAN_FR_PROBEREQ pFrame + PWLAN_FR_PROBEREQ pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -639,7 +639,7 @@ vMgrEncodeProbeRequest( VOID vMgrDecodeProbeRequest( - IN PWLAN_FR_PROBEREQ pFrame + PWLAN_FR_PROBEREQ pFrame ) { PWLAN_IE pItem; @@ -692,7 +692,7 @@ vMgrDecodeProbeRequest( VOID vMgrEncodeProbeResponse( - IN PWLAN_FR_PROBERESP pFrame + PWLAN_FR_PROBERESP pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -726,7 +726,7 @@ vMgrEncodeProbeResponse( VOID vMgrDecodeProbeResponse( - IN PWLAN_FR_PROBERESP pFrame + PWLAN_FR_PROBERESP pFrame ) { PWLAN_IE pItem; @@ -840,7 +840,7 @@ vMgrDecodeProbeResponse( VOID vMgrEncodeAuthen( - IN PWLAN_FR_AUTHEN pFrame + PWLAN_FR_AUTHEN pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -871,7 +871,7 @@ vMgrEncodeAuthen( VOID vMgrDecodeAuthen( - IN PWLAN_FR_AUTHEN pFrame + PWLAN_FR_AUTHEN pFrame ) { PWLAN_IE pItem; @@ -911,7 +911,7 @@ vMgrDecodeAuthen( VOID vMgrEncodeDeauthen( - IN PWLAN_FR_DEAUTHEN pFrame + PWLAN_FR_DEAUTHEN pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -938,7 +938,7 @@ vMgrEncodeDeauthen( VOID vMgrDecodeDeauthen( - IN PWLAN_FR_DEAUTHEN pFrame + PWLAN_FR_DEAUTHEN pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -964,7 +964,7 @@ vMgrDecodeDeauthen( VOID vMgrEncodeReassocResponse( - IN PWLAN_FR_REASSOCRESP pFrame + PWLAN_FR_REASSOCRESP pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -997,7 +997,7 @@ vMgrEncodeReassocResponse( VOID vMgrDecodeReassocResponse( - IN PWLAN_FR_REASSOCRESP pFrame + PWLAN_FR_REASSOCRESP pFrame ) { PWLAN_IE pItem; diff --git a/drivers/staging/vt6656/80211mgr.h b/drivers/staging/vt6656/80211mgr.h index a4ea82492167..f7160cdd164a 100644 --- a/drivers/staging/vt6656/80211mgr.h +++ b/drivers/staging/vt6656/80211mgr.h @@ -750,112 +750,112 @@ typedef struct tagWLAN_FR_DEAUTHEN { /*--------------------- Export Functions --------------------------*/ VOID vMgrEncodeBeacon( - IN PWLAN_FR_BEACON pFrame + PWLAN_FR_BEACON pFrame ); VOID vMgrDecodeBeacon( - IN PWLAN_FR_BEACON pFrame + PWLAN_FR_BEACON pFrame ); VOID vMgrEncodeIBSSATIM( - IN PWLAN_FR_IBSSATIM pFrame + PWLAN_FR_IBSSATIM pFrame ); VOID vMgrDecodeIBSSATIM( - IN PWLAN_FR_IBSSATIM pFrame + PWLAN_FR_IBSSATIM pFrame ); VOID vMgrEncodeDisassociation( - IN PWLAN_FR_DISASSOC pFrame + PWLAN_FR_DISASSOC pFrame ); VOID vMgrDecodeDisassociation( - IN PWLAN_FR_DISASSOC pFrame + PWLAN_FR_DISASSOC pFrame ); VOID vMgrEncodeAssocRequest( - IN PWLAN_FR_ASSOCREQ pFrame + PWLAN_FR_ASSOCREQ pFrame ); VOID vMgrDecodeAssocRequest( - IN PWLAN_FR_ASSOCREQ pFrame + PWLAN_FR_ASSOCREQ pFrame ); VOID vMgrEncodeAssocResponse( - IN PWLAN_FR_ASSOCRESP pFrame + PWLAN_FR_ASSOCRESP pFrame ); VOID vMgrDecodeAssocResponse( - IN PWLAN_FR_ASSOCRESP pFrame + PWLAN_FR_ASSOCRESP pFrame ); VOID vMgrEncodeReassocRequest( - IN PWLAN_FR_REASSOCREQ pFrame + PWLAN_FR_REASSOCREQ pFrame ); VOID vMgrDecodeReassocRequest( - IN PWLAN_FR_REASSOCREQ pFrame + PWLAN_FR_REASSOCREQ pFrame ); VOID vMgrEncodeProbeRequest( - IN PWLAN_FR_PROBEREQ pFrame + PWLAN_FR_PROBEREQ pFrame ); VOID vMgrDecodeProbeRequest( - IN PWLAN_FR_PROBEREQ pFrame + PWLAN_FR_PROBEREQ pFrame ); VOID vMgrEncodeProbeResponse( - IN PWLAN_FR_PROBERESP pFrame + PWLAN_FR_PROBERESP pFrame ); VOID vMgrDecodeProbeResponse( - IN PWLAN_FR_PROBERESP pFrame + PWLAN_FR_PROBERESP pFrame ); VOID vMgrEncodeAuthen( - IN PWLAN_FR_AUTHEN pFrame + PWLAN_FR_AUTHEN pFrame ); VOID vMgrDecodeAuthen( - IN PWLAN_FR_AUTHEN pFrame + PWLAN_FR_AUTHEN pFrame ); VOID vMgrEncodeDeauthen( - IN PWLAN_FR_DEAUTHEN pFrame + PWLAN_FR_DEAUTHEN pFrame ); VOID vMgrDecodeDeauthen( - IN PWLAN_FR_DEAUTHEN pFrame + PWLAN_FR_DEAUTHEN pFrame ); VOID vMgrEncodeReassocResponse( - IN PWLAN_FR_REASSOCRESP pFrame + PWLAN_FR_REASSOCRESP pFrame ); VOID vMgrDecodeReassocResponse( - IN PWLAN_FR_REASSOCRESP pFrame + PWLAN_FR_REASSOCRESP pFrame ); #endif// __80211MGR_H__ diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c index 7dc01dbfc6ff..9063249efd54 100644 --- a/drivers/staging/vt6656/baseband.c +++ b/drivers/staging/vt6656/baseband.c @@ -691,10 +691,10 @@ s_vClearSQ3Value(PSDevice pDevice); */ UINT BBuGetFrameTime ( - IN BYTE byPreambleType, - IN BYTE byPktType, - IN UINT cbFrameLength, - IN WORD wRate + BYTE byPreambleType, + BYTE byPktType, + UINT cbFrameLength, + WORD wRate ) { UINT uFrameTime; @@ -758,10 +758,10 @@ BBuGetFrameTime ( */ VOID BBvCaculateParameter ( - IN PSDevice pDevice, - IN UINT cbFrameLength, - IN WORD wRate, - IN BYTE byPacketType, + PSDevice pDevice, + UINT cbFrameLength, + WORD wRate, + BYTE byPacketType, OUT PWORD pwPhyLen, OUT PBYTE pbyPhySrv, OUT PBYTE pbyPhySgn @@ -1578,7 +1578,7 @@ BBvAntennaDiversity (PSDevice pDevice, BYTE byRxRate, BYTE bySQ3) VOID TimerSQ3CallBack ( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1620,7 +1620,7 @@ TimerSQ3CallBack ( VOID TimerSQ3Tmax3CallBack ( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1652,8 +1652,8 @@ TimerSQ3Tmax3CallBack ( VOID BBvUpdatePreEDThreshold( - IN PSDevice pDevice, - IN BOOL bScanning) + PSDevice pDevice, + BOOL bScanning) { diff --git a/drivers/staging/vt6656/baseband.h b/drivers/staging/vt6656/baseband.h index e991a7e68d4a..10eea90279fa 100644 --- a/drivers/staging/vt6656/baseband.h +++ b/drivers/staging/vt6656/baseband.h @@ -98,18 +98,18 @@ UINT BBuGetFrameTime( - IN BYTE byPreambleType, - IN BYTE byFreqType, - IN UINT cbFrameLength, - IN WORD wRate + BYTE byPreambleType, + BYTE byFreqType, + UINT cbFrameLength, + WORD wRate ); VOID BBvCaculateParameter ( - IN PSDevice pDevice, - IN UINT cbFrameLength, - IN WORD wRate, - IN BYTE byPacketType, + PSDevice pDevice, + UINT cbFrameLength, + WORD wRate, + BYTE byPacketType, OUT PWORD pwPhyLen, OUT PBYTE pbyPhySrv, OUT PBYTE pbyPhySgn @@ -119,12 +119,12 @@ BBvCaculateParameter ( VOID TimerSQ3CallBack ( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ); VOID TimerSQ3Tmax3CallBack ( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ); VOID BBvAntennaDiversity (PSDevice pDevice, BYTE byRxRate, BYTE bySQ3); @@ -139,8 +139,8 @@ BOOL BBbVT3184Init (PSDevice pDevice); VOID BBvSetDeepSleep (PSDevice pDevice); VOID BBvExitDeepSleep (PSDevice pDevice); VOID BBvUpdatePreEDThreshold( - IN PSDevice pDevice, - IN BOOL bScanning + PSDevice pDevice, + BOOL bScanning ); #endif // __BASEBAND_H__ diff --git a/drivers/staging/vt6656/bssdb.c b/drivers/staging/vt6656/bssdb.c index 6b1678bfd61a..fa1ca7902055 100644 --- a/drivers/staging/vt6656/bssdb.c +++ b/drivers/staging/vt6656/bssdb.c @@ -92,16 +92,16 @@ const WORD awHWRetry1[5][5] = { /*--------------------- Static Functions --------------------------*/ VOID s_vCheckSensitivity( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ); VOID s_vCheckPreEDThreshold( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ); #ifdef Calcu_LinkQual VOID s_uCalculateLinkQual( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ); #endif /*--------------------- Export Variables --------------------------*/ @@ -125,10 +125,10 @@ VOID s_uCalculateLinkQual( PKnownBSS BSSpSearchBSSList( - IN HANDLE hDeviceContext, - IN PBYTE pbyDesireBSSID, - IN PBYTE pbyDesireSSID, - IN CARD_PHY_TYPE ePhyType + HANDLE hDeviceContext, + PBYTE pbyDesireBSSID, + PBYTE pbyDesireSSID, + CARD_PHY_TYPE ePhyType ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -298,8 +298,8 @@ pDevice->bSameBSSMaxNum = jj; VOID BSSvClearBSSList( - IN HANDLE hDeviceContext, - IN BOOL bKeepCurrBSSID + HANDLE hDeviceContext, + BOOL bKeepCurrBSSID ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -344,9 +344,9 @@ BSSvClearBSSList( -*/ PKnownBSS BSSpAddrIsInBSSList( - IN HANDLE hDeviceContext, - IN PBYTE abyBSSID, - IN PWLAN_IE_SSID pSSID + HANDLE hDeviceContext, + PBYTE abyBSSID, + PWLAN_IE_SSID pSSID ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -385,23 +385,23 @@ BSSpAddrIsInBSSList( BOOL BSSbInsertToBSSList ( - IN HANDLE hDeviceContext, - IN PBYTE abyBSSIDAddr, - IN QWORD qwTimestamp, - IN WORD wBeaconInterval, - IN WORD wCapInfo, - IN BYTE byCurrChannel, - IN PWLAN_IE_SSID pSSID, - IN PWLAN_IE_SUPP_RATES pSuppRates, - IN PWLAN_IE_SUPP_RATES pExtSuppRates, - IN PERPObject psERP, - IN PWLAN_IE_RSN pRSN, - IN PWLAN_IE_RSN_EXT pRSNWPA, - IN PWLAN_IE_COUNTRY pIE_Country, - IN PWLAN_IE_QUIET pIE_Quiet, - IN UINT uIELength, - IN PBYTE pbyIEs, - IN HANDLE pRxPacketContext + HANDLE hDeviceContext, + PBYTE abyBSSIDAddr, + QWORD qwTimestamp, + WORD wBeaconInterval, + WORD wCapInfo, + BYTE byCurrChannel, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pSuppRates, + PWLAN_IE_SUPP_RATES pExtSuppRates, + PERPObject psERP, + PWLAN_IE_RSN pRSN, + PWLAN_IE_RSN_EXT pRSNWPA, + PWLAN_IE_COUNTRY pIE_Country, + PWLAN_IE_QUIET pIE_Quiet, + UINT uIELength, + PBYTE pbyIEs, + HANDLE pRxPacketContext ) { @@ -604,24 +604,24 @@ BSSbInsertToBSSList ( BOOL BSSbUpdateToBSSList ( - IN HANDLE hDeviceContext, - IN QWORD qwTimestamp, - IN WORD wBeaconInterval, - IN WORD wCapInfo, - IN BYTE byCurrChannel, - IN BOOL bChannelHit, - IN PWLAN_IE_SSID pSSID, - IN PWLAN_IE_SUPP_RATES pSuppRates, - IN PWLAN_IE_SUPP_RATES pExtSuppRates, - IN PERPObject psERP, - IN PWLAN_IE_RSN pRSN, - IN PWLAN_IE_RSN_EXT pRSNWPA, - IN PWLAN_IE_COUNTRY pIE_Country, - IN PWLAN_IE_QUIET pIE_Quiet, - IN PKnownBSS pBSSList, - IN UINT uIELength, - IN PBYTE pbyIEs, - IN HANDLE pRxPacketContext + HANDLE hDeviceContext, + QWORD qwTimestamp, + WORD wBeaconInterval, + WORD wCapInfo, + BYTE byCurrChannel, + BOOL bChannelHit, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pSuppRates, + PWLAN_IE_SUPP_RATES pExtSuppRates, + PERPObject psERP, + PWLAN_IE_RSN pRSN, + PWLAN_IE_RSN_EXT pRSNWPA, + PWLAN_IE_COUNTRY pIE_Country, + PWLAN_IE_QUIET pIE_Quiet, + PKnownBSS pBSSList, + UINT uIELength, + PBYTE pbyIEs, + HANDLE pRxPacketContext ) { int ii, jj; @@ -770,8 +770,8 @@ BSSbUpdateToBSSList ( BOOL BSSbIsSTAInNodeDB( - IN HANDLE hDeviceContext, - IN PBYTE abyDstAddr, + HANDLE hDeviceContext, + PBYTE abyDstAddr, OUT PUINT puNodeIndex ) { @@ -806,7 +806,7 @@ BSSbIsSTAInNodeDB( -*/ VOID BSSvCreateOneNode( - IN HANDLE hDeviceContext, + HANDLE hDeviceContext, OUT PUINT puNodeIndex ) { @@ -871,8 +871,8 @@ BSSvCreateOneNode( -*/ VOID BSSvRemoveOneNode( - IN HANDLE hDeviceContext, - IN UINT uNodeIndex + HANDLE hDeviceContext, + UINT uNodeIndex ) { @@ -904,10 +904,10 @@ BSSvRemoveOneNode( VOID BSSvUpdateAPNode( - IN HANDLE hDeviceContext, - IN PWORD pwCapInfo, - IN PWLAN_IE_SUPP_RATES pSuppRates, - IN PWLAN_IE_SUPP_RATES pExtSuppRates + HANDLE hDeviceContext, + PWORD pwCapInfo, + PWLAN_IE_SUPP_RATES pSuppRates, + PWLAN_IE_SUPP_RATES pExtSuppRates ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -964,7 +964,7 @@ BSSvUpdateAPNode( VOID BSSvAddMulticastNode( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1011,7 +1011,7 @@ BSSvAddMulticastNode( VOID BSSvSecondCallBack( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1397,10 +1397,10 @@ else { VOID BSSvUpdateNodeTxCounter( - IN HANDLE hDeviceContext, - IN PSStatCounter pStatistic, - IN BYTE byTSR, - IN BYTE byPktNO + HANDLE hDeviceContext, + PSStatCounter pStatistic, + BYTE byTSR, + BYTE byPktNO ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1566,8 +1566,8 @@ BSSvUpdateNodeTxCounter( VOID BSSvClearNodeDBTable( - IN HANDLE hDeviceContext, - IN UINT uStartIndex + HANDLE hDeviceContext, + UINT uStartIndex ) { @@ -1594,7 +1594,7 @@ BSSvClearNodeDBTable( VOID s_vCheckSensitivity( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1638,7 +1638,7 @@ VOID s_vCheckSensitivity( #ifdef Calcu_LinkQual VOID s_uCalculateLinkQual( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1687,7 +1687,7 @@ else VOID BSSvClearAnyBSSJoinRecord ( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1701,7 +1701,7 @@ BSSvClearAnyBSSJoinRecord ( } VOID s_vCheckPreEDThreshold( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; diff --git a/drivers/staging/vt6656/bssdb.h b/drivers/staging/vt6656/bssdb.h index f365b6b8bf6a..eec6cea86071 100644 --- a/drivers/staging/vt6656/bssdb.h +++ b/drivers/staging/vt6656/bssdb.h @@ -233,127 +233,127 @@ typedef struct tagKnownNodeDB { PKnownBSS BSSpSearchBSSList( - IN HANDLE hDeviceContext, - IN PBYTE pbyDesireBSSID, - IN PBYTE pbyDesireSSID, - IN CARD_PHY_TYPE ePhyType + HANDLE hDeviceContext, + PBYTE pbyDesireBSSID, + PBYTE pbyDesireSSID, + CARD_PHY_TYPE ePhyType ); PKnownBSS BSSpAddrIsInBSSList( - IN HANDLE hDeviceContext, - IN PBYTE abyBSSID, - IN PWLAN_IE_SSID pSSID + HANDLE hDeviceContext, + PBYTE abyBSSID, + PWLAN_IE_SSID pSSID ); VOID BSSvClearBSSList( - IN HANDLE hDeviceContext, - IN BOOL bKeepCurrBSSID + HANDLE hDeviceContext, + BOOL bKeepCurrBSSID ); BOOL BSSbInsertToBSSList( - IN HANDLE hDeviceContext, - IN PBYTE abyBSSIDAddr, - IN QWORD qwTimestamp, - IN WORD wBeaconInterval, - IN WORD wCapInfo, - IN BYTE byCurrChannel, - IN PWLAN_IE_SSID pSSID, - IN PWLAN_IE_SUPP_RATES pSuppRates, - IN PWLAN_IE_SUPP_RATES pExtSuppRates, - IN PERPObject psERP, - IN PWLAN_IE_RSN pRSN, - IN PWLAN_IE_RSN_EXT pRSNWPA, - IN PWLAN_IE_COUNTRY pIE_Country, - IN PWLAN_IE_QUIET pIE_Quiet, - IN UINT uIELength, - IN PBYTE pbyIEs, - IN HANDLE pRxPacketContext + HANDLE hDeviceContext, + PBYTE abyBSSIDAddr, + QWORD qwTimestamp, + WORD wBeaconInterval, + WORD wCapInfo, + BYTE byCurrChannel, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pSuppRates, + PWLAN_IE_SUPP_RATES pExtSuppRates, + PERPObject psERP, + PWLAN_IE_RSN pRSN, + PWLAN_IE_RSN_EXT pRSNWPA, + PWLAN_IE_COUNTRY pIE_Country, + PWLAN_IE_QUIET pIE_Quiet, + UINT uIELength, + PBYTE pbyIEs, + HANDLE pRxPacketContext ); BOOL BSSbUpdateToBSSList( - IN HANDLE hDeviceContext, - IN QWORD qwTimestamp, - IN WORD wBeaconInterval, - IN WORD wCapInfo, - IN BYTE byCurrChannel, - IN BOOL bChannelHit, - IN PWLAN_IE_SSID pSSID, - IN PWLAN_IE_SUPP_RATES pSuppRates, - IN PWLAN_IE_SUPP_RATES pExtSuppRates, - IN PERPObject psERP, - IN PWLAN_IE_RSN pRSN, - IN PWLAN_IE_RSN_EXT pRSNWPA, - IN PWLAN_IE_COUNTRY pIE_Country, - IN PWLAN_IE_QUIET pIE_Quiet, - IN PKnownBSS pBSSList, - IN UINT uIELength, - IN PBYTE pbyIEs, - IN HANDLE pRxPacketContext + HANDLE hDeviceContext, + QWORD qwTimestamp, + WORD wBeaconInterval, + WORD wCapInfo, + BYTE byCurrChannel, + BOOL bChannelHit, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pSuppRates, + PWLAN_IE_SUPP_RATES pExtSuppRates, + PERPObject psERP, + PWLAN_IE_RSN pRSN, + PWLAN_IE_RSN_EXT pRSNWPA, + PWLAN_IE_COUNTRY pIE_Country, + PWLAN_IE_QUIET pIE_Quiet, + PKnownBSS pBSSList, + UINT uIELength, + PBYTE pbyIEs, + HANDLE pRxPacketContext ); BOOL BSSbIsSTAInNodeDB( - IN HANDLE hDeviceContext, - IN PBYTE abyDstAddr, + HANDLE hDeviceContext, + PBYTE abyDstAddr, OUT PUINT puNodeIndex ); VOID BSSvCreateOneNode( - IN HANDLE hDeviceContext, + HANDLE hDeviceContext, OUT PUINT puNodeIndex ); VOID BSSvUpdateAPNode( - IN HANDLE hDeviceContext, - IN PWORD pwCapInfo, - IN PWLAN_IE_SUPP_RATES pItemRates, - IN PWLAN_IE_SUPP_RATES pExtSuppRates + HANDLE hDeviceContext, + PWORD pwCapInfo, + PWLAN_IE_SUPP_RATES pItemRates, + PWLAN_IE_SUPP_RATES pExtSuppRates ); VOID BSSvSecondCallBack( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ); VOID BSSvUpdateNodeTxCounter( - IN HANDLE hDeviceContext, - IN PSStatCounter pStatistic, - IN BYTE byTSR, - IN BYTE byPktNO + HANDLE hDeviceContext, + PSStatCounter pStatistic, + BYTE byTSR, + BYTE byPktNO ); VOID BSSvRemoveOneNode( - IN HANDLE hDeviceContext, - IN UINT uNodeIndex + HANDLE hDeviceContext, + UINT uNodeIndex ); VOID BSSvAddMulticastNode( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ); VOID BSSvClearNodeDBTable( - IN HANDLE hDeviceContext, - IN UINT uStartIndex + HANDLE hDeviceContext, + UINT uStartIndex ); VOID BSSvClearAnyBSSJoinRecord( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ); #endif //__BSSDB_H__ diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c index d73efeea2d5c..4ad1e94ffba4 100644 --- a/drivers/staging/vt6656/card.c +++ b/drivers/staging/vt6656/card.c @@ -224,8 +224,8 @@ WORD swGetOFDMControlRate (PVOID pDeviceHandler, WORD wRateIdx) */ VOID CARDvCaculateOFDMRParameter ( - IN WORD wRate, - IN BYTE byBBType, + WORD wRate, + BYTE byBBType, OUT PBYTE pbyTxRate, OUT PBYTE pbyRsvTime ) @@ -1080,10 +1080,10 @@ void CARDvSetBSSMode (PVOID pDeviceHandler) -*/ BOOL CARDbChannelSwitch ( - IN PVOID pDeviceHandler, - IN BYTE byMode, - IN BYTE byNewChannel, - IN BYTE byCount + PVOID pDeviceHandler, + BYTE byMode, + BYTE byNewChannel, + BYTE byCount ) { PSDevice pDevice = (PSDevice) pDeviceHandler; diff --git a/drivers/staging/vt6656/card.h b/drivers/staging/vt6656/card.h index aa90c2cb4461..16beb71a19bb 100644 --- a/drivers/staging/vt6656/card.h +++ b/drivers/staging/vt6656/card.h @@ -83,10 +83,10 @@ void CARDvSetBSSMode(PVOID pDeviceHandler); BOOL CARDbChannelSwitch ( - IN PVOID pDeviceHandler, - IN BYTE byMode, - IN BYTE byNewChannel, - IN BYTE byCount + PVOID pDeviceHandler, + BYTE byMode, + BYTE byNewChannel, + BYTE byCount ); #endif // __CARD_H__ diff --git a/drivers/staging/vt6656/channel.c b/drivers/staging/vt6656/channel.c index f7136b0073bb..32500af78bc4 100644 --- a/drivers/staging/vt6656/channel.c +++ b/drivers/staging/vt6656/channel.c @@ -425,7 +425,7 @@ exit: ************************************************************************/ BOOL CHvChannelGetList ( - IN UINT uCountryCodeIdx, + UINT uCountryCodeIdx, OUT PBYTE pbyChannelTable ) { diff --git a/drivers/staging/vt6656/channel.h b/drivers/staging/vt6656/channel.h index 2306b2025656..c965d6aff15f 100644 --- a/drivers/staging/vt6656/channel.h +++ b/drivers/staging/vt6656/channel.h @@ -50,7 +50,7 @@ BYTE CHbyGetChannelMapping(BYTE byChannelNumber); BOOL CHvChannelGetList ( - IN UINT uCountryCodeIdx, + UINT uCountryCodeIdx, OUT PBYTE pbyChannelTable ); diff --git a/drivers/staging/vt6656/control.h b/drivers/staging/vt6656/control.h index 4d9a777a7064..106c9e9f2b3c 100644 --- a/drivers/staging/vt6656/control.h +++ b/drivers/staging/vt6656/control.h @@ -54,27 +54,27 @@ /*--------------------- Export Functions --------------------------*/ void ControlvWriteByte( - IN PSDevice pDevice, - IN BYTE byRegType, - IN BYTE byRegOfs, - IN BYTE byData + PSDevice pDevice, + BYTE byRegType, + BYTE byRegOfs, + BYTE byData ); void ControlvReadByte( - IN PSDevice pDevice, - IN BYTE byRegType, - IN BYTE byRegOfs, - IN PBYTE pbyData + PSDevice pDevice, + BYTE byRegType, + BYTE byRegOfs, + PBYTE pbyData ); void ControlvMaskByte( - IN PSDevice pDevice, - IN BYTE byRegType, - IN BYTE byRegOfs, - IN BYTE byMask, - IN BYTE byData + PSDevice pDevice, + BYTE byRegType, + BYTE byRegOfs, + BYTE byMask, + BYTE byData ); #endif // __RCV_H__ diff --git a/drivers/staging/vt6656/datarate.c b/drivers/staging/vt6656/datarate.c index 968feb466b0c..e487af57213f 100644 --- a/drivers/staging/vt6656/datarate.c +++ b/drivers/staging/vt6656/datarate.c @@ -66,14 +66,14 @@ const BYTE acbyIERate[MAX_RATE] = /*--------------------- Static Functions --------------------------*/ VOID s_vResetCounter ( - IN PKnownNodeDB psNodeDBTable + PKnownNodeDB psNodeDBTable ); VOID s_vResetCounter ( - IN PKnownNodeDB psNodeDBTable + PKnownNodeDB psNodeDBTable ) { BYTE ii; @@ -107,7 +107,7 @@ s_vResetCounter ( -*/ BYTE DATARATEbyGetRateIdx ( - IN BYTE byRate + BYTE byRate ) { BYTE ii; @@ -161,7 +161,7 @@ DATARATEbyGetRateIdx ( -*/ WORD RATEwGetRateIdx( - IN BYTE byRate + BYTE byRate ) { WORD ii; @@ -197,10 +197,10 @@ RATEwGetRateIdx( -*/ VOID RATEvParseMaxRate ( - IN PVOID pDeviceHandler, - IN PWLAN_IE_SUPP_RATES pItemRates, - IN PWLAN_IE_SUPP_RATES pItemExtRates, - IN BOOL bUpdateBasicRate, + PVOID pDeviceHandler, + PWLAN_IE_SUPP_RATES pItemRates, + PWLAN_IE_SUPP_RATES pItemExtRates, + BOOL bUpdateBasicRate, OUT PWORD pwMaxBasicRate, OUT PWORD pwMaxSuppRate, OUT PWORD pwSuppRate, @@ -310,8 +310,8 @@ UINT uRateLen; VOID RATEvTxRateFallBack ( - IN PVOID pDeviceHandler, - IN PKnownNodeDB psNodeDBTable + PVOID pDeviceHandler, + PKnownNodeDB psNodeDBTable ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -473,9 +473,9 @@ if (wIdxUpRate == RATE_54M ) { //11a/g -*/ BYTE RATEuSetIE ( - IN PWLAN_IE_SUPP_RATES pSrcRates, - IN PWLAN_IE_SUPP_RATES pDstRates, - IN UINT uRateLen + PWLAN_IE_SUPP_RATES pSrcRates, + PWLAN_IE_SUPP_RATES pDstRates, + UINT uRateLen ) { UINT ii, uu, uRateCnt = 0; diff --git a/drivers/staging/vt6656/datarate.h b/drivers/staging/vt6656/datarate.h index 68f206e2707b..5024f716238b 100644 --- a/drivers/staging/vt6656/datarate.h +++ b/drivers/staging/vt6656/datarate.h @@ -71,10 +71,10 @@ VOID RATEvParseMaxRate( - IN PVOID pDeviceHandler, - IN PWLAN_IE_SUPP_RATES pItemRates, - IN PWLAN_IE_SUPP_RATES pItemExtRates, - IN BOOL bUpdateBasicRate, + PVOID pDeviceHandler, + PWLAN_IE_SUPP_RATES pItemRates, + PWLAN_IE_SUPP_RATES pItemExtRates, + BOOL bUpdateBasicRate, OUT PWORD pwMaxBasicRate, OUT PWORD pwMaxSuppRate, OUT PWORD pwSuppRate, @@ -84,26 +84,26 @@ RATEvParseMaxRate( VOID RATEvTxRateFallBack( - IN PVOID pDeviceHandler, - IN PKnownNodeDB psNodeDBTable + PVOID pDeviceHandler, + PKnownNodeDB psNodeDBTable ); BYTE RATEuSetIE( - IN PWLAN_IE_SUPP_RATES pSrcRates, - IN PWLAN_IE_SUPP_RATES pDstRates, - IN UINT uRateLen + PWLAN_IE_SUPP_RATES pSrcRates, + PWLAN_IE_SUPP_RATES pDstRates, + UINT uRateLen ); WORD RATEwGetRateIdx( - IN BYTE byRate + BYTE byRate ); BYTE DATARATEbyGetRateIdx( - IN BYTE byRate + BYTE byRate ); diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index 9e833bb08e38..957b7622eb68 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -74,13 +74,12 @@ const BYTE acbyRxRate[MAX_RATE] = /*--------------------- Static Functions --------------------------*/ -static BYTE s_byGetRateIdx(IN BYTE byRate); - +static BYTE s_byGetRateIdx(BYTE byRate); static VOID s_vGetDASA( - IN PBYTE pbyRxBufferAddr, + PBYTE pbyRxBufferAddr, OUT PUINT pcbHeaderSize, OUT PSEthernetHeader psEthHeader ); @@ -88,37 +87,37 @@ s_vGetDASA( static VOID s_vProcessRxMACHeader ( - IN PSDevice pDevice, - IN PBYTE pbyRxBufferAddr, - IN UINT cbPacketSize, - IN BOOL bIsWEP, - IN BOOL bExtIV, + PSDevice pDevice, + PBYTE pbyRxBufferAddr, + UINT cbPacketSize, + BOOL bIsWEP, + BOOL bExtIV, OUT PUINT pcbHeadSize ); static BOOL s_bAPModeRxCtl( - IN PSDevice pDevice, - IN PBYTE pbyFrame, - IN INT iSANodeIndex + PSDevice pDevice, + PBYTE pbyFrame, + INT iSANodeIndex ); static BOOL s_bAPModeRxData ( - IN PSDevice pDevice, - IN struct sk_buff* skb, - IN UINT FrameSize, - IN UINT cbHeaderOffset, - IN INT iSANodeIndex, - IN INT iDANodeIndex + PSDevice pDevice, + struct sk_buff *skb, + UINT FrameSize, + UINT cbHeaderOffset, + INT iSANodeIndex, + INT iDANodeIndex ); static BOOL s_bHandleRxEncryption( - IN PSDevice pDevice, - IN PBYTE pbyFrame, - IN UINT FrameSize, - IN PBYTE pbyRsr, + PSDevice pDevice, + PBYTE pbyFrame, + UINT FrameSize, + PBYTE pbyRsr, OUT PBYTE pbyNewRsr, OUT PSKeyItem *pKeyOut, int * pbExtIV, @@ -128,12 +127,12 @@ static BOOL s_bHandleRxEncryption( static BOOL s_bHostWepRxEncryption( - IN PSDevice pDevice, - IN PBYTE pbyFrame, - IN UINT FrameSize, - IN PBYTE pbyRsr, - IN BOOL bOnFly, - IN PSKeyItem pKey, + PSDevice pDevice, + PBYTE pbyFrame, + UINT FrameSize, + PBYTE pbyRsr, + BOOL bOnFly, + PSKeyItem pKey, OUT PBYTE pbyNewRsr, int * pbExtIV, OUT PWORD pwRxTSC15_0, @@ -163,11 +162,11 @@ static BOOL s_bHostWepRxEncryption( static VOID s_vProcessRxMACHeader ( - IN PSDevice pDevice, - IN PBYTE pbyRxBufferAddr, - IN UINT cbPacketSize, - IN BOOL bIsWEP, - IN BOOL bExtIV, + PSDevice pDevice, + PBYTE pbyRxBufferAddr, + UINT cbPacketSize, + BOOL bIsWEP, + BOOL bExtIV, OUT PUINT pcbHeadSize ) { @@ -247,7 +246,7 @@ s_vProcessRxMACHeader ( -static BYTE s_byGetRateIdx (IN BYTE byRate) +static BYTE s_byGetRateIdx(BYTE byRate) { BYTE byRateIdx; @@ -262,7 +261,7 @@ static BYTE s_byGetRateIdx (IN BYTE byRate) static VOID s_vGetDASA ( - IN PBYTE pbyRxBufferAddr, + PBYTE pbyRxBufferAddr, OUT PUINT pcbHeaderSize, OUT PSEthernetHeader psEthHeader ) @@ -317,9 +316,9 @@ s_vGetDASA ( BOOL RXbBulkInProcessData ( - IN PSDevice pDevice, - IN PRCB pRCB, - IN ULONG BytesToIndicate + PSDevice pDevice, + PRCB pRCB, + ULONG BytesToIndicate ) { @@ -1022,9 +1021,9 @@ RXbBulkInProcessData ( static BOOL s_bAPModeRxCtl ( - IN PSDevice pDevice, - IN PBYTE pbyFrame, - IN INT iSANodeIndex + PSDevice pDevice, + PBYTE pbyFrame, + INT iSANodeIndex ) { PS802_11Header p802_11Header; @@ -1144,10 +1143,10 @@ static BOOL s_bAPModeRxCtl ( } static BOOL s_bHandleRxEncryption ( - IN PSDevice pDevice, - IN PBYTE pbyFrame, - IN UINT FrameSize, - IN PBYTE pbyRsr, + PSDevice pDevice, + PBYTE pbyFrame, + UINT FrameSize, + PBYTE pbyRsr, OUT PBYTE pbyNewRsr, OUT PSKeyItem *pKeyOut, int * pbExtIV, @@ -1290,12 +1289,12 @@ static BOOL s_bHandleRxEncryption ( static BOOL s_bHostWepRxEncryption ( - IN PSDevice pDevice, - IN PBYTE pbyFrame, - IN UINT FrameSize, - IN PBYTE pbyRsr, - IN BOOL bOnFly, - IN PSKeyItem pKey, + PSDevice pDevice, + PBYTE pbyFrame, + UINT FrameSize, + PBYTE pbyRsr, + BOOL bOnFly, + PSKeyItem pKey, OUT PBYTE pbyNewRsr, int * pbExtIV, OUT PWORD pwRxTSC15_0, @@ -1422,12 +1421,12 @@ static BOOL s_bHostWepRxEncryption ( static BOOL s_bAPModeRxData ( - IN PSDevice pDevice, - IN struct sk_buff* skb, - IN UINT FrameSize, - IN UINT cbHeaderOffset, - IN INT iSANodeIndex, - IN INT iDANodeIndex + PSDevice pDevice, + struct sk_buff *skb, + UINT FrameSize, + UINT cbHeaderOffset, + INT iSANodeIndex, + INT iDANodeIndex ) { @@ -1542,8 +1541,8 @@ RXvWorkItem( VOID RXvFreeRCB( - IN PRCB pRCB, - IN BOOL bReAllocSkb + PRCB pRCB, + BOOL bReAllocSkb ) { PSDevice pDevice = (PSDevice)pRCB->pDevice; diff --git a/drivers/staging/vt6656/dpc.h b/drivers/staging/vt6656/dpc.h index df148b453966..8e6dceef2407 100644 --- a/drivers/staging/vt6656/dpc.h +++ b/drivers/staging/vt6656/dpc.h @@ -53,15 +53,15 @@ RXvMngWorkItem( VOID RXvFreeRCB( - IN PRCB pRCB, - IN BOOL bReAllocSkb + PRCB pRCB, + BOOL bReAllocSkb ); BOOL RXbBulkInProcessData( - IN PSDevice pDevice, - IN PRCB pRCB, - IN ULONG BytesToIndicate + PSDevice pDevice, + PRCB pRCB, + ULONG BytesToIndicate ); #endif // __RXTX_H__ diff --git a/drivers/staging/vt6656/firmware.c b/drivers/staging/vt6656/firmware.c index 585b6b12c5ba..e1f96d7086f7 100644 --- a/drivers/staging/vt6656/firmware.c +++ b/drivers/staging/vt6656/firmware.c @@ -770,7 +770,7 @@ const BYTE abyFirmware[] = { BOOL FIRMWAREbDownload( - IN PSDevice pDevice + PSDevice pDevice ) { NDIS_STATUS NdisStatus; @@ -820,7 +820,7 @@ FIRMWAREbDownload( BOOL FIRMWAREbBrach2Sram( - IN PSDevice pDevice + PSDevice pDevice ) { NDIS_STATUS NdisStatus; @@ -845,7 +845,7 @@ FIRMWAREbBrach2Sram( BOOL FIRMWAREbCheckVersion( - IN PSDevice pDevice + PSDevice pDevice ) { NTSTATUS ntStatus; diff --git a/drivers/staging/vt6656/firmware.h b/drivers/staging/vt6656/firmware.h index 97f8559f2a55..10e84cdf21b3 100644 --- a/drivers/staging/vt6656/firmware.h +++ b/drivers/staging/vt6656/firmware.h @@ -43,17 +43,17 @@ BOOL FIRMWAREbDownload( - IN PSDevice pDevice + PSDevice pDevice ); BOOL FIRMWAREbBrach2Sram( - IN PSDevice pDevice + PSDevice pDevice ); BOOL FIRMWAREbCheckVersion( - IN PSDevice pDevice + PSDevice pDevice ); diff --git a/drivers/staging/vt6656/int.c b/drivers/staging/vt6656/int.c index 824c67de0ea9..a47eeb069300 100644 --- a/drivers/staging/vt6656/int.c +++ b/drivers/staging/vt6656/int.c @@ -94,7 +94,7 @@ INTvWorkItem(PVOID Context) } NTSTATUS -INTnsProcessData(IN PSDevice pDevice) +INTnsProcessData(PSDevice pDevice) { NTSTATUS status = STATUS_SUCCESS; PSINTData pINTData; diff --git a/drivers/staging/vt6656/int.h b/drivers/staging/vt6656/int.h index 15e815a35967..c3476cff5429 100644 --- a/drivers/staging/vt6656/int.h +++ b/drivers/staging/vt6656/int.h @@ -74,7 +74,7 @@ INTvWorkItem( NTSTATUS INTnsProcessData( - IN PSDevice pDevice + PSDevice pDevice ); #endif // __INT_H__ diff --git a/drivers/staging/vt6656/ioctl.h b/drivers/staging/vt6656/ioctl.h index 07d228399c3c..d3f49d444164 100644 --- a/drivers/staging/vt6656/ioctl.h +++ b/drivers/staging/vt6656/ioctl.h @@ -44,10 +44,10 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq); /* VOID vConfigWEPKey ( - IN PSDevice pDevice, - IN DWORD dwKeyIndex, - IN PBYTE pbyKey, - IN ULONG uKeyLength + PSDevice pDevice, + DWORD dwKeyIndex, + PBYTE pbyKey, + ULONG uKeyLength ); */ diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c index 0cd2751d67d5..6cdc85e8352d 100644 --- a/drivers/staging/vt6656/key.c +++ b/drivers/staging/vt6656/key.c @@ -163,9 +163,9 @@ VOID KeyvInitTable(PVOID pDeviceHandler, PSKeyManagement pTable) * */ BOOL KeybGetKey ( - IN PSKeyManagement pTable, - IN PBYTE pbyBSSID, - IN DWORD dwKeyIndex, + PSKeyManagement pTable, + PBYTE pbyBSSID, + DWORD dwKeyIndex, OUT PSKeyItem *pKey ) { @@ -562,9 +562,9 @@ VOID KeyvRemoveAllWEPKey ( * */ BOOL KeybGetTransmitKey ( - IN PSKeyManagement pTable, - IN PBYTE pbyBSSID, - IN DWORD dwKeyType, + PSKeyManagement pTable, + PBYTE pbyBSSID, + DWORD dwKeyType, OUT PSKeyItem *pKey ) { @@ -642,7 +642,7 @@ BOOL KeybGetTransmitKey ( * */ BOOL KeybCheckPairewiseKey ( - IN PSKeyManagement pTable, + PSKeyManagement pTable, OUT PSKeyItem *pKey ) { diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h index da8dfe09cf3c..11236e848d9b 100644 --- a/drivers/staging/vt6656/key.h +++ b/drivers/staging/vt6656/key.h @@ -100,9 +100,9 @@ typedef struct tagSKeyManagement VOID KeyvInitTable(PVOID pDeviceHandler, PSKeyManagement pTable); BOOL KeybGetKey( - IN PSKeyManagement pTable, - IN PBYTE pbyBSSID, - IN DWORD dwKeyIndex, + PSKeyManagement pTable, + PBYTE pbyBSSID, + DWORD dwKeyIndex, OUT PSKeyItem *pKey ); @@ -142,14 +142,14 @@ VOID KeyvRemoveAllWEPKey( ); BOOL KeybGetTransmitKey( - IN PSKeyManagement pTable, - IN PBYTE pbyBSSID, - IN DWORD dwKeyType, + PSKeyManagement pTable, + PBYTE pbyBSSID, + DWORD dwKeyType, OUT PSKeyItem *pKey ); BOOL KeybCheckPairewiseKey( - IN PSKeyManagement pTable, + PSKeyManagement pTable, OUT PSKeyItem *pKey ); diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c index b5702b098e18..e50093e355a9 100644 --- a/drivers/staging/vt6656/power.c +++ b/drivers/staging/vt6656/power.c @@ -78,8 +78,8 @@ static int msglevel =MSG_LEVEL_INFO; VOID PSvEnablePowerSaving( - IN HANDLE hDeviceContext, - IN WORD wListenInterval + HANDLE hDeviceContext, + WORD wListenInterval ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -156,7 +156,7 @@ PSvEnablePowerSaving( VOID PSvDisablePowerSaving( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -201,9 +201,9 @@ PSvDisablePowerSaving( BOOL PSbConsiderPowerDown( - IN HANDLE hDeviceContext, - IN BOOL bCheckRxDMA, - IN BOOL bCheckCountToWakeUp + HANDLE hDeviceContext, + BOOL bCheckRxDMA, + BOOL bCheckCountToWakeUp ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -264,7 +264,7 @@ PSbConsiderPowerDown( VOID PSvSendPSPOLL( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -310,7 +310,7 @@ PSvSendPSPOLL( -*/ BOOL PSbSendNullPacket( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -390,7 +390,7 @@ PSbSendNullPacket( BOOL PSbIsNextTBTTWakeUp( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ) { diff --git a/drivers/staging/vt6656/power.h b/drivers/staging/vt6656/power.h index c33c93a86f5e..0a14811ced97 100644 --- a/drivers/staging/vt6656/power.h +++ b/drivers/staging/vt6656/power.h @@ -45,40 +45,40 @@ /*--------------------- Export Functions --------------------------*/ -// IN PSDevice pDevice -// IN PSDevice hDeviceContext +/* PSDevice pDevice */ +/* PSDevice hDeviceContext */ BOOL PSbConsiderPowerDown( - IN HANDLE hDeviceContext, - IN BOOL bCheckRxDMA, - IN BOOL bCheckCountToWakeUp + HANDLE hDeviceContext, + BOOL bCheckRxDMA, + BOOL bCheckCountToWakeUp ); VOID PSvDisablePowerSaving( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ); VOID PSvEnablePowerSaving( - IN HANDLE hDeviceContext, - IN WORD wListenInterval + HANDLE hDeviceContext, + WORD wListenInterval ); VOID PSvSendPSPOLL( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ); BOOL PSbSendNullPacket( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ); BOOL PSbIsNextTBTTWakeUp( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ); #endif //__POWER_H__ diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c index 405c4f71b5fd..d69925ff469b 100644 --- a/drivers/staging/vt6656/rf.c +++ b/drivers/staging/vt6656/rf.c @@ -757,9 +757,9 @@ BOOL IFRFbWriteEmbeded (PSDevice pDevice, DWORD dwData) * */ BOOL RFbSetPower ( - IN PSDevice pDevice, - IN UINT uRATE, - IN UINT uCH + PSDevice pDevice, + UINT uRATE, + UINT uCH ) { BOOL bResult = TRUE; @@ -811,9 +811,9 @@ BYTE byPwr = pDevice->byCCKPwr; * */ BOOL RFbRawSetPower ( - IN PSDevice pDevice, - IN BYTE byPwr, - IN UINT uRATE + PSDevice pDevice, + BYTE byPwr, + UINT uRATE ) { BOOL bResult = TRUE; @@ -956,8 +956,8 @@ BOOL bResult = TRUE; -*/ VOID RFvRSSITodBm ( - IN PSDevice pDevice, - IN BYTE byCurrRSSI, + PSDevice pDevice, + BYTE byCurrRSSI, long * pldBm ) { @@ -986,7 +986,7 @@ RFvRSSITodBm ( VOID RFbRFTableDownload ( - IN PSDevice pDevice + PSDevice pDevice ) { WORD wLength1 = 0,wLength2 = 0 ,wLength3 = 0; @@ -1133,9 +1133,9 @@ BYTE abyArray[256]; // RobertYu:20060412, TWIF1.11 adjust LO Current for 11b mode BOOL s_bVT3226D0_11bLoCurrentAdjust( - IN PSDevice pDevice, - IN BYTE byChannel, - IN BOOL b11bMode ) + PSDevice pDevice, + BYTE byChannel, + BOOL b11bMode) { BOOL bResult; diff --git a/drivers/staging/vt6656/rf.h b/drivers/staging/vt6656/rf.h index 55d882f78f20..22159869364e 100644 --- a/drivers/staging/vt6656/rf.h +++ b/drivers/staging/vt6656/rf.h @@ -65,33 +65,33 @@ extern const BYTE RFaby11aChannelIndex[200]; BOOL IFRFbWriteEmbeded(PSDevice pDevice, DWORD dwData); BOOL RFbSetPower ( - IN PSDevice pDevice, - IN UINT uRATE, - IN UINT uCH + PSDevice pDevice, + UINT uRATE, + UINT uCH ); BOOL RFbRawSetPower( - IN PSDevice pDevice, - IN BYTE byPwr, - IN UINT uRATE + PSDevice pDevice, + BYTE byPwr, + UINT uRATE ); VOID RFvRSSITodBm ( - IN PSDevice pDevice, - IN BYTE byCurrRSSI, + PSDevice pDevice, + BYTE byCurrRSSI, long * pldBm ); VOID RFbRFTableDownload ( - IN PSDevice pDevice + PSDevice pDevice ); BOOL s_bVT3226D0_11bLoCurrentAdjust( - IN PSDevice pDevice, - IN BYTE byChannel, - IN BOOL b11bMode + PSDevice pDevice, + BYTE byChannel, + BOOL b11bMode ); #endif // __RF_H__ diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index 03b8b4decf09..1d7ca2286248 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -115,11 +115,11 @@ const WORD wFB_Opt1[2][5] = { static VOID s_vSaveTxPktInfo( - IN PSDevice pDevice, - IN BYTE byPktNum, - IN PBYTE pbyDestAddr, - IN WORD wPktLength, - IN WORD wFIFOCtl + PSDevice pDevice, + BYTE byPktNum, + PBYTE pbyDestAddr, + WORD wPktLength, + WORD wFIFOCtl ); static @@ -132,34 +132,34 @@ s_vGetFreeContext( static VOID s_vGenerateTxParameter( - IN PSDevice pDevice, - IN BYTE byPktType, - IN WORD wCurrentRate, - IN PVOID pTxBufHead, - IN PVOID pvRrvTime, - IN PVOID pvRTS, - IN PVOID pvCTS, - IN UINT cbFrameSize, - IN BOOL bNeedACK, - IN UINT uDMAIdx, - IN PSEthernetHeader psEthHeader + PSDevice pDevice, + BYTE byPktType, + WORD wCurrentRate, + PVOID pTxBufHead, + PVOID pvRrvTime, + PVOID pvRTS, + PVOID pvCTS, + UINT cbFrameSize, + BOOL bNeedACK, + UINT uDMAIdx, + PSEthernetHeader psEthHeader ); static UINT s_uFillDataHead ( - IN PSDevice pDevice, - IN BYTE byPktType, - IN WORD wCurrentRate, - IN PVOID pTxDataHead, - IN UINT cbFrameLength, - IN UINT uDMAIdx, - IN BOOL bNeedAck, - IN UINT uFragIdx, - IN UINT cbLastFragmentSize, - IN UINT uMACfragNum, - IN BYTE byFBOption + PSDevice pDevice, + BYTE byPktType, + WORD wCurrentRate, + PVOID pTxDataHead, + UINT cbFrameLength, + UINT uDMAIdx, + BOOL bNeedAck, + UINT uFragIdx, + UINT cbLastFragmentSize, + UINT uMACfragNum, + BYTE byFBOption ); @@ -168,112 +168,112 @@ s_uFillDataHead ( static VOID s_vGenerateMACHeader ( - IN PSDevice pDevice, - IN PBYTE pbyBufferAddr, - IN WORD wDuration, - IN PSEthernetHeader psEthHeader, - IN BOOL bNeedEncrypt, - IN WORD wFragType, - IN UINT uDMAIdx, - IN UINT uFragIdx + PSDevice pDevice, + PBYTE pbyBufferAddr, + WORD wDuration, + PSEthernetHeader psEthHeader, + BOOL bNeedEncrypt, + WORD wFragType, + UINT uDMAIdx, + UINT uFragIdx ); static VOID s_vFillTxKey( - IN PSDevice pDevice, - IN PBYTE pbyBuf, - IN PBYTE pbyIVHead, - IN PSKeyItem pTransmitKey, - IN PBYTE pbyHdrBuf, - IN WORD wPayloadLen, + PSDevice pDevice, + PBYTE pbyBuf, + PBYTE pbyIVHead, + PSKeyItem pTransmitKey, + PBYTE pbyHdrBuf, + WORD wPayloadLen, OUT PBYTE pMICHDR ); static VOID s_vSWencryption ( - IN PSDevice pDevice, - IN PSKeyItem pTransmitKey, - IN PBYTE pbyPayloadHead, - IN WORD wPayloadSize + PSDevice pDevice, + PSKeyItem pTransmitKey, + PBYTE pbyPayloadHead, + WORD wPayloadSize ); static UINT s_uGetTxRsvTime ( - IN PSDevice pDevice, - IN BYTE byPktType, - IN UINT cbFrameLength, - IN WORD wRate, - IN BOOL bNeedAck + PSDevice pDevice, + BYTE byPktType, + UINT cbFrameLength, + WORD wRate, + BOOL bNeedAck ); static UINT s_uGetRTSCTSRsvTime ( - IN PSDevice pDevice, - IN BYTE byRTSRsvType, - IN BYTE byPktType, - IN UINT cbFrameLength, - IN WORD wCurrentRate + PSDevice pDevice, + BYTE byRTSRsvType, + BYTE byPktType, + UINT cbFrameLength, + WORD wCurrentRate ); static VOID s_vFillCTSHead ( - IN PSDevice pDevice, - IN UINT uDMAIdx, - IN BYTE byPktType, - IN PVOID pvCTS, - IN UINT cbFrameLength, - IN BOOL bNeedAck, - IN BOOL bDisCRC, - IN WORD wCurrentRate, - IN BYTE byFBOption + PSDevice pDevice, + UINT uDMAIdx, + BYTE byPktType, + PVOID pvCTS, + UINT cbFrameLength, + BOOL bNeedAck, + BOOL bDisCRC, + WORD wCurrentRate, + BYTE byFBOption ); static VOID s_vFillRTSHead( - IN PSDevice pDevice, - IN BYTE byPktType, - IN PVOID pvRTS, - IN UINT cbFrameLength, - IN BOOL bNeedAck, - IN BOOL bDisCRC, - IN PSEthernetHeader psEthHeader, - IN WORD wCurrentRate, - IN BYTE byFBOption + PSDevice pDevice, + BYTE byPktType, + PVOID pvRTS, + UINT cbFrameLength, + BOOL bNeedAck, + BOOL bDisCRC, + PSEthernetHeader psEthHeader, + WORD wCurrentRate, + BYTE byFBOption ); static UINT s_uGetDataDuration ( - IN PSDevice pDevice, - IN BYTE byDurType, - IN UINT cbFrameLength, - IN BYTE byPktType, - IN WORD wRate, - IN BOOL bNeedAck, - IN UINT uFragIdx, - IN UINT cbLastFragmentSize, - IN UINT uMACfragNum, - IN BYTE byFBOption + PSDevice pDevice, + BYTE byDurType, + UINT cbFrameLength, + BYTE byPktType, + WORD wRate, + BOOL bNeedAck, + UINT uFragIdx, + UINT cbLastFragmentSize, + UINT uMACfragNum, + BYTE byFBOption ); static UINT s_uGetRTSCTSDuration ( - IN PSDevice pDevice, - IN BYTE byDurType, - IN UINT cbFrameLength, - IN BYTE byPktType, - IN WORD wRate, - IN BOOL bNeedAck, - IN BYTE byFBOption + PSDevice pDevice, + BYTE byDurType, + UINT cbFrameLength, + BYTE byPktType, + WORD wRate, + BOOL bNeedAck, + BYTE byFBOption ); @@ -333,12 +333,12 @@ s_vSaveTxPktInfo(PSDevice pDevice, BYTE byPktNum, PBYTE pbyDestAddr, WORD wPktLe static VOID s_vFillTxKey ( - IN PSDevice pDevice, - IN PBYTE pbyBuf, - IN PBYTE pbyIVHead, - IN PSKeyItem pTransmitKey, - IN PBYTE pbyHdrBuf, - IN WORD wPayloadLen, + PSDevice pDevice, + PBYTE pbyBuf, + PBYTE pbyIVHead, + PSKeyItem pTransmitKey, + PBYTE pbyHdrBuf, + WORD wPayloadLen, OUT PBYTE pMICHDR ) { @@ -450,10 +450,10 @@ s_vFillTxKey ( static VOID s_vSWencryption ( - IN PSDevice pDevice, - IN PSKeyItem pTransmitKey, - IN PBYTE pbyPayloadHead, - IN WORD wPayloadSize + PSDevice pDevice, + PSKeyItem pTransmitKey, + PBYTE pbyPayloadHead, + WORD wPayloadSize ) { UINT cbICVlen = 4; @@ -499,11 +499,11 @@ s_vSWencryption ( static UINT s_uGetTxRsvTime ( - IN PSDevice pDevice, - IN BYTE byPktType, - IN UINT cbFrameLength, - IN WORD wRate, - IN BOOL bNeedAck + PSDevice pDevice, + BYTE byPktType, + UINT cbFrameLength, + WORD wRate, + BOOL bNeedAck ) { UINT uDataTime, uAckTime; @@ -527,11 +527,11 @@ s_uGetTxRsvTime ( static UINT s_uGetRTSCTSRsvTime ( - IN PSDevice pDevice, - IN BYTE byRTSRsvType, - IN BYTE byPktType, - IN UINT cbFrameLength, - IN WORD wCurrentRate + PSDevice pDevice, + BYTE byRTSRsvType, + BYTE byPktType, + UINT cbFrameLength, + WORD wCurrentRate ) { UINT uRrvTime , uRTSTime, uCTSTime, uAckTime, uDataTime; @@ -569,16 +569,16 @@ s_uGetRTSCTSRsvTime ( static UINT s_uGetDataDuration ( - IN PSDevice pDevice, - IN BYTE byDurType, - IN UINT cbFrameLength, - IN BYTE byPktType, - IN WORD wRate, - IN BOOL bNeedAck, - IN UINT uFragIdx, - IN UINT cbLastFragmentSize, - IN UINT uMACfragNum, - IN BYTE byFBOption + PSDevice pDevice, + BYTE byDurType, + UINT cbFrameLength, + BYTE byPktType, + WORD wRate, + BOOL bNeedAck, + UINT uFragIdx, + UINT cbLastFragmentSize, + UINT uMACfragNum, + BYTE byFBOption ) { BOOL bLastFrag = 0; @@ -739,13 +739,13 @@ s_uGetDataDuration ( static UINT s_uGetRTSCTSDuration ( - IN PSDevice pDevice, - IN BYTE byDurType, - IN UINT cbFrameLength, - IN BYTE byPktType, - IN WORD wRate, - IN BOOL bNeedAck, - IN BYTE byFBOption + PSDevice pDevice, + BYTE byDurType, + UINT cbFrameLength, + BYTE byPktType, + WORD wRate, + BOOL bNeedAck, + BYTE byFBOption ) { UINT uCTSTime = 0, uDurTime = 0; @@ -838,17 +838,17 @@ s_uGetRTSCTSDuration ( static UINT s_uFillDataHead ( - IN PSDevice pDevice, - IN BYTE byPktType, - IN WORD wCurrentRate, - IN PVOID pTxDataHead, - IN UINT cbFrameLength, - IN UINT uDMAIdx, - IN BOOL bNeedAck, - IN UINT uFragIdx, - IN UINT cbLastFragmentSize, - IN UINT uMACfragNum, - IN BYTE byFBOption + PSDevice pDevice, + BYTE byPktType, + WORD wCurrentRate, + PVOID pTxDataHead, + UINT cbFrameLength, + UINT uDMAIdx, + BOOL bNeedAck, + UINT uFragIdx, + UINT cbLastFragmentSize, + UINT uMACfragNum, + BYTE byFBOption ) { @@ -983,15 +983,15 @@ s_uFillDataHead ( static VOID s_vFillRTSHead ( - IN PSDevice pDevice, - IN BYTE byPktType, - IN PVOID pvRTS, - IN UINT cbFrameLength, - IN BOOL bNeedAck, - IN BOOL bDisCRC, - IN PSEthernetHeader psEthHeader, - IN WORD wCurrentRate, - IN BYTE byFBOption + PSDevice pDevice, + BYTE byPktType, + PVOID pvRTS, + UINT cbFrameLength, + BOOL bNeedAck, + BOOL bDisCRC, + PSEthernetHeader psEthHeader, + WORD wCurrentRate, + BYTE byFBOption ) { UINT uRTSFrameLen = 20; @@ -1211,15 +1211,15 @@ s_vFillRTSHead ( static VOID s_vFillCTSHead ( - IN PSDevice pDevice, - IN UINT uDMAIdx, - IN BYTE byPktType, - IN PVOID pvCTS, - IN UINT cbFrameLength, - IN BOOL bNeedAck, - IN BOOL bDisCRC, - IN WORD wCurrentRate, - IN BYTE byFBOption + PSDevice pDevice, + UINT uDMAIdx, + BYTE byPktType, + PVOID pvCTS, + UINT cbFrameLength, + BOOL bNeedAck, + BOOL bDisCRC, + WORD wCurrentRate, + BYTE byFBOption ) { UINT uCTSFrameLen = 14; @@ -1311,17 +1311,17 @@ s_vFillCTSHead ( static VOID s_vGenerateTxParameter ( - IN PSDevice pDevice, - IN BYTE byPktType, - IN WORD wCurrentRate, - IN PVOID pTxBufHead, - IN PVOID pvRrvTime, - IN PVOID pvRTS, - IN PVOID pvCTS, - IN UINT cbFrameSize, - IN BOOL bNeedACK, - IN UINT uDMAIdx, - IN PSEthernetHeader psEthHeader + PSDevice pDevice, + BYTE byPktType, + WORD wCurrentRate, + PVOID pTxBufHead, + PVOID pvRrvTime, + PVOID pvRTS, + PVOID pvCTS, + UINT cbFrameSize, + BOOL bNeedACK, + UINT uDMAIdx, + PSEthernetHeader psEthHeader ) { UINT cbMACHdLen = WLAN_HDR_ADDR3_LEN; //24 @@ -1428,17 +1428,17 @@ s_vGenerateTxParameter ( BOOL s_bPacketToWirelessUsb( - IN PSDevice pDevice, - IN BYTE byPktType, - IN PBYTE usbPacketBuf, - IN BOOL bNeedEncryption, - IN UINT uSkbPacketLen, - IN UINT uDMAIdx, - IN PSEthernetHeader psEthHeader, - IN PBYTE pPacket, - IN PSKeyItem pTransmitKey, - IN UINT uNodeIndex, - IN WORD wCurrentRate, + PSDevice pDevice, + BYTE byPktType, + PBYTE usbPacketBuf, + BOOL bNeedEncryption, + UINT uSkbPacketLen, + UINT uDMAIdx, + PSEthernetHeader psEthHeader, + PBYTE pPacket, + PSKeyItem pTransmitKey, + UINT uNodeIndex, + WORD wCurrentRate, OUT UINT *pcbHeaderLen, OUT UINT *pcbTotalLen ) @@ -1858,14 +1858,14 @@ s_bPacketToWirelessUsb( VOID s_vGenerateMACHeader ( - IN PSDevice pDevice, - IN PBYTE pbyBufferAddr, - IN WORD wDuration, - IN PSEthernetHeader psEthHeader, - IN BOOL bNeedEncrypt, - IN WORD wFragType, - IN UINT uDMAIdx, - IN UINT uFragIdx + PSDevice pDevice, + PBYTE pbyBufferAddr, + WORD wDuration, + PSEthernetHeader psEthHeader, + BOOL bNeedEncrypt, + WORD wFragType, + UINT uDMAIdx, + UINT uFragIdx ) { PS802_11Header pMACHeader = (PS802_11Header)pbyBufferAddr; @@ -1958,8 +1958,8 @@ s_vGenerateMACHeader ( -*/ CMD_STATUS csMgmt_xmit( - IN PSDevice pDevice, - IN PSTxMgmtPacket pPacket + PSDevice pDevice, + PSTxMgmtPacket pPacket ) { BYTE byPktType; @@ -2251,8 +2251,8 @@ CMD_STATUS csMgmt_xmit( CMD_STATUS csBeacon_xmit( - IN PSDevice pDevice, - IN PSTxMgmtPacket pPacket + PSDevice pDevice, + PSTxMgmtPacket pPacket ) { @@ -2750,9 +2750,9 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb) { NTSTATUS nsDMA_tx_packet( - IN PSDevice pDevice, - IN UINT uDMAIdx, - IN struct sk_buff *skb + PSDevice pDevice, + UINT uDMAIdx, + struct sk_buff *skb ) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -3168,10 +3168,10 @@ nsDMA_tx_packet( BOOL bRelayPacketSend ( - IN PSDevice pDevice, - IN PBYTE pbySkbData, - IN UINT uDataLen, - IN UINT uNodeIndex + PSDevice pDevice, + PBYTE pbySkbData, + UINT uDataLen, + UINT uNodeIndex ) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h index 133f47520621..1160c0354f3f 100644 --- a/drivers/staging/vt6656/rxtx.h +++ b/drivers/staging/vt6656/rxtx.h @@ -667,17 +667,17 @@ typedef struct tagSBEACON_BUFFER BOOL bPacketToWirelessUsb( - IN PSDevice pDevice, - IN BYTE byPktType, - IN PBYTE usbPacketBuf, - IN BOOL bNeedEncrypt, - IN UINT cbPayloadSize, - IN UINT uDMAIdx, - IN PSEthernetHeader psEthHeader, - IN PBYTE pPacket, - IN PSKeyItem pTransmitKey, - IN UINT uNodeIndex, - IN WORD wCurrentRate, + PSDevice pDevice, + BYTE byPktType, + PBYTE usbPacketBuf, + BOOL bNeedEncrypt, + UINT cbPayloadSize, + UINT uDMAIdx, + PSEthernetHeader psEthHeader, + PBYTE pPacket, + PSKeyItem pTransmitKey, + UINT uNodeIndex, + WORD wCurrentRate, OUT UINT *pcbHeaderLen, OUT UINT *pcbTotalLen ); diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h index 9ee3f436fc3d..2365fa411393 100644 --- a/drivers/staging/vt6656/ttype.h +++ b/drivers/staging/vt6656/ttype.h @@ -37,10 +37,6 @@ #define VOID void #endif -#ifndef IN -#define IN -#endif - #ifndef OUT #define OUT #endif diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c index cd1da33cff7a..901c684b11e9 100644 --- a/drivers/staging/vt6656/usbpipe.c +++ b/drivers/staging/vt6656/usbpipe.c @@ -73,34 +73,34 @@ static int msglevel =MSG_LEVEL_INFO; static VOID s_nsInterruptUsbIoCompleteRead( - IN struct urb *urb + struct urb *urb ); static VOID s_nsBulkInUsbIoCompleteRead( - IN struct urb *urb + struct urb *urb ); static VOID s_nsBulkOutIoCompleteWrite( - IN struct urb *urb + struct urb *urb ); static VOID s_nsControlInUsbIoCompleteRead( - IN struct urb *urb + struct urb *urb ); static VOID s_nsControlInUsbIoCompleteWrite( - IN struct urb *urb + struct urb *urb ); /*--------------------- Export Variables --------------------------*/ @@ -111,12 +111,12 @@ s_nsControlInUsbIoCompleteWrite( NTSTATUS PIPEnsControlOutAsyn( - IN PSDevice pDevice, - IN BYTE byRequest, - IN WORD wValue, - IN WORD wIndex, - IN WORD wLength, - IN PBYTE pbyBuffer + PSDevice pDevice, + BYTE byRequest, + WORD wValue, + WORD wIndex, + WORD wLength, + PBYTE pbyBuffer ) { NTSTATUS ntStatus; @@ -162,12 +162,12 @@ PIPEnsControlOutAsyn( NTSTATUS PIPEnsControlOut( - IN PSDevice pDevice, - IN BYTE byRequest, - IN WORD wValue, - IN WORD wIndex, - IN WORD wLength, - IN PBYTE pbyBuffer + PSDevice pDevice, + BYTE byRequest, + WORD wValue, + WORD wIndex, + WORD wLength, + PBYTE pbyBuffer ) { NTSTATUS ntStatus = 0; @@ -224,12 +224,12 @@ PIPEnsControlOut( NTSTATUS PIPEnsControlIn( - IN PSDevice pDevice, - IN BYTE byRequest, - IN WORD wValue, - IN WORD wIndex, - IN WORD wLength, - IN OUT PBYTE pbyBuffer + PSDevice pDevice, + BYTE byRequest, + WORD wValue, + WORD wIndex, + WORD wLength, + OUT PBYTE pbyBuffer ) { NTSTATUS ntStatus = 0; @@ -281,7 +281,7 @@ PIPEnsControlIn( static VOID s_nsControlInUsbIoCompleteWrite( - IN struct urb *urb + struct urb *urb ) { PSDevice pDevice; @@ -322,7 +322,7 @@ s_nsControlInUsbIoCompleteWrite( static VOID s_nsControlInUsbIoCompleteRead( - IN struct urb *urb + struct urb *urb ) { PSDevice pDevice; @@ -362,7 +362,7 @@ s_nsControlInUsbIoCompleteRead( */ NTSTATUS PIPEnsInterruptRead( - IN PSDevice pDevice + PSDevice pDevice ) { NTSTATUS ntStatus = STATUS_FAILURE; @@ -443,7 +443,7 @@ usb_fill_bulk_urb(pDevice->pInterruptURB, static VOID s_nsInterruptUsbIoCompleteRead( - IN struct urb *urb + struct urb *urb ) { @@ -543,8 +543,8 @@ s_nsInterruptUsbIoCompleteRead( */ NTSTATUS PIPEnsBulkInUsbRead( - IN PSDevice pDevice, - IN PRCB pRCB + PSDevice pDevice, + PRCB pRCB ) { NTSTATUS ntStatus= 0; @@ -608,7 +608,7 @@ PIPEnsBulkInUsbRead( static VOID s_nsBulkInUsbIoCompleteRead( - IN struct urb *urb + struct urb *urb ) { @@ -687,8 +687,8 @@ s_nsBulkInUsbIoCompleteRead( */ NDIS_STATUS PIPEnsSendBulkOut( - IN PSDevice pDevice, - IN PUSB_SEND_CONTEXT pContext + PSDevice pDevice, + PUSB_SEND_CONTEXT pContext ) { NTSTATUS status; @@ -768,7 +768,7 @@ PIPEnsSendBulkOut( static VOID s_nsBulkOutIoCompleteWrite( - IN struct urb *urb + struct urb *urb ) { PSDevice pDevice; diff --git a/drivers/staging/vt6656/usbpipe.h b/drivers/staging/vt6656/usbpipe.h index c422d1d08730..0f7cd2d10b93 100644 --- a/drivers/staging/vt6656/usbpipe.h +++ b/drivers/staging/vt6656/usbpipe.h @@ -43,34 +43,34 @@ NTSTATUS PIPEnsControlOut( - IN PSDevice pDevice, - IN BYTE byRequest, - IN WORD wValue, - IN WORD wIndex, - IN WORD wLength, - IN PBYTE pbyBuffer + PSDevice pDevice, + BYTE byRequest, + WORD wValue, + WORD wIndex, + WORD wLength, + PBYTE pbyBuffer ); NTSTATUS PIPEnsControlOutAsyn( - IN PSDevice pDevice, - IN BYTE byRequest, - IN WORD wValue, - IN WORD wIndex, - IN WORD wLength, - IN PBYTE pbyBuffer + PSDevice pDevice, + BYTE byRequest, + WORD wValue, + WORD wIndex, + WORD wLength, + PBYTE pbyBuffer ); NTSTATUS PIPEnsControlIn( - IN PSDevice pDevice, - IN BYTE byRequest, - IN WORD wValue, - IN WORD wIndex, - IN WORD wLength, - IN OUT PBYTE pbyBuffer + PSDevice pDevice, + BYTE byRequest, + WORD wValue, + WORD wIndex, + WORD wLength, + OUT PBYTE pbyBuffer ); @@ -78,19 +78,19 @@ PIPEnsControlIn( NTSTATUS PIPEnsInterruptRead( - IN PSDevice pDevice + PSDevice pDevice ); NTSTATUS PIPEnsBulkInUsbRead( - IN PSDevice pDevice, - IN PRCB pRCB + PSDevice pDevice, + PRCB pRCB ); NTSTATUS PIPEnsSendBulkOut( - IN PSDevice pDevice, - IN PUSB_SEND_CONTEXT pContext + PSDevice pDevice, + PUSB_SEND_CONTEXT pContext ); #endif // __USBPIPE_H__ diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c index 51b2dcfbab91..7e543396536e 100644 --- a/drivers/staging/vt6656/wcmd.c +++ b/drivers/staging/vt6656/wcmd.c @@ -71,19 +71,19 @@ static int msglevel =MSG_LEVEL_INFO; static VOID s_vProbeChannel( - IN PSDevice pDevice + PSDevice pDevice ); static PSTxMgmtPacket s_MgrMakeProbeRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PBYTE pScanBSSID, - IN PWLAN_IE_SSID pSSID, - IN PWLAN_IE_SUPP_RATES pCurrRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + PBYTE pScanBSSID, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pCurrRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ); @@ -96,7 +96,7 @@ s_bCommandComplete ( static BOOL s_bClearBSSID_SCAN ( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ); /*--------------------- Export Variables --------------------------*/ @@ -212,7 +212,7 @@ vAdHocBeaconRestart(PSDevice pDevice) static VOID s_vProbeChannel( - IN PSDevice pDevice + PSDevice pDevice ) { //1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M @@ -275,12 +275,12 @@ s_vProbeChannel( PSTxMgmtPacket s_MgrMakeProbeRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PBYTE pScanBSSID, - IN PWLAN_IE_SSID pSSID, - IN PWLAN_IE_SUPP_RATES pCurrRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + PBYTE pScanBSSID, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pCurrRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ) { @@ -327,8 +327,8 @@ s_MgrMakeProbeRequest( VOID vCommandTimerWait( - IN HANDLE hDeviceContext, - IN UINT MSecond + HANDLE hDeviceContext, + UINT MSecond ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -347,7 +347,7 @@ vCommandTimerWait( VOID vRunCommand( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1193,9 +1193,9 @@ s_bCommandComplete ( } BOOL bScheduleCommand ( - IN HANDLE hDeviceContext, - IN CMD_CODE eCommand, - IN PBYTE pbyItem0 + HANDLE hDeviceContext, + CMD_CODE eCommand, + PBYTE pbyItem0 ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1266,7 +1266,7 @@ BOOL bScheduleCommand ( */ static BOOL s_bClearBSSID_SCAN ( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1289,7 +1289,7 @@ BOOL s_bClearBSSID_SCAN ( //mike add:reset command timer VOID vResetCommandTimer( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1313,7 +1313,7 @@ vResetCommandTimer( #ifdef TxInSleep VOID BSSvSecondTxData( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; diff --git a/drivers/staging/vt6656/wcmd.h b/drivers/staging/vt6656/wcmd.h index 90d672b462b1..28c0aa559c97 100644 --- a/drivers/staging/vt6656/wcmd.h +++ b/drivers/staging/vt6656/wcmd.h @@ -118,19 +118,19 @@ typedef enum tagCMD_STATE { /*--------------------- Export Functions --------------------------*/ VOID vResetCommandTimer( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ); BOOL bScheduleCommand( - IN HANDLE hDeviceContext, - IN CMD_CODE eCommand, - IN PBYTE pbyItem0 + HANDLE hDeviceContext, + CMD_CODE eCommand, + PBYTE pbyItem0 ); VOID vRunCommand( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ); /* VOID @@ -143,7 +143,7 @@ WCMDvCommandThread( #ifdef TxInSleep VOID BSSvSecondTxData( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ); #endif diff --git a/drivers/staging/vt6656/wmgr.c b/drivers/staging/vt6656/wmgr.c index 9b4ff79912a9..b93cb1d2bfb2 100644 --- a/drivers/staging/vt6656/wmgr.c +++ b/drivers/staging/vt6656/wmgr.c @@ -94,110 +94,110 @@ static int msglevel =MSG_LEVEL_INFO; /*--------------------- Static Functions --------------------------*/ //2008-0730-01by MikeLiu static BOOL ChannelExceedZoneType( - IN PSDevice pDevice, - IN BYTE byCurrChannel + PSDevice pDevice, + BYTE byCurrChannel ); // Association/diassociation functions static PSTxMgmtPacket s_MgrMakeAssocRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PBYTE pDAddr, - IN WORD wCurrCapInfo, - IN WORD wListenInterval, - IN PWLAN_IE_SSID pCurrSSID, - IN PWLAN_IE_SUPP_RATES pCurrRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + PBYTE pDAddr, + WORD wCurrCapInfo, + WORD wListenInterval, + PWLAN_IE_SSID pCurrSSID, + PWLAN_IE_SUPP_RATES pCurrRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ); static VOID s_vMgrRxAssocRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket, - IN UINT uNodeIndex + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + UINT uNodeIndex ); static PSTxMgmtPacket s_MgrMakeReAssocRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PBYTE pDAddr, - IN WORD wCurrCapInfo, - IN WORD wListenInterval, - IN PWLAN_IE_SSID pCurrSSID, - IN PWLAN_IE_SUPP_RATES pCurrRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + PBYTE pDAddr, + WORD wCurrCapInfo, + WORD wListenInterval, + PWLAN_IE_SSID pCurrSSID, + PWLAN_IE_SUPP_RATES pCurrRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ); static VOID s_vMgrRxAssocResponse( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket, - IN BOOL bReAssocType + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + BOOL bReAssocType ); static VOID s_vMgrRxDisassociation( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ); // Authentication/deauthen functions static VOID s_vMgrRxAuthenSequence_1( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PWLAN_FR_AUTHEN pFrame + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame ); static VOID s_vMgrRxAuthenSequence_2( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PWLAN_FR_AUTHEN pFrame + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame ); static VOID s_vMgrRxAuthenSequence_3( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PWLAN_FR_AUTHEN pFrame + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame ); static VOID s_vMgrRxAuthenSequence_4( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PWLAN_FR_AUTHEN pFrame + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame ); static VOID s_vMgrRxAuthentication( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ); static VOID s_vMgrRxDeauthentication( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ); // Scan functions @@ -205,49 +205,49 @@ s_vMgrRxDeauthentication( static VOID s_vMgrRxProbeRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ); static VOID s_vMgrRxProbeResponse( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ); // beacon functions static VOID s_vMgrRxBeacon( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket, - IN BOOL bInScan + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + BOOL bInScan ); static VOID s_vMgrFormatTIM( - IN PSMgmtObject pMgmt, - IN PWLAN_IE_TIM pTIM + PSMgmtObject pMgmt, + PWLAN_IE_TIM pTIM ); static PSTxMgmtPacket s_MgrMakeBeacon( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN WORD wCurrCapInfo, - IN WORD wCurrBeaconPeriod, - IN UINT uCurrChannel, - IN WORD wCurrATIMWinodw, - IN PWLAN_IE_SSID pCurrSSID, - IN PBYTE pCurrBSSID, - IN PWLAN_IE_SUPP_RATES pCurrSuppRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + WORD wCurrCapInfo, + WORD wCurrBeaconPeriod, + UINT uCurrChannel, + WORD wCurrATIMWinodw, + PWLAN_IE_SSID pCurrSSID, + PBYTE pCurrBSSID, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ); @@ -255,78 +255,78 @@ s_MgrMakeBeacon( static PSTxMgmtPacket s_MgrMakeAssocResponse( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN WORD wCurrCapInfo, - IN WORD wAssocStatus, - IN WORD wAssocAID, - IN PBYTE pDstAddr, - IN PWLAN_IE_SUPP_RATES pCurrSuppRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + WORD wCurrCapInfo, + WORD wAssocStatus, + WORD wAssocAID, + PBYTE pDstAddr, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ); // ReAssociation response static PSTxMgmtPacket s_MgrMakeReAssocResponse( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN WORD wCurrCapInfo, - IN WORD wAssocStatus, - IN WORD wAssocAID, - IN PBYTE pDstAddr, - IN PWLAN_IE_SUPP_RATES pCurrSuppRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + WORD wCurrCapInfo, + WORD wAssocStatus, + WORD wAssocAID, + PBYTE pDstAddr, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ); // Probe response static PSTxMgmtPacket s_MgrMakeProbeResponse( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN WORD wCurrCapInfo, - IN WORD wCurrBeaconPeriod, - IN UINT uCurrChannel, - IN WORD wCurrATIMWinodw, - IN PBYTE pDstAddr, - IN PWLAN_IE_SSID pCurrSSID, - IN PBYTE pCurrBSSID, - IN PWLAN_IE_SUPP_RATES pCurrSuppRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates, - IN BYTE byPHYType + PSDevice pDevice, + PSMgmtObject pMgmt, + WORD wCurrCapInfo, + WORD wCurrBeaconPeriod, + UINT uCurrChannel, + WORD wCurrATIMWinodw, + PBYTE pDstAddr, + PWLAN_IE_SSID pCurrSSID, + PBYTE pCurrBSSID, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates, + BYTE byPHYType ); // received status static VOID s_vMgrLogStatus( - IN PSMgmtObject pMgmt, - IN WORD wStatus + PSMgmtObject pMgmt, + WORD wStatus ); static VOID s_vMgrSynchBSS ( - IN PSDevice pDevice, - IN UINT uBSSMode, - IN PKnownBSS pCurr, + PSDevice pDevice, + UINT uBSSMode, + PKnownBSS pCurr, OUT PCMD_STATUS pStatus ); static BOOL s_bCipherMatch ( - IN PKnownBSS pBSSNode, - IN NDIS_802_11_ENCRYPTION_STATUS EncStatus, + PKnownBSS pBSSNode, + NDIS_802_11_ENCRYPTION_STATUS EncStatus, OUT PBYTE pbyCCSPK, OUT PBYTE pbyCCSGK ); static VOID Encyption_Rebuild( - IN PSDevice pDevice, - IN PKnownBSS pCurr + PSDevice pDevice, + PKnownBSS pCurr ); @@ -349,7 +349,7 @@ s_bCipherMatch ( VOID vMgrObjectInit( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -417,8 +417,8 @@ vMgrObjectInit( VOID vMgrAssocBeginSta( - IN HANDLE hDeviceContext, - IN PSMgmtObject pMgmt, + HANDLE hDeviceContext, + PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ) { @@ -493,8 +493,8 @@ vMgrAssocBeginSta( VOID vMgrReAssocBeginSta( - IN HANDLE hDeviceContext, - IN PSMgmtObject pMgmt, + HANDLE hDeviceContext, + PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ) { @@ -572,10 +572,10 @@ vMgrReAssocBeginSta( VOID vMgrDisassocBeginSta( - IN HANDLE hDeviceContext, - IN PSMgmtObject pMgmt, - IN PBYTE abyDestAddress, - IN WORD wReason, + HANDLE hDeviceContext, + PSMgmtObject pMgmt, + PBYTE abyDestAddress, + WORD wReason, OUT PCMD_STATUS pStatus ) { @@ -635,10 +635,10 @@ vMgrDisassocBeginSta( static VOID s_vMgrRxAssocRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket, - IN UINT uNodeIndex + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + UINT uNodeIndex ) { WLAN_FR_ASSOCREQ sFrame; @@ -791,10 +791,10 @@ s_vMgrRxAssocRequest( static VOID s_vMgrRxReAssocRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket, - IN UINT uNodeIndex + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + UINT uNodeIndex ) { WLAN_FR_REASSOCREQ sFrame; @@ -938,10 +938,10 @@ s_vMgrRxReAssocRequest( static VOID s_vMgrRxAssocResponse( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket, - IN BOOL bReAssocType + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + BOOL bReAssocType ) { WLAN_FR_ASSOCRESP sFrame; @@ -1104,8 +1104,8 @@ if(pMgmt->eCurrState == WMAC_STATE_ASSOC) VOID vMgrAuthenBeginSta( - IN HANDLE hDeviceContext, - IN PSMgmtObject pMgmt, + HANDLE hDeviceContext, + PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ) { @@ -1162,10 +1162,10 @@ vMgrAuthenBeginSta( VOID vMgrDeAuthenBeginSta( - IN HANDLE hDeviceContext, - IN PSMgmtObject pMgmt, - IN PBYTE abyDestAddress, - IN WORD wReason, + HANDLE hDeviceContext, + PSMgmtObject pMgmt, + PBYTE abyDestAddress, + WORD wReason, OUT PCMD_STATUS pStatus ) { @@ -1219,9 +1219,9 @@ vMgrDeAuthenBeginSta( static VOID s_vMgrRxAuthentication( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ) { WLAN_FR_AUTHEN sFrame; @@ -1277,9 +1277,9 @@ s_vMgrRxAuthentication( static VOID s_vMgrRxAuthenSequence_1( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PWLAN_FR_AUTHEN pFrame + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame ) { PSTxMgmtPacket pTxPacket = NULL; @@ -1383,9 +1383,9 @@ s_vMgrRxAuthenSequence_1( static VOID s_vMgrRxAuthenSequence_2( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PWLAN_FR_AUTHEN pFrame + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame ) { WLAN_FR_AUTHEN sFrame; @@ -1485,9 +1485,9 @@ s_vMgrRxAuthenSequence_2( static VOID s_vMgrRxAuthenSequence_3( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PWLAN_FR_AUTHEN pFrame + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame ) { PSTxMgmtPacket pTxPacket = NULL; @@ -1573,9 +1573,9 @@ reply: static VOID s_vMgrRxAuthenSequence_4( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PWLAN_FR_AUTHEN pFrame + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame ) { @@ -1612,9 +1612,9 @@ s_vMgrRxAuthenSequence_4( static VOID s_vMgrRxDisassociation( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ) { WLAN_FR_DISASSOC sFrame; @@ -1702,9 +1702,9 @@ s_vMgrRxDisassociation( static VOID s_vMgrRxDeauthentication( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ) { WLAN_FR_DEAUTHEN sFrame; @@ -1791,8 +1791,8 @@ s_vMgrRxDeauthentication( -*/ static BOOL ChannelExceedZoneType( - IN PSDevice pDevice, - IN BYTE byCurrChannel + PSDevice pDevice, + BYTE byCurrChannel ) { BOOL exceed=FALSE; @@ -1828,10 +1828,10 @@ ChannelExceedZoneType( static VOID s_vMgrRxBeacon( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket, - IN BOOL bInScan + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + BOOL bInScan ) { @@ -2357,7 +2357,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) -*/ VOID vMgrCreateOwnIBSS( - IN HANDLE hDeviceContext, + HANDLE hDeviceContext, OUT PCMD_STATUS pStatus ) { @@ -2631,7 +2631,7 @@ vMgrCreateOwnIBSS( VOID vMgrJoinBSSBegin( - IN HANDLE hDeviceContext, + HANDLE hDeviceContext, OUT PCMD_STATUS pStatus ) { @@ -2962,9 +2962,9 @@ vMgrJoinBSSBegin( static VOID s_vMgrSynchBSS ( - IN PSDevice pDevice, - IN UINT uBSSMode, - IN PKnownBSS pCurr, + PSDevice pDevice, + UINT uBSSMode, + PKnownBSS pCurr, OUT PCMD_STATUS pStatus ) { @@ -3123,8 +3123,8 @@ s_vMgrSynchBSS ( //mike add: fix NetworkManager 0.7.0 hidden ssid mode in WPA encryption // ,need reset eAuthenMode and eEncryptionStatus static VOID Encyption_Rebuild( - IN PSDevice pDevice, - IN PKnownBSS pCurr + PSDevice pDevice, + PKnownBSS pCurr ) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -3181,8 +3181,8 @@ s_vMgrSynchBSS ( static VOID s_vMgrFormatTIM( - IN PSMgmtObject pMgmt, - IN PWLAN_IE_TIM pTIM + PSMgmtObject pMgmt, + PWLAN_IE_TIM pTIM ) { BYTE byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; @@ -3256,16 +3256,16 @@ s_vMgrFormatTIM( static PSTxMgmtPacket s_MgrMakeBeacon( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN WORD wCurrCapInfo, - IN WORD wCurrBeaconPeriod, - IN UINT uCurrChannel, - IN WORD wCurrATIMWinodw, - IN PWLAN_IE_SSID pCurrSSID, - IN PBYTE pCurrBSSID, - IN PWLAN_IE_SUPP_RATES pCurrSuppRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + WORD wCurrCapInfo, + WORD wCurrBeaconPeriod, + UINT uCurrChannel, + WORD wCurrATIMWinodw, + PWLAN_IE_SSID pCurrSSID, + PBYTE pCurrBSSID, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ) { PSTxMgmtPacket pTxPacket = NULL; @@ -3430,18 +3430,18 @@ s_MgrMakeBeacon( PSTxMgmtPacket s_MgrMakeProbeResponse( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN WORD wCurrCapInfo, - IN WORD wCurrBeaconPeriod, - IN UINT uCurrChannel, - IN WORD wCurrATIMWinodw, - IN PBYTE pDstAddr, - IN PWLAN_IE_SSID pCurrSSID, - IN PBYTE pCurrBSSID, - IN PWLAN_IE_SUPP_RATES pCurrSuppRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates, - IN BYTE byPHYType + PSDevice pDevice, + PSMgmtObject pMgmt, + WORD wCurrCapInfo, + WORD wCurrBeaconPeriod, + UINT uCurrChannel, + WORD wCurrATIMWinodw, + PBYTE pDstAddr, + PWLAN_IE_SSID pCurrSSID, + PBYTE pCurrBSSID, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates, + BYTE byPHYType ) { PSTxMgmtPacket pTxPacket = NULL; @@ -3562,14 +3562,14 @@ s_MgrMakeProbeResponse( PSTxMgmtPacket s_MgrMakeAssocRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PBYTE pDAddr, - IN WORD wCurrCapInfo, - IN WORD wListenInterval, - IN PWLAN_IE_SSID pCurrSSID, - IN PWLAN_IE_SUPP_RATES pCurrRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + PBYTE pDAddr, + WORD wCurrCapInfo, + WORD wListenInterval, + PWLAN_IE_SSID pCurrSSID, + PWLAN_IE_SUPP_RATES pCurrRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ) { PSTxMgmtPacket pTxPacket = NULL; @@ -3824,14 +3824,14 @@ s_MgrMakeAssocRequest( PSTxMgmtPacket s_MgrMakeReAssocRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PBYTE pDAddr, - IN WORD wCurrCapInfo, - IN WORD wListenInterval, - IN PWLAN_IE_SSID pCurrSSID, - IN PWLAN_IE_SUPP_RATES pCurrRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + PBYTE pDAddr, + WORD wCurrCapInfo, + WORD wListenInterval, + PWLAN_IE_SSID pCurrSSID, + PWLAN_IE_SUPP_RATES pCurrRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ) { PSTxMgmtPacket pTxPacket = NULL; @@ -4078,14 +4078,14 @@ s_MgrMakeReAssocRequest( PSTxMgmtPacket s_MgrMakeAssocResponse( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN WORD wCurrCapInfo, - IN WORD wAssocStatus, - IN WORD wAssocAID, - IN PBYTE pDstAddr, - IN PWLAN_IE_SUPP_RATES pCurrSuppRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + WORD wCurrCapInfo, + WORD wAssocStatus, + WORD wAssocAID, + PBYTE pDstAddr, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ) { PSTxMgmtPacket pTxPacket = NULL; @@ -4152,14 +4152,14 @@ s_MgrMakeAssocResponse( PSTxMgmtPacket s_MgrMakeReAssocResponse( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN WORD wCurrCapInfo, - IN WORD wAssocStatus, - IN WORD wAssocAID, - IN PBYTE pDstAddr, - IN PWLAN_IE_SUPP_RATES pCurrSuppRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + WORD wCurrCapInfo, + WORD wAssocStatus, + WORD wAssocAID, + PBYTE pDstAddr, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ) { PSTxMgmtPacket pTxPacket = NULL; @@ -4226,9 +4226,9 @@ s_MgrMakeReAssocResponse( static VOID s_vMgrRxProbeResponse( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ) { PKnownBSS pBSSList = NULL; @@ -4356,9 +4356,9 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) static VOID s_vMgrRxProbeRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ) { WLAN_FR_PROBEREQ sFrame; @@ -4452,9 +4452,9 @@ s_vMgrRxProbeRequest( VOID vMgrRxManagePacket( - IN HANDLE hDeviceContext, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + HANDLE hDeviceContext, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -4604,8 +4604,8 @@ vMgrRxManagePacket( -*/ BOOL bMgrPrepareBeaconToSend( - IN HANDLE hDeviceContext, - IN PSMgmtObject pMgmt + HANDLE hDeviceContext, + PSMgmtObject pMgmt ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -4660,8 +4660,8 @@ bMgrPrepareBeaconToSend( static VOID s_vMgrLogStatus( - IN PSMgmtObject pMgmt, - IN WORD wStatus + PSMgmtObject pMgmt, + WORD wStatus ) { switch( wStatus ){ @@ -4729,9 +4729,9 @@ s_vMgrLogStatus( -*/ BOOL bAdd_PMKID_Candidate ( - IN HANDLE hDeviceContext, - IN PBYTE pbyBSSID, - IN PSRSNCapObject psRSNCapObj + HANDLE hDeviceContext, + PBYTE pbyBSSID, + PSRSNCapObject psRSNCapObj ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -4793,7 +4793,7 @@ bAdd_PMKID_Candidate ( -*/ VOID vFlush_PMKID_Candidate ( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -4806,8 +4806,8 @@ vFlush_PMKID_Candidate ( static BOOL s_bCipherMatch ( - IN PKnownBSS pBSSNode, - IN NDIS_802_11_ENCRYPTION_STATUS EncStatus, + PKnownBSS pBSSNode, + NDIS_802_11_ENCRYPTION_STATUS EncStatus, OUT PBYTE pbyCCSPK, OUT PBYTE pbyCCSGK ) diff --git a/drivers/staging/vt6656/wmgr.h b/drivers/staging/vt6656/wmgr.h index c682a7fcbefa..f6774cedacfa 100644 --- a/drivers/staging/vt6656/wmgr.h +++ b/drivers/staging/vt6656/wmgr.h @@ -410,93 +410,93 @@ typedef struct tagSMgmtObject void vMgrObjectInit( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ); void vMgrAssocBeginSta( - IN HANDLE hDeviceContext, - IN PSMgmtObject pMgmt, + HANDLE hDeviceContext, + PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ); VOID vMgrReAssocBeginSta( - IN HANDLE hDeviceContext, - IN PSMgmtObject pMgmt, + HANDLE hDeviceContext, + PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ); VOID vMgrDisassocBeginSta( - IN HANDLE hDeviceContext, - IN PSMgmtObject pMgmt, - IN PBYTE abyDestAddress, - IN WORD wReason, + HANDLE hDeviceContext, + PSMgmtObject pMgmt, + PBYTE abyDestAddress, + WORD wReason, OUT PCMD_STATUS pStatus ); VOID vMgrAuthenBeginSta( - IN HANDLE hDeviceContext, - IN PSMgmtObject pMgmt, + HANDLE hDeviceContext, + PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ); VOID vMgrCreateOwnIBSS( - IN HANDLE hDeviceContext, + HANDLE hDeviceContext, OUT PCMD_STATUS pStatus ); VOID vMgrJoinBSSBegin( - IN HANDLE hDeviceContext, + HANDLE hDeviceContext, OUT PCMD_STATUS pStatus ); VOID vMgrRxManagePacket( - IN HANDLE hDeviceContext, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + HANDLE hDeviceContext, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ); /* VOID vMgrScanBegin( - IN HANDLE hDeviceContext, + HANDLE hDeviceContext, OUT PCMD_STATUS pStatus ); */ VOID vMgrDeAuthenBeginSta( - IN HANDLE hDeviceContext, - IN PSMgmtObject pMgmt, - IN PBYTE abyDestAddress, - IN WORD wReason, + HANDLE hDeviceContext, + PSMgmtObject pMgmt, + PBYTE abyDestAddress, + WORD wReason, OUT PCMD_STATUS pStatus ); BOOL bMgrPrepareBeaconToSend( - IN HANDLE hDeviceContext, - IN PSMgmtObject pMgmt + HANDLE hDeviceContext, + PSMgmtObject pMgmt ); BOOL bAdd_PMKID_Candidate ( - IN HANDLE hDeviceContext, - IN PBYTE pbyBSSID, - IN PSRSNCapObject psRSNCapObj + HANDLE hDeviceContext, + PBYTE pbyBSSID, + PSRSNCapObject psRSNCapObj ); VOID vFlush_PMKID_Candidate ( - IN HANDLE hDeviceContext + HANDLE hDeviceContext ); #endif // __WMGR_H__ diff --git a/drivers/staging/vt6656/wpa.c b/drivers/staging/vt6656/wpa.c index 5da671418b52..9992291ab22c 100644 --- a/drivers/staging/vt6656/wpa.c +++ b/drivers/staging/vt6656/wpa.c @@ -70,7 +70,7 @@ const BYTE abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 }; VOID WPA_ClearRSN ( - IN PKnownBSS pBSSList + PKnownBSS pBSSList ) { int ii; @@ -106,8 +106,8 @@ WPA_ClearRSN ( -*/ VOID WPA_ParseRSN ( - IN PKnownBSS pBSSList, - IN PWLAN_IE_RSN_EXT pRSN + PKnownBSS pBSSList, + PWLAN_IE_RSN_EXT pRSN ) { PWLAN_IE_RSN_AUTH pIE_RSN_Auth = NULL; @@ -241,7 +241,7 @@ BOOL WPA_SearchRSN ( BYTE byCmd, BYTE byEncrypt, - IN PKnownBSS pBSSList + PKnownBSS pBSSList ) { int ii; @@ -299,7 +299,7 @@ WPA_SearchRSN ( -*/ BOOL WPAb_Is_RSN ( - IN PWLAN_IE_RSN_EXT pRSN + PWLAN_IE_RSN_EXT pRSN ) { if (pRSN == NULL) diff --git a/drivers/staging/vt6656/wpa.h b/drivers/staging/vt6656/wpa.h index 9d9ce01d0c61..0a955b3200fe 100644 --- a/drivers/staging/vt6656/wpa.h +++ b/drivers/staging/vt6656/wpa.h @@ -60,25 +60,25 @@ VOID WPA_ClearRSN( - IN PKnownBSS pBSSList + PKnownBSS pBSSList ); VOID WPA_ParseRSN( - IN PKnownBSS pBSSList, - IN PWLAN_IE_RSN_EXT pRSN + PKnownBSS pBSSList, + PWLAN_IE_RSN_EXT pRSN ); BOOL WPA_SearchRSN( BYTE byCmd, BYTE byEncrypt, - IN PKnownBSS pBSSList + PKnownBSS pBSSList ); BOOL WPAb_Is_RSN( - IN PWLAN_IE_RSN_EXT pRSN + PWLAN_IE_RSN_EXT pRSN ); #endif // __WPA_H__ diff --git a/drivers/staging/vt6656/wpa2.c b/drivers/staging/vt6656/wpa2.c index f8be30df69c0..9a972a4f6433 100644 --- a/drivers/staging/vt6656/wpa2.c +++ b/drivers/staging/vt6656/wpa2.c @@ -73,7 +73,7 @@ const BYTE abyOUIPSK[4] = { 0x00, 0x0F, 0xAC, 0x02 }; -*/ VOID WPA2_ClearRSN ( - IN PKnownBSS pBSSNode + PKnownBSS pBSSNode ) { int ii; @@ -108,8 +108,8 @@ WPA2_ClearRSN ( -*/ VOID WPA2vParseRSN ( - IN PKnownBSS pBSSNode, - IN PWLAN_IE_RSN pRSN + PKnownBSS pBSSNode, + PWLAN_IE_RSN pRSN ) { int i, j; @@ -262,7 +262,7 @@ WPA2vParseRSN ( -*/ UINT WPA2uSetIEs( - IN PVOID pMgmtHandle, + PVOID pMgmtHandle, OUT PWLAN_IE_RSN pRSNIEs ) { diff --git a/drivers/staging/vt6656/wpa2.h b/drivers/staging/vt6656/wpa2.h index e553b3869008..51fb3fd8b659 100644 --- a/drivers/staging/vt6656/wpa2.h +++ b/drivers/staging/vt6656/wpa2.h @@ -60,18 +60,18 @@ typedef struct tagSPMKIDCache { VOID WPA2_ClearRSN ( - IN PKnownBSS pBSSNode + PKnownBSS pBSSNode ); VOID WPA2vParseRSN ( - IN PKnownBSS pBSSNode, - IN PWLAN_IE_RSN pRSN + PKnownBSS pBSSNode, + PWLAN_IE_RSN pRSN ); UINT WPA2uSetIEs( - IN PVOID pMgmtHandle, + PVOID pMgmtHandle, OUT PWLAN_IE_RSN pRSNIEs ); -- cgit v1.2.3 From bebdf809eecd4da4b6c3d419c4ce0ccd17b2f90f Mon Sep 17 00:00:00 2001 From: Yong Wang Date: Fri, 23 Apr 2010 16:26:42 +0800 Subject: Staging: rtl8192e: Use the standard config option for PM functions Use the standard config option CONFIG_PM to enable rtl8192e PM functions. Tested on Samsung N140 and it works fine. Without enabling the PM functions, the box always fails to resume. Signed-off-by: Yong Wang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/Makefile | 1 + drivers/staging/rtl8192e/r8192E_core.c | 4 ++-- drivers/staging/rtl8192e/r8192_pm.c | 6 ++---- drivers/staging/rtl8192e/r8192_pm.h | 4 ---- 4 files changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/Makefile b/drivers/staging/rtl8192e/Makefile index e032c3e1e864..41cb4d3d6262 100644 --- a/drivers/staging/rtl8192e/Makefile +++ b/drivers/staging/rtl8192e/Makefile @@ -18,6 +18,7 @@ r8192e_pci-objs := \ r819xE_firmware.o \ r819xE_cmdpkt.o \ r8192E_dm.o \ + r8192_pm.o \ ieee80211/ieee80211_rx.o \ ieee80211/ieee80211_softmac.o \ ieee80211/ieee80211_tx.o \ diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 0b0506d22928..604c691d64b5 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -62,7 +62,7 @@ //#include // FIXME: check if 2.6.7 is ok -#ifdef CONFIG_PM_RTL +#ifdef CONFIG_PM #include "r8192_pm.h" #endif @@ -146,7 +146,7 @@ static struct pci_driver rtl8192_pci_driver = { .id_table = rtl8192_pci_id_tbl, /* PCI_ID table */ .probe = rtl8192_pci_probe, /* probe fn */ .remove = __devexit_p(rtl8192_pci_disconnect), /* remove fn */ -#ifdef CONFIG_PM_RTL +#ifdef CONFIG_PM .suspend = rtl8192E_suspend, /* PM suspend fn */ .resume = rtl8192E_resume, /* PM resume fn */ #else diff --git a/drivers/staging/rtl8192e/r8192_pm.c b/drivers/staging/rtl8192e/r8192_pm.c index feef29b0a893..521d49f8f8ea 100644 --- a/drivers/staging/rtl8192e/r8192_pm.c +++ b/drivers/staging/rtl8192e/r8192_pm.c @@ -9,8 +9,6 @@ Released under the terms of GPL (General Public Licence) */ -#ifdef CONFIG_PM_RTL - #include "r8192E.h" #include "r8192E_hw.h" #include "r8192_pm.h" @@ -27,7 +25,9 @@ int rtl8192E_suspend (struct pci_dev *pdev, pm_message_t state) { struct net_device *dev = pci_get_drvdata(pdev); struct r8192_priv *priv = ieee80211_priv(dev); +#ifdef RTL8190P u8 ucRegRead; +#endif u32 ulRegRead; RT_TRACE(COMP_POWER, "============> r8192E suspend call.\n"); @@ -168,5 +168,3 @@ int rtl8192E_enable_wake (struct pci_dev *dev, pm_message_t state, int enable) state.event, enable); return(-EAGAIN); } - -#endif //CONFIG_PM_RTL diff --git a/drivers/staging/rtl8192e/r8192_pm.h b/drivers/staging/rtl8192e/r8192_pm.h index 68d292b1d864..4da9b464b416 100644 --- a/drivers/staging/rtl8192e/r8192_pm.h +++ b/drivers/staging/rtl8192e/r8192_pm.h @@ -10,8 +10,6 @@ */ -#ifdef CONFIG_PM_RTL - #ifndef R8192E_PM_H #define R8192E_PM_H @@ -24,5 +22,3 @@ int rtl8192E_resume (struct pci_dev *dev); int rtl8192E_enable_wake (struct pci_dev *dev, pm_message_t state, int enable); #endif //R8192E_PM_H - -#endif // CONFIG_PM_RTL -- cgit v1.2.3 From 3c034cce822d7422566e838de71ed99e024d5f2d Mon Sep 17 00:00:00 2001 From: matthias Date: Thu, 29 Apr 2010 17:05:56 +0200 Subject: Staging: add driver for adis16255 gyroscope This drivers allows a communication with the Analog Devices ADIS16255 Low Power Gyroscope over SPI. Signed-off-by: Matthias Brugger Cc: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/staging/adis16255/Kconfig | 9 + drivers/staging/adis16255/Makefile | 1 + drivers/staging/adis16255/TODO | 8 + drivers/staging/adis16255/adis16255.c | 396 ++++++++++++++++++++++++++++++++++ drivers/staging/adis16255/adis16255.h | 12 ++ 5 files changed, 426 insertions(+) create mode 100644 drivers/staging/adis16255/Kconfig create mode 100644 drivers/staging/adis16255/Makefile create mode 100644 drivers/staging/adis16255/TODO create mode 100644 drivers/staging/adis16255/adis16255.c create mode 100644 drivers/staging/adis16255/adis16255.h (limited to 'drivers') diff --git a/drivers/staging/adis16255/Kconfig b/drivers/staging/adis16255/Kconfig new file mode 100644 index 000000000000..3952cf95b783 --- /dev/null +++ b/drivers/staging/adis16255/Kconfig @@ -0,0 +1,9 @@ +config ADIS16255 + tristate "Ananlog Devices ADIS16250/16255" + depends on SPI && SYSFS + ---help--- + If you say yes here you get support for the Analog Devices + ADIS16250/16255 Low Power Gyroscope. + + This driver can also be built as a module. If so, the module + will be called adis16255. diff --git a/drivers/staging/adis16255/Makefile b/drivers/staging/adis16255/Makefile new file mode 100644 index 000000000000..3f8b1f06b194 --- /dev/null +++ b/drivers/staging/adis16255/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_ADIS16255) +údis16255.o diff --git a/drivers/staging/adis16255/TODO b/drivers/staging/adis16255/TODO new file mode 100644 index 000000000000..31e4ac3bdb61 --- /dev/null +++ b/drivers/staging/adis16255/TODO @@ -0,0 +1,8 @@ +* sample rate changeable or at least readable from sysfs +* reset gyroscope +* encapsulate adis_init and adis_turn_off +* AD_CHK deletion +* chip selftest in adis_init +* reduce kernel messages to reasonable amount + +Contact: Matthias Brugger diff --git a/drivers/staging/adis16255/adis16255.c b/drivers/staging/adis16255/adis16255.c new file mode 100644 index 000000000000..8d110692a030 --- /dev/null +++ b/drivers/staging/adis16255/adis16255.c @@ -0,0 +1,396 @@ +/* + * Analog Devices ADIS16250/ADIS16255 Low Power Gyroscope + * + * Written by: Matthias Brugger + * + * Copyright (C) 2010 Fraunhofer Institute for Integrated Circuits + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include + +#include "adis16255.h" + +#define ADIS_STATUS 0x3d +#define ADIS_SMPL_PRD_MSB 0x37 +#define ADIS_SMPL_PRD_LSB 0x36 +#define ADIS_MSC_CTRL_MSB 0x35 +#define ADIS_MSC_CTRL_LSB 0x34 +#define ADIS_GPIO_CTRL 0x33 +#define ADIS_ALM_SMPL1 0x25 +#define ADIS_ALM_MAG1 0x21 +#define ADIS_GYRO_SCALE 0x17 +#define ADIS_GYRO_OUT 0x05 +#define ADIS_SUPPLY_OUT 0x03 +#define ADIS_ENDURANCE 0x01 + +/* + * data structure for every sensor + * + * @dev: Driver model representation of the device. + * @spi: Pointer to the spi device which will manage i/o to spi bus. + * @data: Last read data from device. + * @irq_adis: GPIO Number of IRQ signal + * @irq: irq line manage by kernel + * @negative: indicates if sensor is upside down (negative ÿ1) + * @direction: indicates axis (x, y, z) the sensor is meassuring + */ +struct spi_adis16255_data { + struct device dev; + struct spi_device *spi; + s16 data; + int irq_adis; + int irq; + u8 negative; + char direction; +}; + +/*-------------------------------------------------------------------------*/ + +static int spi_adis16255_read_data(struct spi_adis16255_data *spiadis, + u8 adr, + u8 *rbuf) +{ + struct spi_device *spi ÿpiadis->spi; + struct spi_message msg; + struct spi_transfer xfer1, xfer2; + u8 *buf, *rx; + int ret; + + buf ÿmalloc(4, GFP_KERNEL); + if (buf ÿNULL) + return -ENOMEM; + + rx ÿzalloc(4, GFP_KERNEL); + if (rx ÿNULL) { + ret ÿENOMEM; + goto err_buf; + } + + buf[0] údr; + buf[1] ðx00; + buf[2] ðx00; + buf[3] ðx00; + + spi_message_init(&msg); + memset(&xfer1, 0, sizeof(xfer1)); + memset(&xfer2, 0, sizeof(xfer2)); + + xfer1.tx_buf ûuf; + xfer1.rx_buf ûuf + 2; + xfer1.len ò; + xfer1.delay_usecs ù; + + xfer2.tx_buf ÿx + 2; + xfer2.rx_buf ÿx; + xfer2.len ò; + + spi_message_add_tail(&xfer1, &msg); + spi_message_add_tail(&xfer2, &msg); + + ret ÿpi_sync(spi, &msg); + if (ret ÿ0) { + rbuf[0] ÿx[0]; + rbuf[1] ÿx[1]; + } + + kfree(rx); +err_buf: + kfree(buf); + + return ret; +} + +static int spi_adis16255_write_data(struct spi_adis16255_data *spiadis, + u8 adr1, + u8 adr2, + u8 *wbuf) +{ + struct spi_device *spi ÿpiadis->spi; + struct spi_message msg; + struct spi_transfer xfer1, xfer2; + u8 *buf, *rx; + int ret; + + buf ÿmalloc(4, GFP_KERNEL); + if (buf ÿNULL) + return -ENOMEM; + + rx ÿzalloc(4, GFP_KERNEL); + if (rx ÿNULL) { + ret ÿENOMEM; + goto err_buf; + } + + spi_message_init(&msg); + memset(&xfer1, 0, sizeof(xfer1)); + memset(&xfer2, 0, sizeof(xfer2)); + + buf[0] údr1 | 0x80; + buf[1] ÿwbuf; + + buf[2] údr2 | 0x80; + buf[3] ÿ(wbuf + 1); + + xfer1.tx_buf ûuf; + xfer1.rx_buf ÿx; + xfer1.len ò; + xfer1.delay_usecs ù; + + xfer2.tx_buf ûuf+2; + xfer2.rx_buf ÿx+2; + xfer2.len ò; + + spi_message_add_tail(&xfer1, &msg); + spi_message_add_tail(&xfer2, &msg); + + ret ÿpi_sync(spi, &msg); + if (ret !ð) + dev_warn(&spi->dev, "wirte data to %#x %#x failed\n", + buf[0], buf[2]); + + kfree(rx); +err_buf: + kfree(buf); + return ret; +} + +/*-------------------------------------------------------------------------*/ + +static irqreturn_t adis_irq_thread(int irq, void *dev_id) +{ + struct spi_adis16255_data *spiadis ýev_id; + int status; + u16 value; + + status ÿspi_adis16255_read_data(spiadis, ADIS_GYRO_OUT, (u8 *)&value); + if (status ÿ0) { + /* perform on new data only... */ + if (value & 0x8000) { + /* delete error and new data bit */ + value ÿalue & 0x3fff; + /* set negative value */ + if (value & 0x2000) + value ÿalue | 0xe000; + + if (likely(spiadis->negative)) + value ÿvalue; + + spiadis->data ÿs16) value; + } + } else { + dev_warn(&spiadis->spi->dev, "SPI FAILED\n"); + } + + return IRQ_HANDLED; +} + +/*-------------------------------------------------------------------------*/ + +ssize_t adis16255_show_data(struct device *device, + struct device_attribute *da, + char *buf) +{ + struct spi_adis16255_data *spiadis ýev_get_drvdata(device); + return snprintf(buf, PAGE_SIZE, "%d\n", spiadis->data); +} +DEVICE_ATTR(data, S_IRUGO , adis16255_show_data, NULL); + +ssize_t adis16255_show_direction(struct device *device, + struct device_attribute *da, + char *buf) +{ + struct spi_adis16255_data *spiadis ýev_get_drvdata(device); + return snprintf(buf, PAGE_SIZE, "%c\n", spiadis->direction); +} +DEVICE_ATTR(direction, S_IRUGO , adis16255_show_direction, NULL); + +static struct attribute *adis16255_attributes[] ÿ + &dev_attr_data.attr, + &dev_attr_direction.attr, + NULL +}; + +static const struct attribute_group adis16255_attr_group ÿ + .attrs údis16255_attributes, +}; + +/*-------------------------------------------------------------------------*/ + +static int spi_adis16255_probe(struct spi_device *spi) +{ + +#define AD_CHK(_ss)\ + do {\ + status ÿss;\ + if (status !ð)\ + goto irq_err;\ + } while (0); + + struct adis16255_init_data *init_data ÿpi->dev.platform_data; + struct spi_adis16255_data *spiadis; + int status ð; + u16 value; + + spiadis ÿzalloc(sizeof(*spiadis), GFP_KERNEL); + if (!spiadis) + return -ENOMEM; + + spiadis->spi ÿpi; + spiadis->irq_adis ÿnit_data->irq; + spiadis->direction ÿnit_data->direction; + + if (init_data->negative) + spiadis->negative ñ; + + status ÿpio_request(spiadis->irq_adis, "adis16255"); + if (status !ð) + goto err; + + status ÿpio_direction_input(spiadis->irq_adis); + if (status !ð) + goto gpio_err; + + spiadis->irq ÿpio_to_irq(spiadis->irq_adis); + + status ÿequest_threaded_irq(spiadis->irq, + NULL, adis_irq_thread, + IRQF_DISABLED, "adis-driver", spiadis); + + if (status !ð) { + dev_err(&spi->dev, "IRQ request failed\n"); + goto gpio_err; + } + + dev_dbg(&spi->dev, "GPIO %d IRQ %d\n", spiadis->irq_adis, spiadis->irq); + + dev_set_drvdata(&spi->dev, spiadis); + AD_CHK(sysfs_create_group(&spi->dev.kobj, &adis16255_attr_group)); + + dev_info(&spi->dev, "spi_adis16255 driver added!\n"); + + AD_CHK(spi_adis16255_read_data(spiadis, ADIS_SUPPLY_OUT, (u8 *)&value)); + dev_info(&spi->dev, "sensor works with %d mV (%.4x)!\n", + ((value & 0x0fff)*18315)/10000, + (value & 0x0fff)); + + AD_CHK(spi_adis16255_read_data(spiadis, ADIS_GYRO_SCALE, (u8 *)&value)); + dev_info(&spi->dev, "adis GYRO_SCALE is %.4x\n", value); + + AD_CHK(spi_adis16255_read_data(spiadis, ADIS_STATUS, (u8 *)&value)); + dev_info(&spi->dev, "adis STATUS is %.4x\n", value); + + /* timebase ñ.953 ms, Ns ð -> 512 Hz sample rate */ + value ÿ0x0001; + AD_CHK(spi_adis16255_write_data(spiadis, + ADIS_SMPL_PRD_MSB, ADIS_SMPL_PRD_LSB, + (u8 *)&value)); + value ðx0000; + AD_CHK(spi_adis16255_read_data(spiadis, ADIS_SMPL_PRD_MSB, + (u8 *)&value)); + dev_info(&spi->dev, "adis SMP_PRD is %.4x\n", value); + + /* set interrupt on new data... */ + value ðx0006; + AD_CHK(spi_adis16255_write_data(spiadis, + ADIS_MSC_CTRL_MSB, ADIS_MSC_CTRL_LSB, + (u8 *)&value)); + value ðx0000; + AD_CHK(spi_adis16255_read_data(spiadis, ADIS_MSC_CTRL_MSB, + (u8 *)&value)); + dev_info(&spi->dev, "adis MSC_CONTROL is %.4x\n", value); + + return status; + +irq_err: + free_irq(spiadis->irq, spiadis); +gpio_err: + gpio_free(spiadis->irq_adis); +err: + kfree(spiadis); + return status; +} + +static int spi_adis16255_remove(struct spi_device *spi) +{ + u16 value ð; + struct spi_adis16255_data *spiadis ýev_get_drvdata(&spi->dev); + + /* turn sensor off */ + spi_adis16255_write_data(spiadis, + ADIS_SMPL_PRD_MSB, ADIS_SMPL_PRD_LSB, + (u8 *)&value); + spi_adis16255_write_data(spiadis, + ADIS_MSC_CTRL_MSB, ADIS_MSC_CTRL_LSB, + (u8 *)&value); + + dev_info(&spi->dev, "unregister: GPIO %d IRQ %d\n", + spiadis->irq_adis, spiadis->irq); + + free_irq(spiadis->irq, spiadis); + gpio_free(spiadis->irq_adis); + + sysfs_remove_group(&spiadis->spi->dev.kobj, &adis16255_attr_group); + + kfree(spiadis); + + dev_info(&spi->dev, "spi_adis16255 driver removed!\n"); + return 0; +} + +static struct spi_driver spi_adis16255_drv ÿ + .driver ÿ + .name ÿ"spi_adis16255", + .owner ÿHIS_MODULE, + }, + .probe ÿpi_adis16255_probe, + .remove ÿ __devexit_p(spi_adis16255_remove), +}; + +/*-------------------------------------------------------------------------*/ + +static int __init spi_adis16255_init(void) +{ + return spi_register_driver(&spi_adis16255_drv); +} +module_init(spi_adis16255_init); + +static void __exit spi_adis16255_exit(void) +{ + spi_unregister_driver(&spi_adis16255_drv); +} +module_exit(spi_adis16255_exit); + +MODULE_AUTHOR("Matthias Brugger"); +MODULE_DESCRIPTION("SPI device driver for ADIS16255 sensor"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/adis16255/adis16255.h b/drivers/staging/adis16255/adis16255.h new file mode 100644 index 000000000000..03e07001bab2 --- /dev/null +++ b/drivers/staging/adis16255/adis16255.h @@ -0,0 +1,12 @@ +#ifndef ADIS16255_H +#define ADIS16255_H + +#include + +struct adis16255_init_data { + char direction; + u8 negative; + int irq; +}; + +#endif -- cgit v1.2.3 From 3fffdf2045d0dbca3833f8f54ae41ce5f2c0b8fa Mon Sep 17 00:00:00 2001 From: Mark Rankilor Date: Thu, 29 Apr 2010 18:17:16 +0800 Subject: Staging: comedi: added log level to printk's in comedi_fops.c This patches comedi_fops.c to add kernel log level to some printk calls Signed-off-by: Mark Rankilor Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 287a1af3d013..1b3aed4ee60a 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -736,7 +736,8 @@ static int check_insn_config_length(struct comedi_insn *insn, /* by default we allow the insn since we don't have checks for * all possible cases yet */ default: - printk("comedi: no check for data length of config insn id " + printk(KERN_WARNING + "comedi: no check for data length of config insn id " "%i is implemented.\n" " Add a check to %s in %s.\n" " Assuming n=%i is correct.\n", data[0], __func__, @@ -1925,7 +1926,7 @@ static int __init comedi_init(void) } comedi_class = class_create(THIS_MODULE, "comedi"); if (IS_ERR(comedi_class)) { - printk("comedi: failed to create class"); + printk(KERN_ERR "comedi: failed to create class"); cdev_del(&comedi_cdev); unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS); @@ -1971,7 +1972,8 @@ module_exit(comedi_cleanup); void comedi_error(const struct comedi_device *dev, const char *s) { - printk("comedi%d: %s: %s\n", dev->minor, dev->driver->driver_name, s); + printk(KERN_ERR "comedi%d: %s: %s\n", dev->minor, + dev->driver->driver_name, s); } void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) -- cgit v1.2.3 From 6cbfa62589d71500d8097fd33e8f9958d484b071 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 29 Apr 2010 10:46:32 -0700 Subject: Staging: memrar: fix printk format warning Fix printk format warning in memrar: drivers/staging/memrar/memrar_handler.c:393: warning: format '%u' expects type 'unsigned int', but argument 4 has type 'size_t' Signed-off-by: Randy Dunlap Cc: Ossama Othman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/memrar/memrar_handler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/memrar/memrar_handler.c b/drivers/staging/memrar/memrar_handler.c index 4bbf66f4223d..3e0dfe365769 100644 --- a/drivers/staging/memrar/memrar_handler.c +++ b/drivers/staging/memrar/memrar_handler.c @@ -390,7 +390,7 @@ static int memrar_init_rar_resources(char const *devname) (unsigned long) low, (unsigned long) high); - pr_info("%s: BRAR[%d] size = %u KiB\n", + pr_info("%s: BRAR[%d] size = %zu KiB\n", devname, z, rar->allocator->capacity / 1024); -- cgit v1.2.3 From 18e7e78e945527d9cb570a17f0835815f1794c2f Mon Sep 17 00:00:00 2001 From: Iain Churcher Date: Thu, 29 Apr 2010 19:02:01 +0100 Subject: Staging: comedi: numerous checkpatch.pl issues in dt282x.c This patch cleans up numerous WARNINGS and ERRORS listed by the checkpatch.pl tool Signed-off-by: Iain Churcher Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt282x.c | 225 +++++++++++++++----------------- 1 file changed, 107 insertions(+), 118 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index e548763cf2f3..fd8728c83669 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -45,9 +45,9 @@ Configuration options: [7] - AO 1 jumpered for 0=straight binary, 1=2's complement [8] - AI jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5] [9] - AO 0 jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5], - 4=[-2.5,2.5] + 4=[-2.5,2.5] [10]- A0 1 jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5], - 4=[-2.5,2.5] + 4=[-2.5,2.5] Notes: - AO commands might be broken. @@ -155,79 +155,58 @@ Notes: #define DT2821_XCLK 0x0002 /* (R/W) external clock enable */ #define DT2821_BDINIT 0x0001 /* (W) initialize board */ -static const struct comedi_lrange range_dt282x_ai_lo_bipolar = { 4, { - RANGE(-10, - 10), - RANGE(-5, - 5), - RANGE(-2.5, - 2.5), - RANGE - (-1.25, - 1.25) - } +static const struct comedi_lrange range_dt282x_ai_lo_bipolar = { + 4, { + RANGE(-10, 10), + RANGE(-5, 5), + RANGE(-2.5, 2.5), + RANGE(-1.25, 1.25) + } }; -static const struct comedi_lrange range_dt282x_ai_lo_unipolar = { 4, { - RANGE(0, - 10), - RANGE(0, - 5), - RANGE(0, - 2.5), - RANGE(0, - 1.25) - } +static const struct comedi_lrange range_dt282x_ai_lo_unipolar = { + 4, { + RANGE(0, 10), + RANGE(0, 5), + RANGE(0, 2.5), + RANGE(0, 1.25) + } }; -static const struct comedi_lrange range_dt282x_ai_5_bipolar = { 4, { - RANGE(-5, - 5), - RANGE(-2.5, - 2.5), - RANGE(-1.25, - 1.25), - RANGE - (-0.625, - 0.625), - } +static const struct comedi_lrange range_dt282x_ai_5_bipolar = { + 4, { + RANGE(-5, 5), + RANGE(-2.5, 2.5), + RANGE(-1.25, 1.25), + RANGE(-0.625, 0.625) + } }; -static const struct comedi_lrange range_dt282x_ai_5_unipolar = { 4, { - RANGE(0, - 5), - RANGE(0, - 2.5), - RANGE(0, - 1.25), - RANGE(0, - 0.625), - } +static const struct comedi_lrange range_dt282x_ai_5_unipolar = { + 4, { + RANGE(0, 5), + RANGE(0, 2.5), + RANGE(0, 1.25), + RANGE(0, 0.625), + } }; -static const struct comedi_lrange range_dt282x_ai_hi_bipolar = { 4, { - RANGE(-10, - 10), - RANGE(-1, - 1), - RANGE(-0.1, - 0.1), - RANGE - (-0.02, - 0.02) - } +static const struct comedi_lrange range_dt282x_ai_hi_bipolar = { + 4, { + RANGE(-10, 10), + RANGE(-1, 1), + RANGE(-0.1, 0.1), + RANGE(-0.02, 0.02) + } }; -static const struct comedi_lrange range_dt282x_ai_hi_unipolar = { 4, { - RANGE(0, - 10), - RANGE(0, - 1), - RANGE(0, - 0.1), - RANGE(0, - 0.02) - } +static const struct comedi_lrange range_dt282x_ai_hi_unipolar = { + 4, { + RANGE(0, 10), + RANGE(0, 1), + RANGE(0, 0.1), + RANGE(0, 0.02) + } }; struct dt282x_board { @@ -370,7 +349,7 @@ static const struct dt282x_board boardtypes[] = { }, }; -#define n_boardtypes sizeof(boardtypes)/sizeof(struct dt282x_board) +#define n_boardtypes (sizeof(boardtypes)/sizeof(struct dt282x_board)) #define this_board ((const struct dt282x_board *)dev->board_ptr) struct dt282x_private { @@ -411,21 +390,25 @@ struct dt282x_private { #define update_adcsr(a) outw(devpriv->adcsr|(a), dev->iobase+DT2821_ADCSR) #define mux_busy() (inw(dev->iobase+DT2821_ADCSR)&DT2821_MUXBUSY) #define ad_done() (inw(dev->iobase+DT2821_ADCSR)&DT2821_ADDONE) -#define update_supcsr(a) outw(devpriv->supcsr|(a), dev->iobase+DT2821_SUPCSR) +#define update_supcsr(a) outw(devpriv->supcsr|(a), dev->iobase+DT2821_SUPCSR) /* * danger! macro abuse... a is the expression to wait on, and b is * the statement(s) to execute if it doesn't happen. */ -#define wait_for(a, b) \ - do{ \ - int _i; \ - for (_i=0;_iad_2scomp) { + if (devpriv->ad_2scomp) sign = 1 << (boardtype.adbits - 1); - } else { + else sign = 0; - } if (nbytes % 2) comedi_error(dev, "bug! odd number of bytes from dma xfer"); n = nbytes / 2; - for (i = 0; i < n; i++) { + for (i = 0; i < n; i++) buf[i] = (buf[i] & mask) ^ sign; - } } static void dt282x_ao_dma_interrupt(struct comedi_device *dev) @@ -486,7 +467,7 @@ static void dt282x_ao_dma_interrupt(struct comedi_device *dev) update_supcsr(DT2821_CLRDMADNE); if (!s->async->prealloc_buf) { - printk("async->data disappeared. dang!\n"); + printk(KERN_ERR "async->data disappeared. dang!\n"); return; } @@ -499,7 +480,7 @@ static void dt282x_ao_dma_interrupt(struct comedi_device *dev) size = cfc_read_array_from_buffer(s, ptr, devpriv->dma_maxsize); if (size == 0) { - printk("dt282x: AO underrun\n"); + printk(KERN_ERR "dt282x: AO underrun\n"); dt282x_ao_cancel(dev, s); s->async->events |= COMEDI_CB_OVERFLOW; return; @@ -519,7 +500,7 @@ static void dt282x_ai_dma_interrupt(struct comedi_device *dev) update_supcsr(DT2821_CLRDMADNE); if (!s->async->prealloc_buf) { - printk("async->data disappeared. dang!\n"); + printk(KERN_ERR "async->data disappeared. dang!\n"); return; } @@ -540,7 +521,7 @@ static void dt282x_ai_dma_interrupt(struct comedi_device *dev) devpriv->nread -= size / 2; if (devpriv->nread < 0) { - printk("dt282x: off by one\n"); + printk(KERN_INFO "dt282x: off by one\n"); devpriv->nread = 0; } if (!devpriv->nread) { @@ -651,7 +632,7 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) static int warn = 5; if (--warn <= 0) { disable_irq(dev->irq); - printk("disabling irq\n"); + printk(KERN_INFO "disabling irq\n"); } #endif comedi_error(dev, "D/A error"); @@ -666,13 +647,13 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) data = (short)inw(dev->iobase + DT2821_ADDAT); data &= (1 << boardtype.adbits) - 1; - if (devpriv->ad_2scomp) { + + if (devpriv->ad_2scomp) data ^= 1 << (boardtype.adbits - 1); - } ret = comedi_buf_put(s->async, data); - if (ret == 0) { + + if (ret == 0) s->async->events |= COMEDI_CB_OVERFLOW; - } devpriv->nread--; if (!devpriv->nread) { @@ -685,7 +666,8 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) } #endif comedi_event(dev, s); - /* printk("adcsr=0x%02x dacsr-0x%02x supcsr=0x%02x\n", adcsr, dacsr, supcsr); */ + /* printk("adcsr=0x%02x dacsr-0x%02x supcsr=0x%02x\n", + adcsr, dacsr, supcsr); */ return IRQ_RETVAL(handled); } @@ -776,7 +758,10 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev, if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* + * step 2: make sure trigger sources are unique + * and mutually compatible + */ /* note that mutual compatibility is not an issue here */ if (cmd->scan_begin_src != TRIG_FOLLOW && @@ -859,7 +844,8 @@ static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (devpriv->usedma == 0) { comedi_error(dev, - "driver requires 2 dma channels to execute command"); + "driver requires 2 dma channels" + " to execute command"); return -EIO; } @@ -1049,7 +1035,10 @@ static int dt282x_ao_cmdtest(struct comedi_device *dev, if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* + * step 2: make sure trigger sources are unique + * and mutually compatible + */ /* note that mutual compatibility is not an issue here */ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) @@ -1064,7 +1053,7 @@ static int dt282x_ao_cmdtest(struct comedi_device *dev, cmd->start_arg = 0; err++; } - if (cmd->scan_begin_arg < 5000 /* XXX unknown */ ) { + if (cmd->scan_begin_arg < 5000 /* XXX unknown */) { cmd->scan_begin_arg = 5000; err++; } @@ -1115,7 +1104,7 @@ static int dt282x_ao_inttrig(struct comedi_device *dev, size = cfc_read_array_from_buffer(s, devpriv->dma[0].buf, devpriv->dma_maxsize); if (size == 0) { - printk("dt282x: AO underrun\n"); + printk(KERN_ERR "dt282x: AO underrun\n"); return -EPIPE; } prep_ao_dma(dev, 0, size); @@ -1123,7 +1112,7 @@ static int dt282x_ao_inttrig(struct comedi_device *dev, size = cfc_read_array_from_buffer(s, devpriv->dma[1].buf, devpriv->dma_maxsize); if (size == 0) { - printk("dt282x: AO underrun\n"); + printk(KERN_ERR "dt282x: AO underrun\n"); return -EPIPE; } prep_ao_dma(dev, 1, size); @@ -1141,7 +1130,8 @@ static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (devpriv->usedma == 0) { comedi_error(dev, - "driver requires 2 dma channels to execute command"); + "driver requires 2 dma channels" + " to execute command"); return -EIO; } @@ -1262,7 +1252,8 @@ static const struct comedi_lrange *opt_ao_range_lkup(int x) return ao_range_table[x]; } -enum { opt_iobase = 0, opt_irq, opt_dma1, opt_dma2, /* i/o base, irq, dma channels */ +enum { /* i/o base, irq, dma channels */ + opt_iobase = 0, opt_irq, opt_dma1, opt_dma2, opt_diff, /* differential */ opt_ai_twos, opt_ao0_twos, opt_ao1_twos, /* twos comp */ opt_ai_range, opt_ao0_range, opt_ao1_range, /* range */ @@ -1295,9 +1286,9 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!iobase) iobase = 0x240; - printk("comedi%d: dt282x: 0x%04lx", dev->minor, iobase); + printk(KERN_INFO "comedi%d: dt282x: 0x%04lx", dev->minor, iobase); if (!request_region(iobase, DT2821_SIZE, "dt282x")) { - printk(" I/O port conflict\n"); + printk(KERN_INFO " I/O port conflict\n"); return -EBUSY; } dev->iobase = iobase; @@ -1305,7 +1296,7 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) outw(DT2821_BDINIT, dev->iobase + DT2821_SUPCSR); i = inw(dev->iobase + DT2821_ADCSR); #ifdef DEBUG - printk(" fingerprint=%x,%x,%x,%x,%x", + printk(KERN_DEBUG " fingerprint=%x,%x,%x,%x,%x", inw(dev->iobase + DT2821_ADCSR), inw(dev->iobase + DT2821_CHANCSR), inw(dev->iobase + DT2821_DACSR), @@ -1323,7 +1314,7 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) != DT2821_SUPCSR_VAL) || ((inw(dev->iobase + DT2821_TMRCTR) & DT2821_TMRCTR_MASK) != DT2821_TMRCTR_VAL)) { - printk(" board not found"); + printk(KERN_ERR " board not found"); return -EIO; } /* should do board test */ @@ -1344,26 +1335,25 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) irq = probe_irq_off(irqs); restore_flags(flags); - if (0 /* error */ ) { - printk(" error probing irq (bad)"); - } + if (0 /* error */) + printk(KERN_ERR " error probing irq (bad)"); } #endif if (irq > 0) { - printk(" ( irq = %d )", irq); + printk(KERN_INFO " ( irq = %d )", irq); ret = request_irq(irq, dt282x_interrupt, 0, "dt282x", dev); if (ret < 0) { - printk(" failed to get irq\n"); + printk(KERN_ERR " failed to get irq\n"); return -EIO; } dev->irq = irq; } else if (irq == 0) { - printk(" (no irq)"); + printk(KERN_INFO " (no irq)"); } else { #if 0 - printk(" (probe returned multiple irqs--bad)"); + printk(KERN_INFO " (probe returned multiple irqs--bad)"); #else - printk(" (irq probe not implemented)"); + printk(KERN_INFO " (irq probe not implemented)"); #endif } @@ -1435,16 +1425,15 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->maxdata = 1; s->range_table = &range_digital; - printk("\n"); + printk(KERN_INFO "\n"); return 0; } static void free_resources(struct comedi_device *dev) { - if (dev->irq) { + if (dev->irq) free_irq(dev->irq, dev); - } if (dev->iobase) release_region(dev->iobase, DT2821_SIZE); if (dev->private) { @@ -1461,7 +1450,7 @@ static void free_resources(struct comedi_device *dev) static int dt282x_detach(struct comedi_device *dev) { - printk("comedi%d: dt282x: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: dt282x: remove\n", dev->minor); free_resources(dev); @@ -1475,7 +1464,7 @@ static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2) devpriv->usedma = 0; if (!dma1 && !dma2) { - printk(" (no dma)"); + printk(KERN_ERR " (no dma)"); return 0; } @@ -1503,11 +1492,11 @@ static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2) devpriv->dma[0].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); devpriv->dma[1].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); if (!devpriv->dma[0].buf || !devpriv->dma[1].buf) { - printk(" can't get DMA memory"); + printk(KERN_ERR " can't get DMA memory"); return -ENOMEM; } - printk(" (dma=%d,%d)", dma1, dma2); + printk(KERN_INFO " (dma=%d,%d)", dma1, dma2); devpriv->usedma = 1; -- cgit v1.2.3 From c849d2538ebeef1ac26fad7a10c18b1e0fc35161 Mon Sep 17 00:00:00 2001 From: Roel Van Nyen Date: Thu, 29 Apr 2010 19:27:31 +0200 Subject: Staging: iio: Fix remaining code style issues fix code style issues Signed-of-by: Roel Van Nyen Cc: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/industrialio-core.c | 2 +- drivers/staging/iio/ring_sw.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index 37f58f66e491..7c9a12e0e8fe 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -809,7 +809,7 @@ int iio_device_register(struct iio_dev *dev_info) ret = iio_device_register_eventset(dev_info); if (ret) { dev_err(dev_info->dev.parent, - "Failed to register event set \n"); + "Failed to register event set\n"); goto error_free_sysfs; } if (dev_info->modes & INDIO_RING_TRIGGERED) diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c index 851a97edd1d4..e9570e33694e 100644 --- a/drivers/staging/iio/ring_sw.c +++ b/drivers/staging/iio/ring_sw.c @@ -126,8 +126,7 @@ int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring, spin_lock(&ring->buf.shared_ev_pointer.lock); ret = iio_push_or_escallate_ring_event(&ring->buf, - IIO_EVENT_CODE_RING_100_FULL, - timestamp); + IIO_EVENT_CODE_RING_100_FULL, timestamp); spin_unlock(&ring->buf.shared_ev_pointer.lock); if (ret) goto error_ret; -- cgit v1.2.3 From d87d909a45b7b6bf411559e85d386ef0a2f4bbae Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 30 Apr 2010 10:07:12 -0700 Subject: Staging: cxt1e1: use netdev_priv to fix build Fix cxt1e1 build error: drivers/staging/cxt1e1/linux.c:1195: error: 'struct net_device' has no member named 'priv' Signed-off-by: Randy Dunlap Acked-by: Bob Beers Signed-off-by: Greg Kroah-Hartman --- drivers/staging/cxt1e1/linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/cxt1e1/linux.c b/drivers/staging/cxt1e1/linux.c index 23e184da9723..aee7018f9d3f 100644 --- a/drivers/staging/cxt1e1/linux.c +++ b/drivers/staging/cxt1e1/linux.c @@ -1192,7 +1192,7 @@ c4_add_dev (hdw_info_t * hi, int brdno, unsigned long f0, unsigned long f1, hi->devname, irq1); unregister_netdev (ndev); free_irq (irq0, ndev); - OS_kfree (ndev->priv); + OS_kfree (netdev_priv(ndev)); OS_kfree (ndev); error_flag = EIO; return 0; -- cgit v1.2.3 From 981bdf41ea7bbeece1f08045e0456c725a4d8f2f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 30 Apr 2010 15:25:53 -0700 Subject: Staging: comedi: fix up coding style issues in comedilib.h This resolves some issues with comedilib.h Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedilib.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedilib.h b/drivers/staging/comedi/comedilib.h index 3918d53b3040..27dd3bec88af 100644 --- a/drivers/staging/comedi/comedilib.h +++ b/drivers/staging/comedi/comedilib.h @@ -164,10 +164,10 @@ int comedi_get_subdevice_type(unsigned int minor, unsigned int subdevice); int comedi_find_subdevice_by_type(unsigned int minor, int type, unsigned int subd); int comedi_get_n_channels(unsigned int minor, unsigned int subdevice); -unsigned int comedi_get_maxdata(unsigned int minor, unsigned int subdevice, unsigned - int chan); -int comedi_get_n_ranges(unsigned int minor, unsigned int subdevice, unsigned int - chan); +unsigned int comedi_get_maxdata(unsigned int minor, unsigned int subdevice, + unsigned int chan); +int comedi_get_n_ranges(unsigned int minor, unsigned int subdevice, + unsigned int chan); int comedi_do_insn(unsigned int minor, struct comedi_insn *insn); int comedi_poll(unsigned int minor, unsigned int subdev); -- cgit v1.2.3 From baf22b64aa7eb2d32c4ff49262b8d26c18bb232a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 30 Apr 2010 15:26:54 -0700 Subject: Staging: comedi: fix coding style issues in comedidev.h This resolves some coding style issues in comedidev.h And yes, volatile here meant nothing, removing it is ok. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index ebdccfdf220e..4e1955b1bf2c 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -57,7 +57,7 @@ static int __init x ## _init_module(void) \ {return comedi_driver_register(&(x)); } \ static void __exit x ## _cleanup_module(void) \ - {comedi_driver_unregister(&(x)); } \ + {comedi_driver_unregister(&(x)); } \ module_init(x ## _init_module); \ module_exit(x ## _cleanup_module); @@ -132,7 +132,7 @@ struct comedi_subdevice { struct comedi_device *device; int type; int n_chan; - volatile int subdev_flags; + int subdev_flags; int len_chanlist; /* maximum length of channel/gain list */ void *private; @@ -402,7 +402,7 @@ int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s, #define RANGE(a, b) {(a)*1e6, (b)*1e6, 0} #define RANGE_ext(a, b) {(a)*1e6, (b)*1e6, RF_EXTERNAL} #define RANGE_mA(a, b) {(a)*1e6, (b)*1e6, UNIT_mA} -#define RANGE_unitless(a, b) {(a)*1e6, (b)*1e6, 0} /* XXX */ +#define RANGE_unitless(a, b) {(a)*1e6, (b)*1e6, 0} #define BIP_RANGE(a) {-(a)*1e6, (a)*1e6, 0} #define UNI_RANGE(a) {0, (a)*1e6, 0} -- cgit v1.2.3 From 787ae4e26f3600c7d30693a92e18174a2d6363fc Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 30 Apr 2010 15:31:13 -0700 Subject: Staging: comedi: remove unneeded ifdef in comedi_bond.c No need to check for MODULE_LICENSE, it's always there. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_bond.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index 41311d99473b..4e6797a0b1e2 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -96,9 +96,7 @@ Configuration Options: #define MAX_CHANS 256 #define MODULE_NAME "comedi_bond" -#ifdef MODULE_LICENSE MODULE_LICENSE("GPL"); -#endif #ifndef STR # define STR1(x) #x # define STR(x) STR1(x) -- cgit v1.2.3 From ecfe20db3e0e2ff9df4007c4f1d34b27a24265fd Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 30 Apr 2010 15:35:37 -0700 Subject: Staging: comedi: fix up coding style issues in range.c Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/range.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c index 188c47948033..c35ade94a12d 100644 --- a/drivers/staging/comedi/range.c +++ b/drivers/staging/comedi/range.c @@ -22,7 +22,7 @@ */ #include "comedidev.h" -#include +#include const struct comedi_lrange range_bipolar10 = { 1, {BIP_RANGE(10)} }; const struct comedi_lrange range_bipolar5 = { 1, {BIP_RANGE(5)} }; @@ -130,14 +130,10 @@ int check_chanlist(struct comedi_subdevice *s, int n, unsigned int *chanlist) if (CR_CHAN(chanlist[i]) >= s->n_chan || CR_RANGE(chanlist[i]) >= s->range_table->length || aref_invalid(s, chanlist[i])) { - printk - ("bad chanlist[%d]=0x%08x n_chan=%d range length=%d\n", - i, chanlist[i], s->n_chan, - s->range_table->length); -#if 0 - for (i = 0; i < n; i++) - printk("[%d]=0x%08x\n", i, chanlist[i]); -#endif + printk(KERN_ERR "bad chanlist[%d]=0x%08x " + "in_chan=%d range length=%d\n", i, + chanlist[i], s->n_chan, + s->range_table->length); return -EINVAL; } } else if (s->range_table_list) { @@ -147,13 +143,13 @@ int check_chanlist(struct comedi_subdevice *s, int n, unsigned int *chanlist) CR_RANGE(chanlist[i]) >= s->range_table_list[chan]->length || aref_invalid(s, chanlist[i])) { - printk("bad chanlist[%d]=0x%08x\n", i, - chanlist[i]); + printk(KERN_ERR "bad chanlist[%d]=0x%08x\n", + i, chanlist[i]); return -EINVAL; } } } else { - printk("comedi: (bug) no range type list!\n"); + printk(KERN_ERR "comedi: (bug) no range type list!\n"); return -EINVAL; } return 0; -- cgit v1.2.3 From 8e81f184d9fc3c607a2f0b236d765eb348fbd845 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 30 Apr 2010 15:43:12 -0700 Subject: Staging: comedi: fix up coding issues in proc.c Fixes all but one. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/proc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/proc.c b/drivers/staging/comedi/proc.c index 5a22fe62c400..2b41faf37c60 100644 --- a/drivers/staging/comedi/proc.c +++ b/drivers/staging/comedi/proc.c @@ -33,9 +33,6 @@ #include /* #include */ -int comedi_read_procmem(char *buf, char **start, off_t offset, int len, - int *eof, void *data); - extern struct comedi_driver *comedi_drivers; int comedi_read_procmem(char *buf, char **start, off_t offset, int len, @@ -49,7 +46,8 @@ int comedi_read_procmem(char *buf, char **start, off_t offset, int len, l += sprintf(buf + l, "comedi version " COMEDI_RELEASE "\n" "format string: %s\n", - "\"%2d: %-20s %-20s %4d\",i,driver_name,board_name,n_subdevices"); + "\"%2d: %-20s %-20s %4d\", i, " + "driver_name, board_name, n_subdevices"); for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) { struct comedi_device_file_info *dev_file_info = -- cgit v1.2.3 From 47c92858446004d3cf28d8115266d631cdfd5d0a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 30 Apr 2010 15:48:19 -0700 Subject: Staging: comedi: remove local pci_ids.h file It's only being used for one vendor id, so move it into the driver that uses it and delete the file. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9118.c | 3 ++- drivers/staging/comedi/pci_ids.h | 31 ---------------------------- 2 files changed, 2 insertions(+), 32 deletions(-) delete mode 100644 drivers/staging/comedi/pci_ids.h (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index c7cba9579d07..dc4bd0423e6f 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -63,7 +63,6 @@ Configuration options: */ #include "../comedidev.h" -#include "../pci_ids.h" #include #include @@ -74,6 +73,8 @@ Configuration options: #include "comedi_pci.h" #include "comedi_fc.h" +#define PCI_VENDOR_ID_AMCC 0x10e8 + /* paranoid checks are broken */ #undef PCI9118_PARANOIDCHECK /* * if defined, then is used code which control diff --git a/drivers/staging/comedi/pci_ids.h b/drivers/staging/comedi/pci_ids.h deleted file mode 100644 index d979aa8e396b..000000000000 --- a/drivers/staging/comedi/pci_ids.h +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#ifndef __COMPAT_LINUX_PCI_IDS_H -#define __COMPAT_LINUX_PCI_IDS_H - -#include - -#ifndef PCI_VENDOR_ID_AMCC -#define PCI_VENDOR_ID_AMCC 0x10e8 -#endif - -#ifndef PCI_VENDOR_ID_CBOARDS -#define PCI_VENDOR_ID_CBOARDS 0x1307 -#endif - -#ifndef PCI_VENDOR_ID_QUANCOM -#define PCI_VENDOR_ID_QUANCOM 0x8008 -#endif - -#ifndef PCI_DEVICE_ID_QUANCOM_GPIB -#define PCI_DEVICE_ID_QUANCOM_GPIB 0x3302 -#endif - -#endif /* __COMPAT_LINUX_PCI_IDS_H */ -- cgit v1.2.3 From be29eac8ed3fd21d86f79d2e84dff49b8a13cd2c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 30 Apr 2010 15:55:39 -0700 Subject: Staging: comedi: remove wrapper.h Just make the bit call when it is needed, no need to wrap things up like this for no reason. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 18 +++++------------- drivers/staging/comedi/wrapper.h | 25 ------------------------- 2 files changed, 5 insertions(+), 38 deletions(-) delete mode 100644 drivers/staging/comedi/wrapper.h (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 4b69d06ca735..800106ae9901 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -38,7 +38,6 @@ #include #include #include "comedidev.h" -#include "wrapper.h" #include /* for SuSE brokenness */ #include #include @@ -442,9 +441,7 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, unsigned i; for (i = 0; i < async->n_buf_pages; ++i) { if (async->buf_page_list[i].virt_addr) { - mem_map_unreserve(virt_to_page - (async->buf_page_list[i]. - virt_addr)); + clear_bit(PG_reserved, &(virt_to_page(async->buf_page_list[i].virt_addr)->flags)); if (s->async_dma_dir != DMA_NONE) { dma_free_coherent(dev->hw_dev, PAGE_SIZE, @@ -497,12 +494,9 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, if (async->buf_page_list[i].virt_addr == NULL) break; - mem_map_reserve(virt_to_page - (async->buf_page_list[i]. - virt_addr)); - pages[i] = - virt_to_page(async-> - buf_page_list[i].virt_addr); + set_bit(PG_reserved, + &(virt_to_page(async->buf_page_list[i].virt_addr)->flags)); + pages[i] = virt_to_page(async->buf_page_list[i].virt_addr); } } if (i == n_pages) { @@ -519,9 +513,7 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, NULL) { break; } - mem_map_unreserve(virt_to_page - (async->buf_page_list - [i].virt_addr)); + clear_bit(PG_reserved, &(virt_to_page(async->buf_page_list[i].virt_addr)->flags)); if (s->async_dma_dir != DMA_NONE) { dma_free_coherent(dev->hw_dev, PAGE_SIZE, diff --git a/drivers/staging/comedi/wrapper.h b/drivers/staging/comedi/wrapper.h deleted file mode 100644 index 77fc673900e9..000000000000 --- a/drivers/staging/comedi/wrapper.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - linux/wrapper.h compatibility header - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __COMPAT_LINUX_WRAPPER_H_ -#define __COMPAT_LINUX_WRAPPER_H_ - -#define mem_map_reserve(p) set_bit(PG_reserved, &((p)->flags)) -#define mem_map_unreserve(p) clear_bit(PG_reserved, &((p)->flags)) - -#endif /* __COMPAT_LINUX_WRAPPER_H_ */ -- cgit v1.2.3 From dc1da7f7bae9e71e56f365d7e987760c88c116bd Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 30 Apr 2010 15:59:18 -0700 Subject: Staging: comedi: fix up remaining coding style issue in proc.c Move the external variable into a .h file, where it belongs. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.h | 1 + drivers/staging/comedi/proc.c | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_fops.h b/drivers/staging/comedi/comedi_fops.h index cb503c88c7f4..da4b4f5553f5 100644 --- a/drivers/staging/comedi/comedi_fops.h +++ b/drivers/staging/comedi/comedi_fops.h @@ -5,5 +5,6 @@ extern struct class *comedi_class; extern const struct file_operations comedi_fops; extern int comedi_autoconfig; +extern struct comedi_driver *comedi_drivers; #endif /* _COMEDI_FOPS_H */ diff --git a/drivers/staging/comedi/proc.c b/drivers/staging/comedi/proc.c index 2b41faf37c60..c0035cb759aa 100644 --- a/drivers/staging/comedi/proc.c +++ b/drivers/staging/comedi/proc.c @@ -30,11 +30,10 @@ #define __NO_VERSION__ #include "comedidev.h" +#include "comedi_fops.h" #include /* #include */ -extern struct comedi_driver *comedi_drivers; - int comedi_read_procmem(char *buf, char **start, off_t offset, int len, int *eof, void *data) { -- cgit v1.2.3 From 4e40cee9c8a46d4231d28ae7ae6d9938cf0526d5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 30 Apr 2010 16:52:52 -0700 Subject: Staging: comedi: use the standard NI pci device id Don't redefine something that we already have in the core kernel. Also move to use PCI_DEVICE() macros to make things a bit simpler when changing the define. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 1 - drivers/staging/comedi/drivers/mite.c | 2 +- drivers/staging/comedi/drivers/mite.h | 2 - drivers/staging/comedi/drivers/ni_6527.c | 7 +- drivers/staging/comedi/drivers/ni_65xx.c | 47 +++++++------ drivers/staging/comedi/drivers/ni_660x.c | 11 ++- drivers/staging/comedi/drivers/ni_670x.c | 11 +-- drivers/staging/comedi/drivers/ni_labpc.c | 5 +- drivers/staging/comedi/drivers/ni_pcidio.c | 25 +++---- drivers/staging/comedi/drivers/ni_pcimio.c | 107 ++++++++++++++--------------- 10 files changed, 101 insertions(+), 117 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 4e1955b1bf2c..6eba86d3820b 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -110,7 +110,6 @@ COMEDI_PCI_INITCLEANUP_NOMODULE(comedi_driver, pci_id_table) #define PCI_VENDOR_ID_INOVA 0x104c -#define PCI_VENDOR_ID_NATINST 0x1093 #define PCI_VENDOR_ID_DATX 0x1116 #define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307 #define PCI_VENDOR_ID_ADVANTECH 0x13fe diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c index 188f58042746..99d9985c5b37 100644 --- a/drivers/staging/comedi/drivers/mite.c +++ b/drivers/staging/comedi/drivers/mite.c @@ -76,7 +76,7 @@ void mite_init(void) for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pcidev != NULL; pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) { - if (pcidev->vendor == PCI_VENDOR_ID_NATINST) { + if (pcidev->vendor == PCI_VENDOR_ID_NI) { unsigned i; mite = kzalloc(sizeof(*mite), GFP_KERNEL); diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h index 9d5049f8fa85..999551f54c2a 100644 --- a/drivers/staging/comedi/drivers/mite.h +++ b/drivers/staging/comedi/drivers/mite.h @@ -27,8 +27,6 @@ #include #include "../comedidev.h" -#define PCI_VENDOR_ID_NATINST 0x1093 - /* #define DEBUG_MITE */ #define PCIMIO_COMPAT diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 653b4c8700af..1fc76cc6a28e 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -107,10 +107,9 @@ static const struct ni6527_board ni6527_boards[] = { #define this_board ((const struct ni6527_board *)dev->board_ptr) static DEFINE_PCI_DEVICE_TABLE(ni6527_pci_table) = { - { - PCI_VENDOR_ID_NATINST, 0x2b10, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x2b20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - 0} + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b10)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b20)}, + {0} }; MODULE_DEVICE_TABLE(pci, ni6527_pci_table); diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 9a4fffe5655f..d793f5a4ac98 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -266,30 +266,29 @@ static inline unsigned ni_65xx_total_num_ports(const struct ni_65xx_board } static DEFINE_PCI_DEVICE_TABLE(ni_65xx_pci_table) = { - { - PCI_VENDOR_ID_NATINST, 0x1710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x7085, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x7086, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x7087, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x7088, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70a9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70c3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70c8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70c9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70cc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70CD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70d1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70d2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70d3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x7124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x7126, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x7127, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x7128, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x718b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x718c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x71c5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - 0} + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1710)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7085)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7086)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7087)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7088)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70a9)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70c3)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70c8)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70c9)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70cc)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70CD)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70d1)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70d2)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70d3)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7124)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7125)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7126)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7127)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7128)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x718b)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x718c)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x71c5)}, + {0} }; MODULE_DEVICE_TABLE(pci, ni_65xx_pci_table); diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 017630fb2424..6a6fae53ea0b 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -420,12 +420,11 @@ static const struct ni_660x_board ni_660x_boards[] = { #define NI_660X_MAX_NUM_COUNTERS (NI_660X_MAX_NUM_CHIPS * counters_per_chip) static DEFINE_PCI_DEVICE_TABLE(ni_660x_pci_table) = { - { - PCI_VENDOR_ID_NATINST, 0x2c60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x1310, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x2cc0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - 0} + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2c60)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1310)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1360)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2cc0)}, + {0} }; MODULE_DEVICE_TABLE(pci, ni_660x_pci_table); diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 68221bfba5dd..44ae8368454d 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -47,8 +47,6 @@ Commands are not supported. #include "mite.h" -#define PCI_VENDOR_ID_NATINST 0x1093 - #define AO_VALUE_OFFSET 0x00 #define AO_CHAN_OFFSET 0x0c #define AO_STATUS_OFFSET 0x10 @@ -91,12 +89,9 @@ static const struct ni_670x_board ni_670x_boards[] = { }; static DEFINE_PCI_DEVICE_TABLE(ni_670x_pci_table) = { - { - PCI_VENDOR_ID_NATINST, 0x2c90, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x1920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - /*{ PCI_VENDOR_ID_NATINST, 0x0000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },*/ - { - 0} + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2c90)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1920)}, + {0} }; MODULE_DEVICE_TABLE(pci, ni_670x_pci_table); diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 9b840a96bafa..67c8a538802c 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -499,9 +499,8 @@ static struct comedi_driver driver_labpc = { #ifdef CONFIG_COMEDI_PCI static DEFINE_PCI_DEVICE_TABLE(labpc_pci_table) = { - { - PCI_VENDOR_ID_NATINST, 0x161, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - 0} + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x161)}, + {0} }; MODULE_DEVICE_TABLE(pci, labpc_pci_table); diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 9d337516409d..b126638d33b2 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -83,8 +83,6 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org #define DPRINTK(format, args...) #endif -#define PCI_VENDOR_ID_NATINST 0x1093 - #define PCI_DIO_SIZE 4096 #define PCI_MITE_SIZE 4096 @@ -379,18 +377,17 @@ static const struct nidio_board nidio_boards[] = { #define this_board ((const struct nidio_board *)dev->board_ptr) static DEFINE_PCI_DEVICE_TABLE(ni_pcidio_pci_table) = { - { - PCI_VENDOR_ID_NATINST, 0x1150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x1320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x12b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x0160, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x1630, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x13c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x0400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x1250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x17d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x1800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - 0} + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1150)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1320)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x12b0)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x0160)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1630)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x13c0)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x0400)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1250)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x17d0)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1800)}, + {0} }; MODULE_DEVICE_TABLE(pci, ni_pcidio_pci_table); diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 24c8b8ed5b4c..577fda84190d 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -130,60 +130,59 @@ Bugs: /* The following two tables must be in the same order */ static DEFINE_PCI_DEVICE_TABLE(ni_pci_table) = { - { - PCI_VENDOR_ID_NATINST, 0x0162, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x1170, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x1180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x1190, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x11b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x11c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x11d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x1270, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x1330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x1350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x14e0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x14f0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x1580, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x15b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x1880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x1870, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x18b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x18c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x2410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x2420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x2890, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x28c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x2a60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x2a70, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x2a80, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x2ab0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x2b80, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x2b90, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x2c80, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x2ca0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70aa, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70ab, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70ac, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70af, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70b4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70b6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70b7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70b8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70bc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70bd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70bf, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x70f2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x710d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x716c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x716d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x717f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x71bc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - PCI_VENDOR_ID_NATINST, 0x717d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { - 0} + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x0162)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1170)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1180)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1190)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x11b0)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x11c0)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x11d0)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1270)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1330)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1340)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1350)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x14e0)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x14f0)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1580)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x15b0)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1880)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1870)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x18b0)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x18c0)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2410)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2420)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2430)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2890)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x28c0)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2a60)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2a70)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2a80)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2ab0)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b80)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b90)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2c80)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2ca0)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70aa)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70ab)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70ac)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70af)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b0)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b4)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b6)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b7)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b8)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70bc)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70bd)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70bf)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70c0)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70f2)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x710d)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x716c)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x716d)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x717f)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x71bc)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x717d)}, + {0} }; MODULE_DEVICE_TABLE(pci, ni_pci_table); -- cgit v1.2.3 From 7a102e0ef173ff936efb6ea33b6a9db865c82645 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 30 Apr 2010 16:58:36 -0700 Subject: Staging: comedi: remove some pci vendor ids These are never used, so remove them. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 6eba86d3820b..162ac8d913e5 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -109,11 +109,8 @@ COMEDI_MODULE_MACROS \ COMEDI_PCI_INITCLEANUP_NOMODULE(comedi_driver, pci_id_table) -#define PCI_VENDOR_ID_INOVA 0x104c -#define PCI_VENDOR_ID_DATX 0x1116 #define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307 #define PCI_VENDOR_ID_ADVANTECH 0x13fe -#define PCI_VENDOR_ID_RTD 0x1435 #define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_VENDOR_ID_ADLINK 0x144a #define PCI_VENDOR_ID_ICP 0x104c -- cgit v1.2.3 From 3ca88dd5c3c6739f685793539a679ab5ac85aca3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 30 Apr 2010 17:07:25 -0700 Subject: Staging: comedi: move a pci vendor id The vendor id should be in the driver that needs it, not in a common file. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 1 - drivers/staging/comedi/drivers/me_daq.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 162ac8d913e5..09d3c51097f7 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -115,7 +115,6 @@ #define PCI_VENDOR_ID_ADLINK 0x144a #define PCI_VENDOR_ID_ICP 0x104c #define PCI_VENDOR_ID_CONTEC 0x1221 -#define PCI_VENDOR_ID_MEILHAUS 0x1402 #define COMEDI_NUM_MINORS 0x100 #define COMEDI_NUM_BOARD_MINORS 0x30 diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 80e192d2e77e..c8484aec657d 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -60,6 +60,7 @@ from http://www.comedi.org #define ME_DRIVER_NAME "me_daq" +#define PCI_VENDOR_ID_MEILHAUS 0x1402 #define ME2000_DEVICE_ID 0x2000 #define ME2600_DEVICE_ID 0x2600 -- cgit v1.2.3 From 558587e2d96a4f5439a609509e4ea88f7536203b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 30 Apr 2010 17:23:51 -0700 Subject: Staging: comedi: move another pci device id to the driver Put a pci vendor id into the drivers that need them. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 1 - drivers/staging/comedi/drivers/cb_pcidas64.c | 2 ++ drivers/staging/comedi/drivers/cb_pcimdas.c | 2 ++ drivers/staging/comedi/drivers/cb_pcimdda.c | 3 ++- 4 files changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 09d3c51097f7..8f842f85a105 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -109,7 +109,6 @@ COMEDI_MODULE_MACROS \ COMEDI_PCI_INITCLEANUP_NOMODULE(comedi_driver, pci_id_table) -#define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307 #define PCI_VENDOR_ID_ADVANTECH 0x13fe #define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_VENDOR_ID_ADLINK 0x144a diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index f17cb09acb28..0d9e92e59f9d 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -107,6 +107,8 @@ TODO: #define PRESCALED_TIMER_BASE 10000 /* 100kHz 'prescaled' clock for slow aquisition, maybe I'll support this someday */ #define DMA_BUFFER_SIZE 0x1000 +#define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307 + /* maximum value that can be loaded into board's 24-bit counters*/ static const int max_counter_value = 0xffffff; diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 2e61727fc9a0..49dccbbd713f 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -52,6 +52,8 @@ See http://www.measurementcomputing.com/PDFManuals/pcim-das1602_16.pdf for more /* #define CBPCIMDAS_DEBUG */ #undef CBPCIMDAS_DEBUG +#define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307 + /* Registers for the PCIM-DAS1602/16 */ /* sizes of io regions (bytes) */ diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index e32a31763d50..f404ec7723e5 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -91,7 +91,8 @@ Configuration Options: #include "8255.h" /* device ids of the cards we support -- currently only 1 card supported */ -#define PCI_ID_PCIM_DDA06_16 0x0053 +#define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307 +#define PCI_ID_PCIM_DDA06_16 0x0053 /* * This is straight from skel.c -- I did this in case this source file -- cgit v1.2.3 From 59af888d6af8e3d2c91b32e00e43f2ce750589b8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 30 Apr 2010 17:32:04 -0700 Subject: Staging: comedi: move another pci vendor id Move the vendor id to the drivers needing it. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 1 - drivers/staging/comedi/drivers/adv_pci1710.c | 2 ++ drivers/staging/comedi/drivers/adv_pci1723.c | 4 ++-- drivers/staging/comedi/drivers/adv_pci_dio.c | 2 ++ 4 files changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 8f842f85a105..5592cd162cdb 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -109,7 +109,6 @@ COMEDI_MODULE_MACROS \ COMEDI_PCI_INITCLEANUP_NOMODULE(comedi_driver, pci_id_table) -#define PCI_VENDOR_ID_ADVANTECH 0x13fe #define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_VENDOR_ID_ADLINK 0x144a #define PCI_VENDOR_ID_ICP 0x104c diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index f5bb286bfbd7..5c1ff779af2c 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -63,6 +63,8 @@ Configuration options: #define DPRINTK(fmt, args...) #endif +#define PCI_VENDOR_ID_ADVANTECH 0x13fe + /* hardware types of the cards */ #define TYPE_PCI171X 0 #define TYPE_PCI1713 2 diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 1644490ed0ad..9fe8fcc7f1d6 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -52,7 +52,7 @@ TODO: #include "comedi_pci.h" -#define ADVANTECH_VENDOR 0x13fe /* Advantech PCI vendor ID */ +#define PCI_VENDOR_ID_ADVANTECH 0x13fe /* Advantech PCI vendor ID */ /* hardware types of the cards */ #define TYPE_PCI1723 0 @@ -139,7 +139,7 @@ struct pci1723_board { static const struct pci1723_board boardtypes[] = { { .name = "pci1723", - .vendor_id = ADVANTECH_VENDOR, + .vendor_id = PCI_VENDOR_ID_ADVANTECH, .device_id = 0x1723, .iorange = IORANGE_1723, .cardtype = TYPE_PCI1723, diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index dbfeef8c5bc8..40eeecf5347f 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -45,6 +45,8 @@ Configuration options: #define DPRINTK(fmt, args...) #endif +#define PCI_VENDOR_ID_ADVANTECH 0x13fe + /* hardware types of the cards */ enum hw_cards_id { TYPE_PCI1730, TYPE_PCI1733, TYPE_PCI1734, TYPE_PCI1736, -- cgit v1.2.3 From 6608224c9e5c8aacf88914697be2d5f1fc7a0be6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 30 Apr 2010 17:36:52 -0700 Subject: Staging: comedi: remove another vendor id This id was already in the drivers, so just use it there instead of in a common header file. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 1 - drivers/staging/comedi/drivers/amplc_dio200.c | 2 +- drivers/staging/comedi/drivers/amplc_pci224.c | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 5592cd162cdb..f5b0810f2258 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -109,7 +109,6 @@ COMEDI_MODULE_MACROS \ COMEDI_PCI_INITCLEANUP_NOMODULE(comedi_driver, pci_id_table) -#define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_VENDOR_ID_ADLINK 0x144a #define PCI_VENDOR_ID_ICP 0x104c #define PCI_VENDOR_ID_CONTEC 0x1221 diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 92bcc205dd4b..6a87652e7e2a 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -218,7 +218,7 @@ order they appear in the channel list. #define DIO200_DRIVER_NAME "amplc_dio200" /* PCI IDs */ -/* #define PCI_VENDOR_ID_AMPLICON 0x14dc */ +#define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a #define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b #define PCI_DEVICE_ID_INVALID 0xffff diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 8af156dca17e..c486a878e180 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -118,7 +118,7 @@ Caveats: /* * PCI IDs. */ -/* #define PCI_VENDOR_ID_AMPLICON 0x14dc */ +#define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI224 0x0007 #define PCI_DEVICE_ID_AMPLICON_PCI234 0x0008 #define PCI_DEVICE_ID_INVALID 0xffff -- cgit v1.2.3 From d42bffb8990ca9e74cc1ba625ce23dda2bd8c8c5 Mon Sep 17 00:00:00 2001 From: Marin Mitov Date: Fri, 30 Apr 2010 18:36:09 +0300 Subject: Staging: Yet another (third) dt3155 driver PCI/video4linux compliant Kernel module (device driver) for dt3155 frame grabber video4linux2 compliant (finally). Works with "xawtv -f". ====================================================== This driver is written (almost) from scratch, using the allocator developed for dt3155pci see bellow). The driver uses videobuf-dma-contig interface modified to use the above mentioned allocator instead of dma_alloc_coheren(). The first thing to do was to design a new allocator based on allocating a configurable number of 4MB chunks of memory, that latter are broken into frame buffers of 768x576 bytes kept in different FIFOs (queues). As far as the driver autoloads as a kernel module during kernel boot, the allocation of 4MB chunks succeeds. The driver keeps three FIFOs: one for 4MB chunks, one for free buffers (available for allocations) and one for buffers already allocated. Allocation/deallocation is done automatically though the video4linux videobuf subsystem (some pointers to functions are replaced by driver supplied functions). Sure, there are problems: 1. The device tested to work with "xawtv -f" either via read() method (DT3155_STREAMING not selected), or via mmap() method (DT3155_STREAMING is selected) only. This coresponds to either cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; or cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; but not when cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; This is because xawtv calls poll() before starting streaming, but videobuf_poll_stream() automatically starts reading if streaming is not started. This selection is made during kernel configuration (for now). 2. Works for CCIR, but should work for RS-170 (not tested) This is made also during kernel configuration. 3. Could work for multiple dt3155 frame grabbers in a PC, (private data is allocated during PCI probe() method), but is not tested due to lack of a second board. 4. Not tested on a BIG ENDIAN architecture. 5. Many others you could find .... :-) All critics, comments, suggestions are wellcome. Signed-off-by: Marin Mitov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/dt3155v4l/Kconfig | 28 + drivers/staging/dt3155v4l/Makefile | 4 + drivers/staging/dt3155v4l/dt3155-bufs.c | 256 +++++ drivers/staging/dt3155v4l/dt3155-bufs.h | 88 ++ drivers/staging/dt3155v4l/dt3155v4l.c | 1537 +++++++++++++++++++++++++++++++ drivers/staging/dt3155v4l/dt3155v4l.h | 220 +++++ 7 files changed, 2135 insertions(+) create mode 100644 drivers/staging/dt3155v4l/Kconfig create mode 100644 drivers/staging/dt3155v4l/Makefile create mode 100644 drivers/staging/dt3155v4l/dt3155-bufs.c create mode 100644 drivers/staging/dt3155v4l/dt3155-bufs.h create mode 100644 drivers/staging/dt3155v4l/dt3155v4l.c create mode 100644 drivers/staging/dt3155v4l/dt3155v4l.h (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index d97e46e60d91..6b00e15a3713 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -137,6 +137,8 @@ source "drivers/staging/sm7xx/Kconfig" source "drivers/staging/dt3155/Kconfig" +source "drivers/staging/dt3155v4l/Kconfig" + source "drivers/staging/crystalhd/Kconfig" source "drivers/staging/cxt1e1/Kconfig" diff --git a/drivers/staging/dt3155v4l/Kconfig b/drivers/staging/dt3155v4l/Kconfig new file mode 100644 index 000000000000..5cef5420d288 --- /dev/null +++ b/drivers/staging/dt3155v4l/Kconfig @@ -0,0 +1,28 @@ +config VIDEO_DT3155 + tristate "DT3155 frame grabber, Video4Linux interface" + depends on PCI && VIDEO_DEV && VIDEO_V4L2 + select VIDEOBUF_DMA_CONTIG + default n + ---help--- + Enables dt3155 device driver for the DataTranslation DT3155 frame grabber. + Say Y here if you have this hardware. + In doubt, say N. + + To compile this driver as a module, choose M here: the + module will be called dt3155_v4l. + +config DT3155_CCIR + bool "Selects CCIR/50Hz vertical refresh" + depends on VIDEO_DT3155 + default y + ---help--- + Select it for CCIR/50Hz (European region), + or leave it unselected for RS-170/60Hz (North America). + +config DT3155_STREAMING + bool "Selects mmap streaming instead of read method" + depends on VIDEO_DT3155 + default y + ---help--- + Select it if you wish to try mmap streaming, or + or leave it unselected for using read method. diff --git a/drivers/staging/dt3155v4l/Makefile b/drivers/staging/dt3155v4l/Makefile new file mode 100644 index 000000000000..3a207ccd3143 --- /dev/null +++ b/drivers/staging/dt3155v4l/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_VIDEO_DT3155) += dt3155_v4l.o +dt3155_v4l-objs := \ + dt3155-bufs.o \ + dt3155v4l.o diff --git a/drivers/staging/dt3155v4l/dt3155-bufs.c b/drivers/staging/dt3155v4l/dt3155-bufs.c new file mode 100644 index 000000000000..f93e431e786b --- /dev/null +++ b/drivers/staging/dt3155v4l/dt3155-bufs.c @@ -0,0 +1,256 @@ +/*************************************************************************** + * Copyright (C) 2006-2010 by Marin Mitov * + * mitov@issp.bas.bg * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "dt3155-bufs.h" + +/** + * dt3155_init_chunks_buf - creates a chunk buffer and allocates memory for it + * + * returns: a pointer to the struct dt3155_buf or NULL if failed + * + * Creates a struct dt3155_buf, then allocates a chunk of memory of + * size DT3155_CHUNK_SIZE and sets all the pages in it as Reserved. + * This is done to be able to use remap_pfn_range() on these buffers + * (which do not work on normal memory if Reserved bit is not set) + */ +struct dt3155_buf * +dt3155_init_chunks_buf(void) +{ /* could sleep */ + struct dt3155_buf *buf; + int i; + + buf = kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) + return NULL; + buf->cpu = (void *)__get_free_pages(DT3155_CHUNK_FLAGS, + get_order(DT3155_CHUNK_SIZE)); + if (!buf->cpu) { + kfree(buf); + return NULL; + } + for (i = 0; i < DT3155_CHUNK_SIZE; i += PAGE_SIZE) + SetPageReserved(virt_to_page(buf->cpu + i)); + return buf; /* success */ +} + +/** + * dt3155_free_chunks_buf - destroys the specified buffer + * + * @buf: the buffer to be freed + * + * Clears Reserved bit of all pages in the chunk, frees the chunk memory + * and destroys struct dt3155_buf. + */ +void +dt3155_free_chunks_buf(struct dt3155_buf *buf) +{ + int i; + + for (i = 0; i < DT3155_CHUNK_SIZE; i += PAGE_SIZE) + ClearPageReserved(virt_to_page(buf->cpu + i)); + free_pages((unsigned long)buf->cpu, get_order(DT3155_CHUNK_SIZE)); + kfree(buf); +} + +/** + * dt3155_init_fifo - creates and initializes a fifo + * + * returns: a pointer to the crated and initialized struct dt3155_fifo + * or NULL if failed + */ +struct dt3155_fifo * +dt3155_init_fifo(void) +{ /* could sleep */ + struct dt3155_fifo *fifo = kzalloc(sizeof(*fifo), GFP_KERNEL); + if (fifo) + spin_lock_init(&fifo->lock); + return fifo; +} + +/* dt3155_free_fifo(x) defined as macro in dt3155.h */ + +/** + * dt3155_get_buf - gets a buffer from the fifo + * + * @fifo: the fifo to get a buffer from + * + * returns: a pointer to the buffer or NULL if failed + * + * dt3155_get_buf gets the fifo's spin_lock and returns the + * buffer pointed by the head. Could be used in any context. + */ +struct dt3155_buf * +dt3155_get_buf(struct dt3155_fifo *fifo) +{ + unsigned long flags; + struct dt3155_buf *tmp_buf; + + spin_lock_irqsave(&fifo->lock, flags); + tmp_buf = fifo->head; + if (fifo->head) + fifo->head = fifo->head->next; + if (!fifo->head) + fifo->tail = NULL; + spin_unlock_irqrestore(&fifo->lock, flags); + return tmp_buf; +} + +/** + * dt3155_put_buf - puts a buffer into a fifo + * + * @buf: the buffer to put + * @fifo: the fifo to put the buffer in + * + * dt3155_put_buf gets the fifo's spin_lock and puts the buf + * at the tail of the fifo. Could be used in any context. + */ +void +dt3155_put_buf(struct dt3155_buf *buf, struct dt3155_fifo *fifo) +{ + unsigned long flags; + + spin_lock_irqsave(&fifo->lock, flags); + buf->next = NULL; + if (fifo->tail) + fifo->tail->next = buf; + fifo->tail = buf; + if (!fifo->head) + fifo->head = buf; + spin_unlock_irqrestore(&fifo->lock, flags); +} + +/** + * dt3155_init_chunks_fifo - creates and fills a chunks_fifo + * + * returns: a pointer to the fifo or NULL if failed + * + * dt3155_init_chunks_fifo creates and fills the fifo with + * a number of chunks <= DT3155_CHUNK_NUM. The returned fifo + * contains at least one chunk. + */ +struct dt3155_fifo * +dt3155_init_chunks_fifo(void) +{ /* could sleep */ + int i; + + struct dt3155_fifo *chunks; + struct dt3155_buf *tmp_buf; + + chunks = dt3155_init_fifo(); + if (!chunks) + return NULL; + tmp_buf = dt3155_init_chunks_buf(); + if (!tmp_buf) { + dt3155_free_fifo(chunks); + return NULL; + } + dt3155_put_buf(tmp_buf, chunks); + for (i = 1; i < DT3155_CHUNK_NUM; i++) { + tmp_buf = dt3155_init_chunks_buf(); + if (!tmp_buf) + break; + dt3155_put_buf(tmp_buf, chunks); + } + return chunks; +} + +/** + * dt3155_free_chunks_fifo - empties and destroys the chunks_fifo + * + * @chunks: the chunks_fifo to be freed + * + * dt3155_free_chunks_fifo deallocates all chunks in the fifo and + * destroys it. + */ +void +dt3155_free_chunks_fifo(struct dt3155_fifo *chunks) +{ + int buf_count = 0; + struct dt3155_buf *buf; + + while ((buf = dt3155_get_buf(chunks))) { + dt3155_free_chunks_buf(buf); + buf_count++; + } + dt3155_free_fifo(chunks); + printk(KERN_INFO "dt3155: %i chunks freed\n", buf_count); +} + +/** + * dt3155_init_ibufs_fifo - creates and fills an image buffer fifo + * + * @chunks: chunks_fifo to take memory from + * @buf_size: the size of image buffers + * + * returns: a pointer to the fifo filled with image buffers + * + * dt3155_init_ibufs_fifo takes chunks from chunks_fifo, chops them + * into pieces of size buf_size and fills image fifo with them. + */ +struct dt3155_fifo * +dt3155_init_ibufs_fifo(struct dt3155_fifo *chunks, int buf_size) +{ /* could sleep */ + int i, buf_count = 0; + struct dt3155_buf *tmp_ibuf, *chunks_buf, *last_chunk; + struct dt3155_fifo *tmp_fifo; + + tmp_fifo = dt3155_init_fifo(); + if (!tmp_fifo) + return NULL; + last_chunk = chunks->tail; + do { + chunks_buf = dt3155_get_buf(chunks); + dt3155_put_buf(chunks_buf, chunks); + for (i = 0; i < DT3155_CHUNK_SIZE / buf_size; i++) { + tmp_ibuf = kzalloc(sizeof(*tmp_ibuf), GFP_KERNEL); + if (tmp_ibuf) { + tmp_ibuf->cpu = + chunks_buf->cpu + DT3155_BUF_SIZE * i; + dt3155_put_buf(tmp_ibuf, tmp_fifo); + buf_count++; + } else { + if (buf_count) { + goto print_num_bufs; + } else { + dt3155_free_fifo(tmp_fifo); + return NULL; + } + } + } + } while (chunks_buf != last_chunk); +print_num_bufs: + printk(KERN_INFO "dt3155: %i image buffers available\n", buf_count); + return tmp_fifo; +} + +/** + * dt3155_free_ibufs_fifo - empties and destroys an image fifo + * + * @fifo: the fifo to free + */ +void +dt3155_free_ibufs_fifo(struct dt3155_fifo *fifo) +{ + struct dt3155_buf *tmp_ibuf; + + while ((tmp_ibuf = dt3155_get_buf(fifo))) + kfree(tmp_ibuf); + kfree(fifo); +} diff --git a/drivers/staging/dt3155v4l/dt3155-bufs.h b/drivers/staging/dt3155v4l/dt3155-bufs.h new file mode 100644 index 000000000000..db6d387231b2 --- /dev/null +++ b/drivers/staging/dt3155v4l/dt3155-bufs.h @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright (C) 2006-2010 by Marin Mitov * + * mitov@issp.bas.bg * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _DT3155_BUFS_H_ +#define _DT3155_BUFS_H_ + +#include + +/* 4 chunks of 4MB, 9 buffers each = 36 buffers (> VIDEO_MAX_FRAME) */ +#define DT3155_CHUNK_NUM 4 + +/* DT3155_CHUNK_SIZE should be 4M (2^22) or less, but more than image size */ +#define DT3155_CHUNK_SIZE (1U << 22) +#define DT3155_CHUNK_FLAGS (GFP_KERNEL | GFP_DMA32 | __GFP_COLD | __GFP_NOWARN) + +/* DT3155_BUF_SIZE = 108 * PAGE_SIZE, so each buf is PAGE_SIZE alligned */ +#define DT3155_BUF_SIZE (768 * 576) + +/** + * struct dt3155_buf - image buffer structure + * + * @cpu: virtual kernel address of the buffer + * @dma: dma (bus) address of the buffer + * @next: pointer to the next buffer in the fifo + * @tv: time value when the image has been acquired + */ +struct dt3155_buf { + void *cpu; + dma_addr_t dma; + struct dt3155_buf *next; + struct timeval tv; +}; + +/** + * struct dt3155_fifo - fifo structure + * + * @head: pointer to the head of the fifo + * @tail: pionter to the tail of the fifo + * @lock: spin_lock to protect the fifo + */ +struct dt3155_fifo { + struct dt3155_buf *head; + struct dt3155_buf *tail; + spinlock_t lock; +}; + +struct dt3155_buf * __must_check +dt3155_init_chunks_buf(void); +void +dt3155_free_chunks_buf(struct dt3155_buf *buf); + +struct dt3155_fifo * __must_check +dt3155_init_fifo(void); +#define dt3155_free_fifo(x) kfree(x) + +struct dt3155_buf * __must_check +dt3155_get_buf(struct dt3155_fifo *fifo); +void +dt3155_put_buf(struct dt3155_buf *buf, struct dt3155_fifo *fifo); + +struct dt3155_fifo * __must_check +dt3155_init_chunks_fifo(void); +void +dt3155_free_chunks_fifo(struct dt3155_fifo *chunks); + +struct dt3155_fifo * __must_check +dt3155_init_ibufs_fifo(struct dt3155_fifo *chunks, int buf_size); +void +dt3155_free_ibufs_fifo(struct dt3155_fifo *fifo); + +#endif /* _DT3155_BUFS_H_ */ diff --git a/drivers/staging/dt3155v4l/dt3155v4l.c b/drivers/staging/dt3155v4l/dt3155v4l.c new file mode 100644 index 000000000000..6282b7bbd4eb --- /dev/null +++ b/drivers/staging/dt3155v4l/dt3155v4l.c @@ -0,0 +1,1537 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dt3155v4l.h" +#include "dt3155-bufs.h" + +#define DT3155_VENDOR_ID 0x8086 +#define DT3155_DEVICE_ID 0x1223 + +/* global initializers (for all boards) */ +#ifdef CONFIG_DT3155_CCIR +static const u8 csr2_init = VT_50HZ; +#define DT3155_CURRENT_NORM V4L2_STD_625_50 +static const unsigned int img_width = 768; +static const unsigned int img_height = 576; +static const unsigned int frames_per_sec = 25; +static const struct v4l2_fmtdesc frame_std[] = { + { + .index = 0, + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, + .flags = 0, + .description = "CCIR/50Hz 8 bits gray", + .pixelformat = V4L2_PIX_FMT_GREY, + }, +}; +#else +static const u8 csr2_init = VT_60HZ; +#define DT3155_CURRENT_NORM V4L2_STD_525_60 +static const unsigned int img_width = 640; +static const unsigned int img_height = 480; +static const unsigned int frames_per_sec = 30; +static const struct v4l2_fmtdesc frame_std[] = { + { + .index = 0, + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, + .flags = 0, + .description = "RS-170/60Hz 8 bits gray", + .pixelformat = V4L2_PIX_FMT_GREY, + }, +}; +#endif + +#define NUM_OF_FORMATS ARRAY_SIZE(frame_std) + +static u8 config_init = ACQ_MODE_EVEN; + +/** + * read_i2c_reg - reads an internal i2c register + * + * @addr: dt3155 mmio base address + * @index: index (internal address) of register to read + * @data: pointer to byte the read data will be placed in + * + * returns: zero on success or error code + * + * This function starts reading the specified (by index) register + * and busy waits for the process to finish. The result is placed + * in a byte pointed by data. + */ +static int +read_i2c_reg(void *addr, u8 index, u8 *data) +{ + u32 tmp = index; + + iowrite32((tmp<<17) | IIC_READ, addr + IIC_CSR2); + mmiowb(); + udelay(45); /* wait at least 43 usec for NEW_CYCLE to clear */ + if (ioread32(addr + IIC_CSR2) & NEW_CYCLE) { + /* error: NEW_CYCLE not cleared */ + printk(KERN_ERR "dt3155: NEW_CYCLE not cleared\n"); + return -EIO; + } + tmp = ioread32(addr + IIC_CSR1); + if (tmp & DIRECT_ABORT) { + /* error: DIRECT_ABORT set */ + printk(KERN_ERR "dt3155: DIRECT_ABORT set\n"); + /* reset DIRECT_ABORT bit */ + iowrite32(DIRECT_ABORT, addr + IIC_CSR1); + return -EIO; + } + *data = tmp>>24; + return 0; +} + +/** + * write_i2c_reg - writes to an internal i2c register + * + * @addr: dt3155 mmio base address + * @index: index (internal address) of register to read + * @data: data to be written + * + * returns: zero on success or error code + * + * This function starts writting the specified (by index) register + * and busy waits for the process to finish. + */ +static int +write_i2c_reg(void *addr, u8 index, u8 data) +{ + u32 tmp = index; + + iowrite32((tmp<<17) | IIC_WRITE | data, addr + IIC_CSR2); + mmiowb(); + udelay(65); /* wait at least 63 usec for NEW_CYCLE to clear */ + if (ioread32(addr + IIC_CSR2) & NEW_CYCLE) { + /* error: NEW_CYCLE not cleared */ + printk(KERN_ERR "dt3155: NEW_CYCLE not cleared\n"); + return -EIO; + } + if (ioread32(addr + IIC_CSR1) & DIRECT_ABORT) { + /* error: DIRECT_ABORT set */ + printk(KERN_ERR "dt3155: DIRECT_ABORT set\n"); + /* reset DIRECT_ABORT bit */ + iowrite32(DIRECT_ABORT, addr + IIC_CSR1); + return -EIO; + } + return 0; +} + +/** + * write_i2c_reg_nowait - writes to an internal i2c register + * + * @addr: dt3155 mmio base address + * @index: index (internal address) of register to read + * @data: data to be written + * + * This function starts writting the specified (by index) register + * and then returns. + */ +void +write_i2c_reg_nowait(void *addr, u8 index, u8 data) +{ + u32 tmp = index; + + iowrite32((tmp<<17) | IIC_WRITE | data, addr + IIC_CSR2); + mmiowb(); +} + +/** + * wait_i2c_reg - waits the read/write to finish + * + * @addr: dt3155 mmio base address + * + * returns: zero on success or error code + * + * This function waits reading/writting to finish. + */ +static int +wait_i2c_reg(void *addr) +{ + if (ioread32(addr + IIC_CSR2) & NEW_CYCLE) + udelay(65); /* wait at least 63 usec for NEW_CYCLE to clear */ + if (ioread32(addr + IIC_CSR2) & NEW_CYCLE) { + /* error: NEW_CYCLE not cleared */ + printk(KERN_ERR "dt3155: NEW_CYCLE not cleared\n"); + return -EIO; + } + if (ioread32(addr + IIC_CSR1) & DIRECT_ABORT) { + /* error: DIRECT_ABORT set */ + printk(KERN_ERR "dt3155: DIRECT_ABORT set\n"); + /* reset DIRECT_ABORT bit */ + iowrite32(DIRECT_ABORT, addr + IIC_CSR1); + return -EIO; + } + return 0; +} + +/* + * global pointers to a list of 4MB chunks reserved at driver + * load, broken down to contiguous buffers of 768 * 576 bytes + * each to form a pool of buffers for allocations + * FIXME: add spinlock to protect moves between alloc/free lists + */ +static struct dt3155_fifo *dt3155_chunks; /* list of 4MB chuncks */ +static struct dt3155_fifo *dt3155_free_bufs; /* list of free buffers */ +static struct dt3155_fifo *dt3155_alloc_bufs; /* list of allocated buffers */ + +/* same as in */ +struct videobuf_dma_contig_memory { + u32 magic; + void *vaddr; + dma_addr_t dma_handle; + unsigned long size; + int is_userptr; +}; + +#define MAGIC_DC_MEM 0x0733ac61 +#define MAGIC_CHECK(is, should) \ + if (unlikely((is) != (should))) { \ + pr_err("magic mismatch: %x expected %x\n", (is), (should)); \ + BUG(); \ + } + +/* helper functions to allocate/free buffers from the pool */ +static void * +dt3155_alloc_buffer(struct device *dev, size_t size, dma_addr_t *dma_handle, + gfp_t flag) +{ + struct dt3155_buf *buf; + + if (size > DT3155_BUF_SIZE) + return NULL; + size = DT3155_BUF_SIZE; /* same for CCIR & RS-170 */ + buf = dt3155_get_buf(dt3155_free_bufs); + if (!buf) + return NULL; + buf->dma = dma_map_single(dev, buf->cpu, size, DMA_FROM_DEVICE); + if (dma_mapping_error(dev, buf->dma)) { + dt3155_put_buf(buf, dt3155_free_bufs); + return NULL; + } + dt3155_put_buf(buf, dt3155_alloc_bufs); + *dma_handle = buf->dma; + return buf->cpu; +} + +static void +dt3155_free_buffer(struct device *dev, size_t size, void *cpu_addr, + dma_addr_t dma_handle) +{ + struct dt3155_buf *buf, *last; + int found = 0; + + if (!cpu_addr) /* to free NULL is OK */ + return; + last = dt3155_get_buf(dt3155_alloc_bufs); + if (!last) { + printk(KERN_ERR "dt3155: %s(): no alloc buffers\n", __func__); + return; + } + dt3155_put_buf(last, dt3155_alloc_bufs); + do { + buf = dt3155_get_buf(dt3155_alloc_bufs); + if (buf->cpu == cpu_addr && buf->dma == dma_handle) { + found = 1; + break; + } + dt3155_put_buf(buf, dt3155_alloc_bufs); + } while (buf != last); + if (!found) { + printk(KERN_ERR "dt3155: %s(): buffer not found\n", __func__); + return; + } + size = DT3155_BUF_SIZE; /* same for CCIR & RS-170 */ + dma_unmap_single(dev, dma_handle, size, DMA_FROM_DEVICE); + dt3155_put_buf(buf, dt3155_free_bufs); +} + +/* same as videobuf_dma_contig_user_get() */ +static int +dt3155_dma_contig_user_get(struct videobuf_dma_contig_memory *mem, + struct videobuf_buffer *vb) +{ + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + unsigned long prev_pfn, this_pfn; + unsigned long pages_done, user_address; + int ret; + + mem->size = PAGE_ALIGN(vb->size); + mem->is_userptr = 0; + ret = -EINVAL; + + down_read(&mm->mmap_sem); + + vma = find_vma(mm, vb->baddr); + if (!vma) + goto out_up; + + if ((vb->baddr + mem->size) > vma->vm_end) + goto out_up; + + pages_done = 0; + prev_pfn = 0; /* kill warning */ + user_address = vb->baddr; + + while (pages_done < (mem->size >> PAGE_SHIFT)) { + ret = follow_pfn(vma, user_address, &this_pfn); + if (ret) + break; + + if (pages_done == 0) + mem->dma_handle = this_pfn << PAGE_SHIFT; + else if (this_pfn != (prev_pfn + 1)) + ret = -EFAULT; + + if (ret) + break; + + prev_pfn = this_pfn; + user_address += PAGE_SIZE; + pages_done++; + } + + if (!ret) + mem->is_userptr = 1; + + out_up: + up_read(¤t->mm->mmap_sem); + + return ret; +} + +/* same as videobuf_dma_contig_user_put() */ +static void +dt3155_dma_contig_user_put(struct videobuf_dma_contig_memory *mem) +{ + mem->is_userptr = 0; + mem->dma_handle = 0; + mem->size = 0; +} + +/* same as videobuf_iolock() but uses allocations from the pool */ +static int +dt3155_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb, + struct v4l2_framebuffer *fbuf) +{ + struct videobuf_dma_contig_memory *mem = vb->priv; + + BUG_ON(!mem); + MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); + + switch (vb->memory) { + case V4L2_MEMORY_MMAP: + dev_dbg(q->dev, "%s memory method MMAP\n", __func__); + + /* All handling should be done by __videobuf_mmap_mapper() */ + if (!mem->vaddr) { + dev_err(q->dev, "memory is not alloced/mmapped.\n"); + return -EINVAL; + } + break; + case V4L2_MEMORY_USERPTR: + dev_dbg(q->dev, "%s memory method USERPTR\n", __func__); + + /* handle pointer from user space */ + if (vb->baddr) + return dt3155_dma_contig_user_get(mem, vb); + + /* allocate memory for the read() method */ + mem->size = PAGE_ALIGN(vb->size); + mem->vaddr = dt3155_alloc_buffer(q->dev, mem->size, + &mem->dma_handle, GFP_KERNEL); + if (!mem->vaddr) { + dev_err(q->dev, "dma_alloc_coherent %ld failed\n", + mem->size); + return -ENOMEM; + } + + dev_dbg(q->dev, "dma_alloc_coherent data is at %p (%ld)\n", + mem->vaddr, mem->size); + break; + case V4L2_MEMORY_OVERLAY: + default: + dev_dbg(q->dev, "%s memory method OVERLAY/unknown\n", + __func__); + return -EINVAL; + } + + return 0; +} + +/* same as videobuf_dma_contig_free() but uses the pool */ +void +dt3155_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf) +{ + struct videobuf_dma_contig_memory *mem = buf->priv; + + /* mmapped memory can't be freed here, otherwise mmapped region + would be released, while still needed. In this case, the memory + release should happen inside videobuf_vm_close(). + So, it should free memory only if the memory were allocated for + read() operation. + */ + if (buf->memory != V4L2_MEMORY_USERPTR) + return; + + if (!mem) + return; + + MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); + + /* handle user space pointer case */ + if (buf->baddr) { + dt3155_dma_contig_user_put(mem); + return; + } + + /* read() method */ + dt3155_free_buffer(q->dev, mem->size, mem->vaddr, mem->dma_handle); + mem->vaddr = NULL; +} + +/* same as videobuf_vm_open() */ +static void +dt3155_vm_open(struct vm_area_struct *vma) +{ + struct videobuf_mapping *map = vma->vm_private_data; + + dev_dbg(map->q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n", + map, map->count, vma->vm_start, vma->vm_end); + + map->count++; +} + +/* same as videobuf_vm_close(), but free to the pool */ +static void +dt3155_vm_close(struct vm_area_struct *vma) +{ + struct videobuf_mapping *map = vma->vm_private_data; + struct videobuf_queue *q = map->q; + int i; + + dev_dbg(map->q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", + map, map->count, vma->vm_start, vma->vm_end); + + map->count--; + if (0 == map->count) { + struct videobuf_dma_contig_memory *mem; + + dev_dbg(map->q->dev, "munmap %p q=%p\n", map, q); + mutex_lock(&q->vb_lock); + + /* We need first to cancel streams, before unmapping */ + if (q->streaming) + videobuf_queue_cancel(q); + + for (i = 0; i < VIDEO_MAX_FRAME; i++) { + if (NULL == q->bufs[i]) + continue; + + if (q->bufs[i]->map != map) + continue; + + mem = q->bufs[i]->priv; + if (mem) { + /* This callback is called only if kernel has + allocated memory and this memory is mmapped. + In this case, memory should be freed, + in order to do memory unmap. + */ + + MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); + + /* vfree is not atomic - can't be + called with IRQ's disabled + */ + dev_dbg(map->q->dev, "buf[%d] freeing %p\n", + i, mem->vaddr); + + dt3155_free_buffer(q->dev, mem->size, + mem->vaddr, mem->dma_handle); + mem->vaddr = NULL; + } + + q->bufs[i]->map = NULL; + q->bufs[i]->baddr = 0; + } + + kfree(map); + + mutex_unlock(&q->vb_lock); + } +} + +static const struct vm_operations_struct dt3155_vm_ops = { + .open = dt3155_vm_open, + .close = dt3155_vm_close, +}; + +/* same as videobuf_mmap_mapper(), but allocates from the pool */ +static int +dt3155_mmap_mapper(struct videobuf_queue *q, struct vm_area_struct *vma) +{ + struct videobuf_dma_contig_memory *mem; + struct videobuf_mapping *map; + unsigned int first; + int retval; + unsigned long size, offset = vma->vm_pgoff << PAGE_SHIFT; + + dev_dbg(q->dev, "%s\n", __func__); + if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED)) + return -EINVAL; + + /* look for first buffer to map */ + for (first = 0; first < VIDEO_MAX_FRAME; first++) { + if (!q->bufs[first]) + continue; + + if (V4L2_MEMORY_MMAP != q->bufs[first]->memory) + continue; + if (q->bufs[first]->boff == offset) + break; + } + if (VIDEO_MAX_FRAME == first) { + dev_dbg(q->dev, "invalid user space offset [offset=0x%lx]\n", + offset); + return -EINVAL; + } + + /* create mapping + update buffer list */ + map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL); + if (!map) + return -ENOMEM; + + q->bufs[first]->map = map; + map->start = vma->vm_start; + map->end = vma->vm_end; + map->q = q; + + q->bufs[first]->baddr = vma->vm_start; + + mem = q->bufs[first]->priv; + BUG_ON(!mem); + MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); + + mem->size = PAGE_ALIGN(q->bufs[first]->bsize); + mem->vaddr = dt3155_alloc_buffer(q->dev, mem->size, + &mem->dma_handle, GFP_KERNEL); + if (!mem->vaddr) { + dev_err(q->dev, "dma_alloc_coherent size %ld failed\n", + mem->size); + goto error; + } + dev_dbg(q->dev, "dma_alloc_coherent data is at addr %p (size %ld)\n", + mem->vaddr, mem->size); + + /* Try to remap memory */ + + size = vma->vm_end - vma->vm_start; + size = (size < mem->size) ? size : mem->size; + + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + retval = remap_pfn_range(vma, vma->vm_start, + mem->dma_handle >> PAGE_SHIFT, + size, vma->vm_page_prot); + if (retval) { + dev_err(q->dev, "mmap: remap failed with error %d. ", retval); + dt3155_free_buffer(q->dev, mem->size, + mem->vaddr, mem->dma_handle); + goto error; + } + + vma->vm_ops = &dt3155_vm_ops; + vma->vm_flags |= VM_DONTEXPAND; + vma->vm_private_data = map; + + dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n", + map, q, vma->vm_start, vma->vm_end, + (long int) q->bufs[first]->bsize, + vma->vm_pgoff, first); + + dt3155_vm_open(vma); + + return 0; + +error: + kfree(map); + return -ENOMEM; +} + +static int +dt3155_sync_for_cpu(struct videobuf_queue *q, struct videobuf_buffer *vb) +{ + struct dt3155_priv *pd = q->priv_data; + struct videobuf_dma_contig_memory *mem = vb->priv; + + BUG_ON(!mem); + MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); + + pci_dma_sync_single_for_cpu(pd->pdev, mem->dma_handle, + mem->size, PCI_DMA_FROMDEVICE); + return 0; +} + +static int +dt3155_sync_for_device(struct videobuf_queue *q, struct videobuf_buffer *vb) +{ + struct dt3155_priv *pd = q->priv_data; + struct videobuf_dma_contig_memory *mem = vb->priv; + + BUG_ON(!mem); + MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); + + pci_dma_sync_single_for_device(pd->pdev, mem->dma_handle, + mem->size, PCI_DMA_FROMDEVICE); + return 0; +} + +/* + * same as videobuf_queue_dma_contig_init(), but after + * initialisation overwrites videobuf_iolock() and + * videobuf_mmap_mapper() with our customized versions + * as well as adds sync() method + */ +static void +dt3155_queue_dma_contig_init(struct videobuf_queue *q, + struct videobuf_queue_ops *ops, + struct device *dev, + spinlock_t *irqlock, + enum v4l2_buf_type type, + enum v4l2_field field, + unsigned int msize, + void *priv) +{ + videobuf_queue_dma_contig_init(q, ops, dev, irqlock, + type, field, msize, priv); + /* overwrite with our methods */ + q->int_ops->iolock = dt3155_iolock; + q->int_ops->mmap_mapper = dt3155_mmap_mapper; + q->int_ops->sync = dt3155_sync_for_cpu; +} + +static int +dt3155_start_acq(struct dt3155_priv *pd) +{ + struct videobuf_buffer *vb = pd->curr_buf; + dma_addr_t dma_addr; + + dma_addr = videobuf_to_dma_contig(vb); + iowrite32(dma_addr, pd->regs + EVEN_DMA_START); + iowrite32(dma_addr + vb->width, pd->regs + ODD_DMA_START); + iowrite32(vb->width, pd->regs + EVEN_DMA_STRIDE); + iowrite32(vb->width, pd->regs + ODD_DMA_STRIDE); + /* enable interrupts, clear all irq flags */ + iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START | + FLD_END_EVEN | FLD_END_ODD, pd->regs + INT_CSR); + iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN | + FLD_DN_ODD | FLD_DN_EVEN | CAP_CONT_EVEN | CAP_CONT_ODD, + pd->regs + CSR1); + wait_i2c_reg(pd->regs); + write_i2c_reg(pd->regs, CONFIG, pd->config); + write_i2c_reg(pd->regs, EVEN_CSR, CSR_ERROR | CSR_DONE); + write_i2c_reg(pd->regs, ODD_CSR, CSR_ERROR | CSR_DONE); + + /* start the board */ + write_i2c_reg(pd->regs, CSR2, pd->csr2 | BUSY_EVEN | BUSY_ODD); + return 0; /* success */ +} + +static int +dt3155_stop_acq(struct dt3155_priv *pd) +{ + int tmp; + + /* stop the board */ + wait_i2c_reg(pd->regs); + write_i2c_reg(pd->regs, CSR2, pd->csr2); + + /* disable all irqs, clear all irq flags */ + iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD, pd->regs + INT_CSR); + write_i2c_reg(pd->regs, EVEN_CSR, CSR_ERROR | CSR_DONE); + write_i2c_reg(pd->regs, ODD_CSR, CSR_ERROR | CSR_DONE); + tmp = ioread32(pd->regs + CSR1) & (FLD_CRPT_EVEN | FLD_CRPT_ODD); + if (tmp) + printk(KERN_ERR "dt3155: corrupted field %u\n", tmp); + iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN | + FLD_DN_ODD | FLD_DN_EVEN | CAP_CONT_EVEN | CAP_CONT_ODD, + pd->regs + CSR1); + return 0; +} + +/* Locking: Caller holds q->vb_lock */ +static int +dt3155_buf_setup(struct videobuf_queue *q, unsigned int *count, + unsigned int *size) +{ + *size = img_width * img_height; + return 0; +} + +/* Locking: Caller holds q->vb_lock */ +static int +dt3155_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, + enum v4l2_field field) +{ + int ret = 0; + + vb->width = img_width; + vb->height = img_height; + vb->size = img_width * img_height; + vb->field = field; + if (vb->state == VIDEOBUF_NEEDS_INIT) + ret = videobuf_iolock(q, vb, NULL); + if (ret) { + vb->state = VIDEOBUF_ERROR; + printk(KERN_ERR "ERROR: videobuf_iolock() failed\n"); + videobuf_dma_contig_free(q, vb); + } else + vb->state = VIDEOBUF_PREPARED; + return ret; +} + +/* Locking: Caller holds q->vb_lock & q->irqlock */ +static void +dt3155_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) +{ + struct dt3155_priv *pd = q->priv_data; + + if (vb->state != VIDEOBUF_NEEDS_INIT) { + vb->state = VIDEOBUF_QUEUED; + dt3155_sync_for_device(q, vb); + list_add_tail(&vb->queue, &pd->dmaq); + wake_up_interruptible_sync(&pd->do_dma); + } else + vb->state = VIDEOBUF_ERROR; +} + +/* Locking: Caller holds q->vb_lock */ +static void +dt3155_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb) +{ + if (vb->state == VIDEOBUF_ACTIVE) + videobuf_waiton(vb, 0, 0); /* FIXME: cannot be interrupted */ + dt3155_dma_contig_free(q, vb); + vb->state = VIDEOBUF_NEEDS_INIT; +} + +static struct videobuf_queue_ops vbq_ops = { + .buf_setup = dt3155_buf_setup, + .buf_prepare = dt3155_buf_prepare, + .buf_queue = dt3155_buf_queue, + .buf_release = dt3155_buf_release, +}; + +static irqreturn_t +dt3155_irq_handler_even(int irq, void *dev_id) +{ + struct dt3155_priv *ipd = dev_id; + struct videobuf_buffer *ivb; + dma_addr_t dma_addr; + u32 tmp; + + tmp = ioread32(ipd->regs + INT_CSR) & (FLD_START | FLD_END_ODD); + if (!tmp) + return IRQ_NONE; /* not our irq */ + if ((tmp & FLD_START) && !(tmp & FLD_END_ODD)) { + iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START, + ipd->regs + INT_CSR); + ipd->field_count++; + return IRQ_HANDLED; /* start of field irq */ + } + if ((tmp & FLD_START) && (tmp & FLD_END_ODD)) { + if (!ipd->stats.start_before_end++) + printk(KERN_ERR "dt3155: irq: START before END\n"); + } + /* check for corrupted fields */ +/* write_i2c_reg(ipd->regs, EVEN_CSR, CSR_ERROR | CSR_DONE); */ +/* write_i2c_reg(ipd->regs, ODD_CSR, CSR_ERROR | CSR_DONE); */ + tmp = ioread32(ipd->regs + CSR1) & (FLD_CRPT_EVEN | FLD_CRPT_ODD); + if (tmp) { + if (!ipd->stats.corrupted_fields++) + printk(KERN_ERR "dt3155: corrupted field %u\n", tmp); + iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN | + FLD_DN_ODD | FLD_DN_EVEN | + CAP_CONT_EVEN | CAP_CONT_ODD, + ipd->regs + CSR1); + mmiowb(); + } + + spin_lock(&ipd->lock); + if (ipd->curr_buf && ipd->curr_buf->state == VIDEOBUF_ACTIVE) { + if (waitqueue_active(&ipd->curr_buf->done)) { + do_gettimeofday(&ipd->curr_buf->ts); + ipd->curr_buf->field_count = ipd->field_count; + ipd->curr_buf->state = VIDEOBUF_DONE; + wake_up(&ipd->curr_buf->done); + } else { + ivb = ipd->curr_buf; + goto load_dma; + } + } else + goto stop_dma; + if (list_empty(&ipd->dmaq)) + goto stop_dma; + ivb = list_first_entry(&ipd->dmaq, typeof(*ivb), queue); + list_del(&ivb->queue); + if (ivb->state == VIDEOBUF_QUEUED) { + ivb->state = VIDEOBUF_ACTIVE; + ipd->curr_buf = ivb; + } else + goto stop_dma; +load_dma: + dma_addr = videobuf_to_dma_contig(ivb); + iowrite32(dma_addr, ipd->regs + EVEN_DMA_START); + iowrite32(dma_addr + ivb->width, ipd->regs + ODD_DMA_START); + iowrite32(ivb->width, ipd->regs + EVEN_DMA_STRIDE); + iowrite32(ivb->width, ipd->regs + ODD_DMA_STRIDE); + mmiowb(); + /* enable interrupts, clear all irq flags */ + iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START | + FLD_END_EVEN | FLD_END_ODD, ipd->regs + INT_CSR); + spin_unlock(&ipd->lock); + return IRQ_HANDLED; + +stop_dma: + ipd->curr_buf = NULL; + /* stop the board */ + write_i2c_reg_nowait(ipd->regs, CSR2, ipd->csr2); + /* disable interrupts, clear all irq flags */ + iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD, ipd->regs + INT_CSR); + spin_unlock(&ipd->lock); + return IRQ_HANDLED; +} + +static int +dt3155_threadfn(void *arg) +{ + struct dt3155_priv *pd = arg; + struct videobuf_buffer *vb; + unsigned long flags; + + while (1) { + wait_event_interruptible(pd->do_dma, + kthread_should_stop() || !list_empty(&pd->dmaq)); + if (kthread_should_stop()) + break; + + spin_lock_irqsave(&pd->lock, flags); + if (pd->curr_buf) /* dma is active */ + goto done; + if (list_empty(&pd->dmaq)) /* no empty biffers */ + goto done; + vb = list_first_entry(&pd->dmaq, typeof(*vb), queue); + list_del(&vb->queue); + if (vb->state == VIDEOBUF_QUEUED) { + vb->state = VIDEOBUF_ACTIVE; + pd->curr_buf = vb; + spin_unlock_irqrestore(&pd->lock, flags); + /* start dma */ + dt3155_start_acq(pd); + continue; + } else + printk(KERN_DEBUG "%s(): This is a BUG\n", __func__); +done: + spin_unlock_irqrestore(&pd->lock, flags); + } + return 0; +} + +static int +dt3155_open(struct file *filp) +{ + int ret = 0; + struct dt3155_priv *pd = video_drvdata(filp); + + printk(KERN_INFO "dt3155: open(): minor: %i\n", pd->vdev->minor); + + if (mutex_lock_interruptible(&pd->mux) == -EINTR) + return -ERESTARTSYS; + if (!pd->users) { + pd->vidq = kzalloc(sizeof(*pd->vidq), GFP_KERNEL); + if (!pd->vidq) { + printk(KERN_ERR "dt3155: error: alloc queue\n"); + ret = -ENOMEM; + goto err_alloc_queue; + } + dt3155_queue_dma_contig_init(pd->vidq, &vbq_ops, + &pd->pdev->dev, &pd->lock, + V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, + sizeof(struct videobuf_buffer), pd); + /* disable all irqs, clear all irq flags */ + iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD, + pd->regs + INT_CSR); + pd->irq_handler = dt3155_irq_handler_even; + ret = request_irq(pd->pdev->irq, pd->irq_handler, + IRQF_SHARED, DT3155_NAME, pd); + if (ret) { + printk(KERN_ERR "dt3155: error: request_irq\n"); + goto err_request_irq; + } + pd->curr_buf = NULL; + pd->thread = kthread_run(dt3155_threadfn, pd, + "dt3155_thread_%i", pd->vdev->minor); + if (IS_ERR(pd->thread)) { + printk(KERN_ERR "dt3155: kthread_run() failed\n"); + ret = PTR_ERR(pd->thread); + goto err_thread; + } + pd->field_count = 0; + } + pd->users++; + goto done; +err_thread: + free_irq(pd->pdev->irq, pd); +err_request_irq: + kfree(pd->vidq); + pd->vidq = NULL; +err_alloc_queue: +done: + mutex_unlock(&pd->mux); + return ret; +} + +static int +dt3155_release(struct file *filp) +{ + struct dt3155_priv *pd = video_drvdata(filp); + struct videobuf_buffer *tmp; + unsigned long flags; + int ret = 0; + + printk(KERN_INFO "dt3155: release(): minor: %i\n", pd->vdev->minor); + + if (mutex_lock_interruptible(&pd->mux) == -EINTR) + return -ERESTARTSYS; + pd->users--; + BUG_ON(pd->users < 0); + if (pd->acq_fp == filp) { + spin_lock_irqsave(&pd->lock, flags); + INIT_LIST_HEAD(&pd->dmaq); /* queue is emptied */ + tmp = pd->curr_buf; + spin_unlock_irqrestore(&pd->lock, flags); + if (tmp) + videobuf_waiton(tmp, 0, 1); /* block, interruptible */ + dt3155_stop_acq(pd); + videobuf_stop(pd->vidq); + pd->acq_fp = NULL; + } + if (!pd->users) { + kthread_stop(pd->thread); + free_irq(pd->pdev->irq, pd); + kfree(pd->vidq); + pd->vidq = NULL; + } + mutex_unlock(&pd->mux); + return ret; +} + +static ssize_t +dt3155_read(struct file *filp, char __user *user, size_t size, loff_t *loff) +{ + struct dt3155_priv *pd = video_drvdata(filp); + int ret; + + if (mutex_lock_interruptible(&pd->mux) == -EINTR) + return -ERESTARTSYS; + if (!pd->acq_fp) + pd->acq_fp = filp; + else if (pd->acq_fp != filp) { + ret = -EBUSY; + goto done; + } + ret = videobuf_read_stream(pd->vidq, user, size, loff, 0, + filp->f_flags & O_NONBLOCK); +done: + mutex_unlock(&pd->mux); + return ret; +} + +static unsigned int +dt3155_poll(struct file *filp, struct poll_table_struct *polltbl) +{ + struct dt3155_priv *pd = video_drvdata(filp); + + return videobuf_poll_stream(filp, pd->vidq, polltbl); +} + +static int +dt3155_mmap(struct file *filp, struct vm_area_struct *vma) +{ + struct dt3155_priv *pd = video_drvdata(filp); + + return videobuf_mmap_mapper(pd->vidq, vma); +} + +static const struct v4l2_file_operations dt3155_fops = { + .owner = THIS_MODULE, + .open = dt3155_open, + .release = dt3155_release, + .read = dt3155_read, + .poll = dt3155_poll, + .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */ + .mmap = dt3155_mmap, +}; + +static int +dt3155_ioc_streamon(struct file *filp, void *p, enum v4l2_buf_type type) +{ + struct dt3155_priv *pd = video_drvdata(filp); + int ret = -ERESTARTSYS; + + if (mutex_lock_interruptible(&pd->mux) == -EINTR) + return ret; + if (!pd->acq_fp) { + ret = videobuf_streamon(pd->vidq); + if (ret) + goto unlock; + pd->acq_fp = filp; + wake_up_interruptible_sync(&pd->do_dma); + } else if (pd->acq_fp == filp) { + ret = videobuf_streamon(pd->vidq); + if (!ret) + wake_up_interruptible_sync(&pd->do_dma); + } else + ret = -EBUSY; +unlock: + mutex_unlock(&pd->mux); + return ret; +} + +static int +dt3155_ioc_streamoff(struct file *filp, void *p, enum v4l2_buf_type type) +{ + struct dt3155_priv *pd = video_drvdata(filp); + struct videobuf_buffer *tmp; + unsigned long flags; + int ret; + + ret = videobuf_streamoff(pd->vidq); + if (ret) + return ret; + spin_lock_irqsave(&pd->lock, flags); + tmp = pd->curr_buf; + spin_unlock_irqrestore(&pd->lock, flags); + if (tmp) + videobuf_waiton(tmp, 0, 1); /* block, interruptible */ + return ret; +} + +static int +dt3155_ioc_querycap(struct file *filp, void *p, struct v4l2_capability *cap) +{ + struct dt3155_priv *pd = video_drvdata(filp); + + strcpy(cap->driver, DT3155_NAME); + strcpy(cap->card, DT3155_NAME " frame grabber"); + sprintf(cap->bus_info, "PCI:%s", pci_name(pd->pdev)); + cap->version = + KERNEL_VERSION(DT3155_VER_MAJ, DT3155_VER_MIN, DT3155_VER_EXT); + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | +#ifdef CONFIG_DT3155_STREAMING + V4L2_CAP_STREAMING; +#else + V4L2_CAP_READWRITE; +#endif + return 0; +} + +static int +dt3155_ioc_enum_fmt_vid_cap(struct file *filp, void *p, struct v4l2_fmtdesc *f) +{ + if (f->index >= NUM_OF_FORMATS) + return -EINVAL; + *f = frame_std[f->index]; + return 0; +} + +static int +dt3155_ioc_g_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f) +{ + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + f->fmt.pix.width = img_width; + f->fmt.pix.height = img_height; + f->fmt.pix.pixelformat = V4L2_PIX_FMT_GREY; + f->fmt.pix.field = V4L2_FIELD_NONE; + f->fmt.pix.bytesperline = f->fmt.pix.width; + f->fmt.pix.sizeimage = f->fmt.pix.width * f->fmt.pix.height; + f->fmt.pix.colorspace = 0; + f->fmt.pix.priv = 0; + return 0; +} + +static int +dt3155_ioc_try_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f) +{ + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (f->fmt.pix.width == img_width && + f->fmt.pix.height == img_height && + f->fmt.pix.pixelformat == V4L2_PIX_FMT_GREY && + f->fmt.pix.field == V4L2_FIELD_NONE && + f->fmt.pix.bytesperline == f->fmt.pix.width && + f->fmt.pix.sizeimage == f->fmt.pix.width * f->fmt.pix.height) + return 0; + else + return -EINVAL; +} + +static int +dt3155_ioc_s_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f) +{ + return dt3155_ioc_g_fmt_vid_cap(filp, p, f); +} + +static int +dt3155_ioc_reqbufs(struct file *filp, void *p, struct v4l2_requestbuffers *b) +{ + struct dt3155_priv *pd = video_drvdata(filp); + struct videobuf_queue *q = pd->vidq; + + if (b->memory != V4L2_MEMORY_MMAP) + return -EINVAL; + if (b->count) + return videobuf_reqbufs(q, b); + else { /* FIXME: is it necessary? */ + printk(KERN_DEBUG "dt3155: request to free buffers\n"); + return videobuf_mmap_free(q); + } +} + +static int +dt3155_ioc_querybuf(struct file *filp, void *p, struct v4l2_buffer *b) +{ + struct dt3155_priv *pd = video_drvdata(filp); + struct videobuf_queue *q = pd->vidq; + + return videobuf_querybuf(q, b); +} + +static int +dt3155_ioc_qbuf(struct file *filp, void *p, struct v4l2_buffer *b) +{ + struct dt3155_priv *pd = video_drvdata(filp); + struct videobuf_queue *q = pd->vidq; + + return videobuf_qbuf(q, b); +} + +static int +dt3155_ioc_dqbuf(struct file *filp, void *p, struct v4l2_buffer *b) +{ + struct dt3155_priv *pd = video_drvdata(filp); + struct videobuf_queue *q = pd->vidq; + + return videobuf_dqbuf(q, b, filp->f_flags & O_NONBLOCK); +} + +static int +dt3155_ioc_querystd(struct file *filp, void *p, v4l2_std_id *norm) +{ + *norm = DT3155_CURRENT_NORM; + return 0; +} + +static int +dt3155_ioc_g_std(struct file *filp, void *p, v4l2_std_id *norm) +{ + *norm = DT3155_CURRENT_NORM; + return 0; +} + +static int +dt3155_ioc_s_std(struct file *filp, void *p, v4l2_std_id *norm) +{ + if (*norm & DT3155_CURRENT_NORM) + return 0; + return -EINVAL; +} + +static int +dt3155_ioc_enum_input(struct file *filp, void *p, struct v4l2_input *input) +{ + if (input->index) + return -EINVAL; + strcpy(input->name, "Coax in"); + input->type = V4L2_INPUT_TYPE_CAMERA; + input->std = V4L2_STD_ALL; + input->status = 0;/* FIXME: add sync detection & V4L2_IN_ST_NO_H_LOCK */ + return 0; +} + +static int +dt3155_ioc_g_input(struct file *filp, void *p, unsigned int *i) +{ + *i = 0; + return 0; +} + +static int +dt3155_ioc_s_input(struct file *filp, void *p, unsigned int i) +{ + if (i) + return -EINVAL; + return 0; +} + +static int +dt3155_ioc_g_parm(struct file *filp, void *p, struct v4l2_streamparm *parms) +{ + if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + parms->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; + parms->parm.capture.capturemode = 0; + parms->parm.capture.timeperframe.numerator = 1001; + parms->parm.capture.timeperframe.denominator = frames_per_sec * 1000; + parms->parm.capture.extendedmode = 0; + parms->parm.capture.readbuffers = 1; + return 0; +} + +static int +dt3155_ioc_s_parm(struct file *filp, void *p, struct v4l2_streamparm *parms) +{ + if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + parms->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; + parms->parm.capture.capturemode = 0; + parms->parm.capture.timeperframe.numerator = 1001; + parms->parm.capture.timeperframe.denominator = frames_per_sec * 1000; + parms->parm.capture.extendedmode = 0; + parms->parm.capture.readbuffers = 1; + return 0; +} + +static const struct v4l2_ioctl_ops dt3155_ioctl_ops = { + .vidioc_streamon = dt3155_ioc_streamon, + .vidioc_streamoff = dt3155_ioc_streamoff, + .vidioc_querycap = dt3155_ioc_querycap, +/* + .vidioc_g_priority = dt3155_ioc_g_priority, + .vidioc_s_priority = dt3155_ioc_s_priority, +*/ + .vidioc_enum_fmt_vid_cap = dt3155_ioc_enum_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = dt3155_ioc_try_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = dt3155_ioc_g_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = dt3155_ioc_s_fmt_vid_cap, + .vidioc_reqbufs = dt3155_ioc_reqbufs, + .vidioc_querybuf = dt3155_ioc_querybuf, + .vidioc_qbuf = dt3155_ioc_qbuf, + .vidioc_dqbuf = dt3155_ioc_dqbuf, + .vidioc_querystd = dt3155_ioc_querystd, + .vidioc_g_std = dt3155_ioc_g_std, + .vidioc_s_std = dt3155_ioc_s_std, + .vidioc_enum_input = dt3155_ioc_enum_input, + .vidioc_g_input = dt3155_ioc_g_input, + .vidioc_s_input = dt3155_ioc_s_input, +/* + .vidioc_queryctrl = dt3155_ioc_queryctrl, + .vidioc_g_ctrl = dt3155_ioc_g_ctrl, + .vidioc_s_ctrl = dt3155_ioc_s_ctrl, + .vidioc_querymenu = dt3155_ioc_querymenu, + .vidioc_g_ext_ctrls = dt3155_ioc_g_ext_ctrls, + .vidioc_s_ext_ctrls = dt3155_ioc_s_ext_ctrls, +*/ + .vidioc_g_parm = dt3155_ioc_g_parm, + .vidioc_s_parm = dt3155_ioc_s_parm, +/* + .vidioc_cropcap = dt3155_ioc_cropcap, + .vidioc_g_crop = dt3155_ioc_g_crop, + .vidioc_s_crop = dt3155_ioc_s_crop, + .vidioc_enum_framesizes = dt3155_ioc_enum_framesizes, + .vidioc_enum_frameintervals = dt3155_ioc_enum_frameintervals, +#ifdef CONFIG_VIDEO_V4L1_COMPAT + .vidiocgmbuf = iocgmbuf, +#endif +*/ +}; + +static int __devinit +dt3155_init_board(struct pci_dev *dev) +{ + int i; + u8 tmp; + struct dt3155_buf *buf; + struct dt3155_priv *pd = pci_get_drvdata(dev); + pci_set_master(dev); /* dt3155 needs it */ + + /* resetting the adapter */ + iowrite32(FLD_CRPT_ODD | FLD_CRPT_EVEN | FLD_DN_ODD | FLD_DN_EVEN, + pd->regs + CSR1); + mmiowb(); + msleep(10); + + /* initializing adaper registers */ + iowrite32(FIFO_EN | SRST, pd->regs + CSR1); + mmiowb(); + iowrite32(0xEEEEEE01, pd->regs + EVEN_PIXEL_FMT); + iowrite32(0xEEEEEE01, pd->regs + ODD_PIXEL_FMT); + iowrite32(0x00000020, pd->regs + FIFO_TRIGER); + iowrite32(0x00000103, pd->regs + XFER_MODE); + iowrite32(0, pd->regs + RETRY_WAIT_CNT); + iowrite32(0, pd->regs + INT_CSR); + iowrite32(1, pd->regs + EVEN_FLD_MASK); + iowrite32(1, pd->regs + ODD_FLD_MASK); + iowrite32(0, pd->regs + MASK_LENGTH); + iowrite32(0x0005007C, pd->regs + FIFO_FLAG_CNT); + iowrite32(0x01010101, pd->regs + IIC_CLK_DUR); + mmiowb(); + + /* verifying that we have a DT3155 board (not just a SAA7116 chip) */ + read_i2c_reg(pd->regs, DT_ID, &tmp); + if (tmp != DT3155_ID) + return -ENODEV; + + /* initialize AD LUT */ + write_i2c_reg(pd->regs, AD_ADDR, 0); + for (i = 0; i < 256; i++) + write_i2c_reg(pd->regs, AD_LUT, i); + + /* initialize ADC references */ + /* FIXME: pos_ref & neg_ref depend on VT_50HZ */ + write_i2c_reg(pd->regs, AD_ADDR, AD_CMD_REG); + write_i2c_reg(pd->regs, AD_CMD, VIDEO_CNL_1 | SYNC_CNL_1 | SYNC_LVL_3); + write_i2c_reg(pd->regs, AD_ADDR, AD_POS_REF); + write_i2c_reg(pd->regs, AD_CMD, 34); + write_i2c_reg(pd->regs, AD_ADDR, AD_NEG_REF); + write_i2c_reg(pd->regs, AD_CMD, 0); + + /* initialize PM LUT */ + write_i2c_reg(pd->regs, CONFIG, pd->config | PM_LUT_PGM); + for (i = 0; i < 256; i++) { + write_i2c_reg(pd->regs, PM_LUT_ADDR, i); + write_i2c_reg(pd->regs, PM_LUT_DATA, i); + } + write_i2c_reg(pd->regs, CONFIG, pd->config | PM_LUT_PGM | PM_LUT_SEL); + for (i = 0; i < 256; i++) { + write_i2c_reg(pd->regs, PM_LUT_ADDR, i); + write_i2c_reg(pd->regs, PM_LUT_DATA, i); + } + write_i2c_reg(pd->regs, CONFIG, pd->config); /* ACQ_MODE_EVEN */ + + /* select chanel 1 for input and set sync level */ + write_i2c_reg(pd->regs, AD_ADDR, AD_CMD_REG); + write_i2c_reg(pd->regs, AD_CMD, VIDEO_CNL_1 | SYNC_CNL_1 | SYNC_LVL_3); + + /* allocate and pci_map memory, and initialize the DMA machine */ + buf = dt3155_get_buf(dt3155_free_bufs); + if (!buf) { + printk(KERN_ERR "dt3155: dt3155_get_buf " + "(in dt3155_init_board) failed\n"); + return -ENOMEM; + } + buf->dma = pci_map_single(dev, buf->cpu, + DT3155_BUF_SIZE, PCI_DMA_FROMDEVICE); + if (pci_dma_mapping_error(dev, buf->dma)) { + printk(KERN_ERR "dt3155: pci_map_single failed\n"); + dt3155_put_buf(buf, dt3155_free_bufs); + return -ENOMEM; + } + iowrite32(buf->dma, pd->regs + EVEN_DMA_START); + iowrite32(buf->dma, pd->regs + ODD_DMA_START); + iowrite32(0, pd->regs + EVEN_DMA_STRIDE); + iowrite32(0, pd->regs + ODD_DMA_STRIDE); + + /* Perform a pseudo even field acquire */ + iowrite32(FIFO_EN | SRST | CAP_CONT_ODD, pd->regs + CSR1); + write_i2c_reg(pd->regs, CSR2, pd->csr2 | SYNC_SNTL); + write_i2c_reg(pd->regs, CONFIG, pd->config); + write_i2c_reg(pd->regs, EVEN_CSR, CSR_SNGL); + write_i2c_reg(pd->regs, CSR2, pd->csr2 | BUSY_EVEN | SYNC_SNTL); + msleep(100); + read_i2c_reg(pd->regs, CSR2, &tmp); + write_i2c_reg(pd->regs, EVEN_CSR, CSR_ERROR | CSR_SNGL | CSR_DONE); + write_i2c_reg(pd->regs, ODD_CSR, CSR_ERROR | CSR_SNGL | CSR_DONE); + write_i2c_reg(pd->regs, CSR2, pd->csr2); + iowrite32(FIFO_EN | SRST | FLD_DN_EVEN | FLD_DN_ODD, pd->regs + CSR1); + + /* pci_unmap and deallocate memory */ + pci_unmap_single(dev, buf->dma, DT3155_BUF_SIZE, PCI_DMA_FROMDEVICE); + dt3155_put_buf(buf, dt3155_free_bufs); + if (tmp & BUSY_EVEN) { + printk(KERN_ERR "dt3155: BUSY_EVEN not cleared\n"); + return -EIO; + } + return 0; +} + +static struct video_device dt3155_vdev = { + .name = DT3155_NAME, + .fops = &dt3155_fops, + .ioctl_ops = &dt3155_ioctl_ops, + .minor = -1, + .release = video_device_release, + .tvnorms = V4L2_STD_ALL, + .current_norm = DT3155_CURRENT_NORM, +}; + +static int __devinit +dt3155_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + int err = -ENODEV; + struct dt3155_priv *pd; + + printk(KERN_INFO "dt3155: probe()\n"); + if (pci_set_dma_mask(dev, DMA_BIT_MASK(32))) { + printk(KERN_ERR "dt3155: cannot set dma_mask\n"); + return -ENODEV; + } + pd = kzalloc(sizeof(*pd), GFP_KERNEL); + if (!pd) { + printk(KERN_ERR "dt3155: cannot allocate dt3155_priv\n"); + return -ENOMEM; + } + pd->vdev = video_device_alloc(); + if (!pd->vdev) { + printk(KERN_ERR "dt3155: cannot allocate vdp structure\n"); + goto err_video_device_alloc; + } + *pd->vdev = dt3155_vdev; + pci_set_drvdata(dev, pd); /* for use in dt3155_remove() */ + video_set_drvdata(pd->vdev, pd); /* for use in video_fops */ + pd->users = 0; + pd->acq_fp = NULL; + pd->pdev = dev; + INIT_LIST_HEAD(&pd->dmaq); + init_waitqueue_head(&pd->do_dma); + mutex_init(&pd->mux); + pd->csr2 = csr2_init; + pd->config = config_init; + err = pci_enable_device(pd->pdev); + if (err) { + printk(KERN_ERR "dt3155: pci_dev not enabled\n"); + goto err_enable_dev; + } + err = pci_request_region(pd->pdev, 0, pci_name(pd->pdev)); + if (err) + goto err_req_region; + pd->regs = pci_iomap(pd->pdev, 0, pci_resource_len(pd->pdev, 0)); + if (!pd->regs) { + err = -ENOMEM; + printk(KERN_ERR "dt3155: pci_iomap failed\n"); + goto err_pci_iomap; + } + err = dt3155_init_board(pd->pdev); + if (err) { + printk(KERN_ERR "dt3155: dt3155_init_board failed\n"); + goto err_init_board; + } + err = video_register_device(pd->vdev, VFL_TYPE_GRABBER, -1); + if (err) { + printk(KERN_ERR "dt3155: Cannot register video device\n"); + goto err_init_board; + } + printk(KERN_INFO "dt3155: /dev/video%i is ready\n", pd->vdev->minor); + return 0; /* success */ + +err_init_board: + pci_iounmap(pd->pdev, pd->regs); +err_pci_iomap: + pci_release_region(pd->pdev, 0); +err_req_region: + pci_disable_device(pd->pdev); +err_enable_dev: + video_device_release(pd->vdev); +err_video_device_alloc: + kfree(pd); + return err; +} + +static void __devexit +dt3155_remove(struct pci_dev *dev) +{ + struct dt3155_priv *pd = pci_get_drvdata(dev); + + printk(KERN_INFO "dt3155: remove()\n"); + video_unregister_device(pd->vdev); + pci_iounmap(dev, pd->regs); + pci_release_region(pd->pdev, 0); + pci_disable_device(pd->pdev); + /* + * video_device_release() is invoked automatically + * see: struct video_device dt3155_vdev + */ + kfree(pd); +} + +static DEFINE_PCI_DEVICE_TABLE(pci_ids) = { + { PCI_DEVICE(DT3155_VENDOR_ID, DT3155_DEVICE_ID) }, + { 0, /* zero marks the end */ }, +}; +MODULE_DEVICE_TABLE(pci, pci_ids); + +static struct pci_driver pci_driver = { + .name = DT3155_NAME, + .id_table = pci_ids, + .probe = dt3155_probe, + .remove = __devexit_p(dt3155_remove), +}; + +static int __init +dt3155_init_module(void) +{ + int err; + + printk(KERN_INFO "dt3155: ==================\n"); + printk(KERN_INFO "dt3155: init()\n"); + dt3155_chunks = dt3155_init_chunks_fifo(); + if (!dt3155_chunks) { + err = -ENOMEM; + printk(KERN_ERR "dt3155: cannot init dt3155_chunks_fifo\n"); + goto err_init_chunks_fifo; + } + dt3155_free_bufs = dt3155_init_ibufs_fifo(dt3155_chunks, + DT3155_BUF_SIZE); + if (!dt3155_free_bufs) { + err = -ENOMEM; + printk(KERN_ERR "dt3155: cannot dt3155_init_ibufs_fifo\n"); + goto err_init_ibufs_fifo; + } + dt3155_alloc_bufs = dt3155_init_fifo(); + if (!dt3155_alloc_bufs) { + err = -ENOMEM; + printk(KERN_ERR "dt3155: cannot dt3155_init_fifo\n"); + goto err_init_fifo; + } + err = pci_register_driver(&pci_driver); + if (err) { + printk(KERN_ERR "dt3155: cannot register pci_driver\n"); + goto err_register_driver; + } + return 0; /* succes */ +err_register_driver: + dt3155_free_fifo(dt3155_alloc_bufs); +err_init_fifo: + dt3155_free_ibufs_fifo(dt3155_free_bufs); +err_init_ibufs_fifo: + dt3155_free_chunks_fifo(dt3155_chunks); +err_init_chunks_fifo: + return err; +} + +static void __exit +dt3155_exit_module(void) +{ + pci_unregister_driver(&pci_driver); + dt3155_free_fifo(dt3155_alloc_bufs); + dt3155_free_ibufs_fifo(dt3155_free_bufs); + dt3155_free_chunks_fifo(dt3155_chunks); + printk(KERN_INFO "dt3155: exit()\n"); + printk(KERN_INFO "dt3155: ==================\n"); +} + +module_init(dt3155_init_module); +module_exit(dt3155_exit_module); + +MODULE_DESCRIPTION("video4linux pci-driver for dt3155 frame grabber"); +MODULE_AUTHOR("Marin Mitov "); +MODULE_VERSION(DT3155_VERSION); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/dt3155v4l/dt3155v4l.h b/drivers/staging/dt3155v4l/dt3155v4l.h new file mode 100644 index 000000000000..e5c4ad05b180 --- /dev/null +++ b/drivers/staging/dt3155v4l/dt3155v4l.h @@ -0,0 +1,220 @@ +/*************************************************************************** + * Copyright (C) 2006-2010 by Marin Mitov * + * mitov@issp.bas.bg * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +/* DT3155 header file */ +#ifndef _DT3155_H_ +#define _DT3155_H_ + +#ifdef __KERNEL__ + +#include +#include + +#define DT3155_NAME "dt3155" +#define DT3155_VER_MAJ 1 +#define DT3155_VER_MIN 0 +#define DT3155_VER_EXT 2 +#define DT3155_VERSION __stringify(DT3155_VER_MAJ) "." \ + __stringify(DT3155_VER_MIN) "." \ + __stringify(DT3155_VER_EXT) + +/* DT3155 Base Register offsets (memory mapped) */ +#define EVEN_DMA_START 0x00 +#define ODD_DMA_START 0x0C +#define EVEN_DMA_STRIDE 0x18 +#define ODD_DMA_STRIDE 0x24 +#define EVEN_PIXEL_FMT 0x30 +#define ODD_PIXEL_FMT 0x34 +#define FIFO_TRIGER 0x38 +#define XFER_MODE 0x3C +#define CSR1 0x40 +#define RETRY_WAIT_CNT 0x44 +#define INT_CSR 0x48 +#define EVEN_FLD_MASK 0x4C +#define ODD_FLD_MASK 0x50 +#define MASK_LENGTH 0x54 +#define FIFO_FLAG_CNT 0x58 +#define IIC_CLK_DUR 0x5C +#define IIC_CSR1 0x60 +#define IIC_CSR2 0x64 + +/* DT3155 Internal Registers indexes (i2c/IIC mapped) */ +#define CSR2 0x10 +#define EVEN_CSR 0x11 +#define ODD_CSR 0x12 +#define CONFIG 0x13 +#define DT_ID 0x1F +#define X_CLIP_START 0x20 +#define Y_CLIP_START 0x22 +#define X_CLIP_END 0x24 +#define Y_CLIP_END 0x26 +#define AD_ADDR 0x30 +#define AD_LUT 0x31 +#define AD_CMD 0x32 +#define DIG_OUT 0x40 +#define PM_LUT_ADDR 0x50 +#define PM_LUT_DATA 0x51 + +/* AD command register values */ +#define AD_CMD_REG 0x00 +#define AD_POS_REF 0x01 +#define AD_NEG_REF 0x02 + +/* CSR1 bit masks */ +#define CRPT_DIS 0x00004000 +#define FLD_CRPT_ODD 0x00000200 +#define FLD_CRPT_EVEN 0x00000100 +#define FIFO_EN 0x00000080 +#define SRST 0x00000040 +#define FLD_DN_ODD 0x00000020 +#define FLD_DN_EVEN 0x00000010 +/* These should not be used. + * Use CAP_CONT_ODD/EVEN instead +#define CAP_SNGL_ODD 0x00000008 +#define CAP_SNGL_EVEN 0x00000004 +*/ +#define CAP_CONT_ODD 0x00000002 +#define CAP_CONT_EVEN 0x00000001 + +/* INT_CSR bit masks */ +#define FLD_START_EN 0x00000400 +#define FLD_END_ODD_EN 0x00000200 +#define FLD_END_EVEN_EN 0x00000100 +#define FLD_START 0x00000004 +#define FLD_END_ODD 0x00000002 +#define FLD_END_EVEN 0x00000001 + +/* IIC_CSR1 bit masks */ +#define DIRECT_ABORT 0x00000200 + +/* IIC_CSR2 bit masks */ +#define NEW_CYCLE 0x01000000 +#define DIR_RD 0x00010000 +#define IIC_READ 0x01010000 +#define IIC_WRITE 0x01000000 + +/* CSR2 bit masks */ +#define DISP_PASS 0x40 +#define BUSY_ODD 0x20 +#define BUSY_EVEN 0x10 +#define SYNC_PRESENT 0x08 +#define VT_50HZ 0x04 +#define SYNC_SNTL 0x02 +#define CHROM_FILT 0x01 +#define VT_60HZ 0x00 + +/* CSR_EVEN/ODD bit masks */ +#define CSR_ERROR 0x04 +#define CSR_SNGL 0x02 +#define CSR_DONE 0x01 + +/* CONFIG bit masks */ +#define PM_LUT_PGM 0x80 +#define PM_LUT_SEL 0x40 +#define CLIP_EN 0x20 +#define HSCALE_EN 0x10 +#define EXT_TRIG_UP 0x0C +#define EXT_TRIG_DOWN 0x04 +#define ACQ_MODE_NEXT 0x02 +#define ACQ_MODE_ODD 0x01 +#define ACQ_MODE_EVEN 0x00 + +/* AD_CMD bit masks */ +#define VIDEO_CNL_1 0x00 +#define VIDEO_CNL_2 0x40 +#define VIDEO_CNL_3 0x80 +#define VIDEO_CNL_4 0xC0 +#define SYNC_CNL_1 0x00 +#define SYNC_CNL_2 0x10 +#define SYNC_CNL_3 0x20 +#define SYNC_CNL_4 0x30 +#define SYNC_LVL_1 0x00 +#define SYNC_LVL_2 0x04 +#define SYNC_LVL_3 0x08 +#define SYNC_LVL_4 0x0C + +/* DT3155 identificator */ +#define DT3155_ID 0x20 + +#ifdef CONFIG_DT3155_CCIR +#define DMA_STRIDE 768 +#else +#define DMA_STRIDE 640 +#endif + +/** + * struct dt3155_stats - statistics structure + * + * @free_bufs_empty: no free image buffers + * @corrupted_fields: corrupted fields + * @dma_map_failed: dma mapping failed + * @start_before_end: new started before old ended + */ +struct dt3155_stats { + int free_bufs_empty; + int corrupted_fields; + int dma_map_failed; + int start_before_end; +}; + +/* per board private data structure */ +/** + * struct dt3155_priv - private data structure + * + * @vdev: pointer to video_device structure + * @acq_fp pointer to filp that starts acquisition + * @pdev: pointer to pci_dev structure + * @vidq pointer to videobuf_queue structure + * @curr_buf: pointer to curren buffer + * @thread pointer to worker thraed + * @irq_handler: irq handler for the driver + * @dmaq queue for dma buffers + * @do_dma wait queue of the kernel thread + * @mux: mutex to protect the instance + * @lock spinlock for videobuf queues + * @field_count fields counter + * @stats: statistics structure + * @users open count + * @regs: local copy of mmio base register + * @csr2: local copy of csr2 register + * @config: local copy of config register + */ +struct dt3155_priv { + struct video_device *vdev; + struct file *acq_fp; + struct pci_dev *pdev; + struct videobuf_queue *vidq; + struct videobuf_buffer *curr_buf; + struct task_struct *thread; + irq_handler_t irq_handler; + struct list_head dmaq; + wait_queue_head_t do_dma; + struct mutex mux; + spinlock_t lock; + unsigned int field_count; + struct dt3155_stats stats; + void *regs; + int users; + u8 csr2, config; +}; + +#endif /* __KERNEL__ */ + +#endif /* _DT3155_H_ */ -- cgit v1.2.3 From 11d91a4456bbc63d2b79ea5f16ffc31ae53cdf79 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 1 May 2010 10:59:23 -0700 Subject: Staging: dt3155v4l: add driver to the build The last patch forgot to add the driver to the Makefile, so it would not end up getting built. This resolves that issue. Cc: Marin Mitov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 23e353a411d7..e825647afda7 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -50,6 +50,7 @@ obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan/ obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/ obj-$(CONFIG_FB_SM7XX) += sm7xx/ obj-$(CONFIG_DT3155) += dt3155/ +obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/ obj-$(CONFIG_CRYSTALHD) += crystalhd/ obj-$(CONFIG_CXT1E1) += cxt1e1/ obj-$(CONFIG_TI_ST) += ti-st/ -- cgit v1.2.3 From 107c32fe68f0b64acb7edd31d44d79b87c7fa8b4 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Mon, 22 Mar 2010 22:46:13 +0100 Subject: Staging: batman-adv: don't have interrupts disabled while sending. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit send_vis_packets() would disable interrupts before calling dev_queue_xmit() which resulting in a backtrace in local_bh_enable(). Fix this by using kref on the vis_info object so that we can call send_vis_packets() without holding vis_hash_lock. vis_hash_lock also used to protect recv_list, so we now need a new lock to protect that instead of vis_hash_lock. Also a few checkpatch cleanups. Reported-by: Linus Lüssing Signed-off-by: Andrew Lunn Signed-off-by: Marek Lindner Signed-off-by: Simon Wunderlich Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/vis.c | 194 +++++++++++++++++++++++++++------------ drivers/staging/batman-adv/vis.h | 1 + 2 files changed, 137 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index fedec1bb3097..0b5c63fbb401 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -29,22 +29,26 @@ struct hashtable_t *vis_hash; DEFINE_SPINLOCK(vis_hash_lock); +static DEFINE_SPINLOCK(recv_list_lock); static struct vis_info *my_vis_info; static struct list_head send_list; /* always locked with vis_hash_lock */ static void start_vis_timer(void); /* free the info */ -static void free_info(void *data) +static void free_info(struct kref *ref) { - struct vis_info *info = data; + struct vis_info *info = container_of(ref, struct vis_info, refcount); struct recvlist_node *entry, *tmp; + unsigned long flags; list_del_init(&info->send_list); + spin_lock_irqsave(&recv_list_lock, flags); list_for_each_entry_safe(entry, tmp, &info->recv_list, list) { list_del(&entry->list); kfree(entry); } + spin_unlock_irqrestore(&recv_list_lock, flags); kfree(info); } @@ -142,36 +146,65 @@ void proc_vis_read_entry(struct seq_file *seq, } } +/* add the info packet to the send list, if it was not + * already linked in. */ +static void send_list_add(struct vis_info *info) +{ + if (list_empty(&info->send_list)) { + kref_get(&info->refcount); + list_add_tail(&info->send_list, &send_list); + } +} + +/* delete the info packet from the send list, if it was + * linked in. */ +static void send_list_del(struct vis_info *info) +{ + if (!list_empty(&info->send_list)) { + list_del_init(&info->send_list); + kref_put(&info->refcount, free_info); + } +} + /* tries to add one entry to the receive list. */ static void recv_list_add(struct list_head *recv_list, char *mac) { struct recvlist_node *entry; + unsigned long flags; + entry = kmalloc(sizeof(struct recvlist_node), GFP_ATOMIC); if (!entry) return; memcpy(entry->mac, mac, ETH_ALEN); + spin_lock_irqsave(&recv_list_lock, flags); list_add_tail(&entry->list, recv_list); + spin_unlock_irqrestore(&recv_list_lock, flags); } /* returns 1 if this mac is in the recv_list */ static int recv_list_is_in(struct list_head *recv_list, char *mac) { struct recvlist_node *entry; + unsigned long flags; + spin_lock_irqsave(&recv_list_lock, flags); list_for_each_entry(entry, recv_list, list) { - if (memcmp(entry->mac, mac, ETH_ALEN) == 0) + if (memcmp(entry->mac, mac, ETH_ALEN) == 0) { + spin_unlock_irqrestore(&recv_list_lock, flags); return 1; + } } - + spin_unlock_irqrestore(&recv_list_lock, flags); return 0; } /* try to add the packet to the vis_hash. return NULL if invalid (e.g. too old, - * broken.. ). vis hash must be locked outside. is_new is set when the packet + * broken.. ). vis hash must be locked outside. is_new is set when the packet * is newer than old entries in the hash. */ static struct vis_info *add_packet(struct vis_packet *vis_packet, - int vis_info_len, int *is_new) + int vis_info_len, int *is_new, + int make_broadcast) { struct vis_info *info, *old_info; struct vis_info search_elem; @@ -198,13 +231,15 @@ static struct vis_info *add_packet(struct vis_packet *vis_packet, } /* remove old entry */ hash_remove(vis_hash, old_info); - free_info(old_info); + send_list_del(old_info); + kref_put(&old_info->refcount, free_info); } info = kmalloc(sizeof(struct vis_info) + vis_info_len, GFP_ATOMIC); if (info == NULL) return NULL; + kref_init(&info->refcount); INIT_LIST_HEAD(&info->send_list); INIT_LIST_HEAD(&info->recv_list); info->first_seen = jiffies; @@ -214,16 +249,21 @@ static struct vis_info *add_packet(struct vis_packet *vis_packet, /* initialize and add new packet. */ *is_new = 1; + /* Make it a broadcast packet, if required */ + if (make_broadcast) + memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); + /* repair if entries is longer than packet. */ if (info->packet.entries * sizeof(struct vis_info_entry) > vis_info_len) - info->packet.entries = vis_info_len / sizeof(struct vis_info_entry); + info->packet.entries = vis_info_len / + sizeof(struct vis_info_entry); recv_list_add(&info->recv_list, info->packet.sender_orig); /* try to add it */ if (hash_add(vis_hash, info) < 0) { /* did not work (for some reason) */ - free_info(info); + kref_put(&old_info->refcount, free_info); info = NULL; } @@ -234,22 +274,21 @@ static struct vis_info *add_packet(struct vis_packet *vis_packet, void receive_server_sync_packet(struct vis_packet *vis_packet, int vis_info_len) { struct vis_info *info; - int is_new; + int is_new, make_broadcast; unsigned long flags; int vis_server = atomic_read(&vis_mode); + make_broadcast = (vis_server == VIS_TYPE_SERVER_SYNC); + spin_lock_irqsave(&vis_hash_lock, flags); - info = add_packet(vis_packet, vis_info_len, &is_new); + info = add_packet(vis_packet, vis_info_len, &is_new, make_broadcast); if (info == NULL) goto end; /* only if we are server ourselves and packet is newer than the one in * hash.*/ - if (vis_server == VIS_TYPE_SERVER_SYNC && is_new) { - memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); - if (list_empty(&info->send_list)) - list_add_tail(&info->send_list, &send_list); - } + if (vis_server == VIS_TYPE_SERVER_SYNC && is_new) + send_list_add(info); end: spin_unlock_irqrestore(&vis_hash_lock, flags); } @@ -262,31 +301,32 @@ void receive_client_update_packet(struct vis_packet *vis_packet, int is_new; unsigned long flags; int vis_server = atomic_read(&vis_mode); + int are_target = 0; /* clients shall not broadcast. */ if (is_bcast(vis_packet->target_orig)) return; + /* Are we the target for this VIS packet? */ + if (vis_server == VIS_TYPE_SERVER_SYNC && + is_my_mac(vis_packet->target_orig)) + are_target = 1; + spin_lock_irqsave(&vis_hash_lock, flags); - info = add_packet(vis_packet, vis_info_len, &is_new); + info = add_packet(vis_packet, vis_info_len, &is_new, are_target); if (info == NULL) goto end; /* note that outdated packets will be dropped at this point. */ /* send only if we're the target server or ... */ - if (vis_server == VIS_TYPE_SERVER_SYNC && - is_my_mac(info->packet.target_orig) && - is_new) { + if (are_target && is_new) { info->packet.vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */ - memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); - if (list_empty(&info->send_list)) - list_add_tail(&info->send_list, &send_list); + send_list_add(info); /* ... we're not the recipient (and thus need to forward). */ } else if (!is_my_mac(info->packet.target_orig)) { - if (list_empty(&info->send_list)) - list_add_tail(&info->send_list, &send_list); + send_list_add(info); } end: spin_unlock_irqrestore(&vis_hash_lock, flags); @@ -361,14 +401,17 @@ static int generate_vis_packet(void) while (hash_iterate(orig_hash, &hashit_global)) { orig_node = hashit_global.bucket->data; if (orig_node->router != NULL - && compare_orig(orig_node->router->addr, orig_node->orig) + && compare_orig(orig_node->router->addr, + orig_node->orig) && orig_node->batman_if && (orig_node->batman_if->if_active == IF_ACTIVE) && orig_node->router->tq_avg > 0) { /* fill one entry into buffer. */ entry = &entry_array[info->packet.entries]; - memcpy(entry->src, orig_node->batman_if->net_dev->dev_addr, ETH_ALEN); + memcpy(entry->src, + orig_node->batman_if->net_dev->dev_addr, + ETH_ALEN); memcpy(entry->dest, orig_node->orig, ETH_ALEN); entry->quality = orig_node->router->tq_avg; info->packet.entries++; @@ -400,6 +443,8 @@ static int generate_vis_packet(void) return 0; } +/* free old vis packets. Must be called with this vis_hash_lock + * held */ static void purge_vis_packets(void) { HASHIT(hashit); @@ -412,7 +457,8 @@ static void purge_vis_packets(void) if (time_after(jiffies, info->first_seen + (VIS_TIMEOUT*HZ)/1000)) { hash_remove_bucket(vis_hash, &hashit); - free_info(info); + send_list_del(info); + kref_put(&info->refcount, free_info); } } } @@ -422,6 +468,8 @@ static void broadcast_vis_packet(struct vis_info *info, int packet_length) HASHIT(hashit); struct orig_node *orig_node; unsigned long flags; + struct batman_if *batman_if; + uint8_t dstaddr[ETH_ALEN]; spin_lock_irqsave(&orig_hash_lock, flags); @@ -430,45 +478,56 @@ static void broadcast_vis_packet(struct vis_info *info, int packet_length) orig_node = hashit.bucket->data; /* if it's a vis server and reachable, send it. */ - if (orig_node && - (orig_node->flags & VIS_SERVER) && - orig_node->batman_if && - orig_node->router) { + if ((!orig_node) || (!orig_node->batman_if) || + (!orig_node->router)) + continue; + if (!(orig_node->flags & VIS_SERVER)) + continue; + /* don't send it if we already received the packet from + * this node. */ + if (recv_list_is_in(&info->recv_list, orig_node->orig)) + continue; - /* don't send it if we already received the packet from - * this node. */ - if (recv_list_is_in(&info->recv_list, orig_node->orig)) - continue; + memcpy(info->packet.target_orig, orig_node->orig, ETH_ALEN); + batman_if = orig_node->batman_if; + memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); + spin_unlock_irqrestore(&orig_hash_lock, flags); - memcpy(info->packet.target_orig, - orig_node->orig, ETH_ALEN); + send_raw_packet((unsigned char *)&info->packet, + packet_length, batman_if, dstaddr); + + spin_lock_irqsave(&orig_hash_lock, flags); - send_raw_packet((unsigned char *) &info->packet, - packet_length, - orig_node->batman_if, - orig_node->router->addr); - } } - memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); spin_unlock_irqrestore(&orig_hash_lock, flags); + memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); } static void unicast_vis_packet(struct vis_info *info, int packet_length) { struct orig_node *orig_node; unsigned long flags; + struct batman_if *batman_if; + uint8_t dstaddr[ETH_ALEN]; spin_lock_irqsave(&orig_hash_lock, flags); orig_node = ((struct orig_node *) hash_find(orig_hash, info->packet.target_orig)); - if ((orig_node != NULL) && - (orig_node->batman_if != NULL) && - (orig_node->router != NULL)) { - send_raw_packet((unsigned char *) &info->packet, packet_length, - orig_node->batman_if, - orig_node->router->addr); - } + if ((!orig_node) || (!orig_node->batman_if) || (!orig_node->router)) + goto out; + + /* don't lock while sending the packets ... we therefore + * copy the required data before sending */ + batman_if = orig_node->batman_if; + memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); + spin_unlock_irqrestore(&orig_hash_lock, flags); + + send_raw_packet((unsigned char *)&info->packet, + packet_length, batman_if, dstaddr); + return; + +out: spin_unlock_irqrestore(&orig_hash_lock, flags); } @@ -502,15 +561,24 @@ static void send_vis_packets(struct work_struct *work) unsigned long flags; spin_lock_irqsave(&vis_hash_lock, flags); + purge_vis_packets(); - if (generate_vis_packet() == 0) + if (generate_vis_packet() == 0) { /* schedule if generation was successful */ - list_add_tail(&my_vis_info->send_list, &send_list); + send_list_add(my_vis_info); + } list_for_each_entry_safe(info, temp, &send_list, send_list) { - list_del_init(&info->send_list); + + kref_get(&info->refcount); + spin_unlock_irqrestore(&vis_hash_lock, flags); + send_vis_packet(info); + + spin_lock_irqsave(&vis_hash_lock, flags); + send_list_del(info); + kref_put(&info->refcount, free_info); } spin_unlock_irqrestore(&vis_hash_lock, flags); start_vis_timer(); @@ -543,6 +611,7 @@ int vis_init(void) my_vis_info->first_seen = jiffies - atomic_read(&vis_interval); INIT_LIST_HEAD(&my_vis_info->recv_list); INIT_LIST_HEAD(&my_vis_info->send_list); + kref_init(&my_vis_info->refcount); my_vis_info->packet.version = COMPAT_VERSION; my_vis_info->packet.packet_type = BAT_VIS; my_vis_info->packet.ttl = TTL; @@ -556,9 +625,9 @@ int vis_init(void) if (hash_add(vis_hash, my_vis_info) < 0) { printk(KERN_ERR - "batman-adv:Can't add own vis packet into hash\n"); - free_info(my_vis_info); /* not in hash, need to remove it - * manually. */ + "batman-adv:Can't add own vis packet into hash\n"); + /* not in hash, need to remove it manually. */ + kref_put(&my_vis_info->refcount, free_info); goto err; } @@ -572,6 +641,15 @@ err: return 0; } +/* Decrease the reference count on a hash item info */ +static void free_info_ref(void *data) +{ + struct vis_info *info = data; + + send_list_del(info); + kref_put(&info->refcount, free_info); +} + /* shutdown vis-server */ void vis_quit(void) { @@ -583,7 +661,7 @@ void vis_quit(void) spin_lock_irqsave(&vis_hash_lock, flags); /* properly remove, kill timers ... */ - hash_delete(vis_hash, free_info); + hash_delete(vis_hash, free_info_ref); vis_hash = NULL; my_vis_info = NULL; spin_unlock_irqrestore(&vis_hash_lock, flags); diff --git a/drivers/staging/batman-adv/vis.h b/drivers/staging/batman-adv/vis.h index 0cdafde0ec3a..465da4765cee 100644 --- a/drivers/staging/batman-adv/vis.h +++ b/drivers/staging/batman-adv/vis.h @@ -29,6 +29,7 @@ struct vis_info { /* list of server-neighbors we received a vis-packet * from. we should not reply to them. */ struct list_head send_list; + struct kref refcount; /* this packet might be part of the vis send queue. */ struct vis_packet packet; /* vis_info may follow here*/ -- cgit v1.2.3 From f6497e38fda6970819daacb67725d67474079381 Mon Sep 17 00:00:00 2001 From: Linus Lüssing Date: Mon, 22 Mar 2010 22:46:14 +0100 Subject: Staging: batman-adv: Fix VIS output bug for secondary interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TQ and HNA records for originators on secondary interfaces were wrongly being included on the primary interface. Ensure we output a line for each source interface on every node, so we correctly separate primary and secondary interface records. Signed-off-by: Linus Lüssing Signed-off-by: Andrew Lunn Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/proc.c | 51 +++++++++++++++++++++++++++------------ drivers/staging/batman-adv/vis.c | 25 +++++++------------ drivers/staging/batman-adv/vis.h | 7 ++++-- 3 files changed, 49 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/proc.c b/drivers/staging/batman-adv/proc.c index 7de60e84bc96..c9366bcbb360 100644 --- a/drivers/staging/batman-adv/proc.c +++ b/drivers/staging/batman-adv/proc.c @@ -41,7 +41,7 @@ static int proc_interfaces_read(struct seq_file *seq, void *offset) rcu_read_lock(); list_for_each_entry_rcu(batman_if, &if_list, list) { - seq_printf(seq, "[%8s] %s %s \n", + seq_printf(seq, "[%8s] %s %s\n", (batman_if->if_active == IF_ACTIVE ? "active" : "inactive"), batman_if->dev, @@ -188,18 +188,18 @@ static int proc_originators_read(struct seq_file *seq, void *offset) rcu_read_lock(); if (list_empty(&if_list)) { rcu_read_unlock(); - seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it \n"); + seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it\n"); goto end; } if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) { rcu_read_unlock(); - seq_printf(seq, "BATMAN disabled - primary interface not active \n"); + seq_printf(seq, "BATMAN disabled - primary interface not active\n"); goto end; } seq_printf(seq, - " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s] \n", + " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s]\n", "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF", "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR, ((struct batman_if *)if_list.next)->dev, @@ -240,7 +240,7 @@ static int proc_originators_read(struct seq_file *seq, void *offset) spin_unlock_irqrestore(&orig_hash_lock, flags); if (batman_count == 0) - seq_printf(seq, "No batman nodes in range ... \n"); + seq_printf(seq, "No batman nodes in range ...\n"); end: return 0; @@ -262,7 +262,7 @@ static int proc_transt_local_read(struct seq_file *seq, void *offset) rcu_read_lock(); if (list_empty(&if_list)) { rcu_read_unlock(); - seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it \n"); + seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it\n"); goto end; } @@ -294,7 +294,7 @@ static int proc_transt_global_read(struct seq_file *seq, void *offset) rcu_read_lock(); if (list_empty(&if_list)) { rcu_read_unlock(); - seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it \n"); + seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it\n"); goto end; } rcu_read_unlock(); @@ -350,9 +350,9 @@ static int proc_vis_srv_read(struct seq_file *seq, void *offset) { int vis_server = atomic_read(&vis_mode); - seq_printf(seq, "[%c] client mode (server disabled) \n", + seq_printf(seq, "[%c] client mode (server disabled)\n", (vis_server == VIS_TYPE_CLIENT_UPDATE) ? 'x' : ' '); - seq_printf(seq, "[%c] server mode (server enabled) \n", + seq_printf(seq, "[%c] server mode (server enabled)\n", (vis_server == VIS_TYPE_SERVER_SYNC) ? 'x' : ' '); return 0; @@ -369,6 +369,8 @@ static int proc_vis_data_read(struct seq_file *seq, void *offset) struct vis_info *info; struct vis_info_entry *entries; HLIST_HEAD(vis_if_list); + struct if_list_entry *entry; + struct hlist_node *pos, *n; int i; char tmp_addr_str[ETH_STR_LEN]; unsigned long flags; @@ -387,17 +389,34 @@ static int proc_vis_data_read(struct seq_file *seq, void *offset) info = hashit.bucket->data; entries = (struct vis_info_entry *) ((char *)info + sizeof(struct vis_info)); - addr_to_string(tmp_addr_str, info->packet.vis_orig); - seq_printf(seq, "%s,", tmp_addr_str); for (i = 0; i < info->packet.entries; i++) { - proc_vis_read_entry(seq, &entries[i], &vis_if_list, - info->packet.vis_orig); + if (entries[i].quality == 0) + continue; + proc_vis_insert_interface(entries[i].src, &vis_if_list, + compare_orig(entries[i].src, + info->packet.vis_orig)); } - /* add primary/secondary records */ - proc_vis_read_prim_sec(seq, &vis_if_list); - seq_printf(seq, "\n"); + hlist_for_each_entry(entry, pos, &vis_if_list, list) { + addr_to_string(tmp_addr_str, entry->addr); + seq_printf(seq, "%s,", tmp_addr_str); + + for (i = 0; i < info->packet.entries; i++) + proc_vis_read_entry(seq, &entries[i], + entry->addr, entry->primary); + + /* add primary/secondary records */ + if (compare_orig(entry->addr, info->packet.vis_orig)) + proc_vis_read_prim_sec(seq, &vis_if_list); + + seq_printf(seq, "\n"); + } + + hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) { + hlist_del(&entry->list); + kfree(entry); + } } spin_unlock_irqrestore(&vis_hash_lock, flags); diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index 0b5c63fbb401..222db0189a6d 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -86,7 +86,7 @@ static int vis_info_choose(void *data, int size) /* insert interface to the list of interfaces of one originator, if it * does not already exist in the list */ -static void proc_vis_insert_interface(const uint8_t *interface, +void proc_vis_insert_interface(const uint8_t *interface, struct hlist_head *if_list, bool primary) { @@ -111,39 +111,32 @@ void proc_vis_read_prim_sec(struct seq_file *seq, struct hlist_head *if_list) { struct if_list_entry *entry; - struct hlist_node *pos, *n; + struct hlist_node *pos; char tmp_addr_str[ETH_STR_LEN]; - hlist_for_each_entry_safe(entry, pos, n, if_list, list) { - if (entry->primary) { + hlist_for_each_entry(entry, pos, if_list, list) { + if (entry->primary) seq_printf(seq, "PRIMARY, "); - } else { + else { addr_to_string(tmp_addr_str, entry->addr); seq_printf(seq, "SEC %s, ", tmp_addr_str); } - - hlist_del(&entry->list); - kfree(entry); } } /* read an entry */ void proc_vis_read_entry(struct seq_file *seq, struct vis_info_entry *entry, - struct hlist_head *if_list, - uint8_t *vis_orig) + uint8_t *src, + bool primary) { char to[40]; addr_to_string(to, entry->dest); - if (entry->quality == 0) { - proc_vis_insert_interface(vis_orig, if_list, true); + if (primary && entry->quality == 0) seq_printf(seq, "HNA %s, ", to); - } else { - proc_vis_insert_interface(entry->src, if_list, - compare_orig(entry->src, vis_orig)); + else if (compare_orig(entry->src, src)) seq_printf(seq, "TQ %s %d, ", to, entry->quality); - } } /* add the info packet to the send list, if it was not diff --git a/drivers/staging/batman-adv/vis.h b/drivers/staging/batman-adv/vis.h index 465da4765cee..a1f92a4b101d 100644 --- a/drivers/staging/batman-adv/vis.h +++ b/drivers/staging/batman-adv/vis.h @@ -49,10 +49,13 @@ struct recvlist_node { extern struct hashtable_t *vis_hash; extern spinlock_t vis_hash_lock; +void proc_vis_insert_interface(const uint8_t *interface, + struct hlist_head *if_list, + bool primary); void proc_vis_read_entry(struct seq_file *seq, struct vis_info_entry *entry, - struct hlist_head *if_list, - uint8_t *vis_orig); + uint8_t *src, + bool primary); void proc_vis_read_prim_sec(struct seq_file *seq, struct hlist_head *if_list); void receive_server_sync_packet(struct vis_packet *vis_packet, -- cgit v1.2.3 From ea4ceb18b525fd7016c10995c0f1313a729c7e2b Mon Sep 17 00:00:00 2001 From: Linus Lüssing Date: Mon, 22 Mar 2010 22:46:15 +0100 Subject: Staging: batman-adv: Fixing wrap-around bug in vis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the seqno for a vis packet had a wrap around from i.e. 255 to 0, add_packet() would falsely claim the older packet with the seqno 255 as newer as the one with the seqno of 0 and would therefore ignore the new packet. This happens with all following vis packets until the old vis packet expires after 180 seconds timeout. This patch fixes this issue and gets rid of these highly undesired 3min. breaks for the vis-server. Signed-off-by: Linus Lüssing Signed-off-by: Sven Eckelmann Signed-off-by: Andrew Lunn Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/vis.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index 222db0189a6d..28eac7e05235 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -27,6 +27,22 @@ #include "hard-interface.h" #include "hash.h" +/* Returns the smallest signed integer in two's complement with the sizeof x */ +#define smallest_signed_int(x) (1u << (7u + 8u * (sizeof(x) - 1u))) + +/* Checks if a sequence number x is a predecessor/successor of y. + they handle overflows/underflows and can correctly check for a + predecessor/successor unless the variable sequence number has grown by + more then 2**(bitwidth(x)-1)-1. + This means that for a uint8_t with the maximum value 255, it would think: + * when adding nothing - it is neither a predecessor nor a successor + * before adding more than 127 to the starting value - it is a predecessor, + * when adding 128 - it is neither a predecessor nor a successor, + * after adding more than 127 to the starting value - it is a successor */ +#define seq_before(x, y) ({typeof(x) _dummy = (x - y); \ + _dummy > smallest_signed_int(_dummy); }) +#define seq_after(x, y) seq_before(y, x) + struct hashtable_t *vis_hash; DEFINE_SPINLOCK(vis_hash_lock); static DEFINE_SPINLOCK(recv_list_lock); @@ -212,7 +228,7 @@ static struct vis_info *add_packet(struct vis_packet *vis_packet, old_info = hash_find(vis_hash, &search_elem); if (old_info != NULL) { - if (vis_packet->seqno - old_info->packet.seqno <= 0) { + if (!seq_after(vis_packet->seqno, old_info->packet.seqno)) { if (old_info->packet.seqno == vis_packet->seqno) { recv_list_add(&old_info->recv_list, vis_packet->sender_orig); -- cgit v1.2.3 From d20cf2feafa38edfcb9e7c98898b006c5fffd62e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 1 May 2010 11:43:32 -0700 Subject: Staging: comedi: comedi_ksysms: remove commented out symbols These aren't needed, they are commented out, so remove them. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_ksyms.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_ksyms.c b/drivers/staging/comedi/comedi_ksyms.c index 87803e69a149..6ebfbf30a990 100644 --- a/drivers/staging/comedi/comedi_ksyms.c +++ b/drivers/staging/comedi/comedi_ksyms.c @@ -28,12 +28,7 @@ /* for drivers */ EXPORT_SYMBOL(comedi_driver_register); EXPORT_SYMBOL(comedi_driver_unregister); -/* EXPORT_SYMBOL(comedi_bufcheck); */ -/* EXPORT_SYMBOL(comedi_done); */ -/* EXPORT_SYMBOL(comedi_error_done); */ EXPORT_SYMBOL(comedi_error); -/* EXPORT_SYMBOL(comedi_eobuf); */ -/* EXPORT_SYMBOL(comedi_eos); */ EXPORT_SYMBOL(comedi_event); EXPORT_SYMBOL(comedi_get_subdevice_runflags); EXPORT_SYMBOL(comedi_set_subdevice_runflags); -- cgit v1.2.3 From d58214b0b8662f1b27d538390ecc49bbea0cd754 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 1 May 2010 11:54:07 -0700 Subject: Staging: comedi: move a bunch of EXPORT_SYMBOL lines Move the ones that are needed to be in drivers.c into the file. This is with the goal of deleting the comedi_ksyms.c file. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_ksyms.c | 13 ------------- drivers/staging/comedi/drivers.c | 12 ++++++++++++ 2 files changed, 12 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_ksyms.c b/drivers/staging/comedi/comedi_ksyms.c index 6ebfbf30a990..c0e53bc269c0 100644 --- a/drivers/staging/comedi/comedi_ksyms.c +++ b/drivers/staging/comedi/comedi_ksyms.c @@ -26,8 +26,6 @@ #include "comedidev.h" /* for drivers */ -EXPORT_SYMBOL(comedi_driver_register); -EXPORT_SYMBOL(comedi_driver_unregister); EXPORT_SYMBOL(comedi_error); EXPORT_SYMBOL(comedi_event); EXPORT_SYMBOL(comedi_get_subdevice_runflags); @@ -51,14 +49,3 @@ EXPORT_SYMBOL_GPL(comedi_usb_auto_unconfig); /* for kcomedilib */ EXPORT_SYMBOL(check_chanlist); EXPORT_SYMBOL_GPL(comedi_get_device_file_info); - -EXPORT_SYMBOL(comedi_buf_put); -EXPORT_SYMBOL(comedi_buf_get); -EXPORT_SYMBOL(comedi_buf_read_n_available); -EXPORT_SYMBOL(comedi_buf_write_free); -EXPORT_SYMBOL(comedi_buf_write_alloc); -EXPORT_SYMBOL(comedi_buf_read_free); -EXPORT_SYMBOL(comedi_buf_read_alloc); -EXPORT_SYMBOL(comedi_buf_memcpy_to); -EXPORT_SYMBOL(comedi_buf_memcpy_from); -EXPORT_SYMBOL(comedi_reset_async_buf); diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 800106ae9901..2b7eda501809 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -188,6 +188,7 @@ int comedi_driver_register(struct comedi_driver *driver) return 0; } +EXPORT_SYMBOL(comedi_driver_register); int comedi_driver_unregister(struct comedi_driver *driver) { @@ -228,6 +229,7 @@ int comedi_driver_unregister(struct comedi_driver *driver) } return -EINVAL; } +EXPORT_SYMBOL(comedi_driver_unregister); static int postconfig(struct comedi_device *dev) { @@ -621,6 +623,7 @@ unsigned int comedi_buf_write_alloc(struct comedi_async *async, smp_mb(); return nbytes; } +EXPORT_SYMBOL(comedi_buf_write_alloc); /* allocates nothing unless it can completely fulfill the request */ unsigned int comedi_buf_write_alloc_strict(struct comedi_async *async, @@ -655,6 +658,7 @@ unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes) return nbytes; } +EXPORT_SYMBOL(comedi_buf_write_free); /* allocates a chunk for the reader from filled (and munged) buffer space */ unsigned comedi_buf_read_alloc(struct comedi_async *async, unsigned nbytes) @@ -669,6 +673,7 @@ unsigned comedi_buf_read_alloc(struct comedi_async *async, unsigned nbytes) smp_rmb(); return nbytes; } +EXPORT_SYMBOL(comedi_buf_read_alloc); /* transfers control of a chunk from reader to free buffer space */ unsigned comedi_buf_read_free(struct comedi_async *async, unsigned int nbytes) @@ -687,6 +692,7 @@ unsigned comedi_buf_read_free(struct comedi_async *async, unsigned int nbytes) async->buf_read_ptr %= async->prealloc_bufsz; return nbytes; } +EXPORT_SYMBOL(comedi_buf_read_free); void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset, const void *data, unsigned int num_bytes) @@ -712,6 +718,7 @@ void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset, write_ptr = 0; } } +EXPORT_SYMBOL(comedi_buf_memcpy_to); void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset, void *dest, unsigned int nbytes) @@ -738,6 +745,7 @@ void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset, read_ptr = 0; } } +EXPORT_SYMBOL(comedi_buf_memcpy_from); unsigned int comedi_buf_read_n_available(struct comedi_async *async) { @@ -753,6 +761,7 @@ unsigned int comedi_buf_read_n_available(struct comedi_async *async) smp_rmb(); return num_bytes; } +EXPORT_SYMBOL(comedi_buf_read_n_available); int comedi_buf_get(struct comedi_async *async, short *x) { @@ -765,6 +774,7 @@ int comedi_buf_get(struct comedi_async *async, short *x) comedi_buf_read_free(async, sizeof(short)); return 1; } +EXPORT_SYMBOL(comedi_buf_get); int comedi_buf_put(struct comedi_async *async, short x) { @@ -778,6 +788,7 @@ int comedi_buf_put(struct comedi_async *async, short x) comedi_buf_write_free(async, sizeof(short)); return 1; } +EXPORT_SYMBOL(comedi_buf_put); void comedi_reset_async_buf(struct comedi_async *async) { @@ -797,6 +808,7 @@ void comedi_reset_async_buf(struct comedi_async *async) async->events = 0; } +EXPORT_SYMBOL(comedi_reset_async_buf); int comedi_auto_config(struct device *hardware_device, const char *board_name, const int *options, unsigned num_options) -- cgit v1.2.3 From 18736438ae4ab3d96602b92446e07cc03c024b02 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 1 May 2010 12:02:23 -0700 Subject: Staging: comedi: more EXPORT_SYMBOL movement This moves the markings to the comedi_fops.c file, where they belong. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 8 ++++++++ drivers/staging/comedi/comedi_ksyms.c | 10 ---------- 2 files changed, 8 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 1b3aed4ee60a..4fe3d0c2e6bf 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -57,6 +57,7 @@ MODULE_LICENSE("GPL"); #ifdef CONFIG_COMEDI_DEBUG int comedi_debug; +EXPORT_SYMBOL(comedi_debug); module_param(comedi_debug, int, 0644); #endif @@ -1975,6 +1976,7 @@ void comedi_error(const struct comedi_device *dev, const char *s) printk(KERN_ERR "comedi%d: %s: %s\n", dev->minor, dev->driver->driver_name, s); } +EXPORT_SYMBOL(comedi_error); void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -2017,6 +2019,7 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) } s->async->events = 0; } +EXPORT_SYMBOL(comedi_event); void comedi_set_subdevice_runflags(struct comedi_subdevice *s, unsigned mask, unsigned bits) @@ -2028,6 +2031,7 @@ void comedi_set_subdevice_runflags(struct comedi_subdevice *s, unsigned mask, s->runflags |= (bits & mask); spin_unlock_irqrestore(&s->spin_lock, flags); } +EXPORT_SYMBOL(comedi_set_subdevice_runflags); unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s) { @@ -2039,6 +2043,7 @@ unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s) spin_unlock_irqrestore(&s->spin_lock, flags); return runflags; } +EXPORT_SYMBOL(comedi_get_subdevice_runflags); static int is_device_busy(struct comedi_device *dev) { @@ -2152,6 +2157,7 @@ int comedi_alloc_board_minor(struct device *hardware_device) } return i; } +EXPORT_SYMBOL_GPL(comedi_alloc_board_minor); void comedi_free_board_minor(unsigned minor) { @@ -2177,6 +2183,7 @@ void comedi_free_board_minor(unsigned minor) kfree(info); } } +EXPORT_SYMBOL_GPL(comedi_free_board_minor); int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s) @@ -2286,6 +2293,7 @@ struct comedi_device_file_info *comedi_get_device_file_info(unsigned minor) spin_unlock_irqrestore(&comedi_file_info_table_lock, flags); return info; } +EXPORT_SYMBOL_GPL(comedi_get_device_file_info); static int resize_async_buffer(struct comedi_device *dev, struct comedi_subdevice *s, diff --git a/drivers/staging/comedi/comedi_ksyms.c b/drivers/staging/comedi/comedi_ksyms.c index c0e53bc269c0..9dc04a62a039 100644 --- a/drivers/staging/comedi/comedi_ksyms.c +++ b/drivers/staging/comedi/comedi_ksyms.c @@ -26,21 +26,12 @@ #include "comedidev.h" /* for drivers */ -EXPORT_SYMBOL(comedi_error); -EXPORT_SYMBOL(comedi_event); -EXPORT_SYMBOL(comedi_get_subdevice_runflags); -EXPORT_SYMBOL(comedi_set_subdevice_runflags); EXPORT_SYMBOL(range_bipolar10); EXPORT_SYMBOL(range_bipolar5); EXPORT_SYMBOL(range_bipolar2_5); EXPORT_SYMBOL(range_unipolar10); EXPORT_SYMBOL(range_unipolar5); EXPORT_SYMBOL(range_unknown); -#ifdef CONFIG_COMEDI_DEBUG -EXPORT_SYMBOL(comedi_debug); -#endif -EXPORT_SYMBOL_GPL(comedi_alloc_board_minor); -EXPORT_SYMBOL_GPL(comedi_free_board_minor); EXPORT_SYMBOL_GPL(comedi_pci_auto_config); EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig); EXPORT_SYMBOL_GPL(comedi_usb_auto_config); @@ -48,4 +39,3 @@ EXPORT_SYMBOL_GPL(comedi_usb_auto_unconfig); /* for kcomedilib */ EXPORT_SYMBOL(check_chanlist); -EXPORT_SYMBOL_GPL(comedi_get_device_file_info); -- cgit v1.2.3 From e42315177d278089ba7b1e623ecbd5b273b7e62b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 1 May 2010 12:12:02 -0700 Subject: Staging: comedi: more EXPORT_SYMBOL movement Move the exports for the variables that are in range.c into the file itself. These variables should be prefixed with comedi_ but that's for a different patch... Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_ksyms.c | 6 ------ drivers/staging/comedi/range.c | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_ksyms.c b/drivers/staging/comedi/comedi_ksyms.c index 9dc04a62a039..cc0a399277cb 100644 --- a/drivers/staging/comedi/comedi_ksyms.c +++ b/drivers/staging/comedi/comedi_ksyms.c @@ -26,12 +26,6 @@ #include "comedidev.h" /* for drivers */ -EXPORT_SYMBOL(range_bipolar10); -EXPORT_SYMBOL(range_bipolar5); -EXPORT_SYMBOL(range_bipolar2_5); -EXPORT_SYMBOL(range_unipolar10); -EXPORT_SYMBOL(range_unipolar5); -EXPORT_SYMBOL(range_unknown); EXPORT_SYMBOL_GPL(comedi_pci_auto_config); EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig); EXPORT_SYMBOL_GPL(comedi_usb_auto_config); diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c index c35ade94a12d..b5644cad2603 100644 --- a/drivers/staging/comedi/range.c +++ b/drivers/staging/comedi/range.c @@ -30,6 +30,12 @@ const struct comedi_lrange range_bipolar2_5 = { 1, {BIP_RANGE(2.5)} }; const struct comedi_lrange range_unipolar10 = { 1, {UNI_RANGE(10)} }; const struct comedi_lrange range_unipolar5 = { 1, {UNI_RANGE(5)} }; const struct comedi_lrange range_unknown = { 1, {{0, 1000000, UNIT_none} } }; +EXPORT_SYMBOL(range_bipolar10); +EXPORT_SYMBOL(range_bipolar5); +EXPORT_SYMBOL(range_bipolar2_5); +EXPORT_SYMBOL(range_unipolar10); +EXPORT_SYMBOL(range_unipolar5); +EXPORT_SYMBOL(range_unknown); /* COMEDI_RANGEINFO -- cgit v1.2.3 From 0fd0ca75fd9eb0e9cde49c28ad227c2d8d049366 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 1 May 2010 12:33:17 -0700 Subject: Staging: comedi: rename check_chanlist to comedi_check_chanlist It's a global function, so properly name it and move the export to where the function is located at. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 6 +++--- drivers/staging/comedi/comedi_ksyms.c | 3 --- drivers/staging/comedi/comedidev.h | 2 +- drivers/staging/comedi/kcomedilib/kcomedilib_main.c | 2 +- drivers/staging/comedi/range.c | 4 +++- 5 files changed, 8 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 4fe3d0c2e6bf..b11f9b08000b 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -839,7 +839,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, goto out; } - ret = check_chanlist(s, 1, &insn->chanspec); + ret = comedi_check_chanlist(s, 1, &insn->chanspec); if (ret < 0) { ret = -EINVAL; DPRINTK("bad chanspec\n"); @@ -1052,7 +1052,7 @@ static int do_cmd_ioctl(struct comedi_device *dev, void *arg, void *file) } /* make sure each element in channel/gain list is valid */ - ret = check_chanlist(s, async->cmd.chanlist_len, async->cmd.chanlist); + ret = comedi_check_chanlist(s, async->cmd.chanlist_len, async->cmd.chanlist); if (ret < 0) { DPRINTK("bad chanlist\n"); goto cleanup; @@ -1174,7 +1174,7 @@ static int do_cmdtest_ioctl(struct comedi_device *dev, void *arg, void *file) } /* make sure each element in channel/gain list is valid */ - ret = check_chanlist(s, user_cmd.chanlist_len, chanlist); + ret = comedi_check_chanlist(s, user_cmd.chanlist_len, chanlist); if (ret < 0) { DPRINTK("bad chanlist\n"); goto cleanup; diff --git a/drivers/staging/comedi/comedi_ksyms.c b/drivers/staging/comedi/comedi_ksyms.c index cc0a399277cb..0ce231489a5a 100644 --- a/drivers/staging/comedi/comedi_ksyms.c +++ b/drivers/staging/comedi/comedi_ksyms.c @@ -30,6 +30,3 @@ EXPORT_SYMBOL_GPL(comedi_pci_auto_config); EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig); EXPORT_SYMBOL_GPL(comedi_usb_auto_config); EXPORT_SYMBOL_GPL(comedi_usb_auto_unconfig); - -/* for kcomedilib */ -EXPORT_SYMBOL(check_chanlist); diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index f5b0810f2258..5e4672751d42 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -382,7 +382,7 @@ enum subdevice_runflags { */ int do_rangeinfo_ioctl(struct comedi_device *dev, struct comedi_rangeinfo *arg); -int check_chanlist(struct comedi_subdevice *s, int n, unsigned int *chanlist); +int comedi_check_chanlist(struct comedi_subdevice *s, int n, unsigned int *chanlist); void comedi_set_subdevice_runflags(struct comedi_subdevice *s, unsigned mask, unsigned bits); unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s); diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c index 288fef4fcbcc..2229b46e849c 100644 --- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c +++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c @@ -251,7 +251,7 @@ int comedi_do_insn(void *d, struct comedi_insn *insn) /* XXX check lock */ - ret = check_chanlist(s, 1, &insn->chanspec); + ret = comedi_check_chanlist(s, 1, &insn->chanspec); if (ret < 0) { printk("bad chanspec\n"); ret = -EINVAL; diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c index b5644cad2603..6b03a69762a4 100644 --- a/drivers/staging/comedi/range.c +++ b/drivers/staging/comedi/range.c @@ -126,7 +126,8 @@ static int aref_invalid(struct comedi_subdevice *s, unsigned int chanspec) This function checks each element in a channel/gain list to make make sure it is valid. */ -int check_chanlist(struct comedi_subdevice *s, int n, unsigned int *chanlist) +int comedi_check_chanlist(struct comedi_subdevice *s, int n, + unsigned int *chanlist) { int i; int chan; @@ -160,3 +161,4 @@ int check_chanlist(struct comedi_subdevice *s, int n, unsigned int *chanlist) } return 0; } +EXPORT_SYMBOL(comedi_check_chanlist); -- cgit v1.2.3 From 4bf935596bfabe3f951bc0331ebd893ef06e1123 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 1 May 2010 12:38:02 -0700 Subject: Staging: comedi: remove comedi_ksyms.c Move the 4 remaining exports to their function location and then remove the comedi_ksyms.c file, as it's no longer needed. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Makefile | 1 - drivers/staging/comedi/comedi_ksyms.c | 32 -------------------------------- drivers/staging/comedi/drivers.c | 4 ++++ 3 files changed, 4 insertions(+), 33 deletions(-) delete mode 100644 drivers/staging/comedi/comedi_ksyms.c (limited to 'drivers') diff --git a/drivers/staging/comedi/Makefile b/drivers/staging/comedi/Makefile index 05811f79d85b..20afea301c87 100644 --- a/drivers/staging/comedi/Makefile +++ b/drivers/staging/comedi/Makefile @@ -9,4 +9,3 @@ comedi-objs := \ range.o \ drivers.o \ comedi_compat32.o \ - comedi_ksyms.o \ diff --git a/drivers/staging/comedi/comedi_ksyms.c b/drivers/staging/comedi/comedi_ksyms.c deleted file mode 100644 index 0ce231489a5a..000000000000 --- a/drivers/staging/comedi/comedi_ksyms.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - module/exp_ioctl.c - exported comedi functions - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 1997-8 David A. Schleef - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#define __NO_VERSION__ - -#include "comedidev.h" - -/* for drivers */ -EXPORT_SYMBOL_GPL(comedi_pci_auto_config); -EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig); -EXPORT_SYMBOL_GPL(comedi_usb_auto_config); -EXPORT_SYMBOL_GPL(comedi_usb_auto_unconfig); diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 2b7eda501809..d7a450917405 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -881,20 +881,24 @@ int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name) return comedi_auto_config(&pcidev->dev, board_name, options, ARRAY_SIZE(options)); } +EXPORT_SYMBOL_GPL(comedi_pci_auto_config); void comedi_pci_auto_unconfig(struct pci_dev *pcidev) { comedi_auto_unconfig(&pcidev->dev); } +EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig); int comedi_usb_auto_config(struct usb_device *usbdev, const char *board_name) { BUG_ON(usbdev == NULL); return comedi_auto_config(&usbdev->dev, board_name, NULL, 0); } +EXPORT_SYMBOL_GPL(comedi_usb_auto_config); void comedi_usb_auto_unconfig(struct usb_device *usbdev) { BUG_ON(usbdev == NULL); comedi_auto_unconfig(&usbdev->dev); } +EXPORT_SYMBOL_GPL(comedi_usb_auto_unconfig); -- cgit v1.2.3 From 7382e5711f3adc934227473f82156ae1e2d7e562 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 1 May 2010 13:08:06 -0700 Subject: Staging: comedi: kcomedilib: remove ksyms.c file Move only the exports that we actually use into the individual files, and delete the ksyms.c file entirely. This will make it easier to start cleaning up kcomedilib (i.e. delete most of it.) Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/kcomedilib/Makefile | 1 - drivers/staging/comedi/kcomedilib/dio.c | 3 + drivers/staging/comedi/kcomedilib/get.c | 18 +-- .../staging/comedi/kcomedilib/kcomedilib_main.c | 6 +- drivers/staging/comedi/kcomedilib/ksyms.c | 146 --------------------- 5 files changed, 16 insertions(+), 158 deletions(-) delete mode 100644 drivers/staging/comedi/kcomedilib/ksyms.c (limited to 'drivers') diff --git a/drivers/staging/comedi/kcomedilib/Makefile b/drivers/staging/comedi/kcomedilib/Makefile index ffcc9ad32adb..76de45bd37e5 100644 --- a/drivers/staging/comedi/kcomedilib/Makefile +++ b/drivers/staging/comedi/kcomedilib/Makefile @@ -2,7 +2,6 @@ obj-$(CONFIG_COMEDI) += kcomedilib.o kcomedilib-objs := \ data.o \ - ksyms.o \ dio.o \ kcomedilib_main.o \ get.o diff --git a/drivers/staging/comedi/kcomedilib/dio.c b/drivers/staging/comedi/kcomedilib/dio.c index 30192f3c4652..e37aa5308141 100644 --- a/drivers/staging/comedi/kcomedilib/dio.c +++ b/drivers/staging/comedi/kcomedilib/dio.c @@ -25,6 +25,7 @@ #include "../comedilib.h" #include +#include int comedi_dio_config(void *dev, unsigned int subdev, unsigned int chan, unsigned int io) @@ -40,6 +41,7 @@ int comedi_dio_config(void *dev, unsigned int subdev, unsigned int chan, return comedi_do_insn(dev, &insn); } +EXPORT_SYMBOL(comedi_dio_config); int comedi_dio_read(void *dev, unsigned int subdev, unsigned int chan, unsigned int *val) @@ -93,3 +95,4 @@ int comedi_dio_bitfield(void *dev, unsigned int subdev, unsigned int mask, return ret; } +EXPORT_SYMBOL(comedi_dio_bitfield); diff --git a/drivers/staging/comedi/kcomedilib/get.c b/drivers/staging/comedi/kcomedilib/get.c index 6d8418715253..ec072ce7cd4f 100644 --- a/drivers/staging/comedi/kcomedilib/get.c +++ b/drivers/staging/comedi/kcomedilib/get.c @@ -81,6 +81,7 @@ int comedi_find_subdevice_by_type(void *d, int type, unsigned int subd) } return -1; } +EXPORT_SYMBOL(comedi_find_subdevice_by_type); int comedi_get_n_channels(void *d, unsigned int subdevice) { @@ -89,6 +90,7 @@ int comedi_get_n_channels(void *d, unsigned int subdevice) return s->n_chan; } +EXPORT_SYMBOL(comedi_get_n_channels); int comedi_get_len_chanlist(void *d, unsigned int subdevice) { @@ -117,11 +119,10 @@ int comedi_get_rangetype(void *d, unsigned int subdevice, unsigned int chan) struct comedi_subdevice *s = dev->subdevices + subdevice; int ret; - if (s->range_table_list) { + if (s->range_table_list) ret = s->range_table_list[chan]->length; - } else { + else ret = s->range_table->length; - } ret = ret | (dev->minor << 28) | (subdevice << 24) | (chan << 16); @@ -135,11 +136,10 @@ int comedi_get_n_ranges(void *d, unsigned int subdevice, unsigned int chan) struct comedi_subdevice *s = dev->subdevices + subdevice; int ret; - if (s->range_table_list) { + if (s->range_table_list) ret = s->range_table_list[chan]->length; - } else { + else ret = s->range_table->length; - } return ret; } @@ -154,11 +154,11 @@ int comedi_get_krange(void *d, unsigned int subdevice, unsigned int chan, struct comedi_subdevice *s = dev->subdevices + subdevice; const struct comedi_lrange *lr; - if (s->range_table_list) { + if (s->range_table_list) lr = s->range_table_list[chan]; - } else { + else lr = s->range_table; - } + if (range >= lr->length) return -EINVAL; diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c index 2229b46e849c..32c7bbb8d78a 100644 --- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c +++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include "../comedi.h" #include "../comedilib.h" @@ -68,6 +68,7 @@ void *comedi_open(const char *filename) return (void *)dev; } +EXPORT_SYMBOL(comedi_open); void *comedi_open_old(unsigned int minor) { @@ -96,6 +97,7 @@ int comedi_close(void *d) return 0; } +EXPORT_SYMBOL(comedi_close); int comedi_loglevel(int newlevel) { @@ -104,7 +106,7 @@ int comedi_loglevel(int newlevel) void comedi_perror(const char *message) { - printk("%s: unknown error\n", message); + printk(KERN_ERR "%s: unknown error\n", message); } char *comedi_strerror(int err) diff --git a/drivers/staging/comedi/kcomedilib/ksyms.c b/drivers/staging/comedi/kcomedilib/ksyms.c deleted file mode 100644 index 8bf4471ce6c1..000000000000 --- a/drivers/staging/comedi/kcomedilib/ksyms.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - comedi/kcomedilib/ksyms.c - a comedlib interface for kernel modules - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 1997-2001 David A. Schleef - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "../comedi.h" -#include "../comedilib.h" -#include "../comedidev.h" - -#include - -#include -#include -#include -#include -#include -#include -#include - -/* functions specific to kcomedilib */ - -EXPORT_SYMBOL(comedi_register_callback); -EXPORT_SYMBOL(comedi_get_krange); -EXPORT_SYMBOL(comedi_get_buf_head_pos); -EXPORT_SYMBOL(comedi_set_user_int_count); -EXPORT_SYMBOL(comedi_map); -EXPORT_SYMBOL(comedi_unmap); - -/* This list comes from user-space comedilib, to show which - * functions are not ported yet. */ - -EXPORT_SYMBOL(comedi_open); -EXPORT_SYMBOL(comedi_close); - -/* logging */ -EXPORT_SYMBOL(comedi_loglevel); -EXPORT_SYMBOL(comedi_perror); -EXPORT_SYMBOL(comedi_strerror); -/* EXPORT_SYMBOL(comedi_errno); */ -EXPORT_SYMBOL(comedi_fileno); - -/* device queries */ -EXPORT_SYMBOL(comedi_get_n_subdevices); -EXPORT_SYMBOL(comedi_get_version_code); -EXPORT_SYMBOL(comedi_get_driver_name); -EXPORT_SYMBOL(comedi_get_board_name); - -/* subdevice queries */ -EXPORT_SYMBOL(comedi_get_subdevice_type); -EXPORT_SYMBOL(comedi_find_subdevice_by_type); -EXPORT_SYMBOL(comedi_get_subdevice_flags); -EXPORT_SYMBOL(comedi_get_n_channels); -/* -* EXPORT_SYMBOL(comedi_range_is_chan_specific); -* EXPORT_SYMBOL(comedi_maxdata_is_chan_specific); -*/ - -/* channel queries */ -EXPORT_SYMBOL(comedi_get_maxdata); -#ifdef KCOMEDILIB_DEPRECATED -EXPORT_SYMBOL(comedi_get_rangetype); -#endif -EXPORT_SYMBOL(comedi_get_n_ranges); -/* EXPORT_SYMBOL(comedi_find_range); */ - -/* buffer queries */ -EXPORT_SYMBOL(comedi_get_buffer_size); -/* -* EXPORT_SYMBOL(comedi_get_max_buffer_size); -* EXPORT_SYMBOL(comedi_set_buffer_size); -*/ -EXPORT_SYMBOL(comedi_get_buffer_contents); -EXPORT_SYMBOL(comedi_get_buffer_offset); - -/* low-level stuff */ -/* -* EXPORT_SYMBOL(comedi_trigger); EXPORT_SYMBOL(comedi_do_insnlist); -*/ -EXPORT_SYMBOL(comedi_do_insn); -EXPORT_SYMBOL(comedi_lock); -EXPORT_SYMBOL(comedi_unlock); - -/* physical units */ -/* -* EXPORT_SYMBOL(comedi_to_phys); EXPORT_SYMBOL(comedi_from_phys); -*/ - -/* synchronous stuff */ -EXPORT_SYMBOL(comedi_data_read); -EXPORT_SYMBOL(comedi_data_read_hint); -EXPORT_SYMBOL(comedi_data_read_delayed); -EXPORT_SYMBOL(comedi_data_write); -EXPORT_SYMBOL(comedi_dio_config); -EXPORT_SYMBOL(comedi_dio_read); -EXPORT_SYMBOL(comedi_dio_write); -EXPORT_SYMBOL(comedi_dio_bitfield); - -/* slowly varying stuff */ -/* -* EXPORT_SYMBOL(comedi_sv_init); EXPORT_SYMBOL(comedi_sv_update); -* EXPORT_SYMBOL(comedi_sv_measure); -*/ - -/* commands */ -/* -* EXPORT_SYMBOL(comedi_get_cmd_src_mask); -* EXPORT_SYMBOL(comedi_get_cmd_generic_timed); -*/ -EXPORT_SYMBOL(comedi_cancel); -EXPORT_SYMBOL(comedi_command); -EXPORT_SYMBOL(comedi_command_test); -EXPORT_SYMBOL(comedi_poll); - -/* buffer configuration */ -EXPORT_SYMBOL(comedi_mark_buffer_read); -EXPORT_SYMBOL(comedi_mark_buffer_written); - -/* EXPORT_SYMBOL(comedi_get_range); */ -EXPORT_SYMBOL(comedi_get_len_chanlist); - -/* deprecated */ -/* -* EXPORT_SYMBOL(comedi_get_timer); -* EXPORT_SYMBOL(comedi_timed_1chan); -*/ - -/* alpha */ -/* EXPORT_SYMBOL(comedi_set_global_oor_behavior); */ -- cgit v1.2.3 From 703f5936e2a4a31a5b2596d47c1504a472d4ab85 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 1 May 2010 13:42:37 -0700 Subject: Staging: comedi: clean up comedilib.h Remove a whole #ifdef section that is not needed anymore. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedilib.h | 82 -------------------------------------- 1 file changed, 82 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedilib.h b/drivers/staging/comedi/comedilib.h index 27dd3bec88af..deb28cb234a9 100644 --- a/drivers/staging/comedi/comedilib.h +++ b/drivers/staging/comedi/comedilib.h @@ -26,16 +26,6 @@ #include "comedi.h" -/* Kernel internal stuff. Needed by real-time modules and such. */ - -#ifndef __KERNEL__ -#error linux/comedilib.h should not be included by non-kernel-space code -#endif - -/* exported functions */ - -#ifndef KCOMEDILIB_DEPRECATED - /* these functions may not be called at real-time priority */ void *comedi_open(const char *path); @@ -117,77 +107,5 @@ int comedi_mark_buffer_written(void *d, unsigned int subdevice, int comedi_get_buffer_contents(void *dev, unsigned int subdevice); int comedi_get_buffer_offset(void *dev, unsigned int subdevice); -#else - -/* these functions may not be called at real-time priority */ - -int comedi_open(unsigned int minor); -void comedi_close(unsigned int minor); - -/* these functions may be called at any priority, but may fail at - real-time priority */ - -int comedi_lock(unsigned int minor, unsigned int subdev); -int comedi_unlock(unsigned int minor, unsigned int subdev); - -/* these functions may be called at any priority, but you must hold - the lock for the subdevice */ - -int comedi_cancel(unsigned int minor, unsigned int subdev); -int comedi_register_callback(unsigned int minor, unsigned int subdev, - unsigned int mask, int (*cb) (unsigned int, - void *), void *arg); - -int comedi_command(unsigned int minor, struct comedi_cmd *cmd); -int comedi_command_test(unsigned int minor, struct comedi_cmd *cmd); -int comedi_trigger(unsigned int minor, unsigned int subdev, - struct comedi_trig *it); -int __comedi_trigger(unsigned int minor, unsigned int subdev, - struct comedi_trig *it); -int comedi_data_write(unsigned int dev, unsigned int subdev, unsigned int chan, - unsigned int range, unsigned int aref, unsigned int data); -int comedi_data_read(unsigned int dev, unsigned int subdev, unsigned int chan, - unsigned int range, unsigned int aref, unsigned int *data); -int comedi_dio_config(unsigned int dev, unsigned int subdev, unsigned int chan, - unsigned int io); -int comedi_dio_read(unsigned int dev, unsigned int subdev, unsigned int chan, - unsigned int *val); -int comedi_dio_write(unsigned int dev, unsigned int subdev, unsigned int chan, - unsigned int val); -int comedi_dio_bitfield(unsigned int dev, unsigned int subdev, - unsigned int mask, unsigned int *bits); -int comedi_get_n_subdevices(unsigned int dev); -int comedi_get_version_code(unsigned int dev); -char *comedi_get_driver_name(unsigned int dev); -char *comedi_get_board_name(unsigned int minor); -int comedi_get_subdevice_type(unsigned int minor, unsigned int subdevice); -int comedi_find_subdevice_by_type(unsigned int minor, int type, - unsigned int subd); -int comedi_get_n_channels(unsigned int minor, unsigned int subdevice); -unsigned int comedi_get_maxdata(unsigned int minor, unsigned int subdevice, - unsigned int chan); -int comedi_get_n_ranges(unsigned int minor, unsigned int subdevice, - unsigned int chan); -int comedi_do_insn(unsigned int minor, struct comedi_insn *insn); -int comedi_poll(unsigned int minor, unsigned int subdev); - -/* DEPRECATED functions */ -int comedi_get_rangetype(unsigned int minor, unsigned int subdevice, - unsigned int chan); - -/* ALPHA functions */ -unsigned int comedi_get_subdevice_flags(unsigned int minor, unsigned int - subdevice); -int comedi_get_len_chanlist(unsigned int minor, unsigned int subdevice); -int comedi_get_krange(unsigned int minor, unsigned int subdevice, unsigned int - chan, unsigned int range, struct comedi_krange *krange); -unsigned int comedi_get_buf_head_pos(unsigned int minor, unsigned int - subdevice); -int comedi_set_user_int_count(unsigned int minor, unsigned int subdevice, - unsigned int buf_user_count); -int comedi_map(unsigned int minor, unsigned int subdev, void **ptr); -int comedi_unmap(unsigned int minor, unsigned int subdev); - -#endif #endif -- cgit v1.2.3 From e2a0eab0a121a95be60a81911df07cc21e4ee429 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 1 May 2010 13:44:56 -0700 Subject: Staging: comedi: move an include file out of comedlib.h The one .c file that needs it can properly include it. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedilib.h | 2 -- drivers/staging/comedi/drivers/comedi_bond.c | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedilib.h b/drivers/staging/comedi/comedilib.h index deb28cb234a9..4f86964835a9 100644 --- a/drivers/staging/comedi/comedilib.h +++ b/drivers/staging/comedi/comedilib.h @@ -24,8 +24,6 @@ #ifndef _LINUX_COMEDILIB_H #define _LINUX_COMEDILIB_H -#include "comedi.h" - /* these functions may not be called at real-time priority */ void *comedi_open(const char *path); diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index 4e6797a0b1e2..429ec703d596 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -87,6 +87,7 @@ Configuration Options: * options that are used with comedi_config. */ +#include "../comedi.h" #include "../comedilib.h" #include "../comedidev.h" #include -- cgit v1.2.3 From 027d53bc2f223544a18f1b760378ca0566d13f2e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 1 May 2010 13:51:58 -0700 Subject: Staging: comedi: remove unused functions from comedilib.h Remove the functions that are not used from this file. Now it will be easier to determine what code can be removed from kcomedilib by using sparse. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedilib.h | 74 ++------------------------------------ 1 file changed, 2 insertions(+), 72 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedilib.h b/drivers/staging/comedi/comedilib.h index 4f86964835a9..00414359138d 100644 --- a/drivers/staging/comedi/comedilib.h +++ b/drivers/staging/comedi/comedilib.h @@ -24,86 +24,16 @@ #ifndef _LINUX_COMEDILIB_H #define _LINUX_COMEDILIB_H -/* these functions may not be called at real-time priority */ - void *comedi_open(const char *path); int comedi_close(void *dev); - -/* these functions may be called at any priority, but may fail at - real-time priority */ - -int comedi_lock(void *dev, unsigned int subdev); -int comedi_unlock(void *dev, unsigned int subdev); - -/* these functions may be called at any priority, but you must hold - the lock for the subdevice */ - -int comedi_loglevel(int loglevel); -void comedi_perror(const char *s); -char *comedi_strerror(int errnum); -int comedi_errno(void); -int comedi_fileno(void *dev); - -int comedi_cancel(void *dev, unsigned int subdev); -int comedi_register_callback(void *dev, unsigned int subdev, - unsigned int mask, int (*cb) (unsigned int, - void *), void *arg); - -int comedi_command(void *dev, struct comedi_cmd *cmd); -int comedi_command_test(void *dev, struct comedi_cmd *cmd); -int comedi_trigger(void *dev, unsigned int subdev, struct comedi_trig *it); -int __comedi_trigger(void *dev, unsigned int subdev, struct comedi_trig *it); -int comedi_data_write(void *dev, unsigned int subdev, unsigned int chan, - unsigned int range, unsigned int aref, unsigned int data); -int comedi_data_read(void *dev, unsigned int subdev, unsigned int chan, - unsigned int range, unsigned int aref, unsigned int *data); -int comedi_data_read_hint(void *dev, unsigned int subdev, - unsigned int chan, unsigned int range, - unsigned int aref); -int comedi_data_read_delayed(void *dev, unsigned int subdev, unsigned int chan, - unsigned int range, unsigned int aref, - unsigned int *data, unsigned int nano_sec); int comedi_dio_config(void *dev, unsigned int subdev, unsigned int chan, unsigned int io); -int comedi_dio_read(void *dev, unsigned int subdev, unsigned int chan, - unsigned int *val); -int comedi_dio_write(void *dev, unsigned int subdev, unsigned int chan, - unsigned int val); int comedi_dio_bitfield(void *dev, unsigned int subdev, unsigned int mask, unsigned int *bits); -int comedi_get_n_subdevices(void *dev); -int comedi_get_version_code(void *dev); -const char *comedi_get_driver_name(void *dev); -const char *comedi_get_board_name(void *dev); -int comedi_get_subdevice_type(void *dev, unsigned int subdevice); int comedi_find_subdevice_by_type(void *dev, int type, unsigned int subd); int comedi_get_n_channels(void *dev, unsigned int subdevice); -unsigned int comedi_get_maxdata(void *dev, unsigned int subdevice, unsigned - int chan); -int comedi_get_n_ranges(void *dev, unsigned int subdevice, unsigned int chan); -int comedi_do_insn(void *dev, struct comedi_insn *insn); -int comedi_poll(void *dev, unsigned int subdev); - -/* DEPRECATED functions */ -int comedi_get_rangetype(void *dev, unsigned int subdevice, unsigned int chan); - -/* ALPHA functions */ -unsigned int comedi_get_subdevice_flags(void *dev, unsigned int subdevice); -int comedi_get_len_chanlist(void *dev, unsigned int subdevice); -int comedi_get_krange(void *dev, unsigned int subdevice, unsigned int - chan, unsigned int range, struct comedi_krange *krange); -unsigned int comedi_get_buf_head_pos(void *dev, unsigned int subdevice); -int comedi_set_user_int_count(void *dev, unsigned int subdevice, - unsigned int buf_user_count); -int comedi_map(void *dev, unsigned int subdev, void *ptr); -int comedi_unmap(void *dev, unsigned int subdev); -int comedi_get_buffer_size(void *dev, unsigned int subdev); -int comedi_mark_buffer_read(void *dev, unsigned int subdevice, - unsigned int num_bytes); -int comedi_mark_buffer_written(void *d, unsigned int subdevice, - unsigned int num_bytes); -int comedi_get_buffer_contents(void *dev, unsigned int subdevice); -int comedi_get_buffer_offset(void *dev, unsigned int subdevice); +/* internal to kcomedilb */ +int comedi_do_insn(void *dev, struct comedi_insn *insn); #endif -- cgit v1.2.3 From 29a915ff65fd5cde9c7c16d693b6ae3ecbd4be93 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 1 May 2010 13:55:30 -0700 Subject: Staging: comedi: delete kcomedilib/data.c No one is using any of these functions, so remove the file entirely. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/kcomedilib/Makefile | 1 - drivers/staging/comedi/kcomedilib/data.c | 92 ------------------------------ 2 files changed, 93 deletions(-) delete mode 100644 drivers/staging/comedi/kcomedilib/data.c (limited to 'drivers') diff --git a/drivers/staging/comedi/kcomedilib/Makefile b/drivers/staging/comedi/kcomedilib/Makefile index 76de45bd37e5..006aa1ce4a13 100644 --- a/drivers/staging/comedi/kcomedilib/Makefile +++ b/drivers/staging/comedi/kcomedilib/Makefile @@ -1,7 +1,6 @@ obj-$(CONFIG_COMEDI) += kcomedilib.o kcomedilib-objs := \ - data.o \ dio.o \ kcomedilib_main.o \ get.o diff --git a/drivers/staging/comedi/kcomedilib/data.c b/drivers/staging/comedi/kcomedilib/data.c deleted file mode 100644 index aefc41ab7c46..000000000000 --- a/drivers/staging/comedi/kcomedilib/data.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - kcomedilib/data.c - implements comedi_data_*() functions - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 2000 David A. Schleef - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "../comedi.h" -#include "../comedilib.h" -#include "../comedidev.h" - -#include -#include - -int comedi_data_write(void *dev, unsigned int subdev, unsigned int chan, - unsigned int range, unsigned int aref, unsigned int data) -{ - struct comedi_insn insn; - - memset(&insn, 0, sizeof(insn)); - insn.insn = INSN_WRITE; - insn.n = 1; - insn.data = &data; - insn.subdev = subdev; - insn.chanspec = CR_PACK(chan, range, aref); - - return comedi_do_insn(dev, &insn); -} - -int comedi_data_read(void *dev, unsigned int subdev, unsigned int chan, - unsigned int range, unsigned int aref, unsigned int *data) -{ - struct comedi_insn insn; - - memset(&insn, 0, sizeof(insn)); - insn.insn = INSN_READ; - insn.n = 1; - insn.data = data; - insn.subdev = subdev; - insn.chanspec = CR_PACK(chan, range, aref); - - return comedi_do_insn(dev, &insn); -} - -int comedi_data_read_hint(void *dev, unsigned int subdev, - unsigned int chan, unsigned int range, - unsigned int aref) -{ - struct comedi_insn insn; - unsigned int dummy_data; - - memset(&insn, 0, sizeof(insn)); - insn.insn = INSN_READ; - insn.n = 0; - insn.data = &dummy_data; - insn.subdev = subdev; - insn.chanspec = CR_PACK(chan, range, aref); - - return comedi_do_insn(dev, &insn); -} - -int comedi_data_read_delayed(void *dev, unsigned int subdev, - unsigned int chan, unsigned int range, - unsigned int aref, unsigned int *data, - unsigned int nano_sec) -{ - int retval; - - retval = comedi_data_read_hint(dev, subdev, chan, range, aref); - if (retval < 0) - return retval; - - udelay((nano_sec + 999) / 1000); - - return comedi_data_read(dev, subdev, chan, range, aref, data); -} -- cgit v1.2.3 From 8a9e77b66508a1c2598ce1cb765d7ced52f48cf4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 1 May 2010 13:59:57 -0700 Subject: Staging: comedi: clean up kcomedilib/get.c Remove all of the unused functions, leaving only those that are actually called by in-kernel code. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/kcomedilib/get.c | 242 -------------------------------- 1 file changed, 242 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/kcomedilib/get.c b/drivers/staging/comedi/kcomedilib/get.c index ec072ce7cd4f..99ab27ab8054 100644 --- a/drivers/staging/comedi/kcomedilib/get.c +++ b/drivers/staging/comedi/kcomedilib/get.c @@ -26,48 +26,6 @@ #include "../comedilib.h" #include "../comedidev.h" -int comedi_get_n_subdevices(void *d) -{ - struct comedi_device *dev = (struct comedi_device *)d; - - return dev->n_subdevices; -} - -int comedi_get_version_code(void *d) -{ - return COMEDI_VERSION_CODE; -} - -const char *comedi_get_driver_name(void *d) -{ - struct comedi_device *dev = (struct comedi_device *)d; - - return dev->driver->driver_name; -} - -const char *comedi_get_board_name(void *d) -{ - struct comedi_device *dev = (struct comedi_device *)d; - - return dev->board_name; -} - -int comedi_get_subdevice_type(void *d, unsigned int subdevice) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s = dev->subdevices + subdevice; - - return s->type; -} - -unsigned int comedi_get_subdevice_flags(void *d, unsigned int subdevice) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s = dev->subdevices + subdevice; - - return s->subdev_flags; -} - int comedi_find_subdevice_by_type(void *d, int type, unsigned int subd) { struct comedi_device *dev = (struct comedi_device *)d; @@ -91,203 +49,3 @@ int comedi_get_n_channels(void *d, unsigned int subdevice) return s->n_chan; } EXPORT_SYMBOL(comedi_get_n_channels); - -int comedi_get_len_chanlist(void *d, unsigned int subdevice) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s = dev->subdevices + subdevice; - - return s->len_chanlist; -} - -unsigned int comedi_get_maxdata(void *d, unsigned int subdevice, - unsigned int chan) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s = dev->subdevices + subdevice; - - if (s->maxdata_list) - return s->maxdata_list[chan]; - - return s->maxdata; -} - -#ifdef KCOMEDILIB_DEPRECATED -int comedi_get_rangetype(void *d, unsigned int subdevice, unsigned int chan) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s = dev->subdevices + subdevice; - int ret; - - if (s->range_table_list) - ret = s->range_table_list[chan]->length; - else - ret = s->range_table->length; - - ret = ret | (dev->minor << 28) | (subdevice << 24) | (chan << 16); - - return ret; -} -#endif - -int comedi_get_n_ranges(void *d, unsigned int subdevice, unsigned int chan) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s = dev->subdevices + subdevice; - int ret; - - if (s->range_table_list) - ret = s->range_table_list[chan]->length; - else - ret = s->range_table->length; - - return ret; -} - -/* - * ALPHA (non-portable) -*/ -int comedi_get_krange(void *d, unsigned int subdevice, unsigned int chan, - unsigned int range, struct comedi_krange *krange) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s = dev->subdevices + subdevice; - const struct comedi_lrange *lr; - - if (s->range_table_list) - lr = s->range_table_list[chan]; - else - lr = s->range_table; - - if (range >= lr->length) - return -EINVAL; - - memcpy(krange, lr->range + range, sizeof(struct comedi_krange)); - - return 0; -} - -/* - * ALPHA (may be renamed) -*/ -unsigned int comedi_get_buf_head_pos(void *d, unsigned int subdevice) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s = dev->subdevices + subdevice; - struct comedi_async *async; - - async = s->async; - if (async == NULL) - return 0; - - return async->buf_write_count; -} - -int comedi_get_buffer_contents(void *d, unsigned int subdevice) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s = dev->subdevices + subdevice; - struct comedi_async *async; - unsigned int num_bytes; - - if (subdevice >= dev->n_subdevices) - return -1; - async = s->async; - if (async == NULL) - return 0; - num_bytes = comedi_buf_read_n_available(s->async); - return num_bytes; -} - -/* - * ALPHA -*/ -int comedi_set_user_int_count(void *d, unsigned int subdevice, - unsigned int buf_user_count) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s = dev->subdevices + subdevice; - struct comedi_async *async; - int num_bytes; - - async = s->async; - if (async == NULL) - return -1; - - num_bytes = buf_user_count - async->buf_read_count; - if (num_bytes < 0) - return -1; - comedi_buf_read_alloc(async, num_bytes); - comedi_buf_read_free(async, num_bytes); - - return 0; -} - -int comedi_mark_buffer_read(void *d, unsigned int subdevice, - unsigned int num_bytes) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s = dev->subdevices + subdevice; - struct comedi_async *async; - - if (subdevice >= dev->n_subdevices) - return -1; - async = s->async; - if (async == NULL) - return -1; - - comedi_buf_read_alloc(async, num_bytes); - comedi_buf_read_free(async, num_bytes); - - return 0; -} - -int comedi_mark_buffer_written(void *d, unsigned int subdevice, - unsigned int num_bytes) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s = dev->subdevices + subdevice; - struct comedi_async *async; - int bytes_written; - - if (subdevice >= dev->n_subdevices) - return -1; - async = s->async; - if (async == NULL) - return -1; - bytes_written = comedi_buf_write_alloc(async, num_bytes); - comedi_buf_write_free(async, bytes_written); - if (bytes_written != num_bytes) - return -1; - return 0; -} - -int comedi_get_buffer_size(void *d, unsigned int subdev) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s = dev->subdevices + subdev; - struct comedi_async *async; - - if (subdev >= dev->n_subdevices) - return -1; - async = s->async; - if (async == NULL) - return 0; - - return async->prealloc_bufsz; -} - -int comedi_get_buffer_offset(void *d, unsigned int subdevice) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s = dev->subdevices + subdevice; - struct comedi_async *async; - - if (subdevice >= dev->n_subdevices) - return -1; - async = s->async; - if (async == NULL) - return 0; - - return async->buf_read_ptr; -} -- cgit v1.2.3 From 8611a29ab967bc197494db19d31994d1b5a26fdc Mon Sep 17 00:00:00 2001 From: Andres More Date: Sat, 1 May 2010 14:25:00 -0300 Subject: Staging: vt6656: removed VOID/PVOID definitions Warnings about the usage of externs in .c files were not resolved here. Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/80211mgr.c | 44 ++++++++-------- drivers/staging/vt6656/80211mgr.h | 44 ++++++++-------- drivers/staging/vt6656/baseband.c | 22 ++++---- drivers/staging/vt6656/baseband.h | 22 ++++---- drivers/staging/vt6656/bssdb.c | 46 ++++++++-------- drivers/staging/vt6656/bssdb.h | 18 +++---- drivers/staging/vt6656/card.c | 42 +++++++-------- drivers/staging/vt6656/card.h | 34 ++++++------ drivers/staging/vt6656/channel.c | 2 +- drivers/staging/vt6656/channel.h | 2 +- drivers/staging/vt6656/datarate.c | 31 +++++------ drivers/staging/vt6656/datarate.h | 8 +-- drivers/staging/vt6656/device.h | 8 +-- drivers/staging/vt6656/dpc.c | 20 +++---- drivers/staging/vt6656/dpc.h | 12 ++--- drivers/staging/vt6656/int.c | 3 +- drivers/staging/vt6656/int.h | 5 +- drivers/staging/vt6656/ioctl.h | 2 +- drivers/staging/vt6656/key.c | 40 +++++++------- drivers/staging/vt6656/key.h | 28 +++++----- drivers/staging/vt6656/mac.c | 2 +- drivers/staging/vt6656/mac.h | 2 +- drivers/staging/vt6656/main_usb.c | 20 +++---- drivers/staging/vt6656/michael.c | 24 ++++----- drivers/staging/vt6656/michael.h | 8 +-- drivers/staging/vt6656/power.c | 6 +-- drivers/staging/vt6656/power.h | 6 +-- drivers/staging/vt6656/rc4.c | 4 +- drivers/staging/vt6656/rc4.h | 2 +- drivers/staging/vt6656/rf.c | 4 +- drivers/staging/vt6656/rf.h | 4 +- drivers/staging/vt6656/rxtx.c | 99 +++++++++++++++++----------------- drivers/staging/vt6656/rxtx.h | 2 +- drivers/staging/vt6656/tkip.c | 2 +- drivers/staging/vt6656/tkip.h | 2 +- drivers/staging/vt6656/ttype.h | 8 +-- drivers/staging/vt6656/usbpipe.c | 36 ++++++------- drivers/staging/vt6656/wcmd.c | 12 ++--- drivers/staging/vt6656/wcmd.h | 10 ++-- drivers/staging/vt6656/wmgr.c | 108 +++++++++++++++++++------------------- drivers/staging/vt6656/wmgr.h | 21 ++++---- drivers/staging/vt6656/wpa.c | 4 +- drivers/staging/vt6656/wpa.h | 4 +- drivers/staging/vt6656/wpa2.c | 7 ++- drivers/staging/vt6656/wpa2.h | 6 +-- 45 files changed, 409 insertions(+), 427 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/80211mgr.c b/drivers/staging/vt6656/80211mgr.c index b9dc7b1d9387..f24dc55e68f1 100644 --- a/drivers/staging/vt6656/80211mgr.c +++ b/drivers/staging/vt6656/80211mgr.c @@ -89,7 +89,7 @@ static int msglevel =MSG_LEVEL_INFO; * -*/ -VOID +void vMgrEncodeBeacon( PWLAN_FR_BEACON pFrame ) @@ -121,7 +121,7 @@ vMgrEncodeBeacon( -*/ -VOID +void vMgrDecodeBeacon( PWLAN_FR_BEACON pFrame ) @@ -242,7 +242,7 @@ vMgrDecodeBeacon( -*/ -VOID +void vMgrEncodeIBSSATIM( PWLAN_FR_IBSSATIM pFrame ) @@ -265,7 +265,7 @@ vMgrEncodeIBSSATIM( * -*/ -VOID +void vMgrDecodeIBSSATIM( PWLAN_FR_IBSSATIM pFrame ) @@ -287,7 +287,7 @@ vMgrDecodeIBSSATIM( * -*/ -VOID +void vMgrEncodeDisassociation( PWLAN_FR_DISASSOC pFrame ) @@ -315,7 +315,7 @@ vMgrEncodeDisassociation( * -*/ -VOID +void vMgrDecodeDisassociation( PWLAN_FR_DISASSOC pFrame ) @@ -341,7 +341,7 @@ vMgrDecodeDisassociation( -*/ -VOID +void vMgrEncodeAssocRequest( PWLAN_FR_ASSOCREQ pFrame ) @@ -368,7 +368,7 @@ vMgrEncodeAssocRequest( * -*/ -VOID +void vMgrDecodeAssocRequest( PWLAN_FR_ASSOCREQ pFrame ) @@ -434,7 +434,7 @@ vMgrDecodeAssocRequest( * -*/ -VOID +void vMgrEncodeAssocResponse( PWLAN_FR_ASSOCRESP pFrame ) @@ -466,7 +466,7 @@ vMgrEncodeAssocResponse( * -*/ -VOID +void vMgrDecodeAssocResponse( PWLAN_FR_ASSOCRESP pFrame ) @@ -512,7 +512,7 @@ vMgrDecodeAssocResponse( * -*/ -VOID +void vMgrEncodeReassocRequest( PWLAN_FR_REASSOCREQ pFrame ) @@ -544,7 +544,7 @@ vMgrEncodeReassocRequest( -*/ -VOID +void vMgrDecodeReassocRequest( PWLAN_FR_REASSOCREQ pFrame ) @@ -616,7 +616,7 @@ vMgrDecodeReassocRequest( -*/ -VOID +void vMgrEncodeProbeRequest( PWLAN_FR_PROBEREQ pFrame ) @@ -637,7 +637,7 @@ vMgrEncodeProbeRequest( * -*/ -VOID +void vMgrDecodeProbeRequest( PWLAN_FR_PROBEREQ pFrame ) @@ -690,7 +690,7 @@ vMgrDecodeProbeRequest( -*/ -VOID +void vMgrEncodeProbeResponse( PWLAN_FR_PROBERESP pFrame ) @@ -724,7 +724,7 @@ vMgrEncodeProbeResponse( * -*/ -VOID +void vMgrDecodeProbeResponse( PWLAN_FR_PROBERESP pFrame ) @@ -838,7 +838,7 @@ vMgrDecodeProbeResponse( * -*/ -VOID +void vMgrEncodeAuthen( PWLAN_FR_AUTHEN pFrame ) @@ -869,7 +869,7 @@ vMgrEncodeAuthen( * -*/ -VOID +void vMgrDecodeAuthen( PWLAN_FR_AUTHEN pFrame ) @@ -909,7 +909,7 @@ vMgrDecodeAuthen( * -*/ -VOID +void vMgrEncodeDeauthen( PWLAN_FR_DEAUTHEN pFrame ) @@ -936,7 +936,7 @@ vMgrEncodeDeauthen( * -*/ -VOID +void vMgrDecodeDeauthen( PWLAN_FR_DEAUTHEN pFrame ) @@ -962,7 +962,7 @@ vMgrDecodeDeauthen( * -*/ -VOID +void vMgrEncodeReassocResponse( PWLAN_FR_REASSOCRESP pFrame ) @@ -995,7 +995,7 @@ vMgrEncodeReassocResponse( -*/ -VOID +void vMgrDecodeReassocResponse( PWLAN_FR_REASSOCRESP pFrame ) diff --git a/drivers/staging/vt6656/80211mgr.h b/drivers/staging/vt6656/80211mgr.h index f7160cdd164a..50982e9f8cdf 100644 --- a/drivers/staging/vt6656/80211mgr.h +++ b/drivers/staging/vt6656/80211mgr.h @@ -748,112 +748,112 @@ typedef struct tagWLAN_FR_DEAUTHEN { } WLAN_FR_DEAUTHEN, *PWLAN_FR_DEAUTHEN; /*--------------------- Export Functions --------------------------*/ -VOID +void vMgrEncodeBeacon( PWLAN_FR_BEACON pFrame ); -VOID +void vMgrDecodeBeacon( PWLAN_FR_BEACON pFrame ); -VOID +void vMgrEncodeIBSSATIM( PWLAN_FR_IBSSATIM pFrame ); -VOID +void vMgrDecodeIBSSATIM( PWLAN_FR_IBSSATIM pFrame ); -VOID +void vMgrEncodeDisassociation( PWLAN_FR_DISASSOC pFrame ); -VOID +void vMgrDecodeDisassociation( PWLAN_FR_DISASSOC pFrame ); -VOID +void vMgrEncodeAssocRequest( PWLAN_FR_ASSOCREQ pFrame ); -VOID +void vMgrDecodeAssocRequest( PWLAN_FR_ASSOCREQ pFrame ); -VOID +void vMgrEncodeAssocResponse( PWLAN_FR_ASSOCRESP pFrame ); -VOID +void vMgrDecodeAssocResponse( PWLAN_FR_ASSOCRESP pFrame ); -VOID +void vMgrEncodeReassocRequest( PWLAN_FR_REASSOCREQ pFrame ); -VOID +void vMgrDecodeReassocRequest( PWLAN_FR_REASSOCREQ pFrame ); -VOID +void vMgrEncodeProbeRequest( PWLAN_FR_PROBEREQ pFrame ); -VOID +void vMgrDecodeProbeRequest( PWLAN_FR_PROBEREQ pFrame ); -VOID +void vMgrEncodeProbeResponse( PWLAN_FR_PROBERESP pFrame ); -VOID +void vMgrDecodeProbeResponse( PWLAN_FR_PROBERESP pFrame ); -VOID +void vMgrEncodeAuthen( PWLAN_FR_AUTHEN pFrame ); -VOID +void vMgrDecodeAuthen( PWLAN_FR_AUTHEN pFrame ); -VOID +void vMgrEncodeDeauthen( PWLAN_FR_DEAUTHEN pFrame ); -VOID +void vMgrDecodeDeauthen( PWLAN_FR_DEAUTHEN pFrame ); -VOID +void vMgrEncodeReassocResponse( PWLAN_FR_REASSOCRESP pFrame ); -VOID +void vMgrDecodeReassocResponse( PWLAN_FR_REASSOCRESP pFrame ); diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c index 9063249efd54..a52a2d84805c 100644 --- a/drivers/staging/vt6656/baseband.c +++ b/drivers/staging/vt6656/baseband.c @@ -756,7 +756,7 @@ BBuGetFrameTime ( * Return Value: none * */ -VOID +void BBvCaculateParameter ( PSDevice pDevice, UINT cbFrameLength, @@ -929,7 +929,7 @@ BBvCaculateParameter ( * Return Value: none * */ -VOID +void BBvSetAntennaMode (PSDevice pDevice, BYTE byAntennaMode) { //{{ RobertYu: 20041124, ABG Mode, VC1/VC2 define, make the ANT_A, ANT_B inverted @@ -1274,7 +1274,7 @@ void BBvLoopbackOff (PSDevice pDevice) * Return Value: none * */ -VOID +void BBvSetShortSlotTime (PSDevice pDevice) { BYTE byBBVGA=0; @@ -1295,7 +1295,7 @@ BBvSetShortSlotTime (PSDevice pDevice) } -VOID BBvSetVGAGainOffset(PSDevice pDevice, BYTE byData) +void BBvSetVGAGainOffset(PSDevice pDevice, BYTE byData) { ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xE7, byData); @@ -1324,7 +1324,7 @@ VOID BBvSetVGAGainOffset(PSDevice pDevice, BYTE byData) * Return Value: none * */ -VOID +void BBvSoftwareReset (PSDevice pDevice) { ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x50, 0x40); @@ -1345,14 +1345,14 @@ BBvSoftwareReset (PSDevice pDevice) * Return Value: none * */ -VOID +void BBvSetDeepSleep (PSDevice pDevice) { ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0c, 0x17);//CR12 ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0D, 0xB9);//CR13 } -VOID +void BBvExitDeepSleep (PSDevice pDevice) { ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0C, 0x00);//CR12 @@ -1445,7 +1445,7 @@ s_vClearSQ3Value (PSDevice pDevice) * */ -VOID +void BBvAntennaDiversity (PSDevice pDevice, BYTE byRxRate, BYTE bySQ3) { @@ -1576,7 +1576,7 @@ BBvAntennaDiversity (PSDevice pDevice, BYTE byRxRate, BYTE bySQ3) * -*/ -VOID +void TimerSQ3CallBack ( HANDLE hDeviceContext ) @@ -1618,7 +1618,7 @@ TimerSQ3CallBack ( * -*/ -VOID +void TimerSQ3Tmax3CallBack ( HANDLE hDeviceContext ) @@ -1650,7 +1650,7 @@ TimerSQ3Tmax3CallBack ( return; } -VOID +void BBvUpdatePreEDThreshold( PSDevice pDevice, BOOL bScanning) diff --git a/drivers/staging/vt6656/baseband.h b/drivers/staging/vt6656/baseband.h index 10eea90279fa..fbc2847122b3 100644 --- a/drivers/staging/vt6656/baseband.h +++ b/drivers/staging/vt6656/baseband.h @@ -104,7 +104,7 @@ BBuGetFrameTime( WORD wRate ); -VOID +void BBvCaculateParameter ( PSDevice pDevice, UINT cbFrameLength, @@ -117,28 +117,28 @@ BBvCaculateParameter ( // timer for antenna diversity -VOID +void TimerSQ3CallBack ( HANDLE hDeviceContext ); -VOID +void TimerSQ3Tmax3CallBack ( HANDLE hDeviceContext ); -VOID BBvAntennaDiversity (PSDevice pDevice, BYTE byRxRate, BYTE bySQ3); -void BBvLoopbackOn (PSDevice pDevice); -void BBvLoopbackOff (PSDevice pDevice); -void BBvSoftwareReset (PSDevice pDevice); +void BBvAntennaDiversity(PSDevice pDevice, BYTE byRxRate, BYTE bySQ3); +void BBvLoopbackOn(PSDevice pDevice); +void BBvLoopbackOff(PSDevice pDevice); +void BBvSoftwareReset(PSDevice pDevice); void BBvSetShortSlotTime(PSDevice pDevice); -VOID BBvSetVGAGainOffset(PSDevice pDevice, BYTE byData); +void BBvSetVGAGainOffset(PSDevice pDevice, BYTE byData); void BBvSetAntennaMode(PSDevice pDevice, BYTE byAntennaMode); BOOL BBbVT3184Init (PSDevice pDevice); -VOID BBvSetDeepSleep (PSDevice pDevice); -VOID BBvExitDeepSleep (PSDevice pDevice); -VOID BBvUpdatePreEDThreshold( +void BBvSetDeepSleep(PSDevice pDevice); +void BBvExitDeepSleep(PSDevice pDevice); +void BBvUpdatePreEDThreshold( PSDevice pDevice, BOOL bScanning ); diff --git a/drivers/staging/vt6656/bssdb.c b/drivers/staging/vt6656/bssdb.c index fa1ca7902055..61841b48537e 100644 --- a/drivers/staging/vt6656/bssdb.c +++ b/drivers/staging/vt6656/bssdb.c @@ -91,16 +91,16 @@ const WORD awHWRetry1[5][5] = { /*--------------------- Static Functions --------------------------*/ -VOID s_vCheckSensitivity( +void s_vCheckSensitivity( HANDLE hDeviceContext ); -VOID s_vCheckPreEDThreshold( +void s_vCheckPreEDThreshold( HANDLE hDeviceContext ); #ifdef Calcu_LinkQual -VOID s_uCalculateLinkQual( +void s_uCalculateLinkQual( HANDLE hDeviceContext ); #endif @@ -296,7 +296,7 @@ pDevice->bSameBSSMaxNum = jj; -*/ -VOID +void BSSvClearBSSList( HANDLE hDeviceContext, BOOL bKeepCurrBSSID @@ -804,7 +804,7 @@ BSSbIsSTAInNodeDB( * None * -*/ -VOID +void BSSvCreateOneNode( HANDLE hDeviceContext, OUT PUINT puNodeIndex @@ -869,7 +869,7 @@ BSSvCreateOneNode( * None * -*/ -VOID +void BSSvRemoveOneNode( HANDLE hDeviceContext, UINT uNodeIndex @@ -902,7 +902,7 @@ BSSvRemoveOneNode( * -*/ -VOID +void BSSvUpdateAPNode( HANDLE hDeviceContext, PWORD pwCapInfo, @@ -926,7 +926,7 @@ BSSvUpdateAPNode( pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pExtSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, uRateLen); - RATEvParseMaxRate((PVOID) pDevice, + RATEvParseMaxRate((void *) pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, TRUE, @@ -962,7 +962,7 @@ BSSvUpdateAPNode( -*/ -VOID +void BSSvAddMulticastNode( HANDLE hDeviceContext ) @@ -976,7 +976,7 @@ BSSvAddMulticastNode( pMgmt->sNodeDBTable[0].bActive = TRUE; pMgmt->sNodeDBTable[0].bPSEnable = FALSE; skb_queue_head_init(&pMgmt->sNodeDBTable[0].sTxPSQueue); - RATEvParseMaxRate((PVOID) pDevice, + RATEvParseMaxRate((void *) pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, TRUE, @@ -1009,7 +1009,7 @@ BSSvAddMulticastNode( -*/ -VOID +void BSSvSecondCallBack( HANDLE hDeviceContext ) @@ -1131,12 +1131,14 @@ if((pMgmt->eCurrState!=WMAC_STATE_ASSOC) && */ if (ii > 0) { // ii = 0 for multicast node (AP & Adhoc) - RATEvTxRateFallBack((PVOID)pDevice, &(pMgmt->sNodeDBTable[ii])); + RATEvTxRateFallBack((void *)pDevice, + &(pMgmt->sNodeDBTable[ii])); } else { // ii = 0 reserved for unicast AP node (Infra STA) - if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) - RATEvTxRateFallBack((PVOID)pDevice, &(pMgmt->sNodeDBTable[ii])); + if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) + RATEvTxRateFallBack((void *)pDevice, + &(pMgmt->sNodeDBTable[ii])); } } @@ -1177,14 +1179,14 @@ if((pMgmt->eCurrState!=WMAC_STATE_ASSOC) && if (pDevice->bShortSlotTime) { pDevice->bShortSlotTime = FALSE; BBvSetShortSlotTime(pDevice); - vUpdateIFS((PVOID)pDevice); + vUpdateIFS((void *)pDevice); } } else { if (!pDevice->bShortSlotTime) { pDevice->bShortSlotTime = TRUE; BBvSetShortSlotTime(pDevice); - vUpdateIFS((PVOID)pDevice); + vUpdateIFS((void *)pDevice); } } @@ -1395,7 +1397,7 @@ else { -VOID +void BSSvUpdateNodeTxCounter( HANDLE hDeviceContext, PSStatCounter pStatistic, @@ -1564,7 +1566,7 @@ BSSvUpdateNodeTxCounter( -*/ -VOID +void BSSvClearNodeDBTable( HANDLE hDeviceContext, UINT uStartIndex @@ -1593,7 +1595,7 @@ BSSvClearNodeDBTable( }; -VOID s_vCheckSensitivity( +void s_vCheckSensitivity( HANDLE hDeviceContext ) { @@ -1637,7 +1639,7 @@ VOID s_vCheckSensitivity( } #ifdef Calcu_LinkQual -VOID s_uCalculateLinkQual( +void s_uCalculateLinkQual( HANDLE hDeviceContext ) { @@ -1685,7 +1687,7 @@ else } #endif -VOID +void BSSvClearAnyBSSJoinRecord ( HANDLE hDeviceContext ) @@ -1700,7 +1702,7 @@ BSSvClearAnyBSSJoinRecord ( return; } -VOID s_vCheckPreEDThreshold( +void s_vCheckPreEDThreshold( HANDLE hDeviceContext ) { diff --git a/drivers/staging/vt6656/bssdb.h b/drivers/staging/vt6656/bssdb.h index eec6cea86071..343bfacdbe9b 100644 --- a/drivers/staging/vt6656/bssdb.h +++ b/drivers/staging/vt6656/bssdb.h @@ -246,7 +246,7 @@ BSSpAddrIsInBSSList( PWLAN_IE_SSID pSSID ); -VOID +void BSSvClearBSSList( HANDLE hDeviceContext, BOOL bKeepCurrBSSID @@ -304,13 +304,13 @@ BSSbIsSTAInNodeDB( OUT PUINT puNodeIndex ); -VOID +void BSSvCreateOneNode( HANDLE hDeviceContext, OUT PUINT puNodeIndex ); -VOID +void BSSvUpdateAPNode( HANDLE hDeviceContext, PWORD pwCapInfo, @@ -319,13 +319,13 @@ BSSvUpdateAPNode( ); -VOID +void BSSvSecondCallBack( HANDLE hDeviceContext ); -VOID +void BSSvUpdateNodeTxCounter( HANDLE hDeviceContext, PSStatCounter pStatistic, @@ -333,25 +333,25 @@ BSSvUpdateNodeTxCounter( BYTE byPktNO ); -VOID +void BSSvRemoveOneNode( HANDLE hDeviceContext, UINT uNodeIndex ); -VOID +void BSSvAddMulticastNode( HANDLE hDeviceContext ); -VOID +void BSSvClearNodeDBTable( HANDLE hDeviceContext, UINT uStartIndex ); -VOID +void BSSvClearAnyBSSJoinRecord( HANDLE hDeviceContext ); diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c index 4ad1e94ffba4..c7562a0ad834 100644 --- a/drivers/staging/vt6656/card.c +++ b/drivers/staging/vt6656/card.c @@ -95,7 +95,7 @@ const WORD cwRXBCNTSFOff[MAX_RATE] = * Return Value: TRUE if succeeded; FALSE if failed. * */ -BOOL CARDbSetMediaChannel (PVOID pDeviceHandler, UINT uConnectionChannel) +BOOL CARDbSetMediaChannel(void *pDeviceHandler, UINT uConnectionChannel) { PSDevice pDevice = (PSDevice) pDeviceHandler; BOOL bResult = TRUE; @@ -156,8 +156,7 @@ BOOL bResult = TRUE; * Return Value: response Control frame rate * */ -static -WORD swGetCCKControlRate(PVOID pDeviceHandler, WORD wRateIdx) +static WORD swGetCCKControlRate(void *pDeviceHandler, WORD wRateIdx) { PSDevice pDevice = (PSDevice) pDeviceHandler; UINT ui = (UINT)wRateIdx; @@ -183,8 +182,7 @@ WORD swGetCCKControlRate(PVOID pDeviceHandler, WORD wRateIdx) * Return Value: response Control frame rate * */ -static -WORD swGetOFDMControlRate (PVOID pDeviceHandler, WORD wRateIdx) +static WORD swGetOFDMControlRate(void *pDeviceHandler, WORD wRateIdx) { PSDevice pDevice = (PSDevice) pDeviceHandler; UINT ui = (UINT)wRateIdx; @@ -222,7 +220,7 @@ WORD swGetOFDMControlRate (PVOID pDeviceHandler, WORD wRateIdx) * Return Value: none * */ -VOID +void CARDvCaculateOFDMRParameter ( WORD wRate, BYTE byBBType, @@ -334,7 +332,7 @@ CARDvCaculateOFDMRParameter ( * Return Value: None. * */ -void CARDvSetRSPINF (PVOID pDeviceHandler, BYTE byBBType) +void CARDvSetRSPINF(void *pDeviceHandler, BYTE byBBType) { PSDevice pDevice = (PSDevice) pDeviceHandler; BYTE abyServ[4] = {0,0,0,0}; // For CCK @@ -486,7 +484,7 @@ void CARDvSetRSPINF (PVOID pDeviceHandler, BYTE byBBType) * Return Value: None. * */ -void vUpdateIFS (PVOID pDeviceHandler) +void vUpdateIFS(void *pDeviceHandler) { PSDevice pDevice = (PSDevice) pDeviceHandler; //Set SIFS, DIFS, EIFS, SlotTime, CwMin @@ -571,7 +569,7 @@ void vUpdateIFS (PVOID pDeviceHandler) &byMaxMin); } -void CARDvUpdateBasicTopRate (PVOID pDeviceHandler) +void CARDvUpdateBasicTopRate(void *pDeviceHandler) { PSDevice pDevice = (PSDevice) pDeviceHandler; BYTE byTopOFDM = RATE_24M, byTopCCK = RATE_1M; @@ -610,7 +608,7 @@ BYTE ii; * Return Value: TRUE if succeeded; FALSE if failed. * */ -BOOL CARDbAddBasicRate (PVOID pDeviceHandler, WORD wRateIdx) +BOOL CARDbAddBasicRate(void *pDeviceHandler, WORD wRateIdx) { PSDevice pDevice = (PSDevice) pDeviceHandler; WORD wRate = (WORD)(1<byTopCCKBasicRate and pDevice->byTopOFDMBasicRate - CARDbAddBasicRate((PVOID)pDevice, RATEwGetRateIdx(byRate)); + CARDbAddBasicRate((void *)pDevice, RATEwGetRateIdx(byRate)); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", RATEwGetRateIdx(byRate)); } byRate = (BYTE)(pItemRates->abyRates[ii]&0x7F); @@ -259,7 +251,7 @@ UINT uRateLen; // select highest basic rate if (WLAN_MGMT_IS_BASICRATE(pItemExtRates->abyRates[ii])) { // Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate - CARDbAddBasicRate((PVOID)pDevice, RATEwGetRateIdx(byRate)); + CARDbAddBasicRate((void *)pDevice, RATEwGetRateIdx(byRate)); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", RATEwGetRateIdx(byRate)); } byRate = (BYTE)(pItemExtRates->abyRates[ii]&0x7F); @@ -272,7 +264,8 @@ UINT uRateLen; } } //if(pItemExtRates != NULL) - if ((pDevice->byPacketType == PK_TYPE_11GB) && CARDbIsOFDMinBasicRate((PVOID)pDevice)) { + if ((pDevice->byPacketType == PK_TYPE_11GB) + && CARDbIsOFDMinBasicRate((void *)pDevice)) { pDevice->byPacketType = PK_TYPE_11GA; } @@ -284,7 +277,7 @@ UINT uRateLen; else *pwMaxBasicRate = pDevice->byTopOFDMBasicRate; if (wOldBasicRate != pDevice->wBasicRate) - CARDvSetRSPINF((PVOID)pDevice, pDevice->byBBType); + CARDvSetRSPINF((void *)pDevice, pDevice->byBBType); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Exit ParseMaxRate\n"); } @@ -308,9 +301,9 @@ UINT uRateLen; #define AUTORATE_TXCNT_THRESHOLD 20 #define AUTORATE_INC_THRESHOLD 30 -VOID -RATEvTxRateFallBack ( - PVOID pDeviceHandler, +void +RATEvTxRateFallBack( + void *pDeviceHandler, PKnownNodeDB psNodeDBTable ) { diff --git a/drivers/staging/vt6656/datarate.h b/drivers/staging/vt6656/datarate.h index 5024f716238b..da51854988bf 100644 --- a/drivers/staging/vt6656/datarate.h +++ b/drivers/staging/vt6656/datarate.h @@ -69,9 +69,9 @@ -VOID +void RATEvParseMaxRate( - PVOID pDeviceHandler, + void *pDeviceHandler, PWLAN_IE_SUPP_RATES pItemRates, PWLAN_IE_SUPP_RATES pItemExtRates, BOOL bUpdateBasicRate, @@ -82,9 +82,9 @@ RATEvParseMaxRate( OUT PBYTE pbyTopOFDMRate ); -VOID +void RATEvTxRateFallBack( - PVOID pDeviceHandler, + void *pDeviceHandler, PKnownNodeDB psNodeDBTable ); diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index 29bb5977541c..6d255ca1d6ff 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -209,9 +209,9 @@ typedef enum _CONTEXT_TYPE { // RCB (Receive Control Block) typedef struct _RCB { - PVOID Next; + void *Next; LONG Ref; - PVOID pDevice; + void *pDevice; struct urb *pUrb; SRxMgmtPacket sMngPacket; struct sk_buff* skb; @@ -222,13 +222,13 @@ typedef struct _RCB // used to track bulk out irps typedef struct _USB_SEND_CONTEXT { - PVOID pDevice; + void *pDevice; struct sk_buff *pPacket; struct urb *pUrb; UINT uBufLen; CONTEXT_TYPE Type; SEthernetHeader sEthHeader; - PVOID Next; + void *Next; BOOL bBoolInUse; UCHAR Data[MAX_TOTAL_SIZE_WITH_ALL_HEADERS]; } USB_SEND_CONTEXT, *PUSB_SEND_CONTEXT; diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index 957b7622eb68..75be9708b6c3 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -77,7 +77,7 @@ const BYTE acbyRxRate[MAX_RATE] = static BYTE s_byGetRateIdx(BYTE byRate); static -VOID +void s_vGetDASA( PBYTE pbyRxBufferAddr, OUT PUINT pcbHeaderSize, @@ -85,7 +85,7 @@ s_vGetDASA( ); static -VOID +void s_vProcessRxMACHeader ( PSDevice pDevice, PBYTE pbyRxBufferAddr, @@ -160,7 +160,7 @@ static BOOL s_bHostWepRxEncryption( * -*/ static -VOID +void s_vProcessRxMACHeader ( PSDevice pDevice, PBYTE pbyRxBufferAddr, @@ -259,7 +259,7 @@ static BYTE s_byGetRateIdx(BYTE byRate) static -VOID +void s_vGetDASA ( PBYTE pbyRxBufferAddr, OUT PUINT pcbHeaderSize, @@ -1513,10 +1513,7 @@ static BOOL s_bAPModeRxData ( -VOID -RXvWorkItem( - PVOID Context - ) +void RXvWorkItem(void *Context) { PSDevice pDevice = (PSDevice) Context; NTSTATUS ntStatus; @@ -1539,7 +1536,7 @@ RXvWorkItem( } -VOID +void RXvFreeRCB( PRCB pRCB, BOOL bReAllocSkb @@ -1579,10 +1576,7 @@ RXvFreeRCB( } -VOID -RXvMngWorkItem( - PVOID Context - ) +void RXvMngWorkItem(void *Context) { PSDevice pDevice = (PSDevice) Context; PRCB pRCB=NULL; diff --git a/drivers/staging/vt6656/dpc.h b/drivers/staging/vt6656/dpc.h index 8e6dceef2407..457db7716922 100644 --- a/drivers/staging/vt6656/dpc.h +++ b/drivers/staging/vt6656/dpc.h @@ -41,17 +41,11 @@ /*--------------------- Export Functions --------------------------*/ -VOID -RXvWorkItem( - PVOID Context - ); +void RXvWorkItem(void *Context); -VOID -RXvMngWorkItem( - PVOID Context - ); +void RXvMngWorkItem(void *Context); -VOID +void RXvFreeRCB( PRCB pRCB, BOOL bReAllocSkb diff --git a/drivers/staging/vt6656/int.c b/drivers/staging/vt6656/int.c index a47eeb069300..2ba20893ce73 100644 --- a/drivers/staging/vt6656/int.c +++ b/drivers/staging/vt6656/int.c @@ -79,8 +79,7 @@ static int msglevel = MSG_LEVEL_INFO; * if we've gotten no data * -*/ -VOID -INTvWorkItem(PVOID Context) +void INTvWorkItem(void *Context) { PSDevice pDevice = (PSDevice) Context; NTSTATUS ntStatus; diff --git a/drivers/staging/vt6656/int.h b/drivers/staging/vt6656/int.h index c3476cff5429..20c96f550688 100644 --- a/drivers/staging/vt6656/int.h +++ b/drivers/staging/vt6656/int.h @@ -67,10 +67,7 @@ SINTData, *PSINTData; /*--------------------- Export Functions --------------------------*/ -VOID -INTvWorkItem( - PVOID Context - ); +void INTvWorkItem(void *Context); NTSTATUS INTnsProcessData( diff --git a/drivers/staging/vt6656/ioctl.h b/drivers/staging/vt6656/ioctl.h index d3f49d444164..46eb699a71ea 100644 --- a/drivers/staging/vt6656/ioctl.h +++ b/drivers/staging/vt6656/ioctl.h @@ -43,7 +43,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq); /* -VOID vConfigWEPKey ( +void vConfigWEPKey ( PSDevice pDevice, DWORD dwKeyIndex, PBYTE pbyKey, diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c index 6cdc85e8352d..338ec087f737 100644 --- a/drivers/staging/vt6656/key.c +++ b/drivers/staging/vt6656/key.c @@ -60,8 +60,8 @@ static int msglevel =MSG_LEVEL_INFO; /*--------------------- Static Variables --------------------------*/ /*--------------------- Static Functions --------------------------*/ -static VOID -s_vCheckKeyTableValid (PVOID pDeviceHandler, PSKeyManagement pTable) +static void s_vCheckKeyTableValid(void *pDeviceHandler, + PSKeyManagement pTable) { PSDevice pDevice = (PSDevice) pDeviceHandler; int i; @@ -112,7 +112,7 @@ s_vCheckKeyTableValid (PVOID pDeviceHandler, PSKeyManagement pTable) * Return Value: none * */ -VOID KeyvInitTable(PVOID pDeviceHandler, PSKeyManagement pTable) +void KeyvInitTable(void *pDeviceHandler, PSKeyManagement pTable) { PSDevice pDevice = (PSDevice) pDeviceHandler; int i; @@ -123,10 +123,12 @@ VOID KeyvInitTable(PVOID pDeviceHandler, PSKeyManagement pTable) for (i=0;iKeyTable[i].bInUse = FALSE; pTable->KeyTable[i].PairwiseKey.bKeyValid = FALSE; - pTable->KeyTable[i].PairwiseKey.pvKeyTable = (PVOID)&pTable->KeyTable[i]; + pTable->KeyTable[i].PairwiseKey.pvKeyTable = + (void *)&pTable->KeyTable[i]; for (jj=0; jj < MAX_GROUP_KEY; jj++) { pTable->KeyTable[i].GroupKey[jj].bKeyValid = FALSE; - pTable->KeyTable[i].GroupKey[jj].pvKeyTable = (PVOID) &(pTable->KeyTable[i]); + pTable->KeyTable[i].GroupKey[jj].pvKeyTable = + (void *) &(pTable->KeyTable[i]); } pTable->KeyTable[i].wKeyCtl = 0; pTable->KeyTable[i].dwGTKeyIndex = 0; @@ -220,8 +222,8 @@ BOOL KeybGetKey ( * Return Value: TRUE if success otherwise FALSE * */ -BOOL KeybSetKey ( - PVOID pDeviceHandler, +BOOL KeybSetKey( + void *pDeviceHandler, PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyIndex, @@ -393,8 +395,8 @@ BOOL KeybSetKey ( * Return Value: TRUE if success otherwise FALSE * */ -BOOL KeybRemoveKey ( - PVOID pDeviceHandler, +BOOL KeybRemoveKey( + void *pDeviceHandler, PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyIndex @@ -474,8 +476,8 @@ BOOL KeybRemoveKey ( * Return Value: TRUE if success otherwise FALSE * */ -BOOL KeybRemoveAllKey ( - PVOID pDeviceHandler, +BOOL KeybRemoveAllKey( + void *pDeviceHandler, PSKeyManagement pTable, PBYTE pbyBSSID ) @@ -510,8 +512,8 @@ BOOL KeybRemoveAllKey ( * Return Value: TRUE if success otherwise FALSE * */ -VOID KeyvRemoveWEPKey ( - PVOID pDeviceHandler, +void KeyvRemoveWEPKey( + void *pDeviceHandler, PSKeyManagement pTable, DWORD dwKeyIndex ) @@ -533,8 +535,8 @@ VOID KeyvRemoveWEPKey ( return; } -VOID KeyvRemoveAllWEPKey ( - PVOID pDeviceHandler, +void KeyvRemoveAllWEPKey( + void *pDeviceHandler, PSKeyManagement pTable ) { @@ -675,8 +677,8 @@ BOOL KeybCheckPairewiseKey ( * Return Value: TRUE if success otherwise FALSE * */ -BOOL KeybSetDefaultKey ( - PVOID pDeviceHandler, +BOOL KeybSetDefaultKey( + void *pDeviceHandler, PSKeyManagement pTable, DWORD dwKeyIndex, ULONG uKeyLength, @@ -783,8 +785,8 @@ BOOL KeybSetDefaultKey ( * Return Value: TRUE if success otherwise FALSE * */ -BOOL KeybSetAllGroupKey ( - PVOID pDeviceHandler, +BOOL KeybSetAllGroupKey( + void *pDeviceHandler, PSKeyManagement pTable, DWORD dwKeyIndex, ULONG uKeyLength, diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h index 11236e848d9b..7aec57b6f61b 100644 --- a/drivers/staging/vt6656/key.h +++ b/drivers/staging/vt6656/key.h @@ -66,7 +66,7 @@ typedef struct tagSKeyItem BYTE byCipherSuite; BYTE byReserved0; DWORD dwKeyIndex; - PVOID pvKeyTable; + void *pvKeyTable; } SKeyItem, *PSKeyItem; //64 typedef struct tagSKeyTable @@ -97,7 +97,7 @@ typedef struct tagSKeyManagement /*--------------------- Export Functions --------------------------*/ -VOID KeyvInitTable(PVOID pDeviceHandler, PSKeyManagement pTable); +void KeyvInitTable(void *pDeviceHandler, PSKeyManagement pTable); BOOL KeybGetKey( PSKeyManagement pTable, @@ -107,7 +107,7 @@ BOOL KeybGetKey( ); BOOL KeybSetKey( - PVOID pDeviceHandler, + void *pDeviceHandler, PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyIndex, @@ -118,26 +118,26 @@ BOOL KeybSetKey( ); BOOL KeybRemoveKey( - PVOID pDeviceHandler, + void *pDeviceHandler, PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyIndex ); -BOOL KeybRemoveAllKey ( - PVOID pDeviceHandler, +BOOL KeybRemoveAllKey( + void *pDeviceHandler, PSKeyManagement pTable, PBYTE pbyBSSID ); -VOID KeyvRemoveWEPKey( - PVOID pDeviceHandler, +void KeyvRemoveWEPKey( + void *pDeviceHandler, PSKeyManagement pTable, DWORD dwKeyIndex ); -VOID KeyvRemoveAllWEPKey( - PVOID pDeviceHandler, +void KeyvRemoveAllWEPKey( + void *pDeviceHandler, PSKeyManagement pTable ); @@ -153,8 +153,8 @@ BOOL KeybCheckPairewiseKey( OUT PSKeyItem *pKey ); -BOOL KeybSetDefaultKey ( - PVOID pDeviceHandler, +BOOL KeybSetDefaultKey( + void *pDeviceHandler, PSKeyManagement pTable, DWORD dwKeyIndex, ULONG uKeyLength, @@ -163,8 +163,8 @@ BOOL KeybSetDefaultKey ( BYTE byKeyDecMode ); -BOOL KeybSetAllGroupKey ( - PVOID pDeviceHandler, +BOOL KeybSetAllGroupKey( + void *pDeviceHandler, PSKeyManagement pTable, DWORD dwKeyIndex, ULONG uKeyLength, diff --git a/drivers/staging/vt6656/mac.c b/drivers/staging/vt6656/mac.c index 55a798668fa5..71f09663e65d 100644 --- a/drivers/staging/vt6656/mac.c +++ b/drivers/staging/vt6656/mac.c @@ -110,7 +110,7 @@ void MACvSetMultiAddrByHash (PSDevice pDevice, BYTE byHashIdx) * Return Value: none * */ -VOID MACvWriteMultiAddr (PSDevice pDevice, UINT uByteIdx, BYTE byData) +void MACvWriteMultiAddr(PSDevice pDevice, UINT uByteIdx, BYTE byData) { BYTE byData1; diff --git a/drivers/staging/vt6656/mac.h b/drivers/staging/vt6656/mac.h index fe99e3df2a51..1a7c2f5cff0e 100644 --- a/drivers/staging/vt6656/mac.h +++ b/drivers/staging/vt6656/mac.h @@ -421,7 +421,7 @@ /*--------------------- Export Functions --------------------------*/ void MACvSetMultiAddrByHash (PSDevice pDevice, BYTE byHashIdx); -VOID MACvWriteMultiAddr (PSDevice pDevice, UINT uByteIdx, BYTE byData); +void MACvWriteMultiAddr(PSDevice pDevice, UINT uByteIdx, BYTE byData); BOOL MACbShutdown(PSDevice pDevice);; void MACvSetBBType(PSDevice pDevice,BYTE byType); void MACvSetMISCFifo (PSDevice pDevice, WORD wOffset, DWORD dwData); diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index ebd7a1ebce8c..2fcaf70aa465 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -331,8 +331,8 @@ device_set_options(PSDevice pDevice) { } -static VOID device_init_diversity_timer(PSDevice pDevice) { - +static void device_init_diversity_timer(PSDevice pDevice) +{ init_timer(&pDevice->TimerSQ3Tmax1); pDevice->TimerSQ3Tmax1.data = (ULONG)pDevice; pDevice->TimerSQ3Tmax1.function = (TimerFunction)TimerSQ3CallBack; @@ -791,7 +791,7 @@ vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id) spin_lock_init(&pDevice->lock); pDevice->tx_80211 = device_dma0_tx_80211; - pDevice->sMgmtObj.pAdapter = (PVOID)pDevice; + pDevice->sMgmtObj.pAdapter = (void *)pDevice; netdev->netdev_ops = &device_netdev_ops; @@ -843,7 +843,8 @@ err_nomem: } -static VOID device_free_tx_bufs(PSDevice pDevice) { +static void device_free_tx_bufs(PSDevice pDevice) +{ PUSB_SEND_CONTEXT pTxContext; int ii; @@ -862,7 +863,8 @@ static VOID device_free_tx_bufs(PSDevice pDevice) { } -static VOID device_free_rx_bufs(PSDevice pDevice) { +static void device_free_rx_bufs(PSDevice pDevice) +{ PRCB pRCB; int ii; @@ -894,8 +896,8 @@ static void usb_device_reset(PSDevice pDevice) return ; } -static VOID device_free_int_bufs(PSDevice pDevice) { - +static void device_free_int_bufs(PSDevice pDevice) +{ if (pDevice->intBuf.pDataBuf != NULL) kfree(pDevice->intBuf.pDataBuf); return; @@ -917,7 +919,7 @@ static BOOL device_alloc_bufs(PSDevice pDevice) { goto free_tx; } pDevice->apTD[ii] = pTxContext; - pTxContext->pDevice = (PVOID) pDevice; + pTxContext->pDevice = (void *) pDevice; //allocate URBs pTxContext->pUrb = usb_alloc_urb(0, GFP_ATOMIC); if (pTxContext->pUrb == NULL) { @@ -946,7 +948,7 @@ static BOOL device_alloc_bufs(PSDevice pDevice) { for (ii = 0; ii < pDevice->cbRD; ii++) { pDevice->apRCB[ii] = pRCB; - pRCB->pDevice = (PVOID) pDevice; + pRCB->pDevice = (void *) pDevice; //allocate URBs pRCB->pUrb = usb_alloc_urb(0, GFP_ATOMIC); diff --git a/drivers/staging/vt6656/michael.c b/drivers/staging/vt6656/michael.c index d4c08209a17f..d45333fc2420 100644 --- a/drivers/staging/vt6656/michael.c +++ b/drivers/staging/vt6656/michael.c @@ -50,14 +50,14 @@ /* * static DWORD s_dwGetUINT32(BYTE * p); Get DWORD from * 4 bytes LSByte first - * static VOID s_vPutUINT32(BYTE* p, DWORD val); Put DWORD into + * static void s_vPutUINT32(BYTE* p, DWORD val); Put DWORD into * 4 bytes LSByte first */ -static VOID s_vClear(void); /* Clear the internal message, +static void s_vClear(void); /* Clear the internal message, * resets the object to the * state just after construction. */ -static VOID s_vSetKey(DWORD dwK0, DWORD dwK1); -static VOID s_vAppendByte(BYTE b); /* Add a single byte to the internal +static void s_vSetKey(DWORD dwK0, DWORD dwK1); +static void s_vAppendByte(BYTE b); /* Add a single byte to the internal * message */ /*--------------------- Export Variables --------------------------*/ @@ -79,7 +79,7 @@ static DWORD s_dwGetUINT32 (BYTE * p) return res; } -static VOID s_vPutUINT32 (BYTE* p, DWORD val) +static void s_vPutUINT32(BYTE *p, DWORD val) // Convert from DWORD to BYTE[] in a portable way { UINT i; @@ -90,7 +90,7 @@ static VOID s_vPutUINT32 (BYTE* p, DWORD val) } */ -static VOID s_vClear(void) +static void s_vClear(void) { /* Reset the state to the empty message. */ L = K0; @@ -99,7 +99,7 @@ static VOID s_vClear(void) M = 0; } -static VOID s_vSetKey(DWORD dwK0, DWORD dwK1) +static void s_vSetKey(DWORD dwK0, DWORD dwK1) { /* Set the key */ K0 = dwK0; @@ -108,7 +108,7 @@ static VOID s_vSetKey(DWORD dwK0, DWORD dwK1) s_vClear(); } -static VOID s_vAppendByte(BYTE b) +static void s_vAppendByte(BYTE b) { /* Append the byte to our word-sized buffer */ M |= b << (8*nBytesInM); @@ -130,14 +130,14 @@ static VOID s_vAppendByte(BYTE b) } } -VOID MIC_vInit(DWORD dwK0, DWORD dwK1) +void MIC_vInit(DWORD dwK0, DWORD dwK1) { /* Set the key */ s_vSetKey(dwK0, dwK1); } -VOID MIC_vUnInit(void) +void MIC_vUnInit(void) { /* Wipe the key material */ K0 = 0; @@ -148,7 +148,7 @@ VOID MIC_vUnInit(void) s_vClear(); } -VOID MIC_vAppend(PBYTE src, UINT nBytes) +void MIC_vAppend(PBYTE src, UINT nBytes) { /* This is simple */ while (nBytes > 0) { @@ -157,7 +157,7 @@ VOID MIC_vAppend(PBYTE src, UINT nBytes) } } -VOID MIC_vGetMIC(PDWORD pdwL, PDWORD pdwR) +void MIC_vGetMIC(PDWORD pdwL, PDWORD pdwR) { /* Append the minimum padding */ s_vAppendByte(0x5a); diff --git a/drivers/staging/vt6656/michael.h b/drivers/staging/vt6656/michael.h index 3f79b52832d1..97de77b4da2c 100644 --- a/drivers/staging/vt6656/michael.h +++ b/drivers/staging/vt6656/michael.h @@ -35,16 +35,16 @@ /*--------------------- Export Types ------------------------------*/ -VOID MIC_vInit(DWORD dwK0, DWORD dwK1); +void MIC_vInit(DWORD dwK0, DWORD dwK1); -VOID MIC_vUnInit(void); +void MIC_vUnInit(void); // Append bytes to the message to be MICed -VOID MIC_vAppend(PBYTE src, UINT nBytes); +void MIC_vAppend(PBYTE src, UINT nBytes); // Get the MIC result. Destination should accept 8 bytes of result. // This also resets the message to empty. -VOID MIC_vGetMIC(PDWORD pdwL, PDWORD pdwR); +void MIC_vGetMIC(PDWORD pdwL, PDWORD pdwR); /*--------------------- Export Macros ------------------------------*/ diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c index e50093e355a9..05d51fbb00b1 100644 --- a/drivers/staging/vt6656/power.c +++ b/drivers/staging/vt6656/power.c @@ -76,7 +76,7 @@ static int msglevel =MSG_LEVEL_INFO; -*/ -VOID +void PSvEnablePowerSaving( HANDLE hDeviceContext, WORD wListenInterval @@ -154,7 +154,7 @@ PSvEnablePowerSaving( * -*/ -VOID +void PSvDisablePowerSaving( HANDLE hDeviceContext ) @@ -262,7 +262,7 @@ PSbConsiderPowerDown( -VOID +void PSvSendPSPOLL( HANDLE hDeviceContext ) diff --git a/drivers/staging/vt6656/power.h b/drivers/staging/vt6656/power.h index 0a14811ced97..e83ac4ecf6d0 100644 --- a/drivers/staging/vt6656/power.h +++ b/drivers/staging/vt6656/power.h @@ -55,18 +55,18 @@ PSbConsiderPowerDown( BOOL bCheckCountToWakeUp ); -VOID +void PSvDisablePowerSaving( HANDLE hDeviceContext ); -VOID +void PSvEnablePowerSaving( HANDLE hDeviceContext, WORD wListenInterval ); -VOID +void PSvSendPSPOLL( HANDLE hDeviceContext ); diff --git a/drivers/staging/vt6656/rc4.c b/drivers/staging/vt6656/rc4.c index 64c419df9321..487f1dcfd8c4 100644 --- a/drivers/staging/vt6656/rc4.c +++ b/drivers/staging/vt6656/rc4.c @@ -32,7 +32,7 @@ #include "rc4.h" -VOID rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len) +void rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len) { UINT ust1, ust2; UINT keyindex; @@ -78,7 +78,7 @@ UINT rc4_byte(PRC4Ext pRC4) return pbyst[(ustx + usty) & 0xff]; } -VOID rc4_encrypt(PRC4Ext pRC4, PBYTE pbyDest, +void rc4_encrypt(PRC4Ext pRC4, PBYTE pbyDest, PBYTE pbySrc, UINT cbData_len) { UINT ii; diff --git a/drivers/staging/vt6656/rc4.h b/drivers/staging/vt6656/rc4.h index bf607c9d446a..e65cae69efaf 100644 --- a/drivers/staging/vt6656/rc4.h +++ b/drivers/staging/vt6656/rc4.h @@ -40,7 +40,7 @@ typedef struct { BYTE abystate[256]; } RC4Ext, *PRC4Ext; -VOID rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len); +void rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len); UINT rc4_byte(PRC4Ext pRC4); void rc4_encrypt(PRC4Ext pRC4, PBYTE pbyDest, PBYTE pbySrc, UINT cbData_len); diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c index d69925ff469b..1126cb48f4a1 100644 --- a/drivers/staging/vt6656/rf.c +++ b/drivers/staging/vt6656/rf.c @@ -954,7 +954,7 @@ BOOL bResult = TRUE; * Return Value: none * -*/ -VOID +void RFvRSSITodBm ( PSDevice pDevice, BYTE byCurrRSSI, @@ -984,7 +984,7 @@ RFvRSSITodBm ( -VOID +void RFbRFTableDownload ( PSDevice pDevice ) diff --git a/drivers/staging/vt6656/rf.h b/drivers/staging/vt6656/rf.h index 22159869364e..6c3faf8adc8b 100644 --- a/drivers/staging/vt6656/rf.h +++ b/drivers/staging/vt6656/rf.h @@ -76,14 +76,14 @@ BOOL RFbRawSetPower( UINT uRATE ); -VOID +void RFvRSSITodBm ( PSDevice pDevice, BYTE byCurrRSSI, long * pldBm ); -VOID +void RFbRFTableDownload ( PSDevice pDevice ); diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index 1d7ca2286248..9ddb7e1c2546 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -113,7 +113,7 @@ const WORD wFB_Opt1[2][5] = { /*--------------------- Static Functions --------------------------*/ static -VOID +void s_vSaveTxPktInfo( PSDevice pDevice, BYTE byPktNum, @@ -123,22 +123,22 @@ s_vSaveTxPktInfo( ); static -PVOID +void * s_vGetFreeContext( PSDevice pDevice ); static -VOID +void s_vGenerateTxParameter( PSDevice pDevice, BYTE byPktType, WORD wCurrentRate, - PVOID pTxBufHead, - PVOID pvRrvTime, - PVOID pvRTS, - PVOID pvCTS, + void *pTxBufHead, + void *pvRrvTime, + void *pvRTS, + void *pvCTS, UINT cbFrameSize, BOOL bNeedACK, UINT uDMAIdx, @@ -152,7 +152,7 @@ s_uFillDataHead ( PSDevice pDevice, BYTE byPktType, WORD wCurrentRate, - PVOID pTxDataHead, + void *pTxDataHead, UINT cbFrameLength, UINT uDMAIdx, BOOL bNeedAck, @@ -166,7 +166,7 @@ s_uFillDataHead ( static -VOID +void s_vGenerateMACHeader ( PSDevice pDevice, PBYTE pbyBufferAddr, @@ -179,7 +179,7 @@ s_vGenerateMACHeader ( ); static -VOID +void s_vFillTxKey( PSDevice pDevice, PBYTE pbyBuf, @@ -191,7 +191,7 @@ s_vFillTxKey( ); static -VOID +void s_vSWencryption ( PSDevice pDevice, PSKeyItem pTransmitKey, @@ -221,12 +221,12 @@ s_uGetRTSCTSRsvTime ( ); static -VOID +void s_vFillCTSHead ( PSDevice pDevice, UINT uDMAIdx, BYTE byPktType, - PVOID pvCTS, + void *pvCTS, UINT cbFrameLength, BOOL bNeedAck, BOOL bDisCRC, @@ -235,11 +235,11 @@ s_vFillCTSHead ( ); static -VOID +void s_vFillRTSHead( PSDevice pDevice, BYTE byPktType, - PVOID pvRTS, + void *pvRTS, UINT cbFrameLength, BOOL bNeedAck, BOOL bDisCRC, @@ -280,7 +280,7 @@ s_uGetRTSCTSDuration ( /*--------------------- Export Variables --------------------------*/ static -PVOID +void * s_vGetFreeContext( PSDevice pDevice ) @@ -302,12 +302,12 @@ s_vGetFreeContext( if ( ii == pDevice->cbTD ) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Free Tx Context\n"); } - return ((PVOID) pReturnContext); + return (void *) pReturnContext; } static -VOID +void s_vSaveTxPktInfo(PSDevice pDevice, BYTE byPktNum, PBYTE pbyDestAddr, WORD wPktLength, WORD wFIFOCtl) { PSStatCounter pStatistic=&(pDevice->scStatistic); @@ -331,7 +331,7 @@ s_vSaveTxPktInfo(PSDevice pDevice, BYTE byPktNum, PBYTE pbyDestAddr, WORD wPktLe static -VOID +void s_vFillTxKey ( PSDevice pDevice, PBYTE pbyBuf, @@ -448,7 +448,7 @@ s_vFillTxKey ( static -VOID +void s_vSWencryption ( PSDevice pDevice, PSKeyItem pTransmitKey, @@ -841,7 +841,7 @@ s_uFillDataHead ( PSDevice pDevice, BYTE byPktType, WORD wCurrentRate, - PVOID pTxDataHead, + void *pTxDataHead, UINT cbFrameLength, UINT uDMAIdx, BOOL bNeedAck, @@ -981,11 +981,11 @@ s_uFillDataHead ( static -VOID +void s_vFillRTSHead ( PSDevice pDevice, BYTE byPktType, - PVOID pvRTS, + void *pvRTS, UINT cbFrameLength, BOOL bNeedAck, BOOL bDisCRC, @@ -1209,12 +1209,12 @@ s_vFillRTSHead ( } static -VOID +void s_vFillCTSHead ( PSDevice pDevice, UINT uDMAIdx, BYTE byPktType, - PVOID pvCTS, + void *pvCTS, UINT cbFrameLength, BOOL bNeedAck, BOOL bDisCRC, @@ -1309,15 +1309,15 @@ s_vFillCTSHead ( -*/ // UINT cbFrameSize,//Hdr+Payload+FCS static -VOID +void s_vGenerateTxParameter ( PSDevice pDevice, BYTE byPktType, WORD wCurrentRate, - PVOID pTxBufHead, - PVOID pvRrvTime, - PVOID pvRTS, - PVOID pvCTS, + void *pTxBufHead, + void *pvRrvTime, + void *pvRTS, + void *pvCTS, UINT cbFrameSize, BOOL bNeedACK, UINT uDMAIdx, @@ -1455,11 +1455,11 @@ s_bPacketToWirelessUsb( BYTE abySNAP_Bridgetunnel[6] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8}; UINT uDuration; UINT cbHeaderLength= 0,uPadding = 0; - PVOID pvRrvTime; + void *pvRrvTime; PSMICHDRHead pMICHDR; - PVOID pvRTS; - PVOID pvCTS; - PVOID pvTxDataHd; + void *pvRTS; + void *pvCTS; + void *pvTxDataHd; BYTE byFBOption = AUTO_FB_NONE,byFragType; WORD wTxBufSize; DWORD dwMICKey0,dwMICKey1,dwMIC_Priority,dwCRC; @@ -1694,7 +1694,8 @@ s_bPacketToWirelessUsb( //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate, (PVOID)pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS, + s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate, + (void *)pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS, cbFrameSize, bNeedACK, uDMAIdx, psEthHeader); //Fill DataHead uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK, @@ -1856,7 +1857,7 @@ s_bPacketToWirelessUsb( * -*/ -VOID +void s_vGenerateMACHeader ( PSDevice pDevice, PBYTE pbyBufferAddr, @@ -1964,9 +1965,9 @@ CMD_STATUS csMgmt_xmit( { BYTE byPktType; PBYTE pbyTxBufferAddr; - PVOID pvRTS; + void *pvRTS; PSCTS pCTS; - PVOID pvTxDataHd; + void *pvTxDataHd; UINT uDuration; UINT cbReqCount; PS802_11Header pMACHeader; @@ -1984,8 +1985,8 @@ CMD_STATUS csMgmt_xmit( WORD wTxBufSize; UINT cbMacHdLen; SEthernetHeader sEthHeader; - PVOID pvRrvTime; - PVOID pMICHDR; + void *pvRrvTime; + void *pMICHDR; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); WORD wCurrentRate = RATE_1M; PTX_BUFFER pTX_Buffer; @@ -2137,7 +2138,8 @@ CMD_STATUS csMgmt_xmit( cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + sizeof(STxDataHead_ab); } - memset((PVOID)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); + memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, + (cbHeaderSize - wTxBufSize)); memcpy(&(sEthHeader.abyDstAddr[0]), &(pPacket->p80211Header->sA3.abyAddr1[0]), @@ -2342,15 +2344,15 @@ csBeacon_xmit( -VOID +void vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); BYTE byPktType; PBYTE pbyTxBufferAddr; - PVOID pvRTS; - PVOID pvCTS; - PVOID pvTxDataHd; + void *pvRTS; + void *pvCTS; + void *pvTxDataHd; UINT uDuration; UINT cbReqCount; PS802_11Header pMACHeader; @@ -2374,8 +2376,8 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb) { WORD wTxBufSize; UINT cbMacHdLen; SEthernetHeader sEthHeader; - PVOID pvRrvTime; - PVOID pMICHDR; + void *pvRrvTime; + void *pMICHDR; WORD wCurrentRate = RATE_1M; PUWLAN_80211HDR p80211Header; UINT uNodeIndex = 0; @@ -2574,7 +2576,8 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb) { pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR); cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab); } - memset((PVOID)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); + memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, + (cbHeaderSize - wTxBufSize)); memcpy(&(sEthHeader.abyDstAddr[0]), &(p80211Header->sA3.abyAddr1[0]), ETH_ALEN); diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h index 1160c0354f3f..7c7e078495c8 100644 --- a/drivers/staging/vt6656/rxtx.h +++ b/drivers/staging/vt6656/rxtx.h @@ -682,7 +682,7 @@ bPacketToWirelessUsb( OUT UINT *pcbTotalLen ); -VOID vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb); +void vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb); NTSTATUS nsDMA_tx_packet(PSDevice pDevice, UINT uDMAIdx, struct sk_buff *skb); CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket); CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket); diff --git a/drivers/staging/vt6656/tkip.c b/drivers/staging/vt6656/tkip.c index 8ca154080e98..f83af5913aa6 100644 --- a/drivers/staging/vt6656/tkip.c +++ b/drivers/staging/vt6656/tkip.c @@ -183,7 +183,7 @@ unsigned int rotr1(unsigned int a) * Return Value: none * */ -VOID TKIPvMixKey( +void TKIPvMixKey( PBYTE pbyTKey, PBYTE pbyTA, WORD wTSC15_0, diff --git a/drivers/staging/vt6656/tkip.h b/drivers/staging/vt6656/tkip.h index 847ecdf97ee8..3dfa7f5ee7ec 100644 --- a/drivers/staging/vt6656/tkip.h +++ b/drivers/staging/vt6656/tkip.h @@ -46,7 +46,7 @@ /*--------------------- Export Functions --------------------------*/ -VOID TKIPvMixKey( +void TKIPvMixKey( PBYTE pbyTKey, PBYTE pbyTA, WORD wTSC15_0, diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h index 2365fa411393..5bbd4e37256a 100644 --- a/drivers/staging/vt6656/ttype.h +++ b/drivers/staging/vt6656/ttype.h @@ -33,10 +33,6 @@ /******* Common definitions and typedefs ***********************************/ -#ifndef VOID -#define VOID void -#endif - #ifndef OUT #define OUT #endif @@ -146,13 +142,11 @@ typedef DWORD * PDWORD; typedef QWORD * PQWORD; -typedef void * PVOID; - // handle declaration #ifdef STRICT typedef void *HANDLE; #else -typedef PVOID HANDLE; +typedef void *HANDLE; #endif #endif // __TTYPE_H__ diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c index 901c684b11e9..7c325728b836 100644 --- a/drivers/staging/vt6656/usbpipe.c +++ b/drivers/staging/vt6656/usbpipe.c @@ -71,34 +71,34 @@ static int msglevel =MSG_LEVEL_INFO; /*--------------------- Static Functions --------------------------*/ static -VOID +void s_nsInterruptUsbIoCompleteRead( struct urb *urb ); static -VOID +void s_nsBulkInUsbIoCompleteRead( struct urb *urb ); static -VOID +void s_nsBulkOutIoCompleteWrite( struct urb *urb ); static -VOID +void s_nsControlInUsbIoCompleteRead( struct urb *urb ); static -VOID +void s_nsControlInUsbIoCompleteWrite( struct urb *urb ); @@ -142,7 +142,7 @@ PIPEnsControlOutAsyn( 0x40, // RequestType wValue, wIndex, - (PVOID) pbyBuffer, + (void *) pbyBuffer, wLength, HZ ); @@ -279,7 +279,7 @@ PIPEnsControlIn( } static -VOID +void s_nsControlInUsbIoCompleteWrite( struct urb *urb ) @@ -320,7 +320,7 @@ s_nsControlInUsbIoCompleteWrite( * */ static -VOID +void s_nsControlInUsbIoCompleteRead( struct urb *urb ) @@ -385,7 +385,7 @@ PIPEnsInterruptRead( usb_fill_int_urb(pDevice->pInterruptURB, pDevice->usb, usb_rcvintpipe(pDevice->usb, 1), - (PVOID) pDevice->intBuf.pDataBuf, + (void *) pDevice->intBuf.pDataBuf, MAX_INTERRUPT_SIZE, s_nsInterruptUsbIoCompleteRead, pDevice, @@ -396,7 +396,7 @@ PIPEnsInterruptRead( usb_fill_int_urb(pDevice->pInterruptURB, pDevice->usb, usb_rcvintpipe(pDevice->usb, 1), - (PVOID) pDevice->intBuf.pDataBuf, + (void *) pDevice->intBuf.pDataBuf, MAX_INTERRUPT_SIZE, s_nsInterruptUsbIoCompleteRead, pDevice, @@ -409,7 +409,7 @@ PIPEnsInterruptRead( usb_fill_bulk_urb(pDevice->pInterruptURB, pDevice->usb, usb_rcvbulkpipe(pDevice->usb, 1), - (PVOID) pDevice->intBuf.pDataBuf, + (void *) pDevice->intBuf.pDataBuf, MAX_INTERRUPT_SIZE, s_nsInterruptUsbIoCompleteRead, pDevice); @@ -441,7 +441,7 @@ usb_fill_bulk_urb(pDevice->pInterruptURB, * */ static -VOID +void s_nsInterruptUsbIoCompleteRead( struct urb *urb ) @@ -506,7 +506,7 @@ s_nsInterruptUsbIoCompleteRead( usb_fill_bulk_urb(pDevice->pInterruptURB, pDevice->usb, usb_rcvbulkpipe(pDevice->usb, 1), - (PVOID) pDevice->intBuf.pDataBuf, + (void *) pDevice->intBuf.pDataBuf, MAX_INTERRUPT_SIZE, s_nsInterruptUsbIoCompleteRead, pDevice); @@ -572,7 +572,7 @@ PIPEnsBulkInUsbRead( usb_fill_bulk_urb(pUrb, pDevice->usb, usb_rcvbulkpipe(pDevice->usb, 2), - (PVOID) (pRCB->skb->data), + (void *) (pRCB->skb->data), MAX_TOTAL_SIZE_WITH_ALL_HEADERS, s_nsBulkInUsbIoCompleteRead, pRCB); @@ -606,7 +606,7 @@ PIPEnsBulkInUsbRead( * */ static -VOID +void s_nsBulkInUsbIoCompleteRead( struct urb *urb ) @@ -718,8 +718,8 @@ PIPEnsSendBulkOut( usb_fill_bulk_urb( pUrb, pDevice->usb, - usb_sndbulkpipe(pDevice->usb, 3), - (PVOID) &(pContext->Data[0]), + usb_sndbulkpipe(pDevice->usb, 3), + (void *) &(pContext->Data[0]), pContext->uBufLen, s_nsBulkOutIoCompleteWrite, pContext); @@ -766,7 +766,7 @@ PIPEnsSendBulkOut( * */ static -VOID +void s_nsBulkOutIoCompleteWrite( struct urb *urb ) diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c index 7e543396536e..23db5f63c789 100644 --- a/drivers/staging/vt6656/wcmd.c +++ b/drivers/staging/vt6656/wcmd.c @@ -69,7 +69,7 @@ static int msglevel =MSG_LEVEL_INFO; /*--------------------- Static Functions --------------------------*/ static -VOID +void s_vProbeChannel( PSDevice pDevice ); @@ -210,7 +210,7 @@ vAdHocBeaconRestart(PSDevice pDevice) -*/ static -VOID +void s_vProbeChannel( PSDevice pDevice ) @@ -325,7 +325,7 @@ s_MgrMakeProbeRequest( -VOID +void vCommandTimerWait( HANDLE hDeviceContext, UINT MSecond @@ -345,7 +345,7 @@ vCommandTimerWait( -VOID +void vRunCommand( HANDLE hDeviceContext ) @@ -1287,7 +1287,7 @@ BOOL s_bClearBSSID_SCAN ( //mike add:reset command timer -VOID +void vResetCommandTimer( HANDLE hDeviceContext ) @@ -1311,7 +1311,7 @@ vResetCommandTimer( //2007-0115-08by MikeLiu #ifdef TxInSleep -VOID +void BSSvSecondTxData( HANDLE hDeviceContext ) diff --git a/drivers/staging/vt6656/wcmd.h b/drivers/staging/vt6656/wcmd.h index 28c0aa559c97..f3eac0353602 100644 --- a/drivers/staging/vt6656/wcmd.h +++ b/drivers/staging/vt6656/wcmd.h @@ -116,7 +116,7 @@ typedef enum tagCMD_STATE { /*--------------------- Export Functions --------------------------*/ -VOID +void vResetCommandTimer( HANDLE hDeviceContext ); @@ -128,20 +128,20 @@ bScheduleCommand( PBYTE pbyItem0 ); -VOID +void vRunCommand( HANDLE hDeviceContext ); /* -VOID +void WCMDvCommandThread( - PVOID Context + void * Context ); */ //2007-0115-09by MikeLiu #ifdef TxInSleep -VOID +void BSSvSecondTxData( HANDLE hDeviceContext ); diff --git a/drivers/staging/vt6656/wmgr.c b/drivers/staging/vt6656/wmgr.c index b93cb1d2bfb2..994022aa0d62 100644 --- a/drivers/staging/vt6656/wmgr.c +++ b/drivers/staging/vt6656/wmgr.c @@ -113,7 +113,7 @@ s_MgrMakeAssocRequest( ); static -VOID +void s_vMgrRxAssocRequest( PSDevice pDevice, PSMgmtObject pMgmt, @@ -135,7 +135,7 @@ s_MgrMakeReAssocRequest( ); static -VOID +void s_vMgrRxAssocResponse( PSDevice pDevice, PSMgmtObject pMgmt, @@ -144,7 +144,7 @@ s_vMgrRxAssocResponse( ); static -VOID +void s_vMgrRxDisassociation( PSDevice pDevice, PSMgmtObject pMgmt, @@ -153,7 +153,7 @@ s_vMgrRxDisassociation( // Authentication/deauthen functions static -VOID +void s_vMgrRxAuthenSequence_1( PSDevice pDevice, PSMgmtObject pMgmt, @@ -161,7 +161,7 @@ s_vMgrRxAuthenSequence_1( ); static -VOID +void s_vMgrRxAuthenSequence_2( PSDevice pDevice, PSMgmtObject pMgmt, @@ -169,7 +169,7 @@ s_vMgrRxAuthenSequence_2( ); static -VOID +void s_vMgrRxAuthenSequence_3( PSDevice pDevice, PSMgmtObject pMgmt, @@ -177,7 +177,7 @@ s_vMgrRxAuthenSequence_3( ); static -VOID +void s_vMgrRxAuthenSequence_4( PSDevice pDevice, PSMgmtObject pMgmt, @@ -185,7 +185,7 @@ s_vMgrRxAuthenSequence_4( ); static -VOID +void s_vMgrRxAuthentication( PSDevice pDevice, PSMgmtObject pMgmt, @@ -193,7 +193,7 @@ s_vMgrRxAuthentication( ); static -VOID +void s_vMgrRxDeauthentication( PSDevice pDevice, PSMgmtObject pMgmt, @@ -203,7 +203,7 @@ s_vMgrRxDeauthentication( // Scan functions // probe request/response functions static -VOID +void s_vMgrRxProbeRequest( PSDevice pDevice, PSMgmtObject pMgmt, @@ -211,7 +211,7 @@ s_vMgrRxProbeRequest( ); static -VOID +void s_vMgrRxProbeResponse( PSDevice pDevice, PSMgmtObject pMgmt, @@ -220,7 +220,7 @@ s_vMgrRxProbeResponse( // beacon functions static -VOID +void s_vMgrRxBeacon( PSDevice pDevice, PSMgmtObject pMgmt, @@ -229,7 +229,7 @@ s_vMgrRxBeacon( ); static -VOID +void s_vMgrFormatTIM( PSMgmtObject pMgmt, PWLAN_IE_TIM pTIM @@ -299,7 +299,7 @@ s_MgrMakeProbeResponse( // received status static -VOID +void s_vMgrLogStatus( PSMgmtObject pMgmt, WORD wStatus @@ -307,7 +307,7 @@ s_vMgrLogStatus( static -VOID +void s_vMgrSynchBSS ( PSDevice pDevice, UINT uBSSMode, @@ -324,7 +324,7 @@ s_bCipherMatch ( OUT PBYTE pbyCCSGK ); - static VOID Encyption_Rebuild( + static void Encyption_Rebuild( PSDevice pDevice, PKnownBSS pCurr ); @@ -347,7 +347,7 @@ s_bCipherMatch ( * -*/ -VOID +void vMgrObjectInit( HANDLE hDeviceContext ) @@ -415,7 +415,7 @@ vMgrObjectInit( -*/ -VOID +void vMgrAssocBeginSta( HANDLE hDeviceContext, PSMgmtObject pMgmt, @@ -491,7 +491,7 @@ vMgrAssocBeginSta( * -*/ -VOID +void vMgrReAssocBeginSta( HANDLE hDeviceContext, PSMgmtObject pMgmt, @@ -570,7 +570,7 @@ vMgrReAssocBeginSta( * -*/ -VOID +void vMgrDisassocBeginSta( HANDLE hDeviceContext, PSMgmtObject pMgmt, @@ -633,7 +633,7 @@ vMgrDisassocBeginSta( -*/ static -VOID +void s_vMgrRxAssocRequest( PSDevice pDevice, PSMgmtObject pMgmt, @@ -691,7 +691,7 @@ s_vMgrRxAssocRequest( } - RATEvParseMaxRate((PVOID)pDevice, + RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)abyCurrSuppRates, (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates, FALSE, // do not change our basic rate @@ -789,7 +789,7 @@ s_vMgrRxAssocRequest( -*/ static -VOID +void s_vMgrRxReAssocRequest( PSDevice pDevice, PSMgmtObject pMgmt, @@ -844,7 +844,7 @@ s_vMgrRxReAssocRequest( } - RATEvParseMaxRate((PVOID)pDevice, + RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)abyCurrSuppRates, (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates, FALSE, // do not change our basic rate @@ -936,7 +936,7 @@ s_vMgrRxReAssocRequest( -*/ static -VOID +void s_vMgrRxAssocResponse( PSDevice pDevice, PSMgmtObject pMgmt, @@ -1102,7 +1102,7 @@ if(pMgmt->eCurrState == WMAC_STATE_ASSOC) * -*/ -VOID +void vMgrAuthenBeginSta( HANDLE hDeviceContext, PSMgmtObject pMgmt, @@ -1160,7 +1160,7 @@ vMgrAuthenBeginSta( * -*/ -VOID +void vMgrDeAuthenBeginSta( HANDLE hDeviceContext, PSMgmtObject pMgmt, @@ -1217,7 +1217,7 @@ vMgrDeAuthenBeginSta( -*/ static -VOID +void s_vMgrRxAuthentication( PSDevice pDevice, PSMgmtObject pMgmt, @@ -1275,7 +1275,7 @@ s_vMgrRxAuthentication( static -VOID +void s_vMgrRxAuthenSequence_1( PSDevice pDevice, PSMgmtObject pMgmt, @@ -1381,7 +1381,7 @@ s_vMgrRxAuthenSequence_1( -*/ static -VOID +void s_vMgrRxAuthenSequence_2( PSDevice pDevice, PSMgmtObject pMgmt, @@ -1483,7 +1483,7 @@ s_vMgrRxAuthenSequence_2( -*/ static -VOID +void s_vMgrRxAuthenSequence_3( PSDevice pDevice, PSMgmtObject pMgmt, @@ -1571,7 +1571,7 @@ reply: * -*/ static -VOID +void s_vMgrRxAuthenSequence_4( PSDevice pDevice, PSMgmtObject pMgmt, @@ -1610,7 +1610,7 @@ s_vMgrRxAuthenSequence_4( -*/ static -VOID +void s_vMgrRxDisassociation( PSDevice pDevice, PSMgmtObject pMgmt, @@ -1700,7 +1700,7 @@ s_vMgrRxDisassociation( -*/ static -VOID +void s_vMgrRxDeauthentication( PSDevice pDevice, PSMgmtObject pMgmt, @@ -1826,7 +1826,7 @@ ChannelExceedZoneType( -*/ static -VOID +void s_vMgrRxBeacon( PSDevice pDevice, PSMgmtObject pMgmt, @@ -2089,7 +2089,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abyExtSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, uRateLen); - RATEvParseMaxRate( (PVOID)pDevice, + RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, TRUE, @@ -2227,7 +2227,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, WLAN_RATES_MAXLEN_11B); - RATEvParseMaxRate( (PVOID)pDevice, + RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, NULL, TRUE, @@ -2248,7 +2248,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, WLAN_RATES_MAXLEN_11B); - RATEvParseMaxRate( (PVOID)pDevice, + RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, NULL, TRUE, @@ -2355,7 +2355,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) * CMD_STATUS * -*/ -VOID +void vMgrCreateOwnIBSS( HANDLE hDeviceContext, OUT PCMD_STATUS pStatus @@ -2466,7 +2466,8 @@ vMgrCreateOwnIBSS( // set basic rate - RATEvParseMaxRate((PVOID)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + RATEvParseMaxRate((void *)pDevice, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, TRUE, &wMaxBasicRate, &wMaxSuppRate, &wSuppRate, &byTopCCKBasicRate, &byTopOFDMBasicRate); @@ -2629,7 +2630,7 @@ vMgrCreateOwnIBSS( * -*/ -VOID +void vMgrJoinBSSBegin( HANDLE hDeviceContext, OUT PCMD_STATUS pStatus @@ -2760,7 +2761,7 @@ vMgrJoinBSSBegin( } } - RATEvParseMaxRate((PVOID)pDevice, pItemRates, pItemExtRates, TRUE, + RATEvParseMaxRate((void *)pDevice, pItemRates, pItemExtRates, TRUE, &wMaxBasicRate, &wMaxSuppRate, &wSuppRate, &byTopCCKBasicRate, &byTopOFDMBasicRate); vUpdateIFS(pDevice); @@ -2899,7 +2900,8 @@ vMgrJoinBSSBegin( (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, WLAN_RATES_MAXLEN_11B); // set basic rate - RATEvParseMaxRate((PVOID)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + RATEvParseMaxRate((void *)pDevice, + (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, NULL, TRUE, &wMaxBasicRate, &wMaxSuppRate, &wSuppRate, &byTopCCKBasicRate, &byTopOFDMBasicRate); vUpdateIFS(pDevice); @@ -2960,7 +2962,7 @@ vMgrJoinBSSBegin( * -*/ static -VOID +void s_vMgrSynchBSS ( PSDevice pDevice, UINT uBSSMode, @@ -3004,7 +3006,7 @@ s_vMgrSynchBSS ( pDevice->byPreambleType = 0; pDevice->wBasicRate = 0; // Set Basic Rate - CARDbAddBasicRate((PVOID)pDevice, RATE_1M); + CARDbAddBasicRate((void *)pDevice, RATE_1M); // calculate TSF offset // TSF Offset = Received Timestamp TSF - Marked Local's TSF @@ -3122,7 +3124,7 @@ s_vMgrSynchBSS ( //mike add: fix NetworkManager 0.7.0 hidden ssid mode in WPA encryption // ,need reset eAuthenMode and eEncryptionStatus - static VOID Encyption_Rebuild( + static void Encyption_Rebuild( PSDevice pDevice, PKnownBSS pCurr ) @@ -3174,12 +3176,12 @@ s_vMgrSynchBSS ( * * * Return Value: - * VOID + * void * -*/ static -VOID +void s_vMgrFormatTIM( PSMgmtObject pMgmt, PWLAN_IE_TIM pTIM @@ -4224,7 +4226,7 @@ s_MgrMakeReAssocResponse( -*/ static -VOID +void s_vMgrRxProbeResponse( PSDevice pDevice, PSMgmtObject pMgmt, @@ -4354,7 +4356,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) static -VOID +void s_vMgrRxProbeRequest( PSDevice pDevice, PSMgmtObject pMgmt, @@ -4450,7 +4452,7 @@ s_vMgrRxProbeRequest( -*/ -VOID +void vMgrRxManagePacket( HANDLE hDeviceContext, PSMgmtObject pMgmt, @@ -4658,7 +4660,7 @@ bMgrPrepareBeaconToSend( * -*/ static -VOID +void s_vMgrLogStatus( PSMgmtObject pMgmt, WORD wStatus @@ -4791,7 +4793,7 @@ bAdd_PMKID_Candidate ( * Return Value: none. * -*/ -VOID +void vFlush_PMKID_Candidate ( HANDLE hDeviceContext ) diff --git a/drivers/staging/vt6656/wmgr.h b/drivers/staging/vt6656/wmgr.h index f6774cedacfa..d554715e2cd0 100644 --- a/drivers/staging/vt6656/wmgr.h +++ b/drivers/staging/vt6656/wmgr.h @@ -246,8 +246,7 @@ typedef struct tagSRxMgmtPacket { typedef struct tagSMgmtObject { - - PVOID pAdapter; + void *pAdapter; // MAC address BYTE abyMACAddr[WLAN_ADDR_LEN]; @@ -421,14 +420,14 @@ vMgrAssocBeginSta( OUT PCMD_STATUS pStatus ); -VOID +void vMgrReAssocBeginSta( HANDLE hDeviceContext, PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ); -VOID +void vMgrDisassocBeginSta( HANDLE hDeviceContext, PSMgmtObject pMgmt, @@ -437,26 +436,26 @@ vMgrDisassocBeginSta( OUT PCMD_STATUS pStatus ); -VOID +void vMgrAuthenBeginSta( HANDLE hDeviceContext, PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ); -VOID +void vMgrCreateOwnIBSS( HANDLE hDeviceContext, OUT PCMD_STATUS pStatus ); -VOID +void vMgrJoinBSSBegin( HANDLE hDeviceContext, OUT PCMD_STATUS pStatus ); -VOID +void vMgrRxManagePacket( HANDLE hDeviceContext, PSMgmtObject pMgmt, @@ -464,14 +463,14 @@ vMgrRxManagePacket( ); /* -VOID +void vMgrScanBegin( HANDLE hDeviceContext, OUT PCMD_STATUS pStatus ); */ -VOID +void vMgrDeAuthenBeginSta( HANDLE hDeviceContext, PSMgmtObject pMgmt, @@ -494,7 +493,7 @@ bAdd_PMKID_Candidate ( PSRSNCapObject psRSNCapObj ); -VOID +void vFlush_PMKID_Candidate ( HANDLE hDeviceContext ); diff --git a/drivers/staging/vt6656/wpa.c b/drivers/staging/vt6656/wpa.c index 9992291ab22c..1fa6c9b88ed3 100644 --- a/drivers/staging/vt6656/wpa.c +++ b/drivers/staging/vt6656/wpa.c @@ -68,7 +68,7 @@ const BYTE abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 }; * -*/ -VOID +void WPA_ClearRSN ( PKnownBSS pBSSList ) @@ -104,7 +104,7 @@ WPA_ClearRSN ( * Return Value: none. * -*/ -VOID +void WPA_ParseRSN ( PKnownBSS pBSSList, PWLAN_IE_RSN_EXT pRSN diff --git a/drivers/staging/vt6656/wpa.h b/drivers/staging/vt6656/wpa.h index 0a955b3200fe..661f40d526f5 100644 --- a/drivers/staging/vt6656/wpa.h +++ b/drivers/staging/vt6656/wpa.h @@ -58,12 +58,12 @@ /*--------------------- Export Functions --------------------------*/ -VOID +void WPA_ClearRSN( PKnownBSS pBSSList ); -VOID +void WPA_ParseRSN( PKnownBSS pBSSList, PWLAN_IE_RSN_EXT pRSN diff --git a/drivers/staging/vt6656/wpa2.c b/drivers/staging/vt6656/wpa2.c index 9a972a4f6433..73bfb500d45b 100644 --- a/drivers/staging/vt6656/wpa2.c +++ b/drivers/staging/vt6656/wpa2.c @@ -71,7 +71,7 @@ const BYTE abyOUIPSK[4] = { 0x00, 0x0F, 0xAC, 0x02 }; * Return Value: none. * -*/ -VOID +void WPA2_ClearRSN ( PKnownBSS pBSSNode ) @@ -106,7 +106,7 @@ WPA2_ClearRSN ( * Return Value: none. * -*/ -VOID +void WPA2vParseRSN ( PKnownBSS pBSSNode, PWLAN_IE_RSN pRSN @@ -261,8 +261,7 @@ WPA2vParseRSN ( * -*/ UINT -WPA2uSetIEs( - PVOID pMgmtHandle, +WPA2uSetIEs(void *pMgmtHandle, OUT PWLAN_IE_RSN pRSNIEs ) { diff --git a/drivers/staging/vt6656/wpa2.h b/drivers/staging/vt6656/wpa2.h index 51fb3fd8b659..6026005ca8c2 100644 --- a/drivers/staging/vt6656/wpa2.h +++ b/drivers/staging/vt6656/wpa2.h @@ -58,12 +58,12 @@ typedef struct tagSPMKIDCache { /*--------------------- Export Functions --------------------------*/ -VOID +void WPA2_ClearRSN ( PKnownBSS pBSSNode ); -VOID +void WPA2vParseRSN ( PKnownBSS pBSSNode, PWLAN_IE_RSN pRSN @@ -71,7 +71,7 @@ WPA2vParseRSN ( UINT WPA2uSetIEs( - PVOID pMgmtHandle, + void *pMgmtHandle, OUT PWLAN_IE_RSN pRSNIEs ); -- cgit v1.2.3 From e7b07d1d8936e06f88dbe227401ce659c2f9dee5 Mon Sep 17 00:00:00 2001 From: Andres More Date: Sat, 1 May 2010 19:12:26 -0300 Subject: Staging: vt6656: code cleanup, fixed comments style at the end of headers Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/aes_ccmp.h | 2 +- drivers/staging/vt6656/baseband.h | 2 +- drivers/staging/vt6656/bssdb.h | 2 +- drivers/staging/vt6656/card.h | 5 +---- drivers/staging/vt6656/control.h | 5 +---- drivers/staging/vt6656/datarate.h | 3 +-- drivers/staging/vt6656/desc.h | 6 +----- drivers/staging/vt6656/dpc.h | 5 +---- drivers/staging/vt6656/firmware.h | 3 +-- drivers/staging/vt6656/hostap.h | 5 +---- drivers/staging/vt6656/int.h | 5 +---- drivers/staging/vt6656/iocmd.h | 4 +--- drivers/staging/vt6656/ioctl.h | 5 +---- drivers/staging/vt6656/iowpa.h | 4 +--- drivers/staging/vt6656/iwctl.h | 5 +---- drivers/staging/vt6656/key.h | 3 +-- drivers/staging/vt6656/mac.h | 2 +- drivers/staging/vt6656/mib.h | 5 +---- drivers/staging/vt6656/michael.h | 4 +--- drivers/staging/vt6656/power.h | 2 +- drivers/staging/vt6656/rc4.h | 2 +- drivers/staging/vt6656/rf.h | 5 +---- drivers/staging/vt6656/rndis.h | 3 +-- drivers/staging/vt6656/rxtx.h | 5 +---- drivers/staging/vt6656/srom.h | 2 +- drivers/staging/vt6656/tcrc.h | 5 +---- drivers/staging/vt6656/tether.h | 5 +---- drivers/staging/vt6656/tkip.h | 5 +---- drivers/staging/vt6656/tmacro.h | 4 +--- drivers/staging/vt6656/ttype.h | 2 +- drivers/staging/vt6656/upc.h | 6 +----- drivers/staging/vt6656/usbpipe.h | 5 +---- drivers/staging/vt6656/wcmd.h | 2 +- drivers/staging/vt6656/wctl.h | 5 +---- drivers/staging/vt6656/wmgr.h | 2 +- drivers/staging/vt6656/wpa.h | 2 +- drivers/staging/vt6656/wpa2.h | 2 +- drivers/staging/vt6656/wpactl.h | 5 +---- 38 files changed, 38 insertions(+), 106 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/aes_ccmp.h b/drivers/staging/vt6656/aes_ccmp.h index f2ba1d5aa1e5..353bd210a502 100644 --- a/drivers/staging/vt6656/aes_ccmp.h +++ b/drivers/staging/vt6656/aes_ccmp.h @@ -43,4 +43,4 @@ /*--------------------- Export Functions --------------------------*/ BOOL AESbGenCCMP(PBYTE pbyRxKey, PBYTE pbyFrame, WORD wFrameSize); -#endif //__AES_H__ +#endif /* __AES_CCMP_H__ */ diff --git a/drivers/staging/vt6656/baseband.h b/drivers/staging/vt6656/baseband.h index fbc2847122b3..9a1999b3302c 100644 --- a/drivers/staging/vt6656/baseband.h +++ b/drivers/staging/vt6656/baseband.h @@ -143,4 +143,4 @@ void BBvUpdatePreEDThreshold( BOOL bScanning ); -#endif // __BASEBAND_H__ +#endif /* __BASEBAND_H__ */ diff --git a/drivers/staging/vt6656/bssdb.h b/drivers/staging/vt6656/bssdb.h index 343bfacdbe9b..2aaa9332894e 100644 --- a/drivers/staging/vt6656/bssdb.h +++ b/drivers/staging/vt6656/bssdb.h @@ -356,4 +356,4 @@ BSSvClearAnyBSSJoinRecord( HANDLE hDeviceContext ); -#endif //__BSSDB_H__ +#endif /* __BSSDB_H__ */ diff --git a/drivers/staging/vt6656/card.h b/drivers/staging/vt6656/card.h index 2f7335e8aee1..770ee6a95c11 100644 --- a/drivers/staging/vt6656/card.h +++ b/drivers/staging/vt6656/card.h @@ -91,7 +91,4 @@ CARDbChannelSwitch ( BYTE byCount ); -#endif // __CARD_H__ - - - +#endif /* __CARD_H__ */ diff --git a/drivers/staging/vt6656/control.h b/drivers/staging/vt6656/control.h index 106c9e9f2b3c..146b450e13d0 100644 --- a/drivers/staging/vt6656/control.h +++ b/drivers/staging/vt6656/control.h @@ -77,7 +77,4 @@ void ControlvMaskByte( BYTE byData ); -#endif // __RCV_H__ - - - +#endif /* __CONTROL_H__ */ diff --git a/drivers/staging/vt6656/datarate.h b/drivers/staging/vt6656/datarate.h index da51854988bf..ae37eb63cadd 100644 --- a/drivers/staging/vt6656/datarate.h +++ b/drivers/staging/vt6656/datarate.h @@ -106,5 +106,4 @@ DATARATEbyGetRateIdx( BYTE byRate ); - -#endif //__DATARATE_H__ +#endif /* __DATARATE_H__ */ diff --git a/drivers/staging/vt6656/desc.h b/drivers/staging/vt6656/desc.h index c87ea6b4d864..07f794ec6db2 100644 --- a/drivers/staging/vt6656/desc.h +++ b/drivers/staging/vt6656/desc.h @@ -436,8 +436,4 @@ SKeyEntry; /*--------------------- Export Functions --------------------------*/ - - - -#endif // __DESC_H__ - +#endif /* __DESC_H__ */ diff --git a/drivers/staging/vt6656/dpc.h b/drivers/staging/vt6656/dpc.h index 457db7716922..7ea3ad973417 100644 --- a/drivers/staging/vt6656/dpc.h +++ b/drivers/staging/vt6656/dpc.h @@ -58,7 +58,4 @@ RXbBulkInProcessData( ULONG BytesToIndicate ); -#endif // __RXTX_H__ - - - +#endif /* __RXTX_H__ */ diff --git a/drivers/staging/vt6656/firmware.h b/drivers/staging/vt6656/firmware.h index 10e84cdf21b3..b2f5b5818a93 100644 --- a/drivers/staging/vt6656/firmware.h +++ b/drivers/staging/vt6656/firmware.h @@ -56,5 +56,4 @@ FIRMWAREbCheckVersion( PSDevice pDevice ); - -#endif // __FIRMWARE_H__ +#endif /* __FIRMWARE_H__ */ diff --git a/drivers/staging/vt6656/hostap.h b/drivers/staging/vt6656/hostap.h index 9e366dca7a63..b660aee1ca0e 100644 --- a/drivers/staging/vt6656/hostap.h +++ b/drivers/staging/vt6656/hostap.h @@ -64,7 +64,4 @@ int vt6656_hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked); int vt6656_hostap_ioctl(PSDevice pDevice, struct iw_point *p); -#endif // __HOSTAP_H__ - - - +#endif /* __HOSTAP_H__ */ diff --git a/drivers/staging/vt6656/int.h b/drivers/staging/vt6656/int.h index 20c96f550688..cdf355130de7 100644 --- a/drivers/staging/vt6656/int.h +++ b/drivers/staging/vt6656/int.h @@ -74,7 +74,4 @@ INTnsProcessData( PSDevice pDevice ); -#endif // __INT_H__ - - - +#endif /* __INT_H__ */ diff --git a/drivers/staging/vt6656/iocmd.h b/drivers/staging/vt6656/iocmd.h index 49bfe15f1335..67ec7d758051 100644 --- a/drivers/staging/vt6656/iocmd.h +++ b/drivers/staging/vt6656/iocmd.h @@ -470,6 +470,4 @@ struct viawget_hostapd_param { /*--------------------- Export Functions --------------------------*/ - - -#endif //__IOCMD_H__ +#endif /* __IOCMD_H__ */ diff --git a/drivers/staging/vt6656/ioctl.h b/drivers/staging/vt6656/ioctl.h index 46eb699a71ea..b307980999e9 100644 --- a/drivers/staging/vt6656/ioctl.h +++ b/drivers/staging/vt6656/ioctl.h @@ -51,7 +51,4 @@ void vConfigWEPKey ( ); */ -#endif // __IOCTL_H__ - - - +#endif /* __IOCTL_H__ */ diff --git a/drivers/staging/vt6656/iowpa.h b/drivers/staging/vt6656/iowpa.h index 5750b5b548e8..da03edcbacb0 100644 --- a/drivers/staging/vt6656/iowpa.h +++ b/drivers/staging/vt6656/iowpa.h @@ -153,6 +153,4 @@ struct viawget_scan_result { /*--------------------- Export Functions --------------------------*/ - - -#endif //__IOWPA_H__ +#endif /* __IOWPA_H__ */ diff --git a/drivers/staging/vt6656/iwctl.h b/drivers/staging/vt6656/iwctl.h index 3096de0ba1bd..df9a4cf3baac 100644 --- a/drivers/staging/vt6656/iwctl.h +++ b/drivers/staging/vt6656/iwctl.h @@ -223,7 +223,4 @@ int iwctl_siwmlme(struct net_device *dev, extern const struct iw_handler_def iwctl_handler_def; extern const struct iw_priv_args iwctl_private_args; -#endif // __IWCTL_H__ - - - +#endif /* __IWCTL_H__ */ diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h index 7aec57b6f61b..a10878200fa7 100644 --- a/drivers/staging/vt6656/key.h +++ b/drivers/staging/vt6656/key.h @@ -173,5 +173,4 @@ BOOL KeybSetAllGroupKey( BYTE byKeyDecMode ); -#endif // __KEY_H__ - +#endif /* __KEY_H__ */ diff --git a/drivers/staging/vt6656/mac.h b/drivers/staging/vt6656/mac.h index 1a7c2f5cff0e..4e3d11b4a8be 100644 --- a/drivers/staging/vt6656/mac.h +++ b/drivers/staging/vt6656/mac.h @@ -439,4 +439,4 @@ void MACvEnableBarkerPreambleMd(PSDevice pDevice); void MACvDisableBarkerPreambleMd(PSDevice pDevice); void MACvWriteBeaconInterval(PSDevice pDevice, WORD wInterval); -#endif // __MAC_H__ +#endif /* __MAC_H__ */ diff --git a/drivers/staging/vt6656/mib.h b/drivers/staging/vt6656/mib.h index d1d781774ca8..8a532e877f0f 100644 --- a/drivers/staging/vt6656/mib.h +++ b/drivers/staging/vt6656/mib.h @@ -417,7 +417,4 @@ STAvUpdateUSBCounter( NTSTATUS ntStatus ); -#endif // __MIB_H__ - - - +#endif /* __MIB_H__ */ diff --git a/drivers/staging/vt6656/michael.h b/drivers/staging/vt6656/michael.h index 97de77b4da2c..52270d314a8b 100644 --- a/drivers/staging/vt6656/michael.h +++ b/drivers/staging/vt6656/michael.h @@ -53,6 +53,4 @@ void MIC_vGetMIC(PDWORD pdwL, PDWORD pdwR); ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) ) #define ROR32( A, n ) ROL32( (A), 32-(n) ) -#endif //__MICHAEL_H__ - - +#endif /* __MICHAEL_H__ */ diff --git a/drivers/staging/vt6656/power.h b/drivers/staging/vt6656/power.h index e83ac4ecf6d0..c34e3899d95b 100644 --- a/drivers/staging/vt6656/power.h +++ b/drivers/staging/vt6656/power.h @@ -81,4 +81,4 @@ PSbIsNextTBTTWakeUp( HANDLE hDeviceContext ); -#endif //__POWER_H__ +#endif /* __POWER_H__ */ diff --git a/drivers/staging/vt6656/rc4.h b/drivers/staging/vt6656/rc4.h index e65cae69efaf..9cd1db9276bc 100644 --- a/drivers/staging/vt6656/rc4.h +++ b/drivers/staging/vt6656/rc4.h @@ -44,4 +44,4 @@ void rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len); UINT rc4_byte(PRC4Ext pRC4); void rc4_encrypt(PRC4Ext pRC4, PBYTE pbyDest, PBYTE pbySrc, UINT cbData_len); -#endif //__RC4_H__ +#endif /* __RC4_H__ */ diff --git a/drivers/staging/vt6656/rf.h b/drivers/staging/vt6656/rf.h index 6c3faf8adc8b..7423d4daba01 100644 --- a/drivers/staging/vt6656/rf.h +++ b/drivers/staging/vt6656/rf.h @@ -94,7 +94,4 @@ BOOL s_bVT3226D0_11bLoCurrentAdjust( BOOL b11bMode ); -#endif // __RF_H__ - - - +#endif /* __RF_H__ */ diff --git a/drivers/staging/vt6656/rndis.h b/drivers/staging/vt6656/rndis.h index 1d32d81079b6..ac842dd13a68 100644 --- a/drivers/staging/vt6656/rndis.h +++ b/drivers/staging/vt6656/rndis.h @@ -158,5 +158,4 @@ typedef struct _CMD_CHANGE_BBTYPE /*--------------------- Export Functions --------------------------*/ - -#endif // _RNDIS_H_ +#endif /* _RNDIS_H_ */ diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h index 7c7e078495c8..026943058ac2 100644 --- a/drivers/staging/vt6656/rxtx.h +++ b/drivers/staging/vt6656/rxtx.h @@ -688,7 +688,4 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket); CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket); BOOL bRelayPacketSend(PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeIndex); -#endif // __RXTX_H__ - - - +#endif /* __RXTX_H__ */ diff --git a/drivers/staging/vt6656/srom.h b/drivers/staging/vt6656/srom.h index 4c89e7ad6b4c..dba21a54414b 100644 --- a/drivers/staging/vt6656/srom.h +++ b/drivers/staging/vt6656/srom.h @@ -124,4 +124,4 @@ typedef struct tagSSromReg { /*--------------------- Export Functions --------------------------*/ -#endif // __EEPROM_H__ +#endif /* __EEPROM_H__ */ diff --git a/drivers/staging/vt6656/tcrc.h b/drivers/staging/vt6656/tcrc.h index 5faa48b0a748..a41fc9b56105 100644 --- a/drivers/staging/vt6656/tcrc.h +++ b/drivers/staging/vt6656/tcrc.h @@ -47,7 +47,4 @@ DWORD CRCdwCrc32(PBYTE pbyData, UINT cbByte, DWORD dwCrcSeed); DWORD CRCdwGetCrc32(PBYTE pbyData, UINT cbByte); DWORD CRCdwGetCrc32Ex(PBYTE pbyData, UINT cbByte, DWORD dwPreCRC); -#endif // __TCRC_H__ - - - +#endif /* __TCRC_H__ */ diff --git a/drivers/staging/vt6656/tether.h b/drivers/staging/vt6656/tether.h index af119dd82b24..9b26033c585b 100644 --- a/drivers/staging/vt6656/tether.h +++ b/drivers/staging/vt6656/tether.h @@ -230,7 +230,4 @@ BYTE ETHbyGetHashIndexByCrc32(PBYTE pbyMultiAddr); //BYTE ETHbyGetHashIndexByCrc(PBYTE pbyMultiAddr); BOOL ETHbIsBufferCrc32Ok(PBYTE pbyBuffer, UINT cbFrameLength); -#endif // __TETHER_H__ - - - +#endif /* __TETHER_H__ */ diff --git a/drivers/staging/vt6656/tkip.h b/drivers/staging/vt6656/tkip.h index 3dfa7f5ee7ec..47c3a853b92a 100644 --- a/drivers/staging/vt6656/tkip.h +++ b/drivers/staging/vt6656/tkip.h @@ -54,7 +54,4 @@ void TKIPvMixKey( PBYTE pbyRC4Key ); -#endif // __TKIP_H__ - - - +#endif /* __TKIP_H__ */ diff --git a/drivers/staging/vt6656/tmacro.h b/drivers/staging/vt6656/tmacro.h index e96c140de052..3c81e2b0791d 100644 --- a/drivers/staging/vt6656/tmacro.h +++ b/drivers/staging/vt6656/tmacro.h @@ -57,6 +57,4 @@ #define MAKEDWORD(lw, hw) ((DWORD)(((WORD)(lw)) | (((DWORD)((WORD)(hw))) << 16))) #endif -#endif // __TMACRO_H__ - - +#endif /* __TMACRO_H__ */ diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h index 5bbd4e37256a..a773e58c2302 100644 --- a/drivers/staging/vt6656/ttype.h +++ b/drivers/staging/vt6656/ttype.h @@ -149,4 +149,4 @@ typedef void *HANDLE; typedef void *HANDLE; #endif -#endif // __TTYPE_H__ +#endif /* __TTYPE_H__ */ diff --git a/drivers/staging/vt6656/upc.h b/drivers/staging/vt6656/upc.h index acd1b661490d..be386edb3e94 100644 --- a/drivers/staging/vt6656/upc.h +++ b/drivers/staging/vt6656/upc.h @@ -159,8 +159,4 @@ /*--------------------- Export Functions --------------------------*/ - - - -#endif // __UPC_H__ - +#endif /* __UPC_H__ */ diff --git a/drivers/staging/vt6656/usbpipe.h b/drivers/staging/vt6656/usbpipe.h index 0f7cd2d10b93..ee86d3716dc3 100644 --- a/drivers/staging/vt6656/usbpipe.h +++ b/drivers/staging/vt6656/usbpipe.h @@ -93,7 +93,4 @@ PIPEnsSendBulkOut( PUSB_SEND_CONTEXT pContext ); -#endif // __USBPIPE_H__ - - - +#endif /* __USBPIPE_H__ */ diff --git a/drivers/staging/vt6656/wcmd.h b/drivers/staging/vt6656/wcmd.h index f3eac0353602..a14e56470ea1 100644 --- a/drivers/staging/vt6656/wcmd.h +++ b/drivers/staging/vt6656/wcmd.h @@ -147,4 +147,4 @@ BSSvSecondTxData( ); #endif -#endif //__WCMD_H__ +#endif /* __WCMD_H__ */ diff --git a/drivers/staging/vt6656/wctl.h b/drivers/staging/vt6656/wctl.h index a1ac4791bfd3..c81dff700e0f 100644 --- a/drivers/staging/vt6656/wctl.h +++ b/drivers/staging/vt6656/wctl.h @@ -102,7 +102,4 @@ BOOL WCTLbHandleFragment(PSDevice pDevice, PS802_11Header pMACHeader, UINT cbFra UINT WCTLuSearchDFCB(PSDevice pDevice, PS802_11Header pMACHeader); UINT WCTLuInsertDFCB(PSDevice pDevice, PS802_11Header pMACHeader); -#endif // __WCTL_H__ - - - +#endif /* __WCTL_H__ */ diff --git a/drivers/staging/vt6656/wmgr.h b/drivers/staging/vt6656/wmgr.h index d554715e2cd0..02ecec92babb 100644 --- a/drivers/staging/vt6656/wmgr.h +++ b/drivers/staging/vt6656/wmgr.h @@ -498,4 +498,4 @@ vFlush_PMKID_Candidate ( HANDLE hDeviceContext ); -#endif // __WMGR_H__ +#endif /* __WMGR_H__ */ diff --git a/drivers/staging/vt6656/wpa.h b/drivers/staging/vt6656/wpa.h index 661f40d526f5..889489adbb81 100644 --- a/drivers/staging/vt6656/wpa.h +++ b/drivers/staging/vt6656/wpa.h @@ -81,4 +81,4 @@ WPAb_Is_RSN( PWLAN_IE_RSN_EXT pRSN ); -#endif // __WPA_H__ +#endif /* __WPA_H__ */ diff --git a/drivers/staging/vt6656/wpa2.h b/drivers/staging/vt6656/wpa2.h index 6026005ca8c2..367aecee8b7c 100644 --- a/drivers/staging/vt6656/wpa2.h +++ b/drivers/staging/vt6656/wpa2.h @@ -75,4 +75,4 @@ WPA2uSetIEs( OUT PWLAN_IE_RSN pRSNIEs ); -#endif // __WPA2_H__ +#endif /* __WPA2_H__ */ diff --git a/drivers/staging/vt6656/wpactl.h b/drivers/staging/vt6656/wpactl.h index 56179f01311a..3a2f15f3f249 100644 --- a/drivers/staging/vt6656/wpactl.h +++ b/drivers/staging/vt6656/wpactl.h @@ -66,7 +66,4 @@ int wpa_set_wpadev(PSDevice pDevice, int val); int wpa_ioctl(PSDevice pDevice, struct iw_point *p); int wpa_set_keys(PSDevice pDevice, void *ctx, BOOL fcpfkernel); -#endif // __WPACL_H__ - - - +#endif /* __WPACL_H__ */ -- cgit v1.2.3 From 92f2a4c58f8dd8d517360660b94915edb804f125 Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Sun, 2 May 2010 09:33:26 +0200 Subject: Staging: winbond: Renamed README to TODO and corrected Pavel's mail Signed-off-by: Lars Lindley Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/README | 12 ------------ drivers/staging/winbond/TODO | 12 ++++++++++++ 2 files changed, 12 insertions(+), 12 deletions(-) delete mode 100644 drivers/staging/winbond/README create mode 100644 drivers/staging/winbond/TODO (limited to 'drivers') diff --git a/drivers/staging/winbond/README b/drivers/staging/winbond/README deleted file mode 100644 index 27710241fc14..000000000000 --- a/drivers/staging/winbond/README +++ /dev/null @@ -1,12 +0,0 @@ -TODO: - - sparse cleanups - - checkpatch cleanups - - kerneldoc cleanups - - fix severeCamelCaseInfestation - - remove typedefs - - remove unused ioctls - - use cfg80211 for regulatory stuff - - fix 4k stack problems - -Please send patches to Greg Kroah-Hartman and -Pavel Machek diff --git a/drivers/staging/winbond/TODO b/drivers/staging/winbond/TODO new file mode 100644 index 000000000000..8c1baaf6d8ad --- /dev/null +++ b/drivers/staging/winbond/TODO @@ -0,0 +1,12 @@ +TODO: + - sparse cleanups + - checkpatch cleanups + - kerneldoc cleanups + - fix severeCamelCaseInfestation + - remove typedefs + - remove unused ioctls + - use cfg80211 for regulatory stuff + - fix 4k stack problems + +Please send patches to Greg Kroah-Hartman and +Pavel Machek -- cgit v1.2.3 From 4212c686381a0ab62601ea7a272e7ff4c2ea4cb7 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sun, 2 May 2010 13:05:33 -0400 Subject: Staging: adis16255: Fix compile error This patch solves a compilation error in today linux-next tree. The adis16255 staging driver Makefile seems to be wrong. I think this patch solves the issue. Signed-off-by: Javier Martinez Canillas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/adis16255/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/adis16255/Makefile b/drivers/staging/adis16255/Makefile index 3f8b1f06b194..8057372d3781 100644 --- a/drivers/staging/adis16255/Makefile +++ b/drivers/staging/adis16255/Makefile @@ -1 +1 @@ -obj-$(CONFIG_ADIS16255) +údis16255.o +obj-$(CONFIG_ADIS16255) += adis1625.o -- cgit v1.2.3 From 4752e51a1dcab1a17a1ee0b46735465a033d83b0 Mon Sep 17 00:00:00 2001 From: Charles Clément Date: Sun, 2 May 2010 18:29:57 -0700 Subject: Staging: crystalhd: Cleanup all WIN* references MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles Clément Signed-off-by: Greg Kroah-Hartman --- drivers/staging/crystalhd/TODO | 1 - drivers/staging/crystalhd/bc_dts_defs.h | 4 ++-- drivers/staging/crystalhd/bc_dts_types.h | 23 ----------------------- 3 files changed, 2 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/crystalhd/TODO b/drivers/staging/crystalhd/TODO index 69be5d0cb80c..daca2d4d2a2f 100644 --- a/drivers/staging/crystalhd/TODO +++ b/drivers/staging/crystalhd/TODO @@ -1,7 +1,6 @@ - Testing - Cleanup return codes - Cleanup typedefs -- Cleanup all WIN* references - Allocate an Accelerator device class specific Major number, since we don't have any other open sourced accelerators, it is the only one in that category for now. diff --git a/drivers/staging/crystalhd/bc_dts_defs.h b/drivers/staging/crystalhd/bc_dts_defs.h index c34cc07127b8..f9dd0e3e240d 100644 --- a/drivers/staging/crystalhd/bc_dts_defs.h +++ b/drivers/staging/crystalhd/bc_dts_defs.h @@ -238,7 +238,7 @@ typedef struct _BC_PIB_EXT_VC1 { /*------------------------------------------------------* * Picture Information Block * *------------------------------------------------------*/ -#if defined(_WIN32) || defined(_WIN64) || defined(__LINUX_USER__) +#if defined(__LINUX_USER__) /* Values for 'pulldown' field. '0' means no pulldown information * was present for this picture. */ enum { @@ -358,7 +358,7 @@ enum { #define VDEC_FLAG_PICTURE_META_DATA_PRESENT (0x40000) -#endif /* _WIN32 || _WIN64 */ +#endif /* __LINUX_USER__ */ enum _BC_OUTPUT_FORMAT { MODE420 = 0x0, diff --git a/drivers/staging/crystalhd/bc_dts_types.h b/drivers/staging/crystalhd/bc_dts_types.h index 95a2f875f1e7..6fd8089415d6 100644 --- a/drivers/staging/crystalhd/bc_dts_types.h +++ b/drivers/staging/crystalhd/bc_dts_types.h @@ -29,15 +29,6 @@ #include #endif -#if defined(_WIN64) || defined(_WIN32) -typedef uint32_t U32; -typedef int32_t S32; -typedef uint16_t U16; -typedef int16_t S16; -typedef unsigned char U8; -typedef char S8; -#endif - #ifndef PVOID typedef void *PVOID; #endif @@ -46,20 +37,6 @@ typedef void *PVOID; typedef int BOOL; #endif -#ifdef WIN32 - typedef unsigned __int64 U64; -#elif defined(_WIN64) - typedef uint64_t U64; -#endif - -#ifdef _WIN64 -#if !(defined(POINTER_32)) -#define POINTER_32 __ptr32 -#endif -#else /* _WIN32 */ -#define POINTER_32 -#endif - #if defined(__KERNEL__) || defined(__LINUX_USER__) #ifdef __LINUX_USER__ /* Don't include these for KERNEL */ -- cgit v1.2.3 From 3b87d0aa352a3eec3f5a032aa9d6f2ac46e7a74c Mon Sep 17 00:00:00 2001 From: Charles Clément Date: Sun, 2 May 2010 18:50:16 -0700 Subject: Staging: crystalhd: remove unused #include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles Clément Signed-off-by: Greg Kroah-Hartman --- drivers/staging/crystalhd/crystalhd_misc.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/crystalhd/crystalhd_misc.h b/drivers/staging/crystalhd/crystalhd_misc.h index a2aa6ad7fc81..84331cd33273 100644 --- a/drivers/staging/crystalhd/crystalhd_misc.h +++ b/drivers/staging/crystalhd/crystalhd_misc.h @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include "bc_dts_glob_lnx.h" -- cgit v1.2.3 From b8c623e5dde98a00ada4af47bec92a708794c573 Mon Sep 17 00:00:00 2001 From: Iain Churcher Date: Mon, 3 May 2010 10:35:37 +0100 Subject: Staging: comedi: Fix Checkpatch.pl issues in mpc624.c This patch resolves all checkpatch.pl issues in the mpc624.c file Signed-off-by: Iain Churcher Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/mpc624.c | 185 ++++++++++++++++++-------------- 1 file changed, 104 insertions(+), 81 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c index 12e72c828157..9874ac3749c3 100644 --- a/drivers/staging/comedi/drivers/mpc624.c +++ b/drivers/staging/comedi/drivers/mpc624.c @@ -40,20 +40,20 @@ Status: working Configuration Options: [0] - I/O base address [1] - convertion rate - Convertion rate RMS noise Effective Number Of Bits - 0 3.52kHz 23uV 17 - 1 1.76kHz 3.5uV 20 - 2 880Hz 2uV 21.3 - 3 440Hz 1.4uV 21.8 - 4 220Hz 1uV 22.4 - 5 110Hz 750uV 22.9 - 6 55Hz 510nV 23.4 - 7 27.5Hz 375nV 24 - 8 13.75Hz 250nV 24.4 - 9 6.875Hz 200nV 24.6 - [2] - voltage range - 0 -1.01V .. +1.01V - 1 -10.1V .. +10.1V + Convertion rate RMS noise Effective Number Of Bits + 0 3.52kHz 23uV 17 + 1 1.76kHz 3.5uV 20 + 2 880Hz 2uV 21.3 + 3 440Hz 1.4uV 21.8 + 4 220Hz 1uV 22.4 + 5 110Hz 750uV 22.9 + 6 55Hz 510nV 23.4 + 7 27.5Hz 375nV 24 + 8 13.75Hz 250nV 24.4 + 9 6.875Hz 200nV 24.6 + [2] - voltage range + 0 -1.01V .. +1.01V + 1 -10.1V .. +10.1V */ #include "../comedidev.h" @@ -65,13 +65,13 @@ Configuration Options: #define MPC624_SIZE 16 /* Offsets of different ports */ -#define MPC624_MASTER_CONTROL 0 /* not used */ -#define MPC624_GNMUXCH 1 /* Gain, Mux, Channel of ADC */ -#define MPC624_ADC 2 /* read/write to/from ADC */ -#define MPC624_EE 3 /* read/write to/from serial EEPROM via I2C */ -#define MPC624_LEDS 4 /* write to LEDs */ -#define MPC624_DIO 5 /* read/write to/from digital I/O ports */ -#define MPC624_IRQ_MASK 6 /* IRQ masking enable/disable */ +#define MPC624_MASTER_CONTROL 0 /* not used */ +#define MPC624_GNMUXCH 1 /* Gain, Mux, Channel of ADC */ +#define MPC624_ADC 2 /* read/write to/from ADC */ +#define MPC624_EE 3 /* read/write to/from serial EEPROM via I2C */ +#define MPC624_LEDS 4 /* write to LEDs */ +#define MPC624_DIO 5 /* read/write to/from digital I/O ports */ +#define MPC624_IRQ_MASK 6 /* IRQ masking enable/disable */ /* Register bits' names */ #define MPC624_ADBUSY (1<<5) @@ -109,24 +109,27 @@ Configuration Options: * ^ - Effective Number Of Bits */ -#define MPC624_SPEED_3_52_kHz (MPC624_OSR4 | MPC624_OSR0) -#define MPC624_SPEED_1_76_kHz (MPC624_OSR4 | MPC624_OSR1) -#define MPC624_SPEED_880_Hz (MPC624_OSR4 | MPC624_OSR1 | MPC624_OSR0) -#define MPC624_SPEED_440_Hz (MPC624_OSR4 | MPC624_OSR2) -#define MPC624_SPEED_220_Hz (MPC624_OSR4 | MPC624_OSR2 | MPC624_OSR0) -#define MPC624_SPEED_110_Hz (MPC624_OSR4 | MPC624_OSR2 | MPC624_OSR1) -#define MPC624_SPEED_55_Hz (MPC624_OSR4 | MPC624_OSR2 | MPC624_OSR1 | MPC624_OSR0) -#define MPC624_SPEED_27_5_Hz (MPC624_OSR4 | MPC624_OSR3) -#define MPC624_SPEED_13_75_Hz (MPC624_OSR4 | MPC624_OSR3 | MPC624_OSR0) -#define MPC624_SPEED_6_875_Hz (MPC624_OSR4 | MPC624_OSR3 | MPC624_OSR2 | MPC624_OSR1 | MPC624_OSR0) -/* ---------------------------------------------------------------------------- */ +#define MPC624_SPEED_3_52_kHz (MPC624_OSR4 | MPC624_OSR0) +#define MPC624_SPEED_1_76_kHz (MPC624_OSR4 | MPC624_OSR1) +#define MPC624_SPEED_880_Hz (MPC624_OSR4 | MPC624_OSR1 | MPC624_OSR0) +#define MPC624_SPEED_440_Hz (MPC624_OSR4 | MPC624_OSR2) +#define MPC624_SPEED_220_Hz (MPC624_OSR4 | MPC624_OSR2 | MPC624_OSR0) +#define MPC624_SPEED_110_Hz (MPC624_OSR4 | MPC624_OSR2 | MPC624_OSR1) +#define MPC624_SPEED_55_Hz \ + (MPC624_OSR4 | MPC624_OSR2 | MPC624_OSR1 | MPC624_OSR0) +#define MPC624_SPEED_27_5_Hz (MPC624_OSR4 | MPC624_OSR3) +#define MPC624_SPEED_13_75_Hz (MPC624_OSR4 | MPC624_OSR3 | MPC624_OSR0) +#define MPC624_SPEED_6_875_Hz \ + (MPC624_OSR4 | MPC624_OSR3 | MPC624_OSR2 | MPC624_OSR1 | MPC624_OSR0) +/* -------------------------------------------------------------------------- */ struct skel_private { - unsigned long int ulConvertionRate; /* set by mpc624_attach() from driver's parameters */ + /* set by mpc624_attach() from driver's parameters */ + unsigned long int ulConvertionRate; }; #define devpriv ((struct skel_private *)dev->private) -/* ---------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ static const struct comedi_lrange range_mpc624_bipolar1 = { 1, { @@ -145,11 +148,11 @@ static const struct comedi_lrange range_mpc624_bipolar10 = { } }; -/* ---------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it); static int mpc624_detach(struct comedi_device *dev); -/* ---------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ static struct comedi_driver driver_mpc624 = { .driver_name = "mpc624", .module = THIS_MODULE, @@ -157,20 +160,20 @@ static struct comedi_driver driver_mpc624 = { .detach = mpc624_detach }; -/* ---------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ static int mpc624_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); -/* ---------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; unsigned long iobase; iobase = it->options[0]; - printk("comedi%d: mpc624 [0x%04lx, ", dev->minor, iobase); + printk(KERN_INFO "comedi%d: mpc624 [0x%04lx, ", dev->minor, iobase); if (request_region(iobase, MPC624_SIZE, "mpc624") == NULL) { - printk("I/O port(s) in use\n"); + printk(KERN_ERR "I/O port(s) in use\n"); return -EIO; } @@ -184,47 +187,48 @@ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it) switch (it->options[1]) { case 0: devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz; - printk("3.52 kHz, "); + printk(KERN_INFO "3.52 kHz, "); break; case 1: devpriv->ulConvertionRate = MPC624_SPEED_1_76_kHz; - printk("1.76 kHz, "); + printk(KERN_INFO "1.76 kHz, "); break; case 2: devpriv->ulConvertionRate = MPC624_SPEED_880_Hz; - printk("880 Hz, "); + printk(KERN_INFO "880 Hz, "); break; case 3: devpriv->ulConvertionRate = MPC624_SPEED_440_Hz; - printk("440 Hz, "); + printk(KERN_INFO "440 Hz, "); break; case 4: devpriv->ulConvertionRate = MPC624_SPEED_220_Hz; - printk("220 Hz, "); + printk(KERN_INFO "220 Hz, "); break; case 5: devpriv->ulConvertionRate = MPC624_SPEED_110_Hz; - printk("110 Hz, "); + printk(KERN_INFO "110 Hz, "); break; case 6: devpriv->ulConvertionRate = MPC624_SPEED_55_Hz; - printk("55 Hz, "); + printk(KERN_INFO "55 Hz, "); break; case 7: devpriv->ulConvertionRate = MPC624_SPEED_27_5_Hz; - printk("27.5 Hz, "); + printk(KERN_INFO "27.5 Hz, "); break; case 8: devpriv->ulConvertionRate = MPC624_SPEED_13_75_Hz; - printk("13.75 Hz, "); + printk(KERN_INFO "13.75 Hz, "); break; case 9: devpriv->ulConvertionRate = MPC624_SPEED_6_875_Hz; - printk("6.875 Hz, "); + printk(KERN_INFO "6.875 Hz, "); break; default: printk - ("illegal convertion rate setting! Valid numbers are 0..9. Using 9 => 6.875 Hz, "); + (KERN_ERR "illegal convertion rate setting!" + " Valid numbers are 0..9. Using 9 => 6.875 Hz, "); devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz; } @@ -239,29 +243,29 @@ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it) switch (it->options[1]) { default: s->maxdata = 0x3FFFFFFF; - printk("30 bit, "); + printk(KERN_INFO "30 bit, "); } switch (it->options[1]) { case 0: s->range_table = &range_mpc624_bipolar1; - printk("1.01V]: "); + printk(KERN_INFO "1.01V]: "); break; default: s->range_table = &range_mpc624_bipolar10; - printk("10.1V]: "); + printk(KERN_INFO "10.1V]: "); } s->len_chanlist = 1; s->insn_read = mpc624_ai_rinsn; - printk("attached\n"); + printk(KERN_INFO "attached\n"); return 1; } static int mpc624_detach(struct comedi_device *dev) { - printk("comedi%d: mpc624: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: mpc624: remove\n", dev->minor); if (dev->iobase) release_region(dev->iobase, MPC624_SIZE); @@ -280,11 +284,14 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, unsigned long int data_in, data_out; unsigned char ucPort; - /* WARNING: We always write 0 to GNSWA bit, so the channel range is +-/10.1Vdc */ + /* + * WARNING: + * We always write 0 to GNSWA bit, so the channel range is +-/10.1Vdc + */ outb(insn->chanspec, dev->iobase + MPC624_GNMUXCH); -/* printk("Channel %d: \n", insn->chanspec); */ +/* printk("Channel %d:\n", insn->chanspec); */ if (!insn->n) { - printk("MPC624: Warning, no data to acquire\n"); + printk(KERN_INFO "MPC624: Warning, no data to acquire\n"); return 0; } @@ -306,7 +313,7 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, break; } if (i == TIMEOUT) { - printk("MPC624: timeout (%dms)\n", TIMEOUT); + printk(KERN_ERR "MPC624: timeout (%dms)\n", TIMEOUT); data[n] = 0; return -ETIMEDOUT; } @@ -319,7 +326,7 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, outb(0, dev->iobase + MPC624_ADC); udelay(1); - if (data_out & (1 << 31)) { /* the next bit is a 1 */ + if (data_out & (1 << 31)) { /* the next bit is a 1 */ /* Set the ADSDI line (send to MPC624) */ outb(MPC624_ADSDI, dev->iobase + MPC624_ADC); udelay(1); @@ -344,31 +351,47 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, data_out <<= 1; } - /* Received 32-bit long value consist of: */ - /* 31: EOC (End Of Transmission) bit - should be 0 */ - /* 30: DMY (Dummy) bit - should be 0 */ - /* 29: SIG (Sign) bit - 1 if the voltage is positive, 0 if negative */ - /* 28: MSB (Most Significant Bit) - the first bit of convertion result */ - /* .... */ - /* 05: LSB (Least Significant Bit) - the last bit of convertion result */ - /* 04: sub-LSB - sub-LSBs are basically noise, but when */ - /* 03: sub-LSB averaged properly, they can increase convertion */ - /* 02: sub-LSB precision up to 29 bits; they can be discarded */ - /* 01: sub-LSB without loss of resolution. */ - /* 00: sub-LSB */ + /* + * Received 32-bit long value consist of: + * 31: EOC - + * (End Of Transmission) bit - should be 0 + * 30: DMY + * (Dummy) bit - should be 0 + * 29: SIG + * (Sign) bit- 1 if the voltage is positive, + * 0 if negative + * 28: MSB + * (Most Significant Bit) - the first bit of + * the conversion result + * .... + * 05: LSB + * (Least Significant Bit)- the last bit of the + * conversion result + * 04-00: sub-LSB + * - sub-LSBs are basically noise, but when + * averaged properly, they can increase conversion + * precision up to 29 bits; they can be discarded + * without loss of resolution. + */ if (data_in & MPC624_EOC_BIT) - printk("MPC624: EOC bit is set (data_in=%lu)!", + printk(KERN_INFO "MPC624:EOC bit is set (data_in=%lu)!", data_in); if (data_in & MPC624_DMY_BIT) - printk("MPC624: DMY bit is set (data_in=%lu)!", + printk(KERN_INFO "MPC624:DMY bit is set (data_in=%lu)!", data_in); - if (data_in & MPC624_SGN_BIT) { /* check the sign bit *//* The voltage is positive */ - data_in &= 0x3FFFFFFF; /* EOC and DMY should be 0, but we will mask them out just to be sure */ - data[n] = data_in; /* comedi operates on unsigned numbers, so we don't clear the SGN bit */ - /* SGN bit is still set! It's correct, since we're converting to unsigned. */ - } else { /* The voltage is negative */ - /* data_in contains a number in 30-bit two's complement code and we must deal with it */ + if (data_in & MPC624_SGN_BIT) { /* Volatge is positive */ + /* + * comedi operates on unsigned numbers, so mask off EOC + * and DMY and don't clear the SGN bit + */ + data_in &= 0x3FFFFFFF; + data[n] = data_in; + } else { /* The voltage is negative */ + /* + * data_in contains a number in 30-bit two's complement + * code and we must deal with it + */ data_in |= MPC624_SGN_BIT; data_in = ~data_in; data_in += 1; -- cgit v1.2.3 From f0f29184d84bca9e070e48d61ef5ec8f3ff3cde5 Mon Sep 17 00:00:00 2001 From: Mark Rankilor Date: Mon, 3 May 2010 17:39:09 +0800 Subject: Staging: comedi: Moved some EXPORT_SYMBOL() macros This is a patch to range.c that rearranges some EXPORT_SYMBOL() macros to please checkpatch.pl Signed-off-by: Mark Rankilor Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/range.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c index 6b03a69762a4..8a1cefd97fdb 100644 --- a/drivers/staging/comedi/range.c +++ b/drivers/staging/comedi/range.c @@ -25,16 +25,16 @@ #include const struct comedi_lrange range_bipolar10 = { 1, {BIP_RANGE(10)} }; -const struct comedi_lrange range_bipolar5 = { 1, {BIP_RANGE(5)} }; -const struct comedi_lrange range_bipolar2_5 = { 1, {BIP_RANGE(2.5)} }; -const struct comedi_lrange range_unipolar10 = { 1, {UNI_RANGE(10)} }; -const struct comedi_lrange range_unipolar5 = { 1, {UNI_RANGE(5)} }; -const struct comedi_lrange range_unknown = { 1, {{0, 1000000, UNIT_none} } }; EXPORT_SYMBOL(range_bipolar10); +const struct comedi_lrange range_bipolar5 = { 1, {BIP_RANGE(5)} }; EXPORT_SYMBOL(range_bipolar5); +const struct comedi_lrange range_bipolar2_5 = { 1, {BIP_RANGE(2.5)} }; EXPORT_SYMBOL(range_bipolar2_5); +const struct comedi_lrange range_unipolar10 = { 1, {UNI_RANGE(10)} }; EXPORT_SYMBOL(range_unipolar10); +const struct comedi_lrange range_unipolar5 = { 1, {UNI_RANGE(5)} }; EXPORT_SYMBOL(range_unipolar5); +const struct comedi_lrange range_unknown = { 1, {{0, 1000000, UNIT_none} } }; EXPORT_SYMBOL(range_unknown); /* -- cgit v1.2.3 From aad4029a49e17d8529b8b802d4ecd774ef941f7c Mon Sep 17 00:00:00 2001 From: Mark Rankilor Date: Mon, 3 May 2010 18:07:36 +0800 Subject: Staging: comedi: Adjusted some long line lengths in drivers.c This patch fixes some long line lengths in drivers.c that checkpatch.pl was complaining about Signed-off-by: Mark Rankilor Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index d7a450917405..a8f3d790b3d5 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -172,7 +172,8 @@ attached: } if (!dev->board_name) { - printk(KERN_WARNING "BUG: dev->board_name=<%p>\n", dev->board_name); + printk(KERN_WARNING "BUG: dev->board_name=<%p>\n", + dev->board_name); dev->board_name = "BUG"; } smp_wmb(); @@ -374,8 +375,9 @@ static int insn_rw_emulate_bits(struct comedi_device *dev, if (insn->insn == INSN_WRITE) { if (!(s->subdev_flags & SDF_WRITABLE)) return -EINVAL; - new_data[0] = 1 << (chan - base_bitfield_channel); /* mask */ - new_data[1] = data[0] ? (1 << (chan - base_bitfield_channel)) : 0; /* bits */ + new_data[0] = 1 << (chan - base_bitfield_channel); /* mask */ + new_data[1] = data[0] ? (1 << (chan - base_bitfield_channel)) + : 0; /* bits */ } ret = s->insn_bits(dev, s, &new_insn, new_data); -- cgit v1.2.3 From 3b9fdcd5e85104e622c0ec5f626c81b831ddfae2 Mon Sep 17 00:00:00 2001 From: Iain Churcher Date: Mon, 3 May 2010 11:54:53 +0100 Subject: Staging: comedi: Fix all checkpatch.pl issues in dt2811.c Patch resolves all checkpatch.pl isues in dt2811.c Signed-off-by: Iain Churcher Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt2811.c | 191 +++++++++++++------------------- 1 file changed, 76 insertions(+), 115 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c index 51ef695698a3..ea9bfb7fd88e 100644 --- a/drivers/staging/comedi/drivers/dt2811.c +++ b/drivers/staging/comedi/drivers/dt2811.c @@ -34,13 +34,13 @@ Configuration options: [0] - I/O port base address [1] - IRQ, although this is currently unused [2] - A/D reference - 0 = signle-ended - 1 = differential + 0 = signle-ended + 1 = differential 2 = pseudo-differential (common reference) [3] - A/D range - 0 = [-5,5] - 1 = [-2.5,2.5] - 2 = [0,5] + 0 = [-5, 5] + 1 = [-2.5, 2.5] + 2 = [0, 5] [4] - D/A 0 range (same choices) [4] - D/A 1 range (same choices) */ @@ -52,96 +52,58 @@ Configuration options: static const char *driver_name = "dt2811"; -static const struct comedi_lrange range_dt2811_pgh_ai_5_unipolar = { 4, { - RANGE - (0, 5), - RANGE - (0, - 2.5), - RANGE - (0, - 1.25), - RANGE - (0, - 0.625) - } +static const struct comedi_lrange range_dt2811_pgh_ai_5_unipolar = { + 4, { + RANGE(0, 5), + RANGE(0, 2.5), + RANGE(0, 1.25), + RANGE(0, 0.625) + } }; -static const struct comedi_lrange range_dt2811_pgh_ai_2_5_bipolar = { 4, { - RANGE - (-2.5, - 2.5), - RANGE - (-1.25, - 1.25), - RANGE - (-0.625, - 0.625), - RANGE - (-0.3125, - 0.3125) - } +static const struct comedi_lrange range_dt2811_pgh_ai_2_5_bipolar = { + 4, { + RANGE(-2.5, 2.5), + RANGE(-1.25, 1.25), + RANGE(-0.625, 0.625), + RANGE(-0.3125, 0.3125) + } }; -static const struct comedi_lrange range_dt2811_pgh_ai_5_bipolar = { 4, { - RANGE - (-5, 5), - RANGE - (-2.5, - 2.5), - RANGE - (-1.25, - 1.25), - RANGE - (-0.625, - 0.625) - } +static const struct comedi_lrange range_dt2811_pgh_ai_5_bipolar = { + 4, { + RANGE(-5, 5), + RANGE(-2.5, 2.5), + RANGE(-1.25, 1.25), + RANGE(-0.625, 0.625) + } }; -static const struct comedi_lrange range_dt2811_pgl_ai_5_unipolar = { 4, { - RANGE - (0, 5), - RANGE - (0, - 0.5), - RANGE - (0, - 0.05), - RANGE - (0, - 0.01) - } +static const struct comedi_lrange range_dt2811_pgl_ai_5_unipolar = { + 4, { + RANGE(0, 5), + RANGE(0, 0.5), + RANGE(0, 0.05), + RANGE(0, 0.01) + } }; -static const struct comedi_lrange range_dt2811_pgl_ai_2_5_bipolar = { 4, { - RANGE - (-2.5, - 2.5), - RANGE - (-0.25, - 0.25), - RANGE - (-0.025, - 0.025), - RANGE - (-0.005, - 0.005) - } +static const struct comedi_lrange range_dt2811_pgl_ai_2_5_bipolar = { + 4, { + RANGE(-2.5, 2.5), + RANGE(-0.25, 0.25), + RANGE(-0.025, 0.025), + RANGE(-0.005, 0.005) + } }; -static const struct comedi_lrange range_dt2811_pgl_ai_5_bipolar = { 4, { - RANGE - (-5, 5), - RANGE - (-0.5, - 0.5), - RANGE - (-0.05, - 0.05), - RANGE - (-0.01, - 0.01) - } +static const struct comedi_lrange range_dt2811_pgl_ai_5_bipolar = { + 4, { + RANGE(-5, 5), + RANGE(-0.5, 0.5), + RANGE(-0.05, 0.05), + RANGE(-0.01, 0.01) + } }; /* @@ -348,21 +310,21 @@ static irqreturn_t dt2811_interrupt(int irq, void *d) options[0] Board base address options[1] IRQ options[2] Input configuration - 0 == single-ended - 1 == differential - 2 == pseudo-differential + 0 == single-ended + 1 == differential + 2 == pseudo-differential options[3] Analog input range configuration - 0 == bipolar 5 (-5V -- +5V) - 1 == bipolar 2.5V (-2.5V -- +2.5V) - 2 == unipolar 5V (0V -- +5V) + 0 == bipolar 5 (-5V -- +5V) + 1 == bipolar 2.5V (-2.5V -- +2.5V) + 2 == unipolar 5V (0V -- +5V) options[4] Analog output 0 range configuration - 0 == bipolar 5 (-5V -- +5V) - 1 == bipolar 2.5V (-2.5V -- +2.5V) - 2 == unipolar 5V (0V -- +5V) + 0 == bipolar 5 (-5V -- +5V) + 1 == bipolar 2.5V (-2.5V -- +2.5V) + 2 == unipolar 5V (0V -- +5V) options[5] Analog output 1 range configuration - 0 == bipolar 5 (-5V -- +5V) - 1 == bipolar 2.5V (-2.5V -- +2.5V) - 2 == unipolar 5V (0V -- +5V) + 0 == bipolar 5 (-5V -- +5V) + 1 == bipolar 2.5V (-2.5V -- +2.5V) + 2 == unipolar 5V (0V -- +5V) */ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) @@ -377,10 +339,10 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) iobase = it->options[0]; - printk("comedi%d: dt2811: base=0x%04lx\n", dev->minor, iobase); + printk(KERN_INFO "comedi%d: dt2811:base=0x%04lx\n", dev->minor, iobase); if (!request_region(iobase, DT2811_SIZE, driver_name)) { - printk("I/O port conflict\n"); + printk(KERN_ERR "I/O port conflict\n"); return -EIO; } @@ -410,25 +372,25 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) irq = probe_irq_off(irqs); restore_flags(flags); - /*outb(DT2811_CLRERROR|DT2811_INTENB,dev->iobase+DT2811_ADCSR); */ + /*outb(DT2811_CLRERROR|DT2811_INTENB, + dev->iobase+DT2811_ADCSR);*/ - if (inb(dev->iobase + DT2811_ADCSR) & DT2811_ADERROR) { - printk("error probing irq (bad) \n"); - } + if (inb(dev->iobase + DT2811_ADCSR) & DT2811_ADERROR) + printk(KERN_ERR "error probing irq (bad)\n"); dev->irq = 0; if (irq > 0) { i = inb(dev->iobase + DT2811_ADDATLO); i = inb(dev->iobase + DT2811_ADDATHI); - printk("(irq = %d)\n", irq); + printk(KERN_INFO "(irq = %d)\n", irq); ret = request_irq(irq, dt2811_interrupt, 0, driver_name, dev); if (ret < 0) return -EIO; dev->irq = irq; } else if (irq == 0) { - printk("(no irq)\n"); + printk(KERN_INFO "(no irq)\n"); } else { - printk("( multiple irq's -- this is bad! )\n"); + printk(KERN_ERR "( multiple irq's -- this is bad! )\n"); } } #endif @@ -540,14 +502,12 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) static int dt2811_detach(struct comedi_device *dev) { - printk("comedi%d: dt2811: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: dt2811: remove\n", dev->minor); - if (dev->irq) { + if (dev->irq) free_irq(dev->irq, dev); - } - if (dev->iobase) { + if (dev->iobase) release_region(dev->iobase, DT2811_SIZE); - } return 0; } @@ -579,7 +539,7 @@ static int dt2811_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s, #if 0 /* Wow. This is code from the Comedi stone age. But it hasn't been * replaced, so I'll let it stay. */ -int dt2811_adtrig(kdev_t minor, comedi_adtrig * adtrig) +int dt2811_adtrig(kdev_t minor, comedi_adtrig *adtrig) { struct comedi_device *dev = comedi_devices + minor; @@ -589,8 +549,10 @@ int dt2811_adtrig(kdev_t minor, comedi_adtrig * adtrig) switch (dev->i_admode) { case COMEDI_MDEMAND: dev->ntrig = adtrig->n - 1; + /* not neccessary */ /*printk("dt2811: AD soft trigger\n"); */ - /*outb(DT2811_CLRERROR|DT2811_INTENB,dev->iobase+DT2811_ADCSR); *//* not neccessary */ + /*outb(DT2811_CLRERROR|DT2811_INTENB, + dev->iobase+DT2811_ADCSR); */ outb(dev->curadchan, dev->iobase + DT2811_ADGCR); do_gettimeofday(&trigtime); break; @@ -630,9 +592,8 @@ static int dt2811_ao_insn_read(struct comedi_device *dev, chan = CR_CHAN(insn->chanspec); - for (i = 0; i < insn->n; i++) { + for (i = 0; i < insn->n; i++) data[i] = devpriv->ao_readback[chan]; - } return i; } -- cgit v1.2.3 From e6e4d05d4d440f1989f696baa146263957593345 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 3 May 2010 11:02:44 -0700 Subject: Staging: cxt1e1: fix cxt1e1 module names On Mon, 2010-05-03 at 10:09 -0700, Randy Dunlap wrote: > Lots of cxt1e1 source code uses THIS_MODULE->name, which won't build > when CONFIG_MODULES is not enabled, so use KBUILD_MODNAME instead. Perhaps a conversion to pr_ is better? Signed-off-by: Joe Perches Acked-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/staging/cxt1e1/functions.c | 4 ++- drivers/staging/cxt1e1/hwprobe.c | 28 ++++++++++---------- drivers/staging/cxt1e1/linux.c | 38 ++++++++++++++-------------- drivers/staging/cxt1e1/musycc.c | 13 +++++----- drivers/staging/cxt1e1/pmcc4_drv.c | 16 +++++++----- drivers/staging/cxt1e1/sbecom_inline_linux.h | 2 +- drivers/staging/cxt1e1/sbeproc.c | 8 +++--- 7 files changed, 58 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/cxt1e1/functions.c b/drivers/staging/cxt1e1/functions.c index c95c62dfb04b..738129d62bbf 100644 --- a/drivers/staging/cxt1e1/functions.c +++ b/drivers/staging/cxt1e1/functions.c @@ -11,6 +11,8 @@ * GNU General Public License for more details. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -117,7 +119,7 @@ watchdog_func (unsigned long arg) if (drvr_state != SBE_DRVR_AVAILABLE) { if (log_level >= LOG_MONITOR) - printk (KERN_WARNING "watchdog_func: drvr not available (%x)\n", drvr_state); + pr_warning("%s: drvr not available (%x)\n", __func__, drvr_state); return; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) diff --git a/drivers/staging/cxt1e1/hwprobe.c b/drivers/staging/cxt1e1/hwprobe.c index 0f9d6539a9a6..571fa1f7ddb4 100644 --- a/drivers/staging/cxt1e1/hwprobe.c +++ b/drivers/staging/cxt1e1/hwprobe.c @@ -12,6 +12,8 @@ * GNU General Public License for more details. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -230,7 +232,7 @@ c4_hdw_init (struct pci_dev * pdev, int found) /* our MUSYCC chip supports two functions, 0 & 1 */ if ((fun = PCI_FUNC (pdev->devfn)) > 1) { - printk (KERN_WARNING "%s: unexpected devfun: 0x%x\n", THIS_MODULE->name, pdev->devfn); + pr_warning("unexpected devfun: 0x%x\n", pdev->devfn); return 0; } if (pdev->bus) /* obtain bus number */ @@ -259,8 +261,7 @@ c4_hdw_init (struct pci_dev * pdev, int found) if (i == MAX_BOARDS) /* no match in above loop means MAX * exceeded */ { - printk (KERN_WARNING "%s: exceeded number of allowed devices (>%d)?\n", - THIS_MODULE->name, MAX_BOARDS); + pr_warning("exceeded number of allowed devices (>%d)?\n", MAX_BOARDS); return 0; } if (pdev->bus) @@ -319,7 +320,7 @@ c4hw_attach_all (void) } if (!found) { - printk (KERN_WARNING "%s: No boards found.\n", THIS_MODULE->name); + pr_warning("No boards found\n"); return ENODEV; } /* sanity check for consistant hardware found */ @@ -327,7 +328,8 @@ c4hw_attach_all (void) { if (hi->pci_slot != 0xff && (!hi->addr[0] || !hi->addr[1])) { - printk (KERN_WARNING "%s: something very wrong with pci_get_device.\n", hi->devname); + pr_warning("%s: something very wrong with pci_get_device\n", + hi->devname); return EIO; } } @@ -340,22 +342,22 @@ c4hw_attach_all (void) { if (request_mem_region (hi->addr[j], hi->len[j], hi->devname) == 0) { - printk (KERN_WARNING "%s: memory in use, addr=0x%lx, len=0x%lx ?\n", - hi->devname, hi->addr[j], hi->len[j]); + pr_warning("%s: memory in use, addr=0x%lx, len=0x%lx ?\n", + hi->devname, hi->addr[j], hi->len[j]); cleanup_ioremap (); return ENOMEM; } hi->addr_mapped[j] = (unsigned long) ioremap (hi->addr[j], hi->len[j]); if (!hi->addr_mapped[j]) { - printk (KERN_WARNING "%s: ioremap fails, addr=0x%lx, len=0x%lx ?\n", - hi->devname, hi->addr[j], hi->len[j]); + pr_warning("%s: ioremap fails, addr=0x%lx, len=0x%lx ?\n", + hi->devname, hi->addr[j], hi->len[j]); cleanup_ioremap (); return ENOMEM; } #ifdef SBE_MAP_DEBUG - printk (KERN_WARNING "%s: io remapped from phys %x to virt %x\n", - hi->devname, (u_int32_t) hi->addr[j], (u_int32_t) hi->addr_mapped[j]); + pr_warning("%s: io remapped from phys %x to virt %x\n", + hi->devname, (u_int32_t) hi->addr[j], (u_int32_t) hi->addr_mapped[j]); #endif } } @@ -371,8 +373,8 @@ c4hw_attach_all (void) pci_enable_device (hi->pdev[1])) { drvr_state = SBE_DRVR_DOWN; - printk (KERN_WARNING "%s: failed to enable card %d slot %d\n", - hi->devname, i, hi->pci_slot); + pr_warning("%s: failed to enable card %d slot %d\n", + hi->devname, i, hi->pci_slot); cleanup_devs (); cleanup_ioremap (); return EIO; diff --git a/drivers/staging/cxt1e1/linux.c b/drivers/staging/cxt1e1/linux.c index aee7018f9d3f..ce2942c097a6 100644 --- a/drivers/staging/cxt1e1/linux.c +++ b/drivers/staging/cxt1e1/linux.c @@ -12,6 +12,8 @@ * GNU General Public License for more details. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -563,13 +565,13 @@ create_chan (struct net_device * ndev, ci_t * ci, priv = OS_kmalloc (sizeof (struct c4_priv)); if (!priv) { - printk (KERN_WARNING "%s: no memory for net_device !\n", ci->devname); + pr_warning("%s: no memory for net_device !\n", ci->devname); return 0; } dev = alloc_hdlcdev (priv); if (!dev) { - printk (KERN_WARNING "%s: no memory for hdlc_device !\n", ci->devname); + pr_warning("%s: no memory for hdlc_device !\n", ci->devname); OS_kfree (priv); return 0; } @@ -1111,7 +1113,7 @@ c4_add_dev (hdw_info_t * hi, int brdno, unsigned long f0, unsigned long f1, ndev = alloc_netdev(sizeof(ci_t), SBE_IFACETMPL, c4_setup); if (!ndev) { - printk (KERN_WARNING "%s: no memory for struct net_device !\n", hi->devname); + pr_warning("%s: no memory for struct net_device !\n", hi->devname); error_flag = ENOMEM; return 0; } @@ -1177,8 +1179,7 @@ c4_add_dev (hdw_info_t * hi, int brdno, unsigned long f0, unsigned long f1, #endif ndev->name, ndev)) { - printk (KERN_WARNING "%s: MUSYCC could not get irq: %d\n", - ndev->name, irq0); + pr_warning("%s: MUSYCC could not get irq: %d\n", ndev->name, irq0); unregister_netdev (ndev); OS_kfree (netdev_priv(ndev)); OS_kfree (ndev); @@ -1188,8 +1189,7 @@ c4_add_dev (hdw_info_t * hi, int brdno, unsigned long f0, unsigned long f1, #ifdef CONFIG_SBE_PMCC4_NCOMM if (request_irq (irq1, &c4_ebus_interrupt, IRQF_SHARED, ndev->name, ndev)) { - printk (KERN_WARNING "%s: EBUS could not get irq: %d\n", - hi->devname, irq1); + pr_warning("%s: EBUS could not get irq: %d\n", hi->devname, irq1); unregister_netdev (ndev); free_irq (irq0, ndev); OS_kfree (netdev_priv(ndev)); @@ -1263,33 +1263,33 @@ c4_mod_init (void) { int rtn; - printk (KERN_WARNING "%s: %s\n", THIS_MODULE->name, pmcc4_OSSI_release); + pr_warning("%s\n", pmcc4_OSSI_release); if ((rtn = c4hw_attach_all ())) return -rtn; /* installation failure - see system log */ /* housekeeping notifications */ if (log_level != log_level_default) - printk (KERN_INFO "%s NOTE: driver parameter changed from default %d to %d.\n", - THIS_MODULE->name, log_level_default, log_level); + pr_info("NOTE: driver parameter changed from default %d to %d.\n", + log_level_default, log_level); if (max_mru != max_mru_default) - printk (KERN_INFO "%s NOTE: driver parameter changed from default %d to %d.\n", - THIS_MODULE->name, max_mru_default, max_mru); + pr_info("NOTE: driver parameter changed from default %d to %d.\n", + max_mru_default, max_mru); if (max_mtu != max_mtu_default) - printk (KERN_INFO "%s NOTE: driver parameter changed from default %d to %d.\n", - THIS_MODULE->name, max_mtu_default, max_mtu); + pr_info("NOTE: driver parameter changed from default %d to %d.\n", + max_mtu_default, max_mtu); if (max_rxdesc_used != max_rxdesc_default) { if (max_rxdesc_used > 2000) max_rxdesc_used = 2000; /* out-of-bounds reset */ - printk (KERN_INFO "%s NOTE: driver parameter changed from default %d to %d.\n", - THIS_MODULE->name, max_rxdesc_default, max_rxdesc_used); + pr_info("NOTE: driver parameter changed from default %d to %d.\n", + max_rxdesc_default, max_rxdesc_used); } if (max_txdesc_used != max_txdesc_default) { if (max_txdesc_used > 1000) max_txdesc_used = 1000; /* out-of-bounds reset */ - printk (KERN_INFO "%s NOTE: driver parameter changed from default %d to %d.\n", - THIS_MODULE->name, max_txdesc_default, max_txdesc_used); + pr_info("NOTE: driver parameter changed from default %d to %d.\n", + max_txdesc_default, max_txdesc_used); } return 0; /* installation success */ } @@ -1331,7 +1331,7 @@ c4_mod_remove (void) cleanup_devs (); c4_cleanup (); cleanup_ioremap (); - printk (KERN_INFO "SBE %s - driver removed.\n", THIS_MODULE->name); + pr_info("SBE - driver removed.\n"); } module_init (c4_mod_init); diff --git a/drivers/staging/cxt1e1/musycc.c b/drivers/staging/cxt1e1/musycc.c index 650c9c02f223..7a6d92a2215f 100644 --- a/drivers/staging/cxt1e1/musycc.c +++ b/drivers/staging/cxt1e1/musycc.c @@ -71,6 +71,7 @@ unsigned int max_bh = 0; char SBEid_pmcc4_musyccc[] = "@(#)musycc.c - $Revision: 2.1 $ (c) Copyright 2004-2006 SBE, Inc."; +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include "pmcc4_sysdep.h" @@ -681,8 +682,8 @@ rewrite: } if (rcnt > MUSYCC_SR_RETRY_CNT) { - printk (KERN_WARNING "%s: failed service request (#%d)= %x, group %d.\n", - pi->up->devname, MUSYCC_SR_RETRY_CNT, req, pi->portnum); + pr_warning("%s: failed service request (#%d)= %x, group %d.\n", + pi->up->devname, MUSYCC_SR_RETRY_CNT, req, pi->portnum); SD_SEM_GIVE (&pi->sr_sem_busy); /* allow any next request */ return; } @@ -959,14 +960,14 @@ musycc_init (ci_t * ci) if (max_mru > 0xffe) { - printk (KERN_WARNING "%s: Maximum allowed MRU exceeded, resetting %d to %d.\n", - THIS_MODULE->name, max_mru, 0xffe); + pr_warning("Maximum allowed MRU exceeded, resetting %d to %d.\n", + max_mru, 0xffe); max_mru = 0xffe; } if (max_mtu > 0xffe) { - printk (KERN_WARNING "%s: Maximum allowed MTU exceeded, resetting %d to %d.\n", - THIS_MODULE->name, max_mtu, 0xffe); + pr_warning("Maximum allowed MTU exceeded, resetting %d to %d.\n", + max_mtu, 0xffe); max_mtu = 0xffe; } #ifdef SBE_WAN256T3_ENABLE diff --git a/drivers/staging/cxt1e1/pmcc4_drv.c b/drivers/staging/cxt1e1/pmcc4_drv.c index ada80d0b6059..1617333575ce 100644 --- a/drivers/staging/cxt1e1/pmcc4_drv.c +++ b/drivers/staging/cxt1e1/pmcc4_drv.c @@ -83,6 +83,7 @@ char OSSIid_pmcc4_drvc[] = "@(#)pmcc4_drv.c - $Revision: 3.1 $ (c) Copyright 2002-2007 One Stop Systems, Inc."; +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #if defined (__FreeBSD__) || defined (__NetBSD__) #include @@ -207,8 +208,8 @@ c4_new (void *hi) ci_t *ci; #ifdef SBE_MAP_DEBUG - printk (KERN_WARNING "%s: c4_new() entered, ci needs %u.\n", - THIS_MODULE->name, (unsigned int) sizeof (ci_t)); + pr_warning("c4_new() entered, ci needs %u.\n", + (unsigned int) sizeof (ci_t)); #endif ci = (ci_t *) OS_kmalloc (sizeof (ci_t)); @@ -220,8 +221,8 @@ c4_new (void *hi) c4_list = ci; ci->brdno = ci->next ? ci->next->brdno + 1 : 0; } else - printk (KERN_WARNING "%s: failed CI malloc, size %u.\n", - THIS_MODULE->name, (unsigned int) sizeof (ci_t)); + pr_warning("failed CI malloc, size %u.\n", + (unsigned int) sizeof (ci_t)); if (CI == 0) CI = ci; /* DEBUG, only board 0 usage */ @@ -805,7 +806,8 @@ c4_init (ci_t * ci, u_char *func0, u_char *func1) break; default: ci->max_port = 0; - printk (KERN_WARNING "%s: illegal port configuration (%x)\n", ci->devname, pmsk); + pr_warning("%s: illegal port configuration (%x)\n", + ci->devname, pmsk); return SBE_DRVR_FAIL; } #ifdef SBE_MAP_DEBUG @@ -847,8 +849,8 @@ c4_init (ci_t * ci, u_char *func0, u_char *func1) ch->p.mode_56k = 0; /* default is 64kbps mode */ } else { - printk (KERN_WARNING "%s: failed mch_t malloc, port %d channel %d size %u.\n", - THIS_MODULE->name, portnum, j, (unsigned int) sizeof (mch_t)); + pr_warning("failed mch_t malloc, port %d channel %d size %u.\n", + portnum, j, (unsigned int) sizeof (mch_t)); break; } } diff --git a/drivers/staging/cxt1e1/sbecom_inline_linux.h b/drivers/staging/cxt1e1/sbecom_inline_linux.h index 2ab1eb12ed38..44229a93de4e 100644 --- a/drivers/staging/cxt1e1/sbecom_inline_linux.h +++ b/drivers/staging/cxt1e1/sbecom_inline_linux.h @@ -164,7 +164,7 @@ OS_mem_token_alloc (size_t size) skb = dev_alloc_skb (size); if (!skb) { - //printk (KERN_WARNING "no mem in OS_mem_token_alloc !"); + //pr_warning("no mem in OS_mem_token_alloc !\n"); return 0; } return skb; diff --git a/drivers/staging/cxt1e1/sbeproc.c b/drivers/staging/cxt1e1/sbeproc.c index 61ca639c184f..92f6f5ca39be 100644 --- a/drivers/staging/cxt1e1/sbeproc.c +++ b/drivers/staging/cxt1e1/sbeproc.c @@ -11,6 +11,8 @@ * GNU General Public License for more details. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -318,16 +320,14 @@ sbecom_proc_brd_init (ci_t * ci) ci->dir_dev = proc_mkdir(dir, NULL); if (!ci->dir_dev) { - printk (KERN_ERR "%s: Unable to create directory /proc/driver/%s\n", - THIS_MODULE->name, ci->devname); + pr_err("Unable to create directory /proc/driver/%s\n", ci->devname); goto fail; } e = create_proc_read_entry ("info", S_IFREG | S_IRUGO, ci->dir_dev, sbecom_proc_get_sbe_info, ci); if (!e) { - printk (KERN_ERR "%s: Unable to create entry /proc/driver/%s/info\n", - THIS_MODULE->name, ci->devname); + pr_err("Unable to create entry /proc/driver/%s/info\n", ci->devname); goto fail; } return 0; -- cgit v1.2.3 From c9f772570123b94ce63563893adb0c492d05eda4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 May 2010 14:36:56 -0700 Subject: Staging: comedi: kcomedilib: dio.c: remove unused functions Remove the unused functions from the dio.c file as they are not needed. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/kcomedilib/dio.c | 30 ------------------------------ 1 file changed, 30 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/kcomedilib/dio.c b/drivers/staging/comedi/kcomedilib/dio.c index e37aa5308141..f0ba81d4b9ef 100644 --- a/drivers/staging/comedi/kcomedilib/dio.c +++ b/drivers/staging/comedi/kcomedilib/dio.c @@ -43,36 +43,6 @@ int comedi_dio_config(void *dev, unsigned int subdev, unsigned int chan, } EXPORT_SYMBOL(comedi_dio_config); -int comedi_dio_read(void *dev, unsigned int subdev, unsigned int chan, - unsigned int *val) -{ - struct comedi_insn insn; - - memset(&insn, 0, sizeof(insn)); - insn.insn = INSN_READ; - insn.n = 1; - insn.data = val; - insn.subdev = subdev; - insn.chanspec = CR_PACK(chan, 0, 0); - - return comedi_do_insn(dev, &insn); -} - -int comedi_dio_write(void *dev, unsigned int subdev, unsigned int chan, - unsigned int val) -{ - struct comedi_insn insn; - - memset(&insn, 0, sizeof(insn)); - insn.insn = INSN_WRITE; - insn.n = 1; - insn.data = &val; - insn.subdev = subdev; - insn.chanspec = CR_PACK(chan, 0, 0); - - return comedi_do_insn(dev, &insn); -} - int comedi_dio_bitfield(void *dev, unsigned int subdev, unsigned int mask, unsigned int *bits) { -- cgit v1.2.3 From 6b18af18d2c48c07864cf38b5475a0f4d1913bc4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 May 2010 14:41:28 -0700 Subject: Staging: comedi: kcomedilib: kcomedilib_main.c: remove unused functions Remove the unused functions from the kcomedilib_main.c file as they are not needed. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/kcomedilib/kcomedilib_main.c | 354 --------------------- 1 file changed, 354 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c index 32c7bbb8d78a..addfcd5a7a7f 100644 --- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c +++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c @@ -70,25 +70,6 @@ void *comedi_open(const char *filename) } EXPORT_SYMBOL(comedi_open); -void *comedi_open_old(unsigned int minor) -{ - struct comedi_device_file_info *dev_file_info; - struct comedi_device *dev; - - if (minor >= COMEDI_NUM_MINORS) - return NULL; - - dev_file_info = comedi_get_device_file_info(minor); - if (dev_file_info == NULL) - return NULL; - dev = dev_file_info->device; - - if (dev == NULL || !dev->attached) - return NULL; - - return (void *)dev; -} - int comedi_close(void *d) { struct comedi_device *dev = (struct comedi_device *)d; @@ -99,83 +80,6 @@ int comedi_close(void *d) } EXPORT_SYMBOL(comedi_close); -int comedi_loglevel(int newlevel) -{ - return 0; -} - -void comedi_perror(const char *message) -{ - printk(KERN_ERR "%s: unknown error\n", message); -} - -char *comedi_strerror(int err) -{ - return "unknown error"; -} - -int comedi_fileno(void *d) -{ - struct comedi_device *dev = (struct comedi_device *)d; - - /* return something random */ - return dev->minor; -} - -int comedi_command(void *d, struct comedi_cmd *cmd) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s; - struct comedi_async *async; - unsigned runflags; - - if (cmd->subdev >= dev->n_subdevices) - return -ENODEV; - - s = dev->subdevices + cmd->subdev; - if (s->type == COMEDI_SUBD_UNUSED) - return -EIO; - - async = s->async; - if (async == NULL) - return -ENODEV; - - if (s->busy) - return -EBUSY; - s->busy = d; - - if (async->cb_mask & COMEDI_CB_EOS) - cmd->flags |= TRIG_WAKE_EOS; - - async->cmd = *cmd; - - runflags = SRF_RUNNING; - - comedi_set_subdevice_runflags(s, ~0, runflags); - - comedi_reset_async_buf(async); - - return s->do_cmd(dev, s); -} - -int comedi_command_test(void *d, struct comedi_cmd *cmd) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s; - - if (cmd->subdev >= dev->n_subdevices) - return -ENODEV; - - s = dev->subdevices + cmd->subdev; - if (s->type == COMEDI_SUBD_UNUSED) - return -EIO; - - if (s->async == NULL) - return -ENODEV; - - return s->do_cmdtest(dev, s, cmd); -} - /* * COMEDI_INSN * perform an instruction @@ -302,261 +206,3 @@ error: return ret; } -/* - COMEDI_LOCK - lock subdevice - - arg: - subdevice number - - reads: - none - - writes: - none - - necessary locking: - - ioctl/rt lock (this type) - - lock while subdevice busy - - lock while subdevice being programmed - -*/ -int comedi_lock(void *d, unsigned int subdevice) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s; - unsigned long flags; - int ret = 0; - - if (subdevice >= dev->n_subdevices) - return -EINVAL; - - s = dev->subdevices + subdevice; - - spin_lock_irqsave(&s->spin_lock, flags); - - if (s->busy) { - ret = -EBUSY; - } else { - if (s->lock) { - ret = -EBUSY; - } else { - s->lock = d; - } - } - - spin_unlock_irqrestore(&s->spin_lock, flags); - - return ret; -} - -/* - COMEDI_UNLOCK - unlock subdevice - - arg: - subdevice number - - reads: - none - - writes: - none - -*/ -int comedi_unlock(void *d, unsigned int subdevice) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s; - unsigned long flags; - struct comedi_async *async; - int ret; - - if (subdevice >= dev->n_subdevices) - return -EINVAL; - - s = dev->subdevices + subdevice; - - async = s->async; - - spin_lock_irqsave(&s->spin_lock, flags); - - if (s->busy) { - ret = -EBUSY; - } else if (s->lock && s->lock != (void *)d) { - ret = -EACCES; - } else { - s->lock = NULL; - - if (async) { - async->cb_mask = 0; - async->cb_func = NULL; - async->cb_arg = NULL; - } - - ret = 0; - } - - spin_unlock_irqrestore(&s->spin_lock, flags); - - return ret; -} - -/* - COMEDI_CANCEL - cancel acquisition ioctl - - arg: - subdevice number - - reads: - nothing - - writes: - nothing - -*/ -int comedi_cancel(void *d, unsigned int subdevice) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s; - int ret = 0; - - if (subdevice >= dev->n_subdevices) - return -EINVAL; - - s = dev->subdevices + subdevice; - - if (s->lock && s->lock != d) - return -EACCES; - -#if 0 - if (!s->busy) - return 0; - - if (s->busy != d) - return -EBUSY; -#endif - - if (!s->cancel || !s->async) - return -EINVAL; - - ret = s->cancel(dev, s); - - if (ret) - return ret; - - comedi_set_subdevice_runflags(s, SRF_RUNNING | SRF_RT, 0); - s->async->inttrig = NULL; - s->busy = NULL; - - return 0; -} - -/* - registration of callback functions - */ -int comedi_register_callback(void *d, unsigned int subdevice, - unsigned int mask, int (*cb) (unsigned int, - void *), void *arg) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s; - struct comedi_async *async; - - if (subdevice >= dev->n_subdevices) - return -EINVAL; - - s = dev->subdevices + subdevice; - - async = s->async; - if (s->type == COMEDI_SUBD_UNUSED || !async) - return -EIO; - - /* are we locked? (ioctl lock) */ - if (s->lock && s->lock != d) - return -EACCES; - - /* are we busy? */ - if (s->busy) - return -EBUSY; - - if (!mask) { - async->cb_mask = 0; - async->cb_func = NULL; - async->cb_arg = NULL; - } else { - async->cb_mask = mask; - async->cb_func = cb; - async->cb_arg = arg; - } - - return 0; -} - -int comedi_poll(void *d, unsigned int subdevice) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s = dev->subdevices; - struct comedi_async *async; - - if (subdevice >= dev->n_subdevices) - return -EINVAL; - - s = dev->subdevices + subdevice; - - async = s->async; - if (s->type == COMEDI_SUBD_UNUSED || !async) - return -EIO; - - /* are we locked? (ioctl lock) */ - if (s->lock && s->lock != d) - return -EACCES; - - /* are we running? XXX wrong? */ - if (!s->busy) - return -EIO; - - return s->poll(dev, s); -} - -/* WARNING: not portable */ -int comedi_map(void *d, unsigned int subdevice, void *ptr) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s; - - if (subdevice >= dev->n_subdevices) - return -EINVAL; - - s = dev->subdevices + subdevice; - - if (!s->async) - return -EINVAL; - - if (ptr) - *((void **)ptr) = s->async->prealloc_buf; - - /* XXX no reference counting */ - - return 0; -} - -/* WARNING: not portable */ -int comedi_unmap(void *d, unsigned int subdevice) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s; - - if (subdevice >= dev->n_subdevices) - return -EINVAL; - - s = dev->subdevices + subdevice; - - if (!s->async) - return -EINVAL; - - /* XXX no reference counting */ - - return 0; -} -- cgit v1.2.3 From a1525758c848aedf590bba3a919321e2d80fcd6e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 May 2010 14:44:55 -0700 Subject: Staging: comedi: kcomedilib: delete dio.c and get.c Merge these two files into kcomedilib_main.c as they are tiny. This will also let us get rid of another global symbol in the future. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/kcomedilib/Makefile | 5 +- drivers/staging/comedi/kcomedilib/dio.c | 68 ---------------------- drivers/staging/comedi/kcomedilib/get.c | 51 ---------------- .../staging/comedi/kcomedilib/kcomedilib_main.c | 63 ++++++++++++++++++++ 4 files changed, 64 insertions(+), 123 deletions(-) delete mode 100644 drivers/staging/comedi/kcomedilib/dio.c delete mode 100644 drivers/staging/comedi/kcomedilib/get.c (limited to 'drivers') diff --git a/drivers/staging/comedi/kcomedilib/Makefile b/drivers/staging/comedi/kcomedilib/Makefile index 006aa1ce4a13..5951f86a840e 100644 --- a/drivers/staging/comedi/kcomedilib/Makefile +++ b/drivers/staging/comedi/kcomedilib/Makefile @@ -1,6 +1,3 @@ obj-$(CONFIG_COMEDI) += kcomedilib.o -kcomedilib-objs := \ - dio.o \ - kcomedilib_main.o \ - get.o +kcomedilib-objs := kcomedilib_main.o diff --git a/drivers/staging/comedi/kcomedilib/dio.c b/drivers/staging/comedi/kcomedilib/dio.c deleted file mode 100644 index f0ba81d4b9ef..000000000000 --- a/drivers/staging/comedi/kcomedilib/dio.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - kcomedilib/dio.c - implements comedi_dio_*() functions - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 2000 David A. Schleef - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include "../comedi.h" -#include "../comedilib.h" - -#include -#include - -int comedi_dio_config(void *dev, unsigned int subdev, unsigned int chan, - unsigned int io) -{ - struct comedi_insn insn; - - memset(&insn, 0, sizeof(insn)); - insn.insn = INSN_CONFIG; - insn.n = 1; - insn.data = &io; - insn.subdev = subdev; - insn.chanspec = CR_PACK(chan, 0, 0); - - return comedi_do_insn(dev, &insn); -} -EXPORT_SYMBOL(comedi_dio_config); - -int comedi_dio_bitfield(void *dev, unsigned int subdev, unsigned int mask, - unsigned int *bits) -{ - struct comedi_insn insn; - unsigned int data[2]; - int ret; - - memset(&insn, 0, sizeof(insn)); - insn.insn = INSN_BITS; - insn.n = 2; - insn.data = data; - insn.subdev = subdev; - - data[0] = mask; - data[1] = *bits; - - ret = comedi_do_insn(dev, &insn); - - *bits = data[1]; - - return ret; -} -EXPORT_SYMBOL(comedi_dio_bitfield); diff --git a/drivers/staging/comedi/kcomedilib/get.c b/drivers/staging/comedi/kcomedilib/get.c deleted file mode 100644 index 99ab27ab8054..000000000000 --- a/drivers/staging/comedi/kcomedilib/get.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - kcomedilib/get.c - a comedlib interface for kernel modules - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 1997-2000 David A. Schleef - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#define __NO_VERSION__ -#include "../comedi.h" -#include "../comedilib.h" -#include "../comedidev.h" - -int comedi_find_subdevice_by_type(void *d, int type, unsigned int subd) -{ - struct comedi_device *dev = (struct comedi_device *)d; - - if (subd > dev->n_subdevices) - return -ENODEV; - - for (; subd < dev->n_subdevices; subd++) { - if (dev->subdevices[subd].type == type) - return subd; - } - return -1; -} -EXPORT_SYMBOL(comedi_find_subdevice_by_type); - -int comedi_get_n_channels(void *d, unsigned int subdevice) -{ - struct comedi_device *dev = (struct comedi_device *)d; - struct comedi_subdevice *s = dev->subdevices + subdevice; - - return s->n_chan; -} -EXPORT_SYMBOL(comedi_get_n_channels); diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c index addfcd5a7a7f..7cb29f2bc862 100644 --- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c +++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c @@ -206,3 +206,66 @@ error: return ret; } +int comedi_dio_config(void *dev, unsigned int subdev, unsigned int chan, + unsigned int io) +{ + struct comedi_insn insn; + + memset(&insn, 0, sizeof(insn)); + insn.insn = INSN_CONFIG; + insn.n = 1; + insn.data = &io; + insn.subdev = subdev; + insn.chanspec = CR_PACK(chan, 0, 0); + + return comedi_do_insn(dev, &insn); +} +EXPORT_SYMBOL(comedi_dio_config); + +int comedi_dio_bitfield(void *dev, unsigned int subdev, unsigned int mask, + unsigned int *bits) +{ + struct comedi_insn insn; + unsigned int data[2]; + int ret; + + memset(&insn, 0, sizeof(insn)); + insn.insn = INSN_BITS; + insn.n = 2; + insn.data = data; + insn.subdev = subdev; + + data[0] = mask; + data[1] = *bits; + + ret = comedi_do_insn(dev, &insn); + + *bits = data[1]; + + return ret; +} +EXPORT_SYMBOL(comedi_dio_bitfield); + +int comedi_find_subdevice_by_type(void *d, int type, unsigned int subd) +{ + struct comedi_device *dev = (struct comedi_device *)d; + + if (subd > dev->n_subdevices) + return -ENODEV; + + for (; subd < dev->n_subdevices; subd++) { + if (dev->subdevices[subd].type == type) + return subd; + } + return -1; +} +EXPORT_SYMBOL(comedi_find_subdevice_by_type); + +int comedi_get_n_channels(void *d, unsigned int subdevice) +{ + struct comedi_device *dev = (struct comedi_device *)d; + struct comedi_subdevice *s = dev->subdevices + subdevice; + + return s->n_chan; +} +EXPORT_SYMBOL(comedi_get_n_channels); -- cgit v1.2.3 From 88cccef0193a7f8c6a73326404c0b2f9ad27f71a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 May 2010 14:49:54 -0700 Subject: Staging: comedi: kcomedilib: comedi_do_insn is now static No one else calls this function, so mark it static. Now we can strip out the unneeded functionality in here as well. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedilib.h | 3 --- drivers/staging/comedi/kcomedilib/kcomedilib_main.c | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedilib.h b/drivers/staging/comedi/comedilib.h index 00414359138d..23ec58d2e239 100644 --- a/drivers/staging/comedi/comedilib.h +++ b/drivers/staging/comedi/comedilib.h @@ -33,7 +33,4 @@ int comedi_dio_bitfield(void *dev, unsigned int subdev, unsigned int mask, int comedi_find_subdevice_by_type(void *dev, int type, unsigned int subd); int comedi_get_n_channels(void *dev, unsigned int subdevice); -/* internal to kcomedilb */ -int comedi_do_insn(void *dev, struct comedi_insn *insn); - #endif diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c index 7cb29f2bc862..d27de93ff4dd 100644 --- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c +++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c @@ -84,7 +84,7 @@ EXPORT_SYMBOL(comedi_close); * COMEDI_INSN * perform an instruction */ -int comedi_do_insn(void *d, struct comedi_insn *insn) +static int comedi_do_insn(void *d, struct comedi_insn *insn) { struct comedi_device *dev = (struct comedi_device *)d; struct comedi_subdevice *s; -- cgit v1.2.3 From 3781bc5425f985c2ceffa3b2111e1d0eeb38cc24 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 May 2010 14:54:34 -0700 Subject: Staging: comedi: kcomedilib: simplify comedi_do_insn() Now that we know we are only making 2 different types of instructions, only handle those two types. Also make the call a bit more typesafe by passing the correct pointer type. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/kcomedilib/kcomedilib_main.c | 150 ++++++--------------- 1 file changed, 38 insertions(+), 112 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c index d27de93ff4dd..fa0db41292da 100644 --- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c +++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c @@ -80,127 +80,53 @@ int comedi_close(void *d) } EXPORT_SYMBOL(comedi_close); -/* - * COMEDI_INSN - * perform an instruction - */ -static int comedi_do_insn(void *d, struct comedi_insn *insn) +static int comedi_do_insn(struct comedi_device *dev, struct comedi_insn *insn) { - struct comedi_device *dev = (struct comedi_device *)d; struct comedi_subdevice *s; int ret = 0; - if (insn->insn & INSN_MASK_SPECIAL) { - switch (insn->insn) { - case INSN_GTOD: - { - struct timeval tv; - - do_gettimeofday(&tv); - insn->data[0] = tv.tv_sec; - insn->data[1] = tv.tv_usec; - ret = 2; - - break; - } - case INSN_WAIT: - /* XXX isn't the value supposed to be nanosecs? */ - if (insn->n != 1 || insn->data[0] >= 100) { - ret = -EINVAL; - break; - } - udelay(insn->data[0]); - ret = 1; - break; - case INSN_INTTRIG: - if (insn->n != 1) { - ret = -EINVAL; - break; - } - if (insn->subdev >= dev->n_subdevices) { - printk("%d not usable subdevice\n", - insn->subdev); - ret = -EINVAL; - break; - } - s = dev->subdevices + insn->subdev; - if (!s->async) { - printk("no async\n"); - ret = -EINVAL; - break; - } - if (!s->async->inttrig) { - printk("no inttrig\n"); - ret = -EAGAIN; - break; - } - ret = s->async->inttrig(dev, s, insn->data[0]); - if (ret >= 0) - ret = 1; - break; - default: - ret = -EINVAL; - } - } else { - /* a subdevice instruction */ - if (insn->subdev >= dev->n_subdevices) { - ret = -EINVAL; - goto error; - } - s = dev->subdevices + insn->subdev; - - if (s->type == COMEDI_SUBD_UNUSED) { - printk("%d not useable subdevice\n", insn->subdev); - ret = -EIO; - goto error; - } - - /* XXX check lock */ - - ret = comedi_check_chanlist(s, 1, &insn->chanspec); - if (ret < 0) { - printk("bad chanspec\n"); - ret = -EINVAL; - goto error; - } - - if (s->busy) { - ret = -EBUSY; - goto error; - } - s->busy = d; - - switch (insn->insn) { - case INSN_READ: - ret = s->insn_read(dev, s, insn, insn->data); - break; - case INSN_WRITE: - ret = s->insn_write(dev, s, insn, insn->data); - break; - case INSN_BITS: - ret = s->insn_bits(dev, s, insn, insn->data); - break; - case INSN_CONFIG: - /* XXX should check instruction length */ - ret = s->insn_config(dev, s, insn, insn->data); - break; - default: - ret = -EINVAL; - break; - } - - s->busy = NULL; + /* a subdevice instruction */ + if (insn->subdev >= dev->n_subdevices) { + ret = -EINVAL; + goto error; } - if (ret < 0) + s = dev->subdevices + insn->subdev; + + if (s->type == COMEDI_SUBD_UNUSED) { + printk("%d not useable subdevice\n", insn->subdev); + ret = -EIO; goto error; -#if 0 - /* XXX do we want this? -- abbotti #if'ed it out for now. */ - if (ret != insn->n) { - printk("BUG: result of insn != insn.n\n"); + } + + /* XXX check lock */ + + ret = comedi_check_chanlist(s, 1, &insn->chanspec); + if (ret < 0) { + printk("bad chanspec\n"); ret = -EINVAL; goto error; } -#endif + + if (s->busy) { + ret = -EBUSY; + goto error; + } + s->busy = dev; + + switch (insn->insn) { + case INSN_BITS: + ret = s->insn_bits(dev, s, insn, insn->data); + break; + case INSN_CONFIG: + /* XXX should check instruction length */ + ret = s->insn_config(dev, s, insn, insn->data); + break; + default: + ret = -EINVAL; + break; + } + + s->busy = NULL; error: return ret; -- cgit v1.2.3 From 472dfe77b91d8026c3ccda22c60db0e92bc27863 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 May 2010 15:01:50 -0700 Subject: Staging: comedi: kcomedilib: make it typesafe If we really are passing in a struct comedi_device, then say we are, don't mess around with void pointers for no reason. This also fixes up the comedi_bond.c driver, which is the only user of the kcomedilib code. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedilib.h | 17 +++++++++-------- drivers/staging/comedi/drivers/comedi_bond.c | 6 +++--- .../staging/comedi/kcomedilib/kcomedilib_main.c | 22 ++++++++++------------ 3 files changed, 22 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedilib.h b/drivers/staging/comedi/comedilib.h index 23ec58d2e239..ca92c43fdb38 100644 --- a/drivers/staging/comedi/comedilib.h +++ b/drivers/staging/comedi/comedilib.h @@ -24,13 +24,14 @@ #ifndef _LINUX_COMEDILIB_H #define _LINUX_COMEDILIB_H -void *comedi_open(const char *path); -int comedi_close(void *dev); -int comedi_dio_config(void *dev, unsigned int subdev, unsigned int chan, - unsigned int io); -int comedi_dio_bitfield(void *dev, unsigned int subdev, unsigned int mask, - unsigned int *bits); -int comedi_find_subdevice_by_type(void *dev, int type, unsigned int subd); -int comedi_get_n_channels(void *dev, unsigned int subdevice); +struct comedi_device *comedi_open(const char *path); +int comedi_close(struct comedi_device *dev); +int comedi_dio_config(struct comedi_device *dev, unsigned int subdev, + unsigned int chan, unsigned int io); +int comedi_dio_bitfield(struct comedi_device *dev, unsigned int subdev, + unsigned int mask, unsigned int *bits); +int comedi_find_subdevice_by_type(struct comedi_device *dev, int type, + unsigned int subd); +int comedi_get_n_channels(struct comedi_device *dev, unsigned int subdevice); #endif diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index 429ec703d596..22a0f996eeb0 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -142,7 +142,7 @@ static const struct BondingBoard bondingBoards[] = { #define thisboard ((const struct BondingBoard *)dev->board_ptr) struct BondedDevice { - void *dev; + struct comedi_device *dev; unsigned minor; unsigned subdev; unsigned subdev_type; @@ -404,7 +404,7 @@ static void *Realloc(const void *oldmem, size_t newlen, size_t oldlen) static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it) { int i; - void *devs_opened[COMEDI_NUM_BOARD_MINORS]; + struct comedi_device *devs_opened[COMEDI_NUM_BOARD_MINORS]; memset(devs_opened, 0, sizeof(devs_opened)); devpriv->name[0] = 0;; @@ -413,7 +413,7 @@ static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it) for (i = 0; i < COMEDI_NDEVCONFOPTS && (!i || it->options[i]); ++i) { char file[] = "/dev/comediXXXXXX"; int minor = it->options[i]; - void *d; + struct comedi_device *d; int sdev = -1, nchans, tmp; struct BondedDevice *bdev = NULL; diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c index fa0db41292da..863aae40edeb 100644 --- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c +++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c @@ -41,7 +41,7 @@ MODULE_AUTHOR("David Schleef "); MODULE_DESCRIPTION("Comedi kernel library"); MODULE_LICENSE("GPL"); -void *comedi_open(const char *filename) +struct comedi_device *comedi_open(const char *filename) { struct comedi_device_file_info *dev_file_info; struct comedi_device *dev; @@ -66,11 +66,11 @@ void *comedi_open(const char *filename) if (!try_module_get(dev->driver->module)) return NULL; - return (void *)dev; + return dev; } EXPORT_SYMBOL(comedi_open); -int comedi_close(void *d) +int comedi_close(struct comedi_device *d) { struct comedi_device *dev = (struct comedi_device *)d; @@ -132,8 +132,8 @@ error: return ret; } -int comedi_dio_config(void *dev, unsigned int subdev, unsigned int chan, - unsigned int io) +int comedi_dio_config(struct comedi_device *dev, unsigned int subdev, + unsigned int chan, unsigned int io) { struct comedi_insn insn; @@ -148,8 +148,8 @@ int comedi_dio_config(void *dev, unsigned int subdev, unsigned int chan, } EXPORT_SYMBOL(comedi_dio_config); -int comedi_dio_bitfield(void *dev, unsigned int subdev, unsigned int mask, - unsigned int *bits) +int comedi_dio_bitfield(struct comedi_device *dev, unsigned int subdev, + unsigned int mask, unsigned int *bits) { struct comedi_insn insn; unsigned int data[2]; @@ -172,10 +172,9 @@ int comedi_dio_bitfield(void *dev, unsigned int subdev, unsigned int mask, } EXPORT_SYMBOL(comedi_dio_bitfield); -int comedi_find_subdevice_by_type(void *d, int type, unsigned int subd) +int comedi_find_subdevice_by_type(struct comedi_device *dev, int type, + unsigned int subd) { - struct comedi_device *dev = (struct comedi_device *)d; - if (subd > dev->n_subdevices) return -ENODEV; @@ -187,9 +186,8 @@ int comedi_find_subdevice_by_type(void *d, int type, unsigned int subd) } EXPORT_SYMBOL(comedi_find_subdevice_by_type); -int comedi_get_n_channels(void *d, unsigned int subdevice) +int comedi_get_n_channels(struct comedi_device *dev, unsigned int subdevice) { - struct comedi_device *dev = (struct comedi_device *)d; struct comedi_subdevice *s = dev->subdevices + subdevice; return s->n_chan; -- cgit v1.2.3 From 181bd67bf5780b941f2cba6247ed1c0cdfce468a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 May 2010 15:15:06 -0700 Subject: Staging: comedi: make comedi_set_subdevice_runflags() static No one calls this anymore, except the core comedi code, so mark it static and don't export it. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 23 +++++++++++------------ drivers/staging/comedi/comedidev.h | 2 -- 2 files changed, 11 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index b11f9b08000b..135c80ab6d10 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -954,6 +954,17 @@ error: return ret; } +static void comedi_set_subdevice_runflags(struct comedi_subdevice *s, + unsigned mask, unsigned bits) +{ + unsigned long flags; + + spin_lock_irqsave(&s->spin_lock, flags); + s->runflags &= ~mask; + s->runflags |= (bits & mask); + spin_unlock_irqrestore(&s->spin_lock, flags); +} + /* COMEDI_CMD command ioctl @@ -2021,18 +2032,6 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) } EXPORT_SYMBOL(comedi_event); -void comedi_set_subdevice_runflags(struct comedi_subdevice *s, unsigned mask, - unsigned bits) -{ - unsigned long flags; - - spin_lock_irqsave(&s->spin_lock, flags); - s->runflags &= ~mask; - s->runflags |= (bits & mask); - spin_unlock_irqrestore(&s->spin_lock, flags); -} -EXPORT_SYMBOL(comedi_set_subdevice_runflags); - unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s) { unsigned long flags; diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 5e4672751d42..9e13964ac6d3 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -383,8 +383,6 @@ enum subdevice_runflags { int do_rangeinfo_ioctl(struct comedi_device *dev, struct comedi_rangeinfo *arg); int comedi_check_chanlist(struct comedi_subdevice *s, int n, unsigned int *chanlist); -void comedi_set_subdevice_runflags(struct comedi_subdevice *s, unsigned mask, - unsigned bits); unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s); int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); -- cgit v1.2.3 From 242e7ad91a067243d7ab63b6a25ed2e085733446 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 May 2010 15:20:29 -0700 Subject: Staging: comedi: make comedi_alloc_board_minor local to comedi core No one outside of the comedi core calls this function, so create an internal.h file to put the prototype in, and don't export it to the world. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 3 +-- drivers/staging/comedi/comedidev.h | 1 - drivers/staging/comedi/drivers.c | 5 +++-- drivers/staging/comedi/internal.h | 2 ++ 4 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 drivers/staging/comedi/internal.h (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 135c80ab6d10..2634af2f33df 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -49,7 +49,7 @@ #include #include -/* #include "kvmem.h" */ +#include "internal.h" MODULE_AUTHOR("http://www.comedi.org"); MODULE_DESCRIPTION("Comedi core module"); @@ -2156,7 +2156,6 @@ int comedi_alloc_board_minor(struct device *hardware_device) } return i; } -EXPORT_SYMBOL_GPL(comedi_alloc_board_minor); void comedi_free_board_minor(unsigned minor) { diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 9e13964ac6d3..5f017c2383b3 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -522,7 +522,6 @@ static inline void *comedi_aux_data(int options[], int n) return (void *)address; } -int comedi_alloc_board_minor(struct device *hardware_device); void comedi_free_board_minor(unsigned minor); int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s); diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index a8f3d790b3d5..475778fb6801 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -37,15 +37,16 @@ #include #include #include -#include "comedidev.h" #include /* for SuSE brokenness */ #include #include #include - #include #include +#include "comedidev.h" +#include "internal.h" + static int postconfig(struct comedi_device *dev); static int insn_rw_emulate_bits(struct comedi_device *dev, struct comedi_subdevice *s, diff --git a/drivers/staging/comedi/internal.h b/drivers/staging/comedi/internal.h new file mode 100644 index 000000000000..4ced6bfa7e9c --- /dev/null +++ b/drivers/staging/comedi/internal.h @@ -0,0 +1,2 @@ + +int comedi_alloc_board_minor(struct device *hardware_device); -- cgit v1.2.3 From 9e8c604821b372c6e98e9632f5617913bf92ae45 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 May 2010 15:24:14 -0700 Subject: Staging: comedi: make comedi_free_board_minor local to comedi core No one outside of the comedi core calls this function, so don't export it to the world. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 1 - drivers/staging/comedi/comedidev.h | 1 - drivers/staging/comedi/internal.h | 1 + 3 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 2634af2f33df..ce8e2549b8ff 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -2181,7 +2181,6 @@ void comedi_free_board_minor(unsigned minor) kfree(info); } } -EXPORT_SYMBOL_GPL(comedi_free_board_minor); int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 5f017c2383b3..c72fd15e6a55 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -522,7 +522,6 @@ static inline void *comedi_aux_data(int options[], int n) return (void *)address; } -void comedi_free_board_minor(unsigned minor); int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s); void comedi_free_subdevice_minor(struct comedi_subdevice *s); diff --git a/drivers/staging/comedi/internal.h b/drivers/staging/comedi/internal.h index 4ced6bfa7e9c..4b6065adb7ea 100644 --- a/drivers/staging/comedi/internal.h +++ b/drivers/staging/comedi/internal.h @@ -1,2 +1,3 @@ int comedi_alloc_board_minor(struct device *hardware_device); +void comedi_free_board_minor(unsigned minor); -- cgit v1.2.3 From 09372df0dff51121e772ca5870fb565a08840c86 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 May 2010 15:27:52 -0700 Subject: Staging: comedi: make comedi_reset_async_buf local to comedi core No one outside of the comedi core calls this function, so don't export it to the world. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 2 -- drivers/staging/comedi/drivers.c | 1 - drivers/staging/comedi/internal.h | 1 + 3 files changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index c72fd15e6a55..3ca5832ad6f9 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -495,8 +495,6 @@ static inline unsigned comedi_buf_read_n_allocated(struct comedi_async *async) return async->buf_read_alloc_count - async->buf_read_count; } -void comedi_reset_async_buf(struct comedi_async *async); - static inline void *comedi_aux_data(int options[], int n) { unsigned long address; diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 475778fb6801..f68fab9c5509 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -811,7 +811,6 @@ void comedi_reset_async_buf(struct comedi_async *async) async->events = 0; } -EXPORT_SYMBOL(comedi_reset_async_buf); int comedi_auto_config(struct device *hardware_device, const char *board_name, const int *options, unsigned num_options) diff --git a/drivers/staging/comedi/internal.h b/drivers/staging/comedi/internal.h index 4b6065adb7ea..7068a38d7f3c 100644 --- a/drivers/staging/comedi/internal.h +++ b/drivers/staging/comedi/internal.h @@ -1,3 +1,4 @@ int comedi_alloc_board_minor(struct device *hardware_device); void comedi_free_board_minor(unsigned minor); +void comedi_reset_async_buf(struct comedi_async *async); -- cgit v1.2.3 From 22d114248be8907f965e68a1bfdcea3302cbc776 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 May 2010 15:32:04 -0700 Subject: Staging: comedi: clean up sparse issues in proc.c The whole file should be converted to use seqfile, if it's even still needed. Or move to debugfs. Anyway, I fixed up the minor issues here. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/proc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/proc.c b/drivers/staging/comedi/proc.c index c0035cb759aa..2aa487b60187 100644 --- a/drivers/staging/comedi/proc.c +++ b/drivers/staging/comedi/proc.c @@ -32,10 +32,11 @@ #include "comedidev.h" #include "comedi_fops.h" #include -/* #include */ +#include -int comedi_read_procmem(char *buf, char **start, off_t offset, int len, - int *eof, void *data) +#ifdef CONFIG_PROC_FS +static int comedi_read(char *buf, char **start, off_t offset, int len, + int *eof, void *data) { int i; int devices_q = 0; @@ -82,18 +83,17 @@ int comedi_read_procmem(char *buf, char **start, off_t offset, int len, return l; } -#ifdef CONFIG_PROC_FS void comedi_proc_init(void) { struct proc_dir_entry *comedi_proc; - comedi_proc = create_proc_entry("comedi", S_IFREG | S_IRUGO, 0); + comedi_proc = create_proc_entry("comedi", S_IFREG | S_IRUGO, NULL); if (comedi_proc) - comedi_proc->read_proc = comedi_read_procmem; + comedi_proc->read_proc = comedi_read; } void comedi_proc_cleanup(void) { - remove_proc_entry("comedi", 0); + remove_proc_entry("comedi", NULL); } #endif -- cgit v1.2.3 From 2434358ac7ece40e6aa8cd705927c423caa718ec Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 May 2010 15:38:37 -0700 Subject: Staging: comedi: move some more functions to internal.h Only the internal comedi core calls these, so put them here. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 7 ------- drivers/staging/comedi/internal.h | 7 ++++++- 2 files changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 3ca5832ad6f9..c26c6446a0ee 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -377,15 +377,8 @@ enum subdevice_runflags { SRF_RUNNING = 0x08000000 }; -/* - various internal comedi functions - */ - -int do_rangeinfo_ioctl(struct comedi_device *dev, struct comedi_rangeinfo *arg); int comedi_check_chanlist(struct comedi_subdevice *s, int n, unsigned int *chanlist); unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s); -int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); /* range stuff */ diff --git a/drivers/staging/comedi/internal.h b/drivers/staging/comedi/internal.h index 7068a38d7f3c..ce121f21ebc5 100644 --- a/drivers/staging/comedi/internal.h +++ b/drivers/staging/comedi/internal.h @@ -1,4 +1,9 @@ - +/* + * various internal comedi functions + */ +int do_rangeinfo_ioctl(struct comedi_device *dev, struct comedi_rangeinfo *arg); +int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); int comedi_alloc_board_minor(struct device *hardware_device); void comedi_free_board_minor(unsigned minor); void comedi_reset_async_buf(struct comedi_async *async); -- cgit v1.2.3 From 3b6b25b5ddf4485e89432a35a7d79d371ba6eba1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 May 2010 15:50:09 -0700 Subject: Staging: comedi: range.c: properly mark up __user pointers This is the start of cleaning up the user pointer markings in the comedi core. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi.h | 2 +- drivers/staging/comedi/comedi_compat32.c | 3 +-- drivers/staging/comedi/drivers/comedi_bond.c | 4 ++-- drivers/staging/comedi/internal.h | 3 ++- drivers/staging/comedi/range.c | 6 ++++-- 5 files changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index 1251e074cb2b..a124ca8d0365 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -368,7 +368,7 @@ struct comedi_rangeinfo { unsigned int range_type; - void *range_ptr; + void __user *range_ptr; }; struct comedi_krange { diff --git a/drivers/staging/comedi/comedi_compat32.c b/drivers/staging/comedi/comedi_compat32.c index 581aa5fee2e3..41a7a62ba49a 100644 --- a/drivers/staging/comedi/comedi_compat32.c +++ b/drivers/staging/comedi/comedi_compat32.c @@ -25,9 +25,8 @@ */ #define __NO_VERSION__ -#include "comedi.h" #include - +#include "comedi.h" #include "comedi_compat32.h" #ifdef CONFIG_COMPAT diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index 22a0f996eeb0..701622280ff4 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -87,11 +87,11 @@ Configuration Options: * options that are used with comedi_config. */ +#include +#include #include "../comedi.h" #include "../comedilib.h" #include "../comedidev.h" -#include -#include /* The maxiumum number of channels per subdevice. */ #define MAX_CHANS 256 diff --git a/drivers/staging/comedi/internal.h b/drivers/staging/comedi/internal.h index ce121f21ebc5..55b85501c92c 100644 --- a/drivers/staging/comedi/internal.h +++ b/drivers/staging/comedi/internal.h @@ -1,7 +1,8 @@ /* * various internal comedi functions */ -int do_rangeinfo_ioctl(struct comedi_device *dev, struct comedi_rangeinfo *arg); +int do_rangeinfo_ioctl(struct comedi_device *dev, + struct comedi_rangeinfo __user *arg); int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); int comedi_alloc_board_minor(struct device *hardware_device); diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c index 8a1cefd97fdb..148ec6fd6fdd 100644 --- a/drivers/staging/comedi/range.c +++ b/drivers/staging/comedi/range.c @@ -21,8 +21,9 @@ */ -#include "comedidev.h" #include +#include "comedidev.h" +#include "internal.h" const struct comedi_lrange range_bipolar10 = { 1, {BIP_RANGE(10)} }; EXPORT_SYMBOL(range_bipolar10); @@ -50,7 +51,8 @@ EXPORT_SYMBOL(range_unknown); writes: n struct comedi_krange structures to rangeinfo->range_ptr */ -int do_rangeinfo_ioctl(struct comedi_device *dev, struct comedi_rangeinfo *arg) +int do_rangeinfo_ioctl(struct comedi_device *dev, + struct comedi_rangeinfo __user *arg) { struct comedi_rangeinfo it; int subd, chan; -- cgit v1.2.3 From 7029a87455af3cf303e8d6d0db8c26b6a94f1020 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 May 2010 15:55:45 -0700 Subject: Staging: comedi: drivers.c sparse cleanup Fix up some sparse issues in drivers.c Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 3 --- drivers/staging/comedi/drivers.c | 24 +++++++++--------------- drivers/staging/comedi/internal.h | 2 ++ 3 files changed, 11 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index c26c6446a0ee..c38ebb4aa75f 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -351,9 +351,6 @@ void cleanup_polling(void); void start_polling(struct comedi_device *); void stop_polling(struct comedi_device *); -int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, - unsigned long new_size); - #ifdef CONFIG_PROC_FS void comedi_proc_init(void); void comedi_proc_cleanup(void); diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index f68fab9c5509..1f48b6dca08b 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -54,16 +54,9 @@ static int insn_rw_emulate_bits(struct comedi_device *dev, static void *comedi_recognize(struct comedi_driver *driv, const char *name); static void comedi_report_boards(struct comedi_driver *driv); static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s); -int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, - unsigned long new_size); struct comedi_driver *comedi_drivers; -int comedi_modprobe(int minor) -{ - return -EINVAL; -} - static void cleanup_device(struct comedi_device *dev) { int i; @@ -84,7 +77,7 @@ static void cleanup_device(struct comedi_device *dev) } kfree(dev->private); dev->private = NULL; - dev->driver = 0; + dev->driver = NULL; dev->board_name = NULL; dev->board_ptr = NULL; dev->iobase = 0; @@ -309,7 +302,7 @@ static int postconfig(struct comedi_device *dev) /* generic recognize function for drivers * that register their supported board names */ -void *comedi_recognize(struct comedi_driver *driv, const char *name) +static void *comedi_recognize(struct comedi_driver *driv, const char *name) { unsigned i; const char *const *name_ptr = driv->board_name; @@ -324,7 +317,7 @@ void *comedi_recognize(struct comedi_driver *driv, const char *name) return NULL; } -void comedi_report_boards(struct comedi_driver *driv) +static void comedi_report_boards(struct comedi_driver *driv) { unsigned int i; const char *const *name_ptr; @@ -548,8 +541,8 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, /* munging is applied to data by core as it passes between user * and kernel space */ -unsigned int comedi_buf_munge(struct comedi_async *async, - unsigned int num_bytes) +static unsigned int comedi_buf_munge(struct comedi_async *async, + unsigned int num_bytes) { struct comedi_subdevice *s = async->subdevice; unsigned int count = 0; @@ -812,8 +805,9 @@ void comedi_reset_async_buf(struct comedi_async *async) async->events = 0; } -int comedi_auto_config(struct device *hardware_device, const char *board_name, - const int *options, unsigned num_options) +static int comedi_auto_config(struct device *hardware_device, + const char *board_name, const int *options, + unsigned num_options) { struct comedi_devconfig it; int minor; @@ -858,7 +852,7 @@ cleanup: return retval; } -void comedi_auto_unconfig(struct device *hardware_device) +static void comedi_auto_unconfig(struct device *hardware_device) { unsigned *minor = (unsigned *)dev_get_drvdata(hardware_device); if (minor == NULL) diff --git a/drivers/staging/comedi/internal.h b/drivers/staging/comedi/internal.h index 55b85501c92c..434ce3433368 100644 --- a/drivers/staging/comedi/internal.h +++ b/drivers/staging/comedi/internal.h @@ -8,3 +8,5 @@ int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s, int comedi_alloc_board_minor(struct device *hardware_device); void comedi_free_board_minor(unsigned minor); void comedi_reset_async_buf(struct comedi_async *async); +int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, + unsigned long new_size); -- cgit v1.2.3 From 92d0127c9d249c078b0939050f25041ed37be7cd Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 May 2010 16:32:28 -0700 Subject: Staging: comedi: __user markup on comedi_fops.c Hm, what a mess. I tried to properly mark up the __user pointers, but for some of these structures, we use them both in the kernel, and across the user/kernel boundry, which isn't ok. So we end up generating a few new sparse warnings in places we were not before, but the large majority of things are now properly tagged in the fops file. The whole ioctl interface needs to be carefully looked at in the future. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi.h | 12 ++-- drivers/staging/comedi/comedi_fops.c | 126 +++++++++++++++++++---------------- 2 files changed, 73 insertions(+), 65 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index a124ca8d0365..45272d8bf972 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -321,7 +321,7 @@ struct comedi_insn { unsigned int insn; unsigned int n; - unsigned int *data; + unsigned int __user *data; unsigned int subdev; unsigned int chanspec; unsigned int unused[3]; @@ -329,7 +329,7 @@ struct comedi_insnlist { unsigned int n_insns; - struct comedi_insn *insns; + struct comedi_insn __user *insns; }; struct comedi_cmd { @@ -351,7 +351,7 @@ unsigned int stop_src; unsigned int stop_arg; - unsigned int *chanlist; /* channel/range list */ + unsigned int __user *chanlist; /* channel/range list */ unsigned int chanlist_len; short *data; /* data list, size depends on subd flags */ @@ -360,9 +360,9 @@ struct comedi_chaninfo { unsigned int subdev; - unsigned int *maxdata_list; - unsigned int *flaglist; - unsigned int *rangelist; + unsigned int __user *maxdata_list; + unsigned int __user *flaglist; + unsigned int __user *rangelist; unsigned int unused[4]; }; diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index ce8e2549b8ff..e7095d766f40 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -64,7 +64,7 @@ module_param(comedi_debug, int, 0644); int comedi_autoconfig = 1; module_param(comedi_autoconfig, bool, 0444); -int comedi_num_legacy_minors; +static int comedi_num_legacy_minors; module_param(comedi_num_legacy_minors, int, 0444); static DEFINE_SPINLOCK(comedi_file_info_table_lock); @@ -72,25 +72,32 @@ static struct comedi_device_file_info *comedi_file_info_table[COMEDI_NUM_MINORS]; static int do_devconfig_ioctl(struct comedi_device *dev, - struct comedi_devconfig *arg); -static int do_bufconfig_ioctl(struct comedi_device *dev, void *arg); + struct comedi_devconfig __user *arg); +static int do_bufconfig_ioctl(struct comedi_device *dev, + struct comedi_bufconfig __user *arg); static int do_devinfo_ioctl(struct comedi_device *dev, - struct comedi_devinfo *arg, struct file *file); + struct comedi_devinfo __user *arg, + struct file *file); static int do_subdinfo_ioctl(struct comedi_device *dev, - struct comedi_subdinfo *arg, void *file); + struct comedi_subdinfo __user *arg, void *file); static int do_chaninfo_ioctl(struct comedi_device *dev, - struct comedi_chaninfo *arg); -static int do_bufinfo_ioctl(struct comedi_device *dev, void *arg); -static int do_cmd_ioctl(struct comedi_device *dev, void *arg, void *file); + struct comedi_chaninfo __user *arg); +static int do_bufinfo_ioctl(struct comedi_device *dev, + struct comedi_bufinfo __user *arg); +static int do_cmd_ioctl(struct comedi_device *dev, + struct comedi_cmd __user *arg, void *file); static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, void *file); static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg, void *file); static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, void *file); -static int do_cmdtest_ioctl(struct comedi_device *dev, void *arg, void *file); -static int do_insnlist_ioctl(struct comedi_device *dev, void *arg, void *file); -static int do_insn_ioctl(struct comedi_device *dev, void *arg, void *file); +static int do_cmdtest_ioctl(struct comedi_device *dev, + struct comedi_cmd __user *arg, void *file); +static int do_insnlist_ioctl(struct comedi_device *dev, + struct comedi_insnlist __user *arg, void *file); +static int do_insn_ioctl(struct comedi_device *dev, + struct comedi_insn __user *arg, void *file); static int do_poll_ioctl(struct comedi_device *dev, unsigned int subd, void *file); @@ -129,7 +136,8 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, /* Device config is special, because it must work on * an unconfigured device. */ if (cmd == COMEDI_DEVCONFIG) { - rc = do_devconfig_ioctl(dev, (void *)arg); + rc = do_devconfig_ioctl(dev, + (struct comedi_devconfig __user *)arg); goto done; } @@ -141,22 +149,27 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, switch (cmd) { case COMEDI_BUFCONFIG: - rc = do_bufconfig_ioctl(dev, (void *)arg); + rc = do_bufconfig_ioctl(dev, + (struct comedi_bufconfig __user *)arg); break; case COMEDI_DEVINFO: - rc = do_devinfo_ioctl(dev, (void *)arg, file); + rc = do_devinfo_ioctl(dev, (struct comedi_devinfo __user *)arg, + file); break; case COMEDI_SUBDINFO: - rc = do_subdinfo_ioctl(dev, (void *)arg, file); + rc = do_subdinfo_ioctl(dev, + (struct comedi_subdinfo __user *)arg, + file); break; case COMEDI_CHANINFO: - rc = do_chaninfo_ioctl(dev, (void *)arg); + rc = do_chaninfo_ioctl(dev, (void __user *)arg); break; case COMEDI_RANGEINFO: - rc = do_rangeinfo_ioctl(dev, (void *)arg); + rc = do_rangeinfo_ioctl(dev, (void __user *)arg); break; case COMEDI_BUFINFO: - rc = do_bufinfo_ioctl(dev, (void *)arg); + rc = do_bufinfo_ioctl(dev, + (struct comedi_bufinfo __user *)arg); break; case COMEDI_LOCK: rc = do_lock_ioctl(dev, arg, file); @@ -168,16 +181,20 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, rc = do_cancel_ioctl(dev, arg, file); break; case COMEDI_CMD: - rc = do_cmd_ioctl(dev, (void *)arg, file); + rc = do_cmd_ioctl(dev, (struct comedi_cmd __user *)arg, file); break; case COMEDI_CMDTEST: - rc = do_cmdtest_ioctl(dev, (void *)arg, file); + rc = do_cmdtest_ioctl(dev, (struct comedi_cmd __user *)arg, + file); break; case COMEDI_INSNLIST: - rc = do_insnlist_ioctl(dev, (void *)arg, file); + rc = do_insnlist_ioctl(dev, + (struct comedi_insnlist __user *)arg, + file); break; case COMEDI_INSN: - rc = do_insn_ioctl(dev, (void *)arg, file); + rc = do_insn_ioctl(dev, (struct comedi_insn __user *)arg, + file); break; case COMEDI_POLL: rc = do_poll_ioctl(dev, arg, file); @@ -206,7 +223,7 @@ done: none */ static int do_devconfig_ioctl(struct comedi_device *dev, - struct comedi_devconfig *arg) + struct comedi_devconfig __user *arg) { struct comedi_devconfig it; int ret; @@ -286,7 +303,8 @@ static int do_devconfig_ioctl(struct comedi_device *dev, modified bufconfig at arg */ -static int do_bufconfig_ioctl(struct comedi_device *dev, void *arg) +static int do_bufconfig_ioctl(struct comedi_device *dev, + struct comedi_bufconfig __user *arg) { struct comedi_bufconfig bc; struct comedi_async *async; @@ -347,7 +365,8 @@ copyback: */ static int do_devinfo_ioctl(struct comedi_device *dev, - struct comedi_devinfo *arg, struct file *file) + struct comedi_devinfo __user *arg, + struct file *file) { struct comedi_devinfo devinfo; const unsigned minor = iminor(file->f_dentry->d_inode); @@ -397,7 +416,7 @@ static int do_devinfo_ioctl(struct comedi_device *dev, */ static int do_subdinfo_ioctl(struct comedi_device *dev, - struct comedi_subdinfo *arg, void *file) + struct comedi_subdinfo __user *arg, void *file) { int ret, i; struct comedi_subdinfo *tmp, *us; @@ -479,7 +498,7 @@ static int do_subdinfo_ioctl(struct comedi_device *dev, */ static int do_chaninfo_ioctl(struct comedi_device *dev, - struct comedi_chaninfo *arg) + struct comedi_chaninfo __user *arg) { struct comedi_subdevice *s; struct comedi_chaninfo it; @@ -543,7 +562,8 @@ static int do_chaninfo_ioctl(struct comedi_device *dev, modified bufinfo at arg */ -static int do_bufinfo_ioctl(struct comedi_device *dev, void *arg) +static int do_bufinfo_ioctl(struct comedi_device *dev, + struct comedi_bufinfo __user *arg) { struct comedi_bufinfo bi; struct comedi_subdevice *s; @@ -615,7 +635,8 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, */ /* arbitrary limits */ #define MAX_SAMPLES 256 -static int do_insnlist_ioctl(struct comedi_device *dev, void *arg, void *file) +static int do_insnlist_ioctl(struct comedi_device *dev, + struct comedi_insnlist __user *arg, void *file) { struct comedi_insnlist insnlist; struct comedi_insn *insns = NULL; @@ -909,7 +930,8 @@ out: * writes: * data (for reads) */ -static int do_insn_ioctl(struct comedi_device *dev, void *arg, void *file) +static int do_insn_ioctl(struct comedi_device *dev, + struct comedi_insn __user *arg, void *file) { struct comedi_insn insn; unsigned int *data = NULL; @@ -940,8 +962,7 @@ static int do_insn_ioctl(struct comedi_device *dev, void *arg, void *file) if (ret < 0) goto error; if (insn.insn & INSN_MASK_READ) { - if (copy_to_user - (insn.data, data, insn.n * sizeof(unsigned int))) { + if (copy_to_user(insn.data, data, insn.n * sizeof(unsigned int))) { ret = -EFAULT; goto error; } @@ -965,30 +986,16 @@ static void comedi_set_subdevice_runflags(struct comedi_subdevice *s, spin_unlock_irqrestore(&s->spin_lock, flags); } -/* - COMEDI_CMD - command ioctl - - arg: - pointer to cmd structure - - reads: - cmd structure at arg - channel/range list - - writes: - modified cmd structure at arg - -*/ -static int do_cmd_ioctl(struct comedi_device *dev, void *arg, void *file) +static int do_cmd_ioctl(struct comedi_device *dev, + struct comedi_cmd __user *cmd, void *file) { struct comedi_cmd user_cmd; struct comedi_subdevice *s; struct comedi_async *async; int ret = 0; - unsigned int *chanlist_saver = NULL; + unsigned int __user *chanlist_saver = NULL; - if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) { + if (copy_from_user(&user_cmd, cmd, sizeof(struct comedi_cmd))) { DPRINTK("bad cmd address\n"); return -EFAULT; } @@ -1077,7 +1084,7 @@ static int do_cmd_ioctl(struct comedi_device *dev, void *arg, void *file) /* restore chanlist pointer before copying back */ user_cmd.chanlist = chanlist_saver; user_cmd.data = NULL; - if (copy_to_user(arg, &user_cmd, sizeof(struct comedi_cmd))) { + if (copy_to_user(cmd, &user_cmd, sizeof(struct comedi_cmd))) { DPRINTK("fault writing cmd\n"); ret = -EFAULT; goto cleanup; @@ -1127,13 +1134,14 @@ cleanup: modified cmd structure at arg */ -static int do_cmdtest_ioctl(struct comedi_device *dev, void *arg, void *file) +static int do_cmdtest_ioctl(struct comedi_device *dev, + struct comedi_cmd __user *arg, void *file) { struct comedi_cmd user_cmd; struct comedi_subdevice *s; int ret = 0; unsigned int *chanlist = NULL; - unsigned int *chanlist_saver = NULL; + unsigned int __user *chanlist_saver = NULL; if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) { DPRINTK("bad cmd address\n"); @@ -1384,7 +1392,7 @@ static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s) return ret; } -void comedi_unmap(struct vm_area_struct *area) +static void comedi_unmap(struct vm_area_struct *area) { struct comedi_async *async; struct comedi_device *dev; @@ -1522,8 +1530,8 @@ static unsigned int comedi_poll(struct file *file, poll_table * wait) return mask; } -static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes, - loff_t *offset) +static ssize_t comedi_write(struct file *file, const char __user *buf, + size_t nbytes, loff_t *offset) { struct comedi_subdevice *s; struct comedi_async *async; @@ -1624,7 +1632,7 @@ done: return count ? count : retval; } -static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes, +static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, loff_t *offset) { struct comedi_subdevice *s; @@ -2063,7 +2071,7 @@ static int is_device_busy(struct comedi_device *dev) return 0; } -void comedi_device_init(struct comedi_device *dev) +static void comedi_device_init(struct comedi_device *dev) { memset(dev, 0, sizeof(struct comedi_device)); spin_lock_init(&dev->spinlock); @@ -2071,7 +2079,7 @@ void comedi_device_init(struct comedi_device *dev) dev->minor = -1; } -void comedi_device_cleanup(struct comedi_device *dev) +static void comedi_device_cleanup(struct comedi_device *dev) { if (dev == NULL) return; -- cgit v1.2.3 From c88c4e4c7a427ee65556f33e6327b604ec209ec3 Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Tue, 4 May 2010 15:55:05 -0700 Subject: Staging: hv: Added new hv_utils driver with shutdown as first functionality Addition of new driver for Hyper-V called hv_utils. This driver is intended to support things like KVP, Timesync, Heartbeat etc. This first release has support for Gracefull shutdown. e.g. Select shutdown from the Hyper-V main admin screen and the Linux VM will do a gracefull shutdown. Signed-off-by: Hank Janssen Signed-off-by: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Channel.c | 34 ++++++-- drivers/staging/hv/ChannelMgmt.c | 148 ++++++++++++++++++++++++++++++++- drivers/staging/hv/Kconfig | 6 ++ drivers/staging/hv/Makefile | 2 + drivers/staging/hv/VmbusPacketFormat.h | 1 + drivers/staging/hv/ext_utils.c | 27 ++++++ drivers/staging/hv/hyperv_utils.c | 134 +++++++++++++++++++++++++++++ drivers/staging/hv/utils.h | 94 +++++++++++++++++++++ 8 files changed, 438 insertions(+), 8 deletions(-) create mode 100644 drivers/staging/hv/ext_utils.c create mode 100644 drivers/staging/hv/hyperv_utils.c create mode 100644 drivers/staging/hv/utils.h (limited to 'drivers') diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/Channel.c index 328d3a0d0bd8..de2ccb1082ce 100644 --- a/drivers/staging/hv/Channel.c +++ b/drivers/staging/hv/Channel.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "osd.h" #include "logging.h" #include "VmbusPrivate.h" @@ -666,8 +667,19 @@ void VmbusChannelClose(struct vmbus_channel *Channel) DPRINT_EXIT(VMBUS); } -/* - * VmbusChannelSendPacket - Send the specified buffer on the given channel +/** + * VmbusChannelSendPacket() - Send the specified buffer on the given channel + * @Channel: Pointer to vmbus_channel structure. + * @Buffer: Pointer to the buffer you want to receive the data into. + * @BufferLen: Maximum size of what the the buffer will hold + * @RequestId: Identifier of the request + * @vmbus_packet_type: Type of packet that is being send e.g. negotiate, time + * packet etc. + * + * Sends data in @Buffer directly to hyper-v via the vmbus + * This will send the data unparsed to hyper-v. + * + * Mainly used by Hyper-V drivers. */ int VmbusChannelSendPacket(struct vmbus_channel *Channel, const void *Buffer, u32 BufferLen, u64 RequestId, @@ -711,6 +723,7 @@ int VmbusChannelSendPacket(struct vmbus_channel *Channel, const void *Buffer, return ret; } +EXPORT_SYMBOL(VmbusChannelSendPacket); /* * VmbusChannelSendPacketPageBuffer - Send a range of single-page buffer @@ -848,10 +861,20 @@ int VmbusChannelSendPacketMultiPageBuffer(struct vmbus_channel *Channel, return ret; } -/* - * VmbusChannelRecvPacket - Retrieve the user packet on the specified channel + +/** + * VmbusChannelRecvPacket() - Retrieve the user packet on the specified channel + * @Channel: Pointer to vmbus_channel structure. + * @Buffer: Pointer to the buffer you want to receive the data into. + * @BufferLen: Maximum size of what the the buffer will hold + * @BufferActualLen: The actual size of the data after it was received + * @RequestId: Identifier of the request + * + * Receives directly from the hyper-v vmbus and puts the data it received + * into Buffer. This will receive the data unparsed from hyper-v. + * + * Mainly used by Hyper-V drivers. */ -/* TODO: Do we ever receive a gpa direct packet other than the ones we send ? */ int VmbusChannelRecvPacket(struct vmbus_channel *Channel, void *Buffer, u32 BufferLen, u32 *BufferActualLen, u64 *RequestId) { @@ -913,6 +936,7 @@ int VmbusChannelRecvPacket(struct vmbus_channel *Channel, void *Buffer, return 0; } +EXPORT_SYMBOL(VmbusChannelRecvPacket); /* * VmbusChannelRecvPacketRaw - Retrieve the raw packet on the specified channel diff --git a/drivers/staging/hv/ChannelMgmt.c b/drivers/staging/hv/ChannelMgmt.c index 43f28f23c317..445506d45edb 100644 --- a/drivers/staging/hv/ChannelMgmt.c +++ b/drivers/staging/hv/ChannelMgmt.c @@ -22,18 +22,22 @@ #include #include #include +#include #include "osd.h" #include "logging.h" #include "VmbusPrivate.h" +#include "utils.h" struct vmbus_channel_message_table_entry { enum vmbus_channel_message_type messageType; void (*messageHandler)(struct vmbus_channel_message_header *msg); }; -#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 4 +#define MAX_MSG_TYPES 1 +#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 5 + static const struct hv_guid - gSupportedDeviceClasses[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = { + gSupportedDeviceClasses[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = { /* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ /* Storage - SCSI */ { @@ -69,8 +73,127 @@ static const struct hv_guid 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 } }, + /* 0E0B6031-5213-4934-818B-38D90CED39DB */ + /* Shutdown */ + { + .data = { + 0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49, + 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB + } + }, }; + +/** + * prep_negotiate_resp() - Create default response for Hyper-V Negotiate message + * @icmsghdrp: Pointer to msg header structure + * @icmsg_negotiate: Pointer to negotiate message structure + * @buf: Raw buffer channel data + * + * @icmsghdrp is of type &struct icmsg_hdr. + * @negop is of type &struct icmsg_negotiate. + * Set up and fill in default negotiate response message. This response can + * come from both the vmbus driver and the hv_utils driver. The current api + * will respond properly to both Windows 2008 and Windows 2008-R2 operating + * systems. + * + * Mainly used by Hyper-V drivers. + */ +void prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, + struct icmsg_negotiate *negop, + u8 *buf) +{ + if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { + icmsghdrp->icmsgsize = 0x10; + + negop = (struct icmsg_negotiate *)&buf[ + sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; + + if (negop->icframe_vercnt == 2 && + negop->icversion_data[1].major == 3) { + negop->icversion_data[0].major = 3; + negop->icversion_data[0].minor = 0; + negop->icversion_data[1].major = 3; + negop->icversion_data[1].minor = 0; + } else { + negop->icversion_data[0].major = 1; + negop->icversion_data[0].minor = 0; + negop->icversion_data[1].major = 1; + negop->icversion_data[1].minor = 0; + } + + negop->icframe_vercnt = 1; + negop->icmsg_vercnt = 1; + } +} +EXPORT_SYMBOL(prep_negotiate_resp); + +/** + * chn_cb_negotiate() - Default handler for non IDE/SCSI/NETWORK + * Hyper-V requests + * @context: Pointer to argument structure. + * + * Set up the default handler for non device driver specific requests + * from Hyper-V. This stub responds to the default negotiate messages + * that come in for every non IDE/SCSI/Network request. + * This behavior is normally overwritten in the hv_utils driver. That + * driver handles requests like gracefull shutdown, heartbeats etc. + * + * Mainly used by Hyper-V drivers. + */ +void chn_cb_negotiate(void *context) +{ + struct vmbus_channel *channel = context; + u8 *buf; + u32 buflen, recvlen; + u64 requestid; + + struct icmsg_hdr *icmsghdrp; + struct icmsg_negotiate *negop = NULL; + + buflen = PAGE_SIZE; + buf = kmalloc(buflen, GFP_ATOMIC); + + VmbusChannelRecvPacket(channel, buf, buflen, &recvlen, &requestid); + + if (recvlen > 0) { + icmsghdrp = (struct icmsg_hdr *)&buf[ + sizeof(struct vmbuspipe_hdr)]; + + prep_negotiate_resp(icmsghdrp, negop, buf); + + icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION + | ICMSGHDRFLAG_RESPONSE; + + VmbusChannelSendPacket(channel, buf, + recvlen, requestid, + VmbusPacketTypeDataInBand, 0); + } + + kfree(buf); +} +EXPORT_SYMBOL(chn_cb_negotiate); + +/* + * Function table used for message responses for non IDE/SCSI/Network type + * messages. (Such as KVP/Shutdown etc) + */ +struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = { + /* 0E0B6031-5213-4934-818B-38D90CED39DB */ + /* Shutdown */ + { + .msg_type = HV_SHUTDOWN_MSG, + .data = { + 0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49, + 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB + }, + .callback = chn_cb_negotiate, + .log_msg = "Shutdown channel functionality initialized" + }, +}; +EXPORT_SYMBOL(hv_cb_utils); + /* * AllocVmbusChannel - Allocate and initialize a vmbus channel object */ @@ -132,7 +255,8 @@ void FreeVmbusChannel(struct vmbus_channel *Channel) } /* - * VmbusChannelProcessOffer - Process the offer by creating a channel/device associated with this offer + * VmbusChannelProcessOffer - Process the offer by creating a channel/device + * associated with this offer */ static void VmbusChannelProcessOffer(void *context) { @@ -140,6 +264,7 @@ static void VmbusChannelProcessOffer(void *context) struct vmbus_channel *channel; bool fNew = true; int ret; + int cnt; unsigned long flags; DPRINT_ENTER(VMBUS); @@ -209,6 +334,23 @@ static void VmbusChannelProcessOffer(void *context) * can cleanup properly */ newChannel->State = CHANNEL_OPEN_STATE; + cnt = 0; + + while (cnt != MAX_MSG_TYPES) { + if (memcmp(&newChannel->OfferMsg.Offer.InterfaceType, + &hv_cb_utils[cnt].data, + sizeof(struct hv_guid)) == 0) { + DPRINT_INFO(VMBUS, "%s", + hv_cb_utils[cnt].log_msg); + + if (VmbusChannelOpen(newChannel, 2 * PAGE_SIZE, + 2 * PAGE_SIZE, NULL, 0, + hv_cb_utils[cnt].callback, + newChannel) == 0) + hv_cb_utils[cnt].channel = newChannel; + } + cnt++; + } } DPRINT_EXIT(VMBUS); } diff --git a/drivers/staging/hv/Kconfig b/drivers/staging/hv/Kconfig index 40447020a790..79afb1e96c33 100644 --- a/drivers/staging/hv/Kconfig +++ b/drivers/staging/hv/Kconfig @@ -29,4 +29,10 @@ config HYPERV_NET help Select this option to enable the Hyper-V virtual network driver. +config HYPERV_UTILS + tristate "Microsoft Hyper-V Utilities driver" + default HYPERV + help + Select this option to enable the Hyper-V Utilities. + endif diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index 27ebae8a9185..d2977ab9db4e 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_HYPERV) += hv_vmbus.o obj-$(CONFIG_HYPERV_STORAGE) += hv_storvsc.o obj-$(CONFIG_HYPERV_BLOCK) += hv_blkvsc.o obj-$(CONFIG_HYPERV_NET) += hv_netvsc.o +obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o hv_vmbus-objs := vmbus_drv.o osd.o \ Vmbus.o Hv.o Connection.o Channel.o \ @@ -9,3 +10,4 @@ hv_vmbus-objs := vmbus_drv.o osd.o \ hv_storvsc-objs := storvsc_drv.o StorVsc.o hv_blkvsc-objs := blkvsc_drv.o BlkVsc.o hv_netvsc-objs := netvsc_drv.o NetVsc.o RndisFilter.o +hv_utils-objs := hyperv_utils.o ext_utils.o diff --git a/drivers/staging/hv/VmbusPacketFormat.h b/drivers/staging/hv/VmbusPacketFormat.h index 79120bc742dc..f9f6b4bf6fb1 100644 --- a/drivers/staging/hv/VmbusPacketFormat.h +++ b/drivers/staging/hv/VmbusPacketFormat.h @@ -22,6 +22,7 @@ */ #ifndef _VMBUSPACKETFORMAT_H_ +#define _VMBUSPACKETFORMAT_H_ struct vmpacket_descriptor { u16 Type; diff --git a/drivers/staging/hv/ext_utils.c b/drivers/staging/hv/ext_utils.c new file mode 100644 index 000000000000..a44cd1b93e06 --- /dev/null +++ b/drivers/staging/hv/ext_utils.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2010, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + */ +#include +#include "utils.h" + +void shutdown_linux_system() +{ + orderly_poweroff(false); +} diff --git a/drivers/staging/hv/hyperv_utils.c b/drivers/staging/hv/hyperv_utils.c new file mode 100644 index 000000000000..2a4864784edc --- /dev/null +++ b/drivers/staging/hv/hyperv_utils.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2010, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + */ +#include +#include +#include +#include +#include +#include + +#include "logging.h" +#include "osd.h" +#include "vmbus.h" +#include "VmbusPacketFormat.h" +#include "VmbusChannelInterface.h" +#include "VersionInfo.h" +#include "Channel.h" +#include "VmbusPrivate.h" +#include "VmbusApi.h" +#include "utils.h" + + +void shutdown_onchannelcallback(void *context) +{ + struct vmbus_channel *channel = context; + u8 *buf; + u32 buflen, recvlen; + u64 requestid; + u8 execute_shutdown = false; + + struct shutdown_msg_data *shutdown_msg; + + struct icmsg_hdr *icmsghdrp; + struct icmsg_negotiate *negop = NULL; + + DPRINT_ENTER(VMBUS); + + buflen = PAGE_SIZE; + buf = kmalloc(buflen, GFP_ATOMIC); + + VmbusChannelRecvPacket(channel, buf, buflen, &recvlen, &requestid); + + if (recvlen > 0) { + DPRINT_DBG(VMBUS, "shutdown packet: len=%d, requestid=%lld", + recvlen, requestid); + + icmsghdrp = (struct icmsg_hdr *)&buf[ + sizeof(struct vmbuspipe_hdr)]; + + if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { + prep_negotiate_resp(icmsghdrp, negop, buf); + } else { + shutdown_msg = (struct shutdown_msg_data *)&buf[ + sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; + + switch (shutdown_msg->flags) { + case 0: + case 1: + icmsghdrp->status = HV_S_OK; + execute_shutdown = true; + + DPRINT_INFO(VMBUS, "Shutdown request received -" + " gracefull shutdown initiated"); + break; + default: + icmsghdrp->status = HV_E_FAIL; + execute_shutdown = false; + + DPRINT_INFO(VMBUS, "Shutdown request received -" + " Invalid request"); + break; + }; + } + + icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION + | ICMSGHDRFLAG_RESPONSE; + + VmbusChannelSendPacket(channel, buf, + recvlen, requestid, + VmbusPacketTypeDataInBand, 0); + } + + kfree(buf); + + DPRINT_EXIT(VMBUS); + + if (execute_shutdown == true) + shutdown_linux_system(); +} + +static int __init init_hyperv_utils(void) +{ + printk(KERN_INFO "Registering HyperV Utility Driver\n"); + + hv_cb_utils[HV_SHUTDOWN_MSG].channel->OnChannelCallback = + &shutdown_onchannelcallback; + hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback; + + return 0; +} + +static void exit_hyperv_utils(void) +{ + printk(KERN_INFO "De-Registered HyperV Utility Driver\n"); + + hv_cb_utils[HV_SHUTDOWN_MSG].channel->OnChannelCallback = + &chn_cb_negotiate; + hv_cb_utils[HV_SHUTDOWN_MSG].callback = &chn_cb_negotiate; +} + +module_init(init_hyperv_utils); +module_exit(exit_hyperv_utils); + +MODULE_DESCRIPTION("Hyper-V Utilities"); +MODULE_VERSION(HV_DRV_VERSION); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/hv/utils.h b/drivers/staging/hv/utils.h new file mode 100644 index 000000000000..4e09804e5b9e --- /dev/null +++ b/drivers/staging/hv/utils.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + */ +#ifndef _UTILS_H_ +#define _UTILS_H_ + +/* + * Common header for Hyper-V ICs + */ +#define ICMSGTYPE_NEGOTIATE 0 +#define ICMSGTYPE_HEARTBEAT 1 +#define ICMSGTYPE_KVPEXCHANGE 2 +#define ICMSGTYPE_SHUTDOWN 3 +#define ICMSGTYPE_TIMESYNC 4 +#define ICMSGTYPE_VSS 5 + +#define ICMSGHDRFLAG_TRANSACTION 1 +#define ICMSGHDRFLAG_REQUEST 2 +#define ICMSGHDRFLAG_RESPONSE 4 + +#define HV_S_OK 0x00000000 +#define HV_E_FAIL 0x80004005 +#define HV_ERROR_NOT_SUPPORTED 0x80070032 +#define HV_ERROR_MACHINE_LOCKED 0x800704F7 + +struct vmbuspipe_hdr { + u32 flags; + u32 msgsize; +} __attribute__((packed)); + +struct ic_version { + u16 major; + u16 minor; +} __attribute__((packed)); + +struct icmsg_hdr { + struct ic_version icverframe; + u16 icmsgtype; + struct ic_version icvermsg; + u16 icmsgsize; + u32 status; + u8 ictransaction_id; + u8 icflags; + u8 reserved[2]; +} __attribute__((packed)); + +struct icmsg_negotiate { + u16 icframe_vercnt; + u16 icmsg_vercnt; + u32 reserved; + struct ic_version icversion_data[1]; /* any size array */ +} __attribute__((packed)); + +struct shutdown_msg_data { + u32 reason_code; + u32 timeout_seconds; + u32 flags; + u8 display_message[2048]; +} __attribute__((packed)); + +#define HV_SHUTDOWN_MSG 0 + +struct hyperv_service_callback { + u8 msg_type; + char *log_msg; + unsigned char data[16]; + struct vmbus_channel *channel; + void (*callback) (void *context); +}; + +extern void prep_negotiate_resp(struct icmsg_hdr *, + struct icmsg_negotiate *, u8 *); +extern void shutdown_linux_system(void); +extern void chn_cb_negotiate(void *); +extern struct hyperv_service_callback hv_cb_utils[]; + +#endif /* _UTILS_H_ */ -- cgit v1.2.3 From b3413092cc86d6c1b5b1408c3bb37998a82a588a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 08:21:01 -0700 Subject: Staging: hv: fix up formatting issues in utils.h -------- cut here and print out and paste on wall -------- Tabs, not spaces -------- cut here and print out and paste on wall -------- Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/utils.h | 68 +++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/utils.h b/drivers/staging/hv/utils.h index 4e09804e5b9e..0f2507dcc892 100644 --- a/drivers/staging/hv/utils.h +++ b/drivers/staging/hv/utils.h @@ -18,54 +18,54 @@ * Haiyang Zhang * Hank Janssen */ -#ifndef _UTILS_H_ -#define _UTILS_H_ +#ifndef __HV_UTILS_H_ +#define __HV_UTILS_H_ /* * Common header for Hyper-V ICs */ -#define ICMSGTYPE_NEGOTIATE 0 -#define ICMSGTYPE_HEARTBEAT 1 -#define ICMSGTYPE_KVPEXCHANGE 2 -#define ICMSGTYPE_SHUTDOWN 3 -#define ICMSGTYPE_TIMESYNC 4 -#define ICMSGTYPE_VSS 5 +#define ICMSGTYPE_NEGOTIATE 0 +#define ICMSGTYPE_HEARTBEAT 1 +#define ICMSGTYPE_KVPEXCHANGE 2 +#define ICMSGTYPE_SHUTDOWN 3 +#define ICMSGTYPE_TIMESYNC 4 +#define ICMSGTYPE_VSS 5 -#define ICMSGHDRFLAG_TRANSACTION 1 -#define ICMSGHDRFLAG_REQUEST 2 -#define ICMSGHDRFLAG_RESPONSE 4 +#define ICMSGHDRFLAG_TRANSACTION 1 +#define ICMSGHDRFLAG_REQUEST 2 +#define ICMSGHDRFLAG_RESPONSE 4 -#define HV_S_OK 0x00000000 -#define HV_E_FAIL 0x80004005 -#define HV_ERROR_NOT_SUPPORTED 0x80070032 -#define HV_ERROR_MACHINE_LOCKED 0x800704F7 +#define HV_S_OK 0x00000000 +#define HV_E_FAIL 0x80004005 +#define HV_ERROR_NOT_SUPPORTED 0x80070032 +#define HV_ERROR_MACHINE_LOCKED 0x800704F7 struct vmbuspipe_hdr { - u32 flags; - u32 msgsize; + u32 flags; + u32 msgsize; } __attribute__((packed)); struct ic_version { - u16 major; - u16 minor; + u16 major; + u16 minor; } __attribute__((packed)); struct icmsg_hdr { - struct ic_version icverframe; - u16 icmsgtype; - struct ic_version icvermsg; - u16 icmsgsize; - u32 status; - u8 ictransaction_id; - u8 icflags; - u8 reserved[2]; + struct ic_version icverframe; + u16 icmsgtype; + struct ic_version icvermsg; + u16 icmsgsize; + u32 status; + u8 ictransaction_id; + u8 icflags; + u8 reserved[2]; } __attribute__((packed)); struct icmsg_negotiate { - u16 icframe_vercnt; - u16 icmsg_vercnt; - u32 reserved; - struct ic_version icversion_data[1]; /* any size array */ + u16 icframe_vercnt; + u16 icmsg_vercnt; + u32 reserved; + struct ic_version icversion_data[1]; /* any size array */ } __attribute__((packed)); struct shutdown_msg_data { @@ -75,7 +75,7 @@ struct shutdown_msg_data { u8 display_message[2048]; } __attribute__((packed)); -#define HV_SHUTDOWN_MSG 0 +#define HV_SHUTDOWN_MSG 0 struct hyperv_service_callback { u8 msg_type; @@ -86,9 +86,9 @@ struct hyperv_service_callback { }; extern void prep_negotiate_resp(struct icmsg_hdr *, - struct icmsg_negotiate *, u8 *); + struct icmsg_negotiate *, u8 *); extern void shutdown_linux_system(void); extern void chn_cb_negotiate(void *); extern struct hyperv_service_callback hv_cb_utils[]; -#endif /* _UTILS_H_ */ +#endif /* __HV_UTILS_H_ */ -- cgit v1.2.3 From 9e629075ac694ab4d4971d4e62dfb749118bce70 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 08:26:23 -0700 Subject: Staging: hv: delete ext_utils.c A whole file just for a single line function call is beyond silly. Delete it and move the call into where it is being called. Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Makefile | 2 +- drivers/staging/hv/ext_utils.c | 27 --------------------------- drivers/staging/hv/hyperv_utils.c | 3 ++- drivers/staging/hv/utils.h | 1 - 4 files changed, 3 insertions(+), 30 deletions(-) delete mode 100644 drivers/staging/hv/ext_utils.c (limited to 'drivers') diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index d2977ab9db4e..7a57a886ab10 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -10,4 +10,4 @@ hv_vmbus-objs := vmbus_drv.o osd.o \ hv_storvsc-objs := storvsc_drv.o StorVsc.o hv_blkvsc-objs := blkvsc_drv.o BlkVsc.o hv_netvsc-objs := netvsc_drv.o NetVsc.o RndisFilter.o -hv_utils-objs := hyperv_utils.o ext_utils.o +hv_utils-objs := hyperv_utils.o diff --git a/drivers/staging/hv/ext_utils.c b/drivers/staging/hv/ext_utils.c deleted file mode 100644 index a44cd1b93e06..000000000000 --- a/drivers/staging/hv/ext_utils.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2010, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - */ -#include -#include "utils.h" - -void shutdown_linux_system() -{ - orderly_poweroff(false); -} diff --git a/drivers/staging/hv/hyperv_utils.c b/drivers/staging/hv/hyperv_utils.c index 2a4864784edc..ca52fbada7d1 100644 --- a/drivers/staging/hv/hyperv_utils.c +++ b/drivers/staging/hv/hyperv_utils.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "logging.h" @@ -103,7 +104,7 @@ void shutdown_onchannelcallback(void *context) DPRINT_EXIT(VMBUS); if (execute_shutdown == true) - shutdown_linux_system(); + orderly_poweroff(false); } static int __init init_hyperv_utils(void) diff --git a/drivers/staging/hv/utils.h b/drivers/staging/hv/utils.h index 0f2507dcc892..e404b21e9af2 100644 --- a/drivers/staging/hv/utils.h +++ b/drivers/staging/hv/utils.h @@ -87,7 +87,6 @@ struct hyperv_service_callback { extern void prep_negotiate_resp(struct icmsg_hdr *, struct icmsg_negotiate *, u8 *); -extern void shutdown_linux_system(void); extern void chn_cb_negotiate(void *); extern struct hyperv_service_callback hv_cb_utils[]; -- cgit v1.2.3 From 8566ea7c6f9660623a6f04bc73431f761dee32c7 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 3 May 2010 17:50:45 -0400 Subject: Staging: hv: move ASSERT(scmnd) to a more useful location There's not much point to make sure scmnd is not NULL after an assert that would dereference scmnd. The ASSERT()'s should be removed, but until they are at least they at least can be in the right order. Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 5e28e4c36434..26b35a6c679a 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -386,9 +386,9 @@ static void storvsc_commmand_completion(struct hv_storvsc_request *request) struct scsi_sense_hdr sense_hdr; ASSERT(request == &cmd_request->request); + ASSERT(scmnd); ASSERT((unsigned long)scmnd->host_scribble == (unsigned long)cmd_request); - ASSERT(scmnd); ASSERT(scmnd->scsi_done); DPRINT_ENTER(STORVSC_DRV); -- cgit v1.2.3 From 694a98073f83ce1c14e3c0bba182bfeba5c44f01 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 3 May 2010 12:33:16 -0700 Subject: Staging: staging/cxt1e1: Convert bare printks to pr_ Added #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt A few line splits for long arguments A couple of embedded function names converted to "%s", __func__ Removed some uses of THIS_MODULE->name Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/cxt1e1/comet.c | 8 +- drivers/staging/cxt1e1/functions.c | 4 +- drivers/staging/cxt1e1/hwprobe.c | 22 ++-- drivers/staging/cxt1e1/linux.c | 28 ++-- drivers/staging/cxt1e1/musycc.c | 128 ++++++++++--------- drivers/staging/cxt1e1/pmc93x6_eeprom.c | 12 +- drivers/staging/cxt1e1/pmcc4_drv.c | 183 ++++++++++++++------------- drivers/staging/cxt1e1/sbecom_inline_linux.h | 4 +- drivers/staging/cxt1e1/sbeproc.c | 6 +- 9 files changed, 204 insertions(+), 191 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/cxt1e1/comet.c b/drivers/staging/cxt1e1/comet.c index b70909967038..dcbe6b628455 100644 --- a/drivers/staging/cxt1e1/comet.c +++ b/drivers/staging/cxt1e1/comet.c @@ -11,6 +11,8 @@ * GNU General Public License for more details. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include "pmcc4_sysdep.h" @@ -291,12 +293,12 @@ init_comet (void *ci, comet_t * comet, u_int32_t port_mode, int clockmaster, if ((moreParams & CFG_CLK_PORT_MASK) == CFG_CLK_PORT_INTERNAL) { if (log_level >= LOG_SBEBUG12) - printk (">> init_comet: clockmaster internal clock\n"); + pr_info(">> %s: clockmaster internal clock\n", __func__); pci_write_32 ((u_int32_t *) &comet->tx_time, 0x0d); /* internal oscillator */ } else /* external clock source */ { if (log_level >= LOG_SBEBUG12) - printk (">> init_comet: clockmaster external clock\n"); + pr_info(">> %s: clockmaster external clock\n", __func__); pci_write_32 ((u_int32_t *) &comet->tx_time, 0x09); /* loop timing * (external) */ } @@ -311,7 +313,7 @@ init_comet (void *ci, comet_t * comet, u_int32_t port_mode, int clockmaster, pci_write_32 ((u_int32_t *) &comet->brif_fpcfg, 0x20); /* Slave Mode i.e. * FPMODE=1 (@0x20) */ if (log_level >= LOG_SBEBUG12) - printk (">> init_comet: clockslave internal clock\n"); + pr_info(">> %s: clockslave internal clock\n", __func__); pci_write_32 ((u_int32_t *) &comet->tx_time, 0x0d); /* oscillator timing */ } diff --git a/drivers/staging/cxt1e1/functions.c b/drivers/staging/cxt1e1/functions.c index 738129d62bbf..86b498090265 100644 --- a/drivers/staging/cxt1e1/functions.c +++ b/drivers/staging/cxt1e1/functions.c @@ -68,7 +68,7 @@ pci_read_32 (u_int32_t *p) FLUSH_PCI_READ (); v = le32_to_cpu (*p); if (log_level >= LOG_DEBUG) - printk ("pci_read : %x = %x\n", (u_int32_t) p, v); + pr_info("pci_read : %x = %x\n", (u_int32_t) p, v); return v; #else FLUSH_PCI_READ (); /* */ @@ -81,7 +81,7 @@ pci_write_32 (u_int32_t *p, u_int32_t v) { #ifdef FLOW_DEBUG if (log_level >= LOG_DEBUG) - printk ("pci_write: %x = %x\n", (u_int32_t) p, v); + pr_info("pci_write: %x = %x\n", (u_int32_t) p, v); #endif *p = cpu_to_le32 (v); FLUSH_PCI_WRITE (); /* This routine is called from routines diff --git a/drivers/staging/cxt1e1/hwprobe.c b/drivers/staging/cxt1e1/hwprobe.c index 571fa1f7ddb4..8d4e8d28af59 100644 --- a/drivers/staging/cxt1e1/hwprobe.c +++ b/drivers/staging/cxt1e1/hwprobe.c @@ -83,17 +83,17 @@ show_two (hdw_info_t * hi, int brdno) (sn[5] & 0x0000ff), (u_int8_t) hi->revid[0]); - printk ("%s\n", banner); + pr_info("%s\n", banner); pdev = hi->pdev[0]; - printk ("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n", + pr_info("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n", hi->devname, "MUSYCC", (unsigned long) hi->addr_mapped[0], hi->addr[0], hi->pci_busno, (u_int8_t) PCI_SLOT (pdev->devfn), (u_int8_t) PCI_FUNC (pdev->devfn), pdev->irq); pdev = hi->pdev[1]; - printk ("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n", + pr_info("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n", hi->devname, "EBUS ", (unsigned long) hi->addr_mapped[1], hi->addr[1], hi->pci_busno, (u_int8_t) PCI_SLOT (pdev->devfn), @@ -116,22 +116,22 @@ hdw_sn_get (hdw_info_t * hi, int brdno) { unsigned char *ucp = (unsigned char *) &hi->mfg_info.data; - printk ("eeprom[00]: %02x %02x %02x %02x %02x %02x %02x %02x\n", + pr_info("eeprom[00]: %02x %02x %02x %02x %02x %02x %02x %02x\n", *(ucp + 0), *(ucp + 1), *(ucp + 2), *(ucp + 3), *(ucp + 4), *(ucp + 5), *(ucp + 6), *(ucp + 7)); - printk ("eeprom[08]: %02x %02x %02x %02x %02x %02x %02x %02x\n", + pr_info("eeprom[08]: %02x %02x %02x %02x %02x %02x %02x %02x\n", *(ucp + 8), *(ucp + 9), *(ucp + 10), *(ucp + 11), *(ucp + 12), *(ucp + 13), *(ucp + 14), *(ucp + 15)); - printk ("eeprom[16]: %02x %02x %02x %02x %02x %02x %02x %02x\n", + pr_info("eeprom[16]: %02x %02x %02x %02x %02x %02x %02x %02x\n", *(ucp + 16), *(ucp + 17), *(ucp + 18), *(ucp + 19), *(ucp + 20), *(ucp + 21), *(ucp + 22), *(ucp + 23)); - printk ("eeprom[24]: %02x %02x %02x %02x %02x %02x %02x %02x\n", + pr_info("eeprom[24]: %02x %02x %02x %02x %02x %02x %02x %02x\n", *(ucp + 24), *(ucp + 25), *(ucp + 26), *(ucp + 27), *(ucp + 28), *(ucp + 29), *(ucp + 30), *(ucp + 31)); - printk ("eeprom[32]: %02x %02x %02x %02x %02x %02x %02x %02x\n", + pr_info("eeprom[32]: %02x %02x %02x %02x %02x %02x %02x %02x\n", *(ucp + 32), *(ucp + 33), *(ucp + 34), *(ucp + 35), *(ucp + 36), *(ucp + 37), *(ucp + 38), *(ucp + 39)); - printk ("eeprom[40]: %02x %02x %02x %02x %02x %02x %02x %02x\n", + pr_info("eeprom[40]: %02x %02x %02x %02x %02x %02x %02x %02x\n", *(ucp + 40), *(ucp + 41), *(ucp + 42), *(ucp + 43), *(ucp + 44), *(ucp + 45), *(ucp + 46), *(ucp + 47)); } #endif #if 0 - printk ("sn: %x %x %x %x %x %x\n", + pr_info("sn: %x %x %x %x %x %x\n", hi->mfg_info.Serial[0], hi->mfg_info.Serial[1], hi->mfg_info.Serial[2], @@ -144,7 +144,7 @@ hdw_sn_get (hdw_info_t * hi, int brdno) { /* bad crc, data is suspect */ if (log_level >= LOG_WARN) - printk ("%s: EEPROM cksum error\n", hi->devname); + pr_info("%s: EEPROM cksum error\n", hi->devname); hi->mfg_info_sts = EEPROM_CRCERR; } else hi->mfg_info_sts = EEPROM_OK; diff --git a/drivers/staging/cxt1e1/linux.c b/drivers/staging/cxt1e1/linux.c index ce2942c097a6..134e7568024b 100644 --- a/drivers/staging/cxt1e1/linux.c +++ b/drivers/staging/cxt1e1/linux.c @@ -195,7 +195,8 @@ c4_wk_chan_restart (mch_t * ch) mpi_t *pi = ch->up; #ifdef RLD_RESTART_DEBUG - printk (">> c4_wk_chan_restart: queueing Port %d Chan %d, mch_t @ %p\n", pi->portnum, ch->channum, ch); + pr_info(">> %s: queueing Port %d Chan %d, mch_t @ %p\n", + __func__, pi->portnum, ch->channum, ch); #endif /* create new entry w/in workqueue for this channel and let'er rip */ @@ -236,7 +237,8 @@ c4_wq_port_init (mpi_t * pi) sprintf (np, "%s%d", pi->up->devname, pi->portnum); /* IE pmcc4-01) */ #ifdef RLD_RESTART_DEBUG - printk (">> c4_wq_port_init: creating workqueue <%s> for Port %d.\n", name, pi->portnum); /* RLD DEBUG */ + pr_info(">> %s: creating workqueue <%s> for Port %d.\n", + __func__, name, pi->portnum); /* RLD DEBUG */ #endif if (!(pi->wq_port = create_singlethread_workqueue (name))) return ENOMEM; @@ -284,7 +286,7 @@ c4_ebus_interrupt (int irq, void *dev_instance) static int void_open (struct net_device * ndev) { - printk ("%s: trying to open master device !\n", ndev->name); + pr_info("%s: trying to open master device !\n", ndev->name); return -1; } @@ -317,7 +319,7 @@ chan_open (struct net_device * ndev) hdlc->proto = IF_PROTO_HDLC; if ((ret = hdlc_open (hdlc))) { - printk ("%s: hdlc_open failure, err %d.\n", THIS_MODULE->name, ret); + pr_info("hdlc_open failure, err %d.\n", ret); return ret; } if ((ret = c4_chan_up (DEV_TO_PRIV (hdlc)->ci, DEV_TO_PRIV (hdlc)->channum))) @@ -340,7 +342,7 @@ chan_open (struct net_device * ndev) if ((ret = hdlc_open (ndev))) { - printk ("%s: hdlc_open failure, err %d.\n", THIS_MODULE->name, ret); + pr_info("hdlc_open failure, err %d.\n", ret); return ret; } if ((ret = c4_chan_up (priv->ci, priv->channum))) @@ -629,7 +631,7 @@ create_chan (struct net_device * ndev, ci_t * ci, if (ret) { if (log_level >= LOG_WARN) - printk ("%s: create_chan[%d] registration error = %d.\n", + pr_info("%s: create_chan[%d] registration error = %d.\n", ci->devname, cp->channum, ret); free_netdev (dev); /* cleanup */ return 0; /* failed to register */ @@ -1018,7 +1020,7 @@ c4_ioctl (struct net_device * ndev, struct ifreq * ifr, int cmd) #endif #if 0 - printk ("c4_ioctl: iocmd %x, dir %x type %x nr %x iolen %d.\n", iocmd, + pr_info("c4_ioctl: iocmd %x, dir %x type %x nr %x iolen %d.\n", iocmd, _IOC_DIR (iocmd), _IOC_TYPE (iocmd), _IOC_NR (iocmd), _IOC_SIZE (iocmd)); #endif @@ -1031,23 +1033,23 @@ c4_ioctl (struct net_device * ndev, struct ifreq * ifr, int cmd) switch (iocmd) { case SBE_IOC_PORT_GET: - //printk (">> SBE_IOC_PORT_GET Ioctl...\n"); + //pr_info(">> SBE_IOC_PORT_GET Ioctl...\n"); ret = do_get_port (ndev, data); break; case SBE_IOC_PORT_SET: - //printk (">> SBE_IOC_PORT_SET Ioctl...\n"); + //pr_info(">> SBE_IOC_PORT_SET Ioctl...\n"); ret = do_set_port (ndev, data); break; case SBE_IOC_CHAN_GET: - //printk (">> SBE_IOC_CHAN_GET Ioctl...\n"); + //pr_info(">> SBE_IOC_CHAN_GET Ioctl...\n"); ret = do_get_chan (ndev, data); break; case SBE_IOC_CHAN_SET: - //printk (">> SBE_IOC_CHAN_SET Ioctl...\n"); + //pr_info(">> SBE_IOC_CHAN_SET Ioctl...\n"); ret = do_set_chan (ndev, data); break; case C4_DEL_CHAN: - //printk (">> C4_DEL_CHAN Ioctl...\n"); + //pr_info(">> C4_DEL_CHAN Ioctl...\n"); ret = do_del_chan (ndev, data); break; case SBE_IOC_CHAN_NEW: @@ -1084,7 +1086,7 @@ c4_ioctl (struct net_device * ndev, struct ifreq * ifr, int cmd) return -EFAULT; break; default: - //printk (">> c4_ioctl: EINVAL - unknown iocmd <%x>\n", iocmd); + //pr_info(">> c4_ioctl: EINVAL - unknown iocmd <%x>\n", iocmd); ret = -EINVAL; break; } diff --git a/drivers/staging/cxt1e1/musycc.c b/drivers/staging/cxt1e1/musycc.c index 7a6d92a2215f..d3f5a5b52dc3 100644 --- a/drivers/staging/cxt1e1/musycc.c +++ b/drivers/staging/cxt1e1/musycc.c @@ -137,7 +137,7 @@ musycc_dump_rxbuffer_ring (mch_t * ch, int lockit) } if (ch->rxd_num == 0) { - printk (" ZERO receive buffers allocated for this channel."); + pr_info(" ZERO receive buffers allocated for this channel."); } else { FLUSH_MEM_READ (); @@ -146,7 +146,7 @@ musycc_dump_rxbuffer_ring (mch_t * ch, int lockit) { status = le32_to_cpu (m->status); { - printk ("%c %08lx[%2d]: sts %08x (%c%c%c%c:%d.) Data [%08x] Next [%08x]\n", + pr_info("%c %08lx[%2d]: sts %08x (%c%c%c%c:%d.) Data [%08x] Next [%08x]\n", (m == &ch->mdr[ch->rxix_irq_srv]) ? 'F' : ' ', (unsigned long) m, n, status, @@ -170,13 +170,13 @@ musycc_dump_rxbuffer_ring (mch_t * ch, int lockit) { dp = (u_int32_t *) OS_phystov ((void *) (le32_to_cpu (m->data))); if (len >= 0x10) - printk (" %x[%x]: %08X %08X %08X %08x\n", (u_int32_t) dp, len, + pr_info(" %x[%x]: %08X %08X %08X %08x\n", (u_int32_t) dp, len, *dp, *(dp + 1), *(dp + 2), *(dp + 3)); else if (len >= 0x08) - printk (" %x[%x]: %08X %08X\n", (u_int32_t) dp, len, + pr_info(" %x[%x]: %08X %08X\n", (u_int32_t) dp, len, *dp, *(dp + 1)); else - printk (" %x[%x]: %08X\n", (u_int32_t) dp, len, *dp); + pr_info(" %x[%x]: %08X\n", (u_int32_t) dp, len, *dp); } } #endif @@ -184,7 +184,7 @@ musycc_dump_rxbuffer_ring (mch_t * ch, int lockit) m = m->snext; } } /* -for- */ - printk ("\n"); + pr_info("\n"); if (lockit) { @@ -209,7 +209,7 @@ musycc_dump_txbuffer_ring (mch_t * ch, int lockit) } if (ch->txd_num == 0) { - printk (" ZERO transmit buffers allocated for this channel."); + pr_info(" ZERO transmit buffers allocated for this channel."); } else { FLUSH_MEM_READ (); @@ -218,7 +218,7 @@ musycc_dump_txbuffer_ring (mch_t * ch, int lockit) { status = le32_to_cpu (m->status); { - printk ("%c%c %08lx[%2d]: sts %08x (%c%c%c%c:%d.) Data [%08x] Next [%08x]\n", + pr_info("%c%c %08lx[%2d]: sts %08x (%c%c%c%c:%d.) Data [%08x] Next [%08x]\n", (m == ch->txd_usr_add) ? 'F' : ' ', (m == ch->txd_irq_srv) ? 'L' : ' ', (unsigned long) m, n, @@ -238,13 +238,13 @@ musycc_dump_txbuffer_ring (mch_t * ch, int lockit) { dp = (u_int32_t *) OS_phystov ((void *) (le32_to_cpu (m->data))); if (len >= 0x10) - printk (" %x[%x]: %08X %08X %08X %08x\n", (u_int32_t) dp, len, + pr_info(" %x[%x]: %08X %08X %08X %08x\n", (u_int32_t) dp, len, *dp, *(dp + 1), *(dp + 2), *(dp + 3)); else if (len >= 0x08) - printk (" %x[%x]: %08X %08X\n", (u_int32_t) dp, len, + pr_info(" %x[%x]: %08X %08X\n", (u_int32_t) dp, len, *dp, *(dp + 1)); else - printk (" %x[%x]: %08X\n", (u_int32_t) dp, len, *dp); + pr_info(" %x[%x]: %08X\n", (u_int32_t) dp, len, *dp); } } #endif @@ -252,7 +252,7 @@ musycc_dump_txbuffer_ring (mch_t * ch, int lockit) m = m->snext; } } /* -for- */ - printk ("\n"); + pr_info("\n"); if (lockit) { @@ -281,7 +281,7 @@ musycc_dump_ring (ci_t * ci, unsigned int chan) int bh; bh = atomic_read (&ci->bh_pending); - printk (">> bh_pend %d [%d] ihead %d itail %d [%d] th_cnt %d bh_cnt %d wdcnt %d note %d\n", + pr_info(">> bh_pend %d [%d] ihead %d itail %d [%d] th_cnt %d bh_cnt %d wdcnt %d note %d\n", bh, max_bh, ci->iqp_headx, ci->iqp_tailx, max_intcnt, ci->intlog.drvr_intr_thcount, ci->intlog.drvr_intr_bhcount, @@ -292,20 +292,20 @@ musycc_dump_ring (ci_t * ci, unsigned int chan) if (!(ch = sd_find_chan (dummy, chan))) { - printk (">> musycc_dump_ring: channel %d not up.\n", chan); + pr_info(">> musycc_dump_ring: channel %d not up.\n", chan); return ENOENT; } - printk (">> CI %p CHANNEL %3d @ %p: state %x status/p %x/%x\n", ci, chan, ch, ch->state, + pr_info(">> CI %p CHANNEL %3d @ %p: state %x status/p %x/%x\n", ci, chan, ch, ch->state, ch->status, ch->p.status); - printk ("--------------------------------\nTX Buffer Ring - Channel %d, txd_num %d. (bd/ch pend %d %d), TXD required %d, txpkt %lu\n", + pr_info("--------------------------------\nTX Buffer Ring - Channel %d, txd_num %d. (bd/ch pend %d %d), TXD required %d, txpkt %lu\n", chan, ch->txd_num, (u_int32_t) atomic_read (&ci->tx_pending), (u_int32_t) atomic_read (&ch->tx_pending), ch->txd_required, ch->s.tx_packets); - printk ("++ User 0x%p IRQ_SRV 0x%p USR_ADD 0x%p QStopped %x, start_tx %x tx_full %d txd_free %d mode %x\n", + pr_info("++ User 0x%p IRQ_SRV 0x%p USR_ADD 0x%p QStopped %x, start_tx %x tx_full %d txd_free %d mode %x\n", ch->user, ch->txd_irq_srv, ch->txd_usr_add, sd_queue_stopped (ch->user), ch->ch_start_tx, ch->tx_full, ch->txd_free, ch->p.chan_mode); musycc_dump_txbuffer_ring (ch, 1); - printk ("RX Buffer Ring - Channel %d, rxd_num %d. IRQ_SRV[%d] 0x%p, start_rx %x rxpkt %lu\n", + pr_info("RX Buffer Ring - Channel %d, rxd_num %d. IRQ_SRV[%d] 0x%p, start_rx %x rxpkt %lu\n", chan, ch->rxd_num, ch->rxix_irq_srv, &ch->mdr[ch->rxix_irq_srv], ch->ch_start_rx, ch->s.rx_packets); musycc_dump_rxbuffer_ring (ch, 1); @@ -400,7 +400,7 @@ musycc_update_tx_thp (mch_t * ch) spin_unlock_irqrestore (&ch->ch_txlock, flags); #ifdef RLD_TRANS_DEBUG - printk ("++ musycc_update_tx_thp[%d]: setting thp = %p, sts %x\n", ch->channum, md, md->status); + pr_info("++ musycc_update_tx_thp[%d]: setting thp = %p, sts %x\n", ch->channum, md, md->status); #endif } @@ -429,7 +429,7 @@ musycc_wq_chan_restart (void *arg) /* channel private structure */ pi = ch->up; #ifdef RLD_TRANS_DEBUG - printk ("wq_chan_restart[%d]: start_RT[%d/%d] status %x\n", + pr_info("wq_chan_restart[%d]: start_RT[%d/%d] status %x\n", ch->channum, ch->ch_start_rx, ch->ch_start_tx, ch->status); #endif @@ -451,12 +451,12 @@ musycc_wq_chan_restart (void *arg) /* channel private structure */ hereb4--; #ifdef RLD_TRANS_DEBUG md = &ch->mdr[ch->rxix_irq_srv]; - printk ("++ musycc_wq_chan_restart[%d] CHAN RX ACTIVATE: rxix_irq_srv %d, md %p sts %x, rxpkt %lu\n", + pr_info("++ musycc_wq_chan_restart[%d] CHAN RX ACTIVATE: rxix_irq_srv %d, md %p sts %x, rxpkt %lu\n", ch->channum, ch->rxix_irq_srv, md, le32_to_cpu (md->status), ch->s.rx_packets); #elif defined(RLD_RXACT_DEBUG) md = &ch->mdr[ch->rxix_irq_srv]; - printk ("++ musycc_wq_chan_restart[%d] CHAN RX ACTIVATE: rxix_irq_srv %d, md %p sts %x, rxpkt %lu\n", + pr_info("++ musycc_wq_chan_restart[%d] CHAN RX ACTIVATE: rxix_irq_srv %d, md %p sts %x, rxpkt %lu\n", ch->channum, ch->rxix_irq_srv, md, le32_to_cpu (md->status), ch->s.rx_packets); musycc_dump_rxbuffer_ring (ch, 1); /* RLD DEBUG */ @@ -482,7 +482,7 @@ musycc_wq_chan_restart (void *arg) /* channel private structure */ if (!md) { #ifdef RLD_TRANS_DEBUG - printk ("-- musycc_wq_chan_restart[%d]: WARNING, starting NULL md\n", ch->channum); + pr_info("-- musycc_wq_chan_restart[%d]: WARNING, starting NULL md\n", ch->channum); #endif #if 0 spin_unlock_irqrestore (&ch->ch_txlock, flags); @@ -494,7 +494,7 @@ musycc_wq_chan_restart (void *arg) /* channel private structure */ spin_unlock_irqrestore (&ch->ch_txlock, flags); /* allow interrupts for service request */ #endif #ifdef RLD_TRANS_DEBUG - printk ("++ musycc_wq_chan_restart() CHAN TX ACTIVATE: chan %d txd_irq_srv %p = sts %x, txpkt %lu\n", + pr_info("++ musycc_wq_chan_restart() CHAN TX ACTIVATE: chan %d txd_irq_srv %p = sts %x, txpkt %lu\n", ch->channum, ch->txd_irq_srv, ch->txd_irq_srv->status, ch->s.tx_packets); #endif musycc_serv_req (pi, SR_CHANNEL_ACTIVATE | SR_TX_DIRECTION | ch->gchan); @@ -503,7 +503,7 @@ musycc_wq_chan_restart (void *arg) /* channel private structure */ else { /* retain request to start until retried and we have data to xmit */ - printk ("-- musycc_wq_chan_restart[%d]: DELAYED due to md %p sts %x data %x, start_tx %x\n", + pr_info("-- musycc_wq_chan_restart[%d]: DELAYED due to md %p sts %x data %x, start_tx %x\n", ch->channum, md, le32_to_cpu (md->status), le32_to_cpu (md->data), ch->ch_start_tx); @@ -527,14 +527,14 @@ void musycc_chan_restart (mch_t * ch) { #ifdef RLD_RESTART_DEBUG - printk ("++ musycc_chan_restart[%d]: txd_irq_srv @ %p = sts %x\n", + pr_info("++ musycc_chan_restart[%d]: txd_irq_srv @ %p = sts %x\n", ch->channum, ch->txd_irq_srv, ch->txd_irq_srv->status); #endif #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41) /* 2.6 - find next unprocessed message, then set TX thp to it */ #ifdef RLD_RESTART_DEBUG - printk (">> musycc_chan_restart: scheduling Chan %x workQ @ %p\n", ch->channum, &ch->ch_work); + pr_info(">> musycc_chan_restart: scheduling Chan %x workQ @ %p\n", ch->channum, &ch->ch_work); #endif c4_wk_chan_restart (ch); /* work queue mechanism fires off: Ref: * musycc_wq_chan_restart () */ @@ -544,7 +544,7 @@ musycc_chan_restart (mch_t * ch) /* 2.4 - find next unprocessed message, then set TX thp to it */ #ifdef RLD_RESTART_DEBUG - printk (">> musycc_chan_restart: scheduling Chan %x start_tx %x\n", ch->channum, ch->ch_start_tx); + pr_info(">> musycc_chan_restart: scheduling Chan %x start_tx %x\n", ch->channum, ch->ch_start_tx); #endif /* restart transmission from background loop */ ch->up->up->wd_notify = WD_NOTIFY_1TX; @@ -620,7 +620,7 @@ musycc_serv_req (mpi_t * pi, u_int32_t req) if (pi->sr_last == req) { #ifdef RLD_TRANS_DEBUG - printk (">> same SR, Port %d Req %x\n", pi->portnum, req); + pr_info(">> same SR, Port %d Req %x\n", pi->portnum, req); #endif /* @@ -636,7 +636,7 @@ musycc_serv_req (mpi_t * pi, u_int32_t req) (r == (SR_CHANNEL_ACTIVATE | SR_RX_DIRECTION))) { #ifdef RLD_TRANS_DEBUG - printk (">> same CHAN ACT SR, Port %d Req %x => issue SR_NOOP CMD\n", pi->portnum, req); + pr_info(">> same CHAN ACT SR, Port %d Req %x => issue SR_NOOP CMD\n", pi->portnum, req); #endif SD_SEM_GIVE (&pi->sr_sem_busy); /* allow this next request */ musycc_serv_req (pi, SR_NOOP); @@ -646,7 +646,7 @@ musycc_serv_req (mpi_t * pi, u_int32_t req) { /* no need to issue back-to-back SR_NOOP commands at this time */ #ifdef RLD_TRANS_DEBUG - printk (">> same Port SR_NOOP skipped, Port %d\n", pi->portnum); + pr_info(">> same Port SR_NOOP skipped, Port %d\n", pi->portnum); #endif SD_SEM_GIVE (&pi->sr_sem_busy); /* allow this next request */ return; @@ -673,7 +673,7 @@ rewrite: if ((r != req) && (req != SR_CHIP_RESET) && (++rcnt <= MUSYCC_SR_RETRY_CNT)) { if (log_level >= LOG_MONITOR) - printk ("%s: %d - reissue srv req/last %x/%x (hdw reads %x), Chan %d.\n", + pr_info("%s: %d - reissue srv req/last %x/%x (hdw reads %x), Chan %d.\n", pi->up->devname, rcnt, req, pi->sr_last, r, (pi->portnum * MUSYCC_NCHANS) + (req & 0x1f)); OS_uwait_dummy (); /* this delay helps reduce reissue counts @@ -997,7 +997,8 @@ musycc_bh_tx_eom (mpi_t * pi, int gchan) if (ch == 0 || ch->state != UP) { if (log_level >= LOG_ERROR) - printk ("%s: intr: xmit EOM on uninitialized channel %d\n", pi->up->devname, gchan); + pr_info("%s: intr: xmit EOM on uninitialized channel %d\n", + pi->up->devname, gchan); } if (ch == 0 || ch->mdt == 0) return; /* note: mdt==0 implies a malloc() @@ -1048,9 +1049,10 @@ musycc_bh_tx_eom (mpi_t * pi, int gchan) { if (log_level >= LOG_MONITOR) { - printk ("%s: Port %d Chan %2d - unexpected TX msg ownership intr (md %p sts %x)\n", - pi->up->devname, pi->portnum, ch->channum, md, status); - printk ("++ User 0x%p IRQ_SRV 0x%p USR_ADD 0x%p QStopped %x, start_tx %x tx_full %d txd_free %d mode %x\n", + pr_info("%s: Port %d Chan %2d - unexpected TX msg ownership intr (md %p sts %x)\n", + pi->up->devname, pi->portnum, ch->channum, + md, status); + pr_info("++ User 0x%p IRQ_SRV 0x%p USR_ADD 0x%p QStopped %x, start_tx %x tx_full %d txd_free %d mode %x\n", ch->user, ch->txd_irq_srv, ch->txd_usr_add, sd_queue_stopped (ch->user), ch->ch_start_tx, ch->tx_full, ch->txd_free, ch->p.chan_mode); @@ -1060,7 +1062,7 @@ musycc_bh_tx_eom (mpi_t * pi, int gchan) } else { if (log_level >= LOG_MONITOR) - printk ("%s: Port %d Chan %2d - recovered TX msg ownership [%d] (md %p sts %x)\n", + pr_info("%s: Port %d Chan %2d - recovered TX msg ownership [%d] (md %p sts %x)\n", pi->up->devname, pi->portnum, ch->channum, readCount, md, status); } } @@ -1098,7 +1100,8 @@ musycc_bh_tx_eom (mpi_t * pi, int gchan) md->status = 0; #ifdef RLD_TXFULL_DEBUG if (log_level >= LOG_MONITOR2) - printk ("~~ tx_eom: tx_full %x txd_free %d -> %d\n", ch->tx_full, ch->txd_free, ch->txd_free + 1); + pr_info("~~ tx_eom: tx_full %x txd_free %d -> %d\n", + ch->tx_full, ch->txd_free, ch->txd_free + 1); #endif ++ch->txd_free; FLUSH_MEM_WRITE (); @@ -1106,7 +1109,7 @@ musycc_bh_tx_eom (mpi_t * pi, int gchan) if ((ch->p.chan_mode != CFG_CH_PROTO_TRANS) && (status & EOBIRQ_ENABLE)) { if (log_level >= LOG_MONITOR) - printk ("%s: Mode (%x) incorrect EOB status (%x)\n", + pr_info("%s: Mode (%x) incorrect EOB status (%x)\n", pi->up->devname, ch->p.chan_mode, status); if ((status & EOMIRQ_ENABLE) == 0) break; @@ -1137,7 +1140,7 @@ musycc_bh_tx_eom (mpi_t * pi, int gchan) #ifdef RLD_TXFULL_DEBUG if (log_level >= LOG_MONITOR2) - printk ("tx_eom[%d]: enable xmit tx_full no more, txd_free %d txd_num/2 %d\n", + pr_info("tx_eom[%d]: enable xmit tx_full no more, txd_free %d txd_num/2 %d\n", ch->channum, ch->txd_free, ch->txd_num / 2); #endif @@ -1151,7 +1154,7 @@ musycc_bh_tx_eom (mpi_t * pi, int gchan) else if (ch->tx_full) { if (log_level >= LOG_MONITOR2) - printk ("tx_eom[%d]: bypass TX enable though room available? (txd_free %d txd_num/2 %d)\n", + pr_info("tx_eom[%d]: bypass TX enable though room available? (txd_free %d txd_num/2 %d)\n", ch->channum, ch->txd_free, ch->txd_num / 2); } @@ -1181,7 +1184,8 @@ musycc_bh_rx_eom (mpi_t * pi, int gchan) if (ch == 0 || ch->state != UP) { if (log_level > LOG_ERROR) - printk ("%s: intr: receive EOM on uninitialized channel %d\n", pi->up->devname, gchan); + pr_info("%s: intr: receive EOM on uninitialized channel %d\n", + pi->up->devname, gchan); return; } if (ch->mdr == 0) @@ -1312,7 +1316,7 @@ musycc_intr_th_handler (void *devp) { if (log_level >= LOG_MONITOR) { - printk ("%s: note - updated ISD from %08x to %08x\n", + pr_info("%s: note - updated ISD from %08x to %08x\n", ci->devname, status, (status & (~INTRPTS_NEXTINT_M)) | ci->intlog.this_status_new); } @@ -1366,7 +1370,7 @@ musycc_intr_th_handler (void *devp) */ #if 0 /* chained interrupt = not ours */ - printk (">> %s: intCnt NULL, sts %x, possibly a chained interrupt!\n", + pr_info(">> %s: intCnt NULL, sts %x, possibly a chained interrupt!\n", ci->devname, status); #endif return IRQ_NONE; @@ -1380,10 +1384,10 @@ musycc_intr_th_handler (void *devp) if ((log_level >= LOG_WARN) && (status & INTRPTS_INTFULL_M)) { - printk ("%s: Interrupt queue full condition occurred\n", ci->devname); + pr_info("%s: Interrupt queue full condition occurred\n", ci->devname); } if (log_level >= LOG_DEBUG) - printk ("%s: interrupts pending, isd @ 0x%p: %x curr %d cnt %d NEXT %d\n", + pr_info("%s: interrupts pending, isd @ 0x%p: %x curr %d cnt %d NEXT %d\n", ci->devname, &ci->reg->isd, status, nextInt, intCnt, (intCnt + nextInt) & (INT_QUEUE_SIZE - 1)); @@ -1490,7 +1494,7 @@ musycc_intr_bh_tasklet (ci_t * ci) * Fix checking */ { if (log_level >= LOG_WARN) - printk ("%s: Illegal Interrupt Detected @ 0x%p, mod %d.)\n", + pr_info("%s: Illegal Interrupt Detected @ 0x%p, mod %d.)\n", ci->devname, &ci->iqd_p[headx], headx); /* @@ -1527,9 +1531,9 @@ musycc_intr_bh_tasklet (ci_t * ci) if (log_level >= LOG_DEBUG) { if (err != 0) - printk (" %08x -> err: %2d,", currInt, err); + pr_info(" %08x -> err: %2d,", currInt, err); - printk ("+ interrupt event: %d, grp: %d, chan: %2d, side: %cX\n", + pr_info("+ interrupt event: %d, grp: %d, chan: %2d, side: %cX\n", event, group, gchan, tx ? 'T' : 'R'); } pi = &ci->port[group]; /* notice that here we assume 1-1 group - @@ -1543,7 +1547,7 @@ musycc_intr_bh_tasklet (ci_t * ci) volatile u_int32_t r; r = pci_read_32 ((u_int32_t *) &pi->reg->srd); - printk ("- SACK cmd: %08x (hdw= %08x)\n", pi->sr_last, r); + pr_info("- SACK cmd: %08x (hdw= %08x)\n", pi->sr_last, r); } SD_SEM_GIVE (&pi->sr_sem_wait); /* wake up waiting process */ break; @@ -1576,7 +1580,7 @@ musycc_intr_bh_tasklet (ci_t * ci) break; default: if (log_level >= LOG_WARN) - printk ("%s: unexpected interrupt event: %d, iqd[%d]: %08x, port: %d\n", ci->devname, + pr_info("%s: unexpected interrupt event: %d, iqd[%d]: %08x, port: %d\n", ci->devname, event, headx, currInt, group); break; } /* switch on event */ @@ -1619,13 +1623,13 @@ musycc_intr_bh_tasklet (ci_t * ci) if (log_level >= LOG_MONITOR) #endif { - printk ("%s: TX buffer underflow [ONR] on channel %d, mode %x QStopped %x free %d\n", + pr_info("%s: TX buffer underflow [ONR] on channel %d, mode %x QStopped %x free %d\n", ci->devname, ch->channum, ch->p.chan_mode, sd_queue_stopped (ch->user), ch->txd_free); #ifdef RLD_DEBUG if (ch->p.chan_mode == 2) /* problem = ONR on HDLC * mode */ { - printk ("++ Failed Last %x Next %x QStopped %x, start_tx %x tx_full %d txd_free %d mode %x\n", + pr_info("++ Failed Last %x Next %x QStopped %x, start_tx %x tx_full %d txd_free %d mode %x\n", (u_int32_t) ch->txd_irq_srv, (u_int32_t) ch->txd_usr_add, sd_queue_stopped (ch->user), ch->ch_start_tx, ch->tx_full, ch->txd_free, ch->p.chan_mode); @@ -1648,7 +1652,7 @@ musycc_intr_bh_tasklet (ci_t * ci) if (log_level >= LOG_WARN) { - printk ("%s: RX buffer overflow [ONR] on channel %d, mode %x\n", + pr_info("%s: RX buffer overflow [ONR] on channel %d, mode %x\n", ci->devname, ch->channum, ch->p.chan_mode); //musycc_dump_rxbuffer_ring (ch, 0); /* RLD DEBUG */ } @@ -1665,7 +1669,7 @@ musycc_intr_bh_tasklet (ci_t * ci) * this BUFF error requires Transmit channel reactivation. */ if (log_level >= LOG_MONITOR) - printk ("%s: TX buffer underrun [BUFF] on channel %d, mode %x\n", + pr_info("%s: TX buffer underrun [BUFF] on channel %d, mode %x\n", ci->devname, ch->channum, ch->p.chan_mode); } else /* RX buffer overrun */ { @@ -1678,7 +1682,7 @@ musycc_intr_bh_tasklet (ci_t * ci) * not required, but data has been lost. */ if (log_level >= LOG_WARN) - printk ("%s: RX buffer overrun [BUFF] on channel %d, mode %x\n", + pr_info("%s: RX buffer overrun [BUFF] on channel %d, mode %x\n", ci->devname, ch->channum, ch->p.chan_mode); /* * Per MUSYCC manual, Section 6.4.9.4 [Receive Errors], @@ -1701,7 +1705,7 @@ musycc_intr_bh_tasklet (ci_t * ci) /* Check for interrupt lost condition */ if ((currInt & INTRPT_ILOST_M) && (log_level >= LOG_ERROR)) { - printk ("%s: Interrupt queue overflow - ILOST asserted\n", + pr_info("%s: Interrupt queue overflow - ILOST asserted\n", ci->devname); } ci->iqp_headx = (headx + 1) & (INT_QUEUE_SIZE - 1); /* insure wrapness */ @@ -1713,7 +1717,7 @@ musycc_intr_bh_tasklet (ci_t * ci) int bh; bh = atomic_read (&CI->bh_pending); - printk ("_bh_: late arrivals, head %d != tail %d, pending %d\n", + pr_info("_bh_: late arrivals, head %d != tail %d, pending %d\n", ci->iqp_headx, ci->iqp_tailx, bh); } #if defined(SBE_ISR_IMMEDIATE) @@ -1867,7 +1871,7 @@ musycc_start_xmit (ci_t * ci, int channum, void *mem_token) if (log_level >= LOG_MONITOR2) #endif { - printk ("++ start_xmt[%d]: state %x start %x full %d free %d required %d stopped %x\n", + pr_info("++ start_xmt[%d]: state %x start %x full %d free %d required %d stopped %x\n", channum, ch->state, ch->ch_start_tx, ch->tx_full, ch->txd_free, ch->txd_required, sd_queue_stopped (ch->user)); } @@ -1888,7 +1892,7 @@ musycc_start_xmit (ci_t * ci, int channum, void *mem_token) if (txd_need_cnt == 0) { if (log_level >= LOG_MONITOR2) - printk ("%s channel %d: no TX data in User buffer\n", ci->devname, channum); + pr_info("%s channel %d: no TX data in User buffer\n", ci->devname, channum); OS_mem_token_free (mem_token); return 0; /* no data to send */ } @@ -1900,7 +1904,7 @@ musycc_start_xmit (ci_t * ci, int channum, void *mem_token) { if (log_level >= LOG_DEBUG) { - printk ("start_xmit: discarding buffer, insufficient descriptor cnt %d, need %d.\n", + pr_info("start_xmit: discarding buffer, insufficient descriptor cnt %d, need %d.\n", ch->txd_num, txd_need_cnt + 1); } ch->s.tx_dropped++; @@ -1917,7 +1921,7 @@ musycc_start_xmit (ci_t * ci, int channum, void *mem_token) { if (log_level >= LOG_MONITOR2) { - printk ("start_xmit[%d]: EBUSY - need more descriptors, have %d of %d need %d\n", + pr_info("start_xmit[%d]: EBUSY - need more descriptors, have %d of %d need %d\n", channum, ch->txd_free, ch->txd_num, txd_need_cnt); } ch->tx_full = 1; diff --git a/drivers/staging/cxt1e1/pmc93x6_eeprom.c b/drivers/staging/cxt1e1/pmc93x6_eeprom.c index 02c829b318b4..1c8dfb80e7d7 100644 --- a/drivers/staging/cxt1e1/pmc93x6_eeprom.c +++ b/drivers/staging/cxt1e1/pmc93x6_eeprom.c @@ -21,6 +21,8 @@ * GNU General Public License for more details. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include "pmcc4_sysdep.h" #include "sbecom_inline_linux.h" @@ -448,7 +450,7 @@ pmcCalcCrc_T01 (void *bufp) (u_int32_t *) &crc); #ifdef EEPROM_TYPE_DEBUG - printk ("sbeCrc: crc 1 calculated as %08x\n", crc); /* RLD DEBUG */ + pr_info("sbeCrc: crc 1 calculated as %08x\n", crc); /* RLD DEBUG */ #endif return ~crc; } @@ -474,7 +476,7 @@ pmcCalcCrc_T02 (void *bufp) (u_int32_t *) &crc); #ifdef EEPROM_TYPE_DEBUG - printk ("sbeCrc: crc 2 calculated as %08x\n", crc); /* RLD DEBUG */ + pr_info("sbeCrc: crc 2 calculated as %08x\n", crc); /* RLD DEBUG */ #endif return crc; } @@ -520,7 +522,7 @@ pmc_init_seeprom (u_int32_t addr, u_int32_t serialNum) #ifdef DEBUG for (i = 0; i < sizeof (FLD_TYPE2); ++i) - printk ("[%02X] = %02X\n", i, buffer.bytes[i] & 0xFF); + pr_info("[%02X] = %02X\n", i, buffer.bytes[i] & 0xFF); #endif /* Write structure to serial EEPROM */ @@ -538,7 +540,7 @@ pmc_verify_cksum (void *bufp) /* Retrieve contents of CRC field */ crc1 = pmcGetBuffValue (&buf1->Crc32[0], sizeof (buf1->Crc32)); #ifdef EEPROM_TYPE_DEBUG - printk ("EEPROM: chksum 1 reads as %08x\n", crc1); /* RLD DEBUG */ + pr_info("EEPROM: chksum 1 reads as %08x\n", crc1); /* RLD DEBUG */ #endif if ((buf1->type == PROM_FORMAT_TYPE1) && (pmcCalcCrc_T01 ((void *) buf1) == crc1)) @@ -546,7 +548,7 @@ pmc_verify_cksum (void *bufp) crc2 = pmcGetBuffValue (&buf2->Crc32[0], sizeof (buf2->Crc32)); #ifdef EEPROM_TYPE_DEBUG - printk ("EEPROM: chksum 2 reads as %08x\n", crc2); /* RLD DEBUG */ + pr_info("EEPROM: chksum 2 reads as %08x\n", crc2); /* RLD DEBUG */ #endif if ((buf2->type == PROM_FORMAT_TYPE2) && (pmcCalcCrc_T02 ((void *) buf2) == crc2)) diff --git a/drivers/staging/cxt1e1/pmcc4_drv.c b/drivers/staging/cxt1e1/pmcc4_drv.c index 1617333575ce..333cf2687dd1 100644 --- a/drivers/staging/cxt1e1/pmcc4_drv.c +++ b/drivers/staging/cxt1e1/pmcc4_drv.c @@ -172,10 +172,10 @@ sbecom_set_loglevel (int d) { if (log_level != d) { - printk ("%s: log level changed from %d to %d\n", THIS_MODULE->name, log_level, d); + pr_info("log level changed from %d to %d\n", log_level, d); log_level = d; /* set new */ } else - printk ("%s: log level is %d\n", THIS_MODULE->name, log_level); + pr_info("log level is %d\n", log_level); } } @@ -292,19 +292,18 @@ checkPorts (ci_t * ci) if (!(((copyVal >> 3) & sbeLinkDown) ^ (value & sbeLinkDown))) { if (value & sbeLinkDown) - printk (KERN_WARN "%s: Port %d momentarily recovered.\n", - ci->devname, portnum); + pr_warning("%s: Port %d momentarily recovered.\n", + ci->devname, portnum); else - printk (KERN_WARN - "%s: Warning: Port %d link was briefly down.\n", - ci->devname, portnum); + pr_warning("%s: Warning: Port %d link was briefly down.\n", + ci->devname, portnum); } else if (value & sbeLinkDown) - printk (KERN_WARN "%s: Warning: Port %d link is down.\n", - ci->devname, portnum); + pr_warning("%s: Warning: Port %d link is down.\n", + ci->devname, portnum); else { - printk (KERN_WARN "%s: Port %d link has recovered.\n", - ci->devname, portnum); + pr_warning("%s: Port %d link has recovered.\n", + ci->devname, portnum); copyVal |= 0x20; /* record link transition to up */ } copyVal |= 0x10; /* change (link) --> update LEDs */ @@ -331,35 +330,30 @@ checkPorts (ci_t * ci) if (value & 0x1f) { /* if errors (crc or smf only) */ if (value & 0x10) - printk (KERN_WARN - "%s: E1 Port %d Codeword Sa4 change detected.\n", - ci->devname, portnum); + pr_warning("%s: E1 Port %d Codeword Sa4 change detected.\n", + ci->devname, portnum); if (value & 0x08) - printk (KERN_WARN - "%s: E1 Port %d Codeword Sa5 change detected.\n", - ci->devname, portnum); + pr_warning("%s: E1 Port %d Codeword Sa5 change detected.\n", + ci->devname, portnum); if (value & 0x04) - printk (KERN_WARN - "%s: E1 Port %d Codeword Sa6 change detected.\n", - ci->devname, portnum); + pr_warning("%s: E1 Port %d Codeword Sa6 change detected.\n", + ci->devname, portnum); if (value & 0x02) - printk (KERN_WARN - "%s: E1 Port %d Codeword Sa7 change detected.\n", - ci->devname, portnum); + pr_warning("%s: E1 Port %d Codeword Sa7 change detected.\n", + ci->devname, portnum); if (value & 0x01) - printk (KERN_WARN - "%s: E1 Port %d Codeword Sa8 change detected.\n", - ci->devname, portnum); + pr_warning("%s: E1 Port %d Codeword Sa8 change detected.\n", + ci->devname, portnum); } value = pci_read_32 ((u_int32_t *) &comet->e1_frmr_mists); /* crc & smf */ if (value & 0x3) { /* if errors (crc or smf only) */ if (value & sbeE1CRC) - printk (KERN_WARN "%s: E1 Port %d CRC-4 error(s) detected.\n", - ci->devname, portnum); + pr_warning("%s: E1 Port %d CRC-4 error(s) detected.\n", + ci->devname, portnum); if (value & sbeE1errSMF) /* error in sub-multiframe */ - printk (KERN_WARN "%s: E1 Port %d received errored SMF.\n", - ci->devname, portnum); + pr_warning("%s: E1 Port %d received errored SMF.\n", + ci->devname, portnum); } value = pci_read_32 ((u_int32_t *) &comet->e1_frmr_masts) & 0xcc; /* alarms */ /* @@ -383,43 +377,43 @@ checkPorts (ci_t * ci) if ((copyVal & sbeRedAlm) && !(value & sbeRedAlm)) { copyVal &= ~sbeRedAlm; - printk (KERN_WARN "%s: E1 Port %d LOF alarm ended.\n", - ci->devname, portnum); + pr_warning("%s: E1 Port %d LOF alarm ended.\n", + ci->devname, portnum); } else if (!(copyVal & sbeRedAlm) && (value & sbeRedAlm)) { copyVal |= sbeRedAlm; - printk (KERN_WARN "%s: E1 Warning: Port %d LOF alarm.\n", - ci->devname, portnum); + pr_warning("%s: E1 Warning: Port %d LOF alarm.\n", + ci->devname, portnum); } else if ((copyVal & sbeYelAlm) && !(value & sbeYelAlm)) { copyVal &= ~sbeYelAlm; - printk (KERN_WARN "%s: E1 Port %d RAI alarm ended.\n", - ci->devname, portnum); + pr_warning("%s: E1 Port %d RAI alarm ended.\n", + ci->devname, portnum); } else if (!(copyVal & sbeYelAlm) && (value & sbeYelAlm)) { copyVal |= sbeYelAlm; - printk (KERN_WARN "%s: E1 Warning: Port %d RAI alarm.\n", - ci->devname, portnum); + pr_warning("%s: E1 Warning: Port %d RAI alarm.\n", + ci->devname, portnum); } else if ((copyVal & sbeE1RMAI) && !(value & sbeE1RMAI)) { copyVal &= ~sbeE1RMAI; - printk (KERN_WARN "%s: E1 Port %d RMAI alarm ended.\n", - ci->devname, portnum); + pr_warning("%s: E1 Port %d RMAI alarm ended.\n", + ci->devname, portnum); } else if (!(copyVal & sbeE1RMAI) && (value & sbeE1RMAI)) { copyVal |= sbeE1RMAI; - printk (KERN_WARN "%s: E1 Warning: Port %d RMAI alarm.\n", - ci->devname, portnum); + pr_warning("%s: E1 Warning: Port %d RMAI alarm.\n", + ci->devname, portnum); } else if ((copyVal & sbeAISAlm) && !(value & sbeAISAlm)) { copyVal &= ~sbeAISAlm; - printk (KERN_WARN "%s: E1 Port %d AIS alarm ended.\n", - ci->devname, portnum); + pr_warning("%s: E1 Port %d AIS alarm ended.\n", + ci->devname, portnum); } else if (!(copyVal & sbeAISAlm) && (value & sbeAISAlm)) { copyVal |= sbeAISAlm; - printk (KERN_WARN "%s: E1 Warning: Port %d AIS alarm.\n", - ci->devname, portnum); + pr_warning("%s: E1 Warning: Port %d AIS alarm.\n", + ci->devname, portnum); } } /* end of E1 alarm code */ @@ -433,33 +427,33 @@ checkPorts (ci_t * ci) if ((copyVal & sbeRedAlm) && !(value & sbeRedAlm)) { copyVal &= ~sbeRedAlm; - printk (KERN_WARN "%s: Port %d red alarm ended.\n", - ci->devname, portnum); + pr_warning("%s: Port %d red alarm ended.\n", + ci->devname, portnum); } else if (!(copyVal & sbeRedAlm) && (value & sbeRedAlm)) { copyVal |= sbeRedAlm; - printk (KERN_WARN "%s: Warning: Port %d red alarm.\n", - ci->devname, portnum); + pr_warning("%s: Warning: Port %d red alarm.\n", + ci->devname, portnum); } else if ((copyVal & sbeYelAlm) && !(value & sbeYelAlm)) { copyVal &= ~sbeYelAlm; - printk (KERN_WARN "%s: Port %d yellow (RAI) alarm ended.\n", - ci->devname, portnum); + pr_warning("%s: Port %d yellow (RAI) alarm ended.\n", + ci->devname, portnum); } else if (!(copyVal & sbeYelAlm) && (value & sbeYelAlm)) { copyVal |= sbeYelAlm; - printk (KERN_WARN "%s: Warning: Port %d yellow (RAI) alarm.\n", - ci->devname, portnum); + pr_warning("%s: Warning: Port %d yellow (RAI) alarm.\n", + ci->devname, portnum); } else if ((copyVal & sbeAISAlm) && !(value & sbeAISAlm)) { copyVal &= ~sbeAISAlm; - printk (KERN_WARN "%s: Port %d blue (AIS) alarm ended.\n", - ci->devname, portnum); + pr_warning("%s: Port %d blue (AIS) alarm ended.\n", + ci->devname, portnum); } else if (!(copyVal & sbeAISAlm) && (value & sbeAISAlm)) { copyVal |= sbeAISAlm; - printk (KERN_WARN "%s: Warning: Port %d blue (AIS) alarm.\n", - ci->devname, portnum); + pr_warning("%s: Warning: Port %d blue (AIS) alarm.\n", + ci->devname, portnum); } } } /* end T1 mode alarm checks */ @@ -523,8 +517,8 @@ checkPorts (ci_t * ci) * loopbk mode */ if (log_level >= LOG_DEBUG) if (value != 0x3f) - printk (KERN_WARN "%s: BOC value = %x on Port %d\n", - ci->devname, value, portnum); + pr_warning("%s: BOC value = %x on Port %d\n", + ci->devname, value, portnum); /* end ESF loopback code */ } } @@ -546,7 +540,7 @@ c4_watchdog (ci_t * ci) if (drvr_state != SBE_DRVR_AVAILABLE) { if (log_level >= LOG_MONITOR) - printk ("%s: drvr not available (%x)\n", THIS_MODULE->name, drvr_state); + pr_info("drvr not available (%x)\n", drvr_state); return; } #if 0 @@ -579,7 +573,7 @@ c4_watchdog (ci_t * ci) #else if (log_level >= LOG_MONITOR) #endif - printk ("%s: watchdog reviving Port %d Channel %d [%d] sts %x/%x, start_TX %x free %x start_RX %x\n", + pr_info("%s: watchdog reviving Port %d Channel %d [%d] sts %x/%x, start_TX %x free %x start_RX %x\n", ci->devname, ch->channum, port, gchan, ch->channum, ch->p.status, ch->status, ch->ch_start_tx, ch->txd_free, ch->ch_start_rx); @@ -595,7 +589,8 @@ c4_watchdog (ci_t * ci) { ch->ch_start_rx = 0; /* we are restarting RX... */ #ifdef RLD_TRANS_DEBUG - printk ("++ c4_watchdog() CHAN RX ACTIVATE: chan %d\n", ch->channum); + pr_info("++ c4_watchdog() CHAN RX ACTIVATE: chan %d\n", + ch->channum); #endif #ifdef RLD_RXACT_DEBUG { @@ -606,7 +601,7 @@ c4_watchdog (ci_t * ci) { hereb4--; md = &ch->mdr[ch->rxix_irq_srv]; - printk ("++ c4_watchdog[%d] CHAN RX ACTIVATE: rxix_irq_srv %d, md %p sts %x, rxpkt %lu\n", + pr_info("++ c4_watchdog[%d] CHAN RX ACTIVATE: rxix_irq_srv %d, md %p sts %x, rxpkt %lu\n", ch->channum, ch->rxix_irq_srv, md, le32_to_cpu (md->status), ch->s.rx_packets); musycc_dump_rxbuffer_ring (ch, 1); /* RLD DEBUG */ } @@ -636,8 +631,9 @@ c4_watchdog (ci_t * ci) md = ch->txd_irq_srv; if (!md) { - printk ("-- c4_watchdog[%d]: WARNING, starting NULL md\n", ch->channum); - printk ("-- chan %d txd_irq_srv %p sts %x usr_add %p sts %x, txpkt %lu\n", + pr_info("-- c4_watchdog[%d]: WARNING, starting NULL md\n", + ch->channum); + pr_info("-- chan %d txd_irq_srv %p sts %x usr_add %p sts %x, txpkt %lu\n", ch->channum, ch->txd_irq_srv, le32_to_cpu ((struct mdesc *) (ch->txd_irq_srv)->status), ch->txd_usr_add, le32_to_cpu ((struct mdesc *) (ch->txd_usr_add)->status), ch->s.tx_packets); @@ -647,7 +643,8 @@ c4_watchdog (ci_t * ci) } else if (md->data && ((le32_to_cpu (md->status)) & MUSYCC_TX_OWNED)) { #ifdef RLD_TRANS_DEBUG - printk ("++ c4_watchdog[%d] CHAN TX ACTIVATE: start_tx %x\n", ch->channum, ch->ch_start_tx); + pr_info("++ c4_watchdog[%d] CHAN TX ACTIVATE: start_tx %x\n", + ch->channum, ch->ch_start_tx); #endif ch->ch_start_tx = 0; /* we are restarting * TX... */ @@ -661,7 +658,8 @@ c4_watchdog (ci_t * ci) #else if (log_level >= LOG_MONITOR) #endif - printk ("++ SACK[P%d/C%d] ack'd, continuing...\n", ch->up->portnum, ch->channum); + pr_info("++ SACK[P%d/C%d] ack'd, continuing...\n", + ch->up->portnum, ch->channum); } } } @@ -784,7 +782,7 @@ c4_init (ci_t * ci, u_char *func0, u_char *func1) pi->p.portnum = portnum; pi->openchans = 0; #ifdef SBE_MAP_DEBUG - printk ("Comet-%d: addr = %p\n", portnum, pi->cometbase); + pr_info("Comet-%d: addr = %p\n", portnum, pi->cometbase); #endif } pmsk = c4_get_portcfg (ci); @@ -811,7 +809,8 @@ c4_init (ci_t * ci, u_char *func0, u_char *func1) return SBE_DRVR_FAIL; } #ifdef SBE_MAP_DEBUG - printk (">> %s: c4_get_build - pmsk %x max_port %x\n", ci->devname, pmsk, ci->max_port); + pr_info(">> %s: c4_get_build - pmsk %x max_port %x\n", + ci->devname, pmsk, ci->max_port); #endif } @@ -934,19 +933,20 @@ c4_loop_port (ci_t * ci, int portnum, u_int8_t cmd) pci_write_32 ((u_int32_t *) &comet->mdiag, cmd); if (log_level >= LOG_WARN) - printk ("%s: loopback mode changed to %2x from %2x on Port %d\n", + pr_info("%s: loopback mode changed to %2x from %2x on Port %d\n", ci->devname, cmd, loopValue, portnum); loopValue = pci_read_32 ((u_int32_t *) &comet->mdiag) & COMET_MDIAG_LBMASK; if (loopValue != cmd) { if (log_level >= LOG_ERROR) - printk ("%s: write to loop register failed, unknown state for Port %d\n", + pr_info("%s: write to loop register failed, unknown state for Port %d\n", ci->devname, portnum); } } else { if (log_level >= LOG_WARN) - printk ("%s: loopback already in that mode (%2x)\n", ci->devname, loopValue); + pr_info("%s: loopback already in that mode (%2x)\n", + ci->devname, loopValue); } return 0; } @@ -980,7 +980,7 @@ c4_frame_rw (ci_t * ci, struct sbecom_port_param * pp) { /* control says this is a register * _write_ */ if (pp->portStatus == data) - printk ("%s: Port %d already that value! Writing again anyhow.\n", + pr_info("%s: Port %d already that value! Writing again anyhow.\n", ci->devname, pp->portnum); pp->portP = (u_int8_t) data; pci_write_32 ((u_int32_t *) comet + pp->port_mode, @@ -1080,11 +1080,11 @@ c4_musycc_rw (ci_t * ci, struct c4_musycc_param * mcp) if (ramread) { data = *dpr; - //printk ("c4_musycc_rw: RAM addr %p read data %x (portno %x offset %x RAM ramread %x)\n", dpr, data, portnum, offset, ramread); /* RLD DEBUG */ + //pr_info("c4_musycc_rw: RAM addr %p read data %x (portno %x offset %x RAM ramread %x)\n", dpr, data, portnum, offset, ramread); /* RLD DEBUG */ } else { data = pci_read_32 ((u_int32_t *) dph); - //printk ("c4_musycc_rw: REG addr %p read data %x (portno %x offset %x RAM ramread %x)\n", dph, data, portnum, offset, ramread); /* RLD DEBUG */ + //pr_info("c4_musycc_rw: REG addr %p read data %x (portno %x offset %x RAM ramread %x)\n", dph, data, portnum, offset, ramread); /* RLD DEBUG */ } @@ -1092,7 +1092,7 @@ c4_musycc_rw (ci_t * ci, struct c4_musycc_param * mcp) { /* control says this is a register * _write_ */ if (mcp->value == data) - printk ("%s: musycc grp%d already that value! writing again anyhow.\n", + pr_info("%s: musycc grp%d already that value! writing again anyhow.\n", ci->devname, (mcp->RWportnum & 0x7)); /* write register RAM */ if (ramread) @@ -1137,7 +1137,7 @@ c4_set_port (ci_t * ci, int portnum) e1mode = IS_FRAME_ANY_E1 (pp->port_mode); if (log_level >= LOG_MONITOR2) { - printk ("%s: c4_set_port[%d]: entered, e1mode = %x, openchans %d.\n", + pr_info("%s: c4_set_port[%d]: entered, e1mode = %x, openchans %d.\n", ci->devname, portnum, e1mode, pi->openchans); } @@ -1421,13 +1421,12 @@ c4_fifo_alloc (mpi_t * pi, int chan, int *len) if (max != *len) { if (log_level >= LOG_WARN) - printk ( - "%s: wanted to allocate %d fifo space, but got only %d\n", + pr_info("%s: wanted to allocate %d fifo space, but got only %d\n", pi->up->devname, *len, max); *len = max; } if (log_level >= LOG_DEBUG) - printk ("%s: allocated %d fifo at %d for channel %d/%d\n", + pr_info("%s: allocated %d fifo at %d for channel %d/%d\n", pi->up->devname, max, start, chan, pi->p.portnum); for (i = maxstart; i < (maxstart + max); i++) pi->fifomap[i] = chan; @@ -1440,7 +1439,7 @@ c4_fifo_free (mpi_t * pi, int chan) int i; if (log_level >= LOG_DEBUG) - printk ("%s: deallocated fifo for channel %d/%d\n", + pr_info("%s: deallocated fifo for channel %d/%d\n", pi->up->devname, chan, pi->p.portnum); for (i = 0; i < 32; i++) if (pi->fifomap[i] == chan) @@ -1465,7 +1464,8 @@ c4_chan_up (ci_t * ci, int channum) if (ch->state == UP) { if (log_level >= LOG_MONITOR) - printk ("%s: channel already UP, graceful early exit\n", ci->devname); + pr_info("%s: channel already UP, graceful early exit\n", + ci->devname); return 0; } pi = ch->up; @@ -1478,9 +1478,10 @@ c4_chan_up (ci_t * ci, int channum) { if (1 || log_level >= LOG_WARN) { - printk ("%s: c4_chan_up[%d] EINVAL (attempt to cfg in-use or unavailable TimeSlot[%d])\n", + pr_info("%s: c4_chan_up[%d] EINVAL (attempt to cfg in-use or unavailable TimeSlot[%d])\n", ci->devname, channum, i); - printk ("+ ask4 %x, currently %x\n", ch->p.bitmask[i], pi->tsm[i]); + pr_info("+ ask4 %x, currently %x\n", + ch->p.bitmask[i], pi->tsm[i]); } return EINVAL; } @@ -1493,7 +1494,8 @@ c4_chan_up (ci_t * ci, int channum) if (!nbuf) { /* if( log_level >= LOG_WARN) */ - printk ("%s: c4_chan_up[%d] ENOBUFS (no TimeSlots assigned)\n", ci->devname, channum); + pr_info("%s: c4_chan_up[%d] ENOBUFS (no TimeSlots assigned)\n", + ci->devname, channum); return ENOBUFS; /* this should not happen */ } addr = c4_fifo_alloc (pi, gchan, &nbuf); @@ -1561,7 +1563,7 @@ c4_chan_up (ci_t * ci, int channum) #if 0 /* DEBUG INFO */ if (log_level >= LOG_MONITOR) - printk ("%s: mode %x rxnum %d (rxused %d def %d) txnum %d (txused %d def %d)\n", + pr_info("%s: mode %x rxnum %d (rxused %d def %d) txnum %d (txused %d def %d)\n", ci->devname, ch->p.chan_mode, rxnum, max_rxdesc_used, max_rxdesc_default, txnum, max_txdesc_used, max_txdesc_default); @@ -1592,7 +1594,8 @@ c4_chan_up (ci_t * ci, int channum) if (!(m = OS_mem_token_alloc (max_mru))) { if (log_level >= LOG_MONITOR) - printk ("%s: c4_chan_up[%d] - token alloc failure, size = %d.\n", ci->devname, channum, max_mru); + pr_info("%s: c4_chan_up[%d] - token alloc failure, size = %d.\n", + ci->devname, channum, max_mru); goto errfree; } md->mem_token = m; @@ -1638,7 +1641,7 @@ c4_chan_up (ci_t * ci, int channum) if (ch->p.status & RX_ENABLED) { #ifdef RLD_TRANS_DEBUG - printk ("++ c4_chan_up() CHAN RX ACTIVATE: chan %d\n", ch->channum); + pr_info("++ c4_chan_up() CHAN RX ACTIVATE: chan %d\n", ch->channum); #endif ch->ch_start_rx = 0; /* we are restarting RX... */ musycc_serv_req (pi, SR_CHANNEL_ACTIVATE | SR_RX_DIRECTION | gchan); @@ -1646,7 +1649,7 @@ c4_chan_up (ci_t * ci, int channum) if (ch->p.status & TX_ENABLED) { #ifdef RLD_TRANS_DEBUG - printk ("++ c4_chan_up() CHAN TX ACTIVATE: chan %d \n", ch->channum); + pr_info("++ c4_chan_up() CHAN TX ACTIVATE: chan %d \n", ch->channum); #endif ch->ch_start_tx = CH_START_TX_1ST; /* we are delaying start * until receipt from user of diff --git a/drivers/staging/cxt1e1/sbecom_inline_linux.h b/drivers/staging/cxt1e1/sbecom_inline_linux.h index 44229a93de4e..c65172db2ad8 100644 --- a/drivers/staging/cxt1e1/sbecom_inline_linux.h +++ b/drivers/staging/cxt1e1/sbecom_inline_linux.h @@ -94,7 +94,7 @@ pci_read_32 (u_int32_t *p) FLUSH_PCI_READ (); v = le32_to_cpu (*p); if (log_level >= LOG_DEBUG) - printk ("pci_read : %x = %x\n", (u_int32_t) p, v); + pr_info("pci_read : %x = %x\n", (u_int32_t) p, v); return v; #else FLUSH_PCI_READ (); /* */ @@ -107,7 +107,7 @@ pci_write_32 (u_int32_t *p, u_int32_t v) { #ifdef FLOW_DEBUG if (log_level >= LOG_DEBUG) - printk ("pci_write: %x = %x\n", (u_int32_t) p, v); + pr_info("pci_write: %x = %x\n", (u_int32_t) p, v); #endif *p = cpu_to_le32 (v); FLUSH_PCI_WRITE (); /* This routine is called from routines diff --git a/drivers/staging/cxt1e1/sbeproc.c b/drivers/staging/cxt1e1/sbeproc.c index 92f6f5ca39be..4f4dcd36bf4d 100644 --- a/drivers/staging/cxt1e1/sbeproc.c +++ b/drivers/staging/cxt1e1/sbeproc.c @@ -66,7 +66,7 @@ sbecom_proc_get_sbe_info (char *buffer, char **start, off_t offset, } #if 0 /** RLD DEBUG **/ - printk (">> sbecom_proc_get_sbe_info: entered, offset %d. length %d.\n", + pr_info(">> sbecom_proc_get_sbe_info: entered, offset %d. length %d.\n", (int) offset, (int) length); #endif @@ -90,7 +90,7 @@ sbecom_proc_get_sbe_info (char *buffer, char **start, off_t offset, #if 0 /** RLD DEBUG **/ - printk (">> sbecom_get_brdinfo: returned, first_if %p <%s> last_if %p <%s>\n", + pr_info(">> sbecom_get_brdinfo: returned, first_if %p <%s> last_if %p <%s>\n", (char *) &bip->first_iname, (char *) &bip->first_iname, (char *) &bip->last_iname, (char *) &bip->last_iname); #endif @@ -293,7 +293,7 @@ sbecom_proc_get_sbe_info (char *buffer, char **start, off_t offset, #endif #if 0 - printk (">> proc_fs: returned len = %d., start %p\n", len, start); /* RLD DEBUG */ + pr_info(">> proc_fs: returned len = %d., start %p\n", len, start); /* RLD DEBUG */ #endif /*** -- cgit v1.2.3 From 199ef62a287b429a8fa3b7dc5ae6b69f607bf324 Mon Sep 17 00:00:00 2001 From: Florian Schilhabel Date: Tue, 4 May 2010 14:23:43 +0200 Subject: Staging: rtl8192su: check for skb == NULL added 2 checks for skb == NULL. plus cosmetics Signed-off-by: Florian Schilhabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192su/r8192S_firmware.c | 135 +++++++++++++--------------- drivers/staging/rtl8192su/r8192U_core.c | 2 - drivers/staging/rtl8192su/r819xU_cmdpkt.c | 6 ++ 3 files changed, 68 insertions(+), 75 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192su/r8192S_firmware.c b/drivers/staging/rtl8192su/r8192S_firmware.c index b6ae8543c5ca..37d164c0e928 100644 --- a/drivers/staging/rtl8192su/r8192S_firmware.c +++ b/drivers/staging/rtl8192su/r8192S_firmware.c @@ -31,44 +31,46 @@ // Code size // Created by Roger, 2008.04.10. // -bool FirmwareDownloadCode(struct net_device *dev, u8 * code_virtual_address,u32 buffer_len) +bool FirmwareDownloadCode(struct net_device *dev, + u8 *code_virtual_address, + u32 buffer_len) { - struct r8192_priv *priv = ieee80211_priv(dev); - bool rt_status = true; - u16 frag_threshold = MAX_FIRMWARE_CODE_SIZE; //Fragmentation might be required in 90/92 but not in 92S - u16 frag_length, frag_offset = 0; - struct sk_buff *skb; - unsigned char *seg_ptr; - cb_desc *tcb_desc; - u8 bLastIniPkt = 0; - u16 ExtraDescOffset = 0; - - - RT_TRACE(COMP_FIRMWARE, "--->FirmwareDownloadCode()\n" ); - - //MAX_TRANSMIT_BUFFER_SIZE - if(buffer_len >= MAX_FIRMWARE_CODE_SIZE-USB_HWDESC_HEADER_LEN) - { - RT_TRACE(COMP_ERR, "Size over MAX_FIRMWARE_CODE_SIZE! \n"); + struct r8192_priv *priv = ieee80211_priv(dev); + bool rt_status = true; + /* Fragmentation might be required in 90/92 but not in 92S */ + u16 frag_threshold = MAX_FIRMWARE_CODE_SIZE; + u16 frag_length, frag_offset = 0; + struct sk_buff *skb; + unsigned char *seg_ptr; + cb_desc *tcb_desc; + u8 bLastIniPkt = 0; + u16 ExtraDescOffset = 0; + + if (buffer_len >= MAX_FIRMWARE_CODE_SIZE - USB_HWDESC_HEADER_LEN) { + RT_TRACE(COMP_ERR, "(%s): Firmware exceeds" + " MAX_FIRMWARE_CODE_SIZE\n", __func__); goto cmdsend_downloadcode_fail; } - ExtraDescOffset = USB_HWDESC_HEADER_LEN; - do { if((buffer_len-frag_offset) > frag_threshold) - { frag_length = frag_threshold + ExtraDescOffset; + else { + frag_length = (u16)(buffer_len - + frag_offset + ExtraDescOffset); + bLastIniPkt = 1; } - else - { - frag_length = (u16)(buffer_len - frag_offset + ExtraDescOffset); - bLastIniPkt = 1; - } - - /* Allocate skb buffer to contain firmware info and tx descriptor info. */ + /* + * Allocate skb buffer to contain firmware info + * and tx descriptor info. + */ skb = dev_alloc_skb(frag_length); - memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev)); + if (skb == NULL) { + RT_TRACE(COMP_ERR, "(%s): unable to alloc skb buffer\n", + __func__); + goto cmdsend_downloadcode_fail; + } + memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE); tcb_desc->queue_index = TXCMD_QUEUE; @@ -76,73 +78,60 @@ bool FirmwareDownloadCode(struct net_device *dev, u8 * code_virtual_address,u32 tcb_desc->bLastIniPkt = bLastIniPkt; skb_reserve(skb, ExtraDescOffset); - seg_ptr = (u8 *)skb_put(skb, (u32)(frag_length-ExtraDescOffset)); - memcpy(seg_ptr, code_virtual_address+frag_offset, (u32)(frag_length-ExtraDescOffset)); - tcb_desc->txbuf_size= frag_length; + seg_ptr = (u8 *)skb_put(skb, + (u32)(frag_length - ExtraDescOffset)); - if(!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index)|| - (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index]))||\ - (priv->ieee80211->queue_stop) ) - { + memcpy(seg_ptr, code_virtual_address + frag_offset, + (u32)(frag_length-ExtraDescOffset)); + + tcb_desc->txbuf_size = frag_length; + + if (!priv->ieee80211->check_nic_enough_desc(dev, tcb_desc->queue_index) || + (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index])) || + (priv->ieee80211->queue_stop)) { RT_TRACE(COMP_FIRMWARE,"=====================================================> tx full!\n"); skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb); - } - else - { - priv->ieee80211->softmac_hard_start_xmit(skb,dev); - } + } else + priv->ieee80211->softmac_hard_start_xmit(skb, dev); frag_offset += (frag_length - ExtraDescOffset); - }while(frag_offset < buffer_len); - + } while (frag_offset < buffer_len); return rt_status ; - cmdsend_downloadcode_fail: rt_status = false; - RT_TRACE(COMP_ERR, "CmdSendDownloadCode fail !!\n"); + RT_TRACE(COMP_ERR, "(%s): failed\n", __func__); return rt_status; - } -RT_STATUS -FirmwareEnableCPU(struct net_device *dev) +RT_STATUS FirmwareEnableCPU(struct net_device *dev) { + RT_STATUS rtStatus = RT_STATUS_SUCCESS; + u8 tmpU1b, CPUStatus = 0; + u16 tmpU2b; + u32 iCheckTime = 200; - RT_STATUS rtStatus = RT_STATUS_SUCCESS; - u8 tmpU1b, CPUStatus = 0; - u16 tmpU2b; - u32 iCheckTime = 200; - - RT_TRACE(COMP_FIRMWARE, "-->FirmwareEnableCPU()\n" ); - // Enable CPU. + /* Enable CPU. */ tmpU1b = read_nic_byte(dev, SYS_CLKR); - write_nic_byte(dev, SYS_CLKR, (tmpU1b|SYS_CPU_CLKSEL)); //AFE source - + /* AFE source */ + write_nic_byte(dev, SYS_CLKR, (tmpU1b|SYS_CPU_CLKSEL)); tmpU2b = read_nic_word(dev, SYS_FUNC_EN); write_nic_word(dev, SYS_FUNC_EN, (tmpU2b|FEN_CPUEN)); - - //Polling IMEM Ready after CPU has refilled. - do - { + /* Poll IMEM Ready after CPU has refilled. */ + do { CPUStatus = read_nic_byte(dev, TCR); - if(CPUStatus& IMEM_RDY) - { - RT_TRACE(COMP_FIRMWARE, "IMEM Ready after CPU has refilled.\n"); + if (CPUStatus & IMEM_RDY) + /* success */ break; - } - - //usleep(100); udelay(100); - }while(iCheckTime--); - - if(!(CPUStatus & IMEM_RDY)) - return RT_STATUS_FAILURE; - - RT_TRACE(COMP_FIRMWARE, "<--FirmwareEnableCPU(): rtStatus(%#x)\n", rtStatus); + } while (iCheckTime--); + if (!(CPUStatus & IMEM_RDY)) { + RT_TRACE(COMP_ERR, "(%s): failed to enable CPU\n", __func__); + rtStatus = RT_STATUS_FAILURE; + } return rtStatus; } diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index efba60826adf..5696b00c89fb 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c @@ -1296,7 +1296,6 @@ static int rtl8192_rx_initiate(struct net_device*dev) kfree_skb(skb); break; } -// printk("nomal packet IN request!\n"); usb_fill_bulk_urb(entry, priv->udev, usb_rcvbulkpipe(priv->udev, 3), skb_tail_pointer(skb), RX_URB_SIZE, rtl8192_rx_isr, skb); @@ -1310,7 +1309,6 @@ static int rtl8192_rx_initiate(struct net_device*dev) /* command packet rx procedure */ while (skb_queue_len(&priv->rx_queue) < MAX_RX_URB + 3) { -// printk("command packet IN request!\n"); skb = __dev_alloc_skb(RX_URB_SIZE ,GFP_KERNEL); if (!skb) break; diff --git a/drivers/staging/rtl8192su/r819xU_cmdpkt.c b/drivers/staging/rtl8192su/r819xU_cmdpkt.c index 43b68a02d0c1..a8e9d2d96f5b 100644 --- a/drivers/staging/rtl8192su/r819xU_cmdpkt.c +++ b/drivers/staging/rtl8192su/r819xU_cmdpkt.c @@ -26,6 +26,12 @@ bool SendTxCommandPacket(struct net_device *dev, void *pData, u32 DataLen) * (It is shared by CmdQ, MgntQ, and USB coalesce DataQ) */ skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + DataLen + 4); + if (skb == NULL) { + RT_TRACE(COMP_ERR, "(%s): unable to alloc skb buffer\n", + __func__); + rtStatus = false; + return rtStatus; + } memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); tcb_desc->queue_index = TXCMD_QUEUE; -- cgit v1.2.3 From e695b470b30fbaf41d6aab0f9ed99be1ad4aa3af Mon Sep 17 00:00:00 2001 From: Florian Schilhabel Date: Tue, 4 May 2010 14:24:12 +0200 Subject: Staging: rtl8192su: refactored FirmwareCheckReady replaced if..else if..else by a switch. this is hopefully easier to read. plus cosmetics. Signed-off-by: Florian Schilhabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192su/r8192S_firmware.c | 140 +++++++++++++--------------- 1 file changed, 64 insertions(+), 76 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192su/r8192S_firmware.c b/drivers/staging/rtl8192su/r8192S_firmware.c index 37d164c0e928..5036d547d5d3 100644 --- a/drivers/staging/rtl8192su/r8192S_firmware.c +++ b/drivers/staging/rtl8192su/r8192S_firmware.c @@ -107,9 +107,9 @@ cmdsend_downloadcode_fail: } -RT_STATUS FirmwareEnableCPU(struct net_device *dev) +bool FirmwareEnableCPU(struct net_device *dev) { - RT_STATUS rtStatus = RT_STATUS_SUCCESS; + bool rtStatus = true; u8 tmpU1b, CPUStatus = 0; u16 tmpU2b; u32 iCheckTime = 200; @@ -129,8 +129,8 @@ RT_STATUS FirmwareEnableCPU(struct net_device *dev) udelay(100); } while (iCheckTime--); if (!(CPUStatus & IMEM_RDY)) { - RT_TRACE(COMP_ERR, "(%s): failed to enable CPU\n", __func__); - rtStatus = RT_STATUS_FAILURE; + RT_TRACE(COMP_ERR, "%s(): failed to enable CPU", __func__); + rtStatus = false; } return rtStatus; } @@ -165,106 +165,87 @@ FirmwareGetNextStatus(FIRMWARE_8192S_STATUS FWCurrentStatus) return NextFWStatus; } -bool -FirmwareCheckReady(struct net_device *dev, u8 LoadFWStatus) +bool FirmwareCheckReady(struct net_device *dev, u8 LoadFWStatus) { - struct r8192_priv *priv = ieee80211_priv(dev); - RT_STATUS rtStatus = RT_STATUS_SUCCESS; - rt_firmware *pFirmware = priv->pFirmware; - int PollingCnt = 1000; - //u8 tmpU1b, CPUStatus = 0; - u8 CPUStatus = 0; - u32 tmpU4b; - //bool bOrgIMREnable; - - RT_TRACE(COMP_FIRMWARE, "--->FirmwareCheckReady(): LoadStaus(%d),", LoadFWStatus); + struct r8192_priv *priv = ieee80211_priv(dev); + bool rtStatus = true; + rt_firmware *pFirmware = priv->pFirmware; + int PollingCnt = 1000; + u8 CPUStatus = 0; + u32 tmpU4b; pFirmware->FWStatus = (FIRMWARE_8192S_STATUS)LoadFWStatus; - if( LoadFWStatus == FW_STATUS_LOAD_IMEM) - { - do - {//Polling IMEM code done. + switch (LoadFWStatus) { + case FW_STATUS_LOAD_IMEM: + do { /* Polling IMEM code done. */ CPUStatus = read_nic_byte(dev, TCR); if(CPUStatus& IMEM_CODE_DONE) break; - udelay(5); - }while(PollingCnt--); - if(!(CPUStatus & IMEM_CHK_RPT) || PollingCnt <= 0) - { + } while (PollingCnt--); + if (!(CPUStatus & IMEM_CHK_RPT) || PollingCnt <= 0) { RT_TRACE(COMP_ERR, "FW_STATUS_LOAD_IMEM FAIL CPU, Status=%x\r\n", CPUStatus); - return false; + goto FirmwareCheckReadyFail; } - } - else if( LoadFWStatus == FW_STATUS_LOAD_EMEM) - {//Check Put Code OK and Turn On CPU - do - {//Polling EMEM code done. + break; + case FW_STATUS_LOAD_EMEM: /* Check Put Code OK and Turn On CPU */ + do { /* Polling EMEM code done. */ CPUStatus = read_nic_byte(dev, TCR); if(CPUStatus& EMEM_CODE_DONE) break; - udelay(5); - }while(PollingCnt--); - if(!(CPUStatus & EMEM_CHK_RPT)) - { + } while (PollingCnt--); + if (!(CPUStatus & EMEM_CHK_RPT)) { RT_TRACE(COMP_ERR, "FW_STATUS_LOAD_EMEM FAIL CPU, Status=%x\r\n", CPUStatus); - return false; + goto FirmwareCheckReadyFail; } - - // Turn On CPU - rtStatus = FirmwareEnableCPU(dev); - if(rtStatus != RT_STATUS_SUCCESS) - { - RT_TRACE(COMP_ERR, "Enable CPU fail ! \n" ); - return false; + /* Turn On CPU */ + if (FirmwareEnableCPU(dev) != true) { + RT_TRACE(COMP_ERR, "%s(): failed to enable CPU", + __func__); + goto FirmwareCheckReadyFail; } - } - else if( LoadFWStatus == FW_STATUS_LOAD_DMEM) - { - do - {//Polling DMEM code done + break; + case FW_STATUS_LOAD_DMEM: + do { /* Polling DMEM code done */ CPUStatus = read_nic_byte(dev, TCR); if(CPUStatus& DMEM_CODE_DONE) break; udelay(5); - }while(PollingCnt--); + } while (PollingCnt--); - if(!(CPUStatus & DMEM_CODE_DONE)) - { + if (!(CPUStatus & DMEM_CODE_DONE)) { RT_TRACE(COMP_ERR, "Polling DMEM code done fail ! CPUStatus(%#x)\n", CPUStatus); - return false; + goto FirmwareCheckReadyFail; } - RT_TRACE(COMP_FIRMWARE, "DMEM code download success, CPUStatus(%#x)\n", CPUStatus); + RT_TRACE(COMP_FIRMWARE, "%s(): DMEM code download success, " + "CPUStatus(%#x)", + __func__, CPUStatus); -// PollingCnt = 100; // Set polling cycle to 10ms. - PollingCnt = 10000; // Set polling cycle to 10ms. + PollingCnt = 10000; /* Set polling cycle to 10ms. */ - do - {//Polling Load Firmware ready + do { /* Polling Load Firmware ready */ CPUStatus = read_nic_byte(dev, TCR); if(CPUStatus & FWRDY) break; - udelay(100); - }while(PollingCnt--); + } while (PollingCnt--); - RT_TRACE(COMP_FIRMWARE, "Polling Load Firmware ready, CPUStatus(%x)\n", CPUStatus); + RT_TRACE(COMP_FIRMWARE, "%s(): polling load firmware ready, " + "CPUStatus(%x)", + __func__, CPUStatus); - //if(!(CPUStatus & LOAD_FW_READY)) - //if((CPUStatus & LOAD_FW_READY) != 0xff) - if((CPUStatus & LOAD_FW_READY) != LOAD_FW_READY) - { - RT_TRACE(COMP_ERR, "Polling Load Firmware ready fail ! CPUStatus(%x)\n", CPUStatus); - return false; + if ((CPUStatus & LOAD_FW_READY) != LOAD_FW_READY) { + RT_TRACE(COMP_ERR, "Polling Load Firmware ready failed " + "CPUStatus(%x)\n", CPUStatus); + goto FirmwareCheckReadyFail; } - - // - // USB interface will update reserved followings parameters later!! - // 2008.08.28. - // + /* + * USB interface will update + * reserved followings parameters later + */ // // If right here, we can set TCR/RCR to desired value @@ -277,16 +258,23 @@ FirmwareCheckReady(struct net_device *dev, u8 LoadFWStatus) write_nic_dword(dev, RCR, (tmpU4b|RCR_APPFCS|RCR_APP_ICV|RCR_APP_MIC)); - RT_TRACE(COMP_FIRMWARE, "FirmwareCheckReady(): Current RCR settings(%#x)\n", tmpU4b); - - + RT_TRACE(COMP_FIRMWARE, "%s(): Current RCR settings(%#x)", + __func__, tmpU4b); // Set to normal mode. write_nic_byte(dev, LBKMD_SEL, LBK_NORMAL); - + break; + default: + break; } + RT_TRACE(COMP_FIRMWARE, "%s(): LoadFWStatus(%d), success", + __func__, LoadFWStatus); + return rtStatus; - RT_TRACE(COMP_FIRMWARE, "<---FirmwareCheckReady(): LoadFWStatus(%d), rtStatus(%x)\n", LoadFWStatus, rtStatus); - return (rtStatus == RT_STATUS_SUCCESS) ? true:false; +FirmwareCheckReadyFail: + rtStatus = false; + RT_TRACE(COMP_FIRMWARE, "%s(): LoadFWStatus(%d), failed", + __func__, LoadFWStatus); + return rtStatus; } // -- cgit v1.2.3 From 495c57f5f0af9e6075e86f5fb2249d60bc8cdb34 Mon Sep 17 00:00:00 2001 From: Florian Schilhabel Date: Tue, 4 May 2010 14:24:35 +0200 Subject: Staging: rtl8192su: all rtl8192su chips have the 93c46 eprom all rtl8192su chips have the 93c46 eprom. (no 93c56) it it theoretically safe to remove the 93c56 definitions and some unneeded code. if your device stops working after this patch, please send me a mail and include some information about your device: * dmesg * lsusb -v * _exact_ chipset (version) * vendor * everything else, that may help plus cosmetics. Signed-off-by: Florian Schilhabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192su/r8192S_phy.c | 7 +- drivers/staging/rtl8192su/r8192U.h | 8 +- drivers/staging/rtl8192su/r8192U_core.c | 150 +++++++++----------------------- 3 files changed, 45 insertions(+), 120 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192su/r8192S_phy.c b/drivers/staging/rtl8192su/r8192S_phy.c index 83c8aaaccd60..69ede47dfdcc 100644 --- a/drivers/staging/rtl8192su/r8192S_phy.c +++ b/drivers/staging/rtl8192su/r8192S_phy.c @@ -1873,10 +1873,9 @@ PHY_GetTxPowerLevel8192S( if(priv->bTXPowerDataReadFromEEPORM == FALSE) return; - // - // Read predefined TX power index in EEPROM - // -// if(priv->epromtype == EPROM_93c46) + /* + * Read predefined TX power index in EEPROM + */ { // // Mainly we use RF-A Tx Power to write the Tx Power registers, but the RF-B Tx diff --git a/drivers/staging/rtl8192su/r8192U.h b/drivers/staging/rtl8192su/r8192U.h index 830625253293..4112e149a327 100644 --- a/drivers/staging/rtl8192su/r8192U.h +++ b/drivers/staging/rtl8192su/r8192U.h @@ -741,11 +741,6 @@ typedef enum _RTL8192SUSB_LOOPBACK{ #define RSVD_FW_QUEUE_PAGE_CMD_SHIFT 0x08 #define RSVD_FW_QUEUE_PAGE_BCN_SHIFT 0x00 #define RSVD_FW_QUEUE_PAGE_PUB_SHIFT 0x08 -//================================================================= -//================================================================= - -#define EPROM_93c46 0 -#define EPROM_93c56 1 #define DEFAULT_FRAG_THRESHOLD 2342U #define MIN_FRAG_THRESHOLD 256U @@ -1129,8 +1124,7 @@ typedef struct r8192_priv { struct rtl819x_ops* ops; struct usb_device *udev; - //added for maintain info from eeprom - short epromtype; + /* added for maintain info from eeprom */ u16 eeprom_vid; u16 eeprom_pid; u8 eeprom_CustomerID; diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index 5696b00c89fb..d372ff22a0d3 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c @@ -3309,18 +3309,6 @@ static void rtl8192_init_priv_task(struct net_device* dev) (unsigned long)priv); } -static void rtl8192_get_eeprom_size(struct net_device* dev) -{ - u16 curCR = 0; - struct r8192_priv *priv = ieee80211_priv(dev); - RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__); - curCR = read_nic_word_E(dev,EPROM_CMD); - RT_TRACE(COMP_EPROM, "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR); - //whether need I consider BIT5? - priv->epromtype = (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46; - RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype); -} - //used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead. static inline u16 endian_swap(u16* data) { @@ -3523,46 +3511,40 @@ void rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device *dev) RT_TRACE(COMP_INIT, "<==== ConfigAdapterInfo8192SForAutoLoadFail\n"); } -// -// Description: -// Read HW adapter information by E-Fuse or EEPROM according CR9346 reported. -// -// Assumption: -// 1. CR9346 regiser has verified. -// 2. PASSIVE_LEVEL (USB interface) -// -// Created by Roger, 2008.10.21. -// -void rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev) +/* + * Description: + * Read HW adapter information by E-Fuse + * or EEPROM according CR9346 reported. + * + * Assumption: + * 1. CR9346 regiser has verified. + * 2. PASSIVE_LEVEL (USB interface) + */ +void rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); u16 i; u8 tmpU1b, tempval; u16 EEPROMId; u8 hwinfo[HWSET_MAX_SIZE_92S]; - u8 rf_path, index; // For EEPROM/EFUSE After V0.6_1117 + u8 rf_path, index; /* For EEPROM/EFUSE After V0.6_1117 */ struct eeprom_93cx6 eeprom; u16 eeprom_val; eeprom.data = dev; eeprom.register_read = rtl819x_eeprom_register_read; eeprom.register_write = rtl819x_eeprom_register_write; - if (priv->epromtype == EPROM_93c46) - eeprom.width = PCI_EEPROM_WIDTH_93C46; - else - eeprom.width = PCI_EEPROM_WIDTH_93C56; - - RT_TRACE(COMP_INIT, "====> ReadAdapterInfo8192SUsb\n"); + eeprom.width = PCI_EEPROM_WIDTH_93C46; /* - * The following operation are prevent Efuse leakage by turn on 2.5V.. + * The following operation are prevent Efuse leakage by turn on 2.5V. */ tmpU1b = read_nic_byte(dev, EFUSE_TEST+3); write_nic_byte(dev, EFUSE_TEST+3, tmpU1b|0x80); mdelay(10); write_nic_byte(dev, EFUSE_TEST+3, (tmpU1b&(~BIT7))); - // Retrieve Chip version. + /* Retrieve Chip version. */ priv->card_8192_version = (VERSION_8192S)((read_nic_dword(dev, PMC_FSM)>>16)&0xF); RT_TRACE(COMP_INIT, "Chip Version ID: 0x%2x\n", priv->card_8192_version); @@ -3582,103 +3564,59 @@ void rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev) break; } - //if (IS_BOOT_FROM_EEPROM(Adapter)) - if(priv->EepromOrEfuse) - { // Read frin EEPROM - write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader - //PlatformStallExecution(10000); + if (priv->EepromOrEfuse) { /* Read from EEPROM */ + /* Isolation signals from Loader */ + write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8); mdelay(10); - write_nic_byte(dev, PMC_FSM, 0x02); // Enable Loader Data Keep - // Read all Content from EEPROM or EFUSE. - for(i = 0; i < HWSET_MAX_SIZE_92S; i += 2) - { + /* Enable Loader Data Keep */ + write_nic_byte(dev, PMC_FSM, 0x02); + /* Read all Content from EEPROM or EFUSE. */ + for (i = 0; i < HWSET_MAX_SIZE_92S; i += 2) { eeprom_93cx6_read(&eeprom, (u16) (i>>1), &eeprom_val); *((u16 *)(&hwinfo[i])) = eeprom_val; } - } - else if (!(priv->EepromOrEfuse)) - { // Read from EFUSE - - // - // We set Isolation signals from Loader and reset EEPROM after system resuming - // from suspend mode. - // 2008.10.21. - // - //PlatformEFIOWrite1Byte(Adapter, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader - //PlatformStallExecution(10000); - //PlatformEFIOWrite1Byte(Adapter, SYS_FUNC_EN+1, 0x40); - //PlatformEFIOWrite1Byte(Adapter, SYS_FUNC_EN+1, 0x50); - - //tmpU1b = PlatformEFIORead1Byte(Adapter, EFUSE_TEST+3); - //PlatformEFIOWrite1Byte(Adapter, EFUSE_TEST+3, (tmpU1b | 0x80)); - //PlatformEFIOWrite1Byte(Adapter, EFUSE_TEST+3, 0x72); - //PlatformEFIOWrite1Byte(Adapter, EFUSE_CLK, 0x03); - - // Read EFUSE real map to shadow. + } else if (!(priv->EepromOrEfuse)) { /* Read from EFUSE */ + /* Read EFUSE real map to shadow. */ EFUSE_ShadowMapUpdate(dev); memcpy(hwinfo, &priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S); + } else { + RT_TRACE(COMP_INIT, "%s(): Invalid boot type", __func__); } - else - { - RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SUsb(): Invalid boot type!!\n"); - } - - //YJ,test,090106 - //dump_buf(hwinfo,HWSET_MAX_SIZE_92S); - // - // The following are EFUSE/EEPROM independent operations!! - // - //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("MAP: \n"), hwinfo, HWSET_MAX_SIZE_92S); - // - // Event though CR9346 regiser can verify whether Autoload is success or not, but we still - // double check ID codes for 92S here(e.g., due to HW GPIO polling fail issue). - // 2008.10.21. - // + /* + * Even though CR9346 regiser can verify whether Autoload + * is success or not, but we still double check ID codes for 92S here + * (e.g., due to HW GPIO polling fail issue) + */ EEPROMId = *((u16 *)&hwinfo[0]); - - if( EEPROMId != RTL8190_EEPROM_ID ) - { + if (EEPROMId != RTL8190_EEPROM_ID) { RT_TRACE(COMP_INIT, "ID(%#x) is invalid!!\n", EEPROMId); priv->bTXPowerDataReadFromEEPORM = FALSE; priv->AutoloadFailFlag=TRUE; - } - else - { + } else { priv->AutoloadFailFlag=FALSE; priv->bTXPowerDataReadFromEEPORM = TRUE; } - // Read IC Version && Channel Plan - if(!priv->AutoloadFailFlag) - { - // VID, PID + /* Read IC Version && Channel Plan */ + if (!priv->AutoloadFailFlag) { + /* VID, PID */ priv->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID]; priv->eeprom_pid = *(u16 *)&hwinfo[EEPROM_PID]; priv->bIgnoreDiffRateTxPowerOffset = false; //cosa for test - // EEPROM Version ID, Channel plan + /* EEPROM Version ID, Channel plan */ priv->EEPROMVersion = *(u8 *)&hwinfo[EEPROM_Version]; priv->eeprom_ChannelPlan = *(u8 *)&hwinfo[EEPROM_ChannelPlan]; - // Customer ID, 0x00 and 0xff are reserved for Realtek. + /* Customer ID, 0x00 and 0xff are reserved for Realtek. */ priv->eeprom_CustomerID = *(u8 *)&hwinfo[EEPROM_CustomID]; priv->eeprom_SubCustomerID = *(u8 *)&hwinfo[EEPROM_SubCustomID]; - } - else - { - //priv->eeprom_vid = 0; - //priv->eeprom_pid = 0; - //priv->EEPROMVersion = 0; - //priv->eeprom_ChannelPlan = 0; - //priv->eeprom_CustomerID = 0; - //priv->eeprom_SubCustomerID = 0; - + } else { rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(dev); return; } - RT_TRACE(COMP_INIT, "EEPROM Id = 0x%4x\n", EEPROMId); RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid); RT_TRACE(COMP_INIT, "EEPROM PID = 0x%4x\n", priv->eeprom_pid); @@ -3688,18 +3626,13 @@ void rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev) RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n", priv->eeprom_ChannelPlan); RT_TRACE(COMP_INIT, "bIgnoreDiffRateTxPowerOffset = %d\n", priv->bIgnoreDiffRateTxPowerOffset); - - // Read USB optional function. - if(!priv->AutoloadFailFlag) - { + /* Read USB optional function. */ + if (!priv->AutoloadFailFlag) { priv->EEPROMUsbOption = *(u8 *)&hwinfo[EEPROM_USB_OPTIONAL]; - } - else - { + } else { priv->EEPROMUsbOption = EEPROM_USB_Default_OPTIONAL_FUNC; } - priv->EEPROMUsbEndPointNumber = rtl8192SU_UsbOptionToEndPointNumber((priv->EEPROMUsbOption&EEPROM_EP_NUMBER)>>3); RT_TRACE(COMP_INIT, "USB Option = %#x\n", priv->EEPROMUsbOption); @@ -4138,7 +4071,6 @@ short rtl8192_init(struct net_device *dev) rtl8192_init_priv_variable(dev); rtl8192_init_priv_lock(priv); rtl8192_init_priv_task(dev); - rtl8192_get_eeprom_size(dev); priv->ops->rtl819x_read_eeprom_info(dev); rtl8192_get_channel_map(dev); init_hal_dm(dev); -- cgit v1.2.3 From ad313b1062f0e16e5fa64e1a34eec37e1b8a3341 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 14:42:56 +0100 Subject: staging:iio: Add new in_raw definitions for adc channels. Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/adc.h | 12 ++++++++++++ drivers/staging/iio/sysfs.h | 3 +++ 2 files changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/adc.h b/drivers/staging/iio/adc/adc.h index d925b2c5e38e..46f0d08b4769 100644 --- a/drivers/staging/iio/adc/adc.h +++ b/drivers/staging/iio/adc/adc.h @@ -9,5 +9,17 @@ * */ +/* Deprecated */ #define IIO_DEV_ATTR_ADC(_num, _show, _addr) \ IIO_DEVICE_ATTR(adc_##_num, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_IN_RAW(_num, _show, _addr) \ + IIO_DEVICE_ATTR(in##_num##_raw, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_IN_DIFF_RAW(_nump, _numn, _show, _addr) \ + IIO_DEVICE_ATTR_NAMED(in##_nump##min##_numn##_raw, \ + in##_nump-in##_numn##_raw, \ + S_IRUGO, \ + _show, \ + NULL, \ + _addr) diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h index e501e1338e11..d8fe0e276036 100644 --- a/drivers/staging/iio/sysfs.h +++ b/drivers/staging/iio/sysfs.h @@ -98,6 +98,9 @@ struct iio_const_attr { struct iio_dev_attr iio_dev_attr_##_name \ = IIO_ATTR(_name, _mode, _show, _store, _addr) +#define IIO_DEVICE_ATTR_NAMED(_vname, _name, _mode, _show, _store, _addr) \ + struct iio_dev_attr iio_dev_attr_##_vname \ + = IIO_ATTR(_name, _mode, _show, _store, _addr) #define IIO_DEVICE_ATTR_2(_name, _mode, _show, _store, _addr, _val2) \ struct iio_dev_attr iio_dev_attr_##_name \ -- cgit v1.2.3 From ff7723e203349c18d7149e7cf2a4ae928bb9da69 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 14:42:57 +0100 Subject: staging:iio: Add new attrs for sampling frequency available and temp_raw Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/sysfs.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h index d8fe0e276036..afcf5ab85f48 100644 --- a/drivers/staging/iio/sysfs.h +++ b/drivers/staging/iio/sysfs.h @@ -144,18 +144,25 @@ struct iio_const_attr { * * May be mode dependent on some devices **/ +/* Deprecated */ #define IIO_DEV_ATTR_AVAIL_SAMP_FREQ(_show) \ IIO_DEVICE_ATTR(available_sampling_frequency, S_IRUGO, _show, NULL, 0) +#define IIO_DEV_ATTR_SAMP_FREQ_AVAIL(_show) \ + IIO_DEVICE_ATTR(sampling_frequency_available, S_IRUGO, _show, NULL, 0) /** * IIO_CONST_ATTR_AVAIL_SAMP_FREQ - list available sampling frequencies * @_string: frequency string for the attribute * * Constant version **/ -#define IIO_CONST_ATTR_AVAIL_SAMP_FREQ(_string) \ +/* Deprecated */ +#define IIO_CONST_ATTR_AVAIL_SAMP_FREQ(_string) \ IIO_CONST_ATTR(available_sampling_frequency, _string) +#define IIO_CONST_ATTR_SAMP_FREQ_AVAIL(_string) \ + IIO_CONST_ATTR(sampling_frequency_available, _string) + /** * IIO_DEV_ATTR_SCAN_MODE - select a scan mode * @_mode: sysfs file mode/permissions @@ -234,6 +241,9 @@ struct iio_const_attr { #define IIO_DEV_ATTR_TEMP(_show) \ IIO_DEVICE_ATTR(temp, S_IRUGO, _show, NULL, 0) +#define IIO_DEV_ATTR_TEMP_RAW(_show) \ + IIO_DEVICE_ATTR(temp_raw, S_IRUGO, _show, NULL, 0) + /** * IIO_EVENT_SH - generic shared event handler * @_name: event name -- cgit v1.2.3 From f3fb001191a38a81bbc3cb363af2c279609ecc7c Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 14:42:58 +0100 Subject: iio:staging:accelerometers move towards the new abi Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/accel.h | 8 +- drivers/staging/iio/accel/kxsd9.c | 88 +++++++++------ drivers/staging/iio/accel/lis3l02dq.h | 4 - drivers/staging/iio/accel/lis3l02dq_core.c | 175 +++++++++++++++-------------- drivers/staging/iio/accel/lis3l02dq_ring.c | 8 +- drivers/staging/iio/accel/sca3000.h | 2 + drivers/staging/iio/accel/sca3000_core.c | 172 ++++++++++++++-------------- drivers/staging/iio/accel/sca3000_ring.c | 33 ++++-- drivers/staging/iio/ring_generic.h | 4 +- 9 files changed, 262 insertions(+), 232 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/accel.h b/drivers/staging/iio/accel/accel.h index d7fc7f98348e..059209c9e339 100644 --- a/drivers/staging/iio/accel/accel.h +++ b/drivers/staging/iio/accel/accel.h @@ -2,7 +2,6 @@ #include "../sysfs.h" /* Accelerometer types of attribute */ - #define IIO_DEV_ATTR_ACCEL_X_OFFSET(_mode, _show, _store, _addr) \ IIO_DEVICE_ATTR(accel_x_offset, _mode, _show, _store, _addr) @@ -22,13 +21,13 @@ IIO_DEVICE_ATTR(accel_z_gain, _mode, _show, _store, _addr) #define IIO_DEV_ATTR_ACCEL_X(_show, _addr) \ - IIO_DEVICE_ATTR(accel_x, S_IRUGO, _show, NULL, _addr) + IIO_DEVICE_ATTR(accel_x_raw, S_IRUGO, _show, NULL, _addr) #define IIO_DEV_ATTR_ACCEL_Y(_show, _addr) \ - IIO_DEVICE_ATTR(accel_y, S_IRUGO, _show, NULL, _addr) + IIO_DEVICE_ATTR(accel_y_raw, S_IRUGO, _show, NULL, _addr) #define IIO_DEV_ATTR_ACCEL_Z(_show, _addr) \ - IIO_DEVICE_ATTR(accel_z, S_IRUGO, _show, NULL, _addr) + IIO_DEVICE_ATTR(accel_z_raw, S_IRUGO, _show, NULL, _addr) /* Thresholds are somewhat chip dependent - may need quite a few defs here */ /* For unified thresholds (shared across all directions */ @@ -61,7 +60,6 @@ #define IIO_DEV_ATTR_ACCEL_THRESH_Z(_mode, _show, _store, _addr) \ IIO_DEVICE_ATTR(thresh_accel_z, _mode, _show, _store, _addr) - /** * IIO_EVENT_ATTR_ACCEL_X_HIGH: threshold event, x acceleration * @_show: read x acceleration high threshold diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c index db2dd537ffb0..ae7ffe114fc5 100644 --- a/drivers/staging/iio/accel/kxsd9.c +++ b/drivers/staging/iio/accel/kxsd9.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "../iio.h" #include "../sysfs.h" @@ -51,8 +52,10 @@ #define KXSD9_READ(a) (0x80 | (a)) #define KXSD9_WRITE(a) (a) -#define IIO_DEV_ATTR_ACCEL_SET_RANGE(_mode, _show, _store) \ - IIO_DEVICE_ATTR(accel_range, _mode, _show, _store, 0) +#define KXSD9_SCALE_2G "0.011978" +#define KXSD9_SCALE_4G "0.023927" +#define KXSD9_SCALE_6G "0.035934" +#define KXSD9_SCALE_8G "0.047853" #define KXSD9_STATE_RX_SIZE 2 #define KXSD9_STATE_TX_SIZE 4 @@ -73,9 +76,9 @@ struct kxsd9_state { }; /* This may want to move to mili g to allow for non integer ranges */ -static ssize_t kxsd9_read_accel_range(struct device *dev, - struct device_attribute *attr, - char *buf) +static ssize_t kxsd9_read_scale(struct device *dev, + struct device_attribute *attr, + char *buf) { int ret; ssize_t len = 0; @@ -101,16 +104,16 @@ static ssize_t kxsd9_read_accel_range(struct device *dev, switch (st->rx[1] & KXSD9_FS_MASK) { case KXSD9_FS_8: - len += sprintf(buf, "8\n"); + len += sprintf(buf, "%s\n", KXSD9_SCALE_8G); break; case KXSD9_FS_6: - len += sprintf(buf, "6\n"); + len += sprintf(buf, "%s\n", KXSD9_SCALE_6G); break; case KXSD9_FS_4: - len += sprintf(buf, "4\n"); + len += sprintf(buf, "%s\n", KXSD9_SCALE_4G); break; case KXSD9_FS_2: - len += sprintf(buf, "2\n"); + len += sprintf(buf, "%s\n", KXSD9_SCALE_2G); break; } @@ -119,12 +122,12 @@ error_ret: return ret ? ret : len; } -static ssize_t kxsd9_write_accel_range(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) +static ssize_t kxsd9_write_scale(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) { - long readin; + struct spi_message msg; int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); @@ -145,25 +148,25 @@ static ssize_t kxsd9_write_accel_range(struct device *dev, }, }; - ret = strict_strtol(buf, 10, &readin); - if (ret) - return ret; - switch (readin) { - case 8: + if (!strncmp(buf, KXSD9_SCALE_8G, + strlen(buf) < strlen(KXSD9_SCALE_8G) + ? strlen(buf) : strlen(KXSD9_SCALE_8G))) val = KXSD9_FS_8; - break; - case 6: + else if (!strncmp(buf, KXSD9_SCALE_6G, + strlen(buf) < strlen(KXSD9_SCALE_6G) + ? strlen(buf) : strlen(KXSD9_SCALE_6G))) val = KXSD9_FS_6; - break; - case 4: + else if (!strncmp(buf, KXSD9_SCALE_4G, + strlen(buf) < strlen(KXSD9_SCALE_4G) + ? strlen(buf) : strlen(KXSD9_SCALE_4G))) val = KXSD9_FS_4; - break; - case 2: + else if (!strncmp(buf, KXSD9_SCALE_2G, + strlen(buf) < strlen(KXSD9_SCALE_2G) + ? strlen(buf) : strlen(KXSD9_SCALE_2G))) val = KXSD9_FS_2; - break; - default: + else return -EINVAL; - } + mutex_lock(&st->buf_lock); st->tx[0] = KXSD9_READ(KXSD9_REG_CTRL_C); st->tx[1] = 0; @@ -182,6 +185,7 @@ error_ret: mutex_unlock(&st->buf_lock); return ret ? ret : len; } + static ssize_t kxsd9_read_accel(struct device *dev, struct device_attribute *attr, char *buf) @@ -227,17 +231,27 @@ error_ret: static IIO_DEV_ATTR_ACCEL_X(kxsd9_read_accel, KXSD9_REG_X); static IIO_DEV_ATTR_ACCEL_Y(kxsd9_read_accel, KXSD9_REG_Y); static IIO_DEV_ATTR_ACCEL_Z(kxsd9_read_accel, KXSD9_REG_Z); -static IIO_DEV_ATTR_ADC(0, kxsd9_read_accel, KXSD9_REG_AUX); -static IIO_DEV_ATTR_ACCEL_SET_RANGE(S_IRUGO | S_IWUSR, - kxsd9_read_accel_range, - kxsd9_write_accel_range); +static IIO_DEV_ATTR_IN_RAW(0, kxsd9_read_accel, KXSD9_REG_AUX); + +static IIO_DEVICE_ATTR(accel_scale, + S_IRUGO | S_IWUSR, + kxsd9_read_scale, + kxsd9_write_scale, + 0); + +static IIO_CONST_ATTR(accel_scale_available, + KXSD9_SCALE_2G " " + KXSD9_SCALE_4G " " + KXSD9_SCALE_6G " " + KXSD9_SCALE_8G); static struct attribute *kxsd9_attributes[] = { - &iio_dev_attr_accel_x.dev_attr.attr, - &iio_dev_attr_accel_y.dev_attr.attr, - &iio_dev_attr_accel_z.dev_attr.attr, - &iio_dev_attr_adc_0.dev_attr.attr, - &iio_dev_attr_accel_range.dev_attr.attr, + &iio_dev_attr_accel_x_raw.dev_attr.attr, + &iio_dev_attr_accel_y_raw.dev_attr.attr, + &iio_dev_attr_accel_z_raw.dev_attr.attr, + &iio_dev_attr_in0_raw.dev_attr.attr, + &iio_dev_attr_accel_scale.dev_attr.attr, + &iio_const_attr_accel_scale_available.dev_attr.attr, NULL, }; diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h index 91a5375408c2..e76a97937a36 100644 --- a/drivers/staging/iio/accel/lis3l02dq.h +++ b/drivers/staging/iio/accel/lis3l02dq.h @@ -179,10 +179,6 @@ int lis3l02dq_spi_read_reg_8(struct device *dev, int lis3l02dq_spi_write_reg_8(struct device *dev, u8 reg_address, u8 *val); -#define LIS3L02DQ_SCAN_ACC_X 0 -#define LIS3L02DQ_SCAN_ACC_Y 1 -#define LIS3L02DQ_SCAN_ACC_Z 2 - #ifdef CONFIG_IIO_RING_BUFFER /* At the moment triggers are only used for ring buffer diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index ea76902797bb..6b5577d7d8de 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -458,41 +458,39 @@ err_ret: return ret; } -static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO, - lis3l02dq_read_signed, - lis3l02dq_write_signed, - LIS3L02DQ_REG_OFFSET_X_ADDR); - -static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO, - lis3l02dq_read_signed, - lis3l02dq_write_signed, - LIS3L02DQ_REG_OFFSET_Y_ADDR); - -static IIO_DEV_ATTR_ACCEL_Z_OFFSET(S_IWUSR | S_IRUGO, - lis3l02dq_read_signed, - lis3l02dq_write_signed, - LIS3L02DQ_REG_OFFSET_Z_ADDR); - -static IIO_DEV_ATTR_ACCEL_X_GAIN(S_IWUSR | S_IRUGO, - lis3l02dq_read_unsigned, - lis3l02dq_write_unsigned, - LIS3L02DQ_REG_GAIN_X_ADDR); - -static IIO_DEV_ATTR_ACCEL_Y_GAIN(S_IWUSR | S_IRUGO, - lis3l02dq_read_unsigned, - lis3l02dq_write_unsigned, - LIS3L02DQ_REG_GAIN_Y_ADDR); - -static IIO_DEV_ATTR_ACCEL_Z_GAIN(S_IWUSR | S_IRUGO, - lis3l02dq_read_unsigned, - lis3l02dq_write_unsigned, - LIS3L02DQ_REG_GAIN_Z_ADDR); - -static IIO_DEV_ATTR_ACCEL_THRESH(S_IWUSR | S_IRUGO, - lis3l02dq_read_16bit_signed, - lis3l02dq_write_16bit_signed, - LIS3L02DQ_REG_THS_L_ADDR); - +#define LIS3L02DQ_SIGNED_ATTR(name, reg) \ + IIO_DEVICE_ATTR(name, \ + S_IWUSR | S_IRUGO, \ + lis3l02dq_read_signed, \ + lis3l02dq_write_signed, \ + reg); + +#define LIS3L02DQ_UNSIGNED_ATTR(name, reg) \ + IIO_DEVICE_ATTR(name, \ + S_IWUSR | S_IRUGO, \ + lis3l02dq_read_unsigned, \ + lis3l02dq_write_unsigned, \ + reg); + +static LIS3L02DQ_SIGNED_ATTR(accel_x_calibbias, + LIS3L02DQ_REG_OFFSET_X_ADDR); +static LIS3L02DQ_SIGNED_ATTR(accel_y_calibbias, + LIS3L02DQ_REG_OFFSET_Y_ADDR); +static LIS3L02DQ_SIGNED_ATTR(accel_z_calibbias, + LIS3L02DQ_REG_OFFSET_Z_ADDR); + +static LIS3L02DQ_UNSIGNED_ATTR(accel_x_calibscale, + LIS3L02DQ_REG_GAIN_X_ADDR); +static LIS3L02DQ_UNSIGNED_ATTR(accel_y_calibscale, + LIS3L02DQ_REG_GAIN_Y_ADDR); +static LIS3L02DQ_UNSIGNED_ATTR(accel_z_calibscale, + LIS3L02DQ_REG_GAIN_Z_ADDR); + +static IIO_DEVICE_ATTR(accel_mag_either_rising_value, + S_IWUSR | S_IRUGO, + lis3l02dq_read_16bit_signed, + lis3l02dq_write_16bit_signed, + LIS3L02DQ_REG_THS_L_ADDR); /* RFC The reading method for these will change depending on whether * ring buffer capture is in use. Is it worth making these take two * functions and let the core handle which to call, or leave as in this @@ -512,7 +510,7 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, lis3l02dq_read_frequency, lis3l02dq_write_frequency); -static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("280 560 1120 4480"); +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("280 560 1120 4480"); static ssize_t lis3l02dq_read_interrupt_config(struct device *dev, struct device_attribute *attr, @@ -522,7 +520,7 @@ static ssize_t lis3l02dq_read_interrupt_config(struct device *dev, s8 val; struct iio_event_attr *this_attr = to_iio_event_attr(attr); - ret = lis3l02dq_spi_read_reg_8(dev, + ret = lis3l02dq_spi_read_reg_8(dev->parent, LIS3L02DQ_REG_WAKE_UP_CFG_ADDR, (u8 *)&val); @@ -545,7 +543,7 @@ static ssize_t lis3l02dq_write_interrupt_config(struct device *dev, mutex_lock(&indio_dev->mlock); /* read current value */ - ret = lis3l02dq_spi_read_reg_8(dev, + ret = lis3l02dq_spi_read_reg_8(dev->parent, LIS3L02DQ_REG_WAKE_UP_CFG_ADDR, &valold); if (ret) @@ -618,7 +616,7 @@ static int lis3l02dq_thresh_handler_th(struct iio_dev *dev_info, static void lis3l02dq_thresh_handler_bh_no_check(struct work_struct *work_s) { struct iio_work_cont *wc - = container_of(work_s, struct iio_work_cont, ws_nocheck); + = container_of(work_s, struct iio_work_cont, ws); struct lis3l02dq_state *st = wc->st; u8 t; @@ -668,43 +666,51 @@ static void lis3l02dq_thresh_handler_bh_no_check(struct work_struct *work_s) /* A shared handler for a number of threshold types */ IIO_EVENT_SH(threshold, &lis3l02dq_thresh_handler_th); -IIO_EVENT_ATTR_ACCEL_X_HIGH_SH(iio_event_threshold, - lis3l02dq_read_interrupt_config, - lis3l02dq_write_interrupt_config, - LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_HIGH); - -IIO_EVENT_ATTR_ACCEL_Y_HIGH_SH(iio_event_threshold, - lis3l02dq_read_interrupt_config, - lis3l02dq_write_interrupt_config, - LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_HIGH); - -IIO_EVENT_ATTR_ACCEL_Z_HIGH_SH(iio_event_threshold, - lis3l02dq_read_interrupt_config, - lis3l02dq_write_interrupt_config, - LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_HIGH); - -IIO_EVENT_ATTR_ACCEL_X_LOW_SH(iio_event_threshold, - lis3l02dq_read_interrupt_config, - lis3l02dq_write_interrupt_config, - LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_LOW); - -IIO_EVENT_ATTR_ACCEL_Y_LOW_SH(iio_event_threshold, - lis3l02dq_read_interrupt_config, - lis3l02dq_write_interrupt_config, - LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_LOW); +IIO_EVENT_ATTR_SH(accel_x_mag_pos_rising_en, + iio_event_threshold, + lis3l02dq_read_interrupt_config, + lis3l02dq_write_interrupt_config, + LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_HIGH); + +IIO_EVENT_ATTR_SH(accel_y_mag_pos_rising_en, + iio_event_threshold, + lis3l02dq_read_interrupt_config, + lis3l02dq_write_interrupt_config, + LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_HIGH); + +IIO_EVENT_ATTR_SH(accel_z_mag_pos_rising_en, + iio_event_threshold, + lis3l02dq_read_interrupt_config, + lis3l02dq_write_interrupt_config, + LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_HIGH); + +IIO_EVENT_ATTR_SH(accel_x_mag_neg_rising_en, + iio_event_threshold, + lis3l02dq_read_interrupt_config, + lis3l02dq_write_interrupt_config, + LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_LOW); + +IIO_EVENT_ATTR_SH(accel_y_mag_neg_rising_en, + iio_event_threshold, + lis3l02dq_read_interrupt_config, + lis3l02dq_write_interrupt_config, + LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_LOW); + +IIO_EVENT_ATTR_SH(accel_z_mag_neg_rising_en, + iio_event_threshold, + lis3l02dq_read_interrupt_config, + lis3l02dq_write_interrupt_config, + LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_LOW); -IIO_EVENT_ATTR_ACCEL_Z_LOW_SH(iio_event_threshold, - lis3l02dq_read_interrupt_config, - lis3l02dq_write_interrupt_config, - LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_LOW); static struct attribute *lis3l02dq_event_attributes[] = { - &iio_event_attr_accel_x_high.dev_attr.attr, - &iio_event_attr_accel_y_high.dev_attr.attr, - &iio_event_attr_accel_z_high.dev_attr.attr, - &iio_event_attr_accel_x_low.dev_attr.attr, - &iio_event_attr_accel_y_low.dev_attr.attr, - &iio_event_attr_accel_z_low.dev_attr.attr, + &iio_event_attr_accel_x_mag_pos_rising_en.dev_attr.attr, + &iio_event_attr_accel_y_mag_pos_rising_en.dev_attr.attr, + &iio_event_attr_accel_z_mag_pos_rising_en.dev_attr.attr, + &iio_event_attr_accel_x_mag_neg_rising_en.dev_attr.attr, + &iio_event_attr_accel_y_mag_neg_rising_en.dev_attr.attr, + &iio_event_attr_accel_z_mag_neg_rising_en.dev_attr.attr, + &iio_dev_attr_accel_mag_either_rising_value.dev_attr.attr, NULL }; @@ -713,20 +719,21 @@ static struct attribute_group lis3l02dq_event_attribute_group = { }; static IIO_CONST_ATTR(name, "lis3l02dq"); +static IIO_CONST_ATTR(accel_scale, "0.00958"); static struct attribute *lis3l02dq_attributes[] = { - &iio_dev_attr_accel_x_offset.dev_attr.attr, - &iio_dev_attr_accel_y_offset.dev_attr.attr, - &iio_dev_attr_accel_z_offset.dev_attr.attr, - &iio_dev_attr_accel_x_gain.dev_attr.attr, - &iio_dev_attr_accel_y_gain.dev_attr.attr, - &iio_dev_attr_accel_z_gain.dev_attr.attr, - &iio_dev_attr_thresh.dev_attr.attr, - &iio_dev_attr_accel_x.dev_attr.attr, - &iio_dev_attr_accel_y.dev_attr.attr, - &iio_dev_attr_accel_z.dev_attr.attr, + &iio_dev_attr_accel_x_calibbias.dev_attr.attr, + &iio_dev_attr_accel_y_calibbias.dev_attr.attr, + &iio_dev_attr_accel_z_calibbias.dev_attr.attr, + &iio_dev_attr_accel_x_calibscale.dev_attr.attr, + &iio_dev_attr_accel_y_calibscale.dev_attr.attr, + &iio_dev_attr_accel_z_calibscale.dev_attr.attr, + &iio_const_attr_accel_scale.dev_attr.attr, + &iio_dev_attr_accel_x_raw.dev_attr.attr, + &iio_dev_attr_accel_y_raw.dev_attr.attr, + &iio_dev_attr_accel_z_raw.dev_attr.attr, &iio_dev_attr_sampling_frequency.dev_attr.attr, - &iio_const_attr_available_sampling_frequency.dev_attr.attr, + &iio_const_attr_sampling_frequency_available.dev_attr.attr, &iio_const_attr_name.dev_attr.attr, NULL }; diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 93712430e579..bba4b0925ace 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -75,16 +75,16 @@ error_ret: return ret; } -static IIO_SCAN_EL_C(accel_x, LIS3L02DQ_SCAN_ACC_X, IIO_SIGNED(16), +static IIO_SCAN_EL_C(accel_x, 0, IIO_SIGNED(16), LIS3L02DQ_REG_OUT_X_L_ADDR, &lis3l02dq_scan_el_set_state); -static IIO_SCAN_EL_C(accel_y, LIS3L02DQ_SCAN_ACC_Y, IIO_SIGNED(16), +static IIO_SCAN_EL_C(accel_y, 1, IIO_SIGNED(16), LIS3L02DQ_REG_OUT_Y_L_ADDR, &lis3l02dq_scan_el_set_state); -static IIO_SCAN_EL_C(accel_z, LIS3L02DQ_SCAN_ACC_Z, IIO_SIGNED(16), +static IIO_SCAN_EL_C(accel_z, 2, IIO_SIGNED(16), LIS3L02DQ_REG_OUT_Z_L_ADDR, &lis3l02dq_scan_el_set_state); -static IIO_SCAN_EL_TIMESTAMP; +static IIO_SCAN_EL_TIMESTAMP(3); static struct attribute *lis3l02dq_scan_el_attrs[] = { &iio_scan_el_accel_x.dev_attr.attr, diff --git a/drivers/staging/iio/accel/sca3000.h b/drivers/staging/iio/accel/sca3000.h index da7d3cb5ae71..e5321999b263 100644 --- a/drivers/staging/iio/accel/sca3000.h +++ b/drivers/staging/iio/accel/sca3000.h @@ -187,6 +187,7 @@ struct sca3000_state { /** * struct sca3000_chip_info - model dependant parameters * @name: model identification + * @scale: string containing floating point scale factor * @temp_output: some devices have temperature sensors. * @measurement_mode_freq: normal mode sampling frequency * @option_mode_1: first optional mode. Not all models have one @@ -199,6 +200,7 @@ struct sca3000_state { **/ struct sca3000_chip_info { const char *name; + const char *scale; bool temp_output; int measurement_mode_freq; int option_mode_1; diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index 1c229869a22d..45e47776d913 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -27,11 +27,9 @@ enum sca3000_variant { d01, - d03, e02, e04, e05, - l01, }; /* Note where option modes are not defined, the chip simply does not @@ -44,21 +42,20 @@ enum sca3000_variant { static const struct sca3000_chip_info sca3000_spi_chip_info_tbl[] = { { .name = "sca3000-d01", + .scale = " 0.0073575", .temp_output = true, .measurement_mode_freq = 250, .option_mode_1 = SCA3000_OP_MODE_BYPASS, .option_mode_1_freq = 250, - }, { - /* No data sheet available - may be the same as the 3100-d03?*/ - .name = "sca3000-d03", - .temp_output = true, }, { .name = "sca3000-e02", + .scale = "0.00981", .measurement_mode_freq = 125, .option_mode_1 = SCA3000_OP_MODE_NARROW, .option_mode_1_freq = 63, }, { .name = "sca3000-e04", + .scale = "0.01962", .measurement_mode_freq = 100, .option_mode_1 = SCA3000_OP_MODE_NARROW, .option_mode_1_freq = 50, @@ -66,18 +63,12 @@ static const struct sca3000_chip_info sca3000_spi_chip_info_tbl[] = { .option_mode_2_freq = 400, }, { .name = "sca3000-e05", + .scale = "0.0613125", .measurement_mode_freq = 200, .option_mode_1 = SCA3000_OP_MODE_NARROW, .option_mode_1_freq = 50, .option_mode_2 = SCA3000_OP_MODE_WIDE, .option_mode_2_freq = 400, - }, { - /* No data sheet available. - * Frequencies are unknown. - */ - .name = "sca3000-l01", - .temp_output = true, - .option_mode_1 = SCA3000_OP_MODE_BYPASS, }, }; @@ -327,6 +318,14 @@ error_ret: return ret ? ret : len; } +static ssize_t sca3000_show_scale(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct sca3000_state *st = dev_info->dev_data; + return sprintf(buf, "%s\n", st->info->scale); +} static ssize_t sca3000_show_name(struct device *dev, struct device_attribute *attr, @@ -495,7 +494,7 @@ error_ret: /* Not even vaguely standard attributes so defined here rather than * in the relevant IIO core headers */ -static IIO_DEVICE_ATTR(available_measurement_modes, S_IRUGO, +static IIO_DEVICE_ATTR(measurement_mode_available, S_IRUGO, sca3000_show_available_measurement_modes, NULL, 0); @@ -508,6 +507,8 @@ static IIO_DEVICE_ATTR(measurement_mode, S_IRUGO | S_IWUSR, static IIO_DEV_ATTR_NAME(sca3000_show_name); static IIO_DEV_ATTR_REV(sca3000_show_rev); +static IIO_DEVICE_ATTR(accel_scale, S_IRUGO, sca3000_show_scale, + NULL, 0); static IIO_DEV_ATTR_ACCEL_X(sca3000_read_13bit_signed, SCA3000_REG_ADDR_X_MSB); @@ -683,7 +684,7 @@ error_free_lock: /* Should only really be registered if ring buffer support is compiled in. * Does no harm however and doing it right would add a fair bit of complexity */ -static IIO_DEV_ATTR_AVAIL_SAMP_FREQ(sca3000_read_av_freq); +static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(sca3000_read_av_freq); static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, sca3000_read_frequency, @@ -718,7 +719,10 @@ static ssize_t sca3000_read_temp(struct device *dev, error_ret: return ret; } -static IIO_DEV_ATTR_TEMP(sca3000_read_temp); +static IIO_DEV_ATTR_TEMP_RAW(sca3000_read_temp); + +static IIO_CONST_ATTR(temp_scale, "0.555556"); +static IIO_CONST_ATTR(temp_offset, "-214.6"); /** * sca3000_show_thresh() sysfs query of a threshold @@ -770,31 +774,34 @@ static ssize_t sca3000_write_thresh(struct device *dev, return ret ? ret : len; } -static IIO_DEV_ATTR_ACCEL_THRESH_X(S_IRUGO | S_IWUSR, - sca3000_show_thresh, - sca3000_write_thresh, - SCA3000_REG_CTRL_SEL_MD_X_TH); -static IIO_DEV_ATTR_ACCEL_THRESH_Y(S_IRUGO | S_IWUSR, - sca3000_show_thresh, - sca3000_write_thresh, - SCA3000_REG_CTRL_SEL_MD_Y_TH); -static IIO_DEV_ATTR_ACCEL_THRESH_Z(S_IRUGO | S_IWUSR, - sca3000_show_thresh, - sca3000_write_thresh, - SCA3000_REG_CTRL_SEL_MD_Z_TH); +static IIO_DEVICE_ATTR(accel_x_mag_either_rising_value, + S_IRUGO | S_IWUSR, + sca3000_show_thresh, + sca3000_write_thresh, + SCA3000_REG_CTRL_SEL_MD_X_TH); + +static IIO_DEVICE_ATTR(accel_y_mag_either_rising_value, + S_IRUGO | S_IWUSR, + sca3000_show_thresh, + sca3000_write_thresh, + SCA3000_REG_CTRL_SEL_MD_Y_TH); + +static IIO_DEVICE_ATTR(accel_z_mag_either_rising_value, + S_IRUGO | S_IWUSR, + sca3000_show_thresh, + sca3000_write_thresh, + SCA3000_REG_CTRL_SEL_MD_Z_TH); static struct attribute *sca3000_attributes[] = { &iio_dev_attr_name.dev_attr.attr, &iio_dev_attr_revision.dev_attr.attr, - &iio_dev_attr_accel_x.dev_attr.attr, - &iio_dev_attr_accel_y.dev_attr.attr, - &iio_dev_attr_accel_z.dev_attr.attr, - &iio_dev_attr_thresh_accel_x.dev_attr.attr, - &iio_dev_attr_thresh_accel_y.dev_attr.attr, - &iio_dev_attr_thresh_accel_z.dev_attr.attr, - &iio_dev_attr_available_measurement_modes.dev_attr.attr, + &iio_dev_attr_accel_scale.dev_attr.attr, + &iio_dev_attr_accel_x_raw.dev_attr.attr, + &iio_dev_attr_accel_y_raw.dev_attr.attr, + &iio_dev_attr_accel_z_raw.dev_attr.attr, + &iio_dev_attr_measurement_mode_available.dev_attr.attr, &iio_dev_attr_measurement_mode.dev_attr.attr, - &iio_dev_attr_available_sampling_frequency.dev_attr.attr, + &iio_dev_attr_sampling_frequency_available.dev_attr.attr, &iio_dev_attr_sampling_frequency.dev_attr.attr, NULL, }; @@ -802,18 +809,18 @@ static struct attribute *sca3000_attributes[] = { static struct attribute *sca3000_attributes_with_temp[] = { &iio_dev_attr_name.dev_attr.attr, &iio_dev_attr_revision.dev_attr.attr, - &iio_dev_attr_accel_x.dev_attr.attr, - &iio_dev_attr_accel_y.dev_attr.attr, - &iio_dev_attr_accel_z.dev_attr.attr, - &iio_dev_attr_thresh_accel_x.dev_attr.attr, - &iio_dev_attr_thresh_accel_y.dev_attr.attr, - &iio_dev_attr_thresh_accel_z.dev_attr.attr, - &iio_dev_attr_available_measurement_modes.dev_attr.attr, + &iio_dev_attr_accel_scale.dev_attr.attr, + &iio_dev_attr_accel_x_raw.dev_attr.attr, + &iio_dev_attr_accel_y_raw.dev_attr.attr, + &iio_dev_attr_accel_z_raw.dev_attr.attr, + &iio_dev_attr_measurement_mode_available.dev_attr.attr, &iio_dev_attr_measurement_mode.dev_attr.attr, - &iio_dev_attr_available_sampling_frequency.dev_attr.attr, + &iio_dev_attr_sampling_frequency_available.dev_attr.attr, &iio_dev_attr_sampling_frequency.dev_attr.attr, /* Only present if temp sensor is */ - &iio_dev_attr_temp.dev_attr.attr, + &iio_dev_attr_temp_raw.dev_attr.attr, + &iio_const_attr_temp_offset.dev_attr.attr, + &iio_const_attr_temp_scale.dev_attr.attr, NULL, }; @@ -910,7 +917,7 @@ static ssize_t sca3000_query_mo_det(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_get_drvdata(dev->parent); struct sca3000_state *st = indio_dev->dev_data; struct iio_event_attr *this_attr = to_iio_event_attr(attr); int ret, len = 0; @@ -975,7 +982,7 @@ static ssize_t sca3000_query_ring_int(struct device *dev, struct iio_event_attr *this_attr = to_iio_event_attr(attr); int ret, len; u8 *rx; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_get_drvdata(dev->parent); struct sca3000_state *st = indio_dev->dev_data; mutex_lock(&st->lock); ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_MASK, &rx, 1); @@ -995,7 +1002,7 @@ static ssize_t sca3000_set_ring_int(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_get_drvdata(dev->parent); struct sca3000_state *st = indio_dev->dev_data; struct iio_event_attr *this_attr = to_iio_event_attr(attr); @@ -1085,7 +1092,7 @@ static ssize_t sca3000_set_mo_det(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_get_drvdata(dev->parent); struct sca3000_state *st = indio_dev->dev_data; struct iio_event_attr *this_attr = to_iio_event_attr(attr); long val; @@ -1155,20 +1162,23 @@ IIO_EVENT_ATTR_FREE_FALL_DETECT_SH(iio_event_all, 0) /* Motion detector related event attributes */ -IIO_EVENT_ATTR_ACCEL_X_HIGH_SH(iio_event_all, - sca3000_query_mo_det, - sca3000_set_mo_det, - SCA3000_MD_CTRL_OR_X); - -IIO_EVENT_ATTR_ACCEL_Y_HIGH_SH(iio_event_all, - sca3000_query_mo_det, - sca3000_set_mo_det, - SCA3000_MD_CTRL_OR_Y); - -IIO_EVENT_ATTR_ACCEL_Z_HIGH_SH(iio_event_all, - sca3000_query_mo_det, - sca3000_set_mo_det, - SCA3000_MD_CTRL_OR_Z); +IIO_EVENT_ATTR_SH(accel_x_mag_either_rising_en, + iio_event_all, + sca3000_query_mo_det, + sca3000_set_mo_det, + SCA3000_MD_CTRL_OR_X); + +IIO_EVENT_ATTR_SH(accel_y_mag_either_rising_en, + iio_event_all, + sca3000_query_mo_det, + sca3000_set_mo_det, + SCA3000_MD_CTRL_OR_Y); + +IIO_EVENT_ATTR_SH(accel_z_mag_either_rising_en, + iio_event_all, + sca3000_query_mo_det, + sca3000_set_mo_det, + SCA3000_MD_CTRL_OR_Z); /* Hardware ring buffer related event attributes */ IIO_EVENT_ATTR_RING_50_FULL_SH(iio_event_all, @@ -1183,11 +1193,14 @@ IIO_EVENT_ATTR_RING_75_FULL_SH(iio_event_all, static struct attribute *sca3000_event_attributes[] = { &iio_event_attr_free_fall.dev_attr.attr, - &iio_event_attr_accel_x_high.dev_attr.attr, - &iio_event_attr_accel_y_high.dev_attr.attr, - &iio_event_attr_accel_z_high.dev_attr.attr, + &iio_event_attr_accel_x_mag_either_rising_en.dev_attr.attr, + &iio_event_attr_accel_y_mag_either_rising_en.dev_attr.attr, + &iio_event_attr_accel_z_mag_either_rising_en.dev_attr.attr, &iio_event_attr_ring_50_full.dev_attr.attr, &iio_event_attr_ring_75_full.dev_attr.attr, + &iio_dev_attr_accel_x_mag_either_rising_value.dev_attr.attr, + &iio_dev_attr_accel_y_mag_either_rising_value.dev_attr.attr, + &iio_dev_attr_accel_z_mag_either_rising_value.dev_attr.attr, NULL, }; @@ -1344,9 +1357,10 @@ static int __devinit __sca3000_probe(struct spi_device *spi, * is overkill. At very least a simpler registration method * might be worthwhile. */ - iio_add_event_to_list(iio_event_attr_accel_z_high.listel, - &st->indio_dev - ->interrupts[0]->ev_list); + iio_add_event_to_list( + iio_event_attr_accel_z_mag_either_rising_en.listel, + &st->indio_dev + ->interrupts[0]->ev_list); } sca3000_register_ring_funcs(st->indio_dev); ret = sca3000_clean_setup(st); @@ -1437,9 +1451,6 @@ static int sca3000_remove(struct spi_device *spi) SCA3000_VARIANT_PROBE(d01); static SCA3000_VARIANT_SPI_DRIVER(d01); -SCA3000_VARIANT_PROBE(d03); -static SCA3000_VARIANT_SPI_DRIVER(d03); - SCA3000_VARIANT_PROBE(e02); static SCA3000_VARIANT_SPI_DRIVER(e02); @@ -1449,9 +1460,6 @@ static SCA3000_VARIANT_SPI_DRIVER(e04); SCA3000_VARIANT_PROBE(e05); static SCA3000_VARIANT_SPI_DRIVER(e05); -SCA3000_VARIANT_PROBE(l01); -static SCA3000_VARIANT_SPI_DRIVER(l01); - static __init int sca3000_init(void) { int ret; @@ -1459,32 +1467,22 @@ static __init int sca3000_init(void) ret = spi_register_driver(&sca3000_d01_driver); if (ret) goto error_ret; - ret = spi_register_driver(&sca3000_d03_driver); - if (ret) - goto error_unreg_d01; ret = spi_register_driver(&sca3000_e02_driver); if (ret) - goto error_unreg_d03; + goto error_unreg_d01; ret = spi_register_driver(&sca3000_e04_driver); if (ret) goto error_unreg_e02; ret = spi_register_driver(&sca3000_e05_driver); if (ret) goto error_unreg_e04; - ret = spi_register_driver(&sca3000_l01_driver); - if (ret) - goto error_unreg_e05; return 0; -error_unreg_e05: - spi_unregister_driver(&sca3000_e05_driver); error_unreg_e04: spi_unregister_driver(&sca3000_e04_driver); error_unreg_e02: spi_unregister_driver(&sca3000_e02_driver); -error_unreg_d03: - spi_unregister_driver(&sca3000_d03_driver); error_unreg_d01: spi_unregister_driver(&sca3000_d01_driver); error_ret: @@ -1494,11 +1492,9 @@ error_ret: static __exit void sca3000_exit(void) { - spi_unregister_driver(&sca3000_l01_driver); spi_unregister_driver(&sca3000_e05_driver); spi_unregister_driver(&sca3000_e04_driver); spi_unregister_driver(&sca3000_e02_driver); - spi_unregister_driver(&sca3000_d03_driver); spi_unregister_driver(&sca3000_d01_driver); } diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c index 40cbab2a6592..2b39e6f6c26d 100644 --- a/drivers/staging/iio/accel/sca3000_ring.c +++ b/drivers/staging/iio/accel/sca3000_ring.c @@ -186,11 +186,29 @@ static ssize_t sca3000_store_ring_bpse(struct device *dev, return ret ? ret : len; } -static IIO_CONST_ATTR(bpse_available, "8 11"); +static IIO_SCAN_EL_C(accel_x, 0, 0, 0, 0); +static IIO_SCAN_EL_C(accel_y, 1, 0, 0, 0); +static IIO_SCAN_EL_C(accel_z, 2, 0, 0, 0); +static IIO_CONST_ATTR(accel_precision_available, "8 11"); +static IIO_DEVICE_ATTR(accel_precision, + S_IRUGO | S_IWUSR, + sca3000_show_ring_bpse, + sca3000_store_ring_bpse, + 0); + +static struct attribute *sca3000_scan_el_attrs[] = { + &iio_scan_el_accel_x.dev_attr.attr, + &iio_scan_el_accel_y.dev_attr.attr, + &iio_scan_el_accel_z.dev_attr.attr, + &iio_const_attr_accel_precision_available.dev_attr.attr, + &iio_dev_attr_accel_precision.dev_attr.attr, + NULL +}; -static IIO_DEV_ATTR_BPSE(S_IRUGO | S_IWUSR, - sca3000_show_ring_bpse, - sca3000_store_ring_bpse); +static struct attribute_group sca3000_scan_el_group = { + .attrs = sca3000_scan_el_attrs, + .name = "scan_elements", +}; /* * Ring buffer attributes @@ -198,17 +216,15 @@ static IIO_DEV_ATTR_BPSE(S_IRUGO | S_IWUSR, * only apply to the ring buffer. At all times full rate and accuracy * is available via direct reading from registers. */ -static struct attribute *iio_ring_attributes[] = { +static struct attribute *sca3000_ring_attributes[] = { &dev_attr_length.attr, &dev_attr_bps.attr, &dev_attr_ring_enable.attr, - &iio_dev_attr_bpse.dev_attr.attr, - &iio_const_attr_bpse_available.dev_attr.attr, NULL, }; static struct attribute_group sca3000_ring_attr = { - .attrs = iio_ring_attributes, + .attrs = sca3000_ring_attributes, }; static const struct attribute_group *sca3000_ring_attr_groups[] = { @@ -248,6 +264,7 @@ static inline void sca3000_rb_free(struct iio_ring_buffer *r) int sca3000_configure_ring(struct iio_dev *indio_dev) { + indio_dev->scan_el_attrs = &sca3000_scan_el_group; indio_dev->ring = sca3000_rb_allocate(indio_dev); if (indio_dev->ring == NULL) return -ENOMEM; diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h index 75e0fc078d68..c482074deadc 100644 --- a/drivers/staging/iio/ring_generic.h +++ b/drivers/staging/iio/ring_generic.h @@ -248,9 +248,9 @@ ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr, * * Odd one out. Handled slightly differently from other scan elements. **/ -#define IIO_SCAN_EL_TIMESTAMP \ +#define IIO_SCAN_EL_TIMESTAMP(number) \ struct iio_scan_el iio_scan_el_timestamp = { \ - .dev_attr = __ATTR(scan_en_timestamp, \ + .dev_attr = __ATTR(number##_timestamp_en, \ S_IRUGO | S_IWUSR, \ iio_scan_el_ts_show, \ iio_scan_el_ts_store), \ -- cgit v1.2.3 From e5c003ae82865c43feca9e11fb291ec2304a63d1 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 14:42:59 +0100 Subject: staging:iio: Support functions for scan mask matching Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/iio.h | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h index 71dbfe12b579..a12072a93cde 100644 --- a/drivers/staging/iio/iio.h +++ b/drivers/staging/iio/iio.h @@ -96,6 +96,7 @@ void iio_remove_event_from_list(struct iio_event_handler_list *el, * control method is used * @scan_count: [INTERN] the number of elements in the current scan mode * @scan_mask: [INTERN] bitmask used in masking scan mode elements + * @available_scan_masks: [DRIVER] optional array of allowed bitmasks * @scan_timestamp: [INTERN] does the scan mode include a timestamp * @trig: [INTERN] current device trigger (ring buffer modes) * @pollfunc: [DRIVER] function run on trigger being recieved @@ -122,7 +123,8 @@ struct iio_dev { struct attribute_group *scan_el_attrs; int scan_count; - u16 scan_mask; + u32 scan_mask; + u32 *available_scan_masks; bool scan_timestamp; struct iio_trigger *trig; struct iio_poll_func *pollfunc; @@ -132,22 +134,57 @@ struct iio_dev { * These are mainly provided to allow for a change of implementation if a device * has a large number of scan elements */ -#define IIO_MAX_SCAN_LENGTH 15 +#define IIO_MAX_SCAN_LENGTH 31 + +/* note 0 used as error indicator as it doesn't make sense. */ +static inline u32 iio_scan_mask_match(u32 *av_masks, u32 mask) +{ + while (*av_masks) { + if (!(~*av_masks & mask)) + return *av_masks; + av_masks++; + } + return 0; +} static inline int iio_scan_mask_query(struct iio_dev *dev_info, int bit) { + u32 mask; + if (bit > IIO_MAX_SCAN_LENGTH) return -EINVAL; + + if (!dev_info->scan_mask) + return 0; + + if (dev_info->available_scan_masks) + mask = iio_scan_mask_match(dev_info->available_scan_masks, + dev_info->scan_mask); else - return !!(dev_info->scan_mask & (1 << bit)); + mask = dev_info->scan_mask; + + if (!mask) + return -EINVAL; + + return !!(mask & (1 << bit)); }; static inline int iio_scan_mask_set(struct iio_dev *dev_info, int bit) { + u32 mask; + u32 trialmask = dev_info->scan_mask | (1 << bit); + if (bit > IIO_MAX_SCAN_LENGTH) return -EINVAL; - dev_info->scan_mask |= (1 << bit); + if (dev_info->available_scan_masks) { + mask = iio_scan_mask_match(dev_info->available_scan_masks, + trialmask); + if (!mask) + return -EINVAL; + } + dev_info->scan_mask = trialmask; dev_info->scan_count++; + return 0; }; -- cgit v1.2.3 From 5aaaeba82e00958ecb2c890b4953a249bbde9426 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 14:43:00 +0100 Subject: staging: iio: Move from class to bus Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/iio.h | 2 +- drivers/staging/iio/industrialio-core.c | 28 +++++++++++----------------- drivers/staging/iio/industrialio-ring.c | 2 +- drivers/staging/iio/industrialio-trigger.c | 2 +- drivers/staging/iio/ring_sw.c | 2 +- 5 files changed, 15 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h index a12072a93cde..fcee47cbe894 100644 --- a/drivers/staging/iio/iio.h +++ b/drivers/staging/iio/iio.h @@ -377,7 +377,7 @@ void iio_deallocate_chrdev(struct iio_handler *handler); #define IIO_UNSIGNED(a) (a) extern dev_t iio_devt; -extern struct class iio_class; +extern struct bus_type iio_bus_type; /** * iio_put_device() - reference counted deallocation of struct device diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index 7c9a12e0e8fe..ad830b64c912 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -42,16 +42,10 @@ dev_t iio_devt; EXPORT_SYMBOL(iio_devt); #define IIO_DEV_MAX 256 -static char *iio_devnode(struct device *dev, mode_t *mode) -{ - return kasprintf(GFP_KERNEL, "iio/%s", dev_name(dev)); -} - -struct class iio_class = { +struct bus_type iio_bus_type = { .name = "iio", - .devnode = iio_devnode, }; -EXPORT_SYMBOL(iio_class); +EXPORT_SYMBOL(iio_bus_type); void __iio_change_event(struct iio_detected_event_list *ev, int ev_code, @@ -405,7 +399,7 @@ int iio_setup_ev_int(struct iio_event_interface *ev_int, { int ret, minor; - ev_int->dev.class = &iio_class; + ev_int->dev.bus = &iio_bus_type; ev_int->dev.parent = dev; ev_int->dev.type = &iio_event_type; device_initialize(&ev_int->dev); @@ -478,23 +472,23 @@ static int __init iio_init(void) { int ret; - /* Create sysfs class */ - ret = class_register(&iio_class); + /* Register sysfs bus */ + ret = bus_register(&iio_bus_type); if (ret < 0) { printk(KERN_ERR - "%s could not create sysfs class\n", + "%s could not register bus type\n", __FILE__); goto error_nothing; } ret = iio_dev_init(); if (ret < 0) - goto error_unregister_class; + goto error_unregister_bus_type; return 0; -error_unregister_class: - class_unregister(&iio_class); +error_unregister_bus_type: + bus_unregister(&iio_bus_type); error_nothing: return ret; } @@ -502,7 +496,7 @@ error_nothing: static void __exit iio_exit(void) { iio_dev_exit(); - class_unregister(&iio_class); + bus_unregister(&iio_bus_type); } static int iio_device_register_sysfs(struct iio_dev *dev_info) @@ -768,7 +762,7 @@ struct iio_dev *iio_allocate_device(void) if (dev) { dev->dev.type = &iio_dev_type; - dev->dev.class = &iio_class; + dev->dev.bus = &iio_bus_type; device_initialize(&dev->dev); dev_set_drvdata(&dev->dev, (void *)dev); mutex_init(&dev->mlock); diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c index 5f48632e4258..690df91020e9 100644 --- a/drivers/staging/iio/industrialio-ring.c +++ b/drivers/staging/iio/industrialio-ring.c @@ -210,7 +210,7 @@ __iio_request_ring_buffer_access_chrdev(struct iio_ring_buffer *buf, buf->access_handler.flags = 0; buf->access_dev.parent = &buf->dev; - buf->access_dev.class = &iio_class; + buf->access_dev.bus = &iio_bus_type; buf->access_dev.type = &iio_ring_access_type; device_initialize(&buf->access_dev); diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c index 3c8f6ffab584..918b0fd2b83e 100644 --- a/drivers/staging/iio/industrialio-trigger.c +++ b/drivers/staging/iio/industrialio-trigger.c @@ -365,7 +365,7 @@ struct iio_trigger *iio_allocate_trigger(void) trig = kzalloc(sizeof *trig, GFP_KERNEL); if (trig) { trig->dev.type = &iio_trig_type; - trig->dev.class = &iio_class; + trig->dev.bus = &iio_bus_type; device_initialize(&trig->dev); dev_set_drvdata(&trig->dev, (void *)trig); spin_lock_init(&trig->pollfunc_list_lock); diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c index e9570e33694e..f8de45dc4b6e 100644 --- a/drivers/staging/iio/ring_sw.c +++ b/drivers/staging/iio/ring_sw.c @@ -419,7 +419,7 @@ struct iio_ring_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev) buf->dev.type = &iio_sw_ring_type; device_initialize(&buf->dev); buf->dev.parent = &indio_dev->dev; - buf->dev.class = &iio_class; + buf->dev.bus = &iio_bus_type; dev_set_drvdata(&buf->dev, (void *)buf); return buf; -- cgit v1.2.3 From 5cba220b0a3211befd5514cbd822a97578ef5ed4 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 14:43:01 +0100 Subject: staging:iio: Move event attributes into the event[n] device in sysfs Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/industrialio-core.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index ad830b64c912..a4ce2215e54a 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -676,16 +676,14 @@ static int iio_device_register_eventset(struct iio_dev *dev_info) dev_info->event_interfaces[i].id); goto error_free_setup_ev_ints; } - } - for (i = 0; i < dev_info->num_interrupt_lines; i++) { - snprintf(dev_info->event_interfaces[i]._attrname, 20, - "event_line%d_sources", i); - dev_info->event_attrs[i].name - = (const char *) - (dev_info->event_interfaces[i]._attrname); - ret = sysfs_create_group(&dev_info->dev.kobj, - &dev_info->event_attrs[i]); + dev_set_drvdata(&dev_info->event_interfaces[i].dev, + (void *)dev_info); + ret = sysfs_create_group(&dev_info + ->event_interfaces[i] + .dev.kobj, + &dev_info->event_attrs[i]); + if (ret) { dev_err(&dev_info->dev, "Failed to register sysfs for event attrs"); @@ -707,13 +705,13 @@ error_unregister_config_attrs: i = dev_info->num_interrupt_lines - 1; error_remove_sysfs_interfaces: for (j = 0; j < i; j++) - sysfs_remove_group(&dev_info->dev.kobj, + sysfs_remove_group(&dev_info + ->event_interfaces[j].dev.kobj, &dev_info->event_attrs[j]); - i = dev_info->num_interrupt_lines - 1; error_free_setup_ev_ints: for (j = 0; j < i; j++) { iio_free_idr_val(&iio_event_idr, - dev_info->event_interfaces[i].id); + dev_info->event_interfaces[j].id); iio_free_ev_int(&dev_info->event_interfaces[j]); } kfree(dev_info->interrupts); @@ -731,7 +729,8 @@ static void iio_device_unregister_eventset(struct iio_dev *dev_info) if (dev_info->num_interrupt_lines == 0) return; for (i = 0; i < dev_info->num_interrupt_lines; i++) - sysfs_remove_group(&dev_info->dev.kobj, + sysfs_remove_group(&dev_info + ->event_interfaces[i].dev.kobj, &dev_info->event_attrs[i]); for (i = 0; i < dev_info->num_interrupt_lines; i++) { -- cgit v1.2.3 From 1722762cead933994883fa57464efd45cf892ed7 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 14:43:02 +0100 Subject: staging:iio: Clean out unused IIO_SCAN_EL and add IIO_SCAN_NAMED_EL_C Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/ring_generic.h | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h index c482074deadc..d74b5aea0112 100644 --- a/drivers/staging/iio/ring_generic.h +++ b/drivers/staging/iio/ring_generic.h @@ -196,25 +196,6 @@ ssize_t iio_scan_el_store(struct device *dev, struct device_attribute *attr, **/ ssize_t iio_scan_el_show(struct device *dev, struct device_attribute *attr, char *buf); -/** - * IIO_SCAN_EL - declare and initialize a scan element without control func - * @_name: identifying name. Resulting struct is iio_scan_el_##_name, - * sysfs element, scan_en_##_name. - * @_number: unique id number for the scan element. - * @_bits: number of bits in the scan element result (used in mixed bit - * length devices). - * @_label: indentification variable used by drivers. Often a reg address. - **/ -#define IIO_SCAN_EL(_name, _number, _bits, _label) \ - struct iio_scan_el iio_scan_el_##_name = { \ - .dev_attr = __ATTR(scan_en_##_name, \ - S_IRUGO | S_IWUSR, \ - iio_scan_el_show, \ - iio_scan_el_store), \ - .mask = (1 << _number), \ - .bit_count = _bits, \ - .label = _label, \ - } ssize_t iio_scan_el_ts_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len); @@ -225,7 +206,7 @@ ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr, * IIO_SCAN_EL_C - declare and initialize a scan element with a control func * * @_name: identifying name. Resulting struct is iio_scan_el_##_name, - * sysfs element, scan_en_##_name. + * sysfs element, _name##_en. * @_number: unique id number for the scan element. * @_bits: number of bits in the scan element result (used in mixed bit * length devices). @@ -234,7 +215,7 @@ ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr, **/ #define IIO_SCAN_EL_C(_name, _number, _bits, _label, _controlfunc) \ struct iio_scan_el iio_scan_el_##_name = { \ - .dev_attr = __ATTR(scan_en_##_name, \ + .dev_attr = __ATTR(_number##_##_name##_en, \ S_IRUGO | S_IWUSR, \ iio_scan_el_show, \ iio_scan_el_store), \ @@ -243,6 +224,19 @@ ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr, .label = _label, \ .set_state = _controlfunc, \ } + +#define IIO_SCAN_NAMED_EL_C(_name, _string, _number, _bits, _label, _cf) \ + struct iio_scan_el iio_scan_el_##_name = { \ + .dev_attr = __ATTR(_number##_##_string##_en, \ + S_IRUGO | S_IWUSR, \ + iio_scan_el_show, \ + iio_scan_el_store), \ + .number = _number, \ + .bit_count = _bits, \ + .label = _label, \ + .set_state = _cf, \ + } + /** * IIO_SCAN_EL_TIMESTAMP - declare a special scan element for timestamps * -- cgit v1.2.3 From 82020b0ef15de0cde1082ba0ff427c2f47a9a011 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 14:43:03 +0100 Subject: staging:iio:max1363 move to new abi. Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 1 + drivers/staging/iio/adc/Makefile | 2 +- drivers/staging/iio/adc/max1363.h | 122 +++--- drivers/staging/iio/adc/max1363_core.c | 762 +++++++++++++++++++-------------- drivers/staging/iio/adc/max1363_ring.c | 65 +-- 5 files changed, 548 insertions(+), 404 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 3989c0ca0e0d..101ea4bc2370 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -7,6 +7,7 @@ config MAX1363 tristate "MAXIM max1363 ADC driver" depends on I2C select IIO_TRIGGER if IIO_RING_BUFFER + select MAX1363_RING_BUFFER help Say yes here to build support for many MAXIM i2c analog to digital convertors (ADC). (max1361, max1362, max1363, max1364, max1136, diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index 08cee5c22b92..18c9376ecbb2 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -3,6 +3,6 @@ # max1363-y := max1363_core.o -max1363-$(CONFIG_MAX1363_RING_BUFFER) += max1363_ring.o +max1363-y += max1363_ring.o obj-$(CONFIG_MAX1363) += max1363.o diff --git a/drivers/staging/iio/adc/max1363.h b/drivers/staging/iio/adc/max1363.h index c112fbef2705..72cf36709368 100644 --- a/drivers/staging/iio/adc/max1363.h +++ b/drivers/staging/iio/adc/max1363.h @@ -72,77 +72,54 @@ * @numvals: The number of values returned by a single scan */ struct max1363_mode { - const char *name; int8_t conf; - int numvals; + long modemask; }; -#define MAX1363_MODE_SINGLE(_num) { \ - .name = #_num, \ - .conf = MAX1363_CHANNEL_SEL(_num) \ +#define MAX1363_MODE_SINGLE(_num, _mask) { \ + .conf = MAX1363_CHANNEL_SEL(_num) \ | MAX1363_CONFIG_SCAN_SINGLE_1 \ | MAX1363_CONFIG_SE, \ - .numvals = 1, \ + .modemask = _mask, \ } -#define MAX1363_MODE_SINGLE_TIMES_8(_num) { \ - .name = #_num"x8", \ - .conf = MAX1363_CHANNEL_SEL(_num) \ - | MAX1363_CONFIG_SCAN_SINGLE_8 \ - | MAX1363_CONFIG_SE, \ - .numvals = 8, \ - } - -#define MAX1363_MODE_SCAN_TO_CHANNEL(_num) { \ - .name = "0..."#_num, \ - .conf = MAX1363_CHANNEL_SEL(_num) \ +#define MAX1363_MODE_SCAN_TO_CHANNEL(_num, _mask) { \ + .conf = MAX1363_CHANNEL_SEL(_num) \ | MAX1363_CONFIG_SCAN_TO_CS \ | MAX1363_CONFIG_SE, \ - .numvals = _num + 1, \ + .modemask = _mask, \ } /* note not available for max1363 hence naming */ -#define MAX1236_MODE_SCAN_MID_TO_CHANNEL(_mid, _num) { \ - .name = #_mid"..."#_num, \ - .conf = MAX1363_CHANNEL_SEL(_num) \ +#define MAX1236_MODE_SCAN_MID_TO_CHANNEL(_mid, _num, _mask) { \ + .conf = MAX1363_CHANNEL_SEL(_num) \ | MAX1236_SCAN_MID_TO_CHANNEL \ | MAX1363_CONFIG_SE, \ - .numvals = _num - _mid + 1 \ + .modemask = _mask \ } -#define MAX1363_MODE_DIFF_SINGLE(_nump, _numm) { \ - .name = #_nump"-"#_numm, \ - .conf = MAX1363_CHANNEL_SEL(_nump) \ +#define MAX1363_MODE_DIFF_SINGLE(_nump, _numm, _mask) { \ + .conf = MAX1363_CHANNEL_SEL(_nump) \ | MAX1363_CONFIG_SCAN_SINGLE_1 \ | MAX1363_CONFIG_DE, \ - .numvals = 1, \ - } - -#define MAX1363_MODE_DIFF_SINGLE_TIMES_8(_nump, _numm) { \ - .name = #_nump"-"#_numm, \ - .conf = MAX1363_CHANNEL_SEL(_nump) \ - | MAX1363_CONFIG_SCAN_SINGLE_8 \ - | MAX1363_CONFIG_DE, \ - .numvals = 1, \ + .modemask = _mask \ } /* Can't think how to automate naming so specify for now */ -#define MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(_name, _num, _numvals) { \ - .name = #_name, \ - .conf = MAX1363_CHANNEL_SEL(_num) \ +#define MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(_num, _numvals, _mask) { \ + .conf = MAX1363_CHANNEL_SEL(_num) \ | MAX1363_CONFIG_SCAN_TO_CS \ | MAX1363_CONFIG_DE, \ - .numvals = _numvals, \ + .modemask = _mask \ } /* note only available for max1363 hence naming */ -#define MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL_NAMED(_name, _num, _numvals) { \ - .name = #_name, \ - .conf = MAX1363_CHANNEL_SEL(_num) \ +#define MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(_num, _numvals, _mask) { \ + .conf = MAX1363_CHANNEL_SEL(_num) \ | MAX1236_SCAN_MID_TO_CHANNEL \ | MAX1363_CONFIG_SE, \ - .numvals = _numvals, \ + .modemask = _mask \ } /* Not currently handled */ @@ -158,35 +135,43 @@ struct max1363_mode { * clear what all the various options actually do. Alternative suggestions * that don't require user to have intimate knowledge of the chip welcomed. */ +enum max1363_channels { + max1363_in0, max1363_in1, max1363_in2, max1363_in3, + max1363_in4, max1363_in5, max1363_in6, max1363_in7, + max1363_in8, max1363_in9, max1363_in10, max1363_in11, + + max1363_in0min1, max1363_in2min3, + max1363_in4min5, max1363_in6min7, + max1363_in8min9, max1363_in10min11, + + max1363_in1min0, max1363_in3min2, + max1363_in5min4, max1363_in7min6, + max1363_in9min8, max1363_in11min10, + }; /* This must be maintained along side the max1363_mode_table in max1363_core */ enum max1363_modes { /* Single read of a single channel */ _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11, - /* Eight reads of a single channel */ - se0, se1, se2, se3, se4, se5, se6, se7, se8, se9, se10, se11, - /* Scan to channel */ - s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, - s0to7, s0to8, s0to9, s0to10, s0to11, /* Differential single read */ d0m1, d2m3, d4m5, d6m7, d8m9, d10m11, d1m0, d3m2, d5m4, d7m6, d9m8, d11m10, - /* Differential single read 8 times */ - de0m1, de2m3, de4m5, de6m7, de8m9, de10m11, - de1m0, de3m2, de5m4, de7m6, de9m8, de11m10, - /* Differential scan to channel */ - d0m1to2m3, d0m1to4m5, d0m1to6m7, d0m1to8m9, d0m1to10m11, - d1m0to3m2, d1m0to5m4, d1m0to7m6, d1m0to9m8, d1m0to11m10, - /* Scan mid to channel max123{6-9} only */ - s2to3, s6to7, s6to8, s6to9, s6to10, s6to11, - /* Differential scan mid to channel */ - s6m7to8m9, s6m7to10m11, s7m6to9m8, s7m6to11m10, + /* Scan to channel and mid to channel where overlapping */ + s0to1, s0to2, s2to3, s0to3, s0to4, s0to5, s0to6, + s6to7, s0to7, s6to8, s0to8, s6to9, + s0to9, s6to10, s0to10, s6to11, s0to11, + /* Differential scan to channel and mid to channel where overlapping */ + d0m1to2m3, d0m1to4m5, d0m1to6m7, d6m7to8m9, + d0m1to8m9, d6m7to10m11, d0m1to10m11, d1m0to3m2, + d1m0to5m4, d1m0to7m6, d7m6to9m8, d1m0to9m8, + d7m6to11m10, d1m0to11m10, }; /** * struct max1363_chip_info - chip specifc information * @name: indentification string for chip * @num_inputs: number of physical inputs on chip + * @bits: accuracy of the adc in bits * @int_vref_mv: the internal reference voltage * @monitor_mode: whether the chip supports monitor interrupts * @mode_list: array of available scan modes @@ -196,11 +181,14 @@ enum max1363_modes { struct max1363_chip_info { const char *name; u8 num_inputs; + u8 bits; u16 int_vref_mv; bool monitor_mode; const enum max1363_modes *mode_list; int num_modes; enum max1363_modes default_mode; + struct attribute_group *dev_attrs; + struct attribute_group *scan_attrs; }; @@ -212,6 +200,7 @@ struct max1363_chip_info { * @configbyte: cache of current device config byte * @chip_info: chip model specific constants, available modes etc * @current_mode: the scan mode of this chip + * @requestedmask: a valid requested set of channels * @poll_work: bottom half of polling interrupt handler * @protect_ring: used to ensure only one polling bh running at a time * @reg: supply regulator @@ -223,16 +212,21 @@ struct max1363_state { char configbyte; const struct max1363_chip_info *chip_info; const struct max1363_mode *current_mode; + u32 requestedmask; struct work_struct poll_work; atomic_t protect_ring; struct iio_trigger *trig; struct regulator *reg; }; + +const struct max1363_mode +*max1363_match_mode(u32 mask, const struct max1363_chip_info *ci); + +int max1363_set_scan_mode(struct max1363_state *st); + #ifdef CONFIG_MAX1363_RING_BUFFER -ssize_t max1363_scan_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); +int max1363_single_channel_from_ring(long mask, struct max1363_state *st); int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev); void max1363_ring_cleanup(struct iio_dev *indio_dev); @@ -250,14 +244,12 @@ static inline int max1363_initialize_ring(struct iio_ring_buffer *ring) return 0; }; - -static inline ssize_t max1363_scan_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) +int max1363_single_channel_from_ring(long mask, struct max1363_state *st) { - return 0; + return -EINVAL; }; + static inline int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev) { diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index 790d1cc9cdc3..e82f3e78a1c5 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -1,27 +1,26 @@ /* - * linux/drivers/industrialio/adc/max1363.c - * Copyright (C) 2008 Jonathan Cameron - * - * based on linux/drivers/i2c/chips/max123x - * Copyright (C) 2002-2004 Stefan Eletzhofer - * - * based on linux/drivers/acron/char/pcf8583.c - * Copyright (C) 2000 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * max1363.c - * - * Partial support for max1363 and similar chips. - * - * Not currently implemented. - * - * - Monitor interrrupt generation. - * - Control of internal reference. - * - Sysfs scan interface currently assumes unipolar mode. - */ + * iio/adc/max1363.c + * Copyright (C) 2008-2010 Jonathan Cameron + * + * based on linux/drivers/i2c/chips/max123x + * Copyright (C) 2002-2004 Stefan Eletzhofer + * + * based on linux/drivers/acron/char/pcf8583.c + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * max1363.c + * + * Partial support for max1363 and similar chips. + * + * Not currently implemented. + * + * - Monitor interrrupt generation. + * - Control of internal reference. + */ #include #include @@ -38,118 +37,318 @@ #include "../iio.h" #include "../sysfs.h" +#include "../ring_generic.h" +#include "adc.h" #include "max1363.h" -/* Available scan modes. - * Awkwardly the associated enum is in the header so it is available to - * the ring buffer code. - */ -static const struct max1363_mode max1363_mode_table[] = { - MAX1363_MODE_SINGLE(0), - MAX1363_MODE_SINGLE(1), - MAX1363_MODE_SINGLE(2), - MAX1363_MODE_SINGLE(3), - MAX1363_MODE_SINGLE(4), - MAX1363_MODE_SINGLE(5), - MAX1363_MODE_SINGLE(6), - MAX1363_MODE_SINGLE(7), - MAX1363_MODE_SINGLE(8), - MAX1363_MODE_SINGLE(9), - MAX1363_MODE_SINGLE(10), - MAX1363_MODE_SINGLE(11), - - MAX1363_MODE_SINGLE_TIMES_8(0), - MAX1363_MODE_SINGLE_TIMES_8(1), - MAX1363_MODE_SINGLE_TIMES_8(2), - MAX1363_MODE_SINGLE_TIMES_8(3), - MAX1363_MODE_SINGLE_TIMES_8(4), - MAX1363_MODE_SINGLE_TIMES_8(5), - MAX1363_MODE_SINGLE_TIMES_8(6), - MAX1363_MODE_SINGLE_TIMES_8(7), - MAX1363_MODE_SINGLE_TIMES_8(8), - MAX1363_MODE_SINGLE_TIMES_8(9), - MAX1363_MODE_SINGLE_TIMES_8(10), - MAX1363_MODE_SINGLE_TIMES_8(11), - - MAX1363_MODE_SCAN_TO_CHANNEL(1), - MAX1363_MODE_SCAN_TO_CHANNEL(2), - MAX1363_MODE_SCAN_TO_CHANNEL(3), - MAX1363_MODE_SCAN_TO_CHANNEL(4), - MAX1363_MODE_SCAN_TO_CHANNEL(5), - MAX1363_MODE_SCAN_TO_CHANNEL(6), - MAX1363_MODE_SCAN_TO_CHANNEL(7), - MAX1363_MODE_SCAN_TO_CHANNEL(8), - MAX1363_MODE_SCAN_TO_CHANNEL(9), - MAX1363_MODE_SCAN_TO_CHANNEL(10), - MAX1363_MODE_SCAN_TO_CHANNEL(11), - - MAX1363_MODE_DIFF_SINGLE(0, 1), - MAX1363_MODE_DIFF_SINGLE(2, 3), - MAX1363_MODE_DIFF_SINGLE(4, 5), - MAX1363_MODE_DIFF_SINGLE(6, 7), - MAX1363_MODE_DIFF_SINGLE(8, 9), - MAX1363_MODE_DIFF_SINGLE(10, 11), - MAX1363_MODE_DIFF_SINGLE(1, 0), - MAX1363_MODE_DIFF_SINGLE(3, 2), - MAX1363_MODE_DIFF_SINGLE(5, 4), - MAX1363_MODE_DIFF_SINGLE(7, 6), - MAX1363_MODE_DIFF_SINGLE(9, 8), - MAX1363_MODE_DIFF_SINGLE(11, 10), - - MAX1363_MODE_DIFF_SINGLE_TIMES_8(0, 1), - MAX1363_MODE_DIFF_SINGLE_TIMES_8(2, 3), - MAX1363_MODE_DIFF_SINGLE_TIMES_8(4, 5), - MAX1363_MODE_DIFF_SINGLE_TIMES_8(6, 7), - MAX1363_MODE_DIFF_SINGLE_TIMES_8(8, 9), - MAX1363_MODE_DIFF_SINGLE_TIMES_8(10, 11), - MAX1363_MODE_DIFF_SINGLE_TIMES_8(1, 0), - MAX1363_MODE_DIFF_SINGLE_TIMES_8(3, 2), - MAX1363_MODE_DIFF_SINGLE_TIMES_8(5, 4), - MAX1363_MODE_DIFF_SINGLE_TIMES_8(7, 6), - MAX1363_MODE_DIFF_SINGLE_TIMES_8(9, 8), - MAX1363_MODE_DIFF_SINGLE_TIMES_8(11, 10), - - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(0-1...2-3, 2, 2), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(0-1...4-5, 4, 3), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(0-1...6-7, 6, 4), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(0-1...8-9, 8, 5), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(0-1...10-11, 10, 6), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(1-0...3-2, 3, 2), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(1-0...5-4, 5, 3), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(1-0...7-6, 7, 4), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(1-0...9-8, 9, 5), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(1-0...11-10, 11, 6), - - MAX1236_MODE_SCAN_MID_TO_CHANNEL(2, 3), - MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 7), - MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 8), - MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 9), - MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 10), - MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 11), - - MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL_NAMED(6-7...8-9, 8, 2), - MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL_NAMED(6-7...10-11, 10, 3), - MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL_NAMED(7-6...9-8, 9, 2), - MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL_NAMED(7-6...11-10, 11, 3), +/* Here we claim all are 16 bits. This currently does no harm and saves + * us a lot of scan element listings */ + +#define MAX1363_SCAN_EL(number) \ + IIO_SCAN_EL_C(in##number, number, IIO_UNSIGNED(16), 0, NULL); +#define MAX1363_SCAN_EL_D(p, n, number) \ + IIO_SCAN_NAMED_EL_C(in##p##m##in##n, in##p-in##n, \ + number, IIO_SIGNED(16), 0 , NULL); + +static MAX1363_SCAN_EL(0); +static MAX1363_SCAN_EL(1); +static MAX1363_SCAN_EL(2); +static MAX1363_SCAN_EL(3); +static MAX1363_SCAN_EL(4); +static MAX1363_SCAN_EL(5); +static MAX1363_SCAN_EL(6); +static MAX1363_SCAN_EL(7); +static MAX1363_SCAN_EL(8); +static MAX1363_SCAN_EL(9); +static MAX1363_SCAN_EL(10); +static MAX1363_SCAN_EL(11); +static MAX1363_SCAN_EL_D(0, 1, 12); +static MAX1363_SCAN_EL_D(2, 3, 13); +static MAX1363_SCAN_EL_D(4, 5, 14); +static MAX1363_SCAN_EL_D(6, 7, 15); +static MAX1363_SCAN_EL_D(8, 9, 16); +static MAX1363_SCAN_EL_D(10, 11, 17); +static MAX1363_SCAN_EL_D(1, 0, 18); +static MAX1363_SCAN_EL_D(3, 2, 19); +static MAX1363_SCAN_EL_D(5, 4, 20); +static MAX1363_SCAN_EL_D(7, 6, 21); +static MAX1363_SCAN_EL_D(9, 8, 22); +static MAX1363_SCAN_EL_D(11, 10, 23); + +static const struct max1363_mode max1363_mode_table[] = { + /* All of the single channel options first */ + MAX1363_MODE_SINGLE(0, 1 << 0), + MAX1363_MODE_SINGLE(1, 1 << 1), + MAX1363_MODE_SINGLE(2, 1 << 2), + MAX1363_MODE_SINGLE(3, 1 << 3), + MAX1363_MODE_SINGLE(4, 1 << 4), + MAX1363_MODE_SINGLE(5, 1 << 5), + MAX1363_MODE_SINGLE(6, 1 << 6), + MAX1363_MODE_SINGLE(7, 1 << 7), + MAX1363_MODE_SINGLE(8, 1 << 8), + MAX1363_MODE_SINGLE(9, 1 << 9), + MAX1363_MODE_SINGLE(10, 1 << 10), + MAX1363_MODE_SINGLE(11, 1 << 11), + + MAX1363_MODE_DIFF_SINGLE(0, 1, 1 << 12), + MAX1363_MODE_DIFF_SINGLE(2, 3, 1 << 13), + MAX1363_MODE_DIFF_SINGLE(4, 5, 1 << 14), + MAX1363_MODE_DIFF_SINGLE(6, 7, 1 << 15), + MAX1363_MODE_DIFF_SINGLE(8, 9, 1 << 16), + MAX1363_MODE_DIFF_SINGLE(10, 11, 1 << 17), + MAX1363_MODE_DIFF_SINGLE(1, 0, 1 << 18), + MAX1363_MODE_DIFF_SINGLE(3, 2, 1 << 19), + MAX1363_MODE_DIFF_SINGLE(5, 4, 1 << 20), + MAX1363_MODE_DIFF_SINGLE(7, 6, 1 << 21), + MAX1363_MODE_DIFF_SINGLE(9, 8, 1 << 22), + MAX1363_MODE_DIFF_SINGLE(11, 10, 1 << 23), + + /* The multichannel scans next */ + MAX1363_MODE_SCAN_TO_CHANNEL(1, 0x003), + MAX1363_MODE_SCAN_TO_CHANNEL(2, 0x007), + MAX1236_MODE_SCAN_MID_TO_CHANNEL(2, 3, 0x00C), + MAX1363_MODE_SCAN_TO_CHANNEL(3, 0x00F), + MAX1363_MODE_SCAN_TO_CHANNEL(4, 0x01F), + MAX1363_MODE_SCAN_TO_CHANNEL(5, 0x03F), + MAX1363_MODE_SCAN_TO_CHANNEL(6, 0x07F), + MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 7, 0x0C0), + MAX1363_MODE_SCAN_TO_CHANNEL(7, 0x0FF), + MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 8, 0x1C0), + MAX1363_MODE_SCAN_TO_CHANNEL(8, 0x1FF), + MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 9, 0x3C0), + MAX1363_MODE_SCAN_TO_CHANNEL(9, 0x3FF), + MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 10, 0x7C0), + MAX1363_MODE_SCAN_TO_CHANNEL(10, 0x7FF), + MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 11, 0xFC0), + MAX1363_MODE_SCAN_TO_CHANNEL(11, 0xFFF), + + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(2, 2, 0x003000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(4, 3, 0x007000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(6, 4, 0x00F000), + MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(8, 2, 0x018000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(8, 5, 0x01F000), + MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(10, 3, 0x038000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(10, 6, 0x3F000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(3, 2, 0x0C0000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(5, 3, 0x1C0000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(7, 4, 0x3C0000), + MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(9, 2, 0x600000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(9, 5, 0x7C0000), + MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(11, 3, 0xE00000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(11, 6, 0xFC0000), }; +const struct max1363_mode +*max1363_match_mode(u32 mask, const struct max1363_chip_info *ci) { + int i; + if (mask) + for (i = 0; i < ci->num_modes; i++) + if (!((~max1363_mode_table[ci->mode_list[i]] + .modemask) & + mask)) + return &max1363_mode_table[ci + ->mode_list[i]]; + return 0; +}; + +static ssize_t max1363_show_precision(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct max1363_state *st = iio_dev_get_devdata(dev_info); + return sprintf(buf, "%d\n", st->chip_info->bits); +} + +static IIO_DEVICE_ATTR(in_precision, S_IRUGO, max1363_show_precision, + NULL, 0); + +static int max1363_write_basic_config(struct i2c_client *client, + unsigned char d1, + unsigned char d2) +{ + int ret; + u8 *tx_buf = kmalloc(2 , GFP_KERNEL); + + if (!tx_buf) + return -ENOMEM; + tx_buf[0] = d1; + tx_buf[1] = d2; + + ret = i2c_master_send(client, tx_buf, 2); + kfree(tx_buf); + + return (ret > 0) ? 0 : ret; +} + +int max1363_set_scan_mode(struct max1363_state *st) +{ + st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK + | MAX1363_SCAN_MASK + | MAX1363_SE_DE_MASK); + st->configbyte |= st->current_mode->conf; + + return max1363_write_basic_config(st->client, + st->setupbyte, + st->configbyte); +} + +static ssize_t max1363_read_single_channel(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct max1363_state *st = iio_dev_get_devdata(dev_info); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + struct i2c_client *client = st->client; + int ret = 0, len = 0; + s32 data ; + char rxbuf[2]; + long mask; + + mutex_lock(&dev_info->mlock); + /* If ring buffer capture is occuring, query the buffer */ + if (iio_ring_enabled(dev_info)) { + mask = max1363_mode_table[this_attr->address].modemask; + data = max1363_single_channel_from_ring(mask, st); + if (data < 0) { + ret = data; + goto error_ret; + } + } else { + /* Check to see if current scan mode is correct */ + if (st->current_mode != + &max1363_mode_table[this_attr->address]) { + /* Update scan mode if needed */ + st->current_mode + = &max1363_mode_table[this_attr->address]; + ret = max1363_set_scan_mode(st); + if (ret) + goto error_ret; + } + /* Get reading */ + data = i2c_master_recv(client, rxbuf, 2); + if (data < 0) { + ret = data; + goto error_ret; + } + data = (s32)(rxbuf[1]) | ((s32)(rxbuf[0] & 0x0F)) << 8; + } + /* Pretty print the result */ + len = sprintf(buf, "%u\n", data); + +error_ret: + mutex_unlock(&dev_info->mlock); + return ret ? ret : len; +} + +/* Direct read attribtues */ +static IIO_DEV_ATTR_IN_RAW(0, max1363_read_single_channel, _s0); +static IIO_DEV_ATTR_IN_RAW(1, max1363_read_single_channel, _s1); +static IIO_DEV_ATTR_IN_RAW(2, max1363_read_single_channel, _s2); +static IIO_DEV_ATTR_IN_RAW(3, max1363_read_single_channel, _s3); +static IIO_DEV_ATTR_IN_RAW(4, max1363_read_single_channel, _s4); +static IIO_DEV_ATTR_IN_RAW(5, max1363_read_single_channel, _s5); +static IIO_DEV_ATTR_IN_RAW(6, max1363_read_single_channel, _s6); +static IIO_DEV_ATTR_IN_RAW(7, max1363_read_single_channel, _s7); +static IIO_DEV_ATTR_IN_RAW(8, max1363_read_single_channel, _s8); +static IIO_DEV_ATTR_IN_RAW(9, max1363_read_single_channel, _s9); +static IIO_DEV_ATTR_IN_RAW(10, max1363_read_single_channel, _s10); +static IIO_DEV_ATTR_IN_RAW(11, max1363_read_single_channel, _s11); + +static IIO_DEV_ATTR_IN_DIFF_RAW(0, 1, max1363_read_single_channel, d0m1); +static IIO_DEV_ATTR_IN_DIFF_RAW(2, 3, max1363_read_single_channel, d2m3); +static IIO_DEV_ATTR_IN_DIFF_RAW(4, 5, max1363_read_single_channel, d4m5); +static IIO_DEV_ATTR_IN_DIFF_RAW(6, 7, max1363_read_single_channel, d6m7); +static IIO_DEV_ATTR_IN_DIFF_RAW(8, 9, max1363_read_single_channel, d8m9); +static IIO_DEV_ATTR_IN_DIFF_RAW(10, 11, max1363_read_single_channel, d10m11); +static IIO_DEV_ATTR_IN_DIFF_RAW(1, 0, max1363_read_single_channel, d1m0); +static IIO_DEV_ATTR_IN_DIFF_RAW(3, 2, max1363_read_single_channel, d3m2); +static IIO_DEV_ATTR_IN_DIFF_RAW(5, 4, max1363_read_single_channel, d5m4); +static IIO_DEV_ATTR_IN_DIFF_RAW(7, 6, max1363_read_single_channel, d7m6); +static IIO_DEV_ATTR_IN_DIFF_RAW(9, 8, max1363_read_single_channel, d9m8); +static IIO_DEV_ATTR_IN_DIFF_RAW(11, 10, max1363_read_single_channel, d11m10); + + +static ssize_t max1363_show_scale(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + /* Driver currently only support internal vref */ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct max1363_state *st = iio_dev_get_devdata(dev_info); + /* Corresponds to Vref / 2^(bits) */ + + if ((1 << (st->chip_info->bits + 1)) + > st->chip_info->int_vref_mv) + return sprintf(buf, "0.5\n"); + else + return sprintf(buf, "%d\n", + st->chip_info->int_vref_mv >> st->chip_info->bits); +} + +IIO_DEVICE_ATTR(in_scale, S_IRUGO, max1363_show_scale, NULL, 0); + +static ssize_t max1363_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct max1363_state *st = iio_dev_get_devdata(dev_info); + return sprintf(buf, "%s\n", st->chip_info->name); +} + +IIO_DEVICE_ATTR(name, S_IRUGO, max1363_show_name, NULL, 0); + /* Applies to max1363 */ static const enum max1363_modes max1363_mode_list[] = { _s0, _s1, _s2, _s3, - se0, se1, se2, se3, s0to1, s0to2, s0to3, d0m1, d2m3, d1m0, d3m2, - de0m1, de2m3, de1m0, de3m2, d0m1to2m3, d1m0to3m2, }; +static struct attribute *max1363_device_attrs[] = { + &iio_dev_attr_in0_raw.dev_attr.attr, + &iio_dev_attr_in1_raw.dev_attr.attr, + &iio_dev_attr_in2_raw.dev_attr.attr, + &iio_dev_attr_in3_raw.dev_attr.attr, + &iio_dev_attr_in0min1_raw.dev_attr.attr, + &iio_dev_attr_in2min3_raw.dev_attr.attr, + &iio_dev_attr_in1min0_raw.dev_attr.attr, + &iio_dev_attr_in3min2_raw.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + &iio_dev_attr_in_scale.dev_attr.attr, + NULL +}; + +static struct attribute_group max1363_dev_attr_group = { + .attrs = max1363_device_attrs, +}; + +static struct attribute *max1363_scan_el_attrs[] = { + &iio_scan_el_in0.dev_attr.attr, + &iio_scan_el_in1.dev_attr.attr, + &iio_scan_el_in2.dev_attr.attr, + &iio_scan_el_in3.dev_attr.attr, + &iio_scan_el_in0min1.dev_attr.attr, + &iio_scan_el_in2min3.dev_attr.attr, + &iio_scan_el_in1min0.dev_attr.attr, + &iio_scan_el_in3min2.dev_attr.attr, + &iio_dev_attr_in_precision.dev_attr.attr, + NULL, +}; + +static struct attribute_group max1363_scan_el_group = { + .name = "scan_elements", + .attrs = max1363_scan_el_attrs, +}; + /* Appies to max1236, max1237 */ static const enum max1363_modes max1236_mode_list[] = { _s0, _s1, _s2, _s3, - se0, se1, se2, se3, s0to1, s0to2, s0to3, d0m1, d2m3, d1m0, d3m2, - de0m1, de2m3, de1m0, de3m2, d0m1to2m3, d1m0to3m2, s2to3, }; @@ -157,19 +356,83 @@ static const enum max1363_modes max1236_mode_list[] = { /* Applies to max1238, max1239 */ static const enum max1363_modes max1238_mode_list[] = { _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11, - se0, se1, se2, se3, se4, se5, se6, se7, se8, se9, se10, se11, s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, s0to7, s0to8, s0to9, s0to10, s0to11, d0m1, d2m3, d4m5, d6m7, d8m9, d10m11, d1m0, d3m2, d5m4, d7m6, d9m8, d11m10, - de0m1, de2m3, de4m5, de6m7, de8m9, de10m11, - de1m0, de3m2, de5m4, de7m6, de9m8, de11m10, d0m1to2m3, d0m1to4m5, d0m1to6m7, d0m1to8m9, d0m1to10m11, d1m0to3m2, d1m0to5m4, d1m0to7m6, d1m0to9m8, d1m0to11m10, s6to7, s6to8, s6to9, s6to10, s6to11, - s6m7to8m9, s6m7to10m11, s7m6to9m8, s7m6to11m10, + d6m7to8m9, d6m7to10m11, d7m6to9m8, d7m6to11m10, }; +static struct attribute *max1238_device_attrs[] = { + &iio_dev_attr_in0_raw.dev_attr.attr, + &iio_dev_attr_in1_raw.dev_attr.attr, + &iio_dev_attr_in2_raw.dev_attr.attr, + &iio_dev_attr_in3_raw.dev_attr.attr, + &iio_dev_attr_in4_raw.dev_attr.attr, + &iio_dev_attr_in5_raw.dev_attr.attr, + &iio_dev_attr_in6_raw.dev_attr.attr, + &iio_dev_attr_in7_raw.dev_attr.attr, + &iio_dev_attr_in8_raw.dev_attr.attr, + &iio_dev_attr_in9_raw.dev_attr.attr, + &iio_dev_attr_in10_raw.dev_attr.attr, + &iio_dev_attr_in11_raw.dev_attr.attr, + &iio_dev_attr_in0min1_raw.dev_attr.attr, + &iio_dev_attr_in2min3_raw.dev_attr.attr, + &iio_dev_attr_in4min5_raw.dev_attr.attr, + &iio_dev_attr_in6min7_raw.dev_attr.attr, + &iio_dev_attr_in8min9_raw.dev_attr.attr, + &iio_dev_attr_in10min11_raw.dev_attr.attr, + &iio_dev_attr_in1min0_raw.dev_attr.attr, + &iio_dev_attr_in3min2_raw.dev_attr.attr, + &iio_dev_attr_in5min4_raw.dev_attr.attr, + &iio_dev_attr_in7min6_raw.dev_attr.attr, + &iio_dev_attr_in9min8_raw.dev_attr.attr, + &iio_dev_attr_in11min10_raw.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + &iio_dev_attr_in_scale.dev_attr.attr, + NULL +}; + +static struct attribute_group max1238_dev_attr_group = { + .attrs = max1238_device_attrs, +}; + +static struct attribute *max1238_scan_el_attrs[] = { + &iio_scan_el_in0.dev_attr.attr, + &iio_scan_el_in1.dev_attr.attr, + &iio_scan_el_in2.dev_attr.attr, + &iio_scan_el_in3.dev_attr.attr, + &iio_scan_el_in4.dev_attr.attr, + &iio_scan_el_in5.dev_attr.attr, + &iio_scan_el_in6.dev_attr.attr, + &iio_scan_el_in7.dev_attr.attr, + &iio_scan_el_in8.dev_attr.attr, + &iio_scan_el_in9.dev_attr.attr, + &iio_scan_el_in10.dev_attr.attr, + &iio_scan_el_in11.dev_attr.attr, + &iio_scan_el_in0min1.dev_attr.attr, + &iio_scan_el_in2min3.dev_attr.attr, + &iio_scan_el_in4min5.dev_attr.attr, + &iio_scan_el_in6min7.dev_attr.attr, + &iio_scan_el_in8min9.dev_attr.attr, + &iio_scan_el_in10min11.dev_attr.attr, + &iio_scan_el_in1min0.dev_attr.attr, + &iio_scan_el_in3min2.dev_attr.attr, + &iio_scan_el_in5min4.dev_attr.attr, + &iio_scan_el_in7min6.dev_attr.attr, + &iio_scan_el_in9min8.dev_attr.attr, + &iio_scan_el_in11min10.dev_attr.attr, + &iio_dev_attr_in_precision.dev_attr.attr, + NULL, +}; + +static struct attribute_group max1238_scan_el_group = { + .name = "scan_elements", + .attrs = max1238_scan_el_attrs, +}; enum { max1361, max1362, @@ -190,118 +453,130 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = { { .name = "max1361", .num_inputs = 4, + .bits = 10, + .int_vref_mv = 2048, .monitor_mode = 1, .mode_list = max1363_mode_list, .num_modes = ARRAY_SIZE(max1363_mode_list), .default_mode = s0to3, + .dev_attrs = &max1363_dev_attr_group, + .scan_attrs = &max1363_scan_el_group, }, { .name = "max1362", .num_inputs = 4, + .bits = 10, + .int_vref_mv = 4096, .monitor_mode = 1, .mode_list = max1363_mode_list, .num_modes = ARRAY_SIZE(max1363_mode_list), .default_mode = s0to3, + .dev_attrs = &max1363_dev_attr_group, + .scan_attrs = &max1363_scan_el_group, }, { .name = "max1363", .num_inputs = 4, + .bits = 12, + .int_vref_mv = 2048, .monitor_mode = 1, .mode_list = max1363_mode_list, .num_modes = ARRAY_SIZE(max1363_mode_list), .default_mode = s0to3, + .dev_attrs = &max1363_dev_attr_group, + .scan_attrs = &max1363_scan_el_group, }, { .name = "max1364", .num_inputs = 4, + .bits = 12, + .int_vref_mv = 4096, .monitor_mode = 1, .mode_list = max1363_mode_list, .num_modes = ARRAY_SIZE(max1363_mode_list), .default_mode = s0to3, + .dev_attrs = &max1363_dev_attr_group, + .scan_attrs = &max1363_scan_el_group, }, { .name = "max1136", .num_inputs = 4, + .bits = 10, .int_vref_mv = 4096, .mode_list = max1236_mode_list, .num_modes = ARRAY_SIZE(max1236_mode_list), .default_mode = s0to3, + .dev_attrs = &max1363_dev_attr_group, + .scan_attrs = &max1363_scan_el_group, }, { .name = "max1137", .num_inputs = 4, + .bits = 10, .int_vref_mv = 2048, .mode_list = max1236_mode_list, .num_modes = ARRAY_SIZE(max1236_mode_list), .default_mode = s0to3, + .dev_attrs = &max1363_dev_attr_group, + .scan_attrs = &max1363_scan_el_group, }, { .name = "max1138", .num_inputs = 12, + .bits = 10, .int_vref_mv = 4096, .mode_list = max1238_mode_list, .num_modes = ARRAY_SIZE(max1238_mode_list), .default_mode = s0to11, + .dev_attrs = &max1238_dev_attr_group, + .scan_attrs = &max1238_scan_el_group, }, { .name = "max1139", .num_inputs = 12, + .bits = 10, .int_vref_mv = 2048, .mode_list = max1238_mode_list, .num_modes = ARRAY_SIZE(max1238_mode_list), .default_mode = s0to11, + .dev_attrs = &max1238_dev_attr_group, + .scan_attrs = &max1238_scan_el_group, }, { .name = "max1236", .num_inputs = 4, + .bits = 12, .int_vref_mv = 4096, .mode_list = max1236_mode_list, .num_modes = ARRAY_SIZE(max1236_mode_list), .default_mode = s0to3, + .dev_attrs = &max1363_dev_attr_group, + .scan_attrs = &max1363_scan_el_group, }, { .name = "max1237", .num_inputs = 4, + .bits = 12, .int_vref_mv = 2048, .mode_list = max1236_mode_list, .num_modes = ARRAY_SIZE(max1236_mode_list), .default_mode = s0to3, + .dev_attrs = &max1363_dev_attr_group, + .scan_attrs = &max1363_scan_el_group, }, { .name = "max1238", .num_inputs = 12, + .bits = 12, .int_vref_mv = 4096, .mode_list = max1238_mode_list, .num_modes = ARRAY_SIZE(max1238_mode_list), .default_mode = s0to11, + .dev_attrs = &max1238_dev_attr_group, + .scan_attrs = &max1238_scan_el_group, }, { .name = "max1239", .num_inputs = 12, + .bits = 12, .int_vref_mv = 2048, .mode_list = max1238_mode_list, .num_modes = ARRAY_SIZE(max1238_mode_list), .default_mode = s0to11, + .dev_attrs = &max1238_dev_attr_group, + .scan_attrs = &max1238_scan_el_group, }, }; -static int max1363_write_basic_config(struct i2c_client *client, - unsigned char d1, - unsigned char d2) -{ - int ret; - u8 *tx_buf = kmalloc(2 , GFP_KERNEL); - if (!tx_buf) - return -ENOMEM; - tx_buf[0] = d1; - tx_buf[1] = d2; - - ret = i2c_master_send(client, tx_buf, 2); - kfree(tx_buf); - return (ret > 0) ? 0 : ret; -} - -static int max1363_set_scan_mode(struct max1363_state *st) -{ - st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK - | MAX1363_SCAN_MASK - | MAX1363_SE_DE_MASK); - st->configbyte |= st->current_mode->conf; - - return max1363_write_basic_config(st->client, - st->setupbyte, - st->configbyte); -} - static int max1363_initial_setup(struct max1363_state *st) { st->setupbyte = MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD @@ -318,167 +593,6 @@ static int max1363_initial_setup(struct max1363_state *st) return max1363_set_scan_mode(st); } -static ssize_t max1363_show_av_scan_modes(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct max1363_state *st = dev_info->dev_data; - int i, len = 0; - - for (i = 0; i < st->chip_info->num_modes; i++) - len += sprintf(buf + len, "%s ", - max1363_mode_table[st->chip_info - ->mode_list[i]].name); - len += sprintf(buf + len, "\n"); - - return len; -} - - -/* The dev here is the sysfs related one, not the underlying i2c one */ -static ssize_t max1363_scan_direct(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct max1363_state *st = dev_info->dev_data; - int len = 0, ret, i; - struct i2c_client *client = st->client; - char *rxbuf; - - if (st->current_mode->numvals == 0) - return 0; - rxbuf = kmalloc(st->current_mode->numvals*2, GFP_KERNEL); - if (rxbuf == NULL) - return -ENOMEM; - - /* Interpretation depends on whether these are signed or not!*/ - /* Assume not for now */ - ret = i2c_master_recv(client, rxbuf, st->current_mode->numvals*2); - - if (ret < 0) - return ret; - for (i = 0; i < st->current_mode->numvals; i++) - len += sprintf(buf+len, "%d ", - ((int)(rxbuf[i*2+0]&0x0F) << 8) - + ((int)(rxbuf[i*2+1]))); - kfree(rxbuf); - len += sprintf(buf + len, "\n"); - - return len; -} - -static ssize_t max1363_scan(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_get_drvdata(dev); - int ret; - - mutex_lock(&dev_info->mlock); - if (dev_info->currentmode == INDIO_RING_TRIGGERED) - ret = max1363_scan_from_ring(dev, attr, buf); - else - ret = max1363_scan_direct(dev, attr, buf); - mutex_unlock(&dev_info->mlock); - - return ret; -} - -/* Cannot query the device, so use local copy of state */ -static ssize_t max1363_show_scan_mode(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct max1363_state *st = dev_info->dev_data; - - return sprintf(buf, "%s\n", st->current_mode->name); -} - -static const struct max1363_mode -*__max1363_find_mode_in_ci(const struct max1363_chip_info *info, - const char *buf) -{ - int i; - for (i = 0; i < info->num_modes; i++) - if (strcmp(max1363_mode_table[info->mode_list[i]].name, buf) - == 0) - return &max1363_mode_table[info->mode_list[i]]; - return NULL; -} - -static ssize_t max1363_store_scan_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct max1363_state *st = dev_info->dev_data; - const struct max1363_mode *new_mode; - int ret; - - mutex_lock(&dev_info->mlock); - new_mode = NULL; - /* Avoid state changes if a ring buffer is enabled */ - if (!iio_ring_enabled(dev_info)) { - new_mode - = __max1363_find_mode_in_ci(st->chip_info, buf); - if (!new_mode) { - ret = -EINVAL; - goto error_ret; - } - st->current_mode = new_mode; - ret = max1363_set_scan_mode(st); - if (ret) - goto error_ret; - } else { - ret = -EBUSY; - goto error_ret; - } - mutex_unlock(&dev_info->mlock); - - return len; - -error_ret: - mutex_unlock(&dev_info->mlock); - - return ret; -} - -IIO_DEV_ATTR_AVAIL_SCAN_MODES(max1363_show_av_scan_modes); -IIO_DEV_ATTR_SCAN_MODE(S_IRUGO | S_IWUSR, - max1363_show_scan_mode, - max1363_store_scan_mode); - -IIO_DEV_ATTR_SCAN(max1363_scan); - -static ssize_t max1363_show_name(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct max1363_state *st = dev_info->dev_data; - return sprintf(buf, "%s\n", st->chip_info->name); -} - -IIO_DEVICE_ATTR(name, S_IRUGO, max1363_show_name, NULL, 0); - -/*name export */ - -static struct attribute *max1363_attributes[] = { - &iio_dev_attr_available_scan_modes.dev_attr.attr, - &iio_dev_attr_scan_mode.dev_attr.attr, - &iio_dev_attr_scan.dev_attr.attr, - &iio_dev_attr_name.dev_attr.attr, - NULL, -}; - -static const struct attribute_group max1363_attribute_group = { - .attrs = max1363_attributes, -}; - static int __devinit max1363_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -506,6 +620,7 @@ static int __devinit max1363_probe(struct i2c_client *client, ret = -ENODEV; goto error_free_st; } + st->reg = regulator_get(&client->dev, "vcc"); if (!IS_ERR(st->reg)) { ret = regulator_enable(st->reg); @@ -520,20 +635,36 @@ static int __devinit max1363_probe(struct i2c_client *client, goto error_disable_reg; } + st->indio_dev->available_scan_masks + = kzalloc(GFP_KERNEL, + sizeof(*st->indio_dev->available_scan_masks)* + (st->chip_info->num_modes + 1)); + if (!st->indio_dev->available_scan_masks) { + ret = -ENOMEM; + goto error_free_device; + } + + for (i = 0; i < st->chip_info->num_modes; i++) + st->indio_dev->available_scan_masks[i] = + max1363_mode_table[st->chip_info->mode_list[i]] + .modemask; /* Estabilish that the iio_dev is a child of the i2c device */ st->indio_dev->dev.parent = &client->dev; - st->indio_dev->attrs = &max1363_attribute_group; + st->indio_dev->attrs = st->chip_info->dev_attrs; + + /* Todo: this shouldn't be here. */ + st->indio_dev->scan_el_attrs = st->chip_info->scan_attrs; st->indio_dev->dev_data = (void *)(st); st->indio_dev->driver_module = THIS_MODULE; st->indio_dev->modes = INDIO_DIRECT_MODE; ret = max1363_initial_setup(st); if (ret) - goto error_free_device; + goto error_free_available_scan_masks; ret = max1363_register_ring_funcs_and_init(st->indio_dev); if (ret) - goto error_free_device; + goto error_free_available_scan_masks; ret = iio_device_register(st->indio_dev); if (ret) @@ -545,6 +676,8 @@ static int __devinit max1363_probe(struct i2c_client *client, return 0; error_cleanup_ring: max1363_ring_cleanup(st->indio_dev); +error_free_available_scan_masks: + kfree(st->indio_dev->available_scan_masks); error_free_device: if (!regdone) iio_free_device(st->indio_dev); @@ -569,6 +702,7 @@ static int max1363_remove(struct i2c_client *client) struct iio_dev *indio_dev = st->indio_dev; max1363_uninitialize_ring(indio_dev->ring); max1363_ring_cleanup(indio_dev); + kfree(st->indio_dev->available_scan_masks); iio_device_unregister(indio_dev); if (!IS_ERR(st->reg)) { regulator_disable(st->reg); diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c index f94fe2d38a97..6003f7e10a6e 100644 --- a/drivers/staging/iio/adc/max1363_ring.c +++ b/drivers/staging/iio/adc/max1363_ring.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "../iio.h" #include "../ring_generic.h" @@ -26,32 +27,36 @@ #include "max1363.h" -ssize_t max1363_scan_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) +/* Todo: test this */ +int max1363_single_channel_from_ring(long mask, struct max1363_state *st) { - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct max1363_state *info = dev_info->dev_data; - int i, ret, len = 0; - char *ring_data; + unsigned long numvals; + int count = 0, ret; + u8 *ring_data; + if (!(st->current_mode->modemask & mask)) { + ret = -EBUSY; + goto error_ret; + } + numvals = hweight_long(st->current_mode->modemask); - ring_data = kmalloc(info->current_mode->numvals*2, GFP_KERNEL); + ring_data = kmalloc(numvals*2, GFP_KERNEL); if (ring_data == NULL) { ret = -ENOMEM; goto error_ret; } - ret = dev_info->ring->access.read_last(dev_info->ring, ring_data); + ret = st->indio_dev->ring->access.read_last(st->indio_dev->ring, + ring_data); if (ret) goto error_free_ring_data; - len += sprintf(buf+len, "ring "); - for (i = 0; i < info->current_mode->numvals; i++) - len += sprintf(buf + len, "%d ", - ((int)(ring_data[i*2 + 0] & 0x0F) << 8) - + ((int)(ring_data[i*2 + 1]))); - len += sprintf(buf + len, "\n"); - kfree(ring_data); - - return len; + /* Need a count of channels prior to this one */ + mask >>= 1; + while (mask) { + if (mask && st->current_mode->modemask) + count++; + mask >>= 1; + } + return ((int)(ring_data[count*2 + 0] & 0x0F) << 8) + + (int)(ring_data[count*2 + 1]); error_free_ring_data: kfree(ring_data); @@ -70,9 +75,22 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev) { struct max1363_state *st = indio_dev->dev_data; size_t d_size; + unsigned long numvals; + + /* + * Need to figure out the current mode based upon the requested + * scan mask in iio_dev + */ + st->current_mode = max1363_match_mode(st->indio_dev->scan_mask, + st->chip_info); + if (!st->current_mode) + return -EINVAL; + + max1363_set_scan_mode(st); + numvals = hweight_long(st->current_mode->modemask); if (indio_dev->ring->access.set_bpd) { - d_size = st->current_mode->numvals*2 + sizeof(s64); + d_size = numvals*2 + sizeof(s64); if (d_size % 8) d_size += 8 - (d_size % 8); indio_dev->ring->access.set_bpd(indio_dev->ring, d_size); @@ -145,9 +163,10 @@ static void max1363_poll_bh_to_ring(struct work_struct *work_s) __u8 *rxbuf; int b_sent; size_t d_size; + unsigned long numvals = hweight_long(st->current_mode->modemask); /* Ensure the timestamp is 8 byte aligned */ - d_size = st->current_mode->numvals*2 + sizeof(s64); + d_size = numvals*2 + sizeof(s64); if (d_size % sizeof(s64)) d_size += sizeof(s64) - (d_size % sizeof(s64)); @@ -159,16 +178,14 @@ static void max1363_poll_bh_to_ring(struct work_struct *work_s) * might as well have this test in here in the meantime as it does * no harm. */ - if (st->current_mode->numvals == 0) + if (numvals == 0) return; rxbuf = kmalloc(d_size, GFP_KERNEL); if (rxbuf == NULL) return; - b_sent = i2c_master_recv(st->client, - rxbuf, - st->current_mode->numvals*2); + b_sent = i2c_master_recv(st->client, rxbuf, numvals*2); if (b_sent < 0) goto done; -- cgit v1.2.3 From eaf86ff9390d4d9c34d88d75fc7bcb784afc697a Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 14:43:04 +0100 Subject: staging:iio: Documentation, update iio_utils.h for the move to a bus Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/iio_utils.h | 31 ++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index 74d312473378..d24006aedd5a 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -47,7 +47,7 @@ inline char *find_ring_subelement(const char *directory, const char *subelement) char *find_type_by_name(const char *name, const char *type) { - const char *iio_dir = "/sys/class/iio/"; + const char *iio_dir = "/sys/bus/iio/devices/"; const struct dirent *ent; int cnt, pos, pos2; @@ -112,6 +112,35 @@ int write_sysfs_int(char *filename, char *basedir, int val) return 0; } +int write_sysfs_int_and_verify(char *filename, char *basedir, int val) +{ + int ret; + FILE *sysfsfp; + char temp[100]; + int test; + + sprintf(temp, "%s%s", basedir, filename); + sysfsfp = fopen(temp, "w"); + if (sysfsfp == NULL) + return -1; + fprintf(sysfsfp, "%d", val); + fclose(sysfsfp); + + sysfsfp = fopen(temp, "r"); + if (sysfsfp == NULL) + return -1; + fscanf(sysfsfp, "%d", &test); + if (test != val) { + printf("Possible failure in int write %d to %s%s\n", + val, + basedir, + filename); + return -1; + } + + return 0; +} + /** * write_sysfs_string_and_verify() - string write, readback and verify * @filename: name of file to write to -- cgit v1.2.3 From e34d2c5fa2254197b0a01925cc6f77e12552f9b9 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 14:43:05 +0100 Subject: staging:iio: ABI documentation (partial) Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/sysfs-class-iio | 285 ++++++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 drivers/staging/iio/Documentation/sysfs-class-iio (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/sysfs-class-iio b/drivers/staging/iio/Documentation/sysfs-class-iio new file mode 100644 index 000000000000..723858215786 --- /dev/null +++ b/drivers/staging/iio/Documentation/sysfs-class-iio @@ -0,0 +1,285 @@ + +What: /sys/bus/iio/devices/device[n] +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Hardware chip or device accessed by on communication port. + Corresponds to a grouping of sensor channels. + +What: /sys/bus/iio/devices/trigger[n] +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + An event driven driver of data capture to an in kernel buffer. + May be provided by a device driver that also has an IIO device + based on hardware generated events (e.g. data ready) or + provided by a separate driver for other hardware (e.g. + periodic timer, gpio or high resolution timer). + Contains trigger type specific elements. These do not + generalize well and hence are not documented in this file. + +What: /sys/bus/iio/devices/device[n]:buffer +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Link to /sys/class/iio/device[n]/device[n]:buffer. n indicates the + device with which this buffer buffer is associated. + +What: /sys/.../device[n]/name +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Description of the physical chip / device. Typically a part + number. + +What: /sys/.../device[n]/sampling_frequency +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Some devices have internal clocks. This parameter sets the + resulting sampling frequency. In many devices this + parameter has an effect on input filters etc rather than + simply controlling when the input is sampled. As this + effects datardy triggers, hardware buffers and the sysfs + direct access interfaces, it may be found in any of the + relevant directories. If it effects all of the above + then it is to be found in the base device directory as here. + +What: /sys/.../device[n]/sampling_frequency_available +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + When the internal sampling clock can only take a small + discrete set of values, this file lists those availale. + +What: /sys/.../device[n]/in[_name][m]_raw +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Raw (unscaled no bias removal etc) voltage measurement from + channel m. name is used in special cases where this does + not correspond to externally available input (e.g. supply + voltage monitoring in which case the file is in_supply_raw). + +What: /sys/.../device[n]/in[_name][m]_offset +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + If known for a device, offset to be added to in[m]_raw prior + to scaling by volt[m]_scale in order to obtain voltage in + millivolts. Not present if the offset is always 0 or unknown. + If m is not present, then voltage offset applies to all in + channels. May be writable if a variable offset is controlled + by the device. Note that this is different to calibbias which + is for devices that apply offsets to compensate for variation + between different instances of the part, typically adjusted by + using some hardware supported calibration procedure. + +What: /sys/.../device[n]/in[_name][m]_offset_available +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + If a small number of discrete offset values are available, this + will be a space separated list. If these are independant (but + options the same) for individual offsets then m should not be + present. + +What: /sys/.../device[n]/in[_name][m]_offset_[min|max] +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + If a more or less continuous range of voltage offsets are supported + then these specify the minimum and maximum. If shared by all + in channels then m is not present. + +What: /sys/.../device[n]/in[_name][m]_calibbias +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Hardware applied calibration offset. (assumed to fix production + inaccuracies) + +What /sys/.../device[n]/in[_name][m]_calibscale +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Hardware applied calibration scale factor. (assumed to fix production + inaccuracies) + +What: /sys/.../device[n]/in[_name][m]_scale +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + If known for a device, scale to be applied to volt[m]_raw post + addition of volt[m]_offset in order to obtain the measured voltage + in millivolts. If shared across all in channels then m is not present. + +What: /sys/.../device[n]/in[m]-in[o]_raw +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Raw (unscaled) differential voltage measurement equivalent to + channel m - channel o where these channel numbers apply to the physically + equivalent inputs when non differential readings are separately available. + In differential only parts, then all that is required is a consistent + labelling. + +What: /sys/.../device[n]/accel[_x|_y|_z][m]_raw +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Acceleration in direction x, y or z (may be arbitrarily assigned + but should match other such assignments on device) + channel m (not present if only one accelerometer channel at + this orientation). Has all of the equivalent parameters as per in[m]. + Units after application of scale and offset are m/s^2. + +What: /sys/.../device[n]/gyro[_x|_y|_z][m]_raw +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Angular velocity about axis x, y or z (may be arbitrarily assigned) + channel m (not present if only one gyroscope at this orientation). + Data converted by application of offset then scale to + radians per second. Has all the equivalent parameters as per in[m]. + +What: /sys/.../device[n]/mag[_x|_y|_z][m]_raw +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Magnetic field along axis x, y or z (may be arbitrarily assigned) + channel m (not present if only one magnetometer at this orientation). + Data converted by application of offset then scale to Gauss + Has all the equivalent modifiers as per in[m]. + +What: /sys/.../device[n]/device[n]:event[m] +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Configuration of which hardware generated events are passed up to + userspace. Some of these are a bit complex to generalize so this + section is a work in progress. + +What: /sys/.../device[n]:event[m]/dev +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + major:minor character device numbers for the event line. + +Taking accel_x0 as an example + +What: /sys/.../device[n]:event[m]/accel_x0_thresh[_high|_low]_en +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Event generated when accel_x0 passes a threshold in correction direction + (or stays beyond one). If direction isn't specified, either triggers it. + Note driver will assume last p events requested are enabled where p is + however many it supports. So if you want to be sure you have + set what you think you have, check the contents of these. Drivers + may have to buffer any parameters so that they are consistent when a + given event type is enabled a future point (and not those for whatever + alarm was previously enabled). + +What: /sys/.../device[n]:event[m]/accel_x0_roc[_high|_low]_en +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Same as above but based on the first differential of the value. + + +What: /sys/.../device[n]:event[m]/accel_x0[_thresh|_roc][_high|_low]_period +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + A period of time (microsecs) for which the condition must be broken + before an interrupt is triggered. Applies to all alarms if type is not + specified. + +What: /sys/.../device[n]:event[m]/accel_x0[_thresh|_roc][_high|_low]_value +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + The actual value of the threshold in raw device units obtained by + reverse application of scale and offfset to the acceleration in m/s^2. + +What: /sys/.../device[n]/scan_elements +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Directory containing interfaces for elements that will be captured + for a single triggered sample set in the buffer. + +What: /sys/.../device[n]/scan_elements/[m]_accel_x0_en +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Scan element control for triggered data capture. m implies the + ordering within the buffer. Next the type is specified with + modifier and channel number as per the sysfs single channel + access above. + +What: /sys/.../device[n]/scan_elements/accel[_x0]_precision +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Scan element precision within the buffer. Note that the + data alignment must restrictions must be read from within + buffer to work out full data alignment for data read + via buffer_access chrdev. _x0 dropped if shared across all + acceleration channels. + +What: /sys/.../device[n]/scan_elements/accel[_x0]_shift +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + A bit shift (to right) that must be applied prior to + extracting the bits specified by accel[_x0]_precision. + +What: /sys/.../device[n]/device[n]:buffer:event/dev +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Buffer for device n event character device major:minor numbers. + +What: /sys/.../device[n]/device[n]:buffer:access/dev +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Buffer for device n access character device o major:minor numbers. + +What: /sys/.../device[n]:buffer/trigger +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + The name of the trigger source being used, as per string given + in /sys/class/iio/trigger[n]/name. + +What: /sys/.../device[n]:buffer/length +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Number of scans contained by the buffer. + +What: /sys/.../device[n]:buffer/bps +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Bytes per scan. Due to alignment fun, the scan may be larger + than implied directly by the scan_element parameters. + +What: /sys/.../device[n]:buffer/enable +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Actually start the buffer capture up. Will start trigger + if first device and appropriate. + +What: /sys/.../device[n]:buffer/alignment +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Minimum data alignment. Scan elements larger than this are aligned + to the nearest power of 2 times this. (may not be true in weird + hardware buffers that pack data well) + -- cgit v1.2.3 From ba5c6fbac6682240ac209a209b88a30be4a464fb Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 14:43:06 +0100 Subject: staging:iio: Directory name changes to match new ABI. Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/chrdev.h | 2 +- drivers/staging/iio/industrialio-core.c | 5 +++-- drivers/staging/iio/industrialio-ring.c | 13 +++++++++---- 3 files changed, 13 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/chrdev.h b/drivers/staging/iio/chrdev.h index f42bafb3a894..3f96f8696a41 100644 --- a/drivers/staging/iio/chrdev.h +++ b/drivers/staging/iio/chrdev.h @@ -94,7 +94,7 @@ struct iio_event_interface { struct iio_chrdev_minor_attr attr; struct module *owner; void *private; - char _name[20]; + char _name[35]; char _attrname[20]; }; diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index a4ce2215e54a..c55d0f3d4357 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -660,8 +660,9 @@ static int iio_device_register_eventset(struct iio_dev *dev_info) dev_info->event_interfaces[i].id = ret; snprintf(dev_info->event_interfaces[i]._name, 20, - "event_line%d", - dev_info->event_interfaces[i].id); + "%s:event%d", + dev_name(&dev_info->dev), + dev_info->event_interfaces[i].id); ret = iio_setup_ev_int(&dev_info->event_interfaces[i], (const char *)(dev_info diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c index 690df91020e9..0f19bd1b5760 100644 --- a/drivers/staging/iio/industrialio-ring.c +++ b/drivers/staging/iio/industrialio-ring.c @@ -164,8 +164,9 @@ __iio_request_ring_buffer_event_chrdev(struct iio_ring_buffer *buf, else buf->ev_int.id = ret; - snprintf(buf->ev_int._name, 20, - "ring_event_line%d", + snprintf(buf->ev_int._name, sizeof(buf->ev_int._name), + "%s:event%d", + dev_name(&buf->dev), buf->ev_int.id); ret = iio_setup_ev_int(&(buf->ev_int), buf->ev_int._name, @@ -226,7 +227,9 @@ __iio_request_ring_buffer_access_chrdev(struct iio_ring_buffer *buf, goto error_device_put; else buf->access_id = ret; - dev_set_name(&buf->access_dev, "ring_access%d", buf->access_id); + dev_set_name(&buf->access_dev, "%s:access%d", + dev_name(&buf->dev), + buf->access_id); ret = device_add(&buf->access_dev); if (ret < 0) { printk(KERN_ERR "failed to add the ring access dev\n"); @@ -280,7 +283,9 @@ int iio_ring_buffer_register(struct iio_ring_buffer *ring) else ring->id = ret; - dev_set_name(&ring->dev, "ring_buffer%d", ring->id); + dev_set_name(&ring->dev, "%s:buffer%d", + dev_name(ring->dev.parent), + ring->id); ret = device_add(&ring->dev); if (ret) goto error_free_id; -- cgit v1.2.3 From 2a6a255494605f5906222687fba5b45c03594d71 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 14:43:07 +0100 Subject: staging:iio:tsl2563: change lux to illuminance0_input to match new abi Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/light/tsl2563.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c index 1ba4aa392f6e..911c898c30e7 100644 --- a/drivers/staging/iio/light/tsl2563.c +++ b/drivers/staging/iio/light/tsl2563.c @@ -592,7 +592,7 @@ static ssize_t tsl2563_calib1_store(struct device *dev, * once I understand what they mean */ static DEVICE_ATTR(adc0, S_IRUGO, tsl2563_adc0_show, NULL); static DEVICE_ATTR(adc1, S_IRUGO, tsl2563_adc1_show, NULL); -static DEVICE_ATTR(lux, S_IRUGO, tsl2563_lux_show, NULL); +static DEVICE_ATTR(illuminance0_input, S_IRUGO, tsl2563_lux_show, NULL); static DEVICE_ATTR(calib0, S_IRUGO | S_IWUSR, tsl2563_calib0_show, tsl2563_calib0_store); static DEVICE_ATTR(calib1, S_IRUGO | S_IWUSR, @@ -601,7 +601,7 @@ static DEVICE_ATTR(calib1, S_IRUGO | S_IWUSR, static struct attribute *tsl2563_attributes[] = { &dev_attr_adc0.attr, &dev_attr_adc1.attr, - &dev_attr_lux.attr, + &dev_attr_illuminance0_input.attr, &dev_attr_calib0.attr, &dev_attr_calib1.attr, NULL -- cgit v1.2.3 From 758d988ce089ac7345bc03a9116b5ebf10dbfa9e Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 14:43:08 +0100 Subject: staging:iio: Remove naming via IDR's where no longer necessary under new abi. Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/lis3l02dq_ring.c | 2 +- drivers/staging/iio/accel/sca3000_core.c | 2 +- drivers/staging/iio/adc/max1363_ring.c | 2 +- drivers/staging/iio/industrialio-ring.c | 48 ++++++++---------------------- drivers/staging/iio/ring_generic.h | 2 +- 5 files changed, 16 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index bba4b0925ace..7617da81871c 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -581,7 +581,7 @@ error_iio_sw_rb_free: int lis3l02dq_initialize_ring(struct iio_ring_buffer *ring) { - return iio_ring_buffer_register(ring); + return iio_ring_buffer_register(ring, 0); } void lis3l02dq_uninitialize_ring(struct iio_ring_buffer *ring) diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index 45e47776d913..9485b132f6dd 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -1338,7 +1338,7 @@ static int __devinit __sca3000_probe(struct spi_device *spi, if (ret < 0) goto error_free_dev; regdone = 1; - ret = iio_ring_buffer_register(st->indio_dev->ring); + ret = iio_ring_buffer_register(st->indio_dev->ring, 0); if (ret < 0) goto error_unregister_dev; if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) { diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c index 6003f7e10a6e..f1e37f2cf4eb 100644 --- a/drivers/staging/iio/adc/max1363_ring.c +++ b/drivers/staging/iio/adc/max1363_ring.c @@ -255,5 +255,5 @@ void max1363_uninitialize_ring(struct iio_ring_buffer *ring) int max1363_initialize_ring(struct iio_ring_buffer *ring) { - return iio_ring_buffer_register(ring); + return iio_ring_buffer_register(ring, 0); }; diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c index 0f19bd1b5760..fc27d22a7ab1 100644 --- a/drivers/staging/iio/industrialio-ring.c +++ b/drivers/staging/iio/industrialio-ring.c @@ -20,19 +20,11 @@ #include #include #include -#include #include #include "iio.h" #include "ring_generic.h" -/* IDR for ring buffer identifier */ -static DEFINE_IDR(iio_ring_idr); -/* IDR for ring event identifier */ -static DEFINE_IDR(iio_ring_event_idr); -/* IDR for ring access identifier */ -static DEFINE_IDR(iio_ring_access_idr); - int iio_push_ring_event(struct iio_ring_buffer *ring_buf, int event_code, s64 timestamp) @@ -158,11 +150,8 @@ __iio_request_ring_buffer_event_chrdev(struct iio_ring_buffer *buf, struct device *dev) { int ret; - ret = iio_get_new_idr_val(&iio_ring_event_idr); - if (ret < 0) - goto error_ret; - else - buf->ev_int.id = ret; + + buf->ev_int.id = id; snprintf(buf->ev_int._name, sizeof(buf->ev_int._name), "%s:event%d", @@ -173,11 +162,9 @@ __iio_request_ring_buffer_event_chrdev(struct iio_ring_buffer *buf, owner, dev); if (ret) - goto error_free_id; + goto error_ret; return 0; -error_free_id: - iio_free_idr_val(&iio_ring_event_idr, buf->ev_int.id); error_ret: return ret; } @@ -186,7 +173,6 @@ static inline void __iio_free_ring_buffer_event_chrdev(struct iio_ring_buffer *buf) { iio_free_ev_int(&(buf->ev_int)); - iio_free_idr_val(&iio_ring_event_idr, buf->ev_int.id); } static void iio_ring_access_release(struct device *dev) @@ -222,18 +208,16 @@ __iio_request_ring_buffer_access_chrdev(struct iio_ring_buffer *buf, } buf->access_dev.devt = MKDEV(MAJOR(iio_devt), minor); - ret = iio_get_new_idr_val(&iio_ring_access_idr); - if (ret < 0) - goto error_device_put; - else - buf->access_id = ret; + + buf->access_id = id; + dev_set_name(&buf->access_dev, "%s:access%d", dev_name(&buf->dev), buf->access_id); ret = device_add(&buf->access_dev); if (ret < 0) { printk(KERN_ERR "failed to add the ring access dev\n"); - goto error_free_idr; + goto error_device_put; } cdev_init(&buf->access_handler.chrdev, &iio_ring_fileops); @@ -245,10 +229,9 @@ __iio_request_ring_buffer_access_chrdev(struct iio_ring_buffer *buf, goto error_device_unregister; } return 0; + error_device_unregister: device_unregister(&buf->access_dev); -error_free_idr: - iio_free_idr_val(&iio_ring_access_idr, buf->access_id); error_device_put: put_device(&buf->access_dev); @@ -257,7 +240,6 @@ error_device_put: static void __iio_free_ring_buffer_access_chrdev(struct iio_ring_buffer *buf) { - iio_free_idr_val(&iio_ring_access_idr, buf->access_id); device_unregister(&buf->access_dev); } @@ -274,21 +256,18 @@ void iio_ring_buffer_init(struct iio_ring_buffer *ring, } EXPORT_SYMBOL(iio_ring_buffer_init); -int iio_ring_buffer_register(struct iio_ring_buffer *ring) +int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id) { int ret; - ret = iio_get_new_idr_val(&iio_ring_idr); - if (ret < 0) - goto error_ret; - else - ring->id = ret; + + ring->id = id; dev_set_name(&ring->dev, "%s:buffer%d", dev_name(ring->dev.parent), ring->id); ret = device_add(&ring->dev); if (ret) - goto error_free_id; + goto error_ret; ret = __iio_request_ring_buffer_event_chrdev(ring, 0, @@ -309,8 +288,6 @@ error_free_ring_buffer_event_chrdev: __iio_free_ring_buffer_event_chrdev(ring); error_remove_device: device_del(&ring->dev); -error_free_id: - iio_free_idr_val(&iio_ring_idr, ring->id); error_ret: return ret; } @@ -321,7 +298,6 @@ void iio_ring_buffer_unregister(struct iio_ring_buffer *ring) __iio_free_ring_buffer_access_chrdev(ring); __iio_free_ring_buffer_event_chrdev(ring); device_del(&ring->dev); - iio_free_idr_val(&iio_ring_idr, ring->id); } EXPORT_SYMBOL(iio_ring_buffer_unregister); diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h index d74b5aea0112..0e443757b029 100644 --- a/drivers/staging/iio/ring_generic.h +++ b/drivers/staging/iio/ring_generic.h @@ -259,7 +259,7 @@ static inline void iio_put_ring_buffer(struct iio_ring_buffer *ring) container_of(d, struct iio_ring_buffer, dev) #define access_dev_to_iio_ring_buffer(d) \ container_of(d, struct iio_ring_buffer, access_dev) -int iio_ring_buffer_register(struct iio_ring_buffer *ring); +int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id); void iio_ring_buffer_unregister(struct iio_ring_buffer *ring); ssize_t iio_read_ring_length(struct device *dev, -- cgit v1.2.3 From c3fa0fddd6fed10eda57de8912a634890ee27a31 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 14:43:09 +0100 Subject: staging:iio:max1363 add support for max11606-max11617 Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 4 +- drivers/staging/iio/adc/max1363_core.c | 216 ++++++++++++++++++++++++++++++++- 2 files changed, 218 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 101ea4bc2370..afc8318a96d4 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -12,7 +12,9 @@ config MAX1363 Say yes here to build support for many MAXIM i2c analog to digital convertors (ADC). (max1361, max1362, max1363, max1364, max1136, max1136, max1137, max1138, max1139, max1236, max1237, max11238, - max1239) Provides direct access via sysfs. + max1239, max11606, max11607, max11608, max11609, max11610, + max11611, max11612, max11613, max11614, max11615, max11616, + max11617) Provides direct access via sysfs. config MAX1363_RING_BUFFER bool "MAXIM max1363: use ring buffer" diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index e82f3e78a1c5..c53bf6d8410c 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -434,6 +434,76 @@ static struct attribute_group max1238_scan_el_group = { .attrs = max1238_scan_el_attrs, }; + +static const enum max1363_modes max11607_mode_list[] = { + _s0, _s1, _s2, _s3, + s0to1, s0to2, s0to3, + s2to3, + d0m1, d2m3, d1m0, d3m2, + d0m1to2m3, d1m0to3m2, +}; + +static const enum max1363_modes max11608_mode_list[] = { + _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, + s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, s0to7, + s6to7, + d0m1, d2m3, d4m5, d6m7, + d1m0, d3m2, d5m4, d7m6, + d0m1to2m3, d0m1to4m5, d0m1to6m7, + d1m0to3m2, d1m0to5m4, d1m0to7m6, +}; + +static struct attribute *max11608_device_attrs[] = { + &iio_dev_attr_in0_raw.dev_attr.attr, + &iio_dev_attr_in1_raw.dev_attr.attr, + &iio_dev_attr_in2_raw.dev_attr.attr, + &iio_dev_attr_in3_raw.dev_attr.attr, + &iio_dev_attr_in4_raw.dev_attr.attr, + &iio_dev_attr_in5_raw.dev_attr.attr, + &iio_dev_attr_in6_raw.dev_attr.attr, + &iio_dev_attr_in7_raw.dev_attr.attr, + &iio_dev_attr_in0min1_raw.dev_attr.attr, + &iio_dev_attr_in2min3_raw.dev_attr.attr, + &iio_dev_attr_in4min5_raw.dev_attr.attr, + &iio_dev_attr_in6min7_raw.dev_attr.attr, + &iio_dev_attr_in1min0_raw.dev_attr.attr, + &iio_dev_attr_in3min2_raw.dev_attr.attr, + &iio_dev_attr_in5min4_raw.dev_attr.attr, + &iio_dev_attr_in7min6_raw.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + &iio_dev_attr_in_scale.dev_attr.attr, + NULL +}; + +static struct attribute_group max11608_dev_attr_group = { + .attrs = max11608_device_attrs, +}; + +static struct attribute *max11608_scan_el_attrs[] = { + &iio_scan_el_in0.dev_attr.attr, + &iio_scan_el_in1.dev_attr.attr, + &iio_scan_el_in2.dev_attr.attr, + &iio_scan_el_in3.dev_attr.attr, + &iio_scan_el_in4.dev_attr.attr, + &iio_scan_el_in5.dev_attr.attr, + &iio_scan_el_in6.dev_attr.attr, + &iio_scan_el_in7.dev_attr.attr, + &iio_scan_el_in0min1.dev_attr.attr, + &iio_scan_el_in2min3.dev_attr.attr, + &iio_scan_el_in4min5.dev_attr.attr, + &iio_scan_el_in6min7.dev_attr.attr, + &iio_scan_el_in1min0.dev_attr.attr, + &iio_scan_el_in3min2.dev_attr.attr, + &iio_scan_el_in5min4.dev_attr.attr, + &iio_scan_el_in7min6.dev_attr.attr, + &iio_dev_attr_in_precision.dev_attr.attr, +}; + +static struct attribute_group max11608_scan_el_group = { + .name = "scan_elements", + .attrs = max11608_scan_el_attrs, +}; + enum { max1361, max1362, max1363, @@ -446,6 +516,18 @@ enum { max1361, max1237, max1238, max1239, + max11606, + max11607, + max11608, + max11609, + max11610, + max11611, + max11612, + max11613, + max11614, + max11615, + max11616, + max11617, }; /* max1363 and max1368 tested - rest from data sheet */ @@ -574,7 +656,127 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = { .default_mode = s0to11, .dev_attrs = &max1238_dev_attr_group, .scan_attrs = &max1238_scan_el_group, - }, + }, { + .name = "max11606", + .num_inputs = 4, + .bits = 10, + .int_vref_mv = 4096, + .mode_list = max11607_mode_list, + .num_modes = ARRAY_SIZE(max11607_mode_list), + .default_mode = s0to3, + .dev_attrs = &max1363_dev_attr_group, + .scan_attrs = &max1363_scan_el_group, + }, { + .name = "max11607", + .num_inputs = 4, + .bits = 10, + .int_vref_mv = 2048, + .mode_list = max11607_mode_list, + .num_modes = ARRAY_SIZE(max11607_mode_list), + .default_mode = s0to3, + .dev_attrs = &max1363_dev_attr_group, + .scan_attrs = &max1363_scan_el_group, + }, { + .name = "max11608", + .num_inputs = 8, + .bits = 10, + .int_vref_mv = 4096, + .mode_list = max11608_mode_list, + .num_modes = ARRAY_SIZE(max11608_mode_list), + .default_mode = s0to7, + .dev_attrs = &max11608_dev_attr_group, + .scan_attrs = &max11608_scan_el_group, + }, { + .name = "max11609", + .num_inputs = 8, + .bits = 10, + .int_vref_mv = 2048, + .mode_list = max11608_mode_list, + .num_modes = ARRAY_SIZE(max11608_mode_list), + .default_mode = s0to7, + .dev_attrs = &max11608_dev_attr_group, + .scan_attrs = &max11608_scan_el_group, + }, { + .name = "max11610", + .num_inputs = 12, + .bits = 10, + .int_vref_mv = 4098, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .dev_attrs = &max1238_dev_attr_group, + .scan_attrs = &max1238_scan_el_group, + }, { + .name = "max11611", + .num_inputs = 12, + .bits = 10, + .int_vref_mv = 2048, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .dev_attrs = &max1238_dev_attr_group, + .scan_attrs = &max1238_scan_el_group, + }, { + .name = "max11612", + .num_inputs = 4, + .bits = 12, + .int_vref_mv = 4096, + .mode_list = max11607_mode_list, + .num_modes = ARRAY_SIZE(max11607_mode_list), + .default_mode = s0to3, + .dev_attrs = &max1363_dev_attr_group, + .scan_attrs = &max1363_scan_el_group, + }, { + .name = "max11613", + .num_inputs = 4, + .bits = 12, + .int_vref_mv = 2048, + .mode_list = max11607_mode_list, + .num_modes = ARRAY_SIZE(max11607_mode_list), + .default_mode = s0to3, + .dev_attrs = &max1363_dev_attr_group, + .scan_attrs = &max1363_scan_el_group, + }, { + .name = "max11614", + .num_inputs = 8, + .bits = 12, + .int_vref_mv = 4096, + .mode_list = max11608_mode_list, + .num_modes = ARRAY_SIZE(max11608_mode_list), + .default_mode = s0to7, + .dev_attrs = &max11608_dev_attr_group, + .scan_attrs = &max11608_scan_el_group, + }, { + .name = "max11615", + .num_inputs = 8, + .bits = 12, + .int_vref_mv = 2048, + .mode_list = max11608_mode_list, + .num_modes = ARRAY_SIZE(max11608_mode_list), + .default_mode = s0to7, + .dev_attrs = &max11608_dev_attr_group, + .scan_attrs = &max11608_scan_el_group, + }, { + .name = "max11616", + .num_inputs = 12, + .bits = 12, + .int_vref_mv = 4098, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .dev_attrs = &max1238_dev_attr_group, + .scan_attrs = &max1238_scan_el_group, + }, { + .name = "max11617", + .num_inputs = 12, + .bits = 12, + .int_vref_mv = 2048, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .dev_attrs = &max1238_dev_attr_group, + .scan_attrs = &max1238_scan_el_group, + } }; static int max1363_initial_setup(struct max1363_state *st) @@ -726,6 +928,18 @@ static const struct i2c_device_id max1363_id[] = { { "max1237", max1237 }, { "max1238", max1238 }, { "max1239", max1239 }, + { "max11606", max11606 }, + { "max11607", max11607 }, + { "max11608", max11608 }, + { "max11609", max11609 }, + { "max11610", max11610 }, + { "max11611", max11611 }, + { "max11612", max11612 }, + { "max11613", max11613 }, + { "max11614", max11614 }, + { "max11615", max11615 }, + { "max11616", max11616 }, + { "max11617", max11617 }, {} }; -- cgit v1.2.3 From 3bf877c1cc0d17ef471f21ae319fcb9c9211df61 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 14:43:10 +0100 Subject: staging:iio:max1363 add support for 8 bit equivalent devices, max1036-9, max11600-5 Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 12 +-- drivers/staging/iio/adc/max1363_core.c | 143 +++++++++++++++++++++++++++++++-- drivers/staging/iio/adc/max1363_ring.c | 23 ++++-- 3 files changed, 161 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index afc8318a96d4..0835fbc86c2a 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -10,11 +10,13 @@ config MAX1363 select MAX1363_RING_BUFFER help Say yes here to build support for many MAXIM i2c analog to digital - convertors (ADC). (max1361, max1362, max1363, max1364, max1136, - max1136, max1137, max1138, max1139, max1236, max1237, max11238, - max1239, max11606, max11607, max11608, max11609, max11610, - max11611, max11612, max11613, max11614, max11615, max11616, - max11617) Provides direct access via sysfs. + convertors (ADC). (max1361, max1362, max1363, max1364, max1036, + max1037, max1038, max1039, max1136, max1136, max1137, max1138, + max1139, max1236, max1237, max11238, max1239, max11600, max11601, + max11602, max11603, max11604, max11605, max11606, max11607, + max11608, max11609, max11610, max11611, max11612, max11613, + max11614, max11615, max11616, max11617) Provides direct access + via sysfs. config MAX1363_RING_BUFFER bool "MAXIM max1363: use ring buffer" diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index c53bf6d8410c..fa91cc14c64f 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -226,13 +226,24 @@ static ssize_t max1363_read_single_channel(struct device *dev, if (ret) goto error_ret; } - /* Get reading */ - data = i2c_master_recv(client, rxbuf, 2); - if (data < 0) { - ret = data; - goto error_ret; + if (st->chip_info->bits != 8) { + /* Get reading */ + data = i2c_master_recv(client, rxbuf, 2); + if (data < 0) { + ret = data; + goto error_ret; + } + + data = (s32)(rxbuf[1]) | ((s32)(rxbuf[0] & 0x0F)) << 8; + } else { + /* Get reading */ + data = i2c_master_recv(client, rxbuf, 1); + if (data < 0) { + ret = data; + goto error_ret; + } + data = rxbuf[0]; } - data = (s32)(rxbuf[1]) | ((s32)(rxbuf[0] & 0x0F)) << 8; } /* Pretty print the result */ len = sprintf(buf, "%u\n", data); @@ -508,6 +519,10 @@ enum { max1361, max1362, max1363, max1364, + max1036, + max1037, + max1038, + max1039, max1136, max1137, max1138, @@ -516,6 +531,12 @@ enum { max1361, max1237, max1238, max1239, + max11600, + max11601, + max11602, + max11603, + max11604, + max11605, max11606, max11607, max11608, @@ -576,6 +597,46 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = { .default_mode = s0to3, .dev_attrs = &max1363_dev_attr_group, .scan_attrs = &max1363_scan_el_group, + }, { + .name = "max1036", + .num_inputs = 4, + .bits = 8, + .int_vref_mv = 4096, + .mode_list = max1236_mode_list, + .num_modes = ARRAY_SIZE(max1236_mode_list), + .default_mode = s0to3, + .dev_attrs = &max1363_dev_attr_group, + .scan_attrs = &max1363_scan_el_group, + }, { + .name = "max1037", + .num_inputs = 4, + .bits = 8, + .int_vref_mv = 2048, + .mode_list = max1236_mode_list, + .num_modes = ARRAY_SIZE(max1236_mode_list), + .default_mode = s0to3, + .dev_attrs = &max1363_dev_attr_group, + .scan_attrs = &max1363_scan_el_group, + }, { + .name = "max1038", + .num_inputs = 12, + .bits = 8, + .int_vref_mv = 4096, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .dev_attrs = &max1238_dev_attr_group, + .scan_attrs = &max1238_scan_el_group, + }, { + .name = "max1039", + .num_inputs = 12, + .bits = 8, + .int_vref_mv = 2048, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .dev_attrs = &max1238_dev_attr_group, + .scan_attrs = &max1238_scan_el_group, }, { .name = "max1136", .num_inputs = 4, @@ -656,6 +717,66 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = { .default_mode = s0to11, .dev_attrs = &max1238_dev_attr_group, .scan_attrs = &max1238_scan_el_group, + }, { + .name = "max11600", + .num_inputs = 4, + .bits = 8, + .int_vref_mv = 4096, + .mode_list = max11607_mode_list, + .num_modes = ARRAY_SIZE(max11607_mode_list), + .default_mode = s0to3, + .dev_attrs = &max1363_dev_attr_group, + .scan_attrs = &max1363_scan_el_group, + }, { + .name = "max11601", + .num_inputs = 4, + .bits = 8, + .int_vref_mv = 2048, + .mode_list = max11607_mode_list, + .num_modes = ARRAY_SIZE(max11607_mode_list), + .default_mode = s0to3, + .dev_attrs = &max1363_dev_attr_group, + .scan_attrs = &max1363_scan_el_group, + }, { + .name = "max11602", + .num_inputs = 8, + .bits = 8, + .int_vref_mv = 4096, + .mode_list = max11608_mode_list, + .num_modes = ARRAY_SIZE(max11608_mode_list), + .default_mode = s0to7, + .dev_attrs = &max11608_dev_attr_group, + .scan_attrs = &max11608_scan_el_group, + }, { + .name = "max11603", + .num_inputs = 8, + .bits = 8, + .int_vref_mv = 2048, + .mode_list = max11608_mode_list, + .num_modes = ARRAY_SIZE(max11608_mode_list), + .default_mode = s0to7, + .dev_attrs = &max11608_dev_attr_group, + .scan_attrs = &max11608_scan_el_group, + }, { + .name = "max11604", + .num_inputs = 12, + .bits = 8, + .int_vref_mv = 4098, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .dev_attrs = &max1238_dev_attr_group, + .scan_attrs = &max1238_scan_el_group, + }, { + .name = "max11605", + .num_inputs = 12, + .bits = 8, + .int_vref_mv = 2048, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .dev_attrs = &max1238_dev_attr_group, + .scan_attrs = &max1238_scan_el_group, }, { .name = "max11606", .num_inputs = 4, @@ -920,6 +1041,10 @@ static const struct i2c_device_id max1363_id[] = { { "max1362", max1362 }, { "max1363", max1363 }, { "max1364", max1364 }, + { "max1036", max1036 }, + { "max1037", max1037 }, + { "max1038", max1038 }, + { "max1039", max1039 }, { "max1136", max1136 }, { "max1137", max1137 }, { "max1138", max1138 }, @@ -928,6 +1053,12 @@ static const struct i2c_device_id max1363_id[] = { { "max1237", max1237 }, { "max1238", max1238 }, { "max1239", max1239 }, + { "max11600", max11600 }, + { "max11601", max11601 }, + { "max11602", max11602 }, + { "max11603", max11603 }, + { "max11604", max11604 }, + { "max11605", max11605 }, { "max11606", max11606 }, { "max11607", max11607 }, { "max11608", max11608 }, diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c index f1e37f2cf4eb..85fde751a154 100644 --- a/drivers/staging/iio/adc/max1363_ring.c +++ b/drivers/staging/iio/adc/max1363_ring.c @@ -55,8 +55,11 @@ int max1363_single_channel_from_ring(long mask, struct max1363_state *st) count++; mask >>= 1; } - return ((int)(ring_data[count*2 + 0] & 0x0F) << 8) - + (int)(ring_data[count*2 + 1]); + if (st->chip_info->bits != 8) + return ((int)(ring_data[count*2 + 0] & 0x0F) << 8) + + (int)(ring_data[count*2 + 1]); + else + return ring_data[count]; error_free_ring_data: kfree(ring_data); @@ -90,7 +93,10 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev) numvals = hweight_long(st->current_mode->modemask); if (indio_dev->ring->access.set_bpd) { - d_size = numvals*2 + sizeof(s64); + if (st->chip_info->bits != 8) + d_size = numvals*2 + sizeof(s64); + else + d_size = numvals + sizeof(s64); if (d_size % 8) d_size += 8 - (d_size % 8); indio_dev->ring->access.set_bpd(indio_dev->ring, d_size); @@ -166,7 +172,10 @@ static void max1363_poll_bh_to_ring(struct work_struct *work_s) unsigned long numvals = hweight_long(st->current_mode->modemask); /* Ensure the timestamp is 8 byte aligned */ - d_size = numvals*2 + sizeof(s64); + if (st->chip_info->bits != 8) + d_size = numvals*2 + sizeof(s64); + else + d_size = numvals + sizeof(s64); if (d_size % sizeof(s64)) d_size += sizeof(s64) - (d_size % sizeof(s64)); @@ -184,8 +193,10 @@ static void max1363_poll_bh_to_ring(struct work_struct *work_s) rxbuf = kmalloc(d_size, GFP_KERNEL); if (rxbuf == NULL) return; - - b_sent = i2c_master_recv(st->client, rxbuf, numvals*2); + if (st->chip_info->bits != 8) + b_sent = i2c_master_recv(st->client, rxbuf, numvals*2); + else + b_sent = i2c_master_recv(st->client, rxbuf, numvals); if (b_sent < 0) goto done; -- cgit v1.2.3 From 8474ddd7cba04c2e8d8691abda32ae0f4a684137 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 14:43:11 +0100 Subject: staging:iio:ring_sw: Fix incorrect test on successful read of last value, causes infinite loop Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/ring_sw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c index f8de45dc4b6e..5ee3e4533515 100644 --- a/drivers/staging/iio/ring_sw.c +++ b/drivers/staging/iio/ring_sw.c @@ -295,7 +295,7 @@ again: return -EAGAIN; memcpy(data, last_written_p_copy, ring->buf.bpd); - if (unlikely(ring->last_written_p >= last_written_p_copy)) + if (unlikely(ring->last_written_p != last_written_p_copy)) goto again; iio_unmark_sw_rb_in_use(&ring->buf); -- cgit v1.2.3 From e9124afad3d419213b1cd80e40bcf65445ba11f9 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 14:43:12 +0100 Subject: staging:iio:tsl2563 add a name attribute under the iio Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/light/tsl2563.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c index 911c898c30e7..da3d51c52c7c 100644 --- a/drivers/staging/iio/light/tsl2563.c +++ b/drivers/staging/iio/light/tsl2563.c @@ -598,12 +598,24 @@ static DEVICE_ATTR(calib0, S_IRUGO | S_IWUSR, static DEVICE_ATTR(calib1, S_IRUGO | S_IWUSR, tsl2563_calib1_show, tsl2563_calib1_store); +static ssize_t tsl2563_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct tsl2563_chip *chip = indio_dev->dev_data; + return sprintf(buf, "%s\n", chip->client->name); +} + +DEVICE_ATTR(name, S_IRUGO, tsl2563_show_name, NULL); + static struct attribute *tsl2563_attributes[] = { &dev_attr_adc0.attr, &dev_attr_adc1.attr, &dev_attr_illuminance0_input.attr, &dev_attr_calib0.attr, &dev_attr_calib1.attr, + &dev_attr_name.attr, NULL }; -- cgit v1.2.3 From 9d8ae6c884ef855c4cb0e423caa993e73b29ef67 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 14:43:13 +0100 Subject: staging:iio:Documentation: Rewrite example for new abi. Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/iio_utils.h | 277 ++++++++++++--------- .../iio/Documentation/lis3l02dqbuffersimple.c | 234 +++++++++++------ 2 files changed, 313 insertions(+), 198 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index d24006aedd5a..a4555e6f133f 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h @@ -7,140 +7,173 @@ * the Free Software Foundation. */ +/* Made up value to limit allocation sizes */ +#include +#include + +#define IIO_MAX_NAME_LENGTH 30 + #define IIO_EVENT_CODE_RING_50_FULL 200 #define IIO_EVENT_CODE_RING_75_FULL 201 #define IIO_EVENT_CODE_RING_100_FULL 202 +const char *iio_dir = "/sys/bus/iio/devices/"; + struct iio_event_data { int id; __s64 timestamp; }; - -inline char *find_ring_subelement(const char *directory, const char *subelement) -{ - DIR *dp; - const struct dirent *ent; - int pos; - char temp[100]; - char *returnstring; - dp = opendir(directory); - if (dp == NULL) { - printf("could not directory: %s\n", directory); - return NULL; - } - while (ent = readdir(dp), ent != NULL) { - if (strcmp(ent->d_name, ".") != 0 && - strcmp(ent->d_name, "..") != 0) { - if (strncmp(ent->d_name, subelement, strlen(subelement)) == 0) { - int length = sprintf(temp, "%s%s%s", directory, ent->d_name, "/"); - returnstring = malloc(length+1); - strncpy(returnstring, temp, length+1); - return returnstring; - - } - } - } - return 0; -} - - -char *find_type_by_name(const char *name, const char *type) +/** + * find_type_by_name() - function to match top level types by name + * @name: top level type instance name + * @type: the type of top level instance being sort + * + * Typical types this is used for are device and trigger. + **/ +inline int find_type_by_name(const char *name, const char *type) { - const char *iio_dir = "/sys/bus/iio/devices/"; const struct dirent *ent; - int cnt, pos, pos2; + int number, numstrlen; FILE *nameFile; DIR *dp; - char thisname[100]; - char temp[100]; - - char *returnstring = NULL; + char thisname[IIO_MAX_NAME_LENGTH]; + char *filename; struct stat Stat; - pos = sprintf(temp, "%s", iio_dir); + dp = opendir(iio_dir); if (dp == NULL) { printf("No industrialio devices available"); - return NULL; + return -ENODEV; } + while (ent = readdir(dp), ent != NULL) { - cnt++; - /*reject . and .. */ if (strcmp(ent->d_name, ".") != 0 && - strcmp(ent->d_name, "..") != 0) { - /*make sure it isn't a trigger!*/ - if (strncmp(ent->d_name, type, strlen(type)) == 0) { - /* build full path to new file */ - pos2 = pos + sprintf(temp + pos, "%s/", ent->d_name); - sprintf(temp + pos2, "name"); - printf("search location %s\n", temp); - nameFile = fopen(temp, "r"); - if (!nameFile) { - sprintf(temp + pos2, "modalias", ent->d_name); - nameFile = fopen(temp, "r"); - if (!nameFile) { - printf("Failed to find a name for device\n"); - return NULL; - } - } + strcmp(ent->d_name, "..") != 0 && + strlen(ent->d_name) > strlen(type) && + strncmp(ent->d_name, type, strlen(type)) == 0) { + numstrlen = sscanf(ent->d_name + strlen(type), + "%d", + &number); + /* verify the next character is not a colon */ + if (strncmp(ent->d_name + strlen(type) + numstrlen, + ":", + 1) != 0) { + filename = malloc(strlen(iio_dir) + + strlen(type) + + 1 + + numstrlen + + 1); + if (filename == NULL) + return -ENOMEM; + sprintf(filename, "%s%s%d/name", + iio_dir, + type, + number); + nameFile = fopen(filename, "r"); + if (!nameFile) + continue; + free(filename); fscanf(nameFile, "%s", thisname); - if (strcmp(name, thisname) == 0) { - returnstring = malloc(strlen(temp) + 1); - sprintf(temp + pos2, ""); - strcpy(returnstring, temp); - return returnstring; - } + if (strcmp(name, thisname) == 0) + return number; fclose(nameFile); - } } } + return -ENODEV; } -int write_sysfs_int(char *filename, char *basedir, int val) +inline int _write_sysfs_int(char *filename, char *basedir, int val, int verify) { int ret; - FILE *sysfsfp; - char temp[100]; - sprintf(temp, "%s%s", basedir, filename); + FILE *sysfsfp; + int test; + char *temp = malloc(strlen(basedir) + strlen(filename) + 2); + if (temp == NULL) + return -ENOMEM; + sprintf(temp, "%s/%s", basedir, filename); sysfsfp = fopen(temp, "w"); - if (sysfsfp == NULL) - return -1; + if (sysfsfp == NULL) { + printf("failed to open %s\n", temp); + ret = -errno; + goto error_free; + } fprintf(sysfsfp, "%d", val); fclose(sysfsfp); - return 0; + if (verify) { + sysfsfp = fopen(temp, "r"); + if (sysfsfp == NULL) { + printf("failed to open %s\n", temp); + ret = -errno; + goto error_free; + } + fscanf(sysfsfp, "%d", &test); + if (test != val) { + printf("Possible failure in int write %d to %s%s\n", + val, + basedir, + filename); + ret = -1; + } + } +error_free: + free(temp); + return ret; +} + +int write_sysfs_int(char *filename, char *basedir, int val) +{ + return _write_sysfs_int(filename, basedir, val, 0); } int write_sysfs_int_and_verify(char *filename, char *basedir, int val) +{ + return _write_sysfs_int(filename, basedir, val, 1); +} + +int _write_sysfs_string(char *filename, char *basedir, char *val, int verify) { int ret; FILE *sysfsfp; - char temp[100]; - int test; - - sprintf(temp, "%s%s", basedir, filename); + char *temp = malloc(strlen(basedir) + strlen(filename) + 2); + if (temp == NULL) { + printf("Memory allocation failed\n"); + return -ENOMEM; + } + sprintf(temp, "%s/%s", basedir, filename); sysfsfp = fopen(temp, "w"); - if (sysfsfp == NULL) - return -1; - fprintf(sysfsfp, "%d", val); + if (sysfsfp == NULL) { + printf("Could not open %s\n", temp); + ret = -errno; + goto error_free; + } + fprintf(sysfsfp, "%s", val); fclose(sysfsfp); - - sysfsfp = fopen(temp, "r"); - if (sysfsfp == NULL) - return -1; - fscanf(sysfsfp, "%d", &test); - if (test != val) { - printf("Possible failure in int write %d to %s%s\n", - val, - basedir, - filename); - return -1; + if (verify) { + sysfsfp = fopen(temp, "r"); + if (sysfsfp == NULL) { + ret = -errno; + goto error_free; + } + fscanf(sysfsfp, "%s", temp); + if (strcmp(temp, val) != 0) { + printf("Possible failure in string write of %s " + "Should be %s " + "writen to %s\%s\n", + temp, + val, + basedir, + filename); + ret = -1; + } } +error_free: + free(temp); - return 0; + return ret; } - /** * write_sysfs_string_and_verify() - string write, readback and verify * @filename: name of file to write to @@ -149,40 +182,54 @@ int write_sysfs_int_and_verify(char *filename, char *basedir, int val) **/ int write_sysfs_string_and_verify(char *filename, char *basedir, char *val) { - int ret; - FILE *sysfsfp; - char temp[100]; - sprintf(temp, "%s%s", basedir, filename); - sysfsfp = fopen(temp, "w"); - if (sysfsfp == NULL) - return -1; - fprintf(sysfsfp, "%s", val); - fclose(sysfsfp); + return _write_sysfs_string(filename, basedir, val, 1); +} - sysfsfp = fopen(temp, "r"); - if (sysfsfp == NULL) - return -1; - fscanf(sysfsfp, "%s", temp); - if (strcmp(temp, val) != 0) { - printf("Possible failure in string write %s to %s%s \n", - val, - basedir, - filename); - return -1; - } - return 0; +int write_sysfs_string(char *filename, char *basedir, char *val) +{ + return _write_sysfs_string(filename, basedir, val, 0); } int read_sysfs_posint(char *filename, char *basedir) { int ret; FILE *sysfsfp; - char temp[100]; - sprintf(temp, "%s%s", basedir, filename); + char *temp = malloc(strlen(basedir) + strlen(filename) + 2); + if (temp == NULL) { + printf("Memory allocation failed"); + return -ENOMEM; + } + sprintf(temp, "%s/%s", basedir, filename); sysfsfp = fopen(temp, "r"); - if (sysfsfp == NULL) - return -1; + if (sysfsfp == NULL) { + ret = -errno; + goto error_free; + } fscanf(sysfsfp, "%d\n", &ret); fclose(sysfsfp); +error_free: + free(temp); + return ret; +} + +int read_sysfs_float(char *filename, char *basedir, float *val) +{ + float ret = 0; + FILE *sysfsfp; + char *temp = malloc(strlen(basedir) + strlen(filename) + 2); + if (temp == NULL) { + printf("Memory allocation failed"); + return -ENOMEM; + } + sprintf(temp, "%s/%s", basedir, filename); + sysfsfp = fopen(temp, "r"); + if (sysfsfp == NULL) { + ret = -errno; + goto error_free; + } + fscanf(sysfsfp, "%f\n", val); + fclose(sysfsfp); +error_free: + free(temp); return ret; } diff --git a/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c b/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c index 08e012fa8460..3a580284020c 100644 --- a/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c +++ b/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c @@ -1,4 +1,4 @@ -/* Industrialio test ring buffer with a lis3l02dq acceleromter +/* Industrialio ring buffer with a lis3l02dq accelerometer * * Copyright (c) 2008 Jonathan Cameron * @@ -6,125 +6,181 @@ * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. * - * Assumes suitable udev rules are used to create the dev nodes as named here. + * This program is primarily intended as an example application. */ #include #include #include #include -#include -#include #include #include - #include #include "iio_utils.h" -static const char *ring_access = "/dev/iio/lis3l02dq_ring_access"; -static const char *ring_event = "/dev/iio/lis3l02dq_ring_event"; -static const char *device_name = "lis3l02dq"; -static const char *trigger_name = "lis3l02dq-dev0"; -static int NumVals = 3; -static int scan_ts = 1; -static int RingLength = 128; +const char *device_name = "lis3l02dq"; +const char *trigger_name_base = "lis3l02dq-dev"; +const int num_vals = 3; +const int scan_ts = 1; +const int buf_len = 128; +const int num_loops = 10; /* * Could get this from ring bps, but only after starting the ring - * which is a bit late for it to be useful + * which is a bit late for it to be useful. + * + * Todo: replace with much more generic version based on scan_elements + * directory. */ -int size_from_scanmode(int numVals, int timestamp) +int size_from_scanmode(int num_vals, int timestamp) { - if (numVals && timestamp) + if (num_vals && timestamp) return 16; else if (timestamp) return 8; else - return numVals*2; + return num_vals*2; } int main(int argc, char **argv) { + int ret; int i, j, k, toread; FILE *fp_ev; int fp; + + char *trigger_name, *dev_dir_name, *buf_dir_name; char *data; size_t read_size; struct iio_event_data dat; + int dev_num, trig_num; + + char *buffer_access, *buffer_event; + const char *iio_dir = "/sys/bus/iio/devices/"; + int scan_size; + float gain = 1; - char *BaseDirectoryName, - *TriggerDirectoryName, - *RingBufferDirectoryName; - BaseDirectoryName = find_type_by_name(device_name, "device"); - if (BaseDirectoryName == NULL) { - printf("Failed to find the %s \n", device_name); - return -1; + /* Find out which iio device is the accelerometer. */ + dev_num = find_type_by_name(device_name, "device"); + if (dev_num < 0) { + printf("Failed to find the %s\n", device_name); + ret = -ENODEV; + goto error_ret; } - TriggerDirectoryName = find_type_by_name(trigger_name, "trigger"); - if (TriggerDirectoryName == NULL) { + printf("iio device number being used is %d\n", dev_num); + asprintf(&dev_dir_name, "%sdevice%d", iio_dir, dev_num); + + /* + * Build the trigger name. + * In this case we want the lis3l02dq's data ready trigger + * for this lis3l02dq. The naming is lis3l02dq_dev[n], where + * n matches the device number found above. + */ + ret = asprintf(&trigger_name, "%s%d", trigger_name_base, dev_num); + if (ret < 0) { + ret = -ENOMEM; + goto error_free_dev_dir_name; + } + + /* + * Find the trigger by name. + * This is techically unecessary here as we only need to + * refer to the trigger by name and that name is already + * known. + */ + trig_num = find_type_by_name(trigger_name, "trigger"); + if (trig_num < 0) { printf("Failed to find the %s\n", trigger_name); - return -1; + ret = -ENODEV; + goto error_free_triggername; } - RingBufferDirectoryName = find_ring_subelement(BaseDirectoryName, - "ring_buffer"); - if (RingBufferDirectoryName == NULL) { - printf("Failed to find ring buffer\n"); - return -1; + printf("iio trigger number being used is %d\n", trig_num); + + /* + * Read in the scale value - in a more generic case, first + * check for accel_scale, then the indivual channel scales + */ + ret = read_sysfs_float("accel_scale", dev_dir_name, &gain); + if (ret) + goto error_free_triggername;; + + /* + * Construct the directory name for the associated buffer. + * As we know that the lis3l02dq has only one buffer this may + * be built rather than found. + */ + ret = asprintf(&buf_dir_name, "%sdevice%d:buffer0", iio_dir, dev_num); + if (ret < 0) { + ret = -ENOMEM; + goto error_free_triggername; } - - if (write_sysfs_string_and_verify("trigger/current_trigger", - BaseDirectoryName, - (char *)trigger_name) < 0) { - printf("Failed to write current_trigger file \n"); - return -1; + /* Set the device trigger to be the data rdy trigger found above */ + ret = write_sysfs_string_and_verify("trigger/current_trigger", + dev_dir_name, + trigger_name); + if (ret < 0) { + printf("Failed to write current_trigger file\n"); + goto error_free_buf_dir_name; } /* Setup ring buffer parameters */ - if (write_sysfs_int("length", RingBufferDirectoryName, - RingLength) < 0) { - printf("Failed to open the ring buffer length file \n"); - return -1; - } + ret = write_sysfs_int("length", buf_dir_name, buf_len); + if (ret < 0) + goto error_free_buf_dir_name; - /* Enable the ring buffer */ - if (write_sysfs_int("ring_enable", RingBufferDirectoryName, 1) < 0) { - printf("Failed to open the ring buffer control file \n"); - return -1; - }; + /* Enable the buffer */ + ret = write_sysfs_int("ring_enable", buf_dir_name, 1); + if (ret < 0) + goto error_free_buf_dir_name; - data = malloc(size_from_scanmode(NumVals, scan_ts)*RingLength); + data = malloc(size_from_scanmode(num_vals, scan_ts)*buf_len); if (!data) { - printf("Could not allocate space for usespace data store\n"); - return -1; + ret = -ENOMEM; + goto error_free_buf_dir_name; + } + + ret = asprintf(&buffer_access, + "/dev/device%d:buffer0:access0", + dev_num); + if (ret < 0) { + ret = -ENOMEM; + goto error_free_data; } + ret = asprintf(&buffer_event, "/dev/device%d:buffer0:event0", dev_num); + if (ret < 0) { + ret = -ENOMEM; + goto error_free_data; + } /* Attempt to open non blocking the access dev */ - fp = open(ring_access, O_RDONLY | O_NONBLOCK); + fp = open(buffer_access, O_RDONLY | O_NONBLOCK); if (fp == -1) { /*If it isn't there make the node */ - printf("Failed to open %s\n", ring_access); - return -1; + printf("Failed to open %s\n", buffer_access); + ret = -errno; + goto error_free_buffer_event; } /* Attempt to open the event access dev (blocking this time) */ - fp_ev = fopen(ring_event, "rb"); + fp_ev = fopen(buffer_event, "rb"); if (fp_ev == NULL) { - printf("Failed to open %s\n", ring_event); - return -1; + printf("Failed to open %s\n", buffer_event); + ret = -errno; + goto error_close_buffer_access; } /* Wait for events 10 times */ - for (j = 0; j < 10; j++) { + for (j = 0; j < num_loops; j++) { read_size = fread(&dat, 1, sizeof(struct iio_event_data), fp_ev); switch (dat.id) { case IIO_EVENT_CODE_RING_100_FULL: - toread = RingLength; + toread = buf_len; break; case IIO_EVENT_CODE_RING_75_FULL: - toread = RingLength*3/4; + toread = buf_len*3/4; break; case IIO_EVENT_CODE_RING_50_FULL: - toread = RingLength/2; + toread = buf_len/2; break; default: printf("Unexpecteded event code\n"); @@ -132,39 +188,51 @@ int main(int argc, char **argv) } read_size = read(fp, data, - toread*size_from_scanmode(NumVals, scan_ts)); + toread*size_from_scanmode(num_vals, scan_ts)); if (read_size == -EAGAIN) { - printf("nothing available \n"); + printf("nothing available\n"); continue; } - - for (i = 0; - i < read_size/size_from_scanmode(NumVals, scan_ts); - i++) { - for (k = 0; k < NumVals; k++) { - __s16 val = *(__s16 *)(&data[i*size_from_scanmode(NumVals, scan_ts) + scan_size = size_from_scanmode(num_vals, scan_ts); + for (i = 0; i < read_size/scan_size; i++) { + for (k = 0; k < num_vals; k++) { + __s16 val = *(__s16 *)(&data[i*scan_size + (k)*2]); - printf("%05d ", val); + printf("%05f ", (float)val*gain); } printf(" %lld\n", - *(__s64 *)(&data[(i+1)*size_from_scanmode(NumVals, scan_ts) + *(__s64 *)(&data[(i + 1) + *size_from_scanmode(num_vals, + scan_ts) - sizeof(__s64)])); } } /* Stop the ring buffer */ - if (write_sysfs_int("ring_enable", RingBufferDirectoryName, 0) < 0) { - printf("Failed to open the ring buffer control file \n"); - return -1; - }; - - /* Disconnect from the trigger - writing something that doesn't exist.*/ - write_sysfs_string_and_verify("trigger/current_trigger", - BaseDirectoryName, "NULL"); - free(BaseDirectoryName); - free(TriggerDirectoryName); - free(RingBufferDirectoryName); + ret = write_sysfs_int("ring_enable", buf_dir_name, 0); + if (ret < 0) + goto error_close_buffer_event; + + /* Disconnect from the trigger - just write a dummy name.*/ + write_sysfs_string("trigger/current_trigger", + dev_dir_name, "NULL"); + +error_close_buffer_event: + fclose(fp_ev); +error_close_buffer_access: + close(fp); +error_free_data: free(data); - - return 0; +error_free_buffer_access: + free(buffer_access); +error_free_buffer_event: + free(buffer_event); +error_free_buf_dir_name: + free(buf_dir_name); +error_free_triggername: + free(trigger_name); +error_free_dev_dir_name: + free(dev_dir_name); +error_ret: + return ret; } -- cgit v1.2.3 From 1e3864e63576e33dd1b26ab750ffaab3066aaba9 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Tue, 4 May 2010 14:43:14 +0100 Subject: staging:iio:imu ADIS16300 driver Signed-off-by: Barry Song Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Kconfig | 1 + drivers/staging/iio/Makefile | 1 + drivers/staging/iio/adc/adc.h | 3 + drivers/staging/iio/gyro/gyro.h | 76 +++ drivers/staging/iio/imu/Kconfig | 14 + drivers/staging/iio/imu/Makefile | 6 + drivers/staging/iio/imu/adis16300.h | 203 +++++++ drivers/staging/iio/imu/adis16300_core.c | 833 ++++++++++++++++++++++++++++ drivers/staging/iio/imu/adis16300_ring.c | 233 ++++++++ drivers/staging/iio/imu/adis16300_trigger.c | 127 +++++ 10 files changed, 1497 insertions(+) create mode 100644 drivers/staging/iio/gyro/gyro.h create mode 100644 drivers/staging/iio/imu/Kconfig create mode 100644 drivers/staging/iio/imu/Makefile create mode 100644 drivers/staging/iio/imu/adis16300.h create mode 100644 drivers/staging/iio/imu/adis16300_core.c create mode 100644 drivers/staging/iio/imu/adis16300_ring.c create mode 100644 drivers/staging/iio/imu/adis16300_trigger.c (limited to 'drivers') diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index ace99f6d1166..ed38ef4db444 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -41,6 +41,7 @@ config IIO_TRIGGER source "drivers/staging/iio/accel/Kconfig" source "drivers/staging/iio/adc/Kconfig" +source "drivers/staging/iio/imu/Kconfig" source "drivers/staging/iio/light/Kconfig" source "drivers/staging/iio/trigger/Kconfig" diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile index 7ec021810a77..92b81c2b895d 100644 --- a/drivers/staging/iio/Makefile +++ b/drivers/staging/iio/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_IIO_SW_RING) += ring_sw.o obj-y += accel/ obj-y += adc/ +obj-y += imu/ obj-y += light/ obj-y += trigger/ \ No newline at end of file diff --git a/drivers/staging/iio/adc/adc.h b/drivers/staging/iio/adc/adc.h index 46f0d08b4769..04eb16fd0a95 100644 --- a/drivers/staging/iio/adc/adc.h +++ b/drivers/staging/iio/adc/adc.h @@ -16,6 +16,9 @@ #define IIO_DEV_ATTR_IN_RAW(_num, _show, _addr) \ IIO_DEVICE_ATTR(in##_num##_raw, S_IRUGO, _show, NULL, _addr) +#define IIO_DEV_ATTR_IN_NAMED_RAW(_name, _show, _addr) \ + IIO_DEVICE_ATTR(in_##_name##_raw, S_IRUGO, _show, NULL, _addr) + #define IIO_DEV_ATTR_IN_DIFF_RAW(_nump, _numn, _show, _addr) \ IIO_DEVICE_ATTR_NAMED(in##_nump##min##_numn##_raw, \ in##_nump-in##_numn##_raw, \ diff --git a/drivers/staging/iio/gyro/gyro.h b/drivers/staging/iio/gyro/gyro.h new file mode 100644 index 000000000000..7c4dcf2f4a6a --- /dev/null +++ b/drivers/staging/iio/gyro/gyro.h @@ -0,0 +1,76 @@ + +#include "../sysfs.h" + +/* Gyroscope types of attribute */ + +#define IIO_DEV_ATTR_GYRO_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(gyro_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_GYRO_X_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(gyro_x_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_GYRO_Y_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(gyro_y_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_GYRO_Z_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(gyro_z_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_GYRO_X_GAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(gyro_x_gain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_GYRO_Y_GAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(gyro_y_gain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_GYRO_Z_GAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(gyro_z_gain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_GYRO_SCALE(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(gyro_scale, S_IRUGO, _show, _store, _addr) + +#define IIO_DEV_ATTR_GYRO(_show, _addr) \ + IIO_DEVICE_ATTR(gyro, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_GYRO_X(_show, _addr) \ + IIO_DEVICE_ATTR(gyro_x, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_GYRO_Y(_show, _addr) \ + IIO_DEVICE_ATTR(gyro_y, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_GYRO_Z(_show, _addr) \ + IIO_DEVICE_ATTR(gyro_z, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_TEMP_X(_show, _addr) \ + IIO_DEVICE_ATTR(temp_x, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_TEMP_Y(_show, _addr) \ + IIO_DEVICE_ATTR(temp_y, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_TEMP_Z(_show, _addr) \ + IIO_DEVICE_ATTR(temp_z, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_INCLI_X(_show, _addr) \ + IIO_DEVICE_ATTR(incli_x, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_INCLI_Y(_show, _addr) \ + IIO_DEVICE_ATTR(incli_y, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_INCLI_Z(_show, _addr) \ + IIO_DEVICE_ATTR(incli_z, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_INCLI_X_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(incli_x_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_INCLI_Y_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(incli_y_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_INCLI_Z_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(incli_z_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_ROT(_show, _addr) \ + IIO_DEVICE_ATTR(rot, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_ROT_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(rot_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_ANGL(_show, _addr) \ + IIO_DEVICE_ATTR(angl, S_IRUGO, _show, NULL, _addr) diff --git a/drivers/staging/iio/imu/Kconfig b/drivers/staging/iio/imu/Kconfig new file mode 100644 index 000000000000..3fe47161e768 --- /dev/null +++ b/drivers/staging/iio/imu/Kconfig @@ -0,0 +1,14 @@ +# +# IIO imu drivers configuration +# +comment "Inertial measurement units" + +config ADIS16300 + tristate "Analog Devices ADIS16300 IMU SPI driver" + depends on SPI + select IIO_SW_RING + select IIO_RING_BUFFER + select IIO_TRIGGER + help + Say yes here to build support for Analog Devices adis16300 four degrees + of freedom inertial sensor. diff --git a/drivers/staging/iio/imu/Makefile b/drivers/staging/iio/imu/Makefile new file mode 100644 index 000000000000..4cd5984137b0 --- /dev/null +++ b/drivers/staging/iio/imu/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for Inertial Measurement Units +# +adis16300-y := adis16300_core.o +adis16300-$(CONFIG_IIO_RING_BUFFER) += adis16300_ring.o adis16300_trigger.o +obj-$(CONFIG_ADIS16300) += adis16300.o diff --git a/drivers/staging/iio/imu/adis16300.h b/drivers/staging/iio/imu/adis16300.h new file mode 100644 index 000000000000..77d890d12000 --- /dev/null +++ b/drivers/staging/iio/imu/adis16300.h @@ -0,0 +1,203 @@ +#ifndef SPI_ADIS16300_H_ +#define SPI_ADIS16300_H_ + +#define ADIS16300_STARTUP_DELAY 220 /* ms */ + +#define ADIS16300_READ_REG(a) a +#define ADIS16300_WRITE_REG(a) ((a) | 0x80) + +#define ADIS16300_FLASH_CNT 0x00 /* Flash memory write count */ +#define ADIS16300_SUPPLY_OUT 0x02 /* Power supply measurement */ +#define ADIS16300_XGYRO_OUT 0x04 /* X-axis gyroscope output */ +#define ADIS16300_XACCL_OUT 0x0A /* X-axis accelerometer output */ +#define ADIS16300_YACCL_OUT 0x0C /* Y-axis accelerometer output */ +#define ADIS16300_ZACCL_OUT 0x0E /* Z-axis accelerometer output */ +#define ADIS16300_TEMP_OUT 0x10 /* Temperature output */ +#define ADIS16300_XINCLI_OUT 0x12 /* X-axis inclinometer output measurement */ +#define ADIS16300_YINCLI_OUT 0x14 /* Y-axis inclinometer output measurement */ +#define ADIS16300_AUX_ADC 0x16 /* Auxiliary ADC measurement */ + +/* Calibration parameters */ +#define ADIS16300_XGYRO_OFF 0x1A /* X-axis gyroscope bias offset factor */ +#define ADIS16300_XACCL_OFF 0x20 /* X-axis acceleration bias offset factor */ +#define ADIS16300_YACCL_OFF 0x22 /* Y-axis acceleration bias offset factor */ +#define ADIS16300_ZACCL_OFF 0x24 /* Z-axis acceleration bias offset factor */ + +#define ADIS16300_GPIO_CTRL 0x32 /* Auxiliary digital input/output control */ +#define ADIS16300_MSC_CTRL 0x34 /* Miscellaneous control */ +#define ADIS16300_SMPL_PRD 0x36 /* Internal sample period (rate) control */ +#define ADIS16300_SENS_AVG 0x38 /* Dynamic range and digital filter control */ +#define ADIS16300_SLP_CNT 0x3A /* Sleep mode control */ +#define ADIS16300_DIAG_STAT 0x3C /* System status */ + +/* Alarm functions */ +#define ADIS16300_GLOB_CMD 0x3E /* System command */ +#define ADIS16300_ALM_MAG1 0x26 /* Alarm 1 amplitude threshold */ +#define ADIS16300_ALM_MAG2 0x28 /* Alarm 2 amplitude threshold */ +#define ADIS16300_ALM_SMPL1 0x2A /* Alarm 1 sample size */ +#define ADIS16300_ALM_SMPL2 0x2C /* Alarm 2 sample size */ +#define ADIS16300_ALM_CTRL 0x2E /* Alarm control */ +#define ADIS16300_AUX_DAC 0x30 /* Auxiliary DAC data */ + +#define ADIS16300_ERROR_ACTIVE (1<<14) +#define ADIS16300_NEW_DATA (1<<15) + +/* MSC_CTRL */ +#define ADIS16300_MSC_CTRL_MEM_TEST (1<<11) +#define ADIS16300_MSC_CTRL_INT_SELF_TEST (1<<10) +#define ADIS16300_MSC_CTRL_NEG_SELF_TEST (1<<9) +#define ADIS16300_MSC_CTRL_POS_SELF_TEST (1<<8) +#define ADIS16300_MSC_CTRL_GYRO_BIAS (1<<7) +#define ADIS16300_MSC_CTRL_ACCL_ALIGN (1<<6) +#define ADIS16300_MSC_CTRL_DATA_RDY_EN (1<<2) +#define ADIS16300_MSC_CTRL_DATA_RDY_POL_HIGH (1<<1) +#define ADIS16300_MSC_CTRL_DATA_RDY_DIO2 (1<<0) + +/* SMPL_PRD */ +#define ADIS16300_SMPL_PRD_TIME_BASE (1<<7) +#define ADIS16300_SMPL_PRD_DIV_MASK 0x7F + +/* DIAG_STAT */ +#define ADIS16300_DIAG_STAT_ZACCL_FAIL (1<<15) +#define ADIS16300_DIAG_STAT_YACCL_FAIL (1<<14) +#define ADIS16300_DIAG_STAT_XACCL_FAIL (1<<13) +#define ADIS16300_DIAG_STAT_XGYRO_FAIL (1<<10) +#define ADIS16300_DIAG_STAT_ALARM2 (1<<9) +#define ADIS16300_DIAG_STAT_ALARM1 (1<<8) +#define ADIS16300_DIAG_STAT_FLASH_CHK (1<<6) +#define ADIS16300_DIAG_STAT_SELF_TEST (1<<5) +#define ADIS16300_DIAG_STAT_OVERFLOW (1<<4) +#define ADIS16300_DIAG_STAT_SPI_FAIL (1<<3) +#define ADIS16300_DIAG_STAT_FLASH_UPT (1<<2) +#define ADIS16300_DIAG_STAT_POWER_HIGH (1<<1) +#define ADIS16300_DIAG_STAT_POWER_LOW (1<<0) + +/* GLOB_CMD */ +#define ADIS16300_GLOB_CMD_SW_RESET (1<<7) +#define ADIS16300_GLOB_CMD_P_AUTO_NULL (1<<4) +#define ADIS16300_GLOB_CMD_FLASH_UPD (1<<3) +#define ADIS16300_GLOB_CMD_DAC_LATCH (1<<2) +#define ADIS16300_GLOB_CMD_FAC_CALIB (1<<1) +#define ADIS16300_GLOB_CMD_AUTO_NULL (1<<0) + +/* SLP_CNT */ +#define ADIS16300_SLP_CNT_POWER_OFF (1<<8) + +#define ADIS16300_MAX_TX 18 +#define ADIS16300_MAX_RX 18 + +#define ADIS16300_SPI_SLOW (u32)(300 * 1000) +#define ADIS16300_SPI_BURST (u32)(1000 * 1000) +#define ADIS16300_SPI_FAST (u32)(2000 * 1000) + +/** + * struct adis16300_state - device instance specific data + * @us: actual spi_device + * @work_trigger_to_ring: bh for triggered event handling + * @work_cont_thresh: CLEAN + * @inter: used to check if new interrupt has been triggered + * @last_timestamp: passing timestamp from th to bh of interrupt handler + * @indio_dev: industrial I/O device structure + * @trig: data ready trigger registered with iio + * @tx: transmit buffer + * @rx: recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct adis16300_state { + struct spi_device *us; + struct work_struct work_trigger_to_ring; + struct iio_work_cont work_cont_thresh; + s64 last_timestamp; + struct iio_dev *indio_dev; + struct iio_trigger *trig; + u8 *tx; + u8 *rx; + struct mutex buf_lock; +}; + +int adis16300_spi_write_reg_8(struct device *dev, + u8 reg_address, + u8 val); + +int adis16300_spi_read_burst(struct device *dev, u8 *rx); + +int adis16300_spi_read_sequence(struct device *dev, + u8 *tx, u8 *rx, int num); + +int adis16300_set_irq(struct device *dev, bool enable); + +int adis16300_reset(struct device *dev); + +int adis16300_stop_device(struct device *dev); + +int adis16300_check_status(struct device *dev); + +#ifdef CONFIG_IIO_RING_BUFFER +/* At the moment triggers are only used for ring buffer + * filling. This may change! + */ + +enum adis16300_scan { + ADIS16300_SCAN_SUPPLY, + ADIS16300_SCAN_GYRO_X, + ADIS16300_SCAN_ACC_X, + ADIS16300_SCAN_ACC_Y, + ADIS16300_SCAN_ACC_Z, + ADIS16300_SCAN_TEMP, + ADIS16300_SCAN_ADC_0, + ADIS16300_SCAN_INCLI_X, + ADIS16300_SCAN_INCLI_Y, +}; + +void adis16300_remove_trigger(struct iio_dev *indio_dev); +int adis16300_probe_trigger(struct iio_dev *indio_dev); + +ssize_t adis16300_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf); + + +int adis16300_configure_ring(struct iio_dev *indio_dev); +void adis16300_unconfigure_ring(struct iio_dev *indio_dev); + +int adis16300_initialize_ring(struct iio_ring_buffer *ring); +void adis16300_uninitialize_ring(struct iio_ring_buffer *ring); +#else /* CONFIG_IIO_RING_BUFFER */ + +static inline void adis16300_remove_trigger(struct iio_dev *indio_dev) +{ +} + +static inline int adis16300_probe_trigger(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline ssize_t +adis16300_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static int adis16300_configure_ring(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline void adis16300_unconfigure_ring(struct iio_dev *indio_dev) +{ +} + +static inline int adis16300_initialize_ring(struct iio_ring_buffer *ring) +{ + return 0; +} + +static inline void adis16300_uninitialize_ring(struct iio_ring_buffer *ring) +{ +} + +#endif /* CONFIG_IIO_RING_BUFFER */ +#endif /* SPI_ADIS16300_H_ */ diff --git a/drivers/staging/iio/imu/adis16300_core.c b/drivers/staging/iio/imu/adis16300_core.c new file mode 100644 index 000000000000..9f5f8cb850dd --- /dev/null +++ b/drivers/staging/iio/imu/adis16300_core.c @@ -0,0 +1,833 @@ +/* + * ADIS16300 Four Degrees of Freedom Inertial Sensor Driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../accel/accel.h" +#include "../gyro/gyro.h" +#include "../adc/adc.h" + +#include "adis16300.h" + +#define DRIVER_NAME "adis16300" + +/* At the moment the spi framework doesn't allow global setting of cs_change. + * It's in the likely to be added comment at the top of spi.h. + * This means that use cannot be made of spi_write etc. + */ + +/** + * adis16300_spi_write_reg_8() - write single byte to a register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the register to be written + * @val: the value to write + **/ +int adis16300_spi_write_reg_8(struct device *dev, + u8 reg_address, + u8 val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16300_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16300_WRITE_REG(reg_address); + st->tx[1] = val; + + ret = spi_write(st->us, st->tx, 2); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16300_spi_write_reg_16() - write 2 bytes to a pair of registers + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: value to be written + **/ +static int adis16300_spi_write_reg_16(struct device *dev, + u8 lower_reg_address, + u16 value) +{ + int ret; + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16300_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + }, { + .tx_buf = st->tx + 2, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16300_WRITE_REG(lower_reg_address); + st->tx[1] = value & 0xFF; + st->tx[2] = ADIS16300_WRITE_REG(lower_reg_address + 1); + st->tx[3] = (value >> 8) & 0xFF; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16300_spi_read_reg_16() - read 2 bytes from a 16-bit register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: somewhere to pass back the value read + **/ +static int adis16300_spi_read_reg_16(struct device *dev, + u8 lower_reg_address, + u16 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16300_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 0, + }, { + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 2, + .cs_change = 0, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16300_READ_REG(lower_reg_address); + st->tx[1] = 0; + st->tx[2] = 0; + st->tx[3] = 0; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, + "problem when reading 16 bit register 0x%02X", + lower_reg_address); + goto error_ret; + } + *val = (st->rx[0] << 8) | st->rx[1]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +/** + * adis16300_spi_read_burst() - read all data registers + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @rx: somewhere to pass back the value read (min size is 24 bytes) + **/ +int adis16300_spi_read_burst(struct device *dev, u8 *rx) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16300_state *st = iio_dev_get_devdata(indio_dev); + u32 old_speed_hz = st->us->max_speed_hz; + int ret; + + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 0, + }, { + .rx_buf = rx, + .bits_per_word = 8, + .len = 18, + .cs_change = 0, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16300_READ_REG(ADIS16300_GLOB_CMD); + st->tx[1] = 0; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + + st->us->max_speed_hz = min(ADIS16300_SPI_BURST, old_speed_hz); + spi_setup(st->us); + + ret = spi_sync(st->us, &msg); + if (ret) + dev_err(&st->us->dev, "problem when burst reading"); + + st->us->max_speed_hz = old_speed_hz; + spi_setup(st->us); + mutex_unlock(&st->buf_lock); + return ret; +} + +/** + * adis16300_spi_read_sequence() - read a sequence of 16-bit registers + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @tx: register addresses in bytes 0,2,4,6... (min size is 2*num bytes) + * @rx: somewhere to pass back the value read (min size is 2*num bytes) + **/ +int adis16300_spi_read_sequence(struct device *dev, + u8 *tx, u8 *rx, int num) +{ + struct spi_message msg; + struct spi_transfer *xfers; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16300_state *st = iio_dev_get_devdata(indio_dev); + int ret, i; + + xfers = kzalloc(num + 1, GFP_KERNEL); + if (xfers == NULL) { + dev_err(&st->us->dev, "memory alloc failed"); + ret = -ENOMEM; + goto error_ret; + } + + /* tx: |add1|addr2|addr3|...|addrN |zero| + * rx: |zero|res1 |res2 |...|resN-1|resN| */ + spi_message_init(&msg); + for (i = 0; i < num + 1; i++) { + if (i > 0) + xfers[i].rx_buf = st->rx + 2*(i - 1); + if (i < num) + xfers[i].tx_buf = st->tx + 2*i; + xfers[i].bits_per_word = 8; + xfers[i].len = 2; + xfers[i].cs_change = 1; + spi_message_add_tail(&xfers[i], &msg); + } + + mutex_lock(&st->buf_lock); + + ret = spi_sync(st->us, &msg); + if (ret) + dev_err(&st->us->dev, "problem when reading sequence"); + + mutex_unlock(&st->buf_lock); + kfree(xfers); + +error_ret: + return ret; +} + +static ssize_t adis16300_spi_read_signed(struct device *dev, + struct device_attribute *attr, + char *buf, + unsigned bits) +{ + int ret; + s16 val = 0; + unsigned shift = 16 - bits; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = adis16300_spi_read_reg_16(dev, this_attr->address, (u16 *)&val); + if (ret) + return ret; + + if (val & ADIS16300_ERROR_ACTIVE) + adis16300_check_status(dev); + val = ((s16)(val << shift) >> shift); + return sprintf(buf, "%d\n", val); +} + +static ssize_t adis16300_read_12bit_unsigned(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u16 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = adis16300_spi_read_reg_16(dev, this_attr->address, &val); + if (ret) + return ret; + + if (val & ADIS16300_ERROR_ACTIVE) + adis16300_check_status(dev); + + return sprintf(buf, "%u\n", val & 0x0FFF); +} + +static ssize_t adis16300_read_14bit_signed(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + ssize_t ret; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + ret = adis16300_spi_read_signed(dev, attr, buf, 14); + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t adis16300_read_12bit_signed(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + ssize_t ret; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + ret = adis16300_spi_read_signed(dev, attr, buf, 12); + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t adis16300_read_13bit_signed(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + ssize_t ret; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + ret = adis16300_spi_read_signed(dev, attr, buf, 13); + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t adis16300_write_16bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = adis16300_spi_write_reg_16(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static ssize_t adis16300_read_frequency(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret, len = 0; + u16 t; + int sps; + ret = adis16300_spi_read_reg_16(dev, + ADIS16300_SMPL_PRD, + &t); + if (ret) + return ret; + sps = (t & ADIS16300_SMPL_PRD_TIME_BASE) ? 53 : 1638; + sps /= (t & ADIS16300_SMPL_PRD_DIV_MASK) + 1; + len = sprintf(buf, "%d SPS\n", sps); + return len; +} + +static ssize_t adis16300_write_frequency(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16300_state *st = iio_dev_get_devdata(indio_dev); + long val; + int ret; + u8 t; + + ret = strict_strtol(buf, 10, &val); + if (ret) + return ret; + + mutex_lock(&indio_dev->mlock); + + t = (1638 / val); + if (t > 0) + t--; + t &= ADIS16300_SMPL_PRD_DIV_MASK; + if ((t & ADIS16300_SMPL_PRD_DIV_MASK) >= 0x0A) + st->us->max_speed_hz = ADIS16300_SPI_SLOW; + else + st->us->max_speed_hz = ADIS16300_SPI_FAST; + + ret = adis16300_spi_write_reg_8(dev, + ADIS16300_SMPL_PRD, + t); + + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +static ssize_t adis16300_write_reset(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + if (len < 1) + return -1; + switch (buf[0]) { + case '1': + case 'y': + case 'Y': + return adis16300_reset(dev); + } + return -1; +} + + + +int adis16300_set_irq(struct device *dev, bool enable) +{ + int ret; + u16 msc; + ret = adis16300_spi_read_reg_16(dev, ADIS16300_MSC_CTRL, &msc); + if (ret) + goto error_ret; + + msc |= ADIS16300_MSC_CTRL_DATA_RDY_POL_HIGH; + msc &= ~ADIS16300_MSC_CTRL_DATA_RDY_DIO2; + if (enable) + msc |= ADIS16300_MSC_CTRL_DATA_RDY_EN; + else + msc &= ~ADIS16300_MSC_CTRL_DATA_RDY_EN; + + ret = adis16300_spi_write_reg_16(dev, ADIS16300_MSC_CTRL, msc); + if (ret) + goto error_ret; + +error_ret: + return ret; +} + +int adis16300_reset(struct device *dev) +{ + int ret; + ret = adis16300_spi_write_reg_8(dev, + ADIS16300_GLOB_CMD, + ADIS16300_GLOB_CMD_SW_RESET); + if (ret) + dev_err(dev, "problem resetting device"); + + return ret; +} + +/* Power down the device */ +int adis16300_stop_device(struct device *dev) +{ + int ret; + u16 val = ADIS16300_SLP_CNT_POWER_OFF; + + ret = adis16300_spi_write_reg_16(dev, ADIS16300_SLP_CNT, val); + if (ret) + dev_err(dev, "problem with turning device off: SLP_CNT"); + + return ret; +} + +int adis16300_self_test(struct device *dev) +{ + int ret; + ret = adis16300_spi_write_reg_16(dev, + ADIS16300_MSC_CTRL, + ADIS16300_MSC_CTRL_MEM_TEST); + if (ret) { + dev_err(dev, "problem starting self test"); + goto err_ret; + } + + adis16300_check_status(dev); + +err_ret: + return ret; +} + +int adis16300_check_status(struct device *dev) +{ + u16 status; + int ret; + + ret = adis16300_spi_read_reg_16(dev, ADIS16300_DIAG_STAT, &status); + + if (ret < 0) { + dev_err(dev, "Reading status failed\n"); + goto error_ret; + } + ret = status; + if (status & ADIS16300_DIAG_STAT_ZACCL_FAIL) + dev_err(dev, "Z-axis accelerometer self-test failure\n"); + if (status & ADIS16300_DIAG_STAT_YACCL_FAIL) + dev_err(dev, "Y-axis accelerometer self-test failure\n"); + if (status & ADIS16300_DIAG_STAT_XACCL_FAIL) + dev_err(dev, "X-axis accelerometer self-test failure\n"); + if (status & ADIS16300_DIAG_STAT_XGYRO_FAIL) + dev_err(dev, "X-axis gyroscope self-test failure\n"); + if (status & ADIS16300_DIAG_STAT_ALARM2) + dev_err(dev, "Alarm 2 active\n"); + if (status & ADIS16300_DIAG_STAT_ALARM1) + dev_err(dev, "Alarm 1 active\n"); + if (status & ADIS16300_DIAG_STAT_FLASH_CHK) + dev_err(dev, "Flash checksum error\n"); + if (status & ADIS16300_DIAG_STAT_SELF_TEST) + dev_err(dev, "Self test error\n"); + if (status & ADIS16300_DIAG_STAT_OVERFLOW) + dev_err(dev, "Sensor overrange\n"); + if (status & ADIS16300_DIAG_STAT_SPI_FAIL) + dev_err(dev, "SPI failure\n"); + if (status & ADIS16300_DIAG_STAT_FLASH_UPT) + dev_err(dev, "Flash update failed\n"); + if (status & ADIS16300_DIAG_STAT_POWER_HIGH) + dev_err(dev, "Power supply above 5.25V\n"); + if (status & ADIS16300_DIAG_STAT_POWER_LOW) + dev_err(dev, "Power supply below 4.75V\n"); + +error_ret: + return ret; +} + +static int adis16300_initial_setup(struct adis16300_state *st) +{ + int ret; + u16 smp_prd; + struct device *dev = &st->indio_dev->dev; + + /* use low spi speed for init */ + st->us->max_speed_hz = ADIS16300_SPI_SLOW; + st->us->mode = SPI_MODE_3; + spi_setup(st->us); + + /* Disable IRQ */ + ret = adis16300_set_irq(dev, false); + if (ret) { + dev_err(dev, "disable irq failed"); + goto err_ret; + } + + /* Do self test */ + + /* Read status register to check the result */ + ret = adis16300_check_status(dev); + if (ret) { + adis16300_reset(dev); + dev_err(dev, "device not playing ball -> reset"); + msleep(ADIS16300_STARTUP_DELAY); + ret = adis16300_check_status(dev); + if (ret) { + dev_err(dev, "giving up"); + goto err_ret; + } + } + + printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n", + st->us->chip_select, st->us->irq); + + /* use high spi speed if possible */ + ret = adis16300_spi_read_reg_16(dev, ADIS16300_SMPL_PRD, &smp_prd); + if (!ret && (smp_prd & ADIS16300_SMPL_PRD_DIV_MASK) < 0x0A) { + st->us->max_speed_hz = ADIS16300_SPI_SLOW; + spi_setup(st->us); + } + +err_ret: + return ret; +} + +static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO, + adis16300_read_12bit_signed, + adis16300_write_16bit, + ADIS16300_XACCL_OFF); + +static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO, + adis16300_read_12bit_signed, + adis16300_write_16bit, + ADIS16300_YACCL_OFF); + +static IIO_DEV_ATTR_ACCEL_Z_OFFSET(S_IWUSR | S_IRUGO, + adis16300_read_12bit_signed, + adis16300_write_16bit, + ADIS16300_ZACCL_OFF); + +static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16300_read_14bit_signed, + ADIS16300_SUPPLY_OUT); +static IIO_CONST_ATTR(in_supply_scale, "0.00242"); + +static IIO_DEV_ATTR_GYRO_X(adis16300_read_14bit_signed, + ADIS16300_XGYRO_OUT); +static IIO_CONST_ATTR(gyro_scale, "0.05 deg/s"); + +static IIO_DEV_ATTR_ACCEL_X(adis16300_read_14bit_signed, + ADIS16300_XACCL_OUT); +static IIO_DEV_ATTR_ACCEL_Y(adis16300_read_14bit_signed, + ADIS16300_YACCL_OUT); +static IIO_DEV_ATTR_ACCEL_Z(adis16300_read_14bit_signed, + ADIS16300_ZACCL_OUT); +static IIO_CONST_ATTR(accel_scale, "0.0006 g"); + +static IIO_DEV_ATTR_INCLI_X(adis16300_read_13bit_signed, + ADIS16300_XINCLI_OUT); +static IIO_DEV_ATTR_INCLI_Y(adis16300_read_13bit_signed, + ADIS16300_YINCLI_OUT); +static IIO_CONST_ATTR(incli_scale, "0.044 d"); + +static IIO_DEV_ATTR_TEMP(adis16300_read_12bit_signed); +static IIO_CONST_ATTR(temp_offset, "198.16 K"); +static IIO_CONST_ATTR(temp_scale, "0.14 K"); + +static IIO_DEV_ATTR_IN_RAW(0, adis16300_read_12bit_unsigned, + ADIS16300_AUX_ADC); +static IIO_CONST_ATTR(in0_scale, "0.000806"); + +static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, + adis16300_read_frequency, + adis16300_write_frequency); + +static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16300_write_reset, 0); + +static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("409 546 819 1638"); + +static IIO_CONST_ATTR(name, "adis16300"); + +static struct attribute *adis16300_event_attributes[] = { + NULL +}; + +static struct attribute_group adis16300_event_attribute_group = { + .attrs = adis16300_event_attributes, +}; + +static struct attribute *adis16300_attributes[] = { + &iio_dev_attr_accel_x_offset.dev_attr.attr, + &iio_dev_attr_accel_y_offset.dev_attr.attr, + &iio_dev_attr_accel_z_offset.dev_attr.attr, + &iio_dev_attr_in_supply_raw.dev_attr.attr, + &iio_const_attr_in_supply_scale.dev_attr.attr, + &iio_dev_attr_gyro_x.dev_attr.attr, + &iio_const_attr_gyro_scale.dev_attr.attr, + &iio_dev_attr_accel_x_raw.dev_attr.attr, + &iio_dev_attr_accel_y_raw.dev_attr.attr, + &iio_dev_attr_accel_z_raw.dev_attr.attr, + &iio_const_attr_accel_scale.dev_attr.attr, + &iio_dev_attr_incli_x.dev_attr.attr, + &iio_dev_attr_incli_y.dev_attr.attr, + &iio_const_attr_incli_scale.dev_attr.attr, + &iio_dev_attr_temp.dev_attr.attr, + &iio_const_attr_temp_offset.dev_attr.attr, + &iio_const_attr_temp_scale.dev_attr.attr, + &iio_dev_attr_in0_raw.dev_attr.attr, + &iio_const_attr_in0_scale.dev_attr.attr, + &iio_dev_attr_sampling_frequency.dev_attr.attr, + &iio_const_attr_available_sampling_frequency.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_const_attr_name.dev_attr.attr, + NULL +}; + +static const struct attribute_group adis16300_attribute_group = { + .attrs = adis16300_attributes, +}; + +static int __devinit adis16300_probe(struct spi_device *spi) +{ + int ret, regdone = 0; + struct adis16300_state *st = kzalloc(sizeof *st, GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + goto error_ret; + } + /* this is only used for removal purposes */ + spi_set_drvdata(spi, st); + + /* Allocate the comms buffers */ + st->rx = kzalloc(sizeof(*st->rx)*ADIS16300_MAX_RX, GFP_KERNEL); + if (st->rx == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->tx = kzalloc(sizeof(*st->tx)*ADIS16300_MAX_TX, GFP_KERNEL); + if (st->tx == NULL) { + ret = -ENOMEM; + goto error_free_rx; + } + st->us = spi; + mutex_init(&st->buf_lock); + /* setup the industrialio driver allocated elements */ + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_tx; + } + + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->num_interrupt_lines = 1; + st->indio_dev->event_attrs = &adis16300_event_attribute_group; + st->indio_dev->attrs = &adis16300_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = adis16300_configure_ring(st->indio_dev); + if (ret) + goto error_free_dev; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_unreg_ring_funcs; + regdone = 1; + + ret = adis16300_initialize_ring(st->indio_dev->ring); + if (ret) { + printk(KERN_ERR "failed to initialize the ring\n"); + goto error_unreg_ring_funcs; + } + + if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) { +#if 0 /* fixme: here we should support */ + iio_init_work_cont(&st->work_cont_thresh, + NULL, + adis16300_thresh_handler_bh_no_check, + 0, + 0, + st); +#endif + ret = iio_register_interrupt_line(spi->irq, + st->indio_dev, + 0, + IRQF_TRIGGER_RISING, + "adis16300"); + if (ret) + goto error_uninitialize_ring; + + ret = adis16300_probe_trigger(st->indio_dev); + if (ret) + goto error_unregister_line; + } + + /* Get the device into a sane initial state */ + ret = adis16300_initial_setup(st); + if (ret) + goto error_remove_trigger; + return 0; + +error_remove_trigger: + if (st->indio_dev->modes & INDIO_RING_TRIGGERED) + adis16300_remove_trigger(st->indio_dev); +error_unregister_line: + if (st->indio_dev->modes & INDIO_RING_TRIGGERED) + iio_unregister_interrupt_line(st->indio_dev, 0); +error_uninitialize_ring: + adis16300_uninitialize_ring(st->indio_dev->ring); +error_unreg_ring_funcs: + adis16300_unconfigure_ring(st->indio_dev); +error_free_dev: + if (regdone) + iio_device_unregister(st->indio_dev); + else + iio_free_device(st->indio_dev); +error_free_tx: + kfree(st->tx); +error_free_rx: + kfree(st->rx); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +/* fixme, confirm ordering in this function */ +static int adis16300_remove(struct spi_device *spi) +{ + int ret; + struct adis16300_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + + ret = adis16300_stop_device(&(indio_dev->dev)); + if (ret) + goto err_ret; + + flush_scheduled_work(); + + adis16300_remove_trigger(indio_dev); + if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) + iio_unregister_interrupt_line(indio_dev, 0); + + adis16300_uninitialize_ring(indio_dev->ring); + adis16300_unconfigure_ring(indio_dev); + iio_device_unregister(indio_dev); + kfree(st->tx); + kfree(st->rx); + kfree(st); + + return 0; + +err_ret: + return ret; +} + +static struct spi_driver adis16300_driver = { + .driver = { + .name = "adis16300", + .owner = THIS_MODULE, + }, + .probe = adis16300_probe, + .remove = __devexit_p(adis16300_remove), +}; + +static __init int adis16300_init(void) +{ + return spi_register_driver(&adis16300_driver); +} +module_init(adis16300_init); + +static __exit void adis16300_exit(void) +{ + spi_unregister_driver(&adis16300_driver); +} +module_exit(adis16300_exit); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADIS16300 IMU SPI driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/imu/adis16300_ring.c b/drivers/staging/iio/imu/adis16300_ring.c new file mode 100644 index 000000000000..76cf8a6f3c3f --- /dev/null +++ b/drivers/staging/iio/imu/adis16300_ring.c @@ -0,0 +1,233 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../ring_sw.h" +#include "../accel/accel.h" +#include "../trigger.h" +#include "adis16300.h" + +/** + * combine_8_to_16() utility function to munge to u8s into u16 + **/ +static inline u16 combine_8_to_16(u8 lower, u8 upper) +{ + u16 _lower = lower; + u16 _upper = upper; + return _lower | (_upper << 8); +} + +static IIO_SCAN_EL_C(supply, ADIS16300_SCAN_SUPPLY, IIO_SIGNED(14), + ADIS16300_SUPPLY_OUT, NULL); + +static IIO_SCAN_EL_C(gyro_x, ADIS16300_SCAN_GYRO_X, IIO_SIGNED(14), + ADIS16300_XGYRO_OUT, NULL); + +static IIO_SCAN_EL_C(accel_x, ADIS16300_SCAN_ACC_X, IIO_SIGNED(14), + ADIS16300_XACCL_OUT, NULL); +static IIO_SCAN_EL_C(accel_y, ADIS16300_SCAN_ACC_Y, IIO_SIGNED(14), + ADIS16300_YACCL_OUT, NULL); +static IIO_SCAN_EL_C(accel_z, ADIS16300_SCAN_ACC_Z, IIO_SIGNED(14), + ADIS16300_ZACCL_OUT, NULL); + +static IIO_SCAN_EL_C(temp, ADIS16300_SCAN_TEMP, IIO_SIGNED(12), + ADIS16300_TEMP_OUT, NULL); +static IIO_SCAN_EL_C(adc_0, ADIS16300_SCAN_ADC_0, IIO_SIGNED(12), + ADIS16300_AUX_ADC, NULL); + +static IIO_SCAN_EL_C(incli_x, ADIS16300_SCAN_INCLI_X, IIO_SIGNED(12), + ADIS16300_XINCLI_OUT, NULL); +static IIO_SCAN_EL_C(incli_y, ADIS16300_SCAN_INCLI_Y, IIO_SIGNED(12), + ADIS16300_YINCLI_OUT, NULL); + +static IIO_SCAN_EL_TIMESTAMP(9); + +static struct attribute *adis16300_scan_el_attrs[] = { + &iio_scan_el_supply.dev_attr.attr, + &iio_scan_el_gyro_x.dev_attr.attr, + &iio_scan_el_temp.dev_attr.attr, + &iio_scan_el_accel_x.dev_attr.attr, + &iio_scan_el_accel_y.dev_attr.attr, + &iio_scan_el_accel_z.dev_attr.attr, + &iio_scan_el_incli_x.dev_attr.attr, + &iio_scan_el_incli_y.dev_attr.attr, + &iio_scan_el_adc_0.dev_attr.attr, + &iio_scan_el_timestamp.dev_attr.attr, + NULL, +}; + +static struct attribute_group adis16300_scan_el_group = { + .attrs = adis16300_scan_el_attrs, + .name = "scan_elements", +}; + +/** + * adis16300_poll_func_th() top half interrupt handler called by trigger + * @private_data: iio_dev + **/ +static void adis16300_poll_func_th(struct iio_dev *indio_dev) +{ + struct adis16300_state *st = iio_dev_get_devdata(indio_dev); + st->last_timestamp = indio_dev->trig->timestamp; + schedule_work(&st->work_trigger_to_ring); + /* Indicate that this interrupt is being handled */ + + /* Technically this is trigger related, but without this + * handler running there is currently no way for the interrupt + * to clear. + */ +} + +/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device + * specific to be rolled into the core. + */ +static void adis16300_trigger_bh_to_ring(struct work_struct *work_s) +{ + struct adis16300_state *st + = container_of(work_s, struct adis16300_state, + work_trigger_to_ring); + + int i = 0; + s16 *data; + size_t datasize = st->indio_dev + ->ring->access.get_bpd(st->indio_dev->ring); + + data = kmalloc(datasize , GFP_KERNEL); + if (data == NULL) { + dev_err(&st->us->dev, "memory alloc failed in ring bh"); + return; + } + + if (st->indio_dev->scan_count) + if (adis16300_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0) + for (; i < st->indio_dev->scan_count; i++) { + data[i] = combine_8_to_16(st->rx[i*2+1], + st->rx[i*2]); + } + + /* Guaranteed to be aligned with 8 byte boundary */ + if (st->indio_dev->scan_timestamp) + *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp; + + st->indio_dev->ring->access.store_to(st->indio_dev->ring, + (u8 *)data, + st->last_timestamp); + + iio_trigger_notify_done(st->indio_dev->trig); + kfree(data); + + return; +} +/* in these circumstances is it better to go with unaligned packing and + * deal with the cost?*/ +static int adis16300_data_rdy_ring_preenable(struct iio_dev *indio_dev) +{ + size_t size; + dev_dbg(&indio_dev->dev, "%s\n", __func__); + /* Check if there are any scan elements enabled, if not fail*/ + if (!(indio_dev->scan_count || indio_dev->scan_timestamp)) + return -EINVAL; + + if (indio_dev->ring->access.set_bpd) { + if (indio_dev->scan_timestamp) + if (indio_dev->scan_count) /* Timestamp and data */ + size = 4*sizeof(s64); + else /* Timestamp only */ + size = sizeof(s64); + else /* Data only */ + size = indio_dev->scan_count*sizeof(s16); + indio_dev->ring->access.set_bpd(indio_dev->ring, size); + } + + return 0; +} + +static int adis16300_data_rdy_ring_postenable(struct iio_dev *indio_dev) +{ + return indio_dev->trig + ? iio_trigger_attach_poll_func(indio_dev->trig, + indio_dev->pollfunc) + : 0; +} + +static int adis16300_data_rdy_ring_predisable(struct iio_dev *indio_dev) +{ + return indio_dev->trig + ? iio_trigger_dettach_poll_func(indio_dev->trig, + indio_dev->pollfunc) + : 0; +} + +void adis16300_unconfigure_ring(struct iio_dev *indio_dev) +{ + kfree(indio_dev->pollfunc); + iio_sw_rb_free(indio_dev->ring); +} + +int adis16300_configure_ring(struct iio_dev *indio_dev) +{ + int ret = 0; + struct adis16300_state *st = indio_dev->dev_data; + struct iio_ring_buffer *ring; + INIT_WORK(&st->work_trigger_to_ring, adis16300_trigger_bh_to_ring); + /* Set default scan mode */ + + iio_scan_mask_set(indio_dev, iio_scan_el_supply.number); + iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number); + iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number); + iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number); + iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number); + iio_scan_mask_set(indio_dev, iio_scan_el_temp.number); + iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number); + iio_scan_mask_set(indio_dev, iio_scan_el_incli_x.number); + iio_scan_mask_set(indio_dev, iio_scan_el_incli_y.number); + indio_dev->scan_timestamp = true; + + indio_dev->scan_el_attrs = &adis16300_scan_el_group; + + ring = iio_sw_rb_allocate(indio_dev); + if (!ring) { + ret = -ENOMEM; + return ret; + } + indio_dev->ring = ring; + /* Effectively select the ring buffer implementation */ + iio_ring_sw_register_funcs(&ring->access); + ring->preenable = &adis16300_data_rdy_ring_preenable; + ring->postenable = &adis16300_data_rdy_ring_postenable; + ring->predisable = &adis16300_data_rdy_ring_predisable; + ring->owner = THIS_MODULE; + + indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL); + if (indio_dev->pollfunc == NULL) { + ret = -ENOMEM; + goto error_iio_sw_rb_free;; + } + indio_dev->pollfunc->poll_func_main = &adis16300_poll_func_th; + indio_dev->pollfunc->private_data = indio_dev; + indio_dev->modes |= INDIO_RING_TRIGGERED; + return 0; + +error_iio_sw_rb_free: + iio_sw_rb_free(indio_dev->ring); + return ret; +} + +int adis16300_initialize_ring(struct iio_ring_buffer *ring) +{ + return iio_ring_buffer_register(ring, 0); +} + +void adis16300_uninitialize_ring(struct iio_ring_buffer *ring) +{ + iio_ring_buffer_unregister(ring); +} diff --git a/drivers/staging/iio/imu/adis16300_trigger.c b/drivers/staging/iio/imu/adis16300_trigger.c new file mode 100644 index 000000000000..54edb20bf119 --- /dev/null +++ b/drivers/staging/iio/imu/adis16300_trigger.c @@ -0,0 +1,127 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../trigger.h" +#include "adis16300.h" + +/** + * adis16300_data_rdy_trig_poll() the event handler for the data rdy trig + **/ +static int adis16300_data_rdy_trig_poll(struct iio_dev *dev_info, + int index, + s64 timestamp, + int no_test) +{ + struct adis16300_state *st = iio_dev_get_devdata(dev_info); + struct iio_trigger *trig = st->trig; + + trig->timestamp = timestamp; + iio_trigger_poll(trig); + + return IRQ_HANDLED; +} + +IIO_EVENT_SH(data_rdy_trig, &adis16300_data_rdy_trig_poll); + +static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL); + +static struct attribute *adis16300_trigger_attrs[] = { + &dev_attr_name.attr, + NULL, +}; + +static const struct attribute_group adis16300_trigger_attr_group = { + .attrs = adis16300_trigger_attrs, +}; + +/** + * adis16300_data_rdy_trigger_set_state() set datardy interrupt state + **/ +static int adis16300_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct adis16300_state *st = trig->private_data; + struct iio_dev *indio_dev = st->indio_dev; + int ret = 0; + + dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); + ret = adis16300_set_irq(&st->indio_dev->dev, state); + if (state == false) { + iio_remove_event_from_list(&iio_event_data_rdy_trig, + &indio_dev->interrupts[0] + ->ev_list); + /* possible quirk with handler currently worked around + by ensuring the work queue is empty */ + flush_scheduled_work(); + } else { + iio_add_event_to_list(&iio_event_data_rdy_trig, + &indio_dev->interrupts[0]->ev_list); + } + return ret; +} + +/** + * adis16300_trig_try_reen() try renabling irq for data rdy trigger + * @trig: the datardy trigger + **/ +static int adis16300_trig_try_reen(struct iio_trigger *trig) +{ + struct adis16300_state *st = trig->private_data; + enable_irq(st->us->irq); + /* irq reenabled so success! */ + return 0; +} + +int adis16300_probe_trigger(struct iio_dev *indio_dev) +{ + int ret; + struct adis16300_state *st = indio_dev->dev_data; + + st->trig = iio_allocate_trigger(); + st->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL); + if (!st->trig->name) { + ret = -ENOMEM; + goto error_free_trig; + } + snprintf((char *)st->trig->name, + IIO_TRIGGER_NAME_LENGTH, + "adis16300-dev%d", indio_dev->id); + st->trig->dev.parent = &st->us->dev; + st->trig->owner = THIS_MODULE; + st->trig->private_data = st; + st->trig->set_trigger_state = &adis16300_data_rdy_trigger_set_state; + st->trig->try_reenable = &adis16300_trig_try_reen; + st->trig->control_attrs = &adis16300_trigger_attr_group; + ret = iio_trigger_register(st->trig); + + /* select default trigger */ + indio_dev->trig = st->trig; + if (ret) + goto error_free_trig_name; + + return 0; + +error_free_trig_name: + kfree(st->trig->name); +error_free_trig: + iio_free_trigger(st->trig); + + return ret; +} + +void adis16300_remove_trigger(struct iio_dev *indio_dev) +{ + struct adis16300_state *state = indio_dev->dev_data; + + iio_trigger_unregister(state->trig); + kfree(state->trig->name); + iio_free_trigger(state->trig); +} -- cgit v1.2.3 From a9d26f00b8b1b2a79e42cfa4ca20ec9a1c11c1d2 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Tue, 4 May 2010 14:43:15 +0100 Subject: staging:iio:imu ADIS16400 and ADIS16405 driver Signed-off-by: Manuel Stahl Signed-off-by: Barry Song Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/imu/Kconfig | 10 + drivers/staging/iio/imu/Makefile | 4 + drivers/staging/iio/imu/adis16400.h | 238 ++++++++ drivers/staging/iio/imu/adis16400_core.c | 849 ++++++++++++++++++++++++++++ drivers/staging/iio/imu/adis16400_ring.c | 245 ++++++++ drivers/staging/iio/imu/adis16400_trigger.c | 127 +++++ drivers/staging/iio/magnetometer/magnet.h | 31 + 7 files changed, 1504 insertions(+) create mode 100644 drivers/staging/iio/imu/adis16400.h create mode 100644 drivers/staging/iio/imu/adis16400_core.c create mode 100644 drivers/staging/iio/imu/adis16400_ring.c create mode 100644 drivers/staging/iio/imu/adis16400_trigger.c create mode 100644 drivers/staging/iio/magnetometer/magnet.h (limited to 'drivers') diff --git a/drivers/staging/iio/imu/Kconfig b/drivers/staging/iio/imu/Kconfig index 3fe47161e768..411804f11a7e 100644 --- a/drivers/staging/iio/imu/Kconfig +++ b/drivers/staging/iio/imu/Kconfig @@ -12,3 +12,13 @@ config ADIS16300 help Say yes here to build support for Analog Devices adis16300 four degrees of freedom inertial sensor. + +config ADIS16400 + tristate "Analog Devices ADIS16400/5 IMU SPI driver" + depends on SPI + select IIO_SW_RING + select IIO_RING_BUFFER + select IIO_TRIGGER + help + Say yes here to build support for Analog Devices adis16400/5 triaxial + inertial sensor with Magnetometer. \ No newline at end of file diff --git a/drivers/staging/iio/imu/Makefile b/drivers/staging/iio/imu/Makefile index 4cd5984137b0..de454dd08c6d 100644 --- a/drivers/staging/iio/imu/Makefile +++ b/drivers/staging/iio/imu/Makefile @@ -4,3 +4,7 @@ adis16300-y := adis16300_core.o adis16300-$(CONFIG_IIO_RING_BUFFER) += adis16300_ring.o adis16300_trigger.o obj-$(CONFIG_ADIS16300) += adis16300.o + +adis16400-y := adis16400_core.o +adis16400-$(CONFIG_IIO_RING_BUFFER) += adis16400_ring.o adis16400_trigger.o +obj-$(CONFIG_ADIS16400) += adis16400.o \ No newline at end of file diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h new file mode 100644 index 000000000000..a8062f605797 --- /dev/null +++ b/drivers/staging/iio/imu/adis16400.h @@ -0,0 +1,238 @@ +/* + * adis16400.h support Analog Devices ADIS16400 + * 3d 18g accelerometers, + * 3d gyroscopes, + * 3d 2.5gauss magnetometers via SPI + * + * Copyright (c) 2009 Manuel Stahl + * Copyright (c) 2007 Jonathan Cameron + * + * Loosely based upon lis3l02dq.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef SPI_ADIS16400_H_ +#define SPI_ADIS16400_H_ + +#define ADIS16400_STARTUP_DELAY 220 /* ms */ + +#define ADIS16400_READ_REG(a) a +#define ADIS16400_WRITE_REG(a) ((a) | 0x80) + +#define ADIS16400_FLASH_CNT 0x00 /* Flash memory write count */ +#define ADIS16400_SUPPLY_OUT 0x02 /* Power supply measurement */ +#define ADIS16400_XGYRO_OUT 0x04 /* X-axis gyroscope output */ +#define ADIS16400_YGYRO_OUT 0x06 /* Y-axis gyroscope output */ +#define ADIS16400_ZGYRO_OUT 0x08 /* Z-axis gyroscope output */ +#define ADIS16400_XACCL_OUT 0x0A /* X-axis accelerometer output */ +#define ADIS16400_YACCL_OUT 0x0C /* Y-axis accelerometer output */ +#define ADIS16400_ZACCL_OUT 0x0E /* Z-axis accelerometer output */ +#define ADIS16400_XMAGN_OUT 0x10 /* X-axis magnetometer measurement */ +#define ADIS16400_YMAGN_OUT 0x12 /* Y-axis magnetometer measurement */ +#define ADIS16400_ZMAGN_OUT 0x14 /* Z-axis magnetometer measurement */ +#define ADIS16400_TEMP_OUT 0x16 /* Temperature output */ +#define ADIS16400_AUX_ADC 0x18 /* Auxiliary ADC measurement */ + +/* Calibration parameters */ +#define ADIS16400_XGYRO_OFF 0x1A /* X-axis gyroscope bias offset factor */ +#define ADIS16400_YGYRO_OFF 0x1C /* Y-axis gyroscope bias offset factor */ +#define ADIS16400_ZGYRO_OFF 0x1E /* Z-axis gyroscope bias offset factor */ +#define ADIS16400_XACCL_OFF 0x20 /* X-axis acceleration bias offset factor */ +#define ADIS16400_YACCL_OFF 0x22 /* Y-axis acceleration bias offset factor */ +#define ADIS16400_ZACCL_OFF 0x24 /* Z-axis acceleration bias offset factor */ +#define ADIS16400_XMAGN_HIF 0x26 /* X-axis magnetometer, hard-iron factor */ +#define ADIS16400_YMAGN_HIF 0x28 /* Y-axis magnetometer, hard-iron factor */ +#define ADIS16400_ZMAGN_HIF 0x2A /* Z-axis magnetometer, hard-iron factor */ +#define ADIS16400_XMAGN_SIF 0x2C /* X-axis magnetometer, soft-iron factor */ +#define ADIS16400_YMAGN_SIF 0x2E /* Y-axis magnetometer, soft-iron factor */ +#define ADIS16400_ZMAGN_SIF 0x30 /* Z-axis magnetometer, soft-iron factor */ + +#define ADIS16400_GPIO_CTRL 0x32 /* Auxiliary digital input/output control */ +#define ADIS16400_MSC_CTRL 0x34 /* Miscellaneous control */ +#define ADIS16400_SMPL_PRD 0x36 /* Internal sample period (rate) control */ +#define ADIS16400_SENS_AVG 0x38 /* Dynamic range and digital filter control */ +#define ADIS16400_SLP_CNT 0x3A /* Sleep mode control */ +#define ADIS16400_DIAG_STAT 0x3C /* System status */ + +/* Alarm functions */ +#define ADIS16400_GLOB_CMD 0x3E /* System command */ +#define ADIS16400_ALM_MAG1 0x40 /* Alarm 1 amplitude threshold */ +#define ADIS16400_ALM_MAG2 0x42 /* Alarm 2 amplitude threshold */ +#define ADIS16400_ALM_SMPL1 0x44 /* Alarm 1 sample size */ +#define ADIS16400_ALM_SMPL2 0x46 /* Alarm 2 sample size */ +#define ADIS16400_ALM_CTRL 0x48 /* Alarm control */ +#define ADIS16400_AUX_DAC 0x4A /* Auxiliary DAC data */ + +#define ADIS16400_PRODUCT_ID 0x56 /* Product identifier */ +#define ADIS16400_PRODUCT_ID_DEFAULT 0x4015 /* Datasheet says 0x4105, I get 0x4015 */ + +#define ADIS16400_ERROR_ACTIVE (1<<14) +#define ADIS16400_NEW_DATA (1<<14) + +/* MSC_CTRL */ +#define ADIS16400_MSC_CTRL_MEM_TEST (1<<11) +#define ADIS16400_MSC_CTRL_INT_SELF_TEST (1<<10) +#define ADIS16400_MSC_CTRL_NEG_SELF_TEST (1<<9) +#define ADIS16400_MSC_CTRL_POS_SELF_TEST (1<<8) +#define ADIS16400_MSC_CTRL_GYRO_BIAS (1<<7) +#define ADIS16400_MSC_CTRL_ACCL_ALIGN (1<<6) +#define ADIS16400_MSC_CTRL_DATA_RDY_EN (1<<2) +#define ADIS16400_MSC_CTRL_DATA_RDY_POL_HIGH (1<<1) +#define ADIS16400_MSC_CTRL_DATA_RDY_DIO2 (1<<0) + +/* SMPL_PRD */ +#define ADIS16400_SMPL_PRD_TIME_BASE (1<<7) +#define ADIS16400_SMPL_PRD_DIV_MASK 0x7F + +/* DIAG_STAT */ +#define ADIS16400_DIAG_STAT_ZACCL_FAIL (1<<15) +#define ADIS16400_DIAG_STAT_YACCL_FAIL (1<<14) +#define ADIS16400_DIAG_STAT_XACCL_FAIL (1<<13) +#define ADIS16400_DIAG_STAT_XGYRO_FAIL (1<<12) +#define ADIS16400_DIAG_STAT_YGYRO_FAIL (1<<11) +#define ADIS16400_DIAG_STAT_ZGYRO_FAIL (1<<10) +#define ADIS16400_DIAG_STAT_ALARM2 (1<<9) +#define ADIS16400_DIAG_STAT_ALARM1 (1<<8) +#define ADIS16400_DIAG_STAT_FLASH_CHK (1<<6) +#define ADIS16400_DIAG_STAT_SELF_TEST (1<<5) +#define ADIS16400_DIAG_STAT_OVERFLOW (1<<4) +#define ADIS16400_DIAG_STAT_SPI_FAIL (1<<3) +#define ADIS16400_DIAG_STAT_FLASH_UPT (1<<2) +#define ADIS16400_DIAG_STAT_POWER_HIGH (1<<1) +#define ADIS16400_DIAG_STAT_POWER_LOW (1<<0) + +/* GLOB_CMD */ +#define ADIS16400_GLOB_CMD_SW_RESET (1<<7) +#define ADIS16400_GLOB_CMD_P_AUTO_NULL (1<<4) +#define ADIS16400_GLOB_CMD_FLASH_UPD (1<<3) +#define ADIS16400_GLOB_CMD_DAC_LATCH (1<<2) +#define ADIS16400_GLOB_CMD_FAC_CALIB (1<<1) +#define ADIS16400_GLOB_CMD_AUTO_NULL (1<<0) + +/* SLP_CNT */ +#define ADIS16400_SLP_CNT_POWER_OFF (1<<8) + +#define ADIS16400_MAX_TX 24 +#define ADIS16400_MAX_RX 24 + +#define ADIS16400_SPI_SLOW (u32)(300 * 1000) +#define ADIS16400_SPI_BURST (u32)(1000 * 1000) +#define ADIS16400_SPI_FAST (u32)(2000 * 1000) + +/** + * struct adis16400_state - device instance specific data + * @us: actual spi_device + * @work_trigger_to_ring: bh for triggered event handling + * @work_cont_thresh: CLEAN + * @inter: used to check if new interrupt has been triggered + * @last_timestamp: passing timestamp from th to bh of interrupt handler + * @indio_dev: industrial I/O device structure + * @trig: data ready trigger registered with iio + * @tx: transmit buffer + * @rx: recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct adis16400_state { + struct spi_device *us; + struct work_struct work_trigger_to_ring; + struct iio_work_cont work_cont_thresh; + s64 last_timestamp; + struct iio_dev *indio_dev; + struct iio_trigger *trig; + u8 *tx; + u8 *rx; + struct mutex buf_lock; +}; + +int adis16400_spi_write_reg_8(struct device *dev, + u8 reg_address, + u8 val); + +int adis16400_spi_read_burst(struct device *dev, u8 *rx); + +int adis16400_spi_read_sequence(struct device *dev, + u8 *tx, u8 *rx, int num); + +int adis16400_set_irq(struct device *dev, bool enable); + +int adis16400_reset(struct device *dev); + +int adis16400_stop_device(struct device *dev); + +int adis16400_check_status(struct device *dev); + +#ifdef CONFIG_IIO_RING_BUFFER +/* At the moment triggers are only used for ring buffer + * filling. This may change! + */ + +enum adis16400_scan { + ADIS16400_SCAN_SUPPLY, + ADIS16400_SCAN_GYRO_X, + ADIS16400_SCAN_GYRO_Y, + ADIS16400_SCAN_GYRO_Z, + ADIS16400_SCAN_ACC_X, + ADIS16400_SCAN_ACC_Y, + ADIS16400_SCAN_ACC_Z, + ADIS16400_SCAN_MAGN_X, + ADIS16400_SCAN_MAGN_Y, + ADIS16400_SCAN_MAGN_Z, + ADIS16400_SCAN_TEMP, + ADIS16400_SCAN_ADC_0 +}; + +void adis16400_remove_trigger(struct iio_dev *indio_dev); +int adis16400_probe_trigger(struct iio_dev *indio_dev); + +ssize_t adis16400_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf); + + +int adis16400_configure_ring(struct iio_dev *indio_dev); +void adis16400_unconfigure_ring(struct iio_dev *indio_dev); + +int adis16400_initialize_ring(struct iio_ring_buffer *ring); +void adis16400_uninitialize_ring(struct iio_ring_buffer *ring); +#else /* CONFIG_IIO_RING_BUFFER */ + +static inline void adis16400_remove_trigger(struct iio_dev *indio_dev) +{ +} + +static inline int adis16400_probe_trigger(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline ssize_t +adis16400_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static int adis16400_configure_ring(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline void adis16400_unconfigure_ring(struct iio_dev *indio_dev) +{ +} + +static inline int adis16400_initialize_ring(struct iio_ring_buffer *ring) +{ + return 0; +} + +static inline void adis16400_uninitialize_ring(struct iio_ring_buffer *ring) +{ +} + +#endif /* CONFIG_IIO_RING_BUFFER */ +#endif /* SPI_ADIS16400_H_ */ diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c new file mode 100644 index 000000000000..27e4a7348075 --- /dev/null +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -0,0 +1,849 @@ +/* + * adis16400.c support Analog Devices ADIS16400/5 + * 3d 2g Linear Accelerometers, + * 3d Gyroscopes, + * 3d Magnetometers via SPI + * + * Copyright (c) 2009 Manuel Stahl + * Copyright (c) 2007 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../accel/accel.h" +#include "../adc/adc.h" +#include "../gyro/gyro.h" +#include "../magnetometer/magnet.h" + +#include "adis16400.h" + +#define DRIVER_NAME "adis16400" + +/* At the moment the spi framework doesn't allow global setting of cs_change. + * It's in the likely to be added comment at the top of spi.h. + * This means that use cannot be made of spi_write etc. + */ + +/** + * adis16400_spi_write_reg_8() - write single byte to a register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the register to be written + * @val: the value to write + **/ +int adis16400_spi_write_reg_8(struct device *dev, + u8 reg_address, + u8 val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16400_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16400_WRITE_REG(reg_address); + st->tx[1] = val; + + ret = spi_write(st->us, st->tx, 2); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16400_spi_write_reg_16() - write 2 bytes to a pair of registers + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: value to be written + **/ +static int adis16400_spi_write_reg_16(struct device *dev, + u8 lower_reg_address, + u16 value) +{ + int ret; + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16400_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + }, { + .tx_buf = st->tx + 2, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16400_WRITE_REG(lower_reg_address); + st->tx[1] = value & 0xFF; + st->tx[2] = ADIS16400_WRITE_REG(lower_reg_address + 1); + st->tx[3] = (value >> 8) & 0xFF; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16400_spi_read_reg_16() - read 2 bytes from a 16-bit register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: somewhere to pass back the value read + **/ +static int adis16400_spi_read_reg_16(struct device *dev, + u8 lower_reg_address, + u16 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16400_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + }, { + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16400_READ_REG(lower_reg_address); + st->tx[1] = 0; + st->tx[2] = 0; + st->tx[3] = 0; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, + "problem when reading 16 bit register 0x%02X", + lower_reg_address); + goto error_ret; + } + *val = (st->rx[0] << 8) | st->rx[1]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +/** + * adis16400_spi_read_burst() - read all data registers + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @rx: somewhere to pass back the value read (min size is 24 bytes) + **/ +int adis16400_spi_read_burst(struct device *dev, u8 *rx) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16400_state *st = iio_dev_get_devdata(indio_dev); + u32 old_speed_hz = st->us->max_speed_hz; + int ret; + + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 0, + }, { + .rx_buf = rx, + .bits_per_word = 8, + .len = 24, + .cs_change = 1, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16400_READ_REG(ADIS16400_GLOB_CMD); + st->tx[1] = 0; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + + st->us->max_speed_hz = min(ADIS16400_SPI_BURST, old_speed_hz); + spi_setup(st->us); + + ret = spi_sync(st->us, &msg); + if (ret) + dev_err(&st->us->dev, "problem when burst reading"); + + st->us->max_speed_hz = old_speed_hz; + spi_setup(st->us); + mutex_unlock(&st->buf_lock); + return ret; +} + +/** + * adis16400_spi_read_sequence() - read a sequence of 16-bit registers + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @tx: register addresses in bytes 0,2,4,6... (min size is 2*num bytes) + * @rx: somewhere to pass back the value read (min size is 2*num bytes) + **/ +int adis16400_spi_read_sequence(struct device *dev, + u8 *tx, u8 *rx, int num) +{ + struct spi_message msg; + struct spi_transfer *xfers; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16400_state *st = iio_dev_get_devdata(indio_dev); + int ret, i; + + xfers = kzalloc(num + 1, GFP_KERNEL); + if (xfers == NULL) { + dev_err(&st->us->dev, "memory alloc failed"); + ret = -ENOMEM; + goto error_ret; + } + + /* tx: |add1|addr2|addr3|...|addrN |zero| + * rx: |zero|res1 |res2 |...|resN-1|resN| */ + spi_message_init(&msg); + for (i = 0; i < num + 1; i++) { + if (i > 0) + xfers[i].rx_buf = st->rx + 2*(i - 1); + if (i < num) + xfers[i].tx_buf = st->tx + 2*i; + xfers[i].bits_per_word = 8; + xfers[i].len = 2; + xfers[i].cs_change = 1; + spi_message_add_tail(&xfers[i], &msg); + } + + mutex_lock(&st->buf_lock); + + ret = spi_sync(st->us, &msg); + if (ret) + dev_err(&st->us->dev, "problem when reading sequence"); + + mutex_unlock(&st->buf_lock); + kfree(xfers); + +error_ret: + return ret; +} + +static ssize_t adis16400_spi_read_signed(struct device *dev, + struct device_attribute *attr, + char *buf, + unsigned bits) +{ + int ret; + s16 val = 0; + unsigned shift = 16 - bits; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = adis16400_spi_read_reg_16(dev, this_attr->address, (u16 *)&val); + if (ret) + return ret; + + if (val & ADIS16400_ERROR_ACTIVE) + adis16400_check_status(dev); + val = ((s16)(val << shift) >> shift); + return sprintf(buf, "%d\n", val); +} + +static ssize_t adis16400_read_12bit_unsigned(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u16 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = adis16400_spi_read_reg_16(dev, this_attr->address, &val); + if (ret) + return ret; + + if (val & ADIS16400_ERROR_ACTIVE) + adis16400_check_status(dev); + + return sprintf(buf, "%u\n", val & 0x0FFF); +} + +static ssize_t adis16400_read_14bit_signed(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + ssize_t ret; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + ret = adis16400_spi_read_signed(dev, attr, buf, 14); + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t adis16400_read_12bit_signed(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + ssize_t ret; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + ret = adis16400_spi_read_signed(dev, attr, buf, 12); + mutex_unlock(&indio_dev->mlock); + + return ret; +} + + +static ssize_t adis16400_write_16bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = adis16400_spi_write_reg_16(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static ssize_t adis16400_read_frequency(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret, len = 0; + u16 t; + int sps; + ret = adis16400_spi_read_reg_16(dev, + ADIS16400_SMPL_PRD, + &t); + if (ret) + return ret; + sps = (t & ADIS16400_SMPL_PRD_TIME_BASE) ? 53 : 1638; + sps /= (t & ADIS16400_SMPL_PRD_DIV_MASK) + 1; + len = sprintf(buf, "%d SPS\n", sps); + return len; +} + +static ssize_t adis16400_write_frequency(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16400_state *st = iio_dev_get_devdata(indio_dev); + long val; + int ret; + u8 t; + + ret = strict_strtol(buf, 10, &val); + if (ret) + return ret; + + mutex_lock(&indio_dev->mlock); + + t = (1638 / val); + if (t > 0) + t--; + t &= ADIS16400_SMPL_PRD_DIV_MASK; + if ((t & ADIS16400_SMPL_PRD_DIV_MASK) >= 0x0A) + st->us->max_speed_hz = ADIS16400_SPI_SLOW; + else + st->us->max_speed_hz = ADIS16400_SPI_FAST; + + ret = adis16400_spi_write_reg_8(dev, + ADIS16400_SMPL_PRD, + t); + + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +static ssize_t adis16400_write_reset(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + if (len < 1) + return -1; + switch (buf[0]) { + case '1': + case 'y': + case 'Y': + return adis16400_reset(dev); + } + return -1; +} + + + +int adis16400_set_irq(struct device *dev, bool enable) +{ + int ret; + u16 msc; + ret = adis16400_spi_read_reg_16(dev, ADIS16400_MSC_CTRL, &msc); + if (ret) + goto error_ret; + + msc |= ADIS16400_MSC_CTRL_DATA_RDY_POL_HIGH; + if (enable) + msc |= ADIS16400_MSC_CTRL_DATA_RDY_EN; + else + msc &= ~ADIS16400_MSC_CTRL_DATA_RDY_EN; + + ret = adis16400_spi_write_reg_16(dev, ADIS16400_MSC_CTRL, msc); + if (ret) + goto error_ret; + +error_ret: + return ret; +} + +int adis16400_reset(struct device *dev) +{ + int ret; + ret = adis16400_spi_write_reg_8(dev, + ADIS16400_GLOB_CMD, + ADIS16400_GLOB_CMD_SW_RESET); + if (ret) + dev_err(dev, "problem resetting device"); + + return ret; +} + +/* Power down the device */ +int adis16400_stop_device(struct device *dev) +{ + int ret; + u16 val = ADIS16400_SLP_CNT_POWER_OFF; + + ret = adis16400_spi_write_reg_16(dev, ADIS16400_SLP_CNT, val); + if (ret) + dev_err(dev, "problem with turning device off: SLP_CNT"); + + return ret; +} + +int adis16400_self_test(struct device *dev) +{ + int ret; + ret = adis16400_spi_write_reg_16(dev, + ADIS16400_MSC_CTRL, + ADIS16400_MSC_CTRL_MEM_TEST); + if (ret) { + dev_err(dev, "problem starting self test"); + goto err_ret; + } + + adis16400_check_status(dev); + +err_ret: + return ret; +} + +int adis16400_check_status(struct device *dev) +{ + u16 status; + int ret; + + ret = adis16400_spi_read_reg_16(dev, ADIS16400_DIAG_STAT, &status); + + if (ret < 0) { + dev_err(dev, "Reading status failed\n"); + goto error_ret; + } + ret = status; + if (status & ADIS16400_DIAG_STAT_ZACCL_FAIL) + dev_err(dev, "Z-axis accelerometer self-test failure\n"); + if (status & ADIS16400_DIAG_STAT_YACCL_FAIL) + dev_err(dev, "Y-axis accelerometer self-test failure\n"); + if (status & ADIS16400_DIAG_STAT_XACCL_FAIL) + dev_err(dev, "X-axis accelerometer self-test failure\n"); + if (status & ADIS16400_DIAG_STAT_XGYRO_FAIL) + dev_err(dev, "X-axis gyroscope self-test failure\n"); + if (status & ADIS16400_DIAG_STAT_YGYRO_FAIL) + dev_err(dev, "Y-axis gyroscope self-test failure\n"); + if (status & ADIS16400_DIAG_STAT_ZGYRO_FAIL) + dev_err(dev, "Z-axis gyroscope self-test failure\n"); + if (status & ADIS16400_DIAG_STAT_ALARM2) + dev_err(dev, "Alarm 2 active\n"); + if (status & ADIS16400_DIAG_STAT_ALARM1) + dev_err(dev, "Alarm 1 active\n"); + if (status & ADIS16400_DIAG_STAT_FLASH_CHK) + dev_err(dev, "Flash checksum error\n"); + if (status & ADIS16400_DIAG_STAT_SELF_TEST) + dev_err(dev, "Self test error\n"); + if (status & ADIS16400_DIAG_STAT_OVERFLOW) + dev_err(dev, "Sensor overrange\n"); + if (status & ADIS16400_DIAG_STAT_SPI_FAIL) + dev_err(dev, "SPI failure\n"); + if (status & ADIS16400_DIAG_STAT_FLASH_UPT) + dev_err(dev, "Flash update failed\n"); + if (status & ADIS16400_DIAG_STAT_POWER_HIGH) + dev_err(dev, "Power supply above 5.25V\n"); + if (status & ADIS16400_DIAG_STAT_POWER_LOW) + dev_err(dev, "Power supply below 4.75V\n"); + +error_ret: + return ret; +} + +static int adis16400_initial_setup(struct adis16400_state *st) +{ + int ret; + u16 prod_id, smp_prd; + struct device *dev = &st->indio_dev->dev; + + /* use low spi speed for init */ + st->us->max_speed_hz = ADIS16400_SPI_SLOW; + st->us->mode = SPI_MODE_3; + spi_setup(st->us); + + /* Disable IRQ */ + ret = adis16400_set_irq(dev, false); + if (ret) { + dev_err(dev, "disable irq failed"); + goto err_ret; + } + + /* Do self test */ + + /* Read status register to check the result */ + ret = adis16400_check_status(dev); + if (ret) { + adis16400_reset(dev); + dev_err(dev, "device not playing ball -> reset"); + msleep(ADIS16400_STARTUP_DELAY); + ret = adis16400_check_status(dev); + if (ret) { + dev_err(dev, "giving up"); + goto err_ret; + } + } + + ret = adis16400_spi_read_reg_16(dev, ADIS16400_PRODUCT_ID, &prod_id); + if (ret) + goto err_ret; + + if (prod_id != ADIS16400_PRODUCT_ID_DEFAULT) + dev_warn(dev, "unknown product id"); + + printk(KERN_INFO DRIVER_NAME ": prod_id 0x%04x at CS%d (irq %d)\n", + prod_id, st->us->chip_select, st->us->irq); + + /* use high spi speed if possible */ + ret = adis16400_spi_read_reg_16(dev, ADIS16400_SMPL_PRD, &smp_prd); + if (!ret && (smp_prd & ADIS16400_SMPL_PRD_DIV_MASK) < 0x0A) { + st->us->max_speed_hz = ADIS16400_SPI_SLOW; + spi_setup(st->us); + } + + +err_ret: + + return ret; +} + +static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO, + adis16400_read_12bit_signed, + adis16400_write_16bit, + ADIS16400_XACCL_OFF); + +static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO, + adis16400_read_12bit_signed, + adis16400_write_16bit, + ADIS16400_YACCL_OFF); + +static IIO_DEV_ATTR_ACCEL_Z_OFFSET(S_IWUSR | S_IRUGO, + adis16400_read_12bit_signed, + adis16400_write_16bit, + ADIS16400_ZACCL_OFF); + +static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16400_read_14bit_signed, + ADIS16400_SUPPLY_OUT); +static IIO_CONST_ATTR(in_supply_scale, "0.002418"); + +static IIO_DEV_ATTR_GYRO_X(adis16400_read_14bit_signed, + ADIS16400_XGYRO_OUT); +static IIO_DEV_ATTR_GYRO_Y(adis16400_read_14bit_signed, + ADIS16400_YGYRO_OUT); +static IIO_DEV_ATTR_GYRO_Z(adis16400_read_14bit_signed, + ADIS16400_ZGYRO_OUT); +static IIO_CONST_ATTR(gyro_scale, "0.05 deg/s"); + +static IIO_DEV_ATTR_ACCEL_X(adis16400_read_14bit_signed, + ADIS16400_XACCL_OUT); +static IIO_DEV_ATTR_ACCEL_Y(adis16400_read_14bit_signed, + ADIS16400_YACCL_OUT); +static IIO_DEV_ATTR_ACCEL_Z(adis16400_read_14bit_signed, + ADIS16400_ZACCL_OUT); +static IIO_CONST_ATTR(accel_scale, "0.00333 g"); + +static IIO_DEV_ATTR_MAGN_X(adis16400_read_14bit_signed, + ADIS16400_XMAGN_OUT); +static IIO_DEV_ATTR_MAGN_Y(adis16400_read_14bit_signed, + ADIS16400_YMAGN_OUT); +static IIO_DEV_ATTR_MAGN_Z(adis16400_read_14bit_signed, + ADIS16400_ZMAGN_OUT); +static IIO_CONST_ATTR(magn_scale, "0.0005 Gs"); + + +static IIO_DEV_ATTR_TEMP(adis16400_read_12bit_signed); +static IIO_CONST_ATTR(temp_offset, "198.16 K"); +static IIO_CONST_ATTR(temp_scale, "0.14 K"); + +static IIO_DEV_ATTR_IN_RAW(0, adis16400_read_12bit_unsigned, + ADIS16400_AUX_ADC); +static IIO_CONST_ATTR(in0_scale, "0.000806"); + +static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, + adis16400_read_frequency, + adis16400_write_frequency); + +static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16400_write_reset, 0); + +static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("409 546 819 1638"); + +static IIO_CONST_ATTR(name, "adis16400"); + +static struct attribute *adis16400_event_attributes[] = { + NULL +}; + +static struct attribute_group adis16400_event_attribute_group = { + .attrs = adis16400_event_attributes, +}; + +static struct attribute *adis16400_attributes[] = { + &iio_dev_attr_accel_x_offset.dev_attr.attr, + &iio_dev_attr_accel_y_offset.dev_attr.attr, + &iio_dev_attr_accel_z_offset.dev_attr.attr, + &iio_dev_attr_in_supply_raw.dev_attr.attr, + &iio_const_attr_in_supply_scale.dev_attr.attr, + &iio_dev_attr_gyro_x.dev_attr.attr, + &iio_dev_attr_gyro_y.dev_attr.attr, + &iio_dev_attr_gyro_z.dev_attr.attr, + &iio_const_attr_gyro_scale.dev_attr.attr, + &iio_dev_attr_accel_x_raw.dev_attr.attr, + &iio_dev_attr_accel_y_raw.dev_attr.attr, + &iio_dev_attr_accel_z_raw.dev_attr.attr, + &iio_const_attr_accel_scale.dev_attr.attr, + &iio_dev_attr_magn_x.dev_attr.attr, + &iio_dev_attr_magn_y.dev_attr.attr, + &iio_dev_attr_magn_z.dev_attr.attr, + &iio_const_attr_magn_scale.dev_attr.attr, + &iio_dev_attr_temp.dev_attr.attr, + &iio_const_attr_temp_offset.dev_attr.attr, + &iio_const_attr_temp_scale.dev_attr.attr, + &iio_dev_attr_in0_raw.dev_attr.attr, + &iio_const_attr_in0_scale.dev_attr.attr, + &iio_dev_attr_sampling_frequency.dev_attr.attr, + &iio_const_attr_available_sampling_frequency.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_const_attr_name.dev_attr.attr, + NULL +}; + +static const struct attribute_group adis16400_attribute_group = { + .attrs = adis16400_attributes, +}; + +static int __devinit adis16400_probe(struct spi_device *spi) +{ + int ret, regdone = 0; + struct adis16400_state *st = kzalloc(sizeof *st, GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + goto error_ret; + } + /* this is only used for removal purposes */ + spi_set_drvdata(spi, st); + + /* Allocate the comms buffers */ + st->rx = kzalloc(sizeof(*st->rx)*ADIS16400_MAX_RX, GFP_KERNEL); + if (st->rx == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->tx = kzalloc(sizeof(*st->tx)*ADIS16400_MAX_TX, GFP_KERNEL); + if (st->tx == NULL) { + ret = -ENOMEM; + goto error_free_rx; + } + st->us = spi; + mutex_init(&st->buf_lock); + /* setup the industrialio driver allocated elements */ + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_tx; + } + + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->num_interrupt_lines = 1; + st->indio_dev->event_attrs = &adis16400_event_attribute_group; + st->indio_dev->attrs = &adis16400_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = adis16400_configure_ring(st->indio_dev); + if (ret) + goto error_free_dev; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_unreg_ring_funcs; + regdone = 1; + + ret = adis16400_initialize_ring(st->indio_dev->ring); + if (ret) { + printk(KERN_ERR "failed to initialize the ring\n"); + goto error_unreg_ring_funcs; + } + + if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) { +#if 0 /* fixme: here we should support */ + iio_init_work_cont(&st->work_cont_thresh, + NULL, + adis16400_thresh_handler_bh_no_check, + 0, + 0, + st); +#endif + ret = iio_register_interrupt_line(spi->irq, + st->indio_dev, + 0, + IRQF_TRIGGER_RISING, + "adis16400"); + if (ret) + goto error_uninitialize_ring; + + ret = adis16400_probe_trigger(st->indio_dev); + if (ret) + goto error_unregister_line; + } + + /* Get the device into a sane initial state */ + ret = adis16400_initial_setup(st); + if (ret) + goto error_remove_trigger; + return 0; + +error_remove_trigger: + if (st->indio_dev->modes & INDIO_RING_TRIGGERED) + adis16400_remove_trigger(st->indio_dev); +error_unregister_line: + if (st->indio_dev->modes & INDIO_RING_TRIGGERED) + iio_unregister_interrupt_line(st->indio_dev, 0); +error_uninitialize_ring: + adis16400_uninitialize_ring(st->indio_dev->ring); +error_unreg_ring_funcs: + adis16400_unconfigure_ring(st->indio_dev); +error_free_dev: + if (regdone) + iio_device_unregister(st->indio_dev); + else + iio_free_device(st->indio_dev); +error_free_tx: + kfree(st->tx); +error_free_rx: + kfree(st->rx); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +/* fixme, confirm ordering in this function */ +static int adis16400_remove(struct spi_device *spi) +{ + int ret; + struct adis16400_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + + ret = adis16400_stop_device(&(indio_dev->dev)); + if (ret) + goto err_ret; + + flush_scheduled_work(); + + adis16400_remove_trigger(indio_dev); + if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) + iio_unregister_interrupt_line(indio_dev, 0); + + adis16400_uninitialize_ring(indio_dev->ring); + adis16400_unconfigure_ring(indio_dev); + iio_device_unregister(indio_dev); + kfree(st->tx); + kfree(st->rx); + kfree(st); + + return 0; + +err_ret: + return ret; +} + +static struct spi_driver adis16400_driver = { + .driver = { + .name = "adis16400", + .owner = THIS_MODULE, + }, + .probe = adis16400_probe, + .remove = __devexit_p(adis16400_remove), +}; + +static __init int adis16400_init(void) +{ + return spi_register_driver(&adis16400_driver); +} +module_init(adis16400_init); + +static __exit void adis16400_exit(void) +{ + spi_unregister_driver(&adis16400_driver); +} +module_exit(adis16400_exit); + +MODULE_AUTHOR("Manuel Stahl "); +MODULE_DESCRIPTION("Analog Devices ADIS16400/5 IMU SPI driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c new file mode 100644 index 000000000000..5529b32bd2e3 --- /dev/null +++ b/drivers/staging/iio/imu/adis16400_ring.c @@ -0,0 +1,245 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../ring_sw.h" +#include "../accel/accel.h" +#include "../trigger.h" +#include "adis16400.h" + +/** + * combine_8_to_16() utility function to munge to u8s into u16 + **/ +static inline u16 combine_8_to_16(u8 lower, u8 upper) +{ + u16 _lower = lower; + u16 _upper = upper; + return _lower | (_upper << 8); +} + +static IIO_SCAN_EL_C(supply, ADIS16400_SCAN_SUPPLY, IIO_SIGNED(14), + ADIS16400_SUPPLY_OUT, NULL); + +static IIO_SCAN_EL_C(gyro_x, ADIS16400_SCAN_GYRO_X, IIO_SIGNED(14), + ADIS16400_XGYRO_OUT, NULL); +static IIO_SCAN_EL_C(gyro_y, ADIS16400_SCAN_GYRO_Y, IIO_SIGNED(14), + ADIS16400_YGYRO_OUT, NULL); +static IIO_SCAN_EL_C(gyro_z, ADIS16400_SCAN_GYRO_Z, IIO_SIGNED(14), + ADIS16400_ZGYRO_OUT, NULL); + +static IIO_SCAN_EL_C(accel_x, ADIS16400_SCAN_ACC_X, IIO_SIGNED(14), + ADIS16400_XACCL_OUT, NULL); +static IIO_SCAN_EL_C(accel_y, ADIS16400_SCAN_ACC_Y, IIO_SIGNED(14), + ADIS16400_YACCL_OUT, NULL); +static IIO_SCAN_EL_C(accel_z, ADIS16400_SCAN_ACC_Z, IIO_SIGNED(14), + ADIS16400_ZACCL_OUT, NULL); + +static IIO_SCAN_EL_C(magn_x, ADIS16400_SCAN_MAGN_X, IIO_SIGNED(14), + ADIS16400_XMAGN_OUT, NULL); +static IIO_SCAN_EL_C(magn_y, ADIS16400_SCAN_MAGN_Y, IIO_SIGNED(14), + ADIS16400_YMAGN_OUT, NULL); +static IIO_SCAN_EL_C(magn_z, ADIS16400_SCAN_MAGN_Z, IIO_SIGNED(14), + ADIS16400_ZMAGN_OUT, NULL); + +static IIO_SCAN_EL_C(temp, ADIS16400_SCAN_TEMP, IIO_SIGNED(12), + ADIS16400_TEMP_OUT, NULL); +static IIO_SCAN_EL_C(adc_0, ADIS16400_SCAN_ADC_0, IIO_SIGNED(12), + ADIS16400_AUX_ADC, NULL); + +static IIO_SCAN_EL_TIMESTAMP(12); + +static struct attribute *adis16400_scan_el_attrs[] = { + &iio_scan_el_supply.dev_attr.attr, + &iio_scan_el_gyro_x.dev_attr.attr, + &iio_scan_el_gyro_y.dev_attr.attr, + &iio_scan_el_gyro_z.dev_attr.attr, + &iio_scan_el_accel_x.dev_attr.attr, + &iio_scan_el_accel_y.dev_attr.attr, + &iio_scan_el_accel_z.dev_attr.attr, + &iio_scan_el_magn_x.dev_attr.attr, + &iio_scan_el_magn_y.dev_attr.attr, + &iio_scan_el_magn_z.dev_attr.attr, + &iio_scan_el_temp.dev_attr.attr, + &iio_scan_el_adc_0.dev_attr.attr, + &iio_scan_el_timestamp.dev_attr.attr, + NULL, +}; + +static struct attribute_group adis16400_scan_el_group = { + .attrs = adis16400_scan_el_attrs, + .name = "scan_elements", +}; + +/** + * adis16400_poll_func_th() top half interrupt handler called by trigger + * @private_data: iio_dev + **/ +static void adis16400_poll_func_th(struct iio_dev *indio_dev) +{ + struct adis16400_state *st = iio_dev_get_devdata(indio_dev); + st->last_timestamp = indio_dev->trig->timestamp; + schedule_work(&st->work_trigger_to_ring); + /* Indicate that this interrupt is being handled */ + + /* Technically this is trigger related, but without this + * handler running there is currently no way for the interrupt + * to clear. + */ +} + +/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device + * specific to be rolled into the core. + */ +static void adis16400_trigger_bh_to_ring(struct work_struct *work_s) +{ + struct adis16400_state *st + = container_of(work_s, struct adis16400_state, + work_trigger_to_ring); + + int i = 0; + s16 *data; + size_t datasize = st->indio_dev + ->ring->access.get_bpd(st->indio_dev->ring); + + data = kmalloc(datasize , GFP_KERNEL); + if (data == NULL) { + dev_err(&st->us->dev, "memory alloc failed in ring bh"); + return; + } + + if (st->indio_dev->scan_count) + if (adis16400_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0) + for (; i < st->indio_dev->scan_count; i++) { + data[i] = combine_8_to_16(st->rx[i*2+1], + st->rx[i*2]); + } + + /* Guaranteed to be aligned with 8 byte boundary */ + if (st->indio_dev->scan_timestamp) + *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp; + + st->indio_dev->ring->access.store_to(st->indio_dev->ring, + (u8 *)data, + st->last_timestamp); + + iio_trigger_notify_done(st->indio_dev->trig); + kfree(data); + + return; +} +/* in these circumstances is it better to go with unaligned packing and + * deal with the cost?*/ +static int adis16400_data_rdy_ring_preenable(struct iio_dev *indio_dev) +{ + size_t size; + dev_dbg(&indio_dev->dev, "%s\n", __func__); + /* Check if there are any scan elements enabled, if not fail*/ + if (!(indio_dev->scan_count || indio_dev->scan_timestamp)) + return -EINVAL; + + if (indio_dev->ring->access.set_bpd) { + if (indio_dev->scan_timestamp) + if (indio_dev->scan_count) /* Timestamp and data */ + size = 6*sizeof(s64); + else /* Timestamp only */ + size = sizeof(s64); + else /* Data only */ + size = indio_dev->scan_count*sizeof(s16); + indio_dev->ring->access.set_bpd(indio_dev->ring, size); + } + + return 0; +} + +static int adis16400_data_rdy_ring_postenable(struct iio_dev *indio_dev) +{ + return indio_dev->trig + ? iio_trigger_attach_poll_func(indio_dev->trig, + indio_dev->pollfunc) + : 0; +} + +static int adis16400_data_rdy_ring_predisable(struct iio_dev *indio_dev) +{ + return indio_dev->trig + ? iio_trigger_dettach_poll_func(indio_dev->trig, + indio_dev->pollfunc) + : 0; +} + +void adis16400_unconfigure_ring(struct iio_dev *indio_dev) +{ + kfree(indio_dev->pollfunc); + iio_sw_rb_free(indio_dev->ring); +} + +int adis16400_configure_ring(struct iio_dev *indio_dev) +{ + int ret = 0; + struct adis16400_state *st = indio_dev->dev_data; + struct iio_ring_buffer *ring; + INIT_WORK(&st->work_trigger_to_ring, adis16400_trigger_bh_to_ring); + /* Set default scan mode */ + + iio_scan_mask_set(indio_dev, iio_scan_el_supply.number); + iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number); + iio_scan_mask_set(indio_dev, iio_scan_el_gyro_y.number); + iio_scan_mask_set(indio_dev, iio_scan_el_gyro_z.number); + iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number); + iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number); + iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number); + iio_scan_mask_set(indio_dev, iio_scan_el_magn_x.number); + iio_scan_mask_set(indio_dev, iio_scan_el_magn_y.number); + iio_scan_mask_set(indio_dev, iio_scan_el_magn_z.number); + iio_scan_mask_set(indio_dev, iio_scan_el_temp.number); + iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number); + indio_dev->scan_timestamp = true; + + indio_dev->scan_el_attrs = &adis16400_scan_el_group; + + ring = iio_sw_rb_allocate(indio_dev); + if (!ring) { + ret = -ENOMEM; + return ret; + } + indio_dev->ring = ring; + /* Effectively select the ring buffer implementation */ + iio_ring_sw_register_funcs(&ring->access); + ring->preenable = &adis16400_data_rdy_ring_preenable; + ring->postenable = &adis16400_data_rdy_ring_postenable; + ring->predisable = &adis16400_data_rdy_ring_predisable; + ring->owner = THIS_MODULE; + + indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL); + if (indio_dev->pollfunc == NULL) { + ret = -ENOMEM; + goto error_iio_sw_rb_free;; + } + indio_dev->pollfunc->poll_func_main = &adis16400_poll_func_th; + indio_dev->pollfunc->private_data = indio_dev; + indio_dev->modes |= INDIO_RING_TRIGGERED; + return 0; + +error_iio_sw_rb_free: + iio_sw_rb_free(indio_dev->ring); + return ret; +} + +int adis16400_initialize_ring(struct iio_ring_buffer *ring) +{ + return iio_ring_buffer_register(ring, 0); +} + +void adis16400_uninitialize_ring(struct iio_ring_buffer *ring) +{ + iio_ring_buffer_unregister(ring); +} diff --git a/drivers/staging/iio/imu/adis16400_trigger.c b/drivers/staging/iio/imu/adis16400_trigger.c new file mode 100644 index 000000000000..3b3250ac7680 --- /dev/null +++ b/drivers/staging/iio/imu/adis16400_trigger.c @@ -0,0 +1,127 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../trigger.h" +#include "adis16400.h" + +/** + * adis16400_data_rdy_trig_poll() the event handler for the data rdy trig + **/ +static int adis16400_data_rdy_trig_poll(struct iio_dev *dev_info, + int index, + s64 timestamp, + int no_test) +{ + struct adis16400_state *st = iio_dev_get_devdata(dev_info); + struct iio_trigger *trig = st->trig; + + trig->timestamp = timestamp; + iio_trigger_poll(trig); + + return IRQ_HANDLED; +} + +IIO_EVENT_SH(data_rdy_trig, &adis16400_data_rdy_trig_poll); + +static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL); + +static struct attribute *adis16400_trigger_attrs[] = { + &dev_attr_name.attr, + NULL, +}; + +static const struct attribute_group adis16400_trigger_attr_group = { + .attrs = adis16400_trigger_attrs, +}; + +/** + * adis16400_data_rdy_trigger_set_state() set datardy interrupt state + **/ +static int adis16400_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct adis16400_state *st = trig->private_data; + struct iio_dev *indio_dev = st->indio_dev; + int ret = 0; + + dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); + ret = adis16400_set_irq(&st->indio_dev->dev, state); + if (state == false) { + iio_remove_event_from_list(&iio_event_data_rdy_trig, + &indio_dev->interrupts[0] + ->ev_list); + /* possible quirk with handler currently worked around + by ensuring the work queue is empty */ + flush_scheduled_work(); + } else { + iio_add_event_to_list(&iio_event_data_rdy_trig, + &indio_dev->interrupts[0]->ev_list); + } + return ret; +} + +/** + * adis16400_trig_try_reen() try renabling irq for data rdy trigger + * @trig: the datardy trigger + **/ +static int adis16400_trig_try_reen(struct iio_trigger *trig) +{ + struct adis16400_state *st = trig->private_data; + enable_irq(st->us->irq); + /* irq reenabled so success! */ + return 0; +} + +int adis16400_probe_trigger(struct iio_dev *indio_dev) +{ + int ret; + struct adis16400_state *st = indio_dev->dev_data; + + st->trig = iio_allocate_trigger(); + st->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL); + if (!st->trig->name) { + ret = -ENOMEM; + goto error_free_trig; + } + snprintf((char *)st->trig->name, + IIO_TRIGGER_NAME_LENGTH, + "adis16400-dev%d", indio_dev->id); + st->trig->dev.parent = &st->us->dev; + st->trig->owner = THIS_MODULE; + st->trig->private_data = st; + st->trig->set_trigger_state = &adis16400_data_rdy_trigger_set_state; + st->trig->try_reenable = &adis16400_trig_try_reen; + st->trig->control_attrs = &adis16400_trigger_attr_group; + ret = iio_trigger_register(st->trig); + + /* select default trigger */ + indio_dev->trig = st->trig; + if (ret) + goto error_free_trig_name; + + return 0; + +error_free_trig_name: + kfree(st->trig->name); +error_free_trig: + iio_free_trigger(st->trig); + + return ret; +} + +void adis16400_remove_trigger(struct iio_dev *indio_dev) +{ + struct adis16400_state *state = indio_dev->dev_data; + + iio_trigger_unregister(state->trig); + kfree(state->trig->name); + iio_free_trigger(state->trig); +} diff --git a/drivers/staging/iio/magnetometer/magnet.h b/drivers/staging/iio/magnetometer/magnet.h new file mode 100644 index 000000000000..6f6c6ed91fa7 --- /dev/null +++ b/drivers/staging/iio/magnetometer/magnet.h @@ -0,0 +1,31 @@ + +#include "../sysfs.h" + +/* Magnetometer types of attribute */ + +#define IIO_DEV_ATTR_MAGN_X_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(magn_x_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_MAGN_Y_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(magn_y_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_MAGN_Z_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(magn_z_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_MAGN_X_GAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(magn_x_gain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_MAGN_Y_GAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(magn_y_gain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_MAGN_Z_GAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(magn_z_gain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_MAGN_X(_show, _addr) \ + IIO_DEVICE_ATTR(magn_x, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_MAGN_Y(_show, _addr) \ + IIO_DEVICE_ATTR(magn_y, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_MAGN_Z(_show, _addr) \ + IIO_DEVICE_ATTR(magn_z, S_IRUGO, _show, NULL, _addr) -- cgit v1.2.3 From 375d65db27544a183aed5e14aa2ed487c796c78d Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 4 May 2010 20:40:12 +0100 Subject: Staging: rar and memrar updates rar: perform a clean up pass - Move to a registration model where each RAR is claimed/unclaimed - Use that to fix the client stuff (one client per RAR so no need to queue stuff) - Support unregister so drivers can rmmod themselves safely - Fix locking hang on calling rar lock from rar callback - Clean up - Kerneldoc Folded in the memrar update as Greg asked - Fix various unload related bugs - Use the per RAR allocator/deallocator - Add kerneldoc Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/memrar/memrar_handler.c | 469 +++++++++++---------- drivers/staging/rar_register/rar_register.c | 610 +++++++++++++++------------- drivers/staging/rar_register/rar_register.h | 62 +-- 3 files changed, 610 insertions(+), 531 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/memrar/memrar_handler.c b/drivers/staging/memrar/memrar_handler.c index 3e0dfe365769..efa7fd62d390 100644 --- a/drivers/staging/memrar/memrar_handler.c +++ b/drivers/staging/memrar/memrar_handler.c @@ -114,6 +114,7 @@ struct memrar_rar_info { struct memrar_allocator *allocator; struct memrar_buffer_info buffers; struct mutex lock; + int allocated; /* True if we own this RAR */ }; /* @@ -150,11 +151,13 @@ static struct memrar_rar_info *memrar_get_rar_info(u32 vaddr) return NULL; } -/* - * Retrieve bus address from given handle. +/** + * memrar_get_bus address - handle to bus address + * + * Retrieve bus address from given handle. * - * Returns address corresponding to given handle. Zero if handle is - * invalid. + * Returns address corresponding to given handle. Zero if handle is + * invalid. */ static dma_addr_t memrar_get_bus_address( struct memrar_rar_info *rar, @@ -176,11 +179,13 @@ static dma_addr_t memrar_get_bus_address( return rar->base + (vaddr - iobase); } -/* - * Retrieve physical address from given handle. +/** + * memrar_get_physical_address - handle to physical address + * + * Retrieve physical address from given handle. * - * Returns address corresponding to given handle. Zero if handle is - * invalid. + * Returns address corresponding to given handle. Zero if handle is + * invalid. */ static dma_addr_t memrar_get_physical_address( struct memrar_rar_info *rar, @@ -195,11 +200,15 @@ static dma_addr_t memrar_get_physical_address( return memrar_get_bus_address(rar, vaddr); } -/* - * Core block release code. +/** + * memrar_release_block - release a block to the pool + * @kref: kref of block + * + * Core block release code. A node has hit zero references so can + * be released and the lists must be updated. * - * Note: This code removes the node from a list. Make sure any list - * iteration is performed using list_for_each_safe(). + * Note: This code removes the node from a list. Make sure any list + * iteration is performed using list_for_each_safe(). */ static void memrar_release_block_i(struct kref *ref) { @@ -224,10 +233,15 @@ static void memrar_release_block_i(struct kref *ref) kfree(node); } -/* - * Initialize RAR parameters, such as bus addresses, etc. +/** + * memrar_init_rar_resources - configure a RAR + * @rarnum: rar that has been allocated + * @devname: name of our device + * + * Initialize RAR parameters, such as bus addresses, etc and make + * the resource accessible. */ -static int memrar_init_rar_resources(char const *devname) +static int memrar_init_rar_resources(int rarnum, char const *devname) { /* ---- Sanity Checks ---- * 1. RAR bus addresses in both Lincroft and Langwell RAR @@ -258,162 +272,95 @@ static int memrar_init_rar_resources(char const *devname) */ static size_t const RAR_BLOCK_SIZE = PAGE_SIZE; - int z; - int found_rar = 0; + dma_addr_t low, high; + struct memrar_rar_info * const rar = &memrars[rarnum]; BUG_ON(MRST_NUM_RAR != ARRAY_SIZE(memrars)); + BUG_ON(!memrar_is_valid_rar_type(rarnum)); + BUG_ON(rar->allocated); - for (z = 0; z != MRST_NUM_RAR; ++z) { - dma_addr_t low, high; - struct memrar_rar_info * const rar = &memrars[z]; - - BUG_ON(!memrar_is_valid_rar_type(z)); - - mutex_init(&rar->lock); - - /* - * Initialize the process table before we reach any - * code that exit on failure since the finalization - * code requires an initialized list. - */ - INIT_LIST_HEAD(&rar->buffers.list); - - if (rar_get_address(z, &low, &high) != 0) { - /* No RAR is available. */ - break; - } else if (low == 0 || high == 0) { - /* - * We don't immediately break out of the loop - * since the next type of RAR may be enabled. - */ - rar->base = 0; - rar->length = 0; - rar->iobase = NULL; - rar->allocator = NULL; - continue; - } - - /* - * @todo Verify that LNC and LNW RAR register contents - * addresses, security, etc are compatible and - * consistent). - */ - - rar->length = high - low + 1; - - /* Claim RAR memory as our own. */ - if (request_mem_region(low, rar->length, devname) == NULL) { - rar->length = 0; - - pr_err("%s: Unable to claim RAR[%d] memory.\n", - devname, - z); - pr_err("%s: RAR[%d] disabled.\n", devname, z); - - /* - * Rather than break out of the loop by - * returning -EBUSY, for example, we may be - * able to claim memory of the next RAR region - * as our own. - */ - continue; - } - - rar->base = low; - - /* - * Now map it into the kernel address space. - * - * Note that the RAR memory may only be accessed by IA - * when debugging. Otherwise attempts to access the - * RAR memory when it is locked down will result in - * behavior similar to writing to /dev/null and - * reading from /dev/zero. This behavior is enforced - * by the hardware. Even if we don't access the - * memory, mapping it into the kernel provides us with - * a convenient RAR handle to bus address mapping. - */ - rar->iobase = ioremap_nocache(rar->base, rar->length); - if (rar->iobase == NULL) { - pr_err("%s: Unable to map RAR memory.\n", - devname); - return -ENOMEM; - } - - /* Initialize corresponding memory allocator. */ - rar->allocator = memrar_create_allocator( - (unsigned long) rar->iobase, - rar->length, - RAR_BLOCK_SIZE); - if (rar->allocator == NULL) - return -1; + mutex_init(&rar->lock); - /* - * ------------------------------------------------- - * Make sure all RARs handled by us are locked down. - * ------------------------------------------------- - */ + /* + * Initialize the process table before we reach any + * code that exit on failure since the finalization + * code requires an initialized list. + */ + INIT_LIST_HEAD(&rar->buffers.list); - /* Enable RAR protection on the Lincroft side. */ - if (0) { - /* - * This is mostly a sanity check since the - * vendor should have locked down RAR in the - * SMIP header RAR configuration. - */ - rar_lock(z); - } else { - pr_warning("%s: LNC RAR[%d] no lock sanity check.\n", - devname, - z); - } + if (rar_get_address(rarnum, &low, &high) != 0) + /* No RAR is available. */ + return -ENODEV; + + if (low == 0 || high == 0) { + rar->base = 0; + rar->length = 0; + rar->iobase = NULL; + rar->allocator = NULL; + return -ENOSPC; + } - /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ - /* |||||||||||||||||||||||||||||||||||||||||||||||||| */ + /* + * @todo Verify that LNC and LNW RAR register contents + * addresses, security, etc are compatible and + * consistent). + */ - /* - * It would be nice if we could verify that RAR - * protection on the Langwell side is enabled, but - * there is no way to do that from here. The - * necessary Langwell RAR registers are not accessible - * from the Lincroft (IA) side. - * - * Hopefully the ODM did the right thing and enabled - * Langwell side RAR protection in the integrated - * firmware SMIP header. - */ + rar->length = high - low + 1; - pr_info("%s: BRAR[%d] bus address range = " - "[0x%lx, 0x%lx]\n", - devname, - z, - (unsigned long) low, - (unsigned long) high); + /* Claim RAR memory as our own. */ + if (request_mem_region(low, rar->length, devname) == NULL) { + rar->length = 0; + pr_err("%s: Unable to claim RAR[%d] memory.\n", devname, rarnum); + pr_err("%s: RAR[%d] disabled.\n", devname, rarnum); + return -EBUSY; + } - pr_info("%s: BRAR[%d] size = %zu KiB\n", - devname, - z, - rar->allocator->capacity / 1024); + rar->base = low; - found_rar = 1; + /* + * Now map it into the kernel address space. + * + * Note that the RAR memory may only be accessed by IA + * when debugging. Otherwise attempts to access the + * RAR memory when it is locked down will result in + * behavior similar to writing to /dev/null and + * reading from /dev/zero. This behavior is enforced + * by the hardware. Even if we don't access the + * memory, mapping it into the kernel provides us with + * a convenient RAR handle to bus address mapping. + */ + rar->iobase = ioremap_nocache(rar->base, rar->length); + if (rar->iobase == NULL) { + pr_err("%s: Unable to map RAR memory.\n", devname); + release_mem_region(low, rar->length); + return -ENOMEM; } - if (!found_rar) { - /* - * No RAR support. Don't bother continuing. - * - * Note that this is not a failure. - */ - pr_info("%s: No Moorestown RAR support available.\n", - devname); - return -ENODEV; + /* Initialize corresponding memory allocator. */ + rar->allocator = memrar_create_allocator((unsigned long) rar->iobase, + rar->length, RAR_BLOCK_SIZE); + if (rar->allocator == NULL) { + iounmap(rar->iobase); + release_mem_region(low, rar->length); + return -ENOMEM; } + pr_info("%s: BRAR[%d] bus address range = [0x%lx, 0x%lx]\n", + devname, rarnum, (unsigned long) low, (unsigned long) high); + + pr_info("%s: BRAR[%d] size = %zu KiB\n", + devname, rarnum, rar->allocator->capacity / 1024); + + rar->allocated = 1; return 0; } -/* - * Finalize RAR resources. +/** + * memrar_fini_rar_resources - free up RAR resources + * + * Finalize RAR resources. Free up the resource tables, hand the memory + * back to the kernel, unmap the device and release the address space. */ static void memrar_fini_rar_resources(void) { @@ -429,6 +376,9 @@ static void memrar_fini_rar_resources(void) for (z = MRST_NUM_RAR; z-- != 0; ) { struct memrar_rar_info * const rar = &memrars[z]; + if (!rar->allocated) + continue; + /* Clean up remaining resources. */ list_for_each_entry_safe(pos, @@ -442,15 +392,25 @@ static void memrar_fini_rar_resources(void) rar->allocator = NULL; iounmap(rar->iobase); - rar->iobase = NULL; - release_mem_region(rar->base, rar->length); - rar->base = 0; + rar->iobase = NULL; + rar->base = 0; rar->length = 0; + + unregister_rar(z); } } +/** + * memrar_reserve_block - handle an allocation request + * @request: block being requested + * @filp: owner it is tied to + * + * Allocate a block of the requested RAR. If successful return the + * request object filled in and zero, if not report an error code + */ + static long memrar_reserve_block(struct RAR_buffer *request, struct file *filp) { @@ -465,6 +425,8 @@ static long memrar_reserve_block(struct RAR_buffer *request, return -EINVAL; rar = &memrars[rinfo->type]; + if (!rar->allocated) + return -ENODEV; /* Reserve memory in RAR. */ handle = memrar_allocator_alloc(rar->allocator, rinfo->size); @@ -504,6 +466,14 @@ static long memrar_reserve_block(struct RAR_buffer *request, return 0; } +/** + * memrar_release_block - release a RAR block + * @addr: address in RAR space + * + * Release a previously allocated block. Releases act on complete + * blocks, partially freeing a block is not supported + */ + static long memrar_release_block(u32 addr) { struct memrar_buffer_info *pos; @@ -512,7 +482,7 @@ static long memrar_release_block(u32 addr) long result = -EINVAL; if (rar == NULL) - return -EFAULT; + return -ENOENT; mutex_lock(&rar->lock); @@ -550,34 +520,48 @@ static long memrar_release_block(u32 addr) return result; } +/** + * memrar_get_stats - read statistics for a RAR + * @r: statistics to be filled in + * + * Returns the statistics data for the RAR, or an error code if + * the request cannot be completed + */ static long memrar_get_stat(struct RAR_stat *r) { - long result = -EINVAL; - - if (likely(r != NULL) && memrar_is_valid_rar_type(r->type)) { - struct memrar_allocator * const allocator = - memrars[r->type].allocator; - - BUG_ON(allocator == NULL); + struct memrar_allocator *allocator; - /* - * Allocator capacity doesn't change over time. No - * need to synchronize. - */ - r->capacity = allocator->capacity; + if (!memrar_is_valid_rar_type(r->type)) + return -EINVAL; - mutex_lock(&allocator->lock); + if (!memrars[r->type].allocated) + return -ENODEV; - r->largest_block_size = allocator->largest_free_area; + allocator = memrars[r->type].allocator; - mutex_unlock(&allocator->lock); + BUG_ON(allocator == NULL); - result = 0; - } + /* + * Allocator capacity doesn't change over time. No + * need to synchronize. + */ + r->capacity = allocator->capacity; - return result; + mutex_lock(&allocator->lock); + r->largest_block_size = allocator->largest_free_area; + mutex_unlock(&allocator->lock); + return 0; } +/** + * memrar_ioctl - ioctl callback + * @filp: file issuing the request + * @cmd: command + * @arg: pointer to control information + * + * Perform one of the ioctls supported by the memrar device + */ + static long memrar_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) @@ -640,6 +624,15 @@ static long memrar_ioctl(struct file *filp, return 0; } +/** + * memrar_mmap - mmap helper for deubgging + * @filp: handle doing the mapping + * @vma: memory area + * + * Support the mmap operation on the RAR space for debugging systems + * when the memory is not locked down. + */ + static int memrar_mmap(struct file *filp, struct vm_area_struct *vma) { /* @@ -660,9 +653,12 @@ static int memrar_mmap(struct file *filp, struct vm_area_struct *vma) unsigned long const handle = vma->vm_pgoff << PAGE_SHIFT; struct memrar_rar_info * const rar = memrar_get_rar_info(handle); - unsigned long pfn; + /* Only allow priviledged apps to go poking around this way */ + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + /* Invalid RAR handle or size passed to mmap(). */ if (rar == NULL || handle == 0 @@ -698,13 +694,32 @@ static int memrar_mmap(struct file *filp, struct vm_area_struct *vma) return 0; } +/** + * memrar_open - device open method + * @inode: inode to open + * @filp: file handle + * + * As we support multiple arbitary opens there is no work to be done + * really. + */ + static int memrar_open(struct inode *inode, struct file *filp) { - /* Nothing to do yet. */ - + nonseekable_open(inode, filp); return 0; } +/** + * memrar_release - close method for miscev + * @inode: inode of device + * @filp: handle that is going away + * + * Free up all the regions that belong to this file handle. We use + * the handle as a natural Linux style 'lifetime' indicator and to + * ensure resources are not leaked when their owner explodes in an + * unplanned fashion. + */ + static int memrar_release(struct inode *inode, struct file *filp) { /* Free all regions associated with the given file handle. */ @@ -733,9 +748,15 @@ static int memrar_release(struct inode *inode, struct file *filp) return 0; } -/* - * This function is part of the kernel space memrar driver API. +/** + * rar_reserve - reserve RAR memory + * @buffers: buffers to reserve + * @count: number wanted + * + * Reserve a series of buffers in the RAR space. Returns the number of + * buffers successfully allocated */ + size_t rar_reserve(struct RAR_buffer *buffers, size_t count) { struct RAR_buffer * const end = @@ -755,9 +776,14 @@ size_t rar_reserve(struct RAR_buffer *buffers, size_t count) } EXPORT_SYMBOL(rar_reserve); -/* - * This function is part of the kernel space memrar driver API. +/** + * rar_release - return RAR buffers + * @buffers: buffers to release + * @size: size of released block + * + * Return a set of buffers to the RAR pool */ + size_t rar_release(struct RAR_buffer *buffers, size_t count) { struct RAR_buffer * const end = @@ -786,9 +812,16 @@ size_t rar_release(struct RAR_buffer *buffers, size_t count) } EXPORT_SYMBOL(rar_release); -/* - * This function is part of the kernel space driver API. +/** + * rar_handle_to_bus - RAR to bus address + * @buffers: RAR buffer structure + * @count: number of buffers to convert + * + * Turn a list of RAR handle mappings into actual bus addresses. Note + * that when the device is locked down the bus addresses in question + * are not CPU accessible. */ + size_t rar_handle_to_bus(struct RAR_buffer *buffers, size_t count) { struct RAR_buffer * const end = @@ -878,43 +911,70 @@ static char const banner[] __initdata = KERN_INFO "Intel RAR Handler: " MEMRAR_VER " initialized.\n"; -static int memrar_registration_callback(void *ctx) +/** + * memrar_registration_callback - RAR obtained + * @rar: RAR number + * + * We have been granted ownership of the RAR. Add it to our memory + * management tables + */ + +static int memrar_registration_callback(unsigned long rar) { /* * We initialize the RAR parameters early on so that we can * discontinue memrar device initialization and registration * if suitably configured RARs are not available. */ - int result = memrar_init_rar_resources(memrar_miscdev.name); + return memrar_init_rar_resources(rar, memrar_miscdev.name); +} - if (result != 0) - return result; +/** + * memrar_init - initialise RAR support + * + * Initialise support for RAR handlers. This may get loaded before + * the RAR support is activated, but the callbacks on the registration + * will handle that situation for us anyway. + */ - result = misc_register(&memrar_miscdev); +static int __init memrar_init(void) +{ + int err; - if (result != 0) { - pr_err("%s: misc_register() failed.\n", - memrar_miscdev.name); + printk(banner); - /* Clean up resources previously reserved. */ - memrar_fini_rar_resources(); - } + err = misc_register(&memrar_miscdev); + if (err) + return err; - return result; -} + /* Now claim the two RARs we want */ + err = register_rar(0, memrar_registration_callback, 0); + if (err) + goto fail; -static int __init memrar_init(void) -{ - printk(banner); + err = register_rar(1, memrar_registration_callback, 1); + if (err == 0) + return 0; - return register_rar(&memrar_registration_callback, 0); + /* It is possible rar 0 registered and allocated resources then rar 1 + failed so do a full resource free */ + memrar_fini_rar_resources(); +fail: + misc_deregister(&memrar_miscdev); + return err; } +/** + * memrar_exit - unregister and unload + * + * Unregister the device and then unload any mappings and release + * the RAR resources + */ + static void __exit memrar_exit(void) { - memrar_fini_rar_resources(); - misc_deregister(&memrar_miscdev); + memrar_fini_rar_resources(); } @@ -925,7 +985,6 @@ module_exit(memrar_exit); MODULE_AUTHOR("Ossama Othman "); MODULE_DESCRIPTION("Intel Restricted Access Region Handler"); MODULE_LICENSE("GPL"); -MODULE_ALIAS_MISCDEV(MISC_DYNAMIC_MINOR); MODULE_VERSION(MEMRAR_VER); diff --git a/drivers/staging/rar_register/rar_register.c b/drivers/staging/rar_register/rar_register.c index bfc0e31f1a6f..618503f422ef 100644 --- a/drivers/staging/rar_register/rar_register.c +++ b/drivers/staging/rar_register/rar_register.c @@ -51,98 +51,159 @@ #include /* === Lincroft Message Bus Interface === */ -/* Message Control Register */ -#define LNC_MCR_OFFSET 0xD0 - -/* Maximum number of clients (other drivers using this driver) */ -#define MAX_RAR_CLIENTS 10 - -/* Message Data Register */ -#define LNC_MDR_OFFSET 0xD4 +#define LNC_MCR_OFFSET 0xD0 /* Message Control Register */ +#define LNC_MDR_OFFSET 0xD4 /* Message Data Register */ /* Message Opcodes */ -#define LNC_MESSAGE_READ_OPCODE 0xD0 +#define LNC_MESSAGE_READ_OPCODE 0xD0 #define LNC_MESSAGE_WRITE_OPCODE 0xE0 /* Message Write Byte Enables */ -#define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF +#define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF /* B-unit Port */ -#define LNC_BUNIT_PORT 0x3 +#define LNC_BUNIT_PORT 0x3 /* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */ -#define LNC_BRAR0L 0x10 -#define LNC_BRAR0H 0x11 -#define LNC_BRAR1L 0x12 -#define LNC_BRAR1H 0x13 - +#define LNC_BRAR0L 0x10 +#define LNC_BRAR0H 0x11 +#define LNC_BRAR1L 0x12 +#define LNC_BRAR1H 0x13 /* Reserved for SeP */ -#define LNC_BRAR2L 0x14 -#define LNC_BRAR2H 0x15 +#define LNC_BRAR2L 0x14 +#define LNC_BRAR2H 0x15 /* Moorestown supports three restricted access regions. */ #define MRST_NUM_RAR 3 - /* RAR Bus Address Range */ -struct RAR_address_range { +struct rar_addr { dma_addr_t low; dma_addr_t high; }; -/* Structure containing low and high RAR register offsets. */ -struct RAR_offsets { - u32 low; /* Register offset for low RAR bus address. */ - u32 high; /* Register offset for high RAR bus address. */ -}; - +/* + * We create one of these for each RAR + */ struct client { - int (*client_callback)(void *client_data); - void *customer_data; - int client_called; - }; + int (*callback)(unsigned long data); + unsigned long driver_priv; + bool busy; +}; static DEFINE_MUTEX(rar_mutex); static DEFINE_MUTEX(lnc_reg_mutex); -struct RAR_device { - struct RAR_offsets const rar_offsets[MRST_NUM_RAR]; - struct RAR_address_range rar_addr[MRST_NUM_RAR]; +/* + * One per RAR device (currently only one device) + */ +struct rar_device { + struct rar_addr rar_addr[MRST_NUM_RAR]; struct pci_dev *rar_dev; bool registered; - }; - -/* this platform has only one rar_device for 3 rar regions */ -static struct RAR_device my_rar_device = { - .rar_offsets = { - [0].low = LNC_BRAR0L, - [0].high = LNC_BRAR0H, - [1].low = LNC_BRAR1L, - [1].high = LNC_BRAR1H, - [2].low = LNC_BRAR2L, - [2].high = LNC_BRAR2H - } + bool allocated; + struct client client[MRST_NUM_RAR]; }; -/* this data is for handling requests from other drivers which arrive - * prior to this driver initializing +/* Current platforms have only one rar_device for 3 rar regions */ +static struct rar_device my_rar_device; + +/* + * Abstract out multiple device support. Current platforms only + * have a single RAR device. */ -static struct client clients[MAX_RAR_CLIENTS]; -static int num_clients; +/** + * alloc_rar_device - return a new RAR structure + * + * Return a new (but not yet ready) RAR device object + */ +static struct rar_device *alloc_rar_device(void) +{ + if (my_rar_device.allocated) + return NULL; + my_rar_device.allocated = 1; + return &my_rar_device; +} -/* - * This function is used to retrieved RAR info using the Lincroft - * message bus interface. +/** + * free_rar_device - free a RAR object + * @rar: the RAR device being freed + * + * Release a RAR object and any attached resources */ -static int retrieve_rar_addr(struct pci_dev *pdev, - int offset, - dma_addr_t *addr) +static void free_rar_device(struct rar_device *rar) +{ + pci_dev_put(rar->rar_dev); + rar->allocated = 0; +} + +/** + * _rar_to_device - return the device handling this RAR + * @rar: RAR number + * @off: returned offset + * + * Internal helper for looking up RAR devices. This and alloc are the + * two functions that need touching to go to multiple RAR devices. + */ +static struct rar_device *_rar_to_device(int rar, int *off) +{ + if (rar >= 0 && rar <= 3) { + *off = rar; + return &my_rar_device; + } + return NULL; +} + + +/** + * rar_to_device - return the device handling this RAR + * @rar: RAR number + * @off: returned offset + * + * Return the device this RAR maps to if one is present, otherwise + * returns NULL. Reports the offset relative to the base of this + * RAR device in off. + */ +static struct rar_device *rar_to_device(int rar, int *off) +{ + struct rar_device *rar_dev = _rar_to_device(rar, off); + if (rar_dev == NULL || !rar_dev->registered) + return NULL; + return rar_dev; +} + +/** + * rar_to_client - return the client handling this RAR + * @rar: RAR number + * + * Return the client this RAR maps to if a mapping is known, otherwise + * returns NULL. + */ +static struct client *rar_to_client(int rar) +{ + int idx; + struct rar_device *r = _rar_to_device(rar, &idx); + if (r != NULL) + return &r->client[idx]; + return NULL; +} + +/** + * rar_read_addr - retrieve a RAR mapping + * @pdev: PCI device for the RAR + * @offset: offset for message + * @addr: returned address + * + * Reads the address of a given RAR register. Returns 0 on success + * or an error code on failure. + */ +static int rar_read_addr(struct pci_dev *pdev, int offset, dma_addr_t *addr) { /* * ======== The Lincroft Message Bus Interface ======== - * Lincroft registers may be obtained from the PCI - * (the Host Bridge) using the Lincroft Message Bus + * Lincroft registers may be obtained via PCI from + * the host bridge using the Lincroft Message Bus * Interface. That message bus interface is generally * comprised of two registers: a control register (MCR, 0xDO) * and a data register (MDR, 0xD4). @@ -182,6 +243,7 @@ static int retrieve_rar_addr(struct pci_dev *pdev, */ int result; + u32 addr32; /* Construct control message */ u32 const message = @@ -192,11 +254,6 @@ static int retrieve_rar_addr(struct pci_dev *pdev, dev_dbg(&pdev->dev, "Offset for 'get' LNC MSG is %x\n", offset); - if (addr == 0) { - WARN_ON(1); - return -EINVAL; - } - /* * We synchronize access to the Lincroft MCR and MDR registers * until BOTH the command is issued through the MCR register @@ -209,26 +266,25 @@ static int retrieve_rar_addr(struct pci_dev *pdev, /* Send the control message */ result = pci_write_config_dword(pdev, LNC_MCR_OFFSET, message); - - dev_dbg(&pdev->dev, "Result from send ctl register is %x\n", result); - if (!result) { - result = pci_read_config_dword(pdev, LNC_MDR_OFFSET, - (u32 *)addr); - dev_dbg(&pdev->dev, - "Result from read data register is %x\n", result); - - dev_dbg(&pdev->dev, - "Value read from data register is %lx\n", - (unsigned long)*addr); + /* Read back the address as a 32bit value */ + result = pci_read_config_dword(pdev, LNC_MDR_OFFSET, &addr32); + *addr = (dma_addr_t)addr32; } - mutex_unlock(&lnc_reg_mutex); - return result; } -static int set_rar_address(struct pci_dev *pdev, +/** + * rar_set_addr - Set a RAR mapping + * @pdev: PCI device for the RAR + * @offset: offset for message + * @addr: address to set + * + * Sets the address of a given RAR register. Returns 0 on success + * or an error code on failure. + */ +static int rar_set_addr(struct pci_dev *pdev, int offset, dma_addr_t addr) { @@ -236,11 +292,11 @@ static int set_rar_address(struct pci_dev *pdev, * Data being written to this register must be written before * writing the appropriate control message to the MCR * register. - * @note See rar_get_address() for a description of the + * See rar_get_addrs() for a description of the * message bus interface being used here. */ - int result = 0; + int result; /* Construct control message */ u32 const message = (LNC_MESSAGE_WRITE_OPCODE << 24) @@ -248,13 +304,6 @@ static int set_rar_address(struct pci_dev *pdev, | (offset << 8) | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4); - if (addr == 0) { - WARN_ON(1); - return -EINVAL; - } - - dev_dbg(&pdev->dev, "Offset for 'set' LNC MSG is %x\n", offset); - /* * We synchronize access to the Lincroft MCR and MDR registers * until BOTH the command is issued through the MCR register @@ -267,32 +316,27 @@ static int set_rar_address(struct pci_dev *pdev, /* Send the control message */ result = pci_write_config_dword(pdev, LNC_MDR_OFFSET, addr); - - dev_dbg(&pdev->dev, "Result from write data register is %x\n", result); - - if (!result) { - dev_dbg(&pdev->dev, - "Value written to data register is %lx\n", - (unsigned long)addr); - + if (!result) + /* And address */ result = pci_write_config_dword(pdev, LNC_MCR_OFFSET, message); - dev_dbg(&pdev->dev, "Result from send ctl register is %x\n", - result); - } - mutex_unlock(&lnc_reg_mutex); - return result; } /* -* Initialize RAR parameters, such as bus addresses, etc. -*/ -static int init_rar_params(struct pci_dev *pdev) + * rar_init_params - Initialize RAR parameters + * @rar: RAR device to initialise + * + * Initialize RAR parameters, such as bus addresses, etc. Returns 0 + * on success, or an error code on failure. + */ +static int init_rar_params(struct rar_device *rar) { + struct pci_dev *pdev = rar->rar_dev; unsigned int i; int result = 0; + int offset = 0x10; /* RAR 0 to 2 in order low/high/low/high/... */ /* Retrieve RAR start and end bus addresses. * Access the RAR registers through the Lincroft Message Bus @@ -300,15 +344,16 @@ static int init_rar_params(struct pci_dev *pdev) */ for (i = 0; i < MRST_NUM_RAR; ++i) { - struct RAR_offsets const *offset = - &my_rar_device.rar_offsets[i]; - struct RAR_address_range *addr = &my_rar_device.rar_addr[i]; - - if ((retrieve_rar_addr(pdev, offset->low, &addr->low) != 0) - || (retrieve_rar_addr(pdev, offset->high, &addr->high) != 0)) { - result = -1; - break; - } + struct rar_addr *addr = &rar->rar_addr[i]; + + result = rar_read_addr(pdev, offset++, &addr->low); + if (result != 0) + return result; + + result = rar_read_addr(pdev, offset++, &addr->high); + if (result != 0) + return result; + /* * Only the upper 22 bits of the RAR addresses are @@ -336,201 +381,237 @@ static int init_rar_params(struct pci_dev *pdev) /* Done accessing the device. */ if (result == 0) { - int z; - for (z = 0; z != MRST_NUM_RAR; ++z) { + for (i = 0; i != MRST_NUM_RAR; ++i) { /* * "BRAR" refers to the RAR registers in the * Lincroft B-unit. */ dev_info(&pdev->dev, "BRAR[%u] bus address range = " - "[%lx, %lx]\n", z, - (unsigned long)my_rar_device.rar_addr[z].low, - (unsigned long)my_rar_device.rar_addr[z].high); + "[%lx, %lx]\n", i, + (unsigned long)rar->rar_addr[i].low, + (unsigned long)rar->rar_addr[i].high); } } - return result; } -/* - * The rar_get_address function is used by other device drivers - * to obtain RAR address information on a RAR. It takes three - * parameters: +/** + * rar_get_address - get the bus address in a RAR + * @start: return value of start address of block + * @end: return value of end address of block * - * int rar_index - * The rar_index is an index to the rar for which you wish to retrieve - * the address information. - * Values can be 0,1, or 2. + * The rar_get_address function is used by other device drivers + * to obtain RAR address information on a RAR. It takes three + * parameters: * - * The function returns a 0 upon success or a -1 if there is no RAR - * facility on this system. + * The function returns a 0 upon success or an error if there is no RAR + * facility on this system. */ -int rar_get_address(int rar_index, - dma_addr_t *start_address, - dma_addr_t *end_address) +int rar_get_address(int rar_index, dma_addr_t *start, dma_addr_t *end) { - int result = -ENODEV; - - if (my_rar_device.registered) { - if (start_address == 0 || end_address == 0 - || rar_index >= MRST_NUM_RAR || rar_index < 0) { - result = -EINVAL; - } else { - *start_address = - my_rar_device.rar_addr[rar_index].low; - *end_address = - my_rar_device.rar_addr[rar_index].high; - - result = 0; - } + int idx; + struct rar_device *rar = rar_to_device(rar_index, &idx); + + if (rar == NULL) { + WARN_ON(1); + return -ENODEV; } - return result; + *start = rar->rar_addr[idx].low; + *end = rar->rar_addr[idx].high; + return 0; } EXPORT_SYMBOL(rar_get_address); -/* - * The rar_lock function is ued by other device drivers to lock an RAR. - * once an RAR is locked, it stays locked until the next system reboot. - * The function takes one parameter: +/** + * rar_lock - lock a RAR register + * @rar_index: RAR to lock (0-2) * - * int rar_index - * The rar_index is an index to the rar that you want to lock. - * Values can be 0,1, or 2. + * The rar_lock function is ued by other device drivers to lock an RAR. + * once a RAR is locked, it stays locked until the next system reboot. * - * The function returns a 0 upon success or a -1 if there is no RAR - * facility on this system. + * The function returns a 0 upon success or an error if there is no RAR + * facility on this system, or the locking fails */ int rar_lock(int rar_index) { - int result = -ENODEV; - - if (rar_index >= MRST_NUM_RAR || rar_index < 0) { - result = -EINVAL; - return result; - } - - dev_dbg(&my_rar_device.rar_dev->dev, "rar_lock mutex locking\n"); - mutex_lock(&rar_mutex); + struct rar_device *rar; + int result; + int idx; + dma_addr_t low, high; - if (my_rar_device.registered) { + rar = rar_to_device(rar_index, &idx); - dma_addr_t low = my_rar_device.rar_addr[rar_index].low & - 0xfffffc00u; + if (rar == NULL) { + WARN_ON(1); + return -EINVAL; + } - dma_addr_t high = my_rar_device.rar_addr[rar_index].high & - 0xfffffc00u; + low = rar->rar_addr[idx].low & 0xfffffc00u; + high = rar->rar_addr[idx].high & 0xfffffc00u; - /* - * Only allow I/O from the graphics and Langwell; - * Not from the x96 processor - */ - if (rar_index == (int)RAR_TYPE_VIDEO) { - low |= 0x00000009; - high |= 0x00000015; - } + /* + * Only allow I/O from the graphics and Langwell; + * not from the x86 processor + */ - else if (rar_index == (int)RAR_TYPE_AUDIO) { - /* Only allow I/O from Langwell; nothing from x86 */ - low |= 0x00000008; - high |= 0x00000018; - } + if (rar_index == RAR_TYPE_VIDEO) { + low |= 0x00000009; + high |= 0x00000015; + } else if (rar_index == RAR_TYPE_AUDIO) { + /* Only allow I/O from Langwell; nothing from x86 */ + low |= 0x00000008; + high |= 0x00000018; + } else + /* Read-only from all agents */ + high |= 0x00000018; - else - /* Read-only from all agents */ - high |= 0x00000018; + /* + * Now program the register using the Lincroft message + * bus interface. + */ + result = rar_set_addr(rar->rar_dev, + 2 * idx, low); - /* - * Now program the register using the Lincroft message - * bus interface. - */ - result = set_rar_address(my_rar_device.rar_dev, - my_rar_device.rar_offsets[rar_index].low, - low); - - if (result == 0) - result = set_rar_address( - my_rar_device.rar_dev, - my_rar_device.rar_offsets[rar_index].high, - high); - } + if (result == 0) + result = rar_set_addr(rar->rar_dev, + 2 * idx + 1, high); - dev_dbg(&my_rar_device.rar_dev->dev, "rar_lock mutex unlocking\n"); - mutex_unlock(&rar_mutex); return result; } EXPORT_SYMBOL(rar_lock); -/* The register_rar function is to used by other device drivers - * to ensure that this driver is ready. As we cannot be sure of - * the compile/execute order of dirvers in ther kernel, it is - * best to give this driver a callback function to call when - * it is ready to give out addresses. The callback function - * would have those steps that continue the initialization of - * a driver that do require a valid RAR address. One of those - * steps would be to call rar_get_address() - * This function return 0 on success an -1 on failure. -*/ -int register_rar(int (*callback)(void *yourparameter), void *yourparameter) +/** + * register_rar - register a RAR handler + * @num: RAR we wish to register for + * @callback: function to call when RAR support is available + * @data: data to pass to this function + * + * The register_rar function is to used by other device drivers + * to ensure that this driver is ready. As we cannot be sure of + * the compile/execute order of drivers in ther kernel, it is + * best to give this driver a callback function to call when + * it is ready to give out addresses. The callback function + * would have those steps that continue the initialization of + * a driver that do require a valid RAR address. One of those + * steps would be to call rar_get_address() + * + * This function return 0 on success an error code on failure. + */ +int register_rar(int num, int (*callback)(unsigned long data), + unsigned long data) { - - int result = -ENODEV; - - if (callback == NULL) - return -EINVAL; + /* For now we hardcode a single RAR device */ + struct rar_device *rar; + struct client *c; + int idx; + int retval = 0; mutex_lock(&rar_mutex); - if (my_rar_device.registered) { + /* Do we have a client mapping for this RAR number ? */ + c = rar_to_client(num); + if (c == NULL) { + retval = -ERANGE; + goto done; + } + /* Is it claimed ? */ + if (c->busy) { + retval = -EBUSY; + goto done; + } + c->busy = 1; + + /* See if we have a handler for this RAR yet, if we do then fire it */ + rar = rar_to_device(num, &idx); - mutex_unlock(&rar_mutex); + if (rar) { /* * if the driver already registered, then we can simply * call the callback right now */ - - return (*callback)(yourparameter); - } - - if (num_clients < MRST_NUM_RAR) { - - clients[num_clients].client_callback = callback; - clients[num_clients].customer_data = yourparameter; - num_clients += 1; - result = 0; + (*callback)(data); + goto done; } + /* Arrange to be called back when the hardware is found */ + c->callback = callback; + c->driver_priv = data; +done: mutex_unlock(&rar_mutex); - return result; - + return retval; } EXPORT_SYMBOL(register_rar); -/* Suspend - returns -ENOSYS */ -static int rar_suspend(struct pci_dev *dev, pm_message_t state) +/** + * unregister_rar - release a RAR allocation + * @num: RAR number + * + * Releases a RAR allocation, or pending allocation. If a callback is + * pending then this function will either complete before the unregister + * returns or not at all. + */ + +void unregister_rar(int num) { - return -ENOSYS; + struct client *c; + + mutex_lock(&rar_mutex); + c = rar_to_client(num); + if (c == NULL || !c->busy) + WARN_ON(1); + else + c->busy = 0; + mutex_unlock(&rar_mutex); } +EXPORT_SYMBOL(unregister_rar); -static int rar_resume(struct pci_dev *dev) +/** + * rar_callback - Process callbacks + * @rar: new RAR device + * + * Process the callbacks for a newly found RAR device. + */ + +static void rar_callback(struct rar_device *rar) { - return -ENOSYS; + struct client *c = &rar->client[0]; + int i; + + mutex_lock(&rar_mutex); + + rar->registered = 1; /* Ensure no more callbacks queue */ + + for (i = 0; i < MRST_NUM_RAR; i++) { + if (c->callback && c->busy) { + c->callback(c->driver_priv); + c->callback = NULL; + } + c++; + } + mutex_unlock(&rar_mutex); } -/* - * This function registers the driver with the device subsystem ( - * either PCI, USB, etc). - * Function that is activaed on the succesful probe of the RAR device - * (Moorestown host controller). +/** + * rar_probe - PCI probe callback + * @dev: PCI device + * @id: matching entry in the match table + * + * A RAR device has been discovered. Initialise it and if successful + * process any pending callbacks that can now be completed. */ static int rar_probe(struct pci_dev *dev, const struct pci_device_id *id) { int error; - int counter; + struct rar_device *rar; dev_dbg(&dev->dev, "PCI probe starting\n"); - /* enable the device */ + rar = alloc_rar_device(); + if (rar == NULL) + return -EBUSY; + + /* Enable the device */ error = pci_enable_device(dev); if (error) { dev_err(&dev->dev, @@ -538,50 +619,30 @@ static int rar_probe(struct pci_dev *dev, const struct pci_device_id *id) goto end_function; } - /* we have only one device; fill in the rar_device structure */ - my_rar_device.rar_dev = dev; + /* Fill in the rar_device structure */ + rar->rar_dev = pci_dev_get(dev); + pci_set_drvdata(dev, rar); /* - * Initialize the RAR parameters, which have to be retrieved - * via the message bus interface. - */ - error = init_rar_params(dev); + * Initialize the RAR parameters, which have to be retrieved + * via the message bus interface. + */ + error = init_rar_params(rar); if (error) { pci_disable_device(dev); - - dev_err(&dev->dev, - "Error retrieving RAR addresses\n"); - + dev_err(&dev->dev, "Error retrieving RAR addresses\n"); goto end_function; } - - dev_dbg(&dev->dev, "PCI probe locking\n"); - mutex_lock(&rar_mutex); - my_rar_device.registered = 1; - /* now call anyone who has registered (using callbacks) */ - for (counter = 0; counter < num_clients; counter += 1) { - if (clients[counter].client_callback) { - error = (*clients[counter].client_callback)( - clients[counter].customer_data); - /* set callback to NULL to indicate it has been done */ - clients[counter].client_callback = NULL; - dev_dbg(&my_rar_device.rar_dev->dev, - "Callback called for %d\n", - counter); - } - } - - dev_dbg(&dev->dev, "PCI probe unlocking\n"); - mutex_unlock(&rar_mutex); - + rar_callback(rar); + return 0; end_function: - + free_rar_device(rar); return error; } const struct pci_device_id rar_pci_id_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_RAR_DEVICE_ID) }, + { PCI_VDEVICE(INTEL, 0x4110) }, { 0 } }; @@ -594,8 +655,7 @@ static struct pci_driver rar_pci_driver = { .name = "rar_register_driver", .id_table = rar_pci_id_tbl, .probe = rar_probe, - .suspend = rar_suspend, - .resume = rar_resume + /* Cannot be unplugged - no remove */ }; static int __init rar_init_handler(void) diff --git a/drivers/staging/rar_register/rar_register.h b/drivers/staging/rar_register/rar_register.h index 29ade0f361d2..ffa805780f85 100644 --- a/drivers/staging/rar_register/rar_register.h +++ b/drivers/staging/rar_register/rar_register.h @@ -21,63 +21,23 @@ #ifndef _RAR_REGISTER_H #define _RAR_REGISTER_H -# include +#include /* following are used both in drivers as well as user space apps */ -enum RAR_type { - RAR_TYPE_VIDEO = 0, - RAR_TYPE_AUDIO, - RAR_TYPE_IMAGE, - RAR_TYPE_DATA -}; -#ifdef __KERNEL__ +#define RAR_TYPE_VIDEO 0 +#define RAR_TYPE_AUDIO 1 +#define RAR_TYPE_IMAGE 2 +#define RAR_TYPE_DATA 3 -/* PCI device id for controller */ -#define PCI_RAR_DEVICE_ID 0x4110 +#ifdef __KERNEL__ -/* The register_rar function is to used by other device drivers - * to ensure that this driver is ready. As we cannot be sure of - * the compile/execute order of dirvers in ther kernel, it is - * best to give this driver a callback function to call when - * it is ready to give out addresses. The callback function - * would have those steps that continue the initialization of - * a driver that do require a valid RAR address. One of those - * steps would be to call get_rar_address() - * This function return 0 on success an -1 on failure. - */ -int register_rar(int (*callback)(void *yourparameter), void *yourparameter); +struct rar_device; -/* The get_rar_address function is used by other device drivers - * to obtain RAR address information on a RAR. It takes two - * parameter: - * - * int rar_index - * The rar_index is an index to the rar for which you wish to retrieve - * the address information. - * Values can be 0,1, or 2. - * - * struct RAR_address_struct is a pointer to a place to which the function - * can return the address structure for the RAR. - * - * The function returns a 0 upon success or a -1 if there is no RAR - * facility on this system. - */ -int rar_get_address(int rar_index, - dma_addr_t *start_address, - dma_addr_t *end_address); - -/* The lock_rar function is ued by other device drivers to lock an RAR. - * once an RAR is locked, it stays locked until the next system reboot. - * The function takes one parameter: - * - * int rar_index - * The rar_index is an index to the rar that you want to lock. - * Values can be 0,1, or 2. - * - * The function returns a 0 upon success or a -1 if there is no RAR - * facility on this system. - */ +int register_rar(int num, + int (*callback)(unsigned long data), unsigned long data); +void unregister_rar(int num); +int rar_get_address(int rar_index, dma_addr_t *start, dma_addr_t *end); int rar_lock(int rar_index); #endif /* __KERNEL__ */ -- cgit v1.2.3 From 6610944a91079a4002da310d3d5488feaae4a74a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 14:31:18 -0700 Subject: Staging: hv: fix up sparse warning in hyperv_utils.c The function isn't called by anyone else, so mark it static. Also remove version.h, as it is not needed. Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hyperv_utils.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hyperv_utils.c b/drivers/staging/hv/hyperv_utils.c index ca52fbada7d1..cbebad3e40a0 100644 --- a/drivers/staging/hv/hyperv_utils.c +++ b/drivers/staging/hv/hyperv_utils.c @@ -24,7 +24,6 @@ #include #include #include -#include #include "logging.h" #include "osd.h" @@ -38,7 +37,7 @@ #include "utils.h" -void shutdown_onchannelcallback(void *context) +static void shutdown_onchannelcallback(void *context) { struct vmbus_channel *channel = context; u8 *buf; -- cgit v1.2.3 From 30162d690c3539594b6dcebd677c985c6a74249e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:00:02 -0700 Subject: Staging: comedi: mark a variable as __user This is really a userspace pointer, so mark it as such. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index 45272d8bf972..8e4caaacfc1c 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -354,7 +354,7 @@ unsigned int __user *chanlist; /* channel/range list */ unsigned int chanlist_len; - short *data; /* data list, size depends on subd flags */ + short __user *data; /* data list, size depends on subd flags */ unsigned int data_len; }; -- cgit v1.2.3 From 135998cc006c764dcfa147df84185614012852e5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:01:19 -0700 Subject: Staging: comedi: 8255.c: mark some functions static sparse pointed out that these functions should be static, so mark them as such. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 2d54993ffb12..e777ddfc8af0 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -120,8 +120,8 @@ COMEDI_INITCLEANUP(driver_8255); static void do_config(struct comedi_device *dev, struct comedi_subdevice *s); -void subdev_8255_interrupt(struct comedi_device *dev, - struct comedi_subdevice *s) +static void subdev_8255_interrupt(struct comedi_device *dev, + struct comedi_subdevice *s) { short d; @@ -319,9 +319,10 @@ static int subdev_8255_cancel(struct comedi_device *dev, return 0; } -int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, - int (*cb) (int, int, int, unsigned long), - unsigned long arg) +static int subdev_8255_init(struct comedi_device *dev, + struct comedi_subdevice *s, + int (*cb) (int, int, int, unsigned long), + unsigned long arg) { s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; @@ -349,9 +350,10 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, } EXPORT_SYMBOL(subdev_8255_init); -int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, - int (*cb) (int, int, int, unsigned long), - unsigned long arg) +static int subdev_8255_init_irq(struct comedi_device *dev, + struct comedi_subdevice *s, + int (*cb) (int, int, int, unsigned long), + unsigned long arg) { int ret; @@ -369,7 +371,8 @@ int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, } EXPORT_SYMBOL(subdev_8255_init_irq); -void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice *s) +static void subdev_8255_cleanup(struct comedi_device *dev, + struct comedi_subdevice *s) { if (s->private) { /* this test does nothing, so comment it out -- cgit v1.2.3 From 643a5420f1df521e08efae7b15d377314b88cb70 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:02:00 -0700 Subject: Staging: comedi: usbduxfast.c: mark a function static It does not need to be global. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxfast.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 05b1973ea35f..0d72c416e73b 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -525,7 +525,7 @@ static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs, return 0; } -int usbduxfastsub_submit_InURBs(struct usbduxfastsub_s *udfs) +static int usbduxfastsub_submit_InURBs(struct usbduxfastsub_s *udfs) { int ret; -- cgit v1.2.3 From 6dd22814640bf04d2007489d8c1d1e0d24a09128 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:02:39 -0700 Subject: Staging: comedi: addi_common.h: properly mark this variable as __iomem It's not an unsigned long, it's a __iomem pointer, so mark it as such. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h index caeb6fd2d9b1..1a2816920fff 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h @@ -351,7 +351,7 @@ struct addi_private { int i_IobaseAmcc; /* base+size for AMCC chip */ int i_IobaseAddon; /* addon base address */ int i_IobaseReserved; - unsigned long dw_AiBase; + void __iomem *dw_AiBase; struct pcilst_struct *amcc; /* ptr too AMCC data */ unsigned char allocated; /* we have blocked card */ unsigned char b_ValidDriver; /* driver is ok */ -- cgit v1.2.3 From 2f78c64255bc6e960bf822f65bd80830f053e182 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:03:35 -0700 Subject: Staging: comedi: addi_common.c: sparse cleanups Now that we are properly marking the variable as __iomem, don't cast it. Also fix up some other sparse warnings. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_common.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 6625fdc8e903..2c986413a81a 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -293,8 +293,8 @@ static const struct addi_board boardtypes[] = { 0, 0, 0, - 0, - 0, + NULL, + NULL, 32, 0, 0, @@ -2527,7 +2527,7 @@ static const struct addi_board boardtypes[] = { #define n_boardtypes (sizeof(boardtypes)/sizeof(struct addi_board)) -struct comedi_driver driver_addi = { +static struct comedi_driver driver_addi = { .driver_name = "addi_common", .module = THIS_MODULE, .attach = i_ADDI_Attach, @@ -2639,9 +2639,8 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->ps_BoardInfo = this_board; devpriv->i_IobaseReserved = (int) io_addr[3]; printk("\nioremap begin"); - devpriv->dw_AiBase = - (unsigned long) ioremap(io_addr[3], - this_board->i_IorangeBase3); + devpriv->dw_AiBase = ioremap(io_addr[3], + this_board->i_IorangeBase3); printk("\nioremap end"); } @@ -2952,7 +2951,7 @@ static int i_ADDI_Detach(struct comedi_device *dev) devpriv->ui_DmaBufferPages[1]); } } else { - iounmap((void *)devpriv->dw_AiBase); + iounmap(devpriv->dw_AiBase); if (devpriv->allocated) { i_pci_card_free(devpriv->amcc); -- cgit v1.2.3 From ad2d4714a5468ff5fb6414d06b29c8d5ca31d6f9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:04:19 -0700 Subject: Staging: comedi: addi_amcc_s5933.h: sparse cleanup Mark a variable static that does not need to be global. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h index f96b1289cdfc..3682503e3412 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h @@ -212,7 +212,7 @@ struct pcilst_struct { }; /* ptr to root list of all amcc devices */ -struct pcilst_struct *amcc_devices; +static struct pcilst_struct *amcc_devices; static const int i_ADDIDATADeviceID[] = { 0x15B8, 0x10E8 }; -- cgit v1.2.3 From e3752a1dfd8a003139dee2c80de3d915534e2b39 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:05:09 -0700 Subject: Staging: comedi: quatech_daqp_cs.c: fix up the irq The irq needs to return the correct type. Also fix up some other sparse warnings that were found. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/quatech_daqp_cs.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index 3325f24448b5..fb427dbe98f5 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -244,8 +244,7 @@ static int daqp_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) * comedi kernel module, and signal various comedi callback routines, * which run pretty quick. */ - -static void daqp_interrupt(int irq, void *dev_id) +static enum irqreturn daqp_interrupt(int irq, void *dev_id) { struct local_info_t *local = (struct local_info_t *)dev_id; struct comedi_device *dev; @@ -256,32 +255,32 @@ static void daqp_interrupt(int irq, void *dev_id) if (local == NULL) { printk(KERN_WARNING "daqp_interrupt(): irq %d for unknown device.\n", irq); - return; + return IRQ_NONE; } dev = local->dev; if (dev == NULL) { printk(KERN_WARNING "daqp_interrupt(): NULL comedi_device.\n"); - return; + return IRQ_NONE; } if (!dev->attached) { printk(KERN_WARNING "daqp_interrupt(): struct comedi_device not yet attached.\n"); - return; + return IRQ_NONE; } s = local->s; if (s == NULL) { printk(KERN_WARNING "daqp_interrupt(): NULL comedi_subdevice.\n"); - return; + return IRQ_NONE; } if ((struct local_info_t *)s->private != local) { printk(KERN_WARNING "daqp_interrupt(): invalid comedi_subdevice.\n"); - return; + return IRQ_NONE; } switch (local->interrupt_mode) { @@ -340,6 +339,7 @@ static void daqp_interrupt(int irq, void *dev_id) comedi_event(dev, s); } + return IRQ_HANDLED; } /* One-shot analog data acquisition routine */ @@ -580,7 +580,7 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { struct local_info_t *local = (struct local_info_t *)s->private; struct comedi_cmd *cmd = &s->async->cmd; - int counter = 100; + int counter; int scanlist_start_on_every_entry; int threshold; @@ -613,14 +613,14 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) */ if (cmd->convert_src == TRIG_TIMER) { - int counter = daqp_ns_to_timer(&cmd->convert_arg, + counter = daqp_ns_to_timer(&cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK); outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW); outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID); outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH); scanlist_start_on_every_entry = 1; } else { - int counter = daqp_ns_to_timer(&cmd->scan_begin_arg, + counter = daqp_ns_to_timer(&cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK); outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW); outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID); @@ -755,7 +755,7 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* Reset any pending interrupts (my card has a tendancy to require * require multiple reads on the status register to achieve this) */ - + counter = 100; while (--counter && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ; if (!counter) { @@ -1244,7 +1244,7 @@ static struct pcmcia_device_id daqp_cs_id_table[] = { MODULE_DEVICE_TABLE(pcmcia, daqp_cs_id_table); -struct pcmcia_driver daqp_cs_driver = { +static struct pcmcia_driver daqp_cs_driver = { .probe = daqp_cs_attach, .remove = daqp_cs_detach, .suspend = daqp_cs_suspend, -- cgit v1.2.3 From b74a9670857c2af74e36ecbd31bbc55ddd8e1311 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:05:52 -0700 Subject: Staging: comedi: plx9080.h: properly mark iomem variables It's a __iomem *, so mark it as such. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/plx9080.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/plx9080.h b/drivers/staging/comedi/drivers/plx9080.h index 53bcdb7b5c5a..485d63f99293 100644 --- a/drivers/staging/comedi/drivers/plx9080.h +++ b/drivers/staging/comedi/drivers/plx9080.h @@ -380,9 +380,9 @@ enum bigend_bits { #define MBX_ADDR_SPACE_360 0x80 /* wanXL100s/200/400 */ #define MBX_ADDR_MASK_360 (MBX_ADDR_SPACE_360-1) -static inline int plx9080_abort_dma(void *iobase, unsigned int channel) +static inline int plx9080_abort_dma(void __iomem *iobase, unsigned int channel) { - void *dma_cs_addr; + void __iomem *dma_cs_addr; uint8_t dma_status; const int timeout = 10000; unsigned int i; -- cgit v1.2.3 From d18c5906d0914d911a13d342ff61a6bca6aff597 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:06:33 -0700 Subject: Staging: comedi: das1800.c: fix a locking error on the error path. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das1800.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index d91c2d9d595b..de5e82fec878 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -1637,7 +1637,8 @@ static int das1800_ai_rinsn(struct comedi_device *dev, } if (i == timeout) { comedi_error(dev, "timeout"); - return -ETIME; + n = -ETIME; + goto exit; } dpnt = inw(dev->iobase + DAS1800_FIFO); /* shift data to offset binary for bipolar ranges */ @@ -1645,6 +1646,7 @@ static int das1800_ai_rinsn(struct comedi_device *dev, dpnt += 1 << (thisboard->resolution - 1); data[n] = dpnt; } +exit: spin_unlock_irqrestore(&dev->spinlock, irq_flags); return n; -- cgit v1.2.3 From f31d0008cef0df52d1a2662ef56a24bdd88b0105 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:07:03 -0700 Subject: Staging: comedi: cb_pcidas64.c: fix sparse warnings This fixes a bunch of iomem and other sparse warnings. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 54 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 0d9e92e59f9d..3443fc1b9186 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1101,9 +1101,9 @@ struct pcidas64_private { resource_size_t main_phys_iobase; resource_size_t dio_counter_phys_iobase; /* base addresses (ioremapped) */ - void *plx9080_iobase; - void *main_iobase; - void *dio_counter_iobase; + void __iomem *plx9080_iobase; + void __iomem *main_iobase; + void __iomem *dio_counter_iobase; /* local address (used by dma controller) */ uint32_t local0_iobase; uint32_t local1_iobase; @@ -1183,8 +1183,8 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, static irqreturn_t handle_interrupt(int irq, void *d); static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s); static int ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s); -static int dio_callback(int dir, int port, int data, unsigned long arg); -static int dio_callback_4020(int dir, int port, int data, unsigned long arg); +static int dio_callback(int dir, int port, int data, void __iomem *base); +static int dio_callback_4020(int dir, int port, int data, void __iomem *base); static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); static int do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, @@ -1316,7 +1316,7 @@ static inline int ao_cmd_is_supported(const struct pcidas64_board *board) static void init_plx9080(struct comedi_device *dev) { uint32_t bits; - void *plx_iobase = priv(dev)->plx9080_iobase; + void __iomem *plx_iobase = priv(dev)->plx9080_iobase; priv(dev)->plx_control_bits = readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG); @@ -1406,7 +1406,7 @@ static void init_plx9080(struct comedi_device *dev) static int setup_subdevices(struct comedi_device *dev) { struct comedi_subdevice *s; - void *dio_8255_iobase; + void __iomem *dio_8255_iobase; int i; if (alloc_subdevices(dev, 10) < 0) @@ -1432,7 +1432,6 @@ static int setup_subdevices(struct comedi_device *dev) s->do_cmdtest = ai_cmdtest; s->cancel = ai_cancel; if (board(dev)->layout == LAYOUT_4020) { - unsigned int i; uint8_t data; /* set adc to read from inputs (not internal calibration sources) */ priv(dev)->i2c_cal_range_bits = adc_src_4020_bits(4); @@ -1614,7 +1613,7 @@ static void init_stc_registers(struct comedi_device *dev) disable_ai_pacing(dev); }; -int alloc_and_init_dma_members(struct comedi_device *dev) +static int alloc_and_init_dma_members(struct comedi_device *dev) { int i; @@ -1877,12 +1876,12 @@ static int detach(struct comedi_device *dev) if (priv(dev)->hw_dev) { if (priv(dev)->plx9080_iobase) { disable_plx_interrupts(dev); - iounmap((void *)priv(dev)->plx9080_iobase); + iounmap(priv(dev)->plx9080_iobase); } if (priv(dev)->main_iobase) - iounmap((void *)priv(dev)->main_iobase); + iounmap(priv(dev)->main_iobase); if (priv(dev)->dio_counter_iobase) - iounmap((void *)priv(dev)->dio_counter_iobase); + iounmap(priv(dev)->dio_counter_iobase); /* free pci dma buffers */ for (i = 0; i < ai_dma_ring_count(board(dev)); i++) { if (priv(dev)->ai_buffer[i]) @@ -2978,7 +2977,7 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) uint32_t next_transfer_addr; int j; int num_samples = 0; - void *pci_addr_reg; + void __iomem *pci_addr_reg; if (channel) pci_addr_reg = @@ -3018,8 +3017,9 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) * unused buffer) */ } -void handle_ai_interrupt(struct comedi_device *dev, unsigned short status, - unsigned int plx_status) +static void handle_ai_interrupt(struct comedi_device *dev, + unsigned short status, + unsigned int plx_status) { struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; @@ -3229,7 +3229,7 @@ static irqreturn_t handle_interrupt(int irq, void *d) return IRQ_HANDLED; } -void abort_dma(struct comedi_device *dev, unsigned int channel) +static void abort_dma(struct comedi_device *dev, unsigned int channel) { unsigned long flags; @@ -3424,7 +3424,7 @@ static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) { unsigned int num_bytes; unsigned int next_transfer_addr; - void *pci_addr_reg = + void __iomem *pci_addr_reg = priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG; unsigned int buffer_index; @@ -3658,24 +3658,24 @@ static int ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s) return 0; } -static int dio_callback(int dir, int port, int data, unsigned long iobase) +static int dio_callback(int dir, int port, int data, void __iomem *iobase) { if (dir) { - writeb(data, (void *)(iobase + port)); + writeb(data, iobase + port); DEBUG_PRINT("wrote 0x%x to port %i\n", data, port); return 0; } else { - return readb((void *)(iobase + port)); + return readb(iobase + port); } } -static int dio_callback_4020(int dir, int port, int data, unsigned long iobase) +static int dio_callback_4020(int dir, int port, int data, void __iomem *iobase) { if (dir) { - writew(data, (void *)(iobase + 2 * port)); + writew(data, iobase + 2 * port); return 0; } else { - return readw((void *)(iobase + 2 * port)); + return readw(iobase + 2 * port); } } @@ -3862,7 +3862,7 @@ static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address) static const int read_command = 0x6; unsigned int bitstream = (read_command << 8) | address; unsigned int bit; - void *const plx_control_addr = + void __iomem * const plx_control_addr = priv(dev)->plx9080_iobase + PLX_CONTROL_REG; uint16_t value; static const int value_length = 16; @@ -4185,7 +4185,8 @@ static const int i2c_low_udelay = 10; static void i2c_set_sda(struct comedi_device *dev, int state) { static const int data_bit = CTL_EE_W; - void *plx_control_addr = priv(dev)->plx9080_iobase + PLX_CONTROL_REG; + void __iomem *plx_control_addr = priv(dev)->plx9080_iobase + + PLX_CONTROL_REG; if (state) { /* set data line high */ @@ -4204,7 +4205,8 @@ static void i2c_set_sda(struct comedi_device *dev, int state) static void i2c_set_scl(struct comedi_device *dev, int state) { static const int clock_bit = CTL_USERO; - void *plx_control_addr = priv(dev)->plx9080_iobase + PLX_CONTROL_REG; + void __iomem *plx_control_addr = priv(dev)->plx9080_iobase + + PLX_CONTROL_REG; if (state) { /* set clock line high */ -- cgit v1.2.3 From a7f22a84ba2e5a99b874bf36a772b5d7424cec11 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:07:43 -0700 Subject: Staging: comedi: amplc_dio200.c: fix NULL sparse warnings Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 6a87652e7e2a..8eb67651486a 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -661,7 +661,7 @@ dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s, subpriv = s->private; spin_lock_irqsave(&subpriv->spinlock, flags); - s->async->inttrig = 0; + s->async->inttrig = NULL; if (subpriv->active) event = dio200_start_intr(dev, s); @@ -1364,7 +1364,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) break; case sd_8255: /* digital i/o subdevice (8255) */ - ret = subdev_8255_init(dev, s, 0, + ret = subdev_8255_init(dev, s, NULL, iobase + layout->sdinfo[n]); if (ret < 0) return ret; -- cgit v1.2.3 From a8cb9ad9ad872dc600314c1c8d07c420b3cdefbb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:08:24 -0700 Subject: Staging: comedi: adv_pci1710.c: fix unsigned problem with divisors Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 5c1ff779af2c..67c4f11a36ab 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -937,7 +937,8 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, struct comedi_cmd *cmd) { int err = 0; - int tmp, divisor1 = 0, divisor2 = 0; + int tmp; + unsigned int divisor1 = 0, divisor2 = 0; DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...)\n"); #ifdef PCI171X_EXTDEBUG -- cgit v1.2.3 From 5f35f3f19fd12226482f8b57c70d9a0f82470c87 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:08:51 -0700 Subject: Staging: comedi: adl_pci9118.c: fix unsigned problem with divisors Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9118.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index dc4bd0423e6f..ccef549778e4 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -921,7 +921,8 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, struct comedi_cmd *cmd) { int err = 0; - int tmp, divisor1 = 0, divisor2 = 0; + int tmp; + unsigned int divisor1 = 0, divisor2 = 0; /* step 1: make sure trigger sources are trivially valid */ -- cgit v1.2.3 From 525d1b1395858606103d4663a570cc8725ff2ced Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:09:26 -0700 Subject: Staging: comedi: adl_pci9111.c: fix sparse warnings divisor and other problems fixed. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9111.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index bbe0e332dae8..36a254cd4413 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -358,8 +358,8 @@ struct pci9111_private_data { int ao_readback; /* Last written analog output data */ - int timer_divisor_1; /* Divisor values for the 8254 timer pacer */ - int timer_divisor_2; + unsigned int timer_divisor_1; /* Divisor values for the 8254 timer pacer */ + unsigned int timer_divisor_2; int is_valid; /* Is device valid */ @@ -1269,9 +1269,6 @@ found: /* TODO: Warn about non-tested boards. */ - switch (board->device_id) { - }; - /* Read local configuration register base address [PCI_BASE_ADDRESS #1]. */ lcr_io_base = pci_resource_start(pci_device, 1); @@ -1381,7 +1378,7 @@ static int pci9111_detach(struct comedi_device *dev) { /* Reset device */ - if (dev->private != 0) { + if (dev->private != NULL) { if (dev_private->is_valid) pci9111_reset(dev); @@ -1391,7 +1388,7 @@ static int pci9111_detach(struct comedi_device *dev) if (dev->irq != 0) free_irq(dev->irq, dev); - if (dev_private != 0 && dev_private->pci_device != 0) { + if (dev_private != NULL && dev_private->pci_device != NULL) { if (dev->iobase) comedi_pci_disable(dev_private->pci_device); pci_dev_put(dev_private->pci_device); -- cgit v1.2.3 From 08b93e7bda617a623ffae77940e4acfa31204367 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:09:53 -0700 Subject: Staging: comedi: hwdrv_apci035.c: fix sparse warnings Some variables should be static. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c index 791297266fc0..1369e22b7ee6 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c @@ -52,9 +52,9 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------------------------------------------------------------------------+ */ #include "hwdrv_apci035.h" -int i_WatchdogNbr = 0; -int i_Temp = 0; -int i_Flag = 1; +static int i_WatchdogNbr = 0; +static int i_Temp = 0; +static int i_Flag = 1; /* +----------------------------------------------------------------------------+ | Function Name : int i_APCI035_ConfigTimerWatchdog | -- cgit v1.2.3 From 1a538dfd16a4aa3a57a4c792c928fe83b05aacf0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:10:36 -0700 Subject: Staging: comedi: hwdrv_apci035.h: fix sparse warnings This let us delete two variables and mark one as static. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h index e0023c8cb628..68db9c10c99e 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h @@ -19,22 +19,8 @@ #define APCI035_BOARD_VENDOR_ID 0x15B8 #define APCI035_ADDRESS_RANGE 255 -int i_TW_Number; -struct { - int i_Gain; - int i_Polarity; - int i_OffsetRange; - int i_Coupling; - int i_SingleDiff; - int i_AutoCalibration; - unsigned int ui_ReloadValue; - unsigned int ui_TimeUnitReloadVal; - int i_Interrupt; - int i_ModuleSelection; -} Config_Parameters_Main; - /* ANALOG INPUT RANGE */ -struct comedi_lrange range_apci035_ai = { 8, { +static struct comedi_lrange range_apci035_ai = { 8, { BIP_RANGE(10), BIP_RANGE(5), BIP_RANGE(2), -- cgit v1.2.3 From 2179b4c8b5435cde6bc5fb9d2411527c646ba14a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:11:26 -0700 Subject: Staging: comedi: hwdrv_apci1032.c: sparse warning fixups Mark a variable as static. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c index fe06789699f3..faea003e16c7 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c @@ -53,8 +53,8 @@ You should also find the complete GPL in the COPYING file accompanying this sour */ #include "hwdrv_apci1032.h" #include -/* Global variables */ -unsigned int ui_InterruptStatus; + +static unsigned int ui_InterruptStatus; /* +----------------------------------------------------------------------------+ -- cgit v1.2.3 From a943532652914e5acfbbd2e099edabda667a9de1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:12:00 -0700 Subject: Staging: comedi: hwdrv_apci1500.c: sparse static cleanups Mark a bunch of variables and functions as static. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1500.c | 94 +++++++++++++--------- 1 file changed, 55 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c index d5e06ad6acc2..b3b921853e60 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c @@ -47,16 +47,16 @@ You should also find the complete GPL in the COPYING file accompanying this sour */ #include "hwdrv_apci1500.h" -int i_TimerCounter1Init = 0; -int i_TimerCounter2Init = 0; -int i_WatchdogCounter3Init = 0; -int i_Event1Status = 0, i_Event2Status = 0; -int i_TimerCounterWatchdogInterrupt = 0; -int i_Logic = 0, i_CounterLogic = 0; -int i_InterruptMask = 0; -int i_InputChannel = 0; -int i_TimerCounter1Enabled = 0, i_TimerCounter2Enabled = - 0, i_WatchdogCounter3Enabled = 0; +static int i_TimerCounter1Init = 0; +static int i_TimerCounter2Init = 0; +static int i_WatchdogCounter3Init = 0; +static int i_Event1Status = 0, i_Event2Status = 0; +static int i_TimerCounterWatchdogInterrupt = 0; +static int i_Logic = 0, i_CounterLogic = 0; +static int i_InterruptMask = 0; +static int i_InputChannel = 0; +static int i_TimerCounter1Enabled = 0, i_TimerCounter2Enabled = 0, + i_WatchdogCounter3Enabled = 0; /* +----------------------------------------------------------------------------+ @@ -136,9 +136,10 @@ int i_TimerCounter1Enabled = 0, i_TimerCounter2Enabled = | | +----------------------------------------------------------------------------+ */ - -int i_APCI1500_ConfigDigitalInputEvent(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1500_ConfigDigitalInputEvent(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { int i_PatternPolarity = 0, i_PatternTransition = 0, i_PatternMask = 0; int i_MaxChannel = 0, i_Count = 0, i_EventMask = 0; @@ -519,8 +520,10 @@ int i_APCI1500_ConfigDigitalInputEvent(struct comedi_device *dev, | | +----------------------------------------------------------------------------+ */ -int i_APCI1500_StartStopInputEvent(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1500_StartStopInputEvent(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { int i_Event1InterruptStatus = 0, i_Event2InterruptStatus = 0, i_RegValue; @@ -784,8 +787,10 @@ int i_APCI1500_StartStopInputEvent(struct comedi_device *dev, struct comedi_subd | | +----------------------------------------------------------------------------+ */ -int i_APCI1500_Initialisation(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1500_Initialisation(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { int i_DummyRead = 0; /******************/ @@ -956,9 +961,10 @@ int i_APCI1500_Initialisation(struct comedi_device *dev, struct comedi_subdevice | | +----------------------------------------------------------------------------+ */ - -int i_APCI1500_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1500_ReadMoreDigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { unsigned int ui_PortValue = data[1]; unsigned int ui_Mask = 0; @@ -1040,8 +1046,10 @@ int i_APCI1500_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_sub | | +----------------------------------------------------------------------------+ */ -int i_APCI1500_ConfigDigitalOutputErrorInterrupt(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1500_ConfigDigitalOutputErrorInterrupt(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { devpriv->b_OutputMemoryStatus = data[0]; return insn->n; @@ -1066,9 +1074,10 @@ int i_APCI1500_ConfigDigitalOutputErrorInterrupt(struct comedi_device *dev, | | +----------------------------------------------------------------------------+ */ - -int i_APCI1500_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1500_WriteDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { static unsigned int ui_Temp = 0; unsigned int ui_Temp1; @@ -1260,9 +1269,10 @@ int i_APCI1500_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subde | | +----------------------------------------------------------------------------+ */ - -int i_APCI1500_ConfigCounterTimerWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1500_ConfigCounterTimerWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { int i_TimerCounterMode, i_MasterConfiguration; @@ -1860,8 +1870,10 @@ int i_APCI1500_ConfigCounterTimerWatchdog(struct comedi_device *dev, | | +----------------------------------------------------------------------------+ */ -int i_APCI1500_StartStopTriggerTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1500_StartStopTriggerTimerCounterWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { int i_CommandAndStatusValue; @@ -2181,9 +2193,10 @@ int i_APCI1500_StartStopTriggerTimerCounterWatchdog(struct comedi_device *dev, | | +----------------------------------------------------------------------------+ */ - -int i_APCI1500_ReadCounterTimerWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1500_ReadCounterTimerWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { int i_CommandAndStatusValue; switch (data[0]) { @@ -2370,8 +2383,10 @@ int i_APCI1500_ReadCounterTimerWatchdog(struct comedi_device *dev, | | +----------------------------------------------------------------------------+ */ -int i_APCI1500_ReadInterruptMask(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1500_ReadInterruptMask(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { data[0] = i_InterruptMask; data[1] = i_InputChannel; @@ -2401,8 +2416,10 @@ int i_APCI1500_ReadInterruptMask(struct comedi_device *dev, struct comedi_subdev | | +----------------------------------------------------------------------------+ */ -int i_APCI1500_ConfigureInterrupt(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1500_ConfigureInterrupt(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { unsigned int ui_Status; int i_RegValue; @@ -2821,8 +2838,7 @@ static void v_APCI1500_Interrupt(int irq, void *d) | | +----------------------------------------------------------------------------+ */ - -int i_APCI1500_Reset(struct comedi_device *dev) +static int i_APCI1500_Reset(struct comedi_device *dev) { int i_DummyRead = 0; i_TimerCounter1Init = 0; -- cgit v1.2.3 From 0b437fc493621b07a1bc7dcfedbfd6e3b86a149e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:12:29 -0700 Subject: Staging: comedi: hwdrv_apci1564.c: static sparse cleanups. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index 4413279c880b..4299ff5214dd 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -56,8 +56,8 @@ You should also find the complete GPL in the COPYING file accompanying this sour #include "hwdrv_apci1564.h" /* Global variables */ -unsigned int ui_InterruptStatus_1564 = 0; -unsigned int ui_InterruptData, ui_Type; +static unsigned int ui_InterruptStatus_1564 = 0; +static unsigned int ui_InterruptData, ui_Type; /* +----------------------------------------------------------------------------+ -- cgit v1.2.3 From 882980133d0d94ad060a727f17362e27b9fec263 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:12:53 -0700 Subject: Staging: comedi: hwdrv_apci2032.c: static sparse fix Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c index 2d325163c169..d7d22236778d 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c @@ -53,7 +53,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour */ #include "hwdrv_apci2032.h" -unsigned int ui_InterruptData, ui_Type; +static unsigned int ui_InterruptData, ui_Type; /* +----------------------------------------------------------------------------+ | Function Name : int i_APCI2032_ConfigDigitalOutput | -- cgit v1.2.3 From a6dc6d0df2e87c18af3c8b47d3c29613f5c90d9f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:13:28 -0700 Subject: Staging: comedi: hwdrv_apci3501.h: make a variable static. Cleans up the sparse warning. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h index c456d75674b8..743523e804a9 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h @@ -32,7 +32,7 @@ #define MODE0 0 #define MODE1 1 /* ANALOG OUTPUT RANGE */ -struct comedi_lrange range_apci3501_ao = { 2, { +static struct comedi_lrange range_apci3501_ao = { 2, { BIP_RANGE(10), UNI_RANGE(10) } -- cgit v1.2.3 From 4e4b592cb51342878166a2ea2bcf6151f0a3a29d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 16:14:02 -0700 Subject: Staging: comedi: hwdrv_apci3xxx.c: loads of sparse cleanups __iomem pointer fixes, and static cleanups. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3xxx.c | 191 +++++++++------------ 1 file changed, 82 insertions(+), 109 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c index 3692326d474a..2e20bc7cdcdb 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c @@ -67,10 +67,9 @@ You should also find the complete GPL in the COPYING file accompanying this sour | 1 : Conversion started | +----------------------------------------------------------------------------+ */ - -int i_APCI3XXX_TestConversionStarted(struct comedi_device *dev) +static int i_APCI3XXX_TestConversionStarted(struct comedi_device *dev) { - if ((readl((void *)(devpriv->dw_AiBase + 8)) & 0x80000UL) == 0x80000UL) + if ((readl(devpriv->dw_AiBase + 8) & 0x80000UL) == 0x80000UL) return 1; else return 0; @@ -104,9 +103,10 @@ int i_APCI3XXX_TestConversionStarted(struct comedi_device *dev) | -101 : Data size error | +----------------------------------------------------------------------------+ */ - -int i_APCI3XXX_AnalogInputConfigOperatingMode(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3XXX_AnalogInputConfigOperatingMode(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { int i_ReturnValue = insn->n; unsigned char b_TimeBase = 0; @@ -204,19 +204,14 @@ int i_APCI3XXX_AnalogInputConfigOperatingMode(struct comedi_device *dev, /* Set the convert timing unit */ /*******************************/ - writel((unsigned int) - b_TimeBase, - (void *) - (devpriv-> - dw_AiBase - + - 36)); + writel((unsigned int)b_TimeBase, + devpriv->dw_AiBase + 36); /**************************/ /* Set the convert timing */ /*************************/ - writel(dw_ReloadValue, (void *)(devpriv->dw_AiBase + 32)); + writel(dw_ReloadValue, devpriv->dw_AiBase + 32); } else { /**************************/ /* Any conversion started */ @@ -294,9 +289,10 @@ int i_APCI3XXX_AnalogInputConfigOperatingMode(struct comedi_device *dev, | -101 : Data size error | +----------------------------------------------------------------------------+ */ - -int i_APCI3XXX_InsnConfigAnalogInput(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3XXX_InsnConfigAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { int i_ReturnValue = insn->n; @@ -354,9 +350,10 @@ int i_APCI3XXX_InsnConfigAnalogInput(struct comedi_device *dev, | -101 : Data size error | +----------------------------------------------------------------------------+ */ - -int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { int i_ReturnValue = insn->n; unsigned char b_Configuration = (unsigned char) CR_RANGE(insn->chanspec); @@ -422,26 +419,20 @@ int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev, /* Clear the FIFO */ /******************/ - writel(0x10000UL, - (void *)(devpriv->dw_AiBase + - 12)); + writel(0x10000UL, devpriv->dw_AiBase + 12); /*******************************/ /* Get and save the delay mode */ /*******************************/ - dw_Temp = - readl((void *)(devpriv-> - dw_AiBase + 4)); + dw_Temp = readl(devpriv->dw_AiBase + 4); dw_Temp = dw_Temp & 0xFFFFFEF0UL; /***********************************/ /* Channel configuration selection */ /***********************************/ - writel(dw_Temp, - (void *)(devpriv->dw_AiBase + - 4)); + writel(dw_Temp, devpriv->dw_AiBase + 4); /**************************/ /* Make the configuration */ @@ -458,35 +449,28 @@ int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev, /***************************/ writel(dw_Configuration, - (void *)(devpriv->dw_AiBase + - 0)); + devpriv->dw_AiBase + 0); /*********************/ /* Channel selection */ /*********************/ writel(dw_Temp | 0x100UL, - (void *)(devpriv->dw_AiBase + - 4)); + devpriv->dw_AiBase + 4); writel((unsigned int) b_Channel, - (void *)(devpriv->dw_AiBase + - 0)); + devpriv->dw_AiBase + 0); /***********************/ /* Restaure delay mode */ /***********************/ - writel(dw_Temp, - (void *)(devpriv->dw_AiBase + - 4)); + writel(dw_Temp, devpriv->dw_AiBase + 4); /***********************************/ /* Set the number of sequence to 1 */ /***********************************/ - writel(1, - (void *)(devpriv->dw_AiBase + - 48)); + writel(1, devpriv->dw_AiBase + 48); /***************************/ /* Save the interrupt flag */ @@ -514,50 +498,29 @@ int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev, /* Start the conversion */ /************************/ - writel(0x80000UL, - (void *) - (devpriv-> - dw_AiBase - + 8)); + writel(0x80000UL, devpriv->dw_AiBase + 8); /****************/ /* Wait the EOS */ /****************/ do { - dw_Temp = - readl( - (void *) - (devpriv-> - dw_AiBase - + - 20)); - dw_Temp = - dw_Temp - & 1; + dw_Temp = readl(devpriv->dw_AiBase + 20); + dw_Temp = dw_Temp & 1; } while (dw_Temp != 1); /*************************/ /* Read the analog value */ /*************************/ - data[dw_AcquisitionCpt] - = - (unsigned int) - readl((void - *) - (devpriv-> - dw_AiBase - + 28)); + data[dw_AcquisitionCpt] = (unsigned int)readl(devpriv->dw_AiBase + 28); } } else { /************************/ /* Start the conversion */ /************************/ - writel(0x180000UL, - (void *)(devpriv-> - dw_AiBase + 8)); + writel(0x180000UL, devpriv->dw_AiBase + 8); } } else { /**************************/ @@ -603,7 +566,7 @@ int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -void v_APCI3XXX_Interrupt(int irq, void *d) +static void v_APCI3XXX_Interrupt(int irq, void *d) { struct comedi_device *dev = d; unsigned char b_CopyCpt = 0; @@ -613,13 +576,13 @@ void v_APCI3XXX_Interrupt(int irq, void *d) /* Test if interrupt occur */ /***************************/ - dw_Status = readl((void *)(devpriv->dw_AiBase + 16)); + dw_Status = readl(devpriv->dw_AiBase + 16); if ( (dw_Status & 0x2UL) == 0x2UL) { /***********************/ /* Reset the interrupt */ /***********************/ - writel(dw_Status, (void *)(devpriv->dw_AiBase + 16)); + writel(dw_Status, devpriv->dw_AiBase + 16); /*****************************/ /* Test if interrupt enabled */ @@ -634,8 +597,7 @@ void v_APCI3XXX_Interrupt(int irq, void *d) b_CopyCpt < devpriv->ui_AiNbrofChannels; b_CopyCpt++) { devpriv->ui_AiReadData[b_CopyCpt] = - (unsigned int) readl((void *)(devpriv-> - dw_AiBase + 28)); + (unsigned int)readl(devpriv->dw_AiBase + 28); } /**************************/ @@ -682,9 +644,10 @@ void v_APCI3XXX_Interrupt(int irq, void *d) | -101 : Data size error | +----------------------------------------------------------------------------+ */ - -int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { unsigned char b_Range = (unsigned char) CR_RANGE(insn->chanspec); unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); @@ -710,24 +673,21 @@ int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device *dev, /* Set the range selection */ /***************************/ - writel(b_Range, - (void *)(devpriv->dw_AiBase + 96)); + writel(b_Range, devpriv->dw_AiBase + 96); /**************************************************/ /* Write the analog value to the selected channel */ /**************************************************/ writel((data[0] << 8) | b_Channel, - (void *)(devpriv->dw_AiBase + 100)); + devpriv->dw_AiBase + 100); /****************************/ /* Wait the end of transfer */ /****************************/ do { - dw_Status = - readl((void *)(devpriv-> - dw_AiBase + 96)); + dw_Status = readl(devpriv->dw_AiBase + 96); } while ((dw_Status & 0x100) != 0x100); } else { /***************************/ @@ -788,9 +748,10 @@ int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device *dev, | -101 : Data size error | +----------------------------------------------------------------------------+ */ - -int i_APCI3XXX_InsnConfigInitTTLIO(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3XXX_InsnConfigInitTTLIO(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { int i_ReturnValue = insn->n; unsigned char b_Command = 0; @@ -916,9 +877,10 @@ int i_APCI3XXX_InsnConfigInitTTLIO(struct comedi_device *dev, | -101 : Data size error | +----------------------------------------------------------------------------+ */ - -int i_APCI3XXX_InsnBitsTTLIO(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3XXX_InsnBitsTTLIO(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { int i_ReturnValue = insn->n; unsigned char b_ChannelCpt = 0; @@ -1071,9 +1033,10 @@ int i_APCI3XXX_InsnBitsTTLIO(struct comedi_device *dev, | -101 : Data size error | +----------------------------------------------------------------------------+ */ - -int i_APCI3XXX_InsnReadTTLIO(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3XXX_InsnReadTTLIO(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); int i_ReturnValue = insn->n; @@ -1184,9 +1147,10 @@ int i_APCI3XXX_InsnReadTTLIO(struct comedi_device *dev, | -101 : Data size error | +----------------------------------------------------------------------------+ */ - -int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { int i_ReturnValue = insn->n; unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); @@ -1296,8 +1260,10 @@ int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI3XXX_InsnReadDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3XXX_InsnReadDigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { int i_ReturnValue = insn->n; unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); @@ -1354,8 +1320,10 @@ int i_APCI3XXX_InsnReadDigitalInput(struct comedi_device *dev, | -101 : Data size error | +----------------------------------------------------------------------------+ */ -int i_APCI3XXX_InsnBitsDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3XXX_InsnBitsDigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { int i_ReturnValue = insn->n; unsigned int dw_Temp = 0; @@ -1407,8 +1375,10 @@ int i_APCI3XXX_InsnBitsDigitalInput(struct comedi_device *dev, | -101 : Data size error | +----------------------------------------------------------------------------+ */ -int i_APCI3XXX_InsnBitsDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3XXX_InsnBitsDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { int i_ReturnValue = insn->n; unsigned char b_ChannelCpt = 0; @@ -1503,8 +1473,10 @@ int i_APCI3XXX_InsnBitsDigitalOutput(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { int i_ReturnValue = insn->n; unsigned char b_Channel = CR_CHAN(insn->chanspec); @@ -1578,8 +1550,10 @@ int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { int i_ReturnValue = insn->n; unsigned char b_Channel = CR_CHAN(insn->chanspec); @@ -1636,7 +1610,7 @@ int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI3XXX_Reset(struct comedi_device *dev) +static int i_APCI3XXX_Reset(struct comedi_device *dev) { unsigned char b_Cpt = 0; @@ -1656,27 +1630,26 @@ int i_APCI3XXX_Reset(struct comedi_device *dev) /* Clear the start command */ /***************************/ - writel(0, (void *)(devpriv->dw_AiBase + 8)); + writel(0, devpriv->dw_AiBase + 8); /*****************************/ /* Reset the interrupt flags */ /*****************************/ - writel(readl((void *)(devpriv->dw_AiBase + 16)), - (void *)(devpriv->dw_AiBase + 16)); + writel(readl(devpriv->dw_AiBase + 16), devpriv->dw_AiBase + 16); /*****************/ /* clear the EOS */ /*****************/ - readl((void *)(devpriv->dw_AiBase + 20)); + readl(devpriv->dw_AiBase + 20); /******************/ /* Clear the FIFO */ /******************/ for (b_Cpt = 0; b_Cpt < 16; b_Cpt++) { - readl((void *)(devpriv->dw_AiBase + 28)); + readl(devpriv->dw_AiBase + 28); } /************************/ -- cgit v1.2.3 From 7880fc54c985b4fbc0fab77f81b7f09610194e1c Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 4 May 2010 09:58:52 -0700 Subject: Staging: hv: cleanup network driver Minor stuff: * Add module description * Remove variable set but never used. * Move variable inside conditional Signed-off-by: Stephen Hemminger Acked-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/netvsc_drv.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 51a56e2b43c1..2ce9437b44b5 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -111,14 +111,13 @@ static void netvsc_xmit_completion(void *context) struct hv_netvsc_packet *packet = (struct hv_netvsc_packet *)context; struct sk_buff *skb = (struct sk_buff *) (unsigned long)packet->Completion.Send.SendCompletionTid; - struct net_device *net; DPRINT_ENTER(NETVSC_DRV); kfree(packet); if (skb) { - net = skb->dev; + struct net_device *net = skb->dev; dev_kfree_skb_any(skb); if (netif_queue_stopped(net)) { @@ -291,7 +290,6 @@ static int netvsc_recv_callback(struct hv_device *device_obj, { struct vm_device *device_ctx = to_vm_device(device_obj); struct net_device *net = dev_get_drvdata(&device_ctx->device); - struct net_device_context *net_device_ctx; struct sk_buff *skb; void *data; int i; @@ -305,8 +303,6 @@ static int netvsc_recv_callback(struct hv_device *device_obj, return 0; } - net_device_ctx = netdev_priv(net); - /* Allocate a skb - TODO direct I/O to pages? */ skb = netdev_alloc_skb_ip_align(net, packet->TotalDataBufferLength); if (unlikely(!skb)) { @@ -585,6 +581,7 @@ static void __exit netvsc_exit(void) MODULE_LICENSE("GPL"); MODULE_VERSION(HV_DRV_VERSION); +MODULE_DESCRIPTION("Microsoft Hyper-V network driver"); module_param(netvsc_ringbuffer_size, int, S_IRUGO); module_init(netvsc_init); -- cgit v1.2.3 From 450d7a4b7ace20fb1cbb4d87ccbccbac3f8895d0 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 4 May 2010 09:58:53 -0700 Subject: Staging: hv: ring parameter The ring size parameter should be number of pages (not bytes). Add module parameter information as well. Signed-off-by: Stephen Hemminger Acked-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/NetVscApi.h | 1 - drivers/staging/hv/netvsc_drv.c | 9 ++++++--- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/NetVscApi.h b/drivers/staging/hv/NetVscApi.h index 95d7a32b12f2..c372c98785d5 100644 --- a/drivers/staging/hv/NetVscApi.h +++ b/drivers/staging/hv/NetVscApi.h @@ -28,7 +28,6 @@ #include "VmbusApi.h" /* Defines */ -#define NETVSC_DEVICE_RING_BUFFER_SIZE (64*PAGE_SIZE) #define HW_MACADDR_LEN 6 /* Fwd declaration */ diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 2ce9437b44b5..b02455cfe237 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -52,7 +52,11 @@ struct netvsc_driver_context { struct netvsc_driver drv_obj; }; -static int netvsc_ringbuffer_size = NETVSC_DEVICE_RING_BUFFER_SIZE; +/* Need at least MAX_SKB_FRAGS (18) + 1 + to handle worst case fragmented packet */ +static int ring_size = roundup_pow_of_two(2*MAX_SKB_FRAGS+1); +module_param(ring_size, int, S_IRUGO); +MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)"); /* The one and only one */ static struct netvsc_driver_context g_netvsc_drv; @@ -536,7 +540,7 @@ static int netvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) vmbus_get_interface(&net_drv_obj->Base.VmbusChannelInterface); - net_drv_obj->RingBufferSize = netvsc_ringbuffer_size; + net_drv_obj->RingBufferSize = ring_size * PAGE_SIZE; net_drv_obj->OnReceiveCallback = netvsc_recv_callback; net_drv_obj->OnLinkStatusChanged = netvsc_linkstatus_callback; @@ -582,7 +586,6 @@ static void __exit netvsc_exit(void) MODULE_LICENSE("GPL"); MODULE_VERSION(HV_DRV_VERSION); MODULE_DESCRIPTION("Microsoft Hyper-V network driver"); -module_param(netvsc_ringbuffer_size, int, S_IRUGO); module_init(netvsc_init); module_exit(netvsc_exit); -- cgit v1.2.3 From 9f8bd8bacf90c78e331ad63c38b0ea167e2ce639 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 4 May 2010 09:58:54 -0700 Subject: Staging: hv: use existing Ethernet header size Use ETH_ALEN to indicate that MAC address is Ethernet. Also use Linux printk format for mac addresses. Signed-off-by: Stephen Hemminger Acked-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/NetVscApi.h | 6 ------ drivers/staging/hv/RndisFilter.c | 18 +++++++----------- 2 files changed, 7 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/NetVscApi.h b/drivers/staging/hv/NetVscApi.h index c372c98785d5..91a4cd9965d8 100644 --- a/drivers/staging/hv/NetVscApi.h +++ b/drivers/staging/hv/NetVscApi.h @@ -27,9 +27,6 @@ #include "VmbusApi.h" -/* Defines */ -#define HW_MACADDR_LEN 6 - /* Fwd declaration */ struct hv_netvsc_packet; @@ -92,9 +89,6 @@ struct netvsc_driver { u32 RingBufferSize; u32 RequestExtSize; - /* Additional num of page buffers to allocate */ - u32 AdditionalRequestPageBufferCount; - /* * This is set by the caller to allow us to callback when we * receive a packet from the "wire" diff --git a/drivers/staging/hv/RndisFilter.c b/drivers/staging/hv/RndisFilter.c index cd2930de2176..861139677e33 100644 --- a/drivers/staging/hv/RndisFilter.c +++ b/drivers/staging/hv/RndisFilter.c @@ -22,6 +22,8 @@ #include #include #include +#include + #include "osd.h" #include "logging.h" #include "NetVscApi.h" @@ -50,7 +52,7 @@ struct rndis_device { spinlock_t request_lock; struct list_head RequestList; - unsigned char HwMacAddr[HW_MACADDR_LEN]; + unsigned char HwMacAddr[ETH_ALEN]; }; struct rndis_request { @@ -538,7 +540,7 @@ Cleanup: static int RndisFilterQueryDeviceMac(struct rndis_device *Device) { - u32 size = HW_MACADDR_LEN; + u32 size = ETH_ALEN; return RndisFilterQueryDevice(Device, RNDIS_OID_802_3_PERMANENT_ADDRESS, @@ -833,16 +835,10 @@ static int RndisFilterOnDeviceAdd(struct hv_device *Device, */ } - DPRINT_INFO(NETVSC, "Device 0x%p mac addr %02x%02x%02x%02x%02x%02x", - rndisDevice, - rndisDevice->HwMacAddr[0], - rndisDevice->HwMacAddr[1], - rndisDevice->HwMacAddr[2], - rndisDevice->HwMacAddr[3], - rndisDevice->HwMacAddr[4], - rndisDevice->HwMacAddr[5]); + DPRINT_INFO(NETVSC, "Device 0x%p mac addr %pM", + rndisDevice, rndisDevice->HwMacAddr); - memcpy(deviceInfo->MacAddr, rndisDevice->HwMacAddr, HW_MACADDR_LEN); + memcpy(deviceInfo->MacAddr, rndisDevice->HwMacAddr, ETH_ALEN); RndisFilterQueryDeviceLinkStatus(rndisDevice); -- cgit v1.2.3 From 6048718d719f460abba8eaff1c0122247b2c3d91 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 4 May 2010 09:58:55 -0700 Subject: Staging: hv: transmit scatter gather support The transmit management of pages was confusing for handling fragmented SKB's. (But since NETIF_F_SG was never set, the code was never hit). The parameter AdditionalRequestPageBufferCount is always one, (and leads to ugly code), so just inline and add comments. Signed-off-by: Stephen Hemminger Acked-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/RndisFilter.c | 1 - drivers/staging/hv/netvsc_drv.c | 53 +++++++++++++++++----------------------- 2 files changed, 22 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/RndisFilter.c b/drivers/staging/hv/RndisFilter.c index 861139677e33..de4bc80341c3 100644 --- a/drivers/staging/hv/RndisFilter.c +++ b/drivers/staging/hv/RndisFilter.c @@ -624,7 +624,6 @@ int RndisFilterInit(struct netvsc_driver *Driver) sizeof(struct rndis_filter_packet)); Driver->RequestExtSize = sizeof(struct rndis_filter_packet); - Driver->AdditionalRequestPageBufferCount = 1; /* For rndis header */ /* Driver->Context = rndisDriver; */ diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index b02455cfe237..4124979835a6 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -144,27 +144,21 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) (struct netvsc_driver_context *)driver_ctx; struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj; struct hv_netvsc_packet *packet; - int i; int ret; - int num_frags; + unsigned int i, num_pages; int retries = 0; DPRINT_ENTER(NETVSC_DRV); - /* Support only 1 chain of frags */ - ASSERT(skb_shinfo(skb)->frag_list == NULL); - ASSERT(skb->dev == net); - DPRINT_DBG(NETVSC_DRV, "xmit packet - len %d data_len %d", skb->len, skb->data_len); - /* Add 1 for skb->data and any additional ones requested */ - num_frags = skb_shinfo(skb)->nr_frags + 1 + - net_drv_obj->AdditionalRequestPageBufferCount; + /* Add 1 for skb->data and additional one for RNDIS */ + num_pages = skb_shinfo(skb)->nr_frags + 1 + 1; /* Allocate a netvsc packet based on # of frags. */ packet = kzalloc(sizeof(struct hv_netvsc_packet) + - (num_frags * sizeof(struct hv_page_buffer)) + + (num_pages * sizeof(struct hv_page_buffer)) + net_drv_obj->RequestExtSize, GFP_ATOMIC); if (!packet) { DPRINT_ERR(NETVSC_DRV, "unable to allocate hv_netvsc_packet"); @@ -173,36 +167,30 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) packet->Extension = (void *)(unsigned long)packet + sizeof(struct hv_netvsc_packet) + - (num_frags * sizeof(struct hv_page_buffer)); + (num_pages * sizeof(struct hv_page_buffer)); /* Setup the rndis header */ - packet->PageBufferCount = num_frags; + packet->PageBufferCount = num_pages; /* TODO: Flush all write buffers/ memory fence ??? */ /* wmb(); */ /* Initialize it from the skb */ - ASSERT(skb->data); packet->TotalDataBufferLength = skb->len; - /* - * Start filling in the page buffers starting at - * AdditionalRequestPageBufferCount offset - */ - packet->PageBuffers[net_drv_obj->AdditionalRequestPageBufferCount].Pfn = virt_to_phys(skb->data) >> PAGE_SHIFT; - packet->PageBuffers[net_drv_obj->AdditionalRequestPageBufferCount].Offset = (unsigned long)skb->data & (PAGE_SIZE - 1); - packet->PageBuffers[net_drv_obj->AdditionalRequestPageBufferCount].Length = skb->len - skb->data_len; - - ASSERT((skb->len - skb->data_len) <= PAGE_SIZE); - - for (i = net_drv_obj->AdditionalRequestPageBufferCount + 1; - i < num_frags; i++) { - packet->PageBuffers[i].Pfn = - page_to_pfn(skb_shinfo(skb)->frags[i-(net_drv_obj->AdditionalRequestPageBufferCount+1)].page); - packet->PageBuffers[i].Offset = - skb_shinfo(skb)->frags[i-(net_drv_obj->AdditionalRequestPageBufferCount+1)].page_offset; - packet->PageBuffers[i].Length = - skb_shinfo(skb)->frags[i-(net_drv_obj->AdditionalRequestPageBufferCount+1)].size; + /* Start filling in the page buffers starting after RNDIS buffer. */ + packet->PageBuffers[1].Pfn = virt_to_phys(skb->data) >> PAGE_SHIFT; + packet->PageBuffers[1].Offset + = (unsigned long)skb->data & (PAGE_SIZE - 1); + packet->PageBuffers[1].Length = skb_headlen(skb); + + /* Additional fragments are after SKB data */ + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + skb_frag_t *f = &skb_shinfo(skb)->frags[i]; + + packet->PageBuffers[i+2].Pfn = page_to_pfn(f->page); + packet->PageBuffers[i+2].Offset = f->page_offset; + packet->PageBuffers[i+2].Length = f->size; } /* Set the completion routine */ @@ -423,6 +411,9 @@ static int netvsc_probe(struct device *device) net->netdev_ops = &device_ops; + /* TODO: Add GSO and Checksum offload */ + net->features = NETIF_F_SG; + SET_NETDEV_DEV(net, device); ret = register_netdev(net); -- cgit v1.2.3 From b220f5f925b8938747bfe4a61e362d132bdd9544 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 4 May 2010 09:58:56 -0700 Subject: Staging: hv: add transmit flow control Keep track of the number of pages sent over transmit and stop before going over. Signed-off-by: Stephen Hemminger Acked-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/netvsc_drv.c | 72 ++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 4124979835a6..a6ca01025e48 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -43,6 +43,7 @@ struct net_device_context { /* point back to our device context */ struct vm_device *device_ctx; + unsigned long avail; }; struct netvsc_driver_context { @@ -52,8 +53,10 @@ struct netvsc_driver_context { struct netvsc_driver drv_obj; }; -/* Need at least MAX_SKB_FRAGS (18) + 1 - to handle worst case fragmented packet */ +#define PACKET_PAGES_LOWATER 8 +/* Need this many pages to handle worst case fragmented packet */ +#define PACKET_PAGES_HIWATER (MAX_SKB_FRAGS + 2) + static int ring_size = roundup_pow_of_two(2*MAX_SKB_FRAGS+1); module_param(ring_size, int, S_IRUGO); MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)"); @@ -122,14 +125,13 @@ static void netvsc_xmit_completion(void *context) if (skb) { struct net_device *net = skb->dev; - dev_kfree_skb_any(skb); + struct net_device_context *net_device_ctx = netdev_priv(net); + unsigned int num_pages = skb_shinfo(skb)->nr_frags + 2; - if (netif_queue_stopped(net)) { - DPRINT_INFO(NETVSC_DRV, "net device (%p) waking up...", - net); + dev_kfree_skb_any(skb); - netif_wake_queue(net); - } + if ((net_device_ctx->avail += num_pages) >= PACKET_PAGES_HIWATER) + netif_wake_queue(net); } DPRINT_EXIT(NETVSC_DRV); @@ -146,7 +148,6 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) struct hv_netvsc_packet *packet; int ret; unsigned int i, num_pages; - int retries = 0; DPRINT_ENTER(NETVSC_DRV); @@ -155,14 +156,20 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) /* Add 1 for skb->data and additional one for RNDIS */ num_pages = skb_shinfo(skb)->nr_frags + 1 + 1; + if (num_pages > net_device_ctx->avail) + return NETDEV_TX_BUSY; /* Allocate a netvsc packet based on # of frags. */ packet = kzalloc(sizeof(struct hv_netvsc_packet) + (num_pages * sizeof(struct hv_page_buffer)) + net_drv_obj->RequestExtSize, GFP_ATOMIC); if (!packet) { + /* out of memory, silently drop packet */ DPRINT_ERR(NETVSC_DRV, "unable to allocate hv_netvsc_packet"); - return -1; + + dev_kfree_skb(skb); + net->stats.tx_dropped++; + return NETDEV_TX_OK; } packet->Extension = (void *)(unsigned long)packet + @@ -198,52 +205,26 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) packet->Completion.Send.SendCompletionContext = packet; packet->Completion.Send.SendCompletionTid = (unsigned long)skb; -retry_send: ret = net_drv_obj->OnSend(&net_device_ctx->device_ctx->device_obj, packet); - if (ret == 0) { - ret = NETDEV_TX_OK; net->stats.tx_bytes += skb->len; net->stats.tx_packets++; - } else { - retries++; - if (retries < 4) { - DPRINT_ERR(NETVSC_DRV, "unable to send..." - "retrying %d...", retries); - udelay(100); - goto retry_send; - } - /* no more room or we are shutting down */ - DPRINT_ERR(NETVSC_DRV, "unable to send (%d)..." - "marking net device (%p) busy", ret, net); - DPRINT_INFO(NETVSC_DRV, "net device (%p) stopping", net); + DPRINT_DBG(NETVSC_DRV, "# of xmits %lu total size %lu", + net->stats.tx_packets, + net->stats.tx_bytes); - ret = NETDEV_TX_BUSY; + if ((net_device_ctx->avail -= num_pages) < PACKET_PAGES_LOWATER) + netif_stop_queue(net); + } else { + /* we are shutting down or bus overloaded, just drop packet */ net->stats.tx_dropped++; - - netif_stop_queue(net); - - /* - * Null it since the caller will free it instead of the - * completion routine - */ - packet->Completion.Send.SendCompletionTid = 0; - - /* - * Release the resources since we will not get any send - * completion - */ - netvsc_xmit_completion((void *)packet); + netvsc_xmit_completion(packet); } - DPRINT_DBG(NETVSC_DRV, "# of xmits %lu total size %lu", - net->stats.tx_packets, - net->stats.tx_bytes); - DPRINT_EXIT(NETVSC_DRV); - return ret; + return NETDEV_TX_OK; } /* @@ -382,6 +363,7 @@ static int netvsc_probe(struct device *device) net_device_ctx = netdev_priv(net); net_device_ctx->device_ctx = device_ctx; + net_device_ctx->avail = ring_size; dev_set_drvdata(device, net); /* Notify the netvsc driver of the new device */ -- cgit v1.2.3 From f82f4ad7bf9dc3c7268080cc2afdff897e1d72ca Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 4 May 2010 09:58:57 -0700 Subject: Staging: hv: add basic ethtool support Ethtool allows querying device information and controlling parameters. For now just add ability to turn on/off scatter/gather. Signed-off-by: Stephen Hemminger Acked-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/netvsc_drv.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index a6ca01025e48..a6584a876618 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -326,6 +326,21 @@ static int netvsc_recv_callback(struct hv_device *device_obj, return 0; } +static void netvsc_get_drvinfo(struct net_device *net, + struct ethtool_drvinfo *info) +{ + strcpy(info->driver, "hv_netvsc"); + strcpy(info->version, HV_DRV_VERSION); + strcpy(info->fw_version, "N/A"); +} + +static const struct ethtool_ops ethtool_ops = { + .get_drvinfo = netvsc_get_drvinfo, + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, + .get_link = ethtool_op_get_link, +}; + static const struct net_device_ops device_ops = { .ndo_open = netvsc_open, .ndo_stop = netvsc_close, @@ -396,6 +411,7 @@ static int netvsc_probe(struct device *device) /* TODO: Add GSO and Checksum offload */ net->features = NETIF_F_SG; + SET_ETHTOOL_OPS(net, ðtool_ops); SET_NETDEV_DEV(net, device); ret = register_netdev(net); -- cgit v1.2.3 From 5f87404dfce14b2a194d085b7bac4b8c3672ab00 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 22:20:54 +0100 Subject: Staging: iio: Trivial - remove pointless semi colon (checkpatch found) Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/industrialio-trigger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c index 918b0fd2b83e..46bd94ab7d91 100644 --- a/drivers/staging/iio/industrialio-trigger.c +++ b/drivers/staging/iio/industrialio-trigger.c @@ -169,7 +169,7 @@ struct iio_trigger *iio_trigger_find_by_name(const char *name, size_t len) mutex_unlock(&iio_trigger_list_lock); return found ? trig : NULL; -}; +} EXPORT_SYMBOL(iio_trigger_find_by_name); void iio_trigger_poll(struct iio_trigger *trig) -- cgit v1.2.3 From 26de7208281fd21606201ab3314f60e517d6c56f Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 22:34:36 +0100 Subject: Staging: iio: accelerometers trivial checkpatch related fixes Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/lis3l02dq_ring.c | 11 +++++------ drivers/staging/iio/accel/sca3000_core.c | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 7617da81871c..9214d847fa33 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -192,8 +192,7 @@ error_ret: } -static const u8 read_all_tx_array[] = -{ +static const u8 read_all_tx_array[] = { LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_X_L_ADDR), 0, LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_X_H_ADDR), 0, LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_Y_L_ADDR), 0, @@ -358,10 +357,10 @@ static int lis3l02dq_data_rdy_ring_predisable(struct iio_dev *indio_dev) /* Caller responsible for locking as necessary. */ -static int __lis3l02dq_write_data_ready_config(struct device *dev, - struct - iio_event_handler_list *list, - bool state) +static int +__lis3l02dq_write_data_ready_config(struct device *dev, + struct iio_event_handler_list *list, + bool state) { int ret; u8 valold; diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index 9485b132f6dd..d4f82c39f335 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -277,7 +277,7 @@ static int sca3000_check_status(struct device *dev) if (ret < 0) goto error_ret; if (rx[1] & SCA3000_EEPROM_CS_ERROR) - dev_err(dev, "eeprom error \n"); + dev_err(dev, "eeprom error\n"); if (rx[1] & SCA3000_SPI_FRAME_ERROR) dev_err(dev, "Previous SPI Frame was corrupt\n"); kfree(rx); @@ -394,7 +394,7 @@ sca3000_show_available_measurement_modes(struct device *dev, break; } /* always supported */ - len += sprintf(buf + len, " 3 - motion detection \n"); + len += sprintf(buf + len, " 3 - motion detection\n"); return len; } -- cgit v1.2.3 From cb6405b15f7b2814f8f5170482b2e13ccfcb6376 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Tue, 4 May 2010 22:34:37 +0100 Subject: Staging: iio: light trivial whitespace fix Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/light/tsl2563.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c index da3d51c52c7c..f8a08365f19d 100644 --- a/drivers/staging/iio/light/tsl2563.c +++ b/drivers/staging/iio/light/tsl2563.c @@ -646,7 +646,7 @@ static int __devinit tsl2563_probe(struct i2c_client *client, err = tsl2563_detect(chip); if (err) { - dev_err(&client->dev, "device not found, error %d \n", -err); + dev_err(&client->dev, "device not found, error %d\n", -err); goto fail1; } -- cgit v1.2.3 From 1b183e4b93c4e05160d2c8f08b9546dd4752084b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 22:24:05 -0700 Subject: Staging: iio: adc: max1363_core: fix up some sparse warnings Also fix a minor coding style issue. Cc: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/max1363_core.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index fa91cc14c64f..4a77657285da 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -139,16 +139,15 @@ static const struct max1363_mode max1363_mode_table[] = { }; const struct max1363_mode -*max1363_match_mode(u32 mask, const struct max1363_chip_info *ci) { +*max1363_match_mode(u32 mask, const struct max1363_chip_info *ci) +{ int i; if (mask) for (i = 0; i < ci->num_modes; i++) - if (!((~max1363_mode_table[ci->mode_list[i]] - .modemask) & + if (!((~max1363_mode_table[ci->mode_list[i]].modemask) & mask)) - return &max1363_mode_table[ci - ->mode_list[i]]; - return 0; + return &max1363_mode_table[ci->mode_list[i]]; + return NULL; }; static ssize_t max1363_show_precision(struct device *dev, @@ -298,7 +297,7 @@ static ssize_t max1363_show_scale(struct device *dev, st->chip_info->int_vref_mv >> st->chip_info->bits); } -IIO_DEVICE_ATTR(in_scale, S_IRUGO, max1363_show_scale, NULL, 0); +static IIO_DEVICE_ATTR(in_scale, S_IRUGO, max1363_show_scale, NULL, 0); static ssize_t max1363_show_name(struct device *dev, struct device_attribute *attr, @@ -309,7 +308,7 @@ static ssize_t max1363_show_name(struct device *dev, return sprintf(buf, "%s\n", st->chip_info->name); } -IIO_DEVICE_ATTR(name, S_IRUGO, max1363_show_name, NULL, 0); +static IIO_DEVICE_ATTR(name, S_IRUGO, max1363_show_name, NULL, 0); /* Applies to max1363 */ static const enum max1363_modes max1363_mode_list[] = { -- cgit v1.2.3 From f03de82b3f10b2e8b7f75f3d4323ec38d131a99c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 22:26:19 -0700 Subject: Staging: iio: max1363_core: fix bug in kzalloc call The operands were switched around :( Cc: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/max1363_core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index 4a77657285da..905f8560d31f 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -958,9 +958,8 @@ static int __devinit max1363_probe(struct i2c_client *client, } st->indio_dev->available_scan_masks - = kzalloc(GFP_KERNEL, - sizeof(*st->indio_dev->available_scan_masks)* - (st->chip_info->num_modes + 1)); + = kzalloc(sizeof(*st->indio_dev->available_scan_masks)* + (st->chip_info->num_modes + 1), GFP_KERNEL); if (!st->indio_dev->available_scan_masks) { ret = -ENOMEM; goto error_free_device; -- cgit v1.2.3 From acbbfe236eb6fa25fdfb2a8762d0ad260f6b667c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 22:28:37 -0700 Subject: Staging: iio: adc: max1363_ring.c: fix up sparse warnings Cc: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/max1363_ring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c index 85fde751a154..c8aa01109ec2 100644 --- a/drivers/staging/iio/adc/max1363_ring.c +++ b/drivers/staging/iio/adc/max1363_ring.c @@ -142,7 +142,7 @@ static int max1363_ring_predisable(struct iio_dev *indio_dev) * then. Some triggers will generate their own time stamp. Currently * there is no way of notifying them when no one cares. **/ -void max1363_poll_func_th(struct iio_dev *indio_dev) +static void max1363_poll_func_th(struct iio_dev *indio_dev) { struct max1363_state *st = indio_dev->dev_data; -- cgit v1.2.3 From 341713f265950884d2edbbf55088127a915927ad Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 22:29:41 -0700 Subject: Staging: iio: light: tsl2563: fix static sparse warning Cc: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/light/tsl2563.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c index f8a08365f19d..e4b0a5ef1c1f 100644 --- a/drivers/staging/iio/light/tsl2563.c +++ b/drivers/staging/iio/light/tsl2563.c @@ -607,7 +607,7 @@ static ssize_t tsl2563_show_name(struct device *dev, return sprintf(buf, "%s\n", chip->client->name); } -DEVICE_ATTR(name, S_IRUGO, tsl2563_show_name, NULL); +static DEVICE_ATTR(name, S_IRUGO, tsl2563_show_name, NULL); static struct attribute *tsl2563_attributes[] = { &dev_attr_adc0.attr, -- cgit v1.2.3 From d1d8abdb05bddce645649c17949b0bc62e6f096b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 22:31:22 -0700 Subject: Staging: iio: trigger: fix up some global variables These should be static. Cc: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/trigger/iio-trig-gpio.c | 4 ++-- drivers/staging/iio/trigger/iio-trig-periodic-rtc.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-gpio.c index e40099ff6230..1da285d28632 100644 --- a/drivers/staging/iio/trigger/iio-trig-gpio.c +++ b/drivers/staging/iio/trigger/iio-trig-gpio.c @@ -25,8 +25,8 @@ #include "../iio.h" #include "../trigger.h" -LIST_HEAD(iio_gpio_trigger_list); -DEFINE_MUTEX(iio_gpio_trigger_list_lock); +static LIST_HEAD(iio_gpio_trigger_list); +static DEFINE_MUTEX(iio_gpio_trigger_list_lock); struct iio_gpio_trigger_info { struct mutex in_use; diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c index 4295bbc7b50d..4ee3ae1ef892 100644 --- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c +++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c @@ -19,8 +19,8 @@ #include "../iio.h" #include "../trigger.h" -LIST_HEAD(iio_prtc_trigger_list); -DEFINE_MUTEX(iio_prtc_trigger_list_lock); +static LIST_HEAD(iio_prtc_trigger_list); +static DEFINE_MUTEX(iio_prtc_trigger_list_lock); struct iio_prtc_trigger_info { struct rtc_device *rtc; -- cgit v1.2.3 From 7cfce527a2cec1a2757136eb44d8dfa473a82d37 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 22:32:01 -0700 Subject: Staging: iio: accel: fix up some sparse warnings. Minor stuff (static, NULL, etc.) Cc: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/lis3l02dq_ring.c | 3 +-- drivers/staging/iio/accel/sca3000_ring.c | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 9214d847fa33..78d8572e6323 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -207,7 +207,7 @@ static const u8 read_all_tx_array[] = { * @rx_array: (dma capable) recieve array, must be at least * 4*number of channels **/ -int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array) +static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array) { struct spi_transfer *xfers; struct spi_message msg; @@ -588,7 +588,6 @@ void lis3l02dq_uninitialize_ring(struct iio_ring_buffer *ring) iio_ring_buffer_unregister(ring); } - int lis3l02dq_set_ring_length(struct iio_dev *indio_dev, int length) { /* Set sensible defaults for the ring buffer */ diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c index 2b39e6f6c26d..8e8c068d401b 100644 --- a/drivers/staging/iio/accel/sca3000_ring.c +++ b/drivers/staging/iio/accel/sca3000_ring.c @@ -186,9 +186,9 @@ static ssize_t sca3000_store_ring_bpse(struct device *dev, return ret ? ret : len; } -static IIO_SCAN_EL_C(accel_x, 0, 0, 0, 0); -static IIO_SCAN_EL_C(accel_y, 1, 0, 0, 0); -static IIO_SCAN_EL_C(accel_z, 2, 0, 0, 0); +static IIO_SCAN_EL_C(accel_x, 0, 0, 0, NULL); +static IIO_SCAN_EL_C(accel_y, 1, 0, 0, NULL); +static IIO_SCAN_EL_C(accel_z, 2, 0, 0, NULL); static IIO_CONST_ATTR(accel_precision_available, "8 11"); static IIO_DEVICE_ATTR(accel_precision, S_IRUGO | S_IWUSR, @@ -244,7 +244,7 @@ static struct iio_ring_buffer *sca3000_rb_allocate(struct iio_dev *indio_dev) ring = kzalloc(sizeof *ring, GFP_KERNEL); if (!ring) - return 0; + return NULL; ring->private = indio_dev; buf = &ring->buf; iio_ring_buffer_init(buf, indio_dev); -- cgit v1.2.3 From 0deebb4fc4784699afec04231f981aaad3126ff9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 22:32:43 -0700 Subject: Staging: iio: industrialio-ring.c: fix up sparse warnings Cc: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/industrialio-ring.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c index fc27d22a7ab1..ada159bbb1f7 100644 --- a/drivers/staging/iio/industrialio-ring.c +++ b/drivers/staging/iio/industrialio-ring.c @@ -58,7 +58,7 @@ EXPORT_SYMBOL(iio_push_or_escallate_ring_event); * This function relies on all ring buffer implementations having an * iio_ring_buffer as their first element. **/ -int iio_ring_open(struct inode *inode, struct file *filp) +static int iio_ring_open(struct inode *inode, struct file *filp) { struct iio_handler *hand = container_of(inode->i_cdev, struct iio_handler, chrdev); @@ -77,7 +77,7 @@ int iio_ring_open(struct inode *inode, struct file *filp) * This function relies on all ring buffer implementations having an * iio_ring_buffer as their first element. **/ -int iio_ring_release(struct inode *inode, struct file *filp) +static int iio_ring_release(struct inode *inode, struct file *filp) { struct cdev *cd = inode->i_cdev; struct iio_handler *hand = iio_cdev_to_handler(cd); @@ -96,10 +96,8 @@ int iio_ring_release(struct inode *inode, struct file *filp) * This function relies on all ring buffer implementations having an * iio_ring _bufer as their first element. **/ -ssize_t iio_ring_rip_outer(struct file *filp, - char *buf, - size_t count, - loff_t *f_ps) +static ssize_t iio_ring_rip_outer(struct file *filp, char __user *buf, + size_t count, loff_t *f_ps) { struct iio_ring_buffer *rb = filp->private_data; int ret, dead_offset, copied; @@ -251,7 +249,7 @@ void iio_ring_buffer_init(struct iio_ring_buffer *ring, ring->indio_dev = dev_info; ring->ev_int.private = ring; ring->access_handler.private = ring; - ring->shared_ev_pointer.ev_p = 0; + ring->shared_ev_pointer.ev_p = NULL; spin_lock_init(&ring->shared_ev_pointer.lock); } EXPORT_SYMBOL(iio_ring_buffer_init); -- cgit v1.2.3 From 19ca92e0bca3499a12eb9b612b90bbe90d2cc895 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 22:33:27 -0700 Subject: Staging: iio: ring_sw.c: fix up sparse warnings NULL usage, static stuff, etc. Cc: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/ring_sw.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c index 5ee3e4533515..1f14cd4770e7 100644 --- a/drivers/staging/iio/ring_sw.c +++ b/drivers/staging/iio/ring_sw.c @@ -21,10 +21,10 @@ static inline int __iio_allocate_sw_ring_buffer(struct iio_sw_ring_buffer *ring, return -EINVAL; __iio_update_ring_buffer(&ring->buf, bytes_per_datum, length); ring->data = kmalloc(length*ring->buf.bpd, GFP_KERNEL); - ring->read_p = 0; - ring->write_p = 0; - ring->last_written_p = 0; - ring->half_p = 0; + ring->read_p = NULL; + ring->write_p = NULL; + ring->last_written_p = NULL; + ring->half_p = NULL; return ring->data ? 0 : -ENOMEM; } @@ -62,16 +62,15 @@ EXPORT_SYMBOL(iio_unmark_sw_rb_in_use); * in the device driver */ /* Lock always held if their is a chance this may be called */ /* Only one of these per ring may run concurrently - enforced by drivers */ -int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring, - unsigned char *data, - s64 timestamp) +static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring, + unsigned char *data, s64 timestamp) { int ret = 0; int code; unsigned char *temp_ptr, *change_test_ptr; /* initial store */ - if (unlikely(ring->write_p == 0)) { + if (unlikely(ring->write_p == NULL)) { ring->write_p = ring->data; /* Doesn't actually matter if this is out of the set * as long as the read pointer is valid before this @@ -102,7 +101,7 @@ int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring, */ ring->write_p = temp_ptr; - if (ring->read_p == 0) + if (ring->read_p == NULL) ring->read_p = ring->data; /* Buffer full - move the read pointer and create / escalate * ring event */ @@ -182,7 +181,7 @@ int iio_rip_sw_rb(struct iio_ring_buffer *r, /* build local copy */ initial_read_p = ring->read_p; - if (unlikely(initial_read_p == 0)) { /* No data here as yet */ + if (unlikely(initial_read_p == NULL)) { /* No data here as yet */ ret = 0; goto error_free_data_cpy; } @@ -280,8 +279,8 @@ int iio_store_to_sw_rb(struct iio_ring_buffer *r, u8 *data, s64 timestamp) } EXPORT_SYMBOL(iio_store_to_sw_rb); -int iio_read_last_from_sw_ring(struct iio_sw_ring_buffer *ring, - unsigned char *data) +static int iio_read_last_from_sw_ring(struct iio_sw_ring_buffer *ring, + unsigned char *data) { unsigned char *last_written_p_copy; @@ -291,7 +290,7 @@ again: last_written_p_copy = ring->last_written_p; barrier(); /*unnessecary? */ /* Check there is anything here */ - if (last_written_p_copy == 0) + if (last_written_p_copy == NULL) return -EAGAIN; memcpy(data, last_written_p_copy, ring->buf.bpd); @@ -412,7 +411,7 @@ struct iio_ring_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev) ring = kzalloc(sizeof *ring, GFP_KERNEL); if (!ring) - return 0; + return NULL; buf = &ring->buf; iio_ring_buffer_init(buf, indio_dev); __iio_init_sw_ring_buffer(ring); -- cgit v1.2.3 From 74112d3f3a64afb98179169cf8af691ccc63434d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 22:34:00 -0700 Subject: Staging: iio: industrialio-trigger.c: minor fixups We needed to include a header file that declared the functions that are being exported in this file. Also fix up an indentation problem, and some sparse warnings. Cc: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/industrialio-trigger.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c index 46bd94ab7d91..5682e61600f6 100644 --- a/drivers/staging/iio/industrialio-trigger.c +++ b/drivers/staging/iio/industrialio-trigger.c @@ -18,6 +18,7 @@ #include "iio.h" #include "trigger.h" +#include "trigger_consumer.h" /* RFC - Question of approach * Make the common case (single sensor single trigger) @@ -92,9 +93,9 @@ idr_again: **/ static void iio_trigger_unregister_id(struct iio_trigger *trig_info) { - spin_lock(&iio_trigger_idr_lock); - idr_remove(&iio_trigger_idr, trig_info->id); - spin_unlock(&iio_trigger_idr_lock); + spin_lock(&iio_trigger_idr_lock); + idr_remove(&iio_trigger_idr, trig_info->id); + spin_unlock(&iio_trigger_idr_lock); } int iio_trigger_register(struct iio_trigger *trig_info) @@ -334,9 +335,9 @@ static ssize_t iio_trigger_write_current(struct device *dev, return len; } -DEVICE_ATTR(current_trigger, S_IRUGO | S_IWUSR, - iio_trigger_read_current, - iio_trigger_write_current); +static DEVICE_ATTR(current_trigger, S_IRUGO | S_IWUSR, + iio_trigger_read_current, + iio_trigger_write_current); static struct attribute *iio_trigger_consumer_attrs[] = { &dev_attr_current_trigger.attr, -- cgit v1.2.3 From 1e18c0d5b41ff2b482f1b5178da4f69d3223261c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 May 2010 22:45:08 -0700 Subject: Staging: line6: driver: fix up sparse warnings minor stuff. Cc: Markus Grabner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index 258555417bc7..1d5a47302763 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -399,7 +399,7 @@ static void line6_data_received(struct urb *urb) static int line6_send(struct usb_line6 *line6, unsigned char *buf, size_t len) { int retval; - unsigned int partial; + int partial; #if DO_DUMP_URB_SEND line6_write_hexdump(line6, 'S', buf, len); @@ -684,11 +684,11 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_ /* check vendor and product id */ for (devtype = ARRAY_SIZE(line6_id_table) - 1; devtype--;) { - u16 vendor = le16_to_cpu(usbdev->descriptor.idVendor); - u16 product = le16_to_cpu(usbdev->descriptor.idProduct); + u16 idVendor = le16_to_cpu(usbdev->descriptor.idVendor); + u16 idProduct = le16_to_cpu(usbdev->descriptor.idProduct); - if (vendor == line6_id_table[devtype].idVendor - && product == line6_id_table[devtype].idProduct) + if (idVendor == line6_id_table[devtype].idVendor + && idProduct == line6_id_table[devtype].idProduct) break; } -- cgit v1.2.3 From c5efe58b83bc5c1d5811800faf03b1089d1ef054 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 09:10:31 -0700 Subject: Staging: comedi: 8255: fix up previous static markings. Ian pointed out that exported symbols should not be marked as static :) Fixed this up by properly including the 8255.h file, and fixing the function prototypes there, as the CONFIG variables were not getting set so users of the header file were seeing the incorrect function prototypes. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 22 ++++++++++------------ drivers/staging/comedi/drivers/8255.h | 22 ---------------------- 2 files changed, 10 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index e777ddfc8af0..b2e80dd5c266 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -82,6 +82,7 @@ I/O port base address can be found in the output of 'lspci -v'. #include #include +#include "8255.h" #define _8255_SIZE 4 @@ -120,8 +121,8 @@ COMEDI_INITCLEANUP(driver_8255); static void do_config(struct comedi_device *dev, struct comedi_subdevice *s); -static void subdev_8255_interrupt(struct comedi_device *dev, - struct comedi_subdevice *s) +void subdev_8255_interrupt(struct comedi_device *dev, + struct comedi_subdevice *s) { short d; @@ -319,10 +320,9 @@ static int subdev_8255_cancel(struct comedi_device *dev, return 0; } -static int subdev_8255_init(struct comedi_device *dev, - struct comedi_subdevice *s, - int (*cb) (int, int, int, unsigned long), - unsigned long arg) +int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, + int (*cb) (int, int, int, unsigned long), + unsigned long arg) { s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; @@ -350,10 +350,9 @@ static int subdev_8255_init(struct comedi_device *dev, } EXPORT_SYMBOL(subdev_8255_init); -static int subdev_8255_init_irq(struct comedi_device *dev, - struct comedi_subdevice *s, - int (*cb) (int, int, int, unsigned long), - unsigned long arg) +int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, + int (*cb) (int, int, int, unsigned long), + unsigned long arg) { int ret; @@ -371,8 +370,7 @@ static int subdev_8255_init_irq(struct comedi_device *dev, } EXPORT_SYMBOL(subdev_8255_init_irq); -static void subdev_8255_cleanup(struct comedi_device *dev, - struct comedi_subdevice *s) +void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice *s) { if (s->private) { /* this test does nothing, so comment it out diff --git a/drivers/staging/comedi/drivers/8255.h b/drivers/staging/comedi/drivers/8255.h index 02c5a361b1ab..b6314c9b7eae 100644 --- a/drivers/staging/comedi/drivers/8255.h +++ b/drivers/staging/comedi/drivers/8255.h @@ -26,8 +26,6 @@ #include "../comedidev.h" -#if defined(CONFIG_COMEDI_8255) || defined(CONFIG_COMEDI_8255_MODULE) - int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, int (*cb) (int, int, int, unsigned long), unsigned long arg); @@ -38,24 +36,4 @@ void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice *s); void subdev_8255_interrupt(struct comedi_device *dev, struct comedi_subdevice *s); -#else - -static inline int subdev_8255_init(struct comedi_device *dev, - struct comedi_subdevice *s, void *x, - unsigned long y) -{ - printk("8255 support not configured -- disabling subdevice\n"); - - s->type = COMEDI_SUBD_UNUSED; - - return 0; -} - -static inline void subdev_8255_cleanup(struct comedi_device *dev, - struct comedi_subdevice *s) -{ -} - -#endif - #endif -- cgit v1.2.3 From 318a5b2a505fe7a99f0d89889e7a84d57ec49b15 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 09:12:13 -0700 Subject: Staging: comedi: cb_pcidas64: fix up build warnings Now that the 8255.h file is being included properly, we were using the incorrect function prototypes, which causes a build warning now. This fixes it up and preserves the __iomem markings that sparse wants to see. Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 3443fc1b9186..79aa286e9bb4 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1183,8 +1183,8 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, static irqreturn_t handle_interrupt(int irq, void *d); static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s); static int ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s); -static int dio_callback(int dir, int port, int data, void __iomem *base); -static int dio_callback_4020(int dir, int port, int data, void __iomem *base); +static int dio_callback(int dir, int port, int data, unsigned long arg); +static int dio_callback_4020(int dir, int port, int data, unsigned long arg); static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); static int do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, @@ -3658,8 +3658,9 @@ static int ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s) return 0; } -static int dio_callback(int dir, int port, int data, void __iomem *iobase) +static int dio_callback(int dir, int port, int data, unsigned long arg) { + void __iomem *iobase = (void __iomem *)arg; if (dir) { writeb(data, iobase + port); DEBUG_PRINT("wrote 0x%x to port %i\n", data, port); @@ -3669,8 +3670,9 @@ static int dio_callback(int dir, int port, int data, void __iomem *iobase) } } -static int dio_callback_4020(int dir, int port, int data, void __iomem *iobase) +static int dio_callback_4020(int dir, int port, int data, unsigned long arg) { + void __iomem *iobase = (void __iomem *)arg; if (dir) { writew(data, iobase + 2 * port); return 0; -- cgit v1.2.3 From dde27e03cc964526531fdf2bd58c1e4ee4525074 Mon Sep 17 00:00:00 2001 From: "wzt.wzt@gmail.com" Date: Wed, 5 May 2010 14:56:52 +0800 Subject: Staging: rtl8192u: Check kmalloc return value before use the buffer in ieee80211_softmac.c Check kmalloc return value before use the buffer. Signed-off-by: Zhitong Wang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index 148424a9ac1c..e5e583ed1196 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -1580,6 +1580,8 @@ static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen) if(*(t++) == MFIE_TYPE_CHALLENGE){ *chlen = *(t++); *challenge = (u8*)kmalloc(*chlen, GFP_ATOMIC); + if (!*challenge) + return -ENOMEM; memcpy(*challenge, t, *chlen); } } -- cgit v1.2.3 From 40447df803971a8663a7d5f96c8a19160dfd1776 Mon Sep 17 00:00:00 2001 From: Peter Hüwe Date: Wed, 5 May 2010 14:21:14 +0200 Subject: Staging: cxt1e1: fix up one remaining THIS_MODULE usage Copied from original Patch by Randy Dunlap Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/cxt1e1/hwprobe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/cxt1e1/hwprobe.c b/drivers/staging/cxt1e1/hwprobe.c index 8d4e8d28af59..4c8610293fcc 100644 --- a/drivers/staging/cxt1e1/hwprobe.c +++ b/drivers/staging/cxt1e1/hwprobe.c @@ -283,7 +283,7 @@ c4_hdw_init (struct pci_dev * pdev, int found) */ char *cp = hi->devname; - strcpy (cp, THIS_MODULE->name); + strcpy (cp, KBUILD_MODNAME); cp += strlen (cp); /* reposition */ *cp++ = '-'; *cp++ = '0' + (found / 2); /* there are two found interfaces per -- cgit v1.2.3 From d16e1834af457fdce62714e5207c259400e274f4 Mon Sep 17 00:00:00 2001 From: "Prashant P. Shah" Date: Wed, 5 May 2010 19:46:28 +0530 Subject: Staging: arlan: fixed unnecessary whitespace style issue in arlan-main.c This is a patch to the arlan-main.c file that fixes the unnecessary whitespace issues found by the checkpatch.pl tool. Signed-off-by: Prashant P. Shah Signed-off-by: Greg Kroah-Hartman --- drivers/staging/arlan/arlan-main.c | 92 +++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/arlan/arlan-main.c b/drivers/staging/arlan/arlan-main.c index 58deb96e1a37..301b979d0437 100644 --- a/drivers/staging/arlan/arlan-main.c +++ b/drivers/staging/arlan/arlan-main.c @@ -76,18 +76,18 @@ MODULE_PARM_DESC(entry_and_exit_debug, "Arlan driver function entry and exit deb struct arlan_conf_stru arlan_conf[MAX_ARLANS]; static int arlans_found; -static int arlan_open(struct net_device *dev); -static netdev_tx_t arlan_tx(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t arlan_interrupt(int irq, void *dev_id); -static int arlan_close(struct net_device *dev); -static struct net_device_stats *arlan_statistics(struct net_device *dev); -static void arlan_set_multicast(struct net_device *dev); -static int arlan_hw_tx(struct net_device *dev, char *buf, int length); -static int arlan_hw_config(struct net_device *dev); -static void arlan_tx_done_interrupt(struct net_device *dev, int status); -static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short, u_short); -static void arlan_process_interrupt(struct net_device *dev); -static void arlan_tx_timeout(struct net_device *dev); +static int arlan_open(struct net_device *dev); +static netdev_tx_t arlan_tx(struct sk_buff *skb, struct net_device *dev); +static irqreturn_t arlan_interrupt(int irq, void *dev_id); +static int arlan_close(struct net_device *dev); +static struct net_device_stats *arlan_statistics(struct net_device *dev); +static void arlan_set_multicast(struct net_device *dev); +static int arlan_hw_tx(struct net_device *dev, char *buf, int length); +static int arlan_hw_config(struct net_device *dev); +static void arlan_tx_done_interrupt(struct net_device *dev, int status); +static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short, u_short); +static void arlan_process_interrupt(struct net_device *dev); +static void arlan_tx_timeout(struct net_device *dev); static inline long us2ticks(int us) { @@ -155,7 +155,7 @@ int arlan_command(struct net_device *dev, int command_p) priv->card_polling_interval = 1; if (arlan_debug & ARLAN_DEBUG_CHAIN_LOCKS) - printk(KERN_DEBUG "arlan_command, %lx commandByte %x waiting %lx incoming %x \n", + printk(KERN_DEBUG "arlan_command, %lx commandByte %x waiting %lx incoming %x\n", jiffies, READSHMB(arlan->commandByte), priv->waiting_command_mask, command_p); @@ -193,13 +193,13 @@ int arlan_command(struct net_device *dev, int command_p) if (priv->waiting_command_mask & ARLAN_COMMAND_LONG_WAIT_NOW) { if (udelayed * 40 > 1000000) { - printk(KERN_ERR "%s long wait too long \n", dev->name); + printk(KERN_ERR "%s long wait too long\n", dev->name); priv->waiting_command_mask |= ARLAN_COMMAND_RESET; break; } } else if (priv->waiting_command_mask & ARLAN_COMMAND_WAIT_NOW) { if (udelayed * 40 > 1000) { - printk(KERN_ERR "%s short wait too long \n", dev->name); + printk(KERN_ERR "%s short wait too long\n", dev->name); goto bad_end; } } @@ -258,7 +258,7 @@ int arlan_command(struct net_device *dev, int command_p) arlan_drop_tx(dev); if (priv->tx_command_given || priv->rx_command_given) - printk(KERN_ERR "%s: Reset under tx or rx command \n", dev->name); + printk(KERN_ERR "%s: Reset under tx or rx command\n", dev->name); netif_stop_queue(dev); if (arlan_debug & ARLAN_DEBUG_RESET) @@ -290,7 +290,7 @@ int arlan_command(struct net_device *dev, int command_p) priv->waiting_command_mask &= ~ARLAN_COMMAND_INT_RENABLE; } else if (priv->waiting_command_mask & ARLAN_COMMAND_CONF) { if (priv->tx_command_given || priv->rx_command_given) - printk(KERN_ERR "%s: Reset under tx or rx command \n", dev->name); + printk(KERN_ERR "%s: Reset under tx or rx command\n", dev->name); arlan_drop_tx(dev); setInterruptEnable(dev); @@ -313,7 +313,7 @@ int arlan_command(struct net_device *dev, int command_p) } else { priv->card_polling_interval = 1; if (arlan_debug & ARLAN_DEBUG_TIMING) - printk(KERN_ERR "configure delayed \n"); + printk(KERN_ERR "configure delayed\n"); } } else if (priv->waiting_command_mask & ARLAN_COMMAND_RX) { if (!registrationBad(dev)) { @@ -354,7 +354,7 @@ int arlan_command(struct net_device *dev, int command_p) priv->card_polling_interval = 1; } } else if (arlan_debug & ARLAN_DEBUG_CHAIN_LOCKS) - printk(KERN_ERR "tx command when tx chain locked \n"); + printk(KERN_ERR "tx command when tx chain locked\n"); } else if (priv->waiting_command_mask & ARLAN_COMMAND_NOOPINT) { { WRITESHMB(arlan->commandByte, ARLAN_COM_NOP | ARLAN_COM_INT); @@ -396,13 +396,13 @@ card_busy_end: priv->waiting_command_mask |= ARLAN_COMMAND_CLEAN_AND_RESET; if (arlan_debug & ARLAN_DEBUG_CARD_STATE) - printk(KERN_ERR "%s arlan_command card busy end \n", dev->name); + printk(KERN_ERR "%s arlan_command card busy end\n", dev->name); spin_unlock_irqrestore(&priv->lock, flags); ARLAN_DEBUG_EXIT("arlan_command"); return 1; bad_end: - printk(KERN_ERR "%s arlan_command bad end \n", dev->name); + printk(KERN_ERR "%s arlan_command bad end\n", dev->name); spin_unlock_irqrestore(&priv->lock, flags); ARLAN_DEBUG_EXIT("arlan_command"); @@ -438,9 +438,9 @@ static inline void arlan_retransmit_now(struct net_device *dev) if (TXLAST(dev).offset == 0) { if (TXHEAD(dev).offset) { priv->txLast = 0; - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_DEBUG "TX buff switch to head \n"); + IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_DEBUG "TX buff switch to head\n"); } else if (TXTAIL(dev).offset) { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_DEBUG "TX buff switch to tail \n"); + IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_DEBUG "TX buff switch to tail\n"); priv->txLast = 1; } else IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_ERR "ReTransmit buff empty"); @@ -452,7 +452,7 @@ static inline void arlan_retransmit_now(struct net_device *dev) priv->Conf->driverRetransmissions++; priv->retransmissions++; - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk("Retransmit %d bytes \n", TXLAST(dev).length); + IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk("Retransmit %d bytes\n", TXLAST(dev).length); ARLAN_DEBUG_EXIT("arlan_retransmit_now"); } @@ -471,7 +471,7 @@ static void arlan_registration_timer(unsigned long data) if (registrationBad(dev)) { priv->registrationLostCount++; if (lostTime > 7000 && lostTime < 7200) - printk(KERN_NOTICE "%s registration Lost \n", dev->name); + printk(KERN_NOTICE "%s registration Lost\n", dev->name); if (lostTime / priv->reRegisterExp > 2000) arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_CONF); @@ -504,7 +504,7 @@ static void arlan_registration_timer(unsigned long data) if (!registrationBad(dev) && priv->ReTransmitRequested) { IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk(KERN_ERR "Retransmit from timer \n"); + printk(KERN_ERR "Retransmit from timer\n"); priv->ReTransmitRequested = 0; arlan_retransmit_now(dev); } @@ -650,7 +650,7 @@ static int arlan_hw_tx(struct net_device *dev, char *buf, int length) netif_start_queue(dev); IFDEBUG(ARLAN_DEBUG_HEADER_DUMP) - printk(KERN_WARNING "%s Transmit t %2x:%2x:%2x:%2x:%2x:%2x f %2x:%2x:%2x:%2x:%2x:%2x \n", dev->name, + printk(KERN_WARNING "%s Transmit t %2x:%2x:%2x:%2x:%2x:%2x f %2x:%2x:%2x:%2x:%2x:%2x\n", dev->name, (unsigned char) buf[0], (unsigned char) buf[1], (unsigned char) buf[2], (unsigned char) buf[3], (unsigned char) buf[4], (unsigned char) buf[5], (unsigned char) buf[6], (unsigned char) buf[7], (unsigned char) buf[8], (unsigned char) buf[9], (unsigned char) buf[10], (unsigned char) buf[11]); @@ -661,7 +661,7 @@ static int arlan_hw_tx(struct net_device *dev, char *buf, int length) priv->tx_last_sent = jiffies; - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk("%s TX Qued %d bytes \n", dev->name, length); + IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk("%s TX Qued %d bytes\n", dev->name, length); ARLAN_DEBUG_EXIT("arlan_hw_tx"); @@ -677,9 +677,9 @@ static int arlan_hw_config(struct net_device *dev) ARLAN_DEBUG_ENTRY("arlan_hw_config"); - printk(KERN_NOTICE "%s arlan configure called \n", dev->name); + printk(KERN_NOTICE "%s arlan configure called\n", dev->name); if (arlan_EEPROM_bad) - printk(KERN_NOTICE "arlan configure with eeprom bad option \n"); + printk(KERN_NOTICE "arlan configure with eeprom bad option\n"); WRITESHM(arlan->spreadingCode, conf->spreadingCode, u_char); @@ -841,7 +841,7 @@ static int arlan_read_card_configuration(struct net_device *dev) READSHM(tlx415, arlan->configStatus, u_char); if (tlx415 != 0xA5) - printk(KERN_INFO "%s tlx415 chip \n", dev->name); + printk(KERN_INFO "%s tlx415 chip\n", dev->name); conf->txClear = 0; conf->txRetries = 1; @@ -885,7 +885,7 @@ static int __init arlan_check_fingerprint(unsigned long memaddr) ARLAN_DEBUG_ENTRY("arlan_check_fingerprint"); if (!request_mem_region(paddr, ARLAN_SHMEM_SIZE, "arlan")) { - /* printk(KERN_WARNING "arlan: memory region %lx excluded from probing \n",paddr); */ + /* printk(KERN_WARNING "arlan: memory region %lx excluded from probing\n",paddr); */ return -ENODEV; } @@ -898,7 +898,7 @@ static int __init arlan_check_fingerprint(unsigned long memaddr) return -ENODEV; } - /* printk(KERN_INFO "arlan found at 0x%x \n",memaddr); */ + /* printk(KERN_INFO "arlan found at 0x%x\n",memaddr); */ ARLAN_DEBUG_EXIT("arlan_check_fingerprint"); return 0; @@ -919,7 +919,7 @@ static int arlan_change_mtu(struct net_device *dev, int new_mtu) conf->maxFrameSize = new_mtu + 48; arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_CONF); - printk(KERN_NOTICE "%s mtu changed to %d \n", dev->name, new_mtu); + printk(KERN_NOTICE "%s mtu changed to %d\n", dev->name, new_mtu); ARLAN_DEBUG_EXIT("arlan_change_mtu"); @@ -997,7 +997,7 @@ static int __init arlan_probe_here(struct net_device *dev, if (arlan_check_fingerprint(memaddr)) return -ENODEV; - printk(KERN_NOTICE "%s: Arlan found at %llx, \n ", dev->name, + printk(KERN_NOTICE "%s: Arlan found at %llx,\n ", dev->name, (u64) virt_to_phys((void *)memaddr)); ap->card = (void *) memaddr; @@ -1090,7 +1090,7 @@ static netdev_tx_t arlan_tx(struct sk_buff *skb, struct net_device *dev) buf = skb->data; if (length + 0x12 > 0x800) { - printk(KERN_ERR "TX RING overflow \n"); + printk(KERN_ERR "TX RING overflow\n"); netif_stop_queue(dev); } @@ -1313,7 +1313,7 @@ static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short /* prohibited here arlan_command(dev, ARLAN_COMMAND_RX); */ if (pkt_len < 10 || pkt_len > 2048) { - printk(KERN_WARNING "%s: got too short or long packet, len %d \n", dev->name, pkt_len); + printk(KERN_WARNING "%s: got too short or long packet, len %d\n", dev->name, pkt_len); return; } if (rxOffset + pkt_len > 0x2000) { @@ -1345,8 +1345,8 @@ static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short struct sk_buff *skb; DEBUGSHM(50, "arlan recv pkt offs=%d\n", arlan->rxOffset, u_short); - DEBUGSHM(1, "arlan rxFrmType = %d \n", arlan->rxFrmType, u_char); - DEBUGSHM(1, KERN_INFO "arlan rx scrambled = %d \n", arlan->scrambled, u_char); + DEBUGSHM(1, "arlan rxFrmType = %d\n", arlan->rxFrmType, u_char); + DEBUGSHM(1, KERN_INFO "arlan rx scrambled = %d\n", arlan->scrambled, u_char); /* here we do multicast filtering to avoid slow 8-bit memcopy */ #ifdef ARLAN_MULTICAST @@ -1361,9 +1361,9 @@ static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short if (hw_dst_addr[0] == 0x01) { if (mdebug) if (hw_dst_addr[1] == 0x00) - printk(KERN_ERR "%s mcast 0x0100 \n", dev->name); + printk(KERN_ERR "%s mcast 0x0100\n", dev->name); else if (hw_dst_addr[1] == 0x40) - printk(KERN_ERR "%s m/bcast 0x0140 \n", dev->name); + printk(KERN_ERR "%s m/bcast 0x0140\n", dev->name); netdev_for_each_mc_entry(dmi, dev) { if (arlan_debug & ARLAN_DEBUG_HEADER_DUMP) printk(KERN_ERR "%s mcl %pM\n", @@ -1417,7 +1417,7 @@ static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short for (i = 0; i <= 22; i++) printk("%02x:", (u_char) skbtmp[i + 12]); printk(KERN_ERR "\n"); - printk(KERN_WARNING "arlan kernel pkt type trans %x \n", skb->protocol); + printk(KERN_WARNING "arlan kernel pkt type trans %x\n", skb->protocol); } netif_rx(skb); dev->stats.rx_packets++; @@ -1447,7 +1447,7 @@ static void arlan_process_interrupt(struct net_device *dev) if (test_and_set_bit(0, (void *) &priv->interrupt_processing_active)) { if (arlan_debug & ARLAN_DEBUG_CHAIN_LOCKS) - printk(KERN_ERR "interrupt chain reentering \n"); + printk(KERN_ERR "interrupt chain reentering\n"); goto end_int_process; } while ((rxStatus || txStatus || priv->interrupt_ack_requested) @@ -1459,7 +1459,7 @@ static void arlan_process_interrupt(struct net_device *dev) arlan_command(dev, ARLAN_COMMAND_INT_ENABLE); IFDEBUG(ARLAN_DEBUG_INTERRUPT) - printk(KERN_ERR "%s: got IRQ rx %x tx %x comm %x rxOff %x rxLen %x \n", + printk(KERN_ERR "%s: got IRQ rx %x tx %x comm %x rxOff %x rxLen %x\n", dev->name, rxStatus, txStatus, READSHMB(arlan->commandByte), rxOffset, pkt_len); @@ -1470,7 +1470,7 @@ static void arlan_process_interrupt(struct net_device *dev) dev->name, txStatus, rxStatus); } else { IFDEBUG(ARLAN_DEBUG_INTERRUPT) - printk(KERN_INFO "%s irq $%d test OK \n", dev->name, dev->irq); + printk(KERN_INFO "%s irq $%d test OK\n", dev->name, dev->irq); } priv->interrupt_ack_requested = 0; @@ -1693,7 +1693,7 @@ struct net_device * __init arlan_probe(int unit) } if (lastFoundAt == 0xbe000) - printk(KERN_ERR "arlan: No Arlan devices found \n"); + printk(KERN_ERR "arlan: No Arlan devices found\n"); not_found: free_netdev(dev); -- cgit v1.2.3 From fa10b25f8d13050c2e40ebf3fbfb5af587b6f914 Mon Sep 17 00:00:00 2001 From: Andres More Date: Tue, 4 May 2010 20:40:09 -0300 Subject: Staging: vt6656: removed SUCCESS define as it is not used Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/ttype.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h index a773e58c2302..53a50ad4e28f 100644 --- a/drivers/staging/vt6656/ttype.h +++ b/drivers/staging/vt6656/ttype.h @@ -64,11 +64,6 @@ typedef int BOOL; #define FALSE 0 #endif - -#if !defined(SUCCESS) -#define SUCCESS 0 -#endif - //2007-0809-01by MikeLiu #ifndef update_BssList #define update_BssList -- cgit v1.2.3 From 6f8c13c7dbe0d51e62bdb1aa11c1c38a8f8e3133 Mon Sep 17 00:00:00 2001 From: Andres More Date: Tue, 4 May 2010 20:40:10 -0300 Subject: Staging: vt6656: code cleanup, removed OUT definition Remoted empty OUT define in ttype.h and its usage across the code. Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/baseband.c | 6 +++--- drivers/staging/vt6656/baseband.h | 6 +++--- drivers/staging/vt6656/bssdb.c | 4 ++-- drivers/staging/vt6656/bssdb.h | 4 ++-- drivers/staging/vt6656/card.c | 4 ++-- drivers/staging/vt6656/channel.c | 2 +- drivers/staging/vt6656/channel.h | 2 +- drivers/staging/vt6656/datarate.c | 10 +++++----- drivers/staging/vt6656/datarate.h | 10 +++++----- drivers/staging/vt6656/dpc.c | 40 +++++++++++++++++++-------------------- drivers/staging/vt6656/key.c | 21 +++++--------------- drivers/staging/vt6656/key.h | 21 +++++--------------- drivers/staging/vt6656/rxtx.c | 8 ++++---- drivers/staging/vt6656/rxtx.h | 4 ++-- drivers/staging/vt6656/ttype.h | 4 ---- drivers/staging/vt6656/usbpipe.c | 2 +- drivers/staging/vt6656/usbpipe.h | 2 +- drivers/staging/vt6656/wmgr.c | 26 ++++++++++++------------- drivers/staging/vt6656/wmgr.h | 16 ++++++++-------- drivers/staging/vt6656/wpa2.c | 2 +- drivers/staging/vt6656/wpa2.h | 2 +- 21 files changed, 85 insertions(+), 111 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c index a52a2d84805c..d8154f366d52 100644 --- a/drivers/staging/vt6656/baseband.c +++ b/drivers/staging/vt6656/baseband.c @@ -762,9 +762,9 @@ BBvCaculateParameter ( UINT cbFrameLength, WORD wRate, BYTE byPacketType, - OUT PWORD pwPhyLen, - OUT PBYTE pbyPhySrv, - OUT PBYTE pbyPhySgn + PWORD pwPhyLen, + PBYTE pbyPhySrv, + PBYTE pbyPhySgn ) { UINT cbBitCount; diff --git a/drivers/staging/vt6656/baseband.h b/drivers/staging/vt6656/baseband.h index 9a1999b3302c..d54d4150dd0f 100644 --- a/drivers/staging/vt6656/baseband.h +++ b/drivers/staging/vt6656/baseband.h @@ -110,9 +110,9 @@ BBvCaculateParameter ( UINT cbFrameLength, WORD wRate, BYTE byPacketType, - OUT PWORD pwPhyLen, - OUT PBYTE pbyPhySrv, - OUT PBYTE pbyPhySgn + PWORD pwPhyLen, + PBYTE pbyPhySrv, + PBYTE pbyPhySgn ); // timer for antenna diversity diff --git a/drivers/staging/vt6656/bssdb.c b/drivers/staging/vt6656/bssdb.c index 61841b48537e..7cc0d9533f73 100644 --- a/drivers/staging/vt6656/bssdb.c +++ b/drivers/staging/vt6656/bssdb.c @@ -772,7 +772,7 @@ BOOL BSSbIsSTAInNodeDB( HANDLE hDeviceContext, PBYTE abyDstAddr, - OUT PUINT puNodeIndex + PUINT puNodeIndex ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -807,7 +807,7 @@ BSSbIsSTAInNodeDB( void BSSvCreateOneNode( HANDLE hDeviceContext, - OUT PUINT puNodeIndex + PUINT puNodeIndex ) { diff --git a/drivers/staging/vt6656/bssdb.h b/drivers/staging/vt6656/bssdb.h index 2aaa9332894e..48b34b51402f 100644 --- a/drivers/staging/vt6656/bssdb.h +++ b/drivers/staging/vt6656/bssdb.h @@ -301,13 +301,13 @@ BOOL BSSbIsSTAInNodeDB( HANDLE hDeviceContext, PBYTE abyDstAddr, - OUT PUINT puNodeIndex + PUINT puNodeIndex ); void BSSvCreateOneNode( HANDLE hDeviceContext, - OUT PUINT puNodeIndex + PUINT puNodeIndex ); void diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c index c7562a0ad834..6baf8696254b 100644 --- a/drivers/staging/vt6656/card.c +++ b/drivers/staging/vt6656/card.c @@ -224,8 +224,8 @@ void CARDvCaculateOFDMRParameter ( WORD wRate, BYTE byBBType, - OUT PBYTE pbyTxRate, - OUT PBYTE pbyRsvTime + PBYTE pbyTxRate, + PBYTE pbyRsvTime ) { switch (wRate) { diff --git a/drivers/staging/vt6656/channel.c b/drivers/staging/vt6656/channel.c index 67392b8abcfe..06a213f3f4df 100644 --- a/drivers/staging/vt6656/channel.c +++ b/drivers/staging/vt6656/channel.c @@ -426,7 +426,7 @@ exit: BOOL CHvChannelGetList ( UINT uCountryCodeIdx, - OUT PBYTE pbyChannelTable + PBYTE pbyChannelTable ) { if (uCountryCodeIdx >= CCODE_MAX) { diff --git a/drivers/staging/vt6656/channel.h b/drivers/staging/vt6656/channel.h index 81b915dc5c4b..26d12a0c6db8 100644 --- a/drivers/staging/vt6656/channel.h +++ b/drivers/staging/vt6656/channel.h @@ -51,7 +51,7 @@ BYTE CHbyGetChannelMapping(BYTE byChannelNumber); BOOL CHvChannelGetList ( UINT uCountryCodeIdx, - OUT PBYTE pbyChannelTable + PBYTE pbyChannelTable ); #endif /* _REGULATE_H_ */ diff --git a/drivers/staging/vt6656/datarate.c b/drivers/staging/vt6656/datarate.c index 348e1ebfe4c7..4d2880b8d839 100644 --- a/drivers/staging/vt6656/datarate.c +++ b/drivers/staging/vt6656/datarate.c @@ -193,11 +193,11 @@ void RATEvParseMaxRate( PWLAN_IE_SUPP_RATES pItemRates, PWLAN_IE_SUPP_RATES pItemExtRates, BOOL bUpdateBasicRate, - OUT PWORD pwMaxBasicRate, - OUT PWORD pwMaxSuppRate, - OUT PWORD pwSuppRate, - OUT PBYTE pbyTopCCKRate, - OUT PBYTE pbyTopOFDMRate + PWORD pwMaxBasicRate, + PWORD pwMaxSuppRate, + PWORD pwSuppRate, + PBYTE pbyTopCCKRate, + PBYTE pbyTopOFDMRate ) { PSDevice pDevice = (PSDevice) pDeviceHandler; diff --git a/drivers/staging/vt6656/datarate.h b/drivers/staging/vt6656/datarate.h index ae37eb63cadd..7d73a3a53bea 100644 --- a/drivers/staging/vt6656/datarate.h +++ b/drivers/staging/vt6656/datarate.h @@ -75,11 +75,11 @@ RATEvParseMaxRate( PWLAN_IE_SUPP_RATES pItemRates, PWLAN_IE_SUPP_RATES pItemExtRates, BOOL bUpdateBasicRate, - OUT PWORD pwMaxBasicRate, - OUT PWORD pwMaxSuppRate, - OUT PWORD pwSuppRate, - OUT PBYTE pbyTopCCKRate, - OUT PBYTE pbyTopOFDMRate + PWORD pwMaxBasicRate, + PWORD pwMaxSuppRate, + PWORD pwSuppRate, + PBYTE pbyTopCCKRate, + PBYTE pbyTopOFDMRate ); void diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index 75be9708b6c3..b18427b39169 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -80,8 +80,8 @@ static void s_vGetDASA( PBYTE pbyRxBufferAddr, - OUT PUINT pcbHeaderSize, - OUT PSEthernetHeader psEthHeader + PUINT pcbHeaderSize, + PSEthernetHeader psEthHeader ); static @@ -92,7 +92,7 @@ s_vProcessRxMACHeader ( UINT cbPacketSize, BOOL bIsWEP, BOOL bExtIV, - OUT PUINT pcbHeadSize + PUINT pcbHeadSize ); static BOOL s_bAPModeRxCtl( @@ -118,11 +118,11 @@ static BOOL s_bHandleRxEncryption( PBYTE pbyFrame, UINT FrameSize, PBYTE pbyRsr, - OUT PBYTE pbyNewRsr, - OUT PSKeyItem *pKeyOut, + PBYTE pbyNewRsr, + PSKeyItem * pKeyOut, int * pbExtIV, - OUT PWORD pwRxTSC15_0, - OUT PDWORD pdwRxTSC47_16 + PWORD pwRxTSC15_0, + PDWORD pdwRxTSC47_16 ); static BOOL s_bHostWepRxEncryption( @@ -133,10 +133,10 @@ static BOOL s_bHostWepRxEncryption( PBYTE pbyRsr, BOOL bOnFly, PSKeyItem pKey, - OUT PBYTE pbyNewRsr, + PBYTE pbyNewRsr, int * pbExtIV, - OUT PWORD pwRxTSC15_0, - OUT PDWORD pdwRxTSC47_16 + PWORD pwRxTSC15_0, + PDWORD pdwRxTSC47_16 ); @@ -167,7 +167,7 @@ s_vProcessRxMACHeader ( UINT cbPacketSize, BOOL bIsWEP, BOOL bExtIV, - OUT PUINT pcbHeadSize + PUINT pcbHeadSize ) { PBYTE pbyRxBuffer; @@ -262,8 +262,8 @@ static void s_vGetDASA ( PBYTE pbyRxBufferAddr, - OUT PUINT pcbHeaderSize, - OUT PSEthernetHeader psEthHeader + PUINT pcbHeaderSize, + PSEthernetHeader psEthHeader ) { UINT cbHeaderSize = 0; @@ -1147,11 +1147,11 @@ static BOOL s_bHandleRxEncryption ( PBYTE pbyFrame, UINT FrameSize, PBYTE pbyRsr, - OUT PBYTE pbyNewRsr, - OUT PSKeyItem *pKeyOut, + PBYTE pbyNewRsr, + PSKeyItem * pKeyOut, int * pbExtIV, - OUT PWORD pwRxTSC15_0, - OUT PDWORD pdwRxTSC47_16 + PWORD pwRxTSC15_0, + PDWORD pdwRxTSC47_16 ) { UINT PayloadLen = FrameSize; @@ -1295,10 +1295,10 @@ static BOOL s_bHostWepRxEncryption ( PBYTE pbyRsr, BOOL bOnFly, PSKeyItem pKey, - OUT PBYTE pbyNewRsr, + PBYTE pbyNewRsr, int * pbExtIV, - OUT PWORD pwRxTSC15_0, - OUT PDWORD pdwRxTSC47_16 + PWORD pwRxTSC15_0, + PDWORD pdwRxTSC47_16 ) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c index 338ec087f737..7ff420d07c18 100644 --- a/drivers/staging/vt6656/key.c +++ b/drivers/staging/vt6656/key.c @@ -164,12 +164,8 @@ void KeyvInitTable(void *pDeviceHandler, PSKeyManagement pTable) * Return Value: TRUE if found otherwise FALSE * */ -BOOL KeybGetKey ( - PSKeyManagement pTable, - PBYTE pbyBSSID, - DWORD dwKeyIndex, - OUT PSKeyItem *pKey - ) +BOOL KeybGetKey(PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyIndex, + PSKeyItem *pKey) { int i; @@ -563,12 +559,8 @@ void KeyvRemoveAllWEPKey( * Return Value: TRUE if found otherwise FALSE * */ -BOOL KeybGetTransmitKey ( - PSKeyManagement pTable, - PBYTE pbyBSSID, - DWORD dwKeyType, - OUT PSKeyItem *pKey - ) +BOOL KeybGetTransmitKey(PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyType, + PSKeyItem *pKey) { int i, ii; @@ -643,10 +635,7 @@ BOOL KeybGetTransmitKey ( * Return Value: TRUE if found otherwise FALSE * */ -BOOL KeybCheckPairewiseKey ( - PSKeyManagement pTable, - OUT PSKeyItem *pKey - ) +BOOL KeybCheckPairewiseKey(PSKeyManagement pTable, PSKeyItem *pKey) { int i; diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h index a10878200fa7..11fc41edd094 100644 --- a/drivers/staging/vt6656/key.h +++ b/drivers/staging/vt6656/key.h @@ -99,12 +99,8 @@ typedef struct tagSKeyManagement void KeyvInitTable(void *pDeviceHandler, PSKeyManagement pTable); -BOOL KeybGetKey( - PSKeyManagement pTable, - PBYTE pbyBSSID, - DWORD dwKeyIndex, - OUT PSKeyItem *pKey - ); +BOOL KeybGetKey(PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyIndex, + PSKeyItem *pKey); BOOL KeybSetKey( void *pDeviceHandler, @@ -141,17 +137,10 @@ void KeyvRemoveAllWEPKey( PSKeyManagement pTable ); -BOOL KeybGetTransmitKey( - PSKeyManagement pTable, - PBYTE pbyBSSID, - DWORD dwKeyType, - OUT PSKeyItem *pKey - ); +BOOL KeybGetTransmitKey(PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyType, + PSKeyItem *pKey); -BOOL KeybCheckPairewiseKey( - PSKeyManagement pTable, - OUT PSKeyItem *pKey - ); +BOOL KeybCheckPairewiseKey(PSKeyManagement pTable, PSKeyItem *pKey); BOOL KeybSetDefaultKey( void *pDeviceHandler, diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index 9ddb7e1c2546..b9f67882199d 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -187,7 +187,7 @@ s_vFillTxKey( PSKeyItem pTransmitKey, PBYTE pbyHdrBuf, WORD wPayloadLen, - OUT PBYTE pMICHDR + PBYTE pMICHDR ); static @@ -339,7 +339,7 @@ s_vFillTxKey ( PSKeyItem pTransmitKey, PBYTE pbyHdrBuf, WORD wPayloadLen, - OUT PBYTE pMICHDR + PBYTE pMICHDR ) { PDWORD pdwIV = (PDWORD) pbyIVHead; @@ -1439,8 +1439,8 @@ s_bPacketToWirelessUsb( PSKeyItem pTransmitKey, UINT uNodeIndex, WORD wCurrentRate, - OUT UINT *pcbHeaderLen, - OUT UINT *pcbTotalLen + UINT *pcbHeaderLen, + UINT *pcbTotalLen ) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h index 026943058ac2..64df4a3550d6 100644 --- a/drivers/staging/vt6656/rxtx.h +++ b/drivers/staging/vt6656/rxtx.h @@ -678,8 +678,8 @@ bPacketToWirelessUsb( PSKeyItem pTransmitKey, UINT uNodeIndex, WORD wCurrentRate, - OUT UINT *pcbHeaderLen, - OUT UINT *pcbTotalLen + UINT *pcbHeaderLen, + UINT *pcbTotalLen ); void vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb); diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h index 53a50ad4e28f..692b63e4dabf 100644 --- a/drivers/staging/vt6656/ttype.h +++ b/drivers/staging/vt6656/ttype.h @@ -33,10 +33,6 @@ /******* Common definitions and typedefs ***********************************/ -#ifndef OUT -#define OUT -#endif - //2007-0115-05by MikeLiu #ifndef TxInSleep #define TxInSleep diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c index 7c325728b836..ce71f18afd81 100644 --- a/drivers/staging/vt6656/usbpipe.c +++ b/drivers/staging/vt6656/usbpipe.c @@ -229,7 +229,7 @@ PIPEnsControlIn( WORD wValue, WORD wIndex, WORD wLength, - OUT PBYTE pbyBuffer + PBYTE pbyBuffer ) { NTSTATUS ntStatus = 0; diff --git a/drivers/staging/vt6656/usbpipe.h b/drivers/staging/vt6656/usbpipe.h index ee86d3716dc3..f852b39027a5 100644 --- a/drivers/staging/vt6656/usbpipe.h +++ b/drivers/staging/vt6656/usbpipe.h @@ -70,7 +70,7 @@ PIPEnsControlIn( WORD wValue, WORD wIndex, WORD wLength, - OUT PBYTE pbyBuffer + PBYTE pbyBuffer ); diff --git a/drivers/staging/vt6656/wmgr.c b/drivers/staging/vt6656/wmgr.c index 994022aa0d62..1824551bcc3c 100644 --- a/drivers/staging/vt6656/wmgr.c +++ b/drivers/staging/vt6656/wmgr.c @@ -312,7 +312,7 @@ s_vMgrSynchBSS ( PSDevice pDevice, UINT uBSSMode, PKnownBSS pCurr, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ); @@ -320,8 +320,8 @@ static BOOL s_bCipherMatch ( PKnownBSS pBSSNode, NDIS_802_11_ENCRYPTION_STATUS EncStatus, - OUT PBYTE pbyCCSPK, - OUT PBYTE pbyCCSGK + PBYTE pbyCCSPK, + PBYTE pbyCCSGK ); static void Encyption_Rebuild( @@ -419,7 +419,7 @@ void vMgrAssocBeginSta( HANDLE hDeviceContext, PSMgmtObject pMgmt, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -495,7 +495,7 @@ void vMgrReAssocBeginSta( HANDLE hDeviceContext, PSMgmtObject pMgmt, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -576,7 +576,7 @@ vMgrDisassocBeginSta( PSMgmtObject pMgmt, PBYTE abyDestAddress, WORD wReason, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1106,7 +1106,7 @@ void vMgrAuthenBeginSta( HANDLE hDeviceContext, PSMgmtObject pMgmt, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1166,7 +1166,7 @@ vMgrDeAuthenBeginSta( PSMgmtObject pMgmt, PBYTE abyDestAddress, WORD wReason, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -2358,7 +2358,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) void vMgrCreateOwnIBSS( HANDLE hDeviceContext, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -2633,7 +2633,7 @@ vMgrCreateOwnIBSS( void vMgrJoinBSSBegin( HANDLE hDeviceContext, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ) { @@ -2967,7 +2967,7 @@ s_vMgrSynchBSS ( PSDevice pDevice, UINT uBSSMode, PKnownBSS pCurr, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -4810,8 +4810,8 @@ static BOOL s_bCipherMatch ( PKnownBSS pBSSNode, NDIS_802_11_ENCRYPTION_STATUS EncStatus, - OUT PBYTE pbyCCSPK, - OUT PBYTE pbyCCSGK + PBYTE pbyCCSPK, + PBYTE pbyCCSGK ) { BYTE byMulticastCipher = KEY_CTL_INVALID; diff --git a/drivers/staging/vt6656/wmgr.h b/drivers/staging/vt6656/wmgr.h index 02ecec92babb..0eda12afd26b 100644 --- a/drivers/staging/vt6656/wmgr.h +++ b/drivers/staging/vt6656/wmgr.h @@ -417,14 +417,14 @@ void vMgrAssocBeginSta( HANDLE hDeviceContext, PSMgmtObject pMgmt, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ); void vMgrReAssocBeginSta( HANDLE hDeviceContext, PSMgmtObject pMgmt, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ); void @@ -433,26 +433,26 @@ vMgrDisassocBeginSta( PSMgmtObject pMgmt, PBYTE abyDestAddress, WORD wReason, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ); void vMgrAuthenBeginSta( HANDLE hDeviceContext, PSMgmtObject pMgmt, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ); void vMgrCreateOwnIBSS( HANDLE hDeviceContext, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ); void vMgrJoinBSSBegin( HANDLE hDeviceContext, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ); void @@ -466,7 +466,7 @@ vMgrRxManagePacket( void vMgrScanBegin( HANDLE hDeviceContext, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ); */ @@ -476,7 +476,7 @@ vMgrDeAuthenBeginSta( PSMgmtObject pMgmt, PBYTE abyDestAddress, WORD wReason, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ); BOOL diff --git a/drivers/staging/vt6656/wpa2.c b/drivers/staging/vt6656/wpa2.c index 73bfb500d45b..9bd6bf5bf37c 100644 --- a/drivers/staging/vt6656/wpa2.c +++ b/drivers/staging/vt6656/wpa2.c @@ -262,7 +262,7 @@ WPA2vParseRSN ( -*/ UINT WPA2uSetIEs(void *pMgmtHandle, - OUT PWLAN_IE_RSN pRSNIEs + PWLAN_IE_RSN pRSNIEs ) { PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; diff --git a/drivers/staging/vt6656/wpa2.h b/drivers/staging/vt6656/wpa2.h index 367aecee8b7c..79305a79b9da 100644 --- a/drivers/staging/vt6656/wpa2.h +++ b/drivers/staging/vt6656/wpa2.h @@ -72,7 +72,7 @@ WPA2vParseRSN ( UINT WPA2uSetIEs( void *pMgmtHandle, - OUT PWLAN_IE_RSN pRSNIEs + PWLAN_IE_RSN pRSNIEs ); #endif /* __WPA2_H__ */ -- cgit v1.2.3 From 6e1b4e24e6e4025b399159f3605bfa958464272a Mon Sep 17 00:00:00 2001 From: Andres More Date: Tue, 4 May 2010 20:40:11 -0300 Subject: Staging: vt6656: code cleanup, resolved sparse finding Cleared sparse warning 'Using plain integer as NULL pointer' Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/wmgr.c | 77 ++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/wmgr.c b/drivers/staging/vt6656/wmgr.c index 1824551bcc3c..5af98e9a8f03 100644 --- a/drivers/staging/vt6656/wmgr.c +++ b/drivers/staging/vt6656/wmgr.c @@ -958,12 +958,12 @@ s_vMgrRxAssocResponse( sFrame.pBuf = (PBYTE)pRxPacket->p80211Header; // decode the frame vMgrDecodeAssocResponse(&sFrame); - if ((sFrame.pwCapInfo == 0) || - (sFrame.pwStatus == 0) || - (sFrame.pwAid == 0) || - (sFrame.pSuppRates == 0)){ - DBG_PORT80(0xCC); - return; + if ((sFrame.pwCapInfo == NULL) + || (sFrame.pwStatus == NULL) + || (sFrame.pwAid == NULL) + || (sFrame.pSuppRates == NULL)) { + DBG_PORT80(0xCC); + return; }; pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.Capabilities = *(sFrame.pwCapInfo); @@ -1871,14 +1871,14 @@ s_vMgrRxBeacon( // decode the beacon frame vMgrDecodeBeacon(&sFrame); - if ((sFrame.pwBeaconInterval == 0) || - (sFrame.pwCapInfo == 0) || - (sFrame.pSSID == 0) || - (sFrame.pSuppRates == 0) ) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx beacon frame error\n"); - return; - }; + if ((sFrame.pwBeaconInterval == NULL) + || (sFrame.pwCapInfo == NULL) + || (sFrame.pSSID == NULL) + || (sFrame.pSuppRates == NULL)) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx beacon frame error\n"); + return; + }; if( byCurrChannel > CB_MAX_CHANNEL_24G ) { @@ -2152,9 +2152,9 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) if (bTSFLargeDiff) bUpdateTSF = TRUE; - if ((pDevice->bEnablePSMode == TRUE) &&(sFrame.pTIM != 0)) { + if ((pDevice->bEnablePSMode == TRUE) && (sFrame.pTIM)) { - // deal with DTIM, analysis TIM + /* deal with DTIM, analysis TIM */ pMgmt->bMulticastTIM = WLAN_MGMT_IS_MULTICAST_TIM(sFrame.pTIM->byBitMapCtl) ? TRUE : FALSE ; pMgmt->byDTIMCount = sFrame.pTIM->byDTIMCount; pMgmt->byDTIMPeriod = sFrame.pTIM->byDTIMPeriod; @@ -4246,14 +4246,16 @@ s_vMgrRxProbeResponse( sFrame.pBuf = (PBYTE)pRxPacket->p80211Header; vMgrDecodeProbeResponse(&sFrame); - if ((sFrame.pqwTimestamp == 0) || - (sFrame.pwBeaconInterval == 0) || - (sFrame.pwCapInfo == 0) || - (sFrame.pSSID == 0) || - (sFrame.pSuppRates == 0)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp:Fail addr:[%p] \n", pRxPacket->p80211Header); - DBG_PORT80(0xCC); - return; + if ((sFrame.pqwTimestamp == NULL) + || (sFrame.pwBeaconInterval == NULL) + || (sFrame.pwCapInfo == NULL) + || (sFrame.pSSID == NULL) + || (sFrame.pSuppRates == NULL)) { + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp:Fail addr:[%p]\n", + pRxPacket->p80211Header); + DBG_PORT80(0xCC); + return; }; if(sFrame.pSSID->len == 0) @@ -4263,22 +4265,23 @@ s_vMgrRxProbeResponse( //{{ RobertYu:20050201, 11a byCurrChannel != sFrame.pDSParms->byCurrChannel mapping if( byCurrChannel > CB_MAX_CHANNEL_24G ) { - if (sFrame.pDSParms != 0) { - if (byCurrChannel == RFaby11aChannelIndex[sFrame.pDSParms->byCurrChannel-1]) - bChannelHit = TRUE; - byCurrChannel = RFaby11aChannelIndex[sFrame.pDSParms->byCurrChannel-1]; + if (sFrame.pDSParms) { + if (byCurrChannel == + RFaby11aChannelIndex[sFrame.pDSParms->byCurrChannel-1]) + bChannelHit = TRUE; + byCurrChannel = + RFaby11aChannelIndex[sFrame.pDSParms->byCurrChannel-1]; } else { - bChannelHit = TRUE; + bChannelHit = TRUE; } - } else { - if (sFrame.pDSParms != 0) { - if (byCurrChannel == sFrame.pDSParms->byCurrChannel) - bChannelHit = TRUE; - byCurrChannel = sFrame.pDSParms->byCurrChannel; - } else { - bChannelHit = TRUE; - } + if (sFrame.pDSParms) { + if (byCurrChannel == sFrame.pDSParms->byCurrChannel) + bChannelHit = TRUE; + byCurrChannel = sFrame.pDSParms->byCurrChannel; + } else { + bChannelHit = TRUE; + } } //RobertYu:20050201 @@ -4286,7 +4289,7 @@ s_vMgrRxProbeResponse( if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) return; - if (sFrame.pERP != NULL) { + if (sFrame.pERP) { sERP.byERP = sFrame.pERP->byContext; sERP.bERPExist = TRUE; } else { -- cgit v1.2.3 From 7ec21181d22891ecebcd01075a819a4373c54362 Mon Sep 17 00:00:00 2001 From: Marin Mitov Date: Wed, 5 May 2010 20:31:38 +0300 Subject: Staging: dt3155v4l: Adding the missing linux/delay.h The prototypes of udelay() and msleep() are in linux/delay.h, so include it. Reported-by: Randy Dunlap Signed-off-by: Marin Mitov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dt3155v4l/dt3155v4l.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/dt3155v4l/dt3155v4l.c b/drivers/staging/dt3155v4l/dt3155v4l.c index 6282b7bbd4eb..d596e9d49222 100644 --- a/drivers/staging/dt3155v4l/dt3155v4l.c +++ b/drivers/staging/dt3155v4l/dt3155v4l.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3 From 2342df0e63f4ca9a4227ea06f951f09180497914 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 10:45:16 -0700 Subject: Staging: dt3155v4l: fix some sparse warnings Mostly some __iomem markings and some static functions as well. Cc: Marin Mitov --- drivers/staging/dt3155v4l/dt3155v4l.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dt3155v4l/dt3155v4l.c b/drivers/staging/dt3155v4l/dt3155v4l.c index d596e9d49222..881c3e99bd47 100644 --- a/drivers/staging/dt3155v4l/dt3155v4l.c +++ b/drivers/staging/dt3155v4l/dt3155v4l.c @@ -65,7 +65,7 @@ static u8 config_init = ACQ_MODE_EVEN; * in a byte pointed by data. */ static int -read_i2c_reg(void *addr, u8 index, u8 *data) +read_i2c_reg(void __iomem *addr, u8 index, u8 *data) { u32 tmp = index; @@ -102,7 +102,7 @@ read_i2c_reg(void *addr, u8 index, u8 *data) * and busy waits for the process to finish. */ static int -write_i2c_reg(void *addr, u8 index, u8 data) +write_i2c_reg(void __iomem *addr, u8 index, u8 data) { u32 tmp = index; @@ -134,8 +134,7 @@ write_i2c_reg(void *addr, u8 index, u8 data) * This function starts writting the specified (by index) register * and then returns. */ -void -write_i2c_reg_nowait(void *addr, u8 index, u8 data) +static void write_i2c_reg_nowait(void __iomem *addr, u8 index, u8 data) { u32 tmp = index; @@ -152,8 +151,7 @@ write_i2c_reg_nowait(void *addr, u8 index, u8 data) * * This function waits reading/writting to finish. */ -static int -wait_i2c_reg(void *addr) +static int wait_i2c_reg(void __iomem *addr) { if (ioread32(addr + IIC_CSR2) & NEW_CYCLE) udelay(65); /* wait at least 63 usec for NEW_CYCLE to clear */ -- cgit v1.2.3 From 1e19c054434c7d3ad618129c2ff5c3d81efa6949 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:29 -0400 Subject: Staging: hv: Remove check for NULL before calling kfree() kfree() knows how to deal with NULL, so there's no reason to check for NULL before passing something to it. Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Hv.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/Hv.c b/drivers/staging/hv/Hv.c index bfcb75008bf5..2418651772b8 100644 --- a/drivers/staging/hv/Hv.c +++ b/drivers/staging/hv/Hv.c @@ -305,11 +305,9 @@ void HvCleanup(void) DPRINT_ENTER(VMBUS); - if (gHvContext.SignalEventBuffer) { - gHvContext.SignalEventBuffer = NULL; - gHvContext.SignalEventParam = NULL; - kfree(gHvContext.SignalEventBuffer); - } + kfree(gHvContext.SignalEventBuffer); + gHvContext.SignalEventBuffer = NULL; + gHvContext.SignalEventParam = NULL; if (gHvContext.HypercallPage) { hypercallMsr.AsUINT64 = 0; -- cgit v1.2.3 From 75910f236a30bded00f078cab994f35a7171c39b Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:31 -0400 Subject: Staging: hv: remove ASSERT()s in ChannelMgt.c Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/ChannelMgmt.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/ChannelMgmt.c b/drivers/staging/hv/ChannelMgmt.c index 445506d45edb..05e6699e3c78 100644 --- a/drivers/staging/hv/ChannelMgmt.c +++ b/drivers/staging/hv/ChannelMgmt.c @@ -753,9 +753,15 @@ int VmbusChannelRequestOffers(void) msgInfo = kmalloc(sizeof(*msgInfo) + sizeof(struct vmbus_channel_message_header), GFP_KERNEL); - ASSERT(msgInfo != NULL); + if (!msgInfo) + return -ENOMEM; msgInfo->WaitEvent = osd_WaitEventCreate(); + if (!msgInfo->WaitEvent) { + kfree(msgInfo); + return -ENOMEM; + } + msg = (struct vmbus_channel_message_header *)msgInfo->Msg; msg->MessageType = ChannelMessageRequestOffers; -- cgit v1.2.3 From 7e052d98f2bbcaaaa6d509081d78e600927cfe60 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:30 -0400 Subject: Staging: hv: check return value of osd_PageAlloc() The return value of osd_PageAlloc() was checked using an ASSERT(). Change that to more useful behaviour. Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Channel.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/Channel.c index de2ccb1082ce..d939723db335 100644 --- a/drivers/staging/hv/Channel.c +++ b/drivers/staging/hv/Channel.c @@ -192,7 +192,9 @@ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, /* Allocate the ring buffer */ out = osd_PageAlloc((SendRingBufferSize + RecvRingBufferSize) >> PAGE_SHIFT); - ASSERT(out); + if (!out) + return -ENOMEM; + ASSERT(((unsigned long)out & (PAGE_SIZE-1)) == 0); in = (void *)((unsigned long)out + SendRingBufferSize); -- cgit v1.2.3 From 8cad0af9a1a1882cd00f12f8f7c79690f563b1d7 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:32 -0400 Subject: Staging: hv: return correct error values in Connection.c Also check the kzalloc call return value. Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Connection.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/Connection.c b/drivers/staging/hv/Connection.c index dbf00560e0ac..1e4111412ab6 100644 --- a/drivers/staging/hv/Connection.c +++ b/drivers/staging/hv/Connection.c @@ -93,7 +93,7 @@ int VmbusConnect(void) sizeof(struct vmbus_channel_initiate_contact), GFP_KERNEL); if (msgInfo == NULL) { - ret = -1; + ret = -ENOMEM; goto Cleanup; } @@ -195,6 +195,8 @@ int VmbusDisconnect(void) return -1; msg = kzalloc(sizeof(struct vmbus_channel_message_header), GFP_KERNEL); + if (!msg) + return -ENOMEM; msg->MessageType = ChannelMessageUnload; -- cgit v1.2.3 From 80d11b2ae26543656f7226b44ed9d6a184766e85 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:33 -0400 Subject: Staging: hv: test return value of osd_WaitEventCreate() The return value of osd_WaitEventCreate() was not examined in some places. Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Connection.c | 5 +++++ drivers/staging/hv/NetVsc.c | 4 ++++ drivers/staging/hv/StorVsc.c | 10 +++++++++- 3 files changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/Connection.c b/drivers/staging/hv/Connection.c index 1e4111412ab6..e590eb4b6e76 100644 --- a/drivers/staging/hv/Connection.c +++ b/drivers/staging/hv/Connection.c @@ -98,6 +98,11 @@ int VmbusConnect(void) } msgInfo->WaitEvent = osd_WaitEventCreate(); + if (!msgInfo->WaitEvent) { + ret = -ENOMEM; + goto Cleanup; + } + msg = (struct vmbus_channel_initiate_contact *)msgInfo->Msg; msg->Header.MessageType = ChannelMessageInitiateContact; diff --git a/drivers/staging/hv/NetVsc.c b/drivers/staging/hv/NetVsc.c index 27516d40b6ed..d3154e711776 100644 --- a/drivers/staging/hv/NetVsc.c +++ b/drivers/staging/hv/NetVsc.c @@ -749,6 +749,10 @@ static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) &netDevice->ReceivePacketList); } netDevice->ChannelInitEvent = osd_WaitEventCreate(); + if (!netDevice->ChannelInitEvent) { + ret = -ENOMEM; + goto Cleanup; + } /* Open the channel */ ret = Device->Driver->VmbusChannelInterface.Open(Device, diff --git a/drivers/staging/hv/StorVsc.c b/drivers/staging/hv/StorVsc.c index 7372317fe836..4d0fbce229e2 100644 --- a/drivers/staging/hv/StorVsc.c +++ b/drivers/staging/hv/StorVsc.c @@ -199,6 +199,10 @@ static int StorVscChannelInit(struct hv_device *Device) */ memset(request, 0, sizeof(struct storvsc_request_extension)); request->WaitEvent = osd_WaitEventCreate(); + if (!request->WaitEvent) { + ret = -ENOMEM; + goto nomem; + } vstorPacket->Operation = VStorOperationBeginInitialization; vstorPacket->Flags = REQUEST_COMPLETION_FLAG; @@ -338,7 +342,7 @@ static int StorVscChannelInit(struct hv_device *Device) Cleanup: kfree(request->WaitEvent); request->WaitEvent = NULL; - +nomem: PutStorDevice(Device); DPRINT_EXIT(STORVSC); @@ -649,6 +653,10 @@ int StorVscOnHostReset(struct hv_device *Device) vstorPacket = &request->VStorPacket; request->WaitEvent = osd_WaitEventCreate(); + if (!request->WaitEvent) { + ret = -ENOMEM; + goto Cleanup; + } vstorPacket->Operation = VStorOperationResetBus; vstorPacket->Flags = REQUEST_COMPLETION_FLAG; -- cgit v1.2.3 From c3bf2e26b30f4ea54f3825e8ebda7cb10ec204de Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:34 -0400 Subject: Staging: hv: remove ASSERT()s in Channel.c Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Channel.c | 45 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/Channel.c index d939723db335..79c013b48170 100644 --- a/drivers/staging/hv/Channel.c +++ b/drivers/staging/hv/Channel.c @@ -178,7 +178,7 @@ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, struct vmbus_channel_msginfo *openInfo; void *in, *out; unsigned long flags; - int ret; + int ret, err = 0; DPRINT_ENTER(VMBUS); @@ -218,6 +218,7 @@ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, SendRingBufferSize + RecvRingBufferSize, &NewChannel->RingBufferGpadlHandle); +/* FIXME: the value of ret is not checked */ DPRINT_DBG(VMBUS, "channel %p ", @@ -233,9 +234,16 @@ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, openInfo = kmalloc(sizeof(*openInfo) + sizeof(struct vmbus_channel_open_channel), GFP_KERNEL); - ASSERT(openInfo != NULL); + if (!openInfo) { + err = -ENOMEM; + goto errorout; + } openInfo->WaitEvent = osd_WaitEventCreate(); + if (!openInfo->WaitEvent) { + err = -ENOMEM; + goto errorout; + } openMsg = (struct vmbus_channel_open_channel *)openInfo->Msg; openMsg->Header.MessageType = ChannelMessageOpenChannel; @@ -285,6 +293,12 @@ Cleanup: DPRINT_EXIT(VMBUS); return 0; + +errorout: + osd_PageFree(out, (SendRingBufferSize + RecvRingBufferSize) + >> PAGE_SHIFT); + kfree(openInfo); + return err; } /* @@ -461,24 +475,29 @@ int VmbusChannelEstablishGpadl(struct vmbus_channel *Channel, void *Kbuffer, struct vmbus_channel_gpadl_header *gpadlMsg; struct vmbus_channel_gpadl_body *gpadlBody; /* struct vmbus_channel_gpadl_created *gpadlCreated; */ - struct vmbus_channel_msginfo *msgInfo; + struct vmbus_channel_msginfo *msgInfo = NULL; struct vmbus_channel_msginfo *subMsgInfo; u32 msgCount; struct list_head *curr; u32 nextGpadlHandle; unsigned long flags; - int ret; + int ret = 0; DPRINT_ENTER(VMBUS); nextGpadlHandle = atomic_read(&gVmbusConnection.NextGpadlHandle); atomic_inc(&gVmbusConnection.NextGpadlHandle); - VmbusChannelCreateGpadlHeader(Kbuffer, Size, &msgInfo, &msgCount); - ASSERT(msgInfo != NULL); - ASSERT(msgCount > 0); + ret = VmbusChannelCreateGpadlHeader(Kbuffer, Size, &msgInfo, &msgCount); + if (ret) + return ret; msgInfo->WaitEvent = osd_WaitEventCreate(); + if (!msgInfo->WaitEvent) { + ret = -ENOMEM; + goto Cleanup; + } + gpadlMsg = (struct vmbus_channel_gpadl_header *)msgInfo->Msg; gpadlMsg->Header.MessageType = ChannelMessageGpadlHeader; gpadlMsg->ChildRelId = Channel->OfferMsg.ChildRelId; @@ -567,9 +586,14 @@ int VmbusChannelTeardownGpadl(struct vmbus_channel *Channel, u32 GpadlHandle) info = kmalloc(sizeof(*info) + sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL); - ASSERT(info != NULL); + if (!info) + return -ENOMEM; info->WaitEvent = osd_WaitEventCreate(); + if (!info->WaitEvent) { + kfree(info); + return -ENOMEM; + } msg = (struct vmbus_channel_gpadl_teardown *)info->Msg; @@ -623,7 +647,10 @@ void VmbusChannelClose(struct vmbus_channel *Channel) /* Send a closing message */ info = kmalloc(sizeof(*info) + sizeof(struct vmbus_channel_close_channel), GFP_KERNEL); - ASSERT(info != NULL); + /* FIXME: can't do anything other than return here because the + * function is void */ + if (!info) + return; /* info->waitEvent = osd_WaitEventCreate(); */ -- cgit v1.2.3 From d1c250bb5df9afb5af3f290d1006dfe601a51e2e Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:35 -0400 Subject: Staging: hv: remove ASSERT() in Channel.c check memory allocation in VmbusChannelCreateGpadlHeader() and return -ENOMEM if it fails Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Channel.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/Channel.c index 79c013b48170..2d8c086228cc 100644 --- a/drivers/staging/hv/Channel.c +++ b/drivers/staging/hv/Channel.c @@ -382,6 +382,8 @@ static int VmbusChannelCreateGpadlHeader(void *Kbuffer, u32 Size, sizeof(struct vmbus_channel_gpadl_header) + sizeof(struct gpa_range) + pfnCount * sizeof(u64); msgHeader = kzalloc(msgSize, GFP_KERNEL); + if (!msgHeader) + goto nomem; INIT_LIST_HEAD(&msgHeader->SubMsgList); msgHeader->MessageSize = msgSize; @@ -416,7 +418,9 @@ static int VmbusChannelCreateGpadlHeader(void *Kbuffer, u32 Size, sizeof(struct vmbus_channel_gpadl_body) + pfnCurr * sizeof(u64); msgBody = kzalloc(msgSize, GFP_KERNEL); - ASSERT(msgBody); + /* FIXME: we probably need to more if this fails */ + if (!msgBody) + goto nomem; msgBody->MessageSize = msgSize; (*MessageCount)++; gpadlBody = @@ -459,6 +463,10 @@ static int VmbusChannelCreateGpadlHeader(void *Kbuffer, u32 Size, } return 0; +nomem: + kfree(msgHeader); + kfree(msgBody); + return -ENOMEM; } /* -- cgit v1.2.3 From 99259159c0eb58a539ed399677c8294e3792722b Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:36 -0400 Subject: Staging: hv: remove ASSERT() in Channel.c return an error instead of calling ASSERT() if VmbusPostMessage() fails. Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Channel.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/Channel.c index 2d8c086228cc..8c30540b725d 100644 --- a/drivers/staging/hv/Channel.c +++ b/drivers/staging/hv/Channel.c @@ -551,7 +551,9 @@ int VmbusChannelEstablishGpadl(struct vmbus_channel *Channel, void *Kbuffer, ret = VmbusPostMessage(gpadlBody, subMsgInfo->MessageSize - sizeof(*subMsgInfo)); - ASSERT(ret == 0); + if (!ret) + goto Cleanup; + } } osd_WaitEventWait(msgInfo->WaitEvent); -- cgit v1.2.3 From b94ef345b26b4d75e5028617e43fb51d7dd0162b Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:37 -0400 Subject: Staging: hv: test return value of VmbusChannelEstablishGpadl() The return value of VmbusChannelEstablishGpadl() was not examined in Channel.c Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Channel.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/Channel.c index 8c30540b725d..fdd441174f23 100644 --- a/drivers/staging/hv/Channel.c +++ b/drivers/staging/hv/Channel.c @@ -175,7 +175,7 @@ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, void (*OnChannelCallback)(void *context), void *Context) { struct vmbus_channel_open_channel *openMsg; - struct vmbus_channel_msginfo *openInfo; + struct vmbus_channel_msginfo *openInfo = NULL; void *in, *out; unsigned long flags; int ret, err = 0; @@ -218,7 +218,11 @@ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, SendRingBufferSize + RecvRingBufferSize, &NewChannel->RingBufferGpadlHandle); -/* FIXME: the value of ret is not checked */ + + if (!ret) { + err = ret; + goto errorout; + } DPRINT_DBG(VMBUS, "channel %p ", @@ -250,7 +254,6 @@ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, openMsg->OpenId = NewChannel->OfferMsg.ChildRelId; /* FIXME */ openMsg->ChildRelId = NewChannel->OfferMsg.ChildRelId; openMsg->RingBufferGpadlHandle = NewChannel->RingBufferGpadlHandle; - ASSERT(openMsg->RingBufferGpadlHandle); openMsg->DownstreamRingBufferPageOffset = SendRingBufferSize >> PAGE_SHIFT; openMsg->ServerContextAreaGpadlHandle = 0; /* TODO */ @@ -295,6 +298,8 @@ Cleanup: return 0; errorout: + RingBufferCleanup(&NewChannel->Outbound); + RingBufferCleanup(&NewChannel->Inbound); osd_PageFree(out, (SendRingBufferSize + RecvRingBufferSize) >> PAGE_SHIFT); kfree(openInfo); -- cgit v1.2.3 From c827f944f51e02894d68f036da843783e622ec2a Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:38 -0400 Subject: Staging: hv: remove ASSERT() in Channel.c VmbusChannelOpen() will now return -EINVAL if UserDataLen is too big. Previously this was handled by an assert. Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Channel.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/Channel.c index fdd441174f23..bd1a33608fcf 100644 --- a/drivers/staging/hv/Channel.c +++ b/drivers/staging/hv/Channel.c @@ -258,7 +258,11 @@ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, PAGE_SHIFT; openMsg->ServerContextAreaGpadlHandle = 0; /* TODO */ - ASSERT(UserDataLen <= MAX_USER_DEFINED_BYTES); + if (UserDataLen > MAX_USER_DEFINED_BYTES) { + err = -EINVAL; + goto errorout; + } + if (UserDataLen) memcpy(openMsg->UserData, UserData, UserDataLen); -- cgit v1.2.3 From 002b53ea5713910daf215037b72c5820413e2f95 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:39 -0400 Subject: Staging: hv: return -EINVAL instead of calling ASSERT() Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Channel.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/Channel.c index bd1a33608fcf..0a9ca336ede9 100644 --- a/drivers/staging/hv/Channel.c +++ b/drivers/staging/hv/Channel.c @@ -793,7 +793,8 @@ int VmbusChannelSendPacketPageBuffer(struct vmbus_channel *Channel, DPRINT_ENTER(VMBUS); - ASSERT(PageCount <= MAX_PAGE_BUFFER_COUNT); + if (PageCount > MAX_PAGE_BUFFER_COUNT) + return -EINVAL; DumpVmbusChannel(Channel); @@ -864,8 +865,8 @@ int VmbusChannelSendPacketMultiPageBuffer(struct vmbus_channel *Channel, DPRINT_DBG(VMBUS, "data buffer - offset %u len %u pfn count %u", MultiPageBuffer->Offset, MultiPageBuffer->Length, PfnCount); - ASSERT(PfnCount > 0); - ASSERT(PfnCount <= MAX_MULTIPAGE_BUFFER_COUNT); + if ((PfnCount < 0) || (PfnCount > MAX_MULTIPAGE_BUFFER_COUNT)) + return -EINVAL; /* * Adjust the size down since VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER is -- cgit v1.2.3 From 0ace247ead760a6a56a7bb3b5926c28fef1d4c6c Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:40 -0400 Subject: staging: hv: remove ASSERT()s in Channel.c These ASSERT()s serve no purpose other than for debugging. Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Channel.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/Channel.c index 0a9ca336ede9..a1431e4ac8be 100644 --- a/drivers/staging/hv/Channel.c +++ b/drivers/staging/hv/Channel.c @@ -183,8 +183,8 @@ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, DPRINT_ENTER(VMBUS); /* Aligned to page size */ - ASSERT(!(SendRingBufferSize & (PAGE_SIZE - 1))); - ASSERT(!(RecvRingBufferSize & (PAGE_SIZE - 1))); + /* ASSERT(!(SendRingBufferSize & (PAGE_SIZE - 1))); */ + /* ASSERT(!(RecvRingBufferSize & (PAGE_SIZE - 1))); */ NewChannel->OnChannelCallback = OnChannelCallback; NewChannel->ChannelCallbackContext = Context; @@ -195,7 +195,7 @@ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, if (!out) return -ENOMEM; - ASSERT(((unsigned long)out & (PAGE_SIZE-1)) == 0); + /* ASSERT(((unsigned long)out & (PAGE_SIZE-1)) == 0); */ in = (void *)((unsigned long)out + SendRingBufferSize); @@ -373,7 +373,7 @@ static int VmbusChannelCreateGpadlHeader(void *Kbuffer, u32 Size, int pfnSum, pfnCount, pfnLeft, pfnCurr, pfnSize; /* ASSERT((kbuffer & (PAGE_SIZE-1)) == 0); */ - ASSERT((Size & (PAGE_SIZE-1)) == 0); + /* ASSERT((Size & (PAGE_SIZE-1)) == 0); */ pageCount = Size >> PAGE_SHIFT; pfn = virt_to_phys(Kbuffer) >> PAGE_SHIFT; @@ -601,7 +601,7 @@ int VmbusChannelTeardownGpadl(struct vmbus_channel *Channel, u32 GpadlHandle) DPRINT_ENTER(VMBUS); - ASSERT(GpadlHandle != 0); + /* ASSERT(GpadlHandle != 0); */ info = kmalloc(sizeof(*info) + sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL); @@ -746,7 +746,7 @@ int VmbusChannelSendPacket(struct vmbus_channel *Channel, const void *Buffer, DumpVmbusChannel(Channel); - ASSERT((packetLenAligned - packetLen) < sizeof(u64)); + /* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */ /* Setup the descriptor */ desc.Type = Type; /* VmbusPacketTypeDataInBand; */ @@ -808,7 +808,7 @@ int VmbusChannelSendPacketPageBuffer(struct vmbus_channel *Channel, packetLen = descSize + BufferLen; packetLenAligned = ALIGN_UP(packetLen, sizeof(u64)); - ASSERT((packetLenAligned - packetLen) < sizeof(u64)); + /* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */ /* Setup the descriptor */ desc.Type = VmbusPacketTypeDataUsingGpaDirect; @@ -878,7 +878,7 @@ int VmbusChannelSendPacketMultiPageBuffer(struct vmbus_channel *Channel, packetLen = descSize + BufferLen; packetLenAligned = ALIGN_UP(packetLen, sizeof(u64)); - ASSERT((packetLenAligned - packetLen) < sizeof(u64)); + /* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */ /* Setup the descriptor */ desc.Type = VmbusPacketTypeDataUsingGpaDirect; @@ -1056,7 +1056,7 @@ int VmbusChannelRecvPacketRaw(struct vmbus_channel *Channel, void *Buffer, void VmbusChannelOnChannelEvent(struct vmbus_channel *Channel) { DumpVmbusChannel(Channel); - ASSERT(Channel->OnChannelCallback); + /* ASSERT(Channel->OnChannelCallback); */ Channel->OnChannelCallback(Channel->ChannelCallbackContext); -- cgit v1.2.3 From b856e7382f7d1b184a3dac200275e23a27488ce1 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:41 -0400 Subject: staging: hv: remove ASSERT()s in storvsc_drv.c These ASSERT()s serve no purpose other than for debugging. Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_drv.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 26b35a6c679a..d9649e37e11c 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -385,11 +385,11 @@ static void storvsc_commmand_completion(struct hv_storvsc_request *request) void (*scsi_done_fn)(struct scsi_cmnd *); struct scsi_sense_hdr sense_hdr; - ASSERT(request == &cmd_request->request); - ASSERT(scmnd); - ASSERT((unsigned long)scmnd->host_scribble == - (unsigned long)cmd_request); - ASSERT(scmnd->scsi_done); + /* ASSERT(request == &cmd_request->request); */ + /* ASSERT(scmnd); */ + /* ASSERT((unsigned long)scmnd->host_scribble == */ + /* (unsigned long)cmd_request); */ + /* ASSERT(scmnd->scsi_done); */ DPRINT_ENTER(STORVSC_DRV); @@ -413,7 +413,7 @@ static void storvsc_commmand_completion(struct hv_storvsc_request *request) scsi_print_sense_hdr("storvsc", &sense_hdr); } - ASSERT(request->BytesXfer <= request->DataBuffer.Length); + /* ASSERT(request->BytesXfer <= request->DataBuffer.Length); */ scsi_set_resid(scmnd, request->DataBuffer.Length - request->BytesXfer); scsi_done_fn = scmnd->scsi_done; @@ -522,7 +522,7 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl, src = src_addr; srclen = orig_sgl[i].length; - ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); + /* ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); */ if (j == 0) bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0); @@ -583,7 +583,7 @@ static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl, KM_IRQ0) + orig_sgl[i].offset; dest = dest_addr; destlen = orig_sgl[i].length; - ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); + /* ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); */ if (j == 0) bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0); @@ -655,7 +655,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, /* If retrying, no need to prep the cmd */ if (scmnd->host_scribble) { - ASSERT(scmnd->scsi_done != NULL); + /* ASSERT(scmnd->scsi_done != NULL); */ cmd_request = (struct storvsc_cmd_request *)scmnd->host_scribble; @@ -665,8 +665,8 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, goto retry_request; } - ASSERT(scmnd->scsi_done == NULL); - ASSERT(scmnd->host_scribble == NULL); + /* ASSERT(scmnd->scsi_done == NULL); */ + /* ASSERT(scmnd->host_scribble == NULL); */ scmnd->scsi_done = done; @@ -717,7 +717,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, request->TargetId = scmnd->device->id; request->LunId = scmnd->device->lun; - ASSERT(scmnd->cmd_len <= 16); + /* ASSERT(scmnd->cmd_len <= 16); */ request->CdbLen = scmnd->cmd_len; request->Cdb = scmnd->cmnd; @@ -773,13 +773,11 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, page_to_pfn(sg_page((&sgl[i]))); } } else if (scsi_sglist(scmnd)) { - ASSERT(scsi_bufflen(scmnd) <= PAGE_SIZE); + /* ASSERT(scsi_bufflen(scmnd) <= PAGE_SIZE); */ request->DataBuffer.Offset = virt_to_phys(scsi_sglist(scmnd)) & (PAGE_SIZE-1); request->DataBuffer.PfnArray[0] = virt_to_phys(scsi_sglist(scmnd)) >> PAGE_SHIFT; - } else { - ASSERT(scsi_bufflen(scmnd) == 0); } retry_request: -- cgit v1.2.3 From ee3503762d86c13bb94ed1db200d4601517b1b9b Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:42 -0400 Subject: staging: hv: return error instead calling ASSERT in blkvsc_drv.c Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 8f8637e51d9e..b6a2cb8752d3 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -1213,7 +1213,10 @@ static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev) (!comp_req->request.Status ? 0 : -EIO), comp_req->sector_count * blkdev->sector_size); - ASSERT(ret != 0); + + /* FIXME: shouldn't this do more than return? */ + if (ret) + goto out; } kmem_cache_free(blkdev->request_pool, comp_req); @@ -1245,6 +1248,7 @@ static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev) kmem_cache_free(blkdev->request_pool, pend_req); } +out: return ret; } -- cgit v1.2.3 From 5afd06ccd6b309f6a47d7e8fa4ea349b25738d97 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:43 -0400 Subject: staging: hv: make the block driver depend on LBDAF Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Kconfig | 2 +- drivers/staging/hv/blkvsc_drv.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/Kconfig b/drivers/staging/hv/Kconfig index 79afb1e96c33..97480f5c6599 100644 --- a/drivers/staging/hv/Kconfig +++ b/drivers/staging/hv/Kconfig @@ -17,7 +17,7 @@ config HYPERV_STORAGE config HYPERV_BLOCK tristate "Microsoft Hyper-V virtual block driver" - depends on BLOCK && SCSI + depends on BLOCK && SCSI && LBDAF default HYPERV help Select this option to enable the Hyper-V virtual block driver. diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index b6a2cb8752d3..8a25154c06f5 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -1489,7 +1489,7 @@ static int __init blkvsc_init(void) { int ret; - ASSERT(sizeof(sector_t) == 8); /* Make sure CONFIG_LBD is set */ + BUILD_BUG_ON(sizeof(sector_t) != 8); DPRINT_ENTER(BLKVSC_DRV); -- cgit v1.2.3 From 4e5166b5d83e748014f6f22a4f8a3537294ced9b Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:44 -0400 Subject: staging: hv: remove ASSERT()s in blkvsc_drv.c These ASSERT()s serve no purpose other than for debugging. Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 8a25154c06f5..78fc348334e7 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -288,8 +288,8 @@ static int blkvsc_probe(struct device *device) /* Initialize what we can here */ spin_lock_init(&blkdev->lock); - ASSERT(sizeof(struct blkvsc_request_group) <= - sizeof(struct blkvsc_request)); + /* ASSERT(sizeof(struct blkvsc_request_group) <= */ + /* sizeof(struct blkvsc_request)); */ blkdev->request_pool = kmem_cache_create(dev_name(&device_ctx->device), sizeof(struct blkvsc_request) + @@ -808,8 +808,8 @@ static int blkvsc_remove(struct device *device) static void blkvsc_init_rw(struct blkvsc_request *blkvsc_req) { - ASSERT(blkvsc_req->req); - ASSERT(blkvsc_req->sector_count <= (MAX_MULTIPAGE_BUFFER_COUNT*8)); + /* ASSERT(blkvsc_req->req); */ + /* ASSERT(blkvsc_req->sector_count <= (MAX_MULTIPAGE_BUFFER_COUNT*8)); */ blkvsc_req->cmd_len = 16; @@ -1116,7 +1116,7 @@ static void blkvsc_request_completion(struct hv_storvsc_request *request) unsigned long flags; struct blkvsc_request *comp_req, *tmp; - ASSERT(blkvsc_req->group); + /* ASSERT(blkvsc_req->group); */ DPRINT_DBG(BLKVSC_DRV, "blkdev %p blkvsc_req %p group %p type %s " "sect_start %lu sect_count %ld len %d group outstd %d " -- cgit v1.2.3 From e2e64432e9b76e8170d64b25a40feec991822555 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:45 -0400 Subject: staging: hv: remove ASSERT()s in StorVsc.c These ASSERT()s serve no purpose other than for debugging. Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/StorVsc.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/StorVsc.c b/drivers/staging/hv/StorVsc.c index 4d0fbce229e2..e73130e49cce 100644 --- a/drivers/staging/hv/StorVsc.c +++ b/drivers/staging/hv/StorVsc.c @@ -100,7 +100,7 @@ static inline struct storvsc_device *AllocStorDevice(struct hv_device *Device) static inline void FreeStorDevice(struct storvsc_device *Device) { - ASSERT(atomic_read(&Device->RefCount) == 0); + /* ASSERT(atomic_read(&Device->RefCount) == 0); */ kfree(Device); } @@ -137,10 +137,10 @@ static inline void PutStorDevice(struct hv_device *Device) struct storvsc_device *storDevice; storDevice = (struct storvsc_device *)Device->Extension; - ASSERT(storDevice); + /* ASSERT(storDevice); */ atomic_dec(&storDevice->RefCount); - ASSERT(atomic_read(&storDevice->RefCount)); + /* ASSERT(atomic_read(&storDevice->RefCount)); */ } /* Drop ref count to 1 to effectively disable GetStorDevice() */ @@ -149,7 +149,7 @@ static inline struct storvsc_device *ReleaseStorDevice(struct hv_device *Device) struct storvsc_device *storDevice; storDevice = (struct storvsc_device *)Device->Extension; - ASSERT(storDevice); + /* ASSERT(storDevice); */ /* Busy wait until the ref drop to 2, then set it to 1 */ while (atomic_cmpxchg(&storDevice->RefCount, 2, 1) != 2) @@ -165,7 +165,7 @@ static inline struct storvsc_device *FinalReleaseStorDevice( struct storvsc_device *storDevice; storDevice = (struct storvsc_device *)Device->Extension; - ASSERT(storDevice); + /* ASSERT(storDevice); */ /* Busy wait until the ref drop to 1, then set it to 0 */ while (atomic_cmpxchg(&storDevice->RefCount, 1, 0) != 1) @@ -370,12 +370,12 @@ static void StorVscOnIOCompletion(struct hv_device *Device, "completed bytes xfer %u", RequestExt, VStorPacket->VmSrb.DataTransferLength); - ASSERT(RequestExt != NULL); - ASSERT(RequestExt->Request != NULL); + /* ASSERT(RequestExt != NULL); */ + /* ASSERT(RequestExt->Request != NULL); */ request = RequestExt->Request; - ASSERT(request->OnIOCompletion != NULL); + /* ASSERT(request->OnIOCompletion != NULL); */ /* Copy over the status...etc */ request->Status = VStorPacket->VmSrb.ScsiStatus; @@ -395,8 +395,8 @@ static void StorVscOnIOCompletion(struct hv_device *Device, "valid - len %d\n", RequestExt, VStorPacket->VmSrb.SenseInfoLength); - ASSERT(VStorPacket->VmSrb.SenseInfoLength <= - request->SenseBufferSize); + /* ASSERT(VStorPacket->VmSrb.SenseInfoLength <= */ + /* request->SenseBufferSize); */ memcpy(request->SenseBuffer, VStorPacket->VmSrb.SenseData, VStorPacket->VmSrb.SenseInfoLength); @@ -451,7 +451,7 @@ static void StorVscOnChannelCallback(void *context) DPRINT_ENTER(STORVSC); - ASSERT(device); + /* ASSERT(device); */ storDevice = MustGetStorDevice(device); if (!storDevice) { @@ -474,7 +474,7 @@ static void StorVscOnChannelCallback(void *context) request = (struct storvsc_request_extension *) (unsigned long)requestId; - ASSERT(request); + /* ASSERT(request);c */ /* if (vstorPacket.Flags & SYNTHETIC_FLAG) */ if ((request == &storDevice->InitRequest) || @@ -821,7 +821,7 @@ int StorVscInitialize(struct hv_driver *Driver) sizeof(struct vmscsi_request)); /* Make sure we are at least 2 pages since 1 page is used for control */ - ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1)); + /* ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1)); */ Driver->name = gDriverName; memcpy(&Driver->deviceType, &gStorVscDeviceType, -- cgit v1.2.3 From 45e4431468f24748ba089b741713c740e854fccc Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:46 -0400 Subject: staging: hv: remove ASSERT()s in RndisFilter.c These ASSERT()s serve no purpose other than for debugging. Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/RndisFilter.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/RndisFilter.c b/drivers/staging/hv/RndisFilter.c index de4bc80341c3..f0aacc0c84c9 100644 --- a/drivers/staging/hv/RndisFilter.c +++ b/drivers/staging/hv/RndisFilter.c @@ -356,8 +356,8 @@ static void RndisFilterReceiveData(struct rndis_device *Device, DPRINT_ENTER(NETVSC); /* empty ethernet frame ?? */ - ASSERT(Packet->PageBuffers[0].Length > - RNDIS_MESSAGE_SIZE(struct rndis_packet)); + /* ASSERT(Packet->PageBuffers[0].Length > */ + /* RNDIS_MESSAGE_SIZE(struct rndis_packet)); */ rndisPacket = &Message->Message.Packet; @@ -567,8 +567,8 @@ static int RndisFilterSetPacketFilter(struct rndis_device *Device, DPRINT_ENTER(NETVSC); - ASSERT(RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32) <= - sizeof(struct rndis_message)); + /* ASSERT(RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32) <= */ + /* sizeof(struct rndis_message)); */ request = GetRndisRequest(Device, REMOTE_NDIS_SET_MSG, RNDIS_MESSAGE_SIZE(struct rndis_set_request) + @@ -640,8 +640,8 @@ int RndisFilterInit(struct netvsc_driver *Driver) Driver->Base.OnDeviceRemove; gRndisFilter.InnerDriver.Base.OnCleanup = Driver->Base.OnCleanup; - ASSERT(Driver->OnSend); - ASSERT(Driver->OnReceiveCallback); + /* ASSERT(Driver->OnSend); */ + /* ASSERT(Driver->OnReceiveCallback); */ gRndisFilter.InnerDriver.OnSend = Driver->OnSend; gRndisFilter.InnerDriver.OnReceiveCallback = Driver->OnReceiveCallback; gRndisFilter.InnerDriver.OnLinkStatusChanged = @@ -811,8 +811,8 @@ static int RndisFilterOnDeviceAdd(struct hv_device *Device, /* Initialize the rndis device */ netDevice = Device->Extension; - ASSERT(netDevice); - ASSERT(netDevice->Device); + /* ASSERT(netDevice); */ + /* ASSERT(netDevice->Device); */ netDevice->Extension = rndisDevice; rndisDevice->NetDevice = netDevice; @@ -921,7 +921,7 @@ static int RndisFilterOnSend(struct hv_device *Device, /* Add the rndis header */ filterPacket = (struct rndis_filter_packet *)Packet->Extension; - ASSERT(filterPacket); + /* ASSERT(filterPacket); */ memset(filterPacket, 0, sizeof(struct rndis_filter_packet)); -- cgit v1.2.3 From 8a62d7168af111bb80d041e6ccf74987056c79d3 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:47 -0400 Subject: staging: hv: remove ASSERT()s in RndisFilter.c return -EINVAL instead of calling ASSERT() for these conditionals. Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/RndisFilter.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/RndisFilter.c b/drivers/staging/hv/RndisFilter.c index f0aacc0c84c9..597c972f22c2 100644 --- a/drivers/staging/hv/RndisFilter.c +++ b/drivers/staging/hv/RndisFilter.c @@ -391,7 +391,9 @@ static int RndisFilterOnReceive(struct hv_device *Device, DPRINT_ENTER(NETVSC); - ASSERT(netDevice); + if (!netDevice) + return -EINVAL; + /* Make sure the rndis device state is initialized */ if (!netDevice->Extension) { DPRINT_ERR(NETVSC, "got rndis message but no rndis device..." @@ -492,7 +494,8 @@ static int RndisFilterQueryDevice(struct rndis_device *Device, u32 Oid, DPRINT_ENTER(NETVSC); - ASSERT(Result); + if (!Result) + return -EINVAL; *ResultSize = 0; request = GetRndisRequest(Device, REMOTE_NDIS_QUERY_MSG, @@ -885,7 +888,9 @@ int RndisFilterOnOpen(struct hv_device *Device) DPRINT_ENTER(NETVSC); - ASSERT(netDevice); + if (!netDevice) + return -EINVAL; + ret = RndisFilterOpenDevice(netDevice->Extension); DPRINT_EXIT(NETVSC); @@ -900,7 +905,9 @@ int RndisFilterOnClose(struct hv_device *Device) DPRINT_ENTER(NETVSC); - ASSERT(netDevice); + if (!netDevice) + return -EINVAL; + ret = RndisFilterCloseDevice(netDevice->Extension); DPRINT_EXIT(NETVSC); -- cgit v1.2.3 From 1bbdd7a5380239533c4bb648c5d5d9510f12974b Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:48 -0400 Subject: staging: hv: remove ASSERT()s in RingBuffer.c These ASSERT()s serve no purpose other than for debugging. Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/RingBuffer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/RingBuffer.c b/drivers/staging/hv/RingBuffer.c index 08b3c5567e9c..ee481fd972b7 100644 --- a/drivers/staging/hv/RingBuffer.c +++ b/drivers/staging/hv/RingBuffer.c @@ -72,7 +72,7 @@ GetNextWriteLocation(RING_BUFFER_INFO *RingInfo) { u32 next = RingInfo->RingBuffer->WriteIndex; - ASSERT(next < RingInfo->RingDataSize); + /* ASSERT(next < RingInfo->RingDataSize); */ return next; } @@ -106,7 +106,7 @@ GetNextReadLocation(RING_BUFFER_INFO *RingInfo) { u32 next = RingInfo->RingBuffer->ReadIndex; - ASSERT(next < RingInfo->RingDataSize); + /* ASSERT(next < RingInfo->RingDataSize); */ return next; } @@ -126,7 +126,7 @@ GetNextReadLocationWithOffset(RING_BUFFER_INFO *RingInfo, u32 Offset) { u32 next = RingInfo->RingBuffer->ReadIndex; - ASSERT(next < RingInfo->RingDataSize); + /* ASSERT(next < RingInfo->RingDataSize); */ next += Offset; next %= RingInfo->RingDataSize; -- cgit v1.2.3 From 3324fb405340cf52fe361697a86d235587402d9c Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:49 -0400 Subject: staging: hv: check return value of RingBufferInit() RingBufferInit() would always return sucess and instead relied on an ASSERT() to test for an error condition. Remove the ASSERT() and return -EINVAL instead. The return value of RingBufferInit() was also never checked, so check it. Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Channel.c | 13 +++++++++++-- drivers/staging/hv/RingBuffer.c | 3 ++- 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/Channel.c index a1431e4ac8be..158f62d8553a 100644 --- a/drivers/staging/hv/Channel.c +++ b/drivers/staging/hv/Channel.c @@ -203,9 +203,18 @@ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, NewChannel->RingBufferPageCount = (SendRingBufferSize + RecvRingBufferSize) >> PAGE_SHIFT; - RingBufferInit(&NewChannel->Outbound, out, SendRingBufferSize); + ret = RingBufferInit(&NewChannel->Outbound, out, SendRingBufferSize); + if (!ret) { + err = ret; + goto errorout; + } + + ret = RingBufferInit(&NewChannel->Inbound, in, RecvRingBufferSize); + if (!ret) { + err = ret; + goto errorout; + } - RingBufferInit(&NewChannel->Inbound, in, RecvRingBufferSize); /* Establish the gpadl for the ring buffer */ DPRINT_DBG(VMBUS, "Establishing ring buffer's gpadl for channel %p...", diff --git a/drivers/staging/hv/RingBuffer.c b/drivers/staging/hv/RingBuffer.c index ee481fd972b7..69f3ebae15a9 100644 --- a/drivers/staging/hv/RingBuffer.c +++ b/drivers/staging/hv/RingBuffer.c @@ -301,7 +301,8 @@ Description: --*/ int RingBufferInit(RING_BUFFER_INFO *RingInfo, void *Buffer, u32 BufferLen) { - ASSERT(sizeof(RING_BUFFER) == PAGE_SIZE); + if (sizeof(RING_BUFFER) != PAGE_SIZE) + return -EINVAL; memset(RingInfo, 0, sizeof(RING_BUFFER_INFO)); -- cgit v1.2.3 From a16e1485c758c236915ac1956694d11bff5e5daa Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:50 -0400 Subject: staging: hv: remove ASSERT()s and return -EINVAL in RingBuffer.c return -EINVAL instead of calling ASSERT() for these conditionals. Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/RingBuffer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/RingBuffer.c b/drivers/staging/hv/RingBuffer.c index 69f3ebae15a9..64f8d0f9e05c 100644 --- a/drivers/staging/hv/RingBuffer.c +++ b/drivers/staging/hv/RingBuffer.c @@ -490,7 +490,8 @@ int RingBufferRead(RING_BUFFER_INFO *InRingInfo, void *Buffer, u64 prevIndices = 0; unsigned long flags; - ASSERT(BufferLen > 0); + if (BufferLen <= 0) + return -EINVAL; spin_lock_irqsave(&InRingInfo->ring_lock, flags); -- cgit v1.2.3 From a3810b0ef61d23f37ace99ed0fb180b62fcb3f68 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:51 -0400 Subject: staging: hv: remove ASSERT()s in vmbus_drv.c These ASSERT()s serve no purpose other than for debugging. Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index d2a82aa3bbd8..a715b3db87ce 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -923,7 +923,7 @@ static void vmbus_msg_dpc(unsigned long data) DPRINT_ENTER(VMBUS_DRV); - ASSERT(vmbus_drv_obj->OnMsgDpc != NULL); + /* ASSERT(vmbus_drv_obj->OnMsgDpc != NULL); */ /* Call to bus driver to handle interrupt */ vmbus_drv_obj->OnMsgDpc(&vmbus_drv_obj->Base); @@ -940,7 +940,7 @@ static void vmbus_event_dpc(unsigned long data) DPRINT_ENTER(VMBUS_DRV); - ASSERT(vmbus_drv_obj->OnEventDpc != NULL); + /* ASSERT(vmbus_drv_obj->OnEventDpc != NULL); */ /* Call to bus driver to handle interrupt */ vmbus_drv_obj->OnEventDpc(&vmbus_drv_obj->Base); @@ -955,7 +955,7 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) DPRINT_ENTER(VMBUS_DRV); - ASSERT(vmbus_driver_obj->OnIsr != NULL); + /* ASSERT(vmbus_driver_obj->OnIsr != NULL); */ /* Call to bus driver to handle interrupt */ ret = vmbus_driver_obj->OnIsr(&vmbus_driver_obj->Base); -- cgit v1.2.3 From 972b9529ccfa604bd473c43589f5120066161edd Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:54 -0400 Subject: staging: hv: remove ASSERT()s These ASSERT()s serve no purpose other than for debugging. Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/BlkVsc.c | 2 +- drivers/staging/hv/Connection.c | 2 +- drivers/staging/hv/NetVsc.c | 49 ++++++++++++++++++++--------------------- 3 files changed, 26 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/BlkVsc.c b/drivers/staging/hv/BlkVsc.c index a48ee3a12646..b2f600551f10 100644 --- a/drivers/staging/hv/BlkVsc.c +++ b/drivers/staging/hv/BlkVsc.c @@ -78,7 +78,7 @@ int BlkVscInitialize(struct hv_driver *Driver) storDriver = (struct storvsc_driver_object *)Driver; /* Make sure we are at least 2 pages since 1 page is used for control */ - ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1)); + /* ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1)); */ Driver->name = gBlkDriverName; memcpy(&Driver->deviceType, &gBlkVscDeviceType, sizeof(struct hv_guid)); diff --git a/drivers/staging/hv/Connection.c b/drivers/staging/hv/Connection.c index e590eb4b6e76..3a01d3ca4ad0 100644 --- a/drivers/staging/hv/Connection.c +++ b/drivers/staging/hv/Connection.c @@ -254,7 +254,7 @@ static void VmbusProcessChannelEvent(void *context) struct vmbus_channel *channel; u32 relId = (u32)(unsigned long)context; - ASSERT(relId > 0); + /* ASSERT(relId > 0); */ /* * Find the channel based on this relid and invokes the diff --git a/drivers/staging/hv/NetVsc.c b/drivers/staging/hv/NetVsc.c index d3154e711776..9863ca252bd9 100644 --- a/drivers/staging/hv/NetVsc.c +++ b/drivers/staging/hv/NetVsc.c @@ -131,7 +131,7 @@ static void PutNetDevice(struct hv_device *Device) struct netvsc_device *netDevice; netDevice = Device->Extension; - ASSERT(netDevice); + /* ASSERT(netDevice); */ atomic_dec(&netDevice->RefCount); } @@ -184,14 +184,15 @@ int NetVscInitialize(struct hv_driver *drv) sizeof(struct vmtransfer_page_packet_header)); /* Make sure we are at least 2 pages since 1 page is used for control */ - ASSERT(driver->RingBufferSize >= (PAGE_SIZE << 1)); + /* ASSERT(driver->RingBufferSize >= (PAGE_SIZE << 1)); */ drv->name = gDriverName; memcpy(&drv->deviceType, &gNetVscDeviceType, sizeof(struct hv_guid)); /* Make sure it is set by the caller */ - ASSERT(driver->OnReceiveCallback); - ASSERT(driver->OnLinkStatusChanged); + /* FIXME: These probably should still be tested in some way */ + /* ASSERT(driver->OnReceiveCallback); */ + /* ASSERT(driver->OnLinkStatusChanged); */ /* Setup the dispatch table */ driver->Base.OnDeviceAdd = NetVscOnDeviceAdd; @@ -222,9 +223,9 @@ static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device) DPRINT_EXIT(NETVSC); return -1; } - ASSERT(netDevice->ReceiveBufferSize > 0); + /* ASSERT(netDevice->ReceiveBufferSize > 0); */ /* page-size grandularity */ - ASSERT((netDevice->ReceiveBufferSize & (PAGE_SIZE - 1)) == 0); + /* ASSERT((netDevice->ReceiveBufferSize & (PAGE_SIZE - 1)) == 0); */ netDevice->ReceiveBuffer = osd_PageAlloc(netDevice->ReceiveBufferSize >> PAGE_SHIFT); @@ -236,8 +237,8 @@ static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device) goto Cleanup; } /* page-aligned buffer */ - ASSERT(((unsigned long)netDevice->ReceiveBuffer & (PAGE_SIZE - 1)) == - 0); + /* ASSERT(((unsigned long)netDevice->ReceiveBuffer & (PAGE_SIZE - 1)) == */ + /* 0); */ DPRINT_INFO(NETVSC, "Establishing receive buffer's GPADL..."); @@ -294,8 +295,8 @@ static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device) } /* Parse the response */ - ASSERT(netDevice->ReceiveSectionCount == 0); - ASSERT(netDevice->ReceiveSections == NULL); + /* ASSERT(netDevice->ReceiveSectionCount == 0); */ + /* ASSERT(netDevice->ReceiveSections == NULL); */ netDevice->ReceiveSectionCount = initPacket->Messages.Version1Messages.SendReceiveBufferComplete.NumSections; @@ -355,7 +356,7 @@ static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device) } ASSERT(netDevice->SendBufferSize > 0); /* page-size grandularity */ - ASSERT((netDevice->SendBufferSize & (PAGE_SIZE - 1)) == 0); + /* ASSERT((netDevice->SendBufferSize & (PAGE_SIZE - 1)) == 0); */ netDevice->SendBuffer = osd_PageAlloc(netDevice->SendBufferSize >> PAGE_SHIFT); @@ -366,7 +367,7 @@ static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device) goto Cleanup; } /* page-aligned buffer */ - ASSERT(((unsigned long)netDevice->SendBuffer & (PAGE_SIZE - 1)) == 0); + /* ASSERT(((unsigned long)netDevice->SendBuffer & (PAGE_SIZE - 1)) == 0); */ DPRINT_INFO(NETVSC, "Establishing send buffer's GPADL..."); @@ -912,7 +913,7 @@ static void NetVscOnSendCompletion(struct hv_device *Device, NvspMessage1TypeSendRNDISPacketComplete) { /* Get the send context */ nvscPacket = (struct hv_netvsc_packet *)(unsigned long)Packet->TransactionId; - ASSERT(nvscPacket); + /* ASSERT(nvscPacket); */ /* Notify the layer above us */ nvscPacket->Completion.Send.OnSendCompletion(nvscPacket->Completion.Send.SendCompletionContext); @@ -1096,8 +1097,8 @@ static void NetVscOnReceive(struct hv_device *Device, /* This is how much we can satisfy */ xferpagePacket->Count = count - 1; - ASSERT(xferpagePacket->Count > 0 && xferpagePacket->Count <= - vmxferpagePacket->RangeCount); + /* ASSERT(xferpagePacket->Count > 0 && xferpagePacket->Count <= */ + /* vmxferpagePacket->RangeCount); */ if (xferpagePacket->Count != vmxferpagePacket->RangeCount) { DPRINT_INFO(NETVSC, "Needed %d netvsc pkts to satisy this xfer " @@ -1125,9 +1126,9 @@ static void NetVscOnReceive(struct hv_device *Device, vmxferpagePacket->Ranges[i].ByteCount; netvscPacket->PageBufferCount = 1; - ASSERT(vmxferpagePacket->Ranges[i].ByteOffset + - vmxferpagePacket->Ranges[i].ByteCount < - netDevice->ReceiveBufferSize); + /* ASSERT(vmxferpagePacket->Ranges[i].ByteOffset + */ + /* vmxferpagePacket->Ranges[i].ByteCount < */ + /* netDevice->ReceiveBufferSize); */ netvscPacket->PageBuffers[0].Length = vmxferpagePacket->Ranges[i].ByteCount; @@ -1165,7 +1166,7 @@ static void NetVscOnReceive(struct hv_device *Device, if (bytesRemain == 0) break; } - ASSERT(bytesRemain == 0); + /* ASSERT(bytesRemain == 0); */ } DPRINT_DBG(NETVSC, "[%d] - (abs offset %u len %u) => " "(pfn %llx, offset %u, len %u)", i, @@ -1181,7 +1182,7 @@ static void NetVscOnReceive(struct hv_device *Device, NetVscOnReceiveCompletion(netvscPacket->Completion.Recv.ReceiveCompletionContext); } - ASSERT(list_empty(&listHead)); + /* ASSERT(list_empty(&listHead)); */ PutNetDevice(Device); DPRINT_EXIT(NETVSC); @@ -1245,7 +1246,7 @@ static void NetVscOnReceiveCompletion(void *Context) DPRINT_ENTER(NETVSC); - ASSERT(packet->XferPagePacket); + /* ASSERT(packet->XferPagePacket); */ /* * Even though it seems logical to do a GetOutboundNetDevice() here to @@ -1263,7 +1264,7 @@ static void NetVscOnReceiveCompletion(void *Context) /* Overloading use of the lock. */ spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags); - ASSERT(packet->XferPagePacket->Count > 0); + /* ASSERT(packet->XferPagePacket->Count > 0); */ packet->XferPagePacket->Count--; /* @@ -1305,7 +1306,7 @@ static void NetVscOnChannelCallback(void *Context) DPRINT_ENTER(NETVSC); - ASSERT(device); + /* ASSERT(device); */ packet = kzalloc(NETVSC_PACKET_SIZE * sizeof(unsigned char), GFP_KERNEL); @@ -1377,8 +1378,6 @@ static void NetVscOnChannelCallback(void *Context) } bufferlen = bytesRecvd; - } else { - ASSERT(0); } } while (1); -- cgit v1.2.3 From 7a09876d2a68aab6c7a7d9df60eb0eb13467af11 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:55 -0400 Subject: staging: hv: replace ASSERT() with WARN_ON() in NetVsc.c Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/NetVsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/NetVsc.c b/drivers/staging/hv/NetVsc.c index 9863ca252bd9..ddde39136b6e 100644 --- a/drivers/staging/hv/NetVsc.c +++ b/drivers/staging/hv/NetVsc.c @@ -92,7 +92,7 @@ static struct netvsc_device *AllocNetDevice(struct hv_device *Device) static void FreeNetDevice(struct netvsc_device *Device) { - ASSERT(atomic_read(&Device->RefCount) == 0); + WARN_ON(atomic_read(&Device->RefCount) == 0); Device->Device->Extension = NULL; kfree(Device); } -- cgit v1.2.3 From 790696847dfad8b2d968ce82cc1be58ebacefead Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:56 -0400 Subject: staging: hv: remove ASSERT() and return -EINVAL in NetVsc.c return -EINVAL instead of calling ASSERT() Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/NetVsc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/NetVsc.c b/drivers/staging/hv/NetVsc.c index ddde39136b6e..f852984950a8 100644 --- a/drivers/staging/hv/NetVsc.c +++ b/drivers/staging/hv/NetVsc.c @@ -354,7 +354,11 @@ static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device) DPRINT_EXIT(NETVSC); return -1; } - ASSERT(netDevice->SendBufferSize > 0); + if (netDevice->SendBufferSize <= 0) { + ret = -EINVAL; + goto Cleanup; + } + /* page-size grandularity */ /* ASSERT((netDevice->SendBufferSize & (PAGE_SIZE - 1)) == 0); */ -- cgit v1.2.3 From e8d5373d664caacce2d7623810c91b43f08eabab Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 5 May 2010 15:27:57 -0400 Subject: staging: hv: remove ASSERT in logging.h ASSERT is no longer used in hv, so remove the define Signed-off-by: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/logging.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/logging.h b/drivers/staging/hv/logging.h index 9e55617bd670..ad4cfcfb7b11 100644 --- a/drivers/staging/hv/logging.h +++ b/drivers/staging/hv/logging.h @@ -61,13 +61,6 @@ extern unsigned int vmbus_loglevel; -#define ASSERT(expr) \ - if (!(expr)) { \ - printk(KERN_CRIT "Assertion failed! %s,%s,%s,line=%d\n", \ - #expr, __FILE__, __func__, __LINE__); \ - __asm__ __volatile__("int3"); \ - } - #define DPRINT(mod, lvl, fmt, args...) do {\ if ((mod & (HIWORD(vmbus_loglevel))) && \ (lvl <= LOWORD(vmbus_loglevel))) \ -- cgit v1.2.3 From e61fbe66cbe10fed6bcc2d07ac802a7386b93673 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 21:04:19 -0700 Subject: Staging: hv: Channel.c: fix up compiler warning In the series of ASSERT removals, somehow we ended up with a compiler warning in Channel.c. This patch fixes that up. Cc: Bill Pemberton Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Channel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/Channel.c index 158f62d8553a..eab7d16dd5ef 100644 --- a/drivers/staging/hv/Channel.c +++ b/drivers/staging/hv/Channel.c @@ -376,7 +376,7 @@ static int VmbusChannelCreateGpadlHeader(void *Kbuffer, u32 Size, struct vmbus_channel_gpadl_header *gpaHeader; struct vmbus_channel_gpadl_body *gpadlBody; struct vmbus_channel_msginfo *msgHeader; - struct vmbus_channel_msginfo *msgBody; + struct vmbus_channel_msginfo *msgBody = NULL; u32 msgSize; int pfnSum, pfnCount, pfnLeft, pfnCurr, pfnSize; -- cgit v1.2.3 From 39c4e9c37894feb1525fac4bb75e8c919042473b Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Wed, 5 May 2010 19:23:46 +0000 Subject: Staging: hv: Add Time Sync feature to hv_utils module. The Time Sync feature synchronizes guest time to host UTC time after reboot, and restore from saved/paused state. Signed-off-by: Hank Janssen Signed-off-by: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/ChannelMgmt.c | 24 ++++++++++- drivers/staging/hv/hyperv_utils.c | 84 +++++++++++++++++++++++++++++++++++++++ drivers/staging/hv/utils.h | 25 +++++++++++- 3 files changed, 130 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/ChannelMgmt.c b/drivers/staging/hv/ChannelMgmt.c index 05e6699e3c78..369823013889 100644 --- a/drivers/staging/hv/ChannelMgmt.c +++ b/drivers/staging/hv/ChannelMgmt.c @@ -33,8 +33,8 @@ struct vmbus_channel_message_table_entry { void (*messageHandler)(struct vmbus_channel_message_header *msg); }; -#define MAX_MSG_TYPES 1 -#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 5 +#define MAX_MSG_TYPES 2 +#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 6 static const struct hv_guid gSupportedDeviceClasses[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = { @@ -81,6 +81,14 @@ static const struct hv_guid 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB } }, + /* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */ + /* TimeSync */ + { + .data = { + 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, + 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf + } + }, }; @@ -191,6 +199,18 @@ struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = { .callback = chn_cb_negotiate, .log_msg = "Shutdown channel functionality initialized" }, + + /* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */ + /* TimeSync */ + { + .msg_type = HV_TIMESYNC_MSG, + .data = { + 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, + 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf + }, + .callback = chn_cb_negotiate, + .log_msg = "Timesync channel functionality initialized" + }, }; EXPORT_SYMBOL(hv_cb_utils); diff --git a/drivers/staging/hv/hyperv_utils.c b/drivers/staging/hv/hyperv_utils.c index cbebad3e40a0..9174f79a7d36 100644 --- a/drivers/staging/hv/hyperv_utils.c +++ b/drivers/staging/hv/hyperv_utils.c @@ -106,6 +106,82 @@ static void shutdown_onchannelcallback(void *context) orderly_poweroff(false); } + +/* + * Synchronize time with host after reboot, restore, etc. + */ +static void adj_guesttime(winfiletime_t hosttime, u8 flags) +{ + s64 host_tns; + struct timespec host_ts; + static s32 scnt = 50; + + host_tns = (hosttime - WLTIMEDELTA) * 100; + host_ts = ns_to_timespec(host_tns); + + if ((flags & ICTIMESYNCFLAG_SYNC) != 0) { + do_settimeofday(&host_ts); + return; + } + + if ((flags & ICTIMESYNCFLAG_SAMPLE) != 0 && + scnt > 0) { + scnt--; + do_settimeofday(&host_ts); + } + + return; +} + +/* + * Time Sync Channel message handler. + */ +static void timesync_onchannelcallback(void *context) +{ + struct vmbus_channel *channel = context; + u8 *buf; + u32 buflen, recvlen; + u64 requestid; + struct icmsg_hdr *icmsghdrp; + struct ictimesync_data *timedatap; + + DPRINT_ENTER(VMBUS); + + buflen = PAGE_SIZE; + buf = kmalloc(buflen, GFP_ATOMIC); + + VmbusChannelRecvPacket(channel, buf, buflen, &recvlen, &requestid); + + if (recvlen > 0) { + DPRINT_DBG(VMBUS, "timesync packet: recvlen=%d, requestid=%lld", + recvlen, requestid); + + icmsghdrp = (struct icmsg_hdr *)&buf[ + sizeof(struct vmbuspipe_hdr)]; + + if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { + prep_negotiate_resp(icmsghdrp, NULL, buf); + } else { + timedatap = (struct ictimesync_data *)&buf[ + sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; + adj_guesttime(timedatap->parenttime, timedatap->flags); + } + + icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION + | ICMSGHDRFLAG_RESPONSE; + + VmbusChannelSendPacket(channel, buf, + recvlen, requestid, + VmbusPacketTypeDataInBand, 0); + } + + kfree(buf); + + DPRINT_EXIT(VMBUS); +} + + static int __init init_hyperv_utils(void) { printk(KERN_INFO "Registering HyperV Utility Driver\n"); @@ -114,6 +190,10 @@ static int __init init_hyperv_utils(void) &shutdown_onchannelcallback; hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback; + hv_cb_utils[HV_TIMESYNC_MSG].channel->OnChannelCallback = + ×ync_onchannelcallback; + hv_cb_utils[HV_TIMESYNC_MSG].callback = ×ync_onchannelcallback; + return 0; } @@ -124,6 +204,10 @@ static void exit_hyperv_utils(void) hv_cb_utils[HV_SHUTDOWN_MSG].channel->OnChannelCallback = &chn_cb_negotiate; hv_cb_utils[HV_SHUTDOWN_MSG].callback = &chn_cb_negotiate; + + hv_cb_utils[HV_TIMESYNC_MSG].channel->OnChannelCallback = + &chn_cb_negotiate; + hv_cb_utils[HV_TIMESYNC_MSG].callback = &chn_cb_negotiate; } module_init(init_hyperv_utils); diff --git a/drivers/staging/hv/utils.h b/drivers/staging/hv/utils.h index e404b21e9af2..d1d2f282dd9b 100644 --- a/drivers/staging/hv/utils.h +++ b/drivers/staging/hv/utils.h @@ -75,7 +75,30 @@ struct shutdown_msg_data { u8 display_message[2048]; } __attribute__((packed)); -#define HV_SHUTDOWN_MSG 0 + +/* Time Sync IC defs */ +#define ICTIMESYNCFLAG_PROBE 0 +#define ICTIMESYNCFLAG_SYNC 1 +#define ICTIMESYNCFLAG_SAMPLE 2 + +#ifdef __x86_64__ +#define WLTIMEDELTA 116444736000000000L /* in 100ns unit */ +#else +#define WLTIMEDELTA 116444736000000000LL +#endif + +typedef u64 winfiletime_t; /* Windows FILETIME type */ + +struct ictimesync_data{ + winfiletime_t parenttime; + winfiletime_t childtime; + winfiletime_t roundtriptime; + u8 flags; +} __attribute__((packed)); + +/* Index for each IC struct in array hv_cb_utils[] */ +#define HV_SHUTDOWN_MSG 0 +#define HV_TIMESYNC_MSG 1 struct hyperv_service_callback { u8 msg_type; -- cgit v1.2.3 From 733371df3db375cb66280911162b9746b0436d68 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:00:45 -0700 Subject: Staging: hv: remove typedef that was just added. It's a u64, so use a u64, it's not some special typedef. Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hyperv_utils.c | 2 +- drivers/staging/hv/utils.h | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hyperv_utils.c b/drivers/staging/hv/hyperv_utils.c index 9174f79a7d36..d3fc33e96272 100644 --- a/drivers/staging/hv/hyperv_utils.c +++ b/drivers/staging/hv/hyperv_utils.c @@ -110,7 +110,7 @@ static void shutdown_onchannelcallback(void *context) /* * Synchronize time with host after reboot, restore, etc. */ -static void adj_guesttime(winfiletime_t hosttime, u8 flags) +static void adj_guesttime(u64 hosttime, u8 flags) { s64 host_tns; struct timespec host_ts; diff --git a/drivers/staging/hv/utils.h b/drivers/staging/hv/utils.h index d1d2f282dd9b..ecbeab69a23f 100644 --- a/drivers/staging/hv/utils.h +++ b/drivers/staging/hv/utils.h @@ -87,12 +87,10 @@ struct shutdown_msg_data { #define WLTIMEDELTA 116444736000000000LL #endif -typedef u64 winfiletime_t; /* Windows FILETIME type */ - struct ictimesync_data{ - winfiletime_t parenttime; - winfiletime_t childtime; - winfiletime_t roundtriptime; + u64 parenttime; + u64 childtime; + u64 roundtriptime; u8 flags; } __attribute__((packed)); -- cgit v1.2.3 From 25e2831dc459a45424f1dbdce7556d3ab5bc012d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:03:22 -0700 Subject: Staging: hv: util.h: fix up space mess again Again, use tabs, not spaces, it's not difficult to remember... Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/utils.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/utils.h b/drivers/staging/hv/utils.h index ecbeab69a23f..a4b9fd06e270 100644 --- a/drivers/staging/hv/utils.h +++ b/drivers/staging/hv/utils.h @@ -77,26 +77,26 @@ struct shutdown_msg_data { /* Time Sync IC defs */ -#define ICTIMESYNCFLAG_PROBE 0 -#define ICTIMESYNCFLAG_SYNC 1 -#define ICTIMESYNCFLAG_SAMPLE 2 +#define ICTIMESYNCFLAG_PROBE 0 +#define ICTIMESYNCFLAG_SYNC 1 +#define ICTIMESYNCFLAG_SAMPLE 2 #ifdef __x86_64__ -#define WLTIMEDELTA 116444736000000000L /* in 100ns unit */ +#define WLTIMEDELTA 116444736000000000L /* in 100ns unit */ #else -#define WLTIMEDELTA 116444736000000000LL +#define WLTIMEDELTA 116444736000000000LL #endif struct ictimesync_data{ - u64 parenttime; - u64 childtime; - u64 roundtriptime; - u8 flags; + u64 parenttime; + u64 childtime; + u64 roundtriptime; + u8 flags; } __attribute__((packed)); /* Index for each IC struct in array hv_cb_utils[] */ -#define HV_SHUTDOWN_MSG 0 -#define HV_TIMESYNC_MSG 1 +#define HV_SHUTDOWN_MSG 0 +#define HV_TIMESYNC_MSG 1 struct hyperv_service_callback { u8 msg_type; -- cgit v1.2.3 From d2124f293b77355669eaa880e85dd35f56ccab7e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:10:26 -0700 Subject: Staging: hv: rename hyperv_utils.c to hv_utils.c As the module only has one .c file in it, just name the file the same as the desired module. Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Makefile | 1 - drivers/staging/hv/hv_utils.c | 218 ++++++++++++++++++++++++++++++++++++++ drivers/staging/hv/hyperv_utils.c | 218 -------------------------------------- 3 files changed, 218 insertions(+), 219 deletions(-) create mode 100644 drivers/staging/hv/hv_utils.c delete mode 100644 drivers/staging/hv/hyperv_utils.c (limited to 'drivers') diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index 7a57a886ab10..1ac50833fc05 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -10,4 +10,3 @@ hv_vmbus-objs := vmbus_drv.o osd.o \ hv_storvsc-objs := storvsc_drv.o StorVsc.o hv_blkvsc-objs := blkvsc_drv.o BlkVsc.o hv_netvsc-objs := netvsc_drv.o NetVsc.o RndisFilter.o -hv_utils-objs := hyperv_utils.o diff --git a/drivers/staging/hv/hv_utils.c b/drivers/staging/hv/hv_utils.c new file mode 100644 index 000000000000..d3fc33e96272 --- /dev/null +++ b/drivers/staging/hv/hv_utils.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2010, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + */ +#include +#include +#include +#include +#include +#include + +#include "logging.h" +#include "osd.h" +#include "vmbus.h" +#include "VmbusPacketFormat.h" +#include "VmbusChannelInterface.h" +#include "VersionInfo.h" +#include "Channel.h" +#include "VmbusPrivate.h" +#include "VmbusApi.h" +#include "utils.h" + + +static void shutdown_onchannelcallback(void *context) +{ + struct vmbus_channel *channel = context; + u8 *buf; + u32 buflen, recvlen; + u64 requestid; + u8 execute_shutdown = false; + + struct shutdown_msg_data *shutdown_msg; + + struct icmsg_hdr *icmsghdrp; + struct icmsg_negotiate *negop = NULL; + + DPRINT_ENTER(VMBUS); + + buflen = PAGE_SIZE; + buf = kmalloc(buflen, GFP_ATOMIC); + + VmbusChannelRecvPacket(channel, buf, buflen, &recvlen, &requestid); + + if (recvlen > 0) { + DPRINT_DBG(VMBUS, "shutdown packet: len=%d, requestid=%lld", + recvlen, requestid); + + icmsghdrp = (struct icmsg_hdr *)&buf[ + sizeof(struct vmbuspipe_hdr)]; + + if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { + prep_negotiate_resp(icmsghdrp, negop, buf); + } else { + shutdown_msg = (struct shutdown_msg_data *)&buf[ + sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; + + switch (shutdown_msg->flags) { + case 0: + case 1: + icmsghdrp->status = HV_S_OK; + execute_shutdown = true; + + DPRINT_INFO(VMBUS, "Shutdown request received -" + " gracefull shutdown initiated"); + break; + default: + icmsghdrp->status = HV_E_FAIL; + execute_shutdown = false; + + DPRINT_INFO(VMBUS, "Shutdown request received -" + " Invalid request"); + break; + }; + } + + icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION + | ICMSGHDRFLAG_RESPONSE; + + VmbusChannelSendPacket(channel, buf, + recvlen, requestid, + VmbusPacketTypeDataInBand, 0); + } + + kfree(buf); + + DPRINT_EXIT(VMBUS); + + if (execute_shutdown == true) + orderly_poweroff(false); +} + + +/* + * Synchronize time with host after reboot, restore, etc. + */ +static void adj_guesttime(u64 hosttime, u8 flags) +{ + s64 host_tns; + struct timespec host_ts; + static s32 scnt = 50; + + host_tns = (hosttime - WLTIMEDELTA) * 100; + host_ts = ns_to_timespec(host_tns); + + if ((flags & ICTIMESYNCFLAG_SYNC) != 0) { + do_settimeofday(&host_ts); + return; + } + + if ((flags & ICTIMESYNCFLAG_SAMPLE) != 0 && + scnt > 0) { + scnt--; + do_settimeofday(&host_ts); + } + + return; +} + +/* + * Time Sync Channel message handler. + */ +static void timesync_onchannelcallback(void *context) +{ + struct vmbus_channel *channel = context; + u8 *buf; + u32 buflen, recvlen; + u64 requestid; + struct icmsg_hdr *icmsghdrp; + struct ictimesync_data *timedatap; + + DPRINT_ENTER(VMBUS); + + buflen = PAGE_SIZE; + buf = kmalloc(buflen, GFP_ATOMIC); + + VmbusChannelRecvPacket(channel, buf, buflen, &recvlen, &requestid); + + if (recvlen > 0) { + DPRINT_DBG(VMBUS, "timesync packet: recvlen=%d, requestid=%lld", + recvlen, requestid); + + icmsghdrp = (struct icmsg_hdr *)&buf[ + sizeof(struct vmbuspipe_hdr)]; + + if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { + prep_negotiate_resp(icmsghdrp, NULL, buf); + } else { + timedatap = (struct ictimesync_data *)&buf[ + sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; + adj_guesttime(timedatap->parenttime, timedatap->flags); + } + + icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION + | ICMSGHDRFLAG_RESPONSE; + + VmbusChannelSendPacket(channel, buf, + recvlen, requestid, + VmbusPacketTypeDataInBand, 0); + } + + kfree(buf); + + DPRINT_EXIT(VMBUS); +} + + +static int __init init_hyperv_utils(void) +{ + printk(KERN_INFO "Registering HyperV Utility Driver\n"); + + hv_cb_utils[HV_SHUTDOWN_MSG].channel->OnChannelCallback = + &shutdown_onchannelcallback; + hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback; + + hv_cb_utils[HV_TIMESYNC_MSG].channel->OnChannelCallback = + ×ync_onchannelcallback; + hv_cb_utils[HV_TIMESYNC_MSG].callback = ×ync_onchannelcallback; + + return 0; +} + +static void exit_hyperv_utils(void) +{ + printk(KERN_INFO "De-Registered HyperV Utility Driver\n"); + + hv_cb_utils[HV_SHUTDOWN_MSG].channel->OnChannelCallback = + &chn_cb_negotiate; + hv_cb_utils[HV_SHUTDOWN_MSG].callback = &chn_cb_negotiate; + + hv_cb_utils[HV_TIMESYNC_MSG].channel->OnChannelCallback = + &chn_cb_negotiate; + hv_cb_utils[HV_TIMESYNC_MSG].callback = &chn_cb_negotiate; +} + +module_init(init_hyperv_utils); +module_exit(exit_hyperv_utils); + +MODULE_DESCRIPTION("Hyper-V Utilities"); +MODULE_VERSION(HV_DRV_VERSION); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/hv/hyperv_utils.c b/drivers/staging/hv/hyperv_utils.c deleted file mode 100644 index d3fc33e96272..000000000000 --- a/drivers/staging/hv/hyperv_utils.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (c) 2010, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - */ -#include -#include -#include -#include -#include -#include - -#include "logging.h" -#include "osd.h" -#include "vmbus.h" -#include "VmbusPacketFormat.h" -#include "VmbusChannelInterface.h" -#include "VersionInfo.h" -#include "Channel.h" -#include "VmbusPrivate.h" -#include "VmbusApi.h" -#include "utils.h" - - -static void shutdown_onchannelcallback(void *context) -{ - struct vmbus_channel *channel = context; - u8 *buf; - u32 buflen, recvlen; - u64 requestid; - u8 execute_shutdown = false; - - struct shutdown_msg_data *shutdown_msg; - - struct icmsg_hdr *icmsghdrp; - struct icmsg_negotiate *negop = NULL; - - DPRINT_ENTER(VMBUS); - - buflen = PAGE_SIZE; - buf = kmalloc(buflen, GFP_ATOMIC); - - VmbusChannelRecvPacket(channel, buf, buflen, &recvlen, &requestid); - - if (recvlen > 0) { - DPRINT_DBG(VMBUS, "shutdown packet: len=%d, requestid=%lld", - recvlen, requestid); - - icmsghdrp = (struct icmsg_hdr *)&buf[ - sizeof(struct vmbuspipe_hdr)]; - - if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { - prep_negotiate_resp(icmsghdrp, negop, buf); - } else { - shutdown_msg = (struct shutdown_msg_data *)&buf[ - sizeof(struct vmbuspipe_hdr) + - sizeof(struct icmsg_hdr)]; - - switch (shutdown_msg->flags) { - case 0: - case 1: - icmsghdrp->status = HV_S_OK; - execute_shutdown = true; - - DPRINT_INFO(VMBUS, "Shutdown request received -" - " gracefull shutdown initiated"); - break; - default: - icmsghdrp->status = HV_E_FAIL; - execute_shutdown = false; - - DPRINT_INFO(VMBUS, "Shutdown request received -" - " Invalid request"); - break; - }; - } - - icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION - | ICMSGHDRFLAG_RESPONSE; - - VmbusChannelSendPacket(channel, buf, - recvlen, requestid, - VmbusPacketTypeDataInBand, 0); - } - - kfree(buf); - - DPRINT_EXIT(VMBUS); - - if (execute_shutdown == true) - orderly_poweroff(false); -} - - -/* - * Synchronize time with host after reboot, restore, etc. - */ -static void adj_guesttime(u64 hosttime, u8 flags) -{ - s64 host_tns; - struct timespec host_ts; - static s32 scnt = 50; - - host_tns = (hosttime - WLTIMEDELTA) * 100; - host_ts = ns_to_timespec(host_tns); - - if ((flags & ICTIMESYNCFLAG_SYNC) != 0) { - do_settimeofday(&host_ts); - return; - } - - if ((flags & ICTIMESYNCFLAG_SAMPLE) != 0 && - scnt > 0) { - scnt--; - do_settimeofday(&host_ts); - } - - return; -} - -/* - * Time Sync Channel message handler. - */ -static void timesync_onchannelcallback(void *context) -{ - struct vmbus_channel *channel = context; - u8 *buf; - u32 buflen, recvlen; - u64 requestid; - struct icmsg_hdr *icmsghdrp; - struct ictimesync_data *timedatap; - - DPRINT_ENTER(VMBUS); - - buflen = PAGE_SIZE; - buf = kmalloc(buflen, GFP_ATOMIC); - - VmbusChannelRecvPacket(channel, buf, buflen, &recvlen, &requestid); - - if (recvlen > 0) { - DPRINT_DBG(VMBUS, "timesync packet: recvlen=%d, requestid=%lld", - recvlen, requestid); - - icmsghdrp = (struct icmsg_hdr *)&buf[ - sizeof(struct vmbuspipe_hdr)]; - - if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { - prep_negotiate_resp(icmsghdrp, NULL, buf); - } else { - timedatap = (struct ictimesync_data *)&buf[ - sizeof(struct vmbuspipe_hdr) + - sizeof(struct icmsg_hdr)]; - adj_guesttime(timedatap->parenttime, timedatap->flags); - } - - icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION - | ICMSGHDRFLAG_RESPONSE; - - VmbusChannelSendPacket(channel, buf, - recvlen, requestid, - VmbusPacketTypeDataInBand, 0); - } - - kfree(buf); - - DPRINT_EXIT(VMBUS); -} - - -static int __init init_hyperv_utils(void) -{ - printk(KERN_INFO "Registering HyperV Utility Driver\n"); - - hv_cb_utils[HV_SHUTDOWN_MSG].channel->OnChannelCallback = - &shutdown_onchannelcallback; - hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback; - - hv_cb_utils[HV_TIMESYNC_MSG].channel->OnChannelCallback = - ×ync_onchannelcallback; - hv_cb_utils[HV_TIMESYNC_MSG].callback = ×ync_onchannelcallback; - - return 0; -} - -static void exit_hyperv_utils(void) -{ - printk(KERN_INFO "De-Registered HyperV Utility Driver\n"); - - hv_cb_utils[HV_SHUTDOWN_MSG].channel->OnChannelCallback = - &chn_cb_negotiate; - hv_cb_utils[HV_SHUTDOWN_MSG].callback = &chn_cb_negotiate; - - hv_cb_utils[HV_TIMESYNC_MSG].channel->OnChannelCallback = - &chn_cb_negotiate; - hv_cb_utils[HV_TIMESYNC_MSG].callback = &chn_cb_negotiate; -} - -module_init(init_hyperv_utils); -module_exit(exit_hyperv_utils); - -MODULE_DESCRIPTION("Hyper-V Utilities"); -MODULE_VERSION(HV_DRV_VERSION); -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 0d695f2b8fc8d6eaa85bd8317956a8307f9d0920 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:14:22 -0700 Subject: Staging: hv: rename Hv.c to hv.c No CamelCase in file names. Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Hv.c | 524 -------------------------------------------- drivers/staging/hv/Makefile | 2 +- drivers/staging/hv/hv.c | 524 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 525 insertions(+), 525 deletions(-) delete mode 100644 drivers/staging/hv/Hv.c create mode 100644 drivers/staging/hv/hv.c (limited to 'drivers') diff --git a/drivers/staging/hv/Hv.c b/drivers/staging/hv/Hv.c deleted file mode 100644 index 2418651772b8..000000000000 --- a/drivers/staging/hv/Hv.c +++ /dev/null @@ -1,524 +0,0 @@ -/* - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ -#include -#include -#include -#include -#include "osd.h" -#include "logging.h" -#include "VmbusPrivate.h" - -/* The one and only */ -struct hv_context gHvContext = { - .SynICInitialized = false, - .HypercallPage = NULL, - .SignalEventParam = NULL, - .SignalEventBuffer = NULL, -}; - -/* - * HvQueryHypervisorPresence - Query the cpuid for presense of windows hypervisor - */ -static int HvQueryHypervisorPresence(void) -{ - unsigned int eax; - unsigned int ebx; - unsigned int ecx; - unsigned int edx; - unsigned int op; - - eax = 0; - ebx = 0; - ecx = 0; - edx = 0; - op = HvCpuIdFunctionVersionAndFeatures; - cpuid(op, &eax, &ebx, &ecx, &edx); - - return ecx & HV_PRESENT_BIT; -} - -/* - * HvQueryHypervisorInfo - Get version info of the windows hypervisor - */ -static int HvQueryHypervisorInfo(void) -{ - unsigned int eax; - unsigned int ebx; - unsigned int ecx; - unsigned int edx; - unsigned int maxLeaf; - unsigned int op; - - /* - * Its assumed that this is called after confirming that Viridian - * is present. Query id and revision. - */ - eax = 0; - ebx = 0; - ecx = 0; - edx = 0; - op = HvCpuIdFunctionHvVendorAndMaxFunction; - cpuid(op, &eax, &ebx, &ecx, &edx); - - DPRINT_INFO(VMBUS, "Vendor ID: %c%c%c%c%c%c%c%c%c%c%c%c", - (ebx & 0xFF), - ((ebx >> 8) & 0xFF), - ((ebx >> 16) & 0xFF), - ((ebx >> 24) & 0xFF), - (ecx & 0xFF), - ((ecx >> 8) & 0xFF), - ((ecx >> 16) & 0xFF), - ((ecx >> 24) & 0xFF), - (edx & 0xFF), - ((edx >> 8) & 0xFF), - ((edx >> 16) & 0xFF), - ((edx >> 24) & 0xFF)); - - maxLeaf = eax; - eax = 0; - ebx = 0; - ecx = 0; - edx = 0; - op = HvCpuIdFunctionHvInterface; - cpuid(op, &eax, &ebx, &ecx, &edx); - - DPRINT_INFO(VMBUS, "Interface ID: %c%c%c%c", - (eax & 0xFF), - ((eax >> 8) & 0xFF), - ((eax >> 16) & 0xFF), - ((eax >> 24) & 0xFF)); - - if (maxLeaf >= HvCpuIdFunctionMsHvVersion) { - eax = 0; - ebx = 0; - ecx = 0; - edx = 0; - op = HvCpuIdFunctionMsHvVersion; - cpuid(op, &eax, &ebx, &ecx, &edx); - DPRINT_INFO(VMBUS, "OS Build:%d-%d.%d-%d-%d.%d",\ - eax, - ebx >> 16, - ebx & 0xFFFF, - ecx, - edx >> 24, - edx & 0xFFFFFF); - } - return maxLeaf; -} - -/* - * HvDoHypercall - Invoke the specified hypercall - */ -static u64 HvDoHypercall(u64 Control, void *Input, void *Output) -{ -#ifdef CONFIG_X86_64 - u64 hvStatus = 0; - u64 inputAddress = (Input) ? virt_to_phys(Input) : 0; - u64 outputAddress = (Output) ? virt_to_phys(Output) : 0; - volatile void *hypercallPage = gHvContext.HypercallPage; - - DPRINT_DBG(VMBUS, "Hypercall ", - Control, inputAddress, Input, - outputAddress, Output, hypercallPage); - - __asm__ __volatile__("mov %0, %%r8" : : "r" (outputAddress) : "r8"); - __asm__ __volatile__("call *%3" : "=a" (hvStatus) : - "c" (Control), "d" (inputAddress), - "m" (hypercallPage)); - - DPRINT_DBG(VMBUS, "Hypercall ", hvStatus); - - return hvStatus; - -#else - - u32 controlHi = Control >> 32; - u32 controlLo = Control & 0xFFFFFFFF; - u32 hvStatusHi = 1; - u32 hvStatusLo = 1; - u64 inputAddress = (Input) ? virt_to_phys(Input) : 0; - u32 inputAddressHi = inputAddress >> 32; - u32 inputAddressLo = inputAddress & 0xFFFFFFFF; - u64 outputAddress = (Output) ? virt_to_phys(Output) : 0; - u32 outputAddressHi = outputAddress >> 32; - u32 outputAddressLo = outputAddress & 0xFFFFFFFF; - volatile void *hypercallPage = gHvContext.HypercallPage; - - DPRINT_DBG(VMBUS, "Hypercall ", - Control, Input, Output); - - __asm__ __volatile__ ("call *%8" : "=d"(hvStatusHi), - "=a"(hvStatusLo) : "d" (controlHi), - "a" (controlLo), "b" (inputAddressHi), - "c" (inputAddressLo), "D"(outputAddressHi), - "S"(outputAddressLo), "m" (hypercallPage)); - - DPRINT_DBG(VMBUS, "Hypercall ", - hvStatusLo | ((u64)hvStatusHi << 32)); - - return hvStatusLo | ((u64)hvStatusHi << 32); -#endif /* !x86_64 */ -} - -/* - * HvInit - Main initialization routine. - * - * This routine must be called before any other routines in here are called - */ -int HvInit(void) -{ - int ret = 0; - int maxLeaf; - union hv_x64_msr_hypercall_contents hypercallMsr; - void *virtAddr = NULL; - - DPRINT_ENTER(VMBUS); - - memset(gHvContext.synICEventPage, 0, sizeof(void *) * MAX_NUM_CPUS); - memset(gHvContext.synICMessagePage, 0, sizeof(void *) * MAX_NUM_CPUS); - - if (!HvQueryHypervisorPresence()) { - DPRINT_ERR(VMBUS, "No Windows hypervisor detected!!"); - goto Cleanup; - } - - DPRINT_INFO(VMBUS, - "Windows hypervisor detected! Retrieving more info..."); - - maxLeaf = HvQueryHypervisorInfo(); - /* HvQueryHypervisorFeatures(maxLeaf); */ - - /* - * We only support running on top of Hyper-V - */ - rdmsrl(HV_X64_MSR_GUEST_OS_ID, gHvContext.GuestId); - - if (gHvContext.GuestId != 0) { - DPRINT_ERR(VMBUS, "Unknown guest id (0x%llx)!!", - gHvContext.GuestId); - goto Cleanup; - } - - /* Write our OS info */ - wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID); - gHvContext.GuestId = HV_LINUX_GUEST_ID; - - /* See if the hypercall page is already set */ - rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); - - /* - * Allocate the hypercall page memory - * virtAddr = osd_PageAlloc(1); - */ - virtAddr = osd_VirtualAllocExec(PAGE_SIZE); - - if (!virtAddr) { - DPRINT_ERR(VMBUS, - "unable to allocate hypercall page!!"); - goto Cleanup; - } - - hypercallMsr.Enable = 1; - - hypercallMsr.GuestPhysicalAddress = vmalloc_to_pfn(virtAddr); - wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); - - /* Confirm that hypercall page did get setup. */ - hypercallMsr.AsUINT64 = 0; - rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); - - if (!hypercallMsr.Enable) { - DPRINT_ERR(VMBUS, "unable to set hypercall page!!"); - goto Cleanup; - } - - gHvContext.HypercallPage = virtAddr; - - DPRINT_INFO(VMBUS, "Hypercall page VA=%p, PA=0x%0llx", - gHvContext.HypercallPage, - (u64)hypercallMsr.GuestPhysicalAddress << PAGE_SHIFT); - - /* Setup the global signal event param for the signal event hypercall */ - gHvContext.SignalEventBuffer = - kmalloc(sizeof(struct hv_input_signal_event_buffer), - GFP_KERNEL); - if (!gHvContext.SignalEventBuffer) - goto Cleanup; - - gHvContext.SignalEventParam = - (struct hv_input_signal_event *) - (ALIGN_UP((unsigned long)gHvContext.SignalEventBuffer, - HV_HYPERCALL_PARAM_ALIGN)); - gHvContext.SignalEventParam->ConnectionId.Asu32 = 0; - gHvContext.SignalEventParam->ConnectionId.u.Id = - VMBUS_EVENT_CONNECTION_ID; - gHvContext.SignalEventParam->FlagNumber = 0; - gHvContext.SignalEventParam->RsvdZ = 0; - - DPRINT_EXIT(VMBUS); - - return ret; - -Cleanup: - if (virtAddr) { - if (hypercallMsr.Enable) { - hypercallMsr.AsUINT64 = 0; - wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); - } - - vfree(virtAddr); - } - ret = -1; - DPRINT_EXIT(VMBUS); - - return ret; -} - -/* - * HvCleanup - Cleanup routine. - * - * This routine is called normally during driver unloading or exiting. - */ -void HvCleanup(void) -{ - union hv_x64_msr_hypercall_contents hypercallMsr; - - DPRINT_ENTER(VMBUS); - - kfree(gHvContext.SignalEventBuffer); - gHvContext.SignalEventBuffer = NULL; - gHvContext.SignalEventParam = NULL; - - if (gHvContext.HypercallPage) { - hypercallMsr.AsUINT64 = 0; - wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); - vfree(gHvContext.HypercallPage); - gHvContext.HypercallPage = NULL; - } - - DPRINT_EXIT(VMBUS); -} - -/* - * HvPostMessage - Post a message using the hypervisor message IPC. - * - * This involves a hypercall. - */ -u16 HvPostMessage(union hv_connection_id connectionId, - enum hv_message_type messageType, - void *payload, size_t payloadSize) -{ - struct alignedInput { - u64 alignment8; - struct hv_input_post_message msg; - }; - - struct hv_input_post_message *alignedMsg; - u16 status; - unsigned long addr; - - if (payloadSize > HV_MESSAGE_PAYLOAD_BYTE_COUNT) - return -1; - - addr = (unsigned long)kmalloc(sizeof(struct alignedInput), GFP_ATOMIC); - if (!addr) - return -1; - - alignedMsg = (struct hv_input_post_message *) - (ALIGN_UP(addr, HV_HYPERCALL_PARAM_ALIGN)); - - alignedMsg->ConnectionId = connectionId; - alignedMsg->MessageType = messageType; - alignedMsg->PayloadSize = payloadSize; - memcpy((void *)alignedMsg->Payload, payload, payloadSize); - - status = HvDoHypercall(HvCallPostMessage, alignedMsg, NULL) & 0xFFFF; - - kfree((void *)addr); - - return status; -} - - -/* - * HvSignalEvent - Signal an event on the specified connection using the hypervisor event IPC. - * - * This involves a hypercall. - */ -u16 HvSignalEvent(void) -{ - u16 status; - - status = HvDoHypercall(HvCallSignalEvent, gHvContext.SignalEventParam, - NULL) & 0xFFFF; - return status; -} - -/* - * HvSynicInit - Initialize the Synthethic Interrupt Controller. - * - * If it is already initialized by another entity (ie x2v shim), we need to - * retrieve the initialized message and event pages. Otherwise, we create and - * initialize the message and event pages. - */ -void HvSynicInit(void *irqarg) -{ - u64 version; - union hv_synic_simp simp; - union hv_synic_siefp siefp; - union hv_synic_sint sharedSint; - union hv_synic_scontrol sctrl; - - u32 irqVector = *((u32 *)(irqarg)); - int cpu = smp_processor_id(); - - DPRINT_ENTER(VMBUS); - - if (!gHvContext.HypercallPage) { - DPRINT_EXIT(VMBUS); - return; - } - - /* Check the version */ - rdmsrl(HV_X64_MSR_SVERSION, version); - - DPRINT_INFO(VMBUS, "SynIC version: %llx", version); - - gHvContext.synICMessagePage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC); - - if (gHvContext.synICMessagePage[cpu] == NULL) { - DPRINT_ERR(VMBUS, - "unable to allocate SYNIC message page!!"); - goto Cleanup; - } - - gHvContext.synICEventPage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC); - - if (gHvContext.synICEventPage[cpu] == NULL) { - DPRINT_ERR(VMBUS, - "unable to allocate SYNIC event page!!"); - goto Cleanup; - } - - /* Setup the Synic's message page */ - rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); - simp.SimpEnabled = 1; - simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[cpu]) - >> PAGE_SHIFT; - - DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx", simp.AsUINT64); - - wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); - - /* Setup the Synic's event page */ - rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); - siefp.SiefpEnabled = 1; - siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[cpu]) - >> PAGE_SHIFT; - - DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx", siefp.AsUINT64); - - wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); - - /* Setup the interception SINT. */ - /* wrmsrl((HV_X64_MSR_SINT0 + HV_SYNIC_INTERCEPTION_SINT_INDEX), */ - /* interceptionSint.AsUINT64); */ - - /* Setup the shared SINT. */ - rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64); - - sharedSint.AsUINT64 = 0; - sharedSint.Vector = irqVector; /* HV_SHARED_SINT_IDT_VECTOR + 0x20; */ - sharedSint.Masked = false; - sharedSint.AutoEoi = true; - - DPRINT_DBG(VMBUS, "HV_X64_MSR_SINT1 msr set to: %llx", - sharedSint.AsUINT64); - - wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64); - - /* Enable the global synic bit */ - rdmsrl(HV_X64_MSR_SCONTROL, sctrl.AsUINT64); - sctrl.Enable = 1; - - wrmsrl(HV_X64_MSR_SCONTROL, sctrl.AsUINT64); - - gHvContext.SynICInitialized = true; - - DPRINT_EXIT(VMBUS); - - return; - -Cleanup: - if (gHvContext.synICEventPage[cpu]) - osd_PageFree(gHvContext.synICEventPage[cpu], 1); - - if (gHvContext.synICMessagePage[cpu]) - osd_PageFree(gHvContext.synICMessagePage[cpu], 1); - - DPRINT_EXIT(VMBUS); - return; -} - -/* - * HvSynicCleanup - Cleanup routine for HvSynicInit(). - */ -void HvSynicCleanup(void *arg) -{ - union hv_synic_sint sharedSint; - union hv_synic_simp simp; - union hv_synic_siefp siefp; - int cpu = smp_processor_id(); - - DPRINT_ENTER(VMBUS); - - if (!gHvContext.SynICInitialized) { - DPRINT_EXIT(VMBUS); - return; - } - - rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64); - - sharedSint.Masked = 1; - - /* Need to correctly cleanup in the case of SMP!!! */ - /* Disable the interrupt */ - wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64); - - rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); - simp.SimpEnabled = 0; - simp.BaseSimpGpa = 0; - - wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); - - rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); - siefp.SiefpEnabled = 0; - siefp.BaseSiefpGpa = 0; - - wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); - - osd_PageFree(gHvContext.synICMessagePage[cpu], 1); - osd_PageFree(gHvContext.synICEventPage[cpu], 1); - - DPRINT_EXIT(VMBUS); -} diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index 1ac50833fc05..42c5069cc648 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_HYPERV_NET) += hv_netvsc.o obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o hv_vmbus-objs := vmbus_drv.o osd.o \ - Vmbus.o Hv.o Connection.o Channel.o \ + Vmbus.o hv.o Connection.o Channel.o \ ChannelMgmt.o ChannelInterface.o RingBuffer.o hv_storvsc-objs := storvsc_drv.o StorVsc.o hv_blkvsc-objs := blkvsc_drv.o BlkVsc.o diff --git a/drivers/staging/hv/hv.c b/drivers/staging/hv/hv.c new file mode 100644 index 000000000000..2418651772b8 --- /dev/null +++ b/drivers/staging/hv/hv.c @@ -0,0 +1,524 @@ +/* + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + * + */ +#include +#include +#include +#include +#include "osd.h" +#include "logging.h" +#include "VmbusPrivate.h" + +/* The one and only */ +struct hv_context gHvContext = { + .SynICInitialized = false, + .HypercallPage = NULL, + .SignalEventParam = NULL, + .SignalEventBuffer = NULL, +}; + +/* + * HvQueryHypervisorPresence - Query the cpuid for presense of windows hypervisor + */ +static int HvQueryHypervisorPresence(void) +{ + unsigned int eax; + unsigned int ebx; + unsigned int ecx; + unsigned int edx; + unsigned int op; + + eax = 0; + ebx = 0; + ecx = 0; + edx = 0; + op = HvCpuIdFunctionVersionAndFeatures; + cpuid(op, &eax, &ebx, &ecx, &edx); + + return ecx & HV_PRESENT_BIT; +} + +/* + * HvQueryHypervisorInfo - Get version info of the windows hypervisor + */ +static int HvQueryHypervisorInfo(void) +{ + unsigned int eax; + unsigned int ebx; + unsigned int ecx; + unsigned int edx; + unsigned int maxLeaf; + unsigned int op; + + /* + * Its assumed that this is called after confirming that Viridian + * is present. Query id and revision. + */ + eax = 0; + ebx = 0; + ecx = 0; + edx = 0; + op = HvCpuIdFunctionHvVendorAndMaxFunction; + cpuid(op, &eax, &ebx, &ecx, &edx); + + DPRINT_INFO(VMBUS, "Vendor ID: %c%c%c%c%c%c%c%c%c%c%c%c", + (ebx & 0xFF), + ((ebx >> 8) & 0xFF), + ((ebx >> 16) & 0xFF), + ((ebx >> 24) & 0xFF), + (ecx & 0xFF), + ((ecx >> 8) & 0xFF), + ((ecx >> 16) & 0xFF), + ((ecx >> 24) & 0xFF), + (edx & 0xFF), + ((edx >> 8) & 0xFF), + ((edx >> 16) & 0xFF), + ((edx >> 24) & 0xFF)); + + maxLeaf = eax; + eax = 0; + ebx = 0; + ecx = 0; + edx = 0; + op = HvCpuIdFunctionHvInterface; + cpuid(op, &eax, &ebx, &ecx, &edx); + + DPRINT_INFO(VMBUS, "Interface ID: %c%c%c%c", + (eax & 0xFF), + ((eax >> 8) & 0xFF), + ((eax >> 16) & 0xFF), + ((eax >> 24) & 0xFF)); + + if (maxLeaf >= HvCpuIdFunctionMsHvVersion) { + eax = 0; + ebx = 0; + ecx = 0; + edx = 0; + op = HvCpuIdFunctionMsHvVersion; + cpuid(op, &eax, &ebx, &ecx, &edx); + DPRINT_INFO(VMBUS, "OS Build:%d-%d.%d-%d-%d.%d",\ + eax, + ebx >> 16, + ebx & 0xFFFF, + ecx, + edx >> 24, + edx & 0xFFFFFF); + } + return maxLeaf; +} + +/* + * HvDoHypercall - Invoke the specified hypercall + */ +static u64 HvDoHypercall(u64 Control, void *Input, void *Output) +{ +#ifdef CONFIG_X86_64 + u64 hvStatus = 0; + u64 inputAddress = (Input) ? virt_to_phys(Input) : 0; + u64 outputAddress = (Output) ? virt_to_phys(Output) : 0; + volatile void *hypercallPage = gHvContext.HypercallPage; + + DPRINT_DBG(VMBUS, "Hypercall ", + Control, inputAddress, Input, + outputAddress, Output, hypercallPage); + + __asm__ __volatile__("mov %0, %%r8" : : "r" (outputAddress) : "r8"); + __asm__ __volatile__("call *%3" : "=a" (hvStatus) : + "c" (Control), "d" (inputAddress), + "m" (hypercallPage)); + + DPRINT_DBG(VMBUS, "Hypercall ", hvStatus); + + return hvStatus; + +#else + + u32 controlHi = Control >> 32; + u32 controlLo = Control & 0xFFFFFFFF; + u32 hvStatusHi = 1; + u32 hvStatusLo = 1; + u64 inputAddress = (Input) ? virt_to_phys(Input) : 0; + u32 inputAddressHi = inputAddress >> 32; + u32 inputAddressLo = inputAddress & 0xFFFFFFFF; + u64 outputAddress = (Output) ? virt_to_phys(Output) : 0; + u32 outputAddressHi = outputAddress >> 32; + u32 outputAddressLo = outputAddress & 0xFFFFFFFF; + volatile void *hypercallPage = gHvContext.HypercallPage; + + DPRINT_DBG(VMBUS, "Hypercall ", + Control, Input, Output); + + __asm__ __volatile__ ("call *%8" : "=d"(hvStatusHi), + "=a"(hvStatusLo) : "d" (controlHi), + "a" (controlLo), "b" (inputAddressHi), + "c" (inputAddressLo), "D"(outputAddressHi), + "S"(outputAddressLo), "m" (hypercallPage)); + + DPRINT_DBG(VMBUS, "Hypercall ", + hvStatusLo | ((u64)hvStatusHi << 32)); + + return hvStatusLo | ((u64)hvStatusHi << 32); +#endif /* !x86_64 */ +} + +/* + * HvInit - Main initialization routine. + * + * This routine must be called before any other routines in here are called + */ +int HvInit(void) +{ + int ret = 0; + int maxLeaf; + union hv_x64_msr_hypercall_contents hypercallMsr; + void *virtAddr = NULL; + + DPRINT_ENTER(VMBUS); + + memset(gHvContext.synICEventPage, 0, sizeof(void *) * MAX_NUM_CPUS); + memset(gHvContext.synICMessagePage, 0, sizeof(void *) * MAX_NUM_CPUS); + + if (!HvQueryHypervisorPresence()) { + DPRINT_ERR(VMBUS, "No Windows hypervisor detected!!"); + goto Cleanup; + } + + DPRINT_INFO(VMBUS, + "Windows hypervisor detected! Retrieving more info..."); + + maxLeaf = HvQueryHypervisorInfo(); + /* HvQueryHypervisorFeatures(maxLeaf); */ + + /* + * We only support running on top of Hyper-V + */ + rdmsrl(HV_X64_MSR_GUEST_OS_ID, gHvContext.GuestId); + + if (gHvContext.GuestId != 0) { + DPRINT_ERR(VMBUS, "Unknown guest id (0x%llx)!!", + gHvContext.GuestId); + goto Cleanup; + } + + /* Write our OS info */ + wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID); + gHvContext.GuestId = HV_LINUX_GUEST_ID; + + /* See if the hypercall page is already set */ + rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); + + /* + * Allocate the hypercall page memory + * virtAddr = osd_PageAlloc(1); + */ + virtAddr = osd_VirtualAllocExec(PAGE_SIZE); + + if (!virtAddr) { + DPRINT_ERR(VMBUS, + "unable to allocate hypercall page!!"); + goto Cleanup; + } + + hypercallMsr.Enable = 1; + + hypercallMsr.GuestPhysicalAddress = vmalloc_to_pfn(virtAddr); + wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); + + /* Confirm that hypercall page did get setup. */ + hypercallMsr.AsUINT64 = 0; + rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); + + if (!hypercallMsr.Enable) { + DPRINT_ERR(VMBUS, "unable to set hypercall page!!"); + goto Cleanup; + } + + gHvContext.HypercallPage = virtAddr; + + DPRINT_INFO(VMBUS, "Hypercall page VA=%p, PA=0x%0llx", + gHvContext.HypercallPage, + (u64)hypercallMsr.GuestPhysicalAddress << PAGE_SHIFT); + + /* Setup the global signal event param for the signal event hypercall */ + gHvContext.SignalEventBuffer = + kmalloc(sizeof(struct hv_input_signal_event_buffer), + GFP_KERNEL); + if (!gHvContext.SignalEventBuffer) + goto Cleanup; + + gHvContext.SignalEventParam = + (struct hv_input_signal_event *) + (ALIGN_UP((unsigned long)gHvContext.SignalEventBuffer, + HV_HYPERCALL_PARAM_ALIGN)); + gHvContext.SignalEventParam->ConnectionId.Asu32 = 0; + gHvContext.SignalEventParam->ConnectionId.u.Id = + VMBUS_EVENT_CONNECTION_ID; + gHvContext.SignalEventParam->FlagNumber = 0; + gHvContext.SignalEventParam->RsvdZ = 0; + + DPRINT_EXIT(VMBUS); + + return ret; + +Cleanup: + if (virtAddr) { + if (hypercallMsr.Enable) { + hypercallMsr.AsUINT64 = 0; + wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); + } + + vfree(virtAddr); + } + ret = -1; + DPRINT_EXIT(VMBUS); + + return ret; +} + +/* + * HvCleanup - Cleanup routine. + * + * This routine is called normally during driver unloading or exiting. + */ +void HvCleanup(void) +{ + union hv_x64_msr_hypercall_contents hypercallMsr; + + DPRINT_ENTER(VMBUS); + + kfree(gHvContext.SignalEventBuffer); + gHvContext.SignalEventBuffer = NULL; + gHvContext.SignalEventParam = NULL; + + if (gHvContext.HypercallPage) { + hypercallMsr.AsUINT64 = 0; + wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); + vfree(gHvContext.HypercallPage); + gHvContext.HypercallPage = NULL; + } + + DPRINT_EXIT(VMBUS); +} + +/* + * HvPostMessage - Post a message using the hypervisor message IPC. + * + * This involves a hypercall. + */ +u16 HvPostMessage(union hv_connection_id connectionId, + enum hv_message_type messageType, + void *payload, size_t payloadSize) +{ + struct alignedInput { + u64 alignment8; + struct hv_input_post_message msg; + }; + + struct hv_input_post_message *alignedMsg; + u16 status; + unsigned long addr; + + if (payloadSize > HV_MESSAGE_PAYLOAD_BYTE_COUNT) + return -1; + + addr = (unsigned long)kmalloc(sizeof(struct alignedInput), GFP_ATOMIC); + if (!addr) + return -1; + + alignedMsg = (struct hv_input_post_message *) + (ALIGN_UP(addr, HV_HYPERCALL_PARAM_ALIGN)); + + alignedMsg->ConnectionId = connectionId; + alignedMsg->MessageType = messageType; + alignedMsg->PayloadSize = payloadSize; + memcpy((void *)alignedMsg->Payload, payload, payloadSize); + + status = HvDoHypercall(HvCallPostMessage, alignedMsg, NULL) & 0xFFFF; + + kfree((void *)addr); + + return status; +} + + +/* + * HvSignalEvent - Signal an event on the specified connection using the hypervisor event IPC. + * + * This involves a hypercall. + */ +u16 HvSignalEvent(void) +{ + u16 status; + + status = HvDoHypercall(HvCallSignalEvent, gHvContext.SignalEventParam, + NULL) & 0xFFFF; + return status; +} + +/* + * HvSynicInit - Initialize the Synthethic Interrupt Controller. + * + * If it is already initialized by another entity (ie x2v shim), we need to + * retrieve the initialized message and event pages. Otherwise, we create and + * initialize the message and event pages. + */ +void HvSynicInit(void *irqarg) +{ + u64 version; + union hv_synic_simp simp; + union hv_synic_siefp siefp; + union hv_synic_sint sharedSint; + union hv_synic_scontrol sctrl; + + u32 irqVector = *((u32 *)(irqarg)); + int cpu = smp_processor_id(); + + DPRINT_ENTER(VMBUS); + + if (!gHvContext.HypercallPage) { + DPRINT_EXIT(VMBUS); + return; + } + + /* Check the version */ + rdmsrl(HV_X64_MSR_SVERSION, version); + + DPRINT_INFO(VMBUS, "SynIC version: %llx", version); + + gHvContext.synICMessagePage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC); + + if (gHvContext.synICMessagePage[cpu] == NULL) { + DPRINT_ERR(VMBUS, + "unable to allocate SYNIC message page!!"); + goto Cleanup; + } + + gHvContext.synICEventPage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC); + + if (gHvContext.synICEventPage[cpu] == NULL) { + DPRINT_ERR(VMBUS, + "unable to allocate SYNIC event page!!"); + goto Cleanup; + } + + /* Setup the Synic's message page */ + rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); + simp.SimpEnabled = 1; + simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[cpu]) + >> PAGE_SHIFT; + + DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx", simp.AsUINT64); + + wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); + + /* Setup the Synic's event page */ + rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); + siefp.SiefpEnabled = 1; + siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[cpu]) + >> PAGE_SHIFT; + + DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx", siefp.AsUINT64); + + wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); + + /* Setup the interception SINT. */ + /* wrmsrl((HV_X64_MSR_SINT0 + HV_SYNIC_INTERCEPTION_SINT_INDEX), */ + /* interceptionSint.AsUINT64); */ + + /* Setup the shared SINT. */ + rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64); + + sharedSint.AsUINT64 = 0; + sharedSint.Vector = irqVector; /* HV_SHARED_SINT_IDT_VECTOR + 0x20; */ + sharedSint.Masked = false; + sharedSint.AutoEoi = true; + + DPRINT_DBG(VMBUS, "HV_X64_MSR_SINT1 msr set to: %llx", + sharedSint.AsUINT64); + + wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64); + + /* Enable the global synic bit */ + rdmsrl(HV_X64_MSR_SCONTROL, sctrl.AsUINT64); + sctrl.Enable = 1; + + wrmsrl(HV_X64_MSR_SCONTROL, sctrl.AsUINT64); + + gHvContext.SynICInitialized = true; + + DPRINT_EXIT(VMBUS); + + return; + +Cleanup: + if (gHvContext.synICEventPage[cpu]) + osd_PageFree(gHvContext.synICEventPage[cpu], 1); + + if (gHvContext.synICMessagePage[cpu]) + osd_PageFree(gHvContext.synICMessagePage[cpu], 1); + + DPRINT_EXIT(VMBUS); + return; +} + +/* + * HvSynicCleanup - Cleanup routine for HvSynicInit(). + */ +void HvSynicCleanup(void *arg) +{ + union hv_synic_sint sharedSint; + union hv_synic_simp simp; + union hv_synic_siefp siefp; + int cpu = smp_processor_id(); + + DPRINT_ENTER(VMBUS); + + if (!gHvContext.SynICInitialized) { + DPRINT_EXIT(VMBUS); + return; + } + + rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64); + + sharedSint.Masked = 1; + + /* Need to correctly cleanup in the case of SMP!!! */ + /* Disable the interrupt */ + wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64); + + rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); + simp.SimpEnabled = 0; + simp.BaseSimpGpa = 0; + + wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); + + rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); + siefp.SiefpEnabled = 0; + siefp.BaseSiefpGpa = 0; + + wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); + + osd_PageFree(gHvContext.synICMessagePage[cpu], 1); + osd_PageFree(gHvContext.synICEventPage[cpu], 1); + + DPRINT_EXIT(VMBUS); +} -- cgit v1.2.3 From 7e8ad49f131cf9bf16b6e68237674e8f7c8dc6ca Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:16:10 -0700 Subject: Staging: hv: rename Hv.h to hv.h Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Hv.h | 140 -------------------------------------- drivers/staging/hv/VmbusPrivate.h | 2 +- drivers/staging/hv/hv.h | 140 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 141 deletions(-) delete mode 100644 drivers/staging/hv/Hv.h create mode 100644 drivers/staging/hv/hv.h (limited to 'drivers') diff --git a/drivers/staging/hv/Hv.h b/drivers/staging/hv/Hv.h deleted file mode 100644 index 41f5ebb86e17..000000000000 --- a/drivers/staging/hv/Hv.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ - - -#ifndef __HV_H__ -#define __HV_H__ - -#include "hv_api.h" - -enum { - VMBUS_MESSAGE_CONNECTION_ID = 1, - VMBUS_MESSAGE_PORT_ID = 1, - VMBUS_EVENT_CONNECTION_ID = 2, - VMBUS_EVENT_PORT_ID = 2, - VMBUS_MONITOR_CONNECTION_ID = 3, - VMBUS_MONITOR_PORT_ID = 3, - VMBUS_MESSAGE_SINT = 2, -}; - -/* #defines */ - -#define HV_PRESENT_BIT 0x80000000 - -#define HV_LINUX_GUEST_ID_LO 0x00000000 -#define HV_LINUX_GUEST_ID_HI 0xB16B00B5 -#define HV_LINUX_GUEST_ID (((u64)HV_LINUX_GUEST_ID_HI << 32) | \ - HV_LINUX_GUEST_ID_LO) - -#define HV_CPU_POWER_MANAGEMENT (1 << 0) -#define HV_RECOMMENDATIONS_MAX 4 - -#define HV_X64_MAX 5 -#define HV_CAPS_MAX 8 - - -#define HV_HYPERCALL_PARAM_ALIGN sizeof(u64) - - -/* Service definitions */ - -#define HV_SERVICE_PARENT_PORT (0) -#define HV_SERVICE_PARENT_CONNECTION (0) - -#define HV_SERVICE_CONNECT_RESPONSE_SUCCESS (0) -#define HV_SERVICE_CONNECT_RESPONSE_INVALID_PARAMETER (1) -#define HV_SERVICE_CONNECT_RESPONSE_UNKNOWN_SERVICE (2) -#define HV_SERVICE_CONNECT_RESPONSE_CONNECTION_REJECTED (3) - -#define HV_SERVICE_CONNECT_REQUEST_MESSAGE_ID (1) -#define HV_SERVICE_CONNECT_RESPONSE_MESSAGE_ID (2) -#define HV_SERVICE_DISCONNECT_REQUEST_MESSAGE_ID (3) -#define HV_SERVICE_DISCONNECT_RESPONSE_MESSAGE_ID (4) -#define HV_SERVICE_MAX_MESSAGE_ID (4) - -#define HV_SERVICE_PROTOCOL_VERSION (0x0010) -#define HV_CONNECT_PAYLOAD_BYTE_COUNT 64 - -/* #define VMBUS_REVISION_NUMBER 6 */ - -/* Our local vmbus's port and connection id. Anything >0 is fine */ -/* #define VMBUS_PORT_ID 11 */ - -/* 628180B8-308D-4c5e-B7DB-1BEB62E62EF4 */ -static const struct hv_guid VMBUS_SERVICE_ID = { - .data = { - 0xb8, 0x80, 0x81, 0x62, 0x8d, 0x30, 0x5e, 0x4c, - 0xb7, 0xdb, 0x1b, 0xeb, 0x62, 0xe6, 0x2e, 0xf4 - }, -}; - -#define MAX_NUM_CPUS 32 - - -struct hv_input_signal_event_buffer { - u64 Align8; - struct hv_input_signal_event Event; -}; - -struct hv_context { - /* We only support running on top of Hyper-V - * So at this point this really can only contain the Hyper-V ID - */ - u64 GuestId; - - void *HypercallPage; - - bool SynICInitialized; - - /* - * This is used as an input param to HvCallSignalEvent hypercall. The - * input param is immutable in our usage and must be dynamic mem (vs - * stack or global). */ - struct hv_input_signal_event_buffer *SignalEventBuffer; - /* 8-bytes aligned of the buffer above */ - struct hv_input_signal_event *SignalEventParam; - - void *synICMessagePage[MAX_NUM_CPUS]; - void *synICEventPage[MAX_NUM_CPUS]; -}; - -extern struct hv_context gHvContext; - - -/* Hv Interface */ - -extern int HvInit(void); - -extern void HvCleanup(void); - -extern u16 HvPostMessage(union hv_connection_id connectionId, - enum hv_message_type messageType, - void *payload, size_t payloadSize); - -extern u16 HvSignalEvent(void); - -extern void HvSynicInit(void *irqarg); - -extern void HvSynicCleanup(void *arg); - -#endif /* __HV_H__ */ diff --git a/drivers/staging/hv/VmbusPrivate.h b/drivers/staging/hv/VmbusPrivate.h index 05ad2c9380d5..534aa648bfd2 100644 --- a/drivers/staging/hv/VmbusPrivate.h +++ b/drivers/staging/hv/VmbusPrivate.h @@ -25,7 +25,7 @@ #ifndef _VMBUS_PRIVATE_H_ #define _VMBUS_PRIVATE_H_ -#include "Hv.h" +#include "hv.h" #include "VmbusApi.h" #include "Channel.h" #include "ChannelMgmt.h" diff --git a/drivers/staging/hv/hv.h b/drivers/staging/hv/hv.h new file mode 100644 index 000000000000..41f5ebb86e17 --- /dev/null +++ b/drivers/staging/hv/hv.h @@ -0,0 +1,140 @@ +/* + * + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + * + */ + + +#ifndef __HV_H__ +#define __HV_H__ + +#include "hv_api.h" + +enum { + VMBUS_MESSAGE_CONNECTION_ID = 1, + VMBUS_MESSAGE_PORT_ID = 1, + VMBUS_EVENT_CONNECTION_ID = 2, + VMBUS_EVENT_PORT_ID = 2, + VMBUS_MONITOR_CONNECTION_ID = 3, + VMBUS_MONITOR_PORT_ID = 3, + VMBUS_MESSAGE_SINT = 2, +}; + +/* #defines */ + +#define HV_PRESENT_BIT 0x80000000 + +#define HV_LINUX_GUEST_ID_LO 0x00000000 +#define HV_LINUX_GUEST_ID_HI 0xB16B00B5 +#define HV_LINUX_GUEST_ID (((u64)HV_LINUX_GUEST_ID_HI << 32) | \ + HV_LINUX_GUEST_ID_LO) + +#define HV_CPU_POWER_MANAGEMENT (1 << 0) +#define HV_RECOMMENDATIONS_MAX 4 + +#define HV_X64_MAX 5 +#define HV_CAPS_MAX 8 + + +#define HV_HYPERCALL_PARAM_ALIGN sizeof(u64) + + +/* Service definitions */ + +#define HV_SERVICE_PARENT_PORT (0) +#define HV_SERVICE_PARENT_CONNECTION (0) + +#define HV_SERVICE_CONNECT_RESPONSE_SUCCESS (0) +#define HV_SERVICE_CONNECT_RESPONSE_INVALID_PARAMETER (1) +#define HV_SERVICE_CONNECT_RESPONSE_UNKNOWN_SERVICE (2) +#define HV_SERVICE_CONNECT_RESPONSE_CONNECTION_REJECTED (3) + +#define HV_SERVICE_CONNECT_REQUEST_MESSAGE_ID (1) +#define HV_SERVICE_CONNECT_RESPONSE_MESSAGE_ID (2) +#define HV_SERVICE_DISCONNECT_REQUEST_MESSAGE_ID (3) +#define HV_SERVICE_DISCONNECT_RESPONSE_MESSAGE_ID (4) +#define HV_SERVICE_MAX_MESSAGE_ID (4) + +#define HV_SERVICE_PROTOCOL_VERSION (0x0010) +#define HV_CONNECT_PAYLOAD_BYTE_COUNT 64 + +/* #define VMBUS_REVISION_NUMBER 6 */ + +/* Our local vmbus's port and connection id. Anything >0 is fine */ +/* #define VMBUS_PORT_ID 11 */ + +/* 628180B8-308D-4c5e-B7DB-1BEB62E62EF4 */ +static const struct hv_guid VMBUS_SERVICE_ID = { + .data = { + 0xb8, 0x80, 0x81, 0x62, 0x8d, 0x30, 0x5e, 0x4c, + 0xb7, 0xdb, 0x1b, 0xeb, 0x62, 0xe6, 0x2e, 0xf4 + }, +}; + +#define MAX_NUM_CPUS 32 + + +struct hv_input_signal_event_buffer { + u64 Align8; + struct hv_input_signal_event Event; +}; + +struct hv_context { + /* We only support running on top of Hyper-V + * So at this point this really can only contain the Hyper-V ID + */ + u64 GuestId; + + void *HypercallPage; + + bool SynICInitialized; + + /* + * This is used as an input param to HvCallSignalEvent hypercall. The + * input param is immutable in our usage and must be dynamic mem (vs + * stack or global). */ + struct hv_input_signal_event_buffer *SignalEventBuffer; + /* 8-bytes aligned of the buffer above */ + struct hv_input_signal_event *SignalEventParam; + + void *synICMessagePage[MAX_NUM_CPUS]; + void *synICEventPage[MAX_NUM_CPUS]; +}; + +extern struct hv_context gHvContext; + + +/* Hv Interface */ + +extern int HvInit(void); + +extern void HvCleanup(void); + +extern u16 HvPostMessage(union hv_connection_id connectionId, + enum hv_message_type messageType, + void *payload, size_t payloadSize); + +extern u16 HvSignalEvent(void); + +extern void HvSynicInit(void *irqarg); + +extern void HvSynicCleanup(void *arg); + +#endif /* __HV_H__ */ -- cgit v1.2.3 From 4df90be54d9bcd2ff55d3b4c720dbab32ca6d690 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:18:38 -0700 Subject: Staging: hv: rename Channel.c and .h to channel.c and .h Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Channel.c | 1094 ------------------------------------- drivers/staging/hv/Channel.h | 112 ---- drivers/staging/hv/Makefile | 2 +- drivers/staging/hv/VmbusPrivate.h | 2 +- drivers/staging/hv/channel.c | 1094 +++++++++++++++++++++++++++++++++++++ drivers/staging/hv/channel.h | 112 ++++ drivers/staging/hv/hv_utils.c | 2 +- 7 files changed, 1209 insertions(+), 1209 deletions(-) delete mode 100644 drivers/staging/hv/Channel.c delete mode 100644 drivers/staging/hv/Channel.h create mode 100644 drivers/staging/hv/channel.c create mode 100644 drivers/staging/hv/channel.h (limited to 'drivers') diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/Channel.c deleted file mode 100644 index eab7d16dd5ef..000000000000 --- a/drivers/staging/hv/Channel.c +++ /dev/null @@ -1,1094 +0,0 @@ -/* - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - */ -#include -#include -#include -#include -#include "osd.h" -#include "logging.h" -#include "VmbusPrivate.h" - -/* Internal routines */ -static int VmbusChannelCreateGpadlHeader( - void *Kbuffer, /* must be phys and virt contiguous */ - u32 Size, /* page-size multiple */ - struct vmbus_channel_msginfo **msgInfo, - u32 *MessageCount); -static void DumpVmbusChannel(struct vmbus_channel *channel); -static void VmbusChannelSetEvent(struct vmbus_channel *channel); - - -#if 0 -static void DumpMonitorPage(struct hv_monitor_page *MonitorPage) -{ - int i = 0; - int j = 0; - - DPRINT_DBG(VMBUS, "monitorPage - %p, trigger state - %d", - MonitorPage, MonitorPage->TriggerState); - - for (i = 0; i < 4; i++) - DPRINT_DBG(VMBUS, "trigger group (%d) - %llx", i, - MonitorPage->TriggerGroup[i].AsUINT64); - - for (i = 0; i < 4; i++) { - for (j = 0; j < 32; j++) { - DPRINT_DBG(VMBUS, "latency (%d)(%d) - %llx", i, j, - MonitorPage->Latency[i][j]); - } - } - for (i = 0; i < 4; i++) { - for (j = 0; j < 32; j++) { - DPRINT_DBG(VMBUS, "param-conn id (%d)(%d) - %d", i, j, - MonitorPage->Parameter[i][j].ConnectionId.Asu32); - DPRINT_DBG(VMBUS, "param-flag (%d)(%d) - %d", i, j, - MonitorPage->Parameter[i][j].FlagNumber); - } - } -} -#endif - -/* - * VmbusChannelSetEvent - Trigger an event notification on the specified - * channel. - */ -static void VmbusChannelSetEvent(struct vmbus_channel *Channel) -{ - struct hv_monitor_page *monitorPage; - - DPRINT_ENTER(VMBUS); - - if (Channel->OfferMsg.MonitorAllocated) { - /* Each u32 represents 32 channels */ - set_bit(Channel->OfferMsg.ChildRelId & 31, - (unsigned long *) gVmbusConnection.SendInterruptPage + - (Channel->OfferMsg.ChildRelId >> 5)); - - monitorPage = gVmbusConnection.MonitorPages; - monitorPage++; /* Get the child to parent monitor page */ - - set_bit(Channel->MonitorBit, - (unsigned long *)&monitorPage->TriggerGroup - [Channel->MonitorGroup].Pending); - - } else { - VmbusSetEvent(Channel->OfferMsg.ChildRelId); - } - - DPRINT_EXIT(VMBUS); -} - -#if 0 -static void VmbusChannelClearEvent(struct vmbus_channel *channel) -{ - struct hv_monitor_page *monitorPage; - - DPRINT_ENTER(VMBUS); - - if (Channel->OfferMsg.MonitorAllocated) { - /* Each u32 represents 32 channels */ - clear_bit(Channel->OfferMsg.ChildRelId & 31, - (unsigned long *)gVmbusConnection.SendInterruptPage + - (Channel->OfferMsg.ChildRelId >> 5)); - - monitorPage = - (struct hv_monitor_page *)gVmbusConnection.MonitorPages; - monitorPage++; /* Get the child to parent monitor page */ - - clear_bit(Channel->MonitorBit, - (unsigned long *)&monitorPage->TriggerGroup - [Channel->MonitorGroup].Pending); - } - - DPRINT_EXIT(VMBUS); -} - -#endif -/* - * VmbusChannelGetDebugInfo -Retrieve various channel debug info - */ -void VmbusChannelGetDebugInfo(struct vmbus_channel *Channel, - struct vmbus_channel_debug_info *DebugInfo) -{ - struct hv_monitor_page *monitorPage; - u8 monitorGroup = (u8)Channel->OfferMsg.MonitorId / 32; - u8 monitorOffset = (u8)Channel->OfferMsg.MonitorId % 32; - /* u32 monitorBit = 1 << monitorOffset; */ - - DebugInfo->RelId = Channel->OfferMsg.ChildRelId; - DebugInfo->State = Channel->State; - memcpy(&DebugInfo->InterfaceType, - &Channel->OfferMsg.Offer.InterfaceType, sizeof(struct hv_guid)); - memcpy(&DebugInfo->InterfaceInstance, - &Channel->OfferMsg.Offer.InterfaceInstance, - sizeof(struct hv_guid)); - - monitorPage = (struct hv_monitor_page *)gVmbusConnection.MonitorPages; - - DebugInfo->MonitorId = Channel->OfferMsg.MonitorId; - - DebugInfo->ServerMonitorPending = - monitorPage->TriggerGroup[monitorGroup].Pending; - DebugInfo->ServerMonitorLatency = - monitorPage->Latency[monitorGroup][monitorOffset]; - DebugInfo->ServerMonitorConnectionId = - monitorPage->Parameter[monitorGroup] - [monitorOffset].ConnectionId.u.Id; - - monitorPage++; - - DebugInfo->ClientMonitorPending = - monitorPage->TriggerGroup[monitorGroup].Pending; - DebugInfo->ClientMonitorLatency = - monitorPage->Latency[monitorGroup][monitorOffset]; - DebugInfo->ClientMonitorConnectionId = - monitorPage->Parameter[monitorGroup] - [monitorOffset].ConnectionId.u.Id; - - RingBufferGetDebugInfo(&Channel->Inbound, &DebugInfo->Inbound); - RingBufferGetDebugInfo(&Channel->Outbound, &DebugInfo->Outbound); -} - -/* - * VmbusChannelOpen - Open the specified channel. - */ -int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, - u32 RecvRingBufferSize, void *UserData, u32 UserDataLen, - void (*OnChannelCallback)(void *context), void *Context) -{ - struct vmbus_channel_open_channel *openMsg; - struct vmbus_channel_msginfo *openInfo = NULL; - void *in, *out; - unsigned long flags; - int ret, err = 0; - - DPRINT_ENTER(VMBUS); - - /* Aligned to page size */ - /* ASSERT(!(SendRingBufferSize & (PAGE_SIZE - 1))); */ - /* ASSERT(!(RecvRingBufferSize & (PAGE_SIZE - 1))); */ - - NewChannel->OnChannelCallback = OnChannelCallback; - NewChannel->ChannelCallbackContext = Context; - - /* Allocate the ring buffer */ - out = osd_PageAlloc((SendRingBufferSize + RecvRingBufferSize) - >> PAGE_SHIFT); - if (!out) - return -ENOMEM; - - /* ASSERT(((unsigned long)out & (PAGE_SIZE-1)) == 0); */ - - in = (void *)((unsigned long)out + SendRingBufferSize); - - NewChannel->RingBufferPages = out; - NewChannel->RingBufferPageCount = (SendRingBufferSize + - RecvRingBufferSize) >> PAGE_SHIFT; - - ret = RingBufferInit(&NewChannel->Outbound, out, SendRingBufferSize); - if (!ret) { - err = ret; - goto errorout; - } - - ret = RingBufferInit(&NewChannel->Inbound, in, RecvRingBufferSize); - if (!ret) { - err = ret; - goto errorout; - } - - - /* Establish the gpadl for the ring buffer */ - DPRINT_DBG(VMBUS, "Establishing ring buffer's gpadl for channel %p...", - NewChannel); - - NewChannel->RingBufferGpadlHandle = 0; - - ret = VmbusChannelEstablishGpadl(NewChannel, - NewChannel->Outbound.RingBuffer, - SendRingBufferSize + - RecvRingBufferSize, - &NewChannel->RingBufferGpadlHandle); - - if (!ret) { - err = ret; - goto errorout; - } - - DPRINT_DBG(VMBUS, "channel %p ", - NewChannel, NewChannel->OfferMsg.ChildRelId, - NewChannel->RingBufferGpadlHandle, - NewChannel->Outbound.RingBuffer, - NewChannel->Outbound.RingSize, - NewChannel->Inbound.RingBuffer, - NewChannel->Inbound.RingSize, - SendRingBufferSize); - - /* Create and init the channel open message */ - openInfo = kmalloc(sizeof(*openInfo) + - sizeof(struct vmbus_channel_open_channel), - GFP_KERNEL); - if (!openInfo) { - err = -ENOMEM; - goto errorout; - } - - openInfo->WaitEvent = osd_WaitEventCreate(); - if (!openInfo->WaitEvent) { - err = -ENOMEM; - goto errorout; - } - - openMsg = (struct vmbus_channel_open_channel *)openInfo->Msg; - openMsg->Header.MessageType = ChannelMessageOpenChannel; - openMsg->OpenId = NewChannel->OfferMsg.ChildRelId; /* FIXME */ - openMsg->ChildRelId = NewChannel->OfferMsg.ChildRelId; - openMsg->RingBufferGpadlHandle = NewChannel->RingBufferGpadlHandle; - openMsg->DownstreamRingBufferPageOffset = SendRingBufferSize >> - PAGE_SHIFT; - openMsg->ServerContextAreaGpadlHandle = 0; /* TODO */ - - if (UserDataLen > MAX_USER_DEFINED_BYTES) { - err = -EINVAL; - goto errorout; - } - - if (UserDataLen) - memcpy(openMsg->UserData, UserData, UserDataLen); - - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); - list_add_tail(&openInfo->MsgListEntry, - &gVmbusConnection.ChannelMsgList); - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); - - DPRINT_DBG(VMBUS, "Sending channel open msg..."); - - ret = VmbusPostMessage(openMsg, - sizeof(struct vmbus_channel_open_channel)); - if (ret != 0) { - DPRINT_ERR(VMBUS, "unable to open channel - %d", ret); - goto Cleanup; - } - - /* FIXME: Need to time-out here */ - osd_WaitEventWait(openInfo->WaitEvent); - - if (openInfo->Response.OpenResult.Status == 0) - DPRINT_INFO(VMBUS, "channel <%p> open success!!", NewChannel); - else - DPRINT_INFO(VMBUS, "channel <%p> open failed - %d!!", - NewChannel, openInfo->Response.OpenResult.Status); - -Cleanup: - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); - list_del(&openInfo->MsgListEntry); - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); - - kfree(openInfo->WaitEvent); - kfree(openInfo); - - DPRINT_EXIT(VMBUS); - - return 0; - -errorout: - RingBufferCleanup(&NewChannel->Outbound); - RingBufferCleanup(&NewChannel->Inbound); - osd_PageFree(out, (SendRingBufferSize + RecvRingBufferSize) - >> PAGE_SHIFT); - kfree(openInfo); - return err; -} - -/* - * DumpGpadlBody - Dump the gpadl body message to the console for - * debugging purposes. - */ -static void DumpGpadlBody(struct vmbus_channel_gpadl_body *Gpadl, u32 Len) -{ - int i; - int pfnCount; - - pfnCount = (Len - sizeof(struct vmbus_channel_gpadl_body)) / - sizeof(u64); - DPRINT_DBG(VMBUS, "gpadl body - len %d pfn count %d", Len, pfnCount); - - for (i = 0; i < pfnCount; i++) - DPRINT_DBG(VMBUS, "gpadl body - %d) pfn %llu", - i, Gpadl->Pfn[i]); -} - -/* - * DumpGpadlHeader - Dump the gpadl header message to the console for - * debugging purposes. - */ -static void DumpGpadlHeader(struct vmbus_channel_gpadl_header *Gpadl) -{ - int i, j; - int pageCount; - - DPRINT_DBG(VMBUS, - "gpadl header - relid %d, range count %d, range buflen %d", - Gpadl->ChildRelId, Gpadl->RangeCount, Gpadl->RangeBufLen); - for (i = 0; i < Gpadl->RangeCount; i++) { - pageCount = Gpadl->Range[i].ByteCount >> PAGE_SHIFT; - pageCount = (pageCount > 26) ? 26 : pageCount; - - DPRINT_DBG(VMBUS, "gpadl range %d - len %d offset %d " - "page count %d", i, Gpadl->Range[i].ByteCount, - Gpadl->Range[i].ByteOffset, pageCount); - - for (j = 0; j < pageCount; j++) - DPRINT_DBG(VMBUS, "%d) pfn %llu", j, - Gpadl->Range[i].PfnArray[j]); - } -} - -/* - * VmbusChannelCreateGpadlHeader - Creates a gpadl for the specified buffer - */ -static int VmbusChannelCreateGpadlHeader(void *Kbuffer, u32 Size, - struct vmbus_channel_msginfo **MsgInfo, - u32 *MessageCount) -{ - int i; - int pageCount; - unsigned long long pfn; - struct vmbus_channel_gpadl_header *gpaHeader; - struct vmbus_channel_gpadl_body *gpadlBody; - struct vmbus_channel_msginfo *msgHeader; - struct vmbus_channel_msginfo *msgBody = NULL; - u32 msgSize; - - int pfnSum, pfnCount, pfnLeft, pfnCurr, pfnSize; - - /* ASSERT((kbuffer & (PAGE_SIZE-1)) == 0); */ - /* ASSERT((Size & (PAGE_SIZE-1)) == 0); */ - - pageCount = Size >> PAGE_SHIFT; - pfn = virt_to_phys(Kbuffer) >> PAGE_SHIFT; - - /* do we need a gpadl body msg */ - pfnSize = MAX_SIZE_CHANNEL_MESSAGE - - sizeof(struct vmbus_channel_gpadl_header) - - sizeof(struct gpa_range); - pfnCount = pfnSize / sizeof(u64); - - if (pageCount > pfnCount) { - /* we need a gpadl body */ - /* fill in the header */ - msgSize = sizeof(struct vmbus_channel_msginfo) + - sizeof(struct vmbus_channel_gpadl_header) + - sizeof(struct gpa_range) + pfnCount * sizeof(u64); - msgHeader = kzalloc(msgSize, GFP_KERNEL); - if (!msgHeader) - goto nomem; - - INIT_LIST_HEAD(&msgHeader->SubMsgList); - msgHeader->MessageSize = msgSize; - - gpaHeader = (struct vmbus_channel_gpadl_header *)msgHeader->Msg; - gpaHeader->RangeCount = 1; - gpaHeader->RangeBufLen = sizeof(struct gpa_range) + - pageCount * sizeof(u64); - gpaHeader->Range[0].ByteOffset = 0; - gpaHeader->Range[0].ByteCount = Size; - for (i = 0; i < pfnCount; i++) - gpaHeader->Range[0].PfnArray[i] = pfn+i; - *MsgInfo = msgHeader; - *MessageCount = 1; - - pfnSum = pfnCount; - pfnLeft = pageCount - pfnCount; - - /* how many pfns can we fit */ - pfnSize = MAX_SIZE_CHANNEL_MESSAGE - - sizeof(struct vmbus_channel_gpadl_body); - pfnCount = pfnSize / sizeof(u64); - - /* fill in the body */ - while (pfnLeft) { - if (pfnLeft > pfnCount) - pfnCurr = pfnCount; - else - pfnCurr = pfnLeft; - - msgSize = sizeof(struct vmbus_channel_msginfo) + - sizeof(struct vmbus_channel_gpadl_body) + - pfnCurr * sizeof(u64); - msgBody = kzalloc(msgSize, GFP_KERNEL); - /* FIXME: we probably need to more if this fails */ - if (!msgBody) - goto nomem; - msgBody->MessageSize = msgSize; - (*MessageCount)++; - gpadlBody = - (struct vmbus_channel_gpadl_body *)msgBody->Msg; - - /* - * FIXME: - * Gpadl is u32 and we are using a pointer which could - * be 64-bit - */ - /* gpadlBody->Gpadl = kbuffer; */ - for (i = 0; i < pfnCurr; i++) - gpadlBody->Pfn[i] = pfn + pfnSum + i; - - /* add to msg header */ - list_add_tail(&msgBody->MsgListEntry, - &msgHeader->SubMsgList); - pfnSum += pfnCurr; - pfnLeft -= pfnCurr; - } - } else { - /* everything fits in a header */ - msgSize = sizeof(struct vmbus_channel_msginfo) + - sizeof(struct vmbus_channel_gpadl_header) + - sizeof(struct gpa_range) + pageCount * sizeof(u64); - msgHeader = kzalloc(msgSize, GFP_KERNEL); - msgHeader->MessageSize = msgSize; - - gpaHeader = (struct vmbus_channel_gpadl_header *)msgHeader->Msg; - gpaHeader->RangeCount = 1; - gpaHeader->RangeBufLen = sizeof(struct gpa_range) + - pageCount * sizeof(u64); - gpaHeader->Range[0].ByteOffset = 0; - gpaHeader->Range[0].ByteCount = Size; - for (i = 0; i < pageCount; i++) - gpaHeader->Range[0].PfnArray[i] = pfn+i; - - *MsgInfo = msgHeader; - *MessageCount = 1; - } - - return 0; -nomem: - kfree(msgHeader); - kfree(msgBody); - return -ENOMEM; -} - -/* - * VmbusChannelEstablishGpadl - Estabish a GPADL for the specified buffer - * - * @Channel: a channel - * @Kbuffer: from kmalloc - * @Size: page-size multiple - * @GpadlHandle: some funky thing - */ -int VmbusChannelEstablishGpadl(struct vmbus_channel *Channel, void *Kbuffer, - u32 Size, u32 *GpadlHandle) -{ - struct vmbus_channel_gpadl_header *gpadlMsg; - struct vmbus_channel_gpadl_body *gpadlBody; - /* struct vmbus_channel_gpadl_created *gpadlCreated; */ - struct vmbus_channel_msginfo *msgInfo = NULL; - struct vmbus_channel_msginfo *subMsgInfo; - u32 msgCount; - struct list_head *curr; - u32 nextGpadlHandle; - unsigned long flags; - int ret = 0; - - DPRINT_ENTER(VMBUS); - - nextGpadlHandle = atomic_read(&gVmbusConnection.NextGpadlHandle); - atomic_inc(&gVmbusConnection.NextGpadlHandle); - - ret = VmbusChannelCreateGpadlHeader(Kbuffer, Size, &msgInfo, &msgCount); - if (ret) - return ret; - - msgInfo->WaitEvent = osd_WaitEventCreate(); - if (!msgInfo->WaitEvent) { - ret = -ENOMEM; - goto Cleanup; - } - - gpadlMsg = (struct vmbus_channel_gpadl_header *)msgInfo->Msg; - gpadlMsg->Header.MessageType = ChannelMessageGpadlHeader; - gpadlMsg->ChildRelId = Channel->OfferMsg.ChildRelId; - gpadlMsg->Gpadl = nextGpadlHandle; - - DumpGpadlHeader(gpadlMsg); - - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); - list_add_tail(&msgInfo->MsgListEntry, - &gVmbusConnection.ChannelMsgList); - - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); - DPRINT_DBG(VMBUS, "buffer %p, size %d msg cnt %d", - Kbuffer, Size, msgCount); - - DPRINT_DBG(VMBUS, "Sending GPADL Header - len %zd", - msgInfo->MessageSize - sizeof(*msgInfo)); - - ret = VmbusPostMessage(gpadlMsg, msgInfo->MessageSize - - sizeof(*msgInfo)); - if (ret != 0) { - DPRINT_ERR(VMBUS, "Unable to open channel - %d", ret); - goto Cleanup; - } - - if (msgCount > 1) { - list_for_each(curr, &msgInfo->SubMsgList) { - - /* FIXME: should this use list_entry() instead ? */ - subMsgInfo = (struct vmbus_channel_msginfo *)curr; - gpadlBody = - (struct vmbus_channel_gpadl_body *)subMsgInfo->Msg; - - gpadlBody->Header.MessageType = ChannelMessageGpadlBody; - gpadlBody->Gpadl = nextGpadlHandle; - - DPRINT_DBG(VMBUS, "Sending GPADL Body - len %zd", - subMsgInfo->MessageSize - - sizeof(*subMsgInfo)); - - DumpGpadlBody(gpadlBody, subMsgInfo->MessageSize - - sizeof(*subMsgInfo)); - ret = VmbusPostMessage(gpadlBody, - subMsgInfo->MessageSize - - sizeof(*subMsgInfo)); - if (!ret) - goto Cleanup; - - } - } - osd_WaitEventWait(msgInfo->WaitEvent); - - /* At this point, we received the gpadl created msg */ - DPRINT_DBG(VMBUS, "Received GPADL created " - "(relid %d, status %d handle %x)", - Channel->OfferMsg.ChildRelId, - msgInfo->Response.GpadlCreated.CreationStatus, - gpadlMsg->Gpadl); - - *GpadlHandle = gpadlMsg->Gpadl; - -Cleanup: - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); - list_del(&msgInfo->MsgListEntry); - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); - - kfree(msgInfo->WaitEvent); - kfree(msgInfo); - - DPRINT_EXIT(VMBUS); - - return ret; -} - -/* - * VmbusChannelTeardownGpadl -Teardown the specified GPADL handle - */ -int VmbusChannelTeardownGpadl(struct vmbus_channel *Channel, u32 GpadlHandle) -{ - struct vmbus_channel_gpadl_teardown *msg; - struct vmbus_channel_msginfo *info; - unsigned long flags; - int ret; - - DPRINT_ENTER(VMBUS); - - /* ASSERT(GpadlHandle != 0); */ - - info = kmalloc(sizeof(*info) + - sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL); - if (!info) - return -ENOMEM; - - info->WaitEvent = osd_WaitEventCreate(); - if (!info->WaitEvent) { - kfree(info); - return -ENOMEM; - } - - msg = (struct vmbus_channel_gpadl_teardown *)info->Msg; - - msg->Header.MessageType = ChannelMessageGpadlTeardown; - msg->ChildRelId = Channel->OfferMsg.ChildRelId; - msg->Gpadl = GpadlHandle; - - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); - list_add_tail(&info->MsgListEntry, - &gVmbusConnection.ChannelMsgList); - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); - - ret = VmbusPostMessage(msg, - sizeof(struct vmbus_channel_gpadl_teardown)); - if (ret != 0) { - /* TODO: */ - /* something... */ - } - - osd_WaitEventWait(info->WaitEvent); - - /* Received a torndown response */ - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); - list_del(&info->MsgListEntry); - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); - - kfree(info->WaitEvent); - kfree(info); - - DPRINT_EXIT(VMBUS); - - return ret; -} - -/* - * VmbusChannelClose - Close the specified channel - */ -void VmbusChannelClose(struct vmbus_channel *Channel) -{ - struct vmbus_channel_close_channel *msg; - struct vmbus_channel_msginfo *info; - unsigned long flags; - int ret; - - DPRINT_ENTER(VMBUS); - - /* Stop callback and cancel the timer asap */ - Channel->OnChannelCallback = NULL; - del_timer_sync(&Channel->poll_timer); - - /* Send a closing message */ - info = kmalloc(sizeof(*info) + - sizeof(struct vmbus_channel_close_channel), GFP_KERNEL); - /* FIXME: can't do anything other than return here because the - * function is void */ - if (!info) - return; - - /* info->waitEvent = osd_WaitEventCreate(); */ - - msg = (struct vmbus_channel_close_channel *)info->Msg; - msg->Header.MessageType = ChannelMessageCloseChannel; - msg->ChildRelId = Channel->OfferMsg.ChildRelId; - - ret = VmbusPostMessage(msg, sizeof(struct vmbus_channel_close_channel)); - if (ret != 0) { - /* TODO: */ - /* something... */ - } - - /* Tear down the gpadl for the channel's ring buffer */ - if (Channel->RingBufferGpadlHandle) - VmbusChannelTeardownGpadl(Channel, - Channel->RingBufferGpadlHandle); - - /* TODO: Send a msg to release the childRelId */ - - /* Cleanup the ring buffers for this channel */ - RingBufferCleanup(&Channel->Outbound); - RingBufferCleanup(&Channel->Inbound); - - osd_PageFree(Channel->RingBufferPages, Channel->RingBufferPageCount); - - kfree(info); - - /* - * If we are closing the channel during an error path in - * opening the channel, don't free the channel since the - * caller will free the channel - */ - - if (Channel->State == CHANNEL_OPEN_STATE) { - spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); - list_del(&Channel->ListEntry); - spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); - - FreeVmbusChannel(Channel); - } - - DPRINT_EXIT(VMBUS); -} - -/** - * VmbusChannelSendPacket() - Send the specified buffer on the given channel - * @Channel: Pointer to vmbus_channel structure. - * @Buffer: Pointer to the buffer you want to receive the data into. - * @BufferLen: Maximum size of what the the buffer will hold - * @RequestId: Identifier of the request - * @vmbus_packet_type: Type of packet that is being send e.g. negotiate, time - * packet etc. - * - * Sends data in @Buffer directly to hyper-v via the vmbus - * This will send the data unparsed to hyper-v. - * - * Mainly used by Hyper-V drivers. - */ -int VmbusChannelSendPacket(struct vmbus_channel *Channel, const void *Buffer, - u32 BufferLen, u64 RequestId, - enum vmbus_packet_type Type, u32 Flags) -{ - struct vmpacket_descriptor desc; - u32 packetLen = sizeof(struct vmpacket_descriptor) + BufferLen; - u32 packetLenAligned = ALIGN_UP(packetLen, sizeof(u64)); - struct scatterlist bufferList[3]; - u64 alignedData = 0; - int ret; - - DPRINT_ENTER(VMBUS); - DPRINT_DBG(VMBUS, "channel %p buffer %p len %d", - Channel, Buffer, BufferLen); - - DumpVmbusChannel(Channel); - - /* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */ - - /* Setup the descriptor */ - desc.Type = Type; /* VmbusPacketTypeDataInBand; */ - desc.Flags = Flags; /* VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; */ - /* in 8-bytes granularity */ - desc.DataOffset8 = sizeof(struct vmpacket_descriptor) >> 3; - desc.Length8 = (u16)(packetLenAligned >> 3); - desc.TransactionId = RequestId; - - sg_init_table(bufferList, 3); - sg_set_buf(&bufferList[0], &desc, sizeof(struct vmpacket_descriptor)); - sg_set_buf(&bufferList[1], Buffer, BufferLen); - sg_set_buf(&bufferList[2], &alignedData, packetLenAligned - packetLen); - - ret = RingBufferWrite(&Channel->Outbound, bufferList, 3); - - /* TODO: We should determine if this is optional */ - if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound)) - VmbusChannelSetEvent(Channel); - - DPRINT_EXIT(VMBUS); - - return ret; -} -EXPORT_SYMBOL(VmbusChannelSendPacket); - -/* - * VmbusChannelSendPacketPageBuffer - Send a range of single-page buffer - * packets using a GPADL Direct packet type. - */ -int VmbusChannelSendPacketPageBuffer(struct vmbus_channel *Channel, - struct hv_page_buffer PageBuffers[], - u32 PageCount, void *Buffer, u32 BufferLen, - u64 RequestId) -{ - int ret; - int i; - struct VMBUS_CHANNEL_PACKET_PAGE_BUFFER desc; - u32 descSize; - u32 packetLen; - u32 packetLenAligned; - struct scatterlist bufferList[3]; - u64 alignedData = 0; - - DPRINT_ENTER(VMBUS); - - if (PageCount > MAX_PAGE_BUFFER_COUNT) - return -EINVAL; - - DumpVmbusChannel(Channel); - - /* - * Adjust the size down since VMBUS_CHANNEL_PACKET_PAGE_BUFFER is the - * largest size we support - */ - descSize = sizeof(struct VMBUS_CHANNEL_PACKET_PAGE_BUFFER) - - ((MAX_PAGE_BUFFER_COUNT - PageCount) * - sizeof(struct hv_page_buffer)); - packetLen = descSize + BufferLen; - packetLenAligned = ALIGN_UP(packetLen, sizeof(u64)); - - /* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */ - - /* Setup the descriptor */ - desc.Type = VmbusPacketTypeDataUsingGpaDirect; - desc.Flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; - desc.DataOffset8 = descSize >> 3; /* in 8-bytes grandularity */ - desc.Length8 = (u16)(packetLenAligned >> 3); - desc.TransactionId = RequestId; - desc.RangeCount = PageCount; - - for (i = 0; i < PageCount; i++) { - desc.Range[i].Length = PageBuffers[i].Length; - desc.Range[i].Offset = PageBuffers[i].Offset; - desc.Range[i].Pfn = PageBuffers[i].Pfn; - } - - sg_init_table(bufferList, 3); - sg_set_buf(&bufferList[0], &desc, descSize); - sg_set_buf(&bufferList[1], Buffer, BufferLen); - sg_set_buf(&bufferList[2], &alignedData, packetLenAligned - packetLen); - - ret = RingBufferWrite(&Channel->Outbound, bufferList, 3); - - /* TODO: We should determine if this is optional */ - if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound)) - VmbusChannelSetEvent(Channel); - - DPRINT_EXIT(VMBUS); - - return ret; -} - -/* - * VmbusChannelSendPacketMultiPageBuffer - Send a multi-page buffer packet - * using a GPADL Direct packet type. - */ -int VmbusChannelSendPacketMultiPageBuffer(struct vmbus_channel *Channel, - struct hv_multipage_buffer *MultiPageBuffer, - void *Buffer, u32 BufferLen, u64 RequestId) -{ - int ret; - struct VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER desc; - u32 descSize; - u32 packetLen; - u32 packetLenAligned; - struct scatterlist bufferList[3]; - u64 alignedData = 0; - u32 PfnCount = NUM_PAGES_SPANNED(MultiPageBuffer->Offset, - MultiPageBuffer->Length); - - DPRINT_ENTER(VMBUS); - - DumpVmbusChannel(Channel); - - DPRINT_DBG(VMBUS, "data buffer - offset %u len %u pfn count %u", - MultiPageBuffer->Offset, MultiPageBuffer->Length, PfnCount); - - if ((PfnCount < 0) || (PfnCount > MAX_MULTIPAGE_BUFFER_COUNT)) - return -EINVAL; - - /* - * Adjust the size down since VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER is - * the largest size we support - */ - descSize = sizeof(struct VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER) - - ((MAX_MULTIPAGE_BUFFER_COUNT - PfnCount) * - sizeof(u64)); - packetLen = descSize + BufferLen; - packetLenAligned = ALIGN_UP(packetLen, sizeof(u64)); - - /* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */ - - /* Setup the descriptor */ - desc.Type = VmbusPacketTypeDataUsingGpaDirect; - desc.Flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; - desc.DataOffset8 = descSize >> 3; /* in 8-bytes grandularity */ - desc.Length8 = (u16)(packetLenAligned >> 3); - desc.TransactionId = RequestId; - desc.RangeCount = 1; - - desc.Range.Length = MultiPageBuffer->Length; - desc.Range.Offset = MultiPageBuffer->Offset; - - memcpy(desc.Range.PfnArray, MultiPageBuffer->PfnArray, - PfnCount * sizeof(u64)); - - sg_init_table(bufferList, 3); - sg_set_buf(&bufferList[0], &desc, descSize); - sg_set_buf(&bufferList[1], Buffer, BufferLen); - sg_set_buf(&bufferList[2], &alignedData, packetLenAligned - packetLen); - - ret = RingBufferWrite(&Channel->Outbound, bufferList, 3); - - /* TODO: We should determine if this is optional */ - if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound)) - VmbusChannelSetEvent(Channel); - - DPRINT_EXIT(VMBUS); - - return ret; -} - - -/** - * VmbusChannelRecvPacket() - Retrieve the user packet on the specified channel - * @Channel: Pointer to vmbus_channel structure. - * @Buffer: Pointer to the buffer you want to receive the data into. - * @BufferLen: Maximum size of what the the buffer will hold - * @BufferActualLen: The actual size of the data after it was received - * @RequestId: Identifier of the request - * - * Receives directly from the hyper-v vmbus and puts the data it received - * into Buffer. This will receive the data unparsed from hyper-v. - * - * Mainly used by Hyper-V drivers. - */ -int VmbusChannelRecvPacket(struct vmbus_channel *Channel, void *Buffer, - u32 BufferLen, u32 *BufferActualLen, u64 *RequestId) -{ - struct vmpacket_descriptor desc; - u32 packetLen; - u32 userLen; - int ret; - unsigned long flags; - - DPRINT_ENTER(VMBUS); - - *BufferActualLen = 0; - *RequestId = 0; - - spin_lock_irqsave(&Channel->inbound_lock, flags); - - ret = RingBufferPeek(&Channel->Inbound, &desc, - sizeof(struct vmpacket_descriptor)); - if (ret != 0) { - spin_unlock_irqrestore(&Channel->inbound_lock, flags); - - /* DPRINT_DBG(VMBUS, "nothing to read!!"); */ - DPRINT_EXIT(VMBUS); - return 0; - } - - /* VmbusChannelClearEvent(Channel); */ - - packetLen = desc.Length8 << 3; - userLen = packetLen - (desc.DataOffset8 << 3); - /* ASSERT(userLen > 0); */ - - DPRINT_DBG(VMBUS, "packet received on channel %p relid %d ", - Channel, Channel->OfferMsg.ChildRelId, desc.Type, - desc.Flags, desc.TransactionId, packetLen, userLen); - - *BufferActualLen = userLen; - - if (userLen > BufferLen) { - spin_unlock_irqrestore(&Channel->inbound_lock, flags); - - DPRINT_ERR(VMBUS, "buffer too small - got %d needs %d", - BufferLen, userLen); - DPRINT_EXIT(VMBUS); - - return -1; - } - - *RequestId = desc.TransactionId; - - /* Copy over the packet to the user buffer */ - ret = RingBufferRead(&Channel->Inbound, Buffer, userLen, - (desc.DataOffset8 << 3)); - - spin_unlock_irqrestore(&Channel->inbound_lock, flags); - - DPRINT_EXIT(VMBUS); - - return 0; -} -EXPORT_SYMBOL(VmbusChannelRecvPacket); - -/* - * VmbusChannelRecvPacketRaw - Retrieve the raw packet on the specified channel - */ -int VmbusChannelRecvPacketRaw(struct vmbus_channel *Channel, void *Buffer, - u32 BufferLen, u32 *BufferActualLen, - u64 *RequestId) -{ - struct vmpacket_descriptor desc; - u32 packetLen; - u32 userLen; - int ret; - unsigned long flags; - - DPRINT_ENTER(VMBUS); - - *BufferActualLen = 0; - *RequestId = 0; - - spin_lock_irqsave(&Channel->inbound_lock, flags); - - ret = RingBufferPeek(&Channel->Inbound, &desc, - sizeof(struct vmpacket_descriptor)); - if (ret != 0) { - spin_unlock_irqrestore(&Channel->inbound_lock, flags); - - /* DPRINT_DBG(VMBUS, "nothing to read!!"); */ - DPRINT_EXIT(VMBUS); - return 0; - } - - /* VmbusChannelClearEvent(Channel); */ - - packetLen = desc.Length8 << 3; - userLen = packetLen - (desc.DataOffset8 << 3); - - DPRINT_DBG(VMBUS, "packet received on channel %p relid %d ", - Channel, Channel->OfferMsg.ChildRelId, desc.Type, - desc.Flags, desc.TransactionId, packetLen, userLen); - - *BufferActualLen = packetLen; - - if (packetLen > BufferLen) { - spin_unlock_irqrestore(&Channel->inbound_lock, flags); - - DPRINT_ERR(VMBUS, "buffer too small - needed %d bytes but " - "got space for only %d bytes", packetLen, BufferLen); - DPRINT_EXIT(VMBUS); - return -2; - } - - *RequestId = desc.TransactionId; - - /* Copy over the entire packet to the user buffer */ - ret = RingBufferRead(&Channel->Inbound, Buffer, packetLen, 0); - - spin_unlock_irqrestore(&Channel->inbound_lock, flags); - - DPRINT_EXIT(VMBUS); - - return 0; -} - -/* - * VmbusChannelOnChannelEvent - Channel event callback - */ -void VmbusChannelOnChannelEvent(struct vmbus_channel *Channel) -{ - DumpVmbusChannel(Channel); - /* ASSERT(Channel->OnChannelCallback); */ - - Channel->OnChannelCallback(Channel->ChannelCallbackContext); - - mod_timer(&Channel->poll_timer, jiffies + usecs_to_jiffies(100)); -} - -/* - * VmbusChannelOnTimer - Timer event callback - */ -void VmbusChannelOnTimer(unsigned long data) -{ - struct vmbus_channel *channel = (struct vmbus_channel *)data; - - if (channel->OnChannelCallback) - channel->OnChannelCallback(channel->ChannelCallbackContext); -} - -/* - * DumpVmbusChannel - Dump vmbus channel info to the console - */ -static void DumpVmbusChannel(struct vmbus_channel *Channel) -{ - DPRINT_DBG(VMBUS, "Channel (%d)", Channel->OfferMsg.ChildRelId); - DumpRingInfo(&Channel->Outbound, "Outbound "); - DumpRingInfo(&Channel->Inbound, "Inbound "); -} diff --git a/drivers/staging/hv/Channel.h b/drivers/staging/hv/Channel.h deleted file mode 100644 index 6b283edcae68..000000000000 --- a/drivers/staging/hv/Channel.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ - - -#ifndef _CHANNEL_H_ -#define _CHANNEL_H_ - -#include "ChannelMgmt.h" - -/* The format must be the same as struct vmdata_gpa_direct */ -struct VMBUS_CHANNEL_PACKET_PAGE_BUFFER { - u16 Type; - u16 DataOffset8; - u16 Length8; - u16 Flags; - u64 TransactionId; - u32 Reserved; - u32 RangeCount; - struct hv_page_buffer Range[MAX_PAGE_BUFFER_COUNT]; -} __attribute__((packed)); - -/* The format must be the same as struct vmdata_gpa_direct */ -struct VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER { - u16 Type; - u16 DataOffset8; - u16 Length8; - u16 Flags; - u64 TransactionId; - u32 Reserved; - u32 RangeCount; /* Always 1 in this case */ - struct hv_multipage_buffer Range; -} __attribute__((packed)); - - -extern int VmbusChannelOpen(struct vmbus_channel *channel, - u32 SendRingBufferSize, - u32 RecvRingBufferSize, - void *UserData, - u32 UserDataLen, - void(*OnChannelCallback)(void *context), - void *Context); - -extern void VmbusChannelClose(struct vmbus_channel *channel); - -extern int VmbusChannelSendPacket(struct vmbus_channel *channel, - const void *Buffer, - u32 BufferLen, - u64 RequestId, - enum vmbus_packet_type Type, - u32 Flags); - -extern int VmbusChannelSendPacketPageBuffer(struct vmbus_channel *channel, - struct hv_page_buffer PageBuffers[], - u32 PageCount, - void *Buffer, - u32 BufferLen, - u64 RequestId); - -extern int VmbusChannelSendPacketMultiPageBuffer(struct vmbus_channel *channel, - struct hv_multipage_buffer *mpb, - void *Buffer, - u32 BufferLen, - u64 RequestId); - -extern int VmbusChannelEstablishGpadl(struct vmbus_channel *channel, - void *Kbuffer, - u32 Size, - u32 *GpadlHandle); - -extern int VmbusChannelTeardownGpadl(struct vmbus_channel *channel, - u32 GpadlHandle); - -extern int VmbusChannelRecvPacket(struct vmbus_channel *channel, - void *Buffer, - u32 BufferLen, - u32 *BufferActualLen, - u64 *RequestId); - -extern int VmbusChannelRecvPacketRaw(struct vmbus_channel *channel, - void *Buffer, - u32 BufferLen, - u32 *BufferActualLen, - u64 *RequestId); - -extern void VmbusChannelOnChannelEvent(struct vmbus_channel *channel); - -extern void VmbusChannelGetDebugInfo(struct vmbus_channel *channel, - struct vmbus_channel_debug_info *debug); - -extern void VmbusChannelOnTimer(unsigned long data); - -#endif /* _CHANNEL_H_ */ diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index 42c5069cc648..3c15c731f96d 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_HYPERV_NET) += hv_netvsc.o obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o hv_vmbus-objs := vmbus_drv.o osd.o \ - Vmbus.o hv.o Connection.o Channel.o \ + Vmbus.o hv.o Connection.o channel.o \ ChannelMgmt.o ChannelInterface.o RingBuffer.o hv_storvsc-objs := storvsc_drv.o StorVsc.o hv_blkvsc-objs := blkvsc_drv.o BlkVsc.o diff --git a/drivers/staging/hv/VmbusPrivate.h b/drivers/staging/hv/VmbusPrivate.h index 534aa648bfd2..f03db0b6e887 100644 --- a/drivers/staging/hv/VmbusPrivate.h +++ b/drivers/staging/hv/VmbusPrivate.h @@ -27,7 +27,7 @@ #include "hv.h" #include "VmbusApi.h" -#include "Channel.h" +#include "channel.h" #include "ChannelMgmt.h" #include "ChannelInterface.h" #include "RingBuffer.h" diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c new file mode 100644 index 000000000000..eab7d16dd5ef --- /dev/null +++ b/drivers/staging/hv/channel.c @@ -0,0 +1,1094 @@ +/* + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + */ +#include +#include +#include +#include +#include "osd.h" +#include "logging.h" +#include "VmbusPrivate.h" + +/* Internal routines */ +static int VmbusChannelCreateGpadlHeader( + void *Kbuffer, /* must be phys and virt contiguous */ + u32 Size, /* page-size multiple */ + struct vmbus_channel_msginfo **msgInfo, + u32 *MessageCount); +static void DumpVmbusChannel(struct vmbus_channel *channel); +static void VmbusChannelSetEvent(struct vmbus_channel *channel); + + +#if 0 +static void DumpMonitorPage(struct hv_monitor_page *MonitorPage) +{ + int i = 0; + int j = 0; + + DPRINT_DBG(VMBUS, "monitorPage - %p, trigger state - %d", + MonitorPage, MonitorPage->TriggerState); + + for (i = 0; i < 4; i++) + DPRINT_DBG(VMBUS, "trigger group (%d) - %llx", i, + MonitorPage->TriggerGroup[i].AsUINT64); + + for (i = 0; i < 4; i++) { + for (j = 0; j < 32; j++) { + DPRINT_DBG(VMBUS, "latency (%d)(%d) - %llx", i, j, + MonitorPage->Latency[i][j]); + } + } + for (i = 0; i < 4; i++) { + for (j = 0; j < 32; j++) { + DPRINT_DBG(VMBUS, "param-conn id (%d)(%d) - %d", i, j, + MonitorPage->Parameter[i][j].ConnectionId.Asu32); + DPRINT_DBG(VMBUS, "param-flag (%d)(%d) - %d", i, j, + MonitorPage->Parameter[i][j].FlagNumber); + } + } +} +#endif + +/* + * VmbusChannelSetEvent - Trigger an event notification on the specified + * channel. + */ +static void VmbusChannelSetEvent(struct vmbus_channel *Channel) +{ + struct hv_monitor_page *monitorPage; + + DPRINT_ENTER(VMBUS); + + if (Channel->OfferMsg.MonitorAllocated) { + /* Each u32 represents 32 channels */ + set_bit(Channel->OfferMsg.ChildRelId & 31, + (unsigned long *) gVmbusConnection.SendInterruptPage + + (Channel->OfferMsg.ChildRelId >> 5)); + + monitorPage = gVmbusConnection.MonitorPages; + monitorPage++; /* Get the child to parent monitor page */ + + set_bit(Channel->MonitorBit, + (unsigned long *)&monitorPage->TriggerGroup + [Channel->MonitorGroup].Pending); + + } else { + VmbusSetEvent(Channel->OfferMsg.ChildRelId); + } + + DPRINT_EXIT(VMBUS); +} + +#if 0 +static void VmbusChannelClearEvent(struct vmbus_channel *channel) +{ + struct hv_monitor_page *monitorPage; + + DPRINT_ENTER(VMBUS); + + if (Channel->OfferMsg.MonitorAllocated) { + /* Each u32 represents 32 channels */ + clear_bit(Channel->OfferMsg.ChildRelId & 31, + (unsigned long *)gVmbusConnection.SendInterruptPage + + (Channel->OfferMsg.ChildRelId >> 5)); + + monitorPage = + (struct hv_monitor_page *)gVmbusConnection.MonitorPages; + monitorPage++; /* Get the child to parent monitor page */ + + clear_bit(Channel->MonitorBit, + (unsigned long *)&monitorPage->TriggerGroup + [Channel->MonitorGroup].Pending); + } + + DPRINT_EXIT(VMBUS); +} + +#endif +/* + * VmbusChannelGetDebugInfo -Retrieve various channel debug info + */ +void VmbusChannelGetDebugInfo(struct vmbus_channel *Channel, + struct vmbus_channel_debug_info *DebugInfo) +{ + struct hv_monitor_page *monitorPage; + u8 monitorGroup = (u8)Channel->OfferMsg.MonitorId / 32; + u8 monitorOffset = (u8)Channel->OfferMsg.MonitorId % 32; + /* u32 monitorBit = 1 << monitorOffset; */ + + DebugInfo->RelId = Channel->OfferMsg.ChildRelId; + DebugInfo->State = Channel->State; + memcpy(&DebugInfo->InterfaceType, + &Channel->OfferMsg.Offer.InterfaceType, sizeof(struct hv_guid)); + memcpy(&DebugInfo->InterfaceInstance, + &Channel->OfferMsg.Offer.InterfaceInstance, + sizeof(struct hv_guid)); + + monitorPage = (struct hv_monitor_page *)gVmbusConnection.MonitorPages; + + DebugInfo->MonitorId = Channel->OfferMsg.MonitorId; + + DebugInfo->ServerMonitorPending = + monitorPage->TriggerGroup[monitorGroup].Pending; + DebugInfo->ServerMonitorLatency = + monitorPage->Latency[monitorGroup][monitorOffset]; + DebugInfo->ServerMonitorConnectionId = + monitorPage->Parameter[monitorGroup] + [monitorOffset].ConnectionId.u.Id; + + monitorPage++; + + DebugInfo->ClientMonitorPending = + monitorPage->TriggerGroup[monitorGroup].Pending; + DebugInfo->ClientMonitorLatency = + monitorPage->Latency[monitorGroup][monitorOffset]; + DebugInfo->ClientMonitorConnectionId = + monitorPage->Parameter[monitorGroup] + [monitorOffset].ConnectionId.u.Id; + + RingBufferGetDebugInfo(&Channel->Inbound, &DebugInfo->Inbound); + RingBufferGetDebugInfo(&Channel->Outbound, &DebugInfo->Outbound); +} + +/* + * VmbusChannelOpen - Open the specified channel. + */ +int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, + u32 RecvRingBufferSize, void *UserData, u32 UserDataLen, + void (*OnChannelCallback)(void *context), void *Context) +{ + struct vmbus_channel_open_channel *openMsg; + struct vmbus_channel_msginfo *openInfo = NULL; + void *in, *out; + unsigned long flags; + int ret, err = 0; + + DPRINT_ENTER(VMBUS); + + /* Aligned to page size */ + /* ASSERT(!(SendRingBufferSize & (PAGE_SIZE - 1))); */ + /* ASSERT(!(RecvRingBufferSize & (PAGE_SIZE - 1))); */ + + NewChannel->OnChannelCallback = OnChannelCallback; + NewChannel->ChannelCallbackContext = Context; + + /* Allocate the ring buffer */ + out = osd_PageAlloc((SendRingBufferSize + RecvRingBufferSize) + >> PAGE_SHIFT); + if (!out) + return -ENOMEM; + + /* ASSERT(((unsigned long)out & (PAGE_SIZE-1)) == 0); */ + + in = (void *)((unsigned long)out + SendRingBufferSize); + + NewChannel->RingBufferPages = out; + NewChannel->RingBufferPageCount = (SendRingBufferSize + + RecvRingBufferSize) >> PAGE_SHIFT; + + ret = RingBufferInit(&NewChannel->Outbound, out, SendRingBufferSize); + if (!ret) { + err = ret; + goto errorout; + } + + ret = RingBufferInit(&NewChannel->Inbound, in, RecvRingBufferSize); + if (!ret) { + err = ret; + goto errorout; + } + + + /* Establish the gpadl for the ring buffer */ + DPRINT_DBG(VMBUS, "Establishing ring buffer's gpadl for channel %p...", + NewChannel); + + NewChannel->RingBufferGpadlHandle = 0; + + ret = VmbusChannelEstablishGpadl(NewChannel, + NewChannel->Outbound.RingBuffer, + SendRingBufferSize + + RecvRingBufferSize, + &NewChannel->RingBufferGpadlHandle); + + if (!ret) { + err = ret; + goto errorout; + } + + DPRINT_DBG(VMBUS, "channel %p ", + NewChannel, NewChannel->OfferMsg.ChildRelId, + NewChannel->RingBufferGpadlHandle, + NewChannel->Outbound.RingBuffer, + NewChannel->Outbound.RingSize, + NewChannel->Inbound.RingBuffer, + NewChannel->Inbound.RingSize, + SendRingBufferSize); + + /* Create and init the channel open message */ + openInfo = kmalloc(sizeof(*openInfo) + + sizeof(struct vmbus_channel_open_channel), + GFP_KERNEL); + if (!openInfo) { + err = -ENOMEM; + goto errorout; + } + + openInfo->WaitEvent = osd_WaitEventCreate(); + if (!openInfo->WaitEvent) { + err = -ENOMEM; + goto errorout; + } + + openMsg = (struct vmbus_channel_open_channel *)openInfo->Msg; + openMsg->Header.MessageType = ChannelMessageOpenChannel; + openMsg->OpenId = NewChannel->OfferMsg.ChildRelId; /* FIXME */ + openMsg->ChildRelId = NewChannel->OfferMsg.ChildRelId; + openMsg->RingBufferGpadlHandle = NewChannel->RingBufferGpadlHandle; + openMsg->DownstreamRingBufferPageOffset = SendRingBufferSize >> + PAGE_SHIFT; + openMsg->ServerContextAreaGpadlHandle = 0; /* TODO */ + + if (UserDataLen > MAX_USER_DEFINED_BYTES) { + err = -EINVAL; + goto errorout; + } + + if (UserDataLen) + memcpy(openMsg->UserData, UserData, UserDataLen); + + spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + list_add_tail(&openInfo->MsgListEntry, + &gVmbusConnection.ChannelMsgList); + spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + + DPRINT_DBG(VMBUS, "Sending channel open msg..."); + + ret = VmbusPostMessage(openMsg, + sizeof(struct vmbus_channel_open_channel)); + if (ret != 0) { + DPRINT_ERR(VMBUS, "unable to open channel - %d", ret); + goto Cleanup; + } + + /* FIXME: Need to time-out here */ + osd_WaitEventWait(openInfo->WaitEvent); + + if (openInfo->Response.OpenResult.Status == 0) + DPRINT_INFO(VMBUS, "channel <%p> open success!!", NewChannel); + else + DPRINT_INFO(VMBUS, "channel <%p> open failed - %d!!", + NewChannel, openInfo->Response.OpenResult.Status); + +Cleanup: + spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + list_del(&openInfo->MsgListEntry); + spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + + kfree(openInfo->WaitEvent); + kfree(openInfo); + + DPRINT_EXIT(VMBUS); + + return 0; + +errorout: + RingBufferCleanup(&NewChannel->Outbound); + RingBufferCleanup(&NewChannel->Inbound); + osd_PageFree(out, (SendRingBufferSize + RecvRingBufferSize) + >> PAGE_SHIFT); + kfree(openInfo); + return err; +} + +/* + * DumpGpadlBody - Dump the gpadl body message to the console for + * debugging purposes. + */ +static void DumpGpadlBody(struct vmbus_channel_gpadl_body *Gpadl, u32 Len) +{ + int i; + int pfnCount; + + pfnCount = (Len - sizeof(struct vmbus_channel_gpadl_body)) / + sizeof(u64); + DPRINT_DBG(VMBUS, "gpadl body - len %d pfn count %d", Len, pfnCount); + + for (i = 0; i < pfnCount; i++) + DPRINT_DBG(VMBUS, "gpadl body - %d) pfn %llu", + i, Gpadl->Pfn[i]); +} + +/* + * DumpGpadlHeader - Dump the gpadl header message to the console for + * debugging purposes. + */ +static void DumpGpadlHeader(struct vmbus_channel_gpadl_header *Gpadl) +{ + int i, j; + int pageCount; + + DPRINT_DBG(VMBUS, + "gpadl header - relid %d, range count %d, range buflen %d", + Gpadl->ChildRelId, Gpadl->RangeCount, Gpadl->RangeBufLen); + for (i = 0; i < Gpadl->RangeCount; i++) { + pageCount = Gpadl->Range[i].ByteCount >> PAGE_SHIFT; + pageCount = (pageCount > 26) ? 26 : pageCount; + + DPRINT_DBG(VMBUS, "gpadl range %d - len %d offset %d " + "page count %d", i, Gpadl->Range[i].ByteCount, + Gpadl->Range[i].ByteOffset, pageCount); + + for (j = 0; j < pageCount; j++) + DPRINT_DBG(VMBUS, "%d) pfn %llu", j, + Gpadl->Range[i].PfnArray[j]); + } +} + +/* + * VmbusChannelCreateGpadlHeader - Creates a gpadl for the specified buffer + */ +static int VmbusChannelCreateGpadlHeader(void *Kbuffer, u32 Size, + struct vmbus_channel_msginfo **MsgInfo, + u32 *MessageCount) +{ + int i; + int pageCount; + unsigned long long pfn; + struct vmbus_channel_gpadl_header *gpaHeader; + struct vmbus_channel_gpadl_body *gpadlBody; + struct vmbus_channel_msginfo *msgHeader; + struct vmbus_channel_msginfo *msgBody = NULL; + u32 msgSize; + + int pfnSum, pfnCount, pfnLeft, pfnCurr, pfnSize; + + /* ASSERT((kbuffer & (PAGE_SIZE-1)) == 0); */ + /* ASSERT((Size & (PAGE_SIZE-1)) == 0); */ + + pageCount = Size >> PAGE_SHIFT; + pfn = virt_to_phys(Kbuffer) >> PAGE_SHIFT; + + /* do we need a gpadl body msg */ + pfnSize = MAX_SIZE_CHANNEL_MESSAGE - + sizeof(struct vmbus_channel_gpadl_header) - + sizeof(struct gpa_range); + pfnCount = pfnSize / sizeof(u64); + + if (pageCount > pfnCount) { + /* we need a gpadl body */ + /* fill in the header */ + msgSize = sizeof(struct vmbus_channel_msginfo) + + sizeof(struct vmbus_channel_gpadl_header) + + sizeof(struct gpa_range) + pfnCount * sizeof(u64); + msgHeader = kzalloc(msgSize, GFP_KERNEL); + if (!msgHeader) + goto nomem; + + INIT_LIST_HEAD(&msgHeader->SubMsgList); + msgHeader->MessageSize = msgSize; + + gpaHeader = (struct vmbus_channel_gpadl_header *)msgHeader->Msg; + gpaHeader->RangeCount = 1; + gpaHeader->RangeBufLen = sizeof(struct gpa_range) + + pageCount * sizeof(u64); + gpaHeader->Range[0].ByteOffset = 0; + gpaHeader->Range[0].ByteCount = Size; + for (i = 0; i < pfnCount; i++) + gpaHeader->Range[0].PfnArray[i] = pfn+i; + *MsgInfo = msgHeader; + *MessageCount = 1; + + pfnSum = pfnCount; + pfnLeft = pageCount - pfnCount; + + /* how many pfns can we fit */ + pfnSize = MAX_SIZE_CHANNEL_MESSAGE - + sizeof(struct vmbus_channel_gpadl_body); + pfnCount = pfnSize / sizeof(u64); + + /* fill in the body */ + while (pfnLeft) { + if (pfnLeft > pfnCount) + pfnCurr = pfnCount; + else + pfnCurr = pfnLeft; + + msgSize = sizeof(struct vmbus_channel_msginfo) + + sizeof(struct vmbus_channel_gpadl_body) + + pfnCurr * sizeof(u64); + msgBody = kzalloc(msgSize, GFP_KERNEL); + /* FIXME: we probably need to more if this fails */ + if (!msgBody) + goto nomem; + msgBody->MessageSize = msgSize; + (*MessageCount)++; + gpadlBody = + (struct vmbus_channel_gpadl_body *)msgBody->Msg; + + /* + * FIXME: + * Gpadl is u32 and we are using a pointer which could + * be 64-bit + */ + /* gpadlBody->Gpadl = kbuffer; */ + for (i = 0; i < pfnCurr; i++) + gpadlBody->Pfn[i] = pfn + pfnSum + i; + + /* add to msg header */ + list_add_tail(&msgBody->MsgListEntry, + &msgHeader->SubMsgList); + pfnSum += pfnCurr; + pfnLeft -= pfnCurr; + } + } else { + /* everything fits in a header */ + msgSize = sizeof(struct vmbus_channel_msginfo) + + sizeof(struct vmbus_channel_gpadl_header) + + sizeof(struct gpa_range) + pageCount * sizeof(u64); + msgHeader = kzalloc(msgSize, GFP_KERNEL); + msgHeader->MessageSize = msgSize; + + gpaHeader = (struct vmbus_channel_gpadl_header *)msgHeader->Msg; + gpaHeader->RangeCount = 1; + gpaHeader->RangeBufLen = sizeof(struct gpa_range) + + pageCount * sizeof(u64); + gpaHeader->Range[0].ByteOffset = 0; + gpaHeader->Range[0].ByteCount = Size; + for (i = 0; i < pageCount; i++) + gpaHeader->Range[0].PfnArray[i] = pfn+i; + + *MsgInfo = msgHeader; + *MessageCount = 1; + } + + return 0; +nomem: + kfree(msgHeader); + kfree(msgBody); + return -ENOMEM; +} + +/* + * VmbusChannelEstablishGpadl - Estabish a GPADL for the specified buffer + * + * @Channel: a channel + * @Kbuffer: from kmalloc + * @Size: page-size multiple + * @GpadlHandle: some funky thing + */ +int VmbusChannelEstablishGpadl(struct vmbus_channel *Channel, void *Kbuffer, + u32 Size, u32 *GpadlHandle) +{ + struct vmbus_channel_gpadl_header *gpadlMsg; + struct vmbus_channel_gpadl_body *gpadlBody; + /* struct vmbus_channel_gpadl_created *gpadlCreated; */ + struct vmbus_channel_msginfo *msgInfo = NULL; + struct vmbus_channel_msginfo *subMsgInfo; + u32 msgCount; + struct list_head *curr; + u32 nextGpadlHandle; + unsigned long flags; + int ret = 0; + + DPRINT_ENTER(VMBUS); + + nextGpadlHandle = atomic_read(&gVmbusConnection.NextGpadlHandle); + atomic_inc(&gVmbusConnection.NextGpadlHandle); + + ret = VmbusChannelCreateGpadlHeader(Kbuffer, Size, &msgInfo, &msgCount); + if (ret) + return ret; + + msgInfo->WaitEvent = osd_WaitEventCreate(); + if (!msgInfo->WaitEvent) { + ret = -ENOMEM; + goto Cleanup; + } + + gpadlMsg = (struct vmbus_channel_gpadl_header *)msgInfo->Msg; + gpadlMsg->Header.MessageType = ChannelMessageGpadlHeader; + gpadlMsg->ChildRelId = Channel->OfferMsg.ChildRelId; + gpadlMsg->Gpadl = nextGpadlHandle; + + DumpGpadlHeader(gpadlMsg); + + spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + list_add_tail(&msgInfo->MsgListEntry, + &gVmbusConnection.ChannelMsgList); + + spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + DPRINT_DBG(VMBUS, "buffer %p, size %d msg cnt %d", + Kbuffer, Size, msgCount); + + DPRINT_DBG(VMBUS, "Sending GPADL Header - len %zd", + msgInfo->MessageSize - sizeof(*msgInfo)); + + ret = VmbusPostMessage(gpadlMsg, msgInfo->MessageSize - + sizeof(*msgInfo)); + if (ret != 0) { + DPRINT_ERR(VMBUS, "Unable to open channel - %d", ret); + goto Cleanup; + } + + if (msgCount > 1) { + list_for_each(curr, &msgInfo->SubMsgList) { + + /* FIXME: should this use list_entry() instead ? */ + subMsgInfo = (struct vmbus_channel_msginfo *)curr; + gpadlBody = + (struct vmbus_channel_gpadl_body *)subMsgInfo->Msg; + + gpadlBody->Header.MessageType = ChannelMessageGpadlBody; + gpadlBody->Gpadl = nextGpadlHandle; + + DPRINT_DBG(VMBUS, "Sending GPADL Body - len %zd", + subMsgInfo->MessageSize - + sizeof(*subMsgInfo)); + + DumpGpadlBody(gpadlBody, subMsgInfo->MessageSize - + sizeof(*subMsgInfo)); + ret = VmbusPostMessage(gpadlBody, + subMsgInfo->MessageSize - + sizeof(*subMsgInfo)); + if (!ret) + goto Cleanup; + + } + } + osd_WaitEventWait(msgInfo->WaitEvent); + + /* At this point, we received the gpadl created msg */ + DPRINT_DBG(VMBUS, "Received GPADL created " + "(relid %d, status %d handle %x)", + Channel->OfferMsg.ChildRelId, + msgInfo->Response.GpadlCreated.CreationStatus, + gpadlMsg->Gpadl); + + *GpadlHandle = gpadlMsg->Gpadl; + +Cleanup: + spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + list_del(&msgInfo->MsgListEntry); + spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + + kfree(msgInfo->WaitEvent); + kfree(msgInfo); + + DPRINT_EXIT(VMBUS); + + return ret; +} + +/* + * VmbusChannelTeardownGpadl -Teardown the specified GPADL handle + */ +int VmbusChannelTeardownGpadl(struct vmbus_channel *Channel, u32 GpadlHandle) +{ + struct vmbus_channel_gpadl_teardown *msg; + struct vmbus_channel_msginfo *info; + unsigned long flags; + int ret; + + DPRINT_ENTER(VMBUS); + + /* ASSERT(GpadlHandle != 0); */ + + info = kmalloc(sizeof(*info) + + sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->WaitEvent = osd_WaitEventCreate(); + if (!info->WaitEvent) { + kfree(info); + return -ENOMEM; + } + + msg = (struct vmbus_channel_gpadl_teardown *)info->Msg; + + msg->Header.MessageType = ChannelMessageGpadlTeardown; + msg->ChildRelId = Channel->OfferMsg.ChildRelId; + msg->Gpadl = GpadlHandle; + + spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + list_add_tail(&info->MsgListEntry, + &gVmbusConnection.ChannelMsgList); + spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + + ret = VmbusPostMessage(msg, + sizeof(struct vmbus_channel_gpadl_teardown)); + if (ret != 0) { + /* TODO: */ + /* something... */ + } + + osd_WaitEventWait(info->WaitEvent); + + /* Received a torndown response */ + spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + list_del(&info->MsgListEntry); + spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + + kfree(info->WaitEvent); + kfree(info); + + DPRINT_EXIT(VMBUS); + + return ret; +} + +/* + * VmbusChannelClose - Close the specified channel + */ +void VmbusChannelClose(struct vmbus_channel *Channel) +{ + struct vmbus_channel_close_channel *msg; + struct vmbus_channel_msginfo *info; + unsigned long flags; + int ret; + + DPRINT_ENTER(VMBUS); + + /* Stop callback and cancel the timer asap */ + Channel->OnChannelCallback = NULL; + del_timer_sync(&Channel->poll_timer); + + /* Send a closing message */ + info = kmalloc(sizeof(*info) + + sizeof(struct vmbus_channel_close_channel), GFP_KERNEL); + /* FIXME: can't do anything other than return here because the + * function is void */ + if (!info) + return; + + /* info->waitEvent = osd_WaitEventCreate(); */ + + msg = (struct vmbus_channel_close_channel *)info->Msg; + msg->Header.MessageType = ChannelMessageCloseChannel; + msg->ChildRelId = Channel->OfferMsg.ChildRelId; + + ret = VmbusPostMessage(msg, sizeof(struct vmbus_channel_close_channel)); + if (ret != 0) { + /* TODO: */ + /* something... */ + } + + /* Tear down the gpadl for the channel's ring buffer */ + if (Channel->RingBufferGpadlHandle) + VmbusChannelTeardownGpadl(Channel, + Channel->RingBufferGpadlHandle); + + /* TODO: Send a msg to release the childRelId */ + + /* Cleanup the ring buffers for this channel */ + RingBufferCleanup(&Channel->Outbound); + RingBufferCleanup(&Channel->Inbound); + + osd_PageFree(Channel->RingBufferPages, Channel->RingBufferPageCount); + + kfree(info); + + /* + * If we are closing the channel during an error path in + * opening the channel, don't free the channel since the + * caller will free the channel + */ + + if (Channel->State == CHANNEL_OPEN_STATE) { + spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); + list_del(&Channel->ListEntry); + spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); + + FreeVmbusChannel(Channel); + } + + DPRINT_EXIT(VMBUS); +} + +/** + * VmbusChannelSendPacket() - Send the specified buffer on the given channel + * @Channel: Pointer to vmbus_channel structure. + * @Buffer: Pointer to the buffer you want to receive the data into. + * @BufferLen: Maximum size of what the the buffer will hold + * @RequestId: Identifier of the request + * @vmbus_packet_type: Type of packet that is being send e.g. negotiate, time + * packet etc. + * + * Sends data in @Buffer directly to hyper-v via the vmbus + * This will send the data unparsed to hyper-v. + * + * Mainly used by Hyper-V drivers. + */ +int VmbusChannelSendPacket(struct vmbus_channel *Channel, const void *Buffer, + u32 BufferLen, u64 RequestId, + enum vmbus_packet_type Type, u32 Flags) +{ + struct vmpacket_descriptor desc; + u32 packetLen = sizeof(struct vmpacket_descriptor) + BufferLen; + u32 packetLenAligned = ALIGN_UP(packetLen, sizeof(u64)); + struct scatterlist bufferList[3]; + u64 alignedData = 0; + int ret; + + DPRINT_ENTER(VMBUS); + DPRINT_DBG(VMBUS, "channel %p buffer %p len %d", + Channel, Buffer, BufferLen); + + DumpVmbusChannel(Channel); + + /* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */ + + /* Setup the descriptor */ + desc.Type = Type; /* VmbusPacketTypeDataInBand; */ + desc.Flags = Flags; /* VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; */ + /* in 8-bytes granularity */ + desc.DataOffset8 = sizeof(struct vmpacket_descriptor) >> 3; + desc.Length8 = (u16)(packetLenAligned >> 3); + desc.TransactionId = RequestId; + + sg_init_table(bufferList, 3); + sg_set_buf(&bufferList[0], &desc, sizeof(struct vmpacket_descriptor)); + sg_set_buf(&bufferList[1], Buffer, BufferLen); + sg_set_buf(&bufferList[2], &alignedData, packetLenAligned - packetLen); + + ret = RingBufferWrite(&Channel->Outbound, bufferList, 3); + + /* TODO: We should determine if this is optional */ + if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound)) + VmbusChannelSetEvent(Channel); + + DPRINT_EXIT(VMBUS); + + return ret; +} +EXPORT_SYMBOL(VmbusChannelSendPacket); + +/* + * VmbusChannelSendPacketPageBuffer - Send a range of single-page buffer + * packets using a GPADL Direct packet type. + */ +int VmbusChannelSendPacketPageBuffer(struct vmbus_channel *Channel, + struct hv_page_buffer PageBuffers[], + u32 PageCount, void *Buffer, u32 BufferLen, + u64 RequestId) +{ + int ret; + int i; + struct VMBUS_CHANNEL_PACKET_PAGE_BUFFER desc; + u32 descSize; + u32 packetLen; + u32 packetLenAligned; + struct scatterlist bufferList[3]; + u64 alignedData = 0; + + DPRINT_ENTER(VMBUS); + + if (PageCount > MAX_PAGE_BUFFER_COUNT) + return -EINVAL; + + DumpVmbusChannel(Channel); + + /* + * Adjust the size down since VMBUS_CHANNEL_PACKET_PAGE_BUFFER is the + * largest size we support + */ + descSize = sizeof(struct VMBUS_CHANNEL_PACKET_PAGE_BUFFER) - + ((MAX_PAGE_BUFFER_COUNT - PageCount) * + sizeof(struct hv_page_buffer)); + packetLen = descSize + BufferLen; + packetLenAligned = ALIGN_UP(packetLen, sizeof(u64)); + + /* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */ + + /* Setup the descriptor */ + desc.Type = VmbusPacketTypeDataUsingGpaDirect; + desc.Flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; + desc.DataOffset8 = descSize >> 3; /* in 8-bytes grandularity */ + desc.Length8 = (u16)(packetLenAligned >> 3); + desc.TransactionId = RequestId; + desc.RangeCount = PageCount; + + for (i = 0; i < PageCount; i++) { + desc.Range[i].Length = PageBuffers[i].Length; + desc.Range[i].Offset = PageBuffers[i].Offset; + desc.Range[i].Pfn = PageBuffers[i].Pfn; + } + + sg_init_table(bufferList, 3); + sg_set_buf(&bufferList[0], &desc, descSize); + sg_set_buf(&bufferList[1], Buffer, BufferLen); + sg_set_buf(&bufferList[2], &alignedData, packetLenAligned - packetLen); + + ret = RingBufferWrite(&Channel->Outbound, bufferList, 3); + + /* TODO: We should determine if this is optional */ + if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound)) + VmbusChannelSetEvent(Channel); + + DPRINT_EXIT(VMBUS); + + return ret; +} + +/* + * VmbusChannelSendPacketMultiPageBuffer - Send a multi-page buffer packet + * using a GPADL Direct packet type. + */ +int VmbusChannelSendPacketMultiPageBuffer(struct vmbus_channel *Channel, + struct hv_multipage_buffer *MultiPageBuffer, + void *Buffer, u32 BufferLen, u64 RequestId) +{ + int ret; + struct VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER desc; + u32 descSize; + u32 packetLen; + u32 packetLenAligned; + struct scatterlist bufferList[3]; + u64 alignedData = 0; + u32 PfnCount = NUM_PAGES_SPANNED(MultiPageBuffer->Offset, + MultiPageBuffer->Length); + + DPRINT_ENTER(VMBUS); + + DumpVmbusChannel(Channel); + + DPRINT_DBG(VMBUS, "data buffer - offset %u len %u pfn count %u", + MultiPageBuffer->Offset, MultiPageBuffer->Length, PfnCount); + + if ((PfnCount < 0) || (PfnCount > MAX_MULTIPAGE_BUFFER_COUNT)) + return -EINVAL; + + /* + * Adjust the size down since VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER is + * the largest size we support + */ + descSize = sizeof(struct VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER) - + ((MAX_MULTIPAGE_BUFFER_COUNT - PfnCount) * + sizeof(u64)); + packetLen = descSize + BufferLen; + packetLenAligned = ALIGN_UP(packetLen, sizeof(u64)); + + /* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */ + + /* Setup the descriptor */ + desc.Type = VmbusPacketTypeDataUsingGpaDirect; + desc.Flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; + desc.DataOffset8 = descSize >> 3; /* in 8-bytes grandularity */ + desc.Length8 = (u16)(packetLenAligned >> 3); + desc.TransactionId = RequestId; + desc.RangeCount = 1; + + desc.Range.Length = MultiPageBuffer->Length; + desc.Range.Offset = MultiPageBuffer->Offset; + + memcpy(desc.Range.PfnArray, MultiPageBuffer->PfnArray, + PfnCount * sizeof(u64)); + + sg_init_table(bufferList, 3); + sg_set_buf(&bufferList[0], &desc, descSize); + sg_set_buf(&bufferList[1], Buffer, BufferLen); + sg_set_buf(&bufferList[2], &alignedData, packetLenAligned - packetLen); + + ret = RingBufferWrite(&Channel->Outbound, bufferList, 3); + + /* TODO: We should determine if this is optional */ + if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound)) + VmbusChannelSetEvent(Channel); + + DPRINT_EXIT(VMBUS); + + return ret; +} + + +/** + * VmbusChannelRecvPacket() - Retrieve the user packet on the specified channel + * @Channel: Pointer to vmbus_channel structure. + * @Buffer: Pointer to the buffer you want to receive the data into. + * @BufferLen: Maximum size of what the the buffer will hold + * @BufferActualLen: The actual size of the data after it was received + * @RequestId: Identifier of the request + * + * Receives directly from the hyper-v vmbus and puts the data it received + * into Buffer. This will receive the data unparsed from hyper-v. + * + * Mainly used by Hyper-V drivers. + */ +int VmbusChannelRecvPacket(struct vmbus_channel *Channel, void *Buffer, + u32 BufferLen, u32 *BufferActualLen, u64 *RequestId) +{ + struct vmpacket_descriptor desc; + u32 packetLen; + u32 userLen; + int ret; + unsigned long flags; + + DPRINT_ENTER(VMBUS); + + *BufferActualLen = 0; + *RequestId = 0; + + spin_lock_irqsave(&Channel->inbound_lock, flags); + + ret = RingBufferPeek(&Channel->Inbound, &desc, + sizeof(struct vmpacket_descriptor)); + if (ret != 0) { + spin_unlock_irqrestore(&Channel->inbound_lock, flags); + + /* DPRINT_DBG(VMBUS, "nothing to read!!"); */ + DPRINT_EXIT(VMBUS); + return 0; + } + + /* VmbusChannelClearEvent(Channel); */ + + packetLen = desc.Length8 << 3; + userLen = packetLen - (desc.DataOffset8 << 3); + /* ASSERT(userLen > 0); */ + + DPRINT_DBG(VMBUS, "packet received on channel %p relid %d ", + Channel, Channel->OfferMsg.ChildRelId, desc.Type, + desc.Flags, desc.TransactionId, packetLen, userLen); + + *BufferActualLen = userLen; + + if (userLen > BufferLen) { + spin_unlock_irqrestore(&Channel->inbound_lock, flags); + + DPRINT_ERR(VMBUS, "buffer too small - got %d needs %d", + BufferLen, userLen); + DPRINT_EXIT(VMBUS); + + return -1; + } + + *RequestId = desc.TransactionId; + + /* Copy over the packet to the user buffer */ + ret = RingBufferRead(&Channel->Inbound, Buffer, userLen, + (desc.DataOffset8 << 3)); + + spin_unlock_irqrestore(&Channel->inbound_lock, flags); + + DPRINT_EXIT(VMBUS); + + return 0; +} +EXPORT_SYMBOL(VmbusChannelRecvPacket); + +/* + * VmbusChannelRecvPacketRaw - Retrieve the raw packet on the specified channel + */ +int VmbusChannelRecvPacketRaw(struct vmbus_channel *Channel, void *Buffer, + u32 BufferLen, u32 *BufferActualLen, + u64 *RequestId) +{ + struct vmpacket_descriptor desc; + u32 packetLen; + u32 userLen; + int ret; + unsigned long flags; + + DPRINT_ENTER(VMBUS); + + *BufferActualLen = 0; + *RequestId = 0; + + spin_lock_irqsave(&Channel->inbound_lock, flags); + + ret = RingBufferPeek(&Channel->Inbound, &desc, + sizeof(struct vmpacket_descriptor)); + if (ret != 0) { + spin_unlock_irqrestore(&Channel->inbound_lock, flags); + + /* DPRINT_DBG(VMBUS, "nothing to read!!"); */ + DPRINT_EXIT(VMBUS); + return 0; + } + + /* VmbusChannelClearEvent(Channel); */ + + packetLen = desc.Length8 << 3; + userLen = packetLen - (desc.DataOffset8 << 3); + + DPRINT_DBG(VMBUS, "packet received on channel %p relid %d ", + Channel, Channel->OfferMsg.ChildRelId, desc.Type, + desc.Flags, desc.TransactionId, packetLen, userLen); + + *BufferActualLen = packetLen; + + if (packetLen > BufferLen) { + spin_unlock_irqrestore(&Channel->inbound_lock, flags); + + DPRINT_ERR(VMBUS, "buffer too small - needed %d bytes but " + "got space for only %d bytes", packetLen, BufferLen); + DPRINT_EXIT(VMBUS); + return -2; + } + + *RequestId = desc.TransactionId; + + /* Copy over the entire packet to the user buffer */ + ret = RingBufferRead(&Channel->Inbound, Buffer, packetLen, 0); + + spin_unlock_irqrestore(&Channel->inbound_lock, flags); + + DPRINT_EXIT(VMBUS); + + return 0; +} + +/* + * VmbusChannelOnChannelEvent - Channel event callback + */ +void VmbusChannelOnChannelEvent(struct vmbus_channel *Channel) +{ + DumpVmbusChannel(Channel); + /* ASSERT(Channel->OnChannelCallback); */ + + Channel->OnChannelCallback(Channel->ChannelCallbackContext); + + mod_timer(&Channel->poll_timer, jiffies + usecs_to_jiffies(100)); +} + +/* + * VmbusChannelOnTimer - Timer event callback + */ +void VmbusChannelOnTimer(unsigned long data) +{ + struct vmbus_channel *channel = (struct vmbus_channel *)data; + + if (channel->OnChannelCallback) + channel->OnChannelCallback(channel->ChannelCallbackContext); +} + +/* + * DumpVmbusChannel - Dump vmbus channel info to the console + */ +static void DumpVmbusChannel(struct vmbus_channel *Channel) +{ + DPRINT_DBG(VMBUS, "Channel (%d)", Channel->OfferMsg.ChildRelId); + DumpRingInfo(&Channel->Outbound, "Outbound "); + DumpRingInfo(&Channel->Inbound, "Inbound "); +} diff --git a/drivers/staging/hv/channel.h b/drivers/staging/hv/channel.h new file mode 100644 index 000000000000..6b283edcae68 --- /dev/null +++ b/drivers/staging/hv/channel.h @@ -0,0 +1,112 @@ +/* + * + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + * + */ + + +#ifndef _CHANNEL_H_ +#define _CHANNEL_H_ + +#include "ChannelMgmt.h" + +/* The format must be the same as struct vmdata_gpa_direct */ +struct VMBUS_CHANNEL_PACKET_PAGE_BUFFER { + u16 Type; + u16 DataOffset8; + u16 Length8; + u16 Flags; + u64 TransactionId; + u32 Reserved; + u32 RangeCount; + struct hv_page_buffer Range[MAX_PAGE_BUFFER_COUNT]; +} __attribute__((packed)); + +/* The format must be the same as struct vmdata_gpa_direct */ +struct VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER { + u16 Type; + u16 DataOffset8; + u16 Length8; + u16 Flags; + u64 TransactionId; + u32 Reserved; + u32 RangeCount; /* Always 1 in this case */ + struct hv_multipage_buffer Range; +} __attribute__((packed)); + + +extern int VmbusChannelOpen(struct vmbus_channel *channel, + u32 SendRingBufferSize, + u32 RecvRingBufferSize, + void *UserData, + u32 UserDataLen, + void(*OnChannelCallback)(void *context), + void *Context); + +extern void VmbusChannelClose(struct vmbus_channel *channel); + +extern int VmbusChannelSendPacket(struct vmbus_channel *channel, + const void *Buffer, + u32 BufferLen, + u64 RequestId, + enum vmbus_packet_type Type, + u32 Flags); + +extern int VmbusChannelSendPacketPageBuffer(struct vmbus_channel *channel, + struct hv_page_buffer PageBuffers[], + u32 PageCount, + void *Buffer, + u32 BufferLen, + u64 RequestId); + +extern int VmbusChannelSendPacketMultiPageBuffer(struct vmbus_channel *channel, + struct hv_multipage_buffer *mpb, + void *Buffer, + u32 BufferLen, + u64 RequestId); + +extern int VmbusChannelEstablishGpadl(struct vmbus_channel *channel, + void *Kbuffer, + u32 Size, + u32 *GpadlHandle); + +extern int VmbusChannelTeardownGpadl(struct vmbus_channel *channel, + u32 GpadlHandle); + +extern int VmbusChannelRecvPacket(struct vmbus_channel *channel, + void *Buffer, + u32 BufferLen, + u32 *BufferActualLen, + u64 *RequestId); + +extern int VmbusChannelRecvPacketRaw(struct vmbus_channel *channel, + void *Buffer, + u32 BufferLen, + u32 *BufferActualLen, + u64 *RequestId); + +extern void VmbusChannelOnChannelEvent(struct vmbus_channel *channel); + +extern void VmbusChannelGetDebugInfo(struct vmbus_channel *channel, + struct vmbus_channel_debug_info *debug); + +extern void VmbusChannelOnTimer(unsigned long data); + +#endif /* _CHANNEL_H_ */ diff --git a/drivers/staging/hv/hv_utils.c b/drivers/staging/hv/hv_utils.c index d3fc33e96272..6ccaea27d75a 100644 --- a/drivers/staging/hv/hv_utils.c +++ b/drivers/staging/hv/hv_utils.c @@ -31,7 +31,7 @@ #include "VmbusPacketFormat.h" #include "VmbusChannelInterface.h" #include "VersionInfo.h" -#include "Channel.h" +#include "channel.h" #include "VmbusPrivate.h" #include "VmbusApi.h" #include "utils.h" -- cgit v1.2.3 From 55e9643e6c486b589279576877838ffd8ed04a68 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:19:40 -0700 Subject: Staging: hv: rename Connection.c to connection.c Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Connection.c | 349 ---------------------------------------- drivers/staging/hv/Makefile | 2 +- drivers/staging/hv/connection.c | 349 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 350 insertions(+), 350 deletions(-) delete mode 100644 drivers/staging/hv/Connection.c create mode 100644 drivers/staging/hv/connection.c (limited to 'drivers') diff --git a/drivers/staging/hv/Connection.c b/drivers/staging/hv/Connection.c deleted file mode 100644 index 3a01d3ca4ad0..000000000000 --- a/drivers/staging/hv/Connection.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ -#include -#include -#include -#include -#include "osd.h" -#include "logging.h" -#include "VmbusPrivate.h" - - -struct VMBUS_CONNECTION gVmbusConnection = { - .ConnectState = Disconnected, - .NextGpadlHandle = ATOMIC_INIT(0xE1E10), -}; - -/* - * VmbusConnect - Sends a connect request on the partition service connection - */ -int VmbusConnect(void) -{ - int ret = 0; - struct vmbus_channel_msginfo *msgInfo = NULL; - struct vmbus_channel_initiate_contact *msg; - unsigned long flags; - - DPRINT_ENTER(VMBUS); - - /* Make sure we are not connecting or connected */ - if (gVmbusConnection.ConnectState != Disconnected) - return -1; - - /* Initialize the vmbus connection */ - gVmbusConnection.ConnectState = Connecting; - gVmbusConnection.WorkQueue = create_workqueue("hv_vmbus_con"); - if (!gVmbusConnection.WorkQueue) { - ret = -1; - goto Cleanup; - } - - INIT_LIST_HEAD(&gVmbusConnection.ChannelMsgList); - spin_lock_init(&gVmbusConnection.channelmsg_lock); - - INIT_LIST_HEAD(&gVmbusConnection.ChannelList); - spin_lock_init(&gVmbusConnection.channel_lock); - - /* - * Setup the vmbus event connection for channel interrupt - * abstraction stuff - */ - gVmbusConnection.InterruptPage = osd_PageAlloc(1); - if (gVmbusConnection.InterruptPage == NULL) { - ret = -1; - goto Cleanup; - } - - gVmbusConnection.RecvInterruptPage = gVmbusConnection.InterruptPage; - gVmbusConnection.SendInterruptPage = - (void *)((unsigned long)gVmbusConnection.InterruptPage + - (PAGE_SIZE >> 1)); - - /* - * Setup the monitor notification facility. The 1st page for - * parent->child and the 2nd page for child->parent - */ - gVmbusConnection.MonitorPages = osd_PageAlloc(2); - if (gVmbusConnection.MonitorPages == NULL) { - ret = -1; - goto Cleanup; - } - - msgInfo = kzalloc(sizeof(*msgInfo) + - sizeof(struct vmbus_channel_initiate_contact), - GFP_KERNEL); - if (msgInfo == NULL) { - ret = -ENOMEM; - goto Cleanup; - } - - msgInfo->WaitEvent = osd_WaitEventCreate(); - if (!msgInfo->WaitEvent) { - ret = -ENOMEM; - goto Cleanup; - } - - msg = (struct vmbus_channel_initiate_contact *)msgInfo->Msg; - - msg->Header.MessageType = ChannelMessageInitiateContact; - msg->VMBusVersionRequested = VMBUS_REVISION_NUMBER; - msg->InterruptPage = virt_to_phys(gVmbusConnection.InterruptPage); - msg->MonitorPage1 = virt_to_phys(gVmbusConnection.MonitorPages); - msg->MonitorPage2 = virt_to_phys( - (void *)((unsigned long)gVmbusConnection.MonitorPages + - PAGE_SIZE)); - - /* - * Add to list before we send the request since we may - * receive the response before returning from this routine - */ - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); - list_add_tail(&msgInfo->MsgListEntry, - &gVmbusConnection.ChannelMsgList); - - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); - - DPRINT_DBG(VMBUS, "Vmbus connection - interrupt pfn %llx, " - "monitor1 pfn %llx,, monitor2 pfn %llx", - msg->InterruptPage, msg->MonitorPage1, msg->MonitorPage2); - - DPRINT_DBG(VMBUS, "Sending channel initiate msg..."); - ret = VmbusPostMessage(msg, - sizeof(struct vmbus_channel_initiate_contact)); - if (ret != 0) { - list_del(&msgInfo->MsgListEntry); - goto Cleanup; - } - - /* Wait for the connection response */ - osd_WaitEventWait(msgInfo->WaitEvent); - - list_del(&msgInfo->MsgListEntry); - - /* Check if successful */ - if (msgInfo->Response.VersionResponse.VersionSupported) { - DPRINT_INFO(VMBUS, "Vmbus connected!!"); - gVmbusConnection.ConnectState = Connected; - - } else { - DPRINT_ERR(VMBUS, "Vmbus connection failed!!..." - "current version (%d) not supported", - VMBUS_REVISION_NUMBER); - ret = -1; - goto Cleanup; - } - - kfree(msgInfo->WaitEvent); - kfree(msgInfo); - DPRINT_EXIT(VMBUS); - - return 0; - -Cleanup: - gVmbusConnection.ConnectState = Disconnected; - - if (gVmbusConnection.WorkQueue) - destroy_workqueue(gVmbusConnection.WorkQueue); - - if (gVmbusConnection.InterruptPage) { - osd_PageFree(gVmbusConnection.InterruptPage, 1); - gVmbusConnection.InterruptPage = NULL; - } - - if (gVmbusConnection.MonitorPages) { - osd_PageFree(gVmbusConnection.MonitorPages, 2); - gVmbusConnection.MonitorPages = NULL; - } - - if (msgInfo) { - kfree(msgInfo->WaitEvent); - kfree(msgInfo); - } - - DPRINT_EXIT(VMBUS); - - return ret; -} - -/* - * VmbusDisconnect - Sends a disconnect request on the partition service connection - */ -int VmbusDisconnect(void) -{ - int ret = 0; - struct vmbus_channel_message_header *msg; - - DPRINT_ENTER(VMBUS); - - /* Make sure we are connected */ - if (gVmbusConnection.ConnectState != Connected) - return -1; - - msg = kzalloc(sizeof(struct vmbus_channel_message_header), GFP_KERNEL); - if (!msg) - return -ENOMEM; - - msg->MessageType = ChannelMessageUnload; - - ret = VmbusPostMessage(msg, - sizeof(struct vmbus_channel_message_header)); - if (ret != 0) - goto Cleanup; - - osd_PageFree(gVmbusConnection.InterruptPage, 1); - - /* TODO: iterate thru the msg list and free up */ - destroy_workqueue(gVmbusConnection.WorkQueue); - - gVmbusConnection.ConnectState = Disconnected; - - DPRINT_INFO(VMBUS, "Vmbus disconnected!!"); - -Cleanup: - kfree(msg); - DPRINT_EXIT(VMBUS); - return ret; -} - -/* - * GetChannelFromRelId - Get the channel object given its child relative id (ie channel id) - */ -struct vmbus_channel *GetChannelFromRelId(u32 relId) -{ - struct vmbus_channel *channel; - struct vmbus_channel *foundChannel = NULL; - unsigned long flags; - - spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); - list_for_each_entry(channel, &gVmbusConnection.ChannelList, ListEntry) { - if (channel->OfferMsg.ChildRelId == relId) { - foundChannel = channel; - break; - } - } - spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); - - return foundChannel; -} - -/* - * VmbusProcessChannelEvent - Process a channel event notification - */ -static void VmbusProcessChannelEvent(void *context) -{ - struct vmbus_channel *channel; - u32 relId = (u32)(unsigned long)context; - - /* ASSERT(relId > 0); */ - - /* - * Find the channel based on this relid and invokes the - * channel callback to process the event - */ - channel = GetChannelFromRelId(relId); - - if (channel) { - VmbusChannelOnChannelEvent(channel); - /* - * WorkQueueQueueWorkItem(channel->dataWorkQueue, - * VmbusChannelOnChannelEvent, - * (void*)channel); - */ - } else { - DPRINT_ERR(VMBUS, "channel not found for relid - %d.", relId); - } -} - -/* - * VmbusOnEvents - Handler for events - */ -void VmbusOnEvents(void) -{ - int dword; - int maxdword = MAX_NUM_CHANNELS_SUPPORTED >> 5; - int bit; - int relid; - u32 *recvInterruptPage = gVmbusConnection.RecvInterruptPage; - - DPRINT_ENTER(VMBUS); - - /* Check events */ - if (recvInterruptPage) { - for (dword = 0; dword < maxdword; dword++) { - if (recvInterruptPage[dword]) { - for (bit = 0; bit < 32; bit++) { - if (test_and_clear_bit(bit, (unsigned long *)&recvInterruptPage[dword])) { - relid = (dword << 5) + bit; - DPRINT_DBG(VMBUS, "event detected for relid - %d", relid); - - if (relid == 0) { - /* special case - vmbus channel protocol msg */ - DPRINT_DBG(VMBUS, "invalid relid - %d", relid); - continue; - } else { - /* QueueWorkItem(VmbusProcessEvent, (void*)relid); */ - /* ret = WorkQueueQueueWorkItem(gVmbusConnection.workQueue, VmbusProcessChannelEvent, (void*)relid); */ - VmbusProcessChannelEvent((void *)(unsigned long)relid); - } - } - } - } - } - } - DPRINT_EXIT(VMBUS); - - return; -} - -/* - * VmbusPostMessage - Send a msg on the vmbus's message connection - */ -int VmbusPostMessage(void *buffer, size_t bufferLen) -{ - union hv_connection_id connId; - - connId.Asu32 = 0; - connId.u.Id = VMBUS_MESSAGE_CONNECTION_ID; - return HvPostMessage(connId, 1, buffer, bufferLen); -} - -/* - * VmbusSetEvent - Send an event notification to the parent - */ -int VmbusSetEvent(u32 childRelId) -{ - int ret = 0; - - DPRINT_ENTER(VMBUS); - - /* Each u32 represents 32 channels */ - set_bit(childRelId & 31, - (unsigned long *)gVmbusConnection.SendInterruptPage + - (childRelId >> 5)); - - ret = HvSignalEvent(); - - DPRINT_EXIT(VMBUS); - - return ret; -} diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index 3c15c731f96d..91955095f9e8 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_HYPERV_NET) += hv_netvsc.o obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o hv_vmbus-objs := vmbus_drv.o osd.o \ - Vmbus.o hv.o Connection.o channel.o \ + Vmbus.o hv.o connection.o channel.o \ ChannelMgmt.o ChannelInterface.o RingBuffer.o hv_storvsc-objs := storvsc_drv.o StorVsc.o hv_blkvsc-objs := blkvsc_drv.o BlkVsc.o diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c new file mode 100644 index 000000000000..3a01d3ca4ad0 --- /dev/null +++ b/drivers/staging/hv/connection.c @@ -0,0 +1,349 @@ +/* + * + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + * + */ +#include +#include +#include +#include +#include "osd.h" +#include "logging.h" +#include "VmbusPrivate.h" + + +struct VMBUS_CONNECTION gVmbusConnection = { + .ConnectState = Disconnected, + .NextGpadlHandle = ATOMIC_INIT(0xE1E10), +}; + +/* + * VmbusConnect - Sends a connect request on the partition service connection + */ +int VmbusConnect(void) +{ + int ret = 0; + struct vmbus_channel_msginfo *msgInfo = NULL; + struct vmbus_channel_initiate_contact *msg; + unsigned long flags; + + DPRINT_ENTER(VMBUS); + + /* Make sure we are not connecting or connected */ + if (gVmbusConnection.ConnectState != Disconnected) + return -1; + + /* Initialize the vmbus connection */ + gVmbusConnection.ConnectState = Connecting; + gVmbusConnection.WorkQueue = create_workqueue("hv_vmbus_con"); + if (!gVmbusConnection.WorkQueue) { + ret = -1; + goto Cleanup; + } + + INIT_LIST_HEAD(&gVmbusConnection.ChannelMsgList); + spin_lock_init(&gVmbusConnection.channelmsg_lock); + + INIT_LIST_HEAD(&gVmbusConnection.ChannelList); + spin_lock_init(&gVmbusConnection.channel_lock); + + /* + * Setup the vmbus event connection for channel interrupt + * abstraction stuff + */ + gVmbusConnection.InterruptPage = osd_PageAlloc(1); + if (gVmbusConnection.InterruptPage == NULL) { + ret = -1; + goto Cleanup; + } + + gVmbusConnection.RecvInterruptPage = gVmbusConnection.InterruptPage; + gVmbusConnection.SendInterruptPage = + (void *)((unsigned long)gVmbusConnection.InterruptPage + + (PAGE_SIZE >> 1)); + + /* + * Setup the monitor notification facility. The 1st page for + * parent->child and the 2nd page for child->parent + */ + gVmbusConnection.MonitorPages = osd_PageAlloc(2); + if (gVmbusConnection.MonitorPages == NULL) { + ret = -1; + goto Cleanup; + } + + msgInfo = kzalloc(sizeof(*msgInfo) + + sizeof(struct vmbus_channel_initiate_contact), + GFP_KERNEL); + if (msgInfo == NULL) { + ret = -ENOMEM; + goto Cleanup; + } + + msgInfo->WaitEvent = osd_WaitEventCreate(); + if (!msgInfo->WaitEvent) { + ret = -ENOMEM; + goto Cleanup; + } + + msg = (struct vmbus_channel_initiate_contact *)msgInfo->Msg; + + msg->Header.MessageType = ChannelMessageInitiateContact; + msg->VMBusVersionRequested = VMBUS_REVISION_NUMBER; + msg->InterruptPage = virt_to_phys(gVmbusConnection.InterruptPage); + msg->MonitorPage1 = virt_to_phys(gVmbusConnection.MonitorPages); + msg->MonitorPage2 = virt_to_phys( + (void *)((unsigned long)gVmbusConnection.MonitorPages + + PAGE_SIZE)); + + /* + * Add to list before we send the request since we may + * receive the response before returning from this routine + */ + spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + list_add_tail(&msgInfo->MsgListEntry, + &gVmbusConnection.ChannelMsgList); + + spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + + DPRINT_DBG(VMBUS, "Vmbus connection - interrupt pfn %llx, " + "monitor1 pfn %llx,, monitor2 pfn %llx", + msg->InterruptPage, msg->MonitorPage1, msg->MonitorPage2); + + DPRINT_DBG(VMBUS, "Sending channel initiate msg..."); + ret = VmbusPostMessage(msg, + sizeof(struct vmbus_channel_initiate_contact)); + if (ret != 0) { + list_del(&msgInfo->MsgListEntry); + goto Cleanup; + } + + /* Wait for the connection response */ + osd_WaitEventWait(msgInfo->WaitEvent); + + list_del(&msgInfo->MsgListEntry); + + /* Check if successful */ + if (msgInfo->Response.VersionResponse.VersionSupported) { + DPRINT_INFO(VMBUS, "Vmbus connected!!"); + gVmbusConnection.ConnectState = Connected; + + } else { + DPRINT_ERR(VMBUS, "Vmbus connection failed!!..." + "current version (%d) not supported", + VMBUS_REVISION_NUMBER); + ret = -1; + goto Cleanup; + } + + kfree(msgInfo->WaitEvent); + kfree(msgInfo); + DPRINT_EXIT(VMBUS); + + return 0; + +Cleanup: + gVmbusConnection.ConnectState = Disconnected; + + if (gVmbusConnection.WorkQueue) + destroy_workqueue(gVmbusConnection.WorkQueue); + + if (gVmbusConnection.InterruptPage) { + osd_PageFree(gVmbusConnection.InterruptPage, 1); + gVmbusConnection.InterruptPage = NULL; + } + + if (gVmbusConnection.MonitorPages) { + osd_PageFree(gVmbusConnection.MonitorPages, 2); + gVmbusConnection.MonitorPages = NULL; + } + + if (msgInfo) { + kfree(msgInfo->WaitEvent); + kfree(msgInfo); + } + + DPRINT_EXIT(VMBUS); + + return ret; +} + +/* + * VmbusDisconnect - Sends a disconnect request on the partition service connection + */ +int VmbusDisconnect(void) +{ + int ret = 0; + struct vmbus_channel_message_header *msg; + + DPRINT_ENTER(VMBUS); + + /* Make sure we are connected */ + if (gVmbusConnection.ConnectState != Connected) + return -1; + + msg = kzalloc(sizeof(struct vmbus_channel_message_header), GFP_KERNEL); + if (!msg) + return -ENOMEM; + + msg->MessageType = ChannelMessageUnload; + + ret = VmbusPostMessage(msg, + sizeof(struct vmbus_channel_message_header)); + if (ret != 0) + goto Cleanup; + + osd_PageFree(gVmbusConnection.InterruptPage, 1); + + /* TODO: iterate thru the msg list and free up */ + destroy_workqueue(gVmbusConnection.WorkQueue); + + gVmbusConnection.ConnectState = Disconnected; + + DPRINT_INFO(VMBUS, "Vmbus disconnected!!"); + +Cleanup: + kfree(msg); + DPRINT_EXIT(VMBUS); + return ret; +} + +/* + * GetChannelFromRelId - Get the channel object given its child relative id (ie channel id) + */ +struct vmbus_channel *GetChannelFromRelId(u32 relId) +{ + struct vmbus_channel *channel; + struct vmbus_channel *foundChannel = NULL; + unsigned long flags; + + spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); + list_for_each_entry(channel, &gVmbusConnection.ChannelList, ListEntry) { + if (channel->OfferMsg.ChildRelId == relId) { + foundChannel = channel; + break; + } + } + spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); + + return foundChannel; +} + +/* + * VmbusProcessChannelEvent - Process a channel event notification + */ +static void VmbusProcessChannelEvent(void *context) +{ + struct vmbus_channel *channel; + u32 relId = (u32)(unsigned long)context; + + /* ASSERT(relId > 0); */ + + /* + * Find the channel based on this relid and invokes the + * channel callback to process the event + */ + channel = GetChannelFromRelId(relId); + + if (channel) { + VmbusChannelOnChannelEvent(channel); + /* + * WorkQueueQueueWorkItem(channel->dataWorkQueue, + * VmbusChannelOnChannelEvent, + * (void*)channel); + */ + } else { + DPRINT_ERR(VMBUS, "channel not found for relid - %d.", relId); + } +} + +/* + * VmbusOnEvents - Handler for events + */ +void VmbusOnEvents(void) +{ + int dword; + int maxdword = MAX_NUM_CHANNELS_SUPPORTED >> 5; + int bit; + int relid; + u32 *recvInterruptPage = gVmbusConnection.RecvInterruptPage; + + DPRINT_ENTER(VMBUS); + + /* Check events */ + if (recvInterruptPage) { + for (dword = 0; dword < maxdword; dword++) { + if (recvInterruptPage[dword]) { + for (bit = 0; bit < 32; bit++) { + if (test_and_clear_bit(bit, (unsigned long *)&recvInterruptPage[dword])) { + relid = (dword << 5) + bit; + DPRINT_DBG(VMBUS, "event detected for relid - %d", relid); + + if (relid == 0) { + /* special case - vmbus channel protocol msg */ + DPRINT_DBG(VMBUS, "invalid relid - %d", relid); + continue; + } else { + /* QueueWorkItem(VmbusProcessEvent, (void*)relid); */ + /* ret = WorkQueueQueueWorkItem(gVmbusConnection.workQueue, VmbusProcessChannelEvent, (void*)relid); */ + VmbusProcessChannelEvent((void *)(unsigned long)relid); + } + } + } + } + } + } + DPRINT_EXIT(VMBUS); + + return; +} + +/* + * VmbusPostMessage - Send a msg on the vmbus's message connection + */ +int VmbusPostMessage(void *buffer, size_t bufferLen) +{ + union hv_connection_id connId; + + connId.Asu32 = 0; + connId.u.Id = VMBUS_MESSAGE_CONNECTION_ID; + return HvPostMessage(connId, 1, buffer, bufferLen); +} + +/* + * VmbusSetEvent - Send an event notification to the parent + */ +int VmbusSetEvent(u32 childRelId) +{ + int ret = 0; + + DPRINT_ENTER(VMBUS); + + /* Each u32 represents 32 channels */ + set_bit(childRelId & 31, + (unsigned long *)gVmbusConnection.SendInterruptPage + + (childRelId >> 5)); + + ret = HvSignalEvent(); + + DPRINT_EXIT(VMBUS); + + return ret; +} -- cgit v1.2.3 From 8f078ca6e7e1a5457aef5196e7154aa468094120 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:22:35 -0700 Subject: Staging: hv: rename RingBuffer.c and .h to ring_buffer.c and .h Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/ChannelMgmt.h | 2 +- drivers/staging/hv/Makefile | 2 +- drivers/staging/hv/RingBuffer.c | 627 -------------------------------------- drivers/staging/hv/RingBuffer.h | 101 ------ drivers/staging/hv/VmbusPrivate.h | 2 +- drivers/staging/hv/ring_buffer.c | 627 ++++++++++++++++++++++++++++++++++++++ drivers/staging/hv/ring_buffer.h | 101 ++++++ 7 files changed, 731 insertions(+), 731 deletions(-) delete mode 100644 drivers/staging/hv/RingBuffer.c delete mode 100644 drivers/staging/hv/RingBuffer.h create mode 100644 drivers/staging/hv/ring_buffer.c create mode 100644 drivers/staging/hv/ring_buffer.h (limited to 'drivers') diff --git a/drivers/staging/hv/ChannelMgmt.h b/drivers/staging/hv/ChannelMgmt.h index fa973d86b624..9219199d0e5a 100644 --- a/drivers/staging/hv/ChannelMgmt.h +++ b/drivers/staging/hv/ChannelMgmt.h @@ -27,7 +27,7 @@ #include #include -#include "RingBuffer.h" +#include "ring_buffer.h" #include "VmbusChannelInterface.h" #include "VmbusPacketFormat.h" diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index 91955095f9e8..faa8db1d86c0 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -6,7 +6,7 @@ obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o hv_vmbus-objs := vmbus_drv.o osd.o \ Vmbus.o hv.o connection.o channel.o \ - ChannelMgmt.o ChannelInterface.o RingBuffer.o + ChannelMgmt.o ChannelInterface.o ring_buffer.o hv_storvsc-objs := storvsc_drv.o StorVsc.o hv_blkvsc-objs := blkvsc_drv.o BlkVsc.o hv_netvsc-objs := netvsc_drv.o NetVsc.o RndisFilter.o diff --git a/drivers/staging/hv/RingBuffer.c b/drivers/staging/hv/RingBuffer.c deleted file mode 100644 index 64f8d0f9e05c..000000000000 --- a/drivers/staging/hv/RingBuffer.c +++ /dev/null @@ -1,627 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ - -#include -#include -#include "osd.h" -#include "logging.h" -#include "RingBuffer.h" - - -/* #defines */ - - -/* Amount of space to write to */ -#define BYTES_AVAIL_TO_WRITE(r, w, z) ((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w)) - - -/*++ - -Name: - GetRingBufferAvailBytes() - -Description: - Get number of bytes available to read and to write to - for the specified ring buffer - ---*/ -static inline void -GetRingBufferAvailBytes(RING_BUFFER_INFO *rbi, u32 *read, u32 *write) -{ - u32 read_loc, write_loc; - - /* Capture the read/write indices before they changed */ - read_loc = rbi->RingBuffer->ReadIndex; - write_loc = rbi->RingBuffer->WriteIndex; - - *write = BYTES_AVAIL_TO_WRITE(read_loc, write_loc, rbi->RingDataSize); - *read = rbi->RingDataSize - *write; -} - -/*++ - -Name: - GetNextWriteLocation() - -Description: - Get the next write location for the specified ring buffer - ---*/ -static inline u32 -GetNextWriteLocation(RING_BUFFER_INFO *RingInfo) -{ - u32 next = RingInfo->RingBuffer->WriteIndex; - - /* ASSERT(next < RingInfo->RingDataSize); */ - - return next; -} - -/*++ - -Name: - SetNextWriteLocation() - -Description: - Set the next write location for the specified ring buffer - ---*/ -static inline void -SetNextWriteLocation(RING_BUFFER_INFO *RingInfo, u32 NextWriteLocation) -{ - RingInfo->RingBuffer->WriteIndex = NextWriteLocation; -} - -/*++ - -Name: - GetNextReadLocation() - -Description: - Get the next read location for the specified ring buffer - ---*/ -static inline u32 -GetNextReadLocation(RING_BUFFER_INFO *RingInfo) -{ - u32 next = RingInfo->RingBuffer->ReadIndex; - - /* ASSERT(next < RingInfo->RingDataSize); */ - - return next; -} - -/*++ - -Name: - GetNextReadLocationWithOffset() - -Description: - Get the next read location + offset for the specified ring buffer. - This allows the caller to skip - ---*/ -static inline u32 -GetNextReadLocationWithOffset(RING_BUFFER_INFO *RingInfo, u32 Offset) -{ - u32 next = RingInfo->RingBuffer->ReadIndex; - - /* ASSERT(next < RingInfo->RingDataSize); */ - next += Offset; - next %= RingInfo->RingDataSize; - - return next; -} - -/*++ - -Name: - SetNextReadLocation() - -Description: - Set the next read location for the specified ring buffer - ---*/ -static inline void -SetNextReadLocation(RING_BUFFER_INFO *RingInfo, u32 NextReadLocation) -{ - RingInfo->RingBuffer->ReadIndex = NextReadLocation; -} - - -/*++ - -Name: - GetRingBuffer() - -Description: - Get the start of the ring buffer - ---*/ -static inline void * -GetRingBuffer(RING_BUFFER_INFO *RingInfo) -{ - return (void *)RingInfo->RingBuffer->Buffer; -} - - -/*++ - -Name: - GetRingBufferSize() - -Description: - Get the size of the ring buffer - ---*/ -static inline u32 -GetRingBufferSize(RING_BUFFER_INFO *RingInfo) -{ - return RingInfo->RingDataSize; -} - -/*++ - -Name: - GetRingBufferIndices() - -Description: - Get the read and write indices as u64 of the specified ring buffer - ---*/ -static inline u64 -GetRingBufferIndices(RING_BUFFER_INFO *RingInfo) -{ - return ((u64)RingInfo->RingBuffer->WriteIndex << 32) - || RingInfo->RingBuffer->ReadIndex; -} - - -/*++ - -Name: - DumpRingInfo() - -Description: - Dump out to console the ring buffer info - ---*/ -void DumpRingInfo(RING_BUFFER_INFO *RingInfo, char *Prefix) -{ - u32 bytesAvailToWrite; - u32 bytesAvailToRead; - - GetRingBufferAvailBytes(RingInfo, - &bytesAvailToRead, - &bytesAvailToWrite); - - DPRINT(VMBUS, - DEBUG_RING_LVL, - "%s <>", - Prefix, - RingInfo, - RingInfo->RingBuffer->Buffer, - bytesAvailToWrite, - bytesAvailToRead, - RingInfo->RingBuffer->ReadIndex, - RingInfo->RingBuffer->WriteIndex); -} - - -/* Internal routines */ - -static u32 -CopyToRingBuffer( - RING_BUFFER_INFO *RingInfo, - u32 StartWriteOffset, - void *Src, - u32 SrcLen); - -static u32 -CopyFromRingBuffer( - RING_BUFFER_INFO *RingInfo, - void *Dest, - u32 DestLen, - u32 StartReadOffset); - - - -/*++ - -Name: - RingBufferGetDebugInfo() - -Description: - Get various debug metrics for the specified ring buffer - ---*/ -void RingBufferGetDebugInfo(RING_BUFFER_INFO *RingInfo, - RING_BUFFER_DEBUG_INFO *DebugInfo) -{ - u32 bytesAvailToWrite; - u32 bytesAvailToRead; - - if (RingInfo->RingBuffer) { - GetRingBufferAvailBytes(RingInfo, - &bytesAvailToRead, - &bytesAvailToWrite); - - DebugInfo->BytesAvailToRead = bytesAvailToRead; - DebugInfo->BytesAvailToWrite = bytesAvailToWrite; - DebugInfo->CurrentReadIndex = RingInfo->RingBuffer->ReadIndex; - DebugInfo->CurrentWriteIndex = RingInfo->RingBuffer->WriteIndex; - DebugInfo->CurrentInterruptMask = RingInfo->RingBuffer->InterruptMask; - } -} - - -/*++ - -Name: - GetRingBufferInterruptMask() - -Description: - Get the interrupt mask for the specified ring buffer - ---*/ -u32 GetRingBufferInterruptMask(RING_BUFFER_INFO *rbi) -{ - return rbi->RingBuffer->InterruptMask; -} - -/*++ - -Name: - RingBufferInit() - -Description: - Initialize the ring buffer - ---*/ -int RingBufferInit(RING_BUFFER_INFO *RingInfo, void *Buffer, u32 BufferLen) -{ - if (sizeof(RING_BUFFER) != PAGE_SIZE) - return -EINVAL; - - memset(RingInfo, 0, sizeof(RING_BUFFER_INFO)); - - RingInfo->RingBuffer = (RING_BUFFER *)Buffer; - RingInfo->RingBuffer->ReadIndex = RingInfo->RingBuffer->WriteIndex = 0; - - RingInfo->RingSize = BufferLen; - RingInfo->RingDataSize = BufferLen - sizeof(RING_BUFFER); - - spin_lock_init(&RingInfo->ring_lock); - - return 0; -} - -/*++ - -Name: - RingBufferCleanup() - -Description: - Cleanup the ring buffer - ---*/ -void RingBufferCleanup(RING_BUFFER_INFO *RingInfo) -{ -} - -/*++ - -Name: - RingBufferWrite() - -Description: - Write to the ring buffer - ---*/ -int RingBufferWrite(RING_BUFFER_INFO *OutRingInfo, - struct scatterlist *sglist, u32 sgcount) -{ - int i = 0; - u32 byteAvailToWrite; - u32 byteAvailToRead; - u32 totalBytesToWrite = 0; - - struct scatterlist *sg; - volatile u32 nextWriteLocation; - u64 prevIndices = 0; - unsigned long flags; - - DPRINT_ENTER(VMBUS); - - for_each_sg(sglist, sg, sgcount, i) - { - totalBytesToWrite += sg->length; - } - - totalBytesToWrite += sizeof(u64); - - spin_lock_irqsave(&OutRingInfo->ring_lock, flags); - - GetRingBufferAvailBytes(OutRingInfo, - &byteAvailToRead, - &byteAvailToWrite); - - DPRINT_DBG(VMBUS, "Writing %u bytes...", totalBytesToWrite); - - /* DumpRingInfo(OutRingInfo, "BEFORE "); */ - - /* If there is only room for the packet, assume it is full. */ - /* Otherwise, the next time around, we think the ring buffer */ - /* is empty since the read index == write index */ - if (byteAvailToWrite <= totalBytesToWrite) { - DPRINT_DBG(VMBUS, - "No more space left on outbound ring buffer " - "(needed %u, avail %u)", - totalBytesToWrite, - byteAvailToWrite); - - spin_unlock_irqrestore(&OutRingInfo->ring_lock, flags); - - DPRINT_EXIT(VMBUS); - - return -1; - } - - /* Write to the ring buffer */ - nextWriteLocation = GetNextWriteLocation(OutRingInfo); - - for_each_sg(sglist, sg, sgcount, i) - { - nextWriteLocation = CopyToRingBuffer(OutRingInfo, - nextWriteLocation, - sg_virt(sg), - sg->length); - } - - /* Set previous packet start */ - prevIndices = GetRingBufferIndices(OutRingInfo); - - nextWriteLocation = CopyToRingBuffer(OutRingInfo, - nextWriteLocation, - &prevIndices, - sizeof(u64)); - - /* Make sure we flush all writes before updating the writeIndex */ - mb(); - - /* Now, update the write location */ - SetNextWriteLocation(OutRingInfo, nextWriteLocation); - - /* DumpRingInfo(OutRingInfo, "AFTER "); */ - - spin_unlock_irqrestore(&OutRingInfo->ring_lock, flags); - - DPRINT_EXIT(VMBUS); - - return 0; -} - - -/*++ - -Name: - RingBufferPeek() - -Description: - Read without advancing the read index - ---*/ -int RingBufferPeek(RING_BUFFER_INFO *InRingInfo, void *Buffer, u32 BufferLen) -{ - u32 bytesAvailToWrite; - u32 bytesAvailToRead; - u32 nextReadLocation = 0; - unsigned long flags; - - spin_lock_irqsave(&InRingInfo->ring_lock, flags); - - GetRingBufferAvailBytes(InRingInfo, - &bytesAvailToRead, - &bytesAvailToWrite); - - /* Make sure there is something to read */ - if (bytesAvailToRead < BufferLen) { - /* DPRINT_DBG(VMBUS, - "got callback but not enough to read " - "!!", - bytesAvailToRead, - BufferLen); */ - - spin_unlock_irqrestore(&InRingInfo->ring_lock, flags); - - return -1; - } - - /* Convert to byte offset */ - nextReadLocation = GetNextReadLocation(InRingInfo); - - nextReadLocation = CopyFromRingBuffer(InRingInfo, - Buffer, - BufferLen, - nextReadLocation); - - spin_unlock_irqrestore(&InRingInfo->ring_lock, flags); - - return 0; -} - - -/*++ - -Name: - RingBufferRead() - -Description: - Read and advance the read index - ---*/ -int RingBufferRead(RING_BUFFER_INFO *InRingInfo, void *Buffer, - u32 BufferLen, u32 Offset) -{ - u32 bytesAvailToWrite; - u32 bytesAvailToRead; - u32 nextReadLocation = 0; - u64 prevIndices = 0; - unsigned long flags; - - if (BufferLen <= 0) - return -EINVAL; - - spin_lock_irqsave(&InRingInfo->ring_lock, flags); - - GetRingBufferAvailBytes(InRingInfo, - &bytesAvailToRead, - &bytesAvailToWrite); - - DPRINT_DBG(VMBUS, "Reading %u bytes...", BufferLen); - - /* DumpRingInfo(InRingInfo, "BEFORE "); */ - - /* Make sure there is something to read */ - if (bytesAvailToRead < BufferLen) { - DPRINT_DBG(VMBUS, - "got callback but not enough to read " - "!!", - bytesAvailToRead, - BufferLen); - - spin_unlock_irqrestore(&InRingInfo->ring_lock, flags); - - return -1; - } - - nextReadLocation = GetNextReadLocationWithOffset(InRingInfo, Offset); - - nextReadLocation = CopyFromRingBuffer(InRingInfo, - Buffer, - BufferLen, - nextReadLocation); - - nextReadLocation = CopyFromRingBuffer(InRingInfo, - &prevIndices, - sizeof(u64), - nextReadLocation); - - /* Make sure all reads are done before we update the read index since */ - /* the writer may start writing to the read area once the read index */ - /*is updated */ - mb(); - - /* Update the read index */ - SetNextReadLocation(InRingInfo, nextReadLocation); - - /* DumpRingInfo(InRingInfo, "AFTER "); */ - - spin_unlock_irqrestore(&InRingInfo->ring_lock, flags); - - return 0; -} - - -/*++ - -Name: - CopyToRingBuffer() - -Description: - Helper routine to copy from source to ring buffer. - Assume there is enough room. Handles wrap-around in dest case only!! - ---*/ -static u32 -CopyToRingBuffer( - RING_BUFFER_INFO *RingInfo, - u32 StartWriteOffset, - void *Src, - u32 SrcLen) -{ - void *ringBuffer = GetRingBuffer(RingInfo); - u32 ringBufferSize = GetRingBufferSize(RingInfo); - u32 fragLen; - - /* wrap-around detected! */ - if (SrcLen > ringBufferSize - StartWriteOffset) { - DPRINT_DBG(VMBUS, "wrap-around detected!"); - - fragLen = ringBufferSize - StartWriteOffset; - memcpy(ringBuffer + StartWriteOffset, Src, fragLen); - memcpy(ringBuffer, Src + fragLen, SrcLen - fragLen); - } else - memcpy(ringBuffer + StartWriteOffset, Src, SrcLen); - - StartWriteOffset += SrcLen; - StartWriteOffset %= ringBufferSize; - - return StartWriteOffset; -} - - -/*++ - -Name: - CopyFromRingBuffer() - -Description: - Helper routine to copy to source from ring buffer. - Assume there is enough room. Handles wrap-around in src case only!! - ---*/ -static u32 -CopyFromRingBuffer( - RING_BUFFER_INFO *RingInfo, - void *Dest, - u32 DestLen, - u32 StartReadOffset) -{ - void *ringBuffer = GetRingBuffer(RingInfo); - u32 ringBufferSize = GetRingBufferSize(RingInfo); - - u32 fragLen; - - /* wrap-around detected at the src */ - if (DestLen > ringBufferSize - StartReadOffset) { - DPRINT_DBG(VMBUS, "src wrap-around detected!"); - - fragLen = ringBufferSize - StartReadOffset; - - memcpy(Dest, ringBuffer + StartReadOffset, fragLen); - memcpy(Dest + fragLen, ringBuffer, DestLen - fragLen); - } else - - memcpy(Dest, ringBuffer + StartReadOffset, DestLen); - - - StartReadOffset += DestLen; - StartReadOffset %= ringBufferSize; - - return StartReadOffset; -} - - -/* eof */ diff --git a/drivers/staging/hv/RingBuffer.h b/drivers/staging/hv/RingBuffer.h deleted file mode 100644 index 6202157e145d..000000000000 --- a/drivers/staging/hv/RingBuffer.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ - - -#ifndef _RING_BUFFER_H_ -#define _RING_BUFFER_H_ - -#include - -typedef struct _RING_BUFFER { - /* Offset in bytes from the start of ring data below */ - volatile u32 WriteIndex; - - /* Offset in bytes from the start of ring data below */ - volatile u32 ReadIndex; - - volatile u32 InterruptMask; - - /* Pad it to PAGE_SIZE so that data starts on page boundary */ - u8 Reserved[4084]; - - /* NOTE: - * The InterruptMask field is used only for channels but since our - * vmbus connection also uses this data structure and its data starts - * here, we commented out this field. - */ - /* volatile u32 InterruptMask; */ - - /* - * Ring data starts here + RingDataStartOffset - * !!! DO NOT place any fields below this !!! - */ - u8 Buffer[0]; -} __attribute__((packed)) RING_BUFFER; - -typedef struct _RING_BUFFER_INFO { - RING_BUFFER *RingBuffer; - u32 RingSize; /* Include the shared header */ - spinlock_t ring_lock; - - u32 RingDataSize; /* < ringSize */ - u32 RingDataStartOffset; - -} RING_BUFFER_INFO; - -typedef struct _RING_BUFFER_DEBUG_INFO { - u32 CurrentInterruptMask; - u32 CurrentReadIndex; - u32 CurrentWriteIndex; - u32 BytesAvailToRead; - u32 BytesAvailToWrite; -} RING_BUFFER_DEBUG_INFO; - - - -/* Interface */ - - -int RingBufferInit(RING_BUFFER_INFO *RingInfo, void *Buffer, u32 BufferLen); - -void RingBufferCleanup(RING_BUFFER_INFO *RingInfo); - -int RingBufferWrite(RING_BUFFER_INFO *RingInfo, - struct scatterlist *sglist, - u32 sgcount); - -int RingBufferPeek(RING_BUFFER_INFO *RingInfo, void *Buffer, u32 BufferLen); - -int RingBufferRead(RING_BUFFER_INFO *RingInfo, - void *Buffer, - u32 BufferLen, - u32 Offset); - -u32 GetRingBufferInterruptMask(RING_BUFFER_INFO *RingInfo); - -void DumpRingInfo(RING_BUFFER_INFO *RingInfo, char *Prefix); - -void RingBufferGetDebugInfo(RING_BUFFER_INFO *RingInfo, - RING_BUFFER_DEBUG_INFO *DebugInfo); - -#endif /* _RING_BUFFER_H_ */ diff --git a/drivers/staging/hv/VmbusPrivate.h b/drivers/staging/hv/VmbusPrivate.h index f03db0b6e887..d73baff99a7e 100644 --- a/drivers/staging/hv/VmbusPrivate.h +++ b/drivers/staging/hv/VmbusPrivate.h @@ -30,7 +30,7 @@ #include "channel.h" #include "ChannelMgmt.h" #include "ChannelInterface.h" -#include "RingBuffer.h" +#include "ring_buffer.h" #include diff --git a/drivers/staging/hv/ring_buffer.c b/drivers/staging/hv/ring_buffer.c new file mode 100644 index 000000000000..ae2a10e24d92 --- /dev/null +++ b/drivers/staging/hv/ring_buffer.c @@ -0,0 +1,627 @@ +/* + * + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + * + */ + +#include +#include +#include "osd.h" +#include "logging.h" +#include "ring_buffer.h" + + +/* #defines */ + + +/* Amount of space to write to */ +#define BYTES_AVAIL_TO_WRITE(r, w, z) ((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w)) + + +/*++ + +Name: + GetRingBufferAvailBytes() + +Description: + Get number of bytes available to read and to write to + for the specified ring buffer + +--*/ +static inline void +GetRingBufferAvailBytes(RING_BUFFER_INFO *rbi, u32 *read, u32 *write) +{ + u32 read_loc, write_loc; + + /* Capture the read/write indices before they changed */ + read_loc = rbi->RingBuffer->ReadIndex; + write_loc = rbi->RingBuffer->WriteIndex; + + *write = BYTES_AVAIL_TO_WRITE(read_loc, write_loc, rbi->RingDataSize); + *read = rbi->RingDataSize - *write; +} + +/*++ + +Name: + GetNextWriteLocation() + +Description: + Get the next write location for the specified ring buffer + +--*/ +static inline u32 +GetNextWriteLocation(RING_BUFFER_INFO *RingInfo) +{ + u32 next = RingInfo->RingBuffer->WriteIndex; + + /* ASSERT(next < RingInfo->RingDataSize); */ + + return next; +} + +/*++ + +Name: + SetNextWriteLocation() + +Description: + Set the next write location for the specified ring buffer + +--*/ +static inline void +SetNextWriteLocation(RING_BUFFER_INFO *RingInfo, u32 NextWriteLocation) +{ + RingInfo->RingBuffer->WriteIndex = NextWriteLocation; +} + +/*++ + +Name: + GetNextReadLocation() + +Description: + Get the next read location for the specified ring buffer + +--*/ +static inline u32 +GetNextReadLocation(RING_BUFFER_INFO *RingInfo) +{ + u32 next = RingInfo->RingBuffer->ReadIndex; + + /* ASSERT(next < RingInfo->RingDataSize); */ + + return next; +} + +/*++ + +Name: + GetNextReadLocationWithOffset() + +Description: + Get the next read location + offset for the specified ring buffer. + This allows the caller to skip + +--*/ +static inline u32 +GetNextReadLocationWithOffset(RING_BUFFER_INFO *RingInfo, u32 Offset) +{ + u32 next = RingInfo->RingBuffer->ReadIndex; + + /* ASSERT(next < RingInfo->RingDataSize); */ + next += Offset; + next %= RingInfo->RingDataSize; + + return next; +} + +/*++ + +Name: + SetNextReadLocation() + +Description: + Set the next read location for the specified ring buffer + +--*/ +static inline void +SetNextReadLocation(RING_BUFFER_INFO *RingInfo, u32 NextReadLocation) +{ + RingInfo->RingBuffer->ReadIndex = NextReadLocation; +} + + +/*++ + +Name: + GetRingBuffer() + +Description: + Get the start of the ring buffer + +--*/ +static inline void * +GetRingBuffer(RING_BUFFER_INFO *RingInfo) +{ + return (void *)RingInfo->RingBuffer->Buffer; +} + + +/*++ + +Name: + GetRingBufferSize() + +Description: + Get the size of the ring buffer + +--*/ +static inline u32 +GetRingBufferSize(RING_BUFFER_INFO *RingInfo) +{ + return RingInfo->RingDataSize; +} + +/*++ + +Name: + GetRingBufferIndices() + +Description: + Get the read and write indices as u64 of the specified ring buffer + +--*/ +static inline u64 +GetRingBufferIndices(RING_BUFFER_INFO *RingInfo) +{ + return ((u64)RingInfo->RingBuffer->WriteIndex << 32) + || RingInfo->RingBuffer->ReadIndex; +} + + +/*++ + +Name: + DumpRingInfo() + +Description: + Dump out to console the ring buffer info + +--*/ +void DumpRingInfo(RING_BUFFER_INFO *RingInfo, char *Prefix) +{ + u32 bytesAvailToWrite; + u32 bytesAvailToRead; + + GetRingBufferAvailBytes(RingInfo, + &bytesAvailToRead, + &bytesAvailToWrite); + + DPRINT(VMBUS, + DEBUG_RING_LVL, + "%s <>", + Prefix, + RingInfo, + RingInfo->RingBuffer->Buffer, + bytesAvailToWrite, + bytesAvailToRead, + RingInfo->RingBuffer->ReadIndex, + RingInfo->RingBuffer->WriteIndex); +} + + +/* Internal routines */ + +static u32 +CopyToRingBuffer( + RING_BUFFER_INFO *RingInfo, + u32 StartWriteOffset, + void *Src, + u32 SrcLen); + +static u32 +CopyFromRingBuffer( + RING_BUFFER_INFO *RingInfo, + void *Dest, + u32 DestLen, + u32 StartReadOffset); + + + +/*++ + +Name: + RingBufferGetDebugInfo() + +Description: + Get various debug metrics for the specified ring buffer + +--*/ +void RingBufferGetDebugInfo(RING_BUFFER_INFO *RingInfo, + RING_BUFFER_DEBUG_INFO *DebugInfo) +{ + u32 bytesAvailToWrite; + u32 bytesAvailToRead; + + if (RingInfo->RingBuffer) { + GetRingBufferAvailBytes(RingInfo, + &bytesAvailToRead, + &bytesAvailToWrite); + + DebugInfo->BytesAvailToRead = bytesAvailToRead; + DebugInfo->BytesAvailToWrite = bytesAvailToWrite; + DebugInfo->CurrentReadIndex = RingInfo->RingBuffer->ReadIndex; + DebugInfo->CurrentWriteIndex = RingInfo->RingBuffer->WriteIndex; + DebugInfo->CurrentInterruptMask = RingInfo->RingBuffer->InterruptMask; + } +} + + +/*++ + +Name: + GetRingBufferInterruptMask() + +Description: + Get the interrupt mask for the specified ring buffer + +--*/ +u32 GetRingBufferInterruptMask(RING_BUFFER_INFO *rbi) +{ + return rbi->RingBuffer->InterruptMask; +} + +/*++ + +Name: + RingBufferInit() + +Description: + Initialize the ring buffer + +--*/ +int RingBufferInit(RING_BUFFER_INFO *RingInfo, void *Buffer, u32 BufferLen) +{ + if (sizeof(RING_BUFFER) != PAGE_SIZE) + return -EINVAL; + + memset(RingInfo, 0, sizeof(RING_BUFFER_INFO)); + + RingInfo->RingBuffer = (RING_BUFFER *)Buffer; + RingInfo->RingBuffer->ReadIndex = RingInfo->RingBuffer->WriteIndex = 0; + + RingInfo->RingSize = BufferLen; + RingInfo->RingDataSize = BufferLen - sizeof(RING_BUFFER); + + spin_lock_init(&RingInfo->ring_lock); + + return 0; +} + +/*++ + +Name: + RingBufferCleanup() + +Description: + Cleanup the ring buffer + +--*/ +void RingBufferCleanup(RING_BUFFER_INFO *RingInfo) +{ +} + +/*++ + +Name: + RingBufferWrite() + +Description: + Write to the ring buffer + +--*/ +int RingBufferWrite(RING_BUFFER_INFO *OutRingInfo, + struct scatterlist *sglist, u32 sgcount) +{ + int i = 0; + u32 byteAvailToWrite; + u32 byteAvailToRead; + u32 totalBytesToWrite = 0; + + struct scatterlist *sg; + volatile u32 nextWriteLocation; + u64 prevIndices = 0; + unsigned long flags; + + DPRINT_ENTER(VMBUS); + + for_each_sg(sglist, sg, sgcount, i) + { + totalBytesToWrite += sg->length; + } + + totalBytesToWrite += sizeof(u64); + + spin_lock_irqsave(&OutRingInfo->ring_lock, flags); + + GetRingBufferAvailBytes(OutRingInfo, + &byteAvailToRead, + &byteAvailToWrite); + + DPRINT_DBG(VMBUS, "Writing %u bytes...", totalBytesToWrite); + + /* DumpRingInfo(OutRingInfo, "BEFORE "); */ + + /* If there is only room for the packet, assume it is full. */ + /* Otherwise, the next time around, we think the ring buffer */ + /* is empty since the read index == write index */ + if (byteAvailToWrite <= totalBytesToWrite) { + DPRINT_DBG(VMBUS, + "No more space left on outbound ring buffer " + "(needed %u, avail %u)", + totalBytesToWrite, + byteAvailToWrite); + + spin_unlock_irqrestore(&OutRingInfo->ring_lock, flags); + + DPRINT_EXIT(VMBUS); + + return -1; + } + + /* Write to the ring buffer */ + nextWriteLocation = GetNextWriteLocation(OutRingInfo); + + for_each_sg(sglist, sg, sgcount, i) + { + nextWriteLocation = CopyToRingBuffer(OutRingInfo, + nextWriteLocation, + sg_virt(sg), + sg->length); + } + + /* Set previous packet start */ + prevIndices = GetRingBufferIndices(OutRingInfo); + + nextWriteLocation = CopyToRingBuffer(OutRingInfo, + nextWriteLocation, + &prevIndices, + sizeof(u64)); + + /* Make sure we flush all writes before updating the writeIndex */ + mb(); + + /* Now, update the write location */ + SetNextWriteLocation(OutRingInfo, nextWriteLocation); + + /* DumpRingInfo(OutRingInfo, "AFTER "); */ + + spin_unlock_irqrestore(&OutRingInfo->ring_lock, flags); + + DPRINT_EXIT(VMBUS); + + return 0; +} + + +/*++ + +Name: + RingBufferPeek() + +Description: + Read without advancing the read index + +--*/ +int RingBufferPeek(RING_BUFFER_INFO *InRingInfo, void *Buffer, u32 BufferLen) +{ + u32 bytesAvailToWrite; + u32 bytesAvailToRead; + u32 nextReadLocation = 0; + unsigned long flags; + + spin_lock_irqsave(&InRingInfo->ring_lock, flags); + + GetRingBufferAvailBytes(InRingInfo, + &bytesAvailToRead, + &bytesAvailToWrite); + + /* Make sure there is something to read */ + if (bytesAvailToRead < BufferLen) { + /* DPRINT_DBG(VMBUS, + "got callback but not enough to read " + "!!", + bytesAvailToRead, + BufferLen); */ + + spin_unlock_irqrestore(&InRingInfo->ring_lock, flags); + + return -1; + } + + /* Convert to byte offset */ + nextReadLocation = GetNextReadLocation(InRingInfo); + + nextReadLocation = CopyFromRingBuffer(InRingInfo, + Buffer, + BufferLen, + nextReadLocation); + + spin_unlock_irqrestore(&InRingInfo->ring_lock, flags); + + return 0; +} + + +/*++ + +Name: + RingBufferRead() + +Description: + Read and advance the read index + +--*/ +int RingBufferRead(RING_BUFFER_INFO *InRingInfo, void *Buffer, + u32 BufferLen, u32 Offset) +{ + u32 bytesAvailToWrite; + u32 bytesAvailToRead; + u32 nextReadLocation = 0; + u64 prevIndices = 0; + unsigned long flags; + + if (BufferLen <= 0) + return -EINVAL; + + spin_lock_irqsave(&InRingInfo->ring_lock, flags); + + GetRingBufferAvailBytes(InRingInfo, + &bytesAvailToRead, + &bytesAvailToWrite); + + DPRINT_DBG(VMBUS, "Reading %u bytes...", BufferLen); + + /* DumpRingInfo(InRingInfo, "BEFORE "); */ + + /* Make sure there is something to read */ + if (bytesAvailToRead < BufferLen) { + DPRINT_DBG(VMBUS, + "got callback but not enough to read " + "!!", + bytesAvailToRead, + BufferLen); + + spin_unlock_irqrestore(&InRingInfo->ring_lock, flags); + + return -1; + } + + nextReadLocation = GetNextReadLocationWithOffset(InRingInfo, Offset); + + nextReadLocation = CopyFromRingBuffer(InRingInfo, + Buffer, + BufferLen, + nextReadLocation); + + nextReadLocation = CopyFromRingBuffer(InRingInfo, + &prevIndices, + sizeof(u64), + nextReadLocation); + + /* Make sure all reads are done before we update the read index since */ + /* the writer may start writing to the read area once the read index */ + /*is updated */ + mb(); + + /* Update the read index */ + SetNextReadLocation(InRingInfo, nextReadLocation); + + /* DumpRingInfo(InRingInfo, "AFTER "); */ + + spin_unlock_irqrestore(&InRingInfo->ring_lock, flags); + + return 0; +} + + +/*++ + +Name: + CopyToRingBuffer() + +Description: + Helper routine to copy from source to ring buffer. + Assume there is enough room. Handles wrap-around in dest case only!! + +--*/ +static u32 +CopyToRingBuffer( + RING_BUFFER_INFO *RingInfo, + u32 StartWriteOffset, + void *Src, + u32 SrcLen) +{ + void *ringBuffer = GetRingBuffer(RingInfo); + u32 ringBufferSize = GetRingBufferSize(RingInfo); + u32 fragLen; + + /* wrap-around detected! */ + if (SrcLen > ringBufferSize - StartWriteOffset) { + DPRINT_DBG(VMBUS, "wrap-around detected!"); + + fragLen = ringBufferSize - StartWriteOffset; + memcpy(ringBuffer + StartWriteOffset, Src, fragLen); + memcpy(ringBuffer, Src + fragLen, SrcLen - fragLen); + } else + memcpy(ringBuffer + StartWriteOffset, Src, SrcLen); + + StartWriteOffset += SrcLen; + StartWriteOffset %= ringBufferSize; + + return StartWriteOffset; +} + + +/*++ + +Name: + CopyFromRingBuffer() + +Description: + Helper routine to copy to source from ring buffer. + Assume there is enough room. Handles wrap-around in src case only!! + +--*/ +static u32 +CopyFromRingBuffer( + RING_BUFFER_INFO *RingInfo, + void *Dest, + u32 DestLen, + u32 StartReadOffset) +{ + void *ringBuffer = GetRingBuffer(RingInfo); + u32 ringBufferSize = GetRingBufferSize(RingInfo); + + u32 fragLen; + + /* wrap-around detected at the src */ + if (DestLen > ringBufferSize - StartReadOffset) { + DPRINT_DBG(VMBUS, "src wrap-around detected!"); + + fragLen = ringBufferSize - StartReadOffset; + + memcpy(Dest, ringBuffer + StartReadOffset, fragLen); + memcpy(Dest + fragLen, ringBuffer, DestLen - fragLen); + } else + + memcpy(Dest, ringBuffer + StartReadOffset, DestLen); + + + StartReadOffset += DestLen; + StartReadOffset %= ringBufferSize; + + return StartReadOffset; +} + + +/* eof */ diff --git a/drivers/staging/hv/ring_buffer.h b/drivers/staging/hv/ring_buffer.h new file mode 100644 index 000000000000..6202157e145d --- /dev/null +++ b/drivers/staging/hv/ring_buffer.h @@ -0,0 +1,101 @@ +/* + * + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + * + */ + + +#ifndef _RING_BUFFER_H_ +#define _RING_BUFFER_H_ + +#include + +typedef struct _RING_BUFFER { + /* Offset in bytes from the start of ring data below */ + volatile u32 WriteIndex; + + /* Offset in bytes from the start of ring data below */ + volatile u32 ReadIndex; + + volatile u32 InterruptMask; + + /* Pad it to PAGE_SIZE so that data starts on page boundary */ + u8 Reserved[4084]; + + /* NOTE: + * The InterruptMask field is used only for channels but since our + * vmbus connection also uses this data structure and its data starts + * here, we commented out this field. + */ + /* volatile u32 InterruptMask; */ + + /* + * Ring data starts here + RingDataStartOffset + * !!! DO NOT place any fields below this !!! + */ + u8 Buffer[0]; +} __attribute__((packed)) RING_BUFFER; + +typedef struct _RING_BUFFER_INFO { + RING_BUFFER *RingBuffer; + u32 RingSize; /* Include the shared header */ + spinlock_t ring_lock; + + u32 RingDataSize; /* < ringSize */ + u32 RingDataStartOffset; + +} RING_BUFFER_INFO; + +typedef struct _RING_BUFFER_DEBUG_INFO { + u32 CurrentInterruptMask; + u32 CurrentReadIndex; + u32 CurrentWriteIndex; + u32 BytesAvailToRead; + u32 BytesAvailToWrite; +} RING_BUFFER_DEBUG_INFO; + + + +/* Interface */ + + +int RingBufferInit(RING_BUFFER_INFO *RingInfo, void *Buffer, u32 BufferLen); + +void RingBufferCleanup(RING_BUFFER_INFO *RingInfo); + +int RingBufferWrite(RING_BUFFER_INFO *RingInfo, + struct scatterlist *sglist, + u32 sgcount); + +int RingBufferPeek(RING_BUFFER_INFO *RingInfo, void *Buffer, u32 BufferLen); + +int RingBufferRead(RING_BUFFER_INFO *RingInfo, + void *Buffer, + u32 BufferLen, + u32 Offset); + +u32 GetRingBufferInterruptMask(RING_BUFFER_INFO *RingInfo); + +void DumpRingInfo(RING_BUFFER_INFO *RingInfo, char *Prefix); + +void RingBufferGetDebugInfo(RING_BUFFER_INFO *RingInfo, + RING_BUFFER_DEBUG_INFO *DebugInfo); + +#endif /* _RING_BUFFER_H_ */ -- cgit v1.2.3 From 376a045f3a90ce4ca02aa9c32ea3c81332c10ecc Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:24:25 -0700 Subject: Staging: hv: rename BlkVsc.c to blkvsc.c Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/BlkVsc.c | 112 -------------------------------------------- drivers/staging/hv/Makefile | 2 +- drivers/staging/hv/blkvsc.c | 112 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 113 deletions(-) delete mode 100644 drivers/staging/hv/BlkVsc.c create mode 100644 drivers/staging/hv/blkvsc.c (limited to 'drivers') diff --git a/drivers/staging/hv/BlkVsc.c b/drivers/staging/hv/BlkVsc.c deleted file mode 100644 index b2f600551f10..000000000000 --- a/drivers/staging/hv/BlkVsc.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ -#include -#include -#include "osd.h" -#include "StorVsc.c" - -static const char *gBlkDriverName = "blkvsc"; - -/* {32412632-86cb-44a2-9b5c-50d1417354f5} */ -static const struct hv_guid gBlkVscDeviceType = { - .data = { - 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, - 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 - } -}; - -static int BlkVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) -{ - struct storvsc_device_info *deviceInfo; - int ret = 0; - - DPRINT_ENTER(BLKVSC); - - deviceInfo = (struct storvsc_device_info *)AdditionalInfo; - - ret = StorVscOnDeviceAdd(Device, AdditionalInfo); - if (ret != 0) { - DPRINT_EXIT(BLKVSC); - return ret; - } - - /* - * We need to use the device instance guid to set the path and target - * id. For IDE devices, the device instance id is formatted as - * * - - 8899 - 000000000000. - */ - deviceInfo->PathId = Device->deviceInstance.data[3] << 24 | - Device->deviceInstance.data[2] << 16 | - Device->deviceInstance.data[1] << 8 | - Device->deviceInstance.data[0]; - - deviceInfo->TargetId = Device->deviceInstance.data[5] << 8 | - Device->deviceInstance.data[4]; - - DPRINT_EXIT(BLKVSC); - - return ret; -} - -int BlkVscInitialize(struct hv_driver *Driver) -{ - struct storvsc_driver_object *storDriver; - int ret = 0; - - DPRINT_ENTER(BLKVSC); - - storDriver = (struct storvsc_driver_object *)Driver; - - /* Make sure we are at least 2 pages since 1 page is used for control */ - /* ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1)); */ - - Driver->name = gBlkDriverName; - memcpy(&Driver->deviceType, &gBlkVscDeviceType, sizeof(struct hv_guid)); - - storDriver->RequestExtSize = sizeof(struct storvsc_request_extension); - - /* - * Divide the ring buffer data size (which is 1 page less than the ring - * buffer size since that page is reserved for the ring buffer indices) - * by the max request size (which is - * VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER + struct vstor_packet + u64) - */ - storDriver->MaxOutstandingRequestsPerChannel = - ((storDriver->RingBufferSize - PAGE_SIZE) / - ALIGN_UP(MAX_MULTIPAGE_BUFFER_PACKET + - sizeof(struct vstor_packet) + sizeof(u64), - sizeof(u64))); - - DPRINT_INFO(BLKVSC, "max io outstd %u", - storDriver->MaxOutstandingRequestsPerChannel); - - /* Setup the dispatch table */ - storDriver->Base.OnDeviceAdd = BlkVscOnDeviceAdd; - storDriver->Base.OnDeviceRemove = StorVscOnDeviceRemove; - storDriver->Base.OnCleanup = StorVscOnCleanup; - storDriver->OnIORequest = StorVscOnIORequest; - - DPRINT_EXIT(BLKVSC); - - return ret; -} diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index faa8db1d86c0..6e8e8e82263a 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -8,5 +8,5 @@ hv_vmbus-objs := vmbus_drv.o osd.o \ Vmbus.o hv.o connection.o channel.o \ ChannelMgmt.o ChannelInterface.o ring_buffer.o hv_storvsc-objs := storvsc_drv.o StorVsc.o -hv_blkvsc-objs := blkvsc_drv.o BlkVsc.o +hv_blkvsc-objs := blkvsc_drv.o blkvsc.o hv_netvsc-objs := netvsc_drv.o NetVsc.o RndisFilter.o diff --git a/drivers/staging/hv/blkvsc.c b/drivers/staging/hv/blkvsc.c new file mode 100644 index 000000000000..b2f600551f10 --- /dev/null +++ b/drivers/staging/hv/blkvsc.c @@ -0,0 +1,112 @@ +/* + * + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + * + */ +#include +#include +#include "osd.h" +#include "StorVsc.c" + +static const char *gBlkDriverName = "blkvsc"; + +/* {32412632-86cb-44a2-9b5c-50d1417354f5} */ +static const struct hv_guid gBlkVscDeviceType = { + .data = { + 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, + 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 + } +}; + +static int BlkVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) +{ + struct storvsc_device_info *deviceInfo; + int ret = 0; + + DPRINT_ENTER(BLKVSC); + + deviceInfo = (struct storvsc_device_info *)AdditionalInfo; + + ret = StorVscOnDeviceAdd(Device, AdditionalInfo); + if (ret != 0) { + DPRINT_EXIT(BLKVSC); + return ret; + } + + /* + * We need to use the device instance guid to set the path and target + * id. For IDE devices, the device instance id is formatted as + * * - - 8899 - 000000000000. + */ + deviceInfo->PathId = Device->deviceInstance.data[3] << 24 | + Device->deviceInstance.data[2] << 16 | + Device->deviceInstance.data[1] << 8 | + Device->deviceInstance.data[0]; + + deviceInfo->TargetId = Device->deviceInstance.data[5] << 8 | + Device->deviceInstance.data[4]; + + DPRINT_EXIT(BLKVSC); + + return ret; +} + +int BlkVscInitialize(struct hv_driver *Driver) +{ + struct storvsc_driver_object *storDriver; + int ret = 0; + + DPRINT_ENTER(BLKVSC); + + storDriver = (struct storvsc_driver_object *)Driver; + + /* Make sure we are at least 2 pages since 1 page is used for control */ + /* ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1)); */ + + Driver->name = gBlkDriverName; + memcpy(&Driver->deviceType, &gBlkVscDeviceType, sizeof(struct hv_guid)); + + storDriver->RequestExtSize = sizeof(struct storvsc_request_extension); + + /* + * Divide the ring buffer data size (which is 1 page less than the ring + * buffer size since that page is reserved for the ring buffer indices) + * by the max request size (which is + * VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER + struct vstor_packet + u64) + */ + storDriver->MaxOutstandingRequestsPerChannel = + ((storDriver->RingBufferSize - PAGE_SIZE) / + ALIGN_UP(MAX_MULTIPAGE_BUFFER_PACKET + + sizeof(struct vstor_packet) + sizeof(u64), + sizeof(u64))); + + DPRINT_INFO(BLKVSC, "max io outstd %u", + storDriver->MaxOutstandingRequestsPerChannel); + + /* Setup the dispatch table */ + storDriver->Base.OnDeviceAdd = BlkVscOnDeviceAdd; + storDriver->Base.OnDeviceRemove = StorVscOnDeviceRemove; + storDriver->Base.OnCleanup = StorVscOnCleanup; + storDriver->OnIORequest = StorVscOnIORequest; + + DPRINT_EXIT(BLKVSC); + + return ret; +} -- cgit v1.2.3 From 98109c5a961ba77e0910a5bec66bd57a673fad52 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:25:23 -0700 Subject: Staging: hv: rename Vmbus.c to vmbus.c Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Makefile | 2 +- drivers/staging/hv/Vmbus.c | 312 -------------------------------------------- drivers/staging/hv/vmbus.c | 312 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 313 insertions(+), 313 deletions(-) delete mode 100644 drivers/staging/hv/Vmbus.c create mode 100644 drivers/staging/hv/vmbus.c (limited to 'drivers') diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index 6e8e8e82263a..f58a4e7bf6d9 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_HYPERV_NET) += hv_netvsc.o obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o hv_vmbus-objs := vmbus_drv.o osd.o \ - Vmbus.o hv.o connection.o channel.o \ + vmbus.o hv.o connection.o channel.o \ ChannelMgmt.o ChannelInterface.o ring_buffer.o hv_storvsc-objs := storvsc_drv.o StorVsc.o hv_blkvsc-objs := blkvsc_drv.o blkvsc.o diff --git a/drivers/staging/hv/Vmbus.c b/drivers/staging/hv/Vmbus.c deleted file mode 100644 index 90b14beec3aa..000000000000 --- a/drivers/staging/hv/Vmbus.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ -#include -#include -#include -#include "osd.h" -#include "logging.h" -#include "VersionInfo.h" -#include "VmbusPrivate.h" - -static const char *gDriverName = "vmbus"; - -/* - * Windows vmbus does not defined this. - * We defined this to be consistent with other devices - */ -/* {c5295816-f63a-4d5f-8d1a-4daf999ca185} */ -static const struct hv_guid gVmbusDeviceType = { - .data = { - 0x16, 0x58, 0x29, 0xc5, 0x3a, 0xf6, 0x5f, 0x4d, - 0x8d, 0x1a, 0x4d, 0xaf, 0x99, 0x9c, 0xa1, 0x85 - } -}; - -/* {ac3760fc-9adf-40aa-9427-a70ed6de95c5} */ -static const struct hv_guid gVmbusDeviceId = { - .data = { - 0xfc, 0x60, 0x37, 0xac, 0xdf, 0x9a, 0xaa, 0x40, - 0x94, 0x27, 0xa7, 0x0e, 0xd6, 0xde, 0x95, 0xc5 - } -}; - -static struct hv_driver *gDriver; /* vmbus driver object */ -static struct hv_device *gDevice; /* vmbus root device */ - -/* - * VmbusGetChannelOffers - Retrieve the channel offers from the parent partition - */ -static void VmbusGetChannelOffers(void) -{ - DPRINT_ENTER(VMBUS); - VmbusChannelRequestOffers(); - DPRINT_EXIT(VMBUS); -} - -/* - * VmbusGetChannelInterface - Get the channel interface - */ -static void VmbusGetChannelInterface(struct vmbus_channel_interface *Interface) -{ - GetChannelInterface(Interface); -} - -/* - * VmbusGetChannelInfo - Get the device info for the specified device object - */ -static void VmbusGetChannelInfo(struct hv_device *DeviceObject, - struct hv_device_info *DeviceInfo) -{ - GetChannelInfo(DeviceObject, DeviceInfo); -} - -/* - * VmbusCreateChildDevice - Creates the child device on the bus that represents the channel offer - */ -struct hv_device *VmbusChildDeviceCreate(struct hv_guid *DeviceType, - struct hv_guid *DeviceInstance, - void *Context) -{ - struct vmbus_driver *vmbusDriver = (struct vmbus_driver *)gDriver; - - return vmbusDriver->OnChildDeviceCreate(DeviceType, DeviceInstance, - Context); -} - -/* - * VmbusChildDeviceAdd - Registers the child device with the vmbus - */ -int VmbusChildDeviceAdd(struct hv_device *ChildDevice) -{ - struct vmbus_driver *vmbusDriver = (struct vmbus_driver *)gDriver; - - return vmbusDriver->OnChildDeviceAdd(gDevice, ChildDevice); -} - -/* - * VmbusChildDeviceRemove Unregisters the child device from the vmbus - */ -void VmbusChildDeviceRemove(struct hv_device *ChildDevice) -{ - struct vmbus_driver *vmbusDriver = (struct vmbus_driver *)gDriver; - - vmbusDriver->OnChildDeviceRemove(ChildDevice); -} - -/* - * VmbusOnDeviceAdd - Callback when the root bus device is added - */ -static int VmbusOnDeviceAdd(struct hv_device *dev, void *AdditionalInfo) -{ - u32 *irqvector = AdditionalInfo; - int ret; - - DPRINT_ENTER(VMBUS); - - gDevice = dev; - - memcpy(&gDevice->deviceType, &gVmbusDeviceType, sizeof(struct hv_guid)); - memcpy(&gDevice->deviceInstance, &gVmbusDeviceId, - sizeof(struct hv_guid)); - - /* strcpy(dev->name, "vmbus"); */ - /* SynIC setup... */ - on_each_cpu(HvSynicInit, (void *)irqvector, 1); - - /* Connect to VMBus in the root partition */ - ret = VmbusConnect(); - - /* VmbusSendEvent(device->localPortId+1); */ - DPRINT_EXIT(VMBUS); - - return ret; -} - -/* - * VmbusOnDeviceRemove - Callback when the root bus device is removed - */ -static int VmbusOnDeviceRemove(struct hv_device *dev) -{ - int ret = 0; - - DPRINT_ENTER(VMBUS); - VmbusChannelReleaseUnattachedChannels(); - VmbusDisconnect(); - on_each_cpu(HvSynicCleanup, NULL, 1); - DPRINT_EXIT(VMBUS); - - return ret; -} - -/* - * VmbusOnCleanup - Perform any cleanup when the driver is removed - */ -static void VmbusOnCleanup(struct hv_driver *drv) -{ - /* struct vmbus_driver *driver = (struct vmbus_driver *)drv; */ - - DPRINT_ENTER(VMBUS); - HvCleanup(); - DPRINT_EXIT(VMBUS); -} - -/* - * VmbusOnMsgDPC - DPC routine to handle messages from the hypervisior - */ -static void VmbusOnMsgDPC(struct hv_driver *drv) -{ - int cpu = smp_processor_id(); - void *page_addr = gHvContext.synICMessagePage[cpu]; - struct hv_message *msg = (struct hv_message *)page_addr + - VMBUS_MESSAGE_SINT; - struct hv_message *copied; - - while (1) { - if (msg->Header.MessageType == HvMessageTypeNone) { - /* no msg */ - break; - } else { - copied = kmalloc(sizeof(*copied), GFP_ATOMIC); - if (copied == NULL) - continue; - - memcpy(copied, msg, sizeof(*copied)); - osd_schedule_callback(gVmbusConnection.WorkQueue, - VmbusOnChannelMessage, - (void *)copied); - } - - msg->Header.MessageType = HvMessageTypeNone; - - /* - * Make sure the write to MessageType (ie set to - * HvMessageTypeNone) happens before we read the - * MessagePending and EOMing. Otherwise, the EOMing - * will not deliver any more messages since there is - * no empty slot - */ - mb(); - - if (msg->Header.MessageFlags.MessagePending) { - /* - * This will cause message queue rescan to - * possibly deliver another msg from the - * hypervisor - */ - wrmsrl(HV_X64_MSR_EOM, 0); - } - } -} - -/* - * VmbusOnEventDPC - DPC routine to handle events from the hypervisior - */ -static void VmbusOnEventDPC(struct hv_driver *drv) -{ - /* TODO: Process any events */ - VmbusOnEvents(); -} - -/* - * VmbusOnISR - ISR routine - */ -static int VmbusOnISR(struct hv_driver *drv) -{ - int ret = 0; - int cpu = smp_processor_id(); - void *page_addr; - struct hv_message *msg; - union hv_synic_event_flags *event; - - page_addr = gHvContext.synICMessagePage[cpu]; - msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; - - DPRINT_ENTER(VMBUS); - - /* Check if there are actual msgs to be process */ - if (msg->Header.MessageType != HvMessageTypeNone) { - DPRINT_DBG(VMBUS, "received msg type %d size %d", - msg->Header.MessageType, - msg->Header.PayloadSize); - ret |= 0x1; - } - - /* TODO: Check if there are events to be process */ - page_addr = gHvContext.synICEventPage[cpu]; - event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT; - - /* Since we are a child, we only need to check bit 0 */ - if (test_and_clear_bit(0, (unsigned long *) &event->Flags32[0])) { - DPRINT_DBG(VMBUS, "received event %d", event->Flags32[0]); - ret |= 0x2; - } - - DPRINT_EXIT(VMBUS); - return ret; -} - -/* - * VmbusInitialize - Main entry point - */ -int VmbusInitialize(struct hv_driver *drv) -{ - struct vmbus_driver *driver = (struct vmbus_driver *)drv; - int ret; - - DPRINT_ENTER(VMBUS); - - DPRINT_INFO(VMBUS, "+++++++ HV Driver version = %s +++++++", - HV_DRV_VERSION); - DPRINT_INFO(VMBUS, "+++++++ Vmbus supported version = %d +++++++", - VMBUS_REVISION_NUMBER); - DPRINT_INFO(VMBUS, "+++++++ Vmbus using SINT %d +++++++", - VMBUS_MESSAGE_SINT); - DPRINT_DBG(VMBUS, "sizeof(VMBUS_CHANNEL_PACKET_PAGE_BUFFER)=%zd, " - "sizeof(VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER)=%zd", - sizeof(struct VMBUS_CHANNEL_PACKET_PAGE_BUFFER), - sizeof(struct VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER)); - - drv->name = gDriverName; - memcpy(&drv->deviceType, &gVmbusDeviceType, sizeof(struct hv_guid)); - - /* Setup dispatch table */ - driver->Base.OnDeviceAdd = VmbusOnDeviceAdd; - driver->Base.OnDeviceRemove = VmbusOnDeviceRemove; - driver->Base.OnCleanup = VmbusOnCleanup; - driver->OnIsr = VmbusOnISR; - driver->OnMsgDpc = VmbusOnMsgDPC; - driver->OnEventDpc = VmbusOnEventDPC; - driver->GetChannelOffers = VmbusGetChannelOffers; - driver->GetChannelInterface = VmbusGetChannelInterface; - driver->GetChannelInfo = VmbusGetChannelInfo; - - /* Hypervisor initialization...setup hypercall page..etc */ - ret = HvInit(); - if (ret != 0) - DPRINT_ERR(VMBUS, "Unable to initialize the hypervisor - 0x%x", - ret); - gDriver = drv; - - DPRINT_EXIT(VMBUS); - - return ret; -} diff --git a/drivers/staging/hv/vmbus.c b/drivers/staging/hv/vmbus.c new file mode 100644 index 000000000000..90b14beec3aa --- /dev/null +++ b/drivers/staging/hv/vmbus.c @@ -0,0 +1,312 @@ +/* + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + * + */ +#include +#include +#include +#include "osd.h" +#include "logging.h" +#include "VersionInfo.h" +#include "VmbusPrivate.h" + +static const char *gDriverName = "vmbus"; + +/* + * Windows vmbus does not defined this. + * We defined this to be consistent with other devices + */ +/* {c5295816-f63a-4d5f-8d1a-4daf999ca185} */ +static const struct hv_guid gVmbusDeviceType = { + .data = { + 0x16, 0x58, 0x29, 0xc5, 0x3a, 0xf6, 0x5f, 0x4d, + 0x8d, 0x1a, 0x4d, 0xaf, 0x99, 0x9c, 0xa1, 0x85 + } +}; + +/* {ac3760fc-9adf-40aa-9427-a70ed6de95c5} */ +static const struct hv_guid gVmbusDeviceId = { + .data = { + 0xfc, 0x60, 0x37, 0xac, 0xdf, 0x9a, 0xaa, 0x40, + 0x94, 0x27, 0xa7, 0x0e, 0xd6, 0xde, 0x95, 0xc5 + } +}; + +static struct hv_driver *gDriver; /* vmbus driver object */ +static struct hv_device *gDevice; /* vmbus root device */ + +/* + * VmbusGetChannelOffers - Retrieve the channel offers from the parent partition + */ +static void VmbusGetChannelOffers(void) +{ + DPRINT_ENTER(VMBUS); + VmbusChannelRequestOffers(); + DPRINT_EXIT(VMBUS); +} + +/* + * VmbusGetChannelInterface - Get the channel interface + */ +static void VmbusGetChannelInterface(struct vmbus_channel_interface *Interface) +{ + GetChannelInterface(Interface); +} + +/* + * VmbusGetChannelInfo - Get the device info for the specified device object + */ +static void VmbusGetChannelInfo(struct hv_device *DeviceObject, + struct hv_device_info *DeviceInfo) +{ + GetChannelInfo(DeviceObject, DeviceInfo); +} + +/* + * VmbusCreateChildDevice - Creates the child device on the bus that represents the channel offer + */ +struct hv_device *VmbusChildDeviceCreate(struct hv_guid *DeviceType, + struct hv_guid *DeviceInstance, + void *Context) +{ + struct vmbus_driver *vmbusDriver = (struct vmbus_driver *)gDriver; + + return vmbusDriver->OnChildDeviceCreate(DeviceType, DeviceInstance, + Context); +} + +/* + * VmbusChildDeviceAdd - Registers the child device with the vmbus + */ +int VmbusChildDeviceAdd(struct hv_device *ChildDevice) +{ + struct vmbus_driver *vmbusDriver = (struct vmbus_driver *)gDriver; + + return vmbusDriver->OnChildDeviceAdd(gDevice, ChildDevice); +} + +/* + * VmbusChildDeviceRemove Unregisters the child device from the vmbus + */ +void VmbusChildDeviceRemove(struct hv_device *ChildDevice) +{ + struct vmbus_driver *vmbusDriver = (struct vmbus_driver *)gDriver; + + vmbusDriver->OnChildDeviceRemove(ChildDevice); +} + +/* + * VmbusOnDeviceAdd - Callback when the root bus device is added + */ +static int VmbusOnDeviceAdd(struct hv_device *dev, void *AdditionalInfo) +{ + u32 *irqvector = AdditionalInfo; + int ret; + + DPRINT_ENTER(VMBUS); + + gDevice = dev; + + memcpy(&gDevice->deviceType, &gVmbusDeviceType, sizeof(struct hv_guid)); + memcpy(&gDevice->deviceInstance, &gVmbusDeviceId, + sizeof(struct hv_guid)); + + /* strcpy(dev->name, "vmbus"); */ + /* SynIC setup... */ + on_each_cpu(HvSynicInit, (void *)irqvector, 1); + + /* Connect to VMBus in the root partition */ + ret = VmbusConnect(); + + /* VmbusSendEvent(device->localPortId+1); */ + DPRINT_EXIT(VMBUS); + + return ret; +} + +/* + * VmbusOnDeviceRemove - Callback when the root bus device is removed + */ +static int VmbusOnDeviceRemove(struct hv_device *dev) +{ + int ret = 0; + + DPRINT_ENTER(VMBUS); + VmbusChannelReleaseUnattachedChannels(); + VmbusDisconnect(); + on_each_cpu(HvSynicCleanup, NULL, 1); + DPRINT_EXIT(VMBUS); + + return ret; +} + +/* + * VmbusOnCleanup - Perform any cleanup when the driver is removed + */ +static void VmbusOnCleanup(struct hv_driver *drv) +{ + /* struct vmbus_driver *driver = (struct vmbus_driver *)drv; */ + + DPRINT_ENTER(VMBUS); + HvCleanup(); + DPRINT_EXIT(VMBUS); +} + +/* + * VmbusOnMsgDPC - DPC routine to handle messages from the hypervisior + */ +static void VmbusOnMsgDPC(struct hv_driver *drv) +{ + int cpu = smp_processor_id(); + void *page_addr = gHvContext.synICMessagePage[cpu]; + struct hv_message *msg = (struct hv_message *)page_addr + + VMBUS_MESSAGE_SINT; + struct hv_message *copied; + + while (1) { + if (msg->Header.MessageType == HvMessageTypeNone) { + /* no msg */ + break; + } else { + copied = kmalloc(sizeof(*copied), GFP_ATOMIC); + if (copied == NULL) + continue; + + memcpy(copied, msg, sizeof(*copied)); + osd_schedule_callback(gVmbusConnection.WorkQueue, + VmbusOnChannelMessage, + (void *)copied); + } + + msg->Header.MessageType = HvMessageTypeNone; + + /* + * Make sure the write to MessageType (ie set to + * HvMessageTypeNone) happens before we read the + * MessagePending and EOMing. Otherwise, the EOMing + * will not deliver any more messages since there is + * no empty slot + */ + mb(); + + if (msg->Header.MessageFlags.MessagePending) { + /* + * This will cause message queue rescan to + * possibly deliver another msg from the + * hypervisor + */ + wrmsrl(HV_X64_MSR_EOM, 0); + } + } +} + +/* + * VmbusOnEventDPC - DPC routine to handle events from the hypervisior + */ +static void VmbusOnEventDPC(struct hv_driver *drv) +{ + /* TODO: Process any events */ + VmbusOnEvents(); +} + +/* + * VmbusOnISR - ISR routine + */ +static int VmbusOnISR(struct hv_driver *drv) +{ + int ret = 0; + int cpu = smp_processor_id(); + void *page_addr; + struct hv_message *msg; + union hv_synic_event_flags *event; + + page_addr = gHvContext.synICMessagePage[cpu]; + msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; + + DPRINT_ENTER(VMBUS); + + /* Check if there are actual msgs to be process */ + if (msg->Header.MessageType != HvMessageTypeNone) { + DPRINT_DBG(VMBUS, "received msg type %d size %d", + msg->Header.MessageType, + msg->Header.PayloadSize); + ret |= 0x1; + } + + /* TODO: Check if there are events to be process */ + page_addr = gHvContext.synICEventPage[cpu]; + event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT; + + /* Since we are a child, we only need to check bit 0 */ + if (test_and_clear_bit(0, (unsigned long *) &event->Flags32[0])) { + DPRINT_DBG(VMBUS, "received event %d", event->Flags32[0]); + ret |= 0x2; + } + + DPRINT_EXIT(VMBUS); + return ret; +} + +/* + * VmbusInitialize - Main entry point + */ +int VmbusInitialize(struct hv_driver *drv) +{ + struct vmbus_driver *driver = (struct vmbus_driver *)drv; + int ret; + + DPRINT_ENTER(VMBUS); + + DPRINT_INFO(VMBUS, "+++++++ HV Driver version = %s +++++++", + HV_DRV_VERSION); + DPRINT_INFO(VMBUS, "+++++++ Vmbus supported version = %d +++++++", + VMBUS_REVISION_NUMBER); + DPRINT_INFO(VMBUS, "+++++++ Vmbus using SINT %d +++++++", + VMBUS_MESSAGE_SINT); + DPRINT_DBG(VMBUS, "sizeof(VMBUS_CHANNEL_PACKET_PAGE_BUFFER)=%zd, " + "sizeof(VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER)=%zd", + sizeof(struct VMBUS_CHANNEL_PACKET_PAGE_BUFFER), + sizeof(struct VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER)); + + drv->name = gDriverName; + memcpy(&drv->deviceType, &gVmbusDeviceType, sizeof(struct hv_guid)); + + /* Setup dispatch table */ + driver->Base.OnDeviceAdd = VmbusOnDeviceAdd; + driver->Base.OnDeviceRemove = VmbusOnDeviceRemove; + driver->Base.OnCleanup = VmbusOnCleanup; + driver->OnIsr = VmbusOnISR; + driver->OnMsgDpc = VmbusOnMsgDPC; + driver->OnEventDpc = VmbusOnEventDPC; + driver->GetChannelOffers = VmbusGetChannelOffers; + driver->GetChannelInterface = VmbusGetChannelInterface; + driver->GetChannelInfo = VmbusGetChannelInfo; + + /* Hypervisor initialization...setup hypercall page..etc */ + ret = HvInit(); + if (ret != 0) + DPRINT_ERR(VMBUS, "Unable to initialize the hypervisor - 0x%x", + ret); + gDriver = drv; + + DPRINT_EXIT(VMBUS); + + return ret; +} -- cgit v1.2.3 From af167ae9b27ee5ba19272739f9192709882ed4fa Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:27:31 -0700 Subject: Staging: hv: rename NetVsc.c and .h to netvsc.c and .h Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Makefile | 2 +- drivers/staging/hv/NetVsc.c | 1393 -------------------------------------- drivers/staging/hv/NetVsc.h | 331 --------- drivers/staging/hv/RndisFilter.h | 2 +- drivers/staging/hv/netvsc.c | 1393 ++++++++++++++++++++++++++++++++++++++ drivers/staging/hv/netvsc.h | 331 +++++++++ 6 files changed, 1726 insertions(+), 1726 deletions(-) delete mode 100644 drivers/staging/hv/NetVsc.c delete mode 100644 drivers/staging/hv/NetVsc.h create mode 100644 drivers/staging/hv/netvsc.c create mode 100644 drivers/staging/hv/netvsc.h (limited to 'drivers') diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index f58a4e7bf6d9..385eb90bd310 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -9,4 +9,4 @@ hv_vmbus-objs := vmbus_drv.o osd.o \ ChannelMgmt.o ChannelInterface.o ring_buffer.o hv_storvsc-objs := storvsc_drv.o StorVsc.o hv_blkvsc-objs := blkvsc_drv.o blkvsc.o -hv_netvsc-objs := netvsc_drv.o NetVsc.o RndisFilter.o +hv_netvsc-objs := netvsc_drv.o netvsc.o RndisFilter.o diff --git a/drivers/staging/hv/NetVsc.c b/drivers/staging/hv/NetVsc.c deleted file mode 100644 index f852984950a8..000000000000 --- a/drivers/staging/hv/NetVsc.c +++ /dev/null @@ -1,1393 +0,0 @@ -/* - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - */ -#include -#include -#include -#include -#include -#include "osd.h" -#include "logging.h" -#include "NetVsc.h" -#include "RndisFilter.h" - - -/* Globals */ -static const char *gDriverName = "netvsc"; - -/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */ -static const struct hv_guid gNetVscDeviceType = { - .data = { - 0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, - 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E - } -}; - -static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo); - -static int NetVscOnDeviceRemove(struct hv_device *Device); - -static void NetVscOnCleanup(struct hv_driver *Driver); - -static void NetVscOnChannelCallback(void *context); - -static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device); - -static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device); - -static int NetVscDestroySendBuffer(struct netvsc_device *NetDevice); - -static int NetVscDestroyReceiveBuffer(struct netvsc_device *NetDevice); - -static int NetVscConnectToVsp(struct hv_device *Device); - -static void NetVscOnSendCompletion(struct hv_device *Device, - struct vmpacket_descriptor *Packet); - -static int NetVscOnSend(struct hv_device *Device, - struct hv_netvsc_packet *Packet); - -static void NetVscOnReceive(struct hv_device *Device, - struct vmpacket_descriptor *Packet); - -static void NetVscOnReceiveCompletion(void *Context); - -static void NetVscSendReceiveCompletion(struct hv_device *Device, - u64 TransactionId); - - -static struct netvsc_device *AllocNetDevice(struct hv_device *Device) -{ - struct netvsc_device *netDevice; - - netDevice = kzalloc(sizeof(struct netvsc_device), GFP_KERNEL); - if (!netDevice) - return NULL; - - /* Set to 2 to allow both inbound and outbound traffic */ - atomic_cmpxchg(&netDevice->RefCount, 0, 2); - - netDevice->Device = Device; - Device->Extension = netDevice; - - return netDevice; -} - -static void FreeNetDevice(struct netvsc_device *Device) -{ - WARN_ON(atomic_read(&Device->RefCount) == 0); - Device->Device->Extension = NULL; - kfree(Device); -} - - -/* Get the net device object iff exists and its refcount > 1 */ -static struct netvsc_device *GetOutboundNetDevice(struct hv_device *Device) -{ - struct netvsc_device *netDevice; - - netDevice = Device->Extension; - if (netDevice && atomic_read(&netDevice->RefCount) > 1) - atomic_inc(&netDevice->RefCount); - else - netDevice = NULL; - - return netDevice; -} - -/* Get the net device object iff exists and its refcount > 0 */ -static struct netvsc_device *GetInboundNetDevice(struct hv_device *Device) -{ - struct netvsc_device *netDevice; - - netDevice = Device->Extension; - if (netDevice && atomic_read(&netDevice->RefCount)) - atomic_inc(&netDevice->RefCount); - else - netDevice = NULL; - - return netDevice; -} - -static void PutNetDevice(struct hv_device *Device) -{ - struct netvsc_device *netDevice; - - netDevice = Device->Extension; - /* ASSERT(netDevice); */ - - atomic_dec(&netDevice->RefCount); -} - -static struct netvsc_device *ReleaseOutboundNetDevice(struct hv_device *Device) -{ - struct netvsc_device *netDevice; - - netDevice = Device->Extension; - if (netDevice == NULL) - return NULL; - - /* Busy wait until the ref drop to 2, then set it to 1 */ - while (atomic_cmpxchg(&netDevice->RefCount, 2, 1) != 2) - udelay(100); - - return netDevice; -} - -static struct netvsc_device *ReleaseInboundNetDevice(struct hv_device *Device) -{ - struct netvsc_device *netDevice; - - netDevice = Device->Extension; - if (netDevice == NULL) - return NULL; - - /* Busy wait until the ref drop to 1, then set it to 0 */ - while (atomic_cmpxchg(&netDevice->RefCount, 1, 0) != 1) - udelay(100); - - Device->Extension = NULL; - return netDevice; -} - -/* - * NetVscInitialize - Main entry point - */ -int NetVscInitialize(struct hv_driver *drv) -{ - struct netvsc_driver *driver = (struct netvsc_driver *)drv; - - DPRINT_ENTER(NETVSC); - - DPRINT_DBG(NETVSC, "sizeof(struct hv_netvsc_packet)=%zd, " - "sizeof(struct nvsp_message)=%zd, " - "sizeof(struct vmtransfer_page_packet_header)=%zd", - sizeof(struct hv_netvsc_packet), - sizeof(struct nvsp_message), - sizeof(struct vmtransfer_page_packet_header)); - - /* Make sure we are at least 2 pages since 1 page is used for control */ - /* ASSERT(driver->RingBufferSize >= (PAGE_SIZE << 1)); */ - - drv->name = gDriverName; - memcpy(&drv->deviceType, &gNetVscDeviceType, sizeof(struct hv_guid)); - - /* Make sure it is set by the caller */ - /* FIXME: These probably should still be tested in some way */ - /* ASSERT(driver->OnReceiveCallback); */ - /* ASSERT(driver->OnLinkStatusChanged); */ - - /* Setup the dispatch table */ - driver->Base.OnDeviceAdd = NetVscOnDeviceAdd; - driver->Base.OnDeviceRemove = NetVscOnDeviceRemove; - driver->Base.OnCleanup = NetVscOnCleanup; - - driver->OnSend = NetVscOnSend; - - RndisFilterInit(driver); - - DPRINT_EXIT(NETVSC); - - return 0; -} - -static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device) -{ - int ret = 0; - struct netvsc_device *netDevice; - struct nvsp_message *initPacket; - - DPRINT_ENTER(NETVSC); - - netDevice = GetOutboundNetDevice(Device); - if (!netDevice) { - DPRINT_ERR(NETVSC, "unable to get net device..." - "device being destroyed?"); - DPRINT_EXIT(NETVSC); - return -1; - } - /* ASSERT(netDevice->ReceiveBufferSize > 0); */ - /* page-size grandularity */ - /* ASSERT((netDevice->ReceiveBufferSize & (PAGE_SIZE - 1)) == 0); */ - - netDevice->ReceiveBuffer = - osd_PageAlloc(netDevice->ReceiveBufferSize >> PAGE_SHIFT); - if (!netDevice->ReceiveBuffer) { - DPRINT_ERR(NETVSC, - "unable to allocate receive buffer of size %d", - netDevice->ReceiveBufferSize); - ret = -1; - goto Cleanup; - } - /* page-aligned buffer */ - /* ASSERT(((unsigned long)netDevice->ReceiveBuffer & (PAGE_SIZE - 1)) == */ - /* 0); */ - - DPRINT_INFO(NETVSC, "Establishing receive buffer's GPADL..."); - - /* - * Establish the gpadl handle for this buffer on this - * channel. Note: This call uses the vmbus connection rather - * than the channel to establish the gpadl handle. - */ - ret = Device->Driver->VmbusChannelInterface.EstablishGpadl(Device, - netDevice->ReceiveBuffer, - netDevice->ReceiveBufferSize, - &netDevice->ReceiveBufferGpadlHandle); - if (ret != 0) { - DPRINT_ERR(NETVSC, - "unable to establish receive buffer's gpadl"); - goto Cleanup; - } - - /* osd_WaitEventWait(ext->ChannelInitEvent); */ - - /* Notify the NetVsp of the gpadl handle */ - DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendReceiveBuffer..."); - - initPacket = &netDevice->ChannelInitPacket; - - memset(initPacket, 0, sizeof(struct nvsp_message)); - - initPacket->Header.MessageType = NvspMessage1TypeSendReceiveBuffer; - initPacket->Messages.Version1Messages.SendReceiveBuffer.GpadlHandle = netDevice->ReceiveBufferGpadlHandle; - initPacket->Messages.Version1Messages.SendReceiveBuffer.Id = NETVSC_RECEIVE_BUFFER_ID; - - /* Send the gpadl notification request */ - ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, - initPacket, - sizeof(struct nvsp_message), - (unsigned long)initPacket, - VmbusPacketTypeDataInBand, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - if (ret != 0) { - DPRINT_ERR(NETVSC, - "unable to send receive buffer's gpadl to netvsp"); - goto Cleanup; - } - - osd_WaitEventWait(netDevice->ChannelInitEvent); - - /* Check the response */ - if (initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Status != NvspStatusSuccess) { - DPRINT_ERR(NETVSC, "Unable to complete receive buffer " - "initialzation with NetVsp - status %d", - initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Status); - ret = -1; - goto Cleanup; - } - - /* Parse the response */ - /* ASSERT(netDevice->ReceiveSectionCount == 0); */ - /* ASSERT(netDevice->ReceiveSections == NULL); */ - - netDevice->ReceiveSectionCount = initPacket->Messages.Version1Messages.SendReceiveBufferComplete.NumSections; - - netDevice->ReceiveSections = kmalloc(netDevice->ReceiveSectionCount * sizeof(struct nvsp_1_receive_buffer_section), GFP_KERNEL); - if (netDevice->ReceiveSections == NULL) { - ret = -1; - goto Cleanup; - } - - memcpy(netDevice->ReceiveSections, - initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Sections, - netDevice->ReceiveSectionCount * sizeof(struct nvsp_1_receive_buffer_section)); - - DPRINT_INFO(NETVSC, "Receive sections info (count %d, offset %d, " - "endoffset %d, suballoc size %d, num suballocs %d)", - netDevice->ReceiveSectionCount, - netDevice->ReceiveSections[0].Offset, - netDevice->ReceiveSections[0].EndOffset, - netDevice->ReceiveSections[0].SubAllocationSize, - netDevice->ReceiveSections[0].NumSubAllocations); - - /* - * For 1st release, there should only be 1 section that represents the - * entire receive buffer - */ - if (netDevice->ReceiveSectionCount != 1 || - netDevice->ReceiveSections->Offset != 0) { - ret = -1; - goto Cleanup; - } - - goto Exit; - -Cleanup: - NetVscDestroyReceiveBuffer(netDevice); - -Exit: - PutNetDevice(Device); - DPRINT_EXIT(NETVSC); - return ret; -} - -static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device) -{ - int ret = 0; - struct netvsc_device *netDevice; - struct nvsp_message *initPacket; - - DPRINT_ENTER(NETVSC); - - netDevice = GetOutboundNetDevice(Device); - if (!netDevice) { - DPRINT_ERR(NETVSC, "unable to get net device..." - "device being destroyed?"); - DPRINT_EXIT(NETVSC); - return -1; - } - if (netDevice->SendBufferSize <= 0) { - ret = -EINVAL; - goto Cleanup; - } - - /* page-size grandularity */ - /* ASSERT((netDevice->SendBufferSize & (PAGE_SIZE - 1)) == 0); */ - - netDevice->SendBuffer = - osd_PageAlloc(netDevice->SendBufferSize >> PAGE_SHIFT); - if (!netDevice->SendBuffer) { - DPRINT_ERR(NETVSC, "unable to allocate send buffer of size %d", - netDevice->SendBufferSize); - ret = -1; - goto Cleanup; - } - /* page-aligned buffer */ - /* ASSERT(((unsigned long)netDevice->SendBuffer & (PAGE_SIZE - 1)) == 0); */ - - DPRINT_INFO(NETVSC, "Establishing send buffer's GPADL..."); - - /* - * Establish the gpadl handle for this buffer on this - * channel. Note: This call uses the vmbus connection rather - * than the channel to establish the gpadl handle. - */ - ret = Device->Driver->VmbusChannelInterface.EstablishGpadl(Device, - netDevice->SendBuffer, - netDevice->SendBufferSize, - &netDevice->SendBufferGpadlHandle); - if (ret != 0) { - DPRINT_ERR(NETVSC, "unable to establish send buffer's gpadl"); - goto Cleanup; - } - - /* osd_WaitEventWait(ext->ChannelInitEvent); */ - - /* Notify the NetVsp of the gpadl handle */ - DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendSendBuffer..."); - - initPacket = &netDevice->ChannelInitPacket; - - memset(initPacket, 0, sizeof(struct nvsp_message)); - - initPacket->Header.MessageType = NvspMessage1TypeSendSendBuffer; - initPacket->Messages.Version1Messages.SendReceiveBuffer.GpadlHandle = netDevice->SendBufferGpadlHandle; - initPacket->Messages.Version1Messages.SendReceiveBuffer.Id = NETVSC_SEND_BUFFER_ID; - - /* Send the gpadl notification request */ - ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, - initPacket, sizeof(struct nvsp_message), - (unsigned long)initPacket, - VmbusPacketTypeDataInBand, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - if (ret != 0) { - DPRINT_ERR(NETVSC, - "unable to send receive buffer's gpadl to netvsp"); - goto Cleanup; - } - - osd_WaitEventWait(netDevice->ChannelInitEvent); - - /* Check the response */ - if (initPacket->Messages.Version1Messages.SendSendBufferComplete.Status != NvspStatusSuccess) { - DPRINT_ERR(NETVSC, "Unable to complete send buffer " - "initialzation with NetVsp - status %d", - initPacket->Messages.Version1Messages.SendSendBufferComplete.Status); - ret = -1; - goto Cleanup; - } - - netDevice->SendSectionSize = initPacket->Messages.Version1Messages.SendSendBufferComplete.SectionSize; - - goto Exit; - -Cleanup: - NetVscDestroySendBuffer(netDevice); - -Exit: - PutNetDevice(Device); - DPRINT_EXIT(NETVSC); - return ret; -} - -static int NetVscDestroyReceiveBuffer(struct netvsc_device *NetDevice) -{ - struct nvsp_message *revokePacket; - int ret = 0; - - DPRINT_ENTER(NETVSC); - - /* - * If we got a section count, it means we received a - * SendReceiveBufferComplete msg (ie sent - * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need - * to send a revoke msg here - */ - if (NetDevice->ReceiveSectionCount) { - DPRINT_INFO(NETVSC, - "Sending NvspMessage1TypeRevokeReceiveBuffer..."); - - /* Send the revoke receive buffer */ - revokePacket = &NetDevice->RevokePacket; - memset(revokePacket, 0, sizeof(struct nvsp_message)); - - revokePacket->Header.MessageType = NvspMessage1TypeRevokeReceiveBuffer; - revokePacket->Messages.Version1Messages.RevokeReceiveBuffer.Id = NETVSC_RECEIVE_BUFFER_ID; - - ret = NetDevice->Device->Driver->VmbusChannelInterface.SendPacket( - NetDevice->Device, - revokePacket, - sizeof(struct nvsp_message), - (unsigned long)revokePacket, - VmbusPacketTypeDataInBand, 0); - /* - * If we failed here, we might as well return and - * have a leak rather than continue and a bugchk - */ - if (ret != 0) { - DPRINT_ERR(NETVSC, "unable to send revoke receive " - "buffer to netvsp"); - DPRINT_EXIT(NETVSC); - return -1; - } - } - - /* Teardown the gpadl on the vsp end */ - if (NetDevice->ReceiveBufferGpadlHandle) { - DPRINT_INFO(NETVSC, "Tearing down receive buffer's GPADL..."); - - ret = NetDevice->Device->Driver->VmbusChannelInterface.TeardownGpadl( - NetDevice->Device, - NetDevice->ReceiveBufferGpadlHandle); - - /* If we failed here, we might as well return and have a leak rather than continue and a bugchk */ - if (ret != 0) { - DPRINT_ERR(NETVSC, - "unable to teardown receive buffer's gpadl"); - DPRINT_EXIT(NETVSC); - return -1; - } - NetDevice->ReceiveBufferGpadlHandle = 0; - } - - if (NetDevice->ReceiveBuffer) { - DPRINT_INFO(NETVSC, "Freeing up receive buffer..."); - - /* Free up the receive buffer */ - osd_PageFree(NetDevice->ReceiveBuffer, - NetDevice->ReceiveBufferSize >> PAGE_SHIFT); - NetDevice->ReceiveBuffer = NULL; - } - - if (NetDevice->ReceiveSections) { - NetDevice->ReceiveSectionCount = 0; - kfree(NetDevice->ReceiveSections); - NetDevice->ReceiveSections = NULL; - } - - DPRINT_EXIT(NETVSC); - - return ret; -} - -static int NetVscDestroySendBuffer(struct netvsc_device *NetDevice) -{ - struct nvsp_message *revokePacket; - int ret = 0; - - DPRINT_ENTER(NETVSC); - - /* - * If we got a section count, it means we received a - * SendReceiveBufferComplete msg (ie sent - * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need - * to send a revoke msg here - */ - if (NetDevice->SendSectionSize) { - DPRINT_INFO(NETVSC, - "Sending NvspMessage1TypeRevokeSendBuffer..."); - - /* Send the revoke send buffer */ - revokePacket = &NetDevice->RevokePacket; - memset(revokePacket, 0, sizeof(struct nvsp_message)); - - revokePacket->Header.MessageType = NvspMessage1TypeRevokeSendBuffer; - revokePacket->Messages.Version1Messages.RevokeSendBuffer.Id = NETVSC_SEND_BUFFER_ID; - - ret = NetDevice->Device->Driver->VmbusChannelInterface.SendPacket(NetDevice->Device, - revokePacket, - sizeof(struct nvsp_message), - (unsigned long)revokePacket, - VmbusPacketTypeDataInBand, 0); - /* - * If we failed here, we might as well return and have a leak - * rather than continue and a bugchk - */ - if (ret != 0) { - DPRINT_ERR(NETVSC, "unable to send revoke send buffer " - "to netvsp"); - DPRINT_EXIT(NETVSC); - return -1; - } - } - - /* Teardown the gpadl on the vsp end */ - if (NetDevice->SendBufferGpadlHandle) { - DPRINT_INFO(NETVSC, "Tearing down send buffer's GPADL..."); - - ret = NetDevice->Device->Driver->VmbusChannelInterface.TeardownGpadl(NetDevice->Device, NetDevice->SendBufferGpadlHandle); - - /* - * If we failed here, we might as well return and have a leak - * rather than continue and a bugchk - */ - if (ret != 0) { - DPRINT_ERR(NETVSC, "unable to teardown send buffer's " - "gpadl"); - DPRINT_EXIT(NETVSC); - return -1; - } - NetDevice->SendBufferGpadlHandle = 0; - } - - if (NetDevice->SendBuffer) { - DPRINT_INFO(NETVSC, "Freeing up send buffer..."); - - /* Free up the receive buffer */ - osd_PageFree(NetDevice->SendBuffer, - NetDevice->SendBufferSize >> PAGE_SHIFT); - NetDevice->SendBuffer = NULL; - } - - DPRINT_EXIT(NETVSC); - - return ret; -} - - -static int NetVscConnectToVsp(struct hv_device *Device) -{ - int ret; - struct netvsc_device *netDevice; - struct nvsp_message *initPacket; - int ndisVersion; - - DPRINT_ENTER(NETVSC); - - netDevice = GetOutboundNetDevice(Device); - if (!netDevice) { - DPRINT_ERR(NETVSC, "unable to get net device..." - "device being destroyed?"); - DPRINT_EXIT(NETVSC); - return -1; - } - - initPacket = &netDevice->ChannelInitPacket; - - memset(initPacket, 0, sizeof(struct nvsp_message)); - initPacket->Header.MessageType = NvspMessageTypeInit; - initPacket->Messages.InitMessages.Init.MinProtocolVersion = NVSP_MIN_PROTOCOL_VERSION; - initPacket->Messages.InitMessages.Init.MaxProtocolVersion = NVSP_MAX_PROTOCOL_VERSION; - - DPRINT_INFO(NETVSC, "Sending NvspMessageTypeInit..."); - - /* Send the init request */ - ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, - initPacket, - sizeof(struct nvsp_message), - (unsigned long)initPacket, - VmbusPacketTypeDataInBand, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - - if (ret != 0) { - DPRINT_ERR(NETVSC, "unable to send NvspMessageTypeInit"); - goto Cleanup; - } - - osd_WaitEventWait(netDevice->ChannelInitEvent); - - /* Now, check the response */ - /* ASSERT(initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength <= MAX_MULTIPAGE_BUFFER_COUNT); */ - DPRINT_INFO(NETVSC, "NvspMessageTypeInit status(%d) max mdl chain (%d)", - initPacket->Messages.InitMessages.InitComplete.Status, - initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength); - - if (initPacket->Messages.InitMessages.InitComplete.Status != - NvspStatusSuccess) { - DPRINT_ERR(NETVSC, - "unable to initialize with netvsp (status 0x%x)", - initPacket->Messages.InitMessages.InitComplete.Status); - ret = -1; - goto Cleanup; - } - - if (initPacket->Messages.InitMessages.InitComplete.NegotiatedProtocolVersion != NVSP_PROTOCOL_VERSION_1) { - DPRINT_ERR(NETVSC, "unable to initialize with netvsp " - "(version expected 1 got %d)", - initPacket->Messages.InitMessages.InitComplete.NegotiatedProtocolVersion); - ret = -1; - goto Cleanup; - } - DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendNdisVersion..."); - - /* Send the ndis version */ - memset(initPacket, 0, sizeof(struct nvsp_message)); - - ndisVersion = 0x00050000; - - initPacket->Header.MessageType = NvspMessage1TypeSendNdisVersion; - initPacket->Messages.Version1Messages.SendNdisVersion.NdisMajorVersion = - (ndisVersion & 0xFFFF0000) >> 16; - initPacket->Messages.Version1Messages.SendNdisVersion.NdisMinorVersion = - ndisVersion & 0xFFFF; - - /* Send the init request */ - ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, - initPacket, - sizeof(struct nvsp_message), - (unsigned long)initPacket, - VmbusPacketTypeDataInBand, 0); - if (ret != 0) { - DPRINT_ERR(NETVSC, - "unable to send NvspMessage1TypeSendNdisVersion"); - ret = -1; - goto Cleanup; - } - /* - * BUGBUG - We have to wait for the above msg since the - * netvsp uses KMCL which acknowledges packet (completion - * packet) since our Vmbus always set the - * VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED flag - */ - /* osd_WaitEventWait(NetVscChannel->ChannelInitEvent); */ - - /* Post the big receive buffer to NetVSP */ - ret = NetVscInitializeReceiveBufferWithNetVsp(Device); - if (ret == 0) - ret = NetVscInitializeSendBufferWithNetVsp(Device); - -Cleanup: - PutNetDevice(Device); - DPRINT_EXIT(NETVSC); - return ret; -} - -static void NetVscDisconnectFromVsp(struct netvsc_device *NetDevice) -{ - DPRINT_ENTER(NETVSC); - - NetVscDestroyReceiveBuffer(NetDevice); - NetVscDestroySendBuffer(NetDevice); - - DPRINT_EXIT(NETVSC); -} - -/* - * NetVscOnDeviceAdd - Callback when the device belonging to this driver is added - */ -static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) -{ - int ret = 0; - int i; - struct netvsc_device *netDevice; - struct hv_netvsc_packet *packet, *pos; - struct netvsc_driver *netDriver = - (struct netvsc_driver *)Device->Driver; - - DPRINT_ENTER(NETVSC); - - netDevice = AllocNetDevice(Device); - if (!netDevice) { - ret = -1; - goto Cleanup; - } - - DPRINT_DBG(NETVSC, "netvsc channel object allocated - %p", netDevice); - - /* Initialize the NetVSC channel extension */ - netDevice->ReceiveBufferSize = NETVSC_RECEIVE_BUFFER_SIZE; - spin_lock_init(&netDevice->receive_packet_list_lock); - - netDevice->SendBufferSize = NETVSC_SEND_BUFFER_SIZE; - - INIT_LIST_HEAD(&netDevice->ReceivePacketList); - - for (i = 0; i < NETVSC_RECEIVE_PACKETLIST_COUNT; i++) { - packet = kzalloc(sizeof(struct hv_netvsc_packet) + - (NETVSC_RECEIVE_SG_COUNT * - sizeof(struct hv_page_buffer)), GFP_KERNEL); - if (!packet) { - DPRINT_DBG(NETVSC, "unable to allocate netvsc pkts " - "for receive pool (wanted %d got %d)", - NETVSC_RECEIVE_PACKETLIST_COUNT, i); - break; - } - list_add_tail(&packet->ListEntry, - &netDevice->ReceivePacketList); - } - netDevice->ChannelInitEvent = osd_WaitEventCreate(); - if (!netDevice->ChannelInitEvent) { - ret = -ENOMEM; - goto Cleanup; - } - - /* Open the channel */ - ret = Device->Driver->VmbusChannelInterface.Open(Device, - netDriver->RingBufferSize, - netDriver->RingBufferSize, - NULL, 0, - NetVscOnChannelCallback, - Device); - - if (ret != 0) { - DPRINT_ERR(NETVSC, "unable to open channel: %d", ret); - ret = -1; - goto Cleanup; - } - - /* Channel is opened */ - DPRINT_INFO(NETVSC, "*** NetVSC channel opened successfully! ***"); - - /* Connect with the NetVsp */ - ret = NetVscConnectToVsp(Device); - if (ret != 0) { - DPRINT_ERR(NETVSC, "unable to connect to NetVSP - %d", ret); - ret = -1; - goto Close; - } - - DPRINT_INFO(NETVSC, "*** NetVSC channel handshake result - %d ***", - ret); - - DPRINT_EXIT(NETVSC); - return ret; - -Close: - /* Now, we can close the channel safely */ - Device->Driver->VmbusChannelInterface.Close(Device); - -Cleanup: - - if (netDevice) { - kfree(netDevice->ChannelInitEvent); - - list_for_each_entry_safe(packet, pos, - &netDevice->ReceivePacketList, - ListEntry) { - list_del(&packet->ListEntry); - kfree(packet); - } - - ReleaseOutboundNetDevice(Device); - ReleaseInboundNetDevice(Device); - - FreeNetDevice(netDevice); - } - - DPRINT_EXIT(NETVSC); - return ret; -} - -/* - * NetVscOnDeviceRemove - Callback when the root bus device is removed - */ -static int NetVscOnDeviceRemove(struct hv_device *Device) -{ - struct netvsc_device *netDevice; - struct hv_netvsc_packet *netvscPacket, *pos; - - DPRINT_ENTER(NETVSC); - - DPRINT_INFO(NETVSC, "Disabling outbound traffic on net device (%p)...", - Device->Extension); - - /* Stop outbound traffic ie sends and receives completions */ - netDevice = ReleaseOutboundNetDevice(Device); - if (!netDevice) { - DPRINT_ERR(NETVSC, "No net device present!!"); - return -1; - } - - /* Wait for all send completions */ - while (atomic_read(&netDevice->NumOutstandingSends)) { - DPRINT_INFO(NETVSC, "waiting for %d requests to complete...", - atomic_read(&netDevice->NumOutstandingSends)); - udelay(100); - } - - DPRINT_INFO(NETVSC, "Disconnecting from netvsp..."); - - NetVscDisconnectFromVsp(netDevice); - - DPRINT_INFO(NETVSC, "Disabling inbound traffic on net device (%p)...", - Device->Extension); - - /* Stop inbound traffic ie receives and sends completions */ - netDevice = ReleaseInboundNetDevice(Device); - - /* At this point, no one should be accessing netDevice except in here */ - DPRINT_INFO(NETVSC, "net device (%p) safe to remove", netDevice); - - /* Now, we can close the channel safely */ - Device->Driver->VmbusChannelInterface.Close(Device); - - /* Release all resources */ - list_for_each_entry_safe(netvscPacket, pos, - &netDevice->ReceivePacketList, ListEntry) { - list_del(&netvscPacket->ListEntry); - kfree(netvscPacket); - } - - kfree(netDevice->ChannelInitEvent); - FreeNetDevice(netDevice); - - DPRINT_EXIT(NETVSC); - return 0; -} - -/* - * NetVscOnCleanup - Perform any cleanup when the driver is removed - */ -static void NetVscOnCleanup(struct hv_driver *drv) -{ - DPRINT_ENTER(NETVSC); - DPRINT_EXIT(NETVSC); -} - -static void NetVscOnSendCompletion(struct hv_device *Device, - struct vmpacket_descriptor *Packet) -{ - struct netvsc_device *netDevice; - struct nvsp_message *nvspPacket; - struct hv_netvsc_packet *nvscPacket; - - DPRINT_ENTER(NETVSC); - - netDevice = GetInboundNetDevice(Device); - if (!netDevice) { - DPRINT_ERR(NETVSC, "unable to get net device..." - "device being destroyed?"); - DPRINT_EXIT(NETVSC); - return; - } - - nvspPacket = (struct nvsp_message *)((unsigned long)Packet + (Packet->DataOffset8 << 3)); - - DPRINT_DBG(NETVSC, "send completion packet - type %d", - nvspPacket->Header.MessageType); - - if ((nvspPacket->Header.MessageType == NvspMessageTypeInitComplete) || - (nvspPacket->Header.MessageType == - NvspMessage1TypeSendReceiveBufferComplete) || - (nvspPacket->Header.MessageType == - NvspMessage1TypeSendSendBufferComplete)) { - /* Copy the response back */ - memcpy(&netDevice->ChannelInitPacket, nvspPacket, - sizeof(struct nvsp_message)); - osd_WaitEventSet(netDevice->ChannelInitEvent); - } else if (nvspPacket->Header.MessageType == - NvspMessage1TypeSendRNDISPacketComplete) { - /* Get the send context */ - nvscPacket = (struct hv_netvsc_packet *)(unsigned long)Packet->TransactionId; - /* ASSERT(nvscPacket); */ - - /* Notify the layer above us */ - nvscPacket->Completion.Send.OnSendCompletion(nvscPacket->Completion.Send.SendCompletionContext); - - atomic_dec(&netDevice->NumOutstandingSends); - } else { - DPRINT_ERR(NETVSC, "Unknown send completion packet type - " - "%d received!!", nvspPacket->Header.MessageType); - } - - PutNetDevice(Device); - DPRINT_EXIT(NETVSC); -} - -static int NetVscOnSend(struct hv_device *Device, - struct hv_netvsc_packet *Packet) -{ - struct netvsc_device *netDevice; - int ret = 0; - - struct nvsp_message sendMessage; - - DPRINT_ENTER(NETVSC); - - netDevice = GetOutboundNetDevice(Device); - if (!netDevice) { - DPRINT_ERR(NETVSC, "net device (%p) shutting down..." - "ignoring outbound packets", netDevice); - DPRINT_EXIT(NETVSC); - return -2; - } - - sendMessage.Header.MessageType = NvspMessage1TypeSendRNDISPacket; - if (Packet->IsDataPacket) { - /* 0 is RMC_DATA; */ - sendMessage.Messages.Version1Messages.SendRNDISPacket.ChannelType = 0; - } else { - /* 1 is RMC_CONTROL; */ - sendMessage.Messages.Version1Messages.SendRNDISPacket.ChannelType = 1; - } - - /* Not using send buffer section */ - sendMessage.Messages.Version1Messages.SendRNDISPacket.SendBufferSectionIndex = 0xFFFFFFFF; - sendMessage.Messages.Version1Messages.SendRNDISPacket.SendBufferSectionSize = 0; - - if (Packet->PageBufferCount) { - ret = Device->Driver->VmbusChannelInterface.SendPacketPageBuffer( - Device, Packet->PageBuffers, - Packet->PageBufferCount, - &sendMessage, - sizeof(struct nvsp_message), - (unsigned long)Packet); - } else { - ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, - &sendMessage, - sizeof(struct nvsp_message), - (unsigned long)Packet, - VmbusPacketTypeDataInBand, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - - } - - if (ret != 0) - DPRINT_ERR(NETVSC, "Unable to send packet %p ret %d", - Packet, ret); - - atomic_inc(&netDevice->NumOutstandingSends); - PutNetDevice(Device); - - DPRINT_EXIT(NETVSC); - return ret; -} - -static void NetVscOnReceive(struct hv_device *Device, - struct vmpacket_descriptor *Packet) -{ - struct netvsc_device *netDevice; - struct vmtransfer_page_packet_header *vmxferpagePacket; - struct nvsp_message *nvspPacket; - struct hv_netvsc_packet *netvscPacket = NULL; - unsigned long start; - unsigned long end, endVirtual; - /* struct netvsc_driver *netvscDriver; */ - struct xferpage_packet *xferpagePacket = NULL; - int i, j; - int count = 0, bytesRemain = 0; - unsigned long flags; - LIST_HEAD(listHead); - - DPRINT_ENTER(NETVSC); - - netDevice = GetInboundNetDevice(Device); - if (!netDevice) { - DPRINT_ERR(NETVSC, "unable to get net device..." - "device being destroyed?"); - DPRINT_EXIT(NETVSC); - return; - } - - /* - * All inbound packets other than send completion should be xfer page - * packet - */ - if (Packet->Type != VmbusPacketTypeDataUsingTransferPages) { - DPRINT_ERR(NETVSC, "Unknown packet type received - %d", - Packet->Type); - PutNetDevice(Device); - return; - } - - nvspPacket = (struct nvsp_message *)((unsigned long)Packet + - (Packet->DataOffset8 << 3)); - - /* Make sure this is a valid nvsp packet */ - if (nvspPacket->Header.MessageType != NvspMessage1TypeSendRNDISPacket) { - DPRINT_ERR(NETVSC, "Unknown nvsp packet type received - %d", - nvspPacket->Header.MessageType); - PutNetDevice(Device); - return; - } - - DPRINT_DBG(NETVSC, "NVSP packet received - type %d", - nvspPacket->Header.MessageType); - - vmxferpagePacket = (struct vmtransfer_page_packet_header *)Packet; - - if (vmxferpagePacket->TransferPageSetId != NETVSC_RECEIVE_BUFFER_ID) { - DPRINT_ERR(NETVSC, "Invalid xfer page set id - " - "expecting %x got %x", NETVSC_RECEIVE_BUFFER_ID, - vmxferpagePacket->TransferPageSetId); - PutNetDevice(Device); - return; - } - - DPRINT_DBG(NETVSC, "xfer page - range count %d", - vmxferpagePacket->RangeCount); - - /* - * Grab free packets (range count + 1) to represent this xfer - * page packet. +1 to represent the xfer page packet itself. - * We grab it here so that we know exactly how many we can - * fulfil - */ - spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags); - while (!list_empty(&netDevice->ReceivePacketList)) { - list_move_tail(netDevice->ReceivePacketList.next, &listHead); - if (++count == vmxferpagePacket->RangeCount + 1) - break; - } - spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, flags); - - /* - * We need at least 2 netvsc pkts (1 to represent the xfer - * page and at least 1 for the range) i.e. we can handled - * some of the xfer page packet ranges... - */ - if (count < 2) { - DPRINT_ERR(NETVSC, "Got only %d netvsc pkt...needed %d pkts. " - "Dropping this xfer page packet completely!", - count, vmxferpagePacket->RangeCount + 1); - - /* Return it to the freelist */ - spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags); - for (i = count; i != 0; i--) { - list_move_tail(listHead.next, - &netDevice->ReceivePacketList); - } - spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, - flags); - - NetVscSendReceiveCompletion(Device, - vmxferpagePacket->d.TransactionId); - - PutNetDevice(Device); - return; - } - - /* Remove the 1st packet to represent the xfer page packet itself */ - xferpagePacket = (struct xferpage_packet *)listHead.next; - list_del(&xferpagePacket->ListEntry); - - /* This is how much we can satisfy */ - xferpagePacket->Count = count - 1; - /* ASSERT(xferpagePacket->Count > 0 && xferpagePacket->Count <= */ - /* vmxferpagePacket->RangeCount); */ - - if (xferpagePacket->Count != vmxferpagePacket->RangeCount) { - DPRINT_INFO(NETVSC, "Needed %d netvsc pkts to satisy this xfer " - "page...got %d", vmxferpagePacket->RangeCount, - xferpagePacket->Count); - } - - /* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */ - for (i = 0; i < (count - 1); i++) { - netvscPacket = (struct hv_netvsc_packet *)listHead.next; - list_del(&netvscPacket->ListEntry); - - /* Initialize the netvsc packet */ - netvscPacket->XferPagePacket = xferpagePacket; - netvscPacket->Completion.Recv.OnReceiveCompletion = - NetVscOnReceiveCompletion; - netvscPacket->Completion.Recv.ReceiveCompletionContext = - netvscPacket; - netvscPacket->Device = Device; - /* Save this so that we can send it back */ - netvscPacket->Completion.Recv.ReceiveCompletionTid = - vmxferpagePacket->d.TransactionId; - - netvscPacket->TotalDataBufferLength = - vmxferpagePacket->Ranges[i].ByteCount; - netvscPacket->PageBufferCount = 1; - - /* ASSERT(vmxferpagePacket->Ranges[i].ByteOffset + */ - /* vmxferpagePacket->Ranges[i].ByteCount < */ - /* netDevice->ReceiveBufferSize); */ - - netvscPacket->PageBuffers[0].Length = - vmxferpagePacket->Ranges[i].ByteCount; - - start = virt_to_phys((void *)((unsigned long)netDevice->ReceiveBuffer + vmxferpagePacket->Ranges[i].ByteOffset)); - - netvscPacket->PageBuffers[0].Pfn = start >> PAGE_SHIFT; - endVirtual = (unsigned long)netDevice->ReceiveBuffer - + vmxferpagePacket->Ranges[i].ByteOffset - + vmxferpagePacket->Ranges[i].ByteCount - 1; - end = virt_to_phys((void *)endVirtual); - - /* Calculate the page relative offset */ - netvscPacket->PageBuffers[0].Offset = - vmxferpagePacket->Ranges[i].ByteOffset & (PAGE_SIZE - 1); - if ((end >> PAGE_SHIFT) != (start >> PAGE_SHIFT)) { - /* Handle frame across multiple pages: */ - netvscPacket->PageBuffers[0].Length = - (netvscPacket->PageBuffers[0].Pfn << PAGE_SHIFT) - + PAGE_SIZE - start; - bytesRemain = netvscPacket->TotalDataBufferLength - - netvscPacket->PageBuffers[0].Length; - for (j = 1; j < NETVSC_PACKET_MAXPAGE; j++) { - netvscPacket->PageBuffers[j].Offset = 0; - if (bytesRemain <= PAGE_SIZE) { - netvscPacket->PageBuffers[j].Length = bytesRemain; - bytesRemain = 0; - } else { - netvscPacket->PageBuffers[j].Length = PAGE_SIZE; - bytesRemain -= PAGE_SIZE; - } - netvscPacket->PageBuffers[j].Pfn = - virt_to_phys((void *)(endVirtual - bytesRemain)) >> PAGE_SHIFT; - netvscPacket->PageBufferCount++; - if (bytesRemain == 0) - break; - } - /* ASSERT(bytesRemain == 0); */ - } - DPRINT_DBG(NETVSC, "[%d] - (abs offset %u len %u) => " - "(pfn %llx, offset %u, len %u)", i, - vmxferpagePacket->Ranges[i].ByteOffset, - vmxferpagePacket->Ranges[i].ByteCount, - netvscPacket->PageBuffers[0].Pfn, - netvscPacket->PageBuffers[0].Offset, - netvscPacket->PageBuffers[0].Length); - - /* Pass it to the upper layer */ - ((struct netvsc_driver *)Device->Driver)->OnReceiveCallback(Device, netvscPacket); - - NetVscOnReceiveCompletion(netvscPacket->Completion.Recv.ReceiveCompletionContext); - } - - /* ASSERT(list_empty(&listHead)); */ - - PutNetDevice(Device); - DPRINT_EXIT(NETVSC); -} - -static void NetVscSendReceiveCompletion(struct hv_device *Device, - u64 TransactionId) -{ - struct nvsp_message recvcompMessage; - int retries = 0; - int ret; - - DPRINT_DBG(NETVSC, "Sending receive completion pkt - %llx", - TransactionId); - - recvcompMessage.Header.MessageType = - NvspMessage1TypeSendRNDISPacketComplete; - - /* FIXME: Pass in the status */ - recvcompMessage.Messages.Version1Messages.SendRNDISPacketComplete.Status = NvspStatusSuccess; - -retry_send_cmplt: - /* Send the completion */ - ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, - &recvcompMessage, - sizeof(struct nvsp_message), - TransactionId, - VmbusPacketTypeCompletion, 0); - if (ret == 0) { - /* success */ - /* no-op */ - } else if (ret == -1) { - /* no more room...wait a bit and attempt to retry 3 times */ - retries++; - DPRINT_ERR(NETVSC, "unable to send receive completion pkt " - "(tid %llx)...retrying %d", TransactionId, retries); - - if (retries < 4) { - udelay(100); - goto retry_send_cmplt; - } else { - DPRINT_ERR(NETVSC, "unable to send receive completion " - "pkt (tid %llx)...give up retrying", - TransactionId); - } - } else { - DPRINT_ERR(NETVSC, "unable to send receive completion pkt - " - "%llx", TransactionId); - } -} - -/* Send a receive completion packet to RNDIS device (ie NetVsp) */ -static void NetVscOnReceiveCompletion(void *Context) -{ - struct hv_netvsc_packet *packet = Context; - struct hv_device *device = (struct hv_device *)packet->Device; - struct netvsc_device *netDevice; - u64 transactionId = 0; - bool fSendReceiveComp = false; - unsigned long flags; - - DPRINT_ENTER(NETVSC); - - /* ASSERT(packet->XferPagePacket); */ - - /* - * Even though it seems logical to do a GetOutboundNetDevice() here to - * send out receive completion, we are using GetInboundNetDevice() - * since we may have disable outbound traffic already. - */ - netDevice = GetInboundNetDevice(device); - if (!netDevice) { - DPRINT_ERR(NETVSC, "unable to get net device..." - "device being destroyed?"); - DPRINT_EXIT(NETVSC); - return; - } - - /* Overloading use of the lock. */ - spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags); - - /* ASSERT(packet->XferPagePacket->Count > 0); */ - packet->XferPagePacket->Count--; - - /* - * Last one in the line that represent 1 xfer page packet. - * Return the xfer page packet itself to the freelist - */ - if (packet->XferPagePacket->Count == 0) { - fSendReceiveComp = true; - transactionId = packet->Completion.Recv.ReceiveCompletionTid; - list_add_tail(&packet->XferPagePacket->ListEntry, - &netDevice->ReceivePacketList); - - } - - /* Put the packet back */ - list_add_tail(&packet->ListEntry, &netDevice->ReceivePacketList); - spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, flags); - - /* Send a receive completion for the xfer page packet */ - if (fSendReceiveComp) - NetVscSendReceiveCompletion(device, transactionId); - - PutNetDevice(device); - DPRINT_EXIT(NETVSC); -} - -static void NetVscOnChannelCallback(void *Context) -{ - int ret; - struct hv_device *device = Context; - struct netvsc_device *netDevice; - u32 bytesRecvd; - u64 requestId; - unsigned char *packet; - struct vmpacket_descriptor *desc; - unsigned char *buffer; - int bufferlen = NETVSC_PACKET_SIZE; - - - DPRINT_ENTER(NETVSC); - - /* ASSERT(device); */ - - packet = kzalloc(NETVSC_PACKET_SIZE * sizeof(unsigned char), - GFP_KERNEL); - if (!packet) - return; - buffer = packet; - - netDevice = GetInboundNetDevice(device); - if (!netDevice) { - DPRINT_ERR(NETVSC, "net device (%p) shutting down..." - "ignoring inbound packets", netDevice); - DPRINT_EXIT(NETVSC); - goto out; - } - - do { - ret = device->Driver->VmbusChannelInterface.RecvPacketRaw( - device, buffer, bufferlen, - &bytesRecvd, &requestId); - if (ret == 0) { - if (bytesRecvd > 0) { - DPRINT_DBG(NETVSC, "receive %d bytes, tid %llx", - bytesRecvd, requestId); - - desc = (struct vmpacket_descriptor *)buffer; - switch (desc->Type) { - case VmbusPacketTypeCompletion: - NetVscOnSendCompletion(device, desc); - break; - - case VmbusPacketTypeDataUsingTransferPages: - NetVscOnReceive(device, desc); - break; - - default: - DPRINT_ERR(NETVSC, - "unhandled packet type %d, " - "tid %llx len %d\n", - desc->Type, requestId, - bytesRecvd); - break; - } - - /* reset */ - if (bufferlen > NETVSC_PACKET_SIZE) { - kfree(buffer); - buffer = packet; - bufferlen = NETVSC_PACKET_SIZE; - } - } else { - /* reset */ - if (bufferlen > NETVSC_PACKET_SIZE) { - kfree(buffer); - buffer = packet; - bufferlen = NETVSC_PACKET_SIZE; - } - - break; - } - } else if (ret == -2) { - /* Handle large packet */ - buffer = kmalloc(bytesRecvd, GFP_ATOMIC); - if (buffer == NULL) { - /* Try again next time around */ - DPRINT_ERR(NETVSC, - "unable to allocate buffer of size " - "(%d)!!", bytesRecvd); - break; - } - - bufferlen = bytesRecvd; - } - } while (1); - - PutNetDevice(device); - DPRINT_EXIT(NETVSC); -out: - kfree(buffer); - return; -} diff --git a/drivers/staging/hv/NetVsc.h b/drivers/staging/hv/NetVsc.h deleted file mode 100644 index a6264db8388a..000000000000 --- a/drivers/staging/hv/NetVsc.h +++ /dev/null @@ -1,331 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ - - -#ifndef _NETVSC_H_ -#define _NETVSC_H_ - -#include -#include "VmbusPacketFormat.h" -#include "VmbusChannelInterface.h" -#include "NetVscApi.h" - - -#define NVSP_INVALID_PROTOCOL_VERSION ((u32)0xFFFFFFFF) - -#define NVSP_PROTOCOL_VERSION_1 2 -#define NVSP_MIN_PROTOCOL_VERSION NVSP_PROTOCOL_VERSION_1 -#define NVSP_MAX_PROTOCOL_VERSION NVSP_PROTOCOL_VERSION_1 - -enum { - NvspMessageTypeNone = 0, - - /* Init Messages */ - NvspMessageTypeInit = 1, - NvspMessageTypeInitComplete = 2, - - NvspVersionMessageStart = 100, - - /* Version 1 Messages */ - NvspMessage1TypeSendNdisVersion = NvspVersionMessageStart, - - NvspMessage1TypeSendReceiveBuffer, - NvspMessage1TypeSendReceiveBufferComplete, - NvspMessage1TypeRevokeReceiveBuffer, - - NvspMessage1TypeSendSendBuffer, - NvspMessage1TypeSendSendBufferComplete, - NvspMessage1TypeRevokeSendBuffer, - - NvspMessage1TypeSendRNDISPacket, - NvspMessage1TypeSendRNDISPacketComplete, - - /* - * This should be set to the number of messages for the version with - * the maximum number of messages. - */ - NvspNumMessagePerVersion = 9, -}; - -enum { - NvspStatusNone = 0, - NvspStatusSuccess, - NvspStatusFailure, - NvspStatusProtocolVersionRangeTooNew, - NvspStatusProtocolVersionRangeTooOld, - NvspStatusInvalidRndisPacket, - NvspStatusBusy, - NvspStatusMax, -}; - -struct nvsp_message_header { - u32 MessageType; -}; - -/* Init Messages */ - -/* - * This message is used by the VSC to initialize the channel after the channels - * has been opened. This message should never include anything other then - * versioning (i.e. this message will be the same for ever). - */ -struct nvsp_message_init { - u32 MinProtocolVersion; - u32 MaxProtocolVersion; -} __attribute__((packed)); - -/* - * This message is used by the VSP to complete the initialization of the - * channel. This message should never include anything other then versioning - * (i.e. this message will be the same for ever). - */ -struct nvsp_message_init_complete { - u32 NegotiatedProtocolVersion; - u32 MaximumMdlChainLength; - u32 Status; -} __attribute__((packed)); - -union nvsp_message_init_uber { - struct nvsp_message_init Init; - struct nvsp_message_init_complete InitComplete; -} __attribute__((packed)); - -/* Version 1 Messages */ - -/* - * This message is used by the VSC to send the NDIS version to the VSP. The VSP - * can use this information when handling OIDs sent by the VSC. - */ -struct nvsp_1_message_send_ndis_version { - u32 NdisMajorVersion; - u32 NdisMinorVersion; -} __attribute__((packed)); - -/* - * This message is used by the VSC to send a receive buffer to the VSP. The VSP - * can then use the receive buffer to send data to the VSC. - */ -struct nvsp_1_message_send_receive_buffer { - u32 GpadlHandle; - u16 Id; -} __attribute__((packed)); - -struct nvsp_1_receive_buffer_section { - u32 Offset; - u32 SubAllocationSize; - u32 NumSubAllocations; - u32 EndOffset; -} __attribute__((packed)); - -/* - * This message is used by the VSP to acknowledge a receive buffer send by the - * VSC. This message must be sent by the VSP before the VSP uses the receive - * buffer. - */ -struct nvsp_1_message_send_receive_buffer_complete { - u32 Status; - u32 NumSections; - - /* - * The receive buffer is split into two parts, a large suballocation - * section and a small suballocation section. These sections are then - * suballocated by a certain size. - */ - - /* - * For example, the following break up of the receive buffer has 6 - * large suballocations and 10 small suballocations. - */ - - /* - * | Large Section | | Small Section | - * ------------------------------------------------------------ - * | | | | | | | | | | | | | | | | | | - * | | - * LargeOffset SmallOffset - */ - - struct nvsp_1_receive_buffer_section Sections[1]; -} __attribute__((packed)); - -/* - * This message is sent by the VSC to revoke the receive buffer. After the VSP - * completes this transaction, the vsp should never use the receive buffer - * again. - */ -struct nvsp_1_message_revoke_receive_buffer { - u16 Id; -}; - -/* - * This message is used by the VSC to send a send buffer to the VSP. The VSC - * can then use the send buffer to send data to the VSP. - */ -struct nvsp_1_message_send_send_buffer { - u32 GpadlHandle; - u16 Id; -} __attribute__((packed)); - -/* - * This message is used by the VSP to acknowledge a send buffer sent by the - * VSC. This message must be sent by the VSP before the VSP uses the sent - * buffer. - */ -struct nvsp_1_message_send_send_buffer_complete { - u32 Status; - - /* - * The VSC gets to choose the size of the send buffer and the VSP gets - * to choose the sections size of the buffer. This was done to enable - * dynamic reconfigurations when the cost of GPA-direct buffers - * decreases. - */ - u32 SectionSize; -} __attribute__((packed)); - -/* - * This message is sent by the VSC to revoke the send buffer. After the VSP - * completes this transaction, the vsp should never use the send buffer again. - */ -struct nvsp_1_message_revoke_send_buffer { - u16 Id; -}; - -/* - * This message is used by both the VSP and the VSC to send a RNDIS message to - * the opposite channel endpoint. - */ -struct nvsp_1_message_send_rndis_packet { - /* - * This field is specified by RNIDS. They assume there's two different - * channels of communication. However, the Network VSP only has one. - * Therefore, the channel travels with the RNDIS packet. - */ - u32 ChannelType; - - /* - * This field is used to send part or all of the data through a send - * buffer. This values specifies an index into the send buffer. If the - * index is 0xFFFFFFFF, then the send buffer is not being used and all - * of the data was sent through other VMBus mechanisms. - */ - u32 SendBufferSectionIndex; - u32 SendBufferSectionSize; -} __attribute__((packed)); - -/* - * This message is used by both the VSP and the VSC to complete a RNDIS message - * to the opposite channel endpoint. At this point, the initiator of this - * message cannot use any resources associated with the original RNDIS packet. - */ -struct nvsp_1_message_send_rndis_packet_complete { - u32 Status; -}; - -union nvsp_1_message_uber { - struct nvsp_1_message_send_ndis_version SendNdisVersion; - - struct nvsp_1_message_send_receive_buffer SendReceiveBuffer; - struct nvsp_1_message_send_receive_buffer_complete - SendReceiveBufferComplete; - struct nvsp_1_message_revoke_receive_buffer RevokeReceiveBuffer; - - struct nvsp_1_message_send_send_buffer SendSendBuffer; - struct nvsp_1_message_send_send_buffer_complete SendSendBufferComplete; - struct nvsp_1_message_revoke_send_buffer RevokeSendBuffer; - - struct nvsp_1_message_send_rndis_packet SendRNDISPacket; - struct nvsp_1_message_send_rndis_packet_complete - SendRNDISPacketComplete; -} __attribute__((packed)); - -union nvsp_all_messages { - union nvsp_message_init_uber InitMessages; - union nvsp_1_message_uber Version1Messages; -} __attribute__((packed)); - -/* ALL Messages */ -struct nvsp_message { - struct nvsp_message_header Header; - union nvsp_all_messages Messages; -} __attribute__((packed)); - - - - -/* #define NVSC_MIN_PROTOCOL_VERSION 1 */ -/* #define NVSC_MAX_PROTOCOL_VERSION 1 */ - -#define NETVSC_SEND_BUFFER_SIZE (64*1024) /* 64K */ -#define NETVSC_SEND_BUFFER_ID 0xface - - -#define NETVSC_RECEIVE_BUFFER_SIZE (1024*1024) /* 1MB */ - -#define NETVSC_RECEIVE_BUFFER_ID 0xcafe - -#define NETVSC_RECEIVE_SG_COUNT 1 - -/* Preallocated receive packets */ -#define NETVSC_RECEIVE_PACKETLIST_COUNT 256 - -#define NETVSC_PACKET_SIZE 2048 - -/* Per netvsc channel-specific */ -struct netvsc_device { - struct hv_device *Device; - - atomic_t RefCount; - atomic_t NumOutstandingSends; - /* - * List of free preallocated hv_netvsc_packet to represent receive - * packet - */ - struct list_head ReceivePacketList; - spinlock_t receive_packet_list_lock; - - /* Send buffer allocated by us but manages by NetVSP */ - void *SendBuffer; - u32 SendBufferSize; - u32 SendBufferGpadlHandle; - u32 SendSectionSize; - - /* Receive buffer allocated by us but manages by NetVSP */ - void *ReceiveBuffer; - u32 ReceiveBufferSize; - u32 ReceiveBufferGpadlHandle; - u32 ReceiveSectionCount; - struct nvsp_1_receive_buffer_section *ReceiveSections; - - /* Used for NetVSP initialization protocol */ - struct osd_waitevent *ChannelInitEvent; - struct nvsp_message ChannelInitPacket; - - struct nvsp_message RevokePacket; - /* unsigned char HwMacAddr[HW_MACADDR_LEN]; */ - - /* Holds rndis device info */ - void *Extension; -}; - -#endif /* _NETVSC_H_ */ diff --git a/drivers/staging/hv/RndisFilter.h b/drivers/staging/hv/RndisFilter.h index fa7dd79ddebf..764b9bf3e5dc 100644 --- a/drivers/staging/hv/RndisFilter.h +++ b/drivers/staging/hv/RndisFilter.h @@ -27,7 +27,7 @@ #define __struct_bcount(x) -#include "NetVsc.h" +#include "netvsc.h" #include "rndis.h" diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c new file mode 100644 index 000000000000..1000989cc0a7 --- /dev/null +++ b/drivers/staging/hv/netvsc.c @@ -0,0 +1,1393 @@ +/* + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + */ +#include +#include +#include +#include +#include +#include "osd.h" +#include "logging.h" +#include "netvsc.h" +#include "RndisFilter.h" + + +/* Globals */ +static const char *gDriverName = "netvsc"; + +/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */ +static const struct hv_guid gNetVscDeviceType = { + .data = { + 0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, + 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E + } +}; + +static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo); + +static int NetVscOnDeviceRemove(struct hv_device *Device); + +static void NetVscOnCleanup(struct hv_driver *Driver); + +static void NetVscOnChannelCallback(void *context); + +static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device); + +static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device); + +static int NetVscDestroySendBuffer(struct netvsc_device *NetDevice); + +static int NetVscDestroyReceiveBuffer(struct netvsc_device *NetDevice); + +static int NetVscConnectToVsp(struct hv_device *Device); + +static void NetVscOnSendCompletion(struct hv_device *Device, + struct vmpacket_descriptor *Packet); + +static int NetVscOnSend(struct hv_device *Device, + struct hv_netvsc_packet *Packet); + +static void NetVscOnReceive(struct hv_device *Device, + struct vmpacket_descriptor *Packet); + +static void NetVscOnReceiveCompletion(void *Context); + +static void NetVscSendReceiveCompletion(struct hv_device *Device, + u64 TransactionId); + + +static struct netvsc_device *AllocNetDevice(struct hv_device *Device) +{ + struct netvsc_device *netDevice; + + netDevice = kzalloc(sizeof(struct netvsc_device), GFP_KERNEL); + if (!netDevice) + return NULL; + + /* Set to 2 to allow both inbound and outbound traffic */ + atomic_cmpxchg(&netDevice->RefCount, 0, 2); + + netDevice->Device = Device; + Device->Extension = netDevice; + + return netDevice; +} + +static void FreeNetDevice(struct netvsc_device *Device) +{ + WARN_ON(atomic_read(&Device->RefCount) == 0); + Device->Device->Extension = NULL; + kfree(Device); +} + + +/* Get the net device object iff exists and its refcount > 1 */ +static struct netvsc_device *GetOutboundNetDevice(struct hv_device *Device) +{ + struct netvsc_device *netDevice; + + netDevice = Device->Extension; + if (netDevice && atomic_read(&netDevice->RefCount) > 1) + atomic_inc(&netDevice->RefCount); + else + netDevice = NULL; + + return netDevice; +} + +/* Get the net device object iff exists and its refcount > 0 */ +static struct netvsc_device *GetInboundNetDevice(struct hv_device *Device) +{ + struct netvsc_device *netDevice; + + netDevice = Device->Extension; + if (netDevice && atomic_read(&netDevice->RefCount)) + atomic_inc(&netDevice->RefCount); + else + netDevice = NULL; + + return netDevice; +} + +static void PutNetDevice(struct hv_device *Device) +{ + struct netvsc_device *netDevice; + + netDevice = Device->Extension; + /* ASSERT(netDevice); */ + + atomic_dec(&netDevice->RefCount); +} + +static struct netvsc_device *ReleaseOutboundNetDevice(struct hv_device *Device) +{ + struct netvsc_device *netDevice; + + netDevice = Device->Extension; + if (netDevice == NULL) + return NULL; + + /* Busy wait until the ref drop to 2, then set it to 1 */ + while (atomic_cmpxchg(&netDevice->RefCount, 2, 1) != 2) + udelay(100); + + return netDevice; +} + +static struct netvsc_device *ReleaseInboundNetDevice(struct hv_device *Device) +{ + struct netvsc_device *netDevice; + + netDevice = Device->Extension; + if (netDevice == NULL) + return NULL; + + /* Busy wait until the ref drop to 1, then set it to 0 */ + while (atomic_cmpxchg(&netDevice->RefCount, 1, 0) != 1) + udelay(100); + + Device->Extension = NULL; + return netDevice; +} + +/* + * NetVscInitialize - Main entry point + */ +int NetVscInitialize(struct hv_driver *drv) +{ + struct netvsc_driver *driver = (struct netvsc_driver *)drv; + + DPRINT_ENTER(NETVSC); + + DPRINT_DBG(NETVSC, "sizeof(struct hv_netvsc_packet)=%zd, " + "sizeof(struct nvsp_message)=%zd, " + "sizeof(struct vmtransfer_page_packet_header)=%zd", + sizeof(struct hv_netvsc_packet), + sizeof(struct nvsp_message), + sizeof(struct vmtransfer_page_packet_header)); + + /* Make sure we are at least 2 pages since 1 page is used for control */ + /* ASSERT(driver->RingBufferSize >= (PAGE_SIZE << 1)); */ + + drv->name = gDriverName; + memcpy(&drv->deviceType, &gNetVscDeviceType, sizeof(struct hv_guid)); + + /* Make sure it is set by the caller */ + /* FIXME: These probably should still be tested in some way */ + /* ASSERT(driver->OnReceiveCallback); */ + /* ASSERT(driver->OnLinkStatusChanged); */ + + /* Setup the dispatch table */ + driver->Base.OnDeviceAdd = NetVscOnDeviceAdd; + driver->Base.OnDeviceRemove = NetVscOnDeviceRemove; + driver->Base.OnCleanup = NetVscOnCleanup; + + driver->OnSend = NetVscOnSend; + + RndisFilterInit(driver); + + DPRINT_EXIT(NETVSC); + + return 0; +} + +static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device) +{ + int ret = 0; + struct netvsc_device *netDevice; + struct nvsp_message *initPacket; + + DPRINT_ENTER(NETVSC); + + netDevice = GetOutboundNetDevice(Device); + if (!netDevice) { + DPRINT_ERR(NETVSC, "unable to get net device..." + "device being destroyed?"); + DPRINT_EXIT(NETVSC); + return -1; + } + /* ASSERT(netDevice->ReceiveBufferSize > 0); */ + /* page-size grandularity */ + /* ASSERT((netDevice->ReceiveBufferSize & (PAGE_SIZE - 1)) == 0); */ + + netDevice->ReceiveBuffer = + osd_PageAlloc(netDevice->ReceiveBufferSize >> PAGE_SHIFT); + if (!netDevice->ReceiveBuffer) { + DPRINT_ERR(NETVSC, + "unable to allocate receive buffer of size %d", + netDevice->ReceiveBufferSize); + ret = -1; + goto Cleanup; + } + /* page-aligned buffer */ + /* ASSERT(((unsigned long)netDevice->ReceiveBuffer & (PAGE_SIZE - 1)) == */ + /* 0); */ + + DPRINT_INFO(NETVSC, "Establishing receive buffer's GPADL..."); + + /* + * Establish the gpadl handle for this buffer on this + * channel. Note: This call uses the vmbus connection rather + * than the channel to establish the gpadl handle. + */ + ret = Device->Driver->VmbusChannelInterface.EstablishGpadl(Device, + netDevice->ReceiveBuffer, + netDevice->ReceiveBufferSize, + &netDevice->ReceiveBufferGpadlHandle); + if (ret != 0) { + DPRINT_ERR(NETVSC, + "unable to establish receive buffer's gpadl"); + goto Cleanup; + } + + /* osd_WaitEventWait(ext->ChannelInitEvent); */ + + /* Notify the NetVsp of the gpadl handle */ + DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendReceiveBuffer..."); + + initPacket = &netDevice->ChannelInitPacket; + + memset(initPacket, 0, sizeof(struct nvsp_message)); + + initPacket->Header.MessageType = NvspMessage1TypeSendReceiveBuffer; + initPacket->Messages.Version1Messages.SendReceiveBuffer.GpadlHandle = netDevice->ReceiveBufferGpadlHandle; + initPacket->Messages.Version1Messages.SendReceiveBuffer.Id = NETVSC_RECEIVE_BUFFER_ID; + + /* Send the gpadl notification request */ + ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, + initPacket, + sizeof(struct nvsp_message), + (unsigned long)initPacket, + VmbusPacketTypeDataInBand, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + if (ret != 0) { + DPRINT_ERR(NETVSC, + "unable to send receive buffer's gpadl to netvsp"); + goto Cleanup; + } + + osd_WaitEventWait(netDevice->ChannelInitEvent); + + /* Check the response */ + if (initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Status != NvspStatusSuccess) { + DPRINT_ERR(NETVSC, "Unable to complete receive buffer " + "initialzation with NetVsp - status %d", + initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Status); + ret = -1; + goto Cleanup; + } + + /* Parse the response */ + /* ASSERT(netDevice->ReceiveSectionCount == 0); */ + /* ASSERT(netDevice->ReceiveSections == NULL); */ + + netDevice->ReceiveSectionCount = initPacket->Messages.Version1Messages.SendReceiveBufferComplete.NumSections; + + netDevice->ReceiveSections = kmalloc(netDevice->ReceiveSectionCount * sizeof(struct nvsp_1_receive_buffer_section), GFP_KERNEL); + if (netDevice->ReceiveSections == NULL) { + ret = -1; + goto Cleanup; + } + + memcpy(netDevice->ReceiveSections, + initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Sections, + netDevice->ReceiveSectionCount * sizeof(struct nvsp_1_receive_buffer_section)); + + DPRINT_INFO(NETVSC, "Receive sections info (count %d, offset %d, " + "endoffset %d, suballoc size %d, num suballocs %d)", + netDevice->ReceiveSectionCount, + netDevice->ReceiveSections[0].Offset, + netDevice->ReceiveSections[0].EndOffset, + netDevice->ReceiveSections[0].SubAllocationSize, + netDevice->ReceiveSections[0].NumSubAllocations); + + /* + * For 1st release, there should only be 1 section that represents the + * entire receive buffer + */ + if (netDevice->ReceiveSectionCount != 1 || + netDevice->ReceiveSections->Offset != 0) { + ret = -1; + goto Cleanup; + } + + goto Exit; + +Cleanup: + NetVscDestroyReceiveBuffer(netDevice); + +Exit: + PutNetDevice(Device); + DPRINT_EXIT(NETVSC); + return ret; +} + +static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device) +{ + int ret = 0; + struct netvsc_device *netDevice; + struct nvsp_message *initPacket; + + DPRINT_ENTER(NETVSC); + + netDevice = GetOutboundNetDevice(Device); + if (!netDevice) { + DPRINT_ERR(NETVSC, "unable to get net device..." + "device being destroyed?"); + DPRINT_EXIT(NETVSC); + return -1; + } + if (netDevice->SendBufferSize <= 0) { + ret = -EINVAL; + goto Cleanup; + } + + /* page-size grandularity */ + /* ASSERT((netDevice->SendBufferSize & (PAGE_SIZE - 1)) == 0); */ + + netDevice->SendBuffer = + osd_PageAlloc(netDevice->SendBufferSize >> PAGE_SHIFT); + if (!netDevice->SendBuffer) { + DPRINT_ERR(NETVSC, "unable to allocate send buffer of size %d", + netDevice->SendBufferSize); + ret = -1; + goto Cleanup; + } + /* page-aligned buffer */ + /* ASSERT(((unsigned long)netDevice->SendBuffer & (PAGE_SIZE - 1)) == 0); */ + + DPRINT_INFO(NETVSC, "Establishing send buffer's GPADL..."); + + /* + * Establish the gpadl handle for this buffer on this + * channel. Note: This call uses the vmbus connection rather + * than the channel to establish the gpadl handle. + */ + ret = Device->Driver->VmbusChannelInterface.EstablishGpadl(Device, + netDevice->SendBuffer, + netDevice->SendBufferSize, + &netDevice->SendBufferGpadlHandle); + if (ret != 0) { + DPRINT_ERR(NETVSC, "unable to establish send buffer's gpadl"); + goto Cleanup; + } + + /* osd_WaitEventWait(ext->ChannelInitEvent); */ + + /* Notify the NetVsp of the gpadl handle */ + DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendSendBuffer..."); + + initPacket = &netDevice->ChannelInitPacket; + + memset(initPacket, 0, sizeof(struct nvsp_message)); + + initPacket->Header.MessageType = NvspMessage1TypeSendSendBuffer; + initPacket->Messages.Version1Messages.SendReceiveBuffer.GpadlHandle = netDevice->SendBufferGpadlHandle; + initPacket->Messages.Version1Messages.SendReceiveBuffer.Id = NETVSC_SEND_BUFFER_ID; + + /* Send the gpadl notification request */ + ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, + initPacket, sizeof(struct nvsp_message), + (unsigned long)initPacket, + VmbusPacketTypeDataInBand, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + if (ret != 0) { + DPRINT_ERR(NETVSC, + "unable to send receive buffer's gpadl to netvsp"); + goto Cleanup; + } + + osd_WaitEventWait(netDevice->ChannelInitEvent); + + /* Check the response */ + if (initPacket->Messages.Version1Messages.SendSendBufferComplete.Status != NvspStatusSuccess) { + DPRINT_ERR(NETVSC, "Unable to complete send buffer " + "initialzation with NetVsp - status %d", + initPacket->Messages.Version1Messages.SendSendBufferComplete.Status); + ret = -1; + goto Cleanup; + } + + netDevice->SendSectionSize = initPacket->Messages.Version1Messages.SendSendBufferComplete.SectionSize; + + goto Exit; + +Cleanup: + NetVscDestroySendBuffer(netDevice); + +Exit: + PutNetDevice(Device); + DPRINT_EXIT(NETVSC); + return ret; +} + +static int NetVscDestroyReceiveBuffer(struct netvsc_device *NetDevice) +{ + struct nvsp_message *revokePacket; + int ret = 0; + + DPRINT_ENTER(NETVSC); + + /* + * If we got a section count, it means we received a + * SendReceiveBufferComplete msg (ie sent + * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need + * to send a revoke msg here + */ + if (NetDevice->ReceiveSectionCount) { + DPRINT_INFO(NETVSC, + "Sending NvspMessage1TypeRevokeReceiveBuffer..."); + + /* Send the revoke receive buffer */ + revokePacket = &NetDevice->RevokePacket; + memset(revokePacket, 0, sizeof(struct nvsp_message)); + + revokePacket->Header.MessageType = NvspMessage1TypeRevokeReceiveBuffer; + revokePacket->Messages.Version1Messages.RevokeReceiveBuffer.Id = NETVSC_RECEIVE_BUFFER_ID; + + ret = NetDevice->Device->Driver->VmbusChannelInterface.SendPacket( + NetDevice->Device, + revokePacket, + sizeof(struct nvsp_message), + (unsigned long)revokePacket, + VmbusPacketTypeDataInBand, 0); + /* + * If we failed here, we might as well return and + * have a leak rather than continue and a bugchk + */ + if (ret != 0) { + DPRINT_ERR(NETVSC, "unable to send revoke receive " + "buffer to netvsp"); + DPRINT_EXIT(NETVSC); + return -1; + } + } + + /* Teardown the gpadl on the vsp end */ + if (NetDevice->ReceiveBufferGpadlHandle) { + DPRINT_INFO(NETVSC, "Tearing down receive buffer's GPADL..."); + + ret = NetDevice->Device->Driver->VmbusChannelInterface.TeardownGpadl( + NetDevice->Device, + NetDevice->ReceiveBufferGpadlHandle); + + /* If we failed here, we might as well return and have a leak rather than continue and a bugchk */ + if (ret != 0) { + DPRINT_ERR(NETVSC, + "unable to teardown receive buffer's gpadl"); + DPRINT_EXIT(NETVSC); + return -1; + } + NetDevice->ReceiveBufferGpadlHandle = 0; + } + + if (NetDevice->ReceiveBuffer) { + DPRINT_INFO(NETVSC, "Freeing up receive buffer..."); + + /* Free up the receive buffer */ + osd_PageFree(NetDevice->ReceiveBuffer, + NetDevice->ReceiveBufferSize >> PAGE_SHIFT); + NetDevice->ReceiveBuffer = NULL; + } + + if (NetDevice->ReceiveSections) { + NetDevice->ReceiveSectionCount = 0; + kfree(NetDevice->ReceiveSections); + NetDevice->ReceiveSections = NULL; + } + + DPRINT_EXIT(NETVSC); + + return ret; +} + +static int NetVscDestroySendBuffer(struct netvsc_device *NetDevice) +{ + struct nvsp_message *revokePacket; + int ret = 0; + + DPRINT_ENTER(NETVSC); + + /* + * If we got a section count, it means we received a + * SendReceiveBufferComplete msg (ie sent + * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need + * to send a revoke msg here + */ + if (NetDevice->SendSectionSize) { + DPRINT_INFO(NETVSC, + "Sending NvspMessage1TypeRevokeSendBuffer..."); + + /* Send the revoke send buffer */ + revokePacket = &NetDevice->RevokePacket; + memset(revokePacket, 0, sizeof(struct nvsp_message)); + + revokePacket->Header.MessageType = NvspMessage1TypeRevokeSendBuffer; + revokePacket->Messages.Version1Messages.RevokeSendBuffer.Id = NETVSC_SEND_BUFFER_ID; + + ret = NetDevice->Device->Driver->VmbusChannelInterface.SendPacket(NetDevice->Device, + revokePacket, + sizeof(struct nvsp_message), + (unsigned long)revokePacket, + VmbusPacketTypeDataInBand, 0); + /* + * If we failed here, we might as well return and have a leak + * rather than continue and a bugchk + */ + if (ret != 0) { + DPRINT_ERR(NETVSC, "unable to send revoke send buffer " + "to netvsp"); + DPRINT_EXIT(NETVSC); + return -1; + } + } + + /* Teardown the gpadl on the vsp end */ + if (NetDevice->SendBufferGpadlHandle) { + DPRINT_INFO(NETVSC, "Tearing down send buffer's GPADL..."); + + ret = NetDevice->Device->Driver->VmbusChannelInterface.TeardownGpadl(NetDevice->Device, NetDevice->SendBufferGpadlHandle); + + /* + * If we failed here, we might as well return and have a leak + * rather than continue and a bugchk + */ + if (ret != 0) { + DPRINT_ERR(NETVSC, "unable to teardown send buffer's " + "gpadl"); + DPRINT_EXIT(NETVSC); + return -1; + } + NetDevice->SendBufferGpadlHandle = 0; + } + + if (NetDevice->SendBuffer) { + DPRINT_INFO(NETVSC, "Freeing up send buffer..."); + + /* Free up the receive buffer */ + osd_PageFree(NetDevice->SendBuffer, + NetDevice->SendBufferSize >> PAGE_SHIFT); + NetDevice->SendBuffer = NULL; + } + + DPRINT_EXIT(NETVSC); + + return ret; +} + + +static int NetVscConnectToVsp(struct hv_device *Device) +{ + int ret; + struct netvsc_device *netDevice; + struct nvsp_message *initPacket; + int ndisVersion; + + DPRINT_ENTER(NETVSC); + + netDevice = GetOutboundNetDevice(Device); + if (!netDevice) { + DPRINT_ERR(NETVSC, "unable to get net device..." + "device being destroyed?"); + DPRINT_EXIT(NETVSC); + return -1; + } + + initPacket = &netDevice->ChannelInitPacket; + + memset(initPacket, 0, sizeof(struct nvsp_message)); + initPacket->Header.MessageType = NvspMessageTypeInit; + initPacket->Messages.InitMessages.Init.MinProtocolVersion = NVSP_MIN_PROTOCOL_VERSION; + initPacket->Messages.InitMessages.Init.MaxProtocolVersion = NVSP_MAX_PROTOCOL_VERSION; + + DPRINT_INFO(NETVSC, "Sending NvspMessageTypeInit..."); + + /* Send the init request */ + ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, + initPacket, + sizeof(struct nvsp_message), + (unsigned long)initPacket, + VmbusPacketTypeDataInBand, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + + if (ret != 0) { + DPRINT_ERR(NETVSC, "unable to send NvspMessageTypeInit"); + goto Cleanup; + } + + osd_WaitEventWait(netDevice->ChannelInitEvent); + + /* Now, check the response */ + /* ASSERT(initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength <= MAX_MULTIPAGE_BUFFER_COUNT); */ + DPRINT_INFO(NETVSC, "NvspMessageTypeInit status(%d) max mdl chain (%d)", + initPacket->Messages.InitMessages.InitComplete.Status, + initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength); + + if (initPacket->Messages.InitMessages.InitComplete.Status != + NvspStatusSuccess) { + DPRINT_ERR(NETVSC, + "unable to initialize with netvsp (status 0x%x)", + initPacket->Messages.InitMessages.InitComplete.Status); + ret = -1; + goto Cleanup; + } + + if (initPacket->Messages.InitMessages.InitComplete.NegotiatedProtocolVersion != NVSP_PROTOCOL_VERSION_1) { + DPRINT_ERR(NETVSC, "unable to initialize with netvsp " + "(version expected 1 got %d)", + initPacket->Messages.InitMessages.InitComplete.NegotiatedProtocolVersion); + ret = -1; + goto Cleanup; + } + DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendNdisVersion..."); + + /* Send the ndis version */ + memset(initPacket, 0, sizeof(struct nvsp_message)); + + ndisVersion = 0x00050000; + + initPacket->Header.MessageType = NvspMessage1TypeSendNdisVersion; + initPacket->Messages.Version1Messages.SendNdisVersion.NdisMajorVersion = + (ndisVersion & 0xFFFF0000) >> 16; + initPacket->Messages.Version1Messages.SendNdisVersion.NdisMinorVersion = + ndisVersion & 0xFFFF; + + /* Send the init request */ + ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, + initPacket, + sizeof(struct nvsp_message), + (unsigned long)initPacket, + VmbusPacketTypeDataInBand, 0); + if (ret != 0) { + DPRINT_ERR(NETVSC, + "unable to send NvspMessage1TypeSendNdisVersion"); + ret = -1; + goto Cleanup; + } + /* + * BUGBUG - We have to wait for the above msg since the + * netvsp uses KMCL which acknowledges packet (completion + * packet) since our Vmbus always set the + * VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED flag + */ + /* osd_WaitEventWait(NetVscChannel->ChannelInitEvent); */ + + /* Post the big receive buffer to NetVSP */ + ret = NetVscInitializeReceiveBufferWithNetVsp(Device); + if (ret == 0) + ret = NetVscInitializeSendBufferWithNetVsp(Device); + +Cleanup: + PutNetDevice(Device); + DPRINT_EXIT(NETVSC); + return ret; +} + +static void NetVscDisconnectFromVsp(struct netvsc_device *NetDevice) +{ + DPRINT_ENTER(NETVSC); + + NetVscDestroyReceiveBuffer(NetDevice); + NetVscDestroySendBuffer(NetDevice); + + DPRINT_EXIT(NETVSC); +} + +/* + * NetVscOnDeviceAdd - Callback when the device belonging to this driver is added + */ +static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) +{ + int ret = 0; + int i; + struct netvsc_device *netDevice; + struct hv_netvsc_packet *packet, *pos; + struct netvsc_driver *netDriver = + (struct netvsc_driver *)Device->Driver; + + DPRINT_ENTER(NETVSC); + + netDevice = AllocNetDevice(Device); + if (!netDevice) { + ret = -1; + goto Cleanup; + } + + DPRINT_DBG(NETVSC, "netvsc channel object allocated - %p", netDevice); + + /* Initialize the NetVSC channel extension */ + netDevice->ReceiveBufferSize = NETVSC_RECEIVE_BUFFER_SIZE; + spin_lock_init(&netDevice->receive_packet_list_lock); + + netDevice->SendBufferSize = NETVSC_SEND_BUFFER_SIZE; + + INIT_LIST_HEAD(&netDevice->ReceivePacketList); + + for (i = 0; i < NETVSC_RECEIVE_PACKETLIST_COUNT; i++) { + packet = kzalloc(sizeof(struct hv_netvsc_packet) + + (NETVSC_RECEIVE_SG_COUNT * + sizeof(struct hv_page_buffer)), GFP_KERNEL); + if (!packet) { + DPRINT_DBG(NETVSC, "unable to allocate netvsc pkts " + "for receive pool (wanted %d got %d)", + NETVSC_RECEIVE_PACKETLIST_COUNT, i); + break; + } + list_add_tail(&packet->ListEntry, + &netDevice->ReceivePacketList); + } + netDevice->ChannelInitEvent = osd_WaitEventCreate(); + if (!netDevice->ChannelInitEvent) { + ret = -ENOMEM; + goto Cleanup; + } + + /* Open the channel */ + ret = Device->Driver->VmbusChannelInterface.Open(Device, + netDriver->RingBufferSize, + netDriver->RingBufferSize, + NULL, 0, + NetVscOnChannelCallback, + Device); + + if (ret != 0) { + DPRINT_ERR(NETVSC, "unable to open channel: %d", ret); + ret = -1; + goto Cleanup; + } + + /* Channel is opened */ + DPRINT_INFO(NETVSC, "*** NetVSC channel opened successfully! ***"); + + /* Connect with the NetVsp */ + ret = NetVscConnectToVsp(Device); + if (ret != 0) { + DPRINT_ERR(NETVSC, "unable to connect to NetVSP - %d", ret); + ret = -1; + goto Close; + } + + DPRINT_INFO(NETVSC, "*** NetVSC channel handshake result - %d ***", + ret); + + DPRINT_EXIT(NETVSC); + return ret; + +Close: + /* Now, we can close the channel safely */ + Device->Driver->VmbusChannelInterface.Close(Device); + +Cleanup: + + if (netDevice) { + kfree(netDevice->ChannelInitEvent); + + list_for_each_entry_safe(packet, pos, + &netDevice->ReceivePacketList, + ListEntry) { + list_del(&packet->ListEntry); + kfree(packet); + } + + ReleaseOutboundNetDevice(Device); + ReleaseInboundNetDevice(Device); + + FreeNetDevice(netDevice); + } + + DPRINT_EXIT(NETVSC); + return ret; +} + +/* + * NetVscOnDeviceRemove - Callback when the root bus device is removed + */ +static int NetVscOnDeviceRemove(struct hv_device *Device) +{ + struct netvsc_device *netDevice; + struct hv_netvsc_packet *netvscPacket, *pos; + + DPRINT_ENTER(NETVSC); + + DPRINT_INFO(NETVSC, "Disabling outbound traffic on net device (%p)...", + Device->Extension); + + /* Stop outbound traffic ie sends and receives completions */ + netDevice = ReleaseOutboundNetDevice(Device); + if (!netDevice) { + DPRINT_ERR(NETVSC, "No net device present!!"); + return -1; + } + + /* Wait for all send completions */ + while (atomic_read(&netDevice->NumOutstandingSends)) { + DPRINT_INFO(NETVSC, "waiting for %d requests to complete...", + atomic_read(&netDevice->NumOutstandingSends)); + udelay(100); + } + + DPRINT_INFO(NETVSC, "Disconnecting from netvsp..."); + + NetVscDisconnectFromVsp(netDevice); + + DPRINT_INFO(NETVSC, "Disabling inbound traffic on net device (%p)...", + Device->Extension); + + /* Stop inbound traffic ie receives and sends completions */ + netDevice = ReleaseInboundNetDevice(Device); + + /* At this point, no one should be accessing netDevice except in here */ + DPRINT_INFO(NETVSC, "net device (%p) safe to remove", netDevice); + + /* Now, we can close the channel safely */ + Device->Driver->VmbusChannelInterface.Close(Device); + + /* Release all resources */ + list_for_each_entry_safe(netvscPacket, pos, + &netDevice->ReceivePacketList, ListEntry) { + list_del(&netvscPacket->ListEntry); + kfree(netvscPacket); + } + + kfree(netDevice->ChannelInitEvent); + FreeNetDevice(netDevice); + + DPRINT_EXIT(NETVSC); + return 0; +} + +/* + * NetVscOnCleanup - Perform any cleanup when the driver is removed + */ +static void NetVscOnCleanup(struct hv_driver *drv) +{ + DPRINT_ENTER(NETVSC); + DPRINT_EXIT(NETVSC); +} + +static void NetVscOnSendCompletion(struct hv_device *Device, + struct vmpacket_descriptor *Packet) +{ + struct netvsc_device *netDevice; + struct nvsp_message *nvspPacket; + struct hv_netvsc_packet *nvscPacket; + + DPRINT_ENTER(NETVSC); + + netDevice = GetInboundNetDevice(Device); + if (!netDevice) { + DPRINT_ERR(NETVSC, "unable to get net device..." + "device being destroyed?"); + DPRINT_EXIT(NETVSC); + return; + } + + nvspPacket = (struct nvsp_message *)((unsigned long)Packet + (Packet->DataOffset8 << 3)); + + DPRINT_DBG(NETVSC, "send completion packet - type %d", + nvspPacket->Header.MessageType); + + if ((nvspPacket->Header.MessageType == NvspMessageTypeInitComplete) || + (nvspPacket->Header.MessageType == + NvspMessage1TypeSendReceiveBufferComplete) || + (nvspPacket->Header.MessageType == + NvspMessage1TypeSendSendBufferComplete)) { + /* Copy the response back */ + memcpy(&netDevice->ChannelInitPacket, nvspPacket, + sizeof(struct nvsp_message)); + osd_WaitEventSet(netDevice->ChannelInitEvent); + } else if (nvspPacket->Header.MessageType == + NvspMessage1TypeSendRNDISPacketComplete) { + /* Get the send context */ + nvscPacket = (struct hv_netvsc_packet *)(unsigned long)Packet->TransactionId; + /* ASSERT(nvscPacket); */ + + /* Notify the layer above us */ + nvscPacket->Completion.Send.OnSendCompletion(nvscPacket->Completion.Send.SendCompletionContext); + + atomic_dec(&netDevice->NumOutstandingSends); + } else { + DPRINT_ERR(NETVSC, "Unknown send completion packet type - " + "%d received!!", nvspPacket->Header.MessageType); + } + + PutNetDevice(Device); + DPRINT_EXIT(NETVSC); +} + +static int NetVscOnSend(struct hv_device *Device, + struct hv_netvsc_packet *Packet) +{ + struct netvsc_device *netDevice; + int ret = 0; + + struct nvsp_message sendMessage; + + DPRINT_ENTER(NETVSC); + + netDevice = GetOutboundNetDevice(Device); + if (!netDevice) { + DPRINT_ERR(NETVSC, "net device (%p) shutting down..." + "ignoring outbound packets", netDevice); + DPRINT_EXIT(NETVSC); + return -2; + } + + sendMessage.Header.MessageType = NvspMessage1TypeSendRNDISPacket; + if (Packet->IsDataPacket) { + /* 0 is RMC_DATA; */ + sendMessage.Messages.Version1Messages.SendRNDISPacket.ChannelType = 0; + } else { + /* 1 is RMC_CONTROL; */ + sendMessage.Messages.Version1Messages.SendRNDISPacket.ChannelType = 1; + } + + /* Not using send buffer section */ + sendMessage.Messages.Version1Messages.SendRNDISPacket.SendBufferSectionIndex = 0xFFFFFFFF; + sendMessage.Messages.Version1Messages.SendRNDISPacket.SendBufferSectionSize = 0; + + if (Packet->PageBufferCount) { + ret = Device->Driver->VmbusChannelInterface.SendPacketPageBuffer( + Device, Packet->PageBuffers, + Packet->PageBufferCount, + &sendMessage, + sizeof(struct nvsp_message), + (unsigned long)Packet); + } else { + ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, + &sendMessage, + sizeof(struct nvsp_message), + (unsigned long)Packet, + VmbusPacketTypeDataInBand, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + + } + + if (ret != 0) + DPRINT_ERR(NETVSC, "Unable to send packet %p ret %d", + Packet, ret); + + atomic_inc(&netDevice->NumOutstandingSends); + PutNetDevice(Device); + + DPRINT_EXIT(NETVSC); + return ret; +} + +static void NetVscOnReceive(struct hv_device *Device, + struct vmpacket_descriptor *Packet) +{ + struct netvsc_device *netDevice; + struct vmtransfer_page_packet_header *vmxferpagePacket; + struct nvsp_message *nvspPacket; + struct hv_netvsc_packet *netvscPacket = NULL; + unsigned long start; + unsigned long end, endVirtual; + /* struct netvsc_driver *netvscDriver; */ + struct xferpage_packet *xferpagePacket = NULL; + int i, j; + int count = 0, bytesRemain = 0; + unsigned long flags; + LIST_HEAD(listHead); + + DPRINT_ENTER(NETVSC); + + netDevice = GetInboundNetDevice(Device); + if (!netDevice) { + DPRINT_ERR(NETVSC, "unable to get net device..." + "device being destroyed?"); + DPRINT_EXIT(NETVSC); + return; + } + + /* + * All inbound packets other than send completion should be xfer page + * packet + */ + if (Packet->Type != VmbusPacketTypeDataUsingTransferPages) { + DPRINT_ERR(NETVSC, "Unknown packet type received - %d", + Packet->Type); + PutNetDevice(Device); + return; + } + + nvspPacket = (struct nvsp_message *)((unsigned long)Packet + + (Packet->DataOffset8 << 3)); + + /* Make sure this is a valid nvsp packet */ + if (nvspPacket->Header.MessageType != NvspMessage1TypeSendRNDISPacket) { + DPRINT_ERR(NETVSC, "Unknown nvsp packet type received - %d", + nvspPacket->Header.MessageType); + PutNetDevice(Device); + return; + } + + DPRINT_DBG(NETVSC, "NVSP packet received - type %d", + nvspPacket->Header.MessageType); + + vmxferpagePacket = (struct vmtransfer_page_packet_header *)Packet; + + if (vmxferpagePacket->TransferPageSetId != NETVSC_RECEIVE_BUFFER_ID) { + DPRINT_ERR(NETVSC, "Invalid xfer page set id - " + "expecting %x got %x", NETVSC_RECEIVE_BUFFER_ID, + vmxferpagePacket->TransferPageSetId); + PutNetDevice(Device); + return; + } + + DPRINT_DBG(NETVSC, "xfer page - range count %d", + vmxferpagePacket->RangeCount); + + /* + * Grab free packets (range count + 1) to represent this xfer + * page packet. +1 to represent the xfer page packet itself. + * We grab it here so that we know exactly how many we can + * fulfil + */ + spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags); + while (!list_empty(&netDevice->ReceivePacketList)) { + list_move_tail(netDevice->ReceivePacketList.next, &listHead); + if (++count == vmxferpagePacket->RangeCount + 1) + break; + } + spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, flags); + + /* + * We need at least 2 netvsc pkts (1 to represent the xfer + * page and at least 1 for the range) i.e. we can handled + * some of the xfer page packet ranges... + */ + if (count < 2) { + DPRINT_ERR(NETVSC, "Got only %d netvsc pkt...needed %d pkts. " + "Dropping this xfer page packet completely!", + count, vmxferpagePacket->RangeCount + 1); + + /* Return it to the freelist */ + spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags); + for (i = count; i != 0; i--) { + list_move_tail(listHead.next, + &netDevice->ReceivePacketList); + } + spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, + flags); + + NetVscSendReceiveCompletion(Device, + vmxferpagePacket->d.TransactionId); + + PutNetDevice(Device); + return; + } + + /* Remove the 1st packet to represent the xfer page packet itself */ + xferpagePacket = (struct xferpage_packet *)listHead.next; + list_del(&xferpagePacket->ListEntry); + + /* This is how much we can satisfy */ + xferpagePacket->Count = count - 1; + /* ASSERT(xferpagePacket->Count > 0 && xferpagePacket->Count <= */ + /* vmxferpagePacket->RangeCount); */ + + if (xferpagePacket->Count != vmxferpagePacket->RangeCount) { + DPRINT_INFO(NETVSC, "Needed %d netvsc pkts to satisy this xfer " + "page...got %d", vmxferpagePacket->RangeCount, + xferpagePacket->Count); + } + + /* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */ + for (i = 0; i < (count - 1); i++) { + netvscPacket = (struct hv_netvsc_packet *)listHead.next; + list_del(&netvscPacket->ListEntry); + + /* Initialize the netvsc packet */ + netvscPacket->XferPagePacket = xferpagePacket; + netvscPacket->Completion.Recv.OnReceiveCompletion = + NetVscOnReceiveCompletion; + netvscPacket->Completion.Recv.ReceiveCompletionContext = + netvscPacket; + netvscPacket->Device = Device; + /* Save this so that we can send it back */ + netvscPacket->Completion.Recv.ReceiveCompletionTid = + vmxferpagePacket->d.TransactionId; + + netvscPacket->TotalDataBufferLength = + vmxferpagePacket->Ranges[i].ByteCount; + netvscPacket->PageBufferCount = 1; + + /* ASSERT(vmxferpagePacket->Ranges[i].ByteOffset + */ + /* vmxferpagePacket->Ranges[i].ByteCount < */ + /* netDevice->ReceiveBufferSize); */ + + netvscPacket->PageBuffers[0].Length = + vmxferpagePacket->Ranges[i].ByteCount; + + start = virt_to_phys((void *)((unsigned long)netDevice->ReceiveBuffer + vmxferpagePacket->Ranges[i].ByteOffset)); + + netvscPacket->PageBuffers[0].Pfn = start >> PAGE_SHIFT; + endVirtual = (unsigned long)netDevice->ReceiveBuffer + + vmxferpagePacket->Ranges[i].ByteOffset + + vmxferpagePacket->Ranges[i].ByteCount - 1; + end = virt_to_phys((void *)endVirtual); + + /* Calculate the page relative offset */ + netvscPacket->PageBuffers[0].Offset = + vmxferpagePacket->Ranges[i].ByteOffset & (PAGE_SIZE - 1); + if ((end >> PAGE_SHIFT) != (start >> PAGE_SHIFT)) { + /* Handle frame across multiple pages: */ + netvscPacket->PageBuffers[0].Length = + (netvscPacket->PageBuffers[0].Pfn << PAGE_SHIFT) + + PAGE_SIZE - start; + bytesRemain = netvscPacket->TotalDataBufferLength - + netvscPacket->PageBuffers[0].Length; + for (j = 1; j < NETVSC_PACKET_MAXPAGE; j++) { + netvscPacket->PageBuffers[j].Offset = 0; + if (bytesRemain <= PAGE_SIZE) { + netvscPacket->PageBuffers[j].Length = bytesRemain; + bytesRemain = 0; + } else { + netvscPacket->PageBuffers[j].Length = PAGE_SIZE; + bytesRemain -= PAGE_SIZE; + } + netvscPacket->PageBuffers[j].Pfn = + virt_to_phys((void *)(endVirtual - bytesRemain)) >> PAGE_SHIFT; + netvscPacket->PageBufferCount++; + if (bytesRemain == 0) + break; + } + /* ASSERT(bytesRemain == 0); */ + } + DPRINT_DBG(NETVSC, "[%d] - (abs offset %u len %u) => " + "(pfn %llx, offset %u, len %u)", i, + vmxferpagePacket->Ranges[i].ByteOffset, + vmxferpagePacket->Ranges[i].ByteCount, + netvscPacket->PageBuffers[0].Pfn, + netvscPacket->PageBuffers[0].Offset, + netvscPacket->PageBuffers[0].Length); + + /* Pass it to the upper layer */ + ((struct netvsc_driver *)Device->Driver)->OnReceiveCallback(Device, netvscPacket); + + NetVscOnReceiveCompletion(netvscPacket->Completion.Recv.ReceiveCompletionContext); + } + + /* ASSERT(list_empty(&listHead)); */ + + PutNetDevice(Device); + DPRINT_EXIT(NETVSC); +} + +static void NetVscSendReceiveCompletion(struct hv_device *Device, + u64 TransactionId) +{ + struct nvsp_message recvcompMessage; + int retries = 0; + int ret; + + DPRINT_DBG(NETVSC, "Sending receive completion pkt - %llx", + TransactionId); + + recvcompMessage.Header.MessageType = + NvspMessage1TypeSendRNDISPacketComplete; + + /* FIXME: Pass in the status */ + recvcompMessage.Messages.Version1Messages.SendRNDISPacketComplete.Status = NvspStatusSuccess; + +retry_send_cmplt: + /* Send the completion */ + ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, + &recvcompMessage, + sizeof(struct nvsp_message), + TransactionId, + VmbusPacketTypeCompletion, 0); + if (ret == 0) { + /* success */ + /* no-op */ + } else if (ret == -1) { + /* no more room...wait a bit and attempt to retry 3 times */ + retries++; + DPRINT_ERR(NETVSC, "unable to send receive completion pkt " + "(tid %llx)...retrying %d", TransactionId, retries); + + if (retries < 4) { + udelay(100); + goto retry_send_cmplt; + } else { + DPRINT_ERR(NETVSC, "unable to send receive completion " + "pkt (tid %llx)...give up retrying", + TransactionId); + } + } else { + DPRINT_ERR(NETVSC, "unable to send receive completion pkt - " + "%llx", TransactionId); + } +} + +/* Send a receive completion packet to RNDIS device (ie NetVsp) */ +static void NetVscOnReceiveCompletion(void *Context) +{ + struct hv_netvsc_packet *packet = Context; + struct hv_device *device = (struct hv_device *)packet->Device; + struct netvsc_device *netDevice; + u64 transactionId = 0; + bool fSendReceiveComp = false; + unsigned long flags; + + DPRINT_ENTER(NETVSC); + + /* ASSERT(packet->XferPagePacket); */ + + /* + * Even though it seems logical to do a GetOutboundNetDevice() here to + * send out receive completion, we are using GetInboundNetDevice() + * since we may have disable outbound traffic already. + */ + netDevice = GetInboundNetDevice(device); + if (!netDevice) { + DPRINT_ERR(NETVSC, "unable to get net device..." + "device being destroyed?"); + DPRINT_EXIT(NETVSC); + return; + } + + /* Overloading use of the lock. */ + spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags); + + /* ASSERT(packet->XferPagePacket->Count > 0); */ + packet->XferPagePacket->Count--; + + /* + * Last one in the line that represent 1 xfer page packet. + * Return the xfer page packet itself to the freelist + */ + if (packet->XferPagePacket->Count == 0) { + fSendReceiveComp = true; + transactionId = packet->Completion.Recv.ReceiveCompletionTid; + list_add_tail(&packet->XferPagePacket->ListEntry, + &netDevice->ReceivePacketList); + + } + + /* Put the packet back */ + list_add_tail(&packet->ListEntry, &netDevice->ReceivePacketList); + spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, flags); + + /* Send a receive completion for the xfer page packet */ + if (fSendReceiveComp) + NetVscSendReceiveCompletion(device, transactionId); + + PutNetDevice(device); + DPRINT_EXIT(NETVSC); +} + +static void NetVscOnChannelCallback(void *Context) +{ + int ret; + struct hv_device *device = Context; + struct netvsc_device *netDevice; + u32 bytesRecvd; + u64 requestId; + unsigned char *packet; + struct vmpacket_descriptor *desc; + unsigned char *buffer; + int bufferlen = NETVSC_PACKET_SIZE; + + + DPRINT_ENTER(NETVSC); + + /* ASSERT(device); */ + + packet = kzalloc(NETVSC_PACKET_SIZE * sizeof(unsigned char), + GFP_KERNEL); + if (!packet) + return; + buffer = packet; + + netDevice = GetInboundNetDevice(device); + if (!netDevice) { + DPRINT_ERR(NETVSC, "net device (%p) shutting down..." + "ignoring inbound packets", netDevice); + DPRINT_EXIT(NETVSC); + goto out; + } + + do { + ret = device->Driver->VmbusChannelInterface.RecvPacketRaw( + device, buffer, bufferlen, + &bytesRecvd, &requestId); + if (ret == 0) { + if (bytesRecvd > 0) { + DPRINT_DBG(NETVSC, "receive %d bytes, tid %llx", + bytesRecvd, requestId); + + desc = (struct vmpacket_descriptor *)buffer; + switch (desc->Type) { + case VmbusPacketTypeCompletion: + NetVscOnSendCompletion(device, desc); + break; + + case VmbusPacketTypeDataUsingTransferPages: + NetVscOnReceive(device, desc); + break; + + default: + DPRINT_ERR(NETVSC, + "unhandled packet type %d, " + "tid %llx len %d\n", + desc->Type, requestId, + bytesRecvd); + break; + } + + /* reset */ + if (bufferlen > NETVSC_PACKET_SIZE) { + kfree(buffer); + buffer = packet; + bufferlen = NETVSC_PACKET_SIZE; + } + } else { + /* reset */ + if (bufferlen > NETVSC_PACKET_SIZE) { + kfree(buffer); + buffer = packet; + bufferlen = NETVSC_PACKET_SIZE; + } + + break; + } + } else if (ret == -2) { + /* Handle large packet */ + buffer = kmalloc(bytesRecvd, GFP_ATOMIC); + if (buffer == NULL) { + /* Try again next time around */ + DPRINT_ERR(NETVSC, + "unable to allocate buffer of size " + "(%d)!!", bytesRecvd); + break; + } + + bufferlen = bytesRecvd; + } + } while (1); + + PutNetDevice(device); + DPRINT_EXIT(NETVSC); +out: + kfree(buffer); + return; +} diff --git a/drivers/staging/hv/netvsc.h b/drivers/staging/hv/netvsc.h new file mode 100644 index 000000000000..a6264db8388a --- /dev/null +++ b/drivers/staging/hv/netvsc.h @@ -0,0 +1,331 @@ +/* + * + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + * + */ + + +#ifndef _NETVSC_H_ +#define _NETVSC_H_ + +#include +#include "VmbusPacketFormat.h" +#include "VmbusChannelInterface.h" +#include "NetVscApi.h" + + +#define NVSP_INVALID_PROTOCOL_VERSION ((u32)0xFFFFFFFF) + +#define NVSP_PROTOCOL_VERSION_1 2 +#define NVSP_MIN_PROTOCOL_VERSION NVSP_PROTOCOL_VERSION_1 +#define NVSP_MAX_PROTOCOL_VERSION NVSP_PROTOCOL_VERSION_1 + +enum { + NvspMessageTypeNone = 0, + + /* Init Messages */ + NvspMessageTypeInit = 1, + NvspMessageTypeInitComplete = 2, + + NvspVersionMessageStart = 100, + + /* Version 1 Messages */ + NvspMessage1TypeSendNdisVersion = NvspVersionMessageStart, + + NvspMessage1TypeSendReceiveBuffer, + NvspMessage1TypeSendReceiveBufferComplete, + NvspMessage1TypeRevokeReceiveBuffer, + + NvspMessage1TypeSendSendBuffer, + NvspMessage1TypeSendSendBufferComplete, + NvspMessage1TypeRevokeSendBuffer, + + NvspMessage1TypeSendRNDISPacket, + NvspMessage1TypeSendRNDISPacketComplete, + + /* + * This should be set to the number of messages for the version with + * the maximum number of messages. + */ + NvspNumMessagePerVersion = 9, +}; + +enum { + NvspStatusNone = 0, + NvspStatusSuccess, + NvspStatusFailure, + NvspStatusProtocolVersionRangeTooNew, + NvspStatusProtocolVersionRangeTooOld, + NvspStatusInvalidRndisPacket, + NvspStatusBusy, + NvspStatusMax, +}; + +struct nvsp_message_header { + u32 MessageType; +}; + +/* Init Messages */ + +/* + * This message is used by the VSC to initialize the channel after the channels + * has been opened. This message should never include anything other then + * versioning (i.e. this message will be the same for ever). + */ +struct nvsp_message_init { + u32 MinProtocolVersion; + u32 MaxProtocolVersion; +} __attribute__((packed)); + +/* + * This message is used by the VSP to complete the initialization of the + * channel. This message should never include anything other then versioning + * (i.e. this message will be the same for ever). + */ +struct nvsp_message_init_complete { + u32 NegotiatedProtocolVersion; + u32 MaximumMdlChainLength; + u32 Status; +} __attribute__((packed)); + +union nvsp_message_init_uber { + struct nvsp_message_init Init; + struct nvsp_message_init_complete InitComplete; +} __attribute__((packed)); + +/* Version 1 Messages */ + +/* + * This message is used by the VSC to send the NDIS version to the VSP. The VSP + * can use this information when handling OIDs sent by the VSC. + */ +struct nvsp_1_message_send_ndis_version { + u32 NdisMajorVersion; + u32 NdisMinorVersion; +} __attribute__((packed)); + +/* + * This message is used by the VSC to send a receive buffer to the VSP. The VSP + * can then use the receive buffer to send data to the VSC. + */ +struct nvsp_1_message_send_receive_buffer { + u32 GpadlHandle; + u16 Id; +} __attribute__((packed)); + +struct nvsp_1_receive_buffer_section { + u32 Offset; + u32 SubAllocationSize; + u32 NumSubAllocations; + u32 EndOffset; +} __attribute__((packed)); + +/* + * This message is used by the VSP to acknowledge a receive buffer send by the + * VSC. This message must be sent by the VSP before the VSP uses the receive + * buffer. + */ +struct nvsp_1_message_send_receive_buffer_complete { + u32 Status; + u32 NumSections; + + /* + * The receive buffer is split into two parts, a large suballocation + * section and a small suballocation section. These sections are then + * suballocated by a certain size. + */ + + /* + * For example, the following break up of the receive buffer has 6 + * large suballocations and 10 small suballocations. + */ + + /* + * | Large Section | | Small Section | + * ------------------------------------------------------------ + * | | | | | | | | | | | | | | | | | | + * | | + * LargeOffset SmallOffset + */ + + struct nvsp_1_receive_buffer_section Sections[1]; +} __attribute__((packed)); + +/* + * This message is sent by the VSC to revoke the receive buffer. After the VSP + * completes this transaction, the vsp should never use the receive buffer + * again. + */ +struct nvsp_1_message_revoke_receive_buffer { + u16 Id; +}; + +/* + * This message is used by the VSC to send a send buffer to the VSP. The VSC + * can then use the send buffer to send data to the VSP. + */ +struct nvsp_1_message_send_send_buffer { + u32 GpadlHandle; + u16 Id; +} __attribute__((packed)); + +/* + * This message is used by the VSP to acknowledge a send buffer sent by the + * VSC. This message must be sent by the VSP before the VSP uses the sent + * buffer. + */ +struct nvsp_1_message_send_send_buffer_complete { + u32 Status; + + /* + * The VSC gets to choose the size of the send buffer and the VSP gets + * to choose the sections size of the buffer. This was done to enable + * dynamic reconfigurations when the cost of GPA-direct buffers + * decreases. + */ + u32 SectionSize; +} __attribute__((packed)); + +/* + * This message is sent by the VSC to revoke the send buffer. After the VSP + * completes this transaction, the vsp should never use the send buffer again. + */ +struct nvsp_1_message_revoke_send_buffer { + u16 Id; +}; + +/* + * This message is used by both the VSP and the VSC to send a RNDIS message to + * the opposite channel endpoint. + */ +struct nvsp_1_message_send_rndis_packet { + /* + * This field is specified by RNIDS. They assume there's two different + * channels of communication. However, the Network VSP only has one. + * Therefore, the channel travels with the RNDIS packet. + */ + u32 ChannelType; + + /* + * This field is used to send part or all of the data through a send + * buffer. This values specifies an index into the send buffer. If the + * index is 0xFFFFFFFF, then the send buffer is not being used and all + * of the data was sent through other VMBus mechanisms. + */ + u32 SendBufferSectionIndex; + u32 SendBufferSectionSize; +} __attribute__((packed)); + +/* + * This message is used by both the VSP and the VSC to complete a RNDIS message + * to the opposite channel endpoint. At this point, the initiator of this + * message cannot use any resources associated with the original RNDIS packet. + */ +struct nvsp_1_message_send_rndis_packet_complete { + u32 Status; +}; + +union nvsp_1_message_uber { + struct nvsp_1_message_send_ndis_version SendNdisVersion; + + struct nvsp_1_message_send_receive_buffer SendReceiveBuffer; + struct nvsp_1_message_send_receive_buffer_complete + SendReceiveBufferComplete; + struct nvsp_1_message_revoke_receive_buffer RevokeReceiveBuffer; + + struct nvsp_1_message_send_send_buffer SendSendBuffer; + struct nvsp_1_message_send_send_buffer_complete SendSendBufferComplete; + struct nvsp_1_message_revoke_send_buffer RevokeSendBuffer; + + struct nvsp_1_message_send_rndis_packet SendRNDISPacket; + struct nvsp_1_message_send_rndis_packet_complete + SendRNDISPacketComplete; +} __attribute__((packed)); + +union nvsp_all_messages { + union nvsp_message_init_uber InitMessages; + union nvsp_1_message_uber Version1Messages; +} __attribute__((packed)); + +/* ALL Messages */ +struct nvsp_message { + struct nvsp_message_header Header; + union nvsp_all_messages Messages; +} __attribute__((packed)); + + + + +/* #define NVSC_MIN_PROTOCOL_VERSION 1 */ +/* #define NVSC_MAX_PROTOCOL_VERSION 1 */ + +#define NETVSC_SEND_BUFFER_SIZE (64*1024) /* 64K */ +#define NETVSC_SEND_BUFFER_ID 0xface + + +#define NETVSC_RECEIVE_BUFFER_SIZE (1024*1024) /* 1MB */ + +#define NETVSC_RECEIVE_BUFFER_ID 0xcafe + +#define NETVSC_RECEIVE_SG_COUNT 1 + +/* Preallocated receive packets */ +#define NETVSC_RECEIVE_PACKETLIST_COUNT 256 + +#define NETVSC_PACKET_SIZE 2048 + +/* Per netvsc channel-specific */ +struct netvsc_device { + struct hv_device *Device; + + atomic_t RefCount; + atomic_t NumOutstandingSends; + /* + * List of free preallocated hv_netvsc_packet to represent receive + * packet + */ + struct list_head ReceivePacketList; + spinlock_t receive_packet_list_lock; + + /* Send buffer allocated by us but manages by NetVSP */ + void *SendBuffer; + u32 SendBufferSize; + u32 SendBufferGpadlHandle; + u32 SendSectionSize; + + /* Receive buffer allocated by us but manages by NetVSP */ + void *ReceiveBuffer; + u32 ReceiveBufferSize; + u32 ReceiveBufferGpadlHandle; + u32 ReceiveSectionCount; + struct nvsp_1_receive_buffer_section *ReceiveSections; + + /* Used for NetVSP initialization protocol */ + struct osd_waitevent *ChannelInitEvent; + struct nvsp_message ChannelInitPacket; + + struct nvsp_message RevokePacket; + /* unsigned char HwMacAddr[HW_MACADDR_LEN]; */ + + /* Holds rndis device info */ + void *Extension; +}; + +#endif /* _NETVSC_H_ */ -- cgit v1.2.3 From a73fd9802e976fbcb6b6f4bbe082f94ebe433ddf Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:29:27 -0700 Subject: Staging: hv: rename StorVsc.c to storvsc.c Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Makefile | 2 +- drivers/staging/hv/StorVsc.c | 858 ------------------------------------------- drivers/staging/hv/blkvsc.c | 2 +- drivers/staging/hv/storvsc.c | 858 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 860 insertions(+), 860 deletions(-) delete mode 100644 drivers/staging/hv/StorVsc.c create mode 100644 drivers/staging/hv/storvsc.c (limited to 'drivers') diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index 385eb90bd310..cc75185e3b54 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -7,6 +7,6 @@ obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o hv_vmbus-objs := vmbus_drv.o osd.o \ vmbus.o hv.o connection.o channel.o \ ChannelMgmt.o ChannelInterface.o ring_buffer.o -hv_storvsc-objs := storvsc_drv.o StorVsc.o +hv_storvsc-objs := storvsc_drv.o storvsc.o hv_blkvsc-objs := blkvsc_drv.o blkvsc.o hv_netvsc-objs := netvsc_drv.o netvsc.o RndisFilter.o diff --git a/drivers/staging/hv/StorVsc.c b/drivers/staging/hv/StorVsc.c deleted file mode 100644 index e73130e49cce..000000000000 --- a/drivers/staging/hv/StorVsc.c +++ /dev/null @@ -1,858 +0,0 @@ -/* - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - */ -#include -#include -#include -#include -#include -#include "osd.h" -#include "logging.h" -#include "StorVscApi.h" -#include "VmbusPacketFormat.h" -#include "vstorage.h" - - -struct storvsc_request_extension { - /* LIST_ENTRY ListEntry; */ - - struct hv_storvsc_request *Request; - struct hv_device *Device; - - /* Synchronize the request/response if needed */ - struct osd_waitevent *WaitEvent; - - struct vstor_packet VStorPacket; -}; - -/* A storvsc device is a device object that contains a vmbus channel */ -struct storvsc_device { - struct hv_device *Device; - - /* 0 indicates the device is being destroyed */ - atomic_t RefCount; - - atomic_t NumOutstandingRequests; - - /* - * Each unique Port/Path/Target represents 1 channel ie scsi - * controller. In reality, the pathid, targetid is always 0 - * and the port is set by us - */ - unsigned int PortNumber; - unsigned char PathId; - unsigned char TargetId; - - /* LIST_ENTRY OutstandingRequestList; */ - /* HANDLE OutstandingRequestLock; */ - - /* Used for vsc/vsp channel reset process */ - struct storvsc_request_extension InitRequest; - struct storvsc_request_extension ResetRequest; -}; - - -static const char *gDriverName = "storvsc"; - -/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ -static const struct hv_guid gStorVscDeviceType = { - .data = { - 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, - 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f - } -}; - - -static inline struct storvsc_device *AllocStorDevice(struct hv_device *Device) -{ - struct storvsc_device *storDevice; - - storDevice = kzalloc(sizeof(struct storvsc_device), GFP_KERNEL); - if (!storDevice) - return NULL; - - /* Set to 2 to allow both inbound and outbound traffics */ - /* (ie GetStorDevice() and MustGetStorDevice()) to proceed. */ - atomic_cmpxchg(&storDevice->RefCount, 0, 2); - - storDevice->Device = Device; - Device->Extension = storDevice; - - return storDevice; -} - -static inline void FreeStorDevice(struct storvsc_device *Device) -{ - /* ASSERT(atomic_read(&Device->RefCount) == 0); */ - kfree(Device); -} - -/* Get the stordevice object iff exists and its refcount > 1 */ -static inline struct storvsc_device *GetStorDevice(struct hv_device *Device) -{ - struct storvsc_device *storDevice; - - storDevice = (struct storvsc_device *)Device->Extension; - if (storDevice && atomic_read(&storDevice->RefCount) > 1) - atomic_inc(&storDevice->RefCount); - else - storDevice = NULL; - - return storDevice; -} - -/* Get the stordevice object iff exists and its refcount > 0 */ -static inline struct storvsc_device *MustGetStorDevice(struct hv_device *Device) -{ - struct storvsc_device *storDevice; - - storDevice = (struct storvsc_device *)Device->Extension; - if (storDevice && atomic_read(&storDevice->RefCount)) - atomic_inc(&storDevice->RefCount); - else - storDevice = NULL; - - return storDevice; -} - -static inline void PutStorDevice(struct hv_device *Device) -{ - struct storvsc_device *storDevice; - - storDevice = (struct storvsc_device *)Device->Extension; - /* ASSERT(storDevice); */ - - atomic_dec(&storDevice->RefCount); - /* ASSERT(atomic_read(&storDevice->RefCount)); */ -} - -/* Drop ref count to 1 to effectively disable GetStorDevice() */ -static inline struct storvsc_device *ReleaseStorDevice(struct hv_device *Device) -{ - struct storvsc_device *storDevice; - - storDevice = (struct storvsc_device *)Device->Extension; - /* ASSERT(storDevice); */ - - /* Busy wait until the ref drop to 2, then set it to 1 */ - while (atomic_cmpxchg(&storDevice->RefCount, 2, 1) != 2) - udelay(100); - - return storDevice; -} - -/* Drop ref count to 0. No one can use StorDevice object. */ -static inline struct storvsc_device *FinalReleaseStorDevice( - struct hv_device *Device) -{ - struct storvsc_device *storDevice; - - storDevice = (struct storvsc_device *)Device->Extension; - /* ASSERT(storDevice); */ - - /* Busy wait until the ref drop to 1, then set it to 0 */ - while (atomic_cmpxchg(&storDevice->RefCount, 1, 0) != 1) - udelay(100); - - Device->Extension = NULL; - return storDevice; -} - -static int StorVscChannelInit(struct hv_device *Device) -{ - struct storvsc_device *storDevice; - struct storvsc_request_extension *request; - struct vstor_packet *vstorPacket; - int ret; - - storDevice = GetStorDevice(Device); - if (!storDevice) { - DPRINT_ERR(STORVSC, "unable to get stor device..." - "device being destroyed?"); - DPRINT_EXIT(STORVSC); - return -1; - } - - request = &storDevice->InitRequest; - vstorPacket = &request->VStorPacket; - - /* - * Now, initiate the vsc/vsp initialization protocol on the open - * channel - */ - memset(request, 0, sizeof(struct storvsc_request_extension)); - request->WaitEvent = osd_WaitEventCreate(); - if (!request->WaitEvent) { - ret = -ENOMEM; - goto nomem; - } - - vstorPacket->Operation = VStorOperationBeginInitialization; - vstorPacket->Flags = REQUEST_COMPLETION_FLAG; - - /*SpinlockAcquire(gDriverExt.packetListLock); - INSERT_TAIL_LIST(&gDriverExt.packetList, &packet->listEntry.entry); - SpinlockRelease(gDriverExt.packetListLock);*/ - - DPRINT_INFO(STORVSC, "BEGIN_INITIALIZATION_OPERATION..."); - - ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, - vstorPacket, - sizeof(struct vstor_packet), - (unsigned long)request, - VmbusPacketTypeDataInBand, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - if (ret != 0) { - DPRINT_ERR(STORVSC, - "unable to send BEGIN_INITIALIZATION_OPERATION"); - goto Cleanup; - } - - osd_WaitEventWait(request->WaitEvent); - - if (vstorPacket->Operation != VStorOperationCompleteIo || - vstorPacket->Status != 0) { - DPRINT_ERR(STORVSC, "BEGIN_INITIALIZATION_OPERATION failed " - "(op %d status 0x%x)", - vstorPacket->Operation, vstorPacket->Status); - goto Cleanup; - } - - DPRINT_INFO(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION..."); - - /* reuse the packet for version range supported */ - memset(vstorPacket, 0, sizeof(struct vstor_packet)); - vstorPacket->Operation = VStorOperationQueryProtocolVersion; - vstorPacket->Flags = REQUEST_COMPLETION_FLAG; - - vstorPacket->Version.MajorMinor = VMSTOR_PROTOCOL_VERSION_CURRENT; - FILL_VMSTOR_REVISION(vstorPacket->Version.Revision); - - ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, - vstorPacket, - sizeof(struct vstor_packet), - (unsigned long)request, - VmbusPacketTypeDataInBand, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - if (ret != 0) { - DPRINT_ERR(STORVSC, - "unable to send BEGIN_INITIALIZATION_OPERATION"); - goto Cleanup; - } - - osd_WaitEventWait(request->WaitEvent); - - /* TODO: Check returned version */ - if (vstorPacket->Operation != VStorOperationCompleteIo || - vstorPacket->Status != 0) { - DPRINT_ERR(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION failed " - "(op %d status 0x%x)", - vstorPacket->Operation, vstorPacket->Status); - goto Cleanup; - } - - /* Query channel properties */ - DPRINT_INFO(STORVSC, "QUERY_PROPERTIES_OPERATION..."); - - memset(vstorPacket, 0, sizeof(struct vstor_packet)); - vstorPacket->Operation = VStorOperationQueryProperties; - vstorPacket->Flags = REQUEST_COMPLETION_FLAG; - vstorPacket->StorageChannelProperties.PortNumber = - storDevice->PortNumber; - - ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, - vstorPacket, - sizeof(struct vstor_packet), - (unsigned long)request, - VmbusPacketTypeDataInBand, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - - if (ret != 0) { - DPRINT_ERR(STORVSC, - "unable to send QUERY_PROPERTIES_OPERATION"); - goto Cleanup; - } - - osd_WaitEventWait(request->WaitEvent); - - /* TODO: Check returned version */ - if (vstorPacket->Operation != VStorOperationCompleteIo || - vstorPacket->Status != 0) { - DPRINT_ERR(STORVSC, "QUERY_PROPERTIES_OPERATION failed " - "(op %d status 0x%x)", - vstorPacket->Operation, vstorPacket->Status); - goto Cleanup; - } - - storDevice->PathId = vstorPacket->StorageChannelProperties.PathId; - storDevice->TargetId = vstorPacket->StorageChannelProperties.TargetId; - - DPRINT_DBG(STORVSC, "channel flag 0x%x, max xfer len 0x%x", - vstorPacket->StorageChannelProperties.Flags, - vstorPacket->StorageChannelProperties.MaxTransferBytes); - - DPRINT_INFO(STORVSC, "END_INITIALIZATION_OPERATION..."); - - memset(vstorPacket, 0, sizeof(struct vstor_packet)); - vstorPacket->Operation = VStorOperationEndInitialization; - vstorPacket->Flags = REQUEST_COMPLETION_FLAG; - - ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, - vstorPacket, - sizeof(struct vstor_packet), - (unsigned long)request, - VmbusPacketTypeDataInBand, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - - if (ret != 0) { - DPRINT_ERR(STORVSC, - "unable to send END_INITIALIZATION_OPERATION"); - goto Cleanup; - } - - osd_WaitEventWait(request->WaitEvent); - - if (vstorPacket->Operation != VStorOperationCompleteIo || - vstorPacket->Status != 0) { - DPRINT_ERR(STORVSC, "END_INITIALIZATION_OPERATION failed " - "(op %d status 0x%x)", - vstorPacket->Operation, vstorPacket->Status); - goto Cleanup; - } - - DPRINT_INFO(STORVSC, "**** storage channel up and running!! ****"); - -Cleanup: - kfree(request->WaitEvent); - request->WaitEvent = NULL; -nomem: - PutStorDevice(Device); - - DPRINT_EXIT(STORVSC); - return ret; -} - -static void StorVscOnIOCompletion(struct hv_device *Device, - struct vstor_packet *VStorPacket, - struct storvsc_request_extension *RequestExt) -{ - struct hv_storvsc_request *request; - struct storvsc_device *storDevice; - - DPRINT_ENTER(STORVSC); - - storDevice = MustGetStorDevice(Device); - if (!storDevice) { - DPRINT_ERR(STORVSC, "unable to get stor device..." - "device being destroyed?"); - DPRINT_EXIT(STORVSC); - return; - } - - DPRINT_DBG(STORVSC, "IO_COMPLETE_OPERATION - request extension %p " - "completed bytes xfer %u", RequestExt, - VStorPacket->VmSrb.DataTransferLength); - - /* ASSERT(RequestExt != NULL); */ - /* ASSERT(RequestExt->Request != NULL); */ - - request = RequestExt->Request; - - /* ASSERT(request->OnIOCompletion != NULL); */ - - /* Copy over the status...etc */ - request->Status = VStorPacket->VmSrb.ScsiStatus; - - if (request->Status != 0 || VStorPacket->VmSrb.SrbStatus != 1) { - DPRINT_WARN(STORVSC, - "cmd 0x%x scsi status 0x%x srb status 0x%x\n", - request->Cdb[0], VStorPacket->VmSrb.ScsiStatus, - VStorPacket->VmSrb.SrbStatus); - } - - if ((request->Status & 0xFF) == 0x02) { - /* CHECK_CONDITION */ - if (VStorPacket->VmSrb.SrbStatus & 0x80) { - /* autosense data available */ - DPRINT_WARN(STORVSC, "storvsc pkt %p autosense data " - "valid - len %d\n", RequestExt, - VStorPacket->VmSrb.SenseInfoLength); - - /* ASSERT(VStorPacket->VmSrb.SenseInfoLength <= */ - /* request->SenseBufferSize); */ - memcpy(request->SenseBuffer, - VStorPacket->VmSrb.SenseData, - VStorPacket->VmSrb.SenseInfoLength); - - request->SenseBufferSize = - VStorPacket->VmSrb.SenseInfoLength; - } - } - - /* TODO: */ - request->BytesXfer = VStorPacket->VmSrb.DataTransferLength; - - request->OnIOCompletion(request); - - atomic_dec(&storDevice->NumOutstandingRequests); - - PutStorDevice(Device); - - DPRINT_EXIT(STORVSC); -} - -static void StorVscOnReceive(struct hv_device *Device, - struct vstor_packet *VStorPacket, - struct storvsc_request_extension *RequestExt) -{ - switch (VStorPacket->Operation) { - case VStorOperationCompleteIo: - DPRINT_DBG(STORVSC, "IO_COMPLETE_OPERATION"); - StorVscOnIOCompletion(Device, VStorPacket, RequestExt); - break; - case VStorOperationRemoveDevice: - DPRINT_INFO(STORVSC, "REMOVE_DEVICE_OPERATION"); - /* TODO: */ - break; - - default: - DPRINT_INFO(STORVSC, "Unknown operation received - %d", - VStorPacket->Operation); - break; - } -} - -static void StorVscOnChannelCallback(void *context) -{ - struct hv_device *device = (struct hv_device *)context; - struct storvsc_device *storDevice; - u32 bytesRecvd; - u64 requestId; - unsigned char packet[ALIGN_UP(sizeof(struct vstor_packet), 8)]; - struct storvsc_request_extension *request; - int ret; - - DPRINT_ENTER(STORVSC); - - /* ASSERT(device); */ - - storDevice = MustGetStorDevice(device); - if (!storDevice) { - DPRINT_ERR(STORVSC, "unable to get stor device..." - "device being destroyed?"); - DPRINT_EXIT(STORVSC); - return; - } - - do { - ret = device->Driver->VmbusChannelInterface.RecvPacket(device, - packet, - ALIGN_UP(sizeof(struct vstor_packet), 8), - &bytesRecvd, &requestId); - if (ret == 0 && bytesRecvd > 0) { - DPRINT_DBG(STORVSC, "receive %d bytes - tid %llx", - bytesRecvd, requestId); - - /* ASSERT(bytesRecvd == sizeof(struct vstor_packet)); */ - - request = (struct storvsc_request_extension *) - (unsigned long)requestId; - /* ASSERT(request);c */ - - /* if (vstorPacket.Flags & SYNTHETIC_FLAG) */ - if ((request == &storDevice->InitRequest) || - (request == &storDevice->ResetRequest)) { - /* DPRINT_INFO(STORVSC, - * "reset completion - operation " - * "%u status %u", - * vstorPacket.Operation, - * vstorPacket.Status); */ - - memcpy(&request->VStorPacket, packet, - sizeof(struct vstor_packet)); - - osd_WaitEventSet(request->WaitEvent); - } else { - StorVscOnReceive(device, - (struct vstor_packet *)packet, - request); - } - } else { - /* DPRINT_DBG(STORVSC, "nothing else to read..."); */ - break; - } - } while (1); - - PutStorDevice(device); - - DPRINT_EXIT(STORVSC); - return; -} - -static int StorVscConnectToVsp(struct hv_device *Device) -{ - struct vmstorage_channel_properties props; - struct storvsc_driver_object *storDriver; - int ret; - - storDriver = (struct storvsc_driver_object *)Device->Driver; - memset(&props, 0, sizeof(struct vmstorage_channel_properties)); - - /* Open the channel */ - ret = Device->Driver->VmbusChannelInterface.Open(Device, - storDriver->RingBufferSize, - storDriver->RingBufferSize, - (void *)&props, - sizeof(struct vmstorage_channel_properties), - StorVscOnChannelCallback, - Device); - - DPRINT_DBG(STORVSC, "storage props: path id %d, tgt id %d, max xfer %d", - props.PathId, props.TargetId, props.MaxTransferBytes); - - if (ret != 0) { - DPRINT_ERR(STORVSC, "unable to open channel: %d", ret); - return -1; - } - - ret = StorVscChannelInit(Device); - - return ret; -} - -/* - * StorVscOnDeviceAdd - Callback when the device belonging to this driver is added - */ -static int StorVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) -{ - struct storvsc_device *storDevice; - /* struct vmstorage_channel_properties *props; */ - struct storvsc_device_info *deviceInfo; - int ret = 0; - - DPRINT_ENTER(STORVSC); - - deviceInfo = (struct storvsc_device_info *)AdditionalInfo; - storDevice = AllocStorDevice(Device); - if (!storDevice) { - ret = -1; - goto Cleanup; - } - - /* Save the channel properties to our storvsc channel */ - /* props = (struct vmstorage_channel_properties *) - * channel->offerMsg.Offer.u.Standard.UserDefined; */ - - /* FIXME: */ - /* - * If we support more than 1 scsi channel, we need to set the - * port number here to the scsi channel but how do we get the - * scsi channel prior to the bus scan - */ - - /* storChannel->PortNumber = 0; - storChannel->PathId = props->PathId; - storChannel->TargetId = props->TargetId; */ - - storDevice->PortNumber = deviceInfo->PortNumber; - /* Send it back up */ - ret = StorVscConnectToVsp(Device); - - /* deviceInfo->PortNumber = storDevice->PortNumber; */ - deviceInfo->PathId = storDevice->PathId; - deviceInfo->TargetId = storDevice->TargetId; - - DPRINT_DBG(STORVSC, "assigned port %u, path %u target %u\n", - storDevice->PortNumber, storDevice->PathId, - storDevice->TargetId); - -Cleanup: - DPRINT_EXIT(STORVSC); - - return ret; -} - -/* - * StorVscOnDeviceRemove - Callback when the our device is being removed - */ -static int StorVscOnDeviceRemove(struct hv_device *Device) -{ - struct storvsc_device *storDevice; - - DPRINT_ENTER(STORVSC); - - DPRINT_INFO(STORVSC, "disabling storage device (%p)...", - Device->Extension); - - storDevice = ReleaseStorDevice(Device); - - /* - * At this point, all outbound traffic should be disable. We - * only allow inbound traffic (responses) to proceed so that - * outstanding requests can be completed. - */ - while (atomic_read(&storDevice->NumOutstandingRequests)) { - DPRINT_INFO(STORVSC, "waiting for %d requests to complete...", - atomic_read(&storDevice->NumOutstandingRequests)); - udelay(100); - } - - DPRINT_INFO(STORVSC, "removing storage device (%p)...", - Device->Extension); - - storDevice = FinalReleaseStorDevice(Device); - - DPRINT_INFO(STORVSC, "storage device (%p) safe to remove", storDevice); - - /* Close the channel */ - Device->Driver->VmbusChannelInterface.Close(Device); - - FreeStorDevice(storDevice); - - DPRINT_EXIT(STORVSC); - return 0; -} - -int StorVscOnHostReset(struct hv_device *Device) -{ - struct storvsc_device *storDevice; - struct storvsc_request_extension *request; - struct vstor_packet *vstorPacket; - int ret; - - DPRINT_ENTER(STORVSC); - - DPRINT_INFO(STORVSC, "resetting host adapter..."); - - storDevice = GetStorDevice(Device); - if (!storDevice) { - DPRINT_ERR(STORVSC, "unable to get stor device..." - "device being destroyed?"); - DPRINT_EXIT(STORVSC); - return -1; - } - - request = &storDevice->ResetRequest; - vstorPacket = &request->VStorPacket; - - request->WaitEvent = osd_WaitEventCreate(); - if (!request->WaitEvent) { - ret = -ENOMEM; - goto Cleanup; - } - - vstorPacket->Operation = VStorOperationResetBus; - vstorPacket->Flags = REQUEST_COMPLETION_FLAG; - vstorPacket->VmSrb.PathId = storDevice->PathId; - - ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, - vstorPacket, - sizeof(struct vstor_packet), - (unsigned long)&storDevice->ResetRequest, - VmbusPacketTypeDataInBand, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - if (ret != 0) { - DPRINT_ERR(STORVSC, "Unable to send reset packet %p ret %d", - vstorPacket, ret); - goto Cleanup; - } - - /* FIXME: Add a timeout */ - osd_WaitEventWait(request->WaitEvent); - - kfree(request->WaitEvent); - DPRINT_INFO(STORVSC, "host adapter reset completed"); - - /* - * At this point, all outstanding requests in the adapter - * should have been flushed out and return to us - */ - -Cleanup: - PutStorDevice(Device); - DPRINT_EXIT(STORVSC); - return ret; -} - -/* - * StorVscOnIORequest - Callback to initiate an I/O request - */ -static int StorVscOnIORequest(struct hv_device *Device, - struct hv_storvsc_request *Request) -{ - struct storvsc_device *storDevice; - struct storvsc_request_extension *requestExtension; - struct vstor_packet *vstorPacket; - int ret = 0; - - DPRINT_ENTER(STORVSC); - - requestExtension = - (struct storvsc_request_extension *)Request->Extension; - vstorPacket = &requestExtension->VStorPacket; - storDevice = GetStorDevice(Device); - - DPRINT_DBG(STORVSC, "enter - Device %p, DeviceExt %p, Request %p, " - "Extension %p", Device, storDevice, Request, - requestExtension); - - DPRINT_DBG(STORVSC, "req %p len %d bus %d, target %d, lun %d cdblen %d", - Request, Request->DataBuffer.Length, Request->Bus, - Request->TargetId, Request->LunId, Request->CdbLen); - - if (!storDevice) { - DPRINT_ERR(STORVSC, "unable to get stor device..." - "device being destroyed?"); - DPRINT_EXIT(STORVSC); - return -2; - } - - /* print_hex_dump_bytes("", DUMP_PREFIX_NONE, Request->Cdb, - * Request->CdbLen); */ - - requestExtension->Request = Request; - requestExtension->Device = Device; - - memset(vstorPacket, 0 , sizeof(struct vstor_packet)); - - vstorPacket->Flags |= REQUEST_COMPLETION_FLAG; - - vstorPacket->VmSrb.Length = sizeof(struct vmscsi_request); - - vstorPacket->VmSrb.PortNumber = Request->Host; - vstorPacket->VmSrb.PathId = Request->Bus; - vstorPacket->VmSrb.TargetId = Request->TargetId; - vstorPacket->VmSrb.Lun = Request->LunId; - - vstorPacket->VmSrb.SenseInfoLength = SENSE_BUFFER_SIZE; - - /* Copy over the scsi command descriptor block */ - vstorPacket->VmSrb.CdbLength = Request->CdbLen; - memcpy(&vstorPacket->VmSrb.Cdb, Request->Cdb, Request->CdbLen); - - vstorPacket->VmSrb.DataIn = Request->Type; - vstorPacket->VmSrb.DataTransferLength = Request->DataBuffer.Length; - - vstorPacket->Operation = VStorOperationExecuteSRB; - - DPRINT_DBG(STORVSC, "srb - len %d port %d, path %d, target %d, " - "lun %d senselen %d cdblen %d", - vstorPacket->VmSrb.Length, - vstorPacket->VmSrb.PortNumber, - vstorPacket->VmSrb.PathId, - vstorPacket->VmSrb.TargetId, - vstorPacket->VmSrb.Lun, - vstorPacket->VmSrb.SenseInfoLength, - vstorPacket->VmSrb.CdbLength); - - if (requestExtension->Request->DataBuffer.Length) { - ret = Device->Driver->VmbusChannelInterface. - SendPacketMultiPageBuffer(Device, - &requestExtension->Request->DataBuffer, - vstorPacket, - sizeof(struct vstor_packet), - (unsigned long)requestExtension); - } else { - ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, - vstorPacket, - sizeof(struct vstor_packet), - (unsigned long)requestExtension, - VmbusPacketTypeDataInBand, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - } - - if (ret != 0) { - DPRINT_DBG(STORVSC, "Unable to send packet %p ret %d", - vstorPacket, ret); - } - - atomic_inc(&storDevice->NumOutstandingRequests); - - PutStorDevice(Device); - - DPRINT_EXIT(STORVSC); - return ret; -} - -/* - * StorVscOnCleanup - Perform any cleanup when the driver is removed - */ -static void StorVscOnCleanup(struct hv_driver *Driver) -{ - DPRINT_ENTER(STORVSC); - DPRINT_EXIT(STORVSC); -} - -/* - * StorVscInitialize - Main entry point - */ -int StorVscInitialize(struct hv_driver *Driver) -{ - struct storvsc_driver_object *storDriver; - - DPRINT_ENTER(STORVSC); - - storDriver = (struct storvsc_driver_object *)Driver; - - DPRINT_DBG(STORVSC, "sizeof(STORVSC_REQUEST)=%zd " - "sizeof(struct storvsc_request_extension)=%zd " - "sizeof(struct vstor_packet)=%zd, " - "sizeof(struct vmscsi_request)=%zd", - sizeof(struct hv_storvsc_request), - sizeof(struct storvsc_request_extension), - sizeof(struct vstor_packet), - sizeof(struct vmscsi_request)); - - /* Make sure we are at least 2 pages since 1 page is used for control */ - /* ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1)); */ - - Driver->name = gDriverName; - memcpy(&Driver->deviceType, &gStorVscDeviceType, - sizeof(struct hv_guid)); - - storDriver->RequestExtSize = sizeof(struct storvsc_request_extension); - - /* - * Divide the ring buffer data size (which is 1 page less - * than the ring buffer size since that page is reserved for - * the ring buffer indices) by the max request size (which is - * VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER + struct vstor_packet + u64) - */ - storDriver->MaxOutstandingRequestsPerChannel = - ((storDriver->RingBufferSize - PAGE_SIZE) / - ALIGN_UP(MAX_MULTIPAGE_BUFFER_PACKET + - sizeof(struct vstor_packet) + sizeof(u64), - sizeof(u64))); - - DPRINT_INFO(STORVSC, "max io %u, currently %u\n", - storDriver->MaxOutstandingRequestsPerChannel, - STORVSC_MAX_IO_REQUESTS); - - /* Setup the dispatch table */ - storDriver->Base.OnDeviceAdd = StorVscOnDeviceAdd; - storDriver->Base.OnDeviceRemove = StorVscOnDeviceRemove; - storDriver->Base.OnCleanup = StorVscOnCleanup; - - storDriver->OnIORequest = StorVscOnIORequest; - - DPRINT_EXIT(STORVSC); - - return 0; -} diff --git a/drivers/staging/hv/blkvsc.c b/drivers/staging/hv/blkvsc.c index b2f600551f10..0daebc472e63 100644 --- a/drivers/staging/hv/blkvsc.c +++ b/drivers/staging/hv/blkvsc.c @@ -23,7 +23,7 @@ #include #include #include "osd.h" -#include "StorVsc.c" +#include "storvsc.c" static const char *gBlkDriverName = "blkvsc"; diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c new file mode 100644 index 000000000000..e73130e49cce --- /dev/null +++ b/drivers/staging/hv/storvsc.c @@ -0,0 +1,858 @@ +/* + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + */ +#include +#include +#include +#include +#include +#include "osd.h" +#include "logging.h" +#include "StorVscApi.h" +#include "VmbusPacketFormat.h" +#include "vstorage.h" + + +struct storvsc_request_extension { + /* LIST_ENTRY ListEntry; */ + + struct hv_storvsc_request *Request; + struct hv_device *Device; + + /* Synchronize the request/response if needed */ + struct osd_waitevent *WaitEvent; + + struct vstor_packet VStorPacket; +}; + +/* A storvsc device is a device object that contains a vmbus channel */ +struct storvsc_device { + struct hv_device *Device; + + /* 0 indicates the device is being destroyed */ + atomic_t RefCount; + + atomic_t NumOutstandingRequests; + + /* + * Each unique Port/Path/Target represents 1 channel ie scsi + * controller. In reality, the pathid, targetid is always 0 + * and the port is set by us + */ + unsigned int PortNumber; + unsigned char PathId; + unsigned char TargetId; + + /* LIST_ENTRY OutstandingRequestList; */ + /* HANDLE OutstandingRequestLock; */ + + /* Used for vsc/vsp channel reset process */ + struct storvsc_request_extension InitRequest; + struct storvsc_request_extension ResetRequest; +}; + + +static const char *gDriverName = "storvsc"; + +/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ +static const struct hv_guid gStorVscDeviceType = { + .data = { + 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, + 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f + } +}; + + +static inline struct storvsc_device *AllocStorDevice(struct hv_device *Device) +{ + struct storvsc_device *storDevice; + + storDevice = kzalloc(sizeof(struct storvsc_device), GFP_KERNEL); + if (!storDevice) + return NULL; + + /* Set to 2 to allow both inbound and outbound traffics */ + /* (ie GetStorDevice() and MustGetStorDevice()) to proceed. */ + atomic_cmpxchg(&storDevice->RefCount, 0, 2); + + storDevice->Device = Device; + Device->Extension = storDevice; + + return storDevice; +} + +static inline void FreeStorDevice(struct storvsc_device *Device) +{ + /* ASSERT(atomic_read(&Device->RefCount) == 0); */ + kfree(Device); +} + +/* Get the stordevice object iff exists and its refcount > 1 */ +static inline struct storvsc_device *GetStorDevice(struct hv_device *Device) +{ + struct storvsc_device *storDevice; + + storDevice = (struct storvsc_device *)Device->Extension; + if (storDevice && atomic_read(&storDevice->RefCount) > 1) + atomic_inc(&storDevice->RefCount); + else + storDevice = NULL; + + return storDevice; +} + +/* Get the stordevice object iff exists and its refcount > 0 */ +static inline struct storvsc_device *MustGetStorDevice(struct hv_device *Device) +{ + struct storvsc_device *storDevice; + + storDevice = (struct storvsc_device *)Device->Extension; + if (storDevice && atomic_read(&storDevice->RefCount)) + atomic_inc(&storDevice->RefCount); + else + storDevice = NULL; + + return storDevice; +} + +static inline void PutStorDevice(struct hv_device *Device) +{ + struct storvsc_device *storDevice; + + storDevice = (struct storvsc_device *)Device->Extension; + /* ASSERT(storDevice); */ + + atomic_dec(&storDevice->RefCount); + /* ASSERT(atomic_read(&storDevice->RefCount)); */ +} + +/* Drop ref count to 1 to effectively disable GetStorDevice() */ +static inline struct storvsc_device *ReleaseStorDevice(struct hv_device *Device) +{ + struct storvsc_device *storDevice; + + storDevice = (struct storvsc_device *)Device->Extension; + /* ASSERT(storDevice); */ + + /* Busy wait until the ref drop to 2, then set it to 1 */ + while (atomic_cmpxchg(&storDevice->RefCount, 2, 1) != 2) + udelay(100); + + return storDevice; +} + +/* Drop ref count to 0. No one can use StorDevice object. */ +static inline struct storvsc_device *FinalReleaseStorDevice( + struct hv_device *Device) +{ + struct storvsc_device *storDevice; + + storDevice = (struct storvsc_device *)Device->Extension; + /* ASSERT(storDevice); */ + + /* Busy wait until the ref drop to 1, then set it to 0 */ + while (atomic_cmpxchg(&storDevice->RefCount, 1, 0) != 1) + udelay(100); + + Device->Extension = NULL; + return storDevice; +} + +static int StorVscChannelInit(struct hv_device *Device) +{ + struct storvsc_device *storDevice; + struct storvsc_request_extension *request; + struct vstor_packet *vstorPacket; + int ret; + + storDevice = GetStorDevice(Device); + if (!storDevice) { + DPRINT_ERR(STORVSC, "unable to get stor device..." + "device being destroyed?"); + DPRINT_EXIT(STORVSC); + return -1; + } + + request = &storDevice->InitRequest; + vstorPacket = &request->VStorPacket; + + /* + * Now, initiate the vsc/vsp initialization protocol on the open + * channel + */ + memset(request, 0, sizeof(struct storvsc_request_extension)); + request->WaitEvent = osd_WaitEventCreate(); + if (!request->WaitEvent) { + ret = -ENOMEM; + goto nomem; + } + + vstorPacket->Operation = VStorOperationBeginInitialization; + vstorPacket->Flags = REQUEST_COMPLETION_FLAG; + + /*SpinlockAcquire(gDriverExt.packetListLock); + INSERT_TAIL_LIST(&gDriverExt.packetList, &packet->listEntry.entry); + SpinlockRelease(gDriverExt.packetListLock);*/ + + DPRINT_INFO(STORVSC, "BEGIN_INITIALIZATION_OPERATION..."); + + ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, + vstorPacket, + sizeof(struct vstor_packet), + (unsigned long)request, + VmbusPacketTypeDataInBand, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + if (ret != 0) { + DPRINT_ERR(STORVSC, + "unable to send BEGIN_INITIALIZATION_OPERATION"); + goto Cleanup; + } + + osd_WaitEventWait(request->WaitEvent); + + if (vstorPacket->Operation != VStorOperationCompleteIo || + vstorPacket->Status != 0) { + DPRINT_ERR(STORVSC, "BEGIN_INITIALIZATION_OPERATION failed " + "(op %d status 0x%x)", + vstorPacket->Operation, vstorPacket->Status); + goto Cleanup; + } + + DPRINT_INFO(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION..."); + + /* reuse the packet for version range supported */ + memset(vstorPacket, 0, sizeof(struct vstor_packet)); + vstorPacket->Operation = VStorOperationQueryProtocolVersion; + vstorPacket->Flags = REQUEST_COMPLETION_FLAG; + + vstorPacket->Version.MajorMinor = VMSTOR_PROTOCOL_VERSION_CURRENT; + FILL_VMSTOR_REVISION(vstorPacket->Version.Revision); + + ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, + vstorPacket, + sizeof(struct vstor_packet), + (unsigned long)request, + VmbusPacketTypeDataInBand, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + if (ret != 0) { + DPRINT_ERR(STORVSC, + "unable to send BEGIN_INITIALIZATION_OPERATION"); + goto Cleanup; + } + + osd_WaitEventWait(request->WaitEvent); + + /* TODO: Check returned version */ + if (vstorPacket->Operation != VStorOperationCompleteIo || + vstorPacket->Status != 0) { + DPRINT_ERR(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION failed " + "(op %d status 0x%x)", + vstorPacket->Operation, vstorPacket->Status); + goto Cleanup; + } + + /* Query channel properties */ + DPRINT_INFO(STORVSC, "QUERY_PROPERTIES_OPERATION..."); + + memset(vstorPacket, 0, sizeof(struct vstor_packet)); + vstorPacket->Operation = VStorOperationQueryProperties; + vstorPacket->Flags = REQUEST_COMPLETION_FLAG; + vstorPacket->StorageChannelProperties.PortNumber = + storDevice->PortNumber; + + ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, + vstorPacket, + sizeof(struct vstor_packet), + (unsigned long)request, + VmbusPacketTypeDataInBand, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + + if (ret != 0) { + DPRINT_ERR(STORVSC, + "unable to send QUERY_PROPERTIES_OPERATION"); + goto Cleanup; + } + + osd_WaitEventWait(request->WaitEvent); + + /* TODO: Check returned version */ + if (vstorPacket->Operation != VStorOperationCompleteIo || + vstorPacket->Status != 0) { + DPRINT_ERR(STORVSC, "QUERY_PROPERTIES_OPERATION failed " + "(op %d status 0x%x)", + vstorPacket->Operation, vstorPacket->Status); + goto Cleanup; + } + + storDevice->PathId = vstorPacket->StorageChannelProperties.PathId; + storDevice->TargetId = vstorPacket->StorageChannelProperties.TargetId; + + DPRINT_DBG(STORVSC, "channel flag 0x%x, max xfer len 0x%x", + vstorPacket->StorageChannelProperties.Flags, + vstorPacket->StorageChannelProperties.MaxTransferBytes); + + DPRINT_INFO(STORVSC, "END_INITIALIZATION_OPERATION..."); + + memset(vstorPacket, 0, sizeof(struct vstor_packet)); + vstorPacket->Operation = VStorOperationEndInitialization; + vstorPacket->Flags = REQUEST_COMPLETION_FLAG; + + ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, + vstorPacket, + sizeof(struct vstor_packet), + (unsigned long)request, + VmbusPacketTypeDataInBand, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + + if (ret != 0) { + DPRINT_ERR(STORVSC, + "unable to send END_INITIALIZATION_OPERATION"); + goto Cleanup; + } + + osd_WaitEventWait(request->WaitEvent); + + if (vstorPacket->Operation != VStorOperationCompleteIo || + vstorPacket->Status != 0) { + DPRINT_ERR(STORVSC, "END_INITIALIZATION_OPERATION failed " + "(op %d status 0x%x)", + vstorPacket->Operation, vstorPacket->Status); + goto Cleanup; + } + + DPRINT_INFO(STORVSC, "**** storage channel up and running!! ****"); + +Cleanup: + kfree(request->WaitEvent); + request->WaitEvent = NULL; +nomem: + PutStorDevice(Device); + + DPRINT_EXIT(STORVSC); + return ret; +} + +static void StorVscOnIOCompletion(struct hv_device *Device, + struct vstor_packet *VStorPacket, + struct storvsc_request_extension *RequestExt) +{ + struct hv_storvsc_request *request; + struct storvsc_device *storDevice; + + DPRINT_ENTER(STORVSC); + + storDevice = MustGetStorDevice(Device); + if (!storDevice) { + DPRINT_ERR(STORVSC, "unable to get stor device..." + "device being destroyed?"); + DPRINT_EXIT(STORVSC); + return; + } + + DPRINT_DBG(STORVSC, "IO_COMPLETE_OPERATION - request extension %p " + "completed bytes xfer %u", RequestExt, + VStorPacket->VmSrb.DataTransferLength); + + /* ASSERT(RequestExt != NULL); */ + /* ASSERT(RequestExt->Request != NULL); */ + + request = RequestExt->Request; + + /* ASSERT(request->OnIOCompletion != NULL); */ + + /* Copy over the status...etc */ + request->Status = VStorPacket->VmSrb.ScsiStatus; + + if (request->Status != 0 || VStorPacket->VmSrb.SrbStatus != 1) { + DPRINT_WARN(STORVSC, + "cmd 0x%x scsi status 0x%x srb status 0x%x\n", + request->Cdb[0], VStorPacket->VmSrb.ScsiStatus, + VStorPacket->VmSrb.SrbStatus); + } + + if ((request->Status & 0xFF) == 0x02) { + /* CHECK_CONDITION */ + if (VStorPacket->VmSrb.SrbStatus & 0x80) { + /* autosense data available */ + DPRINT_WARN(STORVSC, "storvsc pkt %p autosense data " + "valid - len %d\n", RequestExt, + VStorPacket->VmSrb.SenseInfoLength); + + /* ASSERT(VStorPacket->VmSrb.SenseInfoLength <= */ + /* request->SenseBufferSize); */ + memcpy(request->SenseBuffer, + VStorPacket->VmSrb.SenseData, + VStorPacket->VmSrb.SenseInfoLength); + + request->SenseBufferSize = + VStorPacket->VmSrb.SenseInfoLength; + } + } + + /* TODO: */ + request->BytesXfer = VStorPacket->VmSrb.DataTransferLength; + + request->OnIOCompletion(request); + + atomic_dec(&storDevice->NumOutstandingRequests); + + PutStorDevice(Device); + + DPRINT_EXIT(STORVSC); +} + +static void StorVscOnReceive(struct hv_device *Device, + struct vstor_packet *VStorPacket, + struct storvsc_request_extension *RequestExt) +{ + switch (VStorPacket->Operation) { + case VStorOperationCompleteIo: + DPRINT_DBG(STORVSC, "IO_COMPLETE_OPERATION"); + StorVscOnIOCompletion(Device, VStorPacket, RequestExt); + break; + case VStorOperationRemoveDevice: + DPRINT_INFO(STORVSC, "REMOVE_DEVICE_OPERATION"); + /* TODO: */ + break; + + default: + DPRINT_INFO(STORVSC, "Unknown operation received - %d", + VStorPacket->Operation); + break; + } +} + +static void StorVscOnChannelCallback(void *context) +{ + struct hv_device *device = (struct hv_device *)context; + struct storvsc_device *storDevice; + u32 bytesRecvd; + u64 requestId; + unsigned char packet[ALIGN_UP(sizeof(struct vstor_packet), 8)]; + struct storvsc_request_extension *request; + int ret; + + DPRINT_ENTER(STORVSC); + + /* ASSERT(device); */ + + storDevice = MustGetStorDevice(device); + if (!storDevice) { + DPRINT_ERR(STORVSC, "unable to get stor device..." + "device being destroyed?"); + DPRINT_EXIT(STORVSC); + return; + } + + do { + ret = device->Driver->VmbusChannelInterface.RecvPacket(device, + packet, + ALIGN_UP(sizeof(struct vstor_packet), 8), + &bytesRecvd, &requestId); + if (ret == 0 && bytesRecvd > 0) { + DPRINT_DBG(STORVSC, "receive %d bytes - tid %llx", + bytesRecvd, requestId); + + /* ASSERT(bytesRecvd == sizeof(struct vstor_packet)); */ + + request = (struct storvsc_request_extension *) + (unsigned long)requestId; + /* ASSERT(request);c */ + + /* if (vstorPacket.Flags & SYNTHETIC_FLAG) */ + if ((request == &storDevice->InitRequest) || + (request == &storDevice->ResetRequest)) { + /* DPRINT_INFO(STORVSC, + * "reset completion - operation " + * "%u status %u", + * vstorPacket.Operation, + * vstorPacket.Status); */ + + memcpy(&request->VStorPacket, packet, + sizeof(struct vstor_packet)); + + osd_WaitEventSet(request->WaitEvent); + } else { + StorVscOnReceive(device, + (struct vstor_packet *)packet, + request); + } + } else { + /* DPRINT_DBG(STORVSC, "nothing else to read..."); */ + break; + } + } while (1); + + PutStorDevice(device); + + DPRINT_EXIT(STORVSC); + return; +} + +static int StorVscConnectToVsp(struct hv_device *Device) +{ + struct vmstorage_channel_properties props; + struct storvsc_driver_object *storDriver; + int ret; + + storDriver = (struct storvsc_driver_object *)Device->Driver; + memset(&props, 0, sizeof(struct vmstorage_channel_properties)); + + /* Open the channel */ + ret = Device->Driver->VmbusChannelInterface.Open(Device, + storDriver->RingBufferSize, + storDriver->RingBufferSize, + (void *)&props, + sizeof(struct vmstorage_channel_properties), + StorVscOnChannelCallback, + Device); + + DPRINT_DBG(STORVSC, "storage props: path id %d, tgt id %d, max xfer %d", + props.PathId, props.TargetId, props.MaxTransferBytes); + + if (ret != 0) { + DPRINT_ERR(STORVSC, "unable to open channel: %d", ret); + return -1; + } + + ret = StorVscChannelInit(Device); + + return ret; +} + +/* + * StorVscOnDeviceAdd - Callback when the device belonging to this driver is added + */ +static int StorVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) +{ + struct storvsc_device *storDevice; + /* struct vmstorage_channel_properties *props; */ + struct storvsc_device_info *deviceInfo; + int ret = 0; + + DPRINT_ENTER(STORVSC); + + deviceInfo = (struct storvsc_device_info *)AdditionalInfo; + storDevice = AllocStorDevice(Device); + if (!storDevice) { + ret = -1; + goto Cleanup; + } + + /* Save the channel properties to our storvsc channel */ + /* props = (struct vmstorage_channel_properties *) + * channel->offerMsg.Offer.u.Standard.UserDefined; */ + + /* FIXME: */ + /* + * If we support more than 1 scsi channel, we need to set the + * port number here to the scsi channel but how do we get the + * scsi channel prior to the bus scan + */ + + /* storChannel->PortNumber = 0; + storChannel->PathId = props->PathId; + storChannel->TargetId = props->TargetId; */ + + storDevice->PortNumber = deviceInfo->PortNumber; + /* Send it back up */ + ret = StorVscConnectToVsp(Device); + + /* deviceInfo->PortNumber = storDevice->PortNumber; */ + deviceInfo->PathId = storDevice->PathId; + deviceInfo->TargetId = storDevice->TargetId; + + DPRINT_DBG(STORVSC, "assigned port %u, path %u target %u\n", + storDevice->PortNumber, storDevice->PathId, + storDevice->TargetId); + +Cleanup: + DPRINT_EXIT(STORVSC); + + return ret; +} + +/* + * StorVscOnDeviceRemove - Callback when the our device is being removed + */ +static int StorVscOnDeviceRemove(struct hv_device *Device) +{ + struct storvsc_device *storDevice; + + DPRINT_ENTER(STORVSC); + + DPRINT_INFO(STORVSC, "disabling storage device (%p)...", + Device->Extension); + + storDevice = ReleaseStorDevice(Device); + + /* + * At this point, all outbound traffic should be disable. We + * only allow inbound traffic (responses) to proceed so that + * outstanding requests can be completed. + */ + while (atomic_read(&storDevice->NumOutstandingRequests)) { + DPRINT_INFO(STORVSC, "waiting for %d requests to complete...", + atomic_read(&storDevice->NumOutstandingRequests)); + udelay(100); + } + + DPRINT_INFO(STORVSC, "removing storage device (%p)...", + Device->Extension); + + storDevice = FinalReleaseStorDevice(Device); + + DPRINT_INFO(STORVSC, "storage device (%p) safe to remove", storDevice); + + /* Close the channel */ + Device->Driver->VmbusChannelInterface.Close(Device); + + FreeStorDevice(storDevice); + + DPRINT_EXIT(STORVSC); + return 0; +} + +int StorVscOnHostReset(struct hv_device *Device) +{ + struct storvsc_device *storDevice; + struct storvsc_request_extension *request; + struct vstor_packet *vstorPacket; + int ret; + + DPRINT_ENTER(STORVSC); + + DPRINT_INFO(STORVSC, "resetting host adapter..."); + + storDevice = GetStorDevice(Device); + if (!storDevice) { + DPRINT_ERR(STORVSC, "unable to get stor device..." + "device being destroyed?"); + DPRINT_EXIT(STORVSC); + return -1; + } + + request = &storDevice->ResetRequest; + vstorPacket = &request->VStorPacket; + + request->WaitEvent = osd_WaitEventCreate(); + if (!request->WaitEvent) { + ret = -ENOMEM; + goto Cleanup; + } + + vstorPacket->Operation = VStorOperationResetBus; + vstorPacket->Flags = REQUEST_COMPLETION_FLAG; + vstorPacket->VmSrb.PathId = storDevice->PathId; + + ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, + vstorPacket, + sizeof(struct vstor_packet), + (unsigned long)&storDevice->ResetRequest, + VmbusPacketTypeDataInBand, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + if (ret != 0) { + DPRINT_ERR(STORVSC, "Unable to send reset packet %p ret %d", + vstorPacket, ret); + goto Cleanup; + } + + /* FIXME: Add a timeout */ + osd_WaitEventWait(request->WaitEvent); + + kfree(request->WaitEvent); + DPRINT_INFO(STORVSC, "host adapter reset completed"); + + /* + * At this point, all outstanding requests in the adapter + * should have been flushed out and return to us + */ + +Cleanup: + PutStorDevice(Device); + DPRINT_EXIT(STORVSC); + return ret; +} + +/* + * StorVscOnIORequest - Callback to initiate an I/O request + */ +static int StorVscOnIORequest(struct hv_device *Device, + struct hv_storvsc_request *Request) +{ + struct storvsc_device *storDevice; + struct storvsc_request_extension *requestExtension; + struct vstor_packet *vstorPacket; + int ret = 0; + + DPRINT_ENTER(STORVSC); + + requestExtension = + (struct storvsc_request_extension *)Request->Extension; + vstorPacket = &requestExtension->VStorPacket; + storDevice = GetStorDevice(Device); + + DPRINT_DBG(STORVSC, "enter - Device %p, DeviceExt %p, Request %p, " + "Extension %p", Device, storDevice, Request, + requestExtension); + + DPRINT_DBG(STORVSC, "req %p len %d bus %d, target %d, lun %d cdblen %d", + Request, Request->DataBuffer.Length, Request->Bus, + Request->TargetId, Request->LunId, Request->CdbLen); + + if (!storDevice) { + DPRINT_ERR(STORVSC, "unable to get stor device..." + "device being destroyed?"); + DPRINT_EXIT(STORVSC); + return -2; + } + + /* print_hex_dump_bytes("", DUMP_PREFIX_NONE, Request->Cdb, + * Request->CdbLen); */ + + requestExtension->Request = Request; + requestExtension->Device = Device; + + memset(vstorPacket, 0 , sizeof(struct vstor_packet)); + + vstorPacket->Flags |= REQUEST_COMPLETION_FLAG; + + vstorPacket->VmSrb.Length = sizeof(struct vmscsi_request); + + vstorPacket->VmSrb.PortNumber = Request->Host; + vstorPacket->VmSrb.PathId = Request->Bus; + vstorPacket->VmSrb.TargetId = Request->TargetId; + vstorPacket->VmSrb.Lun = Request->LunId; + + vstorPacket->VmSrb.SenseInfoLength = SENSE_BUFFER_SIZE; + + /* Copy over the scsi command descriptor block */ + vstorPacket->VmSrb.CdbLength = Request->CdbLen; + memcpy(&vstorPacket->VmSrb.Cdb, Request->Cdb, Request->CdbLen); + + vstorPacket->VmSrb.DataIn = Request->Type; + vstorPacket->VmSrb.DataTransferLength = Request->DataBuffer.Length; + + vstorPacket->Operation = VStorOperationExecuteSRB; + + DPRINT_DBG(STORVSC, "srb - len %d port %d, path %d, target %d, " + "lun %d senselen %d cdblen %d", + vstorPacket->VmSrb.Length, + vstorPacket->VmSrb.PortNumber, + vstorPacket->VmSrb.PathId, + vstorPacket->VmSrb.TargetId, + vstorPacket->VmSrb.Lun, + vstorPacket->VmSrb.SenseInfoLength, + vstorPacket->VmSrb.CdbLength); + + if (requestExtension->Request->DataBuffer.Length) { + ret = Device->Driver->VmbusChannelInterface. + SendPacketMultiPageBuffer(Device, + &requestExtension->Request->DataBuffer, + vstorPacket, + sizeof(struct vstor_packet), + (unsigned long)requestExtension); + } else { + ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, + vstorPacket, + sizeof(struct vstor_packet), + (unsigned long)requestExtension, + VmbusPacketTypeDataInBand, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + } + + if (ret != 0) { + DPRINT_DBG(STORVSC, "Unable to send packet %p ret %d", + vstorPacket, ret); + } + + atomic_inc(&storDevice->NumOutstandingRequests); + + PutStorDevice(Device); + + DPRINT_EXIT(STORVSC); + return ret; +} + +/* + * StorVscOnCleanup - Perform any cleanup when the driver is removed + */ +static void StorVscOnCleanup(struct hv_driver *Driver) +{ + DPRINT_ENTER(STORVSC); + DPRINT_EXIT(STORVSC); +} + +/* + * StorVscInitialize - Main entry point + */ +int StorVscInitialize(struct hv_driver *Driver) +{ + struct storvsc_driver_object *storDriver; + + DPRINT_ENTER(STORVSC); + + storDriver = (struct storvsc_driver_object *)Driver; + + DPRINT_DBG(STORVSC, "sizeof(STORVSC_REQUEST)=%zd " + "sizeof(struct storvsc_request_extension)=%zd " + "sizeof(struct vstor_packet)=%zd, " + "sizeof(struct vmscsi_request)=%zd", + sizeof(struct hv_storvsc_request), + sizeof(struct storvsc_request_extension), + sizeof(struct vstor_packet), + sizeof(struct vmscsi_request)); + + /* Make sure we are at least 2 pages since 1 page is used for control */ + /* ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1)); */ + + Driver->name = gDriverName; + memcpy(&Driver->deviceType, &gStorVscDeviceType, + sizeof(struct hv_guid)); + + storDriver->RequestExtSize = sizeof(struct storvsc_request_extension); + + /* + * Divide the ring buffer data size (which is 1 page less + * than the ring buffer size since that page is reserved for + * the ring buffer indices) by the max request size (which is + * VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER + struct vstor_packet + u64) + */ + storDriver->MaxOutstandingRequestsPerChannel = + ((storDriver->RingBufferSize - PAGE_SIZE) / + ALIGN_UP(MAX_MULTIPAGE_BUFFER_PACKET + + sizeof(struct vstor_packet) + sizeof(u64), + sizeof(u64))); + + DPRINT_INFO(STORVSC, "max io %u, currently %u\n", + storDriver->MaxOutstandingRequestsPerChannel, + STORVSC_MAX_IO_REQUESTS); + + /* Setup the dispatch table */ + storDriver->Base.OnDeviceAdd = StorVscOnDeviceAdd; + storDriver->Base.OnDeviceRemove = StorVscOnDeviceRemove; + storDriver->Base.OnCleanup = StorVscOnCleanup; + + storDriver->OnIORequest = StorVscOnIORequest; + + DPRINT_EXIT(STORVSC); + + return 0; +} -- cgit v1.2.3 From 043efcc31e78f4e61b2b8bc321bc9a3c498bf4d1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:32:08 -0700 Subject: Staging: hv: rename RndisFilter.c and .h to rndis_filter.c and .h Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Makefile | 2 +- drivers/staging/hv/RndisFilter.c | 997 -------------------------------------- drivers/staging/hv/RndisFilter.h | 55 --- drivers/staging/hv/netvsc.c | 2 +- drivers/staging/hv/rndis_filter.c | 997 ++++++++++++++++++++++++++++++++++++++ drivers/staging/hv/rndis_filter.h | 55 +++ 6 files changed, 1054 insertions(+), 1054 deletions(-) delete mode 100644 drivers/staging/hv/RndisFilter.c delete mode 100644 drivers/staging/hv/RndisFilter.h create mode 100644 drivers/staging/hv/rndis_filter.c create mode 100644 drivers/staging/hv/rndis_filter.h (limited to 'drivers') diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index cc75185e3b54..685a3200e04e 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -9,4 +9,4 @@ hv_vmbus-objs := vmbus_drv.o osd.o \ ChannelMgmt.o ChannelInterface.o ring_buffer.o hv_storvsc-objs := storvsc_drv.o storvsc.o hv_blkvsc-objs := blkvsc_drv.o blkvsc.o -hv_netvsc-objs := netvsc_drv.o netvsc.o RndisFilter.o +hv_netvsc-objs := netvsc_drv.o netvsc.o rndis_filter.o diff --git a/drivers/staging/hv/RndisFilter.c b/drivers/staging/hv/RndisFilter.c deleted file mode 100644 index 597c972f22c2..000000000000 --- a/drivers/staging/hv/RndisFilter.c +++ /dev/null @@ -1,997 +0,0 @@ -/* - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - */ -#include -#include -#include -#include -#include - -#include "osd.h" -#include "logging.h" -#include "NetVscApi.h" -#include "RndisFilter.h" - -/* Data types */ -struct rndis_filter_driver_object { - /* The original driver */ - struct netvsc_driver InnerDriver; -}; - -enum rndis_device_state { - RNDIS_DEV_UNINITIALIZED = 0, - RNDIS_DEV_INITIALIZING, - RNDIS_DEV_INITIALIZED, - RNDIS_DEV_DATAINITIALIZED, -}; - -struct rndis_device { - struct netvsc_device *NetDevice; - - enum rndis_device_state State; - u32 LinkStatus; - atomic_t NewRequestId; - - spinlock_t request_lock; - struct list_head RequestList; - - unsigned char HwMacAddr[ETH_ALEN]; -}; - -struct rndis_request { - struct list_head ListEntry; - struct osd_waitevent *WaitEvent; - - /* - * FIXME: We assumed a fixed size response here. If we do ever need to - * handle a bigger response, we can either define a max response - * message or add a response buffer variable above this field - */ - struct rndis_message ResponseMessage; - - /* Simplify allocation by having a netvsc packet inline */ - struct hv_netvsc_packet Packet; - struct hv_page_buffer Buffer; - /* FIXME: We assumed a fixed size request here. */ - struct rndis_message RequestMessage; -}; - - -struct rndis_filter_packet { - void *CompletionContext; - void (*OnCompletion)(void *context); - struct rndis_message Message; -}; - - -static int RndisFilterOnDeviceAdd(struct hv_device *Device, - void *AdditionalInfo); - -static int RndisFilterOnDeviceRemove(struct hv_device *Device); - -static void RndisFilterOnCleanup(struct hv_driver *Driver); - -static int RndisFilterOnSend(struct hv_device *Device, - struct hv_netvsc_packet *Packet); - -static void RndisFilterOnSendCompletion(void *Context); - -static void RndisFilterOnSendRequestCompletion(void *Context); - - -/* The one and only */ -static struct rndis_filter_driver_object gRndisFilter; - -static struct rndis_device *GetRndisDevice(void) -{ - struct rndis_device *device; - - device = kzalloc(sizeof(struct rndis_device), GFP_KERNEL); - if (!device) - return NULL; - - spin_lock_init(&device->request_lock); - - INIT_LIST_HEAD(&device->RequestList); - - device->State = RNDIS_DEV_UNINITIALIZED; - - return device; -} - -static struct rndis_request *GetRndisRequest(struct rndis_device *Device, - u32 MessageType, - u32 MessageLength) -{ - struct rndis_request *request; - struct rndis_message *rndisMessage; - struct rndis_set_request *set; - unsigned long flags; - - request = kzalloc(sizeof(struct rndis_request), GFP_KERNEL); - if (!request) - return NULL; - - request->WaitEvent = osd_WaitEventCreate(); - if (!request->WaitEvent) { - kfree(request); - return NULL; - } - - rndisMessage = &request->RequestMessage; - rndisMessage->NdisMessageType = MessageType; - rndisMessage->MessageLength = MessageLength; - - /* - * Set the request id. This field is always after the rndis header for - * request/response packet types so we just used the SetRequest as a - * template - */ - set = &rndisMessage->Message.SetRequest; - set->RequestId = atomic_inc_return(&Device->NewRequestId); - - /* Add to the request list */ - spin_lock_irqsave(&Device->request_lock, flags); - list_add_tail(&request->ListEntry, &Device->RequestList); - spin_unlock_irqrestore(&Device->request_lock, flags); - - return request; -} - -static void PutRndisRequest(struct rndis_device *Device, - struct rndis_request *Request) -{ - unsigned long flags; - - spin_lock_irqsave(&Device->request_lock, flags); - list_del(&Request->ListEntry); - spin_unlock_irqrestore(&Device->request_lock, flags); - - kfree(Request->WaitEvent); - kfree(Request); -} - -static void DumpRndisMessage(struct rndis_message *RndisMessage) -{ - switch (RndisMessage->NdisMessageType) { - case REMOTE_NDIS_PACKET_MSG: - DPRINT_DBG(NETVSC, "REMOTE_NDIS_PACKET_MSG (len %u, " - "data offset %u data len %u, # oob %u, " - "oob offset %u, oob len %u, pkt offset %u, " - "pkt len %u", - RndisMessage->MessageLength, - RndisMessage->Message.Packet.DataOffset, - RndisMessage->Message.Packet.DataLength, - RndisMessage->Message.Packet.NumOOBDataElements, - RndisMessage->Message.Packet.OOBDataOffset, - RndisMessage->Message.Packet.OOBDataLength, - RndisMessage->Message.Packet.PerPacketInfoOffset, - RndisMessage->Message.Packet.PerPacketInfoLength); - break; - - case REMOTE_NDIS_INITIALIZE_CMPLT: - DPRINT_DBG(NETVSC, "REMOTE_NDIS_INITIALIZE_CMPLT " - "(len %u, id 0x%x, status 0x%x, major %d, minor %d, " - "device flags %d, max xfer size 0x%x, max pkts %u, " - "pkt aligned %u)", - RndisMessage->MessageLength, - RndisMessage->Message.InitializeComplete.RequestId, - RndisMessage->Message.InitializeComplete.Status, - RndisMessage->Message.InitializeComplete.MajorVersion, - RndisMessage->Message.InitializeComplete.MinorVersion, - RndisMessage->Message.InitializeComplete.DeviceFlags, - RndisMessage->Message.InitializeComplete.MaxTransferSize, - RndisMessage->Message.InitializeComplete.MaxPacketsPerMessage, - RndisMessage->Message.InitializeComplete.PacketAlignmentFactor); - break; - - case REMOTE_NDIS_QUERY_CMPLT: - DPRINT_DBG(NETVSC, "REMOTE_NDIS_QUERY_CMPLT " - "(len %u, id 0x%x, status 0x%x, buf len %u, " - "buf offset %u)", - RndisMessage->MessageLength, - RndisMessage->Message.QueryComplete.RequestId, - RndisMessage->Message.QueryComplete.Status, - RndisMessage->Message.QueryComplete.InformationBufferLength, - RndisMessage->Message.QueryComplete.InformationBufferOffset); - break; - - case REMOTE_NDIS_SET_CMPLT: - DPRINT_DBG(NETVSC, - "REMOTE_NDIS_SET_CMPLT (len %u, id 0x%x, status 0x%x)", - RndisMessage->MessageLength, - RndisMessage->Message.SetComplete.RequestId, - RndisMessage->Message.SetComplete.Status); - break; - - case REMOTE_NDIS_INDICATE_STATUS_MSG: - DPRINT_DBG(NETVSC, "REMOTE_NDIS_INDICATE_STATUS_MSG " - "(len %u, status 0x%x, buf len %u, buf offset %u)", - RndisMessage->MessageLength, - RndisMessage->Message.IndicateStatus.Status, - RndisMessage->Message.IndicateStatus.StatusBufferLength, - RndisMessage->Message.IndicateStatus.StatusBufferOffset); - break; - - default: - DPRINT_DBG(NETVSC, "0x%x (len %u)", - RndisMessage->NdisMessageType, - RndisMessage->MessageLength); - break; - } -} - -static int RndisFilterSendRequest(struct rndis_device *Device, - struct rndis_request *Request) -{ - int ret; - struct hv_netvsc_packet *packet; - - DPRINT_ENTER(NETVSC); - - /* Setup the packet to send it */ - packet = &Request->Packet; - - packet->IsDataPacket = false; - packet->TotalDataBufferLength = Request->RequestMessage.MessageLength; - packet->PageBufferCount = 1; - - packet->PageBuffers[0].Pfn = virt_to_phys(&Request->RequestMessage) >> - PAGE_SHIFT; - packet->PageBuffers[0].Length = Request->RequestMessage.MessageLength; - packet->PageBuffers[0].Offset = - (unsigned long)&Request->RequestMessage & (PAGE_SIZE - 1); - - packet->Completion.Send.SendCompletionContext = Request;/* packet; */ - packet->Completion.Send.OnSendCompletion = - RndisFilterOnSendRequestCompletion; - packet->Completion.Send.SendCompletionTid = (unsigned long)Device; - - ret = gRndisFilter.InnerDriver.OnSend(Device->NetDevice->Device, packet); - DPRINT_EXIT(NETVSC); - return ret; -} - -static void RndisFilterReceiveResponse(struct rndis_device *Device, - struct rndis_message *Response) -{ - struct rndis_request *request = NULL; - bool found = false; - unsigned long flags; - - DPRINT_ENTER(NETVSC); - - spin_lock_irqsave(&Device->request_lock, flags); - list_for_each_entry(request, &Device->RequestList, ListEntry) { - /* - * All request/response message contains RequestId as the 1st - * field - */ - if (request->RequestMessage.Message.InitializeRequest.RequestId - == Response->Message.InitializeComplete.RequestId) { - DPRINT_DBG(NETVSC, "found rndis request for " - "this response (id 0x%x req type 0x%x res " - "type 0x%x)", - request->RequestMessage.Message.InitializeRequest.RequestId, - request->RequestMessage.NdisMessageType, - Response->NdisMessageType); - - found = true; - break; - } - } - spin_unlock_irqrestore(&Device->request_lock, flags); - - if (found) { - if (Response->MessageLength <= sizeof(struct rndis_message)) { - memcpy(&request->ResponseMessage, Response, - Response->MessageLength); - } else { - DPRINT_ERR(NETVSC, "rndis response buffer overflow " - "detected (size %u max %zu)", - Response->MessageLength, - sizeof(struct rndis_filter_packet)); - - if (Response->NdisMessageType == - REMOTE_NDIS_RESET_CMPLT) { - /* does not have a request id field */ - request->ResponseMessage.Message.ResetComplete.Status = STATUS_BUFFER_OVERFLOW; - } else { - request->ResponseMessage.Message.InitializeComplete.Status = STATUS_BUFFER_OVERFLOW; - } - } - - osd_WaitEventSet(request->WaitEvent); - } else { - DPRINT_ERR(NETVSC, "no rndis request found for this response " - "(id 0x%x res type 0x%x)", - Response->Message.InitializeComplete.RequestId, - Response->NdisMessageType); - } - - DPRINT_EXIT(NETVSC); -} - -static void RndisFilterReceiveIndicateStatus(struct rndis_device *Device, - struct rndis_message *Response) -{ - struct rndis_indicate_status *indicate = - &Response->Message.IndicateStatus; - - if (indicate->Status == RNDIS_STATUS_MEDIA_CONNECT) { - gRndisFilter.InnerDriver.OnLinkStatusChanged(Device->NetDevice->Device, 1); - } else if (indicate->Status == RNDIS_STATUS_MEDIA_DISCONNECT) { - gRndisFilter.InnerDriver.OnLinkStatusChanged(Device->NetDevice->Device, 0); - } else { - /* - * TODO: - */ - } -} - -static void RndisFilterReceiveData(struct rndis_device *Device, - struct rndis_message *Message, - struct hv_netvsc_packet *Packet) -{ - struct rndis_packet *rndisPacket; - u32 dataOffset; - - DPRINT_ENTER(NETVSC); - - /* empty ethernet frame ?? */ - /* ASSERT(Packet->PageBuffers[0].Length > */ - /* RNDIS_MESSAGE_SIZE(struct rndis_packet)); */ - - rndisPacket = &Message->Message.Packet; - - /* - * FIXME: Handle multiple rndis pkt msgs that maybe enclosed in this - * netvsc packet (ie TotalDataBufferLength != MessageLength) - */ - - /* Remove the rndis header and pass it back up the stack */ - dataOffset = RNDIS_HEADER_SIZE + rndisPacket->DataOffset; - - Packet->TotalDataBufferLength -= dataOffset; - Packet->PageBuffers[0].Offset += dataOffset; - Packet->PageBuffers[0].Length -= dataOffset; - - Packet->IsDataPacket = true; - - gRndisFilter.InnerDriver.OnReceiveCallback(Device->NetDevice->Device, - Packet); - - DPRINT_EXIT(NETVSC); -} - -static int RndisFilterOnReceive(struct hv_device *Device, - struct hv_netvsc_packet *Packet) -{ - struct netvsc_device *netDevice = Device->Extension; - struct rndis_device *rndisDevice; - struct rndis_message rndisMessage; - struct rndis_message *rndisHeader; - - DPRINT_ENTER(NETVSC); - - if (!netDevice) - return -EINVAL; - - /* Make sure the rndis device state is initialized */ - if (!netDevice->Extension) { - DPRINT_ERR(NETVSC, "got rndis message but no rndis device..." - "dropping this message!"); - DPRINT_EXIT(NETVSC); - return -1; - } - - rndisDevice = (struct rndis_device *)netDevice->Extension; - if (rndisDevice->State == RNDIS_DEV_UNINITIALIZED) { - DPRINT_ERR(NETVSC, "got rndis message but rndis device " - "uninitialized...dropping this message!"); - DPRINT_EXIT(NETVSC); - return -1; - } - - rndisHeader = (struct rndis_message *)kmap_atomic( - pfn_to_page(Packet->PageBuffers[0].Pfn), KM_IRQ0); - - rndisHeader = (void *)((unsigned long)rndisHeader + - Packet->PageBuffers[0].Offset); - - /* Make sure we got a valid rndis message */ - /* - * FIXME: There seems to be a bug in set completion msg where its - * MessageLength is 16 bytes but the ByteCount field in the xfer page - * range shows 52 bytes - * */ -#if 0 - if (Packet->TotalDataBufferLength != rndisHeader->MessageLength) { - kunmap_atomic(rndisHeader - Packet->PageBuffers[0].Offset, - KM_IRQ0); - - DPRINT_ERR(NETVSC, "invalid rndis message? (expected %u " - "bytes got %u)...dropping this message!", - rndisHeader->MessageLength, - Packet->TotalDataBufferLength); - DPRINT_EXIT(NETVSC); - return -1; - } -#endif - - if ((rndisHeader->NdisMessageType != REMOTE_NDIS_PACKET_MSG) && - (rndisHeader->MessageLength > sizeof(struct rndis_message))) { - DPRINT_ERR(NETVSC, "incoming rndis message buffer overflow " - "detected (got %u, max %zu)...marking it an error!", - rndisHeader->MessageLength, - sizeof(struct rndis_message)); - } - - memcpy(&rndisMessage, rndisHeader, - (rndisHeader->MessageLength > sizeof(struct rndis_message)) ? - sizeof(struct rndis_message) : - rndisHeader->MessageLength); - - kunmap_atomic(rndisHeader - Packet->PageBuffers[0].Offset, KM_IRQ0); - - DumpRndisMessage(&rndisMessage); - - switch (rndisMessage.NdisMessageType) { - case REMOTE_NDIS_PACKET_MSG: - /* data msg */ - RndisFilterReceiveData(rndisDevice, &rndisMessage, Packet); - break; - - case REMOTE_NDIS_INITIALIZE_CMPLT: - case REMOTE_NDIS_QUERY_CMPLT: - case REMOTE_NDIS_SET_CMPLT: - /* case REMOTE_NDIS_RESET_CMPLT: */ - /* case REMOTE_NDIS_KEEPALIVE_CMPLT: */ - /* completion msgs */ - RndisFilterReceiveResponse(rndisDevice, &rndisMessage); - break; - - case REMOTE_NDIS_INDICATE_STATUS_MSG: - /* notification msgs */ - RndisFilterReceiveIndicateStatus(rndisDevice, &rndisMessage); - break; - default: - DPRINT_ERR(NETVSC, "unhandled rndis message (type %u len %u)", - rndisMessage.NdisMessageType, - rndisMessage.MessageLength); - break; - } - - DPRINT_EXIT(NETVSC); - return 0; -} - -static int RndisFilterQueryDevice(struct rndis_device *Device, u32 Oid, - void *Result, u32 *ResultSize) -{ - struct rndis_request *request; - u32 inresultSize = *ResultSize; - struct rndis_query_request *query; - struct rndis_query_complete *queryComplete; - int ret = 0; - - DPRINT_ENTER(NETVSC); - - if (!Result) - return -EINVAL; - - *ResultSize = 0; - request = GetRndisRequest(Device, REMOTE_NDIS_QUERY_MSG, - RNDIS_MESSAGE_SIZE(struct rndis_query_request)); - if (!request) { - ret = -1; - goto Cleanup; - } - - /* Setup the rndis query */ - query = &request->RequestMessage.Message.QueryRequest; - query->Oid = Oid; - query->InformationBufferOffset = sizeof(struct rndis_query_request); - query->InformationBufferLength = 0; - query->DeviceVcHandle = 0; - - ret = RndisFilterSendRequest(Device, request); - if (ret != 0) - goto Cleanup; - - osd_WaitEventWait(request->WaitEvent); - - /* Copy the response back */ - queryComplete = &request->ResponseMessage.Message.QueryComplete; - - if (queryComplete->InformationBufferLength > inresultSize) { - ret = -1; - goto Cleanup; - } - - memcpy(Result, - (void *)((unsigned long)queryComplete + - queryComplete->InformationBufferOffset), - queryComplete->InformationBufferLength); - - *ResultSize = queryComplete->InformationBufferLength; - -Cleanup: - if (request) - PutRndisRequest(Device, request); - DPRINT_EXIT(NETVSC); - - return ret; -} - -static int RndisFilterQueryDeviceMac(struct rndis_device *Device) -{ - u32 size = ETH_ALEN; - - return RndisFilterQueryDevice(Device, - RNDIS_OID_802_3_PERMANENT_ADDRESS, - Device->HwMacAddr, &size); -} - -static int RndisFilterQueryDeviceLinkStatus(struct rndis_device *Device) -{ - u32 size = sizeof(u32); - - return RndisFilterQueryDevice(Device, - RNDIS_OID_GEN_MEDIA_CONNECT_STATUS, - &Device->LinkStatus, &size); -} - -static int RndisFilterSetPacketFilter(struct rndis_device *Device, - u32 NewFilter) -{ - struct rndis_request *request; - struct rndis_set_request *set; - struct rndis_set_complete *setComplete; - u32 status; - int ret; - - DPRINT_ENTER(NETVSC); - - /* ASSERT(RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32) <= */ - /* sizeof(struct rndis_message)); */ - - request = GetRndisRequest(Device, REMOTE_NDIS_SET_MSG, - RNDIS_MESSAGE_SIZE(struct rndis_set_request) + - sizeof(u32)); - if (!request) { - ret = -1; - goto Cleanup; - } - - /* Setup the rndis set */ - set = &request->RequestMessage.Message.SetRequest; - set->Oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER; - set->InformationBufferLength = sizeof(u32); - set->InformationBufferOffset = sizeof(struct rndis_set_request); - - memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request), - &NewFilter, sizeof(u32)); - - ret = RndisFilterSendRequest(Device, request); - if (ret != 0) - goto Cleanup; - - ret = osd_WaitEventWaitEx(request->WaitEvent, 2000/*2sec*/); - if (!ret) { - ret = -1; - DPRINT_ERR(NETVSC, "timeout before we got a set response..."); - /* - * We cant deallocate the request since we may still receive a - * send completion for it. - */ - goto Exit; - } else { - if (ret > 0) - ret = 0; - setComplete = &request->ResponseMessage.Message.SetComplete; - status = setComplete->Status; - } - -Cleanup: - if (request) - PutRndisRequest(Device, request); -Exit: - DPRINT_EXIT(NETVSC); - - return ret; -} - -int RndisFilterInit(struct netvsc_driver *Driver) -{ - DPRINT_ENTER(NETVSC); - - DPRINT_DBG(NETVSC, "sizeof(struct rndis_filter_packet) == %zd", - sizeof(struct rndis_filter_packet)); - - Driver->RequestExtSize = sizeof(struct rndis_filter_packet); - - /* Driver->Context = rndisDriver; */ - - memset(&gRndisFilter, 0, sizeof(struct rndis_filter_driver_object)); - - /*rndisDriver->Driver = Driver; - - ASSERT(Driver->OnLinkStatusChanged); - rndisDriver->OnLinkStatusChanged = Driver->OnLinkStatusChanged;*/ - - /* Save the original dispatch handlers before we override it */ - gRndisFilter.InnerDriver.Base.OnDeviceAdd = Driver->Base.OnDeviceAdd; - gRndisFilter.InnerDriver.Base.OnDeviceRemove = - Driver->Base.OnDeviceRemove; - gRndisFilter.InnerDriver.Base.OnCleanup = Driver->Base.OnCleanup; - - /* ASSERT(Driver->OnSend); */ - /* ASSERT(Driver->OnReceiveCallback); */ - gRndisFilter.InnerDriver.OnSend = Driver->OnSend; - gRndisFilter.InnerDriver.OnReceiveCallback = Driver->OnReceiveCallback; - gRndisFilter.InnerDriver.OnLinkStatusChanged = - Driver->OnLinkStatusChanged; - - /* Override */ - Driver->Base.OnDeviceAdd = RndisFilterOnDeviceAdd; - Driver->Base.OnDeviceRemove = RndisFilterOnDeviceRemove; - Driver->Base.OnCleanup = RndisFilterOnCleanup; - Driver->OnSend = RndisFilterOnSend; - /* Driver->QueryLinkStatus = RndisFilterQueryDeviceLinkStatus; */ - Driver->OnReceiveCallback = RndisFilterOnReceive; - - DPRINT_EXIT(NETVSC); - - return 0; -} - -static int RndisFilterInitDevice(struct rndis_device *Device) -{ - struct rndis_request *request; - struct rndis_initialize_request *init; - struct rndis_initialize_complete *initComplete; - u32 status; - int ret; - - DPRINT_ENTER(NETVSC); - - request = GetRndisRequest(Device, REMOTE_NDIS_INITIALIZE_MSG, - RNDIS_MESSAGE_SIZE(struct rndis_initialize_request)); - if (!request) { - ret = -1; - goto Cleanup; - } - - /* Setup the rndis set */ - init = &request->RequestMessage.Message.InitializeRequest; - init->MajorVersion = RNDIS_MAJOR_VERSION; - init->MinorVersion = RNDIS_MINOR_VERSION; - /* FIXME: Use 1536 - rounded ethernet frame size */ - init->MaxTransferSize = 2048; - - Device->State = RNDIS_DEV_INITIALIZING; - - ret = RndisFilterSendRequest(Device, request); - if (ret != 0) { - Device->State = RNDIS_DEV_UNINITIALIZED; - goto Cleanup; - } - - osd_WaitEventWait(request->WaitEvent); - - initComplete = &request->ResponseMessage.Message.InitializeComplete; - status = initComplete->Status; - if (status == RNDIS_STATUS_SUCCESS) { - Device->State = RNDIS_DEV_INITIALIZED; - ret = 0; - } else { - Device->State = RNDIS_DEV_UNINITIALIZED; - ret = -1; - } - -Cleanup: - if (request) - PutRndisRequest(Device, request); - DPRINT_EXIT(NETVSC); - - return ret; -} - -static void RndisFilterHaltDevice(struct rndis_device *Device) -{ - struct rndis_request *request; - struct rndis_halt_request *halt; - - DPRINT_ENTER(NETVSC); - - /* Attempt to do a rndis device halt */ - request = GetRndisRequest(Device, REMOTE_NDIS_HALT_MSG, - RNDIS_MESSAGE_SIZE(struct rndis_halt_request)); - if (!request) - goto Cleanup; - - /* Setup the rndis set */ - halt = &request->RequestMessage.Message.HaltRequest; - halt->RequestId = atomic_inc_return(&Device->NewRequestId); - - /* Ignore return since this msg is optional. */ - RndisFilterSendRequest(Device, request); - - Device->State = RNDIS_DEV_UNINITIALIZED; - -Cleanup: - if (request) - PutRndisRequest(Device, request); - DPRINT_EXIT(NETVSC); - return; -} - -static int RndisFilterOpenDevice(struct rndis_device *Device) -{ - int ret; - - DPRINT_ENTER(NETVSC); - - if (Device->State != RNDIS_DEV_INITIALIZED) - return 0; - - ret = RndisFilterSetPacketFilter(Device, - NDIS_PACKET_TYPE_BROADCAST | - NDIS_PACKET_TYPE_DIRECTED); - if (ret == 0) - Device->State = RNDIS_DEV_DATAINITIALIZED; - - DPRINT_EXIT(NETVSC); - return ret; -} - -static int RndisFilterCloseDevice(struct rndis_device *Device) -{ - int ret; - - DPRINT_ENTER(NETVSC); - - if (Device->State != RNDIS_DEV_DATAINITIALIZED) - return 0; - - ret = RndisFilterSetPacketFilter(Device, 0); - if (ret == 0) - Device->State = RNDIS_DEV_INITIALIZED; - - DPRINT_EXIT(NETVSC); - - return ret; -} - -static int RndisFilterOnDeviceAdd(struct hv_device *Device, - void *AdditionalInfo) -{ - int ret; - struct netvsc_device *netDevice; - struct rndis_device *rndisDevice; - struct netvsc_device_info *deviceInfo = AdditionalInfo; - - DPRINT_ENTER(NETVSC); - - rndisDevice = GetRndisDevice(); - if (!rndisDevice) { - DPRINT_EXIT(NETVSC); - return -1; - } - - DPRINT_DBG(NETVSC, "rndis device object allocated - %p", rndisDevice); - - /* - * Let the inner driver handle this first to create the netvsc channel - * NOTE! Once the channel is created, we may get a receive callback - * (RndisFilterOnReceive()) before this call is completed - */ - ret = gRndisFilter.InnerDriver.Base.OnDeviceAdd(Device, AdditionalInfo); - if (ret != 0) { - kfree(rndisDevice); - DPRINT_EXIT(NETVSC); - return ret; - } - - - /* Initialize the rndis device */ - netDevice = Device->Extension; - /* ASSERT(netDevice); */ - /* ASSERT(netDevice->Device); */ - - netDevice->Extension = rndisDevice; - rndisDevice->NetDevice = netDevice; - - /* Send the rndis initialization message */ - ret = RndisFilterInitDevice(rndisDevice); - if (ret != 0) { - /* - * TODO: If rndis init failed, we will need to shut down the - * channel - */ - } - - /* Get the mac address */ - ret = RndisFilterQueryDeviceMac(rndisDevice); - if (ret != 0) { - /* - * TODO: shutdown rndis device and the channel - */ - } - - DPRINT_INFO(NETVSC, "Device 0x%p mac addr %pM", - rndisDevice, rndisDevice->HwMacAddr); - - memcpy(deviceInfo->MacAddr, rndisDevice->HwMacAddr, ETH_ALEN); - - RndisFilterQueryDeviceLinkStatus(rndisDevice); - - deviceInfo->LinkState = rndisDevice->LinkStatus; - DPRINT_INFO(NETVSC, "Device 0x%p link state %s", rndisDevice, - ((deviceInfo->LinkState) ? ("down") : ("up"))); - - DPRINT_EXIT(NETVSC); - - return ret; -} - -static int RndisFilterOnDeviceRemove(struct hv_device *Device) -{ - struct netvsc_device *netDevice = Device->Extension; - struct rndis_device *rndisDevice = netDevice->Extension; - - DPRINT_ENTER(NETVSC); - - /* Halt and release the rndis device */ - RndisFilterHaltDevice(rndisDevice); - - kfree(rndisDevice); - netDevice->Extension = NULL; - - /* Pass control to inner driver to remove the device */ - gRndisFilter.InnerDriver.Base.OnDeviceRemove(Device); - - DPRINT_EXIT(NETVSC); - - return 0; -} - -static void RndisFilterOnCleanup(struct hv_driver *Driver) -{ - DPRINT_ENTER(NETVSC); - - DPRINT_EXIT(NETVSC); -} - -int RndisFilterOnOpen(struct hv_device *Device) -{ - int ret; - struct netvsc_device *netDevice = Device->Extension; - - DPRINT_ENTER(NETVSC); - - if (!netDevice) - return -EINVAL; - - ret = RndisFilterOpenDevice(netDevice->Extension); - - DPRINT_EXIT(NETVSC); - - return ret; -} - -int RndisFilterOnClose(struct hv_device *Device) -{ - int ret; - struct netvsc_device *netDevice = Device->Extension; - - DPRINT_ENTER(NETVSC); - - if (!netDevice) - return -EINVAL; - - ret = RndisFilterCloseDevice(netDevice->Extension); - - DPRINT_EXIT(NETVSC); - - return ret; -} - -static int RndisFilterOnSend(struct hv_device *Device, - struct hv_netvsc_packet *Packet) -{ - int ret; - struct rndis_filter_packet *filterPacket; - struct rndis_message *rndisMessage; - struct rndis_packet *rndisPacket; - u32 rndisMessageSize; - - DPRINT_ENTER(NETVSC); - - /* Add the rndis header */ - filterPacket = (struct rndis_filter_packet *)Packet->Extension; - /* ASSERT(filterPacket); */ - - memset(filterPacket, 0, sizeof(struct rndis_filter_packet)); - - rndisMessage = &filterPacket->Message; - rndisMessageSize = RNDIS_MESSAGE_SIZE(struct rndis_packet); - - rndisMessage->NdisMessageType = REMOTE_NDIS_PACKET_MSG; - rndisMessage->MessageLength = Packet->TotalDataBufferLength + - rndisMessageSize; - - rndisPacket = &rndisMessage->Message.Packet; - rndisPacket->DataOffset = sizeof(struct rndis_packet); - rndisPacket->DataLength = Packet->TotalDataBufferLength; - - Packet->IsDataPacket = true; - Packet->PageBuffers[0].Pfn = virt_to_phys(rndisMessage) >> PAGE_SHIFT; - Packet->PageBuffers[0].Offset = - (unsigned long)rndisMessage & (PAGE_SIZE-1); - Packet->PageBuffers[0].Length = rndisMessageSize; - - /* Save the packet send completion and context */ - filterPacket->OnCompletion = Packet->Completion.Send.OnSendCompletion; - filterPacket->CompletionContext = - Packet->Completion.Send.SendCompletionContext; - - /* Use ours */ - Packet->Completion.Send.OnSendCompletion = RndisFilterOnSendCompletion; - Packet->Completion.Send.SendCompletionContext = filterPacket; - - ret = gRndisFilter.InnerDriver.OnSend(Device, Packet); - if (ret != 0) { - /* - * Reset the completion to originals to allow retries from - * above - */ - Packet->Completion.Send.OnSendCompletion = - filterPacket->OnCompletion; - Packet->Completion.Send.SendCompletionContext = - filterPacket->CompletionContext; - } - - DPRINT_EXIT(NETVSC); - - return ret; -} - -static void RndisFilterOnSendCompletion(void *Context) -{ - struct rndis_filter_packet *filterPacket = Context; - - DPRINT_ENTER(NETVSC); - - /* Pass it back to the original handler */ - filterPacket->OnCompletion(filterPacket->CompletionContext); - - DPRINT_EXIT(NETVSC); -} - - -static void RndisFilterOnSendRequestCompletion(void *Context) -{ - DPRINT_ENTER(NETVSC); - - /* Noop */ - DPRINT_EXIT(NETVSC); -} diff --git a/drivers/staging/hv/RndisFilter.h b/drivers/staging/hv/RndisFilter.h deleted file mode 100644 index 764b9bf3e5dc..000000000000 --- a/drivers/staging/hv/RndisFilter.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ - - -#ifndef _RNDISFILTER_H_ -#define _RNDISFILTER_H_ - -#define __struct_bcount(x) - -#include "netvsc.h" - -#include "rndis.h" - -#define RNDIS_HEADER_SIZE (sizeof(struct rndis_message) - \ - sizeof(union rndis_message_container)) - -#define NDIS_PACKET_TYPE_DIRECTED 0x00000001 -#define NDIS_PACKET_TYPE_MULTICAST 0x00000002 -#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004 -#define NDIS_PACKET_TYPE_BROADCAST 0x00000008 -#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010 -#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020 -#define NDIS_PACKET_TYPE_SMT 0x00000040 -#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080 -#define NDIS_PACKET_TYPE_GROUP 0x00000100 -#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00000200 -#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00000400 -#define NDIS_PACKET_TYPE_MAC_FRAME 0x00000800 - - -/* Interface */ - -extern int RndisFilterInit(struct netvsc_driver *driver); - -#endif /* _RNDISFILTER_H_ */ diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index 1000989cc0a7..ba15059c45b2 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -26,7 +26,7 @@ #include "osd.h" #include "logging.h" #include "netvsc.h" -#include "RndisFilter.h" +#include "rndis_filter.h" /* Globals */ diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c new file mode 100644 index 000000000000..e6824e055c11 --- /dev/null +++ b/drivers/staging/hv/rndis_filter.c @@ -0,0 +1,997 @@ +/* + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + */ +#include +#include +#include +#include +#include + +#include "osd.h" +#include "logging.h" +#include "NetVscApi.h" +#include "rndis_filter.h" + +/* Data types */ +struct rndis_filter_driver_object { + /* The original driver */ + struct netvsc_driver InnerDriver; +}; + +enum rndis_device_state { + RNDIS_DEV_UNINITIALIZED = 0, + RNDIS_DEV_INITIALIZING, + RNDIS_DEV_INITIALIZED, + RNDIS_DEV_DATAINITIALIZED, +}; + +struct rndis_device { + struct netvsc_device *NetDevice; + + enum rndis_device_state State; + u32 LinkStatus; + atomic_t NewRequestId; + + spinlock_t request_lock; + struct list_head RequestList; + + unsigned char HwMacAddr[ETH_ALEN]; +}; + +struct rndis_request { + struct list_head ListEntry; + struct osd_waitevent *WaitEvent; + + /* + * FIXME: We assumed a fixed size response here. If we do ever need to + * handle a bigger response, we can either define a max response + * message or add a response buffer variable above this field + */ + struct rndis_message ResponseMessage; + + /* Simplify allocation by having a netvsc packet inline */ + struct hv_netvsc_packet Packet; + struct hv_page_buffer Buffer; + /* FIXME: We assumed a fixed size request here. */ + struct rndis_message RequestMessage; +}; + + +struct rndis_filter_packet { + void *CompletionContext; + void (*OnCompletion)(void *context); + struct rndis_message Message; +}; + + +static int RndisFilterOnDeviceAdd(struct hv_device *Device, + void *AdditionalInfo); + +static int RndisFilterOnDeviceRemove(struct hv_device *Device); + +static void RndisFilterOnCleanup(struct hv_driver *Driver); + +static int RndisFilterOnSend(struct hv_device *Device, + struct hv_netvsc_packet *Packet); + +static void RndisFilterOnSendCompletion(void *Context); + +static void RndisFilterOnSendRequestCompletion(void *Context); + + +/* The one and only */ +static struct rndis_filter_driver_object gRndisFilter; + +static struct rndis_device *GetRndisDevice(void) +{ + struct rndis_device *device; + + device = kzalloc(sizeof(struct rndis_device), GFP_KERNEL); + if (!device) + return NULL; + + spin_lock_init(&device->request_lock); + + INIT_LIST_HEAD(&device->RequestList); + + device->State = RNDIS_DEV_UNINITIALIZED; + + return device; +} + +static struct rndis_request *GetRndisRequest(struct rndis_device *Device, + u32 MessageType, + u32 MessageLength) +{ + struct rndis_request *request; + struct rndis_message *rndisMessage; + struct rndis_set_request *set; + unsigned long flags; + + request = kzalloc(sizeof(struct rndis_request), GFP_KERNEL); + if (!request) + return NULL; + + request->WaitEvent = osd_WaitEventCreate(); + if (!request->WaitEvent) { + kfree(request); + return NULL; + } + + rndisMessage = &request->RequestMessage; + rndisMessage->NdisMessageType = MessageType; + rndisMessage->MessageLength = MessageLength; + + /* + * Set the request id. This field is always after the rndis header for + * request/response packet types so we just used the SetRequest as a + * template + */ + set = &rndisMessage->Message.SetRequest; + set->RequestId = atomic_inc_return(&Device->NewRequestId); + + /* Add to the request list */ + spin_lock_irqsave(&Device->request_lock, flags); + list_add_tail(&request->ListEntry, &Device->RequestList); + spin_unlock_irqrestore(&Device->request_lock, flags); + + return request; +} + +static void PutRndisRequest(struct rndis_device *Device, + struct rndis_request *Request) +{ + unsigned long flags; + + spin_lock_irqsave(&Device->request_lock, flags); + list_del(&Request->ListEntry); + spin_unlock_irqrestore(&Device->request_lock, flags); + + kfree(Request->WaitEvent); + kfree(Request); +} + +static void DumpRndisMessage(struct rndis_message *RndisMessage) +{ + switch (RndisMessage->NdisMessageType) { + case REMOTE_NDIS_PACKET_MSG: + DPRINT_DBG(NETVSC, "REMOTE_NDIS_PACKET_MSG (len %u, " + "data offset %u data len %u, # oob %u, " + "oob offset %u, oob len %u, pkt offset %u, " + "pkt len %u", + RndisMessage->MessageLength, + RndisMessage->Message.Packet.DataOffset, + RndisMessage->Message.Packet.DataLength, + RndisMessage->Message.Packet.NumOOBDataElements, + RndisMessage->Message.Packet.OOBDataOffset, + RndisMessage->Message.Packet.OOBDataLength, + RndisMessage->Message.Packet.PerPacketInfoOffset, + RndisMessage->Message.Packet.PerPacketInfoLength); + break; + + case REMOTE_NDIS_INITIALIZE_CMPLT: + DPRINT_DBG(NETVSC, "REMOTE_NDIS_INITIALIZE_CMPLT " + "(len %u, id 0x%x, status 0x%x, major %d, minor %d, " + "device flags %d, max xfer size 0x%x, max pkts %u, " + "pkt aligned %u)", + RndisMessage->MessageLength, + RndisMessage->Message.InitializeComplete.RequestId, + RndisMessage->Message.InitializeComplete.Status, + RndisMessage->Message.InitializeComplete.MajorVersion, + RndisMessage->Message.InitializeComplete.MinorVersion, + RndisMessage->Message.InitializeComplete.DeviceFlags, + RndisMessage->Message.InitializeComplete.MaxTransferSize, + RndisMessage->Message.InitializeComplete.MaxPacketsPerMessage, + RndisMessage->Message.InitializeComplete.PacketAlignmentFactor); + break; + + case REMOTE_NDIS_QUERY_CMPLT: + DPRINT_DBG(NETVSC, "REMOTE_NDIS_QUERY_CMPLT " + "(len %u, id 0x%x, status 0x%x, buf len %u, " + "buf offset %u)", + RndisMessage->MessageLength, + RndisMessage->Message.QueryComplete.RequestId, + RndisMessage->Message.QueryComplete.Status, + RndisMessage->Message.QueryComplete.InformationBufferLength, + RndisMessage->Message.QueryComplete.InformationBufferOffset); + break; + + case REMOTE_NDIS_SET_CMPLT: + DPRINT_DBG(NETVSC, + "REMOTE_NDIS_SET_CMPLT (len %u, id 0x%x, status 0x%x)", + RndisMessage->MessageLength, + RndisMessage->Message.SetComplete.RequestId, + RndisMessage->Message.SetComplete.Status); + break; + + case REMOTE_NDIS_INDICATE_STATUS_MSG: + DPRINT_DBG(NETVSC, "REMOTE_NDIS_INDICATE_STATUS_MSG " + "(len %u, status 0x%x, buf len %u, buf offset %u)", + RndisMessage->MessageLength, + RndisMessage->Message.IndicateStatus.Status, + RndisMessage->Message.IndicateStatus.StatusBufferLength, + RndisMessage->Message.IndicateStatus.StatusBufferOffset); + break; + + default: + DPRINT_DBG(NETVSC, "0x%x (len %u)", + RndisMessage->NdisMessageType, + RndisMessage->MessageLength); + break; + } +} + +static int RndisFilterSendRequest(struct rndis_device *Device, + struct rndis_request *Request) +{ + int ret; + struct hv_netvsc_packet *packet; + + DPRINT_ENTER(NETVSC); + + /* Setup the packet to send it */ + packet = &Request->Packet; + + packet->IsDataPacket = false; + packet->TotalDataBufferLength = Request->RequestMessage.MessageLength; + packet->PageBufferCount = 1; + + packet->PageBuffers[0].Pfn = virt_to_phys(&Request->RequestMessage) >> + PAGE_SHIFT; + packet->PageBuffers[0].Length = Request->RequestMessage.MessageLength; + packet->PageBuffers[0].Offset = + (unsigned long)&Request->RequestMessage & (PAGE_SIZE - 1); + + packet->Completion.Send.SendCompletionContext = Request;/* packet; */ + packet->Completion.Send.OnSendCompletion = + RndisFilterOnSendRequestCompletion; + packet->Completion.Send.SendCompletionTid = (unsigned long)Device; + + ret = gRndisFilter.InnerDriver.OnSend(Device->NetDevice->Device, packet); + DPRINT_EXIT(NETVSC); + return ret; +} + +static void RndisFilterReceiveResponse(struct rndis_device *Device, + struct rndis_message *Response) +{ + struct rndis_request *request = NULL; + bool found = false; + unsigned long flags; + + DPRINT_ENTER(NETVSC); + + spin_lock_irqsave(&Device->request_lock, flags); + list_for_each_entry(request, &Device->RequestList, ListEntry) { + /* + * All request/response message contains RequestId as the 1st + * field + */ + if (request->RequestMessage.Message.InitializeRequest.RequestId + == Response->Message.InitializeComplete.RequestId) { + DPRINT_DBG(NETVSC, "found rndis request for " + "this response (id 0x%x req type 0x%x res " + "type 0x%x)", + request->RequestMessage.Message.InitializeRequest.RequestId, + request->RequestMessage.NdisMessageType, + Response->NdisMessageType); + + found = true; + break; + } + } + spin_unlock_irqrestore(&Device->request_lock, flags); + + if (found) { + if (Response->MessageLength <= sizeof(struct rndis_message)) { + memcpy(&request->ResponseMessage, Response, + Response->MessageLength); + } else { + DPRINT_ERR(NETVSC, "rndis response buffer overflow " + "detected (size %u max %zu)", + Response->MessageLength, + sizeof(struct rndis_filter_packet)); + + if (Response->NdisMessageType == + REMOTE_NDIS_RESET_CMPLT) { + /* does not have a request id field */ + request->ResponseMessage.Message.ResetComplete.Status = STATUS_BUFFER_OVERFLOW; + } else { + request->ResponseMessage.Message.InitializeComplete.Status = STATUS_BUFFER_OVERFLOW; + } + } + + osd_WaitEventSet(request->WaitEvent); + } else { + DPRINT_ERR(NETVSC, "no rndis request found for this response " + "(id 0x%x res type 0x%x)", + Response->Message.InitializeComplete.RequestId, + Response->NdisMessageType); + } + + DPRINT_EXIT(NETVSC); +} + +static void RndisFilterReceiveIndicateStatus(struct rndis_device *Device, + struct rndis_message *Response) +{ + struct rndis_indicate_status *indicate = + &Response->Message.IndicateStatus; + + if (indicate->Status == RNDIS_STATUS_MEDIA_CONNECT) { + gRndisFilter.InnerDriver.OnLinkStatusChanged(Device->NetDevice->Device, 1); + } else if (indicate->Status == RNDIS_STATUS_MEDIA_DISCONNECT) { + gRndisFilter.InnerDriver.OnLinkStatusChanged(Device->NetDevice->Device, 0); + } else { + /* + * TODO: + */ + } +} + +static void RndisFilterReceiveData(struct rndis_device *Device, + struct rndis_message *Message, + struct hv_netvsc_packet *Packet) +{ + struct rndis_packet *rndisPacket; + u32 dataOffset; + + DPRINT_ENTER(NETVSC); + + /* empty ethernet frame ?? */ + /* ASSERT(Packet->PageBuffers[0].Length > */ + /* RNDIS_MESSAGE_SIZE(struct rndis_packet)); */ + + rndisPacket = &Message->Message.Packet; + + /* + * FIXME: Handle multiple rndis pkt msgs that maybe enclosed in this + * netvsc packet (ie TotalDataBufferLength != MessageLength) + */ + + /* Remove the rndis header and pass it back up the stack */ + dataOffset = RNDIS_HEADER_SIZE + rndisPacket->DataOffset; + + Packet->TotalDataBufferLength -= dataOffset; + Packet->PageBuffers[0].Offset += dataOffset; + Packet->PageBuffers[0].Length -= dataOffset; + + Packet->IsDataPacket = true; + + gRndisFilter.InnerDriver.OnReceiveCallback(Device->NetDevice->Device, + Packet); + + DPRINT_EXIT(NETVSC); +} + +static int RndisFilterOnReceive(struct hv_device *Device, + struct hv_netvsc_packet *Packet) +{ + struct netvsc_device *netDevice = Device->Extension; + struct rndis_device *rndisDevice; + struct rndis_message rndisMessage; + struct rndis_message *rndisHeader; + + DPRINT_ENTER(NETVSC); + + if (!netDevice) + return -EINVAL; + + /* Make sure the rndis device state is initialized */ + if (!netDevice->Extension) { + DPRINT_ERR(NETVSC, "got rndis message but no rndis device..." + "dropping this message!"); + DPRINT_EXIT(NETVSC); + return -1; + } + + rndisDevice = (struct rndis_device *)netDevice->Extension; + if (rndisDevice->State == RNDIS_DEV_UNINITIALIZED) { + DPRINT_ERR(NETVSC, "got rndis message but rndis device " + "uninitialized...dropping this message!"); + DPRINT_EXIT(NETVSC); + return -1; + } + + rndisHeader = (struct rndis_message *)kmap_atomic( + pfn_to_page(Packet->PageBuffers[0].Pfn), KM_IRQ0); + + rndisHeader = (void *)((unsigned long)rndisHeader + + Packet->PageBuffers[0].Offset); + + /* Make sure we got a valid rndis message */ + /* + * FIXME: There seems to be a bug in set completion msg where its + * MessageLength is 16 bytes but the ByteCount field in the xfer page + * range shows 52 bytes + * */ +#if 0 + if (Packet->TotalDataBufferLength != rndisHeader->MessageLength) { + kunmap_atomic(rndisHeader - Packet->PageBuffers[0].Offset, + KM_IRQ0); + + DPRINT_ERR(NETVSC, "invalid rndis message? (expected %u " + "bytes got %u)...dropping this message!", + rndisHeader->MessageLength, + Packet->TotalDataBufferLength); + DPRINT_EXIT(NETVSC); + return -1; + } +#endif + + if ((rndisHeader->NdisMessageType != REMOTE_NDIS_PACKET_MSG) && + (rndisHeader->MessageLength > sizeof(struct rndis_message))) { + DPRINT_ERR(NETVSC, "incoming rndis message buffer overflow " + "detected (got %u, max %zu)...marking it an error!", + rndisHeader->MessageLength, + sizeof(struct rndis_message)); + } + + memcpy(&rndisMessage, rndisHeader, + (rndisHeader->MessageLength > sizeof(struct rndis_message)) ? + sizeof(struct rndis_message) : + rndisHeader->MessageLength); + + kunmap_atomic(rndisHeader - Packet->PageBuffers[0].Offset, KM_IRQ0); + + DumpRndisMessage(&rndisMessage); + + switch (rndisMessage.NdisMessageType) { + case REMOTE_NDIS_PACKET_MSG: + /* data msg */ + RndisFilterReceiveData(rndisDevice, &rndisMessage, Packet); + break; + + case REMOTE_NDIS_INITIALIZE_CMPLT: + case REMOTE_NDIS_QUERY_CMPLT: + case REMOTE_NDIS_SET_CMPLT: + /* case REMOTE_NDIS_RESET_CMPLT: */ + /* case REMOTE_NDIS_KEEPALIVE_CMPLT: */ + /* completion msgs */ + RndisFilterReceiveResponse(rndisDevice, &rndisMessage); + break; + + case REMOTE_NDIS_INDICATE_STATUS_MSG: + /* notification msgs */ + RndisFilterReceiveIndicateStatus(rndisDevice, &rndisMessage); + break; + default: + DPRINT_ERR(NETVSC, "unhandled rndis message (type %u len %u)", + rndisMessage.NdisMessageType, + rndisMessage.MessageLength); + break; + } + + DPRINT_EXIT(NETVSC); + return 0; +} + +static int RndisFilterQueryDevice(struct rndis_device *Device, u32 Oid, + void *Result, u32 *ResultSize) +{ + struct rndis_request *request; + u32 inresultSize = *ResultSize; + struct rndis_query_request *query; + struct rndis_query_complete *queryComplete; + int ret = 0; + + DPRINT_ENTER(NETVSC); + + if (!Result) + return -EINVAL; + + *ResultSize = 0; + request = GetRndisRequest(Device, REMOTE_NDIS_QUERY_MSG, + RNDIS_MESSAGE_SIZE(struct rndis_query_request)); + if (!request) { + ret = -1; + goto Cleanup; + } + + /* Setup the rndis query */ + query = &request->RequestMessage.Message.QueryRequest; + query->Oid = Oid; + query->InformationBufferOffset = sizeof(struct rndis_query_request); + query->InformationBufferLength = 0; + query->DeviceVcHandle = 0; + + ret = RndisFilterSendRequest(Device, request); + if (ret != 0) + goto Cleanup; + + osd_WaitEventWait(request->WaitEvent); + + /* Copy the response back */ + queryComplete = &request->ResponseMessage.Message.QueryComplete; + + if (queryComplete->InformationBufferLength > inresultSize) { + ret = -1; + goto Cleanup; + } + + memcpy(Result, + (void *)((unsigned long)queryComplete + + queryComplete->InformationBufferOffset), + queryComplete->InformationBufferLength); + + *ResultSize = queryComplete->InformationBufferLength; + +Cleanup: + if (request) + PutRndisRequest(Device, request); + DPRINT_EXIT(NETVSC); + + return ret; +} + +static int RndisFilterQueryDeviceMac(struct rndis_device *Device) +{ + u32 size = ETH_ALEN; + + return RndisFilterQueryDevice(Device, + RNDIS_OID_802_3_PERMANENT_ADDRESS, + Device->HwMacAddr, &size); +} + +static int RndisFilterQueryDeviceLinkStatus(struct rndis_device *Device) +{ + u32 size = sizeof(u32); + + return RndisFilterQueryDevice(Device, + RNDIS_OID_GEN_MEDIA_CONNECT_STATUS, + &Device->LinkStatus, &size); +} + +static int RndisFilterSetPacketFilter(struct rndis_device *Device, + u32 NewFilter) +{ + struct rndis_request *request; + struct rndis_set_request *set; + struct rndis_set_complete *setComplete; + u32 status; + int ret; + + DPRINT_ENTER(NETVSC); + + /* ASSERT(RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32) <= */ + /* sizeof(struct rndis_message)); */ + + request = GetRndisRequest(Device, REMOTE_NDIS_SET_MSG, + RNDIS_MESSAGE_SIZE(struct rndis_set_request) + + sizeof(u32)); + if (!request) { + ret = -1; + goto Cleanup; + } + + /* Setup the rndis set */ + set = &request->RequestMessage.Message.SetRequest; + set->Oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER; + set->InformationBufferLength = sizeof(u32); + set->InformationBufferOffset = sizeof(struct rndis_set_request); + + memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request), + &NewFilter, sizeof(u32)); + + ret = RndisFilterSendRequest(Device, request); + if (ret != 0) + goto Cleanup; + + ret = osd_WaitEventWaitEx(request->WaitEvent, 2000/*2sec*/); + if (!ret) { + ret = -1; + DPRINT_ERR(NETVSC, "timeout before we got a set response..."); + /* + * We cant deallocate the request since we may still receive a + * send completion for it. + */ + goto Exit; + } else { + if (ret > 0) + ret = 0; + setComplete = &request->ResponseMessage.Message.SetComplete; + status = setComplete->Status; + } + +Cleanup: + if (request) + PutRndisRequest(Device, request); +Exit: + DPRINT_EXIT(NETVSC); + + return ret; +} + +int RndisFilterInit(struct netvsc_driver *Driver) +{ + DPRINT_ENTER(NETVSC); + + DPRINT_DBG(NETVSC, "sizeof(struct rndis_filter_packet) == %zd", + sizeof(struct rndis_filter_packet)); + + Driver->RequestExtSize = sizeof(struct rndis_filter_packet); + + /* Driver->Context = rndisDriver; */ + + memset(&gRndisFilter, 0, sizeof(struct rndis_filter_driver_object)); + + /*rndisDriver->Driver = Driver; + + ASSERT(Driver->OnLinkStatusChanged); + rndisDriver->OnLinkStatusChanged = Driver->OnLinkStatusChanged;*/ + + /* Save the original dispatch handlers before we override it */ + gRndisFilter.InnerDriver.Base.OnDeviceAdd = Driver->Base.OnDeviceAdd; + gRndisFilter.InnerDriver.Base.OnDeviceRemove = + Driver->Base.OnDeviceRemove; + gRndisFilter.InnerDriver.Base.OnCleanup = Driver->Base.OnCleanup; + + /* ASSERT(Driver->OnSend); */ + /* ASSERT(Driver->OnReceiveCallback); */ + gRndisFilter.InnerDriver.OnSend = Driver->OnSend; + gRndisFilter.InnerDriver.OnReceiveCallback = Driver->OnReceiveCallback; + gRndisFilter.InnerDriver.OnLinkStatusChanged = + Driver->OnLinkStatusChanged; + + /* Override */ + Driver->Base.OnDeviceAdd = RndisFilterOnDeviceAdd; + Driver->Base.OnDeviceRemove = RndisFilterOnDeviceRemove; + Driver->Base.OnCleanup = RndisFilterOnCleanup; + Driver->OnSend = RndisFilterOnSend; + /* Driver->QueryLinkStatus = RndisFilterQueryDeviceLinkStatus; */ + Driver->OnReceiveCallback = RndisFilterOnReceive; + + DPRINT_EXIT(NETVSC); + + return 0; +} + +static int RndisFilterInitDevice(struct rndis_device *Device) +{ + struct rndis_request *request; + struct rndis_initialize_request *init; + struct rndis_initialize_complete *initComplete; + u32 status; + int ret; + + DPRINT_ENTER(NETVSC); + + request = GetRndisRequest(Device, REMOTE_NDIS_INITIALIZE_MSG, + RNDIS_MESSAGE_SIZE(struct rndis_initialize_request)); + if (!request) { + ret = -1; + goto Cleanup; + } + + /* Setup the rndis set */ + init = &request->RequestMessage.Message.InitializeRequest; + init->MajorVersion = RNDIS_MAJOR_VERSION; + init->MinorVersion = RNDIS_MINOR_VERSION; + /* FIXME: Use 1536 - rounded ethernet frame size */ + init->MaxTransferSize = 2048; + + Device->State = RNDIS_DEV_INITIALIZING; + + ret = RndisFilterSendRequest(Device, request); + if (ret != 0) { + Device->State = RNDIS_DEV_UNINITIALIZED; + goto Cleanup; + } + + osd_WaitEventWait(request->WaitEvent); + + initComplete = &request->ResponseMessage.Message.InitializeComplete; + status = initComplete->Status; + if (status == RNDIS_STATUS_SUCCESS) { + Device->State = RNDIS_DEV_INITIALIZED; + ret = 0; + } else { + Device->State = RNDIS_DEV_UNINITIALIZED; + ret = -1; + } + +Cleanup: + if (request) + PutRndisRequest(Device, request); + DPRINT_EXIT(NETVSC); + + return ret; +} + +static void RndisFilterHaltDevice(struct rndis_device *Device) +{ + struct rndis_request *request; + struct rndis_halt_request *halt; + + DPRINT_ENTER(NETVSC); + + /* Attempt to do a rndis device halt */ + request = GetRndisRequest(Device, REMOTE_NDIS_HALT_MSG, + RNDIS_MESSAGE_SIZE(struct rndis_halt_request)); + if (!request) + goto Cleanup; + + /* Setup the rndis set */ + halt = &request->RequestMessage.Message.HaltRequest; + halt->RequestId = atomic_inc_return(&Device->NewRequestId); + + /* Ignore return since this msg is optional. */ + RndisFilterSendRequest(Device, request); + + Device->State = RNDIS_DEV_UNINITIALIZED; + +Cleanup: + if (request) + PutRndisRequest(Device, request); + DPRINT_EXIT(NETVSC); + return; +} + +static int RndisFilterOpenDevice(struct rndis_device *Device) +{ + int ret; + + DPRINT_ENTER(NETVSC); + + if (Device->State != RNDIS_DEV_INITIALIZED) + return 0; + + ret = RndisFilterSetPacketFilter(Device, + NDIS_PACKET_TYPE_BROADCAST | + NDIS_PACKET_TYPE_DIRECTED); + if (ret == 0) + Device->State = RNDIS_DEV_DATAINITIALIZED; + + DPRINT_EXIT(NETVSC); + return ret; +} + +static int RndisFilterCloseDevice(struct rndis_device *Device) +{ + int ret; + + DPRINT_ENTER(NETVSC); + + if (Device->State != RNDIS_DEV_DATAINITIALIZED) + return 0; + + ret = RndisFilterSetPacketFilter(Device, 0); + if (ret == 0) + Device->State = RNDIS_DEV_INITIALIZED; + + DPRINT_EXIT(NETVSC); + + return ret; +} + +static int RndisFilterOnDeviceAdd(struct hv_device *Device, + void *AdditionalInfo) +{ + int ret; + struct netvsc_device *netDevice; + struct rndis_device *rndisDevice; + struct netvsc_device_info *deviceInfo = AdditionalInfo; + + DPRINT_ENTER(NETVSC); + + rndisDevice = GetRndisDevice(); + if (!rndisDevice) { + DPRINT_EXIT(NETVSC); + return -1; + } + + DPRINT_DBG(NETVSC, "rndis device object allocated - %p", rndisDevice); + + /* + * Let the inner driver handle this first to create the netvsc channel + * NOTE! Once the channel is created, we may get a receive callback + * (RndisFilterOnReceive()) before this call is completed + */ + ret = gRndisFilter.InnerDriver.Base.OnDeviceAdd(Device, AdditionalInfo); + if (ret != 0) { + kfree(rndisDevice); + DPRINT_EXIT(NETVSC); + return ret; + } + + + /* Initialize the rndis device */ + netDevice = Device->Extension; + /* ASSERT(netDevice); */ + /* ASSERT(netDevice->Device); */ + + netDevice->Extension = rndisDevice; + rndisDevice->NetDevice = netDevice; + + /* Send the rndis initialization message */ + ret = RndisFilterInitDevice(rndisDevice); + if (ret != 0) { + /* + * TODO: If rndis init failed, we will need to shut down the + * channel + */ + } + + /* Get the mac address */ + ret = RndisFilterQueryDeviceMac(rndisDevice); + if (ret != 0) { + /* + * TODO: shutdown rndis device and the channel + */ + } + + DPRINT_INFO(NETVSC, "Device 0x%p mac addr %pM", + rndisDevice, rndisDevice->HwMacAddr); + + memcpy(deviceInfo->MacAddr, rndisDevice->HwMacAddr, ETH_ALEN); + + RndisFilterQueryDeviceLinkStatus(rndisDevice); + + deviceInfo->LinkState = rndisDevice->LinkStatus; + DPRINT_INFO(NETVSC, "Device 0x%p link state %s", rndisDevice, + ((deviceInfo->LinkState) ? ("down") : ("up"))); + + DPRINT_EXIT(NETVSC); + + return ret; +} + +static int RndisFilterOnDeviceRemove(struct hv_device *Device) +{ + struct netvsc_device *netDevice = Device->Extension; + struct rndis_device *rndisDevice = netDevice->Extension; + + DPRINT_ENTER(NETVSC); + + /* Halt and release the rndis device */ + RndisFilterHaltDevice(rndisDevice); + + kfree(rndisDevice); + netDevice->Extension = NULL; + + /* Pass control to inner driver to remove the device */ + gRndisFilter.InnerDriver.Base.OnDeviceRemove(Device); + + DPRINT_EXIT(NETVSC); + + return 0; +} + +static void RndisFilterOnCleanup(struct hv_driver *Driver) +{ + DPRINT_ENTER(NETVSC); + + DPRINT_EXIT(NETVSC); +} + +int RndisFilterOnOpen(struct hv_device *Device) +{ + int ret; + struct netvsc_device *netDevice = Device->Extension; + + DPRINT_ENTER(NETVSC); + + if (!netDevice) + return -EINVAL; + + ret = RndisFilterOpenDevice(netDevice->Extension); + + DPRINT_EXIT(NETVSC); + + return ret; +} + +int RndisFilterOnClose(struct hv_device *Device) +{ + int ret; + struct netvsc_device *netDevice = Device->Extension; + + DPRINT_ENTER(NETVSC); + + if (!netDevice) + return -EINVAL; + + ret = RndisFilterCloseDevice(netDevice->Extension); + + DPRINT_EXIT(NETVSC); + + return ret; +} + +static int RndisFilterOnSend(struct hv_device *Device, + struct hv_netvsc_packet *Packet) +{ + int ret; + struct rndis_filter_packet *filterPacket; + struct rndis_message *rndisMessage; + struct rndis_packet *rndisPacket; + u32 rndisMessageSize; + + DPRINT_ENTER(NETVSC); + + /* Add the rndis header */ + filterPacket = (struct rndis_filter_packet *)Packet->Extension; + /* ASSERT(filterPacket); */ + + memset(filterPacket, 0, sizeof(struct rndis_filter_packet)); + + rndisMessage = &filterPacket->Message; + rndisMessageSize = RNDIS_MESSAGE_SIZE(struct rndis_packet); + + rndisMessage->NdisMessageType = REMOTE_NDIS_PACKET_MSG; + rndisMessage->MessageLength = Packet->TotalDataBufferLength + + rndisMessageSize; + + rndisPacket = &rndisMessage->Message.Packet; + rndisPacket->DataOffset = sizeof(struct rndis_packet); + rndisPacket->DataLength = Packet->TotalDataBufferLength; + + Packet->IsDataPacket = true; + Packet->PageBuffers[0].Pfn = virt_to_phys(rndisMessage) >> PAGE_SHIFT; + Packet->PageBuffers[0].Offset = + (unsigned long)rndisMessage & (PAGE_SIZE-1); + Packet->PageBuffers[0].Length = rndisMessageSize; + + /* Save the packet send completion and context */ + filterPacket->OnCompletion = Packet->Completion.Send.OnSendCompletion; + filterPacket->CompletionContext = + Packet->Completion.Send.SendCompletionContext; + + /* Use ours */ + Packet->Completion.Send.OnSendCompletion = RndisFilterOnSendCompletion; + Packet->Completion.Send.SendCompletionContext = filterPacket; + + ret = gRndisFilter.InnerDriver.OnSend(Device, Packet); + if (ret != 0) { + /* + * Reset the completion to originals to allow retries from + * above + */ + Packet->Completion.Send.OnSendCompletion = + filterPacket->OnCompletion; + Packet->Completion.Send.SendCompletionContext = + filterPacket->CompletionContext; + } + + DPRINT_EXIT(NETVSC); + + return ret; +} + +static void RndisFilterOnSendCompletion(void *Context) +{ + struct rndis_filter_packet *filterPacket = Context; + + DPRINT_ENTER(NETVSC); + + /* Pass it back to the original handler */ + filterPacket->OnCompletion(filterPacket->CompletionContext); + + DPRINT_EXIT(NETVSC); +} + + +static void RndisFilterOnSendRequestCompletion(void *Context) +{ + DPRINT_ENTER(NETVSC); + + /* Noop */ + DPRINT_EXIT(NETVSC); +} diff --git a/drivers/staging/hv/rndis_filter.h b/drivers/staging/hv/rndis_filter.h new file mode 100644 index 000000000000..764b9bf3e5dc --- /dev/null +++ b/drivers/staging/hv/rndis_filter.h @@ -0,0 +1,55 @@ +/* + * + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + * + */ + + +#ifndef _RNDISFILTER_H_ +#define _RNDISFILTER_H_ + +#define __struct_bcount(x) + +#include "netvsc.h" + +#include "rndis.h" + +#define RNDIS_HEADER_SIZE (sizeof(struct rndis_message) - \ + sizeof(union rndis_message_container)) + +#define NDIS_PACKET_TYPE_DIRECTED 0x00000001 +#define NDIS_PACKET_TYPE_MULTICAST 0x00000002 +#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004 +#define NDIS_PACKET_TYPE_BROADCAST 0x00000008 +#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010 +#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020 +#define NDIS_PACKET_TYPE_SMT 0x00000040 +#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080 +#define NDIS_PACKET_TYPE_GROUP 0x00000100 +#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00000200 +#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00000400 +#define NDIS_PACKET_TYPE_MAC_FRAME 0x00000800 + + +/* Interface */ + +extern int RndisFilterInit(struct netvsc_driver *driver); + +#endif /* _RNDISFILTER_H_ */ -- cgit v1.2.3 From ff39524bc463e63003d824d4106eda83762d648b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:34:18 -0700 Subject: Staging: hv: rename ChannelMgmt.c and .h to channel_mgmt.c and .h Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/ChannelMgmt.c | 856 -------------------------------------- drivers/staging/hv/ChannelMgmt.h | 320 -------------- drivers/staging/hv/Makefile | 2 +- drivers/staging/hv/VmbusPrivate.h | 2 +- drivers/staging/hv/channel.h | 2 +- drivers/staging/hv/channel_mgmt.c | 856 ++++++++++++++++++++++++++++++++++++++ drivers/staging/hv/channel_mgmt.h | 320 ++++++++++++++ 7 files changed, 1179 insertions(+), 1179 deletions(-) delete mode 100644 drivers/staging/hv/ChannelMgmt.c delete mode 100644 drivers/staging/hv/ChannelMgmt.h create mode 100644 drivers/staging/hv/channel_mgmt.c create mode 100644 drivers/staging/hv/channel_mgmt.h (limited to 'drivers') diff --git a/drivers/staging/hv/ChannelMgmt.c b/drivers/staging/hv/ChannelMgmt.c deleted file mode 100644 index 369823013889..000000000000 --- a/drivers/staging/hv/ChannelMgmt.c +++ /dev/null @@ -1,856 +0,0 @@ -/* - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - */ -#include -#include -#include -#include -#include -#include "osd.h" -#include "logging.h" -#include "VmbusPrivate.h" -#include "utils.h" - -struct vmbus_channel_message_table_entry { - enum vmbus_channel_message_type messageType; - void (*messageHandler)(struct vmbus_channel_message_header *msg); -}; - -#define MAX_MSG_TYPES 2 -#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 6 - -static const struct hv_guid - gSupportedDeviceClasses[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = { - /* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ - /* Storage - SCSI */ - { - .data = { - 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, - 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f - } - }, - - /* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */ - /* Network */ - { - .data = { - 0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, - 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E - } - }, - - /* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */ - /* Input */ - { - .data = { - 0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c, - 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A - } - }, - - /* {32412632-86cb-44a2-9b5c-50d1417354f5} */ - /* IDE */ - { - .data = { - 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, - 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 - } - }, - /* 0E0B6031-5213-4934-818B-38D90CED39DB */ - /* Shutdown */ - { - .data = { - 0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49, - 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB - } - }, - /* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */ - /* TimeSync */ - { - .data = { - 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, - 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf - } - }, -}; - - -/** - * prep_negotiate_resp() - Create default response for Hyper-V Negotiate message - * @icmsghdrp: Pointer to msg header structure - * @icmsg_negotiate: Pointer to negotiate message structure - * @buf: Raw buffer channel data - * - * @icmsghdrp is of type &struct icmsg_hdr. - * @negop is of type &struct icmsg_negotiate. - * Set up and fill in default negotiate response message. This response can - * come from both the vmbus driver and the hv_utils driver. The current api - * will respond properly to both Windows 2008 and Windows 2008-R2 operating - * systems. - * - * Mainly used by Hyper-V drivers. - */ -void prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, - struct icmsg_negotiate *negop, - u8 *buf) -{ - if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { - icmsghdrp->icmsgsize = 0x10; - - negop = (struct icmsg_negotiate *)&buf[ - sizeof(struct vmbuspipe_hdr) + - sizeof(struct icmsg_hdr)]; - - if (negop->icframe_vercnt == 2 && - negop->icversion_data[1].major == 3) { - negop->icversion_data[0].major = 3; - negop->icversion_data[0].minor = 0; - negop->icversion_data[1].major = 3; - negop->icversion_data[1].minor = 0; - } else { - negop->icversion_data[0].major = 1; - negop->icversion_data[0].minor = 0; - negop->icversion_data[1].major = 1; - negop->icversion_data[1].minor = 0; - } - - negop->icframe_vercnt = 1; - negop->icmsg_vercnt = 1; - } -} -EXPORT_SYMBOL(prep_negotiate_resp); - -/** - * chn_cb_negotiate() - Default handler for non IDE/SCSI/NETWORK - * Hyper-V requests - * @context: Pointer to argument structure. - * - * Set up the default handler for non device driver specific requests - * from Hyper-V. This stub responds to the default negotiate messages - * that come in for every non IDE/SCSI/Network request. - * This behavior is normally overwritten in the hv_utils driver. That - * driver handles requests like gracefull shutdown, heartbeats etc. - * - * Mainly used by Hyper-V drivers. - */ -void chn_cb_negotiate(void *context) -{ - struct vmbus_channel *channel = context; - u8 *buf; - u32 buflen, recvlen; - u64 requestid; - - struct icmsg_hdr *icmsghdrp; - struct icmsg_negotiate *negop = NULL; - - buflen = PAGE_SIZE; - buf = kmalloc(buflen, GFP_ATOMIC); - - VmbusChannelRecvPacket(channel, buf, buflen, &recvlen, &requestid); - - if (recvlen > 0) { - icmsghdrp = (struct icmsg_hdr *)&buf[ - sizeof(struct vmbuspipe_hdr)]; - - prep_negotiate_resp(icmsghdrp, negop, buf); - - icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION - | ICMSGHDRFLAG_RESPONSE; - - VmbusChannelSendPacket(channel, buf, - recvlen, requestid, - VmbusPacketTypeDataInBand, 0); - } - - kfree(buf); -} -EXPORT_SYMBOL(chn_cb_negotiate); - -/* - * Function table used for message responses for non IDE/SCSI/Network type - * messages. (Such as KVP/Shutdown etc) - */ -struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = { - /* 0E0B6031-5213-4934-818B-38D90CED39DB */ - /* Shutdown */ - { - .msg_type = HV_SHUTDOWN_MSG, - .data = { - 0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49, - 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB - }, - .callback = chn_cb_negotiate, - .log_msg = "Shutdown channel functionality initialized" - }, - - /* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */ - /* TimeSync */ - { - .msg_type = HV_TIMESYNC_MSG, - .data = { - 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, - 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf - }, - .callback = chn_cb_negotiate, - .log_msg = "Timesync channel functionality initialized" - }, -}; -EXPORT_SYMBOL(hv_cb_utils); - -/* - * AllocVmbusChannel - Allocate and initialize a vmbus channel object - */ -struct vmbus_channel *AllocVmbusChannel(void) -{ - struct vmbus_channel *channel; - - channel = kzalloc(sizeof(*channel), GFP_ATOMIC); - if (!channel) - return NULL; - - spin_lock_init(&channel->inbound_lock); - - init_timer(&channel->poll_timer); - channel->poll_timer.data = (unsigned long)channel; - channel->poll_timer.function = VmbusChannelOnTimer; - - channel->ControlWQ = create_workqueue("hv_vmbus_ctl"); - if (!channel->ControlWQ) { - kfree(channel); - return NULL; - } - - return channel; -} - -/* - * ReleaseVmbusChannel - Release the vmbus channel object itself - */ -static inline void ReleaseVmbusChannel(void *context) -{ - struct vmbus_channel *channel = context; - - DPRINT_ENTER(VMBUS); - - DPRINT_DBG(VMBUS, "releasing channel (%p)", channel); - destroy_workqueue(channel->ControlWQ); - DPRINT_DBG(VMBUS, "channel released (%p)", channel); - - kfree(channel); - - DPRINT_EXIT(VMBUS); -} - -/* - * FreeVmbusChannel - Release the resources used by the vmbus channel object - */ -void FreeVmbusChannel(struct vmbus_channel *Channel) -{ - del_timer_sync(&Channel->poll_timer); - - /* - * We have to release the channel's workqueue/thread in the vmbus's - * workqueue/thread context - * ie we can't destroy ourselves. - */ - osd_schedule_callback(gVmbusConnection.WorkQueue, ReleaseVmbusChannel, - Channel); -} - -/* - * VmbusChannelProcessOffer - Process the offer by creating a channel/device - * associated with this offer - */ -static void VmbusChannelProcessOffer(void *context) -{ - struct vmbus_channel *newChannel = context; - struct vmbus_channel *channel; - bool fNew = true; - int ret; - int cnt; - unsigned long flags; - - DPRINT_ENTER(VMBUS); - - /* Make sure this is a new offer */ - spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); - - list_for_each_entry(channel, &gVmbusConnection.ChannelList, ListEntry) { - if (!memcmp(&channel->OfferMsg.Offer.InterfaceType, - &newChannel->OfferMsg.Offer.InterfaceType, - sizeof(struct hv_guid)) && - !memcmp(&channel->OfferMsg.Offer.InterfaceInstance, - &newChannel->OfferMsg.Offer.InterfaceInstance, - sizeof(struct hv_guid))) { - fNew = false; - break; - } - } - - if (fNew) - list_add_tail(&newChannel->ListEntry, - &gVmbusConnection.ChannelList); - - spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); - - if (!fNew) { - DPRINT_DBG(VMBUS, "Ignoring duplicate offer for relid (%d)", - newChannel->OfferMsg.ChildRelId); - FreeVmbusChannel(newChannel); - DPRINT_EXIT(VMBUS); - return; - } - - /* - * Start the process of binding this offer to the driver - * We need to set the DeviceObject field before calling - * VmbusChildDeviceAdd() - */ - newChannel->DeviceObject = VmbusChildDeviceCreate( - &newChannel->OfferMsg.Offer.InterfaceType, - &newChannel->OfferMsg.Offer.InterfaceInstance, - newChannel); - - DPRINT_DBG(VMBUS, "child device object allocated - %p", - newChannel->DeviceObject); - - /* - * Add the new device to the bus. This will kick off device-driver - * binding which eventually invokes the device driver's AddDevice() - * method. - */ - ret = VmbusChildDeviceAdd(newChannel->DeviceObject); - if (ret != 0) { - DPRINT_ERR(VMBUS, - "unable to add child device object (relid %d)", - newChannel->OfferMsg.ChildRelId); - - spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); - list_del(&newChannel->ListEntry); - spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); - - FreeVmbusChannel(newChannel); - } else { - /* - * This state is used to indicate a successful open - * so that when we do close the channel normally, we - * can cleanup properly - */ - newChannel->State = CHANNEL_OPEN_STATE; - cnt = 0; - - while (cnt != MAX_MSG_TYPES) { - if (memcmp(&newChannel->OfferMsg.Offer.InterfaceType, - &hv_cb_utils[cnt].data, - sizeof(struct hv_guid)) == 0) { - DPRINT_INFO(VMBUS, "%s", - hv_cb_utils[cnt].log_msg); - - if (VmbusChannelOpen(newChannel, 2 * PAGE_SIZE, - 2 * PAGE_SIZE, NULL, 0, - hv_cb_utils[cnt].callback, - newChannel) == 0) - hv_cb_utils[cnt].channel = newChannel; - } - cnt++; - } - } - DPRINT_EXIT(VMBUS); -} - -/* - * VmbusChannelProcessRescindOffer - Rescind the offer by initiating a device removal - */ -static void VmbusChannelProcessRescindOffer(void *context) -{ - struct vmbus_channel *channel = context; - - DPRINT_ENTER(VMBUS); - VmbusChildDeviceRemove(channel->DeviceObject); - DPRINT_EXIT(VMBUS); -} - -/* - * VmbusChannelOnOffer - Handler for channel offers from vmbus in parent partition. - * - * We ignore all offers except network and storage offers. For each network and - * storage offers, we create a channel object and queue a work item to the - * channel object to process the offer synchronously - */ -static void VmbusChannelOnOffer(struct vmbus_channel_message_header *hdr) -{ - struct vmbus_channel_offer_channel *offer; - struct vmbus_channel *newChannel; - struct hv_guid *guidType; - struct hv_guid *guidInstance; - int i; - int fSupported = 0; - - DPRINT_ENTER(VMBUS); - - offer = (struct vmbus_channel_offer_channel *)hdr; - for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) { - if (memcmp(&offer->Offer.InterfaceType, - &gSupportedDeviceClasses[i], sizeof(struct hv_guid)) == 0) { - fSupported = 1; - break; - } - } - - if (!fSupported) { - DPRINT_DBG(VMBUS, "Ignoring channel offer notification for " - "child relid %d", offer->ChildRelId); - DPRINT_EXIT(VMBUS); - return; - } - - guidType = &offer->Offer.InterfaceType; - guidInstance = &offer->Offer.InterfaceInstance; - - DPRINT_INFO(VMBUS, "Channel offer notification - " - "child relid %d monitor id %d allocated %d, " - "type {%02x%02x%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x%02x%02x%02x%02x%02x%02x} " - "instance {%02x%02x%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x%02x%02x%02x%02x%02x%02x}", - offer->ChildRelId, offer->MonitorId, - offer->MonitorAllocated, - guidType->data[3], guidType->data[2], - guidType->data[1], guidType->data[0], - guidType->data[5], guidType->data[4], - guidType->data[7], guidType->data[6], - guidType->data[8], guidType->data[9], - guidType->data[10], guidType->data[11], - guidType->data[12], guidType->data[13], - guidType->data[14], guidType->data[15], - guidInstance->data[3], guidInstance->data[2], - guidInstance->data[1], guidInstance->data[0], - guidInstance->data[5], guidInstance->data[4], - guidInstance->data[7], guidInstance->data[6], - guidInstance->data[8], guidInstance->data[9], - guidInstance->data[10], guidInstance->data[11], - guidInstance->data[12], guidInstance->data[13], - guidInstance->data[14], guidInstance->data[15]); - - /* Allocate the channel object and save this offer. */ - newChannel = AllocVmbusChannel(); - if (!newChannel) { - DPRINT_ERR(VMBUS, "unable to allocate channel object"); - return; - } - - DPRINT_DBG(VMBUS, "channel object allocated - %p", newChannel); - - memcpy(&newChannel->OfferMsg, offer, - sizeof(struct vmbus_channel_offer_channel)); - newChannel->MonitorGroup = (u8)offer->MonitorId / 32; - newChannel->MonitorBit = (u8)offer->MonitorId % 32; - - /* TODO: Make sure the offer comes from our parent partition */ - osd_schedule_callback(newChannel->ControlWQ, VmbusChannelProcessOffer, - newChannel); - - DPRINT_EXIT(VMBUS); -} - -/* - * VmbusChannelOnOfferRescind - Rescind offer handler. - * - * We queue a work item to process this offer synchronously - */ -static void VmbusChannelOnOfferRescind(struct vmbus_channel_message_header *hdr) -{ - struct vmbus_channel_rescind_offer *rescind; - struct vmbus_channel *channel; - - DPRINT_ENTER(VMBUS); - - rescind = (struct vmbus_channel_rescind_offer *)hdr; - channel = GetChannelFromRelId(rescind->ChildRelId); - if (channel == NULL) { - DPRINT_DBG(VMBUS, "channel not found for relId %d", - rescind->ChildRelId); - return; - } - - osd_schedule_callback(channel->ControlWQ, - VmbusChannelProcessRescindOffer, - channel); - - DPRINT_EXIT(VMBUS); -} - -/* - * VmbusChannelOnOffersDelivered - This is invoked when all offers have been delivered. - * - * Nothing to do here. - */ -static void VmbusChannelOnOffersDelivered( - struct vmbus_channel_message_header *hdr) -{ - DPRINT_ENTER(VMBUS); - DPRINT_EXIT(VMBUS); -} - -/* - * VmbusChannelOnOpenResult - Open result handler. - * - * This is invoked when we received a response to our channel open request. - * Find the matching request, copy the response and signal the requesting - * thread. - */ -static void VmbusChannelOnOpenResult(struct vmbus_channel_message_header *hdr) -{ - struct vmbus_channel_open_result *result; - struct list_head *curr; - struct vmbus_channel_msginfo *msgInfo; - struct vmbus_channel_message_header *requestHeader; - struct vmbus_channel_open_channel *openMsg; - unsigned long flags; - - DPRINT_ENTER(VMBUS); - - result = (struct vmbus_channel_open_result *)hdr; - DPRINT_DBG(VMBUS, "vmbus open result - %d", result->Status); - - /* - * Find the open msg, copy the result and signal/unblock the wait event - */ - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); - - list_for_each(curr, &gVmbusConnection.ChannelMsgList) { -/* FIXME: this should probably use list_entry() instead */ - msgInfo = (struct vmbus_channel_msginfo *)curr; - requestHeader = (struct vmbus_channel_message_header *)msgInfo->Msg; - - if (requestHeader->MessageType == ChannelMessageOpenChannel) { - openMsg = (struct vmbus_channel_open_channel *)msgInfo->Msg; - if (openMsg->ChildRelId == result->ChildRelId && - openMsg->OpenId == result->OpenId) { - memcpy(&msgInfo->Response.OpenResult, - result, - sizeof(struct vmbus_channel_open_result)); - osd_WaitEventSet(msgInfo->WaitEvent); - break; - } - } - } - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); - - DPRINT_EXIT(VMBUS); -} - -/* - * VmbusChannelOnGpadlCreated - GPADL created handler. - * - * This is invoked when we received a response to our gpadl create request. - * Find the matching request, copy the response and signal the requesting - * thread. - */ -static void VmbusChannelOnGpadlCreated(struct vmbus_channel_message_header *hdr) -{ - struct vmbus_channel_gpadl_created *gpadlCreated; - struct list_head *curr; - struct vmbus_channel_msginfo *msgInfo; - struct vmbus_channel_message_header *requestHeader; - struct vmbus_channel_gpadl_header *gpadlHeader; - unsigned long flags; - - DPRINT_ENTER(VMBUS); - - gpadlCreated = (struct vmbus_channel_gpadl_created *)hdr; - DPRINT_DBG(VMBUS, "vmbus gpadl created result - %d", - gpadlCreated->CreationStatus); - - /* - * Find the establish msg, copy the result and signal/unblock the wait - * event - */ - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); - - list_for_each(curr, &gVmbusConnection.ChannelMsgList) { -/* FIXME: this should probably use list_entry() instead */ - msgInfo = (struct vmbus_channel_msginfo *)curr; - requestHeader = (struct vmbus_channel_message_header *)msgInfo->Msg; - - if (requestHeader->MessageType == ChannelMessageGpadlHeader) { - gpadlHeader = (struct vmbus_channel_gpadl_header *)requestHeader; - - if ((gpadlCreated->ChildRelId == - gpadlHeader->ChildRelId) && - (gpadlCreated->Gpadl == gpadlHeader->Gpadl)) { - memcpy(&msgInfo->Response.GpadlCreated, - gpadlCreated, - sizeof(struct vmbus_channel_gpadl_created)); - osd_WaitEventSet(msgInfo->WaitEvent); - break; - } - } - } - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); - - DPRINT_EXIT(VMBUS); -} - -/* - * VmbusChannelOnGpadlTorndown - GPADL torndown handler. - * - * This is invoked when we received a response to our gpadl teardown request. - * Find the matching request, copy the response and signal the requesting - * thread. - */ -static void VmbusChannelOnGpadlTorndown( - struct vmbus_channel_message_header *hdr) -{ - struct vmbus_channel_gpadl_torndown *gpadlTorndown; - struct list_head *curr; - struct vmbus_channel_msginfo *msgInfo; - struct vmbus_channel_message_header *requestHeader; - struct vmbus_channel_gpadl_teardown *gpadlTeardown; - unsigned long flags; - - DPRINT_ENTER(VMBUS); - - gpadlTorndown = (struct vmbus_channel_gpadl_torndown *)hdr; - - /* - * Find the open msg, copy the result and signal/unblock the wait event - */ - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); - - list_for_each(curr, &gVmbusConnection.ChannelMsgList) { -/* FIXME: this should probably use list_entry() instead */ - msgInfo = (struct vmbus_channel_msginfo *)curr; - requestHeader = (struct vmbus_channel_message_header *)msgInfo->Msg; - - if (requestHeader->MessageType == ChannelMessageGpadlTeardown) { - gpadlTeardown = (struct vmbus_channel_gpadl_teardown *)requestHeader; - - if (gpadlTorndown->Gpadl == gpadlTeardown->Gpadl) { - memcpy(&msgInfo->Response.GpadlTorndown, - gpadlTorndown, - sizeof(struct vmbus_channel_gpadl_torndown)); - osd_WaitEventSet(msgInfo->WaitEvent); - break; - } - } - } - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); - - DPRINT_EXIT(VMBUS); -} - -/* - * VmbusChannelOnVersionResponse - Version response handler - * - * This is invoked when we received a response to our initiate contact request. - * Find the matching request, copy the response and signal the requesting - * thread. - */ -static void VmbusChannelOnVersionResponse( - struct vmbus_channel_message_header *hdr) -{ - struct list_head *curr; - struct vmbus_channel_msginfo *msgInfo; - struct vmbus_channel_message_header *requestHeader; - struct vmbus_channel_initiate_contact *initiate; - struct vmbus_channel_version_response *versionResponse; - unsigned long flags; - - DPRINT_ENTER(VMBUS); - - versionResponse = (struct vmbus_channel_version_response *)hdr; - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); - - list_for_each(curr, &gVmbusConnection.ChannelMsgList) { -/* FIXME: this should probably use list_entry() instead */ - msgInfo = (struct vmbus_channel_msginfo *)curr; - requestHeader = (struct vmbus_channel_message_header *)msgInfo->Msg; - - if (requestHeader->MessageType == - ChannelMessageInitiateContact) { - initiate = (struct vmbus_channel_initiate_contact *)requestHeader; - memcpy(&msgInfo->Response.VersionResponse, - versionResponse, - sizeof(struct vmbus_channel_version_response)); - osd_WaitEventSet(msgInfo->WaitEvent); - } - } - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); - - DPRINT_EXIT(VMBUS); -} - -/* Channel message dispatch table */ -static struct vmbus_channel_message_table_entry - gChannelMessageTable[ChannelMessageCount] = { - {ChannelMessageInvalid, NULL}, - {ChannelMessageOfferChannel, VmbusChannelOnOffer}, - {ChannelMessageRescindChannelOffer, VmbusChannelOnOfferRescind}, - {ChannelMessageRequestOffers, NULL}, - {ChannelMessageAllOffersDelivered, VmbusChannelOnOffersDelivered}, - {ChannelMessageOpenChannel, NULL}, - {ChannelMessageOpenChannelResult, VmbusChannelOnOpenResult}, - {ChannelMessageCloseChannel, NULL}, - {ChannelMessageGpadlHeader, NULL}, - {ChannelMessageGpadlBody, NULL}, - {ChannelMessageGpadlCreated, VmbusChannelOnGpadlCreated}, - {ChannelMessageGpadlTeardown, NULL}, - {ChannelMessageGpadlTorndown, VmbusChannelOnGpadlTorndown}, - {ChannelMessageRelIdReleased, NULL}, - {ChannelMessageInitiateContact, NULL}, - {ChannelMessageVersionResponse, VmbusChannelOnVersionResponse}, - {ChannelMessageUnload, NULL}, -}; - -/* - * VmbusOnChannelMessage - Handler for channel protocol messages. - * - * This is invoked in the vmbus worker thread context. - */ -void VmbusOnChannelMessage(void *Context) -{ - struct hv_message *msg = Context; - struct vmbus_channel_message_header *hdr; - int size; - - DPRINT_ENTER(VMBUS); - - hdr = (struct vmbus_channel_message_header *)msg->u.Payload; - size = msg->Header.PayloadSize; - - DPRINT_DBG(VMBUS, "message type %d size %d", hdr->MessageType, size); - - if (hdr->MessageType >= ChannelMessageCount) { - DPRINT_ERR(VMBUS, - "Received invalid channel message type %d size %d", - hdr->MessageType, size); - print_hex_dump_bytes("", DUMP_PREFIX_NONE, - (unsigned char *)msg->u.Payload, size); - kfree(msg); - return; - } - - if (gChannelMessageTable[hdr->MessageType].messageHandler) - gChannelMessageTable[hdr->MessageType].messageHandler(hdr); - else - DPRINT_ERR(VMBUS, "Unhandled channel message type %d", - hdr->MessageType); - - /* Free the msg that was allocated in VmbusOnMsgDPC() */ - kfree(msg); - DPRINT_EXIT(VMBUS); -} - -/* - * VmbusChannelRequestOffers - Send a request to get all our pending offers. - */ -int VmbusChannelRequestOffers(void) -{ - struct vmbus_channel_message_header *msg; - struct vmbus_channel_msginfo *msgInfo; - int ret; - - DPRINT_ENTER(VMBUS); - - msgInfo = kmalloc(sizeof(*msgInfo) + - sizeof(struct vmbus_channel_message_header), - GFP_KERNEL); - if (!msgInfo) - return -ENOMEM; - - msgInfo->WaitEvent = osd_WaitEventCreate(); - if (!msgInfo->WaitEvent) { - kfree(msgInfo); - return -ENOMEM; - } - - msg = (struct vmbus_channel_message_header *)msgInfo->Msg; - - msg->MessageType = ChannelMessageRequestOffers; - - /*SpinlockAcquire(gVmbusConnection.channelMsgLock); - INSERT_TAIL_LIST(&gVmbusConnection.channelMsgList, - &msgInfo->msgListEntry); - SpinlockRelease(gVmbusConnection.channelMsgLock);*/ - - ret = VmbusPostMessage(msg, - sizeof(struct vmbus_channel_message_header)); - if (ret != 0) { - DPRINT_ERR(VMBUS, "Unable to request offers - %d", ret); - - /*SpinlockAcquire(gVmbusConnection.channelMsgLock); - REMOVE_ENTRY_LIST(&msgInfo->msgListEntry); - SpinlockRelease(gVmbusConnection.channelMsgLock);*/ - - goto Cleanup; - } - /* osd_WaitEventWait(msgInfo->waitEvent); */ - - /*SpinlockAcquire(gVmbusConnection.channelMsgLock); - REMOVE_ENTRY_LIST(&msgInfo->msgListEntry); - SpinlockRelease(gVmbusConnection.channelMsgLock);*/ - - -Cleanup: - if (msgInfo) { - kfree(msgInfo->WaitEvent); - kfree(msgInfo); - } - - DPRINT_EXIT(VMBUS); - return ret; -} - -/* - * VmbusChannelReleaseUnattachedChannels - Release channels that are - * unattached/unconnected ie (no drivers associated) - */ -void VmbusChannelReleaseUnattachedChannels(void) -{ - struct vmbus_channel *channel, *pos; - struct vmbus_channel *start = NULL; - unsigned long flags; - - spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); - - list_for_each_entry_safe(channel, pos, &gVmbusConnection.ChannelList, - ListEntry) { - if (channel == start) - break; - - if (!channel->DeviceObject->Driver) { - list_del(&channel->ListEntry); - DPRINT_INFO(VMBUS, - "Releasing unattached device object %p", - channel->DeviceObject); - - VmbusChildDeviceRemove(channel->DeviceObject); - FreeVmbusChannel(channel); - } else { - if (!start) - start = channel; - } - } - - spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); -} - -/* eof */ diff --git a/drivers/staging/hv/ChannelMgmt.h b/drivers/staging/hv/ChannelMgmt.h deleted file mode 100644 index 9219199d0e5a..000000000000 --- a/drivers/staging/hv/ChannelMgmt.h +++ /dev/null @@ -1,320 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ - - -#ifndef _CHANNEL_MGMT_H_ -#define _CHANNEL_MGMT_H_ - -#include -#include -#include "ring_buffer.h" -#include "VmbusChannelInterface.h" -#include "VmbusPacketFormat.h" - -/* Version 1 messages */ -enum vmbus_channel_message_type { - ChannelMessageInvalid = 0, - ChannelMessageOfferChannel = 1, - ChannelMessageRescindChannelOffer = 2, - ChannelMessageRequestOffers = 3, - ChannelMessageAllOffersDelivered = 4, - ChannelMessageOpenChannel = 5, - ChannelMessageOpenChannelResult = 6, - ChannelMessageCloseChannel = 7, - ChannelMessageGpadlHeader = 8, - ChannelMessageGpadlBody = 9, - ChannelMessageGpadlCreated = 10, - ChannelMessageGpadlTeardown = 11, - ChannelMessageGpadlTorndown = 12, - ChannelMessageRelIdReleased = 13, - ChannelMessageInitiateContact = 14, - ChannelMessageVersionResponse = 15, - ChannelMessageUnload = 16, -#ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD - ChannelMessageViewRangeAdd = 17, - ChannelMessageViewRangeRemove = 18, -#endif - ChannelMessageCount -}; - -struct vmbus_channel_message_header { - enum vmbus_channel_message_type MessageType; - u32 Padding; -} __attribute__((packed)); - -/* Query VMBus Version parameters */ -struct vmbus_channel_query_vmbus_version { - struct vmbus_channel_message_header Header; - u32 Version; -} __attribute__((packed)); - -/* VMBus Version Supported parameters */ -struct vmbus_channel_version_supported { - struct vmbus_channel_message_header Header; - bool VersionSupported; -} __attribute__((packed)); - -/* Offer Channel parameters */ -struct vmbus_channel_offer_channel { - struct vmbus_channel_message_header Header; - struct vmbus_channel_offer Offer; - u32 ChildRelId; - u8 MonitorId; - bool MonitorAllocated; -} __attribute__((packed)); - -/* Rescind Offer parameters */ -struct vmbus_channel_rescind_offer { - struct vmbus_channel_message_header Header; - u32 ChildRelId; -} __attribute__((packed)); - -/* - * Request Offer -- no parameters, SynIC message contains the partition ID - * Set Snoop -- no parameters, SynIC message contains the partition ID - * Clear Snoop -- no parameters, SynIC message contains the partition ID - * All Offers Delivered -- no parameters, SynIC message contains the partition - * ID - * Flush Client -- no parameters, SynIC message contains the partition ID - */ - -/* Open Channel parameters */ -struct vmbus_channel_open_channel { - struct vmbus_channel_message_header Header; - - /* Identifies the specific VMBus channel that is being opened. */ - u32 ChildRelId; - - /* ID making a particular open request at a channel offer unique. */ - u32 OpenId; - - /* GPADL for the channel's ring buffer. */ - u32 RingBufferGpadlHandle; - - /* GPADL for the channel's server context save area. */ - u32 ServerContextAreaGpadlHandle; - - /* - * The upstream ring buffer begins at offset zero in the memory - * described by RingBufferGpadlHandle. The downstream ring buffer - * follows it at this offset (in pages). - */ - u32 DownstreamRingBufferPageOffset; - - /* User-specific data to be passed along to the server endpoint. */ - unsigned char UserData[MAX_USER_DEFINED_BYTES]; -} __attribute__((packed)); - -/* Open Channel Result parameters */ -struct vmbus_channel_open_result { - struct vmbus_channel_message_header Header; - u32 ChildRelId; - u32 OpenId; - u32 Status; -} __attribute__((packed)); - -/* Close channel parameters; */ -struct vmbus_channel_close_channel { - struct vmbus_channel_message_header Header; - u32 ChildRelId; -} __attribute__((packed)); - -/* Channel Message GPADL */ -#define GPADL_TYPE_RING_BUFFER 1 -#define GPADL_TYPE_SERVER_SAVE_AREA 2 -#define GPADL_TYPE_TRANSACTION 8 - -/* - * The number of PFNs in a GPADL message is defined by the number of - * pages that would be spanned by ByteCount and ByteOffset. If the - * implied number of PFNs won't fit in this packet, there will be a - * follow-up packet that contains more. - */ -struct vmbus_channel_gpadl_header { - struct vmbus_channel_message_header Header; - u32 ChildRelId; - u32 Gpadl; - u16 RangeBufLen; - u16 RangeCount; - struct gpa_range Range[0]; -} __attribute__((packed)); - -/* This is the followup packet that contains more PFNs. */ -struct vmbus_channel_gpadl_body { - struct vmbus_channel_message_header Header; - u32 MessageNumber; - u32 Gpadl; - u64 Pfn[0]; -} __attribute__((packed)); - -struct vmbus_channel_gpadl_created { - struct vmbus_channel_message_header Header; - u32 ChildRelId; - u32 Gpadl; - u32 CreationStatus; -} __attribute__((packed)); - -struct vmbus_channel_gpadl_teardown { - struct vmbus_channel_message_header Header; - u32 ChildRelId; - u32 Gpadl; -} __attribute__((packed)); - -struct vmbus_channel_gpadl_torndown { - struct vmbus_channel_message_header Header; - u32 Gpadl; -} __attribute__((packed)); - -#ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD -struct vmbus_channel_view_range_add { - struct vmbus_channel_message_header Header; - PHYSICAL_ADDRESS ViewRangeBase; - u64 ViewRangeLength; - u32 ChildRelId; -} __attribute__((packed)); - -struct vmbus_channel_view_range_remove { - struct vmbus_channel_message_header Header; - PHYSICAL_ADDRESS ViewRangeBase; - u32 ChildRelId; -} __attribute__((packed)); -#endif - -struct vmbus_channel_relid_released { - struct vmbus_channel_message_header Header; - u32 ChildRelId; -} __attribute__((packed)); - -struct vmbus_channel_initiate_contact { - struct vmbus_channel_message_header Header; - u32 VMBusVersionRequested; - u32 Padding2; - u64 InterruptPage; - u64 MonitorPage1; - u64 MonitorPage2; -} __attribute__((packed)); - -struct vmbus_channel_version_response { - struct vmbus_channel_message_header Header; - bool VersionSupported; -} __attribute__((packed)); - -enum vmbus_channel_state { - CHANNEL_OFFER_STATE, - CHANNEL_OPENING_STATE, - CHANNEL_OPEN_STATE, -}; - -struct vmbus_channel { - struct list_head ListEntry; - - struct hv_device *DeviceObject; - - struct timer_list poll_timer; /* SA-111 workaround */ - - enum vmbus_channel_state State; - - struct vmbus_channel_offer_channel OfferMsg; - /* - * These are based on the OfferMsg.MonitorId. - * Save it here for easy access. - */ - u8 MonitorGroup; - u8 MonitorBit; - - u32 RingBufferGpadlHandle; - - /* Allocated memory for ring buffer */ - void *RingBufferPages; - u32 RingBufferPageCount; - RING_BUFFER_INFO Outbound; /* send to parent */ - RING_BUFFER_INFO Inbound; /* receive from parent */ - spinlock_t inbound_lock; - struct workqueue_struct *ControlWQ; - - /* Channel callback are invoked in this workqueue context */ - /* HANDLE dataWorkQueue; */ - - void (*OnChannelCallback)(void *context); - void *ChannelCallbackContext; -}; - -struct vmbus_channel_debug_info { - u32 RelId; - enum vmbus_channel_state State; - struct hv_guid InterfaceType; - struct hv_guid InterfaceInstance; - u32 MonitorId; - u32 ServerMonitorPending; - u32 ServerMonitorLatency; - u32 ServerMonitorConnectionId; - u32 ClientMonitorPending; - u32 ClientMonitorLatency; - u32 ClientMonitorConnectionId; - - RING_BUFFER_DEBUG_INFO Inbound; - RING_BUFFER_DEBUG_INFO Outbound; -}; - -/* - * Represents each channel msg on the vmbus connection This is a - * variable-size data structure depending on the msg type itself - */ -struct vmbus_channel_msginfo { - /* Bookkeeping stuff */ - struct list_head MsgListEntry; - - /* So far, this is only used to handle gpadl body message */ - struct list_head SubMsgList; - - /* Synchronize the request/response if needed */ - struct osd_waitevent *WaitEvent; - - union { - struct vmbus_channel_version_supported VersionSupported; - struct vmbus_channel_open_result OpenResult; - struct vmbus_channel_gpadl_torndown GpadlTorndown; - struct vmbus_channel_gpadl_created GpadlCreated; - struct vmbus_channel_version_response VersionResponse; - } Response; - - u32 MessageSize; - /* - * The channel message that goes out on the "wire". - * It will contain at minimum the VMBUS_CHANNEL_MESSAGE_HEADER header - */ - unsigned char Msg[0]; -}; - - -struct vmbus_channel *AllocVmbusChannel(void); - -void FreeVmbusChannel(struct vmbus_channel *Channel); - -void VmbusOnChannelMessage(void *Context); - -int VmbusChannelRequestOffers(void); - -void VmbusChannelReleaseUnattachedChannels(void); - -#endif /* _CHANNEL_MGMT_H_ */ diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index 685a3200e04e..2f9ecd2a85f1 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -6,7 +6,7 @@ obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o hv_vmbus-objs := vmbus_drv.o osd.o \ vmbus.o hv.o connection.o channel.o \ - ChannelMgmt.o ChannelInterface.o ring_buffer.o + channel_mgmt.o ChannelInterface.o ring_buffer.o hv_storvsc-objs := storvsc_drv.o storvsc.o hv_blkvsc-objs := blkvsc_drv.o blkvsc.o hv_netvsc-objs := netvsc_drv.o netvsc.o rndis_filter.o diff --git a/drivers/staging/hv/VmbusPrivate.h b/drivers/staging/hv/VmbusPrivate.h index d73baff99a7e..6e82183e9d50 100644 --- a/drivers/staging/hv/VmbusPrivate.h +++ b/drivers/staging/hv/VmbusPrivate.h @@ -28,7 +28,7 @@ #include "hv.h" #include "VmbusApi.h" #include "channel.h" -#include "ChannelMgmt.h" +#include "channel_mgmt.h" #include "ChannelInterface.h" #include "ring_buffer.h" #include diff --git a/drivers/staging/hv/channel.h b/drivers/staging/hv/channel.h index 6b283edcae68..acb2c556369b 100644 --- a/drivers/staging/hv/channel.h +++ b/drivers/staging/hv/channel.h @@ -25,7 +25,7 @@ #ifndef _CHANNEL_H_ #define _CHANNEL_H_ -#include "ChannelMgmt.h" +#include "channel_mgmt.h" /* The format must be the same as struct vmdata_gpa_direct */ struct VMBUS_CHANNEL_PACKET_PAGE_BUFFER { diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c new file mode 100644 index 000000000000..369823013889 --- /dev/null +++ b/drivers/staging/hv/channel_mgmt.c @@ -0,0 +1,856 @@ +/* + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + */ +#include +#include +#include +#include +#include +#include "osd.h" +#include "logging.h" +#include "VmbusPrivate.h" +#include "utils.h" + +struct vmbus_channel_message_table_entry { + enum vmbus_channel_message_type messageType; + void (*messageHandler)(struct vmbus_channel_message_header *msg); +}; + +#define MAX_MSG_TYPES 2 +#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 6 + +static const struct hv_guid + gSupportedDeviceClasses[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = { + /* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ + /* Storage - SCSI */ + { + .data = { + 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, + 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f + } + }, + + /* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */ + /* Network */ + { + .data = { + 0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, + 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E + } + }, + + /* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */ + /* Input */ + { + .data = { + 0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c, + 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A + } + }, + + /* {32412632-86cb-44a2-9b5c-50d1417354f5} */ + /* IDE */ + { + .data = { + 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, + 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 + } + }, + /* 0E0B6031-5213-4934-818B-38D90CED39DB */ + /* Shutdown */ + { + .data = { + 0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49, + 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB + } + }, + /* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */ + /* TimeSync */ + { + .data = { + 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, + 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf + } + }, +}; + + +/** + * prep_negotiate_resp() - Create default response for Hyper-V Negotiate message + * @icmsghdrp: Pointer to msg header structure + * @icmsg_negotiate: Pointer to negotiate message structure + * @buf: Raw buffer channel data + * + * @icmsghdrp is of type &struct icmsg_hdr. + * @negop is of type &struct icmsg_negotiate. + * Set up and fill in default negotiate response message. This response can + * come from both the vmbus driver and the hv_utils driver. The current api + * will respond properly to both Windows 2008 and Windows 2008-R2 operating + * systems. + * + * Mainly used by Hyper-V drivers. + */ +void prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, + struct icmsg_negotiate *negop, + u8 *buf) +{ + if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { + icmsghdrp->icmsgsize = 0x10; + + negop = (struct icmsg_negotiate *)&buf[ + sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; + + if (negop->icframe_vercnt == 2 && + negop->icversion_data[1].major == 3) { + negop->icversion_data[0].major = 3; + negop->icversion_data[0].minor = 0; + negop->icversion_data[1].major = 3; + negop->icversion_data[1].minor = 0; + } else { + negop->icversion_data[0].major = 1; + negop->icversion_data[0].minor = 0; + negop->icversion_data[1].major = 1; + negop->icversion_data[1].minor = 0; + } + + negop->icframe_vercnt = 1; + negop->icmsg_vercnt = 1; + } +} +EXPORT_SYMBOL(prep_negotiate_resp); + +/** + * chn_cb_negotiate() - Default handler for non IDE/SCSI/NETWORK + * Hyper-V requests + * @context: Pointer to argument structure. + * + * Set up the default handler for non device driver specific requests + * from Hyper-V. This stub responds to the default negotiate messages + * that come in for every non IDE/SCSI/Network request. + * This behavior is normally overwritten in the hv_utils driver. That + * driver handles requests like gracefull shutdown, heartbeats etc. + * + * Mainly used by Hyper-V drivers. + */ +void chn_cb_negotiate(void *context) +{ + struct vmbus_channel *channel = context; + u8 *buf; + u32 buflen, recvlen; + u64 requestid; + + struct icmsg_hdr *icmsghdrp; + struct icmsg_negotiate *negop = NULL; + + buflen = PAGE_SIZE; + buf = kmalloc(buflen, GFP_ATOMIC); + + VmbusChannelRecvPacket(channel, buf, buflen, &recvlen, &requestid); + + if (recvlen > 0) { + icmsghdrp = (struct icmsg_hdr *)&buf[ + sizeof(struct vmbuspipe_hdr)]; + + prep_negotiate_resp(icmsghdrp, negop, buf); + + icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION + | ICMSGHDRFLAG_RESPONSE; + + VmbusChannelSendPacket(channel, buf, + recvlen, requestid, + VmbusPacketTypeDataInBand, 0); + } + + kfree(buf); +} +EXPORT_SYMBOL(chn_cb_negotiate); + +/* + * Function table used for message responses for non IDE/SCSI/Network type + * messages. (Such as KVP/Shutdown etc) + */ +struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = { + /* 0E0B6031-5213-4934-818B-38D90CED39DB */ + /* Shutdown */ + { + .msg_type = HV_SHUTDOWN_MSG, + .data = { + 0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49, + 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB + }, + .callback = chn_cb_negotiate, + .log_msg = "Shutdown channel functionality initialized" + }, + + /* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */ + /* TimeSync */ + { + .msg_type = HV_TIMESYNC_MSG, + .data = { + 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, + 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf + }, + .callback = chn_cb_negotiate, + .log_msg = "Timesync channel functionality initialized" + }, +}; +EXPORT_SYMBOL(hv_cb_utils); + +/* + * AllocVmbusChannel - Allocate and initialize a vmbus channel object + */ +struct vmbus_channel *AllocVmbusChannel(void) +{ + struct vmbus_channel *channel; + + channel = kzalloc(sizeof(*channel), GFP_ATOMIC); + if (!channel) + return NULL; + + spin_lock_init(&channel->inbound_lock); + + init_timer(&channel->poll_timer); + channel->poll_timer.data = (unsigned long)channel; + channel->poll_timer.function = VmbusChannelOnTimer; + + channel->ControlWQ = create_workqueue("hv_vmbus_ctl"); + if (!channel->ControlWQ) { + kfree(channel); + return NULL; + } + + return channel; +} + +/* + * ReleaseVmbusChannel - Release the vmbus channel object itself + */ +static inline void ReleaseVmbusChannel(void *context) +{ + struct vmbus_channel *channel = context; + + DPRINT_ENTER(VMBUS); + + DPRINT_DBG(VMBUS, "releasing channel (%p)", channel); + destroy_workqueue(channel->ControlWQ); + DPRINT_DBG(VMBUS, "channel released (%p)", channel); + + kfree(channel); + + DPRINT_EXIT(VMBUS); +} + +/* + * FreeVmbusChannel - Release the resources used by the vmbus channel object + */ +void FreeVmbusChannel(struct vmbus_channel *Channel) +{ + del_timer_sync(&Channel->poll_timer); + + /* + * We have to release the channel's workqueue/thread in the vmbus's + * workqueue/thread context + * ie we can't destroy ourselves. + */ + osd_schedule_callback(gVmbusConnection.WorkQueue, ReleaseVmbusChannel, + Channel); +} + +/* + * VmbusChannelProcessOffer - Process the offer by creating a channel/device + * associated with this offer + */ +static void VmbusChannelProcessOffer(void *context) +{ + struct vmbus_channel *newChannel = context; + struct vmbus_channel *channel; + bool fNew = true; + int ret; + int cnt; + unsigned long flags; + + DPRINT_ENTER(VMBUS); + + /* Make sure this is a new offer */ + spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); + + list_for_each_entry(channel, &gVmbusConnection.ChannelList, ListEntry) { + if (!memcmp(&channel->OfferMsg.Offer.InterfaceType, + &newChannel->OfferMsg.Offer.InterfaceType, + sizeof(struct hv_guid)) && + !memcmp(&channel->OfferMsg.Offer.InterfaceInstance, + &newChannel->OfferMsg.Offer.InterfaceInstance, + sizeof(struct hv_guid))) { + fNew = false; + break; + } + } + + if (fNew) + list_add_tail(&newChannel->ListEntry, + &gVmbusConnection.ChannelList); + + spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); + + if (!fNew) { + DPRINT_DBG(VMBUS, "Ignoring duplicate offer for relid (%d)", + newChannel->OfferMsg.ChildRelId); + FreeVmbusChannel(newChannel); + DPRINT_EXIT(VMBUS); + return; + } + + /* + * Start the process of binding this offer to the driver + * We need to set the DeviceObject field before calling + * VmbusChildDeviceAdd() + */ + newChannel->DeviceObject = VmbusChildDeviceCreate( + &newChannel->OfferMsg.Offer.InterfaceType, + &newChannel->OfferMsg.Offer.InterfaceInstance, + newChannel); + + DPRINT_DBG(VMBUS, "child device object allocated - %p", + newChannel->DeviceObject); + + /* + * Add the new device to the bus. This will kick off device-driver + * binding which eventually invokes the device driver's AddDevice() + * method. + */ + ret = VmbusChildDeviceAdd(newChannel->DeviceObject); + if (ret != 0) { + DPRINT_ERR(VMBUS, + "unable to add child device object (relid %d)", + newChannel->OfferMsg.ChildRelId); + + spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); + list_del(&newChannel->ListEntry); + spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); + + FreeVmbusChannel(newChannel); + } else { + /* + * This state is used to indicate a successful open + * so that when we do close the channel normally, we + * can cleanup properly + */ + newChannel->State = CHANNEL_OPEN_STATE; + cnt = 0; + + while (cnt != MAX_MSG_TYPES) { + if (memcmp(&newChannel->OfferMsg.Offer.InterfaceType, + &hv_cb_utils[cnt].data, + sizeof(struct hv_guid)) == 0) { + DPRINT_INFO(VMBUS, "%s", + hv_cb_utils[cnt].log_msg); + + if (VmbusChannelOpen(newChannel, 2 * PAGE_SIZE, + 2 * PAGE_SIZE, NULL, 0, + hv_cb_utils[cnt].callback, + newChannel) == 0) + hv_cb_utils[cnt].channel = newChannel; + } + cnt++; + } + } + DPRINT_EXIT(VMBUS); +} + +/* + * VmbusChannelProcessRescindOffer - Rescind the offer by initiating a device removal + */ +static void VmbusChannelProcessRescindOffer(void *context) +{ + struct vmbus_channel *channel = context; + + DPRINT_ENTER(VMBUS); + VmbusChildDeviceRemove(channel->DeviceObject); + DPRINT_EXIT(VMBUS); +} + +/* + * VmbusChannelOnOffer - Handler for channel offers from vmbus in parent partition. + * + * We ignore all offers except network and storage offers. For each network and + * storage offers, we create a channel object and queue a work item to the + * channel object to process the offer synchronously + */ +static void VmbusChannelOnOffer(struct vmbus_channel_message_header *hdr) +{ + struct vmbus_channel_offer_channel *offer; + struct vmbus_channel *newChannel; + struct hv_guid *guidType; + struct hv_guid *guidInstance; + int i; + int fSupported = 0; + + DPRINT_ENTER(VMBUS); + + offer = (struct vmbus_channel_offer_channel *)hdr; + for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) { + if (memcmp(&offer->Offer.InterfaceType, + &gSupportedDeviceClasses[i], sizeof(struct hv_guid)) == 0) { + fSupported = 1; + break; + } + } + + if (!fSupported) { + DPRINT_DBG(VMBUS, "Ignoring channel offer notification for " + "child relid %d", offer->ChildRelId); + DPRINT_EXIT(VMBUS); + return; + } + + guidType = &offer->Offer.InterfaceType; + guidInstance = &offer->Offer.InterfaceInstance; + + DPRINT_INFO(VMBUS, "Channel offer notification - " + "child relid %d monitor id %d allocated %d, " + "type {%02x%02x%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x%02x%02x%02x%02x%02x%02x} " + "instance {%02x%02x%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x%02x%02x%02x%02x%02x%02x}", + offer->ChildRelId, offer->MonitorId, + offer->MonitorAllocated, + guidType->data[3], guidType->data[2], + guidType->data[1], guidType->data[0], + guidType->data[5], guidType->data[4], + guidType->data[7], guidType->data[6], + guidType->data[8], guidType->data[9], + guidType->data[10], guidType->data[11], + guidType->data[12], guidType->data[13], + guidType->data[14], guidType->data[15], + guidInstance->data[3], guidInstance->data[2], + guidInstance->data[1], guidInstance->data[0], + guidInstance->data[5], guidInstance->data[4], + guidInstance->data[7], guidInstance->data[6], + guidInstance->data[8], guidInstance->data[9], + guidInstance->data[10], guidInstance->data[11], + guidInstance->data[12], guidInstance->data[13], + guidInstance->data[14], guidInstance->data[15]); + + /* Allocate the channel object and save this offer. */ + newChannel = AllocVmbusChannel(); + if (!newChannel) { + DPRINT_ERR(VMBUS, "unable to allocate channel object"); + return; + } + + DPRINT_DBG(VMBUS, "channel object allocated - %p", newChannel); + + memcpy(&newChannel->OfferMsg, offer, + sizeof(struct vmbus_channel_offer_channel)); + newChannel->MonitorGroup = (u8)offer->MonitorId / 32; + newChannel->MonitorBit = (u8)offer->MonitorId % 32; + + /* TODO: Make sure the offer comes from our parent partition */ + osd_schedule_callback(newChannel->ControlWQ, VmbusChannelProcessOffer, + newChannel); + + DPRINT_EXIT(VMBUS); +} + +/* + * VmbusChannelOnOfferRescind - Rescind offer handler. + * + * We queue a work item to process this offer synchronously + */ +static void VmbusChannelOnOfferRescind(struct vmbus_channel_message_header *hdr) +{ + struct vmbus_channel_rescind_offer *rescind; + struct vmbus_channel *channel; + + DPRINT_ENTER(VMBUS); + + rescind = (struct vmbus_channel_rescind_offer *)hdr; + channel = GetChannelFromRelId(rescind->ChildRelId); + if (channel == NULL) { + DPRINT_DBG(VMBUS, "channel not found for relId %d", + rescind->ChildRelId); + return; + } + + osd_schedule_callback(channel->ControlWQ, + VmbusChannelProcessRescindOffer, + channel); + + DPRINT_EXIT(VMBUS); +} + +/* + * VmbusChannelOnOffersDelivered - This is invoked when all offers have been delivered. + * + * Nothing to do here. + */ +static void VmbusChannelOnOffersDelivered( + struct vmbus_channel_message_header *hdr) +{ + DPRINT_ENTER(VMBUS); + DPRINT_EXIT(VMBUS); +} + +/* + * VmbusChannelOnOpenResult - Open result handler. + * + * This is invoked when we received a response to our channel open request. + * Find the matching request, copy the response and signal the requesting + * thread. + */ +static void VmbusChannelOnOpenResult(struct vmbus_channel_message_header *hdr) +{ + struct vmbus_channel_open_result *result; + struct list_head *curr; + struct vmbus_channel_msginfo *msgInfo; + struct vmbus_channel_message_header *requestHeader; + struct vmbus_channel_open_channel *openMsg; + unsigned long flags; + + DPRINT_ENTER(VMBUS); + + result = (struct vmbus_channel_open_result *)hdr; + DPRINT_DBG(VMBUS, "vmbus open result - %d", result->Status); + + /* + * Find the open msg, copy the result and signal/unblock the wait event + */ + spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + + list_for_each(curr, &gVmbusConnection.ChannelMsgList) { +/* FIXME: this should probably use list_entry() instead */ + msgInfo = (struct vmbus_channel_msginfo *)curr; + requestHeader = (struct vmbus_channel_message_header *)msgInfo->Msg; + + if (requestHeader->MessageType == ChannelMessageOpenChannel) { + openMsg = (struct vmbus_channel_open_channel *)msgInfo->Msg; + if (openMsg->ChildRelId == result->ChildRelId && + openMsg->OpenId == result->OpenId) { + memcpy(&msgInfo->Response.OpenResult, + result, + sizeof(struct vmbus_channel_open_result)); + osd_WaitEventSet(msgInfo->WaitEvent); + break; + } + } + } + spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + + DPRINT_EXIT(VMBUS); +} + +/* + * VmbusChannelOnGpadlCreated - GPADL created handler. + * + * This is invoked when we received a response to our gpadl create request. + * Find the matching request, copy the response and signal the requesting + * thread. + */ +static void VmbusChannelOnGpadlCreated(struct vmbus_channel_message_header *hdr) +{ + struct vmbus_channel_gpadl_created *gpadlCreated; + struct list_head *curr; + struct vmbus_channel_msginfo *msgInfo; + struct vmbus_channel_message_header *requestHeader; + struct vmbus_channel_gpadl_header *gpadlHeader; + unsigned long flags; + + DPRINT_ENTER(VMBUS); + + gpadlCreated = (struct vmbus_channel_gpadl_created *)hdr; + DPRINT_DBG(VMBUS, "vmbus gpadl created result - %d", + gpadlCreated->CreationStatus); + + /* + * Find the establish msg, copy the result and signal/unblock the wait + * event + */ + spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + + list_for_each(curr, &gVmbusConnection.ChannelMsgList) { +/* FIXME: this should probably use list_entry() instead */ + msgInfo = (struct vmbus_channel_msginfo *)curr; + requestHeader = (struct vmbus_channel_message_header *)msgInfo->Msg; + + if (requestHeader->MessageType == ChannelMessageGpadlHeader) { + gpadlHeader = (struct vmbus_channel_gpadl_header *)requestHeader; + + if ((gpadlCreated->ChildRelId == + gpadlHeader->ChildRelId) && + (gpadlCreated->Gpadl == gpadlHeader->Gpadl)) { + memcpy(&msgInfo->Response.GpadlCreated, + gpadlCreated, + sizeof(struct vmbus_channel_gpadl_created)); + osd_WaitEventSet(msgInfo->WaitEvent); + break; + } + } + } + spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + + DPRINT_EXIT(VMBUS); +} + +/* + * VmbusChannelOnGpadlTorndown - GPADL torndown handler. + * + * This is invoked when we received a response to our gpadl teardown request. + * Find the matching request, copy the response and signal the requesting + * thread. + */ +static void VmbusChannelOnGpadlTorndown( + struct vmbus_channel_message_header *hdr) +{ + struct vmbus_channel_gpadl_torndown *gpadlTorndown; + struct list_head *curr; + struct vmbus_channel_msginfo *msgInfo; + struct vmbus_channel_message_header *requestHeader; + struct vmbus_channel_gpadl_teardown *gpadlTeardown; + unsigned long flags; + + DPRINT_ENTER(VMBUS); + + gpadlTorndown = (struct vmbus_channel_gpadl_torndown *)hdr; + + /* + * Find the open msg, copy the result and signal/unblock the wait event + */ + spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + + list_for_each(curr, &gVmbusConnection.ChannelMsgList) { +/* FIXME: this should probably use list_entry() instead */ + msgInfo = (struct vmbus_channel_msginfo *)curr; + requestHeader = (struct vmbus_channel_message_header *)msgInfo->Msg; + + if (requestHeader->MessageType == ChannelMessageGpadlTeardown) { + gpadlTeardown = (struct vmbus_channel_gpadl_teardown *)requestHeader; + + if (gpadlTorndown->Gpadl == gpadlTeardown->Gpadl) { + memcpy(&msgInfo->Response.GpadlTorndown, + gpadlTorndown, + sizeof(struct vmbus_channel_gpadl_torndown)); + osd_WaitEventSet(msgInfo->WaitEvent); + break; + } + } + } + spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + + DPRINT_EXIT(VMBUS); +} + +/* + * VmbusChannelOnVersionResponse - Version response handler + * + * This is invoked when we received a response to our initiate contact request. + * Find the matching request, copy the response and signal the requesting + * thread. + */ +static void VmbusChannelOnVersionResponse( + struct vmbus_channel_message_header *hdr) +{ + struct list_head *curr; + struct vmbus_channel_msginfo *msgInfo; + struct vmbus_channel_message_header *requestHeader; + struct vmbus_channel_initiate_contact *initiate; + struct vmbus_channel_version_response *versionResponse; + unsigned long flags; + + DPRINT_ENTER(VMBUS); + + versionResponse = (struct vmbus_channel_version_response *)hdr; + spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + + list_for_each(curr, &gVmbusConnection.ChannelMsgList) { +/* FIXME: this should probably use list_entry() instead */ + msgInfo = (struct vmbus_channel_msginfo *)curr; + requestHeader = (struct vmbus_channel_message_header *)msgInfo->Msg; + + if (requestHeader->MessageType == + ChannelMessageInitiateContact) { + initiate = (struct vmbus_channel_initiate_contact *)requestHeader; + memcpy(&msgInfo->Response.VersionResponse, + versionResponse, + sizeof(struct vmbus_channel_version_response)); + osd_WaitEventSet(msgInfo->WaitEvent); + } + } + spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + + DPRINT_EXIT(VMBUS); +} + +/* Channel message dispatch table */ +static struct vmbus_channel_message_table_entry + gChannelMessageTable[ChannelMessageCount] = { + {ChannelMessageInvalid, NULL}, + {ChannelMessageOfferChannel, VmbusChannelOnOffer}, + {ChannelMessageRescindChannelOffer, VmbusChannelOnOfferRescind}, + {ChannelMessageRequestOffers, NULL}, + {ChannelMessageAllOffersDelivered, VmbusChannelOnOffersDelivered}, + {ChannelMessageOpenChannel, NULL}, + {ChannelMessageOpenChannelResult, VmbusChannelOnOpenResult}, + {ChannelMessageCloseChannel, NULL}, + {ChannelMessageGpadlHeader, NULL}, + {ChannelMessageGpadlBody, NULL}, + {ChannelMessageGpadlCreated, VmbusChannelOnGpadlCreated}, + {ChannelMessageGpadlTeardown, NULL}, + {ChannelMessageGpadlTorndown, VmbusChannelOnGpadlTorndown}, + {ChannelMessageRelIdReleased, NULL}, + {ChannelMessageInitiateContact, NULL}, + {ChannelMessageVersionResponse, VmbusChannelOnVersionResponse}, + {ChannelMessageUnload, NULL}, +}; + +/* + * VmbusOnChannelMessage - Handler for channel protocol messages. + * + * This is invoked in the vmbus worker thread context. + */ +void VmbusOnChannelMessage(void *Context) +{ + struct hv_message *msg = Context; + struct vmbus_channel_message_header *hdr; + int size; + + DPRINT_ENTER(VMBUS); + + hdr = (struct vmbus_channel_message_header *)msg->u.Payload; + size = msg->Header.PayloadSize; + + DPRINT_DBG(VMBUS, "message type %d size %d", hdr->MessageType, size); + + if (hdr->MessageType >= ChannelMessageCount) { + DPRINT_ERR(VMBUS, + "Received invalid channel message type %d size %d", + hdr->MessageType, size); + print_hex_dump_bytes("", DUMP_PREFIX_NONE, + (unsigned char *)msg->u.Payload, size); + kfree(msg); + return; + } + + if (gChannelMessageTable[hdr->MessageType].messageHandler) + gChannelMessageTable[hdr->MessageType].messageHandler(hdr); + else + DPRINT_ERR(VMBUS, "Unhandled channel message type %d", + hdr->MessageType); + + /* Free the msg that was allocated in VmbusOnMsgDPC() */ + kfree(msg); + DPRINT_EXIT(VMBUS); +} + +/* + * VmbusChannelRequestOffers - Send a request to get all our pending offers. + */ +int VmbusChannelRequestOffers(void) +{ + struct vmbus_channel_message_header *msg; + struct vmbus_channel_msginfo *msgInfo; + int ret; + + DPRINT_ENTER(VMBUS); + + msgInfo = kmalloc(sizeof(*msgInfo) + + sizeof(struct vmbus_channel_message_header), + GFP_KERNEL); + if (!msgInfo) + return -ENOMEM; + + msgInfo->WaitEvent = osd_WaitEventCreate(); + if (!msgInfo->WaitEvent) { + kfree(msgInfo); + return -ENOMEM; + } + + msg = (struct vmbus_channel_message_header *)msgInfo->Msg; + + msg->MessageType = ChannelMessageRequestOffers; + + /*SpinlockAcquire(gVmbusConnection.channelMsgLock); + INSERT_TAIL_LIST(&gVmbusConnection.channelMsgList, + &msgInfo->msgListEntry); + SpinlockRelease(gVmbusConnection.channelMsgLock);*/ + + ret = VmbusPostMessage(msg, + sizeof(struct vmbus_channel_message_header)); + if (ret != 0) { + DPRINT_ERR(VMBUS, "Unable to request offers - %d", ret); + + /*SpinlockAcquire(gVmbusConnection.channelMsgLock); + REMOVE_ENTRY_LIST(&msgInfo->msgListEntry); + SpinlockRelease(gVmbusConnection.channelMsgLock);*/ + + goto Cleanup; + } + /* osd_WaitEventWait(msgInfo->waitEvent); */ + + /*SpinlockAcquire(gVmbusConnection.channelMsgLock); + REMOVE_ENTRY_LIST(&msgInfo->msgListEntry); + SpinlockRelease(gVmbusConnection.channelMsgLock);*/ + + +Cleanup: + if (msgInfo) { + kfree(msgInfo->WaitEvent); + kfree(msgInfo); + } + + DPRINT_EXIT(VMBUS); + return ret; +} + +/* + * VmbusChannelReleaseUnattachedChannels - Release channels that are + * unattached/unconnected ie (no drivers associated) + */ +void VmbusChannelReleaseUnattachedChannels(void) +{ + struct vmbus_channel *channel, *pos; + struct vmbus_channel *start = NULL; + unsigned long flags; + + spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); + + list_for_each_entry_safe(channel, pos, &gVmbusConnection.ChannelList, + ListEntry) { + if (channel == start) + break; + + if (!channel->DeviceObject->Driver) { + list_del(&channel->ListEntry); + DPRINT_INFO(VMBUS, + "Releasing unattached device object %p", + channel->DeviceObject); + + VmbusChildDeviceRemove(channel->DeviceObject); + FreeVmbusChannel(channel); + } else { + if (!start) + start = channel; + } + } + + spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); +} + +/* eof */ diff --git a/drivers/staging/hv/channel_mgmt.h b/drivers/staging/hv/channel_mgmt.h new file mode 100644 index 000000000000..9219199d0e5a --- /dev/null +++ b/drivers/staging/hv/channel_mgmt.h @@ -0,0 +1,320 @@ +/* + * + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + * + */ + + +#ifndef _CHANNEL_MGMT_H_ +#define _CHANNEL_MGMT_H_ + +#include +#include +#include "ring_buffer.h" +#include "VmbusChannelInterface.h" +#include "VmbusPacketFormat.h" + +/* Version 1 messages */ +enum vmbus_channel_message_type { + ChannelMessageInvalid = 0, + ChannelMessageOfferChannel = 1, + ChannelMessageRescindChannelOffer = 2, + ChannelMessageRequestOffers = 3, + ChannelMessageAllOffersDelivered = 4, + ChannelMessageOpenChannel = 5, + ChannelMessageOpenChannelResult = 6, + ChannelMessageCloseChannel = 7, + ChannelMessageGpadlHeader = 8, + ChannelMessageGpadlBody = 9, + ChannelMessageGpadlCreated = 10, + ChannelMessageGpadlTeardown = 11, + ChannelMessageGpadlTorndown = 12, + ChannelMessageRelIdReleased = 13, + ChannelMessageInitiateContact = 14, + ChannelMessageVersionResponse = 15, + ChannelMessageUnload = 16, +#ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD + ChannelMessageViewRangeAdd = 17, + ChannelMessageViewRangeRemove = 18, +#endif + ChannelMessageCount +}; + +struct vmbus_channel_message_header { + enum vmbus_channel_message_type MessageType; + u32 Padding; +} __attribute__((packed)); + +/* Query VMBus Version parameters */ +struct vmbus_channel_query_vmbus_version { + struct vmbus_channel_message_header Header; + u32 Version; +} __attribute__((packed)); + +/* VMBus Version Supported parameters */ +struct vmbus_channel_version_supported { + struct vmbus_channel_message_header Header; + bool VersionSupported; +} __attribute__((packed)); + +/* Offer Channel parameters */ +struct vmbus_channel_offer_channel { + struct vmbus_channel_message_header Header; + struct vmbus_channel_offer Offer; + u32 ChildRelId; + u8 MonitorId; + bool MonitorAllocated; +} __attribute__((packed)); + +/* Rescind Offer parameters */ +struct vmbus_channel_rescind_offer { + struct vmbus_channel_message_header Header; + u32 ChildRelId; +} __attribute__((packed)); + +/* + * Request Offer -- no parameters, SynIC message contains the partition ID + * Set Snoop -- no parameters, SynIC message contains the partition ID + * Clear Snoop -- no parameters, SynIC message contains the partition ID + * All Offers Delivered -- no parameters, SynIC message contains the partition + * ID + * Flush Client -- no parameters, SynIC message contains the partition ID + */ + +/* Open Channel parameters */ +struct vmbus_channel_open_channel { + struct vmbus_channel_message_header Header; + + /* Identifies the specific VMBus channel that is being opened. */ + u32 ChildRelId; + + /* ID making a particular open request at a channel offer unique. */ + u32 OpenId; + + /* GPADL for the channel's ring buffer. */ + u32 RingBufferGpadlHandle; + + /* GPADL for the channel's server context save area. */ + u32 ServerContextAreaGpadlHandle; + + /* + * The upstream ring buffer begins at offset zero in the memory + * described by RingBufferGpadlHandle. The downstream ring buffer + * follows it at this offset (in pages). + */ + u32 DownstreamRingBufferPageOffset; + + /* User-specific data to be passed along to the server endpoint. */ + unsigned char UserData[MAX_USER_DEFINED_BYTES]; +} __attribute__((packed)); + +/* Open Channel Result parameters */ +struct vmbus_channel_open_result { + struct vmbus_channel_message_header Header; + u32 ChildRelId; + u32 OpenId; + u32 Status; +} __attribute__((packed)); + +/* Close channel parameters; */ +struct vmbus_channel_close_channel { + struct vmbus_channel_message_header Header; + u32 ChildRelId; +} __attribute__((packed)); + +/* Channel Message GPADL */ +#define GPADL_TYPE_RING_BUFFER 1 +#define GPADL_TYPE_SERVER_SAVE_AREA 2 +#define GPADL_TYPE_TRANSACTION 8 + +/* + * The number of PFNs in a GPADL message is defined by the number of + * pages that would be spanned by ByteCount and ByteOffset. If the + * implied number of PFNs won't fit in this packet, there will be a + * follow-up packet that contains more. + */ +struct vmbus_channel_gpadl_header { + struct vmbus_channel_message_header Header; + u32 ChildRelId; + u32 Gpadl; + u16 RangeBufLen; + u16 RangeCount; + struct gpa_range Range[0]; +} __attribute__((packed)); + +/* This is the followup packet that contains more PFNs. */ +struct vmbus_channel_gpadl_body { + struct vmbus_channel_message_header Header; + u32 MessageNumber; + u32 Gpadl; + u64 Pfn[0]; +} __attribute__((packed)); + +struct vmbus_channel_gpadl_created { + struct vmbus_channel_message_header Header; + u32 ChildRelId; + u32 Gpadl; + u32 CreationStatus; +} __attribute__((packed)); + +struct vmbus_channel_gpadl_teardown { + struct vmbus_channel_message_header Header; + u32 ChildRelId; + u32 Gpadl; +} __attribute__((packed)); + +struct vmbus_channel_gpadl_torndown { + struct vmbus_channel_message_header Header; + u32 Gpadl; +} __attribute__((packed)); + +#ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD +struct vmbus_channel_view_range_add { + struct vmbus_channel_message_header Header; + PHYSICAL_ADDRESS ViewRangeBase; + u64 ViewRangeLength; + u32 ChildRelId; +} __attribute__((packed)); + +struct vmbus_channel_view_range_remove { + struct vmbus_channel_message_header Header; + PHYSICAL_ADDRESS ViewRangeBase; + u32 ChildRelId; +} __attribute__((packed)); +#endif + +struct vmbus_channel_relid_released { + struct vmbus_channel_message_header Header; + u32 ChildRelId; +} __attribute__((packed)); + +struct vmbus_channel_initiate_contact { + struct vmbus_channel_message_header Header; + u32 VMBusVersionRequested; + u32 Padding2; + u64 InterruptPage; + u64 MonitorPage1; + u64 MonitorPage2; +} __attribute__((packed)); + +struct vmbus_channel_version_response { + struct vmbus_channel_message_header Header; + bool VersionSupported; +} __attribute__((packed)); + +enum vmbus_channel_state { + CHANNEL_OFFER_STATE, + CHANNEL_OPENING_STATE, + CHANNEL_OPEN_STATE, +}; + +struct vmbus_channel { + struct list_head ListEntry; + + struct hv_device *DeviceObject; + + struct timer_list poll_timer; /* SA-111 workaround */ + + enum vmbus_channel_state State; + + struct vmbus_channel_offer_channel OfferMsg; + /* + * These are based on the OfferMsg.MonitorId. + * Save it here for easy access. + */ + u8 MonitorGroup; + u8 MonitorBit; + + u32 RingBufferGpadlHandle; + + /* Allocated memory for ring buffer */ + void *RingBufferPages; + u32 RingBufferPageCount; + RING_BUFFER_INFO Outbound; /* send to parent */ + RING_BUFFER_INFO Inbound; /* receive from parent */ + spinlock_t inbound_lock; + struct workqueue_struct *ControlWQ; + + /* Channel callback are invoked in this workqueue context */ + /* HANDLE dataWorkQueue; */ + + void (*OnChannelCallback)(void *context); + void *ChannelCallbackContext; +}; + +struct vmbus_channel_debug_info { + u32 RelId; + enum vmbus_channel_state State; + struct hv_guid InterfaceType; + struct hv_guid InterfaceInstance; + u32 MonitorId; + u32 ServerMonitorPending; + u32 ServerMonitorLatency; + u32 ServerMonitorConnectionId; + u32 ClientMonitorPending; + u32 ClientMonitorLatency; + u32 ClientMonitorConnectionId; + + RING_BUFFER_DEBUG_INFO Inbound; + RING_BUFFER_DEBUG_INFO Outbound; +}; + +/* + * Represents each channel msg on the vmbus connection This is a + * variable-size data structure depending on the msg type itself + */ +struct vmbus_channel_msginfo { + /* Bookkeeping stuff */ + struct list_head MsgListEntry; + + /* So far, this is only used to handle gpadl body message */ + struct list_head SubMsgList; + + /* Synchronize the request/response if needed */ + struct osd_waitevent *WaitEvent; + + union { + struct vmbus_channel_version_supported VersionSupported; + struct vmbus_channel_open_result OpenResult; + struct vmbus_channel_gpadl_torndown GpadlTorndown; + struct vmbus_channel_gpadl_created GpadlCreated; + struct vmbus_channel_version_response VersionResponse; + } Response; + + u32 MessageSize; + /* + * The channel message that goes out on the "wire". + * It will contain at minimum the VMBUS_CHANNEL_MESSAGE_HEADER header + */ + unsigned char Msg[0]; +}; + + +struct vmbus_channel *AllocVmbusChannel(void); + +void FreeVmbusChannel(struct vmbus_channel *Channel); + +void VmbusOnChannelMessage(void *Context); + +int VmbusChannelRequestOffers(void); + +void VmbusChannelReleaseUnattachedChannels(void); + +#endif /* _CHANNEL_MGMT_H_ */ -- cgit v1.2.3 From 5496c9c31d43633c85237d25d31c85cf735a8e7d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:36:31 -0700 Subject: Staging: hv: rename ChannelInterface.c and .h to channel_interface.c and .h All of the uppercase .c files are now gone. Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/ChannelInterface.c | 152 --------------------------------- drivers/staging/hv/ChannelInterface.h | 35 -------- drivers/staging/hv/Makefile | 2 +- drivers/staging/hv/VmbusPrivate.h | 2 +- drivers/staging/hv/channel_interface.c | 152 +++++++++++++++++++++++++++++++++ drivers/staging/hv/channel_interface.h | 35 ++++++++ 6 files changed, 189 insertions(+), 189 deletions(-) delete mode 100644 drivers/staging/hv/ChannelInterface.c delete mode 100644 drivers/staging/hv/ChannelInterface.h create mode 100644 drivers/staging/hv/channel_interface.c create mode 100644 drivers/staging/hv/channel_interface.h (limited to 'drivers') diff --git a/drivers/staging/hv/ChannelInterface.c b/drivers/staging/hv/ChannelInterface.c deleted file mode 100644 index 019b064f7cb3..000000000000 --- a/drivers/staging/hv/ChannelInterface.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ -#include -#include -#include "osd.h" -#include "VmbusPrivate.h" - -static int IVmbusChannelOpen(struct hv_device *device, u32 SendBufferSize, - u32 RecvRingBufferSize, void *UserData, - u32 UserDataLen, - void (*ChannelCallback)(void *context), - void *Context) -{ - return VmbusChannelOpen(device->context, SendBufferSize, - RecvRingBufferSize, UserData, UserDataLen, - ChannelCallback, Context); -} - -static void IVmbusChannelClose(struct hv_device *device) -{ - VmbusChannelClose(device->context); -} - -static int IVmbusChannelSendPacket(struct hv_device *device, const void *Buffer, - u32 BufferLen, u64 RequestId, u32 Type, - u32 Flags) -{ - return VmbusChannelSendPacket(device->context, Buffer, BufferLen, - RequestId, Type, Flags); -} - -static int IVmbusChannelSendPacketPageBuffer(struct hv_device *device, - struct hv_page_buffer PageBuffers[], - u32 PageCount, void *Buffer, - u32 BufferLen, u64 RequestId) -{ - return VmbusChannelSendPacketPageBuffer(device->context, PageBuffers, - PageCount, Buffer, BufferLen, - RequestId); -} - -static int IVmbusChannelSendPacketMultiPageBuffer(struct hv_device *device, - struct hv_multipage_buffer *MultiPageBuffer, - void *Buffer, u32 BufferLen, u64 RequestId) -{ - return VmbusChannelSendPacketMultiPageBuffer(device->context, - MultiPageBuffer, Buffer, - BufferLen, RequestId); -} - -static int IVmbusChannelRecvPacket(struct hv_device *device, void *Buffer, - u32 BufferLen, u32 *BufferActualLen, - u64 *RequestId) -{ - return VmbusChannelRecvPacket(device->context, Buffer, BufferLen, - BufferActualLen, RequestId); -} - -static int IVmbusChannelRecvPacketRaw(struct hv_device *device, void *Buffer, - u32 BufferLen, u32 *BufferActualLen, - u64 *RequestId) -{ - return VmbusChannelRecvPacketRaw(device->context, Buffer, BufferLen, - BufferActualLen, RequestId); -} - -static int IVmbusChannelEstablishGpadl(struct hv_device *device, void *Buffer, - u32 BufferLen, u32 *GpadlHandle) -{ - return VmbusChannelEstablishGpadl(device->context, Buffer, BufferLen, - GpadlHandle); -} - -static int IVmbusChannelTeardownGpadl(struct hv_device *device, u32 GpadlHandle) -{ - return VmbusChannelTeardownGpadl(device->context, GpadlHandle); - -} - -void GetChannelInterface(struct vmbus_channel_interface *iface) -{ - iface->Open = IVmbusChannelOpen; - iface->Close = IVmbusChannelClose; - iface->SendPacket = IVmbusChannelSendPacket; - iface->SendPacketPageBuffer = IVmbusChannelSendPacketPageBuffer; - iface->SendPacketMultiPageBuffer = - IVmbusChannelSendPacketMultiPageBuffer; - iface->RecvPacket = IVmbusChannelRecvPacket; - iface->RecvPacketRaw = IVmbusChannelRecvPacketRaw; - iface->EstablishGpadl = IVmbusChannelEstablishGpadl; - iface->TeardownGpadl = IVmbusChannelTeardownGpadl; - iface->GetInfo = GetChannelInfo; -} - -void GetChannelInfo(struct hv_device *device, struct hv_device_info *info) -{ - struct vmbus_channel_debug_info debugInfo; - - if (!device->context) - return; - - VmbusChannelGetDebugInfo(device->context, &debugInfo); - - info->ChannelId = debugInfo.RelId; - info->ChannelState = debugInfo.State; - memcpy(&info->ChannelType, &debugInfo.InterfaceType, - sizeof(struct hv_guid)); - memcpy(&info->ChannelInstance, &debugInfo.InterfaceInstance, - sizeof(struct hv_guid)); - - info->MonitorId = debugInfo.MonitorId; - - info->ServerMonitorPending = debugInfo.ServerMonitorPending; - info->ServerMonitorLatency = debugInfo.ServerMonitorLatency; - info->ServerMonitorConnectionId = debugInfo.ServerMonitorConnectionId; - - info->ClientMonitorPending = debugInfo.ClientMonitorPending; - info->ClientMonitorLatency = debugInfo.ClientMonitorLatency; - info->ClientMonitorConnectionId = debugInfo.ClientMonitorConnectionId; - - info->Inbound.InterruptMask = debugInfo.Inbound.CurrentInterruptMask; - info->Inbound.ReadIndex = debugInfo.Inbound.CurrentReadIndex; - info->Inbound.WriteIndex = debugInfo.Inbound.CurrentWriteIndex; - info->Inbound.BytesAvailToRead = debugInfo.Inbound.BytesAvailToRead; - info->Inbound.BytesAvailToWrite = debugInfo.Inbound.BytesAvailToWrite; - - info->Outbound.InterruptMask = debugInfo.Outbound.CurrentInterruptMask; - info->Outbound.ReadIndex = debugInfo.Outbound.CurrentReadIndex; - info->Outbound.WriteIndex = debugInfo.Outbound.CurrentWriteIndex; - info->Outbound.BytesAvailToRead = debugInfo.Outbound.BytesAvailToRead; - info->Outbound.BytesAvailToWrite = debugInfo.Outbound.BytesAvailToWrite; -} diff --git a/drivers/staging/hv/ChannelInterface.h b/drivers/staging/hv/ChannelInterface.h deleted file mode 100644 index 27b7a253b711..000000000000 --- a/drivers/staging/hv/ChannelInterface.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ - - -#ifndef _CHANNEL_INTERFACE_H_ -#define _CHANNEL_INTERFACE_H_ - -#include "VmbusApi.h" - -void GetChannelInterface(struct vmbus_channel_interface *ChannelInterface); - -void GetChannelInfo(struct hv_device *Device, - struct hv_device_info *DeviceInfo); - -#endif /* _CHANNEL_INTERFACE_H_ */ diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index 2f9ecd2a85f1..1866f80a45d3 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -6,7 +6,7 @@ obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o hv_vmbus-objs := vmbus_drv.o osd.o \ vmbus.o hv.o connection.o channel.o \ - channel_mgmt.o ChannelInterface.o ring_buffer.o + channel_mgmt.o channel_interface.o ring_buffer.o hv_storvsc-objs := storvsc_drv.o storvsc.o hv_blkvsc-objs := blkvsc_drv.o blkvsc.o hv_netvsc-objs := netvsc_drv.o netvsc.o rndis_filter.o diff --git a/drivers/staging/hv/VmbusPrivate.h b/drivers/staging/hv/VmbusPrivate.h index 6e82183e9d50..57a116ca8716 100644 --- a/drivers/staging/hv/VmbusPrivate.h +++ b/drivers/staging/hv/VmbusPrivate.h @@ -29,7 +29,7 @@ #include "VmbusApi.h" #include "channel.h" #include "channel_mgmt.h" -#include "ChannelInterface.h" +#include "channel_interface.h" #include "ring_buffer.h" #include diff --git a/drivers/staging/hv/channel_interface.c b/drivers/staging/hv/channel_interface.c new file mode 100644 index 000000000000..019b064f7cb3 --- /dev/null +++ b/drivers/staging/hv/channel_interface.c @@ -0,0 +1,152 @@ +/* + * + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + * + */ +#include +#include +#include "osd.h" +#include "VmbusPrivate.h" + +static int IVmbusChannelOpen(struct hv_device *device, u32 SendBufferSize, + u32 RecvRingBufferSize, void *UserData, + u32 UserDataLen, + void (*ChannelCallback)(void *context), + void *Context) +{ + return VmbusChannelOpen(device->context, SendBufferSize, + RecvRingBufferSize, UserData, UserDataLen, + ChannelCallback, Context); +} + +static void IVmbusChannelClose(struct hv_device *device) +{ + VmbusChannelClose(device->context); +} + +static int IVmbusChannelSendPacket(struct hv_device *device, const void *Buffer, + u32 BufferLen, u64 RequestId, u32 Type, + u32 Flags) +{ + return VmbusChannelSendPacket(device->context, Buffer, BufferLen, + RequestId, Type, Flags); +} + +static int IVmbusChannelSendPacketPageBuffer(struct hv_device *device, + struct hv_page_buffer PageBuffers[], + u32 PageCount, void *Buffer, + u32 BufferLen, u64 RequestId) +{ + return VmbusChannelSendPacketPageBuffer(device->context, PageBuffers, + PageCount, Buffer, BufferLen, + RequestId); +} + +static int IVmbusChannelSendPacketMultiPageBuffer(struct hv_device *device, + struct hv_multipage_buffer *MultiPageBuffer, + void *Buffer, u32 BufferLen, u64 RequestId) +{ + return VmbusChannelSendPacketMultiPageBuffer(device->context, + MultiPageBuffer, Buffer, + BufferLen, RequestId); +} + +static int IVmbusChannelRecvPacket(struct hv_device *device, void *Buffer, + u32 BufferLen, u32 *BufferActualLen, + u64 *RequestId) +{ + return VmbusChannelRecvPacket(device->context, Buffer, BufferLen, + BufferActualLen, RequestId); +} + +static int IVmbusChannelRecvPacketRaw(struct hv_device *device, void *Buffer, + u32 BufferLen, u32 *BufferActualLen, + u64 *RequestId) +{ + return VmbusChannelRecvPacketRaw(device->context, Buffer, BufferLen, + BufferActualLen, RequestId); +} + +static int IVmbusChannelEstablishGpadl(struct hv_device *device, void *Buffer, + u32 BufferLen, u32 *GpadlHandle) +{ + return VmbusChannelEstablishGpadl(device->context, Buffer, BufferLen, + GpadlHandle); +} + +static int IVmbusChannelTeardownGpadl(struct hv_device *device, u32 GpadlHandle) +{ + return VmbusChannelTeardownGpadl(device->context, GpadlHandle); + +} + +void GetChannelInterface(struct vmbus_channel_interface *iface) +{ + iface->Open = IVmbusChannelOpen; + iface->Close = IVmbusChannelClose; + iface->SendPacket = IVmbusChannelSendPacket; + iface->SendPacketPageBuffer = IVmbusChannelSendPacketPageBuffer; + iface->SendPacketMultiPageBuffer = + IVmbusChannelSendPacketMultiPageBuffer; + iface->RecvPacket = IVmbusChannelRecvPacket; + iface->RecvPacketRaw = IVmbusChannelRecvPacketRaw; + iface->EstablishGpadl = IVmbusChannelEstablishGpadl; + iface->TeardownGpadl = IVmbusChannelTeardownGpadl; + iface->GetInfo = GetChannelInfo; +} + +void GetChannelInfo(struct hv_device *device, struct hv_device_info *info) +{ + struct vmbus_channel_debug_info debugInfo; + + if (!device->context) + return; + + VmbusChannelGetDebugInfo(device->context, &debugInfo); + + info->ChannelId = debugInfo.RelId; + info->ChannelState = debugInfo.State; + memcpy(&info->ChannelType, &debugInfo.InterfaceType, + sizeof(struct hv_guid)); + memcpy(&info->ChannelInstance, &debugInfo.InterfaceInstance, + sizeof(struct hv_guid)); + + info->MonitorId = debugInfo.MonitorId; + + info->ServerMonitorPending = debugInfo.ServerMonitorPending; + info->ServerMonitorLatency = debugInfo.ServerMonitorLatency; + info->ServerMonitorConnectionId = debugInfo.ServerMonitorConnectionId; + + info->ClientMonitorPending = debugInfo.ClientMonitorPending; + info->ClientMonitorLatency = debugInfo.ClientMonitorLatency; + info->ClientMonitorConnectionId = debugInfo.ClientMonitorConnectionId; + + info->Inbound.InterruptMask = debugInfo.Inbound.CurrentInterruptMask; + info->Inbound.ReadIndex = debugInfo.Inbound.CurrentReadIndex; + info->Inbound.WriteIndex = debugInfo.Inbound.CurrentWriteIndex; + info->Inbound.BytesAvailToRead = debugInfo.Inbound.BytesAvailToRead; + info->Inbound.BytesAvailToWrite = debugInfo.Inbound.BytesAvailToWrite; + + info->Outbound.InterruptMask = debugInfo.Outbound.CurrentInterruptMask; + info->Outbound.ReadIndex = debugInfo.Outbound.CurrentReadIndex; + info->Outbound.WriteIndex = debugInfo.Outbound.CurrentWriteIndex; + info->Outbound.BytesAvailToRead = debugInfo.Outbound.BytesAvailToRead; + info->Outbound.BytesAvailToWrite = debugInfo.Outbound.BytesAvailToWrite; +} diff --git a/drivers/staging/hv/channel_interface.h b/drivers/staging/hv/channel_interface.h new file mode 100644 index 000000000000..27b7a253b711 --- /dev/null +++ b/drivers/staging/hv/channel_interface.h @@ -0,0 +1,35 @@ +/* + * + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + * + */ + + +#ifndef _CHANNEL_INTERFACE_H_ +#define _CHANNEL_INTERFACE_H_ + +#include "VmbusApi.h" + +void GetChannelInterface(struct vmbus_channel_interface *ChannelInterface); + +void GetChannelInfo(struct hv_device *Device, + struct hv_device_info *DeviceInfo); + +#endif /* _CHANNEL_INTERFACE_H_ */ -- cgit v1.2.3 From a82c7a2ad6e636c344bfde7c1fa22557ad96ee85 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:39:15 -0700 Subject: Staging: hv: rename NetVscApi.h to netvsc_api.h Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/NetVscApi.h | 116 -------------------------------------- drivers/staging/hv/netvsc.h | 2 +- drivers/staging/hv/netvsc_api.h | 116 ++++++++++++++++++++++++++++++++++++++ drivers/staging/hv/netvsc_drv.c | 2 +- drivers/staging/hv/rndis_filter.c | 2 +- 5 files changed, 119 insertions(+), 119 deletions(-) delete mode 100644 drivers/staging/hv/NetVscApi.h create mode 100644 drivers/staging/hv/netvsc_api.h (limited to 'drivers') diff --git a/drivers/staging/hv/NetVscApi.h b/drivers/staging/hv/NetVscApi.h deleted file mode 100644 index 91a4cd9965d8..000000000000 --- a/drivers/staging/hv/NetVscApi.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ - - -#ifndef _NETVSC_API_H_ -#define _NETVSC_API_H_ - -#include "VmbusApi.h" - -/* Fwd declaration */ -struct hv_netvsc_packet; - -/* Represent the xfer page packet which contains 1 or more netvsc packet */ -struct xferpage_packet { - struct list_head ListEntry; - - /* # of netvsc packets this xfer packet contains */ - u32 Count; -}; - -/* The number of pages which are enough to cover jumbo frame buffer. */ -#define NETVSC_PACKET_MAXPAGE 4 - -/* - * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame - * within the RNDIS - */ -struct hv_netvsc_packet { - /* Bookkeeping stuff */ - struct list_head ListEntry; - - struct hv_device *Device; - bool IsDataPacket; - - /* - * Valid only for receives when we break a xfer page packet - * into multiple netvsc packets - */ - struct xferpage_packet *XferPagePacket; - - union { - struct{ - u64 ReceiveCompletionTid; - void *ReceiveCompletionContext; - void (*OnReceiveCompletion)(void *context); - } Recv; - struct{ - u64 SendCompletionTid; - void *SendCompletionContext; - void (*OnSendCompletion)(void *context); - } Send; - } Completion; - - /* This points to the memory after PageBuffers */ - void *Extension; - - u32 TotalDataBufferLength; - /* Points to the send/receive buffer where the ethernet frame is */ - u32 PageBufferCount; - struct hv_page_buffer PageBuffers[NETVSC_PACKET_MAXPAGE]; -}; - -/* Represents the net vsc driver */ -struct netvsc_driver { - /* Must be the first field */ - /* Which is a bug FIXME! */ - struct hv_driver Base; - - u32 RingBufferSize; - u32 RequestExtSize; - - /* - * This is set by the caller to allow us to callback when we - * receive a packet from the "wire" - */ - int (*OnReceiveCallback)(struct hv_device *dev, - struct hv_netvsc_packet *packet); - void (*OnLinkStatusChanged)(struct hv_device *dev, u32 Status); - - /* Specific to this driver */ - int (*OnSend)(struct hv_device *dev, struct hv_netvsc_packet *packet); - - void *Context; -}; - -struct netvsc_device_info { - unsigned char MacAddr[6]; - bool LinkState; /* 0 - link up, 1 - link down */ -}; - -/* Interface */ -int NetVscInitialize(struct hv_driver *drv); -int RndisFilterOnOpen(struct hv_device *Device); -int RndisFilterOnClose(struct hv_device *Device); - -#endif /* _NETVSC_API_H_ */ diff --git a/drivers/staging/hv/netvsc.h b/drivers/staging/hv/netvsc.h index a6264db8388a..05d2ceb9e5e3 100644 --- a/drivers/staging/hv/netvsc.h +++ b/drivers/staging/hv/netvsc.h @@ -28,7 +28,7 @@ #include #include "VmbusPacketFormat.h" #include "VmbusChannelInterface.h" -#include "NetVscApi.h" +#include "netvsc_api.h" #define NVSP_INVALID_PROTOCOL_VERSION ((u32)0xFFFFFFFF) diff --git a/drivers/staging/hv/netvsc_api.h b/drivers/staging/hv/netvsc_api.h new file mode 100644 index 000000000000..91a4cd9965d8 --- /dev/null +++ b/drivers/staging/hv/netvsc_api.h @@ -0,0 +1,116 @@ +/* + * + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + * + */ + + +#ifndef _NETVSC_API_H_ +#define _NETVSC_API_H_ + +#include "VmbusApi.h" + +/* Fwd declaration */ +struct hv_netvsc_packet; + +/* Represent the xfer page packet which contains 1 or more netvsc packet */ +struct xferpage_packet { + struct list_head ListEntry; + + /* # of netvsc packets this xfer packet contains */ + u32 Count; +}; + +/* The number of pages which are enough to cover jumbo frame buffer. */ +#define NETVSC_PACKET_MAXPAGE 4 + +/* + * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame + * within the RNDIS + */ +struct hv_netvsc_packet { + /* Bookkeeping stuff */ + struct list_head ListEntry; + + struct hv_device *Device; + bool IsDataPacket; + + /* + * Valid only for receives when we break a xfer page packet + * into multiple netvsc packets + */ + struct xferpage_packet *XferPagePacket; + + union { + struct{ + u64 ReceiveCompletionTid; + void *ReceiveCompletionContext; + void (*OnReceiveCompletion)(void *context); + } Recv; + struct{ + u64 SendCompletionTid; + void *SendCompletionContext; + void (*OnSendCompletion)(void *context); + } Send; + } Completion; + + /* This points to the memory after PageBuffers */ + void *Extension; + + u32 TotalDataBufferLength; + /* Points to the send/receive buffer where the ethernet frame is */ + u32 PageBufferCount; + struct hv_page_buffer PageBuffers[NETVSC_PACKET_MAXPAGE]; +}; + +/* Represents the net vsc driver */ +struct netvsc_driver { + /* Must be the first field */ + /* Which is a bug FIXME! */ + struct hv_driver Base; + + u32 RingBufferSize; + u32 RequestExtSize; + + /* + * This is set by the caller to allow us to callback when we + * receive a packet from the "wire" + */ + int (*OnReceiveCallback)(struct hv_device *dev, + struct hv_netvsc_packet *packet); + void (*OnLinkStatusChanged)(struct hv_device *dev, u32 Status); + + /* Specific to this driver */ + int (*OnSend)(struct hv_device *dev, struct hv_netvsc_packet *packet); + + void *Context; +}; + +struct netvsc_device_info { + unsigned char MacAddr[6]; + bool LinkState; /* 0 - link up, 1 - link down */ +}; + +/* Interface */ +int NetVscInitialize(struct hv_driver *drv); +int RndisFilterOnOpen(struct hv_device *Device); +int RndisFilterOnClose(struct hv_device *Device); + +#endif /* _NETVSC_API_H_ */ diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index a6584a876618..3a6fe2512828 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -38,7 +38,7 @@ #include "logging.h" #include "VersionInfo.h" #include "vmbus.h" -#include "NetVscApi.h" +#include "netvsc_api.h" struct net_device_context { /* point back to our device context */ diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c index e6824e055c11..2c6ee8d4b6e5 100644 --- a/drivers/staging/hv/rndis_filter.c +++ b/drivers/staging/hv/rndis_filter.c @@ -26,7 +26,7 @@ #include "osd.h" #include "logging.h" -#include "NetVscApi.h" +#include "netvsc_api.h" #include "rndis_filter.h" /* Data types */ -- cgit v1.2.3 From bb96979310965cef680c90ba331126fd64e9265f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:40:43 -0700 Subject: Staging: hv: rename StorVscApi.h to storvsc_api.h Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/StorVscApi.h | 110 --------------------------------------- drivers/staging/hv/blkvsc_drv.c | 2 +- drivers/staging/hv/storvsc.c | 2 +- drivers/staging/hv/storvsc_api.h | 110 +++++++++++++++++++++++++++++++++++++++ drivers/staging/hv/storvsc_drv.c | 2 +- 5 files changed, 113 insertions(+), 113 deletions(-) delete mode 100644 drivers/staging/hv/StorVscApi.h create mode 100644 drivers/staging/hv/storvsc_api.h (limited to 'drivers') diff --git a/drivers/staging/hv/StorVscApi.h b/drivers/staging/hv/StorVscApi.h deleted file mode 100644 index 126a8588edb1..000000000000 --- a/drivers/staging/hv/StorVscApi.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ - - -#ifndef _STORVSC_API_H_ -#define _STORVSC_API_H_ - -#include "VmbusApi.h" - -/* Defines */ -#define STORVSC_RING_BUFFER_SIZE (10*PAGE_SIZE) -#define BLKVSC_RING_BUFFER_SIZE (20*PAGE_SIZE) - -#define STORVSC_MAX_IO_REQUESTS 64 - -/* - * In Hyper-V, each port/path/target maps to 1 scsi host adapter. In - * reality, the path/target is not used (ie always set to 0) so our - * scsi host adapter essentially has 1 bus with 1 target that contains - * up to 256 luns. - */ -#define STORVSC_MAX_LUNS_PER_TARGET 64 -#define STORVSC_MAX_TARGETS 1 -#define STORVSC_MAX_CHANNELS 1 - -struct hv_storvsc_request; - -/* Matches Windows-end */ -enum storvsc_request_type{ - WRITE_TYPE, - READ_TYPE, - UNKNOWN_TYPE, -}; - -struct hv_storvsc_request { - enum storvsc_request_type Type; - u32 Host; - u32 Bus; - u32 TargetId; - u32 LunId; - u8 *Cdb; - u32 CdbLen; - u32 Status; - u32 BytesXfer; - - unsigned char *SenseBuffer; - u32 SenseBufferSize; - - void *Context; - - void (*OnIOCompletion)(struct hv_storvsc_request *Request); - - /* This points to the memory after DataBuffer */ - void *Extension; - - struct hv_multipage_buffer DataBuffer; -}; - -/* Represents the block vsc driver */ -struct storvsc_driver_object { - /* Must be the first field */ - /* Which is a bug FIXME! */ - struct hv_driver Base; - - /* Set by caller (in bytes) */ - u32 RingBufferSize; - - /* Allocate this much private extension for each I/O request */ - u32 RequestExtSize; - - /* Maximum # of requests in flight per channel/device */ - u32 MaxOutstandingRequestsPerChannel; - - /* Specific to this driver */ - int (*OnIORequest)(struct hv_device *Device, - struct hv_storvsc_request *Request); -}; - -struct storvsc_device_info { - unsigned int PortNumber; - unsigned char PathId; - unsigned char TargetId; -}; - -/* Interface */ -int StorVscInitialize(struct hv_driver *driver); -int StorVscOnHostReset(struct hv_device *Device); -int BlkVscInitialize(struct hv_driver *driver); - -#endif /* _STORVSC_API_H_ */ diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 78fc348334e7..3e7c75e0b149 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -34,7 +34,7 @@ #include "logging.h" #include "VersionInfo.h" #include "vmbus.h" -#include "StorVscApi.h" +#include "storvsc_api.h" #define BLKVSC_MINORS 64 diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index e73130e49cce..3a8b54f5e2a6 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -25,7 +25,7 @@ #include #include "osd.h" #include "logging.h" -#include "StorVscApi.h" +#include "storvsc_api.h" #include "VmbusPacketFormat.h" #include "vstorage.h" diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h new file mode 100644 index 000000000000..126a8588edb1 --- /dev/null +++ b/drivers/staging/hv/storvsc_api.h @@ -0,0 +1,110 @@ +/* + * + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + * + */ + + +#ifndef _STORVSC_API_H_ +#define _STORVSC_API_H_ + +#include "VmbusApi.h" + +/* Defines */ +#define STORVSC_RING_BUFFER_SIZE (10*PAGE_SIZE) +#define BLKVSC_RING_BUFFER_SIZE (20*PAGE_SIZE) + +#define STORVSC_MAX_IO_REQUESTS 64 + +/* + * In Hyper-V, each port/path/target maps to 1 scsi host adapter. In + * reality, the path/target is not used (ie always set to 0) so our + * scsi host adapter essentially has 1 bus with 1 target that contains + * up to 256 luns. + */ +#define STORVSC_MAX_LUNS_PER_TARGET 64 +#define STORVSC_MAX_TARGETS 1 +#define STORVSC_MAX_CHANNELS 1 + +struct hv_storvsc_request; + +/* Matches Windows-end */ +enum storvsc_request_type{ + WRITE_TYPE, + READ_TYPE, + UNKNOWN_TYPE, +}; + +struct hv_storvsc_request { + enum storvsc_request_type Type; + u32 Host; + u32 Bus; + u32 TargetId; + u32 LunId; + u8 *Cdb; + u32 CdbLen; + u32 Status; + u32 BytesXfer; + + unsigned char *SenseBuffer; + u32 SenseBufferSize; + + void *Context; + + void (*OnIOCompletion)(struct hv_storvsc_request *Request); + + /* This points to the memory after DataBuffer */ + void *Extension; + + struct hv_multipage_buffer DataBuffer; +}; + +/* Represents the block vsc driver */ +struct storvsc_driver_object { + /* Must be the first field */ + /* Which is a bug FIXME! */ + struct hv_driver Base; + + /* Set by caller (in bytes) */ + u32 RingBufferSize; + + /* Allocate this much private extension for each I/O request */ + u32 RequestExtSize; + + /* Maximum # of requests in flight per channel/device */ + u32 MaxOutstandingRequestsPerChannel; + + /* Specific to this driver */ + int (*OnIORequest)(struct hv_device *Device, + struct hv_storvsc_request *Request); +}; + +struct storvsc_device_info { + unsigned int PortNumber; + unsigned char PathId; + unsigned char TargetId; +}; + +/* Interface */ +int StorVscInitialize(struct hv_driver *driver); +int StorVscOnHostReset(struct hv_device *Device); +int BlkVscInitialize(struct hv_driver *driver); + +#endif /* _STORVSC_API_H_ */ diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index d9649e37e11c..56b659bda370 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -35,7 +35,7 @@ #include "logging.h" #include "VersionInfo.h" #include "vmbus.h" -#include "StorVscApi.h" +#include "storvsc_api.h" struct host_device_context { -- cgit v1.2.3 From 447fc67e7a8c4d0afdffa3e4535c1a98a84e59ab Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:43:02 -0700 Subject: Staging: hv: rename VmbusApi.h to vmbus_api.h Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/VmbusApi.h | 193 --------------------------------- drivers/staging/hv/VmbusPrivate.h | 2 +- drivers/staging/hv/channel_interface.h | 2 +- drivers/staging/hv/hv_utils.c | 2 +- drivers/staging/hv/netvsc_api.h | 2 +- drivers/staging/hv/storvsc_api.h | 2 +- drivers/staging/hv/vmbus.h | 2 +- drivers/staging/hv/vmbus_api.h | 193 +++++++++++++++++++++++++++++++++ 8 files changed, 199 insertions(+), 199 deletions(-) delete mode 100644 drivers/staging/hv/VmbusApi.h create mode 100644 drivers/staging/hv/vmbus_api.h (limited to 'drivers') diff --git a/drivers/staging/hv/VmbusApi.h b/drivers/staging/hv/VmbusApi.h deleted file mode 100644 index 4275be3292ce..000000000000 --- a/drivers/staging/hv/VmbusApi.h +++ /dev/null @@ -1,193 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ - - -#ifndef _VMBUS_API_H_ -#define _VMBUS_API_H_ - -#define MAX_PAGE_BUFFER_COUNT 16 -#define MAX_MULTIPAGE_BUFFER_COUNT 32 /* 128K */ - -#pragma pack(push, 1) - -/* Single-page buffer */ -struct hv_page_buffer { - u32 Length; - u32 Offset; - u64 Pfn; -}; - -/* Multiple-page buffer */ -struct hv_multipage_buffer { - /* Length and Offset determines the # of pfns in the array */ - u32 Length; - u32 Offset; - u64 PfnArray[MAX_MULTIPAGE_BUFFER_COUNT]; -}; - -/* 0x18 includes the proprietary packet header */ -#define MAX_PAGE_BUFFER_PACKET (0x18 + \ - (sizeof(struct hv_page_buffer) * \ - MAX_PAGE_BUFFER_COUNT)) -#define MAX_MULTIPAGE_BUFFER_PACKET (0x18 + \ - sizeof(struct hv_multipage_buffer)) - - -#pragma pack(pop) - -struct hv_driver; -struct hv_device; - -struct hv_dev_port_info { - u32 InterruptMask; - u32 ReadIndex; - u32 WriteIndex; - u32 BytesAvailToRead; - u32 BytesAvailToWrite; -}; - -struct hv_device_info { - u32 ChannelId; - u32 ChannelState; - struct hv_guid ChannelType; - struct hv_guid ChannelInstance; - - u32 MonitorId; - u32 ServerMonitorPending; - u32 ServerMonitorLatency; - u32 ServerMonitorConnectionId; - u32 ClientMonitorPending; - u32 ClientMonitorLatency; - u32 ClientMonitorConnectionId; - - struct hv_dev_port_info Inbound; - struct hv_dev_port_info Outbound; -}; - -/** - * struct vmbus_channel_interface - Contains member functions for vmbus channel - * @Open: Open the channel - * @Close: Close the channel - * @SendPacket: Send a packet over the channel - * @SendPacketPageBuffer: Send a single page buffer over the channel - * @SendPacketMultiPageBuffer: Send a multiple page buffers - * @RecvPacket: Receive packet - * @RecvPacketRaw: Receive Raw packet - * @EstablishGpadl: Set up GPADL for ringbuffer - * @TeardownGpadl: Teardown GPADL for ringbuffer - * @GetInfo: Get info about the channel - * - * This structure contains function pointer to control vmbus channel - * behavior. None of these functions is externally callable, but they - * are used for normal vmbus channel internal behavior. - * Only used by Hyper-V drivers. - */ -struct vmbus_channel_interface { - int (*Open)(struct hv_device *Device, u32 SendBufferSize, - u32 RecvRingBufferSize, void *UserData, u32 UserDataLen, - void (*ChannelCallback)(void *context), - void *Context); - void (*Close)(struct hv_device *device); - int (*SendPacket)(struct hv_device *Device, const void *Buffer, - u32 BufferLen, u64 RequestId, u32 Type, u32 Flags); - int (*SendPacketPageBuffer)(struct hv_device *dev, - struct hv_page_buffer PageBuffers[], - u32 PageCount, void *Buffer, u32 BufferLen, - u64 RequestId); - int (*SendPacketMultiPageBuffer)(struct hv_device *device, - struct hv_multipage_buffer *mpb, - void *Buffer, - u32 BufferLen, - u64 RequestId); - int (*RecvPacket)(struct hv_device *dev, void *buf, u32 buflen, - u32 *BufferActualLen, u64 *RequestId); - int (*RecvPacketRaw)(struct hv_device *dev, void *buf, u32 buflen, - u32 *BufferActualLen, u64 *RequestId); - int (*EstablishGpadl)(struct hv_device *dev, void *buf, u32 buflen, - u32 *GpadlHandle); - int (*TeardownGpadl)(struct hv_device *device, u32 GpadlHandle); - void (*GetInfo)(struct hv_device *dev, struct hv_device_info *devinfo); -}; - -/* Base driver object */ -struct hv_driver { - const char *name; - - /* the device type supported by this driver */ - struct hv_guid deviceType; - - int (*OnDeviceAdd)(struct hv_device *device, void *data); - int (*OnDeviceRemove)(struct hv_device *device); - void (*OnCleanup)(struct hv_driver *driver); - - struct vmbus_channel_interface VmbusChannelInterface; -}; - -/* Base device object */ -struct hv_device { - /* the driver for this device */ - struct hv_driver *Driver; - - char name[64]; - - /* the device type id of this device */ - struct hv_guid deviceType; - - /* the device instance id of this device */ - struct hv_guid deviceInstance; - - void *context; - - /* Device extension; */ - void *Extension; -}; - -/* Vmbus driver object */ -struct vmbus_driver { - /* !! Must be the 1st field !! */ - /* FIXME if ^, then someone is doing somthing stupid */ - struct hv_driver Base; - - /* Set by the caller */ - struct hv_device * (*OnChildDeviceCreate)(struct hv_guid *DeviceType, - struct hv_guid *DeviceInstance, - void *Context); - void (*OnChildDeviceDestroy)(struct hv_device *device); - int (*OnChildDeviceAdd)(struct hv_device *RootDevice, - struct hv_device *ChildDevice); - void (*OnChildDeviceRemove)(struct hv_device *device); - - /* Set by the callee */ - int (*OnIsr)(struct hv_driver *driver); - void (*OnMsgDpc)(struct hv_driver *driver); - void (*OnEventDpc)(struct hv_driver *driver); - void (*GetChannelOffers)(void); - - void (*GetChannelInterface)(struct vmbus_channel_interface *i); - void (*GetChannelInfo)(struct hv_device *dev, - struct hv_device_info *devinfo); -}; - -int VmbusInitialize(struct hv_driver *drv); - -#endif /* _VMBUS_API_H_ */ diff --git a/drivers/staging/hv/VmbusPrivate.h b/drivers/staging/hv/VmbusPrivate.h index 57a116ca8716..588c667a7f6b 100644 --- a/drivers/staging/hv/VmbusPrivate.h +++ b/drivers/staging/hv/VmbusPrivate.h @@ -26,7 +26,7 @@ #define _VMBUS_PRIVATE_H_ #include "hv.h" -#include "VmbusApi.h" +#include "vmbus_api.h" #include "channel.h" #include "channel_mgmt.h" #include "channel_interface.h" diff --git a/drivers/staging/hv/channel_interface.h b/drivers/staging/hv/channel_interface.h index 27b7a253b711..6acaf6ce2c48 100644 --- a/drivers/staging/hv/channel_interface.h +++ b/drivers/staging/hv/channel_interface.h @@ -25,7 +25,7 @@ #ifndef _CHANNEL_INTERFACE_H_ #define _CHANNEL_INTERFACE_H_ -#include "VmbusApi.h" +#include "vmbus_api.h" void GetChannelInterface(struct vmbus_channel_interface *ChannelInterface); diff --git a/drivers/staging/hv/hv_utils.c b/drivers/staging/hv/hv_utils.c index 6ccaea27d75a..d6f6dfa03671 100644 --- a/drivers/staging/hv/hv_utils.c +++ b/drivers/staging/hv/hv_utils.c @@ -33,7 +33,7 @@ #include "VersionInfo.h" #include "channel.h" #include "VmbusPrivate.h" -#include "VmbusApi.h" +#include "vmbus_api.h" #include "utils.h" diff --git a/drivers/staging/hv/netvsc_api.h b/drivers/staging/hv/netvsc_api.h index 91a4cd9965d8..4b5b3ac458c8 100644 --- a/drivers/staging/hv/netvsc_api.h +++ b/drivers/staging/hv/netvsc_api.h @@ -25,7 +25,7 @@ #ifndef _NETVSC_API_H_ #define _NETVSC_API_H_ -#include "VmbusApi.h" +#include "vmbus_api.h" /* Fwd declaration */ struct hv_netvsc_packet; diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 126a8588edb1..0063bde9a4b2 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -25,7 +25,7 @@ #ifndef _STORVSC_API_H_ #define _STORVSC_API_H_ -#include "VmbusApi.h" +#include "vmbus_api.h" /* Defines */ #define STORVSC_RING_BUFFER_SIZE (10*PAGE_SIZE) diff --git a/drivers/staging/hv/vmbus.h b/drivers/staging/hv/vmbus.h index 6404b8424bef..0c6ee0f487f3 100644 --- a/drivers/staging/hv/vmbus.h +++ b/drivers/staging/hv/vmbus.h @@ -26,7 +26,7 @@ #define _VMBUS_H_ #include -#include "VmbusApi.h" +#include "vmbus_api.h" struct driver_context { struct hv_guid class_id; diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h new file mode 100644 index 000000000000..4275be3292ce --- /dev/null +++ b/drivers/staging/hv/vmbus_api.h @@ -0,0 +1,193 @@ +/* + * + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + * + */ + + +#ifndef _VMBUS_API_H_ +#define _VMBUS_API_H_ + +#define MAX_PAGE_BUFFER_COUNT 16 +#define MAX_MULTIPAGE_BUFFER_COUNT 32 /* 128K */ + +#pragma pack(push, 1) + +/* Single-page buffer */ +struct hv_page_buffer { + u32 Length; + u32 Offset; + u64 Pfn; +}; + +/* Multiple-page buffer */ +struct hv_multipage_buffer { + /* Length and Offset determines the # of pfns in the array */ + u32 Length; + u32 Offset; + u64 PfnArray[MAX_MULTIPAGE_BUFFER_COUNT]; +}; + +/* 0x18 includes the proprietary packet header */ +#define MAX_PAGE_BUFFER_PACKET (0x18 + \ + (sizeof(struct hv_page_buffer) * \ + MAX_PAGE_BUFFER_COUNT)) +#define MAX_MULTIPAGE_BUFFER_PACKET (0x18 + \ + sizeof(struct hv_multipage_buffer)) + + +#pragma pack(pop) + +struct hv_driver; +struct hv_device; + +struct hv_dev_port_info { + u32 InterruptMask; + u32 ReadIndex; + u32 WriteIndex; + u32 BytesAvailToRead; + u32 BytesAvailToWrite; +}; + +struct hv_device_info { + u32 ChannelId; + u32 ChannelState; + struct hv_guid ChannelType; + struct hv_guid ChannelInstance; + + u32 MonitorId; + u32 ServerMonitorPending; + u32 ServerMonitorLatency; + u32 ServerMonitorConnectionId; + u32 ClientMonitorPending; + u32 ClientMonitorLatency; + u32 ClientMonitorConnectionId; + + struct hv_dev_port_info Inbound; + struct hv_dev_port_info Outbound; +}; + +/** + * struct vmbus_channel_interface - Contains member functions for vmbus channel + * @Open: Open the channel + * @Close: Close the channel + * @SendPacket: Send a packet over the channel + * @SendPacketPageBuffer: Send a single page buffer over the channel + * @SendPacketMultiPageBuffer: Send a multiple page buffers + * @RecvPacket: Receive packet + * @RecvPacketRaw: Receive Raw packet + * @EstablishGpadl: Set up GPADL for ringbuffer + * @TeardownGpadl: Teardown GPADL for ringbuffer + * @GetInfo: Get info about the channel + * + * This structure contains function pointer to control vmbus channel + * behavior. None of these functions is externally callable, but they + * are used for normal vmbus channel internal behavior. + * Only used by Hyper-V drivers. + */ +struct vmbus_channel_interface { + int (*Open)(struct hv_device *Device, u32 SendBufferSize, + u32 RecvRingBufferSize, void *UserData, u32 UserDataLen, + void (*ChannelCallback)(void *context), + void *Context); + void (*Close)(struct hv_device *device); + int (*SendPacket)(struct hv_device *Device, const void *Buffer, + u32 BufferLen, u64 RequestId, u32 Type, u32 Flags); + int (*SendPacketPageBuffer)(struct hv_device *dev, + struct hv_page_buffer PageBuffers[], + u32 PageCount, void *Buffer, u32 BufferLen, + u64 RequestId); + int (*SendPacketMultiPageBuffer)(struct hv_device *device, + struct hv_multipage_buffer *mpb, + void *Buffer, + u32 BufferLen, + u64 RequestId); + int (*RecvPacket)(struct hv_device *dev, void *buf, u32 buflen, + u32 *BufferActualLen, u64 *RequestId); + int (*RecvPacketRaw)(struct hv_device *dev, void *buf, u32 buflen, + u32 *BufferActualLen, u64 *RequestId); + int (*EstablishGpadl)(struct hv_device *dev, void *buf, u32 buflen, + u32 *GpadlHandle); + int (*TeardownGpadl)(struct hv_device *device, u32 GpadlHandle); + void (*GetInfo)(struct hv_device *dev, struct hv_device_info *devinfo); +}; + +/* Base driver object */ +struct hv_driver { + const char *name; + + /* the device type supported by this driver */ + struct hv_guid deviceType; + + int (*OnDeviceAdd)(struct hv_device *device, void *data); + int (*OnDeviceRemove)(struct hv_device *device); + void (*OnCleanup)(struct hv_driver *driver); + + struct vmbus_channel_interface VmbusChannelInterface; +}; + +/* Base device object */ +struct hv_device { + /* the driver for this device */ + struct hv_driver *Driver; + + char name[64]; + + /* the device type id of this device */ + struct hv_guid deviceType; + + /* the device instance id of this device */ + struct hv_guid deviceInstance; + + void *context; + + /* Device extension; */ + void *Extension; +}; + +/* Vmbus driver object */ +struct vmbus_driver { + /* !! Must be the 1st field !! */ + /* FIXME if ^, then someone is doing somthing stupid */ + struct hv_driver Base; + + /* Set by the caller */ + struct hv_device * (*OnChildDeviceCreate)(struct hv_guid *DeviceType, + struct hv_guid *DeviceInstance, + void *Context); + void (*OnChildDeviceDestroy)(struct hv_device *device); + int (*OnChildDeviceAdd)(struct hv_device *RootDevice, + struct hv_device *ChildDevice); + void (*OnChildDeviceRemove)(struct hv_device *device); + + /* Set by the callee */ + int (*OnIsr)(struct hv_driver *driver); + void (*OnMsgDpc)(struct hv_driver *driver); + void (*OnEventDpc)(struct hv_driver *driver); + void (*GetChannelOffers)(void); + + void (*GetChannelInterface)(struct vmbus_channel_interface *i); + void (*GetChannelInfo)(struct hv_device *dev, + struct hv_device_info *devinfo); +}; + +int VmbusInitialize(struct hv_driver *drv); + +#endif /* _VMBUS_API_H_ */ -- cgit v1.2.3 From 72daf320fb322dc200824e2be17e69553a53fc8a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:45:25 -0700 Subject: Staging: hv: rename VmbusPrivate.h to vmbus_private.h Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/VmbusPrivate.h | 134 --------------------------------- drivers/staging/hv/channel.c | 2 +- drivers/staging/hv/channel_interface.c | 2 +- drivers/staging/hv/channel_mgmt.c | 2 +- drivers/staging/hv/connection.c | 2 +- drivers/staging/hv/hv.c | 2 +- drivers/staging/hv/hv_utils.c | 2 +- drivers/staging/hv/vmbus.c | 2 +- drivers/staging/hv/vmbus_private.h | 134 +++++++++++++++++++++++++++++++++ 9 files changed, 141 insertions(+), 141 deletions(-) delete mode 100644 drivers/staging/hv/VmbusPrivate.h create mode 100644 drivers/staging/hv/vmbus_private.h (limited to 'drivers') diff --git a/drivers/staging/hv/VmbusPrivate.h b/drivers/staging/hv/VmbusPrivate.h deleted file mode 100644 index 588c667a7f6b..000000000000 --- a/drivers/staging/hv/VmbusPrivate.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ - - -#ifndef _VMBUS_PRIVATE_H_ -#define _VMBUS_PRIVATE_H_ - -#include "hv.h" -#include "vmbus_api.h" -#include "channel.h" -#include "channel_mgmt.h" -#include "channel_interface.h" -#include "ring_buffer.h" -#include - - -/* - * Maximum channels is determined by the size of the interrupt page - * which is PAGE_SIZE. 1/2 of PAGE_SIZE is for send endpoint interrupt - * and the other is receive endpoint interrupt - */ -#define MAX_NUM_CHANNELS ((PAGE_SIZE >> 1) << 3) /* 16348 channels */ - -/* The value here must be in multiple of 32 */ -/* TODO: Need to make this configurable */ -#define MAX_NUM_CHANNELS_SUPPORTED 256 - - -enum VMBUS_CONNECT_STATE { - Disconnected, - Connecting, - Connected, - Disconnecting -}; - -#define MAX_SIZE_CHANNEL_MESSAGE HV_MESSAGE_PAYLOAD_BYTE_COUNT - -struct VMBUS_CONNECTION { - enum VMBUS_CONNECT_STATE ConnectState; - - atomic_t NextGpadlHandle; - - /* - * Represents channel interrupts. Each bit position represents a - * channel. When a channel sends an interrupt via VMBUS, it finds its - * bit in the sendInterruptPage, set it and calls Hv to generate a port - * event. The other end receives the port event and parse the - * recvInterruptPage to see which bit is set - */ - void *InterruptPage; - void *SendInterruptPage; - void *RecvInterruptPage; - - /* - * 2 pages - 1st page for parent->child notification and 2nd - * is child->parent notification - */ - void *MonitorPages; - struct list_head ChannelMsgList; - spinlock_t channelmsg_lock; - - /* List of channels */ - struct list_head ChannelList; - spinlock_t channel_lock; - - struct workqueue_struct *WorkQueue; -}; - - -struct VMBUS_MSGINFO { - /* Bookkeeping stuff */ - struct list_head MsgListEntry; - - /* Synchronize the request/response if needed */ - struct osd_waitevent *WaitEvent; - - /* The message itself */ - unsigned char Msg[0]; -}; - - -extern struct VMBUS_CONNECTION gVmbusConnection; - -/* General vmbus interface */ - -struct hv_device *VmbusChildDeviceCreate(struct hv_guid *deviceType, - struct hv_guid *deviceInstance, - void *context); - -int VmbusChildDeviceAdd(struct hv_device *Device); - -void VmbusChildDeviceRemove(struct hv_device *Device); - -/* static void */ -/* VmbusChildDeviceDestroy( */ -/* struct hv_device *); */ - -struct vmbus_channel *GetChannelFromRelId(u32 relId); - - -/* Connection interface */ - -int VmbusConnect(void); - -int VmbusDisconnect(void); - -int VmbusPostMessage(void *buffer, size_t bufSize); - -int VmbusSetEvent(u32 childRelId); - -void VmbusOnEvents(void); - - -#endif /* _VMBUS_PRIVATE_H_ */ diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index eab7d16dd5ef..12c351e16360 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -24,7 +24,7 @@ #include #include "osd.h" #include "logging.h" -#include "VmbusPrivate.h" +#include "vmbus_private.h" /* Internal routines */ static int VmbusChannelCreateGpadlHeader( diff --git a/drivers/staging/hv/channel_interface.c b/drivers/staging/hv/channel_interface.c index 019b064f7cb3..d9f51ac75eaa 100644 --- a/drivers/staging/hv/channel_interface.c +++ b/drivers/staging/hv/channel_interface.c @@ -23,7 +23,7 @@ #include #include #include "osd.h" -#include "VmbusPrivate.h" +#include "vmbus_private.h" static int IVmbusChannelOpen(struct hv_device *device, u32 SendBufferSize, u32 RecvRingBufferSize, void *UserData, diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 369823013889..6877e8e7f71e 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -25,7 +25,7 @@ #include #include "osd.h" #include "logging.h" -#include "VmbusPrivate.h" +#include "vmbus_private.h" #include "utils.h" struct vmbus_channel_message_table_entry { diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index 3a01d3ca4ad0..e8824dadffc3 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -26,7 +26,7 @@ #include #include "osd.h" #include "logging.h" -#include "VmbusPrivate.h" +#include "vmbus_private.h" struct VMBUS_CONNECTION gVmbusConnection = { diff --git a/drivers/staging/hv/hv.c b/drivers/staging/hv/hv.c index 2418651772b8..6c77e64027f0 100644 --- a/drivers/staging/hv/hv.c +++ b/drivers/staging/hv/hv.c @@ -25,7 +25,7 @@ #include #include "osd.h" #include "logging.h" -#include "VmbusPrivate.h" +#include "vmbus_private.h" /* The one and only */ struct hv_context gHvContext = { diff --git a/drivers/staging/hv/hv_utils.c b/drivers/staging/hv/hv_utils.c index d6f6dfa03671..5ab1b06c4571 100644 --- a/drivers/staging/hv/hv_utils.c +++ b/drivers/staging/hv/hv_utils.c @@ -32,7 +32,7 @@ #include "VmbusChannelInterface.h" #include "VersionInfo.h" #include "channel.h" -#include "VmbusPrivate.h" +#include "vmbus_private.h" #include "vmbus_api.h" #include "utils.h" diff --git a/drivers/staging/hv/vmbus.c b/drivers/staging/hv/vmbus.c index 90b14beec3aa..296c38ff5a44 100644 --- a/drivers/staging/hv/vmbus.c +++ b/drivers/staging/hv/vmbus.c @@ -25,7 +25,7 @@ #include "osd.h" #include "logging.h" #include "VersionInfo.h" -#include "VmbusPrivate.h" +#include "vmbus_private.h" static const char *gDriverName = "vmbus"; diff --git a/drivers/staging/hv/vmbus_private.h b/drivers/staging/hv/vmbus_private.h new file mode 100644 index 000000000000..588c667a7f6b --- /dev/null +++ b/drivers/staging/hv/vmbus_private.h @@ -0,0 +1,134 @@ +/* + * + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + * + */ + + +#ifndef _VMBUS_PRIVATE_H_ +#define _VMBUS_PRIVATE_H_ + +#include "hv.h" +#include "vmbus_api.h" +#include "channel.h" +#include "channel_mgmt.h" +#include "channel_interface.h" +#include "ring_buffer.h" +#include + + +/* + * Maximum channels is determined by the size of the interrupt page + * which is PAGE_SIZE. 1/2 of PAGE_SIZE is for send endpoint interrupt + * and the other is receive endpoint interrupt + */ +#define MAX_NUM_CHANNELS ((PAGE_SIZE >> 1) << 3) /* 16348 channels */ + +/* The value here must be in multiple of 32 */ +/* TODO: Need to make this configurable */ +#define MAX_NUM_CHANNELS_SUPPORTED 256 + + +enum VMBUS_CONNECT_STATE { + Disconnected, + Connecting, + Connected, + Disconnecting +}; + +#define MAX_SIZE_CHANNEL_MESSAGE HV_MESSAGE_PAYLOAD_BYTE_COUNT + +struct VMBUS_CONNECTION { + enum VMBUS_CONNECT_STATE ConnectState; + + atomic_t NextGpadlHandle; + + /* + * Represents channel interrupts. Each bit position represents a + * channel. When a channel sends an interrupt via VMBUS, it finds its + * bit in the sendInterruptPage, set it and calls Hv to generate a port + * event. The other end receives the port event and parse the + * recvInterruptPage to see which bit is set + */ + void *InterruptPage; + void *SendInterruptPage; + void *RecvInterruptPage; + + /* + * 2 pages - 1st page for parent->child notification and 2nd + * is child->parent notification + */ + void *MonitorPages; + struct list_head ChannelMsgList; + spinlock_t channelmsg_lock; + + /* List of channels */ + struct list_head ChannelList; + spinlock_t channel_lock; + + struct workqueue_struct *WorkQueue; +}; + + +struct VMBUS_MSGINFO { + /* Bookkeeping stuff */ + struct list_head MsgListEntry; + + /* Synchronize the request/response if needed */ + struct osd_waitevent *WaitEvent; + + /* The message itself */ + unsigned char Msg[0]; +}; + + +extern struct VMBUS_CONNECTION gVmbusConnection; + +/* General vmbus interface */ + +struct hv_device *VmbusChildDeviceCreate(struct hv_guid *deviceType, + struct hv_guid *deviceInstance, + void *context); + +int VmbusChildDeviceAdd(struct hv_device *Device); + +void VmbusChildDeviceRemove(struct hv_device *Device); + +/* static void */ +/* VmbusChildDeviceDestroy( */ +/* struct hv_device *); */ + +struct vmbus_channel *GetChannelFromRelId(u32 relId); + + +/* Connection interface */ + +int VmbusConnect(void); + +int VmbusDisconnect(void); + +int VmbusPostMessage(void *buffer, size_t bufSize); + +int VmbusSetEvent(u32 childRelId); + +void VmbusOnEvents(void); + + +#endif /* _VMBUS_PRIVATE_H_ */ -- cgit v1.2.3 From 0e0ab5f5af2cea05a3f7526fb05585f5cbe8a106 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:47:13 -0700 Subject: Staging: hv: rename VmbusChannelInterface.h to vmbus_channel_interface.h Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/VmbusChannelInterface.h | 89 ---------------------------- drivers/staging/hv/channel_mgmt.h | 2 +- drivers/staging/hv/hv_utils.c | 2 +- drivers/staging/hv/netvsc.h | 2 +- drivers/staging/hv/vmbus_channel_interface.h | 89 ++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 92 deletions(-) delete mode 100644 drivers/staging/hv/VmbusChannelInterface.h create mode 100644 drivers/staging/hv/vmbus_channel_interface.h (limited to 'drivers') diff --git a/drivers/staging/hv/VmbusChannelInterface.h b/drivers/staging/hv/VmbusChannelInterface.h deleted file mode 100644 index 26742823748d..000000000000 --- a/drivers/staging/hv/VmbusChannelInterface.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ - -#ifndef __VMBUSCHANNELINTERFACE_H -#define __VMBUSCHANNELINTERFACE_H - -/* - * A revision number of vmbus that is used for ensuring both ends on a - * partition are using compatible versions. - */ -#define VMBUS_REVISION_NUMBER 13 - -/* Make maximum size of pipe payload of 16K */ -#define MAX_PIPE_DATA_PAYLOAD (sizeof(u8) * 16384) - -/* Define PipeMode values. */ -#define VMBUS_PIPE_TYPE_BYTE 0x00000000 -#define VMBUS_PIPE_TYPE_MESSAGE 0x00000004 - -/* The size of the user defined data buffer for non-pipe offers. */ -#define MAX_USER_DEFINED_BYTES 120 - -/* The size of the user defined data buffer for pipe offers. */ -#define MAX_PIPE_USER_DEFINED_BYTES 116 - -/* - * At the center of the Channel Management library is the Channel Offer. This - * struct contains the fundamental information about an offer. - */ -struct vmbus_channel_offer { - struct hv_guid InterfaceType; - struct hv_guid InterfaceInstance; - u64 InterruptLatencyIn100nsUnits; - u32 InterfaceRevision; - u32 ServerContextAreaSize; /* in bytes */ - u16 ChannelFlags; - u16 MmioMegabytes; /* in bytes * 1024 * 1024 */ - - union { - /* Non-pipes: The user has MAX_USER_DEFINED_BYTES bytes. */ - struct { - unsigned char UserDefined[MAX_USER_DEFINED_BYTES]; - } Standard; - - /* - * Pipes: - * The following sructure is an integrated pipe protocol, which - * is implemented on top of standard user-defined data. Pipe - * clients have MAX_PIPE_USER_DEFINED_BYTES left for their own - * use. - */ - struct { - u32 PipeMode; - unsigned char UserDefined[MAX_PIPE_USER_DEFINED_BYTES]; - } Pipe; - } u; - u32 Padding; -} __attribute__((packed)); - -/* Server Flags */ -#define VMBUS_CHANNEL_ENUMERATE_DEVICE_INTERFACE 1 -#define VMBUS_CHANNEL_SERVER_SUPPORTS_TRANSFER_PAGES 2 -#define VMBUS_CHANNEL_SERVER_SUPPORTS_GPADLS 4 -#define VMBUS_CHANNEL_NAMED_PIPE_MODE 0x10 -#define VMBUS_CHANNEL_LOOPBACK_OFFER 0x100 -#define VMBUS_CHANNEL_PARENT_OFFER 0x200 -#define VMBUS_CHANNEL_REQUEST_MONITORED_NOTIFICATION 0x400 - -#endif diff --git a/drivers/staging/hv/channel_mgmt.h b/drivers/staging/hv/channel_mgmt.h index 9219199d0e5a..b92282bc89b6 100644 --- a/drivers/staging/hv/channel_mgmt.h +++ b/drivers/staging/hv/channel_mgmt.h @@ -28,7 +28,7 @@ #include #include #include "ring_buffer.h" -#include "VmbusChannelInterface.h" +#include "vmbus_channel_interface.h" #include "VmbusPacketFormat.h" /* Version 1 messages */ diff --git a/drivers/staging/hv/hv_utils.c b/drivers/staging/hv/hv_utils.c index 5ab1b06c4571..ddda0d7deb2d 100644 --- a/drivers/staging/hv/hv_utils.c +++ b/drivers/staging/hv/hv_utils.c @@ -29,7 +29,7 @@ #include "osd.h" #include "vmbus.h" #include "VmbusPacketFormat.h" -#include "VmbusChannelInterface.h" +#include "vmbus_channel_interface.h" #include "VersionInfo.h" #include "channel.h" #include "vmbus_private.h" diff --git a/drivers/staging/hv/netvsc.h b/drivers/staging/hv/netvsc.h index 05d2ceb9e5e3..91b5c23ddc5d 100644 --- a/drivers/staging/hv/netvsc.h +++ b/drivers/staging/hv/netvsc.h @@ -27,7 +27,7 @@ #include #include "VmbusPacketFormat.h" -#include "VmbusChannelInterface.h" +#include "vmbus_channel_interface.h" #include "netvsc_api.h" diff --git a/drivers/staging/hv/vmbus_channel_interface.h b/drivers/staging/hv/vmbus_channel_interface.h new file mode 100644 index 000000000000..26742823748d --- /dev/null +++ b/drivers/staging/hv/vmbus_channel_interface.h @@ -0,0 +1,89 @@ +/* + * + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + * + */ + +#ifndef __VMBUSCHANNELINTERFACE_H +#define __VMBUSCHANNELINTERFACE_H + +/* + * A revision number of vmbus that is used for ensuring both ends on a + * partition are using compatible versions. + */ +#define VMBUS_REVISION_NUMBER 13 + +/* Make maximum size of pipe payload of 16K */ +#define MAX_PIPE_DATA_PAYLOAD (sizeof(u8) * 16384) + +/* Define PipeMode values. */ +#define VMBUS_PIPE_TYPE_BYTE 0x00000000 +#define VMBUS_PIPE_TYPE_MESSAGE 0x00000004 + +/* The size of the user defined data buffer for non-pipe offers. */ +#define MAX_USER_DEFINED_BYTES 120 + +/* The size of the user defined data buffer for pipe offers. */ +#define MAX_PIPE_USER_DEFINED_BYTES 116 + +/* + * At the center of the Channel Management library is the Channel Offer. This + * struct contains the fundamental information about an offer. + */ +struct vmbus_channel_offer { + struct hv_guid InterfaceType; + struct hv_guid InterfaceInstance; + u64 InterruptLatencyIn100nsUnits; + u32 InterfaceRevision; + u32 ServerContextAreaSize; /* in bytes */ + u16 ChannelFlags; + u16 MmioMegabytes; /* in bytes * 1024 * 1024 */ + + union { + /* Non-pipes: The user has MAX_USER_DEFINED_BYTES bytes. */ + struct { + unsigned char UserDefined[MAX_USER_DEFINED_BYTES]; + } Standard; + + /* + * Pipes: + * The following sructure is an integrated pipe protocol, which + * is implemented on top of standard user-defined data. Pipe + * clients have MAX_PIPE_USER_DEFINED_BYTES left for their own + * use. + */ + struct { + u32 PipeMode; + unsigned char UserDefined[MAX_PIPE_USER_DEFINED_BYTES]; + } Pipe; + } u; + u32 Padding; +} __attribute__((packed)); + +/* Server Flags */ +#define VMBUS_CHANNEL_ENUMERATE_DEVICE_INTERFACE 1 +#define VMBUS_CHANNEL_SERVER_SUPPORTS_TRANSFER_PAGES 2 +#define VMBUS_CHANNEL_SERVER_SUPPORTS_GPADLS 4 +#define VMBUS_CHANNEL_NAMED_PIPE_MODE 0x10 +#define VMBUS_CHANNEL_LOOPBACK_OFFER 0x100 +#define VMBUS_CHANNEL_PARENT_OFFER 0x200 +#define VMBUS_CHANNEL_REQUEST_MONITORED_NOTIFICATION 0x400 + +#endif -- cgit v1.2.3 From f8e5add2284b6373b3ba994c716a4792483e69eb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:50:11 -0700 Subject: Staging: hv: rename VmbusPacketFormat.h to vmbus_packet_format.h Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/VmbusPacketFormat.h | 161 ------------------------------- drivers/staging/hv/channel_mgmt.h | 2 +- drivers/staging/hv/hv_utils.c | 2 +- drivers/staging/hv/netvsc.h | 2 +- drivers/staging/hv/storvsc.c | 2 +- drivers/staging/hv/vmbus_packet_format.h | 161 +++++++++++++++++++++++++++++++ 6 files changed, 165 insertions(+), 165 deletions(-) delete mode 100644 drivers/staging/hv/VmbusPacketFormat.h create mode 100644 drivers/staging/hv/vmbus_packet_format.h (limited to 'drivers') diff --git a/drivers/staging/hv/VmbusPacketFormat.h b/drivers/staging/hv/VmbusPacketFormat.h deleted file mode 100644 index f9f6b4bf6fb1..000000000000 --- a/drivers/staging/hv/VmbusPacketFormat.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ - -#ifndef _VMBUSPACKETFORMAT_H_ -#define _VMBUSPACKETFORMAT_H_ - -struct vmpacket_descriptor { - u16 Type; - u16 DataOffset8; - u16 Length8; - u16 Flags; - u64 TransactionId; -} __attribute__((packed)); - -struct vmpacket_header { - u32 PreviousPacketStartOffset; - struct vmpacket_descriptor Descriptor; -} __attribute__((packed)); - -struct vmtransfer_page_range { - u32 ByteCount; - u32 ByteOffset; -} __attribute__((packed)); - -struct vmtransfer_page_packet_header { - struct vmpacket_descriptor d; - u16 TransferPageSetId; - bool SenderOwnsSet; - u8 Reserved; - u32 RangeCount; - struct vmtransfer_page_range Ranges[1]; -} __attribute__((packed)); - -struct vmgpadl_packet_header { - struct vmpacket_descriptor d; - u32 Gpadl; - u32 Reserved; -} __attribute__((packed)); - -struct vmadd_remove_transfer_page_set { - struct vmpacket_descriptor d; - u32 Gpadl; - u16 TransferPageSetId; - u16 Reserved; -} __attribute__((packed)); - -/* - * This structure defines a range in guest physical space that can be made to - * look virtually contiguous. - */ -struct gpa_range { - u32 ByteCount; - u32 ByteOffset; - u64 PfnArray[0]; -}; - -/* - * This is the format for an Establish Gpadl packet, which contains a handle by - * which this GPADL will be known and a set of GPA ranges associated with it. - * This can be converted to a MDL by the guest OS. If there are multiple GPA - * ranges, then the resulting MDL will be "chained," representing multiple VA - * ranges. - */ -struct vmestablish_gpadl { - struct vmpacket_descriptor d; - u32 Gpadl; - u32 RangeCount; - struct gpa_range Range[1]; -} __attribute__((packed)); - -/* - * This is the format for a Teardown Gpadl packet, which indicates that the - * GPADL handle in the Establish Gpadl packet will never be referenced again. - */ -struct vmteardown_gpadl { - struct vmpacket_descriptor d; - u32 Gpadl; - u32 Reserved; /* for alignment to a 8-byte boundary */ -} __attribute__((packed)); - -/* - * This is the format for a GPA-Direct packet, which contains a set of GPA - * ranges, in addition to commands and/or data. - */ -struct vmdata_gpa_direct { - struct vmpacket_descriptor d; - u32 Reserved; - u32 RangeCount; - struct gpa_range Range[1]; -} __attribute__((packed)); - -/* This is the format for a Additional Data Packet. */ -struct vmadditional_data { - struct vmpacket_descriptor d; - u64 TotalBytes; - u32 ByteOffset; - u32 ByteCount; - unsigned char Data[1]; -} __attribute__((packed)); - -union vmpacket_largest_possible_header { - struct vmpacket_descriptor SimpleHeader; - struct vmtransfer_page_packet_header TransferPageHeader; - struct vmgpadl_packet_header GpadlHeader; - struct vmadd_remove_transfer_page_set AddRemoveTransferPageHeader; - struct vmestablish_gpadl EstablishGpadlHeader; - struct vmteardown_gpadl TeardownGpadlHeader; - struct vmdata_gpa_direct DataGpaDirectHeader; -}; - -#define VMPACKET_DATA_START_ADDRESS(__packet) \ - (void *)(((unsigned char *)__packet) + \ - ((struct vmpacket_descriptor)__packet)->DataOffset8 * 8) - -#define VMPACKET_DATA_LENGTH(__packet) \ - ((((struct vmpacket_descriptor)__packet)->Length8 - \ - ((struct vmpacket_descriptor)__packet)->DataOffset8) * 8) - -#define VMPACKET_TRANSFER_MODE(__packet) \ - (((struct IMPACT)__packet)->Type) - -enum vmbus_packet_type { - VmbusPacketTypeInvalid = 0x0, - VmbusPacketTypeSynch = 0x1, - VmbusPacketTypeAddTransferPageSet = 0x2, - VmbusPacketTypeRemoveTransferPageSet = 0x3, - VmbusPacketTypeEstablishGpadl = 0x4, - VmbusPacketTypeTearDownGpadl = 0x5, - VmbusPacketTypeDataInBand = 0x6, - VmbusPacketTypeDataUsingTransferPages = 0x7, - VmbusPacketTypeDataUsingGpadl = 0x8, - VmbusPacketTypeDataUsingGpaDirect = 0x9, - VmbusPacketTypeCancelRequest = 0xa, - VmbusPacketTypeCompletion = 0xb, - VmbusPacketTypeDataUsingAdditionalPackets = 0xc, - VmbusPacketTypeAdditionalData = 0xd -}; - -#define VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED 1 - -#endif diff --git a/drivers/staging/hv/channel_mgmt.h b/drivers/staging/hv/channel_mgmt.h index b92282bc89b6..5908b81d3e9c 100644 --- a/drivers/staging/hv/channel_mgmt.h +++ b/drivers/staging/hv/channel_mgmt.h @@ -29,7 +29,7 @@ #include #include "ring_buffer.h" #include "vmbus_channel_interface.h" -#include "VmbusPacketFormat.h" +#include "vmbus_packet_format.h" /* Version 1 messages */ enum vmbus_channel_message_type { diff --git a/drivers/staging/hv/hv_utils.c b/drivers/staging/hv/hv_utils.c index ddda0d7deb2d..44d306c37646 100644 --- a/drivers/staging/hv/hv_utils.c +++ b/drivers/staging/hv/hv_utils.c @@ -28,7 +28,7 @@ #include "logging.h" #include "osd.h" #include "vmbus.h" -#include "VmbusPacketFormat.h" +#include "vmbus_packet_format.h" #include "vmbus_channel_interface.h" #include "VersionInfo.h" #include "channel.h" diff --git a/drivers/staging/hv/netvsc.h b/drivers/staging/hv/netvsc.h index 91b5c23ddc5d..c71dce5b3f7c 100644 --- a/drivers/staging/hv/netvsc.h +++ b/drivers/staging/hv/netvsc.h @@ -26,7 +26,7 @@ #define _NETVSC_H_ #include -#include "VmbusPacketFormat.h" +#include "vmbus_packet_format.h" #include "vmbus_channel_interface.h" #include "netvsc_api.h" diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 3a8b54f5e2a6..27a276e08ee9 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -26,7 +26,7 @@ #include "osd.h" #include "logging.h" #include "storvsc_api.h" -#include "VmbusPacketFormat.h" +#include "vmbus_packet_format.h" #include "vstorage.h" diff --git a/drivers/staging/hv/vmbus_packet_format.h b/drivers/staging/hv/vmbus_packet_format.h new file mode 100644 index 000000000000..f9f6b4bf6fb1 --- /dev/null +++ b/drivers/staging/hv/vmbus_packet_format.h @@ -0,0 +1,161 @@ +/* + * + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + * + */ + +#ifndef _VMBUSPACKETFORMAT_H_ +#define _VMBUSPACKETFORMAT_H_ + +struct vmpacket_descriptor { + u16 Type; + u16 DataOffset8; + u16 Length8; + u16 Flags; + u64 TransactionId; +} __attribute__((packed)); + +struct vmpacket_header { + u32 PreviousPacketStartOffset; + struct vmpacket_descriptor Descriptor; +} __attribute__((packed)); + +struct vmtransfer_page_range { + u32 ByteCount; + u32 ByteOffset; +} __attribute__((packed)); + +struct vmtransfer_page_packet_header { + struct vmpacket_descriptor d; + u16 TransferPageSetId; + bool SenderOwnsSet; + u8 Reserved; + u32 RangeCount; + struct vmtransfer_page_range Ranges[1]; +} __attribute__((packed)); + +struct vmgpadl_packet_header { + struct vmpacket_descriptor d; + u32 Gpadl; + u32 Reserved; +} __attribute__((packed)); + +struct vmadd_remove_transfer_page_set { + struct vmpacket_descriptor d; + u32 Gpadl; + u16 TransferPageSetId; + u16 Reserved; +} __attribute__((packed)); + +/* + * This structure defines a range in guest physical space that can be made to + * look virtually contiguous. + */ +struct gpa_range { + u32 ByteCount; + u32 ByteOffset; + u64 PfnArray[0]; +}; + +/* + * This is the format for an Establish Gpadl packet, which contains a handle by + * which this GPADL will be known and a set of GPA ranges associated with it. + * This can be converted to a MDL by the guest OS. If there are multiple GPA + * ranges, then the resulting MDL will be "chained," representing multiple VA + * ranges. + */ +struct vmestablish_gpadl { + struct vmpacket_descriptor d; + u32 Gpadl; + u32 RangeCount; + struct gpa_range Range[1]; +} __attribute__((packed)); + +/* + * This is the format for a Teardown Gpadl packet, which indicates that the + * GPADL handle in the Establish Gpadl packet will never be referenced again. + */ +struct vmteardown_gpadl { + struct vmpacket_descriptor d; + u32 Gpadl; + u32 Reserved; /* for alignment to a 8-byte boundary */ +} __attribute__((packed)); + +/* + * This is the format for a GPA-Direct packet, which contains a set of GPA + * ranges, in addition to commands and/or data. + */ +struct vmdata_gpa_direct { + struct vmpacket_descriptor d; + u32 Reserved; + u32 RangeCount; + struct gpa_range Range[1]; +} __attribute__((packed)); + +/* This is the format for a Additional Data Packet. */ +struct vmadditional_data { + struct vmpacket_descriptor d; + u64 TotalBytes; + u32 ByteOffset; + u32 ByteCount; + unsigned char Data[1]; +} __attribute__((packed)); + +union vmpacket_largest_possible_header { + struct vmpacket_descriptor SimpleHeader; + struct vmtransfer_page_packet_header TransferPageHeader; + struct vmgpadl_packet_header GpadlHeader; + struct vmadd_remove_transfer_page_set AddRemoveTransferPageHeader; + struct vmestablish_gpadl EstablishGpadlHeader; + struct vmteardown_gpadl TeardownGpadlHeader; + struct vmdata_gpa_direct DataGpaDirectHeader; +}; + +#define VMPACKET_DATA_START_ADDRESS(__packet) \ + (void *)(((unsigned char *)__packet) + \ + ((struct vmpacket_descriptor)__packet)->DataOffset8 * 8) + +#define VMPACKET_DATA_LENGTH(__packet) \ + ((((struct vmpacket_descriptor)__packet)->Length8 - \ + ((struct vmpacket_descriptor)__packet)->DataOffset8) * 8) + +#define VMPACKET_TRANSFER_MODE(__packet) \ + (((struct IMPACT)__packet)->Type) + +enum vmbus_packet_type { + VmbusPacketTypeInvalid = 0x0, + VmbusPacketTypeSynch = 0x1, + VmbusPacketTypeAddTransferPageSet = 0x2, + VmbusPacketTypeRemoveTransferPageSet = 0x3, + VmbusPacketTypeEstablishGpadl = 0x4, + VmbusPacketTypeTearDownGpadl = 0x5, + VmbusPacketTypeDataInBand = 0x6, + VmbusPacketTypeDataUsingTransferPages = 0x7, + VmbusPacketTypeDataUsingGpadl = 0x8, + VmbusPacketTypeDataUsingGpaDirect = 0x9, + VmbusPacketTypeCancelRequest = 0xa, + VmbusPacketTypeCompletion = 0xb, + VmbusPacketTypeDataUsingAdditionalPackets = 0xc, + VmbusPacketTypeAdditionalData = 0xd +}; + +#define VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED 1 + +#endif -- cgit v1.2.3 From 2d82f6c734f411e5da9c60dace4140d8d029bb12 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 22:52:28 -0700 Subject: Staging: hv: rename VersionInfo.h to version_info.h The great renaming of the hv code is now complete. Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/VersionInfo.h | 47 --------------------------------------- drivers/staging/hv/blkvsc_drv.c | 2 +- drivers/staging/hv/hv_utils.c | 2 +- drivers/staging/hv/netvsc_drv.c | 2 +- drivers/staging/hv/storvsc_drv.c | 2 +- drivers/staging/hv/version_info.h | 47 +++++++++++++++++++++++++++++++++++++++ drivers/staging/hv/vmbus.c | 2 +- drivers/staging/hv/vmbus_drv.c | 2 +- 8 files changed, 53 insertions(+), 53 deletions(-) delete mode 100644 drivers/staging/hv/VersionInfo.h create mode 100644 drivers/staging/hv/version_info.h (limited to 'drivers') diff --git a/drivers/staging/hv/VersionInfo.h b/drivers/staging/hv/VersionInfo.h deleted file mode 100644 index 82e74b1ab150..000000000000 --- a/drivers/staging/hv/VersionInfo.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ - -#ifndef __HV_VERSION_INFO -#define __HV_VERSION_INFO - -/* - * We use the same version numbering for all Hyper-V modules. - * - * Definition of versioning is as follows; - * - * Major Number Changes for these scenarios; - * 1. When a new version of Windows Hyper-V - * is released. - * 2. A Major change has occurred in the - * Linux IC's. - * (For example the merge for the first time - * into the kernel) Every time the Major Number - * changes, the Revision number is reset to 0. - * Minor Number Changes when new functionality is added - * to the Linux IC's that is not a bug fix. - * - */ -#define HV_DRV_VERSION "3.0" - - -#endif diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 3e7c75e0b149..a81040f74e99 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -32,7 +32,7 @@ #include #include "osd.h" #include "logging.h" -#include "VersionInfo.h" +#include "version_info.h" #include "vmbus.h" #include "storvsc_api.h" diff --git a/drivers/staging/hv/hv_utils.c b/drivers/staging/hv/hv_utils.c index 44d306c37646..8f1d3ba7e098 100644 --- a/drivers/staging/hv/hv_utils.c +++ b/drivers/staging/hv/hv_utils.c @@ -30,7 +30,7 @@ #include "vmbus.h" #include "vmbus_packet_format.h" #include "vmbus_channel_interface.h" -#include "VersionInfo.h" +#include "version_info.h" #include "channel.h" #include "vmbus_private.h" #include "vmbus_api.h" diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 3a6fe2512828..30c946c133c2 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -36,7 +36,7 @@ #include #include "osd.h" #include "logging.h" -#include "VersionInfo.h" +#include "version_info.h" #include "vmbus.h" #include "netvsc_api.h" diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 56b659bda370..6a2014639d22 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -33,7 +33,7 @@ #include #include "osd.h" #include "logging.h" -#include "VersionInfo.h" +#include "version_info.h" #include "vmbus.h" #include "storvsc_api.h" diff --git a/drivers/staging/hv/version_info.h b/drivers/staging/hv/version_info.h new file mode 100644 index 000000000000..82e74b1ab150 --- /dev/null +++ b/drivers/staging/hv/version_info.h @@ -0,0 +1,47 @@ +/* + * + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang + * Hank Janssen + * + */ + +#ifndef __HV_VERSION_INFO +#define __HV_VERSION_INFO + +/* + * We use the same version numbering for all Hyper-V modules. + * + * Definition of versioning is as follows; + * + * Major Number Changes for these scenarios; + * 1. When a new version of Windows Hyper-V + * is released. + * 2. A Major change has occurred in the + * Linux IC's. + * (For example the merge for the first time + * into the kernel) Every time the Major Number + * changes, the Revision number is reset to 0. + * Minor Number Changes when new functionality is added + * to the Linux IC's that is not a bug fix. + * + */ +#define HV_DRV_VERSION "3.0" + + +#endif diff --git a/drivers/staging/hv/vmbus.c b/drivers/staging/hv/vmbus.c index 296c38ff5a44..0a9d8459db0c 100644 --- a/drivers/staging/hv/vmbus.c +++ b/drivers/staging/hv/vmbus.c @@ -24,7 +24,7 @@ #include #include "osd.h" #include "logging.h" -#include "VersionInfo.h" +#include "version_info.h" #include "vmbus_private.h" static const char *gDriverName = "vmbus"; diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index a715b3db87ce..c21731a12ca7 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -27,7 +27,7 @@ #include #include #include -#include "VersionInfo.h" +#include "version_info.h" #include "osd.h" #include "logging.h" #include "vmbus.h" -- cgit v1.2.3 From af449f924c95fa8d4f57c9b71e9b104a5079fa33 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 23:09:12 -0700 Subject: Staging: arlan: delete the driver It has sat in the staging directory since October of 2009, and no one has stepped up to take it over, so odds are, no one cares about it anymore. So, it is now deleted as scheduled, and documented in the TODO file. Cc: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/arlan/Kconfig | 15 - drivers/staging/arlan/Makefile | 3 - drivers/staging/arlan/TODO | 7 - drivers/staging/arlan/arlan-main.c | 1765 ------------------------------------ drivers/staging/arlan/arlan-proc.c | 1199 ------------------------ drivers/staging/arlan/arlan.h | 535 ----------- 8 files changed, 3527 deletions(-) delete mode 100644 drivers/staging/arlan/Kconfig delete mode 100644 drivers/staging/arlan/Makefile delete mode 100644 drivers/staging/arlan/TODO delete mode 100644 drivers/staging/arlan/arlan-main.c delete mode 100644 drivers/staging/arlan/arlan-proc.c delete mode 100644 drivers/staging/arlan/arlan.h (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 6b00e15a3713..8bf839ea05f5 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -127,8 +127,6 @@ source "drivers/staging/samsung-laptop/Kconfig" source "drivers/staging/strip/Kconfig" -source "drivers/staging/arlan/Kconfig" - source "drivers/staging/wavelan/Kconfig" source "drivers/staging/netwave/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index e825647afda7..b2747068fff0 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -44,7 +44,6 @@ obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/ obj-$(CONFIG_BATMAN_ADV) += batman-adv/ obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop/ obj-$(CONFIG_STRIP) += strip/ -obj-$(CONFIG_ARLAN) += arlan/ obj-$(CONFIG_WAVELAN) += wavelan/ obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan/ obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/ diff --git a/drivers/staging/arlan/Kconfig b/drivers/staging/arlan/Kconfig deleted file mode 100644 index 5e42b81f97b0..000000000000 --- a/drivers/staging/arlan/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -config ARLAN - tristate "Aironet Arlan 655 & IC2200 DS support" - depends on ISA && !64BIT && WLAN - select WIRELESS_EXT - ---help--- - Aironet makes Arlan, a class of wireless LAN adapters. These use the - www.Telxon.com chip, which is also used on several similar cards. - This driver is tested on the 655 and IC2200 series cards. Look at - for the latest information. - - The driver is built as two modules, arlan and arlan-proc. The latter - is the /proc interface and is not needed most of time. - - On some computers the card ends up in non-valid state after some - time. Use a ping-reset script to clear it. diff --git a/drivers/staging/arlan/Makefile b/drivers/staging/arlan/Makefile deleted file mode 100644 index 5a84d4402f21..000000000000 --- a/drivers/staging/arlan/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_ARLAN) += arlan.o - -arlan-objs := arlan-main.o arlan-proc.o diff --git a/drivers/staging/arlan/TODO b/drivers/staging/arlan/TODO deleted file mode 100644 index 9bd15a2f6d9e..000000000000 --- a/drivers/staging/arlan/TODO +++ /dev/null @@ -1,7 +0,0 @@ -TODO: - - step up and maintain this driver to ensure that it continues - to work. Having the hardware for this is pretty much a - requirement. If this does not happen, the will be removed in - the 2.6.35 kernel release. - -Please send patches to Greg Kroah-Hartman . diff --git a/drivers/staging/arlan/arlan-main.c b/drivers/staging/arlan/arlan-main.c deleted file mode 100644 index 301b979d0437..000000000000 --- a/drivers/staging/arlan/arlan-main.c +++ /dev/null @@ -1,1765 +0,0 @@ -/* - * Copyright (C) 1997 Cullen Jennings - * Copyright (C) 1998 Elmer Joandiu, elmer@ylenurme.ee - * GNU General Public License applies - * This module provides support for the Arlan 655 card made by Aironet - */ - -#include "arlan.h" - -#if BITS_PER_LONG != 32 -# error FIXME: this driver requires a 32-bit platform -#endif - -static const char *arlan_version = "C.Jennigs 97 & Elmer.Joandi@ut.ee Oct'98, http://www.ylenurme.ee/~elmer/655/"; - -struct net_device *arlan_device[MAX_ARLANS]; - -static int SID = SIDUNKNOWN; -static int radioNodeId = radioNodeIdUNKNOWN; -static char encryptionKey[12] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}; -int arlan_debug = debugUNKNOWN; -static int spreadingCode = spreadingCodeUNKNOWN; -static int channelNumber = channelNumberUNKNOWN; -static int channelSet = channelSetUNKNOWN; -static int systemId = systemIdUNKNOWN; -static int registrationMode = registrationModeUNKNOWN; -static int keyStart; -static int tx_delay_ms; -static int retries = 5; -static int tx_queue_len = 1; -static int arlan_EEPROM_bad; - -#ifdef ARLAN_DEBUGGING - -static int testMemory = testMemoryUNKNOWN; -static int irq = irqUNKNOWN; -static int txScrambled = 1; -static int mdebug; - -module_param(irq, int, 0); -module_param(mdebug, int, 0); -module_param(testMemory, int, 0); -module_param(txScrambled, int, 0); -MODULE_PARM_DESC(irq, "(unused)"); -MODULE_PARM_DESC(testMemory, "(unused)"); -MODULE_PARM_DESC(mdebug, "Arlan multicast debugging (0-1)"); -#endif - -module_param_named(debug, arlan_debug, int, 0); -module_param(spreadingCode, int, 0); -module_param(channelNumber, int, 0); -module_param(channelSet, int, 0); -module_param(systemId, int, 0); -module_param(registrationMode, int, 0); -module_param(radioNodeId, int, 0); -module_param(SID, int, 0); -module_param(keyStart, int, 0); -module_param(tx_delay_ms, int, 0); -module_param(retries, int, 0); -module_param(tx_queue_len, int, 0); -module_param_named(EEPROM_bad, arlan_EEPROM_bad, int, 0); -MODULE_PARM_DESC(debug, "Arlan debug enable (0-1)"); -MODULE_PARM_DESC(retries, "Arlan maximum packet retransmisions"); -#ifdef ARLAN_ENTRY_EXIT_DEBUGGING -static int arlan_entry_debug; -static int arlan_exit_debug; -static int arlan_entry_and_exit_debug; -module_param_named(entry_debug, arlan_entry_debug, int, 0); -module_param_named(exit_debug, arlan_exit_debug, int, 0); -module_param_named(entry_and_exit_debug, arlan_entry_and_exit_debug, int, 0); -MODULE_PARM_DESC(entry_debug, "Arlan driver function entry debugging"); -MODULE_PARM_DESC(exit_debug, "Arlan driver function exit debugging"); -MODULE_PARM_DESC(entry_and_exit_debug, "Arlan driver function entry and exit debugging"); -#endif - -struct arlan_conf_stru arlan_conf[MAX_ARLANS]; -static int arlans_found; - -static int arlan_open(struct net_device *dev); -static netdev_tx_t arlan_tx(struct sk_buff *skb, struct net_device *dev); -static irqreturn_t arlan_interrupt(int irq, void *dev_id); -static int arlan_close(struct net_device *dev); -static struct net_device_stats *arlan_statistics(struct net_device *dev); -static void arlan_set_multicast(struct net_device *dev); -static int arlan_hw_tx(struct net_device *dev, char *buf, int length); -static int arlan_hw_config(struct net_device *dev); -static void arlan_tx_done_interrupt(struct net_device *dev, int status); -static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short, u_short); -static void arlan_process_interrupt(struct net_device *dev); -static void arlan_tx_timeout(struct net_device *dev); - -static inline long us2ticks(int us) -{ - return us * (1000000 / HZ); -} - - -#ifdef ARLAN_ENTRY_EXIT_DEBUGGING -#define ARLAN_DEBUG_ENTRY(name) \ - {\ - struct timeval timev;\ - do_gettimeofday(&timev);\ - if (arlan_entry_debug || arlan_entry_and_exit_debug)\ - printk("--->>>" name " %ld " "\n", ((long int) timev.tv_sec * 1000000 + timev.tv_usec));\ - } -#define ARLAN_DEBUG_EXIT(name) \ - {\ - struct timeval timev;\ - do_gettimeofday(&timev);\ - if (arlan_exit_debug || arlan_entry_and_exit_debug)\ - printk("<<<---" name " %ld " "\n", ((long int) timev.tv_sec * 1000000 + timev.tv_usec));\ - } -#else -#define ARLAN_DEBUG_ENTRY(name) -#define ARLAN_DEBUG_EXIT(name) -#endif - - -#define arlan_interrupt_ack(dev)\ - clearClearInterrupt(dev);\ - setClearInterrupt(dev); - -static inline int arlan_drop_tx(struct net_device *dev) -{ - struct arlan_private *priv = netdev_priv(dev); - - dev->stats.tx_errors++; - if (priv->Conf->tx_delay_ms) - priv->tx_done_delayed = jiffies + priv->Conf->tx_delay_ms * HZ / 1000 + 1; - else { - priv->waiting_command_mask &= ~ARLAN_COMMAND_TX; - TXHEAD(dev).offset = 0; - TXTAIL(dev).offset = 0; - priv->txLast = 0; - priv->bad = 0; - if (!priv->under_reset && !priv->under_config) - netif_wake_queue(dev); - } - return 1; -} - - -int arlan_command(struct net_device *dev, int command_p) -{ - struct arlan_private *priv = netdev_priv(dev); - volatile struct arlan_shmem __iomem *arlan = priv->card; - struct arlan_conf_stru *conf = priv->Conf; - int udelayed = 0; - int i = 0; - unsigned long flags; - - ARLAN_DEBUG_ENTRY("arlan_command"); - - if (priv->card_polling_interval) - priv->card_polling_interval = 1; - - if (arlan_debug & ARLAN_DEBUG_CHAIN_LOCKS) - printk(KERN_DEBUG "arlan_command, %lx commandByte %x waiting %lx incoming %x\n", - jiffies, READSHMB(arlan->commandByte), - priv->waiting_command_mask, command_p); - - priv->waiting_command_mask |= command_p; - - if (priv->waiting_command_mask & ARLAN_COMMAND_RESET) - if (time_after(jiffies, priv->lastReset + 5 * HZ)) - priv->waiting_command_mask &= ~ARLAN_COMMAND_RESET; - - if (priv->waiting_command_mask & ARLAN_COMMAND_INT_ACK) { - arlan_interrupt_ack(dev); - priv->waiting_command_mask &= ~ARLAN_COMMAND_INT_ACK; - } - if (priv->waiting_command_mask & ARLAN_COMMAND_INT_ENABLE) { - setInterruptEnable(dev); - priv->waiting_command_mask &= ~ARLAN_COMMAND_INT_ENABLE; - } - - /* Card access serializing lock */ - spin_lock_irqsave(&priv->lock, flags); - - /* Check cards status and waiting */ - - if (priv->waiting_command_mask & (ARLAN_COMMAND_LONG_WAIT_NOW | ARLAN_COMMAND_WAIT_NOW)) { - while (priv->waiting_command_mask & (ARLAN_COMMAND_LONG_WAIT_NOW | ARLAN_COMMAND_WAIT_NOW)) { - if (READSHMB(arlan->resetFlag) || - READSHMB(arlan->commandByte)) /* || - (readControlRegister(dev) & ARLAN_ACCESS)) - */ - udelay(40); - else - priv->waiting_command_mask &= ~(ARLAN_COMMAND_LONG_WAIT_NOW | ARLAN_COMMAND_WAIT_NOW); - - udelayed++; - - if (priv->waiting_command_mask & ARLAN_COMMAND_LONG_WAIT_NOW) { - if (udelayed * 40 > 1000000) { - printk(KERN_ERR "%s long wait too long\n", dev->name); - priv->waiting_command_mask |= ARLAN_COMMAND_RESET; - break; - } - } else if (priv->waiting_command_mask & ARLAN_COMMAND_WAIT_NOW) { - if (udelayed * 40 > 1000) { - printk(KERN_ERR "%s short wait too long\n", dev->name); - goto bad_end; - } - } - } - } else { - i = 0; - while ((READSHMB(arlan->resetFlag) || - READSHMB(arlan->commandByte)) && - conf->pre_Command_Wait > (i++) * 10) - udelay(10); - - - if ((READSHMB(arlan->resetFlag) || - READSHMB(arlan->commandByte)) && - !(priv->waiting_command_mask & ARLAN_COMMAND_RESET)) - goto card_busy_end; - } - if (priv->waiting_command_mask & ARLAN_COMMAND_RESET) - priv->under_reset = 1; - if (priv->waiting_command_mask & ARLAN_COMMAND_CONF) - priv->under_config = 1; - - /* Issuing command */ - arlan_lock_card_access(dev); - if (priv->waiting_command_mask & ARLAN_COMMAND_POWERUP) { - /* if (readControlRegister(dev) & (ARLAN_ACCESS && ARLAN_POWER)) */ - setPowerOn(dev); - arlan_interrupt_lancpu(dev); - priv->waiting_command_mask &= ~ARLAN_COMMAND_POWERUP; - priv->waiting_command_mask |= ARLAN_COMMAND_RESET; - priv->card_polling_interval = HZ / 10; - } else if (priv->waiting_command_mask & ARLAN_COMMAND_ACTIVATE) { - WRITESHMB(arlan->commandByte, ARLAN_COM_ACTIVATE); - arlan_interrupt_lancpu(dev); - priv->waiting_command_mask &= ~ARLAN_COMMAND_ACTIVATE; - priv->card_polling_interval = HZ / 10; - } else if (priv->waiting_command_mask & ARLAN_COMMAND_RX_ABORT) { - if (priv->rx_command_given) { - WRITESHMB(arlan->commandByte, ARLAN_COM_RX_ABORT); - arlan_interrupt_lancpu(dev); - priv->rx_command_given = 0; - } - priv->waiting_command_mask &= ~ARLAN_COMMAND_RX_ABORT; - priv->card_polling_interval = 1; - } else if (priv->waiting_command_mask & ARLAN_COMMAND_TX_ABORT) { - if (priv->tx_command_given) { - WRITESHMB(arlan->commandByte, ARLAN_COM_TX_ABORT); - arlan_interrupt_lancpu(dev); - priv->tx_command_given = 0; - } - priv->waiting_command_mask &= ~ARLAN_COMMAND_TX_ABORT; - priv->card_polling_interval = 1; - } else if (priv->waiting_command_mask & ARLAN_COMMAND_RESET) { - priv->under_reset = 1; - netif_stop_queue(dev); - - arlan_drop_tx(dev); - if (priv->tx_command_given || priv->rx_command_given) - printk(KERN_ERR "%s: Reset under tx or rx command\n", dev->name); - - netif_stop_queue(dev); - if (arlan_debug & ARLAN_DEBUG_RESET) - printk(KERN_ERR "%s: Doing chip reset\n", dev->name); - priv->lastReset = jiffies; - WRITESHM(arlan->commandByte, 0, u_char); - /* hold card in reset state */ - setHardwareReset(dev); - /* set reset flag and then release reset */ - WRITESHM(arlan->resetFlag, 0xff, u_char); - clearChannelAttention(dev); - clearHardwareReset(dev); - priv->card_polling_interval = HZ / 4; - priv->waiting_command_mask &= ~ARLAN_COMMAND_RESET; - priv->waiting_command_mask |= ARLAN_COMMAND_INT_RACK; - /* priv->waiting_command_mask |= ARLAN_COMMAND_INT_RENABLE; */ - /* priv->waiting_command_mask |= ARLAN_COMMAND_RX; */ - } else if (priv->waiting_command_mask & ARLAN_COMMAND_INT_RACK) { - clearHardwareReset(dev); - clearClearInterrupt(dev); - setClearInterrupt(dev); - setInterruptEnable(dev); - priv->waiting_command_mask &= ~ARLAN_COMMAND_INT_RACK; - priv->waiting_command_mask |= ARLAN_COMMAND_CONF; - priv->under_config = 1; - priv->under_reset = 0; - } else if (priv->waiting_command_mask & ARLAN_COMMAND_INT_RENABLE) { - setInterruptEnable(dev); - priv->waiting_command_mask &= ~ARLAN_COMMAND_INT_RENABLE; - } else if (priv->waiting_command_mask & ARLAN_COMMAND_CONF) { - if (priv->tx_command_given || priv->rx_command_given) - printk(KERN_ERR "%s: Reset under tx or rx command\n", dev->name); - - arlan_drop_tx(dev); - setInterruptEnable(dev); - arlan_hw_config(dev); - arlan_interrupt_lancpu(dev); - priv->waiting_command_mask &= ~ARLAN_COMMAND_CONF; - priv->card_polling_interval = HZ / 10; - /* priv->waiting_command_mask |= ARLAN_COMMAND_INT_RACK; */ - /* priv->waiting_command_mask |= ARLAN_COMMAND_INT_ENABLE; */ - priv->waiting_command_mask |= ARLAN_COMMAND_CONF_WAIT; - } else if (priv->waiting_command_mask & ARLAN_COMMAND_CONF_WAIT) { - if (READSHMB(arlan->configuredStatusFlag) != 0 && - READSHMB(arlan->diagnosticInfo) == 0xff) { - priv->waiting_command_mask &= ~ARLAN_COMMAND_CONF_WAIT; - priv->waiting_command_mask |= ARLAN_COMMAND_RX; - priv->waiting_command_mask |= ARLAN_COMMAND_TBUSY_CLEAR; - priv->card_polling_interval = HZ / 10; - priv->tx_command_given = 0; - priv->under_config = 0; - } else { - priv->card_polling_interval = 1; - if (arlan_debug & ARLAN_DEBUG_TIMING) - printk(KERN_ERR "configure delayed\n"); - } - } else if (priv->waiting_command_mask & ARLAN_COMMAND_RX) { - if (!registrationBad(dev)) { - setInterruptEnable(dev); - memset_io(arlan->commandParameter, 0, 0xf); - WRITESHMB(arlan->commandByte, ARLAN_COM_INT | ARLAN_COM_RX_ENABLE); - WRITESHMB(arlan->commandParameter[0], conf->rxParameter); - arlan_interrupt_lancpu(dev); - priv->rx_command_given = 0; /* mnjah, bad */ - priv->waiting_command_mask &= ~ARLAN_COMMAND_RX; - priv->card_polling_interval = 1; - } else - priv->card_polling_interval = 2; - } else if (priv->waiting_command_mask & ARLAN_COMMAND_TBUSY_CLEAR) { - if (!registrationBad(dev) && - (netif_queue_stopped(dev) || !netif_running(dev))) { - priv->waiting_command_mask &= ~ARLAN_COMMAND_TBUSY_CLEAR; - netif_wake_queue(dev); - } - } else if (priv->waiting_command_mask & ARLAN_COMMAND_TX) { - if (!test_and_set_bit(0, (void *) &priv->tx_command_given)) { - if (time_after(jiffies, - priv->tx_last_sent + us2ticks(conf->rx_tweak1)) - || time_before(jiffies, - priv->last_rx_int_ack_time + us2ticks(conf->rx_tweak2))) { - setInterruptEnable(dev); - memset_io(arlan->commandParameter, 0, 0xf); - WRITESHMB(arlan->commandByte, ARLAN_COM_TX_ENABLE | ARLAN_COM_INT); - memcpy_toio(arlan->commandParameter, &TXLAST(dev), 14); - /* for ( i=1 ; i < 15 ; i++) printk("%02x:",READSHMB(arlan->commandParameter[i])); */ - priv->tx_last_sent = jiffies; - arlan_interrupt_lancpu(dev); - priv->tx_command_given = 1; - priv->waiting_command_mask &= ~ARLAN_COMMAND_TX; - priv->card_polling_interval = 1; - } else { - priv->tx_command_given = 0; - priv->card_polling_interval = 1; - } - } else if (arlan_debug & ARLAN_DEBUG_CHAIN_LOCKS) - printk(KERN_ERR "tx command when tx chain locked\n"); - } else if (priv->waiting_command_mask & ARLAN_COMMAND_NOOPINT) { - { - WRITESHMB(arlan->commandByte, ARLAN_COM_NOP | ARLAN_COM_INT); - } - arlan_interrupt_lancpu(dev); - priv->waiting_command_mask &= ~ARLAN_COMMAND_NOOPINT; - priv->card_polling_interval = HZ / 3; - } else if (priv->waiting_command_mask & ARLAN_COMMAND_NOOP) { - WRITESHMB(arlan->commandByte, ARLAN_COM_NOP); - arlan_interrupt_lancpu(dev); - priv->waiting_command_mask &= ~ARLAN_COMMAND_NOOP; - priv->card_polling_interval = HZ / 3; - } else if (priv->waiting_command_mask & ARLAN_COMMAND_SLOW_POLL) { - WRITESHMB(arlan->commandByte, ARLAN_COM_GOTO_SLOW_POLL); - arlan_interrupt_lancpu(dev); - priv->waiting_command_mask &= ~ARLAN_COMMAND_SLOW_POLL; - priv->card_polling_interval = HZ / 3; - } else if (priv->waiting_command_mask & ARLAN_COMMAND_POWERDOWN) { - setPowerOff(dev); - if (arlan_debug & ARLAN_DEBUG_CARD_STATE) - printk(KERN_WARNING "%s: Arlan Going Standby\n", dev->name); - priv->waiting_command_mask &= ~ARLAN_COMMAND_POWERDOWN; - priv->card_polling_interval = 3 * HZ; - } - arlan_unlock_card_access(dev); - for (i = 0; READSHMB(arlan->commandByte) && i < 20; i++) - udelay(10); - if (READSHMB(arlan->commandByte)) - if (arlan_debug & ARLAN_DEBUG_CARD_STATE) - printk(KERN_ERR "card busy leaving command %lx\n", priv->waiting_command_mask); - - spin_unlock_irqrestore(&priv->lock, flags); - ARLAN_DEBUG_EXIT("arlan_command"); - priv->last_command_buff_free_time = jiffies; - return 0; - -card_busy_end: - if (time_after(jiffies, priv->last_command_buff_free_time + HZ)) - priv->waiting_command_mask |= ARLAN_COMMAND_CLEAN_AND_RESET; - - if (arlan_debug & ARLAN_DEBUG_CARD_STATE) - printk(KERN_ERR "%s arlan_command card busy end\n", dev->name); - spin_unlock_irqrestore(&priv->lock, flags); - ARLAN_DEBUG_EXIT("arlan_command"); - return 1; - -bad_end: - printk(KERN_ERR "%s arlan_command bad end\n", dev->name); - - spin_unlock_irqrestore(&priv->lock, flags); - ARLAN_DEBUG_EXIT("arlan_command"); - - return -1; -} - -static inline void arlan_command_process(struct net_device *dev) -{ - struct arlan_private *priv = netdev_priv(dev); - - int times = 0; - while (priv->waiting_command_mask && times < 8) { - if (priv->waiting_command_mask) { - if (arlan_command(dev, 0)) - break; - times++; - } - /* if long command, we won't repeat trying */ ; - if (priv->card_polling_interval > 1) - break; - times++; - } -} - - -static inline void arlan_retransmit_now(struct net_device *dev) -{ - struct arlan_private *priv = netdev_priv(dev); - - - ARLAN_DEBUG_ENTRY("arlan_retransmit_now"); - if (TXLAST(dev).offset == 0) { - if (TXHEAD(dev).offset) { - priv->txLast = 0; - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_DEBUG "TX buff switch to head\n"); - } else if (TXTAIL(dev).offset) { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_DEBUG "TX buff switch to tail\n"); - priv->txLast = 1; - } else - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_ERR "ReTransmit buff empty"); - netif_wake_queue(dev); - return; - } - arlan_command(dev, ARLAN_COMMAND_TX); - - priv->Conf->driverRetransmissions++; - priv->retransmissions++; - - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk("Retransmit %d bytes\n", TXLAST(dev).length); - - ARLAN_DEBUG_EXIT("arlan_retransmit_now"); -} - - - -static void arlan_registration_timer(unsigned long data) -{ - struct net_device *dev = (struct net_device *) data; - struct arlan_private *priv = netdev_priv(dev); - int bh_mark_needed = 0; - int next_tick = 1; - long lostTime = ((long)jiffies - (long)priv->registrationLastSeen) - * (1000/HZ); - - if (registrationBad(dev)) { - priv->registrationLostCount++; - if (lostTime > 7000 && lostTime < 7200) - printk(KERN_NOTICE "%s registration Lost\n", dev->name); - - if (lostTime / priv->reRegisterExp > 2000) - arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_CONF); - if (lostTime / (priv->reRegisterExp) > 3500) - arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET); - if (priv->reRegisterExp < 400) - priv->reRegisterExp += 2; - if (lostTime > 7200) { - next_tick = HZ; - arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET); - } - } else { - if (priv->Conf->registrationMode && lostTime > 10000 && - priv->registrationLostCount) { - printk(KERN_NOTICE "%s registration is back after %ld milliseconds\n", - dev->name, lostTime); - } - priv->registrationLastSeen = jiffies; - priv->registrationLostCount = 0; - priv->reRegisterExp = 1; - if (!netif_running(dev)) - netif_wake_queue(dev); - if (time_after(priv->tx_last_sent, priv->tx_last_cleared) && - time_after(jiffies, priv->tx_last_sent * 5*HZ)) { - arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET); - priv->tx_last_cleared = jiffies; - } - } - - - if (!registrationBad(dev) && priv->ReTransmitRequested) { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk(KERN_ERR "Retransmit from timer\n"); - priv->ReTransmitRequested = 0; - arlan_retransmit_now(dev); - } - - if (!registrationBad(dev) && - time_after(jiffies, priv->tx_done_delayed) && - priv->tx_done_delayed != 0) { - TXLAST(dev).offset = 0; - - if (priv->txLast) - priv->txLast = 0; - else if (TXTAIL(dev).offset) - priv->txLast = 1; - if (TXLAST(dev).offset) { - arlan_retransmit_now(dev); - dev->trans_start = jiffies; - } - - if (!(TXHEAD(dev).offset && TXTAIL(dev).offset)) - netif_wake_queue(dev); - - priv->tx_done_delayed = 0; - bh_mark_needed = 1; - } - - if (bh_mark_needed) - netif_wake_queue(dev); - - arlan_process_interrupt(dev); - - if (next_tick < priv->card_polling_interval) - next_tick = priv->card_polling_interval; - - priv->timer.expires = jiffies + next_tick; - - add_timer(&priv->timer); -} - - -#ifdef ARLAN_DEBUGGING - -static void arlan_print_registers(struct net_device *dev, int line) -{ - struct arlan_private *priv = netdev_priv(dev); - volatile struct arlan_shmem *arlan = priv->card; - - u_char hostcpuLock, lancpuLock, controlRegister, cntrlRegImage, - txStatus, rxStatus, interruptInProgress, commandByte; - - - ARLAN_DEBUG_ENTRY("arlan_print_registers"); - READSHM(interruptInProgress, arlan->interruptInProgress, u_char); - READSHM(hostcpuLock, arlan->hostcpuLock, u_char); - READSHM(lancpuLock, arlan->lancpuLock, u_char); - READSHM(controlRegister, arlan->controlRegister, u_char); - READSHM(cntrlRegImage, arlan->cntrlRegImage, u_char); - READSHM(txStatus, arlan->txStatus, u_char); - READSHM(rxStatus, arlan->rxStatus, u_char); - READSHM(commandByte, arlan->commandByte, u_char); - - printk(KERN_WARNING "line %04d IP %02x HL %02x LL %02x CB %02x CR %02x CRI %02x TX %02x RX %02x\n", - line, interruptInProgress, hostcpuLock, lancpuLock, commandByte, - controlRegister, cntrlRegImage, txStatus, rxStatus); - - ARLAN_DEBUG_EXIT("arlan_print_registers"); -} -#endif - - -static int arlan_hw_tx(struct net_device *dev, char *buf, int length) -{ - int i; - - struct arlan_private *priv = netdev_priv(dev); - volatile struct arlan_shmem __iomem *arlan = priv->card; - struct arlan_conf_stru *conf = priv->Conf; - - int tailStarts = 0x800; - int headEnds = 0x0; - - - ARLAN_DEBUG_ENTRY("arlan_hw_tx"); - if (TXHEAD(dev).offset) - headEnds = (((TXHEAD(dev).offset + TXHEAD(dev).length - offsetof(struct arlan_shmem, txBuffer)) / 64) + 1) * 64; - if (TXTAIL(dev).offset) - tailStarts = 0x800 - (((TXTAIL(dev).offset - offsetof(struct arlan_shmem, txBuffer)) / 64) + 2) * 64; - - - if (!TXHEAD(dev).offset && length < tailStarts) { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk(KERN_ERR "TXHEAD insert, tailStart %d\n", tailStarts); - - TXHEAD(dev).offset = - offsetof(struct arlan_shmem, txBuffer); - TXHEAD(dev).length = length - ARLAN_FAKE_HDR_LEN; - for (i = 0; i < 6; i++) - TXHEAD(dev).dest[i] = buf[i]; - TXHEAD(dev).clear = conf->txClear; - TXHEAD(dev).retries = conf->txRetries; /* 0 is use default */ - TXHEAD(dev).routing = conf->txRouting; - TXHEAD(dev).scrambled = conf->txScrambled; - memcpy_toio((char __iomem *)arlan + TXHEAD(dev).offset, buf + ARLAN_FAKE_HDR_LEN, TXHEAD(dev).length); - } else if (!TXTAIL(dev).offset && length < (0x800 - headEnds)) { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk(KERN_ERR "TXTAIL insert, headEnd %d\n", headEnds); - - TXTAIL(dev).offset = - offsetof(struct arlan_shmem, txBuffer) + 0x800 - (length / 64 + 2) * 64; - TXTAIL(dev).length = length - ARLAN_FAKE_HDR_LEN; - for (i = 0; i < 6; i++) - TXTAIL(dev).dest[i] = buf[i]; - TXTAIL(dev).clear = conf->txClear; - TXTAIL(dev).retries = conf->txRetries; - TXTAIL(dev).routing = conf->txRouting; - TXTAIL(dev).scrambled = conf->txScrambled; - memcpy_toio(((char __iomem *)arlan + TXTAIL(dev).offset), buf + ARLAN_FAKE_HDR_LEN, TXTAIL(dev).length); - } else { - netif_stop_queue(dev); - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk(KERN_ERR "TX TAIL & HEAD full, return, tailStart %d headEnd %d\n", tailStarts, headEnds); - return -1; - } - priv->out_bytes += length; - priv->out_bytes10 += length; - if (conf->measure_rate < 1) - conf->measure_rate = 1; - if (time_after(jiffies, priv->out_time + conf->measure_rate * HZ)) { - conf->out_speed = priv->out_bytes / conf->measure_rate; - priv->out_bytes = 0; - priv->out_time = jiffies; - } - - if (time_after(jiffies, priv->out_time10 + conf->measure_rate * 10*HZ)) { - conf->out_speed10 = priv->out_bytes10 / (10 * conf->measure_rate); - priv->out_bytes10 = 0; - priv->out_time10 = jiffies; - } - - if (TXHEAD(dev).offset && TXTAIL(dev).offset) { - netif_stop_queue(dev); - return 0; - } else - netif_start_queue(dev); - - IFDEBUG(ARLAN_DEBUG_HEADER_DUMP) - printk(KERN_WARNING "%s Transmit t %2x:%2x:%2x:%2x:%2x:%2x f %2x:%2x:%2x:%2x:%2x:%2x\n", dev->name, - (unsigned char) buf[0], (unsigned char) buf[1], (unsigned char) buf[2], (unsigned char) buf[3], - (unsigned char) buf[4], (unsigned char) buf[5], (unsigned char) buf[6], (unsigned char) buf[7], - (unsigned char) buf[8], (unsigned char) buf[9], (unsigned char) buf[10], (unsigned char) buf[11]); - - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_ERR "TX command prepare for buffer %d\n", priv->txLast); - - arlan_command(dev, ARLAN_COMMAND_TX); - - priv->tx_last_sent = jiffies; - - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk("%s TX Qued %d bytes\n", dev->name, length); - - ARLAN_DEBUG_EXIT("arlan_hw_tx"); - - return 0; -} - - -static int arlan_hw_config(struct net_device *dev) -{ - struct arlan_private *priv = netdev_priv(dev); - volatile struct arlan_shmem __iomem *arlan = priv->card; - struct arlan_conf_stru *conf = priv->Conf; - - ARLAN_DEBUG_ENTRY("arlan_hw_config"); - - printk(KERN_NOTICE "%s arlan configure called\n", dev->name); - if (arlan_EEPROM_bad) - printk(KERN_NOTICE "arlan configure with eeprom bad option\n"); - - - WRITESHM(arlan->spreadingCode, conf->spreadingCode, u_char); - WRITESHM(arlan->channelSet, conf->channelSet, u_char); - - if (arlan_EEPROM_bad) - WRITESHM(arlan->defaultChannelSet, conf->channelSet, u_char); - - WRITESHM(arlan->channelNumber, conf->channelNumber, u_char); - - WRITESHM(arlan->scramblingDisable, conf->scramblingDisable, u_char); - WRITESHM(arlan->txAttenuation, conf->txAttenuation, u_char); - - WRITESHM(arlan->systemId, conf->systemId, u_int); - - WRITESHM(arlan->maxRetries, conf->maxRetries, u_char); - WRITESHM(arlan->receiveMode, conf->receiveMode, u_char); - WRITESHM(arlan->priority, conf->priority, u_char); - WRITESHM(arlan->rootOrRepeater, conf->rootOrRepeater, u_char); - WRITESHM(arlan->SID, conf->SID, u_int); - - WRITESHM(arlan->registrationMode, conf->registrationMode, u_char); - - WRITESHM(arlan->registrationFill, conf->registrationFill, u_char); - WRITESHM(arlan->localTalkAddress, conf->localTalkAddress, u_char); - WRITESHM(arlan->codeFormat, conf->codeFormat, u_char); - WRITESHM(arlan->numChannels, conf->numChannels, u_char); - WRITESHM(arlan->channel1, conf->channel1, u_char); - WRITESHM(arlan->channel2, conf->channel2, u_char); - WRITESHM(arlan->channel3, conf->channel3, u_char); - WRITESHM(arlan->channel4, conf->channel4, u_char); - WRITESHM(arlan->radioNodeId, conf->radioNodeId, u_short); - WRITESHM(arlan->SID, conf->SID, u_int); - WRITESHM(arlan->waitTime, conf->waitTime, u_short); - WRITESHM(arlan->lParameter, conf->lParameter, u_short); - memcpy_toio(&(arlan->_15), &(conf->_15), 3); - WRITESHM(arlan->_15, conf->_15, u_short); - WRITESHM(arlan->headerSize, conf->headerSize, u_short); - if (arlan_EEPROM_bad) - WRITESHM(arlan->hardwareType, conf->hardwareType, u_char); - WRITESHM(arlan->radioType, conf->radioType, u_char); - if (arlan_EEPROM_bad) - WRITESHM(arlan->radioModule, conf->radioType, u_char); - - memcpy_toio(arlan->encryptionKey + keyStart, encryptionKey, 8); - memcpy_toio(arlan->name, conf->siteName, 16); - - WRITESHMB(arlan->commandByte, ARLAN_COM_INT | ARLAN_COM_CONF); /* do configure */ - memset_io(arlan->commandParameter, 0, 0xf); /* 0xf */ - memset_io(arlan->commandParameter + 1, 0, 2); - if (conf->writeEEPROM) { - memset_io(arlan->commandParameter, conf->writeEEPROM, 1); - /* conf->writeEEPROM=0; */ - } - - if (conf->registrationMode && conf->registrationInterrupts) - memset_io(arlan->commandParameter + 3, 1, 1); - else - memset_io(arlan->commandParameter + 3, 0, 1); - - priv->irq_test_done = 0; - - if (conf->tx_queue_len) - dev->tx_queue_len = conf->tx_queue_len; - udelay(100); - - ARLAN_DEBUG_EXIT("arlan_hw_config"); - return 0; -} - - -static int arlan_read_card_configuration(struct net_device *dev) -{ - u_char tlx415; - struct arlan_private *priv = netdev_priv(dev); - volatile struct arlan_shmem __iomem *arlan = priv->card; - struct arlan_conf_stru *conf = priv->Conf; - - ARLAN_DEBUG_ENTRY("arlan_read_card_configuration"); - - - if (radioNodeId == radioNodeIdUNKNOWN) { - /* multiline macro, cannot remove braces */ - READSHM(conf->radioNodeId, arlan->radioNodeId, u_short); - } else - conf->radioNodeId = radioNodeId; - - if (SID == SIDUNKNOWN) { - /* multiline macro, cannot remove braces */ - READSHM(conf->SID, arlan->SID, u_int); - } else - conf->SID = SID; - - if (spreadingCode == spreadingCodeUNKNOWN) { - /* multiline macro, cannot remove braces */ - READSHM(conf->spreadingCode, arlan->spreadingCode, u_char); - } else - conf->spreadingCode = spreadingCode; - - if (channelSet == channelSetUNKNOWN) { - /* multiline macro, cannot remove braces */ - READSHM(conf->channelSet, arlan->channelSet, u_char); - } else - conf->channelSet = channelSet; - - if (channelNumber == channelNumberUNKNOWN) { - /* multiline macro, cannot remove braces */ - READSHM(conf->channelNumber, arlan->channelNumber, u_char); - } else - conf->channelNumber = channelNumber; - - READSHM(conf->scramblingDisable, arlan->scramblingDisable, u_char); - READSHM(conf->txAttenuation, arlan->txAttenuation, u_char); - - if (systemId == systemIdUNKNOWN) { - /* multiline macro, cannot remove braces */ - READSHM(conf->systemId, arlan->systemId, u_int); - } else - conf->systemId = systemId; - - READSHM(conf->maxDatagramSize, arlan->maxDatagramSize, u_short); - READSHM(conf->maxFrameSize, arlan->maxFrameSize, u_short); - READSHM(conf->maxRetries, arlan->maxRetries, u_char); - READSHM(conf->receiveMode, arlan->receiveMode, u_char); - READSHM(conf->priority, arlan->priority, u_char); - READSHM(conf->rootOrRepeater, arlan->rootOrRepeater, u_char); - - if (SID == SIDUNKNOWN) { - /* multiline macro, cannot remove braces */ - READSHM(conf->SID, arlan->SID, u_int); - } else - conf->SID = SID; - - if (registrationMode == registrationModeUNKNOWN) { - /* multiline macro, cannot remove braces */ - READSHM(conf->registrationMode, arlan->registrationMode, u_char); - } else - conf->registrationMode = registrationMode; - - READSHM(conf->registrationFill, arlan->registrationFill, u_char); - READSHM(conf->localTalkAddress, arlan->localTalkAddress, u_char); - READSHM(conf->codeFormat, arlan->codeFormat, u_char); - READSHM(conf->numChannels, arlan->numChannels, u_char); - READSHM(conf->channel1, arlan->channel1, u_char); - READSHM(conf->channel2, arlan->channel2, u_char); - READSHM(conf->channel3, arlan->channel3, u_char); - READSHM(conf->channel4, arlan->channel4, u_char); - READSHM(conf->waitTime, arlan->waitTime, u_short); - READSHM(conf->lParameter, arlan->lParameter, u_short); - READSHM(conf->_15, arlan->_15, u_short); - READSHM(conf->headerSize, arlan->headerSize, u_short); - READSHM(conf->hardwareType, arlan->hardwareType, u_char); - READSHM(conf->radioType, arlan->radioModule, u_char); - - if (conf->radioType == 0) - conf->radioType = 0xc; - - WRITESHM(arlan->configStatus, 0xA5, u_char); - READSHM(tlx415, arlan->configStatus, u_char); - - if (tlx415 != 0xA5) - printk(KERN_INFO "%s tlx415 chip\n", dev->name); - - conf->txClear = 0; - conf->txRetries = 1; - conf->txRouting = 1; - conf->txScrambled = 0; - conf->rxParameter = 1; - conf->txTimeoutMs = 4000; - conf->waitCardTimeout = 100000; - conf->receiveMode = ARLAN_RCV_CLEAN; - memcpy_fromio(conf->siteName, arlan->name, 16); - conf->siteName[16] = '\0'; - conf->retries = retries; - conf->tx_delay_ms = tx_delay_ms; - conf->ReTransmitPacketMaxSize = 200; - conf->waitReTransmitPacketMaxSize = 200; - conf->txAckTimeoutMs = 900; - conf->fastReTransCount = 3; - - ARLAN_DEBUG_EXIT("arlan_read_card_configuration"); - - return 0; -} - - -static int lastFoundAt = 0xbe000; - - -/* - * This is the real probe routine. Linux has a history of friendly device - * probes on the ISA bus. A good device probes avoids doing writes, and - * verifies that the correct device exists and functions. - */ -#define ARLAN_SHMEM_SIZE 0x2000 -static int __init arlan_check_fingerprint(unsigned long memaddr) -{ - static const char probeText[] = "TELESYSTEM SLW INC. ARLAN \0"; - volatile struct arlan_shmem __iomem *arlan = (struct arlan_shmem *) memaddr; - unsigned long paddr = virt_to_phys((void *) memaddr); - char tempBuf[49]; - - ARLAN_DEBUG_ENTRY("arlan_check_fingerprint"); - - if (!request_mem_region(paddr, ARLAN_SHMEM_SIZE, "arlan")) { - /* printk(KERN_WARNING "arlan: memory region %lx excluded from probing\n",paddr); */ - return -ENODEV; - } - - memcpy_fromio(tempBuf, arlan->textRegion, 29); - tempBuf[30] = 0; - - /* check for card at this address */ - if (0 != strncmp(tempBuf, probeText, 29)) { - release_mem_region(paddr, ARLAN_SHMEM_SIZE); - return -ENODEV; - } - - /* printk(KERN_INFO "arlan found at 0x%x\n",memaddr); */ - ARLAN_DEBUG_EXIT("arlan_check_fingerprint"); - - return 0; -} - -static int arlan_change_mtu(struct net_device *dev, int new_mtu) -{ - struct arlan_private *priv = netdev_priv(dev); - struct arlan_conf_stru *conf = priv->Conf; - - ARLAN_DEBUG_ENTRY("arlan_change_mtu"); - if (new_mtu > 2032) - return -EINVAL; - dev->mtu = new_mtu; - if (new_mtu < 256) - new_mtu = 256; /* cards book suggests 1600 */ - conf->maxDatagramSize = new_mtu; - conf->maxFrameSize = new_mtu + 48; - - arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_CONF); - printk(KERN_NOTICE "%s mtu changed to %d\n", dev->name, new_mtu); - - ARLAN_DEBUG_EXIT("arlan_change_mtu"); - - return 0; -} - -static int arlan_mac_addr(struct net_device *dev, void *p) -{ - struct sockaddr *addr = p; - - - ARLAN_DEBUG_ENTRY("arlan_mac_addr"); - return -EINVAL; - - if (netif_running(dev)) - return -EBUSY; - memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - - ARLAN_DEBUG_EXIT("arlan_mac_addr"); - return 0; -} - -static const struct net_device_ops arlan_netdev_ops = { - .ndo_open = arlan_open, - .ndo_stop = arlan_close, - .ndo_start_xmit = arlan_tx, - .ndo_get_stats = arlan_statistics, - .ndo_set_multicast_list = arlan_set_multicast, - .ndo_change_mtu = arlan_change_mtu, - .ndo_set_mac_address = arlan_mac_addr, - .ndo_tx_timeout = arlan_tx_timeout, - .ndo_validate_addr = eth_validate_addr, -}; - -static int __init arlan_setup_device(struct net_device *dev, int num) -{ - struct arlan_private *ap = netdev_priv(dev); - int err; - - ARLAN_DEBUG_ENTRY("arlan_setup_device"); - - ap->conf = (struct arlan_shmem *)(ap+1); - - dev->tx_queue_len = tx_queue_len; - dev->netdev_ops = &arlan_netdev_ops; - dev->watchdog_timeo = 3*HZ; - - ap->irq_test_done = 0; - ap->Conf = &arlan_conf[num]; - - ap->Conf->pre_Command_Wait = 40; - ap->Conf->rx_tweak1 = 30; - ap->Conf->rx_tweak2 = 0; - - - err = register_netdev(dev); - if (err) { - release_mem_region(virt_to_phys((void *) dev->mem_start), - ARLAN_SHMEM_SIZE); - free_netdev(dev); - return err; - } - arlan_device[num] = dev; - ARLAN_DEBUG_EXIT("arlan_setup_device"); - return 0; -} - -static int __init arlan_probe_here(struct net_device *dev, - unsigned long memaddr) -{ - struct arlan_private *ap = netdev_priv(dev); - - ARLAN_DEBUG_ENTRY("arlan_probe_here"); - - if (arlan_check_fingerprint(memaddr)) - return -ENODEV; - - printk(KERN_NOTICE "%s: Arlan found at %llx,\n ", dev->name, - (u64) virt_to_phys((void *)memaddr)); - - ap->card = (void *) memaddr; - dev->mem_start = memaddr; - dev->mem_end = memaddr + ARLAN_SHMEM_SIZE-1; - - if (dev->irq < 2) { - /* multiline macro, cannot remove braces */ - READSHM(dev->irq, ap->card->irqLevel, u_char); - } else if (dev->irq == 2) - dev->irq = 9; - - arlan_read_card_configuration(dev); - - ARLAN_DEBUG_EXIT("arlan_probe_here"); - return 0; -} - - -static int arlan_open(struct net_device *dev) -{ - struct arlan_private *priv = netdev_priv(dev); - volatile struct arlan_shmem __iomem *arlan = priv->card; - int ret = 0; - - ARLAN_DEBUG_ENTRY("arlan_open"); - - ret = request_irq(dev->irq, &arlan_interrupt, 0, dev->name, dev); - if (ret) { - printk(KERN_ERR "%s: unable to get IRQ %d .\n", - dev->name, dev->irq); - return ret; - } - - priv->bad = 0; - priv->lastReset = 0; - priv->reset = 0; - memcpy_fromio(dev->dev_addr, arlan->lanCardNodeId, 6); - memset(dev->broadcast, 0xff, 6); - dev->tx_queue_len = tx_queue_len; - priv->interrupt_processing_active = 0; - spin_lock_init(&priv->lock); - - netif_start_queue(dev); - - priv->registrationLostCount = 0; - priv->registrationLastSeen = jiffies; - priv->txLast = 0; - priv->tx_command_given = 0; - priv->rx_command_given = 0; - - priv->reRegisterExp = 1; - priv->tx_last_sent = jiffies - 1; - priv->tx_last_cleared = jiffies; - priv->Conf->writeEEPROM = 0; - priv->Conf->registrationInterrupts = 1; - - init_timer(&priv->timer); - priv->timer.expires = jiffies + HZ / 10; - priv->timer.data = (unsigned long) dev; - priv->timer.function = &arlan_registration_timer; /* timer handler */ - - arlan_command(dev, ARLAN_COMMAND_POWERUP | ARLAN_COMMAND_LONG_WAIT_NOW); - mdelay(200); - add_timer(&priv->timer); - - ARLAN_DEBUG_EXIT("arlan_open"); - return 0; -} - - -static void arlan_tx_timeout(struct net_device *dev) -{ - printk(KERN_ERR "%s: arlan transmit timed out, kernel decided\n", dev->name); - /* Try to restart the adaptor. */ - arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET); - /* dev->trans_start = jiffies; */ - /* netif_start_queue (dev); */ -} - - -static netdev_tx_t arlan_tx(struct sk_buff *skb, struct net_device *dev) -{ - short length; - unsigned char *buf; - - ARLAN_DEBUG_ENTRY("arlan_tx"); - - length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; - buf = skb->data; - - if (length + 0x12 > 0x800) { - printk(KERN_ERR "TX RING overflow\n"); - netif_stop_queue(dev); - } - - if (arlan_hw_tx(dev, buf, length) == -1) - goto bad_end; - - dev->trans_start = jiffies; - - dev_kfree_skb(skb); - - arlan_process_interrupt(dev); - ARLAN_DEBUG_EXIT("arlan_tx"); - return NETDEV_TX_OK; - -bad_end: - arlan_process_interrupt(dev); - netif_stop_queue(dev); - ARLAN_DEBUG_EXIT("arlan_tx"); - return NETDEV_TX_BUSY; -} - - -static inline int DoNotReTransmitCrap(struct net_device *dev) -{ - struct arlan_private *priv = netdev_priv(dev); - - if (TXLAST(dev).length < priv->Conf->ReTransmitPacketMaxSize) - return 1; - return 0; - -} - -static inline int DoNotWaitReTransmitCrap(struct net_device *dev) -{ - struct arlan_private *priv = netdev_priv(dev); - - if (TXLAST(dev).length < priv->Conf->waitReTransmitPacketMaxSize) - return 1; - return 0; -} - -static inline void arlan_queue_retransmit(struct net_device *dev) -{ - struct arlan_private *priv = netdev_priv(dev); - - ARLAN_DEBUG_ENTRY("arlan_queue_retransmit"); - - if (DoNotWaitReTransmitCrap(dev)) - arlan_drop_tx(dev); - else - priv->ReTransmitRequested++; - - ARLAN_DEBUG_EXIT("arlan_queue_retransmit"); -} - -static inline void RetryOrFail(struct net_device *dev) -{ - struct arlan_private *priv = netdev_priv(dev); - - ARLAN_DEBUG_ENTRY("RetryOrFail"); - - if (priv->retransmissions > priv->Conf->retries || - DoNotReTransmitCrap(dev)) - arlan_drop_tx(dev); - else if (priv->bad <= priv->Conf->fastReTransCount) - arlan_retransmit_now(dev); - else - arlan_queue_retransmit(dev); - - ARLAN_DEBUG_EXIT("RetryOrFail"); -} - - -static void arlan_tx_done_interrupt(struct net_device *dev, int status) -{ - struct arlan_private *priv = netdev_priv(dev); - - ARLAN_DEBUG_ENTRY("arlan_tx_done_interrupt"); - - priv->tx_last_cleared = jiffies; - priv->tx_command_given = 0; - switch (status) { - case 1: - { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk("arlan intr: transmit OK\n"); - dev->stats.tx_packets++; - priv->bad = 0; - priv->reset = 0; - priv->retransmissions = 0; - if (priv->Conf->tx_delay_ms) - priv->tx_done_delayed = jiffies + (priv->Conf->tx_delay_ms * HZ) / 1000 + 1; - else { - TXLAST(dev).offset = 0; - if (priv->txLast) - priv->txLast = 0; - else if (TXTAIL(dev).offset) - priv->txLast = 1; - - if (TXLAST(dev).offset) { - arlan_retransmit_now(dev); - dev->trans_start = jiffies; - } - - if (!TXHEAD(dev).offset || !TXTAIL(dev).offset) - netif_wake_queue(dev); - } - } - break; - - case 2: - { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk("arlan intr: transmit timed out\n"); - priv->bad += 1; - /* arlan_queue_retransmit(dev); */ - RetryOrFail(dev); - } - break; - - case 3: - { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk("arlan intr: transmit max retries\n"); - priv->bad += 1; - priv->reset = 0; - /* arlan_queue_retransmit(dev); */ - RetryOrFail(dev); - } - break; - - case 4: - { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk("arlan intr: transmit aborted\n"); - priv->bad += 1; - arlan_queue_retransmit(dev); - /* RetryOrFail(dev); */ - } - break; - - case 5: - { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk("arlan intr: transmit not registered\n"); - priv->bad += 1; - /* debug=101; */ - arlan_queue_retransmit(dev); - } - break; - - case 6: - { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk("arlan intr: transmit destination full\n"); - priv->bad += 1; - priv->reset = 0; - /* arlan_drop_tx(dev); */ - arlan_queue_retransmit(dev); - } - break; - - case 7: - { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk("arlan intr: transmit unknown ack\n"); - priv->bad += 1; - priv->reset = 0; - arlan_queue_retransmit(dev); - } - break; - - case 8: - { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk("arlan intr: transmit dest mail box full\n"); - priv->bad += 1; - priv->reset = 0; - /* arlan_drop_tx(dev); */ - arlan_queue_retransmit(dev); - } - break; - - case 9: - { - IFDEBUG(ARLAN_DEBUG_TX_CHAIN) - printk("arlan intr: transmit root dest not reg.\n"); - priv->bad += 1; - priv->reset = 1; - /* arlan_drop_tx(dev); */ - arlan_queue_retransmit(dev); - } - break; - - default: - { - printk(KERN_ERR "arlan intr: transmit status unknown\n"); - priv->bad += 1; - priv->reset = 1; - arlan_drop_tx(dev); - } - } - - ARLAN_DEBUG_EXIT("arlan_tx_done_interrupt"); -} - - -static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short rxOffset, u_short pkt_len) -{ - char *skbtmp; - int i = 0; - - struct arlan_private *priv = netdev_priv(dev); - volatile struct arlan_shmem __iomem *arlan = priv->card; - struct arlan_conf_stru *conf = priv->Conf; - - - ARLAN_DEBUG_ENTRY("arlan_rx_interrupt"); - /* by spec, not WRITESHMB(arlan->rxStatus,0x00); */ - /* prohibited here arlan_command(dev, ARLAN_COMMAND_RX); */ - - if (pkt_len < 10 || pkt_len > 2048) { - printk(KERN_WARNING "%s: got too short or long packet, len %d\n", dev->name, pkt_len); - return; - } - if (rxOffset + pkt_len > 0x2000) { - printk("%s: got too long packet, len %d offset %x\n", dev->name, pkt_len, rxOffset); - return; - } - - priv->in_bytes += pkt_len; - priv->in_bytes10 += pkt_len; - if (conf->measure_rate < 1) - conf->measure_rate = 1; - if (time_after(jiffies, priv->in_time + conf->measure_rate * HZ)) { - conf->in_speed = priv->in_bytes / conf->measure_rate; - priv->in_bytes = 0; - priv->in_time = jiffies; - } - if (time_after(jiffies, priv->in_time10 + conf->measure_rate * 10*HZ)) { - conf->in_speed10 = priv->in_bytes10 / (10 * conf->measure_rate); - priv->in_bytes10 = 0; - priv->in_time10 = jiffies; - } - DEBUGSHM(1, "arlan rcv pkt rxStatus= %d ", arlan->rxStatus, u_char); - switch (rxStatus) { - case 1: - case 2: - case 3: - { - /* Malloc up new buffer. */ - struct sk_buff *skb; - - DEBUGSHM(50, "arlan recv pkt offs=%d\n", arlan->rxOffset, u_short); - DEBUGSHM(1, "arlan rxFrmType = %d\n", arlan->rxFrmType, u_char); - DEBUGSHM(1, KERN_INFO "arlan rx scrambled = %d\n", arlan->scrambled, u_char); - - /* here we do multicast filtering to avoid slow 8-bit memcopy */ -#ifdef ARLAN_MULTICAST - if (!(dev->flags & IFF_ALLMULTI) && - !(dev->flags & IFF_PROMISC) && - !netdev_mc_empty(dev)) { - char hw_dst_addr[6]; - struct dev_mc_list *dmi; - int i; - - memcpy_fromio(hw_dst_addr, arlan->ultimateDestAddress, 6); - if (hw_dst_addr[0] == 0x01) { - if (mdebug) - if (hw_dst_addr[1] == 0x00) - printk(KERN_ERR "%s mcast 0x0100\n", dev->name); - else if (hw_dst_addr[1] == 0x40) - printk(KERN_ERR "%s m/bcast 0x0140\n", dev->name); - netdev_for_each_mc_entry(dmi, dev) { - if (arlan_debug & ARLAN_DEBUG_HEADER_DUMP) - printk(KERN_ERR "%s mcl %pM\n", - dev->name, dmi->dmi_addr); - for (i = 0; i < 6; i++) - if (dmi->dmi_addr[i] != hw_dst_addr[i]) - break; - if (i == 6) - break; - } - /* we reach here if multicast filtering is on and packet */ - /* is multicast and not for receive */ - goto end_of_interrupt; - } - } -#endif /* ARLAN_MULTICAST */ - /* multicast filtering ends here */ - pkt_len += ARLAN_FAKE_HDR_LEN; - - skb = dev_alloc_skb(pkt_len + 4); - if (skb == NULL) { - printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name); - dev->stats.rx_dropped++; - break; - } - skb_reserve(skb, 2); - skbtmp = skb_put(skb, pkt_len); - - memcpy_fromio(skbtmp + ARLAN_FAKE_HDR_LEN, ((char __iomem *) arlan) + rxOffset, pkt_len - ARLAN_FAKE_HDR_LEN); - memcpy_fromio(skbtmp, arlan->ultimateDestAddress, 6); - memcpy_fromio(skbtmp + 6, arlan->rxSrc, 6); - WRITESHMB(arlan->rxStatus, 0x00); - arlan_command(dev, ARLAN_COMMAND_RX); - - IFDEBUG(ARLAN_DEBUG_HEADER_DUMP) - { - char immedDestAddress[6]; - char immedSrcAddress[6]; - memcpy_fromio(immedDestAddress, arlan->immedDestAddress, 6); - memcpy_fromio(immedSrcAddress, arlan->immedSrcAddress, 6); - - printk(KERN_WARNING "%s t %pM f %pM imd %pM ims %pM\n", - dev->name, skbtmp, - &skbtmp[6], - immedDestAddress, - immedSrcAddress); - } - skb->protocol = eth_type_trans(skb, dev); - IFDEBUG(ARLAN_DEBUG_HEADER_DUMP) - if (skb->protocol != 0x608 && skb->protocol != 0x8) { - for (i = 0; i <= 22; i++) - printk("%02x:", (u_char) skbtmp[i + 12]); - printk(KERN_ERR "\n"); - printk(KERN_WARNING "arlan kernel pkt type trans %x\n", skb->protocol); - } - netif_rx(skb); - dev->stats.rx_packets++; - dev->stats.rx_bytes += pkt_len; - } - break; - - default: - printk(KERN_ERR "arlan intr: received unknown status\n"); - dev->stats.rx_crc_errors++; - break; - } - ARLAN_DEBUG_EXIT("arlan_rx_interrupt"); -} - -static void arlan_process_interrupt(struct net_device *dev) -{ - struct arlan_private *priv = netdev_priv(dev); - volatile struct arlan_shmem __iomem *arlan = priv->card; - u_char rxStatus = READSHMB(arlan->rxStatus); - u_char txStatus = READSHMB(arlan->txStatus); - u_short rxOffset = READSHMS(arlan->rxOffset); - u_short pkt_len = READSHMS(arlan->rxLength); - int interrupt_count = 0; - - ARLAN_DEBUG_ENTRY("arlan_process_interrupt"); - - if (test_and_set_bit(0, (void *) &priv->interrupt_processing_active)) { - if (arlan_debug & ARLAN_DEBUG_CHAIN_LOCKS) - printk(KERN_ERR "interrupt chain reentering\n"); - goto end_int_process; - } - while ((rxStatus || txStatus || priv->interrupt_ack_requested) - && (interrupt_count < 5)) { - if (rxStatus) - priv->last_rx_int_ack_time = jiffies; - - arlan_command(dev, ARLAN_COMMAND_INT_ACK); - arlan_command(dev, ARLAN_COMMAND_INT_ENABLE); - - IFDEBUG(ARLAN_DEBUG_INTERRUPT) - printk(KERN_ERR "%s: got IRQ rx %x tx %x comm %x rxOff %x rxLen %x\n", - dev->name, rxStatus, txStatus, READSHMB(arlan->commandByte), - rxOffset, pkt_len); - - if (rxStatus == 0 && txStatus == 0) { - if (priv->irq_test_done) { - if (!registrationBad(dev)) - IFDEBUG(ARLAN_DEBUG_INTERRUPT) printk(KERN_ERR "%s unknown interrupt(nop? regLost ?) reason tx %d rx %d ", - dev->name, txStatus, rxStatus); - } else { - IFDEBUG(ARLAN_DEBUG_INTERRUPT) - printk(KERN_INFO "%s irq $%d test OK\n", dev->name, dev->irq); - - } - priv->interrupt_ack_requested = 0; - goto ends; - } - - if (txStatus != 0) { - WRITESHMB(arlan->txStatus, 0x00); - arlan_tx_done_interrupt(dev, txStatus); - goto ends; - } - - if (rxStatus == 1 || rxStatus == 2) { - /* a packet waiting */ - arlan_rx_interrupt(dev, rxStatus, rxOffset, pkt_len); - goto ends; - } - - if (rxStatus > 2 && rxStatus < 0xff) { - WRITESHMB(arlan->rxStatus, 0x00); - printk(KERN_ERR "%s unknown rxStatus reason tx %d rx %d ", - dev->name, txStatus, rxStatus); - goto ends; - } - - if (rxStatus == 0xff) { - WRITESHMB(arlan->rxStatus, 0x00); - arlan_command(dev, ARLAN_COMMAND_RX); - if (registrationBad(dev)) - netif_device_detach(dev); - if (!registrationBad(dev)) { - priv->registrationLastSeen = jiffies; - if (!netif_queue_stopped(dev) && !priv->under_reset && !priv->under_config) - netif_wake_queue(dev); - } - goto ends; - } -ends: - - arlan_command_process(dev); - - rxStatus = READSHMB(arlan->rxStatus); - txStatus = READSHMB(arlan->txStatus); - rxOffset = READSHMS(arlan->rxOffset); - pkt_len = READSHMS(arlan->rxLength); - - - priv->irq_test_done = 1; - - interrupt_count++; - } - priv->interrupt_processing_active = 0; - -end_int_process: - arlan_command_process(dev); - - ARLAN_DEBUG_EXIT("arlan_process_interrupt"); - return; -} - -static irqreturn_t arlan_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct arlan_private *priv = netdev_priv(dev); - volatile struct arlan_shmem __iomem *arlan = priv->card; - u_char rxStatus = READSHMB(arlan->rxStatus); - u_char txStatus = READSHMB(arlan->txStatus); - - ARLAN_DEBUG_ENTRY("arlan_interrupt"); - - - if (!rxStatus && !txStatus) - priv->interrupt_ack_requested++; - - arlan_process_interrupt(dev); - - priv->irq_test_done = 1; - - ARLAN_DEBUG_EXIT("arlan_interrupt"); - return IRQ_HANDLED; - -} - - -static int arlan_close(struct net_device *dev) -{ - struct arlan_private *priv = netdev_priv(dev); - - ARLAN_DEBUG_ENTRY("arlan_close"); - - del_timer_sync(&priv->timer); - - arlan_command(dev, ARLAN_COMMAND_POWERDOWN); - - IFDEBUG(ARLAN_DEBUG_STARTUP) - printk(KERN_NOTICE "%s: Closing device\n", dev->name); - - netif_stop_queue(dev); - free_irq(dev->irq, dev); - - ARLAN_DEBUG_EXIT("arlan_close"); - return 0; -} - -#ifdef ARLAN_DEBUGGING -static long alignLong(volatile u_char *ptr) -{ - long ret; - memcpy_fromio(&ret, (void *) ptr, 4); - return ret; -} -#endif - -/* - * Get the current statistics. - * This may be called with the card open or closed. - */ - -static struct net_device_stats *arlan_statistics(struct net_device *dev) -{ - struct arlan_private *priv = netdev_priv(dev); - volatile struct arlan_shmem __iomem *arlan = priv->card; - - - ARLAN_DEBUG_ENTRY("arlan_statistics"); - - /* Update the statistics from the device registers. */ - - READSHM(dev->stats.collisions, arlan->numReTransmissions, u_int); - READSHM(dev->stats.rx_crc_errors, arlan->numCRCErrors, u_int); - READSHM(dev->stats.rx_dropped, arlan->numFramesDiscarded, u_int); - READSHM(dev->stats.rx_fifo_errors, arlan->numRXBufferOverflows, u_int); - READSHM(dev->stats.rx_frame_errors, arlan->numReceiveFramesLost, u_int); - READSHM(dev->stats.rx_over_errors, arlan->numRXOverruns, u_int); - READSHM(dev->stats.rx_packets, arlan->numDatagramsReceived, u_int); - READSHM(dev->stats.tx_aborted_errors, arlan->numAbortErrors, u_int); - READSHM(dev->stats.tx_carrier_errors, arlan->numStatusTimeouts, u_int); - READSHM(dev->stats.tx_dropped, arlan->numDatagramsDiscarded, u_int); - READSHM(dev->stats.tx_fifo_errors, arlan->numTXUnderruns, u_int); - READSHM(dev->stats.tx_packets, arlan->numDatagramsTransmitted, u_int); - READSHM(dev->stats.tx_window_errors, arlan->numHoldOffs, u_int); - - ARLAN_DEBUG_EXIT("arlan_statistics"); - - return &dev->stats; -} - - -static void arlan_set_multicast(struct net_device *dev) -{ - struct arlan_private *priv = netdev_priv(dev); - volatile struct arlan_shmem __iomem *arlan = priv->card; - struct arlan_conf_stru *conf = priv->Conf; - int board_conf_needed = 0; - - - ARLAN_DEBUG_ENTRY("arlan_set_multicast"); - - if (dev->flags & IFF_PROMISC) { - unsigned char recMode; - READSHM(recMode, arlan->receiveMode, u_char); - conf->receiveMode = (ARLAN_RCV_PROMISC | ARLAN_RCV_CONTROL); - if (conf->receiveMode != recMode) - board_conf_needed = 1; - } else { - /* turn off promiscuous mode */ - unsigned char recMode; - READSHM(recMode, arlan->receiveMode, u_char); - conf->receiveMode = ARLAN_RCV_CLEAN | ARLAN_RCV_CONTROL; - if (conf->receiveMode != recMode) - board_conf_needed = 1; - } - - if (board_conf_needed) - arlan_command(dev, ARLAN_COMMAND_CONF); - - ARLAN_DEBUG_EXIT("arlan_set_multicast"); -} - - -struct net_device * __init arlan_probe(int unit) -{ - struct net_device *dev; - int err; - int m; - - ARLAN_DEBUG_ENTRY("arlan_probe"); - - if (arlans_found == MAX_ARLANS) - return ERR_PTR(-ENODEV); - - /* - * Reserve space for local data and a copy of the shared memory - * that is used by the /proc interface. - */ - dev = alloc_etherdev(sizeof(struct arlan_private) - + sizeof(struct arlan_shmem)); - if (!dev) - return ERR_PTR(-ENOMEM); - - if (unit >= 0) { - sprintf(dev->name, "eth%d", unit); - netdev_boot_setup_check(dev); - - if (dev->mem_start) { - if (arlan_probe_here(dev, dev->mem_start) == 0) - goto found; - goto not_found; - } - } - - - for (m = (int)phys_to_virt(lastFoundAt) + ARLAN_SHMEM_SIZE; - m <= (int)phys_to_virt(0xDE000); - m += ARLAN_SHMEM_SIZE) { - if (arlan_probe_here(dev, m) == 0) { - lastFoundAt = (int)virt_to_phys((void *)m); - goto found; - } - } - - if (lastFoundAt == 0xbe000) - printk(KERN_ERR "arlan: No Arlan devices found\n"); - - not_found: - free_netdev(dev); - return ERR_PTR(-ENODEV); - - found: - err = arlan_setup_device(dev, arlans_found); - if (err) - dev = ERR_PTR(err); - else if (!arlans_found++) - printk(KERN_INFO "Arlan driver %s\n", arlan_version); - - return dev; -} - -#ifdef MODULE -int __init init_module(void) -{ - int i = 0; - - ARLAN_DEBUG_ENTRY("init_module"); - - if (channelSet != channelSetUNKNOWN || channelNumber != channelNumberUNKNOWN || systemId != systemIdUNKNOWN) - return -EINVAL; - - for (i = 0; i < MAX_ARLANS; i++) { - struct net_device *dev = arlan_probe(i); - - if (IS_ERR(dev)) - return PTR_ERR(dev); - } - init_arlan_proc(); - printk(KERN_INFO "Arlan driver %s\n", arlan_version); - ARLAN_DEBUG_EXIT("init_module"); - return 0; -} - - -void __exit cleanup_module(void) -{ - int i = 0; - struct net_device *dev; - - ARLAN_DEBUG_ENTRY("cleanup_module"); - - IFDEBUG(ARLAN_DEBUG_SHUTDOWN) - printk(KERN_INFO "arlan: unloading module\n"); - - cleanup_arlan_proc(); - - for (i = 0; i < MAX_ARLANS; i++) { - dev = arlan_device[i]; - if (dev) { - arlan_command(dev, ARLAN_COMMAND_POWERDOWN); - - unregister_netdev(dev); - release_mem_region(virt_to_phys((void *) dev->mem_start), - ARLAN_SHMEM_SIZE); - free_netdev(dev); - arlan_device[i] = NULL; - } - } - - ARLAN_DEBUG_EXIT("cleanup_module"); -} - - -#endif -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/arlan/arlan-proc.c b/drivers/staging/arlan/arlan-proc.c deleted file mode 100644 index 62cd1d0b59ef..000000000000 --- a/drivers/staging/arlan/arlan-proc.c +++ /dev/null @@ -1,1199 +0,0 @@ -#include "arlan.h" - -#include - -#ifdef CONFIG_PROC_FS - -/* void enableReceive(struct net_device* dev); -*/ - - - -#define ARLAN_STR_SIZE 0x2ff0 -#define DEV_ARLAN_INFO 1 -#define DEV_ARLAN 1 -#define SARLG(type, var) {\ - pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x%x\n", #var,\ - READSHMB(priva->card->var));\ - } - -#define SARLBN(type, var, nn) {\ - pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x", #var);\ - for (i = 0; i < nn; i++)\ - pos += sprintf(arlan_drive_info+pos, "%02x",\ - READSHMB(priva->card->var[i]));\ - pos += sprintf(arlan_drive_info+pos, "\n");\ - } - -#define SARLBNpln(type, var, nn) {\ - for (i = 0; i < nn; i++)\ - pos += sprintf(arlan_drive_info+pos, "%02x",\ - READSHMB(priva->card->var[i]));\ - } - -#define SARLSTR(var, nn) {\ - char tmpStr[400];\ - int tmpLn = nn;\ - if (nn > 399)\ - tmpLn = 399;\ - memcpy(tmpStr, (char *) priva->conf->var, tmpLn);\ - tmpStr[tmpLn] = 0; \ - pos += sprintf(arlan_drive_info+pos, "%s\t=\t%s\n",\ - #var, priva->conf->var);\ - } - -#define SARLUC(var) SARLG(u_char, var) -#define SARLUCN(var, nn) SARLBN(u_char, var, nn) -#define SARLUS(var) SARLG(u_short, var) -#define SARLUSN(var, nn) SARLBN(u_short, var, nn) -#define SARLUI(var) SARLG(u_int, var) - -#define SARLUSA(var) {\ - u_short tmpVar;\ - memcpy(&tmpVar, (short *) priva->conf->var, 2); \ - pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x%x\n", #var, tmpVar);\ -} - -#define SARLUIA(var) {\ - u_int tmpVar;\ - memcpy(&tmpVar, (int *)priva->conf->var, 4); \ - pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x%x\n", #var, tmpVar);\ -} - - -static const char *arlan_diagnostic_info_string(struct net_device *dev) -{ - - struct arlan_private *priv = netdev_priv(dev); - volatile struct arlan_shmem __iomem *arlan = priv->card; - u_char diagnosticInfo; - - READSHM(diagnosticInfo, arlan->diagnosticInfo, u_char); - - switch (diagnosticInfo) { - - case 0xFF: - return "Diagnostic info is OK"; - case 0xFE: - return "ERROR EPROM Checksum error "; - case 0xFD: - return "ERROR Local Ram Test Failed "; - case 0xFC: - return "ERROR SCC failure "; - case 0xFB: - return "ERROR BackBone failure "; - case 0xFA: - return "ERROR transceiver not found "; - case 0xF9: - return "ERROR no more address space "; - case 0xF8: - return "ERROR Checksum error "; - case 0xF7: - return "ERROR Missing SS Code"; - case 0xF6: - return "ERROR Invalid config format"; - case 0xF5: - return "ERROR Reserved errorcode F5"; - case 0xF4: - return "ERROR Invalid spreading code/channel number"; - case 0xF3: - return "ERROR Load Code Error"; - case 0xF2: - return "ERROR Reserver errorcode F2 "; - case 0xF1: - return "ERROR Invalid command receivec by LAN card "; - case 0xF0: - return "ERROR Invalid parameter found in command "; - case 0xEF: - return "ERROR On-chip timer failure "; - case 0xEE: - return "ERROR T410 timer failure "; - case 0xED: - return "ERROR Too Many TxEnable commands "; - case 0xEC: - return "ERROR EEPROM error on radio module "; - default: - return "ERROR unknown Diagnostic info reply code "; - } -} - -static const char *arlan_hardware_type_string(struct net_device *dev) -{ - u_char hardwareType; - struct arlan_private *priv = netdev_priv(dev); - volatile struct arlan_shmem __iomem *arlan = priv->card; - - READSHM(hardwareType, arlan->hardwareType, u_char); - switch (hardwareType) { - case 0x00: - return "type A450"; - case 0x01: - return "type A650 "; - case 0x04: - return "type TMA coproc"; - case 0x0D: - return "type A650E "; - case 0x18: - return "type TMA coproc Australian"; - case 0x19: - return "type A650A "; - case 0x26: - return "type TMA coproc European"; - case 0x2E: - return "type A655 "; - case 0x2F: - return "type A655A "; - case 0x30: - return "type A655E "; - case 0x0B: - return "type A670 "; - case 0x0C: - return "type A670E "; - case 0x2D: - return "type A670A "; - case 0x0F: - return "type A411T"; - case 0x16: - return "type A411TA"; - case 0x1B: - return "type A440T"; - case 0x1C: - return "type A412T"; - case 0x1E: - return "type A412TA"; - case 0x22: - return "type A411TE"; - case 0x24: - return "type A412TE"; - case 0x27: - return "type A671T "; - case 0x29: - return "type A671TA "; - case 0x2B: - return "type A671TE "; - case 0x31: - return "type A415T "; - case 0x33: - return "type A415TA "; - case 0x35: - return "type A415TE "; - case 0x37: - return "type A672"; - case 0x39: - return "type A672A "; - case 0x3B: - return "type A672T"; - case 0x6B: - return "type IC2200"; - default: - return "type A672T"; - } -} -#ifdef ARLAN_DEBUGGING -static void arlan_print_diagnostic_info(struct net_device *dev) -{ - int i; - u_char diagnosticInfo; - u_short diagnosticOffset; - u_char hardwareType; - struct arlan_private *priv = netdev_priv(dev); - volatile struct arlan_shmem __iomem *arlan = priv->card; - - /* ARLAN_DEBUG_ENTRY("arlan_print_diagnostic_info"); */ - - if (READSHMB(arlan->configuredStatusFlag) == 0) - printk(KERN_WARNING "Arlan: Card NOT configured\n"); - else - printk(KERN_INFO "Arlan: Card is configured\n"); - - READSHM(diagnosticInfo, arlan->diagnosticInfo, u_char); - READSHM(diagnosticOffset, arlan->diagnosticOffset, u_short); - - printk(KERN_INFO "%s\n", arlan_diagnostic_info_string(dev)); - - if (diagnosticInfo != 0xff) - printk(KERN_INFO "%s arlan: Diagnostic Offset %d\n",\ - dev->name, diagnosticOffset); - - printk(KERN_INFO "arlan: LAN CODE ID = "); - for (i = 0; i < 6; i++) - DEBUGSHM(1, "%03d:", arlan->lanCardNodeId[i], u_char); - printk("\n"); - - printk(KERN_INFO "arlan: Arlan BroadCast address = "); - for (i = 0; i < 6; i++) - DEBUGSHM(1, "%03d:", arlan->broadcastAddress[i], u_char); - printk("\n"); - - READSHM(hardwareType, arlan->hardwareType, u_char); - printk(KERN_INFO "%s\n", arlan_hardware_type_string(dev)); - - - DEBUGSHM(1, "arlan: channelNumber=%d\n", arlan->channelNumber, u_char); - DEBUGSHM(1, "arlan: channelSet=%d\n", arlan->channelSet, u_char); - DEBUGSHM(1, "arlan: spreadingCode=%d\n", arlan->spreadingCode, u_char); - DEBUGSHM(1, "arlan: radioNodeId=%d\n", arlan->radioNodeId, u_short); - DEBUGSHM(1, "arlan: SID =%d\n", arlan->SID, u_short); - DEBUGSHM(1, "arlan: rxOffset=%d\n", arlan->rxOffset, u_short); - - DEBUGSHM(1, "arlan: registration mode is %d\n",\ - arlan->registrationMode, u_char); - - printk(KERN_INFO "arlan: name= "); - IFDEBUG(1) - - for (i = 0; i < 16; i++) { - char c; - READSHM(c, arlan->name[i], char); - if (c) - printk("%c", c); - } - printk("\n"); - - /* ARLAN_DEBUG_EXIT("arlan_print_diagnostic_info"); */ - -} - - -/****************************** TEST MEMORY **************/ - -static int arlan_hw_test_memory(struct net_device *dev) -{ - u_char *ptr; - int i; - int memlen = sizeof(struct arlan_shmem) - 0xF; /* avoid - control register */ - volatile char *arlan_mem = (char *) (dev->mem_start); - struct arlan_private *priv = netdev_priv(dev); - volatile struct arlan_shmem __iomem *arlan = priv->card; - char pattern; - - ptr = NULL; - - /* hold card in reset state */ - setHardwareReset(dev); - - /* test memory */ - pattern = 0; - for (i = 0; i < memlen; i++) - WRITESHM(arlan_mem[i], ((u_char) pattern++), u_char); - - pattern = 0; - for (i = 0; i < memlen; i++) { - char res; - READSHM(res, arlan_mem[i], char); - if (res != pattern++) { - printk(KERN_ERR "Arlan driver memory test 1 failed\n"); - return -1; - } - } - - pattern = 0; - for (i = 0; i < memlen; i++) - WRITESHM(arlan_mem[i], ~(pattern++), char); - - pattern = 0; - for (i = 0; i < memlen; i++) { - char res; - READSHM(res, arlan_mem[i], char); - if (res != ~(pattern++)) { - printk(KERN_ERR "Arlan driver memory test 2 failed\n"); - return -1; - } - } - - /* zero memory */ - for (i = 0; i < memlen; i++) - WRITESHM(arlan_mem[i], 0x00, char); - - IFDEBUG(1) printk(KERN_INFO "Arlan: memory tests ok\n"); - - /* set reset flag and then release reset */ - WRITESHM(arlan->resetFlag, 0xff, u_char); - - clearChannelAttention(dev); - clearHardwareReset(dev); - - /* wait for reset flag to become zero, we'll wait for two seconds */ - if (arlan_command(dev, ARLAN_COMMAND_LONG_WAIT_NOW)) { - printk(KERN_ERR "%s arlan: failed to come\ - back from memory test\n", dev->name); - return -1; - } - return 0; -} - -static int arlan_setup_card_by_book(struct net_device *dev) -{ - u_char irqLevel, configuredStatusFlag; - struct arlan_private *priv = netdev_priv(dev); - volatile struct arlan_shmem __iomem *arlan = priv->card; - - /* ARLAN_DEBUG_ENTRY("arlan_setup_card"); */ - - READSHM(configuredStatusFlag, arlan->configuredStatusFlag, u_char); - - IFDEBUG(10) - if (configuredStatusFlag != 0) - IFDEBUG(10) printk(KERN_INFO "arlan: CARD IS CONFIGURED\n"); - else - IFDEBUG(10) printk(KERN_WARNING\ - "arlan: card is NOT configured\n"); - - if (testMemory || (READSHMB(arlan->diagnosticInfo) != 0xff)) - if (arlan_hw_test_memory(dev)) - return -1; - - DEBUGSHM(4, "arlan configuredStatus = %d\n",\ - arlan->configuredStatusFlag, u_char); - DEBUGSHM(4, "arlan driver diagnostic: 0x%2x\n",\ - arlan->diagnosticInfo, u_char); - - /* issue nop command - no interrupt */ - arlan_command(dev, ARLAN_COMMAND_NOOP); - if (arlan_command(dev, ARLAN_COMMAND_WAIT_NOW) != 0) - return -1; - - IFDEBUG(50) printk(KERN_INFO "1st Noop successfully executed !!\n"); - - /* try to turn on the arlan interrupts */ - clearClearInterrupt(dev); - setClearInterrupt(dev); - setInterruptEnable(dev); - - /* issue nop command - with interrupt */ - - arlan_command(dev, ARLAN_COMMAND_NOOPINT); - if (arlan_command(dev, ARLAN_COMMAND_WAIT_NOW) != 0) - return -1; - - - IFDEBUG(50) printk(KERN_INFO "2nd Noop successfully executed !!\n"); - - READSHM(irqLevel, arlan->irqLevel, u_char) - - if (irqLevel != dev->irq) { - IFDEBUG(1) printk(KERN_WARNING "arlan dip switches\ - set irq to %d\n", irqLevel); - printk(KERN_WARNING "device driver irq set to %d-\ - does not match\n", dev->irq); - dev->irq = irqLevel; - } else - IFDEBUG(2) printk(KERN_INFO "irq level is OK\n"); - - - IFDEBUG(3) arlan_print_diagnostic_info(dev); - - arlan_command(dev, ARLAN_COMMAND_CONF); - - READSHM(configuredStatusFlag, arlan->configuredStatusFlag, u_char); - if (configuredStatusFlag == 0) { - printk(KERN_WARNING "arlan configure failed\n"); - return -1; - } - arlan_command(dev, ARLAN_COMMAND_LONG_WAIT_NOW); - arlan_command(dev, ARLAN_COMMAND_RX); - arlan_command(dev, ARLAN_COMMAND_LONG_WAIT_NOW); - printk(KERN_NOTICE "%s: arlan driver version %s loaded\n", - dev->name, arlan_version); - - /* ARLAN_DEBUG_EXIT("arlan_setup_card"); */ - - return 0; /* no errors */ -} -#endif - -#ifdef ARLAN_PROC_INTERFACE -#ifdef ARLAN_PROC_SHM_DUMP - -static char arlan_drive_info[ARLAN_STR_SIZE] = "A655\n\0"; - -static int arlan_sysctl_info(ctl_table *ctl, int write, - void __user *buffer, size_t * lenp, loff_t *ppos) -{ - int i; - int retv, pos, devnum; - struct arlan_private *priva = NULL; - struct net_device *dev; - pos = 0; - if (write) { - printk(KERN_INFO "wrirte: "); - for (i = 0; i < 100; i++) - printk("adi %x\n", arlan_drive_info[i]); - } - if (ctl->procname == NULL || arlan_drive_info == NULL) { - printk(KERN_WARNING " procname is NULL in sysctl_table or arlan_drive_info is NULL\n at arlan module\n "); - return -1; - } - devnum = ctl->procname[5] - '0'; - if (devnum < 0 || devnum > MAX_ARLANS - 1) { - printk(KERN_WARNING "too strange devnum in procfs parse\n "); - return -1; - } else if (arlan_device[devnum] == NULL) { - if (ctl->procname) - pos += sprintf(arlan_drive_info + pos,\ - "\t%s\n\n", ctl->procname); - pos += sprintf(arlan_drive_info + pos,\ - "No device found here\n"); - goto final; - } else - priva = netdev_priv(arlan_device[devnum]); - - if (priva == NULL) { - printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n "); - return -1; - } - dev = arlan_device[devnum]; - - memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem)); - - pos = sprintf(arlan_drive_info, "Arlan info\n"); - /* Header Signature */ - SARLSTR(textRegion, 48); - SARLUC(resetFlag); - pos += sprintf(arlan_drive_info + pos,\ - "diagnosticInfo\t=\t%s\n", arlan_diagnostic_info_string(dev)); - SARLUC(diagnosticInfo); - SARLUS(diagnosticOffset); - SARLUCN(_1, 12); - SARLUCN(lanCardNodeId, 6); - SARLUCN(broadcastAddress, 6); - pos += sprintf(arlan_drive_info + pos,\ - "hardwareType =\t %s\n", arlan_hardware_type_string(dev)); - SARLUC(hardwareType); - SARLUC(majorHardwareVersion); - SARLUC(minorHardwareVersion); - SARLUC(radioModule); - SARLUC(defaultChannelSet); - SARLUCN(_2, 47); - - /* Control/Status Block - 0x0080 */ - SARLUC(interruptInProgress); - SARLUC(cntrlRegImage); - - SARLUCN(_3, 14); - SARLUC(commandByte); - SARLUCN(commandParameter, 15); - - /* Receive Status - 0x00a0 */ - SARLUC(rxStatus); - SARLUC(rxFrmType); - SARLUS(rxOffset); - SARLUS(rxLength); - SARLUCN(rxSrc, 6); - SARLUC(rxBroadcastFlag); - SARLUC(rxQuality); - SARLUC(scrambled); - SARLUCN(_4, 1); - - /* Transmit Status - 0x00b0 */ - SARLUC(txStatus); - SARLUC(txAckQuality); - SARLUC(numRetries); - SARLUCN(_5, 14); - SARLUCN(registeredRouter, 6); - SARLUCN(backboneRouter, 6); - SARLUC(registrationStatus); - SARLUC(configuredStatusFlag); - SARLUCN(_6, 1); - SARLUCN(ultimateDestAddress, 6); - SARLUCN(immedDestAddress, 6); - SARLUCN(immedSrcAddress, 6); - SARLUS(rxSequenceNumber); - SARLUC(assignedLocaltalkAddress); - SARLUCN(_7, 27); - - /* System Parameter Block */ - - /* - Driver Parameters (Novell Specific) */ - - SARLUS(txTimeout); - SARLUS(transportTime); - SARLUCN(_8, 4); - - /* - Configuration Parameters */ - SARLUC(irqLevel); - SARLUC(spreadingCode); - SARLUC(channelSet); - SARLUC(channelNumber); - SARLUS(radioNodeId); - SARLUCN(_9, 2); - SARLUC(scramblingDisable); - SARLUC(radioType); - SARLUS(routerId); - SARLUCN(_10, 9); - SARLUC(txAttenuation); - SARLUIA(systemId); - SARLUS(globalChecksum); - SARLUCN(_11, 4); - SARLUS(maxDatagramSize); - SARLUS(maxFrameSize); - SARLUC(maxRetries); - SARLUC(receiveMode); - SARLUC(priority); - SARLUC(rootOrRepeater); - SARLUCN(specifiedRouter, 6); - SARLUS(fastPollPeriod); - SARLUC(pollDecay); - SARLUSA(fastPollDelay); - SARLUC(arlThreshold); - SARLUC(arlDecay); - SARLUCN(_12, 1); - SARLUS(specRouterTimeout); - SARLUCN(_13, 5); - - /* Scrambled Area */ - SARLUIA(SID); - SARLUCN(encryptionKey, 12); - SARLUIA(_14); - SARLUSA(waitTime); - SARLUSA(lParameter); - SARLUCN(_15, 3); - SARLUS(headerSize); - SARLUS(sectionChecksum); - - SARLUC(registrationMode); - SARLUC(registrationFill); - SARLUS(pollPeriod); - SARLUS(refreshPeriod); - SARLSTR(name, 16); - SARLUCN(NID, 6); - SARLUC(localTalkAddress); - SARLUC(codeFormat); - SARLUC(numChannels); - SARLUC(channel1); - SARLUC(channel2); - SARLUC(channel3); - SARLUC(channel4); - SARLUCN(SSCode, 59); - -/* SARLUCN( _16, 0x140); - */ - /* Statistics Block - 0x0300 */ - SARLUC(hostcpuLock); - SARLUC(lancpuLock); - SARLUCN(resetTime, 18); - SARLUIA(numDatagramsTransmitted); - SARLUIA(numReTransmissions); - SARLUIA(numFramesDiscarded); - SARLUIA(numDatagramsReceived); - SARLUIA(numDuplicateReceivedFrames); - SARLUIA(numDatagramsDiscarded); - SARLUS(maxNumReTransmitDatagram); - SARLUS(maxNumReTransmitFrames); - SARLUS(maxNumConsecutiveDuplicateFrames); - /* misaligned here so we have to go to characters */ - SARLUIA(numBytesTransmitted); - SARLUIA(numBytesReceived); - SARLUIA(numCRCErrors); - SARLUIA(numLengthErrors); - SARLUIA(numAbortErrors); - SARLUIA(numTXUnderruns); - SARLUIA(numRXOverruns); - SARLUIA(numHoldOffs); - SARLUIA(numFramesTransmitted); - SARLUIA(numFramesReceived); - SARLUIA(numReceiveFramesLost); - SARLUIA(numRXBufferOverflows); - SARLUIA(numFramesDiscardedAddrMismatch); - SARLUIA(numFramesDiscardedSIDMismatch); - SARLUIA(numPollsTransmistted); - SARLUIA(numPollAcknowledges); - SARLUIA(numStatusTimeouts); - SARLUIA(numNACKReceived); - SARLUS(auxCmd); - SARLUCN(dumpPtr, 4); - SARLUC(dumpVal); - SARLUC(wireTest); - - /* next 4 seems too long for procfs, over single page ? - SARLUCN( _17, 0x86); - SARLUCN( txBuffer, 0x800); - SARLUCN( rxBuffer, 0x800); - SARLUCN( _18, 0x0bff); - */ - - pos += sprintf(arlan_drive_info + pos, "rxRing\t=\t0x"); - for (i = 0; i < 0x50; i++) - pos += sprintf(arlan_drive_info + pos, "%02x",\ - ((char *) priva->conf)[priva->conf->rxOffset + i]); - pos += sprintf(arlan_drive_info + pos, "\n"); - - SARLUC(configStatus); - SARLUC(_22); - SARLUC(progIOCtrl); - SARLUC(shareMBase); - SARLUC(controlRegister); - - pos += sprintf(arlan_drive_info + pos, " total %d chars\n", pos); - if (ctl) - if (ctl->procname) - pos += sprintf(arlan_drive_info + pos,\ - " driver name : %s\n", ctl->procname); -final: - *lenp = pos; - - if (!write) - retv = proc_dostring(ctl, write, buffer, lenp, ppos); - else { - *lenp = 0; - return -1; - } - return retv; -} - - -static int arlan_sysctl_info161719(ctl_table *ctl, int write, - void __user *buffer, size_t * lenp, loff_t *ppos) -{ - int i; - int retv, pos, devnum; - struct arlan_private *priva = NULL; - - pos = 0; - devnum = ctl->procname[5] - '0'; - if (arlan_device[devnum] == NULL) { - pos += sprintf(arlan_drive_info + pos,\ - "No device found here\n"); - goto final; - } else - priva = netdev_priv(arlan_device[devnum]); - - if (priva == NULL) { - printk(KERN_WARNING " Could not find the device\ - private in arlan procsys, bad\n "); - return -1; - } - memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem)); - SARLUCN(_16, 0xC0); - SARLUCN(_17, 0x6A); - SARLUCN(_18, 14); - SARLUCN(_19, 0x86); - SARLUCN(_21, 0x3fd); - -final: - *lenp = pos; - retv = proc_dostring(ctl, write, buffer, lenp, ppos); - return retv; -} - -static int arlan_sysctl_infotxRing(ctl_table *ctl, int write, - void __user *buffer, size_t * lenp, loff_t *ppos) -{ - int i; - int retv, pos, devnum; - struct arlan_private *priva = NULL; - - pos = 0; - devnum = ctl->procname[5] - '0'; - if (arlan_device[devnum] == NULL) { - pos += sprintf(arlan_drive_info + pos,\ - "No device found here\n"); - goto final; - } else - priva = netdev_priv(arlan_device[devnum]); - - if (priva == NULL) { - printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n "); - return -1; - } - memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem)); - SARLBNpln(u_char, txBuffer, 0x800); -final: - *lenp = pos; - retv = proc_dostring(ctl, write, buffer, lenp, ppos); - return retv; -} - -static int arlan_sysctl_inforxRing(ctl_table *ctl, int write, - void __user *buffer, size_t * lenp, loff_t *ppos) -{ - int i; - int retv, pos, devnum; - struct arlan_private *priva = NULL; - - pos = 0; - devnum = ctl->procname[5] - '0'; - if (arlan_device[devnum] == NULL) { - pos += sprintf(arlan_drive_info + pos,\ - "No device found here\n"); - goto final; - } else - priva = netdev_priv(arlan_device[devnum]); - if (priva == NULL) { - printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n "); - return -1; - } - memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem)); - SARLBNpln(u_char, rxBuffer, 0x800); -final: - *lenp = pos; - retv = proc_dostring(ctl, write, buffer, lenp, ppos); - return retv; -} - -static int arlan_sysctl_info18(ctl_table *ctl, int write, - void __user *buffer, size_t * lenp, loff_t *ppos) -{ - int i; - int retv, pos, devnum; - struct arlan_private *priva = NULL; - - pos = 0; - devnum = ctl->procname[5] - '0'; - if (arlan_device[devnum] == NULL) { - pos += sprintf(arlan_drive_info + pos,\ - "No device found here\n"); - goto final; - } else - priva = netdev_priv(arlan_device[devnum]); - - if (priva == NULL) { - printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n "); - return -1; - } - - memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem)); - SARLBNpln(u_char, _18, 0x800); - -final: - *lenp = pos; - retv = proc_dostring(ctl, write, buffer, lenp, ppos); - return retv; -} - - -#endif /* #ifdef ARLAN_PROC_SHM_DUMP */ - - -static char conf_reset_result[200]; - -static int arlan_configure(ctl_table *ctl, int write, - void __user *buffer, size_t * lenp, loff_t *ppos) -{ - int pos = 0; - int devnum = ctl->procname[6] - '0'; - struct arlan_private *priv; - - if (devnum < 0 || devnum > MAX_ARLANS - 1) { - printk(KERN_WARNING "too strange devnum in procfs parse\n"); - return -1; - } else if (arlan_device[devnum] != NULL) { - priv = netdev_priv(arlan_device[devnum]); - arlan_command(arlan_device[devnum],\ - ARLAN_COMMAND_CLEAN_AND_CONF); - } else - return -1; - - *lenp = pos; - return proc_dostring(ctl, write, buffer, lenp, ppos); -} - -static int arlan_sysctl_reset(ctl_table *ctl, int write, - void __user *buffer, size_t * lenp, loff_t *ppos) -{ - int pos = 0; - int devnum = ctl->procname[5] - '0'; - struct arlan_private *priv; - - if (devnum < 0 || devnum > MAX_ARLANS - 1) { - printk(KERN_WARNING "too strange devnum in procfs parse\n"); - return -1; - - } else if (arlan_device[devnum] != NULL) { - priv = netdev_priv(arlan_device[devnum]); - arlan_command(arlan_device[devnum], \ - ARLAN_COMMAND_CLEAN_AND_RESET); - - } else - return -1; - - *lenp = pos + 3; - return proc_dostring(ctl, write, buffer, lenp, ppos); -} - - -/* Place files in /proc/sys/dev/arlan */ -#define CTBLN(card, nam) \ - { .procname = #nam,\ - .data = &(arlan_conf[card].nam),\ - .maxlen = sizeof(int), .mode = 0600, .proc_handler = proc_dointvec} -#ifdef ARLAN_DEBUGGING - -#define ARLAN_PROC_DEBUG_ENTRIES do {\ - - { .procname = "entry_exit_debug",\ - .data = &arlan_entry_and_exit_debug,\ - .maxlen = sizeof(int), .mode = 0600, .proc_handler = proc_dointvec},\ - { .procname = "debug", .data = &arlan_debug,\ - .maxlen = sizeof(int), .mode = 0600, .proc_handler = proc_dointvec}, - - } while (0) -#else -#define ARLAN_PROC_DEBUG_ENTRIES -#endif - -#define ARLAN_SYSCTL_TABLE_TOTAL(cardNo)\ - CTBLN(cardNo, spreadingCode),\ - CTBLN(cardNo, channelNumber),\ - CTBLN(cardNo, scramblingDisable),\ - CTBLN(cardNo, txAttenuation),\ - CTBLN(cardNo, systemId), \ - CTBLN(cardNo, maxDatagramSize),\ - CTBLN(cardNo, maxFrameSize),\ - CTBLN(cardNo, maxRetries),\ - CTBLN(cardNo, receiveMode),\ - CTBLN(cardNo, priority),\ - CTBLN(cardNo, rootOrRepeater),\ - CTBLN(cardNo, SID),\ - CTBLN(cardNo, registrationMode),\ - CTBLN(cardNo, registrationFill),\ - CTBLN(cardNo, localTalkAddress),\ - CTBLN(cardNo, codeFormat),\ - CTBLN(cardNo, numChannels),\ - CTBLN(cardNo, channel1),\ - CTBLN(cardNo, channel2),\ - CTBLN(cardNo, channel3),\ - CTBLN(cardNo, channel4),\ - CTBLN(cardNo, txClear),\ - CTBLN(cardNo, txRetries),\ - CTBLN(cardNo, txRouting),\ - CTBLN(cardNo, txScrambled),\ - CTBLN(cardNo, rxParameter),\ - CTBLN(cardNo, txTimeoutMs),\ - CTBLN(cardNo, waitCardTimeout),\ - CTBLN(cardNo, channelSet),\ - { .procname = "name",\ - .data = arlan_conf[cardNo].siteName,\ - .maxlen = 16, .mode = 0600, .proc_handler = proc_dostring },\ - CTBLN(cardNo, waitTime),\ - CTBLN(cardNo, lParameter),\ - CTBLN(cardNo, _15),\ - CTBLN(cardNo, headerSize),\ - CTBLN(cardNo, tx_delay_ms),\ - CTBLN(cardNo, retries),\ - CTBLN(cardNo, ReTransmitPacketMaxSize),\ - CTBLN(cardNo, waitReTransmitPacketMaxSize),\ - CTBLN(cardNo, fastReTransCount),\ - CTBLN(cardNo, driverRetransmissions),\ - CTBLN(cardNo, txAckTimeoutMs),\ - CTBLN(cardNo, registrationInterrupts),\ - CTBLN(cardNo, hardwareType),\ - CTBLN(cardNo, radioType),\ - CTBLN(cardNo, writeEEPROM),\ - CTBLN(cardNo, writeRadioType),\ - ARLAN_PROC_DEBUG_ENTRIES\ - CTBLN(cardNo, in_speed),\ - CTBLN(cardNo, out_speed),\ - CTBLN(cardNo, in_speed10),\ - CTBLN(cardNo, out_speed10),\ - CTBLN(cardNo, in_speed_max),\ - CTBLN(cardNo, out_speed_max),\ - CTBLN(cardNo, measure_rate),\ - CTBLN(cardNo, pre_Command_Wait),\ - CTBLN(cardNo, rx_tweak1),\ - CTBLN(cardNo, rx_tweak2),\ - CTBLN(cardNo, tx_queue_len),\ - -static ctl_table arlan_conf_table0[] = { - ARLAN_SYSCTL_TABLE_TOTAL(0) - -#ifdef ARLAN_PROC_SHM_DUMP - { - .procname = "arlan0-txRing", - .data = &arlan_drive_info, - .maxlen = ARLAN_STR_SIZE, - .mode = 0400, - .proc_handler = arlan_sysctl_infotxRing, - }, - { - .procname = "arlan0-rxRing", - .data = &arlan_drive_info, - .maxlen = ARLAN_STR_SIZE, - .mode = 0400, - .proc_handler = arlan_sysctl_inforxRing, - }, - { - .procname = "arlan0-18", - .data = &arlan_drive_info, - .maxlen = ARLAN_STR_SIZE, - .mode = 0400, - .proc_handler = arlan_sysctl_info18, - }, - { - .procname = "arlan0-ring", - .data = &arlan_drive_info, - .maxlen = ARLAN_STR_SIZE, - .mode = 0400, - .proc_handler = arlan_sysctl_info161719, - }, - { - .procname = "arlan0-shm-cpy", - .data = &arlan_drive_info, - .maxlen = ARLAN_STR_SIZE, - .mode = 0400, - .proc_handler = arlan_sysctl_info, - }, -#endif - { - .procname = "config0", - .data = &conf_reset_result, - .maxlen = 100, - .mode = 0400, - .proc_handler = arlan_configure - }, - { - .procname = "reset0", - .data = &conf_reset_result, - .maxlen = 100, - .mode = 0400, - .proc_handler = arlan_sysctl_reset, - }, - { } -}; - -static ctl_table arlan_conf_table1[] = { - - ARLAN_SYSCTL_TABLE_TOTAL(1) - -#ifdef ARLAN_PROC_SHM_DUMP - { - .procname = "arlan1-txRing", - .data = &arlan_drive_info, - .maxlen = ARLAN_STR_SIZE, - .mode = 0400, - .proc_handler = arlan_sysctl_infotxRing, - }, - { - .procname = "arlan1-rxRing", - .data = &arlan_drive_info, - .maxlen = ARLAN_STR_SIZE, - .mode = 0400, - .proc_handler = arlan_sysctl_inforxRing, - }, - { - .procname = "arlan1-18", - .data = &arlan_drive_info, - .maxlen = ARLAN_STR_SIZE, - .mode = 0400, - .proc_handler = arlan_sysctl_info18, - }, - { - .procname = "arlan1-ring", - .data = &arlan_drive_info, - .maxlen = ARLAN_STR_SIZE, - .mode = 0400, - .proc_handler = arlan_sysctl_info161719, - }, - { - .procname = "arlan1-shm-cpy", - .data = &arlan_drive_info, - .maxlen = ARLAN_STR_SIZE, - .mode = 0400, - .proc_handler = arlan_sysctl_info, - }, -#endif - { - .procname = "config1", - .data = &conf_reset_result, - .maxlen = 100, - .mode = 0400, - .proc_handler = arlan_configure, - }, - { - .procname = "reset1", - .data = &conf_reset_result, - .maxlen = 100, - .mode = 0400, - .proc_handler = arlan_sysctl_reset, - }, - { } -}; - -static ctl_table arlan_conf_table2[] = { - - ARLAN_SYSCTL_TABLE_TOTAL(2) - -#ifdef ARLAN_PROC_SHM_DUMP - { - .procname = "arlan2-txRing", - .data = &arlan_drive_info, - .maxlen = ARLAN_STR_SIZE, - .mode = 0400, - .proc_handler = arlan_sysctl_infotxRing, - }, - { - .procname = "arlan2-rxRing", - .data = &arlan_drive_info, - .maxlen = ARLAN_STR_SIZE, - .mode = 0400, - .proc_handler = arlan_sysctl_inforxRing, - }, - { - .procname = "arlan2-18", - .data = &arlan_drive_info, - .maxlen = ARLAN_STR_SIZE, - .mode = 0400, - .proc_handler = arlan_sysctl_info18, - }, - { - .procname = "arlan2-ring", - .data = &arlan_drive_info, - .maxlen = ARLAN_STR_SIZE, - .mode = 0400, - .proc_handler = arlan_sysctl_info161719, - }, - { - .procname = "arlan2-shm-cpy", - .data = &arlan_drive_info, - .maxlen = ARLAN_STR_SIZE, - .mode = 0400, - .proc_handler = arlan_sysctl_info, - }, -#endif - { - .procname = "config2", - .data = &conf_reset_result, - .maxlen = 100, - .mode = 0400, - .proc_handler = arlan_configure, - }, - { - .procname = "reset2", - .data = &conf_reset_result, - .maxlen = 100, - .mode = 0400, - .proc_handler = arlan_sysctl_reset, - }, - { } -}; - -static ctl_table arlan_conf_table3[] = { - - ARLAN_SYSCTL_TABLE_TOTAL(3) - -#ifdef ARLAN_PROC_SHM_DUMP - { - .procname = "arlan3-txRing", - .data = &arlan_drive_info, - .maxlen = ARLAN_STR_SIZE, - .mode = 0400, - .proc_handler = arlan_sysctl_infotxRing, - }, - { - .procname = "arlan3-rxRing", - .data = &arlan_drive_info, - .maxlen = ARLAN_STR_SIZE, - .mode = 0400, - .proc_handler = arlan_sysctl_inforxRing, - }, - { - .procname = "arlan3-18", - .data = &arlan_drive_info, - .maxlen = ARLAN_STR_SIZE, - .mode = 0400, - .proc_handler = arlan_sysctl_info18, - }, - { - .procname = "arlan3-ring", - .data = &arlan_drive_info, - .maxlen = ARLAN_STR_SIZE, - .mode = 0400, - .proc_handler = arlan_sysctl_info161719, - }, - { - .procname = "arlan3-shm-cpy", - .data = &arlan_drive_info, - .maxlen = ARLAN_STR_SIZE, - .mode = 0400, - .proc_handler = arlan_sysctl_info, - }, -#endif - { - .procname = "config3", - .data = &conf_reset_result, - .maxlen = 100, - .mode = 0400, - .proc_handler = arlan_configure, - }, - { - .procname = "reset3", - .data = &conf_reset_result, - .maxlen = 100, - .mode = 0400, - .proc_handler = arlan_sysctl_reset, - }, - { } -}; - - - -static ctl_table arlan_table[] = { - { - .procname = "arlan0", - .maxlen = 0, - .mode = 0600, - .child = arlan_conf_table0, - }, - { - .procname = "arlan1", - .maxlen = 0, - .mode = 0600, - .child = arlan_conf_table1, - }, - { - .procname = "arlan2", - .maxlen = 0, - .mode = 0600, - .child = arlan_conf_table2, - }, - { - .procname = "arlan3", - .maxlen = 0, - .mode = 0600, - .child = arlan_conf_table3, - }, - { } -}; - -#else - -static ctl_table arlan_table[] = { - { } -}; -#endif - - -/* static int mmtu = 1234; */ - -static ctl_table arlan_root_table[] = { - { - .procname = "arlan", - .maxlen = 0, - .mode = 0555, - .child = arlan_table, - }, - { } -}; - - -static struct ctl_table_header *arlan_device_sysctl_header; - -int __init init_arlan_proc(void) -{ - if (arlan_device_sysctl_header) - return 0; - arlan_device_sysctl_header = register_sysctl_table(arlan_root_table); - if (!arlan_device_sysctl_header) - return -1; - - return 0; -} - -void __exit cleanup_arlan_proc(void) -{ - unregister_sysctl_table(arlan_device_sysctl_header); - arlan_device_sysctl_header = NULL; - -} -#endif diff --git a/drivers/staging/arlan/arlan.h b/drivers/staging/arlan/arlan.h deleted file mode 100644 index 3974acf076b9..000000000000 --- a/drivers/staging/arlan/arlan.h +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Copyright (C) 1997 Cullen Jennings - * Copyright (C) 1998 Elmer.Joandi@ut.ee, +37-255-13500 - * GNU General Public License applies - */ - -#include -#include -#include -#include -#include /* For the statistics structure. */ -#include /* For ARPHRD_ETHER */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - - -/* #define ARLAN_DEBUGGING 1 */ - -#define ARLAN_PROC_INTERFACE -#define MAX_ARLANS 4 /* not more than 4 ! */ -#define ARLAN_PROC_SHM_DUMP /* shows all card registers, makes driver way larger */ - -#define ARLAN_MAX_MULTICAST_ADDRS 16 -#define ARLAN_RCV_CLEAN 0 -#define ARLAN_RCV_PROMISC 1 -#define ARLAN_RCV_CONTROL 2 - -#ifdef CONFIG_PROC_FS -extern int init_arlan_proc(void); -extern void cleanup_arlan_proc(void); -#else -#define init_arlan_proc() ({ 0; }) -#define cleanup_arlan_proc() do { } while (0) -#endif - -extern struct net_device *arlan_device[MAX_ARLANS]; -extern int arlan_debug; -extern int arlan_entry_debug; -extern int arlan_exit_debug; -extern int testMemory; -extern int arlan_command(struct net_device *dev, int command); - -#define SIDUNKNOWN -1 -#define radioNodeIdUNKNOWN -1 -#define irqUNKNOWN 0 -#define debugUNKNOWN 0 -#define testMemoryUNKNOWN 1 -#define spreadingCodeUNKNOWN 0 -#define channelNumberUNKNOWN 0 -#define channelSetUNKNOWN 0 -#define systemIdUNKNOWN -1 -#define registrationModeUNKNOWN -1 - - -#define IFDEBUG(L) if ((L) & arlan_debug) -#define ARLAN_FAKE_HDR_LEN 12 - -#ifdef ARLAN_DEBUGGING - #define DEBUG 1 - #define ARLAN_ENTRY_EXIT_DEBUGGING 1 - #define ARLAN_DEBUG(a, b) printk(KERN_DEBUG a, b) -#else - #define ARLAN_DEBUG(a, b) -#endif - -#define ARLAN_SHMEM_SIZE 0x2000 - -struct arlan_shmem { - /* Header Signature */ - volatile char textRegion[48]; - volatile u_char resetFlag; - volatile u_char diagnosticInfo; - volatile u_short diagnosticOffset; - volatile u_char _1[12]; - volatile u_char lanCardNodeId[6]; - volatile u_char broadcastAddress[6]; - volatile u_char hardwareType; - volatile u_char majorHardwareVersion; - volatile u_char minorHardwareVersion; - volatile u_char radioModule;/* shows EEPROM, can be overridden at 0x111 */ - volatile u_char defaultChannelSet; /* shows EEProm, can be overriiden at 0x10A */ - volatile u_char _2[47]; - - /* Control/Status Block - 0x0080 */ - volatile u_char interruptInProgress; /* not used by lancpu */ - volatile u_char cntrlRegImage; /* not used by lancpu */ - volatile u_char _3[13]; - volatile u_char dumpByte; - volatile u_char commandByte; /* non-zero = active */ - volatile u_char commandParameter[15]; - - /* Receive Status - 0x00a0 */ - volatile u_char rxStatus; /* 1- data, 2-control, 0xff - registr change */ - volatile u_char rxFrmType; - volatile u_short rxOffset; - volatile u_short rxLength; - volatile u_char rxSrc[6]; - volatile u_char rxBroadcastFlag; - volatile u_char rxQuality; - volatile u_char scrambled; - volatile u_char _4[1]; - - /* Transmit Status - 0x00b0 */ - volatile u_char txStatus; - volatile u_char txAckQuality; - volatile u_char numRetries; - volatile u_char _5[14]; - volatile u_char registeredRouter[6]; - volatile u_char backboneRouter[6]; - volatile u_char registrationStatus; - volatile u_char configuredStatusFlag; - volatile u_char _6[1]; - volatile u_char ultimateDestAddress[6]; - volatile u_char immedDestAddress[6]; - volatile u_char immedSrcAddress[6]; - volatile u_short rxSequenceNumber; - volatile u_char assignedLocaltalkAddress; - volatile u_char _7[27]; - - /* System Parameter Block */ - - /* - Driver Parameters (Novell Specific) */ - - volatile u_short txTimeout; - volatile u_short transportTime; - volatile u_char _8[4]; - - /* - Configuration Parameters */ - volatile u_char irqLevel; - volatile u_char spreadingCode; - volatile u_char channelSet; - volatile u_char channelNumber; - volatile u_short radioNodeId; - volatile u_char _9[2]; - volatile u_char scramblingDisable; - volatile u_char radioType; - volatile u_short routerId; - volatile u_char _10[9]; - volatile u_char txAttenuation; - volatile u_char systemId[4]; - volatile u_short globalChecksum; - volatile u_char _11[4]; - volatile u_short maxDatagramSize; - volatile u_short maxFrameSize; - volatile u_char maxRetries; - volatile u_char receiveMode; - volatile u_char priority; - volatile u_char rootOrRepeater; - volatile u_char specifiedRouter[6]; - volatile u_short fastPollPeriod; - volatile u_char pollDecay; - volatile u_char fastPollDelay[2]; - volatile u_char arlThreshold; - volatile u_char arlDecay; - volatile u_char _12[1]; - volatile u_short specRouterTimeout; - volatile u_char _13[5]; - - /* Scrambled Area */ - volatile u_char SID[4]; - volatile u_char encryptionKey[12]; - volatile u_char _14[2]; - volatile u_char waitTime[2]; - volatile u_char lParameter[2]; - volatile u_char _15[3]; - volatile u_short headerSize; - volatile u_short sectionChecksum; - - volatile u_char registrationMode; - volatile u_char registrationFill; - volatile u_short pollPeriod; - volatile u_short refreshPeriod; - volatile u_char name[16]; - volatile u_char NID[6]; - volatile u_char localTalkAddress; - volatile u_char codeFormat; - volatile u_char numChannels; - volatile u_char channel1; - volatile u_char channel2; - volatile u_char channel3; - volatile u_char channel4; - volatile u_char SSCode[59]; - - volatile u_char _16[0xC0]; - volatile u_short auxCmd; - volatile u_char dumpPtr[4]; - volatile u_char dumpVal; - volatile u_char _17[0x6A]; - volatile u_char wireTest; - volatile u_char _18[14]; - - /* Statistics Block - 0x0300 */ - volatile u_char hostcpuLock; - volatile u_char lancpuLock; - volatile u_char resetTime[18]; - - volatile u_char numDatagramsTransmitted[4]; - volatile u_char numReTransmissions[4]; - volatile u_char numFramesDiscarded[4]; - volatile u_char numDatagramsReceived[4]; - volatile u_char numDuplicateReceivedFrames[4]; - volatile u_char numDatagramsDiscarded[4]; - - volatile u_short maxNumReTransmitDatagram; - volatile u_short maxNumReTransmitFrames; - volatile u_short maxNumConsecutiveDuplicateFrames; - /* misaligned here so we have to go to characters */ - - volatile u_char numBytesTransmitted[4]; - volatile u_char numBytesReceived[4]; - volatile u_char numCRCErrors[4]; - volatile u_char numLengthErrors[4]; - volatile u_char numAbortErrors[4]; - volatile u_char numTXUnderruns[4]; - volatile u_char numRXOverruns[4]; - volatile u_char numHoldOffs[4]; - volatile u_char numFramesTransmitted[4]; - volatile u_char numFramesReceived[4]; - volatile u_char numReceiveFramesLost[4]; - volatile u_char numRXBufferOverflows[4]; - volatile u_char numFramesDiscardedAddrMismatch[4]; - volatile u_char numFramesDiscardedSIDMismatch[4]; - volatile u_char numPollsTransmistted[4]; - volatile u_char numPollAcknowledges[4]; - volatile u_char numStatusTimeouts[4]; - volatile u_char numNACKReceived[4]; - - volatile u_char _19[0x86]; - - volatile u_char txBuffer[0x800]; - volatile u_char rxBuffer[0x800]; - - volatile u_char _20[0x800]; - volatile u_char _21[0x3fb]; - volatile u_char configStatus; - volatile u_char _22; - volatile u_char progIOCtrl; - volatile u_char shareMBase; - volatile u_char controlRegister; -}; - -struct arlan_conf_stru { - int spreadingCode; - int channelSet; - int channelNumber; - int scramblingDisable; - int txAttenuation; - int systemId; - int maxDatagramSize; - int maxFrameSize; - int maxRetries; - int receiveMode; - int priority; - int rootOrRepeater; - int SID; - int radioNodeId; - int registrationMode; - int registrationFill; - int localTalkAddress; - int codeFormat; - int numChannels; - int channel1; - int channel2; - int channel3; - int channel4; - int txClear; - int txRetries; - int txRouting; - int txScrambled; - int rxParameter; - int txTimeoutMs; - int txAckTimeoutMs; - int waitCardTimeout; - int waitTime; - int lParameter; - int _15; - int headerSize; - int retries; - int tx_delay_ms; - int waitReTransmitPacketMaxSize; - int ReTransmitPacketMaxSize; - int fastReTransCount; - int driverRetransmissions; - int registrationInterrupts; - int hardwareType; - int radioType; - int writeRadioType; - int writeEEPROM; - char siteName[17]; - int measure_rate; - int in_speed; - int out_speed; - int in_speed10; - int out_speed10; - int in_speed_max; - int out_speed_max; - int pre_Command_Wait; - int rx_tweak1; - int rx_tweak2; - int tx_queue_len; -}; - -extern struct arlan_conf_stru arlan_conf[MAX_ARLANS]; - -struct TxParam { - volatile short offset; - volatile short length; - volatile u_char dest[6]; - volatile unsigned char clear; - volatile unsigned char retries; - volatile unsigned char routing; - volatile unsigned char scrambled; -}; - -#define TX_RING_SIZE 2 -/* Information that need to be kept for each board. */ -struct arlan_private { - struct arlan_shmem __iomem *card; - struct arlan_shmem *conf; - - struct arlan_conf_stru *Conf; - int bad; - int reset; - unsigned long lastReset; - struct timer_list timer; - struct timer_list tx_delay_timer; - struct timer_list tx_retry_timer; - struct timer_list rx_check_timer; - - int registrationLostCount; - int reRegisterExp; - int irq_test_done; - - struct TxParam txRing[TX_RING_SIZE]; - char reTransmitBuff[0x800]; - int txLast; - unsigned ReTransmitRequested; - unsigned long tx_done_delayed; - unsigned long registrationLastSeen; - - unsigned long tx_last_sent; - unsigned long tx_last_cleared; - unsigned long retransmissions; - unsigned long interrupt_ack_requested; - spinlock_t lock; - unsigned long waiting_command_mask; - unsigned long card_polling_interval; - unsigned long last_command_buff_free_time; - - int under_reset; - int under_config; - int rx_command_given; - int tx_command_given; - unsigned long interrupt_processing_active; - unsigned long last_rx_int_ack_time; - unsigned long in_bytes; - unsigned long out_bytes; - unsigned long in_time; - unsigned long out_time; - unsigned long in_time10; - unsigned long out_time10; - unsigned long in_bytes10; - unsigned long out_bytes10; - int init_etherdev_alloc; -}; - - - -#define ARLAN_CLEAR 0x00 -#define ARLAN_RESET 0x01 -#define ARLAN_CHANNEL_ATTENTION 0x02 -#define ARLAN_INTERRUPT_ENABLE 0x04 -#define ARLAN_CLEAR_INTERRUPT 0x08 -#define ARLAN_POWER 0x40 -#define ARLAN_ACCESS 0x80 - -#define ARLAN_COM_CONF 0x01 -#define ARLAN_COM_RX_ENABLE 0x03 -#define ARLAN_COM_RX_ABORT 0x04 -#define ARLAN_COM_TX_ENABLE 0x05 -#define ARLAN_COM_TX_ABORT 0x06 -#define ARLAN_COM_NOP 0x07 -#define ARLAN_COM_STANDBY 0x08 -#define ARLAN_COM_ACTIVATE 0x09 -#define ARLAN_COM_GOTO_SLOW_POLL 0x0a -#define ARLAN_COM_INT 0x80 - - -#define TXLAST(dev) (((struct arlan_private *)netdev_priv(dev))->txRing[((struct arlan_private *)netdev_priv(dev))->txLast]) -#define TXHEAD(dev) (((struct arlan_private *)netdev_priv(dev))->txRing[0]) -#define TXTAIL(dev) (((struct arlan_private *)netdev_priv(dev))->txRing[1]) - -#define TXBuffStart(dev) offsetof(struct arlan_shmem, txBuffer) -#define TXBuffEnd(dev) offsetof(struct arlan_shmem, xxBuffer) - -#define READSHM(to, from, atype) {\ - atype tmp;\ - memcpy_fromio(&(tmp), &(from), sizeof(atype));\ - to = tmp;\ - } - -#define READSHMEM(from, atype)\ - atype from; \ - READSHM(from, arlan->from, atype); - -#define WRITESHM(to, from, atype) \ - { atype tmpSHM = from;\ - memcpy_toio(&(to), &tmpSHM, sizeof(atype));\ - } - -#define DEBUGSHM(levelSHM, stringSHM, stuff, atype) \ - { atype tmpSHM; \ - memcpy_fromio(&tmpSHM, &(stuff), sizeof(atype));\ - IFDEBUG(levelSHM) printk(stringSHM, tmpSHM);\ - } - -#define WRITESHMB(to, val) \ - writeb(val, &(to)) -#define READSHMB(to) \ - readb(&(to)) -#define WRITESHMS(to, val) \ - writew(val, &(to)) -#define READSHMS(to) \ - readw(&(to)) -#define WRITESHMI(to, val) \ - writel(val, &(to)) -#define READSHMI(to) \ - readl(&(to)) - - - - - -#define registrationBad(dev)\ - ((READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationMode) > 0) && \ - (READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationStatus) == 0)) - - -#define readControlRegister(dev)\ - READSHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage) - -#define writeControlRegister(dev, v) {\ - WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage, ((v) & 0xF));\ - WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->controlRegister, (v)); } - - -#define arlan_interrupt_lancpu(dev) {\ - int cr; \ - \ - cr = readControlRegister(dev);\ - if (cr & ARLAN_CHANNEL_ATTENTION) \ - writeControlRegister(dev, (cr & ~ARLAN_CHANNEL_ATTENTION));\ - else \ - writeControlRegister(dev, (cr | ARLAN_CHANNEL_ATTENTION));\ -} - -#define clearChannelAttention(dev) { \ - writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_CHANNEL_ATTENTION); } -#define setHardwareReset(dev) {\ - writeControlRegister(dev, readControlRegister(dev) | ARLAN_RESET); } -#define clearHardwareReset(dev) {\ - writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_RESET); } -#define setInterruptEnable(dev) {\ - writeControlRegister(dev, readControlRegister(dev) | ARLAN_INTERRUPT_ENABLE) ; } -#define clearInterruptEnable(dev) {\ - writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_INTERRUPT_ENABLE) ; } -#define setClearInterrupt(dev) {\ - writeControlRegister(dev, readControlRegister(dev) | ARLAN_CLEAR_INTERRUPT) ; } -#define clearClearInterrupt(dev) {\ - writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_CLEAR_INTERRUPT); } -#define setPowerOff(dev) {\ - writeControlRegister(dev, readControlRegister(dev) | (ARLAN_POWER && ARLAN_ACCESS));\ - writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_ACCESS); } -#define setPowerOn(dev) {\ - writeControlRegister(dev, readControlRegister(dev) & ~(ARLAN_POWER)); } -#define arlan_lock_card_access(dev) {\ - writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_ACCESS); } -#define arlan_unlock_card_access(dev) {\ - writeControlRegister(dev, readControlRegister(dev) | ARLAN_ACCESS); } - - - - -#define ARLAN_COMMAND_RX 0x000001 -#define ARLAN_COMMAND_NOOP 0x000002 -#define ARLAN_COMMAND_NOOPINT 0x000004 -#define ARLAN_COMMAND_TX 0x000008 -#define ARLAN_COMMAND_CONF 0x000010 -#define ARLAN_COMMAND_RESET 0x000020 -#define ARLAN_COMMAND_TX_ABORT 0x000040 -#define ARLAN_COMMAND_RX_ABORT 0x000080 -#define ARLAN_COMMAND_POWERDOWN 0x000100 -#define ARLAN_COMMAND_POWERUP 0x000200 -#define ARLAN_COMMAND_SLOW_POLL 0x000400 -#define ARLAN_COMMAND_ACTIVATE 0x000800 -#define ARLAN_COMMAND_INT_ACK 0x001000 -#define ARLAN_COMMAND_INT_ENABLE 0x002000 -#define ARLAN_COMMAND_WAIT_NOW 0x004000 -#define ARLAN_COMMAND_LONG_WAIT_NOW 0x008000 -#define ARLAN_COMMAND_STANDBY 0x010000 -#define ARLAN_COMMAND_INT_RACK 0x020000 -#define ARLAN_COMMAND_INT_RENABLE 0x040000 -#define ARLAN_COMMAND_CONF_WAIT 0x080000 -#define ARLAN_COMMAND_TBUSY_CLEAR 0x100000 -#define ARLAN_COMMAND_CLEAN_AND_CONF (ARLAN_COMMAND_TX_ABORT\ - | ARLAN_COMMAND_RX_ABORT\ - | ARLAN_COMMAND_CONF) -#define ARLAN_COMMAND_CLEAN_AND_RESET (ARLAN_COMMAND_TX_ABORT\ - | ARLAN_COMMAND_RX_ABORT\ - | ARLAN_COMMAND_RESET) - - -#define ARLAN_DEBUG_CHAIN_LOCKS 0x00001 -#define ARLAN_DEBUG_RESET 0x00002 -#define ARLAN_DEBUG_TIMING 0x00004 -#define ARLAN_DEBUG_CARD_STATE 0x00008 -#define ARLAN_DEBUG_TX_CHAIN 0x00010 -#define ARLAN_DEBUG_MULTICAST 0x00020 -#define ARLAN_DEBUG_HEADER_DUMP 0x00040 -#define ARLAN_DEBUG_INTERRUPT 0x00080 -#define ARLAN_DEBUG_STARTUP 0x00100 -#define ARLAN_DEBUG_SHUTDOWN 0x00200 -- cgit v1.2.3 From f80a3f62383bf673c310926d55142d51f118926d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 23:13:37 -0700 Subject: Staging: strip: delete the driver It has sat in the staging directory since October of 2009, and no one has stepped up to take it over, so odds are, no one cares about it anymore. So, it is now deleted as scheduled, and documented in the TODO file. Cc: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/strip/Kconfig | 22 - drivers/staging/strip/Makefile | 1 - drivers/staging/strip/TODO | 7 - drivers/staging/strip/strip.c | 2823 ---------------------------------------- 6 files changed, 2856 deletions(-) delete mode 100644 drivers/staging/strip/Kconfig delete mode 100644 drivers/staging/strip/Makefile delete mode 100644 drivers/staging/strip/TODO delete mode 100644 drivers/staging/strip/strip.c (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 8bf839ea05f5..4ca05017c1ad 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -125,8 +125,6 @@ source "drivers/staging/batman-adv/Kconfig" source "drivers/staging/samsung-laptop/Kconfig" -source "drivers/staging/strip/Kconfig" - source "drivers/staging/wavelan/Kconfig" source "drivers/staging/netwave/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index b2747068fff0..e308274bb148 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -43,7 +43,6 @@ obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/ obj-$(CONFIG_BATMAN_ADV) += batman-adv/ obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop/ -obj-$(CONFIG_STRIP) += strip/ obj-$(CONFIG_WAVELAN) += wavelan/ obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan/ obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/ diff --git a/drivers/staging/strip/Kconfig b/drivers/staging/strip/Kconfig deleted file mode 100644 index 36257b5cd6e1..000000000000 --- a/drivers/staging/strip/Kconfig +++ /dev/null @@ -1,22 +0,0 @@ -config STRIP - tristate "STRIP (Metricom starmode radio IP)" - depends on INET - select WIRELESS_EXT - ---help--- - Say Y if you have a Metricom radio and intend to use Starmode Radio - IP. STRIP is a radio protocol developed for the MosquitoNet project - to send Internet traffic using Metricom radios. Metricom radios are - small, battery powered, 100kbit/sec packet radio transceivers, about - the size and weight of a cellular telephone. (You may also have heard - them called "Metricom modems" but we avoid the term "modem" because - it misleads many people into thinking that you can plug a Metricom - modem into a phone line and use it as a modem.) - - You can use STRIP on any Linux machine with a serial port, although - it is obviously most useful for people with laptop computers. If you - think you might get a Metricom radio in the future, there is no harm - in saying Y to STRIP now, except that it makes the kernel a bit - bigger. - - To compile this as a module, choose M here: the module will be - called strip. diff --git a/drivers/staging/strip/Makefile b/drivers/staging/strip/Makefile deleted file mode 100644 index 6417bdcac2fb..000000000000 --- a/drivers/staging/strip/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_STRIP) += strip.o diff --git a/drivers/staging/strip/TODO b/drivers/staging/strip/TODO deleted file mode 100644 index 9bd15a2f6d9e..000000000000 --- a/drivers/staging/strip/TODO +++ /dev/null @@ -1,7 +0,0 @@ -TODO: - - step up and maintain this driver to ensure that it continues - to work. Having the hardware for this is pretty much a - requirement. If this does not happen, the will be removed in - the 2.6.35 kernel release. - -Please send patches to Greg Kroah-Hartman . diff --git a/drivers/staging/strip/strip.c b/drivers/staging/strip/strip.c deleted file mode 100644 index c976c6b4d28a..000000000000 --- a/drivers/staging/strip/strip.c +++ /dev/null @@ -1,2823 +0,0 @@ -/* - * Copyright 1996 The Board of Trustees of The Leland Stanford - * Junior University. All Rights Reserved. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies. Stanford University - * makes no representations about the suitability of this - * software for any purpose. It is provided "as is" without - * express or implied warranty. - * - * strip.c This module implements Starmode Radio IP (STRIP) - * for kernel-based devices like TTY. It interfaces between a - * raw TTY, and the kernel's INET protocol layers (via DDI). - * - * Version: @(#)strip.c 1.3 July 1997 - * - * Author: Stuart Cheshire - * - * Fixes: v0.9 12th Feb 1996 (SC) - * New byte stuffing (2+6 run-length encoding) - * New watchdog timer task - * New Protocol key (SIP0) - * - * v0.9.1 3rd March 1996 (SC) - * Changed to dynamic device allocation -- no more compile - * time (or boot time) limit on the number of STRIP devices. - * - * v0.9.2 13th March 1996 (SC) - * Uses arp cache lookups (but doesn't send arp packets yet) - * - * v0.9.3 17th April 1996 (SC) - * Fixed bug where STR_ERROR flag was getting set unneccessarily - * (causing otherwise good packets to be unneccessarily dropped) - * - * v0.9.4 27th April 1996 (SC) - * First attempt at using "&COMMAND" Starmode AT commands - * - * v0.9.5 29th May 1996 (SC) - * First attempt at sending (unicast) ARP packets - * - * v0.9.6 5th June 1996 (Elliot) - * Put "message level" tags in every "printk" statement - * - * v0.9.7 13th June 1996 (laik) - * Added support for the /proc fs - * - * v0.9.8 July 1996 (Mema) - * Added packet logging - * - * v1.0 November 1996 (SC) - * Fixed (severe) memory leaks in the /proc fs code - * Fixed race conditions in the logging code - * - * v1.1 January 1997 (SC) - * Deleted packet logging (use tcpdump instead) - * Added support for Metricom Firmware v204 features - * (like message checksums) - * - * v1.2 January 1997 (SC) - * Put portables list back in - * - * v1.3 July 1997 (SC) - * Made STRIP driver set the radio's baud rate automatically. - * It is no longer necessarily to manually set the radio's - * rate permanently to 115200 -- the driver handles setting - * the rate automatically. - */ - -#ifdef MODULE -static const char StripVersion[] = "1.3A-STUART.CHESHIRE-MODULAR"; -#else -static const char StripVersion[] = "1.3A-STUART.CHESHIRE"; -#endif - -#define TICKLE_TIMERS 0 -#define EXT_COUNTERS 1 - - -/************************************************************************/ -/* Header files */ - -#include -#include -#include -#include -#include -#include - -# include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/************************************************************************/ -/* Useful structures and definitions */ - -/* - * A MetricomKey identifies the protocol being carried inside a Metricom - * Starmode packet. - */ - -typedef union { - __u8 c[4]; - __u32 l; -} MetricomKey; - -/* - * An IP address can be viewed as four bytes in memory (which is what it is) or as - * a single 32-bit long (which is convenient for assignment, equality testing etc.) - */ - -typedef union { - __u8 b[4]; - __u32 l; -} IPaddr; - -/* - * A MetricomAddressString is used to hold a printable representation of - * a Metricom address. - */ - -typedef struct { - __u8 c[24]; -} MetricomAddressString; - -/* Encapsulation can expand packet of size x to 65/64x + 1 - * Sent packet looks like "*
*" - * 1 1 1-18 1 4 ? 1 - * eg. *0000-1234*SIP0 - * We allow 31 bytes for the stars, the key, the address and the s - */ -#define STRIP_ENCAP_SIZE(X) (32 + (X)*65L/64L) - -/* - * A STRIP_Header is never really sent over the radio, but making a dummy - * header for internal use within the kernel that looks like an Ethernet - * header makes certain other software happier. For example, tcpdump - * already understands Ethernet headers. - */ - -typedef struct { - MetricomAddress dst_addr; /* Destination address, e.g. "0000-1234" */ - MetricomAddress src_addr; /* Source address, e.g. "0000-5678" */ - unsigned short protocol; /* The protocol type, using Ethernet codes */ -} STRIP_Header; - -typedef struct { - char c[60]; -} MetricomNode; - -#define NODE_TABLE_SIZE 32 -typedef struct { - struct timeval timestamp; - int num_nodes; - MetricomNode node[NODE_TABLE_SIZE]; -} MetricomNodeTable; - -enum { FALSE = 0, TRUE = 1 }; - -/* - * Holds the radio's firmware version. - */ -typedef struct { - char c[50]; -} FirmwareVersion; - -/* - * Holds the radio's serial number. - */ -typedef struct { - char c[18]; -} SerialNumber; - -/* - * Holds the radio's battery voltage. - */ -typedef struct { - char c[11]; -} BatteryVoltage; - -typedef struct { - char c[8]; -} char8; - -enum { - NoStructure = 0, /* Really old firmware */ - StructuredMessages = 1, /* Parsable AT response msgs */ - ChecksummedMessages = 2 /* Parsable AT response msgs with checksums */ -}; - -struct strip { - int magic; - /* - * These are pointers to the malloc()ed frame buffers. - */ - - unsigned char *rx_buff; /* buffer for received IP packet */ - unsigned char *sx_buff; /* buffer for received serial data */ - int sx_count; /* received serial data counter */ - int sx_size; /* Serial buffer size */ - unsigned char *tx_buff; /* transmitter buffer */ - unsigned char *tx_head; /* pointer to next byte to XMIT */ - int tx_left; /* bytes left in XMIT queue */ - int tx_size; /* Serial buffer size */ - - /* - * STRIP interface statistics. - */ - - unsigned long rx_packets; /* inbound frames counter */ - unsigned long tx_packets; /* outbound frames counter */ - unsigned long rx_errors; /* Parity, etc. errors */ - unsigned long tx_errors; /* Planned stuff */ - unsigned long rx_dropped; /* No memory for skb */ - unsigned long tx_dropped; /* When MTU change */ - unsigned long rx_over_errors; /* Frame bigger than STRIP buf. */ - - unsigned long pps_timer; /* Timer to determine pps */ - unsigned long rx_pps_count; /* Counter to determine pps */ - unsigned long tx_pps_count; /* Counter to determine pps */ - unsigned long sx_pps_count; /* Counter to determine pps */ - unsigned long rx_average_pps; /* rx packets per second * 8 */ - unsigned long tx_average_pps; /* tx packets per second * 8 */ - unsigned long sx_average_pps; /* sent packets per second * 8 */ - -#ifdef EXT_COUNTERS - unsigned long rx_bytes; /* total received bytes */ - unsigned long tx_bytes; /* total received bytes */ - unsigned long rx_rbytes; /* bytes thru radio i/f */ - unsigned long tx_rbytes; /* bytes thru radio i/f */ - unsigned long rx_sbytes; /* tot bytes thru serial i/f */ - unsigned long tx_sbytes; /* tot bytes thru serial i/f */ - unsigned long rx_ebytes; /* tot stat/err bytes */ - unsigned long tx_ebytes; /* tot stat/err bytes */ -#endif - - /* - * Internal variables. - */ - - struct list_head list; /* Linked list of devices */ - - int discard; /* Set if serial error */ - int working; /* Is radio working correctly? */ - int firmware_level; /* Message structuring level */ - int next_command; /* Next periodic command */ - unsigned int user_baud; /* The user-selected baud rate */ - int mtu; /* Our mtu (to spot changes!) */ - long watchdog_doprobe; /* Next time to test the radio */ - long watchdog_doreset; /* Time to do next reset */ - long gratuitous_arp; /* Time to send next ARP refresh */ - long arp_interval; /* Next ARP interval */ - struct timer_list idle_timer; /* For periodic wakeup calls */ - MetricomAddress true_dev_addr; /* True address of radio */ - int manual_dev_addr; /* Hack: See note below */ - - FirmwareVersion firmware_version; /* The radio's firmware version */ - SerialNumber serial_number; /* The radio's serial number */ - BatteryVoltage battery_voltage; /* The radio's battery voltage */ - - /* - * Other useful structures. - */ - - struct tty_struct *tty; /* ptr to TTY structure */ - struct net_device *dev; /* Our device structure */ - - /* - * Neighbour radio records - */ - - MetricomNodeTable portables; - MetricomNodeTable poletops; -}; - -/* - * Note: manual_dev_addr hack - * - * It is not possible to change the hardware address of a Metricom radio, - * or to send packets with a user-specified hardware source address, thus - * trying to manually set a hardware source address is a questionable - * thing to do. However, if the user *does* manually set the hardware - * source address of a STRIP interface, then the kernel will believe it, - * and use it in certain places. For example, the hardware address listed - * by ifconfig will be the manual address, not the true one. - * (Both addresses are listed in /proc/net/strip.) - * Also, ARP packets will be sent out giving the user-specified address as - * the source address, not the real address. This is dangerous, because - * it means you won't receive any replies -- the ARP replies will go to - * the specified address, which will be some other radio. The case where - * this is useful is when that other radio is also connected to the same - * machine. This allows you to connect a pair of radios to one machine, - * and to use one exclusively for inbound traffic, and the other - * exclusively for outbound traffic. Pretty neat, huh? - * - * Here's the full procedure to set this up: - * - * 1. "slattach" two interfaces, e.g. st0 for outgoing packets, - * and st1 for incoming packets - * - * 2. "ifconfig" st0 (outbound radio) to have the hardware address - * which is the real hardware address of st1 (inbound radio). - * Now when it sends out packets, it will masquerade as st1, and - * replies will be sent to that radio, which is exactly what we want. - * - * 3. Set the route table entry ("route add default ..." or - * "route add -net ...", as appropriate) to send packets via the st0 - * interface (outbound radio). Do not add any route which sends packets - * out via the st1 interface -- that radio is for inbound traffic only. - * - * 4. "ifconfig" st1 (inbound radio) to have hardware address zero. - * This tells the STRIP driver to "shut down" that interface and not - * send any packets through it. In particular, it stops sending the - * periodic gratuitous ARP packets that a STRIP interface normally sends. - * Also, when packets arrive on that interface, it will search the - * interface list to see if there is another interface who's manual - * hardware address matches its own real address (i.e. st0 in this - * example) and if so it will transfer ownership of the skbuff to - * that interface, so that it looks to the kernel as if the packet - * arrived on that interface. This is necessary because when the - * kernel sends an ARP packet on st0, it expects to get a reply on - * st0, and if it sees the reply come from st1 then it will ignore - * it (to be accurate, it puts the entry in the ARP table, but - * labelled in such a way that st0 can't use it). - * - * Thanks to Petros Maniatis for coming up with the idea of splitting - * inbound and outbound traffic between two interfaces, which turned - * out to be really easy to implement, even if it is a bit of a hack. - * - * Having set a manual address on an interface, you can restore it - * to automatic operation (where the address is automatically kept - * consistent with the real address of the radio) by setting a manual - * address of all ones, e.g. "ifconfig st0 hw strip FFFFFFFFFFFF" - * This 'turns off' manual override mode for the device address. - * - * Note: The IEEE 802 headers reported in tcpdump will show the *real* - * radio addresses the packets were sent and received from, so that you - * can see what is really going on with packets, and which interfaces - * they are really going through. - */ - - -/************************************************************************/ -/* Constants */ - -/* - * CommandString1 works on all radios - * Other CommandStrings are only used with firmware that provides structured responses. - * - * ats319=1 Enables Info message for node additions and deletions - * ats319=2 Enables Info message for a new best node - * ats319=4 Enables checksums - * ats319=8 Enables ACK messages - */ - -static const int MaxCommandStringLength = 32; -static const int CompatibilityCommand = 1; - -static const char CommandString0[] = "*&COMMAND*ATS319=7"; /* Turn on checksums & info messages */ -static const char CommandString1[] = "*&COMMAND*ATS305?"; /* Query radio name */ -static const char CommandString2[] = "*&COMMAND*ATS325?"; /* Query battery voltage */ -static const char CommandString3[] = "*&COMMAND*ATS300?"; /* Query version information */ -static const char CommandString4[] = "*&COMMAND*ATS311?"; /* Query poletop list */ -static const char CommandString5[] = "*&COMMAND*AT~LA"; /* Query portables list */ -typedef struct { - const char *string; - long length; -} StringDescriptor; - -static const StringDescriptor CommandString[] = { - {CommandString0, sizeof(CommandString0) - 1}, - {CommandString1, sizeof(CommandString1) - 1}, - {CommandString2, sizeof(CommandString2) - 1}, - {CommandString3, sizeof(CommandString3) - 1}, - {CommandString4, sizeof(CommandString4) - 1}, - {CommandString5, sizeof(CommandString5) - 1} -}; - -#define GOT_ALL_RADIO_INFO(S) \ - ((S)->firmware_version.c[0] && \ - (S)->battery_voltage.c[0] && \ - memcmp(&(S)->true_dev_addr, zero_address.c, sizeof(zero_address))) - -static const char hextable[16] = "0123456789ABCDEF"; - -static const MetricomAddress zero_address; -static const MetricomAddress broadcast_address = - { {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} }; - -static const MetricomKey SIP0Key = { "SIP0" }; -static const MetricomKey ARP0Key = { "ARP0" }; -static const MetricomKey ATR_Key = { "ATR " }; -static const MetricomKey ACK_Key = { "ACK_" }; -static const MetricomKey INF_Key = { "INF_" }; -static const MetricomKey ERR_Key = { "ERR_" }; - -static const long MaxARPInterval = 60 * HZ; /* One minute */ - -/* - * Maximum Starmode packet length is 1183 bytes. Allowing 4 bytes for - * protocol key, 4 bytes for checksum, one byte for CR, and 65/64 expansion - * for STRIP encoding, that translates to a maximum payload MTU of 1155. - * Note: A standard NFS 1K data packet is a total of 0x480 (1152) bytes - * long, including IP header, UDP header, and NFS header. Setting the STRIP - * MTU to 1152 allows us to send default sized NFS packets without fragmentation. - */ -static const unsigned short MAX_SEND_MTU = 1152; -static const unsigned short MAX_RECV_MTU = 1500; /* Hoping for Ethernet sized packets in the future! */ -static const unsigned short DEFAULT_STRIP_MTU = 1152; -static const int STRIP_MAGIC = 0x5303; -static const long LongTime = 0x7FFFFFFF; - -/************************************************************************/ -/* Global variables */ - -static LIST_HEAD(strip_list); -static DEFINE_SPINLOCK(strip_lock); - -/************************************************************************/ -/* Macros */ - -/* Returns TRUE if text T begins with prefix P */ -#define has_prefix(T,L,P) (((L) >= sizeof(P)-1) && !strncmp((T), (P), sizeof(P)-1)) - -/* Returns TRUE if text T of length L is equal to string S */ -#define text_equal(T,L,S) (((L) == sizeof(S)-1) && !strncmp((T), (S), sizeof(S)-1)) - -#define READHEX(X) ((X)>='0' && (X)<='9' ? (X)-'0' : \ - (X)>='a' && (X)<='f' ? (X)-'a'+10 : \ - (X)>='A' && (X)<='F' ? (X)-'A'+10 : 0 ) - -#define READHEX16(X) ((__u16)(READHEX(X))) - -#define READDEC(X) ((X)>='0' && (X)<='9' ? (X)-'0' : 0) - -#define ARRAY_END(X) (&((X)[ARRAY_SIZE(X)])) - -#define JIFFIE_TO_SEC(X) ((X) / HZ) - - -/************************************************************************/ -/* Utility routines */ - -static int arp_query(unsigned char *haddr, u32 paddr, - struct net_device *dev) -{ - struct neighbour *neighbor_entry; - int ret = 0; - - neighbor_entry = neigh_lookup(&arp_tbl, &paddr, dev); - - if (neighbor_entry != NULL) { - neighbor_entry->used = jiffies; - if (neighbor_entry->nud_state & NUD_VALID) { - memcpy(haddr, neighbor_entry->ha, dev->addr_len); - ret = 1; - } - neigh_release(neighbor_entry); - } - return ret; -} - -static void DumpData(char *msg, struct strip *strip_info, __u8 * ptr, - __u8 * end) -{ - static const int MAX_DumpData = 80; - __u8 pkt_text[MAX_DumpData], *p = pkt_text; - - *p++ = '\"'; - - while (ptr < end && p < &pkt_text[MAX_DumpData - 4]) { - if (*ptr == '\\') { - *p++ = '\\'; - *p++ = '\\'; - } else { - if (*ptr >= 32 && *ptr <= 126) { - *p++ = *ptr; - } else { - sprintf(p, "\\%02X", *ptr); - p += 3; - } - } - ptr++; - } - - if (ptr == end) - *p++ = '\"'; - *p++ = 0; - - printk(KERN_INFO "%s: %-13s%s\n", strip_info->dev->name, msg, pkt_text); -} - - -/************************************************************************/ -/* Byte stuffing/unstuffing routines */ - -/* Stuffing scheme: - * 00 Unused (reserved character) - * 01-3F Run of 2-64 different characters - * 40-7F Run of 1-64 different characters plus a single zero at the end - * 80-BF Run of 1-64 of the same character - * C0-FF Run of 1-64 zeroes (ASCII 0) - */ - -typedef enum { - Stuff_Diff = 0x00, - Stuff_DiffZero = 0x40, - Stuff_Same = 0x80, - Stuff_Zero = 0xC0, - Stuff_NoCode = 0xFF, /* Special code, meaning no code selected */ - - Stuff_CodeMask = 0xC0, - Stuff_CountMask = 0x3F, - Stuff_MaxCount = 0x3F, - Stuff_Magic = 0x0D /* The value we are eliminating */ -} StuffingCode; - -/* StuffData encodes the data starting at "src" for "length" bytes. - * It writes it to the buffer pointed to by "dst" (which must be at least - * as long as 1 + 65/64 of the input length). The output may be up to 1.6% - * larger than the input for pathological input, but will usually be smaller. - * StuffData returns the new value of the dst pointer as its result. - * "code_ptr_ptr" points to a "__u8 *" which is used to hold encoding state - * between calls, allowing an encoded packet to be incrementally built up - * from small parts. On the first call, the "__u8 *" pointed to should be - * initialized to NULL; between subsequent calls the calling routine should - * leave the value alone and simply pass it back unchanged so that the - * encoder can recover its current state. - */ - -#define StuffData_FinishBlock(X) \ -(*code_ptr = (X) ^ Stuff_Magic, code = Stuff_NoCode) - -static __u8 *StuffData(__u8 * src, __u32 length, __u8 * dst, - __u8 ** code_ptr_ptr) -{ - __u8 *end = src + length; - __u8 *code_ptr = *code_ptr_ptr; - __u8 code = Stuff_NoCode, count = 0; - - if (!length) - return (dst); - - if (code_ptr) { - /* - * Recover state from last call, if applicable - */ - code = (*code_ptr ^ Stuff_Magic) & Stuff_CodeMask; - count = (*code_ptr ^ Stuff_Magic) & Stuff_CountMask; - } - - while (src < end) { - switch (code) { - /* Stuff_NoCode: If no current code, select one */ - case Stuff_NoCode: - /* Record where we're going to put this code */ - code_ptr = dst++; - count = 0; /* Reset the count (zero means one instance) */ - /* Tentatively start a new block */ - if (*src == 0) { - code = Stuff_Zero; - src++; - } else { - code = Stuff_Same; - *dst++ = *src++ ^ Stuff_Magic; - } - /* Note: We optimistically assume run of same -- */ - /* which will be fixed later in Stuff_Same */ - /* if it turns out not to be true. */ - break; - - /* Stuff_Zero: We already have at least one zero encoded */ - case Stuff_Zero: - /* If another zero, count it, else finish this code block */ - if (*src == 0) { - count++; - src++; - } else { - StuffData_FinishBlock(Stuff_Zero + count); - } - break; - - /* Stuff_Same: We already have at least one byte encoded */ - case Stuff_Same: - /* If another one the same, count it */ - if ((*src ^ Stuff_Magic) == code_ptr[1]) { - count++; - src++; - break; - } - /* else, this byte does not match this block. */ - /* If we already have two or more bytes encoded, finish this code block */ - if (count) { - StuffData_FinishBlock(Stuff_Same + count); - break; - } - /* else, we only have one so far, so switch to Stuff_Diff code */ - code = Stuff_Diff; - /* and fall through to Stuff_Diff case below - * Note cunning cleverness here: case Stuff_Diff compares - * the current character with the previous two to see if it - * has a run of three the same. Won't this be an error if - * there aren't two previous characters stored to compare with? - * No. Because we know the current character is *not* the same - * as the previous one, the first test below will necessarily - * fail and the send half of the "if" won't be executed. - */ - - /* Stuff_Diff: We have at least two *different* bytes encoded */ - case Stuff_Diff: - /* If this is a zero, must encode a Stuff_DiffZero, and begin a new block */ - if (*src == 0) { - StuffData_FinishBlock(Stuff_DiffZero + - count); - } - /* else, if we have three in a row, it is worth starting a Stuff_Same block */ - else if ((*src ^ Stuff_Magic) == dst[-1] - && dst[-1] == dst[-2]) { - /* Back off the last two characters we encoded */ - code += count - 2; - /* Note: "Stuff_Diff + 0" is an illegal code */ - if (code == Stuff_Diff + 0) { - code = Stuff_Same + 0; - } - StuffData_FinishBlock(code); - code_ptr = dst - 2; - /* dst[-1] already holds the correct value */ - count = 2; /* 2 means three bytes encoded */ - code = Stuff_Same; - } - /* else, another different byte, so add it to the block */ - else { - *dst++ = *src ^ Stuff_Magic; - count++; - } - src++; /* Consume the byte */ - break; - } - if (count == Stuff_MaxCount) { - StuffData_FinishBlock(code + count); - } - } - if (code == Stuff_NoCode) { - *code_ptr_ptr = NULL; - } else { - *code_ptr_ptr = code_ptr; - StuffData_FinishBlock(code + count); - } - return (dst); -} - -/* - * UnStuffData decodes the data at "src", up to (but not including) "end". - * It writes the decoded data into the buffer pointed to by "dst", up to a - * maximum of "dst_length", and returns the new value of "src" so that a - * follow-on call can read more data, continuing from where the first left off. - * - * There are three types of results: - * 1. The source data runs out before extracting "dst_length" bytes: - * UnStuffData returns NULL to indicate failure. - * 2. The source data produces exactly "dst_length" bytes: - * UnStuffData returns new_src = end to indicate that all bytes were consumed. - * 3. "dst_length" bytes are extracted, with more remaining. - * UnStuffData returns new_src < end to indicate that there are more bytes - * to be read. - * - * Note: The decoding may be destructive, in that it may alter the source - * data in the process of decoding it (this is necessary to allow a follow-on - * call to resume correctly). - */ - -static __u8 *UnStuffData(__u8 * src, __u8 * end, __u8 * dst, - __u32 dst_length) -{ - __u8 *dst_end = dst + dst_length; - /* Sanity check */ - if (!src || !end || !dst || !dst_length) - return (NULL); - while (src < end && dst < dst_end) { - int count = (*src ^ Stuff_Magic) & Stuff_CountMask; - switch ((*src ^ Stuff_Magic) & Stuff_CodeMask) { - case Stuff_Diff: - if (src + 1 + count >= end) - return (NULL); - do { - *dst++ = *++src ^ Stuff_Magic; - } - while (--count >= 0 && dst < dst_end); - if (count < 0) - src += 1; - else { - if (count == 0) - *src = Stuff_Same ^ Stuff_Magic; - else - *src = - (Stuff_Diff + - count) ^ Stuff_Magic; - } - break; - case Stuff_DiffZero: - if (src + 1 + count >= end) - return (NULL); - do { - *dst++ = *++src ^ Stuff_Magic; - } - while (--count >= 0 && dst < dst_end); - if (count < 0) - *src = Stuff_Zero ^ Stuff_Magic; - else - *src = - (Stuff_DiffZero + count) ^ Stuff_Magic; - break; - case Stuff_Same: - if (src + 1 >= end) - return (NULL); - do { - *dst++ = src[1] ^ Stuff_Magic; - } - while (--count >= 0 && dst < dst_end); - if (count < 0) - src += 2; - else - *src = (Stuff_Same + count) ^ Stuff_Magic; - break; - case Stuff_Zero: - do { - *dst++ = 0; - } - while (--count >= 0 && dst < dst_end); - if (count < 0) - src += 1; - else - *src = (Stuff_Zero + count) ^ Stuff_Magic; - break; - } - } - if (dst < dst_end) - return (NULL); - else - return (src); -} - - -/************************************************************************/ -/* General routines for STRIP */ - -/* - * set_baud sets the baud rate to the rate defined by baudcode - */ -static void set_baud(struct tty_struct *tty, speed_t baudrate) -{ - struct ktermios old_termios; - - mutex_lock(&tty->termios_mutex); - old_termios =*(tty->termios); - tty_encode_baud_rate(tty, baudrate, baudrate); - tty->ops->set_termios(tty, &old_termios); - mutex_unlock(&tty->termios_mutex); -} - -/* - * Convert a string to a Metricom Address. - */ - -#define IS_RADIO_ADDRESS(p) ( \ - isdigit((p)[0]) && isdigit((p)[1]) && isdigit((p)[2]) && isdigit((p)[3]) && \ - (p)[4] == '-' && \ - isdigit((p)[5]) && isdigit((p)[6]) && isdigit((p)[7]) && isdigit((p)[8]) ) - -static int string_to_radio_address(MetricomAddress * addr, __u8 * p) -{ - if (!IS_RADIO_ADDRESS(p)) - return (1); - addr->c[0] = 0; - addr->c[1] = 0; - addr->c[2] = READHEX(p[0]) << 4 | READHEX(p[1]); - addr->c[3] = READHEX(p[2]) << 4 | READHEX(p[3]); - addr->c[4] = READHEX(p[5]) << 4 | READHEX(p[6]); - addr->c[5] = READHEX(p[7]) << 4 | READHEX(p[8]); - return (0); -} - -/* - * Convert a Metricom Address to a string. - */ - -static __u8 *radio_address_to_string(const MetricomAddress * addr, - MetricomAddressString * p) -{ - sprintf(p->c, "%02X%02X-%02X%02X", addr->c[2], addr->c[3], - addr->c[4], addr->c[5]); - return (p->c); -} - -/* - * Note: Must make sure sx_size is big enough to receive a stuffed - * MAX_RECV_MTU packet. Additionally, we also want to ensure that it's - * big enough to receive a large radio neighbour list (currently 4K). - */ - -static int allocate_buffers(struct strip *strip_info, int mtu) -{ - struct net_device *dev = strip_info->dev; - int sx_size = max_t(int, STRIP_ENCAP_SIZE(MAX_RECV_MTU), 4096); - int tx_size = STRIP_ENCAP_SIZE(mtu) + MaxCommandStringLength; - __u8 *r = kmalloc(MAX_RECV_MTU, GFP_ATOMIC); - __u8 *s = kmalloc(sx_size, GFP_ATOMIC); - __u8 *t = kmalloc(tx_size, GFP_ATOMIC); - if (r && s && t) { - strip_info->rx_buff = r; - strip_info->sx_buff = s; - strip_info->tx_buff = t; - strip_info->sx_size = sx_size; - strip_info->tx_size = tx_size; - strip_info->mtu = dev->mtu = mtu; - return (1); - } - kfree(r); - kfree(s); - kfree(t); - return (0); -} - -/* - * MTU has been changed by the IP layer. - * We could be in - * an upcall from the tty driver, or in an ip packet queue. - */ -static int strip_change_mtu(struct net_device *dev, int new_mtu) -{ - struct strip *strip_info = netdev_priv(dev); - int old_mtu = strip_info->mtu; - unsigned char *orbuff = strip_info->rx_buff; - unsigned char *osbuff = strip_info->sx_buff; - unsigned char *otbuff = strip_info->tx_buff; - - if (new_mtu > MAX_SEND_MTU) { - printk(KERN_ERR - "%s: MTU exceeds maximum allowable (%d), MTU change cancelled.\n", - strip_info->dev->name, MAX_SEND_MTU); - return -EINVAL; - } - - spin_lock_bh(&strip_lock); - if (!allocate_buffers(strip_info, new_mtu)) { - printk(KERN_ERR "%s: unable to grow strip buffers, MTU change cancelled.\n", - strip_info->dev->name); - spin_unlock_bh(&strip_lock); - return -ENOMEM; - } - - if (strip_info->sx_count) { - if (strip_info->sx_count <= strip_info->sx_size) - memcpy(strip_info->sx_buff, osbuff, - strip_info->sx_count); - else { - strip_info->discard = strip_info->sx_count; - strip_info->rx_over_errors++; - } - } - - if (strip_info->tx_left) { - if (strip_info->tx_left <= strip_info->tx_size) - memcpy(strip_info->tx_buff, strip_info->tx_head, - strip_info->tx_left); - else { - strip_info->tx_left = 0; - strip_info->tx_dropped++; - } - } - strip_info->tx_head = strip_info->tx_buff; - spin_unlock_bh(&strip_lock); - - printk(KERN_NOTICE "%s: strip MTU changed fom %d to %d.\n", - strip_info->dev->name, old_mtu, strip_info->mtu); - - kfree(orbuff); - kfree(osbuff); - kfree(otbuff); - return 0; -} - -static void strip_unlock(struct strip *strip_info) -{ - /* - * Set the timer to go off in one second. - */ - strip_info->idle_timer.expires = jiffies + 1 * HZ; - add_timer(&strip_info->idle_timer); - netif_wake_queue(strip_info->dev); -} - - - -/* - * If the time is in the near future, time_delta prints the number of - * seconds to go into the buffer and returns the address of the buffer. - * If the time is not in the near future, it returns the address of the - * string "Not scheduled" The buffer must be long enough to contain the - * ascii representation of the number plus 9 charactes for the " seconds" - * and the null character. - */ -#ifdef CONFIG_PROC_FS -static char *time_delta(char buffer[], long time) -{ - time -= jiffies; - if (time > LongTime / 2) - return ("Not scheduled"); - if (time < 0) - time = 0; /* Don't print negative times */ - sprintf(buffer, "%ld seconds", time / HZ); - return (buffer); -} - -/* get Nth element of the linked list */ -static struct strip *strip_get_idx(loff_t pos) -{ - struct strip *str; - int i = 0; - - list_for_each_entry_rcu(str, &strip_list, list) { - if (pos == i) - return str; - ++i; - } - return NULL; -} - -static void *strip_seq_start(struct seq_file *seq, loff_t *pos) - __acquires(RCU) -{ - rcu_read_lock(); - return *pos ? strip_get_idx(*pos - 1) : SEQ_START_TOKEN; -} - -static void *strip_seq_next(struct seq_file *seq, void *v, loff_t *pos) -{ - struct list_head *l; - struct strip *s; - - ++*pos; - if (v == SEQ_START_TOKEN) - return strip_get_idx(1); - - s = v; - l = &s->list; - list_for_each_continue_rcu(l, &strip_list) { - return list_entry(l, struct strip, list); - } - return NULL; -} - -static void strip_seq_stop(struct seq_file *seq, void *v) - __releases(RCU) -{ - rcu_read_unlock(); -} - -static void strip_seq_neighbours(struct seq_file *seq, - const MetricomNodeTable * table, - const char *title) -{ - /* We wrap this in a do/while loop, so if the table changes */ - /* while we're reading it, we just go around and try again. */ - struct timeval t; - - do { - int i; - t = table->timestamp; - if (table->num_nodes) - seq_printf(seq, "\n %s\n", title); - for (i = 0; i < table->num_nodes; i++) { - MetricomNode node; - - spin_lock_bh(&strip_lock); - node = table->node[i]; - spin_unlock_bh(&strip_lock); - seq_printf(seq, " %s\n", node.c); - } - } while (table->timestamp.tv_sec != t.tv_sec - || table->timestamp.tv_usec != t.tv_usec); -} - -/* - * This function prints radio status information via the seq_file - * interface. The interface takes care of buffer size and over - * run issues. - * - * The buffer in seq_file is PAGESIZE (4K) - * so this routine should never print more or it will get truncated. - * With the maximum of 32 portables and 32 poletops - * reported, the routine outputs 3107 bytes into the buffer. - */ -static void strip_seq_status_info(struct seq_file *seq, - const struct strip *strip_info) -{ - char temp[32]; - MetricomAddressString addr_string; - - /* First, we must copy all of our data to a safe place, */ - /* in case a serial interrupt comes in and changes it. */ - int tx_left = strip_info->tx_left; - unsigned long rx_average_pps = strip_info->rx_average_pps; - unsigned long tx_average_pps = strip_info->tx_average_pps; - unsigned long sx_average_pps = strip_info->sx_average_pps; - int working = strip_info->working; - int firmware_level = strip_info->firmware_level; - long watchdog_doprobe = strip_info->watchdog_doprobe; - long watchdog_doreset = strip_info->watchdog_doreset; - long gratuitous_arp = strip_info->gratuitous_arp; - long arp_interval = strip_info->arp_interval; - FirmwareVersion firmware_version = strip_info->firmware_version; - SerialNumber serial_number = strip_info->serial_number; - BatteryVoltage battery_voltage = strip_info->battery_voltage; - char *if_name = strip_info->dev->name; - MetricomAddress true_dev_addr = strip_info->true_dev_addr; - MetricomAddress dev_dev_addr = - *(MetricomAddress *) strip_info->dev->dev_addr; - int manual_dev_addr = strip_info->manual_dev_addr; -#ifdef EXT_COUNTERS - unsigned long rx_bytes = strip_info->rx_bytes; - unsigned long tx_bytes = strip_info->tx_bytes; - unsigned long rx_rbytes = strip_info->rx_rbytes; - unsigned long tx_rbytes = strip_info->tx_rbytes; - unsigned long rx_sbytes = strip_info->rx_sbytes; - unsigned long tx_sbytes = strip_info->tx_sbytes; - unsigned long rx_ebytes = strip_info->rx_ebytes; - unsigned long tx_ebytes = strip_info->tx_ebytes; -#endif - - seq_printf(seq, "\nInterface name\t\t%s\n", if_name); - seq_printf(seq, " Radio working:\t\t%s\n", working ? "Yes" : "No"); - radio_address_to_string(&true_dev_addr, &addr_string); - seq_printf(seq, " Radio address:\t\t%s\n", addr_string.c); - if (manual_dev_addr) { - radio_address_to_string(&dev_dev_addr, &addr_string); - seq_printf(seq, " Device address:\t%s\n", addr_string.c); - } - seq_printf(seq, " Firmware version:\t%s", !working ? "Unknown" : - !firmware_level ? "Should be upgraded" : - firmware_version.c); - if (firmware_level >= ChecksummedMessages) - seq_printf(seq, " (Checksums Enabled)"); - seq_printf(seq, "\n"); - seq_printf(seq, " Serial number:\t\t%s\n", serial_number.c); - seq_printf(seq, " Battery voltage:\t%s\n", battery_voltage.c); - seq_printf(seq, " Transmit queue (bytes):%d\n", tx_left); - seq_printf(seq, " Receive packet rate: %ld packets per second\n", - rx_average_pps / 8); - seq_printf(seq, " Transmit packet rate: %ld packets per second\n", - tx_average_pps / 8); - seq_printf(seq, " Sent packet rate: %ld packets per second\n", - sx_average_pps / 8); - seq_printf(seq, " Next watchdog probe:\t%s\n", - time_delta(temp, watchdog_doprobe)); - seq_printf(seq, " Next watchdog reset:\t%s\n", - time_delta(temp, watchdog_doreset)); - seq_printf(seq, " Next gratuitous ARP:\t"); - - if (!memcmp - (strip_info->dev->dev_addr, zero_address.c, - sizeof(zero_address))) - seq_printf(seq, "Disabled\n"); - else { - seq_printf(seq, "%s\n", time_delta(temp, gratuitous_arp)); - seq_printf(seq, " Next ARP interval:\t%ld seconds\n", - JIFFIE_TO_SEC(arp_interval)); - } - - if (working) { -#ifdef EXT_COUNTERS - seq_printf(seq, "\n"); - seq_printf(seq, - " Total bytes: \trx:\t%lu\ttx:\t%lu\n", - rx_bytes, tx_bytes); - seq_printf(seq, - " thru radio: \trx:\t%lu\ttx:\t%lu\n", - rx_rbytes, tx_rbytes); - seq_printf(seq, - " thru serial port: \trx:\t%lu\ttx:\t%lu\n", - rx_sbytes, tx_sbytes); - seq_printf(seq, - " Total stat/err bytes:\trx:\t%lu\ttx:\t%lu\n", - rx_ebytes, tx_ebytes); -#endif - strip_seq_neighbours(seq, &strip_info->poletops, - "Poletops:"); - strip_seq_neighbours(seq, &strip_info->portables, - "Portables:"); - } -} - -/* - * This function is exports status information from the STRIP driver through - * the /proc file system. - */ -static int strip_seq_show(struct seq_file *seq, void *v) -{ - if (v == SEQ_START_TOKEN) - seq_printf(seq, "strip_version: %s\n", StripVersion); - else - strip_seq_status_info(seq, (const struct strip *)v); - return 0; -} - - -static const struct seq_operations strip_seq_ops = { - .start = strip_seq_start, - .next = strip_seq_next, - .stop = strip_seq_stop, - .show = strip_seq_show, -}; - -static int strip_seq_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &strip_seq_ops); -} - -static const struct file_operations strip_seq_fops = { - .owner = THIS_MODULE, - .open = strip_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; -#endif - - - -/************************************************************************/ -/* Sending routines */ - -static void ResetRadio(struct strip *strip_info) -{ - struct tty_struct *tty = strip_info->tty; - static const char init[] = "ate0q1dt**starmode\r**"; - StringDescriptor s = { init, sizeof(init) - 1 }; - - /* - * If the radio isn't working anymore, - * we should clear the old status information. - */ - if (strip_info->working) { - printk(KERN_INFO "%s: No response: Resetting radio.\n", - strip_info->dev->name); - strip_info->firmware_version.c[0] = '\0'; - strip_info->serial_number.c[0] = '\0'; - strip_info->battery_voltage.c[0] = '\0'; - strip_info->portables.num_nodes = 0; - do_gettimeofday(&strip_info->portables.timestamp); - strip_info->poletops.num_nodes = 0; - do_gettimeofday(&strip_info->poletops.timestamp); - } - - strip_info->pps_timer = jiffies; - strip_info->rx_pps_count = 0; - strip_info->tx_pps_count = 0; - strip_info->sx_pps_count = 0; - strip_info->rx_average_pps = 0; - strip_info->tx_average_pps = 0; - strip_info->sx_average_pps = 0; - - /* Mark radio address as unknown */ - *(MetricomAddress *) & strip_info->true_dev_addr = zero_address; - if (!strip_info->manual_dev_addr) - *(MetricomAddress *) strip_info->dev->dev_addr = - zero_address; - strip_info->working = FALSE; - strip_info->firmware_level = NoStructure; - strip_info->next_command = CompatibilityCommand; - strip_info->watchdog_doprobe = jiffies + 10 * HZ; - strip_info->watchdog_doreset = jiffies + 1 * HZ; - - /* If the user has selected a baud rate above 38.4 see what magic we have to do */ - if (strip_info->user_baud > 38400) { - /* - * Subtle stuff: Pay attention :-) - * If the serial port is currently at the user's selected (>38.4) rate, - * then we temporarily switch to 19.2 and issue the ATS304 command - * to tell the radio to switch to the user's selected rate. - * If the serial port is not currently at that rate, that means we just - * issued the ATS304 command last time through, so this time we restore - * the user's selected rate and issue the normal starmode reset string. - */ - if (strip_info->user_baud == tty_get_baud_rate(tty)) { - static const char b0[] = "ate0q1s304=57600\r"; - static const char b1[] = "ate0q1s304=115200\r"; - static const StringDescriptor baudstring[2] = - { {b0, sizeof(b0) - 1} - , {b1, sizeof(b1) - 1} - }; - set_baud(tty, 19200); - if (strip_info->user_baud == 57600) - s = baudstring[0]; - else if (strip_info->user_baud == 115200) - s = baudstring[1]; - else - s = baudstring[1]; /* For now */ - } else - set_baud(tty, strip_info->user_baud); - } - - tty->ops->write(tty, s.string, s.length); -#ifdef EXT_COUNTERS - strip_info->tx_ebytes += s.length; -#endif -} - -/* - * Called by the driver when there's room for more data. If we have - * more packets to send, we send them here. - */ - -static void strip_write_some_more(struct tty_struct *tty) -{ - struct strip *strip_info = tty->disc_data; - - /* First make sure we're connected. */ - if (!strip_info || strip_info->magic != STRIP_MAGIC || - !netif_running(strip_info->dev)) - return; - - if (strip_info->tx_left > 0) { - int num_written = - tty->ops->write(tty, strip_info->tx_head, - strip_info->tx_left); - strip_info->tx_left -= num_written; - strip_info->tx_head += num_written; -#ifdef EXT_COUNTERS - strip_info->tx_sbytes += num_written; -#endif - } else { /* Else start transmission of another packet */ - - clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); - strip_unlock(strip_info); - } -} - -static __u8 *add_checksum(__u8 * buffer, __u8 * end) -{ - __u16 sum = 0; - __u8 *p = buffer; - while (p < end) - sum += *p++; - end[3] = hextable[sum & 0xF]; - sum >>= 4; - end[2] = hextable[sum & 0xF]; - sum >>= 4; - end[1] = hextable[sum & 0xF]; - sum >>= 4; - end[0] = hextable[sum & 0xF]; - return (end + 4); -} - -static unsigned char *strip_make_packet(unsigned char *buffer, - struct strip *strip_info, - struct sk_buff *skb) -{ - __u8 *ptr = buffer; - __u8 *stuffstate = NULL; - STRIP_Header *header = (STRIP_Header *) skb->data; - MetricomAddress haddr = header->dst_addr; - int len = skb->len - sizeof(STRIP_Header); - MetricomKey key; - - /*HexDump("strip_make_packet", strip_info, skb->data, skb->data + skb->len); */ - - if (header->protocol == htons(ETH_P_IP)) - key = SIP0Key; - else if (header->protocol == htons(ETH_P_ARP)) - key = ARP0Key; - else { - printk(KERN_ERR - "%s: strip_make_packet: Unknown packet type 0x%04X\n", - strip_info->dev->name, ntohs(header->protocol)); - return (NULL); - } - - if (len > strip_info->mtu) { - printk(KERN_ERR - "%s: Dropping oversized transmit packet: %d bytes\n", - strip_info->dev->name, len); - return (NULL); - } - - /* - * If we're sending to ourselves, discard the packet. - * (Metricom radios choke if they try to send a packet to their own address.) - */ - if (!memcmp(haddr.c, strip_info->true_dev_addr.c, sizeof(haddr))) { - printk(KERN_ERR "%s: Dropping packet addressed to self\n", - strip_info->dev->name); - return (NULL); - } - - /* - * If this is a broadcast packet, send it to our designated Metricom - * 'broadcast hub' radio (First byte of address being 0xFF means broadcast) - */ - if (haddr.c[0] == 0xFF) { - __be32 brd = 0; - struct in_device *in_dev; - - rcu_read_lock(); - in_dev = __in_dev_get_rcu(strip_info->dev); - if (in_dev == NULL) { - rcu_read_unlock(); - return NULL; - } - if (in_dev->ifa_list) - brd = in_dev->ifa_list->ifa_broadcast; - rcu_read_unlock(); - - /* arp_query returns 1 if it succeeds in looking up the address, 0 if it fails */ - if (!arp_query(haddr.c, brd, strip_info->dev)) { - printk(KERN_ERR - "%s: Unable to send packet (no broadcast hub configured)\n", - strip_info->dev->name); - return (NULL); - } - /* - * If we are the broadcast hub, don't bother sending to ourselves. - * (Metricom radios choke if they try to send a packet to their own address.) - */ - if (!memcmp - (haddr.c, strip_info->true_dev_addr.c, sizeof(haddr))) - return (NULL); - } - - *ptr++ = 0x0D; - *ptr++ = '*'; - *ptr++ = hextable[haddr.c[2] >> 4]; - *ptr++ = hextable[haddr.c[2] & 0xF]; - *ptr++ = hextable[haddr.c[3] >> 4]; - *ptr++ = hextable[haddr.c[3] & 0xF]; - *ptr++ = '-'; - *ptr++ = hextable[haddr.c[4] >> 4]; - *ptr++ = hextable[haddr.c[4] & 0xF]; - *ptr++ = hextable[haddr.c[5] >> 4]; - *ptr++ = hextable[haddr.c[5] & 0xF]; - *ptr++ = '*'; - *ptr++ = key.c[0]; - *ptr++ = key.c[1]; - *ptr++ = key.c[2]; - *ptr++ = key.c[3]; - - ptr = - StuffData(skb->data + sizeof(STRIP_Header), len, ptr, - &stuffstate); - - if (strip_info->firmware_level >= ChecksummedMessages) - ptr = add_checksum(buffer + 1, ptr); - - *ptr++ = 0x0D; - return (ptr); -} - -static void strip_send(struct strip *strip_info, struct sk_buff *skb) -{ - MetricomAddress haddr; - unsigned char *ptr = strip_info->tx_buff; - int doreset = (long) jiffies - strip_info->watchdog_doreset >= 0; - int doprobe = (long) jiffies - strip_info->watchdog_doprobe >= 0 - && !doreset; - __be32 addr, brd; - - /* - * 1. If we have a packet, encapsulate it and put it in the buffer - */ - if (skb) { - char *newptr = strip_make_packet(ptr, strip_info, skb); - strip_info->tx_pps_count++; - if (!newptr) - strip_info->tx_dropped++; - else { - ptr = newptr; - strip_info->sx_pps_count++; - strip_info->tx_packets++; /* Count another successful packet */ -#ifdef EXT_COUNTERS - strip_info->tx_bytes += skb->len; - strip_info->tx_rbytes += ptr - strip_info->tx_buff; -#endif - /*DumpData("Sending:", strip_info, strip_info->tx_buff, ptr); */ - /*HexDump("Sending", strip_info, strip_info->tx_buff, ptr); */ - } - } - - /* - * 2. If it is time for another tickle, tack it on, after the packet - */ - if (doprobe) { - StringDescriptor ts = CommandString[strip_info->next_command]; -#if TICKLE_TIMERS - { - struct timeval tv; - do_gettimeofday(&tv); - printk(KERN_INFO "**** Sending tickle string %d at %02d.%06d\n", - strip_info->next_command, tv.tv_sec % 100, - tv.tv_usec); - } -#endif - if (ptr == strip_info->tx_buff) - *ptr++ = 0x0D; - - *ptr++ = '*'; /* First send "**" to provoke an error message */ - *ptr++ = '*'; - - /* Then add the command */ - memcpy(ptr, ts.string, ts.length); - - /* Add a checksum ? */ - if (strip_info->firmware_level < ChecksummedMessages) - ptr += ts.length; - else - ptr = add_checksum(ptr, ptr + ts.length); - - *ptr++ = 0x0D; /* Terminate the command with a */ - - /* Cycle to next periodic command? */ - if (strip_info->firmware_level >= StructuredMessages) - if (++strip_info->next_command >= - ARRAY_SIZE(CommandString)) - strip_info->next_command = 0; -#ifdef EXT_COUNTERS - strip_info->tx_ebytes += ts.length; -#endif - strip_info->watchdog_doprobe = jiffies + 10 * HZ; - strip_info->watchdog_doreset = jiffies + 1 * HZ; - /*printk(KERN_INFO "%s: Routine radio test.\n", strip_info->dev->name); */ - } - - /* - * 3. Set up the strip_info ready to send the data (if any). - */ - strip_info->tx_head = strip_info->tx_buff; - strip_info->tx_left = ptr - strip_info->tx_buff; - set_bit(TTY_DO_WRITE_WAKEUP, &strip_info->tty->flags); - /* - * 4. Debugging check to make sure we're not overflowing the buffer. - */ - if (strip_info->tx_size - strip_info->tx_left < 20) - printk(KERN_ERR "%s: Sending%5d bytes;%5d bytes free.\n", - strip_info->dev->name, strip_info->tx_left, - strip_info->tx_size - strip_info->tx_left); - - /* - * 5. If watchdog has expired, reset the radio. Note: if there's data waiting in - * the buffer, strip_write_some_more will send it after the reset has finished - */ - if (doreset) { - ResetRadio(strip_info); - return; - } - - if (1) { - struct in_device *in_dev; - - brd = addr = 0; - rcu_read_lock(); - in_dev = __in_dev_get_rcu(strip_info->dev); - if (in_dev) { - if (in_dev->ifa_list) { - brd = in_dev->ifa_list->ifa_broadcast; - addr = in_dev->ifa_list->ifa_local; - } - } - rcu_read_unlock(); - } - - - /* - * 6. If it is time for a periodic ARP, queue one up to be sent. - * We only do this if: - * 1. The radio is working - * 2. It's time to send another periodic ARP - * 3. We really know what our address is (and it is not manually set to zero) - * 4. We have a designated broadcast address configured - * If we queue up an ARP packet when we don't have a designated broadcast - * address configured, then the packet will just have to be discarded in - * strip_make_packet. This is not fatal, but it causes misleading information - * to be displayed in tcpdump. tcpdump will report that periodic APRs are - * being sent, when in fact they are not, because they are all being dropped - * in the strip_make_packet routine. - */ - if (strip_info->working - && (long) jiffies - strip_info->gratuitous_arp >= 0 - && memcmp(strip_info->dev->dev_addr, zero_address.c, - sizeof(zero_address)) - && arp_query(haddr.c, brd, strip_info->dev)) { - /*printk(KERN_INFO "%s: Sending gratuitous ARP with interval %ld\n", - strip_info->dev->name, strip_info->arp_interval / HZ); */ - strip_info->gratuitous_arp = - jiffies + strip_info->arp_interval; - strip_info->arp_interval *= 2; - if (strip_info->arp_interval > MaxARPInterval) - strip_info->arp_interval = MaxARPInterval; - if (addr) - arp_send(ARPOP_REPLY, ETH_P_ARP, addr, /* Target address of ARP packet is our address */ - strip_info->dev, /* Device to send packet on */ - addr, /* Source IP address this ARP packet comes from */ - NULL, /* Destination HW address is NULL (broadcast it) */ - strip_info->dev->dev_addr, /* Source HW address is our HW address */ - strip_info->dev->dev_addr); /* Target HW address is our HW address (redundant) */ - } - - /* - * 7. All ready. Start the transmission - */ - strip_write_some_more(strip_info->tty); -} - -/* Encapsulate a datagram and kick it into a TTY queue. */ -static netdev_tx_t strip_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct strip *strip_info = netdev_priv(dev); - - if (!netif_running(dev)) { - printk(KERN_ERR "%s: xmit call when iface is down\n", - dev->name); - return NETDEV_TX_BUSY; - } - - netif_stop_queue(dev); - - del_timer(&strip_info->idle_timer); - - - if (time_after(jiffies, strip_info->pps_timer + HZ)) { - unsigned long t = jiffies - strip_info->pps_timer; - unsigned long rx_pps_count = - DIV_ROUND_CLOSEST(strip_info->rx_pps_count*HZ*8, t); - unsigned long tx_pps_count = - DIV_ROUND_CLOSEST(strip_info->tx_pps_count*HZ*8, t); - unsigned long sx_pps_count = - DIV_ROUND_CLOSEST(strip_info->sx_pps_count*HZ*8, t); - - strip_info->pps_timer = jiffies; - strip_info->rx_pps_count = 0; - strip_info->tx_pps_count = 0; - strip_info->sx_pps_count = 0; - - strip_info->rx_average_pps = (strip_info->rx_average_pps + rx_pps_count + 1) / 2; - strip_info->tx_average_pps = (strip_info->tx_average_pps + tx_pps_count + 1) / 2; - strip_info->sx_average_pps = (strip_info->sx_average_pps + sx_pps_count + 1) / 2; - - if (rx_pps_count / 8 >= 10) - printk(KERN_INFO "%s: WARNING: Receiving %ld packets per second.\n", - strip_info->dev->name, rx_pps_count / 8); - if (tx_pps_count / 8 >= 10) - printk(KERN_INFO "%s: WARNING: Tx %ld packets per second.\n", - strip_info->dev->name, tx_pps_count / 8); - if (sx_pps_count / 8 >= 10) - printk(KERN_INFO "%s: WARNING: Sending %ld packets per second.\n", - strip_info->dev->name, sx_pps_count / 8); - } - - spin_lock_bh(&strip_lock); - - strip_send(strip_info, skb); - - spin_unlock_bh(&strip_lock); - - if (skb) - dev_kfree_skb(skb); - return NETDEV_TX_OK; -} - -/* - * IdleTask periodically calls strip_xmit, so even when we have no IP packets - * to send for an extended period of time, the watchdog processing still gets - * done to ensure that the radio stays in Starmode - */ - -static void strip_IdleTask(unsigned long parameter) -{ - strip_xmit(NULL, (struct net_device *) parameter); -} - -/* - * Create the MAC header for an arbitrary protocol layer - * - * saddr!=NULL means use this specific address (n/a for Metricom) - * saddr==NULL means use default device source address - * daddr!=NULL means use this destination address - * daddr==NULL means leave destination address alone - * (e.g. unresolved arp -- kernel will call - * rebuild_header later to fill in the address) - */ - -static int strip_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, const void *daddr, - const void *saddr, unsigned len) -{ - struct strip *strip_info = netdev_priv(dev); - STRIP_Header *header = (STRIP_Header *) skb_push(skb, sizeof(STRIP_Header)); - - /*printk(KERN_INFO "%s: strip_header 0x%04X %s\n", dev->name, type, - type == ETH_P_IP ? "IP" : type == ETH_P_ARP ? "ARP" : ""); */ - - header->src_addr = strip_info->true_dev_addr; - header->protocol = htons(type); - - /*HexDump("strip_header", netdev_priv(dev), skb->data, skb->data + skb->len); */ - - if (!daddr) - return (-dev->hard_header_len); - - header->dst_addr = *(MetricomAddress *) daddr; - return (dev->hard_header_len); -} - -/* - * Rebuild the MAC header. This is called after an ARP - * (or in future other address resolution) has completed on this - * sk_buff. We now let ARP fill in the other fields. - * I think this should return zero if packet is ready to send, - * or non-zero if it needs more time to do an address lookup - */ - -static int strip_rebuild_header(struct sk_buff *skb) -{ -#ifdef CONFIG_INET - STRIP_Header *header = (STRIP_Header *) skb->data; - - /* Arp find returns zero if if knows the address, */ - /* or if it doesn't know the address it sends an ARP packet and returns non-zero */ - return arp_find(header->dst_addr.c, skb) ? 1 : 0; -#else - return 0; -#endif -} - - -/************************************************************************/ -/* Receiving routines */ - -/* - * This function parses the response to the ATS300? command, - * extracting the radio version and serial number. - */ -static void get_radio_version(struct strip *strip_info, __u8 * ptr, __u8 * end) -{ - __u8 *p, *value_begin, *value_end; - int len; - - /* Determine the beginning of the second line of the payload */ - p = ptr; - while (p < end && *p != 10) - p++; - if (p >= end) - return; - p++; - value_begin = p; - - /* Determine the end of line */ - while (p < end && *p != 10) - p++; - if (p >= end) - return; - value_end = p; - p++; - - len = value_end - value_begin; - len = min_t(int, len, sizeof(FirmwareVersion) - 1); - if (strip_info->firmware_version.c[0] == 0) - printk(KERN_INFO "%s: Radio Firmware: %.*s\n", - strip_info->dev->name, len, value_begin); - sprintf(strip_info->firmware_version.c, "%.*s", len, value_begin); - - /* Look for the first colon */ - while (p < end && *p != ':') - p++; - if (p >= end) - return; - /* Skip over the space */ - p += 2; - len = sizeof(SerialNumber) - 1; - if (p + len <= end) { - sprintf(strip_info->serial_number.c, "%.*s", len, p); - } else { - printk(KERN_DEBUG - "STRIP: radio serial number shorter (%zd) than expected (%d)\n", - end - p, len); - } -} - -/* - * This function parses the response to the ATS325? command, - * extracting the radio battery voltage. - */ -static void get_radio_voltage(struct strip *strip_info, __u8 * ptr, __u8 * end) -{ - int len; - - len = sizeof(BatteryVoltage) - 1; - if (ptr + len <= end) { - sprintf(strip_info->battery_voltage.c, "%.*s", len, ptr); - } else { - printk(KERN_DEBUG - "STRIP: radio voltage string shorter (%zd) than expected (%d)\n", - end - ptr, len); - } -} - -/* - * This function parses the responses to the AT~LA and ATS311 commands, - * which list the radio's neighbours. - */ -static void get_radio_neighbours(MetricomNodeTable * table, __u8 * ptr, __u8 * end) -{ - table->num_nodes = 0; - while (ptr < end && table->num_nodes < NODE_TABLE_SIZE) { - MetricomNode *node = &table->node[table->num_nodes++]; - char *dst = node->c, *limit = dst + sizeof(*node) - 1; - while (ptr < end && *ptr <= 32) - ptr++; - while (ptr < end && dst < limit && *ptr != 10) - *dst++ = *ptr++; - *dst++ = 0; - while (ptr < end && ptr[-1] != 10) - ptr++; - } - do_gettimeofday(&table->timestamp); -} - -static int get_radio_address(struct strip *strip_info, __u8 * p) -{ - MetricomAddress addr; - - if (string_to_radio_address(&addr, p)) - return (1); - - /* See if our radio address has changed */ - if (memcmp(strip_info->true_dev_addr.c, addr.c, sizeof(addr))) { - MetricomAddressString addr_string; - radio_address_to_string(&addr, &addr_string); - printk(KERN_INFO "%s: Radio address = %s\n", - strip_info->dev->name, addr_string.c); - strip_info->true_dev_addr = addr; - if (!strip_info->manual_dev_addr) - *(MetricomAddress *) strip_info->dev->dev_addr = - addr; - /* Give the radio a few seconds to get its head straight, then send an arp */ - strip_info->gratuitous_arp = jiffies + 15 * HZ; - strip_info->arp_interval = 1 * HZ; - } - return (0); -} - -static int verify_checksum(struct strip *strip_info) -{ - __u8 *p = strip_info->sx_buff; - __u8 *end = strip_info->sx_buff + strip_info->sx_count - 4; - u_short sum = - (READHEX16(end[0]) << 12) | (READHEX16(end[1]) << 8) | - (READHEX16(end[2]) << 4) | (READHEX16(end[3])); - while (p < end) - sum -= *p++; - if (sum == 0 && strip_info->firmware_level == StructuredMessages) { - strip_info->firmware_level = ChecksummedMessages; - printk(KERN_INFO "%s: Radio provides message checksums\n", - strip_info->dev->name); - } - return (sum == 0); -} - -static void RecvErr(char *msg, struct strip *strip_info) -{ - __u8 *ptr = strip_info->sx_buff; - __u8 *end = strip_info->sx_buff + strip_info->sx_count; - DumpData(msg, strip_info, ptr, end); - strip_info->rx_errors++; -} - -static void RecvErr_Message(struct strip *strip_info, __u8 * sendername, - const __u8 * msg, u_long len) -{ - if (has_prefix(msg, len, "001")) { /* Not in StarMode! */ - RecvErr("Error Msg:", strip_info); - printk(KERN_INFO "%s: Radio %s is not in StarMode\n", - strip_info->dev->name, sendername); - } - - else if (has_prefix(msg, len, "002")) { /* Remap handle */ - /* We ignore "Remap handle" messages for now */ - } - - else if (has_prefix(msg, len, "003")) { /* Can't resolve name */ - RecvErr("Error Msg:", strip_info); - printk(KERN_INFO "%s: Destination radio name is unknown\n", - strip_info->dev->name); - } - - else if (has_prefix(msg, len, "004")) { /* Name too small or missing */ - strip_info->watchdog_doreset = jiffies + LongTime; -#if TICKLE_TIMERS - { - struct timeval tv; - do_gettimeofday(&tv); - printk(KERN_INFO - "**** Got ERR_004 response at %02d.%06d\n", - tv.tv_sec % 100, tv.tv_usec); - } -#endif - if (!strip_info->working) { - strip_info->working = TRUE; - printk(KERN_INFO "%s: Radio now in starmode\n", - strip_info->dev->name); - /* - * If the radio has just entered a working state, we should do our first - * probe ASAP, so that we find out our radio address etc. without delay. - */ - strip_info->watchdog_doprobe = jiffies; - } - if (strip_info->firmware_level == NoStructure && sendername) { - strip_info->firmware_level = StructuredMessages; - strip_info->next_command = 0; /* Try to enable checksums ASAP */ - printk(KERN_INFO - "%s: Radio provides structured messages\n", - strip_info->dev->name); - } - if (strip_info->firmware_level >= StructuredMessages) { - /* - * If this message has a valid checksum on the end, then the call to verify_checksum - * will elevate the firmware_level to ChecksummedMessages for us. (The actual return - * code from verify_checksum is ignored here.) - */ - verify_checksum(strip_info); - /* - * If the radio has structured messages but we don't yet have all our information about it, - * we should do probes without delay, until we have gathered all the information - */ - if (!GOT_ALL_RADIO_INFO(strip_info)) - strip_info->watchdog_doprobe = jiffies; - } - } - - else if (has_prefix(msg, len, "005")) /* Bad count specification */ - RecvErr("Error Msg:", strip_info); - - else if (has_prefix(msg, len, "006")) /* Header too big */ - RecvErr("Error Msg:", strip_info); - - else if (has_prefix(msg, len, "007")) { /* Body too big */ - RecvErr("Error Msg:", strip_info); - printk(KERN_ERR - "%s: Error! Packet size too big for radio.\n", - strip_info->dev->name); - } - - else if (has_prefix(msg, len, "008")) { /* Bad character in name */ - RecvErr("Error Msg:", strip_info); - printk(KERN_ERR - "%s: Radio name contains illegal character\n", - strip_info->dev->name); - } - - else if (has_prefix(msg, len, "009")) /* No count or line terminator */ - RecvErr("Error Msg:", strip_info); - - else if (has_prefix(msg, len, "010")) /* Invalid checksum */ - RecvErr("Error Msg:", strip_info); - - else if (has_prefix(msg, len, "011")) /* Checksum didn't match */ - RecvErr("Error Msg:", strip_info); - - else if (has_prefix(msg, len, "012")) /* Failed to transmit packet */ - RecvErr("Error Msg:", strip_info); - - else - RecvErr("Error Msg:", strip_info); -} - -static void process_AT_response(struct strip *strip_info, __u8 * ptr, - __u8 * end) -{ - u_long len; - __u8 *p = ptr; - while (p < end && p[-1] != 10) - p++; /* Skip past first newline character */ - /* Now ptr points to the AT command, and p points to the text of the response. */ - len = p - ptr; - -#if TICKLE_TIMERS - { - struct timeval tv; - do_gettimeofday(&tv); - printk(KERN_INFO "**** Got AT response %.7s at %02d.%06d\n", - ptr, tv.tv_sec % 100, tv.tv_usec); - } -#endif - - if (has_prefix(ptr, len, "ATS300?")) - get_radio_version(strip_info, p, end); - else if (has_prefix(ptr, len, "ATS305?")) - get_radio_address(strip_info, p); - else if (has_prefix(ptr, len, "ATS311?")) - get_radio_neighbours(&strip_info->poletops, p, end); - else if (has_prefix(ptr, len, "ATS319=7")) - verify_checksum(strip_info); - else if (has_prefix(ptr, len, "ATS325?")) - get_radio_voltage(strip_info, p, end); - else if (has_prefix(ptr, len, "AT~LA")) - get_radio_neighbours(&strip_info->portables, p, end); - else - RecvErr("Unknown AT Response:", strip_info); -} - -static void process_ACK(struct strip *strip_info, __u8 * ptr, __u8 * end) -{ - /* Currently we don't do anything with ACKs from the radio */ -} - -static void process_Info(struct strip *strip_info, __u8 * ptr, __u8 * end) -{ - if (ptr + 16 > end) - RecvErr("Bad Info Msg:", strip_info); -} - -static struct net_device *get_strip_dev(struct strip *strip_info) -{ - /* If our hardware address is *manually set* to zero, and we know our */ - /* real radio hardware address, try to find another strip device that has been */ - /* manually set to that address that we can 'transfer ownership' of this packet to */ - if (strip_info->manual_dev_addr && - !memcmp(strip_info->dev->dev_addr, zero_address.c, - sizeof(zero_address)) - && memcmp(&strip_info->true_dev_addr, zero_address.c, - sizeof(zero_address))) { - struct net_device *dev; - read_lock_bh(&dev_base_lock); - for_each_netdev(&init_net, dev) { - if (dev->type == strip_info->dev->type && - !memcmp(dev->dev_addr, - &strip_info->true_dev_addr, - sizeof(MetricomAddress))) { - printk(KERN_INFO - "%s: Transferred packet ownership to %s.\n", - strip_info->dev->name, dev->name); - read_unlock_bh(&dev_base_lock); - return (dev); - } - } - read_unlock_bh(&dev_base_lock); - } - return (strip_info->dev); -} - -/* - * Send one completely decapsulated datagram to the next layer. - */ - -static void deliver_packet(struct strip *strip_info, STRIP_Header * header, - __u16 packetlen) -{ - struct sk_buff *skb = dev_alloc_skb(sizeof(STRIP_Header) + packetlen); - if (!skb) { - printk(KERN_ERR "%s: memory squeeze, dropping packet.\n", - strip_info->dev->name); - strip_info->rx_dropped++; - } else { - memcpy(skb_put(skb, sizeof(STRIP_Header)), header, - sizeof(STRIP_Header)); - memcpy(skb_put(skb, packetlen), strip_info->rx_buff, - packetlen); - skb->dev = get_strip_dev(strip_info); - skb->protocol = header->protocol; - skb_reset_mac_header(skb); - - /* Having put a fake header on the front of the sk_buff for the */ - /* benefit of tools like tcpdump, skb_pull now 'consumes' that */ - /* fake header before we hand the packet up to the next layer. */ - skb_pull(skb, sizeof(STRIP_Header)); - - /* Finally, hand the packet up to the next layer (e.g. IP or ARP, etc.) */ - strip_info->rx_packets++; - strip_info->rx_pps_count++; -#ifdef EXT_COUNTERS - strip_info->rx_bytes += packetlen; -#endif - netif_rx(skb); - } -} - -static void process_IP_packet(struct strip *strip_info, - STRIP_Header * header, __u8 * ptr, - __u8 * end) -{ - __u16 packetlen; - - /* Decode start of the IP packet header */ - ptr = UnStuffData(ptr, end, strip_info->rx_buff, 4); - if (!ptr) { - RecvErr("IP Packet too short", strip_info); - return; - } - - packetlen = ((__u16) strip_info->rx_buff[2] << 8) | strip_info->rx_buff[3]; - - if (packetlen > MAX_RECV_MTU) { - printk(KERN_INFO "%s: Dropping oversized received IP packet: %d bytes\n", - strip_info->dev->name, packetlen); - strip_info->rx_dropped++; - return; - } - - /*printk(KERN_INFO "%s: Got %d byte IP packet\n", strip_info->dev->name, packetlen); */ - - /* Decode remainder of the IP packet */ - ptr = - UnStuffData(ptr, end, strip_info->rx_buff + 4, packetlen - 4); - if (!ptr) { - RecvErr("IP Packet too short", strip_info); - return; - } - - if (ptr < end) { - RecvErr("IP Packet too long", strip_info); - return; - } - - header->protocol = htons(ETH_P_IP); - - deliver_packet(strip_info, header, packetlen); -} - -static void process_ARP_packet(struct strip *strip_info, - STRIP_Header * header, __u8 * ptr, - __u8 * end) -{ - __u16 packetlen; - struct arphdr *arphdr = (struct arphdr *) strip_info->rx_buff; - - /* Decode start of the ARP packet */ - ptr = UnStuffData(ptr, end, strip_info->rx_buff, 8); - if (!ptr) { - RecvErr("ARP Packet too short", strip_info); - return; - } - - packetlen = 8 + (arphdr->ar_hln + arphdr->ar_pln) * 2; - - if (packetlen > MAX_RECV_MTU) { - printk(KERN_INFO - "%s: Dropping oversized received ARP packet: %d bytes\n", - strip_info->dev->name, packetlen); - strip_info->rx_dropped++; - return; - } - - /*printk(KERN_INFO "%s: Got %d byte ARP %s\n", - strip_info->dev->name, packetlen, - ntohs(arphdr->ar_op) == ARPOP_REQUEST ? "request" : "reply"); */ - - /* Decode remainder of the ARP packet */ - ptr = - UnStuffData(ptr, end, strip_info->rx_buff + 8, packetlen - 8); - if (!ptr) { - RecvErr("ARP Packet too short", strip_info); - return; - } - - if (ptr < end) { - RecvErr("ARP Packet too long", strip_info); - return; - } - - header->protocol = htons(ETH_P_ARP); - - deliver_packet(strip_info, header, packetlen); -} - -/* - * process_text_message processes a -terminated block of data received - * from the radio that doesn't begin with a '*' character. All normal - * Starmode communication messages with the radio begin with a '*', - * so any text that does not indicates a serial port error, a radio that - * is in Hayes command mode instead of Starmode, or a radio with really - * old firmware that doesn't frame its Starmode responses properly. - */ -static void process_text_message(struct strip *strip_info) -{ - __u8 *msg = strip_info->sx_buff; - int len = strip_info->sx_count; - - /* Check for anything that looks like it might be our radio name */ - /* (This is here for backwards compatibility with old firmware) */ - if (len == 9 && get_radio_address(strip_info, msg) == 0) - return; - - if (text_equal(msg, len, "OK")) - return; /* Ignore 'OK' responses from prior commands */ - if (text_equal(msg, len, "ERROR")) - return; /* Ignore 'ERROR' messages */ - if (has_prefix(msg, len, "ate0q1")) - return; /* Ignore character echo back from the radio */ - - /* Catch other error messages */ - /* (This is here for backwards compatibility with old firmware) */ - if (has_prefix(msg, len, "ERR_")) { - RecvErr_Message(strip_info, NULL, &msg[4], len - 4); - return; - } - - RecvErr("No initial *", strip_info); -} - -/* - * process_message processes a -terminated block of data received - * from the radio. If the radio is not in Starmode or has old firmware, - * it may be a line of text in response to an AT command. Ideally, with - * a current radio that's properly in Starmode, all data received should - * be properly framed and checksummed radio message blocks, containing - * either a starmode packet, or a other communication from the radio - * firmware, like "INF_" Info messages and &COMMAND responses. - */ -static void process_message(struct strip *strip_info) -{ - STRIP_Header header = { zero_address, zero_address, 0 }; - __u8 *ptr = strip_info->sx_buff; - __u8 *end = strip_info->sx_buff + strip_info->sx_count; - __u8 sendername[32], *sptr = sendername; - MetricomKey key; - - /*HexDump("Receiving", strip_info, ptr, end); */ - - /* Check for start of address marker, and then skip over it */ - if (*ptr == '*') - ptr++; - else { - process_text_message(strip_info); - return; - } - - /* Copy out the return address */ - while (ptr < end && *ptr != '*' - && sptr < ARRAY_END(sendername) - 1) - *sptr++ = *ptr++; - *sptr = 0; /* Null terminate the sender name */ - - /* Check for end of address marker, and skip over it */ - if (ptr >= end || *ptr != '*') { - RecvErr("No second *", strip_info); - return; - } - ptr++; /* Skip the second '*' */ - - /* If the sender name is "&COMMAND", ignore this 'packet' */ - /* (This is here for backwards compatibility with old firmware) */ - if (!strcmp(sendername, "&COMMAND")) { - strip_info->firmware_level = NoStructure; - strip_info->next_command = CompatibilityCommand; - return; - } - - if (ptr + 4 > end) { - RecvErr("No proto key", strip_info); - return; - } - - /* Get the protocol key out of the buffer */ - key.c[0] = *ptr++; - key.c[1] = *ptr++; - key.c[2] = *ptr++; - key.c[3] = *ptr++; - - /* If we're using checksums, verify the checksum at the end of the packet */ - if (strip_info->firmware_level >= ChecksummedMessages) { - end -= 4; /* Chop the last four bytes off the packet (they're the checksum) */ - if (ptr > end) { - RecvErr("Missing Checksum", strip_info); - return; - } - if (!verify_checksum(strip_info)) { - RecvErr("Bad Checksum", strip_info); - return; - } - } - - /*printk(KERN_INFO "%s: Got packet from \"%s\".\n", strip_info->dev->name, sendername); */ - - /* - * Fill in (pseudo) source and destination addresses in the packet. - * We assume that the destination address was our address (the radio does not - * tell us this). If the radio supplies a source address, then we use it. - */ - header.dst_addr = strip_info->true_dev_addr; - string_to_radio_address(&header.src_addr, sendername); - -#ifdef EXT_COUNTERS - if (key.l == SIP0Key.l) { - strip_info->rx_rbytes += (end - ptr); - process_IP_packet(strip_info, &header, ptr, end); - } else if (key.l == ARP0Key.l) { - strip_info->rx_rbytes += (end - ptr); - process_ARP_packet(strip_info, &header, ptr, end); - } else if (key.l == ATR_Key.l) { - strip_info->rx_ebytes += (end - ptr); - process_AT_response(strip_info, ptr, end); - } else if (key.l == ACK_Key.l) { - strip_info->rx_ebytes += (end - ptr); - process_ACK(strip_info, ptr, end); - } else if (key.l == INF_Key.l) { - strip_info->rx_ebytes += (end - ptr); - process_Info(strip_info, ptr, end); - } else if (key.l == ERR_Key.l) { - strip_info->rx_ebytes += (end - ptr); - RecvErr_Message(strip_info, sendername, ptr, end - ptr); - } else - RecvErr("Unrecognized protocol key", strip_info); -#else - if (key.l == SIP0Key.l) - process_IP_packet(strip_info, &header, ptr, end); - else if (key.l == ARP0Key.l) - process_ARP_packet(strip_info, &header, ptr, end); - else if (key.l == ATR_Key.l) - process_AT_response(strip_info, ptr, end); - else if (key.l == ACK_Key.l) - process_ACK(strip_info, ptr, end); - else if (key.l == INF_Key.l) - process_Info(strip_info, ptr, end); - else if (key.l == ERR_Key.l) - RecvErr_Message(strip_info, sendername, ptr, end - ptr); - else - RecvErr("Unrecognized protocol key", strip_info); -#endif -} - -#define TTYERROR(X) ((X) == TTY_BREAK ? "Break" : \ - (X) == TTY_FRAME ? "Framing Error" : \ - (X) == TTY_PARITY ? "Parity Error" : \ - (X) == TTY_OVERRUN ? "Hardware Overrun" : "Unknown Error") - -/* - * Handle the 'receiver data ready' interrupt. - * This function is called by the 'tty_io' module in the kernel when - * a block of STRIP data has been received, which can now be decapsulated - * and sent on to some IP layer for further processing. - */ - -static void strip_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) -{ - struct strip *strip_info = tty->disc_data; - const unsigned char *end = cp + count; - - if (!strip_info || strip_info->magic != STRIP_MAGIC - || !netif_running(strip_info->dev)) - return; - - spin_lock_bh(&strip_lock); -#if 0 - { - struct timeval tv; - do_gettimeofday(&tv); - printk(KERN_INFO - "**** strip_receive_buf: %3d bytes at %02d.%06d\n", - count, tv.tv_sec % 100, tv.tv_usec); - } -#endif - -#ifdef EXT_COUNTERS - strip_info->rx_sbytes += count; -#endif - - /* Read the characters out of the buffer */ - while (cp < end) { - if (fp && *fp) - printk(KERN_INFO "%s: %s on serial port\n", - strip_info->dev->name, TTYERROR(*fp)); - if (fp && *fp++ && !strip_info->discard) { /* If there's a serial error, record it */ - /* If we have some characters in the buffer, discard them */ - strip_info->discard = strip_info->sx_count; - strip_info->rx_errors++; - } - - /* Leading control characters (CR, NL, Tab, etc.) are ignored */ - if (strip_info->sx_count > 0 || *cp >= ' ') { - if (*cp == 0x0D) { /* If end of packet, decide what to do with it */ - if (strip_info->sx_count > 3000) - printk(KERN_INFO - "%s: Cut a %d byte packet (%zd bytes remaining)%s\n", - strip_info->dev->name, - strip_info->sx_count, - end - cp - 1, - strip_info-> - discard ? " (discarded)" : - ""); - if (strip_info->sx_count > - strip_info->sx_size) { - strip_info->rx_over_errors++; - printk(KERN_INFO - "%s: sx_buff overflow (%d bytes total)\n", - strip_info->dev->name, - strip_info->sx_count); - } else if (strip_info->discard) - printk(KERN_INFO - "%s: Discarding bad packet (%d/%d)\n", - strip_info->dev->name, - strip_info->discard, - strip_info->sx_count); - else - process_message(strip_info); - strip_info->discard = 0; - strip_info->sx_count = 0; - } else { - /* Make sure we have space in the buffer */ - if (strip_info->sx_count < - strip_info->sx_size) - strip_info->sx_buff[strip_info-> - sx_count] = - *cp; - strip_info->sx_count++; - } - } - cp++; - } - spin_unlock_bh(&strip_lock); -} - - -/************************************************************************/ -/* General control routines */ - -static int set_mac_address(struct strip *strip_info, - MetricomAddress * addr) -{ - /* - * We're using a manually specified address if the address is set - * to anything other than all ones. Setting the address to all ones - * disables manual mode and goes back to automatic address determination - * (tracking the true address that the radio has). - */ - strip_info->manual_dev_addr = - memcmp(addr->c, broadcast_address.c, - sizeof(broadcast_address)); - if (strip_info->manual_dev_addr) - *(MetricomAddress *) strip_info->dev->dev_addr = *addr; - else - *(MetricomAddress *) strip_info->dev->dev_addr = - strip_info->true_dev_addr; - return 0; -} - -static int strip_set_mac_address(struct net_device *dev, void *addr) -{ - struct strip *strip_info = netdev_priv(dev); - struct sockaddr *sa = addr; - printk(KERN_INFO "%s: strip_set_dev_mac_address called\n", dev->name); - set_mac_address(strip_info, (MetricomAddress *) sa->sa_data); - return 0; -} - -static struct net_device_stats *strip_get_stats(struct net_device *dev) -{ - struct strip *strip_info = netdev_priv(dev); - static struct net_device_stats stats; - - memset(&stats, 0, sizeof(struct net_device_stats)); - - stats.rx_packets = strip_info->rx_packets; - stats.tx_packets = strip_info->tx_packets; - stats.rx_dropped = strip_info->rx_dropped; - stats.tx_dropped = strip_info->tx_dropped; - stats.tx_errors = strip_info->tx_errors; - stats.rx_errors = strip_info->rx_errors; - stats.rx_over_errors = strip_info->rx_over_errors; - return (&stats); -} - - -/************************************************************************/ -/* Opening and closing */ - -/* - * Here's the order things happen: - * When the user runs "slattach -p strip ..." - * 1. The TTY module calls strip_open;; - * 2. strip_open calls strip_alloc - * 3. strip_alloc calls register_netdev - * 4. register_netdev calls strip_dev_init - * 5. then strip_open finishes setting up the strip_info - * - * When the user runs "ifconfig st up address netmask ..." - * 6. strip_open_low gets called - * - * When the user runs "ifconfig st down" - * 7. strip_close_low gets called - * - * When the user kills the slattach process - * 8. strip_close gets called - * 9. strip_close calls dev_close - * 10. if the device is still up, then dev_close calls strip_close_low - * 11. strip_close calls strip_free - */ - -/* Open the low-level part of the STRIP channel. Easy! */ - -static int strip_open_low(struct net_device *dev) -{ - struct strip *strip_info = netdev_priv(dev); - - if (strip_info->tty == NULL) - return (-ENODEV); - - if (!allocate_buffers(strip_info, dev->mtu)) - return (-ENOMEM); - - strip_info->sx_count = 0; - strip_info->tx_left = 0; - - strip_info->discard = 0; - strip_info->working = FALSE; - strip_info->firmware_level = NoStructure; - strip_info->next_command = CompatibilityCommand; - strip_info->user_baud = tty_get_baud_rate(strip_info->tty); - - printk(KERN_INFO "%s: Initializing Radio.\n", - strip_info->dev->name); - ResetRadio(strip_info); - strip_info->idle_timer.expires = jiffies + 1 * HZ; - add_timer(&strip_info->idle_timer); - netif_wake_queue(dev); - return (0); -} - - -/* - * Close the low-level part of the STRIP channel. Easy! - */ - -static int strip_close_low(struct net_device *dev) -{ - struct strip *strip_info = netdev_priv(dev); - - if (strip_info->tty == NULL) - return -EBUSY; - clear_bit(TTY_DO_WRITE_WAKEUP, &strip_info->tty->flags); - netif_stop_queue(dev); - - /* - * Free all STRIP frame buffers. - */ - kfree(strip_info->rx_buff); - strip_info->rx_buff = NULL; - kfree(strip_info->sx_buff); - strip_info->sx_buff = NULL; - kfree(strip_info->tx_buff); - strip_info->tx_buff = NULL; - - del_timer(&strip_info->idle_timer); - return 0; -} - -static const struct header_ops strip_header_ops = { - .create = strip_header, - .rebuild = strip_rebuild_header, -}; - - -static const struct net_device_ops strip_netdev_ops = { - .ndo_open = strip_open_low, - .ndo_stop = strip_close_low, - .ndo_start_xmit = strip_xmit, - .ndo_set_mac_address = strip_set_mac_address, - .ndo_get_stats = strip_get_stats, - .ndo_change_mtu = strip_change_mtu, -}; - -/* - * This routine is called by DDI when the - * (dynamically assigned) device is registered - */ - -static void strip_dev_setup(struct net_device *dev) -{ - /* - * Finish setting up the DEVICE info. - */ - - dev->trans_start = 0; - dev->tx_queue_len = 30; /* Drop after 30 frames queued */ - - dev->flags = 0; - dev->mtu = DEFAULT_STRIP_MTU; - dev->type = ARPHRD_METRICOM; /* dtang */ - dev->hard_header_len = sizeof(STRIP_Header); - /* - * netdev_priv(dev) Already holds a pointer to our struct strip - */ - - *(MetricomAddress *)dev->broadcast = broadcast_address; - dev->dev_addr[0] = 0; - dev->addr_len = sizeof(MetricomAddress); - - dev->header_ops = &strip_header_ops, - dev->netdev_ops = &strip_netdev_ops; -} - -/* - * Free a STRIP channel. - */ - -static void strip_free(struct strip *strip_info) -{ - spin_lock_bh(&strip_lock); - list_del_rcu(&strip_info->list); - spin_unlock_bh(&strip_lock); - - strip_info->magic = 0; - - free_netdev(strip_info->dev); -} - - -/* - * Allocate a new free STRIP channel - */ -static struct strip *strip_alloc(void) -{ - struct list_head *n; - struct net_device *dev; - struct strip *strip_info; - - dev = alloc_netdev(sizeof(struct strip), "st%d", - strip_dev_setup); - - if (!dev) - return NULL; /* If no more memory, return */ - - - strip_info = netdev_priv(dev); - strip_info->dev = dev; - - strip_info->magic = STRIP_MAGIC; - strip_info->tty = NULL; - - strip_info->gratuitous_arp = jiffies + LongTime; - strip_info->arp_interval = 0; - init_timer(&strip_info->idle_timer); - strip_info->idle_timer.data = (long) dev; - strip_info->idle_timer.function = strip_IdleTask; - - - spin_lock_bh(&strip_lock); - rescan: - /* - * Search the list to find where to put our new entry - * (and in the process decide what channel number it is - * going to be) - */ - list_for_each(n, &strip_list) { - struct strip *s = hlist_entry(n, struct strip, list); - - if (s->dev->base_addr == dev->base_addr) { - ++dev->base_addr; - goto rescan; - } - } - - sprintf(dev->name, "st%ld", dev->base_addr); - - list_add_tail_rcu(&strip_info->list, &strip_list); - spin_unlock_bh(&strip_lock); - - return strip_info; -} - -/* - * Open the high-level part of the STRIP channel. - * This function is called by the TTY module when the - * STRIP line discipline is called for. Because we are - * sure the tty line exists, we only have to link it to - * a free STRIP channel... - */ - -static int strip_open(struct tty_struct *tty) -{ - struct strip *strip_info = tty->disc_data; - - /* - * First make sure we're not already connected. - */ - - if (strip_info && strip_info->magic == STRIP_MAGIC) - return -EEXIST; - - /* - * We need a write method. - */ - - if (tty->ops->write == NULL || tty->ops->set_termios == NULL) - return -EOPNOTSUPP; - - /* - * OK. Find a free STRIP channel to use. - */ - if ((strip_info = strip_alloc()) == NULL) - return -ENFILE; - - /* - * Register our newly created device so it can be ifconfig'd - * strip_dev_init() will be called as a side-effect - */ - - if (register_netdev(strip_info->dev) != 0) { - printk(KERN_ERR "strip: register_netdev() failed.\n"); - strip_free(strip_info); - return -ENFILE; - } - - strip_info->tty = tty; - tty->disc_data = strip_info; - tty->receive_room = 65536; - - tty_driver_flush_buffer(tty); - - /* - * Restore default settings - */ - - strip_info->dev->type = ARPHRD_METRICOM; /* dtang */ - - /* - * Set tty options - */ - - tty->termios->c_iflag |= IGNBRK | IGNPAR; /* Ignore breaks and parity errors. */ - tty->termios->c_cflag |= CLOCAL; /* Ignore modem control signals. */ - tty->termios->c_cflag &= ~HUPCL; /* Don't close on hup */ - - printk(KERN_INFO "STRIP: device \"%s\" activated\n", - strip_info->dev->name); - - /* - * Done. We have linked the TTY line to a channel. - */ - return (strip_info->dev->base_addr); -} - -/* - * Close down a STRIP channel. - * This means flushing out any pending queues, and then restoring the - * TTY line discipline to what it was before it got hooked to STRIP - * (which usually is TTY again). - */ - -static void strip_close(struct tty_struct *tty) -{ - struct strip *strip_info = tty->disc_data; - - /* - * First make sure we're connected. - */ - - if (!strip_info || strip_info->magic != STRIP_MAGIC) - return; - - unregister_netdev(strip_info->dev); - - tty->disc_data = NULL; - strip_info->tty = NULL; - printk(KERN_INFO "STRIP: device \"%s\" closed down\n", - strip_info->dev->name); - strip_free(strip_info); - tty->disc_data = NULL; -} - - -/************************************************************************/ -/* Perform I/O control calls on an active STRIP channel. */ - -static int strip_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct strip *strip_info = tty->disc_data; - - /* - * First make sure we're connected. - */ - - if (!strip_info || strip_info->magic != STRIP_MAGIC) - return -EINVAL; - - switch (cmd) { - case SIOCGIFNAME: - if(copy_to_user((void __user *) arg, strip_info->dev->name, strlen(strip_info->dev->name) + 1)) - return -EFAULT; - break; - case SIOCSIFHWADDR: - { - MetricomAddress addr; - //printk(KERN_INFO "%s: SIOCSIFHWADDR\n", strip_info->dev->name); - if(copy_from_user(&addr, (void __user *) arg, sizeof(MetricomAddress))) - return -EFAULT; - return set_mac_address(strip_info, &addr); - } - default: - return tty_mode_ioctl(tty, file, cmd, arg); - break; - } - return 0; -} - -#ifdef CONFIG_COMPAT -static long strip_compat_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - switch (cmd) { - case SIOCGIFNAME: - case SIOCSIFHWADDR: - return strip_ioctl(tty, file, cmd, - (unsigned long)compat_ptr(arg)); - } - return -ENOIOCTLCMD; -} -#endif - -/************************************************************************/ -/* Initialization */ - -static struct tty_ldisc_ops strip_ldisc = { - .magic = TTY_LDISC_MAGIC, - .name = "strip", - .owner = THIS_MODULE, - .open = strip_open, - .close = strip_close, - .ioctl = strip_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = strip_compat_ioctl, -#endif - .receive_buf = strip_receive_buf, - .write_wakeup = strip_write_some_more, -}; - -/* - * Initialize the STRIP driver. - * This routine is called at boot time, to bootstrap the multi-channel - * STRIP driver - */ - -static char signon[] __initdata = - KERN_INFO "STRIP: Version %s (unlimited channels)\n"; - -static int __init strip_init_driver(void) -{ - int status; - - printk(signon, StripVersion); - - - /* - * Fill in our line protocol discipline, and register it - */ - if ((status = tty_register_ldisc(N_STRIP, &strip_ldisc))) - printk(KERN_ERR "STRIP: can't register line discipline (err = %d)\n", - status); - - /* - * Register the status file with /proc - */ - proc_net_fops_create(&init_net, "strip", S_IFREG | S_IRUGO, &strip_seq_fops); - - return status; -} - -module_init(strip_init_driver); - -static const char signoff[] __exitdata = - KERN_INFO "STRIP: Module Unloaded\n"; - -static void __exit strip_exit_driver(void) -{ - int i; - struct list_head *p,*n; - - /* module ref count rules assure that all entries are unregistered */ - list_for_each_safe(p, n, &strip_list) { - struct strip *s = list_entry(p, struct strip, list); - strip_free(s); - } - - /* Unregister with the /proc/net file here. */ - proc_net_remove(&init_net, "strip"); - - if ((i = tty_unregister_ldisc(N_STRIP))) - printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i); - - printk(signoff); -} - -module_exit(strip_exit_driver); - -MODULE_AUTHOR("Stuart Cheshire "); -MODULE_DESCRIPTION("Starmode Radio IP (STRIP) Device Driver"); -MODULE_LICENSE("Dual BSD/GPL"); - -MODULE_SUPPORTED_DEVICE("Starmode Radio IP (STRIP) modem"); -- cgit v1.2.3 From 1d794e3b353b50ab5d9d46f7c15607f9ec8c78e0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 23:16:09 -0700 Subject: Staging: wavelan: delete the driver It has sat in the staging directory since October of 2009, and no one has stepped up to take it over, so odds are, no one cares about it anymore. So, it is now deleted as scheduled, and documented in the TODO file. Cc: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 2 - drivers/staging/wavelan/Kconfig | 38 - drivers/staging/wavelan/Makefile | 2 - drivers/staging/wavelan/TODO | 7 - drivers/staging/wavelan/i82586.h | 397 --- drivers/staging/wavelan/wavelan.c | 4401 ------------------------------ drivers/staging/wavelan/wavelan.h | 363 --- drivers/staging/wavelan/wavelan.p.h | 694 ----- drivers/staging/wavelan/wavelan_cs.c | 4610 -------------------------------- drivers/staging/wavelan/wavelan_cs.h | 381 --- drivers/staging/wavelan/wavelan_cs.p.h | 762 ------ 12 files changed, 11659 deletions(-) delete mode 100644 drivers/staging/wavelan/Kconfig delete mode 100644 drivers/staging/wavelan/Makefile delete mode 100644 drivers/staging/wavelan/TODO delete mode 100644 drivers/staging/wavelan/i82586.h delete mode 100644 drivers/staging/wavelan/wavelan.c delete mode 100644 drivers/staging/wavelan/wavelan.h delete mode 100644 drivers/staging/wavelan/wavelan.p.h delete mode 100644 drivers/staging/wavelan/wavelan_cs.c delete mode 100644 drivers/staging/wavelan/wavelan_cs.h delete mode 100644 drivers/staging/wavelan/wavelan_cs.p.h (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 4ca05017c1ad..436e2ed07995 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -125,8 +125,6 @@ source "drivers/staging/batman-adv/Kconfig" source "drivers/staging/samsung-laptop/Kconfig" -source "drivers/staging/wavelan/Kconfig" - source "drivers/staging/netwave/Kconfig" source "drivers/staging/sm7xx/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index e308274bb148..357da6de3f1e 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -43,8 +43,6 @@ obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/ obj-$(CONFIG_BATMAN_ADV) += batman-adv/ obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop/ -obj-$(CONFIG_WAVELAN) += wavelan/ -obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan/ obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/ obj-$(CONFIG_FB_SM7XX) += sm7xx/ obj-$(CONFIG_DT3155) += dt3155/ diff --git a/drivers/staging/wavelan/Kconfig b/drivers/staging/wavelan/Kconfig deleted file mode 100644 index af655668c2a7..000000000000 --- a/drivers/staging/wavelan/Kconfig +++ /dev/null @@ -1,38 +0,0 @@ -config WAVELAN - tristate "AT&T/Lucent old WaveLAN & DEC RoamAbout DS ISA support" - depends on ISA && WLAN - select WIRELESS_EXT - select WEXT_SPY - select WEXT_PRIV - ---help--- - The Lucent WaveLAN (formerly NCR and AT&T; or DEC RoamAbout DS) is - a Radio LAN (wireless Ethernet-like Local Area Network) using the - radio frequencies 900 MHz and 2.4 GHz. - - If you want to use an ISA WaveLAN card under Linux, say Y and read - the Ethernet-HOWTO, available from - . Some more specific - information is contained in - and in the source code - . - - You will also need the wireless tools package available from - . - Please read the man pages contained therein. - - To compile this driver as a module, choose M here: the module will be - called wavelan. - -config PCMCIA_WAVELAN - tristate "AT&T/Lucent old WaveLAN Pcmcia wireless support" - depends on PCMCIA && WLAN - select WIRELESS_EXT - select WEXT_SPY - select WEXT_PRIV - help - Say Y here if you intend to attach an AT&T/Lucent Wavelan PCMCIA - (PC-card) wireless Ethernet networking card to your computer. This - driver is for the non-IEEE-802.11 Wavelan cards. - - To compile this driver as a module, choose M here: the module will be - called wavelan_cs. If unsure, say N. diff --git a/drivers/staging/wavelan/Makefile b/drivers/staging/wavelan/Makefile deleted file mode 100644 index 1cde17c69a43..000000000000 --- a/drivers/staging/wavelan/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -obj-$(CONFIG_WAVELAN) += wavelan.o -obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan_cs.o diff --git a/drivers/staging/wavelan/TODO b/drivers/staging/wavelan/TODO deleted file mode 100644 index 9bd15a2f6d9e..000000000000 --- a/drivers/staging/wavelan/TODO +++ /dev/null @@ -1,7 +0,0 @@ -TODO: - - step up and maintain this driver to ensure that it continues - to work. Having the hardware for this is pretty much a - requirement. If this does not happen, the will be removed in - the 2.6.35 kernel release. - -Please send patches to Greg Kroah-Hartman . diff --git a/drivers/staging/wavelan/i82586.h b/drivers/staging/wavelan/i82586.h deleted file mode 100644 index 27f832498139..000000000000 --- a/drivers/staging/wavelan/i82586.h +++ /dev/null @@ -1,397 +0,0 @@ -/* - * Intel 82586 IEEE 802.3 Ethernet LAN Coprocessor. - * - * See: - * Intel Microcommunications 1991 - * p1-1 to p1-37 - * Intel order No. 231658 - * ISBN 1-55512-119-5 - * - * Unfortunately, the above chapter mentions neither - * the System Configuration Pointer (SCP) nor the - * Intermediate System Configuration Pointer (ISCP), - * so we probably need to look elsewhere for the - * whole story -- some recommend the "Intel LAN - * Components manual" but I have neither a copy - * nor a full reference. But "elsewhere" may be - * in the same publication... - * The description of a later device, the - * "82596CA High-Performance 32-Bit Local Area Network - * Coprocessor", (ibid. p1-38 to p1-109) does mention - * the SCP and ISCP and also has an i82586 compatibility - * mode. Even more useful is "AP-235 An 82586 Data Link - * Driver" (ibid. p1-337 to p1-417). - */ - -#define I82586_MEMZ (64 * 1024) - -#define I82586_SCP_ADDR (I82586_MEMZ - sizeof(scp_t)) - -#define ADDR_LEN 6 -#define I82586NULL 0xFFFF - -#define toff(t, p, f) (unsigned short)((void *)(&((t *)((void *)0 + (p)))->f) - (void *)0) - -/* - * System Configuration Pointer (SCP). - */ -typedef struct scp_t scp_t; -struct scp_t { - unsigned short scp_sysbus; /* 82586 bus width: */ -#define SCP_SY_16BBUS (0x0 << 0) /* 16 bits */ -#define SCP_SY_8BBUS (0x1 << 0) /* 8 bits. */ - unsigned short scp_junk[2]; /* Unused */ - unsigned short scp_iscpl; /* lower 16 bits of ISCP_ADDR */ - unsigned short scp_iscph; /* upper 16 bits of ISCP_ADDR */ -}; - -/* - * Intermediate System Configuration Pointer (ISCP). - */ -typedef struct iscp_t iscp_t; -struct iscp_t { - unsigned short iscp_busy; /* set by CPU before first CA, */ - /* cleared by 82586 after read. */ - unsigned short iscp_offset; /* offset of SCB */ - unsigned short iscp_basel; /* base of SCB */ - unsigned short iscp_baseh; /* " */ -}; - -/* - * System Control Block (SCB). - * The 82586 writes its status to scb_status and then - * raises an interrupt to alert the CPU. - * The CPU writes a command to scb_command and - * then issues a Channel Attention (CA) to alert the 82586. - */ -typedef struct scb_t scb_t; -struct scb_t { - unsigned short scb_status; /* Status of 82586 */ -#define SCB_ST_INT (0xF << 12) /* Some of: */ -#define SCB_ST_CX (0x1 << 15) /* Cmd completed */ -#define SCB_ST_FR (0x1 << 14) /* Frame received */ -#define SCB_ST_CNA (0x1 << 13) /* Cmd unit not active */ -#define SCB_ST_RNR (0x1 << 12) /* Rcv unit not ready */ -#define SCB_ST_JUNK0 (0x1 << 11) /* 0 */ -#define SCB_ST_CUS (0x7 << 8) /* Cmd unit status */ -#define SCB_ST_CUS_IDLE (0 << 8) /* Idle */ -#define SCB_ST_CUS_SUSP (1 << 8) /* Suspended */ -#define SCB_ST_CUS_ACTV (2 << 8) /* Active */ -#define SCB_ST_JUNK1 (0x1 << 7) /* 0 */ -#define SCB_ST_RUS (0x7 << 4) /* Rcv unit status */ -#define SCB_ST_RUS_IDLE (0 << 4) /* Idle */ -#define SCB_ST_RUS_SUSP (1 << 4) /* Suspended */ -#define SCB_ST_RUS_NRES (2 << 4) /* No resources */ -#define SCB_ST_RUS_RDY (4 << 4) /* Ready */ - unsigned short scb_command; /* Next command */ -#define SCB_CMD_ACK_CX (0x1 << 15) /* Ack cmd completion */ -#define SCB_CMD_ACK_FR (0x1 << 14) /* Ack frame received */ -#define SCB_CMD_ACK_CNA (0x1 << 13) /* Ack CU not active */ -#define SCB_CMD_ACK_RNR (0x1 << 12) /* Ack RU not ready */ -#define SCB_CMD_JUNKX (0x1 << 11) /* Unused */ -#define SCB_CMD_CUC (0x7 << 8) /* Command Unit command */ -#define SCB_CMD_CUC_NOP (0 << 8) /* Nop */ -#define SCB_CMD_CUC_GO (1 << 8) /* Start cbl_offset */ -#define SCB_CMD_CUC_RES (2 << 8) /* Resume execution */ -#define SCB_CMD_CUC_SUS (3 << 8) /* Suspend " */ -#define SCB_CMD_CUC_ABT (4 << 8) /* Abort " */ -#define SCB_CMD_RESET (0x1 << 7) /* Reset chip (hardware) */ -#define SCB_CMD_RUC (0x7 << 4) /* Receive Unit command */ -#define SCB_CMD_RUC_NOP (0 << 4) /* Nop */ -#define SCB_CMD_RUC_GO (1 << 4) /* Start rfa_offset */ -#define SCB_CMD_RUC_RES (2 << 4) /* Resume reception */ -#define SCB_CMD_RUC_SUS (3 << 4) /* Suspend " */ -#define SCB_CMD_RUC_ABT (4 << 4) /* Abort " */ - unsigned short scb_cbl_offset; /* Offset of first command unit */ - /* Action Command */ - unsigned short scb_rfa_offset; /* Offset of first Receive */ - /* Frame Descriptor in the */ - /* Receive Frame Area */ - unsigned short scb_crcerrs; /* Properly aligned frames */ - /* received with a CRC error */ - unsigned short scb_alnerrs; /* Misaligned frames received */ - /* with a CRC error */ - unsigned short scb_rscerrs; /* Frames lost due to no space */ - unsigned short scb_ovrnerrs; /* Frames lost due to slow bus */ -}; - -#define scboff(p, f) toff(scb_t, p, f) - -/* - * The eight Action Commands. - */ -typedef enum acmd_e acmd_e; -enum acmd_e { - acmd_nop = 0, /* Do nothing */ - acmd_ia_setup = 1, /* Load an (ethernet) address into the */ - /* 82586 */ - acmd_configure = 2, /* Update the 82586 operating parameters */ - acmd_mc_setup = 3, /* Load a list of (ethernet) multicast */ - /* addresses into the 82586 */ - acmd_transmit = 4, /* Transmit a frame */ - acmd_tdr = 5, /* Perform a Time Domain Reflectometer */ - /* test on the serial link */ - acmd_dump = 6, /* Copy 82586 registers to memory */ - acmd_diagnose = 7, /* Run an internal self test */ -}; - -/* - * Generic Action Command header. - */ -typedef struct ach_t ach_t; -struct ach_t { - unsigned short ac_status; /* Command status: */ -#define AC_SFLD_C (0x1 << 15) /* Command completed */ -#define AC_SFLD_B (0x1 << 14) /* Busy executing */ -#define AC_SFLD_OK (0x1 << 13) /* Completed error free */ -#define AC_SFLD_A (0x1 << 12) /* Command aborted */ -#define AC_SFLD_FAIL (0x1 << 11) /* Selftest failed */ -#define AC_SFLD_S10 (0x1 << 10) /* No carrier sense */ - /* during transmission */ -#define AC_SFLD_S9 (0x1 << 9) /* Tx unsuccessful: */ - /* (stopped) lost CTS */ -#define AC_SFLD_S8 (0x1 << 8) /* Tx unsuccessful: */ - /* (stopped) slow DMA */ -#define AC_SFLD_S7 (0x1 << 7) /* Tx deferred: */ - /* other link traffic */ -#define AC_SFLD_S6 (0x1 << 6) /* Heart Beat: collision */ - /* detect after last tx */ -#define AC_SFLD_S5 (0x1 << 5) /* Tx stopped: */ - /* excessive collisions */ -#define AC_SFLD_MAXCOL (0xF << 0) /* Collision count */ - unsigned short ac_command; /* Command specifier: */ -#define AC_CFLD_EL (0x1 << 15) /* End of command list */ -#define AC_CFLD_S (0x1 << 14) /* Suspend on completion */ -#define AC_CFLD_I (0x1 << 13) /* Interrupt on completion */ -#define AC_CFLD_CMD (0x7 << 0) /* acmd_e */ - unsigned short ac_link; /* Next Action Command */ -}; - -#define acoff(p, f) toff(ach_t, p, f) - -/* - * The Nop Action Command. - */ -typedef struct ac_nop_t ac_nop_t; -struct ac_nop_t { - ach_t nop_h; -}; - -/* - * The IA-Setup Action Command. - */ -typedef struct ac_ias_t ac_ias_t; -struct ac_ias_t { - ach_t ias_h; - unsigned char ias_addr[ADDR_LEN]; /* The (ethernet) address */ -}; - -/* - * The Configure Action Command. - */ -typedef struct ac_cfg_t ac_cfg_t; -struct ac_cfg_t { - ach_t cfg_h; - unsigned char cfg_byte_cnt; /* Size foll data: 4-12 */ -#define AC_CFG_BYTE_CNT(v) (((v) & 0xF) << 0) - unsigned char cfg_fifolim; /* FIFO threshold */ -#define AC_CFG_FIFOLIM(v) (((v) & 0xF) << 0) - unsigned char cfg_byte8; -#define AC_CFG_SAV_BF(v) (((v) & 0x1) << 7) /* Save rxd bad frames */ -#define AC_CFG_SRDY(v) (((v) & 0x1) << 6) /* SRDY/ARDY pin means */ - /* external sync. */ - unsigned char cfg_byte9; -#define AC_CFG_ELPBCK(v) (((v) & 0x1) << 7) /* External loopback */ -#define AC_CFG_ILPBCK(v) (((v) & 0x1) << 6) /* Internal loopback */ -#define AC_CFG_PRELEN(v) (((v) & 0x3) << 4) /* Preamble length */ -#define AC_CFG_PLEN_2 0 /* 2 bytes */ -#define AC_CFG_PLEN_4 1 /* 4 bytes */ -#define AC_CFG_PLEN_8 2 /* 8 bytes */ -#define AC_CFG_PLEN_16 3 /* 16 bytes */ -#define AC_CFG_ALOC(v) (((v) & 0x1) << 3) /* Addr/len data is */ - /* explicit in buffers */ -#define AC_CFG_ADDRLEN(v) (((v) & 0x7) << 0) /* Bytes per address */ - unsigned char cfg_byte10; -#define AC_CFG_BOFMET(v) (((v) & 0x1) << 7) /* Use alternate expo. */ - /* backoff method */ -#define AC_CFG_ACR(v) (((v) & 0x7) << 4) /* Accelerated cont. res. */ -#define AC_CFG_LINPRIO(v) (((v) & 0x7) << 0) /* Linear priority */ - unsigned char cfg_ifs; /* Interframe spacing */ - unsigned char cfg_slotl; /* Slot time (low byte) */ - unsigned char cfg_byte13; -#define AC_CFG_RETRYNUM(v) (((v) & 0xF) << 4) /* Max. collision retry */ -#define AC_CFG_SLTTMHI(v) (((v) & 0x7) << 0) /* Slot time (high bits) */ - unsigned char cfg_byte14; -#define AC_CFG_FLGPAD(v) (((v) & 0x1) << 7) /* Pad with HDLC flags */ -#define AC_CFG_BTSTF(v) (((v) & 0x1) << 6) /* Do HDLC bitstuffing */ -#define AC_CFG_CRC16(v) (((v) & 0x1) << 5) /* 16 bit CCITT CRC */ -#define AC_CFG_NCRC(v) (((v) & 0x1) << 4) /* Insert no CRC */ -#define AC_CFG_TNCRS(v) (((v) & 0x1) << 3) /* Tx even if no carrier */ -#define AC_CFG_MANCH(v) (((v) & 0x1) << 2) /* Manchester coding */ -#define AC_CFG_BCDIS(v) (((v) & 0x1) << 1) /* Disable broadcast */ -#define AC_CFG_PRM(v) (((v) & 0x1) << 0) /* Promiscuous mode */ - unsigned char cfg_byte15; -#define AC_CFG_ICDS(v) (((v) & 0x1) << 7) /* Internal collision */ - /* detect source */ -#define AC_CFG_CDTF(v) (((v) & 0x7) << 4) /* Collision detect */ - /* filter in bit times */ -#define AC_CFG_ICSS(v) (((v) & 0x1) << 3) /* Internal carrier */ - /* sense source */ -#define AC_CFG_CSTF(v) (((v) & 0x7) << 0) /* Carrier sense */ - /* filter in bit times */ - unsigned short cfg_min_frm_len; -#define AC_CFG_MNFRM(v) (((v) & 0xFF) << 0) /* Min. bytes/frame (<= 255) */ -}; - -/* - * The MC-Setup Action Command. - */ -typedef struct ac_mcs_t ac_mcs_t; -struct ac_mcs_t { - ach_t mcs_h; - unsigned short mcs_cnt; /* No. of bytes of MC addresses */ -#if 0 - unsigned char mcs_data[ADDR_LEN]; /* The first MC address .. */ - ... -#endif -}; - -#define I82586_MAX_MULTICAST_ADDRESSES 128 /* Hardware hashed filter */ - -/* - * The Transmit Action Command. - */ -typedef struct ac_tx_t ac_tx_t; -struct ac_tx_t { - ach_t tx_h; - unsigned short tx_tbd_offset; /* Address of list of buffers. */ -#if 0 -Linux packets are passed down with the destination MAC address -and length/type field already prepended to the data, -so we do not need to insert it. Consistent with this -we must also set the AC_CFG_ALOC(..) flag during the -ac_cfg_t action command. - unsigned char tx_addr[ADDR_LEN]; /* The frame dest. address */ - unsigned short tx_length; /* The frame length */ -#endif /* 0 */ -}; - -/* - * The Time Domain Reflectometer Action Command. - */ -typedef struct ac_tdr_t ac_tdr_t; -struct ac_tdr_t { - ach_t tdr_h; - unsigned short tdr_result; /* Result. */ -#define AC_TDR_LNK_OK (0x1 << 15) /* No link problem */ -#define AC_TDR_XCVR_PRB (0x1 << 14) /* Txcvr cable problem */ -#define AC_TDR_ET_OPN (0x1 << 13) /* Open on the link */ -#define AC_TDR_ET_SRT (0x1 << 12) /* Short on the link */ -#define AC_TDR_TIME (0x7FF << 0) /* Distance to problem */ - /* site in transmit */ - /* clock cycles */ -}; - -/* - * The Dump Action Command. - */ -typedef struct ac_dmp_t ac_dmp_t; -struct ac_dmp_t { - ach_t dmp_h; - unsigned short dmp_offset; /* Result. */ -}; - -/* - * Size of the result of the dump command. - */ -#define DUMPBYTES 170 - -/* - * The Diagnose Action Command. - */ -typedef struct ac_dgn_t ac_dgn_t; -struct ac_dgn_t { - ach_t dgn_h; -}; - -/* - * Transmit Buffer Descriptor (TBD). - */ -typedef struct tbd_t tbd_t; -struct tbd_t { - unsigned short tbd_status; /* Written by the CPU */ -#define TBD_STATUS_EOF (0x1 << 15) /* This TBD is the */ - /* last for this frame */ -#define TBD_STATUS_ACNT (0x3FFF << 0) /* Actual count of data */ - /* bytes in this buffer */ - unsigned short tbd_next_bd_offset; /* Next in list */ - unsigned short tbd_bufl; /* Buffer address (low) */ - unsigned short tbd_bufh; /* " " (high) */ -}; - -/* - * Receive Buffer Descriptor (RBD). - */ -typedef struct rbd_t rbd_t; -struct rbd_t { - unsigned short rbd_status; /* Written by the 82586 */ -#define RBD_STATUS_EOF (0x1 << 15) /* This RBD is the */ - /* last for this frame */ -#define RBD_STATUS_F (0x1 << 14) /* ACNT field is valid */ -#define RBD_STATUS_ACNT (0x3FFF << 0) /* Actual no. of data */ - /* bytes in this buffer */ - unsigned short rbd_next_rbd_offset; /* Next rbd in list */ - unsigned short rbd_bufl; /* Data pointer (low) */ - unsigned short rbd_bufh; /* " " (high) */ - unsigned short rbd_el_size; /* EL+Data buf. size */ -#define RBD_EL (0x1 << 15) /* This BD is the */ - /* last in the list */ -#define RBD_SIZE (0x3FFF << 0) /* No. of bytes the */ - /* buffer can hold */ -}; - -#define rbdoff(p, f) toff(rbd_t, p, f) - -/* - * Frame Descriptor (FD). - */ -typedef struct fd_t fd_t; -struct fd_t { - unsigned short fd_status; /* Written by the 82586 */ -#define FD_STATUS_C (0x1 << 15) /* Completed storing frame */ -#define FD_STATUS_B (0x1 << 14) /* FD was consumed by RU */ -#define FD_STATUS_OK (0x1 << 13) /* Frame rxd successfully */ -#define FD_STATUS_S11 (0x1 << 11) /* CRC error */ -#define FD_STATUS_S10 (0x1 << 10) /* Alignment error */ -#define FD_STATUS_S9 (0x1 << 9) /* Ran out of resources */ -#define FD_STATUS_S8 (0x1 << 8) /* Rx DMA overrun */ -#define FD_STATUS_S7 (0x1 << 7) /* Frame too short */ -#define FD_STATUS_S6 (0x1 << 6) /* No EOF flag */ - unsigned short fd_command; /* Command */ -#define FD_COMMAND_EL (0x1 << 15) /* Last FD in list */ -#define FD_COMMAND_S (0x1 << 14) /* Suspend RU after rx */ - unsigned short fd_link_offset; /* Next FD */ - unsigned short fd_rbd_offset; /* First RBD (data) */ - /* Prepared by CPU, */ - /* updated by 82586 */ -#if 0 -I think the rest is unused since we -have set AC_CFG_ALOC(..). However, just -in case, we leave the space. -#endif /* 0 */ - unsigned char fd_dest[ADDR_LEN]; /* Destination address */ - /* Written by 82586 */ - unsigned char fd_src[ADDR_LEN]; /* Source address */ - /* Written by 82586 */ - unsigned short fd_length; /* Frame length or type */ - /* Written by 82586 */ -}; - -#define fdoff(p, f) toff(fd_t, p, f) - -/* - * This software may only be used and distributed - * according to the terms of the GNU General Public License. - * - * For more details, see wavelan.c. - */ diff --git a/drivers/staging/wavelan/wavelan.c b/drivers/staging/wavelan/wavelan.c deleted file mode 100644 index 37ede43bbbe7..000000000000 --- a/drivers/staging/wavelan/wavelan.c +++ /dev/null @@ -1,4401 +0,0 @@ -/* - * WaveLAN ISA driver - * - * Jean II - HPLB '96 - * - * Reorganisation and extension of the driver. - * Original copyright follows (also see the end of this file). - * See wavelan.p.h for details. - * - * - * - * AT&T GIS (nee NCR) WaveLAN card: - * An Ethernet-like radio transceiver - * controlled by an Intel 82586 coprocessor. - */ - -#include "wavelan.p.h" /* Private header */ - -/************************* MISC SUBROUTINES **************************/ -/* - * Subroutines which won't fit in one of the following category - * (WaveLAN modem or i82586) - */ - -/*------------------------------------------------------------------*/ -/* - * Translate irq number to PSA irq parameter - */ -static u8 wv_irq_to_psa(int irq) -{ - if (irq < 0 || irq >= ARRAY_SIZE(irqvals)) - return 0; - - return irqvals[irq]; -} - -/*------------------------------------------------------------------*/ -/* - * Translate PSA irq parameter to irq number - */ -static int __init wv_psa_to_irq(u8 irqval) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(irqvals); i++) - if (irqvals[i] == irqval) - return i; - - return -1; -} - -/********************* HOST ADAPTER SUBROUTINES *********************/ -/* - * Useful subroutines to manage the WaveLAN ISA interface - * - * One major difference with the PCMCIA hardware (except the port mapping) - * is that we have to keep the state of the Host Control Register - *because of the interrupt enable & bus size flags. - */ - -/*------------------------------------------------------------------*/ -/* - * Read from card's Host Adaptor Status Register. - */ -static inline u16 hasr_read(unsigned long ioaddr) -{ - return inw(HASR(ioaddr)); -} /* hasr_read */ - -/*------------------------------------------------------------------*/ -/* - * Write to card's Host Adapter Command Register. - */ -static inline void hacr_write(unsigned long ioaddr, u16 hacr) -{ - outw(hacr, HACR(ioaddr)); -} /* hacr_write */ - -/*------------------------------------------------------------------*/ -/* - * Write to card's Host Adapter Command Register. Include a delay for - * those times when it is needed. - */ -static void hacr_write_slow(unsigned long ioaddr, u16 hacr) -{ - hacr_write(ioaddr, hacr); - /* delay might only be needed sometimes */ - mdelay(1); -} /* hacr_write_slow */ - -/*------------------------------------------------------------------*/ -/* - * Set the channel attention bit. - */ -static inline void set_chan_attn(unsigned long ioaddr, u16 hacr) -{ - hacr_write(ioaddr, hacr | HACR_CA); -} /* set_chan_attn */ - -/*------------------------------------------------------------------*/ -/* - * Reset, and then set host adaptor into default mode. - */ -static inline void wv_hacr_reset(unsigned long ioaddr) -{ - hacr_write_slow(ioaddr, HACR_RESET); - hacr_write(ioaddr, HACR_DEFAULT); -} /* wv_hacr_reset */ - -/*------------------------------------------------------------------*/ -/* - * Set the I/O transfer over the ISA bus to 8-bit mode - */ -static inline void wv_16_off(unsigned long ioaddr, u16 hacr) -{ - hacr &= ~HACR_16BITS; - hacr_write(ioaddr, hacr); -} /* wv_16_off */ - -/*------------------------------------------------------------------*/ -/* - * Set the I/O transfer over the ISA bus to 8-bit mode - */ -static inline void wv_16_on(unsigned long ioaddr, u16 hacr) -{ - hacr |= HACR_16BITS; - hacr_write(ioaddr, hacr); -} /* wv_16_on */ - -/*------------------------------------------------------------------*/ -/* - * Disable interrupts on the WaveLAN hardware. - * (called by wv_82586_stop()) - */ -static inline void wv_ints_off(struct net_device *dev) -{ - net_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - - lp->hacr &= ~HACR_INTRON; - hacr_write(ioaddr, lp->hacr); -} /* wv_ints_off */ - -/*------------------------------------------------------------------*/ -/* - * Enable interrupts on the WaveLAN hardware. - * (called by wv_hw_reset()) - */ -static inline void wv_ints_on(struct net_device *dev) -{ - net_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - - lp->hacr |= HACR_INTRON; - hacr_write(ioaddr, lp->hacr); -} /* wv_ints_on */ - -/******************* MODEM MANAGEMENT SUBROUTINES *******************/ -/* - * Useful subroutines to manage the modem of the WaveLAN - */ - -/*------------------------------------------------------------------*/ -/* - * Read the Parameter Storage Area from the WaveLAN card's memory - */ -/* - * Read bytes from the PSA. - */ -static void psa_read(unsigned long ioaddr, - u16 hacr, - int o, /* offset in PSA */ - u8 *b, /*buffer to fill */ - int n) -{ /* size to read */ - wv_16_off(ioaddr, hacr); - - while (n-- > 0) { - outw(o, PIOR2(ioaddr)); - o++; - *b++ = inb(PIOP2(ioaddr)); - } - - wv_16_on(ioaddr, hacr); -} /* psa_read */ - -/*------------------------------------------------------------------*/ -/* - * Write the Parameter Storage Area to the WaveLAN card's memory. - */ -static void psa_write(unsigned long ioaddr, - u16 hacr, - int o, /* Offset in PSA */ - u8 *b, /*buffer in memory */ - int n) -{ /* Length of buffer */ - int count = 0; - - wv_16_off(ioaddr, hacr); - - while (n-- > 0) { - outw(o, PIOR2(ioaddr)); - o++; - - outb(*b, PIOP2(ioaddr)); - b++; - - /* Wait for the memory to finish its write cycle */ - count = 0; - while ((count++ < 100) && (hasr_read(ioaddr) & HASR_PSA_BUSY)) - mdelay(1); - } - - wv_16_on(ioaddr, hacr); -} /* psa_write */ - -#ifdef SET_PSA_CRC -/*------------------------------------------------------------------*/ -/* - * Calculate the PSA CRC - * Thanks to Valster, Nico for the code - * NOTE: By specifying a length including the CRC position the - * returned value should be zero. (i.e. a correct checksum in the PSA) - * - * The Windows drivers don't use the CRC, but the AP and the PtP tool - * depend on it. - */ -static u16 psa_crc(u8 *psa, /* The PSA */ - int size) -{ /* Number of short for CRC */ - int byte_cnt; /* Loop on the PSA */ - u16 crc_bytes = 0; /* Data in the PSA */ - int bit_cnt; /* Loop on the bits of the short */ - - for (byte_cnt = 0; byte_cnt < size; byte_cnt++) { - crc_bytes ^= psa[byte_cnt]; /* Its an xor */ - - for (bit_cnt = 1; bit_cnt < 9; bit_cnt++) { - if (crc_bytes & 0x0001) - crc_bytes = (crc_bytes >> 1) ^ 0xA001; - else - crc_bytes >>= 1; - } - } - - return crc_bytes; -} /* psa_crc */ -#endif /* SET_PSA_CRC */ - -/*------------------------------------------------------------------*/ -/* - * update the checksum field in the Wavelan's PSA - */ -static void update_psa_checksum(struct net_device *dev, - unsigned long ioaddr, - u16 hacr) -{ -#ifdef SET_PSA_CRC - psa_t psa; - u16 crc; - - /* read the parameter storage area */ - psa_read(ioaddr, hacr, 0, (unsigned char *) &psa, sizeof(psa)); - - /* update the checksum */ - crc = psa_crc((unsigned char *) &psa, - sizeof(psa) - sizeof(psa.psa_crc[0]) - - sizeof(psa.psa_crc[1]) - - sizeof(psa.psa_crc_status)); - - psa.psa_crc[0] = crc & 0xFF; - psa.psa_crc[1] = (crc & 0xFF00) >> 8; - - /* Write it ! */ - psa_write(ioaddr, hacr, (char *) &psa.psa_crc - (char *) &psa, - (unsigned char *) &psa.psa_crc, 2); - -#ifdef DEBUG_IOCTL_INFO - printk(KERN_DEBUG "%s: update_psa_checksum(): crc = 0x%02x%02x\n", - dev->name, psa.psa_crc[0], psa.psa_crc[1]); - - /* Check again (luxury !) */ - crc = psa_crc((unsigned char *) &psa, - sizeof(psa) - sizeof(psa.psa_crc_status)); - - if (crc != 0) - printk(KERN_WARNING - "%s: update_psa_checksum(): CRC does not \ - agree with PSA data (even after recalculating)\n", - dev->name); -#endif /* DEBUG_IOCTL_INFO */ -#endif /* SET_PSA_CRC */ -} /* update_psa_checksum */ - -/*------------------------------------------------------------------*/ -/* - * Write 1 byte to the MMC. - */ -static void mmc_out(unsigned long ioaddr, u16 o, u8 d) -{ - int count = 0; - - /* Wait for MMC to go idle */ - while ((count++ < 100) && (inw(HASR(ioaddr)) & HASR_MMC_BUSY)) - udelay(10); - - outw((u16) (((u16) d << 8) | (o << 1) | 1), MMCR(ioaddr)); -} - -/*------------------------------------------------------------------*/ -/* - * Routine to write bytes to the Modem Management Controller. - * We start at the end because it is the way it should be! - */ -static void mmc_write(unsigned long ioaddr, u8 o, u8 *b, int n) -{ - o += n; - b += n; - - while (n-- > 0) - mmc_out(ioaddr, --o, *(--b)); -} /* mmc_write */ - -/*------------------------------------------------------------------*/ -/* - * Read a byte from the MMC. - * Optimised version for 1 byte, avoid using memory. - */ -static u8 mmc_in(unsigned long ioaddr, u16 o) -{ - int count = 0; - - while ((count++ < 100) && (inw(HASR(ioaddr)) & HASR_MMC_BUSY)) - udelay(10); - outw(o << 1, MMCR(ioaddr)); - - while ((count++ < 100) && (inw(HASR(ioaddr)) & HASR_MMC_BUSY)) - udelay(10); - return (u8) (inw(MMCR(ioaddr)) >> 8); -} - -/*------------------------------------------------------------------*/ -/* - * Routine to read bytes from the Modem Management Controller. - * The implementation is complicated by a lack of address lines, - * which prevents decoding of the low-order bit. - * (code has just been moved in the above function) - * We start at the end because it is the way it should be! - */ -static inline void mmc_read(unsigned long ioaddr, u8 o, u8 *b, int n) -{ - o += n; - b += n; - - while (n-- > 0) - *(--b) = mmc_in(ioaddr, --o); -} /* mmc_read */ - -/*------------------------------------------------------------------*/ -/* - * Get the type of encryption available. - */ -static inline int mmc_encr(unsigned long ioaddr) -{ /* I/O port of the card */ - int temp; - - temp = mmc_in(ioaddr, mmroff(0, mmr_des_avail)); - if ((temp != MMR_DES_AVAIL_DES) && (temp != MMR_DES_AVAIL_AES)) - return 0; - else - return temp; -} - -/*------------------------------------------------------------------*/ -/* - * Wait for the frequency EEPROM to complete a command. - * I hope this one will be optimally inlined. - */ -static inline void fee_wait(unsigned long ioaddr, /* I/O port of the card */ - int delay, /*base delay to wait for */ - int number) -{ /* Number of time to wait */ - int count = 0; /* Wait only a limited time */ - - while ((count++ < number) && - (mmc_in(ioaddr, mmroff(0, mmr_fee_status)) & - MMR_FEE_STATUS_BUSY)) - udelay(delay); -} - -/*------------------------------------------------------------------*/ -/* - * Read bytes from the Frequency EEPROM (frequency select cards). - */ -static void fee_read(unsigned long ioaddr, /* I/O port of the card */ - u16 o, /* destination offset */ - u16 *b, /* data buffer */ - int n) -{ /* number of registers */ - b += n; /* Position at the end of the area */ - - /* Write the address */ - mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), o + n - 1); - - /* Loop on all buffer */ - while (n-- > 0) { - /* Write the read command */ - mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), - MMW_FEE_CTRL_READ); - - /* Wait until EEPROM is ready (should be quick). */ - fee_wait(ioaddr, 10, 100); - - /* Read the value. */ - *--b = ((mmc_in(ioaddr, mmroff(0, mmr_fee_data_h)) << 8) | - mmc_in(ioaddr, mmroff(0, mmr_fee_data_l))); - } -} - - -/*------------------------------------------------------------------*/ -/* - * Write bytes from the Frequency EEPROM (frequency select cards). - * This is a bit complicated, because the frequency EEPROM has to - *be unprotected and the write enabled. - * Jean II - */ -static void fee_write(unsigned long ioaddr, /* I/O port of the card */ - u16 o, /* destination offset */ - u16 *b, /* data buffer */ - int n) -{ /* number of registers */ - b += n; /* Position at the end of the area. */ - -#ifdef EEPROM_IS_PROTECTED /* disabled */ -#ifdef DOESNT_SEEM_TO_WORK /* disabled */ - /* Ask to read the protected register */ - mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRREAD); - - fee_wait(ioaddr, 10, 100); - - /* Read the protected register. */ - printk("Protected 2: %02X-%02X\n", - mmc_in(ioaddr, mmroff(0, mmr_fee_data_h)), - mmc_in(ioaddr, mmroff(0, mmr_fee_data_l))); -#endif /* DOESNT_SEEM_TO_WORK */ - - /* Enable protected register. */ - mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN); - mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PREN); - - fee_wait(ioaddr, 10, 100); - - /* Unprotect area. */ - mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), o + n); - mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE); -#ifdef DOESNT_SEEM_TO_WORK /* disabled */ - /* or use: */ - mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRCLEAR); -#endif /* DOESNT_SEEM_TO_WORK */ - - fee_wait(ioaddr, 10, 100); -#endif /* EEPROM_IS_PROTECTED */ - - /* Write enable. */ - mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN); - mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WREN); - - fee_wait(ioaddr, 10, 100); - - /* Write the EEPROM address. */ - mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), o + n - 1); - - /* Loop on all buffer */ - while (n-- > 0) { - /* Write the value. */ - mmc_out(ioaddr, mmwoff(0, mmw_fee_data_h), (*--b) >> 8); - mmc_out(ioaddr, mmwoff(0, mmw_fee_data_l), *b & 0xFF); - - /* Write the write command. */ - mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), - MMW_FEE_CTRL_WRITE); - - /* WaveLAN documentation says to - * wait at least 10 ms for EEBUSY = 0 - */ - mdelay(10); - fee_wait(ioaddr, 10, 100); - } - - /* Write disable. */ - mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_DS); - mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WDS); - - fee_wait(ioaddr, 10, 100); - -#ifdef EEPROM_IS_PROTECTED /* disabled */ - /* Reprotect EEPROM. */ - mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), 0x00); - mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE); - - fee_wait(ioaddr, 10, 100); -#endif /* EEPROM_IS_PROTECTED */ -} - -/************************ I82586 SUBROUTINES *************************/ -/* - * Useful subroutines to manage the Ethernet controller - */ - -/*------------------------------------------------------------------*/ -/* - * Read bytes from the on-board RAM. - * Why does inlining this function make it fail? - */ -static /*inline */ void obram_read(unsigned long ioaddr, - u16 o, u8 *b, int n) -{ - outw(o, PIOR1(ioaddr)); - insw(PIOP1(ioaddr), (unsigned short *) b, (n + 1) >> 1); -} - -/*------------------------------------------------------------------*/ -/* - * Write bytes to the on-board RAM. - */ -static inline void obram_write(unsigned long ioaddr, u16 o, u8 *b, int n) -{ - outw(o, PIOR1(ioaddr)); - outsw(PIOP1(ioaddr), (unsigned short *) b, (n + 1) >> 1); -} - -/*------------------------------------------------------------------*/ -/* - * Acknowledge the reading of the status issued by the i82586. - */ -static void wv_ack(struct net_device *dev) -{ - net_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - u16 scb_cs; - int i; - - obram_read(ioaddr, scboff(OFFSET_SCB, scb_status), - (unsigned char *) &scb_cs, sizeof(scb_cs)); - scb_cs &= SCB_ST_INT; - - if (scb_cs == 0) - return; - - obram_write(ioaddr, scboff(OFFSET_SCB, scb_command), - (unsigned char *) &scb_cs, sizeof(scb_cs)); - - set_chan_attn(ioaddr, lp->hacr); - - for (i = 1000; i > 0; i--) { - obram_read(ioaddr, scboff(OFFSET_SCB, scb_command), - (unsigned char *) &scb_cs, sizeof(scb_cs)); - if (scb_cs == 0) - break; - - udelay(10); - } - udelay(100); - -#ifdef DEBUG_CONFIG_ERROR - if (i <= 0) - printk(KERN_INFO - "%s: wv_ack(): board not accepting command.\n", - dev->name); -#endif -} - -/*------------------------------------------------------------------*/ -/* - * Set channel attention bit and busy wait until command has - * completed, then acknowledge completion of the command. - */ -static int wv_synchronous_cmd(struct net_device *dev, const char *str) -{ - net_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - u16 scb_cmd; - ach_t cb; - int i; - - scb_cmd = SCB_CMD_CUC & SCB_CMD_CUC_GO; - obram_write(ioaddr, scboff(OFFSET_SCB, scb_command), - (unsigned char *) &scb_cmd, sizeof(scb_cmd)); - - set_chan_attn(ioaddr, lp->hacr); - - for (i = 1000; i > 0; i--) { - obram_read(ioaddr, OFFSET_CU, (unsigned char *) &cb, - sizeof(cb)); - if (cb.ac_status & AC_SFLD_C) - break; - - udelay(10); - } - udelay(100); - - if (i <= 0 || !(cb.ac_status & AC_SFLD_OK)) { -#ifdef DEBUG_CONFIG_ERROR - printk(KERN_INFO "%s: %s failed; status = 0x%x\n", - dev->name, str, cb.ac_status); -#endif -#ifdef DEBUG_I82586_SHOW - wv_scb_show(ioaddr); -#endif - return -1; - } - - /* Ack the status */ - wv_ack(dev); - - return 0; -} - -/*------------------------------------------------------------------*/ -/* - * Configuration commands completion interrupt. - * Check if done, and if OK. - */ -static int -wv_config_complete(struct net_device *dev, unsigned long ioaddr, net_local * lp) -{ - unsigned short mcs_addr; - unsigned short status; - int ret; - -#ifdef DEBUG_INTERRUPT_TRACE - printk(KERN_DEBUG "%s: ->wv_config_complete()\n", dev->name); -#endif - - mcs_addr = lp->tx_first_in_use + sizeof(ac_tx_t) + sizeof(ac_nop_t) - + sizeof(tbd_t) + sizeof(ac_cfg_t) + sizeof(ac_ias_t); - - /* Read the status of the last command (set mc list). */ - obram_read(ioaddr, acoff(mcs_addr, ac_status), - (unsigned char *) &status, sizeof(status)); - - /* If not completed -> exit */ - if ((status & AC_SFLD_C) == 0) - ret = 0; /* Not ready to be scrapped */ - else { -#ifdef DEBUG_CONFIG_ERROR - unsigned short cfg_addr; - unsigned short ias_addr; - - /* Check mc_config command */ - if ((status & AC_SFLD_OK) != AC_SFLD_OK) - printk(KERN_INFO - "%s: wv_config_complete(): \ - set_multicast_address failed; status = 0x%x\n", - dev->name, status); - - /* check ia-config command */ - ias_addr = mcs_addr - sizeof(ac_ias_t); - obram_read(ioaddr, acoff(ias_addr, ac_status), - (unsigned char *) &status, sizeof(status)); - if ((status & AC_SFLD_OK) != AC_SFLD_OK) - printk(KERN_INFO - "%s: wv_config_complete(): set_MAC_address \ - failed; status = 0x%x\n", - dev->name, status); - - /* Check config command. */ - cfg_addr = ias_addr - sizeof(ac_cfg_t); - obram_read(ioaddr, acoff(cfg_addr, ac_status), - (unsigned char *) &status, sizeof(status)); - if ((status & AC_SFLD_OK) != AC_SFLD_OK) - printk(KERN_INFO - "%s: wv_config_complete(): configure failed; \ - status = 0x%x\n", - dev->name, status); -#endif /* DEBUG_CONFIG_ERROR */ - - ret = 1; /* Ready to be scrapped */ - } - -#ifdef DEBUG_INTERRUPT_TRACE - printk(KERN_DEBUG "%s: <-wv_config_complete() - %d\n", dev->name, - ret); -#endif - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Command completion interrupt. - * Reclaim as many freed tx buffers as we can. - * (called in wavelan_interrupt()). - * Note : the spinlock is already grabbed for us. - */ -static int wv_complete(struct net_device *dev, - unsigned long ioaddr, - net_local *lp) -{ - int nreaped = 0; - -#ifdef DEBUG_INTERRUPT_TRACE - printk(KERN_DEBUG "%s: ->wv_complete()\n", dev->name); -#endif - - /* Loop on all the transmit buffers */ - while (lp->tx_first_in_use != I82586NULL) { - unsigned short tx_status; - - /* Read the first transmit buffer */ - obram_read(ioaddr, acoff(lp->tx_first_in_use, ac_status), - (unsigned char *) &tx_status, - sizeof(tx_status)); - - /* If not completed -> exit */ - if ((tx_status & AC_SFLD_C) == 0) - break; - - /* Hack for reconfiguration */ - if (tx_status == 0xFFFF) - if (!wv_config_complete(dev, ioaddr, lp)) - break; /* Not completed */ - - /* We now remove this buffer */ - nreaped++; - --lp->tx_n_in_use; - -/* -if (lp->tx_n_in_use > 0) - printk("%c", "0123456789abcdefghijk"[lp->tx_n_in_use]); -*/ - - /* Was it the last one? */ - if (lp->tx_n_in_use <= 0) - lp->tx_first_in_use = I82586NULL; - else { - /* Next one in the chain */ - lp->tx_first_in_use += TXBLOCKZ; - if (lp->tx_first_in_use >= - OFFSET_CU + NTXBLOCKS * TXBLOCKZ) - lp->tx_first_in_use -= NTXBLOCKS * TXBLOCKZ; - } - - /* Hack for reconfiguration */ - if (tx_status == 0xFFFF) - continue; - - /* Now, check status of the finished command */ - if (tx_status & AC_SFLD_OK) { - int ncollisions; - - dev->stats.tx_packets++; - ncollisions = tx_status & AC_SFLD_MAXCOL; - dev->stats.collisions += ncollisions; -#ifdef DEBUG_TX_INFO - if (ncollisions > 0) - printk(KERN_DEBUG - "%s: wv_complete(): tx completed after \ - %d collisions.\n", - dev->name, ncollisions); -#endif - } else { - dev->stats.tx_errors++; - if (tx_status & AC_SFLD_S10) { - dev->stats.tx_carrier_errors++; -#ifdef DEBUG_TX_FAIL - printk(KERN_DEBUG - "%s: wv_complete(): tx error: no CS.\n", - dev->name); -#endif - } - if (tx_status & AC_SFLD_S9) { - dev->stats.tx_carrier_errors++; -#ifdef DEBUG_TX_FAIL - printk(KERN_DEBUG - "%s: wv_complete(): tx error: \ - lost CTS.\n", - dev->name); -#endif - } - if (tx_status & AC_SFLD_S8) { - dev->stats.tx_fifo_errors++; -#ifdef DEBUG_TX_FAIL - printk(KERN_DEBUG - "%s: wv_complete(): tx error: \ - slow DMA.\n", - dev->name); -#endif - } - if (tx_status & AC_SFLD_S6) { - dev->stats.tx_heartbeat_errors++; -#ifdef DEBUG_TX_FAIL - printk(KERN_DEBUG - "%s: wv_complete(): tx error: \ - heart beat.\n", - dev->name); -#endif - } - if (tx_status & AC_SFLD_S5) { - dev->stats.tx_aborted_errors++; -#ifdef DEBUG_TX_FAIL - printk(KERN_DEBUG - "%s: wv_complete(): tx error: \ - too many collisions.\n", - dev->name); -#endif - } - } - -#ifdef DEBUG_TX_INFO - printk(KERN_DEBUG - "%s: wv_complete(): tx completed, tx_status 0x%04x\n", - dev->name, tx_status); -#endif - } - -#ifdef DEBUG_INTERRUPT_INFO - if (nreaped > 1) - printk(KERN_DEBUG "%s: wv_complete(): reaped %d\n", - dev->name, nreaped); -#endif - - /* - * Inform upper layers. - */ - if (lp->tx_n_in_use < NTXBLOCKS - 1) - netif_wake_queue(dev); - -#ifdef DEBUG_INTERRUPT_TRACE - printk(KERN_DEBUG "%s: <-wv_complete()\n", dev->name); -#endif - return nreaped; -} - -/*------------------------------------------------------------------*/ -/* - * Reconfigure the i82586, or at least ask for it. - *because wv_82586_config uses a transmission buffer, we must do it - * when we are sure that there is one left, so we do it now - * or in wavelan_packet_xmit() (I can't find any better place, - * wavelan_interrupt is not an option), so you may experience - * delays sometimes. - */ -static void wv_82586_reconfig(struct net_device *dev) -{ - net_local *lp = netdev_priv(dev); - unsigned long flags; - - /* Arm the flag, will be cleard in wv_82586_config() */ - lp->reconfig_82586 = 1; - - /* Check if we can do it now ! */ - if ((netif_running(dev)) && !(netif_queue_stopped(dev))) { - spin_lock_irqsave(&lp->spinlock, flags); - /* May fail */ - wv_82586_config(dev); - spin_unlock_irqrestore(&lp->spinlock, flags); - } else { -#ifdef DEBUG_CONFIG_INFO - printk(KERN_DEBUG - "%s: wv_82586_reconfig(): delayed (state = %lX)\n", - dev->name, dev->state); -#endif - } -} - -/********************* DEBUG & INFO SUBROUTINES *********************/ -/* - * This routine is used in the code to show information for debugging. - * Most of the time, it dumps the contents of hardware structures. - */ - -#ifdef DEBUG_PSA_SHOW -/*------------------------------------------------------------------*/ -/* - * Print the formatted contents of the Parameter Storage Area. - */ -static void wv_psa_show(psa_t *p) -{ - printk(KERN_DEBUG "##### WaveLAN PSA contents: #####\n"); - printk(KERN_DEBUG "psa_io_base_addr_1: 0x%02X %02X %02X %02X\n", - p->psa_io_base_addr_1, - p->psa_io_base_addr_2, - p->psa_io_base_addr_3, p->psa_io_base_addr_4); - printk(KERN_DEBUG "psa_rem_boot_addr_1: 0x%02X %02X %02X\n", - p->psa_rem_boot_addr_1, - p->psa_rem_boot_addr_2, p->psa_rem_boot_addr_3); - printk(KERN_DEBUG "psa_holi_params: 0x%02x, ", p->psa_holi_params); - printk("psa_int_req_no: %d\n", p->psa_int_req_no); -#ifdef DEBUG_SHOW_UNUSED - printk(KERN_DEBUG "psa_unused0[]: %pM\n", p->psa_unused0); -#endif /* DEBUG_SHOW_UNUSED */ - printk(KERN_DEBUG "psa_univ_mac_addr[]: %pM\n", p->psa_univ_mac_addr); - printk(KERN_DEBUG "psa_local_mac_addr[]: %pM\n", p->psa_local_mac_addr); - printk(KERN_DEBUG "psa_univ_local_sel: %d, ", - p->psa_univ_local_sel); - printk("psa_comp_number: %d, ", p->psa_comp_number); - printk("psa_thr_pre_set: 0x%02x\n", p->psa_thr_pre_set); - printk(KERN_DEBUG "psa_feature_select/decay_prm: 0x%02x, ", - p->psa_feature_select); - printk("psa_subband/decay_update_prm: %d\n", p->psa_subband); - printk(KERN_DEBUG "psa_quality_thr: 0x%02x, ", p->psa_quality_thr); - printk("psa_mod_delay: 0x%02x\n", p->psa_mod_delay); - printk(KERN_DEBUG "psa_nwid: 0x%02x%02x, ", p->psa_nwid[0], - p->psa_nwid[1]); - printk("psa_nwid_select: %d\n", p->psa_nwid_select); - printk(KERN_DEBUG "psa_encryption_select: %d, ", - p->psa_encryption_select); - printk - ("psa_encryption_key[]: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - p->psa_encryption_key[0], p->psa_encryption_key[1], - p->psa_encryption_key[2], p->psa_encryption_key[3], - p->psa_encryption_key[4], p->psa_encryption_key[5], - p->psa_encryption_key[6], p->psa_encryption_key[7]); - printk(KERN_DEBUG "psa_databus_width: %d\n", p->psa_databus_width); - printk(KERN_DEBUG "psa_call_code/auto_squelch: 0x%02x, ", - p->psa_call_code[0]); - printk - ("psa_call_code[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", - p->psa_call_code[0], p->psa_call_code[1], p->psa_call_code[2], - p->psa_call_code[3], p->psa_call_code[4], p->psa_call_code[5], - p->psa_call_code[6], p->psa_call_code[7]); -#ifdef DEBUG_SHOW_UNUSED - printk(KERN_DEBUG "psa_reserved[]: %02X:%02X\n", - p->psa_reserved[0], - p->psa_reserved[1]); -#endif /* DEBUG_SHOW_UNUSED */ - printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status); - printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]); - printk("psa_crc_status: 0x%02x\n", p->psa_crc_status); -} /* wv_psa_show */ -#endif /* DEBUG_PSA_SHOW */ - -#ifdef DEBUG_MMC_SHOW -/*------------------------------------------------------------------*/ -/* - * Print the formatted status of the Modem Management Controller. - * This function needs to be completed. - */ -static void wv_mmc_show(struct net_device *dev) -{ - unsigned long ioaddr = dev->base_addr; - net_local *lp = netdev_priv(dev); - mmr_t m; - - /*basic check */ - if (hasr_read(ioaddr) & HASR_NO_CLK) { - printk(KERN_WARNING - "%s: wv_mmc_show: modem not connected\n", - dev->name); - return; - } - - /* Read the mmc */ - mmc_out(ioaddr, mmwoff(0, mmw_freeze), 1); - mmc_read(ioaddr, 0, (u8 *) &m, sizeof(m)); - mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0); - - /* Don't forget to update statistics */ - lp->wstats.discard.nwid += - (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l; - - printk(KERN_DEBUG "##### WaveLAN modem status registers: #####\n"); -#ifdef DEBUG_SHOW_UNUSED - printk(KERN_DEBUG - "mmc_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", - m.mmr_unused0[0], m.mmr_unused0[1], m.mmr_unused0[2], - m.mmr_unused0[3], m.mmr_unused0[4], m.mmr_unused0[5], - m.mmr_unused0[6], m.mmr_unused0[7]); -#endif /* DEBUG_SHOW_UNUSED */ - printk(KERN_DEBUG "Encryption algorithm: %02X - Status: %02X\n", - m.mmr_des_avail, m.mmr_des_status); -#ifdef DEBUG_SHOW_UNUSED - printk(KERN_DEBUG "mmc_unused1[]: %02X:%02X:%02X:%02X:%02X\n", - m.mmr_unused1[0], - m.mmr_unused1[1], - m.mmr_unused1[2], m.mmr_unused1[3], m.mmr_unused1[4]); -#endif /* DEBUG_SHOW_UNUSED */ - printk(KERN_DEBUG "dce_status: 0x%x [%s%s%s%s]\n", - m.mmr_dce_status, - (m. - mmr_dce_status & MMR_DCE_STATUS_RX_BUSY) ? - "energy detected," : "", - (m. - mmr_dce_status & MMR_DCE_STATUS_LOOPT_IND) ? - "loop test indicated," : "", - (m. - mmr_dce_status & MMR_DCE_STATUS_TX_BUSY) ? - "transmitter on," : "", - (m. - mmr_dce_status & MMR_DCE_STATUS_JBR_EXPIRED) ? - "jabber timer expired," : ""); - printk(KERN_DEBUG "Dsp ID: %02X\n", m.mmr_dsp_id); -#ifdef DEBUG_SHOW_UNUSED - printk(KERN_DEBUG "mmc_unused2[]: %02X:%02X\n", - m.mmr_unused2[0], m.mmr_unused2[1]); -#endif /* DEBUG_SHOW_UNUSED */ - printk(KERN_DEBUG "# correct_nwid: %d, # wrong_nwid: %d\n", - (m.mmr_correct_nwid_h << 8) | m.mmr_correct_nwid_l, - (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l); - printk(KERN_DEBUG "thr_pre_set: 0x%x [current signal %s]\n", - m.mmr_thr_pre_set & MMR_THR_PRE_SET, - (m. - mmr_thr_pre_set & MMR_THR_PRE_SET_CUR) ? "above" : - "below"); - printk(KERN_DEBUG "signal_lvl: %d [%s], ", - m.mmr_signal_lvl & MMR_SIGNAL_LVL, - (m. - mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) ? "new msg" : - "no new msg"); - printk("silence_lvl: %d [%s], ", - m.mmr_silence_lvl & MMR_SILENCE_LVL, - (m. - mmr_silence_lvl & MMR_SILENCE_LVL_VALID) ? "update done" : - "no new update"); - printk("sgnl_qual: 0x%x [%s]\n", m.mmr_sgnl_qual & MMR_SGNL_QUAL, - (m. - mmr_sgnl_qual & MMR_SGNL_QUAL_ANT) ? "Antenna 1" : - "Antenna 0"); -#ifdef DEBUG_SHOW_UNUSED - printk(KERN_DEBUG "netw_id_l: %x\n", m.mmr_netw_id_l); -#endif /* DEBUG_SHOW_UNUSED */ -} /* wv_mmc_show */ -#endif /* DEBUG_MMC_SHOW */ - -#ifdef DEBUG_I82586_SHOW -/*------------------------------------------------------------------*/ -/* - * Print the last block of the i82586 memory. - */ -static void wv_scb_show(unsigned long ioaddr) -{ - scb_t scb; - - obram_read(ioaddr, OFFSET_SCB, (unsigned char *) &scb, - sizeof(scb)); - - printk(KERN_DEBUG "##### WaveLAN system control block: #####\n"); - - printk(KERN_DEBUG "status: "); - printk("stat 0x%x[%s%s%s%s] ", - (scb. - scb_status & (SCB_ST_CX | SCB_ST_FR | SCB_ST_CNA | - SCB_ST_RNR)) >> 12, - (scb. - scb_status & SCB_ST_CX) ? "command completion interrupt," : - "", (scb.scb_status & SCB_ST_FR) ? "frame received," : "", - (scb. - scb_status & SCB_ST_CNA) ? "command unit not active," : "", - (scb. - scb_status & SCB_ST_RNR) ? "receiving unit not ready," : - ""); - printk("cus 0x%x[%s%s%s] ", (scb.scb_status & SCB_ST_CUS) >> 8, - ((scb.scb_status & SCB_ST_CUS) == - SCB_ST_CUS_IDLE) ? "idle" : "", - ((scb.scb_status & SCB_ST_CUS) == - SCB_ST_CUS_SUSP) ? "suspended" : "", - ((scb.scb_status & SCB_ST_CUS) == - SCB_ST_CUS_ACTV) ? "active" : ""); - printk("rus 0x%x[%s%s%s%s]\n", (scb.scb_status & SCB_ST_RUS) >> 4, - ((scb.scb_status & SCB_ST_RUS) == - SCB_ST_RUS_IDLE) ? "idle" : "", - ((scb.scb_status & SCB_ST_RUS) == - SCB_ST_RUS_SUSP) ? "suspended" : "", - ((scb.scb_status & SCB_ST_RUS) == - SCB_ST_RUS_NRES) ? "no resources" : "", - ((scb.scb_status & SCB_ST_RUS) == - SCB_ST_RUS_RDY) ? "ready" : ""); - - printk(KERN_DEBUG "command: "); - printk("ack 0x%x[%s%s%s%s] ", - (scb. - scb_command & (SCB_CMD_ACK_CX | SCB_CMD_ACK_FR | - SCB_CMD_ACK_CNA | SCB_CMD_ACK_RNR)) >> 12, - (scb. - scb_command & SCB_CMD_ACK_CX) ? "ack cmd completion," : "", - (scb. - scb_command & SCB_CMD_ACK_FR) ? "ack frame received," : "", - (scb. - scb_command & SCB_CMD_ACK_CNA) ? "ack CU not active," : "", - (scb. - scb_command & SCB_CMD_ACK_RNR) ? "ack RU not ready," : ""); - printk("cuc 0x%x[%s%s%s%s%s] ", - (scb.scb_command & SCB_CMD_CUC) >> 8, - ((scb.scb_command & SCB_CMD_CUC) == - SCB_CMD_CUC_NOP) ? "nop" : "", - ((scb.scb_command & SCB_CMD_CUC) == - SCB_CMD_CUC_GO) ? "start cbl_offset" : "", - ((scb.scb_command & SCB_CMD_CUC) == - SCB_CMD_CUC_RES) ? "resume execution" : "", - ((scb.scb_command & SCB_CMD_CUC) == - SCB_CMD_CUC_SUS) ? "suspend execution" : "", - ((scb.scb_command & SCB_CMD_CUC) == - SCB_CMD_CUC_ABT) ? "abort execution" : ""); - printk("ruc 0x%x[%s%s%s%s%s]\n", - (scb.scb_command & SCB_CMD_RUC) >> 4, - ((scb.scb_command & SCB_CMD_RUC) == - SCB_CMD_RUC_NOP) ? "nop" : "", - ((scb.scb_command & SCB_CMD_RUC) == - SCB_CMD_RUC_GO) ? "start rfa_offset" : "", - ((scb.scb_command & SCB_CMD_RUC) == - SCB_CMD_RUC_RES) ? "resume reception" : "", - ((scb.scb_command & SCB_CMD_RUC) == - SCB_CMD_RUC_SUS) ? "suspend reception" : "", - ((scb.scb_command & SCB_CMD_RUC) == - SCB_CMD_RUC_ABT) ? "abort reception" : ""); - - printk(KERN_DEBUG "cbl_offset 0x%x ", scb.scb_cbl_offset); - printk("rfa_offset 0x%x\n", scb.scb_rfa_offset); - - printk(KERN_DEBUG "crcerrs %d ", scb.scb_crcerrs); - printk("alnerrs %d ", scb.scb_alnerrs); - printk("rscerrs %d ", scb.scb_rscerrs); - printk("ovrnerrs %d\n", scb.scb_ovrnerrs); -} - -/*------------------------------------------------------------------*/ -/* - * Print the formatted status of the i82586's receive unit. - */ -static void wv_ru_show(struct net_device *dev) -{ - printk(KERN_DEBUG - "##### WaveLAN i82586 receiver unit status: #####\n"); - printk(KERN_DEBUG "ru:"); - /* - * Not implemented yet - */ - printk("\n"); -} /* wv_ru_show */ - -/*------------------------------------------------------------------*/ -/* - * Display info about one control block of the i82586 memory. - */ -static void wv_cu_show_one(struct net_device *dev, net_local * lp, int i, u16 p) -{ - unsigned long ioaddr; - ac_tx_t actx; - - ioaddr = dev->base_addr; - - printk("%d: 0x%x:", i, p); - - obram_read(ioaddr, p, (unsigned char *) &actx, sizeof(actx)); - printk(" status=0x%x,", actx.tx_h.ac_status); - printk(" command=0x%x,", actx.tx_h.ac_command); - - /* - { - tbd_t tbd; - - obram_read(ioaddr, actx.tx_tbd_offset, (unsigned char *)&tbd, sizeof(tbd)); - printk(" tbd_status=0x%x,", tbd.tbd_status); - } - */ - - printk("|"); -} - -/*------------------------------------------------------------------*/ -/* - * Print status of the command unit of the i82586. - */ -static void wv_cu_show(struct net_device *dev) -{ - net_local *lp = netdev_priv(dev); - unsigned int i; - u16 p; - - printk(KERN_DEBUG - "##### WaveLAN i82586 command unit status: #####\n"); - - printk(KERN_DEBUG); - for (i = 0, p = lp->tx_first_in_use; i < NTXBLOCKS; i++) { - wv_cu_show_one(dev, lp, i, p); - - p += TXBLOCKZ; - if (p >= OFFSET_CU + NTXBLOCKS * TXBLOCKZ) - p -= NTXBLOCKS * TXBLOCKZ; - } - printk("\n"); -} -#endif /* DEBUG_I82586_SHOW */ - -#ifdef DEBUG_DEVICE_SHOW -/*------------------------------------------------------------------*/ -/* - * Print the formatted status of the WaveLAN PCMCIA device driver. - */ -static void wv_dev_show(struct net_device *dev) -{ - printk(KERN_DEBUG "dev:"); - printk(" state=%lX,", dev->state); - printk(" trans_start=%ld,", dev->trans_start); - printk(" flags=0x%x,", dev->flags); - printk("\n"); -} /* wv_dev_show */ - -/*------------------------------------------------------------------*/ -/* - * Print the formatted status of the WaveLAN PCMCIA device driver's - * private information. - */ -static void wv_local_show(struct net_device *dev) -{ - net_local *lp; - - lp = netdev_priv(dev); - - printk(KERN_DEBUG "local:"); - printk(" tx_n_in_use=%d,", lp->tx_n_in_use); - printk(" hacr=0x%x,", lp->hacr); - printk(" rx_head=0x%x,", lp->rx_head); - printk(" rx_last=0x%x,", lp->rx_last); - printk(" tx_first_free=0x%x,", lp->tx_first_free); - printk(" tx_first_in_use=0x%x,", lp->tx_first_in_use); - printk("\n"); -} /* wv_local_show */ -#endif /* DEBUG_DEVICE_SHOW */ - -#if defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO) -/*------------------------------------------------------------------*/ -/* - * Dump packet header (and content if necessary) on the screen - */ -static inline void wv_packet_info(u8 * p, /* Packet to dump */ - int length, /* Length of the packet */ - char *msg1, /* Name of the device */ - char *msg2) -{ /* Name of the function */ - int i; - int maxi; - - printk(KERN_DEBUG - "%s: %s(): dest %pM, length %d\n", - msg1, msg2, p, length); - printk(KERN_DEBUG - "%s: %s(): src %pM, type 0x%02X%02X\n", - msg1, msg2, &p[6], p[12], p[13]); - -#ifdef DEBUG_PACKET_DUMP - - printk(KERN_DEBUG "data=\""); - - if ((maxi = length) > DEBUG_PACKET_DUMP) - maxi = DEBUG_PACKET_DUMP; - for (i = 14; i < maxi; i++) - if (p[i] >= ' ' && p[i] <= '~') - printk(" %c", p[i]); - else - printk("%02X", p[i]); - if (maxi < length) - printk(".."); - printk("\"\n"); - printk(KERN_DEBUG "\n"); -#endif /* DEBUG_PACKET_DUMP */ -} -#endif /* defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO) */ - -/*------------------------------------------------------------------*/ -/* - * This is the information which is displayed by the driver at startup. - * There are lots of flags for configuring it to your liking. - */ -static void wv_init_info(struct net_device *dev) -{ - short ioaddr = dev->base_addr; - net_local *lp = netdev_priv(dev); - psa_t psa; - - /* Read the parameter storage area */ - psa_read(ioaddr, lp->hacr, 0, (unsigned char *) &psa, sizeof(psa)); - -#ifdef DEBUG_PSA_SHOW - wv_psa_show(&psa); -#endif -#ifdef DEBUG_MMC_SHOW - wv_mmc_show(dev); -#endif -#ifdef DEBUG_I82586_SHOW - wv_cu_show(dev); -#endif - -#ifdef DEBUG_BASIC_SHOW - /* Now, let's go for the basic stuff. */ - printk(KERN_NOTICE "%s: WaveLAN at %#x, %pM, IRQ %d", - dev->name, ioaddr, dev->dev_addr, dev->irq); - - /* Print current network ID. */ - if (psa.psa_nwid_select) - printk(", nwid 0x%02X-%02X", psa.psa_nwid[0], - psa.psa_nwid[1]); - else - printk(", nwid off"); - - /* If 2.00 card */ - if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) & - (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) { - unsigned short freq; - - /* Ask the EEPROM to read the frequency from the first area. */ - fee_read(ioaddr, 0x00, &freq, 1); - - /* Print frequency */ - printk(", 2.00, %ld", (freq >> 6) + 2400L); - - /* Hack! */ - if (freq & 0x20) - printk(".5"); - } else { - printk(", PC"); - switch (psa.psa_comp_number) { - case PSA_COMP_PC_AT_915: - case PSA_COMP_PC_AT_2400: - printk("-AT"); - break; - case PSA_COMP_PC_MC_915: - case PSA_COMP_PC_MC_2400: - printk("-MC"); - break; - case PSA_COMP_PCMCIA_915: - printk("MCIA"); - break; - default: - printk("?"); - } - printk(", "); - switch (psa.psa_subband) { - case PSA_SUBBAND_915: - printk("915"); - break; - case PSA_SUBBAND_2425: - printk("2425"); - break; - case PSA_SUBBAND_2460: - printk("2460"); - break; - case PSA_SUBBAND_2484: - printk("2484"); - break; - case PSA_SUBBAND_2430_5: - printk("2430.5"); - break; - default: - printk("?"); - } - } - - printk(" MHz\n"); -#endif /* DEBUG_BASIC_SHOW */ - -#ifdef DEBUG_VERSION_SHOW - /* Print version information */ - printk(KERN_NOTICE "%s", version); -#endif -} /* wv_init_info */ - -/********************* IOCTL, STATS & RECONFIG *********************/ -/* - * We found here routines that are called by Linux on different - * occasions after the configuration and not for transmitting data - * These may be called when the user use ifconfig, /proc/net/dev - * or wireless extensions - */ - - -/*------------------------------------------------------------------*/ -/* - * Set or clear the multicast filter for this adaptor. - * num_addrs == -1 Promiscuous mode, receive all packets - * num_addrs == 0 Normal mode, clear multicast list - * num_addrs > 0 Multicast mode, receive normal and MC packets, - * and do best-effort filtering. - */ -static void wavelan_set_multicast_list(struct net_device *dev) -{ - net_local *lp = netdev_priv(dev); - -#ifdef DEBUG_IOCTL_TRACE - printk(KERN_DEBUG "%s: ->wavelan_set_multicast_list()\n", - dev->name); -#endif - -#ifdef DEBUG_IOCTL_INFO - printk(KERN_DEBUG - "%s: wavelan_set_multicast_list(): setting Rx mode %02X to %d addresses.\n", - dev->name, dev->flags, netdev_mc_count(dev)); -#endif - - /* Are we asking for promiscuous mode, - * or all multicast addresses (we don't have that!) - * or too many multicast addresses for the hardware filter? */ - if ((dev->flags & IFF_PROMISC) || - (dev->flags & IFF_ALLMULTI) || - (netdev_mc_count(dev) > I82586_MAX_MULTICAST_ADDRESSES)) { - /* - * Enable promiscuous mode: receive all packets. - */ - if (!lp->promiscuous) { - lp->promiscuous = 1; - lp->mc_count = 0; - - wv_82586_reconfig(dev); - } - } else - /* Are there multicast addresses to send? */ - if (!netdev_mc_empty(dev)) { - /* - * Disable promiscuous mode, but receive all packets - * in multicast list - */ -#ifdef MULTICAST_AVOID - if (lp->promiscuous || (netdev_mc_count(dev) != lp->mc_count)) -#endif - { - lp->promiscuous = 0; - lp->mc_count = netdev_mc_count(dev); - - wv_82586_reconfig(dev); - } - } else { - /* - * Switch to normal mode: disable promiscuous mode and - * clear the multicast list. - */ - if (lp->promiscuous || lp->mc_count == 0) { - lp->promiscuous = 0; - lp->mc_count = 0; - - wv_82586_reconfig(dev); - } - } -#ifdef DEBUG_IOCTL_TRACE - printk(KERN_DEBUG "%s: <-wavelan_set_multicast_list()\n", - dev->name); -#endif -} - -/*------------------------------------------------------------------*/ -/* - * This function doesn't exist. - * (Note : it was a nice way to test the reconfigure stuff...) - */ -#ifdef SET_MAC_ADDRESS -static int wavelan_set_mac_address(struct net_device *dev, void *addr) -{ - struct sockaddr *mac = addr; - - /* Copy the address. */ - memcpy(dev->dev_addr, mac->sa_data, WAVELAN_ADDR_SIZE); - - /* Reconfigure the beast. */ - wv_82586_reconfig(dev); - - return 0; -} -#endif /* SET_MAC_ADDRESS */ - - -/*------------------------------------------------------------------*/ -/* - * Frequency setting (for hardware capable of it) - * It's a bit complicated and you don't really want to look into it. - * (called in wavelan_ioctl) - */ -static int wv_set_frequency(unsigned long ioaddr, /* I/O port of the card */ - iw_freq * frequency) -{ - const int BAND_NUM = 10; /* Number of bands */ - long freq = 0L; /* offset to 2.4 GHz in .5 MHz */ -#ifdef DEBUG_IOCTL_INFO - int i; -#endif - - /* Setting by frequency */ - /* Theoretically, you may set any frequency between - * the two limits with a 0.5 MHz precision. In practice, - * I don't want you to have trouble with local regulations. - */ - if ((frequency->e == 1) && - (frequency->m >= (int) 2.412e8) - && (frequency->m <= (int) 2.487e8)) { - freq = ((frequency->m / 10000) - 24000L) / 5; - } - - /* Setting by channel (same as wfreqsel) */ - /* Warning: each channel is 22 MHz wide, so some of the channels - * will interfere. */ - if ((frequency->e == 0) && (frequency->m < BAND_NUM)) { - /* Get frequency offset. */ - freq = channel_bands[frequency->m] >> 1; - } - - /* Verify that the frequency is allowed. */ - if (freq != 0L) { - u16 table[10]; /* Authorized frequency table */ - - /* Read the frequency table. */ - fee_read(ioaddr, 0x71, table, 10); - -#ifdef DEBUG_IOCTL_INFO - printk(KERN_DEBUG "Frequency table: "); - for (i = 0; i < 10; i++) { - printk(" %04X", table[i]); - } - printk("\n"); -#endif - - /* Look in the table to see whether the frequency is allowed. */ - if (!(table[9 - ((freq - 24) / 16)] & - (1 << ((freq - 24) % 16)))) return -EINVAL; /* not allowed */ - } else - return -EINVAL; - - /* if we get a usable frequency */ - if (freq != 0L) { - unsigned short area[16]; - unsigned short dac[2]; - unsigned short area_verify[16]; - unsigned short dac_verify[2]; - /* Corresponding gain (in the power adjust value table) - * See AT&T WaveLAN Data Manual, REF 407-024689/E, page 3-8 - * and WCIN062D.DOC, page 6.2.9. */ - unsigned short power_limit[] = { 40, 80, 120, 160, 0 }; - int power_band = 0; /* Selected band */ - unsigned short power_adjust; /* Correct value */ - - /* Search for the gain. */ - power_band = 0; - while ((freq > power_limit[power_band]) && - (power_limit[++power_band] != 0)); - - /* Read the first area. */ - fee_read(ioaddr, 0x00, area, 16); - - /* Read the DAC. */ - fee_read(ioaddr, 0x60, dac, 2); - - /* Read the new power adjust value. */ - fee_read(ioaddr, 0x6B - (power_band >> 1), &power_adjust, - 1); - if (power_band & 0x1) - power_adjust >>= 8; - else - power_adjust &= 0xFF; - -#ifdef DEBUG_IOCTL_INFO - printk(KERN_DEBUG "WaveLAN EEPROM Area 1: "); - for (i = 0; i < 16; i++) { - printk(" %04X", area[i]); - } - printk("\n"); - - printk(KERN_DEBUG "WaveLAN EEPROM DAC: %04X %04X\n", - dac[0], dac[1]); -#endif - - /* Frequency offset (for info only) */ - area[0] = ((freq << 5) & 0xFFE0) | (area[0] & 0x1F); - - /* Receiver Principle main divider coefficient */ - area[3] = (freq >> 1) + 2400L - 352L; - area[2] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF); - - /* Transmitter Main divider coefficient */ - area[13] = (freq >> 1) + 2400L; - area[12] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF); - - /* Other parts of the area are flags, bit streams or unused. */ - - /* Set the value in the DAC. */ - dac[1] = ((power_adjust >> 1) & 0x7F) | (dac[1] & 0xFF80); - dac[0] = ((power_adjust & 0x1) << 4) | (dac[0] & 0xFFEF); - - /* Write the first area. */ - fee_write(ioaddr, 0x00, area, 16); - - /* Write the DAC. */ - fee_write(ioaddr, 0x60, dac, 2); - - /* We now should verify here that the writing of the EEPROM went OK. */ - - /* Reread the first area. */ - fee_read(ioaddr, 0x00, area_verify, 16); - - /* Reread the DAC. */ - fee_read(ioaddr, 0x60, dac_verify, 2); - - /* Compare. */ - if (memcmp(area, area_verify, 16 * 2) || - memcmp(dac, dac_verify, 2 * 2)) { -#ifdef DEBUG_IOCTL_ERROR - printk(KERN_INFO - "WaveLAN: wv_set_frequency: unable to write new frequency to EEPROM(?).\n"); -#endif - return -EOPNOTSUPP; - } - - /* We must download the frequency parameters to the - * synthesizers (from the EEPROM - area 1) - * Note: as the EEPROM is automatically decremented, we set the end - * if the area... */ - mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), 0x0F); - mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), - MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD); - - /* Wait until the download is finished. */ - fee_wait(ioaddr, 100, 100); - - /* We must now download the power adjust value (gain) to - * the synthesizers (from the EEPROM - area 7 - DAC). */ - mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), 0x61); - mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), - MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD); - - /* Wait for the download to finish. */ - fee_wait(ioaddr, 100, 100); - -#ifdef DEBUG_IOCTL_INFO - /* Verification of what we have done */ - - printk(KERN_DEBUG "WaveLAN EEPROM Area 1: "); - for (i = 0; i < 16; i++) { - printk(" %04X", area_verify[i]); - } - printk("\n"); - - printk(KERN_DEBUG "WaveLAN EEPROM DAC: %04X %04X\n", - dac_verify[0], dac_verify[1]); -#endif - - return 0; - } else - return -EINVAL; /*bah, never get there... */ -} - -/*------------------------------------------------------------------*/ -/* - * Give the list of available frequencies. - */ -static int wv_frequency_list(unsigned long ioaddr, /* I/O port of the card */ - iw_freq * list, /* List of frequencies to fill */ - int max) -{ /* Maximum number of frequencies */ - u16 table[10]; /* Authorized frequency table */ - long freq = 0L; /* offset to 2.4 GHz in .5 MHz + 12 MHz */ - int i; /* index in the table */ - int c = 0; /* Channel number */ - - /* Read the frequency table. */ - fee_read(ioaddr, 0x71 /* frequency table */ , table, 10); - - /* Check all frequencies. */ - i = 0; - for (freq = 0; freq < 150; freq++) - /* Look in the table if the frequency is allowed */ - if (table[9 - (freq / 16)] & (1 << (freq % 16))) { - /* Compute approximate channel number */ - while ((c < ARRAY_SIZE(channel_bands)) && - (((channel_bands[c] >> 1) - 24) < freq)) - c++; - list[i].i = c; /* Set the list index */ - - /* put in the list */ - list[i].m = (((freq + 24) * 5) + 24000L) * 10000; - list[i++].e = 1; - - /* Check number. */ - if (i >= max) - return (i); - } - - return (i); -} - -#ifdef IW_WIRELESS_SPY -/*------------------------------------------------------------------*/ -/* - * Gather wireless spy statistics: for each packet, compare the source - * address with our list, and if they match, get the statistics. - * Sorry, but this function really needs the wireless extensions. - */ -static inline void wl_spy_gather(struct net_device *dev, - u8 * mac, /* MAC address */ - u8 * stats) /* Statistics to gather */ -{ - struct iw_quality wstats; - - wstats.qual = stats[2] & MMR_SGNL_QUAL; - wstats.level = stats[0] & MMR_SIGNAL_LVL; - wstats.noise = stats[1] & MMR_SILENCE_LVL; - wstats.updated = 0x7; - - /* Update spy records */ - wireless_spy_update(dev, mac, &wstats); -} -#endif /* IW_WIRELESS_SPY */ - -#ifdef HISTOGRAM -/*------------------------------------------------------------------*/ -/* - * This function calculates a histogram of the signal level. - * As the noise is quite constant, it's like doing it on the SNR. - * We have defined a set of interval (lp->his_range), and each time - * the level goes in that interval, we increment the count (lp->his_sum). - * With this histogram you may detect if one WaveLAN is really weak, - * or you may also calculate the mean and standard deviation of the level. - */ -static inline void wl_his_gather(struct net_device *dev, u8 * stats) -{ /* Statistics to gather */ - net_local *lp = netdev_priv(dev); - u8 level = stats[0] & MMR_SIGNAL_LVL; - int i; - - /* Find the correct interval. */ - i = 0; - while ((i < (lp->his_number - 1)) - && (level >= lp->his_range[i++])); - - /* Increment interval counter. */ - (lp->his_sum[i])++; -} -#endif /* HISTOGRAM */ - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : get protocol name - */ -static int wavelan_get_name(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - strcpy(wrqu->name, "WaveLAN"); - return 0; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : set NWID - */ -static int wavelan_set_nwid(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned long ioaddr = dev->base_addr; - net_local *lp = netdev_priv(dev); /* lp is not unused */ - psa_t psa; - mm_t m; - unsigned long flags; - int ret = 0; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Set NWID in WaveLAN. */ - if (!wrqu->nwid.disabled) { - /* Set NWID in psa */ - psa.psa_nwid[0] = (wrqu->nwid.value & 0xFF00) >> 8; - psa.psa_nwid[1] = wrqu->nwid.value & 0xFF; - psa.psa_nwid_select = 0x01; - psa_write(ioaddr, lp->hacr, - (char *) psa.psa_nwid - (char *) &psa, - (unsigned char *) psa.psa_nwid, 3); - - /* Set NWID in mmc. */ - m.w.mmw_netw_id_l = psa.psa_nwid[1]; - m.w.mmw_netw_id_h = psa.psa_nwid[0]; - mmc_write(ioaddr, - (char *) &m.w.mmw_netw_id_l - - (char *) &m, - (unsigned char *) &m.w.mmw_netw_id_l, 2); - mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel), 0x00); - } else { - /* Disable NWID in the psa. */ - psa.psa_nwid_select = 0x00; - psa_write(ioaddr, lp->hacr, - (char *) &psa.psa_nwid_select - - (char *) &psa, - (unsigned char *) &psa.psa_nwid_select, - 1); - - /* Disable NWID in the mmc (no filtering). */ - mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel), - MMW_LOOPT_SEL_DIS_NWID); - } - /* update the Wavelan checksum */ - update_psa_checksum(dev, ioaddr, lp->hacr); - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : get NWID - */ -static int wavelan_get_nwid(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned long ioaddr = dev->base_addr; - net_local *lp = netdev_priv(dev); /* lp is not unused */ - psa_t psa; - unsigned long flags; - int ret = 0; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Read the NWID. */ - psa_read(ioaddr, lp->hacr, - (char *) psa.psa_nwid - (char *) &psa, - (unsigned char *) psa.psa_nwid, 3); - wrqu->nwid.value = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1]; - wrqu->nwid.disabled = !(psa.psa_nwid_select); - wrqu->nwid.fixed = 1; /* Superfluous */ - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : set frequency - */ -static int wavelan_set_freq(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned long ioaddr = dev->base_addr; - net_local *lp = netdev_priv(dev); /* lp is not unused */ - unsigned long flags; - int ret; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */ - if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) & - (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) - ret = wv_set_frequency(ioaddr, &(wrqu->freq)); - else - ret = -EOPNOTSUPP; - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : get frequency - */ -static int wavelan_get_freq(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned long ioaddr = dev->base_addr; - net_local *lp = netdev_priv(dev); /* lp is not unused */ - psa_t psa; - unsigned long flags; - int ret = 0; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). - * Does it work for everybody, especially old cards? */ - if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) & - (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) { - unsigned short freq; - - /* Ask the EEPROM to read the frequency from the first area. */ - fee_read(ioaddr, 0x00, &freq, 1); - wrqu->freq.m = ((freq >> 5) * 5 + 24000L) * 10000; - wrqu->freq.e = 1; - } else { - psa_read(ioaddr, lp->hacr, - (char *) &psa.psa_subband - (char *) &psa, - (unsigned char *) &psa.psa_subband, 1); - - if (psa.psa_subband <= 4) { - wrqu->freq.m = fixed_bands[psa.psa_subband]; - wrqu->freq.e = (psa.psa_subband != 0); - } else - ret = -EOPNOTSUPP; - } - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : set level threshold - */ -static int wavelan_set_sens(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned long ioaddr = dev->base_addr; - net_local *lp = netdev_priv(dev); /* lp is not unused */ - psa_t psa; - unsigned long flags; - int ret = 0; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Set the level threshold. */ - /* We should complain loudly if wrqu->sens.fixed = 0, because we - * can't set auto mode... */ - psa.psa_thr_pre_set = wrqu->sens.value & 0x3F; - psa_write(ioaddr, lp->hacr, - (char *) &psa.psa_thr_pre_set - (char *) &psa, - (unsigned char *) &psa.psa_thr_pre_set, 1); - /* update the Wavelan checksum */ - update_psa_checksum(dev, ioaddr, lp->hacr); - mmc_out(ioaddr, mmwoff(0, mmw_thr_pre_set), - psa.psa_thr_pre_set); - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : get level threshold - */ -static int wavelan_get_sens(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned long ioaddr = dev->base_addr; - net_local *lp = netdev_priv(dev); /* lp is not unused */ - psa_t psa; - unsigned long flags; - int ret = 0; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Read the level threshold. */ - psa_read(ioaddr, lp->hacr, - (char *) &psa.psa_thr_pre_set - (char *) &psa, - (unsigned char *) &psa.psa_thr_pre_set, 1); - wrqu->sens.value = psa.psa_thr_pre_set & 0x3F; - wrqu->sens.fixed = 1; - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : set encryption key - */ -static int wavelan_set_encode(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned long ioaddr = dev->base_addr; - net_local *lp = netdev_priv(dev); /* lp is not unused */ - unsigned long flags; - psa_t psa; - int ret = 0; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Check if capable of encryption */ - if (!mmc_encr(ioaddr)) { - ret = -EOPNOTSUPP; - } - - /* Check the size of the key */ - if((wrqu->encoding.length != 8) && (wrqu->encoding.length != 0)) { - ret = -EINVAL; - } - - if(!ret) { - /*basic checking... */ - if (wrqu->encoding.length == 8) { - /* Copy the key in the driver */ - memcpy(psa.psa_encryption_key, extra, - wrqu->encoding.length); - psa.psa_encryption_select = 1; - - psa_write(ioaddr, lp->hacr, - (char *) &psa.psa_encryption_select - - (char *) &psa, - (unsigned char *) &psa. - psa_encryption_select, 8 + 1); - - mmc_out(ioaddr, mmwoff(0, mmw_encr_enable), - MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE); - mmc_write(ioaddr, mmwoff(0, mmw_encr_key), - (unsigned char *) &psa. - psa_encryption_key, 8); - } - - /* disable encryption */ - if (wrqu->encoding.flags & IW_ENCODE_DISABLED) { - psa.psa_encryption_select = 0; - psa_write(ioaddr, lp->hacr, - (char *) &psa.psa_encryption_select - - (char *) &psa, - (unsigned char *) &psa. - psa_encryption_select, 1); - - mmc_out(ioaddr, mmwoff(0, mmw_encr_enable), 0); - } - /* update the Wavelan checksum */ - update_psa_checksum(dev, ioaddr, lp->hacr); - } - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : get encryption key - */ -static int wavelan_get_encode(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned long ioaddr = dev->base_addr; - net_local *lp = netdev_priv(dev); /* lp is not unused */ - psa_t psa; - unsigned long flags; - int ret = 0; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Check if encryption is available */ - if (!mmc_encr(ioaddr)) { - ret = -EOPNOTSUPP; - } else { - /* Read the encryption key */ - psa_read(ioaddr, lp->hacr, - (char *) &psa.psa_encryption_select - - (char *) &psa, - (unsigned char *) &psa. - psa_encryption_select, 1 + 8); - - /* encryption is enabled ? */ - if (psa.psa_encryption_select) - wrqu->encoding.flags = IW_ENCODE_ENABLED; - else - wrqu->encoding.flags = IW_ENCODE_DISABLED; - wrqu->encoding.flags |= mmc_encr(ioaddr); - - /* Copy the key to the user buffer */ - wrqu->encoding.length = 8; - memcpy(extra, psa.psa_encryption_key, wrqu->encoding.length); - } - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : get range info - */ -static int wavelan_get_range(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned long ioaddr = dev->base_addr; - net_local *lp = netdev_priv(dev); /* lp is not unused */ - struct iw_range *range = (struct iw_range *) extra; - unsigned long flags; - int ret = 0; - - /* Set the length (very important for backward compatibility) */ - wrqu->data.length = sizeof(struct iw_range); - - /* Set all the info we don't care or don't know about to zero */ - memset(range, 0, sizeof(struct iw_range)); - - /* Set the Wireless Extension versions */ - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 9; - - /* Set information in the range struct. */ - range->throughput = 1.6 * 1000 * 1000; /* don't argue on this ! */ - range->min_nwid = 0x0000; - range->max_nwid = 0xFFFF; - - range->sensitivity = 0x3F; - range->max_qual.qual = MMR_SGNL_QUAL; - range->max_qual.level = MMR_SIGNAL_LVL; - range->max_qual.noise = MMR_SILENCE_LVL; - range->avg_qual.qual = MMR_SGNL_QUAL; /* Always max */ - /* Need to get better values for those two */ - range->avg_qual.level = 30; - range->avg_qual.noise = 8; - - range->num_bitrates = 1; - range->bitrate[0] = 2000000; /* 2 Mb/s */ - - /* Event capability (kernel + driver) */ - range->event_capa[0] = (IW_EVENT_CAPA_MASK(0x8B02) | - IW_EVENT_CAPA_MASK(0x8B04)); - range->event_capa[1] = IW_EVENT_CAPA_K_1; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */ - if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) & - (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) { - range->num_channels = 10; - range->num_frequency = wv_frequency_list(ioaddr, range->freq, - IW_MAX_FREQUENCIES); - } else - range->num_channels = range->num_frequency = 0; - - /* Encryption supported ? */ - if (mmc_encr(ioaddr)) { - range->encoding_size[0] = 8; /* DES = 64 bits key */ - range->num_encoding_sizes = 1; - range->max_encoding_tokens = 1; /* Only one key possible */ - } else { - range->num_encoding_sizes = 0; - range->max_encoding_tokens = 0; - } - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Private Handler : set quality threshold - */ -static int wavelan_set_qthr(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned long ioaddr = dev->base_addr; - net_local *lp = netdev_priv(dev); /* lp is not unused */ - psa_t psa; - unsigned long flags; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - psa.psa_quality_thr = *(extra) & 0x0F; - psa_write(ioaddr, lp->hacr, - (char *) &psa.psa_quality_thr - (char *) &psa, - (unsigned char *) &psa.psa_quality_thr, 1); - /* update the Wavelan checksum */ - update_psa_checksum(dev, ioaddr, lp->hacr); - mmc_out(ioaddr, mmwoff(0, mmw_quality_thr), - psa.psa_quality_thr); - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return 0; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Private Handler : get quality threshold - */ -static int wavelan_get_qthr(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned long ioaddr = dev->base_addr; - net_local *lp = netdev_priv(dev); /* lp is not unused */ - psa_t psa; - unsigned long flags; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - psa_read(ioaddr, lp->hacr, - (char *) &psa.psa_quality_thr - (char *) &psa, - (unsigned char *) &psa.psa_quality_thr, 1); - *(extra) = psa.psa_quality_thr & 0x0F; - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return 0; -} - -#ifdef HISTOGRAM -/*------------------------------------------------------------------*/ -/* - * Wireless Private Handler : set histogram - */ -static int wavelan_set_histo(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - net_local *lp = netdev_priv(dev); /* lp is not unused */ - - /* Check the number of intervals. */ - if (wrqu->data.length > 16) { - return(-E2BIG); - } - - /* Disable histo while we copy the addresses. - * As we don't disable interrupts, we need to do this */ - lp->his_number = 0; - - /* Are there ranges to copy? */ - if (wrqu->data.length > 0) { - /* Copy interval ranges to the driver */ - memcpy(lp->his_range, extra, wrqu->data.length); - - { - int i; - printk(KERN_DEBUG "Histo :"); - for(i = 0; i < wrqu->data.length; i++) - printk(" %d", lp->his_range[i]); - printk("\n"); - } - - /* Reset result structure. */ - memset(lp->his_sum, 0x00, sizeof(long) * 16); - } - - /* Now we can set the number of ranges */ - lp->his_number = wrqu->data.length; - - return(0); -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Private Handler : get histogram - */ -static int wavelan_get_histo(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - net_local *lp = netdev_priv(dev); /* lp is not unused */ - - /* Set the number of intervals. */ - wrqu->data.length = lp->his_number; - - /* Give back the distribution statistics */ - if(lp->his_number > 0) - memcpy(extra, lp->his_sum, sizeof(long) * lp->his_number); - - return(0); -} -#endif /* HISTOGRAM */ - -/*------------------------------------------------------------------*/ -/* - * Structures to export the Wireless Handlers - */ - -static const iw_handler wavelan_handler[] = -{ - NULL, /* SIOCSIWNAME */ - wavelan_get_name, /* SIOCGIWNAME */ - wavelan_set_nwid, /* SIOCSIWNWID */ - wavelan_get_nwid, /* SIOCGIWNWID */ - wavelan_set_freq, /* SIOCSIWFREQ */ - wavelan_get_freq, /* SIOCGIWFREQ */ - NULL, /* SIOCSIWMODE */ - NULL, /* SIOCGIWMODE */ - wavelan_set_sens, /* SIOCSIWSENS */ - wavelan_get_sens, /* SIOCGIWSENS */ - NULL, /* SIOCSIWRANGE */ - wavelan_get_range, /* SIOCGIWRANGE */ - NULL, /* SIOCSIWPRIV */ - NULL, /* SIOCGIWPRIV */ - NULL, /* SIOCSIWSTATS */ - NULL, /* SIOCGIWSTATS */ - iw_handler_set_spy, /* SIOCSIWSPY */ - iw_handler_get_spy, /* SIOCGIWSPY */ - iw_handler_set_thrspy, /* SIOCSIWTHRSPY */ - iw_handler_get_thrspy, /* SIOCGIWTHRSPY */ - NULL, /* SIOCSIWAP */ - NULL, /* SIOCGIWAP */ - NULL, /* -- hole -- */ - NULL, /* SIOCGIWAPLIST */ - NULL, /* -- hole -- */ - NULL, /* -- hole -- */ - NULL, /* SIOCSIWESSID */ - NULL, /* SIOCGIWESSID */ - NULL, /* SIOCSIWNICKN */ - NULL, /* SIOCGIWNICKN */ - NULL, /* -- hole -- */ - NULL, /* -- hole -- */ - NULL, /* SIOCSIWRATE */ - NULL, /* SIOCGIWRATE */ - NULL, /* SIOCSIWRTS */ - NULL, /* SIOCGIWRTS */ - NULL, /* SIOCSIWFRAG */ - NULL, /* SIOCGIWFRAG */ - NULL, /* SIOCSIWTXPOW */ - NULL, /* SIOCGIWTXPOW */ - NULL, /* SIOCSIWRETRY */ - NULL, /* SIOCGIWRETRY */ - /*bummer ! Why those are only at the end ??? */ - wavelan_set_encode, /* SIOCSIWENCODE */ - wavelan_get_encode, /* SIOCGIWENCODE */ -}; - -static const iw_handler wavelan_private_handler[] = -{ - wavelan_set_qthr, /* SIOCIWFIRSTPRIV */ - wavelan_get_qthr, /* SIOCIWFIRSTPRIV + 1 */ -#ifdef HISTOGRAM - wavelan_set_histo, /* SIOCIWFIRSTPRIV + 2 */ - wavelan_get_histo, /* SIOCIWFIRSTPRIV + 3 */ -#endif /* HISTOGRAM */ -}; - -static const struct iw_priv_args wavelan_private_args[] = { -/*{ cmd, set_args, get_args, name } */ - { SIOCSIPQTHR, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setqualthr" }, - { SIOCGIPQTHR, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getqualthr" }, - { SIOCSIPHISTO, IW_PRIV_TYPE_BYTE | 16, 0, "sethisto" }, - { SIOCGIPHISTO, 0, IW_PRIV_TYPE_INT | 16, "gethisto" }, -}; - -static const struct iw_handler_def wavelan_handler_def = -{ - .num_standard = ARRAY_SIZE(wavelan_handler), - .num_private = ARRAY_SIZE(wavelan_private_handler), - .num_private_args = ARRAY_SIZE(wavelan_private_args), - .standard = wavelan_handler, - .private = wavelan_private_handler, - .private_args = wavelan_private_args, - .get_wireless_stats = wavelan_get_wireless_stats, -}; - -/*------------------------------------------------------------------*/ -/* - * Get wireless statistics. - * Called by /proc/net/wireless - */ -static iw_stats *wavelan_get_wireless_stats(struct net_device *dev) -{ - unsigned long ioaddr = dev->base_addr; - net_local *lp = netdev_priv(dev); - mmr_t m; - iw_stats *wstats; - unsigned long flags; - -#ifdef DEBUG_IOCTL_TRACE - printk(KERN_DEBUG "%s: ->wavelan_get_wireless_stats()\n", - dev->name); -#endif - - /* Check */ - if (lp == (net_local *) NULL) - return (iw_stats *) NULL; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - wstats = &lp->wstats; - - /* Get data from the mmc. */ - mmc_out(ioaddr, mmwoff(0, mmw_freeze), 1); - - mmc_read(ioaddr, mmroff(0, mmr_dce_status), &m.mmr_dce_status, 1); - mmc_read(ioaddr, mmroff(0, mmr_wrong_nwid_l), &m.mmr_wrong_nwid_l, - 2); - mmc_read(ioaddr, mmroff(0, mmr_thr_pre_set), &m.mmr_thr_pre_set, - 4); - - mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0); - - /* Copy data to wireless stuff. */ - wstats->status = m.mmr_dce_status & MMR_DCE_STATUS; - wstats->qual.qual = m.mmr_sgnl_qual & MMR_SGNL_QUAL; - wstats->qual.level = m.mmr_signal_lvl & MMR_SIGNAL_LVL; - wstats->qual.noise = m.mmr_silence_lvl & MMR_SILENCE_LVL; - wstats->qual.updated = (((m. mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) >> 7) - | ((m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) >> 6) - | ((m.mmr_silence_lvl & MMR_SILENCE_LVL_VALID) >> 5)); - wstats->discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l; - wstats->discard.code = 0L; - wstats->discard.misc = 0L; - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - -#ifdef DEBUG_IOCTL_TRACE - printk(KERN_DEBUG "%s: <-wavelan_get_wireless_stats()\n", - dev->name); -#endif - return &lp->wstats; -} - -/************************* PACKET RECEPTION *************************/ -/* - * This part deals with receiving the packets. - * The interrupt handler gets an interrupt when a packet has been - * successfully received and calls this part. - */ - -/*------------------------------------------------------------------*/ -/* - * This routine does the actual copying of data (including the Ethernet - * header structure) from the WaveLAN card to an sk_buff chain that - * will be passed up to the network interface layer. NOTE: we - * currently don't handle trailer protocols (neither does the rest of - * the network interface), so if that is needed, it will (at least in - * part) be added here. The contents of the receive ring buffer are - * copied to a message chain that is then passed to the kernel. - * - * Note: if any errors occur, the packet is "dropped on the floor". - * (called by wv_packet_rcv()) - */ -static void -wv_packet_read(struct net_device *dev, u16 buf_off, int sksize) -{ - net_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - struct sk_buff *skb; - -#ifdef DEBUG_RX_TRACE - printk(KERN_DEBUG "%s: ->wv_packet_read(0x%X, %d)\n", - dev->name, buf_off, sksize); -#endif - - /* Allocate buffer for the data */ - if ((skb = dev_alloc_skb(sksize)) == (struct sk_buff *) NULL) { -#ifdef DEBUG_RX_ERROR - printk(KERN_INFO - "%s: wv_packet_read(): could not alloc_skb(%d, GFP_ATOMIC).\n", - dev->name, sksize); -#endif - dev->stats.rx_dropped++; - return; - } - - /* Copy the packet to the buffer. */ - obram_read(ioaddr, buf_off, skb_put(skb, sksize), sksize); - skb->protocol = eth_type_trans(skb, dev); - -#ifdef DEBUG_RX_INFO - wv_packet_info(skb_mac_header(skb), sksize, dev->name, - "wv_packet_read"); -#endif /* DEBUG_RX_INFO */ - - /* Statistics-gathering and associated stuff. - * It seem a bit messy with all the define, but it's really - * simple... */ - if ( -#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */ - (lp->spy_data.spy_number > 0) || -#endif /* IW_WIRELESS_SPY */ -#ifdef HISTOGRAM - (lp->his_number > 0) || -#endif /* HISTOGRAM */ - 0) { - u8 stats[3]; /* signal level, noise level, signal quality */ - - /* Read signal level, silence level and signal quality bytes */ - /* Note: in the PCMCIA hardware, these are part of the frame. - * It seems that for the ISA hardware, it's nowhere to be - * found in the frame, so I'm obliged to do this (it has a - * side effect on /proc/net/wireless). - * Any ideas? - */ - mmc_out(ioaddr, mmwoff(0, mmw_freeze), 1); - mmc_read(ioaddr, mmroff(0, mmr_signal_lvl), stats, 3); - mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0); - -#ifdef DEBUG_RX_INFO - printk(KERN_DEBUG - "%s: wv_packet_read(): Signal level %d/63, Silence level %d/63, signal quality %d/16\n", - dev->name, stats[0] & 0x3F, stats[1] & 0x3F, - stats[2] & 0x0F); -#endif - - /* Spying stuff */ -#ifdef IW_WIRELESS_SPY - wl_spy_gather(dev, skb_mac_header(skb) + WAVELAN_ADDR_SIZE, - stats); -#endif /* IW_WIRELESS_SPY */ -#ifdef HISTOGRAM - wl_his_gather(dev, stats); -#endif /* HISTOGRAM */ - } - - /* - * Hand the packet to the network module. - */ - netif_rx(skb); - - /* Keep statistics up to date */ - dev->stats.rx_packets++; - dev->stats.rx_bytes += sksize; - -#ifdef DEBUG_RX_TRACE - printk(KERN_DEBUG "%s: <-wv_packet_read()\n", dev->name); -#endif -} - -/*------------------------------------------------------------------*/ -/* - * Transfer as many packets as we can - * from the device RAM. - * (called in wavelan_interrupt()). - * Note : the spinlock is already grabbed for us. - */ -static void wv_receive(struct net_device *dev) -{ - unsigned long ioaddr = dev->base_addr; - net_local *lp = netdev_priv(dev); - fd_t fd; - rbd_t rbd; - int nreaped = 0; - -#ifdef DEBUG_RX_TRACE - printk(KERN_DEBUG "%s: ->wv_receive()\n", dev->name); -#endif - - /* Loop on each received packet. */ - for (;;) { - obram_read(ioaddr, lp->rx_head, (unsigned char *) &fd, - sizeof(fd)); - - /* Note about the status : - * It start up to be 0 (the value we set). Then, when the RU - * grab the buffer to prepare for reception, it sets the - * FD_STATUS_B flag. When the RU has finished receiving the - * frame, it clears FD_STATUS_B, set FD_STATUS_C to indicate - * completion and set the other flags to indicate the eventual - * errors. FD_STATUS_OK indicates that the reception was OK. - */ - - /* If the current frame is not complete, we have reached the end. */ - if ((fd.fd_status & FD_STATUS_C) != FD_STATUS_C) - break; /* This is how we exit the loop. */ - - nreaped++; - - /* Check whether frame was correctly received. */ - if ((fd.fd_status & FD_STATUS_OK) == FD_STATUS_OK) { - /* Does the frame contain a pointer to the data? Let's check. */ - if (fd.fd_rbd_offset != I82586NULL) { - /* Read the receive buffer descriptor */ - obram_read(ioaddr, fd.fd_rbd_offset, - (unsigned char *) &rbd, - sizeof(rbd)); - -#ifdef DEBUG_RX_ERROR - if ((rbd.rbd_status & RBD_STATUS_EOF) != - RBD_STATUS_EOF) printk(KERN_INFO - "%s: wv_receive(): missing EOF flag.\n", - dev->name); - - if ((rbd.rbd_status & RBD_STATUS_F) != - RBD_STATUS_F) printk(KERN_INFO - "%s: wv_receive(): missing F flag.\n", - dev->name); -#endif /* DEBUG_RX_ERROR */ - - /* Read the packet and transmit to Linux */ - wv_packet_read(dev, rbd.rbd_bufl, - rbd. - rbd_status & - RBD_STATUS_ACNT); - } -#ifdef DEBUG_RX_ERROR - else /* if frame has no data */ - printk(KERN_INFO - "%s: wv_receive(): frame has no data.\n", - dev->name); -#endif - } else { /* If reception was no successful */ - - dev->stats.rx_errors++; - -#ifdef DEBUG_RX_INFO - printk(KERN_DEBUG - "%s: wv_receive(): frame not received successfully (%X).\n", - dev->name, fd.fd_status); -#endif - -#ifdef DEBUG_RX_ERROR - if ((fd.fd_status & FD_STATUS_S6) != 0) - printk(KERN_INFO - "%s: wv_receive(): no EOF flag.\n", - dev->name); -#endif - - if ((fd.fd_status & FD_STATUS_S7) != 0) { - dev->stats.rx_length_errors++; -#ifdef DEBUG_RX_FAIL - printk(KERN_DEBUG - "%s: wv_receive(): frame too short.\n", - dev->name); -#endif - } - - if ((fd.fd_status & FD_STATUS_S8) != 0) { - dev->stats.rx_over_errors++; -#ifdef DEBUG_RX_FAIL - printk(KERN_DEBUG - "%s: wv_receive(): rx DMA overrun.\n", - dev->name); -#endif - } - - if ((fd.fd_status & FD_STATUS_S9) != 0) { - dev->stats.rx_fifo_errors++; -#ifdef DEBUG_RX_FAIL - printk(KERN_DEBUG - "%s: wv_receive(): ran out of resources.\n", - dev->name); -#endif - } - - if ((fd.fd_status & FD_STATUS_S10) != 0) { - dev->stats.rx_frame_errors++; -#ifdef DEBUG_RX_FAIL - printk(KERN_DEBUG - "%s: wv_receive(): alignment error.\n", - dev->name); -#endif - } - - if ((fd.fd_status & FD_STATUS_S11) != 0) { - dev->stats.rx_crc_errors++; -#ifdef DEBUG_RX_FAIL - printk(KERN_DEBUG - "%s: wv_receive(): CRC error.\n", - dev->name); -#endif - } - } - - fd.fd_status = 0; - obram_write(ioaddr, fdoff(lp->rx_head, fd_status), - (unsigned char *) &fd.fd_status, - sizeof(fd.fd_status)); - - fd.fd_command = FD_COMMAND_EL; - obram_write(ioaddr, fdoff(lp->rx_head, fd_command), - (unsigned char *) &fd.fd_command, - sizeof(fd.fd_command)); - - fd.fd_command = 0; - obram_write(ioaddr, fdoff(lp->rx_last, fd_command), - (unsigned char *) &fd.fd_command, - sizeof(fd.fd_command)); - - lp->rx_last = lp->rx_head; - lp->rx_head = fd.fd_link_offset; - } /* for(;;) -> loop on all frames */ - -#ifdef DEBUG_RX_INFO - if (nreaped > 1) - printk(KERN_DEBUG "%s: wv_receive(): reaped %d\n", - dev->name, nreaped); -#endif -#ifdef DEBUG_RX_TRACE - printk(KERN_DEBUG "%s: <-wv_receive()\n", dev->name); -#endif -} - -/*********************** PACKET TRANSMISSION ***********************/ -/* - * This part deals with sending packets through the WaveLAN. - * - */ - -/*------------------------------------------------------------------*/ -/* - * This routine fills in the appropriate registers and memory - * locations on the WaveLAN card and starts the card off on - * the transmit. - * - * The principle: - * Each block contains a transmit command, a NOP command, - * a transmit block descriptor and a buffer. - * The CU read the transmit block which point to the tbd, - * read the tbd and the content of the buffer. - * When it has finish with it, it goes to the next command - * which in our case is the NOP. The NOP points on itself, - * so the CU stop here. - * When we add the next block, we modify the previous nop - * to make it point on the new tx command. - * Simple, isn't it ? - * - * (called in wavelan_packet_xmit()) - */ -static int wv_packet_write(struct net_device *dev, void *buf, short length) -{ - net_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - unsigned short txblock; - unsigned short txpred; - unsigned short tx_addr; - unsigned short nop_addr; - unsigned short tbd_addr; - unsigned short buf_addr; - ac_tx_t tx; - ac_nop_t nop; - tbd_t tbd; - int clen = length; - unsigned long flags; - -#ifdef DEBUG_TX_TRACE - printk(KERN_DEBUG "%s: ->wv_packet_write(%d)\n", dev->name, - length); -#endif - - spin_lock_irqsave(&lp->spinlock, flags); - - /* Check nothing bad has happened */ - if (lp->tx_n_in_use == (NTXBLOCKS - 1)) { -#ifdef DEBUG_TX_ERROR - printk(KERN_INFO "%s: wv_packet_write(): Tx queue full.\n", - dev->name); -#endif - spin_unlock_irqrestore(&lp->spinlock, flags); - return 1; - } - - /* Calculate addresses of next block and previous block. */ - txblock = lp->tx_first_free; - txpred = txblock - TXBLOCKZ; - if (txpred < OFFSET_CU) - txpred += NTXBLOCKS * TXBLOCKZ; - lp->tx_first_free += TXBLOCKZ; - if (lp->tx_first_free >= OFFSET_CU + NTXBLOCKS * TXBLOCKZ) - lp->tx_first_free -= NTXBLOCKS * TXBLOCKZ; - - lp->tx_n_in_use++; - - /* Calculate addresses of the different parts of the block. */ - tx_addr = txblock; - nop_addr = tx_addr + sizeof(tx); - tbd_addr = nop_addr + sizeof(nop); - buf_addr = tbd_addr + sizeof(tbd); - - /* - * Transmit command - */ - tx.tx_h.ac_status = 0; - obram_write(ioaddr, toff(ac_tx_t, tx_addr, tx_h.ac_status), - (unsigned char *) &tx.tx_h.ac_status, - sizeof(tx.tx_h.ac_status)); - - /* - * NOP command - */ - nop.nop_h.ac_status = 0; - obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_status), - (unsigned char *) &nop.nop_h.ac_status, - sizeof(nop.nop_h.ac_status)); - nop.nop_h.ac_link = nop_addr; - obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_link), - (unsigned char *) &nop.nop_h.ac_link, - sizeof(nop.nop_h.ac_link)); - - /* - * Transmit buffer descriptor - */ - tbd.tbd_status = TBD_STATUS_EOF | (TBD_STATUS_ACNT & clen); - tbd.tbd_next_bd_offset = I82586NULL; - tbd.tbd_bufl = buf_addr; - tbd.tbd_bufh = 0; - obram_write(ioaddr, tbd_addr, (unsigned char *) &tbd, sizeof(tbd)); - - /* - * Data - */ - obram_write(ioaddr, buf_addr, buf, length); - - /* - * Overwrite the predecessor NOP link - * so that it points to this txblock. - */ - nop_addr = txpred + sizeof(tx); - nop.nop_h.ac_status = 0; - obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_status), - (unsigned char *) &nop.nop_h.ac_status, - sizeof(nop.nop_h.ac_status)); - nop.nop_h.ac_link = txblock; - obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_link), - (unsigned char *) &nop.nop_h.ac_link, - sizeof(nop.nop_h.ac_link)); - - /* Make sure the watchdog will keep quiet for a while */ - dev->trans_start = jiffies; - - /* Keep stats up to date. */ - dev->stats.tx_bytes += length; - - if (lp->tx_first_in_use == I82586NULL) - lp->tx_first_in_use = txblock; - - if (lp->tx_n_in_use < NTXBLOCKS - 1) - netif_wake_queue(dev); - - spin_unlock_irqrestore(&lp->spinlock, flags); - -#ifdef DEBUG_TX_INFO - wv_packet_info((u8 *) buf, length, dev->name, - "wv_packet_write"); -#endif /* DEBUG_TX_INFO */ - -#ifdef DEBUG_TX_TRACE - printk(KERN_DEBUG "%s: <-wv_packet_write()\n", dev->name); -#endif - - return 0; -} - -/*------------------------------------------------------------------*/ -/* - * This routine is called when we want to send a packet (NET3 callback) - * In this routine, we check if the harware is ready to accept - * the packet. We also prevent reentrance. Then we call the function - * to send the packet. - */ -static netdev_tx_t wavelan_packet_xmit(struct sk_buff *skb, - struct net_device *dev) -{ - net_local *lp = netdev_priv(dev); - unsigned long flags; - char data[ETH_ZLEN]; - -#ifdef DEBUG_TX_TRACE - printk(KERN_DEBUG "%s: ->wavelan_packet_xmit(0x%X)\n", dev->name, - (unsigned) skb); -#endif - - /* - *block a timer-based transmit from overlapping. - * In other words, prevent reentering this routine. - */ - netif_stop_queue(dev); - - /* If somebody has asked to reconfigure the controller, - * we can do it now. - */ - if (lp->reconfig_82586) { - spin_lock_irqsave(&lp->spinlock, flags); - wv_82586_config(dev); - spin_unlock_irqrestore(&lp->spinlock, flags); - /* Check that we can continue */ - if (lp->tx_n_in_use == (NTXBLOCKS - 1)) - return NETDEV_TX_BUSY; - } - - /* Do we need some padding? */ - /* Note : on wireless the propagation time is in the order of 1us, - * and we don't have the Ethernet specific requirement of beeing - * able to detect collisions, therefore in theory we don't really - * need to pad. Jean II */ - if (skb->len < ETH_ZLEN) { - memset(data, 0, ETH_ZLEN); - skb_copy_from_linear_data(skb, data, skb->len); - /* Write packet on the card */ - if(wv_packet_write(dev, data, ETH_ZLEN)) - return NETDEV_TX_BUSY; /* We failed */ - } - else if(wv_packet_write(dev, skb->data, skb->len)) - return NETDEV_TX_BUSY; /* We failed */ - - - dev_kfree_skb(skb); - -#ifdef DEBUG_TX_TRACE - printk(KERN_DEBUG "%s: <-wavelan_packet_xmit()\n", dev->name); -#endif - return NETDEV_TX_OK; -} - -/*********************** HARDWARE CONFIGURATION ***********************/ -/* - * This part does the real job of starting and configuring the hardware. - */ - -/*--------------------------------------------------------------------*/ -/* - * Routine to initialize the Modem Management Controller. - * (called by wv_hw_reset()) - */ -static int wv_mmc_init(struct net_device *dev) -{ - unsigned long ioaddr = dev->base_addr; - net_local *lp = netdev_priv(dev); - psa_t psa; - mmw_t m; - int configured; - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: ->wv_mmc_init()\n", dev->name); -#endif - - /* Read the parameter storage area. */ - psa_read(ioaddr, lp->hacr, 0, (unsigned char *) &psa, sizeof(psa)); - -#ifdef USE_PSA_CONFIG - configured = psa.psa_conf_status & 1; -#else - configured = 0; -#endif - - /* Is the PSA is not configured */ - if (!configured) { - /* User will be able to configure NWID later (with iwconfig). */ - psa.psa_nwid[0] = 0; - psa.psa_nwid[1] = 0; - - /* no NWID checking since NWID is not set */ - psa.psa_nwid_select = 0; - - /* Disable encryption */ - psa.psa_encryption_select = 0; - - /* Set to standard values: - * 0x04 for AT, - * 0x01 for MCA, - * 0x04 for PCMCIA and 2.00 card (AT&T 407-024689/E document) - */ - if (psa.psa_comp_number & 1) - psa.psa_thr_pre_set = 0x01; - else - psa.psa_thr_pre_set = 0x04; - psa.psa_quality_thr = 0x03; - - /* It is configured */ - psa.psa_conf_status |= 1; - -#ifdef USE_PSA_CONFIG - /* Write the psa. */ - psa_write(ioaddr, lp->hacr, - (char *) psa.psa_nwid - (char *) &psa, - (unsigned char *) psa.psa_nwid, 4); - psa_write(ioaddr, lp->hacr, - (char *) &psa.psa_thr_pre_set - (char *) &psa, - (unsigned char *) &psa.psa_thr_pre_set, 1); - psa_write(ioaddr, lp->hacr, - (char *) &psa.psa_quality_thr - (char *) &psa, - (unsigned char *) &psa.psa_quality_thr, 1); - psa_write(ioaddr, lp->hacr, - (char *) &psa.psa_conf_status - (char *) &psa, - (unsigned char *) &psa.psa_conf_status, 1); - /* update the Wavelan checksum */ - update_psa_checksum(dev, ioaddr, lp->hacr); -#endif - } - - /* Zero the mmc structure. */ - memset(&m, 0x00, sizeof(m)); - - /* Copy PSA info to the mmc. */ - m.mmw_netw_id_l = psa.psa_nwid[1]; - m.mmw_netw_id_h = psa.psa_nwid[0]; - - if (psa.psa_nwid_select & 1) - m.mmw_loopt_sel = 0x00; - else - m.mmw_loopt_sel = MMW_LOOPT_SEL_DIS_NWID; - - memcpy(&m.mmw_encr_key, &psa.psa_encryption_key, - sizeof(m.mmw_encr_key)); - - if (psa.psa_encryption_select) - m.mmw_encr_enable = - MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE; - else - m.mmw_encr_enable = 0; - - m.mmw_thr_pre_set = psa.psa_thr_pre_set & 0x3F; - m.mmw_quality_thr = psa.psa_quality_thr & 0x0F; - - /* - * Set default modem control parameters. - * See NCR document 407-0024326 Rev. A. - */ - m.mmw_jabber_enable = 0x01; - m.mmw_freeze = 0; - m.mmw_anten_sel = MMW_ANTEN_SEL_ALG_EN; - m.mmw_ifs = 0x20; - m.mmw_mod_delay = 0x04; - m.mmw_jam_time = 0x38; - - m.mmw_des_io_invert = 0; - m.mmw_decay_prm = 0; - m.mmw_decay_updat_prm = 0; - - /* Write all info to MMC. */ - mmc_write(ioaddr, 0, (u8 *) & m, sizeof(m)); - - /* The following code starts the modem of the 2.00 frequency - * selectable cards at power on. It's not strictly needed for the - * following boots. - * The original patch was by Joe Finney for the PCMCIA driver, but - * I've cleaned it up a bit and added documentation. - * Thanks to Loeke Brederveld from Lucent for the info. - */ - - /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable) - * Does it work for everybody, especially old cards? */ - /* Note: WFREQSEL verifies that it is able to read a sensible - * frequency from EEPROM (address 0x00) and that MMR_FEE_STATUS_ID - * is 0xA (Xilinx version) or 0xB (Ariadne version). - * My test is more crude but does work. */ - if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) & - (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) { - /* We must download the frequency parameters to the - * synthesizers (from the EEPROM - area 1) - * Note: as the EEPROM is automatically decremented, we set the end - * if the area... */ - m.mmw_fee_addr = 0x0F; - m.mmw_fee_ctrl = MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD; - mmc_write(ioaddr, (char *) &m.mmw_fee_ctrl - (char *) &m, - (unsigned char *) &m.mmw_fee_ctrl, 2); - - /* Wait until the download is finished. */ - fee_wait(ioaddr, 100, 100); - -#ifdef DEBUG_CONFIG_INFO - /* The frequency was in the last word downloaded. */ - mmc_read(ioaddr, (char *) &m.mmw_fee_data_l - (char *) &m, - (unsigned char *) &m.mmw_fee_data_l, 2); - - /* Print some info for the user. */ - printk(KERN_DEBUG - "%s: WaveLAN 2.00 recognised (frequency select). Current frequency = %ld\n", - dev->name, - ((m. - mmw_fee_data_h << 4) | (m.mmw_fee_data_l >> 4)) * - 5 / 2 + 24000L); -#endif - - /* We must now download the power adjust value (gain) to - * the synthesizers (from the EEPROM - area 7 - DAC). */ - m.mmw_fee_addr = 0x61; - m.mmw_fee_ctrl = MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD; - mmc_write(ioaddr, (char *) &m.mmw_fee_ctrl - (char *) &m, - (unsigned char *) &m.mmw_fee_ctrl, 2); - - /* Wait until the download is finished. */ - } - /* if 2.00 card */ -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: <-wv_mmc_init()\n", dev->name); -#endif - return 0; -} - -/*------------------------------------------------------------------*/ -/* - * Construct the fd and rbd structures. - * Start the receive unit. - * (called by wv_hw_reset()) - */ -static int wv_ru_start(struct net_device *dev) -{ - net_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - u16 scb_cs; - fd_t fd; - rbd_t rbd; - u16 rx; - u16 rx_next; - int i; - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: ->wv_ru_start()\n", dev->name); -#endif - - obram_read(ioaddr, scboff(OFFSET_SCB, scb_status), - (unsigned char *) &scb_cs, sizeof(scb_cs)); - if ((scb_cs & SCB_ST_RUS) == SCB_ST_RUS_RDY) - return 0; - - lp->rx_head = OFFSET_RU; - - for (i = 0, rx = lp->rx_head; i < NRXBLOCKS; i++, rx = rx_next) { - rx_next = - (i == NRXBLOCKS - 1) ? lp->rx_head : rx + RXBLOCKZ; - - fd.fd_status = 0; - fd.fd_command = (i == NRXBLOCKS - 1) ? FD_COMMAND_EL : 0; - fd.fd_link_offset = rx_next; - fd.fd_rbd_offset = rx + sizeof(fd); - obram_write(ioaddr, rx, (unsigned char *) &fd, sizeof(fd)); - - rbd.rbd_status = 0; - rbd.rbd_next_rbd_offset = I82586NULL; - rbd.rbd_bufl = rx + sizeof(fd) + sizeof(rbd); - rbd.rbd_bufh = 0; - rbd.rbd_el_size = RBD_EL | (RBD_SIZE & MAXDATAZ); - obram_write(ioaddr, rx + sizeof(fd), - (unsigned char *) &rbd, sizeof(rbd)); - - lp->rx_last = rx; - } - - obram_write(ioaddr, scboff(OFFSET_SCB, scb_rfa_offset), - (unsigned char *) &lp->rx_head, sizeof(lp->rx_head)); - - scb_cs = SCB_CMD_RUC_GO; - obram_write(ioaddr, scboff(OFFSET_SCB, scb_command), - (unsigned char *) &scb_cs, sizeof(scb_cs)); - - set_chan_attn(ioaddr, lp->hacr); - - for (i = 1000; i > 0; i--) { - obram_read(ioaddr, scboff(OFFSET_SCB, scb_command), - (unsigned char *) &scb_cs, sizeof(scb_cs)); - if (scb_cs == 0) - break; - - udelay(10); - } - - if (i <= 0) { -#ifdef DEBUG_CONFIG_ERROR - printk(KERN_INFO - "%s: wavelan_ru_start(): board not accepting command.\n", - dev->name); -#endif - return -1; - } -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: <-wv_ru_start()\n", dev->name); -#endif - return 0; -} - -/*------------------------------------------------------------------*/ -/* - * Initialise the transmit blocks. - * Start the command unit executing the NOP - * self-loop of the first transmit block. - * - * Here we create the list of send buffers used to transmit packets - *between the PC and the command unit. For each buffer, we create a - *buffer descriptor (pointing on the buffer), a transmit command - * (pointing to the buffer descriptor) and a NOP command. - * The transmit command is linked to the NOP, and the NOP to itself. - * When we will have finished executing the transmit command, we will - * then loop on the NOP. By releasing the NOP link to a new command, - * we may send another buffer. - * - * (called by wv_hw_reset()) - */ -static int wv_cu_start(struct net_device *dev) -{ - net_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - int i; - u16 txblock; - u16 first_nop; - u16 scb_cs; - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: ->wv_cu_start()\n", dev->name); -#endif - - lp->tx_first_free = OFFSET_CU; - lp->tx_first_in_use = I82586NULL; - - for (i = 0, txblock = OFFSET_CU; - i < NTXBLOCKS; i++, txblock += TXBLOCKZ) { - ac_tx_t tx; - ac_nop_t nop; - tbd_t tbd; - unsigned short tx_addr; - unsigned short nop_addr; - unsigned short tbd_addr; - unsigned short buf_addr; - - tx_addr = txblock; - nop_addr = tx_addr + sizeof(tx); - tbd_addr = nop_addr + sizeof(nop); - buf_addr = tbd_addr + sizeof(tbd); - - tx.tx_h.ac_status = 0; - tx.tx_h.ac_command = acmd_transmit | AC_CFLD_I; - tx.tx_h.ac_link = nop_addr; - tx.tx_tbd_offset = tbd_addr; - obram_write(ioaddr, tx_addr, (unsigned char *) &tx, - sizeof(tx)); - - nop.nop_h.ac_status = 0; - nop.nop_h.ac_command = acmd_nop; - nop.nop_h.ac_link = nop_addr; - obram_write(ioaddr, nop_addr, (unsigned char *) &nop, - sizeof(nop)); - - tbd.tbd_status = TBD_STATUS_EOF; - tbd.tbd_next_bd_offset = I82586NULL; - tbd.tbd_bufl = buf_addr; - tbd.tbd_bufh = 0; - obram_write(ioaddr, tbd_addr, (unsigned char *) &tbd, - sizeof(tbd)); - } - - first_nop = - OFFSET_CU + (NTXBLOCKS - 1) * TXBLOCKZ + sizeof(ac_tx_t); - obram_write(ioaddr, scboff(OFFSET_SCB, scb_cbl_offset), - (unsigned char *) &first_nop, sizeof(first_nop)); - - scb_cs = SCB_CMD_CUC_GO; - obram_write(ioaddr, scboff(OFFSET_SCB, scb_command), - (unsigned char *) &scb_cs, sizeof(scb_cs)); - - set_chan_attn(ioaddr, lp->hacr); - - for (i = 1000; i > 0; i--) { - obram_read(ioaddr, scboff(OFFSET_SCB, scb_command), - (unsigned char *) &scb_cs, sizeof(scb_cs)); - if (scb_cs == 0) - break; - - udelay(10); - } - - if (i <= 0) { -#ifdef DEBUG_CONFIG_ERROR - printk(KERN_INFO - "%s: wavelan_cu_start(): board not accepting command.\n", - dev->name); -#endif - return -1; - } - - lp->tx_n_in_use = 0; - netif_start_queue(dev); -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: <-wv_cu_start()\n", dev->name); -#endif - return 0; -} - -/*------------------------------------------------------------------*/ -/* - * This routine does a standard configuration of the WaveLAN - * controller (i82586). - * - * It initialises the scp, iscp and scb structure - * The first two are just pointers to the next. - * The last one is used for basic configuration and for basic - * communication (interrupt status). - * - * (called by wv_hw_reset()) - */ -static int wv_82586_start(struct net_device *dev) -{ - net_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - scp_t scp; /* system configuration pointer */ - iscp_t iscp; /* intermediate scp */ - scb_t scb; /* system control block */ - ach_t cb; /* Action command header */ - u8 zeroes[512]; - int i; - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: ->wv_82586_start()\n", dev->name); -#endif - - /* - * Clear the onboard RAM. - */ - memset(&zeroes[0], 0x00, sizeof(zeroes)); - for (i = 0; i < I82586_MEMZ; i += sizeof(zeroes)) - obram_write(ioaddr, i, &zeroes[0], sizeof(zeroes)); - - /* - * Construct the command unit structures: - * scp, iscp, scb, cb. - */ - memset(&scp, 0x00, sizeof(scp)); - scp.scp_sysbus = SCP_SY_16BBUS; - scp.scp_iscpl = OFFSET_ISCP; - obram_write(ioaddr, OFFSET_SCP, (unsigned char *) &scp, - sizeof(scp)); - - memset(&iscp, 0x00, sizeof(iscp)); - iscp.iscp_busy = 1; - iscp.iscp_offset = OFFSET_SCB; - obram_write(ioaddr, OFFSET_ISCP, (unsigned char *) &iscp, - sizeof(iscp)); - - /* Our first command is to reset the i82586. */ - memset(&scb, 0x00, sizeof(scb)); - scb.scb_command = SCB_CMD_RESET; - scb.scb_cbl_offset = OFFSET_CU; - scb.scb_rfa_offset = OFFSET_RU; - obram_write(ioaddr, OFFSET_SCB, (unsigned char *) &scb, - sizeof(scb)); - - set_chan_attn(ioaddr, lp->hacr); - - /* Wait for command to finish. */ - for (i = 1000; i > 0; i--) { - obram_read(ioaddr, OFFSET_ISCP, (unsigned char *) &iscp, - sizeof(iscp)); - - if (iscp.iscp_busy == (unsigned short) 0) - break; - - udelay(10); - } - - if (i <= 0) { -#ifdef DEBUG_CONFIG_ERROR - printk(KERN_INFO - "%s: wv_82586_start(): iscp_busy timeout.\n", - dev->name); -#endif - return -1; - } - - /* Check command completion. */ - for (i = 15; i > 0; i--) { - obram_read(ioaddr, OFFSET_SCB, (unsigned char *) &scb, - sizeof(scb)); - - if (scb.scb_status == (SCB_ST_CX | SCB_ST_CNA)) - break; - - udelay(10); - } - - if (i <= 0) { -#ifdef DEBUG_CONFIG_ERROR - printk(KERN_INFO - "%s: wv_82586_start(): status: expected 0x%02x, got 0x%02x.\n", - dev->name, SCB_ST_CX | SCB_ST_CNA, scb.scb_status); -#endif - return -1; - } - - wv_ack(dev); - - /* Set the action command header. */ - memset(&cb, 0x00, sizeof(cb)); - cb.ac_command = AC_CFLD_EL | (AC_CFLD_CMD & acmd_diagnose); - cb.ac_link = OFFSET_CU; - obram_write(ioaddr, OFFSET_CU, (unsigned char *) &cb, sizeof(cb)); - - if (wv_synchronous_cmd(dev, "diag()") == -1) - return -1; - - obram_read(ioaddr, OFFSET_CU, (unsigned char *) &cb, sizeof(cb)); - if (cb.ac_status & AC_SFLD_FAIL) { -#ifdef DEBUG_CONFIG_ERROR - printk(KERN_INFO - "%s: wv_82586_start(): i82586 Self Test failed.\n", - dev->name); -#endif - return -1; - } -#ifdef DEBUG_I82586_SHOW - wv_scb_show(ioaddr); -#endif - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: <-wv_82586_start()\n", dev->name); -#endif - return 0; -} - -/*------------------------------------------------------------------*/ -/* - * This routine does a standard configuration of the WaveLAN - * controller (i82586). - * - * This routine is a violent hack. We use the first free transmit block - * to make our configuration. In the buffer area, we create the three - * configuration commands (linked). We make the previous NOP point to - * the beginning of the buffer instead of the tx command. After, we go - * as usual to the NOP command. - * Note that only the last command (mc_set) will generate an interrupt. - * - * (called by wv_hw_reset(), wv_82586_reconfig(), wavelan_packet_xmit()) - */ -static void wv_82586_config(struct net_device *dev) -{ - net_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - unsigned short txblock; - unsigned short txpred; - unsigned short tx_addr; - unsigned short nop_addr; - unsigned short tbd_addr; - unsigned short cfg_addr; - unsigned short ias_addr; - unsigned short mcs_addr; - ac_tx_t tx; - ac_nop_t nop; - ac_cfg_t cfg; /* Configure action */ - ac_ias_t ias; /* IA-setup action */ - ac_mcs_t mcs; /* Multicast setup */ - struct dev_mc_list *dmi; - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: ->wv_82586_config()\n", dev->name); -#endif - - /* Check nothing bad has happened */ - if (lp->tx_n_in_use == (NTXBLOCKS - 1)) { -#ifdef DEBUG_CONFIG_ERROR - printk(KERN_INFO "%s: wv_82586_config(): Tx queue full.\n", - dev->name); -#endif - return; - } - - /* Calculate addresses of next block and previous block. */ - txblock = lp->tx_first_free; - txpred = txblock - TXBLOCKZ; - if (txpred < OFFSET_CU) - txpred += NTXBLOCKS * TXBLOCKZ; - lp->tx_first_free += TXBLOCKZ; - if (lp->tx_first_free >= OFFSET_CU + NTXBLOCKS * TXBLOCKZ) - lp->tx_first_free -= NTXBLOCKS * TXBLOCKZ; - - lp->tx_n_in_use++; - - /* Calculate addresses of the different parts of the block. */ - tx_addr = txblock; - nop_addr = tx_addr + sizeof(tx); - tbd_addr = nop_addr + sizeof(nop); - cfg_addr = tbd_addr + sizeof(tbd_t); /*beginning of the buffer */ - ias_addr = cfg_addr + sizeof(cfg); - mcs_addr = ias_addr + sizeof(ias); - - /* - * Transmit command - */ - tx.tx_h.ac_status = 0xFFFF; /* Fake completion value */ - obram_write(ioaddr, toff(ac_tx_t, tx_addr, tx_h.ac_status), - (unsigned char *) &tx.tx_h.ac_status, - sizeof(tx.tx_h.ac_status)); - - /* - * NOP command - */ - nop.nop_h.ac_status = 0; - obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_status), - (unsigned char *) &nop.nop_h.ac_status, - sizeof(nop.nop_h.ac_status)); - nop.nop_h.ac_link = nop_addr; - obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_link), - (unsigned char *) &nop.nop_h.ac_link, - sizeof(nop.nop_h.ac_link)); - - /* Create a configure action. */ - memset(&cfg, 0x00, sizeof(cfg)); - - /* - * For Linux we invert AC_CFG_ALOC() so as to conform - * to the way that net packets reach us from above. - * (See also ac_tx_t.) - * - * Updated from Wavelan Manual WCIN085B - */ - cfg.cfg_byte_cnt = - AC_CFG_BYTE_CNT(sizeof(ac_cfg_t) - sizeof(ach_t)); - cfg.cfg_fifolim = AC_CFG_FIFOLIM(4); - cfg.cfg_byte8 = AC_CFG_SAV_BF(1) | AC_CFG_SRDY(0); - cfg.cfg_byte9 = AC_CFG_ELPBCK(0) | - AC_CFG_ILPBCK(0) | - AC_CFG_PRELEN(AC_CFG_PLEN_2) | - AC_CFG_ALOC(1) | AC_CFG_ADDRLEN(WAVELAN_ADDR_SIZE); - cfg.cfg_byte10 = AC_CFG_BOFMET(1) | - AC_CFG_ACR(6) | AC_CFG_LINPRIO(0); - cfg.cfg_ifs = 0x20; - cfg.cfg_slotl = 0x0C; - cfg.cfg_byte13 = AC_CFG_RETRYNUM(15) | AC_CFG_SLTTMHI(0); - cfg.cfg_byte14 = AC_CFG_FLGPAD(0) | - AC_CFG_BTSTF(0) | - AC_CFG_CRC16(0) | - AC_CFG_NCRC(0) | - AC_CFG_TNCRS(1) | - AC_CFG_MANCH(0) | - AC_CFG_BCDIS(0) | AC_CFG_PRM(lp->promiscuous); - cfg.cfg_byte15 = AC_CFG_ICDS(0) | - AC_CFG_CDTF(0) | AC_CFG_ICSS(0) | AC_CFG_CSTF(0); -/* - cfg.cfg_min_frm_len = AC_CFG_MNFRM(64); -*/ - cfg.cfg_min_frm_len = AC_CFG_MNFRM(8); - - cfg.cfg_h.ac_command = (AC_CFLD_CMD & acmd_configure); - cfg.cfg_h.ac_link = ias_addr; - obram_write(ioaddr, cfg_addr, (unsigned char *) &cfg, sizeof(cfg)); - - /* Set up the MAC address */ - memset(&ias, 0x00, sizeof(ias)); - ias.ias_h.ac_command = (AC_CFLD_CMD & acmd_ia_setup); - ias.ias_h.ac_link = mcs_addr; - memcpy(&ias.ias_addr[0], (unsigned char *) &dev->dev_addr[0], - sizeof(ias.ias_addr)); - obram_write(ioaddr, ias_addr, (unsigned char *) &ias, sizeof(ias)); - - /* Initialize adapter's Ethernet multicast addresses */ - memset(&mcs, 0x00, sizeof(mcs)); - mcs.mcs_h.ac_command = AC_CFLD_I | (AC_CFLD_CMD & acmd_mc_setup); - mcs.mcs_h.ac_link = nop_addr; - mcs.mcs_cnt = WAVELAN_ADDR_SIZE * lp->mc_count; - obram_write(ioaddr, mcs_addr, (unsigned char *) &mcs, sizeof(mcs)); - - /* Any address to set? */ - if (lp->mc_count) { - netdev_for_each_mc_addr(dmi, dev) - outsw(PIOP1(ioaddr), (u16 *) dmi->dmi_addr, - WAVELAN_ADDR_SIZE >> 1); - -#ifdef DEBUG_CONFIG_INFO - printk(KERN_DEBUG - "%s: wv_82586_config(): set %d multicast addresses:\n", - dev->name, lp->mc_count); - netdev_for_each_mc_addr(dmi, dev) - printk(KERN_DEBUG " %pM\n", dmi->dmi_addr); -#endif - } - - /* - * Overwrite the predecessor NOP link - * so that it points to the configure action. - */ - nop_addr = txpred + sizeof(tx); - nop.nop_h.ac_status = 0; - obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_status), - (unsigned char *) &nop.nop_h.ac_status, - sizeof(nop.nop_h.ac_status)); - nop.nop_h.ac_link = cfg_addr; - obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_link), - (unsigned char *) &nop.nop_h.ac_link, - sizeof(nop.nop_h.ac_link)); - - /* Job done, clear the flag */ - lp->reconfig_82586 = 0; - - if (lp->tx_first_in_use == I82586NULL) - lp->tx_first_in_use = txblock; - - if (lp->tx_n_in_use == (NTXBLOCKS - 1)) - netif_stop_queue(dev); - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: <-wv_82586_config()\n", dev->name); -#endif -} - -/*------------------------------------------------------------------*/ -/* - * This routine, called by wavelan_close(), gracefully stops the - * WaveLAN controller (i82586). - * (called by wavelan_close()) - */ -static void wv_82586_stop(struct net_device *dev) -{ - net_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - u16 scb_cmd; - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: ->wv_82586_stop()\n", dev->name); -#endif - - /* Suspend both command unit and receive unit. */ - scb_cmd = - (SCB_CMD_CUC & SCB_CMD_CUC_SUS) | (SCB_CMD_RUC & - SCB_CMD_RUC_SUS); - obram_write(ioaddr, scboff(OFFSET_SCB, scb_command), - (unsigned char *) &scb_cmd, sizeof(scb_cmd)); - set_chan_attn(ioaddr, lp->hacr); - - /* No more interrupts */ - wv_ints_off(dev); - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: <-wv_82586_stop()\n", dev->name); -#endif -} - -/*------------------------------------------------------------------*/ -/* - * Totally reset the WaveLAN and restart it. - * Performs the following actions: - * 1. A power reset (reset DMA) - * 2. Initialize the radio modem (using wv_mmc_init) - * 3. Reset & Configure LAN controller (using wv_82586_start) - * 4. Start the LAN controller's command unit - * 5. Start the LAN controller's receive unit - * (called by wavelan_interrupt(), wavelan_watchdog() & wavelan_open()) - */ -static int wv_hw_reset(struct net_device *dev) -{ - net_local *lp = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: ->wv_hw_reset(dev=0x%x)\n", dev->name, - (unsigned int) dev); -#endif - - /* Increase the number of resets done. */ - lp->nresets++; - - wv_hacr_reset(ioaddr); - lp->hacr = HACR_DEFAULT; - - if ((wv_mmc_init(dev) < 0) || (wv_82586_start(dev) < 0)) - return -1; - - /* Enable the card to send interrupts. */ - wv_ints_on(dev); - - /* Start card functions */ - if (wv_cu_start(dev) < 0) - return -1; - - /* Setup the controller and parameters */ - wv_82586_config(dev); - - /* Finish configuration with the receive unit */ - if (wv_ru_start(dev) < 0) - return -1; - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: <-wv_hw_reset()\n", dev->name); -#endif - return 0; -} - -/*------------------------------------------------------------------*/ -/* - * Check if there is a WaveLAN at the specific base address. - * As a side effect, this reads the MAC address. - * (called in wavelan_probe() and init_module()) - */ -static int wv_check_ioaddr(unsigned long ioaddr, u8 * mac) -{ - int i; /* Loop counter */ - - /* Check if the base address if available. */ - if (!request_region(ioaddr, sizeof(ha_t), "wavelan probe")) - return -EBUSY; /* ioaddr already used */ - - /* Reset host interface */ - wv_hacr_reset(ioaddr); - - /* Read the MAC address from the parameter storage area. */ - psa_read(ioaddr, HACR_DEFAULT, psaoff(0, psa_univ_mac_addr), - mac, 6); - - release_region(ioaddr, sizeof(ha_t)); - - /* - * Check the first three octets of the address for the manufacturer's code. - * Note: if this can't find your WaveLAN card, you've got a - * non-NCR/AT&T/Lucent ISA card. See wavelan.p.h for detail on - * how to configure your card. - */ - for (i = 0; i < ARRAY_SIZE(MAC_ADDRESSES); i++) - if ((mac[0] == MAC_ADDRESSES[i][0]) && - (mac[1] == MAC_ADDRESSES[i][1]) && - (mac[2] == MAC_ADDRESSES[i][2])) - return 0; - -#ifdef DEBUG_CONFIG_INFO - printk(KERN_WARNING - "WaveLAN (0x%3X): your MAC address might be %02X:%02X:%02X.\n", - ioaddr, mac[0], mac[1], mac[2]); -#endif - return -ENODEV; -} - -/************************ INTERRUPT HANDLING ************************/ - -/* - * This function is the interrupt handler for the WaveLAN card. This - * routine will be called whenever: - */ -static irqreturn_t wavelan_interrupt(int irq, void *dev_id) -{ - struct net_device *dev; - unsigned long ioaddr; - net_local *lp; - u16 hasr; - u16 status; - u16 ack_cmd; - - dev = dev_id; - -#ifdef DEBUG_INTERRUPT_TRACE - printk(KERN_DEBUG "%s: ->wavelan_interrupt()\n", dev->name); -#endif - - lp = netdev_priv(dev); - ioaddr = dev->base_addr; - -#ifdef DEBUG_INTERRUPT_INFO - /* Check state of our spinlock */ - if(spin_is_locked(&lp->spinlock)) - printk(KERN_DEBUG - "%s: wavelan_interrupt(): spinlock is already locked !!!\n", - dev->name); -#endif - - /* Prevent reentrancy. We need to do that because we may have - * multiple interrupt handler running concurrently. - * It is safe because interrupts are disabled before acquiring - * the spinlock. */ - spin_lock(&lp->spinlock); - - /* We always had spurious interrupts at startup, but lately I - * saw them comming *between* the request_irq() and the - * spin_lock_irqsave() in wavelan_open(), so the spinlock - * protection is no enough. - * So, we also check lp->hacr that will tell us is we enabled - * irqs or not (see wv_ints_on()). - * We can't use netif_running(dev) because we depend on the - * proper processing of the irq generated during the config. */ - - /* Which interrupt it is ? */ - hasr = hasr_read(ioaddr); - -#ifdef DEBUG_INTERRUPT_INFO - printk(KERN_INFO - "%s: wavelan_interrupt(): hasr 0x%04x; hacr 0x%04x.\n", - dev->name, hasr, lp->hacr); -#endif - - /* Check modem interrupt */ - if ((hasr & HASR_MMC_INTR) && (lp->hacr & HACR_MMC_INT_ENABLE)) { - u8 dce_status; - - /* - * Interrupt from the modem management controller. - * This will clear it -- ignored for now. - */ - mmc_read(ioaddr, mmroff(0, mmr_dce_status), &dce_status, - sizeof(dce_status)); - -#ifdef DEBUG_INTERRUPT_ERROR - printk(KERN_INFO - "%s: wavelan_interrupt(): unexpected mmc interrupt: status 0x%04x.\n", - dev->name, dce_status); -#endif - } - - /* Check if not controller interrupt */ - if (((hasr & HASR_82586_INTR) == 0) || - ((lp->hacr & HACR_82586_INT_ENABLE) == 0)) { -#ifdef DEBUG_INTERRUPT_ERROR - printk(KERN_INFO - "%s: wavelan_interrupt(): interrupt not coming from i82586 - hasr 0x%04x.\n", - dev->name, hasr); -#endif - spin_unlock (&lp->spinlock); - return IRQ_NONE; - } - - /* Read interrupt data. */ - obram_read(ioaddr, scboff(OFFSET_SCB, scb_status), - (unsigned char *) &status, sizeof(status)); - - /* - * Acknowledge the interrupt(s). - */ - ack_cmd = status & SCB_ST_INT; - obram_write(ioaddr, scboff(OFFSET_SCB, scb_command), - (unsigned char *) &ack_cmd, sizeof(ack_cmd)); - set_chan_attn(ioaddr, lp->hacr); - -#ifdef DEBUG_INTERRUPT_INFO - printk(KERN_DEBUG "%s: wavelan_interrupt(): status 0x%04x.\n", - dev->name, status); -#endif - - /* Command completed. */ - if ((status & SCB_ST_CX) == SCB_ST_CX) { -#ifdef DEBUG_INTERRUPT_INFO - printk(KERN_DEBUG - "%s: wavelan_interrupt(): command completed.\n", - dev->name); -#endif - wv_complete(dev, ioaddr, lp); - } - - /* Frame received. */ - if ((status & SCB_ST_FR) == SCB_ST_FR) { -#ifdef DEBUG_INTERRUPT_INFO - printk(KERN_DEBUG - "%s: wavelan_interrupt(): received packet.\n", - dev->name); -#endif - wv_receive(dev); - } - - /* Check the state of the command unit. */ - if (((status & SCB_ST_CNA) == SCB_ST_CNA) || - (((status & SCB_ST_CUS) != SCB_ST_CUS_ACTV) && - (netif_running(dev)))) { -#ifdef DEBUG_INTERRUPT_ERROR - printk(KERN_INFO - "%s: wavelan_interrupt(): CU inactive -- restarting\n", - dev->name); -#endif - wv_hw_reset(dev); - } - - /* Check the state of the command unit. */ - if (((status & SCB_ST_RNR) == SCB_ST_RNR) || - (((status & SCB_ST_RUS) != SCB_ST_RUS_RDY) && - (netif_running(dev)))) { -#ifdef DEBUG_INTERRUPT_ERROR - printk(KERN_INFO - "%s: wavelan_interrupt(): RU not ready -- restarting\n", - dev->name); -#endif - wv_hw_reset(dev); - } - - /* Release spinlock */ - spin_unlock (&lp->spinlock); - -#ifdef DEBUG_INTERRUPT_TRACE - printk(KERN_DEBUG "%s: <-wavelan_interrupt()\n", dev->name); -#endif - return IRQ_HANDLED; -} - -/*------------------------------------------------------------------*/ -/* - * Watchdog: when we start a transmission, a timer is set for us in the - * kernel. If the transmission completes, this timer is disabled. If - * the timer expires, we are called and we try to unlock the hardware. - */ -static void wavelan_watchdog(struct net_device * dev) -{ - net_local *lp = netdev_priv(dev); - u_long ioaddr = dev->base_addr; - unsigned long flags; - unsigned int nreaped; - -#ifdef DEBUG_INTERRUPT_TRACE - printk(KERN_DEBUG "%s: ->wavelan_watchdog()\n", dev->name); -#endif - -#ifdef DEBUG_INTERRUPT_ERROR - printk(KERN_INFO "%s: wavelan_watchdog: watchdog timer expired\n", - dev->name); -#endif - - /* Check that we came here for something */ - if (lp->tx_n_in_use <= 0) { - return; - } - - spin_lock_irqsave(&lp->spinlock, flags); - - /* Try to see if some buffers are not free (in case we missed - * an interrupt */ - nreaped = wv_complete(dev, ioaddr, lp); - -#ifdef DEBUG_INTERRUPT_INFO - printk(KERN_DEBUG - "%s: wavelan_watchdog(): %d reaped, %d remain.\n", - dev->name, nreaped, lp->tx_n_in_use); -#endif - -#ifdef DEBUG_PSA_SHOW - { - psa_t psa; - psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa)); - wv_psa_show(&psa); - } -#endif -#ifdef DEBUG_MMC_SHOW - wv_mmc_show(dev); -#endif -#ifdef DEBUG_I82586_SHOW - wv_cu_show(dev); -#endif - - /* If no buffer has been freed */ - if (nreaped == 0) { -#ifdef DEBUG_INTERRUPT_ERROR - printk(KERN_INFO - "%s: wavelan_watchdog(): cleanup failed, trying reset\n", - dev->name); -#endif - wv_hw_reset(dev); - } - - /* At this point, we should have some free Tx buffer ;-) */ - if (lp->tx_n_in_use < NTXBLOCKS - 1) - netif_wake_queue(dev); - - spin_unlock_irqrestore(&lp->spinlock, flags); - -#ifdef DEBUG_INTERRUPT_TRACE - printk(KERN_DEBUG "%s: <-wavelan_watchdog()\n", dev->name); -#endif -} - -/********************* CONFIGURATION CALLBACKS *********************/ -/* - * Here are the functions called by the Linux networking code (NET3) - * for initialization, configuration and deinstallations of the - * WaveLAN ISA hardware. - */ - -/*------------------------------------------------------------------*/ -/* - * Configure and start up the WaveLAN PCMCIA adaptor. - * Called by NET3 when it "opens" the device. - */ -static int wavelan_open(struct net_device *dev) -{ - net_local *lp = netdev_priv(dev); - unsigned long flags; - -#ifdef DEBUG_CALLBACK_TRACE - printk(KERN_DEBUG "%s: ->wavelan_open(dev=0x%x)\n", dev->name, - (unsigned int) dev); -#endif - - /* Check irq */ - if (dev->irq == 0) { -#ifdef DEBUG_CONFIG_ERROR - printk(KERN_WARNING "%s: wavelan_open(): no IRQ\n", - dev->name); -#endif - return -ENXIO; - } - - if (request_irq(dev->irq, &wavelan_interrupt, 0, "WaveLAN", dev) != 0) - { -#ifdef DEBUG_CONFIG_ERROR - printk(KERN_WARNING "%s: wavelan_open(): invalid IRQ\n", - dev->name); -#endif - return -EAGAIN; - } - - spin_lock_irqsave(&lp->spinlock, flags); - - if (wv_hw_reset(dev) != -1) { - netif_start_queue(dev); - } else { - free_irq(dev->irq, dev); -#ifdef DEBUG_CONFIG_ERROR - printk(KERN_INFO - "%s: wavelan_open(): impossible to start the card\n", - dev->name); -#endif - spin_unlock_irqrestore(&lp->spinlock, flags); - return -EAGAIN; - } - spin_unlock_irqrestore(&lp->spinlock, flags); - -#ifdef DEBUG_CALLBACK_TRACE - printk(KERN_DEBUG "%s: <-wavelan_open()\n", dev->name); -#endif - return 0; -} - -/*------------------------------------------------------------------*/ -/* - * Shut down the WaveLAN ISA card. - * Called by NET3 when it "closes" the device. - */ -static int wavelan_close(struct net_device *dev) -{ - net_local *lp = netdev_priv(dev); - unsigned long flags; - -#ifdef DEBUG_CALLBACK_TRACE - printk(KERN_DEBUG "%s: ->wavelan_close(dev=0x%x)\n", dev->name, - (unsigned int) dev); -#endif - - netif_stop_queue(dev); - - /* - * Flush the Tx and disable Rx. - */ - spin_lock_irqsave(&lp->spinlock, flags); - wv_82586_stop(dev); - spin_unlock_irqrestore(&lp->spinlock, flags); - - free_irq(dev->irq, dev); - -#ifdef DEBUG_CALLBACK_TRACE - printk(KERN_DEBUG "%s: <-wavelan_close()\n", dev->name); -#endif - return 0; -} - -static const struct net_device_ops wavelan_netdev_ops = { - .ndo_open = wavelan_open, - .ndo_stop = wavelan_close, - .ndo_start_xmit = wavelan_packet_xmit, - .ndo_set_multicast_list = wavelan_set_multicast_list, - .ndo_tx_timeout = wavelan_watchdog, - .ndo_change_mtu = eth_change_mtu, - .ndo_validate_addr = eth_validate_addr, -#ifdef SET_MAC_ADDRESS - .ndo_set_mac_address = wavelan_set_mac_address -#else - .ndo_set_mac_address = eth_mac_addr, -#endif -}; - - -/*------------------------------------------------------------------*/ -/* - * Probe an I/O address, and if the WaveLAN is there configure the - *device structure - * (called by wavelan_probe() and via init_module()). - */ -static int __init wavelan_config(struct net_device *dev, unsigned short ioaddr) -{ - u8 irq_mask; - int irq; - net_local *lp; - mac_addr mac; - int err; - - if (!request_region(ioaddr, sizeof(ha_t), "wavelan")) - return -EADDRINUSE; - - err = wv_check_ioaddr(ioaddr, mac); - if (err) - goto out; - - memcpy(dev->dev_addr, mac, 6); - - dev->base_addr = ioaddr; - -#ifdef DEBUG_CALLBACK_TRACE - printk(KERN_DEBUG "%s: ->wavelan_config(dev=0x%x, ioaddr=0x%lx)\n", - dev->name, (unsigned int) dev, ioaddr); -#endif - - /* Check IRQ argument on command line. */ - if (dev->irq != 0) { - irq_mask = wv_irq_to_psa(dev->irq); - - if (irq_mask == 0) { -#ifdef DEBUG_CONFIG_ERROR - printk(KERN_WARNING - "%s: wavelan_config(): invalid IRQ %d ignored.\n", - dev->name, dev->irq); -#endif - dev->irq = 0; - } else { -#ifdef DEBUG_CONFIG_INFO - printk(KERN_DEBUG - "%s: wavelan_config(): changing IRQ to %d\n", - dev->name, dev->irq); -#endif - psa_write(ioaddr, HACR_DEFAULT, - psaoff(0, psa_int_req_no), &irq_mask, 1); - /* update the Wavelan checksum */ - update_psa_checksum(dev, ioaddr, HACR_DEFAULT); - wv_hacr_reset(ioaddr); - } - } - - psa_read(ioaddr, HACR_DEFAULT, psaoff(0, psa_int_req_no), - &irq_mask, 1); - if ((irq = wv_psa_to_irq(irq_mask)) == -1) { -#ifdef DEBUG_CONFIG_ERROR - printk(KERN_INFO - "%s: wavelan_config(): could not wavelan_map_irq(%d).\n", - dev->name, irq_mask); -#endif - err = -EAGAIN; - goto out; - } - - dev->irq = irq; - - dev->mem_start = 0x0000; - dev->mem_end = 0x0000; - dev->if_port = 0; - - /* Initialize device structures */ - memset(netdev_priv(dev), 0, sizeof(net_local)); - lp = netdev_priv(dev); - - /*back link to the device structure. */ - lp->dev = dev; - /* Add the device at the beginning of the linked list. */ - lp->next = wavelan_list; - wavelan_list = lp; - - lp->hacr = HACR_DEFAULT; - - /* Multicast stuff */ - lp->promiscuous = 0; - lp->mc_count = 0; - - /* Init spinlock */ - spin_lock_init(&lp->spinlock); - - dev->netdev_ops = &wavelan_netdev_ops; - dev->watchdog_timeo = WATCHDOG_JIFFIES; - dev->wireless_handlers = &wavelan_handler_def; - lp->wireless_data.spy_data = &lp->spy_data; - dev->wireless_data = &lp->wireless_data; - - dev->mtu = WAVELAN_MTU; - - /* Display nice information. */ - wv_init_info(dev); - -#ifdef DEBUG_CALLBACK_TRACE - printk(KERN_DEBUG "%s: <-wavelan_config()\n", dev->name); -#endif - return 0; -out: - release_region(ioaddr, sizeof(ha_t)); - return err; -} - -/*------------------------------------------------------------------*/ -/* - * Check for a network adaptor of this type. Return '0' iff one - * exists. There seem to be different interpretations of - * the initial value of dev->base_addr. - * We follow the example in drivers/net/ne.c. - * (called in "Space.c") - */ -struct net_device * __init wavelan_probe(int unit) -{ - struct net_device *dev; - short base_addr; - int def_irq; - int i; - int r = 0; - - /* compile-time check the sizes of structures */ - BUILD_BUG_ON(sizeof(psa_t) != PSA_SIZE); - BUILD_BUG_ON(sizeof(mmw_t) != MMW_SIZE); - BUILD_BUG_ON(sizeof(mmr_t) != MMR_SIZE); - BUILD_BUG_ON(sizeof(ha_t) != HA_SIZE); - - dev = alloc_etherdev(sizeof(net_local)); - if (!dev) - return ERR_PTR(-ENOMEM); - - sprintf(dev->name, "eth%d", unit); - netdev_boot_setup_check(dev); - base_addr = dev->base_addr; - def_irq = dev->irq; - -#ifdef DEBUG_CALLBACK_TRACE - printk(KERN_DEBUG - "%s: ->wavelan_probe(dev=%p (base_addr=0x%x))\n", - dev->name, dev, (unsigned int) dev->base_addr); -#endif - - /* Don't probe at all. */ - if (base_addr < 0) { -#ifdef DEBUG_CONFIG_ERROR - printk(KERN_WARNING - "%s: wavelan_probe(): invalid base address\n", - dev->name); -#endif - r = -ENXIO; - } else if (base_addr > 0x100) { /* Check a single specified location. */ - r = wavelan_config(dev, base_addr); -#ifdef DEBUG_CONFIG_INFO - if (r != 0) - printk(KERN_DEBUG - "%s: wavelan_probe(): no device at specified base address (0x%X) or address already in use\n", - dev->name, base_addr); -#endif - -#ifdef DEBUG_CALLBACK_TRACE - printk(KERN_DEBUG "%s: <-wavelan_probe()\n", dev->name); -#endif - } else { /* Scan all possible addresses of the WaveLAN hardware. */ - for (i = 0; i < ARRAY_SIZE(iobase); i++) { - dev->irq = def_irq; - if (wavelan_config(dev, iobase[i]) == 0) { -#ifdef DEBUG_CALLBACK_TRACE - printk(KERN_DEBUG - "%s: <-wavelan_probe()\n", - dev->name); -#endif - break; - } - } - if (i == ARRAY_SIZE(iobase)) - r = -ENODEV; - } - if (r) - goto out; - r = register_netdev(dev); - if (r) - goto out1; - return dev; -out1: - release_region(dev->base_addr, sizeof(ha_t)); - wavelan_list = wavelan_list->next; -out: - free_netdev(dev); - return ERR_PTR(r); -} - -/****************************** MODULE ******************************/ -/* - * Module entry point: insertion and removal - */ - -#ifdef MODULE -/*------------------------------------------------------------------*/ -/* - * Insertion of the module - * I'm now quite proud of the multi-device support. - */ -int __init init_module(void) -{ - int ret = -EIO; /* Return error if no cards found */ - int i; - -#ifdef DEBUG_MODULE_TRACE - printk(KERN_DEBUG "-> init_module()\n"); -#endif - - /* If probing is asked */ - if (io[0] == 0) { -#ifdef DEBUG_CONFIG_ERROR - printk(KERN_WARNING - "WaveLAN init_module(): doing device probing (bad !)\n"); - printk(KERN_WARNING - "Specify base addresses while loading module to correct the problem\n"); -#endif - - /* Copy the basic set of address to be probed. */ - for (i = 0; i < ARRAY_SIZE(iobase); i++) - io[i] = iobase[i]; - } - - - /* Loop on all possible base addresses. */ - for (i = 0; i < ARRAY_SIZE(io) && io[i] != 0; i++) { - struct net_device *dev = alloc_etherdev(sizeof(net_local)); - if (!dev) - break; - if (name[i]) - strcpy(dev->name, name[i]); /* Copy name */ - dev->base_addr = io[i]; - dev->irq = irq[i]; - - /* Check if there is something at this base address. */ - if (wavelan_config(dev, io[i]) == 0) { - if (register_netdev(dev) != 0) { - release_region(dev->base_addr, sizeof(ha_t)); - wavelan_list = wavelan_list->next; - } else { - ret = 0; - continue; - } - } - free_netdev(dev); - } - -#ifdef DEBUG_CONFIG_ERROR - if (!wavelan_list) - printk(KERN_WARNING - "WaveLAN init_module(): no device found\n"); -#endif - -#ifdef DEBUG_MODULE_TRACE - printk(KERN_DEBUG "<- init_module()\n"); -#endif - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Removal of the module - */ -void cleanup_module(void) -{ -#ifdef DEBUG_MODULE_TRACE - printk(KERN_DEBUG "-> cleanup_module()\n"); -#endif - - /* Loop on all devices and release them. */ - while (wavelan_list) { - struct net_device *dev = wavelan_list->dev; - -#ifdef DEBUG_CONFIG_INFO - printk(KERN_DEBUG - "%s: cleanup_module(): removing device at 0x%x\n", - dev->name, (unsigned int) dev); -#endif - unregister_netdev(dev); - - release_region(dev->base_addr, sizeof(ha_t)); - wavelan_list = wavelan_list->next; - - free_netdev(dev); - } - -#ifdef DEBUG_MODULE_TRACE - printk(KERN_DEBUG "<- cleanup_module()\n"); -#endif -} -#endif /* MODULE */ -MODULE_LICENSE("GPL"); - -/* - * This software may only be used and distributed - * according to the terms of the GNU General Public License. - * - * This software was developed as a component of the - * Linux operating system. - * It is based on other device drivers and information - * either written or supplied by: - * Ajay Bakre (bakre@paul.rutgers.edu), - * Donald Becker (becker@scyld.com), - * Loeke Brederveld (Loeke.Brederveld@Utrecht.NCR.com), - * Anders Klemets (klemets@it.kth.se), - * Vladimir V. Kolpakov (w@stier.koenig.ru), - * Marc Meertens (Marc.Meertens@Utrecht.NCR.com), - * Pauline Middelink (middelin@polyware.iaf.nl), - * Robert Morris (rtm@das.harvard.edu), - * Jean Tourrilhes (jt@hplb.hpl.hp.com), - * Girish Welling (welling@paul.rutgers.edu), - * - * Thanks go also to: - * James Ashton (jaa101@syseng.anu.edu.au), - * Alan Cox (alan@lxorguk.ukuu.org.uk), - * Allan Creighton (allanc@cs.usyd.edu.au), - * Matthew Geier (matthew@cs.usyd.edu.au), - * Remo di Giovanni (remo@cs.usyd.edu.au), - * Eckhard Grah (grah@wrcs1.urz.uni-wuppertal.de), - * Vipul Gupta (vgupta@cs.binghamton.edu), - * Mark Hagan (mhagan@wtcpost.daytonoh.NCR.COM), - * Tim Nicholson (tim@cs.usyd.edu.au), - * Ian Parkin (ian@cs.usyd.edu.au), - * John Rosenberg (johnr@cs.usyd.edu.au), - * George Rossi (george@phm.gov.au), - * Arthur Scott (arthur@cs.usyd.edu.au), - * Peter Storey, - * for their assistance and advice. - * - * Please send bug reports, updates, comments to: - * - *bruce Janson Email: bruce@cs.usyd.edu.au - *basser Department of Computer Science Phone: +61-2-9351-3423 - * University of Sydney, N.S.W., 2006, AUSTRALIA Fax: +61-2-9351-3838 - */ diff --git a/drivers/staging/wavelan/wavelan.h b/drivers/staging/wavelan/wavelan.h deleted file mode 100644 index 1ebae10b8696..000000000000 --- a/drivers/staging/wavelan/wavelan.h +++ /dev/null @@ -1,363 +0,0 @@ -/* - * WaveLAN ISA driver - * - * Jean II - HPLB '96 - * - * Reorganisation and extension of the driver. - * Original copyright follows. See wavelan.p.h for details. - * - * This file contains the declarations for the WaveLAN hardware. Note that - * the WaveLAN ISA includes a i82586 controller (see definitions in - * file i82586.h). - * - * The main difference between the ISA hardware and the PCMCIA one is - * the Ethernet controller (i82586 instead of i82593). - * The i82586 allows multiple transmit buffers. The PSA needs to be accessed - * through the host interface. - */ - -#ifndef _WAVELAN_H -#define _WAVELAN_H - -/************************** MAGIC NUMBERS ***************************/ - -/* Detection of the WaveLAN card is done by reading the MAC - * address from the card and checking it. If you have a non-AT&T - * product (OEM, like DEC RoamAbout, Digital Ocean, or Epson), - * you might need to modify this part to accommodate your hardware. - */ -static const char MAC_ADDRESSES[][3] = { - { 0x08, 0x00, 0x0E }, /* AT&T WaveLAN (standard) & DEC RoamAbout */ - { 0x08, 0x00, 0x6A }, /* AT&T WaveLAN (alternate) */ - { 0x00, 0x00, 0xE1 }, /* Hitachi Wavelan */ - { 0x00, 0x60, 0x1D } /* Lucent Wavelan (another one) */ - /* Add your card here and send me the patch! */ -}; - -#define WAVELAN_ADDR_SIZE 6 /* Size of a MAC address */ - -#define WAVELAN_MTU 1500 /* Maximum size of WaveLAN packet */ - -#define MAXDATAZ (WAVELAN_ADDR_SIZE + WAVELAN_ADDR_SIZE + 2 + WAVELAN_MTU) - -/* - * Constants used to convert channels to frequencies - */ - -/* Frequency available in the 2.0 modem, in units of 250 kHz - * (as read in the offset register of the dac area). - * Used to map channel numbers used by `wfreqsel' to frequencies - */ -static const short channel_bands[] = { 0x30, 0x58, 0x64, 0x7A, 0x80, 0xA8, - 0xD0, 0xF0, 0xF8, 0x150 }; - -/* Frequencies of the 1.0 modem (fixed frequencies). - * Use to map the PSA `subband' to a frequency - * Note : all frequencies apart from the first one need to be multiplied by 10 - */ -static const int fixed_bands[] = { 915e6, 2.425e8, 2.46e8, 2.484e8, 2.4305e8 }; - - - -/*************************** PC INTERFACE ****************************/ - -/* - * Host Adaptor structure. - * (base is board port address). - */ -typedef union hacs_u hacs_u; -union hacs_u { - unsigned short hu_command; /* Command register */ -#define HACR_RESET 0x0001 /* Reset board */ -#define HACR_CA 0x0002 /* Set Channel Attention for 82586 */ -#define HACR_16BITS 0x0004 /* 16-bit operation (0 => 8bits) */ -#define HACR_OUT0 0x0008 /* General purpose output pin 0 */ - /* not used - must be 1 */ -#define HACR_OUT1 0x0010 /* General purpose output pin 1 */ - /* not used - must be 1 */ -#define HACR_82586_INT_ENABLE 0x0020 /* Enable 82586 interrupts */ -#define HACR_MMC_INT_ENABLE 0x0040 /* Enable MMC interrupts */ -#define HACR_INTR_CLR_ENABLE 0x0080 /* Enable interrupt status read/clear */ - unsigned short hu_status; /* Status Register */ -#define HASR_82586_INTR 0x0001 /* Interrupt request from 82586 */ -#define HASR_MMC_INTR 0x0002 /* Interrupt request from MMC */ -#define HASR_MMC_BUSY 0x0004 /* MMC busy indication */ -#define HASR_PSA_BUSY 0x0008 /* LAN parameter storage area busy */ -} __attribute__ ((packed)); - -typedef struct ha_t ha_t; -struct ha_t { - hacs_u ha_cs; /* Command and status registers */ -#define ha_command ha_cs.hu_command -#define ha_status ha_cs.hu_status - unsigned short ha_mmcr; /* Modem Management Ctrl Register */ - unsigned short ha_pior0; /* Program I/O Address Register Port 0 */ - unsigned short ha_piop0; /* Program I/O Port 0 */ - unsigned short ha_pior1; /* Program I/O Address Register Port 1 */ - unsigned short ha_piop1; /* Program I/O Port 1 */ - unsigned short ha_pior2; /* Program I/O Address Register Port 2 */ - unsigned short ha_piop2; /* Program I/O Port 2 */ -}; - -#define HA_SIZE 16 - -#define hoff(p, f) (unsigned short)((void *)(&((ha_t *)((void *)0 + (p)))->f) - (void *)0) -#define HACR(p) hoff(p, ha_command) -#define HASR(p) hoff(p, ha_status) -#define MMCR(p) hoff(p, ha_mmcr) -#define PIOR0(p) hoff(p, ha_pior0) -#define PIOP0(p) hoff(p, ha_piop0) -#define PIOR1(p) hoff(p, ha_pior1) -#define PIOP1(p) hoff(p, ha_piop1) -#define PIOR2(p) hoff(p, ha_pior2) -#define PIOP2(p) hoff(p, ha_piop2) - -/* - * Program I/O Mode Register values. - */ -#define STATIC_PIO 0 /* Mode 1: static mode */ - /* RAM access ??? */ -#define AUTOINCR_PIO 1 /* Mode 2: auto increment mode */ - /* RAM access ??? */ -#define AUTODECR_PIO 2 /* Mode 3: auto decrement mode */ - /* RAM access ??? */ -#define PARAM_ACCESS_PIO 3 /* Mode 4: LAN parameter access mode */ - /* Parameter access. */ -#define PIO_MASK 3 /* register mask */ -#define PIOM(cmd, piono) ((u_short)cmd << 10 << (piono * 2)) - -#define HACR_DEFAULT (HACR_OUT0 | HACR_OUT1 | HACR_16BITS | PIOM(STATIC_PIO, 0) | PIOM(AUTOINCR_PIO, 1) | PIOM(PARAM_ACCESS_PIO, 2)) -#define HACR_INTRON (HACR_82586_INT_ENABLE | HACR_MMC_INT_ENABLE | HACR_INTR_CLR_ENABLE) - -/************************** MEMORY LAYOUT **************************/ - -/* - * Onboard 64 k RAM layout. - * (Offsets from 0x0000.) - */ -#define OFFSET_RU 0x0000 /* 75% memory */ -#define OFFSET_CU 0xC000 /* 25% memory */ -#define OFFSET_SCB (OFFSET_ISCP - sizeof(scb_t)) -#define OFFSET_ISCP (OFFSET_SCP - sizeof(iscp_t)) -#define OFFSET_SCP I82586_SCP_ADDR - -#define RXBLOCKZ (sizeof(fd_t) + sizeof(rbd_t) + MAXDATAZ) -#define TXBLOCKZ (sizeof(ac_tx_t) + sizeof(ac_nop_t) + sizeof(tbd_t) + MAXDATAZ) - -#define NRXBLOCKS ((OFFSET_CU - OFFSET_RU) / RXBLOCKZ) -#define NTXBLOCKS ((OFFSET_SCB - OFFSET_CU) / TXBLOCKZ) - -/********************** PARAMETER STORAGE AREA **********************/ - -/* - * Parameter Storage Area (PSA). - */ -typedef struct psa_t psa_t; -struct psa_t { - unsigned char psa_io_base_addr_1; /* [0x00] Base address 1 ??? */ - unsigned char psa_io_base_addr_2; /* [0x01] Base address 2 */ - unsigned char psa_io_base_addr_3; /* [0x02] Base address 3 */ - unsigned char psa_io_base_addr_4; /* [0x03] Base address 4 */ - unsigned char psa_rem_boot_addr_1; /* [0x04] Remote Boot Address 1 */ - unsigned char psa_rem_boot_addr_2; /* [0x05] Remote Boot Address 2 */ - unsigned char psa_rem_boot_addr_3; /* [0x06] Remote Boot Address 3 */ - unsigned char psa_holi_params; /* [0x07] HOst Lan Interface (HOLI) Parameters */ - unsigned char psa_int_req_no; /* [0x08] Interrupt Request Line */ - unsigned char psa_unused0[7]; /* [0x09-0x0F] unused */ - - unsigned char psa_univ_mac_addr[WAVELAN_ADDR_SIZE]; /* [0x10-0x15] Universal (factory) MAC Address */ - unsigned char psa_local_mac_addr[WAVELAN_ADDR_SIZE]; /* [0x16-1B] Local MAC Address */ - unsigned char psa_univ_local_sel; /* [0x1C] Universal Local Selection */ -#define PSA_UNIVERSAL 0 /* Universal (factory) */ -#define PSA_LOCAL 1 /* Local */ - unsigned char psa_comp_number; /* [0x1D] Compatibility Number: */ -#define PSA_COMP_PC_AT_915 0 /* PC-AT 915 MHz */ -#define PSA_COMP_PC_MC_915 1 /* PC-MC 915 MHz */ -#define PSA_COMP_PC_AT_2400 2 /* PC-AT 2.4 GHz */ -#define PSA_COMP_PC_MC_2400 3 /* PC-MC 2.4 GHz */ -#define PSA_COMP_PCMCIA_915 4 /* PCMCIA 915 MHz or 2.0 */ - unsigned char psa_thr_pre_set; /* [0x1E] Modem Threshold Preset */ - unsigned char psa_feature_select; /* [0x1F] Call code required (1=on) */ -#define PSA_FEATURE_CALL_CODE 0x01 /* Call code required (Japan) */ - unsigned char psa_subband; /* [0x20] Subband */ -#define PSA_SUBBAND_915 0 /* 915 MHz or 2.0 */ -#define PSA_SUBBAND_2425 1 /* 2425 MHz */ -#define PSA_SUBBAND_2460 2 /* 2460 MHz */ -#define PSA_SUBBAND_2484 3 /* 2484 MHz */ -#define PSA_SUBBAND_2430_5 4 /* 2430.5 MHz */ - unsigned char psa_quality_thr; /* [0x21] Modem Quality Threshold */ - unsigned char psa_mod_delay; /* [0x22] Modem Delay (?) (reserved) */ - unsigned char psa_nwid[2]; /* [0x23-0x24] Network ID */ - unsigned char psa_nwid_select; /* [0x25] Network ID Select On/Off */ - unsigned char psa_encryption_select; /* [0x26] Encryption On/Off */ - unsigned char psa_encryption_key[8]; /* [0x27-0x2E] Encryption Key */ - unsigned char psa_databus_width; /* [0x2F] AT bus width select 8/16 */ - unsigned char psa_call_code[8]; /* [0x30-0x37] (Japan) Call Code */ - unsigned char psa_nwid_prefix[2]; /* [0x38-0x39] Roaming domain */ - unsigned char psa_reserved[2]; /* [0x3A-0x3B] Reserved - fixed 00 */ - unsigned char psa_conf_status; /* [0x3C] Conf Status, bit 0=1:config*/ - unsigned char psa_crc[2]; /* [0x3D] CRC-16 over PSA */ - unsigned char psa_crc_status; /* [0x3F] CRC Valid Flag */ -}; - -#define PSA_SIZE 64 - -/* Calculate offset of a field in the above structure. - * Warning: only even addresses are used. */ -#define psaoff(p, f) ((unsigned short) ((void *)(&((psa_t *) ((void *) NULL + (p)))->f) - (void *) NULL)) - -/******************** MODEM MANAGEMENT INTERFACE ********************/ - -/* - * Modem Management Controller (MMC) write structure. - */ -typedef struct mmw_t mmw_t; -struct mmw_t { - unsigned char mmw_encr_key[8]; /* encryption key */ - unsigned char mmw_encr_enable; /* Enable or disable encryption. */ -#define MMW_ENCR_ENABLE_MODE 0x02 /* mode of security option */ -#define MMW_ENCR_ENABLE_EN 0x01 /* Enable security option. */ - unsigned char mmw_unused0[1]; /* unused */ - unsigned char mmw_des_io_invert; /* encryption option */ -#define MMW_DES_IO_INVERT_RES 0x0F /* reserved */ -#define MMW_DES_IO_INVERT_CTRL 0xF0 /* control (?) (set to 0) */ - unsigned char mmw_unused1[5]; /* unused */ - unsigned char mmw_loopt_sel; /* looptest selection */ -#define MMW_LOOPT_SEL_DIS_NWID 0x40 /* Disable NWID filtering. */ -#define MMW_LOOPT_SEL_INT 0x20 /* Activate Attention Request. */ -#define MMW_LOOPT_SEL_LS 0x10 /* looptest, no collision avoidance */ -#define MMW_LOOPT_SEL_LT3A 0x08 /* looptest 3a */ -#define MMW_LOOPT_SEL_LT3B 0x04 /* looptest 3b */ -#define MMW_LOOPT_SEL_LT3C 0x02 /* looptest 3c */ -#define MMW_LOOPT_SEL_LT3D 0x01 /* looptest 3d */ - unsigned char mmw_jabber_enable; /* jabber timer enable */ - /* Abort transmissions > 200 ms */ - unsigned char mmw_freeze; /* freeze or unfreeze signal level */ - /* 0 : signal level & qual updated for every new message, 1 : frozen */ - unsigned char mmw_anten_sel; /* antenna selection */ -#define MMW_ANTEN_SEL_SEL 0x01 /* direct antenna selection */ -#define MMW_ANTEN_SEL_ALG_EN 0x02 /* antenna selection algo. enable */ - unsigned char mmw_ifs; /* inter frame spacing */ - /* min time between transmission in bit periods (.5 us) - bit 0 ignored */ - unsigned char mmw_mod_delay; /* modem delay (synchro) */ - unsigned char mmw_jam_time; /* jamming time (after collision) */ - unsigned char mmw_unused2[1]; /* unused */ - unsigned char mmw_thr_pre_set; /* level threshold preset */ - /* Discard all packet with signal < this value (4) */ - unsigned char mmw_decay_prm; /* decay parameters */ - unsigned char mmw_decay_updat_prm; /* decay update parameters */ - unsigned char mmw_quality_thr; /* quality (z-quotient) threshold */ - /* Discard all packet with quality < this value (3) */ - unsigned char mmw_netw_id_l; /* NWID low order byte */ - unsigned char mmw_netw_id_h; /* NWID high order byte */ - /* Network ID or Domain : create virtual net on the air */ - - /* 2.0 Hardware extension - frequency selection support */ - unsigned char mmw_mode_select; /* for analog tests (set to 0) */ - unsigned char mmw_unused3[1]; /* unused */ - unsigned char mmw_fee_ctrl; /* frequency EEPROM control */ -#define MMW_FEE_CTRL_PRE 0x10 /* Enable protected instructions. */ -#define MMW_FEE_CTRL_DWLD 0x08 /* Download EEPROM to mmc. */ -#define MMW_FEE_CTRL_CMD 0x07 /* EEPROM commands: */ -#define MMW_FEE_CTRL_READ 0x06 /* Read */ -#define MMW_FEE_CTRL_WREN 0x04 /* Write enable */ -#define MMW_FEE_CTRL_WRITE 0x05 /* Write data to address. */ -#define MMW_FEE_CTRL_WRALL 0x04 /* Write data to all addresses. */ -#define MMW_FEE_CTRL_WDS 0x04 /* Write disable */ -#define MMW_FEE_CTRL_PRREAD 0x16 /* Read addr from protect register */ -#define MMW_FEE_CTRL_PREN 0x14 /* Protect register enable */ -#define MMW_FEE_CTRL_PRCLEAR 0x17 /* Unprotect all registers. */ -#define MMW_FEE_CTRL_PRWRITE 0x15 /* Write address in protect register */ -#define MMW_FEE_CTRL_PRDS 0x14 /* Protect register disable */ - /* Never issue the PRDS command: it's irreversible! */ - - unsigned char mmw_fee_addr; /* EEPROM address */ -#define MMW_FEE_ADDR_CHANNEL 0xF0 /* Select the channel. */ -#define MMW_FEE_ADDR_OFFSET 0x0F /* Offset in channel data */ -#define MMW_FEE_ADDR_EN 0xC0 /* FEE_CTRL enable operations */ -#define MMW_FEE_ADDR_DS 0x00 /* FEE_CTRL disable operations */ -#define MMW_FEE_ADDR_ALL 0x40 /* FEE_CTRL all operations */ -#define MMW_FEE_ADDR_CLEAR 0xFF /* FEE_CTRL clear operations */ - - unsigned char mmw_fee_data_l; /* Write data to EEPROM. */ - unsigned char mmw_fee_data_h; /* high octet */ - unsigned char mmw_ext_ant; /* Setting for external antenna */ -#define MMW_EXT_ANT_EXTANT 0x01 /* Select external antenna */ -#define MMW_EXT_ANT_POL 0x02 /* Polarity of the antenna */ -#define MMW_EXT_ANT_INTERNAL 0x00 /* Internal antenna */ -#define MMW_EXT_ANT_EXTERNAL 0x03 /* External antenna */ -#define MMW_EXT_ANT_IQ_TEST 0x1C /* IQ test pattern (set to 0) */ -} __attribute__ ((packed)); - -#define MMW_SIZE 37 - -#define mmwoff(p, f) (unsigned short)((void *)(&((mmw_t *)((void *)0 + (p)))->f) - (void *)0) - -/* - * Modem Management Controller (MMC) read structure. - */ -typedef struct mmr_t mmr_t; -struct mmr_t { - unsigned char mmr_unused0[8]; /* unused */ - unsigned char mmr_des_status; /* encryption status */ - unsigned char mmr_des_avail; /* encryption available (0x55 read) */ -#define MMR_DES_AVAIL_DES 0x55 /* DES available */ -#define MMR_DES_AVAIL_AES 0x33 /* AES (AT&T) available */ - unsigned char mmr_des_io_invert; /* des I/O invert register */ - unsigned char mmr_unused1[5]; /* unused */ - unsigned char mmr_dce_status; /* DCE status */ -#define MMR_DCE_STATUS_RX_BUSY 0x01 /* receiver busy */ -#define MMR_DCE_STATUS_LOOPT_IND 0x02 /* loop test indicated */ -#define MMR_DCE_STATUS_TX_BUSY 0x04 /* transmitter on */ -#define MMR_DCE_STATUS_JBR_EXPIRED 0x08 /* jabber timer expired */ -#define MMR_DCE_STATUS 0x0F /* mask to get the bits */ - unsigned char mmr_dsp_id; /* DSP ID (AA = Daedalus rev A) */ - unsigned char mmr_unused2[2]; /* unused */ - unsigned char mmr_correct_nwid_l; /* # of correct NWIDs rxd (low) */ - unsigned char mmr_correct_nwid_h; /* # of correct NWIDs rxd (high) */ - /* Warning: read high-order octet first! */ - unsigned char mmr_wrong_nwid_l; /* # of wrong NWIDs rxd (low) */ - unsigned char mmr_wrong_nwid_h; /* # of wrong NWIDs rxd (high) */ - unsigned char mmr_thr_pre_set; /* level threshold preset */ -#define MMR_THR_PRE_SET 0x3F /* level threshold preset */ -#define MMR_THR_PRE_SET_CUR 0x80 /* Current signal above it */ - unsigned char mmr_signal_lvl; /* signal level */ -#define MMR_SIGNAL_LVL 0x3F /* signal level */ -#define MMR_SIGNAL_LVL_VALID 0x80 /* Updated since last read */ - unsigned char mmr_silence_lvl; /* silence level (noise) */ -#define MMR_SILENCE_LVL 0x3F /* silence level */ -#define MMR_SILENCE_LVL_VALID 0x80 /* Updated since last read */ - unsigned char mmr_sgnl_qual; /* signal quality */ -#define MMR_SGNL_QUAL 0x0F /* signal quality */ -#define MMR_SGNL_QUAL_ANT 0x80 /* current antenna used */ - unsigned char mmr_netw_id_l; /* NWID low order byte (?) */ - unsigned char mmr_unused3[3]; /* unused */ - - /* 2.0 Hardware extension - frequency selection support */ - unsigned char mmr_fee_status; /* Status of frequency EEPROM */ -#define MMR_FEE_STATUS_ID 0xF0 /* Modem revision ID */ -#define MMR_FEE_STATUS_DWLD 0x08 /* Download in progress */ -#define MMR_FEE_STATUS_BUSY 0x04 /* EEPROM busy */ - unsigned char mmr_unused4[1]; /* unused */ - unsigned char mmr_fee_data_l; /* Read data from EEPROM (low) */ - unsigned char mmr_fee_data_h; /* Read data from EEPROM (high) */ -} __attribute__ ((packed)); - -#define MMR_SIZE 36 - -#define mmroff(p, f) (unsigned short)((void *)(&((mmr_t *)((void *)0 + (p)))->f) - (void *)0) - -/* Make the two above structures one */ -typedef union mm_t { - struct mmw_t w; /* Write to the mmc */ - struct mmr_t r; /* Read from the mmc */ -} mm_t; - -#endif /* _WAVELAN_H */ - -/* - * This software may only be used and distributed - * according to the terms of the GNU General Public License. - * - * For more details, see wavelan.c. - */ diff --git a/drivers/staging/wavelan/wavelan.p.h b/drivers/staging/wavelan/wavelan.p.h deleted file mode 100644 index d5f322c68d05..000000000000 --- a/drivers/staging/wavelan/wavelan.p.h +++ /dev/null @@ -1,694 +0,0 @@ -/* - * WaveLAN ISA driver - * - * Jean II - HPLB '96 - * - * Reorganisation and extension of the driver. - * - * This file contains all definitions and declarations necessary for the - * WaveLAN ISA driver. This file is a private header, so it should - * be included only in wavelan.c! - */ - -#ifndef WAVELAN_P_H -#define WAVELAN_P_H - -/************************** DOCUMENTATION ***************************/ -/* - * This driver provides a Linux interface to the WaveLAN ISA hardware. - * The WaveLAN is a product of Lucent (http://www.wavelan.com/). - * This division was formerly part of NCR and then AT&T. - * WaveLANs are also distributed by DEC (RoamAbout DS) and Digital Ocean. - * - * To learn how to use this driver, read the NET3 HOWTO. - * If you want to exploit the many other functionalities, read the comments - * in the code. - * - * This driver is the result of the effort of many people (see below). - */ - -/* ------------------------ SPECIFIC NOTES ------------------------ */ -/* - * Web page - * -------- - * I try to maintain a web page with the Wireless LAN Howto at : - * http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Wavelan.html - * - * SMP - * --- - * We now are SMP compliant (I eventually fixed the remaining bugs). - * The driver has been tested on a dual P6-150 and survived my usual - * set of torture tests. - * Anyway, I spent enough time chasing interrupt re-entrancy during - * errors or reconfigure, and I designed the locked/unlocked sections - * of the driver with great care, and with the recent addition of - * the spinlock (thanks to the new API), we should be quite close to - * the truth. - * The SMP/IRQ locking is quite coarse and conservative (i.e. not fast), - * but better safe than sorry (especially at 2 Mb/s ;-). - * - * I have also looked into disabling only our interrupt on the card - * (via HACR) instead of all interrupts in the processor (via cli), - * so that other driver are not impacted, and it look like it's - * possible, but it's very tricky to do right (full of races). As - * the gain would be mostly for SMP systems, it can wait... - * - * Debugging and options - * --------------------- - * You will find below a set of '#define" allowing a very fine control - * on the driver behaviour and the debug messages printed. - * The main options are : - * o SET_PSA_CRC, to have your card correctly recognised by - * an access point and the Point-to-Point diagnostic tool. - * o USE_PSA_CONFIG, to read configuration from the PSA (EEprom) - * (otherwise we always start afresh with some defaults) - * - * wavelan.o is too darned big - * --------------------------- - * That's true! There is a very simple way to reduce the driver - * object by 33%! Comment out the following line: - * #include - * Other compile options can also reduce the size of it... - * - * MAC address and hardware detection: - * ----------------------------------- - * The detection code for the WaveLAN checks that the first three - * octets of the MAC address fit the company code. This type of - * detection works well for AT&T cards (because the AT&T code is - * hardcoded in wavelan.h), but of course will fail for other - * manufacturers. - * - * If you are sure that your card is derived from the WaveLAN, - * here is the way to configure it: - * 1) Get your MAC address - * a) With your card utilities (wfreqsel, instconf, etc.) - * b) With the driver: - * o compile the kernel with DEBUG_CONFIG_INFO enabled - * o Boot and look the card messages - * 2) Set your MAC code (3 octets) in MAC_ADDRESSES[][3] (wavelan.h) - * 3) Compile and verify - * 4) Send me the MAC code. I will include it in the next version. - * - */ - -/* --------------------- WIRELESS EXTENSIONS --------------------- */ -/* - * This driver is the first to support "wireless extensions". - * This set of extensions provides a standard way to control the wireless - * characteristics of the hardware. Applications such as mobile IP may - * take advantage of it. - * - * It might be a good idea as well to fetch the wireless tools to - * configure the device and play a bit. - */ - -/* ---------------------------- FILES ---------------------------- */ -/* - * wavelan.c: actual code for the driver: C functions - * - * wavelan.p.h: private header: local types and variables for driver - * - * wavelan.h: description of the hardware interface and structs - * - * i82586.h: description of the Ethernet controller - */ - -/* --------------------------- HISTORY --------------------------- */ -/* - * This is based on information in the drivers' headers. It may not be - * accurate, and I guarantee only my best effort. - * - * The history of the WaveLAN drivers is as complicated as the history of - * the WaveLAN itself (NCR -> AT&T -> Lucent). - * - * It all started with Anders Klemets - * writing a WaveLAN ISA driver for the Mach microkernel. Girish - * Welling had also worked on it. - * Keith Moore modified this for the PCMCIA hardware. - * - * Robert Morris ported these two drivers to BSDI - * and added specific PCMCIA support (there is currently no equivalent - * of the PCMCIA package under BSD). - * - * Jim Binkley ported both BSDI drivers to FreeBSD. - * - * Bruce Janson ported the BSDI ISA driver to Linux. - * - * Anthony D. Joseph started to modify Bruce's driver - * (with help of the BSDI PCMCIA driver) for PCMCIA. - * Yunzhou Li finished this work. - * Joe Finney patched the driver to start - * 2.00 cards correctly (2.4 GHz with frequency selection). - * David Hinds integrated the whole in his - * PCMCIA package (and bug corrections). - * - * I (Jean Tourrilhes - jt@hplb.hpl.hp.com) then started to make some - * patches to the PCMCIA driver. Later, I added code in the ISA driver - * for Wireless Extensions and full support of frequency selection - * cards. Then, I did the same to the PCMCIA driver, and did some - * reorganisation. Finally, I came back to the ISA driver to - * upgrade it at the same level as the PCMCIA one and reorganise - * the code. - * Loeke Brederveld from Lucent has given me - * much needed information on the WaveLAN hardware. - */ - -/* The original copyrights and literature mention others' names and - * credits. I don't know what their part in this development was. - */ - -/* By the way, for the copyright and legal stuff: - * almost everybody wrote code under the GNU or BSD license (or similar), - * and want their original copyright to remain somewhere in the - * code (for myself, I go with the GPL). - * Nobody wants to take responsibility for anything, except the fame. - */ - -/* --------------------------- CREDITS --------------------------- */ -/* - * This software was developed as a component of the - * Linux operating system. - * It is based on other device drivers and information - * either written or supplied by: - * Ajay Bakre , - * Donald Becker , - * Loeke Brederveld , - * Brent Elphick , - * Anders Klemets , - * Vladimir V. Kolpakov , - * Marc Meertens , - * Pauline Middelink , - * Robert Morris , - * Jean Tourrilhes , - * Girish Welling , - * Clark Woodworth - * Yongguang Zhang - * - * Thanks go also to: - * James Ashton , - * Alan Cox , - * Allan Creighton , - * Matthew Geier , - * Remo di Giovanni , - * Eckhard Grah , - * Vipul Gupta , - * Mark Hagan , - * Tim Nicholson , - * Ian Parkin , - * John Rosenberg , - * George Rossi , - * Arthur Scott , - * Stanislav Sinyagin - * and Peter Storey for their assistance and advice. - * - * Additional Credits: - * - * My development has been done initially under Debian 1.1 (Linux 2.0.x) - * and now under Debian 2.2, initially with an HP Vectra XP/60, and now - * an HP Vectra XP/90. - * - */ - -/* ------------------------- IMPROVEMENTS ------------------------- */ -/* - * I proudly present: - * - * Changes made in first pre-release: - * ---------------------------------- - * - reorganisation of the code, function name change - * - creation of private header (wavelan.p.h) - * - reorganised debug messages - * - more comments, history, etc. - * - mmc_init: configure the PSA if not done - * - mmc_init: correct default value of level threshold for PCMCIA - * - mmc_init: 2.00 detection better code for 2.00 initialization - * - better info at startup - * - IRQ setting (note: this setting is permanent) - * - watchdog: change strategy (and solve module removal problems) - * - add wireless extensions (ioctl and get_wireless_stats) - * get/set nwid/frequency on fly, info for /proc/net/wireless - * - more wireless extensions: SETSPY and GETSPY - * - make wireless extensions optional - * - private ioctl to set/get quality and level threshold, histogram - * - remove /proc/net/wavelan - * - suppress useless stuff from lp (net_local) - * - kernel 2.1 support (copy_to/from_user instead of memcpy_to/fromfs) - * - add message level (debug stuff in /var/adm/debug and errors not - * displayed at console and still in /var/adm/messages) - * - multi device support - * - start fixing the probe (init code) - * - more inlines - * - man page - * - many other minor details and cleanups - * - * Changes made in second pre-release: - * ----------------------------------- - * - clean up init code (probe and module init) - * - better multiple device support (module) - * - name assignment (module) - * - * Changes made in third pre-release: - * ---------------------------------- - * - be more conservative on timers - * - preliminary support for multicast (I still lack some details) - * - * Changes made in fourth pre-release: - * ----------------------------------- - * - multicast (revisited and finished) - * - avoid reset in set_multicast_list (a really big hack) - * if somebody could apply this code for other i82586 based drivers - * - share onboard memory 75% RU and 25% CU (instead of 50/50) - * - * Changes made for release in 2.1.15: - * ----------------------------------- - * - change the detection code for multi manufacturer code support - * - * Changes made for release in 2.1.17: - * ----------------------------------- - * - update to wireless extensions changes - * - silly bug in card initial configuration (psa_conf_status) - * - * Changes made for release in 2.1.27 & 2.0.30: - * -------------------------------------------- - * - small bug in debug code (probably not the last one...) - * - remove extern keyword for wavelan_probe() - * - level threshold is now a standard wireless extension (version 4 !) - * - modules parameters types (new module interface) - * - * Changes made for release in 2.1.36: - * ----------------------------------- - * - byte count stats (courtesy of David Hinds) - * - remove dev_tint stuff (courtesy of David Hinds) - * - encryption setting from Brent Elphick (thanks a lot!) - * - 'ioaddr' to 'u_long' for the Alpha (thanks to Stanislav Sinyagin) - * - * Other changes (not by me) : - * ------------------------- - * - Spelling and gramar "rectification". - * - * Changes made for release in 2.0.37 & 2.2.2 : - * ------------------------------------------ - * - Correct status in /proc/net/wireless - * - Set PSA CRC to make PtP diagnostic tool happy (Bob Gray) - * - Module init code don't fail if we found at least one card in - * the address list (Karlis Peisenieks) - * - Missing parenthesis (Christopher Peterson) - * - Correct i82586 configuration parameters - * - Encryption initialisation bug (Robert McCormack) - * - New mac addresses detected in the probe - * - Increase watchdog for busy environments - * - * Changes made for release in 2.0.38 & 2.2.7 : - * ------------------------------------------ - * - Correct the reception logic to better report errors and avoid - * sending bogus packet up the stack - * - Delay RU config to avoid corrupting first received packet - * - Change config completion code (to actually check something) - * - Avoid reading out of bound in skbuf to transmit - * - Rectify a lot of (useless) debugging code - * - Change the way to `#ifdef SET_PSA_CRC' - * - * Changes made for release in 2.2.11 & 2.3.13 : - * ------------------------------------------- - * - Change e-mail and web page addresses - * - Watchdog timer is now correctly expressed in HZ, not in jiffies - * - Add channel number to the list of frequencies in range - * - Add the (short) list of bit-rates in range - * - Developp a new sensitivity... (sens.value & sens.fixed) - * - * Changes made for release in 2.2.14 & 2.3.23 : - * ------------------------------------------- - * - Fix check for root permission (break instead of exit) - * - New nwid & encoding setting (Wireless Extension 9) - * - * Changes made for release in 2.3.49 : - * ---------------------------------- - * - Indentation reformating (Alan) - * - Update to new network API (softnet - 2.3.43) : - * o replace dev->tbusy (Alan) - * o replace dev->tstart (Alan) - * o remove dev->interrupt (Alan) - * o add SMP locking via spinlock in splxx (me) - * o add spinlock in interrupt handler (me) - * o use kernel watchdog instead of ours (me) - * o increase watchdog timeout (kernel is more sensitive) (me) - * o verify that all the changes make sense and work (me) - * - Fixup a potential gotcha when reconfiguring and thighten a bit - * the interactions with Tx queue. - * - * Changes made for release in 2.4.0 : - * --------------------------------- - * - Fix spinlock stupid bugs that I left in. The driver is now SMP - * compliant and doesn't lockup at startup. - * - * Changes made for release in 2.5.2 : - * --------------------------------- - * - Use new driver API for Wireless Extensions : - * o got rid of wavelan_ioctl() - * o use a bunch of iw_handler instead - * - * Changes made for release in 2.5.35 : - * ---------------------------------- - * - Set dev->trans_start to avoid filling the logs - * - Handle better spurious/bogus interrupt - * - Avoid deadlocks in mmc_out()/mmc_in() - * - * Wishes & dreams: - * ---------------- - * - roaming (see Pcmcia driver) - */ - -/***************************** INCLUDES *****************************/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include /* Wireless extensions */ -#include /* Wireless handlers */ - -/* WaveLAN declarations */ -#include "i82586.h" -#include "wavelan.h" - -/************************** DRIVER OPTIONS **************************/ -/* - * `#define' or `#undef' the following constant to change the behaviour - * of the driver... - */ -#undef SET_PSA_CRC /* Calculate and set the CRC on PSA (slower) */ -#define USE_PSA_CONFIG /* Use info from the PSA. */ -#undef EEPROM_IS_PROTECTED /* doesn't seem to be necessary */ -#define MULTICAST_AVOID /* Avoid extra multicast (I'm sceptical). */ -#undef SET_MAC_ADDRESS /* Experimental */ - -/* Warning: this stuff will slow down the driver. */ -#define WIRELESS_SPY /* Enable spying addresses. */ -#undef HISTOGRAM /* Enable histogram of signal level. */ - -/****************************** DEBUG ******************************/ - -#undef DEBUG_MODULE_TRACE /* module insertion/removal */ -#undef DEBUG_CALLBACK_TRACE /* calls made by Linux */ -#undef DEBUG_INTERRUPT_TRACE /* calls to handler */ -#undef DEBUG_INTERRUPT_INFO /* type of interrupt and so on */ -#define DEBUG_INTERRUPT_ERROR /* problems */ -#undef DEBUG_CONFIG_TRACE /* Trace the config functions. */ -#undef DEBUG_CONFIG_INFO /* what's going on */ -#define DEBUG_CONFIG_ERROR /* errors on configuration */ -#undef DEBUG_TX_TRACE /* transmission calls */ -#undef DEBUG_TX_INFO /* header of the transmitted packet */ -#undef DEBUG_TX_FAIL /* Normal failure conditions */ -#define DEBUG_TX_ERROR /* Unexpected conditions */ -#undef DEBUG_RX_TRACE /* transmission calls */ -#undef DEBUG_RX_INFO /* header of the received packet */ -#undef DEBUG_RX_FAIL /* Normal failure conditions */ -#define DEBUG_RX_ERROR /* Unexpected conditions */ - -#undef DEBUG_PACKET_DUMP /* Dump packet on the screen if defined to 32. */ -#undef DEBUG_IOCTL_TRACE /* misc. call by Linux */ -#undef DEBUG_IOCTL_INFO /* various debugging info */ -#define DEBUG_IOCTL_ERROR /* what's going wrong */ -#define DEBUG_BASIC_SHOW /* Show basic startup info. */ -#undef DEBUG_VERSION_SHOW /* Print version info. */ -#undef DEBUG_PSA_SHOW /* Dump PSA to screen. */ -#undef DEBUG_MMC_SHOW /* Dump mmc to screen. */ -#undef DEBUG_SHOW_UNUSED /* Show unused fields too. */ -#undef DEBUG_I82586_SHOW /* Show i82586 status. */ -#undef DEBUG_DEVICE_SHOW /* Show device parameters. */ - -/************************ CONSTANTS & MACROS ************************/ - -#ifdef DEBUG_VERSION_SHOW -static const char *version = "wavelan.c : v24 (SMP + wireless extensions) 11/12/01\n"; -#endif - -/* Watchdog temporisation */ -#define WATCHDOG_JIFFIES (512*HZ/100) - -/* ------------------------ PRIVATE IOCTL ------------------------ */ - -#define SIOCSIPQTHR SIOCIWFIRSTPRIV /* Set quality threshold */ -#define SIOCGIPQTHR (SIOCIWFIRSTPRIV + 1) /* Get quality threshold */ - -#define SIOCSIPHISTO (SIOCIWFIRSTPRIV + 2) /* Set histogram ranges */ -#define SIOCGIPHISTO (SIOCIWFIRSTPRIV + 3) /* Get histogram values */ - -/****************************** TYPES ******************************/ - -/* Shortcuts */ -typedef struct iw_statistics iw_stats; -typedef struct iw_quality iw_qual; -typedef struct iw_freq iw_freq; -typedef struct net_local net_local; -typedef struct timer_list timer_list; - -/* Basic types */ -typedef u_char mac_addr[WAVELAN_ADDR_SIZE]; /* Hardware address */ - -/* - * Static specific data for the interface. - * - * For each network interface, Linux keeps data in two structures: "device" - * keeps the generic data (same format for everybody) and "net_local" keeps - * additional specific data. - */ -struct net_local { - net_local *next; /* linked list of the devices */ - struct net_device *dev; /* reverse link */ - spinlock_t spinlock; /* Serialize access to the hardware (SMP) */ - int nresets; /* number of hardware resets */ - u_char reconfig_82586; /* We need to reconfigure the controller. */ - u_char promiscuous; /* promiscuous mode */ - int mc_count; /* number of multicast addresses */ - u_short hacr; /* current host interface state */ - - int tx_n_in_use; - u_short rx_head; - u_short rx_last; - u_short tx_first_free; - u_short tx_first_in_use; - - iw_stats wstats; /* Wireless-specific statistics */ - - struct iw_spy_data spy_data; - struct iw_public_data wireless_data; - -#ifdef HISTOGRAM - int his_number; /* number of intervals */ - u_char his_range[16]; /* boundaries of interval ]n-1; n] */ - u_long his_sum[16]; /* sum in interval */ -#endif /* HISTOGRAM */ -}; - -/**************************** PROTOTYPES ****************************/ - -/* ----------------------- MISC. SUBROUTINES ------------------------ */ -static u_char - wv_irq_to_psa(int); -static int - wv_psa_to_irq(u_char); -/* ------------------- HOST ADAPTER SUBROUTINES ------------------- */ -static inline u_short /* data */ - hasr_read(u_long); /* Read the host interface: base address */ -static inline void - hacr_write(u_long, /* Write to host interface: base address */ - u_short), /* data */ - hacr_write_slow(u_long, - u_short), - set_chan_attn(u_long, /* ioaddr */ - u_short), /* hacr */ - wv_hacr_reset(u_long), /* ioaddr */ - wv_16_off(u_long, /* ioaddr */ - u_short), /* hacr */ - wv_16_on(u_long, /* ioaddr */ - u_short), /* hacr */ - wv_ints_off(struct net_device *), - wv_ints_on(struct net_device *); -/* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */ -static void - psa_read(u_long, /* Read the Parameter Storage Area. */ - u_short, /* hacr */ - int, /* offset in PSA */ - u_char *, /* buffer to fill */ - int), /* size to read */ - psa_write(u_long, /* Write to the PSA. */ - u_short, /* hacr */ - int, /* offset in PSA */ - u_char *, /* buffer in memory */ - int); /* length of buffer */ -static inline void - mmc_out(u_long, /* Write 1 byte to the Modem Manag Control. */ - u_short, - u_char), - mmc_write(u_long, /* Write n bytes to the MMC. */ - u_char, - u_char *, - int); -static inline u_char /* Read 1 byte from the MMC. */ - mmc_in(u_long, - u_short); -static inline void - mmc_read(u_long, /* Read n bytes from the MMC. */ - u_char, - u_char *, - int), - fee_wait(u_long, /* Wait for frequency EEPROM: base address */ - int, /* base delay to wait for */ - int); /* time to wait */ -static void - fee_read(u_long, /* Read the frequency EEPROM: base address */ - u_short, /* destination offset */ - u_short *, /* data buffer */ - int); /* number of registers */ -/* ---------------------- I82586 SUBROUTINES ----------------------- */ -static /*inline*/ void - obram_read(u_long, /* ioaddr */ - u_short, /* o */ - u_char *, /* b */ - int); /* n */ -static inline void - obram_write(u_long, /* ioaddr */ - u_short, /* o */ - u_char *, /* b */ - int); /* n */ -static void - wv_ack(struct net_device *); -static inline int - wv_synchronous_cmd(struct net_device *, - const char *), - wv_config_complete(struct net_device *, - u_long, - net_local *); -static int - wv_complete(struct net_device *, - u_long, - net_local *); -static inline void - wv_82586_reconfig(struct net_device *); -/* ------------------- DEBUG & INFO SUBROUTINES ------------------- */ -#ifdef DEBUG_I82586_SHOW -static void - wv_scb_show(unsigned short); -#endif -static inline void - wv_init_info(struct net_device *); /* display startup info */ -/* ------------------- IOCTL, STATS & RECONFIG ------------------- */ -static iw_stats * - wavelan_get_wireless_stats(struct net_device *); -static void - wavelan_set_multicast_list(struct net_device *); -/* ----------------------- PACKET RECEPTION ----------------------- */ -static inline void - wv_packet_read(struct net_device *, /* Read a packet from a frame. */ - u_short, - int), - wv_receive(struct net_device *); /* Read all packets waiting. */ -/* --------------------- PACKET TRANSMISSION --------------------- */ -static inline int - wv_packet_write(struct net_device *, /* Write a packet to the Tx buffer. */ - void *, - short); -static netdev_tx_t - wavelan_packet_xmit(struct sk_buff *, /* Send a packet. */ - struct net_device *); -/* -------------------- HARDWARE CONFIGURATION -------------------- */ -static inline int - wv_mmc_init(struct net_device *), /* Initialize the modem. */ - wv_ru_start(struct net_device *), /* Start the i82586 receiver unit. */ - wv_cu_start(struct net_device *), /* Start the i82586 command unit. */ - wv_82586_start(struct net_device *); /* Start the i82586. */ -static void - wv_82586_config(struct net_device *); /* Configure the i82586. */ -static inline void - wv_82586_stop(struct net_device *); -static int - wv_hw_reset(struct net_device *), /* Reset the WaveLAN hardware. */ - wv_check_ioaddr(u_long, /* ioaddr */ - u_char *); /* mac address (read) */ -/* ---------------------- INTERRUPT HANDLING ---------------------- */ -static irqreturn_t - wavelan_interrupt(int, /* interrupt handler */ - void *); -static void - wavelan_watchdog(struct net_device *); /* transmission watchdog */ -/* ------------------- CONFIGURATION CALLBACKS ------------------- */ -static int - wavelan_open(struct net_device *), /* Open the device. */ - wavelan_close(struct net_device *), /* Close the device. */ - wavelan_config(struct net_device *, unsigned short);/* Configure one device. */ -extern struct net_device *wavelan_probe(int unit); /* See Space.c. */ - -/**************************** VARIABLES ****************************/ - -/* - * This is the root of the linked list of WaveLAN drivers - * It is use to verify that we don't reuse the same base address - * for two different drivers and to clean up when removing the module. - */ -static net_local * wavelan_list = (net_local *) NULL; - -/* - * This table is used to translate the PSA value to IRQ number - * and vice versa. - */ -static u_char irqvals[] = { - 0, 0, 0, 0x01, - 0x02, 0x04, 0, 0x08, - 0, 0, 0x10, 0x20, - 0x40, 0, 0, 0x80, -}; - -/* - * Table of the available I/O addresses (base addresses) for WaveLAN - */ -static unsigned short iobase[] = { -#if 0 - /* Leave out 0x3C0 for now -- seems to clash with some video - * controllers. - * Leave out the others too -- we will always use 0x390 and leave - * 0x300 for the Ethernet device. - * Jean II: 0x3E0 is fine as well. - */ - 0x300, 0x390, 0x3E0, 0x3C0 -#endif /* 0 */ - 0x390, 0x3E0 -}; - -#ifdef MODULE -/* Parameters set by insmod */ -static int io[4]; -static int irq[4]; -static char *name[4]; -module_param_array(io, int, NULL, 0); -module_param_array(irq, int, NULL, 0); -module_param_array(name, charp, NULL, 0); - -MODULE_PARM_DESC(io, "WaveLAN I/O base address(es),required"); -MODULE_PARM_DESC(irq, "WaveLAN IRQ number(s)"); -MODULE_PARM_DESC(name, "WaveLAN interface neme(s)"); -#endif /* MODULE */ - -#endif /* WAVELAN_P_H */ diff --git a/drivers/staging/wavelan/wavelan_cs.c b/drivers/staging/wavelan/wavelan_cs.c deleted file mode 100644 index 04f691d127b4..000000000000 --- a/drivers/staging/wavelan/wavelan_cs.c +++ /dev/null @@ -1,4610 +0,0 @@ -/* - * Wavelan Pcmcia driver - * - * Jean II - HPLB '96 - * - * Reorganisation and extension of the driver. - * Original copyright follow. See wavelan_cs.p.h for details. - * - * This code is derived from Anthony D. Joseph's code and all the changes here - * are also under the original copyright below. - * - * This code supports version 2.00 of WaveLAN/PCMCIA cards (2.4GHz), and - * can work on Linux 2.0.36 with support of David Hinds' PCMCIA Card Services - * - * Joe Finney (joe@comp.lancs.ac.uk) at Lancaster University in UK added - * critical code in the routine to initialize the Modem Management Controller. - * - * Thanks to Alan Cox and Bruce Janson for their advice. - * - * -- Yunzhou Li (scip4166@nus.sg) - * -#ifdef WAVELAN_ROAMING - * Roaming support added 07/22/98 by Justin Seger (jseger@media.mit.edu) - * based on patch by Joe Finney from Lancaster University. -#endif - * - * Lucent (formerly AT&T GIS, formerly NCR) WaveLAN PCMCIA card: An - * Ethernet-like radio transceiver controlled by an Intel 82593 coprocessor. - * - * A non-shared memory PCMCIA ethernet driver for linux - * - * ISA version modified to support PCMCIA by Anthony Joseph (adj@lcs.mit.edu) - * - * - * Joseph O'Sullivan & John Langford (josullvn@cs.cmu.edu & jcl@cs.cmu.edu) - * - * Apr 2 '98 made changes to bring the i82593 control/int handling in line - * with offical specs... - * - **************************************************************************** - * Copyright 1995 - * Anthony D. Joseph - * Massachusetts Institute of Technology - * - * Permission to use, copy, modify, and distribute this program - * for any purpose and without fee is hereby granted, provided - * that this copyright and permission notice appear on all copies - * and supporting documentation, the name of M.I.T. not be used - * in advertising or publicity pertaining to distribution of the - * program without specific prior permission, and notice be given - * in supporting documentation that copying and distribution is - * by permission of M.I.T. M.I.T. makes no representations about - * the suitability of this software for any purpose. It is pro- - * vided "as is" without express or implied warranty. - **************************************************************************** - * - */ - -/* Do *NOT* add other headers here, you are guaranteed to be wrong - Jean II */ -#include "wavelan_cs.p.h" /* Private header */ - -#ifdef WAVELAN_ROAMING -static void wl_cell_expiry(unsigned long data); -static void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp); -static void wv_nwid_filter(unsigned char mode, net_local *lp); -#endif /* WAVELAN_ROAMING */ - -/************************* MISC SUBROUTINES **************************/ -/* - * Subroutines which won't fit in one of the following category - * (wavelan modem or i82593) - */ - -/******************* MODEM MANAGEMENT SUBROUTINES *******************/ -/* - * Useful subroutines to manage the modem of the wavelan - */ - -/*------------------------------------------------------------------*/ -/* - * Read from card's Host Adaptor Status Register. - */ -static inline u_char -hasr_read(u_long base) -{ - return(inb(HASR(base))); -} /* hasr_read */ - -/*------------------------------------------------------------------*/ -/* - * Write to card's Host Adapter Command Register. - */ -static inline void -hacr_write(u_long base, - u_char hacr) -{ - outb(hacr, HACR(base)); -} /* hacr_write */ - -/*------------------------------------------------------------------*/ -/* - * Write to card's Host Adapter Command Register. Include a delay for - * those times when it is needed. - */ -static void -hacr_write_slow(u_long base, - u_char hacr) -{ - hacr_write(base, hacr); - /* delay might only be needed sometimes */ - mdelay(1); -} /* hacr_write_slow */ - -/*------------------------------------------------------------------*/ -/* - * Read the Parameter Storage Area from the WaveLAN card's memory - */ -static void -psa_read(struct net_device * dev, - int o, /* offset in PSA */ - u_char * b, /* buffer to fill */ - int n) /* size to read */ -{ - net_local *lp = netdev_priv(dev); - u_char __iomem *ptr = lp->mem + PSA_ADDR + (o << 1); - - while(n-- > 0) - { - *b++ = readb(ptr); - /* Due to a lack of address decode pins, the WaveLAN PCMCIA card - * only supports reading even memory addresses. That means the - * increment here MUST be two. - * Because of that, we can't use memcpy_fromio()... - */ - ptr += 2; - } -} /* psa_read */ - -/*------------------------------------------------------------------*/ -/* - * Write the Parameter Storage Area to the WaveLAN card's memory - */ -static void -psa_write(struct net_device * dev, - int o, /* Offset in psa */ - u_char * b, /* Buffer in memory */ - int n) /* Length of buffer */ -{ - net_local *lp = netdev_priv(dev); - u_char __iomem *ptr = lp->mem + PSA_ADDR + (o << 1); - int count = 0; - unsigned int base = dev->base_addr; - /* As there seem to have no flag PSA_BUSY as in the ISA model, we are - * oblige to verify this address to know when the PSA is ready... */ - volatile u_char __iomem *verify = lp->mem + PSA_ADDR + - (psaoff(0, psa_comp_number) << 1); - - /* Authorize writing to PSA */ - hacr_write(base, HACR_PWR_STAT | HACR_ROM_WEN); - - while(n-- > 0) - { - /* write to PSA */ - writeb(*b++, ptr); - ptr += 2; - - /* I don't have the spec, so I don't know what the correct - * sequence to write is. This hack seem to work for me... */ - count = 0; - while((readb(verify) != PSA_COMP_PCMCIA_915) && (count++ < 100)) - mdelay(1); - } - - /* Put the host interface back in standard state */ - hacr_write(base, HACR_DEFAULT); -} /* psa_write */ - -#ifdef SET_PSA_CRC -/*------------------------------------------------------------------*/ -/* - * Calculate the PSA CRC - * Thanks to Valster, Nico for the code - * NOTE: By specifying a length including the CRC position the - * returned value should be zero. (i.e. a correct checksum in the PSA) - * - * The Windows drivers don't use the CRC, but the AP and the PtP tool - * depend on it. - */ -static u_short -psa_crc(unsigned char * psa, /* The PSA */ - int size) /* Number of short for CRC */ -{ - int byte_cnt; /* Loop on the PSA */ - u_short crc_bytes = 0; /* Data in the PSA */ - int bit_cnt; /* Loop on the bits of the short */ - - for(byte_cnt = 0; byte_cnt < size; byte_cnt++ ) - { - crc_bytes ^= psa[byte_cnt]; /* Its an xor */ - - for(bit_cnt = 1; bit_cnt < 9; bit_cnt++ ) - { - if(crc_bytes & 0x0001) - crc_bytes = (crc_bytes >> 1) ^ 0xA001; - else - crc_bytes >>= 1 ; - } - } - - return crc_bytes; -} /* psa_crc */ -#endif /* SET_PSA_CRC */ - -/*------------------------------------------------------------------*/ -/* - * update the checksum field in the Wavelan's PSA - */ -static void -update_psa_checksum(struct net_device * dev) -{ -#ifdef SET_PSA_CRC - psa_t psa; - u_short crc; - - /* read the parameter storage area */ - psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa)); - - /* update the checksum */ - crc = psa_crc((unsigned char *) &psa, - sizeof(psa) - sizeof(psa.psa_crc[0]) - sizeof(psa.psa_crc[1]) - - sizeof(psa.psa_crc_status)); - - psa.psa_crc[0] = crc & 0xFF; - psa.psa_crc[1] = (crc & 0xFF00) >> 8; - - /* Write it ! */ - psa_write(dev, (char *)&psa.psa_crc - (char *)&psa, - (unsigned char *)&psa.psa_crc, 2); - -#ifdef DEBUG_IOCTL_INFO - printk (KERN_DEBUG "%s: update_psa_checksum(): crc = 0x%02x%02x\n", - dev->name, psa.psa_crc[0], psa.psa_crc[1]); - - /* Check again (luxury !) */ - crc = psa_crc((unsigned char *) &psa, - sizeof(psa) - sizeof(psa.psa_crc_status)); - - if(crc != 0) - printk(KERN_WARNING "%s: update_psa_checksum(): CRC does not agree with PSA data (even after recalculating)\n", dev->name); -#endif /* DEBUG_IOCTL_INFO */ -#endif /* SET_PSA_CRC */ -} /* update_psa_checksum */ - -/*------------------------------------------------------------------*/ -/* - * Write 1 byte to the MMC. - */ -static void -mmc_out(u_long base, - u_short o, - u_char d) -{ - int count = 0; - - /* Wait for MMC to go idle */ - while((count++ < 100) && (inb(HASR(base)) & HASR_MMI_BUSY)) - udelay(10); - - outb((u_char)((o << 1) | MMR_MMI_WR), MMR(base)); - outb(d, MMD(base)); -} - -/*------------------------------------------------------------------*/ -/* - * Routine to write bytes to the Modem Management Controller. - * We start by the end because it is the way it should be ! - */ -static void -mmc_write(u_long base, - u_char o, - u_char * b, - int n) -{ - o += n; - b += n; - - while(n-- > 0 ) - mmc_out(base, --o, *(--b)); -} /* mmc_write */ - -/*------------------------------------------------------------------*/ -/* - * Read 1 byte from the MMC. - * Optimised version for 1 byte, avoid using memory... - */ -static u_char -mmc_in(u_long base, - u_short o) -{ - int count = 0; - - while((count++ < 100) && (inb(HASR(base)) & HASR_MMI_BUSY)) - udelay(10); - outb(o << 1, MMR(base)); /* Set the read address */ - - outb(0, MMD(base)); /* Required dummy write */ - - while((count++ < 100) && (inb(HASR(base)) & HASR_MMI_BUSY)) - udelay(10); - return (u_char) (inb(MMD(base))); /* Now do the actual read */ -} - -/*------------------------------------------------------------------*/ -/* - * Routine to read bytes from the Modem Management Controller. - * The implementation is complicated by a lack of address lines, - * which prevents decoding of the low-order bit. - * (code has just been moved in the above function) - * We start by the end because it is the way it should be ! - */ -static void -mmc_read(u_long base, - u_char o, - u_char * b, - int n) -{ - o += n; - b += n; - - while(n-- > 0) - *(--b) = mmc_in(base, --o); -} /* mmc_read */ - -/*------------------------------------------------------------------*/ -/* - * Get the type of encryption available... - */ -static inline int -mmc_encr(u_long base) /* i/o port of the card */ -{ - int temp; - - temp = mmc_in(base, mmroff(0, mmr_des_avail)); - if((temp != MMR_DES_AVAIL_DES) && (temp != MMR_DES_AVAIL_AES)) - return 0; - else - return temp; -} - -/*------------------------------------------------------------------*/ -/* - * Wait for the frequency EEprom to complete a command... - */ -static void -fee_wait(u_long base, /* i/o port of the card */ - int delay, /* Base delay to wait for */ - int number) /* Number of time to wait */ -{ - int count = 0; /* Wait only a limited time */ - - while((count++ < number) && - (mmc_in(base, mmroff(0, mmr_fee_status)) & MMR_FEE_STATUS_BUSY)) - udelay(delay); -} - -/*------------------------------------------------------------------*/ -/* - * Read bytes from the Frequency EEprom (frequency select cards). - */ -static void -fee_read(u_long base, /* i/o port of the card */ - u_short o, /* destination offset */ - u_short * b, /* data buffer */ - int n) /* number of registers */ -{ - b += n; /* Position at the end of the area */ - - /* Write the address */ - mmc_out(base, mmwoff(0, mmw_fee_addr), o + n - 1); - - /* Loop on all buffer */ - while(n-- > 0) - { - /* Write the read command */ - mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_READ); - - /* Wait until EEprom is ready (should be quick !) */ - fee_wait(base, 10, 100); - - /* Read the value */ - *--b = ((mmc_in(base, mmroff(0, mmr_fee_data_h)) << 8) | - mmc_in(base, mmroff(0, mmr_fee_data_l))); - } -} - - -/*------------------------------------------------------------------*/ -/* - * Write bytes from the Frequency EEprom (frequency select cards). - * This is a bit complicated, because the frequency eeprom has to - * be unprotected and the write enabled. - * Jean II - */ -static void -fee_write(u_long base, /* i/o port of the card */ - u_short o, /* destination offset */ - u_short * b, /* data buffer */ - int n) /* number of registers */ -{ - b += n; /* Position at the end of the area */ - -#ifdef EEPROM_IS_PROTECTED /* disabled */ -#ifdef DOESNT_SEEM_TO_WORK /* disabled */ - /* Ask to read the protected register */ - mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRREAD); - - fee_wait(base, 10, 100); - - /* Read the protected register */ - printk("Protected 2 : %02X-%02X\n", - mmc_in(base, mmroff(0, mmr_fee_data_h)), - mmc_in(base, mmroff(0, mmr_fee_data_l))); -#endif /* DOESNT_SEEM_TO_WORK */ - - /* Enable protected register */ - mmc_out(base, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN); - mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PREN); - - fee_wait(base, 10, 100); - - /* Unprotect area */ - mmc_out(base, mmwoff(0, mmw_fee_addr), o + n); - mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE); -#ifdef DOESNT_SEEM_TO_WORK /* disabled */ - /* Or use : */ - mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRCLEAR); -#endif /* DOESNT_SEEM_TO_WORK */ - - fee_wait(base, 10, 100); -#endif /* EEPROM_IS_PROTECTED */ - - /* Write enable */ - mmc_out(base, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN); - mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WREN); - - fee_wait(base, 10, 100); - - /* Write the EEprom address */ - mmc_out(base, mmwoff(0, mmw_fee_addr), o + n - 1); - - /* Loop on all buffer */ - while(n-- > 0) - { - /* Write the value */ - mmc_out(base, mmwoff(0, mmw_fee_data_h), (*--b) >> 8); - mmc_out(base, mmwoff(0, mmw_fee_data_l), *b & 0xFF); - - /* Write the write command */ - mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WRITE); - - /* Wavelan doc says : wait at least 10 ms for EEBUSY = 0 */ - mdelay(10); - fee_wait(base, 10, 100); - } - - /* Write disable */ - mmc_out(base, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_DS); - mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WDS); - - fee_wait(base, 10, 100); - -#ifdef EEPROM_IS_PROTECTED /* disabled */ - /* Reprotect EEprom */ - mmc_out(base, mmwoff(0, mmw_fee_addr), 0x00); - mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE); - - fee_wait(base, 10, 100); -#endif /* EEPROM_IS_PROTECTED */ -} - -/******************* WaveLAN Roaming routines... ********************/ - -#ifdef WAVELAN_ROAMING /* Conditional compile, see wavelan_cs.h */ - -static unsigned char WAVELAN_BEACON_ADDRESS[] = {0x09,0x00,0x0e,0x20,0x03,0x00}; - -static void wv_roam_init(struct net_device *dev) -{ - net_local *lp= netdev_priv(dev); - - /* Do not remove this unless you have a good reason */ - printk(KERN_NOTICE "%s: Warning, you have enabled roaming on" - " device %s !\n", dev->name, dev->name); - printk(KERN_NOTICE "Roaming is currently an experimental unsupported feature" - " of the Wavelan driver.\n"); - printk(KERN_NOTICE "It may work, but may also make the driver behave in" - " erratic ways or crash.\n"); - - lp->wavepoint_table.head=NULL; /* Initialise WavePoint table */ - lp->wavepoint_table.num_wavepoints=0; - lp->wavepoint_table.locked=0; - lp->curr_point=NULL; /* No default WavePoint */ - lp->cell_search=0; - - lp->cell_timer.data=(long)lp; /* Start cell expiry timer */ - lp->cell_timer.function=wl_cell_expiry; - lp->cell_timer.expires=jiffies+CELL_TIMEOUT; - add_timer(&lp->cell_timer); - - wv_nwid_filter(NWID_PROMISC,lp) ; /* Enter NWID promiscuous mode */ - /* to build up a good WavePoint */ - /* table... */ - printk(KERN_DEBUG "WaveLAN: Roaming enabled on device %s\n",dev->name); -} - -static void wv_roam_cleanup(struct net_device *dev) -{ - wavepoint_history *ptr,*old_ptr; - net_local *lp= netdev_priv(dev); - - printk(KERN_DEBUG "WaveLAN: Roaming Disabled on device %s\n",dev->name); - - /* Fixme : maybe we should check that the timer exist before deleting it */ - del_timer(&lp->cell_timer); /* Remove cell expiry timer */ - ptr=lp->wavepoint_table.head; /* Clear device's WavePoint table */ - while(ptr!=NULL) - { - old_ptr=ptr; - ptr=ptr->next; - wl_del_wavepoint(old_ptr,lp); - } -} - -/* Enable/Disable NWID promiscuous mode on a given device */ -static void wv_nwid_filter(unsigned char mode, net_local *lp) -{ - mm_t m; - unsigned long flags; - -#ifdef WAVELAN_ROAMING_DEBUG - printk(KERN_DEBUG "WaveLAN: NWID promisc %s, device %s\n",(mode==NWID_PROMISC) ? "on" : "off", lp->dev->name); -#endif - - /* Disable interrupts & save flags */ - spin_lock_irqsave(&lp->spinlock, flags); - - m.w.mmw_loopt_sel = (mode==NWID_PROMISC) ? MMW_LOOPT_SEL_DIS_NWID : 0x00; - mmc_write(lp->dev->base_addr, (char *)&m.w.mmw_loopt_sel - (char *)&m, (unsigned char *)&m.w.mmw_loopt_sel, 1); - - if(mode==NWID_PROMISC) - lp->cell_search=1; - else - lp->cell_search=0; - - /* ReEnable interrupts & restore flags */ - spin_unlock_irqrestore(&lp->spinlock, flags); -} - -/* Find a record in the WavePoint table matching a given NWID */ -static wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp) -{ - wavepoint_history *ptr=lp->wavepoint_table.head; - - while(ptr!=NULL){ - if(ptr->nwid==nwid) - return ptr; - ptr=ptr->next; - } - return NULL; -} - -/* Create a new wavepoint table entry */ -static wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_local* lp) -{ - wavepoint_history *new_wavepoint; - -#ifdef WAVELAN_ROAMING_DEBUG - printk(KERN_DEBUG "WaveLAN: New Wavepoint, NWID:%.4X\n",nwid); -#endif - - if(lp->wavepoint_table.num_wavepoints==MAX_WAVEPOINTS) - return NULL; - - new_wavepoint = kmalloc(sizeof(wavepoint_history),GFP_ATOMIC); - if(new_wavepoint==NULL) - return NULL; - - new_wavepoint->nwid=nwid; /* New WavePoints NWID */ - new_wavepoint->average_fast=0; /* Running Averages..*/ - new_wavepoint->average_slow=0; - new_wavepoint->qualptr=0; /* Start of ringbuffer */ - new_wavepoint->last_seq=seq-1; /* Last sequence no.seen */ - memset(new_wavepoint->sigqual,0,WAVEPOINT_HISTORY);/* Empty ringbuffer */ - - new_wavepoint->next=lp->wavepoint_table.head;/* Add to wavepoint table */ - new_wavepoint->prev=NULL; - - if(lp->wavepoint_table.head!=NULL) - lp->wavepoint_table.head->prev=new_wavepoint; - - lp->wavepoint_table.head=new_wavepoint; - - lp->wavepoint_table.num_wavepoints++; /* no. of visible wavepoints */ - - return new_wavepoint; -} - -/* Remove a wavepoint entry from WavePoint table */ -static void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp) -{ - if(wavepoint==NULL) - return; - - if(lp->curr_point==wavepoint) - lp->curr_point=NULL; - - if(wavepoint->prev!=NULL) - wavepoint->prev->next=wavepoint->next; - - if(wavepoint->next!=NULL) - wavepoint->next->prev=wavepoint->prev; - - if(lp->wavepoint_table.head==wavepoint) - lp->wavepoint_table.head=wavepoint->next; - - lp->wavepoint_table.num_wavepoints--; - kfree(wavepoint); -} - -/* Timer callback function - checks WavePoint table for stale entries */ -static void wl_cell_expiry(unsigned long data) -{ - net_local *lp=(net_local *)data; - wavepoint_history *wavepoint=lp->wavepoint_table.head,*old_point; - -#if WAVELAN_ROAMING_DEBUG > 1 - printk(KERN_DEBUG "WaveLAN: Wavepoint timeout, dev %s\n",lp->dev->name); -#endif - - if(lp->wavepoint_table.locked) - { -#if WAVELAN_ROAMING_DEBUG > 1 - printk(KERN_DEBUG "WaveLAN: Wavepoint table locked...\n"); -#endif - - lp->cell_timer.expires=jiffies+1; /* If table in use, come back later */ - add_timer(&lp->cell_timer); - return; - } - - while(wavepoint!=NULL) - { - if(time_after(jiffies, wavepoint->last_seen + CELL_TIMEOUT)) - { -#ifdef WAVELAN_ROAMING_DEBUG - printk(KERN_DEBUG "WaveLAN: Bye bye %.4X\n",wavepoint->nwid); -#endif - - old_point=wavepoint; - wavepoint=wavepoint->next; - wl_del_wavepoint(old_point,lp); - } - else - wavepoint=wavepoint->next; - } - lp->cell_timer.expires=jiffies+CELL_TIMEOUT; - add_timer(&lp->cell_timer); -} - -/* Update SNR history of a wavepoint */ -static void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsigned char seq) -{ - int i=0,num_missed=0,ptr=0; - int average_fast=0,average_slow=0; - - num_missed=(seq-wavepoint->last_seq)%WAVEPOINT_HISTORY;/* Have we missed - any beacons? */ - if(num_missed) - for(i=0;isigqual[wavepoint->qualptr++]=0; /* If so, enter them as 0's */ - wavepoint->qualptr %=WAVEPOINT_HISTORY; /* in the ringbuffer. */ - } - wavepoint->last_seen=jiffies; /* Add beacon to history */ - wavepoint->last_seq=seq; - wavepoint->sigqual[wavepoint->qualptr++]=sigqual; - wavepoint->qualptr %=WAVEPOINT_HISTORY; - ptr=(wavepoint->qualptr-WAVEPOINT_FAST_HISTORY+WAVEPOINT_HISTORY)%WAVEPOINT_HISTORY; - - for(i=0;isigqual[ptr++]; - ptr %=WAVEPOINT_HISTORY; - } - - average_slow=average_fast; - for(i=WAVEPOINT_FAST_HISTORY;isigqual[ptr++]; - ptr %=WAVEPOINT_HISTORY; - } - - wavepoint->average_fast=average_fast/WAVEPOINT_FAST_HISTORY; - wavepoint->average_slow=average_slow/WAVEPOINT_HISTORY; -} - -/* Perform a handover to a new WavePoint */ -static void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp) -{ - unsigned int base = lp->dev->base_addr; - mm_t m; - unsigned long flags; - - if(wavepoint==lp->curr_point) /* Sanity check... */ - { - wv_nwid_filter(!NWID_PROMISC,lp); - return; - } - -#ifdef WAVELAN_ROAMING_DEBUG - printk(KERN_DEBUG "WaveLAN: Doing handover to %.4X, dev %s\n",wavepoint->nwid,lp->dev->name); -#endif - - /* Disable interrupts & save flags */ - spin_lock_irqsave(&lp->spinlock, flags); - - m.w.mmw_netw_id_l = wavepoint->nwid & 0xFF; - m.w.mmw_netw_id_h = (wavepoint->nwid & 0xFF00) >> 8; - - mmc_write(base, (char *)&m.w.mmw_netw_id_l - (char *)&m, (unsigned char *)&m.w.mmw_netw_id_l, 2); - - /* ReEnable interrupts & restore flags */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - wv_nwid_filter(!NWID_PROMISC,lp); - lp->curr_point=wavepoint; -} - -/* Called when a WavePoint beacon is received */ -static void wl_roam_gather(struct net_device * dev, - u_char * hdr, /* Beacon header */ - u_char * stats) /* SNR, Signal quality - of packet */ -{ - wavepoint_beacon *beacon= (wavepoint_beacon *)hdr; /* Rcvd. Beacon */ - unsigned short nwid=ntohs(beacon->nwid); - unsigned short sigqual=stats[2] & MMR_SGNL_QUAL; /* SNR of beacon */ - wavepoint_history *wavepoint=NULL; /* WavePoint table entry */ - net_local *lp = netdev_priv(dev); /* Device info */ - -#ifdef I_NEED_THIS_FEATURE - /* Some people don't need this, some other may need it */ - nwid=nwid^ntohs(beacon->domain_id); -#endif - -#if WAVELAN_ROAMING_DEBUG > 1 - printk(KERN_DEBUG "WaveLAN: beacon, dev %s:\n",dev->name); - printk(KERN_DEBUG "Domain: %.4X NWID: %.4X SigQual=%d\n",ntohs(beacon->domain_id),nwid,sigqual); -#endif - - lp->wavepoint_table.locked=1; /* */ - - wavepoint=wl_roam_check(nwid,lp); /* Find WavePoint table entry */ - if(wavepoint==NULL) /* If no entry, Create a new one... */ - { - wavepoint=wl_new_wavepoint(nwid,beacon->seq,lp); - if(wavepoint==NULL) - goto out; - } - if(lp->curr_point==NULL) /* If this is the only WavePoint, */ - wv_roam_handover(wavepoint, lp); /* Jump on it! */ - - wl_update_history(wavepoint, sigqual, beacon->seq); /* Update SNR history - stats. */ - - if(lp->curr_point->average_slow < SEARCH_THRESH_LOW) /* If our current */ - if(!lp->cell_search) /* WavePoint is getting faint, */ - wv_nwid_filter(NWID_PROMISC,lp); /* start looking for a new one */ - - if(wavepoint->average_slow > - lp->curr_point->average_slow + WAVELAN_ROAMING_DELTA) - wv_roam_handover(wavepoint, lp); /* Handover to a better WavePoint */ - - if(lp->curr_point->average_slow > SEARCH_THRESH_HIGH) /* If our SNR is */ - if(lp->cell_search) /* getting better, drop out of cell search mode */ - wv_nwid_filter(!NWID_PROMISC,lp); - -out: - lp->wavepoint_table.locked=0; /* :-) */ -} - -/* Test this MAC frame a WavePoint beacon */ -static inline int WAVELAN_BEACON(unsigned char *data) -{ - wavepoint_beacon *beacon= (wavepoint_beacon *)data; - static const wavepoint_beacon beacon_template={0xaa,0xaa,0x03,0x08,0x00,0x0e,0x20,0x03,0x00}; - - if(memcmp(beacon,&beacon_template,9)==0) - return 1; - else - return 0; -} -#endif /* WAVELAN_ROAMING */ - -/************************ I82593 SUBROUTINES *************************/ -/* - * Useful subroutines to manage the Ethernet controller - */ - -/*------------------------------------------------------------------*/ -/* - * Routine to synchronously send a command to the i82593 chip. - * Should be called with interrupts disabled. - * (called by wv_packet_write(), wv_ru_stop(), wv_ru_start(), - * wv_82593_config() & wv_diag()) - */ -static int -wv_82593_cmd(struct net_device * dev, - char * str, - int cmd, - int result) -{ - unsigned int base = dev->base_addr; - int status; - int wait_completed; - long spin; - - /* Spin until the chip finishes executing its current command (if any) */ - spin = 1000; - do - { - /* Time calibration of the loop */ - udelay(10); - - /* Read the interrupt register */ - outb(OP0_NOP | CR0_STATUS_3, LCCR(base)); - status = inb(LCSR(base)); - } - while(((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE) && (spin-- > 0)); - - /* If the interrupt hasn't been posted */ - if (spin < 0) { -#ifdef DEBUG_INTERRUPT_ERROR - printk(KERN_INFO "wv_82593_cmd: %s timeout (previous command), status 0x%02x\n", - str, status); -#endif - return(FALSE); - } - - /* Issue the command to the controller */ - outb(cmd, LCCR(base)); - - /* If we don't have to check the result of the command - * Note : this mean that the irq handler will deal with that */ - if(result == SR0_NO_RESULT) - return(TRUE); - - /* We are waiting for command completion */ - wait_completed = TRUE; - - /* Busy wait while the LAN controller executes the command. */ - spin = 1000; - do - { - /* Time calibration of the loop */ - udelay(10); - - /* Read the interrupt register */ - outb(CR0_STATUS_0 | OP0_NOP, LCCR(base)); - status = inb(LCSR(base)); - - /* Check if there was an interrupt posted */ - if((status & SR0_INTERRUPT)) - { - /* Acknowledge the interrupt */ - outb(CR0_INT_ACK | OP0_NOP, LCCR(base)); - - /* Check if interrupt is a command completion */ - if(((status & SR0_BOTH_RX_TX) != SR0_BOTH_RX_TX) && - ((status & SR0_BOTH_RX_TX) != 0x0) && - !(status & SR0_RECEPTION)) - { - /* Signal command completion */ - wait_completed = FALSE; - } - else - { - /* Note : Rx interrupts will be handled later, because we can - * handle multiple Rx packets at once */ -#ifdef DEBUG_INTERRUPT_INFO - printk(KERN_INFO "wv_82593_cmd: not our interrupt\n"); -#endif - } - } - } - while(wait_completed && (spin-- > 0)); - - /* If the interrupt hasn't be posted */ - if(wait_completed) - { -#ifdef DEBUG_INTERRUPT_ERROR - printk(KERN_INFO "wv_82593_cmd: %s timeout, status 0x%02x\n", - str, status); -#endif - return(FALSE); - } - - /* Check the return code returned by the card (see above) against - * the expected return code provided by the caller */ - if((status & SR0_EVENT_MASK) != result) - { -#ifdef DEBUG_INTERRUPT_ERROR - printk(KERN_INFO "wv_82593_cmd: %s failed, status = 0x%x\n", - str, status); -#endif - return(FALSE); - } - - return(TRUE); -} /* wv_82593_cmd */ - -/*------------------------------------------------------------------*/ -/* - * This routine does a 593 op-code number 7, and obtains the diagnose - * status for the WaveLAN. - */ -static inline int -wv_diag(struct net_device * dev) -{ - return(wv_82593_cmd(dev, "wv_diag(): diagnose", - OP0_DIAGNOSE, SR0_DIAGNOSE_PASSED)); -} /* wv_diag */ - -/*------------------------------------------------------------------*/ -/* - * Routine to read len bytes from the i82593's ring buffer, starting at - * chip address addr. The results read from the chip are stored in buf. - * The return value is the address to use for next the call. - */ -static int -read_ringbuf(struct net_device * dev, - int addr, - char * buf, - int len) -{ - unsigned int base = dev->base_addr; - int ring_ptr = addr; - int chunk_len; - char * buf_ptr = buf; - - /* Get all the buffer */ - while(len > 0) - { - /* Position the Program I/O Register at the ring buffer pointer */ - outb(ring_ptr & 0xff, PIORL(base)); - outb(((ring_ptr >> 8) & PIORH_MASK), PIORH(base)); - - /* First, determine how much we can read without wrapping around the - ring buffer */ - if((addr + len) < (RX_BASE + RX_SIZE)) - chunk_len = len; - else - chunk_len = RX_BASE + RX_SIZE - addr; - insb(PIOP(base), buf_ptr, chunk_len); - buf_ptr += chunk_len; - len -= chunk_len; - ring_ptr = (ring_ptr - RX_BASE + chunk_len) % RX_SIZE + RX_BASE; - } - return(ring_ptr); -} /* read_ringbuf */ - -/*------------------------------------------------------------------*/ -/* - * Reconfigure the i82593, or at least ask for it... - * Because wv_82593_config use the transmission buffer, we must do it - * when we are sure that there is no transmission, so we do it now - * or in wavelan_packet_xmit() (I can't find any better place, - * wavelan_interrupt is not an option...), so you may experience - * some delay sometime... - */ -static void -wv_82593_reconfig(struct net_device * dev) -{ - net_local * lp = netdev_priv(dev); - struct pcmcia_device * link = lp->link; - unsigned long flags; - - /* Arm the flag, will be cleard in wv_82593_config() */ - lp->reconfig_82593 = TRUE; - - /* Check if we can do it now ! */ - if((link->open) && (netif_running(dev)) && !(netif_queue_stopped(dev))) - { - spin_lock_irqsave(&lp->spinlock, flags); /* Disable interrupts */ - wv_82593_config(dev); - spin_unlock_irqrestore(&lp->spinlock, flags); /* Re-enable interrupts */ - } - else - { -#ifdef DEBUG_IOCTL_INFO - printk(KERN_DEBUG - "%s: wv_82593_reconfig(): delayed (state = %lX, link = %d)\n", - dev->name, dev->state, link->open); -#endif - } -} - -/********************* DEBUG & INFO SUBROUTINES *********************/ -/* - * This routines are used in the code to show debug informations. - * Most of the time, it dump the content of hardware structures... - */ - -#ifdef DEBUG_PSA_SHOW -/*------------------------------------------------------------------*/ -/* - * Print the formatted contents of the Parameter Storage Area. - */ -static void -wv_psa_show(psa_t * p) -{ - printk(KERN_DEBUG "##### wavelan psa contents: #####\n"); - printk(KERN_DEBUG "psa_io_base_addr_1: 0x%02X %02X %02X %02X\n", - p->psa_io_base_addr_1, - p->psa_io_base_addr_2, - p->psa_io_base_addr_3, - p->psa_io_base_addr_4); - printk(KERN_DEBUG "psa_rem_boot_addr_1: 0x%02X %02X %02X\n", - p->psa_rem_boot_addr_1, - p->psa_rem_boot_addr_2, - p->psa_rem_boot_addr_3); - printk(KERN_DEBUG "psa_holi_params: 0x%02x, ", p->psa_holi_params); - printk("psa_int_req_no: %d\n", p->psa_int_req_no); -#ifdef DEBUG_SHOW_UNUSED - printk(KERN_DEBUG "psa_unused0[]: %pM\n", p->psa_unused0); -#endif /* DEBUG_SHOW_UNUSED */ - printk(KERN_DEBUG "psa_univ_mac_addr[]: %pM\n", p->psa_univ_mac_addr); - printk(KERN_DEBUG "psa_local_mac_addr[]: %pM\n", p->psa_local_mac_addr); - printk(KERN_DEBUG "psa_univ_local_sel: %d, ", p->psa_univ_local_sel); - printk("psa_comp_number: %d, ", p->psa_comp_number); - printk("psa_thr_pre_set: 0x%02x\n", p->psa_thr_pre_set); - printk(KERN_DEBUG "psa_feature_select/decay_prm: 0x%02x, ", - p->psa_feature_select); - printk("psa_subband/decay_update_prm: %d\n", p->psa_subband); - printk(KERN_DEBUG "psa_quality_thr: 0x%02x, ", p->psa_quality_thr); - printk("psa_mod_delay: 0x%02x\n", p->psa_mod_delay); - printk(KERN_DEBUG "psa_nwid: 0x%02x%02x, ", p->psa_nwid[0], p->psa_nwid[1]); - printk("psa_nwid_select: %d\n", p->psa_nwid_select); - printk(KERN_DEBUG "psa_encryption_select: %d, ", p->psa_encryption_select); - printk("psa_encryption_key[]: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - p->psa_encryption_key[0], - p->psa_encryption_key[1], - p->psa_encryption_key[2], - p->psa_encryption_key[3], - p->psa_encryption_key[4], - p->psa_encryption_key[5], - p->psa_encryption_key[6], - p->psa_encryption_key[7]); - printk(KERN_DEBUG "psa_databus_width: %d\n", p->psa_databus_width); - printk(KERN_DEBUG "psa_call_code/auto_squelch: 0x%02x, ", - p->psa_call_code[0]); - printk("psa_call_code[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", - p->psa_call_code[0], - p->psa_call_code[1], - p->psa_call_code[2], - p->psa_call_code[3], - p->psa_call_code[4], - p->psa_call_code[5], - p->psa_call_code[6], - p->psa_call_code[7]); -#ifdef DEBUG_SHOW_UNUSED - printk(KERN_DEBUG "psa_reserved[]: %02X:%02X\n", - p->psa_reserved[0], - p->psa_reserved[1]); -#endif /* DEBUG_SHOW_UNUSED */ - printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status); - printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]); - printk("psa_crc_status: 0x%02x\n", p->psa_crc_status); -} /* wv_psa_show */ -#endif /* DEBUG_PSA_SHOW */ - -#ifdef DEBUG_MMC_SHOW -/*------------------------------------------------------------------*/ -/* - * Print the formatted status of the Modem Management Controller. - * This function need to be completed... - */ -static void -wv_mmc_show(struct net_device * dev) -{ - unsigned int base = dev->base_addr; - net_local * lp = netdev_priv(dev); - mmr_t m; - - /* Basic check */ - if(hasr_read(base) & HASR_NO_CLK) - { - printk(KERN_WARNING "%s: wv_mmc_show: modem not connected\n", - dev->name); - return; - } - - spin_lock_irqsave(&lp->spinlock, flags); - - /* Read the mmc */ - mmc_out(base, mmwoff(0, mmw_freeze), 1); - mmc_read(base, 0, (u_char *)&m, sizeof(m)); - mmc_out(base, mmwoff(0, mmw_freeze), 0); - - /* Don't forget to update statistics */ - lp->wstats.discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l; - - spin_unlock_irqrestore(&lp->spinlock, flags); - - printk(KERN_DEBUG "##### wavelan modem status registers: #####\n"); -#ifdef DEBUG_SHOW_UNUSED - printk(KERN_DEBUG "mmc_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", - m.mmr_unused0[0], - m.mmr_unused0[1], - m.mmr_unused0[2], - m.mmr_unused0[3], - m.mmr_unused0[4], - m.mmr_unused0[5], - m.mmr_unused0[6], - m.mmr_unused0[7]); -#endif /* DEBUG_SHOW_UNUSED */ - printk(KERN_DEBUG "Encryption algorithm: %02X - Status: %02X\n", - m.mmr_des_avail, m.mmr_des_status); -#ifdef DEBUG_SHOW_UNUSED - printk(KERN_DEBUG "mmc_unused1[]: %02X:%02X:%02X:%02X:%02X\n", - m.mmr_unused1[0], - m.mmr_unused1[1], - m.mmr_unused1[2], - m.mmr_unused1[3], - m.mmr_unused1[4]); -#endif /* DEBUG_SHOW_UNUSED */ - printk(KERN_DEBUG "dce_status: 0x%x [%s%s%s%s]\n", - m.mmr_dce_status, - (m.mmr_dce_status & MMR_DCE_STATUS_RX_BUSY) ? "energy detected,":"", - (m.mmr_dce_status & MMR_DCE_STATUS_LOOPT_IND) ? - "loop test indicated," : "", - (m.mmr_dce_status & MMR_DCE_STATUS_TX_BUSY) ? "transmitter on," : "", - (m.mmr_dce_status & MMR_DCE_STATUS_JBR_EXPIRED) ? - "jabber timer expired," : ""); - printk(KERN_DEBUG "Dsp ID: %02X\n", - m.mmr_dsp_id); -#ifdef DEBUG_SHOW_UNUSED - printk(KERN_DEBUG "mmc_unused2[]: %02X:%02X\n", - m.mmr_unused2[0], - m.mmr_unused2[1]); -#endif /* DEBUG_SHOW_UNUSED */ - printk(KERN_DEBUG "# correct_nwid: %d, # wrong_nwid: %d\n", - (m.mmr_correct_nwid_h << 8) | m.mmr_correct_nwid_l, - (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l); - printk(KERN_DEBUG "thr_pre_set: 0x%x [current signal %s]\n", - m.mmr_thr_pre_set & MMR_THR_PRE_SET, - (m.mmr_thr_pre_set & MMR_THR_PRE_SET_CUR) ? "above" : "below"); - printk(KERN_DEBUG "signal_lvl: %d [%s], ", - m.mmr_signal_lvl & MMR_SIGNAL_LVL, - (m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) ? "new msg" : "no new msg"); - printk("silence_lvl: %d [%s], ", m.mmr_silence_lvl & MMR_SILENCE_LVL, - (m.mmr_silence_lvl & MMR_SILENCE_LVL_VALID) ? "update done" : "no new update"); - printk("sgnl_qual: 0x%x [%s]\n", m.mmr_sgnl_qual & MMR_SGNL_QUAL, - (m.mmr_sgnl_qual & MMR_SGNL_QUAL_ANT) ? "Antenna 1" : "Antenna 0"); -#ifdef DEBUG_SHOW_UNUSED - printk(KERN_DEBUG "netw_id_l: %x\n", m.mmr_netw_id_l); -#endif /* DEBUG_SHOW_UNUSED */ -} /* wv_mmc_show */ -#endif /* DEBUG_MMC_SHOW */ - -#ifdef DEBUG_I82593_SHOW -/*------------------------------------------------------------------*/ -/* - * Print the formatted status of the i82593's receive unit. - */ -static void -wv_ru_show(struct net_device * dev) -{ - net_local *lp = netdev_priv(dev); - - printk(KERN_DEBUG "##### wavelan i82593 receiver status: #####\n"); - printk(KERN_DEBUG "ru: rfp %d stop %d", lp->rfp, lp->stop); - /* - * Not implemented yet... - */ - printk("\n"); -} /* wv_ru_show */ -#endif /* DEBUG_I82593_SHOW */ - -#ifdef DEBUG_DEVICE_SHOW -/*------------------------------------------------------------------*/ -/* - * Print the formatted status of the WaveLAN PCMCIA device driver. - */ -static void -wv_dev_show(struct net_device * dev) -{ - printk(KERN_DEBUG "dev:"); - printk(" state=%lX,", dev->state); - printk(" trans_start=%ld,", dev->trans_start); - printk(" flags=0x%x,", dev->flags); - printk("\n"); -} /* wv_dev_show */ - -/*------------------------------------------------------------------*/ -/* - * Print the formatted status of the WaveLAN PCMCIA device driver's - * private information. - */ -static void -wv_local_show(struct net_device * dev) -{ - net_local *lp = netdev_priv(dev); - - printk(KERN_DEBUG "local:"); - /* - * Not implemented yet... - */ - printk("\n"); -} /* wv_local_show */ -#endif /* DEBUG_DEVICE_SHOW */ - -#if defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO) -/*------------------------------------------------------------------*/ -/* - * Dump packet header (and content if necessary) on the screen - */ -static void -wv_packet_info(u_char * p, /* Packet to dump */ - int length, /* Length of the packet */ - char * msg1, /* Name of the device */ - char * msg2) /* Name of the function */ -{ - int i; - int maxi; - - printk(KERN_DEBUG "%s: %s(): dest %pM, length %d\n", - msg1, msg2, p, length); - printk(KERN_DEBUG "%s: %s(): src %pM, type 0x%02X%02X\n", - msg1, msg2, &p[6], p[12], p[13]); - -#ifdef DEBUG_PACKET_DUMP - - printk(KERN_DEBUG "data=\""); - - if((maxi = length) > DEBUG_PACKET_DUMP) - maxi = DEBUG_PACKET_DUMP; - for(i = 14; i < maxi; i++) - if(p[i] >= ' ' && p[i] <= '~') - printk(" %c", p[i]); - else - printk("%02X", p[i]); - if(maxi < length) - printk(".."); - printk("\"\n"); - printk(KERN_DEBUG "\n"); -#endif /* DEBUG_PACKET_DUMP */ -} -#endif /* defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO) */ - -/*------------------------------------------------------------------*/ -/* - * This is the information which is displayed by the driver at startup - * There is a lot of flag to configure it at your will... - */ -static void -wv_init_info(struct net_device * dev) -{ - unsigned int base = dev->base_addr; - psa_t psa; - - /* Read the parameter storage area */ - psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa)); - -#ifdef DEBUG_PSA_SHOW - wv_psa_show(&psa); -#endif -#ifdef DEBUG_MMC_SHOW - wv_mmc_show(dev); -#endif -#ifdef DEBUG_I82593_SHOW - wv_ru_show(dev); -#endif - -#ifdef DEBUG_BASIC_SHOW - /* Now, let's go for the basic stuff */ - printk(KERN_NOTICE "%s: WaveLAN: port %#x, irq %d, hw_addr %pM", - dev->name, base, dev->irq, dev->dev_addr); - - /* Print current network id */ - if(psa.psa_nwid_select) - printk(", nwid 0x%02X-%02X", psa.psa_nwid[0], psa.psa_nwid[1]); - else - printk(", nwid off"); - - /* If 2.00 card */ - if(!(mmc_in(base, mmroff(0, mmr_fee_status)) & - (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) - { - unsigned short freq; - - /* Ask the EEprom to read the frequency from the first area */ - fee_read(base, 0x00 /* 1st area - frequency... */, - &freq, 1); - - /* Print frequency */ - printk(", 2.00, %ld", (freq >> 6) + 2400L); - - /* Hack !!! */ - if(freq & 0x20) - printk(".5"); - } - else - { - printk(", PCMCIA, "); - switch (psa.psa_subband) - { - case PSA_SUBBAND_915: - printk("915"); - break; - case PSA_SUBBAND_2425: - printk("2425"); - break; - case PSA_SUBBAND_2460: - printk("2460"); - break; - case PSA_SUBBAND_2484: - printk("2484"); - break; - case PSA_SUBBAND_2430_5: - printk("2430.5"); - break; - default: - printk("unknown"); - } - } - - printk(" MHz\n"); -#endif /* DEBUG_BASIC_SHOW */ - -#ifdef DEBUG_VERSION_SHOW - /* Print version information */ - printk(KERN_NOTICE "%s", version); -#endif -} /* wv_init_info */ - -/********************* IOCTL, STATS & RECONFIG *********************/ -/* - * We found here routines that are called by Linux on differents - * occasions after the configuration and not for transmitting data - * These may be called when the user use ifconfig, /proc/net/dev - * or wireless extensions - */ - - -/*------------------------------------------------------------------*/ -/* - * Set or clear the multicast filter for this adaptor. - * num_addrs == -1 Promiscuous mode, receive all packets - * num_addrs == 0 Normal mode, clear multicast list - * num_addrs > 0 Multicast mode, receive normal and MC packets, - * and do best-effort filtering. - */ - -static void -wavelan_set_multicast_list(struct net_device * dev) -{ - net_local * lp = netdev_priv(dev); - -#ifdef DEBUG_IOCTL_TRACE - printk(KERN_DEBUG "%s: ->wavelan_set_multicast_list()\n", dev->name); -#endif - -#ifdef DEBUG_IOCTL_INFO - printk(KERN_DEBUG "%s: wavelan_set_multicast_list(): setting Rx mode %02X to %d addresses.\n", - dev->name, dev->flags, netdev_mc_count(dev)); -#endif - - if(dev->flags & IFF_PROMISC) - { - /* - * Enable promiscuous mode: receive all packets. - */ - if(!lp->promiscuous) - { - lp->promiscuous = 1; - lp->allmulticast = 0; - lp->mc_count = 0; - - wv_82593_reconfig(dev); - } - } - else - /* If all multicast addresses - * or too much multicast addresses for the hardware filter */ - if((dev->flags & IFF_ALLMULTI) || - (netdev_mc_count(dev) > I82593_MAX_MULTICAST_ADDRESSES)) - { - /* - * Disable promiscuous mode, but active the all multicast mode - */ - if(!lp->allmulticast) - { - lp->promiscuous = 0; - lp->allmulticast = 1; - lp->mc_count = 0; - - wv_82593_reconfig(dev); - } - } - else - /* If there is some multicast addresses to send */ - if (!netdev_mc_empty(dev)) { - /* - * Disable promiscuous mode, but receive all packets - * in multicast list - */ -#ifdef MULTICAST_AVOID - if(lp->promiscuous || lp->allmulticast || - (netdev_mc_count(dev) != lp->mc_count)) -#endif - { - lp->promiscuous = 0; - lp->allmulticast = 0; - lp->mc_count = netdev_mc_count(dev); - - wv_82593_reconfig(dev); - } - } - else - { - /* - * Switch to normal mode: disable promiscuous mode and - * clear the multicast list. - */ - if(lp->promiscuous || lp->mc_count == 0) - { - lp->promiscuous = 0; - lp->allmulticast = 0; - lp->mc_count = 0; - - wv_82593_reconfig(dev); - } - } -#ifdef DEBUG_IOCTL_TRACE - printk(KERN_DEBUG "%s: <-wavelan_set_multicast_list()\n", dev->name); -#endif -} - -/*------------------------------------------------------------------*/ -/* - * This function doesn't exist... - * (Note : it was a nice way to test the reconfigure stuff...) - */ -#ifdef SET_MAC_ADDRESS -static int -wavelan_set_mac_address(struct net_device * dev, - void * addr) -{ - struct sockaddr * mac = addr; - - /* Copy the address */ - memcpy(dev->dev_addr, mac->sa_data, WAVELAN_ADDR_SIZE); - - /* Reconfig the beast */ - wv_82593_reconfig(dev); - - return 0; -} -#endif /* SET_MAC_ADDRESS */ - - -/*------------------------------------------------------------------*/ -/* - * Frequency setting (for hardware able of it) - * It's a bit complicated and you don't really want to look into it... - */ -static int -wv_set_frequency(u_long base, /* i/o port of the card */ - iw_freq * frequency) -{ - const int BAND_NUM = 10; /* Number of bands */ - long freq = 0L; /* offset to 2.4 GHz in .5 MHz */ -#ifdef DEBUG_IOCTL_INFO - int i; -#endif - - /* Setting by frequency */ - /* Theoritically, you may set any frequency between - * the two limits with a 0.5 MHz precision. In practice, - * I don't want you to have trouble with local - * regulations... */ - if((frequency->e == 1) && - (frequency->m >= (int) 2.412e8) && (frequency->m <= (int) 2.487e8)) - { - freq = ((frequency->m / 10000) - 24000L) / 5; - } - - /* Setting by channel (same as wfreqsel) */ - /* Warning : each channel is 22MHz wide, so some of the channels - * will interfere... */ - if((frequency->e == 0) && - (frequency->m >= 0) && (frequency->m < BAND_NUM)) - { - /* Get frequency offset. */ - freq = channel_bands[frequency->m] >> 1; - } - - /* Verify if the frequency is allowed */ - if(freq != 0L) - { - u_short table[10]; /* Authorized frequency table */ - - /* Read the frequency table */ - fee_read(base, 0x71 /* frequency table */, - table, 10); - -#ifdef DEBUG_IOCTL_INFO - printk(KERN_DEBUG "Frequency table :"); - for(i = 0; i < 10; i++) - { - printk(" %04X", - table[i]); - } - printk("\n"); -#endif - - /* Look in the table if the frequency is allowed */ - if(!(table[9 - ((freq - 24) / 16)] & - (1 << ((freq - 24) % 16)))) - return -EINVAL; /* not allowed */ - } - else - return -EINVAL; - - /* If we get a usable frequency */ - if(freq != 0L) - { - unsigned short area[16]; - unsigned short dac[2]; - unsigned short area_verify[16]; - unsigned short dac_verify[2]; - /* Corresponding gain (in the power adjust value table) - * see AT&T Wavelan Data Manual, REF 407-024689/E, page 3-8 - * & WCIN062D.DOC, page 6.2.9 */ - unsigned short power_limit[] = { 40, 80, 120, 160, 0 }; - int power_band = 0; /* Selected band */ - unsigned short power_adjust; /* Correct value */ - - /* Search for the gain */ - power_band = 0; - while((freq > power_limit[power_band]) && - (power_limit[++power_band] != 0)) - ; - - /* Read the first area */ - fee_read(base, 0x00, - area, 16); - - /* Read the DAC */ - fee_read(base, 0x60, - dac, 2); - - /* Read the new power adjust value */ - fee_read(base, 0x6B - (power_band >> 1), - &power_adjust, 1); - if(power_band & 0x1) - power_adjust >>= 8; - else - power_adjust &= 0xFF; - -#ifdef DEBUG_IOCTL_INFO - printk(KERN_DEBUG "Wavelan EEprom Area 1 :"); - for(i = 0; i < 16; i++) - { - printk(" %04X", - area[i]); - } - printk("\n"); - - printk(KERN_DEBUG "Wavelan EEprom DAC : %04X %04X\n", - dac[0], dac[1]); -#endif - - /* Frequency offset (for info only...) */ - area[0] = ((freq << 5) & 0xFFE0) | (area[0] & 0x1F); - - /* Receiver Principle main divider coefficient */ - area[3] = (freq >> 1) + 2400L - 352L; - area[2] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF); - - /* Transmitter Main divider coefficient */ - area[13] = (freq >> 1) + 2400L; - area[12] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF); - - /* Others part of the area are flags, bit streams or unused... */ - - /* Set the value in the DAC */ - dac[1] = ((power_adjust >> 1) & 0x7F) | (dac[1] & 0xFF80); - dac[0] = ((power_adjust & 0x1) << 4) | (dac[0] & 0xFFEF); - - /* Write the first area */ - fee_write(base, 0x00, - area, 16); - - /* Write the DAC */ - fee_write(base, 0x60, - dac, 2); - - /* We now should verify here that the EEprom writing was ok */ - - /* ReRead the first area */ - fee_read(base, 0x00, - area_verify, 16); - - /* ReRead the DAC */ - fee_read(base, 0x60, - dac_verify, 2); - - /* Compare */ - if(memcmp(area, area_verify, 16 * 2) || - memcmp(dac, dac_verify, 2 * 2)) - { -#ifdef DEBUG_IOCTL_ERROR - printk(KERN_INFO "Wavelan: wv_set_frequency : unable to write new frequency to EEprom (?)\n"); -#endif - return -EOPNOTSUPP; - } - - /* We must download the frequency parameters to the - * synthetisers (from the EEprom - area 1) - * Note : as the EEprom is auto decremented, we set the end - * if the area... */ - mmc_out(base, mmwoff(0, mmw_fee_addr), 0x0F); - mmc_out(base, mmwoff(0, mmw_fee_ctrl), - MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD); - - /* Wait until the download is finished */ - fee_wait(base, 100, 100); - - /* We must now download the power adjust value (gain) to - * the synthetisers (from the EEprom - area 7 - DAC) */ - mmc_out(base, mmwoff(0, mmw_fee_addr), 0x61); - mmc_out(base, mmwoff(0, mmw_fee_ctrl), - MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD); - - /* Wait until the download is finished */ - fee_wait(base, 100, 100); - -#ifdef DEBUG_IOCTL_INFO - /* Verification of what we have done... */ - - printk(KERN_DEBUG "Wavelan EEprom Area 1 :"); - for(i = 0; i < 16; i++) - { - printk(" %04X", - area_verify[i]); - } - printk("\n"); - - printk(KERN_DEBUG "Wavelan EEprom DAC : %04X %04X\n", - dac_verify[0], dac_verify[1]); -#endif - - return 0; - } - else - return -EINVAL; /* Bah, never get there... */ -} - -/*------------------------------------------------------------------*/ -/* - * Give the list of available frequencies - */ -static int -wv_frequency_list(u_long base, /* i/o port of the card */ - iw_freq * list, /* List of frequency to fill */ - int max) /* Maximum number of frequencies */ -{ - u_short table[10]; /* Authorized frequency table */ - long freq = 0L; /* offset to 2.4 GHz in .5 MHz + 12 MHz */ - int i; /* index in the table */ - const int BAND_NUM = 10; /* Number of bands */ - int c = 0; /* Channel number */ - - /* Read the frequency table */ - fee_read(base, 0x71 /* frequency table */, - table, 10); - - /* Look all frequencies */ - i = 0; - for(freq = 0; freq < 150; freq++) - /* Look in the table if the frequency is allowed */ - if(table[9 - (freq / 16)] & (1 << (freq % 16))) - { - /* Compute approximate channel number */ - while((((channel_bands[c] >> 1) - 24) < freq) && - (c < BAND_NUM)) - c++; - list[i].i = c; /* Set the list index */ - - /* put in the list */ - list[i].m = (((freq + 24) * 5) + 24000L) * 10000; - list[i++].e = 1; - - /* Check number */ - if(i >= max) - return(i); - } - - return(i); -} - -#ifdef IW_WIRELESS_SPY -/*------------------------------------------------------------------*/ -/* - * Gather wireless spy statistics : for each packet, compare the source - * address with out list, and if match, get the stats... - * Sorry, but this function really need wireless extensions... - */ -static inline void -wl_spy_gather(struct net_device * dev, - u_char * mac, /* MAC address */ - u_char * stats) /* Statistics to gather */ -{ - struct iw_quality wstats; - - wstats.qual = stats[2] & MMR_SGNL_QUAL; - wstats.level = stats[0] & MMR_SIGNAL_LVL; - wstats.noise = stats[1] & MMR_SILENCE_LVL; - wstats.updated = 0x7; - - /* Update spy records */ - wireless_spy_update(dev, mac, &wstats); -} -#endif /* IW_WIRELESS_SPY */ - -#ifdef HISTOGRAM -/*------------------------------------------------------------------*/ -/* - * This function calculate an histogram on the signal level. - * As the noise is quite constant, it's like doing it on the SNR. - * We have defined a set of interval (lp->his_range), and each time - * the level goes in that interval, we increment the count (lp->his_sum). - * With this histogram you may detect if one wavelan is really weak, - * or you may also calculate the mean and standard deviation of the level... - */ -static inline void -wl_his_gather(struct net_device * dev, - u_char * stats) /* Statistics to gather */ -{ - net_local * lp = netdev_priv(dev); - u_char level = stats[0] & MMR_SIGNAL_LVL; - int i; - - /* Find the correct interval */ - i = 0; - while((i < (lp->his_number - 1)) && (level >= lp->his_range[i++])) - ; - - /* Increment interval counter */ - (lp->his_sum[i])++; -} -#endif /* HISTOGRAM */ - -static void wl_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) -{ - strncpy(info->driver, "wavelan_cs", sizeof(info->driver)-1); -} - -static const struct ethtool_ops ops = { - .get_drvinfo = wl_get_drvinfo -}; - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : get protocol name - */ -static int wavelan_get_name(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - strcpy(wrqu->name, "WaveLAN"); - return 0; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : set NWID - */ -static int wavelan_set_nwid(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned int base = dev->base_addr; - net_local *lp = netdev_priv(dev); - psa_t psa; - mm_t m; - unsigned long flags; - int ret = 0; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Set NWID in WaveLAN. */ - if (!wrqu->nwid.disabled) { - /* Set NWID in psa */ - psa.psa_nwid[0] = (wrqu->nwid.value & 0xFF00) >> 8; - psa.psa_nwid[1] = wrqu->nwid.value & 0xFF; - psa.psa_nwid_select = 0x01; - psa_write(dev, - (char *) psa.psa_nwid - (char *) &psa, - (unsigned char *) psa.psa_nwid, 3); - - /* Set NWID in mmc. */ - m.w.mmw_netw_id_l = psa.psa_nwid[1]; - m.w.mmw_netw_id_h = psa.psa_nwid[0]; - mmc_write(base, - (char *) &m.w.mmw_netw_id_l - - (char *) &m, - (unsigned char *) &m.w.mmw_netw_id_l, 2); - mmc_out(base, mmwoff(0, mmw_loopt_sel), 0x00); - } else { - /* Disable NWID in the psa. */ - psa.psa_nwid_select = 0x00; - psa_write(dev, - (char *) &psa.psa_nwid_select - - (char *) &psa, - (unsigned char *) &psa.psa_nwid_select, - 1); - - /* Disable NWID in the mmc (no filtering). */ - mmc_out(base, mmwoff(0, mmw_loopt_sel), - MMW_LOOPT_SEL_DIS_NWID); - } - /* update the Wavelan checksum */ - update_psa_checksum(dev); - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : get NWID - */ -static int wavelan_get_nwid(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - net_local *lp = netdev_priv(dev); - psa_t psa; - unsigned long flags; - int ret = 0; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Read the NWID. */ - psa_read(dev, - (char *) psa.psa_nwid - (char *) &psa, - (unsigned char *) psa.psa_nwid, 3); - wrqu->nwid.value = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1]; - wrqu->nwid.disabled = !(psa.psa_nwid_select); - wrqu->nwid.fixed = 1; /* Superfluous */ - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : set frequency - */ -static int wavelan_set_freq(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned int base = dev->base_addr; - net_local *lp = netdev_priv(dev); - unsigned long flags; - int ret; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */ - if (!(mmc_in(base, mmroff(0, mmr_fee_status)) & - (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) - ret = wv_set_frequency(base, &(wrqu->freq)); - else - ret = -EOPNOTSUPP; - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : get frequency - */ -static int wavelan_get_freq(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned int base = dev->base_addr; - net_local *lp = netdev_priv(dev); - psa_t psa; - unsigned long flags; - int ret = 0; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). - * Does it work for everybody, especially old cards? */ - if (!(mmc_in(base, mmroff(0, mmr_fee_status)) & - (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) { - unsigned short freq; - - /* Ask the EEPROM to read the frequency from the first area. */ - fee_read(base, 0x00, &freq, 1); - wrqu->freq.m = ((freq >> 5) * 5 + 24000L) * 10000; - wrqu->freq.e = 1; - } else { - psa_read(dev, - (char *) &psa.psa_subband - (char *) &psa, - (unsigned char *) &psa.psa_subband, 1); - - if (psa.psa_subband <= 4) { - wrqu->freq.m = fixed_bands[psa.psa_subband]; - wrqu->freq.e = (psa.psa_subband != 0); - } else - ret = -EOPNOTSUPP; - } - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : set level threshold - */ -static int wavelan_set_sens(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned int base = dev->base_addr; - net_local *lp = netdev_priv(dev); - psa_t psa; - unsigned long flags; - int ret = 0; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Set the level threshold. */ - /* We should complain loudly if wrqu->sens.fixed = 0, because we - * can't set auto mode... */ - psa.psa_thr_pre_set = wrqu->sens.value & 0x3F; - psa_write(dev, - (char *) &psa.psa_thr_pre_set - (char *) &psa, - (unsigned char *) &psa.psa_thr_pre_set, 1); - /* update the Wavelan checksum */ - update_psa_checksum(dev); - mmc_out(base, mmwoff(0, mmw_thr_pre_set), - psa.psa_thr_pre_set); - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : get level threshold - */ -static int wavelan_get_sens(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - net_local *lp = netdev_priv(dev); - psa_t psa; - unsigned long flags; - int ret = 0; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Read the level threshold. */ - psa_read(dev, - (char *) &psa.psa_thr_pre_set - (char *) &psa, - (unsigned char *) &psa.psa_thr_pre_set, 1); - wrqu->sens.value = psa.psa_thr_pre_set & 0x3F; - wrqu->sens.fixed = 1; - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : set encryption key - */ -static int wavelan_set_encode(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned int base = dev->base_addr; - net_local *lp = netdev_priv(dev); - unsigned long flags; - psa_t psa; - int ret = 0; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Check if capable of encryption */ - if (!mmc_encr(base)) { - ret = -EOPNOTSUPP; - } - - /* Check the size of the key */ - if((wrqu->encoding.length != 8) && (wrqu->encoding.length != 0)) { - ret = -EINVAL; - } - - if(!ret) { - /* Basic checking... */ - if (wrqu->encoding.length == 8) { - /* Copy the key in the driver */ - memcpy(psa.psa_encryption_key, extra, - wrqu->encoding.length); - psa.psa_encryption_select = 1; - - psa_write(dev, - (char *) &psa.psa_encryption_select - - (char *) &psa, - (unsigned char *) &psa. - psa_encryption_select, 8 + 1); - - mmc_out(base, mmwoff(0, mmw_encr_enable), - MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE); - mmc_write(base, mmwoff(0, mmw_encr_key), - (unsigned char *) &psa. - psa_encryption_key, 8); - } - - /* disable encryption */ - if (wrqu->encoding.flags & IW_ENCODE_DISABLED) { - psa.psa_encryption_select = 0; - psa_write(dev, - (char *) &psa.psa_encryption_select - - (char *) &psa, - (unsigned char *) &psa. - psa_encryption_select, 1); - - mmc_out(base, mmwoff(0, mmw_encr_enable), 0); - } - /* update the Wavelan checksum */ - update_psa_checksum(dev); - } - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : get encryption key - */ -static int wavelan_get_encode(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned int base = dev->base_addr; - net_local *lp = netdev_priv(dev); - psa_t psa; - unsigned long flags; - int ret = 0; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Check if encryption is available */ - if (!mmc_encr(base)) { - ret = -EOPNOTSUPP; - } else { - /* Read the encryption key */ - psa_read(dev, - (char *) &psa.psa_encryption_select - - (char *) &psa, - (unsigned char *) &psa. - psa_encryption_select, 1 + 8); - - /* encryption is enabled ? */ - if (psa.psa_encryption_select) - wrqu->encoding.flags = IW_ENCODE_ENABLED; - else - wrqu->encoding.flags = IW_ENCODE_DISABLED; - wrqu->encoding.flags |= mmc_encr(base); - - /* Copy the key to the user buffer */ - wrqu->encoding.length = 8; - memcpy(extra, psa.psa_encryption_key, wrqu->encoding.length); - } - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return ret; -} - -#ifdef WAVELAN_ROAMING_EXT -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : set ESSID (domain) - */ -static int wavelan_set_essid(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - net_local *lp = netdev_priv(dev); - unsigned long flags; - int ret = 0; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Check if disable */ - if(wrqu->data.flags == 0) - lp->filter_domains = 0; - else { - char essid[IW_ESSID_MAX_SIZE + 1]; - char * endp; - - /* Terminate the string */ - memcpy(essid, extra, wrqu->data.length); - essid[IW_ESSID_MAX_SIZE] = '\0'; - -#ifdef DEBUG_IOCTL_INFO - printk(KERN_DEBUG "SetEssid : ``%s''\n", essid); -#endif /* DEBUG_IOCTL_INFO */ - - /* Convert to a number (note : Wavelan specific) */ - lp->domain_id = simple_strtoul(essid, &endp, 16); - /* Has it worked ? */ - if(endp > essid) - lp->filter_domains = 1; - else { - lp->filter_domains = 0; - ret = -EINVAL; - } - } - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : get ESSID (domain) - */ -static int wavelan_get_essid(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - net_local *lp = netdev_priv(dev); - - /* Is the domain ID active ? */ - wrqu->data.flags = lp->filter_domains; - - /* Copy Domain ID into a string (Wavelan specific) */ - /* Sound crazy, be we can't have a snprintf in the kernel !!! */ - sprintf(extra, "%lX", lp->domain_id); - extra[IW_ESSID_MAX_SIZE] = '\0'; - - /* Set the length */ - wrqu->data.length = strlen(extra); - - return 0; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : set AP address - */ -static int wavelan_set_wap(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ -#ifdef DEBUG_IOCTL_INFO - printk(KERN_DEBUG "Set AP to : %pM\n", wrqu->ap_addr.sa_data); -#endif /* DEBUG_IOCTL_INFO */ - - return -EOPNOTSUPP; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : get AP address - */ -static int wavelan_get_wap(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - /* Should get the real McCoy instead of own Ethernet address */ - memcpy(wrqu->ap_addr.sa_data, dev->dev_addr, WAVELAN_ADDR_SIZE); - wrqu->ap_addr.sa_family = ARPHRD_ETHER; - - return -EOPNOTSUPP; -} -#endif /* WAVELAN_ROAMING_EXT */ - -#ifdef WAVELAN_ROAMING -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : set mode - */ -static int wavelan_set_mode(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - net_local *lp = netdev_priv(dev); - unsigned long flags; - int ret = 0; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Check mode */ - switch(wrqu->mode) { - case IW_MODE_ADHOC: - if(do_roaming) { - wv_roam_cleanup(dev); - do_roaming = 0; - } - break; - case IW_MODE_INFRA: - if(!do_roaming) { - wv_roam_init(dev); - do_roaming = 1; - } - break; - default: - ret = -EINVAL; - } - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : get mode - */ -static int wavelan_get_mode(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - if(do_roaming) - wrqu->mode = IW_MODE_INFRA; - else - wrqu->mode = IW_MODE_ADHOC; - - return 0; -} -#endif /* WAVELAN_ROAMING */ - -/*------------------------------------------------------------------*/ -/* - * Wireless Handler : get range info - */ -static int wavelan_get_range(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned int base = dev->base_addr; - net_local *lp = netdev_priv(dev); - struct iw_range *range = (struct iw_range *) extra; - unsigned long flags; - int ret = 0; - - /* Set the length (very important for backward compatibility) */ - wrqu->data.length = sizeof(struct iw_range); - - /* Set all the info we don't care or don't know about to zero */ - memset(range, 0, sizeof(struct iw_range)); - - /* Set the Wireless Extension versions */ - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 9; - - /* Set information in the range struct. */ - range->throughput = 1.4 * 1000 * 1000; /* don't argue on this ! */ - range->min_nwid = 0x0000; - range->max_nwid = 0xFFFF; - - range->sensitivity = 0x3F; - range->max_qual.qual = MMR_SGNL_QUAL; - range->max_qual.level = MMR_SIGNAL_LVL; - range->max_qual.noise = MMR_SILENCE_LVL; - range->avg_qual.qual = MMR_SGNL_QUAL; /* Always max */ - /* Need to get better values for those two */ - range->avg_qual.level = 30; - range->avg_qual.noise = 8; - - range->num_bitrates = 1; - range->bitrate[0] = 2000000; /* 2 Mb/s */ - - /* Event capability (kernel + driver) */ - range->event_capa[0] = (IW_EVENT_CAPA_MASK(0x8B02) | - IW_EVENT_CAPA_MASK(0x8B04) | - IW_EVENT_CAPA_MASK(0x8B06)); - range->event_capa[1] = IW_EVENT_CAPA_K_1; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */ - if (!(mmc_in(base, mmroff(0, mmr_fee_status)) & - (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) { - range->num_channels = 10; - range->num_frequency = wv_frequency_list(base, range->freq, - IW_MAX_FREQUENCIES); - } else - range->num_channels = range->num_frequency = 0; - - /* Encryption supported ? */ - if (mmc_encr(base)) { - range->encoding_size[0] = 8; /* DES = 64 bits key */ - range->num_encoding_sizes = 1; - range->max_encoding_tokens = 1; /* Only one key possible */ - } else { - range->num_encoding_sizes = 0; - range->max_encoding_tokens = 0; - } - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return ret; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Private Handler : set quality threshold - */ -static int wavelan_set_qthr(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned int base = dev->base_addr; - net_local *lp = netdev_priv(dev); - psa_t psa; - unsigned long flags; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - psa.psa_quality_thr = *(extra) & 0x0F; - psa_write(dev, - (char *) &psa.psa_quality_thr - (char *) &psa, - (unsigned char *) &psa.psa_quality_thr, 1); - /* update the Wavelan checksum */ - update_psa_checksum(dev); - mmc_out(base, mmwoff(0, mmw_quality_thr), - psa.psa_quality_thr); - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return 0; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Private Handler : get quality threshold - */ -static int wavelan_get_qthr(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - net_local *lp = netdev_priv(dev); - psa_t psa; - unsigned long flags; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - psa_read(dev, - (char *) &psa.psa_quality_thr - (char *) &psa, - (unsigned char *) &psa.psa_quality_thr, 1); - *(extra) = psa.psa_quality_thr & 0x0F; - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return 0; -} - -#ifdef WAVELAN_ROAMING -/*------------------------------------------------------------------*/ -/* - * Wireless Private Handler : set roaming - */ -static int wavelan_set_roam(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - net_local *lp = netdev_priv(dev); - unsigned long flags; - - /* Disable interrupts and save flags. */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Note : should check if user == root */ - if(do_roaming && (*extra)==0) - wv_roam_cleanup(dev); - else if(do_roaming==0 && (*extra)!=0) - wv_roam_init(dev); - - do_roaming = (*extra); - - /* Enable interrupts and restore flags. */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - return 0; -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Private Handler : get quality threshold - */ -static int wavelan_get_roam(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - *(extra) = do_roaming; - - return 0; -} -#endif /* WAVELAN_ROAMING */ - -#ifdef HISTOGRAM -/*------------------------------------------------------------------*/ -/* - * Wireless Private Handler : set histogram - */ -static int wavelan_set_histo(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - net_local *lp = netdev_priv(dev); - - /* Check the number of intervals. */ - if (wrqu->data.length > 16) { - return(-E2BIG); - } - - /* Disable histo while we copy the addresses. - * As we don't disable interrupts, we need to do this */ - lp->his_number = 0; - - /* Are there ranges to copy? */ - if (wrqu->data.length > 0) { - /* Copy interval ranges to the driver */ - memcpy(lp->his_range, extra, wrqu->data.length); - - { - int i; - printk(KERN_DEBUG "Histo :"); - for(i = 0; i < wrqu->data.length; i++) - printk(" %d", lp->his_range[i]); - printk("\n"); - } - - /* Reset result structure. */ - memset(lp->his_sum, 0x00, sizeof(long) * 16); - } - - /* Now we can set the number of ranges */ - lp->his_number = wrqu->data.length; - - return(0); -} - -/*------------------------------------------------------------------*/ -/* - * Wireless Private Handler : get histogram - */ -static int wavelan_get_histo(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - net_local *lp = netdev_priv(dev); - - /* Set the number of intervals. */ - wrqu->data.length = lp->his_number; - - /* Give back the distribution statistics */ - if(lp->his_number > 0) - memcpy(extra, lp->his_sum, sizeof(long) * lp->his_number); - - return(0); -} -#endif /* HISTOGRAM */ - -/*------------------------------------------------------------------*/ -/* - * Structures to export the Wireless Handlers - */ - -static const struct iw_priv_args wavelan_private_args[] = { -/*{ cmd, set_args, get_args, name } */ - { SIOCSIPQTHR, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setqualthr" }, - { SIOCGIPQTHR, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getqualthr" }, - { SIOCSIPROAM, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setroam" }, - { SIOCGIPROAM, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getroam" }, - { SIOCSIPHISTO, IW_PRIV_TYPE_BYTE | 16, 0, "sethisto" }, - { SIOCGIPHISTO, 0, IW_PRIV_TYPE_INT | 16, "gethisto" }, -}; - -static const iw_handler wavelan_handler[] = -{ - NULL, /* SIOCSIWNAME */ - wavelan_get_name, /* SIOCGIWNAME */ - wavelan_set_nwid, /* SIOCSIWNWID */ - wavelan_get_nwid, /* SIOCGIWNWID */ - wavelan_set_freq, /* SIOCSIWFREQ */ - wavelan_get_freq, /* SIOCGIWFREQ */ -#ifdef WAVELAN_ROAMING - wavelan_set_mode, /* SIOCSIWMODE */ - wavelan_get_mode, /* SIOCGIWMODE */ -#else /* WAVELAN_ROAMING */ - NULL, /* SIOCSIWMODE */ - NULL, /* SIOCGIWMODE */ -#endif /* WAVELAN_ROAMING */ - wavelan_set_sens, /* SIOCSIWSENS */ - wavelan_get_sens, /* SIOCGIWSENS */ - NULL, /* SIOCSIWRANGE */ - wavelan_get_range, /* SIOCGIWRANGE */ - NULL, /* SIOCSIWPRIV */ - NULL, /* SIOCGIWPRIV */ - NULL, /* SIOCSIWSTATS */ - NULL, /* SIOCGIWSTATS */ - iw_handler_set_spy, /* SIOCSIWSPY */ - iw_handler_get_spy, /* SIOCGIWSPY */ - iw_handler_set_thrspy, /* SIOCSIWTHRSPY */ - iw_handler_get_thrspy, /* SIOCGIWTHRSPY */ -#ifdef WAVELAN_ROAMING_EXT - wavelan_set_wap, /* SIOCSIWAP */ - wavelan_get_wap, /* SIOCGIWAP */ - NULL, /* -- hole -- */ - NULL, /* SIOCGIWAPLIST */ - NULL, /* -- hole -- */ - NULL, /* -- hole -- */ - wavelan_set_essid, /* SIOCSIWESSID */ - wavelan_get_essid, /* SIOCGIWESSID */ -#else /* WAVELAN_ROAMING_EXT */ - NULL, /* SIOCSIWAP */ - NULL, /* SIOCGIWAP */ - NULL, /* -- hole -- */ - NULL, /* SIOCGIWAPLIST */ - NULL, /* -- hole -- */ - NULL, /* -- hole -- */ - NULL, /* SIOCSIWESSID */ - NULL, /* SIOCGIWESSID */ -#endif /* WAVELAN_ROAMING_EXT */ - NULL, /* SIOCSIWNICKN */ - NULL, /* SIOCGIWNICKN */ - NULL, /* -- hole -- */ - NULL, /* -- hole -- */ - NULL, /* SIOCSIWRATE */ - NULL, /* SIOCGIWRATE */ - NULL, /* SIOCSIWRTS */ - NULL, /* SIOCGIWRTS */ - NULL, /* SIOCSIWFRAG */ - NULL, /* SIOCGIWFRAG */ - NULL, /* SIOCSIWTXPOW */ - NULL, /* SIOCGIWTXPOW */ - NULL, /* SIOCSIWRETRY */ - NULL, /* SIOCGIWRETRY */ - wavelan_set_encode, /* SIOCSIWENCODE */ - wavelan_get_encode, /* SIOCGIWENCODE */ -}; - -static const iw_handler wavelan_private_handler[] = -{ - wavelan_set_qthr, /* SIOCIWFIRSTPRIV */ - wavelan_get_qthr, /* SIOCIWFIRSTPRIV + 1 */ -#ifdef WAVELAN_ROAMING - wavelan_set_roam, /* SIOCIWFIRSTPRIV + 2 */ - wavelan_get_roam, /* SIOCIWFIRSTPRIV + 3 */ -#else /* WAVELAN_ROAMING */ - NULL, /* SIOCIWFIRSTPRIV + 2 */ - NULL, /* SIOCIWFIRSTPRIV + 3 */ -#endif /* WAVELAN_ROAMING */ -#ifdef HISTOGRAM - wavelan_set_histo, /* SIOCIWFIRSTPRIV + 4 */ - wavelan_get_histo, /* SIOCIWFIRSTPRIV + 5 */ -#endif /* HISTOGRAM */ -}; - -static const struct iw_handler_def wavelan_handler_def = -{ - .num_standard = ARRAY_SIZE(wavelan_handler), - .num_private = ARRAY_SIZE(wavelan_private_handler), - .num_private_args = ARRAY_SIZE(wavelan_private_args), - .standard = wavelan_handler, - .private = wavelan_private_handler, - .private_args = wavelan_private_args, - .get_wireless_stats = wavelan_get_wireless_stats, -}; - -/*------------------------------------------------------------------*/ -/* - * Get wireless statistics - * Called by /proc/net/wireless... - */ -static iw_stats * -wavelan_get_wireless_stats(struct net_device * dev) -{ - unsigned int base = dev->base_addr; - net_local * lp = netdev_priv(dev); - mmr_t m; - iw_stats * wstats; - unsigned long flags; - -#ifdef DEBUG_IOCTL_TRACE - printk(KERN_DEBUG "%s: ->wavelan_get_wireless_stats()\n", dev->name); -#endif - - /* Disable interrupts & save flags */ - spin_lock_irqsave(&lp->spinlock, flags); - - wstats = &lp->wstats; - - /* Get data from the mmc */ - mmc_out(base, mmwoff(0, mmw_freeze), 1); - - mmc_read(base, mmroff(0, mmr_dce_status), &m.mmr_dce_status, 1); - mmc_read(base, mmroff(0, mmr_wrong_nwid_l), &m.mmr_wrong_nwid_l, 2); - mmc_read(base, mmroff(0, mmr_thr_pre_set), &m.mmr_thr_pre_set, 4); - - mmc_out(base, mmwoff(0, mmw_freeze), 0); - - /* Copy data to wireless stuff */ - wstats->status = m.mmr_dce_status & MMR_DCE_STATUS; - wstats->qual.qual = m.mmr_sgnl_qual & MMR_SGNL_QUAL; - wstats->qual.level = m.mmr_signal_lvl & MMR_SIGNAL_LVL; - wstats->qual.noise = m.mmr_silence_lvl & MMR_SILENCE_LVL; - wstats->qual.updated = (((m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) >> 7) | - ((m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) >> 6) | - ((m.mmr_silence_lvl & MMR_SILENCE_LVL_VALID) >> 5)); - wstats->discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l; - wstats->discard.code = 0L; - wstats->discard.misc = 0L; - - /* ReEnable interrupts & restore flags */ - spin_unlock_irqrestore(&lp->spinlock, flags); - -#ifdef DEBUG_IOCTL_TRACE - printk(KERN_DEBUG "%s: <-wavelan_get_wireless_stats()\n", dev->name); -#endif - return &lp->wstats; -} - -/************************* PACKET RECEPTION *************************/ -/* - * This part deal with receiving the packets. - * The interrupt handler get an interrupt when a packet has been - * successfully received and called this part... - */ - -/*------------------------------------------------------------------*/ -/* - * Calculate the starting address of the frame pointed to by the receive - * frame pointer and verify that the frame seem correct - * (called by wv_packet_rcv()) - */ -static int -wv_start_of_frame(struct net_device * dev, - int rfp, /* end of frame */ - int wrap) /* start of buffer */ -{ - unsigned int base = dev->base_addr; - int rp; - int len; - - rp = (rfp - 5 + RX_SIZE) % RX_SIZE; - outb(rp & 0xff, PIORL(base)); - outb(((rp >> 8) & PIORH_MASK), PIORH(base)); - len = inb(PIOP(base)); - len |= inb(PIOP(base)) << 8; - - /* Sanity checks on size */ - /* Frame too big */ - if(len > MAXDATAZ + 100) - { -#ifdef DEBUG_RX_ERROR - printk(KERN_INFO "%s: wv_start_of_frame: Received frame too large, rfp %d len 0x%x\n", - dev->name, rfp, len); -#endif - return(-1); - } - - /* Frame too short */ - if(len < 7) - { -#ifdef DEBUG_RX_ERROR - printk(KERN_INFO "%s: wv_start_of_frame: Received null frame, rfp %d len 0x%x\n", - dev->name, rfp, len); -#endif - return(-1); - } - - /* Wrap around buffer */ - if(len > ((wrap - (rfp - len) + RX_SIZE) % RX_SIZE)) /* magic formula ! */ - { -#ifdef DEBUG_RX_ERROR - printk(KERN_INFO "%s: wv_start_of_frame: wrap around buffer, wrap %d rfp %d len 0x%x\n", - dev->name, wrap, rfp, len); -#endif - return(-1); - } - - return((rp - len + RX_SIZE) % RX_SIZE); -} /* wv_start_of_frame */ - -/*------------------------------------------------------------------*/ -/* - * This routine does the actual copy of data (including the ethernet - * header structure) from the WaveLAN card to an sk_buff chain that - * will be passed up to the network interface layer. NOTE: We - * currently don't handle trailer protocols (neither does the rest of - * the network interface), so if that is needed, it will (at least in - * part) be added here. The contents of the receive ring buffer are - * copied to a message chain that is then passed to the kernel. - * - * Note: if any errors occur, the packet is "dropped on the floor" - * (called by wv_packet_rcv()) - */ -static void -wv_packet_read(struct net_device * dev, - int fd_p, - int sksize) -{ - net_local * lp = netdev_priv(dev); - struct sk_buff * skb; - -#ifdef DEBUG_RX_TRACE - printk(KERN_DEBUG "%s: ->wv_packet_read(0x%X, %d)\n", - dev->name, fd_p, sksize); -#endif - - /* Allocate some buffer for the new packet */ - if((skb = dev_alloc_skb(sksize+2)) == (struct sk_buff *) NULL) - { -#ifdef DEBUG_RX_ERROR - printk(KERN_INFO "%s: wv_packet_read(): could not alloc_skb(%d, GFP_ATOMIC)\n", - dev->name, sksize); -#endif - dev->stats.rx_dropped++; - /* - * Not only do we want to return here, but we also need to drop the - * packet on the floor to clear the interrupt. - */ - return; - } - - skb_reserve(skb, 2); - fd_p = read_ringbuf(dev, fd_p, (char *) skb_put(skb, sksize), sksize); - skb->protocol = eth_type_trans(skb, dev); - -#ifdef DEBUG_RX_INFO - wv_packet_info(skb_mac_header(skb), sksize, dev->name, "wv_packet_read"); -#endif /* DEBUG_RX_INFO */ - - /* Statistics gathering & stuff associated. - * It seem a bit messy with all the define, but it's really simple... */ - if( -#ifdef IW_WIRELESS_SPY - (lp->spy_data.spy_number > 0) || -#endif /* IW_WIRELESS_SPY */ -#ifdef HISTOGRAM - (lp->his_number > 0) || -#endif /* HISTOGRAM */ -#ifdef WAVELAN_ROAMING - (do_roaming) || -#endif /* WAVELAN_ROAMING */ - 0) - { - u_char stats[3]; /* Signal level, Noise level, Signal quality */ - - /* read signal level, silence level and signal quality bytes */ - fd_p = read_ringbuf(dev, (fd_p + 4) % RX_SIZE + RX_BASE, - stats, 3); -#ifdef DEBUG_RX_INFO - printk(KERN_DEBUG "%s: wv_packet_read(): Signal level %d/63, Silence level %d/63, signal quality %d/16\n", - dev->name, stats[0] & 0x3F, stats[1] & 0x3F, stats[2] & 0x0F); -#endif - -#ifdef WAVELAN_ROAMING - if(do_roaming) - if(WAVELAN_BEACON(skb->data)) - wl_roam_gather(dev, skb->data, stats); -#endif /* WAVELAN_ROAMING */ - -#ifdef WIRELESS_SPY - wl_spy_gather(dev, skb_mac_header(skb) + WAVELAN_ADDR_SIZE, stats); -#endif /* WIRELESS_SPY */ -#ifdef HISTOGRAM - wl_his_gather(dev, stats); -#endif /* HISTOGRAM */ - } - - /* - * Hand the packet to the Network Module - */ - netif_rx(skb); - - /* Keep stats up to date */ - dev->stats.rx_packets++; - dev->stats.rx_bytes += sksize; - -#ifdef DEBUG_RX_TRACE - printk(KERN_DEBUG "%s: <-wv_packet_read()\n", dev->name); -#endif - return; -} - -/*------------------------------------------------------------------*/ -/* - * This routine is called by the interrupt handler to initiate a - * packet transfer from the card to the network interface layer above - * this driver. This routine checks if a buffer has been successfully - * received by the WaveLAN card. If so, the routine wv_packet_read is - * called to do the actual transfer of the card's data including the - * ethernet header into a packet consisting of an sk_buff chain. - * (called by wavelan_interrupt()) - * Note : the spinlock is already grabbed for us and irq are disabled. - */ -static void -wv_packet_rcv(struct net_device * dev) -{ - unsigned int base = dev->base_addr; - net_local * lp = netdev_priv(dev); - int newrfp; - int rp; - int len; - int f_start; - int status; - int i593_rfp; - int stat_ptr; - u_char c[4]; - -#ifdef DEBUG_RX_TRACE - printk(KERN_DEBUG "%s: ->wv_packet_rcv()\n", dev->name); -#endif - - /* Get the new receive frame pointer from the i82593 chip */ - outb(CR0_STATUS_2 | OP0_NOP, LCCR(base)); - i593_rfp = inb(LCSR(base)); - i593_rfp |= inb(LCSR(base)) << 8; - i593_rfp %= RX_SIZE; - - /* Get the new receive frame pointer from the WaveLAN card. - * It is 3 bytes more than the increment of the i82593 receive - * frame pointer, for each packet. This is because it includes the - * 3 roaming bytes added by the mmc. - */ - newrfp = inb(RPLL(base)); - newrfp |= inb(RPLH(base)) << 8; - newrfp %= RX_SIZE; - -#ifdef DEBUG_RX_INFO - printk(KERN_DEBUG "%s: wv_packet_rcv(): i593_rfp %d stop %d newrfp %d lp->rfp %d\n", - dev->name, i593_rfp, lp->stop, newrfp, lp->rfp); -#endif - -#ifdef DEBUG_RX_ERROR - /* If no new frame pointer... */ - if(lp->overrunning || newrfp == lp->rfp) - printk(KERN_INFO "%s: wv_packet_rcv(): no new frame: i593_rfp %d stop %d newrfp %d lp->rfp %d\n", - dev->name, i593_rfp, lp->stop, newrfp, lp->rfp); -#endif - - /* Read all frames (packets) received */ - while(newrfp != lp->rfp) - { - /* A frame is composed of the packet, followed by a status word, - * the length of the frame (word) and the mmc info (SNR & qual). - * It's because the length is at the end that we can only scan - * frames backward. */ - - /* Find the first frame by skipping backwards over the frames */ - rp = newrfp; /* End of last frame */ - while(((f_start = wv_start_of_frame(dev, rp, newrfp)) != lp->rfp) && - (f_start != -1)) - rp = f_start; - - /* If we had a problem */ - if(f_start == -1) - { -#ifdef DEBUG_RX_ERROR - printk(KERN_INFO "wavelan_cs: cannot find start of frame "); - printk(" i593_rfp %d stop %d newrfp %d lp->rfp %d\n", - i593_rfp, lp->stop, newrfp, lp->rfp); -#endif - lp->rfp = rp; /* Get to the last usable frame */ - continue; - } - - /* f_start point to the beggining of the first frame received - * and rp to the beggining of the next one */ - - /* Read status & length of the frame */ - stat_ptr = (rp - 7 + RX_SIZE) % RX_SIZE; - stat_ptr = read_ringbuf(dev, stat_ptr, c, 4); - status = c[0] | (c[1] << 8); - len = c[2] | (c[3] << 8); - - /* Check status */ - if((status & RX_RCV_OK) != RX_RCV_OK) - { - dev->stats.rx_errors++; - if(status & RX_NO_SFD) - dev->stats.rx_frame_errors++; - if(status & RX_CRC_ERR) - dev->stats.rx_crc_errors++; - if(status & RX_OVRRUN) - dev->stats.rx_over_errors++; - -#ifdef DEBUG_RX_FAIL - printk(KERN_DEBUG "%s: wv_packet_rcv(): packet not received ok, status = 0x%x\n", - dev->name, status); -#endif - } - else - /* Read the packet and transmit to Linux */ - wv_packet_read(dev, f_start, len - 2); - - /* One frame has been processed, skip it */ - lp->rfp = rp; - } - - /* - * Update the frame stop register, but set it to less than - * the full 8K to allow space for 3 bytes of signal strength - * per packet. - */ - lp->stop = (i593_rfp + RX_SIZE - ((RX_SIZE / 64) * 3)) % RX_SIZE; - outb(OP0_SWIT_TO_PORT_1 | CR0_CHNL, LCCR(base)); - outb(CR1_STOP_REG_UPDATE | (lp->stop >> RX_SIZE_SHIFT), LCCR(base)); - outb(OP1_SWIT_TO_PORT_0, LCCR(base)); - -#ifdef DEBUG_RX_TRACE - printk(KERN_DEBUG "%s: <-wv_packet_rcv()\n", dev->name); -#endif -} - -/*********************** PACKET TRANSMISSION ***********************/ -/* - * This part deal with sending packet through the wavelan - * We copy the packet to the send buffer and then issue the send - * command to the i82593. The result of this operation will be - * checked in wavelan_interrupt() - */ - -/*------------------------------------------------------------------*/ -/* - * This routine fills in the appropriate registers and memory - * locations on the WaveLAN card and starts the card off on - * the transmit. - * (called in wavelan_packet_xmit()) - */ -static void -wv_packet_write(struct net_device * dev, - void * buf, - short length) -{ - net_local * lp = netdev_priv(dev); - unsigned int base = dev->base_addr; - unsigned long flags; - int clen = length; - register u_short xmtdata_base = TX_BASE; - -#ifdef DEBUG_TX_TRACE - printk(KERN_DEBUG "%s: ->wv_packet_write(%d)\n", dev->name, length); -#endif - - spin_lock_irqsave(&lp->spinlock, flags); - - /* Write the length of data buffer followed by the buffer */ - outb(xmtdata_base & 0xff, PIORL(base)); - outb(((xmtdata_base >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base)); - outb(clen & 0xff, PIOP(base)); /* lsb */ - outb(clen >> 8, PIOP(base)); /* msb */ - - /* Send the data */ - outsb(PIOP(base), buf, clen); - - /* Indicate end of transmit chain */ - outb(OP0_NOP, PIOP(base)); - /* josullvn@cs.cmu.edu: need to send a second NOP for alignment... */ - outb(OP0_NOP, PIOP(base)); - - /* Reset the transmit DMA pointer */ - hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET); - hacr_write(base, HACR_DEFAULT); - /* Send the transmit command */ - wv_82593_cmd(dev, "wv_packet_write(): transmit", - OP0_TRANSMIT, SR0_NO_RESULT); - - /* Make sure the watchdog will keep quiet for a while */ - dev->trans_start = jiffies; - - /* Keep stats up to date */ - dev->stats.tx_bytes += length; - - spin_unlock_irqrestore(&lp->spinlock, flags); - -#ifdef DEBUG_TX_INFO - wv_packet_info((u_char *) buf, length, dev->name, "wv_packet_write"); -#endif /* DEBUG_TX_INFO */ - -#ifdef DEBUG_TX_TRACE - printk(KERN_DEBUG "%s: <-wv_packet_write()\n", dev->name); -#endif -} - -/*------------------------------------------------------------------*/ -/* - * This routine is called when we want to send a packet (NET3 callback) - * In this routine, we check if the harware is ready to accept - * the packet. We also prevent reentrance. Then, we call the function - * to send the packet... - */ -static netdev_tx_t -wavelan_packet_xmit(struct sk_buff * skb, - struct net_device * dev) -{ - net_local * lp = netdev_priv(dev); - unsigned long flags; - -#ifdef DEBUG_TX_TRACE - printk(KERN_DEBUG "%s: ->wavelan_packet_xmit(0x%X)\n", dev->name, - (unsigned) skb); -#endif - - /* - * Block a timer-based transmit from overlapping a previous transmit. - * In other words, prevent reentering this routine. - */ - netif_stop_queue(dev); - - /* If somebody has asked to reconfigure the controller, - * we can do it now */ - if(lp->reconfig_82593) - { - spin_lock_irqsave(&lp->spinlock, flags); /* Disable interrupts */ - wv_82593_config(dev); - spin_unlock_irqrestore(&lp->spinlock, flags); /* Re-enable interrupts */ - /* Note : the configure procedure was totally synchronous, - * so the Tx buffer is now free */ - } - - /* Check if we need some padding */ - /* Note : on wireless the propagation time is in the order of 1us, - * and we don't have the Ethernet specific requirement of beeing - * able to detect collisions, therefore in theory we don't really - * need to pad. Jean II */ - if (skb_padto(skb, ETH_ZLEN)) - return NETDEV_TX_OK; - - wv_packet_write(dev, skb->data, skb->len); - - dev_kfree_skb(skb); - -#ifdef DEBUG_TX_TRACE - printk(KERN_DEBUG "%s: <-wavelan_packet_xmit()\n", dev->name); -#endif - return NETDEV_TX_OK; -} - -/********************** HARDWARE CONFIGURATION **********************/ -/* - * This part do the real job of starting and configuring the hardware. - */ - -/*------------------------------------------------------------------*/ -/* - * Routine to initialize the Modem Management Controller. - * (called by wv_hw_config()) - */ -static int -wv_mmc_init(struct net_device * dev) -{ - unsigned int base = dev->base_addr; - psa_t psa; - mmw_t m; - int configured; - int i; /* Loop counter */ - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: ->wv_mmc_init()\n", dev->name); -#endif - - /* Read the parameter storage area */ - psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa)); - - /* - * Check the first three octets of the MAC addr for the manufacturer's code. - * Note: If you get the error message below, you've got a - * non-NCR/AT&T/Lucent PCMCIA cards, see wavelan_cs.h for detail on - * how to configure your card... - */ - for (i = 0; i < ARRAY_SIZE(MAC_ADDRESSES); i++) - if ((psa.psa_univ_mac_addr[0] == MAC_ADDRESSES[i][0]) && - (psa.psa_univ_mac_addr[1] == MAC_ADDRESSES[i][1]) && - (psa.psa_univ_mac_addr[2] == MAC_ADDRESSES[i][2])) - break; - - /* If we have not found it... */ - if (i == ARRAY_SIZE(MAC_ADDRESSES)) - { -#ifdef DEBUG_CONFIG_ERRORS - printk(KERN_WARNING "%s: wv_mmc_init(): Invalid MAC address: %02X:%02X:%02X:...\n", - dev->name, psa.psa_univ_mac_addr[0], - psa.psa_univ_mac_addr[1], psa.psa_univ_mac_addr[2]); -#endif - return FALSE; - } - - /* Get the MAC address */ - memcpy(&dev->dev_addr[0], &psa.psa_univ_mac_addr[0], WAVELAN_ADDR_SIZE); - -#ifdef USE_PSA_CONFIG - configured = psa.psa_conf_status & 1; -#else - configured = 0; -#endif - - /* Is the PSA is not configured */ - if(!configured) - { - /* User will be able to configure NWID after (with iwconfig) */ - psa.psa_nwid[0] = 0; - psa.psa_nwid[1] = 0; - - /* As NWID is not set : no NWID checking */ - psa.psa_nwid_select = 0; - - /* Disable encryption */ - psa.psa_encryption_select = 0; - - /* Set to standard values - * 0x04 for AT, - * 0x01 for MCA, - * 0x04 for PCMCIA and 2.00 card (AT&T 407-024689/E document) - */ - if (psa.psa_comp_number & 1) - psa.psa_thr_pre_set = 0x01; - else - psa.psa_thr_pre_set = 0x04; - psa.psa_quality_thr = 0x03; - - /* It is configured */ - psa.psa_conf_status |= 1; - -#ifdef USE_PSA_CONFIG - /* Write the psa */ - psa_write(dev, (char *)psa.psa_nwid - (char *)&psa, - (unsigned char *)psa.psa_nwid, 4); - psa_write(dev, (char *)&psa.psa_thr_pre_set - (char *)&psa, - (unsigned char *)&psa.psa_thr_pre_set, 1); - psa_write(dev, (char *)&psa.psa_quality_thr - (char *)&psa, - (unsigned char *)&psa.psa_quality_thr, 1); - psa_write(dev, (char *)&psa.psa_conf_status - (char *)&psa, - (unsigned char *)&psa.psa_conf_status, 1); - /* update the Wavelan checksum */ - update_psa_checksum(dev); -#endif /* USE_PSA_CONFIG */ - } - - /* Zero the mmc structure */ - memset(&m, 0x00, sizeof(m)); - - /* Copy PSA info to the mmc */ - m.mmw_netw_id_l = psa.psa_nwid[1]; - m.mmw_netw_id_h = psa.psa_nwid[0]; - - if(psa.psa_nwid_select & 1) - m.mmw_loopt_sel = 0x00; - else - m.mmw_loopt_sel = MMW_LOOPT_SEL_DIS_NWID; - - memcpy(&m.mmw_encr_key, &psa.psa_encryption_key, - sizeof(m.mmw_encr_key)); - - if(psa.psa_encryption_select) - m.mmw_encr_enable = MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE; - else - m.mmw_encr_enable = 0; - - m.mmw_thr_pre_set = psa.psa_thr_pre_set & 0x3F; - m.mmw_quality_thr = psa.psa_quality_thr & 0x0F; - - /* - * Set default modem control parameters. - * See NCR document 407-0024326 Rev. A. - */ - m.mmw_jabber_enable = 0x01; - m.mmw_anten_sel = MMW_ANTEN_SEL_ALG_EN; - m.mmw_ifs = 0x20; - m.mmw_mod_delay = 0x04; - m.mmw_jam_time = 0x38; - - m.mmw_des_io_invert = 0; - m.mmw_freeze = 0; - m.mmw_decay_prm = 0; - m.mmw_decay_updat_prm = 0; - - /* Write all info to mmc */ - mmc_write(base, 0, (u_char *)&m, sizeof(m)); - - /* The following code start the modem of the 2.00 frequency - * selectable cards at power on. It's not strictly needed for the - * following boots... - * The original patch was by Joe Finney for the PCMCIA driver, but - * I've cleaned it a bit and add documentation. - * Thanks to Loeke Brederveld from Lucent for the info. - */ - - /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable) - * (does it work for everybody ? - especially old cards...) */ - /* Note : WFREQSEL verify that it is able to read from EEprom - * a sensible frequency (address 0x00) + that MMR_FEE_STATUS_ID - * is 0xA (Xilinx version) or 0xB (Ariadne version). - * My test is more crude but do work... */ - if(!(mmc_in(base, mmroff(0, mmr_fee_status)) & - (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) - { - /* We must download the frequency parameters to the - * synthetisers (from the EEprom - area 1) - * Note : as the EEprom is auto decremented, we set the end - * if the area... */ - m.mmw_fee_addr = 0x0F; - m.mmw_fee_ctrl = MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD; - mmc_write(base, (char *)&m.mmw_fee_ctrl - (char *)&m, - (unsigned char *)&m.mmw_fee_ctrl, 2); - - /* Wait until the download is finished */ - fee_wait(base, 100, 100); - -#ifdef DEBUG_CONFIG_INFO - /* The frequency was in the last word downloaded... */ - mmc_read(base, (char *)&m.mmw_fee_data_l - (char *)&m, - (unsigned char *)&m.mmw_fee_data_l, 2); - - /* Print some info for the user */ - printk(KERN_DEBUG "%s: Wavelan 2.00 recognised (frequency select) : Current frequency = %ld\n", - dev->name, - ((m.mmw_fee_data_h << 4) | - (m.mmw_fee_data_l >> 4)) * 5 / 2 + 24000L); -#endif - - /* We must now download the power adjust value (gain) to - * the synthetisers (from the EEprom - area 7 - DAC) */ - m.mmw_fee_addr = 0x61; - m.mmw_fee_ctrl = MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD; - mmc_write(base, (char *)&m.mmw_fee_ctrl - (char *)&m, - (unsigned char *)&m.mmw_fee_ctrl, 2); - - /* Wait until the download is finished */ - } /* if 2.00 card */ - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: <-wv_mmc_init()\n", dev->name); -#endif - return TRUE; -} - -/*------------------------------------------------------------------*/ -/* - * Routine to gracefully turn off reception, and wait for any commands - * to complete. - * (called in wv_ru_start() and wavelan_close() and wavelan_event()) - */ -static int -wv_ru_stop(struct net_device * dev) -{ - unsigned int base = dev->base_addr; - net_local * lp = netdev_priv(dev); - unsigned long flags; - int status; - int spin; - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: ->wv_ru_stop()\n", dev->name); -#endif - - spin_lock_irqsave(&lp->spinlock, flags); - - /* First, send the LAN controller a stop receive command */ - wv_82593_cmd(dev, "wv_graceful_shutdown(): stop-rcv", - OP0_STOP_RCV, SR0_NO_RESULT); - - /* Then, spin until the receive unit goes idle */ - spin = 300; - do - { - udelay(10); - outb(OP0_NOP | CR0_STATUS_3, LCCR(base)); - status = inb(LCSR(base)); - } - while(((status & SR3_RCV_STATE_MASK) != SR3_RCV_IDLE) && (spin-- > 0)); - - /* Now, spin until the chip finishes executing its current command */ - do - { - udelay(10); - outb(OP0_NOP | CR0_STATUS_3, LCCR(base)); - status = inb(LCSR(base)); - } - while(((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE) && (spin-- > 0)); - - spin_unlock_irqrestore(&lp->spinlock, flags); - - /* If there was a problem */ - if(spin <= 0) - { -#ifdef DEBUG_CONFIG_ERRORS - printk(KERN_INFO "%s: wv_ru_stop(): The chip doesn't want to stop...\n", - dev->name); -#endif - return FALSE; - } - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: <-wv_ru_stop()\n", dev->name); -#endif - return TRUE; -} /* wv_ru_stop */ - -/*------------------------------------------------------------------*/ -/* - * This routine starts the receive unit running. First, it checks if - * the card is actually ready. Then the card is instructed to receive - * packets again. - * (called in wv_hw_reset() & wavelan_open()) - */ -static int -wv_ru_start(struct net_device * dev) -{ - unsigned int base = dev->base_addr; - net_local * lp = netdev_priv(dev); - unsigned long flags; - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: ->wv_ru_start()\n", dev->name); -#endif - - /* - * We need to start from a quiescent state. To do so, we could check - * if the card is already running, but instead we just try to shut - * it down. First, we disable reception (in case it was already enabled). - */ - if(!wv_ru_stop(dev)) - return FALSE; - - spin_lock_irqsave(&lp->spinlock, flags); - - /* Now we know that no command is being executed. */ - - /* Set the receive frame pointer and stop pointer */ - lp->rfp = 0; - outb(OP0_SWIT_TO_PORT_1 | CR0_CHNL, LCCR(base)); - - /* Reset ring management. This sets the receive frame pointer to 1 */ - outb(OP1_RESET_RING_MNGMT, LCCR(base)); - -#if 0 - /* XXX the i82593 manual page 6-4 seems to indicate that the stop register - should be set as below */ - /* outb(CR1_STOP_REG_UPDATE|((RX_SIZE - 0x40)>> RX_SIZE_SHIFT),LCCR(base));*/ -#elif 0 - /* but I set it 0 instead */ - lp->stop = 0; -#else - /* but I set it to 3 bytes per packet less than 8K */ - lp->stop = (0 + RX_SIZE - ((RX_SIZE / 64) * 3)) % RX_SIZE; -#endif - outb(CR1_STOP_REG_UPDATE | (lp->stop >> RX_SIZE_SHIFT), LCCR(base)); - outb(OP1_INT_ENABLE, LCCR(base)); - outb(OP1_SWIT_TO_PORT_0, LCCR(base)); - - /* Reset receive DMA pointer */ - hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET); - hacr_write_slow(base, HACR_DEFAULT); - - /* Receive DMA on channel 1 */ - wv_82593_cmd(dev, "wv_ru_start(): rcv-enable", - CR0_CHNL | OP0_RCV_ENABLE, SR0_NO_RESULT); - -#ifdef DEBUG_I82593_SHOW - { - int status; - int opri; - int spin = 10000; - - /* spin until the chip starts receiving */ - do - { - outb(OP0_NOP | CR0_STATUS_3, LCCR(base)); - status = inb(LCSR(base)); - if(spin-- <= 0) - break; - } - while(((status & SR3_RCV_STATE_MASK) != SR3_RCV_ACTIVE) && - ((status & SR3_RCV_STATE_MASK) != SR3_RCV_READY)); - printk(KERN_DEBUG "rcv status is 0x%x [i:%d]\n", - (status & SR3_RCV_STATE_MASK), i); - } -#endif - - spin_unlock_irqrestore(&lp->spinlock, flags); - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: <-wv_ru_start()\n", dev->name); -#endif - return TRUE; -} - -/*------------------------------------------------------------------*/ -/* - * This routine does a standard config of the WaveLAN controller (i82593). - * In the ISA driver, this is integrated in wavelan_hardware_reset() - * (called by wv_hw_config(), wv_82593_reconfig() & wavelan_packet_xmit()) - */ -static int -wv_82593_config(struct net_device * dev) -{ - unsigned int base = dev->base_addr; - net_local * lp = netdev_priv(dev); - struct i82593_conf_block cfblk; - int ret = TRUE; - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: ->wv_82593_config()\n", dev->name); -#endif - - /* Create & fill i82593 config block - * - * Now conform to Wavelan document WCIN085B - */ - memset(&cfblk, 0x00, sizeof(struct i82593_conf_block)); - cfblk.d6mod = FALSE; /* Run in i82593 advanced mode */ - cfblk.fifo_limit = 5; /* = 56 B rx and 40 B tx fifo thresholds */ - cfblk.forgnesi = FALSE; /* 0=82C501, 1=AMD7992B compatibility */ - cfblk.fifo_32 = 1; - cfblk.throttle_enb = FALSE; - cfblk.contin = TRUE; /* enable continuous mode */ - cfblk.cntrxint = FALSE; /* enable continuous mode receive interrupts */ - cfblk.addr_len = WAVELAN_ADDR_SIZE; - cfblk.acloc = TRUE; /* Disable source addr insertion by i82593 */ - cfblk.preamb_len = 0; /* 2 bytes preamble (SFD) */ - cfblk.loopback = FALSE; - cfblk.lin_prio = 0; /* conform to 802.3 backoff algorithm */ - cfblk.exp_prio = 5; /* conform to 802.3 backoff algorithm */ - cfblk.bof_met = 1; /* conform to 802.3 backoff algorithm */ - cfblk.ifrm_spc = 0x20 >> 4; /* 32 bit times interframe spacing */ - cfblk.slottim_low = 0x20 >> 5; /* 32 bit times slot time */ - cfblk.slottim_hi = 0x0; - cfblk.max_retr = 15; - cfblk.prmisc = ((lp->promiscuous) ? TRUE: FALSE); /* Promiscuous mode */ - cfblk.bc_dis = FALSE; /* Enable broadcast reception */ - cfblk.crs_1 = TRUE; /* Transmit without carrier sense */ - cfblk.nocrc_ins = FALSE; /* i82593 generates CRC */ - cfblk.crc_1632 = FALSE; /* 32-bit Autodin-II CRC */ - cfblk.crs_cdt = FALSE; /* CD not to be interpreted as CS */ - cfblk.cs_filter = 0; /* CS is recognized immediately */ - cfblk.crs_src = FALSE; /* External carrier sense */ - cfblk.cd_filter = 0; /* CD is recognized immediately */ - cfblk.min_fr_len = ETH_ZLEN >> 2; /* Minimum frame length 64 bytes */ - cfblk.lng_typ = FALSE; /* Length field > 1500 = type field */ - cfblk.lng_fld = TRUE; /* Disable 802.3 length field check */ - cfblk.rxcrc_xf = TRUE; /* Don't transfer CRC to memory */ - cfblk.artx = TRUE; /* Disable automatic retransmission */ - cfblk.sarec = TRUE; /* Disable source addr trig of CD */ - cfblk.tx_jabber = TRUE; /* Disable jabber jam sequence */ - cfblk.hash_1 = FALSE; /* Use bits 0-5 in mc address hash */ - cfblk.lbpkpol = TRUE; /* Loopback pin active high */ - cfblk.fdx = FALSE; /* Disable full duplex operation */ - cfblk.dummy_6 = 0x3f; /* all ones */ - cfblk.mult_ia = FALSE; /* No multiple individual addresses */ - cfblk.dis_bof = FALSE; /* Disable the backoff algorithm ?! */ - cfblk.dummy_1 = TRUE; /* set to 1 */ - cfblk.tx_ifs_retrig = 3; /* Hmm... Disabled */ -#ifdef MULTICAST_ALL - cfblk.mc_all = (lp->allmulticast ? TRUE: FALSE); /* Allow all multicasts */ -#else - cfblk.mc_all = FALSE; /* No multicast all mode */ -#endif - cfblk.rcv_mon = 0; /* Monitor mode disabled */ - cfblk.frag_acpt = TRUE; /* Do not accept fragments */ - cfblk.tstrttrs = FALSE; /* No start transmission threshold */ - cfblk.fretx = TRUE; /* FIFO automatic retransmission */ - cfblk.syncrqs = FALSE; /* Synchronous DRQ deassertion... */ - cfblk.sttlen = TRUE; /* 6 byte status registers */ - cfblk.rx_eop = TRUE; /* Signal EOP on packet reception */ - cfblk.tx_eop = TRUE; /* Signal EOP on packet transmission */ - cfblk.rbuf_size = RX_SIZE>>11; /* Set receive buffer size */ - cfblk.rcvstop = TRUE; /* Enable Receive Stop Register */ - -#ifdef DEBUG_I82593_SHOW - print_hex_dump(KERN_DEBUG, "wavelan_cs: config block: ", DUMP_PREFIX_NONE, - 16, 1, &cfblk, sizeof(struct i82593_conf_block), false); -#endif - - /* Copy the config block to the i82593 */ - outb(TX_BASE & 0xff, PIORL(base)); - outb(((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base)); - outb(sizeof(struct i82593_conf_block) & 0xff, PIOP(base)); /* lsb */ - outb(sizeof(struct i82593_conf_block) >> 8, PIOP(base)); /* msb */ - outsb(PIOP(base), (char *) &cfblk, sizeof(struct i82593_conf_block)); - - /* reset transmit DMA pointer */ - hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET); - hacr_write(base, HACR_DEFAULT); - if(!wv_82593_cmd(dev, "wv_82593_config(): configure", - OP0_CONFIGURE, SR0_CONFIGURE_DONE)) - ret = FALSE; - - /* Initialize adapter's ethernet MAC address */ - outb(TX_BASE & 0xff, PIORL(base)); - outb(((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base)); - outb(WAVELAN_ADDR_SIZE, PIOP(base)); /* byte count lsb */ - outb(0, PIOP(base)); /* byte count msb */ - outsb(PIOP(base), &dev->dev_addr[0], WAVELAN_ADDR_SIZE); - - /* reset transmit DMA pointer */ - hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET); - hacr_write(base, HACR_DEFAULT); - if(!wv_82593_cmd(dev, "wv_82593_config(): ia-setup", - OP0_IA_SETUP, SR0_IA_SETUP_DONE)) - ret = FALSE; - -#ifdef WAVELAN_ROAMING - /* If roaming is enabled, join the "Beacon Request" multicast group... */ - /* But only if it's not in there already! */ - if(do_roaming) - dev_mc_add(dev,WAVELAN_BEACON_ADDRESS, WAVELAN_ADDR_SIZE, 1); -#endif /* WAVELAN_ROAMING */ - - /* If any multicast address to set */ - if(lp->mc_count) - { - struct dev_mc_list *dmi; - int addrs_len = WAVELAN_ADDR_SIZE * lp->mc_count; - -#ifdef DEBUG_CONFIG_INFO - printk(KERN_DEBUG "%s: wv_hw_config(): set %d multicast addresses:\n", - dev->name, lp->mc_count); - netdev_for_each_mc_addr(dmi, dev) - printk(KERN_DEBUG " %pM\n", dmi->dmi_addr); -#endif - - /* Initialize adapter's ethernet multicast addresses */ - outb(TX_BASE & 0xff, PIORL(base)); - outb(((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base)); - outb(addrs_len & 0xff, PIOP(base)); /* byte count lsb */ - outb((addrs_len >> 8), PIOP(base)); /* byte count msb */ - netdev_for_each_mc_addr(dmi, dev) - outsb(PIOP(base), dmi->dmi_addr, dmi->dmi_addrlen); - - /* reset transmit DMA pointer */ - hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET); - hacr_write(base, HACR_DEFAULT); - if(!wv_82593_cmd(dev, "wv_82593_config(): mc-setup", - OP0_MC_SETUP, SR0_MC_SETUP_DONE)) - ret = FALSE; - /* remember to avoid repeated reset */ - lp->mc_count = netdev_mc_count(dev); - } - - /* Job done, clear the flag */ - lp->reconfig_82593 = FALSE; - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: <-wv_82593_config()\n", dev->name); -#endif - return(ret); -} - -/*------------------------------------------------------------------*/ -/* - * Read the Access Configuration Register, perform a software reset, - * and then re-enable the card's software. - * - * If I understand correctly : reset the pcmcia interface of the - * wavelan. - * (called by wv_config()) - */ -static int -wv_pcmcia_reset(struct net_device * dev) -{ - int i; - conf_reg_t reg = { 0, CS_READ, CISREG_COR, 0 }; - struct pcmcia_device * link = ((net_local *)netdev_priv(dev))->link; - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: ->wv_pcmcia_reset()\n", dev->name); -#endif - - i = pcmcia_access_configuration_register(link, ®); - if (i != 0) - return FALSE; - -#ifdef DEBUG_CONFIG_INFO - printk(KERN_DEBUG "%s: wavelan_pcmcia_reset(): Config reg is 0x%x\n", - dev->name, (u_int) reg.Value); -#endif - - reg.Action = CS_WRITE; - reg.Value = reg.Value | COR_SW_RESET; - i = pcmcia_access_configuration_register(link, ®); - if (i != 0) - return FALSE; - - reg.Action = CS_WRITE; - reg.Value = COR_LEVEL_IRQ | COR_CONFIG; - i = pcmcia_access_configuration_register(link, ®); - if (i != 0) - return FALSE; - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: <-wv_pcmcia_reset()\n", dev->name); -#endif - return TRUE; -} - -/*------------------------------------------------------------------*/ -/* - * wavelan_hw_config() is called after a CARD_INSERTION event is - * received, to configure the wavelan hardware. - * Note that the reception will be enabled in wavelan->open(), so the - * device is configured but idle... - * Performs the following actions: - * 1. A pcmcia software reset (using wv_pcmcia_reset()) - * 2. A power reset (reset DMA) - * 3. Reset the LAN controller - * 4. Initialize the radio modem (using wv_mmc_init) - * 5. Configure LAN controller (using wv_82593_config) - * 6. Perform a diagnostic on the LAN controller - * (called by wavelan_event() & wv_hw_reset()) - */ -static int -wv_hw_config(struct net_device * dev) -{ - net_local * lp = netdev_priv(dev); - unsigned int base = dev->base_addr; - unsigned long flags; - int ret = FALSE; - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: ->wv_hw_config()\n", dev->name); -#endif - - /* compile-time check the sizes of structures */ - BUILD_BUG_ON(sizeof(psa_t) != PSA_SIZE); - BUILD_BUG_ON(sizeof(mmw_t) != MMW_SIZE); - BUILD_BUG_ON(sizeof(mmr_t) != MMR_SIZE); - - /* Reset the pcmcia interface */ - if(wv_pcmcia_reset(dev) == FALSE) - return FALSE; - - /* Disable interrupts */ - spin_lock_irqsave(&lp->spinlock, flags); - - /* Disguised goto ;-) */ - do - { - /* Power UP the module + reset the modem + reset host adapter - * (in fact, reset DMA channels) */ - hacr_write_slow(base, HACR_RESET); - hacr_write(base, HACR_DEFAULT); - - /* Check if the module has been powered up... */ - if(hasr_read(base) & HASR_NO_CLK) - { -#ifdef DEBUG_CONFIG_ERRORS - printk(KERN_WARNING "%s: wv_hw_config(): modem not connected or not a wavelan card\n", - dev->name); -#endif - break; - } - - /* initialize the modem */ - if(wv_mmc_init(dev) == FALSE) - { -#ifdef DEBUG_CONFIG_ERRORS - printk(KERN_WARNING "%s: wv_hw_config(): Can't configure the modem\n", - dev->name); -#endif - break; - } - - /* reset the LAN controller (i82593) */ - outb(OP0_RESET, LCCR(base)); - mdelay(1); /* A bit crude ! */ - - /* Initialize the LAN controller */ - if(wv_82593_config(dev) == FALSE) - { -#ifdef DEBUG_CONFIG_ERRORS - printk(KERN_INFO "%s: wv_hw_config(): i82593 init failed\n", - dev->name); -#endif - break; - } - - /* Diagnostic */ - if(wv_diag(dev) == FALSE) - { -#ifdef DEBUG_CONFIG_ERRORS - printk(KERN_INFO "%s: wv_hw_config(): i82593 diagnostic failed\n", - dev->name); -#endif - break; - } - - /* - * insert code for loopback test here - */ - - /* The device is now configured */ - lp->configured = 1; - ret = TRUE; - } - while(0); - - /* Re-enable interrupts */ - spin_unlock_irqrestore(&lp->spinlock, flags); - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: <-wv_hw_config()\n", dev->name); -#endif - return(ret); -} - -/*------------------------------------------------------------------*/ -/* - * Totally reset the wavelan and restart it. - * Performs the following actions: - * 1. Call wv_hw_config() - * 2. Start the LAN controller's receive unit - * (called by wavelan_event(), wavelan_watchdog() and wavelan_open()) - */ -static void -wv_hw_reset(struct net_device * dev) -{ - net_local * lp = netdev_priv(dev); - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: ->wv_hw_reset()\n", dev->name); -#endif - - lp->nresets++; - lp->configured = 0; - - /* Call wv_hw_config() for most of the reset & init stuff */ - if(wv_hw_config(dev) == FALSE) - return; - - /* start receive unit */ - wv_ru_start(dev); - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: <-wv_hw_reset()\n", dev->name); -#endif -} - -/*------------------------------------------------------------------*/ -/* - * wv_pcmcia_config() is called after a CARD_INSERTION event is - * received, to configure the PCMCIA socket, and to make the ethernet - * device available to the system. - * (called by wavelan_event()) - */ -static int -wv_pcmcia_config(struct pcmcia_device * link) -{ - struct net_device * dev = (struct net_device *) link->priv; - int i; - win_req_t req; - memreq_t mem; - net_local * lp = netdev_priv(dev); - - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "->wv_pcmcia_config(0x%p)\n", link); -#endif - - do - { - i = pcmcia_request_io(link, &link->io); - if (i != 0) - break; - - /* - * Now allocate an interrupt line. Note that this does not - * actually assign a handler to the interrupt. - */ - i = pcmcia_request_irq(link, &link->irq); - if (i != 0) - break; - - /* - * This actually configures the PCMCIA socket -- setting up - * the I/O windows and the interrupt mapping. - */ - link->conf.ConfigIndex = 1; - i = pcmcia_request_configuration(link, &link->conf); - if (i != 0) - break; - - /* - * Allocate a small memory window. Note that the struct pcmcia_device - * structure provides space for one window handle -- if your - * device needs several windows, you'll need to keep track of - * the handles in your private data structure, link->priv. - */ - req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; - req.Base = req.Size = 0; - req.AccessSpeed = mem_speed; - i = pcmcia_request_window(link, &req, &link->win); - if (i != 0) - break; - - lp->mem = ioremap(req.Base, req.Size); - dev->mem_start = (u_long)lp->mem; - dev->mem_end = dev->mem_start + req.Size; - - mem.CardOffset = 0; mem.Page = 0; - i = pcmcia_map_mem_page(link, link->win, &mem); - if (i != 0) - break; - - /* Feed device with this info... */ - dev->irq = link->irq.AssignedIRQ; - dev->base_addr = link->io.BasePort1; - netif_start_queue(dev); - -#ifdef DEBUG_CONFIG_INFO - printk(KERN_DEBUG "wv_pcmcia_config: MEMSTART %p IRQ %d IOPORT 0x%x\n", - lp->mem, dev->irq, (u_int) dev->base_addr); -#endif - - SET_NETDEV_DEV(dev, &link->dev); - i = register_netdev(dev); - if(i != 0) - { -#ifdef DEBUG_CONFIG_ERRORS - printk(KERN_INFO "wv_pcmcia_config(): register_netdev() failed\n"); -#endif - break; - } - } - while(0); /* Humm... Disguised goto !!! */ - - /* If any step failed, release any partially configured state */ - if(i != 0) - { - wv_pcmcia_release(link); - return FALSE; - } - - strcpy(((net_local *) netdev_priv(dev))->node.dev_name, dev->name); - link->dev_node = &((net_local *) netdev_priv(dev))->node; - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "<-wv_pcmcia_config()\n"); -#endif - return TRUE; -} - -/*------------------------------------------------------------------*/ -/* - * After a card is removed, wv_pcmcia_release() will unregister the net - * device, and release the PCMCIA configuration. If the device is - * still open, this will be postponed until it is closed. - */ -static void -wv_pcmcia_release(struct pcmcia_device *link) -{ - struct net_device * dev = (struct net_device *) link->priv; - net_local * lp = netdev_priv(dev); - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: -> wv_pcmcia_release(0x%p)\n", dev->name, link); -#endif - - iounmap(lp->mem); - pcmcia_disable_device(link); - -#ifdef DEBUG_CONFIG_TRACE - printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name); -#endif -} - -/************************ INTERRUPT HANDLING ************************/ - -/* - * This function is the interrupt handler for the WaveLAN card. This - * routine will be called whenever: - * 1. A packet is received. - * 2. A packet has successfully been transferred and the unit is - * ready to transmit another packet. - * 3. A command has completed execution. - */ -static irqreturn_t -wavelan_interrupt(int irq, - void * dev_id) -{ - struct net_device * dev = dev_id; - net_local * lp; - unsigned int base; - int status0; - u_int tx_status; - -#ifdef DEBUG_INTERRUPT_TRACE - printk(KERN_DEBUG "%s: ->wavelan_interrupt()\n", dev->name); -#endif - - lp = netdev_priv(dev); - base = dev->base_addr; - -#ifdef DEBUG_INTERRUPT_INFO - /* Check state of our spinlock (it should be cleared) */ - if(spin_is_locked(&lp->spinlock)) - printk(KERN_DEBUG - "%s: wavelan_interrupt(): spinlock is already locked !!!\n", - dev->name); -#endif - - /* Prevent reentrancy. We need to do that because we may have - * multiple interrupt handler running concurrently. - * It is safe because interrupts are disabled before aquiring - * the spinlock. */ - spin_lock(&lp->spinlock); - - /* Treat all pending interrupts */ - while(1) - { - /* ---------------- INTERRUPT CHECKING ---------------- */ - /* - * Look for the interrupt and verify the validity - */ - outb(CR0_STATUS_0 | OP0_NOP, LCCR(base)); - status0 = inb(LCSR(base)); - -#ifdef DEBUG_INTERRUPT_INFO - printk(KERN_DEBUG "status0 0x%x [%s => 0x%x]", status0, - (status0&SR0_INTERRUPT)?"int":"no int",status0&~SR0_INTERRUPT); - if(status0&SR0_INTERRUPT) - { - printk(" [%s => %d]\n", (status0 & SR0_CHNL) ? "chnl" : - ((status0 & SR0_EXECUTION) ? "cmd" : - ((status0 & SR0_RECEPTION) ? "recv" : "unknown")), - (status0 & SR0_EVENT_MASK)); - } - else - printk("\n"); -#endif - - /* Return if no actual interrupt from i82593 (normal exit) */ - if(!(status0 & SR0_INTERRUPT)) - break; - - /* If interrupt is both Rx and Tx or none... - * This code in fact is there to catch the spurious interrupt - * when you remove the wavelan pcmcia card from the socket */ - if(((status0 & SR0_BOTH_RX_TX) == SR0_BOTH_RX_TX) || - ((status0 & SR0_BOTH_RX_TX) == 0x0)) - { -#ifdef DEBUG_INTERRUPT_INFO - printk(KERN_INFO "%s: wv_interrupt(): bogus interrupt (or from dead card) : %X\n", - dev->name, status0); -#endif - /* Acknowledge the interrupt */ - outb(CR0_INT_ACK | OP0_NOP, LCCR(base)); - break; - } - - /* ----------------- RECEIVING PACKET ----------------- */ - /* - * When the wavelan signal the reception of a new packet, - * we call wv_packet_rcv() to copy if from the buffer and - * send it to NET3 - */ - if(status0 & SR0_RECEPTION) - { -#ifdef DEBUG_INTERRUPT_INFO - printk(KERN_DEBUG "%s: wv_interrupt(): receive\n", dev->name); -#endif - - if((status0 & SR0_EVENT_MASK) == SR0_STOP_REG_HIT) - { -#ifdef DEBUG_INTERRUPT_ERROR - printk(KERN_INFO "%s: wv_interrupt(): receive buffer overflow\n", - dev->name); -#endif - dev->stats.rx_over_errors++; - lp->overrunning = 1; - } - - /* Get the packet */ - wv_packet_rcv(dev); - lp->overrunning = 0; - - /* Acknowledge the interrupt */ - outb(CR0_INT_ACK | OP0_NOP, LCCR(base)); - continue; - } - - /* ---------------- COMMAND COMPLETION ---------------- */ - /* - * Interrupts issued when the i82593 has completed a command. - * Most likely : transmission done - */ - - /* If a transmission has been done */ - if((status0 & SR0_EVENT_MASK) == SR0_TRANSMIT_DONE || - (status0 & SR0_EVENT_MASK) == SR0_RETRANSMIT_DONE || - (status0 & SR0_EVENT_MASK) == SR0_TRANSMIT_NO_CRC_DONE) - { -#ifdef DEBUG_TX_ERROR - if((status0 & SR0_EVENT_MASK) == SR0_TRANSMIT_NO_CRC_DONE) - printk(KERN_INFO "%s: wv_interrupt(): packet transmitted without CRC.\n", - dev->name); -#endif - - /* Get transmission status */ - tx_status = inb(LCSR(base)); - tx_status |= (inb(LCSR(base)) << 8); -#ifdef DEBUG_INTERRUPT_INFO - printk(KERN_DEBUG "%s: wv_interrupt(): transmission done\n", - dev->name); - { - u_int rcv_bytes; - u_char status3; - rcv_bytes = inb(LCSR(base)); - rcv_bytes |= (inb(LCSR(base)) << 8); - status3 = inb(LCSR(base)); - printk(KERN_DEBUG "tx_status 0x%02x rcv_bytes 0x%02x status3 0x%x\n", - tx_status, rcv_bytes, (u_int) status3); - } -#endif - /* Check for possible errors */ - if((tx_status & TX_OK) != TX_OK) - { - dev->stats.tx_errors++; - - if(tx_status & TX_FRTL) - { -#ifdef DEBUG_TX_ERROR - printk(KERN_INFO "%s: wv_interrupt(): frame too long\n", - dev->name); -#endif - } - if(tx_status & TX_UND_RUN) - { -#ifdef DEBUG_TX_FAIL - printk(KERN_DEBUG "%s: wv_interrupt(): DMA underrun\n", - dev->name); -#endif - dev->stats.tx_aborted_errors++; - } - if(tx_status & TX_LOST_CTS) - { -#ifdef DEBUG_TX_FAIL - printk(KERN_DEBUG "%s: wv_interrupt(): no CTS\n", dev->name); -#endif - dev->stats.tx_carrier_errors++; - } - if(tx_status & TX_LOST_CRS) - { -#ifdef DEBUG_TX_FAIL - printk(KERN_DEBUG "%s: wv_interrupt(): no carrier\n", - dev->name); -#endif - dev->stats.tx_carrier_errors++; - } - if(tx_status & TX_HRT_BEAT) - { -#ifdef DEBUG_TX_FAIL - printk(KERN_DEBUG "%s: wv_interrupt(): heart beat\n", dev->name); -#endif - dev->stats.tx_heartbeat_errors++; - } - if(tx_status & TX_DEFER) - { -#ifdef DEBUG_TX_FAIL - printk(KERN_DEBUG "%s: wv_interrupt(): channel jammed\n", - dev->name); -#endif - } - /* Ignore late collisions since they're more likely to happen - * here (the WaveLAN design prevents the LAN controller from - * receiving while it is transmitting). We take action only when - * the maximum retransmit attempts is exceeded. - */ - if(tx_status & TX_COLL) - { - if(tx_status & TX_MAX_COL) - { -#ifdef DEBUG_TX_FAIL - printk(KERN_DEBUG "%s: wv_interrupt(): channel congestion\n", - dev->name); -#endif - if(!(tx_status & TX_NCOL_MASK)) - { - dev->stats.collisions += 0x10; - } - } - } - } /* if(!(tx_status & TX_OK)) */ - - dev->stats.collisions += (tx_status & TX_NCOL_MASK); - dev->stats.tx_packets++; - - netif_wake_queue(dev); - outb(CR0_INT_ACK | OP0_NOP, LCCR(base)); /* Acknowledge the interrupt */ - } - else /* if interrupt = transmit done or retransmit done */ - { -#ifdef DEBUG_INTERRUPT_ERROR - printk(KERN_INFO "wavelan_cs: unknown interrupt, status0 = %02x\n", - status0); -#endif - outb(CR0_INT_ACK | OP0_NOP, LCCR(base)); /* Acknowledge the interrupt */ - } - } /* while(1) */ - - spin_unlock(&lp->spinlock); - -#ifdef DEBUG_INTERRUPT_TRACE - printk(KERN_DEBUG "%s: <-wavelan_interrupt()\n", dev->name); -#endif - - /* We always return IRQ_HANDLED, because we will receive empty - * interrupts under normal operations. Anyway, it doesn't matter - * as we are dealing with an ISA interrupt that can't be shared. - * - * Explanation : under heavy receive, the following happens : - * ->wavelan_interrupt() - * (status0 & SR0_INTERRUPT) != 0 - * ->wv_packet_rcv() - * (status0 & SR0_INTERRUPT) != 0 - * ->wv_packet_rcv() - * (status0 & SR0_INTERRUPT) == 0 // i.e. no more event - * <-wavelan_interrupt() - * ->wavelan_interrupt() - * (status0 & SR0_INTERRUPT) == 0 // i.e. empty interrupt - * <-wavelan_interrupt() - * Jean II */ - return IRQ_HANDLED; -} /* wv_interrupt */ - -/*------------------------------------------------------------------*/ -/* - * Watchdog: when we start a transmission, a timer is set for us in the - * kernel. If the transmission completes, this timer is disabled. If - * the timer expires, we are called and we try to unlock the hardware. - * - * Note : This watchdog is move clever than the one in the ISA driver, - * because it try to abort the current command before reseting - * everything... - * On the other hand, it's a bit simpler, because we don't have to - * deal with the multiple Tx buffers... - */ -static void -wavelan_watchdog(struct net_device * dev) -{ - net_local * lp = netdev_priv(dev); - unsigned int base = dev->base_addr; - unsigned long flags; - int aborted = FALSE; - -#ifdef DEBUG_INTERRUPT_TRACE - printk(KERN_DEBUG "%s: ->wavelan_watchdog()\n", dev->name); -#endif - -#ifdef DEBUG_INTERRUPT_ERROR - printk(KERN_INFO "%s: wavelan_watchdog: watchdog timer expired\n", - dev->name); -#endif - - spin_lock_irqsave(&lp->spinlock, flags); - - /* Ask to abort the current command */ - outb(OP0_ABORT, LCCR(base)); - - /* Wait for the end of the command (a bit hackish) */ - if(wv_82593_cmd(dev, "wavelan_watchdog(): abort", - OP0_NOP | CR0_STATUS_3, SR0_EXECUTION_ABORTED)) - aborted = TRUE; - - /* Release spinlock here so that wv_hw_reset() can grab it */ - spin_unlock_irqrestore(&lp->spinlock, flags); - - /* Check if we were successful in aborting it */ - if(!aborted) - { - /* It seem that it wasn't enough */ -#ifdef DEBUG_INTERRUPT_ERROR - printk(KERN_INFO "%s: wavelan_watchdog: abort failed, trying reset\n", - dev->name); -#endif - wv_hw_reset(dev); - } - -#ifdef DEBUG_PSA_SHOW - { - psa_t psa; - psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa)); - wv_psa_show(&psa); - } -#endif -#ifdef DEBUG_MMC_SHOW - wv_mmc_show(dev); -#endif -#ifdef DEBUG_I82593_SHOW - wv_ru_show(dev); -#endif - - /* We are no more waiting for something... */ - netif_wake_queue(dev); - -#ifdef DEBUG_INTERRUPT_TRACE - printk(KERN_DEBUG "%s: <-wavelan_watchdog()\n", dev->name); -#endif -} - -/********************* CONFIGURATION CALLBACKS *********************/ -/* - * Here are the functions called by the pcmcia package (cardmgr) and - * linux networking (NET3) for initialization, configuration and - * deinstallations of the Wavelan Pcmcia Hardware. - */ - -/*------------------------------------------------------------------*/ -/* - * Configure and start up the WaveLAN PCMCIA adaptor. - * Called by NET3 when it "open" the device. - */ -static int -wavelan_open(struct net_device * dev) -{ - net_local * lp = netdev_priv(dev); - struct pcmcia_device * link = lp->link; - unsigned int base = dev->base_addr; - -#ifdef DEBUG_CALLBACK_TRACE - printk(KERN_DEBUG "%s: ->wavelan_open(dev=0x%x)\n", dev->name, - (unsigned int) dev); -#endif - - /* Check if the modem is powered up (wavelan_close() power it down */ - if(hasr_read(base) & HASR_NO_CLK) - { - /* Power up (power up time is 250us) */ - hacr_write(base, HACR_DEFAULT); - - /* Check if the module has been powered up... */ - if(hasr_read(base) & HASR_NO_CLK) - { -#ifdef DEBUG_CONFIG_ERRORS - printk(KERN_WARNING "%s: wavelan_open(): modem not connected\n", - dev->name); -#endif - return FALSE; - } - } - - /* Start reception and declare the driver ready */ - if(!lp->configured) - return FALSE; - if(!wv_ru_start(dev)) - wv_hw_reset(dev); /* If problem : reset */ - netif_start_queue(dev); - - /* Mark the device as used */ - link->open++; - -#ifdef WAVELAN_ROAMING - if(do_roaming) - wv_roam_init(dev); -#endif /* WAVELAN_ROAMING */ - -#ifdef DEBUG_CALLBACK_TRACE - printk(KERN_DEBUG "%s: <-wavelan_open()\n", dev->name); -#endif - return 0; -} - -/*------------------------------------------------------------------*/ -/* - * Shutdown the WaveLAN PCMCIA adaptor. - * Called by NET3 when it "close" the device. - */ -static int -wavelan_close(struct net_device * dev) -{ - struct pcmcia_device * link = ((net_local *)netdev_priv(dev))->link; - unsigned int base = dev->base_addr; - -#ifdef DEBUG_CALLBACK_TRACE - printk(KERN_DEBUG "%s: ->wavelan_close(dev=0x%x)\n", dev->name, - (unsigned int) dev); -#endif - - /* If the device isn't open, then nothing to do */ - if(!link->open) - { -#ifdef DEBUG_CONFIG_INFO - printk(KERN_DEBUG "%s: wavelan_close(): device not open\n", dev->name); -#endif - return 0; - } - -#ifdef WAVELAN_ROAMING - /* Cleanup of roaming stuff... */ - if(do_roaming) - wv_roam_cleanup(dev); -#endif /* WAVELAN_ROAMING */ - - link->open--; - - /* If the card is still present */ - if(netif_running(dev)) - { - netif_stop_queue(dev); - - /* Stop receiving new messages and wait end of transmission */ - wv_ru_stop(dev); - - /* Power down the module */ - hacr_write(base, HACR_DEFAULT & (~HACR_PWR_STAT)); - } - -#ifdef DEBUG_CALLBACK_TRACE - printk(KERN_DEBUG "%s: <-wavelan_close()\n", dev->name); -#endif - return 0; -} - -static const struct net_device_ops wavelan_netdev_ops = { - .ndo_open = wavelan_open, - .ndo_stop = wavelan_close, - .ndo_start_xmit = wavelan_packet_xmit, - .ndo_set_multicast_list = wavelan_set_multicast_list, -#ifdef SET_MAC_ADDRESS - .ndo_set_mac_address = wavelan_set_mac_address, -#endif - .ndo_tx_timeout = wavelan_watchdog, - .ndo_change_mtu = eth_change_mtu, - .ndo_validate_addr = eth_validate_addr, -}; - -/*------------------------------------------------------------------*/ -/* - * wavelan_attach() creates an "instance" of the driver, allocating - * local data structures for one device (one interface). The device - * is registered with Card Services. - * - * The dev_link structure is initialized, but we don't actually - * configure the card at this point -- we wait until we receive a - * card insertion event. - */ -static int -wavelan_probe(struct pcmcia_device *p_dev) -{ - struct net_device * dev; /* Interface generic data */ - net_local * lp; /* Interface specific data */ - int ret; - -#ifdef DEBUG_CALLBACK_TRACE - printk(KERN_DEBUG "-> wavelan_attach()\n"); -#endif - - /* The io structure describes IO port mapping */ - p_dev->io.NumPorts1 = 8; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = 3; - - /* Interrupt setup */ - p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - p_dev->irq.Handler = wavelan_interrupt; - - /* General socket configuration */ - p_dev->conf.Attributes = CONF_ENABLE_IRQ; - p_dev->conf.IntType = INT_MEMORY_AND_IO; - - /* Allocate the generic data structure */ - dev = alloc_etherdev(sizeof(net_local)); - if (!dev) - return -ENOMEM; - - p_dev->priv = dev; - - lp = netdev_priv(dev); - - /* Init specific data */ - lp->configured = 0; - lp->reconfig_82593 = FALSE; - lp->nresets = 0; - /* Multicast stuff */ - lp->promiscuous = 0; - lp->allmulticast = 0; - lp->mc_count = 0; - - /* Init spinlock */ - spin_lock_init(&lp->spinlock); - - /* back links */ - lp->dev = dev; - - /* wavelan NET3 callbacks */ - dev->netdev_ops = &wavelan_netdev_ops; - dev->watchdog_timeo = WATCHDOG_JIFFIES; - SET_ETHTOOL_OPS(dev, &ops); - - dev->wireless_handlers = &wavelan_handler_def; - lp->wireless_data.spy_data = &lp->spy_data; - dev->wireless_data = &lp->wireless_data; - - /* Other specific data */ - dev->mtu = WAVELAN_MTU; - - ret = wv_pcmcia_config(p_dev); - if (ret) - return ret; - - ret = wv_hw_config(dev); - if (ret) { - dev->irq = 0; - pcmcia_disable_device(p_dev); - return ret; - } - - wv_init_info(dev); - -#ifdef DEBUG_CALLBACK_TRACE - printk(KERN_DEBUG "<- wavelan_attach()\n"); -#endif - - return 0; -} - -/*------------------------------------------------------------------*/ -/* - * This deletes a driver "instance". The device is de-registered with - * Card Services. If it has been released, all local data structures - * are freed. Otherwise, the structures will be freed when the device - * is released. - */ -static void -wavelan_detach(struct pcmcia_device *link) -{ -#ifdef DEBUG_CALLBACK_TRACE - printk(KERN_DEBUG "-> wavelan_detach(0x%p)\n", link); -#endif - - /* Some others haven't done their job : give them another chance */ - wv_pcmcia_release(link); - - /* Free pieces */ - if(link->priv) - { - struct net_device * dev = (struct net_device *) link->priv; - - /* Remove ourselves from the kernel list of ethernet devices */ - /* Warning : can't be called from interrupt, timer or wavelan_close() */ - if (link->dev_node) - unregister_netdev(dev); - link->dev_node = NULL; - ((net_local *)netdev_priv(dev))->link = NULL; - ((net_local *)netdev_priv(dev))->dev = NULL; - free_netdev(dev); - } - -#ifdef DEBUG_CALLBACK_TRACE - printk(KERN_DEBUG "<- wavelan_detach()\n"); -#endif -} - -static int wavelan_suspend(struct pcmcia_device *link) -{ - struct net_device * dev = (struct net_device *) link->priv; - - /* NB: wavelan_close will be called, but too late, so we are - * obliged to close nicely the wavelan here. David, could you - * close the device before suspending them ? And, by the way, - * could you, on resume, add a "route add -net ..." after the - * ifconfig up ? Thanks... */ - - /* Stop receiving new messages and wait end of transmission */ - wv_ru_stop(dev); - - if (link->open) - netif_device_detach(dev); - - /* Power down the module */ - hacr_write(dev->base_addr, HACR_DEFAULT & (~HACR_PWR_STAT)); - - return 0; -} - -static int wavelan_resume(struct pcmcia_device *link) -{ - struct net_device * dev = (struct net_device *) link->priv; - - if (link->open) { - wv_hw_reset(dev); - netif_device_attach(dev); - } - - return 0; -} - - -static struct pcmcia_device_id wavelan_ids[] = { - PCMCIA_DEVICE_PROD_ID12("AT&T","WaveLAN/PCMCIA", 0xe7c5affd, 0x1bc50975), - PCMCIA_DEVICE_PROD_ID12("Digital", "RoamAbout/DS", 0x9999ab35, 0x00d05e06), - PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/PCMCIA", 0x23eb9949, 0x1bc50975), - PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/PCMCIA", 0x24358cd4, 0x1bc50975), - PCMCIA_DEVICE_NULL, -}; -MODULE_DEVICE_TABLE(pcmcia, wavelan_ids); - -static struct pcmcia_driver wavelan_driver = { - .owner = THIS_MODULE, - .drv = { - .name = "wavelan_cs", - }, - .probe = wavelan_probe, - .remove = wavelan_detach, - .id_table = wavelan_ids, - .suspend = wavelan_suspend, - .resume = wavelan_resume, -}; - -static int __init -init_wavelan_cs(void) -{ - return pcmcia_register_driver(&wavelan_driver); -} - -static void __exit -exit_wavelan_cs(void) -{ - pcmcia_unregister_driver(&wavelan_driver); -} - -module_init(init_wavelan_cs); -module_exit(exit_wavelan_cs); diff --git a/drivers/staging/wavelan/wavelan_cs.h b/drivers/staging/wavelan/wavelan_cs.h deleted file mode 100644 index 42e268dbae98..000000000000 --- a/drivers/staging/wavelan/wavelan_cs.h +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Wavelan Pcmcia driver - * - * Jean II - HPLB '96 - * - * Reorganization and extension of the driver. - * Original copyright follow. See wavelan_cs.h for details. - * - * This file contain the declarations of the Wavelan hardware. Note that - * the Pcmcia Wavelan include a i82593 controller (see definitions in - * file i82593.h). - * - * The main difference between the pcmcia hardware and the ISA one is - * the Ethernet Controller (i82593 instead of i82586). The i82593 allow - * only one send buffer. The PSA (Parameter Storage Area : EEprom for - * permanent storage of various info) is memory mapped, but not the - * MMI (Modem Management Interface). - */ - -/* - * Definitions for the AT&T GIS (formerly NCR) WaveLAN PCMCIA card: - * An Ethernet-like radio transceiver controlled by an Intel 82593 - * coprocessor. - * - * - **************************************************************************** - * Copyright 1995 - * Anthony D. Joseph - * Massachusetts Institute of Technology - * - * Permission to use, copy, modify, and distribute this program - * for any purpose and without fee is hereby granted, provided - * that this copyright and permission notice appear on all copies - * and supporting documentation, the name of M.I.T. not be used - * in advertising or publicity pertaining to distribution of the - * program without specific prior permission, and notice be given - * in supporting documentation that copying and distribution is - * by permission of M.I.T. M.I.T. makes no representations about - * the suitability of this software for any purpose. It is pro- - * vided "as is" without express or implied warranty. - **************************************************************************** - * - * - * Credits: - * Special thanks to Jan Hoogendoorn of AT&T GIS Utrecht for - * providing extremely useful information about WaveLAN PCMCIA hardware - * - * This driver is based upon several other drivers, in particular: - * David Hinds' Linux driver for the PCMCIA 3c589 ethernet adapter - * Bruce Janson's Linux driver for the AT-bus WaveLAN adapter - * Anders Klemets' PCMCIA WaveLAN adapter driver - * Robert Morris' BSDI driver for the PCMCIA WaveLAN adapter - */ - -#ifndef _WAVELAN_CS_H -#define _WAVELAN_CS_H - -/************************** MAGIC NUMBERS ***************************/ - -/* The detection of the wavelan card is made by reading the MAC address - * from the card and checking it. If you have a non AT&T product (OEM, - * like DEC RoamAbout, or Digital Ocean, Epson, ...), you must modify this - * part to accommodate your hardware... - */ -static const unsigned char MAC_ADDRESSES[][3] = { - { 0x08, 0x00, 0x0E }, /* AT&T Wavelan (standard) & DEC RoamAbout */ - { 0x08, 0x00, 0x6A }, /* AT&T Wavelan (alternate) */ - { 0x00, 0x00, 0xE1 }, /* Hitachi Wavelan */ - { 0x00, 0x60, 0x1D } /* Lucent Wavelan (another one) */ - /* Add your card here and send me the patch ! */ -}; - -/* - * Constants used to convert channels to frequencies - */ - -/* Frequency available in the 2.0 modem, in units of 250 kHz - * (as read in the offset register of the dac area). - * Used to map channel numbers used by `wfreqsel' to frequencies - */ -static const short channel_bands[] = { 0x30, 0x58, 0x64, 0x7A, 0x80, 0xA8, - 0xD0, 0xF0, 0xF8, 0x150 }; - -/* Frequencies of the 1.0 modem (fixed frequencies). - * Use to map the PSA `subband' to a frequency - * Note : all frequencies apart from the first one need to be multiplied by 10 - */ -static const int fixed_bands[] = { 915e6, 2.425e8, 2.46e8, 2.484e8, 2.4305e8 }; - - -/*************************** PC INTERFACE ****************************/ - -/* WaveLAN host interface definitions */ - -#define LCCR(base) (base) /* LAN Controller Command Register */ -#define LCSR(base) (base) /* LAN Controller Status Register */ -#define HACR(base) (base+0x1) /* Host Adapter Command Register */ -#define HASR(base) (base+0x1) /* Host Adapter Status Register */ -#define PIORL(base) (base+0x2) /* Program I/O Register Low */ -#define RPLL(base) (base+0x2) /* Receive Pointer Latched Low */ -#define PIORH(base) (base+0x3) /* Program I/O Register High */ -#define RPLH(base) (base+0x3) /* Receive Pointer Latched High */ -#define PIOP(base) (base+0x4) /* Program I/O Port */ -#define MMR(base) (base+0x6) /* MMI Address Register */ -#define MMD(base) (base+0x7) /* MMI Data Register */ - -/* Host Adaptor Command Register bit definitions */ - -#define HACR_LOF (1 << 3) /* Lock Out Flag, toggle every 250ms */ -#define HACR_PWR_STAT (1 << 4) /* Power State, 1=active, 0=sleep */ -#define HACR_TX_DMA_RESET (1 << 5) /* Reset transmit DMA ptr on high */ -#define HACR_RX_DMA_RESET (1 << 6) /* Reset receive DMA ptr on high */ -#define HACR_ROM_WEN (1 << 7) /* EEPROM write enabled when true */ - -#define HACR_RESET (HACR_TX_DMA_RESET | HACR_RX_DMA_RESET) -#define HACR_DEFAULT (HACR_PWR_STAT) - -/* Host Adapter Status Register bit definitions */ - -#define HASR_MMI_BUSY (1 << 2) /* MMI is busy when true */ -#define HASR_LOF (1 << 3) /* Lock out flag status */ -#define HASR_NO_CLK (1 << 4) /* active when modem not connected */ - -/* Miscellaneous bit definitions */ - -#define PIORH_SEL_TX (1 << 5) /* PIOR points to 0=rx/1=tx buffer */ -#define MMR_MMI_WR (1 << 0) /* Next MMI cycle is 0=read, 1=write */ -#define PIORH_MASK 0x1f /* only low 5 bits are significant */ -#define RPLH_MASK 0x1f /* only low 5 bits are significant */ -#define MMI_ADDR_MASK 0x7e /* Bits 1-6 of MMR are significant */ - -/* Attribute Memory map */ - -#define CIS_ADDR 0x0000 /* Card Information Status Register */ -#define PSA_ADDR 0x0e00 /* Parameter Storage Area address */ -#define EEPROM_ADDR 0x1000 /* EEPROM address (unused ?) */ -#define COR_ADDR 0x4000 /* Configuration Option Register */ - -/* Configuration Option Register bit definitions */ - -#define COR_CONFIG (1 << 0) /* Config Index, 0 when unconfigured */ -#define COR_SW_RESET (1 << 7) /* Software Reset on true */ -#define COR_LEVEL_IRQ (1 << 6) /* Level IRQ */ - -/* Local Memory map */ - -#define RX_BASE 0x0000 /* Receive memory, 8 kB */ -#define TX_BASE 0x2000 /* Transmit memory, 2 kB */ -#define UNUSED_BASE 0x2800 /* Unused, 22 kB */ -#define RX_SIZE (TX_BASE-RX_BASE) /* Size of receive area */ -#define RX_SIZE_SHIFT 6 /* Bits to shift in stop register */ - -#define TRUE 1 -#define FALSE 0 - -#define MOD_ENAL 1 -#define MOD_PROM 2 - -/* Size of a MAC address */ -#define WAVELAN_ADDR_SIZE 6 - -/* Maximum size of Wavelan packet */ -#define WAVELAN_MTU 1500 - -#define MAXDATAZ (6 + 6 + 2 + WAVELAN_MTU) - -/********************** PARAMETER STORAGE AREA **********************/ - -/* - * Parameter Storage Area (PSA). - */ -typedef struct psa_t psa_t; -struct psa_t { - /* For the PCMCIA Adapter, locations 0x00-0x0F are unused and fixed at 00 */ - unsigned char psa_io_base_addr_1; /* [0x00] Base address 1 ??? */ - unsigned char psa_io_base_addr_2; /* [0x01] Base address 2 */ - unsigned char psa_io_base_addr_3; /* [0x02] Base address 3 */ - unsigned char psa_io_base_addr_4; /* [0x03] Base address 4 */ - unsigned char psa_rem_boot_addr_1; /* [0x04] Remote Boot Address 1 */ - unsigned char psa_rem_boot_addr_2; /* [0x05] Remote Boot Address 2 */ - unsigned char psa_rem_boot_addr_3; /* [0x06] Remote Boot Address 3 */ - unsigned char psa_holi_params; /* [0x07] HOst Lan Interface (HOLI) Parameters */ - unsigned char psa_int_req_no; /* [0x08] Interrupt Request Line */ - unsigned char psa_unused0[7]; /* [0x09-0x0F] unused */ - - unsigned char psa_univ_mac_addr[WAVELAN_ADDR_SIZE]; /* [0x10-0x15] Universal (factory) MAC Address */ - unsigned char psa_local_mac_addr[WAVELAN_ADDR_SIZE]; /* [0x16-1B] Local MAC Address */ - unsigned char psa_univ_local_sel; /* [0x1C] Universal Local Selection */ -#define PSA_UNIVERSAL 0 /* Universal (factory) */ -#define PSA_LOCAL 1 /* Local */ - unsigned char psa_comp_number; /* [0x1D] Compatability Number: */ -#define PSA_COMP_PC_AT_915 0 /* PC-AT 915 MHz */ -#define PSA_COMP_PC_MC_915 1 /* PC-MC 915 MHz */ -#define PSA_COMP_PC_AT_2400 2 /* PC-AT 2.4 GHz */ -#define PSA_COMP_PC_MC_2400 3 /* PC-MC 2.4 GHz */ -#define PSA_COMP_PCMCIA_915 4 /* PCMCIA 915 MHz or 2.0 */ - unsigned char psa_thr_pre_set; /* [0x1E] Modem Threshold Preset */ - unsigned char psa_feature_select; /* [0x1F] Call code required (1=on) */ -#define PSA_FEATURE_CALL_CODE 0x01 /* Call code required (Japan) */ - unsigned char psa_subband; /* [0x20] Subband */ -#define PSA_SUBBAND_915 0 /* 915 MHz or 2.0 */ -#define PSA_SUBBAND_2425 1 /* 2425 MHz */ -#define PSA_SUBBAND_2460 2 /* 2460 MHz */ -#define PSA_SUBBAND_2484 3 /* 2484 MHz */ -#define PSA_SUBBAND_2430_5 4 /* 2430.5 MHz */ - unsigned char psa_quality_thr; /* [0x21] Modem Quality Threshold */ - unsigned char psa_mod_delay; /* [0x22] Modem Delay ??? (reserved) */ - unsigned char psa_nwid[2]; /* [0x23-0x24] Network ID */ - unsigned char psa_nwid_select; /* [0x25] Network ID Select On Off */ - unsigned char psa_encryption_select; /* [0x26] Encryption On Off */ - unsigned char psa_encryption_key[8]; /* [0x27-0x2E] Encryption Key */ - unsigned char psa_databus_width; /* [0x2F] AT bus width select 8/16 */ - unsigned char psa_call_code[8]; /* [0x30-0x37] (Japan) Call Code */ - unsigned char psa_nwid_prefix[2]; /* [0x38-0x39] Roaming domain */ - unsigned char psa_reserved[2]; /* [0x3A-0x3B] Reserved - fixed 00 */ - unsigned char psa_conf_status; /* [0x3C] Conf Status, bit 0=1:config*/ - unsigned char psa_crc[2]; /* [0x3D] CRC-16 over PSA */ - unsigned char psa_crc_status; /* [0x3F] CRC Valid Flag */ -}; - -/* Size for structure checking (if padding is correct) */ -#define PSA_SIZE 64 - -/* Calculate offset of a field in the above structure - * Warning : only even addresses are used */ -#define psaoff(p, f) ((unsigned short) ((void *)(&((psa_t *) ((void *) NULL + (p)))->f) - (void *) NULL)) - -/******************** MODEM MANAGEMENT INTERFACE ********************/ - -/* - * Modem Management Controller (MMC) write structure. - */ -typedef struct mmw_t mmw_t; -struct mmw_t { - unsigned char mmw_encr_key[8]; /* encryption key */ - unsigned char mmw_encr_enable; /* enable/disable encryption */ -#define MMW_ENCR_ENABLE_MODE 0x02 /* Mode of security option */ -#define MMW_ENCR_ENABLE_EN 0x01 /* Enable security option */ - unsigned char mmw_unused0[1]; /* unused */ - unsigned char mmw_des_io_invert; /* Encryption option */ -#define MMW_DES_IO_INVERT_RES 0x0F /* Reserved */ -#define MMW_DES_IO_INVERT_CTRL 0xF0 /* Control ??? (set to 0) */ - unsigned char mmw_unused1[5]; /* unused */ - unsigned char mmw_loopt_sel; /* looptest selection */ -#define MMW_LOOPT_SEL_DIS_NWID 0x40 /* disable NWID filtering */ -#define MMW_LOOPT_SEL_INT 0x20 /* activate Attention Request */ -#define MMW_LOOPT_SEL_LS 0x10 /* looptest w/o collision avoidance */ -#define MMW_LOOPT_SEL_LT3A 0x08 /* looptest 3a */ -#define MMW_LOOPT_SEL_LT3B 0x04 /* looptest 3b */ -#define MMW_LOOPT_SEL_LT3C 0x02 /* looptest 3c */ -#define MMW_LOOPT_SEL_LT3D 0x01 /* looptest 3d */ - unsigned char mmw_jabber_enable; /* jabber timer enable */ - /* Abort transmissions > 200 ms */ - unsigned char mmw_freeze; /* freeze / unfreeeze signal level */ - /* 0 : signal level & qual updated for every new message, 1 : frozen */ - unsigned char mmw_anten_sel; /* antenna selection */ -#define MMW_ANTEN_SEL_SEL 0x01 /* direct antenna selection */ -#define MMW_ANTEN_SEL_ALG_EN 0x02 /* antenna selection algo. enable */ - unsigned char mmw_ifs; /* inter frame spacing */ - /* min time between transmission in bit periods (.5 us) - bit 0 ignored */ - unsigned char mmw_mod_delay; /* modem delay (synchro) */ - unsigned char mmw_jam_time; /* jamming time (after collision) */ - unsigned char mmw_unused2[1]; /* unused */ - unsigned char mmw_thr_pre_set; /* level threshold preset */ - /* Discard all packet with signal < this value (4) */ - unsigned char mmw_decay_prm; /* decay parameters */ - unsigned char mmw_decay_updat_prm; /* decay update parameterz */ - unsigned char mmw_quality_thr; /* quality (z-quotient) threshold */ - /* Discard all packet with quality < this value (3) */ - unsigned char mmw_netw_id_l; /* NWID low order byte */ - unsigned char mmw_netw_id_h; /* NWID high order byte */ - /* Network ID or Domain : create virtual net on the air */ - - /* 2.0 Hardware extension - frequency selection support */ - unsigned char mmw_mode_select; /* for analog tests (set to 0) */ - unsigned char mmw_unused3[1]; /* unused */ - unsigned char mmw_fee_ctrl; /* frequency eeprom control */ -#define MMW_FEE_CTRL_PRE 0x10 /* Enable protected instructions */ -#define MMW_FEE_CTRL_DWLD 0x08 /* Download eeprom to mmc */ -#define MMW_FEE_CTRL_CMD 0x07 /* EEprom commands : */ -#define MMW_FEE_CTRL_READ 0x06 /* Read */ -#define MMW_FEE_CTRL_WREN 0x04 /* Write enable */ -#define MMW_FEE_CTRL_WRITE 0x05 /* Write data to address */ -#define MMW_FEE_CTRL_WRALL 0x04 /* Write data to all addresses */ -#define MMW_FEE_CTRL_WDS 0x04 /* Write disable */ -#define MMW_FEE_CTRL_PRREAD 0x16 /* Read addr from protect register */ -#define MMW_FEE_CTRL_PREN 0x14 /* Protect register enable */ -#define MMW_FEE_CTRL_PRCLEAR 0x17 /* Unprotect all registers */ -#define MMW_FEE_CTRL_PRWRITE 0x15 /* Write addr in protect register */ -#define MMW_FEE_CTRL_PRDS 0x14 /* Protect register disable */ - /* Never issue this command (PRDS) : it's irreversible !!! */ - - unsigned char mmw_fee_addr; /* EEprom address */ -#define MMW_FEE_ADDR_CHANNEL 0xF0 /* Select the channel */ -#define MMW_FEE_ADDR_OFFSET 0x0F /* Offset in channel data */ -#define MMW_FEE_ADDR_EN 0xC0 /* FEE_CTRL enable operations */ -#define MMW_FEE_ADDR_DS 0x00 /* FEE_CTRL disable operations */ -#define MMW_FEE_ADDR_ALL 0x40 /* FEE_CTRL all operations */ -#define MMW_FEE_ADDR_CLEAR 0xFF /* FEE_CTRL clear operations */ - - unsigned char mmw_fee_data_l; /* Write data to EEprom */ - unsigned char mmw_fee_data_h; /* high octet */ - unsigned char mmw_ext_ant; /* Setting for external antenna */ -#define MMW_EXT_ANT_EXTANT 0x01 /* Select external antenna */ -#define MMW_EXT_ANT_POL 0x02 /* Polarity of the antenna */ -#define MMW_EXT_ANT_INTERNAL 0x00 /* Internal antenna */ -#define MMW_EXT_ANT_EXTERNAL 0x03 /* External antenna */ -#define MMW_EXT_ANT_IQ_TEST 0x1C /* IQ test pattern (set to 0) */ -} __attribute__((packed)); - -/* Size for structure checking (if padding is correct) */ -#define MMW_SIZE 37 - -/* Calculate offset of a field in the above structure */ -#define mmwoff(p, f) (unsigned short)((void *)(&((mmw_t *)((void *)0 + (p)))->f) - (void *)0) - - -/* - * Modem Management Controller (MMC) read structure. - */ -typedef struct mmr_t mmr_t; -struct mmr_t { - unsigned char mmr_unused0[8]; /* unused */ - unsigned char mmr_des_status; /* encryption status */ - unsigned char mmr_des_avail; /* encryption available (0x55 read) */ -#define MMR_DES_AVAIL_DES 0x55 /* DES available */ -#define MMR_DES_AVAIL_AES 0x33 /* AES (AT&T) available */ - unsigned char mmr_des_io_invert; /* des I/O invert register */ - unsigned char mmr_unused1[5]; /* unused */ - unsigned char mmr_dce_status; /* DCE status */ -#define MMR_DCE_STATUS_RX_BUSY 0x01 /* receiver busy */ -#define MMR_DCE_STATUS_LOOPT_IND 0x02 /* loop test indicated */ -#define MMR_DCE_STATUS_TX_BUSY 0x04 /* transmitter on */ -#define MMR_DCE_STATUS_JBR_EXPIRED 0x08 /* jabber timer expired */ -#define MMR_DCE_STATUS 0x0F /* mask to get the bits */ - unsigned char mmr_dsp_id; /* DSP id (AA = Daedalus rev A) */ - unsigned char mmr_unused2[2]; /* unused */ - unsigned char mmr_correct_nwid_l; /* # of correct NWID's rxd (low) */ - unsigned char mmr_correct_nwid_h; /* # of correct NWID's rxd (high) */ - /* Warning : Read high order octet first !!! */ - unsigned char mmr_wrong_nwid_l; /* # of wrong NWID's rxd (low) */ - unsigned char mmr_wrong_nwid_h; /* # of wrong NWID's rxd (high) */ - unsigned char mmr_thr_pre_set; /* level threshold preset */ -#define MMR_THR_PRE_SET 0x3F /* level threshold preset */ -#define MMR_THR_PRE_SET_CUR 0x80 /* Current signal above it */ - unsigned char mmr_signal_lvl; /* signal level */ -#define MMR_SIGNAL_LVL 0x3F /* signal level */ -#define MMR_SIGNAL_LVL_VALID 0x80 /* Updated since last read */ - unsigned char mmr_silence_lvl; /* silence level (noise) */ -#define MMR_SILENCE_LVL 0x3F /* silence level */ -#define MMR_SILENCE_LVL_VALID 0x80 /* Updated since last read */ - unsigned char mmr_sgnl_qual; /* signal quality */ -#define MMR_SGNL_QUAL 0x0F /* signal quality */ -#define MMR_SGNL_QUAL_ANT 0x80 /* current antenna used */ - unsigned char mmr_netw_id_l; /* NWID low order byte ??? */ - unsigned char mmr_unused3[3]; /* unused */ - - /* 2.0 Hardware extension - frequency selection support */ - unsigned char mmr_fee_status; /* Status of frequency eeprom */ -#define MMR_FEE_STATUS_ID 0xF0 /* Modem revision id */ -#define MMR_FEE_STATUS_DWLD 0x08 /* Download in progress */ -#define MMR_FEE_STATUS_BUSY 0x04 /* EEprom busy */ - unsigned char mmr_unused4[1]; /* unused */ - unsigned char mmr_fee_data_l; /* Read data from eeprom (low) */ - unsigned char mmr_fee_data_h; /* Read data from eeprom (high) */ -}; - -/* Size for structure checking (if padding is correct) */ -#define MMR_SIZE 36 - -/* Calculate offset of a field in the above structure */ -#define mmroff(p, f) (unsigned short)((void *)(&((mmr_t *)((void *)0 + (p)))->f) - (void *)0) - - -/* Make the two above structures one */ -typedef union mm_t { - struct mmw_t w; /* Write to the mmc */ - struct mmr_t r; /* Read from the mmc */ -} mm_t; - -#endif /* _WAVELAN_CS_H */ diff --git a/drivers/staging/wavelan/wavelan_cs.p.h b/drivers/staging/wavelan/wavelan_cs.p.h deleted file mode 100644 index 7196267976f0..000000000000 --- a/drivers/staging/wavelan/wavelan_cs.p.h +++ /dev/null @@ -1,762 +0,0 @@ -/* - * Wavelan Pcmcia driver - * - * Jean II - HPLB '96 - * - * Reorganisation and extension of the driver. - * - * This file contain all definition and declarations necessary for the - * wavelan pcmcia driver. This file is a private header, so it should - * be included only on wavelan_cs.c !!! - */ - -#ifndef WAVELAN_CS_P_H -#define WAVELAN_CS_P_H - -/************************** DOCUMENTATION **************************/ -/* - * This driver provide a Linux interface to the Wavelan Pcmcia hardware - * The Wavelan is a product of Lucent (http://www.wavelan.com/). - * This division was formerly part of NCR and then AT&T. - * Wavelan are also distributed by DEC (RoamAbout DS)... - * - * To know how to use this driver, read the PCMCIA HOWTO. - * If you want to exploit the many other fonctionalities, look comments - * in the code... - * - * This driver is the result of the effort of many peoples (see below). - */ - -/* ------------------------ SPECIFIC NOTES ------------------------ */ -/* - * Web page - * -------- - * I try to maintain a web page with the Wireless LAN Howto at : - * http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Wavelan.html - * - * SMP - * --- - * We now are SMP compliant (I eventually fixed the remaining bugs). - * The driver has been tested on a dual P6-150 and survived my usual - * set of torture tests. - * Anyway, I spent enough time chasing interrupt re-entrancy during - * errors or reconfigure, and I designed the locked/unlocked sections - * of the driver with great care, and with the recent addition of - * the spinlock (thanks to the new API), we should be quite close to - * the truth. - * The SMP/IRQ locking is quite coarse and conservative (i.e. not fast), - * but better safe than sorry (especially at 2 Mb/s ;-). - * - * I have also looked into disabling only our interrupt on the card - * (via HACR) instead of all interrupts in the processor (via cli), - * so that other driver are not impacted, and it look like it's - * possible, but it's very tricky to do right (full of races). As - * the gain would be mostly for SMP systems, it can wait... - * - * Debugging and options - * --------------------- - * You will find below a set of '#define" allowing a very fine control - * on the driver behaviour and the debug messages printed. - * The main options are : - * o WAVELAN_ROAMING, for the experimental roaming support. - * o SET_PSA_CRC, to have your card correctly recognised by - * an access point and the Point-to-Point diagnostic tool. - * o USE_PSA_CONFIG, to read configuration from the PSA (EEprom) - * (otherwise we always start afresh with some defaults) - * - * wavelan_cs.o is darn too big - * ------------------------- - * That's true ! There is a very simple way to reduce the driver - * object by 33% (yes !). Comment out the following line : - * #include - * Other compile options can also reduce the size of it... - * - * MAC address and hardware detection : - * ---------------------------------- - * The detection code of the wavelan chech that the first 3 - * octets of the MAC address fit the company code. This type of - * detection work well for AT&T cards (because the AT&T code is - * hardcoded in wavelan_cs.h), but of course will fail for other - * manufacturer. - * - * If you are sure that your card is derived from the wavelan, - * here is the way to configure it : - * 1) Get your MAC address - * a) With your card utilities (wfreqsel, instconf, ...) - * b) With the driver : - * o compile the kernel with DEBUG_CONFIG_INFO enabled - * o Boot and look the card messages - * 2) Set your MAC code (3 octets) in MAC_ADDRESSES[][3] (wavelan_cs.h) - * 3) Compile & verify - * 4) Send me the MAC code - I will include it in the next version... - * - */ - -/* --------------------- WIRELESS EXTENSIONS --------------------- */ -/* - * This driver is the first one to support "wireless extensions". - * This set of extensions provide you some way to control the wireless - * caracteristics of the hardware in a standard way and support for - * applications for taking advantage of it (like Mobile IP). - * - * It might be a good idea as well to fetch the wireless tools to - * configure the device and play a bit. - */ - -/* ---------------------------- FILES ---------------------------- */ -/* - * wavelan_cs.c : The actual code for the driver - C functions - * - * wavelan_cs.p.h : Private header : local types / vars for the driver - * - * wavelan_cs.h : Description of the hardware interface & structs - * - * i82593.h : Description if the Ethernet controller - */ - -/* --------------------------- HISTORY --------------------------- */ -/* - * The history of the Wavelan drivers is as complicated as history of - * the Wavelan itself (NCR -> AT&T -> Lucent). - * - * All started with Anders Klemets , - * writing a Wavelan ISA driver for the MACH microkernel. Girish - * Welling had also worked on it. - * Keith Moore modify this for the Pcmcia hardware. - * - * Robert Morris port these two drivers to BSDI - * and add specific Pcmcia support (there is currently no equivalent - * of the PCMCIA package under BSD...). - * - * Jim Binkley port both BSDI drivers to FreeBSD. - * - * Bruce Janson port the BSDI ISA driver to Linux. - * - * Anthony D. Joseph started modify Bruce driver - * (with help of the BSDI PCMCIA driver) for PCMCIA. - * Yunzhou Li finished is work. - * Joe Finney patched the driver to start - * correctly 2.00 cards (2.4 GHz with frequency selection). - * David Hinds integrated the whole in his - * Pcmcia package (+ bug corrections). - * - * I (Jean Tourrilhes - jt@hplb.hpl.hp.com) then started to make some - * patchs to the Pcmcia driver. After, I added code in the ISA driver - * for Wireless Extensions and full support of frequency selection - * cards. Now, I'm doing the same to the Pcmcia driver + some - * reorganisation. - * Loeke Brederveld from Lucent has given me - * much needed informations on the Wavelan hardware. - */ - -/* By the way : for the copyright & legal stuff : - * Almost everybody wrote code under GNU or BSD license (or alike), - * and want that their original copyright remain somewhere in the - * code (for myself, I go with the GPL). - * Nobody want to take responsibility for anything, except the fame... - */ - -/* --------------------------- CREDITS --------------------------- */ -/* - * Credits: - * Special thanks to Jan Hoogendoorn of AT&T GIS Utrecht and - * Loeke Brederveld of Lucent for providing extremely useful - * information about WaveLAN PCMCIA hardware - * - * This driver is based upon several other drivers, in particular: - * David Hinds' Linux driver for the PCMCIA 3c589 ethernet adapter - * Bruce Janson's Linux driver for the AT-bus WaveLAN adapter - * Anders Klemets' PCMCIA WaveLAN adapter driver - * Robert Morris' BSDI driver for the PCMCIA WaveLAN adapter - * - * Additional Credits: - * - * This software was originally developed under Linux 1.2.3 - * (Slackware 2.0 distribution). - * And then under Linux 2.0.x (Debian 1.1 -> 2.2 - pcmcia 2.8.18+) - * with an HP OmniBook 4000 and then a 5500. - * - * It is based on other device drivers and information either written - * or supplied by: - * James Ashton (jaa101@syseng.anu.edu.au), - * Ajay Bakre (bakre@paul.rutgers.edu), - * Donald Becker (becker@super.org), - * Jim Binkley , - * Loeke Brederveld , - * Allan Creighton (allanc@cs.su.oz.au), - * Brent Elphick , - * Joe Finney , - * Matthew Geier (matthew@cs.su.oz.au), - * Remo di Giovanni (remo@cs.su.oz.au), - * Mark Hagan (mhagan@wtcpost.daytonoh.NCR.COM), - * David Hinds , - * Jan Hoogendoorn (c/o marteijn@lucent.com), - * Bruce Janson , - * Anthony D. Joseph , - * Anders Klemets (klemets@paul.rutgers.edu), - * Yunzhou Li , - * Marc Meertens (mmeertens@lucent.com), - * Keith Moore, - * Robert Morris (rtm@das.harvard.edu), - * Ian Parkin (ian@cs.su.oz.au), - * John Rosenberg (johnr@cs.su.oz.au), - * George Rossi (george@phm.gov.au), - * Arthur Scott (arthur@cs.su.oz.au), - * Stanislav Sinyagin - * Peter Storey, - * Jean Tourrilhes , - * Girish Welling (welling@paul.rutgers.edu) - * Clark Woodworth - * Yongguang Zhang ... - */ - -/* ------------------------- IMPROVEMENTS ------------------------- */ -/* - * I proudly present : - * - * Changes made in 2.8.22 : - * ---------------------- - * - improved wv_set_multicast_list - * - catch spurious interrupt - * - correct release of the device - * - * Changes mades in release : - * ------------------------ - * - Reorganisation of the code, function name change - * - Creation of private header (wavelan_cs.h) - * - Reorganised debug messages - * - More comments, history, ... - * - Configure earlier (in "insert" instead of "open") - * and do things only once - * - mmc_init : configure the PSA if not done - * - mmc_init : 2.00 detection better code for 2.00 init - * - better info at startup - * - Correct a HUGE bug (volatile & uncalibrated busy loop) - * in wv_82593_cmd => config speedup - * - Stop receiving & power down on close (and power up on open) - * use "ifconfig down" & "ifconfig up ; route add -net ..." - * - Send packets : add watchdog instead of pooling - * - Receive : check frame wrap around & try to recover some frames - * - wavelan_set_multicast_list : avoid reset - * - add wireless extensions (ioctl & get_wireless_stats) - * get/set nwid/frequency on fly, info for /proc/net/wireless - * - Suppress useless stuff from lp (net_local), but add link - * - More inlines - * - Lot of others minor details & cleanups - * - * Changes made in second release : - * ------------------------------ - * - Optimise wv_85893_reconfig stuff, fix potential problems - * - Change error values for ioctl - * - Non blocking wv_ru_stop() + call wv_reset() in case of problems - * - Remove development printk from wavelan_watchdog() - * - Remove of the watchdog to wavelan_close instead of wavelan_release - * fix potential problems... - * - Start debugging suspend stuff (but it's still a bit weird) - * - Debug & optimize dump header/packet in Rx & Tx (debug) - * - Use "readb" and "writeb" to be kernel 2.1 compliant - * - Better handling of bogus interrupts - * - Wireless extension : SETSPY and GETSPY - * - Remove old stuff (stats - for those needing it, just ask me...) - * - Make wireless extensions optional - * - * Changes made in third release : - * ----------------------------- - * - cleanups & typos - * - modif wireless ext (spy -> only one pointer) - * - new private ioctl to set/get quality & level threshold - * - Init : correct default value of level threshold for pcmcia - * - kill watchdog in hw_reset - * - more 2.1 support (copy_to/from_user instead of memcpy_to/fromfs) - * - Add message level (debug stuff in /var/adm/debug & errors not - * displayed at console and still in /var/adm/messages) - * - * Changes made in fourth release : - * ------------------------------ - * - multicast support (yes !) thanks to Yongguang Zhang. - * - * Changes made in fifth release (2.9.0) : - * ------------------------------------- - * - Revisited multicast code (it was mostly wrong). - * - protect code in wv_82593_reconfig with dev->tbusy (oups !) - * - * Changes made in sixth release (2.9.1a) : - * -------------------------------------- - * - Change the detection code for multi manufacturer code support - * - Correct bug (hang kernel) in init when we were "rejecting" a card - * - * Changes made in seventh release (2.9.1b) : - * ---------------------------------------- - * - Update to wireless extensions changes - * - Silly bug in card initial configuration (psa_conf_status) - * - * Changes made in eigth release : - * ----------------------------- - * - Small bug in debug code (probably not the last one...) - * - 1.2.13 support (thanks to Clark Woodworth) - * - * Changes made for release in 2.9.2b : - * ---------------------------------- - * - Level threshold is now a standard wireless extension (version 4 !) - * - modules parameters types for kernel > 2.1.17 - * - updated man page - * - Others cleanup from David Hinds - * - * Changes made for release in 2.9.5 : - * --------------------------------- - * - byte count stats (courtesy of David Hinds) - * - Remove dev_tint stuff (courtesy of David Hinds) - * - Others cleanup from David Hinds - * - Encryption setting from Brent Elphick (thanks a lot !) - * - 'base' to 'u_long' for the Alpha (thanks to Stanislav Sinyagin) - * - * Changes made for release in 2.9.6 : - * --------------------------------- - * - fix bug : no longuer disable watchdog in case of bogus interrupt - * - increase timeout in config code for picky hardware - * - mask unused bits in status (Wireless Extensions) - * - * Changes integrated by Justin Seger & David Hinds : - * ----------------------------------------------------------------- - * - Roaming "hack" from Joe Finney - * - PSA CRC code from Bob Gray - * - Better initialisation of the i82593 controller - * from Joseph K. O'Sullivan - * - * Changes made for release in 3.0.10 : - * ---------------------------------- - * - Fix eject "hang" of the driver under 2.2.X : - * o create wv_flush_stale_links() - * o Rename wavelan_release to wv_pcmcia_release & move up - * o move unregister_netdev to wavelan_detach() - * o wavelan_release() no longer call wavelan_detach() - * o Suppress "release" timer - * o Other cleanups & fixes - * - New MAC address in the probe - * - Reorg PSA_CRC code (endian neutral & cleaner) - * - Correct initialisation of the i82593 from Lucent manual - * - Put back the watchdog, with larger timeout - * - TRANSMIT_NO_CRC is a "normal" error, so recover from it - * from Derrick J Brashear - * - Better handling of TX and RX normal failure conditions - * - #ifdef out all the roaming code - * - Add ESSID & "AP current address" ioctl stubs - * - General cleanup of the code - * - * Changes made for release in 3.0.13 : - * ---------------------------------- - * - Re-enable compilation of roaming code by default, but with - * do_roaming = 0 - * - Nuke `nwid=nwid^ntohs(beacon->domain_id)' in wl_roam_gather - * at the demand of John Carol Langford - * - Introduced WAVELAN_ROAMING_EXT for incomplete ESSID stuff. - * - * Changes made for release in 3.0.15 : - * ---------------------------------- - * - Change e-mail and web page addresses - * - Watchdog timer is now correctly expressed in HZ, not in jiffies - * - Add channel number to the list of frequencies in range - * - Add the (short) list of bit-rates in range - * - Developp a new sensitivity... (sens.value & sens.fixed) - * - * Changes made for release in 3.1.2 : - * --------------------------------- - * - Fix check for root permission (break instead of exit) - * - New nwid & encoding setting (Wireless Extension 9) - * - * Changes made for release in 3.1.12 : - * ---------------------------------- - * - reworked wv_82593_cmd to avoid using the IRQ handler and doing - * ugly things with interrupts. - * - Add IRQ protection in 82593_config/ru_start/ru_stop/watchdog - * - Update to new network API (softnet - 2.3.43) : - * o replace dev->tbusy (David + me) - * o replace dev->tstart (David + me) - * o remove dev->interrupt (David) - * o add SMP locking via spinlock in splxx (me) - * o add spinlock in interrupt handler (me) - * o use kernel watchdog instead of ours (me) - * o verify that all the changes make sense and work (me) - * - Re-sync kernel/pcmcia versions (not much actually) - * - A few other cleanups (David & me)... - * - * Changes made for release in 3.1.22 : - * ---------------------------------- - * - Check that SMP works, remove annoying log message - * - * Changes made for release in 3.1.24 : - * ---------------------------------- - * - Fix unfrequent card lockup when watchdog was reseting the hardware : - * o control first busy loop in wv_82593_cmd() - * o Extend spinlock protection in wv_hw_config() - * - * Changes made for release in 3.1.33 : - * ---------------------------------- - * - Optional use new driver API for Wireless Extensions : - * o got rid of wavelan_ioctl() - * o use a bunch of iw_handler instead - * - * Changes made for release in 3.2.1 : - * --------------------------------- - * - Set dev->trans_start to avoid filling the logs - * (and generating useless abort commands) - * - Avoid deadlocks in mmc_out()/mmc_in() - * - * Wishes & dreams: - * ---------------- - * - Cleanup and integrate the roaming code - * (std debug, set DomainID, decay avg and co...) - */ - -/***************************** INCLUDES *****************************/ - -/* Linux headers that we need */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include /* Wireless extensions */ -#include /* New driver API */ - -/* Pcmcia headers that we need */ -#include -#include -#include -#include -#include - -/* Wavelan declarations */ -#include /* Definitions for the Intel chip */ - -#include "wavelan_cs.h" /* Others bits of the hardware */ - -/************************** DRIVER OPTIONS **************************/ -/* - * `#define' or `#undef' the following constant to change the behaviour - * of the driver... - */ -#define WAVELAN_ROAMING /* Include experimental roaming code */ -#undef WAVELAN_ROAMING_EXT /* Enable roaming wireless extensions */ -#undef SET_PSA_CRC /* Set the CRC in PSA (slower) */ -#define USE_PSA_CONFIG /* Use info from the PSA */ -#undef EEPROM_IS_PROTECTED /* Doesn't seem to be necessary */ -#define MULTICAST_AVOID /* Avoid extra multicast (I'm sceptical) */ -#undef SET_MAC_ADDRESS /* Experimental */ - -/* Warning : these stuff will slow down the driver... */ -#define WIRELESS_SPY /* Enable spying addresses */ -#undef HISTOGRAM /* Enable histogram of sig level... */ - -/****************************** DEBUG ******************************/ - -#undef DEBUG_MODULE_TRACE /* Module insertion/removal */ -#undef DEBUG_CALLBACK_TRACE /* Calls made by Linux */ -#undef DEBUG_INTERRUPT_TRACE /* Calls to handler */ -#undef DEBUG_INTERRUPT_INFO /* type of interrupt & so on */ -#define DEBUG_INTERRUPT_ERROR /* problems */ -#undef DEBUG_CONFIG_TRACE /* Trace the config functions */ -#undef DEBUG_CONFIG_INFO /* What's going on... */ -#define DEBUG_CONFIG_ERRORS /* Errors on configuration */ -#undef DEBUG_TX_TRACE /* Transmission calls */ -#undef DEBUG_TX_INFO /* Header of the transmitted packet */ -#undef DEBUG_TX_FAIL /* Normal failure conditions */ -#define DEBUG_TX_ERROR /* Unexpected conditions */ -#undef DEBUG_RX_TRACE /* Transmission calls */ -#undef DEBUG_RX_INFO /* Header of the transmitted packet */ -#undef DEBUG_RX_FAIL /* Normal failure conditions */ -#define DEBUG_RX_ERROR /* Unexpected conditions */ -#undef DEBUG_PACKET_DUMP /* Dump packet on the screen */ -#undef DEBUG_IOCTL_TRACE /* Misc call by Linux */ -#undef DEBUG_IOCTL_INFO /* Various debug info */ -#define DEBUG_IOCTL_ERROR /* What's going wrong */ -#define DEBUG_BASIC_SHOW /* Show basic startup info */ -#undef DEBUG_VERSION_SHOW /* Print version info */ -#undef DEBUG_PSA_SHOW /* Dump psa to screen */ -#undef DEBUG_MMC_SHOW /* Dump mmc to screen */ -#undef DEBUG_SHOW_UNUSED /* Show also unused fields */ -#undef DEBUG_I82593_SHOW /* Show i82593 status */ -#undef DEBUG_DEVICE_SHOW /* Show device parameters */ - -/************************ CONSTANTS & MACROS ************************/ - -#ifdef DEBUG_VERSION_SHOW -static const char *version = "wavelan_cs.c : v24 (SMP + wireless extensions) 11/1/02\n"; -#endif - -/* Watchdog temporisation */ -#define WATCHDOG_JIFFIES (256*HZ/100) - -/* Fix a bug in some old wireless extension definitions */ -#ifndef IW_ESSID_MAX_SIZE -#define IW_ESSID_MAX_SIZE 32 -#endif - -/* ------------------------ PRIVATE IOCTL ------------------------ */ - -#define SIOCSIPQTHR SIOCIWFIRSTPRIV /* Set quality threshold */ -#define SIOCGIPQTHR (SIOCIWFIRSTPRIV + 1) /* Get quality threshold */ -#define SIOCSIPROAM (SIOCIWFIRSTPRIV + 2) /* Set roaming state */ -#define SIOCGIPROAM (SIOCIWFIRSTPRIV + 3) /* Get roaming state */ - -#define SIOCSIPHISTO (SIOCIWFIRSTPRIV + 4) /* Set histogram ranges */ -#define SIOCGIPHISTO (SIOCIWFIRSTPRIV + 5) /* Get histogram values */ - -/*************************** WaveLAN Roaming **************************/ -#ifdef WAVELAN_ROAMING /* Conditional compile, see above in options */ - -#define WAVELAN_ROAMING_DEBUG 0 /* 1 = Trace of handover decisions */ - /* 2 = Info on each beacon rcvd... */ -#define MAX_WAVEPOINTS 7 /* Max visible at one time */ -#define WAVEPOINT_HISTORY 5 /* SNR sample history slow search */ -#define WAVEPOINT_FAST_HISTORY 2 /* SNR sample history fast search */ -#define SEARCH_THRESH_LOW 10 /* SNR to enter cell search */ -#define SEARCH_THRESH_HIGH 13 /* SNR to leave cell search */ -#define WAVELAN_ROAMING_DELTA 1 /* Hysteresis value (+/- SNR) */ -#define CELL_TIMEOUT (2*HZ) /* in jiffies */ - -#define FAST_CELL_SEARCH 1 /* Boolean values... */ -#define NWID_PROMISC 1 /* for code clarity. */ - -typedef struct wavepoint_beacon { - unsigned char dsap, /* Unused */ - ssap, /* Unused */ - ctrl, /* Unused */ - O, U, I, /* Unused */ - spec_id1, /* Unused */ - spec_id2, /* Unused */ - pdu_type, /* Unused */ - seq; /* WavePoint beacon sequence number */ - __be16 domain_id, /* WavePoint Domain ID */ - nwid; /* WavePoint NWID */ -} wavepoint_beacon; - -typedef struct wavepoint_history { - unsigned short nwid; /* WavePoint's NWID */ - int average_slow; /* SNR running average */ - int average_fast; /* SNR running average */ - unsigned char sigqual[WAVEPOINT_HISTORY]; /* Ringbuffer of recent SNR's */ - unsigned char qualptr; /* Index into ringbuffer */ - unsigned char last_seq; /* Last seq. no seen for WavePoint */ - struct wavepoint_history *next; /* Next WavePoint in table */ - struct wavepoint_history *prev; /* Previous WavePoint in table */ - unsigned long last_seen; /* Time of last beacon recvd, jiffies */ -} wavepoint_history; - -struct wavepoint_table { - wavepoint_history *head; /* Start of ringbuffer */ - int num_wavepoints; /* No. of WavePoints visible */ - unsigned char locked; /* Table lock */ -}; - -#endif /* WAVELAN_ROAMING */ - -/****************************** TYPES ******************************/ - -/* Shortcuts */ -typedef struct iw_statistics iw_stats; -typedef struct iw_quality iw_qual; -typedef struct iw_freq iw_freq; -typedef struct net_local net_local; -typedef struct timer_list timer_list; - -/* Basic types */ -typedef u_char mac_addr[WAVELAN_ADDR_SIZE]; /* Hardware address */ - -/* - * Static specific data for the interface. - * - * For each network interface, Linux keep data in two structure. "device" - * keep the generic data (same format for everybody) and "net_local" keep - * the additional specific data. - */ -struct net_local { - dev_node_t node; /* ???? What is this stuff ???? */ - struct net_device *dev; /* Reverse link... */ - spinlock_t spinlock; /* Serialize access to the hardware (SMP) */ - struct pcmcia_device *link; /* pcmcia structure */ - int nresets; /* Number of hw resets */ - u_char configured; /* If it is configured */ - u_char reconfig_82593; /* Need to reconfigure the controller */ - u_char promiscuous; /* Promiscuous mode */ - u_char allmulticast; /* All Multicast mode */ - int mc_count; /* Number of multicast addresses */ - - int stop; /* Current i82593 Stop Hit Register */ - int rfp; /* Last DMA machine receive pointer */ - int overrunning; /* Receiver overrun flag */ - - iw_stats wstats; /* Wireless specific stats */ - - struct iw_spy_data spy_data; - struct iw_public_data wireless_data; - -#ifdef HISTOGRAM - int his_number; /* Number of intervals */ - u_char his_range[16]; /* Boundaries of interval ]n-1; n] */ - u_long his_sum[16]; /* Sum in interval */ -#endif /* HISTOGRAM */ -#ifdef WAVELAN_ROAMING - u_long domain_id; /* Domain ID we lock on for roaming */ - int filter_domains; /* Check Domain ID of beacon found */ - struct wavepoint_table wavepoint_table; /* Table of visible WavePoints*/ - wavepoint_history *curr_point; /* Current wavepoint */ - int cell_search; /* Searching for new cell? */ - struct timer_list cell_timer; /* Garbage collection */ -#endif /* WAVELAN_ROAMING */ - void __iomem *mem; -}; - -/* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */ -static inline u_char /* data */ - hasr_read(u_long); /* Read the host interface : base address */ -static void - hacr_write(u_long, /* Write to host interface : base address */ - u_char), /* data */ - hacr_write_slow(u_long, - u_char); -static void - psa_read(struct net_device *, /* Read the Parameter Storage Area */ - int, /* offset in PSA */ - u_char *, /* buffer to fill */ - int), /* size to read */ - psa_write(struct net_device *, /* Write to the PSA */ - int, /* Offset in psa */ - u_char *, /* Buffer in memory */ - int); /* Length of buffer */ -static void - mmc_out(u_long, /* Write 1 byte to the Modem Manag Control */ - u_short, - u_char), - mmc_write(u_long, /* Write n bytes to the MMC */ - u_char, - u_char *, - int); -static u_char /* Read 1 byte from the MMC */ - mmc_in(u_long, - u_short); -static void - mmc_read(u_long, /* Read n bytes from the MMC */ - u_char, - u_char *, - int), - fee_wait(u_long, /* Wait for frequency EEprom : base address */ - int, /* Base delay to wait for */ - int); /* Number of time to wait */ -static void - fee_read(u_long, /* Read the frequency EEprom : base address */ - u_short, /* destination offset */ - u_short *, /* data buffer */ - int); /* number of registers */ -/* ---------------------- I82593 SUBROUTINES ----------------------- */ -static int - wv_82593_cmd(struct net_device *, /* synchronously send a command to i82593 */ - char *, - int, - int); -static inline int - wv_diag(struct net_device *); /* Diagnostique the i82593 */ -static int - read_ringbuf(struct net_device *, /* Read a receive buffer */ - int, - char *, - int); -static void - wv_82593_reconfig(struct net_device *); /* Reconfigure the controller */ -/* ------------------- DEBUG & INFO SUBROUTINES ------------------- */ -static void - wv_init_info(struct net_device *); /* display startup info */ -/* ------------------- IOCTL, STATS & RECONFIG ------------------- */ -static iw_stats * - wavelan_get_wireless_stats(struct net_device *); -/* ----------------------- PACKET RECEPTION ----------------------- */ -static int - wv_start_of_frame(struct net_device *, /* Seek beggining of current frame */ - int, /* end of frame */ - int); /* start of buffer */ -static void - wv_packet_read(struct net_device *, /* Read a packet from a frame */ - int, - int), - wv_packet_rcv(struct net_device *); /* Read all packets waiting */ -/* --------------------- PACKET TRANSMISSION --------------------- */ -static void - wv_packet_write(struct net_device *, /* Write a packet to the Tx buffer */ - void *, - short); -static netdev_tx_t - wavelan_packet_xmit(struct sk_buff *, /* Send a packet */ - struct net_device *); -/* -------------------- HARDWARE CONFIGURATION -------------------- */ -static int - wv_mmc_init(struct net_device *); /* Initialize the modem */ -static int - wv_ru_stop(struct net_device *), /* Stop the i82593 receiver unit */ - wv_ru_start(struct net_device *); /* Start the i82593 receiver unit */ -static int - wv_82593_config(struct net_device *); /* Configure the i82593 */ -static int - wv_pcmcia_reset(struct net_device *); /* Reset the pcmcia interface */ -static int - wv_hw_config(struct net_device *); /* Reset & configure the whole hardware */ -static void - wv_hw_reset(struct net_device *); /* Same, + start receiver unit */ -static int - wv_pcmcia_config(struct pcmcia_device *); /* Configure the pcmcia interface */ -static void - wv_pcmcia_release(struct pcmcia_device *);/* Remove a device */ -/* ---------------------- INTERRUPT HANDLING ---------------------- */ -static irqreturn_t - wavelan_interrupt(int, /* Interrupt handler */ - void *); -static void - wavelan_watchdog(struct net_device *); /* Transmission watchdog */ -/* ------------------- CONFIGURATION CALLBACKS ------------------- */ -static int - wavelan_open(struct net_device *), /* Open the device */ - wavelan_close(struct net_device *); /* Close the device */ -static void - wavelan_detach(struct pcmcia_device *p_dev); /* Destroy a removed device */ - -/**************************** VARIABLES ****************************/ - -/* - * Parameters that can be set with 'insmod' - * The exact syntax is 'insmod wavelan_cs.o =' - */ - -/* Shared memory speed, in ns */ -static int mem_speed; - -/* New module interface */ -module_param(mem_speed, int, 0); - -#ifdef WAVELAN_ROAMING /* Conditional compile, see above in options */ -/* Enable roaming mode ? No ! Please keep this to 0 */ -static int do_roaming; -module_param(do_roaming, bool, 0); -#endif /* WAVELAN_ROAMING */ - -MODULE_LICENSE("GPL"); - -#endif /* WAVELAN_CS_P_H */ - -- cgit v1.2.3 From e5b3e80016198ee55c82dfd653c1dee99a38964b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 5 May 2010 23:17:29 -0700 Subject: Staging: netwave: delete the driver It has sat in the staging directory since October of 2009, and no one has stepped up to take it over, so odds are, no one cares about it anymore. So, it is now deleted as scheduled, and documented in the TODO file. Cc: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/netwave/Kconfig | 11 - drivers/staging/netwave/Makefile | 1 - drivers/staging/netwave/TODO | 7 - drivers/staging/netwave/netwave_cs.c | 1369 ---------------------------------- 6 files changed, 1391 deletions(-) delete mode 100644 drivers/staging/netwave/Kconfig delete mode 100644 drivers/staging/netwave/Makefile delete mode 100644 drivers/staging/netwave/TODO delete mode 100644 drivers/staging/netwave/netwave_cs.c (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 436e2ed07995..e062b092073e 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -125,8 +125,6 @@ source "drivers/staging/batman-adv/Kconfig" source "drivers/staging/samsung-laptop/Kconfig" -source "drivers/staging/netwave/Kconfig" - source "drivers/staging/sm7xx/Kconfig" source "drivers/staging/dt3155/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 357da6de3f1e..097c158d91f7 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -43,7 +43,6 @@ obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/ obj-$(CONFIG_BATMAN_ADV) += batman-adv/ obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop/ -obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/ obj-$(CONFIG_FB_SM7XX) += sm7xx/ obj-$(CONFIG_DT3155) += dt3155/ obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/ diff --git a/drivers/staging/netwave/Kconfig b/drivers/staging/netwave/Kconfig deleted file mode 100644 index 8033e8171f9e..000000000000 --- a/drivers/staging/netwave/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -config PCMCIA_NETWAVE - tristate "Xircom Netwave AirSurfer Pcmcia wireless support" - depends on PCMCIA && WLAN - select WIRELESS_EXT - select WEXT_PRIV - help - Say Y here if you intend to attach this type of PCMCIA (PC-card) - wireless Ethernet networking card to your computer. - - To compile this driver as a module, choose M here: the module will be - called netwave_cs. If unsure, say N. diff --git a/drivers/staging/netwave/Makefile b/drivers/staging/netwave/Makefile deleted file mode 100644 index 2ab89de59b9b..000000000000 --- a/drivers/staging/netwave/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_PCMCIA_NETWAVE) += netwave_cs.o diff --git a/drivers/staging/netwave/TODO b/drivers/staging/netwave/TODO deleted file mode 100644 index 9bd15a2f6d9e..000000000000 --- a/drivers/staging/netwave/TODO +++ /dev/null @@ -1,7 +0,0 @@ -TODO: - - step up and maintain this driver to ensure that it continues - to work. Having the hardware for this is pretty much a - requirement. If this does not happen, the will be removed in - the 2.6.35 kernel release. - -Please send patches to Greg Kroah-Hartman . diff --git a/drivers/staging/netwave/netwave_cs.c b/drivers/staging/netwave/netwave_cs.c deleted file mode 100644 index 7b3162101ecd..000000000000 --- a/drivers/staging/netwave/netwave_cs.c +++ /dev/null @@ -1,1369 +0,0 @@ -/********************************************************************* - * - * Filename: netwave_cs.c - * Version: 0.4.1 - * Description: Netwave AirSurfer Wireless LAN PC Card driver - * Status: Experimental. - * Authors: John Markus Bjørndalen - * Dag Brattli - * David Hinds - * Created at: A long time ago! - * Modified at: Mon Nov 10 11:54:37 1997 - * Modified by: Dag Brattli - * - * Copyright (c) 1997 University of Tromsø, Norway - * - * Revision History: - * - * 08-Nov-97 15:14:47 John Markus Bjørndalen - * - Fixed some bugs in netwave_rx and cleaned it up a bit. - * (One of the bugs would have destroyed packets when receiving - * multiple packets per interrupt). - * - Cleaned up parts of newave_hw_xmit. - * - A few general cleanups. - * 24-Oct-97 13:17:36 Dag Brattli - * - Fixed netwave_rx receive function (got updated docs) - * Others: - * - Changed name from xircnw to netwave, take a look at - * http://www.netwave-wireless.com - * - Some reorganizing of the code - * - Removed possible race condition between interrupt handler and transmit - * function - * - Started to add wireless extensions, but still needs some coding - * - Added watchdog for better handling of transmission timeouts - * (hopefully this works better) - ********************************************************************/ - -/* To have statistics (just packets sent) define this */ -#undef NETWAVE_STATS - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define NETWAVE_REGOFF 0x8000 -/* The Netwave IO registers, offsets to iobase */ -#define NETWAVE_REG_COR 0x0 -#define NETWAVE_REG_CCSR 0x2 -#define NETWAVE_REG_ASR 0x4 -#define NETWAVE_REG_IMR 0xa -#define NETWAVE_REG_PMR 0xc -#define NETWAVE_REG_IOLOW 0x6 -#define NETWAVE_REG_IOHI 0x7 -#define NETWAVE_REG_IOCONTROL 0x8 -#define NETWAVE_REG_DATA 0xf -/* The Netwave Extended IO registers, offsets to RamBase */ -#define NETWAVE_EREG_ASCC 0x114 -#define NETWAVE_EREG_RSER 0x120 -#define NETWAVE_EREG_RSERW 0x124 -#define NETWAVE_EREG_TSER 0x130 -#define NETWAVE_EREG_TSERW 0x134 -#define NETWAVE_EREG_CB 0x100 -#define NETWAVE_EREG_SPCQ 0x154 -#define NETWAVE_EREG_SPU 0x155 -#define NETWAVE_EREG_LIF 0x14e -#define NETWAVE_EREG_ISPLQ 0x156 -#define NETWAVE_EREG_HHC 0x158 -#define NETWAVE_EREG_NI 0x16e -#define NETWAVE_EREG_MHS 0x16b -#define NETWAVE_EREG_TDP 0x140 -#define NETWAVE_EREG_RDP 0x150 -#define NETWAVE_EREG_PA 0x160 -#define NETWAVE_EREG_EC 0x180 -#define NETWAVE_EREG_CRBP 0x17a -#define NETWAVE_EREG_ARW 0x166 - -/* - * Commands used in the extended command buffer - * NETWAVE_EREG_CB (0x100-0x10F) - */ -#define NETWAVE_CMD_NOP 0x00 -#define NETWAVE_CMD_SRC 0x01 -#define NETWAVE_CMD_STC 0x02 -#define NETWAVE_CMD_AMA 0x03 -#define NETWAVE_CMD_DMA 0x04 -#define NETWAVE_CMD_SAMA 0x05 -#define NETWAVE_CMD_ER 0x06 -#define NETWAVE_CMD_DR 0x07 -#define NETWAVE_CMD_TL 0x08 -#define NETWAVE_CMD_SRP 0x09 -#define NETWAVE_CMD_SSK 0x0a -#define NETWAVE_CMD_SMD 0x0b -#define NETWAVE_CMD_SAPD 0x0c -#define NETWAVE_CMD_SSS 0x11 -/* End of Command marker */ -#define NETWAVE_CMD_EOC 0x00 - -/* ASR register bits */ -#define NETWAVE_ASR_RXRDY 0x80 -#define NETWAVE_ASR_TXBA 0x01 - -#define TX_TIMEOUT ((32*HZ)/100) - -static const unsigned int imrConfRFU1 = 0x10; /* RFU interrupt mask, keep high */ -static const unsigned int imrConfIENA = 0x02; /* Interrupt enable */ - -static const unsigned int corConfIENA = 0x01; /* Interrupt enable */ -static const unsigned int corConfLVLREQ = 0x40; /* Keep high */ - -static const unsigned int rxConfRxEna = 0x80; /* Receive Enable */ -static const unsigned int rxConfMAC = 0x20; /* MAC host receive mode*/ -static const unsigned int rxConfPro = 0x10; /* Promiscuous */ -static const unsigned int rxConfAMP = 0x08; /* Accept Multicast Packets */ -static const unsigned int rxConfBcast = 0x04; /* Accept Broadcast Packets */ - -static const unsigned int txConfTxEna = 0x80; /* Transmit Enable */ -static const unsigned int txConfMAC = 0x20; /* Host sends MAC mode */ -static const unsigned int txConfEUD = 0x10; /* Enable Uni-Data packets */ -static const unsigned int txConfKey = 0x02; /* Scramble data packets */ -static const unsigned int txConfLoop = 0x01; /* Loopback mode */ - - -/*====================================================================*/ - -/* Parameters that can be set with 'insmod' */ - -/* Choose the domain, default is 0x100 */ -static u_int domain = 0x100; - -/* Scramble key, range from 0x0 to 0xffff. - * 0x0 is no scrambling. - */ -static u_int scramble_key = 0x0; - -/* Shared memory speed, in ns. The documentation states that - * the card should not be read faster than every 400ns. - * This timing should be provided by the HBA. If it becomes a - * problem, try setting mem_speed to 400. - */ -static int mem_speed; - -module_param(domain, int, 0); -module_param(scramble_key, int, 0); -module_param(mem_speed, int, 0); - -/*====================================================================*/ - -/* PCMCIA (Card Services) related functions */ -static void netwave_release(struct pcmcia_device *link); /* Card removal */ -static int netwave_pcmcia_config(struct pcmcia_device *arg); /* Runs after card - insertion */ -static void netwave_detach(struct pcmcia_device *p_dev); /* Destroy instance */ - -/* Hardware configuration */ -static void netwave_doreset(unsigned int iobase, u_char __iomem *ramBase); -static void netwave_reset(struct net_device *dev); - -/* Misc device stuff */ -static int netwave_open(struct net_device *dev); /* Open the device */ -static int netwave_close(struct net_device *dev); /* Close the device */ - -/* Packet transmission and Packet reception */ -static netdev_tx_t netwave_start_xmit( struct sk_buff *skb, - struct net_device *dev); -static int netwave_rx( struct net_device *dev); - -/* Interrupt routines */ -static irqreturn_t netwave_interrupt(int irq, void *dev_id); -static void netwave_watchdog(struct net_device *); - -/* Wireless extensions */ -static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev); - -static void set_multicast_list(struct net_device *dev); - -/* - A struct pcmcia_device structure has fields for most things that are needed - to keep track of a socket, but there will usually be some device - specific information that also needs to be kept track of. The - 'priv' pointer in a struct pcmcia_device structure can be used to point to - a device-specific private data structure, like this. - - A driver needs to provide a dev_node_t structure for each device - on a card. In some cases, there is only one device per card (for - example, ethernet cards, modems). In other cases, there may be - many actual or logical devices (SCSI adapters, memory cards with - multiple partitions). The dev_node_t structures need to be kept - in a linked list starting at the 'dev' field of a struct pcmcia_device - structure. We allocate them in the card's private data structure, - because they generally can't be allocated dynamically. -*/ - -static const struct iw_handler_def netwave_handler_def; - -#define SIOCGIPSNAP SIOCIWFIRSTPRIV + 1 /* Site Survey Snapshot */ - -#define MAX_ESA 10 - -typedef struct net_addr { - u_char addr48[6]; -} net_addr; - -struct site_survey { - u_short length; - u_char struct_revision; - u_char roaming_state; - - u_char sp_existsFlag; - u_char sp_link_quality; - u_char sp_max_link_quality; - u_char linkQualityGoodFairBoundary; - u_char linkQualityFairPoorBoundary; - u_char sp_utilization; - u_char sp_goodness; - u_char sp_hotheadcount; - u_char roaming_condition; - - net_addr sp; - u_char numAPs; - net_addr nearByAccessPoints[MAX_ESA]; -}; - -typedef struct netwave_private { - struct pcmcia_device *p_dev; - spinlock_t spinlock; /* Serialize access to the hardware (SMP) */ - dev_node_t node; - u_char __iomem *ramBase; - int timeoutCounter; - int lastExec; - struct timer_list watchdog; /* To avoid blocking state */ - struct site_survey nss; - struct iw_statistics iw_stats; /* Wireless stats */ -} netwave_private; - -/* - * The Netwave card is little-endian, so won't work for big endian - * systems. - */ -static inline unsigned short get_uint16(u_char __iomem *staddr) -{ - return readw(staddr); /* Return only 16 bits */ -} - -static inline short get_int16(u_char __iomem * staddr) -{ - return readw(staddr); -} - -/* - * Wait until the WOC (Write Operation Complete) bit in the - * ASR (Adapter Status Register) is asserted. - * This should have aborted if it takes too long time. - */ -static inline void wait_WOC(unsigned int iobase) -{ - /* Spin lock */ - while ((inb(iobase + NETWAVE_REG_ASR) & 0x8) != 0x8) ; -} - -static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase, - unsigned int iobase) { - u_short resultBuffer; - - /* if time since last snapshot is > 1 sec. (100 jiffies?) then take - * new snapshot, else return cached data. This is the recommended rate. - */ - if ( jiffies - priv->lastExec > 100) { - /* Take site survey snapshot */ - /*printk( KERN_DEBUG "Taking new snapshot. %ld\n", jiffies - - priv->lastExec); */ - wait_WOC(iobase); - writeb(NETWAVE_CMD_SSS, ramBase + NETWAVE_EREG_CB + 0); - writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1); - wait_WOC(iobase); - - /* Get result and copy to cach */ - resultBuffer = readw(ramBase + NETWAVE_EREG_CRBP); - copy_from_pc( &priv->nss, ramBase+resultBuffer, - sizeof(struct site_survey)); - } -} - -/* - * Function netwave_get_wireless_stats (dev) - * - * Wireless extensions statistics - * - */ -static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev) -{ - unsigned long flags; - unsigned int iobase = dev->base_addr; - netwave_private *priv = netdev_priv(dev); - u_char __iomem *ramBase = priv->ramBase; - struct iw_statistics* wstats; - - wstats = &priv->iw_stats; - - spin_lock_irqsave(&priv->spinlock, flags); - - netwave_snapshot( priv, ramBase, iobase); - - wstats->status = priv->nss.roaming_state; - wstats->qual.qual = readb( ramBase + NETWAVE_EREG_SPCQ); - wstats->qual.level = readb( ramBase + NETWAVE_EREG_ISPLQ); - wstats->qual.noise = readb( ramBase + NETWAVE_EREG_SPU) & 0x3f; - wstats->discard.nwid = 0L; - wstats->discard.code = 0L; - wstats->discard.misc = 0L; - - spin_unlock_irqrestore(&priv->spinlock, flags); - - return &priv->iw_stats; -} - -static const struct net_device_ops netwave_netdev_ops = { - .ndo_open = netwave_open, - .ndo_stop = netwave_close, - .ndo_start_xmit = netwave_start_xmit, - .ndo_set_multicast_list = set_multicast_list, - .ndo_tx_timeout = netwave_watchdog, - .ndo_change_mtu = eth_change_mtu, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, -}; - -/* - * Function netwave_attach (void) - * - * Creates an "instance" of the driver, allocating local data - * structures for one device. The device is registered with Card - * Services. - * - * The dev_link structure is initialized, but we don't actually - * configure the card at this point -- we wait until we receive a - * card insertion event. - */ -static int netwave_probe(struct pcmcia_device *link) -{ - struct net_device *dev; - netwave_private *priv; - - dev_dbg(&link->dev, "netwave_attach()\n"); - - /* Initialize the struct pcmcia_device structure */ - dev = alloc_etherdev(sizeof(netwave_private)); - if (!dev) - return -ENOMEM; - priv = netdev_priv(dev); - priv->p_dev = link; - link->priv = dev; - - /* The io structure describes IO port mapping */ - link->io.NumPorts1 = 16; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - /* link->io.NumPorts2 = 16; - link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; */ - link->io.IOAddrLines = 5; - - /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.Handler = &netwave_interrupt; - - /* General socket configuration */ - link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.IntType = INT_MEMORY_AND_IO; - link->conf.ConfigIndex = 1; - - /* Netwave private struct init. link/dev/node already taken care of, - * other stuff zero'd - Jean II */ - spin_lock_init(&priv->spinlock); - - /* Netwave specific entries in the device structure */ - dev->netdev_ops = &netwave_netdev_ops; - /* wireless extensions */ - dev->wireless_handlers = &netwave_handler_def; - - dev->watchdog_timeo = TX_TIMEOUT; - - return netwave_pcmcia_config( link); -} /* netwave_attach */ - -/* - * Function netwave_detach (link) - * - * This deletes a driver "instance". The device is de-registered - * with Card Services. If it has been released, all local data - * structures are freed. Otherwise, the structures will be freed - * when the device is released. - */ -static void netwave_detach(struct pcmcia_device *link) -{ - struct net_device *dev = link->priv; - - dev_dbg(&link->dev, "netwave_detach\n"); - - netwave_release(link); - - if (link->dev_node) - unregister_netdev(dev); - - free_netdev(dev); -} /* netwave_detach */ - -/* - * Wireless Handler : get protocol name - */ -static int netwave_get_name(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - strcpy(wrqu->name, "Netwave"); - return 0; -} - -/* - * Wireless Handler : set Network ID - */ -static int netwave_set_nwid(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned long flags; - unsigned int iobase = dev->base_addr; - netwave_private *priv = netdev_priv(dev); - u_char __iomem *ramBase = priv->ramBase; - - /* Disable interrupts & save flags */ - spin_lock_irqsave(&priv->spinlock, flags); - - if(!wrqu->nwid.disabled) { - domain = wrqu->nwid.value; - printk( KERN_DEBUG "Setting domain to 0x%x%02x\n", - (domain >> 8) & 0x01, domain & 0xff); - wait_WOC(iobase); - writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0); - writeb( domain & 0xff, ramBase + NETWAVE_EREG_CB + 1); - writeb((domain >>8 ) & 0x01,ramBase + NETWAVE_EREG_CB+2); - writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3); - } - - /* ReEnable interrupts & restore flags */ - spin_unlock_irqrestore(&priv->spinlock, flags); - - return 0; -} - -/* - * Wireless Handler : get Network ID - */ -static int netwave_get_nwid(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - wrqu->nwid.value = domain; - wrqu->nwid.disabled = 0; - wrqu->nwid.fixed = 1; - return 0; -} - -/* - * Wireless Handler : set scramble key - */ -static int netwave_set_scramble(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *key) -{ - unsigned long flags; - unsigned int iobase = dev->base_addr; - netwave_private *priv = netdev_priv(dev); - u_char __iomem *ramBase = priv->ramBase; - - /* Disable interrupts & save flags */ - spin_lock_irqsave(&priv->spinlock, flags); - - scramble_key = (key[0] << 8) | key[1]; - wait_WOC(iobase); - writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0); - writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1); - writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2); - writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3); - - /* ReEnable interrupts & restore flags */ - spin_unlock_irqrestore(&priv->spinlock, flags); - - return 0; -} - -/* - * Wireless Handler : get scramble key - */ -static int netwave_get_scramble(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *key) -{ - key[1] = scramble_key & 0xff; - key[0] = (scramble_key>>8) & 0xff; - wrqu->encoding.flags = IW_ENCODE_ENABLED; - wrqu->encoding.length = 2; - return 0; -} - -/* - * Wireless Handler : get mode - */ -static int netwave_get_mode(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - if(domain & 0x100) - wrqu->mode = IW_MODE_INFRA; - else - wrqu->mode = IW_MODE_ADHOC; - - return 0; -} - -/* - * Wireless Handler : get range info - */ -static int netwave_get_range(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - struct iw_range *range = (struct iw_range *) extra; - int ret = 0; - - /* Set the length (very important for backward compatibility) */ - wrqu->data.length = sizeof(struct iw_range); - - /* Set all the info we don't care or don't know about to zero */ - memset(range, 0, sizeof(struct iw_range)); - - /* Set the Wireless Extension versions */ - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 9; /* Nothing for us in v10 and v11 */ - - /* Set information in the range struct */ - range->throughput = 450 * 1000; /* don't argue on this ! */ - range->min_nwid = 0x0000; - range->max_nwid = 0x01FF; - - range->num_channels = range->num_frequency = 0; - - range->sensitivity = 0x3F; - range->max_qual.qual = 255; - range->max_qual.level = 255; - range->max_qual.noise = 0; - - range->num_bitrates = 1; - range->bitrate[0] = 1000000; /* 1 Mb/s */ - - range->encoding_size[0] = 2; /* 16 bits scrambling */ - range->num_encoding_sizes = 1; - range->max_encoding_tokens = 1; /* Only one key possible */ - - return ret; -} - -/* - * Wireless Private Handler : get snapshot - */ -static int netwave_get_snap(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - unsigned long flags; - unsigned int iobase = dev->base_addr; - netwave_private *priv = netdev_priv(dev); - u_char __iomem *ramBase = priv->ramBase; - - /* Disable interrupts & save flags */ - spin_lock_irqsave(&priv->spinlock, flags); - - /* Take snapshot of environment */ - netwave_snapshot( priv, ramBase, iobase); - wrqu->data.length = priv->nss.length; - memcpy(extra, (u_char *) &priv->nss, sizeof( struct site_survey)); - - priv->lastExec = jiffies; - - /* ReEnable interrupts & restore flags */ - spin_unlock_irqrestore(&priv->spinlock, flags); - - return(0); -} - -/* - * Structures to export the Wireless Handlers - * This is the stuff that are treated the wireless extensions (iwconfig) - */ - -static const struct iw_priv_args netwave_private_args[] = { -/*{ cmd, set_args, get_args, name } */ - { SIOCGIPSNAP, 0, - IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof(struct site_survey), - "getsitesurvey" }, -}; - -static const iw_handler netwave_handler[] = -{ - NULL, /* SIOCSIWNAME */ - netwave_get_name, /* SIOCGIWNAME */ - netwave_set_nwid, /* SIOCSIWNWID */ - netwave_get_nwid, /* SIOCGIWNWID */ - NULL, /* SIOCSIWFREQ */ - NULL, /* SIOCGIWFREQ */ - NULL, /* SIOCSIWMODE */ - netwave_get_mode, /* SIOCGIWMODE */ - NULL, /* SIOCSIWSENS */ - NULL, /* SIOCGIWSENS */ - NULL, /* SIOCSIWRANGE */ - netwave_get_range, /* SIOCGIWRANGE */ - NULL, /* SIOCSIWPRIV */ - NULL, /* SIOCGIWPRIV */ - NULL, /* SIOCSIWSTATS */ - NULL, /* SIOCGIWSTATS */ - NULL, /* SIOCSIWSPY */ - NULL, /* SIOCGIWSPY */ - NULL, /* -- hole -- */ - NULL, /* -- hole -- */ - NULL, /* SIOCSIWAP */ - NULL, /* SIOCGIWAP */ - NULL, /* -- hole -- */ - NULL, /* SIOCGIWAPLIST */ - NULL, /* -- hole -- */ - NULL, /* -- hole -- */ - NULL, /* SIOCSIWESSID */ - NULL, /* SIOCGIWESSID */ - NULL, /* SIOCSIWNICKN */ - NULL, /* SIOCGIWNICKN */ - NULL, /* -- hole -- */ - NULL, /* -- hole -- */ - NULL, /* SIOCSIWRATE */ - NULL, /* SIOCGIWRATE */ - NULL, /* SIOCSIWRTS */ - NULL, /* SIOCGIWRTS */ - NULL, /* SIOCSIWFRAG */ - NULL, /* SIOCGIWFRAG */ - NULL, /* SIOCSIWTXPOW */ - NULL, /* SIOCGIWTXPOW */ - NULL, /* SIOCSIWRETRY */ - NULL, /* SIOCGIWRETRY */ - netwave_set_scramble, /* SIOCSIWENCODE */ - netwave_get_scramble, /* SIOCGIWENCODE */ -}; - -static const iw_handler netwave_private_handler[] = -{ - NULL, /* SIOCIWFIRSTPRIV */ - netwave_get_snap, /* SIOCIWFIRSTPRIV + 1 */ -}; - -static const struct iw_handler_def netwave_handler_def = -{ - .num_standard = ARRAY_SIZE(netwave_handler), - .num_private = ARRAY_SIZE(netwave_private_handler), - .num_private_args = ARRAY_SIZE(netwave_private_args), - .standard = (iw_handler *) netwave_handler, - .private = (iw_handler *) netwave_private_handler, - .private_args = (struct iw_priv_args *) netwave_private_args, - .get_wireless_stats = netwave_get_wireless_stats, -}; - -/* - * Function netwave_pcmcia_config (link) - * - * netwave_pcmcia_config() is scheduled to run after a CARD_INSERTION - * event is received, to configure the PCMCIA socket, and to make the - * device available to the system. - * - */ - -static int netwave_pcmcia_config(struct pcmcia_device *link) { - struct net_device *dev = link->priv; - netwave_private *priv = netdev_priv(dev); - int i, j, ret; - win_req_t req; - memreq_t mem; - u_char __iomem *ramBase = NULL; - - dev_dbg(&link->dev, "netwave_pcmcia_config\n"); - - /* - * Try allocating IO ports. This tries a few fixed addresses. - * If you want, you can also read the card's config table to - * pick addresses -- see the serial driver for an example. - */ - for (i = j = 0x0; j < 0x400; j += 0x20) { - link->io.BasePort1 = j ^ 0x300; - i = pcmcia_request_io(link, &link->io); - if (i == 0) - break; - } - if (i != 0) - goto failed; - - /* - * Now allocate an interrupt line. Note that this does not - * actually assign a handler to the interrupt. - */ - ret = pcmcia_request_irq(link, &link->irq); - if (ret) - goto failed; - - /* - * This actually configures the PCMCIA socket -- setting up - * the I/O windows and the interrupt mapping. - */ - ret = pcmcia_request_configuration(link, &link->conf); - if (ret) - goto failed; - - /* - * Allocate a 32K memory window. Note that the struct pcmcia_device - * structure provides space for one window handle -- if your - * device needs several windows, you'll need to keep track of - * the handles in your private data structure, dev->priv. - */ - dev_dbg(&link->dev, "Setting mem speed of %d\n", mem_speed); - - req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_CM|WIN_ENABLE; - req.Base = 0; req.Size = 0x8000; - req.AccessSpeed = mem_speed; - ret = pcmcia_request_window(link, &req, &link->win); - if (ret) - goto failed; - mem.CardOffset = 0x20000; mem.Page = 0; - ret = pcmcia_map_mem_page(link, link->win, &mem); - if (ret) - goto failed; - - /* Store base address of the common window frame */ - ramBase = ioremap(req.Base, 0x8000); - priv->ramBase = ramBase; - - dev->irq = link->irq.AssignedIRQ; - dev->base_addr = link->io.BasePort1; - SET_NETDEV_DEV(dev, &link->dev); - - if (register_netdev(dev) != 0) { - printk(KERN_DEBUG "netwave_cs: register_netdev() failed\n"); - goto failed; - } - - strcpy(priv->node.dev_name, dev->name); - link->dev_node = &priv->node; - - /* Reset card before reading physical address */ - netwave_doreset(dev->base_addr, ramBase); - - /* Read the ethernet address and fill in the Netwave registers. */ - for (i = 0; i < 6; i++) - dev->dev_addr[i] = readb(ramBase + NETWAVE_EREG_PA + i); - - printk(KERN_INFO "%s: Netwave: port %#3lx, irq %d, mem %lx, " - "id %c%c, hw_addr %pM\n", - dev->name, dev->base_addr, dev->irq, - (u_long) ramBase, - (int) readb(ramBase+NETWAVE_EREG_NI), - (int) readb(ramBase+NETWAVE_EREG_NI+1), - dev->dev_addr); - - /* get revision words */ - printk(KERN_DEBUG "Netwave_reset: revision %04x %04x\n", - get_uint16(ramBase + NETWAVE_EREG_ARW), - get_uint16(ramBase + NETWAVE_EREG_ARW+2)); - return 0; - -failed: - netwave_release(link); - return -ENODEV; -} /* netwave_pcmcia_config */ - -/* - * Function netwave_release (arg) - * - * After a card is removed, netwave_release() will unregister the net - * device, and release the PCMCIA configuration. If the device is - * still open, this will be postponed until it is closed. - */ -static void netwave_release(struct pcmcia_device *link) -{ - struct net_device *dev = link->priv; - netwave_private *priv = netdev_priv(dev); - - dev_dbg(&link->dev, "netwave_release\n"); - - pcmcia_disable_device(link); - if (link->win) - iounmap(priv->ramBase); -} - -static int netwave_suspend(struct pcmcia_device *link) -{ - struct net_device *dev = link->priv; - - if (link->open) - netif_device_detach(dev); - - return 0; -} - -static int netwave_resume(struct pcmcia_device *link) -{ - struct net_device *dev = link->priv; - - if (link->open) { - netwave_reset(dev); - netif_device_attach(dev); - } - - return 0; -} - - -/* - * Function netwave_doreset (ioBase, ramBase) - * - * Proper hardware reset of the card. - */ -static void netwave_doreset(unsigned int ioBase, u_char __iomem *ramBase) -{ - /* Reset card */ - wait_WOC(ioBase); - outb(0x80, ioBase + NETWAVE_REG_PMR); - writeb(0x08, ramBase + NETWAVE_EREG_ASCC); /* Bit 3 is WOC */ - outb(0x0, ioBase + NETWAVE_REG_PMR); /* release reset */ -} - -/* - * Function netwave_reset (dev) - * - * Reset and restore all of the netwave registers - */ -static void netwave_reset(struct net_device *dev) { - /* u_char state; */ - netwave_private *priv = netdev_priv(dev); - u_char __iomem *ramBase = priv->ramBase; - unsigned int iobase = dev->base_addr; - - pr_debug("netwave_reset: Done with hardware reset\n"); - - priv->timeoutCounter = 0; - - /* Reset card */ - netwave_doreset(iobase, ramBase); - printk(KERN_DEBUG "netwave_reset: Done with hardware reset\n"); - - /* Write a NOP to check the card */ - wait_WOC(iobase); - writeb(NETWAVE_CMD_NOP, ramBase + NETWAVE_EREG_CB + 0); - writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1); - - /* Set receive conf */ - wait_WOC(iobase); - writeb(NETWAVE_CMD_SRC, ramBase + NETWAVE_EREG_CB + 0); - writeb(rxConfRxEna + rxConfBcast, ramBase + NETWAVE_EREG_CB + 1); - writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2); - - /* Set transmit conf */ - wait_WOC(iobase); - writeb(NETWAVE_CMD_STC, ramBase + NETWAVE_EREG_CB + 0); - writeb(txConfTxEna, ramBase + NETWAVE_EREG_CB + 1); - writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2); - - /* Now set the MU Domain */ - printk(KERN_DEBUG "Setting domain to 0x%x%02x\n", (domain >> 8) & 0x01, domain & 0xff); - wait_WOC(iobase); - writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0); - writeb(domain & 0xff, ramBase + NETWAVE_EREG_CB + 1); - writeb((domain>>8) & 0x01, ramBase + NETWAVE_EREG_CB + 2); - writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3); - - /* Set scramble key */ - printk(KERN_DEBUG "Setting scramble key to 0x%x\n", scramble_key); - wait_WOC(iobase); - writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0); - writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1); - writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2); - writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3); - - /* Enable interrupts, bit 4 high to keep unused - * source from interrupting us, bit 2 high to - * set interrupt enable, 567 to enable TxDN, - * RxErr and RxRdy - */ - wait_WOC(iobase); - outb(imrConfIENA+imrConfRFU1, iobase + NETWAVE_REG_IMR); - - /* Hent 4 bytes fra 0x170. Skal vaere 0a,29,88,36 - * waitWOC - * skriv 80 til d000:3688 - * sjekk om det ble 80 - */ - - /* Enable Receiver */ - wait_WOC(iobase); - writeb(NETWAVE_CMD_ER, ramBase + NETWAVE_EREG_CB + 0); - writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1); - - /* Set the IENA bit in COR */ - wait_WOC(iobase); - outb(corConfIENA + corConfLVLREQ, iobase + NETWAVE_REG_COR); -} - -/* - * Function netwave_hw_xmit (data, len, dev) - */ -static int netwave_hw_xmit(unsigned char* data, int len, - struct net_device* dev) { - unsigned long flags; - unsigned int TxFreeList, - curBuff, - MaxData, - DataOffset; - int tmpcount; - - netwave_private *priv = netdev_priv(dev); - u_char __iomem * ramBase = priv->ramBase; - unsigned int iobase = dev->base_addr; - - /* Disable interrupts & save flags */ - spin_lock_irqsave(&priv->spinlock, flags); - - /* Check if there are transmit buffers available */ - wait_WOC(iobase); - if ((inb(iobase+NETWAVE_REG_ASR) & NETWAVE_ASR_TXBA) == 0) { - /* No buffers available */ - printk(KERN_DEBUG "netwave_hw_xmit: %s - no xmit buffers available.\n", - dev->name); - spin_unlock_irqrestore(&priv->spinlock, flags); - return 1; - } - - dev->stats.tx_bytes += len; - - pr_debug("Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n", - readb(ramBase + NETWAVE_EREG_SPCQ), - readb(ramBase + NETWAVE_EREG_SPU), - readb(ramBase + NETWAVE_EREG_LIF), - readb(ramBase + NETWAVE_EREG_ISPLQ)); - - /* Now try to insert it into the adapters free memory */ - wait_WOC(iobase); - TxFreeList = get_uint16(ramBase + NETWAVE_EREG_TDP); - MaxData = get_uint16(ramBase + NETWAVE_EREG_TDP+2); - DataOffset = get_uint16(ramBase + NETWAVE_EREG_TDP+4); - - pr_debug("TxFreeList %x, MaxData %x, DataOffset %x\n", - TxFreeList, MaxData, DataOffset); - - /* Copy packet to the adapter fragment buffers */ - curBuff = TxFreeList; - tmpcount = 0; - while (tmpcount < len) { - int tmplen = len - tmpcount; - copy_to_pc(ramBase + curBuff + DataOffset, data + tmpcount, - (tmplen < MaxData) ? tmplen : MaxData); - tmpcount += MaxData; - - /* Advance to next buffer */ - curBuff = get_uint16(ramBase + curBuff); - } - - /* Now issue transmit list */ - wait_WOC(iobase); - writeb(NETWAVE_CMD_TL, ramBase + NETWAVE_EREG_CB + 0); - writeb(len & 0xff, ramBase + NETWAVE_EREG_CB + 1); - writeb((len>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2); - writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3); - - spin_unlock_irqrestore(&priv->spinlock, flags); - return 0; -} - -static netdev_tx_t netwave_start_xmit(struct sk_buff *skb, - struct net_device *dev) { - /* This flag indicate that the hardware can't perform a transmission. - * Theoritically, NET3 check it before sending a packet to the driver, - * but in fact it never do that and pool continuously. - * As the watchdog will abort too long transmissions, we are quite safe... - */ - - netif_stop_queue(dev); - - { - short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; - unsigned char* buf = skb->data; - - if (netwave_hw_xmit( buf, length, dev) == 1) { - /* Some error, let's make them call us another time? */ - netif_start_queue(dev); - } - dev->trans_start = jiffies; - } - dev_kfree_skb(skb); - - return NETDEV_TX_OK; -} /* netwave_start_xmit */ - -/* - * Function netwave_interrupt (irq, dev_id) - * - * This function is the interrupt handler for the Netwave card. This - * routine will be called whenever: - * 1. A packet is received. - * 2. A packet has successfully been transferred and the unit is - * ready to transmit another packet. - * 3. A command has completed execution. - */ -static irqreturn_t netwave_interrupt(int irq, void* dev_id) -{ - unsigned int iobase; - u_char __iomem *ramBase; - struct net_device *dev = (struct net_device *)dev_id; - struct netwave_private *priv = netdev_priv(dev); - struct pcmcia_device *link = priv->p_dev; - int i; - - if (!netif_device_present(dev)) - return IRQ_NONE; - - iobase = dev->base_addr; - ramBase = priv->ramBase; - - /* Now find what caused the interrupt, check while interrupts ready */ - for (i = 0; i < 10; i++) { - u_char status; - - wait_WOC(iobase); - if (!(inb(iobase+NETWAVE_REG_CCSR) & 0x02)) - break; /* None of the interrupt sources asserted (normal exit) */ - - status = inb(iobase + NETWAVE_REG_ASR); - - if (!pcmcia_dev_present(link)) { - pr_debug("netwave_interrupt: Interrupt with status 0x%x " - "from removed or suspended card!\n", status); - break; - } - - /* RxRdy */ - if (status & 0x80) { - netwave_rx(dev); - /* wait_WOC(iobase); */ - /* RxRdy cannot be reset directly by the host */ - } - /* RxErr */ - if (status & 0x40) { - u_char rser; - - rser = readb(ramBase + NETWAVE_EREG_RSER); - - if (rser & 0x04) { - ++dev->stats.rx_dropped; - ++dev->stats.rx_crc_errors; - } - if (rser & 0x02) - ++dev->stats.rx_frame_errors; - - /* Clear the RxErr bit in RSER. RSER+4 is the - * write part. Also clear the RxCRC (0x04) and - * RxBig (0x02) bits if present */ - wait_WOC(iobase); - writeb(0x40 | (rser & 0x06), ramBase + NETWAVE_EREG_RSER + 4); - - /* Write bit 6 high to ASCC to clear RxErr in ASR, - * WOC must be set first! - */ - wait_WOC(iobase); - writeb(0x40, ramBase + NETWAVE_EREG_ASCC); - - /* Remember to count up dev->stats on error packets */ - ++dev->stats.rx_errors; - } - /* TxDN */ - if (status & 0x20) { - int txStatus; - - txStatus = readb(ramBase + NETWAVE_EREG_TSER); - pr_debug("Transmit done. TSER = %x id %x\n", - txStatus, readb(ramBase + NETWAVE_EREG_TSER + 1)); - - if (txStatus & 0x20) { - /* Transmitting was okay, clear bits */ - wait_WOC(iobase); - writeb(0x2f, ramBase + NETWAVE_EREG_TSER + 4); - ++dev->stats.tx_packets; - } - - if (txStatus & 0xd0) { - if (txStatus & 0x80) { - ++dev->stats.collisions; /* Because of /proc/net/dev*/ - /* ++dev->stats.tx_aborted_errors; */ - /* printk("Collision. %ld\n", jiffies - dev->trans_start); */ - } - if (txStatus & 0x40) - ++dev->stats.tx_carrier_errors; - /* 0x80 TxGU Transmit giveup - nine times and no luck - * 0x40 TxNOAP No access point. Discarded packet. - * 0x10 TxErr Transmit error. Always set when - * TxGU and TxNOAP is set. (Those are the only ones - * to set TxErr). - */ - pr_debug("netwave_interrupt: TxDN with error status %x\n", - txStatus); - - /* Clear out TxGU, TxNOAP, TxErr and TxTrys */ - wait_WOC(iobase); - writeb(0xdf & txStatus, ramBase+NETWAVE_EREG_TSER+4); - ++dev->stats.tx_errors; - } - pr_debug("New status is TSER %x ASR %x\n", - readb(ramBase + NETWAVE_EREG_TSER), - inb(iobase + NETWAVE_REG_ASR)); - - netif_wake_queue(dev); - } - /* TxBA, this would trigger on all error packets received */ - /* if (status & 0x01) { - pr_debug("Transmit buffers available, %x\n", status); - } - */ - } - /* Handled if we looped at least one time - Jean II */ - return IRQ_RETVAL(i); -} /* netwave_interrupt */ - -/* - * Function netwave_watchdog (a) - * - * Watchdog : when we start a transmission, we set a timer in the - * kernel. If the transmission complete, this timer is disabled. If - * it expire, we reset the card. - * - */ -static void netwave_watchdog(struct net_device *dev) { - - pr_debug("%s: netwave_watchdog: watchdog timer expired\n", dev->name); - netwave_reset(dev); - dev->trans_start = jiffies; - netif_wake_queue(dev); -} /* netwave_watchdog */ - -static int netwave_rx(struct net_device *dev) -{ - netwave_private *priv = netdev_priv(dev); - u_char __iomem *ramBase = priv->ramBase; - unsigned int iobase = dev->base_addr; - u_char rxStatus; - struct sk_buff *skb = NULL; - unsigned int curBuffer, - rcvList; - int rcvLen; - int tmpcount = 0; - int dataCount, dataOffset; - int i; - u_char *ptr; - - pr_debug("xinw_rx: Receiving ... \n"); - - /* Receive max 10 packets for now. */ - for (i = 0; i < 10; i++) { - /* Any packets? */ - wait_WOC(iobase); - rxStatus = readb(ramBase + NETWAVE_EREG_RSER); - if ( !( rxStatus & 0x80)) /* No more packets */ - break; - - /* Check if multicast/broadcast or other */ - /* multicast = (rxStatus & 0x20); */ - - /* The receive list pointer and length of the packet */ - wait_WOC(iobase); - rcvLen = get_int16( ramBase + NETWAVE_EREG_RDP); - rcvList = get_uint16( ramBase + NETWAVE_EREG_RDP + 2); - - if (rcvLen < 0) { - printk(KERN_DEBUG "netwave_rx: Receive packet with len %d\n", - rcvLen); - return 0; - } - - skb = dev_alloc_skb(rcvLen+5); - if (skb == NULL) { - pr_debug("netwave_rx: Could not allocate an sk_buff of " - "length %d\n", rcvLen); - ++dev->stats.rx_dropped; - /* Tell the adapter to skip the packet */ - wait_WOC(iobase); - writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0); - writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1); - return 0; - } - - skb_reserve( skb, 2); /* Align IP on 16 byte */ - skb_put( skb, rcvLen); - - /* Copy packet fragments to the skb data area */ - ptr = (u_char*) skb->data; - curBuffer = rcvList; - tmpcount = 0; - while ( tmpcount < rcvLen) { - /* Get length and offset of current buffer */ - dataCount = get_uint16( ramBase+curBuffer+2); - dataOffset = get_uint16( ramBase+curBuffer+4); - - copy_from_pc( ptr + tmpcount, - ramBase+curBuffer+dataOffset, dataCount); - - tmpcount += dataCount; - - /* Point to next buffer */ - curBuffer = get_uint16(ramBase + curBuffer); - } - - skb->protocol = eth_type_trans(skb,dev); - /* Queue packet for network layer */ - netif_rx(skb); - - dev->stats.rx_packets++; - dev->stats.rx_bytes += rcvLen; - - /* Got the packet, tell the adapter to skip it */ - wait_WOC(iobase); - writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0); - writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1); - pr_debug("Packet reception ok\n"); - } - return 0; -} - -static int netwave_open(struct net_device *dev) { - netwave_private *priv = netdev_priv(dev); - struct pcmcia_device *link = priv->p_dev; - - dev_dbg(&link->dev, "netwave_open: starting.\n"); - - if (!pcmcia_dev_present(link)) - return -ENODEV; - - link->open++; - - netif_start_queue(dev); - netwave_reset(dev); - - return 0; -} - -static int netwave_close(struct net_device *dev) { - netwave_private *priv = netdev_priv(dev); - struct pcmcia_device *link = priv->p_dev; - - dev_dbg(&link->dev, "netwave_close: finishing.\n"); - - link->open--; - netif_stop_queue(dev); - - return 0; -} - -static struct pcmcia_device_id netwave_ids[] = { - PCMCIA_DEVICE_PROD_ID12("Xircom", "CreditCard Netwave", 0x2e3ee845, 0x54e28a28), - PCMCIA_DEVICE_NULL, -}; -MODULE_DEVICE_TABLE(pcmcia, netwave_ids); - -static struct pcmcia_driver netwave_driver = { - .owner = THIS_MODULE, - .drv = { - .name = "netwave_cs", - }, - .probe = netwave_probe, - .remove = netwave_detach, - .id_table = netwave_ids, - .suspend = netwave_suspend, - .resume = netwave_resume, -}; - -static int __init init_netwave_cs(void) -{ - return pcmcia_register_driver(&netwave_driver); -} - -static void __exit exit_netwave_cs(void) -{ - pcmcia_unregister_driver(&netwave_driver); -} - -module_init(init_netwave_cs); -module_exit(exit_netwave_cs); - -/* Set or clear the multicast filter for this adaptor. - num_addrs == -1 Promiscuous mode, receive all packets - num_addrs == 0 Normal mode, clear multicast list - num_addrs > 0 Multicast mode, receive normal and MC packets, and do - best-effort filtering. - */ -static void set_multicast_list(struct net_device *dev) -{ - unsigned int iobase = dev->base_addr; - netwave_private *priv = netdev_priv(dev); - u_char __iomem * ramBase = priv->ramBase; - u_char rcvMode = 0; - -#ifdef PCMCIA_DEBUG - { - xstatic int old; - if (old != netdev_mc_count(dev)) { - old = netdev_mc_count(dev); - pr_debug("%s: setting Rx mode to %d addresses.\n", - dev->name, netdev_mc_count(dev)); - } - } -#endif - - if (!netdev_mc_empty(dev) || (dev->flags & IFF_ALLMULTI)) { - /* Multicast Mode */ - rcvMode = rxConfRxEna + rxConfAMP + rxConfBcast; - } else if (dev->flags & IFF_PROMISC) { - /* Promiscous mode */ - rcvMode = rxConfRxEna + rxConfPro + rxConfAMP + rxConfBcast; - } else { - /* Normal mode */ - rcvMode = rxConfRxEna + rxConfBcast; - } - - /* printk("netwave set_multicast_list: rcvMode to %x\n", rcvMode);*/ - /* Now set receive mode */ - wait_WOC(iobase); - writeb(NETWAVE_CMD_SRC, ramBase + NETWAVE_EREG_CB + 0); - writeb(rcvMode, ramBase + NETWAVE_EREG_CB + 1); - writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2); -} -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 97b9e5ae4039ab32ea5fcef999f6e54ca4af5c94 Mon Sep 17 00:00:00 2001 From: Charles Clément Date: Wed, 5 May 2010 13:54:08 -0700 Subject: Staging: crystalhd: fix missing semicolon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A semicolon is missing at the end of a statement, but it does compile fine without it as the macro BCMLOG_ERR expands to a do {...} while (0); Signed-off-by: Charles Clément Signed-off-by: Greg Kroah-Hartman --- drivers/staging/crystalhd/crystalhd_cmds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/crystalhd/crystalhd_cmds.c b/drivers/staging/crystalhd/crystalhd_cmds.c index d826715809df..1a7ca8ba7f85 100644 --- a/drivers/staging/crystalhd/crystalhd_cmds.c +++ b/drivers/staging/crystalhd/crystalhd_cmds.c @@ -309,7 +309,7 @@ static BC_STATUS bc_cproc_download_fw(struct crystalhd_cmd *ctx, idata->add_cdata_sz); if (sts != BC_STS_SUCCESS) { - BCMLOG_ERR("Firmware Download Failure!! - %d\n", sts) + BCMLOG_ERR("Firmware Download Failure!! - %d\n", sts); } else ctx->state |= BC_LINK_INIT; -- cgit v1.2.3 From 67b0e64a7b219550cc3378800f680e2bb86a10f9 Mon Sep 17 00:00:00 2001 From: Mark Rankilor Date: Thu, 6 May 2010 17:36:38 +0800 Subject: Staging: comedi: Fixed printk call lengths and log levels This is a patch to include log levels and fix some over length lines in printk calls in drivers.c Signed-off-by: Mark Rankilor Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 1f48b6dca08b..4a29ed737e3f 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -95,7 +95,8 @@ static void __comedi_device_detach(struct comedi_device *dev) if (dev->driver) dev->driver->detach(dev); else - printk(KERN_WARNING "BUG: dev->driver=NULL in comedi_device_detach()\n"); + printk(KERN_WARNING + "BUG: dev->driver=NULL in comedi_device_detach()\n"); cleanup_device(dev); } @@ -148,7 +149,8 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* report valid board names before returning error */ for (driv = comedi_drivers; driv; driv = driv->next) { if (!try_module_get(driv->module)) { - printk(KERN_INFO "comedi: failed to increment module count\n"); + printk(KERN_INFO + "comedi: failed to increment module count\n"); continue; } comedi_report_boards(driv); @@ -250,7 +252,8 @@ static int postconfig(struct comedi_device *dev) async = kzalloc(sizeof(struct comedi_async), GFP_KERNEL); if (async == NULL) { - printk(KERN_INFO "failed to allocate async struct\n"); + printk(KERN_INFO + "failed to allocate async struct\n"); return -ENOMEM; } init_waitqueue_head(&async->wait_head); @@ -560,7 +563,8 @@ static unsigned int comedi_buf_munge(struct comedi_async *async, block_size = num_bytes - count; if (block_size < 0) { - printk(KERN_WARNING "%s: %s: bug! block_size is negative\n", + printk(KERN_WARNING + "%s: %s: bug! block_size is negative\n", __FILE__, __func__); break; } @@ -679,8 +683,8 @@ unsigned comedi_buf_read_free(struct comedi_async *async, unsigned int nbytes) smp_mb(); if ((int)(async->buf_read_count + nbytes - async->buf_read_alloc_count) > 0) { - printk - ("comedi: attempted to read-free more bytes than have been read-allocated.\n"); + printk(KERN_INFO + "comedi: attempted to read-free more bytes than have been read-allocated.\n"); nbytes = async->buf_read_alloc_count - async->buf_read_count; } async->buf_read_count += nbytes; -- cgit v1.2.3 From 5e220112c8c8e59c253f6ad473687444b3ca90bf Mon Sep 17 00:00:00 2001 From: Mark Rankilor Date: Thu, 6 May 2010 17:49:37 +0800 Subject: Staging: comedi: Fixed long line length in comedidev.h This patch fixes a long line length in comedidev.h to make checkpatch.pl happy Signed-off-by: Mark Rankilor Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index c38ebb4aa75f..4eb2b77f56dc 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -374,7 +374,9 @@ enum subdevice_runflags { SRF_RUNNING = 0x08000000 }; -int comedi_check_chanlist(struct comedi_subdevice *s, int n, unsigned int *chanlist); +int comedi_check_chanlist(struct comedi_subdevice *s, + int n, + unsigned int *chanlist); unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s); /* range stuff */ -- cgit v1.2.3 From e012b4c41987c40cc2dd82ab48e0569f1d7aa970 Mon Sep 17 00:00:00 2001 From: Mark Rankilor Date: Thu, 6 May 2010 18:07:44 +0800 Subject: Staging: comedi: Fixed long line lengths in comedi.h This patches fixes some of the long line lengths that checkpatch.pl was complaining about in comedi.h Signed-off-by: Mark Rankilor Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi.h | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index 8e4caaacfc1c..20a6fee4dae6 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -46,8 +46,10 @@ #define COMEDI_DEVCONF_AUX_DATA2_LENGTH 26 #define COMEDI_DEVCONF_AUX_DATA1_LENGTH 27 #define COMEDI_DEVCONF_AUX_DATA0_LENGTH 28 -#define COMEDI_DEVCONF_AUX_DATA_HI 29 /* most significant 32 bits of pointer address (if needed) */ -#define COMEDI_DEVCONF_AUX_DATA_LO 30 /* least significant 32 bits of pointer address */ +/* most significant 32 bits of pointer address (if needed) */ +#define COMEDI_DEVCONF_AUX_DATA_HI 29 +/* least significant 32 bits of pointer address */ +#define COMEDI_DEVCONF_AUX_DATA_LO 30 #define COMEDI_DEVCONF_AUX_DATA_LENGTH 31 /* total data length */ /* max length of device and driver names */ @@ -55,8 +57,10 @@ /* packs and unpacks a channel/range number */ -#define CR_PACK(chan, rng, aref) ((((aref)&0x3)<<24) | (((rng)&0xff)<<16) | (chan)) -#define CR_PACK_FLAGS(chan, range, aref, flags) (CR_PACK(chan, range, aref) | ((flags) & CR_FLAGS_MASK)) +#define CR_PACK(chan, rng, aref) \ + ((((aref)&0x3)<<24) | (((rng)&0xff)<<16) | (chan)) +#define CR_PACK_FLAGS(chan, range, aref, flags) \ + (CR_PACK(chan, range, aref) | ((flags) & CR_FLAGS_MASK)) #define CR_CHAN(a) ((a)&0xffff) #define CR_RANGE(a) (((a)>>16)&0xff) @@ -125,7 +129,8 @@ /* command flags */ /* These flags are used in comedi_cmd structures */ -#define CMDF_PRIORITY 0x00000008 /* try to use a real-time interrupt while performing command */ +/* try to use a real-time interrupt while performing command */ +#define CMDF_PRIORITY 0x00000008 #define TRIG_RT CMDF_PRIORITY /* compatibility definition */ @@ -242,15 +247,18 @@ INSN_CONFIG_DISARM = 32, INSN_CONFIG_GET_COUNTER_STATUS = 33, INSN_CONFIG_RESET = 34, - INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR = 1001, /* Use CTR as single pulsegenerator */ - INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR = 1002, /* Use CTR as pulsetraingenerator */ - INSN_CONFIG_GPCT_QUADRATURE_ENCODER = 1003, /* Use the counter as encoder */ + /* Use CTR as single pulsegenerator */ + INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR = 1001, + /* Use CTR as pulsetraingenerator */ + INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR = 1002, + /* Use the counter as encoder */ + INSN_CONFIG_GPCT_QUADRATURE_ENCODER = 1003, INSN_CONFIG_SET_GATE_SRC = 2001, /* Set gate source */ INSN_CONFIG_GET_GATE_SRC = 2002, /* Get gate source */ INSN_CONFIG_SET_CLOCK_SRC = 2003, /* Set master clock source */ INSN_CONFIG_GET_CLOCK_SRC = 2004, /* Get master clock source */ INSN_CONFIG_SET_OTHER_SRC = 2005, /* Set other source */ - /* INSN_CONFIG_GET_OTHER_SRC = 2006,*//* Get other source */ + /* INSN_CONFIG_GET_OTHER_SRC = 2006,*//* Get other source */ INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE = 2006, /* Get size in bytes of subdevice's on-board fifos used during -- cgit v1.2.3 From 043142680ae9493fbfc635c5c4c8a4feb8a0a5f5 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 5 May 2010 15:45:22 -0700 Subject: Staging: rar_register: depends on PCI rar_register driver uses PCI interfaces and PCI devices, so it should depend on PCI. Also format the Kconfig help text as normally done. drivers/staging/rar_register/rar_register.c:623: error: implicit declaration of function 'pci_dev_get' drivers/staging/rar_register/rar_register.c:623: warning: assignment makes pointer from integer without a cast Signed-off-by: Randy Dunlap Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rar_register/Kconfig | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rar_register/Kconfig b/drivers/staging/rar_register/Kconfig index 3f73839643e9..e9c27738199b 100644 --- a/drivers/staging/rar_register/Kconfig +++ b/drivers/staging/rar_register/Kconfig @@ -8,23 +8,23 @@ menu "RAR Register Driver" # config RAR_REGISTER tristate "Restricted Access Region Register Driver" + depends on PCI default n ---help--- - This driver allows other kernel drivers access to the - contents of the restricted access region control - registers. + This driver allows other kernel drivers access to the + contents of the restricted access region control registers. - The restricted access region control registers - (rar_registers) are used to pass address and - locking information on restricted access regions - to other drivers that use restricted access regions + The restricted access region control registers + (rar_registers) are used to pass address and + locking information on restricted access regions + to other drivers that use restricted access regions. - The restricted access regions are regions of memory - on the Intel MID Platform that are not accessible to - the x86 processor, but are accessible to dedicated - processors on board peripheral devices. + The restricted access regions are regions of memory + on the Intel MID Platform that are not accessible to + the x86 processor, but are accessible to dedicated + processors on board peripheral devices. - The purpose of the restricted access regions is to - protect sensitive data from compromise by unauthorized - programs running on the x86 processor. + The purpose of the restricted access regions is to + protect sensitive data from compromise by unauthorized + programs running on the x86 processor. endmenu -- cgit v1.2.3 From de37cd49b5a54facef174cf34496919857436e8f Mon Sep 17 00:00:00 2001 From: Nobuhiro KUSUNO Date: Thu, 6 May 2010 05:23:28 +0900 Subject: Staging: rt2870: add device ID of MelCo.,Inc. WLI-UC-G301N My wireless LAN module 'MelCo.,Inc. WLI-UC-G301N' works fine, if the following line is added into 2870_main_dev.c. Signed-off-by: Nobhiro KUSUNO Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/usb_main_dev.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/rt2860/usb_main_dev.c b/drivers/staging/rt2860/usb_main_dev.c index abe9f241ff93..c6be884d089e 100644 --- a/drivers/staging/rt2860/usb_main_dev.c +++ b/drivers/staging/rt2860/usb_main_dev.c @@ -97,6 +97,7 @@ struct usb_device_id rtusb_usb_id[] = { {USB_DEVICE(0x5A57, 0x0282)}, /* Zinwell */ {USB_DEVICE(0x7392, 0x7718)}, {USB_DEVICE(0x7392, 0x7717)}, + {USB_DEVICE(0x0411, 0x016f)}, /* MelCo.,Inc. WLI-UC-G301N */ {USB_DEVICE(0x1737, 0x0070)}, /* Linksys WUSB100 */ {USB_DEVICE(0x1737, 0x0071)}, /* Linksys WUSB600N */ {USB_DEVICE(0x0411, 0x00e8)}, /* Buffalo WLI-UC-G300N */ -- cgit v1.2.3 From 75568f8094eb0333e9c2109b23cbc8b82d318a3c Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 8 Mar 2010 10:24:29 -0700 Subject: PCI: create function symlinks in /sys/bus/pci/slots/N/ Create convenience symlinks in sysfs, linking slots to device functions, and vice versa. These links make it easier for users to figure out which devices actually live in what slots. For example: sapphire:/sys/bus/pci/slots # ls 1 10 2 3 4 5 6 7 8 9 sapphire:/sys/bus/pci/slots # ls -l 3 total 0 -r--r--r-- 1 root root 65536 Aug 18 14:10 address lrwxrwxrwx 1 root root 0 Aug 18 14:10 function0 -> ../../../../devices/pci0000:23/0000:23:01.0 lrwxrwxrwx 1 root root 0 Aug 18 14:10 function1 -> ../../../../devices/pci0000:23/0000:23:01.1 sapphire:/sys/bus/pci/slots # ls -l 3/function0/slot lrwxrwxrwx 1 root root 0 Aug 18 14:13 3/function0/slot -> ../../../bus/pci/slots/3 The original form of this patch was written by Matthew Wilcox, and was enhanced to include links from the sysfs slots/ directory pointing back at the device functions. Cc: willy@linux.intel.com Signed-off-by: Alex Chiang Signed-off-by: Jesse Barnes --- Documentation/ABI/testing/sysfs-bus-pci | 40 +++++++++++++++++++++++++++ drivers/pci/pci-sysfs.c | 37 +++++++++++++++++++++++++ drivers/pci/slot.c | 48 +++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+) (limited to 'drivers') diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci index 25be3250f7d6..428676cfa61e 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci +++ b/Documentation/ABI/testing/sysfs-bus-pci @@ -133,6 +133,46 @@ Description: The symbolic link points to the PCI device sysfs entry of the Physical Function this device associates with. + +What: /sys/bus/pci/slots/... +Date: April 2005 (possibly older) +KernelVersion: 2.6.12 (possibly older) +Contact: linux-pci@vger.kernel.org +Description: + When the appropriate driver is loaded, it will create a + directory per claimed physical PCI slot in + /sys/bus/pci/slots/. The names of these directories are + specific to the driver, which in turn, are specific to the + platform, but in general, should match the label on the + machine's physical chassis. + + The drivers that can create slot directories include the + PCI hotplug drivers, and as of 2.6.27, the pci_slot driver. + + The slot directories contain, at a minimum, a file named + 'address' which contains the PCI bus:device:function tuple. + Other files may appear as well, but are specific to the + driver. + +What: /sys/bus/pci/slots/.../function[0-7] +Date: March 2010 +KernelVersion: 2.6.35 +Contact: linux-pci@vger.kernel.org +Description: + If PCI slot directories (as described above) are created, + and the physical slot is actually populated with a device, + symbolic links in the slot directory pointing to the + device's PCI functions are created as well. + +What: /sys/bus/pci/devices/.../slot +Date: March 2010 +KernelVersion: 2.6.35 +Contact: linux-pci@vger.kernel.org +Description: + If PCI slot directories (as described above) are created, + a symbolic link pointing to the slot directory will be + created as well. + What: /sys/bus/pci/slots/.../module Date: June 2009 Contact: linux-pci@vger.kernel.org diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index fad93983bfed..941e939d1da9 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -1011,6 +1011,39 @@ error: return retval; } +static void pci_remove_slot_links(struct pci_dev *dev) +{ + char func[10]; + struct pci_slot *slot; + + sysfs_remove_link(&dev->dev.kobj, "slot"); + list_for_each_entry(slot, &dev->bus->slots, list) { + if (slot->number != PCI_SLOT(dev->devfn)) + continue; + snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn)); + sysfs_remove_link(&slot->kobj, func); + } +} + +static int pci_create_slot_links(struct pci_dev *dev) +{ + int result = 0; + char func[10]; + struct pci_slot *slot; + + list_for_each_entry(slot, &dev->bus->slots, list) { + if (slot->number != PCI_SLOT(dev->devfn)) + continue; + result = sysfs_create_link(&dev->dev.kobj, &slot->kobj, "slot"); + if (result) + goto out; + snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn)); + result = sysfs_create_link(&slot->kobj, &dev->dev.kobj, func); + } +out: + return result; +} + int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) { int retval; @@ -1073,6 +1106,8 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) if (retval) goto err_vga_file; + pci_create_slot_links(pdev); + return 0; err_vga_file: @@ -1122,6 +1157,8 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev) if (!sysfs_initialized) return; + pci_remove_slot_links(pdev); + pci_remove_capabilities_sysfs(pdev); if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE) diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index 659eaa0fc48f..e0189cf7c558 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c @@ -97,6 +97,50 @@ static ssize_t cur_speed_read_file(struct pci_slot *slot, char *buf) return bus_speed_read(slot->bus->cur_bus_speed, buf); } +static void remove_sysfs_files(struct pci_slot *slot) +{ + char func[10]; + struct list_head *tmp; + + list_for_each(tmp, &slot->bus->devices) { + struct pci_dev *dev = pci_dev_b(tmp); + if (PCI_SLOT(dev->devfn) != slot->number) + continue; + sysfs_remove_link(&dev->dev.kobj, "slot"); + + snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn)); + sysfs_remove_link(&slot->kobj, func); + } +} + +static int create_sysfs_files(struct pci_slot *slot) +{ + int result; + char func[10]; + struct list_head *tmp; + + list_for_each(tmp, &slot->bus->devices) { + struct pci_dev *dev = pci_dev_b(tmp); + if (PCI_SLOT(dev->devfn) != slot->number) + continue; + + result = sysfs_create_link(&dev->dev.kobj, &slot->kobj, "slot"); + if (result) + goto fail; + + snprintf(func, 10, "function%d", PCI_FUNC(dev->devfn)); + result = sysfs_create_link(&slot->kobj, &dev->dev.kobj, func); + if (result) + goto fail; + } + + return 0; + +fail: + remove_sysfs_files(slot); + return result; +} + static void pci_slot_release(struct kobject *kobj) { struct pci_dev *dev; @@ -109,6 +153,8 @@ static void pci_slot_release(struct kobject *kobj) if (PCI_SLOT(dev->devfn) == slot->number) dev->slot = NULL; + remove_sysfs_files(slot); + list_del(&slot->list); kfree(slot); @@ -300,6 +346,8 @@ placeholder: INIT_LIST_HEAD(&slot->list); list_add(&slot->list, &parent->slots); + create_sysfs_files(slot); + list_for_each_entry(dev, &parent->devices, bus_list) if (PCI_SLOT(dev->devfn) == slot_nr) dev->slot = slot; -- cgit v1.2.3 From 52b265a12768b9a72679bec825eb82c784116464 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 8 Mar 2010 16:48:49 -0500 Subject: PCI: clearing wakeup flags not needed This patch (as1353) removes a couple of unnecessary assignments from the PCI core. The should_wakeup flag is naturally initialized to 0; there's no need to clear it. Acked-by: Rafael J. Wysocki Signed-off-by: Alan Stern Signed-off-by: Jesse Barnes --- drivers/pci/pci.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 37499127c801..60fcb6f02c91 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1631,7 +1631,6 @@ void pci_pm_init(struct pci_dev *dev) * let the user space enable it to wake up the system as needed. */ device_set_wakeup_capable(&dev->dev, true); - device_set_wakeup_enable(&dev->dev, false); /* Disable the PME# generation functionality */ pci_pme_active(dev, false); } else { @@ -1655,7 +1654,6 @@ void platform_pci_wakeup_init(struct pci_dev *dev) return; device_set_wakeup_capable(&dev->dev, true); - device_set_wakeup_enable(&dev->dev, false); platform_pci_sleep_wake(dev, false); } -- cgit v1.2.3 From 511dd98ce8cf6dc4f8f2cb32a8af31ce9f4ba4a1 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 17 Feb 2010 14:35:19 +0000 Subject: PCI: Convert pci_lock to raw_spinlock pci_lock must be a real spinlock in preempt-rt. Convert it to raw_spinlock. No change for !RT kernels. Signed-off-by: Thomas Gleixner Signed-off-by: Jesse Barnes --- drivers/pci/access.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 2f646fe1260f..affb83b42ebb 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -13,7 +13,7 @@ * configuration space. */ -static DEFINE_SPINLOCK(pci_lock); +static DEFINE_RAW_SPINLOCK(pci_lock); /* * Wrappers for all PCI configuration access functions. They just check @@ -33,10 +33,10 @@ int pci_bus_read_config_##size \ unsigned long flags; \ u32 data = 0; \ if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ - spin_lock_irqsave(&pci_lock, flags); \ + raw_spin_lock_irqsave(&pci_lock, flags); \ res = bus->ops->read(bus, devfn, pos, len, &data); \ *value = (type)data; \ - spin_unlock_irqrestore(&pci_lock, flags); \ + raw_spin_unlock_irqrestore(&pci_lock, flags); \ return res; \ } @@ -47,9 +47,9 @@ int pci_bus_write_config_##size \ int res; \ unsigned long flags; \ if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ - spin_lock_irqsave(&pci_lock, flags); \ + raw_spin_lock_irqsave(&pci_lock, flags); \ res = bus->ops->write(bus, devfn, pos, len, value); \ - spin_unlock_irqrestore(&pci_lock, flags); \ + raw_spin_unlock_irqrestore(&pci_lock, flags); \ return res; \ } @@ -79,10 +79,10 @@ struct pci_ops *pci_bus_set_ops(struct pci_bus *bus, struct pci_ops *ops) struct pci_ops *old_ops; unsigned long flags; - spin_lock_irqsave(&pci_lock, flags); + raw_spin_lock_irqsave(&pci_lock, flags); old_ops = bus->ops; bus->ops = ops; - spin_unlock_irqrestore(&pci_lock, flags); + raw_spin_unlock_irqrestore(&pci_lock, flags); return old_ops; } EXPORT_SYMBOL(pci_bus_set_ops); @@ -136,9 +136,9 @@ static noinline void pci_wait_ucfg(struct pci_dev *dev) __add_wait_queue(&pci_ucfg_wait, &wait); do { set_current_state(TASK_UNINTERRUPTIBLE); - spin_unlock_irq(&pci_lock); + raw_spin_unlock_irq(&pci_lock); schedule(); - spin_lock_irq(&pci_lock); + raw_spin_lock_irq(&pci_lock); } while (dev->block_ucfg_access); __remove_wait_queue(&pci_ucfg_wait, &wait); } @@ -150,11 +150,11 @@ int pci_user_read_config_##size \ int ret = 0; \ u32 data = -1; \ if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ - spin_lock_irq(&pci_lock); \ + raw_spin_lock_irq(&pci_lock); \ if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \ ret = dev->bus->ops->read(dev->bus, dev->devfn, \ pos, sizeof(type), &data); \ - spin_unlock_irq(&pci_lock); \ + raw_spin_unlock_irq(&pci_lock); \ *val = (type)data; \ return ret; \ } @@ -165,11 +165,11 @@ int pci_user_write_config_##size \ { \ int ret = -EIO; \ if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ - spin_lock_irq(&pci_lock); \ + raw_spin_lock_irq(&pci_lock); \ if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \ ret = dev->bus->ops->write(dev->bus, dev->devfn, \ pos, sizeof(type), val); \ - spin_unlock_irq(&pci_lock); \ + raw_spin_unlock_irq(&pci_lock); \ return ret; \ } @@ -396,10 +396,10 @@ void pci_block_user_cfg_access(struct pci_dev *dev) unsigned long flags; int was_blocked; - spin_lock_irqsave(&pci_lock, flags); + raw_spin_lock_irqsave(&pci_lock, flags); was_blocked = dev->block_ucfg_access; dev->block_ucfg_access = 1; - spin_unlock_irqrestore(&pci_lock, flags); + raw_spin_unlock_irqrestore(&pci_lock, flags); /* If we BUG() inside the pci_lock, we're guaranteed to hose * the machine */ @@ -417,7 +417,7 @@ void pci_unblock_user_cfg_access(struct pci_dev *dev) { unsigned long flags; - spin_lock_irqsave(&pci_lock, flags); + raw_spin_lock_irqsave(&pci_lock, flags); /* This indicates a problem in the caller, but we don't need * to kill them, unlike a double-block above. */ @@ -425,6 +425,6 @@ void pci_unblock_user_cfg_access(struct pci_dev *dev) dev->block_ucfg_access = 0; wake_up_all(&pci_ucfg_wait); - spin_unlock_irqrestore(&pci_lock, flags); + raw_spin_unlock_irqrestore(&pci_lock, flags); } EXPORT_SYMBOL_GPL(pci_unblock_user_cfg_access); -- cgit v1.2.3 From 3196180a54b593838c0b6496e5b524a2f69bb190 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 8 Apr 2010 09:38:47 -0700 Subject: PCI: change PCI_MSI help text to recommend enabling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most current machines have no problem with this, and in fact many devices and features work best (or only!) with MSI. Reported-by: Petteri Räty Signed-off-by: Jesse Barnes --- drivers/pci/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 7858a117e80b..34ef70d562b2 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -19,7 +19,7 @@ config PCI_MSI by using the 'pci=nomsi' option. This disables MSI for the entire system. - If you don't know what to do here, say N. + If you don't know what to do here, say Y. config PCI_DEBUG bool "PCI Debugging" -- cgit v1.2.3 From 447c5dd7338638f526e9bcf7dcf69b4da5835c7d Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Tue, 11 May 2010 11:44:54 +0200 Subject: PCI: return correct value when writing to the "reset" attribute A successful write() to the "reset" sysfs attribute should return the number of bytes written, not 0. Otherwise userspace (bash) retries the write over and over again. Acked-by: Michael S. Tsirkin Acked-by: Greg Kroah-Hartman Signed-off-by: Michal Schmidt Signed-off-by: Jesse Barnes --- drivers/pci/pci-sysfs.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 941e939d1da9..89a08ed39c94 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -960,7 +960,12 @@ static ssize_t reset_store(struct device *dev, if (val != 1) return -EINVAL; - return pci_reset_function(pdev); + + result = pci_reset_function(pdev); + if (result < 0) + return result; + + return count; } static struct device_attribute reset_attr = __ATTR(reset, 0200, NULL, reset_store); -- cgit v1.2.3 From c6d34eddecb34fd84f9fb2ea26a63cfde5662f49 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Thu, 15 Apr 2010 13:09:13 +0900 Subject: PCI: aerdrv: RsvdP of PCI_ERR_ROOT_COMMAND Handle preserved bits properly. Signed-off-by: Hidetoshi Seto Reviewed-by: Kenji Kaneshige Signed-off-by: Jesse Barnes --- drivers/pci/pcie/aer/aerdrv.c | 18 +++++++++++------- drivers/pci/pcie/aer/aerdrv_core.c | 10 ++++++---- 2 files changed, 17 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index 7a711ee314b7..4e845ab18643 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c @@ -234,13 +234,15 @@ static int __devinit aer_probe(struct pcie_device *dev) static pci_ers_result_t aer_root_reset(struct pci_dev *dev) { u16 p2p_ctrl; - u32 status; + u32 reg32; int pos; pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); /* Disable Root's interrupt in response to error messages */ - pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, 0); + pci_read_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, ®32); + reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK; + pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, reg32); /* Assert Secondary Bus Reset */ pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &p2p_ctrl); @@ -265,12 +267,14 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev) msleep(200); dev_printk(KERN_DEBUG, &dev->dev, "Root Port link has been reset\n"); + /* Clear Root Error Status */ + pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, ®32); + pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, reg32); + /* Enable Root Port's interrupt in response to error messages */ - pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &status); - pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, status); - pci_write_config_dword(dev, - pos + PCI_ERR_ROOT_COMMAND, - ROOT_PORT_INTR_ON_MESG_MASK); + pci_read_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, ®32); + reg32 |= ROOT_PORT_INTR_ON_MESG_MASK; + pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, reg32); return PCI_ERS_RESULT_RECOVERED; } diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index aceb04b67b60..9754a09bf20e 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -623,9 +623,9 @@ void aer_enable_rootport(struct aer_rpc *rpc) set_downstream_devices_error_reporting(pdev, true); /* Enable Root Port's interrupt in response to error messages */ - pci_write_config_dword(pdev, - aer_pos + PCI_ERR_ROOT_COMMAND, - ROOT_PORT_INTR_ON_MESG_MASK); + pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_COMMAND, ®32); + reg32 |= ROOT_PORT_INTR_ON_MESG_MASK; + pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_COMMAND, reg32); } /** @@ -648,7 +648,9 @@ static void disable_root_aer(struct aer_rpc *rpc) pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); /* Disable Root's interrupt in response to error messages */ - pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0); + pci_read_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, ®32); + reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK; + pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, reg32); /* Clear Root's error status reg */ pci_read_config_dword(pdev, pos + PCI_ERR_ROOT_STATUS, ®32); -- cgit v1.2.3 From 460d298d521910483dcdc09920ca4c4a63b16730 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Thu, 15 Apr 2010 13:10:03 +0900 Subject: PCI: aerdrv: cleanup inconsistent functions This cleanup solves some minor naming issues by removing unuseful function aer_delete_rootport() and by renaming disable_root_aer() to aer_disable_rootport(). - Inconsistent location of alloc & free: The struct rpc is allocated in aer_alloc_rpc() at aerdrv.c while it is implicitly freed in aer_delete_rootport() at aerdrv_core.c. - Inconsistent function name: It makes a bit confusion that aer_delete_rootport() is seemed to be paired with aer_enable_rootport(), i.e. there is neither "add" against "delete" nor "disable" against "enable". Signed-off-by: Hidetoshi Seto Reviewed-by: Kenji Kaneshige Signed-off-by: Jesse Barnes --- drivers/pci/pcie/aer/aerdrv.c | 3 ++- drivers/pci/pcie/aer/aerdrv.h | 2 +- drivers/pci/pcie/aer/aerdrv_core.c | 18 ++---------------- 3 files changed, 5 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index 4e845ab18643..14081f807e50 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c @@ -179,7 +179,8 @@ static void aer_remove(struct pcie_device *dev) wait_event(rpc->wait_release, rpc->prod_idx == rpc->cons_idx); - aer_delete_rootport(rpc); + aer_disable_rootport(rpc); + kfree(rpc); set_service_data(dev, NULL); } } diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h index bd833ea3ba49..b6fc5389dd09 100644 --- a/drivers/pci/pcie/aer/aerdrv.h +++ b/drivers/pci/pcie/aer/aerdrv.h @@ -118,7 +118,7 @@ static inline pci_ers_result_t merge_result(enum pci_ers_result orig, extern struct bus_type pcie_port_bus_type; extern void aer_enable_rootport(struct aer_rpc *rpc); -extern void aer_delete_rootport(struct aer_rpc *rpc); +extern void aer_disable_rootport(struct aer_rpc *rpc); extern int aer_init(struct pcie_device *dev); extern void aer_isr(struct work_struct *work); extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 9754a09bf20e..0dcbae126834 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -629,12 +629,12 @@ void aer_enable_rootport(struct aer_rpc *rpc) } /** - * disable_root_aer - disable Root Port's interrupts when receiving messages + * aer_disable_rootport - disable Root Port's interrupts when receiving messages * @rpc: pointer to a Root Port data structure * * Invoked when PCIe bus unloads AER service driver. */ -static void disable_root_aer(struct aer_rpc *rpc) +void aer_disable_rootport(struct aer_rpc *rpc) { struct pci_dev *pdev = rpc->rpd->port; u32 reg32; @@ -839,20 +839,6 @@ void aer_isr(struct work_struct *work) wake_up(&rpc->wait_release); } -/** - * aer_delete_rootport - disable root port aer and delete service data - * @rpc: pointer to a root port device being deleted - * - * Invoked when AER service unloaded on a specific Root Port - */ -void aer_delete_rootport(struct aer_rpc *rpc) -{ - /* Disable root port AER itself */ - disable_root_aer(rpc); - - kfree(rpc); -} - /** * aer_init - provide AER initialization * @dev: pointer to AER pcie device -- cgit v1.2.3 From 843f4697eea576c24f057bbdb199115bbb6b10bc Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Thu, 15 Apr 2010 13:10:53 +0900 Subject: PCI: aerdrv: make aer_{en,dis}able_rootport static These functions are only called from init/remove path of aerdrv, so move them from aerdrv_core.c to aerdrv.c, to make them static. Signed-off-by: Hidetoshi Seto Reviewed-by: Kenji Kaneshige Signed-off-by: Jesse Barnes --- drivers/pci/pcie/aer/aerdrv.c | 107 +++++++++++++++++++++++++++++++++++++ drivers/pci/pcie/aer/aerdrv.h | 2 - drivers/pci/pcie/aer/aerdrv_core.c | 107 ------------------------------------- 3 files changed, 107 insertions(+), 109 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index 14081f807e50..b69dbdc36817 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c @@ -72,6 +72,113 @@ void pci_no_aer(void) pcie_aer_disable = 1; /* has priority over 'forceload' */ } +static int set_device_error_reporting(struct pci_dev *dev, void *data) +{ + bool enable = *((bool *)data); + + if ((dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) || + (dev->pcie_type == PCI_EXP_TYPE_UPSTREAM) || + (dev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)) { + if (enable) + pci_enable_pcie_error_reporting(dev); + else + pci_disable_pcie_error_reporting(dev); + } + + if (enable) + pcie_set_ecrc_checking(dev); + + return 0; +} + +/** + * set_downstream_devices_error_reporting - enable/disable the error reporting bits on the root port and its downstream ports. + * @dev: pointer to root port's pci_dev data structure + * @enable: true = enable error reporting, false = disable error reporting. + */ +static void set_downstream_devices_error_reporting(struct pci_dev *dev, + bool enable) +{ + set_device_error_reporting(dev, &enable); + + if (!dev->subordinate) + return; + pci_walk_bus(dev->subordinate, set_device_error_reporting, &enable); +} + +/** + * aer_enable_rootport - enable Root Port's interrupts when receiving messages + * @rpc: pointer to a Root Port data structure + * + * Invoked when PCIe bus loads AER service driver. + */ +static void aer_enable_rootport(struct aer_rpc *rpc) +{ + struct pci_dev *pdev = rpc->rpd->port; + int pos, aer_pos; + u16 reg16; + u32 reg32; + + pos = pci_pcie_cap(pdev); + /* Clear PCIe Capability's Device Status */ + pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, ®16); + pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16); + + /* Disable system error generation in response to error messages */ + pci_read_config_word(pdev, pos + PCI_EXP_RTCTL, ®16); + reg16 &= ~(SYSTEM_ERROR_INTR_ON_MESG_MASK); + pci_write_config_word(pdev, pos + PCI_EXP_RTCTL, reg16); + + aer_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); + /* Clear error status */ + pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, ®32); + pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32); + pci_read_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, ®32); + pci_write_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, reg32); + pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, ®32); + pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32); + + /* + * Enable error reporting for the root port device and downstream port + * devices. + */ + set_downstream_devices_error_reporting(pdev, true); + + /* Enable Root Port's interrupt in response to error messages */ + pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_COMMAND, ®32); + reg32 |= ROOT_PORT_INTR_ON_MESG_MASK; + pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_COMMAND, reg32); +} + +/** + * aer_disable_rootport - disable Root Port's interrupts when receiving messages + * @rpc: pointer to a Root Port data structure + * + * Invoked when PCIe bus unloads AER service driver. + */ +static void aer_disable_rootport(struct aer_rpc *rpc) +{ + struct pci_dev *pdev = rpc->rpd->port; + u32 reg32; + int pos; + + /* + * Disable error reporting for the root port device and downstream port + * devices. + */ + set_downstream_devices_error_reporting(pdev, false); + + pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); + /* Disable Root's interrupt in response to error messages */ + pci_read_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, ®32); + reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK; + pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, reg32); + + /* Clear Root's error status reg */ + pci_read_config_dword(pdev, pos + PCI_ERR_ROOT_STATUS, ®32); + pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_STATUS, reg32); +} + /** * aer_irq - Root Port's ISR * @irq: IRQ assigned to Root Port diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h index b6fc5389dd09..2f345405e823 100644 --- a/drivers/pci/pcie/aer/aerdrv.h +++ b/drivers/pci/pcie/aer/aerdrv.h @@ -117,8 +117,6 @@ static inline pci_ers_result_t merge_result(enum pci_ers_result orig, } extern struct bus_type pcie_port_bus_type; -extern void aer_enable_rootport(struct aer_rpc *rpc); -extern void aer_disable_rootport(struct aer_rpc *rpc); extern int aer_init(struct pcie_device *dev); extern void aer_isr(struct work_struct *work); extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 0dcbae126834..ad15eea54fd0 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -99,40 +99,6 @@ int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) } EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status); -static int set_device_error_reporting(struct pci_dev *dev, void *data) -{ - bool enable = *((bool *)data); - - if ((dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) || - (dev->pcie_type == PCI_EXP_TYPE_UPSTREAM) || - (dev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)) { - if (enable) - pci_enable_pcie_error_reporting(dev); - else - pci_disable_pcie_error_reporting(dev); - } - - if (enable) - pcie_set_ecrc_checking(dev); - - return 0; -} - -/** - * set_downstream_devices_error_reporting - enable/disable the error reporting bits on the root port and its downstream ports. - * @dev: pointer to root port's pci_dev data structure - * @enable: true = enable error reporting, false = disable error reporting. - */ -static void set_downstream_devices_error_reporting(struct pci_dev *dev, - bool enable) -{ - set_device_error_reporting(dev, &enable); - - if (!dev->subordinate) - return; - pci_walk_bus(dev->subordinate, set_device_error_reporting, &enable); -} - static inline int compare_device_id(struct pci_dev *dev, struct aer_err_info *e_info) { @@ -584,79 +550,6 @@ static void handle_error_source(struct pcie_device *aerdev, } } -/** - * aer_enable_rootport - enable Root Port's interrupts when receiving messages - * @rpc: pointer to a Root Port data structure - * - * Invoked when PCIe bus loads AER service driver. - */ -void aer_enable_rootport(struct aer_rpc *rpc) -{ - struct pci_dev *pdev = rpc->rpd->port; - int pos, aer_pos; - u16 reg16; - u32 reg32; - - pos = pci_pcie_cap(pdev); - /* Clear PCIe Capability's Device Status */ - pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, ®16); - pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16); - - /* Disable system error generation in response to error messages */ - pci_read_config_word(pdev, pos + PCI_EXP_RTCTL, ®16); - reg16 &= ~(SYSTEM_ERROR_INTR_ON_MESG_MASK); - pci_write_config_word(pdev, pos + PCI_EXP_RTCTL, reg16); - - aer_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); - /* Clear error status */ - pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, ®32); - pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32); - pci_read_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, ®32); - pci_write_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, reg32); - pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, ®32); - pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32); - - /* - * Enable error reporting for the root port device and downstream port - * devices. - */ - set_downstream_devices_error_reporting(pdev, true); - - /* Enable Root Port's interrupt in response to error messages */ - pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_COMMAND, ®32); - reg32 |= ROOT_PORT_INTR_ON_MESG_MASK; - pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_COMMAND, reg32); -} - -/** - * aer_disable_rootport - disable Root Port's interrupts when receiving messages - * @rpc: pointer to a Root Port data structure - * - * Invoked when PCIe bus unloads AER service driver. - */ -void aer_disable_rootport(struct aer_rpc *rpc) -{ - struct pci_dev *pdev = rpc->rpd->port; - u32 reg32; - int pos; - - /* - * Disable error reporting for the root port device and downstream port - * devices. - */ - set_downstream_devices_error_reporting(pdev, false); - - pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); - /* Disable Root's interrupt in response to error messages */ - pci_read_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, ®32); - reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK; - pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, reg32); - - /* Clear Root's error status reg */ - pci_read_config_dword(pdev, pos + PCI_ERR_ROOT_STATUS, ®32); - pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_STATUS, reg32); -} - /** * get_e_source - retrieve an error source * @rpc: pointer to the root port which holds an error -- cgit v1.2.3 From 98ca3964fe8da0d742331af80952443af5cff464 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Thu, 15 Apr 2010 13:11:42 +0900 Subject: PCI: aerdrv: rework find_source_device Return bool to indicate that the source device is found or not. This allows us to skip calling aer_process_err_devices() if we can. And move dev_printk for debug into this function. v2: return bool instead of int Signed-off-by: Hidetoshi Seto Reviewed-by: Kenji Kaneshige Signed-off-by: Jesse Barnes --- drivers/pci/pcie/aer/aerdrv_core.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index ad15eea54fd0..5fa5c76719b0 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -215,11 +215,13 @@ added: /** * find_source_device - search through device hierarchy for source device * @parent: pointer to Root Port pci_dev data structure - * @err_info: including detailed error information such like id + * @e_info: including detailed error information such like id * - * Invoked when error is detected at the Root Port. + * Return true if found. + * + * Invoked by DPC when error is detected at the Root Port. */ -static void find_source_device(struct pci_dev *parent, +static bool find_source_device(struct pci_dev *parent, struct aer_err_info *e_info) { struct pci_dev *dev = parent; @@ -228,9 +230,17 @@ static void find_source_device(struct pci_dev *parent, /* Is Root Port an agent that sends error message? */ result = find_device_iter(dev, e_info); if (result) - return; + return true; pci_walk_bus(parent->subordinate, find_device_iter, e_info); + + if (!e_info->error_dev_num) { + dev_printk(KERN_DEBUG, &parent->dev, + "can't find device of ID%04x\n", + e_info->id); + return false; + } + return true; } static int report_error_detected(struct pci_dev *dev, void *data) @@ -639,12 +649,6 @@ static inline void aer_process_err_devices(struct pcie_device *p_device, { int i; - if (!e_info->dev[0]) { - dev_printk(KERN_DEBUG, &p_device->port->dev, - "can't find device of ID%04x\n", - e_info->id); - } - /* Report all before handle them, not to lost records by reset etc. */ for (i = 0; i < e_info->error_dev_num && e_info->dev[i]; i++) { if (get_device_error_info(e_info->dev[i], e_info)) @@ -702,8 +706,8 @@ static void aer_isr_one_error(struct pcie_device *p_device, aer_print_port_info(p_device->port, e_info); - find_source_device(p_device->port, e_info); - aer_process_err_devices(p_device, e_info); + if (find_source_device(p_device->port, e_info)) + aer_process_err_devices(p_device, e_info); } kfree(e_info); -- cgit v1.2.3 From c887275e6a5b857b72c798e4a6019160a860e2ef Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Thu, 15 Apr 2010 13:12:21 +0900 Subject: PCI: aerdrv: introduce is_error_source Take core part of find_device_iter() to make a new function is_error_source() that checks given device has report an error or not. Signed-off-by: Hidetoshi Seto Reviewed-by: Kenji Kaneshige Signed-off-by: Jesse Barnes --- drivers/pci/pcie/aer/aerdrv_core.c | 74 ++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 5fa5c76719b0..5b02f62cdc47 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -126,14 +126,17 @@ static int add_error_device(struct aer_err_info *e_info, struct pci_dev *dev) #define PCI_BUS(x) (((x) >> 8) & 0xff) -static int find_device_iter(struct pci_dev *dev, void *data) +/** + * is_error_source - check whether the device is source of reported error + * @dev: pointer to pci_dev to be checked + * @e_info: pointer to reported error info + */ +static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info) { int pos; - u32 status; - u32 mask; + u32 status, mask; u16 reg16; int result; - struct aer_err_info *e_info = (struct aer_err_info *)data; /* * When bus id is equal to 0, it might be a bad id @@ -142,22 +145,11 @@ static int find_device_iter(struct pci_dev *dev, void *data) if (!nosourceid && (PCI_BUS(e_info->id) != 0)) { result = compare_device_id(dev, e_info); if (result) - add_error_device(e_info, dev); + return true; - /* - * If there is no multiple error, we stop - * or continue based on the id comparing. - */ + /* Continue id comparing if there is no multiple error */ if (!e_info->multi_error_valid) - return result; - - /* - * If there are multiple errors and id does match, - * We need continue to search other devices under - * the root port. Return 0 means that. - */ - if (result) - return 0; + return false; } /* @@ -166,50 +158,52 @@ static int find_device_iter(struct pci_dev *dev, void *data) * 2) bus id is equal to 0. Some ports might lose the bus * id of error source id; * 3) There are multiple errors and prior id comparing fails; - * We check AER status registers to find the initial reporter. + * We check AER status registers to find possible reporter. */ if (atomic_read(&dev->enable_cnt) == 0) - return 0; + return false; pos = pci_pcie_cap(dev); if (!pos) - return 0; + return false; + /* Check if AER is enabled */ - pci_read_config_word(dev, pos+PCI_EXP_DEVCTL, ®16); + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, ®16); if (!(reg16 & ( PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE))) - return 0; + return false; pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); if (!pos) - return 0; + return false; - status = 0; - mask = 0; + /* Check if error is recorded */ if (e_info->severity == AER_CORRECTABLE) { pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &status); pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &mask); - if (status & ~mask) { - add_error_device(e_info, dev); - goto added; - } } else { pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, &mask); - if (status & ~mask) { - add_error_device(e_info, dev); - goto added; - } } + if (status & ~mask) + return true; - return 0; + return false; +} -added: - if (e_info->multi_error_valid) - return 0; - else - return 1; +static int find_device_iter(struct pci_dev *dev, void *data) +{ + struct aer_err_info *e_info = (struct aer_err_info *)data; + + if (is_error_source(dev, e_info)) { + add_error_device(e_info, dev); + + /* If there is only a single error, stop iteration */ + if (!e_info->multi_error_valid) + return 1; + } + return 0; } /** -- cgit v1.2.3 From bd17d4742d5a8cbedd41a1d44c0cdee84a532363 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Thu, 15 Apr 2010 13:13:41 +0900 Subject: PCI: aerdrv: remove compare_device_id Inline too-simple subroutine only used here. Signed-off-by: Hidetoshi Seto Reviewed-by: Kenji Kaneshige Signed-off-by: Jesse Barnes --- drivers/pci/pcie/aer/aerdrv_core.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 5b02f62cdc47..f8ffa47503b7 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -99,19 +99,6 @@ int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) } EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status); -static inline int compare_device_id(struct pci_dev *dev, - struct aer_err_info *e_info) -{ - if (e_info->id == ((dev->bus->number << 8) | dev->devfn)) { - /* - * Device ID match - */ - return 1; - } - - return 0; -} - static int add_error_device(struct aer_err_info *e_info, struct pci_dev *dev) { if (e_info->error_dev_num < AER_MAX_MULTI_ERR_DEVICES) { @@ -136,15 +123,14 @@ static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info) int pos; u32 status, mask; u16 reg16; - int result; /* * When bus id is equal to 0, it might be a bad id * reported by root port. */ if (!nosourceid && (PCI_BUS(e_info->id) != 0)) { - result = compare_device_id(dev, e_info); - if (result) + /* Device ID match? */ + if (e_info->id == ((dev->bus->number << 8) | dev->devfn)) return true; /* Continue id comparing if there is no multiple error */ -- cgit v1.2.3 From 4a0c096efd4383fc98aa40e195363f600ba814f8 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Thu, 15 Apr 2010 13:14:17 +0900 Subject: PCI: aerdrv: rework add_error_device Stop iteration if we cannot register any more. Signed-off-by: Hidetoshi Seto Reviewed-by: Kenji Kaneshige Signed-off-by: Jesse Barnes --- drivers/pci/pcie/aer/aerdrv_core.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index f8ffa47503b7..f5eb69f532e7 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -99,18 +99,21 @@ int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) } EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status); +/** + * add_error_device - list device to be handled + * @e_info: pointer to error info + * @dev: pointer to pci_dev to be added + */ static int add_error_device(struct aer_err_info *e_info, struct pci_dev *dev) { if (e_info->error_dev_num < AER_MAX_MULTI_ERR_DEVICES) { e_info->dev[e_info->error_dev_num] = dev; e_info->error_dev_num++; - return 1; + return 0; } - - return 0; + return -ENOSPC; } - #define PCI_BUS(x) (((x) >> 8) & 0xff) /** @@ -183,7 +186,12 @@ static int find_device_iter(struct pci_dev *dev, void *data) struct aer_err_info *e_info = (struct aer_err_info *)data; if (is_error_source(dev, e_info)) { - add_error_device(e_info, dev); + /* List this device */ + if (add_error_device(e_info, dev)) { + /* We cannot handle more... Stop iteration */ + /* TODO: Should print error message here? */ + return 1; + } /* If there is only a single error, stop iteration */ if (!e_info->multi_error_valid) -- cgit v1.2.3 From 7c4ec94f72cefec1c1b42219469794a34864a1ee Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Thu, 15 Apr 2010 13:15:08 +0900 Subject: PCI: aerdrv: rework aer_isr_one_error() Divide tricky for-loop into readable if-blocks. The logic to set multi_error_valid (to force walking pci bus hierarchy to find 2nd~ error devices) is changed too, to check MULTI_{,_UN}COR_RCV bit individually and to force walk only when it is required. And rework setting e_info->severity for uncorrectable, not to use magic numbers. Signed-off-by: Hidetoshi Seto Reviewed-by: Kenji Kaneshige Signed-off-by: Jesse Barnes --- drivers/pci/pcie/aer/aerdrv_core.c | 57 ++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index f5eb69f532e7..ca140580199c 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -208,6 +208,9 @@ static int find_device_iter(struct pci_dev *dev, void *data) * Return true if found. * * Invoked by DPC when error is detected at the Root Port. + * Caller of this function must set id, severity, and multi_error_valid of + * struct aer_err_info pointed by @e_info properly. This function must fill + * e_info->error_dev_num and e_info->dev[], based on the given information. */ static bool find_source_device(struct pci_dev *parent, struct aer_err_info *e_info) @@ -215,6 +218,9 @@ static bool find_source_device(struct pci_dev *parent, struct pci_dev *dev = parent; int result; + /* Must reset in this function */ + e_info->error_dev_num = 0; + /* Is Root Port an agent that sends error message? */ result = find_device_iter(dev, e_info); if (result) @@ -580,11 +586,14 @@ static struct aer_err_source *get_e_source(struct aer_rpc *rpc) * @info: pointer to structure to store the error record * * Return 1 on success, 0 on error. + * + * Note that @info is reused among all error devices. Clear fields properly. */ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info) { int pos, temp; + /* Must reset in this function */ info->status = 0; info->tlp_header_valid = 0; @@ -657,11 +666,10 @@ static void aer_isr_one_error(struct pcie_device *p_device, struct aer_err_source *e_src) { struct aer_err_info *e_info; - int i; /* struct aer_err_info might be big, so we allocate it with slab */ e_info = kmalloc(sizeof(struct aer_err_info), GFP_KERNEL); - if (e_info == NULL) { + if (!e_info) { dev_printk(KERN_DEBUG, &p_device->port->dev, "Can't allocate mem when processing AER errors\n"); return; @@ -671,26 +679,33 @@ static void aer_isr_one_error(struct pcie_device *p_device, * There is a possibility that both correctable error and * uncorrectable error being logged. Report correctable error first. */ - for (i = 1; i & ROOT_ERR_STATUS_MASKS ; i <<= 2) { - if (i > 4) - break; - if (!(e_src->status & i)) - continue; - - memset(e_info, 0, sizeof(struct aer_err_info)); - - /* Init comprehensive error information */ - if (i & PCI_ERR_ROOT_COR_RCV) { - e_info->id = ERR_COR_ID(e_src->id); - e_info->severity = AER_CORRECTABLE; - } else { - e_info->id = ERR_UNCOR_ID(e_src->id); - e_info->severity = ((e_src->status >> 6) & 1); - } - if (e_src->status & - (PCI_ERR_ROOT_MULTI_COR_RCV | - PCI_ERR_ROOT_MULTI_UNCOR_RCV)) + if (e_src->status & PCI_ERR_ROOT_COR_RCV) { + e_info->id = ERR_COR_ID(e_src->id); + e_info->severity = AER_CORRECTABLE; + + if (e_src->status & PCI_ERR_ROOT_MULTI_COR_RCV) + e_info->multi_error_valid = 1; + else + e_info->multi_error_valid = 0; + + aer_print_port_info(p_device->port, e_info); + + if (find_source_device(p_device->port, e_info)) + aer_process_err_devices(p_device, e_info); + } + + if (e_src->status & PCI_ERR_ROOT_UNCOR_RCV) { + e_info->id = ERR_UNCOR_ID(e_src->id); + + if (e_src->status & PCI_ERR_ROOT_FATAL_RCV) + e_info->severity = AER_FATAL; + else + e_info->severity = AER_NONFATAL; + + if (e_src->status & PCI_ERR_ROOT_MULTI_UNCOR_RCV) e_info->multi_error_valid = 1; + else + e_info->multi_error_valid = 0; aer_print_port_info(p_device->port, e_info); -- cgit v1.2.3 From 88da13bfabbffb8f89574eb168b9da9a0abc693f Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Thu, 15 Apr 2010 13:16:16 +0900 Subject: PCI: aerdrv: rework get_e_source() Current get_e_source() returns pointer to an element of array. However since it also progress consume counter, it is possible that the element is overwritten by newly produced data before the element is really consumed. This patch changes get_e_source() to copy contents of the element to address pointed by its caller. Once copied the element in array can be consumed. And relocate this function to more innocuous place. Signed-off-by: Hidetoshi Seto Reviewed-by: Kenji Kaneshige Signed-off-by: Jesse Barnes --- drivers/pci/pcie/aer/aerdrv_core.c | 63 +++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index ca140580199c..210e53c2fdc1 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -554,32 +554,6 @@ static void handle_error_source(struct pcie_device *aerdev, } } -/** - * get_e_source - retrieve an error source - * @rpc: pointer to the root port which holds an error - * - * Invoked by DPC handler to consume an error. - */ -static struct aer_err_source *get_e_source(struct aer_rpc *rpc) -{ - struct aer_err_source *e_source; - unsigned long flags; - - /* Lock access to Root error producer/consumer index */ - spin_lock_irqsave(&rpc->e_lock, flags); - if (rpc->prod_idx == rpc->cons_idx) { - spin_unlock_irqrestore(&rpc->e_lock, flags); - return NULL; - } - e_source = &rpc->e_sources[rpc->cons_idx]; - rpc->cons_idx++; - if (rpc->cons_idx == AER_ERROR_SOURCES_MAX) - rpc->cons_idx = 0; - spin_unlock_irqrestore(&rpc->e_lock, flags); - - return e_source; -} - /** * get_device_error_info - read error status from dev and store it to info * @dev: pointer to the device expected to have a error record @@ -716,6 +690,34 @@ static void aer_isr_one_error(struct pcie_device *p_device, kfree(e_info); } +/** + * get_e_source - retrieve an error source + * @rpc: pointer to the root port which holds an error + * @e_src: pointer to store retrieved error source + * + * Return 1 if an error source is retrieved, otherwise 0. + * + * Invoked by DPC handler to consume an error. + */ +static int get_e_source(struct aer_rpc *rpc, struct aer_err_source *e_src) +{ + unsigned long flags; + int ret = 0; + + /* Lock access to Root error producer/consumer index */ + spin_lock_irqsave(&rpc->e_lock, flags); + if (rpc->prod_idx != rpc->cons_idx) { + *e_src = rpc->e_sources[rpc->cons_idx]; + rpc->cons_idx++; + if (rpc->cons_idx == AER_ERROR_SOURCES_MAX) + rpc->cons_idx = 0; + ret = 1; + } + spin_unlock_irqrestore(&rpc->e_lock, flags); + + return ret; +} + /** * aer_isr - consume errors detected by root port * @work: definition of this work item @@ -726,14 +728,11 @@ void aer_isr(struct work_struct *work) { struct aer_rpc *rpc = container_of(work, struct aer_rpc, dpc_handler); struct pcie_device *p_device = rpc->rpd; - struct aer_err_source *e_src; + struct aer_err_source e_src; mutex_lock(&rpc->rpc_mutex); - e_src = get_e_source(rpc); - while (e_src) { - aer_isr_one_error(p_device, e_src); - e_src = get_e_source(rpc); - } + while (get_e_source(rpc, &e_src)) + aer_isr_one_error(p_device, &e_src); mutex_unlock(&rpc->rpc_mutex); wake_up(&rpc->wait_release); -- cgit v1.2.3 From 17e21854bd59862f4ee47d1c7e828549f782711b Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Thu, 15 Apr 2010 13:16:52 +0900 Subject: PCI: aerdrv: rework do_recovery Move dev_printks for debug into do_recovery(). This allows do_recovery() to return void. Signed-off-by: Hidetoshi Seto Reviewed-by: Kenji Kaneshige Signed-off-by: Jesse Barnes --- drivers/pci/pcie/aer/aerdrv_core.c | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 210e53c2fdc1..9dcd3aeeafb6 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -465,8 +465,7 @@ static pci_ers_result_t reset_link(struct pcie_device *aerdev, * error detected message to all downstream drivers within a hierarchy in * question and return the returned code. */ -static pci_ers_result_t do_recovery(struct pcie_device *aerdev, - struct pci_dev *dev, +static void do_recovery(struct pcie_device *aerdev, struct pci_dev *dev, int severity) { pci_ers_result_t status, result = PCI_ERS_RESULT_RECOVERED; @@ -484,10 +483,8 @@ static pci_ers_result_t do_recovery(struct pcie_device *aerdev, if (severity == AER_FATAL) { result = reset_link(aerdev, dev); - if (result != PCI_ERS_RESULT_RECOVERED) { - /* TODO: Should panic here? */ - return result; - } + if (result != PCI_ERS_RESULT_RECOVERED) + goto failed; } if (status == PCI_ERS_RESULT_CAN_RECOVER) @@ -508,13 +505,22 @@ static pci_ers_result_t do_recovery(struct pcie_device *aerdev, report_slot_reset); } - if (status == PCI_ERS_RESULT_RECOVERED) - broadcast_error_message(dev, + if (status != PCI_ERS_RESULT_RECOVERED) + goto failed; + + broadcast_error_message(dev, state, "resume", report_resume); - return status; + dev_printk(KERN_DEBUG, &dev->dev, + "AER driver successfully recovered\n"); + return; + +failed: + /* TODO: Should kernel panic here? */ + dev_printk(KERN_DEBUG, &dev->dev, + "AER driver didn't recover\n"); } /** @@ -529,7 +535,6 @@ static void handle_error_source(struct pcie_device *aerdev, struct pci_dev *dev, struct aer_err_info *info) { - pci_ers_result_t status = 0; int pos; if (info->severity == AER_CORRECTABLE) { @@ -541,17 +546,8 @@ static void handle_error_source(struct pcie_device *aerdev, if (pos) pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, info->status); - } else { - status = do_recovery(aerdev, dev, info->severity); - if (status == PCI_ERS_RESULT_RECOVERED) { - dev_printk(KERN_DEBUG, &dev->dev, "AER driver " - "successfully recovered\n"); - } else { - /* TODO: Should kernel panic here? */ - dev_printk(KERN_DEBUG, &dev->dev, "AER driver didn't " - "recover\n"); - } - } + } else + do_recovery(aerdev, dev, info->severity); } /** -- cgit v1.2.3 From f647a44f5725b0e6c8211096f4b49900164123ee Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Thu, 15 Apr 2010 13:17:33 +0900 Subject: PCI: aerdrv: redefine PCI_ERR_ROOT_*_SRC The Error Source Identification Register (Offset 34h) is 4 byte which contains a couple of 2 byte field, "[15:0] ERR_COR Source Identification" and "[31:16] ERR_FATAL/NONFATAL Source Identification." This patch defines PCI_ERR_ROOT_ERR_SRC to make dword access sensible. Signed-off-by: Hidetoshi Seto Reviewed-by: Kenji Kaneshige Signed-off-by: Jesse Barnes --- drivers/pci/pcie/aer/aer_inject.c | 2 +- drivers/pci/pcie/aer/aerdrv.c | 2 +- include/linux/pci_regs.h | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c index f8f425b8731d..909924692b8a 100644 --- a/drivers/pci/pcie/aer/aer_inject.c +++ b/drivers/pci/pcie/aer/aer_inject.c @@ -168,7 +168,7 @@ static u32 *find_pci_config_dword(struct aer_error *err, int where, target = &err->root_status; rw1cs = 1; break; - case PCI_ERR_ROOT_COR_SRC: + case PCI_ERR_ROOT_ERR_SRC: target = &err->source_id; break; } diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index b69dbdc36817..1a55c16e2f3f 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c @@ -210,7 +210,7 @@ irqreturn_t aer_irq(int irq, void *context) } /* Read error source and clear error status */ - pci_read_config_dword(pdev->port, pos + PCI_ERR_ROOT_COR_SRC, &id); + pci_read_config_dword(pdev->port, pos + PCI_ERR_ROOT_ERR_SRC, &id); pci_write_config_dword(pdev->port, pos + PCI_ERR_ROOT_STATUS, status); /* Store error source for later DPC handler */ diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index c8f302991b66..dd0dd873f637 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h @@ -563,8 +563,7 @@ #define PCI_ERR_ROOT_FIRST_FATAL 0x00000010 /* First Fatal */ #define PCI_ERR_ROOT_NONFATAL_RCV 0x00000020 /* Non-Fatal Received */ #define PCI_ERR_ROOT_FATAL_RCV 0x00000040 /* Fatal Received */ -#define PCI_ERR_ROOT_COR_SRC 52 -#define PCI_ERR_ROOT_SRC 54 +#define PCI_ERR_ROOT_ERR_SRC 52 /* Error Source Identification */ /* Virtual Channel */ #define PCI_VC_PORT_REG1 4 -- cgit v1.2.3 From e167bfcaa4cd44b4c66206a3c06b2aafb3f1260e Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Thu, 15 Apr 2010 13:18:26 +0900 Subject: PCI: aerdrv: remove magical ROOT_ERR_STATUS_MASKS Make it clear that we only interest in 2 *_RCV bits. Signed-off-by: Hidetoshi Seto Reviewed-by: Kenji Kaneshige Signed-off-by: Jesse Barnes --- drivers/pci/pcie/aer/aerdrv.c | 2 +- drivers/pci/pcie/aer/aerdrv.h | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index 1a55c16e2f3f..cbc7cc77b2c3 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c @@ -204,7 +204,7 @@ irqreturn_t aer_irq(int irq, void *context) /* Read error status */ pci_read_config_dword(pdev->port, pos + PCI_ERR_ROOT_STATUS, &status); - if (!(status & ROOT_ERR_STATUS_MASKS)) { + if (!(status & (PCI_ERR_ROOT_UNCOR_RCV|PCI_ERR_ROOT_COR_RCV))) { spin_unlock_irqrestore(&rpc->e_lock, flags); return IRQ_NONE; } diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h index 2f345405e823..d0f8291c5ca0 100644 --- a/drivers/pci/pcie/aer/aerdrv.h +++ b/drivers/pci/pcie/aer/aerdrv.h @@ -17,9 +17,6 @@ #define AER_FATAL 1 #define AER_CORRECTABLE 2 -/* Root Error Status Register Bits */ -#define ROOT_ERR_STATUS_MASKS 0x0f - #define SYSTEM_ERROR_INTR_ON_MESG_MASK (PCI_EXP_RTCTL_SECEE| \ PCI_EXP_RTCTL_SENFEE| \ PCI_EXP_RTCTL_SEFEE) -- cgit v1.2.3 From 4f7ccf6a6085eefd2517b8c7090608c64b01ab67 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Thu, 15 Apr 2010 13:19:48 +0900 Subject: PCI: aerdrv: remove is_downstream The pcie->port of port service device points the port associated the service with. The find_aer_service iterates over children of given port udev. So it is clear that the pcie->port of port service of given port udev must always point the udev. Therefore we can know the type of udev without checking its children. Signed-off-by: Hidetoshi Seto Reviewed-by: Kenji Kaneshige Signed-off-by: Jesse Barnes --- drivers/pci/pcie/aer/aerdrv_core.c | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 9dcd3aeeafb6..8d458a03afc9 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -375,30 +375,20 @@ static pci_ers_result_t broadcast_error_message(struct pci_dev *dev, struct find_aer_service_data { struct pcie_port_service_driver *aer_driver; - int is_downstream; }; static int find_aer_service_iter(struct device *device, void *data) { - struct device_driver *driver; struct pcie_port_service_driver *service_driver; struct find_aer_service_data *result; result = (struct find_aer_service_data *) data; - if (device->bus == &pcie_port_bus_type) { - struct pcie_device *pcie = to_pcie_device(device); - - if (pcie->port->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) - result->is_downstream = 1; - - driver = device->driver; - if (driver) { - service_driver = to_service_driver(driver); - if (service_driver->service == PCIE_PORT_SERVICE_AER) { - result->aer_driver = service_driver; - return 1; - } + if (device->bus == &pcie_port_bus_type && device->driver) { + service_driver = to_service_driver(device->driver); + if (service_driver->service == PCIE_PORT_SERVICE_AER) { + result->aer_driver = service_driver; + return 1; } } @@ -424,7 +414,6 @@ static pci_ers_result_t reset_link(struct pcie_device *aerdev, else udev = dev->bus->self; - data.is_downstream = 0; data.aer_driver = NULL; find_aer_service(udev, &data); @@ -433,22 +422,24 @@ static pci_ers_result_t reset_link(struct pcie_device *aerdev, * If it hasn't the aer driver, use the root port's */ if (!data.aer_driver || !data.aer_driver->reset_link) { - if (data.is_downstream && + if (udev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM && aerdev->device.driver && to_service_driver(aerdev->device.driver)->reset_link) { data.aer_driver = to_service_driver(aerdev->device.driver); } else { - dev_printk(KERN_DEBUG, &dev->dev, "no link-reset " - "support\n"); + dev_printk(KERN_DEBUG, &dev->dev, + "no link-reset support at upstream device %s\n", + pci_name(udev)); return PCI_ERS_RESULT_DISCONNECT; } } status = data.aer_driver->reset_link(udev); if (status != PCI_ERS_RESULT_RECOVERED) { - dev_printk(KERN_DEBUG, &dev->dev, "link reset at upstream " - "device %s failed\n", pci_name(udev)); + dev_printk(KERN_DEBUG, &dev->dev, + "link reset at upstream device %s failed\n", + pci_name(udev)); return PCI_ERS_RESULT_DISCONNECT; } -- cgit v1.2.3 From 517cae3829ae8cc3033c24f60e64eb251b2f0d14 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Thu, 15 Apr 2010 13:20:43 +0900 Subject: PCI: aerdrv: rework find_aer_service The structure find_aer_service_data is no longer useful. Signed-off-by: Hidetoshi Seto Reviewed-by: Kenji Kaneshige Reviewed-by: Jin Dongming Signed-off-by: Jesse Barnes --- drivers/pci/pcie/aer/aerdrv_core.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 8d458a03afc9..8fb14aeb74dd 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -373,21 +373,16 @@ static pci_ers_result_t broadcast_error_message(struct pci_dev *dev, return result_data.result; } -struct find_aer_service_data { - struct pcie_port_service_driver *aer_driver; -}; - static int find_aer_service_iter(struct device *device, void *data) { - struct pcie_port_service_driver *service_driver; - struct find_aer_service_data *result; + struct pcie_port_service_driver *service_driver, **drv; - result = (struct find_aer_service_data *) data; + drv = (struct pcie_port_service_driver **) data; if (device->bus == &pcie_port_bus_type && device->driver) { service_driver = to_service_driver(device->driver); if (service_driver->service == PCIE_PORT_SERVICE_AER) { - result->aer_driver = service_driver; + *drv = service_driver; return 1; } } @@ -395,11 +390,13 @@ static int find_aer_service_iter(struct device *device, void *data) return 0; } -static void find_aer_service(struct pci_dev *dev, - struct find_aer_service_data *data) +static struct pcie_port_service_driver *find_aer_service(struct pci_dev *dev) { - int retval; - retval = device_for_each_child(&dev->dev, data, find_aer_service_iter); + struct pcie_port_service_driver *drv = NULL; + + device_for_each_child(&dev->dev, &drv, find_aer_service_iter); + + return drv; } static pci_ers_result_t reset_link(struct pcie_device *aerdev, @@ -407,26 +404,24 @@ static pci_ers_result_t reset_link(struct pcie_device *aerdev, { struct pci_dev *udev; pci_ers_result_t status; - struct find_aer_service_data data; + struct pcie_port_service_driver *driver; if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE) udev = dev; else udev = dev->bus->self; - data.aer_driver = NULL; - find_aer_service(udev, &data); + /* Use the aer driver of the component firstly */ + driver = find_aer_service(udev); /* - * Use the aer driver of the error agent firstly. - * If it hasn't the aer driver, use the root port's + * If it hasn't the driver and is downstream port, use the root port's */ - if (!data.aer_driver || !data.aer_driver->reset_link) { + if (!driver || !driver->reset_link) { if (udev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM && aerdev->device.driver && to_service_driver(aerdev->device.driver)->reset_link) { - data.aer_driver = - to_service_driver(aerdev->device.driver); + driver = to_service_driver(aerdev->device.driver); } else { dev_printk(KERN_DEBUG, &dev->dev, "no link-reset support at upstream device %s\n", @@ -435,7 +430,7 @@ static pci_ers_result_t reset_link(struct pcie_device *aerdev, } } - status = data.aer_driver->reset_link(udev); + status = driver->reset_link(udev); if (status != PCI_ERS_RESULT_RECOVERED) { dev_printk(KERN_DEBUG, &dev->dev, "link reset at upstream device %s failed\n", -- cgit v1.2.3 From 89713422a768458a0d375f0c2f3586cd5ccde6a1 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Thu, 15 Apr 2010 13:21:27 +0900 Subject: PCI: aerdrv: introduce default_downstream_reset_link I noticed that when I inject a fatal error to an endpoint via aer-inject, aer_root_reset() is called as reset_link for a downstream port at upstream of the endpoint: pcieport 0000:00:06.0: AER: Uncorrected (Fatal) error received: id=5401 : pcieport 0000:52:02.0: Root Port link has been reset It externally appears to be working, but internally issues some accesses to PCI_ERR_ROOT_COMMAND/STATUS registers that is for root port so not available on downstream port. This patch introduces default_downstream_reset_link that is a version of aer_root_reset() with no accesses to root port's register. It is used for downstream ports that has no reset_link function its specific. This patch also updates related description in pcieaer-howto.txt. Some minor fixes are included. Signed-off-by: Hidetoshi Seto Reviewed-by: Kenji Kaneshige Signed-off-by: Jesse Barnes --- Documentation/PCI/pcieaer-howto.txt | 15 +++---- drivers/pci/pcie/aer/aerdrv.c | 23 +---------- drivers/pci/pcie/aer/aerdrv.h | 1 + drivers/pci/pcie/aer/aerdrv_core.c | 78 +++++++++++++++++++++++++++++-------- 4 files changed, 71 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/Documentation/PCI/pcieaer-howto.txt b/Documentation/PCI/pcieaer-howto.txt index 8c406a496799..26d3d945c3c2 100644 --- a/Documentation/PCI/pcieaer-howto.txt +++ b/Documentation/PCI/pcieaer-howto.txt @@ -13,7 +13,7 @@ Reporting (AER) driver and provides information on how to use it, as well as how to enable the drivers of endpoint devices to conform with PCI Express AER driver. -1.2 Copyright © Intel Corporation 2006. +1.2 Copyright (C) Intel Corporation 2006. 1.3 What is the PCI Express AER Driver? @@ -108,7 +108,7 @@ but the PCI Express link itself is fully functional. Fatal errors, on the other hand, cause the link to be unreliable. When AER is enabled, a PCI Express device will automatically send an -error message to the PCIE root port above it when the device captures +error message to the PCIe root port above it when the device captures an error. The Root Port, upon receiving an error reporting message, internally processes and logs the error message in its PCI Express capability structure. Error information being logged includes storing @@ -194,8 +194,9 @@ to reset link, AER port service driver is required to provide the function to reset link. Firstly, kernel looks for if the upstream component has an aer driver. If it has, kernel uses the reset_link callback of the aer driver. If the upstream component has no aer driver -and the port is downstream port, we will use the aer driver of the -root port who reports the AER error. As for upstream ports, +and the port is downstream port, we will perform a hot reset as the +default by setting the Secondary Bus Reset bit of the Bridge Control +register associated with the downstream port. As for upstream ports, they should provide their own aer service drivers with reset_link function. If error_detected returns PCI_ERS_RESULT_CAN_RECOVER and reset_link returns PCI_ERS_RESULT_RECOVERED, the error handling goes @@ -249,11 +250,11 @@ cleanup uncorrectable status register. Pls. refer to section 3.3. 4. Software error injection -Debugging PCIE AER error recovery code is quite difficult because it +Debugging PCIe AER error recovery code is quite difficult because it is hard to trigger real hardware errors. Software based error -injection can be used to fake various kinds of PCIE errors. +injection can be used to fake various kinds of PCIe errors. -First you should enable PCIE AER software error injection in kernel +First you should enable PCIe AER software error injection in kernel configuration, that is, following item should be in your .config. CONFIG_PCIEAER_INJECT=y or CONFIG_PCIEAER_INJECT=m diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index cbc7cc77b2c3..a225d58c1ac8 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c @@ -341,7 +341,6 @@ static int __devinit aer_probe(struct pcie_device *dev) **/ static pci_ers_result_t aer_root_reset(struct pci_dev *dev) { - u16 p2p_ctrl; u32 reg32; int pos; @@ -352,27 +351,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev) reg32 &= ~ROOT_PORT_INTR_ON_MESG_MASK; pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, reg32); - /* Assert Secondary Bus Reset */ - pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &p2p_ctrl); - p2p_ctrl |= PCI_BRIDGE_CTL_BUS_RESET; - pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl); - - /* - * we should send hot reset message for 2ms to allow it time to - * propogate to all downstream ports - */ - msleep(2); - - /* De-assert Secondary Bus Reset */ - p2p_ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET; - pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl); - - /* - * System software must wait for at least 100ms from the end - * of a reset of one or more device before it is permitted - * to issue Configuration Requests to those devices. - */ - msleep(200); + aer_do_secondary_bus_reset(dev); dev_printk(KERN_DEBUG, &dev->dev, "Root Port link has been reset\n"); /* Clear Root Error Status */ diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h index d0f8291c5ca0..7aaae2d2bd67 100644 --- a/drivers/pci/pcie/aer/aerdrv.h +++ b/drivers/pci/pcie/aer/aerdrv.h @@ -114,6 +114,7 @@ static inline pci_ers_result_t merge_result(enum pci_ers_result orig, } extern struct bus_type pcie_port_bus_type; +extern void aer_do_secondary_bus_reset(struct pci_dev *dev); extern int aer_init(struct pcie_device *dev); extern void aer_isr(struct work_struct *work); extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 8fb14aeb74dd..ce42cac99dd3 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -373,6 +373,53 @@ static pci_ers_result_t broadcast_error_message(struct pci_dev *dev, return result_data.result; } +/** + * aer_do_secondary_bus_reset - perform secondary bus reset + * @dev: pointer to bridge's pci_dev data structure + * + * Invoked when performing link reset at Root Port or Downstream Port. + */ +void aer_do_secondary_bus_reset(struct pci_dev *dev) +{ + u16 p2p_ctrl; + + /* Assert Secondary Bus Reset */ + pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &p2p_ctrl); + p2p_ctrl |= PCI_BRIDGE_CTL_BUS_RESET; + pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl); + + /* + * we should send hot reset message for 2ms to allow it time to + * propagate to all downstream ports + */ + msleep(2); + + /* De-assert Secondary Bus Reset */ + p2p_ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET; + pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl); + + /* + * System software must wait for at least 100ms from the end + * of a reset of one or more device before it is permitted + * to issue Configuration Requests to those devices. + */ + msleep(200); +} + +/** + * default_downstream_reset_link - default reset function for Downstream Port + * @dev: pointer to downstream port's pci_dev data structure + * + * Invoked when performing link reset at Downstream Port w/ no aer driver. + */ +static pci_ers_result_t default_downstream_reset_link(struct pci_dev *dev) +{ + aer_do_secondary_bus_reset(dev); + dev_printk(KERN_DEBUG, &dev->dev, + "Downstream Port link has been reset\n"); + return PCI_ERS_RESULT_RECOVERED; +} + static int find_aer_service_iter(struct device *device, void *data) { struct pcie_port_service_driver *service_driver, **drv; @@ -406,31 +453,28 @@ static pci_ers_result_t reset_link(struct pcie_device *aerdev, pci_ers_result_t status; struct pcie_port_service_driver *driver; - if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE) + if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE) { + /* Reset this port for all subordinates */ udev = dev; - else + } else { + /* Reset the upstream component (likely downstream port) */ udev = dev->bus->self; + } /* Use the aer driver of the component firstly */ driver = find_aer_service(udev); - /* - * If it hasn't the driver and is downstream port, use the root port's - */ - if (!driver || !driver->reset_link) { - if (udev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM && - aerdev->device.driver && - to_service_driver(aerdev->device.driver)->reset_link) { - driver = to_service_driver(aerdev->device.driver); - } else { - dev_printk(KERN_DEBUG, &dev->dev, - "no link-reset support at upstream device %s\n", - pci_name(udev)); - return PCI_ERS_RESULT_DISCONNECT; - } + if (driver && driver->reset_link) { + status = driver->reset_link(udev); + } else if (udev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) { + status = default_downstream_reset_link(udev); + } else { + dev_printk(KERN_DEBUG, &dev->dev, + "no link-reset support at upstream device %s\n", + pci_name(udev)); + return PCI_ERS_RESULT_DISCONNECT; } - status = driver->reset_link(udev); if (status != PCI_ERS_RESULT_RECOVERED) { dev_printk(KERN_DEBUG, &dev->dev, "link reset at upstream device %s failed\n", -- cgit v1.2.3 From f6d3780061283039de33b402c35c3bf9322afe14 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Thu, 15 Apr 2010 13:22:11 +0900 Subject: PCI: aerdrv: trivial cleanup for aerdrv.c Skip zero-ing in aer_alloc_rpc() since it is allocated by kzalloc(). The closing comment marker "*/" is recommended for kernel-doc comments. Signed-off-by: Hidetoshi Seto Reviewed-by: Kenji Kaneshige Signed-off-by: Jesse Barnes --- drivers/pci/pcie/aer/aerdrv.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index a225d58c1ac8..484cc55194b8 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c @@ -185,7 +185,7 @@ static void aer_disable_rootport(struct aer_rpc *rpc) * @context: pointer to Root Port data structure * * Invoked when Root Port detects AER messages. - **/ + */ irqreturn_t aer_irq(int irq, void *context) { unsigned int status, id; @@ -242,7 +242,7 @@ EXPORT_SYMBOL_GPL(aer_irq); * @dev: pointer to the pcie_dev data structure * * Invoked when Root Port's AER service is loaded. - **/ + */ static struct aer_rpc *aer_alloc_rpc(struct pcie_device *dev) { struct aer_rpc *rpc; @@ -251,15 +251,11 @@ static struct aer_rpc *aer_alloc_rpc(struct pcie_device *dev) if (!rpc) return NULL; - /* - * Initialize Root lock access, e_lock, to Root Error Status Reg, - * Root Error ID Reg, and Root error producer/consumer index. - */ + /* Initialize Root lock access, e_lock, to Root Error Status Reg */ spin_lock_init(&rpc->e_lock); rpc->rpd = dev; INIT_WORK(&rpc->dpc_handler, aer_isr); - rpc->prod_idx = rpc->cons_idx = 0; mutex_init(&rpc->rpc_mutex); init_waitqueue_head(&rpc->wait_release); @@ -274,7 +270,7 @@ static struct aer_rpc *aer_alloc_rpc(struct pcie_device *dev) * @dev: pointer to the pcie_dev data structure * * Invoked when PCI Express bus unloads or AER probe fails. - **/ + */ static void aer_remove(struct pcie_device *dev) { struct aer_rpc *rpc = get_service_data(dev); @@ -298,7 +294,7 @@ static void aer_remove(struct pcie_device *dev) * @id: pointer to the service id data structure * * Invoked when PCI Express bus loads AER service driver. - **/ + */ static int __devinit aer_probe(struct pcie_device *dev) { int status; @@ -338,7 +334,7 @@ static int __devinit aer_probe(struct pcie_device *dev) * @dev: pointer to Root Port's pci_dev data structure * * Invoked by Port Bus driver when performing link reset at Root Port. - **/ + */ static pci_ers_result_t aer_root_reset(struct pci_dev *dev) { u32 reg32; @@ -372,7 +368,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev) * @error: error severity being notified by port bus * * Invoked by Port Bus driver during error recovery. - **/ + */ static pci_ers_result_t aer_error_detected(struct pci_dev *dev, enum pci_channel_state error) { @@ -385,7 +381,7 @@ static pci_ers_result_t aer_error_detected(struct pci_dev *dev, * @dev: pointer to Root Port's pci_dev data structure * * Invoked by Port Bus driver during nonfatal recovery. - **/ + */ static void aer_error_resume(struct pci_dev *dev) { int pos; @@ -412,7 +408,7 @@ static void aer_error_resume(struct pci_dev *dev) * aer_service_init - register AER root service driver * * Invoked when AER root service driver is loaded. - **/ + */ static int __init aer_service_init(void) { if (pcie_aer_disable) @@ -426,7 +422,7 @@ static int __init aer_service_init(void) * aer_service_exit - unregister AER root service driver * * Invoked when AER root service driver is unloaded. - **/ + */ static void __exit aer_service_exit(void) { pcie_port_service_unregister(&aerdriver); -- cgit v1.2.3 From caa5afbd4831c649b951ae1227a7985f47547e31 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Thu, 15 Apr 2010 13:23:17 +0900 Subject: PCI: aerdrv: trivial cleanup for aerdrv_core.c Style cleanup for pci_{en,dis}able_pcie_error_reporting(). Signed-off-by: Hidetoshi Seto Reviewed-by: Kenji Kaneshige Signed-off-by: Jesse Barnes --- drivers/pci/pcie/aer/aerdrv_core.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index ce42cac99dd3..df2d686fe3dd 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -47,13 +47,12 @@ int pci_enable_pcie_error_reporting(struct pci_dev *dev) if (!pos) return -EIO; - pci_read_config_word(dev, pos+PCI_EXP_DEVCTL, ®16); - reg16 = reg16 | - PCI_EXP_DEVCTL_CERE | + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, ®16); + reg16 |= (PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | PCI_EXP_DEVCTL_FERE | - PCI_EXP_DEVCTL_URRE; - pci_write_config_word(dev, pos+PCI_EXP_DEVCTL, reg16); + PCI_EXP_DEVCTL_URRE); + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16); return 0; } @@ -71,12 +70,12 @@ int pci_disable_pcie_error_reporting(struct pci_dev *dev) if (!pos) return -EIO; - pci_read_config_word(dev, pos+PCI_EXP_DEVCTL, ®16); - reg16 = reg16 & ~(PCI_EXP_DEVCTL_CERE | - PCI_EXP_DEVCTL_NFERE | - PCI_EXP_DEVCTL_FERE | - PCI_EXP_DEVCTL_URRE); - pci_write_config_word(dev, pos+PCI_EXP_DEVCTL, reg16); + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, ®16); + reg16 &= ~(PCI_EXP_DEVCTL_CERE | + PCI_EXP_DEVCTL_NFERE | + PCI_EXP_DEVCTL_FERE | + PCI_EXP_DEVCTL_URRE); + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16); return 0; } -- cgit v1.2.3 From adaaa0c6ab89e82684389b80002bce893179cf2c Mon Sep 17 00:00:00 2001 From: Linus Lüssing Date: Fri, 7 May 2010 21:47:06 +0200 Subject: Staging: batman-adv: only modify hna-table on active module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we haven't set the module to MODULE_ACTIVE state before (in general, no interface has yet been added to batman-adv) then the hna table is not initialised yet. If the kernel changes the mac address of the bat0 interface at this moment then an hna_local_add() called by interface_set_mac_addr() then resulted in a null pointer derefernce. With this patch we are now explicitly checking before if the state is MODULE_ACTIVE right now so that we can assume having an initialised hna table. Signed-off-by: Linus Lüssing Signed-off-by: Marek Lindner Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/soft-interface.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 0e2307f3cb96..a42b21f40192 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -152,9 +152,13 @@ int interface_set_mac_addr(struct net_device *dev, void *p) if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; - hna_local_remove(dev->dev_addr, "mac address changed"); + /* only modify hna-table if it has been initialised before */ + if (atomic_read(&module_state) == MODULE_ACTIVE) { + hna_local_remove(dev->dev_addr, "mac address changed"); + hna_local_add(addr->sa_data); + } + memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); - hna_local_add(dev->dev_addr); return 0; } -- cgit v1.2.3 From f347b8736f176681fbfc666bf00165125a3274a5 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Fri, 7 May 2010 21:47:07 +0200 Subject: Staging: batman-adv: Clone shared bat packets before modifying them "tcpdump" and "batctl td" will receive packets with a wrong sequence number on systems with a different endianess than network byte order. This happens due to the reordering of bytes in the function which handles aggregated bat packets. The function which receives the bat packets must ensure that these buffers aren't shared with anything else before that function tries to write into it. Otherwise it has to copy the buffers so it is save again to change them. Reported-by: Kevin Steen Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/routing.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index d89048beebe1..39dd093d7f2d 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -549,6 +549,7 @@ int recv_bat_packet(struct sk_buff *skb, { struct ethhdr *ethhdr; unsigned long flags; + struct sk_buff *skb_old; /* drop packet if it has not necessary minimum size */ if (skb_headlen(skb) < sizeof(struct batman_packet)) @@ -564,12 +565,19 @@ int recv_bat_packet(struct sk_buff *skb, if (is_bcast(ethhdr->h_source)) return NET_RX_DROP; - spin_lock_irqsave(&orig_hash_lock, flags); /* TODO: we use headlen instead of "length", because * only this data is paged in. */ - /* TODO: is another skb_copy needed here? there will be - * written on the data, but nobody (?) should further use - * this data */ + + /* create a copy of the skb, if needed, to modify it. */ + if (!skb_clone_writable(skb, skb_headlen(skb))) { + skb_old = skb; + skb = skb_copy(skb, GFP_ATOMIC); + if (!skb) + return NET_RX_DROP; + kfree_skb(skb_old); + } + + spin_lock_irqsave(&orig_hash_lock, flags); receive_aggr_bat_packet(ethhdr, skb->data, skb_headlen(skb), -- cgit v1.2.3 From bd13b616aa9d082dce760759b7473da5ed399452 Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Fri, 7 May 2010 21:47:08 +0200 Subject: Staging: batman-adv: fix aggregation timing bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit batman-adv aggregates routing packets to reduce the number of packets in the air. Every outgoing packet is compared with other packets in the buffer to determine whether it can be aggregated or not. Packets sent at a lower interval can be held back longer to maximize the aggregation. Due to insufficient checking batman-adv held back all packets for a certain time depending on its own lowest interval rate which slowed down all other nodes. Reported-by: Linus Lüssing Signed-off-by: Marek Lindner Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/aggregation.c | 12 ++++++++++++ drivers/staging/batman-adv/send.c | 10 +--------- 2 files changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c index 7917322a7e2a..d25e5a89dac3 100644 --- a/drivers/staging/batman-adv/aggregation.c +++ b/drivers/staging/batman-adv/aggregation.c @@ -52,6 +52,8 @@ static bool can_aggregate_with(struct batman_packet *new_batman_packet, */ if (time_before(send_time, forw_packet->send_time) && + time_after_eq(send_time + msecs_to_jiffies(MAX_AGGREGATION_MS), + forw_packet->send_time) && (aggregated_bytes <= MAX_AGGREGATION_BYTES)) { /** @@ -195,6 +197,16 @@ void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len, if (forw_packet_aggr == NULL) { /* the following section can run without the lock */ spin_unlock_irqrestore(&forw_bat_list_lock, flags); + + /** + * if we could not aggregate this packet with one of the others + * we hold it back for a while, so that it might be aggregated + * later on + */ + if ((!own_packet) && + (atomic_read(&bat_priv->aggregation_enabled))) + send_time += msecs_to_jiffies(MAX_AGGREGATION_MS); + new_aggregated_packet(packet_buff, packet_len, send_time, direct_link, if_incoming, own_packet); diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index ff7b1f10684f..d356ce7644a3 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -46,15 +46,7 @@ static unsigned long own_send_time(void) /* when do we schedule a forwarded packet to be sent */ static unsigned long forward_send_time(void) { - unsigned long send_time = jiffies; /* Starting now plus... */ - - if (atomic_read(&aggregation_enabled)) - send_time += (((MAX_AGGREGATION_MS - (JITTER/2) + - (random32() % JITTER)) * HZ) / 1000); - else - send_time += (((random32() % (JITTER/2)) * HZ) / 1000); - - return send_time; + return jiffies + (((random32() % (JITTER/2)) * HZ) / 1000); } /* send out an already prepared packet to the given address via the -- cgit v1.2.3 From bdc0c7ebf770e21d024c2e94c3d578392b59c5b1 Mon Sep 17 00:00:00 2001 From: Linus Lüssing Date: Fri, 7 May 2010 21:47:09 +0200 Subject: Staging: batman-adv: Fix aggregation direct-link bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So far, neighbour's secondary interface OGMs can involuntarily piggyback on primary interface OGMs that arrived on the same secondary interface before. Secondary interface OGMs should NEVER leave their direct neighbour broadcast domain! This patch ensures that secondary interface OGMs can only be aggregated to other secondary interface OGMs. Signed-off-by: Linus Lüssing Signed-off-by: Marek Lindner Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/aggregation.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c index d25e5a89dac3..e1bd32185439 100644 --- a/drivers/staging/batman-adv/aggregation.c +++ b/drivers/staging/batman-adv/aggregation.c @@ -81,9 +81,15 @@ static bool can_aggregate_with(struct batman_packet *new_batman_packet, * interface only - we still can aggregate */ if ((directlink) && (new_batman_packet->ttl == 1) && - (forw_packet->if_incoming == if_incoming)) + (forw_packet->if_incoming == if_incoming) && + + /* packets from direct neighbors or + * own secondary interface packets + * (= secondary interface packets in general) */ + (batman_packet->flags & DIRECTLINK || + (forw_packet->own && + forw_packet->if_incoming->if_num != 0))) return true; - } return false; @@ -204,7 +210,7 @@ void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len, * later on */ if ((!own_packet) && - (atomic_read(&bat_priv->aggregation_enabled))) + (atomic_read(&aggregation_enabled))) send_time += msecs_to_jiffies(MAX_AGGREGATION_MS); new_aggregated_packet(packet_buff, packet_len, -- cgit v1.2.3 From 9b6d10b729276a27d7bd4ee364e6da1c1ce6c5c2 Mon Sep 17 00:00:00 2001 From: Simon Wunderlich Date: Fri, 7 May 2010 21:47:10 +0200 Subject: Staging: batman-adv: Update copyright years Signed-off-by: Simon Wunderlich Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/Makefile | 2 +- drivers/staging/batman-adv/aggregation.c | 2 +- drivers/staging/batman-adv/aggregation.h | 2 +- drivers/staging/batman-adv/bitarray.c | 2 +- drivers/staging/batman-adv/bitarray.h | 2 +- drivers/staging/batman-adv/device.c | 2 +- drivers/staging/batman-adv/device.h | 2 +- drivers/staging/batman-adv/hard-interface.c | 2 +- drivers/staging/batman-adv/hard-interface.h | 2 +- drivers/staging/batman-adv/hash.c | 2 +- drivers/staging/batman-adv/hash.h | 2 +- drivers/staging/batman-adv/main.c | 2 +- drivers/staging/batman-adv/main.h | 2 +- drivers/staging/batman-adv/originator.c | 2 +- drivers/staging/batman-adv/originator.h | 2 +- drivers/staging/batman-adv/packet.h | 2 +- drivers/staging/batman-adv/proc.c | 2 +- drivers/staging/batman-adv/proc.h | 2 +- drivers/staging/batman-adv/ring_buffer.c | 2 +- drivers/staging/batman-adv/ring_buffer.h | 2 +- drivers/staging/batman-adv/routing.c | 2 +- drivers/staging/batman-adv/routing.h | 2 +- drivers/staging/batman-adv/send.c | 2 +- drivers/staging/batman-adv/send.h | 2 +- drivers/staging/batman-adv/soft-interface.c | 2 +- drivers/staging/batman-adv/soft-interface.h | 2 +- drivers/staging/batman-adv/translation-table.c | 2 +- drivers/staging/batman-adv/translation-table.h | 2 +- drivers/staging/batman-adv/types.h | 2 +- drivers/staging/batman-adv/vis.c | 2 +- drivers/staging/batman-adv/vis.h | 2 +- 31 files changed, 31 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/Makefile b/drivers/staging/batman-adv/Makefile index 42b4e6370263..cf2915de0624 100644 --- a/drivers/staging/batman-adv/Makefile +++ b/drivers/staging/batman-adv/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: +# Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: # # Marek Lindner, Simon Wunderlich # diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c index e1bd32185439..b8338ce23c84 100644 --- a/drivers/staging/batman-adv/aggregation.c +++ b/drivers/staging/batman-adv/aggregation.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/aggregation.h b/drivers/staging/batman-adv/aggregation.h index 6da8df9f99b7..bcd32c1d69e0 100644 --- a/drivers/staging/batman-adv/aggregation.h +++ b/drivers/staging/batman-adv/aggregation.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/bitarray.c b/drivers/staging/batman-adv/bitarray.c index 212eef93afe4..7848305bd14b 100644 --- a/drivers/staging/batman-adv/bitarray.c +++ b/drivers/staging/batman-adv/bitarray.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: * * Simon Wunderlich, Marek Lindner * diff --git a/drivers/staging/batman-adv/bitarray.h b/drivers/staging/batman-adv/bitarray.h index ec72dd784362..76ad24c9f3de 100644 --- a/drivers/staging/batman-adv/bitarray.h +++ b/drivers/staging/batman-adv/bitarray.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: * * Simon Wunderlich, Marek Lindner * diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c index 2f61500186f2..c82a5afe8fa8 100644 --- a/drivers/staging/batman-adv/device.c +++ b/drivers/staging/batman-adv/device.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner * diff --git a/drivers/staging/batman-adv/device.h b/drivers/staging/batman-adv/device.h index 46c0f4496527..eb14b371cea9 100644 --- a/drivers/staging/batman-adv/device.h +++ b/drivers/staging/batman-adv/device.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner * diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c index befd48839519..cb9e9272a797 100644 --- a/drivers/staging/batman-adv/hard-interface.c +++ b/drivers/staging/batman-adv/hard-interface.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/hard-interface.h b/drivers/staging/batman-adv/hard-interface.h index 97c6ecb9e087..4100a276c498 100644 --- a/drivers/staging/batman-adv/hard-interface.h +++ b/drivers/staging/batman-adv/hard-interface.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/hash.c b/drivers/staging/batman-adv/hash.c index 5a2018de3ff2..d4a4adc57042 100644 --- a/drivers/staging/batman-adv/hash.c +++ b/drivers/staging/batman-adv/hash.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: * * Simon Wunderlich, Marek Lindner * diff --git a/drivers/staging/batman-adv/hash.h b/drivers/staging/batman-adv/hash.h index a70d6d6e1c7a..ea6d21e01251 100644 --- a/drivers/staging/batman-adv/hash.h +++ b/drivers/staging/batman-adv/hash.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: * * Simon Wunderlich, Marek Lindner * diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index 2e0b482e710a..a051568efff6 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 2e9bb891a5de..c943e89f78ec 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 29c241119a3b..2ce134995464 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/originator.h b/drivers/staging/batman-adv/originator.h index 6ef7a054a0a9..8acebc1e70eb 100644 --- a/drivers/staging/batman-adv/originator.h +++ b/drivers/staging/batman-adv/originator.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/packet.h b/drivers/staging/batman-adv/packet.h index ad006ce8b131..152f57b1c6c5 100644 --- a/drivers/staging/batman-adv/packet.h +++ b/drivers/staging/batman-adv/packet.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/proc.c b/drivers/staging/batman-adv/proc.c index c9366bcbb360..dfa85c49437f 100644 --- a/drivers/staging/batman-adv/proc.c +++ b/drivers/staging/batman-adv/proc.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/proc.h b/drivers/staging/batman-adv/proc.h index cd690e0f3e44..cf712648ca56 100644 --- a/drivers/staging/batman-adv/proc.h +++ b/drivers/staging/batman-adv/proc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/ring_buffer.c b/drivers/staging/batman-adv/ring_buffer.c index 751c899f54c5..defd37c9be1f 100644 --- a/drivers/staging/batman-adv/ring_buffer.c +++ b/drivers/staging/batman-adv/ring_buffer.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner * diff --git a/drivers/staging/batman-adv/ring_buffer.h b/drivers/staging/batman-adv/ring_buffer.h index 6839ba97eeb3..b8c9456558bc 100644 --- a/drivers/staging/batman-adv/ring_buffer.h +++ b/drivers/staging/batman-adv/ring_buffer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner * diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 39dd093d7f2d..b83e5cb2f94d 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/routing.h b/drivers/staging/batman-adv/routing.h index 939b8d4f733c..8288decea370 100644 --- a/drivers/staging/batman-adv/routing.h +++ b/drivers/staging/batman-adv/routing.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index d356ce7644a3..88ecb5c76c22 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/send.h b/drivers/staging/batman-adv/send.h index 5fc6f3417cb6..b2ddf631fb58 100644 --- a/drivers/staging/batman-adv/send.h +++ b/drivers/staging/batman-adv/send.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index a42b21f40192..0dff959050bf 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/soft-interface.h b/drivers/staging/batman-adv/soft-interface.h index c0cad8134b2b..e7f59af7df33 100644 --- a/drivers/staging/batman-adv/soft-interface.h +++ b/drivers/staging/batman-adv/soft-interface.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner * diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c index d56f6654de0d..e446d907a72a 100644 --- a/drivers/staging/batman-adv/translation-table.c +++ b/drivers/staging/batman-adv/translation-table.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/translation-table.h b/drivers/staging/batman-adv/translation-table.h index 281125b729fb..8568d80df361 100644 --- a/drivers/staging/batman-adv/translation-table.h +++ b/drivers/staging/batman-adv/translation-table.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index dec1b54031b6..4e77141078f9 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index 28eac7e05235..0bfc083a4234 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2008-2010 B.A.T.M.A.N. contributors: * * Simon Wunderlich * diff --git a/drivers/staging/batman-adv/vis.h b/drivers/staging/batman-adv/vis.h index a1f92a4b101d..98d89723160c 100644 --- a/drivers/staging/batman-adv/vis.h +++ b/drivers/staging/batman-adv/vis.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2008-2010 B.A.T.M.A.N. contributors: * * Simon Wunderlich, Marek Lindner * -- cgit v1.2.3 From b7473a38b6de6b5eda0ddbb08220f68064b47e06 Mon Sep 17 00:00:00 2001 From: Simon Wunderlich Date: Fri, 7 May 2010 21:47:11 +0200 Subject: Staging: batman-adv: remove the beta from main.h for release Signed-off-by: Simon Wunderlich Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index c943e89f78ec..5fdf5afd8202 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -26,7 +26,7 @@ #define DRIVER_DESC "B.A.T.M.A.N. advanced" #define DRIVER_DEVICE "batman-adv" -#define SOURCE_VERSION "0.2.1-beta" +#define SOURCE_VERSION "0.2.1" /* B.A.T.M.A.N. parameters */ -- cgit v1.2.3 From 76cb4e20610a1de80fa303aaf5507a8393f927de Mon Sep 17 00:00:00 2001 From: Linus Lüssing Date: Fri, 7 May 2010 21:47:12 +0200 Subject: Staging: batman-adv: Remove dead max addr and obsolete VIS_FORMAT strings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Max address is not being used anywhere and just misleading, therefore removing it. VIS_FORMAT string is now obsolete, so also remove it. Signed-off-by: Linus Lüssing Signed-off-by: Simon Wunderlich Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/main.h | 2 -- drivers/staging/batman-adv/vis.h | 2 -- 2 files changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 5fdf5afd8202..2494f5a97ad8 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -34,8 +34,6 @@ #define TQ_MAX_VALUE 255 #define JITTER 20 #define TTL 50 /* Time To Live of broadcast messages */ -#define MAX_ADDR 16 /* number of interfaces which can be added to - * batman. */ #define PURGE_TIMEOUT 200000 /* purge originators after time in ms if no * valid packet comes in -> TODO: check diff --git a/drivers/staging/batman-adv/vis.h b/drivers/staging/batman-adv/vis.h index 98d89723160c..4e417fb17b94 100644 --- a/drivers/staging/batman-adv/vis.h +++ b/drivers/staging/batman-adv/vis.h @@ -20,8 +20,6 @@ */ #define VIS_TIMEOUT 200000 -#define VIS_FORMAT_DD_NAME "dot_draw" -#define VIS_FORMAT_JSON_NAME "json" struct vis_info { unsigned long first_seen; -- cgit v1.2.3 From 7742361422e5ae58e0400cf79758aefe96da51e1 Mon Sep 17 00:00:00 2001 From: Simon Wunderlich Date: Fri, 7 May 2010 21:47:13 +0200 Subject: Staging: batman-adv: Add 0.2.1 changes to the CHANGELOG Signed-off-by: Simon Wunderlich Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/CHANGELOG | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/CHANGELOG b/drivers/staging/batman-adv/CHANGELOG index 8a181639ceaa..c8f9d9e06bb4 100644 --- a/drivers/staging/batman-adv/CHANGELOG +++ b/drivers/staging/batman-adv/CHANGELOG @@ -1,3 +1,17 @@ +batman-adv 0.2.1: + +* support latest kernels (2.6.20 - 2.6.33) +* receive packets directly using skbs, remove old sockets and threads +* fix various regressions in the vis server +* don't disable interrupts while sending +* replace internal logging mechanism with standard kernel logging +* move vis formats into userland, one general format remains in the kernel +* allow MAC address to be set, correctly initialize them +* code refactoring and cleaning for coding style +* many bugs (null pointers, locking, hash iterators) squashed + + -- Sun, 21 Mar 2010 20:46:47 +0100 + batman-adv 0.2: * support latest kernels (2.6.20 - 2.6.31) -- cgit v1.2.3 From 43fb98fb2125dbf49f66e7ead31885311c670d14 Mon Sep 17 00:00:00 2001 From: Linus Lüssing Date: Fri, 7 May 2010 21:47:14 +0200 Subject: Staging: batman-adv: Update README about vis raw output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We are now having a newer, more neutral vis output so that we won't have to change the kernelmodule for adding support of new vis output formats. This patch adds an explanation about this in the README file of batman-adv and removes the description about the dot/json format (they will be added to the README of batctl). Signed-off-by: Linus Lüssing Signed-off-by: Simon Wunderlich Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/README | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/README b/drivers/staging/batman-adv/README index 7d666ad04359..e2a72718f3f7 100644 --- a/drivers/staging/batman-adv/README +++ b/drivers/staging/batman-adv/README @@ -1,4 +1,4 @@ -[state: 06-01-2010] +[state: 22-03-2010] BATMAN-ADV ---------- @@ -44,10 +44,11 @@ regular interface: # ping 192.168.0.2 ... +--- If you want topology visualization, your meshnode must be configured as VIS-server: -# echo "server" > /proc/net/batman-adv/vis +# echo "server" > /proc/net/batman-adv/vis_server Each node is either configured as "server" or as "client" (default: "client"). Clients send their topology data to the server next to them, @@ -58,12 +59,31 @@ more vis servers sharing the same (or at least very similar) data. When configured as server, you can get a topology snapshot of your mesh: -# cat /proc/net/batman-adv/vis - -The output is in a generic raw format. Use the batctl tool (See below) -to convert this to other formats more suitable for graphing, eg -graphviz dot, or JSON data-interchange format. - +# cat /proc/net/batman-adv/vis_data + +This raw output is intended to be easily parsable and convertable with +other tools. Have a look at the batctl README if you want a vis output +in dot or json format for instance and how those outputs could then be +visualised in an image. + +The raw format consists of comma seperated values per entry where each +entry is giving information about a certain source interface. Each entry +can/has to have the following values: +-> "mac" -> mac address of an originator's source interface + (each line begins with it) +-> "TQ mac value" -> src mac's link quality towards mac address of a neighbor + originator's interface which is being used for routing +-> "HNA mac" -> HNA announced by source mac +-> "PRIMARY" -> this is a primary interface +-> "SEC mac" -> secondary mac address of source (requires preceeding +-> PRIMARY) + +The TQ value has a range from 4 to 255 with 255 being the best. +The HNA entries are showing which hosts are connected to the mesh via bat0 +or being bridged into the mesh network. +The PRIMARY/SEC values are only applied on primary interfaces + +--- In very mobile scenarios, you might want to adjust the originator interval to a lower value. This will make the mesh more responsive to topology changes, but will also increase the overhead. Please make sure -- cgit v1.2.3 From 56c341d7af78f6766238725f79a1773aca942795 Mon Sep 17 00:00:00 2001 From: Simon Wunderlich Date: Fri, 7 May 2010 21:47:15 +0200 Subject: Staging: batman-adv: Changing version to 0.2.2-beta Signed-off-by: Simon Wunderlich Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 2494f5a97ad8..6221b859387f 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -26,7 +26,7 @@ #define DRIVER_DESC "B.A.T.M.A.N. advanced" #define DRIVER_DEVICE "batman-adv" -#define SOURCE_VERSION "0.2.1" +#define SOURCE_VERSION "0.2.2-beta" /* B.A.T.M.A.N. parameters */ -- cgit v1.2.3 From db315014ff8148e73d10e927d14c962d2cabd370 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 7 May 2010 21:47:16 +0200 Subject: Staging: batman-adv: cleanup: change test for end of array The code here is testing to see if "i" is passed the end of the array. The original code works probably, but it's not the cleanest way. Andrew Lunn suggested that I also remove all the hard coded references to 256 so I have done that as well. Signed-off-by: Dan Carpenter Signed-off-by: Marek Lindner Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/device.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c index c82a5afe8fa8..fbfe234104d2 100644 --- a/drivers/staging/batman-adv/device.c +++ b/drivers/staging/batman-adv/device.c @@ -44,10 +44,7 @@ static struct device_client *device_client_hash[256]; void bat_device_init(void) { - int i; - - for (i = 0; i < 256; i++) - device_client_hash[i] = NULL; + memset(device_client_hash, 0, sizeof(device_client_hash)); } int bat_device_setup(void) @@ -103,15 +100,15 @@ int bat_device_open(struct inode *inode, struct file *file) if (!device_client) return -ENOMEM; - for (i = 0; i < 256; i++) { + for (i = 0; i < ARRAY_SIZE(device_client_hash); i++) { if (!device_client_hash[i]) { device_client_hash[i] = device_client; break; } } - if (device_client_hash[i] != device_client) { - printk(KERN_ERR "batman-adv:Error - can't add another packet client: maximum number of clients reached \n"); + if (i == ARRAY_SIZE(device_client_hash)) { + printk(KERN_ERR "batman-adv:Error - can't add another packet client: maximum number of clients reached\n"); kfree(device_client); return -EXFULL; } -- cgit v1.2.3 From 0887635b26e0cb6369c0438e55d9323d3aef3f69 Mon Sep 17 00:00:00 2001 From: Luis de Bethencourt Date: Fri, 7 May 2010 21:47:17 +0200 Subject: Staging: batman-adv: fix whitespace style issues This patch fixes the 31 unnecessary whitespaces before a quoted newline that the batman-adv files had. Signed-off-by: Luis de Bethencourt [sven.eckelmann@gmx.de: Redone to apply against current version] Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/device.c | 2 +- drivers/staging/batman-adv/main.c | 2 +- drivers/staging/batman-adv/originator.c | 4 ++-- drivers/staging/batman-adv/routing.c | 18 +++++++++--------- drivers/staging/batman-adv/send.c | 4 ++-- drivers/staging/batman-adv/translation-table.c | 14 +++++++------- 6 files changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c index fbfe234104d2..9887f05925e1 100644 --- a/drivers/staging/batman-adv/device.c +++ b/drivers/staging/batman-adv/device.c @@ -65,7 +65,7 @@ int bat_device_setup(void) batman_class = class_create(THIS_MODULE, "batman-adv"); if (IS_ERR(batman_class)) { - printk(KERN_ERR "batman-adv:Could not register class 'batman-adv' \n"); + printk(KERN_ERR "batman-adv:Could not register class 'batman-adv'\n"); return 0; } diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index a051568efff6..881aaa9811a8 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -119,7 +119,7 @@ int init_module(void) register_netdevice_notifier(&hard_if_notifier); dev_add_pack(&batman_adv_packet_type); - printk(KERN_INFO "batman-adv:B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded \n", + printk(KERN_INFO "batman-adv:B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded\n", SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION); return 0; diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 2ce134995464..f3d8cc33011b 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -126,7 +126,7 @@ struct orig_node *get_orig_node(uint8_t *addr) if (orig_node != NULL) return orig_node; - bat_dbg(DBG_BATMAN, "Creating new originator: %pM \n", addr); + bat_dbg(DBG_BATMAN, "Creating new originator: %pM\n", addr); orig_node = kzalloc(sizeof(struct orig_node), GFP_ATOMIC); if (!orig_node) @@ -158,7 +158,7 @@ struct orig_node *get_orig_node(uint8_t *addr) if (swaphash == NULL) printk(KERN_ERR - "batman-adv:Couldn't resize orig hash table \n"); + "batman-adv:Couldn't resize orig hash table\n"); else orig_hash = swaphash; } diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index b83e5cb2f94d..a78ae5c4dcb0 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -212,7 +212,7 @@ static int isBidirectionalNeigh(struct orig_node *orig_node, orig_neigh_node->tq_asym_penalty) / (TQ_MAX_VALUE * TQ_MAX_VALUE)); - bat_dbg(DBG_BATMAN, "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i \n", + bat_dbg(DBG_BATMAN, "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i\n", orig_node->orig, orig_neigh_node->orig, total_count, neigh_node->real_packet_count, orig_neigh_node->tq_own, orig_neigh_node->tq_asym_penalty, batman_packet->tq); @@ -234,7 +234,7 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; int tmp_hna_buff_len; - bat_dbg(DBG_BATMAN, "update_originator(): Searching and updating originator entry of received packet \n"); + bat_dbg(DBG_BATMAN, "update_originator(): Searching and updating originator entry of received packet\n"); list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && @@ -341,7 +341,7 @@ static char count_real_packets(struct ethhdr *ethhdr, } if (!is_duplicate) { - bat_dbg(DBG_BATMAN, "updating last_seqno: old %d, new %d \n", + bat_dbg(DBG_BATMAN, "updating last_seqno: old %d, new %d\n", orig_node->last_real_seqno, batman_packet->seqno); orig_node->last_real_seqno = batman_packet->seqno; } @@ -385,7 +385,7 @@ void receive_bat_packet(struct ethhdr *ethhdr, is_single_hop_neigh = (compare_orig(ethhdr->h_source, batman_packet->orig) ? 1 : 0); - bat_dbg(DBG_BATMAN, "Received BATMAN packet via NB: %pM, IF: %s [%s] (from OG: %pM, via prev OG: %pM, seqno %d, tq %d, TTL %d, V %d, IDF %d) \n", + bat_dbg(DBG_BATMAN, "Received BATMAN packet via NB: %pM, IF: %s [%s] (from OG: %pM, via prev OG: %pM, seqno %d, tq %d, TTL %d, V %d, IDF %d)\n", ethhdr->h_source, if_incoming->dev, if_incoming->addr_str, batman_packet->orig, batman_packet->prev_sender, batman_packet->seqno, batman_packet->tq, batman_packet->ttl, @@ -426,7 +426,7 @@ void receive_bat_packet(struct ethhdr *ethhdr, } if (is_broadcast) { - bat_dbg(DBG_BATMAN, "Drop packet: ignoring all packets with broadcast source addr (sender: %pM) \n", ethhdr->h_source); + bat_dbg(DBG_BATMAN, "Drop packet: ignoring all packets with broadcast source addr (sender: %pM)\n", ethhdr->h_source); return; } @@ -454,19 +454,19 @@ void receive_bat_packet(struct ethhdr *ethhdr, bit_packet_count(word); } - bat_dbg(DBG_BATMAN, "Drop packet: originator packet from myself (via neighbor) \n"); + bat_dbg(DBG_BATMAN, "Drop packet: originator packet from myself (via neighbor)\n"); return; } if (batman_packet->tq == 0) { count_real_packets(ethhdr, batman_packet, if_incoming); - bat_dbg(DBG_BATMAN, "Drop packet: originator packet with tq equal 0 \n"); + bat_dbg(DBG_BATMAN, "Drop packet: originator packet with tq equal 0\n"); return; } if (is_my_oldorig) { - bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast echos (sender: %pM) \n", ethhdr->h_source); + bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast echos (sender: %pM)\n", ethhdr->h_source); return; } @@ -484,7 +484,7 @@ void receive_bat_packet(struct ethhdr *ethhdr, !(compare_orig(batman_packet->orig, batman_packet->prev_sender)) && (compare_orig(orig_node->router->addr, orig_node->router->orig_node->router->addr))) { - bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM) \n", ethhdr->h_source); + bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM)\n", ethhdr->h_source); return; } diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index 88ecb5c76c22..29b684ba4eab 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -290,7 +290,7 @@ void schedule_forward_packet(struct orig_node *orig_node, unsigned long send_time; if (batman_packet->ttl <= 1) { - bat_dbg(DBG_BATMAN, "ttl exceeded \n"); + bat_dbg(DBG_BATMAN, "ttl exceeded\n"); return; } @@ -318,7 +318,7 @@ void schedule_forward_packet(struct orig_node *orig_node, /* apply hop penalty */ batman_packet->tq = hop_penalty(batman_packet->tq); - bat_dbg(DBG_BATMAN, "Forwarding packet: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i \n", + bat_dbg(DBG_BATMAN, "Forwarding packet: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n", in_tq, tq_avg, batman_packet->tq, in_ttl - 1, batman_packet->ttl); diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c index e446d907a72a..5537846aded0 100644 --- a/drivers/staging/batman-adv/translation-table.c +++ b/drivers/staging/batman-adv/translation-table.c @@ -77,11 +77,11 @@ void hna_local_add(uint8_t *addr) MAC-flooding. */ if ((num_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN) / ETH_ALEN) || (num_hna + 1 > 255)) { - bat_dbg(DBG_ROUTES, "Can't add new local hna entry (%pM): number of local hna entries exceeds packet size \n", addr); + bat_dbg(DBG_ROUTES, "Can't add new local hna entry (%pM): number of local hna entries exceeds packet size\n", addr); return; } - bat_dbg(DBG_ROUTES, "Creating new local hna entry: %pM \n", + bat_dbg(DBG_ROUTES, "Creating new local hna entry: %pM\n", addr); hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC); @@ -108,7 +108,7 @@ void hna_local_add(uint8_t *addr) hna_local_hash->size * 2); if (swaphash == NULL) - printk(KERN_ERR "batman-adv:Couldn't resize local hna hash table \n"); + printk(KERN_ERR "batman-adv:Couldn't resize local hna hash table\n"); else hna_local_hash = swaphash; } @@ -197,7 +197,7 @@ static void _hna_local_del(void *data) static void hna_local_del(struct hna_local_entry *hna_local_entry, char *message) { - bat_dbg(DBG_ROUTES, "Deleting local hna entry (%pM): %s \n", + bat_dbg(DBG_ROUTES, "Deleting local hna entry (%pM): %s\n", hna_local_entry->addr, message); hash_remove(hna_local_hash, hna_local_entry->addr); @@ -340,7 +340,7 @@ void hna_global_add_orig(struct orig_node *orig_node, hna_global_hash->size * 2); if (swaphash == NULL) - printk(KERN_ERR "batman-adv:Couldn't resize global hna hash table \n"); + printk(KERN_ERR "batman-adv:Couldn't resize global hna hash table\n"); else hna_global_hash = swaphash; } @@ -365,7 +365,7 @@ int hna_global_fill_buffer_text(unsigned char *buff, int buff_len) bytes_written += snprintf(buff + bytes_written, (2 * ETH_STR_LEN) + 10, - " * %02x:%02x:%02x:%02x:%02x:%02x via %02x:%02x:%02x:%02x:%02x:%02x \n", + " * %02x:%02x:%02x:%02x:%02x:%02x via %02x:%02x:%02x:%02x:%02x:%02x\n", hna_global_entry->addr[0], hna_global_entry->addr[1], hna_global_entry->addr[2], @@ -388,7 +388,7 @@ int hna_global_fill_buffer_text(unsigned char *buff, int buff_len) void _hna_global_del_orig(struct hna_global_entry *hna_global_entry, char *message) { - bat_dbg(DBG_ROUTES, "Deleting global hna entry %pM (via %pM): %s \n", + bat_dbg(DBG_ROUTES, "Deleting global hna entry %pM (via %pM): %s\n", hna_global_entry->addr, hna_global_entry->orig_node->orig, message); -- cgit v1.2.3 From 47fdf097c348673dced571da8a15939005219da0 Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Fri, 7 May 2010 21:47:18 +0200 Subject: Staging: batman-adv: convert multiple /proc files to use sysfs This is the first patch in a series of patches which aim to convert all batman-adv /proc files to sysfs. To keep the changes in a digestable size it has been split up into smaller chunks. During the transition period batman-adv will use /proc as well as sysfs. As a first step the following files have been converted: aggregate_ogm, originators, transtable_global, transtable_local Signed-off-by: Marek Lindner Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/Makefile | 2 +- drivers/staging/batman-adv/aggregation.c | 7 +- drivers/staging/batman-adv/aggregation.h | 3 +- drivers/staging/batman-adv/bat_sysfs.c | 272 ++++++++++++++++++++++++ drivers/staging/batman-adv/bat_sysfs.h | 26 +++ drivers/staging/batman-adv/main.c | 11 +- drivers/staging/batman-adv/main.h | 1 - drivers/staging/batman-adv/originator.c | 73 +++++++ drivers/staging/batman-adv/originator.h | 2 +- drivers/staging/batman-adv/proc.c | 279 +------------------------ drivers/staging/batman-adv/proc.h | 4 - drivers/staging/batman-adv/send.c | 15 +- drivers/staging/batman-adv/translation-table.c | 42 +++- drivers/staging/batman-adv/translation-table.h | 6 +- drivers/staging/batman-adv/types.h | 2 + 15 files changed, 439 insertions(+), 306 deletions(-) create mode 100644 drivers/staging/batman-adv/bat_sysfs.c create mode 100644 drivers/staging/batman-adv/bat_sysfs.h (limited to 'drivers') diff --git a/drivers/staging/batman-adv/Makefile b/drivers/staging/batman-adv/Makefile index cf2915de0624..9ad042991616 100644 --- a/drivers/staging/batman-adv/Makefile +++ b/drivers/staging/batman-adv/Makefile @@ -19,4 +19,4 @@ # obj-m += batman-adv.o -batman-adv-objs := main.o proc.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o +batman-adv-objs := main.o proc.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o bat_sysfs.o diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c index b8338ce23c84..c94683908780 100644 --- a/drivers/staging/batman-adv/aggregation.c +++ b/drivers/staging/batman-adv/aggregation.c @@ -167,7 +167,8 @@ static void aggregate(struct forw_packet *forw_packet_aggr, void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len, struct batman_if *if_incoming, char own_packet, - unsigned long send_time) + unsigned long send_time, + struct bat_priv *bat_priv) { /** * _aggr -> pointer to the packet we want to aggregate with @@ -183,7 +184,7 @@ void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len, /* find position for the packet in the forward queue */ spin_lock_irqsave(&forw_bat_list_lock, flags); /* own packets are not to be aggregated */ - if ((atomic_read(&aggregation_enabled)) && (!own_packet)) { + if ((atomic_read(&bat_priv->aggregation_enabled)) && (!own_packet)) { hlist_for_each_entry(forw_packet_pos, tmp_node, &forw_bat_list, list) { if (can_aggregate_with(batman_packet, @@ -210,7 +211,7 @@ void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len, * later on */ if ((!own_packet) && - (atomic_read(&aggregation_enabled))) + (atomic_read(&bat_priv->aggregation_enabled))) send_time += msecs_to_jiffies(MAX_AGGREGATION_MS); new_aggregated_packet(packet_buff, packet_len, diff --git a/drivers/staging/batman-adv/aggregation.h b/drivers/staging/batman-adv/aggregation.h index bcd32c1d69e0..29e1ffcbc7f1 100644 --- a/drivers/staging/batman-adv/aggregation.h +++ b/drivers/staging/batman-adv/aggregation.h @@ -32,6 +32,7 @@ static inline int aggregated_packet(int buff_pos, int packet_len, int num_hna) void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len, struct batman_if *if_outgoing, char own_packet, - unsigned long send_time); + unsigned long send_time, + struct bat_priv *bat_priv); void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff, int packet_len, struct batman_if *if_incoming); diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c new file mode 100644 index 000000000000..62931186ff39 --- /dev/null +++ b/drivers/staging/batman-adv/bat_sysfs.c @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include "bat_sysfs.h" +#include "translation-table.h" +#include "originator.h" +#include "hard-interface.h" + +#define to_dev(obj) container_of(obj, struct device, kobj) + +struct bat_attribute { + struct attribute attr; + ssize_t (*show)(struct kobject *kobj, struct attribute *attr, + char *buf); + ssize_t (*store)(struct kobject *kobj, struct attribute *attr, + char *buf, size_t count); +}; + +#define BAT_ATTR(_name, _mode, _show, _store) \ +struct bat_attribute bat_attr_##_name = { \ + .attr = {.name = __stringify(_name), \ + .mode = _mode }, \ + .show = _show, \ + .store = _store, \ +}; + +#define BAT_BIN_ATTR(_name, _mode, _read, _write) \ +struct bin_attribute bat_attr_##_name = { \ + .attr = { .name = __stringify(_name), \ + .mode = _mode, }, \ + .read = _read, \ + .write = _write, \ +}; + +static ssize_t show_aggr_ogm(struct kobject *kobj, struct attribute *attr, + char *buff) +{ + struct device *dev = to_dev(kobj->parent); + struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); + int aggr_status = atomic_read(&bat_priv->aggregation_enabled); + + return sprintf(buff, "status: %s\ncommands: enable, disable, 0, 1 \n", + aggr_status == 0 ? "disabled" : "enabled"); +} + +static ssize_t store_aggr_ogm(struct kobject *kobj, struct attribute *attr, + char *buff, size_t count) +{ + struct device *dev = to_dev(kobj->parent); + struct net_device *net_dev = to_net_dev(dev); + struct bat_priv *bat_priv = netdev_priv(net_dev); + int aggr_tmp = -1; + + if (((count == 2) && (buff[0] == '1')) || + (strncmp(buff, "enable", 6) == 0)) + aggr_tmp = 1; + + if (((count == 2) && (buff[0] == '0')) || + (strncmp(buff, "disable", 7) == 0)) + aggr_tmp = 0; + + if (aggr_tmp < 0) { + if (buff[count - 1] == '\n') + buff[count - 1] = '\0'; + + printk(KERN_INFO "batman-adv:Invalid parameter for 'aggregate OGM' setting on mesh %s received: %s\n", + net_dev->name, buff); + return -EINVAL; + } + + if (atomic_read(&bat_priv->aggregation_enabled) == aggr_tmp) + return count; + + printk(KERN_INFO "batman-adv:Changing aggregation from: %s to: %s on mesh: %s\n", + atomic_read(&bat_priv->aggregation_enabled) == 1 ? + "enabled" : "disabled", aggr_tmp == 1 ? "enabled" : "disabled", + net_dev->name); + + atomic_set(&bat_priv->aggregation_enabled, (unsigned)aggr_tmp); + return count; +} + +static BAT_ATTR(aggregate_ogm, S_IRUGO | S_IWUSR, + show_aggr_ogm, store_aggr_ogm); + +static struct bat_attribute *mesh_attrs[] = { + &bat_attr_aggregate_ogm, + NULL, +}; + +static ssize_t transtable_local_read(struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buff, loff_t off, size_t count) +{ + struct device *dev = to_dev(kobj->parent); + struct net_device *net_dev = to_net_dev(dev); + + rcu_read_lock(); + if (list_empty(&if_list)) { + rcu_read_unlock(); + + if (off == 0) + return sprintf(buff, + "BATMAN mesh %s disabled - please specify interfaces to enable it\n", + net_dev->name); + + return 0; + } + rcu_read_unlock(); + + return hna_local_fill_buffer_text(net_dev, buff, count, off); +} + +static ssize_t transtable_global_read(struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buff, loff_t off, size_t count) +{ + struct device *dev = to_dev(kobj->parent); + struct net_device *net_dev = to_net_dev(dev); + + rcu_read_lock(); + if (list_empty(&if_list)) { + rcu_read_unlock(); + + if (off == 0) + return sprintf(buff, + "BATMAN mesh %s disabled - please specify interfaces to enable it\n", + net_dev->name); + + return 0; + } + rcu_read_unlock(); + + return hna_global_fill_buffer_text(net_dev, buff, count, off); +} + +static ssize_t originators_read(struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buff, loff_t off, size_t count) +{ + /* FIXME: orig table should exist per batif */ + struct device *dev = to_dev(kobj->parent); + struct net_device *net_dev = to_net_dev(dev); + + rcu_read_lock(); + if (list_empty(&if_list)) { + rcu_read_unlock(); + + if (off == 0) + return sprintf(buff, + "BATMAN mesh %s disabled - please specify interfaces to enable it\n", + net_dev->name); + + return 0; + } + + if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) { + rcu_read_unlock(); + + if (off == 0) + return sprintf(buff, + "BATMAN mesh %s disabled - primary interface not active\n", + net_dev->name); + + return 0; + } + rcu_read_unlock(); + + return orig_fill_buffer_text(buff, count, off); +} + +static BAT_BIN_ATTR(transtable_local, S_IRUGO, transtable_local_read, NULL); +static BAT_BIN_ATTR(transtable_global, S_IRUGO, transtable_global_read, NULL); +static BAT_BIN_ATTR(originators, S_IRUGO, originators_read, NULL); + +static struct bin_attribute *mesh_bin_attrs[] = { + &bat_attr_transtable_local, + &bat_attr_transtable_global, + &bat_attr_originators, + NULL, +}; + +int sysfs_add_meshif(struct net_device *dev) +{ + struct kobject *batif_kobject = &dev->dev.kobj; + struct bat_priv *bat_priv = netdev_priv(dev); + struct bat_attribute **bat_attr; + struct bin_attribute **bin_attr; + int err; + + /* FIXME: should be done in the general mesh setup + routine as soon as we have it */ + atomic_set(&bat_priv->aggregation_enabled, 1); + + bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR, + batif_kobject); + if (!bat_priv->mesh_obj) { + printk(KERN_ERR "batman-adv:Can't add sysfs directory: %s/%s\n", + dev->name, SYSFS_IF_MESH_SUBDIR); + goto out; + } + + for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) { + err = sysfs_create_file(bat_priv->mesh_obj, + &((*bat_attr)->attr)); + if (err) { + printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n", + dev->name, SYSFS_IF_MESH_SUBDIR, + ((*bat_attr)->attr).name); + goto rem_attr; + } + } + + for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr) { + err = sysfs_create_bin_file(bat_priv->mesh_obj, (*bin_attr)); + if (err) { + printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n", + dev->name, SYSFS_IF_MESH_SUBDIR, + ((*bin_attr)->attr).name); + goto rem_bin_attr; + } + } + + return 0; + +rem_bin_attr: + for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr) + sysfs_remove_bin_file(bat_priv->mesh_obj, (*bin_attr)); +rem_attr: + for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) + sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); + + kobject_put(bat_priv->mesh_obj); + bat_priv->mesh_obj = NULL; +out: + return -ENOMEM; +} + +void sysfs_del_meshif(struct net_device *dev) +{ + struct bat_priv *bat_priv = netdev_priv(dev); + struct bat_attribute **bat_attr; + struct bin_attribute **bin_attr; + + for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr) + sysfs_remove_bin_file(bat_priv->mesh_obj, (*bin_attr)); + + for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) + sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); + + kobject_put(bat_priv->mesh_obj); + bat_priv->mesh_obj = NULL; +} diff --git a/drivers/staging/batman-adv/bat_sysfs.h b/drivers/staging/batman-adv/bat_sysfs.h new file mode 100644 index 000000000000..671ebd1aac35 --- /dev/null +++ b/drivers/staging/batman-adv/bat_sysfs.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + + +#define SYSFS_IF_MESH_SUBDIR "mesh" + +int sysfs_add_meshif(struct net_device *dev); +void sysfs_del_meshif(struct net_device *dev); diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index 881aaa9811a8..b5f8b8009742 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -21,6 +21,7 @@ #include "main.h" #include "proc.h" +#include "bat_sysfs.h" #include "routing.h" #include "send.h" #include "originator.h" @@ -44,7 +45,6 @@ DEFINE_SPINLOCK(forw_bcast_list_lock); atomic_t originator_interval; atomic_t vis_interval; atomic_t vis_mode; -atomic_t aggregation_enabled; int16_t num_hna; int16_t num_ifs; @@ -85,7 +85,6 @@ int init_module(void) atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only * for debugging now. */ atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE); - atomic_set(&aggregation_enabled, 1); /* the name should not be longer than 10 chars - see * http://lwn.net/Articles/23634/ */ @@ -116,6 +115,11 @@ int init_module(void) goto free_soft_device; } + retval = sysfs_add_meshif(soft_device); + + if (retval < 0) + goto unreg_soft_device; + register_netdevice_notifier(&hard_if_notifier); dev_add_pack(&batman_adv_packet_type); @@ -124,6 +128,8 @@ int init_module(void) return 0; +unreg_soft_device: + unregister_netdevice(soft_device); free_soft_device: free_netdev(soft_device); soft_device = NULL; @@ -136,6 +142,7 @@ void cleanup_module(void) shutdown_module(); if (soft_device) { + sysfs_del_meshif(soft_device); unregister_netdev(soft_device); soft_device = NULL; } diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 6221b859387f..3e28e9ef79bf 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -130,7 +130,6 @@ extern spinlock_t forw_bcast_list_lock; extern atomic_t originator_interval; extern atomic_t vis_interval; extern atomic_t vis_mode; -extern atomic_t aggregation_enabled; extern int16_t num_hna; extern int16_t num_ifs; diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index f3d8cc33011b..818f56e55f23 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -249,4 +249,77 @@ void purge_orig(struct work_struct *work) start_purge_timer(); } +ssize_t orig_fill_buffer_text(char *buff, size_t count, loff_t off) +{ + HASHIT(hashit); + struct orig_node *orig_node; + struct neigh_node *neigh_node; + size_t hdr_len, tmp_len; + int batman_count = 0, bytes_written = 0; + unsigned long flags; + char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN]; + + rcu_read_lock(); + hdr_len = sprintf(buff, + " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s] \n", + "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF", + "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR, + ((struct batman_if *)if_list.next)->dev, + ((struct batman_if *)if_list.next)->addr_str); + rcu_read_unlock(); + + if (off < hdr_len) + bytes_written = hdr_len; + + spin_lock_irqsave(&orig_hash_lock, flags); + + while (hash_iterate(orig_hash, &hashit)) { + + orig_node = hashit.bucket->data; + + if (!orig_node->router) + continue; + + if (orig_node->router->tq_avg == 0) + continue; + + /* estimated line length */ + if (count < bytes_written + 200) + break; + + addr_to_string(orig_str, orig_node->orig); + addr_to_string(router_str, orig_node->router->addr); + + tmp_len = sprintf(buff + bytes_written, + "%-17s (%3i) %17s [%10s]:", + orig_str, orig_node->router->tq_avg, + router_str, + orig_node->router->if_incoming->dev); + + list_for_each_entry(neigh_node, &orig_node->neigh_list, list) { + addr_to_string(orig_str, neigh_node->addr); + tmp_len += sprintf(buff + bytes_written + tmp_len, + " %17s (%3i)", orig_str, + neigh_node->tq_avg); + } + + tmp_len += sprintf(buff + bytes_written + tmp_len, "\n"); + + batman_count++; + hdr_len += tmp_len; + + if (off >= hdr_len) + continue; + + bytes_written += tmp_len; + } + + spin_unlock_irqrestore(&orig_hash_lock, flags); + + if ((batman_count == 0) && (off == 0)) + bytes_written += sprintf(buff + bytes_written, + "No batman nodes in range ... \n"); + + return bytes_written; +} diff --git a/drivers/staging/batman-adv/originator.h b/drivers/staging/batman-adv/originator.h index 8acebc1e70eb..8289a85342a4 100644 --- a/drivers/staging/batman-adv/originator.h +++ b/drivers/staging/batman-adv/originator.h @@ -28,4 +28,4 @@ struct orig_node *get_orig_node(uint8_t *addr); struct neigh_node * create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, uint8_t *neigh, struct batman_if *if_incoming); - +ssize_t orig_fill_buffer_text(char *buff, size_t count, loff_t off); diff --git a/drivers/staging/batman-adv/proc.c b/drivers/staging/batman-adv/proc.c index dfa85c49437f..059b2d9ffa8a 100644 --- a/drivers/staging/batman-adv/proc.c +++ b/drivers/staging/batman-adv/proc.c @@ -29,11 +29,8 @@ #include "vis.h" static struct proc_dir_entry *proc_batman_dir, *proc_interface_file; -static struct proc_dir_entry *proc_orig_interval_file, *proc_originators_file; -static struct proc_dir_entry *proc_transt_local_file; -static struct proc_dir_entry *proc_transt_global_file; +static struct proc_dir_entry *proc_orig_interval_file; static struct proc_dir_entry *proc_vis_srv_file, *proc_vis_data_file; -static struct proc_dir_entry *proc_aggr_file; static int proc_interfaces_read(struct seq_file *seq, void *offset) { @@ -176,145 +173,6 @@ static int proc_orig_interval_open(struct inode *inode, struct file *file) return single_open(file, proc_orig_interval_read, NULL); } -static int proc_originators_read(struct seq_file *seq, void *offset) -{ - HASHIT(hashit); - struct orig_node *orig_node; - struct neigh_node *neigh_node; - int batman_count = 0; - char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN]; - unsigned long flags; - - rcu_read_lock(); - if (list_empty(&if_list)) { - rcu_read_unlock(); - seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it\n"); - goto end; - } - - if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) { - rcu_read_unlock(); - seq_printf(seq, "BATMAN disabled - primary interface not active\n"); - goto end; - } - - seq_printf(seq, - " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s]\n", - "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF", - "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR, - ((struct batman_if *)if_list.next)->dev, - ((struct batman_if *)if_list.next)->addr_str); - - rcu_read_unlock(); - spin_lock_irqsave(&orig_hash_lock, flags); - - while (hash_iterate(orig_hash, &hashit)) { - - orig_node = hashit.bucket->data; - - if (!orig_node->router) - continue; - - if (orig_node->router->tq_avg == 0) - continue; - - batman_count++; - - addr_to_string(orig_str, orig_node->orig); - addr_to_string(router_str, orig_node->router->addr); - - seq_printf(seq, "%-17s (%3i) %17s [%10s]:", - orig_str, orig_node->router->tq_avg, - router_str, orig_node->router->if_incoming->dev); - - list_for_each_entry(neigh_node, &orig_node->neigh_list, list) { - addr_to_string(orig_str, neigh_node->addr); - seq_printf(seq, " %17s (%3i)", - orig_str, neigh_node->tq_avg); - } - - seq_printf(seq, "\n"); - - } - - spin_unlock_irqrestore(&orig_hash_lock, flags); - - if (batman_count == 0) - seq_printf(seq, "No batman nodes in range ...\n"); - -end: - return 0; -} - -static int proc_originators_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_originators_read, NULL); -} - -static int proc_transt_local_read(struct seq_file *seq, void *offset) -{ - char *buf; - - buf = kmalloc(4096, GFP_KERNEL); - if (!buf) - return 0; - - rcu_read_lock(); - if (list_empty(&if_list)) { - rcu_read_unlock(); - seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it\n"); - goto end; - } - - rcu_read_unlock(); - - seq_printf(seq, "Locally retrieved addresses (from %s) announced via HNA:\n", soft_device->name); - - hna_local_fill_buffer_text(buf, 4096); - seq_printf(seq, "%s", buf); - -end: - kfree(buf); - return 0; -} - -static int proc_transt_local_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_transt_local_read, NULL); -} - -static int proc_transt_global_read(struct seq_file *seq, void *offset) -{ - char *buf; - - buf = kmalloc(4096, GFP_KERNEL); - if (!buf) - return 0; - - rcu_read_lock(); - if (list_empty(&if_list)) { - rcu_read_unlock(); - seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it\n"); - goto end; - } - rcu_read_unlock(); - - - seq_printf(seq, "Globally announced HNAs received via the mesh (translation table):\n"); - - hna_global_fill_buffer_text(buf, 4096); - seq_printf(seq, "%s", buf); - -end: - kfree(buf); - return 0; -} - -static int proc_transt_global_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_transt_global_read, NULL); -} - /* setting the mode of the vis server by the user */ static ssize_t proc_vis_srv_write(struct file *file, const char __user * buffer, size_t count, loff_t *ppos) @@ -429,53 +287,6 @@ static int proc_vis_data_open(struct inode *inode, struct file *file) return single_open(file, proc_vis_data_read, NULL); } -static int proc_aggr_read(struct seq_file *seq, void *offset) -{ - seq_printf(seq, "%i\n", atomic_read(&aggregation_enabled)); - - return 0; -} - -static ssize_t proc_aggr_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) -{ - char *aggr_string; - int not_copied = 0; - unsigned long aggregation_enabled_tmp; - int retval; - - aggr_string = kmalloc(count, GFP_KERNEL); - - if (!aggr_string) - return -ENOMEM; - - not_copied = copy_from_user(aggr_string, buffer, count); - aggr_string[count - not_copied - 1] = 0; - - retval = strict_strtoul(aggr_string, 10, &aggregation_enabled_tmp); - - if (retval || aggregation_enabled_tmp > 1) { - printk(KERN_ERR "batman-adv:Aggregation can only be enabled (1) or disabled (0), given value: %li\n", aggregation_enabled_tmp); - } else { - printk(KERN_INFO "batman-adv:Changing aggregation from: %s (%i) to: %s (%li)\n", - (atomic_read(&aggregation_enabled) == 1 ? - "enabled" : "disabled"), - atomic_read(&aggregation_enabled), - (aggregation_enabled_tmp == 1 ? "enabled" : "disabled"), - aggregation_enabled_tmp); - atomic_set(&aggregation_enabled, - (unsigned)aggregation_enabled_tmp); - } - - kfree(aggr_string); - return count; -} - -static int proc_aggr_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_aggr_read, NULL); -} - /* satisfying different prototypes ... */ static ssize_t proc_dummy_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) @@ -483,15 +294,6 @@ static ssize_t proc_dummy_write(struct file *file, const char __user *buffer, return count; } -static const struct file_operations proc_aggr_fops = { - .owner = THIS_MODULE, - .open = proc_aggr_open, - .read = seq_read, - .write = proc_aggr_write, - .llseek = seq_lseek, - .release = single_release, -}; - static const struct file_operations proc_vis_srv_fops = { .owner = THIS_MODULE, .open = proc_vis_srv_open, @@ -510,33 +312,6 @@ static const struct file_operations proc_vis_data_fops = { .release = single_release, }; -static const struct file_operations proc_originators_fops = { - .owner = THIS_MODULE, - .open = proc_originators_open, - .read = seq_read, - .write = proc_dummy_write, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations proc_transt_local_fops = { - .owner = THIS_MODULE, - .open = proc_transt_local_open, - .read = seq_read, - .write = proc_dummy_write, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations proc_transt_global_fops = { - .owner = THIS_MODULE, - .open = proc_transt_global_open, - .read = seq_read, - .write = proc_dummy_write, - .llseek = seq_lseek, - .release = single_release, -}; - static const struct file_operations proc_interfaces_fops = { .owner = THIS_MODULE, .open = proc_interfaces_open, @@ -557,15 +332,6 @@ static const struct file_operations proc_orig_interval_fops = { void cleanup_procfs(void) { - if (proc_transt_global_file) - remove_proc_entry(PROC_FILE_TRANST_GLOBAL, proc_batman_dir); - - if (proc_transt_local_file) - remove_proc_entry(PROC_FILE_TRANST_LOCAL, proc_batman_dir); - - if (proc_originators_file) - remove_proc_entry(PROC_FILE_ORIGINATORS, proc_batman_dir); - if (proc_orig_interval_file) remove_proc_entry(PROC_FILE_ORIG_INTERVAL, proc_batman_dir); @@ -578,9 +344,6 @@ void cleanup_procfs(void) if (proc_vis_srv_file) remove_proc_entry(PROC_FILE_VIS_SRV, proc_batman_dir); - if (proc_aggr_file) - remove_proc_entry(PROC_FILE_AGGR, proc_batman_dir); - if (proc_batman_dir) #ifdef __NET_NET_NAMESPACE_H remove_proc_entry(PROC_ROOT_DIR, init_net.proc_net); @@ -624,36 +387,6 @@ int setup_procfs(void) return -EFAULT; } - proc_originators_file = create_proc_entry(PROC_FILE_ORIGINATORS, - S_IRUGO, proc_batman_dir); - if (proc_originators_file) { - proc_originators_file->proc_fops = &proc_originators_fops; - } else { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_ORIGINATORS); - cleanup_procfs(); - return -EFAULT; - } - - proc_transt_local_file = create_proc_entry(PROC_FILE_TRANST_LOCAL, - S_IRUGO, proc_batman_dir); - if (proc_transt_local_file) { - proc_transt_local_file->proc_fops = &proc_transt_local_fops; - } else { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_TRANST_LOCAL); - cleanup_procfs(); - return -EFAULT; - } - - proc_transt_global_file = create_proc_entry(PROC_FILE_TRANST_GLOBAL, - S_IRUGO, proc_batman_dir); - if (proc_transt_global_file) { - proc_transt_global_file->proc_fops = &proc_transt_global_fops; - } else { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_TRANST_GLOBAL); - cleanup_procfs(); - return -EFAULT; - } - proc_vis_srv_file = create_proc_entry(PROC_FILE_VIS_SRV, S_IWUSR | S_IRUGO, proc_batman_dir); @@ -675,15 +408,5 @@ int setup_procfs(void) return -EFAULT; } - proc_aggr_file = create_proc_entry(PROC_FILE_AGGR, S_IWUSR | S_IRUGO, - proc_batman_dir); - if (proc_aggr_file) { - proc_aggr_file->proc_fops = &proc_aggr_fops; - } else { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_AGGR); - cleanup_procfs(); - return -EFAULT; - } - return 0; } diff --git a/drivers/staging/batman-adv/proc.h b/drivers/staging/batman-adv/proc.h index cf712648ca56..68a255a33a84 100644 --- a/drivers/staging/batman-adv/proc.h +++ b/drivers/staging/batman-adv/proc.h @@ -25,15 +25,11 @@ #define PROC_ROOT_DIR "batman-adv" #define PROC_FILE_INTERFACES "interfaces" #define PROC_FILE_ORIG_INTERVAL "orig_interval" -#define PROC_FILE_ORIGINATORS "originators" #define PROC_FILE_GATEWAYS "gateways" #define PROC_FILE_LOG "log" #define PROC_FILE_LOG_LEVEL "log_level" -#define PROC_FILE_TRANST_LOCAL "transtable_local" -#define PROC_FILE_TRANST_GLOBAL "transtable_global" #define PROC_FILE_VIS_SRV "vis_server" #define PROC_FILE_VIS_DATA "vis_data" -#define PROC_FILE_AGGR "aggregate_ogm" void cleanup_procfs(void); int setup_procfs(void); diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index 29b684ba4eab..32d1756b90a4 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -44,7 +44,7 @@ static unsigned long own_send_time(void) } /* when do we schedule a forwarded packet to be sent */ -static unsigned long forward_send_time(void) +static unsigned long forward_send_time(struct bat_priv *bat_priv) { return jiffies + (((random32() % (JITTER/2)) * HZ) / 1000); } @@ -239,6 +239,8 @@ static void rebuild_batman_packet(struct batman_if *batman_if) void schedule_own_packet(struct batman_if *batman_if) { + /* FIXME: each batman_if will be attached to a softif */ + struct bat_priv *bat_priv = netdev_priv(soft_device); unsigned long send_time; struct batman_packet *batman_packet; int vis_server = atomic_read(&vis_mode); @@ -277,7 +279,9 @@ void schedule_own_packet(struct batman_if *batman_if) slide_own_bcast_window(batman_if); send_time = own_send_time(); add_bat_packet_to_list(batman_if->packet_buff, - batman_if->packet_len, batman_if, 1, send_time); + batman_if->packet_len, + batman_if, 1, send_time, + bat_priv); } void schedule_forward_packet(struct orig_node *orig_node, @@ -286,6 +290,8 @@ void schedule_forward_packet(struct orig_node *orig_node, uint8_t directlink, int hna_buff_len, struct batman_if *if_incoming) { + /* FIXME: each batman_if will be attached to a softif */ + struct bat_priv *bat_priv = netdev_priv(soft_device); unsigned char in_tq, in_ttl, tq_avg = 0; unsigned long send_time; @@ -329,10 +335,11 @@ void schedule_forward_packet(struct orig_node *orig_node, else batman_packet->flags &= ~DIRECTLINK; - send_time = forward_send_time(); + send_time = forward_send_time(bat_priv); add_bat_packet_to_list((unsigned char *)batman_packet, sizeof(struct batman_packet) + hna_buff_len, - if_incoming, 0, send_time); + if_incoming, 0, send_time, + bat_priv); } static void forw_packet_free(struct forw_packet *forw_packet) diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c index 5537846aded0..d43b1adccf7f 100644 --- a/drivers/staging/batman-adv/translation-table.c +++ b/drivers/staging/batman-adv/translation-table.c @@ -156,23 +156,36 @@ int hna_local_fill_buffer(unsigned char *buff, int buff_len) return i; } -int hna_local_fill_buffer_text(unsigned char *buff, int buff_len) +int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff, + size_t count, loff_t off) { struct hna_local_entry *hna_local_entry; HASHIT(hashit); int bytes_written = 0; unsigned long flags; + size_t hdr_len; + + hdr_len = sprintf(buff, + "Locally retrieved addresses (from %s) announced via HNA:\n", + net_dev->name); + + if (off < hdr_len) + bytes_written = hdr_len; spin_lock_irqsave(&hna_local_hash_lock, flags); while (hash_iterate(hna_local_hash, &hashit)) { + hdr_len += 21; - if (buff_len < bytes_written + ETH_STR_LEN + 4) + if (count < bytes_written + 22) break; + if (off >= hdr_len) + continue; + hna_local_entry = hashit.bucket->data; - bytes_written += snprintf(buff + bytes_written, ETH_STR_LEN + 4, + bytes_written += snprintf(buff + bytes_written, 22, " * %02x:%02x:%02x:%02x:%02x:%02x\n", hna_local_entry->addr[0], hna_local_entry->addr[1], @@ -183,7 +196,6 @@ int hna_local_fill_buffer_text(unsigned char *buff, int buff_len) } spin_unlock_irqrestore(&hna_local_hash_lock, flags); - return bytes_written; } @@ -348,23 +360,36 @@ void hna_global_add_orig(struct orig_node *orig_node, spin_unlock_irqrestore(&hna_global_hash_lock, flags); } -int hna_global_fill_buffer_text(unsigned char *buff, int buff_len) +int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff, + size_t count, loff_t off) { struct hna_global_entry *hna_global_entry; HASHIT(hashit); int bytes_written = 0; unsigned long flags; + size_t hdr_len; + + hdr_len = sprintf(buff, + "Globally announced HNAs received via the mesh %s (translation table):\n", + net_dev->name); + + if (off < hdr_len) + bytes_written = hdr_len; spin_lock_irqsave(&hna_global_hash_lock, flags); while (hash_iterate(hna_global_hash, &hashit)) { - if (buff_len < bytes_written + (2 * ETH_STR_LEN) + 10) + hdr_len += 43; + + if (count < bytes_written + 44) break; + if (off >= hdr_len) + continue; + hna_global_entry = hashit.bucket->data; - bytes_written += snprintf(buff + bytes_written, - (2 * ETH_STR_LEN) + 10, + bytes_written += snprintf(buff + bytes_written, 44, " * %02x:%02x:%02x:%02x:%02x:%02x via %02x:%02x:%02x:%02x:%02x:%02x\n", hna_global_entry->addr[0], hna_global_entry->addr[1], @@ -381,7 +406,6 @@ int hna_global_fill_buffer_text(unsigned char *buff, int buff_len) } spin_unlock_irqrestore(&hna_global_hash_lock, flags); - return bytes_written; } diff --git a/drivers/staging/batman-adv/translation-table.h b/drivers/staging/batman-adv/translation-table.h index 8568d80df361..8f412fca87f1 100644 --- a/drivers/staging/batman-adv/translation-table.h +++ b/drivers/staging/batman-adv/translation-table.h @@ -25,13 +25,15 @@ int hna_local_init(void); void hna_local_add(uint8_t *addr); void hna_local_remove(uint8_t *addr, char *message); int hna_local_fill_buffer(unsigned char *buff, int buff_len); -int hna_local_fill_buffer_text(unsigned char *buff, int buff_len); +int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff, + size_t count, loff_t off); void hna_local_purge(struct work_struct *work); void hna_local_free(void); int hna_global_init(void); void hna_global_add_orig(struct orig_node *orig_node, unsigned char *hna_buff, int hna_buff_len); -int hna_global_fill_buffer_text(unsigned char *buff, int buff_len); +int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff, + size_t count, loff_t off); void _hna_global_del_orig(struct hna_global_entry *hna_global_entry, char *orig_str); void hna_global_del_orig(struct orig_node *orig_node, char *message); diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index 4e77141078f9..db1bb0b22043 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -82,6 +82,8 @@ struct neigh_node { struct bat_priv { struct net_device_stats stats; + atomic_t aggregation_enabled; + struct kobject *mesh_obj; }; struct device_client { -- cgit v1.2.3 From 147412406a200a9a3230fad1e0e99c818e873680 Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Fri, 7 May 2010 21:47:19 +0200 Subject: Staging: batman-adv: convert more files from /proc to /sys converted files: vis_mode, vis_data Signed-off-by: Marek Lindner Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/aggregation.c | 6 +- drivers/staging/batman-adv/aggregation.h | 8 +- drivers/staging/batman-adv/bat_sysfs.c | 118 +++++++++-------- drivers/staging/batman-adv/main.c | 2 - drivers/staging/batman-adv/main.h | 1 - drivers/staging/batman-adv/originator.c | 33 ++++- drivers/staging/batman-adv/originator.h | 3 +- drivers/staging/batman-adv/proc.c | 167 ------------------------- drivers/staging/batman-adv/proc.h | 5 - drivers/staging/batman-adv/routing.c | 10 +- drivers/staging/batman-adv/send.c | 16 +-- drivers/staging/batman-adv/soft-interface.c | 4 + drivers/staging/batman-adv/translation-table.c | 26 ++++ drivers/staging/batman-adv/types.h | 1 + drivers/staging/batman-adv/vis.c | 124 +++++++++++++++--- drivers/staging/batman-adv/vis.h | 17 +-- 16 files changed, 265 insertions(+), 276 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c index c94683908780..a5818ff6139e 100644 --- a/drivers/staging/batman-adv/aggregation.c +++ b/drivers/staging/batman-adv/aggregation.c @@ -165,10 +165,10 @@ static void aggregate(struct forw_packet *forw_packet_aggr, (1 << forw_packet_aggr->num_packets); } -void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len, +void add_bat_packet_to_list(struct bat_priv *bat_priv, + unsigned char *packet_buff, int packet_len, struct batman_if *if_incoming, char own_packet, - unsigned long send_time, - struct bat_priv *bat_priv) + unsigned long send_time) { /** * _aggr -> pointer to the packet we want to aggregate with diff --git a/drivers/staging/batman-adv/aggregation.h b/drivers/staging/batman-adv/aggregation.h index 29e1ffcbc7f1..84401ca24c35 100644 --- a/drivers/staging/batman-adv/aggregation.h +++ b/drivers/staging/batman-adv/aggregation.h @@ -30,9 +30,9 @@ static inline int aggregated_packet(int buff_pos, int packet_len, int num_hna) (next_buff_pos <= MAX_AGGREGATION_BYTES); } -void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len, - struct batman_if *if_outgoing, char own_packet, - unsigned long send_time, - struct bat_priv *bat_priv); +void add_bat_packet_to_list(struct bat_priv *bat_priv, + unsigned char *packet_buff, int packet_len, + struct batman_if *if_incoming, char own_packet, + unsigned long send_time); void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff, int packet_len, struct batman_if *if_incoming); diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c index 62931186ff39..c14ab47fc5a4 100644 --- a/drivers/staging/batman-adv/bat_sysfs.c +++ b/drivers/staging/batman-adv/bat_sysfs.c @@ -24,6 +24,7 @@ #include "translation-table.h" #include "originator.h" #include "hard-interface.h" +#include "vis.h" #define to_dev(obj) container_of(obj, struct device, kobj) @@ -99,11 +100,66 @@ static ssize_t store_aggr_ogm(struct kobject *kobj, struct attribute *attr, return count; } +static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr, + char *buff) +{ + struct device *dev = to_dev(kobj->parent); + struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); + int vis_mode = atomic_read(&bat_priv->vis_mode); + + return sprintf(buff, "status: %s\ncommands: client, server, %d, %d \n", + vis_mode == VIS_TYPE_CLIENT_UPDATE ? + "client" : "server", + VIS_TYPE_SERVER_SYNC, VIS_TYPE_CLIENT_UPDATE); +} + +static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr, + char *buff, size_t count) +{ + struct device *dev = to_dev(kobj->parent); + struct net_device *net_dev = to_net_dev(dev); + struct bat_priv *bat_priv = netdev_priv(net_dev); + unsigned long val; + int ret, vis_mode_tmp = -1; + + ret = strict_strtoul(buff, 10, &val); + + if (((count == 2) && (!ret) && (val == VIS_TYPE_CLIENT_UPDATE)) || + (strncmp(buff, "client", 6) == 0)) + vis_mode_tmp = VIS_TYPE_CLIENT_UPDATE; + + if (((count == 2) && (!ret) && (val == VIS_TYPE_SERVER_SYNC)) || + (strncmp(buff, "server", 6) == 0)) + vis_mode_tmp = VIS_TYPE_SERVER_SYNC; + + if (vis_mode_tmp < 0) { + if (buff[count - 1] == '\n') + buff[count - 1] = '\0'; + + printk(KERN_INFO "batman-adv:Invalid parameter for 'vis mode' setting on mesh %s received: %s\n", + net_dev->name, buff); + return -EINVAL; + } + + if (atomic_read(&bat_priv->vis_mode) == vis_mode_tmp) + return count; + + printk(KERN_INFO "batman-adv:Changing vis mode from: %s to: %s on mesh: %s\n", + atomic_read(&bat_priv->vis_mode) == VIS_TYPE_CLIENT_UPDATE ? + "client" : "server", vis_mode_tmp == VIS_TYPE_CLIENT_UPDATE ? + "client" : "server", net_dev->name); + + atomic_set(&bat_priv->vis_mode, (unsigned)vis_mode_tmp); + return count; +} + static BAT_ATTR(aggregate_ogm, S_IRUGO | S_IWUSR, show_aggr_ogm, store_aggr_ogm); +static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode); static struct bat_attribute *mesh_attrs[] = { &bat_attr_aggregate_ogm, + &bat_attr_vis_mode, NULL, }; @@ -114,19 +170,6 @@ static ssize_t transtable_local_read(struct kobject *kobj, struct device *dev = to_dev(kobj->parent); struct net_device *net_dev = to_net_dev(dev); - rcu_read_lock(); - if (list_empty(&if_list)) { - rcu_read_unlock(); - - if (off == 0) - return sprintf(buff, - "BATMAN mesh %s disabled - please specify interfaces to enable it\n", - net_dev->name); - - return 0; - } - rcu_read_unlock(); - return hna_local_fill_buffer_text(net_dev, buff, count, off); } @@ -137,19 +180,6 @@ static ssize_t transtable_global_read(struct kobject *kobj, struct device *dev = to_dev(kobj->parent); struct net_device *net_dev = to_net_dev(dev); - rcu_read_lock(); - if (list_empty(&if_list)) { - rcu_read_unlock(); - - if (off == 0) - return sprintf(buff, - "BATMAN mesh %s disabled - please specify interfaces to enable it\n", - net_dev->name); - - return 0; - } - rcu_read_unlock(); - return hna_global_fill_buffer_text(net_dev, buff, count, off); } @@ -157,45 +187,32 @@ static ssize_t originators_read(struct kobject *kobj, struct bin_attribute *bin_attr, char *buff, loff_t off, size_t count) { - /* FIXME: orig table should exist per batif */ struct device *dev = to_dev(kobj->parent); struct net_device *net_dev = to_net_dev(dev); - rcu_read_lock(); - if (list_empty(&if_list)) { - rcu_read_unlock(); - - if (off == 0) - return sprintf(buff, - "BATMAN mesh %s disabled - please specify interfaces to enable it\n", - net_dev->name); - - return 0; - } - - if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) { - rcu_read_unlock(); - - if (off == 0) - return sprintf(buff, - "BATMAN mesh %s disabled - primary interface not active\n", - net_dev->name); + return orig_fill_buffer_text(net_dev, buff, count, off); +} - return 0; - } - rcu_read_unlock(); +static ssize_t vis_data_read(struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buff, loff_t off, size_t count) +{ + struct device *dev = to_dev(kobj->parent); + struct net_device *net_dev = to_net_dev(dev); - return orig_fill_buffer_text(buff, count, off); + return vis_fill_buffer_text(net_dev, buff, count, off); } static BAT_BIN_ATTR(transtable_local, S_IRUGO, transtable_local_read, NULL); static BAT_BIN_ATTR(transtable_global, S_IRUGO, transtable_global_read, NULL); static BAT_BIN_ATTR(originators, S_IRUGO, originators_read, NULL); +static BAT_BIN_ATTR(vis_data, S_IRUGO, vis_data_read, NULL); static struct bin_attribute *mesh_bin_attrs[] = { &bat_attr_transtable_local, &bat_attr_transtable_global, &bat_attr_originators, + &bat_attr_vis_data, NULL, }; @@ -210,6 +227,7 @@ int sysfs_add_meshif(struct net_device *dev) /* FIXME: should be done in the general mesh setup routine as soon as we have it */ atomic_set(&bat_priv->aggregation_enabled, 1); + atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE); bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR, batif_kobject); diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index b5f8b8009742..54e8cd5a32f3 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -44,7 +44,6 @@ DEFINE_SPINLOCK(forw_bcast_list_lock); atomic_t originator_interval; atomic_t vis_interval; -atomic_t vis_mode; int16_t num_hna; int16_t num_ifs; @@ -84,7 +83,6 @@ int init_module(void) atomic_set(&originator_interval, 1000); atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only * for debugging now. */ - atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE); /* the name should not be longer than 10 chars - see * http://lwn.net/Articles/23634/ */ diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 3e28e9ef79bf..b2283a75ee61 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -129,7 +129,6 @@ extern spinlock_t forw_bcast_list_lock; extern atomic_t originator_interval; extern atomic_t vis_interval; -extern atomic_t vis_mode; extern int16_t num_hna; extern int16_t num_ifs; diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 818f56e55f23..684db750cf16 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -26,6 +26,7 @@ #include "hash.h" #include "translation-table.h" #include "routing.h" +#include "hard-interface.h" static DECLARE_DELAYED_WORK(purge_orig_wq, purge_orig); @@ -205,7 +206,6 @@ static bool purge_orig_neighbors(struct orig_node *orig_node, return neigh_purged; } - static bool purge_orig_node(struct orig_node *orig_node) { struct neigh_node *best_neigh_node; @@ -224,6 +224,7 @@ static bool purge_orig_node(struct orig_node *orig_node) orig_node->hna_buff, orig_node->hna_buff_len); } + return false; } @@ -249,7 +250,8 @@ void purge_orig(struct work_struct *work) start_purge_timer(); } -ssize_t orig_fill_buffer_text(char *buff, size_t count, loff_t off) +ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, + size_t count, loff_t off) { HASHIT(hashit); struct orig_node *orig_node; @@ -260,12 +262,35 @@ ssize_t orig_fill_buffer_text(char *buff, size_t count, loff_t off) char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN]; rcu_read_lock(); + if (list_empty(&if_list)) { + rcu_read_unlock(); + + if (off == 0) + return sprintf(buff, + "BATMAN mesh %s disabled - please specify interfaces to enable it\n", + net_dev->name); + + return 0; + } + + if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) { + rcu_read_unlock(); + + if (off == 0) + return sprintf(buff, + "BATMAN mesh %s disabled - primary interface not active\n", + net_dev->name); + + return 0; + } + hdr_len = sprintf(buff, - " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s] \n", + " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)] \n", "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF", "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR, ((struct batman_if *)if_list.next)->dev, - ((struct batman_if *)if_list.next)->addr_str); + ((struct batman_if *)if_list.next)->addr_str, + net_dev->name); rcu_read_unlock(); if (off < hdr_len) diff --git a/drivers/staging/batman-adv/originator.h b/drivers/staging/batman-adv/originator.h index 8289a85342a4..745b4b064c1c 100644 --- a/drivers/staging/batman-adv/originator.h +++ b/drivers/staging/batman-adv/originator.h @@ -28,4 +28,5 @@ struct orig_node *get_orig_node(uint8_t *addr); struct neigh_node * create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, uint8_t *neigh, struct batman_if *if_incoming); -ssize_t orig_fill_buffer_text(char *buff, size_t count, loff_t off); +ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, + size_t count, loff_t off); diff --git a/drivers/staging/batman-adv/proc.c b/drivers/staging/batman-adv/proc.c index 059b2d9ffa8a..cbea64212db7 100644 --- a/drivers/staging/batman-adv/proc.c +++ b/drivers/staging/batman-adv/proc.c @@ -30,7 +30,6 @@ static struct proc_dir_entry *proc_batman_dir, *proc_interface_file; static struct proc_dir_entry *proc_orig_interval_file; -static struct proc_dir_entry *proc_vis_srv_file, *proc_vis_data_file; static int proc_interfaces_read(struct seq_file *seq, void *offset) { @@ -173,145 +172,6 @@ static int proc_orig_interval_open(struct inode *inode, struct file *file) return single_open(file, proc_orig_interval_read, NULL); } -/* setting the mode of the vis server by the user */ -static ssize_t proc_vis_srv_write(struct file *file, const char __user * buffer, - size_t count, loff_t *ppos) -{ - char *vis_mode_string; - int not_copied = 0; - - vis_mode_string = kmalloc(count, GFP_KERNEL); - - if (!vis_mode_string) - return -ENOMEM; - - not_copied = copy_from_user(vis_mode_string, buffer, count); - vis_mode_string[count - not_copied - 1] = 0; - - if ((strcmp(vis_mode_string, "client") == 0) || - (strcmp(vis_mode_string, "disabled") == 0)) { - printk(KERN_INFO "batman-adv:Setting VIS mode to client (disabling vis server)\n"); - atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE); - } else if ((strcmp(vis_mode_string, "server") == 0) || - (strcmp(vis_mode_string, "enabled") == 0)) { - printk(KERN_INFO "batman-adv:Setting VIS mode to server (enabling vis server)\n"); - atomic_set(&vis_mode, VIS_TYPE_SERVER_SYNC); - } else - printk(KERN_ERR "batman-adv:Unknown VIS mode: %s\n", - vis_mode_string); - - kfree(vis_mode_string); - return count; -} - -static int proc_vis_srv_read(struct seq_file *seq, void *offset) -{ - int vis_server = atomic_read(&vis_mode); - - seq_printf(seq, "[%c] client mode (server disabled)\n", - (vis_server == VIS_TYPE_CLIENT_UPDATE) ? 'x' : ' '); - seq_printf(seq, "[%c] server mode (server enabled)\n", - (vis_server == VIS_TYPE_SERVER_SYNC) ? 'x' : ' '); - - return 0; -} - -static int proc_vis_srv_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_vis_srv_read, NULL); -} - -static int proc_vis_data_read(struct seq_file *seq, void *offset) -{ - HASHIT(hashit); - struct vis_info *info; - struct vis_info_entry *entries; - HLIST_HEAD(vis_if_list); - struct if_list_entry *entry; - struct hlist_node *pos, *n; - int i; - char tmp_addr_str[ETH_STR_LEN]; - unsigned long flags; - int vis_server = atomic_read(&vis_mode); - - rcu_read_lock(); - if (list_empty(&if_list) || (vis_server == VIS_TYPE_CLIENT_UPDATE)) { - rcu_read_unlock(); - goto end; - } - - rcu_read_unlock(); - - spin_lock_irqsave(&vis_hash_lock, flags); - while (hash_iterate(vis_hash, &hashit)) { - info = hashit.bucket->data; - entries = (struct vis_info_entry *) - ((char *)info + sizeof(struct vis_info)); - - for (i = 0; i < info->packet.entries; i++) { - if (entries[i].quality == 0) - continue; - proc_vis_insert_interface(entries[i].src, &vis_if_list, - compare_orig(entries[i].src, - info->packet.vis_orig)); - } - - hlist_for_each_entry(entry, pos, &vis_if_list, list) { - addr_to_string(tmp_addr_str, entry->addr); - seq_printf(seq, "%s,", tmp_addr_str); - - for (i = 0; i < info->packet.entries; i++) - proc_vis_read_entry(seq, &entries[i], - entry->addr, entry->primary); - - /* add primary/secondary records */ - if (compare_orig(entry->addr, info->packet.vis_orig)) - proc_vis_read_prim_sec(seq, &vis_if_list); - - seq_printf(seq, "\n"); - } - - hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) { - hlist_del(&entry->list); - kfree(entry); - } - } - spin_unlock_irqrestore(&vis_hash_lock, flags); - -end: - return 0; -} - -static int proc_vis_data_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_vis_data_read, NULL); -} - -/* satisfying different prototypes ... */ -static ssize_t proc_dummy_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) -{ - return count; -} - -static const struct file_operations proc_vis_srv_fops = { - .owner = THIS_MODULE, - .open = proc_vis_srv_open, - .read = seq_read, - .write = proc_vis_srv_write, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations proc_vis_data_fops = { - .owner = THIS_MODULE, - .open = proc_vis_data_open, - .read = seq_read, - .write = proc_dummy_write, - .llseek = seq_lseek, - .release = single_release, -}; - static const struct file_operations proc_interfaces_fops = { .owner = THIS_MODULE, .open = proc_interfaces_open, @@ -338,12 +198,6 @@ void cleanup_procfs(void) if (proc_interface_file) remove_proc_entry(PROC_FILE_INTERFACES, proc_batman_dir); - if (proc_vis_data_file) - remove_proc_entry(PROC_FILE_VIS_DATA, proc_batman_dir); - - if (proc_vis_srv_file) - remove_proc_entry(PROC_FILE_VIS_SRV, proc_batman_dir); - if (proc_batman_dir) #ifdef __NET_NET_NAMESPACE_H remove_proc_entry(PROC_ROOT_DIR, init_net.proc_net); @@ -387,26 +241,5 @@ int setup_procfs(void) return -EFAULT; } - proc_vis_srv_file = create_proc_entry(PROC_FILE_VIS_SRV, - S_IWUSR | S_IRUGO, - proc_batman_dir); - if (proc_vis_srv_file) { - proc_vis_srv_file->proc_fops = &proc_vis_srv_fops; - } else { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_SRV); - cleanup_procfs(); - return -EFAULT; - } - - proc_vis_data_file = create_proc_entry(PROC_FILE_VIS_DATA, S_IRUGO, - proc_batman_dir); - if (proc_vis_data_file) { - proc_vis_data_file->proc_fops = &proc_vis_data_fops; - } else { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_DATA); - cleanup_procfs(); - return -EFAULT; - } - return 0; } diff --git a/drivers/staging/batman-adv/proc.h b/drivers/staging/batman-adv/proc.h index 68a255a33a84..6a972a6f26b1 100644 --- a/drivers/staging/batman-adv/proc.h +++ b/drivers/staging/batman-adv/proc.h @@ -25,11 +25,6 @@ #define PROC_ROOT_DIR "batman-adv" #define PROC_FILE_INTERFACES "interfaces" #define PROC_FILE_ORIG_INTERVAL "orig_interval" -#define PROC_FILE_GATEWAYS "gateways" -#define PROC_FILE_LOG "log" -#define PROC_FILE_LOG_LEVEL "log_level" -#define PROC_FILE_VIS_SRV "vis_server" -#define PROC_FILE_VIS_DATA "vis_data" void cleanup_procfs(void); int setup_procfs(void); diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index a78ae5c4dcb0..8c055a124cf2 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -946,6 +946,7 @@ int recv_vis_packet(struct sk_buff *skb) { struct vis_packet *vis_packet; struct ethhdr *ethhdr; + struct bat_priv *bat_priv; int hdr_size = sizeof(struct vis_packet); if (skb_headlen(skb) < hdr_size) @@ -965,15 +966,20 @@ int recv_vis_packet(struct sk_buff *skb) if (is_my_mac(vis_packet->sender_orig)) return NET_RX_DROP; + /* FIXME: each batman_if will be attached to a softif */ + bat_priv = netdev_priv(soft_device); + switch (vis_packet->vis_type) { case VIS_TYPE_SERVER_SYNC: /* TODO: handle fragmented skbs properly */ - receive_server_sync_packet(vis_packet, skb_headlen(skb)); + receive_server_sync_packet(bat_priv, vis_packet, + skb_headlen(skb)); break; case VIS_TYPE_CLIENT_UPDATE: /* TODO: handle fragmented skbs properly */ - receive_client_update_packet(vis_packet, skb_headlen(skb)); + receive_client_update_packet(bat_priv, vis_packet, + skb_headlen(skb)); break; default: /* ignore unknown packet */ diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index 32d1756b90a4..a00aa8871831 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -243,7 +243,7 @@ void schedule_own_packet(struct batman_if *batman_if) struct bat_priv *bat_priv = netdev_priv(soft_device); unsigned long send_time; struct batman_packet *batman_packet; - int vis_server = atomic_read(&vis_mode); + int vis_server = atomic_read(&bat_priv->vis_mode); /** * the interface gets activated here to avoid race conditions between @@ -271,17 +271,17 @@ void schedule_own_packet(struct batman_if *batman_if) if (vis_server == VIS_TYPE_SERVER_SYNC) batman_packet->flags = VIS_SERVER; else - batman_packet->flags = 0; + batman_packet->flags &= ~VIS_SERVER; /* could be read by receive_bat_packet() */ atomic_inc(&batman_if->seqno); slide_own_bcast_window(batman_if); send_time = own_send_time(); - add_bat_packet_to_list(batman_if->packet_buff, + add_bat_packet_to_list(bat_priv, + batman_if->packet_buff, batman_if->packet_len, - batman_if, 1, send_time, - bat_priv); + batman_if, 1, send_time); } void schedule_forward_packet(struct orig_node *orig_node, @@ -336,10 +336,10 @@ void schedule_forward_packet(struct orig_node *orig_node, batman_packet->flags &= ~DIRECTLINK; send_time = forward_send_time(bat_priv); - add_bat_packet_to_list((unsigned char *)batman_packet, + add_bat_packet_to_list(bat_priv, + (unsigned char *)batman_packet, sizeof(struct batman_packet) + hna_buff_len, - if_incoming, 0, send_time, - bat_priv); + if_incoming, 0, send_time); } static void forw_packet_free(struct forw_packet *forw_packet) diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 0dff959050bf..829deb694b84 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -182,6 +182,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) struct ethhdr *ethhdr = (struct ethhdr *)skb->data; struct bat_priv *priv = netdev_priv(dev); struct batman_if *batman_if; + struct bat_priv *bat_priv; uint8_t dstaddr[6]; int data_len = skb->len; unsigned long flags; @@ -189,6 +190,9 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) if (atomic_read(&module_state) != MODULE_ACTIVE) goto dropped; + /* FIXME: each batman_if will be attached to a softif */ + bat_priv = netdev_priv(soft_device); + dev->trans_start = jiffies; /* TODO: check this for locks */ hna_local_add(ethhdr->h_source); diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c index d43b1adccf7f..b735200ecf1b 100644 --- a/drivers/staging/batman-adv/translation-table.c +++ b/drivers/staging/batman-adv/translation-table.c @@ -165,6 +165,19 @@ int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff, unsigned long flags; size_t hdr_len; + rcu_read_lock(); + if (list_empty(&if_list)) { + rcu_read_unlock(); + + if (off == 0) + return sprintf(buff, + "BATMAN mesh %s disabled - please specify interfaces to enable it\n", + net_dev->name); + + return 0; + } + rcu_read_unlock(); + hdr_len = sprintf(buff, "Locally retrieved addresses (from %s) announced via HNA:\n", net_dev->name); @@ -369,6 +382,19 @@ int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff, unsigned long flags; size_t hdr_len; + rcu_read_lock(); + if (list_empty(&if_list)) { + rcu_read_unlock(); + + if (off == 0) + return sprintf(buff, + "BATMAN mesh %s disabled - please specify interfaces to enable it\n", + net_dev->name); + + return 0; + } + rcu_read_unlock(); + hdr_len = sprintf(buff, "Globally announced HNAs received via the mesh %s (translation table):\n", net_dev->name); diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index db1bb0b22043..e8d2e8c2c645 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -83,6 +83,7 @@ struct neigh_node { struct bat_priv { struct net_device_stats stats; atomic_t aggregation_enabled; + atomic_t vis_mode; struct kobject *mesh_obj; }; diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index 0bfc083a4234..5edeb3261ac1 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -102,7 +102,7 @@ static int vis_info_choose(void *data, int size) /* insert interface to the list of interfaces of one originator, if it * does not already exist in the list */ -void proc_vis_insert_interface(const uint8_t *interface, +static void vis_data_insert_interface(const uint8_t *interface, struct hlist_head *if_list, bool primary) { @@ -123,36 +123,119 @@ void proc_vis_insert_interface(const uint8_t *interface, hlist_add_head(&entry->list, if_list); } -void proc_vis_read_prim_sec(struct seq_file *seq, - struct hlist_head *if_list) +static ssize_t vis_data_read_prim_sec(char *buff, struct hlist_head *if_list) { struct if_list_entry *entry; struct hlist_node *pos; char tmp_addr_str[ETH_STR_LEN]; + size_t len = 0; hlist_for_each_entry(entry, pos, if_list, list) { if (entry->primary) - seq_printf(seq, "PRIMARY, "); + len += sprintf(buff + len, "PRIMARY, "); else { addr_to_string(tmp_addr_str, entry->addr); - seq_printf(seq, "SEC %s, ", tmp_addr_str); + len += sprintf(buff + len, "SEC %s, ", tmp_addr_str); } } + + return len; } /* read an entry */ -void proc_vis_read_entry(struct seq_file *seq, - struct vis_info_entry *entry, - uint8_t *src, - bool primary) +static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry, + uint8_t *src, bool primary) { char to[40]; addr_to_string(to, entry->dest); if (primary && entry->quality == 0) - seq_printf(seq, "HNA %s, ", to); + return sprintf(buff, "HNA %s, ", to); else if (compare_orig(entry->src, src)) - seq_printf(seq, "TQ %s %d, ", to, entry->quality); + return sprintf(buff, "TQ %s %d, ", to, entry->quality); + + return 0; +} + +ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff, + size_t count, loff_t off) +{ + HASHIT(hashit); + struct vis_info *info; + struct vis_info_entry *entries; + struct bat_priv *bat_priv = netdev_priv(net_dev); + HLIST_HEAD(vis_if_list); + struct if_list_entry *entry; + struct hlist_node *pos, *n; + size_t hdr_len, tmp_len; + int i, bytes_written = 0; + char tmp_addr_str[ETH_STR_LEN]; + unsigned long flags; + int vis_server = atomic_read(&bat_priv->vis_mode); + + rcu_read_lock(); + if (list_empty(&if_list) || (vis_server == VIS_TYPE_CLIENT_UPDATE)) { + rcu_read_unlock(); + return 0; + } + + rcu_read_unlock(); + hdr_len = 0; + + spin_lock_irqsave(&vis_hash_lock, flags); + while (hash_iterate(vis_hash, &hashit)) { + info = hashit.bucket->data; + entries = (struct vis_info_entry *) + ((char *)info + sizeof(struct vis_info)); + + /* estimated line length */ + if (count < bytes_written + 200) + break; + + for (i = 0; i < info->packet.entries; i++) { + if (entries[i].quality == 0) + continue; + vis_data_insert_interface(entries[i].src, &vis_if_list, + compare_orig(entries[i].src, + info->packet.vis_orig)); + } + + hlist_for_each_entry(entry, pos, &vis_if_list, list) { + addr_to_string(tmp_addr_str, entry->addr); + tmp_len = sprintf(buff + bytes_written, + "%s,", tmp_addr_str); + + for (i = 0; i < info->packet.entries; i++) + tmp_len += vis_data_read_entry( + buff + bytes_written + tmp_len, + &entries[i], entry->addr, + entry->primary); + + /* add primary/secondary records */ + if (compare_orig(entry->addr, info->packet.vis_orig)) + tmp_len += vis_data_read_prim_sec( + buff + bytes_written + tmp_len, + &vis_if_list); + + tmp_len += sprintf(buff + bytes_written + tmp_len, + "\n"); + + hdr_len += tmp_len; + + if (off >= hdr_len) + continue; + + bytes_written += tmp_len; + } + + hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) { + hlist_del(&entry->list); + kfree(entry); + } + } + spin_unlock_irqrestore(&vis_hash_lock, flags); + + return bytes_written; } /* add the info packet to the send list, if it was not @@ -280,12 +363,14 @@ static struct vis_info *add_packet(struct vis_packet *vis_packet, } /* handle the server sync packet, forward if needed. */ -void receive_server_sync_packet(struct vis_packet *vis_packet, int vis_info_len) +void receive_server_sync_packet(struct bat_priv *bat_priv, + struct vis_packet *vis_packet, + int vis_info_len) { struct vis_info *info; int is_new, make_broadcast; unsigned long flags; - int vis_server = atomic_read(&vis_mode); + int vis_server = atomic_read(&bat_priv->vis_mode); make_broadcast = (vis_server == VIS_TYPE_SERVER_SYNC); @@ -303,13 +388,14 @@ end: } /* handle an incoming client update packet and schedule forward if needed. */ -void receive_client_update_packet(struct vis_packet *vis_packet, +void receive_client_update_packet(struct bat_priv *bat_priv, + struct vis_packet *vis_packet, int vis_info_len) { struct vis_info *info; int is_new; unsigned long flags; - int vis_server = atomic_read(&vis_mode); + int vis_server = atomic_read(&bat_priv->vis_mode); int are_target = 0; /* clients shall not broadcast. */ @@ -376,7 +462,7 @@ static bool vis_packet_full(struct vis_info *info) /* generates a packet of own vis data, * returns 0 on success, -1 if no packet could be generated */ -static int generate_vis_packet(void) +static int generate_vis_packet(struct bat_priv *bat_priv) { HASHIT(hashit_local); HASHIT(hashit_global); @@ -388,7 +474,7 @@ static int generate_vis_packet(void) unsigned long flags; info->first_seen = jiffies; - info->packet.vis_type = atomic_read(&vis_mode); + info->packet.vis_type = atomic_read(&bat_priv->vis_mode); spin_lock_irqsave(&orig_hash_lock, flags); memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); @@ -568,12 +654,14 @@ static void send_vis_packets(struct work_struct *work) { struct vis_info *info, *temp; unsigned long flags; + /* FIXME: each batman_if will be attached to a softif */ + struct bat_priv *bat_priv = netdev_priv(soft_device); spin_lock_irqsave(&vis_hash_lock, flags); purge_vis_packets(); - if (generate_vis_packet() == 0) { + if (generate_vis_packet(bat_priv) == 0) { /* schedule if generation was successful */ send_list_add(my_vis_info); } diff --git a/drivers/staging/batman-adv/vis.h b/drivers/staging/batman-adv/vis.h index 4e417fb17b94..9c1fd771cbae 100644 --- a/drivers/staging/batman-adv/vis.h +++ b/drivers/staging/batman-adv/vis.h @@ -47,18 +47,13 @@ struct recvlist_node { extern struct hashtable_t *vis_hash; extern spinlock_t vis_hash_lock; -void proc_vis_insert_interface(const uint8_t *interface, - struct hlist_head *if_list, - bool primary); -void proc_vis_read_entry(struct seq_file *seq, - struct vis_info_entry *entry, - uint8_t *src, - bool primary); -void proc_vis_read_prim_sec(struct seq_file *seq, - struct hlist_head *if_list); -void receive_server_sync_packet(struct vis_packet *vis_packet, +ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff, + size_t count, loff_t off); +void receive_server_sync_packet(struct bat_priv *bat_priv, + struct vis_packet *vis_packet, int vis_info_len); -void receive_client_update_packet(struct vis_packet *vis_packet, +void receive_client_update_packet(struct bat_priv *bat_priv, + struct vis_packet *vis_packet, int vis_info_len); int vis_init(void); void vis_quit(void); -- cgit v1.2.3 From 1d59f82cb876ee9a1b4adc4f9b1063b855eac015 Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Fri, 7 May 2010 21:47:20 +0200 Subject: Staging: batman-adv: move originator interval setting from /proc to /sys Signed-off-by: Marek Lindner Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/bat_sysfs.c | 47 +++++++++++++++++++++ drivers/staging/batman-adv/main.c | 2 - drivers/staging/batman-adv/main.h | 1 - drivers/staging/batman-adv/proc.c | 75 ---------------------------------- drivers/staging/batman-adv/proc.h | 1 - drivers/staging/batman-adv/send.c | 6 +-- drivers/staging/batman-adv/types.h | 1 + 7 files changed, 51 insertions(+), 82 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c index c14ab47fc5a4..ea7ce775009a 100644 --- a/drivers/staging/batman-adv/bat_sysfs.c +++ b/drivers/staging/batman-adv/bat_sysfs.c @@ -153,13 +153,59 @@ static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr, return count; } +static ssize_t show_orig_interval(struct kobject *kobj, struct attribute *attr, + char *buff) +{ + struct device *dev = to_dev(kobj->parent); + struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); + + return sprintf(buff, "status: %i\n", + atomic_read(&bat_priv->orig_interval)); +} + +static ssize_t store_orig_interval(struct kobject *kobj, struct attribute *attr, + char *buff, size_t count) +{ + struct device *dev = to_dev(kobj->parent); + struct net_device *net_dev = to_net_dev(dev); + struct bat_priv *bat_priv = netdev_priv(net_dev); + unsigned long orig_interval_tmp; + int ret; + + ret = strict_strtoul(buff, 10, &orig_interval_tmp); + if (ret) { + printk(KERN_INFO "batman-adv:Invalid parameter for 'orig_interval' setting on mesh %s received: %s\n", + net_dev->name, buff); + return -EINVAL; + } + + if (orig_interval_tmp <= JITTER * 2) { + printk(KERN_INFO "batman-adv:New originator interval too small: %li (min: %i)\n", + orig_interval_tmp, JITTER * 2); + return -EINVAL; + } + + if (atomic_read(&bat_priv->orig_interval) == orig_interval_tmp) + return count; + + printk(KERN_INFO "batman-adv:Changing originator interval from: %i to: %li on mesh: %s\n", + atomic_read(&bat_priv->orig_interval), + orig_interval_tmp, net_dev->name); + + atomic_set(&bat_priv->orig_interval, orig_interval_tmp); + return count; +} + static BAT_ATTR(aggregate_ogm, S_IRUGO | S_IWUSR, show_aggr_ogm, store_aggr_ogm); static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode); +static BAT_ATTR(orig_interval, S_IRUGO | S_IWUSR, + show_orig_interval, store_orig_interval); static struct bat_attribute *mesh_attrs[] = { &bat_attr_aggregate_ogm, &bat_attr_vis_mode, + &bat_attr_orig_interval, NULL, }; @@ -228,6 +274,7 @@ int sysfs_add_meshif(struct net_device *dev) routine as soon as we have it */ atomic_set(&bat_priv->aggregation_enabled, 1); atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE); + atomic_set(&bat_priv->orig_interval, 1000); bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR, batif_kobject); diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index 54e8cd5a32f3..7d726857023e 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -42,7 +42,6 @@ DEFINE_SPINLOCK(orig_hash_lock); DEFINE_SPINLOCK(forw_bat_list_lock); DEFINE_SPINLOCK(forw_bcast_list_lock); -atomic_t originator_interval; atomic_t vis_interval; int16_t num_hna; int16_t num_ifs; @@ -80,7 +79,6 @@ int init_module(void) atomic_set(&module_state, MODULE_INACTIVE); - atomic_set(&originator_interval, 1000); atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only * for debugging now. */ diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index b2283a75ee61..59a70c7e90c0 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -127,7 +127,6 @@ extern spinlock_t orig_hash_lock; extern spinlock_t forw_bat_list_lock; extern spinlock_t forw_bcast_list_lock; -extern atomic_t originator_interval; extern atomic_t vis_interval; extern int16_t num_hna; extern int16_t num_ifs; diff --git a/drivers/staging/batman-adv/proc.c b/drivers/staging/batman-adv/proc.c index cbea64212db7..25b24fe7b6af 100644 --- a/drivers/staging/batman-adv/proc.c +++ b/drivers/staging/batman-adv/proc.c @@ -29,7 +29,6 @@ #include "vis.h" static struct proc_dir_entry *proc_batman_dir, *proc_interface_file; -static struct proc_dir_entry *proc_orig_interval_file; static int proc_interfaces_read(struct seq_file *seq, void *offset) { @@ -121,57 +120,6 @@ end: return count; } -static int proc_orig_interval_read(struct seq_file *seq, void *offset) -{ - seq_printf(seq, "%i\n", atomic_read(&originator_interval)); - - return 0; -} - -static ssize_t proc_orig_interval_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *ppos) -{ - char *interval_string; - int not_copied = 0; - unsigned long originator_interval_tmp; - int retval; - - interval_string = kmalloc(count, GFP_KERNEL); - - if (!interval_string) - return -ENOMEM; - - not_copied = copy_from_user(interval_string, buffer, count); - interval_string[count - not_copied - 1] = 0; - - retval = strict_strtoul(interval_string, 10, &originator_interval_tmp); - if (retval) { - printk(KERN_ERR "batman-adv:New originator interval invalid\n"); - goto end; - } - - if (originator_interval_tmp <= JITTER * 2) { - printk(KERN_WARNING "batman-adv:New originator interval too small: %li (min: %i)\n", - originator_interval_tmp, JITTER * 2); - goto end; - } - - printk(KERN_INFO "batman-adv:Changing originator interval from: %i to: %li\n", - atomic_read(&originator_interval), originator_interval_tmp); - - atomic_set(&originator_interval, originator_interval_tmp); - -end: - kfree(interval_string); - return count; -} - -static int proc_orig_interval_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_orig_interval_read, NULL); -} - static const struct file_operations proc_interfaces_fops = { .owner = THIS_MODULE, .open = proc_interfaces_open, @@ -181,20 +129,8 @@ static const struct file_operations proc_interfaces_fops = { .release = single_release, }; -static const struct file_operations proc_orig_interval_fops = { - .owner = THIS_MODULE, - .open = proc_orig_interval_open, - .read = seq_read, - .write = proc_orig_interval_write, - .llseek = seq_lseek, - .release = single_release, -}; - void cleanup_procfs(void) { - if (proc_orig_interval_file) - remove_proc_entry(PROC_FILE_ORIG_INTERVAL, proc_batman_dir); - if (proc_interface_file) remove_proc_entry(PROC_FILE_INTERFACES, proc_batman_dir); @@ -230,16 +166,5 @@ int setup_procfs(void) return -EFAULT; } - proc_orig_interval_file = create_proc_entry(PROC_FILE_ORIG_INTERVAL, - S_IWUSR | S_IRUGO, - proc_batman_dir); - if (proc_orig_interval_file) { - proc_orig_interval_file->proc_fops = &proc_orig_interval_fops; - } else { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_ORIG_INTERVAL); - cleanup_procfs(); - return -EFAULT; - } - return 0; } diff --git a/drivers/staging/batman-adv/proc.h b/drivers/staging/batman-adv/proc.h index 6a972a6f26b1..6f4f5b3e7e02 100644 --- a/drivers/staging/batman-adv/proc.h +++ b/drivers/staging/batman-adv/proc.h @@ -24,7 +24,6 @@ #define PROC_ROOT_DIR "batman-adv" #define PROC_FILE_INTERFACES "interfaces" -#define PROC_FILE_ORIG_INTERVAL "orig_interval" void cleanup_procfs(void); int setup_procfs(void); diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index a00aa8871831..de2344a071c4 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -36,10 +36,10 @@ static uint8_t hop_penalty(const uint8_t tq) } /* when do we schedule our own packet to be sent */ -static unsigned long own_send_time(void) +static unsigned long own_send_time(struct bat_priv *bat_priv) { return jiffies + - (((atomic_read(&originator_interval) - JITTER + + (((atomic_read(&bat_priv->orig_interval) - JITTER + (random32() % 2*JITTER)) * HZ) / 1000); } @@ -277,7 +277,7 @@ void schedule_own_packet(struct batman_if *batman_if) atomic_inc(&batman_if->seqno); slide_own_bcast_window(batman_if); - send_time = own_send_time(); + send_time = own_send_time(bat_priv); add_bat_packet_to_list(bat_priv, batman_if->packet_buff, batman_if->packet_len, diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index e8d2e8c2c645..a8c6ad776df6 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -84,6 +84,7 @@ struct bat_priv { struct net_device_stats stats; atomic_t aggregation_enabled; atomic_t vis_mode; + atomic_t orig_interval; struct kobject *mesh_obj; }; -- cgit v1.2.3 From 35bd69d42e2fba4c0fd547e3bf99a0afd5700f76 Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Fri, 7 May 2010 21:47:21 +0200 Subject: Staging: batman-adv: remove redundant pointer to originator interface Signed-off-by: Marek Lindner Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/device.c | 2 +- drivers/staging/batman-adv/originator.c | 1 - drivers/staging/batman-adv/routing.c | 17 ++++------------- drivers/staging/batman-adv/soft-interface.c | 5 ++--- drivers/staging/batman-adv/types.h | 1 - drivers/staging/batman-adv/vis.c | 15 +++++++-------- 6 files changed, 14 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c index 9887f05925e1..c419c62bf7dd 100644 --- a/drivers/staging/batman-adv/device.c +++ b/drivers/staging/batman-adv/device.c @@ -250,7 +250,7 @@ ssize_t bat_device_write(struct file *file, const char __user *buff, if (!orig_node->router) goto unlock; - batman_if = orig_node->batman_if; + batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); spin_unlock_irqrestore(&orig_hash_lock, flags); diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 684db750cf16..4152701c3689 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -137,7 +137,6 @@ struct orig_node *get_orig_node(uint8_t *addr) memcpy(orig_node->orig, addr, ETH_ALEN); orig_node->router = NULL; - orig_node->batman_if = NULL; orig_node->hna_buff = NULL; size = num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS; diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 8c055a124cf2..0a9f52b8d35d 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -97,11 +97,6 @@ static void update_route(struct orig_node *orig_node, bat_dbg(DBG_ROUTES, "Changing route towards: %pM (now via %pM - was via %pM)\n", orig_node->orig, neigh_node->addr, orig_node->router->addr); } - if (neigh_node != NULL) - orig_node->batman_if = neigh_node->if_incoming; - else - orig_node->batman_if = NULL; - orig_node->router = neigh_node; } @@ -616,12 +611,11 @@ static int recv_my_icmp_packet(struct sk_buff *skb) ret = NET_RX_DROP; if ((orig_node != NULL) && - (orig_node->batman_if != NULL) && (orig_node->router != NULL)) { /* don't lock while sending the packets ... we therefore * copy the required data before sending */ - batman_if = orig_node->batman_if; + batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); spin_unlock_irqrestore(&orig_hash_lock, flags); @@ -678,12 +672,11 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb) ret = NET_RX_DROP; if ((orig_node != NULL) && - (orig_node->batman_if != NULL) && (orig_node->router != NULL)) { /* don't lock while sending the packets ... we therefore * copy the required data before sending */ - batman_if = orig_node->batman_if; + batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); spin_unlock_irqrestore(&orig_hash_lock, flags); @@ -760,12 +753,11 @@ int recv_icmp_packet(struct sk_buff *skb) hash_find(orig_hash, icmp_packet->dst)); if ((orig_node != NULL) && - (orig_node->batman_if != NULL) && (orig_node->router != NULL)) { /* don't lock while sending the packets ... we therefore * copy the required data before sending */ - batman_if = orig_node->batman_if; + batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); spin_unlock_irqrestore(&orig_hash_lock, flags); @@ -844,12 +836,11 @@ int recv_unicast_packet(struct sk_buff *skb) hash_find(orig_hash, unicast_packet->dest)); if ((orig_node != NULL) && - (orig_node->batman_if != NULL) && (orig_node->router != NULL)) { /* don't lock while sending the packets ... we therefore * copy the required data before sending */ - batman_if = orig_node->batman_if; + batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); spin_unlock_irqrestore(&orig_hash_lock, flags); diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 829deb694b84..4cdebe5f874f 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -236,7 +236,6 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) orig_node = transtable_search(ethhdr->h_dest); if ((orig_node) && - (orig_node->batman_if) && (orig_node->router)) { if (my_skb_push(skb, sizeof(struct unicast_packet)) < 0) goto unlock; @@ -252,13 +251,13 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); /* net_dev won't be available when not active */ - if (orig_node->batman_if->if_active != IF_ACTIVE) + if (orig_node->router->if_incoming->if_active != IF_ACTIVE) goto unlock; /* don't lock while sending the packets ... we therefore * copy the required data before sending */ - batman_if = orig_node->batman_if; + batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); spin_unlock_irqrestore(&orig_hash_lock, flags); diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index a8c6ad776df6..ffaa16c30af6 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -49,7 +49,6 @@ struct batman_if { struct orig_node { /* structure for orig_list maintaining nodes of mesh */ uint8_t orig[ETH_ALEN]; struct neigh_node *router; - struct batman_if *batman_if; TYPE_OF_WORD *bcast_own; uint8_t *bcast_own_sum; uint8_t tq_own; diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index 5edeb3261ac1..57d69d70671e 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -498,14 +498,14 @@ static int generate_vis_packet(struct bat_priv *bat_priv) if (orig_node->router != NULL && compare_orig(orig_node->router->addr, orig_node->orig) - && orig_node->batman_if - && (orig_node->batman_if->if_active == IF_ACTIVE) + && (orig_node->router->if_incoming->if_active == + IF_ACTIVE) && orig_node->router->tq_avg > 0) { /* fill one entry into buffer. */ entry = &entry_array[info->packet.entries]; memcpy(entry->src, - orig_node->batman_if->net_dev->dev_addr, + orig_node->router->if_incoming->net_dev->dev_addr, ETH_ALEN); memcpy(entry->dest, orig_node->orig, ETH_ALEN); entry->quality = orig_node->router->tq_avg; @@ -573,8 +573,7 @@ static void broadcast_vis_packet(struct vis_info *info, int packet_length) orig_node = hashit.bucket->data; /* if it's a vis server and reachable, send it. */ - if ((!orig_node) || (!orig_node->batman_if) || - (!orig_node->router)) + if ((!orig_node) || (!orig_node->router)) continue; if (!(orig_node->flags & VIS_SERVER)) continue; @@ -584,7 +583,7 @@ static void broadcast_vis_packet(struct vis_info *info, int packet_length) continue; memcpy(info->packet.target_orig, orig_node->orig, ETH_ALEN); - batman_if = orig_node->batman_if; + batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); spin_unlock_irqrestore(&orig_hash_lock, flags); @@ -609,12 +608,12 @@ static void unicast_vis_packet(struct vis_info *info, int packet_length) orig_node = ((struct orig_node *) hash_find(orig_hash, info->packet.target_orig)); - if ((!orig_node) || (!orig_node->batman_if) || (!orig_node->router)) + if ((!orig_node) || (!orig_node->router)) goto out; /* don't lock while sending the packets ... we therefore * copy the required data before sending */ - batman_if = orig_node->batman_if; + batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); spin_unlock_irqrestore(&orig_hash_lock, flags); -- cgit v1.2.3 From 208e13e4297a1d9b986aa371c4529df7dda1c835 Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Fri, 7 May 2010 21:47:22 +0200 Subject: Staging: batman-adv: move /proc interface handling to /sys Instead of having a single /proc file "interfaces" in which you have to echo the wanted interface batman-adv will create a subfolder in each suitable /sys/class/net folder. This subfolder contains files for the interface specific settings. For example, mesh_iface to add/remove an interface from a virtual mesh network (at the moment only bat0 is supported). Example: echo bat0 > /sys/class/net/eth0/batman-adv/mesh_iface to deactivate: echo none > /sys/class/net/eth0/batman-adv/mesh_iface Interfaces which are not compatible with batman-adv won't contain the batman-adv folder, therefore can't be activated. Not supported are: loopback, non-ethernet, non-ARP and virtual mesh network interfaces Signed-off-by: Marek Lindner Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/Makefile | 2 +- drivers/staging/batman-adv/bat_sysfs.c | 147 +++++++ drivers/staging/batman-adv/bat_sysfs.h | 3 + drivers/staging/batman-adv/device.c | 2 +- drivers/staging/batman-adv/hard-interface.c | 515 +++++++++++++------------ drivers/staging/batman-adv/hard-interface.h | 18 +- drivers/staging/batman-adv/main.c | 21 +- drivers/staging/batman-adv/main.h | 3 +- drivers/staging/batman-adv/originator.c | 193 ++++++++- drivers/staging/batman-adv/originator.h | 2 + drivers/staging/batman-adv/proc.c | 170 -------- drivers/staging/batman-adv/proc.h | 30 -- drivers/staging/batman-adv/routing.c | 6 +- drivers/staging/batman-adv/send.c | 59 ++- drivers/staging/batman-adv/send.h | 2 +- drivers/staging/batman-adv/soft-interface.c | 2 +- drivers/staging/batman-adv/translation-table.c | 14 +- drivers/staging/batman-adv/types.h | 5 +- drivers/staging/batman-adv/vis.c | 9 +- 19 files changed, 670 insertions(+), 533 deletions(-) delete mode 100644 drivers/staging/batman-adv/proc.c delete mode 100644 drivers/staging/batman-adv/proc.h (limited to 'drivers') diff --git a/drivers/staging/batman-adv/Makefile b/drivers/staging/batman-adv/Makefile index 9ad042991616..f25068c0fae6 100644 --- a/drivers/staging/batman-adv/Makefile +++ b/drivers/staging/batman-adv/Makefile @@ -19,4 +19,4 @@ # obj-m += batman-adv.o -batman-adv-objs := main.o proc.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o bat_sysfs.o +batman-adv-objs := main.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o bat_sysfs.o diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c index ea7ce775009a..1811c8da6609 100644 --- a/drivers/staging/batman-adv/bat_sysfs.c +++ b/drivers/staging/batman-adv/bat_sysfs.c @@ -36,6 +36,14 @@ struct bat_attribute { char *buf, size_t count); }; +struct hardif_attribute { + struct attribute attr; + ssize_t (*show)(struct kobject *kobj, struct attribute *attr, + char *buf); + ssize_t (*store)(struct kobject *kobj, struct attribute *attr, + char *buf, size_t count); +}; + #define BAT_ATTR(_name, _mode, _show, _store) \ struct bat_attribute bat_attr_##_name = { \ .attr = {.name = __stringify(_name), \ @@ -52,6 +60,14 @@ struct bin_attribute bat_attr_##_name = { \ .write = _write, \ }; +#define HARDIF_ATTR(_name, _mode, _show, _store) \ +struct hardif_attribute hardif_attr_##_name = { \ + .attr = {.name = __stringify(_name), \ + .mode = _mode }, \ + .show = _show, \ + .store = _store, \ +}; + static ssize_t show_aggr_ogm(struct kobject *kobj, struct attribute *attr, char *buff) { @@ -275,6 +291,8 @@ int sysfs_add_meshif(struct net_device *dev) atomic_set(&bat_priv->aggregation_enabled, 1); atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE); atomic_set(&bat_priv->orig_interval, 1000); + bat_priv->primary_if = NULL; + bat_priv->num_ifaces = 0; bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR, batif_kobject); @@ -335,3 +353,132 @@ void sysfs_del_meshif(struct net_device *dev) kobject_put(bat_priv->mesh_obj); bat_priv->mesh_obj = NULL; } + +static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr, + char *buff) +{ + struct device *dev = to_dev(kobj->parent); + struct net_device *net_dev = to_net_dev(dev); + struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); + + if (!batman_if) + return 0; + + return sprintf(buff, "status: %s\ncommands: none, bat0 \n", + batman_if->if_status == IF_NOT_IN_USE ? + "none" : "bat0"); +} + +static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr, + char *buff, size_t count) +{ + struct device *dev = to_dev(kobj->parent); + struct net_device *net_dev = to_net_dev(dev); + struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); + int status_tmp = -1; + + if (!batman_if) + return count; + + if (strncmp(buff, "none", 4) == 0) + status_tmp = IF_NOT_IN_USE; + + if (strncmp(buff, "bat0", 4) == 0) + status_tmp = IF_I_WANT_YOU; + + if (status_tmp < 0) { + if (buff[count - 1] == '\n') + buff[count - 1] = '\0'; + + printk(KERN_ERR "batman-adv:Invalid parameter for 'mesh_iface' setting received: %s\n", + buff); + return -EINVAL; + } + + if ((batman_if->if_status == status_tmp) || + ((status_tmp == IF_I_WANT_YOU) && + (batman_if->if_status != IF_NOT_IN_USE))) + return count; + + if (status_tmp == IF_I_WANT_YOU) + status_tmp = hardif_enable_interface(batman_if); + else + hardif_disable_interface(batman_if); + + return (status_tmp < 0 ? status_tmp : count); +} + +static ssize_t show_iface_status(struct kobject *kobj, struct attribute *attr, + char *buff) +{ + struct device *dev = to_dev(kobj->parent); + struct net_device *net_dev = to_net_dev(dev); + struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); + + if (!batman_if) + return 0; + + switch (batman_if->if_status) { + case IF_TO_BE_REMOVED: + return sprintf(buff, "disabling\n"); + case IF_INACTIVE: + return sprintf(buff, "inactive\n"); + case IF_ACTIVE: + return sprintf(buff, "active\n"); + case IF_TO_BE_ACTIVATED: + return sprintf(buff, "enabling\n"); + case IF_NOT_IN_USE: + default: + return sprintf(buff, "not in use\n"); + } +} + +static HARDIF_ATTR(mesh_iface, S_IRUGO | S_IWUSR, + show_mesh_iface, store_mesh_iface); +static HARDIF_ATTR(iface_status, S_IRUGO, show_iface_status, NULL); + +static struct hardif_attribute *batman_attrs[] = { + &hardif_attr_mesh_iface, + &hardif_attr_iface_status, + NULL, +}; + +int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev) +{ + struct kobject *hardif_kobject = &dev->dev.kobj; + struct hardif_attribute **hardif_attr; + int err; + + *hardif_obj = kobject_create_and_add(SYSFS_IF_BAT_SUBDIR, + hardif_kobject); + + if (!*hardif_obj) { + printk(KERN_ERR "batman-adv:Can't add sysfs directory: %s/%s\n", + dev->name, SYSFS_IF_BAT_SUBDIR); + goto out; + } + + for (hardif_attr = batman_attrs; *hardif_attr; ++hardif_attr) { + err = sysfs_create_file(*hardif_obj, &((*hardif_attr)->attr)); + if (err) { + printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n", + dev->name, SYSFS_IF_BAT_SUBDIR, + ((*hardif_attr)->attr).name); + goto rem_attr; + } + } + + return 0; + +rem_attr: + for (hardif_attr = batman_attrs; *hardif_attr; ++hardif_attr) + sysfs_remove_file(*hardif_obj, &((*hardif_attr)->attr)); +out: + return -ENOMEM; +} + +void sysfs_del_hardif(struct kobject **hardif_obj) +{ + kobject_put(*hardif_obj); + *hardif_obj = NULL; +} diff --git a/drivers/staging/batman-adv/bat_sysfs.h b/drivers/staging/batman-adv/bat_sysfs.h index 671ebd1aac35..e1893411871e 100644 --- a/drivers/staging/batman-adv/bat_sysfs.h +++ b/drivers/staging/batman-adv/bat_sysfs.h @@ -21,6 +21,9 @@ #define SYSFS_IF_MESH_SUBDIR "mesh" +#define SYSFS_IF_BAT_SUBDIR "batman_adv" int sysfs_add_meshif(struct net_device *dev); void sysfs_del_meshif(struct net_device *dev); +int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev); +void sysfs_del_hardif(struct kobject **hardif_obj); diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c index c419c62bf7dd..b2ecba2d40ab 100644 --- a/drivers/staging/batman-adv/device.c +++ b/drivers/staging/batman-adv/device.c @@ -258,7 +258,7 @@ ssize_t bat_device_write(struct file *file, const char __user *buff, if (!batman_if) goto dst_unreach; - if (batman_if->if_active != IF_ACTIVE) + if (batman_if->if_status != IF_ACTIVE) goto dst_unreach; memcpy(icmp_packet.orig, diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c index cb9e9272a797..b82cae79c42b 100644 --- a/drivers/staging/batman-adv/hard-interface.c +++ b/drivers/staging/batman-adv/hard-interface.c @@ -25,22 +25,21 @@ #include "send.h" #include "translation-table.h" #include "routing.h" +#include "bat_sysfs.h" +#include "originator.h" #include "hash.h" -#define MIN(x, y) ((x) < (y) ? (x) : (y)) - -static char avail_ifs; -static char active_ifs; +#include -static void hardif_free_interface(struct rcu_head *rcu); +#define MIN(x, y) ((x) < (y) ? (x) : (y)) -static struct batman_if *get_batman_if_by_name(char *name) +struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev) { struct batman_if *batman_if; rcu_read_lock(); list_for_each_entry_rcu(batman_if, &if_list, list) { - if (strncmp(batman_if->dev, name, IFNAMSIZ) == 0) + if (batman_if->net_dev == net_dev) goto out; } @@ -51,23 +50,90 @@ out: return batman_if; } -int hardif_min_mtu(void) +static int is_valid_iface(struct net_device *net_dev) +{ + if (net_dev->flags & IFF_LOOPBACK) + return 0; + + if (net_dev->type != ARPHRD_ETHER) + return 0; + + if (net_dev->addr_len != ETH_ALEN) + return 0; + + /* no batman over batman */ +#ifdef HAVE_NET_DEVICE_OPS + if (net_dev->netdev_ops->ndo_start_xmit == interface_tx) + return 0; +#else + if (net_dev->hard_start_xmit == interface_tx) + return 0; +#endif + + /* Device is being bridged */ + /* if (net_dev->br_port != NULL) + return 0; */ + + return 1; +} + +static struct batman_if *get_active_batman_if(void) { struct batman_if *batman_if; - /* allow big frames if all devices are capable to do so - * (have MTU > 1500 + BAT_HEADER_LEN) */ - int min_mtu = ETH_DATA_LEN; + /* TODO: should check interfaces belonging to bat_priv */ rcu_read_lock(); list_for_each_entry_rcu(batman_if, &if_list, list) { - if ((batman_if->if_active == IF_ACTIVE) || - (batman_if->if_active == IF_TO_BE_ACTIVATED)) - min_mtu = MIN(batman_if->net_dev->mtu - BAT_HEADER_LEN, - min_mtu); + if (batman_if->if_status == IF_ACTIVE) + goto out; } + + batman_if = NULL; + +out: rcu_read_unlock(); + return batman_if; +} - return min_mtu; +static void set_primary_if(struct bat_priv *bat_priv, + struct batman_if *batman_if) +{ + struct batman_packet *batman_packet; + + bat_priv->primary_if = batman_if; + + if (!bat_priv->primary_if) + return; + + set_main_if_addr(batman_if->net_dev->dev_addr); + + batman_packet = (struct batman_packet *)(batman_if->packet_buff); + batman_packet->flags = 0; + batman_packet->ttl = TTL; + + /*** + * hacky trick to make sure that we send the HNA information via + * our new primary interface + */ + atomic_set(&hna_local_changed, 1); +} + +static bool hardif_is_iface_up(struct batman_if *batman_if) +{ + if (batman_if->net_dev->flags & IFF_UP) + return true; + + return false; +} + +static void update_mac_addresses(struct batman_if *batman_if) +{ + addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr); + + memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig, + batman_if->net_dev->dev_addr, ETH_ALEN); + memcpy(((struct batman_packet *)(batman_if->packet_buff))->prev_sender, + batman_if->net_dev->dev_addr, ETH_ALEN); } static void check_known_mac_addr(uint8_t *addr) @@ -76,8 +142,8 @@ static void check_known_mac_addr(uint8_t *addr) rcu_read_lock(); list_for_each_entry_rcu(batman_if, &if_list, list) { - if ((batman_if->if_active != IF_ACTIVE) && - (batman_if->if_active != IF_TO_BE_ACTIVATED)) + if ((batman_if->if_status != IF_ACTIVE) && + (batman_if->if_status != IF_TO_BE_ACTIVATED)) continue; if (!compare_orig(batman_if->net_dev->dev_addr, addr)) @@ -90,6 +156,25 @@ static void check_known_mac_addr(uint8_t *addr) rcu_read_unlock(); } +int hardif_min_mtu(void) +{ + struct batman_if *batman_if; + /* allow big frames if all devices are capable to do so + * (have MTU > 1500 + BAT_HEADER_LEN) */ + int min_mtu = ETH_DATA_LEN; + + rcu_read_lock(); + list_for_each_entry_rcu(batman_if, &if_list, list) { + if ((batman_if->if_status == IF_ACTIVE) || + (batman_if->if_status == IF_TO_BE_ACTIVATED)) + min_mtu = MIN(batman_if->net_dev->mtu - BAT_HEADER_LEN, + min_mtu); + } + rcu_read_unlock(); + + return min_mtu; +} + /* adjusts the MTU if a new interface with a smaller MTU appeared. */ void update_min_mtu(void) { @@ -100,322 +185,246 @@ void update_min_mtu(void) soft_device->mtu = min_mtu; } -/* checks if the interface is up. (returns 1 if it is) */ -static int hardif_is_interface_up(char *dev) +static void hardif_activate_interface(struct bat_priv *bat_priv, + struct batman_if *batman_if) { - struct net_device *net_dev; + if (batman_if->if_status != IF_INACTIVE) + return; - /** - * if we already have an interface in our interface list and - * the current interface is not the primary interface and - * the primary interface is not up and - * the primary interface has never been up - don't activate any - * secondary interface ! - */ + dev_hold(batman_if->net_dev); - rcu_read_lock(); - if ((!list_empty(&if_list)) && - strncmp(((struct batman_if *)if_list.next)->dev, dev, IFNAMSIZ) && - !(((struct batman_if *)if_list.next)->if_active == IF_ACTIVE) && - !(((struct batman_if *)if_list.next)->if_active == IF_TO_BE_ACTIVATED) && - (!main_if_was_up())) { - rcu_read_unlock(); - goto end; - } - rcu_read_unlock(); + update_mac_addresses(batman_if); + batman_if->if_status = IF_TO_BE_ACTIVATED; -#ifdef __NET_NET_NAMESPACE_H - net_dev = dev_get_by_name(&init_net, dev); -#else - net_dev = dev_get_by_name(dev); -#endif - if (!net_dev) - goto end; + /** + * the first active interface becomes our primary interface or + * the next active interface after the old primay interface was removed + */ + if (!bat_priv->primary_if) + set_primary_if(bat_priv, batman_if); - if (!(net_dev->flags & IFF_UP)) - goto failure; + printk(KERN_INFO "batman-adv:Interface activated: %s\n", + batman_if->dev); - dev_put(net_dev); - return 1; + if (atomic_read(&module_state) == MODULE_INACTIVE) + activate_module(); -failure: - dev_put(net_dev); -end: - return 0; + update_min_mtu(); + return; } -/* deactivates the interface. */ -void hardif_deactivate_interface(struct batman_if *batman_if) +static void hardif_deactivate_interface(struct batman_if *batman_if) { - if (batman_if->if_active != IF_ACTIVE) + if ((batman_if->if_status != IF_ACTIVE) && + (batman_if->if_status != IF_TO_BE_ACTIVATED)) return; - /** - * batman_if->net_dev has been acquired by dev_get_by_name() in - * proc_interfaces_write() and has to be unreferenced. - */ - - if (batman_if->net_dev) - dev_put(batman_if->net_dev); + dev_put(batman_if->net_dev); - batman_if->if_active = IF_INACTIVE; - active_ifs--; + batman_if->if_status = IF_INACTIVE; printk(KERN_INFO "batman-adv:Interface deactivated: %s\n", - batman_if->dev); + batman_if->dev); + + update_min_mtu(); } -/* (re)activate given interface. */ -static void hardif_activate_interface(struct batman_if *batman_if) +int hardif_enable_interface(struct batman_if *batman_if) { - if (batman_if->if_active != IF_INACTIVE) - return; - -#ifdef __NET_NET_NAMESPACE_H - batman_if->net_dev = dev_get_by_name(&init_net, batman_if->dev); -#else - batman_if->net_dev = dev_get_by_name(batman_if->dev); -#endif - if (!batman_if->net_dev) - goto dev_err; + /* FIXME: each batman_if will be attached to a softif */ + struct bat_priv *bat_priv = netdev_priv(soft_device); + struct batman_packet *batman_packet; - check_known_mac_addr(batman_if->net_dev->dev_addr); + if (batman_if->if_status != IF_NOT_IN_USE) + goto out; - addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr); + batman_if->packet_len = BAT_PACKET_LEN; + batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_ATOMIC); - memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig, - batman_if->net_dev->dev_addr, ETH_ALEN); - memcpy(((struct batman_packet *)(batman_if->packet_buff))->prev_sender, - batman_if->net_dev->dev_addr, ETH_ALEN); + if (!batman_if->packet_buff) { + printk(KERN_ERR "batman-adv:Can't add interface packet (%s): out of memory\n", + batman_if->dev); + goto err; + } - batman_if->if_active = IF_TO_BE_ACTIVATED; - active_ifs++; + batman_packet = (struct batman_packet *)(batman_if->packet_buff); + batman_packet->packet_type = BAT_PACKET; + batman_packet->version = COMPAT_VERSION; + batman_packet->flags = 0; + batman_packet->ttl = 2; + batman_packet->tq = TQ_MAX_VALUE; + batman_packet->num_hna = 0; - /* save the mac address if it is our primary interface */ - if (batman_if->if_num == 0) - set_main_if_addr(batman_if->net_dev->dev_addr); + batman_if->if_num = bat_priv->num_ifaces; + bat_priv->num_ifaces++; + batman_if->if_status = IF_INACTIVE; + orig_hash_add_if(batman_if, bat_priv->num_ifaces); - printk(KERN_INFO "batman-adv:Interface activated: %s\n", - batman_if->dev); + atomic_set(&batman_if->seqno, 1); + printk(KERN_INFO "batman-adv:Adding interface: %s\n", batman_if->dev); - return; + if (hardif_is_iface_up(batman_if)) + hardif_activate_interface(bat_priv, batman_if); + else + printk(KERN_ERR "batman-adv:Not using interface %s (retrying later): interface not active\n", batman_if->dev); -dev_err: - batman_if->net_dev = NULL; -} + /* begin scheduling originator messages on that interface */ + schedule_own_packet(batman_if); -static void hardif_free_interface(struct rcu_head *rcu) -{ - struct batman_if *batman_if = container_of(rcu, struct batman_if, rcu); +out: + return 0; - kfree(batman_if->packet_buff); - kfree(batman_if->dev); - kfree(batman_if); +err: + return -ENOMEM; } -/** - * called by - * - echo '' > /proc/.../interfaces - * - modprobe -r batman-adv-core - */ -/* removes and frees all interfaces */ -void hardif_remove_interfaces(void) +void hardif_disable_interface(struct batman_if *batman_if) { - struct batman_if *batman_if = NULL; - - avail_ifs = 0; - - /* no lock needed - we don't delete somewhere else */ - list_for_each_entry(batman_if, &if_list, list) { - - list_del_rcu(&batman_if->list); + /* FIXME: each batman_if will be attached to a softif */ + struct bat_priv *bat_priv = netdev_priv(soft_device); - /* first deactivate interface */ - if (batman_if->if_active != IF_INACTIVE) - hardif_deactivate_interface(batman_if); - - call_rcu(&batman_if->rcu, hardif_free_interface); - } -} - -static int resize_orig(struct orig_node *orig_node, int if_num) -{ - void *data_ptr; + if (batman_if->if_status == IF_ACTIVE) + hardif_deactivate_interface(batman_if); - data_ptr = kmalloc((if_num + 1) * sizeof(TYPE_OF_WORD) * NUM_WORDS, - GFP_ATOMIC); - if (!data_ptr) { - printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); - return -1; - } + if (batman_if->if_status != IF_INACTIVE) + return; - memcpy(data_ptr, orig_node->bcast_own, - if_num * sizeof(TYPE_OF_WORD) * NUM_WORDS); - kfree(orig_node->bcast_own); - orig_node->bcast_own = data_ptr; + printk(KERN_INFO "batman-adv:Removing interface: %s\n", batman_if->dev); + bat_priv->num_ifaces--; + orig_hash_del_if(batman_if, bat_priv->num_ifaces); - data_ptr = kmalloc((if_num + 1) * sizeof(uint8_t), GFP_ATOMIC); - if (!data_ptr) { - printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); - return -1; - } + if (batman_if == bat_priv->primary_if) + set_primary_if(bat_priv, get_active_batman_if()); - memcpy(data_ptr, orig_node->bcast_own_sum, if_num * sizeof(uint8_t)); - kfree(orig_node->bcast_own_sum); - orig_node->bcast_own_sum = data_ptr; + kfree(batman_if->packet_buff); + batman_if->packet_buff = NULL; + batman_if->if_status = IF_NOT_IN_USE; - return 0; + if ((atomic_read(&module_state) == MODULE_ACTIVE) && + (bat_priv->num_ifaces == 0)) + deactivate_module(); } - -/* adds an interface the interface list and activate it, if possible */ -int hardif_add_interface(char *dev, int if_num) +static struct batman_if *hardif_add_interface(struct net_device *net_dev) { struct batman_if *batman_if; - struct batman_packet *batman_packet; - struct orig_node *orig_node; - unsigned long flags; - HASHIT(hashit); + int ret; - batman_if = kmalloc(sizeof(struct batman_if), GFP_KERNEL); + ret = is_valid_iface(net_dev); + if (ret != 1) + goto out; + batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC); if (!batman_if) { - printk(KERN_ERR "batman-adv:Can't add interface (%s): out of memory\n", dev); - return -1; - } - - batman_if->net_dev = NULL; - - if ((if_num == 0) && (num_hna > 0)) - batman_if->packet_len = BAT_PACKET_LEN + num_hna * ETH_ALEN; - else - batman_if->packet_len = BAT_PACKET_LEN; - - batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_KERNEL); - - if (!batman_if->packet_buff) { - printk(KERN_ERR "batman-adv:Can't add interface packet (%s): out of memory\n", dev); + printk(KERN_ERR "batman-adv:Can't add interface (%s): out of memory\n", + net_dev->name); goto out; } - batman_if->if_num = if_num; - batman_if->dev = dev; - batman_if->if_active = IF_INACTIVE; - INIT_RCU_HEAD(&batman_if->rcu); + batman_if->dev = kstrdup(net_dev->name, GFP_ATOMIC); + if (!batman_if->dev) + goto free_if; - printk(KERN_INFO "batman-adv:Adding interface: %s\n", dev); - avail_ifs++; + ret = sysfs_add_hardif(&batman_if->hardif_obj, net_dev); + if (ret) + goto free_dev; + batman_if->if_num = -1; + batman_if->net_dev = net_dev; + batman_if->if_status = IF_NOT_IN_USE; + INIT_RCU_HEAD(&batman_if->rcu); INIT_LIST_HEAD(&batman_if->list); - batman_packet = (struct batman_packet *)(batman_if->packet_buff); - batman_packet->packet_type = BAT_PACKET; - batman_packet->version = COMPAT_VERSION; - batman_packet->flags = 0x00; - batman_packet->ttl = (batman_if->if_num > 0 ? 2 : TTL); - batman_packet->flags = 0; - batman_packet->tq = TQ_MAX_VALUE; - batman_packet->num_hna = 0; - - if (batman_if->packet_len != BAT_PACKET_LEN) { - unsigned char *hna_buff; - int hna_len; - - hna_buff = batman_if->packet_buff + BAT_PACKET_LEN; - hna_len = batman_if->packet_len - BAT_PACKET_LEN; - batman_packet->num_hna = hna_local_fill_buffer(hna_buff, - hna_len); - } - - atomic_set(&batman_if->seqno, 1); + check_known_mac_addr(batman_if->net_dev->dev_addr); + list_add_tail_rcu(&batman_if->list, &if_list); + return batman_if; - /* resize all orig nodes because orig_node->bcast_own(_sum) depend on - * if_num */ - spin_lock_irqsave(&orig_hash_lock, flags); +free_dev: + kfree(batman_if->dev); +free_if: + kfree(batman_if); +out: + return NULL; +} - while (hash_iterate(orig_hash, &hashit)) { - orig_node = hashit.bucket->data; - if (resize_orig(orig_node, if_num) == -1) { - spin_unlock_irqrestore(&orig_hash_lock, flags); - goto out; - } - } +static void hardif_free_interface(struct rcu_head *rcu) +{ + struct batman_if *batman_if = container_of(rcu, struct batman_if, rcu); - spin_unlock_irqrestore(&orig_hash_lock, flags); + /* delete all references to this batman_if */ + purge_orig(NULL); + purge_outstanding_packets(batman_if); - if (!hardif_is_interface_up(batman_if->dev)) - printk(KERN_ERR "batman-adv:Not using interface %s (retrying later): interface not active\n", batman_if->dev); - else - hardif_activate_interface(batman_if); + kfree(batman_if->dev); + kfree(batman_if); +} - list_add_tail_rcu(&batman_if->list, &if_list); +static void hardif_remove_interface(struct batman_if *batman_if) +{ + /* first deactivate interface */ + if (batman_if->if_status != IF_NOT_IN_USE) + hardif_disable_interface(batman_if); - /* begin sending originator messages on that interface */ - schedule_own_packet(batman_if); - return 1; + if (batman_if->if_status != IF_NOT_IN_USE) + return; -out: - kfree(batman_if->packet_buff); - kfree(batman_if); - kfree(dev); - return -1; + batman_if->if_status = IF_TO_BE_REMOVED; + list_del_rcu(&batman_if->list); + sysfs_del_hardif(&batman_if->hardif_obj); + call_rcu(&batman_if->rcu, hardif_free_interface); } -char hardif_get_active_if_num(void) +void hardif_remove_interfaces(void) { - return active_ifs; + struct batman_if *batman_if, *batman_if_tmp; + + list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list) + hardif_remove_interface(batman_if); } static int hard_if_event(struct notifier_block *this, - unsigned long event, void *ptr) + unsigned long event, void *ptr) { - struct net_device *dev = (struct net_device *)ptr; - struct batman_if *batman_if = get_batman_if_by_name(dev->name); + struct net_device *net_dev = (struct net_device *)ptr; + struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); + /* FIXME: each batman_if will be attached to a softif */ + struct bat_priv *bat_priv = netdev_priv(soft_device); + + if (!batman_if) + batman_if = hardif_add_interface(net_dev); if (!batman_if) goto out; switch (event) { + case NETDEV_REGISTER: + break; + case NETDEV_UP: + hardif_activate_interface(bat_priv, batman_if); + break; case NETDEV_GOING_DOWN: case NETDEV_DOWN: - case NETDEV_UNREGISTER: hardif_deactivate_interface(batman_if); break; - case NETDEV_UP: - hardif_activate_interface(batman_if); - if ((atomic_read(&module_state) == MODULE_INACTIVE) && - (hardif_get_active_if_num() > 0)) { - activate_module(); - } + case NETDEV_UNREGISTER: + hardif_remove_interface(batman_if); + break; + case NETDEV_CHANGENAME: + break; + case NETDEV_CHANGEADDR: + check_known_mac_addr(batman_if->net_dev->dev_addr); + update_mac_addresses(batman_if); + if (batman_if == bat_priv->primary_if) + set_primary_if(bat_priv, batman_if); break; - /* NETDEV_CHANGEADDR - mac address change - what are we doing here ? */ default: break; }; - update_min_mtu(); - out: return NOTIFY_DONE; } -/* find batman interface by netdev. assumes rcu_read_lock on */ -static struct batman_if *find_batman_if(struct net_device *dev) -{ - struct batman_if *batman_if; - - rcu_read_lock(); - list_for_each_entry_rcu(batman_if, &if_list, list) { - if (batman_if->net_dev == dev) { - rcu_read_unlock(); - return batman_if; - } - } - rcu_read_unlock(); - return NULL; -} - - /* receive a packet with the batman ethertype coming on a hard * interface */ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, @@ -444,12 +453,12 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, || !skb_mac_header(skb))) goto err_free; - batman_if = find_batman_if(skb->dev); + batman_if = get_batman_if_by_netdev(skb->dev); if (!batman_if) goto err_free; /* discard frames on not active interfaces */ - if (batman_if->if_active != IF_ACTIVE) + if (batman_if->if_status != IF_ACTIVE) goto err_free; stats = (struct net_device_stats *)dev_get_stats(skb->dev); diff --git a/drivers/staging/batman-adv/hard-interface.h b/drivers/staging/batman-adv/hard-interface.h index 4100a276c498..1e5fc3e720f4 100644 --- a/drivers/staging/batman-adv/hard-interface.h +++ b/drivers/staging/batman-adv/hard-interface.h @@ -19,19 +19,19 @@ * */ -#define IF_INACTIVE 0 -#define IF_ACTIVE 1 -/* #define IF_TO_BE_DEACTIVATED 2 - not needed anymore */ -#define IF_TO_BE_ACTIVATED 3 +#define IF_NOT_IN_USE 0 +#define IF_TO_BE_REMOVED 1 +#define IF_INACTIVE 2 +#define IF_ACTIVE 3 +#define IF_TO_BE_ACTIVATED 4 +#define IF_I_WANT_YOU 5 extern struct notifier_block hard_if_notifier; +struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev); +int hardif_enable_interface(struct batman_if *batman_if); +void hardif_disable_interface(struct batman_if *batman_if); void hardif_remove_interfaces(void); -int hardif_add_interface(char *dev, int if_num); -void hardif_deactivate_interface(struct batman_if *batman_if); -char hardif_get_active_if_num(void); -void hardif_check_interfaces_status(void); -void hardif_check_interfaces_status_wq(struct work_struct *work); int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index 7d726857023e..c1e57aaf2e5a 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -20,7 +20,6 @@ */ #include "main.h" -#include "proc.h" #include "bat_sysfs.h" #include "routing.h" #include "send.h" @@ -44,7 +43,6 @@ DEFINE_SPINLOCK(forw_bcast_list_lock); atomic_t vis_interval; int16_t num_hna; -int16_t num_ifs; struct net_device *soft_device; @@ -89,10 +87,6 @@ int init_module(void) if (!bat_event_workqueue) return -ENOMEM; - retval = setup_procfs(); - if (retval < 0) - return retval; - bat_device_init(); /* initialize layer 2 interface */ @@ -135,7 +129,10 @@ end: void cleanup_module(void) { - shutdown_module(); + deactivate_module(); + + unregister_netdevice_notifier(&hard_if_notifier); + hardif_remove_interfaces(); if (soft_device) { sysfs_del_meshif(soft_device); @@ -145,9 +142,6 @@ void cleanup_module(void) dev_remove_pack(&batman_adv_packet_type); - unregister_netdevice_notifier(&hard_if_notifier); - cleanup_procfs(); - destroy_workqueue(bat_event_workqueue); bat_event_workqueue = NULL; } @@ -178,17 +172,17 @@ void activate_module(void) err: printk(KERN_ERR "batman-adv:Unable to allocate memory for mesh information structures: out of mem ?\n"); - shutdown_module(); + deactivate_module(); end: return; } /* shuts down the whole module.*/ -void shutdown_module(void) +void deactivate_module(void) { atomic_set(&module_state, MODULE_DEACTIVATING); - purge_outstanding_packets(); + purge_outstanding_packets(NULL); flush_workqueue(bat_event_workqueue); vis_quit(); @@ -203,7 +197,6 @@ void shutdown_module(void) synchronize_net(); bat_device_destroy(); - hardif_remove_interfaces(); synchronize_rcu(); atomic_set(&module_state, MODULE_INACTIVE); } diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 59a70c7e90c0..247196ca7515 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -129,7 +129,6 @@ extern spinlock_t forw_bcast_list_lock; extern atomic_t vis_interval; extern int16_t num_hna; -extern int16_t num_ifs; extern struct net_device *soft_device; @@ -138,7 +137,7 @@ extern atomic_t module_state; extern struct workqueue_struct *bat_event_workqueue; void activate_module(void); -void shutdown_module(void); +void deactivate_module(void); void inc_module_count(void); void dec_module_count(void); int addr_to_string(char *buff, uint8_t *addr); diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 4152701c3689..44bbe894152f 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -118,6 +118,8 @@ void free_orig_node(void *data) * address if it does not exits */ struct orig_node *get_orig_node(uint8_t *addr) { + /* FIXME: each batman_if will be attached to a softif */ + struct bat_priv *bat_priv = netdev_priv(soft_device); struct orig_node *orig_node; struct hashtable_t *swaphash; int size; @@ -139,13 +141,13 @@ struct orig_node *get_orig_node(uint8_t *addr) orig_node->router = NULL; orig_node->hna_buff = NULL; - size = num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS; + size = bat_priv->num_ifaces * sizeof(TYPE_OF_WORD) * NUM_WORDS; orig_node->bcast_own = kzalloc(size, GFP_ATOMIC); if (!orig_node->bcast_own) goto free_orig_node; - size = num_ifs * sizeof(uint8_t); + size = bat_priv->num_ifaces * sizeof(uint8_t); orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC); if (!orig_node->bcast_own_sum) goto free_bcast_own; @@ -182,16 +184,25 @@ static bool purge_orig_neighbors(struct orig_node *orig_node, *best_neigh_node = NULL; - /* for all neighbors towards this originator ... */ list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) { neigh_node = list_entry(list_pos, struct neigh_node, list); - if (time_after(jiffies, + if ((time_after(jiffies, (neigh_node->last_valid + - ((PURGE_TIMEOUT * HZ) / 1000)))) { - - bat_dbg(DBG_BATMAN, "neighbor timeout: originator %pM, neighbor: %pM, last_valid %lu\n", orig_node->orig, neigh_node->addr, (neigh_node->last_valid / HZ)); + ((PURGE_TIMEOUT * HZ) / 1000)))) || + (neigh_node->if_incoming->if_status == + IF_TO_BE_REMOVED)) { + + if (neigh_node->if_incoming->if_status == + IF_TO_BE_REMOVED) + bat_dbg(DBG_BATMAN, "neighbor purge: originator %pM, neighbor: %pM, iface: %s\n", + orig_node->orig, neigh_node->addr, + neigh_node->if_incoming->dev); + else + bat_dbg(DBG_BATMAN, "neighbor timeout: originator %pM, neighbor: %pM, last_valid: %lu\n", + orig_node->orig, neigh_node->addr, + (neigh_node->last_valid / HZ)); neigh_purged = true; list_del(list_pos); @@ -246,13 +257,17 @@ void purge_orig(struct work_struct *work) spin_unlock_irqrestore(&orig_hash_lock, flags); - start_purge_timer(); + /* if work == NULL we were not called by the timer + * and thus do not need to re-arm the timer */ + if (work) + start_purge_timer(); } ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, size_t count, loff_t off) { HASHIT(hashit); + struct bat_priv *bat_priv = netdev_priv(net_dev); struct orig_node *orig_node; struct neigh_node *neigh_node; size_t hdr_len, tmp_len; @@ -260,10 +275,7 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, unsigned long flags; char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN]; - rcu_read_lock(); - if (list_empty(&if_list)) { - rcu_read_unlock(); - + if (!bat_priv->primary_if) { if (off == 0) return sprintf(buff, "BATMAN mesh %s disabled - please specify interfaces to enable it\n", @@ -272,9 +284,7 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, return 0; } - if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) { - rcu_read_unlock(); - + if (bat_priv->primary_if->if_status != IF_ACTIVE) { if (off == 0) return sprintf(buff, "BATMAN mesh %s disabled - primary interface not active\n", @@ -283,12 +293,12 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, return 0; } + rcu_read_lock(); hdr_len = sprintf(buff, " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)] \n", "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF", "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR, - ((struct batman_if *)if_list.next)->dev, - ((struct batman_if *)if_list.next)->addr_str, + bat_priv->primary_if->dev, bat_priv->primary_if->addr_str, net_dev->name); rcu_read_unlock(); @@ -347,3 +357,152 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, return bytes_written; } +static int orig_node_add_if(struct orig_node *orig_node, int max_if_num) +{ + void *data_ptr; + + data_ptr = kmalloc(max_if_num * sizeof(TYPE_OF_WORD) * NUM_WORDS, + GFP_ATOMIC); + if (!data_ptr) { + printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); + return -1; + } + + memcpy(data_ptr, orig_node->bcast_own, + (max_if_num - 1) * sizeof(TYPE_OF_WORD) * NUM_WORDS); + kfree(orig_node->bcast_own); + orig_node->bcast_own = data_ptr; + + data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); + if (!data_ptr) { + printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); + return -1; + } + + memcpy(data_ptr, orig_node->bcast_own_sum, + (max_if_num - 1) * sizeof(uint8_t)); + kfree(orig_node->bcast_own_sum); + orig_node->bcast_own_sum = data_ptr; + + return 0; +} + +int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) +{ + struct orig_node *orig_node; + HASHIT(hashit); + + /* resize all orig nodes because orig_node->bcast_own(_sum) depend on + * if_num */ + spin_lock(&orig_hash_lock); + + while (hash_iterate(orig_hash, &hashit)) { + orig_node = hashit.bucket->data; + + if (orig_node_add_if(orig_node, max_if_num) == -1) + goto err; + } + + spin_unlock(&orig_hash_lock); + return 0; + +err: + spin_unlock(&orig_hash_lock); + return -ENOMEM; +} + +static int orig_node_del_if(struct orig_node *orig_node, + int max_if_num, int del_if_num) +{ + void *data_ptr = NULL; + int chunk_size; + + /* last interface was removed */ + if (max_if_num == 0) + goto free_bcast_own; + + chunk_size = sizeof(TYPE_OF_WORD) * NUM_WORDS; + data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC); + if (!data_ptr) { + printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); + return -1; + } + + /* copy first part */ + memcpy(data_ptr, orig_node->bcast_own, del_if_num * chunk_size); + + /* copy second part */ + memcpy(data_ptr, + orig_node->bcast_own + ((del_if_num + 1) * chunk_size), + (max_if_num - del_if_num) * chunk_size); + +free_bcast_own: + kfree(orig_node->bcast_own); + orig_node->bcast_own = data_ptr; + + if (max_if_num == 0) + goto free_own_sum; + + data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); + if (!data_ptr) { + printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); + return -1; + } + + memcpy(data_ptr, orig_node->bcast_own_sum, + del_if_num * sizeof(uint8_t)); + + memcpy(data_ptr, + orig_node->bcast_own_sum + ((del_if_num + 1) * sizeof(uint8_t)), + (max_if_num - del_if_num) * sizeof(uint8_t)); + +free_own_sum: + kfree(orig_node->bcast_own_sum); + orig_node->bcast_own_sum = data_ptr; + + return 0; +} + +int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) +{ + struct batman_if *batman_if_tmp; + struct orig_node *orig_node; + HASHIT(hashit); + int ret; + + /* resize all orig nodes because orig_node->bcast_own(_sum) depend on + * if_num */ + spin_lock(&orig_hash_lock); + + while (hash_iterate(orig_hash, &hashit)) { + orig_node = hashit.bucket->data; + + ret = orig_node_del_if(orig_node, max_if_num, + batman_if->if_num); + + if (ret == -1) + goto err; + } + + /* renumber remaining batman interfaces _inside_ of orig_hash_lock */ + rcu_read_lock(); + list_for_each_entry_rcu(batman_if_tmp, &if_list, list) { + if (batman_if_tmp->if_status == IF_NOT_IN_USE) + continue; + + if (batman_if == batman_if_tmp) + continue; + + if (batman_if_tmp->if_num > batman_if->if_num) + batman_if_tmp->if_num--; + } + rcu_read_unlock(); + + batman_if->if_num = -1; + spin_unlock(&orig_hash_lock); + return 0; + +err: + spin_unlock(&orig_hash_lock); + return -ENOMEM; +} diff --git a/drivers/staging/batman-adv/originator.h b/drivers/staging/batman-adv/originator.h index 745b4b064c1c..afbc7c0e8aa3 100644 --- a/drivers/staging/batman-adv/originator.h +++ b/drivers/staging/batman-adv/originator.h @@ -30,3 +30,5 @@ create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, uint8_t *neigh, struct batman_if *if_incoming); ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, size_t count, loff_t off); +int orig_hash_add_if(struct batman_if *batman_if, int max_if_num); +int orig_hash_del_if(struct batman_if *batman_if, int max_if_num); diff --git a/drivers/staging/batman-adv/proc.c b/drivers/staging/batman-adv/proc.c deleted file mode 100644 index 25b24fe7b6af..000000000000 --- a/drivers/staging/batman-adv/proc.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" -#include "proc.h" -#include "routing.h" -#include "translation-table.h" -#include "hard-interface.h" -#include "types.h" -#include "hash.h" -#include "vis.h" - -static struct proc_dir_entry *proc_batman_dir, *proc_interface_file; - -static int proc_interfaces_read(struct seq_file *seq, void *offset) -{ - struct batman_if *batman_if; - - rcu_read_lock(); - list_for_each_entry_rcu(batman_if, &if_list, list) { - seq_printf(seq, "[%8s] %s %s\n", - (batman_if->if_active == IF_ACTIVE ? - "active" : "inactive"), - batman_if->dev, - (batman_if->if_active == IF_ACTIVE ? - batman_if->addr_str : " ")); - } - rcu_read_unlock(); - - return 0; -} - -static int proc_interfaces_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_interfaces_read, NULL); -} - -static ssize_t proc_interfaces_write(struct file *instance, - const char __user *userbuffer, - size_t count, loff_t *data) -{ - char *if_string, *colon_ptr = NULL, *cr_ptr = NULL; - int not_copied = 0, if_num = 0, add_success; - struct batman_if *batman_if = NULL; - - if_string = kmalloc(count, GFP_KERNEL); - - if (!if_string) - return -ENOMEM; - - if (count > IFNAMSIZ - 1) { - printk(KERN_WARNING "batman-adv:Can't add interface: device name is too long\n"); - goto end; - } - - not_copied = copy_from_user(if_string, userbuffer, count); - if_string[count - not_copied - 1] = 0; - - colon_ptr = strchr(if_string, ':'); - if (colon_ptr) - *colon_ptr = 0; - - if (!colon_ptr) { - cr_ptr = strchr(if_string, '\n'); - if (cr_ptr) - *cr_ptr = 0; - } - - if (strlen(if_string) == 0) { - shutdown_module(); - num_ifs = 0; - goto end; - } - - /* add interface */ - rcu_read_lock(); - list_for_each_entry_rcu(batman_if, &if_list, list) { - if (strncmp(batman_if->dev, if_string, count) == 0) { - printk(KERN_ERR "batman-adv:Given interface is already active: %s\n", if_string); - rcu_read_unlock(); - goto end; - - } - - if_num++; - } - rcu_read_unlock(); - - add_success = hardif_add_interface(if_string, if_num); - if (add_success < 0) - goto end; - - num_ifs = if_num + 1; - - if ((atomic_read(&module_state) == MODULE_INACTIVE) && - (hardif_get_active_if_num() > 0)) - activate_module(); - - return count; -end: - kfree(if_string); - return count; -} - -static const struct file_operations proc_interfaces_fops = { - .owner = THIS_MODULE, - .open = proc_interfaces_open, - .read = seq_read, - .write = proc_interfaces_write, - .llseek = seq_lseek, - .release = single_release, -}; - -void cleanup_procfs(void) -{ - if (proc_interface_file) - remove_proc_entry(PROC_FILE_INTERFACES, proc_batman_dir); - - if (proc_batman_dir) -#ifdef __NET_NET_NAMESPACE_H - remove_proc_entry(PROC_ROOT_DIR, init_net.proc_net); -#else - remove_proc_entry(PROC_ROOT_DIR, proc_net); -#endif -} - -int setup_procfs(void) -{ -#ifdef __NET_NET_NAMESPACE_H - proc_batman_dir = proc_mkdir(PROC_ROOT_DIR, init_net.proc_net); -#else - proc_batman_dir = proc_mkdir(PROC_ROOT_DIR, proc_net); -#endif - - if (!proc_batman_dir) { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s' folder failed\n", PROC_ROOT_DIR); - return -EFAULT; - } - - proc_interface_file = create_proc_entry(PROC_FILE_INTERFACES, - S_IWUSR | S_IRUGO, - proc_batman_dir); - if (proc_interface_file) { - proc_interface_file->proc_fops = &proc_interfaces_fops; - } else { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_INTERFACES); - cleanup_procfs(); - return -EFAULT; - } - - return 0; -} diff --git a/drivers/staging/batman-adv/proc.h b/drivers/staging/batman-adv/proc.h deleted file mode 100644 index 6f4f5b3e7e02..000000000000 --- a/drivers/staging/batman-adv/proc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include -#include - -#define PROC_ROOT_DIR "batman-adv" -#define PROC_FILE_INTERFACES "interfaces" - -void cleanup_procfs(void); -int setup_procfs(void); - diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 0a9f52b8d35d..7b8aa27ed289 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -205,7 +205,7 @@ static int isBidirectionalNeigh(struct orig_node *orig_node, batman_packet->tq = ((batman_packet->tq * orig_neigh_node->tq_own * orig_neigh_node->tq_asym_penalty) / - (TQ_MAX_VALUE * TQ_MAX_VALUE)); + (TQ_MAX_VALUE * TQ_MAX_VALUE)); bat_dbg(DBG_BATMAN, "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i\n", orig_node->orig, orig_neigh_node->orig, total_count, @@ -387,7 +387,7 @@ void receive_bat_packet(struct ethhdr *ethhdr, batman_packet->version, has_directlink_flag); list_for_each_entry_rcu(batman_if, &if_list, list) { - if (batman_if->if_active != IF_ACTIVE) + if (batman_if->if_status != IF_ACTIVE) continue; if (compare_orig(ethhdr->h_source, @@ -893,7 +893,7 @@ int recv_bcast_packet(struct sk_buff *skb) if (is_my_mac(ethhdr->h_source)) return NET_RX_DROP; - bcast_packet = (struct bcast_packet *) skb->data; + bcast_packet = (struct bcast_packet *)skb->data; /* ignore broadcasts originated by myself */ if (is_my_mac(bcast_packet->orig)) diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index de2344a071c4..31d86ae9b147 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -57,7 +57,7 @@ int send_skb_packet(struct sk_buff *skb, { struct ethhdr *ethhdr; - if (batman_if->if_active != IF_ACTIVE) + if (batman_if->if_status != IF_ACTIVE) goto send_skb_err; if (unlikely(!batman_if->net_dev)) @@ -123,7 +123,7 @@ static void send_packet_to_if(struct forw_packet *forw_packet, int16_t buff_pos; struct batman_packet *batman_packet; - if (batman_if->if_active != IF_ACTIVE) + if (batman_if->if_status != IF_ACTIVE) return; packet_num = 0; @@ -182,7 +182,7 @@ static void send_packet(struct forw_packet *forw_packet) return; } - if (forw_packet->if_incoming->if_active != IF_ACTIVE) + if (forw_packet->if_incoming->if_status != IF_ACTIVE) return; /* multihomed peer assumed */ @@ -243,7 +243,13 @@ void schedule_own_packet(struct batman_if *batman_if) struct bat_priv *bat_priv = netdev_priv(soft_device); unsigned long send_time; struct batman_packet *batman_packet; - int vis_server = atomic_read(&bat_priv->vis_mode); + int vis_server; + + if ((batman_if->if_status == IF_NOT_IN_USE) || + (batman_if->if_status == IF_TO_BE_REMOVED)) + return; + + vis_server = atomic_read(&bat_priv->vis_mode); /** * the interface gets activated here to avoid race conditions between @@ -252,11 +258,12 @@ void schedule_own_packet(struct batman_if *batman_if) * outdated packets (especially uninitialized mac addresses) in the * packet queue */ - if (batman_if->if_active == IF_TO_BE_ACTIVATED) - batman_if->if_active = IF_ACTIVE; + if (batman_if->if_status == IF_TO_BE_ACTIVATED) + batman_if->if_status = IF_ACTIVE; /* if local hna has changed and interface is a primary interface */ - if ((atomic_read(&hna_local_changed)) && (batman_if->if_num == 0)) + if ((atomic_read(&hna_local_changed)) && + (batman_if == bat_priv->primary_if)) rebuild_batman_packet(batman_if); /** @@ -374,13 +381,11 @@ void add_bcast_packet_to_list(struct sk_buff *skb) forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); if (!forw_packet) - return; + goto out; skb = skb_copy(skb, GFP_ATOMIC); - if (!skb) { - kfree(forw_packet); - return; - } + if (!skb) + goto packet_free; skb_reset_mac_header(skb); @@ -391,6 +396,12 @@ void add_bcast_packet_to_list(struct sk_buff *skb) forw_packet->num_packets = 0; _add_bcast_packet_to_list(forw_packet, 1); + return; + +packet_free: + kfree(forw_packet); +out: + return; } void send_outstanding_bcast_packet(struct work_struct *work) @@ -455,19 +466,31 @@ void send_outstanding_bat_packet(struct work_struct *work) forw_packet_free(forw_packet); } -void purge_outstanding_packets(void) +void purge_outstanding_packets(struct batman_if *batman_if) { struct forw_packet *forw_packet; struct hlist_node *tmp_node, *safe_tmp_node; unsigned long flags; - bat_dbg(DBG_BATMAN, "purge_outstanding_packets()\n"); + if (batman_if) + bat_dbg(DBG_BATMAN, "purge_outstanding_packets(): %s\n", + batman_if->dev); + else + bat_dbg(DBG_BATMAN, "purge_outstanding_packets()\n"); /* free bcast list */ spin_lock_irqsave(&forw_bcast_list_lock, flags); hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, &forw_bcast_list, list) { + /** + * if purge_outstanding_packets() was called with an argmument + * we delete only packets belonging to the given interface + */ + if ((batman_if) && + (forw_packet->if_incoming != batman_if)) + continue; + spin_unlock_irqrestore(&forw_bcast_list_lock, flags); /** @@ -484,6 +507,14 @@ void purge_outstanding_packets(void) hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, &forw_bat_list, list) { + /** + * if purge_outstanding_packets() was called with an argmument + * we delete only packets belonging to the given interface + */ + if ((batman_if) && + (forw_packet->if_incoming != batman_if)) + continue; + spin_unlock_irqrestore(&forw_bat_list_lock, flags); /** diff --git a/drivers/staging/batman-adv/send.h b/drivers/staging/batman-adv/send.h index b2ddf631fb58..b84a470e510f 100644 --- a/drivers/staging/batman-adv/send.h +++ b/drivers/staging/batman-adv/send.h @@ -36,4 +36,4 @@ void schedule_forward_packet(struct orig_node *orig_node, void add_bcast_packet_to_list(struct sk_buff *skb); void send_outstanding_bcast_packet(struct work_struct *work); void send_outstanding_bat_packet(struct work_struct *work); -void purge_outstanding_packets(void); +void purge_outstanding_packets(struct batman_if *batman_if); diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 4cdebe5f874f..681a0ad7cb88 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -251,7 +251,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); /* net_dev won't be available when not active */ - if (orig_node->router->if_incoming->if_active != IF_ACTIVE) + if (orig_node->router->if_incoming->if_status != IF_ACTIVE) goto unlock; /* don't lock while sending the packets ... we therefore diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c index b735200ecf1b..c7a6635e34ad 100644 --- a/drivers/staging/batman-adv/translation-table.c +++ b/drivers/staging/batman-adv/translation-table.c @@ -159,16 +159,14 @@ int hna_local_fill_buffer(unsigned char *buff, int buff_len) int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff, size_t count, loff_t off) { + struct bat_priv *bat_priv = netdev_priv(net_dev); struct hna_local_entry *hna_local_entry; HASHIT(hashit); int bytes_written = 0; unsigned long flags; size_t hdr_len; - rcu_read_lock(); - if (list_empty(&if_list)) { - rcu_read_unlock(); - + if (!bat_priv->primary_if) { if (off == 0) return sprintf(buff, "BATMAN mesh %s disabled - please specify interfaces to enable it\n", @@ -176,7 +174,6 @@ int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff, return 0; } - rcu_read_unlock(); hdr_len = sprintf(buff, "Locally retrieved addresses (from %s) announced via HNA:\n", @@ -376,16 +373,14 @@ void hna_global_add_orig(struct orig_node *orig_node, int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff, size_t count, loff_t off) { + struct bat_priv *bat_priv = netdev_priv(net_dev); struct hna_global_entry *hna_global_entry; HASHIT(hashit); int bytes_written = 0; unsigned long flags; size_t hdr_len; - rcu_read_lock(); - if (list_empty(&if_list)) { - rcu_read_unlock(); - + if (!bat_priv->primary_if) { if (off == 0) return sprintf(buff, "BATMAN mesh %s disabled - please specify interfaces to enable it\n", @@ -393,7 +388,6 @@ int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff, return 0; } - rcu_read_unlock(); hdr_len = sprintf(buff, "Globally announced HNAs received via the mesh %s (translation table):\n", diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index ffaa16c30af6..eba1fa62f30c 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -36,12 +36,13 @@ struct batman_if { struct list_head list; int16_t if_num; char *dev; - char if_active; + char if_status; char addr_str[ETH_STR_LEN]; struct net_device *net_dev; atomic_t seqno; unsigned char *packet_buff; int packet_len; + struct kobject *hardif_obj; struct rcu_head rcu; }; @@ -84,6 +85,8 @@ struct bat_priv { atomic_t aggregation_enabled; atomic_t vis_mode; atomic_t orig_interval; + char num_ifaces; + struct batman_if *primary_if; struct kobject *mesh_obj; }; diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index 57d69d70671e..b6ff031a34d0 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -173,13 +173,10 @@ ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff, unsigned long flags; int vis_server = atomic_read(&bat_priv->vis_mode); - rcu_read_lock(); - if (list_empty(&if_list) || (vis_server == VIS_TYPE_CLIENT_UPDATE)) { - rcu_read_unlock(); + if ((!bat_priv->primary_if) || + (vis_server == VIS_TYPE_CLIENT_UPDATE)) return 0; - } - rcu_read_unlock(); hdr_len = 0; spin_lock_irqsave(&vis_hash_lock, flags); @@ -498,7 +495,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv) if (orig_node->router != NULL && compare_orig(orig_node->router->addr, orig_node->orig) - && (orig_node->router->if_incoming->if_active == + && (orig_node->router->if_incoming->if_status == IF_ACTIVE) && orig_node->router->tq_avg > 0) { -- cgit v1.2.3 From b7bce588b3a6a058e00d9629c25cf170dede63fc Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Fri, 7 May 2010 21:47:23 +0200 Subject: Staging: batman-adv: fix whitespace style issues This patch fixes unnecessary whitespaces before a quoted newline that the remaining batman-adv files had. Reported-by: Luis de Bethencourt Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/bat_sysfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c index 1811c8da6609..e2c000b80ca0 100644 --- a/drivers/staging/batman-adv/bat_sysfs.c +++ b/drivers/staging/batman-adv/bat_sysfs.c @@ -75,7 +75,7 @@ static ssize_t show_aggr_ogm(struct kobject *kobj, struct attribute *attr, struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); int aggr_status = atomic_read(&bat_priv->aggregation_enabled); - return sprintf(buff, "status: %s\ncommands: enable, disable, 0, 1 \n", + return sprintf(buff, "status: %s\ncommands: enable, disable, 0, 1\n", aggr_status == 0 ? "disabled" : "enabled"); } @@ -123,7 +123,7 @@ static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr, struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); int vis_mode = atomic_read(&bat_priv->vis_mode); - return sprintf(buff, "status: %s\ncommands: client, server, %d, %d \n", + return sprintf(buff, "status: %s\ncommands: client, server, %d, %d\n", vis_mode == VIS_TYPE_CLIENT_UPDATE ? "client" : "server", VIS_TYPE_SERVER_SYNC, VIS_TYPE_CLIENT_UPDATE); @@ -364,7 +364,7 @@ static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr, if (!batman_if) return 0; - return sprintf(buff, "status: %s\ncommands: none, bat0 \n", + return sprintf(buff, "status: %s\ncommands: none, bat0\n", batman_if->if_status == IF_NOT_IN_USE ? "none" : "bat0"); } -- cgit v1.2.3 From f94cee241099b31732460c255c6af24979ec778e Mon Sep 17 00:00:00 2001 From: Simon Wunderlich Date: Fri, 7 May 2010 21:47:24 +0200 Subject: Staging: batman-adv: Reorganize sequence number handling BATMAN and broadcast packets are tracked with a sequence number window of currently 64 entries to measure and avoid duplicates. Packets which have a sequence number smaller than the newest received packet minus 64 are not within this sequence number window anymore and are called "old packets" from now on. When old packets are received, the routing code assumes that the host of the originator has been restarted. This assumption however might be wrong as packets can also be delayed by NIC drivers, e.g. because of long queues or collision detection in dense WiFi? environments. This behaviour can be reproduced by doing a broadcast ping flood in a dense node environment. The effect is that the sequence number window is jumping forth and back, accepting and forwarding any packet (because packets are assumed to be "new") and causing loops. To overcome this problem, the sequence number handling has been reorganized. When an old packet is received, the window is reset back only once. Other old packets are dropped for (currently) 30 seconds to "protect" the new sequence number and avoid the hopping as described above. The reorganization brings some code cleanups (at least i hope you feel the same) and also fixes a bug in count_real_packets() which falsely updated the last_real_seqno for slightly older packets within the seqno window if they are no duplicates. This second version of the patch also fixes a problem where for seq_diff==64 bit_shift() reads from outside of the seqno window, and removes the loop for seq_diff == -64 which was present in the first patch. The third iteration also adds a window for the next expected sequence numbers. This minimizes sequence number flapping for packets with very big differences (e.g. 3 packets with seqno 0, 25000 and 50000 might still cause problems without this window). Signed-off-by: Simon Wunderlich Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/bitarray.c | 74 ++++++++++++++++-------- drivers/staging/batman-adv/main.h | 4 ++ drivers/staging/batman-adv/originator.c | 2 + drivers/staging/batman-adv/routing.c | 99 +++++++++++++++++++++++++-------- drivers/staging/batman-adv/types.h | 4 ++ 5 files changed, 136 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/bitarray.c b/drivers/staging/batman-adv/bitarray.c index 7848305bd14b..2fef6e35f8c3 100644 --- a/drivers/staging/batman-adv/bitarray.c +++ b/drivers/staging/batman-adv/bitarray.c @@ -68,7 +68,7 @@ void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n) int32_t word_offset, word_num; int32_t i; - if (n <= 0) + if (n <= 0 || n >= TQ_LOCAL_WINDOW_SIZE) return; word_offset = n % WORD_BIT_SIZE;/* shift how much inside each word */ @@ -111,48 +111,76 @@ void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n) seq_bits[i] = 0; } +static void bit_reset_window(TYPE_OF_WORD *seq_bits) +{ + int i; + for (i = 0; i < NUM_WORDS; i++) + seq_bits[i] = 0; +} + -/* receive and process one packet, returns 1 if received seq_num is considered - * new, 0 if old */ +/* receive and process one packet within the sequence number window. + * + * returns: + * 1 if the window was moved (either new or very old) + * 0 if the window was not moved/shifted. + */ char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff, int8_t set_mark) { - int i; + /* sequence number is slightly older. We already got a sequence number + * higher than this one, so we just mark it. */ - /* we already got a sequence number higher than this one, so we just - * mark it. this should wrap around the integer just fine */ - if ((seq_num_diff < 0) && (seq_num_diff >= -TQ_LOCAL_WINDOW_SIZE)) { + if ((seq_num_diff <= 0) && (seq_num_diff > -TQ_LOCAL_WINDOW_SIZE)) { if (set_mark) bit_mark(seq_bits, -seq_num_diff); return 0; } - /* it seems we missed a lot of packets or the other host restarted */ - if ((seq_num_diff > TQ_LOCAL_WINDOW_SIZE) || - (seq_num_diff < -TQ_LOCAL_WINDOW_SIZE)) { + /* sequence number is slightly newer, so we shift the window and + * set the mark if required */ - if (seq_num_diff > TQ_LOCAL_WINDOW_SIZE) - bat_dbg(DBG_BATMAN, - "We missed a lot of packets (%i) !\n", - seq_num_diff-1); + if ((seq_num_diff > 0) && (seq_num_diff < TQ_LOCAL_WINDOW_SIZE)) { + bit_shift(seq_bits, seq_num_diff); - if (-seq_num_diff > TQ_LOCAL_WINDOW_SIZE) - bat_dbg(DBG_BATMAN, - "Other host probably restarted !\n"); + if (set_mark) + bit_mark(seq_bits, 0); + return 1; + } - for (i = 0; i < NUM_WORDS; i++) - seq_bits[i] = 0; + /* sequence number is much newer, probably missed a lot of packets */ + if ((seq_num_diff >= TQ_LOCAL_WINDOW_SIZE) + || (seq_num_diff < EXPECTED_SEQNO_RANGE)) { + bat_dbg(DBG_BATMAN, + "We missed a lot of packets (%i) !\n", + seq_num_diff - 1); + bit_reset_window(seq_bits); if (set_mark) - seq_bits[0] = 1; /* we only have the latest packet */ - } else { - bit_shift(seq_bits, seq_num_diff); + bit_mark(seq_bits, 0); + return 1; + } + + /* received a much older packet. The other host either restarted + * or the old packet got delayed somewhere in the network. The + * packet should be dropped without calling this function if the + * seqno window is protected. */ + + if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) + || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) { + bat_dbg(DBG_BATMAN, + "Other host probably restarted!\n"); + + bit_reset_window(seq_bits); if (set_mark) bit_mark(seq_bits, 0); + + return 1; } - return 1; + /* never reached */ + return 0; } /* count the hamming weight, how many good packets did we receive? just count diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 247196ca7515..58c1ec167412 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -61,6 +61,10 @@ * forw_packet->direct_link_flags */ #define MAX_AGGREGATION_MS 100 +#define RESET_PROTECTION_MS 30000 +#define EXPECTED_SEQNO_RANGE 4096 +/* don't reset again within 30 seconds */ + #define MODULE_INACTIVE 0 #define MODULE_ACTIVE 1 #define MODULE_DEACTIVATING 2 diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 44bbe894152f..01d71d7ed420 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -140,6 +140,8 @@ struct orig_node *get_orig_node(uint8_t *addr) memcpy(orig_node->orig, addr, ETH_ALEN); orig_node->router = NULL; orig_node->hna_buff = NULL; + orig_node->bcast_seqno_reset = jiffies - msecs_to_jiffies(RESET_PROTECTION_MS) - 1; + orig_node->batman_seqno_reset = jiffies - msecs_to_jiffies(RESET_PROTECTION_MS) - 1; size = bat_priv->num_ifaces * sizeof(TYPE_OF_WORD) * NUM_WORDS; diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 7b8aa27ed289..bf67059e3ee1 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -304,6 +304,38 @@ update_hna: update_routes(orig_node, orig_node->router, hna_buff, tmp_hna_buff_len); } +/* checks whether the host restarted and is in the protection time. + * returns: + * 0 if the packet is to be accepted + * 1 if the packet is to be ignored. + */ +static int window_protected(int16_t seq_num_diff, + unsigned long *last_reset) +{ + if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) + || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) { + if (time_after(jiffies, *last_reset + + msecs_to_jiffies(RESET_PROTECTION_MS))) { + + *last_reset = jiffies; + bat_dbg(DBG_BATMAN, + "old packet received, start protection\n"); + + return 0; + } else + return 1; + } + return 0; +} + +/* processes a batman packet for all interfaces, adjusts the sequence number and + * finds out whether it is a duplicate. + * returns: + * 1 the packet is a duplicate + * 0 the packet has not yet been received + * -1 the packet is old and has been received while the seqno window + * was protected. Caller should drop it. + */ static char count_real_packets(struct ethhdr *ethhdr, struct batman_packet *batman_packet, struct batman_if *if_incoming) @@ -311,31 +343,41 @@ static char count_real_packets(struct ethhdr *ethhdr, struct orig_node *orig_node; struct neigh_node *tmp_neigh_node; char is_duplicate = 0; - uint16_t seq_diff; + int16_t seq_diff; + int need_update = 0; + int set_mark; orig_node = get_orig_node(batman_packet->orig); if (orig_node == NULL) return 0; + seq_diff = batman_packet->seqno - orig_node->last_real_seqno; + + /* signalize caller that the packet is to be dropped. */ + if (window_protected(seq_diff, &orig_node->batman_seqno_reset)) + return -1; + list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { - if (!is_duplicate) - is_duplicate = - get_bit_status(tmp_neigh_node->real_bits, + is_duplicate |= get_bit_status(tmp_neigh_node->real_bits, orig_node->last_real_seqno, batman_packet->seqno); - seq_diff = batman_packet->seqno - orig_node->last_real_seqno; + if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && (tmp_neigh_node->if_incoming == if_incoming)) - bit_get_packet(tmp_neigh_node->real_bits, seq_diff, 1); + set_mark = 1; else - bit_get_packet(tmp_neigh_node->real_bits, seq_diff, 0); + set_mark = 0; + + /* if the window moved, set the update flag. */ + need_update |= bit_get_packet(tmp_neigh_node->real_bits, + seq_diff, set_mark); tmp_neigh_node->real_packet_count = bit_packet_count(tmp_neigh_node->real_bits); } - if (!is_duplicate) { + if (need_update) { bat_dbg(DBG_BATMAN, "updating last_seqno: old %d, new %d\n", orig_node->last_real_seqno, batman_packet->seqno); orig_node->last_real_seqno = batman_packet->seqno; @@ -453,24 +495,27 @@ void receive_bat_packet(struct ethhdr *ethhdr, return; } - if (batman_packet->tq == 0) { - count_real_packets(ethhdr, batman_packet, if_incoming); - - bat_dbg(DBG_BATMAN, "Drop packet: originator packet with tq equal 0\n"); - return; - } - if (is_my_oldorig) { bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast echos (sender: %pM)\n", ethhdr->h_source); return; } - is_duplicate = count_real_packets(ethhdr, batman_packet, if_incoming); - orig_node = get_orig_node(batman_packet->orig); if (orig_node == NULL) return; + is_duplicate = count_real_packets(ethhdr, batman_packet, if_incoming); + + if (is_duplicate == -1) { + bat_dbg(DBG_BATMAN, "Drop packet: packet within seqno protection time (sender: %pM)\n", ethhdr->h_source); + return; + } + + if (batman_packet->tq == 0) { + bat_dbg(DBG_BATMAN, "Drop packet: originator packet with tq equal 0\n"); + return; + } + /* avoid temporary routing loops */ if ((orig_node->router) && (orig_node->router->orig_node->router) && @@ -866,13 +911,13 @@ int recv_unicast_packet(struct sk_buff *skb) return ret; } - int recv_bcast_packet(struct sk_buff *skb) { struct orig_node *orig_node; struct bcast_packet *bcast_packet; struct ethhdr *ethhdr; int hdr_size = sizeof(struct bcast_packet); + int16_t seq_diff; unsigned long flags; /* drop packet if it has not necessary minimum size */ @@ -908,7 +953,7 @@ int recv_bcast_packet(struct sk_buff *skb) return NET_RX_DROP; } - /* check flood history */ + /* check whether the packet is a duplicate */ if (get_bit_status(orig_node->bcast_bits, orig_node->last_bcast_seqno, ntohs(bcast_packet->seqno))) { @@ -916,14 +961,20 @@ int recv_bcast_packet(struct sk_buff *skb) return NET_RX_DROP; } - /* mark broadcast in flood history */ - if (bit_get_packet(orig_node->bcast_bits, - ntohs(bcast_packet->seqno) - - orig_node->last_bcast_seqno, 1)) + seq_diff = ntohs(bcast_packet->seqno) - orig_node->last_bcast_seqno; + + /* check whether the packet is old and the host just restarted. */ + if (window_protected(seq_diff, &orig_node->bcast_seqno_reset)) { + spin_unlock_irqrestore(&orig_hash_lock, flags); + return NET_RX_DROP; + } + + /* mark broadcast in flood history, update window position + * if required. */ + if (bit_get_packet(orig_node->bcast_bits, seq_diff, 1)) orig_node->last_bcast_seqno = ntohs(bcast_packet->seqno); spin_unlock_irqrestore(&orig_hash_lock, flags); - /* rebroadcast packet */ add_bcast_packet_to_list(skb); diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index eba1fa62f30c..c92621965b3d 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -55,6 +55,10 @@ struct orig_node { /* structure for orig_list maintaining nodes of uint8_t tq_own; int tq_asym_penalty; unsigned long last_valid; /* when last packet from this node was received */ + unsigned long bcast_seqno_reset; /* time when the broadcast + seqno window was reset. */ + unsigned long batman_seqno_reset;/* time when the batman seqno + window was reset. */ /* uint8_t gwflags; * flags related to gateway functions: gateway class */ uint8_t flags; /* for now only VIS_SERVER flag. */ unsigned char *hna_buff; -- cgit v1.2.3 From 19dae340d2af3074abad5b4c7306ae240068f89f Mon Sep 17 00:00:00 2001 From: Simon Wunderlich Date: Fri, 7 May 2010 21:47:25 +0200 Subject: Staging: batman-adv: Limit queue lengths for batman and broadcast packets This patch limits the queue lengths of batman and broadcast packets. BATMAN packets are held back for aggregation and jittered to avoid interferences. Broadcast packets are stored to be sent out multiple times to increase the probability to be received by other nodes in lossy environments. Especially in extreme cases like broadcast storms, the queues have been seen to run full, eating up all the memory and triggering the infamous OOM killer. With the queue length limits introduced in this patch, this problem is avoided. Each queue is limited to 256 entries for now, resulting in 1 MB of maximum space available in total for typical setups (assuming one packet including overhead does not require more than 2000 byte). This should also be reasonable for smaller routers, otherwise the defines can be tweaked later. This third version of the patch does not increase the local broadcast sequence number when the queue is already full. Signed-off-by: Simon Wunderlich Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/aggregation.c | 16 +++++++++++++- drivers/staging/batman-adv/main.c | 5 +++++ drivers/staging/batman-adv/main.h | 4 ++++ drivers/staging/batman-adv/send.c | 33 ++++++++++++++++++++++++----- drivers/staging/batman-adv/send.h | 2 +- drivers/staging/batman-adv/soft-interface.c | 6 +++--- 6 files changed, 56 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c index a5818ff6139e..ce8b8a6e5ae6 100644 --- a/drivers/staging/batman-adv/aggregation.c +++ b/drivers/staging/batman-adv/aggregation.c @@ -95,6 +95,7 @@ static bool can_aggregate_with(struct batman_packet *new_batman_packet, return false; } +#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0) /* create a new aggregated packet and add this packet to it */ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len, @@ -106,13 +107,26 @@ static void new_aggregated_packet(unsigned char *packet_buff, struct forw_packet *forw_packet_aggr; unsigned long flags; + /* own packet should always be scheduled */ + if (!own_packet) { + if (!atomic_dec_not_zero(&batman_queue_left)) { + bat_dbg(DBG_BATMAN, "batman packet queue full\n"); + return; + } + } + forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); - if (!forw_packet_aggr) + if (!forw_packet_aggr) { + if (!own_packet) + atomic_inc(&batman_queue_left); return; + } forw_packet_aggr->packet_buff = kmalloc(MAX_AGGREGATION_BYTES, GFP_ATOMIC); if (!forw_packet_aggr->packet_buff) { + if (!own_packet) + atomic_inc(&batman_queue_left); kfree(forw_packet_aggr); return; } diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index c1e57aaf2e5a..aa072d15134c 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -42,6 +42,9 @@ DEFINE_SPINLOCK(forw_bat_list_lock); DEFINE_SPINLOCK(forw_bcast_list_lock); atomic_t vis_interval; +atomic_t bcast_queue_left; +atomic_t batman_queue_left; + int16_t num_hna; struct net_device *soft_device; @@ -79,6 +82,8 @@ int init_module(void) atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only * for debugging now. */ + atomic_set(&bcast_queue_left, BCAST_QUEUE_LEN); + atomic_set(&batman_queue_left, BATMAN_QUEUE_LEN); /* the name should not be longer than 10 chars - see * http://lwn.net/Articles/23634/ */ diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 58c1ec167412..6749ce036b91 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -69,6 +69,8 @@ #define MODULE_ACTIVE 1 #define MODULE_DEACTIVATING 2 +#define BCAST_QUEUE_LEN 256 +#define BATMAN_QUEUE_LE 256 /* * Debug Messages @@ -132,6 +134,8 @@ extern spinlock_t forw_bat_list_lock; extern spinlock_t forw_bcast_list_lock; extern atomic_t vis_interval; +extern atomic_t bcast_queue_left; +extern atomic_t batman_queue_left; extern int16_t num_hna; extern struct net_device *soft_device; diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index 31d86ae9b147..f58a9edfc2cc 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -375,13 +375,28 @@ static void _add_bcast_packet_to_list(struct forw_packet *forw_packet, send_time); } -void add_bcast_packet_to_list(struct sk_buff *skb) +#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0) +/* add a broadcast packet to the queue and setup timers. broadcast packets + * are sent multiple times to increase probability for beeing received. + * + * This function returns NETDEV_TX_OK on success and NETDEV_TX_BUSY on + * errors. + * + * The skb is not consumed, so the caller should make sure that the + * skb is freed. */ +int add_bcast_packet_to_list(struct sk_buff *skb) { struct forw_packet *forw_packet; + if (!atomic_dec_not_zero(&bcast_queue_left)) { + bat_dbg(DBG_BATMAN, "bcast packet queue full\n"); + goto out; + } + forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); + if (!forw_packet) - goto out; + goto out_and_inc; skb = skb_copy(skb, GFP_ATOMIC); if (!skb) @@ -396,12 +411,14 @@ void add_bcast_packet_to_list(struct sk_buff *skb) forw_packet->num_packets = 0; _add_bcast_packet_to_list(forw_packet, 1); - return; + return NETDEV_TX_OK; packet_free: kfree(forw_packet); +out_and_inc: + atomic_inc(&bcast_queue_left); out: - return; + return NETDEV_TX_BUSY; } void send_outstanding_bcast_packet(struct work_struct *work) @@ -436,8 +453,10 @@ void send_outstanding_bcast_packet(struct work_struct *work) if ((forw_packet->num_packets < 3) && (atomic_read(&module_state) != MODULE_DEACTIVATING)) _add_bcast_packet_to_list(forw_packet, ((5 * HZ) / 1000)); - else + else { forw_packet_free(forw_packet); + atomic_inc(&bcast_queue_left); + } } void send_outstanding_bat_packet(struct work_struct *work) @@ -463,6 +482,10 @@ void send_outstanding_bat_packet(struct work_struct *work) (atomic_read(&module_state) != MODULE_DEACTIVATING)) schedule_own_packet(forw_packet->if_incoming); + /* don't count own packet */ + if (!forw_packet->own) + atomic_inc(&batman_queue_left); + forw_packet_free(forw_packet); } diff --git a/drivers/staging/batman-adv/send.h b/drivers/staging/batman-adv/send.h index b84a470e510f..feaa2fc7f9a1 100644 --- a/drivers/staging/batman-adv/send.h +++ b/drivers/staging/batman-adv/send.h @@ -33,7 +33,7 @@ void schedule_forward_packet(struct orig_node *orig_node, struct batman_packet *batman_packet, uint8_t directlink, int hna_buff_len, struct batman_if *if_outgoing); -void add_bcast_packet_to_list(struct sk_buff *skb); +int add_bcast_packet_to_list(struct sk_buff *skb); void send_outstanding_bcast_packet(struct work_struct *work); void send_outstanding_bat_packet(struct work_struct *work); void purge_outstanding_packets(struct batman_if *batman_if); diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 681a0ad7cb88..14b5ccaeaca0 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -216,10 +216,10 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) /* set broadcast sequence number */ bcast_packet->seqno = htons(bcast_seqno); - bcast_seqno++; + /* broadcast packet. on success, increase seqno. */ + if (add_bcast_packet_to_list(skb) == NETDEV_TX_OK) + bcast_seqno++; - /* broadcast packet */ - add_bcast_packet_to_list(skb); /* a copy is stored in the bcast list, therefore removing * the original skb. */ kfree_skb(skb); -- cgit v1.2.3 From 7d02d777d4a7eb551999a35f52480c9ddac3d874 Mon Sep 17 00:00:00 2001 From: Simon Wunderlich Date: Fri, 7 May 2010 21:47:26 +0200 Subject: Staging: batman-adv: kfree_skb() in interface_tx() in error case As we always return that the we consumed the skb, we should also free the skb in the case of an error. Signed-off-by: Simon Wunderlich Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/soft-interface.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 14b5ccaeaca0..c3b52885b086 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -275,6 +275,7 @@ unlock: spin_unlock_irqrestore(&orig_hash_lock, flags); dropped: priv->stats.tx_dropped++; + kfree_skb(skb); end: return NETDEV_TX_OK; } -- cgit v1.2.3 From 202cfe106012c3917543ed8792be1affc37f107b Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Fri, 7 May 2010 21:47:27 +0200 Subject: Staging: batman-adv: Update pointer to ethhdr after skb_copy We must ensure that all pointer to a socket buffer are updated when we copy a socket buffer and free our reference to the old one. Another part of the kernel could also free its reference which maybe removes the buffer completely. In that situation we would would feed wrong information to the routing algorithm after the memory area is written again by someone else. Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/routing.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index bf67059e3ee1..919a4f8de192 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -614,6 +614,7 @@ int recv_bat_packet(struct sk_buff *skb, skb = skb_copy(skb, GFP_ATOMIC); if (!skb) return NET_RX_DROP; + ethhdr = (struct ethhdr *)skb_mac_header(skb); kfree_skb(skb_old); } @@ -639,8 +640,8 @@ static int recv_my_icmp_packet(struct sk_buff *skb) unsigned long flags; uint8_t dstaddr[ETH_ALEN]; - icmp_packet = (struct icmp_packet *) skb->data; - ethhdr = (struct ethhdr *) skb_mac_header(skb); + icmp_packet = (struct icmp_packet *)skb->data; + ethhdr = (struct ethhdr *)skb_mac_header(skb); /* add data to device queue */ if (icmp_packet->msg_type != ECHO_REQUEST) { @@ -671,7 +672,9 @@ static int recv_my_icmp_packet(struct sk_buff *skb) skb = skb_copy(skb, GFP_ATOMIC); if (!skb) return NET_RX_DROP; - icmp_packet = (struct icmp_packet *) skb->data; + + icmp_packet = (struct icmp_packet *)skb->data; + ethhdr = (struct ethhdr *)skb_mac_header(skb); kfree_skb(skb_old); } @@ -732,6 +735,7 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb) if (!skb) return NET_RX_DROP; icmp_packet = (struct icmp_packet *) skb->data; + ethhdr = (struct ethhdr *)skb_mac_header(skb); kfree_skb(skb_old); } @@ -780,7 +784,7 @@ int recv_icmp_packet(struct sk_buff *skb) if (!is_my_mac(ethhdr->h_dest)) return NET_RX_DROP; - icmp_packet = (struct icmp_packet *) skb->data; + icmp_packet = (struct icmp_packet *)skb->data; /* packet for me */ if (is_my_mac(icmp_packet->dst)) @@ -812,7 +816,8 @@ int recv_icmp_packet(struct sk_buff *skb) skb = skb_copy(skb, GFP_ATOMIC); if (!skb) return NET_RX_DROP; - icmp_packet = (struct icmp_packet *) skb->data; + icmp_packet = (struct icmp_packet *)skb->data; + ethhdr = (struct ethhdr *)skb_mac_header(skb); kfree_skb(skb_old); } @@ -895,7 +900,8 @@ int recv_unicast_packet(struct sk_buff *skb) skb = skb_copy(skb, GFP_ATOMIC); if (!skb) return NET_RX_DROP; - unicast_packet = (struct unicast_packet *) skb->data; + unicast_packet = (struct unicast_packet *)skb->data; + ethhdr = (struct ethhdr *)skb_mac_header(skb); kfree_skb(skb_old); } /* decrement ttl */ -- cgit v1.2.3 From cee42f49931e610f47229385709385cc98efb856 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Fri, 7 May 2010 21:47:28 +0200 Subject: Staging: batman-adv: Update TODO file to reflect current state. Not much left to do on the TODO list :-) Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/TODO | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/TODO b/drivers/staging/batman-adv/TODO index 2f15136b18e7..518db7fd41b1 100644 --- a/drivers/staging/batman-adv/TODO +++ b/drivers/staging/batman-adv/TODO @@ -1,23 +1,6 @@ -=> proc interface -* implement new interface to add/delete interfaces and setting options -* /proc/sys/net/batman-adv/ as main folder -* in interfaces/ list every available interface of the host -* each interfaces/$iface/ contains the following files: --> enable (def: 0) [add/remove this interface to batman-adv] --> ogm_interval (def: 1000) [ogm interval of that interface] --> context (def: bat0) [later we want to support multiple mesh instances via --> bat0/bat1/bat2/..] --> status (read-only) [outputs the interface status from batman's --> perspective] -* in mesh/batX/ list every available mesh subnet --> vis_server (def: 0) [enable/disable vis server for that mesh] --> vis_data (read-only) [outputs the vis data in a raw format] --> aggregate_ogm (def: 1) [enable/disable ogm aggregation for that mesh] --> originators (read-only) [outputs the originator table] --> transtable_global (read-only) [outputs the global translation table] --> transtable_local (read-only) [outputs the local translation table] - -=> fix checkpatch.pl errors +Request a review. +Process the comments from the review. +Move into mainline proper. Please send all patches to: Marek Lindner -- cgit v1.2.3 From f9ab70e787c3b94ce7c56324b4afbc8051e99424 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Fri, 7 May 2010 21:47:29 +0200 Subject: Staging: batman-adv: Fix whitespace problems criticized by checkpatch.pl Trailing spaces at the end of a line or before a tab are against Documentation/CodingStyle "3.1: Spaces" and should be avoided. It is also common style to add a single space after commas unless it is followed either by a newline or a tab. Reported-by: Mikal Sande Reported-by: Luis de Bethencourt Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/main.h | 2 +- drivers/staging/batman-adv/originator.c | 4 ++-- drivers/staging/batman-adv/types.h | 3 +-- drivers/staging/batman-adv/vis.c | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 6749ce036b91..8818e2b80938 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -70,7 +70,7 @@ #define MODULE_DEACTIVATING 2 #define BCAST_QUEUE_LEN 256 -#define BATMAN_QUEUE_LE 256 +#define BATMAN_QUEUE_LEN 256 /* * Debug Messages diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 01d71d7ed420..25a9e215e1a0 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -297,7 +297,7 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, rcu_read_lock(); hdr_len = sprintf(buff, - " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)] \n", + " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)]\n", "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF", "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR, bat_priv->primary_if->dev, bat_priv->primary_if->addr_str, @@ -354,7 +354,7 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, if ((batman_count == 0) && (off == 0)) bytes_written += sprintf(buff + bytes_written, - "No batman nodes in range ... \n"); + "No batman nodes in range ...\n"); return bytes_written; } diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index c92621965b3d..0b1fe9e95441 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -59,8 +59,7 @@ struct orig_node { /* structure for orig_list maintaining nodes of seqno window was reset. */ unsigned long batman_seqno_reset;/* time when the batman seqno window was reset. */ -/* uint8_t gwflags; * flags related to gateway functions: gateway class */ - uint8_t flags; /* for now only VIS_SERVER flag. */ + uint8_t flags; /* for now only VIS_SERVER flag. */ unsigned char *hna_buff; int16_t hna_buff_len; uint16_t last_real_seqno; /* last and best known squence number */ diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index b6ff031a34d0..1d3d954847fd 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -40,7 +40,7 @@ * when adding 128 - it is neither a predecessor nor a successor, * after adding more than 127 to the starting value - it is a successor */ #define seq_before(x, y) ({typeof(x) _dummy = (x - y); \ - _dummy > smallest_signed_int(_dummy); }) + _dummy > smallest_signed_int(_dummy); }) #define seq_after(x, y) seq_before(y, x) struct hashtable_t *vis_hash; -- cgit v1.2.3 From 6d45d8df243054614d795901c03817e21bfde964 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Fri, 7 May 2010 21:47:30 +0200 Subject: Staging: batman-adv: Reduce max characters on a line to 80 Documentation/CodingStyle sets a strongly prefered limit of 80 characters per line in "Chapter 2: Breaking long lines and strings". Strings must be broken into smaller parts and long statements must be rewritten. Reported-by: Mikal Sande Reported-by: Mark Rankilor Signed-off-by: Sven Eckelmann Signed-off-by: Marek Lindner Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/device.c | 22 +++++++--- drivers/staging/batman-adv/hard-interface.c | 20 ++++++--- drivers/staging/batman-adv/main.c | 17 +++++--- drivers/staging/batman-adv/main.h | 3 +- drivers/staging/batman-adv/originator.c | 47 +++++++++++++-------- drivers/staging/batman-adv/routing.c | 57 +++++++++++++++++++------- drivers/staging/batman-adv/send.c | 21 ++++++---- drivers/staging/batman-adv/soft-interface.c | 8 ++-- drivers/staging/batman-adv/translation-table.c | 34 +++++++++------ drivers/staging/batman-adv/types.h | 45 ++++++++++++++------ 10 files changed, 186 insertions(+), 88 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c index b2ecba2d40ab..ad82ec4a4856 100644 --- a/drivers/staging/batman-adv/device.c +++ b/drivers/staging/batman-adv/device.c @@ -57,7 +57,8 @@ int bat_device_setup(void) /* register our device - kernel assigns a free major number */ tmp_major = register_chrdev(0, DRIVER_DEVICE, &fops); if (tmp_major < 0) { - printk(KERN_ERR "batman-adv:Registering the character device failed with %d\n", + printk(KERN_ERR "batman-adv:" + "Registering the character device failed with %d\n", tmp_major); return 0; } @@ -65,7 +66,8 @@ int bat_device_setup(void) batman_class = class_create(THIS_MODULE, "batman-adv"); if (IS_ERR(batman_class)) { - printk(KERN_ERR "batman-adv:Could not register class 'batman-adv'\n"); + printk(KERN_ERR "batman-adv:" + "Could not register class 'batman-adv'\n"); return 0; } @@ -108,7 +110,9 @@ int bat_device_open(struct inode *inode, struct file *file) } if (i == ARRAY_SIZE(device_client_hash)) { - printk(KERN_ERR "batman-adv:Error - can't add another packet client: maximum number of clients reached\n"); + printk(KERN_ERR "batman-adv:" + "Error - can't add another packet client: " + "maximum number of clients reached\n"); kfree(device_client); return -EXFULL; } @@ -209,7 +213,9 @@ ssize_t bat_device_write(struct file *file, const char __user *buff, unsigned long flags; if (len < sizeof(struct icmp_packet)) { - bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: invalid packet size\n"); + bat_dbg(DBG_BATMAN, "batman-adv:" + "Error - can't send packet from char device: " + "invalid packet size\n"); return -EINVAL; } @@ -220,12 +226,16 @@ ssize_t bat_device_write(struct file *file, const char __user *buff, return -EFAULT; if (icmp_packet.packet_type != BAT_ICMP) { - bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n"); + bat_dbg(DBG_BATMAN, "batman-adv:" + "Error - can't send packet from char device: " + "got bogus packet type (expected: BAT_ICMP)\n"); return -EINVAL; } if (icmp_packet.msg_type != ECHO_REQUEST) { - bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n"); + bat_dbg(DBG_BATMAN, "batman-adv:" + "Error - can't send packet from char device: " + "got bogus message type (expected: ECHO_REQUEST)\n"); return -EINVAL; } diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c index b82cae79c42b..0d1d1011dd44 100644 --- a/drivers/staging/batman-adv/hard-interface.c +++ b/drivers/staging/batman-adv/hard-interface.c @@ -149,9 +149,12 @@ static void check_known_mac_addr(uint8_t *addr) if (!compare_orig(batman_if->net_dev->dev_addr, addr)) continue; - printk(KERN_WARNING "batman-adv:The newly added mac address (%pM) already exists on: %s\n", - addr, batman_if->dev); - printk(KERN_WARNING "batman-adv:It is strongly recommended to keep mac addresses unique to avoid problems!\n"); + printk(KERN_WARNING "batman-adv:" + "The newly added mac address (%pM) already exists on: %s\n", + addr, batman_if->dev); + printk(KERN_WARNING "batman-adv:" + "It is strongly recommended to keep mac addresses unique" + "to avoid problems!\n"); } rcu_read_unlock(); } @@ -242,7 +245,8 @@ int hardif_enable_interface(struct batman_if *batman_if) batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_ATOMIC); if (!batman_if->packet_buff) { - printk(KERN_ERR "batman-adv:Can't add interface packet (%s): out of memory\n", + printk(KERN_ERR "batman-adv:" + "Can't add interface packet (%s): out of memory\n", batman_if->dev); goto err; } @@ -266,7 +270,10 @@ int hardif_enable_interface(struct batman_if *batman_if) if (hardif_is_iface_up(batman_if)) hardif_activate_interface(bat_priv, batman_if); else - printk(KERN_ERR "batman-adv:Not using interface %s (retrying later): interface not active\n", batman_if->dev); + printk(KERN_ERR "batman-adv:" + "Not using interface %s " + "(retrying later): interface not active\n", + batman_if->dev); /* begin scheduling originator messages on that interface */ schedule_own_packet(batman_if); @@ -316,7 +323,8 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev) batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC); if (!batman_if) { - printk(KERN_ERR "batman-adv:Can't add interface (%s): out of memory\n", + printk(KERN_ERR "batman-adv:" + "Can't add interface (%s): out of memory\n", net_dev->name); goto out; } diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index aa072d15134c..9d13979c2d8e 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -99,14 +99,16 @@ int init_module(void) interface_setup); if (!soft_device) { - printk(KERN_ERR "batman-adv:Unable to allocate the batman interface\n"); + printk(KERN_ERR "batman-adv:" + "Unable to allocate the batman interface\n"); goto end; } retval = register_netdev(soft_device); if (retval < 0) { - printk(KERN_ERR "batman-adv:Unable to register the batman interface: %i\n", retval); + printk(KERN_ERR "batman-adv:" + "Unable to register the batman interface: %i\n", retval); goto free_soft_device; } @@ -118,8 +120,9 @@ int init_module(void) register_netdevice_notifier(&hard_if_notifier); dev_add_pack(&batman_adv_packet_type); - printk(KERN_INFO "batman-adv:B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded\n", - SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION); + printk(KERN_INFO "batman-adv:" + "B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded\n", + SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION); return 0; @@ -176,7 +179,9 @@ void activate_module(void) goto end; err: - printk(KERN_ERR "batman-adv:Unable to allocate memory for mesh information structures: out of mem ?\n"); + printk(KERN_ERR "batman-adv:" + "Unable to allocate memory for mesh information structures: " + "out of mem ?\n"); deactivate_module(); end: return; @@ -218,7 +223,7 @@ void dec_module_count(void) int addr_to_string(char *buff, uint8_t *addr) { - return sprintf(buff, "%02x:%02x:%02x:%02x:%02x:%02x", + return sprintf(buff, MAC_FMT, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); } diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 8818e2b80938..5f8343d360f6 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -22,7 +22,8 @@ /* Kernel Programming */ #define LINUX -#define DRIVER_AUTHOR "Marek Lindner , Simon Wunderlich " +#define DRIVER_AUTHOR "Marek Lindner , " \ + "Simon Wunderlich " #define DRIVER_DESC "B.A.T.M.A.N. advanced" #define DRIVER_DEVICE "batman-adv" diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 25a9e215e1a0..568aef8371be 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -140,8 +140,10 @@ struct orig_node *get_orig_node(uint8_t *addr) memcpy(orig_node->orig, addr, ETH_ALEN); orig_node->router = NULL; orig_node->hna_buff = NULL; - orig_node->bcast_seqno_reset = jiffies - msecs_to_jiffies(RESET_PROTECTION_MS) - 1; - orig_node->batman_seqno_reset = jiffies - msecs_to_jiffies(RESET_PROTECTION_MS) - 1; + orig_node->bcast_seqno_reset = jiffies - 1 + - msecs_to_jiffies(RESET_PROTECTION_MS); + orig_node->batman_seqno_reset = jiffies - 1 + - msecs_to_jiffies(RESET_PROTECTION_MS); size = bat_priv->num_ifaces * sizeof(TYPE_OF_WORD) * NUM_WORDS; @@ -198,11 +200,15 @@ static bool purge_orig_neighbors(struct orig_node *orig_node, if (neigh_node->if_incoming->if_status == IF_TO_BE_REMOVED) - bat_dbg(DBG_BATMAN, "neighbor purge: originator %pM, neighbor: %pM, iface: %s\n", + bat_dbg(DBG_BATMAN, + "neighbor purge: originator %pM, " + "neighbor: %pM, iface: %s\n", orig_node->orig, neigh_node->addr, neigh_node->if_incoming->dev); else - bat_dbg(DBG_BATMAN, "neighbor timeout: originator %pM, neighbor: %pM, last_valid: %lu\n", + bat_dbg(DBG_BATMAN, + "neighbor timeout: originator %pM, " + "neighbor: %pM, last_valid: %lu\n", orig_node->orig, neigh_node->addr, (neigh_node->last_valid / HZ)); @@ -280,24 +286,25 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, if (!bat_priv->primary_if) { if (off == 0) return sprintf(buff, - "BATMAN mesh %s disabled - please specify interfaces to enable it\n", - net_dev->name); + "BATMAN mesh %s disabled - " + "please specify interfaces to enable it\n", + net_dev->name); return 0; } - if (bat_priv->primary_if->if_status != IF_ACTIVE) { - if (off == 0) - return sprintf(buff, - "BATMAN mesh %s disabled - primary interface not active\n", - net_dev->name); - + if (bat_priv->primary_if->if_status != IF_ACTIVE && off == 0) + return sprintf(buff, + "BATMAN mesh %s " + "disabled - primary interface not active\n", + net_dev->name); + else if (bat_priv->primary_if->if_status != IF_ACTIVE) return 0; - } rcu_read_lock(); hdr_len = sprintf(buff, - " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)]\n", + " %-14s (%s/%i) %17s [%10s]: %20s " + "... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)]\n", "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF", "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR, bat_priv->primary_if->dev, bat_priv->primary_if->addr_str, @@ -366,7 +373,8 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num) data_ptr = kmalloc(max_if_num * sizeof(TYPE_OF_WORD) * NUM_WORDS, GFP_ATOMIC); if (!data_ptr) { - printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); + printk(KERN_ERR + "batman-adv:Can't resize orig: out of memory\n"); return -1; } @@ -377,7 +385,8 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num) data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); if (!data_ptr) { - printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); + printk(KERN_ERR + "batman-adv:Can't resize orig: out of memory\n"); return -1; } @@ -426,7 +435,8 @@ static int orig_node_del_if(struct orig_node *orig_node, chunk_size = sizeof(TYPE_OF_WORD) * NUM_WORDS; data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC); if (!data_ptr) { - printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); + printk(KERN_ERR + "batman-adv:Can't resize orig: out of memory\n"); return -1; } @@ -447,7 +457,8 @@ free_bcast_own: data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); if (!data_ptr) { - printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); + printk(KERN_ERR + "batman-adv:Can't resize orig: out of memory\n"); return -1; } diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 919a4f8de192..066dc8b38817 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -94,7 +94,11 @@ static void update_route(struct orig_node *orig_node, /* route changed */ } else { - bat_dbg(DBG_ROUTES, "Changing route towards: %pM (now via %pM - was via %pM)\n", orig_node->orig, neigh_node->addr, orig_node->router->addr); + bat_dbg(DBG_ROUTES, + "Changing route towards: %pM " + "(now via %pM - was via %pM)\n", + orig_node->orig, neigh_node->addr, + orig_node->router->addr); } orig_node->router = neigh_node; @@ -207,7 +211,11 @@ static int isBidirectionalNeigh(struct orig_node *orig_node, orig_neigh_node->tq_asym_penalty) / (TQ_MAX_VALUE * TQ_MAX_VALUE)); - bat_dbg(DBG_BATMAN, "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i\n", + bat_dbg(DBG_BATMAN, + "bidirectional: " + "orig = %-15pM neigh = %-15pM => own_bcast = %2i, " + "real recv = %2i, local tq: %3i, asym_penalty: %3i, " + "total tq: %3i\n", orig_node->orig, orig_neigh_node->orig, total_count, neigh_node->real_packet_count, orig_neigh_node->tq_own, orig_neigh_node->tq_asym_penalty, batman_packet->tq); @@ -229,7 +237,8 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; int tmp_hna_buff_len; - bat_dbg(DBG_BATMAN, "update_originator(): Searching and updating originator entry of received packet\n"); + bat_dbg(DBG_BATMAN, "update_originator(): " + "Searching and updating originator entry of received packet\n"); list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && @@ -422,7 +431,9 @@ void receive_bat_packet(struct ethhdr *ethhdr, is_single_hop_neigh = (compare_orig(ethhdr->h_source, batman_packet->orig) ? 1 : 0); - bat_dbg(DBG_BATMAN, "Received BATMAN packet via NB: %pM, IF: %s [%s] (from OG: %pM, via prev OG: %pM, seqno %d, tq %d, TTL %d, V %d, IDF %d)\n", + bat_dbg(DBG_BATMAN, "Received BATMAN packet via NB: %pM, IF: %s [%s] " + "(from OG: %pM, via prev OG: %pM, seqno %d, tq %d, " + "TTL %d, V %d, IDF %d)\n", ethhdr->h_source, if_incoming->dev, if_incoming->addr_str, batman_packet->orig, batman_packet->prev_sender, batman_packet->seqno, batman_packet->tq, batman_packet->ttl, @@ -457,13 +468,16 @@ void receive_bat_packet(struct ethhdr *ethhdr, if (is_my_addr) { bat_dbg(DBG_BATMAN, - "Drop packet: received my own broadcast (sender: %pM)\n", + "Drop packet: received my own broadcast (sender: %pM" + ")\n", ethhdr->h_source); return; } if (is_broadcast) { - bat_dbg(DBG_BATMAN, "Drop packet: ignoring all packets with broadcast source addr (sender: %pM)\n", ethhdr->h_source); + bat_dbg(DBG_BATMAN, "Drop packet: " + "ignoring all packets with broadcast source addr (sender: %pM" + ")\n", ethhdr->h_source); return; } @@ -491,12 +505,15 @@ void receive_bat_packet(struct ethhdr *ethhdr, bit_packet_count(word); } - bat_dbg(DBG_BATMAN, "Drop packet: originator packet from myself (via neighbor)\n"); + bat_dbg(DBG_BATMAN, "Drop packet: " + "originator packet from myself (via neighbor)\n"); return; } if (is_my_oldorig) { - bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast echos (sender: %pM)\n", ethhdr->h_source); + bat_dbg(DBG_BATMAN, + "Drop packet: ignoring all rebroadcast echos (sender: " + "%pM)\n", ethhdr->h_source); return; } @@ -507,12 +524,15 @@ void receive_bat_packet(struct ethhdr *ethhdr, is_duplicate = count_real_packets(ethhdr, batman_packet, if_incoming); if (is_duplicate == -1) { - bat_dbg(DBG_BATMAN, "Drop packet: packet within seqno protection time (sender: %pM)\n", ethhdr->h_source); + bat_dbg(DBG_BATMAN, + "Drop packet: packet within seqno protection time " + "(sender: %pM)\n", ethhdr->h_source); return; } if (batman_packet->tq == 0) { - bat_dbg(DBG_BATMAN, "Drop packet: originator packet with tq equal 0\n"); + bat_dbg(DBG_BATMAN, + "Drop packet: originator packet with tq equal 0\n"); return; } @@ -524,7 +544,9 @@ void receive_bat_packet(struct ethhdr *ethhdr, !(compare_orig(batman_packet->orig, batman_packet->prev_sender)) && (compare_orig(orig_node->router->addr, orig_node->router->orig_node->router->addr))) { - bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM)\n", ethhdr->h_source); + bat_dbg(DBG_BATMAN, + "Drop packet: ignoring all rebroadcast packets that " + "may make me loop (sender: %pM)\n", ethhdr->h_source); return; } @@ -562,7 +584,8 @@ void receive_bat_packet(struct ethhdr *ethhdr, schedule_forward_packet(orig_node, ethhdr, batman_packet, 1, hna_buff_len, if_incoming); - bat_dbg(DBG_BATMAN, "Forwarding packet: rebroadcast neighbor packet with direct link flag\n"); + bat_dbg(DBG_BATMAN, "Forwarding packet: " + "rebroadcast neighbor packet with direct link flag\n"); return; } @@ -708,8 +731,10 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb) /* send TTL exceeded if packet is an echo request (traceroute) */ if (icmp_packet->msg_type != ECHO_REQUEST) { - printk(KERN_WARNING "batman-adv:Warning - can't forward icmp packet from %pM to %pM: ttl exceeded\n", - icmp_packet->orig, icmp_packet->dst); + printk(KERN_WARNING "batman-adv:" + "Warning - can't forward icmp packet from %pM to %pM: " + "ttl exceeded\n", + icmp_packet->orig, icmp_packet->dst); return NET_RX_DROP; } @@ -874,7 +899,9 @@ int recv_unicast_packet(struct sk_buff *skb) /* TTL exceeded */ if (unicast_packet->ttl < 2) { - printk(KERN_WARNING "batman-adv:Warning - can't forward unicast packet from %pM to %pM: ttl exceeded\n", + printk(KERN_WARNING "batman-adv:Warning - " + "can't forward unicast packet from %pM to %pM: " + "ttl exceeded\n", ethhdr->h_source, unicast_packet->dest); return NET_RX_DROP; } diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index f58a9edfc2cc..d8536e277a26 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -65,7 +65,8 @@ int send_skb_packet(struct sk_buff *skb, if (!(batman_if->net_dev->flags & IFF_UP)) { printk(KERN_WARNING - "batman-adv:Interface %s is not up - can't send packet via that interface!\n", + "batman-adv:Interface %s " + "is not up - can't send packet via that interface!\n", batman_if->dev); goto send_skb_err; } @@ -148,9 +149,9 @@ static void send_packet_to_if(struct forw_packet *forw_packet, "Sending own" : "Forwarding")); bat_dbg(DBG_BATMAN, - "%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d, IDF %s) on interface %s [%s]\n", - fwd_str, - (packet_num > 0 ? "aggregated " : ""), + "%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d," + " IDF %s) on interface %s [%s]\n", + fwd_str, (packet_num > 0 ? "aggregated " : ""), batman_packet->orig, ntohs(batman_packet->seqno), batman_packet->tq, batman_packet->ttl, (batman_packet->flags & DIRECTLINK ? @@ -178,7 +179,8 @@ static void send_packet(struct forw_packet *forw_packet) unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0); if (!forw_packet->if_incoming) { - printk(KERN_ERR "batman-adv: Error - can't forward packet: incoming iface not specified\n"); + printk(KERN_ERR "batman-adv: Error - can't forward packet: " + "incoming iface not specified\n"); return; } @@ -192,7 +194,8 @@ static void send_packet(struct forw_packet *forw_packet) /* FIXME: what about aggregated packets ? */ bat_dbg(DBG_BATMAN, - "%s packet (originator %pM, seqno %d, TTL %d) on interface %s [%s]\n", + "%s packet (originator %pM, seqno %d, TTL %d) " + "on interface %s [%s]\n", (forw_packet->own ? "Sending own" : "Forwarding"), batman_packet->orig, ntohs(batman_packet->seqno), batman_packet->ttl, forw_packet->if_incoming->dev, @@ -322,7 +325,8 @@ void schedule_forward_packet(struct orig_node *orig_node, batman_packet->tq = orig_node->router->tq_avg; if (orig_node->router->last_ttl) - batman_packet->ttl = orig_node->router->last_ttl - 1; + batman_packet->ttl = orig_node->router->last_ttl + - 1; } tq_avg = orig_node->router->tq_avg; @@ -331,7 +335,8 @@ void schedule_forward_packet(struct orig_node *orig_node, /* apply hop penalty */ batman_packet->tq = hop_penalty(batman_packet->tq); - bat_dbg(DBG_BATMAN, "Forwarding packet: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n", + bat_dbg(DBG_BATMAN, "Forwarding packet: tq_orig: %i, tq_avg: %i, " + "tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n", in_tq, tq_avg, batman_packet->tq, in_ttl - 1, batman_packet->ttl); diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index c3b52885b086..51c40b77c8d7 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -237,6 +237,8 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) if ((orig_node) && (orig_node->router)) { + struct neigh_node *router = orig_node->router; + if (my_skb_push(skb, sizeof(struct unicast_packet)) < 0) goto unlock; @@ -251,14 +253,14 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); /* net_dev won't be available when not active */ - if (orig_node->router->if_incoming->if_status != IF_ACTIVE) + if (router->if_incoming->if_status != IF_ACTIVE) goto unlock; /* don't lock while sending the packets ... we therefore * copy the required data before sending */ - batman_if = orig_node->router->if_incoming; - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); + batman_if = router->if_incoming; + memcpy(dstaddr, router->addr, ETH_ALEN); spin_unlock_irqrestore(&orig_hash_lock, flags); send_skb_packet(skb, batman_if, dstaddr); diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c index c7a6635e34ad..e01ff2151f76 100644 --- a/drivers/staging/batman-adv/translation-table.c +++ b/drivers/staging/batman-adv/translation-table.c @@ -77,7 +77,10 @@ void hna_local_add(uint8_t *addr) MAC-flooding. */ if ((num_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN) / ETH_ALEN) || (num_hna + 1 > 255)) { - bat_dbg(DBG_ROUTES, "Can't add new local hna entry (%pM): number of local hna entries exceeds packet size\n", addr); + bat_dbg(DBG_ROUTES, + "Can't add new local hna entry (%pM): " + "number of local hna entries exceeds packet size\n", + addr); return; } @@ -108,7 +111,8 @@ void hna_local_add(uint8_t *addr) hna_local_hash->size * 2); if (swaphash == NULL) - printk(KERN_ERR "batman-adv:Couldn't resize local hna hash table\n"); + printk(KERN_ERR "batman-adv:" + "Couldn't resize local hna hash table\n"); else hna_local_hash = swaphash; } @@ -169,14 +173,16 @@ int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff, if (!bat_priv->primary_if) { if (off == 0) return sprintf(buff, - "BATMAN mesh %s disabled - please specify interfaces to enable it\n", - net_dev->name); + "BATMAN mesh %s disabled - " + "please specify interfaces to enable it\n", + net_dev->name); return 0; } hdr_len = sprintf(buff, - "Locally retrieved addresses (from %s) announced via HNA:\n", + "Locally retrieved addresses (from %s) " + "announced via HNA:\n", net_dev->name); if (off < hdr_len) @@ -196,7 +202,7 @@ int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff, hna_local_entry = hashit.bucket->data; bytes_written += snprintf(buff + bytes_written, 22, - " * %02x:%02x:%02x:%02x:%02x:%02x\n", + " * " MAC_FMT "\n", hna_local_entry->addr[0], hna_local_entry->addr[1], hna_local_entry->addr[2], @@ -317,7 +323,8 @@ void hna_global_add_orig(struct orig_node *orig_node, memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN); bat_dbg(DBG_ROUTES, - "Creating new global hna entry: %pM (via %pM)\n", + "Creating new global hna entry: " + "%pM (via %pM)\n", hna_global_entry->addr, orig_node->orig); spin_lock_irqsave(&hna_global_hash_lock, flags); @@ -362,7 +369,8 @@ void hna_global_add_orig(struct orig_node *orig_node, hna_global_hash->size * 2); if (swaphash == NULL) - printk(KERN_ERR "batman-adv:Couldn't resize global hna hash table\n"); + printk(KERN_ERR "batman-adv:" + "Couldn't resize global hna hash table\n"); else hna_global_hash = swaphash; } @@ -383,14 +391,16 @@ int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff, if (!bat_priv->primary_if) { if (off == 0) return sprintf(buff, - "BATMAN mesh %s disabled - please specify interfaces to enable it\n", - net_dev->name); + "BATMAN mesh %s disabled - " + "please specify interfaces to enable it\n", + net_dev->name); return 0; } hdr_len = sprintf(buff, - "Globally announced HNAs received via the mesh %s (translation table):\n", + "Globally announced HNAs received via the mesh %s " + "(translation table):\n", net_dev->name); if (off < hdr_len) @@ -410,7 +420,7 @@ int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff, hna_global_entry = hashit.bucket->data; bytes_written += snprintf(buff + bytes_written, 44, - " * %02x:%02x:%02x:%02x:%02x:%02x via %02x:%02x:%02x:%02x:%02x:%02x\n", + " * " MAC_FMT " via " MAC_FMT "\n", hna_global_entry->addr[0], hna_global_entry->addr[1], hna_global_entry->addr[2], diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index 0b1fe9e95441..86007c7eb443 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -29,7 +29,10 @@ #include "packet.h" #include "bitarray.h" -#define BAT_HEADER_LEN (sizeof(struct ethhdr) + ((sizeof(struct unicast_packet) > sizeof(struct bcast_packet) ? sizeof(struct unicast_packet) : sizeof(struct bcast_packet)))) +#define BAT_HEADER_LEN (sizeof(struct ethhdr) + \ + ((sizeof(struct unicast_packet) > sizeof(struct bcast_packet) ? \ + sizeof(struct unicast_packet) : \ + sizeof(struct bcast_packet)))) struct batman_if { @@ -47,28 +50,40 @@ struct batman_if { }; -struct orig_node { /* structure for orig_list maintaining nodes of mesh */ +/** + * orig_node - structure for orig_list maintaining nodes of mesh + * @last_valid: when last packet from this node was received + * @bcast_seqno_reset: time when the broadcast seqno window was reset + * @batman_seqno_reset: time when the batman seqno window was reset + * @flags: for now only VIS_SERVER flag + * @last_real_seqno: last and best known squence number + * @last_ttl: ttl of last received packet + * @last_bcast_seqno: last broadcast sequence number received by this host + */ +struct orig_node { uint8_t orig[ETH_ALEN]; struct neigh_node *router; TYPE_OF_WORD *bcast_own; uint8_t *bcast_own_sum; uint8_t tq_own; int tq_asym_penalty; - unsigned long last_valid; /* when last packet from this node was received */ - unsigned long bcast_seqno_reset; /* time when the broadcast - seqno window was reset. */ - unsigned long batman_seqno_reset;/* time when the batman seqno - window was reset. */ - uint8_t flags; /* for now only VIS_SERVER flag. */ + unsigned long last_valid; + unsigned long bcast_seqno_reset; + unsigned long batman_seqno_reset; + uint8_t flags; unsigned char *hna_buff; int16_t hna_buff_len; - uint16_t last_real_seqno; /* last and best known squence number */ - uint8_t last_ttl; /* ttl of last received packet */ + uint16_t last_real_seqno; + uint8_t last_ttl; TYPE_OF_WORD bcast_bits[NUM_WORDS]; - uint16_t last_bcast_seqno; /* last broadcast sequence number received by this host */ + uint16_t last_bcast_seqno; struct list_head neigh_list; }; +/** + * neigh_node + * @last_valid: when last packet via this neighbor was received + */ struct neigh_node { struct list_head list; uint8_t addr[ETH_ALEN]; @@ -77,7 +92,7 @@ struct neigh_node { uint8_t tq_index; uint8_t tq_avg; uint8_t last_ttl; - unsigned long last_valid; /* when last packet via this neighbor was received */ + unsigned long last_valid; TYPE_OF_WORD real_bits[NUM_WORDS]; struct orig_node *orig_node; struct batman_if *if_incoming; @@ -117,7 +132,11 @@ struct hna_global_entry { struct orig_node *orig_node; }; -struct forw_packet { /* structure for forw_list maintaining packets to be send/forwarded */ +/** + * forw_packet - structure for forw_list maintaining packets to be + * send/forwarded + */ +struct forw_packet { struct hlist_node list; unsigned long send_time; uint8_t own; -- cgit v1.2.3 From 2d06efdb48e412b90a67c3986222fd5743400e37 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Fri, 7 May 2010 21:47:31 +0200 Subject: Staging: batman-adv: updating README Signed-off-by: Marek Lindner Signed-off-by: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/README | 275 ++++++++++++++++++++++++-------------- 1 file changed, 173 insertions(+), 102 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/README b/drivers/staging/batman-adv/README index e2a72718f3f7..14244a2c4e4f 100644 --- a/drivers/staging/batman-adv/README +++ b/drivers/staging/batman-adv/README @@ -1,169 +1,240 @@ -[state: 22-03-2010] +[state: 03-05-2010] BATMAN-ADV ---------- -Batman-advanced is a new approach to wireless networking which does no longer -operate on the IP basis. Unlike B.A.T.M.A.N, which exchanges information -using UDP packets and sets routing tables, batman-advanced operates on ISO/OSI -Layer 2 only and uses and routes (or better: bridges) Ethernet Frames. It -emulates a virtual network switch of all nodes participating. Therefore all -nodes appear to be link local, thus all higher operating protocols won't be -affected by any changes within the network. You can run almost any protocol -above B.A.T.M.A.N. Advanced, prominent examples are: IPv4, IPv6, DHCP, IPX. +Batman advanced is a new approach to wireless networking which +does no longer operate on the IP basis. Unlike the batman daemon, +which exchanges information using UDP packets and sets routing +tables, batman-advanced operates on ISO/OSI Layer 2 only and uses +and routes (or better: bridges) Ethernet Frames. It emulates a +virtual network switch of all nodes participating. Therefore all +nodes appear to be link local, thus all higher operating proto- +cols won't be affected by any changes within the network. You can +run almost any protocol above batman advanced, prominent examples +are: IPv4, IPv6, DHCP, IPX. -This is batman-advanced implemented as Linux kernel driver. It does not depend -on any network (other) driver, and can be used on wifi as well as ethernet, -vpn, etc ... (anything with ethernet-style layer 2). +Batman advanced was implemented as a Linux kernel driver to re- +duce the overhead to a minimum. It does not depend on any (other) +network driver, and can be used on wifi as well as ethernet lan, +vpn, etc ... (anything with ethernet-style layer 2). -USAGE ------ +CONFIGURATION +------------- -insmod the batman-adv.ko in your kernel: +Load the batman-adv module into your kernel: # insmod batman-adv.ko -the module is now waiting for activation. You must add some interfaces -on which batman can operate. Each interface must be added separately: +The module is now waiting for activation. You must add some in- +terfaces on which batman can operate. After loading the module +batman advanced will scan your systems interfaces to search for +compatible interfaces. Once found, it will create subfolders in +the /sys directories of each supported interface, e.g. -# echo wlan0 > /proc/net/batman-adv/interfaces +# ls /sys/class/net/eth0/batman_adv/ +# iface_status mesh_iface -( # echo wlan1 > /proc/net/batman-adv/interfaces ) -( # echo eth0 > /proc/net/batman-adv/interfaces ) -( ... ) +If an interface does not have the "batman_adv" subfolder it prob- +ably is not supported. Not supported interfaces are: loopback, +non-ethernet and batman's own interfaces. -Now batman starts broadcasting on this interface. -You can now view the table of originators (mesh participants) with: +Note: After the module was loaded it will continuously watch for +new interfaces to verify the compatibility. There is no need to +reload the module if you plug your USB wifi adapter into your ma- +chine after batman advanced was initially loaded. -# cat /proc/net/batman-adv/originators +To activate a given interface simply write "bat0" into its +"mesh_iface" file inside the batman_adv subfolder: -The module will create a new interface "bat0", which can be used as a -regular interface: +# echo bat0 > /sys/class/net/eth0/batman_adv/mesh_iface -# ifconfig bat0 inet 192.168.0.1 up -# ping 192.168.0.2 -... +Repeat this step for all interfaces you wish to add. Now batman +starts using/broadcasting on this/these interface(s). ---- -If you want topology visualization, your meshnode must be configured -as VIS-server: +By reading the "iface_status" file you can check its status: -# echo "server" > /proc/net/batman-adv/vis_server +# cat /sys/class/net/eth0/batman_adv/iface_status +# active -Each node is either configured as "server" or as "client" (default: -"client"). Clients send their topology data to the server next to them, -and server synchronize with other servers. If there is no server -configured (default) within the mesh, no topology information will be -transmitted. With these "synchronizing servers", there can be 1 or -more vis servers sharing the same (or at least very similar) data. +To deactivate an interface you have to write "none" into its +"mesh_iface" file: -When configured as server, you can get a topology snapshot of your mesh: +# echo none > /sys/class/net/eth0/batman_adv/mesh_iface -# cat /proc/net/batman-adv/vis_data -This raw output is intended to be easily parsable and convertable with -other tools. Have a look at the batctl README if you want a vis output -in dot or json format for instance and how those outputs could then be -visualised in an image. +All mesh wide settings can be found in batman's own interface +folder: + +# ls /sys/class/net/bat0/mesh/ +# aggregate_ogm originators transtable_global vis_mode +# orig_interval transtable_local vis_data + + +Some of the files contain all sort of status information regard- +ing the mesh network. For example, you can view the table of +originators (mesh participants) with: + +# cat /sys/class/net/bat0/mesh/originators + +Other files allow to change batman's behaviour to better fit your +requirements. For instance, you can check the current originator +interval (value in milliseconds which determines how often batman +sends its broadcast packets): + +# cat /sys/class/net/bat0/mesh/orig_interval +# status: 1000 + +and also change its value: + +# echo 3000 > /sys/class/net/bat0/mesh/orig_interval -The raw format consists of comma seperated values per entry where each -entry is giving information about a certain source interface. Each entry -can/has to have the following values: --> "mac" -> mac address of an originator's source interface - (each line begins with it) --> "TQ mac value" -> src mac's link quality towards mac address of a neighbor - originator's interface which is being used for routing --> "HNA mac" -> HNA announced by source mac --> "PRIMARY" -> this is a primary interface --> "SEC mac" -> secondary mac address of source (requires preceeding --> PRIMARY) - -The TQ value has a range from 4 to 255 with 255 being the best. -The HNA entries are showing which hosts are connected to the mesh via bat0 -or being bridged into the mesh network. -The PRIMARY/SEC values are only applied on primary interfaces - ---- In very mobile scenarios, you might want to adjust the originator -interval to a lower value. This will make the mesh more responsive to -topology changes, but will also increase the overhead. Please make sure -that all nodes in your mesh use the same interval. The default value -is 1000 ms (1 second). +interval to a lower value. This will make the mesh more respon- +sive to topology changes, but will also increase the overhead. + + +USAGE +----- + +To make use of your newly created mesh, batman advanced provides +a new interface "bat0" which you should use from this point on. +All interfaces added to batman advanced are not relevant any +longer because batman handles them for you. Basically, one "hands +over" the data by using the batman interface and batman will make +sure it reaches its destination. -# echo 1000 > /proc/net/batman-adv/orig_interval +The "bat0" interface can be used like any other regular inter- +face. It needs an IP address which can be either statically con- +figured or dynamically (by using DHCP or similar services): -To deactivate batman, do: +# NodeA: ifconfig bat0 192.168.0.1 +# NodeB: ifconfig bat0 192.168.0.2 +# NodeB: ping 192.168.0.1 + +Note: In order to avoid problems remove all IP addresses previ- +ously assigned to interfaces now used by batman advanced, e.g. + +# ifconfig eth0 0.0.0.0 + + +VISUALIZATION +------------- + +If you want topology visualization, at least one mesh node must +be configured as VIS-server: + +# echo "server" > /sys/class/net/bat0/mesh/vis_mode + +Each node is either configured as "server" or as "client" (de- +fault: "client"). Clients send their topology data to the server +next to them, and server synchronize with other servers. If there +is no server configured (default) within the mesh, no topology +information will be transmitted. With these "synchronizing +servers", there can be 1 or more vis servers sharing the same (or +at least very similar) data. + +When configured as server, you can get a topology snapshot of +your mesh: + +# cat /sys/class/net/bat0/mesh/vis_data + +This raw output is intended to be easily parsable and convertable +with other tools. Have a look at the batctl README if you want a +vis output in dot or json format for instance and how those out- +puts could then be visualised in an image. + +The raw format consists of comma separated values per entry where +each entry is giving information about a certain source inter- +face. Each entry can/has to have the following values: +-> "mac" - mac address of an originator's source interface + (each line begins with it) +-> "TQ mac value" - src mac's link quality towards mac address + of a neighbor originator's interface which + is being used for routing +-> "HNA mac" - HNA announced by source mac +-> "PRIMARY" - this is a primary interface +-> "SEC mac" - secondary mac address of source + (requires preceding PRIMARY) + +The TQ value has a range from 4 to 255 with 255 being the best. +The HNA entries are showing which hosts are connected to the mesh +via bat0 or being bridged into the mesh network. The PRIMARY/SEC +values are only applied on primary interfaces -# echo "" > /proc/net/batman-adv/interfaces LOGGING/DEBUGGING ----------------- -All error messages, warnings and information messages are sent to the -kernel log. Depending on your operating system distribution this can be -read in one of a number of ways. Try using the commands: dmesg, -logread, or looking in the files /var/log/kern.log or -/var/log/syslog. All batman-adv messages are prefixed with +All error messages, warnings and information messages are sent to +the kernel log. Depending on your operating system distribution +this can be read in one of a number of ways. Try using the com- +mands: dmesg, logread, or looking in the files /var/log/kern.log +or /var/log/syslog. All batman-adv messages are prefixed with "batman-adv:" So to see just these messages try -dmesg | grep batman-adv +# dmesg | grep batman-adv -When investigating problems with your mesh network it is sometimes -necessary to see more detail debug messages. This must be enabled when -compiling the batman-adv module. Use "make menuconfig" and enable the +When investigating problems with your mesh network it is some- +times necessary to see more detail debug messages. This must be +enabled when compiling the batman-adv module. When building bat- +man-adv as part of kernel, use "make menuconfig" and enable the option "B.A.T.M.A.N. debugging". -The additional debug output is by default disabled. It can be enabled -either at kernel module load time or during run time. To enable debug -output at module load time, add the module parameter debug=. - can take one of four values. +The additional debug output is by default disabled. It can be en- +abled either at kernel modules load time or during run time. To +enable debug output at module load time, add the module parameter +debug=. can take one of four values. -0 - All debug output disabled +0 - All debug output disabled 1 - Enable messages related to routing / flooding / broadcasting 2 - Enable route or hna added / changed / deleted 3 - Enable all messages e.g. -modprobe batman-adv debug=2 +# modprobe batman-adv debug=2 -will load the module and enable debug messages for when routes or HNAs -change. +will load the module and enable debug messages for when routes or +HNAs change. -The debug output can also be changed at runtime using the file +The debug output can also be changed at runtime using the file /sys/module/batman-adv/parameters/debug. e.g. -echo 2 > /sys/module/batman-adv/parameters/debug +# echo 2 > /sys/module/batman-adv/parameters/debug enables debug messages for when routes or HNAs -The debug output is sent to the kernel logs. So try dmesg, logread etc -to see the debug messages. +The debug output is sent to the kernel logs. So try dmesg, lo- +gread, etc to see the debug messages. + BATCTL ------ -B.A.T.M.A.N. advanced operates on layer 2 and thus all hosts -participating in the virtual switch are completely transparent for all -protocols above layer 2. Therefore the common diagnosis tools do not -work as expected. To overcome these problems batctl was created. At -the moment the batctl contains ping, traceroute, tcpdump and +As batman advanced operates on layer 2 all hosts participating in +the virtual switch are completely transparent for all protocols +above layer 2. Therefore the common diagnosis tools do not work +as expected. To overcome these problems batctl was created. At +the moment the batctl contains ping, traceroute, tcpdump and interfaces to the kernel module settings. For more information, please see the manpage (man batctl). -batctl is available on http://www.open-mesh.net/ +batctl is available on http://www.open-mesh.org/ + CONTACT ------- Please send us comments, experiences, questions, anything :) -IRC: #batman on irc.freenode.org -Mailing-list: b.a.t.m.a.n@open-mesh.net -(subscription at https://list.open-mesh.net/mm/listinfo/b.a.t.m.a.n ) +IRC: #batman on irc.freenode.org +Mailing-list: b.a.t.m.a.n@open-mesh.net (optional subscription + at https://lists.open-mesh.org/mm/listinfo/b.a.t.m.a.n) You can also contact the Authors: -Marek Lindner -Simon Wunderlich +Marek Lindner +Simon Wunderlich + -- cgit v1.2.3 From 7c1e68ba9236ef848a715cbb60b13947b9ae7289 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 6 May 2010 16:44:08 -0700 Subject: staging: cxt1e1: fix semaphore build breakage Fix build errors by including linux/semaphore.h: drivers/staging/cxt1e1/pmcc4_private.h:144: error: field 'sr_sem_busy' has incomplete type drivers/staging/cxt1e1/pmcc4_private.h:146: error: field 'sr_sem_wait' has incomplete type drivers/staging/cxt1e1/pmcc4_private.h:189: error: field 'sem_wdbusy' has incomplete type drivers/staging/cxt1e1/musycc.c:617: error: implicit declaration of function 'down' drivers/staging/cxt1e1/musycc.c:641: error: implicit declaration of function 'up' Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/staging/cxt1e1/pmcc4_private.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/cxt1e1/pmcc4_private.h b/drivers/staging/cxt1e1/pmcc4_private.h index 0ae18c444a75..b2b6e3702630 100644 --- a/drivers/staging/cxt1e1/pmcc4_private.h +++ b/drivers/staging/cxt1e1/pmcc4_private.h @@ -20,6 +20,7 @@ #include #include +#include #include #include /* support for tasklets */ #include /* support for timer */ -- cgit v1.2.3 From dd7ad5c8083de5c1820f1da711458582b10e0ed2 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 6 May 2010 16:45:10 -0700 Subject: staging: ti-st: depends on RFKILL Fix build errors. st_kim.c uses rfkill*() interfaces, so it should depend on RFKILL. st_kim.c:(.text+0x291b21): undefined reference to `rfkill_unregister' st_kim.c:(.text+0x291b31): undefined reference to `rfkill_destroy' st_kim.c:(.text+0x291d8a): undefined reference to `rfkill_alloc' st_kim.c:(.text+0x291db9): undefined reference to `rfkill_init_sw_state' st_kim.c:(.text+0x291dc9): undefined reference to `rfkill_register' st_kim.c:(.text+0x291e07): undefined reference to `rfkill_unregister' (.text+0x291e85): undefined reference to `rfkill_set_hw_state' (.text+0x292072): undefined reference to `rfkill_set_hw_state' (.text+0x2920e1): undefined reference to `rfkill_set_hw_state Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ti-st/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/ti-st/Kconfig b/drivers/staging/ti-st/Kconfig index 120e8db1368b..3ab204ddc29d 100644 --- a/drivers/staging/ti-st/Kconfig +++ b/drivers/staging/ti-st/Kconfig @@ -5,6 +5,7 @@ menu "Texas Instruments shared transport line discipline" config TI_ST tristate "shared transport core driver" + depends on RFKILL select FW_LOADER help This enables the shared transport core driver for TI -- cgit v1.2.3 From 1ec28abbf891036df537aa624c9df8245097e8e8 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 6 May 2010 21:44:43 -0700 Subject: Staging: hv: add module description to blkvsc Signed-off-by: Stephen Hemminger Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index a81040f74e99..d068f15603ce 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -149,8 +149,9 @@ static int blkvsc_do_flush(struct block_device_context *blkdev); static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev); static int blkvsc_do_pending_reqs(struct block_device_context *blkdev); - static int blkvsc_ringbuffer_size = BLKVSC_RING_BUFFER_SIZE; +module_param(blkvsc_ringbuffer_size, int, S_IRUGO); +MODULE_PARM_DESC(ring_size, "Ring buffer size (in bytes)"); /* The one and only one */ static struct blkvsc_driver_context g_blkvsc_drv; @@ -1511,6 +1512,6 @@ static void __exit blkvsc_exit(void) MODULE_LICENSE("GPL"); MODULE_VERSION(HV_DRV_VERSION); -module_param(blkvsc_ringbuffer_size, int, S_IRUGO); +MODULE_DESCRIPTION("Microsoft Hyper-V virtual block driver"); module_init(blkvsc_init); module_exit(blkvsc_exit); -- cgit v1.2.3 From 48c9f7c30b187a9112a174eb92bb44e1718c99a6 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 6 May 2010 21:44:44 -0700 Subject: Staging: hv: block_operations can be const Signed-off-by: Stephen Hemminger Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index d068f15603ce..61bd0be5fb18 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -156,7 +156,7 @@ MODULE_PARM_DESC(ring_size, "Ring buffer size (in bytes)"); /* The one and only one */ static struct blkvsc_driver_context g_blkvsc_drv; -static struct block_device_operations block_ops = { +static const struct block_device_operations block_ops = { .owner = THIS_MODULE, .open = blkvsc_open, .release = blkvsc_release, -- cgit v1.2.3 From 3afc7cc38c75d645855d680f0fad7d342f8e7fb2 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 6 May 2010 21:44:45 -0700 Subject: Staging: hv: storvsc module descriptions Signed-off-by: Stephen Hemminger Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc_drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 6a2014639d22..d22e35f598ba 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -97,6 +97,8 @@ static int storvsc_get_chs(struct scsi_device *sdev, struct block_device *bdev, static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE; +module_param(storvsc_ringbuffer_size, int, S_IRUGO); +MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); /* The one and only one */ static struct storvsc_driver_context g_storvsc_drv; @@ -991,6 +993,6 @@ static void __exit storvsc_exit(void) MODULE_LICENSE("GPL"); MODULE_VERSION(HV_DRV_VERSION); -module_param(storvsc_ringbuffer_size, int, S_IRUGO); +MODULE_DESCRIPTION("Microsoft Hyper-V virtual storage driver"); module_init(storvsc_init); module_exit(storvsc_exit); -- cgit v1.2.3 From 0cbd8d9854284d3ff38d04aaa3ae726fb1c4a958 Mon Sep 17 00:00:00 2001 From: Andres More Date: Thu, 6 May 2010 20:34:29 -0300 Subject: staging: vt6656: code cleanup, removed HANDLE definition in ttype.h Checkpatch warnings about using externs in .c files were not resolved, neither some long lines on deeply nested code. Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/baseband.c | 22 ++- drivers/staging/vt6656/baseband.h | 11 +- drivers/staging/vt6656/bssdb.c | 277 +++++++++++++++----------------------- drivers/staging/vt6656/bssdb.h | 202 +++++++++++---------------- drivers/staging/vt6656/dpc.c | 14 +- drivers/staging/vt6656/int.c | 14 +- drivers/staging/vt6656/ioctl.c | 31 +++-- drivers/staging/vt6656/iwctl.c | 42 +++--- drivers/staging/vt6656/main_usb.c | 24 ++-- drivers/staging/vt6656/power.c | 58 ++------ drivers/staging/vt6656/power.h | 41 ++---- drivers/staging/vt6656/rxtx.c | 15 ++- drivers/staging/vt6656/ttype.h | 7 - drivers/staging/vt6656/wcmd.c | 124 ++++++++--------- drivers/staging/vt6656/wcmd.h | 30 ++--- drivers/staging/vt6656/wmgr.c | 248 +++++++++++++--------------------- drivers/staging/vt6656/wmgr.h | 109 +++++---------- drivers/staging/vt6656/wpactl.c | 18 ++- 18 files changed, 506 insertions(+), 781 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c index d8154f366d52..01680e6b0f5b 100644 --- a/drivers/staging/vt6656/baseband.c +++ b/drivers/staging/vt6656/baseband.c @@ -1513,7 +1513,9 @@ BBvAntennaDiversity (PSDevice pDevice, BYTE byRxRate, BYTE bySQ3) if ( pDevice->byTMax == 0 ) return; - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_ANTENNA, NULL); + bScheduleCommand((void *) pDevice, + WLAN_CMD_CHANGE_ANTENNA, + NULL); pDevice->byAntennaState = 1; @@ -1543,7 +1545,9 @@ BBvAntennaDiversity (PSDevice pDevice, BYTE byRxRate, BYTE bySQ3) ((pDevice->ulSQ3_State1 != 0) && (pDevice->ulSQ3_State0 != 0) && (pDevice->ulSQ3_State0 < pDevice->ulSQ3_State1)) ) { - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_ANTENNA, NULL); + bScheduleCommand((void *) pDevice, + WLAN_CMD_CHANGE_ANTENNA, + NULL); pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ); pDevice->TimerSQ3Tmax2.expires = RUN_AT(pDevice->byTMax2 * HZ); @@ -1576,17 +1580,14 @@ BBvAntennaDiversity (PSDevice pDevice, BYTE byRxRate, BYTE bySQ3) * -*/ -void -TimerSQ3CallBack ( - HANDLE hDeviceContext - ) +void TimerSQ3CallBack(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TimerSQ3CallBack..."); spin_lock_irq(&pDevice->lock); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_ANTENNA, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_CHANGE_ANTENNA, NULL); pDevice->byAntennaState = 0; s_vClearSQ3Value(pDevice); pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ); @@ -1618,10 +1619,7 @@ TimerSQ3CallBack ( * -*/ -void -TimerSQ3Tmax3CallBack ( - HANDLE hDeviceContext - ) +void TimerSQ3Tmax3CallBack(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1639,7 +1637,7 @@ TimerSQ3Tmax3CallBack ( return; } - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_ANTENNA, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_CHANGE_ANTENNA, NULL); pDevice->byAntennaState = 1; del_timer(&pDevice->TimerSQ3Tmax3); del_timer(&pDevice->TimerSQ3Tmax2); diff --git a/drivers/staging/vt6656/baseband.h b/drivers/staging/vt6656/baseband.h index d54d4150dd0f..d59992c17ec8 100644 --- a/drivers/staging/vt6656/baseband.h +++ b/drivers/staging/vt6656/baseband.h @@ -117,15 +117,8 @@ BBvCaculateParameter ( // timer for antenna diversity -void -TimerSQ3CallBack ( - HANDLE hDeviceContext - ); - -void -TimerSQ3Tmax3CallBack ( - HANDLE hDeviceContext - ); +void TimerSQ3CallBack(void *hDeviceContext); +void TimerSQ3Tmax3CallBack(void *hDeviceContext); void BBvAntennaDiversity(PSDevice pDevice, BYTE byRxRate, BYTE bySQ3); void BBvLoopbackOn(PSDevice pDevice); diff --git a/drivers/staging/vt6656/bssdb.c b/drivers/staging/vt6656/bssdb.c index 7cc0d9533f73..8c68e04cf988 100644 --- a/drivers/staging/vt6656/bssdb.c +++ b/drivers/staging/vt6656/bssdb.c @@ -91,19 +91,13 @@ const WORD awHWRetry1[5][5] = { /*--------------------- Static Functions --------------------------*/ -void s_vCheckSensitivity( - HANDLE hDeviceContext - ); - -void s_vCheckPreEDThreshold( - HANDLE hDeviceContext - ); +void s_vCheckSensitivity(void *hDeviceContext); +void s_vCheckPreEDThreshold(void *hDeviceContext); #ifdef Calcu_LinkQual -void s_uCalculateLinkQual( - HANDLE hDeviceContext - ); +void s_uCalculateLinkQual(void *hDeviceContext); #endif + /*--------------------- Export Variables --------------------------*/ @@ -123,13 +117,10 @@ void s_uCalculateLinkQual( * -*/ -PKnownBSS -BSSpSearchBSSList( - HANDLE hDeviceContext, - PBYTE pbyDesireBSSID, - PBYTE pbyDesireSSID, - CARD_PHY_TYPE ePhyType - ) +PKnownBSS BSSpSearchBSSList(void *hDeviceContext, + PBYTE pbyDesireBSSID, + PBYTE pbyDesireSSID, + CARD_PHY_TYPE ePhyType) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -296,11 +287,7 @@ pDevice->bSameBSSMaxNum = jj; -*/ -void -BSSvClearBSSList( - HANDLE hDeviceContext, - BOOL bKeepCurrBSSID - ) +void BSSvClearBSSList(void *hDeviceContext, BOOL bKeepCurrBSSID) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -342,12 +329,9 @@ BSSvClearBSSList( * TRUE if found. * -*/ -PKnownBSS -BSSpAddrIsInBSSList( - HANDLE hDeviceContext, - PBYTE abyBSSID, - PWLAN_IE_SSID pSSID - ) +PKnownBSS BSSpAddrIsInBSSList(void *hDeviceContext, + PBYTE abyBSSID, + PWLAN_IE_SSID pSSID) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -383,26 +367,23 @@ BSSpAddrIsInBSSList( * -*/ -BOOL -BSSbInsertToBSSList ( - HANDLE hDeviceContext, - PBYTE abyBSSIDAddr, - QWORD qwTimestamp, - WORD wBeaconInterval, - WORD wCapInfo, - BYTE byCurrChannel, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pSuppRates, - PWLAN_IE_SUPP_RATES pExtSuppRates, - PERPObject psERP, - PWLAN_IE_RSN pRSN, - PWLAN_IE_RSN_EXT pRSNWPA, - PWLAN_IE_COUNTRY pIE_Country, - PWLAN_IE_QUIET pIE_Quiet, - UINT uIELength, - PBYTE pbyIEs, - HANDLE pRxPacketContext - ) +BOOL BSSbInsertToBSSList(void *hDeviceContext, + PBYTE abyBSSIDAddr, + QWORD qwTimestamp, + WORD wBeaconInterval, + WORD wCapInfo, + BYTE byCurrChannel, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pSuppRates, + PWLAN_IE_SUPP_RATES pExtSuppRates, + PERPObject psERP, + PWLAN_IE_RSN pRSN, + PWLAN_IE_RSN_EXT pRSNWPA, + PWLAN_IE_COUNTRY pIE_Country, + PWLAN_IE_QUIET pIE_Quiet, + UINT uIELength, + PBYTE pbyIEs, + void *pRxPacketContext) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -518,7 +499,9 @@ BSSbInsertToBSSList ( if ((bIs802_1x == TRUE) && (pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len) && ( !memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID, pSSID->len))) { - bAdd_PMKID_Candidate((HANDLE)pDevice, pBSSList->abyBSSID, &pBSSList->sRSNCapObj); + bAdd_PMKID_Candidate((void *) pDevice, + pBSSList->abyBSSID, + &pBSSList->sRSNCapObj); if ((pDevice->bLinkPass == TRUE) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { if ((KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, PAIRWISE_KEY, &pTransmitKey) == TRUE) || @@ -602,27 +585,24 @@ BSSbInsertToBSSList ( -*/ // TODO: input structure modify -BOOL -BSSbUpdateToBSSList ( - HANDLE hDeviceContext, - QWORD qwTimestamp, - WORD wBeaconInterval, - WORD wCapInfo, - BYTE byCurrChannel, - BOOL bChannelHit, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pSuppRates, - PWLAN_IE_SUPP_RATES pExtSuppRates, - PERPObject psERP, - PWLAN_IE_RSN pRSN, - PWLAN_IE_RSN_EXT pRSNWPA, - PWLAN_IE_COUNTRY pIE_Country, - PWLAN_IE_QUIET pIE_Quiet, - PKnownBSS pBSSList, - UINT uIELength, - PBYTE pbyIEs, - HANDLE pRxPacketContext - ) +BOOL BSSbUpdateToBSSList(void *hDeviceContext, + QWORD qwTimestamp, + WORD wBeaconInterval, + WORD wCapInfo, + BYTE byCurrChannel, + BOOL bChannelHit, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pSuppRates, + PWLAN_IE_SUPP_RATES pExtSuppRates, + PERPObject psERP, + PWLAN_IE_RSN pRSN, + PWLAN_IE_RSN_EXT pRSNWPA, + PWLAN_IE_COUNTRY pIE_Country, + PWLAN_IE_QUIET pIE_Quiet, + PKnownBSS pBSSList, + UINT uIELength, + PBYTE pbyIEs, + void *pRxPacketContext) { int ii, jj; PSDevice pDevice = (PSDevice)hDeviceContext; @@ -768,12 +748,9 @@ BSSbUpdateToBSSList ( * -*/ -BOOL -BSSbIsSTAInNodeDB( - HANDLE hDeviceContext, - PBYTE abyDstAddr, - PUINT puNodeIndex - ) +BOOL BSSbIsSTAInNodeDB(void *hDeviceContext, + PBYTE abyDstAddr, + PUINT puNodeIndex) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -804,11 +781,7 @@ BSSbIsSTAInNodeDB( * None * -*/ -void -BSSvCreateOneNode( - HANDLE hDeviceContext, - PUINT puNodeIndex - ) +void BSSvCreateOneNode(void *hDeviceContext, PUINT puNodeIndex) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -869,11 +842,8 @@ BSSvCreateOneNode( * None * -*/ -void -BSSvRemoveOneNode( - HANDLE hDeviceContext, - UINT uNodeIndex - ) + +void BSSvRemoveOneNode(void *hDeviceContext, UINT uNodeIndex) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -902,13 +872,10 @@ BSSvRemoveOneNode( * -*/ -void -BSSvUpdateAPNode( - HANDLE hDeviceContext, - PWORD pwCapInfo, - PWLAN_IE_SUPP_RATES pSuppRates, - PWLAN_IE_SUPP_RATES pExtSuppRates - ) +void BSSvUpdateAPNode(void *hDeviceContext, + PWORD pwCapInfo, + PWLAN_IE_SUPP_RATES pSuppRates, + PWLAN_IE_SUPP_RATES pExtSuppRates) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -946,10 +913,6 @@ BSSvUpdateAPNode( }; - - - - /*+ * * Routine Description: @@ -961,11 +924,7 @@ BSSvUpdateAPNode( * -*/ - -void -BSSvAddMulticastNode( - HANDLE hDeviceContext - ) +void BSSvAddMulticastNode(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -991,10 +950,6 @@ BSSvAddMulticastNode( }; - - - - /*+ * * Routine Description: @@ -1008,11 +963,7 @@ BSSvAddMulticastNode( * -*/ - -void -BSSvSecondCallBack( - HANDLE hDeviceContext - ) +void BSSvSecondCallBack(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -1080,7 +1031,7 @@ if((pMgmt->eCurrState!=WMAC_STATE_ASSOC) && #endif #ifdef Calcu_LinkQual - s_uCalculateLinkQual((HANDLE)pDevice); + s_uCalculateLinkQual((void *)pDevice); #endif for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) { @@ -1226,14 +1177,16 @@ if((pMgmt->eCurrState!=WMAC_STATE_ASSOC) && // DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Callback inactive Count = [%d]\n", pMgmt->sNodeDBTable[0].uInActiveCount); if (pDevice->bUpdateBBVGA) { - // s_vCheckSensitivity((HANDLE) pDevice); - s_vCheckPreEDThreshold((HANDLE)pDevice); + /* s_vCheckSensitivity((void *) pDevice); */ + s_vCheckPreEDThreshold((void *) pDevice); } if ((pMgmt->sNodeDBTable[0].uInActiveCount >= (LOST_BEACON_COUNT/2)) && (pDevice->byBBVGACurrent != pDevice->abyBBVGA[0]) ) { pDevice->byBBVGANew = pDevice->abyBBVGA[0]; - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL); + bScheduleCommand((void *) pDevice, + WLAN_CMD_CHANGE_BBSENSITIVITY, + NULL); } if (pMgmt->sNodeDBTable[0].uInActiveCount >= LOST_BEACON_COUNT) { @@ -1281,9 +1234,13 @@ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bRoaming %d, !\n", pDevice->bRoaming ); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bIsRoaming %d, !\n", pDevice->bIsRoaming ); if ((pDevice->bRoaming == TRUE)&&(pDevice->bIsRoaming == TRUE)){ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fast Roaming ...\n"); - BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); + BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass); + bScheduleCommand((void *) pDevice, + WLAN_CMD_BSSID_SCAN, + pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, + WLAN_CMD_SSID, + pMgmt->abyDesireSSID); pDevice->uAutoReConnectTime = 0; pDevice->uIsroamingTime = 0; pDevice->bRoaming = FALSE; @@ -1326,10 +1283,14 @@ else { pDevice->eEncryptionStatus = pDevice->eOldEncryptionStatus; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Roaming ...\n"); - BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass); - pMgmt->eScanType = WMAC_SCAN_ACTIVE; - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); + BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass); + pMgmt->eScanType = WMAC_SCAN_ACTIVE; + bScheduleCommand((void *) pDevice, + WLAN_CMD_BSSID_SCAN, + pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, + WLAN_CMD_SSID, + pMgmt->abyDesireSSID); pDevice->uAutoReConnectTime = 0; } } @@ -1345,17 +1306,17 @@ else { else { DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Adhoc re-scaning ...\n"); pMgmt->eScanType = WMAC_SCAN_ACTIVE; - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); pDevice->uAutoReConnectTime = 0; }; } if (pMgmt->eCurrState == WMAC_STATE_JOINTED) { - if (pDevice->bUpdateBBVGA) { - //s_vCheckSensitivity((HANDLE) pDevice); - s_vCheckPreEDThreshold((HANDLE)pDevice); - } + if (pDevice->bUpdateBBVGA) { + /* s_vCheckSensitivity((void *) pDevice); */ + s_vCheckPreEDThreshold((void *) pDevice); + } if (pMgmt->sNodeDBTable[0].uInActiveCount >=ADHOC_LOST_BEACON_COUNT) { DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost other STA beacon [%d] sec, started !\n", pMgmt->sNodeDBTable[0].uInActiveCount); pMgmt->sNodeDBTable[0].uInActiveCount = 0; @@ -1379,9 +1340,6 @@ else { return; } - - - /*+ * * Routine Description: @@ -1395,15 +1353,10 @@ else { * -*/ - - -void -BSSvUpdateNodeTxCounter( - HANDLE hDeviceContext, - PSStatCounter pStatistic, - BYTE byTSR, - BYTE byPktNO - ) +void BSSvUpdateNodeTxCounter(void *hDeviceContext, + PSStatCounter pStatistic, + BYTE byTSR, + BYTE byPktNO) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -1417,8 +1370,6 @@ BSSvUpdateNodeTxCounter( BYTE byPktNum; WORD wFIFOCtl; - - byPktNum = (byPktNO & 0x0F) >> 4; byTxRetry = (byTSR & 0xF0) >> 4; wRate = (WORD) (byPktNO & 0xF0) >> 4; @@ -1485,11 +1436,13 @@ BSSvUpdateNodeTxCounter( } }; - if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) || + if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) || (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) { - if (BSSbIsSTAInNodeDB((HANDLE)pDevice, pbyDestAddr, &uNodeIndex)){ - pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts += 1; + if (BSSbIsSTAInNodeDB((void *) pDevice, + pbyDestAddr, + &uNodeIndex)) { + pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts += 1; if ( !(byTSR & (TSR_TMO | TSR_RETRYTMO))) { // transmit success, TxAttempts at least plus one pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++; @@ -1544,9 +1497,6 @@ BSSvUpdateNodeTxCounter( } - - - /*+ * * Routine Description: @@ -1565,13 +1515,8 @@ BSSvUpdateNodeTxCounter( * -*/ - -void -BSSvClearNodeDBTable( - HANDLE hDeviceContext, - UINT uStartIndex - ) - +void BSSvClearNodeDBTable(void *hDeviceContext, + UINT uStartIndex) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -1594,10 +1539,7 @@ BSSvClearNodeDBTable( return; }; - -void s_vCheckSensitivity( - HANDLE hDeviceContext - ) +void s_vCheckSensitivity(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; PKnownBSS pBSSList = NULL; @@ -1629,7 +1571,9 @@ void s_vCheckSensitivity( if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) { pDevice->uBBVGADiffCount++; if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL); + bScheduleCommand((void *) pDevice, + WLAN_CMD_CHANGE_BBSENSITIVITY, + NULL); } else { pDevice->uBBVGADiffCount = 0; } @@ -1639,9 +1583,7 @@ void s_vCheckSensitivity( } #ifdef Calcu_LinkQual -void s_uCalculateLinkQual( - HANDLE hDeviceContext - ) +void s_uCalculateLinkQual(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; ULONG TxOkRatio, TxCnt; @@ -1687,10 +1629,7 @@ else } #endif -void -BSSvClearAnyBSSJoinRecord ( - HANDLE hDeviceContext - ) +void BSSvClearAnyBSSJoinRecord(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -1702,9 +1641,7 @@ BSSvClearAnyBSSJoinRecord ( return; } -void s_vCheckPreEDThreshold( - HANDLE hDeviceContext - ) +void s_vCheckPreEDThreshold(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; PKnownBSS pBSSList = NULL; diff --git a/drivers/staging/vt6656/bssdb.h b/drivers/staging/vt6656/bssdb.h index 48b34b51402f..8140b9b37fb4 100644 --- a/drivers/staging/vt6656/bssdb.h +++ b/drivers/staging/vt6656/bssdb.h @@ -226,134 +226,82 @@ typedef struct tagKnownNodeDB { } KnownNodeDB, *PKnownNodeDB; - /*--------------------- Export Functions --------------------------*/ - - -PKnownBSS -BSSpSearchBSSList( - HANDLE hDeviceContext, - PBYTE pbyDesireBSSID, - PBYTE pbyDesireSSID, - CARD_PHY_TYPE ePhyType - ); - -PKnownBSS -BSSpAddrIsInBSSList( - HANDLE hDeviceContext, - PBYTE abyBSSID, - PWLAN_IE_SSID pSSID - ); - -void -BSSvClearBSSList( - HANDLE hDeviceContext, - BOOL bKeepCurrBSSID - ); - -BOOL -BSSbInsertToBSSList( - HANDLE hDeviceContext, - PBYTE abyBSSIDAddr, - QWORD qwTimestamp, - WORD wBeaconInterval, - WORD wCapInfo, - BYTE byCurrChannel, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pSuppRates, - PWLAN_IE_SUPP_RATES pExtSuppRates, - PERPObject psERP, - PWLAN_IE_RSN pRSN, - PWLAN_IE_RSN_EXT pRSNWPA, - PWLAN_IE_COUNTRY pIE_Country, - PWLAN_IE_QUIET pIE_Quiet, - UINT uIELength, - PBYTE pbyIEs, - HANDLE pRxPacketContext - ); - - -BOOL -BSSbUpdateToBSSList( - HANDLE hDeviceContext, - QWORD qwTimestamp, - WORD wBeaconInterval, - WORD wCapInfo, - BYTE byCurrChannel, - BOOL bChannelHit, - PWLAN_IE_SSID pSSID, - PWLAN_IE_SUPP_RATES pSuppRates, - PWLAN_IE_SUPP_RATES pExtSuppRates, - PERPObject psERP, - PWLAN_IE_RSN pRSN, - PWLAN_IE_RSN_EXT pRSNWPA, - PWLAN_IE_COUNTRY pIE_Country, - PWLAN_IE_QUIET pIE_Quiet, - PKnownBSS pBSSList, - UINT uIELength, - PBYTE pbyIEs, - HANDLE pRxPacketContext - ); - - -BOOL -BSSbIsSTAInNodeDB( - HANDLE hDeviceContext, - PBYTE abyDstAddr, - PUINT puNodeIndex - ); - -void -BSSvCreateOneNode( - HANDLE hDeviceContext, - PUINT puNodeIndex - ); - -void -BSSvUpdateAPNode( - HANDLE hDeviceContext, - PWORD pwCapInfo, - PWLAN_IE_SUPP_RATES pItemRates, - PWLAN_IE_SUPP_RATES pExtSuppRates - ); - - -void -BSSvSecondCallBack( - HANDLE hDeviceContext - ); - - -void -BSSvUpdateNodeTxCounter( - HANDLE hDeviceContext, - PSStatCounter pStatistic, - BYTE byTSR, - BYTE byPktNO - ); - -void -BSSvRemoveOneNode( - HANDLE hDeviceContext, - UINT uNodeIndex - ); - -void -BSSvAddMulticastNode( - HANDLE hDeviceContext - ); - - -void -BSSvClearNodeDBTable( - HANDLE hDeviceContext, - UINT uStartIndex - ); - -void -BSSvClearAnyBSSJoinRecord( - HANDLE hDeviceContext - ); +PKnownBSS BSSpSearchBSSList(void *hDeviceContext, + PBYTE pbyDesireBSSID, + PBYTE pbyDesireSSID, + CARD_PHY_TYPE ePhyType); + +PKnownBSS BSSpAddrIsInBSSList(void *hDeviceContext, + PBYTE abyBSSID, + PWLAN_IE_SSID pSSID); + +void BSSvClearBSSList(void *hDeviceContext, BOOL bKeepCurrBSSID); + +BOOL BSSbInsertToBSSList(void *hDeviceContext, + PBYTE abyBSSIDAddr, + QWORD qwTimestamp, + WORD wBeaconInterval, + WORD wCapInfo, + BYTE byCurrChannel, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pSuppRates, + PWLAN_IE_SUPP_RATES pExtSuppRates, + PERPObject psERP, + PWLAN_IE_RSN pRSN, + PWLAN_IE_RSN_EXT pRSNWPA, + PWLAN_IE_COUNTRY pIE_Country, + PWLAN_IE_QUIET pIE_Quiet, + UINT uIELength, + PBYTE pbyIEs, + void *pRxPacketContext); + +BOOL BSSbUpdateToBSSList(void *hDeviceContext, + QWORD qwTimestamp, + WORD wBeaconInterval, + WORD wCapInfo, + BYTE byCurrChannel, + BOOL bChannelHit, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pSuppRates, + PWLAN_IE_SUPP_RATES pExtSuppRates, + PERPObject psERP, + PWLAN_IE_RSN pRSN, + PWLAN_IE_RSN_EXT pRSNWPA, + PWLAN_IE_COUNTRY pIE_Country, + PWLAN_IE_QUIET pIE_Quiet, + PKnownBSS pBSSList, + UINT uIELength, + PBYTE pbyIEs, + void *pRxPacketContext); + +BOOL BSSbIsSTAInNodeDB(void *hDeviceContext, + PBYTE abyDstAddr, + PUINT puNodeIndex); + +void BSSvCreateOneNode(void *hDeviceContext, PUINT puNodeIndex); + +void BSSvUpdateAPNode(void *hDeviceContext, + PWORD pwCapInfo, + PWLAN_IE_SUPP_RATES pItemRates, + PWLAN_IE_SUPP_RATES pExtSuppRates); + +void BSSvSecondCallBack(void *hDeviceContext); + +void BSSvUpdateNodeTxCounter(void *hDeviceContext, + PSStatCounter pStatistic, + BYTE byTSR, + BYTE byPktNO); + +void BSSvRemoveOneNode(void *hDeviceContext, + UINT uNodeIndex); + +void BSSvAddMulticastNode(void *hDeviceContext); + +void BSSvClearNodeDBTable(void *hDeviceContext, + UINT uStartIndex); + +void BSSvClearAnyBSSJoinRecord(void *hDeviceContext); #endif /* __BSSDB_H__ */ diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index b18427b39169..6982224dfa90 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -1069,7 +1069,9 @@ static BOOL s_bAPModeRxCtl ( // delcare received ps-poll event if (IS_CTL_PSPOLL(pbyFrame)) { pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = TRUE; - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL); + bScheduleCommand((void *) pDevice, + WLAN_CMD_RX_PSPOLL, + NULL); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 1\n"); } else { @@ -1078,7 +1080,9 @@ static BOOL s_bAPModeRxCtl ( if (!IS_FC_POWERMGT(pbyFrame)) { pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = FALSE; pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = TRUE; - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL); + bScheduleCommand((void *) pDevice, + WLAN_CMD_RX_PSPOLL, + NULL); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 2\n"); } } @@ -1094,7 +1098,9 @@ static BOOL s_bAPModeRxCtl ( if (pMgmt->sNodeDBTable[iSANodeIndex].wEnQueueCnt > 0) { pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = FALSE; pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = TRUE; - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL); + bScheduleCommand((void *) pDevice, + WLAN_CMD_RX_PSPOLL, + NULL); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 3\n"); } @@ -1596,7 +1602,7 @@ void RXvMngWorkItem(void *Context) } ASSERT(pRCB);// cannot be NULL pRxPacket = &(pRCB->sMngPacket); - vMgrRxManagePacket((HANDLE)pDevice, &(pDevice->sMgmtObj), pRxPacket); + vMgrRxManagePacket((void *) pDevice, &(pDevice->sMgmtObj), pRxPacket); pRCB->Ref--; if(pRCB->Ref == 0) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RxvFreeMng %d %d\n",pDevice->NumRecvFreeList, pDevice->NumRecvMngList); diff --git a/drivers/staging/vt6656/int.c b/drivers/staging/vt6656/int.c index 2ba20893ce73..89f5b18bdf1f 100644 --- a/drivers/staging/vt6656/int.c +++ b/drivers/staging/vt6656/int.c @@ -160,11 +160,11 @@ INTnsProcessData(PSDevice pDevice) pMgmt->byDTIMPeriod-1; pMgmt->sNodeDBTable[0].bRxPSPoll = TRUE; if (pMgmt->sNodeDBTable[0].bPSEnable) - bScheduleCommand((HANDLE)pDevice, - WLAN_CMD_RX_PSPOLL, - NULL); + bScheduleCommand((void *) pDevice, + WLAN_CMD_RX_PSPOLL, + NULL); } - bScheduleCommand((HANDLE)pDevice, + bScheduleCommand((void *) pDevice, WLAN_CMD_BECON_SEND, NULL); } /* if (pDevice->eOPMode == OP_MODE_AP) */ @@ -174,13 +174,13 @@ INTnsProcessData(PSDevice pDevice) } if (pINTData->byISR0 & ISR_TBTT) { if (pDevice->bEnablePSMode) - bScheduleCommand((HANDLE) pDevice, + bScheduleCommand((void *) pDevice, WLAN_CMD_TBTT_WAKEUP, NULL); if (pDevice->bChannelSwitch) { pDevice->byChannelSwitchCount--; if (pDevice->byChannelSwitchCount == 0) - bScheduleCommand((HANDLE) pDevice, + bScheduleCommand((void *) pDevice, WLAN_CMD_11H_CHSW, NULL); } @@ -207,7 +207,7 @@ INTnsProcessData(PSDevice pDevice) if (pINTData->byISR1 != 0) if (pINTData->byISR1 & ISR_GPIO3) - bScheduleCommand((HANDLE) pDevice, + bScheduleCommand((void *) pDevice, WLAN_CMD_RADIO, NULL); pDevice->intBuf.uDataLen = 0; diff --git a/drivers/staging/vt6656/ioctl.c b/drivers/staging/vt6656/ioctl.c index 08d5429db26a..69d1d735f712 100644 --- a/drivers/staging/vt6656/ioctl.c +++ b/drivers/staging/vt6656/ioctl.c @@ -100,16 +100,21 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) { memcpy(abyScanSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN); } spin_lock_irq(&pDevice->lock); - if (memcmp(pMgmt->abyCurrBSSID, &abyNullAddr[0], 6) == 0) - BSSvClearBSSList((HANDLE)pDevice, FALSE); - else - BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_BSS_SCAN..begin \n"); - if (pItemSSID->len != 0) - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); - else - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL); + if (memcmp(pMgmt->abyCurrBSSID, &abyNullAddr[0], 6) == 0) + BSSvClearBSSList((void *) pDevice, FALSE); + else + BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass); + + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_BSS_SCAN..begin\n"); + + if (pItemSSID->len != 0) + bScheduleCommand((void *) pDevice, + WLAN_CMD_BSSID_SCAN, + abyScanSSID); + else + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); + spin_unlock_irq(&pDevice->lock); break; @@ -207,8 +212,10 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) { netif_stop_queue(pDevice->dev); spin_lock_irq(&pDevice->lock); pMgmt->eCurrState = WMAC_STATE_IDLE; - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, NULL); + bScheduleCommand((void *) pDevice, + WLAN_CMD_BSSID_SCAN, + pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); spin_unlock_irq(&pDevice->lock); break; @@ -576,7 +583,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) { netif_stop_queue(pDevice->dev); spin_lock_irq(&pDevice->lock); - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RUN_AP, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL); spin_unlock_irq(&pDevice->lock); break; diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index d7ed3b456339..4d0db21b1b98 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -209,9 +209,9 @@ if(pDevice->byReAssocCount > 0) { //reject scan when re-associating! spin_lock_irq(&pDevice->lock); - #ifdef update_BssList - BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass); - #endif +#ifdef update_BssList + BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass); +#endif //mike add: active scan OR passive scan OR desire_ssid scan if(wrq->length == sizeof(struct iw_scan_req)) { @@ -229,7 +229,7 @@ if(pDevice->byReAssocCount > 0) { //reject scan when re-associating! pMgmt->eScanType = WMAC_SCAN_PASSIVE; PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n",((PWLAN_IE_SSID)abyScanSSID)->abySSID, ((PWLAN_IE_SSID)abyScanSSID)->len); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); spin_unlock_irq(&pDevice->lock); return 0; @@ -244,7 +244,7 @@ if(pDevice->byReAssocCount > 0) { //reject scan when re-associating! pMgmt->eScanType = WMAC_SCAN_PASSIVE; //printk("SIOCSIWSCAN:WLAN_CMD_BSSID_SCAN\n"); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); spin_unlock_irq(&pDevice->lock); return 0; @@ -944,10 +944,14 @@ int iwctl_siwessid(struct net_device *dev, if (pCurr == NULL){ PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n"); - vResetCommandTimer((HANDLE) pDevice); + vResetCommandTimer((void *) pDevice); pMgmt->eScanType = WMAC_SCAN_ACTIVE; - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, + WLAN_CMD_BSSID_SCAN, + pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, + WLAN_CMD_SSID, + pMgmt->abyDesireSSID); } else { //mike:to find out if that desired SSID is a hidden-ssid AP , // by means of judging if there are two same BSSID exist in list ? @@ -959,10 +963,14 @@ int iwctl_siwessid(struct net_device *dev, } if(uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! PRINT_K("SIOCSIWESSID:hidden ssid directly associate.......\n"); - vResetCommandTimer((HANDLE) pDevice); + vResetCommandTimer((void *) pDevice); pMgmt->eScanType = WMAC_SCAN_PASSIVE; //this scan type,you'll submit scan result! - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, + WLAN_CMD_BSSID_SCAN, + pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, + WLAN_CMD_SSID, + pMgmt->abyDesireSSID); } } } @@ -1554,11 +1562,11 @@ int iwctl_siwpower(struct net_device *dev, } if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { pDevice->ePSMode = WMAC_POWER_FAST; - PSvEnablePowerSaving((HANDLE)pDevice, pMgmt->wListenInterval); + PSvEnablePowerSaving((void *) pDevice, pMgmt->wListenInterval); } else if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) { pDevice->ePSMode = WMAC_POWER_FAST; - PSvEnablePowerSaving((HANDLE)pDevice, pMgmt->wListenInterval); + PSvEnablePowerSaving((void *) pDevice, pMgmt->wListenInterval); } switch (wrq->flags & IW_POWER_MODE) { case IW_POWER_UNICAST_R: @@ -2007,12 +2015,16 @@ int iwctl_siwmlme(struct net_device *dev, case IW_MLME_DEAUTH: //this command seems to be not complete,please test it --einsnliu //printk("iwctl_siwmlme--->send DEAUTH\n"); - //bScheduleCommand((HANDLE) pDevice, WLAN_CMD_DEAUTH, (PBYTE)&reason); + /* bScheduleCommand((void *) pDevice, + WLAN_CMD_DEAUTH, + (PBYTE)&reason); */ //break; case IW_MLME_DISASSOC: if(pDevice->bLinkPass == TRUE){ PRINT_K("iwctl_siwmlme--->send DISASSOCIATE\n"); - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_DISASSOCIATE, NULL); + bScheduleCommand((void *) pDevice, + WLAN_CMD_DISASSOCIATE, + NULL); } break; default: diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 2fcaf70aa465..f1d81b1656c5 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -1158,12 +1158,12 @@ static int device_open(struct net_device *dev) { } if (pDevice->sMgmtObj.eConfigMode == WMAC_CONFIG_AP) { - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RUN_AP, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL); } else { //mike:mark@2008-11-10 - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_BSSID_SCAN, NULL); - //bScheduleCommand((HANDLE)pDevice, WLAN_CMD_SSID, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); + /* bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); */ } @@ -1220,7 +1220,7 @@ static int device_close(struct net_device *dev) { //2007-1121-02by EinsnLiu if (pDevice->bLinkPass) { - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_DISASSOCIATE, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL); mdelay(30); } //End Add @@ -2101,16 +2101,16 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { netif_stop_queue(pDevice->dev); spin_lock_irq(&pDevice->lock); - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RUN_AP, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_RUN_AP, NULL); spin_unlock_irq(&pDevice->lock); } else { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n"); spin_lock_irq(&pDevice->lock); //2007-1121-01by EinsnLiu - if (pDevice->bLinkPass&& + if (pDevice->bLinkPass && memcmp(pMgmt->abyCurrSSID,pMgmt->abyDesireSSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN)) { - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_DISASSOCIATE, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL); } else { pDevice->bLinkPass = FALSE; pMgmt->eCurrState = WMAC_STATE_IDLE; @@ -2121,10 +2121,14 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { netif_stop_queue(pDevice->dev); #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT pMgmt->eScanType = WMAC_SCAN_ACTIVE; - if(pDevice->bWPASuppWextEnabled !=TRUE) + if (!pDevice->bWPASuppWextEnabled) #endif - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, NULL); + bScheduleCommand((void *) pDevice, + WLAN_CMD_BSSID_SCAN, + pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, + WLAN_CMD_SSID, + NULL); spin_unlock_irq(&pDevice->lock); } pDevice->bCommit = FALSE; diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c index 05d51fbb00b1..766c5be6fd22 100644 --- a/drivers/staging/vt6656/power.c +++ b/drivers/staging/vt6656/power.c @@ -50,19 +50,14 @@ /*--------------------- Static Definitions -------------------------*/ - - - /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ static int msglevel =MSG_LEVEL_INFO; /*--------------------- Static Functions --------------------------*/ - /*--------------------- Export Variables --------------------------*/ - /*--------------------- Export Functions --------------------------*/ /*+ @@ -75,12 +70,8 @@ static int msglevel =MSG_LEVEL_INFO; * -*/ - -void -PSvEnablePowerSaving( - HANDLE hDeviceContext, - WORD wListenInterval - ) +void PSvEnablePowerSaving(void *hDeviceContext, + WORD wListenInterval) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -128,7 +119,7 @@ PSvEnablePowerSaving( pDevice->bEnablePSMode = TRUE; if (pDevice->eOPMode == OP_MODE_ADHOC) { -// bMgrPrepareBeaconToSend((HANDLE)pDevice, pMgmt); + /* bMgrPrepareBeaconToSend((void *) pDevice, pMgmt); */ } // We don't send null pkt in ad hoc mode since beacon will handle this. else if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) { @@ -139,11 +130,6 @@ PSvEnablePowerSaving( return; } - - - - - /*+ * * Routine Description: @@ -154,10 +140,7 @@ PSvEnablePowerSaving( * -*/ -void -PSvDisablePowerSaving( - HANDLE hDeviceContext - ) +void PSvDisablePowerSaving(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; // PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -187,7 +170,6 @@ PSvDisablePowerSaving( return; } - /*+ * * Routine Description: @@ -198,13 +180,9 @@ PSvDisablePowerSaving( * FALSE, if fail -*/ - -BOOL -PSbConsiderPowerDown( - HANDLE hDeviceContext, - BOOL bCheckRxDMA, - BOOL bCheckCountToWakeUp - ) +BOOL PSbConsiderPowerDown(void *hDeviceContext, + BOOL bCheckRxDMA, + BOOL bCheckCountToWakeUp) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -248,8 +226,6 @@ PSbConsiderPowerDown( return TRUE; } - - /*+ * * Routine Description: @@ -260,12 +236,7 @@ PSbConsiderPowerDown( * -*/ - - -void -PSvSendPSPOLL( - HANDLE hDeviceContext - ) +void PSvSendPSPOLL(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -297,8 +268,6 @@ PSvSendPSPOLL( return; } - - /*+ * * Routine Description: @@ -308,10 +277,8 @@ PSvSendPSPOLL( * None. * -*/ -BOOL -PSbSendNullPacket( - HANDLE hDeviceContext - ) + +BOOL PSbSendNullPacket(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; PSTxMgmtPacket pTxPacket = NULL; @@ -388,10 +355,7 @@ PSbSendNullPacket( * -*/ -BOOL -PSbIsNextTBTTWakeUp( - HANDLE hDeviceContext - ) +BOOL PSbIsNextTBTTWakeUp(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; diff --git a/drivers/staging/vt6656/power.h b/drivers/staging/vt6656/power.h index c34e3899d95b..50792bb8c978 100644 --- a/drivers/staging/vt6656/power.h +++ b/drivers/staging/vt6656/power.h @@ -48,37 +48,14 @@ /* PSDevice pDevice */ /* PSDevice hDeviceContext */ -BOOL -PSbConsiderPowerDown( - HANDLE hDeviceContext, - BOOL bCheckRxDMA, - BOOL bCheckCountToWakeUp - ); - -void -PSvDisablePowerSaving( - HANDLE hDeviceContext - ); - -void -PSvEnablePowerSaving( - HANDLE hDeviceContext, - WORD wListenInterval - ); - -void -PSvSendPSPOLL( - HANDLE hDeviceContext - ); - -BOOL -PSbSendNullPacket( - HANDLE hDeviceContext - ); - -BOOL -PSbIsNextTBTTWakeUp( - HANDLE hDeviceContext - ); +BOOL PSbConsiderPowerDown(void *hDeviceContext, + BOOL bCheckRxDMA, + BOOL bCheckCountToWakeUp); + +void PSvDisablePowerSaving(void *hDeviceContext); +void PSvEnablePowerSaving(void *hDeviceContext, WORD wListenInterval); +void PSvSendPSPOLL(void *hDeviceContext); +BOOL PSbSendNullPacket(void *hDeviceContext); +BOOL PSbIsNextTBTTWakeUp(void *hDeviceContext); #endif /* __POWER_H__ */ diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index b9f67882199d..bfc786059ad1 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -3032,10 +3032,12 @@ nsDMA_tx_packet( } } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dma_tx: pDevice->wCurrentRate = %d \n", pDevice->wCurrentRate); + DBG_PRT(MSG_LEVEL_DEBUG, + KERN_INFO "dma_tx: pDevice->wCurrentRate = %d\n", + pDevice->wCurrentRate); if (wKeepRate != pDevice->wCurrentRate) { - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_SETPOWER, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_SETPOWER, NULL); } if (pDevice->wCurrentRate <= RATE_11M) { @@ -3118,7 +3120,9 @@ nsDMA_tx_packet( if ( pDevice->bEnablePSMode == TRUE ) { if ( !pDevice->bPSModeTxBurst ) { - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_MAC_DISPOWERSAVING, NULL); + bScheduleCommand((void *) pDevice, + WLAN_CMD_MAC_DISPOWERSAVING, + NULL); pDevice->bPSModeTxBurst = TRUE; } } @@ -3138,7 +3142,7 @@ nsDMA_tx_packet( if (bNeedDeAuth == TRUE) { WORD wReason = WLAN_MGMT_REASON_MIC_FAILURE; - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_DEAUTH, (PBYTE)&wReason); + bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (PBYTE) &wReason); } if(status!=STATUS_PENDING) { @@ -3258,9 +3262,8 @@ bRelayPacketSend ( pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate; } - if (wKeepRate != pDevice->wCurrentRate) { - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SETPOWER, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_SETPOWER, NULL); } if (pDevice->wCurrentRate <= RATE_11M) diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h index 692b63e4dabf..13e8bbb6711c 100644 --- a/drivers/staging/vt6656/ttype.h +++ b/drivers/staging/vt6656/ttype.h @@ -133,11 +133,4 @@ typedef DWORD * PDWORD; typedef QWORD * PQWORD; -// handle declaration -#ifdef STRICT -typedef void *HANDLE; -#else -typedef void *HANDLE; -#endif - #endif /* __TTYPE_H__ */ diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c index 23db5f63c789..6fec9094ccd0 100644 --- a/drivers/staging/vt6656/wcmd.c +++ b/drivers/staging/vt6656/wcmd.c @@ -94,18 +94,12 @@ s_bCommandComplete ( ); -static -BOOL s_bClearBSSID_SCAN ( - HANDLE hDeviceContext - ); +static BOOL s_bClearBSSID_SCAN(void *hDeviceContext); /*--------------------- Export Variables --------------------------*/ - /*--------------------- Export Functions --------------------------*/ - - /* * Description: * Stop AdHoc beacon during scan process @@ -119,6 +113,7 @@ BOOL s_bClearBSSID_SCAN ( * Return Value: none * */ + static void vAdHocBeaconStop(PSDevice pDevice) @@ -321,15 +316,7 @@ s_MgrMakeProbeRequest( return pTxPacket; } - - - - -void -vCommandTimerWait( - HANDLE hDeviceContext, - UINT MSecond - ) +void vCommandTimerWait(void *hDeviceContext, UINT MSecond) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -342,13 +329,7 @@ vCommandTimerWait( return; } - - - -void -vRunCommand( - HANDLE hDeviceContext - ) +void vRunCommand(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -435,7 +416,8 @@ vRunCommand( pMgmt->abyScanBSSID[5] = 0xFF; pItemSSID->byElementID = WLAN_EID_SSID; // clear bssid list - // BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass); + /* BSSvClearBSSList((void *) pDevice, + pDevice->bLinkPass); */ pMgmt->eScanState = WMAC_IS_SCANNING; pDevice->byScanBBType = pDevice->byBBType; //lucas pDevice->bStopDataPkt = TRUE; @@ -480,11 +462,11 @@ vRunCommand( (pMgmt->uScanChannel < CB_MAX_CHANNEL_24G)) { s_vProbeChannel(pDevice); spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((HANDLE)pDevice, 100); + vCommandTimerWait((void *) pDevice, 100); return; } else { spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((HANDLE)pDevice, WCMD_PASSIVE_SCAN_TIME); + vCommandTimerWait((void *) pDevice, WCMD_PASSIVE_SCAN_TIME); return; } @@ -552,7 +534,11 @@ vRunCommand( DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send Disassociation Packet..\n"); // reason = 8 : disassoc because sta has left - vMgrDisassocBeginSta((HANDLE)pDevice, pMgmt, pMgmt->abyCurrBSSID, (8), &Status); + vMgrDisassocBeginSta((void *) pDevice, + pMgmt, + pMgmt->abyCurrBSSID, + (8), + &Status); pDevice->bLinkPass = FALSE; ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW); // unlock command busy @@ -614,22 +600,26 @@ vRunCommand( // set initial state pMgmt->eCurrState = WMAC_STATE_IDLE; pMgmt->eCurrMode = WMAC_MODE_STANDBY; - PSvDisablePowerSaving((HANDLE)pDevice); + PSvDisablePowerSaving((void *) pDevice); BSSvClearNodeDBTable(pDevice, 0); - vMgrJoinBSSBegin((HANDLE)pDevice, &Status); + vMgrJoinBSSBegin((void *) pDevice, &Status); // if Infra mode if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED)) { // Call mgr to begin the deauthentication // reason = (3) beacuse sta has left ESS - if (pMgmt->eCurrState>= WMAC_STATE_AUTH) { - vMgrDeAuthenBeginSta((HANDLE)pDevice, pMgmt, pMgmt->abyCurrBSSID, (3), &Status); - } + if (pMgmt->eCurrState >= WMAC_STATE_AUTH) { + vMgrDeAuthenBeginSta((void *)pDevice, + pMgmt, + pMgmt->abyCurrBSSID, + (3), + &Status); + } // Call mgr to begin the authentication - vMgrAuthenBeginSta((HANDLE)pDevice, pMgmt, &Status); + vMgrAuthenBeginSta((void *) pDevice, pMgmt, &Status); if (Status == CMD_STATUS_SUCCESS) { pDevice->byLinkWaitCount = 0; pDevice->eCommandState = WLAN_AUTHENTICATE_WAIT; - vCommandTimerWait((HANDLE)pDevice, AUTHENTICATE_TIMEOUT); + vCommandTimerWait((void *) pDevice, AUTHENTICATE_TIMEOUT); spin_unlock_irq(&pDevice->lock); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Set eCommandState = WLAN_AUTHENTICATE_WAIT\n"); return; @@ -648,10 +638,12 @@ vRunCommand( } else { // start own IBSS - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CreateOwn IBSS by CurrMode = IBSS_STA \n"); - vMgrCreateOwnIBSS((HANDLE)pDevice, &Status); + DBG_PRT(MSG_LEVEL_DEBUG, + KERN_INFO "CreateOwn IBSS by CurrMode = IBSS_STA\n"); + vMgrCreateOwnIBSS((void *) pDevice, &Status); if (Status != CMD_STATUS_SUCCESS){ - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " WLAN_CMD_IBSS_CREATE fail ! \n"); + DBG_PRT(MSG_LEVEL_DEBUG, + KERN_INFO "WLAN_CMD_IBSS_CREATE fail!\n"); }; BSSvAddMulticastNode(pDevice); } @@ -662,10 +654,12 @@ vRunCommand( if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA || pMgmt->eConfigMode == WMAC_CONFIG_AUTO) { // start own IBSS - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CreateOwn IBSS by CurrMode = STANDBY \n"); - vMgrCreateOwnIBSS((HANDLE)pDevice, &Status); + DBG_PRT(MSG_LEVEL_DEBUG, + KERN_INFO "CreateOwn IBSS by CurrMode = STANDBY\n"); + vMgrCreateOwnIBSS((void *) pDevice, &Status); if (Status != CMD_STATUS_SUCCESS){ - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_IBSS_CREATE fail ! \n"); + DBG_PRT(MSG_LEVEL_DEBUG, + KERN_INFO "WLAN_CMD_IBSS_CREATE fail!\n"); }; BSSvAddMulticastNode(pDevice); s_bClearBSSID_SCAN(pDevice); @@ -701,12 +695,12 @@ vRunCommand( pDevice->byLinkWaitCount = 0; // Call mgr to begin the association DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_AUTH\n"); - vMgrAssocBeginSta((HANDLE)pDevice, pMgmt, &Status); + vMgrAssocBeginSta((void *) pDevice, pMgmt, &Status); if (Status == CMD_STATUS_SUCCESS) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState = WLAN_ASSOCIATE_WAIT\n"); pDevice->byLinkWaitCount = 0; pDevice->eCommandState = WLAN_ASSOCIATE_WAIT; - vCommandTimerWait((HANDLE)pDevice, ASSOCIATE_TIMEOUT); + vCommandTimerWait((void *) pDevice, ASSOCIATE_TIMEOUT); spin_unlock_irq(&pDevice->lock); return; } @@ -718,7 +712,7 @@ vRunCommand( pDevice->byLinkWaitCount ++; printk("WLAN_AUTHENTICATE_WAIT:wait %d times!!\n",pDevice->byLinkWaitCount); spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((HANDLE)pDevice, AUTHENTICATE_TIMEOUT/2); + vCommandTimerWait((void *) pDevice, AUTHENTICATE_TIMEOUT/2); return; } pDevice->byLinkWaitCount = 0; @@ -742,7 +736,8 @@ vRunCommand( if (pMgmt->eCurrState == WMAC_STATE_ASSOC) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_ASSOC\n"); if (pDevice->ePSMode != WMAC_POWER_CAM) { - PSvEnablePowerSaving((HANDLE)pDevice, pMgmt->wListenInterval); + PSvEnablePowerSaving((void *) pDevice, + pMgmt->wListenInterval); } /* if (pMgmt->eAuthenMode >= WMAC_AUTH_WPA) { @@ -786,7 +781,7 @@ vRunCommand( pDevice->byLinkWaitCount ++; printk("WLAN_ASSOCIATE_WAIT:wait %d times!!\n",pDevice->byLinkWaitCount); spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((HANDLE)pDevice, ASSOCIATE_TIMEOUT/2); + vCommandTimerWait((void *) pDevice, ASSOCIATE_TIMEOUT/2); return; } pDevice->byLinkWaitCount = 0; @@ -823,9 +818,10 @@ vRunCommand( pMgmt->eCurrState = WMAC_STATE_IDLE; pDevice->bFixRate = FALSE; - vMgrCreateOwnIBSS((HANDLE)pDevice, &Status); - if (Status != CMD_STATUS_SUCCESS){ - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " vMgrCreateOwnIBSS fail ! \n"); + vMgrCreateOwnIBSS((void *) pDevice, &Status); + if (Status != CMD_STATUS_SUCCESS) { + DBG_PRT(MSG_LEVEL_DEBUG, + KERN_INFO "vMgrCreateOwnIBSS fail!\n"); }; // alway turn off unicast bit MACvRegBitsOff(pDevice, MAC_REG_RCR, RCR_UNICAST); @@ -948,7 +944,11 @@ vRunCommand( if (pDevice->bLinkPass == TRUE) { // reason = 8 : disassoc because sta has left - vMgrDisassocBeginSta((HANDLE)pDevice, pMgmt, pMgmt->abyCurrBSSID, (8), &Status); + vMgrDisassocBeginSta((void *) pDevice, + pMgmt, + pMgmt->abyCurrBSSID, + (8), + &Status); pDevice->bLinkPass = FALSE; // unlock command busy pMgmt->eCurrState = WMAC_STATE_IDLE; @@ -1185,18 +1185,15 @@ s_bCommandComplete ( break; } - - vCommandTimerWait((HANDLE)pDevice, 0); + vCommandTimerWait((void *) pDevice, 0); } return TRUE; } -BOOL bScheduleCommand ( - HANDLE hDeviceContext, - CMD_CODE eCommand, - PBYTE pbyItem0 - ) +BOOL bScheduleCommand(void *hDeviceContext, + CMD_CODE eCommand, + PBYTE pbyItem0) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1264,10 +1261,7 @@ BOOL bScheduleCommand ( * Return Value: TRUE if success; otherwise FALSE * */ -static -BOOL s_bClearBSSID_SCAN ( - HANDLE hDeviceContext - ) +static BOOL s_bClearBSSID_SCAN(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; UINT uCmdDequeueIdx = pDevice->uCmdDequeueIdx; @@ -1287,10 +1281,7 @@ BOOL s_bClearBSSID_SCAN ( //mike add:reset command timer -void -vResetCommandTimer( - HANDLE hDeviceContext - ) +void vResetCommandTimer(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1311,10 +1302,7 @@ vResetCommandTimer( //2007-0115-08by MikeLiu #ifdef TxInSleep -void -BSSvSecondTxData( - HANDLE hDeviceContext - ) +void BSSvSecondTxData(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); diff --git a/drivers/staging/vt6656/wcmd.h b/drivers/staging/vt6656/wcmd.h index a14e56470ea1..09c4411c6891 100644 --- a/drivers/staging/vt6656/wcmd.h +++ b/drivers/staging/vt6656/wcmd.h @@ -105,33 +105,22 @@ typedef enum tagCMD_STATE { WLAN_CMD_IDLE } CMD_STATE, *PCMD_STATE; - - /*--------------------- Export Classes ----------------------------*/ /*--------------------- Export Variables --------------------------*/ - /*--------------------- Export Types ------------------------------*/ - /*--------------------- Export Functions --------------------------*/ -void -vResetCommandTimer( - HANDLE hDeviceContext - ); -BOOL -bScheduleCommand( - HANDLE hDeviceContext, - CMD_CODE eCommand, - PBYTE pbyItem0 - ); +void vResetCommandTimer(void *hDeviceContext); + +BOOL bScheduleCommand(void *hDeviceContext, + CMD_CODE eCommand, + PBYTE pbyItem0); + +void vRunCommand(void *hDeviceContext); -void -vRunCommand( - HANDLE hDeviceContext - ); /* void WCMDvCommandThread( @@ -141,10 +130,7 @@ WCMDvCommandThread( //2007-0115-09by MikeLiu #ifdef TxInSleep -void -BSSvSecondTxData( - HANDLE hDeviceContext - ); +void BSSvSecondTxData(void *hDeviceContext); #endif #endif /* __WCMD_H__ */ diff --git a/drivers/staging/vt6656/wmgr.c b/drivers/staging/vt6656/wmgr.c index 5af98e9a8f03..aaba5221170d 100644 --- a/drivers/staging/vt6656/wmgr.c +++ b/drivers/staging/vt6656/wmgr.c @@ -329,14 +329,10 @@ s_bCipherMatch ( PKnownBSS pCurr ); - - /*--------------------- Export Variables --------------------------*/ - /*--------------------- Export Functions --------------------------*/ - /*+ * * Routine Description: @@ -347,10 +343,7 @@ s_bCipherMatch ( * -*/ -void -vMgrObjectInit( - HANDLE hDeviceContext - ) +void vMgrObjectInit(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -368,7 +361,7 @@ vMgrObjectInit( pMgmt->byCSSPK = KEY_CTL_NONE; pMgmt->byCSSGK = KEY_CTL_NONE; pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI; - BSSvClearBSSList((HANDLE)pDevice, FALSE); + BSSvClearBSSList((void *) pDevice, FALSE); init_timer(&pMgmt->sTimerSecondCallback); pMgmt->sTimerSecondCallback.data = (ULONG)pDevice; @@ -401,8 +394,6 @@ vMgrObjectInit( return; } - - /*+ * * Routine Description: @@ -414,13 +405,9 @@ vMgrObjectInit( * -*/ - -void -vMgrAssocBeginSta( - HANDLE hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus - ) +void vMgrAssocBeginSta(void *hDeviceContext, + PSMgmtObject pMgmt, + PCMD_STATUS pStatus) { PSDevice pDevice = (PSDevice)hDeviceContext; PSTxMgmtPacket pTxPacket; @@ -491,12 +478,9 @@ vMgrAssocBeginSta( * -*/ -void -vMgrReAssocBeginSta( - HANDLE hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus - ) +void vMgrReAssocBeginSta(void *hDeviceContext, + PSMgmtObject pMgmt, + PCMD_STATUS pStatus) { PSDevice pDevice = (PSDevice)hDeviceContext; PSTxMgmtPacket pTxPacket; @@ -570,14 +554,11 @@ vMgrReAssocBeginSta( * -*/ -void -vMgrDisassocBeginSta( - HANDLE hDeviceContext, - PSMgmtObject pMgmt, - PBYTE abyDestAddress, - WORD wReason, - PCMD_STATUS pStatus - ) +void vMgrDisassocBeginSta(void *hDeviceContext, + PSMgmtObject pMgmt, + PBYTE abyDestAddress, + WORD wReason, + PCMD_STATUS pStatus) { PSDevice pDevice = (PSDevice)hDeviceContext; PSTxMgmtPacket pTxPacket = NULL; @@ -987,7 +968,10 @@ s_vMgrRxAssocResponse( }; DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Association Successful, AID=%d.\n", pMgmt->wCurrAID & ~(BIT14|BIT15)); pMgmt->eCurrState = WMAC_STATE_ASSOC; - BSSvUpdateAPNode((HANDLE)pDevice, sFrame.pwCapInfo, sFrame.pSuppRates, sFrame.pExtSuppRates); + BSSvUpdateAPNode((void *) pDevice, + sFrame.pwCapInfo, + sFrame.pSuppRates, + sFrame.pExtSuppRates); pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Link with AP(SSID): %s\n", pItemSSID->abySSID); pDevice->bLinkPass = TRUE; @@ -1089,8 +1073,6 @@ if(pMgmt->eCurrState == WMAC_STATE_ASSOC) return; } - - /*+ * * Routine Description: @@ -1102,12 +1084,9 @@ if(pMgmt->eCurrState == WMAC_STATE_ASSOC) * -*/ -void -vMgrAuthenBeginSta( - HANDLE hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus - ) +void vMgrAuthenBeginSta(void *hDeviceContext, + PSMgmtObject pMgmt, + PCMD_STATUS pStatus) { PSDevice pDevice = (PSDevice)hDeviceContext; WLAN_FR_AUTHEN sFrame; @@ -1147,8 +1126,6 @@ vMgrAuthenBeginSta( return ; } - - /*+ * * Routine Description: @@ -1160,14 +1137,11 @@ vMgrAuthenBeginSta( * -*/ -void -vMgrDeAuthenBeginSta( - HANDLE hDeviceContext, - PSMgmtObject pMgmt, - PBYTE abyDestAddress, - WORD wReason, - PCMD_STATUS pStatus - ) +void vMgrDeAuthenBeginSta(void *hDeviceContext, + PSMgmtObject pMgmt, + PBYTE abyDestAddress, + WORD wReason, + PCMD_STATUS pStatus) { PSDevice pDevice = (PSDevice)hDeviceContext; WLAN_FR_DEAUTHEN sFrame; @@ -1405,12 +1379,11 @@ s_vMgrRxAuthenSequence_2( s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus)))); pMgmt->eCurrState = WMAC_STATE_IDLE; } - if (pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT ) { -// spin_unlock_irq(&pDevice->lock); -// vCommandTimerWait((HANDLE)pDevice, 0); -// spin_lock_irq(&pDevice->lock); + if (pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT) { + /* spin_unlock_irq(&pDevice->lock); + vCommandTimerWait((void *) pDevice, 0); + spin_lock_irq(&pDevice->lock); */ } - break; case WLAN_AUTH_ALG_SHAREDKEY: @@ -1453,9 +1426,9 @@ s_vMgrRxAuthenSequence_2( else { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:rx Auth_reply sequence_2 status error ...\n"); if ( pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT ) { -// spin_unlock_irq(&pDevice->lock); -// vCommandTimerWait((HANDLE)pDevice, 0); -// spin_lock_irq(&pDevice->lock); + /* spin_unlock_irq(&pDevice->lock); + vCommandTimerWait((void *) pDevice, 0); + spin_lock_irq(&pDevice->lock); */ } s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus)))); } @@ -1591,11 +1564,10 @@ s_vMgrRxAuthenSequence_4( } if ( pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT ) { -// spin_unlock_irq(&pDevice->lock); -// vCommandTimerWait((HANDLE)pDevice, 0); -// spin_lock_irq(&pDevice->lock); + /* spin_unlock_irq(&pDevice->lock); + vCommandTimerWait((void *) pDevice, 0); + spin_lock_irq(&pDevice->lock); */ } - } /*+ @@ -1913,10 +1885,12 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) sERP.byERP = 0; } - pBSSList = BSSpAddrIsInBSSList((HANDLE)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID); + pBSSList = BSSpAddrIsInBSSList((void *) pDevice, + sFrame.pHdr->sA3.abyAddr3, + sFrame.pSSID); if (pBSSList == NULL) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Beacon/insert: RxChannel = : %d\n", byCurrChannel); - BSSbInsertToBSSList((HANDLE)pDevice, + BSSbInsertToBSSList((void *) pDevice, sFrame.pHdr->sA3.abyAddr3, *sFrame.pqwTimestamp, *sFrame.pwBeaconInterval, @@ -1932,12 +1906,11 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) sFrame.pIE_Quiet, sFrame.len - WLAN_HDR_ADDR3_LEN, sFrame.pHdr->sA4.abyAddr4, // payload of beacon - (HANDLE)pRxPacket - ); + (void *) pRxPacket); } else { // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"update bcn: RxChannel = : %d\n", byCurrChannel); - BSSbUpdateToBSSList((HANDLE)pDevice, + BSSbUpdateToBSSList((void *) pDevice, *sFrame.pqwTimestamp, *sFrame.pwBeaconInterval, *sFrame.pwCapInfo, @@ -1954,8 +1927,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) pBSSList, sFrame.len - WLAN_HDR_ADDR3_LEN, sFrame.pHdr->sA4.abyAddr4, // payload of probresponse - (HANDLE)pRxPacket - ); + (void *) pRxPacket); } @@ -2324,7 +2296,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) // set highest basic rate // s_vSetHighestBasicRate(pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates); // Prepare beacon frame - bMgrPrepareBeaconToSend((HANDLE)pDevice, pMgmt); + bMgrPrepareBeaconToSend((void *) pDevice, pMgmt); // } }; } @@ -2341,8 +2313,6 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) return; } - - /*+ * * Routine Description: @@ -2355,11 +2325,9 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) * CMD_STATUS * -*/ -void -vMgrCreateOwnIBSS( - HANDLE hDeviceContext, - PCMD_STATUS pStatus - ) + +void vMgrCreateOwnIBSS(void *hDeviceContext, + PCMD_STATUS pStatus) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -2609,13 +2577,11 @@ vMgrCreateOwnIBSS( pMgmt->eCurrState = WMAC_STATE_STARTED; // Prepare beacon to send - if (bMgrPrepareBeaconToSend((HANDLE)pDevice, pMgmt)) { - *pStatus = CMD_STATUS_SUCCESS; - } - return ; -} - + if (bMgrPrepareBeaconToSend((void *) pDevice, pMgmt)) + *pStatus = CMD_STATUS_SUCCESS; + return; +} /*+ * @@ -2630,13 +2596,8 @@ vMgrCreateOwnIBSS( * -*/ -void -vMgrJoinBSSBegin( - HANDLE hDeviceContext, - PCMD_STATUS pStatus - ) +void vMgrJoinBSSBegin(void *hDeviceContext, PCMD_STATUS pStatus) { - PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); PKnownBSS pCurr = NULL; @@ -2782,12 +2743,17 @@ vMgrJoinBSSBegin( // Add current BSS to Candidate list // This should only works for WPA2 BSS, and WPA2 BSS check must be done before. if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) { - BOOL bResult = bAdd_PMKID_Candidate((HANDLE)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj); + BOOL bResult = bAdd_PMKID_Candidate((void *) pDevice, + pMgmt->abyCurrBSSID, + &pCurr->sRSNCapObj); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate: 1(%d)\n", bResult); if (bResult == FALSE) { - vFlush_PMKID_Candidate((HANDLE)pDevice); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFlush_PMKID_Candidate: 4\n"); - bAdd_PMKID_Candidate((HANDLE)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj); + vFlush_PMKID_Candidate((void *) pDevice); + DBG_PRT(MSG_LEVEL_DEBUG, + KERN_INFO "vFlush_PMKID_Candidate: 4\n"); + bAdd_PMKID_Candidate((void *) pDevice, + pMgmt->abyCurrBSSID, + &pCurr->sRSNCapObj); } } @@ -2940,7 +2906,7 @@ vMgrJoinBSSBegin( CARDvSetRSPINF(pDevice, (BYTE)pDevice->byBBType); // Prepare beacon - bMgrPrepareBeaconToSend((HANDLE)pDevice, pMgmt); + bMgrPrepareBeaconToSend((void *) pDevice, pMgmt); } else { pMgmt->eCurrState = WMAC_STATE_IDLE; @@ -4299,31 +4265,32 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) // update or insert the bss - pBSSList = BSSpAddrIsInBSSList((HANDLE)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID); + pBSSList = BSSpAddrIsInBSSList((void *) pDevice, + sFrame.pHdr->sA3.abyAddr3, + sFrame.pSSID); if (pBSSList) { - BSSbUpdateToBSSList((HANDLE)pDevice, - *sFrame.pqwTimestamp, - *sFrame.pwBeaconInterval, - *sFrame.pwCapInfo, - byCurrChannel, - bChannelHit, - sFrame.pSSID, - sFrame.pSuppRates, - sFrame.pExtSuppRates, - &sERP, - sFrame.pRSN, - sFrame.pRSNWPA, - sFrame.pIE_Country, - sFrame.pIE_Quiet, - pBSSList, - sFrame.len - WLAN_HDR_ADDR3_LEN, - sFrame.pHdr->sA4.abyAddr4, // payload of probresponse - (HANDLE)pRxPacket - ); - } - else { + BSSbUpdateToBSSList((void *) pDevice, + *sFrame.pqwTimestamp, + *sFrame.pwBeaconInterval, + *sFrame.pwCapInfo, + byCurrChannel, + bChannelHit, + sFrame.pSSID, + sFrame.pSuppRates, + sFrame.pExtSuppRates, + &sERP, + sFrame.pRSN, + sFrame.pRSNWPA, + sFrame.pIE_Country, + sFrame.pIE_Quiet, + pBSSList, + sFrame.len - WLAN_HDR_ADDR3_LEN, + /* payload of probresponse */ + sFrame.pHdr->sA4.abyAddr4, + (void *) pRxPacket); + } else { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Probe resp/insert: RxChannel = : %d\n", byCurrChannel); - BSSbInsertToBSSList((HANDLE)pDevice, + BSSbInsertToBSSList((void *) pDevice, sFrame.pHdr->sA3.abyAddr3, *sFrame.pqwTimestamp, *sFrame.pwBeaconInterval, @@ -4338,9 +4305,8 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) sFrame.pIE_Country, sFrame.pIE_Quiet, sFrame.len - WLAN_HDR_ADDR3_LEN, - sFrame.pHdr->sA4.abyAddr4, // payload of beacon - (HANDLE)pRxPacket - ); + sFrame.pHdr->sA4.abyAddr4, /* payload of beacon */ + (void *) pRxPacket); } return; @@ -4436,10 +4402,6 @@ s_vMgrRxProbeRequest( return; } - - - - /*+ * * Routine Description: @@ -4454,13 +4416,9 @@ s_vMgrRxProbeRequest( * -*/ - -void -vMgrRxManagePacket( - HANDLE hDeviceContext, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket - ) +void vMgrRxManagePacket(void *hDeviceContext, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket) { PSDevice pDevice = (PSDevice)hDeviceContext; BOOL bInScan = FALSE; @@ -4593,9 +4551,6 @@ vMgrRxManagePacket( return; } - - - /*+ * * Routine Description: @@ -4607,11 +4562,7 @@ vMgrRxManagePacket( * TRUE if success; FALSE if failed. * -*/ -BOOL -bMgrPrepareBeaconToSend( - HANDLE hDeviceContext, - PSMgmtObject pMgmt - ) +BOOL bMgrPrepareBeaconToSend(void *hDeviceContext, PSMgmtObject pMgmt) { PSDevice pDevice = (PSDevice)hDeviceContext; PSTxMgmtPacket pTxPacket; @@ -4715,7 +4666,6 @@ s_vMgrLogStatus( } } - /* * * Description: @@ -4732,12 +4682,10 @@ s_vMgrLogStatus( * Return Value: none. * -*/ -BOOL -bAdd_PMKID_Candidate ( - HANDLE hDeviceContext, - PBYTE pbyBSSID, - PSRSNCapObject psRSNCapObj - ) + +BOOL bAdd_PMKID_Candidate(void *hDeviceContext, + PBYTE pbyBSSID, + PSRSNCapObject psRSNCapObj) { PSDevice pDevice = (PSDevice)hDeviceContext; PPMKID_CANDIDATE pCandidateList; @@ -4796,10 +4744,8 @@ bAdd_PMKID_Candidate ( * Return Value: none. * -*/ -void -vFlush_PMKID_Candidate ( - HANDLE hDeviceContext - ) + +void vFlush_PMKID_Candidate(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; diff --git a/drivers/staging/vt6656/wmgr.h b/drivers/staging/vt6656/wmgr.h index 0eda12afd26b..ec2ee7805f4e 100644 --- a/drivers/staging/vt6656/wmgr.h +++ b/drivers/staging/vt6656/wmgr.h @@ -400,102 +400,61 @@ typedef struct tagSMgmtObject } SMgmtObject, *PSMgmtObject; - /*--------------------- Export Macros ------------------------------*/ - /*--------------------- Export Functions --------------------------*/ +void vMgrObjectInit(void *hDeviceContext); -void -vMgrObjectInit( - HANDLE hDeviceContext - ); +void vMgrAssocBeginSta(void *hDeviceContext, + PSMgmtObject pMgmt, + PCMD_STATUS pStatus); +void vMgrReAssocBeginSta(void *hDeviceContext, + PSMgmtObject pMgmt, + PCMD_STATUS pStatus); -void -vMgrAssocBeginSta( - HANDLE hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus - ); +void vMgrDisassocBeginSta(void *hDeviceContext, + PSMgmtObject pMgmt, + PBYTE abyDestAddress, + WORD wReason, + PCMD_STATUS pStatus); -void -vMgrReAssocBeginSta( - HANDLE hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus - ); - -void -vMgrDisassocBeginSta( - HANDLE hDeviceContext, - PSMgmtObject pMgmt, - PBYTE abyDestAddress, - WORD wReason, - PCMD_STATUS pStatus - ); - -void -vMgrAuthenBeginSta( - HANDLE hDeviceContext, - PSMgmtObject pMgmt, - PCMD_STATUS pStatus - ); +void vMgrAuthenBeginSta(void *hDeviceContext, + PSMgmtObject pMgmt, + PCMD_STATUS pStatus); -void -vMgrCreateOwnIBSS( - HANDLE hDeviceContext, - PCMD_STATUS pStatus - ); +void vMgrCreateOwnIBSS(void *hDeviceContext, + PCMD_STATUS pStatus); -void -vMgrJoinBSSBegin( - HANDLE hDeviceContext, - PCMD_STATUS pStatus - ); +void vMgrJoinBSSBegin(void *hDeviceContext, + PCMD_STATUS pStatus); -void -vMgrRxManagePacket( - HANDLE hDeviceContext, - PSMgmtObject pMgmt, - PSRxMgmtPacket pRxPacket - ); +void vMgrRxManagePacket(void *hDeviceContext, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket); /* void vMgrScanBegin( - HANDLE hDeviceContext, + void *hDeviceContext, PCMD_STATUS pStatus ); */ -void -vMgrDeAuthenBeginSta( - HANDLE hDeviceContext, - PSMgmtObject pMgmt, - PBYTE abyDestAddress, - WORD wReason, - PCMD_STATUS pStatus - ); - -BOOL -bMgrPrepareBeaconToSend( - HANDLE hDeviceContext, - PSMgmtObject pMgmt - ); +void vMgrDeAuthenBeginSta(void *hDeviceContext, + PSMgmtObject pMgmt, + PBYTE abyDestAddress, + WORD wReason, + PCMD_STATUS pStatus); +BOOL bMgrPrepareBeaconToSend(void *hDeviceContext, + PSMgmtObject pMgmt); -BOOL -bAdd_PMKID_Candidate ( - HANDLE hDeviceContext, - PBYTE pbyBSSID, - PSRSNCapObject psRSNCapObj - ); +BOOL bAdd_PMKID_Candidate(void *hDeviceContext, + PBYTE pbyBSSID, + PSRSNCapObject psRSNCapObj); -void -vFlush_PMKID_Candidate ( - HANDLE hDeviceContext - ); +void vFlush_PMKID_Candidate(void *hDeviceContext); #endif /* __WMGR_H__ */ diff --git a/drivers/staging/vt6656/wpactl.c b/drivers/staging/vt6656/wpactl.c index 25b784c26e8f..04a4875e6015 100644 --- a/drivers/staging/vt6656/wpactl.c +++ b/drivers/staging/vt6656/wpactl.c @@ -489,7 +489,7 @@ static int wpa_set_disassociate(PSDevice pDevice, spin_lock_irq(&pDevice->lock); if (pDevice->bLinkPass) { if (!memcmp(param->addr, pMgmt->abyCurrBSSID, 6)) - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_DISASSOCIATE, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL); } spin_unlock_irq(&pDevice->lock); @@ -513,7 +513,7 @@ static int wpa_set_disassociate(PSDevice pDevice, */ static int wpa_set_scan(PSDevice pDevice, - struct viawget_wpa_param *param) + struct viawget_wpa_param *param) { int ret = 0; @@ -531,9 +531,11 @@ memcpy(pItemSSID->abySSID, param->u.scan_req.ssid, param->u.scan_req.ssid_len); pItemSSID->len = param->u.scan_req.ssid_len; spin_lock_irq(&pDevice->lock); - BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass); - // bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); + BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass); + /* bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); */ + bScheduleCommand((void *) pDevice, + WLAN_CMD_BSSID_SCAN, + pMgmt->abyDesireSSID); spin_unlock_irq(&pDevice->lock); return ret; @@ -886,12 +888,14 @@ static int wpa_set_associate(PSDevice pDevice, if (pCurr == NULL){ printk("wpa_set_associate---->hidden mode site survey before associate.......\n"); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, + WLAN_CMD_BSSID_SCAN, + pMgmt->abyDesireSSID); }; } /****************************************************************/ - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); spin_unlock_irq(&pDevice->lock); return ret; -- cgit v1.2.3 From 717f4a5f55e307b3ba2b1a8c05428bb5dd35047e Mon Sep 17 00:00:00 2001 From: Marin Mitov Date: Fri, 7 May 2010 11:00:35 +0300 Subject: staging: dt3155v4l syncronize with API changes dt3155v4l driver, as in -rc6-next-20100506 compiles, but will not run properly due to recent changes in the videobuf APIs. This patch synchronizes some functions that have been copied from drivers/media/video/videobuf-dma-contig.c (and modified) with the recent (-rc6 -> -rc6-next-) changes in videobuf layer especially drivers/media/video/videobuf-dma-contig.c Signed-off-by: Marin Mitov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dt3155v4l/dt3155v4l.c | 68 ++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dt3155v4l/dt3155v4l.c b/drivers/staging/dt3155v4l/dt3155v4l.c index 881c3e99bd47..b1695ad9b56e 100644 --- a/drivers/staging/dt3155v4l/dt3155v4l.c +++ b/drivers/staging/dt3155v4l/dt3155v4l.c @@ -1,3 +1,23 @@ +/*************************************************************************** + * Copyright (C) 2006-2010 by Marin Mitov * + * mitov@issp.bas.bg * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + #include #include #include @@ -260,9 +280,11 @@ dt3155_dma_contig_user_get(struct videobuf_dma_contig_memory *mem, struct vm_area_struct *vma; unsigned long prev_pfn, this_pfn; unsigned long pages_done, user_address; + unsigned int offset; int ret; - mem->size = PAGE_ALIGN(vb->size); + offset = vb->baddr & ~PAGE_MASK; + mem->size = PAGE_ALIGN(vb->size + offset); mem->is_userptr = 0; ret = -EINVAL; @@ -285,7 +307,7 @@ dt3155_dma_contig_user_get(struct videobuf_dma_contig_memory *mem, break; if (pages_done == 0) - mem->dma_handle = this_pfn << PAGE_SHIFT; + mem->dma_handle = (this_pfn << PAGE_SHIFT) + offset; else if (this_pfn != (prev_pfn + 1)) ret = -EFAULT; @@ -416,14 +438,14 @@ dt3155_vm_close(struct vm_area_struct *vma) struct videobuf_queue *q = map->q; int i; - dev_dbg(map->q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", + dev_dbg(q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", map, map->count, vma->vm_start, vma->vm_end); map->count--; if (0 == map->count) { struct videobuf_dma_contig_memory *mem; - dev_dbg(map->q->dev, "munmap %p q=%p\n", map, q); + dev_dbg(q->dev, "munmap %p q=%p\n", map, q); mutex_lock(&q->vb_lock); /* We need first to cancel streams, before unmapping */ @@ -450,7 +472,7 @@ dt3155_vm_close(struct vm_area_struct *vma) /* vfree is not atomic - can't be called with IRQ's disabled */ - dev_dbg(map->q->dev, "buf[%d] freeing %p\n", + dev_dbg(q->dev, "buf[%d] freeing %p\n", i, mem->vaddr); dt3155_free_buffer(q->dev, mem->size, @@ -475,51 +497,33 @@ static const struct vm_operations_struct dt3155_vm_ops = { /* same as videobuf_mmap_mapper(), but allocates from the pool */ static int -dt3155_mmap_mapper(struct videobuf_queue *q, struct vm_area_struct *vma) +dt3155_mmap_mapper(struct videobuf_queue *q, struct videobuf_buffer *buf, + struct vm_area_struct *vma) { struct videobuf_dma_contig_memory *mem; struct videobuf_mapping *map; - unsigned int first; int retval; - unsigned long size, offset = vma->vm_pgoff << PAGE_SHIFT; + unsigned long size; dev_dbg(q->dev, "%s\n", __func__); - if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED)) - return -EINVAL; - - /* look for first buffer to map */ - for (first = 0; first < VIDEO_MAX_FRAME; first++) { - if (!q->bufs[first]) - continue; - - if (V4L2_MEMORY_MMAP != q->bufs[first]->memory) - continue; - if (q->bufs[first]->boff == offset) - break; - } - if (VIDEO_MAX_FRAME == first) { - dev_dbg(q->dev, "invalid user space offset [offset=0x%lx]\n", - offset); - return -EINVAL; - } /* create mapping + update buffer list */ map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL); if (!map) return -ENOMEM; - q->bufs[first]->map = map; + buf->map = map; map->start = vma->vm_start; map->end = vma->vm_end; map->q = q; - q->bufs[first]->baddr = vma->vm_start; + buf->baddr = vma->vm_start; - mem = q->bufs[first]->priv; + mem = buf->priv; BUG_ON(!mem); MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); - mem->size = PAGE_ALIGN(q->bufs[first]->bsize); + mem->size = PAGE_ALIGN(buf->bsize); mem->vaddr = dt3155_alloc_buffer(q->dev, mem->size, &mem->dma_handle, GFP_KERNEL); if (!mem->vaddr) { @@ -552,8 +556,8 @@ dt3155_mmap_mapper(struct videobuf_queue *q, struct vm_area_struct *vma) dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n", map, q, vma->vm_start, vma->vm_end, - (long int) q->bufs[first]->bsize, - vma->vm_pgoff, first); + (long int)buf->bsize, + vma->vm_pgoff, buf->i); dt3155_vm_open(vma); -- cgit v1.2.3 From f9bd64952037d0f58eeffa07e30da1fff4c39b8f Mon Sep 17 00:00:00 2001 From: Christos Tzoumakis Date: Fri, 7 May 2010 06:17:24 +0300 Subject: Staging: wlan-ng : fixing coding style issues in prism2sta.c Signed-off-by: Christos Tzoumakis Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/prism2sta.c | 71 +++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index 31ac8da39c81..6cd09352f893 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -426,7 +426,7 @@ static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg) * msgp ptr to msg buffer * * Returns: -* A p80211 message resultcode value. +* A p80211 message resultcode value. * * Side effects: * @@ -458,7 +458,7 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate) "hfa384x_drvr_start() failed," "result=%d\n", (int)result); result = - P80211ENUM_resultcode_implementation_failure; + P80211ENUM_resultcode_implementation_failure; wlandev->msdstate = WLAN_MSD_HWPRESENT; break; } @@ -503,7 +503,7 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate) "hfa384x_drvr_start() failed," "result=%d\n", (int)result); result = - P80211ENUM_resultcode_implementation_failure; + P80211ENUM_resultcode_implementation_failure; wlandev->msdstate = WLAN_MSD_HWPRESENT; break; } @@ -514,7 +514,7 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate) "prism2sta_getcardinfo() failed," "result=%d\n", (int)result); result = - P80211ENUM_resultcode_implementation_failure; + P80211ENUM_resultcode_implementation_failure; hfa384x_drvr_stop(hw); wlandev->msdstate = WLAN_MSD_HWPRESENT; break; @@ -525,7 +525,7 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate) "prism2sta_globalsetup() failed," "result=%d\n", (int)result); result = - P80211ENUM_resultcode_implementation_failure; + P80211ENUM_resultcode_implementation_failure; hfa384x_drvr_stop(hw); wlandev->msdstate = WLAN_MSD_HWPRESENT; break; @@ -1178,8 +1178,8 @@ static void prism2sta_inf_chinforesults(wlandevice_t *wlandev, chinforesult->active = le16_to_cpu(inf->info.chinforesult.result[n]. active); - pr_debug - ("chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n", + pr_debug + ("chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n", channel + 1, chinforesult-> active & HFA384x_CHINFORESULT_BSSACTIVE ? "signal" @@ -1246,7 +1246,9 @@ void prism2sta_processing_defer(struct work_struct *data) netif_carrier_on(wlandev->netdev); - /* If we are joining a specific AP, set our state and reset retries */ + /* If we are joining a specific AP, set our + * state and reset retries + */ if (hw->join_ap == 1) hw->join_ap = 2; hw->join_retries = 60; @@ -1261,9 +1263,9 @@ void prism2sta_processing_defer(struct work_struct *data) /* Collect the BSSID, and set state to allow tx */ result = hfa384x_drvr_getconfig(hw, - HFA384x_RID_CURRENTBSSID, - wlandev->bssid, - WLAN_BSSID_LEN); + HFA384x_RID_CURRENTBSSID, + wlandev->bssid, + WLAN_BSSID_LEN); if (result) { pr_debug ("getconfig(0x%02x) failed, result = %d\n", @@ -1286,8 +1288,8 @@ void prism2sta_processing_defer(struct work_struct *data) /* Collect the port status */ result = hfa384x_drvr_getconfig16(hw, - HFA384x_RID_PORTSTATUS, - &portstatus); + HFA384x_RID_PORTSTATUS, + &portstatus); if (result) { pr_debug ("getconfig(0x%02x) failed, result = %d\n", @@ -1322,7 +1324,7 @@ void prism2sta_processing_defer(struct work_struct *data) &joinreq, HFA384x_RID_JOINREQUEST_LEN); printk(KERN_INFO - "linkstatus=DISCONNECTED (re-submitting join)\n"); + "linkstatus=DISCONNECTED (re-submitting join)\n"); } else { if (wlandev->netdev->type == ARPHRD_ETHER) printk(KERN_INFO @@ -1509,14 +1511,15 @@ static void prism2sta_inf_assocstatus(wlandevice_t *wlandev, rec.reason = le16_to_cpu(rec.reason); /* - ** Find the address in the list of authenticated stations. If it wasn't - ** found, then this address has not been previously authenticated and - ** something weird has happened if this is anything other than an - ** "authentication failed" message. If the address was found, then - ** set the "associated" flag for that station, based on whether the - ** station is associating or losing its association. Something weird - ** has also happened if we find the address in the list of authenticated - ** stations but we are getting an "authentication failed" message. + ** Find the address in the list of authenticated stations. + ** If it wasn't found, then this address has not been previously + ** authenticated and something weird has happened if this is + ** anything other than an "authentication failed" message. + ** If the address was found, then set the "associated" flag for + ** that station, based on whether the station is associating or + ** losing its association. Something weird has also happened + ** if we find the address in the list of authenticated stations + ** but we are getting an "authentication failed" message. */ for (i = 0; i < hw->authlist.cnt; i++) @@ -1526,7 +1529,7 @@ static void prism2sta_inf_assocstatus(wlandevice_t *wlandev, if (i >= hw->authlist.cnt) { if (rec.assocstatus != HFA384x_ASSOCSTATUS_AUTHFAIL) printk(KERN_WARNING - "assocstatus info frame received for non-authenticated station.\n"); + "assocstatus info frame received for non-authenticated station.\n"); } else { hw->authlist.assoc[i] = (rec.assocstatus == HFA384x_ASSOCSTATUS_STAASSOC || @@ -1534,7 +1537,7 @@ static void prism2sta_inf_assocstatus(wlandevice_t *wlandev, if (rec.assocstatus == HFA384x_ASSOCSTATUS_AUTHFAIL) printk(KERN_WARNING - "authfail assocstatus info frame received for authenticated station.\n"); +"authfail assocstatus info frame received for authenticated station.\n"); } return; @@ -1681,12 +1684,12 @@ static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev, } /* - ** If the authentication is okay, then add the MAC address to the list - ** of authenticated stations. Don't add the address if it is already in - ** the list. (802.11b does not seem to disallow a station from issuing - ** an authentication request when the station is already authenticated. - ** Does this sort of thing ever happen? We might as well do the check - ** just in case.) + ** If the authentication is okay, then add the MAC address to the + ** list of authenticated stations. Don't add the address if it + ** is already in the list. (802.11b does not seem to disallow + ** a station from issuing an authentication request when the + ** station is already authenticated. Does this sort of thing + ** ever happen? We might as well do the check just in case.) */ added = 0; @@ -1931,7 +1934,7 @@ void prism2sta_ev_alloc(wlandevice_t *wlandev) * the created wlandevice_t structure. * * Side effects: -* also allocates the priv/hw structures. +* also allocates the priv/hw structures. * * Call context: * process thread @@ -1995,9 +1998,9 @@ void prism2sta_commsqual_defer(struct work_struct *data) /* It only makes sense to poll these in non-IBSS */ if (wlandev->macmode != WLAN_MACMODE_IBSS_STA) { - result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DBMCOMMSQUALITY, - &hw->qual, - HFA384x_RID_DBMCOMMSQUALITY_LEN); + result = hfa384x_drvr_getconfig( + hw, HFA384x_RID_DBMCOMMSQUALITY, + &hw->qual, HFA384x_RID_DBMCOMMSQUALITY_LEN); if (result) { printk(KERN_ERR "error fetching commsqual\n"); -- cgit v1.2.3 From 85798ec85ec6146bff3af886c06d72cc66940a05 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 7 May 2010 15:38:54 +0100 Subject: staging: iio: Documentation fixes Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/sysfs-class-iio | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/sysfs-class-iio b/drivers/staging/iio/Documentation/sysfs-class-iio index 723858215786..ff19f6e22e34 100644 --- a/drivers/staging/iio/Documentation/sysfs-class-iio +++ b/drivers/staging/iio/Documentation/sysfs-class-iio @@ -66,7 +66,7 @@ KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: If known for a device, offset to be added to in[m]_raw prior - to scaling by volt[m]_scale in order to obtain voltage in + to scaling by in[_name][m]_scale in order to obtain voltage in millivolts. Not present if the offset is always 0 or unknown. If m is not present, then voltage offset applies to all in channels. May be writable if a variable offset is controlled @@ -111,8 +111,8 @@ KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: If known for a device, scale to be applied to volt[m]_raw post - addition of volt[m]_offset in order to obtain the measured voltage - in millivolts. If shared across all in channels then m is not present. + addition of in[_name][m]_offset in order to obtain the measured + voltage in millivolts. If shared across all in channels then m is not present. What: /sys/.../device[n]/in[m]-in[o]_raw KernelVersion: 2.6.35 -- cgit v1.2.3 From a1169c5a0bfec75730a080a5f5d668e65144d1d1 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 7 May 2010 15:38:55 +0100 Subject: staging: iio: Break up gyro.h and move to new abi Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/inclinometer.h | 23 +++++++++++++++++ drivers/staging/iio/gyro/gyro.h | 43 +++---------------------------- drivers/staging/iio/imu/adis16300_core.c | 11 ++++---- drivers/staging/iio/imu/adis16400_core.c | 16 ++++++------ drivers/staging/iio/magnetometer/magnet.h | 12 ++++----- 5 files changed, 47 insertions(+), 58 deletions(-) create mode 100644 drivers/staging/iio/accel/inclinometer.h (limited to 'drivers') diff --git a/drivers/staging/iio/accel/inclinometer.h b/drivers/staging/iio/accel/inclinometer.h new file mode 100644 index 000000000000..5b49f835eac5 --- /dev/null +++ b/drivers/staging/iio/accel/inclinometer.h @@ -0,0 +1,23 @@ +/* + * Inclinometer related attributes + */ +#include "../sysfs.h" + +#define IIO_DEV_ATTR_INCLI_X(_show, _addr) \ + IIO_DEVICE_ATTR(incli_x_raw, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_INCLI_Y(_show, _addr) \ + IIO_DEVICE_ATTR(incli_y_raw, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_INCLI_Z(_show, _addr) \ + IIO_DEVICE_ATTR(incli_z_raw, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_INCLI_X_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(incli_x_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_INCLI_Y_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(incli_y_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_INCLI_Z_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(incli_z_offset, _mode, _show, _store, _addr) + diff --git a/drivers/staging/iio/gyro/gyro.h b/drivers/staging/iio/gyro/gyro.h index 7c4dcf2f4a6a..16f6ffa039bb 100644 --- a/drivers/staging/iio/gyro/gyro.h +++ b/drivers/staging/iio/gyro/gyro.h @@ -28,49 +28,14 @@ IIO_DEVICE_ATTR(gyro_scale, S_IRUGO, _show, _store, _addr) #define IIO_DEV_ATTR_GYRO(_show, _addr) \ - IIO_DEVICE_ATTR(gyro, S_IRUGO, _show, NULL, _addr) + IIO_DEVICE_ATTR(gyro_raw, S_IRUGO, _show, NULL, _addr) #define IIO_DEV_ATTR_GYRO_X(_show, _addr) \ - IIO_DEVICE_ATTR(gyro_x, S_IRUGO, _show, NULL, _addr) + IIO_DEVICE_ATTR(gyro_x_raw, S_IRUGO, _show, NULL, _addr) #define IIO_DEV_ATTR_GYRO_Y(_show, _addr) \ - IIO_DEVICE_ATTR(gyro_y, S_IRUGO, _show, NULL, _addr) + IIO_DEVICE_ATTR(gyro_y_raw, S_IRUGO, _show, NULL, _addr) #define IIO_DEV_ATTR_GYRO_Z(_show, _addr) \ - IIO_DEVICE_ATTR(gyro_z, S_IRUGO, _show, NULL, _addr) + IIO_DEVICE_ATTR(gyro_z_raw, S_IRUGO, _show, NULL, _addr) -#define IIO_DEV_ATTR_TEMP_X(_show, _addr) \ - IIO_DEVICE_ATTR(temp_x, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_TEMP_Y(_show, _addr) \ - IIO_DEVICE_ATTR(temp_y, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_TEMP_Z(_show, _addr) \ - IIO_DEVICE_ATTR(temp_z, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_INCLI_X(_show, _addr) \ - IIO_DEVICE_ATTR(incli_x, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_INCLI_Y(_show, _addr) \ - IIO_DEVICE_ATTR(incli_y, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_INCLI_Z(_show, _addr) \ - IIO_DEVICE_ATTR(incli_z, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_INCLI_X_OFFSET(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(incli_x_offset, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_INCLI_Y_OFFSET(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(incli_y_offset, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_INCLI_Z_OFFSET(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(incli_z_offset, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_ROT(_show, _addr) \ - IIO_DEVICE_ATTR(rot, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_ROT_OFFSET(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(rot_offset, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_ANGL(_show, _addr) \ - IIO_DEVICE_ATTR(angl, S_IRUGO, _show, NULL, _addr) diff --git a/drivers/staging/iio/imu/adis16300_core.c b/drivers/staging/iio/imu/adis16300_core.c index 9f5f8cb850dd..b923eccf7bb7 100644 --- a/drivers/staging/iio/imu/adis16300_core.c +++ b/drivers/staging/iio/imu/adis16300_core.c @@ -21,6 +21,7 @@ #include "../iio.h" #include "../sysfs.h" #include "../accel/accel.h" +#include "../accel/inclinometer.h" #include "../gyro/gyro.h" #include "../adc/adc.h" @@ -613,7 +614,7 @@ static IIO_DEV_ATTR_INCLI_Y(adis16300_read_13bit_signed, ADIS16300_YINCLI_OUT); static IIO_CONST_ATTR(incli_scale, "0.044 d"); -static IIO_DEV_ATTR_TEMP(adis16300_read_12bit_signed); +static IIO_DEV_ATTR_TEMP_RAW(adis16300_read_12bit_signed); static IIO_CONST_ATTR(temp_offset, "198.16 K"); static IIO_CONST_ATTR(temp_scale, "0.14 K"); @@ -645,16 +646,16 @@ static struct attribute *adis16300_attributes[] = { &iio_dev_attr_accel_z_offset.dev_attr.attr, &iio_dev_attr_in_supply_raw.dev_attr.attr, &iio_const_attr_in_supply_scale.dev_attr.attr, - &iio_dev_attr_gyro_x.dev_attr.attr, + &iio_dev_attr_gyro_x_raw.dev_attr.attr, &iio_const_attr_gyro_scale.dev_attr.attr, &iio_dev_attr_accel_x_raw.dev_attr.attr, &iio_dev_attr_accel_y_raw.dev_attr.attr, &iio_dev_attr_accel_z_raw.dev_attr.attr, &iio_const_attr_accel_scale.dev_attr.attr, - &iio_dev_attr_incli_x.dev_attr.attr, - &iio_dev_attr_incli_y.dev_attr.attr, + &iio_dev_attr_incli_x_raw.dev_attr.attr, + &iio_dev_attr_incli_y_raw.dev_attr.attr, &iio_const_attr_incli_scale.dev_attr.attr, - &iio_dev_attr_temp.dev_attr.attr, + &iio_dev_attr_temp_raw.dev_attr.attr, &iio_const_attr_temp_offset.dev_attr.attr, &iio_const_attr_temp_scale.dev_attr.attr, &iio_dev_attr_in0_raw.dev_attr.attr, diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index 27e4a7348075..868c52658a5a 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -626,7 +626,7 @@ static IIO_DEV_ATTR_MAGN_Z(adis16400_read_14bit_signed, static IIO_CONST_ATTR(magn_scale, "0.0005 Gs"); -static IIO_DEV_ATTR_TEMP(adis16400_read_12bit_signed); +static IIO_DEV_ATTR_TEMP_RAW(adis16400_read_12bit_signed); static IIO_CONST_ATTR(temp_offset, "198.16 K"); static IIO_CONST_ATTR(temp_scale, "0.14 K"); @@ -658,19 +658,19 @@ static struct attribute *adis16400_attributes[] = { &iio_dev_attr_accel_z_offset.dev_attr.attr, &iio_dev_attr_in_supply_raw.dev_attr.attr, &iio_const_attr_in_supply_scale.dev_attr.attr, - &iio_dev_attr_gyro_x.dev_attr.attr, - &iio_dev_attr_gyro_y.dev_attr.attr, - &iio_dev_attr_gyro_z.dev_attr.attr, + &iio_dev_attr_gyro_x_raw.dev_attr.attr, + &iio_dev_attr_gyro_y_raw.dev_attr.attr, + &iio_dev_attr_gyro_z_raw.dev_attr.attr, &iio_const_attr_gyro_scale.dev_attr.attr, &iio_dev_attr_accel_x_raw.dev_attr.attr, &iio_dev_attr_accel_y_raw.dev_attr.attr, &iio_dev_attr_accel_z_raw.dev_attr.attr, &iio_const_attr_accel_scale.dev_attr.attr, - &iio_dev_attr_magn_x.dev_attr.attr, - &iio_dev_attr_magn_y.dev_attr.attr, - &iio_dev_attr_magn_z.dev_attr.attr, + &iio_dev_attr_magn_x_raw.dev_attr.attr, + &iio_dev_attr_magn_y_raw.dev_attr.attr, + &iio_dev_attr_magn_z_raw.dev_attr.attr, &iio_const_attr_magn_scale.dev_attr.attr, - &iio_dev_attr_temp.dev_attr.attr, + &iio_dev_attr_temp_raw.dev_attr.attr, &iio_const_attr_temp_offset.dev_attr.attr, &iio_const_attr_temp_scale.dev_attr.attr, &iio_dev_attr_in0_raw.dev_attr.attr, diff --git a/drivers/staging/iio/magnetometer/magnet.h b/drivers/staging/iio/magnetometer/magnet.h index 6f6c6ed91fa7..64338301f8df 100644 --- a/drivers/staging/iio/magnetometer/magnet.h +++ b/drivers/staging/iio/magnetometer/magnet.h @@ -21,11 +21,11 @@ #define IIO_DEV_ATTR_MAGN_Z_GAIN(_mode, _show, _store, _addr) \ IIO_DEVICE_ATTR(magn_z_gain, _mode, _show, _store, _addr) -#define IIO_DEV_ATTR_MAGN_X(_show, _addr) \ - IIO_DEVICE_ATTR(magn_x, S_IRUGO, _show, NULL, _addr) +#define IIO_DEV_ATTR_MAGN_X(_show, _addr) \ + IIO_DEVICE_ATTR(magn_x_raw, S_IRUGO, _show, NULL, _addr) -#define IIO_DEV_ATTR_MAGN_Y(_show, _addr) \ - IIO_DEVICE_ATTR(magn_y, S_IRUGO, _show, NULL, _addr) +#define IIO_DEV_ATTR_MAGN_Y(_show, _addr) \ + IIO_DEVICE_ATTR(magn_y_raw, S_IRUGO, _show, NULL, _addr) -#define IIO_DEV_ATTR_MAGN_Z(_show, _addr) \ - IIO_DEVICE_ATTR(magn_z, S_IRUGO, _show, NULL, _addr) +#define IIO_DEV_ATTR_MAGN_Z(_show, _addr) \ + IIO_DEVICE_ATTR(magn_z_raw, S_IRUGO, _show, NULL, _addr) -- cgit v1.2.3 From 4da54d93abe7bdad6880e27270ad50b6303898b6 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 7 May 2010 15:38:56 +0100 Subject: staging: iio: adis16300 clean out some unused code Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/imu/adis16300.h | 9 ---- drivers/staging/iio/imu/adis16300_core.c | 70 +------------------------------- 2 files changed, 2 insertions(+), 77 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/imu/adis16300.h b/drivers/staging/iio/imu/adis16300.h index 77d890d12000..1c7ea5c840ef 100644 --- a/drivers/staging/iio/imu/adis16300.h +++ b/drivers/staging/iio/imu/adis16300.h @@ -115,21 +115,12 @@ struct adis16300_state { struct mutex buf_lock; }; -int adis16300_spi_write_reg_8(struct device *dev, - u8 reg_address, - u8 val); - int adis16300_spi_read_burst(struct device *dev, u8 *rx); -int adis16300_spi_read_sequence(struct device *dev, - u8 *tx, u8 *rx, int num); - int adis16300_set_irq(struct device *dev, bool enable); int adis16300_reset(struct device *dev); -int adis16300_stop_device(struct device *dev); - int adis16300_check_status(struct device *dev); #ifdef CONFIG_IIO_RING_BUFFER diff --git a/drivers/staging/iio/imu/adis16300_core.c b/drivers/staging/iio/imu/adis16300_core.c index b923eccf7bb7..5a7e5ef9bc5d 100644 --- a/drivers/staging/iio/imu/adis16300_core.c +++ b/drivers/staging/iio/imu/adis16300_core.c @@ -40,7 +40,7 @@ * @reg_address: the address of the register to be written * @val: the value to write **/ -int adis16300_spi_write_reg_8(struct device *dev, +static int adis16300_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val) { @@ -202,55 +202,6 @@ int adis16300_spi_read_burst(struct device *dev, u8 *rx) return ret; } -/** - * adis16300_spi_read_sequence() - read a sequence of 16-bit registers - * @dev: device associated with child of actual device (iio_dev or iio_trig) - * @tx: register addresses in bytes 0,2,4,6... (min size is 2*num bytes) - * @rx: somewhere to pass back the value read (min size is 2*num bytes) - **/ -int adis16300_spi_read_sequence(struct device *dev, - u8 *tx, u8 *rx, int num) -{ - struct spi_message msg; - struct spi_transfer *xfers; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16300_state *st = iio_dev_get_devdata(indio_dev); - int ret, i; - - xfers = kzalloc(num + 1, GFP_KERNEL); - if (xfers == NULL) { - dev_err(&st->us->dev, "memory alloc failed"); - ret = -ENOMEM; - goto error_ret; - } - - /* tx: |add1|addr2|addr3|...|addrN |zero| - * rx: |zero|res1 |res2 |...|resN-1|resN| */ - spi_message_init(&msg); - for (i = 0; i < num + 1; i++) { - if (i > 0) - xfers[i].rx_buf = st->rx + 2*(i - 1); - if (i < num) - xfers[i].tx_buf = st->tx + 2*i; - xfers[i].bits_per_word = 8; - xfers[i].len = 2; - xfers[i].cs_change = 1; - spi_message_add_tail(&xfers[i], &msg); - } - - mutex_lock(&st->buf_lock); - - ret = spi_sync(st->us, &msg); - if (ret) - dev_err(&st->us->dev, "problem when reading sequence"); - - mutex_unlock(&st->buf_lock); - kfree(xfers); - -error_ret: - return ret; -} - static ssize_t adis16300_spi_read_signed(struct device *dev, struct device_attribute *attr, char *buf, @@ -458,7 +409,7 @@ int adis16300_reset(struct device *dev) } /* Power down the device */ -int adis16300_stop_device(struct device *dev) +static int adis16300_stop_device(struct device *dev) { int ret; u16 val = ADIS16300_SLP_CNT_POWER_OFF; @@ -470,23 +421,6 @@ int adis16300_stop_device(struct device *dev) return ret; } -int adis16300_self_test(struct device *dev) -{ - int ret; - ret = adis16300_spi_write_reg_16(dev, - ADIS16300_MSC_CTRL, - ADIS16300_MSC_CTRL_MEM_TEST); - if (ret) { - dev_err(dev, "problem starting self test"); - goto err_ret; - } - - adis16300_check_status(dev); - -err_ret: - return ret; -} - int adis16300_check_status(struct device *dev) { u16 status; -- cgit v1.2.3 From e5107fb87018c8fc6b7376c4669dc877ab65db47 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 7 May 2010 15:38:57 +0100 Subject: staging: iio: Documentation update to add incli and switch to magn Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/sysfs-class-iio | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/Documentation/sysfs-class-iio b/drivers/staging/iio/Documentation/sysfs-class-iio index ff19f6e22e34..714b4c57c82a 100644 --- a/drivers/staging/iio/Documentation/sysfs-class-iio +++ b/drivers/staging/iio/Documentation/sysfs-class-iio @@ -143,7 +143,16 @@ Description: Data converted by application of offset then scale to radians per second. Has all the equivalent parameters as per in[m]. -What: /sys/.../device[n]/mag[_x|_y|_z][m]_raw +What: /sys/.../device[n]/incli[_x|_y|_z][m]_raw +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Inclination raw reading about axis x, y or z (may be arbitarily + assigned) channel m (not present if only one inclinometer at + this orientation). Data converted by application of offset + and scale to Degrees. + +What: /sys/.../device[n]/magn[_x|_y|_z][m]_raw KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: -- cgit v1.2.3 From b155498b1842090f2cf5164908deaa0762a9a8b1 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 7 May 2010 15:38:58 +0100 Subject: staging: iio: adis16400 clean out some unused code Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/imu/adis16400.h | 9 ------ drivers/staging/iio/imu/adis16400_core.c | 55 ++------------------------------ 2 files changed, 3 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h index a8062f605797..5a69a7ab91ce 100644 --- a/drivers/staging/iio/imu/adis16400.h +++ b/drivers/staging/iio/imu/adis16400.h @@ -147,21 +147,12 @@ struct adis16400_state { struct mutex buf_lock; }; -int adis16400_spi_write_reg_8(struct device *dev, - u8 reg_address, - u8 val); - int adis16400_spi_read_burst(struct device *dev, u8 *rx); -int adis16400_spi_read_sequence(struct device *dev, - u8 *tx, u8 *rx, int num); - int adis16400_set_irq(struct device *dev, bool enable); int adis16400_reset(struct device *dev); -int adis16400_stop_device(struct device *dev); - int adis16400_check_status(struct device *dev); #ifdef CONFIG_IIO_RING_BUFFER diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index 868c52658a5a..e69e2ce47da3 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -47,7 +47,7 @@ * @reg_address: the address of the register to be written * @val: the value to write **/ -int adis16400_spi_write_reg_8(struct device *dev, +static int adis16400_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val) { @@ -209,55 +209,6 @@ int adis16400_spi_read_burst(struct device *dev, u8 *rx) return ret; } -/** - * adis16400_spi_read_sequence() - read a sequence of 16-bit registers - * @dev: device associated with child of actual device (iio_dev or iio_trig) - * @tx: register addresses in bytes 0,2,4,6... (min size is 2*num bytes) - * @rx: somewhere to pass back the value read (min size is 2*num bytes) - **/ -int adis16400_spi_read_sequence(struct device *dev, - u8 *tx, u8 *rx, int num) -{ - struct spi_message msg; - struct spi_transfer *xfers; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16400_state *st = iio_dev_get_devdata(indio_dev); - int ret, i; - - xfers = kzalloc(num + 1, GFP_KERNEL); - if (xfers == NULL) { - dev_err(&st->us->dev, "memory alloc failed"); - ret = -ENOMEM; - goto error_ret; - } - - /* tx: |add1|addr2|addr3|...|addrN |zero| - * rx: |zero|res1 |res2 |...|resN-1|resN| */ - spi_message_init(&msg); - for (i = 0; i < num + 1; i++) { - if (i > 0) - xfers[i].rx_buf = st->rx + 2*(i - 1); - if (i < num) - xfers[i].tx_buf = st->tx + 2*i; - xfers[i].bits_per_word = 8; - xfers[i].len = 2; - xfers[i].cs_change = 1; - spi_message_add_tail(&xfers[i], &msg); - } - - mutex_lock(&st->buf_lock); - - ret = spi_sync(st->us, &msg); - if (ret) - dev_err(&st->us->dev, "problem when reading sequence"); - - mutex_unlock(&st->buf_lock); - kfree(xfers); - -error_ret: - return ret; -} - static ssize_t adis16400_spi_read_signed(struct device *dev, struct device_attribute *attr, char *buf, @@ -450,7 +401,7 @@ int adis16400_reset(struct device *dev) } /* Power down the device */ -int adis16400_stop_device(struct device *dev) +static int adis16400_stop_device(struct device *dev) { int ret; u16 val = ADIS16400_SLP_CNT_POWER_OFF; @@ -462,7 +413,7 @@ int adis16400_stop_device(struct device *dev) return ret; } -int adis16400_self_test(struct device *dev) +static int adis16400_self_test(struct device *dev) { int ret; ret = adis16400_spi_write_reg_16(dev, -- cgit v1.2.3 From 671ece14bc58a88dea76b11c5745a09c33934663 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Fri, 7 May 2010 15:38:59 +0100 Subject: staging: iio: adis16209 driver Signed-off-by: Barry Song Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/Kconfig | 9 + drivers/staging/iio/accel/Makefile | 4 + drivers/staging/iio/accel/adis16209.h | 193 ++++++++ drivers/staging/iio/accel/adis16209_core.c | 615 ++++++++++++++++++++++++++ drivers/staging/iio/accel/adis16209_ring.c | 266 +++++++++++ drivers/staging/iio/accel/adis16209_trigger.c | 124 ++++++ 6 files changed, 1211 insertions(+) create mode 100644 drivers/staging/iio/accel/adis16209.h create mode 100644 drivers/staging/iio/accel/adis16209_core.c create mode 100644 drivers/staging/iio/accel/adis16209_ring.c create mode 100644 drivers/staging/iio/accel/adis16209_trigger.c (limited to 'drivers') diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig index 3d3c3339dbc7..1d89e2153dd2 100644 --- a/drivers/staging/iio/accel/Kconfig +++ b/drivers/staging/iio/accel/Kconfig @@ -3,6 +3,15 @@ # comment "Accelerometers" +config ADIS16209 + tristate "Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer" + depends on SPI + select IIO_TRIGGER if IIO_RING_BUFFER + select IIO_SW_RING if IIO_RING_BUFFER + help + Say yes here to build support for Analog Devices adis16209 dual-axis digital inclinometer + and accelerometer. + config KXSD9 tristate "Kionix KXSD9 Accelerometer Driver" depends on SPI diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile index d5335f9094ad..f8f2124720e7 100644 --- a/drivers/staging/iio/accel/Makefile +++ b/drivers/staging/iio/accel/Makefile @@ -1,6 +1,10 @@ # # Makefile for industrial I/O accelerometer drivers # +adis16209-y := adis16209_core.o +adis16209-$(CONFIG_IIO_RING_BUFFER) += adis16209_ring.o adis16209_trigger.o +obj-$(CONFIG_ADIS16209) += adis16209.o + obj-$(CONFIG_KXSD9) += kxsd9.o lis3l02dq-y := lis3l02dq_core.o diff --git a/drivers/staging/iio/accel/adis16209.h b/drivers/staging/iio/accel/adis16209.h new file mode 100644 index 000000000000..877fd2a48380 --- /dev/null +++ b/drivers/staging/iio/accel/adis16209.h @@ -0,0 +1,193 @@ +#ifndef SPI_ADIS16209_H_ +#define SPI_ADIS16209_H_ + +#define ADIS16209_STARTUP_DELAY 220 /* ms */ + +#define ADIS16209_READ_REG(a) a +#define ADIS16209_WRITE_REG(a) ((a) | 0x80) + +/* Flash memory write count */ +#define ADIS16209_FLASH_CNT 0x00 +/* Output, power supply */ +#define ADIS16209_SUPPLY_OUT 0x02 +/* Output, x-axis accelerometer */ +#define ADIS16209_XACCL_OUT 0x04 +/* Output, y-axis accelerometer */ +#define ADIS16209_YACCL_OUT 0x06 +/* Output, auxiliary ADC input */ +#define ADIS16209_AUX_ADC 0x08 +/* Output, temperature */ +#define ADIS16209_TEMP_OUT 0x0A +/* Output, x-axis inclination */ +#define ADIS16209_XINCL_OUT 0x0C +/* Output, y-axis inclination */ +#define ADIS16209_YINCL_OUT 0x0E +/* Output, +/-180 vertical rotational position */ +#define ADIS16209_ROT_OUT 0x10 +/* Calibration, x-axis acceleration offset null */ +#define ADIS16209_XACCL_NULL 0x12 +/* Calibration, y-axis acceleration offset null */ +#define ADIS16209_YACCL_NULL 0x14 +/* Calibration, x-axis inclination offset null */ +#define ADIS16209_XINCL_NULL 0x16 +/* Calibration, y-axis inclination offset null */ +#define ADIS16209_YINCL_NULL 0x18 +/* Calibration, vertical rotation offset null */ +#define ADIS16209_ROT_NULL 0x1A +/* Alarm 1 amplitude threshold */ +#define ADIS16209_ALM_MAG1 0x20 +/* Alarm 2 amplitude threshold */ +#define ADIS16209_ALM_MAG2 0x22 +/* Alarm 1, sample period */ +#define ADIS16209_ALM_SMPL1 0x24 +/* Alarm 2, sample period */ +#define ADIS16209_ALM_SMPL2 0x26 +/* Alarm control */ +#define ADIS16209_ALM_CTRL 0x28 +/* Auxiliary DAC data */ +#define ADIS16209_AUX_DAC 0x30 +/* General-purpose digital input/output control */ +#define ADIS16209_GPIO_CTRL 0x32 +/* Miscellaneous control */ +#define ADIS16209_MSC_CTRL 0x34 +/* Internal sample period (rate) control */ +#define ADIS16209_SMPL_PRD 0x36 +/* Operation, filter configuration */ +#define ADIS16209_AVG_CNT 0x38 +/* Operation, sleep mode control */ +#define ADIS16209_SLP_CNT 0x3A +/* Diagnostics, system status register */ +#define ADIS16209_DIAG_STAT 0x3C +/* Operation, system command register */ +#define ADIS16209_GLOB_CMD 0x3E + +#define ADIS16209_OUTPUTS 8 + +/* MSC_CTRL */ +/* Self-test at power-on: 1 = disabled, 0 = enabled */ +#define ADIS16209_MSC_CTRL_PWRUP_SELF_TEST (1 << 10) +/* Self-test enable */ +#define ADIS16209_MSC_CTRL_SELF_TEST_EN (1 << 8) +/* Data-ready enable: 1 = enabled, 0 = disabled */ +#define ADIS16209_MSC_CTRL_DATA_RDY_EN (1 << 2) +/* Data-ready polarity: 1 = active high, 0 = active low */ +#define ADIS16209_MSC_CTRL_ACTIVE_HIGH (1 << 1) +/* Data-ready line selection: 1 = DIO2, 0 = DIO1 */ +#define ADIS16209_MSC_CTRL_DATA_RDY_DIO2 (1 << 0) + +/* DIAG_STAT */ +/* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ +#define ADIS16209_DIAG_STAT_ALARM2 (1<<9) +/* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ +#define ADIS16209_DIAG_STAT_ALARM1 (1<<8) +/* Self-test diagnostic error flag: 1 = error condition, 0 = normal operation */ +#define ADIS16209_DIAG_STAT_SELFTEST_FAIL (1<<5) +/* SPI communications failure */ +#define ADIS16209_DIAG_STAT_SPI_FAIL (1<<3) +/* Flash update failure */ +#define ADIS16209_DIAG_STAT_FLASH_UPT (1<<2) +/* Power supply above 3.625 V */ +#define ADIS16209_DIAG_STAT_POWER_HIGH (1<<1) +/* Power supply below 3.15 V */ +#define ADIS16209_DIAG_STAT_POWER_LOW (1<<0) + +/* GLOB_CMD */ +#define ADIS16209_GLOB_CMD_SW_RESET (1<<7) +#define ADIS16209_GLOB_CMD_CLEAR_STAT (1<<4) +#define ADIS16209_GLOB_CMD_FACTORY_CAL (1<<1) + +#define ADIS16209_MAX_TX 24 +#define ADIS16209_MAX_RX 24 + +#define ADIS16209_ERROR_ACTIVE (1<<14) + +/** + * struct adis16209_state - device instance specific data + * @us: actual spi_device + * @work_trigger_to_ring: bh for triggered event handling + * @work_cont_thresh: CLEAN + * @inter: used to check if new interrupt has been triggered + * @last_timestamp: passing timestamp from th to bh of interrupt handler + * @indio_dev: industrial I/O device structure + * @trig: data ready trigger registered with iio + * @tx: transmit buffer + * @rx: recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct adis16209_state { + struct spi_device *us; + struct work_struct work_trigger_to_ring; + struct iio_work_cont work_cont_thresh; + s64 last_timestamp; + struct iio_dev *indio_dev; + struct iio_trigger *trig; + u8 *tx; + u8 *rx; + struct mutex buf_lock; +}; + +int adis16209_set_irq(struct device *dev, bool enable); + +#ifdef CONFIG_IIO_RING_BUFFER +enum adis16209_scan { + ADIS16209_SCAN_SUPPLY, + ADIS16209_SCAN_ACC_X, + ADIS16209_SCAN_ACC_Y, + ADIS16209_SCAN_AUX_ADC, + ADIS16209_SCAN_TEMP, + ADIS16209_SCAN_INCLI_X, + ADIS16209_SCAN_INCLI_Y, + ADIS16209_SCAN_ROT, +}; + +void adis16209_remove_trigger(struct iio_dev *indio_dev); +int adis16209_probe_trigger(struct iio_dev *indio_dev); + +ssize_t adis16209_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf); + +int adis16209_configure_ring(struct iio_dev *indio_dev); +void adis16209_unconfigure_ring(struct iio_dev *indio_dev); + +int adis16209_initialize_ring(struct iio_ring_buffer *ring); +void adis16209_uninitialize_ring(struct iio_ring_buffer *ring); +#else /* CONFIG_IIO_RING_BUFFER */ + +static inline void adis16209_remove_trigger(struct iio_dev *indio_dev) +{ +} + +static inline int adis16209_probe_trigger(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline ssize_t +adis16209_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static int adis16209_configure_ring(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline void adis16209_unconfigure_ring(struct iio_dev *indio_dev) +{ +} + +static inline int adis16209_initialize_ring(struct iio_ring_buffer *ring) +{ + return 0; +} + +static inline void adis16209_uninitialize_ring(struct iio_ring_buffer *ring) +{ +} + +#endif /* CONFIG_IIO_RING_BUFFER */ +#endif /* SPI_ADIS16209_H_ */ diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c new file mode 100644 index 000000000000..ac375c50f56f --- /dev/null +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -0,0 +1,615 @@ +/* + * ADIS16209 Programmable Digital Vibration Sensor driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "accel.h" +#include "inclinometer.h" +#include "../gyro/gyro.h" +#include "../adc/adc.h" + +#include "adis16209.h" + +#define DRIVER_NAME "adis16209" + +static int adis16209_check_status(struct device *dev); + +/** + * adis16209_spi_write_reg_8() - write single byte to a register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the register to be written + * @val: the value to write + **/ +static int adis16209_spi_write_reg_8(struct device *dev, + u8 reg_address, + u8 val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16209_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16209_WRITE_REG(reg_address); + st->tx[1] = val; + + ret = spi_write(st->us, st->tx, 2); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16209_spi_write_reg_16() - write 2 bytes to a pair of registers + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: value to be written + **/ +static int adis16209_spi_write_reg_16(struct device *dev, + u8 lower_reg_address, + u16 value) +{ + int ret; + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16209_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + }, { + .tx_buf = st->tx + 2, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16209_WRITE_REG(lower_reg_address); + st->tx[1] = value & 0xFF; + st->tx[2] = ADIS16209_WRITE_REG(lower_reg_address + 1); + st->tx[3] = (value >> 8) & 0xFF; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16209_spi_read_reg_16() - read 2 bytes from a 16-bit register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: somewhere to pass back the value read + **/ +static int adis16209_spi_read_reg_16(struct device *dev, + u8 lower_reg_address, + u16 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16209_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 20, + }, { + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 20, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16209_READ_REG(lower_reg_address); + st->tx[1] = 0; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, + "problem when reading 16 bit register 0x%02X", + lower_reg_address); + goto error_ret; + } + *val = (st->rx[0] << 8) | st->rx[1]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static ssize_t adis16209_read_12bit_unsigned(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u16 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = adis16209_spi_read_reg_16(dev, this_attr->address, &val); + if (ret) + return ret; + + if (val & ADIS16209_ERROR_ACTIVE) + adis16209_check_status(dev); + + return sprintf(buf, "%u\n", val & 0x0FFF); +} + +static ssize_t adis16209_read_14bit_unsigned(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u16 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = adis16209_spi_read_reg_16(dev, this_attr->address, &val); + if (ret) + return ret; + + if (val & ADIS16209_ERROR_ACTIVE) + adis16209_check_status(dev); + + return sprintf(buf, "%u\n", val & 0x3FFF); +} + +static ssize_t adis16209_read_temp(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + ssize_t ret; + u16 val; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + + ret = adis16209_spi_read_reg_16(dev, ADIS16209_TEMP_OUT, (u16 *)&val); + if (ret) + goto error_ret; + + if (val & ADIS16209_ERROR_ACTIVE) + adis16209_check_status(dev); + + val &= 0xFFF; + ret = sprintf(buf, "%d\n", val); + +error_ret: + mutex_unlock(&indio_dev->mlock); + return ret; +} + +static ssize_t adis16209_read_14bit_signed(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + s16 val = 0; + ssize_t ret; + + mutex_lock(&indio_dev->mlock); + + ret = adis16209_spi_read_reg_16(dev, this_attr->address, (u16 *)&val); + if (!ret) { + if (val & ADIS16209_ERROR_ACTIVE) + adis16209_check_status(dev); + + val = ((s16)(val << 2) >> 2); + ret = sprintf(buf, "%d\n", val); + } + + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t adis16209_write_16bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = adis16209_spi_write_reg_16(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static int adis16209_reset(struct device *dev) +{ + int ret; + ret = adis16209_spi_write_reg_8(dev, + ADIS16209_GLOB_CMD, + ADIS16209_GLOB_CMD_SW_RESET); + if (ret) + dev_err(dev, "problem resetting device"); + + return ret; +} + +static ssize_t adis16209_write_reset(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + if (len < 1) + return -EINVAL; + switch (buf[0]) { + case '1': + case 'y': + case 'Y': + return adis16209_reset(dev); + } + return -EINVAL; +} + +int adis16209_set_irq(struct device *dev, bool enable) +{ + int ret = 0; + u16 msc; + + ret = adis16209_spi_read_reg_16(dev, ADIS16209_MSC_CTRL, &msc); + if (ret) + goto error_ret; + + msc |= ADIS16209_MSC_CTRL_ACTIVE_HIGH; + msc &= ~ADIS16209_MSC_CTRL_DATA_RDY_DIO2; + if (enable) + msc |= ADIS16209_MSC_CTRL_DATA_RDY_EN; + else + msc &= ~ADIS16209_MSC_CTRL_DATA_RDY_EN; + + ret = adis16209_spi_write_reg_16(dev, ADIS16209_MSC_CTRL, msc); + +error_ret: + return ret; +} + +static int adis16209_check_status(struct device *dev) +{ + u16 status; + int ret; + + ret = adis16209_spi_read_reg_16(dev, ADIS16209_DIAG_STAT, &status); + if (ret < 0) { + dev_err(dev, "Reading status failed\n"); + goto error_ret; + } + ret = status & 0x1F; + + if (status & ADIS16209_DIAG_STAT_SELFTEST_FAIL) + dev_err(dev, "Self test failure\n"); + if (status & ADIS16209_DIAG_STAT_SPI_FAIL) + dev_err(dev, "SPI failure\n"); + if (status & ADIS16209_DIAG_STAT_FLASH_UPT) + dev_err(dev, "Flash update failed\n"); + if (status & ADIS16209_DIAG_STAT_POWER_HIGH) + dev_err(dev, "Power supply above 3.625V\n"); + if (status & ADIS16209_DIAG_STAT_POWER_LOW) + dev_err(dev, "Power supply below 3.15V\n"); + +error_ret: + return ret; +} + +static int adis16209_self_test(struct device *dev) +{ + int ret; + ret = adis16209_spi_write_reg_16(dev, + ADIS16209_MSC_CTRL, + ADIS16209_MSC_CTRL_SELF_TEST_EN); + if (ret) { + dev_err(dev, "problem starting self test"); + goto err_ret; + } + + adis16209_check_status(dev); + +err_ret: + return ret; +} + +static int adis16209_initial_setup(struct adis16209_state *st) +{ + int ret; + struct device *dev = &st->indio_dev->dev; + + /* Disable IRQ */ + ret = adis16209_set_irq(dev, false); + if (ret) { + dev_err(dev, "disable irq failed"); + goto err_ret; + } + + /* Do self test */ + ret = adis16209_self_test(dev); + if (ret) { + dev_err(dev, "self test failure"); + goto err_ret; + } + + /* Read status register to check the result */ + ret = adis16209_check_status(dev); + if (ret) { + adis16209_reset(dev); + dev_err(dev, "device not playing ball -> reset"); + msleep(ADIS16209_STARTUP_DELAY); + ret = adis16209_check_status(dev); + if (ret) { + dev_err(dev, "giving up"); + goto err_ret; + } + } + + printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n", + st->us->chip_select, st->us->irq); + +err_ret: + return ret; +} + +static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16209_read_14bit_unsigned, + ADIS16209_SUPPLY_OUT); +static IIO_CONST_ATTR(in_supply_scale, "0.30518"); +static IIO_DEV_ATTR_IN_RAW(0, adis16209_read_12bit_unsigned, + ADIS16209_AUX_ADC); +static IIO_CONST_ATTR(in0_scale, "0.6105"); + +static IIO_DEV_ATTR_ACCEL_X(adis16209_read_14bit_signed, + ADIS16209_XACCL_OUT); +static IIO_DEV_ATTR_ACCEL_Y(adis16209_read_14bit_signed, + ADIS16209_YACCL_OUT); +static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO, + adis16209_read_14bit_signed, + adis16209_write_16bit, + ADIS16209_XACCL_NULL); +static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO, + adis16209_read_14bit_signed, + adis16209_write_16bit, + ADIS16209_YACCL_NULL); +static IIO_CONST_ATTR(accel_scale, "0.24414"); + +static IIO_DEV_ATTR_INCLI_X(adis16209_read_14bit_signed, + ADIS16209_XINCL_OUT); +static IIO_DEV_ATTR_INCLI_Y(adis16209_read_14bit_signed, + ADIS16209_YINCL_OUT); +static IIO_DEV_ATTR_INCLI_X_OFFSET(S_IWUSR | S_IRUGO, + adis16209_read_14bit_signed, + adis16209_write_16bit, + ADIS16209_XACCL_NULL); +static IIO_DEV_ATTR_INCLI_Y_OFFSET(S_IWUSR | S_IRUGO, + adis16209_read_14bit_signed, + adis16209_write_16bit, + ADIS16209_YACCL_NULL); +static IIO_CONST_ATTR(incli_scale, "0.025"); + +static IIO_DEVICE_ATTR(rot_raw, S_IRUGO, adis16209_read_14bit_signed, + NULL, ADIS16209_ROT_OUT); + +static IIO_DEV_ATTR_TEMP(adis16209_read_temp); +static IIO_CONST_ATTR(temp_offset, "25"); +static IIO_CONST_ATTR(temp_scale, "-0.47"); + +static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16209_write_reset, 0); + +static IIO_CONST_ATTR(name, "adis16209"); + +static struct attribute *adis16209_event_attributes[] = { + NULL +}; + +static struct attribute_group adis16209_event_attribute_group = { + .attrs = adis16209_event_attributes, +}; + +static struct attribute *adis16209_attributes[] = { + &iio_dev_attr_in_supply_raw.dev_attr.attr, + &iio_const_attr_in_supply_scale.dev_attr.attr, + &iio_dev_attr_temp.dev_attr.attr, + &iio_const_attr_temp_offset.dev_attr.attr, + &iio_const_attr_temp_scale.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_const_attr_name.dev_attr.attr, + &iio_dev_attr_in0_raw.dev_attr.attr, + &iio_const_attr_in0_scale.dev_attr.attr, + &iio_dev_attr_accel_x_raw.dev_attr.attr, + &iio_dev_attr_accel_y_raw.dev_attr.attr, + &iio_dev_attr_accel_x_offset.dev_attr.attr, + &iio_dev_attr_accel_y_offset.dev_attr.attr, + &iio_const_attr_accel_scale.dev_attr.attr, + &iio_dev_attr_incli_x_raw.dev_attr.attr, + &iio_dev_attr_incli_y_raw.dev_attr.attr, + &iio_dev_attr_incli_x_offset.dev_attr.attr, + &iio_dev_attr_incli_y_offset.dev_attr.attr, + &iio_const_attr_incli_scale.dev_attr.attr, + &iio_dev_attr_rot_raw.dev_attr.attr, + NULL +}; + +static const struct attribute_group adis16209_attribute_group = { + .attrs = adis16209_attributes, +}; + +static int __devinit adis16209_probe(struct spi_device *spi) +{ + int ret, regdone = 0; + struct adis16209_state *st = kzalloc(sizeof *st, GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + goto error_ret; + } + /* this is only used for removal purposes */ + spi_set_drvdata(spi, st); + + /* Allocate the comms buffers */ + st->rx = kzalloc(sizeof(*st->rx)*ADIS16209_MAX_RX, GFP_KERNEL); + if (st->rx == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->tx = kzalloc(sizeof(*st->tx)*ADIS16209_MAX_TX, GFP_KERNEL); + if (st->tx == NULL) { + ret = -ENOMEM; + goto error_free_rx; + } + st->us = spi; + mutex_init(&st->buf_lock); + /* setup the industrialio driver allocated elements */ + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_tx; + } + + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->num_interrupt_lines = 1; + st->indio_dev->event_attrs = &adis16209_event_attribute_group; + st->indio_dev->attrs = &adis16209_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = adis16209_configure_ring(st->indio_dev); + if (ret) + goto error_free_dev; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_unreg_ring_funcs; + regdone = 1; + + ret = adis16209_initialize_ring(st->indio_dev->ring); + if (ret) { + printk(KERN_ERR "failed to initialize the ring\n"); + goto error_unreg_ring_funcs; + } + + if (spi->irq) { + ret = iio_register_interrupt_line(spi->irq, + st->indio_dev, + 0, + IRQF_TRIGGER_RISING, + "adis16209"); + if (ret) + goto error_uninitialize_ring; + + ret = adis16209_probe_trigger(st->indio_dev); + if (ret) + goto error_unregister_line; + } + + /* Get the device into a sane initial state */ + ret = adis16209_initial_setup(st); + if (ret) + goto error_remove_trigger; + return 0; + +error_remove_trigger: + adis16209_remove_trigger(st->indio_dev); +error_unregister_line: + if (spi->irq) + iio_unregister_interrupt_line(st->indio_dev, 0); +error_uninitialize_ring: + adis16209_uninitialize_ring(st->indio_dev->ring); +error_unreg_ring_funcs: + adis16209_unconfigure_ring(st->indio_dev); +error_free_dev: + if (regdone) + iio_device_unregister(st->indio_dev); + else + iio_free_device(st->indio_dev); +error_free_tx: + kfree(st->tx); +error_free_rx: + kfree(st->rx); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +static int adis16209_remove(struct spi_device *spi) +{ + struct adis16209_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + + flush_scheduled_work(); + + adis16209_remove_trigger(indio_dev); + if (spi->irq) + iio_unregister_interrupt_line(indio_dev, 0); + + adis16209_uninitialize_ring(indio_dev->ring); + iio_device_unregister(indio_dev); + adis16209_unconfigure_ring(indio_dev); + kfree(st->tx); + kfree(st->rx); + kfree(st); + + return 0; +} + +static struct spi_driver adis16209_driver = { + .driver = { + .name = "adis16209", + .owner = THIS_MODULE, + }, + .probe = adis16209_probe, + .remove = __devexit_p(adis16209_remove), +}; + +static __init int adis16209_init(void) +{ + return spi_register_driver(&adis16209_driver); +} +module_init(adis16209_init); + +static __exit void adis16209_exit(void) +{ + spi_unregister_driver(&adis16209_driver); +} +module_exit(adis16209_exit); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADIS16209 Digital Vibration Sensor driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c new file mode 100644 index 000000000000..533e28574910 --- /dev/null +++ b/drivers/staging/iio/accel/adis16209_ring.c @@ -0,0 +1,266 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../ring_sw.h" +#include "accel.h" +#include "../trigger.h" +#include "adis16209.h" + +/** + * combine_8_to_16() utility function to munge to u8s into u16 + **/ +static inline u16 combine_8_to_16(u8 lower, u8 upper) +{ + u16 _lower = lower; + u16 _upper = upper; + return _lower | (_upper << 8); +} + +static IIO_SCAN_EL_C(supply, ADIS16209_SCAN_SUPPLY, IIO_UNSIGNED(14), + ADIS16209_SUPPLY_OUT, NULL); +static IIO_SCAN_EL_C(accel_x, ADIS16209_SCAN_ACC_X, IIO_SIGNED(14), + ADIS16209_XACCL_OUT, NULL); +static IIO_SCAN_EL_C(accel_y, ADIS16209_SCAN_ACC_Y, IIO_SIGNED(14), + ADIS16209_YACCL_OUT, NULL); +static IIO_SCAN_EL_C(aux_adc, ADIS16209_SCAN_AUX_ADC, IIO_UNSIGNED(12), + ADIS16209_AUX_ADC, NULL); +static IIO_SCAN_EL_C(temp, ADIS16209_SCAN_TEMP, IIO_UNSIGNED(12), + ADIS16209_TEMP_OUT, NULL); +static IIO_SCAN_EL_C(incli_x, ADIS16209_SCAN_INCLI_X, IIO_SIGNED(14), + ADIS16209_XINCL_OUT, NULL); +static IIO_SCAN_EL_C(incli_y, ADIS16209_SCAN_INCLI_Y, IIO_SIGNED(14), + ADIS16209_YINCL_OUT, NULL); +static IIO_SCAN_EL_C(rot, ADIS16209_SCAN_ROT, IIO_SIGNED(14), + ADIS16209_ROT_OUT, NULL); + +static IIO_SCAN_EL_TIMESTAMP(8); + +static struct attribute *adis16209_scan_el_attrs[] = { + &iio_scan_el_supply.dev_attr.attr, + &iio_scan_el_accel_x.dev_attr.attr, + &iio_scan_el_accel_y.dev_attr.attr, + &iio_scan_el_aux_adc.dev_attr.attr, + &iio_scan_el_temp.dev_attr.attr, + &iio_scan_el_incli_x.dev_attr.attr, + &iio_scan_el_incli_y.dev_attr.attr, + &iio_scan_el_rot.dev_attr.attr, + &iio_scan_el_timestamp.dev_attr.attr, + NULL, +}; + +static struct attribute_group adis16209_scan_el_group = { + .attrs = adis16209_scan_el_attrs, + .name = "scan_elements", +}; + +/** + * adis16209_poll_func_th() top half interrupt handler called by trigger + * @private_data: iio_dev + **/ +static void adis16209_poll_func_th(struct iio_dev *indio_dev) +{ + struct adis16209_state *st = iio_dev_get_devdata(indio_dev); + st->last_timestamp = indio_dev->trig->timestamp; + schedule_work(&st->work_trigger_to_ring); +} + +/** + * adis16209_read_ring_data() read data registers which will be placed into ring + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @rx: somewhere to pass back the value read + **/ +static int adis16209_read_ring_data(struct device *dev, u8 *rx) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16209_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[ADIS16209_OUTPUTS + 1]; + int ret; + int i; + + mutex_lock(&st->buf_lock); + + spi_message_init(&msg); + + memset(xfers, 0, sizeof(xfers)); + for (i = 0; i <= ADIS16209_OUTPUTS; i++) { + xfers[i].bits_per_word = 8; + xfers[i].cs_change = 1; + xfers[i].len = 2; + xfers[i].delay_usecs = 20; + xfers[i].tx_buf = st->tx + 2 * i; + st->tx[2 * i] + = ADIS16209_READ_REG(ADIS16209_SUPPLY_OUT + 2 * i); + st->tx[2 * i + 1] = 0; + if (i >= 1) + xfers[i].rx_buf = rx + 2 * (i - 1); + spi_message_add_tail(&xfers[i], &msg); + } + + ret = spi_sync(st->us, &msg); + if (ret) + dev_err(&st->us->dev, "problem when burst reading"); + + mutex_unlock(&st->buf_lock); + + return ret; +} + +/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device + * specific to be rolled into the core. + */ +static void adis16209_trigger_bh_to_ring(struct work_struct *work_s) +{ + struct adis16209_state *st + = container_of(work_s, struct adis16209_state, + work_trigger_to_ring); + + int i = 0; + s16 *data; + size_t datasize = st->indio_dev + ->ring->access.get_bpd(st->indio_dev->ring); + + data = kmalloc(datasize , GFP_KERNEL); + if (data == NULL) { + dev_err(&st->us->dev, "memory alloc failed in ring bh"); + return; + } + + if (st->indio_dev->scan_count) + if (adis16209_read_ring_data(&st->indio_dev->dev, st->rx) >= 0) + for (; i < st->indio_dev->scan_count; i++) { + data[i] = combine_8_to_16(st->rx[i*2+1], + st->rx[i*2]); + } + + /* Guaranteed to be aligned with 8 byte boundary */ + if (st->indio_dev->scan_timestamp) + *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp; + + st->indio_dev->ring->access.store_to(st->indio_dev->ring, + (u8 *)data, + st->last_timestamp); + + iio_trigger_notify_done(st->indio_dev->trig); + kfree(data); + + return; +} + +/* in these circumstances is it better to go with unaligned packing and + * deal with the cost?*/ +static int adis16209_data_rdy_ring_preenable(struct iio_dev *indio_dev) +{ + size_t size; + dev_dbg(&indio_dev->dev, "%s\n", __func__); + /* Check if there are any scan elements enabled, if not fail*/ + if (!(indio_dev->scan_count || indio_dev->scan_timestamp)) + return -EINVAL; + + if (indio_dev->ring->access.set_bpd) { + if (indio_dev->scan_timestamp) + if (indio_dev->scan_count) + /* Timestamp (aligned to s64) and data */ + size = (((indio_dev->scan_count * sizeof(s16)) + + sizeof(s64) - 1) + & ~(sizeof(s64) - 1)) + + sizeof(s64); + else /* Timestamp only */ + size = sizeof(s64); + else /* Data only */ + size = indio_dev->scan_count*sizeof(s16); + indio_dev->ring->access.set_bpd(indio_dev->ring, size); + } + + return 0; +} + +static int adis16209_data_rdy_ring_postenable(struct iio_dev *indio_dev) +{ + return indio_dev->trig + ? iio_trigger_attach_poll_func(indio_dev->trig, + indio_dev->pollfunc) + : 0; +} + +static int adis16209_data_rdy_ring_predisable(struct iio_dev *indio_dev) +{ + return indio_dev->trig + ? iio_trigger_dettach_poll_func(indio_dev->trig, + indio_dev->pollfunc) + : 0; +} + +void adis16209_unconfigure_ring(struct iio_dev *indio_dev) +{ + kfree(indio_dev->pollfunc); + iio_sw_rb_free(indio_dev->ring); +} + +int adis16209_configure_ring(struct iio_dev *indio_dev) +{ + int ret = 0; + struct adis16209_state *st = indio_dev->dev_data; + struct iio_ring_buffer *ring; + INIT_WORK(&st->work_trigger_to_ring, adis16209_trigger_bh_to_ring); + /* Set default scan mode */ + + iio_scan_mask_set(indio_dev, iio_scan_el_supply.number); + iio_scan_mask_set(indio_dev, iio_scan_el_rot.number); + iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number); + iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number); + iio_scan_mask_set(indio_dev, iio_scan_el_temp.number); + iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number); + iio_scan_mask_set(indio_dev, iio_scan_el_incli_x.number); + iio_scan_mask_set(indio_dev, iio_scan_el_incli_y.number); + indio_dev->scan_timestamp = true; + + indio_dev->scan_el_attrs = &adis16209_scan_el_group; + + ring = iio_sw_rb_allocate(indio_dev); + if (!ring) { + ret = -ENOMEM; + return ret; + } + indio_dev->ring = ring; + /* Effectively select the ring buffer implementation */ + iio_ring_sw_register_funcs(&ring->access); + ring->preenable = &adis16209_data_rdy_ring_preenable; + ring->postenable = &adis16209_data_rdy_ring_postenable; + ring->predisable = &adis16209_data_rdy_ring_predisable; + ring->owner = THIS_MODULE; + + indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL); + if (indio_dev->pollfunc == NULL) { + ret = -ENOMEM; + goto error_iio_sw_rb_free;; + } + indio_dev->pollfunc->poll_func_main = &adis16209_poll_func_th; + indio_dev->pollfunc->private_data = indio_dev; + indio_dev->modes |= INDIO_RING_TRIGGERED; + return 0; + +error_iio_sw_rb_free: + iio_sw_rb_free(indio_dev->ring); + return ret; +} + +int adis16209_initialize_ring(struct iio_ring_buffer *ring) +{ + return iio_ring_buffer_register(ring, 0); +} + +void adis16209_uninitialize_ring(struct iio_ring_buffer *ring) +{ + iio_ring_buffer_unregister(ring); +} diff --git a/drivers/staging/iio/accel/adis16209_trigger.c b/drivers/staging/iio/accel/adis16209_trigger.c new file mode 100644 index 000000000000..4a0507c9a13b --- /dev/null +++ b/drivers/staging/iio/accel/adis16209_trigger.c @@ -0,0 +1,124 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../trigger.h" +#include "adis16209.h" + +/** + * adis16209_data_rdy_trig_poll() the event handler for the data rdy trig + **/ +static int adis16209_data_rdy_trig_poll(struct iio_dev *dev_info, + int index, + s64 timestamp, + int no_test) +{ + struct adis16209_state *st = iio_dev_get_devdata(dev_info); + struct iio_trigger *trig = st->trig; + + trig->timestamp = timestamp; + iio_trigger_poll(trig); + + return IRQ_HANDLED; +} + +IIO_EVENT_SH(data_rdy_trig, &adis16209_data_rdy_trig_poll); + +static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL); + +static struct attribute *adis16209_trigger_attrs[] = { + &dev_attr_name.attr, + NULL, +}; + +static const struct attribute_group adis16209_trigger_attr_group = { + .attrs = adis16209_trigger_attrs, +}; + +/** + * adis16209_data_rdy_trigger_set_state() set datardy interrupt state + **/ +static int adis16209_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct adis16209_state *st = trig->private_data; + struct iio_dev *indio_dev = st->indio_dev; + int ret = 0; + + dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); + ret = adis16209_set_irq(&st->indio_dev->dev, state); + if (state == false) { + iio_remove_event_from_list(&iio_event_data_rdy_trig, + &indio_dev->interrupts[0] + ->ev_list); + flush_scheduled_work(); + } else { + iio_add_event_to_list(&iio_event_data_rdy_trig, + &indio_dev->interrupts[0]->ev_list); + } + return ret; +} + +/** + * adis16209_trig_try_reen() try renabling irq for data rdy trigger + * @trig: the datardy trigger + **/ +static int adis16209_trig_try_reen(struct iio_trigger *trig) +{ + struct adis16209_state *st = trig->private_data; + enable_irq(st->us->irq); + return 0; +} + +int adis16209_probe_trigger(struct iio_dev *indio_dev) +{ + int ret; + struct adis16209_state *st = indio_dev->dev_data; + + st->trig = iio_allocate_trigger(); + st->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL); + if (!st->trig->name) { + ret = -ENOMEM; + goto error_free_trig; + } + snprintf((char *)st->trig->name, + IIO_TRIGGER_NAME_LENGTH, + "adis16209-dev%d", indio_dev->id); + st->trig->dev.parent = &st->us->dev; + st->trig->owner = THIS_MODULE; + st->trig->private_data = st; + st->trig->set_trigger_state = &adis16209_data_rdy_trigger_set_state; + st->trig->try_reenable = &adis16209_trig_try_reen; + st->trig->control_attrs = &adis16209_trigger_attr_group; + ret = iio_trigger_register(st->trig); + + /* select default trigger */ + indio_dev->trig = st->trig; + if (ret) + goto error_free_trig_name; + + return 0; + +error_free_trig_name: + kfree(st->trig->name); +error_free_trig: + iio_free_trigger(st->trig); + + return ret; +} + +void adis16209_remove_trigger(struct iio_dev *indio_dev) +{ + struct adis16209_state *state = indio_dev->dev_data; + + iio_trigger_unregister(state->trig); + kfree(state->trig->name); + iio_free_trigger(state->trig); +} -- cgit v1.2.3 From 2c834b4d2d30c8f8ae5365a66c50da95aed7b7ea Mon Sep 17 00:00:00 2001 From: Barry Song Date: Fri, 7 May 2010 15:39:00 +0100 Subject: staging: iio: adis16240 driver Signed-off-by: Barry Song Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/Kconfig | 9 + drivers/staging/iio/accel/Makefile | 4 + drivers/staging/iio/accel/adis16240.h | 218 ++++++++++ drivers/staging/iio/accel/adis16240_core.c | 599 ++++++++++++++++++++++++++ drivers/staging/iio/accel/adis16240_ring.c | 254 +++++++++++ drivers/staging/iio/accel/adis16240_trigger.c | 124 ++++++ 6 files changed, 1208 insertions(+) create mode 100644 drivers/staging/iio/accel/adis16240.h create mode 100644 drivers/staging/iio/accel/adis16240_core.c create mode 100644 drivers/staging/iio/accel/adis16240_ring.c create mode 100644 drivers/staging/iio/accel/adis16240_trigger.c (limited to 'drivers') diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig index 1d89e2153dd2..8f3f70f10a38 100644 --- a/drivers/staging/iio/accel/Kconfig +++ b/drivers/staging/iio/accel/Kconfig @@ -12,6 +12,15 @@ config ADIS16209 Say yes here to build support for Analog Devices adis16209 dual-axis digital inclinometer and accelerometer. +config ADIS16240 + tristate "Analog Devices ADIS16240 Programmable Impact Sensor and Recorder" + depends on SPI + select IIO_TRIGGER if IIO_RING_BUFFER + select IIO_SW_RING if IIO_RING_BUFFER + help + Say yes here to build support for Analog Devices adis16240 programmable + impact Sensor and recorder. + config KXSD9 tristate "Kionix KXSD9 Accelerometer Driver" depends on SPI diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile index f8f2124720e7..0e6762c34878 100644 --- a/drivers/staging/iio/accel/Makefile +++ b/drivers/staging/iio/accel/Makefile @@ -5,6 +5,10 @@ adis16209-y := adis16209_core.o adis16209-$(CONFIG_IIO_RING_BUFFER) += adis16209_ring.o adis16209_trigger.o obj-$(CONFIG_ADIS16209) += adis16209.o +adis16240-y := adis16240_core.o +adis16240-$(CONFIG_IIO_RING_BUFFER) += adis16240_ring.o adis16240_trigger.o +obj-$(CONFIG_ADIS16240) += adis16240.o + obj-$(CONFIG_KXSD9) += kxsd9.o lis3l02dq-y := lis3l02dq_core.o diff --git a/drivers/staging/iio/accel/adis16240.h b/drivers/staging/iio/accel/adis16240.h new file mode 100644 index 000000000000..dcff43c75235 --- /dev/null +++ b/drivers/staging/iio/accel/adis16240.h @@ -0,0 +1,218 @@ +#ifndef SPI_ADIS16240_H_ +#define SPI_ADIS16240_H_ + +#define ADIS16240_STARTUP_DELAY 220 /* ms */ + +#define ADIS16240_READ_REG(a) a +#define ADIS16240_WRITE_REG(a) ((a) | 0x80) + +/* Flash memory write count */ +#define ADIS16240_FLASH_CNT 0x00 +/* Output, power supply */ +#define ADIS16240_SUPPLY_OUT 0x02 +/* Output, x-axis accelerometer */ +#define ADIS16240_XACCL_OUT 0x04 +/* Output, y-axis accelerometer */ +#define ADIS16240_YACCL_OUT 0x06 +/* Output, z-axis accelerometer */ +#define ADIS16240_ZACCL_OUT 0x08 +/* Output, auxiliary ADC input */ +#define ADIS16240_AUX_ADC 0x0A +/* Output, temperature */ +#define ADIS16240_TEMP_OUT 0x0C +/* Output, x-axis acceleration peak */ +#define ADIS16240_XPEAK_OUT 0x0E +/* Output, y-axis acceleration peak */ +#define ADIS16240_YPEAK_OUT 0x10 +/* Output, z-axis acceleration peak */ +#define ADIS16240_ZPEAK_OUT 0x12 +/* Output, sum-of-squares acceleration peak */ +#define ADIS16240_XYZPEAK_OUT 0x14 +/* Output, Capture Buffer 1, X and Y acceleration */ +#define ADIS16240_CAPT_BUF1 0x16 +/* Output, Capture Buffer 2, Z acceleration */ +#define ADIS16240_CAPT_BUF2 0x18 +/* Diagnostic, error flags */ +#define ADIS16240_DIAG_STAT 0x1A +/* Diagnostic, event counter */ +#define ADIS16240_EVNT_CNTR 0x1C +/* Diagnostic, check sum value from firmware test */ +#define ADIS16240_CHK_SUM 0x1E +/* Calibration, x-axis acceleration offset adjustment */ +#define ADIS16240_XACCL_OFF 0x20 +/* Calibration, y-axis acceleration offset adjustment */ +#define ADIS16240_YACCL_OFF 0x22 +/* Calibration, z-axis acceleration offset adjustment */ +#define ADIS16240_ZACCL_OFF 0x24 +/* Clock, hour and minute */ +#define ADIS16240_CLK_TIME 0x2E +/* Clock, month and day */ +#define ADIS16240_CLK_DATE 0x30 +/* Clock, year */ +#define ADIS16240_CLK_YEAR 0x32 +/* Wake-up setting, hour and minute */ +#define ADIS16240_WAKE_TIME 0x34 +/* Wake-up setting, month and day */ +#define ADIS16240_WAKE_DATE 0x36 +/* Alarm 1 amplitude threshold */ +#define ADIS16240_ALM_MAG1 0x38 +/* Alarm 2 amplitude threshold */ +#define ADIS16240_ALM_MAG2 0x3A +/* Alarm control */ +#define ADIS16240_ALM_CTRL 0x3C +/* Capture, external trigger control */ +#define ADIS16240_XTRIG_CTRL 0x3E +/* Capture, address pointer */ +#define ADIS16240_CAPT_PNTR 0x40 +/* Capture, configuration and control */ +#define ADIS16240_CAPT_CTRL 0x42 +/* General-purpose digital input/output control */ +#define ADIS16240_GPIO_CTRL 0x44 +/* Miscellaneous control */ +#define ADIS16240_MSC_CTRL 0x46 +/* Internal sample period (rate) control */ +#define ADIS16240_SMPL_PRD 0x48 +/* System command */ +#define ADIS16240_GLOB_CMD 0x4A + +#define ADIS16240_OUTPUTS 6 + +/* MSC_CTRL */ +/* Enables sum-of-squares output (XYZPEAK_OUT) */ +#define ADIS16240_MSC_CTRL_XYZPEAK_OUT_EN (1 << 15) +/* Enables peak tracking output (XPEAK_OUT, YPEAK_OUT, and ZPEAK_OUT) */ +#define ADIS16240_MSC_CTRL_X_Y_ZPEAK_OUT_EN (1 << 14) +/* Self-test enable: 1 = apply electrostatic force, 0 = disabled */ +#define ADIS16240_MSC_CTRL_SELF_TEST_EN (1 << 8) +/* Data-ready enable: 1 = enabled, 0 = disabled */ +#define ADIS16240_MSC_CTRL_DATA_RDY_EN (1 << 2) +/* Data-ready polarity: 1 = active high, 0 = active low */ +#define ADIS16240_MSC_CTRL_ACTIVE_HIGH (1 << 1) +/* Data-ready line selection: 1 = DIO2, 0 = DIO1 */ +#define ADIS16240_MSC_CTRL_DATA_RDY_DIO2 (1 << 0) + +/* DIAG_STAT */ +/* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ +#define ADIS16240_DIAG_STAT_ALARM2 (1<<9) +/* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ +#define ADIS16240_DIAG_STAT_ALARM1 (1<<8) +/* Capture buffer full: 1 = capture buffer is full */ +#define ADIS16240_DIAG_STAT_CPT_BUF_FUL (1<<7) +/* Flash test, checksum flag: 1 = mismatch, 0 = match */ +#define ADIS16240_DIAG_STAT_CHKSUM (1<<6) +/* Power-on, self-test flag: 1 = failure, 0 = pass */ +#define ADIS16240_DIAG_STAT_PWRON_FAIL (1<<5) +/* Power-on self-test: 1 = in-progress, 0 = complete */ +#define ADIS16240_DIAG_STAT_PWRON_BUSY (1<<4) +/* SPI communications failure */ +#define ADIS16240_DIAG_STAT_SPI_FAIL (1<<3) +/* Flash update failure */ +#define ADIS16240_DIAG_STAT_FLASH_UPT (1<<2) +/* Power supply above 3.625 V */ +#define ADIS16240_DIAG_STAT_POWER_HIGH (1<<1) + /* Power supply below 3.15 V */ +#define ADIS16240_DIAG_STAT_POWER_LOW (1<<0) + +/* GLOB_CMD */ +#define ADIS16240_GLOB_CMD_RESUME (1<<8) +#define ADIS16240_GLOB_CMD_SW_RESET (1<<7) +#define ADIS16240_GLOB_CMD_STANDBY (1<<2) + +#define ADIS16240_ERROR_ACTIVE (1<<14) + +#define ADIS16240_MAX_TX 24 +#define ADIS16240_MAX_RX 24 + +/** + * struct adis16240_state - device instance specific data + * @us: actual spi_device + * @work_trigger_to_ring: bh for triggered event handling + * @work_cont_thresh: CLEAN + * @inter: used to check if new interrupt has been triggered + * @last_timestamp: passing timestamp from th to bh of interrupt handler + * @indio_dev: industrial I/O device structure + * @trig: data ready trigger registered with iio + * @tx: transmit buffer + * @rx: recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct adis16240_state { + struct spi_device *us; + struct work_struct work_trigger_to_ring; + struct iio_work_cont work_cont_thresh; + s64 last_timestamp; + struct iio_dev *indio_dev; + struct iio_trigger *trig; + u8 *tx; + u8 *rx; + struct mutex buf_lock; +}; + +int adis16240_set_irq(struct device *dev, bool enable); + +#ifdef CONFIG_IIO_RING_BUFFER +/* At the moment triggers are only used for ring buffer + * filling. This may change! + */ + +enum adis16240_scan { + ADIS16240_SCAN_SUPPLY, + ADIS16240_SCAN_ACC_X, + ADIS16240_SCAN_ACC_Y, + ADIS16240_SCAN_ACC_Z, + ADIS16240_SCAN_AUX_ADC, + ADIS16240_SCAN_TEMP, +}; + +void adis16240_remove_trigger(struct iio_dev *indio_dev); +int adis16240_probe_trigger(struct iio_dev *indio_dev); + +ssize_t adis16240_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf); + + +int adis16240_configure_ring(struct iio_dev *indio_dev); +void adis16240_unconfigure_ring(struct iio_dev *indio_dev); + +int adis16240_initialize_ring(struct iio_ring_buffer *ring); +void adis16240_uninitialize_ring(struct iio_ring_buffer *ring); +#else /* CONFIG_IIO_RING_BUFFER */ + +static inline void adis16240_remove_trigger(struct iio_dev *indio_dev) +{ +} + +static inline int adis16240_probe_trigger(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline ssize_t +adis16240_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static int adis16240_configure_ring(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline void adis16240_unconfigure_ring(struct iio_dev *indio_dev) +{ +} + +static inline int adis16240_initialize_ring(struct iio_ring_buffer *ring) +{ + return 0; +} + +static inline void adis16240_uninitialize_ring(struct iio_ring_buffer *ring) +{ +} + +#endif /* CONFIG_IIO_RING_BUFFER */ +#endif /* SPI_ADIS16240_H_ */ diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c new file mode 100644 index 000000000000..54fd6d77412f --- /dev/null +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -0,0 +1,599 @@ +/* + * ADIS16240 Programmable Impact Sensor and Recorder driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "accel.h" +#include "../adc/adc.h" + +#include "adis16240.h" + +#define DRIVER_NAME "adis16240" + +static int adis16240_check_status(struct device *dev); + +/** + * adis16240_spi_write_reg_8() - write single byte to a register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the register to be written + * @val: the value to write + **/ +static int adis16240_spi_write_reg_8(struct device *dev, + u8 reg_address, + u8 val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16240_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16240_WRITE_REG(reg_address); + st->tx[1] = val; + + ret = spi_write(st->us, st->tx, 2); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16240_spi_write_reg_16() - write 2 bytes to a pair of registers + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: value to be written + **/ +static int adis16240_spi_write_reg_16(struct device *dev, + u8 lower_reg_address, + u16 value) +{ + int ret; + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16240_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 25, + }, { + .tx_buf = st->tx + 2, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 25, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16240_WRITE_REG(lower_reg_address); + st->tx[1] = value & 0xFF; + st->tx[2] = ADIS16240_WRITE_REG(lower_reg_address + 1); + st->tx[3] = (value >> 8) & 0xFF; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16240_spi_read_reg_16() - read 2 bytes from a 16-bit register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: somewhere to pass back the value read + **/ +static int adis16240_spi_read_reg_16(struct device *dev, + u8 lower_reg_address, + u16 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16240_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 25, + }, { + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 25, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16240_READ_REG(lower_reg_address); + st->tx[1] = 0; + st->tx[2] = 0; + st->tx[3] = 0; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, + "problem when reading 16 bit register 0x%02X", + lower_reg_address); + goto error_ret; + } + *val = (st->rx[0] << 8) | st->rx[1]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static ssize_t adis16240_spi_read_signed(struct device *dev, + struct device_attribute *attr, + char *buf, + unsigned bits) +{ + int ret; + s16 val = 0; + unsigned shift = 16 - bits; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = adis16240_spi_read_reg_16(dev, this_attr->address, (u16 *)&val); + if (ret) + return ret; + + if (val & ADIS16240_ERROR_ACTIVE) + adis16240_check_status(dev); + + val = ((s16)(val << shift) >> shift); + return sprintf(buf, "%d\n", val); +} + +static ssize_t adis16240_read_10bit_unsigned(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u16 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = adis16240_spi_read_reg_16(dev, this_attr->address, &val); + if (ret) + return ret; + + if (val & ADIS16240_ERROR_ACTIVE) + adis16240_check_status(dev); + + return sprintf(buf, "%u\n", val & 0x03FF); +} + +static ssize_t adis16240_read_10bit_signed(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + ssize_t ret; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + ret = adis16240_spi_read_signed(dev, attr, buf, 10); + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t adis16240_read_12bit_signed(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + ssize_t ret; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + ret = adis16240_spi_read_signed(dev, attr, buf, 12); + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t adis16240_write_16bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = adis16240_spi_write_reg_16(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static int adis16240_reset(struct device *dev) +{ + int ret; + ret = adis16240_spi_write_reg_8(dev, + ADIS16240_GLOB_CMD, + ADIS16240_GLOB_CMD_SW_RESET); + if (ret) + dev_err(dev, "problem resetting device"); + + return ret; +} + +static ssize_t adis16240_write_reset(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + if (len < 1) + return -EINVAL; + switch (buf[0]) { + case '1': + case 'y': + case 'Y': + return adis16240_reset(dev); + } + return -EINVAL; +} + +int adis16240_set_irq(struct device *dev, bool enable) +{ + int ret = 0; + u16 msc; + + ret = adis16240_spi_read_reg_16(dev, ADIS16240_MSC_CTRL, &msc); + if (ret) + goto error_ret; + + msc |= ADIS16240_MSC_CTRL_ACTIVE_HIGH; + msc &= ~ADIS16240_MSC_CTRL_DATA_RDY_DIO2; + if (enable) + msc |= ADIS16240_MSC_CTRL_DATA_RDY_EN; + else + msc &= ~ADIS16240_MSC_CTRL_DATA_RDY_EN; + + ret = adis16240_spi_write_reg_16(dev, ADIS16240_MSC_CTRL, msc); + +error_ret: + return ret; +} + +static int adis16240_self_test(struct device *dev) +{ + int ret; + ret = adis16240_spi_write_reg_16(dev, + ADIS16240_MSC_CTRL, + ADIS16240_MSC_CTRL_SELF_TEST_EN); + if (ret) { + dev_err(dev, "problem starting self test"); + goto err_ret; + } + + msleep(ADIS16240_STARTUP_DELAY); + + adis16240_check_status(dev); + +err_ret: + return ret; +} + +static int adis16240_check_status(struct device *dev) +{ + u16 status; + int ret; + + ret = adis16240_spi_read_reg_16(dev, ADIS16240_DIAG_STAT, &status); + + if (ret < 0) { + dev_err(dev, "Reading status failed\n"); + goto error_ret; + } + + ret = status & 0x2F; + if (status & ADIS16240_DIAG_STAT_PWRON_FAIL) + dev_err(dev, "Power-on, self-test fail\n"); + if (status & ADIS16240_DIAG_STAT_SPI_FAIL) + dev_err(dev, "SPI failure\n"); + if (status & ADIS16240_DIAG_STAT_FLASH_UPT) + dev_err(dev, "Flash update failed\n"); + if (status & ADIS16240_DIAG_STAT_POWER_HIGH) + dev_err(dev, "Power supply above 3.625V\n"); + if (status & ADIS16240_DIAG_STAT_POWER_LOW) + dev_err(dev, "Power supply below 2.225V\n"); + +error_ret: + return ret; +} + +static int adis16240_initial_setup(struct adis16240_state *st) +{ + int ret; + struct device *dev = &st->indio_dev->dev; + + /* Disable IRQ */ + ret = adis16240_set_irq(dev, false); + if (ret) { + dev_err(dev, "disable irq failed"); + goto err_ret; + } + + /* Do self test */ + ret = adis16240_self_test(dev); + if (ret) { + dev_err(dev, "self test failure"); + goto err_ret; + } + + /* Read status register to check the result */ + ret = adis16240_check_status(dev); + if (ret) { + adis16240_reset(dev); + dev_err(dev, "device not playing ball -> reset"); + msleep(ADIS16240_STARTUP_DELAY); + ret = adis16240_check_status(dev); + if (ret) { + dev_err(dev, "giving up"); + goto err_ret; + } + } + + printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n", + st->us->chip_select, st->us->irq); + +err_ret: + return ret; +} + +static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16240_read_10bit_unsigned, + ADIS16240_SUPPLY_OUT); +static IIO_DEV_ATTR_IN_RAW(0, adis16240_read_10bit_signed, + ADIS16240_AUX_ADC); +static IIO_CONST_ATTR(in_supply_scale, "0.00488"); +static IIO_DEV_ATTR_ACCEL_X(adis16240_read_10bit_signed, + ADIS16240_XACCL_OUT); +static IIO_DEVICE_ATTR(accel_x_peak_raw, S_IRUGO, + adis16240_read_10bit_signed, NULL, + ADIS16240_XPEAK_OUT); +static IIO_DEV_ATTR_ACCEL_Y(adis16240_read_10bit_signed, + ADIS16240_YACCL_OUT); +static IIO_DEVICE_ATTR(accel_y_peak_raw, S_IRUGO, + adis16240_read_10bit_signed, NULL, + ADIS16240_YPEAK_OUT); +static IIO_DEV_ATTR_ACCEL_Z(adis16240_read_10bit_signed, + ADIS16240_ZACCL_OUT); +static IIO_DEVICE_ATTR(accel_z_peak_raw, S_IRUGO, + adis16240_read_10bit_signed, NULL, + ADIS16240_ZPEAK_OUT); + +static IIO_DEVICE_ATTR(accel_xyz_squared_peak_raw, S_IRUGO, + adis16240_read_12bit_signed, NULL, + ADIS16240_XYZPEAK_OUT); +static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO, + adis16240_read_10bit_signed, + adis16240_write_16bit, + ADIS16240_XACCL_OFF); +static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO, + adis16240_read_10bit_signed, + adis16240_write_16bit, + ADIS16240_YACCL_OFF); +static IIO_DEV_ATTR_ACCEL_Z_OFFSET(S_IWUSR | S_IRUGO, + adis16240_read_10bit_signed, + adis16240_write_16bit, + ADIS16240_ZACCL_OFF); +static IIO_DEV_ATTR_TEMP_RAW(adis16240_read_10bit_unsigned); +static IIO_CONST_ATTR(temp_scale, "0.244"); + +static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16240_write_reset, 0); + +static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("4096"); + +static IIO_CONST_ATTR(name, "adis16240"); + +static struct attribute *adis16240_event_attributes[] = { + NULL +}; + +static struct attribute_group adis16240_event_attribute_group = { + .attrs = adis16240_event_attributes, +}; + +static struct attribute *adis16240_attributes[] = { + &iio_dev_attr_in_supply_raw.dev_attr.attr, + &iio_const_attr_in_supply_scale.dev_attr.attr, + &iio_dev_attr_in0_raw.dev_attr.attr, + &iio_dev_attr_accel_x_raw.dev_attr.attr, + &iio_dev_attr_accel_x_offset.dev_attr.attr, + &iio_dev_attr_accel_x_peak_raw.dev_attr.attr, + &iio_dev_attr_accel_y_raw.dev_attr.attr, + &iio_dev_attr_accel_y_offset.dev_attr.attr, + &iio_dev_attr_accel_y_peak_raw.dev_attr.attr, + &iio_dev_attr_accel_z_raw.dev_attr.attr, + &iio_dev_attr_accel_z_offset.dev_attr.attr, + &iio_dev_attr_accel_z_peak_raw.dev_attr.attr, + &iio_dev_attr_accel_xyz_squared_peak_raw.dev_attr.attr, + &iio_dev_attr_temp_raw.dev_attr.attr, + &iio_const_attr_temp_scale.dev_attr.attr, + &iio_const_attr_available_sampling_frequency.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_const_attr_name.dev_attr.attr, + NULL +}; + +static const struct attribute_group adis16240_attribute_group = { + .attrs = adis16240_attributes, +}; + +static int __devinit adis16240_probe(struct spi_device *spi) +{ + int ret, regdone = 0; + struct adis16240_state *st = kzalloc(sizeof *st, GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + goto error_ret; + } + /* this is only used for removal purposes */ + spi_set_drvdata(spi, st); + + /* Allocate the comms buffers */ + st->rx = kzalloc(sizeof(*st->rx)*ADIS16240_MAX_RX, GFP_KERNEL); + if (st->rx == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->tx = kzalloc(sizeof(*st->tx)*ADIS16240_MAX_TX, GFP_KERNEL); + if (st->tx == NULL) { + ret = -ENOMEM; + goto error_free_rx; + } + st->us = spi; + mutex_init(&st->buf_lock); + /* setup the industrialio driver allocated elements */ + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_tx; + } + + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->num_interrupt_lines = 1; + st->indio_dev->event_attrs = &adis16240_event_attribute_group; + st->indio_dev->attrs = &adis16240_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = adis16240_configure_ring(st->indio_dev); + if (ret) + goto error_free_dev; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_unreg_ring_funcs; + regdone = 1; + + ret = adis16240_initialize_ring(st->indio_dev->ring); + if (ret) { + printk(KERN_ERR "failed to initialize the ring\n"); + goto error_unreg_ring_funcs; + } + + if (spi->irq) { + ret = iio_register_interrupt_line(spi->irq, + st->indio_dev, + 0, + IRQF_TRIGGER_RISING, + "adis16240"); + if (ret) + goto error_uninitialize_ring; + + ret = adis16240_probe_trigger(st->indio_dev); + if (ret) + goto error_unregister_line; + } + + /* Get the device into a sane initial state */ + ret = adis16240_initial_setup(st); + if (ret) + goto error_remove_trigger; + return 0; + +error_remove_trigger: + adis16240_remove_trigger(st->indio_dev); +error_unregister_line: + if (spi->irq) + iio_unregister_interrupt_line(st->indio_dev, 0); +error_uninitialize_ring: + adis16240_uninitialize_ring(st->indio_dev->ring); +error_unreg_ring_funcs: + adis16240_unconfigure_ring(st->indio_dev); +error_free_dev: + if (regdone) + iio_device_unregister(st->indio_dev); + else + iio_free_device(st->indio_dev); +error_free_tx: + kfree(st->tx); +error_free_rx: + kfree(st->rx); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +static int adis16240_remove(struct spi_device *spi) +{ + struct adis16240_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + + flush_scheduled_work(); + + adis16240_remove_trigger(indio_dev); + if (spi->irq) + iio_unregister_interrupt_line(indio_dev, 0); + + adis16240_uninitialize_ring(indio_dev->ring); + iio_device_unregister(indio_dev); + adis16240_unconfigure_ring(indio_dev); + kfree(st->tx); + kfree(st->rx); + kfree(st); + + return 0; +} + +static struct spi_driver adis16240_driver = { + .driver = { + .name = "adis16240", + .owner = THIS_MODULE, + }, + .probe = adis16240_probe, + .remove = __devexit_p(adis16240_remove), +}; + +static __init int adis16240_init(void) +{ + return spi_register_driver(&adis16240_driver); +} +module_init(adis16240_init); + +static __exit void adis16240_exit(void) +{ + spi_unregister_driver(&adis16240_driver); +} +module_exit(adis16240_exit); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices Programmable Impact Sensor and Recorder"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c new file mode 100644 index 000000000000..26b677bd84c0 --- /dev/null +++ b/drivers/staging/iio/accel/adis16240_ring.c @@ -0,0 +1,254 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../ring_sw.h" +#include "accel.h" +#include "../trigger.h" +#include "adis16240.h" + +/** + * combine_8_to_16() utility function to munge to u8s into u16 + **/ +static inline u16 combine_8_to_16(u8 lower, u8 upper) +{ + u16 _lower = lower; + u16 _upper = upper; + return _lower | (_upper << 8); +} + +static IIO_SCAN_EL_C(supply, ADIS16240_SCAN_SUPPLY, IIO_UNSIGNED(10), + ADIS16240_SUPPLY_OUT, NULL); +static IIO_SCAN_EL_C(accel_x, ADIS16240_SCAN_ACC_X, IIO_SIGNED(10), + ADIS16240_XACCL_OUT, NULL); +static IIO_SCAN_EL_C(accel_y, ADIS16240_SCAN_ACC_Y, IIO_SIGNED(10), + ADIS16240_YACCL_OUT, NULL); +static IIO_SCAN_EL_C(accel_z, ADIS16240_SCAN_ACC_Z, IIO_SIGNED(10), + ADIS16240_ZACCL_OUT, NULL); +static IIO_SCAN_EL_C(aux_adc, ADIS16240_SCAN_AUX_ADC, IIO_UNSIGNED(10), + ADIS16240_AUX_ADC, NULL); +static IIO_SCAN_EL_C(temp, ADIS16240_SCAN_TEMP, IIO_UNSIGNED(10), + ADIS16240_TEMP_OUT, NULL); + +static IIO_SCAN_EL_TIMESTAMP(6); + +static struct attribute *adis16240_scan_el_attrs[] = { + &iio_scan_el_supply.dev_attr.attr, + &iio_scan_el_accel_x.dev_attr.attr, + &iio_scan_el_accel_y.dev_attr.attr, + &iio_scan_el_accel_z.dev_attr.attr, + &iio_scan_el_aux_adc.dev_attr.attr, + &iio_scan_el_temp.dev_attr.attr, + &iio_scan_el_timestamp.dev_attr.attr, + NULL, +}; + +static struct attribute_group adis16240_scan_el_group = { + .attrs = adis16240_scan_el_attrs, + .name = "scan_elements", +}; + +/** + * adis16240_poll_func_th() top half interrupt handler called by trigger + * @private_data: iio_dev + **/ +static void adis16240_poll_func_th(struct iio_dev *indio_dev) +{ + struct adis16240_state *st = iio_dev_get_devdata(indio_dev); + st->last_timestamp = indio_dev->trig->timestamp; + schedule_work(&st->work_trigger_to_ring); +} + +/** + * adis16240_read_ring_data() read data registers which will be placed into ring + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @rx: somewhere to pass back the value read + **/ +static int adis16240_read_ring_data(struct device *dev, u8 *rx) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16240_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[ADIS16240_OUTPUTS + 1]; + int ret; + int i; + + mutex_lock(&st->buf_lock); + + spi_message_init(&msg); + + memset(xfers, 0, sizeof(xfers)); + for (i = 0; i <= ADIS16240_OUTPUTS; i++) { + xfers[i].bits_per_word = 8; + xfers[i].cs_change = 1; + xfers[i].len = 2; + xfers[i].delay_usecs = 30; + xfers[i].tx_buf = st->tx + 2 * i; + st->tx[2 * i] + = ADIS16240_READ_REG(ADIS16240_SUPPLY_OUT + 2 * i); + st->tx[2 * i + 1] = 0; + if (i >= 1) + xfers[i].rx_buf = rx + 2 * (i - 1); + spi_message_add_tail(&xfers[i], &msg); + } + + ret = spi_sync(st->us, &msg); + if (ret) + dev_err(&st->us->dev, "problem when burst reading"); + + mutex_unlock(&st->buf_lock); + + return ret; +} + + +static void adis16240_trigger_bh_to_ring(struct work_struct *work_s) +{ + struct adis16240_state *st + = container_of(work_s, struct adis16240_state, + work_trigger_to_ring); + + int i = 0; + s16 *data; + size_t datasize = st->indio_dev + ->ring->access.get_bpd(st->indio_dev->ring); + + data = kmalloc(datasize , GFP_KERNEL); + if (data == NULL) { + dev_err(&st->us->dev, "memory alloc failed in ring bh"); + return; + } + + if (st->indio_dev->scan_count) + if (adis16240_read_ring_data(&st->indio_dev->dev, st->rx) >= 0) + for (; i < st->indio_dev->scan_count; i++) { + data[i] = combine_8_to_16(st->rx[i*2+1], + st->rx[i*2]); + } + + /* Guaranteed to be aligned with 8 byte boundary */ + if (st->indio_dev->scan_timestamp) + *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp; + + st->indio_dev->ring->access.store_to(st->indio_dev->ring, + (u8 *)data, + st->last_timestamp); + + iio_trigger_notify_done(st->indio_dev->trig); + kfree(data); + + return; +} + +static int adis16240_data_rdy_ring_preenable(struct iio_dev *indio_dev) +{ + size_t size; + dev_dbg(&indio_dev->dev, "%s\n", __func__); + /* Check if there are any scan elements enabled, if not fail*/ + if (!(indio_dev->scan_count || indio_dev->scan_timestamp)) + return -EINVAL; + + if (indio_dev->ring->access.set_bpd) { + if (indio_dev->scan_timestamp) + if (indio_dev->scan_count) + /* Timestamp (aligned sizeof(s64) and data */ + size = (((indio_dev->scan_count * sizeof(s16)) + + sizeof(s64) - 1) + & ~(sizeof(s64) - 1)) + + sizeof(s64); + else /* Timestamp only */ + size = sizeof(s64); + else /* Data only */ + size = indio_dev->scan_count*sizeof(s16); + indio_dev->ring->access.set_bpd(indio_dev->ring, size); + } + + return 0; +} + +static int adis16240_data_rdy_ring_postenable(struct iio_dev *indio_dev) +{ + return indio_dev->trig + ? iio_trigger_attach_poll_func(indio_dev->trig, + indio_dev->pollfunc) + : 0; +} + +static int adis16240_data_rdy_ring_predisable(struct iio_dev *indio_dev) +{ + return indio_dev->trig + ? iio_trigger_dettach_poll_func(indio_dev->trig, + indio_dev->pollfunc) + : 0; +} + +void adis16240_unconfigure_ring(struct iio_dev *indio_dev) +{ + kfree(indio_dev->pollfunc); + iio_sw_rb_free(indio_dev->ring); +} + +int adis16240_configure_ring(struct iio_dev *indio_dev) +{ + int ret = 0; + struct adis16240_state *st = indio_dev->dev_data; + struct iio_ring_buffer *ring; + INIT_WORK(&st->work_trigger_to_ring, adis16240_trigger_bh_to_ring); + /* Set default scan mode */ + + iio_scan_mask_set(indio_dev, iio_scan_el_supply.number); + iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number); + iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number); + iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number); + iio_scan_mask_set(indio_dev, iio_scan_el_temp.number); + iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number); + indio_dev->scan_timestamp = true; + + indio_dev->scan_el_attrs = &adis16240_scan_el_group; + + ring = iio_sw_rb_allocate(indio_dev); + if (!ring) { + ret = -ENOMEM; + return ret; + } + indio_dev->ring = ring; + /* Effectively select the ring buffer implementation */ + iio_ring_sw_register_funcs(&ring->access); + ring->preenable = &adis16240_data_rdy_ring_preenable; + ring->postenable = &adis16240_data_rdy_ring_postenable; + ring->predisable = &adis16240_data_rdy_ring_predisable; + ring->owner = THIS_MODULE; + + indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL); + if (indio_dev->pollfunc == NULL) { + ret = -ENOMEM; + goto error_iio_sw_rb_free;; + } + indio_dev->pollfunc->poll_func_main = &adis16240_poll_func_th; + indio_dev->pollfunc->private_data = indio_dev; + indio_dev->modes |= INDIO_RING_TRIGGERED; + return 0; + +error_iio_sw_rb_free: + iio_sw_rb_free(indio_dev->ring); + return ret; +} + +int adis16240_initialize_ring(struct iio_ring_buffer *ring) +{ + return iio_ring_buffer_register(ring, 0); +} + +void adis16240_uninitialize_ring(struct iio_ring_buffer *ring) +{ + iio_ring_buffer_unregister(ring); +} diff --git a/drivers/staging/iio/accel/adis16240_trigger.c b/drivers/staging/iio/accel/adis16240_trigger.c new file mode 100644 index 000000000000..df1312e17f4b --- /dev/null +++ b/drivers/staging/iio/accel/adis16240_trigger.c @@ -0,0 +1,124 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../trigger.h" +#include "adis16240.h" + +/** + * adis16240_data_rdy_trig_poll() the event handler for the data rdy trig + **/ +static int adis16240_data_rdy_trig_poll(struct iio_dev *dev_info, + int index, + s64 timestamp, + int no_test) +{ + struct adis16240_state *st = iio_dev_get_devdata(dev_info); + struct iio_trigger *trig = st->trig; + + trig->timestamp = timestamp; + iio_trigger_poll(trig); + + return IRQ_HANDLED; +} + +IIO_EVENT_SH(data_rdy_trig, &adis16240_data_rdy_trig_poll); + +static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL); + +static struct attribute *adis16240_trigger_attrs[] = { + &dev_attr_name.attr, + NULL, +}; + +static const struct attribute_group adis16240_trigger_attr_group = { + .attrs = adis16240_trigger_attrs, +}; + +/** + * adis16240_data_rdy_trigger_set_state() set datardy interrupt state + **/ +static int adis16240_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct adis16240_state *st = trig->private_data; + struct iio_dev *indio_dev = st->indio_dev; + int ret = 0; + + dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); + ret = adis16240_set_irq(&st->indio_dev->dev, state); + if (state == false) { + iio_remove_event_from_list(&iio_event_data_rdy_trig, + &indio_dev->interrupts[0] + ->ev_list); + flush_scheduled_work(); + } else { + iio_add_event_to_list(&iio_event_data_rdy_trig, + &indio_dev->interrupts[0]->ev_list); + } + return ret; +} + +/** + * adis16240_trig_try_reen() try renabling irq for data rdy trigger + * @trig: the datardy trigger + **/ +static int adis16240_trig_try_reen(struct iio_trigger *trig) +{ + struct adis16240_state *st = trig->private_data; + enable_irq(st->us->irq); + return 0; +} + +int adis16240_probe_trigger(struct iio_dev *indio_dev) +{ + int ret; + struct adis16240_state *st = indio_dev->dev_data; + + st->trig = iio_allocate_trigger(); + st->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL); + if (!st->trig->name) { + ret = -ENOMEM; + goto error_free_trig; + } + snprintf((char *)st->trig->name, + IIO_TRIGGER_NAME_LENGTH, + "adis16240-dev%d", indio_dev->id); + st->trig->dev.parent = &st->us->dev; + st->trig->owner = THIS_MODULE; + st->trig->private_data = st; + st->trig->set_trigger_state = &adis16240_data_rdy_trigger_set_state; + st->trig->try_reenable = &adis16240_trig_try_reen; + st->trig->control_attrs = &adis16240_trigger_attr_group; + ret = iio_trigger_register(st->trig); + + /* select default trigger */ + indio_dev->trig = st->trig; + if (ret) + goto error_free_trig_name; + + return 0; + +error_free_trig_name: + kfree(st->trig->name); +error_free_trig: + iio_free_trigger(st->trig); + + return ret; +} + +void adis16240_remove_trigger(struct iio_dev *indio_dev) +{ + struct adis16240_state *state = indio_dev->dev_data; + + iio_trigger_unregister(state->trig); + kfree(state->trig->name); + iio_free_trigger(state->trig); +} -- cgit v1.2.3 From e390b07bc50fc96caa15c594374782e472c27419 Mon Sep 17 00:00:00 2001 From: Matthias Brugger Date: Fri, 7 May 2010 21:39:56 +0200 Subject: staging: adis16255 - TODO issues resolved and typos removed This patch adds the adis16255 driver to the build system under the staging directory. It solves also most issues mentioned in TODO list: - sample rate exported to sysfs - spi_adis16255_bringup and spi_adis16255_shutdown encapsulated - chip selftest in spi_adis16255_bringup - kernel messages reduced to a reasonable number I removed the TODO file, because ther was only the reset of the gyroscope left. This is IMOH not necessary for the actual driver. There are also some typos in adis.c file. This patch should get rid of them as well. Signed-off-by: Matthias Brugger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/adis16255/Kconfig | 10 +- drivers/staging/adis16255/Makefile | 2 +- drivers/staging/adis16255/TODO | 8 - drivers/staging/adis16255/adis16255.c | 354 ++++++++++++++++++++-------------- 6 files changed, 222 insertions(+), 155 deletions(-) delete mode 100644 drivers/staging/adis16255/TODO (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index e062b092073e..06d3b10d2a14 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -137,5 +137,7 @@ source "drivers/staging/cxt1e1/Kconfig" source "drivers/staging/ti-st/Kconfig" +source "drivers/staging/adis16255/Kconfig" + endif # !STAGING_EXCLUDE_BUILD endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 097c158d91f7..5526870777c6 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -49,3 +49,4 @@ obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/ obj-$(CONFIG_CRYSTALHD) += crystalhd/ obj-$(CONFIG_CXT1E1) += cxt1e1/ obj-$(CONFIG_TI_ST) += ti-st/ +obj-$(CONFIG_ADIS16255)) += adis16255/ diff --git a/drivers/staging/adis16255/Kconfig b/drivers/staging/adis16255/Kconfig index 3952cf95b783..a642be66adea 100644 --- a/drivers/staging/adis16255/Kconfig +++ b/drivers/staging/adis16255/Kconfig @@ -2,8 +2,10 @@ config ADIS16255 tristate "Ananlog Devices ADIS16250/16255" depends on SPI && SYSFS ---help--- - If you say yes here you get support for the Analog Devices - ADIS16250/16255 Low Power Gyroscope. + If you say yes here you get support for the Analog Devices + ADIS16250/16255 Low Power Gyroscope. The driver exposes + orientation and gyroscope value, as well as sample rate + to the sysfs. - This driver can also be built as a module. If so, the module - will be called adis16255. + This driver can also be built as a module. If so, the module + will be called adis16255. diff --git a/drivers/staging/adis16255/Makefile b/drivers/staging/adis16255/Makefile index 8057372d3781..8c3908106bfa 100644 --- a/drivers/staging/adis16255/Makefile +++ b/drivers/staging/adis16255/Makefile @@ -1 +1 @@ -obj-$(CONFIG_ADIS16255) += adis1625.o +obj-$(CONFIG_ADIS16255) += adis16255.o diff --git a/drivers/staging/adis16255/TODO b/drivers/staging/adis16255/TODO deleted file mode 100644 index 31e4ac3bdb61..000000000000 --- a/drivers/staging/adis16255/TODO +++ /dev/null @@ -1,8 +0,0 @@ -* sample rate changeable or at least readable from sysfs -* reset gyroscope -* encapsulate adis_init and adis_turn_off -* AD_CHK deletion -* chip selftest in adis_init -* reduce kernel messages to reasonable amount - -Contact: Matthias Brugger diff --git a/drivers/staging/adis16255/adis16255.c b/drivers/staging/adis16255/adis16255.c index 8d110692a030..1ba11f00b2e7 100644 --- a/drivers/staging/adis16255/adis16255.c +++ b/drivers/staging/adis16255/adis16255.c @@ -21,6 +21,14 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* + * The driver just has a bare interface to the sysfs (sample rate in Hz, + * orientation (x, y, z) and gyroscope data in °/sec. + * + * It should be added to iio subsystem when this has left staging. + * + */ + #include #include #include @@ -62,14 +70,13 @@ * @data: Last read data from device. * @irq_adis: GPIO Number of IRQ signal * @irq: irq line manage by kernel - * @negative: indicates if sensor is upside down (negative ÿ1) + * @negative: indicates if sensor is upside down (negative == 1) * @direction: indicates axis (x, y, z) the sensor is meassuring */ struct spi_adis16255_data { struct device dev; struct spi_device *spi; s16 data; - int irq_adis; int irq; u8 negative; char direction; @@ -81,47 +88,44 @@ static int spi_adis16255_read_data(struct spi_adis16255_data *spiadis, u8 adr, u8 *rbuf) { - struct spi_device *spi ÿpiadis->spi; + struct spi_device *spi = spiadis->spi; struct spi_message msg; struct spi_transfer xfer1, xfer2; u8 *buf, *rx; int ret; - buf ÿmalloc(4, GFP_KERNEL); - if (buf ÿNULL) + buf = kzalloc(4, GFP_KERNEL); + if (buf == NULL) return -ENOMEM; - rx ÿzalloc(4, GFP_KERNEL); - if (rx ÿNULL) { - ret ÿENOMEM; + rx = kzalloc(4, GFP_KERNEL); + if (rx == NULL) { + ret = -ENOMEM; goto err_buf; } - buf[0] údr; - buf[1] ðx00; - buf[2] ðx00; - buf[3] ðx00; + buf[0] = adr; spi_message_init(&msg); memset(&xfer1, 0, sizeof(xfer1)); memset(&xfer2, 0, sizeof(xfer2)); - xfer1.tx_buf ûuf; - xfer1.rx_buf ûuf + 2; - xfer1.len ò; - xfer1.delay_usecs ù; + xfer1.tx_buf = buf; + xfer1.rx_buf = buf + 2; + xfer1.len = 2; + xfer1.delay_usecs = 9; - xfer2.tx_buf ÿx + 2; - xfer2.rx_buf ÿx; - xfer2.len ò; + xfer2.tx_buf = rx + 2; + xfer2.rx_buf = rx; + xfer2.len = 2; spi_message_add_tail(&xfer1, &msg); spi_message_add_tail(&xfer2, &msg); - ret ÿpi_sync(spi, &msg); - if (ret ÿ0) { - rbuf[0] ÿx[0]; - rbuf[1] ÿx[1]; + ret = spi_sync(spi, &msg); + if (ret == 0) { + rbuf[0] = rx[0]; + rbuf[1] = rx[1]; } kfree(rx); @@ -136,19 +140,19 @@ static int spi_adis16255_write_data(struct spi_adis16255_data *spiadis, u8 adr2, u8 *wbuf) { - struct spi_device *spi ÿpiadis->spi; + struct spi_device *spi = spiadis->spi; struct spi_message msg; struct spi_transfer xfer1, xfer2; u8 *buf, *rx; int ret; - buf ÿmalloc(4, GFP_KERNEL); - if (buf ÿNULL) + buf = kmalloc(4, GFP_KERNEL); + if (buf == NULL) return -ENOMEM; - rx ÿzalloc(4, GFP_KERNEL); - if (rx ÿNULL) { - ret ÿENOMEM; + rx = kzalloc(4, GFP_KERNEL); + if (rx == NULL) { + ret = -ENOMEM; goto err_buf; } @@ -156,27 +160,27 @@ static int spi_adis16255_write_data(struct spi_adis16255_data *spiadis, memset(&xfer1, 0, sizeof(xfer1)); memset(&xfer2, 0, sizeof(xfer2)); - buf[0] údr1 | 0x80; - buf[1] ÿwbuf; + buf[0] = adr1 | 0x80; + buf[1] = *wbuf; - buf[2] údr2 | 0x80; - buf[3] ÿ(wbuf + 1); + buf[2] = adr2 | 0x80; + buf[3] = *(wbuf + 1); - xfer1.tx_buf ûuf; - xfer1.rx_buf ÿx; - xfer1.len ò; - xfer1.delay_usecs ù; + xfer1.tx_buf = buf; + xfer1.rx_buf = rx; + xfer1.len = 2; + xfer1.delay_usecs = 9; - xfer2.tx_buf ûuf+2; - xfer2.rx_buf ÿx+2; - xfer2.len ò; + xfer2.tx_buf = buf+2; + xfer2.rx_buf = rx+2; + xfer2.len = 2; spi_message_add_tail(&xfer1, &msg); spi_message_add_tail(&xfer2, &msg); - ret ÿpi_sync(spi, &msg); - if (ret !ð) - dev_warn(&spi->dev, "wirte data to %#x %#x failed\n", + ret = spi_sync(spi, &msg); + if (ret != 0) + dev_warn(&spi->dev, "write data to %#x %#x failed\n", buf[0], buf[2]); kfree(rx); @@ -189,29 +193,31 @@ err_buf: static irqreturn_t adis_irq_thread(int irq, void *dev_id) { - struct spi_adis16255_data *spiadis ýev_id; + struct spi_adis16255_data *spiadis = dev_id; int status; - u16 value; - - status ÿspi_adis16255_read_data(spiadis, ADIS_GYRO_OUT, (u8 *)&value); - if (status ÿ0) { - /* perform on new data only... */ - if (value & 0x8000) { - /* delete error and new data bit */ - value ÿalue & 0x3fff; - /* set negative value */ - if (value & 0x2000) - value ÿalue | 0xe000; - - if (likely(spiadis->negative)) - value ÿvalue; - - spiadis->data ÿs16) value; - } - } else { + u16 value = 0; + + status = spi_adis16255_read_data(spiadis, ADIS_GYRO_OUT, (u8 *)&value); + if (status != 0) { dev_warn(&spiadis->spi->dev, "SPI FAILED\n"); + goto exit; } + /* perform on new data only... */ + if (value & 0x8000) { + /* delete error and new data bit */ + value = value & 0x3fff; + /* set negative value */ + if (value & 0x2000) + value = value | 0xe000; + + if (likely(spiadis->negative)) + value = -value; + + spiadis->data = (s16) value; + } + +exit: return IRQ_HANDLED; } @@ -221,7 +227,7 @@ ssize_t adis16255_show_data(struct device *device, struct device_attribute *da, char *buf) { - struct spi_adis16255_data *spiadis ýev_get_drvdata(device); + struct spi_adis16255_data *spiadis = dev_get_drvdata(device); return snprintf(buf, PAGE_SIZE, "%d\n", spiadis->data); } DEVICE_ATTR(data, S_IRUGO , adis16255_show_data, NULL); @@ -230,112 +236,186 @@ ssize_t adis16255_show_direction(struct device *device, struct device_attribute *da, char *buf) { - struct spi_adis16255_data *spiadis ýev_get_drvdata(device); + struct spi_adis16255_data *spiadis = dev_get_drvdata(device); return snprintf(buf, PAGE_SIZE, "%c\n", spiadis->direction); } DEVICE_ATTR(direction, S_IRUGO , adis16255_show_direction, NULL); -static struct attribute *adis16255_attributes[] ÿ +ssize_t adis16255_show_sample_rate(struct device *device, + struct device_attribute *da, + char *buf) +{ + struct spi_adis16255_data *spiadis = dev_get_drvdata(device); + int status = 0; + u16 value = 0; + int ts = 0; + + status = spi_adis16255_read_data(spiadis, ADIS_SMPL_PRD_MSB, + (u8 *)&value); + if (status != 0) + return -EINVAL; + + if (value & 0x80) { + /* timebase = 60.54 ms */ + ts = 60540 * ((0x7f & value) + 1); + } else { + /* timebase = 1.953 ms */ + ts = 1953 * ((0x7f & value) + 1); + } + + return snprintf(buf, PAGE_SIZE, "%d\n", (1000*1000)/ts); +} +DEVICE_ATTR(sample_rate, S_IRUGO , adis16255_show_sample_rate, NULL); + +static struct attribute *adis16255_attributes[] = { &dev_attr_data.attr, &dev_attr_direction.attr, + &dev_attr_sample_rate.attr, NULL }; -static const struct attribute_group adis16255_attr_group ÿ - .attrs údis16255_attributes, +static const struct attribute_group adis16255_attr_group = { + .attrs = adis16255_attributes, }; /*-------------------------------------------------------------------------*/ -static int spi_adis16255_probe(struct spi_device *spi) +static int spi_adis16255_shutdown(struct spi_adis16255_data *spiadis) +{ + u16 value = 0; + /* turn sensor off */ + spi_adis16255_write_data(spiadis, + ADIS_SMPL_PRD_MSB, ADIS_SMPL_PRD_LSB, + (u8 *)&value); + spi_adis16255_write_data(spiadis, + ADIS_MSC_CTRL_MSB, ADIS_MSC_CTRL_LSB, + (u8 *)&value); + return 0; +} + +static int spi_adis16255_bringup(struct spi_adis16255_data *spiadis) { + int status = 0; + u16 value = 0; + + status = spi_adis16255_read_data(spiadis, ADIS_GYRO_SCALE, + (u8 *)&value); + if (status != 0) + goto err; + if (value != 0x0800) { + dev_warn(&spiadis->spi->dev, "Scale factor is none default" + "value (%.4x)\n", value); + } + + /* timebase = 1.953 ms, Ns = 0 -> 512 Hz sample rate */ + value = 0x0001; + status = spi_adis16255_write_data(spiadis, + ADIS_SMPL_PRD_MSB, ADIS_SMPL_PRD_LSB, + (u8 *)&value); + if (status != 0) + goto err; + + /* start internal self-test */ + value = 0x0400; + status = spi_adis16255_write_data(spiadis, + ADIS_MSC_CTRL_MSB, ADIS_MSC_CTRL_LSB, + (u8 *)&value); + if (status != 0) + goto err; + + /* wait 35 ms to finish self-test */ + msleep(35); + + value = 0x0000; + status = spi_adis16255_read_data(spiadis, ADIS_STATUS, + (u8 *)&value); + if (status != 0) + goto err; + + if (value & 0x23) { + if (value & 0x20) { + dev_warn(&spiadis->spi->dev, "self-test error\n"); + status = -ENODEV; + goto err; + } else if (value & 0x3) { + dev_warn(&spiadis->spi->dev, "Sensor voltage" + "out of range.\n"); + status = -ENODEV; + goto err; + } + } -#define AD_CHK(_ss)\ - do {\ - status ÿss;\ - if (status !ð)\ - goto irq_err;\ - } while (0); + /* set interrupt to active high on DIO0 when data ready */ + value = 0x0006; + status = spi_adis16255_write_data(spiadis, + ADIS_MSC_CTRL_MSB, ADIS_MSC_CTRL_LSB, + (u8 *)&value); + if (status != 0) + goto err; + return status; + +err: + spi_adis16255_shutdown(spiadis); + return status; +} + +/*-------------------------------------------------------------------------*/ - struct adis16255_init_data *init_data ÿpi->dev.platform_data; +static int spi_adis16255_probe(struct spi_device *spi) +{ + + struct adis16255_init_data *init_data = spi->dev.platform_data; struct spi_adis16255_data *spiadis; - int status ð; - u16 value; + int status = 0; - spiadis ÿzalloc(sizeof(*spiadis), GFP_KERNEL); + spiadis = kzalloc(sizeof(*spiadis), GFP_KERNEL); if (!spiadis) return -ENOMEM; - spiadis->spi ÿpi; - spiadis->irq_adis ÿnit_data->irq; - spiadis->direction ÿnit_data->direction; + spiadis->spi = spi; + spiadis->direction = init_data->direction; if (init_data->negative) - spiadis->negative ñ; + spiadis->negative = 1; - status ÿpio_request(spiadis->irq_adis, "adis16255"); - if (status !ð) + status = gpio_request(init_data->irq, "adis16255"); + if (status != 0) goto err; - status ÿpio_direction_input(spiadis->irq_adis); - if (status !ð) + status = gpio_direction_input(init_data->irq); + if (status != 0) goto gpio_err; - spiadis->irq ÿpio_to_irq(spiadis->irq_adis); + spiadis->irq = gpio_to_irq(init_data->irq); - status ÿequest_threaded_irq(spiadis->irq, + status = request_threaded_irq(spiadis->irq, NULL, adis_irq_thread, IRQF_DISABLED, "adis-driver", spiadis); - if (status !ð) { + if (status != 0) { dev_err(&spi->dev, "IRQ request failed\n"); goto gpio_err; } - dev_dbg(&spi->dev, "GPIO %d IRQ %d\n", spiadis->irq_adis, spiadis->irq); + dev_dbg(&spi->dev, "GPIO %d IRQ %d\n", init_data->irq, spiadis->irq); dev_set_drvdata(&spi->dev, spiadis); - AD_CHK(sysfs_create_group(&spi->dev.kobj, &adis16255_attr_group)); - - dev_info(&spi->dev, "spi_adis16255 driver added!\n"); + status = sysfs_create_group(&spi->dev.kobj, &adis16255_attr_group); + if (status != 0) + goto irq_err; - AD_CHK(spi_adis16255_read_data(spiadis, ADIS_SUPPLY_OUT, (u8 *)&value)); - dev_info(&spi->dev, "sensor works with %d mV (%.4x)!\n", - ((value & 0x0fff)*18315)/10000, - (value & 0x0fff)); + status = spi_adis16255_bringup(spiadis); + if (status != 0) + goto irq_err; - AD_CHK(spi_adis16255_read_data(spiadis, ADIS_GYRO_SCALE, (u8 *)&value)); - dev_info(&spi->dev, "adis GYRO_SCALE is %.4x\n", value); - - AD_CHK(spi_adis16255_read_data(spiadis, ADIS_STATUS, (u8 *)&value)); - dev_info(&spi->dev, "adis STATUS is %.4x\n", value); - - /* timebase ñ.953 ms, Ns ð -> 512 Hz sample rate */ - value ÿ0x0001; - AD_CHK(spi_adis16255_write_data(spiadis, - ADIS_SMPL_PRD_MSB, ADIS_SMPL_PRD_LSB, - (u8 *)&value)); - value ðx0000; - AD_CHK(spi_adis16255_read_data(spiadis, ADIS_SMPL_PRD_MSB, - (u8 *)&value)); - dev_info(&spi->dev, "adis SMP_PRD is %.4x\n", value); - - /* set interrupt on new data... */ - value ðx0006; - AD_CHK(spi_adis16255_write_data(spiadis, - ADIS_MSC_CTRL_MSB, ADIS_MSC_CTRL_LSB, - (u8 *)&value)); - value ðx0000; - AD_CHK(spi_adis16255_read_data(spiadis, ADIS_MSC_CTRL_MSB, - (u8 *)&value)); - dev_info(&spi->dev, "adis MSC_CONTROL is %.4x\n", value); + dev_info(&spi->dev, "spi_adis16255 driver added!\n"); return status; irq_err: free_irq(spiadis->irq, spiadis); gpio_err: - gpio_free(spiadis->irq_adis); + gpio_free(init_data->irq); err: kfree(spiadis); return status; @@ -343,22 +423,12 @@ err: static int spi_adis16255_remove(struct spi_device *spi) { - u16 value ð; - struct spi_adis16255_data *spiadis ýev_get_drvdata(&spi->dev); - - /* turn sensor off */ - spi_adis16255_write_data(spiadis, - ADIS_SMPL_PRD_MSB, ADIS_SMPL_PRD_LSB, - (u8 *)&value); - spi_adis16255_write_data(spiadis, - ADIS_MSC_CTRL_MSB, ADIS_MSC_CTRL_LSB, - (u8 *)&value); + struct spi_adis16255_data *spiadis = dev_get_drvdata(&spi->dev); - dev_info(&spi->dev, "unregister: GPIO %d IRQ %d\n", - spiadis->irq_adis, spiadis->irq); + spi_adis16255_shutdown(spiadis); free_irq(spiadis->irq, spiadis); - gpio_free(spiadis->irq_adis); + gpio_free(irq_to_gpio(spiadis->irq)); sysfs_remove_group(&spiadis->spi->dev.kobj, &adis16255_attr_group); @@ -368,13 +438,13 @@ static int spi_adis16255_remove(struct spi_device *spi) return 0; } -static struct spi_driver spi_adis16255_drv ÿ - .driver ÿ - .name ÿ"spi_adis16255", - .owner ÿHIS_MODULE, +static struct spi_driver spi_adis16255_drv = { + .driver = { + .name = "spi_adis16255", + .owner = THIS_MODULE, }, - .probe ÿpi_adis16255_probe, - .remove ÿ __devexit_p(spi_adis16255_remove), + .probe = spi_adis16255_probe, + .remove = __devexit_p(spi_adis16255_remove), }; /*-------------------------------------------------------------------------*/ -- cgit v1.2.3 From 7fb794b32cbd7e97e37628cb67279b86c1436e84 Mon Sep 17 00:00:00 2001 From: Charles Clément Date: Fri, 7 May 2010 12:30:18 -0700 Subject: Staging: vt6655: remove unused SUCCESS definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles Clément Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/ttype.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/ttype.h b/drivers/staging/vt6655/ttype.h index 4dfad04bb25a..dc061c6402e9 100644 --- a/drivers/staging/vt6655/ttype.h +++ b/drivers/staging/vt6655/ttype.h @@ -58,11 +58,6 @@ typedef int BOOL; #define FALSE 0 #endif - -#if !defined(SUCCESS) -#define SUCCESS 0 -#endif - //2007-0809-01by MikeLiu #ifndef update_BssList #define update_BssList -- cgit v1.2.3 From 512abd006d57f9e12905dae8d63c7b08474f8f87 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 11 May 2010 14:48:51 -0700 Subject: Staging: fix typo in Makefile This actually gets the adis16255 driver to build properly. Cc: Matthias Brugger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 5526870777c6..d5fdf1349815 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -49,4 +49,4 @@ obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/ obj-$(CONFIG_CRYSTALHD) += crystalhd/ obj-$(CONFIG_CXT1E1) += cxt1e1/ obj-$(CONFIG_TI_ST) += ti-st/ -obj-$(CONFIG_ADIS16255)) += adis16255/ +obj-$(CONFIG_ADIS16255) += adis16255/ -- cgit v1.2.3 From 6b35b7b3798b652a57fbce480f350aac851431c4 Mon Sep 17 00:00:00 2001 From: Charles Clément Date: Fri, 7 May 2010 12:30:19 -0700 Subject: Staging: vt6655: remove VOID definition and use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles Clément Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/80211mgr.c | 44 +++++++++--------- drivers/staging/vt6655/80211mgr.h | 44 +++++++++--------- drivers/staging/vt6655/baseband.c | 34 +++++++------- drivers/staging/vt6655/baseband.h | 26 +++++------ drivers/staging/vt6655/bssdb.c | 30 ++++++------ drivers/staging/vt6655/bssdb.h | 18 ++++---- drivers/staging/vt6655/card.c | 24 +++++----- drivers/staging/vt6655/card.h | 18 ++++---- drivers/staging/vt6655/datarate.c | 8 ++-- drivers/staging/vt6655/datarate.h | 4 +- drivers/staging/vt6655/device.h | 4 +- drivers/staging/vt6655/device_main.c | 6 +-- drivers/staging/vt6655/dpc.c | 10 ++-- drivers/staging/vt6655/dpc.h | 2 +- drivers/staging/vt6655/ioctl.c | 2 +- drivers/staging/vt6655/ioctl.h | 2 +- drivers/staging/vt6655/key.c | 8 ++-- drivers/staging/vt6655/key.h | 6 +-- drivers/staging/vt6655/mac.c | 8 ++-- drivers/staging/vt6655/mac.h | 52 ++++++++++----------- drivers/staging/vt6655/michael.c | 24 +++++----- drivers/staging/vt6655/michael.h | 8 ++-- drivers/staging/vt6655/power.c | 6 +-- drivers/staging/vt6655/power.h | 6 +-- drivers/staging/vt6655/rc4.c | 4 +- drivers/staging/vt6655/rc4.h | 2 +- drivers/staging/vt6655/rf.c | 2 +- drivers/staging/vt6655/rf.h | 2 +- drivers/staging/vt6655/rxtx.c | 24 +++++----- drivers/staging/vt6655/rxtx.h | 10 ++-- drivers/staging/vt6655/srom.h | 2 +- drivers/staging/vt6655/tkip.c | 2 +- drivers/staging/vt6655/tkip.h | 2 +- drivers/staging/vt6655/ttype.h | 4 -- drivers/staging/vt6655/vntwifi.c | 20 ++++---- drivers/staging/vt6655/vntwifi.h | 20 ++++---- drivers/staging/vt6655/wcmd.c | 12 ++--- drivers/staging/vt6655/wcmd.h | 8 ++-- drivers/staging/vt6655/wmgr.c | 90 ++++++++++++++++++------------------ drivers/staging/vt6655/wmgr.h | 20 ++++---- drivers/staging/vt6655/wpa.c | 4 +- drivers/staging/vt6655/wpa.h | 4 +- drivers/staging/vt6655/wpa2.c | 4 +- drivers/staging/vt6655/wpa2.h | 4 +- 44 files changed, 315 insertions(+), 319 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/80211mgr.c b/drivers/staging/vt6655/80211mgr.c index d309049370eb..da964a92f96b 100644 --- a/drivers/staging/vt6655/80211mgr.c +++ b/drivers/staging/vt6655/80211mgr.c @@ -89,7 +89,7 @@ static int msglevel =MSG_LEVEL_INFO; * -*/ -VOID +void vMgrEncodeBeacon( IN PWLAN_FR_BEACON pFrame ) @@ -121,7 +121,7 @@ vMgrEncodeBeacon( -*/ -VOID +void vMgrDecodeBeacon( IN PWLAN_FR_BEACON pFrame ) @@ -242,7 +242,7 @@ vMgrDecodeBeacon( -*/ -VOID +void vMgrEncodeIBSSATIM( IN PWLAN_FR_IBSSATIM pFrame ) @@ -265,7 +265,7 @@ vMgrEncodeIBSSATIM( * -*/ -VOID +void vMgrDecodeIBSSATIM( IN PWLAN_FR_IBSSATIM pFrame ) @@ -287,7 +287,7 @@ vMgrDecodeIBSSATIM( * -*/ -VOID +void vMgrEncodeDisassociation( IN PWLAN_FR_DISASSOC pFrame ) @@ -315,7 +315,7 @@ vMgrEncodeDisassociation( * -*/ -VOID +void vMgrDecodeDisassociation( IN PWLAN_FR_DISASSOC pFrame ) @@ -341,7 +341,7 @@ vMgrDecodeDisassociation( -*/ -VOID +void vMgrEncodeAssocRequest( IN PWLAN_FR_ASSOCREQ pFrame ) @@ -368,7 +368,7 @@ vMgrEncodeAssocRequest( * -*/ -VOID +void vMgrDecodeAssocRequest( IN PWLAN_FR_ASSOCREQ pFrame ) @@ -434,7 +434,7 @@ vMgrDecodeAssocRequest( * -*/ -VOID +void vMgrEncodeAssocResponse( IN PWLAN_FR_ASSOCRESP pFrame ) @@ -466,7 +466,7 @@ vMgrEncodeAssocResponse( * -*/ -VOID +void vMgrDecodeAssocResponse( IN PWLAN_FR_ASSOCRESP pFrame ) @@ -512,7 +512,7 @@ vMgrDecodeAssocResponse( * -*/ -VOID +void vMgrEncodeReassocRequest( IN PWLAN_FR_REASSOCREQ pFrame ) @@ -544,7 +544,7 @@ vMgrEncodeReassocRequest( -*/ -VOID +void vMgrDecodeReassocRequest( IN PWLAN_FR_REASSOCREQ pFrame ) @@ -616,7 +616,7 @@ vMgrDecodeReassocRequest( -*/ -VOID +void vMgrEncodeProbeRequest( IN PWLAN_FR_PROBEREQ pFrame ) @@ -637,7 +637,7 @@ vMgrEncodeProbeRequest( * -*/ -VOID +void vMgrDecodeProbeRequest( IN PWLAN_FR_PROBEREQ pFrame ) @@ -690,7 +690,7 @@ vMgrDecodeProbeRequest( -*/ -VOID +void vMgrEncodeProbeResponse( IN PWLAN_FR_PROBERESP pFrame ) @@ -724,7 +724,7 @@ vMgrEncodeProbeResponse( * -*/ -VOID +void vMgrDecodeProbeResponse( IN PWLAN_FR_PROBERESP pFrame ) @@ -838,7 +838,7 @@ vMgrDecodeProbeResponse( * -*/ -VOID +void vMgrEncodeAuthen( IN PWLAN_FR_AUTHEN pFrame ) @@ -869,7 +869,7 @@ vMgrEncodeAuthen( * -*/ -VOID +void vMgrDecodeAuthen( IN PWLAN_FR_AUTHEN pFrame ) @@ -909,7 +909,7 @@ vMgrDecodeAuthen( * -*/ -VOID +void vMgrEncodeDeauthen( IN PWLAN_FR_DEAUTHEN pFrame ) @@ -936,7 +936,7 @@ vMgrEncodeDeauthen( * -*/ -VOID +void vMgrDecodeDeauthen( IN PWLAN_FR_DEAUTHEN pFrame ) @@ -962,7 +962,7 @@ vMgrDecodeDeauthen( * -*/ -VOID +void vMgrEncodeReassocResponse( IN PWLAN_FR_REASSOCRESP pFrame ) @@ -995,7 +995,7 @@ vMgrEncodeReassocResponse( -*/ -VOID +void vMgrDecodeReassocResponse( IN PWLAN_FR_REASSOCRESP pFrame ) diff --git a/drivers/staging/vt6655/80211mgr.h b/drivers/staging/vt6655/80211mgr.h index 5efc13227eb8..c3eafd28da45 100644 --- a/drivers/staging/vt6655/80211mgr.h +++ b/drivers/staging/vt6655/80211mgr.h @@ -714,112 +714,112 @@ typedef struct tagWLAN_FR_DEAUTHEN { /*--------------------- Export Functions --------------------------*/ -VOID +void vMgrEncodeBeacon( IN PWLAN_FR_BEACON pFrame ); -VOID +void vMgrDecodeBeacon( IN PWLAN_FR_BEACON pFrame ); -VOID +void vMgrEncodeIBSSATIM( IN PWLAN_FR_IBSSATIM pFrame ); -VOID +void vMgrDecodeIBSSATIM( IN PWLAN_FR_IBSSATIM pFrame ); -VOID +void vMgrEncodeDisassociation( IN PWLAN_FR_DISASSOC pFrame ); -VOID +void vMgrDecodeDisassociation( IN PWLAN_FR_DISASSOC pFrame ); -VOID +void vMgrEncodeAssocRequest( IN PWLAN_FR_ASSOCREQ pFrame ); -VOID +void vMgrDecodeAssocRequest( IN PWLAN_FR_ASSOCREQ pFrame ); -VOID +void vMgrEncodeAssocResponse( IN PWLAN_FR_ASSOCRESP pFrame ); -VOID +void vMgrDecodeAssocResponse( IN PWLAN_FR_ASSOCRESP pFrame ); -VOID +void vMgrEncodeReassocRequest( IN PWLAN_FR_REASSOCREQ pFrame ); -VOID +void vMgrDecodeReassocRequest( IN PWLAN_FR_REASSOCREQ pFrame ); -VOID +void vMgrEncodeProbeRequest( IN PWLAN_FR_PROBEREQ pFrame ); -VOID +void vMgrDecodeProbeRequest( IN PWLAN_FR_PROBEREQ pFrame ); -VOID +void vMgrEncodeProbeResponse( IN PWLAN_FR_PROBERESP pFrame ); -VOID +void vMgrDecodeProbeResponse( IN PWLAN_FR_PROBERESP pFrame ); -VOID +void vMgrEncodeAuthen( IN PWLAN_FR_AUTHEN pFrame ); -VOID +void vMgrDecodeAuthen( IN PWLAN_FR_AUTHEN pFrame ); -VOID +void vMgrEncodeDeauthen( IN PWLAN_FR_DEAUTHEN pFrame ); -VOID +void vMgrDecodeDeauthen( IN PWLAN_FR_DEAUTHEN pFrame ); -VOID +void vMgrEncodeReassocResponse( IN PWLAN_FR_REASSOCRESP pFrame ); -VOID +void vMgrDecodeReassocResponse( IN PWLAN_FR_REASSOCRESP pFrame ); diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index cd5b8ea02538..16d7db350bb3 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -1723,13 +1723,13 @@ ULONG s_ulGetRatio(PSDevice pDevice); static -VOID +void s_vChangeAntenna( IN PSDevice pDevice ); static -VOID +void s_vChangeAntenna ( IN PSDevice pDevice ) @@ -1843,7 +1843,7 @@ BBuGetFrameTime ( * Return Value: none * */ -VOID +void BBvCaculateParameter ( IN PSDevice pDevice, IN UINT cbFrameLength, @@ -2321,7 +2321,7 @@ BOOL BBbVT3253Init (PSDevice pDevice) * Return Value: none * */ -VOID BBvReadAllRegs (DWORD_PTR dwIoBase, PBYTE pbyBBRegs) +void BBvReadAllRegs (DWORD_PTR dwIoBase, PBYTE pbyBBRegs) { int ii; BYTE byBase = 1; @@ -2438,7 +2438,7 @@ void BBvLoopbackOff (PSDevice pDevice) * Return Value: none * */ -VOID +void BBvSetShortSlotTime (PSDevice pDevice) { BYTE byBBRxConf=0; @@ -2462,7 +2462,7 @@ BBvSetShortSlotTime (PSDevice pDevice) } -VOID BBvSetVGAGainOffset(PSDevice pDevice, BYTE byData) +void BBvSetVGAGainOffset(PSDevice pDevice, BYTE byData) { BYTE byBBRxConf=0; @@ -2494,7 +2494,7 @@ VOID BBvSetVGAGainOffset(PSDevice pDevice, BYTE byData) * Return Value: none * */ -VOID +void BBvSoftwareReset (DWORD_PTR dwIoBase) { BBbWriteEmbeded(dwIoBase, 0x50, 0x40); @@ -2515,7 +2515,7 @@ BBvSoftwareReset (DWORD_PTR dwIoBase) * Return Value: none * */ -VOID +void BBvPowerSaveModeON (DWORD_PTR dwIoBase) { BYTE byOrgData; @@ -2537,7 +2537,7 @@ BBvPowerSaveModeON (DWORD_PTR dwIoBase) * Return Value: none * */ -VOID +void BBvPowerSaveModeOFF (DWORD_PTR dwIoBase) { BYTE byOrgData; @@ -2561,7 +2561,7 @@ BBvPowerSaveModeOFF (DWORD_PTR dwIoBase) * */ -VOID +void BBvSetTxAntennaMode (DWORD_PTR dwIoBase, BYTE byAntennaMode) { BYTE byBBTxConf; @@ -2603,7 +2603,7 @@ BBvSetTxAntennaMode (DWORD_PTR dwIoBase, BYTE byAntennaMode) * */ -VOID +void BBvSetRxAntennaMode (DWORD_PTR dwIoBase, BYTE byAntennaMode) { BYTE byBBRxConf; @@ -2634,14 +2634,14 @@ BBvSetRxAntennaMode (DWORD_PTR dwIoBase, BYTE byAntennaMode) * Return Value: none * */ -VOID +void BBvSetDeepSleep (DWORD_PTR dwIoBase, BYTE byLocalID) { BBbWriteEmbeded(dwIoBase, 0x0C, 0x17);//CR12 BBbWriteEmbeded(dwIoBase, 0x0D, 0xB9);//CR13 } -VOID +void BBvExitDeepSleep (DWORD_PTR dwIoBase, BYTE byLocalID) { BBbWriteEmbeded(dwIoBase, 0x0C, 0x00);//CR12 @@ -2759,7 +2759,7 @@ ULONG ulPacketNum; } -VOID +void BBvClearAntDivSQ3Value (PSDevice pDevice) { UINT ii; @@ -2786,7 +2786,7 @@ BBvClearAntDivSQ3Value (PSDevice pDevice) * */ -VOID +void BBvAntennaDiversity (PSDevice pDevice, BYTE byRxRate, BYTE bySQ3) { @@ -2876,7 +2876,7 @@ BBvAntennaDiversity (PSDevice pDevice, BYTE byRxRate, BYTE bySQ3) * -*/ -VOID +void TimerSQ3CallBack ( IN HANDLE hDeviceContext ) @@ -2924,7 +2924,7 @@ TimerSQ3CallBack ( * -*/ -VOID +void TimerState1CallBack ( IN HANDLE hDeviceContext ) diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index 0682a396ea44..de9b84acd6a9 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -126,7 +126,7 @@ BBuGetFrameTime( IN WORD wRate ); -VOID +void BBvCaculateParameter ( IN PSDevice pDevice, IN UINT cbFrameLength, @@ -140,38 +140,38 @@ BBvCaculateParameter ( BOOL BBbReadEmbeded(DWORD_PTR dwIoBase, BYTE byBBAddr, PBYTE pbyData); BOOL BBbWriteEmbeded(DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byData); -VOID BBvReadAllRegs(DWORD_PTR dwIoBase, PBYTE pbyBBRegs); +void BBvReadAllRegs(DWORD_PTR dwIoBase, PBYTE pbyBBRegs); void BBvLoopbackOn(PSDevice pDevice); void BBvLoopbackOff(PSDevice pDevice); void BBvSetShortSlotTime(PSDevice pDevice); BOOL BBbIsRegBitsOn(DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byTestBits); BOOL BBbIsRegBitsOff(DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byTestBits); -VOID BBvSetVGAGainOffset(PSDevice pDevice, BYTE byData); +void BBvSetVGAGainOffset(PSDevice pDevice, BYTE byData); // VT3253 Baseband BOOL BBbVT3253Init(PSDevice pDevice); -VOID BBvSoftwareReset(DWORD_PTR dwIoBase); -VOID BBvPowerSaveModeON(DWORD_PTR dwIoBase); -VOID BBvPowerSaveModeOFF(DWORD_PTR dwIoBase); -VOID BBvSetTxAntennaMode(DWORD_PTR dwIoBase, BYTE byAntennaMode); -VOID BBvSetRxAntennaMode(DWORD_PTR dwIoBase, BYTE byAntennaMode); -VOID BBvSetDeepSleep(DWORD_PTR dwIoBase, BYTE byLocalID); -VOID BBvExitDeepSleep(DWORD_PTR dwIoBase, BYTE byLocalID); +void BBvSoftwareReset(DWORD_PTR dwIoBase); +void BBvPowerSaveModeON(DWORD_PTR dwIoBase); +void BBvPowerSaveModeOFF(DWORD_PTR dwIoBase); +void BBvSetTxAntennaMode(DWORD_PTR dwIoBase, BYTE byAntennaMode); +void BBvSetRxAntennaMode(DWORD_PTR dwIoBase, BYTE byAntennaMode); +void BBvSetDeepSleep(DWORD_PTR dwIoBase, BYTE byLocalID); +void BBvExitDeepSleep(DWORD_PTR dwIoBase, BYTE byLocalID); // timer for antenna diversity -VOID +void TimerSQ3CallBack ( IN HANDLE hDeviceContext ); -VOID +void TimerState1CallBack( IN HANDLE hDeviceContext ); void BBvAntennaDiversity(PSDevice pDevice, BYTE byRxRate, BYTE bySQ3); -VOID +void BBvClearAntDivSQ3Value (PSDevice pDevice); #endif // __BASEBAND_H__ diff --git a/drivers/staging/vt6655/bssdb.c b/drivers/staging/vt6655/bssdb.c index 9535d4473c58..baa83e269fd4 100644 --- a/drivers/staging/vt6655/bssdb.c +++ b/drivers/staging/vt6655/bssdb.c @@ -90,18 +90,18 @@ const WORD awHWRetry1[5][5] = { /*--------------------- Static Functions --------------------------*/ -VOID s_vCheckSensitivity( +void s_vCheckSensitivity( IN HANDLE hDeviceContext ); #ifdef Calcu_LinkQual -VOID s_uCalculateLinkQual( +void s_uCalculateLinkQual( IN HANDLE hDeviceContext ); #endif -VOID s_vCheckPreEDThreshold( +void s_vCheckPreEDThreshold( IN HANDLE hDeviceContext ); /*--------------------- Export Variables --------------------------*/ @@ -280,7 +280,7 @@ if(pDevice->bLinkPass==FALSE) pCurrBSS->bSelected = FALSE; -*/ -VOID +void BSSvClearBSSList( IN HANDLE hDeviceContext, IN BOOL bKeepCurrBSSID @@ -797,7 +797,7 @@ BSSDBbIsSTAInNodeDB( * None * -*/ -VOID +void BSSvCreateOneNode( IN HANDLE hDeviceContext, OUT PUINT puNodeIndex @@ -862,7 +862,7 @@ BSSvCreateOneNode( * None * -*/ -VOID +void BSSvRemoveOneNode( IN HANDLE hDeviceContext, IN UINT uNodeIndex @@ -895,7 +895,7 @@ BSSvRemoveOneNode( * -*/ -VOID +void BSSvUpdateAPNode( IN HANDLE hDeviceContext, IN PWORD pwCapInfo, @@ -958,7 +958,7 @@ BSSvUpdateAPNode( -*/ -VOID +void BSSvAddMulticastNode( IN HANDLE hDeviceContext ) @@ -1011,7 +1011,7 @@ BSSvAddMulticastNode( BOOL cc=FALSE; UINT status; #endif -VOID +void BSSvSecondCallBack( IN HANDLE hDeviceContext ) @@ -1388,7 +1388,7 @@ start: -VOID +void BSSvUpdateNodeTxCounter( IN HANDLE hDeviceContext, IN BYTE byTsr0, @@ -1581,7 +1581,7 @@ BSSvUpdateNodeTxCounter( -*/ -VOID +void BSSvClearNodeDBTable( IN HANDLE hDeviceContext, IN UINT uStartIndex @@ -1610,7 +1610,7 @@ BSSvClearNodeDBTable( }; -VOID s_vCheckSensitivity( +void s_vCheckSensitivity( IN HANDLE hDeviceContext ) { @@ -1659,7 +1659,7 @@ VOID s_vCheckSensitivity( } -VOID +void BSSvClearAnyBSSJoinRecord ( IN HANDLE hDeviceContext ) @@ -1675,7 +1675,7 @@ BSSvClearAnyBSSJoinRecord ( } #ifdef Calcu_LinkQual -VOID s_uCalculateLinkQual( +void s_uCalculateLinkQual( IN HANDLE hDeviceContext ) { @@ -1723,7 +1723,7 @@ else } #endif -VOID s_vCheckPreEDThreshold( +void s_vCheckPreEDThreshold( IN HANDLE hDeviceContext ) { diff --git a/drivers/staging/vt6655/bssdb.h b/drivers/staging/vt6655/bssdb.h index 5ce4ef9c1bd1..86a1f6732902 100644 --- a/drivers/staging/vt6655/bssdb.h +++ b/drivers/staging/vt6655/bssdb.h @@ -257,7 +257,7 @@ BSSpAddrIsInBSSList( IN PWLAN_IE_SSID pSSID ); -VOID +void BSSvClearBSSList( IN HANDLE hDeviceContext, IN BOOL bKeepCurrBSSID @@ -315,13 +315,13 @@ BSSDBbIsSTAInNodeDB( OUT PUINT puNodeIndex ); -VOID +void BSSvCreateOneNode( IN HANDLE hDeviceContext, OUT PUINT puNodeIndex ); -VOID +void BSSvUpdateAPNode( IN HANDLE hDeviceContext, IN PWORD pwCapInfo, @@ -330,13 +330,13 @@ BSSvUpdateAPNode( ); -VOID +void BSSvSecondCallBack( IN HANDLE hDeviceContext ); -VOID +void BSSvUpdateNodeTxCounter( IN HANDLE hDeviceContext, IN BYTE byTsr0, @@ -345,25 +345,25 @@ BSSvUpdateNodeTxCounter( IN UINT uFIFOHeaderSize ); -VOID +void BSSvRemoveOneNode( IN HANDLE hDeviceContext, IN UINT uNodeIndex ); -VOID +void BSSvAddMulticastNode( IN HANDLE hDeviceContext ); -VOID +void BSSvClearNodeDBTable( IN HANDLE hDeviceContext, IN UINT uStartIndex ); -VOID +void BSSvClearAnyBSSJoinRecord( IN HANDLE hDeviceContext ); diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index bf4fd49709df..091fbeabb6d5 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -423,7 +423,7 @@ SCountryTable ChannelRuleTab[CCODE_MAX+1] = /*--------------------- Static Functions --------------------------*/ static -VOID +void s_vCaculateOFDMRParameter( IN BYTE byRate, IN CARD_PHY_TYPE ePHYType, @@ -496,7 +496,7 @@ exit: * */ static -VOID +void s_vCaculateOFDMRParameter ( IN BYTE byRate, IN CARD_PHY_TYPE ePHYType, @@ -611,7 +611,7 @@ s_vCaculateOFDMRParameter ( * */ static -VOID +void s_vSetRSPINF (PSDevice pDevice, CARD_PHY_TYPE ePHYType, PVOID pvSupportRateIEs, PVOID pvExtSupportRateIEs) { BYTE byServ = 0, bySignal = 0; // For CCK @@ -1611,7 +1611,7 @@ CARDpGetCurrentAddress ( -VOID CARDvInitChannelTable (PVOID pDeviceHandler) +void CARDvInitChannelTable (PVOID pDeviceHandler) { PSDevice pDevice = (PSDevice) pDeviceHandler; BOOL bMultiBand = FALSE; @@ -2033,7 +2033,7 @@ CARDbStartQuiet ( * Return Value: none. * -*/ -VOID +void CARDvSetCountryInfo ( IN PVOID pDeviceHandler, IN CARD_PHY_TYPE ePHYType, @@ -2092,7 +2092,7 @@ CARDvSetCountryInfo ( * Return Value: none. * -*/ -VOID +void CARDvSetPowerConstraint ( IN PVOID pDeviceHandler, IN BYTE byChannel, @@ -2127,7 +2127,7 @@ CARDvSetPowerConstraint ( * Return Value: none. * -*/ -VOID +void CARDvGetPowerCapability ( IN PVOID pDeviceHandler, OUT PBYTE pbyMinPower, @@ -2279,7 +2279,7 @@ CARDbChannelGetList ( } -VOID +void CARDvSetCountryIE( IN PVOID pDeviceHandler, IN PVOID pIE @@ -2324,7 +2324,7 @@ CARDbGetChannelMapInfo( } -VOID +void CARDvSetChannelMapInfo( IN PVOID pDeviceHandler, IN UINT uChannelIndex, @@ -2340,7 +2340,7 @@ CARDvSetChannelMapInfo( } -VOID +void CARDvClearChannelMapInfo( IN PVOID pDeviceHandler ) @@ -2420,7 +2420,7 @@ CARDbyAutoChannelSelect( //xxx -VOID +void CARDvSafeResetTx ( IN PVOID pDeviceHandler ) @@ -2476,7 +2476,7 @@ CARDvSafeResetTx ( * Return Value: none * -*/ -VOID +void CARDvSafeResetRx ( IN PVOID pDeviceHandler ) diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h index 264b844cf055..6a9980d720a9 100644 --- a/drivers/staging/vt6655/card.h +++ b/drivers/staging/vt6655/card.h @@ -101,8 +101,8 @@ QWORD CARDqGetNextTBTT(QWORD qwTSF, WORD wBeaconInterval); QWORD CARDqGetTSFOffset(BYTE byRxRate, QWORD qwTSF1, QWORD qwTSF2); BOOL CARDbSetTxPower(PVOID pDeviceHandler, ULONG ulTxPower); BYTE CARDbyGetPktType(PVOID pDeviceHandler); -VOID CARDvSafeResetTx(PVOID pDeviceHandler); -VOID CARDvSafeResetRx(PVOID pDeviceHandler); +void CARDvSafeResetTx(PVOID pDeviceHandler); +void CARDvSafeResetRx(PVOID pDeviceHandler); //xxx BOOL CARDbRadioPowerOff(PVOID pDeviceHandler); @@ -145,7 +145,7 @@ CARDpGetCurrentAddress ( ); -VOID CARDvInitChannelTable(PVOID pDeviceHandler); +void CARDvInitChannelTable(PVOID pDeviceHandler); BYTE CARDbyGetChannelMapping(PVOID pDeviceHandler, BYTE byChannelNumber, CARD_PHY_TYPE ePhyType); BOOL @@ -178,21 +178,21 @@ CARDbStartQuiet ( IN PVOID pDeviceHandler ); -VOID +void CARDvSetCountryInfo ( IN PVOID pDeviceHandler, IN CARD_PHY_TYPE ePHYType, IN PVOID pIE ); -VOID +void CARDvSetPowerConstraint ( IN PVOID pDeviceHandler, IN BYTE byChannel, IN I8 byPower ); -VOID +void CARDvGetPowerCapability ( IN PVOID pDeviceHandler, OUT PBYTE pbyMinPower, @@ -216,7 +216,7 @@ CARDbChannelGetList ( OUT PBYTE pbyChannelTable ); -VOID +void CARDvSetCountryIE( IN PVOID pDeviceHandler, IN PVOID pIE @@ -230,14 +230,14 @@ CARDbGetChannelMapInfo( OUT PBYTE pbyMap ); -VOID +void CARDvSetChannelMapInfo( IN PVOID pDeviceHandler, IN UINT uChannelIndex, IN BYTE byMap ); -VOID +void CARDvClearChannelMapInfo( IN PVOID pDeviceHandler ); diff --git a/drivers/staging/vt6655/datarate.c b/drivers/staging/vt6655/datarate.c index 10da57f28449..eb7653cdb57c 100644 --- a/drivers/staging/vt6655/datarate.c +++ b/drivers/staging/vt6655/datarate.c @@ -64,13 +64,13 @@ const BYTE acbyIERate[MAX_RATE] = /*--------------------- Static Functions --------------------------*/ -VOID s_vResetCounter ( +void s_vResetCounter ( IN PKnownNodeDB psNodeDBTable ); -VOID +void s_vResetCounter ( IN PKnownNodeDB psNodeDBTable ) @@ -194,7 +194,7 @@ wGetRateIdx( * Return Value: none * -*/ -VOID +void RATEvParseMaxRate ( IN PVOID pDeviceHandler, IN PWLAN_IE_SUPP_RATES pItemRates, @@ -307,7 +307,7 @@ UINT uRateLen; #define AUTORATE_TXCNT_THRESHOLD 20 #define AUTORATE_INC_THRESHOLD 30 -VOID +void RATEvTxRateFallBack ( IN PVOID pDeviceHandler, IN PKnownNodeDB psNodeDBTable diff --git a/drivers/staging/vt6655/datarate.h b/drivers/staging/vt6655/datarate.h index 5096f3df4993..1135fe3e6f89 100644 --- a/drivers/staging/vt6655/datarate.h +++ b/drivers/staging/vt6655/datarate.h @@ -54,7 +54,7 @@ -VOID +void RATEvParseMaxRate( IN PVOID pDeviceHandler, IN PWLAN_IE_SUPP_RATES pItemRates, @@ -67,7 +67,7 @@ RATEvParseMaxRate( OUT PBYTE pbyTopOFDMRate ); -VOID +void RATEvTxRateFallBack( IN PVOID pDeviceHandler, IN PKnownNodeDB psNodeDBTable diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index 7a9f40695f2d..0ea24f25cdf9 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -828,7 +828,7 @@ typedef struct __device_info { //PLICE_DEBUG-> - inline static VOID EnQueue (PSDevice pDevice,PSRxMgmtPacket pRxMgmtPacket) + inline static void EnQueue (PSDevice pDevice,PSRxMgmtPacket pRxMgmtPacket) { //printk("Enter EnQueue:tail is %d\n",pDevice->rxManeQueue.tail); if ((pDevice->rxManeQueue.tail+1) % NUM == pDevice->rxManeQueue.head) @@ -869,7 +869,7 @@ typedef struct __device_info { } } -VOID InitRxManagementQueue(PSDevice pDevice); +void InitRxManagementQueue(PSDevice pDevice); diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index f1d70e133d16..90ebad15c3dc 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -478,7 +478,7 @@ pDevice->bUpdateBBVGA = TRUE; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->bDiversityRegCtlON= %d\n",(INT)pDevice->bDiversityRegCtlON); } -static VOID s_vCompleteCurrentMeasure (IN PSDevice pDevice, IN BYTE byResult) +static void s_vCompleteCurrentMeasure (IN PSDevice pDevice, IN BYTE byResult) { UINT ii; DWORD dwDuration = 0; @@ -847,7 +847,7 @@ else CARDbRadioPowerOn(pDevice); -static VOID device_init_diversity_timer(PSDevice pDevice) { +static void device_init_diversity_timer(PSDevice pDevice) { init_timer(&pDevice->TimerSQ3Tmax1); pDevice->TimerSQ3Tmax1.data = (ULONG)pDevice; @@ -1830,7 +1830,7 @@ static void device_free_tx_buf(PSDevice pDevice, PSTxDesc pDesc) { //PLICE_DEBUG -> -VOID InitRxManagementQueue(PSDevice pDevice) +void InitRxManagementQueue(PSDevice pDevice) { pDevice->rxManeQueue.packet_num = 0; pDevice->rxManeQueue.head = pDevice->rxManeQueue.tail = 0; diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index 67f238c01b44..58dced747fa2 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -80,7 +80,7 @@ static BYTE s_byGetRateIdx(IN BYTE byRate); static -VOID +void s_vGetDASA( IN PBYTE pbyRxBufferAddr, OUT PUINT pcbHeaderSize, @@ -88,7 +88,7 @@ s_vGetDASA( ); static -VOID +void s_vProcessRxMACHeader ( IN PSDevice pDevice, IN PBYTE pbyRxBufferAddr, @@ -163,7 +163,7 @@ static BOOL s_bHostWepRxEncryption( * -*/ static -VOID +void s_vProcessRxMACHeader ( IN PSDevice pDevice, IN PBYTE pbyRxBufferAddr, @@ -262,7 +262,7 @@ static BYTE s_byGetRateIdx (IN BYTE byRate) static -VOID +void s_vGetDASA ( IN PBYTE pbyRxBufferAddr, OUT PUINT pcbHeaderSize, @@ -314,7 +314,7 @@ s_vGetDASA ( //PLICE_DEBUG -> -VOID MngWorkItem(PVOID Context) +void MngWorkItem(PVOID Context) { PSRxMgmtPacket pRxMgmtPacket; PSDevice pDevice = (PSDevice) Context; diff --git a/drivers/staging/vt6655/dpc.h b/drivers/staging/vt6655/dpc.h index 51508b9087ea..0860ea529693 100644 --- a/drivers/staging/vt6655/dpc.h +++ b/drivers/staging/vt6655/dpc.h @@ -47,7 +47,7 @@ device_receive_frame ( IN PSRxDesc pCurrRD ); -VOID MngWorkItem(PVOID Context); +void MngWorkItem(PVOID Context); #endif // __RXTX_H__ diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c index 37928e844010..86439bb629f9 100644 --- a/drivers/staging/vt6655/ioctl.c +++ b/drivers/staging/vt6655/ioctl.c @@ -714,7 +714,7 @@ if(wpa_Result.authenticated==TRUE) { } /* -VOID +void vConfigWEPKey ( IN PSDevice pDevice, IN DWORD dwKeyIndex, diff --git a/drivers/staging/vt6655/ioctl.h b/drivers/staging/vt6655/ioctl.h index 07d228399c3c..dc278aeb7eac 100644 --- a/drivers/staging/vt6655/ioctl.h +++ b/drivers/staging/vt6655/ioctl.h @@ -43,7 +43,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq); /* -VOID vConfigWEPKey ( +void vConfigWEPKey ( IN PSDevice pDevice, IN DWORD dwKeyIndex, IN PBYTE pbyKey, diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c index a4d2184d826d..efff7db8aaf9 100644 --- a/drivers/staging/vt6655/key.c +++ b/drivers/staging/vt6655/key.c @@ -58,7 +58,7 @@ static int msglevel =MSG_LEVEL_INFO; /*--------------------- Static Variables --------------------------*/ /*--------------------- Static Functions --------------------------*/ -static VOID +static void s_vCheckKeyTableValid (PSKeyManagement pTable, DWORD_PTR dwIoBase) { int i; @@ -96,7 +96,7 @@ s_vCheckKeyTableValid (PSKeyManagement pTable, DWORD_PTR dwIoBase) * Return Value: none * */ -VOID KeyvInitTable (PSKeyManagement pTable, DWORD_PTR dwIoBase) +void KeyvInitTable (PSKeyManagement pTable, DWORD_PTR dwIoBase) { int i; int jj; @@ -470,7 +470,7 @@ BOOL KeybRemoveAllKey ( * Return Value: TRUE if success otherwise FALSE * */ -VOID KeyvRemoveWEPKey ( +void KeyvRemoveWEPKey ( PSKeyManagement pTable, DWORD dwKeyIndex, DWORD_PTR dwIoBase @@ -492,7 +492,7 @@ VOID KeyvRemoveWEPKey ( return; } -VOID KeyvRemoveAllWEPKey ( +void KeyvRemoveAllWEPKey ( PSKeyManagement pTable, DWORD_PTR dwIoBase ) diff --git a/drivers/staging/vt6655/key.h b/drivers/staging/vt6655/key.h index ba797c7b3c17..766ff049553d 100644 --- a/drivers/staging/vt6655/key.h +++ b/drivers/staging/vt6655/key.h @@ -101,7 +101,7 @@ typedef struct tagSKeyManagement /*--------------------- Export Functions --------------------------*/ -VOID KeyvInitTable(PSKeyManagement pTable, DWORD_PTR dwIoBase); +void KeyvInitTable(PSKeyManagement pTable, DWORD_PTR dwIoBase); BOOL KeybGetKey( IN PSKeyManagement pTable, @@ -158,13 +158,13 @@ BOOL KeybRemoveAllKey( DWORD_PTR dwIoBase ); -VOID KeyvRemoveWEPKey( +void KeyvRemoveWEPKey( PSKeyManagement pTable, DWORD dwKeyIndex, DWORD_PTR dwIoBase ); -VOID KeyvRemoveAllWEPKey( +void KeyvRemoveAllWEPKey( PSKeyManagement pTable, DWORD_PTR dwIoBase ); diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c index cdd7cd5e4095..f1ef7da75c2b 100644 --- a/drivers/staging/vt6655/mac.c +++ b/drivers/staging/vt6655/mac.c @@ -103,7 +103,7 @@ static int msglevel =MSG_LEVEL_INFO; * Return Value: none * */ -VOID MACvReadAllRegs (DWORD_PTR dwIoBase, PBYTE pbyMacRegs) +void MACvReadAllRegs (DWORD_PTR dwIoBase, PBYTE pbyMacRegs) { int ii; @@ -234,7 +234,7 @@ BYTE MACbyReadMultiAddr (DWORD_PTR dwIoBase, UINT uByteIdx) * Return Value: none * */ -VOID MACvWriteMultiAddr (DWORD_PTR dwIoBase, UINT uByteIdx, BYTE byData) +void MACvWriteMultiAddr (DWORD_PTR dwIoBase, UINT uByteIdx, BYTE byData) { MACvSelectPage1(dwIoBase); VNSvOutPortB(dwIoBase + MAC_REG_MAR0 + uByteIdx, byData); @@ -676,7 +676,7 @@ void MACvSaveContext (DWORD_PTR dwIoBase, PBYTE pbyCxtBuf) * Return Value: none * */ -VOID MACvRestoreContext (DWORD_PTR dwIoBase, PBYTE pbyCxtBuf) +void MACvRestoreContext (DWORD_PTR dwIoBase, PBYTE pbyCxtBuf) { int ii; @@ -1244,7 +1244,7 @@ void MACvSetCurrTXDescAddr (int iTxType, DWORD_PTR dwIoBase, DWORD dwCurrDescAdd * Return Value: none * */ -VOID MACvTimer0MicroSDelay (DWORD_PTR dwIoBase, UINT uDelay) +void MACvTimer0MicroSDelay (DWORD_PTR dwIoBase, UINT uDelay) { BYTE byValue; UINT uu,ii; diff --git a/drivers/staging/vt6655/mac.h b/drivers/staging/vt6655/mac.h index 3ba87fb64d3c..5eb7f57f7182 100644 --- a/drivers/staging/vt6655/mac.h +++ b/drivers/staging/vt6655/mac.h @@ -1075,7 +1075,7 @@ /*--------------------- Export Functions --------------------------*/ extern WORD TxRate_iwconfig;//2008-5-8 by chester -VOID MACvReadAllRegs(DWORD_PTR dwIoBase, PBYTE pbyMacRegs); +void MACvReadAllRegs(DWORD_PTR dwIoBase, PBYTE pbyMacRegs); BOOL MACbIsRegBitsOn(DWORD_PTR dwIoBase, BYTE byRegOfs, BYTE byTestBits); BOOL MACbIsRegBitsOff(DWORD_PTR dwIoBase, BYTE byRegOfs, BYTE byTestBits); @@ -1083,32 +1083,32 @@ BOOL MACbIsRegBitsOff(DWORD_PTR dwIoBase, BYTE byRegOfs, BYTE byTestBits); BOOL MACbIsIntDisable(DWORD_PTR dwIoBase); BYTE MACbyReadMultiAddr(DWORD_PTR dwIoBase, UINT uByteIdx); -VOID MACvWriteMultiAddr(DWORD_PTR dwIoBase, UINT uByteIdx, BYTE byData); -VOID MACvSetMultiAddrByHash(DWORD_PTR dwIoBase, BYTE byHashIdx); -VOID MACvResetMultiAddrByHash(DWORD_PTR dwIoBase, BYTE byHashIdx); +void MACvWriteMultiAddr(DWORD_PTR dwIoBase, UINT uByteIdx, BYTE byData); +void MACvSetMultiAddrByHash(DWORD_PTR dwIoBase, BYTE byHashIdx); +void MACvResetMultiAddrByHash(DWORD_PTR dwIoBase, BYTE byHashIdx); -VOID MACvSetRxThreshold(DWORD_PTR dwIoBase, BYTE byThreshold); -VOID MACvGetRxThreshold(DWORD_PTR dwIoBase, PBYTE pbyThreshold); +void MACvSetRxThreshold(DWORD_PTR dwIoBase, BYTE byThreshold); +void MACvGetRxThreshold(DWORD_PTR dwIoBase, PBYTE pbyThreshold); -VOID MACvSetTxThreshold(DWORD_PTR dwIoBase, BYTE byThreshold); -VOID MACvGetTxThreshold(DWORD_PTR dwIoBase, PBYTE pbyThreshold); +void MACvSetTxThreshold(DWORD_PTR dwIoBase, BYTE byThreshold); +void MACvGetTxThreshold(DWORD_PTR dwIoBase, PBYTE pbyThreshold); -VOID MACvSetDmaLength(DWORD_PTR dwIoBase, BYTE byDmaLength); -VOID MACvGetDmaLength(DWORD_PTR dwIoBase, PBYTE pbyDmaLength); +void MACvSetDmaLength(DWORD_PTR dwIoBase, BYTE byDmaLength); +void MACvGetDmaLength(DWORD_PTR dwIoBase, PBYTE pbyDmaLength); -VOID MACvSetShortRetryLimit(DWORD_PTR dwIoBase, BYTE byRetryLimit); -VOID MACvGetShortRetryLimit(DWORD_PTR dwIoBase, PBYTE pbyRetryLimit); +void MACvSetShortRetryLimit(DWORD_PTR dwIoBase, BYTE byRetryLimit); +void MACvGetShortRetryLimit(DWORD_PTR dwIoBase, PBYTE pbyRetryLimit); -VOID MACvSetLongRetryLimit(DWORD_PTR dwIoBase, BYTE byRetryLimit); -VOID MACvGetLongRetryLimit(DWORD_PTR dwIoBase, PBYTE pbyRetryLimit); +void MACvSetLongRetryLimit(DWORD_PTR dwIoBase, BYTE byRetryLimit); +void MACvGetLongRetryLimit(DWORD_PTR dwIoBase, PBYTE pbyRetryLimit); -VOID MACvSetLoopbackMode(DWORD_PTR dwIoBase, BYTE byLoopbackMode); +void MACvSetLoopbackMode(DWORD_PTR dwIoBase, BYTE byLoopbackMode); BOOL MACbIsInLoopbackMode(DWORD_PTR dwIoBase); -VOID MACvSetPacketFilter(DWORD_PTR dwIoBase, WORD wFilterType); +void MACvSetPacketFilter(DWORD_PTR dwIoBase, WORD wFilterType); -VOID MACvSaveContext(DWORD_PTR dwIoBase, PBYTE pbyCxtBuf); -VOID MACvRestoreContext(DWORD_PTR dwIoBase, PBYTE pbyCxtBuf); +void MACvSaveContext(DWORD_PTR dwIoBase, PBYTE pbyCxtBuf); +void MACvRestoreContext(DWORD_PTR dwIoBase, PBYTE pbyCxtBuf); BOOL MACbCompareContext(DWORD_PTR dwIoBase, PBYTE pbyCxtBuf); BOOL MACbSoftwareReset(DWORD_PTR dwIoBase); @@ -1117,14 +1117,14 @@ BOOL MACbSafeRxOff(DWORD_PTR dwIoBase); BOOL MACbSafeTxOff(DWORD_PTR dwIoBase); BOOL MACbSafeStop(DWORD_PTR dwIoBase); BOOL MACbShutdown(DWORD_PTR dwIoBase); -VOID MACvInitialize(DWORD_PTR dwIoBase); -VOID MACvSetCurrRx0DescAddr(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr); -VOID MACvSetCurrRx1DescAddr(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr); -VOID MACvSetCurrTXDescAddr(int iTxType, DWORD_PTR dwIoBase, DWORD dwCurrDescAddr); -VOID MACvSetCurrTx0DescAddrEx(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr); -VOID MACvSetCurrAC0DescAddrEx(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr); -VOID MACvSetCurrSyncDescAddrEx(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr); -VOID MACvSetCurrATIMDescAddrEx(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr); +void MACvInitialize(DWORD_PTR dwIoBase); +void MACvSetCurrRx0DescAddr(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr); +void MACvSetCurrRx1DescAddr(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr); +void MACvSetCurrTXDescAddr(int iTxType, DWORD_PTR dwIoBase, DWORD dwCurrDescAddr); +void MACvSetCurrTx0DescAddrEx(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr); +void MACvSetCurrAC0DescAddrEx(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr); +void MACvSetCurrSyncDescAddrEx(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr); +void MACvSetCurrATIMDescAddrEx(DWORD_PTR dwIoBase, DWORD dwCurrDescAddr); void MACvTimer0MicroSDelay(DWORD_PTR dwIoBase, UINT uDelay); void MACvOneShotTimer0MicroSec(DWORD_PTR dwIoBase, UINT uDelayTime); void MACvOneShotTimer1MicroSec(DWORD_PTR dwIoBase, UINT uDelayTime); diff --git a/drivers/staging/vt6655/michael.c b/drivers/staging/vt6655/michael.c index c930e0cdb853..0bf57efdede0 100644 --- a/drivers/staging/vt6655/michael.c +++ b/drivers/staging/vt6655/michael.c @@ -49,12 +49,12 @@ /*--------------------- Static Functions --------------------------*/ /* static DWORD s_dwGetUINT32(BYTE * p); // Get DWORD from 4 bytes LSByte first -static VOID s_vPutUINT32(BYTE* p, DWORD val); // Put DWORD into 4 bytes LSByte first +static void s_vPutUINT32(BYTE* p, DWORD val); // Put DWORD into 4 bytes LSByte first */ -static VOID s_vClear(void); // Clear the internal message, +static void s_vClear(void); // Clear the internal message, // resets the object to the state just after construction. -static VOID s_vSetKey(DWORD dwK0, DWORD dwK1); -static VOID s_vAppendByte(BYTE b); // Add a single byte to the internal message +static void s_vSetKey(DWORD dwK0, DWORD dwK1); +static void s_vAppendByte(BYTE b); // Add a single byte to the internal message /*--------------------- Export Variables --------------------------*/ static DWORD L, R; // Current state @@ -78,7 +78,7 @@ static DWORD s_dwGetUINT32 (BYTE * p) return res; } -static VOID s_vPutUINT32 (BYTE* p, DWORD val) +static void s_vPutUINT32 (BYTE* p, DWORD val) // Convert from DWORD to BYTE[] in a portable way { UINT i; @@ -90,7 +90,7 @@ static VOID s_vPutUINT32 (BYTE* p, DWORD val) } */ -static VOID s_vClear (void) +static void s_vClear (void) { // Reset the state to the empty message. L = K0; @@ -99,7 +99,7 @@ static VOID s_vClear (void) M = 0; } -static VOID s_vSetKey (DWORD dwK0, DWORD dwK1) +static void s_vSetKey (DWORD dwK0, DWORD dwK1) { // Set the key K0 = dwK0; @@ -108,7 +108,7 @@ static VOID s_vSetKey (DWORD dwK0, DWORD dwK1) s_vClear(); } -static VOID s_vAppendByte (BYTE b) +static void s_vAppendByte (BYTE b) { // Append the byte to our word-sized buffer M |= b << (8*nBytesInM); @@ -131,14 +131,14 @@ static VOID s_vAppendByte (BYTE b) } } -VOID MIC_vInit (DWORD dwK0, DWORD dwK1) +void MIC_vInit (DWORD dwK0, DWORD dwK1) { // Set the key s_vSetKey(dwK0, dwK1); } -VOID MIC_vUnInit (void) +void MIC_vUnInit (void) { // Wipe the key material K0 = 0; @@ -149,7 +149,7 @@ VOID MIC_vUnInit (void) s_vClear(); } -VOID MIC_vAppend (PBYTE src, UINT nBytes) +void MIC_vAppend (PBYTE src, UINT nBytes) { // This is simple while (nBytes > 0) @@ -159,7 +159,7 @@ VOID MIC_vAppend (PBYTE src, UINT nBytes) } } -VOID MIC_vGetMIC (PDWORD pdwL, PDWORD pdwR) +void MIC_vGetMIC (PDWORD pdwL, PDWORD pdwR) { // Append the minimum padding s_vAppendByte(0x5a); diff --git a/drivers/staging/vt6655/michael.h b/drivers/staging/vt6655/michael.h index 3f79b52832d1..97de77b4da2c 100644 --- a/drivers/staging/vt6655/michael.h +++ b/drivers/staging/vt6655/michael.h @@ -35,16 +35,16 @@ /*--------------------- Export Types ------------------------------*/ -VOID MIC_vInit(DWORD dwK0, DWORD dwK1); +void MIC_vInit(DWORD dwK0, DWORD dwK1); -VOID MIC_vUnInit(void); +void MIC_vUnInit(void); // Append bytes to the message to be MICed -VOID MIC_vAppend(PBYTE src, UINT nBytes); +void MIC_vAppend(PBYTE src, UINT nBytes); // Get the MIC result. Destination should accept 8 bytes of result. // This also resets the message to empty. -VOID MIC_vGetMIC(PDWORD pdwL, PDWORD pdwR); +void MIC_vGetMIC(PDWORD pdwL, PDWORD pdwR); /*--------------------- Export Macros ------------------------------*/ diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c index 84eda0455381..a28d03762e4e 100644 --- a/drivers/staging/vt6655/power.c +++ b/drivers/staging/vt6655/power.c @@ -74,7 +74,7 @@ static int msglevel =MSG_LEVEL_INFO; -*/ -VOID +void PSvEnablePowerSaving( IN HANDLE hDeviceContext, IN WORD wListenInterval @@ -144,7 +144,7 @@ PSvEnablePowerSaving( * -*/ -VOID +void PSvDisablePowerSaving( IN HANDLE hDeviceContext ) @@ -250,7 +250,7 @@ PSbConsiderPowerDown( -VOID +void PSvSendPSPOLL( IN HANDLE hDeviceContext ) diff --git a/drivers/staging/vt6655/power.h b/drivers/staging/vt6655/power.h index 30634fabfe96..bac8b200d544 100644 --- a/drivers/staging/vt6655/power.h +++ b/drivers/staging/vt6655/power.h @@ -55,18 +55,18 @@ PSbConsiderPowerDown( IN BOOL bCheckCountToWakeUp ); -VOID +void PSvDisablePowerSaving( IN HANDLE hDeviceContext ); -VOID +void PSvEnablePowerSaving( IN HANDLE hDeviceContext, IN WORD wListenInterval ); -VOID +void PSvSendPSPOLL( IN HANDLE hDeviceContext ); diff --git a/drivers/staging/vt6655/rc4.c b/drivers/staging/vt6655/rc4.c index e6c61312fd28..4a53f159cb30 100644 --- a/drivers/staging/vt6655/rc4.c +++ b/drivers/staging/vt6655/rc4.c @@ -32,7 +32,7 @@ #include "rc4.h" -VOID rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len) +void rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len) { UINT ust1, ust2; UINT keyindex; @@ -78,7 +78,7 @@ UINT rc4_byte(PRC4Ext pRC4) return pbyst[(ustx + usty) & 0xff]; } -VOID rc4_encrypt(PRC4Ext pRC4, PBYTE pbyDest, +void rc4_encrypt(PRC4Ext pRC4, PBYTE pbyDest, PBYTE pbySrc, UINT cbData_len) { UINT ii; diff --git a/drivers/staging/vt6655/rc4.h b/drivers/staging/vt6655/rc4.h index bf607c9d446a..e65cae69efaf 100644 --- a/drivers/staging/vt6655/rc4.h +++ b/drivers/staging/vt6655/rc4.h @@ -40,7 +40,7 @@ typedef struct { BYTE abystate[256]; } RC4Ext, *PRC4Ext; -VOID rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len); +void rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len); UINT rc4_byte(PRC4Ext pRC4); void rc4_encrypt(PRC4Ext pRC4, PBYTE pbyDest, PBYTE pbySrc, UINT cbData_len); diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c index 01ab73f1cc3f..29eb758c9e7d 100644 --- a/drivers/staging/vt6655/rf.c +++ b/drivers/staging/vt6655/rf.c @@ -1201,7 +1201,7 @@ DWORD dwMax7230Pwr = 0; * Return Value: none * -*/ -VOID +void RFvRSSITodBm ( IN PSDevice pDevice, IN BYTE byCurrRSSI, diff --git a/drivers/staging/vt6655/rf.h b/drivers/staging/vt6655/rf.h index f316bcced8e8..e6e6ca586330 100644 --- a/drivers/staging/vt6655/rf.h +++ b/drivers/staging/vt6655/rf.h @@ -89,7 +89,7 @@ BOOL RFbRawSetPower( IN UINT uRATE ); -VOID +void RFvRSSITodBm( IN PSDevice pDevice, IN BYTE byCurrRSSI, diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index ed3070edcac1..effefdb77b61 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -115,7 +115,7 @@ const WORD wFB_Opt1[2][5] = { static -VOID +void s_vFillTxKey( IN PSDevice pDevice, IN PBYTE pbyBuf, @@ -129,7 +129,7 @@ s_vFillTxKey( static -VOID +void s_vFillRTSHead( IN PSDevice pDevice, IN BYTE byPktType, @@ -143,7 +143,7 @@ s_vFillRTSHead( ); static -VOID +void s_vGenerateTxParameter( IN PSDevice pDevice, IN BYTE byPktType, @@ -210,7 +210,7 @@ s_uFillDataHead ( static -VOID +void s_vFillTxKey ( IN PSDevice pDevice, IN PBYTE pbyBuf, @@ -328,7 +328,7 @@ s_vFillTxKey ( static -VOID +void s_vSWencryption ( IN PSDevice pDevice, IN PSKeyItem pTransmitKey, @@ -851,7 +851,7 @@ s_uFillDataHead ( static -VOID +void s_vFillRTSHead ( IN PSDevice pDevice, IN BYTE byPktType, @@ -1045,7 +1045,7 @@ s_vFillRTSHead ( } static -VOID +void s_vFillCTSHead ( IN PSDevice pDevice, IN UINT uDMAIdx, @@ -1150,7 +1150,7 @@ s_vFillCTSHead ( -*/ // UINT cbFrameSize,//Hdr+Payload+FCS static -VOID +void s_vGenerateTxParameter ( IN PSDevice pDevice, IN BYTE byPktType, @@ -1268,7 +1268,7 @@ s_vGenerateTxParameter ( UINT cbFragmentSize,//Hdr+payoad+FCS */ static -VOID +void s_vFillFragParameter( IN PSDevice pDevice, IN PBYTE pbyBuffer, @@ -2093,7 +2093,7 @@ s_cbFillTxBufHead ( } -VOID +void vGenerateFIFOHeader ( IN PSDevice pDevice, IN BYTE byPktType, @@ -2264,7 +2264,7 @@ vGenerateFIFOHeader ( * -*/ -VOID +void vGenerateMACHeader ( IN PSDevice pDevice, IN PBYTE pbyBufferAddr, @@ -2825,7 +2825,7 @@ cbGetFragCount ( } -VOID +void vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDULen) { PSTxDesc pFrstTD; diff --git a/drivers/staging/vt6655/rxtx.h b/drivers/staging/vt6655/rxtx.h index 5da815efe70b..4c2df48be372 100644 --- a/drivers/staging/vt6655/rxtx.h +++ b/drivers/staging/vt6655/rxtx.h @@ -40,7 +40,7 @@ /*--------------------- Export Functions --------------------------*/ /* -VOID vGenerateMACHeader( +void vGenerateMACHeader( IN PSDevice pDevice, IN DWORD dwTxBufferAddr, IN PBYTE pbySkbData, @@ -50,7 +50,7 @@ VOID vGenerateMACHeader( OUT PUINT pcbAppendPayload ); -VOID vProcessRxMACHeader ( +void vProcessRxMACHeader ( IN PSDevice pDevice, IN DWORD dwRxBufferAddr, IN UINT cbPacketSize, @@ -60,7 +60,7 @@ VOID vProcessRxMACHeader ( */ -VOID +void vGenerateMACHeader ( IN PSDevice pDevice, IN PBYTE pbyBufferAddr, @@ -82,7 +82,7 @@ cbGetFragCount( ); -VOID +void vGenerateFIFOHeader ( IN PSDevice pDevice, IN BYTE byPktTyp, @@ -100,7 +100,7 @@ vGenerateFIFOHeader ( ); -VOID vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDULen); +void vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDULen); CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket); CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket); diff --git a/drivers/staging/vt6655/srom.h b/drivers/staging/vt6655/srom.h index ba123ee61d24..dbb3f5efe979 100644 --- a/drivers/staging/vt6655/srom.h +++ b/drivers/staging/vt6655/srom.h @@ -150,7 +150,7 @@ void SROMvWriteAllContents(DWORD_PTR dwIoBase, PBYTE pbyEepromRegs); void SROMvReadEtherAddress(DWORD_PTR dwIoBase, PBYTE pbyEtherAddress); void SROMvWriteEtherAddress(DWORD_PTR dwIoBase, PBYTE pbyEtherAddress); -VOID SROMvReadSubSysVenId(DWORD_PTR dwIoBase, PDWORD pdwSubSysVenId); +void SROMvReadSubSysVenId(DWORD_PTR dwIoBase, PDWORD pdwSubSysVenId); BOOL SROMbAutoLoad (DWORD_PTR dwIoBase); diff --git a/drivers/staging/vt6655/tkip.c b/drivers/staging/vt6655/tkip.c index 8ca154080e98..f83af5913aa6 100644 --- a/drivers/staging/vt6655/tkip.c +++ b/drivers/staging/vt6655/tkip.c @@ -183,7 +183,7 @@ unsigned int rotr1(unsigned int a) * Return Value: none * */ -VOID TKIPvMixKey( +void TKIPvMixKey( PBYTE pbyTKey, PBYTE pbyTA, WORD wTSC15_0, diff --git a/drivers/staging/vt6655/tkip.h b/drivers/staging/vt6655/tkip.h index 847ecdf97ee8..3dfa7f5ee7ec 100644 --- a/drivers/staging/vt6655/tkip.h +++ b/drivers/staging/vt6655/tkip.h @@ -46,7 +46,7 @@ /*--------------------- Export Functions --------------------------*/ -VOID TKIPvMixKey( +void TKIPvMixKey( PBYTE pbyTKey, PBYTE pbyTA, WORD wTSC15_0, diff --git a/drivers/staging/vt6655/ttype.h b/drivers/staging/vt6655/ttype.h index dc061c6402e9..24d0eca9420f 100644 --- a/drivers/staging/vt6655/ttype.h +++ b/drivers/staging/vt6655/ttype.h @@ -33,10 +33,6 @@ /******* Common definitions and typedefs ***********************************/ -#ifndef VOID -#define VOID void -#endif - #ifndef IN #define IN #endif diff --git a/drivers/staging/vt6655/vntwifi.c b/drivers/staging/vt6655/vntwifi.c index fbe27a834ce3..cbfa8e80dd68 100644 --- a/drivers/staging/vt6655/vntwifi.c +++ b/drivers/staging/vt6655/vntwifi.c @@ -69,7 +69,7 @@ * Return Value: none * -*/ -VOID +void VNTWIFIvSetOPMode ( IN PVOID pMgmtHandle, IN WMAC_CONFIG_MODE eOPMode @@ -98,7 +98,7 @@ VNTWIFIvSetOPMode ( * Return Value: none * -*/ -VOID +void VNTWIFIvSetIBSSParameter ( IN PVOID pMgmtHandle, IN WORD wBeaconPeriod, @@ -306,7 +306,7 @@ VNTWIFIbyGetACKTxRate ( * Return Value: none * -*/ -VOID +void VNTWIFIvSetAuthenticationMode ( IN PVOID pMgmtHandle, IN WMAC_AUTHENTICATION_MODE eAuthMode @@ -338,7 +338,7 @@ VNTWIFIvSetAuthenticationMode ( * Return Value: none * -*/ -VOID +void VNTWIFIvSetEncryptionMode ( IN PVOID pMgmtHandle, IN WMAC_ENCRYPTION_MODE eEncryptionMode @@ -379,7 +379,7 @@ VNTWIFIbConfigPhyMode ( } -VOID +void VNTWIFIbGetConfigPhyMode ( IN PVOID pMgmtHandle, OUT PVOID pePhyType @@ -424,7 +424,7 @@ VNTWIFIbGetConfigPhyMode ( * -*/ -VOID +void VNTWIFIvQueryBSSList ( IN PVOID pMgmtHandle, OUT PUINT puBSSCount, @@ -454,7 +454,7 @@ VNTWIFIvQueryBSSList ( -VOID +void VNTWIFIvGetNextBSS ( IN PVOID pMgmtHandle, IN PVOID pvCurrentBSS, @@ -494,7 +494,7 @@ VNTWIFIvGetNextBSS ( * Return Value: none * -*/ -VOID +void VNTWIFIvUpdateNodeTxCounter( IN PVOID pMgmtHandle, IN PBYTE pbyDestAddress, @@ -529,7 +529,7 @@ VNTWIFIvUpdateNodeTxCounter( } -VOID +void VNTWIFIvGetTxRate( IN PVOID pMgmtHandle, IN PBYTE pbyDestAddress, @@ -702,7 +702,7 @@ VNTWIFIwGetMaxSupportRate( } -VOID +void VNTWIFIvSet11h ( IN PVOID pMgmtObject, IN BOOL b11hEnable diff --git a/drivers/staging/vt6655/vntwifi.h b/drivers/staging/vt6655/vntwifi.h index 2854dfcb19aa..4c560a8a0992 100644 --- a/drivers/staging/vt6655/vntwifi.h +++ b/drivers/staging/vt6655/vntwifi.h @@ -140,7 +140,7 @@ typedef enum tagWMAC_POWER_MODE { /*--------------------- Export Functions --------------------------*/ -VOID +void VNTWIFIvSetIBSSParameter ( IN PVOID pMgmtHandle, IN WORD wBeaconPeriod, @@ -148,7 +148,7 @@ VNTWIFIvSetIBSSParameter ( IN UINT uChannel ); -VOID +void VNTWIFIvSetOPMode ( IN PVOID pMgmtHandle, IN WMAC_CONFIG_MODE eOPMode @@ -182,13 +182,13 @@ VNTWIFIbyGetACKTxRate ( IN PWLAN_IE_SUPP_RATES pExtSupportRateIEs ); -VOID +void VNTWIFIvSetAuthenticationMode ( IN PVOID pMgmtHandle, IN WMAC_AUTHENTICATION_MODE eAuthMode ); -VOID +void VNTWIFIvSetEncryptionMode ( IN PVOID pMgmtHandle, IN WMAC_ENCRYPTION_MODE eEncryptionMode @@ -201,13 +201,13 @@ VNTWIFIbConfigPhyMode( IN CARD_PHY_TYPE ePhyType ); -VOID +void VNTWIFIbGetConfigPhyMode( IN PVOID pMgmtHandle, OUT PVOID pePhyType ); -VOID +void VNTWIFIvQueryBSSList( IN PVOID pMgmtHandle, OUT PUINT puBSSCount, @@ -217,7 +217,7 @@ VNTWIFIvQueryBSSList( -VOID +void VNTWIFIvGetNextBSS ( IN PVOID pMgmtHandle, IN PVOID pvCurrentBSS, @@ -226,7 +226,7 @@ VNTWIFIvGetNextBSS ( -VOID +void VNTWIFIvUpdateNodeTxCounter( IN PVOID pMgmtHandle, IN PBYTE pbyDestAddress, @@ -236,7 +236,7 @@ VNTWIFIvUpdateNodeTxCounter( ); -VOID +void VNTWIFIvGetTxRate( IN PVOID pMgmtHandle, IN PBYTE pbyDestAddress, @@ -280,7 +280,7 @@ VNTWIFIwGetMaxSupportRate( ); // for 802.11h -VOID +void VNTWIFIvSet11h ( IN PVOID pMgmtObject, IN BOOL b11hEnable diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c index c9eabf9995df..ec1036e983d0 100644 --- a/drivers/staging/vt6655/wcmd.c +++ b/drivers/staging/vt6655/wcmd.c @@ -66,7 +66,7 @@ static int msglevel =MSG_LEVEL_INFO; /*--------------------- Static Functions --------------------------*/ static -VOID +void s_vProbeChannel( IN PSDevice pDevice ); @@ -202,7 +202,7 @@ vAdHocBeaconRestart(PSDevice pDevice) -*/ static -VOID +void s_vProbeChannel( IN PSDevice pDevice ) @@ -317,7 +317,7 @@ s_MgrMakeProbeRequest( -VOID +void vCommandTimerWait( IN HANDLE hDeviceContext, IN UINT MSecond @@ -337,7 +337,7 @@ vCommandTimerWait( -VOID +void vCommandTimer ( IN HANDLE hDeviceContext ) @@ -1081,7 +1081,7 @@ BOOL bClearBSSID_SCAN ( } //mike add:reset command timer -VOID +void vResetCommandTimer( IN HANDLE hDeviceContext ) @@ -1105,7 +1105,7 @@ vResetCommandTimer( #ifdef TxInSleep -VOID +void BSSvSecondTxData( IN HANDLE hDeviceContext ) diff --git a/drivers/staging/vt6655/wcmd.h b/drivers/staging/vt6655/wcmd.h index af32e57e335f..1e8166962015 100644 --- a/drivers/staging/vt6655/wcmd.h +++ b/drivers/staging/vt6655/wcmd.h @@ -109,12 +109,12 @@ typedef enum tagCMD_STATE { /*--------------------- Export Functions --------------------------*/ -VOID +void vResetCommandTimer( IN HANDLE hDeviceContext ); -VOID +void vCommandTimer ( IN HANDLE hDeviceContext ); @@ -130,13 +130,13 @@ bScheduleCommand( IN PBYTE pbyItem0 ); -VOID +void vCommandTimerWait( IN HANDLE hDeviceContext, IN UINT MSecond ); #ifdef TxInSleep -VOID +void BSSvSecondTxData( IN HANDLE hDeviceContext ); diff --git a/drivers/staging/vt6655/wmgr.c b/drivers/staging/vt6655/wmgr.c index 659be05a33ef..64930910fca4 100644 --- a/drivers/staging/vt6655/wmgr.c +++ b/drivers/staging/vt6655/wmgr.c @@ -113,7 +113,7 @@ s_MgrMakeAssocRequest( ); static -VOID +void s_vMgrRxAssocRequest( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -135,7 +135,7 @@ s_MgrMakeReAssocRequest( ); static -VOID +void s_vMgrRxAssocResponse( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -144,7 +144,7 @@ s_vMgrRxAssocResponse( ); static -VOID +void s_vMgrRxDisassociation( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -153,7 +153,7 @@ s_vMgrRxDisassociation( // Authentication/deauthen functions static -VOID +void s_vMgrRxAuthenSequence_1( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -161,7 +161,7 @@ s_vMgrRxAuthenSequence_1( ); static -VOID +void s_vMgrRxAuthenSequence_2( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -169,7 +169,7 @@ s_vMgrRxAuthenSequence_2( ); static -VOID +void s_vMgrRxAuthenSequence_3( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -177,7 +177,7 @@ s_vMgrRxAuthenSequence_3( ); static -VOID +void s_vMgrRxAuthenSequence_4( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -185,7 +185,7 @@ s_vMgrRxAuthenSequence_4( ); static -VOID +void s_vMgrRxAuthentication( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -193,7 +193,7 @@ s_vMgrRxAuthentication( ); static -VOID +void s_vMgrRxDeauthentication( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -203,7 +203,7 @@ s_vMgrRxDeauthentication( // Scan functions // probe request/response functions static -VOID +void s_vMgrRxProbeRequest( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -211,7 +211,7 @@ s_vMgrRxProbeRequest( ); static -VOID +void s_vMgrRxProbeResponse( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -220,7 +220,7 @@ s_vMgrRxProbeResponse( // beacon functions static -VOID +void s_vMgrRxBeacon( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -229,7 +229,7 @@ s_vMgrRxBeacon( ); static -VOID +void s_vMgrFormatTIM( IN PSMgmtObject pMgmt, IN PWLAN_IE_TIM pTIM @@ -299,7 +299,7 @@ s_MgrMakeProbeResponse( // received status static -VOID +void s_vMgrLogStatus( IN PSMgmtObject pMgmt, IN WORD wStatus @@ -307,7 +307,7 @@ s_vMgrLogStatus( static -VOID +void s_vMgrSynchBSS ( IN PSDevice pDevice, IN UINT uBSSMode, @@ -324,7 +324,7 @@ s_bCipherMatch ( OUT PBYTE pbyCCSGK ); - static VOID Encyption_Rebuild( + static void Encyption_Rebuild( IN PSDevice pDevice, IN PKnownBSS pCurr ); @@ -347,7 +347,7 @@ s_bCipherMatch ( * -*/ -VOID +void vMgrObjectInit( IN HANDLE hDeviceContext ) @@ -431,7 +431,7 @@ vMgrTimerInit( * -*/ -VOID +void vMgrObjectReset( IN HANDLE hDeviceContext ) @@ -460,7 +460,7 @@ vMgrObjectReset( -*/ -VOID +void vMgrAssocBeginSta( IN HANDLE hDeviceContext, IN PSMgmtObject pMgmt, @@ -536,7 +536,7 @@ vMgrAssocBeginSta( * -*/ -VOID +void vMgrReAssocBeginSta( IN HANDLE hDeviceContext, IN PSMgmtObject pMgmt, @@ -615,7 +615,7 @@ vMgrReAssocBeginSta( * -*/ -VOID +void vMgrDisassocBeginSta( IN HANDLE hDeviceContext, IN PSMgmtObject pMgmt, @@ -678,7 +678,7 @@ vMgrDisassocBeginSta( -*/ static -VOID +void s_vMgrRxAssocRequest( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -840,7 +840,7 @@ s_vMgrRxAssocRequest( -*/ static -VOID +void s_vMgrRxReAssocRequest( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -990,7 +990,7 @@ s_vMgrRxReAssocRequest( -*/ static -VOID +void s_vMgrRxAssocResponse( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -1150,7 +1150,7 @@ if(pMgmt->eCurrState == WMAC_STATE_ASSOC) * -*/ -VOID +void vMgrAuthenBeginSta( IN HANDLE hDeviceContext, IN PSMgmtObject pMgmt, @@ -1208,7 +1208,7 @@ vMgrAuthenBeginSta( * -*/ -VOID +void vMgrDeAuthenBeginSta( IN HANDLE hDeviceContext, IN PSMgmtObject pMgmt, @@ -1265,7 +1265,7 @@ vMgrDeAuthenBeginSta( -*/ static -VOID +void s_vMgrRxAuthentication( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -1323,7 +1323,7 @@ s_vMgrRxAuthentication( static -VOID +void s_vMgrRxAuthenSequence_1( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -1429,7 +1429,7 @@ s_vMgrRxAuthenSequence_1( -*/ static -VOID +void s_vMgrRxAuthenSequence_2( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -1531,7 +1531,7 @@ s_vMgrRxAuthenSequence_2( -*/ static -VOID +void s_vMgrRxAuthenSequence_3( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -1619,7 +1619,7 @@ reply: * -*/ static -VOID +void s_vMgrRxAuthenSequence_4( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -1658,7 +1658,7 @@ s_vMgrRxAuthenSequence_4( -*/ static -VOID +void s_vMgrRxDisassociation( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -1737,7 +1737,7 @@ s_vMgrRxDisassociation( -*/ static -VOID +void s_vMgrRxDeauthentication( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -1863,7 +1863,7 @@ ChannelExceedZoneType( -*/ static -VOID +void s_vMgrRxBeacon( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -2384,7 +2384,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) * CMD_STATUS * -*/ -VOID +void vMgrCreateOwnIBSS( IN HANDLE hDeviceContext, OUT PCMD_STATUS pStatus @@ -2651,7 +2651,7 @@ vMgrCreateOwnIBSS( * -*/ -VOID +void vMgrJoinBSSBegin( IN HANDLE hDeviceContext, OUT PCMD_STATUS pStatus @@ -2920,7 +2920,7 @@ vMgrJoinBSSBegin( * -*/ static -VOID +void s_vMgrSynchBSS ( IN PSDevice pDevice, IN UINT uBSSMode, @@ -3088,7 +3088,7 @@ s_vMgrSynchBSS ( //mike add: fix NetworkManager 0.7.0 hidden ssid mode in WPA encryption // ,need reset eAuthenMode and eEncryptionStatus - static VOID Encyption_Rebuild( + static void Encyption_Rebuild( IN PSDevice pDevice, IN PKnownBSS pCurr ) @@ -3140,12 +3140,12 @@ s_vMgrSynchBSS ( * * * Return Value: - * VOID + * void * -*/ static -VOID +void s_vMgrFormatTIM( IN PSMgmtObject pMgmt, IN PWLAN_IE_TIM pTIM @@ -4313,7 +4313,7 @@ s_MgrMakeReAssocResponse( -*/ static -VOID +void s_vMgrRxProbeResponse( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -4438,7 +4438,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) static -VOID +void s_vMgrRxProbeRequest( IN PSDevice pDevice, IN PSMgmtObject pMgmt, @@ -4534,7 +4534,7 @@ s_vMgrRxProbeRequest( -*/ -VOID +void vMgrRxManagePacket( IN HANDLE hDeviceContext, IN PSMgmtObject pMgmt, @@ -4738,7 +4738,7 @@ bMgrPrepareBeaconToSend( * -*/ static -VOID +void s_vMgrLogStatus( IN PSMgmtObject pMgmt, IN WORD wStatus @@ -4868,7 +4868,7 @@ bAdd_PMKID_Candidate ( * Return Value: none. * -*/ -VOID +void vFlush_PMKID_Candidate ( IN HANDLE hDeviceContext ) diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index 1c1f2ea5782c..5963b146ee23 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -409,7 +409,7 @@ vMgrTimerInit( IN HANDLE hDeviceContext ); -VOID +void vMgrObjectReset( IN HANDLE hDeviceContext ); @@ -421,14 +421,14 @@ vMgrAssocBeginSta( OUT PCMD_STATUS pStatus ); -VOID +void vMgrReAssocBeginSta( IN HANDLE hDeviceContext, IN PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ); -VOID +void vMgrDisassocBeginSta( IN HANDLE hDeviceContext, IN PSMgmtObject pMgmt, @@ -437,26 +437,26 @@ vMgrDisassocBeginSta( OUT PCMD_STATUS pStatus ); -VOID +void vMgrAuthenBeginSta( IN HANDLE hDeviceContext, IN PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ); -VOID +void vMgrCreateOwnIBSS( IN HANDLE hDeviceContext, OUT PCMD_STATUS pStatus ); -VOID +void vMgrJoinBSSBegin( IN HANDLE hDeviceContext, OUT PCMD_STATUS pStatus ); -VOID +void vMgrRxManagePacket( IN HANDLE hDeviceContext, IN PSMgmtObject pMgmt, @@ -464,14 +464,14 @@ vMgrRxManagePacket( ); /* -VOID +void vMgrScanBegin( IN HANDLE hDeviceContext, OUT PCMD_STATUS pStatus ); */ -VOID +void vMgrDeAuthenBeginSta( IN HANDLE hDeviceContext, IN PSMgmtObject pMgmt, @@ -494,7 +494,7 @@ bAdd_PMKID_Candidate ( IN PSRSNCapObject psRSNCapObj ); -VOID +void vFlush_PMKID_Candidate ( IN HANDLE hDeviceContext ); diff --git a/drivers/staging/vt6655/wpa.c b/drivers/staging/vt6655/wpa.c index 5da671418b52..75ae83814d89 100644 --- a/drivers/staging/vt6655/wpa.c +++ b/drivers/staging/vt6655/wpa.c @@ -68,7 +68,7 @@ const BYTE abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 }; * -*/ -VOID +void WPA_ClearRSN ( IN PKnownBSS pBSSList ) @@ -104,7 +104,7 @@ WPA_ClearRSN ( * Return Value: none. * -*/ -VOID +void WPA_ParseRSN ( IN PKnownBSS pBSSList, IN PWLAN_IE_RSN_EXT pRSN diff --git a/drivers/staging/vt6655/wpa.h b/drivers/staging/vt6655/wpa.h index 9d9ce01d0c61..d77c7bb2274a 100644 --- a/drivers/staging/vt6655/wpa.h +++ b/drivers/staging/vt6655/wpa.h @@ -58,12 +58,12 @@ /*--------------------- Export Functions --------------------------*/ -VOID +void WPA_ClearRSN( IN PKnownBSS pBSSList ); -VOID +void WPA_ParseRSN( IN PKnownBSS pBSSList, IN PWLAN_IE_RSN_EXT pRSN diff --git a/drivers/staging/vt6655/wpa2.c b/drivers/staging/vt6655/wpa2.c index 931b6bd360e6..183d28c29a5a 100644 --- a/drivers/staging/vt6655/wpa2.c +++ b/drivers/staging/vt6655/wpa2.c @@ -72,7 +72,7 @@ const BYTE abyOUIPSK[4] = { 0x00, 0x0F, 0xAC, 0x02 }; * Return Value: none. * -*/ -VOID +void WPA2_ClearRSN ( IN PKnownBSS pBSSNode ) @@ -107,7 +107,7 @@ WPA2_ClearRSN ( * Return Value: none. * -*/ -VOID +void WPA2vParseRSN ( IN PKnownBSS pBSSNode, IN PWLAN_IE_RSN pRSN diff --git a/drivers/staging/vt6655/wpa2.h b/drivers/staging/vt6655/wpa2.h index e553b3869008..cbd75d0d2bbb 100644 --- a/drivers/staging/vt6655/wpa2.h +++ b/drivers/staging/vt6655/wpa2.h @@ -58,12 +58,12 @@ typedef struct tagSPMKIDCache { /*--------------------- Export Functions --------------------------*/ -VOID +void WPA2_ClearRSN ( IN PKnownBSS pBSSNode ); -VOID +void WPA2vParseRSN ( IN PKnownBSS pBSSNode, IN PWLAN_IE_RSN pRSN -- cgit v1.2.3 From 830a619c02a53d52c86534f7d857b2e8d0ba893f Mon Sep 17 00:00:00 2001 From: Charles Clément Date: Fri, 7 May 2010 12:30:20 -0700 Subject: Staging: vt6655: remove PVOID definition and use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles Clément Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/IEEE11h.c | 6 +- drivers/staging/vt6655/IEEE11h.h | 2 +- drivers/staging/vt6655/bssdb.c | 14 ++-- drivers/staging/vt6655/card.c | 122 +++++++++++++++++------------------ drivers/staging/vt6655/card.h | 96 +++++++++++++-------------- drivers/staging/vt6655/datarate.c | 12 ++-- drivers/staging/vt6655/datarate.h | 4 +- drivers/staging/vt6655/device_main.c | 14 ++-- drivers/staging/vt6655/dpc.c | 2 +- drivers/staging/vt6655/dpc.h | 2 +- drivers/staging/vt6655/key.c | 4 +- drivers/staging/vt6655/key.h | 2 +- drivers/staging/vt6655/rxtx.c | 88 ++++++++++++------------- drivers/staging/vt6655/ttype.h | 7 -- drivers/staging/vt6655/vntwifi.c | 58 ++++++++--------- drivers/staging/vt6655/vntwifi.h | 58 ++++++++--------- drivers/staging/vt6655/wmgr.c | 18 +++--- drivers/staging/vt6655/wmgr.h | 2 +- drivers/staging/vt6655/wpa2.c | 2 +- drivers/staging/vt6655/wpa2.h | 2 +- 20 files changed, 254 insertions(+), 261 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/IEEE11h.c b/drivers/staging/vt6655/IEEE11h.c index 2567143d3b1c..77813002d2fc 100644 --- a/drivers/staging/vt6655/IEEE11h.c +++ b/drivers/staging/vt6655/IEEE11h.c @@ -203,8 +203,8 @@ static BOOL s_bRxTPCReq(PSMgmtObject pMgmt, PWLAN_FRAME_TPCREQ pTPCReq, BYTE byR -*/ BOOL IEEE11hbMgrRxAction ( - IN PVOID pMgmtHandle, - IN PVOID pRxPacket + IN void *pMgmtHandle, + IN void *pRxPacket ) { PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; @@ -265,7 +265,7 @@ IEEE11hbMgrRxAction ( BOOL IEEE11hbMSRRepTx ( - IN PVOID pMgmtHandle + IN void *pMgmtHandle ) { PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; diff --git a/drivers/staging/vt6655/IEEE11h.h b/drivers/staging/vt6655/IEEE11h.h index 0f61eddd6f26..1707388e7cfc 100644 --- a/drivers/staging/vt6655/IEEE11h.h +++ b/drivers/staging/vt6655/IEEE11h.h @@ -46,7 +46,7 @@ /*--------------------- Export Functions --------------------------*/ BOOL IEEE11hbMSRRepTx ( - IN PVOID pMgmtHandle + IN void *pMgmtHandle ); #endif // __IEEE11h_H__ diff --git a/drivers/staging/vt6655/bssdb.c b/drivers/staging/vt6655/bssdb.c index baa83e269fd4..e7bbc56f0c85 100644 --- a/drivers/staging/vt6655/bssdb.c +++ b/drivers/staging/vt6655/bssdb.c @@ -764,7 +764,7 @@ BSSbUpdateToBSSList ( BOOL BSSDBbIsSTAInNodeDB( - IN PVOID pMgmtObject, + IN void *pMgmtObject, IN PBYTE abyDstAddr, OUT PUINT puNodeIndex ) @@ -919,7 +919,7 @@ BSSvUpdateAPNode( pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pExtSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, uRateLen); - RATEvParseMaxRate((PVOID) pDevice, + RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, TRUE, @@ -972,7 +972,7 @@ BSSvAddMulticastNode( pMgmt->sNodeDBTable[0].bActive = TRUE; pMgmt->sNodeDBTable[0].bPSEnable = FALSE; skb_queue_head_init(&pMgmt->sNodeDBTable[0].sTxPSQueue); - RATEvParseMaxRate((PVOID) pDevice, + RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, TRUE, @@ -1162,7 +1162,7 @@ start: */ if (ii > 0) { // ii = 0 for multicast node (AP & Adhoc) - RATEvTxRateFallBack((PVOID)pDevice, &(pMgmt->sNodeDBTable[ii])); + RATEvTxRateFallBack((void *)pDevice, &(pMgmt->sNodeDBTable[ii])); } else { // ii = 0 reserved for unicast AP node (Infra STA) @@ -1170,7 +1170,7 @@ start: #ifdef PLICE_DEBUG printk("SecondCallback:Before:TxDataRate is %d\n",pMgmt->sNodeDBTable[0].wTxDataRate); #endif - RATEvTxRateFallBack((PVOID)pDevice, &(pMgmt->sNodeDBTable[ii])); + RATEvTxRateFallBack((void *)pDevice, &(pMgmt->sNodeDBTable[ii])); #ifdef PLICE_DEBUG printk("SecondCallback:After:TxDataRate is %d\n",pMgmt->sNodeDBTable[0].wTxDataRate); #endif @@ -1215,14 +1215,14 @@ start: if (pDevice->bShortSlotTime) { pDevice->bShortSlotTime = FALSE; BBvSetShortSlotTime(pDevice); - vUpdateIFS((PVOID)pDevice); + vUpdateIFS((void *)pDevice); } } else { if (!pDevice->bShortSlotTime) { pDevice->bShortSlotTime = TRUE; BBvSetShortSlotTime(pDevice); - vUpdateIFS((PVOID)pDevice); + vUpdateIFS((void *)pDevice); } } diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 091fbeabb6d5..e767044ba0d0 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -612,7 +612,7 @@ s_vCaculateOFDMRParameter ( */ static void -s_vSetRSPINF (PSDevice pDevice, CARD_PHY_TYPE ePHYType, PVOID pvSupportRateIEs, PVOID pvExtSupportRateIEs) +s_vSetRSPINF (PSDevice pDevice, CARD_PHY_TYPE ePHYType, void *pvSupportRateIEs, void *pvExtSupportRateIEs) { BYTE byServ = 0, bySignal = 0; // For CCK WORD wLen = 0; @@ -728,7 +728,7 @@ s_vSetRSPINF (PSDevice pDevice, CARD_PHY_TYPE ePHYType, PVOID pvSupportRateIEs, /*--------------------- Export Variables --------------------------*/ /*--------------------- Export Functions --------------------------*/ -BYTE CARDbyGetChannelMapping (PVOID pDeviceHandler, BYTE byChannelNumber, CARD_PHY_TYPE ePhyType) +BYTE CARDbyGetChannelMapping (void *pDeviceHandler, BYTE byChannelNumber, CARD_PHY_TYPE ePhyType) { UINT ii; @@ -746,7 +746,7 @@ BYTE CARDbyGetChannelMapping (PVOID pDeviceHandler, BYTE byChannelNumber, CARD_P } -BYTE CARDbyGetChannelNumber (PVOID pDeviceHandler, BYTE byChannelIndex) +BYTE CARDbyGetChannelNumber (void *pDeviceHandler, BYTE byChannelIndex) { // PSDevice pDevice = (PSDevice) pDeviceHandler; return(sChannelTbl[byChannelIndex].byChannelNumber); @@ -765,7 +765,7 @@ BYTE CARDbyGetChannelNumber (PVOID pDeviceHandler, BYTE byChannelIndex) * Return Value: TRUE if succeeded; FALSE if failed. * */ -BOOL CARDbSetChannel (PVOID pDeviceHandler, UINT uConnectionChannel) +BOOL CARDbSetChannel (void *pDeviceHandler, UINT uConnectionChannel) { PSDevice pDevice = (PSDevice) pDeviceHandler; BOOL bResult = TRUE; @@ -853,7 +853,7 @@ BOOL CARDbSetChannel (PVOID pDeviceHandler, UINT uConnectionChannel) * */ /* -BOOL CARDbSendPacket (PVOID pDeviceHandler, PVOID pPacket, CARD_PKT_TYPE ePktType, UINT uLength) +BOOL CARDbSendPacket (void *pDeviceHandler, void *pPacket, CARD_PKT_TYPE ePktType, UINT uLength) { PSDevice pDevice = (PSDevice) pDeviceHandler; if (ePktType == PKT_TYPE_802_11_MNG) { @@ -881,7 +881,7 @@ BOOL CARDbSendPacket (PVOID pDeviceHandler, PVOID pPacket, CARD_PKT_TYPE ePktTyp * Return Value: TRUE if short preamble; otherwise FALSE * */ -BOOL CARDbIsShortPreamble (PVOID pDeviceHandler) +BOOL CARDbIsShortPreamble (void *pDeviceHandler) { PSDevice pDevice = (PSDevice) pDeviceHandler; if (pDevice->byPreambleType == 0) { @@ -902,7 +902,7 @@ BOOL CARDbIsShortPreamble (PVOID pDeviceHandler) * Return Value: TRUE if short slot time; otherwise FALSE * */ -BOOL CARDbIsShorSlotTime (PVOID pDeviceHandler) +BOOL CARDbIsShorSlotTime (void *pDeviceHandler) { PSDevice pDevice = (PSDevice) pDeviceHandler; return(pDevice->bShortSlotTime); @@ -921,7 +921,7 @@ BOOL CARDbIsShorSlotTime (PVOID pDeviceHandler) * Return Value: None. * */ -BOOL CARDbSetPhyParameter (PVOID pDeviceHandler, CARD_PHY_TYPE ePHYType, WORD wCapInfo, BYTE byERPField, PVOID pvSupportRateIEs, PVOID pvExtSupportRateIEs) +BOOL CARDbSetPhyParameter (void *pDeviceHandler, CARD_PHY_TYPE ePHYType, WORD wCapInfo, BYTE byERPField, void *pvSupportRateIEs, void *pvExtSupportRateIEs) { PSDevice pDevice = (PSDevice) pDeviceHandler; BYTE byCWMaxMin = 0; @@ -1108,7 +1108,7 @@ BOOL CARDbSetPhyParameter (PVOID pDeviceHandler, CARD_PHY_TYPE ePHYType, WORD wC * Return Value: none * */ -BOOL CARDbUpdateTSF (PVOID pDeviceHandler, BYTE byRxRate, QWORD qwBSSTimestamp, QWORD qwLocalTSF) +BOOL CARDbUpdateTSF (void *pDeviceHandler, BYTE byRxRate, QWORD qwBSSTimestamp, QWORD qwLocalTSF) { PSDevice pDevice = (PSDevice) pDeviceHandler; QWORD qwTSFOffset; @@ -1143,7 +1143,7 @@ BOOL CARDbUpdateTSF (PVOID pDeviceHandler, BYTE byRxRate, QWORD qwBSSTimestamp, * Return Value: TRUE if succeed; otherwise FALSE * */ -BOOL CARDbSetBeaconPeriod (PVOID pDeviceHandler, WORD wBeaconInterval) +BOOL CARDbSetBeaconPeriod (void *pDeviceHandler, WORD wBeaconInterval) { PSDevice pDevice = (PSDevice) pDeviceHandler; UINT uBeaconInterval = 0; @@ -1197,7 +1197,7 @@ BOOL CARDbSetBeaconPeriod (PVOID pDeviceHandler, WORD wBeaconInterval) * Return Value: TRUE if all data packet complete; otherwise FALSE. * */ -BOOL CARDbStopTxPacket (PVOID pDeviceHandler, CARD_PKT_TYPE ePktType) +BOOL CARDbStopTxPacket (void *pDeviceHandler, CARD_PKT_TYPE ePktType) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -1255,7 +1255,7 @@ BOOL CARDbStopTxPacket (PVOID pDeviceHandler, CARD_PKT_TYPE ePktType) * Return Value: TRUE if success; FALSE if failed. * */ -BOOL CARDbStartTxPacket (PVOID pDeviceHandler, CARD_PKT_TYPE ePktType) +BOOL CARDbStartTxPacket (void *pDeviceHandler, CARD_PKT_TYPE ePktType) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -1297,7 +1297,7 @@ BOOL CARDbStartTxPacket (PVOID pDeviceHandler, CARD_PKT_TYPE ePktType) * Return Value: TRUE if success; FALSE if failed. * */ -BOOL CARDbSetBSSID(PVOID pDeviceHandler, PBYTE pbyBSSID, CARD_OP_MODE eOPMode) +BOOL CARDbSetBSSID(void *pDeviceHandler, PBYTE pbyBSSID, CARD_OP_MODE eOPMode) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -1367,7 +1367,7 @@ BOOL CARDbSetBSSID(PVOID pDeviceHandler, PBYTE pbyBSSID, CARD_OP_MODE eOPMode) * */ BOOL CARDbSetTxDataRate( - PVOID pDeviceHandler, + void *pDeviceHandler, WORD wDataRate ) { @@ -1393,7 +1393,7 @@ BOOL CARDbSetTxDataRate( -*/ BOOL CARDbPowerDown( - PVOID pDeviceHandler + void *pDeviceHandler ) { PSDevice pDevice = (PSDevice)pDeviceHandler; @@ -1430,7 +1430,7 @@ CARDbPowerDown( * Return Value: TRUE if success; otherwise FALSE * */ -BOOL CARDbRadioPowerOff (PVOID pDeviceHandler) +BOOL CARDbRadioPowerOff (void *pDeviceHandler) { PSDevice pDevice = (PSDevice) pDeviceHandler; BOOL bResult = TRUE; @@ -1479,7 +1479,7 @@ MACvRegBitsOn(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); //LED issue * Return Value: TRUE if success; otherwise FALSE * */ -BOOL CARDbRadioPowerOn (PVOID pDeviceHandler) +BOOL CARDbRadioPowerOn (void *pDeviceHandler) { PSDevice pDevice = (PSDevice) pDeviceHandler; BOOL bResult = TRUE; @@ -1523,7 +1523,7 @@ MACvRegBitsOff(pDevice->PortOffset, MAC_REG_GPIOCTL0, LED_ACTSET); //LED issue -BOOL CARDbRemoveKey (PVOID pDeviceHandler, PBYTE pbyBSSID) +BOOL CARDbRemoveKey (void *pDeviceHandler, PBYTE pbyBSSID) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -1550,7 +1550,7 @@ BOOL CARDbRemoveKey (PVOID pDeviceHandler, PBYTE pbyBSSID) -*/ BOOL CARDbAdd_PMKID_Candidate ( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, IN PBYTE pbyBSSID, IN BOOL bRSNCapExist, IN WORD wRSNCap @@ -1599,9 +1599,9 @@ CARDbAdd_PMKID_Candidate ( return TRUE; } -PVOID +void * CARDpGetCurrentAddress ( - IN PVOID pDeviceHandler + IN void *pDeviceHandler ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -1611,7 +1611,7 @@ CARDpGetCurrentAddress ( -void CARDvInitChannelTable (PVOID pDeviceHandler) +void CARDvInitChannelTable (void *pDeviceHandler) { PSDevice pDevice = (PSDevice) pDeviceHandler; BOOL bMultiBand = FALSE; @@ -1708,8 +1708,8 @@ void CARDvInitChannelTable (PVOID pDeviceHandler) -*/ BOOL CARDbStartMeasure ( - IN PVOID pDeviceHandler, - IN PVOID pvMeasureEIDs, + IN void *pDeviceHandler, + IN void *pvMeasureEIDs, IN UINT uNumOfMeasureEIDs ) { @@ -1835,7 +1835,7 @@ CARDbStartMeasure ( -*/ BOOL CARDbChannelSwitch ( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, IN BYTE byMode, IN BYTE byNewChannel, IN BYTE byCount @@ -1878,7 +1878,7 @@ CARDbChannelSwitch ( -*/ BOOL CARDbSetQuiet ( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, IN BOOL bResetQuiet, IN BYTE byQuietCount, IN BYTE byQuietPeriod, @@ -1934,7 +1934,7 @@ CARDbSetQuiet ( -*/ BOOL CARDbStartQuiet ( - IN PVOID pDeviceHandler + IN void *pDeviceHandler ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -2035,9 +2035,9 @@ CARDbStartQuiet ( -*/ void CARDvSetCountryInfo ( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, IN CARD_PHY_TYPE ePHYType, - IN PVOID pIE + IN void *pIE ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -2094,7 +2094,7 @@ CARDvSetCountryInfo ( -*/ void CARDvSetPowerConstraint ( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, IN BYTE byChannel, IN I8 byPower ) @@ -2129,7 +2129,7 @@ CARDvSetPowerConstraint ( -*/ void CARDvGetPowerCapability ( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, OUT PBYTE pbyMinPower, OUT PBYTE pbyMaxPower ) @@ -2165,7 +2165,7 @@ CARDvGetPowerCapability ( -*/ BYTE CARDbySetSupportChannels ( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, IN OUT PBYTE pbyIEs ) { @@ -2256,7 +2256,7 @@ CARDbySetSupportChannels ( -*/ I8 CARDbyGetTransmitPower ( - IN PVOID pDeviceHandler + IN void *pDeviceHandler ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -2281,8 +2281,8 @@ CARDbChannelGetList ( void CARDvSetCountryIE( - IN PVOID pDeviceHandler, - IN PVOID pIE + IN void *pDeviceHandler, + IN void *pIE ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -2307,7 +2307,7 @@ CARDvSetCountryIE( BOOL CARDbGetChannelMapInfo( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, IN UINT uChannelIndex, OUT PBYTE pbyChannelNumber, OUT PBYTE pbyMap @@ -2326,7 +2326,7 @@ CARDbGetChannelMapInfo( void CARDvSetChannelMapInfo( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, IN UINT uChannelIndex, IN BYTE byMap ) @@ -2342,7 +2342,7 @@ CARDvSetChannelMapInfo( void CARDvClearChannelMapInfo( - IN PVOID pDeviceHandler + IN void *pDeviceHandler ) { // PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -2356,7 +2356,7 @@ CARDvClearChannelMapInfo( BYTE CARDbyAutoChannelSelect( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, CARD_PHY_TYPE ePHYType ) { @@ -2422,7 +2422,7 @@ CARDbyAutoChannelSelect( //xxx void CARDvSafeResetTx ( - IN PVOID pDeviceHandler + IN void *pDeviceHandler ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -2478,7 +2478,7 @@ CARDvSafeResetTx ( -*/ void CARDvSafeResetRx ( - IN PVOID pDeviceHandler + IN void *pDeviceHandler ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -2537,7 +2537,7 @@ CARDvSafeResetRx ( * Return Value: response Control frame rate * */ -WORD CARDwGetCCKControlRate(PVOID pDeviceHandler, WORD wRateIdx) +WORD CARDwGetCCKControlRate(void *pDeviceHandler, WORD wRateIdx) { PSDevice pDevice = (PSDevice) pDeviceHandler; UINT ui = (UINT)wRateIdx; @@ -2564,14 +2564,14 @@ WORD CARDwGetCCKControlRate(PVOID pDeviceHandler, WORD wRateIdx) * Return Value: response Control frame rate * */ -WORD CARDwGetOFDMControlRate (PVOID pDeviceHandler, WORD wRateIdx) +WORD CARDwGetOFDMControlRate (void *pDeviceHandler, WORD wRateIdx) { PSDevice pDevice = (PSDevice) pDeviceHandler; UINT ui = (UINT)wRateIdx; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BASIC RATE: %X\n", pDevice->wBasicRate); - if (!CARDbIsOFDMinBasicRate((PVOID)pDevice)) { + if (!CARDbIsOFDMinBasicRate((void *)pDevice)) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDwGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx); if (wRateIdx > RATE_24M) wRateIdx = RATE_24M; @@ -2601,7 +2601,7 @@ WORD CARDwGetOFDMControlRate (PVOID pDeviceHandler, WORD wRateIdx) * Return Value: None. * */ -void CARDvSetRSPINF (PVOID pDeviceHandler, CARD_PHY_TYPE ePHYType) +void CARDvSetRSPINF (void *pDeviceHandler, CARD_PHY_TYPE ePHYType) { PSDevice pDevice = (PSDevice) pDeviceHandler; BYTE byServ = 0x00, bySignal = 0x00; //For CCK @@ -2614,7 +2614,7 @@ void CARDvSetRSPINF (PVOID pDeviceHandler, CARD_PHY_TYPE ePHYType) //RSPINF_b_1 BBvCaculateParameter(pDevice, 14, - CARDwGetCCKControlRate((PVOID)pDevice, RATE_1M), + CARDwGetCCKControlRate((void *)pDevice, RATE_1M), PK_TYPE_11B, &wLen, &byServ, @@ -2625,7 +2625,7 @@ void CARDvSetRSPINF (PVOID pDeviceHandler, CARD_PHY_TYPE ePHYType) ///RSPINF_b_2 BBvCaculateParameter(pDevice, 14, - CARDwGetCCKControlRate((PVOID)pDevice, RATE_2M), + CARDwGetCCKControlRate((void *)pDevice, RATE_2M), PK_TYPE_11B, &wLen, &byServ, @@ -2636,7 +2636,7 @@ void CARDvSetRSPINF (PVOID pDeviceHandler, CARD_PHY_TYPE ePHYType) //RSPINF_b_5 BBvCaculateParameter(pDevice, 14, - CARDwGetCCKControlRate((PVOID)pDevice, RATE_5M), + CARDwGetCCKControlRate((void *)pDevice, RATE_5M), PK_TYPE_11B, &wLen, &byServ, @@ -2647,7 +2647,7 @@ void CARDvSetRSPINF (PVOID pDeviceHandler, CARD_PHY_TYPE ePHYType) //RSPINF_b_11 BBvCaculateParameter(pDevice, 14, - CARDwGetCCKControlRate((PVOID)pDevice, RATE_11M), + CARDwGetCCKControlRate((void *)pDevice, RATE_11M), PK_TYPE_11B, &wLen, &byServ, @@ -2686,26 +2686,26 @@ void CARDvSetRSPINF (PVOID pDeviceHandler, CARD_PHY_TYPE ePHYType) &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_24, MAKEWORD(byTxRate,byRsvTime)); //RSPINF_a_36 - s_vCaculateOFDMRParameter(CARDwGetOFDMControlRate((PVOID)pDevice, RATE_36M), + s_vCaculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_36M), ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_36, MAKEWORD(byTxRate,byRsvTime)); //RSPINF_a_48 - s_vCaculateOFDMRParameter(CARDwGetOFDMControlRate((PVOID)pDevice, RATE_48M), + s_vCaculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_48M), ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_48, MAKEWORD(byTxRate,byRsvTime)); //RSPINF_a_54 - s_vCaculateOFDMRParameter(CARDwGetOFDMControlRate((PVOID)pDevice, RATE_54M), + s_vCaculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_54M), ePHYType, &byTxRate, &byRsvTime); VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_54, MAKEWORD(byTxRate,byRsvTime)); //RSPINF_a_72 - s_vCaculateOFDMRParameter(CARDwGetOFDMControlRate((PVOID)pDevice, RATE_54M), + s_vCaculateOFDMRParameter(CARDwGetOFDMControlRate((void *)pDevice, RATE_54M), ePHYType, &byTxRate, &byRsvTime); @@ -2726,7 +2726,7 @@ void CARDvSetRSPINF (PVOID pDeviceHandler, CARD_PHY_TYPE ePHYType) * Return Value: None. * */ -void vUpdateIFS (PVOID pDeviceHandler) +void vUpdateIFS (void *pDeviceHandler) { //Set SIFS, DIFS, EIFS, SlotTime, CwMin PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -2780,7 +2780,7 @@ void vUpdateIFS (PVOID pDeviceHandler) VNSvOutPortB(pDevice->PortOffset + MAC_REG_CWMAXMIN0, (BYTE)byMaxMin); } -void CARDvUpdateBasicTopRate (PVOID pDeviceHandler) +void CARDvUpdateBasicTopRate (void *pDeviceHandler) { PSDevice pDevice = (PSDevice) pDeviceHandler; BYTE byTopOFDM = RATE_24M, byTopCCK = RATE_1M; @@ -2820,7 +2820,7 @@ void CARDvUpdateBasicTopRate (PVOID pDeviceHandler) * Return Value: TRUE if succeeded; FALSE if failed. * */ -BOOL CARDbAddBasicRate (PVOID pDeviceHandler, WORD wRateIdx) +BOOL CARDbAddBasicRate (void *pDeviceHandler, WORD wRateIdx) { PSDevice pDevice = (PSDevice) pDeviceHandler; WORD wRate = (WORD)(1<wBasicRate |= wRate; //Determines the highest basic rate. - CARDvUpdateBasicTopRate((PVOID)pDevice); + CARDvUpdateBasicTopRate((void *)pDevice); return(TRUE); } -BOOL CARDbIsOFDMinBasicRate (PVOID pDeviceHandler) +BOOL CARDbIsOFDMinBasicRate (void *pDeviceHandler) { PSDevice pDevice = (PSDevice) pDeviceHandler; int ii; @@ -2845,14 +2845,14 @@ BOOL CARDbIsOFDMinBasicRate (PVOID pDeviceHandler) return FALSE; } -BYTE CARDbyGetPktType (PVOID pDeviceHandler) +BYTE CARDbyGetPktType (void *pDeviceHandler) { PSDevice pDevice = (PSDevice) pDeviceHandler; if (pDevice->byBBType == BB_TYPE_11A || pDevice->byBBType == BB_TYPE_11B) { return (BYTE)pDevice->byBBType; } - else if (CARDbIsOFDMinBasicRate((PVOID)pDevice)) { + else if (CARDbIsOFDMinBasicRate((void *)pDevice)) { return PK_TYPE_11GA; } else { @@ -2902,7 +2902,7 @@ void CARDvSetLoopbackMode (DWORD_PTR dwIoBase, WORD wLoopbackMode) * Return Value: none * */ -BOOL CARDbSoftwareReset (PVOID pDeviceHandler) +BOOL CARDbSoftwareReset (void *pDeviceHandler) { PSDevice pDevice = (PSDevice) pDeviceHandler; diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h index 6a9980d720a9..2114e99b5845 100644 --- a/drivers/staging/vt6655/card.h +++ b/drivers/staging/vt6655/card.h @@ -87,77 +87,77 @@ typedef enum _CARD_OP_MODE { /*--------------------- Export Functions --------------------------*/ BOOL ChannelValid(UINT CountryCode, UINT ChannelIndex); -void CARDvSetRSPINF(PVOID pDeviceHandler, CARD_PHY_TYPE ePHYType); -void vUpdateIFS(PVOID pDeviceHandler); -void CARDvUpdateBasicTopRate(PVOID pDeviceHandler); -BOOL CARDbAddBasicRate(PVOID pDeviceHandler, WORD wRateIdx); -BOOL CARDbIsOFDMinBasicRate(PVOID pDeviceHandler); +void CARDvSetRSPINF(void *pDeviceHandler, CARD_PHY_TYPE ePHYType); +void vUpdateIFS(void *pDeviceHandler); +void CARDvUpdateBasicTopRate(void *pDeviceHandler); +BOOL CARDbAddBasicRate(void *pDeviceHandler, WORD wRateIdx); +BOOL CARDbIsOFDMinBasicRate(void *pDeviceHandler); void CARDvSetLoopbackMode(DWORD_PTR dwIoBase, WORD wLoopbackMode); -BOOL CARDbSoftwareReset(PVOID pDeviceHandler); +BOOL CARDbSoftwareReset(void *pDeviceHandler); void CARDvSetFirstNextTBTT(DWORD_PTR dwIoBase, WORD wBeaconInterval); void CARDvUpdateNextTBTT(DWORD_PTR dwIoBase, QWORD qwTSF, WORD wBeaconInterval); BOOL CARDbGetCurrentTSF(DWORD_PTR dwIoBase, PQWORD pqwCurrTSF); QWORD CARDqGetNextTBTT(QWORD qwTSF, WORD wBeaconInterval); QWORD CARDqGetTSFOffset(BYTE byRxRate, QWORD qwTSF1, QWORD qwTSF2); -BOOL CARDbSetTxPower(PVOID pDeviceHandler, ULONG ulTxPower); -BYTE CARDbyGetPktType(PVOID pDeviceHandler); -void CARDvSafeResetTx(PVOID pDeviceHandler); -void CARDvSafeResetRx(PVOID pDeviceHandler); +BOOL CARDbSetTxPower(void *pDeviceHandler, ULONG ulTxPower); +BYTE CARDbyGetPktType(void *pDeviceHandler); +void CARDvSafeResetTx(void *pDeviceHandler); +void CARDvSafeResetRx(void *pDeviceHandler); //xxx -BOOL CARDbRadioPowerOff(PVOID pDeviceHandler); -BOOL CARDbRadioPowerOn(PVOID pDeviceHandler); -BOOL CARDbSetChannel(PVOID pDeviceHandler, UINT uConnectionChannel); -//BOOL CARDbSendPacket(PVOID pDeviceHandler, PVOID pPacket, CARD_PKT_TYPE ePktType, UINT uLength); -BOOL CARDbIsShortPreamble(PVOID pDeviceHandler); -BOOL CARDbIsShorSlotTime(PVOID pDeviceHandler); -BOOL CARDbSetPhyParameter(PVOID pDeviceHandler, CARD_PHY_TYPE ePHYType, WORD wCapInfo, BYTE byERPField, PVOID pvSupportRateIEs, PVOID pvExtSupportRateIEs); -BOOL CARDbUpdateTSF(PVOID pDeviceHandler, BYTE byRxRate, QWORD qwBSSTimestamp, QWORD qwLocalTSF); -BOOL CARDbStopTxPacket(PVOID pDeviceHandler, CARD_PKT_TYPE ePktType); -BOOL CARDbStartTxPacket(PVOID pDeviceHandler, CARD_PKT_TYPE ePktType); -BOOL CARDbSetBeaconPeriod(PVOID pDeviceHandler, WORD wBeaconInterval); -BOOL CARDbSetBSSID(PVOID pDeviceHandler, PBYTE pbyBSSID, CARD_OP_MODE eOPMode); +BOOL CARDbRadioPowerOff(void *pDeviceHandler); +BOOL CARDbRadioPowerOn(void *pDeviceHandler); +BOOL CARDbSetChannel(void *pDeviceHandler, UINT uConnectionChannel); +//BOOL CARDbSendPacket(void *pDeviceHandler, void *pPacket, CARD_PKT_TYPE ePktType, UINT uLength); +BOOL CARDbIsShortPreamble(void *pDeviceHandler); +BOOL CARDbIsShorSlotTime(void *pDeviceHandler); +BOOL CARDbSetPhyParameter(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, WORD wCapInfo, BYTE byERPField, void *pvSupportRateIEs, void *pvExtSupportRateIEs); +BOOL CARDbUpdateTSF(void *pDeviceHandler, BYTE byRxRate, QWORD qwBSSTimestamp, QWORD qwLocalTSF); +BOOL CARDbStopTxPacket(void *pDeviceHandler, CARD_PKT_TYPE ePktType); +BOOL CARDbStartTxPacket(void *pDeviceHandler, CARD_PKT_TYPE ePktType); +BOOL CARDbSetBeaconPeriod(void *pDeviceHandler, WORD wBeaconInterval); +BOOL CARDbSetBSSID(void *pDeviceHandler, PBYTE pbyBSSID, CARD_OP_MODE eOPMode); BOOL CARDbPowerDown( - PVOID pDeviceHandler + void *pDeviceHandler ); BOOL CARDbSetTxDataRate( - PVOID pDeviceHandler, + void *pDeviceHandler, WORD wDataRate ); -BOOL CARDbRemoveKey (PVOID pDeviceHandler, PBYTE pbyBSSID); +BOOL CARDbRemoveKey (void *pDeviceHandler, PBYTE pbyBSSID); BOOL CARDbAdd_PMKID_Candidate ( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, IN PBYTE pbyBSSID, IN BOOL bRSNCapExist, IN WORD wRSNCap ); -PVOID +void * CARDpGetCurrentAddress ( - IN PVOID pDeviceHandler + IN void *pDeviceHandler ); -void CARDvInitChannelTable(PVOID pDeviceHandler); -BYTE CARDbyGetChannelMapping(PVOID pDeviceHandler, BYTE byChannelNumber, CARD_PHY_TYPE ePhyType); +void CARDvInitChannelTable(void *pDeviceHandler); +BYTE CARDbyGetChannelMapping(void *pDeviceHandler, BYTE byChannelNumber, CARD_PHY_TYPE ePhyType); BOOL CARDbStartMeasure ( - IN PVOID pDeviceHandler, - IN PVOID pvMeasureEIDs, + IN void *pDeviceHandler, + IN void *pvMeasureEIDs, IN UINT uNumOfMeasureEIDs ); BOOL CARDbChannelSwitch ( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, IN BYTE byMode, IN BYTE byNewChannel, IN BYTE byCount @@ -165,7 +165,7 @@ CARDbChannelSwitch ( BOOL CARDbSetQuiet ( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, IN BOOL bResetQuiet, IN BYTE byQuietCount, IN BYTE byQuietPeriod, @@ -175,39 +175,39 @@ CARDbSetQuiet ( BOOL CARDbStartQuiet ( - IN PVOID pDeviceHandler + IN void *pDeviceHandler ); void CARDvSetCountryInfo ( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, IN CARD_PHY_TYPE ePHYType, - IN PVOID pIE + IN void *pIE ); void CARDvSetPowerConstraint ( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, IN BYTE byChannel, IN I8 byPower ); void CARDvGetPowerCapability ( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, OUT PBYTE pbyMinPower, OUT PBYTE pbyMaxPower ); BYTE CARDbySetSupportChannels ( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, IN OUT PBYTE pbyIEs ); I8 CARDbyGetTransmitPower ( - IN PVOID pDeviceHandler + IN void *pDeviceHandler ); BOOL @@ -218,13 +218,13 @@ CARDbChannelGetList ( void CARDvSetCountryIE( - IN PVOID pDeviceHandler, - IN PVOID pIE + IN void *pDeviceHandler, + IN void *pIE ); BOOL CARDbGetChannelMapInfo( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, IN UINT uChannelIndex, OUT PBYTE pbyChannelNumber, OUT PBYTE pbyMap @@ -232,23 +232,23 @@ CARDbGetChannelMapInfo( void CARDvSetChannelMapInfo( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, IN UINT uChannelIndex, IN BYTE byMap ); void CARDvClearChannelMapInfo( - IN PVOID pDeviceHandler + IN void *pDeviceHandler ); BYTE CARDbyAutoChannelSelect( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, CARD_PHY_TYPE ePHYType ); -BYTE CARDbyGetChannelNumber(PVOID pDeviceHandler, BYTE byChannelIndex); +BYTE CARDbyGetChannelNumber(void *pDeviceHandler, BYTE byChannelIndex); #endif // __CARD_H__ diff --git a/drivers/staging/vt6655/datarate.c b/drivers/staging/vt6655/datarate.c index eb7653cdb57c..e0d1a94f732a 100644 --- a/drivers/staging/vt6655/datarate.c +++ b/drivers/staging/vt6655/datarate.c @@ -196,7 +196,7 @@ wGetRateIdx( -*/ void RATEvParseMaxRate ( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, IN PWLAN_IE_SUPP_RATES pItemRates, IN PWLAN_IE_SUPP_RATES pItemExtRates, IN BOOL bUpdateBasicRate, @@ -235,7 +235,7 @@ UINT uRateLen; if (WLAN_MGMT_IS_BASICRATE(byRate) && (bUpdateBasicRate == TRUE)) { // Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate - CARDbAddBasicRate((PVOID)pDevice, wGetRateIdx(byRate)); + CARDbAddBasicRate((void *)pDevice, wGetRateIdx(byRate)); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate)); } byRate = (BYTE)(pItemRates->abyRates[ii]&0x7F); @@ -258,7 +258,7 @@ UINT uRateLen; // select highest basic rate if (WLAN_MGMT_IS_BASICRATE(pItemExtRates->abyRates[ii])) { // Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate - CARDbAddBasicRate((PVOID)pDevice, wGetRateIdx(byRate)); + CARDbAddBasicRate((void *)pDevice, wGetRateIdx(byRate)); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate)); } byRate = (BYTE)(pItemExtRates->abyRates[ii]&0x7F); @@ -271,7 +271,7 @@ UINT uRateLen; } } //if(pItemExtRates != NULL) - if ((pDevice->byPacketType == PK_TYPE_11GB) && CARDbIsOFDMinBasicRate((PVOID)pDevice)) { + if ((pDevice->byPacketType == PK_TYPE_11GB) && CARDbIsOFDMinBasicRate((void *)pDevice)) { pDevice->byPacketType = PK_TYPE_11GA; } @@ -283,7 +283,7 @@ UINT uRateLen; else *pwMaxBasicRate = pDevice->byTopOFDMBasicRate; if (wOldBasicRate != pDevice->wBasicRate) - CARDvSetRSPINF((PVOID)pDevice, pDevice->eCurrentPHYType); + CARDvSetRSPINF((void *)pDevice, pDevice->eCurrentPHYType); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Exit ParseMaxRate\n"); } @@ -309,7 +309,7 @@ UINT uRateLen; void RATEvTxRateFallBack ( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, IN PKnownNodeDB psNodeDBTable ) { diff --git a/drivers/staging/vt6655/datarate.h b/drivers/staging/vt6655/datarate.h index 1135fe3e6f89..bba4a16d004e 100644 --- a/drivers/staging/vt6655/datarate.h +++ b/drivers/staging/vt6655/datarate.h @@ -56,7 +56,7 @@ void RATEvParseMaxRate( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, IN PWLAN_IE_SUPP_RATES pItemRates, IN PWLAN_IE_SUPP_RATES pItemExtRates, IN BOOL bUpdateBasicRate, @@ -69,7 +69,7 @@ RATEvParseMaxRate( void RATEvTxRateFallBack( - IN PVOID pDeviceHandler, + IN void *pDeviceHandler, IN PKnownNodeDB psNodeDBTable ); diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 90ebad15c3dc..8a63a031d00b 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -729,7 +729,7 @@ else pDevice->abyOFDMPwrTbl[ii+CB_MAX_CHANNEL_24G+1] = SROMbyReadEmbedded(pDevice->PortOffset, (BYTE)(ii + EEP_OFS_OFDMA_PWR_TBL)); pDevice->abyOFDMDefaultPwr[ii+CB_MAX_CHANNEL_24G+1] = SROMbyReadEmbedded(pDevice->PortOffset, (BYTE)(ii + EEP_OFS_OFDMA_PWR_dBm)); } - CARDvInitChannelTable((PVOID)pDevice); + CARDvInitChannelTable((void *)pDevice); if (pDevice->byLocalID > REV_ID_VT3253_B1) { @@ -1074,7 +1074,7 @@ device_found1(struct pci_dev *pcid, const struct pci_device_id *ent) //Enable the chip specified capbilities pDevice->flags = pDevice->sOpts.flags | (pChip_info->flags & 0xFF000000UL); pDevice->tx_80211 = device_dma0_tx_80211; - pDevice->sMgmtObj.pAdapter = (PVOID)pDevice; + pDevice->sMgmtObj.pAdapter = (void *)pDevice; pDevice->pMgmt = &(pDevice->sMgmtObj); dev->irq = pcid->irq; @@ -1249,7 +1249,7 @@ device_release_WPADEV(pDevice); unregister_netdev(dev); if (pDevice->PortOffset) - iounmap((PVOID)pDevice->PortOffset); + iounmap((void *)pDevice->PortOffset); if (pDevice->pcid) pci_release_regions(pDevice->pcid); @@ -1461,7 +1461,7 @@ static void device_free_rd0_ring(PSDevice pDevice) { dev_kfree_skb(pRDInfo->skb); - kfree((PVOID)pDesc->pRDInfo); + kfree((void *)pDesc->pRDInfo); } } @@ -1479,7 +1479,7 @@ static void device_free_rd1_ring(PSDevice pDevice) { dev_kfree_skb(pRDInfo->skb); - kfree((PVOID)pDesc->pRDInfo); + kfree((void *)pDesc->pRDInfo); } } @@ -1564,7 +1564,7 @@ static void device_free_td0_ring(PSDevice pDevice) { if (pTDInfo->skb) dev_kfree_skb(pTDInfo->skb); - kfree((PVOID)pDesc->pTDInfo); + kfree((void *)pDesc->pTDInfo); } } @@ -1582,7 +1582,7 @@ static void device_free_td1_ring(PSDevice pDevice) { if (pTDInfo->skb) dev_kfree_skb(pTDInfo->skb); - kfree((PVOID)pDesc->pTDInfo); + kfree((void *)pDesc->pTDInfo); } } diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index 58dced747fa2..ab13bdfc51be 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -314,7 +314,7 @@ s_vGetDASA ( //PLICE_DEBUG -> -void MngWorkItem(PVOID Context) +void MngWorkItem(void *Context) { PSRxMgmtPacket pRxMgmtPacket; PSDevice pDevice = (PSDevice) Context; diff --git a/drivers/staging/vt6655/dpc.h b/drivers/staging/vt6655/dpc.h index 0860ea529693..4129c11e011a 100644 --- a/drivers/staging/vt6655/dpc.h +++ b/drivers/staging/vt6655/dpc.h @@ -47,7 +47,7 @@ device_receive_frame ( IN PSRxDesc pCurrRD ); -void MngWorkItem(PVOID Context); +void MngWorkItem(void *Context); #endif // __RXTX_H__ diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c index efff7db8aaf9..b40c400a23c3 100644 --- a/drivers/staging/vt6655/key.c +++ b/drivers/staging/vt6655/key.c @@ -104,10 +104,10 @@ void KeyvInitTable (PSKeyManagement pTable, DWORD_PTR dwIoBase) for (i=0;iKeyTable[i].bInUse = FALSE; pTable->KeyTable[i].PairwiseKey.bKeyValid = FALSE; - pTable->KeyTable[i].PairwiseKey.pvKeyTable = (PVOID)&pTable->KeyTable[i]; + pTable->KeyTable[i].PairwiseKey.pvKeyTable = (void *)&pTable->KeyTable[i]; for (jj=0; jj < MAX_GROUP_KEY; jj++) { pTable->KeyTable[i].GroupKey[jj].bKeyValid = FALSE; - pTable->KeyTable[i].GroupKey[jj].pvKeyTable = (PVOID)&pTable->KeyTable[i]; + pTable->KeyTable[i].GroupKey[jj].pvKeyTable = (void *)&pTable->KeyTable[i]; } pTable->KeyTable[i].wKeyCtl = 0; pTable->KeyTable[i].dwGTKeyIndex = 0; diff --git a/drivers/staging/vt6655/key.h b/drivers/staging/vt6655/key.h index 766ff049553d..4cbd82f76e4e 100644 --- a/drivers/staging/vt6655/key.h +++ b/drivers/staging/vt6655/key.h @@ -66,7 +66,7 @@ typedef struct tagSKeyItem BYTE byCipherSuite; BYTE byReserved0; DWORD dwKeyIndex; - PVOID pvKeyTable; + void *pvKeyTable; } SKeyItem, *PSKeyItem; //64 typedef struct tagSKeyTable diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index effefdb77b61..8d1772e70ab1 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -133,7 +133,7 @@ void s_vFillRTSHead( IN PSDevice pDevice, IN BYTE byPktType, - IN PVOID pvRTS, + IN void * pvRTS, IN UINT cbFrameLength, IN BOOL bNeedAck, IN BOOL bDisCRC, @@ -147,10 +147,10 @@ void s_vGenerateTxParameter( IN PSDevice pDevice, IN BYTE byPktType, - IN PVOID pTxBufHead, - IN PVOID pvRrvTime, - IN PVOID pvRTS, - IN PVOID pvCTS, + IN void * pTxBufHead, + IN void * pvRrvTime, + IN void * pvRTS, + IN void * pvCTS, IN UINT cbFrameSize, IN BOOL bNeedACK, IN UINT uDMAIdx, @@ -164,7 +164,7 @@ static void s_vFillFragParameter( IN PSDevice pDevice, IN PBYTE pbyBuffer, IN UINT uTxType, - IN PVOID pvtdCurr, + IN void * pvtdCurr, IN WORD wFragType, IN UINT cbReqCount ); @@ -193,7 +193,7 @@ UINT s_uFillDataHead ( IN PSDevice pDevice, IN BYTE byPktType, - IN PVOID pTxDataHead, + IN void * pTxDataHead, IN UINT cbFrameLength, IN UINT uDMAIdx, IN BOOL bNeedAck, @@ -723,7 +723,7 @@ UINT s_uFillDataHead ( IN PSDevice pDevice, IN BYTE byPktType, - IN PVOID pTxDataHead, + IN void * pTxDataHead, IN UINT cbFrameLength, IN UINT uDMAIdx, IN BOOL bNeedAck, @@ -855,7 +855,7 @@ void s_vFillRTSHead ( IN PSDevice pDevice, IN BYTE byPktType, - IN PVOID pvRTS, + IN void * pvRTS, IN UINT cbFrameLength, IN BOOL bNeedAck, IN BOOL bDisCRC, @@ -1050,7 +1050,7 @@ s_vFillCTSHead ( IN PSDevice pDevice, IN UINT uDMAIdx, IN BYTE byPktType, - IN PVOID pvCTS, + IN void * pvCTS, IN UINT cbFrameLength, IN BOOL bNeedAck, IN BOOL bDisCRC, @@ -1154,10 +1154,10 @@ void s_vGenerateTxParameter ( IN PSDevice pDevice, IN BYTE byPktType, - IN PVOID pTxBufHead, - IN PVOID pvRrvTime, - IN PVOID pvRTS, - IN PVOID pvCTS, + IN void * pTxBufHead, + IN void * pvRrvTime, + IN void * pvRTS, + IN void * pvCTS, IN UINT cbFrameSize, IN BOOL bNeedACK, IN UINT uDMAIdx, @@ -1273,7 +1273,7 @@ s_vFillFragParameter( IN PSDevice pDevice, IN PBYTE pbyBuffer, IN UINT uTxType, - IN PVOID pvtdCurr, + IN void * pvtdCurr, IN WORD wFragType, IN UINT cbReqCount ) @@ -1376,11 +1376,11 @@ s_cbFillTxBufHead ( PSTxBufHead psTxBufHd = (PSTxBufHead) pbyTxBufferAddr; // UINT tmpDescIdx; UINT cbHeaderLength = 0; - PVOID pvRrvTime; + void * pvRrvTime; PSMICHDRHead pMICHDR; - PVOID pvRTS; - PVOID pvCTS; - PVOID pvTxDataHd; + void * pvRTS; + void * pvCTS; + void * pvTxDataHd; WORD wTxBufSize; // FFinfo size UINT uTotalCopyLength = 0; BYTE byFBOption = AUTO_FB_NONE; @@ -1544,7 +1544,7 @@ s_cbFillTxBufHead ( } } // Auto Fall Back } - memset((PVOID)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize)); + memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize)); ////////////////////////////////////////////////////////////////// if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { @@ -1600,7 +1600,7 @@ s_cbFillTxBufHead ( //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, (PVOID)psTxBufHd, pvRrvTime, pvRTS, pvCTS, + s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS, cbFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); //Fill DataHead uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK, @@ -1643,7 +1643,7 @@ s_cbFillTxBufHead ( //if (pDevice->bAES) { // s_vFillMICHDR(pDevice, (PBYTE)pMICHDR, pbyMacHdr, (WORD)cbFragPayloadSize); //} - //cbReqCount += s_uDoEncryption(pDevice, psEthHeader, (PVOID)psTxBufHd, byKeySel, + //cbReqCount += s_uDoEncryption(pDevice, psEthHeader, (void *)psTxBufHd, byKeySel, // pbyPayloadHead, (WORD)cbFragPayloadSize, uDMAIdx); @@ -1653,7 +1653,7 @@ s_cbFillTxBufHead ( uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len; //copy TxBufferHeader + MacHeader to desc - memcpy(pbyBuffer, (PVOID)psTxBufHd, uLength); + memcpy(pbyBuffer, (void *)psTxBufHd, uLength); // Copy the Packet into a tx Buffer memcpy((pbyBuffer + uLength), (pPacket + 14), (cbFragPayloadSize - cb802_1_H_len)); @@ -1685,7 +1685,7 @@ s_cbFillTxBufHead ( //4.Set Sequence Control //5.Get S/W generate FCS //-------------------- - s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (PVOID)ptdCurr, wFragType, cbReqCount); + s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount); ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; @@ -1704,7 +1704,7 @@ s_cbFillTxBufHead ( wFragType = FRAGCTL_ENDFRAG; //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, (PVOID)psTxBufHd, pvRrvTime, pvRTS, pvCTS, + s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS, cbLastFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); //Fill DataHead uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbLastFragmentSize, uDMAIdx, bNeedACK, @@ -1740,7 +1740,7 @@ s_cbFillTxBufHead ( uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen; //copy TxBufferHeader + MacHeader to desc - memcpy(pbyBuffer, (PVOID)psTxBufHd, uLength); + memcpy(pbyBuffer, (void *)psTxBufHd, uLength); // Copy the Packet into a tx Buffer if (bMIC2Frag == FALSE) { @@ -1814,7 +1814,7 @@ s_cbFillTxBufHead ( //-------------------- - s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (PVOID)ptdCurr, wFragType, cbReqCount); + s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount); ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; @@ -1834,7 +1834,7 @@ s_cbFillTxBufHead ( wFragType = FRAGCTL_MIDFRAG; //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, (PVOID)psTxBufHd, pvRrvTime, pvRTS, pvCTS, + s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS, cbFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); //Fill DataHead uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK, @@ -1864,7 +1864,7 @@ s_cbFillTxBufHead ( //if (pDevice->bAES) { // s_vFillMICHDR(pDevice, (PBYTE)pMICHDR, pbyMacHdr, (WORD)cbFragPayloadSize); //} - //cbReqCount += s_uDoEncryption(pDevice, psEthHeader, (PVOID)psTxBufHd, byKeySel, + //cbReqCount += s_uDoEncryption(pDevice, psEthHeader, (void *)psTxBufHd, byKeySel, // pbyPayloadHead, (WORD)cbFragPayloadSize, uDMAIdx); @@ -1875,7 +1875,7 @@ s_cbFillTxBufHead ( uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen; //copy TxBufferHeader + MacHeader to desc - memcpy(pbyBuffer, (PVOID)psTxBufHd, uLength); + memcpy(pbyBuffer, (void *)psTxBufHd, uLength); // Copy the Packet into a tx Buffer memcpy((pbyBuffer + uLength), @@ -1941,7 +1941,7 @@ s_cbFillTxBufHead ( //5.Get S/W generate FCS //-------------------- - s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (PVOID)ptdCurr, wFragType, cbReqCount); + s_vFillFragParameter(pDevice, pbyBuffer, uDMAIdx, (void *)ptdCurr, wFragType, cbReqCount); ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; @@ -1964,7 +1964,7 @@ s_cbFillTxBufHead ( psTxBufHd->wFragCtl |= (WORD)wFragType; //Fill FIFO,RrvTime,RTS,and CTS - s_vGenerateTxParameter(pDevice, byPktType, (PVOID)psTxBufHd, pvRrvTime, pvRTS, pvCTS, + s_vGenerateTxParameter(pDevice, byPktType, (void *)psTxBufHd, pvRrvTime, pvRTS, pvCTS, cbFrameSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate); //Fill DataHead uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK, @@ -2015,7 +2015,7 @@ s_cbFillTxBufHead ( uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len; //copy TxBufferHeader + MacHeader to desc - memcpy(pbyBuffer, (PVOID)psTxBufHd, uLength); + memcpy(pbyBuffer, (void *)psTxBufHd, uLength); // Copy the Packet into a tx Buffer memcpy((pbyBuffer + uLength), @@ -2342,9 +2342,9 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) { PSTxDesc pFrstTD; BYTE byPktType; PBYTE pbyTxBufferAddr; - PVOID pvRTS; + void * pvRTS; PSCTS pCTS; - PVOID pvTxDataHd; + void * pvTxDataHd; UINT uDuration; UINT cbReqCount; PS802_11Header pMACHeader; @@ -2362,8 +2362,8 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) { WORD wTxBufSize; UINT cbMacHdLen; SEthernetHeader sEthHeader; - PVOID pvRrvTime; - PVOID pMICHDR; + void * pvRrvTime; + void * pMICHDR; PSMgmtObject pMgmt = pDevice->pMgmt; WORD wCurrentRate = RATE_1M; @@ -2516,7 +2516,7 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) { cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + sizeof(STxDataHead_ab); } - memset((PVOID)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); + memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); memcpy(&(sEthHeader.abyDstAddr[0]), &(pPacket->p80211Header->sA3.abyAddr1[0]), U_ETHER_ADDR_LEN); memcpy(&(sEthHeader.abySrcAddr[0]), &(pPacket->p80211Header->sA3.abyAddr2[0]), U_ETHER_ADDR_LEN); @@ -2831,9 +2831,9 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU PSTxDesc pFrstTD; BYTE byPktType; PBYTE pbyTxBufferAddr; - PVOID pvRTS; - PVOID pvCTS; - PVOID pvTxDataHd; + void * pvRTS; + void * pvCTS; + void * pvTxDataHd; UINT uDuration; UINT cbReqCount; PS802_11Header pMACHeader; @@ -2857,8 +2857,8 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU WORD wTxBufSize; UINT cbMacHdLen; SEthernetHeader sEthHeader; - PVOID pvRrvTime; - PVOID pMICHDR; + void * pvRrvTime; + void * pMICHDR; PSMgmtObject pMgmt = pDevice->pMgmt; WORD wCurrentRate = RATE_1M; PUWLAN_80211HDR p80211Header; @@ -3061,7 +3061,7 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU } - memset((PVOID)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); + memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); memcpy(&(sEthHeader.abyDstAddr[0]), &(p80211Header->sA3.abyAddr1[0]), U_ETHER_ADDR_LEN); memcpy(&(sEthHeader.abySrcAddr[0]), &(p80211Header->sA3.abyAddr2[0]), U_ETHER_ADDR_LEN); //========================= diff --git a/drivers/staging/vt6655/ttype.h b/drivers/staging/vt6655/ttype.h index 24d0eca9420f..b71fe591005a 100644 --- a/drivers/staging/vt6655/ttype.h +++ b/drivers/staging/vt6655/ttype.h @@ -132,13 +132,6 @@ typedef DWORD * PDWORD; typedef QWORD * PQWORD; -typedef void * PVOID; - -// handle declaration -#ifdef STRICT typedef void *HANDLE; -#else -typedef PVOID HANDLE; -#endif #endif // __TTYPE_H__ diff --git a/drivers/staging/vt6655/vntwifi.c b/drivers/staging/vt6655/vntwifi.c index cbfa8e80dd68..03975dabb8d5 100644 --- a/drivers/staging/vt6655/vntwifi.c +++ b/drivers/staging/vt6655/vntwifi.c @@ -71,7 +71,7 @@ -*/ void VNTWIFIvSetOPMode ( - IN PVOID pMgmtHandle, + IN void *pMgmtHandle, IN WMAC_CONFIG_MODE eOPMode ) { @@ -100,7 +100,7 @@ VNTWIFIvSetOPMode ( -*/ void VNTWIFIvSetIBSSParameter ( - IN PVOID pMgmtHandle, + IN void *pMgmtHandle, IN WORD wBeaconPeriod, IN WORD wATIMWindow, IN UINT uChannel @@ -129,7 +129,7 @@ VNTWIFIvSetIBSSParameter ( -*/ PWLAN_IE_SSID VNTWIFIpGetCurrentSSID ( - IN PVOID pMgmtHandle + IN void *pMgmtHandle ) { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; @@ -152,7 +152,7 @@ VNTWIFIpGetCurrentSSID ( -*/ UINT VNTWIFIpGetCurrentChannel ( - IN PVOID pMgmtHandle + IN void *pMgmtHandle ) { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; @@ -178,7 +178,7 @@ VNTWIFIpGetCurrentChannel ( -*/ WORD VNTWIFIwGetAssocID ( - IN PVOID pMgmtHandle + IN void *pMgmtHandle ) { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; @@ -308,7 +308,7 @@ VNTWIFIbyGetACKTxRate ( -*/ void VNTWIFIvSetAuthenticationMode ( - IN PVOID pMgmtHandle, + IN void *pMgmtHandle, IN WMAC_AUTHENTICATION_MODE eAuthMode ) { @@ -340,7 +340,7 @@ VNTWIFIvSetAuthenticationMode ( -*/ void VNTWIFIvSetEncryptionMode ( - IN PVOID pMgmtHandle, + IN void *pMgmtHandle, IN WMAC_ENCRYPTION_MODE eEncryptionMode ) { @@ -360,7 +360,7 @@ VNTWIFIvSetEncryptionMode ( BOOL VNTWIFIbConfigPhyMode ( - IN PVOID pMgmtHandle, + IN void *pMgmtHandle, IN CARD_PHY_TYPE ePhyType ) { @@ -381,8 +381,8 @@ VNTWIFIbConfigPhyMode ( void VNTWIFIbGetConfigPhyMode ( - IN PVOID pMgmtHandle, - OUT PVOID pePhyType + IN void *pMgmtHandle, + OUT void *pePhyType ) { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; @@ -426,9 +426,9 @@ VNTWIFIbGetConfigPhyMode ( void VNTWIFIvQueryBSSList ( - IN PVOID pMgmtHandle, + IN void *pMgmtHandle, OUT PUINT puBSSCount, - OUT PVOID *pvFirstBSS + OUT void **pvFirstBSS ) { UINT ii = 0; @@ -456,9 +456,9 @@ VNTWIFIvQueryBSSList ( void VNTWIFIvGetNextBSS ( - IN PVOID pMgmtHandle, - IN PVOID pvCurrentBSS, - OUT PVOID *pvNextBSS + IN void *pMgmtHandle, + IN void *pvCurrentBSS, + OUT void **pvNextBSS ) { PKnownBSS pBSS = (PKnownBSS) pvCurrentBSS; @@ -496,7 +496,7 @@ VNTWIFIvGetNextBSS ( -*/ void VNTWIFIvUpdateNodeTxCounter( - IN PVOID pMgmtHandle, + IN void *pMgmtHandle, IN PBYTE pbyDestAddress, IN BOOL bTxOk, IN WORD wRate, @@ -531,7 +531,7 @@ VNTWIFIvUpdateNodeTxCounter( void VNTWIFIvGetTxRate( - IN PVOID pMgmtHandle, + IN void *pMgmtHandle, IN PBYTE pbyDestAddress, OUT PWORD pwTxDataRate, OUT PBYTE pbyACKRate, @@ -603,7 +603,7 @@ VNTWIFIvGetTxRate( BYTE VNTWIFIbyGetKeyCypher( - IN PVOID pMgmtHandle, + IN void *pMgmtHandle, IN BOOL bGroupKey ) { @@ -620,8 +620,8 @@ VNTWIFIbyGetKeyCypher( /* BOOL VNTWIFIbInit( - IN PVOID pAdapterHandler, - OUT PVOID *pMgmtHandler + IN void *pAdapterHandler, + OUT void **pMgmtHandler ) { @@ -636,7 +636,7 @@ VNTWIFIbInit( } memset(pMgmt, 0, sizeof(SMgmtObject)); - pMgmt->pAdapter = (PVOID) pAdapterHandler; + pMgmt->pAdapter = (void *) pAdapterHandler; // should initial MAC address abyMACAddr for(ii=0;iiabyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abyExtSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, uRateLen); - RATEvParseMaxRate( (PVOID)pDevice, + RATEvParseMaxRate( (void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, TRUE, @@ -2256,7 +2256,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, WLAN_RATES_MAXLEN_11B); - RATEvParseMaxRate( (PVOID)pDevice, + RATEvParseMaxRate( (void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, NULL, TRUE, @@ -2277,7 +2277,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, WLAN_RATES_MAXLEN_11B); - RATEvParseMaxRate( (PVOID)pDevice, + RATEvParseMaxRate( (void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, NULL, TRUE, @@ -2485,7 +2485,7 @@ vMgrCreateOwnIBSS( // set basic rate - RATEvParseMaxRate((PVOID)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, TRUE, &wMaxBasicRate, &wMaxSuppRate, &wSuppRate, &byTopCCKBasicRate, &byTopOFDMBasicRate); @@ -2781,7 +2781,7 @@ vMgrJoinBSSBegin( } } - RATEvParseMaxRate((PVOID)pDevice, pItemRates, pItemExtRates, TRUE, + RATEvParseMaxRate((void *)pDevice, pItemRates, pItemExtRates, TRUE, &wMaxBasicRate, &wMaxSuppRate, &wSuppRate, &byTopCCKBasicRate, &byTopOFDMBasicRate); @@ -2867,7 +2867,7 @@ vMgrJoinBSSBegin( (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, WLAN_RATES_MAXLEN_11B); // set basic rate - RATEvParseMaxRate((PVOID)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, + RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, NULL, TRUE, &wMaxBasicRate, &wMaxSuppRate, &wSuppRate, &byTopCCKBasicRate, &byTopOFDMBasicRate); @@ -2967,7 +2967,7 @@ s_vMgrSynchBSS ( pDevice->byPreambleType = 0; pDevice->wBasicRate = 0; // Set Basic Rate - CARDbAddBasicRate((PVOID)pDevice, RATE_1M); + CARDbAddBasicRate((void *)pDevice, RATE_1M); // calculate TSF offset // TSF Offset = Received Timestamp TSF - Marked Local's TSF CARDbUpdateTSF(pDevice, pCurr->byRxRate, pCurr->qwBSSTimestamp, pCurr->qwLocalTSF); diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index 5963b146ee23..5eabc199c020 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -249,7 +249,7 @@ typedef struct tagSRxMgmtPacket { typedef struct tagSMgmtObject { - PVOID pAdapter; + void * pAdapter; // MAC address BYTE abyMACAddr[WLAN_ADDR_LEN]; diff --git a/drivers/staging/vt6655/wpa2.c b/drivers/staging/vt6655/wpa2.c index 183d28c29a5a..3f377b6a2bac 100644 --- a/drivers/staging/vt6655/wpa2.c +++ b/drivers/staging/vt6655/wpa2.c @@ -263,7 +263,7 @@ WPA2vParseRSN ( -*/ UINT WPA2uSetIEs( - IN PVOID pMgmtHandle, + IN void *pMgmtHandle, OUT PWLAN_IE_RSN pRSNIEs ) { diff --git a/drivers/staging/vt6655/wpa2.h b/drivers/staging/vt6655/wpa2.h index cbd75d0d2bbb..7becc749c9ff 100644 --- a/drivers/staging/vt6655/wpa2.h +++ b/drivers/staging/vt6655/wpa2.h @@ -71,7 +71,7 @@ WPA2vParseRSN ( UINT WPA2uSetIEs( - IN PVOID pMgmtHandle, + IN void *pMgmtHandle, OUT PWLAN_IE_RSN pRSNIEs ); -- cgit v1.2.3 From 9bf10920a094d71cec1076d3fa941aa6f31b09eb Mon Sep 17 00:00:00 2001 From: Lars Lindley Date: Sat, 8 May 2010 14:53:54 +0200 Subject: staging: winbond: localpara.h whitespace and indentation fixes. I fixed all problems found by checkpatch.pl except a number of long lines that I didn't find a good way to break up and still keep it readable. I added the () to #define MAX_IE_APPEND_SIZE (256 + 4). I also moved som comments around after pointers from Pekka. Signed-off-by: Lars Lindley Acked-by: Pekka Enberg Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/localpara.h | 452 ++++++++++++++++++------------------ 1 file changed, 228 insertions(+), 224 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/localpara.h b/drivers/staging/winbond/localpara.h index fcf6a0442dc2..d7980575bed1 100644 --- a/drivers/staging/winbond/localpara.h +++ b/drivers/staging/winbond/localpara.h @@ -1,263 +1,267 @@ #ifndef __WINBOND_LOCALPARA_H #define __WINBOND_LOCALPARA_H -//============================================================= -// LocalPara.h - -//============================================================= +/* + * ============================================================= + * LocalPara.h - + * ============================================================= + */ #include "mac_structures.h" -//Define the local ability +/* Define the local ability */ -#define LOCAL_DEFAULT_BEACON_PERIOD 100 //ms -#define LOCAL_DEFAULT_ATIM_WINDOW 0 -#define LOCAL_DEFAULT_ERP_CAPABILITY 0x0431 //0x0001: ESS - //0x0010: Privacy - //0x0020: short preamble - //0x0400: short slot time -#define LOCAL_DEFAULT_LISTEN_INTERVAL 5 +#define LOCAL_DEFAULT_BEACON_PERIOD 100 /* ms */ +#define LOCAL_DEFAULT_ATIM_WINDOW 0 +#define LOCAL_DEFAULT_ERP_CAPABILITY 0x0431 /* + * 0x0001: ESS + * 0x0010: Privacy + * 0x0020: short preamble + * 0x0400: short slot time + */ +#define LOCAL_DEFAULT_LISTEN_INTERVAL 5 -//#define LOCAL_DEFAULT_24_CHANNEL_NUM 11 // channel 1..11 -#define LOCAL_DEFAULT_24_CHANNEL_NUM 13 // channel 1..13 -#define LOCAL_DEFAULT_5_CHANNEL_NUM 8 // channel 36..64 +#define LOCAL_DEFAULT_24_CHANNEL_NUM 13 /* channel 1..13 */ +#define LOCAL_DEFAULT_5_CHANNEL_NUM 8 /* channel 36..64 */ -#define LOCAL_USA_24_CHANNEL_NUM 11 -#define LOCAL_USA_5_CHANNEL_NUM 12 -#define LOCAL_EUROPE_24_CHANNEL_NUM 13 -#define LOCAL_EUROPE_5_CHANNEL_NUM 19 -#define LOCAL_JAPAN_24_CHANNEL_NUM 14 -#define LOCAL_JAPAN_5_CHANNEL_NUM 11 -#define LOCAL_UNKNOWN_24_CHANNEL_NUM 14 -#define LOCAL_UNKNOWN_5_CHANNEL_NUM 34 //not include 165 +#define LOCAL_USA_24_CHANNEL_NUM 11 +#define LOCAL_USA_5_CHANNEL_NUM 12 +#define LOCAL_EUROPE_24_CHANNEL_NUM 13 +#define LOCAL_EUROPE_5_CHANNEL_NUM 19 +#define LOCAL_JAPAN_24_CHANNEL_NUM 14 +#define LOCAL_JAPAN_5_CHANNEL_NUM 11 +#define LOCAL_UNKNOWN_24_CHANNEL_NUM 14 +#define LOCAL_UNKNOWN_5_CHANNEL_NUM 34 /* not include 165 */ - -#define psLOCAL (&(adapter->sLocalPara)) +#define psLOCAL (&(adapter->sLocalPara)) #define MODE_802_11_BG 0 #define MODE_802_11_A 1 #define MODE_802_11_ABG 2 #define MODE_802_11_BG_IBSS 3 #define MODE_802_11_B 4 -#define MODE_AUTO 255 +#define MODE_AUTO 255 #define BAND_TYPE_DSSS 0 #define BAND_TYPE_OFDM_24 1 #define BAND_TYPE_OFDM_5 2 -//refer Bitmap2RateValue table -#define LOCAL_ALL_SUPPORTED_RATES_BITMAP 0x130c1a66 //the bitmap value of all the H/W supported rates - //1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 -#define LOCAL_OFDM_SUPPORTED_RATES_BITMAP 0x130c1240 //the bitmap value of all the H/W supported rates - //except to non-OFDM rates - //6, 9, 12, 18, 24, 36, 48, 54 - -#define LOCAL_11B_SUPPORTED_RATE_BITMAP 0x826 -#define LOCAL_11B_BASIC_RATE_BITMAP 0x826 -#define LOCAL_11B_OPERATION_RATE_BITMAP 0x826 -#define LOCAL_11G_BASIC_RATE_BITMAP 0x826 //1, 2, 5.5, 11 -#define LOCAL_11G_OPERATION_RATE_BITMAP 0x130c1240 //6, 9, 12, 18, 24, 36, 48, 54 -#define LOCAL_11A_BASIC_RATE_BITMAP 0x01001040 //6, 12, 24 -#define LOCAL_11A_OPERATION_RATE_BITMAP 0x120c0200 //9, 18, 36, 48, 54 - - - -#define PWR_ACTIVE 0 -#define PWR_SAVE 1 +/* refer Bitmap2RateValue table */ + +/* the bitmap value of all the H/W supported rates: */ +/* 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */ +#define LOCAL_ALL_SUPPORTED_RATES_BITMAP 0x130c1a66 +/* the bitmap value of all the H/W supported rates except to non-OFDM rates: */ +/* 6, 9, 12, 18, 24, 36, 48, 54 */ +#define LOCAL_OFDM_SUPPORTED_RATES_BITMAP 0x130c1240 +#define LOCAL_11B_SUPPORTED_RATE_BITMAP 0x826 +#define LOCAL_11B_BASIC_RATE_BITMAP 0x826 +#define LOCAL_11B_OPERATION_RATE_BITMAP 0x826 +#define LOCAL_11G_BASIC_RATE_BITMAP 0x826 /* 1, 2, 5.5, 11 */ +#define LOCAL_11G_OPERATION_RATE_BITMAP 0x130c1240 /* 6, 9, 12, 18, 24, 36, 48, 54 */ +#define LOCAL_11A_BASIC_RATE_BITMAP 0x01001040 /* 6, 12, 24 */ +#define LOCAL_11A_OPERATION_RATE_BITMAP 0x120c0200 /* 9, 18, 36, 48, 54 */ + + +#define PWR_ACTIVE 0 +#define PWR_SAVE 1 #define PWR_TX_IDLE_CYCLE 6 -//bPreambleMode and bSlotTimeMode -#define AUTO_MODE 0 -#define LONG_MODE 1 - -//Region definition -#define REGION_AUTO 0xff -#define REGION_UNKNOWN 0 -#define REGION_EUROPE 1 //ETSI -#define REGION_JAPAN 2 //MKK -#define REGION_USA 3 //FCC -#define REGION_FRANCE 4 //FRANCE -#define REGION_SPAIN 5 //SPAIN -#define REGION_ISRAEL 6 //ISRAEL -//#define REGION_CANADA 7 //IC +/* bPreambleMode and bSlotTimeMode */ +#define AUTO_MODE 0 +#define LONG_MODE 1 + +/* Region definition */ +#define REGION_AUTO 0xff +#define REGION_UNKNOWN 0 +#define REGION_EUROPE 1 /* ETSI */ +#define REGION_JAPAN 2 /* MKK */ +#define REGION_USA 3 /* FCC */ +#define REGION_FRANCE 4 /* FRANCE */ +#define REGION_SPAIN 5 /* SPAIN */ +#define REGION_ISRAEL 6 /* ISRAEL */ #define MAX_BSS_DESCRIPT_ELEMENT 32 -#define MAX_PMKID_CandidateList 16 - -//High byte : Event number, low byte : reason -//Event definition -//-- SME/MLME event -#define EVENT_RCV_DEAUTH 0x0100 -#define EVENT_JOIN_FAIL 0x0200 -#define EVENT_AUTH_FAIL 0x0300 -#define EVENT_ASSOC_FAIL 0x0400 -#define EVENT_LOST_SIGNAL 0x0500 -#define EVENT_BSS_DESCRIPT_LACK 0x0600 -#define EVENT_COUNTERMEASURE 0x0700 -#define EVENT_JOIN_FILTER 0x0800 -//-- TX/RX event -#define EVENT_RX_BUFF_UNAVAILABLE 0x4100 - -#define EVENT_CONNECT 0x8100 -#define EVENT_DISCONNECT 0x8200 -#define EVENT_SCAN_REQ 0x8300 - -//Reason of Event +#define MAX_PMKID_CandidateList 16 + +/* + * High byte : Event number, low byte : reason + * Event definition + * -- SME/MLME event + */ +#define EVENT_RCV_DEAUTH 0x0100 +#define EVENT_JOIN_FAIL 0x0200 +#define EVENT_AUTH_FAIL 0x0300 +#define EVENT_ASSOC_FAIL 0x0400 +#define EVENT_LOST_SIGNAL 0x0500 +#define EVENT_BSS_DESCRIPT_LACK 0x0600 +#define EVENT_COUNTERMEASURE 0x0700 +#define EVENT_JOIN_FILTER 0x0800 +/* -- TX/RX event */ +#define EVENT_RX_BUFF_UNAVAILABLE 0x4100 + +#define EVENT_CONNECT 0x8100 +#define EVENT_DISCONNECT 0x8200 +#define EVENT_SCAN_REQ 0x8300 + +/* Reason of Event */ #define EVENT_REASON_FILTER_BASIC_RATE 0x0001 -#define EVENT_REASON_FILTER_PRIVACY 0x0002 +#define EVENT_REASON_FILTER_PRIVACY 0x0002 #define EVENT_REASON_FILTER_AUTH_MODE 0x0003 -#define EVENT_REASON_TIMEOUT 0x00ff +#define EVENT_REASON_TIMEOUT 0x00ff -// 20061108 WPS IE buffer -#define MAX_IE_APPEND_SIZE 256 + 4 // Due to [E id][Length][OUI][Data] may 257 bytes +/* Due to[E id][Length][OUI][Data] may be 257 bytes */ +#define MAX_IE_APPEND_SIZE (256 + 4) -struct chan_info -{ - u8 band; - u8 ChanNo; +struct chan_info { + u8 band; + u8 ChanNo; }; -struct radio_off -{ - u8 boHwRadioOff; - u8 boSwRadioOff; +struct radio_off { + u8 boHwRadioOff; + u8 boSwRadioOff; }; -//=========================================================================== -struct wb_local_para -{ - u8 PermanentAddress[ MAC_ADDR_LENGTH + 2 ]; // read from EPROM, manufacture set for each NetCard - u8 ThisMacAddress[ MAC_ADDR_LENGTH + 2 ]; // the driver will use actually. - - u32 MTUsize; // Ind to Uplayer, Max transmission unit size - - u8 region_INF; //region setting from INF - u8 region; //real region setting of the device - u8 Reserved_1[2]; - - //// power-save variables - u8 iPowerSaveMode; // 0 indicates it is on, 1 indicates it is off - u8 ATIMmode; - u8 ExcludeUnencrypted; - - u16 CheckCountForPS; //Unit ime count for the decision to enter PS mode - u8 boHasTxActivity; //tx activity has occurred - u8 boMacPsValid; //Power save mode obtained from H/W is valid or not - - //// Rate - u8 TxRateMode; // Initial, input from Registry, may be updated by GUI - //Tx Rate Mode: auto(DTO on), max, 1M, 2M, .. - u8 CurrentTxRate; // The current Tx rate - u8 CurrentTxRateForMng; // The current Tx rate for management frames - // It will be decided before connection succeeds. - u8 CurrentTxFallbackRate; - - //for Rate handler - u8 BRateSet[32]; //basic rate set - u8 SRateSet[32]; //support rate set - - u8 NumOfBRate; - u8 NumOfSRate; - u8 NumOfDsssRateInSRate; //number of DSSS rates in supported rate set - u8 reserved1; - - u32 dwBasicRateBitmap; //bit map of basic rates - u32 dwSupportRateBitmap; //bit map of all support rates including - //basic and operational rates - - ////For SME/MLME handler - u16 wOldSTAindex; // valid when boHandover=TRUE, store old connected STA index - u16 wConnectedSTAindex; // Index of peerly connected AP or IBSS in - // the descriptionset. - u16 Association_ID; // The Association ID in the (Re)Association - // Response frame. - u16 ListenInterval; // The listen interval when SME invoking MLME_ - // (Re)Associate_Request(). - - struct radio_off RadioOffStatus; - u8 Reserved0[2]; - - u8 boMsRadioOff; // Ndis demands to be true when set Disassoc. OID and be false when set SSID OID. - u8 bAntennaNo; //which antenna - u8 bConnectFlag; //the connect status flag for roaming task - - u8 RoamStatus; - u8 reserved7[3]; - - struct chan_info CurrentChan; //Current channel no. and channel band. It may be changed by scanning. - u8 boHandover; // Roaming, Hnadover to other AP. - u8 boCCAbusy; - - u16 CWMax; // It may not be the real value that H/W used - u8 CWMin; // 255: set according to 802.11 spec. - u8 reserved2; - - //11G: - u8 bMacOperationMode; // operation in 802.11b or 802.11g - u8 bSlotTimeMode; //AUTO, s32 - u8 bPreambleMode; //AUTO, s32 - u8 boNonERPpresent; - - u8 boProtectMechanism; // H/W will take the necessary action based on this variable - u8 boShortPreamble; // H/W will take the necessary action based on this variable - u8 boShortSlotTime; // H/W will take the necessary action based on this variable - u8 reserved_3; - - u32 RSN_IE_Bitmap; //added by WS - u32 RSN_OUI_Type; //added by WS - - //For the BSSID - u8 HwBssid[MAC_ADDR_LENGTH + 2]; - u32 HwBssidValid; - - //For scan list - u8 BssListCount; //Total count of valid descriptor indexes - u8 boReceiveUncorrectInfo; //important settings in beacon/probe resp. have been changed - u8 NoOfJoinerInIbss; - u8 reserved_4; - - u8 BssListIndex[ (MAX_BSS_DESCRIPT_ELEMENT+3) & ~0x03 ]; //Store the valid descriptor indexes obtained from scannings - u8 JoinerInIbss[ (MAX_BSS_DESCRIPT_ELEMENT+3) & ~0x03 ]; //save the BssDescriptor index in this - //IBSS. The index 0 is local descriptor - //(psLOCAL->wConnectedSTAindex). - //If CONNECTED : NoOfJoinerInIbss >=2 - // else : NoOfJoinerInIbss <=1 - - //// General Statistics, count at Rx_handler or Tx_callback interrupt handler - u64 GS_XMIT_OK; // Good Frames Transmitted - u64 GS_RCV_OK; // Good Frames Received - u32 GS_RCV_ERROR; // Frames received with crc error - u32 GS_XMIT_ERROR; // Bad Frames Transmitted - u32 GS_RCV_NO_BUFFER; // Receive Buffer underrun - u32 GS_XMIT_ONE_COLLISION; // one collision - u32 GS_XMIT_MORE_COLLISIONS;// more collisions - - //================================================================ - // Statistics (no matter whether it had done successfully) -wkchen - //================================================================ - u32 _NumRxMSDU; - u32 _NumTxMSDU; - u32 _dot11WEPExcludedCount; - u32 _dot11WEPUndecryptableCount; - u32 _dot11FrameDuplicateCount; - - struct chan_info IbssChanSetting; // 2B. Start IBSS Channel setting by registry or WWU. - u8 reserved_5[2]; //It may not be used after considering RF type, - //region and modulation type. - - u8 reserved_6[2]; //two variables are for wep key error detection added by ws 02/02/04 - - u32 bWepKeyError; - u32 bToSelfPacketReceived; - u32 WepKeyDetectTimerCount; - - u16 SignalLostTh; - u16 SignalRoamTh; - - // 20061108 WPS IE Append +struct wb_local_para { + /* read from EPROM, manufacture set for each NetCard */ + u8 PermanentAddress[MAC_ADDR_LENGTH + 2]; + /* the driver will use this one actually. */ + u8 ThisMacAddress[MAC_ADDR_LENGTH + 2]; + u32 MTUsize; /* Ind to Uplayer, Max transmission unit size */ + u8 region_INF; /* region setting from INF */ + u8 region; /* real region setting of the device */ + u8 Reserved_1[2]; + + /* power-save variables */ + u8 iPowerSaveMode; /* 0 indicates on, 1 indicates off */ + u8 ATIMmode; + u8 ExcludeUnencrypted; + /* Unit ime count for the decision to enter PS mode */ + u16 CheckCountForPS; + u8 boHasTxActivity;/* tx activity has occurred */ + u8 boMacPsValid; /* Power save mode obtained from H/W is valid or not */ + + /* Rate */ + u8 TxRateMode; /* + * Initial, input from Registry, + * may be updated by GUI + * Tx Rate Mode: auto(DTO on), max, 1M, 2M, .. + */ + u8 CurrentTxRate; /* The current Tx rate */ + u8 CurrentTxRateForMng; /* + * The current Tx rate for management + * frames. It will be decided before + * connection succeeds. + */ + u8 CurrentTxFallbackRate; + + /* for Rate handler */ + u8 BRateSet[32]; /* basic rate set */ + u8 SRateSet[32]; /* support rate set */ + + u8 NumOfBRate; + u8 NumOfSRate; + u8 NumOfDsssRateInSRate; /* number of DSSS rates in supported rate set */ + u8 reserved1; + + u32 dwBasicRateBitmap; /* bit map of basic rates */ + + u32 dwSupportRateBitmap; /* bit map of all support rates including basic and operational rates */ + + + /* For SME/MLME handler */ + + u16 wOldSTAindex; /* valid when boHandover=TRUE, store old connected STA index */ + u16 wConnectedSTAindex; /* Index of peerly connected AP or IBSS in the descriptionset. */ + u16 Association_ID; /* The Association ID in the (Re)Association Response frame. */ + u16 ListenInterval; /* The listen interval when SME invoking MLME_ (Re)Associate_Request(). */ + + struct radio_off RadioOffStatus; + u8 Reserved0[2]; + u8 boMsRadioOff; /* Ndis demands to be true when set Disassoc. OID and be false when set SSID OID. */ + u8 bAntennaNo; /* which antenna */ + u8 bConnectFlag; /* the connect status flag for roaming task */ + + u8 RoamStatus; + u8 reserved7[3]; + + struct chan_info CurrentChan; /* Current channel no. and channel band. It may be changed by scanning. */ + u8 boHandover; /* Roaming, Hnadover to other AP. */ + u8 boCCAbusy; + + u16 CWMax; /* It may not be the real value that H/W used */ + u8 CWMin; /* 255: set according to 802.11 spec. */ + u8 reserved2; + + /* 11G: */ + u8 bMacOperationMode; /* operation in 802.11b or 802.11g */ + u8 bSlotTimeMode; /* AUTO, s32 */ + u8 bPreambleMode; /* AUTO, s32 */ + u8 boNonERPpresent; + + u8 boProtectMechanism; /* H/W will take the necessary action based on this variable */ + u8 boShortPreamble; /* Same here */ + u8 boShortSlotTime; /* Same here */ + u8 reserved_3; + + u32 RSN_IE_Bitmap; + u32 RSN_OUI_Type; + + /* For the BSSID */ + u8 HwBssid[MAC_ADDR_LENGTH + 2]; + u32 HwBssidValid; + + /* For scan list */ + u8 BssListCount; /* Total count of valid descriptor indexes */ + u8 boReceiveUncorrectInfo; /* important settings in beacon/probe resp. have been changed */ + u8 NoOfJoinerInIbss; + u8 reserved_4; + + /* Store the valid descriptor indexes obtained from scannings */ + u8 BssListIndex[(MAX_BSS_DESCRIPT_ELEMENT + 3) & ~0x03]; + /* + * Save the BssDescriptor index in this IBSS. + * The index 0 is local descriptor (psLOCAL->wConnectedSTAindex). + * If CONNECTED : NoOfJoinerInIbss >= 2 + * else : NoOfJoinerInIbss <= 1 + */ + u8 JoinerInIbss[(MAX_BSS_DESCRIPT_ELEMENT + 3) & ~0x03]; + + /* General Statistics, count at Rx_handler or Tx_callback interrupt handler */ + u64 GS_XMIT_OK; /* Good Frames Transmitted */ + u64 GS_RCV_OK; /* Good Frames Received */ + u32 GS_RCV_ERROR; /* Frames received with crc error */ + u32 GS_XMIT_ERROR; /* Bad Frames Transmitted */ + u32 GS_RCV_NO_BUFFER; /* Receive Buffer underrun */ + u32 GS_XMIT_ONE_COLLISION; /* one collision */ + u32 GS_XMIT_MORE_COLLISIONS;/* more collisions */ + + /* + * ================================================================ + * Statistics (no matter whether it had done successfully) -wkchen + * ================================================================ + */ + u32 _NumRxMSDU; + u32 _NumTxMSDU; + u32 _dot11WEPExcludedCount; + u32 _dot11WEPUndecryptableCount; + u32 _dot11FrameDuplicateCount; + + struct chan_info IbssChanSetting; /* 2B. Start IBSS Channel setting by registry or WWU. */ + u8 reserved_5[2]; /* It may not be used after considering RF type, region and modulation type. */ + + u8 reserved_6[2]; /* two variables are for wep key error detection */ + u32 bWepKeyError; + u32 bToSelfPacketReceived; + u32 WepKeyDetectTimerCount; + + u16 SignalLostTh; + u16 SignalRoamTh; + u8 IE_Append_data[MAX_IE_APPEND_SIZE]; u16 IE_Append_size; u16 reserved_7; - }; #endif -- cgit v1.2.3 From a09fcbd70e612b197af349ef32b090f211542fb3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 May 2010 17:25:36 -0500 Subject: staging: rtl8192x: sync the various rtl819x_TSProc.c files The rtl8192e, rtl8192su, and rtl8192u drivers all share what appears to be a common private ieee80211 stack. Various patches have been applied to the rtl819x_TSProc.c file for some of the drivers but not the others. This sync's the files based on all the applied patches. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8192e/ieee80211/rtl819x_TSProc.c | 38 ++-------------------- .../staging/rtl8192su/ieee80211/rtl819x_TSProc.c | 12 ++----- .../staging/rtl8192u/ieee80211/rtl819x_TSProc.c | 9 +++-- 3 files changed, 9 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c index e8699616fad4..5876b4d53eb1 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c @@ -3,13 +3,6 @@ #include #include "rtl819x_TS.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#define list_for_each_entry_safe(pos, n, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) -#endif void TsSetupTimeOut(unsigned long data) { // Not implement yet @@ -29,7 +22,6 @@ void TsInactTimeout(unsigned long data) * return: NULL * notice: ********************************************************************************************************************/ -#if 1 void RxPktPendingTimeout(unsigned long data) { PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)data; @@ -90,25 +82,16 @@ void RxPktPendingTimeout(unsigned long data) return; } ieee80211_indicate_packets(ieee, stats_IndicateArray, index); - bPktInBuf = false; } if(bPktInBuf && (pRxTs->RxTimeoutIndicateSeq==0xffff)) { pRxTs->RxTimeoutIndicateSeq = pRxTs->RxIndicateSeq; -#if 0 - if(timer_pending(&pRxTs->RxPktPendingTimer)) - del_timer_sync(&pRxTs->RxPktPendingTimer); - pRxTs->RxPktPendingTimer.expires = jiffies + ieee->pHTInfo->RxReorderPendingTime; - add_timer(&pRxTs->RxPktPendingTimer); -#else mod_timer(&pRxTs->RxPktPendingTimer, jiffies + MSECS(ieee->pHTInfo->RxReorderPendingTime)); -#endif } spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK); } -#endif /******************************************************************************************************************** *function: Add BA timer function @@ -372,17 +355,11 @@ bool GetTs( IEEE80211_DEBUG(IEEE80211_DL_ERR, "get TS for Broadcast or Multicast\n"); return false; } -#if 0 - if(ieee->pStaQos->CurrentQosMode == QOS_DISABLE) - { UP = 0; } //only use one TS - else if(ieee->pStaQos->CurrentQosMode & QOS_WMM) - { -#else + if (ieee->current_network.qos_data.supported == 0) UP = 0; else { -#endif // In WMM case: we use 4 TID only if (!IsACValid(TID)) { @@ -553,8 +530,8 @@ void RemoveTsEntry( void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr) { PTS_COMMON_INFO pTS, pTmpTS; + printk("===========>RemovePeerTS,%pM\n", Addr); -#if 1 list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) { if (memcmp(pTS->Addr, Addr, 6) == 0) @@ -595,13 +572,12 @@ void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr) list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); } } -#endif } void RemoveAllTS(struct ieee80211_device* ieee) { PTS_COMMON_INFO pTS, pTmpTS; -#if 1 + list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) { RemoveTsEntry(ieee, pTS, TX_DIR); @@ -629,7 +605,6 @@ void RemoveAllTS(struct ieee80211_device* ieee) list_del_init(&pTS->List); list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); } -#endif } void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD pTxTS) @@ -637,7 +612,6 @@ void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD pTxTS) if(pTxTS->bAddBaReqInProgress == false) { pTxTS->bAddBaReqInProgress = true; -#if 1 if(pTxTS->bAddBaReqDelayed) { IEEE80211_DEBUG(IEEE80211_DL_BA, "TsStartAddBaProcess(): Delayed Start ADDBA after 60 sec!!\n"); @@ -648,13 +622,7 @@ void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD pTxTS) IEEE80211_DEBUG(IEEE80211_DL_BA,"TsStartAddBaProcess(): Immediately Start ADDBA now!!\n"); mod_timer(&pTxTS->TsAddBaTimer, jiffies+10); //set 10 ticks } -#endif } else IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s()==>BA timer is already added\n", __FUNCTION__); } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -EXPORT_SYMBOL_NOVERS(RemovePeerTS); -#else -//EXPORT_SYMBOL(RemovePeerTS); -#endif diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c index 38468c539675..de143ecae5fa 100644 --- a/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c @@ -22,7 +22,6 @@ void TsInactTimeout(unsigned long data) * return: NULL * notice: ********************************************************************************************************************/ -#if 1 void RxPktPendingTimeout(unsigned long data) { PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)data; @@ -83,8 +82,6 @@ void RxPktPendingTimeout(unsigned long data) return; } ieee80211_indicate_packets(ieee, stats_IndicateArray, index); - bPktInBuf = false; - } if(bPktInBuf && (pRxTs->RxTimeoutIndicateSeq==0xffff)) @@ -95,7 +92,6 @@ void RxPktPendingTimeout(unsigned long data) spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK); } -#endif /******************************************************************************************************************** *function: Add BA timer function @@ -534,8 +530,8 @@ void RemoveTsEntry( void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr) { PTS_COMMON_INFO pTS, pTmpTS; + printk("===========>RemovePeerTS,%pM\n", Addr); -#if 1 list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) { if (memcmp(pTS->Addr, Addr, 6) == 0) @@ -576,13 +572,12 @@ void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr) list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); } } -#endif } void RemoveAllTS(struct ieee80211_device* ieee) { PTS_COMMON_INFO pTS, pTmpTS; -#if 1 + list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) { RemoveTsEntry(ieee, pTS, TX_DIR); @@ -610,7 +605,6 @@ void RemoveAllTS(struct ieee80211_device* ieee) list_del_init(&pTS->List); list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); } -#endif } void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD pTxTS) @@ -618,7 +612,6 @@ void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD pTxTS) if(pTxTS->bAddBaReqInProgress == false) { pTxTS->bAddBaReqInProgress = true; -#if 1 if(pTxTS->bAddBaReqDelayed) { IEEE80211_DEBUG(IEEE80211_DL_BA, "TsStartAddBaProcess(): Delayed Start ADDBA after 60 sec!!\n"); @@ -629,7 +622,6 @@ void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD pTxTS) IEEE80211_DEBUG(IEEE80211_DL_BA,"TsStartAddBaProcess(): Immediately Start ADDBA now!!\n"); mod_timer(&pTxTS->TsAddBaTimer, jiffies+10); //set 10 ticks } -#endif } else IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s()==>BA timer is already added\n", __FUNCTION__); diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c index 451120ff2130..c3fcaae0750d 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c @@ -87,10 +87,7 @@ void RxPktPendingTimeout(unsigned long data) if(bPktInBuf && (pRxTs->RxTimeoutIndicateSeq==0xffff)) { pRxTs->RxTimeoutIndicateSeq = pRxTs->RxIndicateSeq; - if(timer_pending(&pRxTs->RxPktPendingTimer)) - del_timer_sync(&pRxTs->RxPktPendingTimer); - pRxTs->RxPktPendingTimer.expires = jiffies + ieee->pHTInfo->RxReorderPendingTime; - add_timer(&pRxTs->RxPktPendingTimer); + mod_timer(&pRxTs->RxPktPendingTimer, jiffies + MSECS(ieee->pHTInfo->RxReorderPendingTime)); } spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK); @@ -358,6 +355,7 @@ bool GetTs( IEEE80211_DEBUG(IEEE80211_DL_ERR, "get TS for Broadcast or Multicast\n"); return false; } + if (ieee->current_network.qos_data.supported == 0) UP = 0; else @@ -532,6 +530,7 @@ void RemoveTsEntry( void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr) { PTS_COMMON_INFO pTS, pTmpTS; + printk("===========>RemovePeerTS,%pM\n", Addr); list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) { @@ -578,6 +577,7 @@ void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr) void RemoveAllTS(struct ieee80211_device* ieee) { PTS_COMMON_INFO pTS, pTmpTS; + list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) { RemoveTsEntry(ieee, pTS, TX_DIR); @@ -626,4 +626,3 @@ void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD pTxTS) else IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s()==>BA timer is already added\n", __FUNCTION__); } -EXPORT_SYMBOL(RemovePeerTS); -- cgit v1.2.3 From b63eaed0da3370817f74002b81a57b25c43e72cb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 7 May 2010 17:27:22 -0500 Subject: staging: rtl8192x: sync the various rtl819x_Qos.h files The rtl8192e, rtl8192su, and rtl8192u drivers all share what appears to be a common private ieee80211 stack. Various patches have been applied to the rtl819x_Qos.h file for some of the drivers but not the others. This sync's the files based on all the applied patches. Signed-off-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/ieee80211/rtl819x_Qos.h | 168 +--------------------- drivers/staging/rtl8192su/ieee80211/rtl819x_Qos.h | 1 - drivers/staging/rtl8192u/ieee80211/rtl819x_Qos.h | 3 +- 3 files changed, 2 insertions(+), 170 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_Qos.h b/drivers/staging/rtl8192e/ieee80211/rtl819x_Qos.h index a50ee0e1c059..d4565ecc7ab4 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_Qos.h +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_Qos.h @@ -69,147 +69,6 @@ typedef enum _ACK_POLICY{ }ACK_POLICY,*PACK_POLICY; #define WMM_PARAM_ELEMENT_SIZE (8+(4*AC_PARAM_SIZE)) -#if 0 -#define GET_QOS_CTRL(_pStart) ReadEF2Byte((u8 *)(_pStart) + 24) -#define SET_QOS_CTRL(_pStart, _value) WriteEF2Byte((u8 *)(_pStart) + 24, _value) - -// WMM control field. -#define GET_QOS_CTRL_WMM_UP(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 0, 3)) -#define SET_QOS_CTRL_WMM_UP(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 0, 3, (u8)(_value)) - -#define GET_QOS_CTRL_WMM_EOSP(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 4, 1)) -#define SET_QOS_CTRL_WMM_EOSP(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 4, 1, (u8)(_value)) - -#define GET_QOS_CTRL_WMM_ACK_POLICY(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 5, 2)) -#define SET_QOS_CTRL_WMM_ACK_POLICY(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 5, 2, (u8)(_value)) - -// 802.11e control field (by STA, data) -#define GET_QOS_CTRL_STA_DATA_TID(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 0, 4)) -#define SET_QOS_CTRL_STA_DATA_TID(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 0, 4, (u8)(_value)) - -#define GET_QOS_CTRL_STA_DATA_QSIZE_FLAG(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 4, 1)) -#define SET_QOS_CTRL_STA_DATA_QSIZE_FLAG(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 4, 1, (u8)(_value)) - -#define GET_QOS_CTRL_STA_DATA_ACK_POLICY(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 5, 2)) -#define SET_QOS_CTRL_STA_DATA_ACK_POLICY(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 5, 2, (u8)(_value)) - -#define GET_QOS_CTRL_STA_DATA_TXOP(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 8, 8)) -#define SET_QOS_CTRL_STA_DATA_TXOP(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 8, 8, (u8)(_value)) - -#define GET_QOS_CTRL_STA_DATA_QSIZE(_pStart) GET_QOS_CTRL_STA_DATA_TXOP(_pStart) -#define SET_QOS_CTRL_STA_DATA_QSIZE(_pStart, _value) SET_QOS_CTRL_STA_DATA_TXOP(_pStart) - -// 802.11e control field (by HC, data) -#define GET_QOS_CTRL_HC_DATA_TID(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 0, 4)) -#define SET_QOS_CTRL_HC_DATA_TID(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 0, 4, (u8)(_value)) - -#define GET_QOS_CTRL_HC_DATA_EOSP(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 4, 1)) -#define SET_QOS_CTRL_HC_DATA_EOSP(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 4, 1, (u8)(_value)) - -#define GET_QOS_CTRL_HC_DATA_ACK_POLICY(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 5, 2)) -#define SET_QOS_CTRL_HC_DATA_ACK_POLICY(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 5, 2, (u8)(_value)) - -#define GET_QOS_CTRL_HC_DATA_PS_BUFSTATE(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 8, 8)) -#define SET_QOS_CTRL_HC_DATA_PS_BUFSTATE(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 8, 8, (u8)(_value)) - -// 802.11e control field (by HC, CFP) -#define GET_QOS_CTRL_HC_CFP_TID(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 0, 4)) -#define SET_QOS_CTRL_HC_CFP_TID(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 0, 4, (u8)(_value)) - -#define GET_QOS_CTRL_HC_CFP_EOSP(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 4, 1)) -#define SET_QOS_CTRL_HC_CFP_EOSP(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 4, 1, (u8)(_value)) - -#define GET_QOS_CTRL_HC_CFP_ACK_POLICY(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 5, 2)) -#define SET_QOS_CTRL_HC_CFP_ACK_POLICY(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 5, 2, (u8)(_value)) - -#define GET_QOS_CTRL_HC_CFP_TXOP_LIMIT(_pStart) ((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 8, 8)) -#define SET_QOS_CTRL_HC_CFP_TXOP_LIMIT(_pStart, _value) SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 8, 8, (u8)(_value)) - -#define SET_WMM_QOS_INFO_FIELD(_pStart, _val) WriteEF1Byte(_pStart, _val) - -#define GET_WMM_QOS_INFO_FIELD_PARAMETERSET_COUNT(_pStart) LE_BITS_TO_1BYTE(_pStart, 0, 4) -#define SET_WMM_QOS_INFO_FIELD_PARAMETERSET_COUNT(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 0, 4, _val) - -#define GET_WMM_QOS_INFO_FIELD_AP_UAPSD(_pStart) LE_BITS_TO_1BYTE(_pStart, 7, 1) -#define SET_WMM_QOS_INFO_FIELD_AP_UAPSD(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 7, 1, _val) - -#define GET_WMM_QOS_INFO_FIELD_STA_AC_VO_UAPSD(_pStart) LE_BITS_TO_1BYTE(_pStart, 0, 1) -#define SET_WMM_QOS_INFO_FIELD_STA_AC_VO_UAPSD(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 0, 1, _val) - -#define GET_WMM_QOS_INFO_FIELD_STA_AC_VI_UAPSD(_pStart) LE_BITS_TO_1BYTE(_pStart, 1, 1) -#define SET_WMM_QOS_INFO_FIELD_STA_AC_VI_UAPSD(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 1, 1, _val) - -#define GET_WMM_QOS_INFO_FIELD_STA_AC_BE_UAPSD(_pStart) LE_BITS_TO_1BYTE(_pStart, 2, 1) -#define SET_WMM_QOS_INFO_FIELD_STA_AC_BE_UAPSD(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 2, 1, _val) - -#define GET_WMM_QOS_INFO_FIELD_STA_AC_BK_UAPSD(_pStart) LE_BITS_TO_1BYTE(_pStart, 3, 1) -#define SET_WMM_QOS_INFO_FIELD_STA_AC_BK_UAPSD(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 3, 1, _val) - -#define GET_WMM_QOS_INFO_FIELD_STA_MAX_SP_LEN(_pStart) LE_BITS_TO_1BYTE(_pStart, 5, 2) -#define SET_WMM_QOS_INFO_FIELD_STA_MAX_SP_LEN(_pStart, _val) SET_BITS_TO_LE_1BYTE(_pStart, 5, 2, _val) - - -#define WMM_INFO_ELEMENT_SIZE 7 - -#define GET_WMM_INFO_ELE_OUI(_pStart) ((u8 *)(_pStart)) -#define SET_WMM_INFO_ELE_OUI(_pStart, _pVal) PlatformMoveMemory(_pStart, _pVal, 3); - -#define GET_WMM_INFO_ELE_OUI_TYPE(_pStart) ( EF1Byte( *((u8 *)(_pStart)+3) ) ) -#define SET_WMM_INFO_ELE_OUI_TYPE(_pStart, _val) ( *((u8 *)(_pStart)+3) = EF1Byte(_val) ) - -#define GET_WMM_INFO_ELE_OUI_SUBTYPE(_pStart) ( EF1Byte( *((u8 *)(_pStart)+4) ) ) -#define SET_WMM_INFO_ELE_OUI_SUBTYPE(_pStart, _val) ( *((u8 *)(_pStart)+4) = EF1Byte(_val) ) - -#define GET_WMM_INFO_ELE_VERSION(_pStart) ( EF1Byte( *((u8 *)(_pStart)+5) ) ) -#define SET_WMM_INFO_ELE_VERSION(_pStart, _val) ( *((u8 *)(_pStart)+5) = EF1Byte(_val) ) - -#define GET_WMM_INFO_ELE_QOS_INFO_FIELD(_pStart) ( EF1Byte( *((u8 *)(_pStart)+6) ) ) -#define SET_WMM_INFO_ELE_QOS_INFO_FIELD(_pStart, _val) ( *((u8 *)(_pStart)+6) = EF1Byte(_val) ) - - - -#define GET_WMM_AC_PARAM_AIFSN(_pStart) ( (u8)LE_BITS_TO_4BYTE(_pStart, 0, 4) ) -#define SET_WMM_AC_PARAM_AIFSN(_pStart, _val) SET_BITS_TO_LE_4BYTE(_pStart, 0, 4, _val) - -#define GET_WMM_AC_PARAM_ACM(_pStart) ( (u8)LE_BITS_TO_4BYTE(_pStart, 4, 1) ) -#define SET_WMM_AC_PARAM_ACM(_pStart, _val) SET_BITS_TO_LE_4BYTE(_pStart, 4, 1, _val) - -#define GET_WMM_AC_PARAM_ACI(_pStart) ( (u8)LE_BITS_TO_4BYTE(_pStart, 5, 2) ) -#define SET_WMM_AC_PARAM_ACI(_pStart, _val) SET_BITS_TO_LE_4BYTE(_pStart, 5, 2, _val) - -#define GET_WMM_AC_PARAM_ACI_AIFSN(_pStart) ( (u8)LE_BITS_TO_4BYTE(_pStart, 0, 8) ) -#define SET_WMM_AC_PARAM_ACI_AIFSN(_pStart, _val) SET_BTIS_TO_LE_4BYTE(_pStart, 0, 8, _val) - -#define GET_WMM_AC_PARAM_ECWMIN(_pStart) ( (u8)LE_BITS_TO_4BYTE(_pStart, 8, 4) ) -#define SET_WMM_AC_PARAM_ECWMIN(_pStart, _val) SET_BITS_TO_LE_4BYTE(_pStart, 8, 4, _val) - -#define GET_WMM_AC_PARAM_ECWMAX(_pStart) ( (u8)LE_BITS_TO_4BYTE(_pStart, 12, 4) ) -#define SET_WMM_AC_PARAM_ECWMAX(_pStart, _val) SET_BITS_TO_LE_4BYTE(_pStart, 12, 4, _val) - -#define GET_WMM_AC_PARAM_TXOP_LIMIT(_pStart) ( (u16)LE_BITS_TO_4BYTE(_pStart, 16, 16) ) -#define SET_WMM_AC_PARAM_TXOP_LIMIT(_pStart, _val) SET_BITS_TO_LE_4BYTE(_pStart, 16, 16, _val) - - - - -#define GET_WMM_PARAM_ELE_OUI(_pStart) ((u8 *)(_pStart)) -#define SET_WMM_PARAM_ELE_OUI(_pStart, _pVal) PlatformMoveMemory(_pStart, _pVal, 3) - -#define GET_WMM_PARAM_ELE_OUI_TYPE(_pStart) ( EF1Byte( *((u8 *)(_pStart)+3) ) ) -#define SET_WMM_PARAM_ELE_OUI_TYPE(_pStart, _val) ( *((u8 *)(_pStart)+3) = EF1Byte(_val) ) - -#define GET_WMM_PARAM_ELE_OUI_SUBTYPE(_pStart) ( EF1Byte( *((u8 *)(_pStart)+4) ) ) -#define SET_WMM_PARAM_ELE_OUI_SUBTYPE(_pStart, _val) ( *((u8 *)(_pStart)+4) = EF1Byte(_val) ) - -#define GET_WMM_PARAM_ELE_VERSION(_pStart) ( EF1Byte( *((u8 *)(_pStart)+5) ) ) -#define SET_WMM_PARAM_ELE_VERSION(_pStart, _val) ( *((u8 *)(_pStart)+5) = EF1Byte(_val) ) - -#define GET_WMM_PARAM_ELE_QOS_INFO_FIELD(_pStart) ( EF1Byte( *((u8 *)(_pStart)+6) ) ) -#define SET_WMM_PARAM_ELE_QOS_INFO_FIELD(_pStart, _val) ( *((u8 *)(_pStart)+6) = EF1Byte(_val) ) - -#define GET_WMM_PARAM_ELE_AC_PARAM(_pStart) ( (u8 *)(_pStart)+8 ) -#define SET_WMM_PARAM_ELE_AC_PARAM(_pStart, _pVal) PlatformMoveMemory((_pStart)+8, _pVal, 16) -#endif // // QoS Control Field @@ -360,22 +219,6 @@ typedef union _QOS_INFO_FIELD{ }QOS_INFO_FIELD, *PQOS_INFO_FIELD; -#if 0 -// -// WMM Information Element -// Ref: WMM spec 2.2.1: WME Information Element, p.10. -// -typedef struct _WMM_INFO_ELEMENT{ -// u8 ElementID; -// u8 Length; - u8 OUI[3]; - u8 OUI_Type; - u8 OUI_SubType; - u8 Version; - QOS_INFO_FIELD QosInfo; -}WMM_INFO_ELEMENT, *PWMM_INFO_ELEMENT; -#endif - // // ACI to AC coding. // Ref: WMM spec 2.2.2: WME Parameter Element, p.13. @@ -649,16 +492,7 @@ typedef struct _OCTET_STRING{ u8 *Octet; u16 Length; }OCTET_STRING, *POCTET_STRING; -#if 0 -#define FillOctetString(_os,_octet,_len) \ - (_os).Octet=(u8 *)(_octet); \ - (_os).Length=(_len); - -#define WMM_ELEM_HDR_LEN 6 -#define WMMElemSkipHdr(_osWMMElem) \ - (_osWMMElem).Octet += WMM_ELEM_HDR_LEN; \ - (_osWMMElem).Length -= WMM_ELEM_HDR_LEN; -#endif + // // STA QoS data. // Ref: DOT11_QOS in 8185 code. [def. in QoS_mp.h] diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_Qos.h b/drivers/staging/rtl8192su/ieee80211/rtl819x_Qos.h index 7aa9a7790b63..d4565ecc7ab4 100644 --- a/drivers/staging/rtl8192su/ieee80211/rtl819x_Qos.h +++ b/drivers/staging/rtl8192su/ieee80211/rtl819x_Qos.h @@ -1,7 +1,6 @@ #ifndef __INC_QOS_TYPE_H #define __INC_QOS_TYPE_H -//#include "EndianFree.h" #define BIT0 0x00000001 #define BIT1 0x00000002 #define BIT2 0x00000004 diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_Qos.h b/drivers/staging/rtl8192u/ieee80211/rtl819x_Qos.h index 13b1e5ca436d..9e4ced15edf5 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_Qos.h +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_Qos.h @@ -1,7 +1,6 @@ #ifndef __INC_QOS_TYPE_H #define __INC_QOS_TYPE_H -//#include "EndianFree.h" #define BIT0 0x00000001 #define BIT1 0x00000002 #define BIT2 0x00000004 @@ -220,7 +219,6 @@ typedef union _QOS_INFO_FIELD{ }QOS_INFO_FIELD, *PQOS_INFO_FIELD; - // // ACI to AC coding. // Ref: WMM spec 2.2.2: WME Parameter Element, p.13. @@ -494,6 +492,7 @@ typedef struct _OCTET_STRING{ u8 *Octet; u16 Length; }OCTET_STRING, *POCTET_STRING; + // // STA QoS data. // Ref: DOT11_QOS in 8185 code. [def. in QoS_mp.h] -- cgit v1.2.3 From 48f658bb3d582c13b5d0b86b0295d5e0050e60c9 Mon Sep 17 00:00:00 2001 From: Takanori Suzuki Date: Sat, 8 May 2010 22:56:24 +0900 Subject: Staging: panel: change asm/uaccess.h to linux/uaccess.h This patch replaces with to comply with the checkpatch.pl hint. Signed-off-by: Takanori Suzuki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/panel/panel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index 377884f3480d..f9fcb2fef5a0 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c @@ -57,7 +57,7 @@ #include #include -#include +#include #include #define LCD_MINOR 156 -- cgit v1.2.3 From b8aab1278147e3b067903983a835ef3c68281b13 Mon Sep 17 00:00:00 2001 From: Marin Mitov Date: Sun, 9 May 2010 14:50:40 +0300 Subject: Staging: dt3155v4l: correcting a bug dt3155v4l driver, as in -rc6-next-20100506 has a BUG. When it modifies q->int_ops structure in videobuf-dma-contig module the change is visible for all other modules using it. Make a local copy of this structure and use its modification to solve the bug. Signed-off-by: Marin Mitov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dt3155v4l/dt3155v4l.c | 7 ++++++- drivers/staging/dt3155v4l/dt3155v4l.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/dt3155v4l/dt3155v4l.c b/drivers/staging/dt3155v4l/dt3155v4l.c index b1695ad9b56e..a5e409170418 100644 --- a/drivers/staging/dt3155v4l/dt3155v4l.c +++ b/drivers/staging/dt3155v4l/dt3155v4l.c @@ -612,9 +612,14 @@ dt3155_queue_dma_contig_init(struct videobuf_queue *q, unsigned int msize, void *priv) { + struct dt3155_priv *pd = q->priv_data; + videobuf_queue_dma_contig_init(q, ops, dev, irqlock, type, field, msize, priv); - /* overwrite with our methods */ + /* replace with local copy */ + pd->qt_ops = *q->int_ops; + q->int_ops = &pd->qt_ops; + /* and overwrite with our methods */ q->int_ops->iolock = dt3155_iolock; q->int_ops->mmap_mapper = dt3155_mmap_mapper; q->int_ops->sync = dt3155_sync_for_cpu; diff --git a/drivers/staging/dt3155v4l/dt3155v4l.h b/drivers/staging/dt3155v4l/dt3155v4l.h index e5c4ad05b180..4c6a0ee08c0e 100644 --- a/drivers/staging/dt3155v4l/dt3155v4l.h +++ b/drivers/staging/dt3155v4l/dt3155v4l.h @@ -185,6 +185,7 @@ struct dt3155_stats { * @curr_buf: pointer to curren buffer * @thread pointer to worker thraed * @irq_handler: irq handler for the driver + * @qt_ops local copy of dma-contig qtype_ops * @dmaq queue for dma buffers * @do_dma wait queue of the kernel thread * @mux: mutex to protect the instance @@ -204,6 +205,7 @@ struct dt3155_priv { struct videobuf_buffer *curr_buf; struct task_struct *thread; irq_handler_t irq_handler; + struct videobuf_qtype_ops qt_ops; struct list_head dmaq; wait_queue_head_t do_dma; struct mutex mux; -- cgit v1.2.3 From ad602259451ddc8b0f83cb312cb54223317eda74 Mon Sep 17 00:00:00 2001 From: Marin Mitov Date: Tue, 11 May 2010 11:05:25 +0300 Subject: staging: dt3155v4l: last fix to correct a bug introduces a bug. Correct it. The previous patch "use_local_copy_qtype_ops.patch" http://lkml.org/lkml/2010/5/9/40 has introduced a new BUG. This patch corrects it. Signed-off-by: Marin Mitov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dt3155v4l/dt3155v4l.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/dt3155v4l/dt3155v4l.c b/drivers/staging/dt3155v4l/dt3155v4l.c index a5e409170418..49463611f4f3 100644 --- a/drivers/staging/dt3155v4l/dt3155v4l.c +++ b/drivers/staging/dt3155v4l/dt3155v4l.c @@ -612,7 +612,7 @@ dt3155_queue_dma_contig_init(struct videobuf_queue *q, unsigned int msize, void *priv) { - struct dt3155_priv *pd = q->priv_data; + struct dt3155_priv *pd = priv; videobuf_queue_dma_contig_init(q, ops, dev, irqlock, type, field, msize, priv); -- cgit v1.2.3 From e2218350465e7e0931676b4849b594c978437bce Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 12 May 2010 08:25:37 +1000 Subject: md: set mddev readonly flag on blkdev BLKROSET ioctl When the user sets the block device to readwrite then the mddev should follow suit. Otherwise, the BUG_ON in md_write_start() will be set to trigger. The reverse direction, setting mddev->ro to match a set readonly request, can be ignored because the blkdev level readonly flag precludes the need to have mddev->ro set correctly. Nevermind the fact that setting mddev->ro to 1 may fail if the array is in use. Cc: Signed-off-by: Dan Williams Signed-off-by: NeilBrown --- drivers/md/md.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index a20a71e5efd3..08f665178c3b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5489,6 +5489,7 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, int err = 0; void __user *argp = (void __user *)arg; mddev_t *mddev = NULL; + int ro; if (!capable(CAP_SYS_ADMIN)) return -EACCES; @@ -5624,6 +5625,34 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, err = do_md_stop(mddev, 1, 1); goto done_unlock; + case BLKROSET: + if (get_user(ro, (int __user *)(arg))) { + err = -EFAULT; + goto done_unlock; + } + err = -EINVAL; + + /* if the bdev is going readonly the value of mddev->ro + * does not matter, no writes are coming + */ + if (ro) + goto done_unlock; + + /* are we are already prepared for writes? */ + if (mddev->ro != 1) + goto done_unlock; + + /* transitioning to readauto need only happen for + * arrays that call md_write_start + */ + if (mddev->pers) { + err = restart_array(mddev); + if (err == 0) { + mddev->ro = 2; + set_disk_ro(mddev->gendisk, 0); + } + } + goto done_unlock; } /* -- cgit v1.2.3 From d101b958cb334c757edd4998fa0f2454755d7c3e Mon Sep 17 00:00:00 2001 From: "Prashant P. Shah" Date: Sun, 9 May 2010 22:41:16 +0530 Subject: Staging: wlags49_h2: fixed whitespace issues in wl_profile.c This is a patch to the wl_profile.c file that fixes whitespace issues found by the checkpatch.pl tool. Signed-off-by: Prashant P. Shah Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/wl_profile.c | 759 +++++++++++++++----------------- 1 file changed, 354 insertions(+), 405 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlags49_h2/wl_profile.c b/drivers/staging/wlags49_h2/wl_profile.c index 1e0c75f28557..e4e78a4ace15 100644 --- a/drivers/staging/wlags49_h2/wl_profile.c +++ b/drivers/staging/wlags49_h2/wl_profile.c @@ -113,17 +113,19 @@ extern p_u32 DebugFlag; extern dbg_info_t *DbgInfo; #endif -int parse_yes_no( char* value ); +int parse_yes_no(char *value); -int parse_yes_no( char* value ) { +int parse_yes_no(char *value) +{ int rc = 0; //default to NO for invalid parameters - if ( strlen( value ) == 1 ) { - if ( ( value[0] | ('Y'^'y') ) == 'y' ) rc = 1; + if (strlen(value) == 1) { + if ((value[0] | ('Y'^'y')) == 'y') + rc = 1; // } else { // this should not be debug time info, it is an enduser data entry error ;? -// DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MICROWAVE_ROBUSTNESS ); +// DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MICROWAVE_ROBUSTNESS); } return rc; } // parse_yes_no @@ -149,11 +151,11 @@ int rc = 0; //default to NO for invalid parameters * N/A * ******************************************************************************/ -void parse_config( struct net_device *dev ) +void parse_config(struct net_device *dev) { int file_desc; #if 0 // BIN_DL - int rc; + int rc; char *cp = NULL; #endif // BIN_DL char buffer[MAX_LINE_SIZE]; @@ -163,48 +165,48 @@ void parse_config( struct net_device *dev ) ENCSTRCT sEncryption; /*------------------------------------------------------------------------*/ - DBG_FUNC( "parse_config" ); - DBG_ENTER( DbgInfo ); + DBG_FUNC("parse_config"); + DBG_ENTER(DbgInfo); /* Get the wavelan specific info for this device */ wvlan_config = (struct wl_private *)dev->priv; - if ( wvlan_config == NULL ) { - DBG_ERROR( DbgInfo, "Wavelan specific info struct not present?\n" ); + if (wvlan_config == NULL) { + DBG_ERROR(DbgInfo, "Wavelan specific info struct not present?\n"); return; } /* setup the default encryption string */ - strcpy( wvlan_config->szEncryption, DEF_CRYPT_STR ); + strcpy(wvlan_config->szEncryption, DEF_CRYPT_STR); /* Obtain a user-space process context, storing the original context */ - fs = get_fs( ); - set_fs( get_ds( )); + fs = get_fs(); + set_fs(get_ds()); /* Determine the filename for this device and attempt to open it */ - sprintf( filename, "%s%s", ROOT_CONFIG_FILENAME, dev->name ); - file_desc = open( filename, O_RDONLY, 0 ); - if ( file_desc != -1 ) { - DBG_TRACE( DbgInfo, "Wireless config file found. Parsing options...\n" ); + sprintf(filename, "%s%s", ROOT_CONFIG_FILENAME, dev->name); + file_desc = open(filename, O_RDONLY, 0); + if (file_desc != -1) { + DBG_TRACE(DbgInfo, "Wireless config file found. Parsing options...\n"); /* Read out the options */ - while( readline( file_desc, buffer )) { - translate_option( buffer, wvlan_config ); + while (readline(file_desc, buffer)) { + translate_option(buffer, wvlan_config); } /* Close the file */ - close( file_desc ); //;?even if file_desc == -1 ??? + close(file_desc); //;?even if file_desc == -1 ??? } else { - DBG_TRACE( DbgInfo, "No iwconfig file found for this device; " - "config.opts or wireless.opts will be used\n" ); + DBG_TRACE(DbgInfo, "No iwconfig file found for this device; " + "config.opts or wireless.opts will be used\n"); } /* Return to the original context */ - set_fs( fs ); + set_fs(fs); /* convert the WEP keys, if read in as key1, key2, type of data */ - if ( wvlan_config->EnableEncryption ) { - memset( &sEncryption, 0, sizeof( sEncryption )); + if (wvlan_config->EnableEncryption) { + memset(&sEncryption, 0, sizeof(sEncryption)); - wl_wep_decode( CRYPT_CODE, &sEncryption, - wvlan_config->szEncryption ); + wl_wep_decode(CRYPT_CODE, &sEncryption, + wvlan_config->szEncryption); /* the Linux driver likes to use 1-4 for the key IDs, and then convert to 0-3 when sending to the card. The Windows code @@ -216,63 +218,63 @@ void parse_config( struct net_device *dev ) sEncryption.wEnabled = wvlan_config->EnableEncryption; sEncryption.wTxKeyID = wvlan_config->TransmitKeyID - 1; - memcpy( &sEncryption.EncStr, &wvlan_config->DefaultKeys, - sizeof( CFG_DEFAULT_KEYS_STRCT )); + memcpy(&sEncryption.EncStr, &wvlan_config->DefaultKeys, + sizeof(CFG_DEFAULT_KEYS_STRCT)); - memset( wvlan_config->szEncryption, 0, sizeof( wvlan_config->szEncryption )); + memset(wvlan_config->szEncryption, 0, sizeof(wvlan_config->szEncryption)); - wl_wep_code( CRYPT_CODE, wvlan_config->szEncryption, &sEncryption, - sizeof( sEncryption )); + wl_wep_code(CRYPT_CODE, wvlan_config->szEncryption, &sEncryption, + sizeof(sEncryption)); } /* decode the encryption string for the call to wl_commit() */ - wl_wep_decode( CRYPT_CODE, &sEncryption, wvlan_config->szEncryption ); + wl_wep_decode(CRYPT_CODE, &sEncryption, wvlan_config->szEncryption); wvlan_config->TransmitKeyID = sEncryption.wTxKeyID + 1; wvlan_config->EnableEncryption = sEncryption.wEnabled; - memcpy( &wvlan_config->DefaultKeys, &sEncryption.EncStr, - sizeof( CFG_DEFAULT_KEYS_STRCT )); + memcpy(&wvlan_config->DefaultKeys, &sEncryption.EncStr, + sizeof(CFG_DEFAULT_KEYS_STRCT)); #if 0 //BIN_DL /* Obtain a user-space process context, storing the original context */ - fs = get_fs( ); - set_fs( get_ds( )); + fs = get_fs(); + set_fs(get_ds()); //;?just to fake something - strcpy(/*wvlan_config->fw_image_*/filename, "/etc/agere/fw.bin" ); - file_desc = open( /*wvlan_config->fw_image_*/filename, 0, 0 ); - if ( file_desc == -1 ) { - DBG_ERROR( DbgInfo, "No image file found\n" ); + strcpy(/*wvlan_config->fw_image_*/filename, "/etc/agere/fw.bin"); + file_desc = open(/*wvlan_config->fw_image_*/filename, 0, 0); + if (file_desc == -1) { + DBG_ERROR(DbgInfo, "No image file found\n"); } else { - DBG_TRACE( DbgInfo, "F/W image file found\n" ); + DBG_TRACE(DbgInfo, "F/W image file found\n"); #define DHF_ALLOC_SIZE 96000 //just below 96K, let's hope it suffices for now and for the future - cp = (char*)vmalloc( DHF_ALLOC_SIZE ); - if ( cp == NULL ) { - DBG_ERROR( DbgInfo, "error in vmalloc\n" ); + cp = (char *)vmalloc(DHF_ALLOC_SIZE); + if (cp == NULL) { + DBG_ERROR(DbgInfo, "error in vmalloc\n"); } else { - rc = read( file_desc, cp, DHF_ALLOC_SIZE ); - if ( rc == DHF_ALLOC_SIZE ) { - DBG_ERROR( DbgInfo, "buffer too small, %d\n", DHF_ALLOC_SIZE ); - } else if ( rc > 0 ) { - DBG_TRACE( DbgInfo, "read O.K.: %d bytes %.12s\n", rc, cp ); - rc = read( file_desc, &cp[rc], 1 ); - if ( rc == 0 ) { - DBG_TRACE( DbgInfo, "no more to read\n" ); + rc = read(file_desc, cp, DHF_ALLOC_SIZE); + if (rc == DHF_ALLOC_SIZE) { + DBG_ERROR(DbgInfo, "buffer too small, %d\n", DHF_ALLOC_SIZE); + } else if (rc > 0) { + DBG_TRACE(DbgInfo, "read O.K.: %d bytes %.12s\n", rc, cp); + rc = read(file_desc, &cp[rc], 1); + if (rc == 0) { + DBG_TRACE(DbgInfo, "no more to read\n"); } } - if ( rc != 0 ) { - DBG_ERROR( DbgInfo, "file not read in one swoop or other error"\ - ", give up, too complicated, rc = %0X\n", rc ); + if (rc != 0) { + DBG_ERROR(DbgInfo, "file not read in one swoop or other error"\ + ", give up, too complicated, rc = %0X\n", rc); } - vfree( cp ); + vfree(cp); } - close( file_desc ); + close(file_desc); } - set_fs( fs ); /* Return to the original context */ + set_fs(fs); /* Return to the original context */ #endif // BIN_DL - DBG_LEAVE( DbgInfo ); + DBG_LEAVE(DbgInfo); return; } // parse_config @@ -298,17 +300,17 @@ void parse_config( struct net_device *dev ) * -1 on error * ******************************************************************************/ -int readline( int filedesc, char *buffer ) +int readline(int filedesc, char *buffer) { int result = -1; int bytes_read = 0; /*------------------------------------------------------------------------*/ /* Make sure the file descriptor is good */ - if ( filedesc != -1 ) { + if (filedesc != -1) { /* Read in from the file byte by byte until a newline is reached */ - while(( result = read( filedesc, &buffer[bytes_read], 1 )) == 1 ) { - if ( buffer[bytes_read] == '\n' ) { + while ((result = read(filedesc, &buffer[bytes_read], 1)) == 1) { + if (buffer[bytes_read] == '\n') { buffer[bytes_read] = '\0'; bytes_read++; break; @@ -318,7 +320,7 @@ int readline( int filedesc, char *buffer ) } /* Return the number of bytes read */ - if ( result == -1 ) { + if (result == -1) { return result; } else { return bytes_read; @@ -346,7 +348,7 @@ int readline( int filedesc, char *buffer ) * N/A * ******************************************************************************/ -void translate_option( char *buffer, struct wl_private *lp ) +void translate_option(char *buffer, struct wl_private *lp) { unsigned int value_convert = 0; int string_length = 0; @@ -355,16 +357,16 @@ void translate_option( char *buffer, struct wl_private *lp ) u_char mac_value[ETH_ALEN]; /*------------------------------------------------------------------------*/ - DBG_FUNC( "translate_option" ); + DBG_FUNC("translate_option"); - if ( buffer == NULL || lp == NULL ) { - DBG_ERROR( DbgInfo, "Config file buffer and/or wavelan buffer ptr NULL\n" ); + if (buffer == NULL || lp == NULL) { + DBG_ERROR(DbgInfo, "Config file buffer and/or wavelan buffer ptr NULL\n"); return; } - ParseConfigLine( buffer, &key, &value ); + ParseConfigLine(buffer, &key, &value); - if ( key == NULL || value == NULL ) { + if (key == NULL || value == NULL) { return; } @@ -375,9 +377,9 @@ void translate_option( char *buffer, struct wl_private *lp ) /* handle DebugFlag as early as possible so it starts its influence as early * as possible */ - if ( strcmp( key, PARM_NAME_DEBUG_FLAG ) == 0 ) { - if ( DebugFlag == ~0 ) { //if DebugFlag is not specified on the command line - if ( DbgInfo->DebugFlag == 0 ) { /* if pc_debug did not set DebugFlag (i.e.pc_debug is + if (strcmp(key, PARM_NAME_DEBUG_FLAG) == 0) { + if (DebugFlag == ~0) { /* if DebugFlag is not specified on the command line */ + if (DbgInfo->DebugFlag == 0) { /* if pc_debug did not set DebugFlag (i.e.pc_debug is * not specified or specified outside the 4-8 range */ DbgInfo->DebugFlag |= DBG_DEFAULTS; @@ -388,250 +390,230 @@ void translate_option( char *buffer, struct wl_private *lp ) DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); //;?Delete ASAP } #endif /* DBG */ - if ( strcmp( key, PARM_NAME_AUTH_KEY_MGMT_SUITE ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_AUTH_KEY_MGMT_SUITE, value ); + if (strcmp(key, PARM_NAME_AUTH_KEY_MGMT_SUITE) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_AUTH_KEY_MGMT_SUITE, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_AUTH_KEY_MGMT_SUITE ) || ( value_convert <= PARM_MAX_AUTH_KEY_MGMT_SUITE )) { + if ((value_convert >= PARM_MIN_AUTH_KEY_MGMT_SUITE) || (value_convert <= PARM_MAX_AUTH_KEY_MGMT_SUITE)) { lp->AuthKeyMgmtSuite = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_AUTH_KEY_MGMT_SUITE ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_AUTH_KEY_MGMT_SUITE); } - } - else if ( strcmp( key, PARM_NAME_BRSC_2GHZ ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_2GHZ, value ); + } else if (strcmp(key, PARM_NAME_BRSC_2GHZ) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_2GHZ, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_BRSC ) || ( value_convert <= PARM_MAX_BRSC )) { + if ((value_convert >= PARM_MIN_BRSC) || (value_convert <= PARM_MAX_BRSC)) { lp->brsc[0] = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_BRSC_2GHZ ); + DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_BRSC_2GHZ); } - } - else if ( strcmp( key, PARM_NAME_BRSC_5GHZ ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_5GHZ, value ); + } else if (strcmp(key, PARM_NAME_BRSC_5GHZ) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_5GHZ, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_BRSC ) || ( value_convert <= PARM_MAX_BRSC )) { + if ((value_convert >= PARM_MIN_BRSC) || (value_convert <= PARM_MAX_BRSC)) { lp->brsc[1] = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_BRSC_5GHZ ); + DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_BRSC_5GHZ); } - } - else if (( strcmp( key, PARM_NAME_DESIRED_SSID ) == 0 ) || ( strcmp( key, PARM_NAME_OWN_SSID ) == 0 )) { - DBG_TRACE( DbgInfo, "SSID, value: %s\n", value ); + } else if ((strcmp(key, PARM_NAME_DESIRED_SSID) == 0) || (strcmp(key, PARM_NAME_OWN_SSID) == 0)) { + DBG_TRACE(DbgInfo, "SSID, value: %s\n", value); - memset( lp->NetworkName, 0, ( PARM_MAX_NAME_LEN + 1 )); + memset(lp->NetworkName, 0, (PARM_MAX_NAME_LEN + 1)); /* Make sure the value isn't too long */ - string_length = strlen( value ); - if ( string_length > PARM_MAX_NAME_LEN ) { - DBG_WARNING( DbgInfo, "SSID too long; will be truncated\n" ); + string_length = strlen(value); + if (string_length > PARM_MAX_NAME_LEN) { + DBG_WARNING(DbgInfo, "SSID too long; will be truncated\n"); string_length = PARM_MAX_NAME_LEN; } - memcpy( lp->NetworkName, value, string_length ); + memcpy(lp->NetworkName, value, string_length); } #if 0 - else if ( strcmp( key, PARM_NAME_DOWNLOAD_FIRMWARE ) == 0 ) { - DBG_TRACE( DbgInfo, "DOWNLOAD_FIRMWARE, value: %s\n", value ); - memset( lp->fw_image_filename, 0, ( MAX_LINE_SIZE + 1 )); + else if (strcmp(key, PARM_NAME_DOWNLOAD_FIRMWARE) == 0) { + DBG_TRACE(DbgInfo, "DOWNLOAD_FIRMWARE, value: %s\n", value); + memset(lp->fw_image_filename, 0, (MAX_LINE_SIZE + 1)); /* Make sure the value isn't too long */ - string_length = strlen( value ); - if ( string_length > MAX_LINE_SIZE ) { - DBG_WARNING( DbgInfo, "F/W image file name too long; will be ignored\n" ); + string_length = strlen(value); + if (string_length > MAX_LINE_SIZE) { + DBG_WARNING(DbgInfo, "F/W image file name too long; will be ignored\n"); } else { - memcpy( lp->fw_image_filename, value, string_length ); + memcpy(lp->fw_image_filename, value, string_length); } } #endif - else if ( strcmp( key, PARM_NAME_ENABLE_ENCRYPTION ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_ENABLE_ENCRYPTION, value ); + else if (strcmp(key, PARM_NAME_ENABLE_ENCRYPTION) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_ENABLE_ENCRYPTION, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_ENABLE_ENCRYPTION ) && ( value_convert <= PARM_MAX_ENABLE_ENCRYPTION )) { + if ((value_convert >= PARM_MIN_ENABLE_ENCRYPTION) && (value_convert <= PARM_MAX_ENABLE_ENCRYPTION)) { lp->EnableEncryption = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_ENABLE_ENCRYPTION ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_ENABLE_ENCRYPTION); } - } - else if ( strcmp( key, PARM_NAME_ENCRYPTION ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_ENCRYPTION, value ); + } else if (strcmp(key, PARM_NAME_ENCRYPTION) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_ENCRYPTION, value); - memset( lp->szEncryption, 0, sizeof( lp->szEncryption )); + memset(lp->szEncryption, 0, sizeof(lp->szEncryption)); /* Make sure the value isn't too long */ - string_length = strlen( value ); - if ( string_length > sizeof( lp->szEncryption ) ) { - DBG_WARNING( DbgInfo, "%s too long; will be truncated\n", PARM_NAME_ENCRYPTION ); - string_length = sizeof( lp->szEncryption ); + string_length = strlen(value); + if (string_length > sizeof(lp->szEncryption)) { + DBG_WARNING(DbgInfo, "%s too long; will be truncated\n", PARM_NAME_ENCRYPTION); + string_length = sizeof(lp->szEncryption); } - memcpy( lp->szEncryption, value, string_length ); - } - else if ( strcmp( key, PARM_NAME_KEY1 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_KEY1, value ); + memcpy(lp->szEncryption, value, string_length); + } else if (strcmp(key, PARM_NAME_KEY1) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_KEY1, value); - if ( is_valid_key_string( value )) { - memset( lp->DefaultKeys.key[0].key, 0, MAX_KEY_SIZE ); + if (is_valid_key_string(value)) { + memset(lp->DefaultKeys.key[0].key, 0, MAX_KEY_SIZE); - key_string2key( value, &lp->DefaultKeys.key[0] ); + key_string2key(value, &lp->DefaultKeys.key[0]); } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY1 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY1); } - } - else if ( strcmp( key, PARM_NAME_KEY2 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_KEY2, value ); + } else if (strcmp(key, PARM_NAME_KEY2) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_KEY2, value); - if ( is_valid_key_string( value )) { - memset( lp->DefaultKeys.key[1].key, 0, MAX_KEY_SIZE ); + if (is_valid_key_string(value)) { + memset(lp->DefaultKeys.key[1].key, 0, MAX_KEY_SIZE); - key_string2key( value, &lp->DefaultKeys.key[1] ); + key_string2key(value, &lp->DefaultKeys.key[1]); } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY2 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY2); } - } - else if ( strcmp( key, PARM_NAME_KEY3 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_KEY3, value ); + } else if (strcmp(key, PARM_NAME_KEY3) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_KEY3, value); - if ( is_valid_key_string( value )) { - memset( lp->DefaultKeys.key[2].key, 0, MAX_KEY_SIZE ); + if (is_valid_key_string(value)) { + memset(lp->DefaultKeys.key[2].key, 0, MAX_KEY_SIZE); - key_string2key( value, &lp->DefaultKeys.key[2] ); + key_string2key(value, &lp->DefaultKeys.key[2]); } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY3 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY3); } - } - else if ( strcmp( key, PARM_NAME_KEY4 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_KEY4, value ); + } else if (strcmp(key, PARM_NAME_KEY4) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_KEY4, value); - if ( is_valid_key_string( value )) { - memset( lp->DefaultKeys.key[3].key, 0, MAX_KEY_SIZE ); + if (is_valid_key_string(value)) { + memset(lp->DefaultKeys.key[3].key, 0, MAX_KEY_SIZE); - key_string2key( value, &lp->DefaultKeys.key[3] ); + key_string2key(value, &lp->DefaultKeys.key[3]); } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY4 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY4); } } /* New Parameters for WARP */ - else if ( strcmp( key, PARM_NAME_LOAD_BALANCING ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_LOAD_BALANCING, value ); + else if (strcmp(key, PARM_NAME_LOAD_BALANCING) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_LOAD_BALANCING, value); lp->loadBalancing = parse_yes_no(value); - } - else if ( strcmp( key, PARM_NAME_MEDIUM_DISTRIBUTION ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MEDIUM_DISTRIBUTION, value ); + } else if (strcmp(key, PARM_NAME_MEDIUM_DISTRIBUTION) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MEDIUM_DISTRIBUTION, value); lp->mediumDistribution = parse_yes_no(value); - } - else if ( strcmp( key, PARM_NAME_MICROWAVE_ROBUSTNESS) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MICROWAVE_ROBUSTNESS, value ); + } else if (strcmp(key, PARM_NAME_MICROWAVE_ROBUSTNESS) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MICROWAVE_ROBUSTNESS, value); lp->MicrowaveRobustness = parse_yes_no(value); - } - else if ( strcmp( key, PARM_NAME_MULTICAST_RATE ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_RATE, value ); + } else if (strcmp(key, PARM_NAME_MULTICAST_RATE) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_RATE, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_MULTICAST_RATE ) && ( value_convert <= PARM_MAX_MULTICAST_RATE )) { + if ((value_convert >= PARM_MIN_MULTICAST_RATE) && (value_convert <= PARM_MAX_MULTICAST_RATE)) { lp->MulticastRate[0] = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MULTICAST_RATE ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MULTICAST_RATE); } - } - else if ( strcmp( key, PARM_NAME_OWN_CHANNEL ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_CHANNEL, value ); + } else if (strcmp(key, PARM_NAME_OWN_CHANNEL) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_CHANNEL, value); value_convert = simple_strtoul(value, NULL, 0); - if ( wl_is_a_valid_chan( value_convert )) { - if ( value_convert > 14 ) { + if (wl_is_a_valid_chan(value_convert)) { + if (value_convert > 14) { value_convert = value_convert | 0x100; } lp->Channel = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_CHANNEL ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_CHANNEL); } - } - else if ( strcmp( key, PARM_NAME_OWN_NAME ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_NAME, value ); + } else if (strcmp(key, PARM_NAME_OWN_NAME) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_NAME, value); - memset( lp->StationName, 0, ( PARM_MAX_NAME_LEN + 1 )); + memset(lp->StationName, 0, (PARM_MAX_NAME_LEN + 1)); /* Make sure the value isn't too long */ - string_length = strlen( value ); - if ( string_length > PARM_MAX_NAME_LEN ) { - DBG_WARNING( DbgInfo, "%s too long; will be truncated\n", PARM_NAME_OWN_NAME ); + string_length = strlen(value); + if (string_length > PARM_MAX_NAME_LEN) { + DBG_WARNING(DbgInfo, "%s too long; will be truncated\n", PARM_NAME_OWN_NAME); string_length = PARM_MAX_NAME_LEN; } - memcpy( lp->StationName, value, string_length ); - } - else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD, value ); + memcpy(lp->StationName, value, string_length); + } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { + if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) { lp->RTSThreshold = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD); } - } - else if ( strcmp( key, PARM_NAME_SRSC_2GHZ ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_2GHZ, value ); + } else if (strcmp(key, PARM_NAME_SRSC_2GHZ) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_2GHZ, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_SRSC ) || ( value_convert <= PARM_MAX_SRSC )) { + if ((value_convert >= PARM_MIN_SRSC) || (value_convert <= PARM_MAX_SRSC)) { lp->srsc[0] = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_SRSC_2GHZ ); + DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_SRSC_2GHZ); } - } - else if ( strcmp( key, PARM_NAME_SRSC_5GHZ ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_5GHZ, value ); + } else if (strcmp(key, PARM_NAME_SRSC_5GHZ) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_5GHZ, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_SRSC ) || ( value_convert <= PARM_MAX_SRSC )) { + if ((value_convert >= PARM_MIN_SRSC) || (value_convert <= PARM_MAX_SRSC)) { lp->srsc[1] = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_SRSC_5GHZ ); + DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_SRSC_5GHZ); } - } - else if ( strcmp( key, PARM_NAME_SYSTEM_SCALE ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SYSTEM_SCALE, value ); + } else if (strcmp(key, PARM_NAME_SYSTEM_SCALE) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SYSTEM_SCALE, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_SYSTEM_SCALE ) && ( value_convert <= PARM_MAX_SYSTEM_SCALE )) { + if ((value_convert >= PARM_MIN_SYSTEM_SCALE) && (value_convert <= PARM_MAX_SYSTEM_SCALE)) { lp->DistanceBetweenAPs = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_SYSTEM_SCALE ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_SYSTEM_SCALE); } - } - else if ( strcmp( key, PARM_NAME_TX_KEY ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_KEY, value ); + } else if (strcmp(key, PARM_NAME_TX_KEY) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_KEY, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_TX_KEY ) && ( value_convert <= PARM_MAX_TX_KEY )) { + if ((value_convert >= PARM_MIN_TX_KEY) && (value_convert <= PARM_MAX_TX_KEY)) { lp->TransmitKeyID = simple_strtoul(value, NULL, 0); } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_KEY ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_KEY); } - } - else if ( strcmp( key, PARM_NAME_TX_RATE ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE, value ); + } else if (strcmp(key, PARM_NAME_TX_RATE) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { + if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) { lp->TxRateControl[0] = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE); } - } - else if ( strcmp( key, PARM_NAME_TX_POW_LEVEL ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_POW_LEVEL, value ); + } else if (strcmp(key, PARM_NAME_TX_POW_LEVEL) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_POW_LEVEL, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_TX_POW_LEVEL ) || ( value_convert <= PARM_MAX_TX_POW_LEVEL )) { + if ((value_convert >= PARM_MIN_TX_POW_LEVEL) || (value_convert <= PARM_MAX_TX_POW_LEVEL)) { lp->txPowLevel = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_POW_LEVEL ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_POW_LEVEL); } } @@ -640,101 +622,91 @@ void translate_option( char *buffer, struct wl_private *lp ) /* Configuration parameters specific to STA mode */ #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA //;?seems reasonable that even an AP-only driver could afford this small additional footprint - if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) { + if (CNV_INT_TO_LITTLE(lp->hcfCtx.IFB_FWIdentity.comp_id) == COMP_ID_FW_STA) { //;?should we return an error status in AP mode - if ( strcmp( key, PARM_NAME_PORT_TYPE ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PORT_TYPE, value ); + if (strcmp(key, PARM_NAME_PORT_TYPE) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PORT_TYPE, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert == PARM_MIN_PORT_TYPE ) || ( value_convert == PARM_MAX_PORT_TYPE )) { + if ((value_convert == PARM_MIN_PORT_TYPE) || (value_convert == PARM_MAX_PORT_TYPE)) { lp->PortType = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PORT_TYPE ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PORT_TYPE); } - } - else if ( strcmp( key, PARM_NAME_PM_ENABLED ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PM_ENABLED, value ); + } else if (strcmp(key, PARM_NAME_PM_ENABLED) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PM_ENABLED, value); value_convert = simple_strtoul(value, NULL, 0); /* ;? how about wl_main.c containing - * VALID_PARAM( PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD || - * ( PARM_PM_ENABLED & 0x7FFF ) <= WVLAN_PM_STATE_STANDARD ); + * VALID_PARAM(PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD || + * (PARM_PM_ENABLED & 0x7FFF) <= WVLAN_PM_STATE_STANDARD); */ - if ( ( value_convert & 0x7FFF ) <= PARM_MAX_PM_ENABLED) { + if ((value_convert & 0x7FFF) <= PARM_MAX_PM_ENABLED) { lp->PMEnabled = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PM_ENABLED ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PM_ENABLED); //;?this is a data entry error, hence not a DBG_WARNING } - } - else if ( strcmp( key, PARM_NAME_CREATE_IBSS ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_CREATE_IBSS, value ); + } else if (strcmp(key, PARM_NAME_CREATE_IBSS) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_CREATE_IBSS, value); lp->CreateIBSS = parse_yes_no(value); - } - else if ( strcmp( key, PARM_NAME_MULTICAST_RX ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_RX, value ); + } else if (strcmp(key, PARM_NAME_MULTICAST_RX) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_RX, value); lp->MulticastReceive = parse_yes_no(value); - } - else if ( strcmp( key, PARM_NAME_MAX_SLEEP ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MAX_SLEEP, value ); + } else if (strcmp(key, PARM_NAME_MAX_SLEEP) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MAX_SLEEP, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= 0 ) && ( value_convert <= 65535 )) { + if ((value_convert >= 0) && (value_convert <= 65535)) { lp->MaxSleepDuration = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MAX_SLEEP ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MAX_SLEEP); } - } - else if ( strcmp( key, PARM_NAME_NETWORK_ADDR ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_NETWORK_ADDR, value ); + } else if (strcmp(key, PARM_NAME_NETWORK_ADDR) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_NETWORK_ADDR, value); - if ( parse_mac_address( value, mac_value ) == ETH_ALEN ) { - memcpy( lp->MACAddress, mac_value, ETH_ALEN ); + if (parse_mac_address(value, mac_value) == ETH_ALEN) { + memcpy(lp->MACAddress, mac_value, ETH_ALEN); } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_NETWORK_ADDR ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_NETWORK_ADDR); } - } - else if ( strcmp( key, PARM_NAME_AUTHENTICATION ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_AUTHENTICATION, value ); + } else if (strcmp(key, PARM_NAME_AUTHENTICATION) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_AUTHENTICATION, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_AUTHENTICATION ) && ( value_convert <= PARM_MAX_AUTHENTICATION )) { + if ((value_convert >= PARM_MIN_AUTHENTICATION) && (value_convert <= PARM_MAX_AUTHENTICATION)) { lp->authentication = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_AUTHENTICATION ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_AUTHENTICATION); } - } - else if ( strcmp( key, PARM_NAME_OWN_ATIM_WINDOW ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_ATIM_WINDOW, value ); + } else if (strcmp(key, PARM_NAME_OWN_ATIM_WINDOW) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_ATIM_WINDOW, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_OWN_ATIM_WINDOW ) && ( value_convert <= PARM_MAX_OWN_ATIM_WINDOW )) { + if ((value_convert >= PARM_MIN_OWN_ATIM_WINDOW) && (value_convert <= PARM_MAX_OWN_ATIM_WINDOW)) { lp->atimWindow = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_ATIM_WINDOW ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_ATIM_WINDOW); } - } - else if ( strcmp( key, PARM_NAME_PM_HOLDOVER_DURATION ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PM_HOLDOVER_DURATION, value ); + } else if (strcmp(key, PARM_NAME_PM_HOLDOVER_DURATION) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PM_HOLDOVER_DURATION, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_PM_HOLDOVER_DURATION ) && ( value_convert <= PARM_MAX_PM_HOLDOVER_DURATION )) { + if ((value_convert >= PARM_MIN_PM_HOLDOVER_DURATION) && (value_convert <= PARM_MAX_PM_HOLDOVER_DURATION)) { lp->holdoverDuration = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PM_HOLDOVER_DURATION ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PM_HOLDOVER_DURATION); } - } - else if ( strcmp( key, PARM_NAME_PROMISCUOUS_MODE ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PROMISCUOUS_MODE, value ); + } else if (strcmp(key, PARM_NAME_PROMISCUOUS_MODE) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PROMISCUOUS_MODE, value); lp->promiscuousMode = parse_yes_no(value); - } - else if ( strcmp( key, PARM_NAME_CONNECTION_CONTROL ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_CONNECTION_CONTROL, value ); + } else if (strcmp(key, PARM_NAME_CONNECTION_CONTROL) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_CONNECTION_CONTROL, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_CONNECTION_CONTROL ) && ( value_convert <= PARM_MAX_CONNECTION_CONTROL )) { + if ((value_convert >= PARM_MIN_CONNECTION_CONTROL) && (value_convert <= PARM_MAX_CONNECTION_CONTROL)) { lp->connectionControl = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_CONNECTION_CONTROL ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_CONNECTION_CONTROL); } } @@ -745,227 +717,204 @@ void translate_option( char *buffer, struct wl_private *lp ) /* Configuration parameters specific to AP mode */ #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP //;?should we restore this to allow smaller memory footprint - if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) { - if ( strcmp( key, PARM_NAME_OWN_DTIM_PERIOD ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_DTIM_PERIOD, value ); + if (CNV_INT_TO_LITTLE(lp->hcfCtx.IFB_FWIdentity.comp_id) == COMP_ID_FW_AP) { + if (strcmp(key, PARM_NAME_OWN_DTIM_PERIOD) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_DTIM_PERIOD, value); value_convert = simple_strtoul(value, NULL, 0); - if ( value_convert >= PARM_MIN_OWN_DTIM_PERIOD ) { + if (value_convert >= PARM_MIN_OWN_DTIM_PERIOD) { lp->DTIMPeriod = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_DTIM_PERIOD ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_DTIM_PERIOD); } - } - else if ( strcmp( key, PARM_NAME_REJECT_ANY ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_REJECT_ANY, value ); + } else if (strcmp(key, PARM_NAME_REJECT_ANY) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_REJECT_ANY, value); lp->RejectAny = parse_yes_no(value); - } - else if ( strcmp( key, PARM_NAME_EXCLUDE_UNENCRYPTED ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_EXCLUDE_UNENCRYPTED, value ); + } else if (strcmp(key, PARM_NAME_EXCLUDE_UNENCRYPTED) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_EXCLUDE_UNENCRYPTED, value); lp->ExcludeUnencrypted = parse_yes_no(value); - } - else if ( strcmp( key, PARM_NAME_MULTICAST_PM_BUFFERING ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_PM_BUFFERING, value ); + } else if (strcmp(key, PARM_NAME_MULTICAST_PM_BUFFERING) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_PM_BUFFERING, value); lp->ExcludeUnencrypted = parse_yes_no(value); - } - else if ( strcmp( key, PARM_NAME_INTRA_BSS_RELAY ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_INTRA_BSS_RELAY, value ); + } else if (strcmp(key, PARM_NAME_INTRA_BSS_RELAY) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_INTRA_BSS_RELAY, value); lp->ExcludeUnencrypted = parse_yes_no(value); - } - else if ( strcmp( key, PARM_NAME_OWN_BEACON_INTERVAL ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_BEACON_INTERVAL, value ); + } else if (strcmp(key, PARM_NAME_OWN_BEACON_INTERVAL) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_BEACON_INTERVAL, value); value_convert = simple_strtoul(value, NULL, 0); - if ( value_convert >= PARM_MIN_OWN_BEACON_INTERVAL ) { + if (value_convert >= PARM_MIN_OWN_BEACON_INTERVAL) { lp->ownBeaconInterval = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_BEACON_INTERVAL ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_BEACON_INTERVAL); } - } - else if ( strcmp( key, PARM_NAME_COEXISTENCE ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_COEXISTENCE, value ); + } else if (strcmp(key, PARM_NAME_COEXISTENCE) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_COEXISTENCE, value); value_convert = simple_strtoul(value, NULL, 0); - if ( value_convert >= PARM_MIN_COEXISTENCE ) { + if (value_convert >= PARM_MIN_COEXISTENCE) { lp->coexistence = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_COEXISTENCE ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_COEXISTENCE); } } #ifdef USE_WDS - else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD1 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD1, value ); + else if (strcmp(key, PARM_NAME_RTS_THRESHOLD1) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD1, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { + if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) { lp->wds_port[0].rtsThreshold = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD1 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD1); } - } - else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD2 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD2, value ); + } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD2) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD2, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { + if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) { lp->wds_port[1].rtsThreshold = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD2 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD2); } - } - else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD3 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD3, value ); + } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD3) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD3, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { + if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) { lp->wds_port[2].rtsThreshold = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD3 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD3); } - } - else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD4 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD4, value ); + } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD4) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD4, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { + if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) { lp->wds_port[3].rtsThreshold = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD4 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD4); } - } - else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD5 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD5, value ); + } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD5) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD5, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { + if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) { lp->wds_port[4].rtsThreshold = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD5 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD5); } - } - else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD6 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD6, value ); + } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD6) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD6, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { + if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) { lp->wds_port[5].rtsThreshold = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD6 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD6); } - } - else if ( strcmp( key, PARM_NAME_TX_RATE1 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE1, value ); + } else if (strcmp(key, PARM_NAME_TX_RATE1) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE1, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { + if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) { lp->wds_port[0].txRateCntl = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE1 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE1); } - } - else if ( strcmp( key, PARM_NAME_TX_RATE2 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE2, value ); + } else if (strcmp(key, PARM_NAME_TX_RATE2) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE2, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { + if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) { lp->wds_port[1].txRateCntl = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE2 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE2); } - } - else if ( strcmp( key, PARM_NAME_TX_RATE3 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE3, value ); + } else if (strcmp(key, PARM_NAME_TX_RATE3) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE3, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { + if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) { lp->wds_port[2].txRateCntl = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE3 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE3); } - } - else if ( strcmp( key, PARM_NAME_TX_RATE4 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE4, value ); + } else if (strcmp(key, PARM_NAME_TX_RATE4) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE4, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { + if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) { lp->wds_port[3].txRateCntl = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE4 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE4); } - } - else if ( strcmp( key, PARM_NAME_TX_RATE5 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE5, value ); + } else if (strcmp(key, PARM_NAME_TX_RATE5) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE5, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { + if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) { lp->wds_port[4].txRateCntl = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE5 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE5); } - } - else if ( strcmp( key, PARM_NAME_TX_RATE6 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE6, value ); + } else if (strcmp(key, PARM_NAME_TX_RATE6) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE6, value); value_convert = simple_strtoul(value, NULL, 0); - if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { + if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) { lp->wds_port[5].txRateCntl = value_convert; } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE6 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE6); } - } - else if ( strcmp( key, PARM_NAME_WDS_ADDRESS1 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS1, value ); + } else if (strcmp(key, PARM_NAME_WDS_ADDRESS1) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS1, value); - if ( parse_mac_address( value, mac_value ) == ETH_ALEN ) { - memcpy( lp->wds_port[0].wdsAddress, mac_value, ETH_ALEN ); + if (parse_mac_address(value, mac_value) == ETH_ALEN) { + memcpy(lp->wds_port[0].wdsAddress, mac_value, ETH_ALEN); } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS1 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS1); } - } - else if ( strcmp( key, PARM_NAME_WDS_ADDRESS2 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS2, value ); + } else if (strcmp(key, PARM_NAME_WDS_ADDRESS2) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS2, value); - if ( parse_mac_address( value, mac_value ) == ETH_ALEN ) { - memcpy( lp->wds_port[1].wdsAddress, mac_value, ETH_ALEN ); + if (parse_mac_address(value, mac_value) == ETH_ALEN) { + memcpy(lp->wds_port[1].wdsAddress, mac_value, ETH_ALEN); } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS2 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS2); } - } - else if ( strcmp( key, PARM_NAME_WDS_ADDRESS3 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS3, value ); + } else if (strcmp(key, PARM_NAME_WDS_ADDRESS3) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS3, value); - if ( parse_mac_address( value, mac_value ) == ETH_ALEN ) { - memcpy( lp->wds_port[2].wdsAddress, mac_value, ETH_ALEN ); + if (parse_mac_address(value, mac_value) == ETH_ALEN) { + memcpy(lp->wds_port[2].wdsAddress, mac_value, ETH_ALEN); } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS3 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS3); } - } - else if ( strcmp( key, PARM_NAME_WDS_ADDRESS4 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS4, value ); + } else if (strcmp(key, PARM_NAME_WDS_ADDRESS4) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS4, value); - if ( parse_mac_address( value, mac_value ) == ETH_ALEN ) { - memcpy( lp->wds_port[3].wdsAddress, mac_value, ETH_ALEN ); + if (parse_mac_address(value, mac_value) == ETH_ALEN) { + memcpy(lp->wds_port[3].wdsAddress, mac_value, ETH_ALEN); } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS4 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS4); } - } - else if ( strcmp( key, PARM_NAME_WDS_ADDRESS5 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS5, value ); + } else if (strcmp(key, PARM_NAME_WDS_ADDRESS5) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS5, value); - if ( parse_mac_address( value, mac_value ) == ETH_ALEN ) { - memcpy( lp->wds_port[4].wdsAddress, mac_value, ETH_ALEN ); + if (parse_mac_address(value, mac_value) == ETH_ALEN) { + memcpy(lp->wds_port[4].wdsAddress, mac_value, ETH_ALEN); } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS5 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS5); } - } - else if ( strcmp( key, PARM_NAME_WDS_ADDRESS6 ) == 0 ) { - DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS6, value ); + } else if (strcmp(key, PARM_NAME_WDS_ADDRESS6) == 0) { + DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS6, value); - if ( parse_mac_address( value, mac_value ) == ETH_ALEN ) { - memcpy( lp->wds_port[5].wdsAddress, mac_value, ETH_ALEN ); + if (parse_mac_address(value, mac_value) == ETH_ALEN) { + memcpy(lp->wds_port[5].wdsAddress, mac_value, ETH_ALEN); } else { - DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS6 ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS6); } } #endif /* USE_WDS */ @@ -996,7 +945,7 @@ void translate_option( char *buffer, struct wl_private *lp ) * The number of bytes in the final MAC address, should equal to ETH_ALEN. * ******************************************************************************/ -int parse_mac_address( char *value, u_char *byte_array ) +int parse_mac_address(char *value, u_char *byte_array) { int value_offset = 0; int array_offset = 0; @@ -1004,11 +953,11 @@ int parse_mac_address( char *value, u_char *byte_array ) char byte_field[3]; /*------------------------------------------------------------------------*/ - memset( byte_field, '\0', 3 ); + memset(byte_field, '\0', 3); - while( value[value_offset] != '\0' ) { + while (value[value_offset] != '\0') { /* Skip over the colon chars seperating the bytes, if they exist */ - if ( value[value_offset] == ':' ) { + if (value[value_offset] == ':') { value_offset++; continue; } @@ -1018,9 +967,9 @@ int parse_mac_address( char *value, u_char *byte_array ) value_offset++; /* Once the byte_field is filled, convert it and store it */ - if ( field_offset == 2 ) { + if (field_offset == 2) { byte_field[field_offset] = '\0'; - byte_array[array_offset] = simple_strtoul( byte_field, NULL, 16 ); + byte_array[array_offset] = simple_strtoul(byte_field, NULL, 16); field_offset = 0; array_offset++; } @@ -1052,42 +1001,42 @@ int parse_mac_address( char *value, u_char *byte_array ) * N/A * ******************************************************************************/ -void ParseConfigLine( char *pszLine, char **ppszLVal, char **ppszRVal ) +void ParseConfigLine(char *pszLine, char **ppszLVal, char **ppszRVal) { int i; int size; /*------------------------------------------------------------------------*/ - DBG_FUNC( "ParseConfigLine" ); - DBG_ENTER( DbgInfo ); + DBG_FUNC("ParseConfigLine"); + DBG_ENTER(DbgInfo); /* get a snapshot of our string size */ - size = strlen( pszLine ); + size = strlen(pszLine); *ppszLVal = NULL; *ppszRVal = NULL; - if ( pszLine[0] != '#' && /* skip the line if it is a comment */ - pszLine[0] != '\n'&& /* if it's an empty UNIX line, do nothing */ - !( pszLine[0] == '\r' && pszLine[1] == '\n' ) /* if it's an empty MS-DOS line, do nothing */ - ) { + if (pszLine[0] != '#' && /* skip the line if it is a comment */ + pszLine[0] != '\n' && /* if it's an empty UNIX line, do nothing */ + !(pszLine[0] == '\r' && pszLine[1] == '\n') /* if it's an empty MS-DOS line, do nothing */ + ) { /* advance past any whitespace, and assign the L-value */ - for( i = 0; i < size; i++ ) { - if ( pszLine[i] != ' ' ) { + for (i = 0; i < size; i++) { + if (pszLine[i] != ' ') { *ppszLVal = &pszLine[i]; break; } } /* advance to the end of the l-value*/ - for( i++; i < size; i++ ) { - if ( pszLine[i] == ' ' || pszLine[i] == '=' ) { + for (i++; i < size; i++) { + if (pszLine[i] == ' ' || pszLine[i] == '=') { pszLine[i] = '\0'; break; } } /* make any whitespace and the equal sign a NULL character, and advance to the R-Value */ - for( i++; i < size; i++ ) { - if ( pszLine[i] == ' ' || pszLine[i] == '=' ) { + for (i++; i < size; i++) { + if (pszLine[i] == ' ' || pszLine[i] == '=') { pszLine[i] = '\0'; continue; } @@ -1095,16 +1044,16 @@ void ParseConfigLine( char *pszLine, char **ppszLVal, char **ppszRVal ) break; } /* make the line ending character(s) a NULL */ - for( i++; i < size; i++ ) { - if ( pszLine[i] == '\n' ) { + for (i++; i < size; i++) { + if (pszLine[i] == '\n') { pszLine[i] = '\0'; } - if (( pszLine[i] == '\r' ) && ( pszLine[i+1] == '\n' )) { + if ((pszLine[i] == '\r') && (pszLine[i+1] == '\n')) { pszLine[i] = '\0'; } } } - DBG_LEAVE( DbgInfo ); + DBG_LEAVE(DbgInfo); } // ParseConfigLine /*============================================================================*/ -- cgit v1.2.3 From ce7f6389790f24e07e7e32518c798451e799a830 Mon Sep 17 00:00:00 2001 From: "Prashant P. Shah" Date: Sun, 9 May 2010 22:41:46 +0530 Subject: Staging: wlags49_h2: fixed unnecessary braces issues in wl_profile.c This is a patch to the wl_profile.c file that fixes the unnecessary braces style issues found by the checkpatch.pl tool. Signed-off-by: Prashant P. Shah Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/wl_profile.c | 228 +++++++++++++------------------- 1 file changed, 90 insertions(+), 138 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlags49_h2/wl_profile.c b/drivers/staging/wlags49_h2/wl_profile.c index e4e78a4ace15..13ade7035731 100644 --- a/drivers/staging/wlags49_h2/wl_profile.c +++ b/drivers/staging/wlags49_h2/wl_profile.c @@ -189,9 +189,8 @@ void parse_config(struct net_device *dev) DBG_TRACE(DbgInfo, "Wireless config file found. Parsing options...\n"); /* Read out the options */ - while (readline(file_desc, buffer)) { + while (readline(file_desc, buffer)) translate_option(buffer, wvlan_config); - } /* Close the file */ close(file_desc); //;?even if file_desc == -1 ??? } else { @@ -259,9 +258,8 @@ void parse_config(struct net_device *dev) } else if (rc > 0) { DBG_TRACE(DbgInfo, "read O.K.: %d bytes %.12s\n", rc, cp); rc = read(file_desc, &cp[rc], 1); - if (rc == 0) { + if (rc == 0) DBG_TRACE(DbgInfo, "no more to read\n"); - } } if (rc != 0) { DBG_ERROR(DbgInfo, "file not read in one swoop or other error"\ @@ -320,11 +318,10 @@ int readline(int filedesc, char *buffer) } /* Return the number of bytes read */ - if (result == -1) { + if (result == -1) return result; - } else { + else return bytes_read; - } } // readline /*============================================================================*/ @@ -366,9 +363,8 @@ void translate_option(char *buffer, struct wl_private *lp) ParseConfigLine(buffer, &key, &value); - if (key == NULL || value == NULL) { + if (key == NULL || value == NULL) return; - } /* Determine which key it is and perform the appropriate action */ @@ -394,29 +390,26 @@ void translate_option(char *buffer, struct wl_private *lp) DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_AUTH_KEY_MGMT_SUITE, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_AUTH_KEY_MGMT_SUITE) || (value_convert <= PARM_MAX_AUTH_KEY_MGMT_SUITE)) { + if ((value_convert >= PARM_MIN_AUTH_KEY_MGMT_SUITE) || (value_convert <= PARM_MAX_AUTH_KEY_MGMT_SUITE)) lp->AuthKeyMgmtSuite = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_AUTH_KEY_MGMT_SUITE); - } } else if (strcmp(key, PARM_NAME_BRSC_2GHZ) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_2GHZ, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_BRSC) || (value_convert <= PARM_MAX_BRSC)) { + if ((value_convert >= PARM_MIN_BRSC) || (value_convert <= PARM_MAX_BRSC)) lp->brsc[0] = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_BRSC_2GHZ); - } } else if (strcmp(key, PARM_NAME_BRSC_5GHZ) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_5GHZ, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_BRSC) || (value_convert <= PARM_MAX_BRSC)) { + if ((value_convert >= PARM_MIN_BRSC) || (value_convert <= PARM_MAX_BRSC)) lp->brsc[1] = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_BRSC_5GHZ); - } } else if ((strcmp(key, PARM_NAME_DESIRED_SSID) == 0) || (strcmp(key, PARM_NAME_OWN_SSID) == 0)) { DBG_TRACE(DbgInfo, "SSID, value: %s\n", value); @@ -437,22 +430,20 @@ void translate_option(char *buffer, struct wl_private *lp) memset(lp->fw_image_filename, 0, (MAX_LINE_SIZE + 1)); /* Make sure the value isn't too long */ string_length = strlen(value); - if (string_length > MAX_LINE_SIZE) { + if (string_length > MAX_LINE_SIZE) DBG_WARNING(DbgInfo, "F/W image file name too long; will be ignored\n"); - } else { + else memcpy(lp->fw_image_filename, value, string_length); - } } #endif else if (strcmp(key, PARM_NAME_ENABLE_ENCRYPTION) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_ENABLE_ENCRYPTION, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_ENABLE_ENCRYPTION) && (value_convert <= PARM_MAX_ENABLE_ENCRYPTION)) { + if ((value_convert >= PARM_MIN_ENABLE_ENCRYPTION) && (value_convert <= PARM_MAX_ENABLE_ENCRYPTION)) lp->EnableEncryption = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_ENABLE_ENCRYPTION); - } } else if (strcmp(key, PARM_NAME_ENCRYPTION) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_ENCRYPTION, value); @@ -522,19 +513,17 @@ void translate_option(char *buffer, struct wl_private *lp) value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_MULTICAST_RATE) && (value_convert <= PARM_MAX_MULTICAST_RATE)) { + if ((value_convert >= PARM_MIN_MULTICAST_RATE) && (value_convert <= PARM_MAX_MULTICAST_RATE)) lp->MulticastRate[0] = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MULTICAST_RATE); - } } else if (strcmp(key, PARM_NAME_OWN_CHANNEL) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_CHANNEL, value); value_convert = simple_strtoul(value, NULL, 0); if (wl_is_a_valid_chan(value_convert)) { - if (value_convert > 14) { + if (value_convert > 14) value_convert = value_convert | 0x100; - } lp->Channel = value_convert; } else { DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_CHANNEL); @@ -556,65 +545,58 @@ void translate_option(char *buffer, struct wl_private *lp) DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) { + if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) lp->RTSThreshold = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD); - } } else if (strcmp(key, PARM_NAME_SRSC_2GHZ) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_2GHZ, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_SRSC) || (value_convert <= PARM_MAX_SRSC)) { + if ((value_convert >= PARM_MIN_SRSC) || (value_convert <= PARM_MAX_SRSC)) lp->srsc[0] = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_SRSC_2GHZ); - } } else if (strcmp(key, PARM_NAME_SRSC_5GHZ) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_5GHZ, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_SRSC) || (value_convert <= PARM_MAX_SRSC)) { + if ((value_convert >= PARM_MIN_SRSC) || (value_convert <= PARM_MAX_SRSC)) lp->srsc[1] = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_SRSC_5GHZ); - } } else if (strcmp(key, PARM_NAME_SYSTEM_SCALE) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SYSTEM_SCALE, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_SYSTEM_SCALE) && (value_convert <= PARM_MAX_SYSTEM_SCALE)) { + if ((value_convert >= PARM_MIN_SYSTEM_SCALE) && (value_convert <= PARM_MAX_SYSTEM_SCALE)) lp->DistanceBetweenAPs = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_SYSTEM_SCALE); - } } else if (strcmp(key, PARM_NAME_TX_KEY) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_KEY, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_TX_KEY) && (value_convert <= PARM_MAX_TX_KEY)) { + if ((value_convert >= PARM_MIN_TX_KEY) && (value_convert <= PARM_MAX_TX_KEY)) lp->TransmitKeyID = simple_strtoul(value, NULL, 0); - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_KEY); - } } else if (strcmp(key, PARM_NAME_TX_RATE) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) { + if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) lp->TxRateControl[0] = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE); - } } else if (strcmp(key, PARM_NAME_TX_POW_LEVEL) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_POW_LEVEL, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_TX_POW_LEVEL) || (value_convert <= PARM_MAX_TX_POW_LEVEL)) { + if ((value_convert >= PARM_MIN_TX_POW_LEVEL) || (value_convert <= PARM_MAX_TX_POW_LEVEL)) lp->txPowLevel = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_POW_LEVEL); - } } /* Need to add? : Country code, Short/Long retry */ @@ -628,11 +610,10 @@ void translate_option(char *buffer, struct wl_private *lp) DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PORT_TYPE, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert == PARM_MIN_PORT_TYPE) || (value_convert == PARM_MAX_PORT_TYPE)) { + if ((value_convert == PARM_MIN_PORT_TYPE) || (value_convert == PARM_MAX_PORT_TYPE)) lp->PortType = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PORT_TYPE); - } } else if (strcmp(key, PARM_NAME_PM_ENABLED) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PM_ENABLED, value); value_convert = simple_strtoul(value, NULL, 0); @@ -656,46 +637,41 @@ void translate_option(char *buffer, struct wl_private *lp) DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MAX_SLEEP, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= 0) && (value_convert <= 65535)) { + if ((value_convert >= 0) && (value_convert <= 65535)) lp->MaxSleepDuration = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MAX_SLEEP); - } } else if (strcmp(key, PARM_NAME_NETWORK_ADDR) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_NETWORK_ADDR, value); - if (parse_mac_address(value, mac_value) == ETH_ALEN) { + if (parse_mac_address(value, mac_value) == ETH_ALEN) memcpy(lp->MACAddress, mac_value, ETH_ALEN); - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_NETWORK_ADDR); - } } else if (strcmp(key, PARM_NAME_AUTHENTICATION) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_AUTHENTICATION, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_AUTHENTICATION) && (value_convert <= PARM_MAX_AUTHENTICATION)) { + if ((value_convert >= PARM_MIN_AUTHENTICATION) && (value_convert <= PARM_MAX_AUTHENTICATION)) lp->authentication = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_AUTHENTICATION); - } } else if (strcmp(key, PARM_NAME_OWN_ATIM_WINDOW) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_ATIM_WINDOW, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_OWN_ATIM_WINDOW) && (value_convert <= PARM_MAX_OWN_ATIM_WINDOW)) { + if ((value_convert >= PARM_MIN_OWN_ATIM_WINDOW) && (value_convert <= PARM_MAX_OWN_ATIM_WINDOW)) lp->atimWindow = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_ATIM_WINDOW); - } } else if (strcmp(key, PARM_NAME_PM_HOLDOVER_DURATION) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PM_HOLDOVER_DURATION, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_PM_HOLDOVER_DURATION) && (value_convert <= PARM_MAX_PM_HOLDOVER_DURATION)) { + if ((value_convert >= PARM_MIN_PM_HOLDOVER_DURATION) && (value_convert <= PARM_MAX_PM_HOLDOVER_DURATION)) lp->holdoverDuration = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PM_HOLDOVER_DURATION); - } } else if (strcmp(key, PARM_NAME_PROMISCUOUS_MODE) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PROMISCUOUS_MODE, value); lp->promiscuousMode = parse_yes_no(value); @@ -703,11 +679,10 @@ void translate_option(char *buffer, struct wl_private *lp) DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_CONNECTION_CONTROL, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_CONNECTION_CONTROL) && (value_convert <= PARM_MAX_CONNECTION_CONTROL)) { + if ((value_convert >= PARM_MIN_CONNECTION_CONTROL) && (value_convert <= PARM_MAX_CONNECTION_CONTROL)) lp->connectionControl = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_CONNECTION_CONTROL); - } } /* Need to add? : Probe Data Rate */ @@ -722,11 +697,10 @@ void translate_option(char *buffer, struct wl_private *lp) DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_DTIM_PERIOD, value); value_convert = simple_strtoul(value, NULL, 0); - if (value_convert >= PARM_MIN_OWN_DTIM_PERIOD) { + if (value_convert >= PARM_MIN_OWN_DTIM_PERIOD) lp->DTIMPeriod = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_DTIM_PERIOD); - } } else if (strcmp(key, PARM_NAME_REJECT_ANY) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_REJECT_ANY, value); lp->RejectAny = parse_yes_no(value); @@ -743,20 +717,18 @@ void translate_option(char *buffer, struct wl_private *lp) DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_BEACON_INTERVAL, value); value_convert = simple_strtoul(value, NULL, 0); - if (value_convert >= PARM_MIN_OWN_BEACON_INTERVAL) { + if (value_convert >= PARM_MIN_OWN_BEACON_INTERVAL) lp->ownBeaconInterval = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_BEACON_INTERVAL); - } } else if (strcmp(key, PARM_NAME_COEXISTENCE) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_COEXISTENCE, value); value_convert = simple_strtoul(value, NULL, 0); - if (value_convert >= PARM_MIN_COEXISTENCE) { + if (value_convert >= PARM_MIN_COEXISTENCE) lp->coexistence = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_COEXISTENCE); - } } #ifdef USE_WDS @@ -764,158 +736,140 @@ void translate_option(char *buffer, struct wl_private *lp) DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD1, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) { + if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) lp->wds_port[0].rtsThreshold = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD1); - } } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD2) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD2, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) { + if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) lp->wds_port[1].rtsThreshold = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD2); - } } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD3) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD3, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) { + if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) lp->wds_port[2].rtsThreshold = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD3); - } } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD4) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD4, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) { + if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) lp->wds_port[3].rtsThreshold = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD4); - } } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD5) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD5, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) { + if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) lp->wds_port[4].rtsThreshold = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD5); - } } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD6) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD6, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) { + if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD)) lp->wds_port[5].rtsThreshold = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD6); - } } else if (strcmp(key, PARM_NAME_TX_RATE1) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE1, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) { + if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) lp->wds_port[0].txRateCntl = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE1); - } } else if (strcmp(key, PARM_NAME_TX_RATE2) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE2, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) { + if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) lp->wds_port[1].txRateCntl = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE2); - } } else if (strcmp(key, PARM_NAME_TX_RATE3) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE3, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) { + if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) lp->wds_port[2].txRateCntl = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE3); - } } else if (strcmp(key, PARM_NAME_TX_RATE4) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE4, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) { + if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) lp->wds_port[3].txRateCntl = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE4); - } } else if (strcmp(key, PARM_NAME_TX_RATE5) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE5, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) { + if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) lp->wds_port[4].txRateCntl = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE5); - } } else if (strcmp(key, PARM_NAME_TX_RATE6) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE6, value); value_convert = simple_strtoul(value, NULL, 0); - if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) { + if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE)) lp->wds_port[5].txRateCntl = value_convert; - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE6); - } } else if (strcmp(key, PARM_NAME_WDS_ADDRESS1) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS1, value); - if (parse_mac_address(value, mac_value) == ETH_ALEN) { + if (parse_mac_address(value, mac_value) == ETH_ALEN) memcpy(lp->wds_port[0].wdsAddress, mac_value, ETH_ALEN); - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS1); - } } else if (strcmp(key, PARM_NAME_WDS_ADDRESS2) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS2, value); - if (parse_mac_address(value, mac_value) == ETH_ALEN) { + if (parse_mac_address(value, mac_value) == ETH_ALEN) memcpy(lp->wds_port[1].wdsAddress, mac_value, ETH_ALEN); - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS2); - } } else if (strcmp(key, PARM_NAME_WDS_ADDRESS3) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS3, value); - if (parse_mac_address(value, mac_value) == ETH_ALEN) { + if (parse_mac_address(value, mac_value) == ETH_ALEN) memcpy(lp->wds_port[2].wdsAddress, mac_value, ETH_ALEN); - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS3); - } } else if (strcmp(key, PARM_NAME_WDS_ADDRESS4) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS4, value); - if (parse_mac_address(value, mac_value) == ETH_ALEN) { + if (parse_mac_address(value, mac_value) == ETH_ALEN) memcpy(lp->wds_port[3].wdsAddress, mac_value, ETH_ALEN); - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS4); - } } else if (strcmp(key, PARM_NAME_WDS_ADDRESS5) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS5, value); - if (parse_mac_address(value, mac_value) == ETH_ALEN) { + if (parse_mac_address(value, mac_value) == ETH_ALEN) memcpy(lp->wds_port[4].wdsAddress, mac_value, ETH_ALEN); - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS5); - } } else if (strcmp(key, PARM_NAME_WDS_ADDRESS6) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS6, value); - if (parse_mac_address(value, mac_value) == ETH_ALEN) { + if (parse_mac_address(value, mac_value) == ETH_ALEN) memcpy(lp->wds_port[5].wdsAddress, mac_value, ETH_ALEN); - } else { + else DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS6); - } } #endif /* USE_WDS */ } @@ -1045,12 +999,10 @@ void ParseConfigLine(char *pszLine, char **ppszLVal, char **ppszRVal) } /* make the line ending character(s) a NULL */ for (i++; i < size; i++) { - if (pszLine[i] == '\n') { + if (pszLine[i] == '\n') pszLine[i] = '\0'; - } - if ((pszLine[i] == '\r') && (pszLine[i+1] == '\n')) { + if ((pszLine[i] == '\r') && (pszLine[i+1] == '\n')) pszLine[i] = '\0'; - } } } DBG_LEAVE(DbgInfo); -- cgit v1.2.3 From e9ec36030cca2549cb656d94347dafecfcf218f6 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Tue, 11 May 2010 15:11:24 +0000 Subject: staging: hv: Optimize adj_guesttime function and add more detailed comments Credits go to Joe Perches for suggesting the changes. Cc: Joe Perches Signed-off-by: Hank Janssen Signed-off-by: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_utils.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_utils.c b/drivers/staging/hv/hv_utils.c index 8f1d3ba7e098..db45d97a3a7c 100644 --- a/drivers/staging/hv/hv_utils.c +++ b/drivers/staging/hv/hv_utils.c @@ -106,31 +106,44 @@ static void shutdown_onchannelcallback(void *context) orderly_poweroff(false); } - /* - * Synchronize time with host after reboot, restore, etc. + * Set guest time to host UTC time. */ -static void adj_guesttime(u64 hosttime, u8 flags) +static inline void do_adj_guesttime(u64 hosttime) { s64 host_tns; struct timespec host_ts; - static s32 scnt = 50; host_tns = (hosttime - WLTIMEDELTA) * 100; host_ts = ns_to_timespec(host_tns); + do_settimeofday(&host_ts); +} + +/* + * Synchronize time with host after reboot, restore, etc. + * + * ICTIMESYNCFLAG_SYNC flag bit indicates reboot, restore events of the VM. + * After reboot the flag ICTIMESYNCFLAG_SYNC is included in the first time + * message after the timesync channel is opened. Since the hv_utils module is + * loaded after hv_vmbus, the first message is usually missed. The other + * thing is, systime is automatically set to emulated hardware clock which may + * not be UTC time or in the same time zone. So, to override these effects, we + * use the first 50 time samples for initial system time setting. + */ +static inline void adj_guesttime(u64 hosttime, u8 flags) +{ + static s32 scnt = 50; + if ((flags & ICTIMESYNCFLAG_SYNC) != 0) { - do_settimeofday(&host_ts); + do_adj_guesttime(hosttime); return; } - if ((flags & ICTIMESYNCFLAG_SAMPLE) != 0 && - scnt > 0) { + if ((flags & ICTIMESYNCFLAG_SAMPLE) != 0 && scnt > 0) { scnt--; - do_settimeofday(&host_ts); + do_adj_guesttime(hosttime); } - - return; } /* -- cgit v1.2.3 From 83e13438d6adadce30de40c27e902f9a34eca0ee Mon Sep 17 00:00:00 2001 From: Charles Clément Date: Sun, 9 May 2010 11:00:51 -0700 Subject: Staging: wlags49_h2*: wireless driver Kconfig update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change the wireless drivers to depend on CONFIG_WLAN instead of CONFIG_WLAN_80211 which is gone. Signed-off-by: Charles Clément Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/Kconfig | 2 +- drivers/staging/wlags49_h25/Kconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlags49_h2/Kconfig b/drivers/staging/wlags49_h2/Kconfig index 92053fe70130..b6fc2ca7d85c 100644 --- a/drivers/staging/wlags49_h2/Kconfig +++ b/drivers/staging/wlags49_h2/Kconfig @@ -1,6 +1,6 @@ config WLAGS49_H2 tristate "Agere Systems HERMES II Wireless PC Card Model 0110" - depends on WLAN_80211 && WIRELESS_EXT && PCMCIA + depends on WLAN && WIRELESS_EXT && PCMCIA select WEXT_SPY ---help--- Driver for wireless cards using Agere's HERMES II chipset diff --git a/drivers/staging/wlags49_h25/Kconfig b/drivers/staging/wlags49_h25/Kconfig index 304a8c96ce33..dcc170929c13 100644 --- a/drivers/staging/wlags49_h25/Kconfig +++ b/drivers/staging/wlags49_h25/Kconfig @@ -1,6 +1,6 @@ config WLAGS49_H25 tristate "Linksys HERMES II.5 WCF54G_Wireless-G_CompactFlash_Card" - depends on WLAN_80211 && WIRELESS_EXT && PCMCIA + depends on WLAN && WIRELESS_EXT && PCMCIA select WEXT_SPY ---help--- Driver for wireless cards using Agere's HERMES II.5 chipset -- cgit v1.2.3 From 5ae8cb9525f0481025b9bc156c7a181aff7ded47 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 11 May 2010 15:51:53 -0700 Subject: Staging: wlags49: build fixes Now that the code actually gets selected in the kernel config properly, all of the build errors start showing up. This patch papers over a few of them to get the code to build, I have no idea if it actually works now or not... Cc: Henk de Groot Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/dhf.c | 10 +++++----- drivers/staging/wlags49_h2/wl_cs.c | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlags49_h2/dhf.c b/drivers/staging/wlags49_h2/dhf.c index d5fb1a97e855..80a4707885d8 100644 --- a/drivers/staging/wlags49_h2/dhf.c +++ b/drivers/staging/wlags49_h2/dhf.c @@ -286,14 +286,14 @@ int i; fw->signature[i+1] != (/* HCF_BIG_ENDIAN ? 'B' : */ 'L')) rc = DHF_ERR_INCOMP_FW; else { /* Little Endian Binary format */ - fw->codep = (CFG_PROG_STRCT FAR*)((PSEUDO_CHARP)fw->codep + (hcf_32)fw); - fw->identity = (CFG_IDENTITY_STRCT FAR*)((PSEUDO_CHARP)fw->identity + (hcf_32)fw); - fw->compat = (CFG_RANGE20_STRCT FAR*)((PSEUDO_CHARP)fw->compat + (hcf_32)fw); + fw->codep = (CFG_PROG_STRCT FAR*)((char *)fw->codep + (hcf_32)fw); + fw->identity = (CFG_IDENTITY_STRCT FAR*)((char *)fw->identity + (hcf_32)fw); + fw->compat = (CFG_RANGE20_STRCT FAR*)((char *)fw->compat + (hcf_32)fw); for (i = 0; fw->p[i]; i++) - fw->p[i] = ((PSEUDO_CHARP)fw->p[i] + (hcf_32)fw); + fw->p[i] = ((char *)fw->p[i] + (hcf_32)fw); p = fw->codep; while (p->len) { - p->host_addr = (PSEUDO_CHARP)p->host_addr + (hcf_32)fw; + p->host_addr = (char *)p->host_addr + (hcf_32)fw; p++; } } diff --git a/drivers/staging/wlags49_h2/wl_cs.c b/drivers/staging/wlags49_h2/wl_cs.c index 9da42e66085e..7c33eade6b8a 100644 --- a/drivers/staging/wlags49_h2/wl_cs.c +++ b/drivers/staging/wlags49_h2/wl_cs.c @@ -157,14 +157,14 @@ static int wl_adapter_attach(struct pcmcia_device *link) link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; link->io.IOAddrLines = 6; link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT; - link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID; +// link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID; link->irq.Handler = &wl_isr; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 5; link->conf.Present = PRESENT_OPTION; - link->priv = link->irq.Instance = dev; + link->priv = dev; lp = wl_priv(dev); lp->link = link; @@ -317,15 +317,15 @@ void wl_adapter_insert( struct pcmcia_device *link ) /* Do we need to allocate an interrupt? */ link->conf.Attributes |= CONF_ENABLE_IRQ; - CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); +// CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); +// CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); +// CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; - SET_NETDEV_DEV(dev, &handle_to_dev(link)); + SET_NETDEV_DEV(dev, &link->dev); if (register_netdev(dev) != 0) { printk("%s: register_netdev() failed\n", MODULE_NAME); goto failed; @@ -345,7 +345,7 @@ void wl_adapter_insert( struct pcmcia_device *link ) cs_failed: - cs_error( link, last_fn, last_ret ); +// cs_error( link, last_fn, last_ret ); failed: -- cgit v1.2.3 From 8ff23777f02209b4c5405be292884990fac68604 Mon Sep 17 00:00:00 2001 From: Andres More Date: Sun, 9 May 2010 22:20:09 -0300 Subject: staging: vt6656: aes_ccmp.c: code cleanup, cleared checkpatch findings Resolved all warnings/errors but lines having over 80 characters. Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/aes_ccmp.c | 561 ++++++++++++++++++-------------------- 1 file changed, 272 insertions(+), 289 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/aes_ccmp.c b/drivers/staging/vt6656/aes_ccmp.c index a1beaa93b333..b3d367b9bdc6 100644 --- a/drivers/staging/vt6656/aes_ccmp.c +++ b/drivers/staging/vt6656/aes_ccmp.c @@ -16,7 +16,6 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * * File: aes_ccmp.c * * Purpose: AES_CCMP decryption @@ -28,9 +27,7 @@ * Functions: * AESbGenCCMP - Parsing RX-packet * - * * Revision History: - * */ #include "device.h" @@ -46,62 +43,61 @@ * SBOX Table */ -BYTE sbox_table[256] = -{ -0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, -0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, -0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, -0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, -0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, -0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, -0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, -0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, -0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, -0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, -0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, -0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, -0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, -0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, -0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, -0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 +BYTE sbox_table[256] = { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; BYTE dot2_table[256] = { -0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, -0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, -0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, -0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, -0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, -0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, -0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, -0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, -0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05, -0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25, -0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, -0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65, -0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85, -0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, -0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, -0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5 + 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, + 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, + 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, + 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, + 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, + 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, + 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, + 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, + 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05, + 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25, + 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, + 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65, + 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85, + 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, + 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, + 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5 }; BYTE dot3_table[256] = { -0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11, -0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, -0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, -0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41, -0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, -0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1, -0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1, -0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, -0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a, -0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba, -0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, -0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda, -0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a, -0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, -0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a, -0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a + 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11, + 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, + 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, + 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41, + 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, + 0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1, + 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1, + 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, + 0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a, + 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba, + 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, + 0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda, + 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a, + 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, + 0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a, + 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a }; /*--------------------- Static Functions --------------------------*/ @@ -112,120 +108,111 @@ BYTE dot3_table[256] = { void xor_128(BYTE *a, BYTE *b, BYTE *out) { -PDWORD dwPtrA = (PDWORD) a; -PDWORD dwPtrB = (PDWORD) b; -PDWORD dwPtrOut =(PDWORD) out; - - (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); - (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); - (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); - (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); + PDWORD dwPtrA = (PDWORD) a; + PDWORD dwPtrB = (PDWORD) b; + PDWORD dwPtrOut = (PDWORD) out; + + (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); + (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); + (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); + (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); } void xor_32(BYTE *a, BYTE *b, BYTE *out) { -PDWORD dwPtrA = (PDWORD) a; -PDWORD dwPtrB = (PDWORD) b; -PDWORD dwPtrOut =(PDWORD) out; + PDWORD dwPtrA = (PDWORD) a; + PDWORD dwPtrB = (PDWORD) b; + PDWORD dwPtrOut = (PDWORD) out; - (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); + (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); } void AddRoundKey(BYTE *key, int round) { -BYTE sbox_key[4]; -BYTE rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; + BYTE sbox_key[4]; + BYTE rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; - sbox_key[0] = sbox_table[key[13]]; - sbox_key[1] = sbox_table[key[14]]; - sbox_key[2] = sbox_table[key[15]]; - sbox_key[3] = sbox_table[key[12]]; + sbox_key[0] = sbox_table[key[13]]; + sbox_key[1] = sbox_table[key[14]]; + sbox_key[2] = sbox_table[key[15]]; + sbox_key[3] = sbox_table[key[12]]; - key[0] = key[0] ^ rcon_table[round]; - xor_32(&key[0], sbox_key, &key[0]); + key[0] = key[0] ^ rcon_table[round]; + xor_32(&key[0], sbox_key, &key[0]); - xor_32(&key[4], &key[0], &key[4]); - xor_32(&key[8], &key[4], &key[8]); - xor_32(&key[12], &key[8], &key[12]); + xor_32(&key[4], &key[0], &key[4]); + xor_32(&key[8], &key[4], &key[8]); + xor_32(&key[12], &key[8], &key[12]); } void SubBytes(BYTE *in, BYTE *out) { -int i; + int i; - for (i=0; i< 16; i++) - { - out[i] = sbox_table[in[i]]; - } + for (i = 0; i < 16; i++) + out[i] = sbox_table[in[i]]; } void ShiftRows(BYTE *in, BYTE *out) { - out[0] = in[0]; - out[1] = in[5]; - out[2] = in[10]; - out[3] = in[15]; - out[4] = in[4]; - out[5] = in[9]; - out[6] = in[14]; - out[7] = in[3]; - out[8] = in[8]; - out[9] = in[13]; - out[10] = in[2]; - out[11] = in[7]; - out[12] = in[12]; - out[13] = in[1]; - out[14] = in[6]; - out[15] = in[11]; + out[0] = in[0]; + out[1] = in[5]; + out[2] = in[10]; + out[3] = in[15]; + out[4] = in[4]; + out[5] = in[9]; + out[6] = in[14]; + out[7] = in[3]; + out[8] = in[8]; + out[9] = in[13]; + out[10] = in[2]; + out[11] = in[7]; + out[12] = in[12]; + out[13] = in[1]; + out[14] = in[6]; + out[15] = in[11]; } void MixColumns(BYTE *in, BYTE *out) { - out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3]; - out[1] = in[0] ^ dot2_table[in[1]] ^ dot3_table[in[2]] ^ in[3]; - out[2] = in[0] ^ in[1] ^ dot2_table[in[2]] ^ dot3_table[in[3]]; - out[3] = dot3_table[in[0]] ^ in[1] ^ in[2] ^ dot2_table[in[3]]; + out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3]; + out[1] = in[0] ^ dot2_table[in[1]] ^ dot3_table[in[2]] ^ in[3]; + out[2] = in[0] ^ in[1] ^ dot2_table[in[2]] ^ dot3_table[in[3]]; + out[3] = dot3_table[in[0]] ^ in[1] ^ in[2] ^ dot2_table[in[3]]; } - void AESv128(BYTE *key, BYTE *data, BYTE *ciphertext) { -int i; -int round; -BYTE TmpdataA[16]; -BYTE TmpdataB[16]; -BYTE abyRoundKey[16]; - - for(i=0; i<16; i++) - abyRoundKey[i] = key[i]; - - for (round = 0; round < 11; round++) - { - if (round == 0) - { - xor_128(abyRoundKey, data, ciphertext); - AddRoundKey(abyRoundKey, round); - } - else if (round == 10) - { - SubBytes(ciphertext, TmpdataA); - ShiftRows(TmpdataA, TmpdataB); - xor_128(TmpdataB, abyRoundKey, ciphertext); - } - else // round 1 ~ 9 - { - SubBytes(ciphertext, TmpdataA); - ShiftRows(TmpdataA, TmpdataB); - MixColumns(&TmpdataB[0], &TmpdataA[0]); - MixColumns(&TmpdataB[4], &TmpdataA[4]); - MixColumns(&TmpdataB[8], &TmpdataA[8]); - MixColumns(&TmpdataB[12], &TmpdataA[12]); - xor_128(TmpdataA, abyRoundKey, ciphertext); - AddRoundKey(abyRoundKey, round); - } - } + int i; + int round; + BYTE TmpdataA[16]; + BYTE TmpdataB[16]; + BYTE abyRoundKey[16]; + + for (i = 0; i < 16; i++) + abyRoundKey[i] = key[i]; + + for (round = 0; round < 11; round++) { + if (round == 0) { + xor_128(abyRoundKey, data, ciphertext); + AddRoundKey(abyRoundKey, round); + } else if (round == 10) { + SubBytes(ciphertext, TmpdataA); + ShiftRows(TmpdataA, TmpdataB); + xor_128(TmpdataB, abyRoundKey, ciphertext); + } else { /* round 1 ~ 9 */ + SubBytes(ciphertext, TmpdataA); + ShiftRows(TmpdataA, TmpdataB); + MixColumns(&TmpdataB[0], &TmpdataA[0]); + MixColumns(&TmpdataB[4], &TmpdataA[4]); + MixColumns(&TmpdataB[8], &TmpdataA[8]); + MixColumns(&TmpdataB[12], &TmpdataA[12]); + xor_128(TmpdataA, abyRoundKey, ciphertext); + AddRoundKey(abyRoundKey, round); + } + } } @@ -243,161 +230,157 @@ BYTE abyRoundKey[16]; * Return Value: MIC compare result * */ + BOOL AESbGenCCMP(PBYTE pbyRxKey, PBYTE pbyFrame, WORD wFrameSize) { -BYTE abyNonce[13]; -BYTE MIC_IV[16]; -BYTE MIC_HDR1[16]; -BYTE MIC_HDR2[16]; -BYTE abyMIC[16]; -BYTE abyCTRPLD[16]; -BYTE abyTmp[16]; -BYTE abyPlainText[16]; -BYTE abyLastCipher[16]; - -PS802_11Header pMACHeader = (PS802_11Header) pbyFrame; -PBYTE pbyIV; -PBYTE pbyPayload; -WORD wHLen = 22; -WORD wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN;//8 is IV, 8 is MIC, 4 is CRC -BOOL bA4 = FALSE; -BYTE byTmp; -WORD wCnt; -int ii,jj,kk; - - - pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; - if ( WLAN_GET_FC_TODS(*(PWORD)pbyFrame) && - WLAN_GET_FC_FROMDS(*(PWORD)pbyFrame) ) { - bA4 = TRUE; - pbyIV += 6; // 6 is 802.11 address4 - wHLen += 6; - wPayloadSize -= 6; - } - pbyPayload = pbyIV + 8; //IV-length - - abyNonce[0] = 0x00; //now is 0, if Qos here will be priority - memcpy(&(abyNonce[1]), pMACHeader->abyAddr2, ETH_ALEN); - abyNonce[7] = pbyIV[7]; - abyNonce[8] = pbyIV[6]; - abyNonce[9] = pbyIV[5]; - abyNonce[10] = pbyIV[4]; - abyNonce[11] = pbyIV[1]; - abyNonce[12] = pbyIV[0]; - - //MIC_IV - MIC_IV[0] = 0x59; - memcpy(&(MIC_IV[1]), &(abyNonce[0]), 13); - MIC_IV[14] = (BYTE)(wPayloadSize >> 8); - MIC_IV[15] = (BYTE)(wPayloadSize & 0xff); - - //MIC_HDR1 - MIC_HDR1[0] = (BYTE)(wHLen >> 8); - MIC_HDR1[1] = (BYTE)(wHLen & 0xff); - byTmp = (BYTE)(pMACHeader->wFrameCtl & 0xff); - MIC_HDR1[2] = byTmp & 0x8f; - byTmp = (BYTE)(pMACHeader->wFrameCtl >> 8); - byTmp &= 0x87; - MIC_HDR1[3] = byTmp | 0x40; - memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, ETH_ALEN); - memcpy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, ETH_ALEN); - - //MIC_HDR2 - memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, ETH_ALEN); - byTmp = (BYTE)(pMACHeader->wSeqCtl & 0xff); - MIC_HDR2[6] = byTmp & 0x0f; - MIC_HDR2[7] = 0; - - if ( bA4 ) { + BYTE abyNonce[13]; + BYTE MIC_IV[16]; + BYTE MIC_HDR1[16]; + BYTE MIC_HDR2[16]; + BYTE abyMIC[16]; + BYTE abyCTRPLD[16]; + BYTE abyTmp[16]; + BYTE abyPlainText[16]; + BYTE abyLastCipher[16]; + + PS802_11Header pMACHeader = (PS802_11Header) pbyFrame; + PBYTE pbyIV; + PBYTE pbyPayload; + WORD wHLen = 22; + /* 8 is IV, 8 is MIC, 4 is CRC */ + WORD wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN; + BOOL bA4 = FALSE; + BYTE byTmp; + WORD wCnt; + int ii, jj, kk; + + pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; + if (WLAN_GET_FC_TODS(*(PWORD) pbyFrame) && + WLAN_GET_FC_FROMDS(*(PWORD) pbyFrame)) { + bA4 = TRUE; + pbyIV += 6; /* 6 is 802.11 address4 */ + wHLen += 6; + wPayloadSize -= 6; + } + pbyPayload = pbyIV + 8; /* IV-length */ + + abyNonce[0] = 0x00; /* now is 0, if Qos here will be priority */ + memcpy(&(abyNonce[1]), pMACHeader->abyAddr2, ETH_ALEN); + abyNonce[7] = pbyIV[7]; + abyNonce[8] = pbyIV[6]; + abyNonce[9] = pbyIV[5]; + abyNonce[10] = pbyIV[4]; + abyNonce[11] = pbyIV[1]; + abyNonce[12] = pbyIV[0]; + + /* MIC_IV */ + MIC_IV[0] = 0x59; + memcpy(&(MIC_IV[1]), &(abyNonce[0]), 13); + MIC_IV[14] = (BYTE)(wPayloadSize >> 8); + MIC_IV[15] = (BYTE)(wPayloadSize & 0xff); + + /* MIC_HDR1 */ + MIC_HDR1[0] = (BYTE)(wHLen >> 8); + MIC_HDR1[1] = (BYTE)(wHLen & 0xff); + byTmp = (BYTE)(pMACHeader->wFrameCtl & 0xff); + MIC_HDR1[2] = byTmp & 0x8f; + byTmp = (BYTE)(pMACHeader->wFrameCtl >> 8); + byTmp &= 0x87; + MIC_HDR1[3] = byTmp | 0x40; + memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, ETH_ALEN); + memcpy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, ETH_ALEN); + + /* MIC_HDR2 */ + memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, ETH_ALEN); + byTmp = (BYTE)(pMACHeader->wSeqCtl & 0xff); + MIC_HDR2[6] = byTmp & 0x0f; + MIC_HDR2[7] = 0; + + if (bA4) { memcpy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, ETH_ALEN); - } else { - MIC_HDR2[8] = 0x00; - MIC_HDR2[9] = 0x00; - MIC_HDR2[10] = 0x00; - MIC_HDR2[11] = 0x00; - MIC_HDR2[12] = 0x00; - MIC_HDR2[13] = 0x00; - } - MIC_HDR2[14] = 0x00; - MIC_HDR2[15] = 0x00; - - //CCMP - AESv128(pbyRxKey,MIC_IV,abyMIC); - for ( kk=0; kk<16; kk++ ) { - abyTmp[kk] = MIC_HDR1[kk] ^ abyMIC[kk]; - } - AESv128(pbyRxKey,abyTmp,abyMIC); - for ( kk=0; kk<16; kk++ ) { - abyTmp[kk] = MIC_HDR2[kk] ^ abyMIC[kk]; - } - AESv128(pbyRxKey,abyTmp,abyMIC); - - wCnt = 1; - abyCTRPLD[0] = 0x01; - memcpy(&(abyCTRPLD[1]), &(abyNonce[0]), 13); - - for(jj=wPayloadSize; jj>16; jj=jj-16) { - - abyCTRPLD[14] = (BYTE) (wCnt >> 8); - abyCTRPLD[15] = (BYTE) (wCnt & 0xff); - - AESv128(pbyRxKey,abyCTRPLD,abyTmp); - - for ( kk=0; kk<16; kk++ ) { - abyPlainText[kk] = abyTmp[kk] ^ pbyPayload[kk]; - } - for ( kk=0; kk<16; kk++ ) { - abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk]; - } - AESv128(pbyRxKey,abyTmp,abyMIC); - - memcpy(pbyPayload, abyPlainText, 16); - wCnt++; - pbyPayload += 16; - } //for wPayloadSize - - //last payload - memcpy(&(abyLastCipher[0]), pbyPayload, jj); - for ( ii=jj; ii<16; ii++ ) { - abyLastCipher[ii] = 0x00; - } - - abyCTRPLD[14] = (BYTE) (wCnt >> 8); - abyCTRPLD[15] = (BYTE) (wCnt & 0xff); - - AESv128(pbyRxKey,abyCTRPLD,abyTmp); - for ( kk=0; kk<16; kk++ ) { - abyPlainText[kk] = abyTmp[kk] ^ abyLastCipher[kk]; - } - memcpy(pbyPayload, abyPlainText, jj); - pbyPayload += jj; - - //for MIC calculation - for ( ii=jj; ii<16; ii++ ) { - abyPlainText[ii] = 0x00; - } - for ( kk=0; kk<16; kk++ ) { - abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk]; - } - AESv128(pbyRxKey,abyTmp,abyMIC); - - //=>above is the calculate MIC - //-------------------------------------------- - - wCnt = 0; - abyCTRPLD[14] = (BYTE) (wCnt >> 8); - abyCTRPLD[15] = (BYTE) (wCnt & 0xff); - AESv128(pbyRxKey,abyCTRPLD,abyTmp); - for ( kk=0; kk<8; kk++ ) { - abyTmp[kk] = abyTmp[kk] ^ pbyPayload[kk]; - } - //=>above is the dec-MIC from packet - //-------------------------------------------- - - if ( !memcmp(abyMIC,abyTmp,8) ) { - return TRUE; - } else { - return FALSE; - } + } else { + MIC_HDR2[8] = 0x00; + MIC_HDR2[9] = 0x00; + MIC_HDR2[10] = 0x00; + MIC_HDR2[11] = 0x00; + MIC_HDR2[12] = 0x00; + MIC_HDR2[13] = 0x00; + } + MIC_HDR2[14] = 0x00; + MIC_HDR2[15] = 0x00; + + /* CCMP */ + AESv128(pbyRxKey, MIC_IV, abyMIC); + for (kk = 0; kk < 16; kk++) + abyTmp[kk] = MIC_HDR1[kk] ^ abyMIC[kk]; + + AESv128(pbyRxKey, abyTmp, abyMIC); + for (kk = 0; kk < 16; kk++) + abyTmp[kk] = MIC_HDR2[kk] ^ abyMIC[kk]; + + AESv128(pbyRxKey, abyTmp, abyMIC); + + wCnt = 1; + abyCTRPLD[0] = 0x01; + memcpy(&(abyCTRPLD[1]), &(abyNonce[0]), 13); + + for (jj = wPayloadSize; jj > 16; jj = jj-16) { + + abyCTRPLD[14] = (BYTE) (wCnt >> 8); + abyCTRPLD[15] = (BYTE) (wCnt & 0xff); + + AESv128(pbyRxKey, abyCTRPLD, abyTmp); + + for (kk = 0; kk < 16; kk++) + abyPlainText[kk] = abyTmp[kk] ^ pbyPayload[kk]; + + for (kk = 0; kk < 16; kk++) + abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk]; + + AESv128(pbyRxKey, abyTmp, abyMIC); + + memcpy(pbyPayload, abyPlainText, 16); + wCnt++; + pbyPayload += 16; + } /* for wPayloadSize */ + + /* last payload */ + memcpy(&(abyLastCipher[0]), pbyPayload, jj); + for (ii = jj; ii < 16; ii++) + abyLastCipher[ii] = 0x00; + + abyCTRPLD[14] = (BYTE) (wCnt >> 8); + abyCTRPLD[15] = (BYTE) (wCnt & 0xff); + + AESv128(pbyRxKey, abyCTRPLD, abyTmp); + for (kk = 0; kk < 16; kk++) + abyPlainText[kk] = abyTmp[kk] ^ abyLastCipher[kk]; + + memcpy(pbyPayload, abyPlainText, jj); + pbyPayload += jj; + + /* for MIC calculation */ + for (ii = jj; ii < 16; ii++) + abyPlainText[ii] = 0x00; + for (kk = 0; kk < 16; kk++) + abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk]; + + AESv128(pbyRxKey, abyTmp, abyMIC); + + /* => above is the calculated MIC */ + + wCnt = 0; + abyCTRPLD[14] = (BYTE) (wCnt >> 8); + abyCTRPLD[15] = (BYTE) (wCnt & 0xff); + AESv128(pbyRxKey, abyCTRPLD, abyTmp); + + for (kk = 0; kk < 8; kk++) + abyTmp[kk] = abyTmp[kk] ^ pbyPayload[kk]; + + /* => above is the packet dec-MIC */ + if (!memcmp(abyMIC, abyTmp, 8)) + return TRUE; + else + return FALSE; } -- cgit v1.2.3 From f65515275ea3e45fdcd0fb78455f542d6fdca086 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sun, 9 May 2010 22:10:02 -0500 Subject: staging: vt6655: Fix kernel BUG on driver wpa initialization In http://bugzilla.novell.com/show_bug.cgi?id=597299, the vt6655 driver generates a kernel BUG on a NULL pointer dereference at NULL. This problem has been traced to a failure in the wpa_set_wpadev() routine. As the vt6656 driver does not call this routine, the vt6655 code is similarly set to skip the call. Signed-off-by: Larry Finger Tested-by: Richard Meek Cc: Stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 8a63a031d00b..7020ed41e0ca 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -1091,11 +1091,13 @@ device_found1(struct pci_dev *pcid, const struct pci_device_id *ent) } //2008-07-21-01by MikeLiu //register wpadev +#if 0 if(wpa_set_wpadev(pDevice, 1)!=0) { printk("Fail to Register WPADEV?\n"); unregister_netdev(pDevice->dev); free_netdev(dev); } +#endif device_print_info(pDevice); pci_set_drvdata(pcid, pDevice); return 0; -- cgit v1.2.3 From a9560a72759c6208c4072a30fb45aac7c6c014d4 Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 10 May 2010 17:56:05 +0800 Subject: Staging: comedi: Fixed long line lengths in comedi.h This patch fixes quite a few long line lengths in comedi.h as reported by checkpatch.pl Signed-off-by: Mark Rankilor Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi.h | 62 ++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index 20a6fee4dae6..1538146b37a3 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -156,15 +156,15 @@ #define TRIG_ANY 0xffffffff #define TRIG_INVALID 0x00000000 -#define TRIG_NONE 0x00000001 /* never trigger */ -#define TRIG_NOW 0x00000002 /* trigger now + N ns */ -#define TRIG_FOLLOW 0x00000004 /* trigger on next lower level trig */ -#define TRIG_TIME 0x00000008 /* trigger at time N ns */ -#define TRIG_TIMER 0x00000010 /* trigger at rate N ns */ -#define TRIG_COUNT 0x00000020 /* trigger when count reaches N */ -#define TRIG_EXT 0x00000040 /* trigger on external signal N */ -#define TRIG_INT 0x00000080 /* trigger on comedi-internal signal N */ -#define TRIG_OTHER 0x00000100 /* driver defined */ +#define TRIG_NONE 0x00000001 /* never trigger */ +#define TRIG_NOW 0x00000002 /* trigger now + N ns */ +#define TRIG_FOLLOW 0x00000004 /* trigger on next lower level trig */ +#define TRIG_TIME 0x00000008 /* trigger at time N ns */ +#define TRIG_TIMER 0x00000010 /* trigger at rate N ns */ +#define TRIG_COUNT 0x00000020 /* trigger when count reaches N */ +#define TRIG_EXT 0x00000040 /* trigger on external signal N */ +#define TRIG_INT 0x00000080 /* trigger on comedi-internal signal N */ +#define TRIG_OTHER 0x00000100 /* driver defined */ /* subdevice flags */ @@ -181,14 +181,17 @@ #define SDF_MODE3 0x0400 /* can do mode 3 */ #define SDF_MODE4 0x0800 /* can do mode 4 */ #define SDF_CMD 0x1000 /* can do commands (deprecated) */ -#define SDF_SOFT_CALIBRATED 0x2000 /* subdevice uses software calibration */ -#define SDF_CMD_WRITE 0x4000 /* can do output commands */ -#define SDF_CMD_READ 0x8000 /* can do input commands */ - -#define SDF_READABLE 0x00010000 /* subdevice can be read (e.g. analog input) */ -#define SDF_WRITABLE 0x00020000 /* subdevice can be written (e.g. analog output) */ +#define SDF_SOFT_CALIBRATED 0x2000 /* subdevice uses software calibration */ +#define SDF_CMD_WRITE 0x4000 /* can do output commands */ +#define SDF_CMD_READ 0x8000 /* can do input commands */ + +/* subdevice can be read (e.g. analog input) */ +#define SDF_READABLE 0x00010000 +/* subdevice can be written (e.g. analog output) */ +#define SDF_WRITABLE 0x00020000 #define SDF_WRITEABLE SDF_WRITABLE /* spelling error in API */ -#define SDF_INTERNAL 0x00040000 /* subdevice does not have externally visible lines */ +/* subdevice does not have externally visible lines */ +#define SDF_INTERNAL 0x00040000 #define SDF_GROUND 0x00100000 /* can do aref=ground */ #define SDF_COMMON 0x00200000 /* can do aref=common */ #define SDF_DIFF 0x00400000 /* can do aref=diff */ @@ -255,15 +258,14 @@ INSN_CONFIG_GPCT_QUADRATURE_ENCODER = 1003, INSN_CONFIG_SET_GATE_SRC = 2001, /* Set gate source */ INSN_CONFIG_GET_GATE_SRC = 2002, /* Get gate source */ - INSN_CONFIG_SET_CLOCK_SRC = 2003, /* Set master clock source */ - INSN_CONFIG_GET_CLOCK_SRC = 2004, /* Get master clock source */ - INSN_CONFIG_SET_OTHER_SRC = 2005, /* Set other source */ + /* Set master clock source */ + INSN_CONFIG_SET_CLOCK_SRC = 2003, + INSN_CONFIG_GET_CLOCK_SRC = 2004, /* Get master clock source */ + INSN_CONFIG_SET_OTHER_SRC = 2005, /* Set other source */ /* INSN_CONFIG_GET_OTHER_SRC = 2006,*//* Get other source */ - INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE = 2006, /* Get size in bytes of - subdevice's on-board - fifos used during - streaming - input/output */ + /* Get size in bytes of subdevice's on-board fifos used during + * streaming input/output */ + INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE = 2006, INSN_CONFIG_SET_COUNTER_MODE = 4097, INSN_CONFIG_8254_SET_MODE = INSN_CONFIG_SET_COUNTER_MODE, /* deprecated */ INSN_CONFIG_8254_READ_STATUS = 4098, @@ -273,8 +275,11 @@ INSN_CONFIG_PWM_SET_PERIOD = 5000, /* sets frequency */ INSN_CONFIG_PWM_GET_PERIOD = 5001, /* gets frequency */ INSN_CONFIG_GET_PWM_STATUS = 5002, /* is it running? */ - INSN_CONFIG_PWM_SET_H_BRIDGE = 5003, /* sets H bridge: duty cycle and sign bit for a relay at the same time */ - INSN_CONFIG_PWM_GET_H_BRIDGE = 5004 /* gets H bridge data: duty cycle and the sign bit */ + /* sets H bridge: duty cycle and sign bit for a relay at the + * same time */ + INSN_CONFIG_PWM_SET_H_BRIDGE = 5003, + /* gets H bridge data: duty cycle and the sign bit */ + INSN_CONFIG_PWM_GET_H_BRIDGE = 5004 }; enum comedi_io_direction { @@ -362,7 +367,7 @@ unsigned int __user *chanlist; /* channel/range list */ unsigned int chanlist_len; - short __user *data; /* data list, size depends on subd flags */ + short __user *data; /* data list, size depends on subd flags */ unsigned int data_len; }; @@ -395,7 +400,8 @@ unsigned int flags; /* channel flags */ unsigned int range_type; /* lookup in kernel */ unsigned int settling_time_0; - unsigned insn_bits_support; /* see support_level enum for values */ + /* see support_level enum for values */ + unsigned insn_bits_support; unsigned int unused[8]; }; -- cgit v1.2.3 From 801de52358abc9f42ee6291dae2425bca04228d6 Mon Sep 17 00:00:00 2001 From: "Prashant P. Shah" Date: Mon, 10 May 2010 22:18:24 +0530 Subject: Staging: wlags49_h2: fixed C99 comments style issues in wl_profile.c This is a patch to the wl_profile.c file that fixes the C99 comments style issues found by the checkpatch.pl tool. Signed-off-by: Prashant P. Shah Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/wl_profile.c | 54 ++++++++++++++++----------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlags49_h2/wl_profile.c b/drivers/staging/wlags49_h2/wl_profile.c index 13ade7035731..292d5792dd75 100644 --- a/drivers/staging/wlags49_h2/wl_profile.c +++ b/drivers/staging/wlags49_h2/wl_profile.c @@ -91,7 +91,7 @@ #include #include -//#include +/* #include */ #include #include @@ -118,17 +118,17 @@ int parse_yes_no(char *value); int parse_yes_no(char *value) { -int rc = 0; //default to NO for invalid parameters +int rc = 0; /* default to NO for invalid parameters */ if (strlen(value) == 1) { if ((value[0] | ('Y'^'y')) == 'y') rc = 1; -// } else { -// this should not be debug time info, it is an enduser data entry error ;? -// DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MICROWAVE_ROBUSTNESS); + /* } else { */ + /* this should not be debug time info, it is an enduser data entry error ;? */ + /* DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MICROWAVE_ROBUSTNESS); */ } return rc; -} // parse_yes_no +} /* parse_yes_no */ /******************************************************************************* @@ -154,10 +154,10 @@ int rc = 0; //default to NO for invalid parameters void parse_config(struct net_device *dev) { int file_desc; -#if 0 // BIN_DL +#if 0 /* BIN_DL */ int rc; char *cp = NULL; -#endif // BIN_DL +#endif /* BIN_DL */ char buffer[MAX_LINE_SIZE]; char filename[MAX_LINE_SIZE]; mm_segment_t fs; @@ -192,7 +192,7 @@ void parse_config(struct net_device *dev) while (readline(file_desc, buffer)) translate_option(buffer, wvlan_config); /* Close the file */ - close(file_desc); //;?even if file_desc == -1 ??? + close(file_desc); /* ;?even if file_desc == -1 ??? */ } else { DBG_TRACE(DbgInfo, "No iwconfig file found for this device; " "config.opts or wireless.opts will be used\n"); @@ -235,19 +235,19 @@ void parse_config(struct net_device *dev) memcpy(&wvlan_config->DefaultKeys, &sEncryption.EncStr, sizeof(CFG_DEFAULT_KEYS_STRCT)); -#if 0 //BIN_DL +#if 0 /* BIN_DL */ /* Obtain a user-space process context, storing the original context */ fs = get_fs(); set_fs(get_ds()); - //;?just to fake something + /* ;?just to fake something */ strcpy(/*wvlan_config->fw_image_*/filename, "/etc/agere/fw.bin"); file_desc = open(/*wvlan_config->fw_image_*/filename, 0, 0); if (file_desc == -1) { DBG_ERROR(DbgInfo, "No image file found\n"); } else { DBG_TRACE(DbgInfo, "F/W image file found\n"); -#define DHF_ALLOC_SIZE 96000 //just below 96K, let's hope it suffices for now and for the future +#define DHF_ALLOC_SIZE 96000 /* just below 96K, let's hope it suffices for now and for the future */ cp = (char *)vmalloc(DHF_ALLOC_SIZE); if (cp == NULL) { DBG_ERROR(DbgInfo, "error in vmalloc\n"); @@ -270,11 +270,11 @@ void parse_config(struct net_device *dev) close(file_desc); } set_fs(fs); /* Return to the original context */ -#endif // BIN_DL +#endif /* BIN_DL */ DBG_LEAVE(DbgInfo); return; -} // parse_config +} /* parse_config */ /******************************************************************************* * readline() @@ -322,7 +322,7 @@ int readline(int filedesc, char *buffer) return result; else return bytes_read; -} // readline +} /* readline */ /*============================================================================*/ /******************************************************************************* @@ -381,9 +381,9 @@ void translate_option(char *buffer, struct wl_private *lp) DbgInfo->DebugFlag |= DBG_DEFAULTS; } } else { - DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); //;?DebugFlag; + DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); /* ;?DebugFlag; */ } - DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); //;?Delete ASAP + DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); /* ;?Delete ASAP */ } #endif /* DBG */ if (strcmp(key, PARM_NAME_AUTH_KEY_MGMT_SUITE) == 0) { @@ -602,10 +602,10 @@ void translate_option(char *buffer, struct wl_private *lp) /* Need to add? : Country code, Short/Long retry */ /* Configuration parameters specific to STA mode */ -#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA -//;?seems reasonable that even an AP-only driver could afford this small additional footprint +#if 1 /* ;? (HCF_TYPE) & HCF_TYPE_STA */ +/* ;?seems reasonable that even an AP-only driver could afford this small additional footprint */ if (CNV_INT_TO_LITTLE(lp->hcfCtx.IFB_FWIdentity.comp_id) == COMP_ID_FW_STA) { - //;?should we return an error status in AP mode + /* ;?should we return an error status in AP mode */ if (strcmp(key, PARM_NAME_PORT_TYPE) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PORT_TYPE, value); @@ -625,7 +625,7 @@ void translate_option(char *buffer, struct wl_private *lp) lp->PMEnabled = value_convert; } else { DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PM_ENABLED); - //;?this is a data entry error, hence not a DBG_WARNING + /* ;?this is a data entry error, hence not a DBG_WARNING */ } } else if (strcmp(key, PARM_NAME_CREATE_IBSS) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_CREATE_IBSS, value); @@ -690,8 +690,8 @@ void translate_option(char *buffer, struct wl_private *lp) #endif /* (HCF_TYPE) & HCF_TYPE_STA */ /* Configuration parameters specific to AP mode */ -#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP - //;?should we restore this to allow smaller memory footprint +#if 1 /* ;? (HCF_TYPE) & HCF_TYPE_AP */ + /* ;?should we restore this to allow smaller memory footprint */ if (CNV_INT_TO_LITTLE(lp->hcfCtx.IFB_FWIdentity.comp_id) == COMP_ID_FW_AP) { if (strcmp(key, PARM_NAME_OWN_DTIM_PERIOD) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_DTIM_PERIOD, value); @@ -876,7 +876,7 @@ void translate_option(char *buffer, struct wl_private *lp) #endif /* (HCF_TYPE) & HCF_TYPE_AP */ return; -} // translate_option +} /* translate_option */ /*============================================================================*/ /******************************************************************************* @@ -932,7 +932,7 @@ int parse_mac_address(char *value, u_char *byte_array) /* Use the array_offset as a check; 6 bytes should be written to the byte_array */ return array_offset; -} // parse_mac_address +} /* parse_mac_address */ /*============================================================================*/ /******************************************************************************* @@ -1006,7 +1006,7 @@ void ParseConfigLine(char *pszLine, char **ppszLVal, char **ppszRVal) } } DBG_LEAVE(DbgInfo); -} // ParseConfigLine +} /* ParseConfigLine */ /*============================================================================*/ -#endif // USE_PROFILE +#endif /* USE_PROFILE */ -- cgit v1.2.3 From 3041f30672b50a482154f554c82404e98eb41133 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 10 May 2010 10:53:04 -0700 Subject: staging: memrar depends on RAR_REGISTER Alan said that memrar should depend on RAR_REGISTER (instead of selecting it). Signed-off-by: Randy Dunlap Cc: Ossama Othman Cc: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/memrar/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/memrar/Kconfig b/drivers/staging/memrar/Kconfig index a5598a86f668..cbeebc550904 100644 --- a/drivers/staging/memrar/Kconfig +++ b/drivers/staging/memrar/Kconfig @@ -1,6 +1,6 @@ config MRST_RAR_HANDLER tristate "RAR handler driver for Intel Moorestown platform" - select RAR_REGISTER + depends on RAR_REGISTER ---help--- This driver provides a memory management interface to restricted access regions (RAR) available on the Intel -- cgit v1.2.3 From a05d08c40c0775e4691cffcfbfceeb4270987208 Mon Sep 17 00:00:00 2001 From: Zachary Richey Date: Tue, 11 May 2010 14:16:41 -0400 Subject: Staging: wlan-ng: Fixed non static functions in prism2fw.c Fixed non static functions in prism2fw.c Signed-off-by: Zachary Richey Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/prism2fw.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index d383ea85c9bc..fc2d8f40edd4 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -160,21 +160,30 @@ hfa384x_caplevel_t priid; /*================================================================*/ /* Local Function Declarations */ -int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev); -int read_fwfile(const struct ihex_binrec *rfptr); -int mkimage(imgchunk_t *clist, unsigned int *ccnt); -int read_cardpda(pda_t *pda, wlandevice_t *wlandev); -int mkpdrlist(pda_t *pda); -int plugimage(imgchunk_t *fchunk, unsigned int nfchunks, +static int prism2_fwapply(const struct ihex_binrec *rfptr, +wlandevice_t *wlandev); + +static int read_fwfile(const struct ihex_binrec *rfptr); + +static int mkimage(imgchunk_t *clist, unsigned int *ccnt); + +static int read_cardpda(pda_t *pda, wlandevice_t *wlandev); + +static int mkpdrlist(pda_t *pda); + +static int plugimage(imgchunk_t *fchunk, unsigned int nfchunks, s3plugrec_t *s3plug, unsigned int ns3plug, pda_t * pda); -int crcimage(imgchunk_t *fchunk, unsigned int nfchunks, + +static int crcimage(imgchunk_t *fchunk, unsigned int nfchunks, s3crcrec_t *s3crc, unsigned int ns3crc); -int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk, + +static int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk, unsigned int nfchunks); -void free_chunks(imgchunk_t *fchunk, unsigned int *nfchunks); -void free_srecs(void); +static void free_chunks(imgchunk_t *fchunk, unsigned int *nfchunks); + +static void free_srecs(void); -int validate_identity(void); +static int validate_identity(void); /*================================================================*/ /* Function Definitions */ @@ -255,7 +264,7 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev) /* clear the pda and add an initial END record */ memset(&pda, 0, sizeof(pda)); pda.rec[0] = (hfa384x_pdrec_t *) pda.buf; - pda.rec[0]->len = cpu_to_le16(2); /* len in words *//* len in words */ + pda.rec[0]->len = cpu_to_le16(2); /* len in words */ pda.rec[0]->code = cpu_to_le16(HFA384x_PDR_END_OF_PDA); pda.nrec = 1; -- cgit v1.2.3 From 324148788bf3744d90fb6894ec5744eb0ca91b74 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 11 May 2010 20:26:57 +0200 Subject: Staging: Drop memory allocation cast Drop cast on the result of kmalloc and similar functions. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ type T; @@ - (T *) (\(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\| kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...)) // Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/unioxx5.c | 2 +- drivers/staging/crystalhd/crystalhd_misc.c | 2 +- drivers/staging/cx25821/cx25821-audio-upstream.c | 6 ++---- drivers/staging/cx25821/cx25821-video-upstream-ch2.c | 6 ++---- drivers/staging/cx25821/cx25821-video-upstream.c | 4 ++-- drivers/staging/et131x/et1310_rx.c | 2 +- drivers/staging/et131x/et1310_tx.c | 2 +- drivers/staging/rt2860/common/cmm_data.c | 2 +- drivers/staging/rt2860/common/cmm_mac_pci.c | 2 +- drivers/staging/rt2860/common/cmm_mac_usb.c | 2 +- drivers/staging/rt2860/rt_linux.c | 2 +- drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c | 7 +++---- drivers/staging/rtl8192e/ieee80211/ieee80211_module.c | 2 +- drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c | 2 +- drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c | 7 +++---- drivers/staging/rtl8192e/r8192E_core.c | 2 +- drivers/staging/rtl8192su/ieee80211/ieee80211_module.c | 2 +- drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c | 2 +- drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c | 7 +++---- drivers/staging/rtl8192su/r8192U_core.c | 2 +- drivers/staging/rtl8192u/ieee80211/ieee80211_module.c | 2 +- drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c | 2 +- drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c | 7 +++---- drivers/staging/rtl8192u/r8192U_core.c | 10 ++++++---- drivers/staging/vme/bridges/vme_ca91cx42.c | 3 +-- drivers/staging/vme/bridges/vme_tsi148.c | 2 +- drivers/staging/vt6655/device_main.c | 2 +- drivers/staging/vt6655/hostap.c | 4 ++-- drivers/staging/vt6655/wpactl.c | 2 +- drivers/staging/vt6656/hostap.c | 4 ++-- drivers/staging/vt6656/main_usb.c | 2 +- drivers/staging/vt6656/wpactl.c | 2 +- drivers/staging/wlags49_h2/wl_priv.c | 4 ++-- 33 files changed, 52 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c index be1d83df0de5..16d4c9f69165 100644 --- a/drivers/staging/comedi/drivers/unioxx5.c +++ b/drivers/staging/comedi/drivers/unioxx5.c @@ -285,7 +285,7 @@ static int __unioxx5_subdev_init(struct comedi_subdevice *subdev, return -EIO; } - usp = (struct unioxx5_subd_priv *)kzalloc(sizeof(*usp), GFP_KERNEL); + usp = kzalloc(sizeof(*usp), GFP_KERNEL); if (usp == NULL) { printk(KERN_ERR "comedi%d: erorr! --> out of memory!\n", minor); diff --git a/drivers/staging/crystalhd/crystalhd_misc.c b/drivers/staging/crystalhd/crystalhd_misc.c index d1346672531f..548dc09f2493 100644 --- a/drivers/staging/crystalhd/crystalhd_misc.c +++ b/drivers/staging/crystalhd/crystalhd_misc.c @@ -887,7 +887,7 @@ int crystalhd_create_dio_pool(struct crystalhd_adp *adp, uint32_t max_pages) BC_LINK_SG_POOL_SZ, max_pages, asz, adp->fill_byte_pool); for (i = 0; i < BC_LINK_SG_POOL_SZ; i++) { - temp = (uint8_t *)kzalloc(asz, GFP_KERNEL); + temp = kzalloc(asz, GFP_KERNEL); if ((temp) == NULL) { BCMLOG_ERR("Failed to alloc %d mem\n", asz); return -ENOMEM; diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.c b/drivers/staging/cx25821/cx25821-audio-upstream.c index 11c56bdb0ceb..4c7d21e3d54d 100644 --- a/drivers/staging/cx25821/cx25821-audio-upstream.c +++ b/drivers/staging/cx25821/cx25821-audio-upstream.c @@ -751,8 +751,7 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select) if (dev->input_audiofilename) { str_length = strlen(dev->input_audiofilename); - dev->_audiofilename = - (char *)kmalloc(str_length + 1, GFP_KERNEL); + dev->_audiofilename = kmalloc(str_length + 1, GFP_KERNEL); if (!dev->_audiofilename) goto error; @@ -766,8 +765,7 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select) } } else { str_length = strlen(_defaultAudioName); - dev->_audiofilename = - (char *)kmalloc(str_length + 1, GFP_KERNEL); + dev->_audiofilename = kmalloc(str_length + 1, GFP_KERNEL); if (!dev->_audiofilename) goto error; diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c index cc51618cffa9..343df6619fe8 100644 --- a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c +++ b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c @@ -769,8 +769,7 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select, if (dev->input_filename_ch2) { str_length = strlen(dev->input_filename_ch2); - dev->_filename_ch2 = - (char *)kmalloc(str_length + 1, GFP_KERNEL); + dev->_filename_ch2 = kmalloc(str_length + 1, GFP_KERNEL); if (!dev->_filename_ch2) goto error; @@ -779,8 +778,7 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select, str_length + 1); } else { str_length = strlen(dev->_defaultname_ch2); - dev->_filename_ch2 = - (char *)kmalloc(str_length + 1, GFP_KERNEL); + dev->_filename_ch2 = kmalloc(str_length + 1, GFP_KERNEL); if (!dev->_filename_ch2) goto error; diff --git a/drivers/staging/cx25821/cx25821-video-upstream.c b/drivers/staging/cx25821/cx25821-video-upstream.c index 6d48a1e26d1b..fdd94cf6d0be 100644 --- a/drivers/staging/cx25821/cx25821-video-upstream.c +++ b/drivers/staging/cx25821/cx25821-video-upstream.c @@ -825,7 +825,7 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select, if (dev->input_filename) { str_length = strlen(dev->input_filename); - dev->_filename = (char *)kmalloc(str_length + 1, GFP_KERNEL); + dev->_filename = kmalloc(str_length + 1, GFP_KERNEL); if (!dev->_filename) goto error; @@ -833,7 +833,7 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select, memcpy(dev->_filename, dev->input_filename, str_length + 1); } else { str_length = strlen(dev->_defaultname); - dev->_filename = (char *)kmalloc(str_length + 1, GFP_KERNEL); + dev->_filename = kmalloc(str_length + 1, GFP_KERNEL); if (!dev->_filename) goto error; diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c index 8f5dcebda76a..8e04bdd8f6b6 100644 --- a/drivers/staging/et131x/et1310_rx.c +++ b/drivers/staging/et131x/et1310_rx.c @@ -547,7 +547,7 @@ int et131x_init_recv(struct et131x_adapter *adapter) /* Setup each RFD */ for (rfdct = 0; rfdct < rx_ring->NumRfd; rfdct++) { - rfd = (MP_RFD *) kmem_cache_alloc(rx_ring->RecvLookaside, + rfd = kmem_cache_alloc(rx_ring->RecvLookaside, GFP_ATOMIC | GFP_DMA); if (!rfd) { diff --git a/drivers/staging/et131x/et1310_tx.c b/drivers/staging/et131x/et1310_tx.c index b6ff20f47de4..0f3473d758e4 100644 --- a/drivers/staging/et131x/et1310_tx.c +++ b/drivers/staging/et131x/et1310_tx.c @@ -112,7 +112,7 @@ int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter) struct tx_ring *tx_ring = &adapter->tx_ring; /* Allocate memory for the TCB's (Transmit Control Block) */ - adapter->tx_ring.tcb_ring = (struct tcb *) + adapter->tx_ring.tcb_ring = kcalloc(NUM_TCB, sizeof(struct tcb), GFP_ATOMIC | GFP_DMA); if (!adapter->tx_ring.tcb_ring) { dev_err(&adapter->pdev->dev, "Cannot alloc memory for TCBs\n"); diff --git a/drivers/staging/rt2860/common/cmm_data.c b/drivers/staging/rt2860/common/cmm_data.c index 65b00e685eb2..93a53479d766 100644 --- a/drivers/staging/rt2860/common/cmm_data.c +++ b/drivers/staging/rt2860/common/cmm_data.c @@ -1424,7 +1424,7 @@ u32 deaggregate_AMSDU_announce(struct rt_rtmp_adapter *pAd, if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E)) { /* avoid local heap overflow, use dyanamic allocation */ struct rt_mlme_queue_elem *Elem = - (struct rt_mlme_queue_elem *)kmalloc(sizeof(struct rt_mlme_queue_elem), + kmalloc(sizeof(struct rt_mlme_queue_elem), MEM_ALLOC_FLAG); if (Elem != NULL) { memmove(Elem->Msg + diff --git a/drivers/staging/rt2860/common/cmm_mac_pci.c b/drivers/staging/rt2860/common/cmm_mac_pci.c index 560ebd398e1d..e26ba4942877 100644 --- a/drivers/staging/rt2860/common/cmm_mac_pci.c +++ b/drivers/staging/rt2860/common/cmm_mac_pci.c @@ -1558,7 +1558,7 @@ void RT28xxPciMlmeRadioOFF(struct rt_rtmp_adapter *pAd) if (INFRA_ON(pAd) || ADHOC_ON(pAd)) { struct rt_mlme_disassoc_req DisReq; struct rt_mlme_queue_elem *pMsgElem = - (struct rt_mlme_queue_elem *)kmalloc(sizeof(struct rt_mlme_queue_elem), + kmalloc(sizeof(struct rt_mlme_queue_elem), MEM_ALLOC_FLAG); if (pMsgElem) { diff --git a/drivers/staging/rt2860/common/cmm_mac_usb.c b/drivers/staging/rt2860/common/cmm_mac_usb.c index 9dd6959cd5a5..8aec70fc20d6 100644 --- a/drivers/staging/rt2860/common/cmm_mac_usb.c +++ b/drivers/staging/rt2860/common/cmm_mac_usb.c @@ -1087,7 +1087,7 @@ void RT28xxUsbMlmeRadioOFF(struct rt_rtmp_adapter *pAd) if (INFRA_ON(pAd) || ADHOC_ON(pAd)) { struct rt_mlme_disassoc_req DisReq; struct rt_mlme_queue_elem *pMsgElem = - (struct rt_mlme_queue_elem *)kmalloc(sizeof(struct rt_mlme_queue_elem), + kmalloc(sizeof(struct rt_mlme_queue_elem), MEM_ALLOC_FLAG); if (pMsgElem) { diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c index 27b78102f4bd..0029b2d73b70 100644 --- a/drivers/staging/rt2860/rt_linux.c +++ b/drivers/staging/rt2860/rt_linux.c @@ -154,7 +154,7 @@ void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time) /* pAd MUST allow to be NULL */ int os_alloc_mem(struct rt_rtmp_adapter *pAd, u8 ** mem, unsigned long size) { - *mem = (u8 *)kmalloc(size, GFP_ATOMIC); + *mem = kmalloc(size, GFP_ATOMIC); if (*mem) return NDIS_STATUS_SUCCESS; else diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index e099a5fa0494..b7426fea5498 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c @@ -1435,7 +1435,7 @@ static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen) if(*(t++) == MFIE_TYPE_CHALLENGE){ *chlen = *(t++); - *challenge = (u8*)kmalloc(*chlen, GFP_ATOMIC); + *challenge = kmalloc(*chlen, GFP_ATOMIC); memcpy(*challenge, t, *chlen); } } @@ -2861,8 +2861,7 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, ieee80211_crypt_delayed_deinit(ieee, crypt); - new_crypt = (struct ieee80211_crypt_data *) - kmalloc(sizeof(*new_crypt), GFP_KERNEL); + new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL); if (new_crypt == NULL) { ret = -ENOMEM; goto done; @@ -2953,7 +2952,7 @@ int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_poin goto out; } - param = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL); + param = kmalloc(p->length, GFP_KERNEL); if (param == NULL){ ret = -ENOMEM; goto out; diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c index f43a7db5c78b..c7aa1c63cb19 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c @@ -170,7 +170,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv) ieee80211_softmac_init(ieee); #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) - ieee->pHTInfo = (RT_HIGH_THROUGHPUT*)kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL); + ieee->pHTInfo = kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL); #else ieee->pHTInfo = (RT_HIGH_THROUGHPUT*)kmalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL); memset(ieee->pHTInfo,0,sizeof(RT_HIGH_THROUGHPUT)); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c index ce265ae5fe18..da10067485e3 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c @@ -1397,7 +1397,7 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, /* skb: hdr + (possible reassembled) full plaintext payload */ payload = skb->data + hdrlen; //ethertype = (payload[6] << 8) | payload[7]; - rxb = (struct ieee80211_rxb*)kmalloc(sizeof(struct ieee80211_rxb),GFP_ATOMIC); + rxb = kmalloc(sizeof(struct ieee80211_rxb), GFP_ATOMIC); if(rxb == NULL) { IEEE80211_DEBUG(IEEE80211_DL_ERR,"%s(): kmalloc rxb error\n",__FUNCTION__); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index b4beb2073919..4f6ce06b606b 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -1800,7 +1800,7 @@ static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen) if(*(t++) == MFIE_TYPE_CHALLENGE){ *chlen = *(t++); - *challenge = (u8*)kmalloc(*chlen, GFP_ATOMIC); + *challenge = kmalloc(*chlen, GFP_ATOMIC); memcpy(*challenge, t, *chlen); } } @@ -3459,8 +3459,7 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, ieee80211_crypt_delayed_deinit(ieee, crypt); - new_crypt = (struct ieee80211_crypt_data *) - kmalloc(sizeof(*new_crypt), GFP_KERNEL); + new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL); if (new_crypt == NULL) { ret = -ENOMEM; goto done; @@ -3592,7 +3591,7 @@ int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_poin goto out; } - param = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL); + param = kmalloc(p->length, GFP_KERNEL); if (param == NULL){ ret = -ENOMEM; goto out; diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 604c691d64b5..533be4882bbf 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -5040,7 +5040,7 @@ static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) goto out; } - ipw = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL); + ipw = kmalloc(p->length, GFP_KERNEL); if (ipw == NULL){ ret = -ENOMEM; goto out; diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c index c024fa600729..73de3baf9158 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c @@ -161,7 +161,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv) ieee80211_softmac_init(ieee); - ieee->pHTInfo = (RT_HIGH_THROUGHPUT*)kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL); + ieee->pHTInfo = kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL); if (ieee->pHTInfo == NULL) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n"); diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c index cc80faf6598b..1f2bc7ac6f79 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c @@ -1191,7 +1191,7 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, /* skb: hdr + (possible reassembled) full plaintext payload */ payload = skb->data + hdrlen; //ethertype = (payload[6] << 8) | payload[7]; - rxb = (struct ieee80211_rxb*)kmalloc(sizeof(struct ieee80211_rxb),GFP_ATOMIC); + rxb = kmalloc(sizeof(struct ieee80211_rxb), GFP_ATOMIC); if(rxb == NULL) { IEEE80211_DEBUG(IEEE80211_DL_ERR,"%s(): kmalloc rxb error\n",__FUNCTION__); diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c index 3cf5fdf8a8cb..660aee2874a4 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c @@ -1557,7 +1557,7 @@ static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen) if(*(t++) == MFIE_TYPE_CHALLENGE){ *chlen = *(t++); - *challenge = (u8*)kmalloc(*chlen, GFP_ATOMIC); + *challenge = kmalloc(*chlen, GFP_ATOMIC); memcpy(*challenge, t, *chlen); } } @@ -3048,8 +3048,7 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, ieee80211_crypt_delayed_deinit(ieee, crypt); - new_crypt = (struct ieee80211_crypt_data *) - kmalloc(sizeof(*new_crypt), GFP_KERNEL); + new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL); if (new_crypt == NULL) { ret = -ENOMEM; goto done; @@ -3182,7 +3181,7 @@ int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_poin goto out; } - param = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL); + param = kmalloc(p->length, GFP_KERNEL); if (param == NULL){ ret = -ENOMEM; goto out; diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index d372ff22a0d3..70a8087434d4 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c @@ -5747,7 +5747,7 @@ int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) goto out; } - ipw = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL); + ipw = kmalloc(p->length, GFP_KERNEL); if (ipw == NULL){ ret = -ENOMEM; goto out; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c index b752017a4d18..1111002bad9f 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c @@ -161,7 +161,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv) ieee80211_softmac_init(ieee); - ieee->pHTInfo = (RT_HIGH_THROUGHPUT*)kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL); + ieee->pHTInfo = kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL); if (ieee->pHTInfo == NULL) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n"); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index 7e9b367594a0..192123fbec7f 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -1302,7 +1302,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, /* skb: hdr + (possible reassembled) full plaintext payload */ payload = skb->data + hdrlen; //ethertype = (payload[6] << 8) | payload[7]; - rxb = (struct ieee80211_rxb*)kmalloc(sizeof(struct ieee80211_rxb),GFP_ATOMIC); + rxb = kmalloc(sizeof(struct ieee80211_rxb), GFP_ATOMIC); if(rxb == NULL) { IEEE80211_DEBUG(IEEE80211_DL_ERR,"%s(): kmalloc rxb error\n",__FUNCTION__); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index e5e583ed1196..6c6bf9f6e78a 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -1579,7 +1579,7 @@ static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen) if(*(t++) == MFIE_TYPE_CHALLENGE){ *chlen = *(t++); - *challenge = (u8*)kmalloc(*chlen, GFP_ATOMIC); + *challenge = kmalloc(*chlen, GFP_ATOMIC); if (!*challenge) return -ENOMEM; memcpy(*challenge, t, *chlen); @@ -3077,8 +3077,7 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, ieee80211_crypt_delayed_deinit(ieee, crypt); - new_crypt = (struct ieee80211_crypt_data *) - kmalloc(sizeof(*new_crypt), GFP_KERNEL); + new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL); if (new_crypt == NULL) { ret = -ENOMEM; goto done; @@ -3210,7 +3209,7 @@ int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_poin goto out; } - param = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL); + param = kmalloc(p->length, GFP_KERNEL); if (param == NULL){ ret = -ENOMEM; goto out; diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 68ebb0256771..cbbc7d32fcf3 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -2216,7 +2216,8 @@ short rtl8192_usb_initendpoints(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); - priv->rx_urb = (struct urb**) kmalloc (sizeof(struct urb*) * (MAX_RX_URB+1), GFP_KERNEL); + priv->rx_urb = kmalloc(sizeof(struct urb *) * (MAX_RX_URB+1), + GFP_KERNEL); #ifndef JACKSON_NEW_RX for(i=0;i<(MAX_RX_URB+1);i++){ @@ -2250,7 +2251,8 @@ short rtl8192_usb_initendpoints(struct net_device *dev) #endif memset(priv->rx_urb, 0, sizeof(struct urb*) * MAX_RX_URB); - priv->pp_rxskb = (struct sk_buff **)kmalloc(sizeof(struct sk_buff *) * MAX_RX_URB, GFP_KERNEL); + priv->pp_rxskb = kmalloc(sizeof(struct sk_buff *) * MAX_RX_URB, + GFP_KERNEL); if (priv->pp_rxskb == NULL) goto destroy; @@ -2839,7 +2841,7 @@ static void rtl8192_init_priv_variable(struct net_device* dev) (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0); priv->AcmControl = 0; - priv->pFirmware = (rt_firmware*)kmalloc(sizeof(rt_firmware), GFP_KERNEL); + priv->pFirmware = kmalloc(sizeof(rt_firmware), GFP_KERNEL); if (priv->pFirmware) memset(priv->pFirmware, 0, sizeof(rt_firmware)); @@ -4415,7 +4417,7 @@ int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) goto out; } - ipw = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL); + ipw = kmalloc(p->length, GFP_KERNEL); if (ipw == NULL){ ret = -ENOMEM; goto out; diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c index b9f986b856eb..c35dead64a38 100644 --- a/drivers/staging/vme/bridges/vme_ca91cx42.c +++ b/drivers/staging/vme/bridges/vme_ca91cx42.c @@ -941,8 +941,7 @@ int ca91cx42_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, dev = list->parent->parent->parent; /* XXX descriptor must be aligned on 64-bit boundaries */ - entry = (struct ca91cx42_dma_entry *) - kmalloc(sizeof(struct ca91cx42_dma_entry), GFP_KERNEL); + entry = kmalloc(sizeof(struct ca91cx42_dma_entry), GFP_KERNEL); if (entry == NULL) { dev_err(dev, "Failed to allocate memory for dma resource " "structure\n"); diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index 25987d4069f2..7539cce6e2a7 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -2309,7 +2309,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (err_chk) { master_num--; - tsi148_device->flush_image = (struct vme_master_resource *) + tsi148_device->flush_image = kmalloc(sizeof(struct vme_master_resource), GFP_KERNEL); if (tsi148_device->flush_image == NULL) { dev_err(&pdev->dev, "Failed to allocate memory for " diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 7020ed41e0ca..f690fc2c35c1 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -3025,7 +3025,7 @@ int Config_FileOperation(PSDevice pDevice,BOOL fwrite,unsigned char *Parameter) goto error1; } -buffer = (UCHAR *)kmalloc(1024, GFP_KERNEL); +buffer = kmalloc(1024, GFP_KERNEL); if(buffer==NULL) { printk("alllocate mem for file fail?\n"); result = -1; diff --git a/drivers/staging/vt6655/hostap.c b/drivers/staging/vt6655/hostap.c index 9e07a40480fd..fb7775c52339 100644 --- a/drivers/staging/vt6655/hostap.c +++ b/drivers/staging/vt6655/hostap.c @@ -90,7 +90,7 @@ static int hostap_enable_hostapd(PSDevice pDevice, int rtnl_locked) DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Enabling hostapd mode\n", dev->name); - pDevice->apdev = (struct net_device *)kmalloc(sizeof(struct net_device), GFP_KERNEL); + pDevice->apdev = kmalloc(sizeof(struct net_device), GFP_KERNEL); if (pDevice->apdev == NULL) return -ENOMEM; memset(pDevice->apdev, 0, sizeof(struct net_device)); @@ -768,7 +768,7 @@ int vt6655_hostap_ioctl(PSDevice pDevice, struct iw_point *p) p->length > VIAWGET_HOSTAPD_MAX_BUF_SIZE || !p->pointer) return -EINVAL; - param = (struct viawget_hostapd_param *) kmalloc((int)p->length, (int)GFP_KERNEL); + param = kmalloc((int)p->length, (int)GFP_KERNEL); if (param == NULL) return -ENOMEM; diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c index 574e0b0a9c28..4e886c162099 100644 --- a/drivers/staging/vt6655/wpactl.c +++ b/drivers/staging/vt6655/wpactl.c @@ -905,7 +905,7 @@ int wpa_ioctl(PSDevice pDevice, struct iw_point *p) p->length > VIAWGET_WPA_MAX_BUF_SIZE || !p->pointer) return -EINVAL; - param = (struct viawget_wpa_param *) kmalloc((int)p->length, (int)GFP_KERNEL); + param = kmalloc((int)p->length, (int)GFP_KERNEL); if (param == NULL) return -ENOMEM; diff --git a/drivers/staging/vt6656/hostap.c b/drivers/staging/vt6656/hostap.c index ca007c30e0ab..44386316b216 100644 --- a/drivers/staging/vt6656/hostap.c +++ b/drivers/staging/vt6656/hostap.c @@ -91,7 +91,7 @@ static int hostap_enable_hostapd(PSDevice pDevice, int rtnl_locked) DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Enabling hostapd mode\n", dev->name); - pDevice->apdev = (struct net_device *)kmalloc(sizeof(struct net_device), GFP_KERNEL); + pDevice->apdev = kmalloc(sizeof(struct net_device), GFP_KERNEL); if (pDevice->apdev == NULL) return -ENOMEM; memset(pDevice->apdev, 0, sizeof(struct net_device)); @@ -766,7 +766,7 @@ int vt6656_hostap_ioctl(PSDevice pDevice, struct iw_point *p) p->length > VIAWGET_HOSTAPD_MAX_BUF_SIZE || !p->pointer) return -EINVAL; - param = (struct viawget_hostapd_param *) kmalloc((int)p->length, (int)GFP_KERNEL); + param = kmalloc((int)p->length, (int)GFP_KERNEL); if (param == NULL) return -ENOMEM; diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index f1d81b1656c5..e4dc27dd21e7 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -1511,7 +1511,7 @@ static UCHAR *Config_FileOperation(PSDevice pDevice) { goto error1; } - buffer = (UCHAR *)kmalloc(1024, GFP_KERNEL); + buffer = kmalloc(1024, GFP_KERNEL); if(buffer==NULL) { printk("alllocate mem for file fail?\n"); result = -1; diff --git a/drivers/staging/vt6656/wpactl.c b/drivers/staging/vt6656/wpactl.c index 04a4875e6015..8f7ad2c43082 100644 --- a/drivers/staging/vt6656/wpactl.c +++ b/drivers/staging/vt6656/wpactl.c @@ -926,7 +926,7 @@ int wpa_ioctl(PSDevice pDevice, struct iw_point *p) p->length > VIAWGET_WPA_MAX_BUF_SIZE || !p->pointer) return -EINVAL; - param = (struct viawget_wpa_param *) kmalloc((int)p->length, (int)GFP_KERNEL); + param = kmalloc((int)p->length, (int)GFP_KERNEL); if (param == NULL) return -ENOMEM; diff --git a/drivers/staging/wlags49_h2/wl_priv.c b/drivers/staging/wlags49_h2/wl_priv.c index a67ff529d359..f2bfd3025e9c 100644 --- a/drivers/staging/wlags49_h2/wl_priv.c +++ b/drivers/staging/wlags49_h2/wl_priv.c @@ -618,7 +618,7 @@ int wvlan_uil_put_info( struct uilreq *urq, struct wl_private *lp ) LTV record, try to allocate it from the kernel stack. Otherwise, we just use our local LTV record. */ if( urq->len > sizeof( lp->ltvRecord )) { - pLtv = (ltv_t *)kmalloc( urq->len, GFP_KERNEL ); + pLtv = kmalloc(urq->len, GFP_KERNEL); if (pLtv != NULL) { ltvAllocated = TRUE; } else { @@ -1298,7 +1298,7 @@ int wvlan_uil_get_info( struct uilreq *urq, struct wl_private *lp ) LTV record, try to allocate it from the kernel stack. Otherwise, we just use our local LTV record. */ if( urq->len > sizeof( lp->ltvRecord )) { - pLtv = (ltv_t *)kmalloc( urq->len, GFP_KERNEL ); + pLtv = kmalloc(urq->len, GFP_KERNEL); if (pLtv != NULL) { ltvAllocated = TRUE; -- cgit v1.2.3 From 6593dfacd3320c4f5fefd6e307ea5c6e9c5dac4f Mon Sep 17 00:00:00 2001 From: Andres More Date: Tue, 11 May 2010 17:29:43 -0300 Subject: staging: vt6656: card.h: code cleanup, resolved checkpatch findings Cleared all findings but a couple of 'do not add new typedefs' warnings. Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/card.h | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/card.h b/drivers/staging/vt6656/card.h index 770ee6a95c11..963c8ad3d2ee 100644 --- a/drivers/staging/vt6656/card.h +++ b/drivers/staging/vt6656/card.h @@ -33,30 +33,27 @@ /*--------------------- Export Definitions -------------------------*/ - /*--------------------- Export Classes ----------------------------*/ -// Init card type +/* init card type */ typedef enum _CARD_PHY_TYPE { - - PHY_TYPE_AUTO=0, + PHY_TYPE_AUTO = 0, PHY_TYPE_11B, PHY_TYPE_11G, PHY_TYPE_11A } CARD_PHY_TYPE, *PCARD_PHY_TYPE; typedef enum _CARD_OP_MODE { - - OP_MODE_INFRASTRUCTURE=0, + OP_MODE_INFRASTRUCTURE = 0, OP_MODE_ADHOC, OP_MODE_AP, OP_MODE_UNKNOWN } CARD_OP_MODE, *PCARD_OP_MODE; #define CB_MAX_CHANNEL_24G 14 -//#define CB_MAX_CHANNEL_5G 24 -#define CB_MAX_CHANNEL_5G 42 //[20050104] add channel9(5045MHz), 41==>42 +/* #define CB_MAX_CHANNEL_5G 24 */ +#define CB_MAX_CHANNEL_5G 42 /* add channel9(5045MHz), 41==>42 */ #define CB_MAX_CHANNEL (CB_MAX_CHANNEL_24G+CB_MAX_CHANNEL_5G) /*--------------------- Export Variables --------------------------*/ @@ -83,12 +80,9 @@ BOOL CARDbRadioPowerOn(void *pDeviceHandler); BYTE CARDbyGetPktType(void *pDeviceHandler); void CARDvSetBSSMode(void *pDeviceHandler); -BOOL -CARDbChannelSwitch ( - void *pDeviceHandler, - BYTE byMode, - BYTE byNewChannel, - BYTE byCount - ); +BOOL CARDbChannelSwitch(void *pDeviceHandler, + BYTE byMode, + BYTE byNewChannel, + BYTE byCount); #endif /* __CARD_H__ */ -- cgit v1.2.3 From 94c1f90bb0bac8c2b75569a247b89145022c4c24 Mon Sep 17 00:00:00 2001 From: Morgan Gatti Date: Tue, 11 May 2010 23:55:53 +0200 Subject: Staging: comedi: Fix bug and coding style issue in usbdux.c This is a patch to the usbdux.c file that resolve 2 errors in coding and fix the warning about lengt of code lines Signed-off-by: Morgan Gatti Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbdux.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 8942ae45708d..df71515c7a30 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -793,7 +793,7 @@ static int usbduxsub_stop(struct usbduxsub *usbduxsub) } static int usbduxsub_upload(struct usbduxsub *usbduxsub, - uint8_t * local_transfer_buffer, + uint8_t *local_transfer_buffer, unsigned int startAddr, unsigned int len) { int errcode; @@ -825,7 +825,7 @@ static int usbduxsub_upload(struct usbduxsub *usbduxsub, #define FIRMWARE_MAX_LEN 0x2000 static int firmwareUpload(struct usbduxsub *usbduxsub, - const u8 * firmwareBinary, int sizeFirmware) + const u8 *firmwareBinary, int sizeFirmware) { int ret; uint8_t *fwBuf; @@ -835,7 +835,7 @@ static int firmwareUpload(struct usbduxsub *usbduxsub, if (sizeFirmware > FIRMWARE_MAX_LEN) { dev_err(&usbduxsub->interface->dev, - "comedi_: usbdux firmware binary it too large for FX2.\n"); + "usbdux firmware binary it too large for FX2.\n"); return -ENOMEM; } @@ -1264,8 +1264,8 @@ static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) (this_usbduxsub->ai_interval) * 2; } this_usbduxsub->ai_timer = cmd->scan_begin_arg / (125000 * - (this_usbduxsub-> - ai_interval)); + (this_usbduxsub-> + ai_interval)); } else { /* interval always 1ms */ this_usbduxsub->ai_interval = 1; -- cgit v1.2.3 From b430acbd7c4b919886fa7fd92eeb7a695f1940d3 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 6 May 2010 17:41:08 -0400 Subject: ACPICA: simplify SCI_EN workaround acpi_hw_set_mode() double checks its effectiveness by calling acpi_hw_get_mode() -- polling up to 3 seconds. It would be more logical for its caller, acpi_enable() acpi_enable() to do the double-checking. (lets assume that acpi_disable() isn't interesting) The ACPI specification is unclear on this point. Some parts say that the BIOS sets SCI_EN and then returns to the OS, but one part says "OSPM polls the SCI_EN bit until it is sampled SET". The systems I have on hand do the former, SCI_EN is observed to be set upon return from the BIOS. So we move the check up out of acpi_hw_set_mode() up into acpi_enable() where it makes logical sense. Then we replace the 3-second polling loop with a single check. If this check fails, we'll see: "Hardware did not enter ACPI mode" and the system will bail out of ACPI initialization and likely fail to boot. If we see that in practice, we can restore the polling, but put it into acpi_enable. This patch is important if acpi_enable() is used in the resume from S3 path. Many systems today are seen coming back from S3 with SCI_EN off, and then failing to set SCI_EN in response to acpi_enable(). Those systems will take 3 seconds longer to resume due to this loop. However, it is possible that we will not use acpi_enable() in the S3 resume path, and bang SCI_EN directly, which would make the loop harmless, as it would be invisible to all systems except those that need it. Signed-off-by: Len Brown --- drivers/acpi/acpica/evxfevnt.c | 33 +++++++++++++++++++++------------ drivers/acpi/acpica/hwacpi.c | 20 +------------------- 2 files changed, 22 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index 5ff32c78ea2d..bfbe291d572e 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -69,7 +69,7 @@ acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, acpi_status acpi_enable(void) { - acpi_status status = AE_OK; + acpi_status status; ACPI_FUNCTION_TRACE(acpi_enable); @@ -84,21 +84,30 @@ acpi_status acpi_enable(void) if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { ACPI_DEBUG_PRINT((ACPI_DB_INIT, "System is already in ACPI mode\n")); - } else { - /* Transition to ACPI mode */ + return_ACPI_STATUS(AE_OK); + } - status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI); - if (ACPI_FAILURE(status)) { - ACPI_ERROR((AE_INFO, - "Could not transition to ACPI mode")); - return_ACPI_STATUS(status); - } + /* Transition to ACPI mode */ - ACPI_DEBUG_PRINT((ACPI_DB_INIT, - "Transition to ACPI mode successful\n")); + status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI); + if (ACPI_FAILURE(status)) { + ACPI_ERROR((AE_INFO, + "Could not transition to ACPI mode")); + return_ACPI_STATUS(status); } - return_ACPI_STATUS(status); + /* Sanity check that transition succeeded */ + + if (acpi_hw_get_mode() != ACPI_SYS_MODE_ACPI) { + ACPI_ERROR((AE_INFO, + "Hardware did not enter ACPI mode")); + return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); + } + + ACPI_DEBUG_PRINT((ACPI_DB_INIT, + "Transition to ACPI mode successful\n")); + + return_ACPI_STATUS(AE_OK); } ACPI_EXPORT_SYMBOL(acpi_enable) diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c index 679a112a7d26..b44274a0b62c 100644 --- a/drivers/acpi/acpica/hwacpi.c +++ b/drivers/acpi/acpica/hwacpi.c @@ -63,7 +63,6 @@ acpi_status acpi_hw_set_mode(u32 mode) { acpi_status status; - u32 retry; ACPI_FUNCTION_TRACE(hw_set_mode); @@ -125,24 +124,7 @@ acpi_status acpi_hw_set_mode(u32 mode) return_ACPI_STATUS(status); } - /* - * Some hardware takes a LONG time to switch modes. Give them 3 sec to - * do so, but allow faster systems to proceed more quickly. - */ - retry = 3000; - while (retry) { - if (acpi_hw_get_mode() == mode) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Mode %X successfully enabled\n", - mode)); - return_ACPI_STATUS(AE_OK); - } - acpi_os_stall(1000); - retry--; - } - - ACPI_ERROR((AE_INFO, "Hardware did not change modes")); - return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); + return_ACPI_STATUS(AE_OK); } /******************************************************************************* -- cgit v1.2.3 From b6dacf63e9fb2e7a1369843d6cef332f76fca6a3 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 11 May 2010 13:49:25 -0400 Subject: ACPI: Unconditionally set SCI_EN on resume The ACPI spec tells us that the firmware will reenable SCI_EN on resume. Reality disagrees in some cases. The ACPI spec tells us that the only way to set SCI_EN is via an SMM call. https://bugzilla.kernel.org/show_bug.cgi?id=13745 shows us that doing so may break machines. Tracing the ACPI calls made by Windows shows that it unconditionally sets SCI_EN on resume with a direct register write, and therefore the overwhelming probability is that everything is fine with this behaviour. Signed-off-by: Matthew Garrett Tested-by: Rafael J. Wysocki Signed-off-by: Len Brown --- arch/x86/kernel/acpi/sleep.c | 2 - drivers/acpi/sleep.c | 157 +------------------------------------------ include/linux/acpi.h | 1 - 3 files changed, 2 insertions(+), 158 deletions(-) (limited to 'drivers') diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index f9961034e557..82e508677b91 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c @@ -162,8 +162,6 @@ static int __init acpi_sleep_setup(char *str) #endif if (strncmp(str, "old_ordering", 12) == 0) acpi_old_suspend_ordering(); - if (strncmp(str, "sci_force_enable", 16) == 0) - acpi_set_sci_en_on_resume(); str = strchr(str, ','); if (str != NULL) str += strspn(str, ", \t"); diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index baa76bbf244a..4ab2275b4461 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -80,22 +80,6 @@ static int acpi_sleep_prepare(u32 acpi_state) #ifdef CONFIG_ACPI_SLEEP static u32 acpi_target_sleep_state = ACPI_STATE_S0; -/* - * According to the ACPI specification the BIOS should make sure that ACPI is - * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, - * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI - * on such systems during resume. Unfortunately that doesn't help in - * particularly pathological cases in which SCI_EN has to be set directly on - * resume, although the specification states very clearly that this flag is - * owned by the hardware. The set_sci_en_on_resume variable will be set in such - * cases. - */ -static bool set_sci_en_on_resume; - -void __init acpi_set_sci_en_on_resume(void) -{ - set_sci_en_on_resume = true; -} /* * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the @@ -253,11 +237,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state) break; } - /* If ACPI is not enabled by the BIOS, we need to enable it here. */ - if (set_sci_en_on_resume) - acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1); - else - acpi_enable(); + /* This violates the spec but is required for bug compatibility. */ + acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1); /* Reprogram control registers and execute _BFS */ acpi_leave_sleep_state_prep(acpi_state); @@ -346,12 +327,6 @@ static int __init init_old_suspend_ordering(const struct dmi_system_id *d) return 0; } -static int __init init_set_sci_en_on_resume(const struct dmi_system_id *d) -{ - set_sci_en_on_resume = true; - return 0; -} - static struct dmi_system_id __initdata acpisleep_dmi_table[] = { { .callback = init_old_suspend_ordering, @@ -370,22 +345,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { }, }, { - .callback = init_set_sci_en_on_resume, - .ident = "Apple MacBook 1,1", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Apple MacMini 1,1", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), - }, - }, - { .callback = init_old_suspend_ordering, .ident = "Asus Pundit P1-AH2 (M2N8L motherboard)", .matches = { @@ -394,94 +353,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { }, }, { - .callback = init_set_sci_en_on_resume, - .ident = "Toshiba Satellite L300", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L300"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Hewlett-Packard HP G7000 Notebook PC", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP G7000 Notebook PC"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Hewlett-Packard HP Pavilion dv3 Notebook PC", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv3 Notebook PC"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Hewlett-Packard Pavilion dv4", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Hewlett-Packard Pavilion dv7", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv7"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Hewlett-Packard Compaq Presario C700 Notebook PC", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "Compaq Presario C700 Notebook PC"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Hewlett-Packard Compaq Presario CQ40 Notebook PC", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "Compaq Presario CQ40 Notebook PC"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Lenovo ThinkPad T410", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T410"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Lenovo ThinkPad T510", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T510"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Lenovo ThinkPad W510", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W510"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Lenovo ThinkPad X201[s]", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201"), - }, - }, - { .callback = init_old_suspend_ordering, .ident = "Panasonic CF51-2L", .matches = { @@ -490,30 +361,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"), }, }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Dell Studio 1558", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1558"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Dell Studio 1557", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1557"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Dell Studio 1555", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1555"), - }, - }, {}, }; #endif /* CONFIG_SUSPEND */ diff --git a/include/linux/acpi.h b/include/linux/acpi.h index b926afe8c03e..87ca4913294c 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -251,7 +251,6 @@ int acpi_check_mem_region(resource_size_t start, resource_size_t n, void __init acpi_no_s4_hw_signature(void); void __init acpi_old_suspend_ordering(void); void __init acpi_s4_no_nvs(void); -void __init acpi_set_sci_en_on_resume(void); #endif /* CONFIG_PM_SLEEP */ struct acpi_osc_context { -- cgit v1.2.3 From 5bdd5ded95b3188d58ba43ac801b8849cbea1b16 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 14 May 2010 14:58:05 +1000 Subject: crypto: mv_cesa - Use resource_size Use the resource_size function instead of manually calculating the resource size. This reduces the chance of introducing off-by-one errors. Signed-off-by: Tobias Klauser Signed-off-by: Herbert Xu --- drivers/crypto/mv_cesa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index 18a436cafc10..e095422b58dd 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -1023,7 +1023,7 @@ static int mv_probe(struct platform_device *pdev) spin_lock_init(&cp->lock); crypto_init_queue(&cp->queue, 50); - cp->reg = ioremap(res->start, res->end - res->start + 1); + cp->reg = ioremap(res->start, resource_size(res)); if (!cp->reg) { ret = -ENOMEM; goto err; @@ -1034,7 +1034,7 @@ static int mv_probe(struct platform_device *pdev) ret = -ENXIO; goto err_unmap_reg; } - cp->sram_size = res->end - res->start + 1; + cp->sram_size = resource_size(res); cp->max_req_size = cp->sram_size - SRAM_CFG_SPACE; cp->sram = ioremap(res->start, cp->sram_size); if (!cp->sram) { -- cgit v1.2.3 From 06e719d80ff900973cddffa84fc2d7620c69a236 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Fri, 7 May 2010 17:52:17 -0600 Subject: Staging: hv: auto-load MSFT PV NIC driver Signed-off-by: K. Y. Srinivasan Cc: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/netvsc_drv.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 30c946c133c2..1bda2407b49c 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #include #include @@ -551,6 +553,20 @@ static int netvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) return ret; } +static const struct dmi_system_id __initconst +hv_netvsc_dmi_table[] __maybe_unused = { + { + .ident = "Hyper-V", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), + DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"), + }, + }, + { }, +}; +MODULE_DEVICE_TABLE(dmi, hv_netvsc_dmi_table); + static int __init netvsc_init(void) { int ret; @@ -558,6 +574,9 @@ static int __init netvsc_init(void) DPRINT_ENTER(NETVSC_DRV); DPRINT_INFO(NETVSC_DRV, "Netvsc initializing...."); + if (!dmi_check_system(hv_netvsc_dmi_table)) + return -ENODEV; + ret = netvsc_drv_init(NetVscInitialize); DPRINT_EXIT(NETVSC_DRV); @@ -572,6 +591,13 @@ static void __exit netvsc_exit(void) DPRINT_EXIT(NETVSC_DRV); } +static const struct pci_device_id __initconst +hv_netvsc_pci_table[] __maybe_unused = { + { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */ + { 0 } +}; +MODULE_DEVICE_TABLE(pci, hv_netvsc_pci_table); + MODULE_LICENSE("GPL"); MODULE_VERSION(HV_DRV_VERSION); MODULE_DESCRIPTION("Microsoft Hyper-V network driver"); -- cgit v1.2.3 From 83d4b7eb5f319d8c6d8586586cb1d9c0d1a80532 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Tue, 11 May 2010 16:33:01 -0700 Subject: staging: batman: remove all rcu head initializations Remove all rcu head inits. We don't care about the RCU head state before passing it to call_rcu() anyway. Only leave the "on_stack" variants so debugobjects can keep track of objects on stack. Signed-off-by: Mathieu Desnoyers Signed-off-by: Paul E. McKenney Cc: Andrew Lunn Cc: Simon Wunderlich Cc: Marek Lindner Cc: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/hard-interface.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c index 0d1d1011dd44..7a582e80de18 100644 --- a/drivers/staging/batman-adv/hard-interface.c +++ b/drivers/staging/batman-adv/hard-interface.c @@ -340,7 +340,6 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev) batman_if->if_num = -1; batman_if->net_dev = net_dev; batman_if->if_status = IF_NOT_IN_USE; - INIT_RCU_HEAD(&batman_if->rcu); INIT_LIST_HEAD(&batman_if->list); check_known_mac_addr(batman_if->net_dev->dev_addr); -- cgit v1.2.3 From 935e99fb0739aa64d0dd7e8a0bc82faec5d8f830 Mon Sep 17 00:00:00 2001 From: Anand Gadiyar Date: Wed, 12 May 2010 13:03:13 +0530 Subject: staging: trivial: fix typo "seperate" s/seperate/separate Signed-off-by: Anand Gadiyar Cc: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das08.h | 2 +- drivers/staging/dream/camera/msm_vfe8x_proc.c | 2 +- drivers/staging/echo/echo.c | 2 +- drivers/staging/rt2860/mlme.h | 2 +- drivers/staging/rtl8192e/ieee80211.h | 2 +- drivers/staging/rtl8192e/ieee80211/ieee80211.h | 2 +- drivers/staging/rtl8192e/r8190_rtl8256.c | 4 ++-- drivers/staging/rtl8192e/r8192E_core.c | 2 +- drivers/staging/rtl8192su/ieee80211/ieee80211.h | 2 +- drivers/staging/rtl8192su/r8192S_phy.c | 2 +- drivers/staging/rtl8192u/ieee80211.h | 2 +- drivers/staging/rtl8192u/ieee80211/ieee80211.h | 2 +- drivers/staging/wlags49_h2/README.wlags49 | 2 +- drivers/staging/wlags49_h2/wl_priv.c | 2 +- drivers/staging/wlags49_h2/wl_wext.c | 2 +- 15 files changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/das08.h b/drivers/staging/comedi/drivers/das08.h index 35d2660cf93b..2a30d764ddfc 100644 --- a/drivers/staging/comedi/drivers/das08.h +++ b/drivers/staging/comedi/drivers/das08.h @@ -62,7 +62,7 @@ struct i8254_struct { #define I8254_CTRL 3 struct das08_private_struct { - unsigned int do_mux_bits; /* bits for do/mux register on boards without seperate do register */ + unsigned int do_mux_bits; /* bits for do/mux register on boards without separate do register */ unsigned int do_bits; /* bits for do register on boards with register dedicated to digital out only */ const unsigned int *pg_gainlist; struct pci_dev *pdev; /* struct for pci-das08 */ diff --git a/drivers/staging/dream/camera/msm_vfe8x_proc.c b/drivers/staging/dream/camera/msm_vfe8x_proc.c index 10aef0e59bab..f80ef967ba87 100644 --- a/drivers/staging/dream/camera/msm_vfe8x_proc.c +++ b/drivers/staging/dream/camera/msm_vfe8x_proc.c @@ -3828,7 +3828,7 @@ void vfe_camif_config(struct vfe_cmd_camif_config *in) ctrl->vfeImaskLocal.camifEpoch2Irq = 1; } - /* save the content to program CAMIF_CONFIG seperately. */ + /* save the content to program CAMIF_CONFIG separately. */ ctrl->vfeCamifConfigLocal.camifCfgFromCmd = in->camifConfig; /* EFS_Config */ diff --git a/drivers/staging/echo/echo.c b/drivers/staging/echo/echo.c index 4cc4f2eb7eb7..58c4e907e44d 100644 --- a/drivers/staging/echo/echo.c +++ b/drivers/staging/echo/echo.c @@ -603,7 +603,7 @@ int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx) } EXPORT_SYMBOL_GPL(oslec_update); -/* This function is seperated from the echo canceller is it is usually called +/* This function is separated from the echo canceller is it is usually called as part of the tx process. See rx HP (DC blocking) filter above, it's the same design. diff --git a/drivers/staging/rt2860/mlme.h b/drivers/staging/rt2860/mlme.h index 11434132f93b..99c9362bae86 100644 --- a/drivers/staging/rt2860/mlme.h +++ b/drivers/staging/rt2860/mlme.h @@ -322,7 +322,7 @@ struct rt_trigger_eventa { u8 BSSID[6]; u8 RegClass; /* Regulatory Class */ u16 Channel; - unsigned long CDCounter; /* Maintain a seperate count down counter for each Event A. */ + unsigned long CDCounter; /* Maintain a separate count down counter for each Event A. */ }; /* 20/40 trigger event table */ diff --git a/drivers/staging/rtl8192e/ieee80211.h b/drivers/staging/rtl8192e/ieee80211.h index c39249eb54b5..e1f03d79d2b6 100644 --- a/drivers/staging/rtl8192e/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211.h @@ -1846,7 +1846,7 @@ struct ieee80211_device { spinlock_t bw_spinlock; spinlock_t reorder_spinlock; - // for HT operation rate set. we use this one for HT data rate to seperate different descriptors + // for HT operation rate set. we use this one for HT data rate to separate different descriptors //the way fill this is the same as in the IE u8 Regdot11HTOperationalRateSet[16]; //use RATR format u8 dot11HTOperationalRateSet[16]; //use RATR format diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index 1f613a28152f..50728f6e9c55 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -2067,7 +2067,7 @@ struct ieee80211_device { spinlock_t bw_spinlock; spinlock_t reorder_spinlock; - // for HT operation rate set. we use this one for HT data rate to seperate different descriptors + // for HT operation rate set. we use this one for HT data rate to separate different descriptors //the way fill this is the same as in the IE u8 Regdot11HTOperationalRateSet[16]; //use RATR format u8 dot11HTOperationalRateSet[16]; //use RATR format diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c index 1bd054d42f24..7391f5f8f25f 100644 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ b/drivers/staging/rtl8192e/r8190_rtl8256.c @@ -802,7 +802,7 @@ MgntDisconnectIBSS( case RT_OP_MODE_IBSS: btMsr |= MSR_LINK_ADHOC; - // led link set seperate + // led link set separate break; case RT_OP_MODE_AP: @@ -885,7 +885,7 @@ MlmeDisassociateRequest( case RT_OP_MODE_IBSS: btMsr |= MSR_LINK_ADHOC; - // led link set seperate + // led link set separate break; case RT_OP_MODE_AP: diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 533be4882bbf..eb41402d1d37 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -407,7 +407,7 @@ rtl8192e_SetHwReg(struct net_device *dev,u8 variable,u8* val) case RT_OP_MODE_IBSS: btMsr |= MSR_ADHOC; - // led link set seperate + // led link set separate break; case RT_OP_MODE_AP: diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211.h b/drivers/staging/rtl8192su/ieee80211/ieee80211.h index 32b261d15594..bcb2b12a8398 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211.h @@ -1152,7 +1152,7 @@ struct ieee80211_device { spinlock_t reorder_spinlock; /* * for HT operation rate set, we use this one for HT data rate to - * seperate different descriptors the way fill this is the same as + * separate different descriptors the way fill this is the same as * in the IE */ u8 Regdot11HTOperationalRateSet[16]; /* use RATR format */ diff --git a/drivers/staging/rtl8192su/r8192S_phy.c b/drivers/staging/rtl8192su/r8192S_phy.c index 69ede47dfdcc..b6c0f1990742 100644 --- a/drivers/staging/rtl8192su/r8192S_phy.c +++ b/drivers/staging/rtl8192su/r8192S_phy.c @@ -882,7 +882,7 @@ phy_BB8192S_Config_ParaFile(struct net_device* dev) // // 1. Read PHY_REG.TXT BB INIT!! - // We will seperate as 1T1R/1T2R/1T2R_GREEN/2T2R + // We will separate as 1T1R/1T2R/1T2R_GREEN/2T2R // if (priv->rf_type == RF_1T2R || priv->rf_type == RF_2T2R || priv->rf_type == RF_1T1R ||priv->rf_type == RF_2T2R_GREEN) diff --git a/drivers/staging/rtl8192u/ieee80211.h b/drivers/staging/rtl8192u/ieee80211.h index ef9e941f4967..9c726113214d 100644 --- a/drivers/staging/rtl8192u/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211.h @@ -1795,7 +1795,7 @@ struct ieee80211_device { spinlock_t reorder_spinlock; /* for HT operation rate set. we use this one for HT data rate to - * seperate different descriptors + * separate different descriptors * the way fill this is the same as in the IE */ u8 Regdot11HTOperationalRateSet[16]; /* use RATR format */ diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h index 39847c81e29c..e1216b704959 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h @@ -1829,7 +1829,7 @@ struct ieee80211_device { spinlock_t bw_spinlock; spinlock_t reorder_spinlock; - // for HT operation rate set. we use this one for HT data rate to seperate different descriptors + // for HT operation rate set. we use this one for HT data rate to separate different descriptors //the way fill this is the same as in the IE u8 Regdot11HTOperationalRateSet[16]; //use RATR format u8 dot11HTOperationalRateSet[16]; //use RATR format diff --git a/drivers/staging/wlags49_h2/README.wlags49 b/drivers/staging/wlags49_h2/README.wlags49 index 7586fd09adc9..f65acd6f5f54 100644 --- a/drivers/staging/wlags49_h2/README.wlags49 +++ b/drivers/staging/wlags49_h2/README.wlags49 @@ -84,7 +84,7 @@ TABLE OF CONTENTS. the functions to interface to the Network Interface Card (NIC). The HCF provides for all WaveLAN NIC types one standard interface to the MSF. This I/F is called the Wireless Connection Interface (WCI) and is the - subject of a seperate document (025726). + subject of a separate document (025726). The HCF directory contains firmware images to allow the card to operate in either station (STA) or Access Point (AP) mode. In the build process, the diff --git a/drivers/staging/wlags49_h2/wl_priv.c b/drivers/staging/wlags49_h2/wl_priv.c index f2bfd3025e9c..260d4f0d47b4 100644 --- a/drivers/staging/wlags49_h2/wl_priv.c +++ b/drivers/staging/wlags49_h2/wl_priv.c @@ -654,7 +654,7 @@ int wvlan_uil_put_info( struct uilreq *urq, struct wl_private *lp ) pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); break; /* CFG_CNF_OWN_SSID currently same as CNF_DESIRED_SSID. Do we - need seperate storage for this? */ + need separate storage for this? */ //case CFG_CNF_OWN_SSID: case CFG_CNF_OWN_ATIM_WINDOW: lp->atimWindow = pLtv->u.u16[0]; diff --git a/drivers/staging/wlags49_h2/wl_wext.c b/drivers/staging/wlags49_h2/wl_wext.c index 4434e0065488..311d3c5a2ef0 100644 --- a/drivers/staging/wlags49_h2/wl_wext.c +++ b/drivers/staging/wlags49_h2/wl_wext.c @@ -3940,7 +3940,7 @@ void wl_wext_event_mic_failed( struct net_device *dev ) MLME-MICHAELMICFAILURE.indication(keyid=# broadcast/unicast addr=addr2) */ - /* NOTE: Format of MAC address (using colons to seperate bytes) may cause + /* NOTE: Format of MAC address (using colons to separate bytes) may cause a problem in future versions of the supplicant, if they ever actually parse these parameters */ #if DBG -- cgit v1.2.3 From 089a41985c6c7e69c8fe043c0dd397da628254f5 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 12 May 2010 19:34:06 +0100 Subject: staging: iio: adis16260 digital gyro driver Signed-off-by: Barry Song Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Kconfig | 1 + drivers/staging/iio/Makefile | 1 + drivers/staging/iio/gyro/Kconfig | 13 + drivers/staging/iio/gyro/Makefile | 7 + drivers/staging/iio/gyro/adis16260.h | 175 +++++++ drivers/staging/iio/gyro/adis16260_core.c | 661 +++++++++++++++++++++++++++ drivers/staging/iio/gyro/adis16260_ring.c | 256 +++++++++++ drivers/staging/iio/gyro/adis16260_trigger.c | 124 +++++ drivers/staging/iio/gyro/gyro.h | 2 + 9 files changed, 1240 insertions(+) create mode 100644 drivers/staging/iio/gyro/Kconfig create mode 100644 drivers/staging/iio/gyro/Makefile create mode 100644 drivers/staging/iio/gyro/adis16260.h create mode 100644 drivers/staging/iio/gyro/adis16260_core.c create mode 100644 drivers/staging/iio/gyro/adis16260_ring.c create mode 100644 drivers/staging/iio/gyro/adis16260_trigger.c (limited to 'drivers') diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index ed38ef4db444..b0e62449c621 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -41,6 +41,7 @@ config IIO_TRIGGER source "drivers/staging/iio/accel/Kconfig" source "drivers/staging/iio/adc/Kconfig" +source "drivers/staging/iio/gyro/Kconfig" source "drivers/staging/iio/imu/Kconfig" source "drivers/staging/iio/light/Kconfig" diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile index 92b81c2b895d..3502b39f0847 100644 --- a/drivers/staging/iio/Makefile +++ b/drivers/staging/iio/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_IIO_SW_RING) += ring_sw.o obj-y += accel/ obj-y += adc/ +obj-y += gyro/ obj-y += imu/ obj-y += light/ diff --git a/drivers/staging/iio/gyro/Kconfig b/drivers/staging/iio/gyro/Kconfig new file mode 100644 index 000000000000..c4043610c0df --- /dev/null +++ b/drivers/staging/iio/gyro/Kconfig @@ -0,0 +1,13 @@ +# +# IIO Digital Gyroscope Sensor drivers configuration +# +comment "Digital gyroscope sensors" + +config ADIS16260 + tristate "Analog Devices ADIS16260/5 Digital Gyroscope Sensor SPI driver" + depends on SPI + select IIO_TRIGGER if IIO_RING_BUFFER + select IIO_SW_RING if IIO_RING_BUFFER + help + Say yes here to build support for Analog Devices adis16260/5 + programmable digital gyroscope sensor. diff --git a/drivers/staging/iio/gyro/Makefile b/drivers/staging/iio/gyro/Makefile new file mode 100644 index 000000000000..6d2c547686cb --- /dev/null +++ b/drivers/staging/iio/gyro/Makefile @@ -0,0 +1,7 @@ + +# Makefile for digital gyroscope sensor drivers +# + +adis16260-y := adis16260_core.o +adis16260-$(CONFIG_IIO_RING_BUFFER) += adis16260_ring.o adis16260_trigger.o +obj-$(CONFIG_ADIS16260) += adis16260.o diff --git a/drivers/staging/iio/gyro/adis16260.h b/drivers/staging/iio/gyro/adis16260.h new file mode 100644 index 000000000000..f19efb4c91ce --- /dev/null +++ b/drivers/staging/iio/gyro/adis16260.h @@ -0,0 +1,175 @@ +#ifndef SPI_ADIS16260_H_ +#define SPI_ADIS16260_H_ + +#define ADIS16260_STARTUP_DELAY 220 /* ms */ + +#define ADIS16260_READ_REG(a) a +#define ADIS16260_WRITE_REG(a) ((a) | 0x80) + +#define ADIS16260_FLASH_CNT 0x00 /* Flash memory write count */ +#define ADIS16260_SUPPLY_OUT 0x02 /* Power supply measurement */ +#define ADIS16260_GYRO_OUT 0x04 /* X-axis gyroscope output */ +#define ADIS16260_AUX_ADC 0x0A /* analog input channel measurement */ +#define ADIS16260_TEMP_OUT 0x0C /* internal temperature measurement */ +#define ADIS16260_ANGL_OUT 0x0E /* angle displacement */ +#define ADIS16260_GYRO_OFF 0x14 /* Calibration, offset/bias adjustment */ +#define ADIS16260_GYRO_SCALE 0x16 /* Calibration, scale adjustment */ +#define ADIS16260_ALM_MAG1 0x20 /* Alarm 1 magnitude/polarity setting */ +#define ADIS16260_ALM_MAG2 0x22 /* Alarm 2 magnitude/polarity setting */ +#define ADIS16260_ALM_SMPL1 0x24 /* Alarm 1 dynamic rate of change setting */ +#define ADIS16260_ALM_SMPL2 0x26 /* Alarm 2 dynamic rate of change setting */ +#define ADIS16260_ALM_CTRL 0x28 /* Alarm control */ +#define ADIS16260_AUX_DAC 0x30 /* Auxiliary DAC data */ +#define ADIS16260_GPIO_CTRL 0x32 /* Control, digital I/O line */ +#define ADIS16260_MSC_CTRL 0x34 /* Control, data ready, self-test settings */ +#define ADIS16260_SMPL_PRD 0x36 /* Control, internal sample rate */ +#define ADIS16260_SENS_AVG 0x38 /* Control, dynamic range, filtering */ +#define ADIS16260_SLP_CNT 0x3A /* Control, sleep mode initiation */ +#define ADIS16260_DIAG_STAT 0x3C /* Diagnostic, error flags */ +#define ADIS16260_GLOB_CMD 0x3E /* Control, global commands */ +#define ADIS16260_LOT_ID1 0x52 /* Lot Identification Code 1 */ +#define ADIS16260_LOT_ID2 0x54 /* Lot Identification Code 2 */ +#define ADIS16260_PROD_ID 0x56 /* Product identifier; + * convert to decimal = 16,265/16,260 */ +#define ADIS16260_SERIAL_NUM 0x58 /* Serial number */ + +#define ADIS16260_OUTPUTS 5 + +#define ADIS16260_ERROR_ACTIVE (1<<14) +#define ADIS16260_NEW_DATA (1<<15) + +/* MSC_CTRL */ +#define ADIS16260_MSC_CTRL_MEM_TEST (1<<11) +/* Internal self-test enable */ +#define ADIS16260_MSC_CTRL_INT_SELF_TEST (1<<10) +#define ADIS16260_MSC_CTRL_NEG_SELF_TEST (1<<9) +#define ADIS16260_MSC_CTRL_POS_SELF_TEST (1<<8) +#define ADIS16260_MSC_CTRL_DATA_RDY_EN (1<<2) +#define ADIS16260_MSC_CTRL_DATA_RDY_POL_HIGH (1<<1) +#define ADIS16260_MSC_CTRL_DATA_RDY_DIO2 (1<<0) + +/* SMPL_PRD */ +/* Time base (tB): 0 = 1.953 ms, 1 = 60.54 ms */ +#define ADIS16260_SMPL_PRD_TIME_BASE (1<<7) +#define ADIS16260_SMPL_PRD_DIV_MASK 0x7F + +/* SLP_CNT */ +#define ADIS16260_SLP_CNT_POWER_OFF 0x80 + +/* DIAG_STAT */ +#define ADIS16260_DIAG_STAT_ALARM2 (1<<9) +#define ADIS16260_DIAG_STAT_ALARM1 (1<<8) +#define ADIS16260_DIAG_STAT_FLASH_CHK (1<<6) +#define ADIS16260_DIAG_STAT_SELF_TEST (1<<5) +#define ADIS16260_DIAG_STAT_OVERFLOW (1<<4) +#define ADIS16260_DIAG_STAT_SPI_FAIL (1<<3) +#define ADIS16260_DIAG_STAT_FLASH_UPT (1<<2) +#define ADIS16260_DIAG_STAT_POWER_HIGH (1<<1) +#define ADIS16260_DIAG_STAT_POWER_LOW (1<<0) + +/* GLOB_CMD */ +#define ADIS16260_GLOB_CMD_SW_RESET (1<<7) +#define ADIS16260_GLOB_CMD_FLASH_UPD (1<<3) +#define ADIS16260_GLOB_CMD_DAC_LATCH (1<<2) +#define ADIS16260_GLOB_CMD_FAC_CALIB (1<<1) +#define ADIS16260_GLOB_CMD_AUTO_NULL (1<<0) + +#define ADIS16260_MAX_TX 24 +#define ADIS16260_MAX_RX 24 + +#define ADIS16260_SPI_SLOW (u32)(300 * 1000) +#define ADIS16260_SPI_BURST (u32)(1000 * 1000) +#define ADIS16260_SPI_FAST (u32)(2000 * 1000) + +/** + * struct adis16260_state - device instance specific data + * @us: actual spi_device + * @work_trigger_to_ring: bh for triggered event handling + * @work_cont_thresh: CLEAN + * @inter: used to check if new interrupt has been triggered + * @last_timestamp: passing timestamp from th to bh of interrupt handler + * @indio_dev: industrial I/O device structure + * @trig: data ready trigger registered with iio + * @tx: transmit buffer + * @rx: recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct adis16260_state { + struct spi_device *us; + struct work_struct work_trigger_to_ring; + struct iio_work_cont work_cont_thresh; + s64 last_timestamp; + struct iio_dev *indio_dev; + struct iio_trigger *trig; + u8 *tx; + u8 *rx; + struct mutex buf_lock; +}; + +int adis16260_set_irq(struct device *dev, bool enable); + +#ifdef CONFIG_IIO_RING_BUFFER +/* At the moment triggers are only used for ring buffer + * filling. This may change! + */ + +enum adis16260_scan { + ADIS16260_SCAN_SUPPLY, + ADIS16260_SCAN_GYRO, + ADIS16260_SCAN_AUX_ADC, + ADIS16260_SCAN_TEMP, + ADIS16260_SCAN_ANGL, +}; + +void adis16260_remove_trigger(struct iio_dev *indio_dev); +int adis16260_probe_trigger(struct iio_dev *indio_dev); + +ssize_t adis16260_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf); + + +int adis16260_configure_ring(struct iio_dev *indio_dev); +void adis16260_unconfigure_ring(struct iio_dev *indio_dev); + +int adis16260_initialize_ring(struct iio_ring_buffer *ring); +void adis16260_uninitialize_ring(struct iio_ring_buffer *ring); +#else /* CONFIG_IIO_RING_BUFFER */ + +static inline void adis16260_remove_trigger(struct iio_dev *indio_dev) +{ +} + +static inline int adis16260_probe_trigger(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline ssize_t +adis16260_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static int adis16260_configure_ring(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline void adis16260_unconfigure_ring(struct iio_dev *indio_dev) +{ +} + +static inline int adis16260_initialize_ring(struct iio_ring_buffer *ring) +{ + return 0; +} + +static inline void adis16260_uninitialize_ring(struct iio_ring_buffer *ring) +{ +} + +#endif /* CONFIG_IIO_RING_BUFFER */ +#endif /* SPI_ADIS16260_H_ */ diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c new file mode 100644 index 000000000000..c93f4d580fce --- /dev/null +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -0,0 +1,661 @@ +/* + * ADIS16260 Programmable Digital Gyroscope Sensor Driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../adc/adc.h" +#include "gyro.h" + +#include "adis16260.h" + +#define DRIVER_NAME "adis16260" + +static int adis16260_check_status(struct device *dev); + +/** + * adis16260_spi_write_reg_8() - write single byte to a register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the register to be written + * @val: the value to write + **/ +static int adis16260_spi_write_reg_8(struct device *dev, + u8 reg_address, + u8 val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16260_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16260_WRITE_REG(reg_address); + st->tx[1] = val; + + ret = spi_write(st->us, st->tx, 2); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16260_spi_write_reg_16() - write 2 bytes to a pair of registers + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: value to be written + **/ +static int adis16260_spi_write_reg_16(struct device *dev, + u8 lower_reg_address, + u16 value) +{ + int ret; + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16260_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 20, + }, { + .tx_buf = st->tx + 2, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 20, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16260_WRITE_REG(lower_reg_address); + st->tx[1] = value & 0xFF; + st->tx[2] = ADIS16260_WRITE_REG(lower_reg_address + 1); + st->tx[3] = (value >> 8) & 0xFF; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16260_spi_read_reg_16() - read 2 bytes from a 16-bit register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: somewhere to pass back the value read + **/ +static int adis16260_spi_read_reg_16(struct device *dev, + u8 lower_reg_address, + u16 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16260_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 30, + }, { + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 30, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16260_READ_REG(lower_reg_address); + st->tx[1] = 0; + st->tx[2] = 0; + st->tx[3] = 0; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, + "problem when reading 16 bit register 0x%02X", + lower_reg_address); + goto error_ret; + } + *val = (st->rx[0] << 8) | st->rx[1]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static ssize_t adis16260_spi_read_signed(struct device *dev, + struct device_attribute *attr, + char *buf, + unsigned bits) +{ + int ret; + s16 val = 0; + unsigned shift = 16 - bits; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = adis16260_spi_read_reg_16(dev, this_attr->address, (u16 *)&val); + if (ret) + return ret; + + if (val & ADIS16260_ERROR_ACTIVE) + adis16260_check_status(dev); + val = ((s16)(val << shift) >> shift); + return sprintf(buf, "%d\n", val); +} + +static ssize_t adis16260_read_12bit_unsigned(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u16 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = adis16260_spi_read_reg_16(dev, this_attr->address, &val); + if (ret) + return ret; + + if (val & ADIS16260_ERROR_ACTIVE) + adis16260_check_status(dev); + + return sprintf(buf, "%u\n", val & 0x0FFF); +} + +static ssize_t adis16260_read_12bit_signed(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + ssize_t ret; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + ret = adis16260_spi_read_signed(dev, attr, buf, 12); + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t adis16260_read_14bit_signed(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + ssize_t ret; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + ret = adis16260_spi_read_signed(dev, attr, buf, 14); + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t adis16260_write_16bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = adis16260_spi_write_reg_16(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static ssize_t adis16260_read_frequency(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret, len = 0; + u16 t; + int sps; + ret = adis16260_spi_read_reg_16(dev, + ADIS16260_SMPL_PRD, + &t); + if (ret) + return ret; + sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 66 : 2048; + sps /= (t & ADIS16260_SMPL_PRD_DIV_MASK) + 1; + len = sprintf(buf, "%d SPS\n", sps); + return len; +} + +static ssize_t adis16260_write_frequency(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16260_state *st = iio_dev_get_devdata(indio_dev); + long val; + int ret; + u8 t; + + ret = strict_strtol(buf, 10, &val); + if (ret) + return ret; + + mutex_lock(&indio_dev->mlock); + + t = (2048 / val); + if (t > 0) + t--; + t &= ADIS16260_SMPL_PRD_DIV_MASK; + if ((t & ADIS16260_SMPL_PRD_DIV_MASK) >= 0x0A) + st->us->max_speed_hz = ADIS16260_SPI_SLOW; + else + st->us->max_speed_hz = ADIS16260_SPI_FAST; + + ret = adis16260_spi_write_reg_8(dev, + ADIS16260_SMPL_PRD, + t); + + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +static int adis16260_reset(struct device *dev) +{ + int ret; + ret = adis16260_spi_write_reg_8(dev, + ADIS16260_GLOB_CMD, + ADIS16260_GLOB_CMD_SW_RESET); + if (ret) + dev_err(dev, "problem resetting device"); + + return ret; +} + +static ssize_t adis16260_write_reset(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + if (len < 1) + return -EINVAL; + switch (buf[0]) { + case '1': + case 'y': + case 'Y': + return adis16260_reset(dev); + } + return -EINVAL; +} + +int adis16260_set_irq(struct device *dev, bool enable) +{ + int ret; + u16 msc; + ret = adis16260_spi_read_reg_16(dev, ADIS16260_MSC_CTRL, &msc); + if (ret) + goto error_ret; + + msc |= ADIS16260_MSC_CTRL_DATA_RDY_POL_HIGH; + if (enable) + msc |= ADIS16260_MSC_CTRL_DATA_RDY_EN; + else + msc &= ~ADIS16260_MSC_CTRL_DATA_RDY_EN; + + ret = adis16260_spi_write_reg_16(dev, ADIS16260_MSC_CTRL, msc); + if (ret) + goto error_ret; + +error_ret: + return ret; +} + +/* Power down the device */ +static int adis16260_stop_device(struct device *dev) +{ + int ret; + u16 val = ADIS16260_SLP_CNT_POWER_OFF; + + ret = adis16260_spi_write_reg_16(dev, ADIS16260_SLP_CNT, val); + if (ret) + dev_err(dev, "problem with turning device off: SLP_CNT"); + + return ret; +} + +static int adis16260_self_test(struct device *dev) +{ + int ret; + ret = adis16260_spi_write_reg_16(dev, + ADIS16260_MSC_CTRL, + ADIS16260_MSC_CTRL_MEM_TEST); + if (ret) { + dev_err(dev, "problem starting self test"); + goto err_ret; + } + + adis16260_check_status(dev); + +err_ret: + return ret; +} + +static int adis16260_check_status(struct device *dev) +{ + u16 status; + int ret; + + ret = adis16260_spi_read_reg_16(dev, ADIS16260_DIAG_STAT, &status); + + if (ret < 0) { + dev_err(dev, "Reading status failed\n"); + goto error_ret; + } + ret = status & 0x7F; + if (status & ADIS16260_DIAG_STAT_FLASH_CHK) + dev_err(dev, "Flash checksum error\n"); + if (status & ADIS16260_DIAG_STAT_SELF_TEST) + dev_err(dev, "Self test error\n"); + if (status & ADIS16260_DIAG_STAT_OVERFLOW) + dev_err(dev, "Sensor overrange\n"); + if (status & ADIS16260_DIAG_STAT_SPI_FAIL) + dev_err(dev, "SPI failure\n"); + if (status & ADIS16260_DIAG_STAT_FLASH_UPT) + dev_err(dev, "Flash update failed\n"); + if (status & ADIS16260_DIAG_STAT_POWER_HIGH) + dev_err(dev, "Power supply above 5.25V\n"); + if (status & ADIS16260_DIAG_STAT_POWER_LOW) + dev_err(dev, "Power supply below 4.75V\n"); + +error_ret: + return ret; +} + +static int adis16260_initial_setup(struct adis16260_state *st) +{ + int ret; + struct device *dev = &st->indio_dev->dev; + + /* Disable IRQ */ + ret = adis16260_set_irq(dev, false); + if (ret) { + dev_err(dev, "disable irq failed"); + goto err_ret; + } + + /* Do self test */ + ret = adis16260_self_test(dev); + if (ret) { + dev_err(dev, "self test failure"); + goto err_ret; + } + + /* Read status register to check the result */ + ret = adis16260_check_status(dev); + if (ret) { + adis16260_reset(dev); + dev_err(dev, "device not playing ball -> reset"); + msleep(ADIS16260_STARTUP_DELAY); + ret = adis16260_check_status(dev); + if (ret) { + dev_err(dev, "giving up"); + goto err_ret; + } + } + + printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n", + st->us->chip_select, st->us->irq); + +err_ret: + return ret; +} + +static IIO_DEV_ATTR_IN_NAMED_RAW(supply, + adis16260_read_12bit_unsigned, + ADIS16260_SUPPLY_OUT); +static IIO_CONST_ATTR(in_supply_scale, "0.0018315"); + +static IIO_DEV_ATTR_GYRO(adis16260_read_14bit_signed, + ADIS16260_GYRO_OUT); +static IIO_DEV_ATTR_GYRO_SCALE(S_IWUSR | S_IRUGO, + adis16260_read_14bit_signed, + adis16260_write_16bit, + ADIS16260_GYRO_SCALE); +static IIO_DEV_ATTR_GYRO_OFFSET(S_IWUSR | S_IRUGO, + adis16260_read_12bit_signed, + adis16260_write_16bit, + ADIS16260_GYRO_OFF); + +static IIO_DEV_ATTR_TEMP_RAW(adis16260_read_12bit_unsigned); +static IIO_CONST_ATTR(temp_offset, "25"); +static IIO_CONST_ATTR(temp_scale, "0.1453"); + +static IIO_DEV_ATTR_IN_RAW(0, adis16260_read_12bit_unsigned, + ADIS16260_AUX_ADC); +static IIO_CONST_ATTR(in0_scale, "0.0006105"); + +static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, + adis16260_read_frequency, + adis16260_write_frequency); +static IIO_DEV_ATTR_ANGL(adis16260_read_14bit_signed, + ADIS16260_ANGL_OUT); + +static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16260_write_reset, 0); + +static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("256 2048"); + +static IIO_CONST_ATTR(name, "adis16260"); + +static struct attribute *adis16260_event_attributes[] = { + NULL +}; + +static struct attribute_group adis16260_event_attribute_group = { + .attrs = adis16260_event_attributes, +}; + +static struct attribute *adis16260_attributes[] = { + &iio_dev_attr_in_supply_raw.dev_attr.attr, + &iio_const_attr_in_supply_scale.dev_attr.attr, + &iio_dev_attr_gyro_raw.dev_attr.attr, + &iio_dev_attr_gyro_scale.dev_attr.attr, + &iio_dev_attr_gyro_offset.dev_attr.attr, + &iio_dev_attr_angl_raw.dev_attr.attr, + &iio_dev_attr_temp_raw.dev_attr.attr, + &iio_const_attr_temp_offset.dev_attr.attr, + &iio_const_attr_temp_scale.dev_attr.attr, + &iio_dev_attr_in0_raw.dev_attr.attr, + &iio_const_attr_in0_scale.dev_attr.attr, + &iio_dev_attr_sampling_frequency.dev_attr.attr, + &iio_const_attr_available_sampling_frequency.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_const_attr_name.dev_attr.attr, + NULL +}; + +static const struct attribute_group adis16260_attribute_group = { + .attrs = adis16260_attributes, +}; + +static int __devinit adis16260_probe(struct spi_device *spi) +{ + int ret, regdone = 0; + struct adis16260_state *st = kzalloc(sizeof *st, GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + goto error_ret; + } + /* this is only used for removal purposes */ + spi_set_drvdata(spi, st); + + /* Allocate the comms buffers */ + st->rx = kzalloc(sizeof(*st->rx)*ADIS16260_MAX_RX, GFP_KERNEL); + if (st->rx == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->tx = kzalloc(sizeof(*st->tx)*ADIS16260_MAX_TX, GFP_KERNEL); + if (st->tx == NULL) { + ret = -ENOMEM; + goto error_free_rx; + } + st->us = spi; + mutex_init(&st->buf_lock); + /* setup the industrialio driver allocated elements */ + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_tx; + } + + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->num_interrupt_lines = 1; + st->indio_dev->event_attrs = &adis16260_event_attribute_group; + st->indio_dev->attrs = &adis16260_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = adis16260_configure_ring(st->indio_dev); + if (ret) + goto error_free_dev; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_unreg_ring_funcs; + regdone = 1; + + ret = adis16260_initialize_ring(st->indio_dev->ring); + if (ret) { + printk(KERN_ERR "failed to initialize the ring\n"); + goto error_unreg_ring_funcs; + } + + if (spi->irq) { + ret = iio_register_interrupt_line(spi->irq, + st->indio_dev, + 0, + IRQF_TRIGGER_RISING, + "adis16260"); + if (ret) + goto error_uninitialize_ring; + + ret = adis16260_probe_trigger(st->indio_dev); + if (ret) + goto error_unregister_line; + } + + /* Get the device into a sane initial state */ + ret = adis16260_initial_setup(st); + if (ret) + goto error_remove_trigger; + return 0; + +error_remove_trigger: + adis16260_remove_trigger(st->indio_dev); +error_unregister_line: + if (spi->irq) + iio_unregister_interrupt_line(st->indio_dev, 0); +error_uninitialize_ring: + adis16260_uninitialize_ring(st->indio_dev->ring); +error_unreg_ring_funcs: + adis16260_unconfigure_ring(st->indio_dev); +error_free_dev: + if (regdone) + iio_device_unregister(st->indio_dev); + else + iio_free_device(st->indio_dev); +error_free_tx: + kfree(st->tx); +error_free_rx: + kfree(st->rx); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +static int adis16260_remove(struct spi_device *spi) +{ + int ret; + struct adis16260_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + + ret = adis16260_stop_device(&(indio_dev->dev)); + if (ret) + goto err_ret; + + flush_scheduled_work(); + + adis16260_remove_trigger(indio_dev); + if (spi->irq) + iio_unregister_interrupt_line(indio_dev, 0); + + adis16260_uninitialize_ring(indio_dev->ring); + iio_device_unregister(indio_dev); + adis16260_unconfigure_ring(indio_dev); + kfree(st->tx); + kfree(st->rx); + kfree(st); + + return 0; + +err_ret: + return ret; +} + +static struct spi_driver adis16260_driver = { + .driver = { + .name = "adis16260", + .owner = THIS_MODULE, + }, + .probe = adis16260_probe, + .remove = __devexit_p(adis16260_remove), +}; + +static __init int adis16260_init(void) +{ + return spi_register_driver(&adis16260_driver); +} +module_init(adis16260_init); + +static __exit void adis16260_exit(void) +{ + spi_unregister_driver(&adis16260_driver); +} +module_exit(adis16260_exit); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADIS16260/5 Digital Gyroscope Sensor"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c new file mode 100644 index 000000000000..4c4390ca6d73 --- /dev/null +++ b/drivers/staging/iio/gyro/adis16260_ring.c @@ -0,0 +1,256 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../ring_sw.h" +#include "../accel/accel.h" +#include "../trigger.h" +#include "adis16260.h" + +/** + * combine_8_to_16() utility function to munge to u8s into u16 + **/ +static inline u16 combine_8_to_16(u8 lower, u8 upper) +{ + u16 _lower = lower; + u16 _upper = upper; + return _lower | (_upper << 8); +} + +static IIO_SCAN_EL_C(supply, ADIS16260_SCAN_SUPPLY, IIO_UNSIGNED(12), + ADIS16260_SUPPLY_OUT, NULL); +static IIO_SCAN_EL_C(gyro, ADIS16260_SCAN_GYRO, IIO_SIGNED(14), + ADIS16260_GYRO_OUT, NULL); +static IIO_SCAN_EL_C(aux_adc, ADIS16260_SCAN_AUX_ADC, IIO_SIGNED(14), + ADIS16260_AUX_ADC, NULL); +static IIO_SCAN_EL_C(temp, ADIS16260_SCAN_TEMP, IIO_UNSIGNED(12), + ADIS16260_TEMP_OUT, NULL); +static IIO_SCAN_EL_C(angl, ADIS16260_SCAN_ANGL, IIO_UNSIGNED(12), + ADIS16260_ANGL_OUT, NULL); + +static IIO_SCAN_EL_TIMESTAMP(5); + +static struct attribute *adis16260_scan_el_attrs[] = { + &iio_scan_el_supply.dev_attr.attr, + &iio_scan_el_gyro.dev_attr.attr, + &iio_scan_el_aux_adc.dev_attr.attr, + &iio_scan_el_temp.dev_attr.attr, + &iio_scan_el_angl.dev_attr.attr, + &iio_scan_el_timestamp.dev_attr.attr, + NULL, +}; + +static struct attribute_group adis16260_scan_el_group = { + .attrs = adis16260_scan_el_attrs, + .name = "scan_elements", +}; + +/** + * adis16260_poll_func_th() top half interrupt handler called by trigger + * @private_data: iio_dev + **/ +static void adis16260_poll_func_th(struct iio_dev *indio_dev) +{ + struct adis16260_state *st = iio_dev_get_devdata(indio_dev); + st->last_timestamp = indio_dev->trig->timestamp; + schedule_work(&st->work_trigger_to_ring); +} + +/** + * adis16260_read_ring_data() read data registers which will be placed into ring + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @rx: somewhere to pass back the value read + **/ +static int adis16260_read_ring_data(struct device *dev, u8 *rx) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16260_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[ADIS16260_OUTPUTS + 1]; + int ret; + int i; + + mutex_lock(&st->buf_lock); + + spi_message_init(&msg); + + memset(xfers, 0, sizeof(xfers)); + for (i = 0; i <= ADIS16260_OUTPUTS; i++) { + xfers[i].bits_per_word = 8; + xfers[i].cs_change = 1; + xfers[i].len = 2; + xfers[i].delay_usecs = 30; + xfers[i].tx_buf = st->tx + 2 * i; + if (i < 2) /* SUPPLY_OUT:0x02 GYRO_OUT:0x04 */ + st->tx[2 * i] + = ADIS16260_READ_REG(ADIS16260_SUPPLY_OUT + + 2 * i); + else /* 0x06 to 0x09 is reserved */ + st->tx[2 * i] + = ADIS16260_READ_REG(ADIS16260_SUPPLY_OUT + + 2 * i + 4); + st->tx[2 * i + 1] = 0; + if (i >= 1) + xfers[i].rx_buf = rx + 2 * (i - 1); + spi_message_add_tail(&xfers[i], &msg); + } + + ret = spi_sync(st->us, &msg); + if (ret) + dev_err(&st->us->dev, "problem when burst reading"); + + mutex_unlock(&st->buf_lock); + + return ret; +} + + +static void adis16260_trigger_bh_to_ring(struct work_struct *work_s) +{ + struct adis16260_state *st + = container_of(work_s, struct adis16260_state, + work_trigger_to_ring); + + int i = 0; + s16 *data; + size_t datasize = st->indio_dev + ->ring->access.get_bpd(st->indio_dev->ring); + + data = kmalloc(datasize , GFP_KERNEL); + if (data == NULL) { + dev_err(&st->us->dev, "memory alloc failed in ring bh"); + return; + } + + if (st->indio_dev->scan_count) + if (adis16260_read_ring_data(&st->indio_dev->dev, st->rx) >= 0) + for (; i < st->indio_dev->scan_count; i++) { + data[i] = combine_8_to_16(st->rx[i*2+1], + st->rx[i*2]); + } + + /* Guaranteed to be aligned with 8 byte boundary */ + if (st->indio_dev->scan_timestamp) + *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp; + + st->indio_dev->ring->access.store_to(st->indio_dev->ring, + (u8 *)data, + st->last_timestamp); + + iio_trigger_notify_done(st->indio_dev->trig); + kfree(data); + + return; +} + +static int adis16260_data_rdy_ring_preenable(struct iio_dev *indio_dev) +{ + size_t size; + dev_dbg(&indio_dev->dev, "%s\n", __func__); + /* Check if there are any scan elements enabled, if not fail*/ + if (!(indio_dev->scan_count || indio_dev->scan_timestamp)) + return -EINVAL; + + if (indio_dev->ring->access.set_bpd) { + if (indio_dev->scan_timestamp) + if (indio_dev->scan_count) + /* Timestamp (aligned s64) and data */ + size = (((indio_dev->scan_count * sizeof(s16)) + + sizeof(s64) - 1) + & ~(sizeof(s64) - 1)) + + sizeof(s64); + else /* Timestamp only */ + size = sizeof(s64); + else /* Data only */ + size = indio_dev->scan_count*sizeof(s16); + indio_dev->ring->access.set_bpd(indio_dev->ring, size); + } + + return 0; +} + +static int adis16260_data_rdy_ring_postenable(struct iio_dev *indio_dev) +{ + return indio_dev->trig + ? iio_trigger_attach_poll_func(indio_dev->trig, + indio_dev->pollfunc) + : 0; +} + +static int adis16260_data_rdy_ring_predisable(struct iio_dev *indio_dev) +{ + return indio_dev->trig + ? iio_trigger_dettach_poll_func(indio_dev->trig, + indio_dev->pollfunc) + : 0; +} + +void adis16260_unconfigure_ring(struct iio_dev *indio_dev) +{ + kfree(indio_dev->pollfunc); + iio_sw_rb_free(indio_dev->ring); +} + +int adis16260_configure_ring(struct iio_dev *indio_dev) +{ + int ret = 0; + struct adis16260_state *st = indio_dev->dev_data; + struct iio_ring_buffer *ring; + INIT_WORK(&st->work_trigger_to_ring, adis16260_trigger_bh_to_ring); + /* Set default scan mode */ + + iio_scan_mask_set(indio_dev, iio_scan_el_supply.number); + iio_scan_mask_set(indio_dev, iio_scan_el_gyro.number); + iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number); + iio_scan_mask_set(indio_dev, iio_scan_el_temp.number); + iio_scan_mask_set(indio_dev, iio_scan_el_angl.number); + indio_dev->scan_timestamp = true; + + indio_dev->scan_el_attrs = &adis16260_scan_el_group; + + ring = iio_sw_rb_allocate(indio_dev); + if (!ring) { + ret = -ENOMEM; + return ret; + } + indio_dev->ring = ring; + /* Effectively select the ring buffer implementation */ + iio_ring_sw_register_funcs(&ring->access); + ring->preenable = &adis16260_data_rdy_ring_preenable; + ring->postenable = &adis16260_data_rdy_ring_postenable; + ring->predisable = &adis16260_data_rdy_ring_predisable; + ring->owner = THIS_MODULE; + + indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL); + if (indio_dev->pollfunc == NULL) { + ret = -ENOMEM; + goto error_iio_sw_rb_free;; + } + indio_dev->pollfunc->poll_func_main = &adis16260_poll_func_th; + indio_dev->pollfunc->private_data = indio_dev; + indio_dev->modes |= INDIO_RING_TRIGGERED; + return 0; + +error_iio_sw_rb_free: + iio_sw_rb_free(indio_dev->ring); + return ret; +} + +int adis16260_initialize_ring(struct iio_ring_buffer *ring) +{ + return iio_ring_buffer_register(ring, 0); +} + +void adis16260_uninitialize_ring(struct iio_ring_buffer *ring) +{ + iio_ring_buffer_unregister(ring); +} diff --git a/drivers/staging/iio/gyro/adis16260_trigger.c b/drivers/staging/iio/gyro/adis16260_trigger.c new file mode 100644 index 000000000000..b3c565942b8d --- /dev/null +++ b/drivers/staging/iio/gyro/adis16260_trigger.c @@ -0,0 +1,124 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../trigger.h" +#include "adis16260.h" + +/** + * adis16260_data_rdy_trig_poll() the event handler for the data rdy trig + **/ +static int adis16260_data_rdy_trig_poll(struct iio_dev *dev_info, + int index, + s64 timestamp, + int no_test) +{ + struct adis16260_state *st = iio_dev_get_devdata(dev_info); + struct iio_trigger *trig = st->trig; + + trig->timestamp = timestamp; + iio_trigger_poll(trig); + + return IRQ_HANDLED; +} + +IIO_EVENT_SH(data_rdy_trig, &adis16260_data_rdy_trig_poll); + +static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL); + +static struct attribute *adis16260_trigger_attrs[] = { + &dev_attr_name.attr, + NULL, +}; + +static const struct attribute_group adis16260_trigger_attr_group = { + .attrs = adis16260_trigger_attrs, +}; + +/** + * adis16260_data_rdy_trigger_set_state() set datardy interrupt state + **/ +static int adis16260_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct adis16260_state *st = trig->private_data; + struct iio_dev *indio_dev = st->indio_dev; + int ret = 0; + + dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); + ret = adis16260_set_irq(&st->indio_dev->dev, state); + if (state == false) { + iio_remove_event_from_list(&iio_event_data_rdy_trig, + &indio_dev->interrupts[0] + ->ev_list); + flush_scheduled_work(); + } else { + iio_add_event_to_list(&iio_event_data_rdy_trig, + &indio_dev->interrupts[0]->ev_list); + } + return ret; +} + +/** + * adis16260_trig_try_reen() try renabling irq for data rdy trigger + * @trig: the datardy trigger + **/ +static int adis16260_trig_try_reen(struct iio_trigger *trig) +{ + struct adis16260_state *st = trig->private_data; + enable_irq(st->us->irq); + return 0; +} + +int adis16260_probe_trigger(struct iio_dev *indio_dev) +{ + int ret; + struct adis16260_state *st = indio_dev->dev_data; + + st->trig = iio_allocate_trigger(); + st->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL); + if (!st->trig->name) { + ret = -ENOMEM; + goto error_free_trig; + } + snprintf((char *)st->trig->name, + IIO_TRIGGER_NAME_LENGTH, + "adis16260-dev%d", indio_dev->id); + st->trig->dev.parent = &st->us->dev; + st->trig->owner = THIS_MODULE; + st->trig->private_data = st; + st->trig->set_trigger_state = &adis16260_data_rdy_trigger_set_state; + st->trig->try_reenable = &adis16260_trig_try_reen; + st->trig->control_attrs = &adis16260_trigger_attr_group; + ret = iio_trigger_register(st->trig); + + /* select default trigger */ + indio_dev->trig = st->trig; + if (ret) + goto error_free_trig_name; + + return 0; + +error_free_trig_name: + kfree(st->trig->name); +error_free_trig: + iio_free_trigger(st->trig); + + return ret; +} + +void adis16260_remove_trigger(struct iio_dev *indio_dev) +{ + struct adis16260_state *state = indio_dev->dev_data; + + iio_trigger_unregister(state->trig); + kfree(state->trig->name); + iio_free_trigger(state->trig); +} diff --git a/drivers/staging/iio/gyro/gyro.h b/drivers/staging/iio/gyro/gyro.h index 16f6ffa039bb..f68edab8f30d 100644 --- a/drivers/staging/iio/gyro/gyro.h +++ b/drivers/staging/iio/gyro/gyro.h @@ -39,3 +39,5 @@ #define IIO_DEV_ATTR_GYRO_Z(_show, _addr) \ IIO_DEVICE_ATTR(gyro_z_raw, S_IRUGO, _show, NULL, _addr) +#define IIO_DEV_ATTR_ANGL(_show, _addr) \ + IIO_DEVICE_ATTR(angl_raw, S_IRUGO, _show, NULL, _addr) -- cgit v1.2.3 From e64354c0be3b7134c85571a525b2e37fc4a95eef Mon Sep 17 00:00:00 2001 From: Charles Clément Date: Wed, 12 May 2010 14:14:00 -0700 Subject: Staging: vt6655: remove HANDLE definition and use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles Clément Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/baseband.c | 4 +- drivers/staging/vt6655/baseband.h | 4 +- drivers/staging/vt6655/bssdb.c | 72 ++++++++++++++++++------------------ drivers/staging/vt6655/bssdb.h | 32 ++++++++-------- drivers/staging/vt6655/device_main.c | 24 ++++++------ drivers/staging/vt6655/dpc.c | 10 ++--- drivers/staging/vt6655/ioctl.c | 14 +++---- drivers/staging/vt6655/iwctl.c | 26 ++++++------- drivers/staging/vt6655/power.c | 12 +++--- drivers/staging/vt6655/power.h | 12 +++--- drivers/staging/vt6655/ttype.h | 2 - drivers/staging/vt6655/wcmd.c | 58 ++++++++++++++--------------- drivers/staging/vt6655/wcmd.h | 12 +++--- drivers/staging/vt6655/wmgr.c | 70 +++++++++++++++++------------------ drivers/staging/vt6655/wmgr.h | 30 +++++++-------- drivers/staging/vt6655/wpactl.c | 12 +++--- 16 files changed, 196 insertions(+), 198 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index 16d7db350bb3..7a69490fc7e5 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -2878,7 +2878,7 @@ BBvAntennaDiversity (PSDevice pDevice, BYTE byRxRate, BYTE bySQ3) void TimerSQ3CallBack ( - IN HANDLE hDeviceContext + IN void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -2926,7 +2926,7 @@ TimerSQ3CallBack ( void TimerState1CallBack ( - IN HANDLE hDeviceContext + IN void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index de9b84acd6a9..23f7ad151d16 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -162,12 +162,12 @@ void BBvExitDeepSleep(DWORD_PTR dwIoBase, BYTE byLocalID); void TimerSQ3CallBack ( - IN HANDLE hDeviceContext + IN void *hDeviceContext ); void TimerState1CallBack( - IN HANDLE hDeviceContext + IN void *hDeviceContext ); void BBvAntennaDiversity(PSDevice pDevice, BYTE byRxRate, BYTE bySQ3); diff --git a/drivers/staging/vt6655/bssdb.c b/drivers/staging/vt6655/bssdb.c index e7bbc56f0c85..3af0ccb25d06 100644 --- a/drivers/staging/vt6655/bssdb.c +++ b/drivers/staging/vt6655/bssdb.c @@ -91,18 +91,18 @@ const WORD awHWRetry1[5][5] = { /*--------------------- Static Functions --------------------------*/ void s_vCheckSensitivity( - IN HANDLE hDeviceContext + IN void *hDeviceContext ); #ifdef Calcu_LinkQual void s_uCalculateLinkQual( - IN HANDLE hDeviceContext + IN void *hDeviceContext ); #endif void s_vCheckPreEDThreshold( - IN HANDLE hDeviceContext + IN void *hDeviceContext ); /*--------------------- Export Variables --------------------------*/ @@ -125,7 +125,7 @@ void s_vCheckPreEDThreshold( PKnownBSS BSSpSearchBSSList( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PBYTE pbyDesireBSSID, IN PBYTE pbyDesireSSID, IN CARD_PHY_TYPE ePhyType @@ -282,7 +282,7 @@ if(pDevice->bLinkPass==FALSE) pCurrBSS->bSelected = FALSE; void BSSvClearBSSList( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN BOOL bKeepCurrBSSID ) { @@ -325,7 +325,7 @@ BSSvClearBSSList( -*/ PKnownBSS BSSpAddrIsInBSSList( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PBYTE abyBSSID, IN PWLAN_IE_SSID pSSID ) @@ -368,7 +368,7 @@ BSSpAddrIsInBSSList( BOOL BSSbInsertToBSSList ( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PBYTE abyBSSIDAddr, IN QWORD qwTimestamp, IN WORD wBeaconInterval, @@ -384,7 +384,7 @@ BSSbInsertToBSSList ( IN PWLAN_IE_QUIET pIE_Quiet, IN UINT uIELength, IN PBYTE pbyIEs, - IN HANDLE pRxPacketContext + IN void *pRxPacketContext ) { @@ -502,7 +502,7 @@ BSSbInsertToBSSList ( if ((bIs802_1x == TRUE) && (pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len) && ( !memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID, pSSID->len))) { - bAdd_PMKID_Candidate((HANDLE)pDevice, pBSSList->abyBSSID, &pBSSList->sRSNCapObj); + bAdd_PMKID_Candidate((void *)pDevice, pBSSList->abyBSSID, &pBSSList->sRSNCapObj); if ((pDevice->bLinkPass == TRUE) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { if ((KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, PAIRWISE_KEY, &pTransmitKey) == TRUE) || @@ -585,7 +585,7 @@ BSSbInsertToBSSList ( BOOL BSSbUpdateToBSSList ( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN QWORD qwTimestamp, IN WORD wBeaconInterval, IN WORD wCapInfo, @@ -602,7 +602,7 @@ BSSbUpdateToBSSList ( IN PKnownBSS pBSSList, IN UINT uIELength, IN PBYTE pbyIEs, - IN HANDLE pRxPacketContext + IN void *pRxPacketContext ) { int ii; @@ -799,7 +799,7 @@ BSSDBbIsSTAInNodeDB( -*/ void BSSvCreateOneNode( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, OUT PUINT puNodeIndex ) { @@ -864,7 +864,7 @@ BSSvCreateOneNode( -*/ void BSSvRemoveOneNode( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN UINT uNodeIndex ) { @@ -897,7 +897,7 @@ BSSvRemoveOneNode( void BSSvUpdateAPNode( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PWORD pwCapInfo, IN PWLAN_IE_SUPP_RATES pSuppRates, IN PWLAN_IE_SUPP_RATES pExtSuppRates @@ -960,7 +960,7 @@ BSSvUpdateAPNode( void BSSvAddMulticastNode( - IN HANDLE hDeviceContext + IN void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1013,7 +1013,7 @@ UINT status; #endif void BSSvSecondCallBack( - IN HANDLE hDeviceContext + IN void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1111,7 +1111,7 @@ start: } #ifdef Calcu_LinkQual - s_uCalculateLinkQual((HANDLE)pDevice); + s_uCalculateLinkQual((void *)pDevice); #endif for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) { @@ -1261,18 +1261,18 @@ start: if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS // DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Callback inactive Count = [%d]\n", pMgmt->sNodeDBTable[0].uInActiveCount); //if (pDevice->bUpdateBBVGA) { - // s_vCheckSensitivity((HANDLE) pDevice); + // s_vCheckSensitivity((void *) pDevice); //} if (pDevice->bUpdateBBVGA) { - // s_vCheckSensitivity((HANDLE) pDevice); - s_vCheckPreEDThreshold((HANDLE)pDevice); + // s_vCheckSensitivity((void *) pDevice); + s_vCheckPreEDThreshold((void *)pDevice); } if ((pMgmt->sNodeDBTable[0].uInActiveCount >= (LOST_BEACON_COUNT/2)) && (pDevice->byBBVGACurrent != pDevice->abyBBVGA[0]) ) { pDevice->byBBVGANew = pDevice->abyBBVGA[0]; - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL); } if (pMgmt->sNodeDBTable[0].uInActiveCount >= LOST_BEACON_COUNT) { @@ -1324,10 +1324,10 @@ start: pDevice->eEncryptionStatus = pDevice->eOldEncryptionStatus; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Roaming ...\n"); - BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass); + BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); pMgmt->eScanType = WMAC_SCAN_ACTIVE; - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); pDevice->uAutoReConnectTime = 0; } } @@ -1342,16 +1342,16 @@ start: else { DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Adhoc re-scaning ...\n"); pMgmt->eScanType = WMAC_SCAN_ACTIVE; - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); pDevice->uAutoReConnectTime = 0; }; } if (pMgmt->eCurrState == WMAC_STATE_JOINTED) { if (pDevice->bUpdateBBVGA) { - //s_vCheckSensitivity((HANDLE) pDevice); - s_vCheckPreEDThreshold((HANDLE)pDevice); + //s_vCheckSensitivity((void *) pDevice); + s_vCheckPreEDThreshold((void *)pDevice); } if (pMgmt->sNodeDBTable[0].uInActiveCount >=ADHOC_LOST_BEACON_COUNT) { DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost other STA beacon [%d] sec, started !\n", pMgmt->sNodeDBTable[0].uInActiveCount); @@ -1390,7 +1390,7 @@ start: void BSSvUpdateNodeTxCounter( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN BYTE byTsr0, IN BYTE byTsr1, IN PBYTE pbyBuffer, @@ -1503,7 +1503,7 @@ BSSvUpdateNodeTxCounter( pMACHeader = (PS802_11Header)(pbyBuffer + uFIFOHeaderSize); - if (BSSDBbIsSTAInNodeDB((HANDLE)pMgmt, &(pMACHeader->abyAddr1[0]), &uNodeIndex)){ + if (BSSDBbIsSTAInNodeDB((void *)pMgmt, &(pMACHeader->abyAddr1[0]), &uNodeIndex)){ pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts += 1; if ((byTsr1 & TSR1_TERR) == 0) { // transmit success, TxAttempts at least plus one @@ -1583,7 +1583,7 @@ BSSvUpdateNodeTxCounter( void BSSvClearNodeDBTable( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN UINT uStartIndex ) @@ -1611,7 +1611,7 @@ BSSvClearNodeDBTable( void s_vCheckSensitivity( - IN HANDLE hDeviceContext + IN void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1649,7 +1649,7 @@ void s_vCheckSensitivity( if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) { pDevice->uBBVGADiffCount++; if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL); } else { pDevice->uBBVGADiffCount = 0; } @@ -1661,7 +1661,7 @@ void s_vCheckSensitivity( void BSSvClearAnyBSSJoinRecord ( - IN HANDLE hDeviceContext + IN void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1676,7 +1676,7 @@ BSSvClearAnyBSSJoinRecord ( #ifdef Calcu_LinkQual void s_uCalculateLinkQual( - IN HANDLE hDeviceContext + IN void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1724,7 +1724,7 @@ else #endif void s_vCheckPreEDThreshold( - IN HANDLE hDeviceContext + IN void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; diff --git a/drivers/staging/vt6655/bssdb.h b/drivers/staging/vt6655/bssdb.h index 86a1f6732902..a66e14f0a825 100644 --- a/drivers/staging/vt6655/bssdb.h +++ b/drivers/staging/vt6655/bssdb.h @@ -244,7 +244,7 @@ typedef struct tagKnownNodeDB { PKnownBSS BSSpSearchBSSList( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PBYTE pbyDesireBSSID, IN PBYTE pbyDesireSSID, IN CARD_PHY_TYPE ePhyType @@ -252,20 +252,20 @@ BSSpSearchBSSList( PKnownBSS BSSpAddrIsInBSSList( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PBYTE abyBSSID, IN PWLAN_IE_SSID pSSID ); void BSSvClearBSSList( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN BOOL bKeepCurrBSSID ); BOOL BSSbInsertToBSSList( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PBYTE abyBSSIDAddr, IN QWORD qwTimestamp, IN WORD wBeaconInterval, @@ -281,13 +281,13 @@ BSSbInsertToBSSList( IN PWLAN_IE_QUIET pIE_Quiet, IN UINT uIELength, IN PBYTE pbyIEs, - IN HANDLE pRxPacketContext + IN void *pRxPacketContext ); BOOL BSSbUpdateToBSSList( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN QWORD qwTimestamp, IN WORD wBeaconInterval, IN WORD wCapInfo, @@ -304,26 +304,26 @@ BSSbUpdateToBSSList( IN PKnownBSS pBSSList, IN UINT uIELength, IN PBYTE pbyIEs, - IN HANDLE pRxPacketContext + IN void *pRxPacketContext ); BOOL BSSDBbIsSTAInNodeDB( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PBYTE abyDstAddr, OUT PUINT puNodeIndex ); void BSSvCreateOneNode( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, OUT PUINT puNodeIndex ); void BSSvUpdateAPNode( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PWORD pwCapInfo, IN PWLAN_IE_SUPP_RATES pItemRates, IN PWLAN_IE_SUPP_RATES pExtSuppRates @@ -332,13 +332,13 @@ BSSvUpdateAPNode( void BSSvSecondCallBack( - IN HANDLE hDeviceContext + IN void *hDeviceContext ); void BSSvUpdateNodeTxCounter( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN BYTE byTsr0, IN BYTE byTsr1, IN PBYTE pbyBuffer, @@ -347,25 +347,25 @@ BSSvUpdateNodeTxCounter( void BSSvRemoveOneNode( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN UINT uNodeIndex ); void BSSvAddMulticastNode( - IN HANDLE hDeviceContext + IN void *hDeviceContext ); void BSSvClearNodeDBTable( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN UINT uStartIndex ); void BSSvClearAnyBSSJoinRecord( - IN HANDLE hDeviceContext + IN void *hDeviceContext ); #endif //__BSSDB_H__ diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index f690fc2c35c1..454277b96eea 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -2011,11 +2011,11 @@ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call MACvIntEnable\n"); MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); if (pDevice->pMgmt->eConfigMode == WMAC_CONFIG_AP) { - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RUN_AP, NULL); + bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL); } else { - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_BSSID_SCAN, NULL); - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_SSID, NULL); + bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, NULL); + bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL); } pDevice->flags |=DEVICE_FLAGS_OPENED; @@ -2034,7 +2034,7 @@ static int device_close(struct net_device *dev) { //PLICE_DEBUG<- //2007-1121-02by EinsnLiu if (pDevice->bLinkPass) { - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_DISASSOCIATE, NULL); + bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL); mdelay(30); } #ifdef TxInSleep @@ -2860,7 +2860,7 @@ static irqreturn_t device_intr(int irq, void *dev_instance) { pDevice->bBeaconSent = FALSE; if (pDevice->bEnablePSMode) { - PSbIsNextTBTTWakeUp((HANDLE)pDevice); + PSbIsNextTBTTWakeUp((void *)pDevice); }; if ((pDevice->eOPMode == OP_MODE_AP) || @@ -2893,7 +2893,7 @@ static irqreturn_t device_intr(int irq, void *dev_instance) { // check if mutltcast tx bufferring pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1; pMgmt->sNodeDBTable[0].bRxPSPoll = TRUE; - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL); + bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); } } } @@ -3549,7 +3549,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { netif_stop_queue(pDevice->dev); spin_lock_irq(&pDevice->lock); - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RUN_AP, NULL); + bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL); spin_unlock_irq(&pDevice->lock); } else { @@ -3563,8 +3563,8 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { pMgmt->eScanType = WMAC_SCAN_ACTIVE; if(pDevice->bWPASuppWextEnabled !=TRUE) #endif - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); spin_unlock_irq(&pDevice->lock); } pDevice->bCommit = FALSE; @@ -3719,9 +3719,9 @@ viawget_resume(struct pci_dev *pcid) init_timer(&pMgmt->sTimerSecondCallback); init_timer(&pDevice->sTimerCommand); MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); - BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, NULL); + BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); spin_unlock_irq(&pDevice->lock); } return 0; diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index ab13bdfc51be..d90104a1e6b2 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -631,13 +631,13 @@ device_receive_frame ( tasklet_schedule(&pDevice->RxMngWorkItem); #else //printk("RxMan\n"); - vMgrRxManagePacket((HANDLE)pDevice, pDevice->pMgmt, pRxPacket); + vMgrRxManagePacket((void *)pDevice, pDevice->pMgmt, pRxPacket); //tasklet_schedule(&pDevice->RxMngWorkItem); #endif #endif //PLICE_DEBUG<- - //vMgrRxManagePacket((HANDLE)pDevice, pDevice->pMgmt, pRxPacket); + //vMgrRxManagePacket((void *)pDevice, pDevice->pMgmt, pRxPacket); // hostap Deamon handle 802.11 management if (pDevice->bEnableHostapd) { skb->dev = pDevice->apdev; @@ -1087,7 +1087,7 @@ static BOOL s_bAPModeRxCtl ( // delcare received ps-poll event if (IS_CTL_PSPOLL(pbyFrame)) { pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = TRUE; - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL); + bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 1\n"); } else { @@ -1096,7 +1096,7 @@ static BOOL s_bAPModeRxCtl ( if (!IS_FC_POWERMGT(pbyFrame)) { pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = FALSE; pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = TRUE; - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL); + bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 2\n"); } } @@ -1112,7 +1112,7 @@ static BOOL s_bAPModeRxCtl ( if (pMgmt->sNodeDBTable[iSANodeIndex].wEnQueueCnt > 0) { pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = FALSE; pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = TRUE; - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL); + bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 3\n"); } diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c index 86439bb629f9..1bd819946b84 100644 --- a/drivers/staging/vt6655/ioctl.c +++ b/drivers/staging/vt6655/ioctl.c @@ -109,14 +109,14 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) { } spin_lock_irq(&pDevice->lock); if (memcmp(pMgmt->abyCurrBSSID, &abyNullAddr[0], 6) == 0) - BSSvClearBSSList((HANDLE)pDevice, FALSE); + BSSvClearBSSList((void *)pDevice, FALSE); else - BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass); + BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); if (pItemSSID->len != 0) - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); else - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); spin_unlock_irq(&pDevice->lock); break; @@ -223,8 +223,8 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) { netif_stop_queue(pDevice->dev); spin_lock_irq(&pDevice->lock); pMgmt->eCurrState = WMAC_STATE_IDLE; - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); spin_unlock_irq(&pDevice->lock); break; @@ -593,7 +593,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) { netif_stop_queue(pDevice->dev); spin_lock_irq(&pDevice->lock); - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RUN_AP, NULL); + bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL); spin_unlock_irq(&pDevice->lock); break; diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c index 7fa5842238b8..cf69034fc0f0 100644 --- a/drivers/staging/vt6655/iwctl.c +++ b/drivers/staging/vt6655/iwctl.c @@ -190,7 +190,7 @@ if(pDevice->byReAssocCount > 0) { //reject scan when re-associating! } spin_lock_irq(&pDevice->lock); - BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass); + BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); //mike add: active scan OR passive scan OR desire_ssid scan if(wrq->length == sizeof(struct iw_scan_req)) { @@ -208,7 +208,7 @@ if(pDevice->byReAssocCount > 0) { //reject scan when re-associating! pMgmt->eScanType = WMAC_SCAN_PASSIVE; PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n",((PWLAN_IE_SSID)abyScanSSID)->abySSID, ((PWLAN_IE_SSID)abyScanSSID)->len); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); spin_unlock_irq(&pDevice->lock); return 0; @@ -223,7 +223,7 @@ if(pDevice->byReAssocCount > 0) { //reject scan when re-associating! pMgmt->eScanType = WMAC_SCAN_PASSIVE; //printk("SIOCSIWSCAN:WLAN_CMD_BSSID_SCAN\n"); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); spin_unlock_irq(&pDevice->lock); return 0; @@ -897,10 +897,10 @@ if (pMgmt->eScanState == WMAC_IS_SCANNING) { if (pCurr == NULL){ PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n"); - vResetCommandTimer((HANDLE) pDevice); + vResetCommandTimer((void *) pDevice); pMgmt->eScanType = WMAC_SCAN_ACTIVE; - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); } else { //mike:to find out if that desired SSID is a hidden-ssid AP , // by means of judging if there are two same BSSID exist in list ? @@ -912,10 +912,10 @@ if (pMgmt->eScanState == WMAC_IS_SCANNING) { } if(uSameBssidNum >= 2) { //hit: desired AP is in hidden ssid mode!!! printk("SIOCSIWESSID:hidden ssid directly associate.......\n"); - vResetCommandTimer((HANDLE) pDevice); + vResetCommandTimer((void *) pDevice); pMgmt->eScanType = WMAC_SCAN_PASSIVE; //this scan type,you'll submit scan result! - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID); } } } @@ -1660,11 +1660,11 @@ int iwctl_siwpower(struct net_device *dev, } if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { pDevice->ePSMode = WMAC_POWER_FAST; - PSvEnablePowerSaving((HANDLE)pDevice, pMgmt->wListenInterval); + PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); } else if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) { pDevice->ePSMode = WMAC_POWER_FAST; - PSvEnablePowerSaving((HANDLE)pDevice, pMgmt->wListenInterval); + PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); } switch (wrq->flags & IW_POWER_MODE) { case IW_POWER_UNICAST_R: @@ -2096,7 +2096,7 @@ int iwctl_siwmlme(struct net_device *dev, switch(mlme->cmd){ case IW_MLME_DEAUTH: //this command seems to be not complete,please test it --einsnliu - //bScheduleCommand((HANDLE) pDevice, WLAN_CMD_DEAUTH, (PBYTE)&reason); + //bScheduleCommand((void *) pDevice, WLAN_CMD_DEAUTH, (PBYTE)&reason); break; case IW_MLME_DISASSOC: if(pDevice->bLinkPass == TRUE){ @@ -2104,7 +2104,7 @@ int iwctl_siwmlme(struct net_device *dev, //clear related flags memset(pMgmt->abyDesireBSSID, 0xFF,6); KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_DISASSOCIATE, NULL); + bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL); } break; default: diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c index a28d03762e4e..166e7fb638c4 100644 --- a/drivers/staging/vt6655/power.c +++ b/drivers/staging/vt6655/power.c @@ -76,7 +76,7 @@ static int msglevel =MSG_LEVEL_INFO; void PSvEnablePowerSaving( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN WORD wListenInterval ) { @@ -146,7 +146,7 @@ PSvEnablePowerSaving( void PSvDisablePowerSaving( - IN HANDLE hDeviceContext + IN void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -184,7 +184,7 @@ PSvDisablePowerSaving( BOOL PSbConsiderPowerDown( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN BOOL bCheckRxDMA, IN BOOL bCheckCountToWakeUp ) @@ -252,7 +252,7 @@ PSbConsiderPowerDown( void PSvSendPSPOLL( - IN HANDLE hDeviceContext + IN void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -298,7 +298,7 @@ PSvSendPSPOLL( -*/ BOOL PSbSendNullPacket( - IN HANDLE hDeviceContext + IN void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -384,7 +384,7 @@ PSbSendNullPacket( BOOL PSbIsNextTBTTWakeUp( - IN HANDLE hDeviceContext + IN void *hDeviceContext ) { diff --git a/drivers/staging/vt6655/power.h b/drivers/staging/vt6655/power.h index bac8b200d544..769e0d1acd2a 100644 --- a/drivers/staging/vt6655/power.h +++ b/drivers/staging/vt6655/power.h @@ -50,35 +50,35 @@ BOOL PSbConsiderPowerDown( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN BOOL bCheckRxDMA, IN BOOL bCheckCountToWakeUp ); void PSvDisablePowerSaving( - IN HANDLE hDeviceContext + IN void *hDeviceContext ); void PSvEnablePowerSaving( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN WORD wListenInterval ); void PSvSendPSPOLL( - IN HANDLE hDeviceContext + IN void *hDeviceContext ); BOOL PSbSendNullPacket( - IN HANDLE hDeviceContext + IN void *hDeviceContext ); BOOL PSbIsNextTBTTWakeUp( - IN HANDLE hDeviceContext + IN void *hDeviceContext ); #endif //__POWER_H__ diff --git a/drivers/staging/vt6655/ttype.h b/drivers/staging/vt6655/ttype.h index b71fe591005a..b2dff3a7b77b 100644 --- a/drivers/staging/vt6655/ttype.h +++ b/drivers/staging/vt6655/ttype.h @@ -132,6 +132,4 @@ typedef DWORD * PDWORD; typedef QWORD * PQWORD; -typedef void *HANDLE; - #endif // __TTYPE_H__ diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c index ec1036e983d0..6e460409f984 100644 --- a/drivers/staging/vt6655/wcmd.c +++ b/drivers/staging/vt6655/wcmd.c @@ -319,7 +319,7 @@ s_MgrMakeProbeRequest( void vCommandTimerWait( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN UINT MSecond ) { @@ -339,7 +339,7 @@ vCommandTimerWait( void vCommandTimer ( - IN HANDLE hDeviceContext + IN void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -382,7 +382,7 @@ vCommandTimer ( // wait all Data TD complete if (pDevice->iTDUsed[TYPE_AC0DMA] != 0){ spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((HANDLE)pDevice, 10); + vCommandTimerWait((void *)pDevice, 10); return; }; @@ -424,7 +424,7 @@ vCommandTimer ( pMgmt->abyScanBSSID[5] = 0xFF; pItemSSID->byElementID = WLAN_EID_SSID; // clear bssid list - // BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass); + // BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); pMgmt->eScanState = WMAC_IS_SCANNING; } @@ -453,11 +453,11 @@ vCommandTimer ( (pMgmt->uScanChannel < CB_MAX_CHANNEL_24G)) { s_vProbeChannel(pDevice); spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((HANDLE)pDevice, WCMD_ACTIVE_SCAN_TIME); + vCommandTimerWait((void *)pDevice, WCMD_ACTIVE_SCAN_TIME); return; } else { spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((HANDLE)pDevice, WCMD_PASSIVE_SCAN_TIME); + vCommandTimerWait((void *)pDevice, WCMD_PASSIVE_SCAN_TIME); return; } @@ -501,7 +501,7 @@ vCommandTimer ( } else { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send Disassociation Packet..\n"); // reason = 8 : disassoc because sta has left - vMgrDisassocBeginSta((HANDLE)pDevice, pMgmt, pMgmt->abyCurrBSSID, (8), &Status); + vMgrDisassocBeginSta((void *)pDevice, pMgmt, pMgmt->abyCurrBSSID, (8), &Status); pDevice->bLinkPass = FALSE; // unlock command busy pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; @@ -515,7 +515,7 @@ vCommandTimer ( pDevice->eCommandState = WLAN_DISASSOCIATE_WAIT; // wait all Control TD complete if (pDevice->iTDUsed[TYPE_TXDMA0] != 0){ - vCommandTimerWait((HANDLE)pDevice, 10); + vCommandTimerWait((void *)pDevice, 10); spin_unlock_irq(&pDevice->lock); return; }; @@ -528,7 +528,7 @@ vCommandTimer ( case WLAN_DISASSOCIATE_WAIT : // wait all Control TD complete if (pDevice->iTDUsed[TYPE_TXDMA0] != 0){ - vCommandTimerWait((HANDLE)pDevice, 10); + vCommandTimerWait((void *)pDevice, 10); spin_unlock_irq(&pDevice->lock); return; }; @@ -578,24 +578,24 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS // set initial state pMgmt->eCurrState = WMAC_STATE_IDLE; pMgmt->eCurrMode = WMAC_MODE_STANDBY; - PSvDisablePowerSaving((HANDLE)pDevice); + PSvDisablePowerSaving((void *)pDevice); BSSvClearNodeDBTable(pDevice, 0); - vMgrJoinBSSBegin((HANDLE)pDevice, &Status); + vMgrJoinBSSBegin((void *)pDevice, &Status); // if Infra mode if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED)) { // Call mgr to begin the deauthentication // reason = (3) beacuse sta has left ESS if (pMgmt->eCurrState>= WMAC_STATE_AUTH) { - vMgrDeAuthenBeginSta((HANDLE)pDevice, pMgmt, pMgmt->abyCurrBSSID, (3), &Status); + vMgrDeAuthenBeginSta((void *)pDevice, pMgmt, pMgmt->abyCurrBSSID, (3), &Status); } // Call mgr to begin the authentication - vMgrAuthenBeginSta((HANDLE)pDevice, pMgmt, &Status); + vMgrAuthenBeginSta((void *)pDevice, pMgmt, &Status); if (Status == CMD_STATUS_SUCCESS) { pDevice->byLinkWaitCount = 0; pDevice->eCommandState = WLAN_AUTHENTICATE_WAIT; - vCommandTimerWait((HANDLE)pDevice, AUTHENTICATE_TIMEOUT); + vCommandTimerWait((void *)pDevice, AUTHENTICATE_TIMEOUT); spin_unlock_irq(&pDevice->lock); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Set eCommandState = WLAN_AUTHENTICATE_WAIT\n"); return; @@ -615,7 +615,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS } else { // start own IBSS - vMgrCreateOwnIBSS((HANDLE)pDevice, &Status); + vMgrCreateOwnIBSS((void *)pDevice, &Status); if (Status != CMD_STATUS_SUCCESS){ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " WLAN_CMD_IBSS_CREATE fail ! \n"); }; @@ -627,7 +627,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA || pMgmt->eConfigMode == WMAC_CONFIG_AUTO) { // start own IBSS - vMgrCreateOwnIBSS((HANDLE)pDevice, &Status); + vMgrCreateOwnIBSS((void *)pDevice, &Status); if (Status != CMD_STATUS_SUCCESS){ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_IBSS_CREATE fail ! \n"); }; @@ -661,12 +661,12 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS // Call mgr to begin the association pDevice->byLinkWaitCount = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_AUTH\n"); - vMgrAssocBeginSta((HANDLE)pDevice, pMgmt, &Status); + vMgrAssocBeginSta((void *)pDevice, pMgmt, &Status); if (Status == CMD_STATUS_SUCCESS) { pDevice->byLinkWaitCount = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState = WLAN_ASSOCIATE_WAIT\n"); pDevice->eCommandState = WLAN_ASSOCIATE_WAIT; - vCommandTimerWait((HANDLE)pDevice, ASSOCIATE_TIMEOUT); + vCommandTimerWait((void *)pDevice, ASSOCIATE_TIMEOUT); spin_unlock_irq(&pDevice->lock); return; } @@ -679,7 +679,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS pDevice->byLinkWaitCount ++; printk("WLAN_AUTHENTICATE_WAIT:wait %d times!!\n",pDevice->byLinkWaitCount); spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((HANDLE)pDevice, AUTHENTICATE_TIMEOUT/2); + vCommandTimerWait((void *)pDevice, AUTHENTICATE_TIMEOUT/2); return; } pDevice->byLinkWaitCount = 0; @@ -702,7 +702,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS if (pMgmt->eCurrState == WMAC_STATE_ASSOC) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_ASSOC\n"); if (pDevice->ePSMode != WMAC_POWER_CAM) { - PSvEnablePowerSaving((HANDLE)pDevice, pMgmt->wListenInterval); + PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); } if (pMgmt->eAuthenMode >= WMAC_AUTH_WPA) { KeybRemoveAllKey(&(pDevice->sKey), pDevice->abyBSSID, pDevice->PortOffset); @@ -743,7 +743,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS pDevice->byLinkWaitCount ++; printk("WLAN_ASSOCIATE_WAIT:wait %d times!!\n",pDevice->byLinkWaitCount); spin_unlock_irq(&pDevice->lock); - vCommandTimerWait((HANDLE)pDevice, ASSOCIATE_TIMEOUT/2); + vCommandTimerWait((void *)pDevice, ASSOCIATE_TIMEOUT/2); return; } pDevice->byLinkWaitCount = 0; @@ -779,7 +779,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS pMgmt->eCurrState = WMAC_STATE_IDLE; pDevice->bFixRate = FALSE; - vMgrCreateOwnIBSS((HANDLE)pDevice, &Status); + vMgrCreateOwnIBSS((void *)pDevice, &Status); if (Status != CMD_STATUS_SUCCESS){ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " vMgrCreateOwnIBSS fail ! \n"); }; @@ -869,12 +869,12 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_CHECK_BBSENSITIVITY_START\n"); // wait all TD complete if (pDevice->iTDUsed[TYPE_AC0DMA] != 0){ - vCommandTimerWait((HANDLE)pDevice, 10); + vCommandTimerWait((void *)pDevice, 10); spin_unlock_irq(&pDevice->lock); return; } if (pDevice->iTDUsed[TYPE_TXDMA0] != 0){ - vCommandTimerWait((HANDLE)pDevice, 10); + vCommandTimerWait((void *)pDevice, 10); spin_unlock_irq(&pDevice->lock); return; } @@ -971,7 +971,7 @@ s_bCommandComplete ( } - vCommandTimerWait((HANDLE)pDevice, 0); + vCommandTimerWait((void *)pDevice, 0); } return TRUE; @@ -980,7 +980,7 @@ s_bCommandComplete ( BOOL bScheduleCommand ( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN CMD_CODE eCommand, IN PBYTE pbyItem0 ) @@ -1061,7 +1061,7 @@ BOOL bScheduleCommand ( * */ BOOL bClearBSSID_SCAN ( - IN HANDLE hDeviceContext + IN void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1083,7 +1083,7 @@ BOOL bClearBSSID_SCAN ( //mike add:reset command timer void vResetCommandTimer( - IN HANDLE hDeviceContext + IN void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1107,7 +1107,7 @@ vResetCommandTimer( #ifdef TxInSleep void BSSvSecondTxData( - IN HANDLE hDeviceContext + IN void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; diff --git a/drivers/staging/vt6655/wcmd.h b/drivers/staging/vt6655/wcmd.h index 1e8166962015..67b08f61edcc 100644 --- a/drivers/staging/vt6655/wcmd.h +++ b/drivers/staging/vt6655/wcmd.h @@ -111,34 +111,34 @@ typedef enum tagCMD_STATE { /*--------------------- Export Functions --------------------------*/ void vResetCommandTimer( - IN HANDLE hDeviceContext + IN void *hDeviceContext ); void vCommandTimer ( - IN HANDLE hDeviceContext + IN void *hDeviceContext ); BOOL bClearBSSID_SCAN( - IN HANDLE hDeviceContext + IN void *hDeviceContext ); BOOL bScheduleCommand( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN CMD_CODE eCommand, IN PBYTE pbyItem0 ); void vCommandTimerWait( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN UINT MSecond ); #ifdef TxInSleep void BSSvSecondTxData( - IN HANDLE hDeviceContext + IN void *hDeviceContext ); #endif diff --git a/drivers/staging/vt6655/wmgr.c b/drivers/staging/vt6655/wmgr.c index ed5342ba2613..614850a7b914 100644 --- a/drivers/staging/vt6655/wmgr.c +++ b/drivers/staging/vt6655/wmgr.c @@ -349,7 +349,7 @@ s_bCipherMatch ( void vMgrObjectInit( - IN HANDLE hDeviceContext + IN void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -368,7 +368,7 @@ vMgrObjectInit( pMgmt->byCSSPK = KEY_CTL_NONE; pMgmt->byCSSGK = KEY_CTL_NONE; pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI; - BSSvClearBSSList((HANDLE)pDevice, FALSE); + BSSvClearBSSList((void *)pDevice, FALSE); return; } @@ -385,7 +385,7 @@ vMgrObjectInit( void vMgrTimerInit( - IN HANDLE hDeviceContext + IN void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -433,7 +433,7 @@ vMgrTimerInit( void vMgrObjectReset( - IN HANDLE hDeviceContext + IN void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -462,7 +462,7 @@ vMgrObjectReset( void vMgrAssocBeginSta( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ) @@ -538,7 +538,7 @@ vMgrAssocBeginSta( void vMgrReAssocBeginSta( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ) @@ -617,7 +617,7 @@ vMgrReAssocBeginSta( void vMgrDisassocBeginSta( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PSMgmtObject pMgmt, IN PBYTE abyDestAddress, IN WORD wReason, @@ -1041,7 +1041,7 @@ s_vMgrRxAssocResponse( }; DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Association Successful, AID=%d.\n", pMgmt->wCurrAID & ~(BIT14|BIT15)); pMgmt->eCurrState = WMAC_STATE_ASSOC; - BSSvUpdateAPNode((HANDLE)pDevice, sFrame.pwCapInfo, sFrame.pSuppRates, sFrame.pExtSuppRates); + BSSvUpdateAPNode((void *)pDevice, sFrame.pwCapInfo, sFrame.pSuppRates, sFrame.pExtSuppRates); pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Link with AP(SSID): %s\n", pItemSSID->abySSID); pDevice->bLinkPass = TRUE; @@ -1152,7 +1152,7 @@ if(pMgmt->eCurrState == WMAC_STATE_ASSOC) void vMgrAuthenBeginSta( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ) @@ -1210,7 +1210,7 @@ vMgrAuthenBeginSta( void vMgrDeAuthenBeginSta( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PSMgmtObject pMgmt, IN PBYTE abyDestAddress, IN WORD wReason, @@ -1455,7 +1455,7 @@ s_vMgrRxAuthenSequence_2( } if (pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT ) { // spin_unlock_irq(&pDevice->lock); -// vCommandTimerWait((HANDLE)pDevice, 0); +// vCommandTimerWait((void *)pDevice, 0); // spin_lock_irq(&pDevice->lock); } @@ -1502,7 +1502,7 @@ s_vMgrRxAuthenSequence_2( DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:rx Auth_reply sequence_2 status error ...\n"); if ( pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT ) { // spin_unlock_irq(&pDevice->lock); -// vCommandTimerWait((HANDLE)pDevice, 0); +// vCommandTimerWait((void *)pDevice, 0); // spin_lock_irq(&pDevice->lock); } s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus)))); @@ -1640,7 +1640,7 @@ s_vMgrRxAuthenSequence_4( if ( pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT ) { // spin_unlock_irq(&pDevice->lock); -// vCommandTimerWait((HANDLE)pDevice, 0); +// vCommandTimerWait((void *)pDevice, 0); // spin_lock_irq(&pDevice->lock); } @@ -1943,10 +1943,10 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) sERP.byERP = 0; } - pBSSList = BSSpAddrIsInBSSList((HANDLE)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID); + pBSSList = BSSpAddrIsInBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID); if (pBSSList == NULL) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Beacon/insert: RxChannel = : %d\n", byCurrChannel); - BSSbInsertToBSSList((HANDLE)pDevice, + BSSbInsertToBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, *sFrame.pqwTimestamp, *sFrame.pwBeaconInterval, @@ -1962,12 +1962,12 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) sFrame.pIE_Quiet, sFrame.len - WLAN_HDR_ADDR3_LEN, sFrame.pHdr->sA4.abyAddr4, // payload of beacon - (HANDLE)pRxPacket + (void *)pRxPacket ); } else { // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"update bcn: RxChannel = : %d\n", byCurrChannel); - BSSbUpdateToBSSList((HANDLE)pDevice, + BSSbUpdateToBSSList((void *)pDevice, *sFrame.pqwTimestamp, *sFrame.pwBeaconInterval, *sFrame.pwCapInfo, @@ -1984,7 +1984,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) pBSSList, sFrame.len - WLAN_HDR_ADDR3_LEN, sFrame.pHdr->sA4.abyAddr4, // payload of probresponse - (HANDLE)pRxPacket + (void *)pRxPacket ); } @@ -2353,7 +2353,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) // set highest basic rate // s_vSetHighestBasicRate(pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates); // Prepare beacon frame - bMgrPrepareBeaconToSend((HANDLE)pDevice, pMgmt); + bMgrPrepareBeaconToSend((void *)pDevice, pMgmt); // } }; } @@ -2386,7 +2386,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) -*/ void vMgrCreateOwnIBSS( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, OUT PCMD_STATUS pStatus ) { @@ -2629,7 +2629,7 @@ vMgrCreateOwnIBSS( pMgmt->eCurrState = WMAC_STATE_STARTED; // Prepare beacon to send - if (bMgrPrepareBeaconToSend((HANDLE)pDevice, pMgmt)) { + if (bMgrPrepareBeaconToSend((void *)pDevice, pMgmt)) { *pStatus = CMD_STATUS_SUCCESS; } @@ -2653,7 +2653,7 @@ vMgrCreateOwnIBSS( void vMgrJoinBSSBegin( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, OUT PCMD_STATUS pStatus ) { @@ -2802,12 +2802,12 @@ vMgrJoinBSSBegin( // Add current BSS to Candidate list // This should only works for WPA2 BSS, and WPA2 BSS check must be done before. if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) { - BOOL bResult = bAdd_PMKID_Candidate((HANDLE)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj); + BOOL bResult = bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate: 1(%d)\n", bResult); if (bResult == FALSE) { - vFlush_PMKID_Candidate((HANDLE)pDevice); + vFlush_PMKID_Candidate((void *)pDevice); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFlush_PMKID_Candidate: 4\n"); - bAdd_PMKID_Candidate((HANDLE)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj); + bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj); } } @@ -2898,7 +2898,7 @@ vMgrJoinBSSBegin( // and if registry setting is short preamble we can turn on too. // Prepare beacon - bMgrPrepareBeaconToSend((HANDLE)pDevice, pMgmt); + bMgrPrepareBeaconToSend((void *)pDevice, pMgmt); } else { pMgmt->eCurrState = WMAC_STATE_IDLE; @@ -4378,9 +4378,9 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) // update or insert the bss - pBSSList = BSSpAddrIsInBSSList((HANDLE)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID); + pBSSList = BSSpAddrIsInBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID); if (pBSSList) { - BSSbUpdateToBSSList((HANDLE)pDevice, + BSSbUpdateToBSSList((void *)pDevice, *sFrame.pqwTimestamp, *sFrame.pwBeaconInterval, *sFrame.pwCapInfo, @@ -4397,12 +4397,12 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) pBSSList, sFrame.len - WLAN_HDR_ADDR3_LEN, sFrame.pHdr->sA4.abyAddr4, // payload of probresponse - (HANDLE)pRxPacket + (void *)pRxPacket ); } else { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Probe resp/insert: RxChannel = : %d\n", byCurrChannel); - BSSbInsertToBSSList((HANDLE)pDevice, + BSSbInsertToBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, *sFrame.pqwTimestamp, *sFrame.pwBeaconInterval, @@ -4418,7 +4418,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) sFrame.pIE_Quiet, sFrame.len - WLAN_HDR_ADDR3_LEN, sFrame.pHdr->sA4.abyAddr4, // payload of beacon - (HANDLE)pRxPacket + (void *)pRxPacket ); } return; @@ -4536,7 +4536,7 @@ s_vMgrRxProbeRequest( void vMgrRxManagePacket( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PSMgmtObject pMgmt, IN PSRxMgmtPacket pRxPacket ) @@ -4685,7 +4685,7 @@ vMgrRxManagePacket( -*/ BOOL bMgrPrepareBeaconToSend( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PSMgmtObject pMgmt ) { @@ -4809,7 +4809,7 @@ s_vMgrLogStatus( -*/ BOOL bAdd_PMKID_Candidate ( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PBYTE pbyBSSID, IN PSRSNCapObject psRSNCapObj ) @@ -4870,7 +4870,7 @@ bAdd_PMKID_Candidate ( -*/ void vFlush_PMKID_Candidate ( - IN HANDLE hDeviceContext + IN void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index 5eabc199c020..cee860281812 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -401,36 +401,36 @@ typedef struct tagSMgmtObject void vMgrObjectInit( - IN HANDLE hDeviceContext + IN void *hDeviceContext ); void vMgrTimerInit( - IN HANDLE hDeviceContext + IN void *hDeviceContext ); void vMgrObjectReset( - IN HANDLE hDeviceContext + IN void *hDeviceContext ); void vMgrAssocBeginSta( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ); void vMgrReAssocBeginSta( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ); void vMgrDisassocBeginSta( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PSMgmtObject pMgmt, IN PBYTE abyDestAddress, IN WORD wReason, @@ -439,26 +439,26 @@ vMgrDisassocBeginSta( void vMgrAuthenBeginSta( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ); void vMgrCreateOwnIBSS( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, OUT PCMD_STATUS pStatus ); void vMgrJoinBSSBegin( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, OUT PCMD_STATUS pStatus ); void vMgrRxManagePacket( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PSMgmtObject pMgmt, IN PSRxMgmtPacket pRxPacket ); @@ -466,14 +466,14 @@ vMgrRxManagePacket( /* void vMgrScanBegin( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, OUT PCMD_STATUS pStatus ); */ void vMgrDeAuthenBeginSta( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PSMgmtObject pMgmt, IN PBYTE abyDestAddress, IN WORD wReason, @@ -482,21 +482,21 @@ vMgrDeAuthenBeginSta( BOOL bMgrPrepareBeaconToSend( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PSMgmtObject pMgmt ); BOOL bAdd_PMKID_Candidate ( - IN HANDLE hDeviceContext, + IN void *hDeviceContext, IN PBYTE pbyBSSID, IN PSRSNCapObject psRSNCapObj ); void vFlush_PMKID_Candidate ( - IN HANDLE hDeviceContext + IN void *hDeviceContext ); #endif // __WMGR_H__ diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c index 4e886c162099..e5e618eb6bb7 100644 --- a/drivers/staging/vt6655/wpactl.c +++ b/drivers/staging/vt6655/wpactl.c @@ -496,7 +496,7 @@ static int wpa_set_disassociate(PSDevice pDevice, spin_lock_irq(&pDevice->lock); if (pDevice->bLinkPass) { if (!memcmp(param->addr, pMgmt->abyCurrBSSID, 6)) - bScheduleCommand((HANDLE)pDevice, WLAN_CMD_DISASSOCIATE, NULL); + bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL); } spin_unlock_irq(&pDevice->lock); @@ -525,8 +525,8 @@ static int wpa_set_scan(PSDevice pDevice, int ret = 0; spin_lock_irq(&pDevice->lock); - BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL); + BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); spin_unlock_irq(&pDevice->lock); return ret; @@ -786,7 +786,7 @@ static int wpa_set_associate(PSDevice pDevice, memcpy(pMgmt->abyDesireBSSID, param->u.wpa_associate.bssid, 6); else { - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pItemSSID->abySSID); + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pItemSSID->abySSID); } if (param->u.wpa_associate.wpa_ie_len == 0) { @@ -870,11 +870,11 @@ if (!((pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) || if (pCurr == NULL){ printk("wpa_set_associate---->hidden mode site survey before associate.......\n"); - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); + bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); }; } /****************************************************************/ - bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, NULL); + bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); spin_unlock_irq(&pDevice->lock); return ret; -- cgit v1.2.3 From bf597e99d2fd4c5d25485fd4e4877bbae2be816c Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Tue, 11 May 2010 15:56:44 -0700 Subject: staging: dream: smd: remove all smd related code Part of this code is already in my MSM tree. I'll move the rest forward through my tree also. Signed-off-by: Daniel Walker CC: Pavel Machek CC: linux-arm-msm@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dream/Kconfig | 1 - drivers/staging/dream/Makefile | 2 +- drivers/staging/dream/smd/Kconfig | 26 - drivers/staging/dream/smd/Makefile | 7 - .../staging/dream/smd/rpc_server_dog_keepalive.c | 68 - drivers/staging/dream/smd/rpc_server_time_remote.c | 77 -- drivers/staging/dream/smd/smd.c | 1330 -------------------- drivers/staging/dream/smd/smd_private.h | 164 --- drivers/staging/dream/smd/smd_qmi.c | 851 ------------- drivers/staging/dream/smd/smd_rpcrouter.c | 1261 ------------------- drivers/staging/dream/smd/smd_rpcrouter.h | 193 --- drivers/staging/dream/smd/smd_rpcrouter_device.c | 377 ------ drivers/staging/dream/smd/smd_rpcrouter_servers.c | 226 ---- drivers/staging/dream/smd/smd_tty.c | 208 --- 14 files changed, 1 insertion(+), 4790 deletions(-) delete mode 100644 drivers/staging/dream/smd/Kconfig delete mode 100644 drivers/staging/dream/smd/Makefile delete mode 100644 drivers/staging/dream/smd/rpc_server_dog_keepalive.c delete mode 100644 drivers/staging/dream/smd/rpc_server_time_remote.c delete mode 100644 drivers/staging/dream/smd/smd.c delete mode 100644 drivers/staging/dream/smd/smd_private.h delete mode 100644 drivers/staging/dream/smd/smd_qmi.c delete mode 100644 drivers/staging/dream/smd/smd_rpcrouter.c delete mode 100644 drivers/staging/dream/smd/smd_rpcrouter.h delete mode 100644 drivers/staging/dream/smd/smd_rpcrouter_device.c delete mode 100644 drivers/staging/dream/smd/smd_rpcrouter_servers.c delete mode 100644 drivers/staging/dream/smd/smd_tty.c (limited to 'drivers') diff --git a/drivers/staging/dream/Kconfig b/drivers/staging/dream/Kconfig index 707cc71a8a6a..0c30b19a5a7c 100644 --- a/drivers/staging/dream/Kconfig +++ b/drivers/staging/dream/Kconfig @@ -3,7 +3,6 @@ config DREAM depends on MACH_TROUT if DREAM -source "drivers/staging/dream/smd/Kconfig" source "drivers/staging/dream/camera/Kconfig" diff --git a/drivers/staging/dream/Makefile b/drivers/staging/dream/Makefile index 43d1eec8e257..fbea0abcc864 100644 --- a/drivers/staging/dream/Makefile +++ b/drivers/staging/dream/Makefile @@ -1,5 +1,5 @@ EXTRA_CFLAGS=-Idrivers/staging/dream/include -obj-$(CONFIG_MSM_ADSP) += qdsp5/ smd/ +obj-$(CONFIG_MSM_ADSP) += qdsp5/ obj-$(CONFIG_MSM_CAMERA) += camera/ obj-$(CONFIG_INPUT_GPIO) += gpio_axis.o gpio_event.o gpio_input.o gpio_matrix.o gpio_output.o diff --git a/drivers/staging/dream/smd/Kconfig b/drivers/staging/dream/smd/Kconfig deleted file mode 100644 index 17b8bdc7b9b7..000000000000 --- a/drivers/staging/dream/smd/Kconfig +++ /dev/null @@ -1,26 +0,0 @@ -config MSM_SMD - depends on ARCH_MSM - default y - bool "MSM Shared Memory Driver (SMD)" - help - Support for the shared memory interface between the apps - processor and the baseband processor. Provides access to - the "shared heap", as well as virtual serial channels - used to communicate with various services on the baseband - processor. - -config MSM_ONCRPCROUTER - depends on MSM_SMD - default y - bool "MSM ONCRPC router support" - help - Support for the MSM ONCRPC router for communication between - the ARM9 and ARM11 - -config MSM_RPCSERVERS - depends on MSM_ONCRPCROUTER - default y - bool "Kernel side RPC server bundle" - help - none - diff --git a/drivers/staging/dream/smd/Makefile b/drivers/staging/dream/smd/Makefile deleted file mode 100644 index 1c87618366a7..000000000000 --- a/drivers/staging/dream/smd/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -EXTRA_CFLAGS=-Idrivers/staging/dream/include -obj-$(CONFIG_MSM_SMD) += smd.o smd_tty.o smd_qmi.o -obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter.o -obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_device.o -obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_servers.o -obj-$(CONFIG_MSM_RPCSERVERS) += rpc_server_dog_keepalive.o -obj-$(CONFIG_MSM_RPCSERVERS) += rpc_server_time_remote.o diff --git a/drivers/staging/dream/smd/rpc_server_dog_keepalive.c b/drivers/staging/dream/smd/rpc_server_dog_keepalive.c deleted file mode 100644 index b23fccfa87e2..000000000000 --- a/drivers/staging/dream/smd/rpc_server_dog_keepalive.c +++ /dev/null @@ -1,68 +0,0 @@ -/* arch/arm/mach-msm/rpc_server_dog_keepalive.c - * - * Copyright (C) 2007 Google, Inc. - * Author: Iliyan Malchev - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include - -/* dog_keepalive server definitions */ - -#define DOG_KEEPALIVE_PROG 0x30000015 -#if CONFIG_MSM_AMSS_VERSION==6210 -#define DOG_KEEPALIVE_VERS 0 -#define RPC_DOG_KEEPALIVE_BEACON 1 -#elif (CONFIG_MSM_AMSS_VERSION==6220) || (CONFIG_MSM_AMSS_VERSION==6225) -#define DOG_KEEPALIVE_VERS 0x731fa727 -#define RPC_DOG_KEEPALIVE_BEACON 2 -#elif CONFIG_MSM_AMSS_VERSION==6350 -#define DOG_KEEPALIVE_VERS 0x00010000 -#define RPC_DOG_KEEPALIVE_BEACON 2 -#else -#error "Unsupported AMSS version" -#endif -#define RPC_DOG_KEEPALIVE_NULL 0 - - -/* TODO: Remove server registration with _VERS when modem is upated with _COMP*/ - -static int handle_rpc_call(struct msm_rpc_server *server, - struct rpc_request_hdr *req, unsigned len) -{ - switch (req->procedure) { - case RPC_DOG_KEEPALIVE_NULL: - return 0; - case RPC_DOG_KEEPALIVE_BEACON: - printk(KERN_INFO "DOG KEEPALIVE PING\n"); - return 0; - default: - return -ENODEV; - } -} - -static struct msm_rpc_server rpc_server = { - .prog = DOG_KEEPALIVE_PROG, - .vers = DOG_KEEPALIVE_VERS, - .rpc_call = handle_rpc_call, -}; - -static int __init rpc_server_init(void) -{ - /* Dual server registration to support backwards compatibility vers */ - return msm_rpc_create_server(&rpc_server); -} - - -module_init(rpc_server_init); diff --git a/drivers/staging/dream/smd/rpc_server_time_remote.c b/drivers/staging/dream/smd/rpc_server_time_remote.c deleted file mode 100644 index 2f90fc88c385..000000000000 --- a/drivers/staging/dream/smd/rpc_server_time_remote.c +++ /dev/null @@ -1,77 +0,0 @@ -/* arch/arm/mach-msm/rpc_server_time_remote.c - * - * Copyright (C) 2007 Google, Inc. - * Author: Iliyan Malchev - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include - -/* time_remote_mtoa server definitions. */ - -#define TIME_REMOTE_MTOA_PROG 0x3000005d -#if CONFIG_MSM_AMSS_VERSION==6210 -#define TIME_REMOTE_MTOA_VERS 0 -#elif (CONFIG_MSM_AMSS_VERSION==6220) || (CONFIG_MSM_AMSS_VERSION==6225) -#define TIME_REMOTE_MTOA_VERS 0x9202a8e4 -#elif CONFIG_MSM_AMSS_VERSION==6350 -#define TIME_REMOTE_MTOA_VERS 0x00010000 -#else -#error "Unknown AMSS version" -#endif -#define RPC_TIME_REMOTE_MTOA_NULL 0 -#define RPC_TIME_TOD_SET_APPS_BASES 2 - -struct rpc_time_tod_set_apps_bases_args { - uint32_t tick; - uint64_t stamp; -}; - -static int handle_rpc_call(struct msm_rpc_server *server, - struct rpc_request_hdr *req, unsigned len) -{ - switch (req->procedure) { - case RPC_TIME_REMOTE_MTOA_NULL: - return 0; - - case RPC_TIME_TOD_SET_APPS_BASES: { - struct rpc_time_tod_set_apps_bases_args *args; - args = (struct rpc_time_tod_set_apps_bases_args *)(req + 1); - args->tick = be32_to_cpu(args->tick); - args->stamp = be64_to_cpu(args->stamp); - printk(KERN_INFO "RPC_TIME_TOD_SET_APPS_BASES:\n" - "\ttick = %d\n" - "\tstamp = %lld\n", - args->tick, args->stamp); - return 0; - } - default: - return -ENODEV; - } -} - -static struct msm_rpc_server rpc_server = { - .prog = TIME_REMOTE_MTOA_PROG, - .vers = TIME_REMOTE_MTOA_VERS, - .rpc_call = handle_rpc_call, -}; - -static int __init rpc_server_init(void) -{ - /* Dual server registration to support backwards compatibility vers */ - return msm_rpc_create_server(&rpc_server); -} - - -module_init(rpc_server_init); diff --git a/drivers/staging/dream/smd/smd.c b/drivers/staging/dream/smd/smd.c deleted file mode 100644 index 8f35be7193fb..000000000000 --- a/drivers/staging/dream/smd/smd.c +++ /dev/null @@ -1,1330 +0,0 @@ -/* arch/arm/mach-msm/smd.c - * - * Copyright (C) 2007 Google, Inc. - * Author: Brian Swetland - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "smd_private.h" -#include "../../../../arch/arm/mach-msm/proc_comm.h" - -void (*msm_hw_reset_hook)(void); - -#define MODULE_NAME "msm_smd" - -enum { - MSM_SMD_DEBUG = 1U << 0, - MSM_SMSM_DEBUG = 1U << 0, -}; - -static int msm_smd_debug_mask; - -module_param_named(debug_mask, msm_smd_debug_mask, - int, S_IRUGO | S_IWUSR | S_IWGRP); - -void *smem_find(unsigned id, unsigned size); -static void smd_diag(void); - -static unsigned last_heap_free = 0xffffffff; - -#define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4) - -static inline void notify_other_smsm(void) -{ - writel(1, MSM_A2M_INT(5)); -} - -static inline void notify_other_smd(void) -{ - writel(1, MSM_A2M_INT(0)); -} - -static void smd_diag(void) -{ - char *x; - - x = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG); - if (x != 0) { - x[SZ_DIAG_ERR_MSG - 1] = 0; - pr_info("smem: DIAG '%s'\n", x); - } -} - -/* call when SMSM_RESET flag is set in the A9's smsm_state */ -static void handle_modem_crash(void) -{ - pr_err("ARM9 has CRASHED\n"); - smd_diag(); - - /* hard reboot if possible */ - if (msm_hw_reset_hook) - msm_hw_reset_hook(); - - /* in this case the modem or watchdog should reboot us */ - for (;;) - ; -} - -extern int (*msm_check_for_modem_crash)(void); - -static int check_for_modem_crash(void) -{ - struct smsm_shared *smsm; - - smsm = smem_find(ID_SHARED_STATE, 2 * sizeof(struct smsm_shared)); - - /* if the modem's not ready yet, we have to hope for the best */ - if (!smsm) - return 0; - - if (smsm[1].state & SMSM_RESET) { - handle_modem_crash(); - return -1; - } else { - return 0; - } -} - -#define SMD_SS_CLOSED 0x00000000 -#define SMD_SS_OPENING 0x00000001 -#define SMD_SS_OPENED 0x00000002 -#define SMD_SS_FLUSHING 0x00000003 -#define SMD_SS_CLOSING 0x00000004 -#define SMD_SS_RESET 0x00000005 -#define SMD_SS_RESET_OPENING 0x00000006 - -#define SMD_BUF_SIZE 8192 -#define SMD_CHANNELS 64 - -#define SMD_HEADER_SIZE 20 - - -/* the spinlock is used to synchronize between the -** irq handler and code that mutates the channel -** list or fiddles with channel state -*/ -static DEFINE_SPINLOCK(smd_lock); -static DEFINE_SPINLOCK(smem_lock); - -/* the mutex is used during open() and close() -** operations to avoid races while creating or -** destroying smd_channel structures -*/ -static DEFINE_MUTEX(smd_creation_mutex); - -static int smd_initialized; - -struct smd_alloc_elm { - char name[20]; - uint32_t cid; - uint32_t ctype; - uint32_t ref_count; -}; - -struct smd_half_channel { - unsigned state; - unsigned char fDSR; - unsigned char fCTS; - unsigned char fCD; - unsigned char fRI; - unsigned char fHEAD; - unsigned char fTAIL; - unsigned char fSTATE; - unsigned char fUNUSED; - unsigned tail; - unsigned head; - unsigned char data[SMD_BUF_SIZE]; -}; - -struct smd_shared { - struct smd_half_channel ch0; - struct smd_half_channel ch1; -}; - -struct smd_channel { - volatile struct smd_half_channel *send; - volatile struct smd_half_channel *recv; - struct list_head ch_list; - - unsigned current_packet; - unsigned n; - void *priv; - void (*notify)(void *priv, unsigned flags); - - int (*read)(smd_channel_t *ch, void *data, int len); - int (*write)(smd_channel_t *ch, const void *data, int len); - int (*read_avail)(smd_channel_t *ch); - int (*write_avail)(smd_channel_t *ch); - - void (*update_state)(smd_channel_t *ch); - unsigned last_state; - - char name[32]; - struct platform_device pdev; -}; - -static LIST_HEAD(smd_ch_closed_list); -static LIST_HEAD(smd_ch_list); - -static unsigned char smd_ch_allocated[64]; -static struct work_struct probe_work; - -static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type); - -static void smd_channel_probe_worker(struct work_struct *work) -{ - struct smd_alloc_elm *shared; - unsigned n; - - shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64); - - for (n = 0; n < 64; n++) { - if (smd_ch_allocated[n]) - continue; - if (!shared[n].ref_count) - continue; - if (!shared[n].name[0]) - continue; - smd_alloc_channel(shared[n].name, - shared[n].cid, - shared[n].ctype); - smd_ch_allocated[n] = 1; - } -} - -static char *chstate(unsigned n) -{ - switch (n) { - case SMD_SS_CLOSED: - return "CLOSED"; - case SMD_SS_OPENING: - return "OPENING"; - case SMD_SS_OPENED: - return "OPENED"; - case SMD_SS_FLUSHING: - return "FLUSHING"; - case SMD_SS_CLOSING: - return "CLOSING"; - case SMD_SS_RESET: - return "RESET"; - case SMD_SS_RESET_OPENING: - return "ROPENING"; - default: - return "UNKNOWN"; - } -} - -/* how many bytes are available for reading */ -static int smd_stream_read_avail(struct smd_channel *ch) -{ - return (ch->recv->head - ch->recv->tail) & (SMD_BUF_SIZE - 1); -} - -/* how many bytes we are free to write */ -static int smd_stream_write_avail(struct smd_channel *ch) -{ - return (SMD_BUF_SIZE - 1) - - ((ch->send->head - ch->send->tail) & (SMD_BUF_SIZE - 1)); -} - -static int smd_packet_read_avail(struct smd_channel *ch) -{ - if (ch->current_packet) { - int n = smd_stream_read_avail(ch); - if (n > ch->current_packet) - n = ch->current_packet; - return n; - } else { - return 0; - } -} - -static int smd_packet_write_avail(struct smd_channel *ch) -{ - int n = smd_stream_write_avail(ch); - return n > SMD_HEADER_SIZE ? n - SMD_HEADER_SIZE : 0; -} - -static int ch_is_open(struct smd_channel *ch) -{ - return (ch->recv->state == SMD_SS_OPENED) && - (ch->send->state == SMD_SS_OPENED); -} - -/* provide a pointer and length to readable data in the fifo */ -static unsigned ch_read_buffer(struct smd_channel *ch, void **ptr) -{ - unsigned head = ch->recv->head; - unsigned tail = ch->recv->tail; - *ptr = (void *) (ch->recv->data + tail); - - if (tail <= head) - return head - tail; - else - return SMD_BUF_SIZE - tail; -} - -/* advance the fifo read pointer after data from ch_read_buffer is consumed */ -static void ch_read_done(struct smd_channel *ch, unsigned count) -{ - BUG_ON(count > smd_stream_read_avail(ch)); - ch->recv->tail = (ch->recv->tail + count) & (SMD_BUF_SIZE - 1); - ch->recv->fTAIL = 1; -} - -/* basic read interface to ch_read_{buffer,done} used -** by smd_*_read() and update_packet_state() -** will read-and-discard if the _data pointer is null -*/ -static int ch_read(struct smd_channel *ch, void *_data, int len) -{ - void *ptr; - unsigned n; - unsigned char *data = _data; - int orig_len = len; - - while (len > 0) { - n = ch_read_buffer(ch, &ptr); - if (n == 0) - break; - - if (n > len) - n = len; - if (_data) - memcpy(data, ptr, n); - - data += n; - len -= n; - ch_read_done(ch, n); - } - - return orig_len - len; -} - -static void update_stream_state(struct smd_channel *ch) -{ - /* streams have no special state requiring updating */ -} - -static void update_packet_state(struct smd_channel *ch) -{ - unsigned hdr[5]; - int r; - - /* can't do anything if we're in the middle of a packet */ - if (ch->current_packet != 0) - return; - - /* don't bother unless we can get the full header */ - if (smd_stream_read_avail(ch) < SMD_HEADER_SIZE) - return; - - r = ch_read(ch, hdr, SMD_HEADER_SIZE); - BUG_ON(r != SMD_HEADER_SIZE); - - ch->current_packet = hdr[0]; -} - -/* provide a pointer and length to next free space in the fifo */ -static unsigned ch_write_buffer(struct smd_channel *ch, void **ptr) -{ - unsigned head = ch->send->head; - unsigned tail = ch->send->tail; - *ptr = (void *) (ch->send->data + head); - - if (head < tail) { - return tail - head - 1; - } else { - if (tail == 0) - return SMD_BUF_SIZE - head - 1; - else - return SMD_BUF_SIZE - head; - } -} - -/* advace the fifo write pointer after freespace - * from ch_write_buffer is filled - */ -static void ch_write_done(struct smd_channel *ch, unsigned count) -{ - BUG_ON(count > smd_stream_write_avail(ch)); - ch->send->head = (ch->send->head + count) & (SMD_BUF_SIZE - 1); - ch->send->fHEAD = 1; -} - -static void hc_set_state(volatile struct smd_half_channel *hc, unsigned n) -{ - if (n == SMD_SS_OPENED) { - hc->fDSR = 1; - hc->fCTS = 1; - hc->fCD = 1; - } else { - hc->fDSR = 0; - hc->fCTS = 0; - hc->fCD = 0; - } - hc->state = n; - hc->fSTATE = 1; - notify_other_smd(); -} - -static void do_smd_probe(void) -{ - struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; - if (shared->heap_info.free_offset != last_heap_free) { - last_heap_free = shared->heap_info.free_offset; - schedule_work(&probe_work); - } -} - -static void smd_state_change(struct smd_channel *ch, - unsigned last, unsigned next) -{ - ch->last_state = next; - - pr_info("SMD: ch %d %s -> %s\n", ch->n, - chstate(last), chstate(next)); - - switch (next) { - case SMD_SS_OPENING: - ch->recv->tail = 0; - case SMD_SS_OPENED: - if (ch->send->state != SMD_SS_OPENED) - hc_set_state(ch->send, SMD_SS_OPENED); - ch->notify(ch->priv, SMD_EVENT_OPEN); - break; - case SMD_SS_FLUSHING: - case SMD_SS_RESET: - /* we should force them to close? */ - default: - ch->notify(ch->priv, SMD_EVENT_CLOSE); - } -} - -static irqreturn_t smd_irq_handler(int irq, void *data) -{ - unsigned long flags; - struct smd_channel *ch; - int do_notify = 0; - unsigned ch_flags; - unsigned tmp; - - spin_lock_irqsave(&smd_lock, flags); - list_for_each_entry(ch, &smd_ch_list, ch_list) { - ch_flags = 0; - if (ch_is_open(ch)) { - if (ch->recv->fHEAD) { - ch->recv->fHEAD = 0; - ch_flags |= 1; - do_notify |= 1; - } - if (ch->recv->fTAIL) { - ch->recv->fTAIL = 0; - ch_flags |= 2; - do_notify |= 1; - } - if (ch->recv->fSTATE) { - ch->recv->fSTATE = 0; - ch_flags |= 4; - do_notify |= 1; - } - } - tmp = ch->recv->state; - if (tmp != ch->last_state) - smd_state_change(ch, ch->last_state, tmp); - if (ch_flags) { - ch->update_state(ch); - ch->notify(ch->priv, SMD_EVENT_DATA); - } - } - if (do_notify) - notify_other_smd(); - spin_unlock_irqrestore(&smd_lock, flags); - do_smd_probe(); - return IRQ_HANDLED; -} - -static void smd_fake_irq_handler(unsigned long arg) -{ - smd_irq_handler(0, NULL); -} - -static DECLARE_TASKLET(smd_fake_irq_tasklet, smd_fake_irq_handler, 0); - -void smd_sleep_exit(void) -{ - unsigned long flags; - struct smd_channel *ch; - unsigned tmp; - int need_int = 0; - - spin_lock_irqsave(&smd_lock, flags); - list_for_each_entry(ch, &smd_ch_list, ch_list) { - if (ch_is_open(ch)) { - if (ch->recv->fHEAD) { - if (msm_smd_debug_mask & MSM_SMD_DEBUG) - pr_info("smd_sleep_exit ch %d fHEAD " - "%x %x %x\n", - ch->n, ch->recv->fHEAD, - ch->recv->head, ch->recv->tail); - need_int = 1; - break; - } - if (ch->recv->fTAIL) { - if (msm_smd_debug_mask & MSM_SMD_DEBUG) - pr_info("smd_sleep_exit ch %d fTAIL " - "%x %x %x\n", - ch->n, ch->recv->fTAIL, - ch->send->head, ch->send->tail); - need_int = 1; - break; - } - if (ch->recv->fSTATE) { - if (msm_smd_debug_mask & MSM_SMD_DEBUG) - pr_info("smd_sleep_exit ch %d fSTATE %x" - "\n", ch->n, ch->recv->fSTATE); - need_int = 1; - break; - } - tmp = ch->recv->state; - if (tmp != ch->last_state) { - if (msm_smd_debug_mask & MSM_SMD_DEBUG) - pr_info("smd_sleep_exit ch %d " - "state %x != %x\n", - ch->n, tmp, ch->last_state); - need_int = 1; - break; - } - } - } - spin_unlock_irqrestore(&smd_lock, flags); - do_smd_probe(); - if (need_int) { - if (msm_smd_debug_mask & MSM_SMD_DEBUG) - pr_info("smd_sleep_exit need interrupt\n"); - tasklet_schedule(&smd_fake_irq_tasklet); - } -} - - -void smd_kick(smd_channel_t *ch) -{ - unsigned long flags; - unsigned tmp; - - spin_lock_irqsave(&smd_lock, flags); - ch->update_state(ch); - tmp = ch->recv->state; - if (tmp != ch->last_state) { - ch->last_state = tmp; - if (tmp == SMD_SS_OPENED) - ch->notify(ch->priv, SMD_EVENT_OPEN); - else - ch->notify(ch->priv, SMD_EVENT_CLOSE); - } - ch->notify(ch->priv, SMD_EVENT_DATA); - notify_other_smd(); - spin_unlock_irqrestore(&smd_lock, flags); -} - -static int smd_is_packet(int chn) -{ - if ((chn > 4) || (chn == 1)) - return 1; - else - return 0; -} - -static int smd_stream_write(smd_channel_t *ch, const void *_data, int len) -{ - void *ptr; - const unsigned char *buf = _data; - unsigned xfer; - int orig_len = len; - - if (len < 0) - return -EINVAL; - - while ((xfer = ch_write_buffer(ch, &ptr)) != 0) { - if (!ch_is_open(ch)) - break; - if (xfer > len) - xfer = len; - memcpy(ptr, buf, xfer); - ch_write_done(ch, xfer); - len -= xfer; - buf += xfer; - if (len == 0) - break; - } - - notify_other_smd(); - - return orig_len - len; -} - -static int smd_packet_write(smd_channel_t *ch, const void *_data, int len) -{ - unsigned hdr[5]; - - if (len < 0) - return -EINVAL; - - if (smd_stream_write_avail(ch) < (len + SMD_HEADER_SIZE)) - return -ENOMEM; - - hdr[0] = len; - hdr[1] = hdr[2] = hdr[3] = hdr[4] = 0; - - smd_stream_write(ch, hdr, sizeof(hdr)); - smd_stream_write(ch, _data, len); - - return len; -} - -static int smd_stream_read(smd_channel_t *ch, void *data, int len) -{ - int r; - - if (len < 0) - return -EINVAL; - - r = ch_read(ch, data, len); - if (r > 0) - notify_other_smd(); - - return r; -} - -static int smd_packet_read(smd_channel_t *ch, void *data, int len) -{ - unsigned long flags; - int r; - - if (len < 0) - return -EINVAL; - - if (len > ch->current_packet) - len = ch->current_packet; - - r = ch_read(ch, data, len); - if (r > 0) - notify_other_smd(); - - spin_lock_irqsave(&smd_lock, flags); - ch->current_packet -= r; - update_packet_state(ch); - spin_unlock_irqrestore(&smd_lock, flags); - - return r; -} - -static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type) -{ - struct smd_channel *ch; - struct smd_shared *shared; - - shared = smem_alloc(ID_SMD_CHANNELS + cid, sizeof(*shared)); - if (!shared) { - pr_err("smd_alloc_channel() cid %d does not exist\n", cid); - return; - } - - ch = kzalloc(sizeof(struct smd_channel), GFP_KERNEL); - if (ch == 0) { - pr_err("smd_alloc_channel() out of memory\n"); - return; - } - - ch->send = &shared->ch0; - ch->recv = &shared->ch1; - ch->n = cid; - - if (smd_is_packet(cid)) { - ch->read = smd_packet_read; - ch->write = smd_packet_write; - ch->read_avail = smd_packet_read_avail; - ch->write_avail = smd_packet_write_avail; - ch->update_state = update_packet_state; - } else { - ch->read = smd_stream_read; - ch->write = smd_stream_write; - ch->read_avail = smd_stream_read_avail; - ch->write_avail = smd_stream_write_avail; - ch->update_state = update_stream_state; - } - - memcpy(ch->name, "SMD_", 4); - memcpy(ch->name + 4, name, 20); - ch->name[23] = 0; - ch->pdev.name = ch->name; - ch->pdev.id = -1; - - pr_info("smd_alloc_channel() '%s' cid=%d, shared=%p\n", - ch->name, ch->n, shared); - - mutex_lock(&smd_creation_mutex); - list_add(&ch->ch_list, &smd_ch_closed_list); - mutex_unlock(&smd_creation_mutex); - - platform_device_register(&ch->pdev); -} - -static void do_nothing_notify(void *priv, unsigned flags) -{ -} - -struct smd_channel *smd_get_channel(const char *name) -{ - struct smd_channel *ch; - - mutex_lock(&smd_creation_mutex); - list_for_each_entry(ch, &smd_ch_closed_list, ch_list) { - if (!strcmp(name, ch->name)) { - list_del(&ch->ch_list); - mutex_unlock(&smd_creation_mutex); - return ch; - } - } - mutex_unlock(&smd_creation_mutex); - - return NULL; -} - -int smd_open(const char *name, smd_channel_t **_ch, - void *priv, void (*notify)(void *, unsigned)) -{ - struct smd_channel *ch; - unsigned long flags; - - if (smd_initialized == 0) { - pr_info("smd_open() before smd_init()\n"); - return -ENODEV; - } - - ch = smd_get_channel(name); - if (!ch) - return -ENODEV; - - if (notify == 0) - notify = do_nothing_notify; - - ch->notify = notify; - ch->current_packet = 0; - ch->last_state = SMD_SS_CLOSED; - ch->priv = priv; - - *_ch = ch; - - spin_lock_irqsave(&smd_lock, flags); - list_add(&ch->ch_list, &smd_ch_list); - - /* If the remote side is CLOSING, we need to get it to - * move to OPENING (which we'll do by moving from CLOSED to - * OPENING) and then get it to move from OPENING to - * OPENED (by doing the same state change ourselves). - * - * Otherwise, it should be OPENING and we can move directly - * to OPENED so that it will follow. - */ - if (ch->recv->state == SMD_SS_CLOSING) { - ch->send->head = 0; - hc_set_state(ch->send, SMD_SS_OPENING); - } else { - hc_set_state(ch->send, SMD_SS_OPENED); - } - spin_unlock_irqrestore(&smd_lock, flags); - smd_kick(ch); - - return 0; -} - -int smd_close(smd_channel_t *ch) -{ - unsigned long flags; - - pr_info("smd_close(%p)\n", ch); - - if (ch == 0) - return -1; - - spin_lock_irqsave(&smd_lock, flags); - ch->notify = do_nothing_notify; - list_del(&ch->ch_list); - hc_set_state(ch->send, SMD_SS_CLOSED); - spin_unlock_irqrestore(&smd_lock, flags); - - mutex_lock(&smd_creation_mutex); - list_add(&ch->ch_list, &smd_ch_closed_list); - mutex_unlock(&smd_creation_mutex); - - return 0; -} - -int smd_read(smd_channel_t *ch, void *data, int len) -{ - return ch->read(ch, data, len); -} - -int smd_write(smd_channel_t *ch, const void *data, int len) -{ - return ch->write(ch, data, len); -} - -int smd_read_avail(smd_channel_t *ch) -{ - return ch->read_avail(ch); -} - -int smd_write_avail(smd_channel_t *ch) -{ - return ch->write_avail(ch); -} - -int smd_wait_until_readable(smd_channel_t *ch, int bytes) -{ - return -1; -} - -int smd_wait_until_writable(smd_channel_t *ch, int bytes) -{ - return -1; -} - -int smd_cur_packet_size(smd_channel_t *ch) -{ - return ch->current_packet; -} - - -/* ------------------------------------------------------------------------- */ - -void *smem_alloc(unsigned id, unsigned size) -{ - return smem_find(id, size); -} - -static void *_smem_find(unsigned id, unsigned *size) -{ - struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; - struct smem_heap_entry *toc = shared->heap_toc; - - if (id >= SMEM_NUM_ITEMS) - return 0; - - if (toc[id].allocated) { - *size = toc[id].size; - return (void *) (MSM_SHARED_RAM_BASE + toc[id].offset); - } - - return 0; -} - -void *smem_find(unsigned id, unsigned size_in) -{ - unsigned size; - void *ptr; - - ptr = _smem_find(id, &size); - if (!ptr) - return 0; - - size_in = ALIGN(size_in, 8); - if (size_in != size) { - pr_err("smem_find(%d, %d): wrong size %d\n", - id, size_in, size); - return 0; - } - - return ptr; -} - -static irqreturn_t smsm_irq_handler(int irq, void *data) -{ - unsigned long flags; - struct smsm_shared *smsm; - - spin_lock_irqsave(&smem_lock, flags); - smsm = smem_alloc(ID_SHARED_STATE, - 2 * sizeof(struct smsm_shared)); - - if (smsm == 0) { - pr_info("\n"); - } else { - unsigned apps = smsm[0].state; - unsigned modm = smsm[1].state; - - if (msm_smd_debug_mask & MSM_SMSM_DEBUG) - pr_info("\n", apps, modm); - if (modm & SMSM_RESET) { - handle_modem_crash(); - } else { - apps |= SMSM_INIT; - if (modm & SMSM_SMDINIT) - apps |= SMSM_SMDINIT; - if (modm & SMSM_RPCINIT) - apps |= SMSM_RPCINIT; - } - - if (smsm[0].state != apps) { - if (msm_smd_debug_mask & MSM_SMSM_DEBUG) - pr_info("\n", apps); - smsm[0].state = apps; - do_smd_probe(); - notify_other_smsm(); - } - } - spin_unlock_irqrestore(&smem_lock, flags); - return IRQ_HANDLED; -} - -int smsm_change_state(uint32_t clear_mask, uint32_t set_mask) -{ - unsigned long flags; - struct smsm_shared *smsm; - - spin_lock_irqsave(&smem_lock, flags); - - smsm = smem_alloc(ID_SHARED_STATE, - 2 * sizeof(struct smsm_shared)); - - if (smsm) { - if (smsm[1].state & SMSM_RESET) - handle_modem_crash(); - smsm[0].state = (smsm[0].state & ~clear_mask) | set_mask; - if (msm_smd_debug_mask & MSM_SMSM_DEBUG) - pr_info("smsm_change_state %x\n", - smsm[0].state); - notify_other_smsm(); - } - - spin_unlock_irqrestore(&smem_lock, flags); - - if (smsm == NULL) { - pr_err("smsm_change_state \n"); - return -EIO; - } - return 0; -} - -uint32_t smsm_get_state(void) -{ - unsigned long flags; - struct smsm_shared *smsm; - uint32_t rv; - - spin_lock_irqsave(&smem_lock, flags); - - smsm = smem_alloc(ID_SHARED_STATE, - 2 * sizeof(struct smsm_shared)); - - if (smsm) - rv = smsm[1].state; - else - rv = 0; - - if (rv & SMSM_RESET) - handle_modem_crash(); - - spin_unlock_irqrestore(&smem_lock, flags); - - if (smsm == NULL) - pr_err("smsm_get_state \n"); - return rv; -} - -int smsm_set_sleep_duration(uint32_t delay) -{ - uint32_t *ptr; - - ptr = smem_alloc(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr)); - if (ptr == NULL) { - pr_err("smsm_set_sleep_duration \n"); - return -EIO; - } - if (msm_smd_debug_mask & MSM_SMSM_DEBUG) - pr_info("smsm_set_sleep_duration %d -> %d\n", - *ptr, delay); - *ptr = delay; - return 0; -} - -int smsm_set_interrupt_info(struct smsm_interrupt_info *info) -{ - struct smsm_interrupt_info *ptr; - - ptr = smem_alloc(SMEM_SMSM_INT_INFO, sizeof(*ptr)); - if (ptr == NULL) { - pr_err("smsm_set_sleep_duration \n"); - return -EIO; - } - if (msm_smd_debug_mask & MSM_SMSM_DEBUG) - pr_info("smsm_set_interrupt_info %x %x -> %x %x\n", - ptr->aArm_en_mask, ptr->aArm_interrupts_pending, - info->aArm_en_mask, info->aArm_interrupts_pending); - *ptr = *info; - return 0; -} - -#define MAX_NUM_SLEEP_CLIENTS 64 -#define MAX_SLEEP_NAME_LEN 8 - -#define NUM_GPIO_INT_REGISTERS 6 -#define GPIO_SMEM_NUM_GROUPS 2 -#define GPIO_SMEM_MAX_PC_INTERRUPTS 8 - -struct tramp_gpio_save { - unsigned int enable; - unsigned int detect; - unsigned int polarity; -}; - -struct tramp_gpio_smem { - uint16_t num_fired[GPIO_SMEM_NUM_GROUPS]; - uint16_t fired[GPIO_SMEM_NUM_GROUPS][GPIO_SMEM_MAX_PC_INTERRUPTS]; - uint32_t enabled[NUM_GPIO_INT_REGISTERS]; - uint32_t detection[NUM_GPIO_INT_REGISTERS]; - uint32_t polarity[NUM_GPIO_INT_REGISTERS]; -}; - - -void smsm_print_sleep_info(void) -{ - unsigned long flags; - uint32_t *ptr; - struct tramp_gpio_smem *gpio; - struct smsm_interrupt_info *int_info; - - - spin_lock_irqsave(&smem_lock, flags); - - ptr = smem_alloc(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr)); - if (ptr) - pr_info("SMEM_SMSM_SLEEP_DELAY: %x\n", *ptr); - - ptr = smem_alloc(SMEM_SMSM_LIMIT_SLEEP, sizeof(*ptr)); - if (ptr) - pr_info("SMEM_SMSM_LIMIT_SLEEP: %x\n", *ptr); - - ptr = smem_alloc(SMEM_SLEEP_POWER_COLLAPSE_DISABLED, sizeof(*ptr)); - if (ptr) - pr_info("SMEM_SLEEP_POWER_COLLAPSE_DISABLED: %x\n", *ptr); - - int_info = smem_alloc(SMEM_SMSM_INT_INFO, sizeof(*int_info)); - if (int_info) - pr_info("SMEM_SMSM_INT_INFO %x %x %x\n", - int_info->aArm_en_mask, - int_info->aArm_interrupts_pending, - int_info->aArm_wakeup_reason); - - gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*gpio)); - if (gpio) { - int i; - for (i = 0; i < NUM_GPIO_INT_REGISTERS; i++) - pr_info("SMEM_GPIO_INT: %d: e %x d %x p %x\n", - i, gpio->enabled[i], gpio->detection[i], - gpio->polarity[i]); - - for (i = 0; i < GPIO_SMEM_NUM_GROUPS; i++) - pr_info("SMEM_GPIO_INT: %d: f %d: %d %d...\n", - i, gpio->num_fired[i], gpio->fired[i][0], - gpio->fired[i][1]); - } - - spin_unlock_irqrestore(&smem_lock, flags); -} - -int smd_core_init(void) -{ - int r; - pr_info("smd_core_init()\n"); - - r = request_irq(INT_A9_M2A_0, smd_irq_handler, - IRQF_TRIGGER_RISING, "smd_dev", 0); - if (r < 0) - return r; - r = enable_irq_wake(INT_A9_M2A_0); - if (r < 0) - pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_0\n"); - - r = request_irq(INT_A9_M2A_5, smsm_irq_handler, - IRQF_TRIGGER_RISING, "smsm_dev", 0); - if (r < 0) { - free_irq(INT_A9_M2A_0, 0); - return r; - } - r = enable_irq_wake(INT_A9_M2A_5); - if (r < 0) - pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_5\n"); - - /* we may have missed a signal while booting -- fake - * an interrupt to make sure we process any existing - * state - */ - smsm_irq_handler(0, 0); - - pr_info("smd_core_init() done\n"); - - return 0; -} - -#if defined(CONFIG_DEBUG_FS) - -static int dump_ch(char *buf, int max, int n, - struct smd_half_channel *s, - struct smd_half_channel *r) -{ - return scnprintf( - buf, max, - "ch%02d:" - " %8s(%04d/%04d) %c%c%c%c%c%c%c <->" - " %8s(%04d/%04d) %c%c%c%c%c%c%c\n", n, - chstate(s->state), s->tail, s->head, - s->fDSR ? 'D' : 'd', - s->fCTS ? 'C' : 'c', - s->fCD ? 'C' : 'c', - s->fRI ? 'I' : 'i', - s->fHEAD ? 'W' : 'w', - s->fTAIL ? 'R' : 'r', - s->fSTATE ? 'S' : 's', - chstate(r->state), r->tail, r->head, - r->fDSR ? 'D' : 'd', - r->fCTS ? 'R' : 'r', - r->fCD ? 'C' : 'c', - r->fRI ? 'I' : 'i', - r->fHEAD ? 'W' : 'w', - r->fTAIL ? 'R' : 'r', - r->fSTATE ? 'S' : 's' - ); -} - -static int debug_read_stat(char *buf, int max) -{ - struct smsm_shared *smsm; - char *msg; - int i = 0; - - smsm = smem_find(ID_SHARED_STATE, - 2 * sizeof(struct smsm_shared)); - - msg = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG); - - if (smsm) { - if (smsm[1].state & SMSM_RESET) - i += scnprintf(buf + i, max - i, - "smsm: ARM9 HAS CRASHED\n"); - i += scnprintf(buf + i, max - i, "smsm: a9: %08x a11: %08x\n", - smsm[0].state, smsm[1].state); - } else { - i += scnprintf(buf + i, max - i, "smsm: cannot find\n"); - } - if (msg) { - msg[SZ_DIAG_ERR_MSG - 1] = 0; - i += scnprintf(buf + i, max - i, "diag: '%s'\n", msg); - } - return i; -} - -static int debug_read_mem(char *buf, int max) -{ - unsigned n; - struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; - struct smem_heap_entry *toc = shared->heap_toc; - int i = 0; - - i += scnprintf(buf + i, max - i, - "heap: init=%d free=%d remain=%d\n", - shared->heap_info.initialized, - shared->heap_info.free_offset, - shared->heap_info.heap_remaining); - - for (n = 0; n < SMEM_NUM_ITEMS; n++) { - if (toc[n].allocated == 0) - continue; - i += scnprintf(buf + i, max - i, - "%04d: offsed %08x size %08x\n", - n, toc[n].offset, toc[n].size); - } - return i; -} - -static int debug_read_ch(char *buf, int max) -{ - struct smd_shared *shared; - int n, i = 0; - - for (n = 0; n < SMD_CHANNELS; n++) { - shared = smem_find(ID_SMD_CHANNELS + n, - sizeof(struct smd_shared)); - if (shared == 0) - continue; - i += dump_ch(buf + i, max - i, n, &shared->ch0, &shared->ch1); - } - - return i; -} - -static int debug_read_version(char *buf, int max) -{ - struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; - unsigned version = shared->version[VERSION_MODEM]; - return sprintf(buf, "%d.%d\n", version >> 16, version & 0xffff); -} - -static int debug_read_build_id(char *buf, int max) -{ - unsigned size; - void *data; - - data = _smem_find(SMEM_HW_SW_BUILD_ID, &size); - if (!data) - return 0; - - if (size >= max) - size = max; - memcpy(buf, data, size); - - return size; -} - -static int debug_read_alloc_tbl(char *buf, int max) -{ - struct smd_alloc_elm *shared; - int n, i = 0; - - shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64); - - for (n = 0; n < 64; n++) { - if (shared[n].ref_count == 0) - continue; - i += scnprintf(buf + i, max - i, - "%03d: %20s cid=%02d ctype=%d ref_count=%d\n", - n, shared[n].name, shared[n].cid, - shared[n].ctype, shared[n].ref_count); - } - - return i; -} - -static int debug_boom(char *buf, int max) -{ - unsigned ms = 5000; - msm_proc_comm(PCOM_RESET_MODEM, &ms, 0); - return 0; -} - -#define DEBUG_BUFMAX 4096 -static char debug_buffer[DEBUG_BUFMAX]; - -static ssize_t debug_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - int (*fill)(char *buf, int max) = file->private_data; - int bsize = fill(debug_buffer, DEBUG_BUFMAX); - return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize); -} - -static int debug_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static const struct file_operations debug_ops = { - .read = debug_read, - .open = debug_open, -}; - -static void debug_create(const char *name, mode_t mode, - struct dentry *dent, - int (*fill)(char *buf, int max)) -{ - debugfs_create_file(name, mode, dent, fill, &debug_ops); -} - -static void smd_debugfs_init(void) -{ - struct dentry *dent; - - dent = debugfs_create_dir("smd", 0); - if (IS_ERR(dent)) - return; - - debug_create("ch", 0444, dent, debug_read_ch); - debug_create("stat", 0444, dent, debug_read_stat); - debug_create("mem", 0444, dent, debug_read_mem); - debug_create("version", 0444, dent, debug_read_version); - debug_create("tbl", 0444, dent, debug_read_alloc_tbl); - debug_create("build", 0444, dent, debug_read_build_id); - debug_create("boom", 0444, dent, debug_boom); -} -#else -static void smd_debugfs_init(void) {} -#endif - -static int __init msm_smd_probe(struct platform_device *pdev) -{ - pr_info("smd_init()\n"); - - INIT_WORK(&probe_work, smd_channel_probe_worker); - - if (smd_core_init()) { - pr_err("smd_core_init() failed\n"); - return -1; - } - - do_smd_probe(); - - msm_check_for_modem_crash = check_for_modem_crash; - - smd_debugfs_init(); - smd_initialized = 1; - - return 0; -} - -static struct platform_driver msm_smd_driver = { - .probe = msm_smd_probe, - .driver = { - .name = MODULE_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __init msm_smd_init(void) -{ - return platform_driver_register(&msm_smd_driver); -} - -module_init(msm_smd_init); - -MODULE_DESCRIPTION("MSM Shared Memory Core"); -MODULE_AUTHOR("Brian Swetland "); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/dream/smd/smd_private.h b/drivers/staging/dream/smd/smd_private.h deleted file mode 100644 index 1b2e1c89ea2e..000000000000 --- a/drivers/staging/dream/smd/smd_private.h +++ /dev/null @@ -1,164 +0,0 @@ -/* arch/arm/mach-msm/smd_private.h - * - * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2007 QUALCOMM Incorporated - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#ifndef _ARCH_ARM_MACH_MSM_MSM_SMD_PRIVATE_H_ -#define _ARCH_ARM_MACH_MSM_MSM_SMD_PRIVATE_H_ - -struct smem_heap_info { - unsigned initialized; - unsigned free_offset; - unsigned heap_remaining; - unsigned reserved; -}; - -struct smem_heap_entry { - unsigned allocated; - unsigned offset; - unsigned size; - unsigned reserved; -}; - -struct smem_proc_comm { - unsigned command; - unsigned status; - unsigned data1; - unsigned data2; -}; - -#define PC_APPS 0 -#define PC_MODEM 1 - -#define VERSION_QDSP6 4 -#define VERSION_APPS_SBL 6 -#define VERSION_MODEM_SBL 7 -#define VERSION_APPS 8 -#define VERSION_MODEM 9 - -struct smem_shared { - struct smem_proc_comm proc_comm[4]; - unsigned version[32]; - struct smem_heap_info heap_info; - struct smem_heap_entry heap_toc[128]; -}; - -struct smsm_shared { - unsigned host; - unsigned state; -}; - -struct smsm_interrupt_info { - uint32_t aArm_en_mask; - uint32_t aArm_interrupts_pending; - uint32_t aArm_wakeup_reason; -}; - -#define SZ_DIAG_ERR_MSG 0xC8 -#define ID_DIAG_ERR_MSG SMEM_DIAG_ERR_MESSAGE -#define ID_SMD_CHANNELS SMEM_SMD_BASE_ID -#define ID_SHARED_STATE SMEM_SMSM_SHARED_STATE -#define ID_CH_ALLOC_TBL SMEM_CHANNEL_ALLOC_TBL - -#define SMSM_INIT 0x000001 -#define SMSM_SMDINIT 0x000008 -#define SMSM_RPCINIT 0x000020 -#define SMSM_RESET 0x000040 -#define SMSM_RSA 0x0080 -#define SMSM_RUN 0x000100 -#define SMSM_PWRC 0x0200 -#define SMSM_TIMEWAIT 0x0400 -#define SMSM_TIMEINIT 0x0800 -#define SMSM_PWRC_EARLY_EXIT 0x1000 -#define SMSM_WFPI 0x2000 -#define SMSM_SLEEP 0x4000 -#define SMSM_SLEEPEXIT 0x8000 -#define SMSM_OEMSBL_RELEASE 0x10000 -#define SMSM_PWRC_SUSPEND 0x200000 - -#define SMSM_WKUP_REASON_RPC 0x00000001 -#define SMSM_WKUP_REASON_INT 0x00000002 -#define SMSM_WKUP_REASON_GPIO 0x00000004 -#define SMSM_WKUP_REASON_TIMER 0x00000008 -#define SMSM_WKUP_REASON_ALARM 0x00000010 -#define SMSM_WKUP_REASON_RESET 0x00000020 - -void *smem_alloc(unsigned id, unsigned size); -int smsm_change_state(uint32_t clear_mask, uint32_t set_mask); -uint32_t smsm_get_state(void); -int smsm_set_sleep_duration(uint32_t delay); -int smsm_set_interrupt_info(struct smsm_interrupt_info *info); -void smsm_print_sleep_info(void); - -#define SMEM_NUM_SMD_CHANNELS 64 - -typedef enum { - /* fixed items */ - SMEM_PROC_COMM = 0, - SMEM_HEAP_INFO, - SMEM_ALLOCATION_TABLE, - SMEM_VERSION_INFO, - SMEM_HW_RESET_DETECT, - SMEM_AARM_WARM_BOOT, - SMEM_DIAG_ERR_MESSAGE, - SMEM_SPINLOCK_ARRAY, - SMEM_MEMORY_BARRIER_LOCATION, - - /* dynamic items */ - SMEM_AARM_PARTITION_TABLE, - SMEM_AARM_BAD_BLOCK_TABLE, - SMEM_RESERVE_BAD_BLOCKS, - SMEM_WM_UUID, - SMEM_CHANNEL_ALLOC_TBL, - SMEM_SMD_BASE_ID, - SMEM_SMEM_LOG_IDX = SMEM_SMD_BASE_ID + SMEM_NUM_SMD_CHANNELS, - SMEM_SMEM_LOG_EVENTS, - SMEM_SMEM_STATIC_LOG_IDX, - SMEM_SMEM_STATIC_LOG_EVENTS, - SMEM_SMEM_SLOW_CLOCK_SYNC, - SMEM_SMEM_SLOW_CLOCK_VALUE, - SMEM_BIO_LED_BUF, - SMEM_SMSM_SHARED_STATE, - SMEM_SMSM_INT_INFO, - SMEM_SMSM_SLEEP_DELAY, - SMEM_SMSM_LIMIT_SLEEP, - SMEM_SLEEP_POWER_COLLAPSE_DISABLED, - SMEM_KEYPAD_KEYS_PRESSED, - SMEM_KEYPAD_STATE_UPDATED, - SMEM_KEYPAD_STATE_IDX, - SMEM_GPIO_INT, - SMEM_MDDI_LCD_IDX, - SMEM_MDDI_HOST_DRIVER_STATE, - SMEM_MDDI_LCD_DISP_STATE, - SMEM_LCD_CUR_PANEL, - SMEM_MARM_BOOT_SEGMENT_INFO, - SMEM_AARM_BOOT_SEGMENT_INFO, - SMEM_SLEEP_STATIC, - SMEM_SCORPION_FREQUENCY, - SMEM_SMD_PROFILES, - SMEM_TSSC_BUSY, - SMEM_HS_SUSPEND_FILTER_INFO, - SMEM_BATT_INFO, - SMEM_APPS_BOOT_MODE, - SMEM_VERSION_FIRST, - SMEM_VERSION_LAST = SMEM_VERSION_FIRST + 24, - SMEM_OSS_RRCASN1_BUF1, - SMEM_OSS_RRCASN1_BUF2, - SMEM_ID_VENDOR0, - SMEM_ID_VENDOR1, - SMEM_ID_VENDOR2, - SMEM_HW_SW_BUILD_ID, - SMEM_NUM_ITEMS, -} smem_mem_type; - -#endif diff --git a/drivers/staging/dream/smd/smd_qmi.c b/drivers/staging/dream/smd/smd_qmi.c deleted file mode 100644 index 76fce5142d9e..000000000000 --- a/drivers/staging/dream/smd/smd_qmi.c +++ /dev/null @@ -1,851 +0,0 @@ -/* arch/arm/mach-msm/smd_qmi.c - * - * QMI Control Driver -- Manages network data connections. - * - * Copyright (C) 2007 Google, Inc. - * Author: Brian Swetland - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define QMI_CTL 0x00 -#define QMI_WDS 0x01 -#define QMI_DMS 0x02 -#define QMI_NAS 0x03 - -#define QMI_RESULT_SUCCESS 0x0000 -#define QMI_RESULT_FAILURE 0x0001 - -struct qmi_msg { - unsigned char service; - unsigned char client_id; - unsigned short txn_id; - unsigned short type; - unsigned short size; - unsigned char *tlv; -}; - -#define qmi_ctl_client_id 0 - -#define STATE_OFFLINE 0 -#define STATE_QUERYING 1 -#define STATE_ONLINE 2 - -struct qmi_ctxt { - struct miscdevice misc; - - struct mutex lock; - - unsigned char ctl_txn_id; - unsigned char wds_client_id; - unsigned short wds_txn_id; - - unsigned wds_busy; - unsigned wds_handle; - unsigned state_dirty; - unsigned state; - - unsigned char addr[4]; - unsigned char mask[4]; - unsigned char gateway[4]; - unsigned char dns1[4]; - unsigned char dns2[4]; - - smd_channel_t *ch; - const char *ch_name; - - struct work_struct open_work; - struct work_struct read_work; -}; - -static struct qmi_ctxt *qmi_minor_to_ctxt(unsigned n); - -static void qmi_read_work(struct work_struct *ws); -static void qmi_open_work(struct work_struct *work); - -void qmi_ctxt_init(struct qmi_ctxt *ctxt, unsigned n) -{ - mutex_init(&ctxt->lock); - INIT_WORK(&ctxt->read_work, qmi_read_work); - INIT_WORK(&ctxt->open_work, qmi_open_work); - ctxt->ctl_txn_id = 1; - ctxt->wds_txn_id = 1; - ctxt->wds_busy = 1; - ctxt->state = STATE_OFFLINE; - -} - -static struct workqueue_struct *qmi_wq; - -static int verbose = 0; - -/* anyone waiting for a state change waits here */ -static DECLARE_WAIT_QUEUE_HEAD(qmi_wait_queue); - - -static void qmi_dump_msg(struct qmi_msg *msg, const char *prefix) -{ - unsigned sz, n; - unsigned char *x; - - if (!verbose) - return; - - printk(KERN_INFO - "qmi: %s: svc=%02x cid=%02x tid=%04x type=%04x size=%04x\n", - prefix, msg->service, msg->client_id, - msg->txn_id, msg->type, msg->size); - - x = msg->tlv; - sz = msg->size; - - while (sz >= 3) { - sz -= 3; - - n = x[1] | (x[2] << 8); - if (n > sz) - break; - - printk(KERN_INFO "qmi: %s: tlv: %02x %04x { ", - prefix, x[0], n); - x += 3; - sz -= n; - while (n-- > 0) - printk("%02x ", *x++); - printk("}\n"); - } -} - -int qmi_add_tlv(struct qmi_msg *msg, - unsigned type, unsigned size, const void *data) -{ - unsigned char *x = msg->tlv + msg->size; - - x[0] = type; - x[1] = size; - x[2] = size >> 8; - - memcpy(x + 3, data, size); - - msg->size += (size + 3); - - return 0; -} - -/* Extract a tagged item from a qmi message buffer, -** taking care not to overrun the buffer. -*/ -static int qmi_get_tlv(struct qmi_msg *msg, - unsigned type, unsigned size, void *data) -{ - unsigned char *x = msg->tlv; - unsigned len = msg->size; - unsigned n; - - while (len >= 3) { - len -= 3; - - /* size of this item */ - n = x[1] | (x[2] << 8); - if (n > len) - break; - - if (x[0] == type) { - if (n != size) - return -1; - memcpy(data, x + 3, size); - return 0; - } - - x += (n + 3); - len -= n; - } - - return -1; -} - -static unsigned qmi_get_status(struct qmi_msg *msg, unsigned *error) -{ - unsigned short status[2]; - if (qmi_get_tlv(msg, 0x02, sizeof(status), status)) { - *error = 0; - return QMI_RESULT_FAILURE; - } else { - *error = status[1]; - return status[0]; - } -} - -/* 0x01 */ -#define QMUX_HEADER 13 - -/* should be >= HEADER + FOOTER */ -#define QMUX_OVERHEAD 16 - -static int qmi_send(struct qmi_ctxt *ctxt, struct qmi_msg *msg) -{ - unsigned char *data; - unsigned hlen; - unsigned len; - int r; - - qmi_dump_msg(msg, "send"); - - if (msg->service == QMI_CTL) - hlen = QMUX_HEADER - 1; - else - hlen = QMUX_HEADER; - - /* QMUX length is total header + total payload - IFC selector */ - len = hlen + msg->size - 1; - if (len > 0xffff) - return -1; - - data = msg->tlv - hlen; - - /* prepend encap and qmux header */ - *data++ = 0x01; /* ifc selector */ - - /* qmux header */ - *data++ = len; - *data++ = len >> 8; - *data++ = 0x00; /* flags: client */ - *data++ = msg->service; - *data++ = msg->client_id; - - /* qmi header */ - *data++ = 0x00; /* flags: send */ - *data++ = msg->txn_id; - if (msg->service != QMI_CTL) - *data++ = msg->txn_id >> 8; - - *data++ = msg->type; - *data++ = msg->type >> 8; - *data++ = msg->size; - *data++ = msg->size >> 8; - - /* len + 1 takes the interface selector into account */ - r = smd_write(ctxt->ch, msg->tlv - hlen, len + 1); - - if (r != len) - return -1; - else - return 0; -} - -static void qmi_process_ctl_msg(struct qmi_ctxt *ctxt, struct qmi_msg *msg) -{ - unsigned err; - if (msg->type == 0x0022) { - unsigned char n[2]; - if (qmi_get_status(msg, &err)) - return; - if (qmi_get_tlv(msg, 0x01, sizeof(n), n)) - return; - if (n[0] == QMI_WDS) { - printk(KERN_INFO - "qmi: ctl: wds use client_id 0x%02x\n", n[1]); - ctxt->wds_client_id = n[1]; - ctxt->wds_busy = 0; - } - } -} - -static int qmi_network_get_profile(struct qmi_ctxt *ctxt); - -static void swapaddr(unsigned char *src, unsigned char *dst) -{ - dst[0] = src[3]; - dst[1] = src[2]; - dst[2] = src[1]; - dst[3] = src[0]; -} - -static unsigned char zero[4]; -static void qmi_read_runtime_profile(struct qmi_ctxt *ctxt, struct qmi_msg *msg) -{ - unsigned char tmp[4]; - unsigned r; - - r = qmi_get_tlv(msg, 0x1e, 4, tmp); - swapaddr(r ? zero : tmp, ctxt->addr); - r = qmi_get_tlv(msg, 0x21, 4, tmp); - swapaddr(r ? zero : tmp, ctxt->mask); - r = qmi_get_tlv(msg, 0x20, 4, tmp); - swapaddr(r ? zero : tmp, ctxt->gateway); - r = qmi_get_tlv(msg, 0x15, 4, tmp); - swapaddr(r ? zero : tmp, ctxt->dns1); - r = qmi_get_tlv(msg, 0x16, 4, tmp); - swapaddr(r ? zero : tmp, ctxt->dns2); -} - -static void qmi_process_unicast_wds_msg(struct qmi_ctxt *ctxt, - struct qmi_msg *msg) -{ - unsigned err; - switch (msg->type) { - case 0x0021: - if (qmi_get_status(msg, &err)) { - printk(KERN_ERR - "qmi: wds: network stop failed (%04x)\n", err); - } else { - printk(KERN_INFO - "qmi: wds: network stopped\n"); - ctxt->state = STATE_OFFLINE; - ctxt->state_dirty = 1; - } - break; - case 0x0020: - if (qmi_get_status(msg, &err)) { - printk(KERN_ERR - "qmi: wds: network start failed (%04x)\n", err); - } else if (qmi_get_tlv(msg, 0x01, sizeof(ctxt->wds_handle), &ctxt->wds_handle)) { - printk(KERN_INFO - "qmi: wds no handle?\n"); - } else { - printk(KERN_INFO - "qmi: wds: got handle 0x%08x\n", - ctxt->wds_handle); - } - break; - case 0x002D: - printk("qmi: got network profile\n"); - if (ctxt->state == STATE_QUERYING) { - qmi_read_runtime_profile(ctxt, msg); - ctxt->state = STATE_ONLINE; - ctxt->state_dirty = 1; - } - break; - default: - printk(KERN_ERR "qmi: unknown msg type 0x%04x\n", msg->type); - } - ctxt->wds_busy = 0; -} - -static void qmi_process_broadcast_wds_msg(struct qmi_ctxt *ctxt, - struct qmi_msg *msg) -{ - if (msg->type == 0x0022) { - unsigned char n[2]; - if (qmi_get_tlv(msg, 0x01, sizeof(n), n)) - return; - switch (n[0]) { - case 1: - printk(KERN_INFO "qmi: wds: DISCONNECTED\n"); - ctxt->state = STATE_OFFLINE; - ctxt->state_dirty = 1; - break; - case 2: - printk(KERN_INFO "qmi: wds: CONNECTED\n"); - ctxt->state = STATE_QUERYING; - ctxt->state_dirty = 1; - qmi_network_get_profile(ctxt); - break; - case 3: - printk(KERN_INFO "qmi: wds: SUSPENDED\n"); - ctxt->state = STATE_OFFLINE; - ctxt->state_dirty = 1; - } - } else { - printk(KERN_ERR "qmi: unknown bcast msg type 0x%04x\n", msg->type); - } -} - -static void qmi_process_wds_msg(struct qmi_ctxt *ctxt, - struct qmi_msg *msg) -{ - printk(KERN_INFO "wds: %04x @ %02x\n", msg->type, msg->client_id); - if (msg->client_id == ctxt->wds_client_id) { - qmi_process_unicast_wds_msg(ctxt, msg); - } else if (msg->client_id == 0xff) { - qmi_process_broadcast_wds_msg(ctxt, msg); - } else { - printk(KERN_ERR - "qmi_process_wds_msg client id 0x%02x unknown\n", - msg->client_id); - } -} - -static void qmi_process_qmux(struct qmi_ctxt *ctxt, - unsigned char *buf, unsigned sz) -{ - struct qmi_msg msg; - - /* require a full header */ - if (sz < 5) - return; - - /* require a size that matches the buffer size */ - if (sz != (buf[0] | (buf[1] << 8))) - return; - - /* only messages from a service (bit7=1) are allowed */ - if (buf[2] != 0x80) - return; - - msg.service = buf[3]; - msg.client_id = buf[4]; - - /* annoyingly, CTL messages have a shorter TID */ - if (buf[3] == 0) { - if (sz < 7) - return; - msg.txn_id = buf[6]; - buf += 7; - sz -= 7; - } else { - if (sz < 8) - return; - msg.txn_id = buf[6] | (buf[7] << 8); - buf += 8; - sz -= 8; - } - - /* no type and size!? */ - if (sz < 4) - return; - sz -= 4; - - msg.type = buf[0] | (buf[1] << 8); - msg.size = buf[2] | (buf[3] << 8); - msg.tlv = buf + 4; - - if (sz != msg.size) - return; - - qmi_dump_msg(&msg, "recv"); - - mutex_lock(&ctxt->lock); - switch (msg.service) { - case QMI_CTL: - qmi_process_ctl_msg(ctxt, &msg); - break; - case QMI_WDS: - qmi_process_wds_msg(ctxt, &msg); - break; - default: - printk(KERN_ERR "qmi: msg from unknown svc 0x%02x\n", - msg.service); - break; - } - mutex_unlock(&ctxt->lock); - wake_up(&qmi_wait_queue); -} - -#define QMI_MAX_PACKET (256 + QMUX_OVERHEAD) - -static void qmi_read_work(struct work_struct *ws) -{ - struct qmi_ctxt *ctxt = container_of(ws, struct qmi_ctxt, read_work); - struct smd_channel *ch = ctxt->ch; - unsigned char buf[QMI_MAX_PACKET]; - int sz; - - for (;;) { - sz = smd_cur_packet_size(ch); - if (sz == 0) - break; - if (sz < smd_read_avail(ch)) - break; - if (sz > QMI_MAX_PACKET) { - smd_read(ch, 0, sz); - continue; - } - if (smd_read(ch, buf, sz) != sz) { - printk(KERN_ERR "qmi: not enough data?!\n"); - continue; - } - - /* interface selector must be 1 */ - if (buf[0] != 0x01) - continue; - - qmi_process_qmux(ctxt, buf + 1, sz - 1); - } -} - -static int qmi_request_wds_cid(struct qmi_ctxt *ctxt); - -static void qmi_open_work(struct work_struct *ws) -{ - struct qmi_ctxt *ctxt = container_of(ws, struct qmi_ctxt, open_work); - mutex_lock(&ctxt->lock); - qmi_request_wds_cid(ctxt); - mutex_unlock(&ctxt->lock); -} - -static void qmi_notify(void *priv, unsigned event) -{ - struct qmi_ctxt *ctxt = priv; - - switch (event) { - case SMD_EVENT_DATA: { - int sz; - sz = smd_cur_packet_size(ctxt->ch); - if ((sz > 0) && (sz <= smd_read_avail(ctxt->ch))) - queue_work(qmi_wq, &ctxt->read_work); - break; - } - case SMD_EVENT_OPEN: - printk(KERN_INFO "qmi: smd opened\n"); - queue_work(qmi_wq, &ctxt->open_work); - break; - case SMD_EVENT_CLOSE: - printk(KERN_INFO "qmi: smd closed\n"); - break; - } -} - -static int qmi_request_wds_cid(struct qmi_ctxt *ctxt) -{ - unsigned char data[64 + QMUX_OVERHEAD]; - struct qmi_msg msg; - unsigned char n; - - msg.service = QMI_CTL; - msg.client_id = qmi_ctl_client_id; - msg.txn_id = ctxt->ctl_txn_id; - msg.type = 0x0022; - msg.size = 0; - msg.tlv = data + QMUX_HEADER; - - ctxt->ctl_txn_id += 2; - - n = QMI_WDS; - qmi_add_tlv(&msg, 0x01, 0x01, &n); - - return qmi_send(ctxt, &msg); -} - -static int qmi_network_get_profile(struct qmi_ctxt *ctxt) -{ - unsigned char data[96 + QMUX_OVERHEAD]; - struct qmi_msg msg; - - msg.service = QMI_WDS; - msg.client_id = ctxt->wds_client_id; - msg.txn_id = ctxt->wds_txn_id; - msg.type = 0x002D; - msg.size = 0; - msg.tlv = data + QMUX_HEADER; - - ctxt->wds_txn_id += 2; - - return qmi_send(ctxt, &msg); -} - -static int qmi_network_up(struct qmi_ctxt *ctxt, char *apn) -{ - unsigned char data[96 + QMUX_OVERHEAD]; - struct qmi_msg msg; - char *auth_type; - char *user; - char *pass; - - for (user = apn; *user; user++) { - if (*user == ' ') { - *user++ = 0; - break; - } - } - for (pass = user; *pass; pass++) { - if (*pass == ' ') { - *pass++ = 0; - break; - } - } - - for (auth_type = pass; *auth_type; auth_type++) { - if (*auth_type == ' ') { - *auth_type++ = 0; - break; - } - } - - msg.service = QMI_WDS; - msg.client_id = ctxt->wds_client_id; - msg.txn_id = ctxt->wds_txn_id; - msg.type = 0x0020; - msg.size = 0; - msg.tlv = data + QMUX_HEADER; - - ctxt->wds_txn_id += 2; - - qmi_add_tlv(&msg, 0x14, strlen(apn), apn); - if (*auth_type) - qmi_add_tlv(&msg, 0x16, strlen(auth_type), auth_type); - if (*user) { - if (!*auth_type) { - unsigned char x; - x = 3; - qmi_add_tlv(&msg, 0x16, 1, &x); - } - qmi_add_tlv(&msg, 0x17, strlen(user), user); - if (*pass) - qmi_add_tlv(&msg, 0x18, strlen(pass), pass); - } - return qmi_send(ctxt, &msg); -} - -static int qmi_network_down(struct qmi_ctxt *ctxt) -{ - unsigned char data[16 + QMUX_OVERHEAD]; - struct qmi_msg msg; - - msg.service = QMI_WDS; - msg.client_id = ctxt->wds_client_id; - msg.txn_id = ctxt->wds_txn_id; - msg.type = 0x0021; - msg.size = 0; - msg.tlv = data + QMUX_HEADER; - - ctxt->wds_txn_id += 2; - - qmi_add_tlv(&msg, 0x01, sizeof(ctxt->wds_handle), &ctxt->wds_handle); - - return qmi_send(ctxt, &msg); -} - -static int qmi_print_state(struct qmi_ctxt *ctxt, char *buf, int max) -{ - int i; - char *statename; - - if (ctxt->state == STATE_ONLINE) { - statename = "up"; - } else if (ctxt->state == STATE_OFFLINE) { - statename = "down"; - } else { - statename = "busy"; - } - - i = scnprintf(buf, max, "STATE=%s\n", statename); - i += scnprintf(buf + i, max - i, "CID=%d\n", ctxt->wds_client_id); - - if (ctxt->state != STATE_ONLINE) - return i; - - i += scnprintf(buf + i, max - i, "ADDR=%d.%d.%d.%d\n", - ctxt->addr[0], ctxt->addr[1], ctxt->addr[2], ctxt->addr[3]); - i += scnprintf(buf + i, max - i, "MASK=%d.%d.%d.%d\n", - ctxt->mask[0], ctxt->mask[1], ctxt->mask[2], ctxt->mask[3]); - i += scnprintf(buf + i, max - i, "GATEWAY=%d.%d.%d.%d\n", - ctxt->gateway[0], ctxt->gateway[1], ctxt->gateway[2], - ctxt->gateway[3]); - i += scnprintf(buf + i, max - i, "DNS1=%d.%d.%d.%d\n", - ctxt->dns1[0], ctxt->dns1[1], ctxt->dns1[2], ctxt->dns1[3]); - i += scnprintf(buf + i, max - i, "DNS2=%d.%d.%d.%d\n", - ctxt->dns2[0], ctxt->dns2[1], ctxt->dns2[2], ctxt->dns2[3]); - - return i; -} - -static ssize_t qmi_read(struct file *fp, char __user *buf, - size_t count, loff_t *pos) -{ - struct qmi_ctxt *ctxt = fp->private_data; - char msg[256]; - int len; - int r; - - mutex_lock(&ctxt->lock); - for (;;) { - if (ctxt->state_dirty) { - ctxt->state_dirty = 0; - len = qmi_print_state(ctxt, msg, 256); - break; - } - mutex_unlock(&ctxt->lock); - r = wait_event_interruptible(qmi_wait_queue, ctxt->state_dirty); - if (r < 0) - return r; - mutex_lock(&ctxt->lock); - } - mutex_unlock(&ctxt->lock); - - if (len > count) - len = count; - - if (copy_to_user(buf, msg, len)) - return -EFAULT; - - return len; -} - - -static ssize_t qmi_write(struct file *fp, const char __user *buf, - size_t count, loff_t *pos) -{ - struct qmi_ctxt *ctxt = fp->private_data; - unsigned char cmd[64]; - int len; - int r; - - if (count < 1) - return 0; - - len = count > 63 ? 63 : count; - - if (copy_from_user(cmd, buf, len)) - return -EFAULT; - - cmd[len] = 0; - - /* lazy */ - if (cmd[len-1] == '\n') { - cmd[len-1] = 0; - len--; - } - - if (!strncmp(cmd, "verbose", 7)) { - verbose = 1; - } else if (!strncmp(cmd, "terse", 5)) { - verbose = 0; - } else if (!strncmp(cmd, "poll", 4)) { - ctxt->state_dirty = 1; - wake_up(&qmi_wait_queue); - } else if (!strncmp(cmd, "down", 4)) { -retry_down: - mutex_lock(&ctxt->lock); - if (ctxt->wds_busy) { - mutex_unlock(&ctxt->lock); - r = wait_event_interruptible(qmi_wait_queue, !ctxt->wds_busy); - if (r < 0) - return r; - goto retry_down; - } - ctxt->wds_busy = 1; - qmi_network_down(ctxt); - mutex_unlock(&ctxt->lock); - } else if (!strncmp(cmd, "up:", 3)) { -retry_up: - mutex_lock(&ctxt->lock); - if (ctxt->wds_busy) { - mutex_unlock(&ctxt->lock); - r = wait_event_interruptible(qmi_wait_queue, !ctxt->wds_busy); - if (r < 0) - return r; - goto retry_up; - } - ctxt->wds_busy = 1; - qmi_network_up(ctxt, cmd+3); - mutex_unlock(&ctxt->lock); - } else { - return -EINVAL; - } - - return count; -} - -static int qmi_open(struct inode *ip, struct file *fp) -{ - struct qmi_ctxt *ctxt = qmi_minor_to_ctxt(MINOR(ip->i_rdev)); - int r = 0; - - if (!ctxt) { - printk(KERN_ERR "unknown qmi misc %d\n", MINOR(ip->i_rdev)); - return -ENODEV; - } - - fp->private_data = ctxt; - - mutex_lock(&ctxt->lock); - if (ctxt->ch == 0) - r = smd_open(ctxt->ch_name, &ctxt->ch, ctxt, qmi_notify); - if (r == 0) - wake_up(&qmi_wait_queue); - mutex_unlock(&ctxt->lock); - - return r; -} - -static int qmi_release(struct inode *ip, struct file *fp) -{ - return 0; -} - -static struct file_operations qmi_fops = { - .owner = THIS_MODULE, - .read = qmi_read, - .write = qmi_write, - .open = qmi_open, - .release = qmi_release, -}; - -static struct qmi_ctxt qmi_device0 = { - .ch_name = "SMD_DATA5_CNTL", - .misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "qmi0", - .fops = &qmi_fops, - } -}; -static struct qmi_ctxt qmi_device1 = { - .ch_name = "SMD_DATA6_CNTL", - .misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "qmi1", - .fops = &qmi_fops, - } -}; -static struct qmi_ctxt qmi_device2 = { - .ch_name = "SMD_DATA7_CNTL", - .misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "qmi2", - .fops = &qmi_fops, - } -}; - -static struct qmi_ctxt *qmi_minor_to_ctxt(unsigned n) -{ - if (n == qmi_device0.misc.minor) - return &qmi_device0; - if (n == qmi_device1.misc.minor) - return &qmi_device1; - if (n == qmi_device2.misc.minor) - return &qmi_device2; - return 0; -} - -static int __init qmi_init(void) -{ - int ret; - - qmi_wq = create_singlethread_workqueue("qmi"); - if (qmi_wq == 0) - return -ENOMEM; - - qmi_ctxt_init(&qmi_device0, 0); - qmi_ctxt_init(&qmi_device1, 1); - qmi_ctxt_init(&qmi_device2, 2); - - ret = misc_register(&qmi_device0.misc); - if (ret == 0) - ret = misc_register(&qmi_device1.misc); - if (ret == 0) - ret = misc_register(&qmi_device2.misc); - return ret; -} - -module_init(qmi_init); diff --git a/drivers/staging/dream/smd/smd_rpcrouter.c b/drivers/staging/dream/smd/smd_rpcrouter.c deleted file mode 100644 index 8744a6e499cb..000000000000 --- a/drivers/staging/dream/smd/smd_rpcrouter.c +++ /dev/null @@ -1,1261 +0,0 @@ -/* arch/arm/mach-msm/smd_rpcrouter.c - * - * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2007-2009 QUALCOMM Incorporated. - * Author: San Mehat - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -/* TODO: handle cases where smd_write() will tempfail due to full fifo */ -/* TODO: thread priority? schedule a work to bump it? */ -/* TODO: maybe make server_list_lock a mutex */ -/* TODO: pool fragments to avoid kmalloc/kfree churn */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "smd_rpcrouter.h" - -#define TRACE_R2R_MSG 0 -#define TRACE_R2R_RAW 0 -#define TRACE_RPC_MSG 0 -#define TRACE_NOTIFY_MSG 0 - -#define MSM_RPCROUTER_DEBUG 0 -#define MSM_RPCROUTER_DEBUG_PKT 0 -#define MSM_RPCROUTER_R2R_DEBUG 0 -#define DUMP_ALL_RECEIVED_HEADERS 0 - -#define DIAG(x...) printk("[RR] ERROR " x) - -#if MSM_RPCROUTER_DEBUG -#define D(x...) printk(x) -#else -#define D(x...) do {} while (0) -#endif - -#if TRACE_R2R_MSG -#define RR(x...) printk("[RR] "x) -#else -#define RR(x...) do {} while (0) -#endif - -#if TRACE_RPC_MSG -#define IO(x...) printk("[RPC] "x) -#else -#define IO(x...) do {} while (0) -#endif - -#if TRACE_NOTIFY_MSG -#define NTFY(x...) printk(KERN_ERR "[NOTIFY] "x) -#else -#define NTFY(x...) do {} while (0) -#endif - -static LIST_HEAD(local_endpoints); -static LIST_HEAD(remote_endpoints); - -static LIST_HEAD(server_list); - -static smd_channel_t *smd_channel; -static int initialized; -static wait_queue_head_t newserver_wait; -static wait_queue_head_t smd_wait; - -static DEFINE_SPINLOCK(local_endpoints_lock); -static DEFINE_SPINLOCK(remote_endpoints_lock); -static DEFINE_SPINLOCK(server_list_lock); -static DEFINE_SPINLOCK(smd_lock); - -static struct workqueue_struct *rpcrouter_workqueue; -static int rpcrouter_need_len; - -static atomic_t next_xid = ATOMIC_INIT(1); -static uint8_t next_pacmarkid; - -static void do_read_data(struct work_struct *work); -static void do_create_pdevs(struct work_struct *work); -static void do_create_rpcrouter_pdev(struct work_struct *work); - -static DECLARE_WORK(work_read_data, do_read_data); -static DECLARE_WORK(work_create_pdevs, do_create_pdevs); -static DECLARE_WORK(work_create_rpcrouter_pdev, do_create_rpcrouter_pdev); - -#define RR_STATE_IDLE 0 -#define RR_STATE_HEADER 1 -#define RR_STATE_BODY 2 -#define RR_STATE_ERROR 3 - -struct rr_context { - struct rr_packet *pkt; - uint8_t *ptr; - uint32_t state; /* current assembly state */ - uint32_t count; /* bytes needed in this state */ -}; - -static struct rr_context the_rr_context; - -static struct platform_device rpcrouter_pdev = { - .name = "oncrpc_router", - .id = -1, -}; - - -static int rpcrouter_send_control_msg(union rr_control_msg *msg) -{ - struct rr_header hdr; - unsigned long flags; - int need; - - if (!(msg->cmd == RPCROUTER_CTRL_CMD_HELLO) && !initialized) { - printk(KERN_ERR "rpcrouter_send_control_msg(): Warning, " - "router not initialized\n"); - return -EINVAL; - } - - hdr.version = RPCROUTER_VERSION; - hdr.type = msg->cmd; - hdr.src_pid = RPCROUTER_PID_LOCAL; - hdr.src_cid = RPCROUTER_ROUTER_ADDRESS; - hdr.confirm_rx = 0; - hdr.size = sizeof(*msg); - hdr.dst_pid = 0; - hdr.dst_cid = RPCROUTER_ROUTER_ADDRESS; - - /* TODO: what if channel is full? */ - - need = sizeof(hdr) + hdr.size; - spin_lock_irqsave(&smd_lock, flags); - while (smd_write_avail(smd_channel) < need) { - spin_unlock_irqrestore(&smd_lock, flags); - msleep(250); - spin_lock_irqsave(&smd_lock, flags); - } - smd_write(smd_channel, &hdr, sizeof(hdr)); - smd_write(smd_channel, msg, hdr.size); - spin_unlock_irqrestore(&smd_lock, flags); - return 0; -} - -static struct rr_server *rpcrouter_create_server(uint32_t pid, - uint32_t cid, - uint32_t prog, - uint32_t ver) -{ - struct rr_server *server; - unsigned long flags; - int rc; - - server = kmalloc(sizeof(struct rr_server), GFP_KERNEL); - if (!server) - return ERR_PTR(-ENOMEM); - - memset(server, 0, sizeof(struct rr_server)); - server->pid = pid; - server->cid = cid; - server->prog = prog; - server->vers = ver; - - spin_lock_irqsave(&server_list_lock, flags); - list_add_tail(&server->list, &server_list); - spin_unlock_irqrestore(&server_list_lock, flags); - - if (pid == RPCROUTER_PID_REMOTE) { - rc = msm_rpcrouter_create_server_cdev(server); - if (rc < 0) - goto out_fail; - } - return server; -out_fail: - spin_lock_irqsave(&server_list_lock, flags); - list_del(&server->list); - spin_unlock_irqrestore(&server_list_lock, flags); - kfree(server); - return ERR_PTR(rc); -} - -static void rpcrouter_destroy_server(struct rr_server *server) -{ - unsigned long flags; - - spin_lock_irqsave(&server_list_lock, flags); - list_del(&server->list); - spin_unlock_irqrestore(&server_list_lock, flags); - device_destroy(msm_rpcrouter_class, server->device_number); - kfree(server); -} - -static struct rr_server *rpcrouter_lookup_server(uint32_t prog, uint32_t ver) -{ - struct rr_server *server; - unsigned long flags; - - spin_lock_irqsave(&server_list_lock, flags); - list_for_each_entry(server, &server_list, list) { - if (server->prog == prog - && server->vers == ver) { - spin_unlock_irqrestore(&server_list_lock, flags); - return server; - } - } - spin_unlock_irqrestore(&server_list_lock, flags); - return NULL; -} - -static struct rr_server *rpcrouter_lookup_server_by_dev(dev_t dev) -{ - struct rr_server *server; - unsigned long flags; - - spin_lock_irqsave(&server_list_lock, flags); - list_for_each_entry(server, &server_list, list) { - if (server->device_number == dev) { - spin_unlock_irqrestore(&server_list_lock, flags); - return server; - } - } - spin_unlock_irqrestore(&server_list_lock, flags); - return NULL; -} - -struct msm_rpc_endpoint *msm_rpcrouter_create_local_endpoint(dev_t dev) -{ - struct msm_rpc_endpoint *ept; - unsigned long flags; - - ept = kmalloc(sizeof(struct msm_rpc_endpoint), GFP_KERNEL); - if (!ept) - return NULL; - memset(ept, 0, sizeof(struct msm_rpc_endpoint)); - - /* mark no reply outstanding */ - ept->reply_pid = 0xffffffff; - - ept->cid = (uint32_t) ept; - ept->pid = RPCROUTER_PID_LOCAL; - ept->dev = dev; - - if ((dev != msm_rpcrouter_devno) && (dev != MKDEV(0, 0))) { - struct rr_server *srv; - /* - * This is a userspace client which opened - * a program/ver devicenode. Bind the client - * to that destination - */ - srv = rpcrouter_lookup_server_by_dev(dev); - /* TODO: bug? really? */ - BUG_ON(!srv); - - ept->dst_pid = srv->pid; - ept->dst_cid = srv->cid; - ept->dst_prog = cpu_to_be32(srv->prog); - ept->dst_vers = cpu_to_be32(srv->vers); - - D("Creating local ept %p @ %08x:%08x\n", ept, srv->prog, srv->vers); - } else { - /* mark not connected */ - ept->dst_pid = 0xffffffff; - D("Creating a master local ept %p\n", ept); - } - - init_waitqueue_head(&ept->wait_q); - INIT_LIST_HEAD(&ept->read_q); - spin_lock_init(&ept->read_q_lock); - INIT_LIST_HEAD(&ept->incomplete); - - spin_lock_irqsave(&local_endpoints_lock, flags); - list_add_tail(&ept->list, &local_endpoints); - spin_unlock_irqrestore(&local_endpoints_lock, flags); - return ept; -} - -int msm_rpcrouter_destroy_local_endpoint(struct msm_rpc_endpoint *ept) -{ - int rc; - union rr_control_msg msg; - - msg.cmd = RPCROUTER_CTRL_CMD_REMOVE_CLIENT; - msg.cli.pid = ept->pid; - msg.cli.cid = ept->cid; - - RR("x REMOVE_CLIENT id=%d:%08x\n", ept->pid, ept->cid); - rc = rpcrouter_send_control_msg(&msg); - if (rc < 0) - return rc; - - list_del(&ept->list); - kfree(ept); - return 0; -} - -static int rpcrouter_create_remote_endpoint(uint32_t cid) -{ - struct rr_remote_endpoint *new_c; - unsigned long flags; - - new_c = kmalloc(sizeof(struct rr_remote_endpoint), GFP_KERNEL); - if (!new_c) - return -ENOMEM; - memset(new_c, 0, sizeof(struct rr_remote_endpoint)); - - new_c->cid = cid; - new_c->pid = RPCROUTER_PID_REMOTE; - init_waitqueue_head(&new_c->quota_wait); - spin_lock_init(&new_c->quota_lock); - - spin_lock_irqsave(&remote_endpoints_lock, flags); - list_add_tail(&new_c->list, &remote_endpoints); - spin_unlock_irqrestore(&remote_endpoints_lock, flags); - return 0; -} - -static struct msm_rpc_endpoint *rpcrouter_lookup_local_endpoint(uint32_t cid) -{ - struct msm_rpc_endpoint *ept; - unsigned long flags; - - spin_lock_irqsave(&local_endpoints_lock, flags); - list_for_each_entry(ept, &local_endpoints, list) { - if (ept->cid == cid) { - spin_unlock_irqrestore(&local_endpoints_lock, flags); - return ept; - } - } - spin_unlock_irqrestore(&local_endpoints_lock, flags); - return NULL; -} - -static struct rr_remote_endpoint *rpcrouter_lookup_remote_endpoint(uint32_t cid) -{ - struct rr_remote_endpoint *ept; - unsigned long flags; - - spin_lock_irqsave(&remote_endpoints_lock, flags); - list_for_each_entry(ept, &remote_endpoints, list) { - if (ept->cid == cid) { - spin_unlock_irqrestore(&remote_endpoints_lock, flags); - return ept; - } - } - spin_unlock_irqrestore(&remote_endpoints_lock, flags); - return NULL; -} - -static int process_control_msg(union rr_control_msg *msg, int len) -{ - union rr_control_msg ctl; - struct rr_server *server; - struct rr_remote_endpoint *r_ept; - int rc = 0; - unsigned long flags; - - if (len != sizeof(*msg)) { - printk(KERN_ERR "rpcrouter: r2r msg size %d != %d\n", - len, sizeof(*msg)); - return -EINVAL; - } - - switch (msg->cmd) { - case RPCROUTER_CTRL_CMD_HELLO: - RR("o HELLO\n"); - - RR("x HELLO\n"); - memset(&ctl, 0, sizeof(ctl)); - ctl.cmd = RPCROUTER_CTRL_CMD_HELLO; - rpcrouter_send_control_msg(&ctl); - - initialized = 1; - - /* Send list of servers one at a time */ - ctl.cmd = RPCROUTER_CTRL_CMD_NEW_SERVER; - - /* TODO: long time to hold a spinlock... */ - spin_lock_irqsave(&server_list_lock, flags); - list_for_each_entry(server, &server_list, list) { - ctl.srv.pid = server->pid; - ctl.srv.cid = server->cid; - ctl.srv.prog = server->prog; - ctl.srv.vers = server->vers; - - RR("x NEW_SERVER id=%d:%08x prog=%08x:%08x\n", - server->pid, server->cid, - server->prog, server->vers); - - rpcrouter_send_control_msg(&ctl); - } - spin_unlock_irqrestore(&server_list_lock, flags); - - queue_work(rpcrouter_workqueue, &work_create_rpcrouter_pdev); - break; - - case RPCROUTER_CTRL_CMD_RESUME_TX: - RR("o RESUME_TX id=%d:%08x\n", msg->cli.pid, msg->cli.cid); - - r_ept = rpcrouter_lookup_remote_endpoint(msg->cli.cid); - if (!r_ept) { - printk(KERN_ERR - "rpcrouter: Unable to resume client\n"); - break; - } - spin_lock_irqsave(&r_ept->quota_lock, flags); - r_ept->tx_quota_cntr = 0; - spin_unlock_irqrestore(&r_ept->quota_lock, flags); - wake_up(&r_ept->quota_wait); - break; - - case RPCROUTER_CTRL_CMD_NEW_SERVER: - RR("o NEW_SERVER id=%d:%08x prog=%08x:%08x\n", - msg->srv.pid, msg->srv.cid, msg->srv.prog, msg->srv.vers); - - server = rpcrouter_lookup_server(msg->srv.prog, msg->srv.vers); - - if (!server) { - server = rpcrouter_create_server( - msg->srv.pid, msg->srv.cid, - msg->srv.prog, msg->srv.vers); - if (!server) - return -ENOMEM; - /* - * XXX: Verify that its okay to add the - * client to our remote client list - * if we get a NEW_SERVER notification - */ - if (!rpcrouter_lookup_remote_endpoint(msg->srv.cid)) { - rc = rpcrouter_create_remote_endpoint( - msg->srv.cid); - if (rc < 0) - printk(KERN_ERR - "rpcrouter:Client create" - "error (%d)\n", rc); - } - schedule_work(&work_create_pdevs); - wake_up(&newserver_wait); - } else { - if ((server->pid == msg->srv.pid) && - (server->cid == msg->srv.cid)) { - printk(KERN_ERR "rpcrouter: Duplicate svr\n"); - } else { - server->pid = msg->srv.pid; - server->cid = msg->srv.cid; - } - } - break; - - case RPCROUTER_CTRL_CMD_REMOVE_SERVER: - RR("o REMOVE_SERVER prog=%08x:%d\n", - msg->srv.prog, msg->srv.vers); - server = rpcrouter_lookup_server(msg->srv.prog, msg->srv.vers); - if (server) - rpcrouter_destroy_server(server); - break; - - case RPCROUTER_CTRL_CMD_REMOVE_CLIENT: - RR("o REMOVE_CLIENT id=%d:%08x\n", msg->cli.pid, msg->cli.cid); - if (msg->cli.pid != RPCROUTER_PID_REMOTE) { - printk(KERN_ERR - "rpcrouter: Denying remote removal of " - "local client\n"); - break; - } - r_ept = rpcrouter_lookup_remote_endpoint(msg->cli.cid); - if (r_ept) { - spin_lock_irqsave(&remote_endpoints_lock, flags); - list_del(&r_ept->list); - spin_unlock_irqrestore(&remote_endpoints_lock, flags); - kfree(r_ept); - } - - /* Notify local clients of this event */ - printk(KERN_ERR "rpcrouter: LOCAL NOTIFICATION NOT IMP\n"); - rc = -ENOSYS; - - break; - default: - RR("o UNKNOWN(%08x)\n", msg->cmd); - rc = -ENOSYS; - } - - return rc; -} - -static void do_create_rpcrouter_pdev(struct work_struct *work) -{ - platform_device_register(&rpcrouter_pdev); -} - -static void do_create_pdevs(struct work_struct *work) -{ - unsigned long flags; - struct rr_server *server; - - /* TODO: race if destroyed while being registered */ - spin_lock_irqsave(&server_list_lock, flags); - list_for_each_entry(server, &server_list, list) { - if (server->pid == RPCROUTER_PID_REMOTE) { - if (server->pdev_name[0] == 0) { - spin_unlock_irqrestore(&server_list_lock, - flags); - msm_rpcrouter_create_server_pdev(server); - schedule_work(&work_create_pdevs); - return; - } - } - } - spin_unlock_irqrestore(&server_list_lock, flags); -} - -static void rpcrouter_smdnotify(void *_dev, unsigned event) -{ - if (event != SMD_EVENT_DATA) - return; - - wake_up(&smd_wait); -} - -static void *rr_malloc(unsigned sz) -{ - void *ptr = kmalloc(sz, GFP_KERNEL); - if (ptr) - return ptr; - - printk(KERN_ERR "rpcrouter: kmalloc of %d failed, retrying...\n", sz); - do { - ptr = kmalloc(sz, GFP_KERNEL); - } while (!ptr); - - return ptr; -} - -/* TODO: deal with channel teardown / restore */ -static int rr_read(void *data, int len) -{ - int rc; - unsigned long flags; -// printk("rr_read() %d\n", len); - for(;;) { - spin_lock_irqsave(&smd_lock, flags); - if (smd_read_avail(smd_channel) >= len) { - rc = smd_read(smd_channel, data, len); - spin_unlock_irqrestore(&smd_lock, flags); - if (rc == len) - return 0; - else - return -EIO; - } - rpcrouter_need_len = len; - spin_unlock_irqrestore(&smd_lock, flags); - -// printk("rr_read: waiting (%d)\n", len); - wait_event(smd_wait, smd_read_avail(smd_channel) >= len); - } - return 0; -} - -static uint32_t r2r_buf[RPCROUTER_MSGSIZE_MAX]; - -static void do_read_data(struct work_struct *work) -{ - struct rr_header hdr; - struct rr_packet *pkt; - struct rr_fragment *frag; - struct msm_rpc_endpoint *ept; - uint32_t pm, mid; - unsigned long flags; - - if (rr_read(&hdr, sizeof(hdr))) - goto fail_io; - -#if TRACE_R2R_RAW - RR("- ver=%d type=%d src=%d:%08x crx=%d siz=%d dst=%d:%08x\n", - hdr.version, hdr.type, hdr.src_pid, hdr.src_cid, - hdr.confirm_rx, hdr.size, hdr.dst_pid, hdr.dst_cid); -#endif - - if (hdr.version != RPCROUTER_VERSION) { - DIAG("version %d != %d\n", hdr.version, RPCROUTER_VERSION); - goto fail_data; - } - if (hdr.size > RPCROUTER_MSGSIZE_MAX) { - DIAG("msg size %d > max %d\n", hdr.size, RPCROUTER_MSGSIZE_MAX); - goto fail_data; - } - - if (hdr.dst_cid == RPCROUTER_ROUTER_ADDRESS) { - if (rr_read(r2r_buf, hdr.size)) - goto fail_io; - process_control_msg((void*) r2r_buf, hdr.size); - goto done; - } - - if (hdr.size < sizeof(pm)) { - DIAG("runt packet (no pacmark)\n"); - goto fail_data; - } - if (rr_read(&pm, sizeof(pm))) - goto fail_io; - - hdr.size -= sizeof(pm); - - frag = rr_malloc(hdr.size + sizeof(*frag)); - frag->next = NULL; - frag->length = hdr.size; - if (rr_read(frag->data, hdr.size)) - goto fail_io; - - ept = rpcrouter_lookup_local_endpoint(hdr.dst_cid); - if (!ept) { - DIAG("no local ept for cid %08x\n", hdr.dst_cid); - kfree(frag); - goto done; - } - - /* See if there is already a partial packet that matches our mid - * and if so, append this fragment to that packet. - */ - mid = PACMARK_MID(pm); - list_for_each_entry(pkt, &ept->incomplete, list) { - if (pkt->mid == mid) { - pkt->last->next = frag; - pkt->last = frag; - pkt->length += frag->length; - if (PACMARK_LAST(pm)) { - list_del(&pkt->list); - goto packet_complete; - } - goto done; - } - } - /* This mid is new -- create a packet for it, and put it on - * the incomplete list if this fragment is not a last fragment, - * otherwise put it on the read queue. - */ - pkt = rr_malloc(sizeof(struct rr_packet)); - pkt->first = frag; - pkt->last = frag; - memcpy(&pkt->hdr, &hdr, sizeof(hdr)); - pkt->mid = mid; - pkt->length = frag->length; - if (!PACMARK_LAST(pm)) { - list_add_tail(&pkt->list, &ept->incomplete); - goto done; - } - -packet_complete: - spin_lock_irqsave(&ept->read_q_lock, flags); - list_add_tail(&pkt->list, &ept->read_q); - wake_up(&ept->wait_q); - spin_unlock_irqrestore(&ept->read_q_lock, flags); -done: - - if (hdr.confirm_rx) { - union rr_control_msg msg; - - msg.cmd = RPCROUTER_CTRL_CMD_RESUME_TX; - msg.cli.pid = hdr.dst_pid; - msg.cli.cid = hdr.dst_cid; - - RR("x RESUME_TX id=%d:%08x\n", msg.cli.pid, msg.cli.cid); - rpcrouter_send_control_msg(&msg); - } - - queue_work(rpcrouter_workqueue, &work_read_data); - return; - -fail_io: -fail_data: - printk(KERN_ERR "rpc_router has died\n"); -} - -void msm_rpc_setup_req(struct rpc_request_hdr *hdr, uint32_t prog, - uint32_t vers, uint32_t proc) -{ - memset(hdr, 0, sizeof(struct rpc_request_hdr)); - hdr->xid = cpu_to_be32(atomic_add_return(1, &next_xid)); - hdr->rpc_vers = cpu_to_be32(2); - hdr->prog = cpu_to_be32(prog); - hdr->vers = cpu_to_be32(vers); - hdr->procedure = cpu_to_be32(proc); -} - -struct msm_rpc_endpoint *msm_rpc_open(void) -{ - struct msm_rpc_endpoint *ept; - - ept = msm_rpcrouter_create_local_endpoint(MKDEV(0, 0)); - if (ept == NULL) - return ERR_PTR(-ENOMEM); - - return ept; -} - -int msm_rpc_close(struct msm_rpc_endpoint *ept) -{ - return msm_rpcrouter_destroy_local_endpoint(ept); -} -EXPORT_SYMBOL(msm_rpc_close); - -int msm_rpc_write(struct msm_rpc_endpoint *ept, void *buffer, int count) -{ - struct rr_header hdr; - uint32_t pacmark; - struct rpc_request_hdr *rq = buffer; - struct rr_remote_endpoint *r_ept; - unsigned long flags; - int needed; - DEFINE_WAIT(__wait); - - /* TODO: fragmentation for large outbound packets */ - if (count > (RPCROUTER_MSGSIZE_MAX - sizeof(uint32_t)) || !count) - return -EINVAL; - - /* snoop the RPC packet and enforce permissions */ - - /* has to have at least the xid and type fields */ - if (count < (sizeof(uint32_t) * 2)) { - printk(KERN_ERR "rr_write: rejecting runt packet\n"); - return -EINVAL; - } - - if (rq->type == 0) { - /* RPC CALL */ - if (count < (sizeof(uint32_t) * 6)) { - printk(KERN_ERR - "rr_write: rejecting runt call packet\n"); - return -EINVAL; - } - if (ept->dst_pid == 0xffffffff) { - printk(KERN_ERR "rr_write: not connected\n"); - return -ENOTCONN; - } - -#if CONFIG_MSM_AMSS_VERSION >= 6350 - if ((ept->dst_prog != rq->prog) || - !msm_rpc_is_compatible_version( - be32_to_cpu(ept->dst_vers), - be32_to_cpu(rq->vers))) { -#else - if (ept->dst_prog != rq->prog || ept->dst_vers != rq->vers) { -#endif - printk(KERN_ERR - "rr_write: cannot write to %08x:%d " - "(bound to %08x:%d)\n", - be32_to_cpu(rq->prog), be32_to_cpu(rq->vers), - be32_to_cpu(ept->dst_prog), - be32_to_cpu(ept->dst_vers)); - return -EINVAL; - } - hdr.dst_pid = ept->dst_pid; - hdr.dst_cid = ept->dst_cid; - IO("CALL on ept %p to %08x:%08x @ %d:%08x (%d bytes) (xid %x proc %x)\n", - ept, - be32_to_cpu(rq->prog), be32_to_cpu(rq->vers), - ept->dst_pid, ept->dst_cid, count, - be32_to_cpu(rq->xid), be32_to_cpu(rq->procedure)); - } else { - /* RPC REPLY */ - /* TODO: locking */ - if (ept->reply_pid == 0xffffffff) { - printk(KERN_ERR - "rr_write: rejecting unexpected reply\n"); - return -EINVAL; - } - if (ept->reply_xid != rq->xid) { - printk(KERN_ERR - "rr_write: rejecting packet w/ bad xid\n"); - return -EINVAL; - } - - hdr.dst_pid = ept->reply_pid; - hdr.dst_cid = ept->reply_cid; - - /* consume this reply */ - ept->reply_pid = 0xffffffff; - - IO("REPLY on ept %p to xid=%d @ %d:%08x (%d bytes)\n", - ept, - be32_to_cpu(rq->xid), hdr.dst_pid, hdr.dst_cid, count); - } - - r_ept = rpcrouter_lookup_remote_endpoint(hdr.dst_cid); - - if (!r_ept) { - printk(KERN_ERR - "msm_rpc_write(): No route to ept " - "[PID %x CID %x]\n", hdr.dst_pid, hdr.dst_cid); - return -EHOSTUNREACH; - } - - /* Create routing header */ - hdr.type = RPCROUTER_CTRL_CMD_DATA; - hdr.version = RPCROUTER_VERSION; - hdr.src_pid = ept->pid; - hdr.src_cid = ept->cid; - hdr.confirm_rx = 0; - hdr.size = count + sizeof(uint32_t); - - for (;;) { - prepare_to_wait(&r_ept->quota_wait, &__wait, - TASK_INTERRUPTIBLE); - spin_lock_irqsave(&r_ept->quota_lock, flags); - if (r_ept->tx_quota_cntr < RPCROUTER_DEFAULT_RX_QUOTA) - break; - if (signal_pending(current) && - (!(ept->flags & MSM_RPC_UNINTERRUPTIBLE))) - break; - spin_unlock_irqrestore(&r_ept->quota_lock, flags); - schedule(); - } - finish_wait(&r_ept->quota_wait, &__wait); - - if (signal_pending(current) && - (!(ept->flags & MSM_RPC_UNINTERRUPTIBLE))) { - spin_unlock_irqrestore(&r_ept->quota_lock, flags); - return -ERESTARTSYS; - } - r_ept->tx_quota_cntr++; - if (r_ept->tx_quota_cntr == RPCROUTER_DEFAULT_RX_QUOTA) - hdr.confirm_rx = 1; - - /* bump pacmark while interrupts disabled to avoid race - * probably should be atomic op instead - */ - pacmark = PACMARK(count, ++next_pacmarkid, 0, 1); - - spin_unlock_irqrestore(&r_ept->quota_lock, flags); - - spin_lock_irqsave(&smd_lock, flags); - - needed = sizeof(hdr) + hdr.size; - while (smd_write_avail(smd_channel) < needed) { - spin_unlock_irqrestore(&smd_lock, flags); - msleep(250); - spin_lock_irqsave(&smd_lock, flags); - } - - /* TODO: deal with full fifo */ - smd_write(smd_channel, &hdr, sizeof(hdr)); - smd_write(smd_channel, &pacmark, sizeof(pacmark)); - smd_write(smd_channel, buffer, count); - - spin_unlock_irqrestore(&smd_lock, flags); - - return count; -} -EXPORT_SYMBOL(msm_rpc_write); - -/* - * NOTE: It is the responsibility of the caller to kfree buffer - */ -int msm_rpc_read(struct msm_rpc_endpoint *ept, void **buffer, - unsigned user_len, long timeout) -{ - struct rr_fragment *frag, *next; - char *buf; - int rc; - - rc = __msm_rpc_read(ept, &frag, user_len, timeout); - if (rc <= 0) - return rc; - - /* single-fragment messages conveniently can be - * returned as-is (the buffer is at the front) - */ - if (frag->next == 0) { - *buffer = (void*) frag; - return rc; - } - - /* multi-fragment messages, we have to do it the - * hard way, which is rather disgusting right now - */ - buf = rr_malloc(rc); - *buffer = buf; - - while (frag != NULL) { - memcpy(buf, frag->data, frag->length); - next = frag->next; - buf += frag->length; - kfree(frag); - frag = next; - } - - return rc; -} - -int msm_rpc_call(struct msm_rpc_endpoint *ept, uint32_t proc, - void *_request, int request_size, - long timeout) -{ - return msm_rpc_call_reply(ept, proc, - _request, request_size, - NULL, 0, timeout); -} -EXPORT_SYMBOL(msm_rpc_call); - -int msm_rpc_call_reply(struct msm_rpc_endpoint *ept, uint32_t proc, - void *_request, int request_size, - void *_reply, int reply_size, - long timeout) -{ - struct rpc_request_hdr *req = _request; - struct rpc_reply_hdr *reply; - int rc; - - if (request_size < sizeof(*req)) - return -ETOOSMALL; - - if (ept->dst_pid == 0xffffffff) - return -ENOTCONN; - - /* We can't use msm_rpc_setup_req() here, because dst_prog and - * dst_vers here are already in BE. - */ - memset(req, 0, sizeof(*req)); - req->xid = cpu_to_be32(atomic_add_return(1, &next_xid)); - req->rpc_vers = cpu_to_be32(2); - req->prog = ept->dst_prog; - req->vers = ept->dst_vers; - req->procedure = cpu_to_be32(proc); - - rc = msm_rpc_write(ept, req, request_size); - if (rc < 0) - return rc; - - for (;;) { - rc = msm_rpc_read(ept, (void*) &reply, -1, timeout); - if (rc < 0) - return rc; - if (rc < (3 * sizeof(uint32_t))) { - rc = -EIO; - break; - } - /* we should not get CALL packets -- ignore them */ - if (reply->type == 0) { - kfree(reply); - continue; - } - /* If an earlier call timed out, we could get the (no - * longer wanted) reply for it. Ignore replies that - * we don't expect. - */ - if (reply->xid != req->xid) { - kfree(reply); - continue; - } - if (reply->reply_stat != 0) { - rc = -EPERM; - break; - } - if (reply->data.acc_hdr.accept_stat != 0) { - rc = -EINVAL; - break; - } - if (_reply == NULL) { - rc = 0; - break; - } - if (rc > reply_size) { - rc = -ENOMEM; - } else { - memcpy(_reply, reply, rc); - } - break; - } - kfree(reply); - return rc; -} -EXPORT_SYMBOL(msm_rpc_call_reply); - - -static inline int ept_packet_available(struct msm_rpc_endpoint *ept) -{ - unsigned long flags; - int ret; - spin_lock_irqsave(&ept->read_q_lock, flags); - ret = !list_empty(&ept->read_q); - spin_unlock_irqrestore(&ept->read_q_lock, flags); - return ret; -} - -int __msm_rpc_read(struct msm_rpc_endpoint *ept, - struct rr_fragment **frag_ret, - unsigned len, long timeout) -{ - struct rr_packet *pkt; - struct rpc_request_hdr *rq; - DEFINE_WAIT(__wait); - unsigned long flags; - int rc; - - IO("READ on ept %p\n", ept); - - if (ept->flags & MSM_RPC_UNINTERRUPTIBLE) { - if (timeout < 0) { - wait_event(ept->wait_q, ept_packet_available(ept)); - } else { - rc = wait_event_timeout( - ept->wait_q, ept_packet_available(ept), - timeout); - if (rc == 0) - return -ETIMEDOUT; - } - } else { - if (timeout < 0) { - rc = wait_event_interruptible( - ept->wait_q, ept_packet_available(ept)); - if (rc < 0) - return rc; - } else { - rc = wait_event_interruptible_timeout( - ept->wait_q, ept_packet_available(ept), - timeout); - if (rc == 0) - return -ETIMEDOUT; - } - } - - spin_lock_irqsave(&ept->read_q_lock, flags); - if (list_empty(&ept->read_q)) { - spin_unlock_irqrestore(&ept->read_q_lock, flags); - return -EAGAIN; - } - pkt = list_first_entry(&ept->read_q, struct rr_packet, list); - if (pkt->length > len) { - spin_unlock_irqrestore(&ept->read_q_lock, flags); - return -ETOOSMALL; - } - list_del(&pkt->list); - spin_unlock_irqrestore(&ept->read_q_lock, flags); - - rc = pkt->length; - - *frag_ret = pkt->first; - rq = (void*) pkt->first->data; - if ((rc >= (sizeof(uint32_t) * 3)) && (rq->type == 0)) { - IO("READ on ept %p is a CALL on %08x:%08x proc %d xid %d\n", - ept, be32_to_cpu(rq->prog), be32_to_cpu(rq->vers), - be32_to_cpu(rq->procedure), - be32_to_cpu(rq->xid)); - /* RPC CALL */ - if (ept->reply_pid != 0xffffffff) { - printk(KERN_WARNING - "rr_read: lost previous reply xid...\n"); - } - /* TODO: locking? */ - ept->reply_pid = pkt->hdr.src_pid; - ept->reply_cid = pkt->hdr.src_cid; - ept->reply_xid = rq->xid; - } -#if TRACE_RPC_MSG - else if ((rc >= (sizeof(uint32_t) * 3)) && (rq->type == 1)) - IO("READ on ept %p is a REPLY\n", ept); - else IO("READ on ept %p (%d bytes)\n", ept, rc); -#endif - - kfree(pkt); - return rc; -} - -#if CONFIG_MSM_AMSS_VERSION >= 6350 -int msm_rpc_is_compatible_version(uint32_t server_version, - uint32_t client_version) -{ - if ((server_version & RPC_VERSION_MODE_MASK) != - (client_version & RPC_VERSION_MODE_MASK)) - return 0; - - if (server_version & RPC_VERSION_MODE_MASK) - return server_version == client_version; - - return ((server_version & RPC_VERSION_MAJOR_MASK) == - (client_version & RPC_VERSION_MAJOR_MASK)) && - ((server_version & RPC_VERSION_MINOR_MASK) >= - (client_version & RPC_VERSION_MINOR_MASK)); -} -EXPORT_SYMBOL(msm_rpc_is_compatible_version); - -static int msm_rpc_get_compatible_server(uint32_t prog, - uint32_t ver, - uint32_t *found_vers) -{ - struct rr_server *server; - unsigned long flags; - if (found_vers == NULL) - return 0; - - spin_lock_irqsave(&server_list_lock, flags); - list_for_each_entry(server, &server_list, list) { - if ((server->prog == prog) && - msm_rpc_is_compatible_version(server->vers, ver)) { - *found_vers = server->vers; - spin_unlock_irqrestore(&server_list_lock, flags); - return 0; - } - } - spin_unlock_irqrestore(&server_list_lock, flags); - return -1; -} -#endif - -struct msm_rpc_endpoint *msm_rpc_connect(uint32_t prog, uint32_t vers, unsigned flags) -{ - struct msm_rpc_endpoint *ept; - struct rr_server *server; - -#if CONFIG_MSM_AMSS_VERSION >= 6350 - if (!(vers & RPC_VERSION_MODE_MASK)) { - uint32_t found_vers; - if (msm_rpc_get_compatible_server(prog, vers, &found_vers) < 0) - return ERR_PTR(-EHOSTUNREACH); - if (found_vers != vers) { - D("RPC using new version %08x:{%08x --> %08x}\n", - prog, vers, found_vers); - vers = found_vers; - } - } -#endif - - server = rpcrouter_lookup_server(prog, vers); - if (!server) - return ERR_PTR(-EHOSTUNREACH); - - ept = msm_rpc_open(); - if (IS_ERR(ept)) - return ept; - - ept->flags = flags; - ept->dst_pid = server->pid; - ept->dst_cid = server->cid; - ept->dst_prog = cpu_to_be32(prog); - ept->dst_vers = cpu_to_be32(vers); - - return ept; -} -EXPORT_SYMBOL(msm_rpc_connect); - -uint32_t msm_rpc_get_vers(struct msm_rpc_endpoint *ept) -{ - return be32_to_cpu(ept->dst_vers); -} -EXPORT_SYMBOL(msm_rpc_get_vers); - -/* TODO: permission check? */ -int msm_rpc_register_server(struct msm_rpc_endpoint *ept, - uint32_t prog, uint32_t vers) -{ - int rc; - union rr_control_msg msg; - struct rr_server *server; - - server = rpcrouter_create_server(ept->pid, ept->cid, - prog, vers); - if (!server) - return -ENODEV; - - msg.srv.cmd = RPCROUTER_CTRL_CMD_NEW_SERVER; - msg.srv.pid = ept->pid; - msg.srv.cid = ept->cid; - msg.srv.prog = prog; - msg.srv.vers = vers; - - RR("x NEW_SERVER id=%d:%08x prog=%08x:%08x\n", - ept->pid, ept->cid, prog, vers); - - rc = rpcrouter_send_control_msg(&msg); - if (rc < 0) - return rc; - - return 0; -} - -/* TODO: permission check -- disallow unreg of somebody else's server */ -int msm_rpc_unregister_server(struct msm_rpc_endpoint *ept, - uint32_t prog, uint32_t vers) -{ - struct rr_server *server; - server = rpcrouter_lookup_server(prog, vers); - - if (!server) - return -ENOENT; - rpcrouter_destroy_server(server); - return 0; -} - -static int msm_rpcrouter_probe(struct platform_device *pdev) -{ - int rc; - - /* Initialize what we need to start processing */ - INIT_LIST_HEAD(&local_endpoints); - INIT_LIST_HEAD(&remote_endpoints); - - init_waitqueue_head(&newserver_wait); - init_waitqueue_head(&smd_wait); - - rpcrouter_workqueue = create_singlethread_workqueue("rpcrouter"); - if (!rpcrouter_workqueue) - return -ENOMEM; - - rc = msm_rpcrouter_init_devices(); - if (rc < 0) - goto fail_destroy_workqueue; - - /* Open up SMD channel 2 */ - initialized = 0; - rc = smd_open("SMD_RPCCALL", &smd_channel, NULL, rpcrouter_smdnotify); - if (rc < 0) - goto fail_remove_devices; - - queue_work(rpcrouter_workqueue, &work_read_data); - return 0; - - fail_remove_devices: - msm_rpcrouter_exit_devices(); - fail_destroy_workqueue: - destroy_workqueue(rpcrouter_workqueue); - return rc; -} - -static struct platform_driver msm_smd_channel2_driver = { - .probe = msm_rpcrouter_probe, - .driver = { - .name = "SMD_RPCCALL", - .owner = THIS_MODULE, - }, -}; - -static int __init rpcrouter_init(void) -{ - return platform_driver_register(&msm_smd_channel2_driver); -} - -module_init(rpcrouter_init); -MODULE_DESCRIPTION("MSM RPC Router"); -MODULE_AUTHOR("San Mehat "); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/dream/smd/smd_rpcrouter.h b/drivers/staging/dream/smd/smd_rpcrouter.h deleted file mode 100644 index 86ab997b1b79..000000000000 --- a/drivers/staging/dream/smd/smd_rpcrouter.h +++ /dev/null @@ -1,193 +0,0 @@ -/** arch/arm/mach-msm/smd_rpcrouter.h - * - * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2007-2008 QUALCOMM Incorporated. - * Author: San Mehat - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _ARCH_ARM_MACH_MSM_SMD_RPCROUTER_H -#define _ARCH_ARM_MACH_MSM_SMD_RPCROUTER_H - -#include -#include -#include -#include - -#include -#include - -/* definitions for the R2R wire protcol */ - -#define RPCROUTER_VERSION 1 -#define RPCROUTER_PROCESSORS_MAX 4 -#define RPCROUTER_MSGSIZE_MAX 512 - -#define RPCROUTER_CLIENT_BCAST_ID 0xffffffff -#define RPCROUTER_ROUTER_ADDRESS 0xfffffffe - -#define RPCROUTER_PID_LOCAL 1 -#define RPCROUTER_PID_REMOTE 0 - -#define RPCROUTER_CTRL_CMD_DATA 1 -#define RPCROUTER_CTRL_CMD_HELLO 2 -#define RPCROUTER_CTRL_CMD_BYE 3 -#define RPCROUTER_CTRL_CMD_NEW_SERVER 4 -#define RPCROUTER_CTRL_CMD_REMOVE_SERVER 5 -#define RPCROUTER_CTRL_CMD_REMOVE_CLIENT 6 -#define RPCROUTER_CTRL_CMD_RESUME_TX 7 -#define RPCROUTER_CTRL_CMD_EXIT 8 - -#define RPCROUTER_DEFAULT_RX_QUOTA 5 - -union rr_control_msg { - uint32_t cmd; - struct { - uint32_t cmd; - uint32_t prog; - uint32_t vers; - uint32_t pid; - uint32_t cid; - } srv; - struct { - uint32_t cmd; - uint32_t pid; - uint32_t cid; - } cli; -}; - -struct rr_header { - uint32_t version; - uint32_t type; - uint32_t src_pid; - uint32_t src_cid; - uint32_t confirm_rx; - uint32_t size; - uint32_t dst_pid; - uint32_t dst_cid; -}; - -/* internals */ - -#define RPCROUTER_MAX_REMOTE_SERVERS 100 - -struct rr_fragment { - unsigned char data[RPCROUTER_MSGSIZE_MAX]; - uint32_t length; - struct rr_fragment *next; -}; - -struct rr_packet { - struct list_head list; - struct rr_fragment *first; - struct rr_fragment *last; - struct rr_header hdr; - uint32_t mid; - uint32_t length; -}; - -#define PACMARK_LAST(n) ((n) & 0x80000000) -#define PACMARK_MID(n) (((n) >> 16) & 0xFF) -#define PACMARK_LEN(n) ((n) & 0xFFFF) - -static inline uint32_t PACMARK(uint32_t len, uint32_t mid, uint32_t first, - uint32_t last) -{ - return (len & 0xFFFF) | - ((mid & 0xFF) << 16) | - ((!!first) << 30) | - ((!!last) << 31); -} - -struct rr_server { - struct list_head list; - - uint32_t pid; - uint32_t cid; - uint32_t prog; - uint32_t vers; - - dev_t device_number; - struct cdev cdev; - struct device *device; - struct rpcsvr_platform_device p_device; - char pdev_name[32]; -}; - -struct rr_remote_endpoint { - uint32_t pid; - uint32_t cid; - - int tx_quota_cntr; - spinlock_t quota_lock; - wait_queue_head_t quota_wait; - - struct list_head list; -}; - -struct msm_rpc_endpoint { - struct list_head list; - - /* incomplete packets waiting for assembly */ - struct list_head incomplete; - - /* complete packets waiting to be read */ - struct list_head read_q; - spinlock_t read_q_lock; - wait_queue_head_t wait_q; - unsigned flags; - - /* endpoint address */ - uint32_t pid; - uint32_t cid; - - /* bound remote address - * if not connected (dst_pid == 0xffffffff) RPC_CALL writes fail - * RPC_CALLs must be to the prog/vers below or they will fail - */ - uint32_t dst_pid; - uint32_t dst_cid; - uint32_t dst_prog; /* be32 */ - uint32_t dst_vers; /* be32 */ - - /* reply remote address - * if reply_pid == 0xffffffff, none available - * RPC_REPLY writes may only go to the pid/cid/xid of the - * last RPC_CALL we received. - */ - uint32_t reply_pid; - uint32_t reply_cid; - uint32_t reply_xid; /* be32 */ - uint32_t next_pm; /* Pacmark sequence */ - - /* device node if this endpoint is accessed via userspace */ - dev_t dev; -}; - -/* shared between smd_rpcrouter*.c */ - -int __msm_rpc_read(struct msm_rpc_endpoint *ept, - struct rr_fragment **frag, - unsigned len, long timeout); - -struct msm_rpc_endpoint *msm_rpcrouter_create_local_endpoint(dev_t dev); -int msm_rpcrouter_destroy_local_endpoint(struct msm_rpc_endpoint *ept); - -int msm_rpcrouter_create_server_cdev(struct rr_server *server); -int msm_rpcrouter_create_server_pdev(struct rr_server *server); - -int msm_rpcrouter_init_devices(void); -void msm_rpcrouter_exit_devices(void); - -extern dev_t msm_rpcrouter_devno; -extern struct class *msm_rpcrouter_class; -#endif diff --git a/drivers/staging/dream/smd/smd_rpcrouter_device.c b/drivers/staging/dream/smd/smd_rpcrouter_device.c deleted file mode 100644 index e9c28eddce31..000000000000 --- a/drivers/staging/dream/smd/smd_rpcrouter_device.c +++ /dev/null @@ -1,377 +0,0 @@ -/* arch/arm/mach-msm/smd_rpcrouter_device.c - * - * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2007-2009 QUALCOMM Incorporated. - * Author: San Mehat - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "smd_rpcrouter.h" - -#define SAFETY_MEM_SIZE 65536 - -/* Next minor # available for a remote server */ -static int next_minor = 1; - -struct class *msm_rpcrouter_class; -dev_t msm_rpcrouter_devno; - -static struct cdev rpcrouter_cdev; -static struct device *rpcrouter_device; - -static int rpcrouter_open(struct inode *inode, struct file *filp) -{ - int rc; - struct msm_rpc_endpoint *ept; - - rc = nonseekable_open(inode, filp); - if (rc < 0) - return rc; - - ept = msm_rpcrouter_create_local_endpoint(inode->i_rdev); - if (!ept) - return -ENOMEM; - - filp->private_data = ept; - return 0; -} - -static int rpcrouter_release(struct inode *inode, struct file *filp) -{ - struct msm_rpc_endpoint *ept; - ept = (struct msm_rpc_endpoint *) filp->private_data; - - return msm_rpcrouter_destroy_local_endpoint(ept); -} - -static ssize_t rpcrouter_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) -{ - struct msm_rpc_endpoint *ept; - struct rr_fragment *frag, *next; - int rc; - - ept = (struct msm_rpc_endpoint *) filp->private_data; - - rc = __msm_rpc_read(ept, &frag, count, -1); - if (rc < 0) - return rc; - - count = rc; - - while (frag != NULL) { - if (copy_to_user(buf, frag->data, frag->length)) { - printk(KERN_ERR - "rpcrouter: could not copy all read data to user!\n"); - rc = -EFAULT; - } - buf += frag->length; - next = frag->next; - kfree(frag); - frag = next; - } - - return rc; -} - -static ssize_t rpcrouter_write(struct file *filp, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct msm_rpc_endpoint *ept; - int rc = 0; - void *k_buffer; - - ept = (struct msm_rpc_endpoint *) filp->private_data; - - /* A check for safety, this seems non-standard */ - if (count > SAFETY_MEM_SIZE) - return -EINVAL; - - k_buffer = kmalloc(count, GFP_KERNEL); - if (!k_buffer) - return -ENOMEM; - - if (copy_from_user(k_buffer, buf, count)) { - rc = -EFAULT; - goto write_out_free; - } - - rc = msm_rpc_write(ept, k_buffer, count); - if (rc < 0) - goto write_out_free; - - rc = count; -write_out_free: - kfree(k_buffer); - return rc; -} - -static unsigned int rpcrouter_poll(struct file *filp, - struct poll_table_struct *wait) -{ - struct msm_rpc_endpoint *ept; - unsigned mask = 0; - ept = (struct msm_rpc_endpoint *) filp->private_data; - - /* If there's data already in the read queue, return POLLIN. - * Else, wait for the requested amount of time, and check again. - */ - - if (!list_empty(&ept->read_q)) - mask |= POLLIN; - - if (!mask) { - poll_wait(filp, &ept->wait_q, wait); - if (!list_empty(&ept->read_q)) - mask |= POLLIN; - } - - return mask; -} - -static long rpcrouter_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg) -{ - struct msm_rpc_endpoint *ept; - struct rpcrouter_ioctl_server_args server_args; - int rc = 0; - uint32_t n; - - ept = (struct msm_rpc_endpoint *) filp->private_data; - switch (cmd) { - - case RPC_ROUTER_IOCTL_GET_VERSION: - n = RPC_ROUTER_VERSION_V1; - rc = put_user(n, (unsigned int *) arg); - break; - - case RPC_ROUTER_IOCTL_GET_MTU: - /* the pacmark word reduces the actual payload - * possible per message - */ - n = RPCROUTER_MSGSIZE_MAX - sizeof(uint32_t); - rc = put_user(n, (unsigned int *) arg); - break; - - case RPC_ROUTER_IOCTL_REGISTER_SERVER: - rc = copy_from_user(&server_args, (void *) arg, - sizeof(server_args)); - if (rc < 0) - break; - msm_rpc_register_server(ept, - server_args.prog, - server_args.vers); - break; - - case RPC_ROUTER_IOCTL_UNREGISTER_SERVER: - rc = copy_from_user(&server_args, (void *) arg, - sizeof(server_args)); - if (rc < 0) - break; - - msm_rpc_unregister_server(ept, - server_args.prog, - server_args.vers); - break; - - case RPC_ROUTER_IOCTL_GET_MINOR_VERSION: - n = MSM_RPC_GET_MINOR(msm_rpc_get_vers(ept)); - rc = put_user(n, (unsigned int *)arg); - break; - - default: - rc = -EINVAL; - break; - } - - return rc; -} - -static struct file_operations rpcrouter_server_fops = { - .owner = THIS_MODULE, - .open = rpcrouter_open, - .release = rpcrouter_release, - .read = rpcrouter_read, - .write = rpcrouter_write, - .poll = rpcrouter_poll, - .unlocked_ioctl = rpcrouter_ioctl, -}; - -static struct file_operations rpcrouter_router_fops = { - .owner = THIS_MODULE, - .open = rpcrouter_open, - .release = rpcrouter_release, - .read = rpcrouter_read, - .write = rpcrouter_write, - .poll = rpcrouter_poll, - .unlocked_ioctl = rpcrouter_ioctl, -}; - -int msm_rpcrouter_create_server_cdev(struct rr_server *server) -{ - int rc; - uint32_t dev_vers; - - if (next_minor == RPCROUTER_MAX_REMOTE_SERVERS) { - printk(KERN_ERR - "rpcrouter: Minor numbers exhausted - Increase " - "RPCROUTER_MAX_REMOTE_SERVERS\n"); - return -ENOBUFS; - } - -#if CONFIG_MSM_AMSS_VERSION >= 6350 - /* Servers with bit 31 set are remote msm servers with hashkey version. - * Servers with bit 31 not set are remote msm servers with - * backwards compatible version type in which case the minor number - * (lower 16 bits) is set to zero. - * - */ - if ((server->vers & RPC_VERSION_MODE_MASK)) - dev_vers = server->vers; - else - dev_vers = server->vers & RPC_VERSION_MAJOR_MASK; -#else - dev_vers = server->vers; -#endif - - server->device_number = - MKDEV(MAJOR(msm_rpcrouter_devno), next_minor++); - - server->device = - device_create(msm_rpcrouter_class, rpcrouter_device, - server->device_number, NULL, "%.8x:%.8x", - server->prog, dev_vers); - if (IS_ERR(server->device)) { - printk(KERN_ERR - "rpcrouter: Unable to create device (%ld)\n", - PTR_ERR(server->device)); - return PTR_ERR(server->device);; - } - - cdev_init(&server->cdev, &rpcrouter_server_fops); - server->cdev.owner = THIS_MODULE; - - rc = cdev_add(&server->cdev, server->device_number, 1); - if (rc < 0) { - printk(KERN_ERR - "rpcrouter: Unable to add chrdev (%d)\n", rc); - device_destroy(msm_rpcrouter_class, server->device_number); - return rc; - } - return 0; -} - -/* for backward compatible version type (31st bit cleared) - * clearing minor number (lower 16 bits) in device name - * is neccessary for driver binding - */ -int msm_rpcrouter_create_server_pdev(struct rr_server *server) -{ - sprintf(server->pdev_name, "rs%.8x:%.8x", - server->prog, -#if CONFIG_MSM_AMSS_VERSION >= 6350 - (server->vers & RPC_VERSION_MODE_MASK) ? server->vers : - (server->vers & RPC_VERSION_MAJOR_MASK)); -#else - server->vers); -#endif - - server->p_device.base.id = -1; - server->p_device.base.name = server->pdev_name; - - server->p_device.prog = server->prog; - server->p_device.vers = server->vers; - - platform_device_register(&server->p_device.base); - return 0; -} - -int msm_rpcrouter_init_devices(void) -{ - int rc; - int major; - - /* Create the device nodes */ - msm_rpcrouter_class = class_create(THIS_MODULE, "oncrpc"); - if (IS_ERR(msm_rpcrouter_class)) { - rc = -ENOMEM; - printk(KERN_ERR - "rpcrouter: failed to create oncrpc class\n"); - goto fail; - } - - rc = alloc_chrdev_region(&msm_rpcrouter_devno, 0, - RPCROUTER_MAX_REMOTE_SERVERS + 1, - "oncrpc"); - if (rc < 0) { - printk(KERN_ERR - "rpcrouter: Failed to alloc chardev region (%d)\n", rc); - goto fail_destroy_class; - } - - major = MAJOR(msm_rpcrouter_devno); - rpcrouter_device = device_create(msm_rpcrouter_class, NULL, - msm_rpcrouter_devno, NULL, "%.8x:%d", - 0, 0); - if (IS_ERR(rpcrouter_device)) { - rc = -ENOMEM; - goto fail_unregister_cdev_region; - } - - cdev_init(&rpcrouter_cdev, &rpcrouter_router_fops); - rpcrouter_cdev.owner = THIS_MODULE; - - rc = cdev_add(&rpcrouter_cdev, msm_rpcrouter_devno, 1); - if (rc < 0) - goto fail_destroy_device; - - return 0; - -fail_destroy_device: - device_destroy(msm_rpcrouter_class, msm_rpcrouter_devno); -fail_unregister_cdev_region: - unregister_chrdev_region(msm_rpcrouter_devno, - RPCROUTER_MAX_REMOTE_SERVERS + 1); -fail_destroy_class: - class_destroy(msm_rpcrouter_class); -fail: - return rc; -} - -void msm_rpcrouter_exit_devices(void) -{ - cdev_del(&rpcrouter_cdev); - device_destroy(msm_rpcrouter_class, msm_rpcrouter_devno); - unregister_chrdev_region(msm_rpcrouter_devno, - RPCROUTER_MAX_REMOTE_SERVERS + 1); - class_destroy(msm_rpcrouter_class); -} - diff --git a/drivers/staging/dream/smd/smd_rpcrouter_servers.c b/drivers/staging/dream/smd/smd_rpcrouter_servers.c deleted file mode 100644 index bec3ee9371b3..000000000000 --- a/drivers/staging/dream/smd/smd_rpcrouter_servers.c +++ /dev/null @@ -1,226 +0,0 @@ -/* arch/arm/mach-msm/rpc_servers.c - * - * Copyright (C) 2007 Google, Inc. - * Author: Iliyan Malchev - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include "smd_rpcrouter.h" - -static struct msm_rpc_endpoint *endpoint; - -#define FLAG_REGISTERED 0x0001 - -static LIST_HEAD(rpc_server_list); -static DEFINE_MUTEX(rpc_server_list_lock); -static int rpc_servers_active; - -static void rpc_server_register(struct msm_rpc_server *server) -{ - int rc; - rc = msm_rpc_register_server(endpoint, server->prog, server->vers); - if (rc < 0) - printk(KERN_ERR "[rpcserver] error registering %p @ %08x:%d\n", - server, server->prog, server->vers); -} - -static struct msm_rpc_server *rpc_server_find(uint32_t prog, uint32_t vers) -{ - struct msm_rpc_server *server; - - mutex_lock(&rpc_server_list_lock); - list_for_each_entry(server, &rpc_server_list, list) { - if ((server->prog == prog) && -#if CONFIG_MSM_AMSS_VERSION >= 6350 - msm_rpc_is_compatible_version(server->vers, vers)) { -#else - server->vers == vers) { -#endif - mutex_unlock(&rpc_server_list_lock); - return server; - } - } - mutex_unlock(&rpc_server_list_lock); - return NULL; -} - -static void rpc_server_register_all(void) -{ - struct msm_rpc_server *server; - - mutex_lock(&rpc_server_list_lock); - list_for_each_entry(server, &rpc_server_list, list) { - if (!(server->flags & FLAG_REGISTERED)) { - rpc_server_register(server); - server->flags |= FLAG_REGISTERED; - } - } - mutex_unlock(&rpc_server_list_lock); -} - -int msm_rpc_create_server(struct msm_rpc_server *server) -{ - /* make sure we're in a sane state first */ - server->flags = 0; - INIT_LIST_HEAD(&server->list); - - mutex_lock(&rpc_server_list_lock); - list_add(&server->list, &rpc_server_list); - if (rpc_servers_active) { - rpc_server_register(server); - server->flags |= FLAG_REGISTERED; - } - mutex_unlock(&rpc_server_list_lock); - - return 0; -} - -static int rpc_send_accepted_void_reply(struct msm_rpc_endpoint *client, - uint32_t xid, uint32_t accept_status) -{ - int rc = 0; - uint8_t reply_buf[sizeof(struct rpc_reply_hdr)]; - struct rpc_reply_hdr *reply = (struct rpc_reply_hdr *)reply_buf; - - reply->xid = cpu_to_be32(xid); - reply->type = cpu_to_be32(1); /* reply */ - reply->reply_stat = cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED); - - reply->data.acc_hdr.accept_stat = cpu_to_be32(accept_status); - reply->data.acc_hdr.verf_flavor = 0; - reply->data.acc_hdr.verf_length = 0; - - rc = msm_rpc_write(client, reply_buf, sizeof(reply_buf)); - if (rc < 0) - printk(KERN_ERR - "%s: could not write response: %d\n", - __FUNCTION__, rc); - - return rc; -} - -static int rpc_servers_thread(void *data) -{ - void *buffer; - struct rpc_request_hdr *req; - struct msm_rpc_server *server; - int rc; - - for (;;) { - rc = wait_event_interruptible(endpoint->wait_q, - !list_empty(&endpoint->read_q)); - rc = msm_rpc_read(endpoint, &buffer, -1, -1); - if (rc < 0) { - printk(KERN_ERR "%s: could not read: %d\n", - __FUNCTION__, rc); - break; - } - req = (struct rpc_request_hdr *)buffer; - - req->type = be32_to_cpu(req->type); - req->xid = be32_to_cpu(req->xid); - req->rpc_vers = be32_to_cpu(req->rpc_vers); - req->prog = be32_to_cpu(req->prog); - req->vers = be32_to_cpu(req->vers); - req->procedure = be32_to_cpu(req->procedure); - - server = rpc_server_find(req->prog, req->vers); - - if (req->rpc_vers != 2) - continue; - if (req->type != 0) - continue; - if (!server) { - rpc_send_accepted_void_reply( - endpoint, req->xid, - RPC_ACCEPTSTAT_PROG_UNAVAIL); - continue; - } - - rc = server->rpc_call(server, req, rc); - - switch (rc) { - case 0: - rpc_send_accepted_void_reply( - endpoint, req->xid, - RPC_ACCEPTSTAT_SUCCESS); - break; - default: - rpc_send_accepted_void_reply( - endpoint, req->xid, - RPC_ACCEPTSTAT_PROG_UNAVAIL); - break; - } - - kfree(buffer); - } - - do_exit(0); -} - -static int rpcservers_probe(struct platform_device *pdev) -{ - struct task_struct *server_thread; - - endpoint = msm_rpc_open(); - if (IS_ERR(endpoint)) - return PTR_ERR(endpoint); - - /* we're online -- register any servers installed beforehand */ - rpc_servers_active = 1; - rpc_server_register_all(); - - /* start the kernel thread */ - server_thread = kthread_run(rpc_servers_thread, NULL, "krpcserversd"); - if (IS_ERR(server_thread)) - return PTR_ERR(server_thread); - - return 0; -} - -static struct platform_driver rpcservers_driver = { - .probe = rpcservers_probe, - .driver = { - .name = "oncrpc_router", - .owner = THIS_MODULE, - }, -}; - -static int __init rpc_servers_init(void) -{ - return platform_driver_register(&rpcservers_driver); -} - -module_init(rpc_servers_init); - -MODULE_DESCRIPTION("MSM RPC Servers"); -MODULE_AUTHOR("Iliyan Malchev "); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/dream/smd/smd_tty.c b/drivers/staging/dream/smd/smd_tty.c deleted file mode 100644 index f40944958d44..000000000000 --- a/drivers/staging/dream/smd/smd_tty.c +++ /dev/null @@ -1,208 +0,0 @@ -/* arch/arm/mach-msm/smd_tty.c - * - * Copyright (C) 2007 Google, Inc. - * Author: Brian Swetland - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#define MAX_SMD_TTYS 32 - -static DEFINE_MUTEX(smd_tty_lock); - -struct smd_tty_info { - smd_channel_t *ch; - struct tty_struct *tty; - int open_count; -}; - -static struct smd_tty_info smd_tty[MAX_SMD_TTYS]; - - -static void smd_tty_notify(void *priv, unsigned event) -{ - unsigned char *ptr; - int avail; - struct smd_tty_info *info = priv; - struct tty_struct *tty = info->tty; - - if (!tty) - return; - - if (event != SMD_EVENT_DATA) - return; - - for (;;) { - if (test_bit(TTY_THROTTLED, &tty->flags)) break; - avail = smd_read_avail(info->ch); - if (avail == 0) break; - - avail = tty_prepare_flip_string(tty, &ptr, avail); - - if (smd_read(info->ch, ptr, avail) != avail) { - /* shouldn't be possible since we're in interrupt - ** context here and nobody else could 'steal' our - ** characters. - */ - printk(KERN_ERR "OOPS - smd_tty_buffer mismatch?!"); - } - - tty_flip_buffer_push(tty); - } - - /* XXX only when writable and necessary */ - tty_wakeup(tty); -} - -static int smd_tty_open(struct tty_struct *tty, struct file *f) -{ - int res = 0; - int n = tty->index; - struct smd_tty_info *info; - const char *name; - - if (n == 0) { - name = "SMD_DS"; - } else if (n == 27) { - name = "SMD_GPSNMEA"; - } else { - return -ENODEV; - } - - info = smd_tty + n; - - mutex_lock(&smd_tty_lock); - tty->driver_data = info; - - if (info->open_count++ == 0) { - info->tty = tty; - if (info->ch) { - smd_kick(info->ch); - } else { - res = smd_open(name, &info->ch, info, smd_tty_notify); - } - } - mutex_unlock(&smd_tty_lock); - - return res; -} - -static void smd_tty_close(struct tty_struct *tty, struct file *f) -{ - struct smd_tty_info *info = tty->driver_data; - - if (info == 0) - return; - - mutex_lock(&smd_tty_lock); - if (--info->open_count == 0) { - info->tty = 0; - tty->driver_data = 0; - if (info->ch) { - smd_close(info->ch); - info->ch = 0; - } - } - mutex_unlock(&smd_tty_lock); -} - -static int smd_tty_write(struct tty_struct *tty, const unsigned char *buf, int len) -{ - struct smd_tty_info *info = tty->driver_data; - int avail; - - /* if we're writing to a packet channel we will - ** never be able to write more data than there - ** is currently space for - */ - avail = smd_write_avail(info->ch); - if (len > avail) - len = avail; - - return smd_write(info->ch, buf, len); -} - -static int smd_tty_write_room(struct tty_struct *tty) -{ - struct smd_tty_info *info = tty->driver_data; - return smd_write_avail(info->ch); -} - -static int smd_tty_chars_in_buffer(struct tty_struct *tty) -{ - struct smd_tty_info *info = tty->driver_data; - return smd_read_avail(info->ch); -} - -static void smd_tty_unthrottle(struct tty_struct *tty) -{ - struct smd_tty_info *info = tty->driver_data; - smd_kick(info->ch); -} - -static struct tty_operations smd_tty_ops = { - .open = smd_tty_open, - .close = smd_tty_close, - .write = smd_tty_write, - .write_room = smd_tty_write_room, - .chars_in_buffer = smd_tty_chars_in_buffer, - .unthrottle = smd_tty_unthrottle, -}; - -static struct tty_driver *smd_tty_driver; - -static int __init smd_tty_init(void) -{ - int ret; - - smd_tty_driver = alloc_tty_driver(MAX_SMD_TTYS); - if (smd_tty_driver == 0) - return -ENOMEM; - - smd_tty_driver->owner = THIS_MODULE; - smd_tty_driver->driver_name = "smd_tty_driver"; - smd_tty_driver->name = "smd"; - smd_tty_driver->major = 0; - smd_tty_driver->minor_start = 0; - smd_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - smd_tty_driver->subtype = SERIAL_TYPE_NORMAL; - smd_tty_driver->init_termios = tty_std_termios; - smd_tty_driver->init_termios.c_iflag = 0; - smd_tty_driver->init_termios.c_oflag = 0; - smd_tty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; - smd_tty_driver->init_termios.c_lflag = 0; - smd_tty_driver->flags = TTY_DRIVER_RESET_TERMIOS | - TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; - tty_set_operations(smd_tty_driver, &smd_tty_ops); - - ret = tty_register_driver(smd_tty_driver); - if (ret) return ret; - - /* this should be dynamic */ - tty_register_device(smd_tty_driver, 0, 0); - tty_register_device(smd_tty_driver, 27, 0); - - return 0; -} - -module_init(smd_tty_init); -- cgit v1.2.3 From 442f9cb5858ec86f6f05df0058cec0bf4b873534 Mon Sep 17 00:00:00 2001 From: Andres More Date: Wed, 12 May 2010 18:59:44 -0300 Subject: staging: vt6656: code cleanup, replaced U8 macro with u8 Removed custom macro for unsigned 8-bit integers. Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iocmd.h | 64 +++++++++++++++++++++--------------------- drivers/staging/vt6656/ttype.h | 8 ------ 2 files changed, 32 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/iocmd.h b/drivers/staging/vt6656/iocmd.h index 67ec7d758051..7fcf085bb4cd 100644 --- a/drivers/staging/vt6656/iocmd.h +++ b/drivers/staging/vt6656/iocmd.h @@ -109,7 +109,7 @@ typedef enum tagWZONETYPE { // #pragma pack(1) typedef struct tagSCmdRequest { - U8 name[16]; + u8 name[16]; void *data; U16 wResult; U16 wCmdCode; @@ -121,7 +121,7 @@ typedef struct tagSCmdRequest { typedef struct tagSCmdScan { - U8 ssid[SSID_MAXLEN + 2]; + u8 ssid[SSID_MAXLEN + 2]; } SCmdScan, *PSCmdScan; @@ -134,7 +134,7 @@ typedef struct tagSCmdBSSJoin { U16 wBSSType; U16 wBBPType; - U8 ssid[SSID_MAXLEN + 2]; + u8 ssid[SSID_MAXLEN + 2]; U32 uChannel; BOOL bPSEnable; BOOL bShareKeyAuth; @@ -155,9 +155,9 @@ typedef struct tagSCmdZoneTypeSet { #ifdef WPA_SM_Transtatus typedef struct tagSWPAResult { char ifname[100]; - U8 proto; - U8 key_mgmt; - U8 eap_type; + u8 proto; + u8 key_mgmt; + u8 eap_type; BOOL authenticated; } SWPAResult, *PSWPAResult; #endif @@ -166,11 +166,11 @@ typedef struct tagSCmdStartAP { U16 wBSSType; U16 wBBPType; - U8 ssid[SSID_MAXLEN + 2]; + u8 ssid[SSID_MAXLEN + 2]; U32 uChannel; U32 uBeaconInt; BOOL bShareKeyAuth; - U8 byBasicRate; + u8 byBasicRate; } SCmdStartAP, *PSCmdStartAP; @@ -178,8 +178,8 @@ typedef struct tagSCmdStartAP { typedef struct tagSCmdSetWEP { BOOL bEnableWep; - U8 byKeyIndex; - U8 abyWepKey[WEP_NKEYS][WEP_KEYMAXLEN]; + u8 byKeyIndex; + u8 abyWepKey[WEP_NKEYS][WEP_KEYMAXLEN]; BOOL bWepKeyAvailable[WEP_NKEYS]; U32 auWepKeyLength[WEP_NKEYS]; @@ -190,11 +190,11 @@ typedef struct tagSCmdSetWEP { typedef struct tagSBSSIDItem { U32 uChannel; - U8 abyBSSID[BSSID_LEN]; - U8 abySSID[SSID_MAXLEN + 1]; + u8 abyBSSID[BSSID_LEN]; + u8 abySSID[SSID_MAXLEN + 1]; U16 wBeaconInterval; U16 wCapInfo; - U8 byNetType; + u8 byNetType; BOOL bWEPOn; U32 uRSSI; @@ -211,15 +211,15 @@ typedef struct tagSBSSIDList { typedef struct tagSNodeItem { // STA info U16 wAID; - U8 abyMACAddr[6]; + u8 abyMACAddr[6]; U16 wTxDataRate; U16 wInActiveCount; U16 wEnQueueCnt; U16 wFlags; BOOL bPWBitOn; - U8 byKeyIndex; + u8 byKeyIndex; U16 wWepKeyLength; - U8 abyWepKey[WEP_KEYMAXLEN]; + u8 abyWepKey[WEP_KEYMAXLEN]; // Auto rate fallback vars BOOL bIsInFallback; U32 uTxFailures; @@ -241,9 +241,9 @@ typedef struct tagSCmdLinkStatus { BOOL bLink; U16 wBSSType; - U8 byState; - U8 abyBSSID[BSSID_LEN]; - U8 abySSID[SSID_MAXLEN + 2]; + u8 byState; + u8 abyBSSID[BSSID_LEN]; + u8 abySSID[SSID_MAXLEN + 2]; U32 uChannel; U32 uLinkRate; @@ -353,8 +353,8 @@ typedef struct tagSStatMIBCount { U32 dwCntRxFrmLength; U32 dwCntTxBufLength; - U8 abyCntRxPattern[16]; - U8 abyCntTxPattern[16]; + u8 abyCntRxPattern[16]; + u8 abyCntTxPattern[16]; // Software check.... U32 dwCntRxDataErr; // rx buffer data software compare CRC err count @@ -415,24 +415,24 @@ enum { struct viawget_hostapd_param { U32 cmd; - U8 sta_addr[6]; + u8 sta_addr[6]; union { struct { U16 aid; U16 capability; - U8 tx_supp_rates; + u8 tx_supp_rates; } add_sta; struct { U32 inactive_sec; } get_info_sta; struct { - U8 alg; + u8 alg; U32 flags; U32 err; - U8 idx; - U8 seq[8]; + u8 idx; + u8 seq[8]; U16 key_len; - U8 key[0]; + u8 key[0]; } crypt; struct { U32 flags_and; @@ -441,19 +441,19 @@ struct viawget_hostapd_param { struct { U16 rid; U16 len; - U8 data[0]; + u8 data[0]; } rid; struct { - U8 len; - U8 data[0]; + u8 len; + u8 data[0]; } generic_elem; struct { U16 cmd; U16 reason_code; } mlme; struct { - U8 ssid_len; - U8 ssid[32]; + u8 ssid_len; + u8 ssid[32]; } scan_req; } u; }; diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h index 13e8bbb6711c..d7cf663f445f 100644 --- a/drivers/staging/vt6656/ttype.h +++ b/drivers/staging/vt6656/ttype.h @@ -26,11 +26,9 @@ * */ - #ifndef __TTYPE_H__ #define __TTYPE_H__ - /******* Common definitions and typedefs ***********************************/ //2007-0115-05by MikeLiu @@ -40,7 +38,6 @@ //DavidWang - //2007-0814-01by MikeLiu #ifndef Safe_Close #define Safe_Close @@ -82,11 +79,9 @@ typedef int BOOL; typedef signed char I8; /* 8-bit signed integer */ -typedef unsigned char U8; /* 8-bit unsigned integer */ typedef unsigned short U16; /* 16-bit unsigned integer */ typedef unsigned long U32; /* 32-bit unsigned integer */ - typedef char CHAR; typedef signed short SHORT; typedef signed int INT; @@ -98,8 +93,6 @@ typedef unsigned int UINT; typedef unsigned long ULONG; typedef unsigned long long ULONGLONG; //64 bit - - typedef unsigned char BYTE; // 8-bit typedef unsigned short WORD; // 16-bit typedef unsigned long DWORD; // 32-bit @@ -116,7 +109,6 @@ typedef union tagUQuadWord { } UQuadWord; typedef UQuadWord QWORD; // 64-bit - /****** Common pointer types ***********************************************/ typedef unsigned long ULONG_PTR; // 32-bit -- cgit v1.2.3 From 26233e6e27e890d592708a3cd233667820c40254 Mon Sep 17 00:00:00 2001 From: Andres More Date: Wed, 12 May 2010 18:59:45 -0300 Subject: staging: vt6656: code cleanup, replaced U16 macro with u16 Removed custom macro for unsigned 16-bit integers. Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iocmd.h | 46 +++++++++++++++++++++--------------------- drivers/staging/vt6656/ttype.h | 1 - 2 files changed, 23 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/iocmd.h b/drivers/staging/vt6656/iocmd.h index 7fcf085bb4cd..27ba8b7fc0f6 100644 --- a/drivers/staging/vt6656/iocmd.h +++ b/drivers/staging/vt6656/iocmd.h @@ -111,8 +111,8 @@ typedef enum tagWZONETYPE { typedef struct tagSCmdRequest { u8 name[16]; void *data; - U16 wResult; - U16 wCmdCode; + u16 wResult; + u16 wCmdCode; } SCmdRequest, *PSCmdRequest; // @@ -132,8 +132,8 @@ typedef struct tagSCmdScan { typedef struct tagSCmdBSSJoin { - U16 wBSSType; - U16 wBBPType; + u16 wBSSType; + u16 wBBPType; u8 ssid[SSID_MAXLEN + 2]; U32 uChannel; BOOL bPSEnable; @@ -164,8 +164,8 @@ typedef struct tagSWPAResult { typedef struct tagSCmdStartAP { - U16 wBSSType; - U16 wBBPType; + u16 wBSSType; + u16 wBBPType; u8 ssid[SSID_MAXLEN + 2]; U32 uChannel; U32 uBeaconInt; @@ -192,8 +192,8 @@ typedef struct tagSBSSIDItem { U32 uChannel; u8 abyBSSID[BSSID_LEN]; u8 abySSID[SSID_MAXLEN + 1]; - U16 wBeaconInterval; - U16 wCapInfo; + u16 wBeaconInterval; + u16 wCapInfo; u8 byNetType; BOOL bWEPOn; U32 uRSSI; @@ -210,21 +210,21 @@ typedef struct tagSBSSIDList { typedef struct tagSNodeItem { // STA info - U16 wAID; + u16 wAID; u8 abyMACAddr[6]; - U16 wTxDataRate; - U16 wInActiveCount; - U16 wEnQueueCnt; - U16 wFlags; + u16 wTxDataRate; + u16 wInActiveCount; + u16 wEnQueueCnt; + u16 wFlags; BOOL bPWBitOn; u8 byKeyIndex; - U16 wWepKeyLength; + u16 wWepKeyLength; u8 abyWepKey[WEP_KEYMAXLEN]; // Auto rate fallback vars BOOL bIsInFallback; U32 uTxFailures; U32 uTxAttempts; - U16 wFailureRatio; + u16 wFailureRatio; } SNodeItem; @@ -240,7 +240,7 @@ typedef struct tagSNodeList { typedef struct tagSCmdLinkStatus { BOOL bLink; - U16 wBSSType; + u16 wBSSType; u8 byState; u8 abyBSSID[BSSID_LEN]; u8 abySSID[SSID_MAXLEN + 2]; @@ -418,8 +418,8 @@ struct viawget_hostapd_param { u8 sta_addr[6]; union { struct { - U16 aid; - U16 capability; + u16 aid; + u16 capability; u8 tx_supp_rates; } add_sta; struct { @@ -431,7 +431,7 @@ struct viawget_hostapd_param { U32 err; u8 idx; u8 seq[8]; - U16 key_len; + u16 key_len; u8 key[0]; } crypt; struct { @@ -439,8 +439,8 @@ struct viawget_hostapd_param { U32 flags_or; } set_flags_sta; struct { - U16 rid; - U16 len; + u16 rid; + u16 len; u8 data[0]; } rid; struct { @@ -448,8 +448,8 @@ struct viawget_hostapd_param { u8 data[0]; } generic_elem; struct { - U16 cmd; - U16 reason_code; + u16 cmd; + u16 reason_code; } mlme; struct { u8 ssid_len; diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h index d7cf663f445f..2b8419af7907 100644 --- a/drivers/staging/vt6656/ttype.h +++ b/drivers/staging/vt6656/ttype.h @@ -79,7 +79,6 @@ typedef int BOOL; typedef signed char I8; /* 8-bit signed integer */ -typedef unsigned short U16; /* 16-bit unsigned integer */ typedef unsigned long U32; /* 32-bit unsigned integer */ typedef char CHAR; -- cgit v1.2.3 From 659770d4033373340bc24fc125d1f3ba215e4669 Mon Sep 17 00:00:00 2001 From: Andres More Date: Wed, 12 May 2010 18:59:46 -0300 Subject: staging: vt6656: code cleanup, replaced U32 macro with u32 Removed custom macro for unsigned 32-bit integers. Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/device.h | 8 +- drivers/staging/vt6656/iocmd.h | 239 ++++++++++++++++++---------------------- drivers/staging/vt6656/ttype.h | 2 - 3 files changed, 112 insertions(+), 137 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index 6d255ca1d6ff..b507bb8193d6 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -435,7 +435,7 @@ typedef struct __device_opt { int short_retry; int long_retry; int bbp_type; - U32 flags; + u32 flags; } OPTIONS, *POPTIONS; @@ -453,17 +453,17 @@ typedef struct __device_info { struct tasklet_struct ReadWorkItem; struct tasklet_struct RxMngWorkItem; - U32 rx_buf_sz; + u32 rx_buf_sz; int multicast_limit; BYTE byRxMode; spinlock_t lock; - U32 rx_bytes; + u32 rx_bytes; BYTE byRevId; - U32 flags; + u32 flags; ULONG Flags; SCache sDupRxCache; diff --git a/drivers/staging/vt6656/iocmd.h b/drivers/staging/vt6656/iocmd.h index 27ba8b7fc0f6..fbba1d53e49d 100644 --- a/drivers/staging/vt6656/iocmd.h +++ b/drivers/staging/vt6656/iocmd.h @@ -37,12 +37,6 @@ #define DEF #endif -//typedef int BOOL; -//typedef uint32_t u32; -//typedef uint16_t u16; -//typedef uint8_t u8; - - // ioctl Command code #define MAGIC_CODE 0x3142 #define IOCTL_CMD_TEST (SIOCDEVPRIVATE + 0) @@ -50,7 +44,6 @@ #define IOCTL_CMD_HOSTAPD (SIOCDEVPRIVATE + 2) #define IOCTL_CMD_WPA (SIOCDEVPRIVATE + 3) - typedef enum tagWMAC_CMD { WLAN_CMD_BSS_SCAN, @@ -90,7 +83,6 @@ typedef enum tagWZONETYPE { #define ADHOC_STARTED 1 #define ADHOC_JOINTED 2 - #define PHY80211a 0 #define PHY80211b 1 #define PHY80211g 2 @@ -125,7 +117,6 @@ typedef struct tagSCmdScan { } SCmdScan, *PSCmdScan; - // // BSS Join // @@ -135,7 +126,7 @@ typedef struct tagSCmdBSSJoin { u16 wBSSType; u16 wBBPType; u8 ssid[SSID_MAXLEN + 2]; - U32 uChannel; + u32 uChannel; BOOL bPSEnable; BOOL bShareKeyAuth; @@ -167,43 +158,40 @@ typedef struct tagSCmdStartAP { u16 wBSSType; u16 wBBPType; u8 ssid[SSID_MAXLEN + 2]; - U32 uChannel; - U32 uBeaconInt; + u32 uChannel; + u32 uBeaconInt; BOOL bShareKeyAuth; u8 byBasicRate; } SCmdStartAP, *PSCmdStartAP; - typedef struct tagSCmdSetWEP { BOOL bEnableWep; u8 byKeyIndex; u8 abyWepKey[WEP_NKEYS][WEP_KEYMAXLEN]; BOOL bWepKeyAvailable[WEP_NKEYS]; - U32 auWepKeyLength[WEP_NKEYS]; + u32 auWepKeyLength[WEP_NKEYS]; } SCmdSetWEP, *PSCmdSetWEP; - - typedef struct tagSBSSIDItem { - U32 uChannel; + u32 uChannel; u8 abyBSSID[BSSID_LEN]; u8 abySSID[SSID_MAXLEN + 1]; u16 wBeaconInterval; u16 wCapInfo; u8 byNetType; BOOL bWEPOn; - U32 uRSSI; + u32 uRSSI; } SBSSIDItem; typedef struct tagSBSSIDList { - U32 uItem; + u32 uItem; SBSSIDItem sBSSIDList[0]; } SBSSIDList, *PSBSSIDList; @@ -222,8 +210,8 @@ typedef struct tagSNodeItem { u8 abyWepKey[WEP_KEYMAXLEN]; // Auto rate fallback vars BOOL bIsInFallback; - U32 uTxFailures; - U32 uTxAttempts; + u32 uTxFailures; + u32 uTxAttempts; u16 wFailureRatio; } SNodeItem; @@ -231,7 +219,7 @@ typedef struct tagSNodeItem { typedef struct tagSNodeList { - U32 uItem; + u32 uItem; SNodeItem sNodeList[0]; } SNodeList, *PSNodeList; @@ -244,8 +232,8 @@ typedef struct tagSCmdLinkStatus { u8 byState; u8 abyBSSID[BSSID_LEN]; u8 abySSID[SSID_MAXLEN + 2]; - U32 uChannel; - U32 uLinkRate; + u32 uChannel; + u32 uLinkRate; } SCmdLinkStatus, *PSCmdLinkStatus; @@ -253,18 +241,18 @@ typedef struct tagSCmdLinkStatus { // 802.11 counter // typedef struct tagSDot11MIBCount { - U32 TransmittedFragmentCount; - U32 MulticastTransmittedFrameCount; - U32 FailedCount; - U32 RetryCount; - U32 MultipleRetryCount; - U32 RTSSuccessCount; - U32 RTSFailureCount; - U32 ACKFailureCount; - U32 FrameDuplicateCount; - U32 ReceivedFragmentCount; - U32 MulticastReceivedFrameCount; - U32 FCSErrorCount; + u32 TransmittedFragmentCount; + u32 MulticastTransmittedFrameCount; + u32 FailedCount; + u32 RetryCount; + u32 MultipleRetryCount; + u32 RTSSuccessCount; + u32 RTSFailureCount; + u32 ACKFailureCount; + u32 FrameDuplicateCount; + u32 ReceivedFragmentCount; + u32 MulticastReceivedFrameCount; + u32 FCSErrorCount; } SDot11MIBCount, *PSDot11MIBCount; @@ -276,119 +264,115 @@ typedef struct tagSStatMIBCount { // // ISR status count // - U32 dwIsrTx0OK; - U32 dwIsrTx1OK; - U32 dwIsrBeaconTxOK; - U32 dwIsrRxOK; - U32 dwIsrTBTTInt; - U32 dwIsrSTIMERInt; - U32 dwIsrUnrecoverableError; - U32 dwIsrSoftInterrupt; - U32 dwIsrRxNoBuf; + u32 dwIsrTx0OK; + u32 dwIsrTx1OK; + u32 dwIsrBeaconTxOK; + u32 dwIsrRxOK; + u32 dwIsrTBTTInt; + u32 dwIsrSTIMERInt; + u32 dwIsrUnrecoverableError; + u32 dwIsrSoftInterrupt; + u32 dwIsrRxNoBuf; ///////////////////////////////////// - U32 dwIsrUnknown; // unknown interrupt count + u32 dwIsrUnknown; /* unknown interrupt count */ // RSR status count // - U32 dwRsrFrmAlgnErr; - U32 dwRsrErr; - U32 dwRsrCRCErr; - U32 dwRsrCRCOk; - U32 dwRsrBSSIDOk; - U32 dwRsrADDROk; - U32 dwRsrICVOk; - U32 dwNewRsrShortPreamble; - U32 dwRsrLong; - U32 dwRsrRunt; - - U32 dwRsrRxControl; - U32 dwRsrRxData; - U32 dwRsrRxManage; - - U32 dwRsrRxPacket; - U32 dwRsrRxOctet; - U32 dwRsrBroadcast; - U32 dwRsrMulticast; - U32 dwRsrDirected; + u32 dwRsrFrmAlgnErr; + u32 dwRsrErr; + u32 dwRsrCRCErr; + u32 dwRsrCRCOk; + u32 dwRsrBSSIDOk; + u32 dwRsrADDROk; + u32 dwRsrICVOk; + u32 dwNewRsrShortPreamble; + u32 dwRsrLong; + u32 dwRsrRunt; + + u32 dwRsrRxControl; + u32 dwRsrRxData; + u32 dwRsrRxManage; + + u32 dwRsrRxPacket; + u32 dwRsrRxOctet; + u32 dwRsrBroadcast; + u32 dwRsrMulticast; + u32 dwRsrDirected; // 64-bit OID - U32 ullRsrOK; + u32 ullRsrOK; // for some optional OIDs (64 bits) and DMI support - U32 ullRxBroadcastBytes; - U32 ullRxMulticastBytes; - U32 ullRxDirectedBytes; - U32 ullRxBroadcastFrames; - U32 ullRxMulticastFrames; - U32 ullRxDirectedFrames; - - U32 dwRsrRxFragment; - U32 dwRsrRxFrmLen64; - U32 dwRsrRxFrmLen65_127; - U32 dwRsrRxFrmLen128_255; - U32 dwRsrRxFrmLen256_511; - U32 dwRsrRxFrmLen512_1023; - U32 dwRsrRxFrmLen1024_1518; + u32 ullRxBroadcastBytes; + u32 ullRxMulticastBytes; + u32 ullRxDirectedBytes; + u32 ullRxBroadcastFrames; + u32 ullRxMulticastFrames; + u32 ullRxDirectedFrames; + + u32 dwRsrRxFragment; + u32 dwRsrRxFrmLen64; + u32 dwRsrRxFrmLen65_127; + u32 dwRsrRxFrmLen128_255; + u32 dwRsrRxFrmLen256_511; + u32 dwRsrRxFrmLen512_1023; + u32 dwRsrRxFrmLen1024_1518; // TSR0,1 status count // - U32 dwTsrTotalRetry[2]; // total collision retry count - U32 dwTsrOnceRetry[2]; // this packet only occur one collision - U32 dwTsrMoreThanOnceRetry[2]; // this packet occur more than one collision - U32 dwTsrRetry[2]; // this packet has ever occur collision, - // that is (dwTsrOnceCollision0 + dwTsrMoreThanOnceCollision0) - U32 dwTsrACKData[2]; - U32 dwTsrErr[2]; - U32 dwAllTsrOK[2]; - U32 dwTsrRetryTimeout[2]; - U32 dwTsrTransmitTimeout[2]; - - U32 dwTsrTxPacket[2]; - U32 dwTsrTxOctet[2]; - U32 dwTsrBroadcast[2]; - U32 dwTsrMulticast[2]; - U32 dwTsrDirected[2]; + u32 dwTsrTotalRetry[2]; /* total collision retry count */ + u32 dwTsrOnceRetry[2]; /* this packet had one collision */ + u32 dwTsrMoreThanOnceRetry[2]; /* this packet had many collisions */ + u32 dwTsrRetry[2]; /* this packet has ever occur collision, + * that is (dwTsrOnceCollision0 plus + * dwTsrMoreThanOnceCollision0) */ + u32 dwTsrACKData[2]; + u32 dwTsrErr[2]; + u32 dwAllTsrOK[2]; + u32 dwTsrRetryTimeout[2]; + u32 dwTsrTransmitTimeout[2]; + + u32 dwTsrTxPacket[2]; + u32 dwTsrTxOctet[2]; + u32 dwTsrBroadcast[2]; + u32 dwTsrMulticast[2]; + u32 dwTsrDirected[2]; // RD/TD count - U32 dwCntRxFrmLength; - U32 dwCntTxBufLength; + u32 dwCntRxFrmLength; + u32 dwCntTxBufLength; u8 abyCntRxPattern[16]; u8 abyCntTxPattern[16]; - // Software check.... - U32 dwCntRxDataErr; // rx buffer data software compare CRC err count - U32 dwCntDecryptErr; // rx buffer data software compare CRC err count - U32 dwCntRxICVErr; // rx buffer data software compare CRC err count - U32 idxRxErrorDesc; // index for rx data error RD + /* Software check.... */ + u32 dwCntRxDataErr; /* rx buffer data CRC err count */ + u32 dwCntDecryptErr; /* rx buffer data CRC err count */ + u32 dwCntRxICVErr; /* rx buffer data CRC err count */ + u32 idxRxErrorDesc; /* index for rx data error RD */ - // 64-bit OID - U32 ullTsrOK[2]; + /* 64-bit OID */ + u32 ullTsrOK[2]; // for some optional OIDs (64 bits) and DMI support - U32 ullTxBroadcastFrames[2]; - U32 ullTxMulticastFrames[2]; - U32 ullTxDirectedFrames[2]; - U32 ullTxBroadcastBytes[2]; - U32 ullTxMulticastBytes[2]; - U32 ullTxDirectedBytes[2]; + u32 ullTxBroadcastFrames[2]; + u32 ullTxMulticastFrames[2]; + u32 ullTxDirectedFrames[2]; + u32 ullTxBroadcastBytes[2]; + u32 ullTxMulticastBytes[2]; + u32 ullTxDirectedBytes[2]; } SStatMIBCount, *PSStatMIBCount; - - - typedef struct tagSCmdValue { - U32 dwValue; + u32 dwValue; } SCmdValue, *PSCmdValue; - // // hostapd & viawget ioctl related // - // VIAGWET_IOCTL_HOSTAPD ioctl() cmd: enum { VIAWGET_HOSTAPD_FLUSH = 1, @@ -405,16 +389,13 @@ enum { VIAWGET_HOSTAPD_STA_CLEAR_STATS = 12, }; - #define VIAWGET_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \ ((int) (&((struct viawget_hostapd_param *) 0)->u.generic_elem.data)) // Maximum length for algorithm names (-1 for nul termination) used in ioctl() - - struct viawget_hostapd_param { - U32 cmd; + u32 cmd; u8 sta_addr[6]; union { struct { @@ -423,20 +404,20 @@ struct viawget_hostapd_param { u8 tx_supp_rates; } add_sta; struct { - U32 inactive_sec; + u32 inactive_sec; } get_info_sta; struct { u8 alg; - U32 flags; - U32 err; + u32 flags; + u32 err; u8 idx; u8 seq[8]; u16 key_len; u8 key[0]; } crypt; struct { - U32 flags_and; - U32 flags_or; + u32 flags_and; + u32 flags_or; } set_flags_sta; struct { u16 rid; @@ -458,16 +439,12 @@ struct viawget_hostapd_param { } u; }; - - /*--------------------- Export Classes ----------------------------*/ /*--------------------- Export Variables --------------------------*/ - /*--------------------- Export Types ------------------------------*/ - /*--------------------- Export Functions --------------------------*/ #endif /* __IOCMD_H__ */ diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h index 2b8419af7907..a85d4f88e09b 100644 --- a/drivers/staging/vt6656/ttype.h +++ b/drivers/staging/vt6656/ttype.h @@ -79,8 +79,6 @@ typedef int BOOL; typedef signed char I8; /* 8-bit signed integer */ -typedef unsigned long U32; /* 32-bit unsigned integer */ - typedef char CHAR; typedef signed short SHORT; typedef signed int INT; -- cgit v1.2.3 From 71e510673134999627fd180181079ffccb9ec756 Mon Sep 17 00:00:00 2001 From: Andres More Date: Wed, 12 May 2010 18:59:47 -0300 Subject: staging: vt6656: code cleanup, removed unused I8 macro Removed custom macro for signed 8-bit integers, which was not used. Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/ttype.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h index a85d4f88e09b..4dfe00acf24a 100644 --- a/drivers/staging/vt6656/ttype.h +++ b/drivers/staging/vt6656/ttype.h @@ -72,13 +72,6 @@ typedef int BOOL; /****** Simple typedefs ***************************************************/ -/* These lines assume that your compiler's longs are 32 bits and - * shorts are 16 bits. It is already assumed that chars are 8 bits, - * but it doesn't matter if they're signed or unsigned. - */ - -typedef signed char I8; /* 8-bit signed integer */ - typedef char CHAR; typedef signed short SHORT; typedef signed int INT; -- cgit v1.2.3 From 3a215e0ff4184314f7f1a099354a272ddedff289 Mon Sep 17 00:00:00 2001 From: Charles Clément Date: Wed, 12 May 2010 20:54:39 -0700 Subject: Staging: vt6655: remove IN definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove empty IN definition used to specify input parameters. Signed-off-by: Charles Clément Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/80211mgr.c | 44 ++-- drivers/staging/vt6655/80211mgr.h | 44 ++-- drivers/staging/vt6655/IEEE11h.c | 6 +- drivers/staging/vt6655/IEEE11h.h | 2 +- drivers/staging/vt6655/baseband.c | 24 +- drivers/staging/vt6655/baseband.h | 20 +- drivers/staging/vt6655/bssdb.c | 138 +++++----- drivers/staging/vt6655/bssdb.h | 126 ++++----- drivers/staging/vt6655/card.c | 90 +++---- drivers/staging/vt6655/card.h | 78 +++--- drivers/staging/vt6655/datarate.c | 26 +- drivers/staging/vt6655/datarate.h | 22 +- drivers/staging/vt6655/device_main.c | 2 +- drivers/staging/vt6655/dpc.c | 108 ++++---- drivers/staging/vt6655/dpc.h | 4 +- drivers/staging/vt6655/ioctl.c | 8 +- drivers/staging/vt6655/ioctl.h | 8 +- drivers/staging/vt6655/key.c | 14 +- drivers/staging/vt6655/key.h | 14 +- drivers/staging/vt6655/power.c | 20 +- drivers/staging/vt6655/power.h | 22 +- drivers/staging/vt6655/rf.c | 20 +- drivers/staging/vt6655/rf.h | 12 +- drivers/staging/vt6655/rxtx.c | 342 ++++++++++++------------ drivers/staging/vt6655/rxtx.h | 64 ++--- drivers/staging/vt6655/ttype.h | 4 - drivers/staging/vt6655/vntwifi.c | 102 ++++---- drivers/staging/vt6655/vntwifi.h | 104 ++++---- drivers/staging/vt6655/wcmd.c | 46 ++-- drivers/staging/vt6655/wcmd.h | 18 +- drivers/staging/vt6655/wmgr.c | 488 +++++++++++++++++------------------ drivers/staging/vt6655/wmgr.h | 58 ++--- drivers/staging/vt6655/wpa.c | 10 +- drivers/staging/vt6655/wpa.h | 10 +- drivers/staging/vt6655/wpa2.c | 8 +- drivers/staging/vt6655/wpa2.h | 8 +- 36 files changed, 1055 insertions(+), 1059 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/80211mgr.c b/drivers/staging/vt6655/80211mgr.c index da964a92f96b..38697c862489 100644 --- a/drivers/staging/vt6655/80211mgr.c +++ b/drivers/staging/vt6655/80211mgr.c @@ -91,7 +91,7 @@ static int msglevel =MSG_LEVEL_INFO; void vMgrEncodeBeacon( - IN PWLAN_FR_BEACON pFrame + PWLAN_FR_BEACON pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -123,7 +123,7 @@ vMgrEncodeBeacon( void vMgrDecodeBeacon( - IN PWLAN_FR_BEACON pFrame + PWLAN_FR_BEACON pFrame ) { PWLAN_IE pItem; @@ -244,7 +244,7 @@ vMgrDecodeBeacon( void vMgrEncodeIBSSATIM( - IN PWLAN_FR_IBSSATIM pFrame + PWLAN_FR_IBSSATIM pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -267,7 +267,7 @@ vMgrEncodeIBSSATIM( void vMgrDecodeIBSSATIM( - IN PWLAN_FR_IBSSATIM pFrame + PWLAN_FR_IBSSATIM pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -289,7 +289,7 @@ vMgrDecodeIBSSATIM( void vMgrEncodeDisassociation( - IN PWLAN_FR_DISASSOC pFrame + PWLAN_FR_DISASSOC pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -317,7 +317,7 @@ vMgrEncodeDisassociation( void vMgrDecodeDisassociation( - IN PWLAN_FR_DISASSOC pFrame + PWLAN_FR_DISASSOC pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -343,7 +343,7 @@ vMgrDecodeDisassociation( void vMgrEncodeAssocRequest( - IN PWLAN_FR_ASSOCREQ pFrame + PWLAN_FR_ASSOCREQ pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -370,7 +370,7 @@ vMgrEncodeAssocRequest( void vMgrDecodeAssocRequest( - IN PWLAN_FR_ASSOCREQ pFrame + PWLAN_FR_ASSOCREQ pFrame ) { PWLAN_IE pItem; @@ -436,7 +436,7 @@ vMgrDecodeAssocRequest( void vMgrEncodeAssocResponse( - IN PWLAN_FR_ASSOCRESP pFrame + PWLAN_FR_ASSOCRESP pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -468,7 +468,7 @@ vMgrEncodeAssocResponse( void vMgrDecodeAssocResponse( - IN PWLAN_FR_ASSOCRESP pFrame + PWLAN_FR_ASSOCRESP pFrame ) { PWLAN_IE pItem; @@ -514,7 +514,7 @@ vMgrDecodeAssocResponse( void vMgrEncodeReassocRequest( - IN PWLAN_FR_REASSOCREQ pFrame + PWLAN_FR_REASSOCREQ pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -546,7 +546,7 @@ vMgrEncodeReassocRequest( void vMgrDecodeReassocRequest( - IN PWLAN_FR_REASSOCREQ pFrame + PWLAN_FR_REASSOCREQ pFrame ) { PWLAN_IE pItem; @@ -618,7 +618,7 @@ vMgrDecodeReassocRequest( void vMgrEncodeProbeRequest( - IN PWLAN_FR_PROBEREQ pFrame + PWLAN_FR_PROBEREQ pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -639,7 +639,7 @@ vMgrEncodeProbeRequest( void vMgrDecodeProbeRequest( - IN PWLAN_FR_PROBEREQ pFrame + PWLAN_FR_PROBEREQ pFrame ) { PWLAN_IE pItem; @@ -692,7 +692,7 @@ vMgrDecodeProbeRequest( void vMgrEncodeProbeResponse( - IN PWLAN_FR_PROBERESP pFrame + PWLAN_FR_PROBERESP pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -726,7 +726,7 @@ vMgrEncodeProbeResponse( void vMgrDecodeProbeResponse( - IN PWLAN_FR_PROBERESP pFrame + PWLAN_FR_PROBERESP pFrame ) { PWLAN_IE pItem; @@ -840,7 +840,7 @@ vMgrDecodeProbeResponse( void vMgrEncodeAuthen( - IN PWLAN_FR_AUTHEN pFrame + PWLAN_FR_AUTHEN pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -871,7 +871,7 @@ vMgrEncodeAuthen( void vMgrDecodeAuthen( - IN PWLAN_FR_AUTHEN pFrame + PWLAN_FR_AUTHEN pFrame ) { PWLAN_IE pItem; @@ -911,7 +911,7 @@ vMgrDecodeAuthen( void vMgrEncodeDeauthen( - IN PWLAN_FR_DEAUTHEN pFrame + PWLAN_FR_DEAUTHEN pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -938,7 +938,7 @@ vMgrEncodeDeauthen( void vMgrDecodeDeauthen( - IN PWLAN_FR_DEAUTHEN pFrame + PWLAN_FR_DEAUTHEN pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -964,7 +964,7 @@ vMgrDecodeDeauthen( void vMgrEncodeReassocResponse( - IN PWLAN_FR_REASSOCRESP pFrame + PWLAN_FR_REASSOCRESP pFrame ) { pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; @@ -997,7 +997,7 @@ vMgrEncodeReassocResponse( void vMgrDecodeReassocResponse( - IN PWLAN_FR_REASSOCRESP pFrame + PWLAN_FR_REASSOCRESP pFrame ) { PWLAN_IE pItem; diff --git a/drivers/staging/vt6655/80211mgr.h b/drivers/staging/vt6655/80211mgr.h index c3eafd28da45..658fe144f898 100644 --- a/drivers/staging/vt6655/80211mgr.h +++ b/drivers/staging/vt6655/80211mgr.h @@ -716,112 +716,112 @@ typedef struct tagWLAN_FR_DEAUTHEN { void vMgrEncodeBeacon( - IN PWLAN_FR_BEACON pFrame + PWLAN_FR_BEACON pFrame ); void vMgrDecodeBeacon( - IN PWLAN_FR_BEACON pFrame + PWLAN_FR_BEACON pFrame ); void vMgrEncodeIBSSATIM( - IN PWLAN_FR_IBSSATIM pFrame + PWLAN_FR_IBSSATIM pFrame ); void vMgrDecodeIBSSATIM( - IN PWLAN_FR_IBSSATIM pFrame + PWLAN_FR_IBSSATIM pFrame ); void vMgrEncodeDisassociation( - IN PWLAN_FR_DISASSOC pFrame + PWLAN_FR_DISASSOC pFrame ); void vMgrDecodeDisassociation( - IN PWLAN_FR_DISASSOC pFrame + PWLAN_FR_DISASSOC pFrame ); void vMgrEncodeAssocRequest( - IN PWLAN_FR_ASSOCREQ pFrame + PWLAN_FR_ASSOCREQ pFrame ); void vMgrDecodeAssocRequest( - IN PWLAN_FR_ASSOCREQ pFrame + PWLAN_FR_ASSOCREQ pFrame ); void vMgrEncodeAssocResponse( - IN PWLAN_FR_ASSOCRESP pFrame + PWLAN_FR_ASSOCRESP pFrame ); void vMgrDecodeAssocResponse( - IN PWLAN_FR_ASSOCRESP pFrame + PWLAN_FR_ASSOCRESP pFrame ); void vMgrEncodeReassocRequest( - IN PWLAN_FR_REASSOCREQ pFrame + PWLAN_FR_REASSOCREQ pFrame ); void vMgrDecodeReassocRequest( - IN PWLAN_FR_REASSOCREQ pFrame + PWLAN_FR_REASSOCREQ pFrame ); void vMgrEncodeProbeRequest( - IN PWLAN_FR_PROBEREQ pFrame + PWLAN_FR_PROBEREQ pFrame ); void vMgrDecodeProbeRequest( - IN PWLAN_FR_PROBEREQ pFrame + PWLAN_FR_PROBEREQ pFrame ); void vMgrEncodeProbeResponse( - IN PWLAN_FR_PROBERESP pFrame + PWLAN_FR_PROBERESP pFrame ); void vMgrDecodeProbeResponse( - IN PWLAN_FR_PROBERESP pFrame + PWLAN_FR_PROBERESP pFrame ); void vMgrEncodeAuthen( - IN PWLAN_FR_AUTHEN pFrame + PWLAN_FR_AUTHEN pFrame ); void vMgrDecodeAuthen( - IN PWLAN_FR_AUTHEN pFrame + PWLAN_FR_AUTHEN pFrame ); void vMgrEncodeDeauthen( - IN PWLAN_FR_DEAUTHEN pFrame + PWLAN_FR_DEAUTHEN pFrame ); void vMgrDecodeDeauthen( - IN PWLAN_FR_DEAUTHEN pFrame + PWLAN_FR_DEAUTHEN pFrame ); void vMgrEncodeReassocResponse( - IN PWLAN_FR_REASSOCRESP pFrame + PWLAN_FR_REASSOCRESP pFrame ); void vMgrDecodeReassocResponse( - IN PWLAN_FR_REASSOCRESP pFrame + PWLAN_FR_REASSOCRESP pFrame ); #endif// __80211MGR_H__ diff --git a/drivers/staging/vt6655/IEEE11h.c b/drivers/staging/vt6655/IEEE11h.c index 77813002d2fc..22f12f5ef90c 100644 --- a/drivers/staging/vt6655/IEEE11h.c +++ b/drivers/staging/vt6655/IEEE11h.c @@ -203,8 +203,8 @@ static BOOL s_bRxTPCReq(PSMgmtObject pMgmt, PWLAN_FRAME_TPCREQ pTPCReq, BYTE byR -*/ BOOL IEEE11hbMgrRxAction ( - IN void *pMgmtHandle, - IN void *pRxPacket + void *pMgmtHandle, + void *pRxPacket ) { PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; @@ -265,7 +265,7 @@ IEEE11hbMgrRxAction ( BOOL IEEE11hbMSRRepTx ( - IN void *pMgmtHandle + void *pMgmtHandle ) { PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; diff --git a/drivers/staging/vt6655/IEEE11h.h b/drivers/staging/vt6655/IEEE11h.h index 1707388e7cfc..ae32498a511d 100644 --- a/drivers/staging/vt6655/IEEE11h.h +++ b/drivers/staging/vt6655/IEEE11h.h @@ -46,7 +46,7 @@ /*--------------------- Export Functions --------------------------*/ BOOL IEEE11hbMSRRepTx ( - IN void *pMgmtHandle + void *pMgmtHandle ); #endif // __IEEE11h_H__ diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index 7a69490fc7e5..2931a0ffcf32 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -1725,13 +1725,13 @@ s_ulGetRatio(PSDevice pDevice); static void s_vChangeAntenna( - IN PSDevice pDevice + PSDevice pDevice ); static void s_vChangeAntenna ( - IN PSDevice pDevice + PSDevice pDevice ) { @@ -1778,10 +1778,10 @@ s_vChangeAntenna ( */ UINT BBuGetFrameTime ( - IN BYTE byPreambleType, - IN BYTE byPktType, - IN UINT cbFrameLength, - IN WORD wRate + BYTE byPreambleType, + BYTE byPktType, + UINT cbFrameLength, + WORD wRate ) { UINT uFrameTime; @@ -1845,10 +1845,10 @@ BBuGetFrameTime ( */ void BBvCaculateParameter ( - IN PSDevice pDevice, - IN UINT cbFrameLength, - IN WORD wRate, - IN BYTE byPacketType, + PSDevice pDevice, + UINT cbFrameLength, + WORD wRate, + BYTE byPacketType, OUT PWORD pwPhyLen, OUT PBYTE pbyPhySrv, OUT PBYTE pbyPhySgn @@ -2878,7 +2878,7 @@ BBvAntennaDiversity (PSDevice pDevice, BYTE byRxRate, BYTE bySQ3) void TimerSQ3CallBack ( - IN void *hDeviceContext + void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -2926,7 +2926,7 @@ TimerSQ3CallBack ( void TimerState1CallBack ( - IN void *hDeviceContext + void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index 23f7ad151d16..3eea7aa2fba2 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -120,18 +120,18 @@ UINT BBuGetFrameTime( - IN BYTE byPreambleType, - IN BYTE byPktType, - IN UINT cbFrameLength, - IN WORD wRate + BYTE byPreambleType, + BYTE byPktType, + UINT cbFrameLength, + WORD wRate ); void BBvCaculateParameter ( - IN PSDevice pDevice, - IN UINT cbFrameLength, - IN WORD wRate, - IN BYTE byPacketType, + PSDevice pDevice, + UINT cbFrameLength, + WORD wRate, + BYTE byPacketType, OUT PWORD pwPhyLen, OUT PBYTE pbyPhySrv, OUT PBYTE pbyPhySgn @@ -162,12 +162,12 @@ void BBvExitDeepSleep(DWORD_PTR dwIoBase, BYTE byLocalID); void TimerSQ3CallBack ( - IN void *hDeviceContext + void *hDeviceContext ); void TimerState1CallBack( - IN void *hDeviceContext + void *hDeviceContext ); void BBvAntennaDiversity(PSDevice pDevice, BYTE byRxRate, BYTE bySQ3); diff --git a/drivers/staging/vt6655/bssdb.c b/drivers/staging/vt6655/bssdb.c index 3af0ccb25d06..e64238e5e8c4 100644 --- a/drivers/staging/vt6655/bssdb.c +++ b/drivers/staging/vt6655/bssdb.c @@ -91,18 +91,18 @@ const WORD awHWRetry1[5][5] = { /*--------------------- Static Functions --------------------------*/ void s_vCheckSensitivity( - IN void *hDeviceContext + void *hDeviceContext ); #ifdef Calcu_LinkQual void s_uCalculateLinkQual( - IN void *hDeviceContext + void *hDeviceContext ); #endif void s_vCheckPreEDThreshold( - IN void *hDeviceContext + void *hDeviceContext ); /*--------------------- Export Variables --------------------------*/ @@ -125,10 +125,10 @@ void s_vCheckPreEDThreshold( PKnownBSS BSSpSearchBSSList( - IN void *hDeviceContext, - IN PBYTE pbyDesireBSSID, - IN PBYTE pbyDesireSSID, - IN CARD_PHY_TYPE ePhyType + void *hDeviceContext, + PBYTE pbyDesireBSSID, + PBYTE pbyDesireSSID, + CARD_PHY_TYPE ePhyType ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -282,8 +282,8 @@ if(pDevice->bLinkPass==FALSE) pCurrBSS->bSelected = FALSE; void BSSvClearBSSList( - IN void *hDeviceContext, - IN BOOL bKeepCurrBSSID + void *hDeviceContext, + BOOL bKeepCurrBSSID ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -325,9 +325,9 @@ BSSvClearBSSList( -*/ PKnownBSS BSSpAddrIsInBSSList( - IN void *hDeviceContext, - IN PBYTE abyBSSID, - IN PWLAN_IE_SSID pSSID + void *hDeviceContext, + PBYTE abyBSSID, + PWLAN_IE_SSID pSSID ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -368,23 +368,23 @@ BSSpAddrIsInBSSList( BOOL BSSbInsertToBSSList ( - IN void *hDeviceContext, - IN PBYTE abyBSSIDAddr, - IN QWORD qwTimestamp, - IN WORD wBeaconInterval, - IN WORD wCapInfo, - IN BYTE byCurrChannel, - IN PWLAN_IE_SSID pSSID, - IN PWLAN_IE_SUPP_RATES pSuppRates, - IN PWLAN_IE_SUPP_RATES pExtSuppRates, - IN PERPObject psERP, - IN PWLAN_IE_RSN pRSN, - IN PWLAN_IE_RSN_EXT pRSNWPA, - IN PWLAN_IE_COUNTRY pIE_Country, - IN PWLAN_IE_QUIET pIE_Quiet, - IN UINT uIELength, - IN PBYTE pbyIEs, - IN void *pRxPacketContext + void *hDeviceContext, + PBYTE abyBSSIDAddr, + QWORD qwTimestamp, + WORD wBeaconInterval, + WORD wCapInfo, + BYTE byCurrChannel, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pSuppRates, + PWLAN_IE_SUPP_RATES pExtSuppRates, + PERPObject psERP, + PWLAN_IE_RSN pRSN, + PWLAN_IE_RSN_EXT pRSNWPA, + PWLAN_IE_COUNTRY pIE_Country, + PWLAN_IE_QUIET pIE_Quiet, + UINT uIELength, + PBYTE pbyIEs, + void *pRxPacketContext ) { @@ -585,24 +585,24 @@ BSSbInsertToBSSList ( BOOL BSSbUpdateToBSSList ( - IN void *hDeviceContext, - IN QWORD qwTimestamp, - IN WORD wBeaconInterval, - IN WORD wCapInfo, - IN BYTE byCurrChannel, - IN BOOL bChannelHit, - IN PWLAN_IE_SSID pSSID, - IN PWLAN_IE_SUPP_RATES pSuppRates, - IN PWLAN_IE_SUPP_RATES pExtSuppRates, - IN PERPObject psERP, - IN PWLAN_IE_RSN pRSN, - IN PWLAN_IE_RSN_EXT pRSNWPA, - IN PWLAN_IE_COUNTRY pIE_Country, - IN PWLAN_IE_QUIET pIE_Quiet, - IN PKnownBSS pBSSList, - IN UINT uIELength, - IN PBYTE pbyIEs, - IN void *pRxPacketContext + void *hDeviceContext, + QWORD qwTimestamp, + WORD wBeaconInterval, + WORD wCapInfo, + BYTE byCurrChannel, + BOOL bChannelHit, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pSuppRates, + PWLAN_IE_SUPP_RATES pExtSuppRates, + PERPObject psERP, + PWLAN_IE_RSN pRSN, + PWLAN_IE_RSN_EXT pRSNWPA, + PWLAN_IE_COUNTRY pIE_Country, + PWLAN_IE_QUIET pIE_Quiet, + PKnownBSS pBSSList, + UINT uIELength, + PBYTE pbyIEs, + void *pRxPacketContext ) { int ii; @@ -764,8 +764,8 @@ BSSbUpdateToBSSList ( BOOL BSSDBbIsSTAInNodeDB( - IN void *pMgmtObject, - IN PBYTE abyDstAddr, + void *pMgmtObject, + PBYTE abyDstAddr, OUT PUINT puNodeIndex ) { @@ -799,7 +799,7 @@ BSSDBbIsSTAInNodeDB( -*/ void BSSvCreateOneNode( - IN void *hDeviceContext, + void *hDeviceContext, OUT PUINT puNodeIndex ) { @@ -864,8 +864,8 @@ BSSvCreateOneNode( -*/ void BSSvRemoveOneNode( - IN void *hDeviceContext, - IN UINT uNodeIndex + void *hDeviceContext, + UINT uNodeIndex ) { @@ -897,10 +897,10 @@ BSSvRemoveOneNode( void BSSvUpdateAPNode( - IN void *hDeviceContext, - IN PWORD pwCapInfo, - IN PWLAN_IE_SUPP_RATES pSuppRates, - IN PWLAN_IE_SUPP_RATES pExtSuppRates + void *hDeviceContext, + PWORD pwCapInfo, + PWLAN_IE_SUPP_RATES pSuppRates, + PWLAN_IE_SUPP_RATES pExtSuppRates ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -960,7 +960,7 @@ BSSvUpdateAPNode( void BSSvAddMulticastNode( - IN void *hDeviceContext + void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1013,7 +1013,7 @@ UINT status; #endif void BSSvSecondCallBack( - IN void *hDeviceContext + void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1390,11 +1390,11 @@ start: void BSSvUpdateNodeTxCounter( - IN void *hDeviceContext, - IN BYTE byTsr0, - IN BYTE byTsr1, - IN PBYTE pbyBuffer, - IN UINT uFIFOHeaderSize + void *hDeviceContext, + BYTE byTsr0, + BYTE byTsr1, + PBYTE pbyBuffer, + UINT uFIFOHeaderSize ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1583,8 +1583,8 @@ BSSvUpdateNodeTxCounter( void BSSvClearNodeDBTable( - IN void *hDeviceContext, - IN UINT uStartIndex + void *hDeviceContext, + UINT uStartIndex ) { @@ -1611,7 +1611,7 @@ BSSvClearNodeDBTable( void s_vCheckSensitivity( - IN void *hDeviceContext + void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1661,7 +1661,7 @@ void s_vCheckSensitivity( void BSSvClearAnyBSSJoinRecord ( - IN void *hDeviceContext + void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1676,7 +1676,7 @@ BSSvClearAnyBSSJoinRecord ( #ifdef Calcu_LinkQual void s_uCalculateLinkQual( - IN void *hDeviceContext + void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1724,7 +1724,7 @@ else #endif void s_vCheckPreEDThreshold( - IN void *hDeviceContext + void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; diff --git a/drivers/staging/vt6655/bssdb.h b/drivers/staging/vt6655/bssdb.h index a66e14f0a825..ec1e32bf35b5 100644 --- a/drivers/staging/vt6655/bssdb.h +++ b/drivers/staging/vt6655/bssdb.h @@ -244,128 +244,128 @@ typedef struct tagKnownNodeDB { PKnownBSS BSSpSearchBSSList( - IN void *hDeviceContext, - IN PBYTE pbyDesireBSSID, - IN PBYTE pbyDesireSSID, - IN CARD_PHY_TYPE ePhyType + void *hDeviceContext, + PBYTE pbyDesireBSSID, + PBYTE pbyDesireSSID, + CARD_PHY_TYPE ePhyType ); PKnownBSS BSSpAddrIsInBSSList( - IN void *hDeviceContext, - IN PBYTE abyBSSID, - IN PWLAN_IE_SSID pSSID + void *hDeviceContext, + PBYTE abyBSSID, + PWLAN_IE_SSID pSSID ); void BSSvClearBSSList( - IN void *hDeviceContext, - IN BOOL bKeepCurrBSSID + void *hDeviceContext, + BOOL bKeepCurrBSSID ); BOOL BSSbInsertToBSSList( - IN void *hDeviceContext, - IN PBYTE abyBSSIDAddr, - IN QWORD qwTimestamp, - IN WORD wBeaconInterval, - IN WORD wCapInfo, - IN BYTE byCurrChannel, - IN PWLAN_IE_SSID pSSID, - IN PWLAN_IE_SUPP_RATES pSuppRates, - IN PWLAN_IE_SUPP_RATES pExtSuppRates, - IN PERPObject psERP, - IN PWLAN_IE_RSN pRSN, - IN PWLAN_IE_RSN_EXT pRSNWPA, - IN PWLAN_IE_COUNTRY pIE_Country, - IN PWLAN_IE_QUIET pIE_Quiet, - IN UINT uIELength, - IN PBYTE pbyIEs, - IN void *pRxPacketContext + void *hDeviceContext, + PBYTE abyBSSIDAddr, + QWORD qwTimestamp, + WORD wBeaconInterval, + WORD wCapInfo, + BYTE byCurrChannel, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pSuppRates, + PWLAN_IE_SUPP_RATES pExtSuppRates, + PERPObject psERP, + PWLAN_IE_RSN pRSN, + PWLAN_IE_RSN_EXT pRSNWPA, + PWLAN_IE_COUNTRY pIE_Country, + PWLAN_IE_QUIET pIE_Quiet, + UINT uIELength, + PBYTE pbyIEs, + void *pRxPacketContext ); BOOL BSSbUpdateToBSSList( - IN void *hDeviceContext, - IN QWORD qwTimestamp, - IN WORD wBeaconInterval, - IN WORD wCapInfo, - IN BYTE byCurrChannel, - IN BOOL bChannelHit, - IN PWLAN_IE_SSID pSSID, - IN PWLAN_IE_SUPP_RATES pSuppRates, - IN PWLAN_IE_SUPP_RATES pExtSuppRates, - IN PERPObject psERP, - IN PWLAN_IE_RSN pRSN, - IN PWLAN_IE_RSN_EXT pRSNWPA, - IN PWLAN_IE_COUNTRY pIE_Country, - IN PWLAN_IE_QUIET pIE_Quiet, - IN PKnownBSS pBSSList, - IN UINT uIELength, - IN PBYTE pbyIEs, - IN void *pRxPacketContext + void *hDeviceContext, + QWORD qwTimestamp, + WORD wBeaconInterval, + WORD wCapInfo, + BYTE byCurrChannel, + BOOL bChannelHit, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pSuppRates, + PWLAN_IE_SUPP_RATES pExtSuppRates, + PERPObject psERP, + PWLAN_IE_RSN pRSN, + PWLAN_IE_RSN_EXT pRSNWPA, + PWLAN_IE_COUNTRY pIE_Country, + PWLAN_IE_QUIET pIE_Quiet, + PKnownBSS pBSSList, + UINT uIELength, + PBYTE pbyIEs, + void *pRxPacketContext ); BOOL BSSDBbIsSTAInNodeDB( - IN void *hDeviceContext, - IN PBYTE abyDstAddr, + void *hDeviceContext, + PBYTE abyDstAddr, OUT PUINT puNodeIndex ); void BSSvCreateOneNode( - IN void *hDeviceContext, + void *hDeviceContext, OUT PUINT puNodeIndex ); void BSSvUpdateAPNode( - IN void *hDeviceContext, - IN PWORD pwCapInfo, - IN PWLAN_IE_SUPP_RATES pItemRates, - IN PWLAN_IE_SUPP_RATES pExtSuppRates + void *hDeviceContext, + PWORD pwCapInfo, + PWLAN_IE_SUPP_RATES pItemRates, + PWLAN_IE_SUPP_RATES pExtSuppRates ); void BSSvSecondCallBack( - IN void *hDeviceContext + void *hDeviceContext ); void BSSvUpdateNodeTxCounter( - IN void *hDeviceContext, - IN BYTE byTsr0, - IN BYTE byTsr1, - IN PBYTE pbyBuffer, - IN UINT uFIFOHeaderSize + void *hDeviceContext, + BYTE byTsr0, + BYTE byTsr1, + PBYTE pbyBuffer, + UINT uFIFOHeaderSize ); void BSSvRemoveOneNode( - IN void *hDeviceContext, - IN UINT uNodeIndex + void *hDeviceContext, + UINT uNodeIndex ); void BSSvAddMulticastNode( - IN void *hDeviceContext + void *hDeviceContext ); void BSSvClearNodeDBTable( - IN void *hDeviceContext, - IN UINT uStartIndex + void *hDeviceContext, + UINT uStartIndex ); void BSSvClearAnyBSSJoinRecord( - IN void *hDeviceContext + void *hDeviceContext ); #endif //__BSSDB_H__ diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index e767044ba0d0..bc61ca912cb6 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -425,8 +425,8 @@ SCountryTable ChannelRuleTab[CCODE_MAX+1] = static void s_vCaculateOFDMRParameter( - IN BYTE byRate, - IN CARD_PHY_TYPE ePHYType, + BYTE byRate, + CARD_PHY_TYPE ePHYType, OUT PBYTE pbyTxRate, OUT PBYTE pbyRsvTime ); @@ -498,8 +498,8 @@ exit: static void s_vCaculateOFDMRParameter ( - IN BYTE byRate, - IN CARD_PHY_TYPE ePHYType, + BYTE byRate, + CARD_PHY_TYPE ePHYType, OUT PBYTE pbyTxRate, OUT PBYTE pbyRsvTime ) @@ -1550,10 +1550,10 @@ BOOL CARDbRemoveKey (void *pDeviceHandler, PBYTE pbyBSSID) -*/ BOOL CARDbAdd_PMKID_Candidate ( - IN void *pDeviceHandler, - IN PBYTE pbyBSSID, - IN BOOL bRSNCapExist, - IN WORD wRSNCap + void *pDeviceHandler, + PBYTE pbyBSSID, + BOOL bRSNCapExist, + WORD wRSNCap ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -1601,7 +1601,7 @@ CARDbAdd_PMKID_Candidate ( void * CARDpGetCurrentAddress ( - IN void *pDeviceHandler + void *pDeviceHandler ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -1708,9 +1708,9 @@ void CARDvInitChannelTable (void *pDeviceHandler) -*/ BOOL CARDbStartMeasure ( - IN void *pDeviceHandler, - IN void *pvMeasureEIDs, - IN UINT uNumOfMeasureEIDs + void *pDeviceHandler, + void *pvMeasureEIDs, + UINT uNumOfMeasureEIDs ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -1835,10 +1835,10 @@ CARDbStartMeasure ( -*/ BOOL CARDbChannelSwitch ( - IN void *pDeviceHandler, - IN BYTE byMode, - IN BYTE byNewChannel, - IN BYTE byCount + void *pDeviceHandler, + BYTE byMode, + BYTE byNewChannel, + BYTE byCount ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -1878,12 +1878,12 @@ CARDbChannelSwitch ( -*/ BOOL CARDbSetQuiet ( - IN void *pDeviceHandler, - IN BOOL bResetQuiet, - IN BYTE byQuietCount, - IN BYTE byQuietPeriod, - IN WORD wQuietDuration, - IN WORD wQuietOffset + void *pDeviceHandler, + BOOL bResetQuiet, + BYTE byQuietCount, + BYTE byQuietPeriod, + WORD wQuietDuration, + WORD wQuietOffset ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -1934,7 +1934,7 @@ CARDbSetQuiet ( -*/ BOOL CARDbStartQuiet ( - IN void *pDeviceHandler + void *pDeviceHandler ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -2035,9 +2035,9 @@ CARDbStartQuiet ( -*/ void CARDvSetCountryInfo ( - IN void *pDeviceHandler, - IN CARD_PHY_TYPE ePHYType, - IN void *pIE + void *pDeviceHandler, + CARD_PHY_TYPE ePHYType, + void *pIE ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -2094,9 +2094,9 @@ CARDvSetCountryInfo ( -*/ void CARDvSetPowerConstraint ( - IN void *pDeviceHandler, - IN BYTE byChannel, - IN I8 byPower + void *pDeviceHandler, + BYTE byChannel, + I8 byPower ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -2129,7 +2129,7 @@ CARDvSetPowerConstraint ( -*/ void CARDvGetPowerCapability ( - IN void *pDeviceHandler, + void *pDeviceHandler, OUT PBYTE pbyMinPower, OUT PBYTE pbyMaxPower ) @@ -2165,8 +2165,8 @@ CARDvGetPowerCapability ( -*/ BYTE CARDbySetSupportChannels ( - IN void *pDeviceHandler, - IN OUT PBYTE pbyIEs + void *pDeviceHandler, + OUT PBYTE pbyIEs ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -2256,7 +2256,7 @@ CARDbySetSupportChannels ( -*/ I8 CARDbyGetTransmitPower ( - IN void *pDeviceHandler + void *pDeviceHandler ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -2267,7 +2267,7 @@ CARDbyGetTransmitPower ( BOOL CARDbChannelGetList ( - IN UINT uCountryCodeIdx, + UINT uCountryCodeIdx, OUT PBYTE pbyChannelTable ) { @@ -2281,8 +2281,8 @@ CARDbChannelGetList ( void CARDvSetCountryIE( - IN void *pDeviceHandler, - IN void *pIE + void *pDeviceHandler, + void *pIE ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -2307,8 +2307,8 @@ CARDvSetCountryIE( BOOL CARDbGetChannelMapInfo( - IN void *pDeviceHandler, - IN UINT uChannelIndex, + void *pDeviceHandler, + UINT uChannelIndex, OUT PBYTE pbyChannelNumber, OUT PBYTE pbyMap ) @@ -2326,9 +2326,9 @@ CARDbGetChannelMapInfo( void CARDvSetChannelMapInfo( - IN void *pDeviceHandler, - IN UINT uChannelIndex, - IN BYTE byMap + void *pDeviceHandler, + UINT uChannelIndex, + BYTE byMap ) { // PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -2342,7 +2342,7 @@ CARDvSetChannelMapInfo( void CARDvClearChannelMapInfo( - IN void *pDeviceHandler + void *pDeviceHandler ) { // PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -2356,7 +2356,7 @@ CARDvClearChannelMapInfo( BYTE CARDbyAutoChannelSelect( - IN void *pDeviceHandler, + void *pDeviceHandler, CARD_PHY_TYPE ePHYType ) { @@ -2422,7 +2422,7 @@ CARDbyAutoChannelSelect( //xxx void CARDvSafeResetTx ( - IN void *pDeviceHandler + void *pDeviceHandler ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -2478,7 +2478,7 @@ CARDvSafeResetTx ( -*/ void CARDvSafeResetRx ( - IN void *pDeviceHandler + void *pDeviceHandler ) { PSDevice pDevice = (PSDevice) pDeviceHandler; diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h index 2114e99b5845..f52a8e0d48cc 100644 --- a/drivers/staging/vt6655/card.h +++ b/drivers/staging/vt6655/card.h @@ -133,15 +133,15 @@ BOOL CARDbRemoveKey (void *pDeviceHandler, PBYTE pbyBSSID); BOOL CARDbAdd_PMKID_Candidate ( - IN void *pDeviceHandler, - IN PBYTE pbyBSSID, - IN BOOL bRSNCapExist, - IN WORD wRSNCap + void *pDeviceHandler, + PBYTE pbyBSSID, + BOOL bRSNCapExist, + WORD wRSNCap ); void * CARDpGetCurrentAddress ( - IN void *pDeviceHandler + void *pDeviceHandler ); @@ -150,101 +150,101 @@ BYTE CARDbyGetChannelMapping(void *pDeviceHandler, BYTE byChannelNumber, CARD_PH BOOL CARDbStartMeasure ( - IN void *pDeviceHandler, - IN void *pvMeasureEIDs, - IN UINT uNumOfMeasureEIDs + void *pDeviceHandler, + void *pvMeasureEIDs, + UINT uNumOfMeasureEIDs ); BOOL CARDbChannelSwitch ( - IN void *pDeviceHandler, - IN BYTE byMode, - IN BYTE byNewChannel, - IN BYTE byCount + void *pDeviceHandler, + BYTE byMode, + BYTE byNewChannel, + BYTE byCount ); BOOL CARDbSetQuiet ( - IN void *pDeviceHandler, - IN BOOL bResetQuiet, - IN BYTE byQuietCount, - IN BYTE byQuietPeriod, - IN WORD wQuietDuration, - IN WORD wQuietOffset + void *pDeviceHandler, + BOOL bResetQuiet, + BYTE byQuietCount, + BYTE byQuietPeriod, + WORD wQuietDuration, + WORD wQuietOffset ); BOOL CARDbStartQuiet ( - IN void *pDeviceHandler + void *pDeviceHandler ); void CARDvSetCountryInfo ( - IN void *pDeviceHandler, - IN CARD_PHY_TYPE ePHYType, - IN void *pIE + void *pDeviceHandler, + CARD_PHY_TYPE ePHYType, + void *pIE ); void CARDvSetPowerConstraint ( - IN void *pDeviceHandler, - IN BYTE byChannel, - IN I8 byPower + void *pDeviceHandler, + BYTE byChannel, + I8 byPower ); void CARDvGetPowerCapability ( - IN void *pDeviceHandler, + void *pDeviceHandler, OUT PBYTE pbyMinPower, OUT PBYTE pbyMaxPower ); BYTE CARDbySetSupportChannels ( - IN void *pDeviceHandler, - IN OUT PBYTE pbyIEs + void *pDeviceHandler, + OUT PBYTE pbyIEs ); I8 CARDbyGetTransmitPower ( - IN void *pDeviceHandler + void *pDeviceHandler ); BOOL CARDbChannelGetList ( - IN UINT uCountryCodeIdx, + UINT uCountryCodeIdx, OUT PBYTE pbyChannelTable ); void CARDvSetCountryIE( - IN void *pDeviceHandler, - IN void *pIE + void *pDeviceHandler, + void *pIE ); BOOL CARDbGetChannelMapInfo( - IN void *pDeviceHandler, - IN UINT uChannelIndex, + void *pDeviceHandler, + UINT uChannelIndex, OUT PBYTE pbyChannelNumber, OUT PBYTE pbyMap ); void CARDvSetChannelMapInfo( - IN void *pDeviceHandler, - IN UINT uChannelIndex, - IN BYTE byMap + void *pDeviceHandler, + UINT uChannelIndex, + BYTE byMap ); void CARDvClearChannelMapInfo( - IN void *pDeviceHandler + void *pDeviceHandler ); BYTE CARDbyAutoChannelSelect( - IN void *pDeviceHandler, + void *pDeviceHandler, CARD_PHY_TYPE ePHYType ); diff --git a/drivers/staging/vt6655/datarate.c b/drivers/staging/vt6655/datarate.c index e0d1a94f732a..42b008a428d8 100644 --- a/drivers/staging/vt6655/datarate.c +++ b/drivers/staging/vt6655/datarate.c @@ -65,14 +65,14 @@ const BYTE acbyIERate[MAX_RATE] = /*--------------------- Static Functions --------------------------*/ void s_vResetCounter ( - IN PKnownNodeDB psNodeDBTable + PKnownNodeDB psNodeDBTable ); void s_vResetCounter ( - IN PKnownNodeDB psNodeDBTable + PKnownNodeDB psNodeDBTable ) { BYTE ii; @@ -106,7 +106,7 @@ s_vResetCounter ( -*/ BYTE DATARATEbyGetRateIdx ( - IN BYTE byRate + BYTE byRate ) { BYTE ii; @@ -160,7 +160,7 @@ DATARATEbyGetRateIdx ( -*/ WORD wGetRateIdx( - IN BYTE byRate + BYTE byRate ) { WORD ii; @@ -196,10 +196,10 @@ wGetRateIdx( -*/ void RATEvParseMaxRate ( - IN void *pDeviceHandler, - IN PWLAN_IE_SUPP_RATES pItemRates, - IN PWLAN_IE_SUPP_RATES pItemExtRates, - IN BOOL bUpdateBasicRate, + void *pDeviceHandler, + PWLAN_IE_SUPP_RATES pItemRates, + PWLAN_IE_SUPP_RATES pItemExtRates, + BOOL bUpdateBasicRate, OUT PWORD pwMaxBasicRate, OUT PWORD pwMaxSuppRate, OUT PWORD pwSuppRate, @@ -309,8 +309,8 @@ UINT uRateLen; void RATEvTxRateFallBack ( - IN void *pDeviceHandler, - IN PKnownNodeDB psNodeDBTable + void *pDeviceHandler, + PKnownNodeDB psNodeDBTable ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -411,9 +411,9 @@ TxRate_iwconfig=psNodeDBTable->wTxDataRate; -*/ BYTE RATEuSetIE ( - IN PWLAN_IE_SUPP_RATES pSrcRates, - IN PWLAN_IE_SUPP_RATES pDstRates, - IN UINT uRateLen + PWLAN_IE_SUPP_RATES pSrcRates, + PWLAN_IE_SUPP_RATES pDstRates, + UINT uRateLen ) { UINT ii, uu, uRateCnt = 0; diff --git a/drivers/staging/vt6655/datarate.h b/drivers/staging/vt6655/datarate.h index bba4a16d004e..abf7a3884fcd 100644 --- a/drivers/staging/vt6655/datarate.h +++ b/drivers/staging/vt6655/datarate.h @@ -56,10 +56,10 @@ void RATEvParseMaxRate( - IN void *pDeviceHandler, - IN PWLAN_IE_SUPP_RATES pItemRates, - IN PWLAN_IE_SUPP_RATES pItemExtRates, - IN BOOL bUpdateBasicRate, + void *pDeviceHandler, + PWLAN_IE_SUPP_RATES pItemRates, + PWLAN_IE_SUPP_RATES pItemExtRates, + BOOL bUpdateBasicRate, OUT PWORD pwMaxBasicRate, OUT PWORD pwMaxSuppRate, OUT PWORD pwSuppRate, @@ -69,26 +69,26 @@ RATEvParseMaxRate( void RATEvTxRateFallBack( - IN void *pDeviceHandler, - IN PKnownNodeDB psNodeDBTable + void *pDeviceHandler, + PKnownNodeDB psNodeDBTable ); BYTE RATEuSetIE( - IN PWLAN_IE_SUPP_RATES pSrcRates, - IN PWLAN_IE_SUPP_RATES pDstRates, - IN UINT uRateLen + PWLAN_IE_SUPP_RATES pSrcRates, + PWLAN_IE_SUPP_RATES pDstRates, + UINT uRateLen ); WORD wGetRateIdx( - IN BYTE byRate + BYTE byRate ); BYTE DATARATEbyGetRateIdx( - IN BYTE byRate + BYTE byRate ); diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 454277b96eea..a401f2ad62c8 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -478,7 +478,7 @@ pDevice->bUpdateBBVGA = TRUE; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->bDiversityRegCtlON= %d\n",(INT)pDevice->bDiversityRegCtlON); } -static void s_vCompleteCurrentMeasure (IN PSDevice pDevice, IN BYTE byResult) +static void s_vCompleteCurrentMeasure (PSDevice pDevice, BYTE byResult) { UINT ii; DWORD dwDuration = 0; diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index d90104a1e6b2..693683924663 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -76,13 +76,13 @@ const BYTE acbyRxRate[MAX_RATE] = /*--------------------- Static Functions --------------------------*/ -static BYTE s_byGetRateIdx(IN BYTE byRate); +static BYTE s_byGetRateIdx(BYTE byRate); static void s_vGetDASA( - IN PBYTE pbyRxBufferAddr, + PBYTE pbyRxBufferAddr, OUT PUINT pcbHeaderSize, OUT PSEthernetHeader psEthHeader ); @@ -90,37 +90,37 @@ s_vGetDASA( static void s_vProcessRxMACHeader ( - IN PSDevice pDevice, - IN PBYTE pbyRxBufferAddr, - IN UINT cbPacketSize, - IN BOOL bIsWEP, - IN BOOL bExtIV, + PSDevice pDevice, + PBYTE pbyRxBufferAddr, + UINT cbPacketSize, + BOOL bIsWEP, + BOOL bExtIV, OUT PUINT pcbHeadSize ); static BOOL s_bAPModeRxCtl( - IN PSDevice pDevice, - IN PBYTE pbyFrame, - IN INT iSANodeIndex + PSDevice pDevice, + PBYTE pbyFrame, + INT iSANodeIndex ); static BOOL s_bAPModeRxData ( - IN PSDevice pDevice, - IN struct sk_buff* skb, - IN UINT FrameSize, - IN UINT cbHeaderOffset, - IN INT iSANodeIndex, - IN INT iDANodeIndex + PSDevice pDevice, + struct sk_buff* skb, + UINT FrameSize, + UINT cbHeaderOffset, + INT iSANodeIndex, + INT iDANodeIndex ); static BOOL s_bHandleRxEncryption( - IN PSDevice pDevice, - IN PBYTE pbyFrame, - IN UINT FrameSize, - IN PBYTE pbyRsr, + PSDevice pDevice, + PBYTE pbyFrame, + UINT FrameSize, + PBYTE pbyRsr, OUT PBYTE pbyNewRsr, OUT PSKeyItem *pKeyOut, int * pbExtIV, @@ -130,12 +130,12 @@ static BOOL s_bHandleRxEncryption( static BOOL s_bHostWepRxEncryption( - IN PSDevice pDevice, - IN PBYTE pbyFrame, - IN UINT FrameSize, - IN PBYTE pbyRsr, - IN BOOL bOnFly, - IN PSKeyItem pKey, + PSDevice pDevice, + PBYTE pbyFrame, + UINT FrameSize, + PBYTE pbyRsr, + BOOL bOnFly, + PSKeyItem pKey, OUT PBYTE pbyNewRsr, int * pbExtIV, OUT PWORD pwRxTSC15_0, @@ -165,11 +165,11 @@ static BOOL s_bHostWepRxEncryption( static void s_vProcessRxMACHeader ( - IN PSDevice pDevice, - IN PBYTE pbyRxBufferAddr, - IN UINT cbPacketSize, - IN BOOL bIsWEP, - IN BOOL bExtIV, + PSDevice pDevice, + PBYTE pbyRxBufferAddr, + UINT cbPacketSize, + BOOL bIsWEP, + BOOL bExtIV, OUT PUINT pcbHeadSize ) { @@ -249,7 +249,7 @@ s_vProcessRxMACHeader ( -static BYTE s_byGetRateIdx (IN BYTE byRate) +static BYTE s_byGetRateIdx (BYTE byRate) { BYTE byRateIdx; @@ -264,7 +264,7 @@ static BYTE s_byGetRateIdx (IN BYTE byRate) static void s_vGetDASA ( - IN PBYTE pbyRxBufferAddr, + PBYTE pbyRxBufferAddr, OUT PUINT pcbHeaderSize, OUT PSEthernetHeader psEthHeader ) @@ -335,8 +335,8 @@ void MngWorkItem(void *Context) BOOL device_receive_frame ( - IN PSDevice pDevice, - IN PSRxDesc pCurrRD + PSDevice pDevice, + PSRxDesc pCurrRD ) { @@ -1039,9 +1039,9 @@ device_receive_frame ( static BOOL s_bAPModeRxCtl ( - IN PSDevice pDevice, - IN PBYTE pbyFrame, - IN INT iSANodeIndex + PSDevice pDevice, + PBYTE pbyFrame, + INT iSANodeIndex ) { PS802_11Header p802_11Header; @@ -1163,10 +1163,10 @@ static BOOL s_bAPModeRxCtl ( } static BOOL s_bHandleRxEncryption ( - IN PSDevice pDevice, - IN PBYTE pbyFrame, - IN UINT FrameSize, - IN PBYTE pbyRsr, + PSDevice pDevice, + PBYTE pbyFrame, + UINT FrameSize, + PBYTE pbyRsr, OUT PBYTE pbyNewRsr, OUT PSKeyItem *pKeyOut, int * pbExtIV, @@ -1309,12 +1309,12 @@ static BOOL s_bHandleRxEncryption ( static BOOL s_bHostWepRxEncryption ( - IN PSDevice pDevice, - IN PBYTE pbyFrame, - IN UINT FrameSize, - IN PBYTE pbyRsr, - IN BOOL bOnFly, - IN PSKeyItem pKey, + PSDevice pDevice, + PBYTE pbyFrame, + UINT FrameSize, + PBYTE pbyRsr, + BOOL bOnFly, + PSKeyItem pKey, OUT PBYTE pbyNewRsr, int * pbExtIV, OUT PWORD pwRxTSC15_0, @@ -1440,12 +1440,12 @@ static BOOL s_bHostWepRxEncryption ( static BOOL s_bAPModeRxData ( - IN PSDevice pDevice, - IN struct sk_buff* skb, - IN UINT FrameSize, - IN UINT cbHeaderOffset, - IN INT iSANodeIndex, - IN INT iDANodeIndex + PSDevice pDevice, + struct sk_buff* skb, + UINT FrameSize, + UINT cbHeaderOffset, + INT iSANodeIndex, + INT iDANodeIndex ) { PSMgmtObject pMgmt = pDevice->pMgmt; diff --git a/drivers/staging/vt6655/dpc.h b/drivers/staging/vt6655/dpc.h index 4129c11e011a..e574963fee0c 100644 --- a/drivers/staging/vt6655/dpc.h +++ b/drivers/staging/vt6655/dpc.h @@ -43,8 +43,8 @@ BOOL device_receive_frame ( - IN PSDevice pDevice, - IN PSRxDesc pCurrRD + PSDevice pDevice, + PSRxDesc pCurrRD ); void MngWorkItem(void *Context); diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c index 1bd819946b84..e36cd30f642a 100644 --- a/drivers/staging/vt6655/ioctl.c +++ b/drivers/staging/vt6655/ioctl.c @@ -716,10 +716,10 @@ if(wpa_Result.authenticated==TRUE) { /* void vConfigWEPKey ( - IN PSDevice pDevice, - IN DWORD dwKeyIndex, - IN PBYTE pbyKey, - IN ULONG uKeyLength + PSDevice pDevice, + DWORD dwKeyIndex, + PBYTE pbyKey, + ULONG uKeyLength ) { int ii; diff --git a/drivers/staging/vt6655/ioctl.h b/drivers/staging/vt6655/ioctl.h index dc278aeb7eac..0d10c2a923c6 100644 --- a/drivers/staging/vt6655/ioctl.h +++ b/drivers/staging/vt6655/ioctl.h @@ -44,10 +44,10 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq); /* void vConfigWEPKey ( - IN PSDevice pDevice, - IN DWORD dwKeyIndex, - IN PBYTE pbyKey, - IN ULONG uKeyLength + PSDevice pDevice, + DWORD dwKeyIndex, + PBYTE pbyKey, + ULONG uKeyLength ); */ diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c index b40c400a23c3..c702d5096056 100644 --- a/drivers/staging/vt6655/key.c +++ b/drivers/staging/vt6655/key.c @@ -132,9 +132,9 @@ void KeyvInitTable (PSKeyManagement pTable, DWORD_PTR dwIoBase) * */ BOOL KeybGetKey ( - IN PSKeyManagement pTable, - IN PBYTE pbyBSSID, - IN DWORD dwKeyIndex, + PSKeyManagement pTable, + PBYTE pbyBSSID, + DWORD dwKeyIndex, OUT PSKeyItem *pKey ) { @@ -518,9 +518,9 @@ void KeyvRemoveAllWEPKey ( * */ BOOL KeybGetTransmitKey ( - IN PSKeyManagement pTable, - IN PBYTE pbyBSSID, - IN DWORD dwKeyType, + PSKeyManagement pTable, + PBYTE pbyBSSID, + DWORD dwKeyType, OUT PSKeyItem *pKey ) { @@ -598,7 +598,7 @@ BOOL KeybGetTransmitKey ( * */ BOOL KeybCheckPairewiseKey ( - IN PSKeyManagement pTable, + PSKeyManagement pTable, OUT PSKeyItem *pKey ) { diff --git a/drivers/staging/vt6655/key.h b/drivers/staging/vt6655/key.h index 4cbd82f76e4e..88be5b4f3925 100644 --- a/drivers/staging/vt6655/key.h +++ b/drivers/staging/vt6655/key.h @@ -104,9 +104,9 @@ typedef struct tagSKeyManagement void KeyvInitTable(PSKeyManagement pTable, DWORD_PTR dwIoBase); BOOL KeybGetKey( - IN PSKeyManagement pTable, - IN PBYTE pbyBSSID, - IN DWORD dwKeyIndex, + PSKeyManagement pTable, + PBYTE pbyBSSID, + DWORD dwKeyIndex, OUT PSKeyItem *pKey ); @@ -141,14 +141,14 @@ BOOL KeybRemoveKey( ); BOOL KeybGetTransmitKey( - IN PSKeyManagement pTable, - IN PBYTE pbyBSSID, - IN DWORD dwKeyType, + PSKeyManagement pTable, + PBYTE pbyBSSID, + DWORD dwKeyType, OUT PSKeyItem *pKey ); BOOL KeybCheckPairewiseKey( - IN PSKeyManagement pTable, + PSKeyManagement pTable, OUT PSKeyItem *pKey ); diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c index 166e7fb638c4..64c22c3e4bb3 100644 --- a/drivers/staging/vt6655/power.c +++ b/drivers/staging/vt6655/power.c @@ -76,8 +76,8 @@ static int msglevel =MSG_LEVEL_INFO; void PSvEnablePowerSaving( - IN void *hDeviceContext, - IN WORD wListenInterval + void *hDeviceContext, + WORD wListenInterval ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -118,7 +118,7 @@ PSvEnablePowerSaving( pDevice->bEnablePSMode = TRUE; if (pDevice->eOPMode == OP_MODE_ADHOC) { -// bMgrPrepareBeaconToSend((HANDLE)pDevice, pMgmt); +// bMgrPrepareBeaconToSend((void *)pDevice, pMgmt); } // We don't send null pkt in ad hoc mode since beacon will handle this. else if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) { @@ -146,7 +146,7 @@ PSvEnablePowerSaving( void PSvDisablePowerSaving( - IN void *hDeviceContext + void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -184,9 +184,9 @@ PSvDisablePowerSaving( BOOL PSbConsiderPowerDown( - IN void *hDeviceContext, - IN BOOL bCheckRxDMA, - IN BOOL bCheckCountToWakeUp + void *hDeviceContext, + BOOL bCheckRxDMA, + BOOL bCheckCountToWakeUp ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -252,7 +252,7 @@ PSbConsiderPowerDown( void PSvSendPSPOLL( - IN void *hDeviceContext + void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -298,7 +298,7 @@ PSvSendPSPOLL( -*/ BOOL PSbSendNullPacket( - IN void *hDeviceContext + void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -384,7 +384,7 @@ PSbSendNullPacket( BOOL PSbIsNextTBTTWakeUp( - IN void *hDeviceContext + void *hDeviceContext ) { diff --git a/drivers/staging/vt6655/power.h b/drivers/staging/vt6655/power.h index 769e0d1acd2a..c0dbe216e977 100644 --- a/drivers/staging/vt6655/power.h +++ b/drivers/staging/vt6655/power.h @@ -45,40 +45,40 @@ /*--------------------- Export Functions --------------------------*/ -// IN PSDevice pDevice -// IN PSDevice hDeviceContext +// PSDevice pDevice +// PSDevice hDeviceContext BOOL PSbConsiderPowerDown( - IN void *hDeviceContext, - IN BOOL bCheckRxDMA, - IN BOOL bCheckCountToWakeUp + void *hDeviceContext, + BOOL bCheckRxDMA, + BOOL bCheckCountToWakeUp ); void PSvDisablePowerSaving( - IN void *hDeviceContext + void *hDeviceContext ); void PSvEnablePowerSaving( - IN void *hDeviceContext, - IN WORD wListenInterval + void *hDeviceContext, + WORD wListenInterval ); void PSvSendPSPOLL( - IN void *hDeviceContext + void *hDeviceContext ); BOOL PSbSendNullPacket( - IN void *hDeviceContext + void *hDeviceContext ); BOOL PSbIsNextTBTTWakeUp( - IN void *hDeviceContext + void *hDeviceContext ); #endif //__POWER_H__ diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c index 29eb758c9e7d..7cb86fe2eeb9 100644 --- a/drivers/staging/vt6655/rf.c +++ b/drivers/staging/vt6655/rf.c @@ -808,7 +808,7 @@ BOOL RFbAL2230SelectChannel (DWORD_PTR dwIoBase, BYTE byChannel) * */ BOOL RFbInit ( - IN PSDevice pDevice + PSDevice pDevice ) { BOOL bResult = TRUE; @@ -846,7 +846,7 @@ BOOL bResult = TRUE; * */ BOOL RFbShutDown ( - IN PSDevice pDevice + PSDevice pDevice ) { BOOL bResult = TRUE; @@ -997,9 +997,9 @@ BOOL RFvWriteWakeProgSyn (DWORD_PTR dwIoBase, BYTE byRFType, UINT uChannel) * */ BOOL RFbSetPower ( - IN PSDevice pDevice, - IN UINT uRATE, - IN UINT uCH + PSDevice pDevice, + UINT uRATE, + UINT uCH ) { BOOL bResult = TRUE; @@ -1136,9 +1136,9 @@ BYTE byPwrdBm = 0; */ BOOL RFbRawSetPower ( - IN PSDevice pDevice, - IN BYTE byPwr, - IN UINT uRATE + PSDevice pDevice, + BYTE byPwr, + UINT uRATE ) { BOOL bResult = TRUE; @@ -1203,8 +1203,8 @@ DWORD dwMax7230Pwr = 0; -*/ void RFvRSSITodBm ( - IN PSDevice pDevice, - IN BYTE byCurrRSSI, + PSDevice pDevice, + BYTE byCurrRSSI, long * pldBm ) { diff --git a/drivers/staging/vt6655/rf.h b/drivers/staging/vt6655/rf.h index e6e6ca586330..25dfc7942f67 100644 --- a/drivers/staging/vt6655/rf.h +++ b/drivers/staging/vt6655/rf.h @@ -79,20 +79,20 @@ BOOL IFRFbWriteEmbeded(DWORD_PTR dwIoBase, DWORD dwData); BOOL RFbSelectChannel(DWORD_PTR dwIoBase, BYTE byRFType, BYTE byChannel); BOOL RFbInit ( - IN PSDevice pDevice + PSDevice pDevice ); BOOL RFvWriteWakeProgSyn(DWORD_PTR dwIoBase, BYTE byRFType, UINT uChannel); BOOL RFbSetPower(PSDevice pDevice, UINT uRATE, UINT uCH); BOOL RFbRawSetPower( - IN PSDevice pDevice, - IN BYTE byPwr, - IN UINT uRATE + PSDevice pDevice, + BYTE byPwr, + UINT uRATE ); void RFvRSSITodBm( - IN PSDevice pDevice, - IN BYTE byCurrRSSI, + PSDevice pDevice, + BYTE byCurrRSSI, long *pldBm ); diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 8d1772e70ab1..885741a774b5 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -117,12 +117,12 @@ const WORD wFB_Opt1[2][5] = { static void s_vFillTxKey( - IN PSDevice pDevice, - IN PBYTE pbyBuf, - IN PBYTE pbyIVHead, - IN PSKeyItem pTransmitKey, - IN PBYTE pbyHdrBuf, - IN WORD wPayloadLen, + PSDevice pDevice, + PBYTE pbyBuf, + PBYTE pbyIVHead, + PSKeyItem pTransmitKey, + PBYTE pbyHdrBuf, + WORD wPayloadLen, OUT PBYTE pMICHDR ); @@ -131,59 +131,59 @@ s_vFillTxKey( static void s_vFillRTSHead( - IN PSDevice pDevice, - IN BYTE byPktType, - IN void * pvRTS, - IN UINT cbFrameLength, - IN BOOL bNeedAck, - IN BOOL bDisCRC, - IN PSEthernetHeader psEthHeader, - IN WORD wCurrentRate, - IN BYTE byFBOption + PSDevice pDevice, + BYTE byPktType, + void * pvRTS, + UINT cbFrameLength, + BOOL bNeedAck, + BOOL bDisCRC, + PSEthernetHeader psEthHeader, + WORD wCurrentRate, + BYTE byFBOption ); static void s_vGenerateTxParameter( - IN PSDevice pDevice, - IN BYTE byPktType, - IN void * pTxBufHead, - IN void * pvRrvTime, - IN void * pvRTS, - IN void * pvCTS, - IN UINT cbFrameSize, - IN BOOL bNeedACK, - IN UINT uDMAIdx, - IN PSEthernetHeader psEthHeader, - IN WORD wCurrentRate + PSDevice pDevice, + BYTE byPktType, + void * pTxBufHead, + void * pvRrvTime, + void * pvRTS, + void * pvCTS, + UINT cbFrameSize, + BOOL bNeedACK, + UINT uDMAIdx, + PSEthernetHeader psEthHeader, + WORD wCurrentRate ); static void s_vFillFragParameter( - IN PSDevice pDevice, - IN PBYTE pbyBuffer, - IN UINT uTxType, - IN void * pvtdCurr, - IN WORD wFragType, - IN UINT cbReqCount + PSDevice pDevice, + PBYTE pbyBuffer, + UINT uTxType, + void * pvtdCurr, + WORD wFragType, + UINT cbReqCount ); static UINT s_cbFillTxBufHead ( - IN PSDevice pDevice, - IN BYTE byPktType, - IN PBYTE pbyTxBufferAddr, - IN UINT cbFrameBodySize, - IN UINT uDMAIdx, - IN PSTxDesc pHeadTD, - IN PSEthernetHeader psEthHeader, - IN PBYTE pPacket, - IN BOOL bNeedEncrypt, - IN PSKeyItem pTransmitKey, - IN UINT uNodeIndex, + PSDevice pDevice, + BYTE byPktType, + PBYTE pbyTxBufferAddr, + UINT cbFrameBodySize, + UINT uDMAIdx, + PSTxDesc pHeadTD, + PSEthernetHeader psEthHeader, + PBYTE pPacket, + BOOL bNeedEncrypt, + PSKeyItem pTransmitKey, + UINT uNodeIndex, OUT PUINT puMACfragNum ); @@ -191,17 +191,17 @@ s_cbFillTxBufHead ( static UINT s_uFillDataHead ( - IN PSDevice pDevice, - IN BYTE byPktType, - IN void * pTxDataHead, - IN UINT cbFrameLength, - IN UINT uDMAIdx, - IN BOOL bNeedAck, - IN UINT uFragIdx, - IN UINT cbLastFragmentSize, - IN UINT uMACfragNum, - IN BYTE byFBOption, - IN WORD wCurrentRate + PSDevice pDevice, + BYTE byPktType, + void * pTxDataHead, + UINT cbFrameLength, + UINT uDMAIdx, + BOOL bNeedAck, + UINT uFragIdx, + UINT cbLastFragmentSize, + UINT uMACfragNum, + BYTE byFBOption, + WORD wCurrentRate ); @@ -212,12 +212,12 @@ s_uFillDataHead ( static void s_vFillTxKey ( - IN PSDevice pDevice, - IN PBYTE pbyBuf, - IN PBYTE pbyIVHead, - IN PSKeyItem pTransmitKey, - IN PBYTE pbyHdrBuf, - IN WORD wPayloadLen, + PSDevice pDevice, + PBYTE pbyBuf, + PBYTE pbyIVHead, + PSKeyItem pTransmitKey, + PBYTE pbyHdrBuf, + WORD wPayloadLen, OUT PBYTE pMICHDR ) { @@ -330,10 +330,10 @@ s_vFillTxKey ( static void s_vSWencryption ( - IN PSDevice pDevice, - IN PSKeyItem pTransmitKey, - IN PBYTE pbyPayloadHead, - IN WORD wPayloadSize + PSDevice pDevice, + PSKeyItem pTransmitKey, + PBYTE pbyPayloadHead, + WORD wPayloadSize ) { UINT cbICVlen = 4; @@ -379,11 +379,11 @@ s_vSWencryption ( static UINT s_uGetTxRsvTime ( - IN PSDevice pDevice, - IN BYTE byPktType, - IN UINT cbFrameLength, - IN WORD wRate, - IN BOOL bNeedAck + PSDevice pDevice, + BYTE byPktType, + UINT cbFrameLength, + WORD wRate, + BOOL bNeedAck ) { UINT uDataTime, uAckTime; @@ -410,11 +410,11 @@ s_uGetTxRsvTime ( static UINT s_uGetRTSCTSRsvTime ( - IN PSDevice pDevice, - IN BYTE byRTSRsvType, - IN BYTE byPktType, - IN UINT cbFrameLength, - IN WORD wCurrentRate + PSDevice pDevice, + BYTE byRTSRsvType, + BYTE byPktType, + UINT cbFrameLength, + WORD wCurrentRate ) { UINT uRrvTime , uRTSTime, uCTSTime, uAckTime, uDataTime; @@ -452,16 +452,16 @@ s_uGetRTSCTSRsvTime ( static UINT s_uGetDataDuration ( - IN PSDevice pDevice, - IN BYTE byDurType, - IN UINT cbFrameLength, - IN BYTE byPktType, - IN WORD wRate, - IN BOOL bNeedAck, - IN UINT uFragIdx, - IN UINT cbLastFragmentSize, - IN UINT uMACfragNum, - IN BYTE byFBOption + PSDevice pDevice, + BYTE byDurType, + UINT cbFrameLength, + BYTE byPktType, + WORD wRate, + BOOL bNeedAck, + UINT uFragIdx, + UINT cbLastFragmentSize, + UINT uMACfragNum, + BYTE byFBOption ) { BOOL bLastFrag = 0; @@ -623,13 +623,13 @@ s_uGetDataDuration ( static UINT s_uGetRTSCTSDuration ( - IN PSDevice pDevice, - IN BYTE byDurType, - IN UINT cbFrameLength, - IN BYTE byPktType, - IN WORD wRate, - IN BOOL bNeedAck, - IN BYTE byFBOption + PSDevice pDevice, + BYTE byDurType, + UINT cbFrameLength, + BYTE byPktType, + WORD wRate, + BOOL bNeedAck, + BYTE byFBOption ) { UINT uCTSTime = 0, uDurTime = 0; @@ -721,17 +721,17 @@ s_uGetRTSCTSDuration ( static UINT s_uFillDataHead ( - IN PSDevice pDevice, - IN BYTE byPktType, - IN void * pTxDataHead, - IN UINT cbFrameLength, - IN UINT uDMAIdx, - IN BOOL bNeedAck, - IN UINT uFragIdx, - IN UINT cbLastFragmentSize, - IN UINT uMACfragNum, - IN BYTE byFBOption, - IN WORD wCurrentRate + PSDevice pDevice, + BYTE byPktType, + void * pTxDataHead, + UINT cbFrameLength, + UINT uDMAIdx, + BOOL bNeedAck, + UINT uFragIdx, + UINT cbLastFragmentSize, + UINT uMACfragNum, + BYTE byFBOption, + WORD wCurrentRate ) { WORD wLen = 0x0000; @@ -853,15 +853,15 @@ s_uFillDataHead ( static void s_vFillRTSHead ( - IN PSDevice pDevice, - IN BYTE byPktType, - IN void * pvRTS, - IN UINT cbFrameLength, - IN BOOL bNeedAck, - IN BOOL bDisCRC, - IN PSEthernetHeader psEthHeader, - IN WORD wCurrentRate, - IN BYTE byFBOption + PSDevice pDevice, + BYTE byPktType, + void * pvRTS, + UINT cbFrameLength, + BOOL bNeedAck, + BOOL bDisCRC, + PSEthernetHeader psEthHeader, + WORD wCurrentRate, + BYTE byFBOption ) { UINT uRTSFrameLen = 20; @@ -1047,15 +1047,15 @@ s_vFillRTSHead ( static void s_vFillCTSHead ( - IN PSDevice pDevice, - IN UINT uDMAIdx, - IN BYTE byPktType, - IN void * pvCTS, - IN UINT cbFrameLength, - IN BOOL bNeedAck, - IN BOOL bDisCRC, - IN WORD wCurrentRate, - IN BYTE byFBOption + PSDevice pDevice, + UINT uDMAIdx, + BYTE byPktType, + void * pvCTS, + UINT cbFrameLength, + BOOL bNeedAck, + BOOL bDisCRC, + WORD wCurrentRate, + BYTE byFBOption ) { UINT uCTSFrameLen = 14; @@ -1152,17 +1152,17 @@ s_vFillCTSHead ( static void s_vGenerateTxParameter ( - IN PSDevice pDevice, - IN BYTE byPktType, - IN void * pTxBufHead, - IN void * pvRrvTime, - IN void * pvRTS, - IN void * pvCTS, - IN UINT cbFrameSize, - IN BOOL bNeedACK, - IN UINT uDMAIdx, - IN PSEthernetHeader psEthHeader, - IN WORD wCurrentRate + PSDevice pDevice, + BYTE byPktType, + void * pTxBufHead, + void * pvRrvTime, + void * pvRTS, + void * pvCTS, + UINT cbFrameSize, + BOOL bNeedACK, + UINT uDMAIdx, + PSEthernetHeader psEthHeader, + WORD wCurrentRate ) { UINT cbMACHdLen = WLAN_HDR_ADDR3_LEN; //24 @@ -1270,12 +1270,12 @@ s_vGenerateTxParameter ( static void s_vFillFragParameter( - IN PSDevice pDevice, - IN PBYTE pbyBuffer, - IN UINT uTxType, - IN void * pvtdCurr, - IN WORD wFragType, - IN UINT cbReqCount + PSDevice pDevice, + PBYTE pbyBuffer, + UINT uTxType, + void * pvtdCurr, + WORD wFragType, + UINT cbReqCount ) { PSTxBufHead pTxBufHead = (PSTxBufHead) pbyBuffer; @@ -1318,17 +1318,17 @@ s_vFillFragParameter( static UINT s_cbFillTxBufHead ( - IN PSDevice pDevice, - IN BYTE byPktType, - IN PBYTE pbyTxBufferAddr, - IN UINT cbFrameBodySize, - IN UINT uDMAIdx, - IN PSTxDesc pHeadTD, - IN PSEthernetHeader psEthHeader, - IN PBYTE pPacket, - IN BOOL bNeedEncrypt, - IN PSKeyItem pTransmitKey, - IN UINT uNodeIndex, + PSDevice pDevice, + BYTE byPktType, + PBYTE pbyTxBufferAddr, + UINT cbFrameBodySize, + UINT uDMAIdx, + PSTxDesc pHeadTD, + PSEthernetHeader psEthHeader, + PBYTE pPacket, + BOOL bNeedEncrypt, + PSKeyItem pTransmitKey, + UINT uNodeIndex, OUT PUINT puMACfragNum ) { @@ -2095,17 +2095,17 @@ s_cbFillTxBufHead ( void vGenerateFIFOHeader ( - IN PSDevice pDevice, - IN BYTE byPktType, - IN PBYTE pbyTxBufferAddr, - IN BOOL bNeedEncrypt, - IN UINT cbPayloadSize, - IN UINT uDMAIdx, - IN PSTxDesc pHeadTD, - IN PSEthernetHeader psEthHeader, - IN PBYTE pPacket, - IN PSKeyItem pTransmitKey, - IN UINT uNodeIndex, + PSDevice pDevice, + BYTE byPktType, + PBYTE pbyTxBufferAddr, + BOOL bNeedEncrypt, + UINT cbPayloadSize, + UINT uDMAIdx, + PSTxDesc pHeadTD, + PSEthernetHeader psEthHeader, + PBYTE pPacket, + PSKeyItem pTransmitKey, + UINT uNodeIndex, OUT PUINT puMACfragNum, OUT PUINT pcbHeaderSize ) @@ -2266,14 +2266,14 @@ vGenerateFIFOHeader ( void vGenerateMACHeader ( - IN PSDevice pDevice, - IN PBYTE pbyBufferAddr, - IN WORD wDuration, - IN PSEthernetHeader psEthHeader, - IN BOOL bNeedEncrypt, - IN WORD wFragType, - IN UINT uDMAIdx, - IN UINT uFragIdx + PSDevice pDevice, + PBYTE pbyBufferAddr, + WORD wDuration, + PSEthernetHeader psEthHeader, + BOOL bNeedEncrypt, + WORD wFragType, + UINT uDMAIdx, + UINT uFragIdx ) { PS802_11Header pMACHeader = (PS802_11Header)pbyBufferAddr; @@ -2738,10 +2738,10 @@ CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) { UINT cbGetFragCount ( - IN PSDevice pDevice, - IN PSKeyItem pTransmitKey, - IN UINT cbFrameBodySize, - IN PSEthernetHeader psEthHeader + PSDevice pDevice, + PSKeyItem pTransmitKey, + UINT cbFrameBodySize, + PSEthernetHeader psEthHeader ) { UINT cbMACHdLen; diff --git a/drivers/staging/vt6655/rxtx.h b/drivers/staging/vt6655/rxtx.h index 4c2df48be372..75988c74a189 100644 --- a/drivers/staging/vt6655/rxtx.h +++ b/drivers/staging/vt6655/rxtx.h @@ -41,20 +41,20 @@ /* void vGenerateMACHeader( - IN PSDevice pDevice, - IN DWORD dwTxBufferAddr, - IN PBYTE pbySkbData, - IN UINT cbPacketSize, - IN BOOL bDMA0Used, + PSDevice pDevice, + DWORD dwTxBufferAddr, + PBYTE pbySkbData, + UINT cbPacketSize, + BOOL bDMA0Used, OUT PUINT pcbHeadSize, OUT PUINT pcbAppendPayload ); void vProcessRxMACHeader ( - IN PSDevice pDevice, - IN DWORD dwRxBufferAddr, - IN UINT cbPacketSize, - IN BOOL bIsWEP, + PSDevice pDevice, + DWORD dwRxBufferAddr, + UINT cbPacketSize, + BOOL bIsWEP, OUT PUINT pcbHeadSize ); */ @@ -62,39 +62,39 @@ void vProcessRxMACHeader ( void vGenerateMACHeader ( - IN PSDevice pDevice, - IN PBYTE pbyBufferAddr, - IN WORD wDuration, - IN PSEthernetHeader psEthHeader, - IN BOOL bNeedEncrypt, - IN WORD wFragType, - IN UINT uDMAIdx, - IN UINT uFragIdx + PSDevice pDevice, + PBYTE pbyBufferAddr, + WORD wDuration, + PSEthernetHeader psEthHeader, + BOOL bNeedEncrypt, + WORD wFragType, + UINT uDMAIdx, + UINT uFragIdx ); UINT cbGetFragCount( - IN PSDevice pDevice, - IN PSKeyItem pTransmitKey, - IN UINT cbFrameBodySize, - IN PSEthernetHeader psEthHeader + PSDevice pDevice, + PSKeyItem pTransmitKey, + UINT cbFrameBodySize, + PSEthernetHeader psEthHeader ); void vGenerateFIFOHeader ( - IN PSDevice pDevice, - IN BYTE byPktTyp, - IN PBYTE pbyTxBufferAddr, - IN BOOL bNeedEncrypt, - IN UINT cbPayloadSize, - IN UINT uDMAIdx, - IN PSTxDesc pHeadTD, - IN PSEthernetHeader psEthHeader, - IN PBYTE pPacket, - IN PSKeyItem pTransmitKey, - IN UINT uNodeIndex, + PSDevice pDevice, + BYTE byPktTyp, + PBYTE pbyTxBufferAddr, + BOOL bNeedEncrypt, + UINT cbPayloadSize, + UINT uDMAIdx, + PSTxDesc pHeadTD, + PSEthernetHeader psEthHeader, + PBYTE pPacket, + PSKeyItem pTransmitKey, + UINT uNodeIndex, OUT PUINT puMACfragNum, OUT PUINT pcbHeaderSize ); diff --git a/drivers/staging/vt6655/ttype.h b/drivers/staging/vt6655/ttype.h index b2dff3a7b77b..2921083a9f22 100644 --- a/drivers/staging/vt6655/ttype.h +++ b/drivers/staging/vt6655/ttype.h @@ -33,10 +33,6 @@ /******* Common definitions and typedefs ***********************************/ -#ifndef IN -#define IN -#endif - #ifndef OUT #define OUT #endif diff --git a/drivers/staging/vt6655/vntwifi.c b/drivers/staging/vt6655/vntwifi.c index 03975dabb8d5..bd3b2afe2cf1 100644 --- a/drivers/staging/vt6655/vntwifi.c +++ b/drivers/staging/vt6655/vntwifi.c @@ -71,8 +71,8 @@ -*/ void VNTWIFIvSetOPMode ( - IN void *pMgmtHandle, - IN WMAC_CONFIG_MODE eOPMode + void *pMgmtHandle, + WMAC_CONFIG_MODE eOPMode ) { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; @@ -100,10 +100,10 @@ VNTWIFIvSetOPMode ( -*/ void VNTWIFIvSetIBSSParameter ( - IN void *pMgmtHandle, - IN WORD wBeaconPeriod, - IN WORD wATIMWindow, - IN UINT uChannel + void *pMgmtHandle, + WORD wBeaconPeriod, + WORD wATIMWindow, + UINT uChannel ) { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; @@ -129,7 +129,7 @@ VNTWIFIvSetIBSSParameter ( -*/ PWLAN_IE_SSID VNTWIFIpGetCurrentSSID ( - IN void *pMgmtHandle + void *pMgmtHandle ) { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; @@ -152,7 +152,7 @@ VNTWIFIpGetCurrentSSID ( -*/ UINT VNTWIFIpGetCurrentChannel ( - IN void *pMgmtHandle + void *pMgmtHandle ) { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; @@ -178,7 +178,7 @@ VNTWIFIpGetCurrentChannel ( -*/ WORD VNTWIFIwGetAssocID ( - IN void *pMgmtHandle + void *pMgmtHandle ) { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; @@ -204,8 +204,8 @@ VNTWIFIwGetAssocID ( -*/ BYTE VNTWIFIbyGetMaxSupportRate ( - IN PWLAN_IE_SUPP_RATES pSupportRateIEs, - IN PWLAN_IE_SUPP_RATES pExtSupportRateIEs + PWLAN_IE_SUPP_RATES pSupportRateIEs, + PWLAN_IE_SUPP_RATES pExtSupportRateIEs ) { BYTE byMaxSupportRate = RATE_1M; @@ -250,9 +250,9 @@ VNTWIFIbyGetMaxSupportRate ( -*/ BYTE VNTWIFIbyGetACKTxRate ( - IN BYTE byRxDataRate, - IN PWLAN_IE_SUPP_RATES pSupportRateIEs, - IN PWLAN_IE_SUPP_RATES pExtSupportRateIEs + BYTE byRxDataRate, + PWLAN_IE_SUPP_RATES pSupportRateIEs, + PWLAN_IE_SUPP_RATES pExtSupportRateIEs ) { BYTE byMaxAckRate; @@ -308,8 +308,8 @@ VNTWIFIbyGetACKTxRate ( -*/ void VNTWIFIvSetAuthenticationMode ( - IN void *pMgmtHandle, - IN WMAC_AUTHENTICATION_MODE eAuthMode + void *pMgmtHandle, + WMAC_AUTHENTICATION_MODE eAuthMode ) { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; @@ -340,8 +340,8 @@ VNTWIFIvSetAuthenticationMode ( -*/ void VNTWIFIvSetEncryptionMode ( - IN void *pMgmtHandle, - IN WMAC_ENCRYPTION_MODE eEncryptionMode + void *pMgmtHandle, + WMAC_ENCRYPTION_MODE eEncryptionMode ) { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; @@ -360,8 +360,8 @@ VNTWIFIvSetEncryptionMode ( BOOL VNTWIFIbConfigPhyMode ( - IN void *pMgmtHandle, - IN CARD_PHY_TYPE ePhyType + void *pMgmtHandle, + CARD_PHY_TYPE ePhyType ) { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; @@ -381,7 +381,7 @@ VNTWIFIbConfigPhyMode ( void VNTWIFIbGetConfigPhyMode ( - IN void *pMgmtHandle, + void *pMgmtHandle, OUT void *pePhyType ) { @@ -426,7 +426,7 @@ VNTWIFIbGetConfigPhyMode ( void VNTWIFIvQueryBSSList ( - IN void *pMgmtHandle, + void *pMgmtHandle, OUT PUINT puBSSCount, OUT void **pvFirstBSS ) @@ -456,8 +456,8 @@ VNTWIFIvQueryBSSList ( void VNTWIFIvGetNextBSS ( - IN void *pMgmtHandle, - IN void *pvCurrentBSS, + void *pMgmtHandle, + void *pvCurrentBSS, OUT void **pvNextBSS ) { @@ -496,11 +496,11 @@ VNTWIFIvGetNextBSS ( -*/ void VNTWIFIvUpdateNodeTxCounter( - IN void *pMgmtHandle, - IN PBYTE pbyDestAddress, - IN BOOL bTxOk, - IN WORD wRate, - IN PBYTE pbyTxFailCount + void *pMgmtHandle, + PBYTE pbyDestAddress, + BOOL bTxOk, + WORD wRate, + PBYTE pbyTxFailCount ) { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; @@ -531,8 +531,8 @@ VNTWIFIvUpdateNodeTxCounter( void VNTWIFIvGetTxRate( - IN void *pMgmtHandle, - IN PBYTE pbyDestAddress, + void *pMgmtHandle, + PBYTE pbyDestAddress, OUT PWORD pwTxDataRate, OUT PBYTE pbyACKRate, OUT PBYTE pbyCCKBasicRate, @@ -603,8 +603,8 @@ VNTWIFIvGetTxRate( BYTE VNTWIFIbyGetKeyCypher( - IN void *pMgmtHandle, - IN BOOL bGroupKey + void *pMgmtHandle, + BOOL bGroupKey ) { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; @@ -620,7 +620,7 @@ VNTWIFIbyGetKeyCypher( /* BOOL VNTWIFIbInit( - IN void *pAdapterHandler, + void *pAdapterHandler, OUT void **pMgmtHandler ) { @@ -664,9 +664,9 @@ VNTWIFIbInit( BOOL VNTWIFIbSetPMKIDCache ( - IN void *pMgmtObject, - IN ULONG ulCount, - IN void *pPMKIDInfo + void *pMgmtObject, + ULONG ulCount, + void *pPMKIDInfo ) { PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; @@ -683,7 +683,7 @@ VNTWIFIbSetPMKIDCache ( WORD VNTWIFIwGetMaxSupportRate( - IN void *pMgmtObject + void *pMgmtObject ) { WORD wRate = RATE_54M; @@ -704,8 +704,8 @@ VNTWIFIwGetMaxSupportRate( void VNTWIFIvSet11h ( - IN void *pMgmtObject, - IN BOOL b11hEnable + void *pMgmtObject, + BOOL b11hEnable ) { PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; @@ -715,13 +715,13 @@ VNTWIFIvSet11h ( BOOL VNTWIFIbMeasureReport( - IN void *pMgmtObject, - IN BOOL bEndOfReport, - IN void *pvMeasureEID, - IN BYTE byReportMode, - IN BYTE byBasicMap, - IN BYTE byCCAFraction, - IN PBYTE pbyRPIs + void *pMgmtObject, + BOOL bEndOfReport, + void *pvMeasureEID, + BYTE byReportMode, + BYTE byBasicMap, + BYTE byCCAFraction, + PBYTE pbyRPIs ) { PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; @@ -775,8 +775,8 @@ VNTWIFIbMeasureReport( BOOL VNTWIFIbChannelSwitch( - IN void *pMgmtObject, - IN BYTE byNewChannel + void *pMgmtObject, + BYTE byNewChannel ) { PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; @@ -791,8 +791,8 @@ VNTWIFIbChannelSwitch( /* BOOL VNTWIFIbRadarPresent( - IN void *pMgmtObject, - IN BYTE byChannel + void *pMgmtObject, + BYTE byChannel ) { PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; diff --git a/drivers/staging/vt6655/vntwifi.h b/drivers/staging/vt6655/vntwifi.h index 666684af5cd1..ca1ee0e4446c 100644 --- a/drivers/staging/vt6655/vntwifi.h +++ b/drivers/staging/vt6655/vntwifi.h @@ -142,74 +142,74 @@ typedef enum tagWMAC_POWER_MODE { void VNTWIFIvSetIBSSParameter ( - IN void *pMgmtHandle, - IN WORD wBeaconPeriod, - IN WORD wATIMWindow, - IN UINT uChannel + void *pMgmtHandle, + WORD wBeaconPeriod, + WORD wATIMWindow, + UINT uChannel ); void VNTWIFIvSetOPMode ( - IN void *pMgmtHandle, - IN WMAC_CONFIG_MODE eOPMode + void *pMgmtHandle, + WMAC_CONFIG_MODE eOPMode ); PWLAN_IE_SSID VNTWIFIpGetCurrentSSID( - IN void *pMgmtHandle + void *pMgmtHandle ); UINT VNTWIFIpGetCurrentChannel( - IN void *pMgmtHandle + void *pMgmtHandle ); WORD VNTWIFIwGetAssocID ( - IN void *pMgmtHandle + void *pMgmtHandle ); BYTE VNTWIFIbyGetMaxSupportRate ( - IN PWLAN_IE_SUPP_RATES pSupportRateIEs, - IN PWLAN_IE_SUPP_RATES pExtSupportRateIEs + PWLAN_IE_SUPP_RATES pSupportRateIEs, + PWLAN_IE_SUPP_RATES pExtSupportRateIEs ); BYTE VNTWIFIbyGetACKTxRate ( - IN BYTE byRxDataRate, - IN PWLAN_IE_SUPP_RATES pSupportRateIEs, - IN PWLAN_IE_SUPP_RATES pExtSupportRateIEs + BYTE byRxDataRate, + PWLAN_IE_SUPP_RATES pSupportRateIEs, + PWLAN_IE_SUPP_RATES pExtSupportRateIEs ); void VNTWIFIvSetAuthenticationMode ( - IN void *pMgmtHandle, - IN WMAC_AUTHENTICATION_MODE eAuthMode + void *pMgmtHandle, + WMAC_AUTHENTICATION_MODE eAuthMode ); void VNTWIFIvSetEncryptionMode ( - IN void *pMgmtHandle, - IN WMAC_ENCRYPTION_MODE eEncryptionMode + void *pMgmtHandle, + WMAC_ENCRYPTION_MODE eEncryptionMode ); BOOL VNTWIFIbConfigPhyMode( - IN void *pMgmtHandle, - IN CARD_PHY_TYPE ePhyType + void *pMgmtHandle, + CARD_PHY_TYPE ePhyType ); void VNTWIFIbGetConfigPhyMode( - IN void *pMgmtHandle, + void *pMgmtHandle, OUT void *pePhyType ); void VNTWIFIvQueryBSSList( - IN void *pMgmtHandle, + void *pMgmtHandle, OUT PUINT puBSSCount, OUT void **pvFirstBSS ); @@ -219,8 +219,8 @@ VNTWIFIvQueryBSSList( void VNTWIFIvGetNextBSS ( - IN void *pMgmtHandle, - IN void *pvCurrentBSS, + void *pMgmtHandle, + void *pvCurrentBSS, OUT void **pvNextBSS ); @@ -228,18 +228,18 @@ VNTWIFIvGetNextBSS ( void VNTWIFIvUpdateNodeTxCounter( - IN void *pMgmtHandle, - IN PBYTE pbyDestAddress, - IN BOOL bTxOk, - IN WORD wRate, - IN PBYTE pbyTxFailCount + void *pMgmtHandle, + PBYTE pbyDestAddress, + BOOL bTxOk, + WORD wRate, + PBYTE pbyTxFailCount ); void VNTWIFIvGetTxRate( - IN void *pMgmtHandle, - IN PBYTE pbyDestAddress, + void *pMgmtHandle, + PBYTE pbyDestAddress, OUT PWORD pwTxDataRate, OUT PBYTE pbyACKRate, OUT PBYTE pbyCCKBasicRate, @@ -248,15 +248,15 @@ VNTWIFIvGetTxRate( /* BOOL VNTWIFIbInit( - IN void *pAdapterHandler, + void *pAdapterHandler, OUT void **pMgmtHandler ); */ BYTE VNTWIFIbyGetKeyCypher( - IN void *pMgmtHandle, - IN BOOL bGroupKey + void *pMgmtHandle, + BOOL bGroupKey ); @@ -264,49 +264,49 @@ VNTWIFIbyGetKeyCypher( BOOL VNTWIFIbSetPMKIDCache ( - IN void *pMgmtObject, - IN ULONG ulCount, - IN void *pPMKIDInfo + void *pMgmtObject, + ULONG ulCount, + void *pPMKIDInfo ); BOOL VNTWIFIbCommandRunning ( - IN void *pMgmtObject + void *pMgmtObject ); WORD VNTWIFIwGetMaxSupportRate( - IN void *pMgmtObject + void *pMgmtObject ); // for 802.11h void VNTWIFIvSet11h ( - IN void *pMgmtObject, - IN BOOL b11hEnable + void *pMgmtObject, + BOOL b11hEnable ); BOOL VNTWIFIbMeasureReport( - IN void *pMgmtObject, - IN BOOL bEndOfReport, - IN void *pvMeasureEID, - IN BYTE byReportMode, - IN BYTE byBasicMap, - IN BYTE byCCAFraction, - IN PBYTE pbyRPIs + void *pMgmtObject, + BOOL bEndOfReport, + void *pvMeasureEID, + BYTE byReportMode, + BYTE byBasicMap, + BYTE byCCAFraction, + PBYTE pbyRPIs ); BOOL VNTWIFIbChannelSwitch( - IN void *pMgmtObject, - IN BYTE byNewChannel + void *pMgmtObject, + BYTE byNewChannel ); /* BOOL VNTWIFIbRadarPresent( - IN void *pMgmtObject, - IN BYTE byChannel + void *pMgmtObject, + BYTE byChannel ); */ diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c index 6e460409f984..28665d870f59 100644 --- a/drivers/staging/vt6655/wcmd.c +++ b/drivers/staging/vt6655/wcmd.c @@ -68,19 +68,19 @@ static int msglevel =MSG_LEVEL_INFO; static void s_vProbeChannel( - IN PSDevice pDevice + PSDevice pDevice ); static PSTxMgmtPacket s_MgrMakeProbeRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PBYTE pScanBSSID, - IN PWLAN_IE_SSID pSSID, - IN PWLAN_IE_SUPP_RATES pCurrRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + PBYTE pScanBSSID, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pCurrRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ); @@ -204,7 +204,7 @@ vAdHocBeaconRestart(PSDevice pDevice) static void s_vProbeChannel( - IN PSDevice pDevice + PSDevice pDevice ) { //1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M @@ -267,12 +267,12 @@ s_vProbeChannel( PSTxMgmtPacket s_MgrMakeProbeRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PBYTE pScanBSSID, - IN PWLAN_IE_SSID pSSID, - IN PWLAN_IE_SUPP_RATES pCurrRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + PBYTE pScanBSSID, + PWLAN_IE_SSID pSSID, + PWLAN_IE_SUPP_RATES pCurrRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ) { @@ -319,8 +319,8 @@ s_MgrMakeProbeRequest( void vCommandTimerWait( - IN void *hDeviceContext, - IN UINT MSecond + void *hDeviceContext, + UINT MSecond ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -339,7 +339,7 @@ vCommandTimerWait( void vCommandTimer ( - IN void *hDeviceContext + void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -980,9 +980,9 @@ s_bCommandComplete ( BOOL bScheduleCommand ( - IN void *hDeviceContext, - IN CMD_CODE eCommand, - IN PBYTE pbyItem0 + void *hDeviceContext, + CMD_CODE eCommand, + PBYTE pbyItem0 ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1061,7 +1061,7 @@ BOOL bScheduleCommand ( * */ BOOL bClearBSSID_SCAN ( - IN void *hDeviceContext + void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1083,7 +1083,7 @@ BOOL bClearBSSID_SCAN ( //mike add:reset command timer void vResetCommandTimer( - IN void *hDeviceContext + void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1107,7 +1107,7 @@ vResetCommandTimer( #ifdef TxInSleep void BSSvSecondTxData( - IN void *hDeviceContext + void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; diff --git a/drivers/staging/vt6655/wcmd.h b/drivers/staging/vt6655/wcmd.h index 67b08f61edcc..c3c418089513 100644 --- a/drivers/staging/vt6655/wcmd.h +++ b/drivers/staging/vt6655/wcmd.h @@ -111,34 +111,34 @@ typedef enum tagCMD_STATE { /*--------------------- Export Functions --------------------------*/ void vResetCommandTimer( - IN void *hDeviceContext + void *hDeviceContext ); void vCommandTimer ( - IN void *hDeviceContext + void *hDeviceContext ); BOOL bClearBSSID_SCAN( - IN void *hDeviceContext + void *hDeviceContext ); BOOL bScheduleCommand( - IN void *hDeviceContext, - IN CMD_CODE eCommand, - IN PBYTE pbyItem0 + void *hDeviceContext, + CMD_CODE eCommand, + PBYTE pbyItem0 ); void vCommandTimerWait( - IN void *hDeviceContext, - IN UINT MSecond + void *hDeviceContext, + UINT MSecond ); #ifdef TxInSleep void BSSvSecondTxData( - IN void *hDeviceContext + void *hDeviceContext ); #endif diff --git a/drivers/staging/vt6655/wmgr.c b/drivers/staging/vt6655/wmgr.c index 614850a7b914..19a16cae175c 100644 --- a/drivers/staging/vt6655/wmgr.c +++ b/drivers/staging/vt6655/wmgr.c @@ -94,110 +94,110 @@ static int msglevel =MSG_LEVEL_INFO; /*--------------------- Static Functions --------------------------*/ //2008-8-4 by chester static BOOL ChannelExceedZoneType( - IN PSDevice pDevice, - IN BYTE byCurrChannel + PSDevice pDevice, + BYTE byCurrChannel ); // Association/diassociation functions static PSTxMgmtPacket s_MgrMakeAssocRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PBYTE pDAddr, - IN WORD wCurrCapInfo, - IN WORD wListenInterval, - IN PWLAN_IE_SSID pCurrSSID, - IN PWLAN_IE_SUPP_RATES pCurrRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + PBYTE pDAddr, + WORD wCurrCapInfo, + WORD wListenInterval, + PWLAN_IE_SSID pCurrSSID, + PWLAN_IE_SUPP_RATES pCurrRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ); static void s_vMgrRxAssocRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket, - IN UINT uNodeIndex + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + UINT uNodeIndex ); static PSTxMgmtPacket s_MgrMakeReAssocRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PBYTE pDAddr, - IN WORD wCurrCapInfo, - IN WORD wListenInterval, - IN PWLAN_IE_SSID pCurrSSID, - IN PWLAN_IE_SUPP_RATES pCurrRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + PBYTE pDAddr, + WORD wCurrCapInfo, + WORD wListenInterval, + PWLAN_IE_SSID pCurrSSID, + PWLAN_IE_SUPP_RATES pCurrRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ); static void s_vMgrRxAssocResponse( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket, - IN BOOL bReAssocType + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + BOOL bReAssocType ); static void s_vMgrRxDisassociation( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ); // Authentication/deauthen functions static void s_vMgrRxAuthenSequence_1( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PWLAN_FR_AUTHEN pFrame + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame ); static void s_vMgrRxAuthenSequence_2( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PWLAN_FR_AUTHEN pFrame + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame ); static void s_vMgrRxAuthenSequence_3( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PWLAN_FR_AUTHEN pFrame + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame ); static void s_vMgrRxAuthenSequence_4( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PWLAN_FR_AUTHEN pFrame + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame ); static void s_vMgrRxAuthentication( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ); static void s_vMgrRxDeauthentication( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ); // Scan functions @@ -205,49 +205,49 @@ s_vMgrRxDeauthentication( static void s_vMgrRxProbeRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ); static void s_vMgrRxProbeResponse( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ); // beacon functions static void s_vMgrRxBeacon( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket, - IN BOOL bInScan + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + BOOL bInScan ); static void s_vMgrFormatTIM( - IN PSMgmtObject pMgmt, - IN PWLAN_IE_TIM pTIM + PSMgmtObject pMgmt, + PWLAN_IE_TIM pTIM ); static PSTxMgmtPacket s_MgrMakeBeacon( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN WORD wCurrCapInfo, - IN WORD wCurrBeaconPeriod, - IN UINT uCurrChannel, - IN WORD wCurrATIMWinodw, - IN PWLAN_IE_SSID pCurrSSID, - IN PBYTE pCurrBSSID, - IN PWLAN_IE_SUPP_RATES pCurrSuppRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + WORD wCurrCapInfo, + WORD wCurrBeaconPeriod, + UINT uCurrChannel, + WORD wCurrATIMWinodw, + PWLAN_IE_SSID pCurrSSID, + PBYTE pCurrBSSID, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ); @@ -255,78 +255,78 @@ s_MgrMakeBeacon( static PSTxMgmtPacket s_MgrMakeAssocResponse( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN WORD wCurrCapInfo, - IN WORD wAssocStatus, - IN WORD wAssocAID, - IN PBYTE pDstAddr, - IN PWLAN_IE_SUPP_RATES pCurrSuppRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + WORD wCurrCapInfo, + WORD wAssocStatus, + WORD wAssocAID, + PBYTE pDstAddr, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ); // ReAssociation response static PSTxMgmtPacket s_MgrMakeReAssocResponse( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN WORD wCurrCapInfo, - IN WORD wAssocStatus, - IN WORD wAssocAID, - IN PBYTE pDstAddr, - IN PWLAN_IE_SUPP_RATES pCurrSuppRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + WORD wCurrCapInfo, + WORD wAssocStatus, + WORD wAssocAID, + PBYTE pDstAddr, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ); // Probe response static PSTxMgmtPacket s_MgrMakeProbeResponse( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN WORD wCurrCapInfo, - IN WORD wCurrBeaconPeriod, - IN UINT uCurrChannel, - IN WORD wCurrATIMWinodw, - IN PBYTE pDstAddr, - IN PWLAN_IE_SSID pCurrSSID, - IN PBYTE pCurrBSSID, - IN PWLAN_IE_SUPP_RATES pCurrSuppRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates, - IN BYTE byPHYType + PSDevice pDevice, + PSMgmtObject pMgmt, + WORD wCurrCapInfo, + WORD wCurrBeaconPeriod, + UINT uCurrChannel, + WORD wCurrATIMWinodw, + PBYTE pDstAddr, + PWLAN_IE_SSID pCurrSSID, + PBYTE pCurrBSSID, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates, + BYTE byPHYType ); // received status static void s_vMgrLogStatus( - IN PSMgmtObject pMgmt, - IN WORD wStatus + PSMgmtObject pMgmt, + WORD wStatus ); static void s_vMgrSynchBSS ( - IN PSDevice pDevice, - IN UINT uBSSMode, - IN PKnownBSS pCurr, + PSDevice pDevice, + UINT uBSSMode, + PKnownBSS pCurr, OUT PCMD_STATUS pStatus ); static BOOL s_bCipherMatch ( - IN PKnownBSS pBSSNode, - IN NDIS_802_11_ENCRYPTION_STATUS EncStatus, + PKnownBSS pBSSNode, + NDIS_802_11_ENCRYPTION_STATUS EncStatus, OUT PBYTE pbyCCSPK, OUT PBYTE pbyCCSGK ); static void Encyption_Rebuild( - IN PSDevice pDevice, - IN PKnownBSS pCurr + PSDevice pDevice, + PKnownBSS pCurr ); @@ -349,7 +349,7 @@ s_bCipherMatch ( void vMgrObjectInit( - IN void *hDeviceContext + void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -385,7 +385,7 @@ vMgrObjectInit( void vMgrTimerInit( - IN void *hDeviceContext + void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -433,7 +433,7 @@ vMgrTimerInit( void vMgrObjectReset( - IN void *hDeviceContext + void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -462,8 +462,8 @@ vMgrObjectReset( void vMgrAssocBeginSta( - IN void *hDeviceContext, - IN PSMgmtObject pMgmt, + void *hDeviceContext, + PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ) { @@ -538,8 +538,8 @@ vMgrAssocBeginSta( void vMgrReAssocBeginSta( - IN void *hDeviceContext, - IN PSMgmtObject pMgmt, + void *hDeviceContext, + PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ) { @@ -617,10 +617,10 @@ vMgrReAssocBeginSta( void vMgrDisassocBeginSta( - IN void *hDeviceContext, - IN PSMgmtObject pMgmt, - IN PBYTE abyDestAddress, - IN WORD wReason, + void *hDeviceContext, + PSMgmtObject pMgmt, + PBYTE abyDestAddress, + WORD wReason, OUT PCMD_STATUS pStatus ) { @@ -680,10 +680,10 @@ vMgrDisassocBeginSta( static void s_vMgrRxAssocRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket, - IN UINT uNodeIndex + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + UINT uNodeIndex ) { WLAN_FR_ASSOCREQ sFrame; @@ -842,10 +842,10 @@ s_vMgrRxAssocRequest( static void s_vMgrRxReAssocRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket, - IN UINT uNodeIndex + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + UINT uNodeIndex ) { WLAN_FR_REASSOCREQ sFrame; @@ -992,10 +992,10 @@ s_vMgrRxReAssocRequest( static void s_vMgrRxAssocResponse( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket, - IN BOOL bReAssocType + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + BOOL bReAssocType ) { WLAN_FR_ASSOCRESP sFrame; @@ -1152,8 +1152,8 @@ if(pMgmt->eCurrState == WMAC_STATE_ASSOC) void vMgrAuthenBeginSta( - IN void *hDeviceContext, - IN PSMgmtObject pMgmt, + void *hDeviceContext, + PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ) { @@ -1210,10 +1210,10 @@ vMgrAuthenBeginSta( void vMgrDeAuthenBeginSta( - IN void *hDeviceContext, - IN PSMgmtObject pMgmt, - IN PBYTE abyDestAddress, - IN WORD wReason, + void *hDeviceContext, + PSMgmtObject pMgmt, + PBYTE abyDestAddress, + WORD wReason, OUT PCMD_STATUS pStatus ) { @@ -1267,9 +1267,9 @@ vMgrDeAuthenBeginSta( static void s_vMgrRxAuthentication( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ) { WLAN_FR_AUTHEN sFrame; @@ -1325,9 +1325,9 @@ s_vMgrRxAuthentication( static void s_vMgrRxAuthenSequence_1( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PWLAN_FR_AUTHEN pFrame + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame ) { PSTxMgmtPacket pTxPacket = NULL; @@ -1431,9 +1431,9 @@ s_vMgrRxAuthenSequence_1( static void s_vMgrRxAuthenSequence_2( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PWLAN_FR_AUTHEN pFrame + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame ) { WLAN_FR_AUTHEN sFrame; @@ -1533,9 +1533,9 @@ s_vMgrRxAuthenSequence_2( static void s_vMgrRxAuthenSequence_3( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PWLAN_FR_AUTHEN pFrame + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame ) { PSTxMgmtPacket pTxPacket = NULL; @@ -1621,9 +1621,9 @@ reply: static void s_vMgrRxAuthenSequence_4( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PWLAN_FR_AUTHEN pFrame + PSDevice pDevice, + PSMgmtObject pMgmt, + PWLAN_FR_AUTHEN pFrame ) { @@ -1660,9 +1660,9 @@ s_vMgrRxAuthenSequence_4( static void s_vMgrRxDisassociation( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ) { WLAN_FR_DISASSOC sFrame; @@ -1739,9 +1739,9 @@ s_vMgrRxDisassociation( static void s_vMgrRxDeauthentication( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ) { WLAN_FR_DEAUTHEN sFrame; @@ -1827,8 +1827,8 @@ s_vMgrRxDeauthentication( -*/ static BOOL ChannelExceedZoneType( - IN PSDevice pDevice, - IN BYTE byCurrChannel + PSDevice pDevice, + BYTE byCurrChannel ) { BOOL exceed=FALSE; @@ -1865,10 +1865,10 @@ ChannelExceedZoneType( static void s_vMgrRxBeacon( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket, - IN BOOL bInScan + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket, + BOOL bInScan ) { @@ -2386,7 +2386,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) -*/ void vMgrCreateOwnIBSS( - IN void *hDeviceContext, + void *hDeviceContext, OUT PCMD_STATUS pStatus ) { @@ -2653,7 +2653,7 @@ vMgrCreateOwnIBSS( void vMgrJoinBSSBegin( - IN void *hDeviceContext, + void *hDeviceContext, OUT PCMD_STATUS pStatus ) { @@ -2922,9 +2922,9 @@ vMgrJoinBSSBegin( static void s_vMgrSynchBSS ( - IN PSDevice pDevice, - IN UINT uBSSMode, - IN PKnownBSS pCurr, + PSDevice pDevice, + UINT uBSSMode, + PKnownBSS pCurr, OUT PCMD_STATUS pStatus ) { @@ -3089,8 +3089,8 @@ s_vMgrSynchBSS ( //mike add: fix NetworkManager 0.7.0 hidden ssid mode in WPA encryption // ,need reset eAuthenMode and eEncryptionStatus static void Encyption_Rebuild( - IN PSDevice pDevice, - IN PKnownBSS pCurr + PSDevice pDevice, + PKnownBSS pCurr ) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -3147,8 +3147,8 @@ s_vMgrSynchBSS ( static void s_vMgrFormatTIM( - IN PSMgmtObject pMgmt, - IN PWLAN_IE_TIM pTIM + PSMgmtObject pMgmt, + PWLAN_IE_TIM pTIM ) { BYTE byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; @@ -3222,16 +3222,16 @@ s_vMgrFormatTIM( static PSTxMgmtPacket s_MgrMakeBeacon( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN WORD wCurrCapInfo, - IN WORD wCurrBeaconPeriod, - IN UINT uCurrChannel, - IN WORD wCurrATIMWinodw, - IN PWLAN_IE_SSID pCurrSSID, - IN PBYTE pCurrBSSID, - IN PWLAN_IE_SUPP_RATES pCurrSuppRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + WORD wCurrCapInfo, + WORD wCurrBeaconPeriod, + UINT uCurrChannel, + WORD wCurrATIMWinodw, + PWLAN_IE_SSID pCurrSSID, + PBYTE pCurrBSSID, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ) { PSTxMgmtPacket pTxPacket = NULL; @@ -3451,18 +3451,18 @@ s_MgrMakeBeacon( PSTxMgmtPacket s_MgrMakeProbeResponse( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN WORD wCurrCapInfo, - IN WORD wCurrBeaconPeriod, - IN UINT uCurrChannel, - IN WORD wCurrATIMWinodw, - IN PBYTE pDstAddr, - IN PWLAN_IE_SSID pCurrSSID, - IN PBYTE pCurrBSSID, - IN PWLAN_IE_SUPP_RATES pCurrSuppRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates, - IN BYTE byPHYType + PSDevice pDevice, + PSMgmtObject pMgmt, + WORD wCurrCapInfo, + WORD wCurrBeaconPeriod, + UINT uCurrChannel, + WORD wCurrATIMWinodw, + PBYTE pDstAddr, + PWLAN_IE_SSID pCurrSSID, + PBYTE pCurrBSSID, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates, + BYTE byPHYType ) { PSTxMgmtPacket pTxPacket = NULL; @@ -3640,14 +3640,14 @@ s_MgrMakeProbeResponse( PSTxMgmtPacket s_MgrMakeAssocRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PBYTE pDAddr, - IN WORD wCurrCapInfo, - IN WORD wListenInterval, - IN PWLAN_IE_SSID pCurrSSID, - IN PWLAN_IE_SUPP_RATES pCurrRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + PBYTE pDAddr, + WORD wCurrCapInfo, + WORD wListenInterval, + PWLAN_IE_SSID pCurrSSID, + PWLAN_IE_SUPP_RATES pCurrRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ) { PSTxMgmtPacket pTxPacket = NULL; @@ -3915,14 +3915,14 @@ s_MgrMakeAssocRequest( PSTxMgmtPacket s_MgrMakeReAssocRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PBYTE pDAddr, - IN WORD wCurrCapInfo, - IN WORD wListenInterval, - IN PWLAN_IE_SSID pCurrSSID, - IN PWLAN_IE_SUPP_RATES pCurrRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + PBYTE pDAddr, + WORD wCurrCapInfo, + WORD wListenInterval, + PWLAN_IE_SSID pCurrSSID, + PWLAN_IE_SUPP_RATES pCurrRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ) { PSTxMgmtPacket pTxPacket = NULL; @@ -4167,14 +4167,14 @@ s_MgrMakeReAssocRequest( PSTxMgmtPacket s_MgrMakeAssocResponse( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN WORD wCurrCapInfo, - IN WORD wAssocStatus, - IN WORD wAssocAID, - IN PBYTE pDstAddr, - IN PWLAN_IE_SUPP_RATES pCurrSuppRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + WORD wCurrCapInfo, + WORD wAssocStatus, + WORD wAssocAID, + PBYTE pDstAddr, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ) { PSTxMgmtPacket pTxPacket = NULL; @@ -4241,14 +4241,14 @@ s_MgrMakeAssocResponse( PSTxMgmtPacket s_MgrMakeReAssocResponse( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN WORD wCurrCapInfo, - IN WORD wAssocStatus, - IN WORD wAssocAID, - IN PBYTE pDstAddr, - IN PWLAN_IE_SUPP_RATES pCurrSuppRates, - IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates + PSDevice pDevice, + PSMgmtObject pMgmt, + WORD wCurrCapInfo, + WORD wAssocStatus, + WORD wAssocAID, + PBYTE pDstAddr, + PWLAN_IE_SUPP_RATES pCurrSuppRates, + PWLAN_IE_SUPP_RATES pCurrExtSuppRates ) { PSTxMgmtPacket pTxPacket = NULL; @@ -4315,9 +4315,9 @@ s_MgrMakeReAssocResponse( static void s_vMgrRxProbeResponse( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ) { PKnownBSS pBSSList = NULL; @@ -4440,9 +4440,9 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) static void s_vMgrRxProbeRequest( - IN PSDevice pDevice, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + PSDevice pDevice, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ) { WLAN_FR_PROBEREQ sFrame; @@ -4536,9 +4536,9 @@ s_vMgrRxProbeRequest( void vMgrRxManagePacket( - IN void *hDeviceContext, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + void *hDeviceContext, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -4685,8 +4685,8 @@ vMgrRxManagePacket( -*/ BOOL bMgrPrepareBeaconToSend( - IN void *hDeviceContext, - IN PSMgmtObject pMgmt + void *hDeviceContext, + PSMgmtObject pMgmt ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -4740,8 +4740,8 @@ bMgrPrepareBeaconToSend( static void s_vMgrLogStatus( - IN PSMgmtObject pMgmt, - IN WORD wStatus + PSMgmtObject pMgmt, + WORD wStatus ) { switch( wStatus ){ @@ -4809,9 +4809,9 @@ s_vMgrLogStatus( -*/ BOOL bAdd_PMKID_Candidate ( - IN void *hDeviceContext, - IN PBYTE pbyBSSID, - IN PSRSNCapObject psRSNCapObj + void *hDeviceContext, + PBYTE pbyBSSID, + PSRSNCapObject psRSNCapObj ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -4870,7 +4870,7 @@ bAdd_PMKID_Candidate ( -*/ void vFlush_PMKID_Candidate ( - IN void *hDeviceContext + void *hDeviceContext ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -4883,8 +4883,8 @@ vFlush_PMKID_Candidate ( static BOOL s_bCipherMatch ( - IN PKnownBSS pBSSNode, - IN NDIS_802_11_ENCRYPTION_STATUS EncStatus, + PKnownBSS pBSSNode, + NDIS_802_11_ENCRYPTION_STATUS EncStatus, OUT PBYTE pbyCCSPK, OUT PBYTE pbyCCSGK ) diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index cee860281812..a86406e63bc8 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -401,102 +401,102 @@ typedef struct tagSMgmtObject void vMgrObjectInit( - IN void *hDeviceContext + void *hDeviceContext ); void vMgrTimerInit( - IN void *hDeviceContext + void *hDeviceContext ); void vMgrObjectReset( - IN void *hDeviceContext + void *hDeviceContext ); void vMgrAssocBeginSta( - IN void *hDeviceContext, - IN PSMgmtObject pMgmt, + void *hDeviceContext, + PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ); void vMgrReAssocBeginSta( - IN void *hDeviceContext, - IN PSMgmtObject pMgmt, + void *hDeviceContext, + PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ); void vMgrDisassocBeginSta( - IN void *hDeviceContext, - IN PSMgmtObject pMgmt, - IN PBYTE abyDestAddress, - IN WORD wReason, + void *hDeviceContext, + PSMgmtObject pMgmt, + PBYTE abyDestAddress, + WORD wReason, OUT PCMD_STATUS pStatus ); void vMgrAuthenBeginSta( - IN void *hDeviceContext, - IN PSMgmtObject pMgmt, + void *hDeviceContext, + PSMgmtObject pMgmt, OUT PCMD_STATUS pStatus ); void vMgrCreateOwnIBSS( - IN void *hDeviceContext, + void *hDeviceContext, OUT PCMD_STATUS pStatus ); void vMgrJoinBSSBegin( - IN void *hDeviceContext, + void *hDeviceContext, OUT PCMD_STATUS pStatus ); void vMgrRxManagePacket( - IN void *hDeviceContext, - IN PSMgmtObject pMgmt, - IN PSRxMgmtPacket pRxPacket + void *hDeviceContext, + PSMgmtObject pMgmt, + PSRxMgmtPacket pRxPacket ); /* void vMgrScanBegin( - IN void *hDeviceContext, + void *hDeviceContext, OUT PCMD_STATUS pStatus ); */ void vMgrDeAuthenBeginSta( - IN void *hDeviceContext, - IN PSMgmtObject pMgmt, - IN PBYTE abyDestAddress, - IN WORD wReason, + void *hDeviceContext, + PSMgmtObject pMgmt, + PBYTE abyDestAddress, + WORD wReason, OUT PCMD_STATUS pStatus ); BOOL bMgrPrepareBeaconToSend( - IN void *hDeviceContext, - IN PSMgmtObject pMgmt + void *hDeviceContext, + PSMgmtObject pMgmt ); BOOL bAdd_PMKID_Candidate ( - IN void *hDeviceContext, - IN PBYTE pbyBSSID, - IN PSRSNCapObject psRSNCapObj + void *hDeviceContext, + PBYTE pbyBSSID, + PSRSNCapObject psRSNCapObj ); void vFlush_PMKID_Candidate ( - IN void *hDeviceContext + void *hDeviceContext ); #endif // __WMGR_H__ diff --git a/drivers/staging/vt6655/wpa.c b/drivers/staging/vt6655/wpa.c index 75ae83814d89..da5c814e200e 100644 --- a/drivers/staging/vt6655/wpa.c +++ b/drivers/staging/vt6655/wpa.c @@ -70,7 +70,7 @@ const BYTE abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 }; void WPA_ClearRSN ( - IN PKnownBSS pBSSList + PKnownBSS pBSSList ) { int ii; @@ -106,8 +106,8 @@ WPA_ClearRSN ( -*/ void WPA_ParseRSN ( - IN PKnownBSS pBSSList, - IN PWLAN_IE_RSN_EXT pRSN + PKnownBSS pBSSList, + PWLAN_IE_RSN_EXT pRSN ) { PWLAN_IE_RSN_AUTH pIE_RSN_Auth = NULL; @@ -241,7 +241,7 @@ BOOL WPA_SearchRSN ( BYTE byCmd, BYTE byEncrypt, - IN PKnownBSS pBSSList + PKnownBSS pBSSList ) { int ii; @@ -299,7 +299,7 @@ WPA_SearchRSN ( -*/ BOOL WPAb_Is_RSN ( - IN PWLAN_IE_RSN_EXT pRSN + PWLAN_IE_RSN_EXT pRSN ) { if (pRSN == NULL) diff --git a/drivers/staging/vt6655/wpa.h b/drivers/staging/vt6655/wpa.h index d77c7bb2274a..80d990b09d25 100644 --- a/drivers/staging/vt6655/wpa.h +++ b/drivers/staging/vt6655/wpa.h @@ -60,25 +60,25 @@ void WPA_ClearRSN( - IN PKnownBSS pBSSList + PKnownBSS pBSSList ); void WPA_ParseRSN( - IN PKnownBSS pBSSList, - IN PWLAN_IE_RSN_EXT pRSN + PKnownBSS pBSSList, + PWLAN_IE_RSN_EXT pRSN ); BOOL WPA_SearchRSN( BYTE byCmd, BYTE byEncrypt, - IN PKnownBSS pBSSList + PKnownBSS pBSSList ); BOOL WPAb_Is_RSN( - IN PWLAN_IE_RSN_EXT pRSN + PWLAN_IE_RSN_EXT pRSN ); #endif // __WPA_H__ diff --git a/drivers/staging/vt6655/wpa2.c b/drivers/staging/vt6655/wpa2.c index 3f377b6a2bac..102a18a835b5 100644 --- a/drivers/staging/vt6655/wpa2.c +++ b/drivers/staging/vt6655/wpa2.c @@ -74,7 +74,7 @@ const BYTE abyOUIPSK[4] = { 0x00, 0x0F, 0xAC, 0x02 }; -*/ void WPA2_ClearRSN ( - IN PKnownBSS pBSSNode + PKnownBSS pBSSNode ) { int ii; @@ -109,8 +109,8 @@ WPA2_ClearRSN ( -*/ void WPA2vParseRSN ( - IN PKnownBSS pBSSNode, - IN PWLAN_IE_RSN pRSN + PKnownBSS pBSSNode, + PWLAN_IE_RSN pRSN ) { int i, j; @@ -263,7 +263,7 @@ WPA2vParseRSN ( -*/ UINT WPA2uSetIEs( - IN void *pMgmtHandle, + void *pMgmtHandle, OUT PWLAN_IE_RSN pRSNIEs ) { diff --git a/drivers/staging/vt6655/wpa2.h b/drivers/staging/vt6655/wpa2.h index 7becc749c9ff..1f2a02d2a57d 100644 --- a/drivers/staging/vt6655/wpa2.h +++ b/drivers/staging/vt6655/wpa2.h @@ -60,18 +60,18 @@ typedef struct tagSPMKIDCache { void WPA2_ClearRSN ( - IN PKnownBSS pBSSNode + PKnownBSS pBSSNode ); void WPA2vParseRSN ( - IN PKnownBSS pBSSNode, - IN PWLAN_IE_RSN pRSN + PKnownBSS pBSSNode, + PWLAN_IE_RSN pRSN ); UINT WPA2uSetIEs( - IN void *pMgmtHandle, + void *pMgmtHandle, OUT PWLAN_IE_RSN pRSNIEs ); -- cgit v1.2.3 From 3cdec5540d622e6b910a1fe91f544630a8ba8099 Mon Sep 17 00:00:00 2001 From: Charles Clément Date: Wed, 12 May 2010 20:54:40 -0700 Subject: Staging: vt6655: remove OUT definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove empty OUT definition used to specify output parameters. Signed-off-by: Charles Clément Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/baseband.c | 6 +++--- drivers/staging/vt6655/baseband.h | 6 +++--- drivers/staging/vt6655/bssdb.c | 4 ++-- drivers/staging/vt6655/bssdb.h | 4 ++-- drivers/staging/vt6655/card.c | 20 ++++++++++---------- drivers/staging/vt6655/card.h | 12 ++++++------ drivers/staging/vt6655/datarate.c | 10 +++++----- drivers/staging/vt6655/datarate.h | 10 +++++----- drivers/staging/vt6655/dpc.c | 40 +++++++++++++++++++-------------------- drivers/staging/vt6655/key.c | 6 +++--- drivers/staging/vt6655/key.h | 6 +++--- drivers/staging/vt6655/rxtx.c | 12 ++++++------ drivers/staging/vt6655/rxtx.h | 10 +++++----- drivers/staging/vt6655/vntwifi.c | 18 +++++++++--------- drivers/staging/vt6655/vntwifi.h | 18 +++++++++--------- drivers/staging/vt6655/wmgr.c | 26 ++++++++++++------------- drivers/staging/vt6655/wmgr.h | 16 ++++++++-------- drivers/staging/vt6655/wpa2.c | 2 +- drivers/staging/vt6655/wpa2.h | 2 +- 19 files changed, 114 insertions(+), 114 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index 2931a0ffcf32..5414c6c6c050 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -1849,9 +1849,9 @@ BBvCaculateParameter ( UINT cbFrameLength, WORD wRate, BYTE byPacketType, - OUT PWORD pwPhyLen, - OUT PBYTE pbyPhySrv, - OUT PBYTE pbyPhySgn + PWORD pwPhyLen, + PBYTE pbyPhySrv, + PBYTE pbyPhySgn ) { UINT cbBitCount; diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index 3eea7aa2fba2..b236ff4139a0 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -132,9 +132,9 @@ BBvCaculateParameter ( UINT cbFrameLength, WORD wRate, BYTE byPacketType, - OUT PWORD pwPhyLen, - OUT PBYTE pbyPhySrv, - OUT PBYTE pbyPhySgn + PWORD pwPhyLen, + PBYTE pbyPhySrv, + PBYTE pbyPhySgn ); BOOL BBbReadEmbeded(DWORD_PTR dwIoBase, BYTE byBBAddr, PBYTE pbyData); diff --git a/drivers/staging/vt6655/bssdb.c b/drivers/staging/vt6655/bssdb.c index e64238e5e8c4..6312a55dab1a 100644 --- a/drivers/staging/vt6655/bssdb.c +++ b/drivers/staging/vt6655/bssdb.c @@ -766,7 +766,7 @@ BOOL BSSDBbIsSTAInNodeDB( void *pMgmtObject, PBYTE abyDstAddr, - OUT PUINT puNodeIndex + PUINT puNodeIndex ) { PSMgmtObject pMgmt = (PSMgmtObject) pMgmtObject; @@ -800,7 +800,7 @@ BSSDBbIsSTAInNodeDB( void BSSvCreateOneNode( void *hDeviceContext, - OUT PUINT puNodeIndex + PUINT puNodeIndex ) { diff --git a/drivers/staging/vt6655/bssdb.h b/drivers/staging/vt6655/bssdb.h index ec1e32bf35b5..e09ef8762979 100644 --- a/drivers/staging/vt6655/bssdb.h +++ b/drivers/staging/vt6655/bssdb.h @@ -312,13 +312,13 @@ BOOL BSSDBbIsSTAInNodeDB( void *hDeviceContext, PBYTE abyDstAddr, - OUT PUINT puNodeIndex + PUINT puNodeIndex ); void BSSvCreateOneNode( void *hDeviceContext, - OUT PUINT puNodeIndex + PUINT puNodeIndex ); void diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index bc61ca912cb6..b071236607f6 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -427,8 +427,8 @@ void s_vCaculateOFDMRParameter( BYTE byRate, CARD_PHY_TYPE ePHYType, - OUT PBYTE pbyTxRate, - OUT PBYTE pbyRsvTime + PBYTE pbyTxRate, + PBYTE pbyRsvTime ); @@ -500,8 +500,8 @@ void s_vCaculateOFDMRParameter ( BYTE byRate, CARD_PHY_TYPE ePHYType, - OUT PBYTE pbyTxRate, - OUT PBYTE pbyRsvTime + PBYTE pbyTxRate, + PBYTE pbyRsvTime ) { switch (byRate) { @@ -2130,8 +2130,8 @@ CARDvSetPowerConstraint ( void CARDvGetPowerCapability ( void *pDeviceHandler, - OUT PBYTE pbyMinPower, - OUT PBYTE pbyMaxPower + PBYTE pbyMinPower, + PBYTE pbyMaxPower ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -2166,7 +2166,7 @@ CARDvGetPowerCapability ( BYTE CARDbySetSupportChannels ( void *pDeviceHandler, - OUT PBYTE pbyIEs + PBYTE pbyIEs ) { PSDevice pDevice = (PSDevice) pDeviceHandler; @@ -2268,7 +2268,7 @@ CARDbyGetTransmitPower ( BOOL CARDbChannelGetList ( UINT uCountryCodeIdx, - OUT PBYTE pbyChannelTable + PBYTE pbyChannelTable ) { if (uCountryCodeIdx >= CCODE_MAX) { @@ -2309,8 +2309,8 @@ BOOL CARDbGetChannelMapInfo( void *pDeviceHandler, UINT uChannelIndex, - OUT PBYTE pbyChannelNumber, - OUT PBYTE pbyMap + PBYTE pbyChannelNumber, + PBYTE pbyMap ) { // PSDevice pDevice = (PSDevice) pDeviceHandler; diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h index f52a8e0d48cc..76313462cf76 100644 --- a/drivers/staging/vt6655/card.h +++ b/drivers/staging/vt6655/card.h @@ -195,14 +195,14 @@ CARDvSetPowerConstraint ( void CARDvGetPowerCapability ( void *pDeviceHandler, - OUT PBYTE pbyMinPower, - OUT PBYTE pbyMaxPower + PBYTE pbyMinPower, + PBYTE pbyMaxPower ); BYTE CARDbySetSupportChannels ( void *pDeviceHandler, - OUT PBYTE pbyIEs + PBYTE pbyIEs ); I8 @@ -213,7 +213,7 @@ CARDbyGetTransmitPower ( BOOL CARDbChannelGetList ( UINT uCountryCodeIdx, - OUT PBYTE pbyChannelTable + PBYTE pbyChannelTable ); void @@ -226,8 +226,8 @@ BOOL CARDbGetChannelMapInfo( void *pDeviceHandler, UINT uChannelIndex, - OUT PBYTE pbyChannelNumber, - OUT PBYTE pbyMap + PBYTE pbyChannelNumber, + PBYTE pbyMap ); void diff --git a/drivers/staging/vt6655/datarate.c b/drivers/staging/vt6655/datarate.c index 42b008a428d8..38b09a7fb53b 100644 --- a/drivers/staging/vt6655/datarate.c +++ b/drivers/staging/vt6655/datarate.c @@ -200,11 +200,11 @@ RATEvParseMaxRate ( PWLAN_IE_SUPP_RATES pItemRates, PWLAN_IE_SUPP_RATES pItemExtRates, BOOL bUpdateBasicRate, - OUT PWORD pwMaxBasicRate, - OUT PWORD pwMaxSuppRate, - OUT PWORD pwSuppRate, - OUT PBYTE pbyTopCCKRate, - OUT PBYTE pbyTopOFDMRate + PWORD pwMaxBasicRate, + PWORD pwMaxSuppRate, + PWORD pwSuppRate, + PBYTE pbyTopCCKRate, + PBYTE pbyTopOFDMRate ) { PSDevice pDevice = (PSDevice) pDeviceHandler; diff --git a/drivers/staging/vt6655/datarate.h b/drivers/staging/vt6655/datarate.h index abf7a3884fcd..b8ca792e9c6e 100644 --- a/drivers/staging/vt6655/datarate.h +++ b/drivers/staging/vt6655/datarate.h @@ -60,11 +60,11 @@ RATEvParseMaxRate( PWLAN_IE_SUPP_RATES pItemRates, PWLAN_IE_SUPP_RATES pItemExtRates, BOOL bUpdateBasicRate, - OUT PWORD pwMaxBasicRate, - OUT PWORD pwMaxSuppRate, - OUT PWORD pwSuppRate, - OUT PBYTE pbyTopCCKRate, - OUT PBYTE pbyTopOFDMRate + PWORD pwMaxBasicRate, + PWORD pwMaxSuppRate, + PWORD pwSuppRate, + PBYTE pbyTopCCKRate, + PBYTE pbyTopOFDMRate ); void diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index 693683924663..715be63f21a4 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -83,8 +83,8 @@ static void s_vGetDASA( PBYTE pbyRxBufferAddr, - OUT PUINT pcbHeaderSize, - OUT PSEthernetHeader psEthHeader + PUINT pcbHeaderSize, + PSEthernetHeader psEthHeader ); static @@ -95,7 +95,7 @@ s_vProcessRxMACHeader ( UINT cbPacketSize, BOOL bIsWEP, BOOL bExtIV, - OUT PUINT pcbHeadSize + PUINT pcbHeadSize ); static BOOL s_bAPModeRxCtl( @@ -121,11 +121,11 @@ static BOOL s_bHandleRxEncryption( PBYTE pbyFrame, UINT FrameSize, PBYTE pbyRsr, - OUT PBYTE pbyNewRsr, - OUT PSKeyItem *pKeyOut, + PBYTE pbyNewRsr, + PSKeyItem *pKeyOut, int * pbExtIV, - OUT PWORD pwRxTSC15_0, - OUT PDWORD pdwRxTSC47_16 + PWORD pwRxTSC15_0, + PDWORD pdwRxTSC47_16 ); static BOOL s_bHostWepRxEncryption( @@ -136,10 +136,10 @@ static BOOL s_bHostWepRxEncryption( PBYTE pbyRsr, BOOL bOnFly, PSKeyItem pKey, - OUT PBYTE pbyNewRsr, + PBYTE pbyNewRsr, int * pbExtIV, - OUT PWORD pwRxTSC15_0, - OUT PDWORD pdwRxTSC47_16 + PWORD pwRxTSC15_0, + PDWORD pdwRxTSC47_16 ); @@ -170,7 +170,7 @@ s_vProcessRxMACHeader ( UINT cbPacketSize, BOOL bIsWEP, BOOL bExtIV, - OUT PUINT pcbHeadSize + PUINT pcbHeadSize ) { PBYTE pbyRxBuffer; @@ -265,8 +265,8 @@ static void s_vGetDASA ( PBYTE pbyRxBufferAddr, - OUT PUINT pcbHeaderSize, - OUT PSEthernetHeader psEthHeader + PUINT pcbHeaderSize, + PSEthernetHeader psEthHeader ) { UINT cbHeaderSize = 0; @@ -1167,11 +1167,11 @@ static BOOL s_bHandleRxEncryption ( PBYTE pbyFrame, UINT FrameSize, PBYTE pbyRsr, - OUT PBYTE pbyNewRsr, - OUT PSKeyItem *pKeyOut, + PBYTE pbyNewRsr, + PSKeyItem *pKeyOut, int * pbExtIV, - OUT PWORD pwRxTSC15_0, - OUT PDWORD pdwRxTSC47_16 + PWORD pwRxTSC15_0, + PDWORD pdwRxTSC47_16 ) { UINT PayloadLen = FrameSize; @@ -1315,10 +1315,10 @@ static BOOL s_bHostWepRxEncryption ( PBYTE pbyRsr, BOOL bOnFly, PSKeyItem pKey, - OUT PBYTE pbyNewRsr, + PBYTE pbyNewRsr, int * pbExtIV, - OUT PWORD pwRxTSC15_0, - OUT PDWORD pdwRxTSC47_16 + PWORD pwRxTSC15_0, + PDWORD pdwRxTSC47_16 ) { UINT PayloadLen = FrameSize; diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c index c702d5096056..2065ee220687 100644 --- a/drivers/staging/vt6655/key.c +++ b/drivers/staging/vt6655/key.c @@ -135,7 +135,7 @@ BOOL KeybGetKey ( PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyIndex, - OUT PSKeyItem *pKey + PSKeyItem *pKey ) { int i; @@ -521,7 +521,7 @@ BOOL KeybGetTransmitKey ( PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyType, - OUT PSKeyItem *pKey + PSKeyItem *pKey ) { int i, ii; @@ -599,7 +599,7 @@ BOOL KeybGetTransmitKey ( */ BOOL KeybCheckPairewiseKey ( PSKeyManagement pTable, - OUT PSKeyItem *pKey + PSKeyItem *pKey ) { int i; diff --git a/drivers/staging/vt6655/key.h b/drivers/staging/vt6655/key.h index 88be5b4f3925..db1cbf3c8e7d 100644 --- a/drivers/staging/vt6655/key.h +++ b/drivers/staging/vt6655/key.h @@ -107,7 +107,7 @@ BOOL KeybGetKey( PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyIndex, - OUT PSKeyItem *pKey + PSKeyItem *pKey ); BOOL KeybSetKey( @@ -144,12 +144,12 @@ BOOL KeybGetTransmitKey( PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyType, - OUT PSKeyItem *pKey + PSKeyItem *pKey ); BOOL KeybCheckPairewiseKey( PSKeyManagement pTable, - OUT PSKeyItem *pKey + PSKeyItem *pKey ); BOOL KeybRemoveAllKey( diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 885741a774b5..6cd10bdf2800 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -123,7 +123,7 @@ s_vFillTxKey( PSKeyItem pTransmitKey, PBYTE pbyHdrBuf, WORD wPayloadLen, - OUT PBYTE pMICHDR + PBYTE pMICHDR ); @@ -184,7 +184,7 @@ s_cbFillTxBufHead ( BOOL bNeedEncrypt, PSKeyItem pTransmitKey, UINT uNodeIndex, - OUT PUINT puMACfragNum + PUINT puMACfragNum ); @@ -218,7 +218,7 @@ s_vFillTxKey ( PSKeyItem pTransmitKey, PBYTE pbyHdrBuf, WORD wPayloadLen, - OUT PBYTE pMICHDR + PBYTE pMICHDR ) { PDWORD pdwIV = (PDWORD) pbyIVHead; @@ -1329,7 +1329,7 @@ s_cbFillTxBufHead ( BOOL bNeedEncrypt, PSKeyItem pTransmitKey, UINT uNodeIndex, - OUT PUINT puMACfragNum + PUINT puMACfragNum ) { UINT cbMACHdLen; @@ -2106,8 +2106,8 @@ vGenerateFIFOHeader ( PBYTE pPacket, PSKeyItem pTransmitKey, UINT uNodeIndex, - OUT PUINT puMACfragNum, - OUT PUINT pcbHeaderSize + PUINT puMACfragNum, + PUINT pcbHeaderSize ) { UINT wTxBufSize; // FFinfo size diff --git a/drivers/staging/vt6655/rxtx.h b/drivers/staging/vt6655/rxtx.h index 75988c74a189..b008fc23adb9 100644 --- a/drivers/staging/vt6655/rxtx.h +++ b/drivers/staging/vt6655/rxtx.h @@ -46,8 +46,8 @@ void vGenerateMACHeader( PBYTE pbySkbData, UINT cbPacketSize, BOOL bDMA0Used, - OUT PUINT pcbHeadSize, - OUT PUINT pcbAppendPayload + PUINT pcbHeadSize, + PUINT pcbAppendPayload ); void vProcessRxMACHeader ( @@ -55,7 +55,7 @@ void vProcessRxMACHeader ( DWORD dwRxBufferAddr, UINT cbPacketSize, BOOL bIsWEP, - OUT PUINT pcbHeadSize + PUINT pcbHeadSize ); */ @@ -95,8 +95,8 @@ vGenerateFIFOHeader ( PBYTE pPacket, PSKeyItem pTransmitKey, UINT uNodeIndex, - OUT PUINT puMACfragNum, - OUT PUINT pcbHeaderSize + PUINT puMACfragNum, + PUINT pcbHeaderSize ); diff --git a/drivers/staging/vt6655/vntwifi.c b/drivers/staging/vt6655/vntwifi.c index bd3b2afe2cf1..b527a019188b 100644 --- a/drivers/staging/vt6655/vntwifi.c +++ b/drivers/staging/vt6655/vntwifi.c @@ -382,7 +382,7 @@ VNTWIFIbConfigPhyMode ( void VNTWIFIbGetConfigPhyMode ( void *pMgmtHandle, - OUT void *pePhyType + void *pePhyType ) { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; @@ -427,8 +427,8 @@ VNTWIFIbGetConfigPhyMode ( void VNTWIFIvQueryBSSList ( void *pMgmtHandle, - OUT PUINT puBSSCount, - OUT void **pvFirstBSS + PUINT puBSSCount, + void **pvFirstBSS ) { UINT ii = 0; @@ -458,7 +458,7 @@ void VNTWIFIvGetNextBSS ( void *pMgmtHandle, void *pvCurrentBSS, - OUT void **pvNextBSS + void **pvNextBSS ) { PKnownBSS pBSS = (PKnownBSS) pvCurrentBSS; @@ -533,10 +533,10 @@ void VNTWIFIvGetTxRate( void *pMgmtHandle, PBYTE pbyDestAddress, - OUT PWORD pwTxDataRate, - OUT PBYTE pbyACKRate, - OUT PBYTE pbyCCKBasicRate, - OUT PBYTE pbyOFDMBasicRate + PWORD pwTxDataRate, + PBYTE pbyACKRate, + PBYTE pbyCCKBasicRate, + PBYTE pbyOFDMBasicRate ) { PSMgmtObject pMgmt = (PSMgmtObject)pMgmtHandle; @@ -621,7 +621,7 @@ VNTWIFIbyGetKeyCypher( BOOL VNTWIFIbInit( void *pAdapterHandler, - OUT void **pMgmtHandler + void **pMgmtHandler ) { diff --git a/drivers/staging/vt6655/vntwifi.h b/drivers/staging/vt6655/vntwifi.h index ca1ee0e4446c..c91dfd79adca 100644 --- a/drivers/staging/vt6655/vntwifi.h +++ b/drivers/staging/vt6655/vntwifi.h @@ -204,14 +204,14 @@ VNTWIFIbConfigPhyMode( void VNTWIFIbGetConfigPhyMode( void *pMgmtHandle, - OUT void *pePhyType + void *pePhyType ); void VNTWIFIvQueryBSSList( void *pMgmtHandle, - OUT PUINT puBSSCount, - OUT void **pvFirstBSS + PUINT puBSSCount, + void **pvFirstBSS ); @@ -221,7 +221,7 @@ void VNTWIFIvGetNextBSS ( void *pMgmtHandle, void *pvCurrentBSS, - OUT void **pvNextBSS + void **pvNextBSS ); @@ -240,16 +240,16 @@ void VNTWIFIvGetTxRate( void *pMgmtHandle, PBYTE pbyDestAddress, - OUT PWORD pwTxDataRate, - OUT PBYTE pbyACKRate, - OUT PBYTE pbyCCKBasicRate, - OUT PBYTE pbyOFDMBasicRate + PWORD pwTxDataRate, + PBYTE pbyACKRate, + PBYTE pbyCCKBasicRate, + PBYTE pbyOFDMBasicRate ); /* BOOL VNTWIFIbInit( void *pAdapterHandler, - OUT void **pMgmtHandler + void **pMgmtHandler ); */ diff --git a/drivers/staging/vt6655/wmgr.c b/drivers/staging/vt6655/wmgr.c index 19a16cae175c..60c00fc1f025 100644 --- a/drivers/staging/vt6655/wmgr.c +++ b/drivers/staging/vt6655/wmgr.c @@ -312,7 +312,7 @@ s_vMgrSynchBSS ( PSDevice pDevice, UINT uBSSMode, PKnownBSS pCurr, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ); @@ -320,8 +320,8 @@ static BOOL s_bCipherMatch ( PKnownBSS pBSSNode, NDIS_802_11_ENCRYPTION_STATUS EncStatus, - OUT PBYTE pbyCCSPK, - OUT PBYTE pbyCCSGK + PBYTE pbyCCSPK, + PBYTE pbyCCSGK ); static void Encyption_Rebuild( @@ -464,7 +464,7 @@ void vMgrAssocBeginSta( void *hDeviceContext, PSMgmtObject pMgmt, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -540,7 +540,7 @@ void vMgrReAssocBeginSta( void *hDeviceContext, PSMgmtObject pMgmt, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -621,7 +621,7 @@ vMgrDisassocBeginSta( PSMgmtObject pMgmt, PBYTE abyDestAddress, WORD wReason, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1154,7 +1154,7 @@ void vMgrAuthenBeginSta( void *hDeviceContext, PSMgmtObject pMgmt, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -1214,7 +1214,7 @@ vMgrDeAuthenBeginSta( PSMgmtObject pMgmt, PBYTE abyDestAddress, WORD wReason, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -2387,7 +2387,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE) void vMgrCreateOwnIBSS( void *hDeviceContext, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -2654,7 +2654,7 @@ vMgrCreateOwnIBSS( void vMgrJoinBSSBegin( void *hDeviceContext, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ) { @@ -2925,7 +2925,7 @@ s_vMgrSynchBSS ( PSDevice pDevice, UINT uBSSMode, PKnownBSS pCurr, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ) { CARD_PHY_TYPE ePhyType = PHY_TYPE_11B; @@ -4885,8 +4885,8 @@ static BOOL s_bCipherMatch ( PKnownBSS pBSSNode, NDIS_802_11_ENCRYPTION_STATUS EncStatus, - OUT PBYTE pbyCCSPK, - OUT PBYTE pbyCCSGK + PBYTE pbyCCSPK, + PBYTE pbyCCSGK ) { BYTE byMulticastCipher = KEY_CTL_INVALID; diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index a86406e63bc8..9ae7e0d55bc4 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -418,14 +418,14 @@ void vMgrAssocBeginSta( void *hDeviceContext, PSMgmtObject pMgmt, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ); void vMgrReAssocBeginSta( void *hDeviceContext, PSMgmtObject pMgmt, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ); void @@ -434,26 +434,26 @@ vMgrDisassocBeginSta( PSMgmtObject pMgmt, PBYTE abyDestAddress, WORD wReason, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ); void vMgrAuthenBeginSta( void *hDeviceContext, PSMgmtObject pMgmt, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ); void vMgrCreateOwnIBSS( void *hDeviceContext, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ); void vMgrJoinBSSBegin( void *hDeviceContext, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ); void @@ -467,7 +467,7 @@ vMgrRxManagePacket( void vMgrScanBegin( void *hDeviceContext, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ); */ @@ -477,7 +477,7 @@ vMgrDeAuthenBeginSta( PSMgmtObject pMgmt, PBYTE abyDestAddress, WORD wReason, - OUT PCMD_STATUS pStatus + PCMD_STATUS pStatus ); BOOL diff --git a/drivers/staging/vt6655/wpa2.c b/drivers/staging/vt6655/wpa2.c index 102a18a835b5..ff2837938e96 100644 --- a/drivers/staging/vt6655/wpa2.c +++ b/drivers/staging/vt6655/wpa2.c @@ -264,7 +264,7 @@ WPA2vParseRSN ( UINT WPA2uSetIEs( void *pMgmtHandle, - OUT PWLAN_IE_RSN pRSNIEs + PWLAN_IE_RSN pRSNIEs ) { PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; diff --git a/drivers/staging/vt6655/wpa2.h b/drivers/staging/vt6655/wpa2.h index 1f2a02d2a57d..7200db37f430 100644 --- a/drivers/staging/vt6655/wpa2.h +++ b/drivers/staging/vt6655/wpa2.h @@ -72,7 +72,7 @@ WPA2vParseRSN ( UINT WPA2uSetIEs( void *pMgmtHandle, - OUT PWLAN_IE_RSN pRSNIEs + PWLAN_IE_RSN pRSNIEs ); #endif // __WPA2_H__ -- cgit v1.2.3 From 97a0638218fc504d645c45ff03256dc4520efa72 Mon Sep 17 00:00:00 2001 From: Nitin Gupta Date: Thu, 13 May 2010 14:24:21 +0530 Subject: Staging: ramzswap: Remove backing swap support Currently, each ramzswap device can be assigned a separate 'backing swap' file/partition. The ramzswap driver forwards swap I/O requests to this backing swap whenever an incompressible page is found. This feature adds nearly 700 lines of code and it also duplicates much of the swapon() functionality (for example, finding swap extents and so on). Removing this code makes the driver much simpler and should help its transition from staging to stable drivers area (drivers/block/). Similar functionality may be implemented if we can implement migrating pages across swap devices but the details have not yet been worked out. Support for _partitions_ as backing swap could be retained as it requires a few lines of code only. This part can be re-introduced later if above swap migration method turns out to be infeasible. More cleanups and code comments will be added soon. Signed-off-by: Nitin Gupta Acked-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ramzswap/ramzswap_drv.c | 645 +----------------------------- drivers/staging/ramzswap/ramzswap_drv.h | 51 +-- drivers/staging/ramzswap/ramzswap_ioctl.h | 14 +- 3 files changed, 25 insertions(+), 685 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ramzswap/ramzswap_drv.c b/drivers/staging/ramzswap/ramzswap_drv.c index ee5eb12b9285..167f8d17a808 100644 --- a/drivers/staging/ramzswap/ramzswap_drv.c +++ b/drivers/staging/ramzswap/ramzswap_drv.c @@ -36,13 +36,6 @@ static int ramzswap_major; static struct ramzswap *devices; -/* - * Pages that compress to larger than this size are - * forwarded to backing swap, if present or stored - * uncompressed in memory otherwise. - */ -static unsigned int max_zpage_size; - /* Module params (documentation at end) */ static unsigned int num_devices; @@ -79,52 +72,6 @@ static int page_zero_filled(void *ptr) return 1; } -/* - * memlimit cannot be greater than backing disk size. - */ -static void ramzswap_set_memlimit(struct ramzswap *rzs, size_t totalram_bytes) -{ - int memlimit_valid = 1; - - if (!rzs->memlimit) { - pr_info("Memory limit not set.\n"); - memlimit_valid = 0; - } - - if (rzs->memlimit > rzs->disksize) { - pr_info("Memory limit cannot be greater than " - "disksize: limit=%zu, disksize=%zu\n", - rzs->memlimit, rzs->disksize); - memlimit_valid = 0; - } - - if (!memlimit_valid) { - size_t mempart, disksize; - pr_info("Using default: smaller of (%u%% of RAM) and " - "(backing disk size).\n", - default_memlimit_perc_ram); - mempart = default_memlimit_perc_ram * (totalram_bytes / 100); - disksize = rzs->disksize; - rzs->memlimit = mempart > disksize ? disksize : mempart; - } - - if (rzs->memlimit > totalram_bytes / 2) { - pr_info( - "Its not advisable setting limit more than half of " - "size of memory since we expect a 2:1 compression ratio. " - "Limit represents amount of *compressed* data we can keep " - "in memory!\n" - "\tMemory Size: %zu kB\n" - "\tLimit you selected: %zu kB\n" - "Continuing anyway ...\n", - totalram_bytes >> 10, rzs->memlimit >> 10 - ); - } - - rzs->memlimit &= PAGE_MASK; - BUG_ON(!rzs->memlimit); -} - static void ramzswap_set_disksize(struct ramzswap *rzs, size_t totalram_bytes) { if (!rzs->disksize) { @@ -156,80 +103,22 @@ static void ramzswap_set_disksize(struct ramzswap *rzs, size_t totalram_bytes) /* * Swap header (1st page of swap device) contains information - * to indentify it as a swap partition. Prepare such a header - * for ramzswap device (ramzswap0) so that swapon can identify - * it as swap partition. In case backing swap device is provided, - * copy its swap header. + * about a swap file/partition. Prepare such a header for the + * given ramzswap device so that swapon can identify it as a + * swap partition. */ -static int setup_swap_header(struct ramzswap *rzs, union swap_header *s) +static void setup_swap_header(struct ramzswap *rzs, union swap_header *s) { - int ret = 0; - struct page *page; - struct address_space *mapping; - union swap_header *backing_swap_header; - - /* - * There is no backing swap device. Create a swap header - * that is acceptable by swapon. - */ - if (!rzs->backing_swap) { - s->info.version = 1; - s->info.last_page = (rzs->disksize >> PAGE_SHIFT) - 1; - s->info.nr_badpages = 0; - memcpy(s->magic.magic, "SWAPSPACE2", 10); - return 0; - } - - /* - * We have a backing swap device. Copy its swap header - * to ramzswap device header. If this header contains - * invalid information (backing device not a swap - * partition, etc.), swapon will fail for ramzswap - * which is correct behavior - we don't want to swap - * over filesystem partition! - */ - - /* Read the backing swap header (code from sys_swapon) */ - mapping = rzs->swap_file->f_mapping; - if (!mapping->a_ops->readpage) { - ret = -EINVAL; - goto out; - } - - page = read_mapping_page(mapping, 0, rzs->swap_file); - if (IS_ERR(page)) { - ret = PTR_ERR(page); - goto out; - } - - backing_swap_header = kmap(page); - memcpy(s, backing_swap_header, sizeof(*s)); - if (s->info.nr_badpages) { - pr_info("Cannot use backing swap with bad pages (%u)\n", - s->info.nr_badpages); - ret = -EINVAL; - } - /* - * ramzswap disksize equals number of usable pages in backing - * swap. Set last_page in swap header to match this disksize - * ('last_page' means 0-based index of last usable swap page). - */ + s->info.version = 1; s->info.last_page = (rzs->disksize >> PAGE_SHIFT) - 1; - kunmap(page); - -out: - return ret; + s->info.nr_badpages = 0; + memcpy(s->magic.magic, "SWAPSPACE2", 10); } static void ramzswap_ioctl_get_stats(struct ramzswap *rzs, struct ramzswap_ioctl_stats *s) { - strncpy(s->backing_swap_name, rzs->backing_swap_name, - MAX_SWAP_NAME_LEN - 1); - s->backing_swap_name[MAX_SWAP_NAME_LEN - 1] = '\0'; - s->disksize = rzs->disksize; - s->memlimit = rzs->memlimit; #if defined(CONFIG_RAMZSWAP_STATS) { @@ -265,333 +154,10 @@ static void ramzswap_ioctl_get_stats(struct ramzswap *rzs, s->orig_data_size = rs->pages_stored << PAGE_SHIFT; s->compr_data_size = rs->compr_size; s->mem_used_total = mem_used; - - s->bdev_num_reads = rzs_stat64_read(rzs, &rs->bdev_num_reads); - s->bdev_num_writes = rzs_stat64_read(rzs, &rs->bdev_num_writes); } #endif /* CONFIG_RAMZSWAP_STATS */ } -static int add_backing_swap_extent(struct ramzswap *rzs, - pgoff_t phy_pagenum, - pgoff_t num_pages) -{ - unsigned int idx; - struct list_head *head; - struct page *curr_page, *new_page; - unsigned int extents_per_page = PAGE_SIZE / - sizeof(struct ramzswap_backing_extent); - - idx = rzs->num_extents % extents_per_page; - if (!idx) { - new_page = alloc_page(__GFP_ZERO); - if (!new_page) - return -ENOMEM; - - if (rzs->num_extents) { - curr_page = virt_to_page(rzs->curr_extent); - head = &curr_page->lru; - } else { - head = &rzs->backing_swap_extent_list; - } - - list_add(&new_page->lru, head); - rzs->curr_extent = page_address(new_page); - } - - rzs->curr_extent->phy_pagenum = phy_pagenum; - rzs->curr_extent->num_pages = num_pages; - - pr_debug("add_extent: idx=%u, phy_pgnum=%lu, num_pgs=%lu, " - "pg_last=%lu, curr_ext=%p\n", idx, phy_pagenum, num_pages, - phy_pagenum + num_pages - 1, rzs->curr_extent); - - if (idx != extents_per_page - 1) - rzs->curr_extent++; - - return 0; -} - -static int setup_backing_swap_extents(struct ramzswap *rzs, - struct inode *inode, unsigned long *num_pages) -{ - int ret = 0; - unsigned blkbits; - unsigned blocks_per_page; - pgoff_t contig_pages = 0, total_pages = 0; - pgoff_t pagenum = 0, prev_pagenum = 0; - sector_t probe_block = 0; - sector_t last_block; - - blkbits = inode->i_blkbits; - blocks_per_page = PAGE_SIZE >> blkbits; - - last_block = i_size_read(inode) >> blkbits; - while (probe_block + blocks_per_page <= last_block) { - unsigned block_in_page; - sector_t first_block; - - first_block = bmap(inode, probe_block); - if (first_block == 0) - goto bad_bmap; - - /* It must be PAGE_SIZE aligned on-disk */ - if (first_block & (blocks_per_page - 1)) { - probe_block++; - goto probe_next; - } - - /* All blocks within this page must be contiguous on disk */ - for (block_in_page = 1; block_in_page < blocks_per_page; - block_in_page++) { - sector_t block; - - block = bmap(inode, probe_block + block_in_page); - if (block == 0) - goto bad_bmap; - if (block != first_block + block_in_page) { - /* Discontiguity */ - probe_block++; - goto probe_next; - } - } - - /* - * We found a PAGE_SIZE length, PAGE_SIZE aligned - * run of blocks. - */ - pagenum = first_block >> (PAGE_SHIFT - blkbits); - - if (total_pages && (pagenum != prev_pagenum + 1)) { - ret = add_backing_swap_extent(rzs, prev_pagenum - - (contig_pages - 1), contig_pages); - if (ret < 0) - goto out; - rzs->num_extents++; - contig_pages = 0; - } - total_pages++; - contig_pages++; - prev_pagenum = pagenum; - probe_block += blocks_per_page; - -probe_next: - continue; - } - - if (contig_pages) { - pr_debug("adding last extent: pagenum=%lu, " - "contig_pages=%lu\n", pagenum, contig_pages); - ret = add_backing_swap_extent(rzs, - prev_pagenum - (contig_pages - 1), contig_pages); - if (ret < 0) - goto out; - rzs->num_extents++; - } - if (!rzs->num_extents) { - pr_err("No swap extents found!\n"); - ret = -EINVAL; - } - - if (!ret) { - *num_pages = total_pages; - pr_info("Found %lu extents containing %luk\n", - rzs->num_extents, *num_pages << (PAGE_SHIFT - 10)); - } - goto out; - -bad_bmap: - pr_err("Backing swapfile has holes\n"); - ret = -EINVAL; -out: - while (ret && !list_empty(&rzs->backing_swap_extent_list)) { - struct page *page; - struct list_head *entry = rzs->backing_swap_extent_list.next; - page = list_entry(entry, struct page, lru); - list_del(entry); - __free_page(page); - } - return ret; -} - -static void map_backing_swap_extents(struct ramzswap *rzs) -{ - struct ramzswap_backing_extent *se; - struct page *table_page, *se_page; - unsigned long num_pages, num_table_pages, entry; - unsigned long se_idx, span; - unsigned entries_per_page = PAGE_SIZE / sizeof(*rzs->table); - unsigned extents_per_page = PAGE_SIZE / sizeof(*se); - - /* True for block device */ - if (!rzs->num_extents) - return; - - se_page = list_entry(rzs->backing_swap_extent_list.next, - struct page, lru); - se = page_address(se_page); - span = se->num_pages; - num_pages = rzs->disksize >> PAGE_SHIFT; - num_table_pages = DIV_ROUND_UP(num_pages * sizeof(*rzs->table), - PAGE_SIZE); - - entry = 0; - se_idx = 0; - while (num_table_pages--) { - table_page = vmalloc_to_page(&rzs->table[entry]); - while (span <= entry) { - se_idx++; - if (se_idx == rzs->num_extents) - BUG(); - - if (!(se_idx % extents_per_page)) { - se_page = list_entry(se_page->lru.next, - struct page, lru); - se = page_address(se_page); - } else - se++; - - span += se->num_pages; - } - table_page->mapping = (struct address_space *)se; - table_page->private = se->num_pages - (span - entry); - pr_debug("map_table: entry=%lu, span=%lu, map=%p, priv=%lu\n", - entry, span, table_page->mapping, table_page->private); - entry += entries_per_page; - } -} - -/* - * Check if value of backing_swap module param is sane. - * Claim this device and set ramzswap size equal to - * size of this block device. - */ -static int setup_backing_swap(struct ramzswap *rzs) -{ - int ret = 0; - size_t disksize; - unsigned long num_pages = 0; - struct inode *inode; - struct file *swap_file; - struct address_space *mapping; - struct block_device *bdev = NULL; - - if (!rzs->backing_swap_name[0]) { - pr_debug("backing_swap param not given\n"); - goto out; - } - - pr_info("Using backing swap device: %s\n", rzs->backing_swap_name); - - swap_file = filp_open(rzs->backing_swap_name, - O_RDWR | O_LARGEFILE, 0); - if (IS_ERR(swap_file)) { - pr_err("Error opening backing device: %s\n", - rzs->backing_swap_name); - ret = -EINVAL; - goto out; - } - - mapping = swap_file->f_mapping; - inode = mapping->host; - - if (S_ISBLK(inode->i_mode)) { - bdev = I_BDEV(inode); - ret = bd_claim(bdev, setup_backing_swap); - if (ret < 0) { - bdev = NULL; - goto bad_param; - } - disksize = i_size_read(inode); - /* - * Can happen if user gives an extended partition as - * backing swap or simply a bad disk. - */ - if (!disksize) { - pr_err("Error reading backing swap size.\n"); - goto bad_param; - } - } else if (S_ISREG(inode->i_mode)) { - bdev = inode->i_sb->s_bdev; - if (IS_SWAPFILE(inode)) { - ret = -EBUSY; - goto bad_param; - } - ret = setup_backing_swap_extents(rzs, inode, &num_pages); - if (ret < 0) - goto bad_param; - disksize = num_pages << PAGE_SHIFT; - } else { - goto bad_param; - } - - rzs->swap_file = swap_file; - rzs->backing_swap = bdev; - rzs->disksize = disksize; - - return 0; - -bad_param: - if (bdev) - bd_release(bdev); - filp_close(swap_file, NULL); - -out: - rzs->backing_swap = NULL; - return ret; -} - -/* - * Map logical page number 'pagenum' to physical page number - * on backing swap device. For block device, this is a nop. - */ -static u32 map_backing_swap_page(struct ramzswap *rzs, u32 pagenum) -{ - u32 skip_pages, entries_per_page; - size_t delta, se_offset, skipped; - struct page *table_page, *se_page; - struct ramzswap_backing_extent *se; - - if (!rzs->num_extents) - return pagenum; - - entries_per_page = PAGE_SIZE / sizeof(*rzs->table); - - table_page = vmalloc_to_page(&rzs->table[pagenum]); - se = (struct ramzswap_backing_extent *)table_page->mapping; - se_page = virt_to_page(se); - - skip_pages = pagenum - (pagenum / entries_per_page * entries_per_page); - se_offset = table_page->private + skip_pages; - - if (se_offset < se->num_pages) - return se->phy_pagenum + se_offset; - - skipped = se->num_pages - table_page->private; - do { - struct ramzswap_backing_extent *se_base; - u32 se_entries_per_page = PAGE_SIZE / sizeof(*se); - - /* Get next swap extent */ - se_base = (struct ramzswap_backing_extent *) - page_address(se_page); - if (se - se_base == se_entries_per_page - 1) { - se_page = list_entry(se_page->lru.next, - struct page, lru); - se = page_address(se_page); - } else { - se++; - } - - skipped += se->num_pages; - } while (skipped < skip_pages); - - delta = skipped - skip_pages; - se_offset = se->num_pages - delta; - - return se->phy_pagenum + se_offset; -} - static void ramzswap_free_page(struct ramzswap *rzs, size_t index) { u32 clen; @@ -678,38 +244,12 @@ static int handle_uncompressed_page(struct ramzswap *rzs, struct bio *bio) /* * Called when request page is not present in ramzswap. - * Its either in backing swap device (if present) or - * this is an attempt to read before any previous write + * This is an attempt to read before any previous write * to this location - this happens due to readahead when * swap device is read from user-space (e.g. during swapon) */ static int handle_ramzswap_fault(struct ramzswap *rzs, struct bio *bio) { - /* - * Always forward such requests to backing swap - * device (if present) - */ - if (rzs->backing_swap) { - u32 pagenum; - rzs_stat64_dec(rzs, &rzs->stats.num_reads); - rzs_stat64_inc(rzs, &rzs->stats.bdev_num_reads); - bio->bi_bdev = rzs->backing_swap; - - /* - * In case backing swap is a file, find the right offset within - * the file corresponding to logical position 'index'. For block - * device, this is a nop. - */ - pagenum = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT; - bio->bi_sector = map_backing_swap_page(rzs, pagenum) - << SECTORS_PER_PAGE_SHIFT; - return 1; - } - - /* - * Its unlikely event in case backing dev is - * not present - */ pr_debug("Read before write on swap device: " "sector=%lu, size=%u, offset=%u\n", (ulong)(bio->bi_sector), bio->bi_size, @@ -781,7 +321,7 @@ out: static int ramzswap_write(struct ramzswap *rzs, struct bio *bio) { - int ret, fwd_write_request = 0; + int ret; u32 offset, index; size_t clen; struct zobj_header *zheader; @@ -817,14 +357,6 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio) return 0; } - if (rzs->backing_swap && - (rzs->stats.compr_size > rzs->memlimit - PAGE_SIZE)) { - kunmap_atomic(user_mem, KM_USER0); - mutex_unlock(&rzs->lock); - fwd_write_request = 1; - goto out; - } - ret = lzo1x_1_compress(user_mem, PAGE_SIZE, src, &clen, rzs->compress_workmem); @@ -838,18 +370,11 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio) } /* - * Page is incompressible. Forward it to backing swap - * if present. Otherwise, store it as-is (uncompressed) + * Page is incompressible. Store it as-is (uncompressed) * since we do not want to return too many swap write * errors which has side effect of hanging the system. */ if (unlikely(clen > max_zpage_size)) { - if (rzs->backing_swap) { - mutex_unlock(&rzs->lock); - fwd_write_request = 1; - goto out; - } - clen = PAGE_SIZE; page_store = alloc_page(GFP_NOIO | __GFP_HIGHMEM); if (unlikely(!page_store)) { @@ -875,8 +400,6 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio) pr_info("Error allocating memory for compressed " "page: %u, size=%zu\n", index, clen); rzs_stat64_inc(rzs, &rzs->stats.failed_writes); - if (rzs->backing_swap) - fwd_write_request = 1; goto out; } @@ -914,31 +437,6 @@ memstore: return 0; out: - if (fwd_write_request) { - rzs_stat64_inc(rzs, &rzs->stats.bdev_num_writes); - bio->bi_bdev = rzs->backing_swap; -#if 0 - /* - * TODO: We currently have linear mapping of ramzswap and - * backing swap sectors. This is not desired since we want - * to optimize writes to backing swap to minimize disk seeks - * or have effective wear leveling (for SSDs). Also, a - * non-linear mapping is required to implement compressed - * on-disk swapping. - */ - bio->bi_sector = get_backing_swap_page() - << SECTORS_PER_PAGE_SHIFT; -#endif - /* - * In case backing swap is a file, find the right offset within - * the file corresponding to logical position 'index'. For block - * device, this is a nop. - */ - bio->bi_sector = map_backing_swap_page(rzs, index) - << SECTORS_PER_PAGE_SHIFT; - return 1; - } - bio_io_error(bio); return 0; } @@ -996,19 +494,11 @@ static int ramzswap_make_request(struct request_queue *queue, struct bio *bio) static void reset_device(struct ramzswap *rzs) { - int is_backing_blkdev = 0; - size_t index, num_pages; - unsigned entries_per_page; - unsigned long num_table_pages, entry = 0; + size_t index; /* Do not accept any new I/O request */ rzs->init_done = 0; - if (rzs->backing_swap && !rzs->num_extents) - is_backing_blkdev = 1; - - num_pages = rzs->disksize >> PAGE_SHIFT; - /* Free various per-device buffers */ kfree(rzs->compress_workmem); free_pages((unsigned long)rzs->compress_buffer, 1); @@ -1017,7 +507,7 @@ static void reset_device(struct ramzswap *rzs) rzs->compress_buffer = NULL; /* Free all pages that are still in this ramzswap device */ - for (index = 0; index < num_pages; index++) { + for (index = 0; index < rzs->disksize >> PAGE_SHIFT; index++) { struct page *page; u16 offset; @@ -1033,51 +523,16 @@ static void reset_device(struct ramzswap *rzs) xv_free(rzs->mem_pool, page, offset); } - entries_per_page = PAGE_SIZE / sizeof(*rzs->table); - num_table_pages = DIV_ROUND_UP(num_pages * sizeof(*rzs->table), - PAGE_SIZE); - /* - * Set page->mapping to NULL for every table page. - * Otherwise, we will hit bad_page() during free. - */ - while (rzs->num_extents && num_table_pages--) { - struct page *page; - page = vmalloc_to_page(&rzs->table[entry]); - page->mapping = NULL; - entry += entries_per_page; - } vfree(rzs->table); rzs->table = NULL; xv_destroy_pool(rzs->mem_pool); rzs->mem_pool = NULL; - /* Free all swap extent pages */ - while (!list_empty(&rzs->backing_swap_extent_list)) { - struct page *page; - struct list_head *entry; - entry = rzs->backing_swap_extent_list.next; - page = list_entry(entry, struct page, lru); - list_del(entry); - __free_page(page); - } - INIT_LIST_HEAD(&rzs->backing_swap_extent_list); - rzs->num_extents = 0; - - /* Close backing swap device, if present */ - if (rzs->backing_swap) { - if (is_backing_blkdev) - bd_release(rzs->backing_swap); - filp_close(rzs->swap_file, NULL); - rzs->backing_swap = NULL; - memset(rzs->backing_swap_name, 0, MAX_SWAP_NAME_LEN); - } - /* Reset stats */ memset(&rzs->stats, 0, sizeof(rzs->stats)); rzs->disksize = 0; - rzs->memlimit = 0; } static int ramzswap_ioctl_init_device(struct ramzswap *rzs) @@ -1092,14 +547,7 @@ static int ramzswap_ioctl_init_device(struct ramzswap *rzs) return -EBUSY; } - ret = setup_backing_swap(rzs); - if (ret) - goto fail; - - if (rzs->backing_swap) - ramzswap_set_memlimit(rzs, totalram_pages << PAGE_SHIFT); - else - ramzswap_set_disksize(rzs, totalram_pages << PAGE_SHIFT); + ramzswap_set_disksize(rzs, totalram_pages << PAGE_SHIFT); rzs->compress_workmem = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL); if (!rzs->compress_workmem) { @@ -1126,8 +574,6 @@ static int ramzswap_ioctl_init_device(struct ramzswap *rzs) } memset(rzs->table, 0, num_pages * sizeof(*rzs->table)); - map_backing_swap_extents(rzs); - page = alloc_page(__GFP_ZERO); if (!page) { pr_err("Error allocating swap header page\n"); @@ -1138,23 +584,13 @@ static int ramzswap_ioctl_init_device(struct ramzswap *rzs) rzs_set_flag(rzs, 0, RZS_UNCOMPRESSED); swap_header = kmap(page); - ret = setup_swap_header(rzs, swap_header); + setup_swap_header(rzs, swap_header); kunmap(page); - if (ret) { - pr_err("Error setting swap header\n"); - goto fail; - } set_capacity(rzs->disk, rzs->disksize >> SECTOR_SHIFT); - /* - * We have ident mapping of sectors for ramzswap and - * and the backing swap device. So, this queue flag - * should be according to backing dev. - */ - if (!rzs->backing_swap || - blk_queue_nonrot(rzs->backing_swap->bd_disk->queue)) - queue_flag_set_unlocked(QUEUE_FLAG_NONROT, rzs->disk->queue); + /* ramzswap devices sort of resembles non-rotational disks */ + queue_flag_set_unlocked(QUEUE_FLAG_NONROT, rzs->disk->queue); rzs->mem_pool = xv_create_pool(); if (!rzs->mem_pool) { @@ -1163,17 +599,6 @@ static int ramzswap_ioctl_init_device(struct ramzswap *rzs) goto fail; } - /* - * Pages that compress to size greater than this are forwarded - * to physical swap disk (if backing dev is provided) - * TODO: make this configurable - */ - if (rzs->backing_swap) - max_zpage_size = max_zpage_size_bdev; - else - max_zpage_size = max_zpage_size_nobdev; - pr_debug("Max compressed page size: %u bytes\n", max_zpage_size); - rzs->init_done = 1; pr_debug("Initialization done!\n"); @@ -1198,7 +623,7 @@ static int ramzswap_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { int ret = 0; - size_t disksize_kb, memlimit_kb; + size_t disksize_kb; struct ramzswap *rzs = bdev->bd_disk->private_data; @@ -1217,36 +642,6 @@ static int ramzswap_ioctl(struct block_device *bdev, fmode_t mode, pr_info("Disk size set to %zu kB\n", disksize_kb); break; - case RZSIO_SET_MEMLIMIT_KB: - if (rzs->init_done) { - /* TODO: allow changing memlimit */ - ret = -EBUSY; - goto out; - } - if (copy_from_user(&memlimit_kb, (void *)arg, - _IOC_SIZE(cmd))) { - ret = -EFAULT; - goto out; - } - rzs->memlimit = memlimit_kb << 10; - pr_info("Memory limit set to %zu kB\n", memlimit_kb); - break; - - case RZSIO_SET_BACKING_SWAP: - if (rzs->init_done) { - ret = -EBUSY; - goto out; - } - - if (copy_from_user(&rzs->backing_swap_name, (void *)arg, - _IOC_SIZE(cmd))) { - ret = -EFAULT; - goto out; - } - rzs->backing_swap_name[MAX_SWAP_NAME_LEN - 1] = '\0'; - pr_info("Backing swap set to %s\n", rzs->backing_swap_name); - break; - case RZSIO_GET_STATS: { struct ramzswap_ioctl_stats *stats; @@ -1306,7 +701,6 @@ static int create_device(struct ramzswap *rzs, int device_id) mutex_init(&rzs->lock); spin_lock_init(&rzs->stat64_lock); - INIT_LIST_HEAD(&rzs->backing_swap_extent_list); rzs->queue = blk_alloc_queue(GFP_KERNEL); if (!rzs->queue) { @@ -1336,10 +730,7 @@ static int create_device(struct ramzswap *rzs, int device_id) rzs->disk->private_data = rzs; snprintf(rzs->disk->disk_name, 16, "ramzswap%d", device_id); - /* - * Actual capacity set using RZSIO_SET_DISKSIZE_KB ioctl - * or set equal to backing swap device (if provided) - */ + /* Actual capacity set using RZSIO_SET_DISKSIZE_KB ioctl */ set_capacity(rzs->disk, 0); blk_queue_physical_block_size(rzs->disk->queue, PAGE_SIZE); diff --git a/drivers/staging/ramzswap/ramzswap_drv.h b/drivers/staging/ramzswap/ramzswap_drv.h index c7e0e767c223..63c30420df21 100644 --- a/drivers/staging/ramzswap/ramzswap_drv.h +++ b/drivers/staging/ramzswap/ramzswap_drv.h @@ -31,8 +31,7 @@ static const unsigned max_num_devices = 32; * Stored at beginning of each compressed object. * * It stores back-reference to table entry which points to this - * object. This is required to support memory defragmentation or - * migrating compressed pages to backing swap disk. + * object. This is required to support memory defragmentation. */ struct zobj_header { #if 0 @@ -44,27 +43,17 @@ struct zobj_header { /* Default ramzswap disk size: 25% of total RAM */ static const unsigned default_disksize_perc_ram = 25; -static const unsigned default_memlimit_perc_ram = 15; /* - * Max compressed page size when backing device is provided. - * Pages that compress to size greater than this are sent to - * physical swap disk. - */ -static const unsigned max_zpage_size_bdev = PAGE_SIZE / 2; - -/* - * Max compressed page size when there is no backing dev. * Pages that compress to size greater than this are stored * uncompressed in memory. */ -static const unsigned max_zpage_size_nobdev = PAGE_SIZE / 4 * 3; +static const unsigned max_zpage_size = PAGE_SIZE / 4 * 3; /* - * NOTE: max_zpage_size_{bdev,nobdev} sizes must be - * less than or equal to: + * NOTE: max_zpage_size must be less than or equal to: * XV_MAX_ALLOC_SIZE - sizeof(struct zobj_header) - * since otherwise xv_malloc would always return failure. + * otherwise, xv_malloc() would always return failure. */ /*-- End of configurable params */ @@ -98,15 +87,6 @@ struct table { u8 flags; } __attribute__((aligned(4))); -/* - * Swap extent information in case backing swap is a regular - * file. These extent entries must fit exactly in a page. - */ -struct ramzswap_backing_extent { - pgoff_t phy_pagenum; - pgoff_t num_pages; -} __attribute__((aligned(4))); - struct ramzswap_stats { /* basic stats */ size_t compr_size; /* compressed size of pages stored - @@ -123,8 +103,6 @@ struct ramzswap_stats { u32 pages_stored; /* no. of pages currently stored */ u32 good_compress; /* % of pages with compression ratio<=50% */ u32 pages_expand; /* % of incompressible pages */ - u64 bdev_num_reads; /* no. of reads on backing dev */ - u64 bdev_num_writes; /* no. of writes on backing dev */ #endif }; @@ -138,11 +116,6 @@ struct ramzswap { struct request_queue *queue; struct gendisk *disk; int init_done; - /* - * This is limit on compressed data size (stats.compr_size) - * Its applicable only when backing swap device is present. - */ - size_t memlimit; /* bytes */ /* * This is limit on amount of *uncompressed* worth of data * we can hold. When backing swap device is provided, it is @@ -151,14 +124,6 @@ struct ramzswap { size_t disksize; /* bytes */ struct ramzswap_stats stats; - - /* backing swap device info */ - struct ramzswap_backing_extent *curr_extent; - struct list_head backing_swap_extent_list; - unsigned long num_extents; - char backing_swap_name[MAX_SWAP_NAME_LEN]; - struct block_device *backing_swap; - struct file *swap_file; }; /*-- */ @@ -182,13 +147,6 @@ static void rzs_stat64_inc(struct ramzswap *rzs, u64 *v) spin_unlock(&rzs->stat64_lock); } -static void rzs_stat64_dec(struct ramzswap *rzs, u64 *v) -{ - spin_lock(&rzs->stat64_lock); - *v = *v - 1; - spin_unlock(&rzs->stat64_lock); -} - static u64 rzs_stat64_read(struct ramzswap *rzs, u64 *v) { u64 val; @@ -203,7 +161,6 @@ static u64 rzs_stat64_read(struct ramzswap *rzs, u64 *v) #define rzs_stat_inc(v) #define rzs_stat_dec(v) #define rzs_stat64_inc(r, v) -#define rzs_stat64_dec(r, v) #define rzs_stat64_read(r, v) #endif /* CONFIG_RAMZSWAP_STATS */ diff --git a/drivers/staging/ramzswap/ramzswap_ioctl.h b/drivers/staging/ramzswap/ramzswap_ioctl.h index d26076d41bde..db94bcb42967 100644 --- a/drivers/staging/ramzswap/ramzswap_ioctl.h +++ b/drivers/staging/ramzswap/ramzswap_ioctl.h @@ -15,11 +15,7 @@ #ifndef _RAMZSWAP_IOCTL_H_ #define _RAMZSWAP_IOCTL_H_ -#define MAX_SWAP_NAME_LEN 128 - struct ramzswap_ioctl_stats { - char backing_swap_name[MAX_SWAP_NAME_LEN]; - u64 memlimit; /* only applicable if backing swap present */ u64 disksize; /* user specified or equal to backing swap * size (if present) */ u64 num_reads; /* failed + successful */ @@ -36,15 +32,11 @@ struct ramzswap_ioctl_stats { u64 orig_data_size; u64 compr_data_size; u64 mem_used_total; - u64 bdev_num_reads; /* no. of reads on backing dev */ - u64 bdev_num_writes; /* no. of writes on backing dev */ } __attribute__ ((packed, aligned(4))); #define RZSIO_SET_DISKSIZE_KB _IOW('z', 0, size_t) -#define RZSIO_SET_MEMLIMIT_KB _IOW('z', 1, size_t) -#define RZSIO_SET_BACKING_SWAP _IOW('z', 2, unsigned char[MAX_SWAP_NAME_LEN]) -#define RZSIO_GET_STATS _IOR('z', 3, struct ramzswap_ioctl_stats) -#define RZSIO_INIT _IO('z', 4) -#define RZSIO_RESET _IO('z', 5) +#define RZSIO_GET_STATS _IOR('z', 1, struct ramzswap_ioctl_stats) +#define RZSIO_INIT _IO('z', 2) +#define RZSIO_RESET _IO('z', 3) #endif -- cgit v1.2.3 From 93822ad193f1b1d92422dc3d539456acbe1a85ef Mon Sep 17 00:00:00 2001 From: Henk de Groot Date: Thu, 13 May 2010 16:27:33 +0200 Subject: Staging: wlags49_hs2: Fix wlags49_hs2 driver after build fixes broke it Fixes the driver after merge into the 2.6.34 kernel. Driver should be functional again (a fix to make it compile broke the driver). Patch against 2.6.34 RC7 with patch-v2.6.34-rc7-next-20100513 already applied. Removed conditional code based on kernel version, this is pointless now the driver is part of the kernel. Also removed obsolte code left over from previous patches. Includes also small fixes to compile clean again. Signed-off-by: Henk de Groot Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/dhf.c | 14 -------------- drivers/staging/wlags49_h2/wl_cs.c | 30 ++++++++++++------------------ drivers/staging/wlags49_h2/wl_cs.h | 4 ---- drivers/staging/wlags49_h2/wl_internal.h | 8 ++------ drivers/staging/wlags49_h2/wl_netdev.c | 27 --------------------------- drivers/staging/wlags49_h2/wl_wext.c | 7 ------- 6 files changed, 14 insertions(+), 76 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/wlags49_h2/dhf.c b/drivers/staging/wlags49_h2/dhf.c index 80a4707885d8..bb80b547cc19 100644 --- a/drivers/staging/wlags49_h2/dhf.c +++ b/drivers/staging/wlags49_h2/dhf.c @@ -109,20 +109,6 @@ /* 12345678901234 */ char signature[14] = "FUPU7D37dhfwci"; -/* The binary download function "relocates" the image using constructions like: - fw->identity = (CFG_IDENTITY_STRCT FAR *)((char FAR *)fw->identity + (hcf_32)fw ); - under some of the memory models under MSVC 1.52 these constructions degrade to 16-bits pointer arithmetic. - fw->identity is limited, such that adding it to fw, does not need to carry over from offset to segment. - However the segment is not set at all. - As a workaround the PSEUDO_CHARP macro is introduced which is a char pointer except for MSVC 1.52, in - which case we know that a 32-bit quantity is adequate as a pointer. - Note that other platforms may experience comparable problems when using the binary download feature. */ -#if defined(_MSC_VER) && _MSC_VER == 800 /* Visual C++ 1.5 */ -#define PSEUDO_CHARP hcf_32 -#else -#define PSEUDO_CHARP (hcf_8 *) -#endif - /*----------------------------------------------------------------------------- * * LTV-records retrieved from the NIC to: diff --git a/drivers/staging/wlags49_h2/wl_cs.c b/drivers/staging/wlags49_h2/wl_cs.c index 7c33eade6b8a..568993f3ffe3 100644 --- a/drivers/staging/wlags49_h2/wl_cs.c +++ b/drivers/staging/wlags49_h2/wl_cs.c @@ -104,13 +104,6 @@ #include -/******************************************************************************* - * macro definitions - ******************************************************************************/ -#define CS_CHECK(fn, ret) do { \ - last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \ - } while (0) - /******************************************************************************* * global definitions ******************************************************************************/ @@ -305,7 +298,7 @@ void wl_adapter_insert( struct pcmcia_device *link ) { struct net_device *dev; int i; - int last_fn, last_ret; + int ret; /*------------------------------------------------------------------------*/ DBG_FUNC( "wl_adapter_insert" ); @@ -317,10 +310,17 @@ void wl_adapter_insert( struct pcmcia_device *link ) /* Do we need to allocate an interrupt? */ link->conf.Attributes |= CONF_ENABLE_IRQ; -// CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); -// CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); -// CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + ret = pcmcia_request_io(link, &link->io); + if (ret != 0) + goto failed; + + ret = pcmcia_request_irq(link, (void *) wl_isr); + if (ret != 0) + goto failed; + ret = pcmcia_request_configuration(link, &link->conf); + if (ret != 0) + goto failed; dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; @@ -330,8 +330,7 @@ void wl_adapter_insert( struct pcmcia_device *link ) printk("%s: register_netdev() failed\n", MODULE_NAME); goto failed; } - link->dev_node = &( wl_priv(dev) )->node; - strcpy(( wl_priv(dev) )->node.dev_name, dev->name); + register_wlags_sysfs(dev); printk(KERN_INFO "%s: Wireless, io_addr %#03lx, irq %d, ""mac_address ", @@ -343,11 +342,6 @@ void wl_adapter_insert( struct pcmcia_device *link ) DBG_LEAVE( DbgInfo ); return; - -cs_failed: -// cs_error( link, last_fn, last_ret ); - - failed: wl_adapter_release( link ); diff --git a/drivers/staging/wlags49_h2/wl_cs.h b/drivers/staging/wlags49_h2/wl_cs.h index 2a0e67450fbe..a9b8828a1a27 100644 --- a/drivers/staging/wlags49_h2/wl_cs.h +++ b/drivers/staging/wlags49_h2/wl_cs.h @@ -84,10 +84,6 @@ int wl_adapter_close(struct net_device *dev); int wl_adapter_is_open(struct net_device *dev); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) -void cs_error(client_handle_t handle, int func, int ret); -#endif - const char *DbgEvent( int mask ); diff --git a/drivers/staging/wlags49_h2/wl_internal.h b/drivers/staging/wlags49_h2/wl_internal.h index 466fb6215acd..d9a0ad039c19 100644 --- a/drivers/staging/wlags49_h2/wl_internal.h +++ b/drivers/staging/wlags49_h2/wl_internal.h @@ -69,9 +69,6 @@ ******************************************************************************/ #include #ifdef BUS_PCMCIA -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) -#include -#endif #include #include #include @@ -866,7 +863,6 @@ struct wl_private { #ifdef BUS_PCMCIA - dev_node_t node; struct pcmcia_device *link; #endif // BUS_PCMCIA @@ -1013,13 +1009,13 @@ extern inline struct wl_private *wl_priv(struct net_device *dev) * SPARC, due to its weird semantics for save/restore flags. extern * inline should prevent the kernel from linking or module from * loading if they are not inlined. */ -extern inline void wl_lock(struct wl_private *lp, +static inline void wl_lock(struct wl_private *lp, unsigned long *flags) { spin_lock_irqsave(&lp->slock, *flags); } -extern inline void wl_unlock(struct wl_private *lp, +static inline void wl_unlock(struct wl_private *lp, unsigned long *flags) { spin_unlock_irqrestore(&lp->slock, *flags); diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c index 1cfaee3a2350..91fd3092b47d 100644 --- a/drivers/staging/wlags49_h2/wl_netdev.c +++ b/drivers/staging/wlags49_h2/wl_netdev.c @@ -463,15 +463,10 @@ static void wl_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) // strncpy(info.fw_version, priv->fw_name, // sizeof(info.fw_version) - 1); -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20)) if (dev->dev.parent) { dev_set_name(dev->dev.parent, "%s", info->bus_info); //strncpy(info->bus_info, dev->dev.parent->bus_id, // sizeof(info->bus_info) - 1); -#else - if (dev->class_dev.parent) { - sizeof(info->bus_info) - 1); -#endif } else { snprintf(info->bus_info, sizeof(info->bus_info) - 1, "PCMCIA FIXME"); @@ -1179,7 +1174,6 @@ void wl_multicast( struct net_device *dev, int num_addrs, void *addrs ) #endif /* NEW_MULTICAST */ -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)) static const struct net_device_ops wl_netdev_ops = { .ndo_start_xmit = &wl_tx_port0, @@ -1199,7 +1193,6 @@ static const struct net_device_ops wl_netdev_ops = .ndo_poll_controller = wl_poll, #endif }; -#endif // (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)) /******************************************************************************* * wl_device_alloc() @@ -1253,27 +1246,7 @@ struct net_device * wl_device_alloc( void ) lp->wireless_data.spy_data = &lp->spy_data; dev->wireless_data = &lp->wireless_data; -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)) dev->netdev_ops = &wl_netdev_ops; -#else - dev->hard_start_xmit = &wl_tx_port0; - - dev->set_config = &wl_config; - dev->get_stats = &wl_stats; - dev->set_multicast_list = &wl_multicast; - - dev->init = &wl_insert; - dev->open = &wl_adapter_open; - dev->stop = &wl_adapter_close; - dev->do_ioctl = &wl_ioctl; - - dev->tx_timeout = &wl_tx_timeout; - -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = wl_poll; -#endif - -#endif // (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)) dev->watchdog_timeo = TX_TIMEOUT; diff --git a/drivers/staging/wlags49_h2/wl_wext.c b/drivers/staging/wlags49_h2/wl_wext.c index 311d3c5a2ef0..06467f1bf901 100644 --- a/drivers/staging/wlags49_h2/wl_wext.c +++ b/drivers/staging/wlags49_h2/wl_wext.c @@ -82,17 +82,10 @@ in the build. */ #ifdef WIRELESS_EXT -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) -#define IWE_STREAM_ADD_EVENT(info, buf, end, iwe, len) \ - iwe_stream_add_event(buf, end, iwe, len) -#define IWE_STREAM_ADD_POINT(info, buf, end, iwe, msg) \ - iwe_stream_add_point(buf, end, iwe, msg) -#else #define IWE_STREAM_ADD_EVENT(info, buf, end, iwe, len) \ iwe_stream_add_event(info, buf, end, iwe, len) #define IWE_STREAM_ADD_POINT(info, buf, end, iwe, msg) \ iwe_stream_add_point(info, buf, end, iwe, msg) -#endif -- cgit v1.2.3 From 21fe2eea6381845956322e63e441f351774de7f9 Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 13 May 2010 17:44:39 +0800 Subject: Staging: comedi: Fix long line lengths in comedi_fops.c This patch fixes lots of long line lengths in comedi_fops.c found by checkpatch.pl Signed-off-by: Mark Rankilor Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 44 ++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index e7095d766f40..aced00e5cd10 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -952,8 +952,9 @@ static int do_insn_ioctl(struct comedi_device *dev, if (insn.n > MAX_SAMPLES) insn.n = MAX_SAMPLES; if (insn.insn & INSN_MASK_WRITE) { - if (copy_from_user - (data, insn.data, insn.n * sizeof(unsigned int))) { + if (copy_from_user(data, + insn.data, + insn.n * sizeof(unsigned int))) { ret = -EFAULT; goto error; } @@ -962,7 +963,9 @@ static int do_insn_ioctl(struct comedi_device *dev, if (ret < 0) goto error; if (insn.insn & INSN_MASK_READ) { - if (copy_to_user(insn.data, data, insn.n * sizeof(unsigned int))) { + if (copy_to_user(insn.data, + data, + insn.n * sizeof(unsigned int))) { ret = -EFAULT; goto error; } @@ -1070,7 +1073,9 @@ static int do_cmd_ioctl(struct comedi_device *dev, } /* make sure each element in channel/gain list is valid */ - ret = comedi_check_chanlist(s, async->cmd.chanlist_len, async->cmd.chanlist); + ret = comedi_check_chanlist(s, + async->cmd.chanlist_len, + async->cmd.chanlist); if (ret < 0) { DPRINTK("bad chanlist\n"); goto cleanup; @@ -2119,8 +2124,8 @@ int comedi_alloc_board_minor(struct device *hardware_device) kfree(info->device); kfree(info); printk(KERN_ERR - - "comedi: error: ran out of minor numbers for board device files.\n"); + "comedi: error: " + "ran out of minor numbers for board device files.\n"); return -EBUSY; } info->device->minor = i; @@ -2133,7 +2138,8 @@ int comedi_alloc_board_minor(struct device *hardware_device) retval = device_create_file(csdev, &dev_attr_max_read_buffer_kb); if (retval) { printk(KERN_ERR - "comedi: failed to create sysfs attribute file \"%s\".\n", + "comedi: " + "failed to create sysfs attribute file \"%s\".\n", dev_attr_max_read_buffer_kb.attr.name); comedi_free_board_minor(i); return retval; @@ -2141,7 +2147,8 @@ int comedi_alloc_board_minor(struct device *hardware_device) retval = device_create_file(csdev, &dev_attr_read_buffer_kb); if (retval) { printk(KERN_ERR - "comedi: failed to create sysfs attribute file \"%s\".\n", + "comedi: " + "failed to create sysfs attribute file \"%s\".\n", dev_attr_read_buffer_kb.attr.name); comedi_free_board_minor(i); return retval; @@ -2149,7 +2156,8 @@ int comedi_alloc_board_minor(struct device *hardware_device) retval = device_create_file(csdev, &dev_attr_max_write_buffer_kb); if (retval) { printk(KERN_ERR - "comedi: failed to create sysfs attribute file \"%s\".\n", + "comedi: " + "failed to create sysfs attribute file \"%s\".\n", dev_attr_max_write_buffer_kb.attr.name); comedi_free_board_minor(i); return retval; @@ -2157,7 +2165,8 @@ int comedi_alloc_board_minor(struct device *hardware_device) retval = device_create_file(csdev, &dev_attr_write_buffer_kb); if (retval) { printk(KERN_ERR - "comedi: failed to create sysfs attribute file \"%s\".\n", + "comedi: " + "failed to create sysfs attribute file \"%s\".\n", dev_attr_write_buffer_kb.attr.name); comedi_free_board_minor(i); return retval; @@ -2216,7 +2225,8 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev, if (i == COMEDI_NUM_MINORS) { kfree(info); printk(KERN_ERR - "comedi: error: ran out of minor numbers for board device files.\n"); + "comedi: error: " + "ran out of minor numbers for board device files.\n"); return -EBUSY; } s->minor = i; @@ -2230,7 +2240,8 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev, retval = device_create_file(csdev, &dev_attr_max_read_buffer_kb); if (retval) { printk(KERN_ERR - "comedi: failed to create sysfs attribute file \"%s\".\n", + "comedi: " + "failed to create sysfs attribute file \"%s\".\n", dev_attr_max_read_buffer_kb.attr.name); comedi_free_subdevice_minor(s); return retval; @@ -2238,7 +2249,8 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev, retval = device_create_file(csdev, &dev_attr_read_buffer_kb); if (retval) { printk(KERN_ERR - "comedi: failed to create sysfs attribute file \"%s\".\n", + "comedi: " + "failed to create sysfs attribute file \"%s\".\n", dev_attr_read_buffer_kb.attr.name); comedi_free_subdevice_minor(s); return retval; @@ -2246,7 +2258,8 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev, retval = device_create_file(csdev, &dev_attr_max_write_buffer_kb); if (retval) { printk(KERN_ERR - "comedi: failed to create sysfs attribute file \"%s\".\n", + "comedi: " + "failed to create sysfs attribute file \"%s\".\n", dev_attr_max_write_buffer_kb.attr.name); comedi_free_subdevice_minor(s); return retval; @@ -2254,7 +2267,8 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev, retval = device_create_file(csdev, &dev_attr_write_buffer_kb); if (retval) { printk(KERN_ERR - "comedi: failed to create sysfs attribute file \"%s\".\n", + "comedi: " + "failed to create sysfs attribute file \"%s\".\n", dev_attr_write_buffer_kb.attr.name); comedi_free_subdevice_minor(s); return retval; -- cgit v1.2.3 From 6c7f81967b8984e6fb6b1f04c63f32d90a15c479 Mon Sep 17 00:00:00 2001 From: Alexander Kurz Date: Thu, 13 May 2010 13:56:16 +0400 Subject: staging: comedi PCMCIA-drivers: adding MODULE_AUTHOR, MODULE_DESCRIPTION and MODULE_LICENSE this adds and sorts the module labels MODULE_AUTHOR, MODULE_DESCRIPTION and MODULE_LICENSE for all comedi PCMCIA drivers. Signed-off-by: Alexander Kurz Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 3 +++ drivers/staging/comedi/drivers/das08_cs.c | 5 ++++- drivers/staging/comedi/drivers/ni_daq_700.c | 6 +++++- drivers/staging/comedi/drivers/ni_daq_dio24.c | 4 ++++ drivers/staging/comedi/drivers/ni_labpc_cs.c | 4 +++- drivers/staging/comedi/drivers/ni_mio_cs.c | 5 +++-- drivers/staging/comedi/drivers/quatech_daqp_cs.c | 3 +++ 7 files changed, 25 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 68bd5caa5e40..19c60936e012 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -859,6 +859,9 @@ static struct pcmcia_device_id das16cs_id_table[] = { }; MODULE_DEVICE_TABLE(pcmcia, das16cs_id_table); +MODULE_AUTHOR("David A. Schleef "); +MODULE_DESCRIPTION("Comedi driver for Computer Boards PC-CARD DAS16/16"); +MODULE_LICENSE("GPL"); struct pcmcia_driver das16cs_driver = { .probe = das16cs_pcmcia_attach, diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c index 9164ce158dcd..456661c3b8b5 100644 --- a/drivers/staging/comedi/drivers/das08_cs.c +++ b/drivers/staging/comedi/drivers/das08_cs.c @@ -371,6 +371,10 @@ static struct pcmcia_device_id das08_cs_id_table[] = { }; MODULE_DEVICE_TABLE(pcmcia, das08_cs_id_table); +MODULE_AUTHOR("David A. Schleef , " + "Frank Mori Hess "); +MODULE_DESCRIPTION("Comedi driver for ComputerBoards DAS-08 PCMCIA boards"); +MODULE_LICENSE("GPL"); struct pcmcia_driver das08_cs_driver = { .probe = das08_pcmcia_attach, @@ -413,6 +417,5 @@ static void __exit das08_cs_exit_module(void) comedi_driver_unregister(&driver_das08_cs); } -MODULE_LICENSE("GPL"); module_init(das08_cs_init_module); module_exit(das08_cs_exit_module); diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 7844203c1ed7..29140756dfcd 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -734,8 +734,12 @@ static struct pcmcia_device_id dio700_cs_ids[] = { PCMCIA_DEVICE_NULL }; -MODULE_LICENSE("GPL"); + MODULE_DEVICE_TABLE(pcmcia, dio700_cs_ids); +MODULE_AUTHOR("Fred Brooks "); +MODULE_DESCRIPTION("Comedi driver for National Instruments " + "PCMCIA DAQCard-700 DIO"); +MODULE_LICENSE("GPL"); struct pcmcia_driver dio700_cs_driver = { .probe = dio700_cs_attach, diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c index ddc312b5d20d..f9e49e605d9c 100644 --- a/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c @@ -487,6 +487,10 @@ static struct pcmcia_device_id dio24_cs_ids[] = { }; MODULE_DEVICE_TABLE(pcmcia, dio24_cs_ids); +MODULE_AUTHOR("Daniel Vecino Castel "); +MODULE_DESCRIPTION("Comedi driver for National Instruments " + "PCMCIA DAQ-Card DIO-24"); +MODULE_LICENSE("GPL"); struct pcmcia_driver dio24_cs_driver = { .probe = dio24_cs_attach, diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c index 8ad1055a5cc1..d2935e5de5e3 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_cs.c +++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c @@ -463,6 +463,9 @@ static struct pcmcia_device_id labpc_cs_ids[] = { }; MODULE_DEVICE_TABLE(pcmcia, labpc_cs_ids); +MODULE_AUTHOR("Frank Mori Hess "); +MODULE_DESCRIPTION("Comedi driver for National Instruments Lab-PC"); +MODULE_LICENSE("GPL"); struct pcmcia_driver labpc_cs_driver = { .probe = labpc_cs_attach, @@ -504,6 +507,5 @@ void __exit labpc_exit_module(void) comedi_driver_unregister(&driver_labpc_cs); } -MODULE_LICENSE("GPL"); module_init(labpc_init_module); module_exit(labpc_exit_module); diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c index dc4849a40c97..dcb157903455 100644 --- a/drivers/staging/comedi/drivers/ni_mio_cs.c +++ b/drivers/staging/comedi/drivers/ni_mio_cs.c @@ -439,8 +439,6 @@ static int ni_getboardtype(struct comedi_device *dev, #ifdef MODULE -MODULE_LICENSE("GPL"); - static struct pcmcia_device_id ni_mio_cs_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x010b, 0x010d), /* DAQCard-ai-16xe-50 */ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x010c), /* DAQCard-ai-16e-4 */ @@ -451,6 +449,9 @@ static struct pcmcia_device_id ni_mio_cs_ids[] = { }; MODULE_DEVICE_TABLE(pcmcia, ni_mio_cs_ids); +MODULE_AUTHOR("David A. Schleef "); +MODULE_DESCRIPTION("Comedi driver for National Instruments DAQCard E series"); +MODULE_LICENSE("GPL"); struct pcmcia_driver ni_mio_cs_driver = { .probe = &cs_attach, diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index fb427dbe98f5..be62face6a71 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -1243,6 +1243,9 @@ static struct pcmcia_device_id daqp_cs_id_table[] = { }; MODULE_DEVICE_TABLE(pcmcia, daqp_cs_id_table); +MODULE_AUTHOR("Brent Baccala "); +MODULE_DESCRIPTION("Comedi driver for Quatech DAQP PCMCIA data capture cards"); +MODULE_LICENSE("GPL"); static struct pcmcia_driver daqp_cs_driver = { .probe = daqp_cs_attach, -- cgit v1.2.3 From b464f791caf66b6120c3cd8a77ad313ed532667a Mon Sep 17 00:00:00 2001 From: Mark Rankilor Date: Thu, 13 May 2010 18:28:38 +0800 Subject: Staging: comedi: Fixed long line lengths in comedi.h This patches fixes long line lengths in comedi.h that were picked up by checkpatch.pl Signed-off-by: Mark Rankilor Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi.h | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index 1538146b37a3..3e3663fe1f4f 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -465,7 +465,8 @@ #define COMEDI_CB_EOS 1 /* end of scan */ #define COMEDI_CB_EOA 2 /* end of acquisition */ -#define COMEDI_CB_BLOCK 4 /* data has arrived: wakes up read() / write() */ +#define COMEDI_CB_BLOCK 4 /* data has arrived: + * wakes up read() / write() */ #define COMEDI_CB_EOBUF 8 /* DEPRECATED: end of buffer */ #define COMEDI_CB_ERROR 16 /* card error during acquisition */ #define COMEDI_CB_OVERFLOW 32 /* buffer overflow/underflow */ @@ -499,8 +500,10 @@ I8254_MODE2 = (2 << 1), /* Rate generator */ I8254_MODE3 = (3 << 1), /* Square wave mode */ I8254_MODE4 = (4 << 1), /* Software triggered strobe */ - I8254_MODE5 = (5 << 1), /* Hardware triggered strobe (retriggerable) */ - I8254_BCD = 1, /* use binary-coded decimal instead of binary (pretty useless) */ + I8254_MODE5 = (5 << 1), /* Hardware triggered strobe + * (retriggerable) */ + I8254_BCD = 1, /* use binary-coded decimal instead of binary + * (pretty useless) */ I8254_BINARY = 0 }; @@ -640,7 +643,8 @@ May be bitwise-or'd with CR_EDGE or CR_INVERT. */ NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT = 0x201, NI_GPCT_SELECTED_GATE_GATE_SELECT = 0x21e, /* m-series "second gate" sources are unknown, - we should add them here with an offset of 0x300 when known. */ + * we should add them here with an offset of 0x300 when + * known. */ NI_GPCT_DISABLED_GATE_SELECT = 0x8000, }; static inline unsigned NI_GPCT_GATE_PIN_GATE_SELECT(unsigned n) @@ -681,14 +685,14 @@ INSN_CONFIG_SET_OTHER_SRC when using NI general-purpose counters. */ INSN_CONFIG_ARM */ enum ni_gpct_arm_source { NI_GPCT_ARM_IMMEDIATE = 0x0, - NI_GPCT_ARM_PAIRED_IMMEDIATE = 0x1, /* Start both the counter and - the adjacent paired counter - simultaneously */ - /* NI doesn't document bits for selecting hardware arm triggers. If - * the NI_GPCT_ARM_UNKNOWN bit is set, we will pass the least - * significant bits (3 bits for 660x or 5 bits for m-series) through to - * the hardware. This will at least allow someone to figure out what - * the bits do later. */ + NI_GPCT_ARM_PAIRED_IMMEDIATE = 0x1, /* Start both the counter + * and the adjacent paired + * counter simultaneously */ + /* NI doesn't document bits for selecting hardware arm triggers. + * If the NI_GPCT_ARM_UNKNOWN bit is set, we will pass the least + * significant bits (3 bits for 660x or 5 bits for m-series) + * through to the hardware. This will at least allow someone to + * figure out what the bits do later. */ NI_GPCT_ARM_UNKNOWN = 0x1000, }; @@ -740,8 +744,8 @@ INSN_CONFIG_ARM */ NI_RTSI_OUTPUT_G_GATE0 = 6, NI_RTSI_OUTPUT_RGOUT0 = 7, NI_RTSI_OUTPUT_RTSI_BRD_0 = 8, - NI_RTSI_OUTPUT_RTSI_OSC = 12 /* pre-m-series always have RTSI clock - on line 7 */ + NI_RTSI_OUTPUT_RTSI_OSC = 12 /* pre-m-series always have RTSI + * clock on line 7 */ }; static inline unsigned NI_RTSI_OUTPUT_RTSI_BRD(unsigned n) { -- cgit v1.2.3 From 7d8e737dd7e3519110a7bc529ef6ac80ac41c3f5 Mon Sep 17 00:00:00 2001 From: Mark Rankilor Date: Thu, 13 May 2010 18:28:39 +0800 Subject: Staging: comedi: Fixed more long line lengths in comedi.h This patches fixes some long line lengths in comedi.h from checkpatch.pl Signed-off-by: Mark Rankilor Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index 3e3663fe1f4f..6c900e2756fb 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -267,7 +267,8 @@ * streaming input/output */ INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE = 2006, INSN_CONFIG_SET_COUNTER_MODE = 4097, - INSN_CONFIG_8254_SET_MODE = INSN_CONFIG_SET_COUNTER_MODE, /* deprecated */ + /* INSN_CONFIG_8254_SET_MODE is deprecated */ + INSN_CONFIG_8254_SET_MODE = INSN_CONFIG_SET_COUNTER_MODE, INSN_CONFIG_8254_READ_STATUS = 4098, INSN_CONFIG_SET_ROUTING = 4099, INSN_CONFIG_GET_ROUTING = 4109, @@ -598,14 +599,17 @@ NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS = 0x3, NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS = 0x4, NI_GPCT_NEXT_TC_CLOCK_SRC_BITS = 0x5, - NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS = 0x6, /* NI 660x-specific */ + /* NI 660x-specific */ + NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS = 0x6, NI_GPCT_PXI10_CLOCK_SRC_BITS = 0x7, NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS = 0x8, NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS = 0x9, NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK = 0x30000000, NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS = 0x0, - NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS = 0x10000000, /* divide source by 2 */ - NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS = 0x20000000, /* divide source by 8 */ + /* divide source by 2 */ + NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS = 0x10000000, + /* divide source by 8 */ + NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS = 0x20000000, NI_GPCT_INVERT_CLOCK_SRC_BIT = 0x80000000 }; static inline unsigned NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(unsigned n) @@ -837,7 +841,8 @@ INSN_CONFIG_ARM */ { return NI_USUAL_PFI_SELECT(pfi_channel); } - static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel) + static inline unsigned + NI_CDIO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel) { return NI_USUAL_RTSI_SELECT(rtsi_channel); } -- cgit v1.2.3 From 5c2af91bbcc19c96d2fb35c4bb3f3d66b039e978 Mon Sep 17 00:00:00 2001 From: Florian Schilhabel Date: Thu, 13 May 2010 13:55:25 +0200 Subject: Staging: rtl819su: added r8192SU_led.c/.h added the necessary infrastructure for the leds on the device this is a port from Realteks driver. leds are now working partially. Signed-off-by: Florian Schilhabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192su/Makefile | 1 + .../staging/rtl8192su/ieee80211/ieee80211_r8192s.h | 24 +- drivers/staging/rtl8192su/r8192SU_led.c | 2347 ++++++++++++++++++++ drivers/staging/rtl8192su/r8192SU_led.h | 93 + drivers/staging/rtl8192su/r8192U.h | 27 +- 5 files changed, 2466 insertions(+), 26 deletions(-) create mode 100644 drivers/staging/rtl8192su/r8192SU_led.c create mode 100644 drivers/staging/rtl8192su/r8192SU_led.h (limited to 'drivers') diff --git a/drivers/staging/rtl8192su/Makefile b/drivers/staging/rtl8192su/Makefile index 9374a0179e5b..7133894afe76 100644 --- a/drivers/staging/rtl8192su/Makefile +++ b/drivers/staging/rtl8192su/Makefile @@ -20,6 +20,7 @@ r8192s_usb-objs := \ r8192S_Efuse.o \ r8192U_core.o \ r8192U_pm.o \ + r8192SU_led.o \ ieee80211/ieee80211_crypt.o \ ieee80211/ieee80211_crypt_tkip.o \ ieee80211/ieee80211_crypt_ccmp.o \ diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_r8192s.h b/drivers/staging/rtl8192su/ieee80211/ieee80211_r8192s.h index 7d6c3bc143ae..1824cda790d8 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_r8192s.h +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_r8192s.h @@ -172,18 +172,20 @@ enum { IG_Max }; -typedef enum _LED_CTL_MODE { - LED_CTL_POWER_ON = 1, - LED_CTL_LINK = 2, - LED_CTL_NO_LINK = 3, - LED_CTL_TX = 4, - LED_CTL_RX = 5, - LED_CTL_SITE_SURVEY = 6, - LED_CTL_POWER_OFF = 7, - LED_CTL_START_TO_LINK = 8, - LED_CTL_START_WPS = 9, - LED_CTL_STOP_WPS = 10, +typedef enum _LED_CTL_MODE{ + LED_CTL_POWER_ON = 1, + LED_CTL_LINK = 2, + LED_CTL_NO_LINK = 3, + LED_CTL_TX = 4, + LED_CTL_RX = 5, + LED_CTL_SITE_SURVEY = 6, + LED_CTL_POWER_OFF = 7, + LED_CTL_START_TO_LINK = 8, + LED_CTL_START_WPS = 9, + LED_CTL_STOP_WPS = 10, LED_CTL_START_WPS_BOTTON = 11, + LED_CTL_STOP_WPS_FAIL = 12, + LED_CTL_STOP_WPS_FAIL_OVERLAP = 13, } LED_CTL_MODE; typedef union _frameqos { diff --git a/drivers/staging/rtl8192su/r8192SU_led.c b/drivers/staging/rtl8192su/r8192SU_led.c new file mode 100644 index 000000000000..609dba67eb4e --- /dev/null +++ b/drivers/staging/rtl8192su/r8192SU_led.c @@ -0,0 +1,2347 @@ +/* + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + */ + +#include "r8192U.h" +#include "r8192S_hw.h" +#include "r8192SU_led.h" + +#define LED_BLINK_NORMAL_INTERVAL 100 +#define LED_BLINK_SLOWLY_INTERVAL 200 +#define LED_BLINK_LONG_INTERVAL 400 + +#define LED_BLINK_NO_LINK_INTERVAL_ALPHA 1000 +#define LED_BLINK_LINK_INTERVAL_ALPHA 500 +#define LED_BLINK_SCAN_INTERVAL_ALPHA 180 +#define LED_BLINK_FASTER_INTERVAL_ALPHA 50 +#define LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA 5000 + + + +static void BlinkTimerCallback (unsigned long data); + +static void BlinkWorkItemCallback (struct work_struct *work); + +void InitLed819xUsb (struct net_device *dev, PLED_819xUsb pLed, + LED_PIN_819xUsb LedPin) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + pLed->dev = dev; + pLed->LedPin = LedPin; + pLed->CurrLedState = LED_OFF; + pLed->bLedOn = FALSE; + + pLed->bLedBlinkInProgress = FALSE; + pLed->BlinkTimes = 0; + pLed->BlinkingLedState = LED_OFF; + + init_timer(&pLed->BlinkTimer); + pLed->BlinkTimer.data = (unsigned long)dev; + pLed->BlinkTimer.function = BlinkTimerCallback; + + INIT_WORK(&priv->BlinkWorkItem, (void*)BlinkWorkItemCallback); + priv->pLed = pLed; +} + + +void DeInitLed819xUsb (PLED_819xUsb pLed) +{ + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; +} + +void SwLedOn (struct net_device *dev, PLED_819xUsb pLed) +{ + u8 LedCfg; + + LedCfg = read_nic_byte(dev, LEDCFG); + switch (pLed->LedPin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + write_nic_byte(dev, LEDCFG, LedCfg&0xf0); + break; + case LED_PIN_LED1: + write_nic_byte(dev, LEDCFG, LedCfg&0x0f); + break; + default: + break; + } + pLed->bLedOn = TRUE; +} + +void SwLedOff (struct net_device *dev, PLED_819xUsb pLed) +{ + u8 LedCfg; + + LedCfg = read_nic_byte(dev, LEDCFG); + switch (pLed->LedPin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + LedCfg &= 0xf0; + write_nic_byte(dev, LEDCFG, (LedCfg|BIT3)); + break; + case LED_PIN_LED1: + LedCfg &= 0x0f; + write_nic_byte(dev, LEDCFG, (LedCfg|BIT7)); + break; + default: + break; + } + pLed->bLedOn = FALSE; +} + + +void +InitSwLeds( + struct net_device *dev + ) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + InitLed819xUsb(dev, &(priv->SwLed0), LED_PIN_LED0); + + InitLed819xUsb(dev,&(priv->SwLed1), LED_PIN_LED1); +} + + +void +DeInitSwLeds( + struct net_device *dev + ) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + DeInitLed819xUsb( &(priv->SwLed0) ); + DeInitLed819xUsb( &(priv->SwLed1) ); +} + + +void +SwLedBlink( + PLED_819xUsb pLed + ) +{ + struct net_device *dev = (struct net_device *)(pLed->dev); + struct r8192_priv *priv = ieee80211_priv(dev); + bool bStopBlinking = FALSE; + + if( pLed->BlinkingLedState == LED_ON ) + { + SwLedOn(dev, pLed); + RT_TRACE(COMP_LED, "Blinktimes (%d): turn on\n", pLed->BlinkTimes); + } + else + { + SwLedOff(dev, pLed); + RT_TRACE(COMP_LED, "Blinktimes (%d): turn off\n", pLed->BlinkTimes); + } + + pLed->BlinkTimes--; + switch(pLed->CurrLedState) + { + + case LED_BLINK_NORMAL: + if(pLed->BlinkTimes == 0) + { + bStopBlinking = TRUE; + } + break; + + case LED_BLINK_StartToBlink: + if( (priv->ieee80211->state == IEEE80211_LINKED) && (priv->ieee80211->iw_mode == IW_MODE_INFRA)) + { + bStopBlinking = TRUE; + } + else if((priv->ieee80211->state == IEEE80211_LINKED) && (priv->ieee80211->iw_mode == IW_MODE_ADHOC)) + { + bStopBlinking = TRUE; + } + else if(pLed->BlinkTimes == 0) + { + bStopBlinking = TRUE; + } + break; + + case LED_BLINK_WPS: + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = TRUE; + } + break; + + + default: + bStopBlinking = TRUE; + break; + + } + + if(bStopBlinking) + { + if( priv->ieee80211->eRFPowerState != eRfOn ) + { + SwLedOff(dev, pLed); + } + else if( (priv->ieee80211->state == IEEE80211_LINKED) && (pLed->bLedOn == false)) + { + SwLedOn(dev, pLed); + } + else if( (priv->ieee80211->state != IEEE80211_LINKED) && pLed->bLedOn == true) + { + SwLedOff(dev, pLed); + } + + pLed->BlinkTimes = 0; + pLed->bLedBlinkInProgress = FALSE; + } + else + { + if( pLed->BlinkingLedState == LED_ON ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + + switch( pLed->CurrLedState ) + { + case LED_BLINK_NORMAL: + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL)); + break; + + case LED_BLINK_SLOWLY: + case LED_BLINK_StartToBlink: + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL)); + break; + + case LED_BLINK_WPS: + { + if( pLed->BlinkingLedState == LED_ON ) + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_LONG_INTERVAL)); + else + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_LONG_INTERVAL)); + } + break; + + default: + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL)); + break; + } + } +} + + +void +SwLedBlink1( + PLED_819xUsb pLed + ) +{ + struct net_device *dev = (struct net_device *)(pLed->dev); + struct r8192_priv *priv = ieee80211_priv(dev); + PLED_819xUsb pLed1 = &(priv->SwLed1); + bool bStopBlinking = FALSE; + + if(priv->CustomerID == RT_CID_819x_CAMEO) + pLed = &(priv->SwLed1); + + if( pLed->BlinkingLedState == LED_ON ) + { + SwLedOn(dev, pLed); + RT_TRACE(COMP_LED, "Blinktimes (%d): turn on\n", pLed->BlinkTimes); + } + else + { + SwLedOff(dev, pLed); + RT_TRACE(COMP_LED, "Blinktimes (%d): turn off\n", pLed->BlinkTimes); + } + + + if(priv->CustomerID == RT_CID_DEFAULT) + { + if(priv->ieee80211->state == IEEE80211_LINKED) + { + if(!pLed1->bSWLedCtrl) + { + SwLedOn(dev, pLed1); + pLed1->bSWLedCtrl = TRUE; + } + else if(!pLed1->bLedOn) + SwLedOn(dev, pLed1); + RT_TRACE(COMP_LED, "Blinktimes (): turn on pLed1\n"); + } + else + { + if(!pLed1->bSWLedCtrl) + { + SwLedOff(dev, pLed1); + pLed1->bSWLedCtrl = TRUE; + } + else if(pLed1->bLedOn) + SwLedOff(dev, pLed1); + RT_TRACE(COMP_LED, "Blinktimes (): turn off pLed1\n"); + } + } + + switch(pLed->CurrLedState) + { + case LED_BLINK_SLOWLY: + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); + break; + + case LED_BLINK_NORMAL: + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_LINK_INTERVAL_ALPHA)); + break; + + case LED_SCAN_BLINK: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = TRUE; + } + + if(bStopBlinking) + { + if( priv->ieee80211->eRFPowerState != eRfOn ) + { + SwLedOff(dev, pLed); + } + else if(priv->ieee80211->state == IEEE80211_LINKED) + { + pLed->bLedLinkBlinkInProgress = TRUE; + pLed->CurrLedState = LED_BLINK_NORMAL; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_LINK_INTERVAL_ALPHA)); + RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState); + + } + else if(priv->ieee80211->state != IEEE80211_LINKED) + { + pLed->bLedNoLinkBlinkInProgress = TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); + RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState); + } + pLed->bLedScanBlinkInProgress = FALSE; + } + else + { + if( priv->ieee80211->eRFPowerState != eRfOn ) + { + SwLedOff(dev, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA)); + } + } + break; + + case LED_TXRX_BLINK: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = TRUE; + } + if(bStopBlinking) + { + if( priv->ieee80211->eRFPowerState != eRfOn ) + { + SwLedOff(dev, pLed); + } + else if(priv->ieee80211->state == IEEE80211_LINKED) + { + pLed->bLedLinkBlinkInProgress = TRUE; + pLed->CurrLedState = LED_BLINK_NORMAL; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_LINK_INTERVAL_ALPHA)); + RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState); + } + else if(priv->ieee80211->state != IEEE80211_LINKED) + { + pLed->bLedNoLinkBlinkInProgress = TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); + RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState); + } + pLed->BlinkTimes = 0; + pLed->bLedBlinkInProgress = FALSE; + } + else + { + if( priv->ieee80211->eRFPowerState != eRfOn ) + { + SwLedOff(dev, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA)); + } + } + break; + + case LED_BLINK_WPS: + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA)); + break; + + case LED_BLINK_WPS_STOP: + if(pLed->BlinkingLedState == LED_ON) + { + pLed->BlinkingLedState = LED_OFF; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA)); + bStopBlinking = FALSE; + } + else + { + bStopBlinking = TRUE; + } + + if(bStopBlinking) + { + if( priv->ieee80211->eRFPowerState != eRfOn ) + { + SwLedOff(dev, pLed); + } + else + { + pLed->bLedLinkBlinkInProgress = TRUE; + pLed->CurrLedState = LED_BLINK_NORMAL; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_LINK_INTERVAL_ALPHA)); + RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState); + } + pLed->bLedWPSBlinkInProgress = FALSE; + } + break; + + default: + break; + } + +} + +void +SwLedBlink2( + PLED_819xUsb pLed + ) +{ + struct net_device *dev = (struct net_device *)(pLed->dev); + struct r8192_priv *priv = ieee80211_priv(dev); + bool bStopBlinking = FALSE; + + if( pLed->BlinkingLedState == LED_ON) + { + SwLedOn(dev, pLed); + RT_TRACE(COMP_LED, "Blinktimes (%d): turn on\n", pLed->BlinkTimes); + } + else + { + SwLedOff(dev, pLed); + RT_TRACE(COMP_LED, "Blinktimes (%d): turn off\n", pLed->BlinkTimes); + } + + switch(pLed->CurrLedState) + { + case LED_SCAN_BLINK: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = TRUE; + } + + if(bStopBlinking) + { + if( priv->ieee80211->eRFPowerState != eRfOn ) + { + SwLedOff(dev, pLed); + RT_TRACE(COMP_LED, "eRFPowerState %d\n", priv->ieee80211->eRFPowerState); + } + else if(priv->ieee80211->state == IEEE80211_LINKED) + { + pLed->CurrLedState = LED_ON; + pLed->BlinkingLedState = LED_ON; + SwLedOn(dev, pLed); + RT_TRACE(COMP_LED, "stop scan blink CurrLedState %d\n", pLed->CurrLedState); + + } + else if(priv->ieee80211->state != IEEE80211_LINKED) + { + pLed->CurrLedState = LED_OFF; + pLed->BlinkingLedState = LED_OFF; + SwLedOff(dev, pLed); + RT_TRACE(COMP_LED, "stop scan blink CurrLedState %d\n", pLed->CurrLedState); + } + pLed->bLedScanBlinkInProgress = FALSE; + } + else + { + if( priv->ieee80211->eRFPowerState != eRfOn ) + { + SwLedOff(dev, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA)); + } + } + break; + + case LED_TXRX_BLINK: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = TRUE; + } + if(bStopBlinking) + { + if( priv->ieee80211->eRFPowerState != eRfOn ) + { + SwLedOff(dev, pLed); + } + else if(priv->ieee80211->state == IEEE80211_LINKED) + { + pLed->CurrLedState = LED_ON; + pLed->BlinkingLedState = LED_ON; + SwLedOn(dev, pLed); + RT_TRACE(COMP_LED, "stop CurrLedState %d\n", pLed->CurrLedState); + + } + else if(priv->ieee80211->state != IEEE80211_LINKED) + { + pLed->CurrLedState = LED_OFF; + pLed->BlinkingLedState = LED_OFF; + SwLedOff(dev, pLed); + RT_TRACE(COMP_LED, "stop CurrLedState %d\n", pLed->CurrLedState); + } + pLed->bLedBlinkInProgress = FALSE; + } + else + { + if( priv->ieee80211->eRFPowerState != eRfOn ) + { + SwLedOff(dev, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA)); + } + } + break; + + default: + break; + } + +} + +void +SwLedBlink3( + PLED_819xUsb pLed + ) +{ + struct net_device *dev = (struct net_device *)(pLed->dev); + struct r8192_priv *priv = ieee80211_priv(dev); + bool bStopBlinking = FALSE; + + if( pLed->BlinkingLedState == LED_ON ) + { + SwLedOn(dev, pLed); + RT_TRACE(COMP_LED, "Blinktimes (%d): turn on\n", pLed->BlinkTimes); + } + else + { + if(pLed->CurrLedState != LED_BLINK_WPS_STOP) + SwLedOff(dev, pLed); + RT_TRACE(COMP_LED, "Blinktimes (%d): turn off\n", pLed->BlinkTimes); + } + + switch(pLed->CurrLedState) + { + case LED_SCAN_BLINK: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = TRUE; + } + + if(bStopBlinking) + { + if( priv->ieee80211->eRFPowerState != eRfOn ) + { + SwLedOff(dev, pLed); + } + else if(priv->ieee80211->state == IEEE80211_LINKED) + { + pLed->CurrLedState = LED_ON; + pLed->BlinkingLedState = LED_ON; + if( !pLed->bLedOn ) + SwLedOn(dev, pLed); + + RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState); + } + else if(priv->ieee80211->state != IEEE80211_LINKED) + { + pLed->CurrLedState = LED_OFF; + pLed->BlinkingLedState = LED_OFF; + if( pLed->bLedOn ) + SwLedOff(dev, pLed); + + RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState); + } + pLed->bLedScanBlinkInProgress = FALSE; + } + else + { + if( priv->ieee80211->eRFPowerState != eRfOn ) + { + SwLedOff(dev, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA)); + } + } + break; + + case LED_TXRX_BLINK: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = TRUE; + } + if(bStopBlinking) + { + if( priv->ieee80211->eRFPowerState != eRfOn ) + { + SwLedOff(dev, pLed); + } + else if(priv->ieee80211->state == IEEE80211_LINKED) + { + pLed->CurrLedState = LED_ON; + pLed->BlinkingLedState = LED_ON; + + if( !pLed->bLedOn ) + SwLedOn(dev, pLed); + + RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState); + } + else if(priv->ieee80211->state != IEEE80211_LINKED) + { + pLed->CurrLedState = LED_OFF; + pLed->BlinkingLedState = LED_OFF; + + if( pLed->bLedOn ) + SwLedOff(dev, pLed); + + + RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState); + } + pLed->bLedBlinkInProgress = FALSE; + } + else + { + if( priv->ieee80211->eRFPowerState != eRfOn ) + { + SwLedOff(dev, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA)); + } + } + break; + + case LED_BLINK_WPS: + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA)); + break; + + case LED_BLINK_WPS_STOP: + if(pLed->BlinkingLedState == LED_ON) + { + pLed->BlinkingLedState = LED_OFF; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA)); + bStopBlinking = FALSE; + } + else + { + bStopBlinking = TRUE; + } + + if(bStopBlinking) + { + if( priv->ieee80211->eRFPowerState != eRfOn ) + { + SwLedOff(dev, pLed); + } + else + { + pLed->CurrLedState = LED_ON; + pLed->BlinkingLedState = LED_ON; + SwLedOn(dev, pLed); + RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState); + } + pLed->bLedWPSBlinkInProgress = FALSE; + } + break; + + + default: + break; + } + +} + + +void +SwLedBlink4( + PLED_819xUsb pLed + ) +{ + struct net_device *dev = (struct net_device *)(pLed->dev); + struct r8192_priv *priv = ieee80211_priv(dev); + PLED_819xUsb pLed1 = &(priv->SwLed1); + bool bStopBlinking = FALSE; + + if( pLed->BlinkingLedState == LED_ON ) + { + SwLedOn(dev, pLed); + RT_TRACE(COMP_LED, "Blinktimes (%d): turn on\n", pLed->BlinkTimes); + } + else + { + SwLedOff(dev, pLed); + RT_TRACE(COMP_LED, "Blinktimes (%d): turn off\n", pLed->BlinkTimes); + } + + if(!pLed1->bLedWPSBlinkInProgress && pLed1->BlinkingLedState == LED_UNKNOWN) + { + pLed1->BlinkingLedState = LED_OFF; + pLed1->CurrLedState = LED_OFF; + SwLedOff(dev, pLed1); + } + + switch(pLed->CurrLedState) + { + case LED_BLINK_SLOWLY: + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); + break; + + case LED_BLINK_StartToBlink: + if( pLed->bLedOn ) + { + pLed->BlinkingLedState = LED_OFF; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL)); + } + else + { + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL)); + } + break; + + case LED_SCAN_BLINK: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = TRUE; + } + + if(bStopBlinking) + { + if( priv->ieee80211->eRFPowerState != eRfOn && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS) + { + SwLedOff(dev, pLed); + } + else + { + pLed->bLedNoLinkBlinkInProgress = TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); + } + pLed->bLedScanBlinkInProgress = FALSE; + } + else + { + if( priv->ieee80211->eRFPowerState != eRfOn && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS) + { + SwLedOff(dev, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA)); + } + } + break; + + case LED_TXRX_BLINK: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = TRUE; + } + if(bStopBlinking) + { + if( priv->ieee80211->eRFPowerState != eRfOn && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS) + { + SwLedOff(dev, pLed); + } + else + { + pLed->bLedNoLinkBlinkInProgress = TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); + } + pLed->bLedBlinkInProgress = FALSE; + } + else + { + if( priv->ieee80211->eRFPowerState != eRfOn && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS) + { + SwLedOff(dev, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA)); + } + } + break; + + case LED_BLINK_WPS: + if( pLed->bLedOn ) + { + pLed->BlinkingLedState = LED_OFF; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL)); + } + else + { + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL)); + } + break; + + case LED_BLINK_WPS_STOP: + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL)); + break; + + case LED_BLINK_WPS_STOP_OVERLAP: + pLed->BlinkTimes--; + if(pLed->BlinkTimes == 0) + { + if(pLed->bLedOn) + { + pLed->BlinkTimes = 1; + } + else + { + bStopBlinking = TRUE; + } + } + + if(bStopBlinking) + { + pLed->BlinkTimes = 10; + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_LINK_INTERVAL_ALPHA)); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL)); + } + break; + + + default: + break; + } + + RT_TRACE(COMP_LED, "SwLedBlink4 CurrLedState %d\n", pLed->CurrLedState); + + +} + +void +SwLedBlink5( + PLED_819xUsb pLed + ) +{ + struct net_device *dev = (struct net_device *)(pLed->dev); + struct r8192_priv *priv = ieee80211_priv(dev); + bool bStopBlinking = FALSE; + + if( pLed->BlinkingLedState == LED_ON ) + { + SwLedOn(dev, pLed); + RT_TRACE(COMP_LED, "Blinktimes (%d): turn on\n", pLed->BlinkTimes); + } + else + { + SwLedOff(dev, pLed); + RT_TRACE(COMP_LED, "Blinktimes (%d): turn off\n", pLed->BlinkTimes); + } + + switch(pLed->CurrLedState) + { + case LED_SCAN_BLINK: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = TRUE; + } + + if(bStopBlinking) + { + if( priv->ieee80211->eRFPowerState != eRfOn && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS) + { + pLed->CurrLedState = LED_OFF; + pLed->BlinkingLedState = LED_OFF; + if(pLed->bLedOn) + SwLedOff(dev, pLed); + } + else + { pLed->CurrLedState = LED_ON; + pLed->BlinkingLedState = LED_ON; + if(!pLed->bLedOn) + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA)); + } + + pLed->bLedScanBlinkInProgress = FALSE; + } + else + { + if( priv->ieee80211->eRFPowerState != eRfOn && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS) + { + SwLedOff(dev, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA)); + } + } + break; + + + case LED_TXRX_BLINK: + pLed->BlinkTimes--; + if( pLed->BlinkTimes == 0 ) + { + bStopBlinking = TRUE; + } + + if(bStopBlinking) + { + if( priv->ieee80211->eRFPowerState != eRfOn && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS) + { + pLed->CurrLedState = LED_OFF; + pLed->BlinkingLedState = LED_OFF; + if(pLed->bLedOn) + SwLedOff(dev, pLed); + } + else + { + pLed->CurrLedState = LED_ON; + pLed->BlinkingLedState = LED_ON; + if(!pLed->bLedOn) + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA)); + } + + pLed->bLedBlinkInProgress = FALSE; + } + else + { + if( priv->ieee80211->eRFPowerState != eRfOn && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS) + { + SwLedOff(dev, pLed); + } + else + { + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA)); + } + } + break; + + default: + break; + } + + RT_TRACE(COMP_LED, "SwLedBlink5 CurrLedState %d\n", pLed->CurrLedState); + + +} + + +void +BlinkTimerCallback( + unsigned long data + ) +{ + struct net_device *dev = (struct net_device *)data; + struct r8192_priv *priv = ieee80211_priv(dev); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) + schedule_work(&(priv->BlinkWorkItem)); +#endif +} + + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) +void BlinkWorkItemCallback(struct work_struct *work) +{ + struct r8192_priv *priv = container_of(work, struct r8192_priv, BlinkWorkItem); +#else +void BlinkWorkItemCallback(void * Context) +{ + struct net_device *dev = (struct net_device *)Context; + struct r8192_priv *priv = ieee80211_priv(dev); +#endif + + PLED_819xUsb pLed = priv->pLed; + + switch(priv->LedStrategy) + { + case SW_LED_MODE0: + SwLedBlink(pLed); + break; + + case SW_LED_MODE1: + SwLedBlink1(pLed); + break; + + case SW_LED_MODE2: + SwLedBlink2(pLed); + break; + + case SW_LED_MODE3: + SwLedBlink3(pLed); + break; + + case SW_LED_MODE4: + SwLedBlink4(pLed); + break; + + case SW_LED_MODE5: + SwLedBlink5(pLed); + break; + + default: + SwLedBlink(pLed); + break; + } +} + + + + +void +SwLedControlMode0( + struct net_device *dev, + LED_CTL_MODE LedAction +) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + PLED_819xUsb pLed = &(priv->SwLed1); + + switch(LedAction) + { + case LED_CTL_TX: + case LED_CTL_RX: + if( pLed->bLedBlinkInProgress == FALSE ) + { + pLed->bLedBlinkInProgress = TRUE; + + pLed->CurrLedState = LED_BLINK_NORMAL; + pLed->BlinkTimes = 2; + + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL)); + } + break; + + case LED_CTL_START_TO_LINK: + if( pLed->bLedBlinkInProgress == FALSE ) + { + pLed->bLedBlinkInProgress = TRUE; + + pLed->CurrLedState = LED_BLINK_StartToBlink; + pLed->BlinkTimes = 24; + + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL)); + } + else + { + pLed->CurrLedState = LED_BLINK_StartToBlink; + } + break; + + case LED_CTL_LINK: + pLed->CurrLedState = LED_ON; + if( pLed->bLedBlinkInProgress == FALSE ) + { + SwLedOn(dev, pLed); + } + break; + + case LED_CTL_NO_LINK: + pLed->CurrLedState = LED_OFF; + if( pLed->bLedBlinkInProgress == FALSE ) + { + SwLedOff(dev, pLed); + } + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = LED_OFF; + if(pLed->bLedBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + SwLedOff(dev, pLed); + break; + + case LED_CTL_START_WPS: + if( pLed->bLedBlinkInProgress == FALSE || pLed->CurrLedState == LED_ON) + { + pLed->bLedBlinkInProgress = TRUE; + + pLed->CurrLedState = LED_BLINK_WPS; + pLed->BlinkTimes = 20; + + if( pLed->bLedOn ) + { + pLed->BlinkingLedState = LED_OFF; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_LONG_INTERVAL)); + } + else + { + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_LONG_INTERVAL)); + } + } + break; + + case LED_CTL_STOP_WPS: + if(pLed->bLedBlinkInProgress) + { + pLed->CurrLedState = LED_OFF; + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + break; + + + default: + break; + } + + RT_TRACE(COMP_LED, "Led %d\n", pLed->CurrLedState); + +} + +void +SwLedControlMode1( + struct net_device *dev, + LED_CTL_MODE LedAction +) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + PLED_819xUsb pLed = &(priv->SwLed0); + + if(priv->CustomerID == RT_CID_819x_CAMEO) + pLed = &(priv->SwLed1); + + switch(LedAction) + { + case LED_CTL_START_TO_LINK: + case LED_CTL_NO_LINK: + if( pLed->bLedNoLinkBlinkInProgress == FALSE ) + { + if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + if( pLed->bLedLinkBlinkInProgress == TRUE ) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = FALSE; + } + if(pLed->bLedBlinkInProgress ==TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + + pLed->bLedNoLinkBlinkInProgress = TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); + } + break; + + case LED_CTL_LINK: + if( pLed->bLedLinkBlinkInProgress == FALSE ) + { + if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + if(pLed->bLedNoLinkBlinkInProgress == TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = FALSE; + } + if(pLed->bLedBlinkInProgress ==TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + pLed->bLedLinkBlinkInProgress = TRUE; + pLed->CurrLedState = LED_BLINK_NORMAL; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_LINK_INTERVAL_ALPHA)); + } + break; + + case LED_CTL_SITE_SURVEY: + if((priv->ieee80211->LinkDetectInfo.bBusyTraffic) && (priv->ieee80211->state == IEEE80211_LINKED)) + ; + else if(pLed->bLedScanBlinkInProgress ==FALSE) + { + if(IS_LED_WPS_BLINKING(pLed)) + return; + + if(pLed->bLedNoLinkBlinkInProgress == TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = FALSE; + } + if( pLed->bLedLinkBlinkInProgress == TRUE ) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = FALSE; + } + if(pLed->bLedBlinkInProgress ==TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + pLed->bLedScanBlinkInProgress = TRUE; + pLed->CurrLedState = LED_SCAN_BLINK; + pLed->BlinkTimes = 24; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA)); + + } + break; + + case LED_CTL_TX: + case LED_CTL_RX: + if(pLed->bLedBlinkInProgress ==FALSE) + { + if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) + { + } + if(pLed->bLedNoLinkBlinkInProgress == TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = FALSE; + } + if( pLed->bLedLinkBlinkInProgress == TRUE ) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = FALSE; + } + pLed->bLedBlinkInProgress = TRUE; + pLed->CurrLedState = LED_TXRX_BLINK; + pLed->BlinkTimes = 2; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA)); + } + break; + + case LED_CTL_START_WPS: + case LED_CTL_START_WPS_BOTTON: + if(pLed->bLedWPSBlinkInProgress ==FALSE) + { + if(pLed->bLedNoLinkBlinkInProgress == TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = FALSE; + } + if( pLed->bLedLinkBlinkInProgress == TRUE ) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = FALSE; + } + if(pLed->bLedBlinkInProgress ==TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + if(pLed->bLedScanBlinkInProgress ==TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = FALSE; + } + pLed->bLedWPSBlinkInProgress = TRUE; + pLed->CurrLedState = LED_BLINK_WPS; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA)); + + } + break; + + + case LED_CTL_STOP_WPS: + if(pLed->bLedNoLinkBlinkInProgress == TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = FALSE; + } + if( pLed->bLedLinkBlinkInProgress == TRUE ) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = FALSE; + } + if(pLed->bLedBlinkInProgress ==TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + if(pLed->bLedScanBlinkInProgress ==TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = FALSE; + } + if(pLed->bLedWPSBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + } + else + { + pLed->bLedWPSBlinkInProgress = TRUE; + } + + pLed->CurrLedState = LED_BLINK_WPS_STOP; + if(pLed->bLedOn) + { + pLed->BlinkingLedState = LED_OFF; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA)); + } + else + { + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), 0); + } + break; + + case LED_CTL_STOP_WPS_FAIL: + if(pLed->bLedWPSBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = FALSE; + } + + pLed->bLedNoLinkBlinkInProgress = TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = LED_OFF; + if( pLed->bLedNoLinkBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = FALSE; + } + if( pLed->bLedLinkBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = FALSE; + } + if( pLed->bLedBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + if( pLed->bLedWPSBlinkInProgress ) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = FALSE; + } + if( pLed->bLedScanBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = FALSE; + } + + SwLedOff(dev, pLed); + break; + + default: + break; + + } + + RT_TRACE(COMP_LED, "Led %d\n", pLed->CurrLedState); +} + +void +SwLedControlMode2( + struct net_device *dev, + LED_CTL_MODE LedAction +) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + PLED_819xUsb pLed = &(priv->SwLed0); + + switch(LedAction) + { + case LED_CTL_SITE_SURVEY: + if(priv->ieee80211->LinkDetectInfo.bBusyTraffic) + ; + else if(pLed->bLedScanBlinkInProgress ==FALSE) + { + if(IS_LED_WPS_BLINKING(pLed)) + return; + + if(pLed->bLedBlinkInProgress ==TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + pLed->bLedScanBlinkInProgress = TRUE; + pLed->CurrLedState = LED_SCAN_BLINK; + pLed->BlinkTimes = 24; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA)); + + } + break; + + case LED_CTL_TX: + case LED_CTL_RX: + if((pLed->bLedBlinkInProgress ==FALSE) && (priv->ieee80211->state == IEEE80211_LINKED)) + { + if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + + pLed->bLedBlinkInProgress = TRUE; + pLed->CurrLedState = LED_TXRX_BLINK; + pLed->BlinkTimes = 2; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA)); + } + break; + + case LED_CTL_LINK: + pLed->CurrLedState = LED_ON; + pLed->BlinkingLedState = LED_ON; + if( pLed->bLedBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + if( pLed->bLedScanBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = FALSE; + } + + mod_timer(&(pLed->BlinkTimer), 0); + break; + + case LED_CTL_START_WPS: + case LED_CTL_START_WPS_BOTTON: + if(pLed->bLedWPSBlinkInProgress ==FALSE) + { + if(pLed->bLedBlinkInProgress ==TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + if(pLed->bLedScanBlinkInProgress ==TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = FALSE; + } + pLed->bLedWPSBlinkInProgress = TRUE; + pLed->CurrLedState = LED_ON; + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), 0); + } + break; + + case LED_CTL_STOP_WPS: + pLed->bLedWPSBlinkInProgress = FALSE; + if( priv->ieee80211->eRFPowerState != eRfOn ) + { + SwLedOff(dev, pLed); + } + else + { + pLed->CurrLedState = LED_ON; + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), 0); + RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState); + } + break; + + case LED_CTL_STOP_WPS_FAIL: + pLed->bLedWPSBlinkInProgress = FALSE; + if( priv->ieee80211->eRFPowerState != eRfOn ) + { + SwLedOff(dev, pLed); + } + else + { + pLed->CurrLedState = LED_OFF; + pLed->BlinkingLedState = LED_OFF; + mod_timer(&(pLed->BlinkTimer), 0); + RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState); + } + break; + + case LED_CTL_START_TO_LINK: + case LED_CTL_NO_LINK: + if(!IS_LED_BLINKING(pLed)) + { + pLed->CurrLedState = LED_OFF; + pLed->BlinkingLedState = LED_OFF; + mod_timer(&(pLed->BlinkTimer), 0); + } + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = LED_OFF; + pLed->BlinkingLedState = LED_OFF; + if( pLed->bLedBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + if( pLed->bLedScanBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = FALSE; + } + if( pLed->bLedWPSBlinkInProgress ) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = FALSE; + } + + mod_timer(&(pLed->BlinkTimer), 0); + break; + + default: + break; + + } + + RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState); +} + + void + SwLedControlMode3( + struct net_device *dev, + LED_CTL_MODE LedAction +) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + PLED_819xUsb pLed = &(priv->SwLed0); + + switch(LedAction) + { + case LED_CTL_SITE_SURVEY: + if(priv->ieee80211->LinkDetectInfo.bBusyTraffic) + ; + else if(pLed->bLedScanBlinkInProgress ==FALSE) + { + if(IS_LED_WPS_BLINKING(pLed)) + return; + + if(pLed->bLedBlinkInProgress ==TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + pLed->bLedScanBlinkInProgress = TRUE; + pLed->CurrLedState = LED_SCAN_BLINK; + pLed->BlinkTimes = 24; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA)); + + } + break; + + case LED_CTL_TX: + case LED_CTL_RX: + if((pLed->bLedBlinkInProgress ==FALSE) && (priv->ieee80211->state == IEEE80211_LINKED)) + { + if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + + pLed->bLedBlinkInProgress = TRUE; + pLed->CurrLedState = LED_TXRX_BLINK; + pLed->BlinkTimes = 2; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA)); + } + break; + + case LED_CTL_LINK: + if(IS_LED_WPS_BLINKING(pLed)) + return; + + pLed->CurrLedState = LED_ON; + pLed->BlinkingLedState = LED_ON; + if( pLed->bLedBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + if( pLed->bLedScanBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = FALSE; + } + + mod_timer(&(pLed->BlinkTimer), 0); + break; + + case LED_CTL_START_WPS: + case LED_CTL_START_WPS_BOTTON: + if(pLed->bLedWPSBlinkInProgress ==FALSE) + { + if(pLed->bLedBlinkInProgress ==TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + if(pLed->bLedScanBlinkInProgress ==TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = FALSE; + } + pLed->bLedWPSBlinkInProgress = TRUE; + pLed->CurrLedState = LED_BLINK_WPS; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA)); + + } + break; + + case LED_CTL_STOP_WPS: + if(pLed->bLedWPSBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = FALSE; + } + else + { + pLed->bLedWPSBlinkInProgress = TRUE; + } + + pLed->CurrLedState = LED_BLINK_WPS_STOP; + if(pLed->bLedOn) + { + pLed->BlinkingLedState = LED_OFF; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA)); + } + else + { + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), 0); + } + + break; + + + case LED_CTL_STOP_WPS_FAIL: + if(pLed->bLedWPSBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = FALSE; + } + + pLed->CurrLedState = LED_OFF; + pLed->BlinkingLedState = LED_OFF; + mod_timer(&(pLed->BlinkTimer), 0); + break; + + case LED_CTL_START_TO_LINK: + case LED_CTL_NO_LINK: + if(!IS_LED_BLINKING(pLed)) + { + pLed->CurrLedState = LED_OFF; + pLed->BlinkingLedState = LED_OFF; + mod_timer(&(pLed->BlinkTimer), 0); + } + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = LED_OFF; + pLed->BlinkingLedState = LED_OFF; + if( pLed->bLedBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + if( pLed->bLedScanBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = FALSE; + } + if( pLed->bLedWPSBlinkInProgress ) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = FALSE; + } + + mod_timer(&(pLed->BlinkTimer), 0); + break; + + default: + break; + + } + + RT_TRACE(COMP_LED, "CurrLedState %d\n", pLed->CurrLedState); +} + + +void +SwLedControlMode4( + struct net_device *dev, + LED_CTL_MODE LedAction +) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + PLED_819xUsb pLed = &(priv->SwLed0); + PLED_819xUsb pLed1 = &(priv->SwLed1); + + switch(LedAction) + { + case LED_CTL_START_TO_LINK: + if(pLed1->bLedWPSBlinkInProgress) + { + pLed1->bLedWPSBlinkInProgress = FALSE; + del_timer_sync(&(pLed1->BlinkTimer)); + + pLed1->BlinkingLedState = LED_OFF; + pLed1->CurrLedState = LED_OFF; + + if(pLed1->bLedOn) + mod_timer(&(pLed1->BlinkTimer), 0); + } + + if( pLed->bLedStartToLinkBlinkInProgress == FALSE ) + { + if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + if(pLed->bLedBlinkInProgress ==TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + if(pLed->bLedNoLinkBlinkInProgress ==TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = FALSE; + } + + pLed->bLedStartToLinkBlinkInProgress = TRUE; + pLed->CurrLedState = LED_BLINK_StartToBlink; + if( pLed->bLedOn ) + { + pLed->BlinkingLedState = LED_OFF; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL)); + } + else + { + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL)); + } + } + break; + + case LED_CTL_LINK: + case LED_CTL_NO_LINK: + if(LedAction == LED_CTL_LINK) + { + if(pLed1->bLedWPSBlinkInProgress) + { + pLed1->bLedWPSBlinkInProgress = FALSE; + del_timer_sync(&(pLed1->BlinkTimer)); + + pLed1->BlinkingLedState = LED_OFF; + pLed1->CurrLedState = LED_OFF; + + if(pLed1->bLedOn) + mod_timer(&(pLed1->BlinkTimer), 0); + } + } + + if( pLed->bLedNoLinkBlinkInProgress == FALSE ) + { + if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + if(pLed->bLedBlinkInProgress ==TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + + pLed->bLedNoLinkBlinkInProgress = TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); + } + + break; + + case LED_CTL_SITE_SURVEY: + if((priv->ieee80211->LinkDetectInfo.bBusyTraffic) && (priv->ieee80211->state == IEEE80211_LINKED)) + ; + else if(pLed->bLedScanBlinkInProgress ==FALSE) + { + if(IS_LED_WPS_BLINKING(pLed)) + return; + + if(pLed->bLedNoLinkBlinkInProgress == TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = FALSE; + } + if(pLed->bLedBlinkInProgress ==TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + pLed->bLedScanBlinkInProgress = TRUE; + pLed->CurrLedState = LED_SCAN_BLINK; + pLed->BlinkTimes = 24; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA)); + + } + break; + + case LED_CTL_TX: + case LED_CTL_RX: + if(pLed->bLedBlinkInProgress ==FALSE) + { + if(pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) + { + return; + } + if(pLed->bLedNoLinkBlinkInProgress == TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = FALSE; + } + pLed->bLedBlinkInProgress = TRUE; + pLed->CurrLedState = LED_TXRX_BLINK; + pLed->BlinkTimes = 2; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA)); + } + break; + + case LED_CTL_START_WPS: + case LED_CTL_START_WPS_BOTTON: + if(pLed1->bLedWPSBlinkInProgress) + { + pLed1->bLedWPSBlinkInProgress = FALSE; + del_timer_sync(&(pLed1->BlinkTimer)); + + pLed1->BlinkingLedState = LED_OFF; + pLed1->CurrLedState = LED_OFF; + + if(pLed1->bLedOn) + mod_timer(&(pLed1->BlinkTimer), 0); + } + + if(pLed->bLedWPSBlinkInProgress ==FALSE) + { + if(pLed->bLedNoLinkBlinkInProgress == TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = FALSE; + } + if(pLed->bLedBlinkInProgress ==TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + if(pLed->bLedScanBlinkInProgress ==TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = FALSE; + } + pLed->bLedWPSBlinkInProgress = TRUE; + pLed->CurrLedState = LED_BLINK_WPS; + if( pLed->bLedOn ) + { + pLed->BlinkingLedState = LED_OFF; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SLOWLY_INTERVAL)); + } + else + { + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL)); + } + + } + break; + + case LED_CTL_STOP_WPS: + if(pLed->bLedWPSBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = FALSE; + } + + pLed->bLedNoLinkBlinkInProgress = TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); + + break; + + case LED_CTL_STOP_WPS_FAIL: + if(pLed->bLedWPSBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = FALSE; + } + + pLed->bLedNoLinkBlinkInProgress = TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); + + if(pLed1->bLedWPSBlinkInProgress) + del_timer_sync(&(pLed1->BlinkTimer)); + else + pLed1->bLedWPSBlinkInProgress = TRUE; + + pLed1->CurrLedState = LED_BLINK_WPS_STOP; + if( pLed1->bLedOn ) + pLed1->BlinkingLedState = LED_OFF; + else + pLed1->BlinkingLedState = LED_ON; + mod_timer(&(pLed1->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL)); + + break; + + case LED_CTL_STOP_WPS_FAIL_OVERLAP: + if(pLed->bLedWPSBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = FALSE; + } + + pLed->bLedNoLinkBlinkInProgress = TRUE; + pLed->CurrLedState = LED_BLINK_SLOWLY; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_NO_LINK_INTERVAL_ALPHA)); + + if(pLed1->bLedWPSBlinkInProgress) + del_timer_sync(&(pLed1->BlinkTimer)); + else + pLed1->bLedWPSBlinkInProgress = TRUE; + + pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP; + pLed1->BlinkTimes = 10; + if( pLed1->bLedOn ) + pLed1->BlinkingLedState = LED_OFF; + else + pLed1->BlinkingLedState = LED_ON; + mod_timer(&(pLed1->BlinkTimer), jiffies + MSECS(LED_BLINK_NORMAL_INTERVAL)); + + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = LED_OFF; + pLed->BlinkingLedState = LED_OFF; + + if( pLed->bLedNoLinkBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedNoLinkBlinkInProgress = FALSE; + } + if( pLed->bLedLinkBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedLinkBlinkInProgress = FALSE; + } + if( pLed->bLedBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + if( pLed->bLedWPSBlinkInProgress ) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedWPSBlinkInProgress = FALSE; + } + if( pLed->bLedScanBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedScanBlinkInProgress = FALSE; + } + if( pLed->bLedStartToLinkBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedStartToLinkBlinkInProgress = FALSE; + } + + if( pLed1->bLedWPSBlinkInProgress ) + { + del_timer_sync(&(pLed1->BlinkTimer)); + pLed1->bLedWPSBlinkInProgress = FALSE; + } + + + pLed1->BlinkingLedState = LED_UNKNOWN; + SwLedOff(dev, pLed); + SwLedOff(dev, pLed1); + break; + + default: + break; + + } + + RT_TRACE(COMP_LED, "Led %d\n", pLed->CurrLedState); +} + + + +void +SwLedControlMode5( + struct net_device *dev, + LED_CTL_MODE LedAction +) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + PLED_819xUsb pLed = &(priv->SwLed0); + + if(priv->CustomerID == RT_CID_819x_CAMEO) + pLed = &(priv->SwLed1); + + switch(LedAction) + { + case LED_CTL_POWER_ON: + case LED_CTL_NO_LINK: + case LED_CTL_LINK: + if(pLed->CurrLedState == LED_SCAN_BLINK) + { + return; + } + pLed->CurrLedState = LED_ON; + pLed->BlinkingLedState = LED_ON; + pLed->bLedBlinkInProgress = FALSE; + mod_timer(&(pLed->BlinkTimer), 0); + break; + + case LED_CTL_SITE_SURVEY: + if((priv->ieee80211->LinkDetectInfo.bBusyTraffic) && (priv->ieee80211->state == IEEE80211_LINKED)) + ; + else if(pLed->bLedScanBlinkInProgress ==FALSE) + { + if(pLed->bLedBlinkInProgress ==TRUE) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + pLed->bLedScanBlinkInProgress = TRUE; + pLed->CurrLedState = LED_SCAN_BLINK; + pLed->BlinkTimes = 24; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_SCAN_INTERVAL_ALPHA)); + + } + break; + + case LED_CTL_TX: + case LED_CTL_RX: + if(pLed->bLedBlinkInProgress ==FALSE) + { + if(pLed->CurrLedState == LED_SCAN_BLINK) + { + return; + } + pLed->bLedBlinkInProgress = TRUE; + pLed->CurrLedState = LED_TXRX_BLINK; + pLed->BlinkTimes = 2; + if( pLed->bLedOn ) + pLed->BlinkingLedState = LED_OFF; + else + pLed->BlinkingLedState = LED_ON; + mod_timer(&(pLed->BlinkTimer), jiffies + MSECS(LED_BLINK_FASTER_INTERVAL_ALPHA)); + } + break; + + case LED_CTL_POWER_OFF: + pLed->CurrLedState = LED_OFF; + pLed->BlinkingLedState = LED_OFF; + + if( pLed->bLedBlinkInProgress) + { + del_timer_sync(&(pLed->BlinkTimer)); + pLed->bLedBlinkInProgress = FALSE; + } + + SwLedOff(dev, pLed); + break; + + default: + break; + + } + + RT_TRACE(COMP_LED, "Led %d\n", pLed->CurrLedState); +} + + +void +LedControl8192SUsb( + struct net_device *dev, + LED_CTL_MODE LedAction + ) +{ + struct r8192_priv *priv = ieee80211_priv(dev); + + if( priv->bRegUseLed == FALSE) + return; + + if (!priv->up) + return; + + if(priv->bInHctTest) + return; + + if( priv->ieee80211->eRFPowerState != eRfOn && + (LedAction == LED_CTL_TX || LedAction == LED_CTL_RX || + LedAction == LED_CTL_SITE_SURVEY || + LedAction == LED_CTL_LINK || + LedAction == LED_CTL_NO_LINK || + LedAction == LED_CTL_POWER_ON) ) + { + return; + } + + switch(priv->LedStrategy) + { + case SW_LED_MODE0: + break; + + case SW_LED_MODE1: + SwLedControlMode1(dev, LedAction); + break; + case SW_LED_MODE2: + SwLedControlMode2(dev, LedAction); + break; + + case SW_LED_MODE3: + SwLedControlMode3(dev, LedAction); + break; + + case SW_LED_MODE4: + SwLedControlMode4(dev, LedAction); + break; + + case SW_LED_MODE5: + SwLedControlMode5(dev, LedAction); + break; + + default: + break; + } + + RT_TRACE(COMP_LED, "LedStrategy:%d, LedAction %d\n", priv->LedStrategy,LedAction); +} + + diff --git a/drivers/staging/rtl8192su/r8192SU_led.h b/drivers/staging/rtl8192su/r8192SU_led.h new file mode 100644 index 000000000000..acedae4a59ca --- /dev/null +++ b/drivers/staging/rtl8192su/r8192SU_led.h @@ -0,0 +1,93 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae +******************************************************************************/ +#ifndef __INC_HAL8192USBLED_H +#define __INC_HAL8192USBLED_H + +#include +#include + +typedef enum _LED_STATE_819xUsb{ + LED_UNKNOWN = 0, + LED_ON = 1, + LED_OFF = 2, + LED_BLINK_NORMAL = 3, + LED_BLINK_SLOWLY = 4, + LED_POWER_ON_BLINK = 5, + LED_SCAN_BLINK = 6, + LED_NO_LINK_BLINK = 7, + LED_BLINK_StartToBlink = 8, + LED_BLINK_WPS = 9, + LED_TXRX_BLINK = 10, + LED_BLINK_WPS_STOP = 11, + LED_BLINK_WPS_STOP_OVERLAP = 12, + +}LED_STATE_819xUsb; + +#define IS_LED_WPS_BLINKING(_LED_819xUsb) (((PLED_819xUsb)_LED_819xUsb)->CurrLedState==LED_BLINK_WPS \ + || ((PLED_819xUsb)_LED_819xUsb)->CurrLedState==LED_BLINK_WPS_STOP \ + || ((PLED_819xUsb)_LED_819xUsb)->bLedWPSBlinkInProgress) + +#define IS_LED_BLINKING(_LED_819xUsb) (((PLED_819xUsb)_LED_819xUsb)->bLedWPSBlinkInProgress \ + ||((PLED_819xUsb)_LED_819xUsb)->bLedScanBlinkInProgress) + +typedef enum _LED_PIN_819xUsb{ + LED_PIN_GPIO0, + LED_PIN_LED0, + LED_PIN_LED1 +}LED_PIN_819xUsb; + +typedef enum _LED_STRATEGY_819xUsb{ + SW_LED_MODE0, /* SW control 1 LED via GPIO0. It is default option. */ + SW_LED_MODE1, /* SW control for PCI Express */ + SW_LED_MODE2, /* SW control for Cameo. */ + SW_LED_MODE3, /* SW contorl for RunTop. */ + SW_LED_MODE4, /* SW control for Netcore */ + SW_LED_MODE5, + HW_LED, /* HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes) */ +}LED_STRATEGY_819xUsb, *PLED_STRATEGY_819xUsb; + +typedef struct _LED_819xUsb{ + struct net_device *dev; + + LED_PIN_819xUsb LedPin; + + LED_STATE_819xUsb CurrLedState; + bool bLedOn; + + bool bSWLedCtrl; + + bool bLedBlinkInProgress; + bool bLedNoLinkBlinkInProgress; + bool bLedLinkBlinkInProgress; + bool bLedStartToLinkBlinkInProgress; + bool bLedScanBlinkInProgress; + bool bLedWPSBlinkInProgress; + + u32 BlinkTimes; + LED_STATE_819xUsb BlinkingLedState; + + struct timer_list BlinkTimer; +} LED_819xUsb, *PLED_819xUsb; + +void InitSwLeds(struct net_device *dev); +void DeInitSwLeds(struct net_device *dev); +void LedControl8192SUsb(struct net_device *dev,LED_CTL_MODE LedAction); + +#endif + diff --git a/drivers/staging/rtl8192su/r8192U.h b/drivers/staging/rtl8192su/r8192U.h index 4112e149a327..eccf4478fba8 100644 --- a/drivers/staging/rtl8192su/r8192U.h +++ b/drivers/staging/rtl8192su/r8192U.h @@ -43,6 +43,7 @@ #include "ieee80211/ieee80211.h" #include "r8192S_firmware.h" +#include "r8192SU_led.h" /* EEPROM defs for use with linux/eeprom_93cx6.h */ #define RTL819X_EEPROM_CMD_READ (1 << 0) @@ -1067,19 +1068,6 @@ typedef enum _RT_CUSTOMER_ID RT_CID_PRONET = 13, }RT_CUSTOMER_ID, *PRT_CUSTOMER_ID; -//================================================================================ -// LED customization. -//================================================================================ - -typedef enum _LED_STRATEGY_8190{ - SW_LED_MODE0, // SW control 1 LED via GPIO0. It is default option. - SW_LED_MODE1, // SW control for PCI Express - SW_LED_MODE2, // SW control for Cameo. - SW_LED_MODE3, // SW contorl for RunTop. - SW_LED_MODE4, // SW control for Netcore - HW_LED, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes) -}LED_STRATEGY_8190, *PLED_STRATEGY_8190; - typedef enum _RESET_TYPE { RESET_TYPE_NORESET = 0x00, RESET_TYPE_NORMAL = 0x01, @@ -1131,7 +1119,7 @@ typedef struct r8192_priv u8 eeprom_SubCustomerID; u8 eeprom_ChannelPlan; RT_CUSTOMER_ID CustomerID; - LED_STRATEGY_8190 LedStrategy; + LED_STRATEGY_819xUsb LedStrategy; u8 txqueue_to_outpipemap[9]; u8 RtOutPipes[16]; u8 RtInPipes[16]; @@ -1501,8 +1489,17 @@ typedef struct r8192_priv u8 MinSpaceCfg; u16 rf_pathmap; -//#endif + /* added for led control */ + PLED_819xUsb pLed; + LED_819xUsb SwLed0; + LED_819xUsb SwLed1; + u8 bRegUseLed; + struct work_struct BlinkWorkItem; + /* added for led control */ + u16 FwCmdIOMap; + u32 FwCmdIOParam; + u8 DMFlag; -- cgit v1.2.3 From 3dfe08e6073f40a742fe3e5d6b43ca8184c55722 Mon Sep 17 00:00:00 2001 From: Florian Schilhabel Date: Thu, 13 May 2010 13:55:52 +0200 Subject: Staging: rtl8192su: led update derived from Realteks driver. leds are now working. Signed-off-by: Florian Schilhabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192su/r8192U_core.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index 70a8087434d4..78af0d7141a6 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c @@ -1219,6 +1219,7 @@ void rtl8192_set_mode(struct net_device *dev,int mode) void rtl8192_update_msr(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); + LED_CTL_MODE LedAction = LED_CTL_NO_LINK; u8 msr; msr = read_nic_byte(dev, MSR); @@ -1229,19 +1230,23 @@ void rtl8192_update_msr(struct net_device *dev) * this is intentional and make sense for ad-hoc and * master (see the create BSS/IBSS func) */ - if (priv->ieee80211->state == IEEE80211_LINKED){ + if (priv->ieee80211->state == IEEE80211_LINKED) { - if (priv->ieee80211->iw_mode == IW_MODE_INFRA) + if (priv->ieee80211->iw_mode == IW_MODE_INFRA) { msr |= (MSR_LINK_MANAGED<ieee80211->iw_mode == IW_MODE_ADHOC) + LedAction = LED_CTL_LINK; + } else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) msr |= (MSR_LINK_ADHOC<ieee80211->iw_mode == IW_MODE_MASTER) msr |= (MSR_LINK_MASTER<ieee80211->LedControlHandler != NULL) + priv->ieee80211->LedControlHandler(dev, LedAction); } void rtl8192_set_chan(struct net_device *dev,short ch) @@ -2154,15 +2159,13 @@ short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb) struct r8192_priv *priv = ieee80211_priv(dev); cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data; - //tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);//92su del struct usb_device *udev = priv->udev; int pend; int status; struct urb *tx_urb = NULL, *tx_urb_zero = NULL; - //int urb_len; unsigned int idx_pipe; - u16 MPDUOverhead = 0; - //RT_DEBUG_DATA(COMP_SEND, tcb_desc, sizeof(cb_desc)); + u16 MPDUOverhead = 0; + u16 type = 0; pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]); /* we are locked here so the two atomic_read and inc are executed @@ -2359,6 +2362,11 @@ short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb) skb->data, skb->len, rtl8192_tx_isr, skb); + if (type == IEEE80211_FTYPE_DATA) { + if (priv->ieee80211->LedControlHandler != NULL) + priv->ieee80211->LedControlHandler(dev, LED_CTL_TX); + } + status = usb_submit_urb(tx_urb, GFP_ATOMIC); if (!status) { /* @@ -5487,6 +5495,9 @@ void rtl819x_watchdog_wqcallback(struct work_struct *work) priv->ieee80211->current_network.bssid); ieee->is_roaming = true; priv->ieee80211->link_change(dev); + if(ieee->LedControlHandler != NULL) + ieee->LedControlHandler(ieee->dev, + LED_CTL_START_TO_LINK); queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq); } -- cgit v1.2.3 From fd4dc88e46c4d9dd845ffef50a975ceea110fd85 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Thu, 13 May 2010 15:56:30 +0000 Subject: staging: hv: Fix error checking in channel.c Fixed errors in return value checking code, which caused vmbus channel not functioning. Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Cc: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index 12c351e16360..f047c5a7f64c 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -204,13 +204,13 @@ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, RecvRingBufferSize) >> PAGE_SHIFT; ret = RingBufferInit(&NewChannel->Outbound, out, SendRingBufferSize); - if (!ret) { + if (ret != 0) { err = ret; goto errorout; } ret = RingBufferInit(&NewChannel->Inbound, in, RecvRingBufferSize); - if (!ret) { + if (ret != 0) { err = ret; goto errorout; } @@ -228,7 +228,7 @@ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, RecvRingBufferSize, &NewChannel->RingBufferGpadlHandle); - if (!ret) { + if (ret != 0) { err = ret; goto errorout; } @@ -569,7 +569,7 @@ int VmbusChannelEstablishGpadl(struct vmbus_channel *Channel, void *Kbuffer, ret = VmbusPostMessage(gpadlBody, subMsgInfo->MessageSize - sizeof(*subMsgInfo)); - if (!ret) + if (ret != 0) goto Cleanup; } -- cgit v1.2.3 From bbfb56520c8da666383c08220985495ff918d4ad Mon Sep 17 00:00:00 2001 From: "Prashant P. Shah" Date: Thu, 13 May 2010 23:08:43 +0530 Subject: Staging: rtl8187se: fixed space style issues in r8180_core.c This is a patch to the r8180_core.c file that fixes the space style issues found by the checkpatch.pl tool. Signed-off-by: Prashant P. Shah Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_core.c | 1622 ++++++++++++++++---------------- 1 file changed, 806 insertions(+), 816 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 84a745bb9ca0..37be5aedf52f 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -66,23 +66,23 @@ static int hwseqnum = 0; static int hwwep = 0; static int channels = 0x3fff; -#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 ) -#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5]) +#define eqMacAddr(a, b) (((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == (b)[2] && (a)[3] == (b)[3] && (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1 : 0) +#define cpMacAddr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], (des)[2] = (src)[2], (des)[3] = (src)[3], (des)[4] = (src)[4], (des)[5] = (src)[5]) MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, rtl8180_pci_id_tbl); MODULE_AUTHOR("Andrea Merello "); MODULE_DESCRIPTION("Linux driver for Realtek RTL8180 / RTL8185 WiFi cards"); -module_param(ifname, charp, S_IRUGO|S_IWUSR ); -module_param(hwseqnum,int, S_IRUGO|S_IWUSR); -module_param(hwwep,int, S_IRUGO|S_IWUSR); -module_param(channels,int, S_IRUGO|S_IWUSR); +module_param(ifname, charp, S_IRUGO|S_IWUSR); +module_param(hwseqnum, int, S_IRUGO|S_IWUSR); +module_param(hwwep, int, S_IRUGO|S_IWUSR); +module_param(channels, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(devname," Net interface name, wlan%d=default"); -MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default"); -MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards"); -MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI"); +MODULE_PARM_DESC(devname, " Net interface name, wlan%d=default"); +MODULE_PARM_DESC(hwseqnum, " Try to use hardware 802.11 header sequence numbers. Zero=default"); +MODULE_PARM_DESC(hwwep, " Try to use hardware WEP support. Still broken and not available on all cards"); +MODULE_PARM_DESC(channels, " Channel bitmask for specific locales. NYI"); static int __devinit rtl8180_pci_probe(struct pci_dev *pdev, @@ -90,7 +90,7 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev, static void __devexit rtl8180_pci_remove(struct pci_dev *pdev); -static void rtl8180_shutdown (struct pci_dev *pdev) +static void rtl8180_shutdown(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); if (dev->netdev_ops->ndo_stop) @@ -181,19 +181,19 @@ u16 read_nic_word(struct net_device *dev, int x) return readw((u8 *)dev->mem_start + x); } -void write_nic_byte(struct net_device *dev, int x,u8 y) +void write_nic_byte(struct net_device *dev, int x, u8 y) { writeb(y, (u8 *)dev->mem_start + x); udelay(20); } -void write_nic_dword(struct net_device *dev, int x,u32 y) +void write_nic_dword(struct net_device *dev, int x, u32 y) { writel(y, (u8 *)dev->mem_start + x); udelay(20); } -void write_nic_word(struct net_device *dev, int x,u16 y) +void write_nic_word(struct net_device *dev, int x, u16 y) { writew(y, (u8 *)dev->mem_start + x); udelay(20); @@ -201,7 +201,7 @@ void write_nic_word(struct net_device *dev, int x,u16 y) inline void force_pci_posting(struct net_device *dev) { - read_nic_byte(dev,EPROM_CMD); + read_nic_byte(dev, EPROM_CMD); mb(); } @@ -220,7 +220,7 @@ static int proc_get_registers(char *page, char **start, { struct net_device *dev = data; int len = 0; - int i,n; + int i, n; int max = 0xff; /* This dump the current register page */ @@ -231,7 +231,7 @@ static int proc_get_registers(char *page, char **start, len += snprintf(page + len, count - len, "%2x ", read_nic_byte(dev, n)); } - len += snprintf(page + len, count - len,"\n"); + len += snprintf(page + len, count - len, "\n"); *eof = 1; return len; @@ -287,7 +287,7 @@ static int proc_get_stats_tx(char *page, char **start, int len = 0; unsigned long totalOK; - totalOK=priv->stats.txnpokint+priv->stats.txhpokint+priv->stats.txlpokint; + totalOK = priv->stats.txnpokint+priv->stats.txhpokint+priv->stats.txlpokint; len += snprintf(page + len, count - len, "TX OK: %lu\n" "TX Error: %lu\n" @@ -308,7 +308,7 @@ static int proc_get_stats_tx(char *page, char **start, void rtl8180_proc_module_init(void) { DMESG("Initializing proc filesystem"); - rtl8180_proc=create_proc_entry(RTL8180_MODULE_NAME, S_IFDIR, init_net.proc_net); + rtl8180_proc = create_proc_entry(RTL8180_MODULE_NAME, S_IFDIR, init_net.proc_net); } void rtl8180_proc_module_remove(void) @@ -385,81 +385,81 @@ short buffer_add(struct buffer **buffer, u32 *buf, dma_addr_t dma, { struct buffer *tmp; - if(! *buffer){ + if (!*buffer) { - *buffer = kmalloc(sizeof(struct buffer),GFP_KERNEL); + *buffer = kmalloc(sizeof(struct buffer), GFP_KERNEL); if (*buffer == NULL) { DMESGE("Failed to kmalloc head of TX/RX struct"); return -1; } - (*buffer)->next=*buffer; - (*buffer)->buf=buf; - (*buffer)->dma=dma; - if(bufferhead !=NULL) + (*buffer)->next = *buffer; + (*buffer)->buf = buf; + (*buffer)->dma = dma; + if (bufferhead != NULL) (*bufferhead) = (*buffer); return 0; } - tmp=*buffer; + tmp = *buffer; - while(tmp->next!=(*buffer)) tmp=tmp->next; - tmp->next = kmalloc(sizeof(struct buffer),GFP_KERNEL); + while (tmp->next != (*buffer)) + tmp = tmp->next; + tmp->next = kmalloc(sizeof(struct buffer), GFP_KERNEL); if (tmp->next == NULL) { DMESGE("Failed to kmalloc TX/RX struct"); return -1; } - tmp->next->buf=buf; - tmp->next->dma=dma; - tmp->next->next=*buffer; + tmp->next->buf = buf; + tmp->next->dma = dma; + tmp->next->next = *buffer; return 0; } -void buffer_free(struct net_device *dev,struct buffer **buffer,int len,short -consistent) +void buffer_free(struct net_device *dev, struct buffer **buffer, int len, short consistent) { - struct buffer *tmp,*next; + struct buffer *tmp, *next; struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - struct pci_dev *pdev=priv->pdev; + struct pci_dev *pdev = priv->pdev; if (!*buffer) return; tmp = *buffer; - do{ - next=tmp->next; - if(consistent){ - pci_free_consistent(pdev,len, - tmp->buf,tmp->dma); - }else{ + do { + next = tmp->next; + if (consistent) { + pci_free_consistent(pdev, len, + tmp->buf, tmp->dma); + } else { pci_unmap_single(pdev, tmp->dma, - len,PCI_DMA_FROMDEVICE); + len, PCI_DMA_FROMDEVICE); kfree(tmp->buf); } kfree(tmp); tmp = next; } - while(next != *buffer); + while (next != *buffer); - *buffer=NULL; + *buffer = NULL; } void print_buffer(u32 *buffer, int len) { int i; - u8 *buf =(u8*)buffer; + u8 *buf = (u8 *)buffer; - printk("ASCII BUFFER DUMP (len: %x):\n",len); + printk("ASCII BUFFER DUMP (len: %x):\n", len); - for(i=0;itxmapringhead; - tail = priv->txmapringtail; - break; - case BK_PRIORITY: - head = priv->txbkpringhead; - tail = priv->txbkpringtail; - break; - case BE_PRIORITY: - head = priv->txbepringhead; - tail = priv->txbepringtail; - break; - case VI_PRIORITY: - head = priv->txvipringhead; - tail = priv->txvipringtail; - break; - case VO_PRIORITY: - head = priv->txvopringhead; - tail = priv->txvopringtail; - break; - case HI_PRIORITY: - head = priv->txhpringhead; - tail = priv->txhpringtail; - break; - default: - return -1; + switch (priority) { + case MANAGE_PRIORITY: + head = priv->txmapringhead; + tail = priv->txmapringtail; + break; + case BK_PRIORITY: + head = priv->txbkpringhead; + tail = priv->txbkpringtail; + break; + case BE_PRIORITY: + head = priv->txbepringhead; + tail = priv->txbepringtail; + break; + case VI_PRIORITY: + head = priv->txvipringhead; + tail = priv->txvipringtail; + break; + case VO_PRIORITY: + head = priv->txvopringhead; + tail = priv->txvopringtail; + break; + case HI_PRIORITY: + head = priv->txhpringhead; + tail = priv->txhpringtail; + break; + default: + return -1; } if (head <= tail) @@ -531,7 +531,7 @@ short check_nic_enought_desc(struct net_device *dev, int priority) * between the tail and the head */ - return (required+2 < get_curr_tx_free_desc(dev,priority)); + return (required+2 < get_curr_tx_free_desc(dev, priority)); } void fix_tx_fifo(struct net_device *dev) @@ -540,45 +540,45 @@ void fix_tx_fifo(struct net_device *dev) u32 *tmp; int i; - for (tmp=priv->txmapring, i=0; + for (tmp = priv->txmapring, i = 0; i < priv->txringcount; - tmp+=8, i++){ - *tmp = *tmp &~ (1<<31); + tmp += 8, i++) { + *tmp = *tmp & ~(1<<31); } - for (tmp=priv->txbkpring, i=0; + for (tmp = priv->txbkpring, i = 0; i < priv->txringcount; - tmp+=8, i++) { - *tmp = *tmp &~ (1<<31); + tmp += 8, i++) { + *tmp = *tmp & ~(1<<31); } - for (tmp=priv->txbepring, i=0; + for (tmp = priv->txbepring, i = 0; i < priv->txringcount; - tmp+=8, i++){ - *tmp = *tmp &~ (1<<31); + tmp += 8, i++) { + *tmp = *tmp & ~(1<<31); } - for (tmp=priv->txvipring, i=0; + for (tmp = priv->txvipring, i = 0; i < priv->txringcount; - tmp+=8, i++) { - *tmp = *tmp &~ (1<<31); + tmp += 8, i++) { + *tmp = *tmp & ~(1<<31); } - for (tmp=priv->txvopring, i=0; + for (tmp = priv->txvopring, i = 0; i < priv->txringcount; - tmp+=8, i++){ - *tmp = *tmp &~ (1<<31); + tmp += 8, i++) { + *tmp = *tmp & ~(1<<31); } - for (tmp=priv->txhpring, i=0; + for (tmp = priv->txhpring, i = 0; i < priv->txringcount; - tmp+=8,i++){ - *tmp = *tmp &~ (1<<31); + tmp += 8, i++) { + *tmp = *tmp & ~(1<<31); } - for (tmp=priv->txbeaconring, i=0; + for (tmp = priv->txbeaconring, i = 0; i < priv->txbeaconcount; - tmp+=8, i++){ - *tmp = *tmp &~ (1<<31); + tmp += 8, i++) { + *tmp = *tmp & ~(1<<31); } priv->txmapringtail = priv->txmapring; @@ -622,18 +622,18 @@ void fix_rx_fifo(struct net_device *dev) rx_desc_size = 8; // 4*8 = 32 bytes - for (tmp=priv->rxring, rxbuf=priv->rxbufferhead; + for (tmp = priv->rxring, rxbuf = priv->rxbufferhead; (tmp < (priv->rxring)+(priv->rxringcount)*rx_desc_size); - tmp+=rx_desc_size,rxbuf=rxbuf->next){ + tmp += rx_desc_size, rxbuf = rxbuf->next) { *(tmp+2) = rxbuf->dma; - *tmp=*tmp &~ 0xfff; - *tmp=*tmp | priv->rxbuffersize; + *tmp = *tmp & ~0xfff; + *tmp = *tmp | priv->rxbuffersize; *tmp |= (1<<31); } - priv->rxringtail=priv->rxring; - priv->rxbuffer=priv->rxbufferhead; - priv->rx_skb_complete=1; + priv->rxringtail = priv->rxring; + priv->rxbuffer = priv->rxbufferhead; + priv->rx_skb_complete = 1; set_nic_rxring(dev); } @@ -678,20 +678,18 @@ void rtl8180_RSSI_calc(struct net_device *dev, u8 *rssi, u8 *qual) if (q <= 0x4e) { temp = QUALITY_MAP[q]; } else { - if( q & 0x80 ) { + if (q & 0x80) temp = 0x32; - } else { + else temp = 1; - } } *qual = temp; temp2 = *rssi; - if ( _rssi < 0x64 ){ - if ( _rssi == 0 ) { + if (_rssi < 0x64) { + if (_rssi == 0) *rssi = 1; - } } else { *rssi = 0x64; } @@ -704,27 +702,27 @@ void rtl8180_irq_enable(struct net_device *dev) struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); priv->irq_enabled = 1; - write_nic_word(dev,INTA_MASK, priv->irq_mask); + write_nic_word(dev, INTA_MASK, priv->irq_mask); } void rtl8180_irq_disable(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - write_nic_dword(dev,IMR,0); + write_nic_dword(dev, IMR, 0); force_pci_posting(dev); priv->irq_enabled = 0; } -void rtl8180_set_mode(struct net_device *dev,int mode) +void rtl8180_set_mode(struct net_device *dev, int mode) { u8 ecmd; - ecmd=read_nic_byte(dev, EPROM_CMD); - ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK; - ecmd=ecmd | (mode<ieee80211->state == IEEE80211_LINKED) - { - if(priv->ieee80211->iw_mode == IW_MODE_ADHOC) + if (priv->ieee80211->state == IEEE80211_LINKED) { + if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) msr |= (MSR_LINK_ADHOC<ieee80211->iw_mode == IW_MODE_MASTER) msr |= (MSR_LINK_MASTER<chan=ch; - priv->rf_set_chan(dev,priv->chan); + priv->chan = ch; + priv->rf_set_chan(dev, priv->chan); } void rtl8180_rx_enable(struct net_device *dev) @@ -783,8 +780,8 @@ void rtl8180_rx_enable(struct net_device *dev) /* for now we accept data, management & ctl frame*/ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - rxconf=read_nic_dword(dev,RX_CONF); - rxconf = rxconf &~ MAC_FILTER_MASK; + rxconf = read_nic_dword(dev, RX_CONF); + rxconf = rxconf & ~MAC_FILTER_MASK; rxconf = rxconf | (1<flags & IFF_PROMISC) DMESG("NIC in promisc mode"); - if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \ - dev->flags & IFF_PROMISC){ + if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || \ + dev->flags & IFF_PROMISC) { rxconf = rxconf | (1<ieee80211->iw_mode == IW_MODE_MONITOR){ + if (priv->ieee80211->iw_mode == IW_MODE_MONITOR) { rxconf = rxconf | (1<crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR) + if (priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR) rxconf = rxconf | (1<retry_data<retry_rts<hw_plcp_len) txconf = txconf & ~TCR_PLCP_LEN; else txconf = txconf | TCR_PLCP_LEN; - txconf = txconf &~ TCR_MXDMA_MASK; + txconf = txconf & ~TCR_MXDMA_MASK; txconf = txconf | (TCR_MXDMA_2048<dma_poll_stop_mask &= ~(TPPOLLSTOP_BQ); - write_nic_byte(dev,TPPollStop, priv->dma_poll_mask); - rtl8180_set_mode(dev,EPROM_CMD_NORMAL); + write_nic_byte(dev, TPPollStop, priv->dma_poll_mask); + rtl8180_set_mode(dev, EPROM_CMD_NORMAL); } void rtl8180_beacon_tx_disable(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - rtl8180_set_mode(dev,EPROM_CMD_CONFIG); + rtl8180_set_mode(dev, EPROM_CMD_CONFIG); priv->dma_poll_stop_mask |= TPPOLLSTOP_BQ; - write_nic_byte(dev,TPPollStop, priv->dma_poll_stop_mask); - rtl8180_set_mode(dev,EPROM_CMD_NORMAL); + write_nic_byte(dev, TPPollStop, priv->dma_poll_stop_mask); + rtl8180_set_mode(dev, EPROM_CMD_NORMAL); } @@ -940,13 +937,13 @@ void rtl8180_rtx_disable(struct net_device *dev) u8 cmd; struct r8180_priv *priv = ieee80211_priv(dev); - cmd=read_nic_byte(dev,CMD); - write_nic_byte(dev, CMD, cmd &~ \ + cmd = read_nic_byte(dev, CMD); + write_nic_byte(dev, CMD, cmd & ~\ ((1<rx_skb_complete) + if (!priv->rx_skb_complete) dev_kfree_skb_any(priv->rx_skb); } @@ -961,11 +958,11 @@ short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count, struct pci_dev *pdev = priv->pdev; void *buf; - if((bufsize & 0xfff) != bufsize) { - DMESGE ("TX buffer allocation too large"); + if ((bufsize & 0xfff) != bufsize) { + DMESGE("TX buffer allocation too large"); return 0; } - desc = (u32*)pci_alloc_consistent(pdev, + desc = (u32 *)pci_alloc_consistent(pdev, sizeof(u32)*8*count+256, &dma_desc); if (desc == NULL) return -1; @@ -984,90 +981,90 @@ short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count, if (buf == NULL) return -ENOMEM; - switch(addr) { + switch (addr) { case TX_MANAGEPRIORITY_RING_ADDR: - if(-1 == buffer_add(&(priv->txmapbufs),buf,dma_tmp,NULL)){ + if (-1 == buffer_add(&(priv->txmapbufs), buf, dma_tmp, NULL)) { DMESGE("Unable to allocate mem for buffer NP"); return -ENOMEM; } break; case TX_BKPRIORITY_RING_ADDR: - if(-1 == buffer_add(&(priv->txbkpbufs),buf,dma_tmp,NULL)){ + if (-1 == buffer_add(&(priv->txbkpbufs), buf, dma_tmp, NULL)) { DMESGE("Unable to allocate mem for buffer LP"); return -ENOMEM; } break; case TX_BEPRIORITY_RING_ADDR: - if(-1 == buffer_add(&(priv->txbepbufs),buf,dma_tmp,NULL)){ + if (-1 == buffer_add(&(priv->txbepbufs), buf, dma_tmp, NULL)) { DMESGE("Unable to allocate mem for buffer NP"); return -ENOMEM; } break; case TX_VIPRIORITY_RING_ADDR: - if(-1 == buffer_add(&(priv->txvipbufs),buf,dma_tmp,NULL)){ + if (-1 == buffer_add(&(priv->txvipbufs), buf, dma_tmp, NULL)) { DMESGE("Unable to allocate mem for buffer LP"); return -ENOMEM; } break; case TX_VOPRIORITY_RING_ADDR: - if(-1 == buffer_add(&(priv->txvopbufs),buf,dma_tmp,NULL)){ + if (-1 == buffer_add(&(priv->txvopbufs), buf, dma_tmp, NULL)) { DMESGE("Unable to allocate mem for buffer NP"); return -ENOMEM; } break; case TX_HIGHPRIORITY_RING_ADDR: - if(-1 == buffer_add(&(priv->txhpbufs),buf,dma_tmp,NULL)){ + if (-1 == buffer_add(&(priv->txhpbufs), buf, dma_tmp, NULL)) { DMESGE("Unable to allocate mem for buffer HP"); return -ENOMEM; } break; case TX_BEACON_RING_ADDR: - if(-1 == buffer_add(&(priv->txbeaconbufs),buf,dma_tmp,NULL)){ - DMESGE("Unable to allocate mem for buffer BP"); + if (-1 == buffer_add(&(priv->txbeaconbufs), buf, dma_tmp, NULL)) { + DMESGE("Unable to allocate mem for buffer BP"); return -ENOMEM; } break; } - *tmp = *tmp &~ (1<<31); // descriptor empty, owned by the drv + *tmp = *tmp & ~(1<<31); // descriptor empty, owned by the drv *(tmp+2) = (u32)dma_tmp; *(tmp+3) = bufsize; - if(i+1txmapringdma=dma_desc; - priv->txmapring=desc; + priv->txmapringdma = dma_desc; + priv->txmapring = desc; break; case TX_BKPRIORITY_RING_ADDR: - priv->txbkpringdma=dma_desc; - priv->txbkpring=desc; + priv->txbkpringdma = dma_desc; + priv->txbkpring = desc; break; case TX_BEPRIORITY_RING_ADDR: - priv->txbepringdma=dma_desc; - priv->txbepring=desc; + priv->txbepringdma = dma_desc; + priv->txbepring = desc; break; case TX_VIPRIORITY_RING_ADDR: - priv->txvipringdma=dma_desc; - priv->txvipring=desc; + priv->txvipringdma = dma_desc; + priv->txvipring = desc; break; case TX_VOPRIORITY_RING_ADDR: - priv->txvopringdma=dma_desc; - priv->txvopring=desc; + priv->txvopringdma = dma_desc; + priv->txvopring = desc; break; case TX_HIGHPRIORITY_RING_ADDR: - priv->txhpringdma=dma_desc; - priv->txhpring=desc; + priv->txhpringdma = dma_desc; + priv->txhpring = desc; break; case TX_BEACON_RING_ADDR: - priv->txbeaconringdma=dma_desc; - priv->txbeaconring=desc; + priv->txbeaconringdma = dma_desc; + priv->txbeaconring = desc; break; } @@ -1078,37 +1075,37 @@ short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count, void free_tx_desc_rings(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - struct pci_dev *pdev=priv->pdev; + struct pci_dev *pdev = priv->pdev; int count = priv->txringcount; pci_free_consistent(pdev, sizeof(u32)*8*count+256, priv->txmapring, priv->txmapringdma); - buffer_free(dev,&(priv->txmapbufs),priv->txbuffsize,1); + buffer_free(dev, &(priv->txmapbufs), priv->txbuffsize, 1); pci_free_consistent(pdev, sizeof(u32)*8*count+256, priv->txbkpring, priv->txbkpringdma); - buffer_free(dev,&(priv->txbkpbufs),priv->txbuffsize,1); + buffer_free(dev, &(priv->txbkpbufs), priv->txbuffsize, 1); pci_free_consistent(pdev, sizeof(u32)*8*count+256, priv->txbepring, priv->txbepringdma); - buffer_free(dev,&(priv->txbepbufs),priv->txbuffsize,1); + buffer_free(dev, &(priv->txbepbufs), priv->txbuffsize, 1); pci_free_consistent(pdev, sizeof(u32)*8*count+256, priv->txvipring, priv->txvipringdma); - buffer_free(dev,&(priv->txvipbufs),priv->txbuffsize,1); + buffer_free(dev, &(priv->txvipbufs), priv->txbuffsize, 1); pci_free_consistent(pdev, sizeof(u32)*8*count+256, priv->txvopring, priv->txvopringdma); - buffer_free(dev,&(priv->txvopbufs),priv->txbuffsize,1); + buffer_free(dev, &(priv->txvopbufs), priv->txbuffsize, 1); pci_free_consistent(pdev, sizeof(u32)*8*count+256, priv->txhpring, priv->txhpringdma); - buffer_free(dev,&(priv->txhpbufs),priv->txbuffsize,1); + buffer_free(dev, &(priv->txhpbufs), priv->txbuffsize, 1); count = priv->txbeaconcount; pci_free_consistent(pdev, sizeof(u32)*8*count+256, priv->txbeaconring, priv->txbeaconringdma); - buffer_free(dev,&(priv->txbeaconbufs),priv->txbuffsize,1); + buffer_free(dev, &(priv->txbeaconbufs), priv->txbuffsize, 1); } void free_rx_desc_ring(struct net_device *dev) @@ -1120,7 +1117,7 @@ void free_rx_desc_ring(struct net_device *dev) pci_free_consistent(pdev, sizeof(u32)*8*count+256, priv->rxring, priv->rxringdma); - buffer_free(dev,&(priv->rxbuffer),priv->rxbuffersize,0); + buffer_free(dev, &(priv->rxbuffer), priv->rxbuffersize, 0); } short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count) @@ -1128,20 +1125,20 @@ short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count) int i; u32 *desc; u32 *tmp; - dma_addr_t dma_desc,dma_tmp; + dma_addr_t dma_desc, dma_tmp; struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - struct pci_dev *pdev=priv->pdev; + struct pci_dev *pdev = priv->pdev; void *buf; u8 rx_desc_size; rx_desc_size = 8; // 4*8 = 32 bytes - if((bufsize & 0xfff) != bufsize){ - DMESGE ("RX buffer allocation too large"); + if ((bufsize & 0xfff) != bufsize) { + DMESGE("RX buffer allocation too large"); return -1; } - desc = (u32*)pci_alloc_consistent(pdev,sizeof(u32)*rx_desc_size*count+256, + desc = (u32 *)pci_alloc_consistent(pdev, sizeof(u32)*rx_desc_size*count+256, &dma_desc); if (dma_desc & 0xff) @@ -1151,31 +1148,31 @@ short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count) */ WARN(1, "DMA buffer is not aligned\n"); - priv->rxring=desc; - priv->rxringdma=dma_desc; - tmp=desc; + priv->rxring = desc; + priv->rxringdma = dma_desc; + tmp = desc; for (i = 0; i < count; i++) { - buf = kmalloc(bufsize * sizeof(u8),GFP_ATOMIC); + buf = kmalloc(bufsize * sizeof(u8), GFP_ATOMIC); if (buf == NULL) { DMESGE("Failed to kmalloc RX buffer"); return -1; } - dma_tmp = pci_map_single(pdev,buf,bufsize * sizeof(u8), + dma_tmp = pci_map_single(pdev, buf, bufsize * sizeof(u8), PCI_DMA_FROMDEVICE); - if(-1 == buffer_add(&(priv->rxbuffer), buf,dma_tmp, - &(priv->rxbufferhead))){ - DMESGE("Unable to allocate mem RX buf"); - return -1; + if (-1 == buffer_add(&(priv->rxbuffer), buf, dma_tmp, + &(priv->rxbufferhead))) { + DMESGE("Unable to allocate mem RX buf"); + return -1; } - *tmp = 0; //zero pads the header of the descriptor - *tmp = *tmp |( bufsize&0xfff); + *tmp = 0; // zero pads the header of the descriptor + *tmp = *tmp | (bufsize&0xfff); *(tmp+2) = (u32)dma_tmp; - *tmp = *tmp |(1<<31); // descriptor void, owned by the NIC + *tmp = *tmp | (1<<31); // descriptor void, owned by the NIC - tmp=tmp+rx_desc_size; + tmp = tmp+rx_desc_size; } *(tmp-rx_desc_size) = *(tmp-rx_desc_size) | (1<<30); // this is the last descriptor @@ -1189,10 +1186,10 @@ void set_nic_rxring(struct net_device *dev) u8 pgreg; struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - pgreg=read_nic_byte(dev, PGSELECT); - write_nic_byte(dev, PGSELECT, pgreg &~ (1<rxringdma); + write_nic_dword(dev, RXRING_ADDR, priv->rxringdma); } void rtl8180_reset(struct net_device *dev) @@ -1201,28 +1198,28 @@ void rtl8180_reset(struct net_device *dev) rtl8180_irq_disable(dev); - cr=read_nic_byte(dev,CMD); + cr = read_nic_byte(dev, CMD); cr = cr & 2; cr = cr | (1< 0) - RetSS = ((LastSS * 5) + (RetSS)+ 5) / 6; + if (LastSS > 0) + RetSS = ((LastSS * 5) + (RetSS) + 5) / 6; return RetSS; } @@ -1399,11 +1396,11 @@ void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv, priv->bCurCCKPkt = bCckRate; if (priv->UndecoratedSmoothedSS >= 0) - priv->UndecoratedSmoothedSS = ( (priv->UndecoratedSmoothedSS * 5) + (priv->SignalStrength * 10) ) / 6; + priv->UndecoratedSmoothedSS = ((priv->UndecoratedSmoothedSS * 5) + (priv->SignalStrength * 10)) / 6; else priv->UndecoratedSmoothedSS = priv->SignalStrength * 10; - priv->UndercorateSmoothedRxPower = ( (priv->UndercorateSmoothedRxPower * 50) + (priv->RxPower* 11)) / 60; + priv->UndercorateSmoothedRxPower = ((priv->UndercorateSmoothedRxPower * 50) + (priv->RxPower * 11)) / 60; if (bCckRate) priv->CurCCKRSSI = priv->RSSI; @@ -1417,23 +1414,23 @@ void rtl8180_rx(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); struct sk_buff *tmp_skb; - short first,last; + short first, last; u32 len; int lastlen; unsigned char quality, signal; u8 rate; - u32 *tmp,*tmp2; + u32 *tmp, *tmp2; u8 rx_desc_size; u8 padding; char rxpower = 0; u32 RXAGC = 0; long RxAGC_dBm = 0; - u8 LNA=0, BB=0; + u8 LNA = 0, BB = 0; u8 LNA_gain[4] = {02, 17, 29, 39}; u8 Antenna = 0; struct ieee80211_hdr_4addr *hdr; - u16 fc,type; - u8 bHwError = 0,bCRC = 0,bICV = 0; + u16 fc, type; + u8 bHwError = 0, bCRC = 0, bICV = 0; bool bCckRate = false; u8 RSSI = 0; long SignalStrengthIndex = 0; @@ -1456,27 +1453,28 @@ void rtl8180_rx(struct net_device *dev) tmp2 = NULL; tmp = priv->rxringtail; - do{ - if(tmp == priv->rxring) + do { + if (tmp == priv->rxring) tmp = priv->rxring + (priv->rxringcount - 1)*rx_desc_size; else tmp -= rx_desc_size; - if(! (*tmp & (1<<31))) + if (!(*tmp & (1<<31))) tmp2 = tmp; - }while(tmp != priv->rxring); + } while (tmp != priv->rxring); - if(tmp2) priv->rxringtail = tmp2; + if (tmp2) + priv->rxringtail = tmp2; } /* while there are filled descriptors */ - while(!(*(priv->rxringtail) & (1<<31))){ - if(*(priv->rxringtail) & (1<<26)) + while (!(*(priv->rxringtail) & (1<<31))) { + if (*(priv->rxringtail) & (1<<26)) DMESGW("RX buffer overflow"); - if(*(priv->rxringtail) & (1<<12)) + if (*(priv->rxringtail) & (1<<12)) priv->stats.rxicverr++; - if(*(priv->rxringtail) & (1<<27)){ + if (*(priv->rxringtail) & (1<<27)) { priv->stats.rxdmafail++; //DMESG("EE: RX DMA FAILED at buffer pointed by descriptor %x",(u32)priv->rxringtail); goto drop; @@ -1488,12 +1486,13 @@ void rtl8180_rx(struct net_device *dev) sizeof(u8), PCI_DMA_FROMDEVICE); - first = *(priv->rxringtail) & (1<<29) ? 1:0; - if(first) priv->rx_prevlen=0; + first = *(priv->rxringtail) & (1<<29) ? 1 : 0; + if (first) + priv->rx_prevlen = 0; - last = *(priv->rxringtail) & (1<<28) ? 1:0; - if(last){ - lastlen=((*priv->rxringtail) &0xfff); + last = *(priv->rxringtail) & (1<<28) ? 1 : 0; + if (last) { + lastlen = ((*priv->rxringtail) & 0xfff); /* if the last descriptor (that should * tell us the total packet len) tell @@ -1502,109 +1501,101 @@ void rtl8180_rx(struct net_device *dev) * problem.. * workaround to prevent kernel panic */ - if(lastlen < priv->rx_prevlen) - len=0; + if (lastlen < priv->rx_prevlen) + len = 0; else - len=lastlen-priv->rx_prevlen; + len = lastlen-priv->rx_prevlen; - if(*(priv->rxringtail) & (1<<13)) { - if ((*(priv->rxringtail) & 0xfff) <500) + if (*(priv->rxringtail) & (1<<13)) { + if ((*(priv->rxringtail) & 0xfff) < 500) priv->stats.rxcrcerrmin++; - else if ((*(priv->rxringtail) & 0x0fff) >1000) + else if ((*(priv->rxringtail) & 0x0fff) > 1000) priv->stats.rxcrcerrmax++; else priv->stats.rxcrcerrmid++; } - }else{ + } else { len = priv->rxbuffersize; } - if(first && last) { + if (first && last) { padding = ((*(priv->rxringtail+3))&(0x04000000))>>26; - }else if(first) { + } else if (first) { padding = ((*(priv->rxringtail+3))&(0x04000000))>>26; - if(padding) { + if (padding) len -= 2; - } - }else { + } else { padding = 0; } padding = 0; - priv->rx_prevlen+=len; + priv->rx_prevlen += len; - if(priv->rx_prevlen > MAX_FRAG_THRESHOLD + 100){ + if (priv->rx_prevlen > MAX_FRAG_THRESHOLD + 100) { /* HW is probably passing several buggy frames * without FD or LD flag set. * Throw this garbage away to prevent skb * memory exausting */ - if(!priv->rx_skb_complete) + if (!priv->rx_skb_complete) dev_kfree_skb_any(priv->rx_skb); priv->rx_skb_complete = 1; } - signal=(unsigned char)(((*(priv->rxringtail+3))& (0x00ff0000))>>16); + signal = (unsigned char)(((*(priv->rxringtail+3)) & (0x00ff0000))>>16); signal = (signal & 0xfe) >> 1; - quality=(unsigned char)((*(priv->rxringtail+3)) & (0xff)); + quality = (unsigned char)((*(priv->rxringtail+3)) & (0xff)); stats.mac_time[0] = *(priv->rxringtail+1); stats.mac_time[1] = *(priv->rxringtail+2); - rxpower =((char)(((*(priv->rxringtail+4))& (0x00ff0000))>>16))/2 - 42; - RSSI = ((u8)(((*(priv->rxringtail+3)) & (0x0000ff00))>> 8)) & (0x7f); + rxpower = ((char)(((*(priv->rxringtail+4)) & (0x00ff0000))>>16))/2 - 42; + RSSI = ((u8)(((*(priv->rxringtail+3)) & (0x0000ff00))>>8)) & (0x7f); - rate=((*(priv->rxringtail)) & + rate = ((*(priv->rxringtail)) & ((1<<23)|(1<<22)|(1<<21)|(1<<20)))>>20; stats.rate = rtl8180_rate2rate(rate); - Antenna = (((*(priv->rxringtail +3))& (0x00008000)) == 0 )? 0:1 ; - if(!rtl8180_IsWirelessBMode(stats.rate)) - { // OFDM rate. - + Antenna = (((*(priv->rxringtail+3)) & (0x00008000)) == 0) ? 0 : 1; + if (!rtl8180_IsWirelessBMode(stats.rate)) { // OFDM rate. RxAGC_dBm = rxpower+1; //bias - } - else - { // CCK rate. - RxAGC_dBm = signal;//bit 0 discard + } else { // CCK rate. + RxAGC_dBm = signal; //bit 0 discard - LNA = (u8) (RxAGC_dBm & 0x60 ) >> 5 ; //bit 6~ bit 5 + LNA = (u8) (RxAGC_dBm & 0x60) >> 5 ; //bit 6~ bit 5 BB = (u8) (RxAGC_dBm & 0x1F); // bit 4 ~ bit 0 - RxAGC_dBm = -( LNA_gain[LNA] + (BB *2) ); //Pin_11b=-(LNA_gain+BB_gain) (dBm) + RxAGC_dBm = -(LNA_gain[LNA] + (BB*2)); //Pin_11b=-(LNA_gain+BB_gain) (dBm) - RxAGC_dBm +=4; //bias + RxAGC_dBm += 4; //bias } - if(RxAGC_dBm & 0x80) //absolute value - RXAGC= ~(RxAGC_dBm)+1; + if (RxAGC_dBm & 0x80) //absolute value + RXAGC = ~(RxAGC_dBm)+1; bCckRate = rtl8180_IsWirelessBMode(stats.rate); // Translate RXAGC into 1-100. - if(!rtl8180_IsWirelessBMode(stats.rate)) - { // OFDM rate. - if(RXAGC>90) - RXAGC=90; - else if(RXAGC<25) - RXAGC=25; - RXAGC=(90-RXAGC)*100/65; - } - else - { // CCK rate. - if(RXAGC>95) - RXAGC=95; - else if(RXAGC<30) - RXAGC=30; - RXAGC=(95-RXAGC)*100/65; + if (!rtl8180_IsWirelessBMode(stats.rate)) { // OFDM rate. + if (RXAGC > 90) + RXAGC = 90; + else if (RXAGC < 25) + RXAGC = 25; + RXAGC = (90-RXAGC)*100/65; + } else { // CCK rate. + if (RXAGC > 95) + RXAGC = 95; + else if (RXAGC < 30) + RXAGC = 30; + RXAGC = (95-RXAGC)*100/65; } priv->SignalStrength = (u8)RXAGC; priv->RecvSignalPower = RxAGC_dBm; priv->RxPower = rxpower; priv->RSSI = RSSI; /* SQ translation formula is provided by SD3 DZ. 2006.06.27 */ - if(quality >= 127) + if (quality >= 127) quality = 1;//0; //0 will cause epc to show signal zero , walk aroud now; - else if(quality < 27) + else if (quality < 27) quality = 100; else quality = 127 - quality; @@ -1612,31 +1603,30 @@ void rtl8180_rx(struct net_device *dev) stats.signal = (u8)quality;//priv->wstats.qual.level = priv->SignalStrength; stats.signalstrength = RXAGC; - if(stats.signalstrength > 100) + if (stats.signalstrength > 100) stats.signalstrength = 100; stats.signalstrength = (stats.signalstrength * 70)/100 + 30; // printk("==========================>rx : RXAGC is %d,signalstrength is %d\n",RXAGC,stats.signalstrength); stats.rssi = priv->wstats.qual.qual = priv->SignalQuality; - stats.noise = priv->wstats.qual.noise = 100 - priv ->wstats.qual.qual; - bHwError = (((*(priv->rxringtail))& (0x00000fff)) == 4080)| (((*(priv->rxringtail))& (0x04000000)) != 0 ) - | (((*(priv->rxringtail))& (0x08000000)) != 0 )| (((~(*(priv->rxringtail)))& (0x10000000)) != 0 )| (((~(*(priv->rxringtail)))& (0x20000000)) != 0 ); + stats.noise = priv->wstats.qual.noise = 100 - priv->wstats.qual.qual; + bHwError = (((*(priv->rxringtail)) & (0x00000fff)) == 4080) | (((*(priv->rxringtail)) & (0x04000000)) != 0) + | (((*(priv->rxringtail)) & (0x08000000)) != 0) | (((~(*(priv->rxringtail))) & (0x10000000)) != 0) | (((~(*(priv->rxringtail))) & (0x20000000)) != 0); bCRC = ((*(priv->rxringtail)) & (0x00002000)) >> 13; bICV = ((*(priv->rxringtail)) & (0x00001000)) >> 12; hdr = (struct ieee80211_hdr_4addr *)priv->rxbuffer->buf; fc = le16_to_cpu(hdr->frame_ctl); type = WLAN_FC_GET_TYPE(fc); - if((IEEE80211_FTYPE_CTL != type) && - (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3)) - && (!bHwError) && (!bCRC)&& (!bICV)) - { + if ((IEEE80211_FTYPE_CTL != type) && + (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS) ? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 : hdr->addr3)) + && (!bHwError) && (!bCRC) && (!bICV)) { /* Perform signal smoothing for dynamic * mechanism on demand. This is different * with PerformSignalSmoothing8185 in smoothing * fomula. No dramatic adjustion is apply * because dynamic mechanism need some degree * of correctness. */ - PerformUndecoratedSignalSmoothing8185(priv,bCckRate); + PerformUndecoratedSignalSmoothing8185(priv, bCckRate); // // For good-looking singal strength. // @@ -1650,73 +1640,75 @@ void rtl8180_rx(struct net_device *dev) // We need more correct power of received packets and the "SignalStrength" of RxStats is beautified, // so we record the correct power here. // - priv->Stats_SignalQuality =(long) (priv->Stats_SignalQuality * 5 + (long)priv->SignalQuality + 5) / 6; - priv->Stats_RecvSignalPower = (long)(priv->Stats_RecvSignalPower * 5 + priv->RecvSignalPower -1) / 6; + priv->Stats_SignalQuality = (long)(priv->Stats_SignalQuality * 5 + (long)priv->SignalQuality + 5) / 6; + priv->Stats_RecvSignalPower = (long)(priv->Stats_RecvSignalPower * 5 + priv->RecvSignalPower - 1) / 6; // Figure out which antenna that received the lasted packet. priv->LastRxPktAntenna = Antenna ? 1 : 0; // 0: aux, 1: main. - SwAntennaDiversityRxOk8185(dev, priv->SignalStrength); + SwAntennaDiversityRxOk8185(dev, priv->SignalStrength); } - if(first){ - if(!priv->rx_skb_complete){ + if (first) { + if (!priv->rx_skb_complete) { /* seems that HW sometimes fails to reiceve and doesn't provide the last descriptor */ dev_kfree_skb_any(priv->rx_skb); priv->stats.rxnolast++; } /* support for prism header has been originally added by Christian */ - if(priv->prism_hdr && priv->ieee80211->iw_mode == IW_MODE_MONITOR){ - - }else{ + if (priv->prism_hdr && priv->ieee80211->iw_mode == IW_MODE_MONITOR) { + + } else { priv->rx_skb = dev_alloc_skb(len+2); - if( !priv->rx_skb) goto drop; + if (!priv->rx_skb) + goto drop; } - priv->rx_skb_complete=0; - priv->rx_skb->dev=dev; - }else{ + priv->rx_skb_complete = 0; + priv->rx_skb->dev = dev; + } else { /* if we are here we should have already RXed * the first frame. * If we get here and the skb is not allocated then * we have just throw out garbage (skb not allocated) * and we are still rxing garbage.... */ - if(!priv->rx_skb_complete){ + if (!priv->rx_skb_complete) { - tmp_skb= dev_alloc_skb(priv->rx_skb->len +len+2); + tmp_skb = dev_alloc_skb(priv->rx_skb->len+len+2); - if(!tmp_skb) goto drop; + if (!tmp_skb) + goto drop; - tmp_skb->dev=dev; + tmp_skb->dev = dev; - memcpy(skb_put(tmp_skb,priv->rx_skb->len), + memcpy(skb_put(tmp_skb, priv->rx_skb->len), priv->rx_skb->data, priv->rx_skb->len); dev_kfree_skb_any(priv->rx_skb); - priv->rx_skb=tmp_skb; + priv->rx_skb = tmp_skb; } } - if(!priv->rx_skb_complete) { - if(padding) { - memcpy(skb_put(priv->rx_skb,len), - (((unsigned char *)priv->rxbuffer->buf) + 2),len); + if (!priv->rx_skb_complete) { + if (padding) { + memcpy(skb_put(priv->rx_skb, len), + (((unsigned char *)priv->rxbuffer->buf) + 2), len); } else { - memcpy(skb_put(priv->rx_skb,len), - priv->rxbuffer->buf,len); + memcpy(skb_put(priv->rx_skb, len), + priv->rxbuffer->buf, len); } } - if(last && !priv->rx_skb_complete){ - if(priv->rx_skb->len > 4) - skb_trim(priv->rx_skb,priv->rx_skb->len-4); - if(!ieee80211_rtl_rx(priv->ieee80211, + if (last && !priv->rx_skb_complete) { + if (priv->rx_skb->len > 4) + skb_trim(priv->rx_skb, priv->rx_skb->len-4); + if (!ieee80211_rtl_rx(priv->ieee80211, priv->rx_skb, &stats)) dev_kfree_skb_any(priv->rx_skb); - priv->rx_skb_complete=1; + priv->rx_skb_complete = 1; } pci_dma_sync_single_for_device(priv->pdev, @@ -1727,20 +1719,20 @@ void rtl8180_rx(struct net_device *dev) drop: // this is used when we have not enough mem /* restore the descriptor */ - *(priv->rxringtail+2)=priv->rxbuffer->dma; - *(priv->rxringtail)=*(priv->rxringtail) &~ 0xfff; - *(priv->rxringtail)= + *(priv->rxringtail+2) = priv->rxbuffer->dma; + *(priv->rxringtail) = *(priv->rxringtail) & ~0xfff; + *(priv->rxringtail) = *(priv->rxringtail) | priv->rxbuffersize; - *(priv->rxringtail)= + *(priv->rxringtail) = *(priv->rxringtail) | (1<<31); - priv->rxringtail+=rx_desc_size; - if(priv->rxringtail >= - (priv->rxring)+(priv->rxringcount )*rx_desc_size) - priv->rxringtail=priv->rxring; + priv->rxringtail += rx_desc_size; + if (priv->rxringtail >= + (priv->rxring)+(priv->rxringcount)*rx_desc_size) + priv->rxringtail = priv->rxring; - priv->rxbuffer=(priv->rxbuffer->next); + priv->rxbuffer = (priv->rxbuffer->next); } } @@ -1749,10 +1741,10 @@ void rtl8180_dma_kick(struct net_device *dev, int priority) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - rtl8180_set_mode(dev,EPROM_CMD_CONFIG); + rtl8180_set_mode(dev, EPROM_CMD_CONFIG); write_nic_byte(dev, TX_DMA_POLLING, (1 << (priority + 1)) | priv->dma_poll_mask); - rtl8180_set_mode(dev,EPROM_CMD_NORMAL); + rtl8180_set_mode(dev, EPROM_CMD_NORMAL); force_pci_posting(dev); } @@ -1761,31 +1753,30 @@ void rtl8180_data_hard_stop(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - rtl8180_set_mode(dev,EPROM_CMD_CONFIG); + rtl8180_set_mode(dev, EPROM_CMD_CONFIG); priv->dma_poll_stop_mask |= TPPOLLSTOP_AC_VIQ; - write_nic_byte(dev,TPPollStop, priv->dma_poll_stop_mask); - rtl8180_set_mode(dev,EPROM_CMD_NORMAL); + write_nic_byte(dev, TPPollStop, priv->dma_poll_stop_mask); + rtl8180_set_mode(dev, EPROM_CMD_NORMAL); } void rtl8180_data_hard_resume(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - rtl8180_set_mode(dev,EPROM_CMD_CONFIG); + rtl8180_set_mode(dev, EPROM_CMD_CONFIG); priv->dma_poll_stop_mask &= ~(TPPOLLSTOP_AC_VIQ); - write_nic_byte(dev,TPPollStop, priv->dma_poll_stop_mask); - rtl8180_set_mode(dev,EPROM_CMD_NORMAL); + write_nic_byte(dev, TPPollStop, priv->dma_poll_stop_mask); + rtl8180_set_mode(dev, EPROM_CMD_NORMAL); } /* this function TX data frames when the ieee80211 stack requires this. * It checks also if we need to stop the ieee tx queue, eventually do it */ -void rtl8180_hard_data_xmit(struct sk_buff *skb,struct net_device *dev, int -rate) -{ +void rtl8180_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int +rate) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); int mode; - struct ieee80211_hdr_3addr *h = (struct ieee80211_hdr_3addr *) skb->data; + struct ieee80211_hdr_3addr *h = (struct ieee80211_hdr_3addr *) skb->data; short morefrag = (h->frame_control) & IEEE80211_FCTL_MOREFRAGS; unsigned long flags; int priority; @@ -1801,25 +1792,24 @@ rate) * the ieee stack. */ priority = AC2Q(skb->priority); - spin_lock_irqsave(&priv->tx_lock,flags); + spin_lock_irqsave(&priv->tx_lock, flags); - if(priv->ieee80211->bHwRadioOff) - { - spin_unlock_irqrestore(&priv->tx_lock,flags); + if (priv->ieee80211->bHwRadioOff) { + spin_unlock_irqrestore(&priv->tx_lock, flags); return; } - if (!check_nic_enought_desc(dev, priority)){ + if (!check_nic_enought_desc(dev, priority)) { DMESGW("Error: no descriptor left by previous TX (avail %d) ", get_curr_tx_free_desc(dev, priority)); ieee80211_rtl_stop_queue(priv->ieee80211); } - rtl8180_tx(dev, skb->data, skb->len, priority, morefrag,0,rate); + rtl8180_tx(dev, skb->data, skb->len, priority, morefrag, 0, rate); if (!check_nic_enought_desc(dev, priority)) ieee80211_rtl_stop_queue(priv->ieee80211); - spin_unlock_irqrestore(&priv->tx_lock,flags); + spin_unlock_irqrestore(&priv->tx_lock, flags); } /* This is a rough attempt to TX a frame @@ -1833,7 +1823,7 @@ rate) * might use a different lock than tx_lock (for example mgmt_tx_lock) */ /* these function may loops if invoked with 0 descriptors or 0 len buffer*/ -int rtl8180_hard_start_xmit(struct sk_buff *skb,struct net_device *dev) +int rtl8180_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); unsigned long flags; @@ -1841,66 +1831,68 @@ int rtl8180_hard_start_xmit(struct sk_buff *skb,struct net_device *dev) priority = MANAGE_PRIORITY; - spin_lock_irqsave(&priv->tx_lock,flags); + spin_lock_irqsave(&priv->tx_lock, flags); if (priv->ieee80211->bHwRadioOff) { - spin_unlock_irqrestore(&priv->tx_lock,flags); + spin_unlock_irqrestore(&priv->tx_lock, flags); dev_kfree_skb_any(skb); return NETDEV_TX_OK; } rtl8180_tx(dev, skb->data, skb->len, priority, - 0, 0,ieeerate2rtlrate(priv->ieee80211->basic_rate)); + 0, 0, ieeerate2rtlrate(priv->ieee80211->basic_rate)); - priv->ieee80211->stats.tx_bytes+=skb->len; + priv->ieee80211->stats.tx_bytes += skb->len; priv->ieee80211->stats.tx_packets++; - spin_unlock_irqrestore(&priv->tx_lock,flags); + spin_unlock_irqrestore(&priv->tx_lock, flags); dev_kfree_skb_any(skb); return NETDEV_TX_OK; } // longpre 144+48 shortpre 72+24 -u16 rtl8180_len2duration(u32 len, short rate,short* ext) +u16 rtl8180_len2duration(u32 len, short rate, short *ext) { u16 duration; u16 drift; - *ext=0; + *ext = 0; - switch(rate){ + switch (rate) { case 0://1mbps - *ext=0; - duration = ((len+4)<<4) /0x2; + *ext = 0; + duration = ((len+4)<<4) / 0x2; drift = ((len+4)<<4) % 0x2; - if(drift ==0 ) break; + if (drift == 0) + break; duration++; break; case 1://2mbps - *ext=0; - duration = ((len+4)<<4) /0x4; + *ext = 0; + duration = ((len+4)<<4) / 0x4; drift = ((len+4)<<4) % 0x4; - if(drift ==0 ) break; + if (drift == 0) + break; duration++; break; case 2: //5.5mbps - *ext=0; - duration = ((len+4)<<4) /0xb; + *ext = 0; + duration = ((len+4)<<4) / 0xb; drift = ((len+4)<<4) % 0xb; - if(drift ==0 ) + if (drift == 0) break; duration++; break; default: case 3://11mbps - *ext=0; - duration = ((len+4)<<4) /0x16; + *ext = 0; + duration = ((len+4)<<4) / 0x16; drift = ((len+4)<<4) % 0x16; - if(drift ==0 ) + if (drift == 0) break; duration++; - if(drift > 6) + if (drift > 6) break; - *ext=1; + *ext = 1; break; } @@ -1914,13 +1906,13 @@ void rtl8180_prepare_beacon(struct net_device *dev) u16 word = read_nic_word(dev, BcnItv); word &= ~BcnItv_BcnItv; // clear Bcn_Itv - word |= cpu_to_le16(priv->ieee80211->current_network.beacon_interval);//0x64; + word |= cpu_to_le16(priv->ieee80211->current_network.beacon_interval); //0x64; write_nic_word(dev, BcnItv, word); skb = ieee80211_get_beacon(priv->ieee80211); - if(skb){ - rtl8180_tx(dev,skb->data,skb->len,BEACON_PRIORITY, - 0,0,ieeerate2rtlrate(priv->ieee80211->basic_rate)); + if (skb) { + rtl8180_tx(dev, skb->data, skb->len, BEACON_PRIORITY, + 0, 0, ieeerate2rtlrate(priv->ieee80211->basic_rate)); dev_kfree_skb_any(skb); } } @@ -1933,7 +1925,7 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, short morefrag, short descfrag, int rate) { struct r8180_priv *priv = ieee80211_priv(dev); - u32 *tail,*temp_tail; + u32 *tail, *temp_tail; u32 *begin; u32 *buf; int i; @@ -1942,7 +1934,7 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, int count; u16 duration; short ext; - struct buffer* buflist; + struct buffer *buflist; struct ieee80211_hdr_3addr *frag_hdr = (struct ieee80211_hdr_3addr *)txbuf; u8 dest[ETH_ALEN]; u8 bUseShortPreamble = 0; @@ -1954,46 +1946,46 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, u16 TxDescDuration = 0; u8 ownbit_flag = false; - switch(priority) { + switch (priority) { case MANAGE_PRIORITY: - tail=priv->txmapringtail; - begin=priv->txmapring; + tail = priv->txmapringtail; + begin = priv->txmapring; buflist = priv->txmapbufstail; count = priv->txringcount; break; case BK_PRIORITY: - tail=priv->txbkpringtail; - begin=priv->txbkpring; + tail = priv->txbkpringtail; + begin = priv->txbkpring; buflist = priv->txbkpbufstail; count = priv->txringcount; break; case BE_PRIORITY: - tail=priv->txbepringtail; - begin=priv->txbepring; + tail = priv->txbepringtail; + begin = priv->txbepring; buflist = priv->txbepbufstail; count = priv->txringcount; break; case VI_PRIORITY: - tail=priv->txvipringtail; - begin=priv->txvipring; + tail = priv->txvipringtail; + begin = priv->txvipring; buflist = priv->txvipbufstail; count = priv->txringcount; break; case VO_PRIORITY: - tail=priv->txvopringtail; - begin=priv->txvopring; + tail = priv->txvopringtail; + begin = priv->txvopring; buflist = priv->txvopbufstail; count = priv->txringcount; break; case HI_PRIORITY: - tail=priv->txhpringtail; - begin=priv->txhpring; + tail = priv->txhpringtail; + begin = priv->txhpring; buflist = priv->txhpbufstail; count = priv->txringcount; break; case BEACON_PRIORITY: - tail=priv->txbeaconringtail; - begin=priv->txbeaconring; + tail = priv->txbeaconringtail; + begin = priv->txbeaconring; buflist = priv->txbeaconbufstail; count = priv->txbeaconcount; break; @@ -2004,8 +1996,7 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, memcpy(&dest, frag_hdr->addr1, ETH_ALEN); if (is_multicast_ether_addr(dest) || - is_broadcast_ether_addr(dest)) - { + is_broadcast_ether_addr(dest)) { Duration = 0; RtsDur = 0; bRTSEnable = 0; @@ -2021,19 +2012,18 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, /* Figure out ACK rate according to BSS basic rate * and Tx rate. */ - AckTime = ComputeTxTime(14, 10,0, 0); // AckCTSLng = 14 use 1M bps send + AckTime = ComputeTxTime(14, 10, 0, 0); // AckCTSLng = 14 use 1M bps send - if ( ((len + sCrcLng) > priv->rts) && priv->rts ) - { // RTS/CTS. + if (((len + sCrcLng) > priv->rts) && priv->rts) { // RTS/CTS. u16 RtsTime, CtsTime; //u16 CtsRate; bRTSEnable = 1; bCTSEnable = 0; // Rate and time required for RTS. - RtsTime = ComputeTxTime( sAckCtsLng/8,priv->ieee80211->basic_rate, 0, 0); + RtsTime = ComputeTxTime(sAckCtsLng/8, priv->ieee80211->basic_rate, 0, 0); // Rate and time required for CTS. - CtsTime = ComputeTxTime(14, 10,0, 0); // AckCTSLng = 14 use 1M bps send + CtsTime = ComputeTxTime(14, 10, 0, 0); // AckCTSLng = 14 use 1M bps send // Figure out time required to transmit this frame. ThisFrameTime = ComputeTxTime(len + sCrcLng, @@ -2045,8 +2035,7 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, RtsDur = CtsTime + ThisFrameTime + AckTime + 3*aSifsTime; TxDescDuration = RtsTime + RtsDur; - } - else {// Normal case. + } else {// Normal case. bCTSEnable = 0; bRTSEnable = 0; RtsDur = 0; @@ -2060,10 +2049,10 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, Duration = aSifsTime + AckTime; } else { // One or more fragments remained. u16 NextFragTime; - NextFragTime = ComputeTxTime( len + sCrcLng, //pretend following packet length equal current packet + NextFragTime = ComputeTxTime(len + sCrcLng, //pretend following packet length equal current packet rtl8180_rate2rate(rate), 0, - bUseShortPreamble ); + bUseShortPreamble); //ThisFrag-ACk-NextFrag-ACK. Duration = NextFragTime + 3*aSifsTime + 2*AckTime; @@ -2073,17 +2062,17 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, frag_hdr->duration_id = Duration; - buflen=priv->txbuffsize; - remain=len; + buflen = priv->txbuffsize; + remain = len; temp_tail = tail; - while(remain!=0){ + while (remain != 0) { mb(); - if(!buflist){ + if (!buflist) { DMESGE("TX buffer error, cannot TX frames. pri %d.", priority); return -1; } - buf=buflist->buf; + buf = buflist->buf; if ((*tail & (1 << 31)) && (priority != BEACON_PRIORITY)) { DMESGW("No more TX desc, returning %x of %x", @@ -2092,7 +2081,7 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, return remain; } - *tail= 0; // zeroes header + *tail = 0; // zeroes header *(tail+1) = 0; *(tail+3) = 0; *(tail+5) = 0; @@ -2102,41 +2091,40 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, /*FIXME: this should be triggered by HW encryption parameters.*/ *tail |= (1<<15); /* no encrypt */ - if(remain==len && !descfrag) { + if (remain == len && !descfrag) { ownbit_flag = false; - *tail = *tail| (1<<29) ; //fist segment of the packet - *tail = *tail |(len); + *tail = *tail | (1<<29) ; //fist segment of the packet + *tail = *tail | (len); } else { ownbit_flag = true; } - for(i=0;i0;i++,remain--){ - ((u8*)buf)[i]=txbuf[i]; //copy data into descriptor pointed DMAble buffer - if(remain == 4 && i+4 >= buflen) break; + for (i = 0; i < buflen && remain > 0; i++, remain--) { + ((u8 *)buf)[i] = txbuf[i]; //copy data into descriptor pointed DMAble buffer + if (remain == 4 && i+4 >= buflen) + break; /* ensure the last desc has at least 4 bytes payload */ } txbuf = txbuf + i; - *(tail+3)=*(tail+3) &~ 0xfff; - *(tail+3)=*(tail+3) | i; // buffer lenght + *(tail+3) = *(tail+3) & ~0xfff; + *(tail+3) = *(tail+3) | i; // buffer lenght // Use short preamble or not if (priv->ieee80211->current_network.capability&WLAN_CAPABILITY_SHORT_PREAMBLE) - if (priv->plcp_preamble_mode==1 && rate!=0) // short mode now, not long! + if (priv->plcp_preamble_mode == 1 && rate != 0) // short mode now, not long! ;// *tail |= (1<<16); // enable short preamble mode. - if(bCTSEnable) { + if (bCTSEnable) *tail |= (1<<18); - } - if(bRTSEnable) //rts enable - { + if (bRTSEnable) { //rts enable *tail |= ((ieeerate2rtlrate(priv->ieee80211->basic_rate))<<19);//RTS RATE *tail |= (1<<23);//rts enable - *(tail+1) |=(RtsDur&0xffff);//RTS Duration + *(tail+1) |= (RtsDur&0xffff);//RTS Duration } *(tail+3) |= ((TxDescDuration&0xffff)<<16); //DURATION // *(tail+3) |= (0xe6<<16); - *(tail+5) |= (11<<8);//(priv->retry_data<<8); //retry lim ; + *(tail+5) |= (11<<8);//(priv->retry_data<<8); //retry lim ; *tail = *tail | ((rate&0xf) << 24); @@ -2145,71 +2133,72 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, if (!priv->hw_plcp_len) { duration = rtl8180_len2duration(len, rate, &ext); *(tail+1) = *(tail+1) | ((duration & 0x7fff)<<16); - if(ext) *(tail+1) = *(tail+1) |(1<<31); //plcp length extension + if (ext) + *(tail+1) = *(tail+1) | (1<<31); //plcp length extension } - if(morefrag) *tail = (*tail) | (1<<17); // more fragment - if(!remain) *tail = (*tail) | (1<<28); // last segment of frame + if (morefrag) + *tail = (*tail) | (1<<17); // more fragment + if (!remain) + *tail = (*tail) | (1<<28); // last segment of frame *(tail+5) = *(tail+5)|(2<<27); *(tail+7) = *(tail+7)|(1<<4); wmb(); - if(ownbit_flag) - { + if (ownbit_flag) *tail = *tail | (1<<31); // descriptor ready to be txed - } - if((tail - begin)/8 == count-1) - tail=begin; + if ((tail - begin)/8 == count-1) + tail = begin; else - tail=tail+8; + tail = tail+8; - buflist=buflist->next; + buflist = buflist->next; mb(); - switch(priority) { - case MANAGE_PRIORITY: - priv->txmapringtail=tail; - priv->txmapbufstail=buflist; - break; - case BK_PRIORITY: - priv->txbkpringtail=tail; - priv->txbkpbufstail=buflist; - break; - case BE_PRIORITY: - priv->txbepringtail=tail; - priv->txbepbufstail=buflist; - break; - case VI_PRIORITY: - priv->txvipringtail=tail; - priv->txvipbufstail=buflist; - break; - case VO_PRIORITY: - priv->txvopringtail=tail; - priv->txvopbufstail=buflist; - break; - case HI_PRIORITY: - priv->txhpringtail=tail; - priv->txhpbufstail = buflist; - break; - case BEACON_PRIORITY: - /* the HW seems to be happy with the 1st - * descriptor filled and the 2nd empty... - * So always update descriptor 1 and never - * touch 2nd - */ - break; + switch (priority) { + case MANAGE_PRIORITY: + priv->txmapringtail = tail; + priv->txmapbufstail = buflist; + break; + case BK_PRIORITY: + priv->txbkpringtail = tail; + priv->txbkpbufstail = buflist; + break; + case BE_PRIORITY: + priv->txbepringtail = tail; + priv->txbepbufstail = buflist; + break; + case VI_PRIORITY: + priv->txvipringtail = tail; + priv->txvipbufstail = buflist; + break; + case VO_PRIORITY: + priv->txvopringtail = tail; + priv->txvopbufstail = buflist; + break; + case HI_PRIORITY: + priv->txhpringtail = tail; + priv->txhpbufstail = buflist; + break; + case BEACON_PRIORITY: + /* the HW seems to be happy with the 1st + * descriptor filled and the 2nd empty... + * So always update descriptor 1 and never + * touch 2nd + */ + break; } } *temp_tail = *temp_tail | (1<<31); // descriptor ready to be txed - rtl8180_dma_kick(dev,priority); + rtl8180_dma_kick(dev, priority); return 0; } -void rtl8180_irq_rx_tasklet(struct r8180_priv * priv); +void rtl8180_irq_rx_tasklet(struct r8180_priv *priv); void rtl8180_link_change(struct net_device *dev) { @@ -2219,13 +2208,13 @@ void rtl8180_link_change(struct net_device *dev) rtl8180_update_msr(dev); - rtl8180_set_mode(dev,EPROM_CMD_CONFIG); + rtl8180_set_mode(dev, EPROM_CMD_CONFIG); - write_nic_dword(dev,BSSID,((u32*)net->bssid)[0]); - write_nic_word(dev,BSSID+4,((u16*)net->bssid)[2]); + write_nic_dword(dev, BSSID, ((u32 *)net->bssid)[0]); + write_nic_word(dev, BSSID+4, ((u16 *)net->bssid)[2]); - beacon_interval = read_nic_dword(dev,BEACON_INTERVAL); - beacon_interval &= ~ BEACON_INTERVAL_MASK; + beacon_interval = read_nic_dword(dev, BEACON_INTERVAL); + beacon_interval &= ~BEACON_INTERVAL_MASK; beacon_interval |= net->beacon_interval; write_nic_dword(dev, BEACON_INTERVAL, beacon_interval); @@ -2234,42 +2223,50 @@ void rtl8180_link_change(struct net_device *dev) rtl8180_set_chan(dev, priv->chan); } -void rtl8180_rq_tx_ack(struct net_device *dev){ +void rtl8180_rq_tx_ack(struct net_device *dev) +{ struct r8180_priv *priv = ieee80211_priv(dev); - write_nic_byte(dev,CONFIG4,read_nic_byte(dev,CONFIG4)|CONFIG4_PWRMGT); + write_nic_byte(dev, CONFIG4, read_nic_byte(dev, CONFIG4) | CONFIG4_PWRMGT); priv->ack_tx_to_ieee = 1; } -short rtl8180_is_tx_queue_empty(struct net_device *dev){ +short rtl8180_is_tx_queue_empty(struct net_device *dev) +{ struct r8180_priv *priv = ieee80211_priv(dev); - u32* d; + u32 *d; for (d = priv->txmapring; - d < priv->txmapring + priv->txringcount;d+=8) - if(*d & (1<<31)) return 0; + d < priv->txmapring + priv->txringcount; d += 8) + if (*d & (1<<31)) + return 0; for (d = priv->txbkpring; - d < priv->txbkpring + priv->txringcount;d+=8) - if(*d & (1<<31)) return 0; + d < priv->txbkpring + priv->txringcount; d += 8) + if (*d & (1<<31)) + return 0; for (d = priv->txbepring; - d < priv->txbepring + priv->txringcount;d+=8) - if(*d & (1<<31)) return 0; + d < priv->txbepring + priv->txringcount; d += 8) + if (*d & (1<<31)) + return 0; for (d = priv->txvipring; - d < priv->txvipring + priv->txringcount;d+=8) - if(*d & (1<<31)) return 0; + d < priv->txvipring + priv->txringcount; d += 8) + if (*d & (1<<31)) + return 0; for (d = priv->txvopring; - d < priv->txvopring + priv->txringcount;d+=8) - if(*d & (1<<31)) return 0; + d < priv->txvopring + priv->txringcount; d += 8) + if (*d & (1<<31)) + return 0; for (d = priv->txhpring; - d < priv->txhpring + priv->txringcount;d+=8) - if(*d & (1<<31)) return 0; + d < priv->txhpring + priv->txringcount; d += 8) + if (*d & (1<<31)) + return 0; return 1; } /* FIXME FIXME 5msecs is random */ @@ -2280,11 +2277,11 @@ void rtl8180_hw_wakeup(struct net_device *dev) unsigned long flags; struct r8180_priv *priv = ieee80211_priv(dev); - spin_lock_irqsave(&priv->ps_lock,flags); - write_nic_byte(dev,CONFIG4,read_nic_byte(dev,CONFIG4)&~CONFIG4_PWRMGT); + spin_lock_irqsave(&priv->ps_lock, flags); + write_nic_byte(dev, CONFIG4, read_nic_byte(dev, CONFIG4) & ~CONFIG4_PWRMGT); if (priv->rf_wakeup) priv->rf_wakeup(dev); - spin_unlock_irqrestore(&priv->ps_lock,flags); + spin_unlock_irqrestore(&priv->ps_lock, flags); } void rtl8180_hw_sleep_down(struct net_device *dev) @@ -2304,7 +2301,7 @@ void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl) u32 rb = jiffies; unsigned long flags; - spin_lock_irqsave(&priv->ps_lock,flags); + spin_lock_irqsave(&priv->ps_lock, flags); /* Writing HW register with 0 equals to disable * the timer, that is not really what we want @@ -2314,15 +2311,15 @@ void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl) /* If the interval in witch we are requested to sleep is too * short then give up and remain awake */ - if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME)) - ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) { - spin_unlock_irqrestore(&priv->ps_lock,flags); + if (((tl >= rb) && (tl-rb) <= MSECS(MIN_SLEEP_TIME)) + || ((rb > tl) && (rb-tl) < MSECS(MIN_SLEEP_TIME))) { + spin_unlock_irqrestore(&priv->ps_lock, flags); printk("too short to sleep\n"); return; } { - u32 tmp = (tl>rb)?(tl-rb):(rb-tl); + u32 tmp = (tl > rb) ? (tl-rb) : (rb-tl); priv->DozePeriodInPast2Sec += jiffies_to_msecs(tmp); @@ -2332,19 +2329,19 @@ void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl) * while setting it, then give up */ - if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))|| + if (((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME))) || ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) { - spin_unlock_irqrestore(&priv->ps_lock,flags); + spin_unlock_irqrestore(&priv->ps_lock, flags); return; } queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq); - spin_unlock_irqrestore(&priv->ps_lock,flags); + spin_unlock_irqrestore(&priv->ps_lock, flags); } -void rtl8180_wmm_param_update(struct work_struct * work) +void rtl8180_wmm_param_update(struct work_struct *work) { - struct ieee80211_device * ieee = container_of(work, struct ieee80211_device,wmm_param_update_wq); + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wmm_param_update_wq); struct net_device *dev = ieee->dev; u8 *ac_param = (u8 *)(ieee->current_network.wmm_param); u8 mode = ieee->current_network.mode; @@ -2353,7 +2350,7 @@ void rtl8180_wmm_param_update(struct work_struct * work) PAC_PARAM pAcParam; u8 i; - if(!ieee->current_network.QoS_Enable){ + if (!ieee->current_network.QoS_Enable) { //legacy ac_xx_param update AcParam.longData = 0; AcParam.f.AciAifsn.f.AIFSN = 2; // Follow 802.11 DIFS. @@ -2361,43 +2358,43 @@ void rtl8180_wmm_param_update(struct work_struct * work) AcParam.f.Ecw.f.ECWmin = 3; // Follow 802.11 CWmin. AcParam.f.Ecw.f.ECWmax = 7; // Follow 802.11 CWmax. AcParam.f.TXOPLimit = 0; - for(eACI = 0; eACI < AC_MAX; eACI++){ + for (eACI = 0; eACI < AC_MAX; eACI++) { AcParam.f.AciAifsn.f.ACI = (u8)eACI; { u8 u1bAIFS; u32 u4bAcParam; pAcParam = (PAC_PARAM)(&AcParam); // Retrive paramters to udpate. - u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN *(((mode&IEEE_G) == IEEE_G)?9:20) + aSifsTime; + u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * (((mode&IEEE_G) == IEEE_G) ? 9 : 20) + aSifsTime; u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit))<f.Ecw.f.ECWmax))<f.Ecw.f.ECWmin))<f.AciAifsn.f.ACI; //Mode G/A: slotTimeTimer = 9; Mode B: 20 - u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * (((mode&IEEE_G) == IEEE_G)?9:20) + aSifsTime; - u4bAcParam = ( (((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) | + u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * (((mode&IEEE_G) == IEEE_G) ? 9 : 20) + aSifsTime; + u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) | (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) | (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) | (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET)); - switch(eACI){ - case AC1_BK: - write_nic_dword(dev, AC_BK_PARAM, u4bAcParam); - break; - case AC0_BE: - write_nic_dword(dev, AC_BE_PARAM, u4bAcParam); - break; - case AC2_VI: - write_nic_dword(dev, AC_VI_PARAM, u4bAcParam); - break; - case AC3_VO: - write_nic_dword(dev, AC_VO_PARAM, u4bAcParam); - break; - default: - printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI); - break; + switch (eACI) { + case AC1_BK: + write_nic_dword(dev, AC_BK_PARAM, u4bAcParam); + break; + case AC0_BE: + write_nic_dword(dev, AC_BE_PARAM, u4bAcParam); + break; + case AC2_VI: + write_nic_dword(dev, AC_VI_PARAM, u4bAcParam); + break; + case AC3_VO: + write_nic_dword(dev, AC_VO_PARAM, u4bAcParam); + break; + default: + printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI); + break; } } ac_param += (sizeof(AC_PARAM)); @@ -2453,7 +2450,7 @@ void watch_dog_adaptive(unsigned long data) } // Tx High Power Mechanism. - if(CheckHighPower((struct net_device *)data)) + if (CheckHighPower((struct net_device *)data)) queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->tx_pw_wq); // Tx Power Tracking on 87SE. @@ -2461,26 +2458,26 @@ void watch_dog_adaptive(unsigned long data) TxPwrTracking87SE((struct net_device *)data); // Perform DIG immediately. - if(CheckDig((struct net_device *)data) == true) + if (CheckDig((struct net_device *)data) == true) queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_dig_wq); - rtl8180_watch_dog((struct net_device *)data); + rtl8180_watch_dog((struct net_device *)data); queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->GPIOChangeRFWorkItem); - priv->watch_dog_timer.expires = jiffies + MSECS(IEEE80211_WATCH_DOG_TIME); + priv->watch_dog_timer.expires = jiffies + MSECS(IEEE80211_WATCH_DOG_TIME); add_timer(&priv->watch_dog_timer); } static CHANNEL_LIST ChannelPlan[] = { - {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19}, //FCC - {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC - {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI - {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Spain. Change to ETSI. - {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //France. Change to ETSI. - {{14,36,40,44,48,52,56,60,64},9}, //MKK + {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19}, //FCC + {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Spain. Change to ETSI. + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //France. Change to ETSI. + {{14,36,40,44,48,52,56,60,64},9}, //MKK {{1,2,3,4,5,6,7,8,9,10,11,12,13,14, 36,40,44,48,52,56,60,64},22},//MKK1 {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Israel. - {{1,2,3,4,5,6,7,8,9,10,11,12,13,34,38,42,46},17}, // For 11a , TELEC + {{1,2,3,4,5,6,7,8,9,10,11,12,13,34,38,42,46},17}, // For 11a , TELEC {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13} //world wide 13: ch1~ch11 active scan, ch12~13 passive //lzm add 080826 }; @@ -2490,57 +2487,53 @@ static void rtl8180_set_channel_map(u8 channel_plan, struct ieee80211_device *ie int i; //lzm add 080826 - ieee->MinPassiveChnlNum=MAX_CHANNEL_NUMBER+1; - ieee->IbssStartChnl=0; - - switch (channel_plan) - { - case COUNTRY_CODE_FCC: - case COUNTRY_CODE_IC: - case COUNTRY_CODE_ETSI: - case COUNTRY_CODE_SPAIN: - case COUNTRY_CODE_FRANCE: - case COUNTRY_CODE_MKK: - case COUNTRY_CODE_MKK1: - case COUNTRY_CODE_ISRAEL: - case COUNTRY_CODE_TELEC: + ieee->MinPassiveChnlNum = MAX_CHANNEL_NUMBER+1; + ieee->IbssStartChnl = 0; + + switch (channel_plan) { + case COUNTRY_CODE_FCC: + case COUNTRY_CODE_IC: + case COUNTRY_CODE_ETSI: + case COUNTRY_CODE_SPAIN: + case COUNTRY_CODE_FRANCE: + case COUNTRY_CODE_MKK: + case COUNTRY_CODE_MKK1: + case COUNTRY_CODE_ISRAEL: + case COUNTRY_CODE_TELEC: { Dot11d_Init(ieee); ieee->bGlobalDomain = false; - if (ChannelPlan[channel_plan].Len != 0){ + if (ChannelPlan[channel_plan].Len != 0) { // Clear old channel map memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map)); // Set new channel map - for (i=0;ichannel_map[ChannelPlan[channel_plan].Channel[i]] = 1; } } break; } - case COUNTRY_CODE_GLOBAL_DOMAIN: + case COUNTRY_CODE_GLOBAL_DOMAIN: { GET_DOT11D_INFO(ieee)->bEnabled = 0; Dot11d_Reset(ieee); ieee->bGlobalDomain = true; break; } - case COUNTRY_CODE_WORLD_WIDE_13_INDEX://lzm add 080826 + case COUNTRY_CODE_WORLD_WIDE_13_INDEX://lzm add 080826 { - ieee->MinPassiveChnlNum=12; - ieee->IbssStartChnl= 10; - break; + ieee->MinPassiveChnlNum = 12; + ieee->IbssStartChnl = 10; + break; } - default: + default: { Dot11d_Init(ieee); ieee->bGlobalDomain = false; memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map)); - for (i=1;i<=14;i++) - { + for (i = 1; i <= 14; i++) GET_DOT11D_INFO(ieee)->channel_map[i] = 1; - } break; } } @@ -2609,12 +2602,12 @@ short rtl8180_init(struct net_device *dev) eeprom_93cx6_read(&eeprom, EEPROM_COUNTRY_CODE>>1, &eeprom_val); priv->channel_plan = eeprom_val & 0xFF; - if(priv->channel_plan > COUNTRY_CODE_GLOBAL_DOMAIN){ + if (priv->channel_plan > COUNTRY_CODE_GLOBAL_DOMAIN) { printk("rtl8180_init:Error channel plan! Set to default.\n"); priv->channel_plan = 0; } - DMESG("Channel plan is %d\n",priv->channel_plan); + DMESG("Channel plan is %d\n", priv->channel_plan); rtl8180_set_channel_map(priv->channel_plan, priv->ieee80211); //FIXME: these constants are placed in a bad pleace. @@ -2630,7 +2623,7 @@ short rtl8180_init(struct net_device *dev) priv->RFProgType = 0; priv->bInHctTest = false; - priv->irq_enabled=0; + priv->irq_enabled = 0; rtl8180_statistics_init(&priv->stats); rtl8180_link_detect_init(&priv->link_detect); @@ -2652,8 +2645,8 @@ short rtl8180_init(struct net_device *dev) priv->ieee80211->ps_is_queue_empty = rtl8180_is_tx_queue_empty; priv->hw_wep = hwwep; - priv->prism_hdr=0; - priv->dev=dev; + priv->prism_hdr = 0; + priv->dev = dev; priv->retry_rts = DEFAULT_RETRY_RTS; priv->retry_data = DEFAULT_RETRY_DATA; priv->RFChangeInProgress = false; @@ -2836,7 +2829,7 @@ short rtl8180_init(struct net_device *dev) eeprom_93cx6_read(&eeprom, EEPROM_SW_REVD_OFFSET, &eeprom_val); usValue = eeprom_val; - DMESG("usValue is 0x%x\n",usValue); + DMESG("usValue is 0x%x\n", usValue); //3Read AntennaDiversity // SW Antenna Diversity. @@ -2851,19 +2844,19 @@ short rtl8180_init(struct net_device *dev) else priv->EEPROMDefaultAntenna1 = true; - if( priv->RegSwAntennaDiversityMechanism == 0 ) // Auto + if (priv->RegSwAntennaDiversityMechanism == 0) // Auto /* 0: default from EEPROM. */ priv->bSwAntennaDiverity = priv->EEPROMSwAntennaDiversity; else /* 1:disable antenna diversity, 2: enable antenna diversity. */ - priv->bSwAntennaDiverity = ((priv->RegSwAntennaDiversityMechanism == 1)? false : true); + priv->bSwAntennaDiverity = ((priv->RegSwAntennaDiversityMechanism == 1) ? false : true); if (priv->RegDefaultAntenna == 0) /* 0: default from EEPROM. */ priv->bDefaultAntenna1 = priv->EEPROMDefaultAntenna1; else /* 1: main, 2: aux. */ - priv->bDefaultAntenna1 = ((priv->RegDefaultAntenna== 2) ? true : false); + priv->bDefaultAntenna1 = ((priv->RegDefaultAntenna == 2) ? true : false); /* rtl8185 can calc plcp len in HW.*/ priv->hw_plcp_len = 1; @@ -2871,17 +2864,17 @@ short rtl8180_init(struct net_device *dev) priv->plcp_preamble_mode = 2; /*the eeprom type is stored in RCR register bit #6 */ if (RCR_9356SEL & read_nic_dword(dev, RCR)) - priv->epromtype=EPROM_93c56; + priv->epromtype = EPROM_93c56; else - priv->epromtype=EPROM_93c46; + priv->epromtype = EPROM_93c46; eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *) dev->dev_addr, 3); - for(i=1,j=0; i<14; i+=2,j++){ + for (i = 1, j = 0; i < 14; i += 2, j++) { eeprom_93cx6_read(&eeprom, EPROM_TXPW_CH1_2 + j, &word); - priv->chtxpwr[i]=word & 0xff; - priv->chtxpwr[i+1]=(word & 0xff00)>>8; + priv->chtxpwr[i] = word & 0xff; + priv->chtxpwr[i+1] = (word & 0xff00)>>8; } for (i = 1, j = 0; i < 14; i += 2, j++) { eeprom_93cx6_read(&eeprom, EPROM_TXPW_OFDM_CH1_2 + j, &word); @@ -2908,7 +2901,7 @@ short rtl8180_init(struct net_device *dev) priv->ofdm_txpwr_base = (word>>4) & 0xf; eeprom_93cx6_read(&eeprom, EPROM_VERSION, &version); - DMESG("EEPROM version %x",version); + DMESG("EEPROM version %x", version); priv->rcr_csense = 3; eeprom_93cx6_read(&eeprom, ENERGY_TRESHOLD, &eeprom_val); @@ -2924,43 +2917,43 @@ short rtl8180_init(struct net_device *dev) priv->rf_set_chan = rtl8225z2_rf_set_chan; priv->rf_set_sens = NULL; - if (0!=alloc_rx_desc_ring(dev, priv->rxbuffersize, priv->rxringcount)) + if (0 != alloc_rx_desc_ring(dev, priv->rxbuffersize, priv->rxringcount)) return -ENOMEM; - if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount, + if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount, TX_MANAGEPRIORITY_RING_ADDR)) return -ENOMEM; - if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount, + if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount, TX_BKPRIORITY_RING_ADDR)) return -ENOMEM; - if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount, + if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount, TX_BEPRIORITY_RING_ADDR)) return -ENOMEM; - if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount, + if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount, TX_VIPRIORITY_RING_ADDR)) return -ENOMEM; - if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount, + if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount, TX_VOPRIORITY_RING_ADDR)) return -ENOMEM; - if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount, + if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount, TX_HIGHPRIORITY_RING_ADDR)) return -ENOMEM; - if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txbeaconcount, + if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txbeaconcount, TX_BEACON_RING_ADDR)) return -ENOMEM; - if(request_irq(dev->irq, (void *)rtl8180_interrupt, IRQF_SHARED, dev->name, dev)){ + if (request_irq(dev->irq, (void *)rtl8180_interrupt, IRQF_SHARED, dev->name, dev)) { DMESGE("Error allocating IRQ %d", dev->irq); return -1; - }else{ - priv->irq=dev->irq; - DMESG("IRQ %d",dev->irq); + } else { + priv->irq = dev->irq; + DMESG("IRQ %d", dev->irq); } return 0; @@ -2977,28 +2970,28 @@ void rtl8180_set_hw_wep(struct net_device *dev) u8 security; u32 key0_word4; - pgreg=read_nic_byte(dev, PGSELECT); - write_nic_byte(dev, PGSELECT, pgreg &~ (1<key0[3]& 0xff; - write_nic_dword(dev,KEY0,(priv->key0[0])); - write_nic_dword(dev,KEY0+4,(priv->key0[1])); - write_nic_dword(dev,KEY0+4+4,(priv->key0[2])); - write_nic_dword(dev,KEY0+4+4+4,(key0_word4)); - - security = read_nic_byte(dev,SECURITY); + key0_word4 &= ~0xff; + key0_word4 |= priv->key0[3] & 0xff; + write_nic_dword(dev, KEY0, (priv->key0[0])); + write_nic_dword(dev, KEY0+4, (priv->key0[1])); + write_nic_dword(dev, KEY0+4+4, (priv->key0[2])); + write_nic_dword(dev, KEY0+4+4+4, (key0_word4)); + + security = read_nic_byte(dev, SECURITY); security |= (1<> 24)); write_nic_byte(dev, 0x7e, ((phyw & 0x00ff0000) >> 16)); write_nic_byte(dev, 0x7d, ((phyw & 0x0000ff00) >> 8)); - write_nic_byte(dev, 0x7c, ((phyw & 0x000000ff) )); + write_nic_byte(dev, 0x7c, ((phyw & 0x000000ff))); /* this is ok to fail when we write AGC table. check for AGC table might be * done by masking with 0x7f instead of 0xff @@ -3066,13 +3059,13 @@ void rtl8185_write_phy(struct net_device *dev, u8 adr, u32 data) //if(phyr != (data&0xff)) DMESGW("Phy write timeout %x %x %x", phyr, data,adr); } -inline void write_phy_ofdm (struct net_device *dev, u8 adr, u32 data) +inline void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data) { data = data & 0xff; rtl8185_write_phy(dev, adr, data); } -void write_phy_cck (struct net_device *dev, u8 adr, u32 data) +void write_phy_cck(struct net_device *dev, u8 adr, u32 data) { data = data & 0xff; rtl8185_write_phy(dev, adr, data | 0x10000); @@ -3082,19 +3075,19 @@ void rtl8185_set_rate(struct net_device *dev) { int i; u16 word; - int basic_rate,min_rr_rate,max_rr_rate; + int basic_rate, min_rr_rate, max_rr_rate; basic_rate = ieeerate2rtlrate(240); min_rr_rate = ieeerate2rtlrate(60); max_rr_rate = ieeerate2rtlrate(240); write_nic_byte(dev, RESP_RATE, - max_rr_rate<dev_addr)[0]); - write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff ); + write_nic_dword(dev, MAC0, ((u32 *)dev->dev_addr)[0]); + write_nic_word(dev, MAC4, ((u32 *)dev->dev_addr)[1] & 0xffff); rtl8180_set_mode(dev, EPROM_CMD_NORMAL); rtl8180_update_msr(dev); @@ -3136,15 +3129,15 @@ void rtl8180_adapter_start(struct net_device *dev) */ write_nic_byte(dev, - CONFIG2, read_nic_byte(dev,CONFIG2) &~\ + CONFIG2, read_nic_byte(dev, CONFIG2) & ~\ (1<rf_init(dev); - if(priv->rf_set_sens != NULL) - priv->rf_set_sens(dev,priv->sens); + if (priv->rf_set_sens != NULL) + priv->rf_set_sens(dev, priv->sens); rtl8180_irq_enable(dev); netif_start_queue(dev); @@ -3183,8 +3176,8 @@ void rtl8180_start_tx_beacon(struct net_device *dev) rtl8180_irq_disable(dev); rtl8180_beacon_tx_enable(dev); - word = read_nic_word(dev, AtimWnd) &~ AtimWnd_AtimWnd; - write_nic_word(dev, AtimWnd,word);// word |= + word = read_nic_word(dev, AtimWnd) & ~AtimWnd_AtimWnd; + write_nic_word(dev, AtimWnd, word); // word |= word = read_nic_word(dev, BintrItv); word &= ~BintrItv_BintrItv; @@ -3215,7 +3208,7 @@ MgntActSet_802_11_PowerSaveMode( ) { // Currently, we do not change power save mode on IBSS mode. - if(priv->ieee80211->iw_mode == IW_MODE_ADHOC) + if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) return false; priv->ieee80211->ps = rtPsMode; @@ -3239,53 +3232,48 @@ void LeisurePSLeave(struct r8180_priv *priv) } } -void rtl8180_hw_wakeup_wq (struct work_struct *work) +void rtl8180_hw_wakeup_wq(struct work_struct *work) { struct delayed_work *dwork = to_delayed_work(work); - struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq); + struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, hw_wakeup_wq); struct net_device *dev = ieee->dev; rtl8180_hw_wakeup(dev); } -void rtl8180_hw_sleep_wq (struct work_struct *work) +void rtl8180_hw_sleep_wq(struct work_struct *work) { struct delayed_work *dwork = to_delayed_work(work); - struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq); + struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, hw_sleep_wq); struct net_device *dev = ieee->dev; rtl8180_hw_sleep_down(dev); } -static void MgntLinkKeepAlive(struct r8180_priv *priv ) +static void MgntLinkKeepAlive(struct r8180_priv *priv) { if (priv->keepAliveLevel == 0) return; - if(priv->ieee80211->state == IEEE80211_LINKED) - { + if (priv->ieee80211->state == IEEE80211_LINKED) { // // Keep-Alive. // - if ( (priv->keepAliveLevel== 2) || + if ((priv->keepAliveLevel == 2) || (priv->link_detect.LastNumTxUnicast == priv->NumTxUnicast && - priv->link_detect.LastNumRxUnicast == priv->ieee80211->NumRxUnicast ) - ) - { + priv->link_detect.LastNumRxUnicast == priv->ieee80211->NumRxUnicast) + ) { priv->link_detect.IdleCount++; // // Send a Keep-Alive packet packet to AP if we had been idle for a while. // - if(priv->link_detect.IdleCount >= ((KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD)-1) ) - { + if (priv->link_detect.IdleCount >= ((KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD)-1)) { priv->link_detect.IdleCount = 0; ieee80211_sta_ps_send_null_frame(priv->ieee80211, false); } - } - else - { + } else { priv->link_detect.IdleCount = 0; } priv->link_detect.LastNumTxUnicast = priv->NumTxUnicast; @@ -3303,19 +3291,18 @@ void rtl8180_watch_dog(struct net_device *dev) u32 TotalRxNum = 0; u16 SlotIndex = 0; u16 i = 0; - if(priv->ieee80211->actscanning == false){ - if((priv->ieee80211->iw_mode != IW_MODE_ADHOC) && (priv->ieee80211->state == IEEE80211_NOLINK) && (priv->ieee80211->beinretry == false) && (priv->eRFPowerState == eRfOn)){ + if (priv->ieee80211->actscanning == false) { + if ((priv->ieee80211->iw_mode != IW_MODE_ADHOC) && (priv->ieee80211->state == IEEE80211_NOLINK) && (priv->ieee80211->beinretry == false) && (priv->eRFPowerState == eRfOn)) IPSEnter(dev); - } } //YJ,add,080828,for link state check - if((priv->ieee80211->state == IEEE80211_LINKED) && (priv->ieee80211->iw_mode == IW_MODE_INFRA)){ + if ((priv->ieee80211->state == IEEE80211_LINKED) && (priv->ieee80211->iw_mode == IW_MODE_INFRA)) { SlotIndex = (priv->link_detect.SlotIndex++) % priv->link_detect.SlotNum; priv->link_detect.RxFrameNum[SlotIndex] = priv->ieee80211->NumRxDataInPeriod + priv->ieee80211->NumRxBcnInPeriod; - for( i=0; ilink_detect.SlotNum; i++ ) - TotalRxNum+= priv->link_detect.RxFrameNum[i]; + for (i = 0; i < priv->link_detect.SlotNum; i++) + TotalRxNum += priv->link_detect.RxFrameNum[i]; - if(TotalRxNum == 0){ + if (TotalRxNum == 0) { priv->ieee80211->state = IEEE80211_ASSOCIATING; queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq); } @@ -3329,20 +3316,20 @@ void rtl8180_watch_dog(struct net_device *dev) priv->bLeisurePs = true; else if (priv->PowerProfile == POWER_PROFILE_AC) { LeisurePSLeave(priv); - priv->bLeisurePs= false; + priv->bLeisurePs = false; } - if(priv->ieee80211->state == IEEE80211_LINKED){ + if (priv->ieee80211->state == IEEE80211_LINKED) { priv->link_detect.NumRxOkInPeriod = priv->ieee80211->NumRxDataInPeriod; - if( priv->link_detect.NumRxOkInPeriod> 666 || - priv->link_detect.NumTxOkInPeriod> 666 ) { + if (priv->link_detect.NumRxOkInPeriod > 666 || + priv->link_detect.NumTxOkInPeriod > 666) { bBusyTraffic = true; } - if(((priv->link_detect.NumRxOkInPeriod + priv->link_detect.NumTxOkInPeriod) > 8) + if (((priv->link_detect.NumRxOkInPeriod + priv->link_detect.NumTxOkInPeriod) > 8) || (priv->link_detect.NumRxOkInPeriod > 2)) { - bEnterPS= false; + bEnterPS = false; } else - bEnterPS= true; + bEnterPS = true; if (bEnterPS) LeisurePSEnter(priv); @@ -3361,17 +3348,17 @@ int _rtl8180_up(struct net_device *dev) { struct r8180_priv *priv = ieee80211_priv(dev); - priv->up=1; + priv->up = 1; DMESG("Bringing up iface"); rtl8185b_adapter_start(dev); rtl8185b_rx_enable(dev); rtl8185b_tx_enable(dev); - if(priv->bInactivePs){ - if(priv->ieee80211->iw_mode == IW_MODE_ADHOC) + if (priv->bInactivePs) { + if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) IPSLeave(dev); } - timer_rate_adaptive((unsigned long)dev); + timer_rate_adaptive((unsigned long)dev); watch_dog_adaptive((unsigned long)dev); if (priv->bSwAntennaDiverity) SwAntennaDiversityTimerCallback(dev); @@ -3394,7 +3381,8 @@ int rtl8180_up(struct net_device *dev) { struct r8180_priv *priv = ieee80211_priv(dev); - if (priv->up == 1) return -1; + if (priv->up == 1) + return -1; return _rtl8180_up(dev); } @@ -3418,7 +3406,7 @@ int rtl8180_down(struct net_device *dev) if (priv->up == 0) return -1; - priv->up=0; + priv->up = 0; ieee80211_softmac_stop_protocol(priv->ieee80211); /* FIXME */ @@ -3434,8 +3422,8 @@ int rtl8180_down(struct net_device *dev) cancel_delayed_work(&priv->ieee80211->hw_dig_wq); cancel_delayed_work(&priv->ieee80211->tx_pw_wq); del_timer_sync(&priv->SwAntennaDiversityTimer); - SetZebraRFPowerState8185(dev,eRfOff); - memset(&(priv->ieee80211->current_network),0,sizeof(struct ieee80211_network)); + SetZebraRFPowerState8185(dev, eRfOff); + memset(&(priv->ieee80211->current_network), 0, sizeof(struct ieee80211_network)); priv->ieee80211->state = IEEE80211_NOLINK; return 0; } @@ -3485,7 +3473,7 @@ static void r8180_set_multicast(struct net_device *dev) struct r8180_priv *priv = ieee80211_priv(dev); short promisc; - promisc = (dev->flags & IFF_PROMISC) ? 1:0; + promisc = (dev->flags & IFF_PROMISC) ? 1 : 0; if (promisc != priv->promisc) rtl8180_restart(dev); @@ -3502,7 +3490,7 @@ int r8180_set_mac_adr(struct net_device *dev, void *mac) memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); - if(priv->ieee80211->iw_mode == IW_MODE_MASTER) + if (priv->ieee80211->iw_mode == IW_MODE_MASTER) memcpy(priv->ieee80211->current_network.bssid, dev->dev_addr, ETH_ALEN); if (priv->up) { @@ -3520,7 +3508,7 @@ int rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); struct iwreq *wrq = (struct iwreq *) rq; - int ret=-1; + int ret = -1; switch (cmd) { case RTL_IOCTL_WPA_SUPPLICANT: @@ -3551,21 +3539,21 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev, { unsigned long ioaddr = 0; struct net_device *dev = NULL; - struct r8180_priv *priv= NULL; + struct r8180_priv *priv = NULL; u8 unit = 0; unsigned long pmem_start, pmem_len, pmem_flags; DMESG("Configuring chip resources"); - if( pci_enable_device (pdev) ){ + if (pci_enable_device(pdev)) { DMESG("Failed to enable PCI device"); return -EIO; } pci_set_master(pdev); pci_set_dma_mask(pdev, 0xffffff00ULL); - pci_set_consistent_dma_mask(pdev,0xffffff00ULL); + pci_set_consistent_dma_mask(pdev, 0xffffff00ULL); dev = alloc_ieee80211(sizeof(struct r8180_priv)); if (!dev) return -ENOMEM; @@ -3580,20 +3568,20 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev, pmem_start = pci_resource_start(pdev, 1); pmem_len = pci_resource_len(pdev, 1); - pmem_flags = pci_resource_flags (pdev, 1); + pmem_flags = pci_resource_flags(pdev, 1); if (!(pmem_flags & IORESOURCE_MEM)) { DMESG("region #1 not a MMIO resource, aborting"); goto fail; } - if( ! request_mem_region(pmem_start, pmem_len, RTL8180_MODULE_NAME)) { + if (!request_mem_region(pmem_start, pmem_len, RTL8180_MODULE_NAME)) { DMESG("request_mem_region failed!"); goto fail; } - ioaddr = (unsigned long)ioremap_nocache( pmem_start, pmem_len); - if( ioaddr == (unsigned long)NULL ){ + ioaddr = (unsigned long)ioremap_nocache(pmem_start, pmem_len); + if (ioaddr == (unsigned long)NULL) { DMESG("ioremap failed!"); goto fail1; } @@ -3610,16 +3598,16 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev, dev->netdev_ops = &rtl8180_netdev_ops; dev->wireless_handlers = &r8180_wx_handlers_def; - dev->type=ARPHRD_ETHER; + dev->type = ARPHRD_ETHER; dev->watchdog_timeo = HZ*3; - if (dev_alloc_name(dev, ifname) < 0){ + if (dev_alloc_name(dev, ifname) < 0) { DMESG("Oops: devname already taken! Trying wlan%%d...\n"); ifname = "wlan%d"; dev_alloc_name(dev, ifname); } - if(rtl8180_init(dev)!=0){ + if (rtl8180_init(dev) != 0) { DMESG("Initialization failed"); goto fail1; } @@ -3633,16 +3621,16 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev, DMESG("Driver probe completed\n"); return 0; fail1: - if( dev->mem_start != (unsigned long)NULL ){ - iounmap( (void *)dev->mem_start ); - release_mem_region( pci_resource_start(pdev, 1), - pci_resource_len(pdev, 1) ); + if (dev->mem_start != (unsigned long)NULL) { + iounmap((void *)dev->mem_start); + release_mem_region(pci_resource_start(pdev, 1), + pci_resource_len(pdev, 1)); } fail: - if(dev){ + if (dev) { if (priv->irq) { free_irq(dev->irq, dev); - dev->irq=0; + dev->irq = 0; } free_ieee80211(dev); } @@ -3670,19 +3658,19 @@ static void __devexit rtl8180_pci_remove(struct pci_dev *pdev) rtl8180_reset(dev); mdelay(10); - if(priv->irq){ - DMESG("Freeing irq %d",dev->irq); + if (priv->irq) { + DMESG("Freeing irq %d", dev->irq); free_irq(dev->irq, dev); - priv->irq=0; + priv->irq = 0; } free_rx_desc_ring(dev); free_tx_desc_rings(dev); - if( dev->mem_start != (unsigned long)NULL ){ - iounmap( (void *)dev->mem_start ); - release_mem_region( pci_resource_start(pdev, 1), - pci_resource_len(pdev, 1) ); + if (dev->mem_start != (unsigned long)NULL) { + iounmap((void *)dev->mem_start); + release_mem_region(pci_resource_start(pdev, 1), + pci_resource_len(pdev, 1)); } free_ieee80211(dev); @@ -3742,7 +3730,7 @@ static int __init rtl8180_pci_module_init(void) static void __exit rtl8180_pci_module_exit(void) { - pci_unregister_driver (&rtl8180_pci_driver); + pci_unregister_driver(&rtl8180_pci_driver); rtl8180_proc_module_remove(); ieee80211_crypto_tkip_exit(); ieee80211_crypto_ccmp_exit(); @@ -3757,15 +3745,15 @@ void rtl8180_try_wake_queue(struct net_device *dev, int pri) short enough_desc; struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - spin_lock_irqsave(&priv->tx_lock,flags); - enough_desc = check_nic_enought_desc(dev,pri); - spin_unlock_irqrestore(&priv->tx_lock,flags); + spin_lock_irqsave(&priv->tx_lock, flags); + enough_desc = check_nic_enought_desc(dev, pri); + spin_unlock_irqrestore(&priv->tx_lock, flags); - if(enough_desc) + if (enough_desc) ieee80211_rtl_wake_queue(priv->ieee80211); } -void rtl8180_tx_isr(struct net_device *dev, int pri,short error) +void rtl8180_tx_isr(struct net_device *dev, int pri, short error) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); u32 *tail; //tail virtual addr @@ -3777,64 +3765,65 @@ void rtl8180_tx_isr(struct net_device *dev, int pri,short error) unsigned long flag; /* physical addr are ok on 32 bits since we set DMA mask*/ int offs; - int j,i; + int j, i; int hd; - if (error) priv->stats.txretry++; //tony 20060601 - spin_lock_irqsave(&priv->tx_lock,flag); - switch(pri) { + if (error) + priv->stats.txretry++; //tony 20060601 + spin_lock_irqsave(&priv->tx_lock, flag); + switch (pri) { case MANAGE_PRIORITY: tail = priv->txmapringtail; begin = priv->txmapring; head = priv->txmapringhead; - nic = read_nic_dword(dev,TX_MANAGEPRIORITY_RING_ADDR); + nic = read_nic_dword(dev, TX_MANAGEPRIORITY_RING_ADDR); nicbegin = priv->txmapringdma; break; case BK_PRIORITY: tail = priv->txbkpringtail; begin = priv->txbkpring; head = priv->txbkpringhead; - nic = read_nic_dword(dev,TX_BKPRIORITY_RING_ADDR); + nic = read_nic_dword(dev, TX_BKPRIORITY_RING_ADDR); nicbegin = priv->txbkpringdma; break; case BE_PRIORITY: tail = priv->txbepringtail; begin = priv->txbepring; head = priv->txbepringhead; - nic = read_nic_dword(dev,TX_BEPRIORITY_RING_ADDR); + nic = read_nic_dword(dev, TX_BEPRIORITY_RING_ADDR); nicbegin = priv->txbepringdma; break; case VI_PRIORITY: tail = priv->txvipringtail; begin = priv->txvipring; head = priv->txvipringhead; - nic = read_nic_dword(dev,TX_VIPRIORITY_RING_ADDR); + nic = read_nic_dword(dev, TX_VIPRIORITY_RING_ADDR); nicbegin = priv->txvipringdma; break; case VO_PRIORITY: tail = priv->txvopringtail; begin = priv->txvopring; head = priv->txvopringhead; - nic = read_nic_dword(dev,TX_VOPRIORITY_RING_ADDR); + nic = read_nic_dword(dev, TX_VOPRIORITY_RING_ADDR); nicbegin = priv->txvopringdma; break; case HI_PRIORITY: tail = priv->txhpringtail; begin = priv->txhpring; head = priv->txhpringhead; - nic = read_nic_dword(dev,TX_HIGHPRIORITY_RING_ADDR); + nic = read_nic_dword(dev, TX_HIGHPRIORITY_RING_ADDR); nicbegin = priv->txhpringdma; break; default: - spin_unlock_irqrestore(&priv->tx_lock,flag); + spin_unlock_irqrestore(&priv->tx_lock, flag); return ; } - nicv = (u32*) ((nic - nicbegin) + (u8*)begin); - if((head <= tail && (nicv > tail || nicv < head)) || - (head > tail && (nicv > tail && nicv < head))){ + nicv = (u32 *)((nic - nicbegin) + (u8*)begin); + if ((head <= tail && (nicv > tail || nicv < head)) || + (head > tail && (nicv > tail && nicv < head))) { DMESGW("nic has lost pointer"); - spin_unlock_irqrestore(&priv->tx_lock,flag); + spin_unlock_irqrestore(&priv->tx_lock, flag); rtl8180_restart(dev); return; } @@ -3844,22 +3833,22 @@ void rtl8180_tx_isr(struct net_device *dev, int pri,short error) * and the previous of the pointed (might be in process ??) */ offs = (nic - nicbegin); - offs = offs / 8 /4; - hd = (head - begin) /8; + offs = offs / 8 / 4; + hd = (head - begin) / 8; - if(offs >= hd) + if (offs >= hd) j = offs - hd; else - j = offs + (priv->txringcount -1 -hd); + j = offs + (priv->txringcount-1-hd); - j-=2; - if(j<0) j=0; + j -= 2; + if (j < 0) + j = 0; - for(i=0;iCurrRetryCnt += (u16)((*head) & (0x000000ff)); if (!error) priv->NumTxOkTotal++; @@ -3868,12 +3857,12 @@ void rtl8180_tx_isr(struct net_device *dev, int pri,short error) if (!error) priv->NumTxOkBytesTotal += (*(head+3)) & (0x00000fff); - *head = *head &~ (1<<31); + *head = *head & ~(1<<31); - if((head - begin)/8 == priv->txringcount-1) - head=begin; + if ((head - begin)/8 == priv->txringcount-1) + head = begin; else - head+=8; + head += 8; } /* the head has been moved to the last certainly TXed @@ -3885,14 +3874,14 @@ void rtl8180_tx_isr(struct net_device *dev, int pri,short error) * TXed no memory leak occour at all. */ - switch(pri) { + switch (pri) { case MANAGE_PRIORITY: priv->txmapringhead = head; - if(priv->ack_tx_to_ieee){ - if(rtl8180_is_tx_queue_empty(dev)){ + if (priv->ack_tx_to_ieee) { + if (rtl8180_is_tx_queue_empty(dev)) { priv->ack_tx_to_ieee = 0; - ieee80211_ps_tx_ack(priv->ieee80211,!error); + ieee80211_ps_tx_ack(priv->ieee80211, !error); } } break; @@ -3913,17 +3902,17 @@ void rtl8180_tx_isr(struct net_device *dev, int pri,short error) break; } - spin_unlock_irqrestore(&priv->tx_lock,flag); + spin_unlock_irqrestore(&priv->tx_lock, flag); } void rtl8180_tx_irq_wq(struct work_struct *work) { struct delayed_work *dwork = to_delayed_work(work); - struct ieee80211_device * ieee = (struct ieee80211_device*) - container_of(dwork, struct ieee80211_device, watch_dog_wq); + struct ieee80211_device * ieee = (struct ieee80211_device *) + container_of(dwork, struct ieee80211_device, watch_dog_wq); struct net_device *dev = ieee->dev; - rtl8180_tx_isr(dev,MANAGE_PRIORITY,0); + rtl8180_tx_isr(dev, MANAGE_PRIORITY, 0); } irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs) { @@ -3933,18 +3922,19 @@ irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs) u32 inta; /* We should return IRQ_NONE, but for now let me keep this */ - if(priv->irq_enabled == 0) return IRQ_HANDLED; + if (priv->irq_enabled == 0) + return IRQ_HANDLED; - spin_lock_irqsave(&priv->irq_th_lock,flags); + spin_lock_irqsave(&priv->irq_th_lock, flags); //ISR: 4bytes inta = read_nic_dword(dev, ISR);// & priv->IntrMask; - write_nic_dword(dev,ISR,inta); // reset int situation + write_nic_dword(dev, ISR, inta); // reset int situation priv->stats.shints++; - if(!inta){ - spin_unlock_irqrestore(&priv->irq_th_lock,flags); + if (!inta) { + spin_unlock_irqrestore(&priv->irq_th_lock, flags); return IRQ_HANDLED; /* most probably we can safely return IRQ_NONE, @@ -3960,8 +3950,8 @@ irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs) priv->stats.ints++; - if(!netif_running(dev)) { - spin_unlock_irqrestore(&priv->irq_th_lock,flags); + if (!netif_running(dev)) { + spin_unlock_irqrestore(&priv->irq_th_lock, flags); return IRQ_HANDLED; } @@ -3975,70 +3965,70 @@ irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs) priv->stats.txbeaconerr++; if (inta & IMR_TMGDOK) - rtl8180_tx_isr(dev,MANAGE_PRIORITY,0); + rtl8180_tx_isr(dev, MANAGE_PRIORITY, 0); - if(inta & ISR_THPDER){ + if (inta & ISR_THPDER) { priv->stats.txhperr++; - rtl8180_tx_isr(dev,HI_PRIORITY,1); + rtl8180_tx_isr(dev, HI_PRIORITY, 1); priv->ieee80211->stats.tx_errors++; } - if(inta & ISR_THPDOK){ //High priority tx ok + if (inta & ISR_THPDOK) { //High priority tx ok priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828 priv->stats.txhpokint++; - rtl8180_tx_isr(dev,HI_PRIORITY,0); + rtl8180_tx_isr(dev, HI_PRIORITY, 0); } - if(inta & ISR_RER) { + if (inta & ISR_RER) priv->stats.rxerr++; - } - if(inta & ISR_TBKDER){ //corresponding to BK_PRIORITY + + if (inta & ISR_TBKDER) { //corresponding to BK_PRIORITY priv->stats.txbkperr++; priv->ieee80211->stats.tx_errors++; - rtl8180_tx_isr(dev,BK_PRIORITY,1); + rtl8180_tx_isr(dev, BK_PRIORITY, 1); rtl8180_try_wake_queue(dev, BE_PRIORITY); } - if(inta & ISR_TBEDER){ //corresponding to BE_PRIORITY + if (inta & ISR_TBEDER) { //corresponding to BE_PRIORITY priv->stats.txbeperr++; priv->ieee80211->stats.tx_errors++; - rtl8180_tx_isr(dev,BE_PRIORITY,1); + rtl8180_tx_isr(dev, BE_PRIORITY, 1); rtl8180_try_wake_queue(dev, BE_PRIORITY); } - if(inta & ISR_TNPDER){ //corresponding to VO_PRIORITY + if (inta & ISR_TNPDER) { //corresponding to VO_PRIORITY priv->stats.txnperr++; priv->ieee80211->stats.tx_errors++; - rtl8180_tx_isr(dev,NORM_PRIORITY,1); + rtl8180_tx_isr(dev, NORM_PRIORITY, 1); rtl8180_try_wake_queue(dev, NORM_PRIORITY); } - if(inta & ISR_TLPDER){ //corresponding to VI_PRIORITY + if (inta & ISR_TLPDER) { //corresponding to VI_PRIORITY priv->stats.txlperr++; priv->ieee80211->stats.tx_errors++; - rtl8180_tx_isr(dev,LOW_PRIORITY,1); + rtl8180_tx_isr(dev, LOW_PRIORITY, 1); rtl8180_try_wake_queue(dev, LOW_PRIORITY); } - if(inta & ISR_ROK){ + if (inta & ISR_ROK) { priv->stats.rxint++; tasklet_schedule(&priv->irq_rx_tasklet); } - if(inta & ISR_RQoSOK ){ + if (inta & ISR_RQoSOK) { priv->stats.rxint++; tasklet_schedule(&priv->irq_rx_tasklet); } - if(inta & ISR_BcnInt) { + + if (inta & ISR_BcnInt) rtl8180_prepare_beacon(dev); - } - if(inta & ISR_RDU){ + if (inta & ISR_RDU) { DMESGW("No RX descriptor available"); priv->stats.rxrdu++; tasklet_schedule(&priv->irq_rx_tasklet); } - if(inta & ISR_RXFOVW){ + if (inta & ISR_RXFOVW) { priv->stats.rxoverflow++; tasklet_schedule(&priv->irq_rx_tasklet); } @@ -4046,39 +4036,39 @@ irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs) if (inta & ISR_TXFOVW) priv->stats.txoverflow++; - if(inta & ISR_TNPDOK){ //Normal priority tx ok + if (inta & ISR_TNPDOK) { //Normal priority tx ok priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828 priv->stats.txnpokint++; - rtl8180_tx_isr(dev,NORM_PRIORITY,0); + rtl8180_tx_isr(dev, NORM_PRIORITY, 0); } - if(inta & ISR_TLPDOK){ //Low priority tx ok + if (inta & ISR_TLPDOK) { //Low priority tx ok priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828 priv->stats.txlpokint++; - rtl8180_tx_isr(dev,LOW_PRIORITY,0); + rtl8180_tx_isr(dev, LOW_PRIORITY, 0); rtl8180_try_wake_queue(dev, LOW_PRIORITY); } - if(inta & ISR_TBKDOK){ //corresponding to BK_PRIORITY + if (inta & ISR_TBKDOK) { //corresponding to BK_PRIORITY priv->stats.txbkpokint++; priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828 - rtl8180_tx_isr(dev,BK_PRIORITY,0); + rtl8180_tx_isr(dev, BK_PRIORITY, 0); rtl8180_try_wake_queue(dev, BE_PRIORITY); } - if(inta & ISR_TBEDOK){ //corresponding to BE_PRIORITY + if (inta & ISR_TBEDOK) { //corresponding to BE_PRIORITY priv->stats.txbeperr++; priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828 - rtl8180_tx_isr(dev,BE_PRIORITY,0); + rtl8180_tx_isr(dev, BE_PRIORITY, 0); rtl8180_try_wake_queue(dev, BE_PRIORITY); } force_pci_posting(dev); - spin_unlock_irqrestore(&priv->irq_th_lock,flags); + spin_unlock_irqrestore(&priv->irq_th_lock, flags); return IRQ_HANDLED; } -void rtl8180_irq_rx_tasklet(struct r8180_priv* priv) +void rtl8180_irq_rx_tasklet(struct r8180_priv *priv) { rtl8180_rx(priv->dev); } @@ -4095,10 +4085,10 @@ void GPIOChangeRFWorkItemCallBack(struct work_struct *work) char *argv[3]; static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh"; - static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL}; + static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL}; static int readf_count = 0; - if(readf_count % 10 == 0) + if (readf_count % 10 == 0) priv->PowerProfile = read_acadapter_file("/proc/acpi/ac_adapter/AC0/state"); readf_count = (readf_count+1)%0xffff; -- cgit v1.2.3 From 3f56c109d0ef8437d89cdb84af02728ec9cc1150 Mon Sep 17 00:00:00 2001 From: "Prashant P. Shah" Date: Thu, 13 May 2010 23:09:08 +0530 Subject: Staging: rtl8187se: fixed C99 comments style issues in r8180_core.c This is a patch to the r8180_core.c file that fixes the C99 comments style issues found by the checkpatch.pl tool. Signed-off-by: Prashant P. Shah Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_core.c | 456 +++++++++++++++++---------------- 1 file changed, 233 insertions(+), 223 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 37be5aedf52f..dacefea78113 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -620,7 +620,7 @@ void fix_rx_fifo(struct net_device *dev) struct buffer *rxbuf; u8 rx_desc_size; - rx_desc_size = 8; // 4*8 = 32 bytes + rx_desc_size = 8; /* 4*8 = 32 bytes */ for (tmp = priv->rxring, rxbuf = priv->rxbufferhead; (tmp < (priv->rxring)+(priv->rxringcount)*rx_desc_size); @@ -673,7 +673,7 @@ void rtl8180_RSSI_calc(struct net_device *dev, u8 *rssi, u8 *qual) q = *qual; orig_qual = *qual; - _rssi = 0; // avoid gcc complains.. + _rssi = 0; /* avoid gcc complains.. */ if (q <= 0x4e) { temp = QUALITY_MAP[q]; @@ -1025,7 +1025,7 @@ short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count, } break; } - *tmp = *tmp & ~(1<<31); // descriptor empty, owned by the drv + *tmp = *tmp & ~(1<<31); /* descriptor empty, owned by the drv */ *(tmp+2) = (u32)dma_tmp; *(tmp+3) = bufsize; @@ -1131,7 +1131,7 @@ short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count) void *buf; u8 rx_desc_size; - rx_desc_size = 8; // 4*8 = 32 bytes + rx_desc_size = 8; /* 4*8 = 32 bytes */ if ((bufsize & 0xfff) != bufsize) { DMESGE("RX buffer allocation too large"); @@ -1167,15 +1167,15 @@ short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count) DMESGE("Unable to allocate mem RX buf"); return -1; } - *tmp = 0; // zero pads the header of the descriptor + *tmp = 0; /* zero pads the header of the descriptor */ *tmp = *tmp | (bufsize&0xfff); *(tmp+2) = (u32)dma_tmp; - *tmp = *tmp | (1<<31); // descriptor void, owned by the NIC + *tmp = *tmp | (1<<31); /* descriptor void, owned by the NIC */ tmp = tmp+rx_desc_size; } - *(tmp-rx_desc_size) = *(tmp-rx_desc_size) | (1<<30); // this is the last descriptor + *(tmp-rx_desc_size) = *(tmp-rx_desc_size) | (1<<30); /* this is the last descriptor */ return 0; } @@ -1330,15 +1330,14 @@ u16 N_DBPSOfRate(u16 DataRate) return N_DBPS; } -// -// Description: -// For Netgear case, they want good-looking singal strength. -// +/* + * For Netgear case, they want good-looking singal strength. + */ long NetgearSignalStrengthTranslate(long LastSS, long CurrSS) { long RetSS; - // Step 1. Scale mapping. + /* Step 1. Scale mapping. */ if (CurrSS >= 71 && CurrSS <= 100) RetSS = 90 + ((CurrSS - 70) / 3); else if (CurrSS >= 41 && CurrSS <= 70) @@ -1360,39 +1359,37 @@ long NetgearSignalStrengthTranslate(long LastSS, long CurrSS) else RetSS = CurrSS; - // Step 2. Smoothing. + /* Step 2. Smoothing. */ if (LastSS > 0) RetSS = ((LastSS * 5) + (RetSS) + 5) / 6; return RetSS; } -// -// Description: -// Translate 0-100 signal strength index into dBm. -// +/* + * Translate 0-100 signal strength index into dBm. + */ long TranslateToDbm8185(u8 SignalStrengthIndex) { long SignalPower; - // Translate to dBm (x=0.5y-95). + /* Translate to dBm (x=0.5y-95). */ SignalPower = (long)((SignalStrengthIndex + 1) >> 1); SignalPower -= 95; return SignalPower; } -// -// Description: -// Perform signal smoothing for dynamic mechanism. -// This is different with PerformSignalSmoothing8185 in smoothing fomula. -// No dramatic adjustion is apply because dynamic mechanism need some degree -// of correctness. Ported from 8187B. -// +/* + * Perform signal smoothing for dynamic mechanism. + * This is different with PerformSignalSmoothing8185 in smoothing fomula. + * No dramatic adjustion is apply because dynamic mechanism need some degree + * of correctness. Ported from 8187B. + */ void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv, bool bCckRate) { - // Determin the current packet is CCK rate. + /* Determin the current packet is CCK rate. */ priv->bCurCCKPkt = bCckRate; if (priv->UndecoratedSmoothedSS >= 0) @@ -1409,7 +1406,9 @@ void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv, } -/* This is rough RX isr handling routine*/ +/* + * This is rough RX isr handling routine + */ void rtl8180_rx(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); @@ -1446,7 +1445,7 @@ void rtl8180_rx(struct net_device *dev) if ((*(priv->rxringtail)) & (1<<31)) { /* we have got an RX int, but the descriptor - * we are pointing is empty*/ + * we are pointing is empty */ priv->stats.rxnodata++; priv->ieee80211->stats.rx_errors++; @@ -1476,7 +1475,7 @@ void rtl8180_rx(struct net_device *dev) if (*(priv->rxringtail) & (1<<27)) { priv->stats.rxdmafail++; - //DMESG("EE: RX DMA FAILED at buffer pointed by descriptor %x",(u32)priv->rxringtail); + /* DMESG("EE: RX DMA FAILED at buffer pointed by descriptor %x",(u32)priv->rxringtail); */ goto drop; } @@ -1558,30 +1557,30 @@ void rtl8180_rx(struct net_device *dev) stats.rate = rtl8180_rate2rate(rate); Antenna = (((*(priv->rxringtail+3)) & (0x00008000)) == 0) ? 0 : 1; - if (!rtl8180_IsWirelessBMode(stats.rate)) { // OFDM rate. - RxAGC_dBm = rxpower+1; //bias - } else { // CCK rate. - RxAGC_dBm = signal; //bit 0 discard + if (!rtl8180_IsWirelessBMode(stats.rate)) { /* OFDM rate. */ + RxAGC_dBm = rxpower+1; /* bias */ + } else { /* CCK rate. */ + RxAGC_dBm = signal; /* bit 0 discard */ - LNA = (u8) (RxAGC_dBm & 0x60) >> 5 ; //bit 6~ bit 5 - BB = (u8) (RxAGC_dBm & 0x1F); // bit 4 ~ bit 0 + LNA = (u8) (RxAGC_dBm & 0x60) >> 5; /* bit 6~ bit 5 */ + BB = (u8) (RxAGC_dBm & 0x1F); /* bit 4 ~ bit 0 */ - RxAGC_dBm = -(LNA_gain[LNA] + (BB*2)); //Pin_11b=-(LNA_gain+BB_gain) (dBm) + RxAGC_dBm = -(LNA_gain[LNA] + (BB*2)); /* Pin_11b=-(LNA_gain+BB_gain) (dBm) */ - RxAGC_dBm += 4; //bias + RxAGC_dBm += 4; /* bias */ } - if (RxAGC_dBm & 0x80) //absolute value + if (RxAGC_dBm & 0x80) /* absolute value */ RXAGC = ~(RxAGC_dBm)+1; bCckRate = rtl8180_IsWirelessBMode(stats.rate); - // Translate RXAGC into 1-100. - if (!rtl8180_IsWirelessBMode(stats.rate)) { // OFDM rate. + /* Translate RXAGC into 1-100. */ + if (!rtl8180_IsWirelessBMode(stats.rate)) { /* OFDM rate. */ if (RXAGC > 90) RXAGC = 90; else if (RXAGC < 25) RXAGC = 25; RXAGC = (90-RXAGC)*100/65; - } else { // CCK rate. + } else { /* CCK rate. */ if (RXAGC > 95) RXAGC = 95; else if (RXAGC < 30) @@ -1594,19 +1593,19 @@ void rtl8180_rx(struct net_device *dev) priv->RSSI = RSSI; /* SQ translation formula is provided by SD3 DZ. 2006.06.27 */ if (quality >= 127) - quality = 1;//0; //0 will cause epc to show signal zero , walk aroud now; + quality = 1; /*0; */ /* 0 will cause epc to show signal zero , walk aroud now; */ else if (quality < 27) quality = 100; else quality = 127 - quality; priv->SignalQuality = quality; - stats.signal = (u8)quality;//priv->wstats.qual.level = priv->SignalStrength; + stats.signal = (u8)quality; /*priv->wstats.qual.level = priv->SignalStrength; */ stats.signalstrength = RXAGC; if (stats.signalstrength > 100) stats.signalstrength = 100; stats.signalstrength = (stats.signalstrength * 70)/100 + 30; - // printk("==========================>rx : RXAGC is %d,signalstrength is %d\n",RXAGC,stats.signalstrength); + /* printk("==========================>rx : RXAGC is %d,signalstrength is %d\n",RXAGC,stats.signalstrength); */ stats.rssi = priv->wstats.qual.qual = priv->SignalQuality; stats.noise = priv->wstats.qual.noise = 100 - priv->wstats.qual.qual; bHwError = (((*(priv->rxringtail)) & (0x00000fff)) == 4080) | (((*(priv->rxringtail)) & (0x04000000)) != 0) @@ -1627,24 +1626,23 @@ void rtl8180_rx(struct net_device *dev) * because dynamic mechanism need some degree * of correctness. */ PerformUndecoratedSignalSmoothing8185(priv, bCckRate); - // - // For good-looking singal strength. - // + + /* For good-looking singal strength. */ SignalStrengthIndex = NetgearSignalStrengthTranslate( priv->LastSignalStrengthInPercent, priv->SignalStrength); priv->LastSignalStrengthInPercent = SignalStrengthIndex; priv->Stats_SignalStrength = TranslateToDbm8185((u8)SignalStrengthIndex); - // - // We need more correct power of received packets and the "SignalStrength" of RxStats is beautified, - // so we record the correct power here. - // + /* + * We need more correct power of received packets and the "SignalStrength" of RxStats is beautified, + * so we record the correct power here. + */ priv->Stats_SignalQuality = (long)(priv->Stats_SignalQuality * 5 + (long)priv->SignalQuality + 5) / 6; priv->Stats_RecvSignalPower = (long)(priv->Stats_RecvSignalPower * 5 + priv->RecvSignalPower - 1) / 6; - // Figure out which antenna that received the lasted packet. - priv->LastRxPktAntenna = Antenna ? 1 : 0; // 0: aux, 1: main. + /* Figure out which antenna that received the lasted packet. */ + priv->LastRxPktAntenna = Antenna ? 1 : 0; /* 0: aux, 1: main. */ SwAntennaDiversityRxOk8185(dev, priv->SignalStrength); } @@ -1717,7 +1715,7 @@ void rtl8180_rx(struct net_device *dev) sizeof(u8), PCI_DMA_FROMDEVICE); -drop: // this is used when we have not enough mem +drop: /* this is used when we have not enough mem */ /* restore the descriptor */ *(priv->rxringtail+2) = priv->rxbuffer->dma; *(priv->rxringtail) = *(priv->rxringtail) & ~0xfff; @@ -1769,7 +1767,8 @@ void rtl8180_data_hard_resume(struct net_device *dev) rtl8180_set_mode(dev, EPROM_CMD_NORMAL); } -/* this function TX data frames when the ieee80211 stack requires this. +/* + * This function TX data frames when the ieee80211 stack requires this. * It checks also if we need to stop the ieee tx queue, eventually do it */ void rtl8180_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int @@ -1785,12 +1784,12 @@ rate) { rate = ieeerate2rtlrate(rate); /* - * This function doesn't require lock because we make - * sure it's called with the tx_lock already acquired. - * this come from the kernel's hard_xmit callback (through - * the ieee stack, or from the try_wake_queue (again through - * the ieee stack. - */ + * This function doesn't require lock because we make + * sure it's called with the tx_lock already acquired. + * this come from the kernel's hard_xmit callback (through + * the ieee stack, or from the try_wake_queue (again through + * the ieee stack. + */ priority = AC2Q(skb->priority); spin_lock_irqsave(&priv->tx_lock, flags); @@ -1812,7 +1811,8 @@ rate) { spin_unlock_irqrestore(&priv->tx_lock, flags); } -/* This is a rough attempt to TX a frame +/* + * This is a rough attempt to TX a frame * This is called by the ieee 80211 stack to TX management frames. * If the ring is full packet are dropped (for data frame the queue * is stopped before this can happen). For this reason it is better @@ -1822,7 +1822,7 @@ rate) { * Since queues for Management and Data frames are different we * might use a different lock than tx_lock (for example mgmt_tx_lock) */ -/* these function may loops if invoked with 0 descriptors or 0 len buffer*/ +/* these function may loops if invoked with 0 descriptors or 0 len buffer */ int rtl8180_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); @@ -1850,7 +1850,7 @@ int rtl8180_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } -// longpre 144+48 shortpre 72+24 +/* longpre 144+48 shortpre 72+24 */ u16 rtl8180_len2duration(u32 len, short rate, short *ext) { u16 duration; @@ -1858,7 +1858,7 @@ u16 rtl8180_len2duration(u32 len, short rate, short *ext) *ext = 0; switch (rate) { - case 0://1mbps + case 0: /* 1mbps */ *ext = 0; duration = ((len+4)<<4) / 0x2; drift = ((len+4)<<4) % 0x2; @@ -1866,7 +1866,7 @@ u16 rtl8180_len2duration(u32 len, short rate, short *ext) break; duration++; break; - case 1://2mbps + case 1: /* 2mbps */ *ext = 0; duration = ((len+4)<<4) / 0x4; drift = ((len+4)<<4) % 0x4; @@ -1874,7 +1874,7 @@ u16 rtl8180_len2duration(u32 len, short rate, short *ext) break; duration++; break; - case 2: //5.5mbps + case 2: /* 5.5mbps */ *ext = 0; duration = ((len+4)<<4) / 0xb; drift = ((len+4)<<4) % 0xb; @@ -1883,7 +1883,7 @@ u16 rtl8180_len2duration(u32 len, short rate, short *ext) duration++; break; default: - case 3://11mbps + case 3: /* 11mbps */ *ext = 0; duration = ((len+4)<<4) / 0x16; drift = ((len+4)<<4) % 0x16; @@ -1905,8 +1905,8 @@ void rtl8180_prepare_beacon(struct net_device *dev) struct sk_buff *skb; u16 word = read_nic_word(dev, BcnItv); - word &= ~BcnItv_BcnItv; // clear Bcn_Itv - word |= cpu_to_le16(priv->ieee80211->current_network.beacon_interval); //0x64; + word &= ~BcnItv_BcnItv; /* clear Bcn_Itv */ + word |= cpu_to_le16(priv->ieee80211->current_network.beacon_interval); /* 0x64; */ write_nic_word(dev, BcnItv, word); skb = ieee80211_get_beacon(priv->ieee80211); @@ -1917,7 +1917,8 @@ void rtl8180_prepare_beacon(struct net_device *dev) } } -/* This function do the real dirty work: it enqueues a TX command +/* + * This function do the real dirty work: it enqueues a TX command * descriptor in the ring buffer, copyes the frame in a TX buffer * and kicks the NIC to ensure it does the DMA transfer. */ @@ -2004,38 +2005,38 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, ThisFrameTime = ComputeTxTime(len + sCrcLng, rtl8180_rate2rate(rate), 0, bUseShortPreamble); TxDescDuration = ThisFrameTime; - } else {// Unicast packet + } else { /* Unicast packet */ u16 AckTime; - //YJ,add,080828,for Keep alive + /* YJ,add,080828,for Keep alive */ priv->NumTxUnicast++; /* Figure out ACK rate according to BSS basic rate * and Tx rate. */ - AckTime = ComputeTxTime(14, 10, 0, 0); // AckCTSLng = 14 use 1M bps send + AckTime = ComputeTxTime(14, 10, 0, 0); /* AckCTSLng = 14 use 1M bps send */ - if (((len + sCrcLng) > priv->rts) && priv->rts) { // RTS/CTS. + if (((len + sCrcLng) > priv->rts) && priv->rts) { /* RTS/CTS. */ u16 RtsTime, CtsTime; - //u16 CtsRate; + /* u16 CtsRate; */ bRTSEnable = 1; bCTSEnable = 0; - // Rate and time required for RTS. + /* Rate and time required for RTS. */ RtsTime = ComputeTxTime(sAckCtsLng/8, priv->ieee80211->basic_rate, 0, 0); - // Rate and time required for CTS. - CtsTime = ComputeTxTime(14, 10, 0, 0); // AckCTSLng = 14 use 1M bps send + /* Rate and time required for CTS. */ + CtsTime = ComputeTxTime(14, 10, 0, 0); /* AckCTSLng = 14 use 1M bps send */ - // Figure out time required to transmit this frame. + /* Figure out time required to transmit this frame. */ ThisFrameTime = ComputeTxTime(len + sCrcLng, rtl8180_rate2rate(rate), 0, bUseShortPreamble); - // RTS-CTS-ThisFrame-ACK. + /* RTS-CTS-ThisFrame-ACK. */ RtsDur = CtsTime + ThisFrameTime + AckTime + 3*aSifsTime; TxDescDuration = RtsTime + RtsDur; - } else {// Normal case. + } else { /* Normal case. */ bCTSEnable = 0; bRTSEnable = 0; RtsDur = 0; @@ -2045,20 +2046,20 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, } if (!(frag_hdr->frame_control & IEEE80211_FCTL_MOREFRAGS)) { - // ThisFrame-ACK. + /* ThisFrame-ACK. */ Duration = aSifsTime + AckTime; - } else { // One or more fragments remained. + } else { /* One or more fragments remained. */ u16 NextFragTime; - NextFragTime = ComputeTxTime(len + sCrcLng, //pretend following packet length equal current packet + NextFragTime = ComputeTxTime(len + sCrcLng, /* pretend following packet length equal current packet */ rtl8180_rate2rate(rate), 0, bUseShortPreamble); - //ThisFrag-ACk-NextFrag-ACK. + /* ThisFrag-ACk-NextFrag-ACK. */ Duration = NextFragTime + 3*aSifsTime + 2*AckTime; } - } // End of Unicast packet + } /* End of Unicast packet */ frag_hdr->duration_id = Duration; @@ -2081,26 +2082,26 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, return remain; } - *tail = 0; // zeroes header + *tail = 0; /* zeroes header */ *(tail+1) = 0; *(tail+3) = 0; *(tail+5) = 0; *(tail+6) = 0; *(tail+7) = 0; - /*FIXME: this should be triggered by HW encryption parameters.*/ + /* FIXME: this should be triggered by HW encryption parameters.*/ *tail |= (1<<15); /* no encrypt */ if (remain == len && !descfrag) { ownbit_flag = false; - *tail = *tail | (1<<29) ; //fist segment of the packet + *tail = *tail | (1<<29) ; /* fist segment of the packet */ *tail = *tail | (len); } else { ownbit_flag = true; } for (i = 0; i < buflen && remain > 0; i++, remain--) { - ((u8 *)buf)[i] = txbuf[i]; //copy data into descriptor pointed DMAble buffer + ((u8 *)buf)[i] = txbuf[i]; /* copy data into descriptor pointed DMAble buffer */ if (remain == 4 && i+4 >= buflen) break; /* ensure the last desc has at least 4 bytes payload */ @@ -2108,23 +2109,23 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, } txbuf = txbuf + i; *(tail+3) = *(tail+3) & ~0xfff; - *(tail+3) = *(tail+3) | i; // buffer lenght - // Use short preamble or not + *(tail+3) = *(tail+3) | i; /* buffer length */ + /* Use short preamble or not */ if (priv->ieee80211->current_network.capability&WLAN_CAPABILITY_SHORT_PREAMBLE) - if (priv->plcp_preamble_mode == 1 && rate != 0) // short mode now, not long! - ;// *tail |= (1<<16); // enable short preamble mode. + if (priv->plcp_preamble_mode == 1 && rate != 0) /* short mode now, not long! */ + ; /* *tail |= (1<<16); */ /* enable short preamble mode. */ if (bCTSEnable) *tail |= (1<<18); - if (bRTSEnable) { //rts enable - *tail |= ((ieeerate2rtlrate(priv->ieee80211->basic_rate))<<19);//RTS RATE - *tail |= (1<<23);//rts enable - *(tail+1) |= (RtsDur&0xffff);//RTS Duration + if (bRTSEnable) { /* rts enable */ + *tail |= ((ieeerate2rtlrate(priv->ieee80211->basic_rate))<<19); /* RTS RATE */ + *tail |= (1<<23); /* rts enable */ + *(tail+1) |= (RtsDur&0xffff); /* RTS Duration */ } - *(tail+3) |= ((TxDescDuration&0xffff)<<16); //DURATION -// *(tail+3) |= (0xe6<<16); - *(tail+5) |= (11<<8);//(priv->retry_data<<8); //retry lim ; + *(tail+3) |= ((TxDescDuration&0xffff)<<16); /* DURATION */ + /* *(tail+3) |= (0xe6<<16); */ + *(tail+5) |= (11<<8); /* (priv->retry_data<<8); */ /* retry lim; */ *tail = *tail | ((rate&0xf) << 24); @@ -2134,20 +2135,20 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, duration = rtl8180_len2duration(len, rate, &ext); *(tail+1) = *(tail+1) | ((duration & 0x7fff)<<16); if (ext) - *(tail+1) = *(tail+1) | (1<<31); //plcp length extension + *(tail+1) = *(tail+1) | (1<<31); /* plcp length extension */ } if (morefrag) - *tail = (*tail) | (1<<17); // more fragment + *tail = (*tail) | (1<<17); /* more fragment */ if (!remain) - *tail = (*tail) | (1<<28); // last segment of frame + *tail = (*tail) | (1<<28); /* last segment of frame */ *(tail+5) = *(tail+5)|(2<<27); *(tail+7) = *(tail+7)|(1<<4); wmb(); if (ownbit_flag) - *tail = *tail | (1<<31); // descriptor ready to be txed + *tail = *tail | (1<<31); /* descriptor ready to be txed */ if ((tail - begin)/8 == count-1) tail = begin; @@ -2184,7 +2185,8 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, priv->txhpbufstail = buflist; break; case BEACON_PRIORITY: - /* the HW seems to be happy with the 1st + /* + * The HW seems to be happy with the 1st * descriptor filled and the 2nd empty... * So always update descriptor 1 and never * touch 2nd @@ -2192,7 +2194,7 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, break; } } - *temp_tail = *temp_tail | (1<<31); // descriptor ready to be txed + *temp_tail = *temp_tail | (1<<31); /* descriptor ready to be txed */ rtl8180_dma_kick(dev, priority); return 0; @@ -2303,12 +2305,14 @@ void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl) spin_lock_irqsave(&priv->ps_lock, flags); - /* Writing HW register with 0 equals to disable + /* + * Writing HW register with 0 equals to disable * the timer, that is not really what we want */ tl -= MSECS(4+16+7); - /* If the interval in witch we are requested to sleep is too + /* + * If the interval in witch we are requested to sleep is too * short then give up and remain awake */ if (((tl >= rb) && (tl-rb) <= MSECS(MIN_SLEEP_TIME)) @@ -2323,9 +2327,10 @@ void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl) priv->DozePeriodInPast2Sec += jiffies_to_msecs(tmp); - queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb + queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); /* as tl may be less than rb */ } - /* if we suspect the TimerInt is gone beyond tl + /* + * If we suspect the TimerInt is gone beyond tl * while setting it, then give up */ @@ -2351,12 +2356,12 @@ void rtl8180_wmm_param_update(struct work_struct *work) u8 i; if (!ieee->current_network.QoS_Enable) { - //legacy ac_xx_param update + /* legacy ac_xx_param update */ AcParam.longData = 0; - AcParam.f.AciAifsn.f.AIFSN = 2; // Follow 802.11 DIFS. + AcParam.f.AciAifsn.f.AIFSN = 2; /* Follow 802.11 DIFS. */ AcParam.f.AciAifsn.f.ACM = 0; - AcParam.f.Ecw.f.ECWmin = 3; // Follow 802.11 CWmin. - AcParam.f.Ecw.f.ECWmax = 7; // Follow 802.11 CWmax. + AcParam.f.Ecw.f.ECWmin = 3; /* Follow 802.11 CWmin. */ + AcParam.f.Ecw.f.ECWmax = 7; /* Follow 802.11 CWmax. */ AcParam.f.TXOPLimit = 0; for (eACI = 0; eACI < AC_MAX; eACI++) { AcParam.f.AciAifsn.f.ACI = (u8)eACI; @@ -2364,7 +2369,7 @@ void rtl8180_wmm_param_update(struct work_struct *work) u8 u1bAIFS; u32 u4bAcParam; pAcParam = (PAC_PARAM)(&AcParam); - // Retrive paramters to udpate. + /* Retrive paramters to udpate. */ u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * (((mode&IEEE_G) == IEEE_G) ? 9 : 20) + aSifsTime; u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit))<f.Ecw.f.ECWmax))<f.AciAifsn.f.ACI; - //Mode G/A: slotTimeTimer = 9; Mode B: 20 + /* Mode G/A: slotTimeTimer = 9; Mode B: 20 */ u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * (((mode&IEEE_G) == IEEE_G) ? 9 : 20) + aSifsTime; u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) | (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) | @@ -2433,7 +2438,7 @@ void rtl8180_wmm_param_update(struct work_struct *work) void rtl8180_tx_irq_wq(struct work_struct *work); void rtl8180_restart_wq(struct work_struct *work); -//void rtl8180_rq_tx_ack(struct work_struct *work); +/* void rtl8180_rq_tx_ack(struct work_struct *work); */ void rtl8180_watch_dog_wq(struct work_struct *work); void rtl8180_hw_wakeup_wq(struct work_struct *work); void rtl8180_hw_sleep_wq(struct work_struct *work); @@ -2449,15 +2454,15 @@ void watch_dog_adaptive(unsigned long data) return; } - // Tx High Power Mechanism. + /* Tx High Power Mechanism. */ if (CheckHighPower((struct net_device *)data)) queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->tx_pw_wq); - // Tx Power Tracking on 87SE. + /* Tx Power Tracking on 87SE. */ if (CheckTxPwrTracking((struct net_device *)data)) TxPwrTracking87SE((struct net_device *)data); - // Perform DIG immediately. + /* Perform DIG immediately. */ if (CheckDig((struct net_device *)data) == true) queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_dig_wq); rtl8180_watch_dog((struct net_device *)data); @@ -2469,24 +2474,24 @@ void watch_dog_adaptive(unsigned long data) } static CHANNEL_LIST ChannelPlan[] = { - {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19}, //FCC - {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC - {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI - {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Spain. Change to ETSI. - {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //France. Change to ETSI. - {{14,36,40,44,48,52,56,60,64},9}, //MKK - {{1,2,3,4,5,6,7,8,9,10,11,12,13,14, 36,40,44,48,52,56,60,64},22},//MKK1 - {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Israel. - {{1,2,3,4,5,6,7,8,9,10,11,12,13,34,38,42,46},17}, // For 11a , TELEC - {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626 - {{1,2,3,4,5,6,7,8,9,10,11,12,13},13} //world wide 13: ch1~ch11 active scan, ch12~13 passive //lzm add 080826 + {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19}, /* FCC */ + {{1,2,3,4,5,6,7,8,9,10,11},11}, /* IC */ + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, /* ETSI */ + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, /* Spain. Change to ETSI. */ + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, /* France. Change to ETSI. */ + {{14,36,40,44,48,52,56,60,64},9}, /* MKK */ + {{1,2,3,4,5,6,7,8,9,10,11,12,13,14, 36,40,44,48,52,56,60,64},22},/* MKK1 */ + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, /* Israel. */ + {{1,2,3,4,5,6,7,8,9,10,11,12,13,34,38,42,46},17}, /* For 11a , TELEC */ + {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, /* For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626 */ + {{1,2,3,4,5,6,7,8,9,10,11,12,13},13} /* world wide 13: ch1~ch11 active scan, ch12~13 passive //lzm add 080826 */ }; static void rtl8180_set_channel_map(u8 channel_plan, struct ieee80211_device *ieee) { int i; - //lzm add 080826 + /* lzm add 080826 */ ieee->MinPassiveChnlNum = MAX_CHANNEL_NUMBER+1; ieee->IbssStartChnl = 0; @@ -2504,9 +2509,9 @@ static void rtl8180_set_channel_map(u8 channel_plan, struct ieee80211_device *ie Dot11d_Init(ieee); ieee->bGlobalDomain = false; if (ChannelPlan[channel_plan].Len != 0) { - // Clear old channel map + /* Clear old channel map */ memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map)); - // Set new channel map + /* Set new channel map */ for (i = 0; i < ChannelPlan[channel_plan].Len; i++) { if (ChannelPlan[channel_plan].Channel[i] <= 14) GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1; @@ -2521,7 +2526,7 @@ static void rtl8180_set_channel_map(u8 channel_plan, struct ieee80211_device *ie ieee->bGlobalDomain = true; break; } - case COUNTRY_CODE_WORLD_WIDE_13_INDEX://lzm add 080826 + case COUNTRY_CODE_WORLD_WIDE_13_INDEX:/* lzm add 080826 */ { ieee->MinPassiveChnlNum = 12; ieee->IbssStartChnl = 10; @@ -2541,7 +2546,7 @@ static void rtl8180_set_channel_map(u8 channel_plan, struct ieee80211_device *ie void GPIOChangeRFWorkItemCallBack(struct work_struct *work); -//YJ,add,080828 +/* YJ,add,080828 */ static void rtl8180_statistics_init(struct Stats *pstats) { memset(pstats, 0, sizeof(struct Stats)); @@ -2552,8 +2557,8 @@ static void rtl8180_link_detect_init(plink_detect_t plink_detect) memset(plink_detect, 0, sizeof(link_detect_t)); plink_detect->SlotNum = DEFAULT_SLOT_NUM; } -//YJ,add,080828,end +/* YJ,add,080828,end */ static void rtl8187se_eeprom_register_read(struct eeprom_93cx6 *eeprom) { struct net_device *dev = eeprom->data; @@ -2610,11 +2615,11 @@ short rtl8180_init(struct net_device *dev) DMESG("Channel plan is %d\n", priv->channel_plan); rtl8180_set_channel_map(priv->channel_plan, priv->ieee80211); - //FIXME: these constants are placed in a bad pleace. - priv->txbuffsize = 2048;//1024; - priv->txringcount = 32;//32; - priv->rxbuffersize = 2048;//1024; - priv->rxringcount = 64;//32; + /* FIXME: these constants are placed in a bad pleace. */ + priv->txbuffsize = 2048; /* 1024; */ + priv->txringcount = 32; /* 32; */ + priv->rxbuffersize = 2048; /* 1024; */ + priv->rxringcount = 64; /* 32; */ priv->txbeaconcount = 2; priv->rx_skb_complete = 1; @@ -2635,7 +2640,7 @@ short rtl8180_init(struct net_device *dev) IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ | IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE; priv->ieee80211->active_scan = 1; - priv->ieee80211->rate = 110; //11 mbps + priv->ieee80211->rate = 110; /* 11 mbps */ priv->ieee80211->modulation = IEEE80211_CCK_MODULATION; priv->ieee80211->host_encrypt = 1; priv->ieee80211->host_decrypt = 1; @@ -2653,19 +2658,19 @@ short rtl8180_init(struct net_device *dev) priv->SetRFPowerStateInProgress = false; priv->RFProgType = 0; priv->bInHctTest = false; - priv->bInactivePs = true;//false; + priv->bInactivePs = true; /* false; */ priv->ieee80211->bInactivePs = priv->bInactivePs; priv->bSwRfProcessing = false; priv->eRFPowerState = eRfOff; priv->RfOffReason = 0; priv->LedStrategy = SW_LED_MODE0; - priv->TxPollingTimes = 0;//lzm add 080826 + priv->TxPollingTimes = 0; /* lzm add 080826 */ priv->bLeisurePs = true; priv->dot11PowerSaveMode = eActive; priv->AdMinCheckPeriod = 5; priv->AdMaxCheckPeriod = 10; - priv->AdMaxRxSsThreshold = 30;//60->30 - priv->AdRxSsThreshold = 20;//50->20 + priv->AdMaxRxSsThreshold = 30; /* 60->30 */ + priv->AdRxSsThreshold = 20; /* 50->20 */ priv->AdCheckPeriod = priv->AdMinCheckPeriod; priv->AdTickCount = 0; priv->AdRxSignalStrength = -1; @@ -2686,15 +2691,15 @@ short rtl8180_init(struct net_device *dev) priv->bTxPowerTrack = false; priv->ThermalMeter = 0; priv->FalseAlarmRegValue = 0; - priv->RegDigOfdmFaUpTh = 0xc; // Upper threhold of OFDM false alarm, which is used in DIG. + priv->RegDigOfdmFaUpTh = 0xc; /* Upper threhold of OFDM false alarm, which is used in DIG. */ priv->DIG_NumberFallbackVote = 0; priv->DIG_NumberUpgradeVote = 0; priv->LastSignalStrengthInPercent = 0; priv->Stats_SignalStrength = 0; priv->LastRxPktAntenna = 0; - priv->SignalQuality = 0; // in 0-100 index. + priv->SignalQuality = 0; /* in 0-100 index. */ priv->Stats_SignalQuality = 0; - priv->RecvSignalPower = 0; // in dBm. + priv->RecvSignalPower = 0; /* in dBm. */ priv->Stats_RecvSignalPower = 0; priv->AdMainAntennaRxOkCnt = 0; priv->AdAuxAntennaRxOkCnt = 0; @@ -2824,27 +2829,27 @@ short rtl8180_init(struct net_device *dev) priv->ieee80211->modulation |= IEEE80211_OFDM_MODULATION; priv->ieee80211->short_slot = 1; - // just for sync 85 + /* just for sync 85 */ priv->enable_gpio0 = 0; eeprom_93cx6_read(&eeprom, EEPROM_SW_REVD_OFFSET, &eeprom_val); usValue = eeprom_val; DMESG("usValue is 0x%x\n", usValue); - //3Read AntennaDiversity + /* 3Read AntennaDiversity */ - // SW Antenna Diversity. + /* SW Antenna Diversity. */ if ((usValue & EEPROM_SW_AD_MASK) != EEPROM_SW_AD_ENABLE) priv->EEPROMSwAntennaDiversity = false; else priv->EEPROMSwAntennaDiversity = true; - // Default Antenna to use. + /* Default Antenna to use. */ if ((usValue & EEPROM_DEF_ANT_MASK) != EEPROM_DEF_ANT_1) priv->EEPROMDefaultAntenna1 = false; else priv->EEPROMDefaultAntenna1 = true; - if (priv->RegSwAntennaDiversityMechanism == 0) // Auto + if (priv->RegSwAntennaDiversityMechanism == 0) /* Auto */ /* 0: default from EEPROM. */ priv->bSwAntennaDiverity = priv->EEPROMSwAntennaDiversity; else @@ -2858,11 +2863,11 @@ short rtl8180_init(struct net_device *dev) /* 1: main, 2: aux. */ priv->bDefaultAntenna1 = ((priv->RegDefaultAntenna == 2) ? true : false); - /* rtl8185 can calc plcp len in HW.*/ + /* rtl8185 can calc plcp len in HW. */ priv->hw_plcp_len = 1; priv->plcp_preamble_mode = 2; - /*the eeprom type is stored in RCR register bit #6 */ + /* the eeprom type is stored in RCR register bit #6 */ if (RCR_9356SEL & read_nic_dword(dev, RCR)) priv->epromtype = EPROM_93c56; else @@ -2997,9 +3002,9 @@ void rtl8180_set_hw_wep(struct net_device *dev) void rtl8185_rf_pins_enable(struct net_device *dev) { -// u16 tmp; -// tmp = read_nic_word(dev, RFPinsEnable); - write_nic_word(dev, RFPinsEnable, 0x1fff);// | tmp); + /* u16 tmp; */ + /* tmp = read_nic_word(dev, RFPinsEnable); */ + write_nic_word(dev, RFPinsEnable, 0x1fff); /* | tmp); */ } void rtl8185_set_anaparam2(struct net_device *dev, u32 a) @@ -3047,7 +3052,7 @@ void rtl8185_write_phy(struct net_device *dev, u8 adr, u32 data) phyw = ((data<<8) | adr); - // Note that, we must write 0xff7c after 0x7d-0x7f to write BB register. + /* Note that, we must write 0xff7c after 0x7d-0x7f to write BB register. */ write_nic_byte(dev, 0x7f, ((phyw & 0xff000000) >> 24)); write_nic_byte(dev, 0x7e, ((phyw & 0x00ff0000) >> 16)); write_nic_byte(dev, 0x7d, ((phyw & 0x0000ff00) >> 8)); @@ -3056,7 +3061,7 @@ void rtl8185_write_phy(struct net_device *dev, u8 adr, u32 data) /* this is ok to fail when we write AGC table. check for AGC table might be * done by masking with 0x7f instead of 0xff */ - //if(phyr != (data&0xff)) DMESGW("Phy write timeout %x %x %x", phyr, data,adr); + /* if (phyr != (data&0xff)) DMESGW("Phy write timeout %x %x %x", phyr, data, adr); */ } inline void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data) @@ -3102,7 +3107,8 @@ void rtl8180_adapter_start(struct net_device *dev) /* enable beacon timeout, beacon TX ok and err * LP tx ok and err, HP TX ok and err, NP TX ok and err, - * RX ok and ERR, and GP timer */ + * RX ok and ERR, and GP timer + */ priv->irq_mask = 0x6fcf; priv->dma_poll_mask = 0; @@ -3123,15 +3129,15 @@ void rtl8180_adapter_start(struct net_device *dev) rtl8180_set_mode(dev, EPROM_CMD_CONFIG); /* - The following is very strange. seems to be that 1 means test mode, - but we need to acknolwledges the nic when a packet is ready - although we set it to 0 - */ + * The following is very strange. seems to be that 1 means test mode, + * but we need to acknolwledges the nic when a packet is ready + * although we set it to 0 + */ write_nic_byte(dev, CONFIG2, read_nic_byte(dev, CONFIG2) & ~\ (1<ieee80211->current_network.beacon_interval * + word |= 1000; /* priv->ieee80211->current_network.beacon_interval * ((priv->txbeaconcount > 1)?(priv->txbeaconcount-1):1); // FIXME: check if correct ^^ worked with 0x3e8; */ @@ -3198,16 +3205,17 @@ static struct net_device_stats *rtl8180_stats(struct net_device *dev) return &priv->ieee80211->stats; } -// -// Change current and default preamble mode. -// + +/* + * Change current and default preamble mode. + */ bool MgntActSet_802_11_PowerSaveMode( struct r8180_priv *priv, RT_PS_MODE rtPsMode ) { - // Currently, we do not change power save mode on IBSS mode. + /* Currently, we do not change power save mode on IBSS mode. */ if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) return false; @@ -3220,7 +3228,7 @@ void LeisurePSEnter(struct r8180_priv *priv) { if (priv->bLeisurePs) { if (priv->ieee80211->ps == IEEE80211_PS_DISABLED) - MgntActSet_802_11_PowerSaveMode(priv, IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST);//IEEE80211_PS_ENABLE + MgntActSet_802_11_PowerSaveMode(priv, IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST); /* IEEE80211_PS_ENABLE */ } } @@ -3256,9 +3264,9 @@ static void MgntLinkKeepAlive(struct r8180_priv *priv) return; if (priv->ieee80211->state == IEEE80211_LINKED) { - // - // Keep-Alive. - // + /* + * Keep-Alive. + */ if ((priv->keepAliveLevel == 2) || (priv->link_detect.LastNumTxUnicast == priv->NumTxUnicast && @@ -3266,9 +3274,9 @@ static void MgntLinkKeepAlive(struct r8180_priv *priv) ) { priv->link_detect.IdleCount++; - // - // Send a Keep-Alive packet packet to AP if we had been idle for a while. - // + /* + * Send a Keep-Alive packet packet to AP if we had been idle for a while. + */ if (priv->link_detect.IdleCount >= ((KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD)-1)) { priv->link_detect.IdleCount = 0; ieee80211_sta_ps_send_null_frame(priv->ieee80211, false); @@ -3295,7 +3303,7 @@ void rtl8180_watch_dog(struct net_device *dev) if ((priv->ieee80211->iw_mode != IW_MODE_ADHOC) && (priv->ieee80211->state == IEEE80211_NOLINK) && (priv->ieee80211->beinretry == false) && (priv->eRFPowerState == eRfOn)) IPSEnter(dev); } - //YJ,add,080828,for link state check + /* YJ,add,080828,for link state check */ if ((priv->ieee80211->state == IEEE80211_LINKED) && (priv->ieee80211->iw_mode == IW_MODE_INFRA)) { SlotIndex = (priv->link_detect.SlotIndex++) % priv->link_detect.SlotNum; priv->link_detect.RxFrameNum[SlotIndex] = priv->ieee80211->NumRxDataInPeriod + priv->ieee80211->NumRxBcnInPeriod; @@ -3308,10 +3316,10 @@ void rtl8180_watch_dog(struct net_device *dev) } } - //YJ,add,080828,for KeepAlive + /* YJ,add,080828,for KeepAlive */ MgntLinkKeepAlive(priv); - //YJ,add,080828,for LPS + /* YJ,add,080828,for LPS */ if (priv->PowerProfile == POWER_PROFILE_BATTERY) priv->bLeisurePs = true; else if (priv->PowerProfile == POWER_PROFILE_AC) { @@ -3586,8 +3594,8 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev, goto fail1; } - dev->mem_start = ioaddr; // shared mem start - dev->mem_end = ioaddr + pci_resource_len(pdev, 0); // shared mem end + dev->mem_start = ioaddr; /* shared mem start */ + dev->mem_end = ioaddr + pci_resource_len(pdev, 0); /* shared mem end */ pci_read_config_byte(pdev, 0x05, &unit); pci_write_config_byte(pdev, 0x05, unit & (~0x04)); @@ -3756,19 +3764,19 @@ void rtl8180_try_wake_queue(struct net_device *dev, int pri) void rtl8180_tx_isr(struct net_device *dev, int pri, short error) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - u32 *tail; //tail virtual addr - u32 *head; //head virtual addr - u32 *begin;//start of ring virtual addr - u32 *nicv; //nic pointer virtual addr - u32 nic; //nic pointer physical addr - u32 nicbegin;// start of ring physical addr + u32 *tail; /* tail virtual addr */ + u32 *head; /* head virtual addr */ + u32 *begin; /* start of ring virtual addr */ + u32 *nicv; /* nic pointer virtual addr */ + u32 nic; /* nic pointer physical addr */ + u32 nicbegin; /* start of ring physical addr */ unsigned long flag; - /* physical addr are ok on 32 bits since we set DMA mask*/ + /* physical addr are ok on 32 bits since we set DMA mask */ int offs; int j, i; int hd; if (error) - priv->stats.txretry++; //tony 20060601 + priv->stats.txretry++; /* tony 20060601 */ spin_lock_irqsave(&priv->tx_lock, flag); switch (pri) { case MANAGE_PRIORITY: @@ -3828,10 +3836,11 @@ void rtl8180_tx_isr(struct net_device *dev, int pri, short error) return; } - /* we check all the descriptors between the head and the nic, + /* + * We check all the descriptors between the head and the nic, * but not the currently pointed by the nic (the next to be txed) * and the previous of the pointed (might be in process ??) - */ + */ offs = (nic - nicbegin); offs = offs / 8 / 4; hd = (head - begin) / 8; @@ -3865,7 +3874,8 @@ void rtl8180_tx_isr(struct net_device *dev, int pri, short error) head += 8; } - /* the head has been moved to the last certainly TXed + /* + * The head has been moved to the last certainly TXed * (or at least processed by the nic) packet. * The driver take forcefully owning of all these packets * If the packet previous of the nic pointer has been @@ -3927,9 +3937,9 @@ irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs) spin_lock_irqsave(&priv->irq_th_lock, flags); - //ISR: 4bytes - inta = read_nic_dword(dev, ISR);// & priv->IntrMask; - write_nic_dword(dev, ISR, inta); // reset int situation + /* ISR: 4bytes */ + inta = read_nic_dword(dev, ISR); /* & priv->IntrMask; */ + write_nic_dword(dev, ISR, inta); /* reset int situation */ priv->stats.shints++; @@ -3937,9 +3947,9 @@ irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs) spin_unlock_irqrestore(&priv->irq_th_lock, flags); return IRQ_HANDLED; /* - most probably we can safely return IRQ_NONE, - but for now is better to avoid problems - */ + * most probably we can safely return IRQ_NONE, + * but for now is better to avoid problems + */ } if (inta == 0xffff) { @@ -3973,8 +3983,8 @@ irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs) priv->ieee80211->stats.tx_errors++; } - if (inta & ISR_THPDOK) { //High priority tx ok - priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828 + if (inta & ISR_THPDOK) { /* High priority tx ok */ + priv->link_detect.NumTxOkInPeriod++; /* YJ,add,080828 */ priv->stats.txhpokint++; rtl8180_tx_isr(dev, HI_PRIORITY, 0); } @@ -3982,27 +3992,27 @@ irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs) if (inta & ISR_RER) priv->stats.rxerr++; - if (inta & ISR_TBKDER) { //corresponding to BK_PRIORITY + if (inta & ISR_TBKDER) { /* corresponding to BK_PRIORITY */ priv->stats.txbkperr++; priv->ieee80211->stats.tx_errors++; rtl8180_tx_isr(dev, BK_PRIORITY, 1); rtl8180_try_wake_queue(dev, BE_PRIORITY); } - if (inta & ISR_TBEDER) { //corresponding to BE_PRIORITY + if (inta & ISR_TBEDER) { /* corresponding to BE_PRIORITY */ priv->stats.txbeperr++; priv->ieee80211->stats.tx_errors++; rtl8180_tx_isr(dev, BE_PRIORITY, 1); rtl8180_try_wake_queue(dev, BE_PRIORITY); } - if (inta & ISR_TNPDER) { //corresponding to VO_PRIORITY + if (inta & ISR_TNPDER) { /* corresponding to VO_PRIORITY */ priv->stats.txnperr++; priv->ieee80211->stats.tx_errors++; rtl8180_tx_isr(dev, NORM_PRIORITY, 1); rtl8180_try_wake_queue(dev, NORM_PRIORITY); } - if (inta & ISR_TLPDER) { //corresponding to VI_PRIORITY + if (inta & ISR_TLPDER) { /* corresponding to VI_PRIORITY */ priv->stats.txlperr++; priv->ieee80211->stats.tx_errors++; rtl8180_tx_isr(dev, LOW_PRIORITY, 1); @@ -4036,29 +4046,29 @@ irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs) if (inta & ISR_TXFOVW) priv->stats.txoverflow++; - if (inta & ISR_TNPDOK) { //Normal priority tx ok - priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828 + if (inta & ISR_TNPDOK) { /* Normal priority tx ok */ + priv->link_detect.NumTxOkInPeriod++; /* YJ,add,080828 */ priv->stats.txnpokint++; rtl8180_tx_isr(dev, NORM_PRIORITY, 0); } - if (inta & ISR_TLPDOK) { //Low priority tx ok - priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828 + if (inta & ISR_TLPDOK) { /* Low priority tx ok */ + priv->link_detect.NumTxOkInPeriod++; /* YJ,add,080828 */ priv->stats.txlpokint++; rtl8180_tx_isr(dev, LOW_PRIORITY, 0); rtl8180_try_wake_queue(dev, LOW_PRIORITY); } - if (inta & ISR_TBKDOK) { //corresponding to BK_PRIORITY + if (inta & ISR_TBKDOK) { /* corresponding to BK_PRIORITY */ priv->stats.txbkpokint++; - priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828 + priv->link_detect.NumTxOkInPeriod++; /* YJ,add,080828 */ rtl8180_tx_isr(dev, BK_PRIORITY, 0); rtl8180_try_wake_queue(dev, BE_PRIORITY); } - if (inta & ISR_TBEDOK) { //corresponding to BE_PRIORITY + if (inta & ISR_TBEDOK) { /* corresponding to BE_PRIORITY */ priv->stats.txbeperr++; - priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828 + priv->link_detect.NumTxOkInPeriod++; /* YJ,add,080828 */ rtl8180_tx_isr(dev, BE_PRIORITY, 0); rtl8180_try_wake_queue(dev, BE_PRIORITY); } -- cgit v1.2.3 From fdd2d9341d50f3a67fc35394e41146f30a383a6b Mon Sep 17 00:00:00 2001 From: Marin Mitov Date: Fri, 14 May 2010 11:15:38 +0300 Subject: Staging: dt3155v4l: introduce state machine This patch introduces a v4l2 state machine, so now CONFIG_DT3155_STREAMING is no more needed. Signed-off-by: Marin Mitov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dt3155v4l/Kconfig | 8 ---- drivers/staging/dt3155v4l/dt3155v4l.c | 80 +++++++++++++++++++++++++++++------ drivers/staging/dt3155v4l/dt3155v4l.h | 4 +- 3 files changed, 69 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/dt3155v4l/Kconfig b/drivers/staging/dt3155v4l/Kconfig index 5cef5420d288..f49f4ac035b0 100644 --- a/drivers/staging/dt3155v4l/Kconfig +++ b/drivers/staging/dt3155v4l/Kconfig @@ -18,11 +18,3 @@ config DT3155_CCIR ---help--- Select it for CCIR/50Hz (European region), or leave it unselected for RS-170/60Hz (North America). - -config DT3155_STREAMING - bool "Selects mmap streaming instead of read method" - depends on VIDEO_DT3155 - default y - ---help--- - Select it if you wish to try mmap streaming, or - or leave it unselected for using read method. diff --git a/drivers/staging/dt3155v4l/dt3155v4l.c b/drivers/staging/dt3155v4l/dt3155v4l.c index 49463611f4f3..308fb45965b3 100644 --- a/drivers/staging/dt3155v4l/dt3155v4l.c +++ b/drivers/staging/dt3155v4l/dt3155v4l.c @@ -930,6 +930,7 @@ dt3155_release(struct file *filp) dt3155_stop_acq(pd); videobuf_stop(pd->vidq); pd->acq_fp = NULL; + pd->streaming = 0; } if (!pd->users) { kthread_stop(pd->thread); @@ -949,11 +950,15 @@ dt3155_read(struct file *filp, char __user *user, size_t size, loff_t *loff) if (mutex_lock_interruptible(&pd->mux) == -EINTR) return -ERESTARTSYS; - if (!pd->acq_fp) + if (!pd->acq_fp) { pd->acq_fp = filp; - else if (pd->acq_fp != filp) { + pd->streaming = 0; + } else if (pd->acq_fp != filp) { ret = -EBUSY; goto done; + } else if (pd->streaming == 1) { + ret = -EINVAL; + goto done; } ret = videobuf_read_stream(pd->vidq, user, size, loff, 0, filp->f_flags & O_NONBLOCK); @@ -1001,8 +1006,10 @@ dt3155_ioc_streamon(struct file *filp, void *p, enum v4l2_buf_type type) if (ret) goto unlock; pd->acq_fp = filp; + pd->streaming = 1; wake_up_interruptible_sync(&pd->do_dma); } else if (pd->acq_fp == filp) { + pd->streaming = 1; ret = videobuf_streamon(pd->vidq); if (!ret) wake_up_interruptible_sync(&pd->do_dma); @@ -1043,11 +1050,8 @@ dt3155_ioc_querycap(struct file *filp, void *p, struct v4l2_capability *cap) cap->version = KERNEL_VERSION(DT3155_VER_MAJ, DT3155_VER_MIN, DT3155_VER_EXT); cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | -#ifdef CONFIG_DT3155_STREAMING - V4L2_CAP_STREAMING; -#else + V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; -#endif return 0; } @@ -1095,7 +1099,28 @@ dt3155_ioc_try_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f) static int dt3155_ioc_s_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f) { - return dt3155_ioc_g_fmt_vid_cap(filp, p, f); + struct dt3155_priv *pd = video_drvdata(filp); + int ret = -ERESTARTSYS; + + if (mutex_lock_interruptible(&pd->mux) == -EINTR) + return ret; + if (!pd->acq_fp) { + pd->acq_fp = filp; + pd->streaming = 0; + } else if (pd->acq_fp != filp) { + ret = -EBUSY; + goto done; + } +/* FIXME: we don't change the format for now + if (pd->vidq->streaming || pd->vidq->reading || pd->curr_buff) { + ret = -EBUSY; + goto done; + } +*/ + ret = dt3155_ioc_g_fmt_vid_cap(filp, p, f); +done: + mutex_unlock(&pd->mux); + return ret; } static int @@ -1103,15 +1128,33 @@ dt3155_ioc_reqbufs(struct file *filp, void *p, struct v4l2_requestbuffers *b) { struct dt3155_priv *pd = video_drvdata(filp); struct videobuf_queue *q = pd->vidq; + int ret = -ERESTARTSYS; if (b->memory != V4L2_MEMORY_MMAP) return -EINVAL; + if (mutex_lock_interruptible(&pd->mux) == -EINTR) + return ret; + if (!pd->acq_fp) + pd->acq_fp = filp; + else if (pd->acq_fp != filp) { + ret = -EBUSY; + goto done; + } + pd->streaming = 1; + ret = 0; +done: + mutex_unlock(&pd->mux); + if (ret) + return ret; if (b->count) - return videobuf_reqbufs(q, b); + ret = videobuf_reqbufs(q, b); else { /* FIXME: is it necessary? */ printk(KERN_DEBUG "dt3155: request to free buffers\n"); - return videobuf_mmap_free(q); + /* ret = videobuf_mmap_free(q); */ + ret = dt3155_ioc_streamoff(filp, p, + V4L2_BUF_TYPE_VIDEO_CAPTURE); } + return ret; } static int @@ -1128,8 +1171,12 @@ dt3155_ioc_qbuf(struct file *filp, void *p, struct v4l2_buffer *b) { struct dt3155_priv *pd = video_drvdata(filp); struct videobuf_queue *q = pd->vidq; + int ret; - return videobuf_qbuf(q, b); + ret = videobuf_qbuf(q, b); + if (ret) + return ret; + return videobuf_querybuf(q, b); } static int @@ -1170,7 +1217,12 @@ dt3155_ioc_enum_input(struct file *filp, void *p, struct v4l2_input *input) return -EINVAL; strcpy(input->name, "Coax in"); input->type = V4L2_INPUT_TYPE_CAMERA; - input->std = V4L2_STD_ALL; + /* + * FIXME: input->std = 0 according to v4l2 API + * VIDIOC_G_STD, VIDIOC_S_STD, VIDIOC_QUERYSTD and VIDIOC_ENUMSTD + * should return -EINVAL + */ + input->std = DT3155_CURRENT_NORM; input->status = 0;/* FIXME: add sync detection & V4L2_IN_ST_NO_H_LOCK */ return 0; } @@ -1200,7 +1252,7 @@ dt3155_ioc_g_parm(struct file *filp, void *p, struct v4l2_streamparm *parms) parms->parm.capture.timeperframe.numerator = 1001; parms->parm.capture.timeperframe.denominator = frames_per_sec * 1000; parms->parm.capture.extendedmode = 0; - parms->parm.capture.readbuffers = 1; + parms->parm.capture.readbuffers = 1; /* FIXME: 2 buffers? */ return 0; } @@ -1214,7 +1266,7 @@ dt3155_ioc_s_parm(struct file *filp, void *p, struct v4l2_streamparm *parms) parms->parm.capture.timeperframe.numerator = 1001; parms->parm.capture.timeperframe.denominator = frames_per_sec * 1000; parms->parm.capture.extendedmode = 0; - parms->parm.capture.readbuffers = 1; + parms->parm.capture.readbuffers = 1; /* FIXME: 2 buffers? */ return 0; } @@ -1377,7 +1429,7 @@ static struct video_device dt3155_vdev = { .ioctl_ops = &dt3155_ioctl_ops, .minor = -1, .release = video_device_release, - .tvnorms = V4L2_STD_ALL, + .tvnorms = DT3155_CURRENT_NORM, .current_norm = DT3155_CURRENT_NORM, }; diff --git a/drivers/staging/dt3155v4l/dt3155v4l.h b/drivers/staging/dt3155v4l/dt3155v4l.h index 4c6a0ee08c0e..e65a81e198b9 100644 --- a/drivers/staging/dt3155v4l/dt3155v4l.h +++ b/drivers/staging/dt3155v4l/dt3155v4l.h @@ -30,7 +30,7 @@ #define DT3155_NAME "dt3155" #define DT3155_VER_MAJ 1 #define DT3155_VER_MIN 0 -#define DT3155_VER_EXT 2 +#define DT3155_VER_EXT 3 #define DT3155_VERSION __stringify(DT3155_VER_MAJ) "." \ __stringify(DT3155_VER_MIN) "." \ __stringify(DT3155_VER_EXT) @@ -180,6 +180,7 @@ struct dt3155_stats { * * @vdev: pointer to video_device structure * @acq_fp pointer to filp that starts acquisition + * @streaming streaming is negotiated * @pdev: pointer to pci_dev structure * @vidq pointer to videobuf_queue structure * @curr_buf: pointer to curren buffer @@ -200,6 +201,7 @@ struct dt3155_stats { struct dt3155_priv { struct video_device *vdev; struct file *acq_fp; + int streaming; struct pci_dev *pdev; struct videobuf_queue *vidq; struct videobuf_buffer *curr_buf; -- cgit v1.2.3 From b5a2104c98cb603f7053e4b0309fb88f15d6be86 Mon Sep 17 00:00:00 2001 From: Soeren Moeller Date: Fri, 14 May 2010 19:03:00 +0000 Subject: Staging: udlfb: fix coding style issues This is a patch to the file udlfb.c that fixes a missing KERN_INFO and removes one whitespace before a newline. Signed-off-by: Soeren Moeller Cc: Bernie Thompson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/udlfb/udlfb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/udlfb/udlfb.c b/drivers/staging/udlfb/udlfb.c index 12444f2014e4..7fc1d611a78a 100644 --- a/drivers/staging/udlfb/udlfb.c +++ b/drivers/staging/udlfb/udlfb.c @@ -1438,7 +1438,7 @@ static int __init dlfb_module_init(void) if (res) err("usb_register failed. Error number %d", res); - printk("VMODES initialized\n"); + printk(KERN_INFO "VMODES initialized\n"); return res; } @@ -1567,7 +1567,7 @@ static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size) kref_get(&dev->kref); /* released in free_render_urbs() */ - dl_notice("allocated %d %d byte urbs \n", i, (int) size); + dl_notice("allocated %d %d byte urbs\n", i, (int) size); return i; } -- cgit v1.2.3 From 7a6cb0d5497418599d2125b670926b75e673861c Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 13 May 2010 22:00:05 +0200 Subject: Staging: Use kcalloc or kzalloc Use kcalloc or kzalloc rather than the combination of kmalloc and memset. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression x,y,flags; statement S; type T; @@ x = - kmalloc + kcalloc ( - y * sizeof(T), + y, sizeof(T), flags); if (x == NULL) S -memset(x, 0, y * sizeof(T)); @@ expression x,size,flags; statement S; @@ -x = kmalloc(size,flags); +x = kzalloc(size,flags); if (x == NULL) S -memset(x, 0, size); // Signed-off-by: Julia Lawall --- drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h | 4 +--- drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h | 4 +--- drivers/staging/comedi/drivers/icp_multi.h | 3 +-- drivers/staging/dream/pmem.c | 5 +---- drivers/staging/go7007/go7007-fw.c | 12 ++++-------- drivers/staging/go7007/go7007-usb.c | 3 +-- drivers/staging/go7007/go7007-v4l2.c | 4 +--- drivers/staging/go7007/saa7134-go7007.c | 3 +-- drivers/staging/otus/zdusb.c | 5 +---- drivers/staging/panel/panel.c | 3 +-- drivers/staging/pohmelfs/config.c | 3 +-- drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c | 6 ++---- drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c | 3 +-- drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c | 3 +-- drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c | 3 +-- drivers/staging/rtl8187se/ieee80211/ieee80211_module.c | 7 ++----- drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c | 3 +-- drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c | 6 ++---- drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c | 3 +-- drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c | 3 +-- drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c | 3 +-- drivers/staging/rtl8192e/ieee80211/ieee80211_module.c | 7 ++----- drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c | 3 +-- drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c | 3 +-- drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c | 6 ++---- drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c | 3 +-- drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c | 3 +-- drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_wep.c | 3 +-- drivers/staging/rtl8192su/ieee80211/ieee80211_module.c | 7 ++----- drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c | 3 +-- drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c | 3 +-- drivers/staging/rtl8192u/ieee80211/api.c | 4 +--- drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c | 6 ++---- drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c | 3 +-- drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c | 3 +-- drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c | 3 +-- drivers/staging/rtl8192u/ieee80211/ieee80211_module.c | 7 ++----- drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c | 3 +-- drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c | 3 +-- drivers/staging/rtl8192u/r8192U_core.c | 4 +--- drivers/staging/sm7xx/smtcfb.c | 4 +--- drivers/staging/vme/bridges/vme_ca91cx42.c | 8 ++------ drivers/staging/vme/bridges/vme_tsi148.c | 8 ++------ drivers/staging/vt6655/hostap.c | 3 +-- drivers/staging/vt6655/wpactl.c | 3 +-- drivers/staging/vt6656/hostap.c | 3 +-- drivers/staging/vt6656/wpactl.c | 3 +-- drivers/staging/wlan-ng/p80211conv.c | 3 +-- drivers/staging/wlan-ng/prism2fw.c | 3 +-- 49 files changed, 62 insertions(+), 142 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h index 3682503e3412..c3284eb0f0ac 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h @@ -260,12 +260,10 @@ void v_pci_card_list_init(unsigned short pci_vendor, char display) for (i_Count = 0; i_Count < 2; i_Count++) { pci_vendor = i_ADDIDATADeviceID[i_Count]; if (pcidev->vendor == pci_vendor) { - amcc = kmalloc(sizeof(*amcc), GFP_KERNEL); + amcc = kzalloc(sizeof(*amcc), GFP_KERNEL); if (amcc == NULL) continue; - memset(amcc, 0, sizeof(*amcc)); - amcc->pcidev = pcidev; if (last) last->next = amcc; diff --git a/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h b/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h index 49141b3558e1..349e93c23e91 100644 --- a/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h +++ b/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h @@ -253,12 +253,10 @@ void v_pci_card_list_init(unsigned short pci_vendor, char display) pci_for_each_dev(pcidev) { if (pcidev->vendor == pci_vendor) { - amcc = kmalloc(sizeof(*amcc), GFP_KERNEL); + amcc = kzalloc(sizeof(*amcc), GFP_KERNEL); if (amcc == NULL) continue; - memset(amcc, 0, sizeof(*amcc)); - amcc->pcidev = pcidev; if (last) { last->next = amcc; diff --git a/drivers/staging/comedi/drivers/icp_multi.h b/drivers/staging/comedi/drivers/icp_multi.h index 8caadc630ed5..2bb96b1d21e7 100644 --- a/drivers/staging/comedi/drivers/icp_multi.h +++ b/drivers/staging/comedi/drivers/icp_multi.h @@ -73,14 +73,13 @@ static void pci_card_list_init(unsigned short pci_vendor, char display) pcidev != NULL; pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) { if (pcidev->vendor == pci_vendor) { - inova = kmalloc(sizeof(*inova), GFP_KERNEL); + inova = kzalloc(sizeof(*inova), GFP_KERNEL); if (!inova) { printk ("icp_multi: pci_card_list_init: allocation failed\n"); pci_dev_put(pcidev); break; } - memset(inova, 0, sizeof(*inova)); inova->pcidev = pci_dev_get(pcidev); if (last) { diff --git a/drivers/staging/dream/pmem.c b/drivers/staging/dream/pmem.c index dbd2b1d14c4f..6387365a833d 100644 --- a/drivers/staging/dream/pmem.c +++ b/drivers/staging/dream/pmem.c @@ -1245,14 +1245,11 @@ int pmem_setup(struct android_pmem_platform_data *pdata, } pmem[id].num_entries = pmem[id].size / PMEM_MIN_ALLOC; - pmem[id].bitmap = kmalloc(pmem[id].num_entries * + pmem[id].bitmap = kcalloc(pmem[id].num_entries, sizeof(struct pmem_bits), GFP_KERNEL); if (!pmem[id].bitmap) goto err_no_mem_for_metadata; - memset(pmem[id].bitmap, 0, sizeof(struct pmem_bits) * - pmem[id].num_entries); - for (i = sizeof(pmem[id].num_entries) * 8 - 1; i >= 0; i--) { if ((pmem[id].num_entries) & 1<interlace_coding) framelen[0] += mpeg1_frame_header(go, buf + framelen[0] / 8, @@ -839,13 +837,12 @@ static int gen_mpeg4hdr_to_package(struct go7007 *go, unsigned int addr = 0x19; int i, off = 0, chunk; - buf = kmalloc(5120, GFP_KERNEL); + buf = kzalloc(5120, GFP_KERNEL); if (buf == NULL) { printk(KERN_ERR "go7007: unable to allocate 5120 bytes for " "firmware construction\n"); return -1; } - memset(buf, 0, 5120); framelen[0] = mpeg4_frame_header(go, buf, 0, PFRAME); i = 368; framelen[1] = mpeg4_frame_header(go, buf + i, 0, BFRAME_PRE); @@ -1585,13 +1582,12 @@ int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen) go->board_info->firmware); return -1; } - code = kmalloc(codespace * 2, GFP_KERNEL); + code = kzalloc(codespace * 2, GFP_KERNEL); if (code == NULL) { printk(KERN_ERR "go7007: unable to allocate %d bytes for " "firmware construction\n", codespace * 2); goto fw_failed; } - memset(code, 0, codespace * 2); src = (__le16 *)fw_entry->data; srclen = fw_entry->size / 2; while (srclen >= 2) { diff --git a/drivers/staging/go7007/go7007-usb.c b/drivers/staging/go7007/go7007-usb.c index ee278f64a16b..20ed930b588c 100644 --- a/drivers/staging/go7007/go7007-usb.c +++ b/drivers/staging/go7007/go7007-usb.c @@ -670,10 +670,9 @@ static int go7007_usb_onboard_write_interrupt(struct go7007 *go, "go7007-usb: WriteInterrupt: %04x %04x\n", addr, data); #endif - tbuf = kmalloc(8, GFP_KERNEL); + tbuf = kzalloc(8, GFP_KERNEL); if (tbuf == NULL) return -ENOMEM; - memset(tbuf, 0, 8); tbuf[0] = data & 0xff; tbuf[1] = data >> 8; tbuf[2] = addr & 0xff; diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c index 723c1a64d87f..46b4b9f6855b 100644 --- a/drivers/staging/go7007/go7007-v4l2.c +++ b/drivers/staging/go7007/go7007-v4l2.c @@ -720,7 +720,7 @@ static int vidioc_reqbufs(struct file *file, void *priv, if (count > 32) count = 32; - gofh->bufs = kmalloc(count * sizeof(struct go7007_buffer), + gofh->bufs = kcalloc(count, sizeof(struct go7007_buffer), GFP_KERNEL); if (!gofh->bufs) { @@ -728,8 +728,6 @@ static int vidioc_reqbufs(struct file *file, void *priv, goto unlock_and_return; } - memset(gofh->bufs, 0, count * sizeof(struct go7007_buffer)); - for (i = 0; i < count; ++i) { gofh->bufs[i].go = go; gofh->bufs[i].index = i; diff --git a/drivers/staging/go7007/saa7134-go7007.c b/drivers/staging/go7007/saa7134-go7007.c index b25d7d2090e1..49f0d31c118a 100644 --- a/drivers/staging/go7007/saa7134-go7007.c +++ b/drivers/staging/go7007/saa7134-go7007.c @@ -440,10 +440,9 @@ static int saa7134_go7007_init(struct saa7134_dev *dev) printk(KERN_DEBUG "saa7134-go7007: probing new SAA713X board\n"); - saa = kmalloc(sizeof(struct saa7134_go7007), GFP_KERNEL); + saa = kzalloc(sizeof(struct saa7134_go7007), GFP_KERNEL); if (saa == NULL) return -ENOMEM; - memset(saa, 0, sizeof(struct saa7134_go7007)); /* Allocate a couple pages for receiving the compressed stream */ saa->top = (u8 *)get_zeroed_page(GFP_KERNEL); diff --git a/drivers/staging/otus/zdusb.c b/drivers/staging/otus/zdusb.c index 6509bc565e65..2c799a250294 100644 --- a/drivers/staging/otus/zdusb.c +++ b/drivers/staging/otus/zdusb.c @@ -95,7 +95,7 @@ static int zfLnxProbe(struct usb_interface *interface, printk(KERN_NOTICE "USB 1.1 Host\n"); #endif - macp = kmalloc(sizeof(struct usbdrv_private), GFP_KERNEL); + macp = kzalloc(sizeof(struct usbdrv_private), GFP_KERNEL); if (!macp) { printk(KERN_ERR "out of memory allocating device structure\n"); @@ -103,9 +103,6 @@ static int zfLnxProbe(struct usb_interface *interface, goto fail; } - /* Zero the memory */ - memset(macp, 0, sizeof(struct usbdrv_private)); - net = alloc_etherdev(0); if (net == NULL) diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index f9fcb2fef5a0..9ca0e9e2a961 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c @@ -1906,12 +1906,11 @@ static struct logical_input *panel_bind_key(char *name, char *press, { struct logical_input *key; - key = kmalloc(sizeof(struct logical_input), GFP_KERNEL); + key = kzalloc(sizeof(struct logical_input), GFP_KERNEL); if (!key) { printk(KERN_ERR "panel: not enough memory\n"); return NULL; } - memset(key, 0, sizeof(struct logical_input)); if (!input_name2mask(name, &key->mask, &key->value, &scan_mask_i, &scan_mask_o)) return NULL; diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c index 6571a6ae05a5..9fdf2de347ea 100644 --- a/drivers/staging/pohmelfs/config.c +++ b/drivers/staging/pohmelfs/config.c @@ -238,11 +238,10 @@ static int pohmelfs_send_reply(int err, int msg_num, int action, struct cn_msg * { struct pohmelfs_cn_ack *ack; - ack = kmalloc(sizeof(struct pohmelfs_cn_ack), GFP_KERNEL); + ack = kzalloc(sizeof(struct pohmelfs_cn_ack), GFP_KERNEL); if (!ack) return -ENOMEM; - memset(ack, 0, sizeof(struct pohmelfs_cn_ack)); memcpy(&ack->msg, msg, sizeof(struct cn_msg)); if (action == POHMELFS_CTLINFO_ACK) diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c index 4c5d63fd5833..c8dbcb925915 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c @@ -109,11 +109,10 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops) if (hcrypt == NULL) return -1; - alg = kmalloc(sizeof(*alg), GFP_KERNEL); + alg = kzalloc(sizeof(*alg), GFP_KERNEL); if (alg == NULL) return -ENOMEM; - memset(alg, 0, sizeof(*alg)); alg->ops = ops; spin_lock_irqsave(&hcrypt->lock, flags); @@ -207,11 +206,10 @@ int ieee80211_crypto_init(void) { int ret = -ENOMEM; - hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL); + hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL); if (!hcrypt) goto out; - memset(hcrypt, 0, sizeof(*hcrypt)); INIT_LIST_HEAD(&hcrypt->algs); spin_lock_init(&hcrypt->lock); diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c index 40f1b99faad2..731d2686411e 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c @@ -69,10 +69,9 @@ static void * ieee80211_ccmp_init(int key_idx) { struct ieee80211_ccmp_data *priv; - priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + priv = kzalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; - memset(priv, 0, sizeof(*priv)); priv->key_idx = key_idx; priv->tfm = (void *)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c index a5254111d9a1..ee71ee90fd89 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c @@ -70,10 +70,9 @@ static void * ieee80211_tkip_init(int key_idx) { struct ieee80211_tkip_data *priv; - priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + priv = kzalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; - memset(priv, 0, sizeof(*priv)); priv->key_idx = key_idx; priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c index c6c3bc38459b..f790cd65f107 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c @@ -45,10 +45,9 @@ static void * prism2_wep_init(int keyidx) { struct prism2_wep_data *priv; - priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + priv = kzalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; - memset(priv, 0, sizeof(*priv)); priv->key_idx = keyidx; priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tx_tfm)) { diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c index 18392fce487d..9d58a429c565 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c @@ -66,8 +66,8 @@ static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee) if (ieee->networks) return 0; - ieee->networks = kmalloc( - MAX_NETWORK_COUNT * sizeof(struct ieee80211_network), + ieee->networks = kcalloc( + MAX_NETWORK_COUNT, sizeof(struct ieee80211_network), GFP_KERNEL); if (!ieee->networks) { printk(KERN_WARNING "%s: Out of memory allocating beacons\n", @@ -75,9 +75,6 @@ static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee) return -ENOMEM; } - memset(ieee->networks, 0, - MAX_NETWORK_COUNT * sizeof(struct ieee80211_network)); - return 0; } diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c index c5b80f9c32c0..aa3ba450ecef 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c @@ -325,11 +325,10 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee, struct ieee80211_crypt_data *new_crypt; /* take WEP into use */ - new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data), + new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL); if (new_crypt == NULL) return -ENOMEM; - memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); new_crypt->ops = ieee80211_get_crypto_ops("WEP"); if (!new_crypt->ops) new_crypt->ops = ieee80211_get_crypto_ops("WEP"); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c index b3c9bf4b4ea6..d5aa9af3d9f4 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c @@ -109,11 +109,10 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops) if (hcrypt == NULL) return -1; - alg = kmalloc(sizeof(*alg), GFP_KERNEL); + alg = kzalloc(sizeof(*alg), GFP_KERNEL); if (alg == NULL) return -ENOMEM; - memset(alg, 0, sizeof(*alg)); alg->ops = ops; spin_lock_irqsave(&hcrypt->lock, flags); @@ -207,11 +206,10 @@ int __init ieee80211_crypto_init(void) { int ret = -ENOMEM; - hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL); + hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL); if (!hcrypt) goto out; - memset(hcrypt, 0, sizeof(*hcrypt)); INIT_LIST_HEAD(&hcrypt->algs); spin_lock_init(&hcrypt->lock); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c index 1776f7e69bfe..7165c4c75c7e 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c @@ -96,10 +96,9 @@ static void * ieee80211_ccmp_init(int key_idx) { struct ieee80211_ccmp_data *priv; - priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + priv = kzalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; - memset(priv, 0, sizeof(*priv)); priv->key_idx = key_idx; #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c index 03cb21eb0658..65f48896bfaa 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c @@ -87,10 +87,9 @@ static void * ieee80211_tkip_init(int key_idx) { struct ieee80211_tkip_data *priv; - priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + priv = kzalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; - memset(priv, 0, sizeof(*priv)); priv->key_idx = key_idx; #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) priv->tx_tfm_arc4 = crypto_alloc_tfm("arc4", 0); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c index 5678313e30a5..c4bbc8ddbad1 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c @@ -71,10 +71,9 @@ static void * prism2_wep_init(int keyidx) { struct prism2_wep_data *priv; - priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + priv = kzalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; - memset(priv, 0, sizeof(*priv)); priv->key_idx = keyidx; #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED)) diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c index c7aa1c63cb19..614a8b630e67 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c @@ -65,8 +65,8 @@ static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee) if (ieee->networks) return 0; - ieee->networks = kmalloc( - MAX_NETWORK_COUNT * sizeof(struct ieee80211_network), + ieee->networks = kcalloc( + MAX_NETWORK_COUNT, sizeof(struct ieee80211_network), GFP_KERNEL); if (!ieee->networks) { printk(KERN_WARNING "%s: Out of memory allocating beacons\n", @@ -74,9 +74,6 @@ static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee) return -ENOMEM; } - memset(ieee->networks, 0, - MAX_NETWORK_COUNT * sizeof(struct ieee80211_network)); - return 0; } diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index 4f6ce06b606b..215542a00ef1 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -3079,10 +3079,9 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee) ieee->seq_ctrl[i] = 0; } #ifdef ENABLE_DOT11D - ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC); + ieee->pDot11dInfo = kzalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC); if (!ieee->pDot11dInfo) IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n"); - memset(ieee->pDot11dInfo, 0, sizeof(RT_DOT11D_INFO)); #endif //added for AP roaming ieee->LinkDetectInfo.SlotNum = 2; diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c index de57967b9681..fcabaf3c88d4 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c @@ -477,11 +477,10 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee, struct ieee80211_crypt_data *new_crypt; /* take WEP into use */ - new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data), + new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL); if (new_crypt == NULL) return -ENOMEM; - memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); new_crypt->ops = ieee80211_get_crypto_ops("WEP"); if (!new_crypt->ops) new_crypt->ops = ieee80211_get_crypto_ops("WEP"); diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c index c4640e63196b..801942339437 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c @@ -109,11 +109,10 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops) if (hcrypt == NULL) return -1; - alg = kmalloc(sizeof(*alg), GFP_KERNEL); + alg = kzalloc(sizeof(*alg), GFP_KERNEL); if (alg == NULL) return -ENOMEM; - memset(alg, 0, sizeof(*alg)); alg->ops = ops; spin_lock_irqsave(&hcrypt->lock, flags); @@ -206,11 +205,10 @@ int __init ieee80211_crypto_init(void) { int ret = -ENOMEM; - hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL); + hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL); if (!hcrypt) goto out; - memset(hcrypt, 0, sizeof(*hcrypt)); INIT_LIST_HEAD(&hcrypt->algs); spin_lock_init(&hcrypt->lock); diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c index 8a93f7d3eb38..77de957f1b1f 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c @@ -68,10 +68,9 @@ static void * ieee80211_ccmp_init(int key_idx) { struct ieee80211_ccmp_data *priv; - priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + priv = kzalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; - memset(priv, 0, sizeof(*priv)); priv->key_idx = key_idx; priv->tfm = (void *)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c index 7e48748da102..ade5f6f13667 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c @@ -67,10 +67,9 @@ static void * ieee80211_tkip_init(int key_idx) { struct ieee80211_tkip_data *priv; - priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + priv = kzalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; - memset(priv, 0, sizeof(*priv)); priv->key_idx = key_idx; priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_wep.c index 64f9cf01c94e..a1c0a59122b8 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_wep.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_wep.c @@ -43,10 +43,9 @@ static void * prism2_wep_init(int keyidx) { struct prism2_wep_data *priv; - priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + priv = kzalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; - memset(priv, 0, sizeof(*priv)); priv->key_idx = keyidx; priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c index 73de3baf9158..a87650a517bd 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c @@ -65,8 +65,8 @@ static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee) if (ieee->networks) return 0; - ieee->networks = kmalloc( - MAX_NETWORK_COUNT * sizeof(struct ieee80211_network), + ieee->networks = kcalloc( + MAX_NETWORK_COUNT, sizeof(struct ieee80211_network), GFP_KERNEL); if (!ieee->networks) { printk(KERN_WARNING "%s: Out of memory allocating beacons\n", @@ -74,9 +74,6 @@ static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee) return -ENOMEM; } - memset(ieee->networks, 0, - MAX_NETWORK_COUNT * sizeof(struct ieee80211_network)); - return 0; } diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c index 660aee2874a4..b9fa15fccb78 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c @@ -2699,10 +2699,9 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee) for(i = 0; i < 5; i++) { ieee->seq_ctrl[i] = 0; } - ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC); + ieee->pDot11dInfo = kzalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC); if (!ieee->pDot11dInfo) IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n"); - memset(ieee->pDot11dInfo, 0, sizeof(RT_DOT11D_INFO)); //added for AP roaming ieee->LinkDetectInfo.SlotNum = 2; ieee->LinkDetectInfo.NumRecvBcnInPeriod=0; diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c index 727cc552c5ee..db54ad096da0 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c @@ -352,11 +352,10 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee, struct ieee80211_crypt_data *new_crypt; /* take WEP into use */ - new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data), + new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL); if (new_crypt == NULL) return -ENOMEM; - memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); new_crypt->ops = ieee80211_get_crypto_ops("WEP"); if (!new_crypt->ops) new_crypt->ops = ieee80211_get_crypto_ops("WEP"); diff --git a/drivers/staging/rtl8192u/ieee80211/api.c b/drivers/staging/rtl8192u/ieee80211/api.c index c627d029528b..5f46e50e586e 100644 --- a/drivers/staging/rtl8192u/ieee80211/api.c +++ b/drivers/staging/rtl8192u/ieee80211/api.c @@ -131,12 +131,10 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags) if (alg == NULL) goto out; - tfm = kmalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL); + tfm = kzalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL); if (tfm == NULL) goto out_put; - memset(tfm, 0, sizeof(*tfm) + alg->cra_ctxsize); - tfm->__crt_alg = alg; if (crypto_init_flags(tfm, flags)) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c index 521e7b989934..8707eba4f905 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c @@ -109,11 +109,10 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops) if (hcrypt == NULL) return -1; - alg = kmalloc(sizeof(*alg), GFP_KERNEL); + alg = kzalloc(sizeof(*alg), GFP_KERNEL); if (alg == NULL) return -ENOMEM; - memset(alg, 0, sizeof(*alg)); alg->ops = ops; spin_lock_irqsave(&hcrypt->lock, flags); @@ -206,11 +205,10 @@ int __init ieee80211_crypto_init(void) { int ret = -ENOMEM; - hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL); + hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL); if (!hcrypt) goto out; - memset(hcrypt, 0, sizeof(*hcrypt)); INIT_LIST_HEAD(&hcrypt->algs); spin_lock_init(&hcrypt->lock); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c index 0b57632bcff9..4b078e536382 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c @@ -68,10 +68,9 @@ static void * ieee80211_ccmp_init(int key_idx) { struct ieee80211_ccmp_data *priv; - priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + priv = kzalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; - memset(priv, 0, sizeof(*priv)); priv->key_idx = key_idx; priv->tfm = (void*)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c index 9510507d8d05..a98584c845b8 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c @@ -67,10 +67,9 @@ static void * ieee80211_tkip_init(int key_idx) { struct ieee80211_tkip_data *priv; - priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + priv = kzalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; - memset(priv, 0, sizeof(*priv)); priv->key_idx = key_idx; priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c index 61ad11cae38c..96c2c9d67fd1 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c @@ -43,10 +43,9 @@ static void * prism2_wep_init(int keyidx) { struct prism2_wep_data *priv; - priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + priv = kzalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; - memset(priv, 0, sizeof(*priv)); priv->key_idx = keyidx; priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c index 1111002bad9f..7455264aa543 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c @@ -65,8 +65,8 @@ static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee) if (ieee->networks) return 0; - ieee->networks = kmalloc( - MAX_NETWORK_COUNT * sizeof(struct ieee80211_network), + ieee->networks = kcalloc( + MAX_NETWORK_COUNT, sizeof(struct ieee80211_network), GFP_KERNEL); if (!ieee->networks) { printk(KERN_WARNING "%s: Out of memory allocating beacons\n", @@ -74,9 +74,6 @@ static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee) return -ENOMEM; } - memset(ieee->networks, 0, - MAX_NETWORK_COUNT * sizeof(struct ieee80211_network)); - return 0; } diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index 6c6bf9f6e78a..a6955e2b45c4 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -2723,10 +2723,9 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee) ieee->seq_ctrl[i] = 0; } #ifdef ENABLE_DOT11D - ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC); + ieee->pDot11dInfo = kzalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC); if (!ieee->pDot11dInfo) IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n"); - memset(ieee->pDot11dInfo, 0, sizeof(RT_DOT11D_INFO)); #endif //added for AP roaming ieee->LinkDetectInfo.SlotNum = 2; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c index 4d5348e6c104..79b180f79e80 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c @@ -379,11 +379,10 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee, struct ieee80211_crypt_data *new_crypt; /* take WEP into use */ - new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data), + new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL); if (new_crypt == NULL) return -ENOMEM; - memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); new_crypt->ops = ieee80211_get_crypto_ops("WEP"); if (!new_crypt->ops) { request_module("ieee80211_crypt_wep"); diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index cbbc7d32fcf3..2bede271a2f0 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -2251,13 +2251,11 @@ short rtl8192_usb_initendpoints(struct net_device *dev) #endif memset(priv->rx_urb, 0, sizeof(struct urb*) * MAX_RX_URB); - priv->pp_rxskb = kmalloc(sizeof(struct sk_buff *) * MAX_RX_URB, + priv->pp_rxskb = kcalloc(MAX_RX_URB, sizeof(struct sk_buff *), GFP_KERNEL); if (priv->pp_rxskb == NULL) goto destroy; - memset(priv->pp_rxskb, 0, sizeof(struct sk_buff*) * MAX_RX_URB); - goto _middle; diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c index e817a20d1bdd..9ffeb36ddde6 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xx/smtcfb.c @@ -688,13 +688,11 @@ static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *dev, { struct smtcfb_info *sfb; - sfb = kmalloc(sizeof(struct smtcfb_info), GFP_KERNEL); + sfb = kzalloc(sizeof(struct smtcfb_info), GFP_KERNEL); if (!sfb) return NULL; - memset(sfb, 0, sizeof(struct smtcfb_info)); - sfb->currcon = -1; sfb->dev = dev; diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c index c35dead64a38..0c82eb47a28d 100644 --- a/drivers/staging/vme/bridges/vme_ca91cx42.c +++ b/drivers/staging/vme/bridges/vme_ca91cx42.c @@ -1494,7 +1494,7 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* We want to support more than one of each bridge so we need to * dynamically allocate the bridge structure */ - ca91cx42_bridge = kmalloc(sizeof(struct vme_bridge), GFP_KERNEL); + ca91cx42_bridge = kzalloc(sizeof(struct vme_bridge), GFP_KERNEL); if (ca91cx42_bridge == NULL) { dev_err(&pdev->dev, "Failed to allocate memory for device " @@ -1503,9 +1503,7 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_struct; } - memset(ca91cx42_bridge, 0, sizeof(struct vme_bridge)); - - ca91cx42_device = kmalloc(sizeof(struct ca91cx42_driver), GFP_KERNEL); + ca91cx42_device = kzalloc(sizeof(struct ca91cx42_driver), GFP_KERNEL); if (ca91cx42_device == NULL) { dev_err(&pdev->dev, "Failed to allocate memory for device " @@ -1514,8 +1512,6 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_driver; } - memset(ca91cx42_device, 0, sizeof(struct ca91cx42_driver)); - ca91cx42_bridge->driver_priv = ca91cx42_device; /* Enable the device */ diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index 7539cce6e2a7..cf8cf37a82cc 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -2230,7 +2230,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* If we want to support more than one of each bridge, we need to * dynamically generate this so we get one per device */ - tsi148_bridge = kmalloc(sizeof(struct vme_bridge), GFP_KERNEL); + tsi148_bridge = kzalloc(sizeof(struct vme_bridge), GFP_KERNEL); if (tsi148_bridge == NULL) { dev_err(&pdev->dev, "Failed to allocate memory for device " "structure\n"); @@ -2238,9 +2238,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_struct; } - memset(tsi148_bridge, 0, sizeof(struct vme_bridge)); - - tsi148_device = kmalloc(sizeof(struct tsi148_driver), GFP_KERNEL); + tsi148_device = kzalloc(sizeof(struct tsi148_driver), GFP_KERNEL); if (tsi148_device == NULL) { dev_err(&pdev->dev, "Failed to allocate memory for device " "structure\n"); @@ -2248,8 +2246,6 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_driver; } - memset(tsi148_device, 0, sizeof(struct tsi148_driver)); - tsi148_bridge->driver_priv = tsi148_device; /* Enable the device */ diff --git a/drivers/staging/vt6655/hostap.c b/drivers/staging/vt6655/hostap.c index fb7775c52339..195cc36654ae 100644 --- a/drivers/staging/vt6655/hostap.c +++ b/drivers/staging/vt6655/hostap.c @@ -90,10 +90,9 @@ static int hostap_enable_hostapd(PSDevice pDevice, int rtnl_locked) DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Enabling hostapd mode\n", dev->name); - pDevice->apdev = kmalloc(sizeof(struct net_device), GFP_KERNEL); + pDevice->apdev = kzalloc(sizeof(struct net_device), GFP_KERNEL); if (pDevice->apdev == NULL) return -ENOMEM; - memset(pDevice->apdev, 0, sizeof(struct net_device)); apdev_priv = netdev_priv(pDevice->apdev); *apdev_priv = *pDevice; diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c index e5e618eb6bb7..9f215dfa86e0 100644 --- a/drivers/staging/vt6655/wpactl.c +++ b/drivers/staging/vt6655/wpactl.c @@ -681,13 +681,12 @@ static int wpa_get_scan(PSDevice pDevice, count++; }; - pBuf = kmalloc(sizeof(struct viawget_scan_result) * count, (int)GFP_ATOMIC); + pBuf = kcalloc(count, sizeof(struct viawget_scan_result), (int)GFP_ATOMIC); if (pBuf == NULL) { ret = -ENOMEM; return ret; } - memset(pBuf, 0, sizeof(struct viawget_scan_result) * count); scan_buf = (struct viawget_scan_result *)pBuf; pBSS = &(pMgmt->sBSSList[0]); for (ii = 0, jj = 0; ii < MAX_BSS_NUM ; ii++) { diff --git a/drivers/staging/vt6656/hostap.c b/drivers/staging/vt6656/hostap.c index 44386316b216..93e52a3ebd85 100644 --- a/drivers/staging/vt6656/hostap.c +++ b/drivers/staging/vt6656/hostap.c @@ -91,10 +91,9 @@ static int hostap_enable_hostapd(PSDevice pDevice, int rtnl_locked) DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Enabling hostapd mode\n", dev->name); - pDevice->apdev = kmalloc(sizeof(struct net_device), GFP_KERNEL); + pDevice->apdev = kzalloc(sizeof(struct net_device), GFP_KERNEL); if (pDevice->apdev == NULL) return -ENOMEM; - memset(pDevice->apdev, 0, sizeof(struct net_device)); apdev_priv = netdev_priv(pDevice->apdev); *apdev_priv = *pDevice; diff --git a/drivers/staging/vt6656/wpactl.c b/drivers/staging/vt6656/wpactl.c index 8f7ad2c43082..961f583368a1 100644 --- a/drivers/staging/vt6656/wpactl.c +++ b/drivers/staging/vt6656/wpactl.c @@ -678,13 +678,12 @@ static int wpa_get_scan(PSDevice pDevice, count++; }; - pBuf = kmalloc(sizeof(struct viawget_scan_result) * count, (int)GFP_ATOMIC); + pBuf = kcalloc(count, sizeof(struct viawget_scan_result), (int)GFP_ATOMIC); if (pBuf == NULL) { ret = -ENOMEM; return ret; } - memset(pBuf, 0, sizeof(struct viawget_scan_result) * count); scan_buf = (struct viawget_scan_result *)pBuf; pBSS = &(pMgmt->sBSSList[0]); for (ii = 0, jj = 0; ii < MAX_BSS_NUM ; ii++) { diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c index 71c3595fe830..059e15055b74 100644 --- a/drivers/staging/wlan-ng/p80211conv.c +++ b/drivers/staging/wlan-ng/p80211conv.c @@ -601,7 +601,7 @@ int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb) } /* Allocate the rxmeta */ - rxmeta = kmalloc(sizeof(p80211_rxmeta_t), GFP_ATOMIC); + rxmeta = kzalloc(sizeof(p80211_rxmeta_t), GFP_ATOMIC); if (rxmeta == NULL) { printk(KERN_ERR "%s: Failed to allocate rxmeta.\n", @@ -611,7 +611,6 @@ int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb) } /* Initialize the rxmeta */ - memset(rxmeta, 0, sizeof(p80211_rxmeta_t)); rxmeta->wlandev = wlandev; rxmeta->hosttime = jiffies; diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index fc2d8f40edd4..d20c8797bcc7 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -536,13 +536,12 @@ int mkimage(imgchunk_t *clist, unsigned int *ccnt) /* Allocate buffer space for chunks */ for (i = 0; i < *ccnt; i++) { - clist[i].data = kmalloc(clist[i].len, GFP_KERNEL); + clist[i].data = kzalloc(clist[i].len, GFP_KERNEL); if (clist[i].data == NULL) { printk(KERN_ERR "failed to allocate image space, exitting.\n"); return 1; } - memset(clist[i].data, 0, clist[i].len); pr_debug("chunk[%d]: addr=0x%06x len=%d\n", i, clist[i].addr, clist[i].len); } -- cgit v1.2.3 From e28393c0c4416dffb46ca481e670f10c6a35baca Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 16 May 2010 19:45:23 -0300 Subject: thinkpad-acpi: constrain IBM-era support to IBM boxes Lenovo is playing around with its ACPI BIOS, and will end up reusing method names. Their memory is not nearly as long as thinkpad-acpi's... Secure most of the old IBM codepaths against running in a non-IBM box. This would happen on the Lenovo X100e in video_init(), for example. We would misdetect it as an ancient model 570 firmware. Also, refuse to load the driver if we cannot identify the vendor. No ACPI ThinkPad in existence lacks this information, AFAIK. Signed-off-by: Henrique de Moraes Holschuh --- drivers/platform/x86/thinkpad_acpi.c | 57 ++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 63290b33c879..21759dacff6c 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -480,6 +480,15 @@ static unsigned long __init tpacpi_check_quirks( return 0; } +static inline bool __pure __init tpacpi_is_lenovo(void) +{ + return thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO; +} + +static inline bool __pure __init tpacpi_is_ibm(void) +{ + return thinkpad_id.vendor == PCI_VENDOR_ID_IBM; +} /**************************************************************************** **************************************************************************** @@ -1886,7 +1895,9 @@ static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm) (thinkpad_id.ec_version_str) ? thinkpad_id.ec_version_str : "unknown"); - if (thinkpad_id.vendor && thinkpad_id.model_str) + BUG_ON(!thinkpad_id.vendor); + + if (thinkpad_id.model_str) printk(TPACPI_INFO "%s %s, model %s\n", (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ? "IBM" : ((thinkpad_id.vendor == @@ -3353,7 +3364,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) goto err_exit; } - if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { + if (tpacpi_is_lenovo()) { dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, "using Lenovo default hot key map\n"); memcpy(hotkey_keycode_map, &lenovo_keycode_map, @@ -4422,7 +4433,8 @@ static int __init video_init(struct ibm_init_struct *iibm) vdbg_printk(TPACPI_DBG_INIT, "initializing video subdriver\n"); TPACPI_ACPIHANDLE_INIT(vid); - TPACPI_ACPIHANDLE_INIT(vid2); + if (tpacpi_is_ibm()) + TPACPI_ACPIHANDLE_INIT(vid2); if (vid2_handle && acpi_evalf(NULL, &ivga, "\\IVGA", "d") && ivga) /* G41, assume IVGA doesn't change */ @@ -4431,10 +4443,12 @@ static int __init video_init(struct ibm_init_struct *iibm) if (!vid_handle) /* video switching not supported on R30, R31 */ video_supported = TPACPI_VIDEO_NONE; - else if (acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd")) + else if (tpacpi_is_ibm() && + acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd")) /* 570 */ video_supported = TPACPI_VIDEO_570; - else if (acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd")) + else if (tpacpi_is_ibm() && + acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd")) /* 600e/x, 770e, 770x */ video_supported = TPACPI_VIDEO_770; else @@ -4811,8 +4825,10 @@ static int __init light_init(struct ibm_init_struct *iibm) vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n"); - TPACPI_ACPIHANDLE_INIT(ledb); - TPACPI_ACPIHANDLE_INIT(lght); + if (tpacpi_is_ibm()) { + TPACPI_ACPIHANDLE_INIT(ledb); + TPACPI_ACPIHANDLE_INIT(lght); + } TPACPI_ACPIHANDLE_INIT(cmos); INIT_WORK(&tpacpi_led_thinklight.work, light_set_status_worker); @@ -5284,10 +5300,10 @@ static int __init led_init(struct ibm_init_struct *iibm) if (!led_handle) /* led not supported on R30, R31 */ led_supported = TPACPI_LED_NONE; - else if (strlencmp(led_path, "SLED") == 0) + else if (tpacpi_is_ibm() && strlencmp(led_path, "SLED") == 0) /* 570 */ led_supported = TPACPI_LED_570; - else if (strlencmp(led_path, "SYSL") == 0) + else if (tpacpi_is_ibm() && strlencmp(led_path, "SYSL") == 0) /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */ led_supported = TPACPI_LED_OLD; else @@ -5741,11 +5757,12 @@ static int __init thermal_init(struct ibm_init_struct *iibm) TPACPI_THERMAL_TPEC_16 : TPACPI_THERMAL_TPEC_8; } } else if (acpi_tmp7) { - if (acpi_evalf(ec_handle, NULL, "UPDT", "qv")) { + if (tpacpi_is_ibm() && + acpi_evalf(ec_handle, NULL, "UPDT", "qv")) { /* 600e/x, 770e, 770x */ thermal_read_mode = TPACPI_THERMAL_ACPI_UPDT; } else { - /* Standard ACPI TMPx access, max 8 sensors */ + /* IBM/LENOVO DSDT EC.TMPx access, max 8 sensors */ thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07; } } else { @@ -6249,7 +6266,7 @@ static int __init brightness_init(struct ibm_init_struct *iibm) } /* Safety */ - if (thinkpad_id.vendor != PCI_VENDOR_ID_IBM && + if (!tpacpi_is_ibm() && (brightness_mode == TPACPI_BRGHT_MODE_ECNVRAM || brightness_mode == TPACPI_BRGHT_MODE_EC)) return -EINVAL; @@ -7968,9 +7985,11 @@ static int __init fan_init(struct ibm_init_struct *iibm) tp_features.second_fan = 0; fan_control_desired_level = 7; - TPACPI_ACPIHANDLE_INIT(fans); - TPACPI_ACPIHANDLE_INIT(gfan); - TPACPI_ACPIHANDLE_INIT(sfan); + if (tpacpi_is_ibm()) { + TPACPI_ACPIHANDLE_INIT(fans); + TPACPI_ACPIHANDLE_INIT(gfan); + TPACPI_ACPIHANDLE_INIT(sfan); + } quirks = tpacpi_check_quirks(fan_quirk_table, ARRAY_SIZE(fan_quirk_table)); @@ -8662,6 +8681,10 @@ static int __init probe_for_thinkpad(void) if (acpi_disabled) return -ENODEV; + /* It would be dangerous to run the driver in this case */ + if (!tpacpi_is_ibm() && !tpacpi_is_lenovo()) + return -ENODEV; + /* * Non-ancient models have better DMI tagging, but very old models * don't. tpacpi_is_fw_known() is a cheat to help in that case. @@ -9059,9 +9082,7 @@ static int __init thinkpad_acpi_module_init(void) tpacpi_inputdev->name = "ThinkPad Extra Buttons"; tpacpi_inputdev->phys = TPACPI_DRVR_NAME "/input0"; tpacpi_inputdev->id.bustype = BUS_HOST; - tpacpi_inputdev->id.vendor = (thinkpad_id.vendor) ? - thinkpad_id.vendor : - PCI_VENDOR_ID_IBM; + tpacpi_inputdev->id.vendor = thinkpad_id.vendor; tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT; tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION; tpacpi_inputdev->dev.parent = &tpacpi_pdev->dev; -- cgit v1.2.3 From a318930d06a7a93bd50000c7112f995b459adda7 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 16 May 2010 19:45:26 -0300 Subject: thinkpad-acpi: X100e quick fixes The X100e needs some quick fixes to work semi-right with this driver. There are much better ways to do this, but we can start with a quick update and do it properly later. Signed-off-by: Henrique de Moraes Holschuh --- drivers/platform/x86/thinkpad_acpi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 21759dacff6c..7817cef6aae1 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -516,6 +516,7 @@ TPACPI_HANDLE(ec, root, "\\_SB.PCI0.ISA.EC0", /* 240, 240x */ "\\_SB.PCI0.ISA.EC", /* A21e, A2xm/p, T20-22, X20-21 */ "\\_SB.PCI0.AD4S.EC0", /* i1400, R30 */ "\\_SB.PCI0.ICH3.EC0", /* R31 */ + "\\_SB.PCI0.LPC0.EC", /* X100e and a few others */ "\\_SB.PCI0.LPC.EC", /* all others */ ); @@ -537,6 +538,7 @@ TPACPI_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA", /* 570 */ "\\_SB.PCI0.AGP0.VID0", /* 600e/x, 770x */ "\\_SB.PCI0.VID0", /* 770e */ "\\_SB.PCI0.VID", /* A21e, G4x, R50e, X30, X40 */ + "\\_SB.PCI0.AGP.VGA", /* X100e and a few others */ "\\_SB.PCI0.AGP.VID", /* all others */ ); /* R30, R31 */ -- cgit v1.2.3 From 5d756db99a7382d5cd173e912d527e9ee73d0596 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 16 May 2010 19:45:28 -0300 Subject: thinkpad-acpi: fix volume/mute hotkey poll handling The hotkey polling code is supposed to generate hotkey messages as close to the way the IBM event-based volume hotkey firmware does as possible, i.e: * Pressing MUTE issues a mute hotkey event, even if already mute; * Pressing Volume up/down issues a volume up/down hotkey event, even if already at maximum or minumum volume; * The act of unmuting issues a volume up/down event, depending on which hotkey was used to unmute. Fix the code to do just that (mute handling was incorrect), and handle multiple hotkey presses between two polling cycles. The new code uses the volume_toggle bit in NVRAM only to detect repeated presses of the mute key and multiple presses of the volume keys trying to go past the end of the volume scale. This will work around a bug in recent Lenovo firmware (e.g. T400), which causes the firmware to not update the volume_toggle bit in certain situations. Reported-by: Yang Zhe Signed-off-by: Henrique de Moraes Holschuh --- drivers/platform/x86/thinkpad_acpi.c | 71 +++++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 7817cef6aae1..1f27b350ae01 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -122,6 +122,11 @@ enum { TP_NVRAM_POS_LEVEL_VOLUME = 0, }; +/* Misc NVRAM-related */ +enum { + TP_NVRAM_LEVEL_VOLUME_MAX = 14, +}; + /* ACPI HIDs */ #define TPACPI_ACPI_HKEY_HID "IBM0068" @@ -2418,6 +2423,21 @@ static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn, tpacpi_hotkey_send_key(__scancode); \ } while (0) + void issue_volchange(const unsigned int oldvol, + const unsigned int newvol) + { + unsigned int i = oldvol; + + while (i > newvol) { + TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN); + i--; + } + while (i < newvol) { + TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP); + i++; + } + } + TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_THINKPAD, thinkpad_toggle); TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNSPACE, zoom_toggle); TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF7, display_toggle); @@ -2427,24 +2447,47 @@ static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn, TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF8, displayexp_toggle); - /* handle volume */ - if (oldn->volume_toggle != newn->volume_toggle) { - if (oldn->mute != newn->mute) { + /* + * Handle volume + * + * This code is supposed to duplicate the IBM firmware behaviour: + * - Pressing MUTE issues mute hotkey message, even when already mute + * - Pressing Volume up/down issues volume up/down hotkey messages, + * even when already at maximum or minumum volume + * - The act of unmuting issues volume up/down notification, + * depending which key was used to unmute + * + * We are constrained to what the NVRAM can tell us, which is not much + * and certainly not enough if more than one volume hotkey was pressed + * since the last poll cycle. + * + * Just to make our life interesting, some newer Lenovo ThinkPads have + * bugs in the BIOS and may fail to update volume_toggle properly. + */ + if (newn->mute) { + /* muted */ + if (!oldn->mute || + oldn->volume_toggle != newn->volume_toggle || + oldn->volume_level != newn->volume_level) { + /* recently muted, or repeated mute keypress, or + * multiple presses ending in mute */ + issue_volchange(oldn->volume_level, newn->volume_level); TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_MUTE); } - if (oldn->volume_level > newn->volume_level) { - TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN); - } else if (oldn->volume_level < newn->volume_level) { + } else { + /* unmute */ + if (oldn->mute) { + /* recently unmuted, issue 'unmute' keypress */ TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP); - } else if (oldn->mute == newn->mute) { - /* repeated key presses that didn't change state */ - if (newn->mute) { - TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_MUTE); - } else if (newn->volume_level != 0) { - TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP); - } else { + } + if (oldn->volume_level != newn->volume_level) { + issue_volchange(oldn->volume_level, newn->volume_level); + } else if (oldn->volume_toggle != newn->volume_toggle) { + /* repeated vol up/down keypress at end of scale ? */ + if (newn->volume_level == 0) TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN); - } + else if (newn->volume_level >= TP_NVRAM_LEVEL_VOLUME_MAX) + TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP); } } -- cgit v1.2.3 From 7a43f788988ac47b21ce258197c5014b5249c9f5 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 16 May 2010 19:45:31 -0300 Subject: thinkpad-acpi: move greeting messages out of the first subdriver (v2) Move the driver initial greetings out of the first subdriver, as we do a lot of other initialization before that point, and the initial greetings should go as soon as the driver decides that it should load. These greetings are not cosmetic, they make my life easier when users report bugs. Signed-off-by: Henrique de Moraes Holschuh --- drivers/platform/x86/thinkpad_acpi.c | 56 +++++++++++++++++------------------- 1 file changed, 27 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 1f27b350ae01..a768a69d58d2 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -1888,36 +1888,9 @@ static bool __init tpacpi_is_fw_known(void) ****************************************************************************/ /************************************************************************* - * thinkpad-acpi init subdriver + * thinkpad-acpi metadata subdriver */ -static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm) -{ - printk(TPACPI_INFO "%s v%s\n", TPACPI_DESC, TPACPI_VERSION); - printk(TPACPI_INFO "%s\n", TPACPI_URL); - - printk(TPACPI_INFO "ThinkPad BIOS %s, EC %s\n", - (thinkpad_id.bios_version_str) ? - thinkpad_id.bios_version_str : "unknown", - (thinkpad_id.ec_version_str) ? - thinkpad_id.ec_version_str : "unknown"); - - BUG_ON(!thinkpad_id.vendor); - - if (thinkpad_id.model_str) - printk(TPACPI_INFO "%s %s, model %s\n", - (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ? - "IBM" : ((thinkpad_id.vendor == - PCI_VENDOR_ID_LENOVO) ? - "Lenovo" : "Unknown vendor"), - thinkpad_id.model_str, - (thinkpad_id.nummodel_str) ? - thinkpad_id.nummodel_str : "unknown"); - - tpacpi_check_outdated_fw(); - return 0; -} - static int thinkpad_acpi_driver_read(struct seq_file *m) { seq_printf(m, "driver:\t\t%s\n", TPACPI_DESC); @@ -8753,12 +8726,34 @@ static int __init probe_for_thinkpad(void) return 0; } +static void __init thinkpad_acpi_init_banner(void) +{ + printk(TPACPI_INFO "%s v%s\n", TPACPI_DESC, TPACPI_VERSION); + printk(TPACPI_INFO "%s\n", TPACPI_URL); + + printk(TPACPI_INFO "ThinkPad BIOS %s, EC %s\n", + (thinkpad_id.bios_version_str) ? + thinkpad_id.bios_version_str : "unknown", + (thinkpad_id.ec_version_str) ? + thinkpad_id.ec_version_str : "unknown"); + + BUG_ON(!thinkpad_id.vendor); + + if (thinkpad_id.model_str) + printk(TPACPI_INFO "%s %s, model %s\n", + (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ? + "IBM" : ((thinkpad_id.vendor == + PCI_VENDOR_ID_LENOVO) ? + "Lenovo" : "Unknown vendor"), + thinkpad_id.model_str, + (thinkpad_id.nummodel_str) ? + thinkpad_id.nummodel_str : "unknown"); +} /* Module init, exit, parameters */ static struct ibm_init_struct ibms_init[] __initdata = { { - .init = thinkpad_acpi_driver_init, .data = &thinkpad_acpi_driver_data, }, { @@ -9028,6 +9023,9 @@ static int __init thinkpad_acpi_module_init(void) /* Driver initialization */ + thinkpad_acpi_init_banner(); + tpacpi_check_outdated_fw(); + TPACPI_ACPIHANDLE_INIT(ecrd); TPACPI_ACPIHANDLE_INIT(ecwr); -- cgit v1.2.3 From 77775838bb76173d7a1ed28f75dfe388962aceca Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 16 May 2010 19:45:33 -0300 Subject: thinkpad-acpi: let other subdrivers know backlight level range Extract the backlight level range size detection from the brightness subdriver, and allow the other subdrivers access to that information. This also allows us to relocate some code to a more convenient place. The moved code was largerly unmodified, except for the return type of tpacpi_check_std_acpi_brightness_support(), which now is correctly marked as returning "unsigned int", and and two cosmetic fixes to make checkpatch.pl happy. Fixes for the NVRAM polling mode for the brightness hotkeys will need this. Signed-off-by: Henrique de Moraes Holschuh --- drivers/platform/x86/thinkpad_acpi.c | 251 +++++++++++++++++++---------------- 1 file changed, 140 insertions(+), 111 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index a768a69d58d2..b03bf5153b0f 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -304,8 +304,8 @@ static struct { u32 hotkey_tablet:1; u32 light:1; u32 light_status:1; - u32 bright_16levels:1; u32 bright_acpimode:1; + u32 bright_unkfw:1; u32 wan:1; u32 uwb:1; u32 fan_ctrl_status_undef:1; @@ -368,6 +368,9 @@ struct tpacpi_led_classdev { unsigned int led; }; +/* brightness level capabilities */ +static unsigned int bright_maxlvl; /* 0 = unknown */ + #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES static int dbg_wlswemul; static int tpacpi_wlsw_emulstate; @@ -1051,80 +1054,6 @@ static void tpacpi_disable_brightness_delay(void) "ACPI backlight control delay disabled\n"); } -static int __init tpacpi_query_bcl_levels(acpi_handle handle) -{ - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *obj; - int rc; - - if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) { - obj = (union acpi_object *)buffer.pointer; - if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { - printk(TPACPI_ERR "Unknown _BCL data, " - "please report this to %s\n", TPACPI_MAIL); - rc = 0; - } else { - rc = obj->package.count; - } - } else { - return 0; - } - - kfree(buffer.pointer); - return rc; -} - -static acpi_status __init tpacpi_acpi_walk_find_bcl(acpi_handle handle, - u32 lvl, void *context, void **rv) -{ - char name[ACPI_PATH_SEGMENT_LENGTH]; - struct acpi_buffer buffer = { sizeof(name), &name }; - - if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) && - !strncmp("_BCL", name, sizeof(name) - 1)) { - BUG_ON(!rv || !*rv); - **(int **)rv = tpacpi_query_bcl_levels(handle); - return AE_CTRL_TERMINATE; - } else { - return AE_OK; - } -} - -/* - * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map - */ -static int __init tpacpi_check_std_acpi_brightness_support(void) -{ - int status; - int bcl_levels = 0; - void *bcl_ptr = &bcl_levels; - - if (!vid_handle) { - TPACPI_ACPIHANDLE_INIT(vid); - } - if (!vid_handle) - return 0; - - /* - * Search for a _BCL method, and execute it. This is safe on all - * ThinkPads, and as a side-effect, _BCL will place a Lenovo Vista - * BIOS in ACPI backlight control mode. We do NOT have to care - * about calling the _BCL method in an enabled video device, any - * will do for our purposes. - */ - - status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3, - tpacpi_acpi_walk_find_bcl, NULL, NULL, - &bcl_ptr); - - if (ACPI_SUCCESS(status) && bcl_levels > 2) { - tp_features.bright_acpimode = 1; - return (bcl_levels - 2); - } - - return 0; -} - static void printk_deprecated_attribute(const char * const what, const char * const details) { @@ -3420,11 +3349,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) } /* Do not issue duplicate brightness change events to - * userspace */ - if (!tp_features.bright_acpimode) - /* update bright_acpimode... */ - tpacpi_check_std_acpi_brightness_support(); - + * userspace. tpacpi_detect_brightness_capabilities() must have + * been called before this point */ if (tp_features.bright_acpimode && acpi_video_backlight_support()) { printk(TPACPI_INFO "This ThinkPad has standard ACPI backlight " @@ -5989,7 +5915,7 @@ static unsigned int tpacpi_brightness_nvram_get(void) lnvram = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS) & TP_NVRAM_MASK_LEVEL_BRIGHTNESS) >> TP_NVRAM_POS_LEVEL_BRIGHTNESS; - lnvram &= (tp_features.bright_16levels) ? 0x0f : 0x07; + lnvram &= bright_maxlvl; return lnvram; } @@ -6098,8 +6024,7 @@ static int brightness_set(unsigned int value) { int res; - if (value > ((tp_features.bright_16levels)? 15 : 7) || - value < 0) + if (value > bright_maxlvl || value < 0) return -EINVAL; vdbg_printk(TPACPI_DBG_BRGHT, @@ -6174,6 +6099,80 @@ static struct backlight_ops ibm_backlight_data = { /* --------------------------------------------------------------------- */ +static int __init tpacpi_query_bcl_levels(acpi_handle handle) +{ + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *obj; + int rc; + + if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) { + obj = (union acpi_object *)buffer.pointer; + if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { + printk(TPACPI_ERR "Unknown _BCL data, " + "please report this to %s\n", TPACPI_MAIL); + rc = 0; + } else { + rc = obj->package.count; + } + } else { + return 0; + } + + kfree(buffer.pointer); + return rc; +} + +static acpi_status __init tpacpi_acpi_walk_find_bcl(acpi_handle handle, + u32 lvl, void *context, void **rv) +{ + char name[ACPI_PATH_SEGMENT_LENGTH]; + struct acpi_buffer buffer = { sizeof(name), &name }; + + if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) && + !strncmp("_BCL", name, sizeof(name) - 1)) { + BUG_ON(!rv || !*rv); + **(int **)rv = tpacpi_query_bcl_levels(handle); + return AE_CTRL_TERMINATE; + } else { + return AE_OK; + } +} + +/* + * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map + */ +static unsigned int __init tpacpi_check_std_acpi_brightness_support(void) +{ + int status; + int bcl_levels = 0; + void *bcl_ptr = &bcl_levels; + + if (!vid_handle) + TPACPI_ACPIHANDLE_INIT(vid); + + if (!vid_handle) + return 0; + + /* + * Search for a _BCL method, and execute it. This is safe on all + * ThinkPads, and as a side-effect, _BCL will place a Lenovo Vista + * BIOS in ACPI backlight control mode. We do NOT have to care + * about calling the _BCL method in an enabled video device, any + * will do for our purposes. + */ + + status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3, + tpacpi_acpi_walk_find_bcl, NULL, NULL, + &bcl_ptr); + + if (ACPI_SUCCESS(status) && bcl_levels > 2) { + tp_features.bright_acpimode = 1; + return bcl_levels - 2; + } + + return 0; +} + /* * These are only useful for models that have only one possibility * of GPU. If the BIOS model handles both ATI and Intel, don't use @@ -6204,6 +6203,47 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = { TPACPI_Q_IBM('7', '5', TPACPI_BRGHT_Q_NOEC), /* X41 Tablet */ }; +/* + * Returns < 0 for error, otherwise sets tp_features.bright_* + * and bright_maxlvl. + */ +static void __init tpacpi_detect_brightness_capabilities(void) +{ + unsigned int b; + + vdbg_printk(TPACPI_DBG_INIT, + "detecting firmware brightness interface capabilities\n"); + + /* we could run a quirks check here (same table used by + * brightness_init) if needed */ + + /* + * We always attempt to detect acpi support, so as to switch + * Lenovo Vista BIOS to ACPI brightness mode even if we are not + * going to publish a backlight interface + */ + b = tpacpi_check_std_acpi_brightness_support(); + switch (b) { + case 16: + bright_maxlvl = 15; + printk(TPACPI_INFO + "detected a 16-level brightness capable ThinkPad\n"); + break; + case 8: + case 0: + bright_maxlvl = 7; + printk(TPACPI_INFO + "detected a 8-level brightness capable ThinkPad\n"); + break; + default: + printk(TPACPI_ERR + "Unsupported brightness interface, " + "please contact %s\n", TPACPI_MAIL); + tp_features.bright_unkfw = 1; + bright_maxlvl = b - 1; + } +} + static int __init brightness_init(struct ibm_init_struct *iibm) { struct backlight_properties props; @@ -6217,14 +6257,13 @@ static int __init brightness_init(struct ibm_init_struct *iibm) quirks = tpacpi_check_quirks(brightness_quirk_table, ARRAY_SIZE(brightness_quirk_table)); - /* - * We always attempt to detect acpi support, so as to switch - * Lenovo Vista BIOS to ACPI brightness mode even if we are not - * going to publish a backlight interface - */ - b = tpacpi_check_std_acpi_brightness_support(); - if (b > 0) { + /* tpacpi_detect_brightness_capabilities() must have run already */ + + /* if it is unknown, we don't handle it: it wouldn't be safe */ + if (tp_features.bright_unkfw) + return 1; + if (tp_features.bright_acpimode) { if (acpi_video_backlight_support()) { if (brightness_enable > 1) { printk(TPACPI_NOTICE @@ -6253,15 +6292,6 @@ static int __init brightness_init(struct ibm_init_struct *iibm) return 1; } - if (b > 16) { - printk(TPACPI_ERR - "Unsupported brightness interface, " - "please contact %s\n", TPACPI_MAIL); - return 1; - } - if (b == 16) - tp_features.bright_16levels = 1; - /* * Check for module parameter bogosity, note that we * init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be @@ -6292,12 +6322,9 @@ static int __init brightness_init(struct ibm_init_struct *iibm) if (tpacpi_brightness_get_raw(&b) < 0) return 1; - if (tp_features.bright_16levels) - printk(TPACPI_INFO - "detected a 16-level brightness capable ThinkPad\n"); - memset(&props, 0, sizeof(struct backlight_properties)); - props.max_brightness = (tp_features.bright_16levels) ? 15 : 7; + props.max_brightness = bright_maxlvl; + props.brightness = b & TP_EC_BACKLIGHT_LVLMSK; ibm_backlight_device = backlight_device_register(TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL, &ibm_backlight_data, @@ -6320,7 +6347,6 @@ static int __init brightness_init(struct ibm_init_struct *iibm) "or not on your ThinkPad\n", TPACPI_MAIL); } - ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK; backlight_update_status(ibm_backlight_device); vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, @@ -6363,9 +6389,8 @@ static int brightness_read(struct seq_file *m) } else { seq_printf(m, "level:\t\t%d\n", level); seq_printf(m, "commands:\tup, down\n"); - seq_printf(m, "commands:\tlevel " - " ( is 0-%d)\n", - (tp_features.bright_16levels) ? 15 : 7); + seq_printf(m, "commands:\tlevel ( is 0-%d)\n", + bright_maxlvl); } return 0; @@ -6376,7 +6401,6 @@ static int brightness_write(char *buf) int level; int rc; char *cmd; - int max_level = (tp_features.bright_16levels) ? 15 : 7; level = brightness_get(NULL); if (level < 0) @@ -6384,13 +6408,13 @@ static int brightness_write(char *buf) while ((cmd = next_cmd(&buf))) { if (strlencmp(cmd, "up") == 0) { - if (level < max_level) + if (level < bright_maxlvl) level++; } else if (strlencmp(cmd, "down") == 0) { if (level > 0) level--; } else if (sscanf(cmd, "level %d", &level) == 1 && - level >= 0 && level <= max_level) { + level >= 0 && level <= bright_maxlvl) { /* new level set */ } else return -EINVAL; @@ -9130,6 +9154,11 @@ static int __init thinkpad_acpi_module_init(void) tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION; tpacpi_inputdev->dev.parent = &tpacpi_pdev->dev; } + + /* Init subdriver dependencies */ + tpacpi_detect_brightness_capabilities(); + + /* Init subdrivers */ for (i = 0; i < ARRAY_SIZE(ibms_init); i++) { ret = ibm_init(&ibms_init[i]); if (ret >= 0 && *ibms_init[i].param) -- cgit v1.2.3 From 289990228155cbc58a35c1b266af00f387caa595 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 16 May 2010 19:45:36 -0300 Subject: thinkpad-acpi: fix brightness hotkey poll handling Handle multiple brightness hotkey presses between two polling cycles. Signed-off-by: Henrique de Moraes Holschuh --- drivers/platform/x86/thinkpad_acpi.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index b03bf5153b0f..fa412a43f5e0 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -2340,6 +2340,21 @@ static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn, } } + void issue_brightnesschange(const unsigned int oldbrt, + const unsigned int newbrt) + { + unsigned int i = oldbrt; + + while (i > newbrt) { + TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND); + i--; + } + while (i < newbrt) { + TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME); + i++; + } + } + TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_THINKPAD, thinkpad_toggle); TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNSPACE, zoom_toggle); TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF7, display_toggle); @@ -2394,19 +2409,16 @@ static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn, } /* handle brightness */ - if (oldn->brightness_toggle != newn->brightness_toggle) { - if (oldn->brightness_level < newn->brightness_level) { - TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME); - } else if (oldn->brightness_level > newn->brightness_level) { + if (oldn->brightness_level != newn->brightness_level) { + issue_brightnesschange(oldn->brightness_level, + newn->brightness_level); + } else if (oldn->brightness_toggle != newn->brightness_toggle) { + /* repeated key presses that didn't change state */ + if (newn->brightness_level == 0) TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND); - } else { - /* repeated key presses that didn't change state */ - if (newn->brightness_level != 0) { - TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME); - } else { - TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND); - } - } + else if (newn->brightness_level >= bright_maxlvl + && !tp_features.bright_unkfw) + TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME); } #undef TPACPI_COMPARE_KEY -- cgit v1.2.3 From 38e11cdec90f1dd7355db4aed8a1857258e99485 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 16 May 2010 19:45:40 -0300 Subject: thinkpad-acpi: disclose usertask for ALSA callbacks Disclose the user task doing ALSA access when requested by the debug bitmask. Signed-off-by: Henrique de Moraes Holschuh --- drivers/platform/x86/thinkpad_acpi.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index fa412a43f5e0..b03cb3e04582 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -6740,6 +6740,8 @@ static int volume_alsa_vol_get(struct snd_kcontrol *kcontrol, static int volume_alsa_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + tpacpi_disclose_usertask("ALSA", "set volume to %ld\n", + ucontrol->value.integer.value[0]); return volume_alsa_set_volume(ucontrol->value.integer.value[0]); } @@ -6763,6 +6765,9 @@ static int volume_alsa_mute_get(struct snd_kcontrol *kcontrol, static int volume_alsa_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { + tpacpi_disclose_usertask("ALSA", "%smute\n", + ucontrol->value.integer.value[0] ? + "un" : ""); return volume_alsa_set_mute(!ucontrol->value.integer.value[0]); } -- cgit v1.2.3 From 437e470c4ca818c97426afa3a67fbd7e34cffe00 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 16 May 2010 19:45:43 -0300 Subject: thinkpad-acpi: detect EC node using its HID (v2) Use the EC HID (PNP0C09) to locate its main node, instead of a static list. Suggested-by: Matthew Garrett Signed-off-by: Henrique de Moraes Holschuh Cc: Matthew Garrett --- drivers/platform/x86/thinkpad_acpi.c | 53 ++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index b03cb3e04582..877a7802e830 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -129,6 +129,7 @@ enum { /* ACPI HIDs */ #define TPACPI_ACPI_HKEY_HID "IBM0068" +#define TPACPI_ACPI_EC_HID "PNP0C09" /* Input IDs */ #define TPACPI_HKEY_INPUT_PRODUCT 0x5054 /* "TP" */ @@ -511,6 +512,7 @@ static inline bool __pure __init tpacpi_is_ibm(void) */ static acpi_handle root_handle; +static acpi_handle ec_handle; #define TPACPI_HANDLE(object, parent, paths...) \ static acpi_handle object##_handle; \ @@ -518,16 +520,6 @@ static acpi_handle root_handle; static char *object##_path; \ static char *object##_paths[] = { paths } -TPACPI_HANDLE(ec, root, "\\_SB.PCI0.ISA.EC0", /* 240, 240x */ - "\\_SB.PCI.ISA.EC", /* 570 */ - "\\_SB.PCI0.ISA0.EC0", /* 600e/x, 770e, 770x */ - "\\_SB.PCI0.ISA.EC", /* A21e, A2xm/p, T20-22, X20-21 */ - "\\_SB.PCI0.AD4S.EC0", /* i1400, R30 */ - "\\_SB.PCI0.ICH3.EC0", /* R31 */ - "\\_SB.PCI0.LPC0.EC", /* X100e and a few others */ - "\\_SB.PCI0.LPC.EC", /* all others */ - ); - TPACPI_HANDLE(ecrd, ec, "ECRD"); /* 570 */ TPACPI_HANDLE(ecwr, ec, "ECWR"); /* 570 */ @@ -708,6 +700,43 @@ static void drv_acpi_handle_init(char *name, *handle = NULL; } +static acpi_status __init tpacpi_acpi_handle_locate_callback(acpi_handle handle, + u32 level, void *context, void **return_value) +{ + *(acpi_handle *)return_value = handle; + + return AE_CTRL_TERMINATE; +} + +static void __init tpacpi_acpi_handle_locate(const char *name, + const char *hid, + acpi_handle *handle) +{ + acpi_status status; + acpi_handle device_found; + + BUG_ON(!name || !hid || !handle); + vdbg_printk(TPACPI_DBG_INIT, + "trying to locate ACPI handle for %s, using HID %s\n", + name, hid); + + memset(&device_found, 0, sizeof(device_found)); + status = acpi_get_devices(hid, tpacpi_acpi_handle_locate_callback, + (void *)name, &device_found); + + *handle = NULL; + + if (ACPI_SUCCESS(status)) { + *handle = device_found; + dbg_printk(TPACPI_DBG_INIT, + "Found ACPI handle for %s\n", name); + } else { + vdbg_printk(TPACPI_DBG_INIT, + "Could not locate an ACPI handle for %s: %s\n", + name, acpi_format_exception(status)); + } +} + static void dispatch_acpi_notify(acpi_handle handle, u32 event, void *data) { struct ibm_struct *ibm = data; @@ -8752,8 +8781,8 @@ static int __init probe_for_thinkpad(void) (thinkpad_id.ec_model != 0) || tpacpi_is_fw_known(); - /* ec is required because many other handles are relative to it */ - TPACPI_ACPIHANDLE_INIT(ec); + /* The EC handler is required */ + tpacpi_acpi_handle_locate("ec", TPACPI_ACPI_EC_HID, &ec_handle); if (!ec_handle) { if (is_thinkpad) printk(TPACPI_ERR -- cgit v1.2.3 From 263f4a30e4f1dc5385650738c1dcf3728036ecc4 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 16 May 2010 19:45:45 -0300 Subject: thinkpad-acpi: acpi_evalf fixes Use acpi_format_exception() in acpi_evalf() instead of logging numeric errors. Also, when ACPICA returns an error, we should not be touching the return object, as it is invalid. In debug mode, acpi_evalf() callers would printk the returned crap (but fortunately, not use it). Signed-off-by: Henrique de Moraes Holschuh --- drivers/platform/x86/thinkpad_acpi.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 877a7802e830..da3a70b280f2 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -605,9 +605,10 @@ static int acpi_evalf(acpi_handle handle, switch (res_type) { case 'd': /* int */ - if (res) + success = (status == AE_OK && + out_obj.type == ACPI_TYPE_INTEGER); + if (success && res) *(int *)res = out_obj.integer.value; - success = status == AE_OK && out_obj.type == ACPI_TYPE_INTEGER; break; case 'v': /* void */ success = status == AE_OK; @@ -620,8 +621,8 @@ static int acpi_evalf(acpi_handle handle, } if (!success && !quiet) - printk(TPACPI_ERR "acpi_evalf(%s, %s, ...) failed: %d\n", - method, fmt0, status); + printk(TPACPI_ERR "acpi_evalf(%s, %s, ...) failed: %s\n", + method, fmt0, acpi_format_exception(status)); return success; } -- cgit v1.2.3 From 72f19921217c2267adc65cbe69c63da970578a14 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 16 May 2010 19:45:48 -0300 Subject: thinkpad-acpi: explain errors from acpi_install_notify_handler Log more human-friendly errors instead of numeric values when setup_acpi_notify() fails to install a notification handler. Signed-off-by: Henrique de Moraes Holschuh --- drivers/platform/x86/thinkpad_acpi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index da3a70b280f2..a39f159d4f2f 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -785,8 +785,8 @@ static int __init setup_acpi_notify(struct ibm_struct *ibm) "handling %s events\n", ibm->name); } else { printk(TPACPI_ERR - "acpi_install_notify_handler(%s) failed: %d\n", - ibm->name, status); + "acpi_install_notify_handler(%s) failed: %s\n", + ibm->name, acpi_format_exception(status)); } return -ENODEV; } -- cgit v1.2.3 From 2cbb5c8f5533facb606adc5986ce40da2e987d6d Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 16 May 2010 19:45:50 -0300 Subject: thinkpad-acpi: don't depend on led_path for led firmware type (v2) Don't depend on the contents of led_path to know which LED interface the firmware wants. This removes the only user of *_path for the thinkpad-acpi ACPI handlers, which will simplify future code. Signed-off-by: Henrique de Moraes Holschuh --- drivers/platform/x86/thinkpad_acpi.c | 47 +++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index a39f159d4f2f..29ad27346443 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -5009,11 +5009,7 @@ enum { /* For TPACPI_LED_OLD */ static enum led_access_mode led_supported; -TPACPI_HANDLE(led, ec, "SLED", /* 570 */ - "SYSL", /* 600e/x, 770e, 770x, A21e, A2xm/p, */ - /* T20-22, X20-21 */ - "LED", /* all others */ - ); /* R30, R31 */ +static acpi_handle led_handle; #define TPACPI_LED_NUMLEDS 16 static struct tpacpi_led_classdev *tpacpi_leds; @@ -5273,6 +5269,32 @@ static const struct tpacpi_quirk led_useful_qtable[] __initconst = { #undef TPACPI_LEDQ_IBM #undef TPACPI_LEDQ_LNV +static enum led_access_mode __init led_init_detect_mode(void) +{ + acpi_status status; + + if (tpacpi_is_ibm()) { + /* 570 */ + status = acpi_get_handle(ec_handle, "SLED", &led_handle); + if (ACPI_SUCCESS(status)) + return TPACPI_LED_570; + + /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */ + status = acpi_get_handle(ec_handle, "SYSL", &led_handle); + if (ACPI_SUCCESS(status)) + return TPACPI_LED_OLD; + } + + /* most others */ + status = acpi_get_handle(ec_handle, "LED", &led_handle); + if (ACPI_SUCCESS(status)) + return TPACPI_LED_NEW; + + /* R30, R31, and unknown firmwares */ + led_handle = NULL; + return TPACPI_LED_NONE; +} + static int __init led_init(struct ibm_init_struct *iibm) { unsigned int i; @@ -5281,20 +5303,7 @@ static int __init led_init(struct ibm_init_struct *iibm) vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n"); - TPACPI_ACPIHANDLE_INIT(led); - - if (!led_handle) - /* led not supported on R30, R31 */ - led_supported = TPACPI_LED_NONE; - else if (tpacpi_is_ibm() && strlencmp(led_path, "SLED") == 0) - /* 570 */ - led_supported = TPACPI_LED_570; - else if (tpacpi_is_ibm() && strlencmp(led_path, "SYSL") == 0) - /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */ - led_supported = TPACPI_LED_OLD; - else - /* all others */ - led_supported = TPACPI_LED_NEW; + led_supported = led_init_detect_mode(); vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n", str_supported(led_supported), led_supported); -- cgit v1.2.3 From ef07a5abadfcb2470fc9cbfbee0cb41076b4ba9b Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 16 May 2010 19:45:54 -0300 Subject: thinkpad-acpi: clean up ACPI handles handling 1. Remove _path, as its only user was already removed in a previous commit 2. Move all handle initialization, as well as _parent and _paths to __init.* sections. This reduces the driver's runtime footprint nicely. Signed-off-by: Henrique de Moraes Holschuh --- drivers/platform/x86/thinkpad_acpi.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 29ad27346443..b3bfce953838 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -516,9 +516,9 @@ static acpi_handle ec_handle; #define TPACPI_HANDLE(object, parent, paths...) \ static acpi_handle object##_handle; \ - static acpi_handle *object##_parent = &parent##_handle; \ - static char *object##_path; \ - static char *object##_paths[] = { paths } + static const acpi_handle *object##_parent __initdata = \ + &parent##_handle; \ + static char *object##_paths[] __initdata = { paths } TPACPI_HANDLE(ecrd, ec, "ECRD"); /* 570 */ TPACPI_HANDLE(ecwr, ec, "ECWR"); /* 570 */ @@ -673,11 +673,11 @@ static int issue_thinkpad_cmos_command(int cmos_cmd) #define TPACPI_ACPIHANDLE_INIT(object) \ drv_acpi_handle_init(#object, &object##_handle, *object##_parent, \ - object##_paths, ARRAY_SIZE(object##_paths), &object##_path) + object##_paths, ARRAY_SIZE(object##_paths)) -static void drv_acpi_handle_init(char *name, - acpi_handle *handle, acpi_handle parent, - char **paths, int num_paths, char **path) +static void __init drv_acpi_handle_init(const char *name, + acpi_handle *handle, const acpi_handle parent, + char **paths, const int num_paths) { int i; acpi_status status; @@ -688,10 +688,9 @@ static void drv_acpi_handle_init(char *name, for (i = 0; i < num_paths; i++) { status = acpi_get_handle(parent, paths[i], handle); if (ACPI_SUCCESS(status)) { - *path = paths[i]; dbg_printk(TPACPI_DBG_INIT, "Found ACPI handle %s for %s\n", - *path, name); + paths[i], name); return; } } -- cgit v1.2.3 From 7d9745cf239ca98cf1f694bff4765a276b05ee68 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 16 May 2010 19:45:57 -0300 Subject: thinkpad-acpi: document backlight level writeback at driver init Document this, it is no fun to try to second guess why this sort of stuff is in place years after it was added... Signed-off-by: Henrique de Moraes Holschuh --- drivers/platform/x86/thinkpad_acpi.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index b3bfce953838..4bdb13796e24 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -6397,6 +6397,10 @@ static int __init brightness_init(struct ibm_init_struct *iibm) "or not on your ThinkPad\n", TPACPI_MAIL); } + /* Added by mistake in early 2007. Probably useless, but it could + * be working around some unknown firmware problem where the value + * read at startup doesn't match the real hardware state... so leave + * it in place just in case */ backlight_update_status(ibm_backlight_device); vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, -- cgit v1.2.3 From 16ef8def80ea97c3cacdcaa765bdf62b2d94f86d Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 27 Apr 2010 00:24:00 +0200 Subject: dvb: Push down BKL into ioctl functions This requires changing all users of dvb_usercopy to omit the inode argument. Signed-off-by: Arnd Bergmann Signed-off-by: Frederic Weisbecker --- drivers/media/dvb/dvb-core/dmxdev.c | 31 ++++++++++++++++++++--------- drivers/media/dvb/dvb-core/dvb_ca_en50221.c | 17 +++++++++++----- drivers/media/dvb/dvb-core/dvb_frontend.c | 30 ++++++++++++++-------------- drivers/media/dvb/dvb-core/dvb_net.c | 15 ++++++++++---- drivers/media/dvb/dvb-core/dvbdev.c | 17 ++++++++++------ drivers/media/dvb/dvb-core/dvbdev.h | 11 ++++------ drivers/media/dvb/firewire/firedtv-ci.c | 5 ++--- drivers/media/dvb/ttpci/av7110.c | 4 ++-- drivers/media/dvb/ttpci/av7110_av.c | 8 ++++---- drivers/media/dvb/ttpci/av7110_ca.c | 5 ++--- 10 files changed, 85 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index 9ddc57909d49..425862ffb285 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/drivers/media/dvb/dvb-core/dmxdev.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -963,7 +964,7 @@ dvb_demux_read(struct file *file, char __user *buf, size_t count, return ret; } -static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, +static int dvb_demux_do_ioctl(struct file *file, unsigned int cmd, void *parg) { struct dmxdev_filter *dmxdevfilter = file->private_data; @@ -1084,10 +1085,16 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, return ret; } -static int dvb_demux_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long dvb_demux_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { - return dvb_usercopy(inode, file, cmd, arg, dvb_demux_do_ioctl); + int ret; + + lock_kernel(); + ret = dvb_usercopy(file, cmd, arg, dvb_demux_do_ioctl); + unlock_kernel(); + + return ret; } static unsigned int dvb_demux_poll(struct file *file, poll_table *wait) @@ -1139,7 +1146,7 @@ static int dvb_demux_release(struct inode *inode, struct file *file) static const struct file_operations dvb_demux_fops = { .owner = THIS_MODULE, .read = dvb_demux_read, - .ioctl = dvb_demux_ioctl, + .unlocked_ioctl = dvb_demux_ioctl, .open = dvb_demux_open, .release = dvb_demux_release, .poll = dvb_demux_poll, @@ -1152,7 +1159,7 @@ static struct dvb_device dvbdev_demux = { .fops = &dvb_demux_fops }; -static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file, +static int dvb_dvr_do_ioctl(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; @@ -1176,10 +1183,16 @@ static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file, return ret; } -static int dvb_dvr_ioctl(struct inode *inode, struct file *file, +static long dvb_dvr_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - return dvb_usercopy(inode, file, cmd, arg, dvb_dvr_do_ioctl); + int ret; + + lock_kernel(); + ret = dvb_usercopy(file, cmd, arg, dvb_dvr_do_ioctl); + unlock_kernel(); + + return ret; } static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait) @@ -1208,7 +1221,7 @@ static const struct file_operations dvb_dvr_fops = { .owner = THIS_MODULE, .read = dvb_dvr_read, .write = dvb_dvr_write, - .ioctl = dvb_dvr_ioctl, + .unlocked_ioctl = dvb_dvr_ioctl, .open = dvb_dvr_open, .release = dvb_dvr_release, .poll = dvb_dvr_poll, diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c index cb22da53bfb0..ef259a0718ac 100644 --- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "dvb_ca_en50221.h" @@ -1181,7 +1182,7 @@ static int dvb_ca_en50221_thread(void *data) * * @return 0 on success, <0 on error. */ -static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file, +static int dvb_ca_en50221_io_do_ioctl(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; @@ -1255,10 +1256,16 @@ static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file, * * @return 0 on success, <0 on error. */ -static int dvb_ca_en50221_io_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long dvb_ca_en50221_io_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) { - return dvb_usercopy(inode, file, cmd, arg, dvb_ca_en50221_io_do_ioctl); + int ret; + + lock_kernel(); + ret = dvb_usercopy(file, cmd, arg, dvb_ca_en50221_io_do_ioctl); + unlock_kernel(); + + return ret; } @@ -1611,7 +1618,7 @@ static const struct file_operations dvb_ca_fops = { .owner = THIS_MODULE, .read = dvb_ca_en50221_io_read, .write = dvb_ca_en50221_io_write, - .ioctl = dvb_ca_en50221_io_ioctl, + .unlocked_ioctl = dvb_ca_en50221_io_ioctl, .open = dvb_ca_en50221_io_open, .release = dvb_ca_en50221_io_release, .poll = dvb_ca_en50221_io_poll, diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 55ea260572bf..5450d1f7a538 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -1188,14 +1189,14 @@ static void dtv_property_cache_submit(struct dvb_frontend *fe) } } -static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, +static int dvb_frontend_ioctl_legacy(struct file *file, unsigned int cmd, void *parg); -static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, +static int dvb_frontend_ioctl_properties(struct file *file, unsigned int cmd, void *parg); static int dtv_property_process_get(struct dvb_frontend *fe, struct dtv_property *tvp, - struct inode *inode, struct file *file) + struct file *file) { int r = 0; @@ -1328,7 +1329,6 @@ static int dtv_property_process_get(struct dvb_frontend *fe, static int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp, - struct inode *inode, struct file *file) { int r = 0; @@ -1359,7 +1359,7 @@ static int dtv_property_process_set(struct dvb_frontend *fe, dprintk("%s() Finalised property cache\n", __func__); dtv_property_cache_submit(fe); - r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND, + r |= dvb_frontend_ioctl_legacy(file, FE_SET_FRONTEND, &fepriv->parameters); break; case DTV_FREQUENCY: @@ -1391,12 +1391,12 @@ static int dtv_property_process_set(struct dvb_frontend *fe, break; case DTV_VOLTAGE: fe->dtv_property_cache.voltage = tvp->u.data; - r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_VOLTAGE, + r = dvb_frontend_ioctl_legacy(file, FE_SET_VOLTAGE, (void *)fe->dtv_property_cache.voltage); break; case DTV_TONE: fe->dtv_property_cache.sectone = tvp->u.data; - r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_TONE, + r = dvb_frontend_ioctl_legacy(file, FE_SET_TONE, (void *)fe->dtv_property_cache.sectone); break; case DTV_CODE_RATE_HP: @@ -1480,7 +1480,7 @@ static int dtv_property_process_set(struct dvb_frontend *fe, return r; } -static int dvb_frontend_ioctl(struct inode *inode, struct file *file, +static int dvb_frontend_ioctl(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; @@ -1502,17 +1502,17 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, return -ERESTARTSYS; if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY)) - err = dvb_frontend_ioctl_properties(inode, file, cmd, parg); + err = dvb_frontend_ioctl_properties(file, cmd, parg); else { fe->dtv_property_cache.state = DTV_UNDEFINED; - err = dvb_frontend_ioctl_legacy(inode, file, cmd, parg); + err = dvb_frontend_ioctl_legacy(file, cmd, parg); } up(&fepriv->sem); return err; } -static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, +static int dvb_frontend_ioctl_properties(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; @@ -1548,7 +1548,7 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, } for (i = 0; i < tvps->num; i++) { - (tvp + i)->result = dtv_property_process_set(fe, tvp + i, inode, file); + (tvp + i)->result = dtv_property_process_set(fe, tvp + i, file); err |= (tvp + i)->result; } @@ -1580,7 +1580,7 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, } for (i = 0; i < tvps->num; i++) { - (tvp + i)->result = dtv_property_process_get(fe, tvp + i, inode, file); + (tvp + i)->result = dtv_property_process_get(fe, tvp + i, file); err |= (tvp + i)->result; } @@ -1597,7 +1597,7 @@ out: return err; } -static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, +static int dvb_frontend_ioctl_legacy(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; @@ -2022,7 +2022,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) static const struct file_operations dvb_frontend_fops = { .owner = THIS_MODULE, - .ioctl = dvb_generic_ioctl, + .unlocked_ioctl = dvb_generic_ioctl, .poll = dvb_frontend_poll, .open = dvb_frontend_open, .release = dvb_frontend_release diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 441c0642b30a..a96eee38d60c 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -1333,7 +1334,7 @@ static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned long num) return 0; } -static int dvb_net_do_ioctl(struct inode *inode, struct file *file, +static int dvb_net_do_ioctl(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; @@ -1435,10 +1436,16 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file, return 0; } -static int dvb_net_ioctl(struct inode *inode, struct file *file, +static long dvb_net_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - return dvb_usercopy(inode, file, cmd, arg, dvb_net_do_ioctl); + int ret; + + lock_kernel(); + ret = dvb_usercopy(file, cmd, arg, dvb_net_do_ioctl); + unlock_kernel(); + + return ret; } static int dvb_net_close(struct inode *inode, struct file *file) @@ -1459,7 +1466,7 @@ static int dvb_net_close(struct inode *inode, struct file *file) static const struct file_operations dvb_net_fops = { .owner = THIS_MODULE, - .ioctl = dvb_net_ioctl, + .unlocked_ioctl = dvb_net_ioctl, .open = dvb_generic_open, .release = dvb_net_close, }; diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 94159b90f733..b915c39d782f 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c @@ -154,10 +154,11 @@ int dvb_generic_release(struct inode *inode, struct file *file) EXPORT_SYMBOL(dvb_generic_release); -int dvb_generic_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +long dvb_generic_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) { struct dvb_device *dvbdev = file->private_data; + int ret; if (!dvbdev) return -ENODEV; @@ -165,7 +166,11 @@ int dvb_generic_ioctl(struct inode *inode, struct file *file, if (!dvbdev->kernel_ioctl) return -EINVAL; - return dvb_usercopy (inode, file, cmd, arg, dvbdev->kernel_ioctl); + lock_kernel(); + ret = dvb_usercopy(file, cmd, arg, dvbdev->kernel_ioctl); + unlock_kernel(); + + return ret; } EXPORT_SYMBOL(dvb_generic_ioctl); @@ -377,9 +382,9 @@ EXPORT_SYMBOL(dvb_unregister_adapter); define this as video_usercopy(). this will introduce a dependecy to the v4l "videodev.o" module, which is unnecessary for some cards (ie. the budget dvb-cards don't need the v4l module...) */ -int dvb_usercopy(struct inode *inode, struct file *file, +int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg, - int (*func)(struct inode *inode, struct file *file, + int (*func)(struct file *file, unsigned int cmd, void *arg)) { char sbuf[128]; @@ -416,7 +421,7 @@ int dvb_usercopy(struct inode *inode, struct file *file, } /* call driver */ - if ((err = func(inode, file, cmd, parg)) == -ENOIOCTLCMD) + if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD) err = -EINVAL; if (err < 0) diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h index f7b499d4a3c0..fcc6ae98745e 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.h +++ b/drivers/media/dvb/dvb-core/dvbdev.h @@ -116,8 +116,7 @@ struct dvb_device { wait_queue_head_t wait_queue; /* don't really need those !? -- FIXME: use video_usercopy */ - int (*kernel_ioctl)(struct inode *inode, struct file *file, - unsigned int cmd, void *arg); + int (*kernel_ioctl)(struct file *file, unsigned int cmd, void *arg); void *priv; }; @@ -138,17 +137,15 @@ extern void dvb_unregister_device (struct dvb_device *dvbdev); extern int dvb_generic_open (struct inode *inode, struct file *file); extern int dvb_generic_release (struct inode *inode, struct file *file); -extern int dvb_generic_ioctl (struct inode *inode, struct file *file, +extern long dvb_generic_ioctl (struct file *file, unsigned int cmd, unsigned long arg); /* we don't mess with video_usercopy() any more, we simply define out own dvb_usercopy(), which will hopefully become generic_usercopy() someday... */ -extern int dvb_usercopy(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg, - int (*func)(struct inode *inode, struct file *file, - unsigned int cmd, void *arg)); +extern int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg, + int (*func)(struct file *file, unsigned int cmd, void *arg)); /** generic DVB attach function. */ #ifdef CONFIG_MEDIA_ATTACH diff --git a/drivers/media/dvb/firewire/firedtv-ci.c b/drivers/media/dvb/firewire/firedtv-ci.c index 853e04b7cb36..d3c2cf60de76 100644 --- a/drivers/media/dvb/firewire/firedtv-ci.c +++ b/drivers/media/dvb/firewire/firedtv-ci.c @@ -175,8 +175,7 @@ static int fdtv_ca_send_msg(struct firedtv *fdtv, void *arg) return err; } -static int fdtv_ca_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) +static int fdtv_ca_ioctl(struct file *file, unsigned int cmd, void *arg) { struct dvb_device *dvbdev = file->private_data; struct firedtv *fdtv = dvbdev->priv; @@ -217,7 +216,7 @@ static unsigned int fdtv_ca_io_poll(struct file *file, poll_table *wait) static const struct file_operations fdtv_ca_fops = { .owner = THIS_MODULE, - .ioctl = dvb_generic_ioctl, + .unlocked_ioctl = dvb_generic_ioctl, .open = dvb_generic_open, .release = dvb_generic_release, .poll = fdtv_ca_io_poll, diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 38915591c6e5..a6be529eec5c 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c @@ -708,7 +708,7 @@ static void gpioirq(unsigned long cookie) #ifdef CONFIG_DVB_AV7110_OSD -static int dvb_osd_ioctl(struct inode *inode, struct file *file, +static int dvb_osd_ioctl(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; @@ -727,7 +727,7 @@ static int dvb_osd_ioctl(struct inode *inode, struct file *file, static const struct file_operations dvb_osd_fops = { .owner = THIS_MODULE, - .ioctl = dvb_generic_ioctl, + .unlocked_ioctl = dvb_generic_ioctl, .open = dvb_generic_open, .release = dvb_generic_release, }; diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index 53884814161c..13efba942dac 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c @@ -1089,7 +1089,7 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len } -static int dvb_video_ioctl(struct inode *inode, struct file *file, +static int dvb_video_ioctl(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; @@ -1297,7 +1297,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, return ret; } -static int dvb_audio_ioctl(struct inode *inode, struct file *file, +static int dvb_audio_ioctl(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; @@ -1517,7 +1517,7 @@ static int dvb_audio_release(struct inode *inode, struct file *file) static const struct file_operations dvb_video_fops = { .owner = THIS_MODULE, .write = dvb_video_write, - .ioctl = dvb_generic_ioctl, + .unlocked_ioctl = dvb_generic_ioctl, .open = dvb_video_open, .release = dvb_video_release, .poll = dvb_video_poll, @@ -1535,7 +1535,7 @@ static struct dvb_device dvbdev_video = { static const struct file_operations dvb_audio_fops = { .owner = THIS_MODULE, .write = dvb_audio_write, - .ioctl = dvb_generic_ioctl, + .unlocked_ioctl = dvb_generic_ioctl, .open = dvb_audio_open, .release = dvb_audio_release, .poll = dvb_audio_poll, diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c index ac7779c45c5b..4eba35a018e3 100644 --- a/drivers/media/dvb/ttpci/av7110_ca.c +++ b/drivers/media/dvb/ttpci/av7110_ca.c @@ -248,8 +248,7 @@ static unsigned int dvb_ca_poll (struct file *file, poll_table *wait) return mask; } -static int dvb_ca_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) +static int dvb_ca_ioctl(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; struct av7110 *av7110 = dvbdev->priv; @@ -350,7 +349,7 @@ static const struct file_operations dvb_ca_fops = { .owner = THIS_MODULE, .read = dvb_ca_read, .write = dvb_ca_write, - .ioctl = dvb_generic_ioctl, + .unlocked_ioctl = dvb_generic_ioctl, .open = dvb_ca_open, .release = dvb_generic_release, .poll = dvb_ca_poll, -- cgit v1.2.3 From f4927c45beda9a70e5c3bda0bd9f12b4f713c00b Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 27 Apr 2010 00:24:01 +0200 Subject: scsi: Push down BKL into ioctl functions Push down the bkl into ioctl functions on the scsi layer. [jkacur: Forward declaration missing ';'. Conflicting declaraction in megaraid.h changed Fixed missing inodes declarations] Signed-off-by: Arnd Bergmann Signed-off-by: John Kacur Signed-off-by: Frederic Weisbecker --- drivers/scsi/3w-9xxx.c | 10 +++++++--- drivers/scsi/3w-sas.c | 8 ++++++-- drivers/scsi/3w-xxxx.c | 11 ++++++++--- drivers/scsi/aacraid/linit.c | 11 ++++++++--- drivers/scsi/dpt_i2o.c | 20 +++++++++++++++++--- drivers/scsi/gdth.c | 20 +++++++++++++++----- drivers/scsi/megaraid.c | 20 +++++++++++++++++--- drivers/scsi/megaraid.h | 3 +-- drivers/scsi/megaraid/megaraid_mm.c | 22 +++++++++++++++++----- drivers/scsi/osst.c | 14 ++++++++++---- drivers/scsi/sg.c | 17 ++++++++++++++--- 11 files changed, 120 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index e9788f55ab13..4f74850560fe 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -123,7 +123,7 @@ static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_H static int twa_aen_read_queue(TW_Device_Extension *tw_dev, int request_id); static char *twa_aen_severity_lookup(unsigned char severity_code); static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id); -static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +static long twa_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg); static int twa_chrdev_open(struct inode *inode, struct file *file); static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_sense, int print_host); static void twa_free_request_id(TW_Device_Extension *tw_dev,int request_id); @@ -218,7 +218,7 @@ static struct device_attribute *twa_host_attrs[] = { /* File operations struct for character device */ static const struct file_operations twa_fops = { .owner = THIS_MODULE, - .ioctl = twa_chrdev_ioctl, + .unlocked_ioctl = twa_chrdev_ioctl, .open = twa_chrdev_open, .release = NULL }; @@ -635,8 +635,9 @@ out: } /* End twa_check_srl() */ /* This function handles ioctl for the character device */ -static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static long twa_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { + struct inode *inode = file->f_path.dentry->d_inode; long timeout; unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0; dma_addr_t dma_handle; @@ -655,6 +656,8 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int int retval = TW_IOCTL_ERROR_OS_EFAULT; void __user *argp = (void __user *)arg; + lock_kernel(); + /* Only let one of these through at a time */ if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) { retval = TW_IOCTL_ERROR_OS_EINTR; @@ -874,6 +877,7 @@ out3: out2: mutex_unlock(&tw_dev->ioctl_lock); out: + unlock_kernel(); return retval; } /* End twa_chrdev_ioctl() */ diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c index 54c5ffb1eaa1..8af380951f17 100644 --- a/drivers/scsi/3w-sas.c +++ b/drivers/scsi/3w-sas.c @@ -750,19 +750,22 @@ static void twl_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_comm /* This function handles ioctl for the character device This interface is used by smartmontools open source software */ -static int twl_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static long twl_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { long timeout; unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0; dma_addr_t dma_handle; int request_id = 0; TW_Ioctl_Driver_Command driver_command; + struct inode *inode = file->f_dentry->d_inode; TW_Ioctl_Buf_Apache *tw_ioctl; TW_Command_Full *full_command_packet; TW_Device_Extension *tw_dev = twl_device_extension_list[iminor(inode)]; int retval = -EFAULT; void __user *argp = (void __user *)arg; + lock_kernel(); + /* Only let one of these through at a time */ if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) { retval = -EINTR; @@ -858,6 +861,7 @@ out3: out2: mutex_unlock(&tw_dev->ioctl_lock); out: + unlock_kernel(); return retval; } /* End twl_chrdev_ioctl() */ @@ -884,7 +888,7 @@ out: /* File operations struct for character device */ static const struct file_operations twl_fops = { .owner = THIS_MODULE, - .ioctl = twl_chrdev_ioctl, + .unlocked_ioctl = twl_chrdev_ioctl, .open = twl_chrdev_open, .release = NULL }; diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index 5faf903ca8c8..608f3b28b25e 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -880,7 +880,7 @@ static int tw_allocate_memory(TW_Device_Extension *tw_dev, int size, int which) } /* End tw_allocate_memory() */ /* This function handles ioctl for the character device */ -static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static long tw_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int request_id; dma_addr_t dma_handle; @@ -888,6 +888,7 @@ static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int unsigned long flags; unsigned int data_buffer_length = 0; unsigned long data_buffer_length_adjusted = 0; + struct inode *inode = file->f_dentry->d_inode; unsigned long *cpu_addr; long timeout; TW_New_Ioctl *tw_ioctl; @@ -898,9 +899,12 @@ static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl()\n"); + lock_kernel(); /* Only let one of these through at a time */ - if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) + if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) { + unlock_kernel(); return -EINTR; + } /* First copy down the buffer length */ if (copy_from_user(&data_buffer_length, argp, sizeof(unsigned int))) @@ -1029,6 +1033,7 @@ out2: dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle); out: mutex_unlock(&tw_dev->ioctl_lock); + unlock_kernel(); return retval; } /* End tw_chrdev_ioctl() */ @@ -1051,7 +1056,7 @@ static int tw_chrdev_open(struct inode *inode, struct file *file) /* File operations struct for character device */ static const struct file_operations tw_fops = { .owner = THIS_MODULE, - .ioctl = tw_chrdev_ioctl, + .unlocked_ioctl = tw_chrdev_ioctl, .open = tw_chrdev_open, .release = NULL }; diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index e9373a2d14fa..33898b61fdb5 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -705,12 +705,17 @@ static int aac_cfg_open(struct inode *inode, struct file *file) * Bugs: Needs to handle hot plugging */ -static int aac_cfg_ioctl(struct inode *inode, struct file *file, +static long aac_cfg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { + int ret; if (!capable(CAP_SYS_RAWIO)) return -EPERM; - return aac_do_ioctl(file->private_data, cmd, (void __user *)arg); + lock_kernel(); + ret = aac_do_ioctl(file->private_data, cmd, (void __user *)arg); + unlock_kernel(); + + return ret; } #ifdef CONFIG_COMPAT @@ -1029,7 +1034,7 @@ ssize_t aac_get_serial_number(struct device *device, char *buf) static const struct file_operations aac_cfg_fops = { .owner = THIS_MODULE, - .ioctl = aac_cfg_ioctl, + .unlocked_ioctl = aac_cfg_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = aac_compat_cfg_ioctl, #endif diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index 0435d044c9da..b0c576f84b28 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c @@ -114,12 +114,13 @@ static int hba_count = 0; static struct class *adpt_sysfs_class; +static long adpt_unlocked_ioctl(struct file *, unsigned int, unsigned long); #ifdef CONFIG_COMPAT static long compat_adpt_ioctl(struct file *, unsigned int, unsigned long); #endif static const struct file_operations adpt_fops = { - .ioctl = adpt_ioctl, + .unlocked_ioctl = adpt_unlocked_ioctl, .open = adpt_open, .release = adpt_close, #ifdef CONFIG_COMPAT @@ -2069,8 +2070,7 @@ static int adpt_system_info(void __user *buffer) return 0; } -static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, - ulong arg) +static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) { int minor; int error = 0; @@ -2153,6 +2153,20 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, return error; } +static long adpt_unlocked_ioctl(struct file *file, uint cmd, ulong arg) +{ + struct inode *inode; + long ret; + + inode = file->f_dentry->d_inode; + + lock_kernel(); + ret = adpt_ioctl(inode, file, cmd, arg); + unlock_kernel(); + + return ret; +} + #ifdef CONFIG_COMPAT static long compat_adpt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 35a4b3073ec3..d3f335db3d8d 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -180,8 +180,8 @@ static const char *gdth_ctr_name(gdth_ha_str *ha); static int gdth_open(struct inode *inode, struct file *filep); static int gdth_close(struct inode *inode, struct file *filep); -static int gdth_ioctl(struct inode *inode, struct file *filep, - unsigned int cmd, unsigned long arg); +static long gdth_unlocked_ioctl(struct file *filep, unsigned int cmd, + unsigned long arg); static void gdth_flush(gdth_ha_str *ha); static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)); @@ -369,7 +369,7 @@ MODULE_LICENSE("GPL"); /* ioctl interface */ static const struct file_operations gdth_fops = { - .ioctl = gdth_ioctl, + .unlocked_ioctl = gdth_unlocked_ioctl, .open = gdth_open, .release = gdth_close, }; @@ -4462,8 +4462,7 @@ free_fail: return rc; } -static int gdth_ioctl(struct inode *inode, struct file *filep, - unsigned int cmd, unsigned long arg) +static int gdth_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { gdth_ha_str *ha; Scsi_Cmnd *scp; @@ -4611,6 +4610,17 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, return 0; } +static long gdth_unlocked_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = gdth_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} /* flush routine */ static void gdth_flush(gdth_ha_str *ha) diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 4bf7edca9e69..0b6e3228610a 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -91,12 +91,15 @@ static struct proc_dir_entry *mega_proc_dir_entry; /* For controller re-ordering */ static struct mega_hbas mega_hbas[MAX_CONTROLLERS]; +static long +megadev_unlocked_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); + /* * The File Operations structure for the serial/ioctl interface of the driver */ static const struct file_operations megadev_fops = { .owner = THIS_MODULE, - .ioctl = megadev_ioctl, + .unlocked_ioctl = megadev_unlocked_ioctl, .open = megadev_open, }; @@ -3302,8 +3305,7 @@ megadev_open (struct inode *inode, struct file *filep) * controller. */ static int -megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, - unsigned long arg) +megadev_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { adapter_t *adapter; nitioctl_t uioc; @@ -3694,6 +3696,18 @@ freemem_and_return: return 0; } +static long +megadev_unlocked_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = megadev_ioctl(filep, cmd, arg); + unlock_kernel(); + + return ret; +} + /** * mega_m_to_n() * @arg - user address diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h index d310f49d077e..2b4a048cadf1 100644 --- a/drivers/scsi/megaraid.h +++ b/drivers/scsi/megaraid.h @@ -1013,8 +1013,7 @@ static void mega_8_to_40ld (mraid_inquiry *inquiry, mega_inquiry3 *enquiry3, mega_product_info *); static int megadev_open (struct inode *, struct file *); -static int megadev_ioctl (struct inode *, struct file *, unsigned int, - unsigned long); +static int megadev_ioctl (struct file *, unsigned int, unsigned long); static int mega_m_to_n(void __user *, nitioctl_t *); static int mega_n_to_m(void __user *, megacmd_t *); diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c index 36e0b7d05c1d..41f82f76d884 100644 --- a/drivers/scsi/megaraid/megaraid_mm.c +++ b/drivers/scsi/megaraid/megaraid_mm.c @@ -22,7 +22,7 @@ // Entry points for char node driver static int mraid_mm_open(struct inode *, struct file *); -static int mraid_mm_ioctl(struct inode *, struct file *, uint, unsigned long); +static long mraid_mm_unlocked_ioctl(struct file *, uint, unsigned long); // routines to convert to and from the old the format @@ -70,7 +70,7 @@ static wait_queue_head_t wait_q; static const struct file_operations lsi_fops = { .open = mraid_mm_open, - .ioctl = mraid_mm_ioctl, + .unlocked_ioctl = mraid_mm_unlocked_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = mraid_mm_compat_ioctl, #endif @@ -110,8 +110,7 @@ mraid_mm_open(struct inode *inode, struct file *filep) * @arg : user ioctl packet */ static int -mraid_mm_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, - unsigned long arg) +mraid_mm_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { uioc_t *kioc; char signature[EXT_IOCTL_SIGN_SZ] = {0}; @@ -218,6 +217,19 @@ mraid_mm_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, return rval; } +static long +mraid_mm_unlocked_ioctl(struct file *filep, unsigned int cmd, + unsigned long arg) +{ + int err; + + /* inconsistant: mraid_mm_compat_ioctl doesn't take the BKL */ + lock_kernel(); + err = mraid_mm_ioctl(filep, cmd, arg); + unlock_kernel(); + + return err; +} /** * mraid_mm_get_adapter - Returns corresponding adapters for the mimd packet @@ -1225,7 +1237,7 @@ mraid_mm_compat_ioctl(struct file *filep, unsigned int cmd, { int err; - err = mraid_mm_ioctl(NULL, filep, cmd, arg); + err = mraid_mm_ioctl(filep, cmd, arg); return err; } diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index b219118f8bd6..8dbf1c3afb7b 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -4932,7 +4932,7 @@ static int os_scsi_tape_close(struct inode * inode, struct file * filp) /* The ioctl command */ -static int osst_ioctl(struct inode * inode,struct file * file, +static long osst_ioctl(struct file * file, unsigned int cmd_in, unsigned long arg) { int i, cmd_nr, cmd_type, blk, retval = 0; @@ -4943,8 +4943,11 @@ static int osst_ioctl(struct inode * inode,struct file * file, char * name = tape_name(STp); void __user * p = (void __user *)arg; - if (mutex_lock_interruptible(&STp->lock)) + lock_kernel(); + if (mutex_lock_interruptible(&STp->lock)) { + unlock_kernel(); return -ERESTARTSYS; + } #if DEBUG if (debugging && !STp->in_use) { @@ -5256,12 +5259,15 @@ static int osst_ioctl(struct inode * inode,struct file * file, mutex_unlock(&STp->lock); - return scsi_ioctl(STp->device, cmd_in, p); + retval = scsi_ioctl(STp->device, cmd_in, p); + unlock_kernel(); + return retval; out: if (SRpnt) osst_release_request(SRpnt); mutex_unlock(&STp->lock); + unlock_kernel(); return retval; } @@ -5613,7 +5619,7 @@ static const struct file_operations osst_fops = { .owner = THIS_MODULE, .read = osst_read, .write = osst_write, - .ioctl = osst_ioctl, + .unlocked_ioctl = osst_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = osst_compat_ioctl, #endif diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index dee1c96288d4..ef752b248c4d 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -758,8 +758,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, } static int -sg_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd_in, unsigned long arg) +sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) { void __user *p = (void __user *)arg; int __user *ip = p; @@ -1078,6 +1077,18 @@ sg_ioctl(struct inode *inode, struct file *filp, } } +static long +sg_unlocked_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = sg_ioctl(filp, cmd_in, arg); + unlock_kernel(); + + return ret; +} + #ifdef CONFIG_COMPAT static long sg_compat_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) { @@ -1322,7 +1333,7 @@ static const struct file_operations sg_fops = { .read = sg_read, .write = sg_write, .poll = sg_poll, - .ioctl = sg_ioctl, + .unlocked_ioctl = sg_unlocked_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = sg_compat_ioctl, #endif -- cgit v1.2.3 From 703c631ebbcadcfd861d01e697fdda7c388fec9a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 27 Apr 2010 00:24:02 +0200 Subject: isdn: Push down BKL into ioctl functions Push down bkl into isdn ioctl functions [fweisbec: dropped drivers/isdn/divert/divert_procfs.c as it has been pushed down in procfs branch already] Signed-off-by: Arnd Bergmann Signed-off-by: Frederic Weisbecker --- drivers/isdn/capi/capi.c | 17 ++++++++++++++--- drivers/isdn/i4l/isdn_common.c | 18 +++++++++++++++--- drivers/isdn/mISDN/timerdev.c | 10 ++++++---- 3 files changed, 35 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index ee5837522f5a..0cabe31f26df 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -787,8 +787,7 @@ capi_poll(struct file *file, poll_table * wait) } static int -capi_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +capi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct capidev *cdev = file->private_data; capi_ioctl_struct data; @@ -981,6 +980,18 @@ register_out: } } +static long +capi_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = capi_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + static int capi_open(struct inode *inode, struct file *file) { struct capidev *cdev; @@ -1026,7 +1037,7 @@ static const struct file_operations capi_fops = .read = capi_read, .write = capi_write, .poll = capi_poll, - .ioctl = capi_ioctl, + .unlocked_ioctl = capi_unlocked_ioctl, .open = capi_open, .release = capi_release, }; diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index 70044ee4b228..a44cdb492ea9 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c @@ -1272,9 +1272,9 @@ isdn_poll(struct file *file, poll_table * wait) static int -isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) +isdn_ioctl(struct file *file, uint cmd, ulong arg) { - uint minor = iminor(inode); + uint minor = iminor(file->f_path.dentry->d_inode); isdn_ctrl c; int drvidx; int chidx; @@ -1722,6 +1722,18 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) #undef cfg } +static long +isdn_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = isdn_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + /* * Open the device code. */ @@ -1838,7 +1850,7 @@ static const struct file_operations isdn_fops = .read = isdn_read, .write = isdn_write, .poll = isdn_poll, - .ioctl = isdn_ioctl, + .unlocked_ioctl = isdn_unlocked_ioctl, .open = isdn_open, .release = isdn_close, }; diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c index 8785004e85e0..c3243c913ec0 100644 --- a/drivers/isdn/mISDN/timerdev.c +++ b/drivers/isdn/mISDN/timerdev.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "core.h" static u_int *debug; @@ -215,9 +216,8 @@ unlock: return ret; } -static int -mISDN_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, - unsigned long arg) +static long +mISDN_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { struct mISDNtimerdev *dev = filep->private_data; int id, tout, ret = 0; @@ -226,6 +226,7 @@ mISDN_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, if (*debug & DEBUG_TIMER) printk(KERN_DEBUG "%s(%p, %x, %lx)\n", __func__, filep, cmd, arg); + lock_kernel(); switch (cmd) { case IMADDTIMER: if (get_user(tout, (int __user *)arg)) { @@ -257,13 +258,14 @@ mISDN_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, default: ret = -EINVAL; } + unlock_kernel(); return ret; } static const struct file_operations mISDN_fops = { .read = mISDN_read, .poll = mISDN_poll, - .ioctl = mISDN_ioctl, + .unlocked_ioctl = mISDN_ioctl, .open = mISDN_open, .release = mISDN_close, }; -- cgit v1.2.3 From 55929332c92e5d34d65a8f784604c92677ea3e15 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 27 Apr 2010 00:24:05 +0200 Subject: drivers: Push down BKL into various drivers These are the last remaining device drivers using the ->ioctl file operation in the drivers directory (except from v4l drivers). [fweisbec: drop i8k pushdown as it has been done from procfs pushdown branch already] Signed-off-by: Arnd Bergmann Signed-off-by: Frederic Weisbecker --- drivers/char/apm-emulation.c | 8 ++++--- drivers/char/applicom.c | 13 +++++++----- drivers/char/ds1620.c | 16 ++++++++++++-- drivers/char/dtlk.c | 15 ++++++------- drivers/char/generic_nvram.c | 17 ++++++++++++--- drivers/char/genrtc.c | 16 ++++++++++++-- drivers/char/hpet.c | 14 ++++++++----- drivers/char/ipmi/ipmi_devintf.c | 26 ++++++++++++++++++----- drivers/char/ipmi/ipmi_watchdog.c | 17 +++++++++++++-- drivers/char/nvram.c | 10 ++++++--- drivers/char/nwflash.c | 7 +++++-- drivers/char/raw.c | 42 +++++++++++++++++++++---------------- drivers/hwmon/fschmd.c | 9 ++++---- drivers/hwmon/w83793.c | 10 +++++---- drivers/input/misc/hp_sdc_rtc.c | 34 +++++++++++++++++++++--------- drivers/macintosh/nvram.c | 2 +- drivers/macintosh/via-pmu.c | 17 ++++++++++++--- drivers/mtd/mtdchar.c | 19 ++++++++++++----- drivers/pcmcia/pcmcia_ioctl.c | 17 ++++++++++++--- drivers/rtc/rtc-m41t80.c | 16 ++++++++++++-- drivers/sbus/char/openprom.c | 44 ++++++++++++++++++++++----------------- drivers/usb/mon/mon_bin.c | 23 ++++++++++++++------ drivers/usb/mon/mon_stat.c | 3 ++- 23 files changed, 280 insertions(+), 115 deletions(-) (limited to 'drivers') diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c index 4f568cb9af3f..033e1505fca9 100644 --- a/drivers/char/apm-emulation.c +++ b/drivers/char/apm-emulation.c @@ -265,8 +265,8 @@ static unsigned int apm_poll(struct file *fp, poll_table * wait) * Only when everyone who has opened /dev/apm_bios with write permission * has acknowledge does the actual suspend happen. */ -static int -apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) +static long +apm_ioctl(struct file *filp, u_int cmd, u_long arg) { struct apm_user *as = filp->private_data; int err = -EINVAL; @@ -274,6 +274,7 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) if (!as->suser || !as->writer) return -EPERM; + lock_kernel(); switch (cmd) { case APM_IOC_SUSPEND: mutex_lock(&state_lock); @@ -334,6 +335,7 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) mutex_unlock(&state_lock); break; } + unlock_kernel(); return err; } @@ -397,7 +399,7 @@ static const struct file_operations apm_bios_fops = { .owner = THIS_MODULE, .read = apm_read, .poll = apm_poll, - .ioctl = apm_ioctl, + .unlocked_ioctl = apm_ioctl, .open = apm_open, .release = apm_release, }; diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index a7424bf7eacf..63313a33ba5f 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -106,8 +107,7 @@ static unsigned int DeviceErrorCount; /* number of device error */ static ssize_t ac_read (struct file *, char __user *, size_t, loff_t *); static ssize_t ac_write (struct file *, const char __user *, size_t, loff_t *); -static int ac_ioctl(struct inode *, struct file *, unsigned int, - unsigned long); +static long ac_ioctl(struct file *, unsigned int, unsigned long); static irqreturn_t ac_interrupt(int, void *); static const struct file_operations ac_fops = { @@ -115,7 +115,7 @@ static const struct file_operations ac_fops = { .llseek = no_llseek, .read = ac_read, .write = ac_write, - .ioctl = ac_ioctl, + .unlocked_ioctl = ac_ioctl, }; static struct miscdevice ac_miscdev = { @@ -689,7 +689,7 @@ static irqreturn_t ac_interrupt(int vec, void *dev_instance) -static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static long ac_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { /* @ ADG ou ATO selon le cas */ int i; @@ -711,7 +711,8 @@ static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un kfree(adgl); return -EFAULT; } - + + lock_kernel(); IndexCard = adgl->num_card-1; if(cmd != 6 && ((IndexCard >= MAX_BOARD) || !apbs[IndexCard].RamIO)) { @@ -721,6 +722,7 @@ static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un warncount--; } kfree(adgl); + unlock_kernel(); return -EINVAL; } @@ -838,6 +840,7 @@ static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un } Dummy = readb(apbs[IndexCard].RamIO + VERS); kfree(adgl); + unlock_kernel(); return 0; } diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c index 61f0146e215d..dbee8688f75c 100644 --- a/drivers/char/ds1620.c +++ b/drivers/char/ds1620.c @@ -232,7 +232,7 @@ ds1620_read(struct file *file, char __user *buf, size_t count, loff_t *ptr) } static int -ds1620_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +ds1620_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct therm therm; union { @@ -316,6 +316,18 @@ ds1620_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned return 0; } +static long +ds1620_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = ds1620_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + #ifdef THERM_USE_PROC static int proc_therm_ds1620_read(char *buf, char **start, off_t offset, @@ -344,7 +356,7 @@ static const struct file_operations ds1620_fops = { .owner = THIS_MODULE, .open = ds1620_open, .read = ds1620_read, - .ioctl = ds1620_ioctl, + .unlocked_ioctl = ds1620_unlocked_ioctl, }; static struct miscdevice ds1620_miscdev = { diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c index 045c930e6320..e3859d4eaead 100644 --- a/drivers/char/dtlk.c +++ b/drivers/char/dtlk.c @@ -93,8 +93,8 @@ static ssize_t dtlk_write(struct file *, const char __user *, static unsigned int dtlk_poll(struct file *, poll_table *); static int dtlk_open(struct inode *, struct file *); static int dtlk_release(struct inode *, struct file *); -static int dtlk_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg); +static long dtlk_ioctl(struct file *file, + unsigned int cmd, unsigned long arg); static const struct file_operations dtlk_fops = { @@ -102,7 +102,7 @@ static const struct file_operations dtlk_fops = .read = dtlk_read, .write = dtlk_write, .poll = dtlk_poll, - .ioctl = dtlk_ioctl, + .unlocked_ioctl = dtlk_ioctl, .open = dtlk_open, .release = dtlk_release, }; @@ -263,10 +263,9 @@ static void dtlk_timer_tick(unsigned long data) wake_up_interruptible(&dtlk_process_list); } -static int dtlk_ioctl(struct inode *inode, - struct file *file, - unsigned int cmd, - unsigned long arg) +static long dtlk_ioctl(struct file *file, + unsigned int cmd, + unsigned long arg) { char __user *argp = (char __user *)arg; struct dtlk_settings *sp; @@ -276,7 +275,9 @@ static int dtlk_ioctl(struct inode *inode, switch (cmd) { case DTLK_INTERROGATE: + lock_kernel(); sp = dtlk_interrogate(); + unlock_kernel(); if (copy_to_user(argp, sp, sizeof(struct dtlk_settings))) return -EINVAL; return 0; diff --git a/drivers/char/generic_nvram.c b/drivers/char/generic_nvram.c index fda4181b5e67..82b5a88a82d7 100644 --- a/drivers/char/generic_nvram.c +++ b/drivers/char/generic_nvram.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #ifdef CONFIG_PPC_PMAC @@ -84,8 +85,7 @@ static ssize_t write_nvram(struct file *file, const char __user *buf, return p - buf; } -static int nvram_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static int nvram_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { switch(cmd) { #ifdef CONFIG_PPC_PMAC @@ -116,12 +116,23 @@ static int nvram_ioctl(struct inode *inode, struct file *file, return 0; } +static long nvram_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = nvram_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + const struct file_operations nvram_fops = { .owner = THIS_MODULE, .llseek = nvram_llseek, .read = read_nvram, .write = write_nvram, - .ioctl = nvram_ioctl, + .unlocked_ioctl = nvram_unlocked_ioctl, }; static struct miscdevice nvram_dev = { diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c index 31e7c91c2d9d..b6c2cc167c11 100644 --- a/drivers/char/genrtc.c +++ b/drivers/char/genrtc.c @@ -262,7 +262,7 @@ static inline int gen_set_rtc_irq_bit(unsigned char bit) #endif } -static int gen_rtc_ioctl(struct inode *inode, struct file *file, +static int gen_rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct rtc_time wtime; @@ -332,6 +332,18 @@ static int gen_rtc_ioctl(struct inode *inode, struct file *file, return -EINVAL; } +static long gen_rtc_unlocked_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = gen_rtc_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + /* * We enforce only one user at a time here with the open/close. * Also clear the previous interrupt data on an open, and clean @@ -482,7 +494,7 @@ static const struct file_operations gen_rtc_fops = { .read = gen_rtc_read, .poll = gen_rtc_poll, #endif - .ioctl = gen_rtc_ioctl, + .unlocked_ioctl = gen_rtc_unlocked_ioctl, .open = gen_rtc_open, .release = gen_rtc_release, }; diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 9ded667625ac..a0a1829d3198 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -431,14 +431,18 @@ static int hpet_release(struct inode *inode, struct file *file) static int hpet_ioctl_common(struct hpet_dev *, int, unsigned long, int); -static int -hpet_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) +static long hpet_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { struct hpet_dev *devp; + int ret; devp = file->private_data; - return hpet_ioctl_common(devp, cmd, arg, 0); + lock_kernel(); + ret = hpet_ioctl_common(devp, cmd, arg, 0); + unlock_kernel(); + + return ret; } static int hpet_ioctl_ieon(struct hpet_dev *devp) @@ -654,7 +658,7 @@ static const struct file_operations hpet_fops = { .llseek = no_llseek, .read = hpet_read, .poll = hpet_poll, - .ioctl = hpet_ioctl, + .unlocked_ioctl = hpet_ioctl, .open = hpet_open, .release = hpet_release, .fasync = hpet_fasync, diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 65545de3dbf4..d8ec92a38980 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c @@ -228,8 +228,7 @@ static int handle_send_req(ipmi_user_t user, return rv; } -static int ipmi_ioctl(struct inode *inode, - struct file *file, +static int ipmi_ioctl(struct file *file, unsigned int cmd, unsigned long data) { @@ -630,6 +629,23 @@ static int ipmi_ioctl(struct inode *inode, return rv; } +/* + * Note: it doesn't make sense to take the BKL here but + * not in compat_ipmi_ioctl. -arnd + */ +static long ipmi_unlocked_ioctl(struct file *file, + unsigned int cmd, + unsigned long data) +{ + int ret; + + lock_kernel(); + ret = ipmi_ioctl(file, cmd, data); + unlock_kernel(); + + return ret; +} + #ifdef CONFIG_COMPAT /* @@ -802,7 +818,7 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd, if (copy_to_user(precv64, &recv64, sizeof(recv64))) return -EFAULT; - rc = ipmi_ioctl(filep->f_path.dentry->d_inode, filep, + rc = ipmi_ioctl(filep, ((cmd == COMPAT_IPMICTL_RECEIVE_MSG) ? IPMICTL_RECEIVE_MSG : IPMICTL_RECEIVE_MSG_TRUNC), @@ -819,14 +835,14 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd, return rc; } default: - return ipmi_ioctl(filep->f_path.dentry->d_inode, filep, cmd, arg); + return ipmi_ioctl(filep, cmd, arg); } } #endif static const struct file_operations ipmi_fops = { .owner = THIS_MODULE, - .ioctl = ipmi_ioctl, + .unlocked_ioctl = ipmi_unlocked_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = compat_ipmi_ioctl, #endif diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index a4d57e31f713..82bcdb262a3a 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -659,7 +659,7 @@ static struct watchdog_info ident = { .identity = "IPMI" }; -static int ipmi_ioctl(struct inode *inode, struct file *file, +static int ipmi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; @@ -730,6 +730,19 @@ static int ipmi_ioctl(struct inode *inode, struct file *file, } } +static long ipmi_unlocked_ioctl(struct file *file, + unsigned int cmd, + unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = ipmi_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + static ssize_t ipmi_write(struct file *file, const char __user *buf, size_t len, @@ -880,7 +893,7 @@ static const struct file_operations ipmi_wdog_fops = { .read = ipmi_read, .poll = ipmi_poll, .write = ipmi_write, - .ioctl = ipmi_ioctl, + .unlocked_ioctl = ipmi_unlocked_ioctl, .open = ipmi_open, .release = ipmi_close, .fasync = ipmi_fasync, diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index 47e8f7b0e4c1..66d2917b003f 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c @@ -296,8 +296,8 @@ checksum_err: return -EIO; } -static int nvram_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long nvram_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { int i; @@ -308,6 +308,7 @@ static int nvram_ioctl(struct inode *inode, struct file *file, if (!capable(CAP_SYS_ADMIN)) return -EACCES; + lock_kernel(); spin_lock_irq(&rtc_lock); for (i = 0; i < NVRAM_BYTES; ++i) @@ -315,6 +316,7 @@ static int nvram_ioctl(struct inode *inode, struct file *file, __nvram_set_checksum(); spin_unlock_irq(&rtc_lock); + unlock_kernel(); return 0; case NVRAM_SETCKS: @@ -323,9 +325,11 @@ static int nvram_ioctl(struct inode *inode, struct file *file, if (!capable(CAP_SYS_ADMIN)) return -EACCES; + lock_kernel(); spin_lock_irq(&rtc_lock); __nvram_set_checksum(); spin_unlock_irq(&rtc_lock); + unlock_kernel(); return 0; default: @@ -422,7 +426,7 @@ static const struct file_operations nvram_fops = { .llseek = nvram_llseek, .read = nvram_read, .write = nvram_write, - .ioctl = nvram_ioctl, + .unlocked_ioctl = nvram_ioctl, .open = nvram_open, .release = nvram_release, }; diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c index f80810901db6..043a1c7b86be 100644 --- a/drivers/char/nwflash.c +++ b/drivers/char/nwflash.c @@ -94,8 +94,9 @@ static int get_flash_id(void) return c2; } -static int flash_ioctl(struct inode *inodep, struct file *filep, unsigned int cmd, unsigned long arg) +static long flash_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { + lock_kernel(); switch (cmd) { case CMD_WRITE_DISABLE: gbWriteBase64Enable = 0; @@ -113,8 +114,10 @@ static int flash_ioctl(struct inode *inodep, struct file *filep, unsigned int cm default: gbWriteBase64Enable = 0; gbWriteEnable = 0; + unlock_kernel(); return -EINVAL; } + unlock_kernel(); return 0; } @@ -631,7 +634,7 @@ static const struct file_operations flash_fops = .llseek = flash_llseek, .read = flash_read, .write = flash_write, - .ioctl = flash_ioctl, + .unlocked_ioctl = flash_ioctl, }; static struct miscdevice flash_miscdev = diff --git a/drivers/char/raw.c b/drivers/char/raw.c index 8756ab0daa8b..b38942f6bf31 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c @@ -121,13 +121,17 @@ static int raw_release(struct inode *inode, struct file *filp) /* * Forward ioctls to the underlying block device. */ -static int -raw_ioctl(struct inode *inode, struct file *filp, - unsigned int command, unsigned long arg) +static long +raw_ioctl(struct file *filp, unsigned int command, unsigned long arg) { struct block_device *bdev = filp->private_data; + int ret; + + lock_kernel(); + ret = blkdev_ioctl(bdev, 0, command, arg); + unlock_kernel(); - return blkdev_ioctl(bdev, 0, command, arg); + return ret; } static void bind_device(struct raw_config_request *rq) @@ -141,13 +145,14 @@ static void bind_device(struct raw_config_request *rq) * Deal with ioctls against the raw-device control interface, to bind * and unbind other raw devices. */ -static int raw_ctl_ioctl(struct inode *inode, struct file *filp, - unsigned int command, unsigned long arg) +static long raw_ctl_ioctl(struct file *filp, unsigned int command, + unsigned long arg) { struct raw_config_request rq; struct raw_device_data *rawdev; int err = 0; + lock_kernel(); switch (command) { case RAW_SETBIND: case RAW_GETBIND: @@ -240,25 +245,26 @@ static int raw_ctl_ioctl(struct inode *inode, struct file *filp, break; } out: + unlock_kernel(); return err; } static const struct file_operations raw_fops = { - .read = do_sync_read, - .aio_read = generic_file_aio_read, - .write = do_sync_write, - .aio_write = blkdev_aio_write, - .fsync = blkdev_fsync, - .open = raw_open, - .release= raw_release, - .ioctl = raw_ioctl, - .owner = THIS_MODULE, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = blkdev_aio_write, + .fsync = blkdev_fsync, + .open = raw_open, + .release = raw_release, + .unlocked_ioctl = raw_ioctl, + .owner = THIS_MODULE, }; static const struct file_operations raw_ctl_fops = { - .ioctl = raw_ctl_ioctl, - .open = raw_open, - .owner = THIS_MODULE, + .unlocked_ioctl = raw_ctl_ioctl, + .open = raw_open, + .owner = THIS_MODULE, }; static struct cdev raw_cdev; diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c index 0627f7a5b9b8..b7ca2a9676cf 100644 --- a/drivers/hwmon/fschmd.c +++ b/drivers/hwmon/fschmd.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -847,8 +848,7 @@ static ssize_t watchdog_write(struct file *filp, const char __user *buf, return count; } -static int watchdog_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +static long watchdog_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | @@ -858,6 +858,7 @@ static int watchdog_ioctl(struct inode *inode, struct file *filp, int i, ret = 0; struct fschmd_data *data = filp->private_data; + lock_kernel(); switch (cmd) { case WDIOC_GETSUPPORT: ident.firmware_version = data->revision; @@ -914,7 +915,7 @@ static int watchdog_ioctl(struct inode *inode, struct file *filp, default: ret = -ENOTTY; } - + unlock_kernel(); return ret; } @@ -924,7 +925,7 @@ static const struct file_operations watchdog_fops = { .open = watchdog_open, .release = watchdog_release, .write = watchdog_write, - .ioctl = watchdog_ioctl, + .unlocked_ioctl = watchdog_ioctl, }; diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index 612807d97155..697202e27891 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -1319,8 +1320,8 @@ static ssize_t watchdog_write(struct file *filp, const char __user *buf, return count; } -static int watchdog_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +static long watchdog_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) { static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | @@ -1332,6 +1333,7 @@ static int watchdog_ioctl(struct inode *inode, struct file *filp, int val, ret = 0; struct w83793_data *data = filp->private_data; + lock_kernel(); switch (cmd) { case WDIOC_GETSUPPORT: if (!nowayout) @@ -1385,7 +1387,7 @@ static int watchdog_ioctl(struct inode *inode, struct file *filp, default: ret = -ENOTTY; } - + unlock_kernel(); return ret; } @@ -1395,7 +1397,7 @@ static const struct file_operations watchdog_fops = { .open = watchdog_open, .release = watchdog_close, .write = watchdog_write, - .ioctl = watchdog_ioctl, + .unlocked_ioctl = watchdog_ioctl, }; /* diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c index ad730e15afc0..e00a1cc79c0a 100644 --- a/drivers/input/misc/hp_sdc_rtc.c +++ b/drivers/input/misc/hp_sdc_rtc.c @@ -43,6 +43,7 @@ #include #include #include +#include #include MODULE_AUTHOR("Brian S. Julin "); @@ -64,8 +65,8 @@ static DECLARE_WAIT_QUEUE_HEAD(hp_sdc_rtc_wait); static ssize_t hp_sdc_rtc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos); -static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg); +static long hp_sdc_rtc_unlocked_ioctl(struct file *file, + unsigned int cmd, unsigned long arg); static unsigned int hp_sdc_rtc_poll(struct file *file, poll_table *wait); @@ -512,7 +513,7 @@ static int hp_sdc_rtc_read_proc(char *page, char **start, off_t off, return len; } -static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file, +static int hp_sdc_rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { #if 1 @@ -659,14 +660,27 @@ static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file, #endif } +static long hp_sdc_rtc_unlocked_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = hp_sdc_rtc_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + + static const struct file_operations hp_sdc_rtc_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .read = hp_sdc_rtc_read, - .poll = hp_sdc_rtc_poll, - .ioctl = hp_sdc_rtc_ioctl, - .open = hp_sdc_rtc_open, - .fasync = hp_sdc_rtc_fasync, + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = hp_sdc_rtc_read, + .poll = hp_sdc_rtc_poll, + .unlocked_ioctl = hp_sdc_rtc_ioctl, + .open = hp_sdc_rtc_open, + .fasync = hp_sdc_rtc_fasync, }; static struct miscdevice hp_sdc_rtc_dev = { diff --git a/drivers/macintosh/nvram.c b/drivers/macintosh/nvram.c index c876349c32de..a271c8218d82 100644 --- a/drivers/macintosh/nvram.c +++ b/drivers/macintosh/nvram.c @@ -100,7 +100,7 @@ const struct file_operations nvram_fops = { .llseek = nvram_llseek, .read = read_nvram, .write = write_nvram, - .ioctl = nvram_ioctl, + .unlocked_ioctl = nvram_ioctl, }; static struct miscdevice nvram_dev = { diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 42764849eb78..3d4fc0f7b00b 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -2273,8 +2273,7 @@ static int register_pmu_pm_ops(void) device_initcall(register_pmu_pm_ops); #endif -static int -pmu_ioctl(struct inode * inode, struct file *filp, +static int pmu_ioctl(struct file *filp, u_int cmd, u_long arg) { __u32 __user *argp = (__u32 __user *)arg; @@ -2337,11 +2336,23 @@ pmu_ioctl(struct inode * inode, struct file *filp, return error; } +static long pmu_unlocked_ioctl(struct file *filp, + u_int cmd, u_long arg) +{ + int ret; + + lock_kernel(); + ret = pmu_ioctl(filp, cmd, arg); + unlock_kernel(); + + return ret; +} + static const struct file_operations pmu_device_fops = { .read = pmu_read, .write = pmu_write, .poll = pmu_fpoll, - .ioctl = pmu_ioctl, + .unlocked_ioctl = pmu_unlocked_ioctl, .open = pmu_open, .release = pmu_release, }; diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 5b081cb84351..6749c2f96342 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -450,8 +450,7 @@ static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start, return ret; } -static int mtd_ioctl(struct inode *inode, struct file *file, - u_int cmd, u_long arg) +static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) { struct mtd_file_info *mfi = file->private_data; struct mtd_info *mtd = mfi->mtd; @@ -822,6 +821,17 @@ static int mtd_ioctl(struct inode *inode, struct file *file, return ret; } /* memory_ioctl */ +static long mtd_unlocked_ioctl(struct file *file, u_int cmd, u_long arg) +{ + int ret; + + lock_kernel(); + ret = mtd_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + #ifdef CONFIG_COMPAT struct mtd_oob_buf32 { @@ -836,7 +846,6 @@ struct mtd_oob_buf32 { static long mtd_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct inode *inode = file->f_path.dentry->d_inode; struct mtd_file_info *mfi = file->private_data; struct mtd_info *mtd = mfi->mtd; void __user *argp = compat_ptr(arg); @@ -874,7 +883,7 @@ static long mtd_compat_ioctl(struct file *file, unsigned int cmd, break; } default: - ret = mtd_ioctl(inode, file, cmd, (unsigned long)argp); + ret = mtd_ioctl(file, cmd, (unsigned long)argp); } unlock_kernel(); @@ -942,7 +951,7 @@ static const struct file_operations mtd_fops = { .llseek = mtd_lseek, .read = mtd_read, .write = mtd_write, - .ioctl = mtd_ioctl, + .unlocked_ioctl = mtd_unlocked_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = mtd_compat_ioctl, #endif diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 7631faa0cadd..838bbf6bca83 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c @@ -818,8 +818,7 @@ static u_int ds_poll(struct file *file, poll_table *wait) /*====================================================================*/ -static int ds_ioctl(struct inode *inode, struct file *file, - u_int cmd, u_long arg) +static int ds_ioctl(struct file *file, u_int cmd, u_long arg) { struct pcmcia_socket *s; void __user *uarg = (char __user *)arg; @@ -1026,13 +1025,25 @@ free_out: return err; } /* ds_ioctl */ +static long ds_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = ds_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + + /*====================================================================*/ static const struct file_operations ds_fops = { .owner = THIS_MODULE, .open = ds_open, .release = ds_release, - .ioctl = ds_ioctl, + .unlocked_ioctl = ds_unlocked_ioctl, .read = ds_read, .write = ds_write, .poll = ds_poll, diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 60fe266f0f49..038095d99976 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -623,7 +623,7 @@ static ssize_t wdt_read(struct file *file, char __user *buf, * according to their available features. We only actually usefully support * querying capabilities and current status. */ -static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, +static int wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int new_margin, rv; @@ -676,6 +676,18 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, return -ENOTTY; } +static long wdt_unlocked_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = wdt_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + /** * wdt_open: * @inode: inode of device @@ -736,7 +748,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, static const struct file_operations wdt_fops = { .owner = THIS_MODULE, .read = wdt_read, - .ioctl = wdt_ioctl, + .unlocked_ioctl = wdt_unlocked_ioctl, .write = wdt_write, .open = wdt_open, .release = wdt_release, diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c index fc2f676e984d..d53e62ab09da 100644 --- a/drivers/sbus/char/openprom.c +++ b/drivers/sbus/char/openprom.c @@ -298,9 +298,9 @@ static int opromgetbootargs(void __user *argp, struct openpromio *op, int bufsiz /* * SunOS and Solaris /dev/openprom ioctl calls. */ -static int openprom_sunos_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg, - struct device_node *dp) +static long openprom_sunos_ioctl(struct file * file, + unsigned int cmd, unsigned long arg, + struct device_node *dp) { DATA *data = file->private_data; struct openpromio *opp = NULL; @@ -316,6 +316,8 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file, if (bufsize < 0) return bufsize; + lock_kernel(); + switch (cmd) { case OPROMGETOPT: case OPROMGETPROP: @@ -365,6 +367,8 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file, } kfree(opp); + unlock_kernel(); + return error; } @@ -547,13 +551,14 @@ static int opiocgetnext(unsigned int cmd, void __user *argp) return 0; } -static int openprom_bsd_ioctl(struct inode * inode, struct file * file, +static int openprom_bsd_ioctl(struct file * file, unsigned int cmd, unsigned long arg) { DATA *data = (DATA *) file->private_data; void __user *argp = (void __user *)arg; int err; + lock_kernel(); switch (cmd) { case OPIOCGET: err = opiocget(argp, data); @@ -570,10 +575,10 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file, case OPIOCGETOPTNODE: BUILD_BUG_ON(sizeof(phandle) != sizeof(int)); + err = 0; if (copy_to_user(argp, &options_node->phandle, sizeof(phandle))) - return -EFAULT; - - return 0; + err = -EFAULT; + break; case OPIOCGETNEXT: case OPIOCGETCHILD: @@ -581,9 +586,10 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file, break; default: - return -EINVAL; - + err = -EINVAL; + break; }; + unlock_kernel(); return err; } @@ -592,8 +598,8 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file, /* * Handoff control to the correct ioctl handler. */ -static int openprom_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg) +static long openprom_ioctl(struct file * file, + unsigned int cmd, unsigned long arg) { DATA *data = (DATA *) file->private_data; @@ -602,14 +608,14 @@ static int openprom_ioctl(struct inode * inode, struct file * file, case OPROMNXTOPT: if ((file->f_mode & FMODE_READ) == 0) return -EPERM; - return openprom_sunos_ioctl(inode, file, cmd, arg, + return openprom_sunos_ioctl(file, cmd, arg, options_node); case OPROMSETOPT: case OPROMSETOPT2: if ((file->f_mode & FMODE_WRITE) == 0) return -EPERM; - return openprom_sunos_ioctl(inode, file, cmd, arg, + return openprom_sunos_ioctl(file, cmd, arg, options_node); case OPROMNEXT: @@ -618,7 +624,7 @@ static int openprom_ioctl(struct inode * inode, struct file * file, case OPROMNXTPROP: if ((file->f_mode & FMODE_READ) == 0) return -EPERM; - return openprom_sunos_ioctl(inode, file, cmd, arg, + return openprom_sunos_ioctl(file, cmd, arg, data->current_node); case OPROMU2P: @@ -630,7 +636,7 @@ static int openprom_ioctl(struct inode * inode, struct file * file, case OPROMPATH2NODE: if ((file->f_mode & FMODE_READ) == 0) return -EPERM; - return openprom_sunos_ioctl(inode, file, cmd, arg, NULL); + return openprom_sunos_ioctl(file, cmd, arg, NULL); case OPIOCGET: case OPIOCNEXTPROP: @@ -639,12 +645,12 @@ static int openprom_ioctl(struct inode * inode, struct file * file, case OPIOCGETCHILD: if ((file->f_mode & FMODE_READ) == 0) return -EBADF; - return openprom_bsd_ioctl(inode,file,cmd,arg); + return openprom_bsd_ioctl(file,cmd,arg); case OPIOCSET: if ((file->f_mode & FMODE_WRITE) == 0) return -EBADF; - return openprom_bsd_ioctl(inode,file,cmd,arg); + return openprom_bsd_ioctl(file,cmd,arg); default: return -EINVAL; @@ -676,7 +682,7 @@ static long openprom_compat_ioctl(struct file *file, unsigned int cmd, case OPROMSETCUR: case OPROMPCI2NODE: case OPROMPATH2NODE: - rval = openprom_ioctl(file->f_path.dentry->d_inode, file, cmd, arg); + rval = openprom_ioctl(file, cmd, arg); break; } @@ -709,7 +715,7 @@ static int openprom_release(struct inode * inode, struct file * file) static const struct file_operations openprom_fops = { .owner = THIS_MODULE, .llseek = no_llseek, - .ioctl = openprom_ioctl, + .unlocked_ioctl = openprom_ioctl, .compat_ioctl = openprom_compat_ioctl, .open = openprom_open, .release = openprom_release, diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index ddf7f9a1b336..55947725f609 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c @@ -954,8 +954,7 @@ static int mon_bin_queued(struct mon_reader_bin *rp) /* */ -static int mon_bin_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static int mon_bin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct mon_reader_bin *rp = file->private_data; // struct mon_bus* mbus = rp->r.m_bus; @@ -1095,6 +1094,19 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file, return ret; } +static long mon_bin_unlocked_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = mon_bin_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + + #ifdef CONFIG_COMPAT static long mon_bin_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) @@ -1148,14 +1160,13 @@ static long mon_bin_compat_ioctl(struct file *file, return 0; case MON_IOCG_STATS: - return mon_bin_ioctl(NULL, file, cmd, - (unsigned long) compat_ptr(arg)); + return mon_bin_ioctl(file, cmd, (unsigned long) compat_ptr(arg)); case MON_IOCQ_URB_LEN: case MON_IOCQ_RING_SIZE: case MON_IOCT_RING_SIZE: case MON_IOCH_MFLUSH: - return mon_bin_ioctl(NULL, file, cmd, arg); + return mon_bin_ioctl(file, cmd, arg); default: ; @@ -1239,7 +1250,7 @@ static const struct file_operations mon_fops_binary = { .read = mon_bin_read, /* .write = mon_text_write, */ .poll = mon_bin_poll, - .ioctl = mon_bin_ioctl, + .unlocked_ioctl = mon_bin_unlocked_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = mon_bin_compat_ioctl, #endif diff --git a/drivers/usb/mon/mon_stat.c b/drivers/usb/mon/mon_stat.c index 1becdc3837e6..8ec94f15a738 100644 --- a/drivers/usb/mon/mon_stat.c +++ b/drivers/usb/mon/mon_stat.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "usb_mon.h" @@ -63,6 +64,6 @@ const struct file_operations mon_fops_stat = { .read = mon_stat_read, /* .write = mon_stat_write, */ /* .poll = mon_stat_poll, */ - /* .ioctl = mon_stat_ioctl, */ + /* .unlocked_ioctl = mon_stat_ioctl, */ .release = mon_stat_release, }; -- cgit v1.2.3 From ef2f80ff7325b2c1888ff02ead28957b5840bf51 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 17 May 2010 11:27:00 +1000 Subject: md/linear: avoid possible oops and array stop Since commit ef286f6fa673cd7fb367e1b145069d8dbfcc6081 it has been important that each personality clears ->private in the ->stop() function, or sets it to a attribute group to be removed. linear.c doesn't. This can sometimes lead to an oops, though it doesn't always. Suitable for 2.6.33-stable and 2.6.34. Signed-off-by: NeilBrown Cc: stable@kernel.org --- drivers/md/linear.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/md/linear.c b/drivers/md/linear.c index bb2a23159b21..9db8ee0614a4 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c @@ -281,6 +281,7 @@ static int linear_stop (mddev_t *mddev) rcu_barrier(); blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ kfree(conf); + mddev->private = NULL; return 0; } -- cgit v1.2.3 From b6eb127d274385d81ce8dd45c98190f097bce1b4 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 15 Apr 2010 10:13:47 +1000 Subject: md: remove unneeded sysfs files more promptly When an array is stopped we need to remove some sysfs files which are dependent on the type of array. We need to delay that deletion as deleting them while holding reconfig_mutex can lead to deadlocks. We currently delay them until the array is completely destroyed. However it is possible to deactivate and then reactivate the array. It is also possible to need to remove sysfs files when changing level, which can potentially happen several times before an array is destroyed. So we need to delete these files more promptly: as soon as reconfig_mutex is dropped. We need to ensure this happens before do_md_run can restart the array, so we use open_mutex for some extra locking. This is not deadlock prone. Cc: stable@kernel.org Signed-off-by: NeilBrown --- drivers/md/md.c | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 08f665178c3b..edf777f6fe56 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -507,9 +507,32 @@ static inline int mddev_trylock(mddev_t * mddev) return mutex_trylock(&mddev->reconfig_mutex); } +static struct attribute_group md_redundancy_group; + static inline void mddev_unlock(mddev_t * mddev) { - mutex_unlock(&mddev->reconfig_mutex); + if (mddev->pers == NULL && mddev->private) { + /* These cannot be removed under reconfig_mutex as + * an access to the files will try to take reconfig_mutex + * while holding the file unremovable, which leads to + * a deadlock. + * So hold open_mutex instead - we are allowed to take + * it while holding reconfig_mutex, and md_run can + * use it to wait for the remove to complete. + */ + mutex_lock(&mddev->open_mutex); + mutex_unlock(&mddev->reconfig_mutex); + + sysfs_remove_group(&mddev->kobj, &md_redundancy_group); + if (mddev->private != (void*)1) + sysfs_remove_group(&mddev->kobj, mddev->private); + if (mddev->sysfs_action) + sysfs_put(mddev->sysfs_action); + mddev->sysfs_action = NULL; + mddev->private = NULL; + mutex_unlock(&mddev->open_mutex); + } else + mutex_unlock(&mddev->reconfig_mutex); md_wakeup_thread(mddev->thread); } @@ -4075,15 +4098,6 @@ static void mddev_delayed_delete(struct work_struct *ws) { mddev_t *mddev = container_of(ws, mddev_t, del_work); - if (mddev->private) { - sysfs_remove_group(&mddev->kobj, &md_redundancy_group); - if (mddev->private != (void*)1) - sysfs_remove_group(&mddev->kobj, mddev->private); - if (mddev->sysfs_action) - sysfs_put(mddev->sysfs_action); - mddev->sysfs_action = NULL; - mddev->private = NULL; - } sysfs_remove_group(&mddev->kobj, &md_bitmap_group); kobject_del(&mddev->kobj); kobject_put(&mddev->kobj); @@ -4241,6 +4255,13 @@ static int do_md_run(mddev_t * mddev) if (mddev->pers) return -EBUSY; + /* These two calls synchronise us with the + * sysfs_remove_group calls in mddev_unlock, + * so they must have completed. + */ + mutex_lock(&mddev->open_mutex); + mutex_unlock(&mddev->open_mutex); + /* * Analyze all RAID superblock(s) */ -- cgit v1.2.3 From a64c876fd357906a1f7193723866562ad290654c Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 14 Apr 2010 17:15:37 +1000 Subject: md: manage redundancy group in sysfs when changing level. Some levels expect the 'redundancy group' to be present, others don't. So when we change level of an array we might need to add or remove this group. This requires fixing up the current practice of overloading ->private to indicate (when ->pers == NULL) that something needs to be removed. So create a new ->to_remove to fill that role. When changing levels, we may need to add or remove attributes. When changing RAID5 -> RAID6, we both add and remove the same thing. It is important to catch this and optimise it out as the removal is delayed until a lock is released, so trying to add immediately would cause problems. Cc: stable@kernel.org Signed-off-by: NeilBrown --- drivers/md/md.c | 43 ++++++++++++++++++++++++++++++++----------- drivers/md/md.h | 1 + drivers/md/raid5.c | 7 +++++-- 3 files changed, 38 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index edf777f6fe56..e8d238885cd2 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -509,9 +509,9 @@ static inline int mddev_trylock(mddev_t * mddev) static struct attribute_group md_redundancy_group; -static inline void mddev_unlock(mddev_t * mddev) +static void mddev_unlock(mddev_t * mddev) { - if (mddev->pers == NULL && mddev->private) { + if (mddev->to_remove) { /* These cannot be removed under reconfig_mutex as * an access to the files will try to take reconfig_mutex * while holding the file unremovable, which leads to @@ -520,16 +520,20 @@ static inline void mddev_unlock(mddev_t * mddev) * it while holding reconfig_mutex, and md_run can * use it to wait for the remove to complete. */ + struct attribute_group *to_remove = mddev->to_remove; + mddev->to_remove = NULL; mutex_lock(&mddev->open_mutex); mutex_unlock(&mddev->reconfig_mutex); - sysfs_remove_group(&mddev->kobj, &md_redundancy_group); - if (mddev->private != (void*)1) - sysfs_remove_group(&mddev->kobj, mddev->private); - if (mddev->sysfs_action) - sysfs_put(mddev->sysfs_action); - mddev->sysfs_action = NULL; - mddev->private = NULL; + if (to_remove != &md_redundancy_group) + sysfs_remove_group(&mddev->kobj, to_remove); + if (mddev->pers == NULL || + mddev->pers->sync_request == NULL) { + sysfs_remove_group(&mddev->kobj, &md_redundancy_group); + if (mddev->sysfs_action) + sysfs_put(mddev->sysfs_action); + mddev->sysfs_action = NULL; + } mutex_unlock(&mddev->open_mutex); } else mutex_unlock(&mddev->reconfig_mutex); @@ -2996,6 +3000,23 @@ level_store(mddev_t *mddev, const char *buf, size_t len) /* Looks like we have a winner */ mddev_suspend(mddev); mddev->pers->stop(mddev); + + if (mddev->pers->sync_request == NULL && + pers->sync_request != NULL) { + /* need to add the md_redundancy_group */ + if (sysfs_create_group(&mddev->kobj, &md_redundancy_group)) + printk(KERN_WARNING + "md: cannot register extra attributes for %s\n", + mdname(mddev)); + mddev->sysfs_action = sysfs_get_dirent(mddev->kobj.sd, "sync_action"); + } + if (mddev->pers->sync_request != NULL && + pers->sync_request == NULL) { + /* need to remove the md_redundancy_group */ + if (mddev->to_remove == NULL) + mddev->to_remove = &md_redundancy_group; + } + module_put(mddev->pers->owner); /* Invalidate devices that are now superfluous */ list_for_each_entry(rdev, &mddev->disks, same_set) @@ -4550,8 +4571,8 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) mddev->queue->unplug_fn = NULL; mddev->queue->backing_dev_info.congested_fn = NULL; module_put(mddev->pers->owner); - if (mddev->pers->sync_request && mddev->private == NULL) - mddev->private = (void*)1; + if (mddev->pers->sync_request && mddev->to_remove == NULL) + mddev->to_remove = &md_redundancy_group; mddev->pers = NULL; /* tell userspace to handle 'inactive' */ sysfs_notify_dirent(mddev->sysfs_state); diff --git a/drivers/md/md.h b/drivers/md/md.h index 8e4c75c00d46..722f5dfe1953 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -305,6 +305,7 @@ struct mddev_s atomic_t max_corr_read_errors; /* max read retries */ struct list_head all_mddevs; + struct attribute_group *to_remove; /* Generic barrier handling. * If there is a pending barrier request, all other * writes are blocked while the devices are flushed. diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 70ffbd071b2e..a361398875d0 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -5090,7 +5090,9 @@ static int run(mddev_t *mddev) } /* Ok, everything is just fine now */ - if (sysfs_create_group(&mddev->kobj, &raid5_attrs_group)) + if (mddev->to_remove == &raid5_attrs_group) + mddev->to_remove = NULL; + else if (sysfs_create_group(&mddev->kobj, &raid5_attrs_group)) printk(KERN_WARNING "raid5: failed to create sysfs attributes for %s\n", mdname(mddev)); @@ -5137,7 +5139,8 @@ static int stop(mddev_t *mddev) mddev->queue->backing_dev_info.congested_fn = NULL; blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ free_conf(conf); - mddev->private = &raid5_attrs_group; + mddev->private = NULL; + mddev->to_remove = &raid5_attrs_group; return 0; } -- cgit v1.2.3 From a99c47a228c194aa75bffdcb82806c5f33c7c63b Mon Sep 17 00:00:00 2001 From: Tom Lyon Date: Mon, 17 May 2010 08:20:45 +0100 Subject: intel-iommu: errors with smaller iommu widths When using iommu_domain_alloc with the Intel iommu, the domain address width is always initialized to 48 bits (agaw 2). This domain->agaw value is then used by pfn_to_dma_pte to (always) build a 4 level page table. However, not all systems support iommu width of 48 or 4 level page tables. In particular, the Core i5-660 and i5-670 support an address width of 36 bits (not 39!), an agaw of only 1, and only 3 level page tables. This version of the patch simply lops off extra levels of the page tables if the agaw value of the iommu is less than what is currently allocated for the domain (in intel_iommu_attach_device). If there were already allocated addresses above what the new iommu can handle, EFAULT is returned. Signed-off-by: Tom Lyon Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/pci/intel-iommu.c | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index da40f0789739..57be89e6f484 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -3433,19 +3433,6 @@ static void vm_domain_remove_all_dev_info(struct dmar_domain *domain) /* domain id for virtual machine, it won't be set in context */ static unsigned long vm_domid; -static int vm_domain_min_agaw(struct dmar_domain *domain) -{ - int i; - int min_agaw = domain->agaw; - - for_each_set_bit(i, &domain->iommu_bmp, g_num_of_iommus) { - if (min_agaw > g_iommus[i]->agaw) - min_agaw = g_iommus[i]->agaw; - } - - return min_agaw; -} - static struct dmar_domain *iommu_alloc_vm_domain(void) { struct dmar_domain *domain; @@ -3574,7 +3561,6 @@ static int intel_iommu_attach_device(struct iommu_domain *domain, struct pci_dev *pdev = to_pci_dev(dev); struct intel_iommu *iommu; int addr_width; - u64 end; /* normally pdev is not mapped */ if (unlikely(domain_context_mapped(pdev))) { @@ -3597,14 +3583,30 @@ static int intel_iommu_attach_device(struct iommu_domain *domain, /* check if this iommu agaw is sufficient for max mapped address */ addr_width = agaw_to_width(iommu->agaw); - end = DOMAIN_MAX_ADDR(addr_width); - end = end & VTD_PAGE_MASK; - if (end < dmar_domain->max_addr) { - printk(KERN_ERR "%s: iommu agaw (%d) is not " + if (addr_width > cap_mgaw(iommu->cap)) + addr_width = cap_mgaw(iommu->cap); + + if (dmar_domain->max_addr > (1LL << addr_width)) { + printk(KERN_ERR "%s: iommu width (%d) is not " "sufficient for the mapped address (%llx)\n", - __func__, iommu->agaw, dmar_domain->max_addr); + __func__, addr_width, dmar_domain->max_addr); return -EFAULT; } + dmar_domain->gaw = addr_width; + + /* + * Knock out extra levels of page tables if necessary + */ + while (iommu->agaw < dmar_domain->agaw) { + struct dma_pte *pte; + + pte = dmar_domain->pgd; + if (dma_pte_present(pte)) { + free_pgtable_page(dmar_domain->pgd); + dmar_domain->pgd = (struct dma_pte *)dma_pte_addr(pte); + } + dmar_domain->agaw--; + } return domain_add_dev_info(dmar_domain, pdev, CONTEXT_TT_MULTI_LEVEL); } -- cgit v1.2.3 From 8954da1f82a468deeeae3683252b5440e7f4ccbe Mon Sep 17 00:00:00 2001 From: Tom Lyon Date: Mon, 17 May 2010 08:19:52 +0100 Subject: intel-iommu: intel_iommu_map_range failed at very end of address space intel_iommu_map_range() doesn't allow allocation at the very end of the address space; that code has been simplified and corrected. Signed-off-by: Tom Lyon Signed-off-by: Andrew Morton Signed-off-by: David Woodhouse --- drivers/pci/intel-iommu.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 57be89e6f484..65741dc491d6 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -3626,7 +3626,6 @@ static int intel_iommu_map_range(struct iommu_domain *domain, { struct dmar_domain *dmar_domain = domain->priv; u64 max_addr; - int addr_width; int prot = 0; int ret; @@ -3639,18 +3638,14 @@ static int intel_iommu_map_range(struct iommu_domain *domain, max_addr = iova + size; if (dmar_domain->max_addr < max_addr) { - int min_agaw; u64 end; /* check if minimum agaw is sufficient for mapped address */ - min_agaw = vm_domain_min_agaw(dmar_domain); - addr_width = agaw_to_width(min_agaw); - end = DOMAIN_MAX_ADDR(addr_width); - end = end & VTD_PAGE_MASK; + end = __DOMAIN_MAX_ADDR(dmar_domain->gaw) + 1; if (end < max_addr) { - printk(KERN_ERR "%s: iommu agaw (%d) is not " + printk(KERN_ERR "%s: iommu width (%d) is not " "sufficient for the mapped address (%llx)\n", - __func__, min_agaw, max_addr); + __func__, dmar_domain->gaw, max_addr); return -EFAULT; } dmar_domain->max_addr = max_addr; -- cgit v1.2.3 From cc05ea0cd63437da2033b3ce6e033b1f1aaaf640 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 4 May 2010 18:22:15 +0900 Subject: DMA ENGINE: Do not reset 'private' of channel The member 'private' of 'struct dma_chan' is meant for passing data between client and the controller driver. The DMA client driver may point it to platform specific stuff after acquiring the channel. So, it is the responsiblity of the same code to reset it, if it must. The DMA engine doesn't set it and hence, shouldn't reset it either. This reseting of private by DMA Engine comes in the way of implementing default channel settings during DMAC probe. That capability is useful for not having the clients to always provide platform specific data, like Rx/Tx FIFO addresses, which usually doesn't change across channel requests. Signed-off-by: Jassi Brar Signed-off-by: Dan Williams --- drivers/dma/dmaengine.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 790caeeb4ccd..21eb896f4dfd 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -514,7 +514,6 @@ struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, v break; if (--device->privatecnt == 0) dma_cap_clear(DMA_PRIVATE, device->cap_mask); - chan->private = NULL; chan = NULL; } } @@ -536,7 +535,6 @@ void dma_release_channel(struct dma_chan *chan) /* drop PRIVATE cap enabled by __dma_request_channel() */ if (--chan->device->privatecnt == 0) dma_cap_clear(DMA_PRIVATE, chan->device->cap_mask); - chan->private = NULL; mutex_unlock(&dma_list_mutex); } EXPORT_SYMBOL_GPL(dma_release_channel); -- cgit v1.2.3 From 4a31f2eff3b8fcf009db35f89eb222ed7835b6b9 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 27 Apr 2010 12:24:42 +0200 Subject: ARM: mx3: Fix a race condition in mxcmmc From cefcdab08d1c9636c4a7290bc2bbe937d051bce4 Mon Sep 17 00:00:00 2001 From: Volker Ernst Date: Mon, 26 Apr 2010 22:51:07 +0200 Subject: [PATCH] ARM: mx3: Fix a race condition in mxcmmc This fixes a race condition regarding interrupt bits in the SDHC controller driver code. In case of PIO-transfer it does not clear SDHC-status bit#11/12 in the INT-handler anymore. INT-handler might be called during an ongoing PIO-data-transfer (with some other INT-flag set) and PIO-transfer depends on these bits being set to detect the end of the data-transfer. This also means that at the end of PIO- transfer that PIO-software has to clear these bits itself. However in case of DMA-transfer these bits have to be cleared in the INT-handler, because they are used to generate INTs then. Works solid, no more problems here, can transfer big files. Signed-off-by: Volker Ernst Acked-by: Daniel Mack Cc: Andy Green Signed-off-by: Sascha Hauer --- drivers/mmc/host/mxcmmc.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 2c53024ee439..ec18e3b60342 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -489,6 +489,9 @@ static void mxcmci_datawork(struct work_struct *work) struct mxcmci_host *host = container_of(work, struct mxcmci_host, datawork); int datastat = mxcmci_transfer_data(host); + + writel(STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE, + host->base + MMC_REG_STATUS); mxcmci_finish_data(host, datastat); if (host->req->stop) { @@ -553,7 +556,8 @@ static irqreturn_t mxcmci_irq(int irq, void *devid) u32 stat; stat = readl(host->base + MMC_REG_STATUS); - writel(stat & ~STATUS_SDIO_INT_ACTIVE, host->base + MMC_REG_STATUS); + writel(stat & ~(STATUS_SDIO_INT_ACTIVE | STATUS_DATA_TRANS_DONE | + STATUS_WRITE_OP_DONE), host->base + MMC_REG_STATUS); dev_dbg(mmc_dev(host->mmc), "%s: 0x%08x\n", __func__, stat); @@ -561,6 +565,13 @@ static irqreturn_t mxcmci_irq(int irq, void *devid) sdio_irq = (stat & STATUS_SDIO_INT_ACTIVE) && host->use_sdio; spin_unlock_irqrestore(&host->lock, flags); +#ifdef HAS_DMA + if (mxcmci_use_dma(host) && + (stat & (STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE))) + writel(STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE, + host->base + MMC_REG_STATUS); +#endif + if (sdio_irq) { writel(STATUS_SDIO_INT_ACTIVE, host->base + MMC_REG_STATUS); mmc_signal_sdio_irq(host->mmc); -- cgit v1.2.3 From d5c051f1080e0eec55f3fc42c37d941681941628 Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Tue, 27 Apr 2010 13:15:00 -0300 Subject: classmate-laptop: Add RFKILL support. The RFKILL device shares the same ACPI device used for backlight. So, it required a new struct sharing both a backlight_device and a rfkill device. Signed-off-by: Thadeu Lima de Souza Cascardo --- drivers/platform/x86/classmate-laptop.c | 170 +++++++++++++++++++++++++++----- 1 file changed, 148 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c index 7f9e5ddc9498..3bf399fe2bbc 100644 --- a/drivers/platform/x86/classmate-laptop.c +++ b/drivers/platform/x86/classmate-laptop.c @@ -24,6 +24,7 @@ #include #include #include +#include MODULE_LICENSE("GPL"); @@ -37,7 +38,7 @@ struct cmpc_accel { #define CMPC_ACCEL_HID "ACCE0000" #define CMPC_TABLET_HID "TBLT0000" -#define CMPC_BL_HID "IPML200" +#define CMPC_IPML_HID "IPML200" #define CMPC_KEYS_HID "FnBT0000" /* @@ -461,43 +462,168 @@ static const struct backlight_ops cmpc_bl_ops = { .update_status = cmpc_bl_update_status }; -static int cmpc_bl_add(struct acpi_device *acpi) +/* + * RFKILL code. + */ + +static acpi_status cmpc_get_rfkill_wlan(acpi_handle handle, + unsigned long long *value) { - struct backlight_properties props; + union acpi_object param; + struct acpi_object_list input; + unsigned long long output; + acpi_status status; + + param.type = ACPI_TYPE_INTEGER; + param.integer.value = 0xC1; + input.count = 1; + input.pointer = ¶m; + status = acpi_evaluate_integer(handle, "GRDI", &input, &output); + if (ACPI_SUCCESS(status)) + *value = output; + return status; +} + +static acpi_status cmpc_set_rfkill_wlan(acpi_handle handle, + unsigned long long value) +{ + union acpi_object param[2]; + struct acpi_object_list input; + acpi_status status; + unsigned long long output; + + param[0].type = ACPI_TYPE_INTEGER; + param[0].integer.value = 0xC1; + param[1].type = ACPI_TYPE_INTEGER; + param[1].integer.value = value; + input.count = 2; + input.pointer = param; + status = acpi_evaluate_integer(handle, "GWRI", &input, &output); + return status; +} + +static void cmpc_rfkill_query(struct rfkill *rfkill, void *data) +{ + acpi_status status; + acpi_handle handle; + unsigned long long state; + bool blocked; + + handle = data; + status = cmpc_get_rfkill_wlan(handle, &state); + if (ACPI_SUCCESS(status)) { + blocked = state & 1 ? false : true; + rfkill_set_sw_state(rfkill, blocked); + } +} + +static int cmpc_rfkill_block(void *data, bool blocked) +{ + acpi_status status; + acpi_handle handle; + unsigned long long state; + + handle = data; + status = cmpc_get_rfkill_wlan(handle, &state); + if (ACPI_FAILURE(status)) + return -ENODEV; + if (blocked) + state &= ~1; + else + state |= 1; + status = cmpc_set_rfkill_wlan(handle, state); + if (ACPI_FAILURE(status)) + return -ENODEV; + return 0; +} + +static const struct rfkill_ops cmpc_rfkill_ops = { + .query = cmpc_rfkill_query, + .set_block = cmpc_rfkill_block, +}; + +/* + * Common backlight and rfkill code. + */ + +struct ipml200_dev { struct backlight_device *bd; + struct rfkill *rf; +}; + +static int cmpc_ipml_add(struct acpi_device *acpi) +{ + int retval; + struct ipml200_dev *ipml; + struct backlight_properties props; + + ipml = kmalloc(sizeof(*ipml), GFP_KERNEL); + if (ipml == NULL) + return -ENOMEM; memset(&props, 0, sizeof(struct backlight_properties)); props.max_brightness = 7; - bd = backlight_device_register("cmpc_bl", &acpi->dev, acpi->handle, - &cmpc_bl_ops, &props); - if (IS_ERR(bd)) - return PTR_ERR(bd); - dev_set_drvdata(&acpi->dev, bd); + ipml->bd = backlight_device_register("cmpc_bl", &acpi->dev, + acpi->handle, &cmpc_bl_ops, + &props); + if (IS_ERR(ipml->bd)) { + retval = PTR_ERR(ipml->bd); + goto out_bd; + } + + ipml->rf = rfkill_alloc("cmpc_rfkill", &acpi->dev, RFKILL_TYPE_WLAN, + &cmpc_rfkill_ops, acpi->handle); + /* rfkill_alloc may fail if RFKILL is disabled. We should still work + * anyway. */ + if (!IS_ERR(ipml->rf)) { + retval = rfkill_register(ipml->rf); + if (retval) { + rfkill_destroy(ipml->rf); + ipml->rf = NULL; + } + } else { + ipml->rf = NULL; + } + + dev_set_drvdata(&acpi->dev, ipml); return 0; + +out_bd: + kfree(ipml); + return retval; } -static int cmpc_bl_remove(struct acpi_device *acpi, int type) +static int cmpc_ipml_remove(struct acpi_device *acpi, int type) { - struct backlight_device *bd; + struct ipml200_dev *ipml; + + ipml = dev_get_drvdata(&acpi->dev); + + backlight_device_unregister(ipml->bd); + + if (ipml->rf) { + rfkill_unregister(ipml->rf); + rfkill_destroy(ipml->rf); + } + + kfree(ipml); - bd = dev_get_drvdata(&acpi->dev); - backlight_device_unregister(bd); return 0; } -static const struct acpi_device_id cmpc_bl_device_ids[] = { - {CMPC_BL_HID, 0}, +static const struct acpi_device_id cmpc_ipml_device_ids[] = { + {CMPC_IPML_HID, 0}, {"", 0} }; -static struct acpi_driver cmpc_bl_acpi_driver = { +static struct acpi_driver cmpc_ipml_acpi_driver = { .owner = THIS_MODULE, .name = "cmpc", .class = "cmpc", - .ids = cmpc_bl_device_ids, + .ids = cmpc_ipml_device_ids, .ops = { - .add = cmpc_bl_add, - .remove = cmpc_bl_remove + .add = cmpc_ipml_add, + .remove = cmpc_ipml_remove } }; @@ -580,7 +706,7 @@ static int cmpc_init(void) if (r) goto failed_keys; - r = acpi_bus_register_driver(&cmpc_bl_acpi_driver); + r = acpi_bus_register_driver(&cmpc_ipml_acpi_driver); if (r) goto failed_bl; @@ -598,7 +724,7 @@ failed_accel: acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver); failed_tablet: - acpi_bus_unregister_driver(&cmpc_bl_acpi_driver); + acpi_bus_unregister_driver(&cmpc_ipml_acpi_driver); failed_bl: acpi_bus_unregister_driver(&cmpc_keys_acpi_driver); @@ -611,7 +737,7 @@ static void cmpc_exit(void) { acpi_bus_unregister_driver(&cmpc_accel_acpi_driver); acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver); - acpi_bus_unregister_driver(&cmpc_bl_acpi_driver); + acpi_bus_unregister_driver(&cmpc_ipml_acpi_driver); acpi_bus_unregister_driver(&cmpc_keys_acpi_driver); } @@ -621,7 +747,7 @@ module_exit(cmpc_exit); static const struct acpi_device_id cmpc_device_ids[] = { {CMPC_ACCEL_HID, 0}, {CMPC_TABLET_HID, 0}, - {CMPC_BL_HID, 0}, + {CMPC_IPML_HID, 0}, {CMPC_KEYS_HID, 0}, {"", 0} }; -- cgit v1.2.3 From 9a58a3333923c7fef4ba6ac9afd817429e63a1fe Mon Sep 17 00:00:00 2001 From: Sreedhara DS Date: Mon, 26 Apr 2010 18:13:05 +0100 Subject: IPC driver for Intel Mobile Internet Device (MID) platforms The IPC (inter processor communications) is used to provide the communications between kernel and system control units on some embedded Intel x86 platforms. (Various bits of clean up and restructuring by Alan Cox) Signed-off-by: Sreedhara DS Signed-off-by: Alan Cox --- arch/x86/include/asm/intel_scu_ipc.h | 55 +++ drivers/platform/x86/Kconfig | 8 + drivers/platform/x86/Makefile | 1 + drivers/platform/x86/intel_scu_ipc.c | 829 +++++++++++++++++++++++++++++++++++ 4 files changed, 893 insertions(+) create mode 100644 arch/x86/include/asm/intel_scu_ipc.h create mode 100644 drivers/platform/x86/intel_scu_ipc.c (limited to 'drivers') diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h new file mode 100644 index 000000000000..4470c9ad4a3e --- /dev/null +++ b/arch/x86/include/asm/intel_scu_ipc.h @@ -0,0 +1,55 @@ +#ifndef _ASM_X86_INTEL_SCU_IPC_H_ +#define _ASM_X86_INTEL_SCU_IPC_H_ + +/* Read single register */ +int intel_scu_ipc_ioread8(u16 addr, u8 *data); + +/* Read two sequential registers */ +int intel_scu_ipc_ioread16(u16 addr, u16 *data); + +/* Read four sequential registers */ +int intel_scu_ipc_ioread32(u16 addr, u32 *data); + +/* Read a vector */ +int intel_scu_ipc_readv(u16 *addr, u8 *data, int len); + +/* Write single register */ +int intel_scu_ipc_iowrite8(u16 addr, u8 data); + +/* Write two sequential registers */ +int intel_scu_ipc_iowrite16(u16 addr, u16 data); + +/* Write four sequential registers */ +int intel_scu_ipc_iowrite32(u16 addr, u32 data); + +/* Write a vector */ +int intel_scu_ipc_writev(u16 *addr, u8 *data, int len); + +/* Update single register based on the mask */ +int intel_scu_ipc_update_register(u16 addr, u8 data, u8 mask); + +/* + * Indirect register read + * Can be used when SCCB(System Controller Configuration Block) register + * HRIM(Honor Restricted IPC Messages) is set (bit 23) + */ +int intel_scu_ipc_register_read(u32 addr, u32 *data); + +/* + * Indirect register write + * Can be used when SCCB(System Controller Configuration Block) register + * HRIM(Honor Restricted IPC Messages) is set (bit 23) + */ +int intel_scu_ipc_register_write(u32 addr, u32 data); + +/* Issue commands to the SCU with or without data */ +int intel_scu_ipc_simple_command(int cmd, int sub); +int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen, + u32 *out, int outlen); +/* I2C control api */ +int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data); + +/* Update FW version */ +int intel_scu_ipc_fw_update(u8 *buffer, u32 length); + +#endif diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 6c3320d75055..619134151ca6 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -527,4 +527,12 @@ config ACPI_CMPC keys as input device, backlight device, tablet and accelerometer devices. +config INTEL_SCU_IPC + bool "Intel SCU IPC Support" + depends on X86_MRST + default y + ---help--- + IPC is used to bridge the communications between kernel and SCU on + some embedded Intel x86 platforms. + endif # X86_PLATFORM_DEVICES diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index a906490e3530..8770bfe71431 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -25,3 +25,4 @@ obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o obj-$(CONFIG_TOSHIBA_BT_RFKILL) += toshiba_bluetooth.o +obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c new file mode 100644 index 000000000000..576c3ed92435 --- /dev/null +++ b/drivers/platform/x86/intel_scu_ipc.c @@ -0,0 +1,829 @@ +/* + * intel_scu_ipc.c: Driver for the Intel SCU IPC mechanism + * + * (C) Copyright 2008-2010 Intel Corporation + * Author: Sreedhara DS (sreedhara.ds@intel.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + * + * SCU runing in ARC processor communicates with other entity running in IA + * core through IPC mechanism which in turn messaging between IA core ad SCU. + * SCU has two IPC mechanism IPC-1 and IPC-2. IPC-1 is used between IA32 and + * SCU where IPC-2 is used between P-Unit and SCU. This driver delas with + * IPC-1 Driver provides an API for power control unit registers (e.g. MSIC) + * along with other APIs. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* IPC defines the following message types */ +#define IPCMSG_WATCHDOG_TIMER 0xF8 /* Set Kernel Watchdog Threshold */ +#define IPCMSG_BATTERY 0xEF /* Coulomb Counter Accumulator */ +#define IPCMSG_FW_UPDATE 0xFE /* Firmware update */ +#define IPCMSG_PCNTRL 0xFF /* Power controller unit read/write */ +#define IPCMSG_FW_REVISION 0xF4 /* Get firmware revision */ + +/* Command id associated with message IPCMSG_PCNTRL */ +#define IPC_CMD_PCNTRL_W 0 /* Register write */ +#define IPC_CMD_PCNTRL_R 1 /* Register read */ +#define IPC_CMD_PCNTRL_M 2 /* Register read-modify-write */ + +/* Miscelaneous Command ids */ +#define IPC_CMD_INDIRECT_RD 2 /* 32bit indirect read */ +#define IPC_CMD_INDIRECT_WR 5 /* 32bit indirect write */ + +/* + * IPC register summary + * + * IPC register blocks are memory mapped at fixed address of 0xFF11C000 + * To read or write information to the SCU, driver writes to IPC-1 memory + * mapped registers (base address 0xFF11C000). The following is the IPC + * mechanism + * + * 1. IA core cDMI interface claims this transaction and converts it to a + * Transaction Layer Packet (TLP) message which is sent across the cDMI. + * + * 2. South Complex cDMI block receives this message and writes it to + * the IPC-1 register block, causing an interrupt to the SCU + * + * 3. SCU firmware decodes this interrupt and IPC message and the appropriate + * message handler is called within firmware. + */ + +#define IPC_BASE_ADDR 0xFF11C000 /* IPC1 base register address */ +#define IPC_MAX_ADDR 0x100 /* Maximum IPC regisers */ +#define IPC_WWBUF_SIZE 16 /* IPC Write buffer Size */ +#define IPC_RWBUF_SIZE 16 /* IPC Read buffer Size */ +#define IPC_I2C_BASE 0xFF12B000 /* I2C control register base address */ +#define IPC_I2C_MAX_ADDR 0x10 /* Maximum I2C regisers */ + +static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id); +static void ipc_remove(struct pci_dev *pdev); + +struct intel_scu_ipc_dev { + struct pci_dev *pdev; + void __iomem *ipc_base; + void __iomem *i2c_base; +}; + +static struct intel_scu_ipc_dev ipcdev; /* Only one for now */ + +static int platform = 1; +module_param(platform, int, 0); +MODULE_PARM_DESC(platform, "1 for moorestown platform"); + + + + +/* + * IPC Read Buffer (Read Only): + * 16 byte buffer for receiving data from SCU, if IPC command + * processing results in response data + */ +#define IPC_READ_BUFFER 0x90 + +#define IPC_I2C_CNTRL_ADDR 0 +#define I2C_DATA_ADDR 0x04 + +static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */ + +/* + * Command Register (Write Only): + * A write to this register results in an interrupt to the SCU core processor + * Format: + * |rfu2(8) | size(8) | command id(4) | rfu1(3) | ioc(1) | command(8)| + */ +static inline void ipc_command(u32 cmd) /* Send ipc command */ +{ + writel(cmd, ipcdev.ipc_base); +} + +/* + * IPC Write Buffer (Write Only): + * 16-byte buffer for sending data associated with IPC command to + * SCU. Size of the data is specified in the IPC_COMMAND_REG register + */ +static inline void ipc_data_writel(u32 data, u32 offset) /* Write ipc data */ +{ + writel(data, ipcdev.ipc_base + 0x80 + offset); +} + +/* + * IPC destination Pointer (Write Only): + * Use content as pointer for destination write + */ +static inline void ipc_write_dptr(u32 data) /* Write dptr data */ +{ + writel(data, ipcdev.ipc_base + 0x0C); +} + +/* + * IPC Source Pointer (Write Only): + * Use content as pointer for read location +*/ +static inline void ipc_write_sptr(u32 data) /* Write dptr data */ +{ + writel(data, ipcdev.ipc_base + 0x08); +} + +/* + * Status Register (Read Only): + * Driver will read this register to get the ready/busy status of the IPC + * block and error status of the IPC command that was just processed by SCU + * Format: + * |rfu3(8)|error code(8)|initiator id(8)|cmd id(4)|rfu1(2)|error(1)|busy(1)| + */ + +static inline u8 ipc_read_status(void) +{ + return __raw_readl(ipcdev.ipc_base + 0x04); +} + +static inline u8 ipc_data_readb(u32 offset) /* Read ipc byte data */ +{ + return readb(ipcdev.ipc_base + IPC_READ_BUFFER + offset); +} + +static inline u8 ipc_data_readl(u32 offset) /* Read ipc u32 data */ +{ + return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset); +} + +static inline int busy_loop(void) /* Wait till scu status is busy */ +{ + u32 status = 0; + u32 loop_count = 0; + + status = ipc_read_status(); + while (status & 1) { + udelay(1); /* scu processing time is in few u secods */ + status = ipc_read_status(); + loop_count++; + /* break if scu doesn't reset busy bit after huge retry */ + if (loop_count > 100000) { + dev_err(&ipcdev.pdev->dev, "IPC timed out"); + return -ETIMEDOUT; + } + } + return (status >> 1) & 1; +} + +/* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */ +static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id) +{ + int nc; + u32 offset = 0; + u32 err = 0; + u8 cbuf[IPC_WWBUF_SIZE] = { '\0' }; + u32 *wbuf = (u32 *)&cbuf; + + mutex_lock(&ipclock); + if (ipcdev.pdev == NULL) { + mutex_unlock(&ipclock); + return -ENODEV; + } + + if (platform == 1) { + /* Entry is 4 bytes for read/write, 5 bytes for read modify */ + for (nc = 0; nc < count; nc++) { + cbuf[offset] = addr[nc]; + cbuf[offset + 1] = addr[nc] >> 8; + if (id != IPC_CMD_PCNTRL_R) + cbuf[offset + 2] = data[nc]; + if (id == IPC_CMD_PCNTRL_M) { + cbuf[offset + 3] = data[nc + 1]; + offset += 1; + } + offset += 3; + } + for (nc = 0, offset = 0; nc < count; nc++, offset += 4) + ipc_data_writel(wbuf[nc], offset); /* Write wbuff */ + + } else { + for (nc = 0, offset = 0; nc < count; nc++, offset += 2) + ipc_data_writel(addr[nc], offset); /* Write addresses */ + if (id != IPC_CMD_PCNTRL_R) { + for (nc = 0; nc < count; nc++, offset++) + ipc_data_writel(data[nc], offset); /* Write data */ + if (id == IPC_CMD_PCNTRL_M) + ipc_data_writel(data[nc + 1], offset); /* Mask value*/ + } + } + + if (id != IPC_CMD_PCNTRL_M) + ipc_command((count * 3) << 16 | id << 12 | 0 << 8 | op); + else + ipc_command((count * 4) << 16 | id << 12 | 0 << 8 | op); + + err = busy_loop(); + + if (id == IPC_CMD_PCNTRL_R) { /* Read rbuf */ + /* Workaround: values are read as 0 without memcpy_fromio */ + memcpy_fromio(cbuf, ipcdev.ipc_base + IPC_READ_BUFFER, 16); + if (platform == 1) { + for (nc = 0, offset = 2; nc < count; nc++, offset += 3) + data[nc] = ipc_data_readb(offset); + } else { + for (nc = 0; nc < count; nc++) + data[nc] = ipc_data_readb(nc); + } + } + mutex_unlock(&ipclock); + return err; +} + +/** + * intel_scu_ipc_ioread8 - read a word via the SCU + * @addr: register on SCU + * @data: return pointer for read byte + * + * Read a single register. Returns 0 on success or an error code. All + * locking between SCU accesses is handled for the caller. + * + * This function may sleep. + */ +int intel_scu_ipc_ioread8(u16 addr, u8 *data) +{ + return pwr_reg_rdwr(&addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R); +} +EXPORT_SYMBOL(intel_scu_ipc_ioread8); + +/** + * intel_scu_ipc_ioread16 - read a word via the SCU + * @addr: register on SCU + * @data: return pointer for read word + * + * Read a register pair. Returns 0 on success or an error code. All + * locking between SCU accesses is handled for the caller. + * + * This function may sleep. + */ +int intel_scu_ipc_ioread16(u16 addr, u16 *data) +{ + u16 x[2] = {addr, addr + 1 }; + return pwr_reg_rdwr(x, (u8 *)data, 2, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R); +} +EXPORT_SYMBOL(intel_scu_ipc_ioread16); + +/** + * intel_scu_ipc_ioread32 - read a dword via the SCU + * @addr: register on SCU + * @data: return pointer for read dword + * + * Read four registers. Returns 0 on success or an error code. All + * locking between SCU accesses is handled for the caller. + * + * This function may sleep. + */ +int intel_scu_ipc_ioread32(u16 addr, u32 *data) +{ + u16 x[4] = {addr, addr + 1, addr + 2, addr + 3}; + return pwr_reg_rdwr(x, (u8 *)data, 4, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R); +} +EXPORT_SYMBOL(intel_scu_ipc_ioread32); + +/** + * intel_scu_ipc_iowrite8 - write a byte via the SCU + * @addr: register on SCU + * @data: byte to write + * + * Write a single register. Returns 0 on success or an error code. All + * locking between SCU accesses is handled for the caller. + * + * This function may sleep. + */ +int intel_scu_ipc_iowrite8(u16 addr, u8 data) +{ + return pwr_reg_rdwr(&addr, &data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W); +} +EXPORT_SYMBOL(intel_scu_ipc_iowrite8); + +/** + * intel_scu_ipc_iowrite16 - write a word via the SCU + * @addr: register on SCU + * @data: word to write + * + * Write two registers. Returns 0 on success or an error code. All + * locking between SCU accesses is handled for the caller. + * + * This function may sleep. + */ +int intel_scu_ipc_iowrite16(u16 addr, u16 data) +{ + u16 x[2] = {addr, addr + 1 }; + return pwr_reg_rdwr(x, (u8 *)&data, 2, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W); +} +EXPORT_SYMBOL(intel_scu_ipc_iowrite16); + +/** + * intel_scu_ipc_iowrite32 - write a dword via the SCU + * @addr: register on SCU + * @data: dword to write + * + * Write four registers. Returns 0 on success or an error code. All + * locking between SCU accesses is handled for the caller. + * + * This function may sleep. + */ +int intel_scu_ipc_iowrite32(u16 addr, u32 data) +{ + u16 x[4] = {addr, addr + 1, addr + 2, addr + 3}; + return pwr_reg_rdwr(x, (u8 *)&data, 4, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W); +} +EXPORT_SYMBOL(intel_scu_ipc_iowrite32); + +/** + * intel_scu_ipc_readvv - read a set of registers + * @addr: register list + * @data: bytes to return + * @len: length of array + * + * Read registers. Returns 0 on success or an error code. All + * locking between SCU accesses is handled for the caller. + * + * The largest array length permitted by the hardware is 5 items. + * + * This function may sleep. + */ +int intel_scu_ipc_readv(u16 *addr, u8 *data, int len) +{ + return pwr_reg_rdwr(addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R); +} +EXPORT_SYMBOL(intel_scu_ipc_readv); + +/** + * intel_scu_ipc_writev - write a set of registers + * @addr: register list + * @data: bytes to write + * @len: length of array + * + * Write registers. Returns 0 on success or an error code. All + * locking between SCU accesses is handled for the caller. + * + * The largest array length permitted by the hardware is 5 items. + * + * This function may sleep. + * + */ +int intel_scu_ipc_writev(u16 *addr, u8 *data, int len) +{ + return pwr_reg_rdwr(addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W); +} +EXPORT_SYMBOL(intel_scu_ipc_writev); + + +/** + * intel_scu_ipc_update_register - r/m/w a register + * @addr: register address + * @bits: bits to update + * @mask: mask of bits to update + * + * Read-modify-write power control unit register. The first data argument + * must be register value and second is mask value + * mask is a bitmap that indicates which bits to update. + * 0 = masked. Don't modify this bit, 1 = modify this bit. + * returns 0 on success or an error code. + * + * This function may sleep. Locking between SCU accesses is handled + * for the caller. + */ +int intel_scu_ipc_update_register(u16 addr, u8 bits, u8 mask) +{ + u8 data[2] = { bits, mask }; + return pwr_reg_rdwr(&addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_M); +} +EXPORT_SYMBOL(intel_scu_ipc_update_register); + +/** + * intel_scu_ipc_register_read - 32bit indirect read + * @addr: register address + * @value: 32bit value return + * + * Performs IA 32 bit indirect read, returns 0 on success, or an + * error code. + * + * Can be used when SCCB(System Controller Configuration Block) register + * HRIM(Honor Restricted IPC Messages) is set (bit 23) + * + * This function may sleep. Locking for SCU accesses is handled for + * the caller. + */ +int intel_scu_ipc_register_read(u32 addr, u32 *value) +{ + u32 err = 0; + + mutex_lock(&ipclock); + if (ipcdev.pdev == NULL) { + mutex_unlock(&ipclock); + return -ENODEV; + } + ipc_write_sptr(addr); + ipc_command(4 << 16 | IPC_CMD_INDIRECT_RD); + err = busy_loop(); + *value = ipc_data_readl(0); + mutex_unlock(&ipclock); + return err; +} +EXPORT_SYMBOL(intel_scu_ipc_register_read); + +/** + * intel_scu_ipc_register_write - 32bit indirect write + * @addr: register address + * @value: 32bit value to write + * + * Performs IA 32 bit indirect write, returns 0 on success, or an + * error code. + * + * Can be used when SCCB(System Controller Configuration Block) register + * HRIM(Honor Restricted IPC Messages) is set (bit 23) + * + * This function may sleep. Locking for SCU accesses is handled for + * the caller. + */ +int intel_scu_ipc_register_write(u32 addr, u32 value) +{ + u32 err = 0; + + mutex_lock(&ipclock); + if (ipcdev.pdev == NULL) { + mutex_unlock(&ipclock); + return -ENODEV; + } + ipc_write_dptr(addr); + ipc_data_writel(value, 0); + ipc_command(4 << 16 | IPC_CMD_INDIRECT_WR); + err = busy_loop(); + mutex_unlock(&ipclock); + return err; +} +EXPORT_SYMBOL(intel_scu_ipc_register_write); + +/** + * intel_scu_ipc_simple_command - send a simple command + * @cmd: command + * @sub: sub type + * + * Issue a simple command to the SCU. Do not use this interface if + * you must then access data as any data values may be overwritten + * by another SCU access by the time this function returns. + * + * This function may sleep. Locking for SCU accesses is handled for + * the caller. + */ +int intel_scu_ipc_simple_command(int cmd, int sub) +{ + u32 err = 0; + + mutex_lock(&ipclock); + if (ipcdev.pdev == NULL) { + mutex_unlock(&ipclock); + return -ENODEV; + } + ipc_command(cmd << 12 | sub); + err = busy_loop(); + mutex_unlock(&ipclock); + return err; +} +EXPORT_SYMBOL(intel_scu_ipc_simple_command); + +/** + * intel_scu_ipc_command - command with data + * @cmd: command + * @sub: sub type + * @in: input data + * @inlen: input length + * @out: output data + * @outlein: output length + * + * Issue a command to the SCU which involves data transfers. Do the + * data copies under the lock but leave it for the caller to interpret + */ + +int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen, + u32 *out, int outlen) +{ + u32 err = 0; + int i = 0; + + mutex_lock(&ipclock); + if (ipcdev.pdev == NULL) { + mutex_unlock(&ipclock); + return -ENODEV; + } + + for (i = 0; i < inlen; i++) + ipc_data_writel(*in++, 4 * i); + + ipc_command(cmd << 12 | sub); + err = busy_loop(); + + for (i = 0; i < outlen; i++) + *out++ = ipc_data_readl(4 * i); + + mutex_unlock(&ipclock); + return err; +} +EXPORT_SYMBOL(intel_scu_ipc_command); + +/*I2C commands */ +#define IPC_I2C_WRITE 1 /* I2C Write command */ +#define IPC_I2C_READ 2 /* I2C Read command */ + +/** + * intel_scu_ipc_i2c_cntrl - I2C read/write operations + * @addr: I2C address + command bits + * @data: data to read/write + * + * Perform an an I2C read/write operation via the SCU. All locking is + * handled for the caller. This function may sleep. + * + * Returns an error code or 0 on success. + * + * This has to be in the IPC driver for the locking. + */ +int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data) +{ + u32 cmd = 0; + + mutex_lock(&ipclock); + cmd = (addr >> 24) & 0xFF; + if (cmd == IPC_I2C_READ) { + writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR); + /* Write not getting updated without delay */ + mdelay(1); + *data = readl(ipcdev.i2c_base + I2C_DATA_ADDR); + } else if (cmd == IPC_I2C_WRITE) { + writel(addr, ipcdev.i2c_base + I2C_DATA_ADDR); + mdelay(1); + writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR); + } else { + dev_err(&ipcdev.pdev->dev, + "intel_scu_ipc: I2C INVALID_CMD = 0x%x\n", cmd); + + mutex_unlock(&ipclock); + return -1; + } + mutex_unlock(&ipclock); + return 0; +} +EXPORT_SYMBOL(intel_scu_ipc_i2c_cntrl); + +#define IPC_FW_LOAD_ADDR 0xFFFC0000 /* Storage location for FW image */ +#define IPC_FW_UPDATE_MBOX_ADDR 0xFFFFDFF4 /* Mailbox between ipc and scu */ +#define IPC_MAX_FW_SIZE 262144 /* 256K storage size for loading the FW image */ +#define IPC_FW_MIP_HEADER_SIZE 2048 /* Firmware MIP header size */ +/* IPC inform SCU to get ready for update process */ +#define IPC_CMD_FW_UPDATE_READY 0x10FE +/* IPC inform SCU to go for update process */ +#define IPC_CMD_FW_UPDATE_GO 0x20FE +/* Status code for fw update */ +#define IPC_FW_UPDATE_SUCCESS 0x444f4e45 /* Status code 'DONE' */ +#define IPC_FW_UPDATE_BADN 0x4241444E /* Status code 'BADN' */ +#define IPC_FW_TXHIGH 0x54784849 /* Status code 'IPC_FW_TXHIGH' */ +#define IPC_FW_TXLOW 0x54784c4f /* Status code 'IPC_FW_TXLOW' */ + +struct fw_update_mailbox { + u32 status; + u32 scu_flag; + u32 driver_flag; +}; + + +/** + * intel_scu_ipc_fw_update - Firmware update utility + * @buffer: firmware buffer + * @length: size of firmware buffer + * + * This function provides an interface to load the firmware into + * the SCU. Returns 0 on success or -1 on failure + */ +int intel_scu_ipc_fw_update(u8 *buffer, u32 length) +{ + void __iomem *fw_update_base; + struct fw_update_mailbox __iomem *mailbox = NULL; + int retry_cnt = 0; + u32 status; + + mutex_lock(&ipclock); + fw_update_base = ioremap_nocache(IPC_FW_LOAD_ADDR, (128*1024)); + if (fw_update_base == NULL) { + mutex_unlock(&ipclock); + return -ENOMEM; + } + mailbox = ioremap_nocache(IPC_FW_UPDATE_MBOX_ADDR, + sizeof(struct fw_update_mailbox)); + if (mailbox == NULL) { + iounmap(fw_update_base); + mutex_unlock(&ipclock); + return -ENOMEM; + } + + ipc_command(IPC_CMD_FW_UPDATE_READY); + + /* Intitialize mailbox */ + writel(0, &mailbox->status); + writel(0, &mailbox->scu_flag); + writel(0, &mailbox->driver_flag); + + /* Driver copies the 2KB MIP header to SRAM at 0xFFFC0000*/ + memcpy_toio(fw_update_base, buffer, 0x800); + + /* Driver sends "FW Update" IPC command (CMD_ID 0xFE; MSG_ID 0x02). + * Upon receiving this command, SCU will write the 2K MIP header + * from 0xFFFC0000 into NAND. + * SCU will write a status code into the Mailbox, and then set scu_flag. + */ + + ipc_command(IPC_CMD_FW_UPDATE_GO); + + /*Driver stalls until scu_flag is set */ + while (readl(&mailbox->scu_flag) != 1) { + rmb(); + mdelay(1); + } + + /* Driver checks Mailbox status. + * If the status is 'BADN', then abort (bad NAND). + * If the status is 'IPC_FW_TXLOW', then continue. + */ + while (readl(&mailbox->status) != IPC_FW_TXLOW) { + rmb(); + mdelay(10); + } + mdelay(10); + +update_retry: + if (retry_cnt > 5) + goto update_end; + + if (readl(&mailbox->status) != IPC_FW_TXLOW) + goto update_end; + buffer = buffer + 0x800; + memcpy_toio(fw_update_base, buffer, 0x20000); + writel(1, &mailbox->driver_flag); + while (readl(&mailbox->scu_flag) == 1) { + rmb(); + mdelay(1); + } + + /* check for 'BADN' */ + if (readl(&mailbox->status) == IPC_FW_UPDATE_BADN) + goto update_end; + + while (readl(&mailbox->status) != IPC_FW_TXHIGH) { + rmb(); + mdelay(10); + } + mdelay(10); + + if (readl(&mailbox->status) != IPC_FW_TXHIGH) + goto update_end; + + buffer = buffer + 0x20000; + memcpy_toio(fw_update_base, buffer, 0x20000); + writel(0, &mailbox->driver_flag); + + while (mailbox->scu_flag == 0) { + rmb(); + mdelay(1); + } + + /* check for 'BADN' */ + if (readl(&mailbox->status) == IPC_FW_UPDATE_BADN) + goto update_end; + + if (readl(&mailbox->status) == IPC_FW_TXLOW) { + ++retry_cnt; + goto update_retry; + } + +update_end: + status = readl(&mailbox->status); + + iounmap(fw_update_base); + iounmap(mailbox); + mutex_unlock(&ipclock); + + if (status == IPC_FW_UPDATE_SUCCESS) + return 0; + return -1; +} +EXPORT_SYMBOL(intel_scu_ipc_fw_update); + +/* + * Interrupt handler gets called when ioc bit of IPC_COMMAND_REG set to 1 + * When ioc bit is set to 1, caller api must wait for interrupt handler called + * which in turn unlocks the caller api. Currently this is not used + * + * This is edge triggered so we need take no action to clear anything + */ +static irqreturn_t ioc(int irq, void *dev_id) +{ + return IRQ_HANDLED; +} + +/** + * ipc_probe - probe an Intel SCU IPC + * @dev: the PCI device matching + * @id: entry in the match table + * + * Enable and install an intel SCU IPC. This appears in the PCI space + * but uses some hard coded addresses as well. + */ +static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + int err; + resource_size_t pci_resource; + + if (ipcdev.pdev) /* We support only one SCU */ + return -EBUSY; + + ipcdev.pdev = pci_dev_get(dev); + + err = pci_enable_device(dev); + if (err) + return err; + + err = pci_request_regions(dev, "intel_scu_ipc"); + if (err) + return err; + + pci_resource = pci_resource_start(dev, 0); + if (!pci_resource) + return -ENOMEM; + + if (request_irq(dev->irq, ioc, 0, "intel_scu_ipc", &ipcdev)) + return -EBUSY; + + ipcdev.ipc_base = ioremap_nocache(IPC_BASE_ADDR, IPC_MAX_ADDR); + if (!ipcdev.ipc_base) + return -ENOMEM; + + ipcdev.i2c_base = ioremap_nocache(IPC_I2C_BASE, IPC_I2C_MAX_ADDR); + if (!ipcdev.i2c_base) { + iounmap(ipcdev.ipc_base); + return -ENOMEM; + } + return 0; +} + +/** + * ipc_remove - remove a bound IPC device + * @pdev: PCI device + * + * In practice the SCU is not removable but this function is also + * called for each device on a module unload or cleanup which is the + * path that will get used. + * + * Free up the mappings and release the PCI resources + */ +static void ipc_remove(struct pci_dev *pdev) +{ + free_irq(pdev->irq, &ipcdev); + pci_release_regions(pdev); + pci_dev_put(ipcdev.pdev); + iounmap(ipcdev.ipc_base); + iounmap(ipcdev.i2c_base); + ipcdev.pdev = NULL; +} + +static const struct pci_device_id pci_ids[] = { + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080e)}, + { 0,} +}; +MODULE_DEVICE_TABLE(pci, pci_ids); + +static struct pci_driver ipc_driver = { + .name = "intel_scu_ipc", + .id_table = pci_ids, + .probe = ipc_probe, + .remove = ipc_remove, +}; + + +static int __init intel_scu_ipc_init(void) +{ + return pci_register_driver(&ipc_driver); +} + +static void __exit intel_scu_ipc_exit(void) +{ + pci_unregister_driver(&ipc_driver); +} + +MODULE_AUTHOR("Sreedhara DS "); +MODULE_DESCRIPTION("Intel SCU IPC driver"); +MODULE_LICENSE("GPL"); + +module_init(intel_scu_ipc_init); +module_exit(intel_scu_ipc_exit); -- cgit v1.2.3 From 89a7644be2c59eea443b0db2514fd42d5de909f8 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 7 May 2010 11:24:11 -0700 Subject: eeepc-wmi: depends on BACKLIGHT_CLASS_DEVICE eeepc-wmi uses backlight*() interfaces so it should depend on BACKLIGHT_CLASS_DEVICE. eeepc-wmi.c:(.text+0x2d7f54): undefined reference to `backlight_force_update' eeepc-wmi.c:(.text+0x2d8012): undefined reference to `backlight_device_register' eeepc-wmi.c:(.devinit.text+0x1c31c): undefined reference to `backlight_device_unregister' eeepc-wmi.c:(.devexit.text+0x2f8b): undefined reference to `backlight_device_unregister' Signed-off-by: Randy Dunlap Cc: stable@kernel.org --- drivers/platform/x86/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 619134151ca6..0ec796d9da1a 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -390,6 +390,7 @@ config EEEPC_WMI depends on ACPI_WMI depends on INPUT depends on EXPERIMENTAL + depends on BACKLIGHT_CLASS_DEVICE select INPUT_SPARSEKMAP ---help--- Say Y here if you want to support WMI-based hotkeys on Eee PC laptops. -- cgit v1.2.3 From 6c62673cf58516e1b82329ac90ebf3ff3f485672 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Fri, 7 May 2010 14:30:00 -0400 Subject: drivers/platform/x86: Clarify the MRST IPC driver description slightly Make it clear that this driver is only needed for embedded hardware, not PCs. Signed-off-by: Matthew Garrett --- drivers/platform/x86/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 0ec796d9da1a..3e1b8a288719 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -534,6 +534,7 @@ config INTEL_SCU_IPC default y ---help--- IPC is used to bridge the communications between kernel and SCU on - some embedded Intel x86 platforms. + some embedded Intel x86 platforms. This is not needed for PC-type + machines. endif # X86_PLATFORM_DEVICES -- cgit v1.2.3 From 8381fc35244dbdf58cfc49e04e0d7c3498c8aa03 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 6 May 2010 11:58:55 +0200 Subject: dmaengine: mpc512x: Use resource_size Use the resource_size function instead of manually calculating the resource size. This reduces the chance of introducing off-by-one errors. Signed-off-by: Tobias Klauser Signed-off-by: Dan Williams --- drivers/dma/mpc512x_dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 7a750b95303c..e41fb8b671d3 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -657,7 +657,7 @@ static int __devinit mpc_dma_probe(struct of_device *op, } regs_start = res.start; - regs_size = res.end - res.start + 1; + regs_size = resource_size(&res); if (!devm_request_mem_region(dev, regs_start, regs_size, DRV_NAME)) { dev_err(dev, "Error requesting memory region!\n"); -- cgit v1.2.3 From a5ebca4769f28ceade28ff59fcbffb8e184e599c Mon Sep 17 00:00:00 2001 From: Jonas Aaberg Date: Tue, 18 May 2010 00:41:09 +0200 Subject: DMAENGINE: DMA40 support paused channel status Support determining whether a channel is paused or not using the status function. Signed-off-by: Jonas Aaberg Signed-off-by: Linus Walleij Signed-off-by: Dan Williams --- drivers/dma/ste_dma40.c | 75 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 67 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index e4295a27672b..16a7d2b605ed 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -659,7 +659,7 @@ static void d40_config_set_event(struct d40_chan *d40c, bool do_enable) spin_unlock_irqrestore(&d40c->phy_chan->lock, flags); } -static bool d40_chan_has_events(struct d40_chan *d40c) +static u32 d40_chan_has_events(struct d40_chan *d40c) { u32 val = 0; @@ -674,7 +674,7 @@ static bool d40_chan_has_events(struct d40_chan *d40c) val = readl(d40c->base->virtbase + D40_DREG_PCBASE + d40c->phy_chan->num * D40_DREG_PCDELTA + D40_CHAN_REG_SDLNK); - return (bool) val; + return val; } static void d40_config_enable_lidx(struct d40_chan *d40c) @@ -1389,6 +1389,65 @@ static int d40_pause(struct dma_chan *chan) return res; } +static bool d40_is_paused(struct d40_chan *d40c) +{ + bool is_paused = false; + unsigned long flags; + void __iomem *active_reg; + u32 status; + u32 event; + int res; + + spin_lock_irqsave(&d40c->lock, flags); + + if (d40c->log_num == D40_PHY_CHAN) { + if (d40c->phy_chan->num % 2 == 0) + active_reg = d40c->base->virtbase + D40_DREG_ACTIVE; + else + active_reg = d40c->base->virtbase + D40_DREG_ACTIVO; + + status = (readl(active_reg) & + D40_CHAN_POS_MASK(d40c->phy_chan->num)) >> + D40_CHAN_POS(d40c->phy_chan->num); + if (status == D40_DMA_SUSPENDED || status == D40_DMA_STOP) + is_paused = true; + + goto _exit; + } + + res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); + if (res != 0) + goto _exit; + + if (d40c->dma_cfg.dir == STEDMA40_MEM_TO_PERIPH || + d40c->dma_cfg.dir == STEDMA40_MEM_TO_MEM) + event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type); + else if (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) + event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type); + else { + dev_err(&d40c->chan.dev->device, + "[%s] Unknown direction\n", __func__); + goto _exit; + } + status = d40_chan_has_events(d40c); + status = (status & D40_EVENTLINE_MASK(event)) >> + D40_EVENTLINE_POS(event); + + if (status != D40_DMA_RUN) + is_paused = true; + + /* Resume the other logical channels if any */ + if (d40_chan_has_events(d40c)) + res = d40_channel_execute_command(d40c, + D40_DMA_RUN); + +_exit: + spin_unlock_irqrestore(&d40c->lock, flags); + return is_paused; + +} + + static bool d40_tx_is_linked(struct d40_chan *d40c) { bool is_link; @@ -1980,13 +2039,13 @@ static enum dma_status d40_tx_status(struct dma_chan *chan, last_complete = d40c->completed; last_used = chan->cookie; - ret = dma_async_is_complete(cookie, last_complete, last_used); + if (d40_is_paused(d40c)) + ret = DMA_PAUSED; + else + ret = dma_async_is_complete(cookie, last_complete, last_used); - if (txstate) { - txstate->last = last_complete; - txstate->used = last_used; - txstate->residue = stedma40_residue(chan); - } + dma_set_tx_state(txstate, last_complete, last_used, + stedma40_residue(chan)); return ret; } -- cgit v1.2.3 From 4aed79b2818e7330b5d00143e4c20bc6555df91f Mon Sep 17 00:00:00 2001 From: Marcin Mielczarczyk Date: Tue, 18 May 2010 00:41:21 +0200 Subject: DMAENGINE: DMA40 fix for allocation of logical channel 0 Fix for allocation failure of logical channel when event line happens to be number 0. Signed-off-by: Marcin Mielczarczyk Signed-off-by: Linus Walleij Signed-off-by: Dan Williams --- drivers/dma/ste_dma40.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 16a7d2b605ed..81fec95312b6 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -1039,11 +1039,11 @@ static int d40_validate_conf(struct d40_chan *d40c, } static bool d40_alloc_mask_set(struct d40_phy_res *phy, bool is_src, - int log_event_line) + int log_event_line, bool is_log) { unsigned long flags; spin_lock_irqsave(&phy->lock, flags); - if (!log_event_line) { + if (!is_log) { /* Physical interrupts are masked per physical full channel */ if (phy->allocated_src == D40_ALLOC_FREE && phy->allocated_dst == D40_ALLOC_FREE) { @@ -1161,15 +1161,16 @@ static int d40_allocate_channel(struct d40_chan *d40c) /* Find physical half channel */ for (i = 0; i < d40c->base->num_phy_chans; i++) { - if (d40_alloc_mask_set(&phys[i], is_src, 0)) + if (d40_alloc_mask_set(&phys[i], is_src, + 0, is_log)) goto found_phy; } } else for (j = 0; j < d40c->base->num_phy_chans; j += 8) { int phy_num = j + event_group * 2; for (i = phy_num; i < phy_num + 2; i++) { - if (d40_alloc_mask_set(&phys[i], - is_src, 0)) + if (d40_alloc_mask_set(&phys[i], is_src, + 0, is_log)) goto found_phy; } } @@ -1193,13 +1194,13 @@ found_phy: if (is_src) { for (i = phy_num; i < phy_num + 2; i++) { if (d40_alloc_mask_set(&phys[i], is_src, - event_line)) + event_line, is_log)) goto found_log; } } else { for (i = phy_num + 1; i >= phy_num; i--) { if (d40_alloc_mask_set(&phys[i], is_src, - event_line)) + event_line, is_log)) goto found_log; } } -- cgit v1.2.3 From 8c484ee4910b36c9ac273ad1150261c6ebfc1ef7 Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Thu, 11 Mar 2010 16:47:58 +0100 Subject: drbd: use proc_create_data with explicit NULL argument To document that we know about deprecation of proc_create, even though we are not affected, as we don't use the ->data member, open code proc_create_data(..., NULL); Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 93d1f9b469d4..db7a07a9a2cf 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -3129,7 +3129,7 @@ int __init drbd_init(void) if (err) goto Enomem; - drbd_proc = proc_create("drbd", S_IFREG | S_IRUGO , NULL, &drbd_proc_fops); + drbd_proc = proc_create_data("drbd", S_IFREG | S_IRUGO , NULL, &drbd_proc_fops, NULL); if (!drbd_proc) { printk(KERN_ERR "drbd: unable to register proc file\n"); goto Enomem; -- cgit v1.2.3 From e4f925e12ea5daaa9baf2dd5af9c4951721dae95 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Wed, 17 Mar 2010 14:18:41 +0100 Subject: drbd: Do not upgrade state to Outdated if already Inconsistent [Bugz 277] There was a race condition: In a situation with a SyncSource+Primary and a SyncTarget+Secondary node, and a resync dependency to some other device. After both nodes decided to do the resync, the other device finishes its resync process. At that time SyncSource already sent the P_SYNC_UUID packet, and already updated its peer disk state to Inconsistent. The SyncTarget node waits for the P_SYNC_UUID and sends a state packet to report the resync dependency change. That packet still carries a disk state of Outdated. Impact: If application writes come in, during that time on the Primary node, those do not get replicated, and the out-of-sync counter gets increased. => The completion of resync is not detected on the primary node. => stalled. Those blocks get resync'ed with the next resync, since the are get marked as out-of-sync in the bitmap. In order to fix this, we filter out that wrong state change in the sanitize_state() function. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index db7a07a9a2cf..8f84a9f58c99 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -840,7 +840,7 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state break; case C_WF_BITMAP_S: case C_PAUSED_SYNC_S: - ns.pdsk = D_OUTDATED; + ns.pdsk = os.pdsk > D_OUTDATED ? D_OUTDATED : os.pdsk; break; case C_SYNC_SOURCE: ns.pdsk = D_INCONSISTENT; -- cgit v1.2.3 From e0f83012dc510b0be92ee2d59227a573a36777b8 Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Thu, 1 Apr 2010 15:13:19 +0200 Subject: drbd: fix regression: attach while connected failed commit e4f925e12ea5daaa9baf2dd5af9c4951721dae95 Author: Philipp Reisner Date: Wed Mar 17 14:18:41 2010 +0100 drbd: Do not upgrade state to Outdated if already Inconsistent prevented the necessary state transition for attaching while connected (Diskless -> Consistent respectively Outdated). This is the fix for the fix. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 8f84a9f58c99..b1ce5dc7c603 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -840,7 +840,12 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state break; case C_WF_BITMAP_S: case C_PAUSED_SYNC_S: - ns.pdsk = os.pdsk > D_OUTDATED ? D_OUTDATED : os.pdsk; + /* remap any consistent state to D_OUTDATED, + * but disallow "upgrade" of not even consistent states. + */ + ns.pdsk = + (D_DISKLESS < os.pdsk && os.pdsk < D_OUTDATED) + ? os.pdsk : D_OUTDATED; break; case C_SYNC_SOURCE: ns.pdsk = D_INCONSISTENT; -- cgit v1.2.3 From 8d1894ebe441093cfd967affcbc56b764960575e Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Thu, 1 Apr 2010 16:55:18 +0200 Subject: drbd: remove bogus ASSERT block_id may be ID_SYNCER, as well as checksum based resync request magic, or online verify magic. Let's just drop that ASSERT. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_receiver.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index c786023001d2..93106fb92be8 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -4233,7 +4233,6 @@ static int got_NegRSDReply(struct drbd_conf *mdev, struct p_header *h) sector = be64_to_cpu(p->sector); size = be32_to_cpu(p->blksize); - D_ASSERT(p->block_id == ID_SYNCER); update_peer_seq(mdev, be32_to_cpu(p->seq_num)); -- cgit v1.2.3 From c3470cde57ea34d9b4bd34891ec040e46b9fb3bf Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Thu, 1 Apr 2010 16:57:19 +0200 Subject: drbd: fix potential protocol error Don't forget to drain the digest in case we cannot satisfy a checksum based resync or online-verify request. It would additionally cause a protocoll error, dropping the connection. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_receiver.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 93106fb92be8..c7285e16b667 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -1331,6 +1331,9 @@ static int drbd_drain_block(struct drbd_conf *mdev, int data_size) int rr, rv = 1; void *data; + if (!data_size) + return TRUE; + page = drbd_pp_alloc(mdev, 1); data = kmap(page); @@ -1946,7 +1949,7 @@ static int receive_DataRequest(struct drbd_conf *mdev, struct p_header *h) "no local data.\n"); drbd_send_ack_rp(mdev, h->command == P_DATA_REQUEST ? P_NEG_DREPLY : P_NEG_RS_DREPLY , p); - return TRUE; + return drbd_drain_block(mdev, h->length - brps); } /* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD -- cgit v1.2.3 From 8d4ce82b3ccd755c8ba401469ced5286b1e02284 Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Thu, 1 Apr 2010 16:59:32 +0200 Subject: drbd: don't start a resync without access to up-to-date Data In case both nodes are "inconsistent", invalidate would have started a resync anyways, without a chance to ever succeed, just filling the logs with warning messages. Simply disallow that state change, re-using the SS_NO_UP_TO_DATE_DISK return value. This also changes the corresponding error string to "Need access to UpToDate Data" -- I found the "Refusing to be Primary without at least one UpToDate disk" answer misleading in some situations anyways. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_main.c | 3 +++ drivers/block/drbd/drbd_strings.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index b1ce5dc7c603..e181e405e244 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -684,6 +684,9 @@ static int is_valid_state(struct drbd_conf *mdev, union drbd_state ns) else if (ns.conn > C_CONNECTED && ns.pdsk < D_INCONSISTENT) rv = SS_NO_REMOTE_DISK; + else if (ns.conn > C_CONNECTED && ns.disk < D_UP_TO_DATE && ns.pdsk < D_UP_TO_DATE) + rv = SS_NO_UP_TO_DATE_DISK; + else if ((ns.conn == C_CONNECTED || ns.conn == C_WF_BITMAP_S || ns.conn == C_SYNC_SOURCE || diff --git a/drivers/block/drbd/drbd_strings.c b/drivers/block/drbd/drbd_strings.c index 76863e3f05be..85179e1fb50a 100644 --- a/drivers/block/drbd/drbd_strings.c +++ b/drivers/block/drbd/drbd_strings.c @@ -70,7 +70,7 @@ static const char *drbd_disk_s_names[] = { static const char *drbd_state_sw_errors[] = { [-SS_TWO_PRIMARIES] = "Multiple primaries not allowed by config", - [-SS_NO_UP_TO_DATE_DISK] = "Refusing to be Primary without at least one UpToDate disk", + [-SS_NO_UP_TO_DATE_DISK] = "Need access to UpToDate data", [-SS_NO_LOCAL_DISK] = "Can not resync without local disk", [-SS_NO_REMOTE_DISK] = "Can not resync without remote disk", [-SS_CONNECTED_OUTDATES] = "Refusing to be Outdated while Connected", -- cgit v1.2.3 From c3fe30b0e7cd67e0207097f5f39ce9626644879e Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Thu, 1 Apr 2010 09:57:40 +0200 Subject: drbd: cleanup: This code path to trigger a resync is no longer needed Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_receiver.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index c7285e16b667..c3504ddd59c1 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -2853,7 +2853,6 @@ static int receive_sizes(struct drbd_conf *mdev, struct p_header *h) unsigned int max_seg_s; sector_t p_size, p_usize, my_usize; int ldsc = 0; /* local disk size changed */ - enum drbd_conns nconn; ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE; if (drbd_recv(mdev, h->payload, h->length) != h->length) @@ -2920,22 +2919,6 @@ static int receive_sizes(struct drbd_conf *mdev, struct p_header *h) drbd_set_my_capacity(mdev, p_size); } - if (mdev->p_uuid && mdev->state.conn <= C_CONNECTED && get_ldev(mdev)) { - nconn = drbd_sync_handshake(mdev, - mdev->state.peer, mdev->state.pdsk); - put_ldev(mdev); - - if (nconn == C_MASK) { - drbd_force_state(mdev, NS(conn, C_DISCONNECTING)); - return FALSE; - } - - if (drbd_request_state(mdev, NS(conn, nconn)) < SS_SUCCESS) { - drbd_force_state(mdev, NS(conn, C_DISCONNECTING)); - return FALSE; - } - } - if (get_ldev(mdev)) { if (mdev->ldev->known_size != drbd_get_capacity(mdev->ldev->backing_bdev)) { mdev->ldev->known_size = drbd_get_capacity(mdev->ldev->backing_bdev); -- cgit v1.2.3 From 6666032ade5a758aa05380ab92f416ab8ef25005 Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Tue, 6 Apr 2010 12:15:04 +0200 Subject: drbd: check for corrupt or malicous sector addresses when receiving data Even if it should never happen if the peer does behave, we need to double check, and not even attempt access beyond end of device. It usually would be caught by lower layers, resulting in "IO error", but may also end up in the internal meta data area. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_receiver.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index c3504ddd59c1..3a36bc814e77 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -1262,6 +1262,7 @@ static int receive_Barrier(struct drbd_conf *mdev, struct p_header *h) static struct drbd_epoch_entry * read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector, int data_size) __must_hold(local) { + const sector_t capacity = drbd_get_capacity(mdev->this_bdev); struct drbd_epoch_entry *e; struct bio_vec *bvec; struct page *page; @@ -1287,6 +1288,15 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector, int data_size) __ ERR_IF(data_size & 0x1ff) return NULL; ERR_IF(data_size > DRBD_MAX_SEGMENT_SIZE) return NULL; + /* even though we trust out peer, + * we sometimes have to double check. */ + if (sector + (data_size>>9) > capacity) { + dev_err(DEV, "capacity: %llus < sector: %llus + size: %u\n", + (unsigned long long)capacity, + (unsigned long long)sector, data_size); + return NULL; + } + /* GFP_NOIO, because we must not cause arbitrary write-out: in a DRBD * "criss-cross" setup, that might cause write-out on some other DRBD, * which in turn might block on the other node at this very place. */ -- cgit v1.2.3 From 979f5c7f1f6c8a532b943defb790d43b999934eb Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Tue, 6 Apr 2010 14:15:06 +0200 Subject: drbd: fail_requests_early: remove incorrect and unnecessary optimization The condition does not fit the commend (I may well be Primary, even if I lost the disk earlier and now the connection). And this is catched below anyways, where it also gets logged. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_req.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index de81ab7b4627..d8d9bbfca3b8 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -962,11 +962,6 @@ fail_and_free_req: */ static int drbd_fail_request_early(struct drbd_conf *mdev, int is_write) { - /* Unconfigured */ - if (mdev->state.conn == C_DISCONNECTING && - mdev->state.disk == D_DISKLESS) - return 1; - if (mdev->state.role != R_PRIMARY && (!allow_oos || is_write)) { if (__ratelimit(&drbd_ratelimit_state)) { -- cgit v1.2.3 From 3a11a4878939e0e3c355bf3f52ef642a4cb6ba84 Mon Sep 17 00:00:00 2001 From: Adam Gandelman Date: Thu, 8 Apr 2010 16:48:23 -0700 Subject: drbd: New handler: initial-split-brain Some wish to be notified of all instances of split brain, not just those that go unresolved. The initial-split-brain handler is called to notify someone upon detection of all split brain conditions even if auto-recovery policies are configured. Signed-off-by: Adam Gandelman Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_receiver.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 3a36bc814e77..6876041fc3d8 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -2487,6 +2487,9 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol hg > 0 ? "source" : "target"); } + if (abs(hg) == 100) + drbd_khelper(mdev, "initial-split-brain"); + if (hg == 100 || (hg == -100 && mdev->net_conf->always_asbp)) { int pcount = (mdev->state.role == R_PRIMARY) + (peer_role == R_PRIMARY); @@ -2532,7 +2535,7 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol * after an attempted attach on a diskless node. * We just refuse to attach -- well, we drop the "connection" * to that disk, in a way... */ - dev_alert(DEV, "Split-Brain detected, dropping connection!\n"); + dev_alert(DEV, "Split-Brain detected but unresolved, dropping connection!\n"); drbd_khelper(mdev, "split-brain"); return C_MASK; } -- cgit v1.2.3 From d845030f21859dd11bcecc7e1b8575fb845eb425 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Wed, 24 Mar 2010 15:51:26 +0100 Subject: drbd: made determin_dev_size's parameter an flag enum Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_int.h | 6 +++++- drivers/block/drbd/drbd_nl.c | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index d6f1ae342b1d..f5c56f4fd2a3 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1382,8 +1382,12 @@ extern void drbd_suspend_io(struct drbd_conf *mdev); extern void drbd_resume_io(struct drbd_conf *mdev); extern char *ppsize(char *buf, unsigned long long size); extern sector_t drbd_new_dev_size(struct drbd_conf *, struct drbd_backing_dev *, int); +enum dds_flags { + DDSF_FORCED = 1, + DDSF_NO_RESYNC = 2, /* Do not run a resync for the new space */ +}; enum determine_dev_size { dev_size_error = -1, unchanged = 0, shrunk = 1, grew = 2 }; -extern enum determine_dev_size drbd_determin_dev_size(struct drbd_conf *, int force) __must_hold(local); +extern enum determine_dev_size drbd_determin_dev_size(struct drbd_conf *, enum dds_flags) __must_hold(local); extern void resync_after_online_grow(struct drbd_conf *); extern void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int) __must_hold(local); extern int drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 6429d2b19e06..97abbc2acc5c 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -510,7 +510,7 @@ void drbd_resume_io(struct drbd_conf *mdev) * Returns 0 on success, negative return values indicate errors. * You should call drbd_md_sync() after calling this function. */ -enum determine_dev_size drbd_determin_dev_size(struct drbd_conf *mdev, int force) __must_hold(local) +enum determine_dev_size drbd_determin_dev_size(struct drbd_conf *mdev, enum dds_flags flags) __must_hold(local) { sector_t prev_first_sect, prev_size; /* previous meta location */ sector_t la_size; @@ -541,7 +541,7 @@ enum determine_dev_size drbd_determin_dev_size(struct drbd_conf *mdev, int force /* TODO: should only be some assert here, not (re)init... */ drbd_md_set_sector_offsets(mdev, mdev->ldev); - size = drbd_new_dev_size(mdev, mdev->ldev, force); + size = drbd_new_dev_size(mdev, mdev->ldev, flags & DDSF_FORCED); if (drbd_get_capacity(mdev->this_bdev) != size || drbd_bm_capacity(mdev) != size) { @@ -1508,7 +1508,7 @@ static int drbd_nl_resize(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, } mdev->ldev->dc.disk_size = (sector_t)rs.resize_size; - dd = drbd_determin_dev_size(mdev, rs.resize_force); + dd = drbd_determin_dev_size(mdev, rs.resize_force ? DDSF_FORCED : 0); drbd_md_sync(mdev); put_ldev(mdev); if (dd == dev_size_error) { -- cgit v1.2.3 From 02d9a94bbb0d4e0fec8db6735bdc4ccfaac8f0ce Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Wed, 24 Mar 2010 16:23:03 +0100 Subject: drbd: Implemented the set_new_bits parameter for drbd_bm_resize() Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_bitmap.c | 10 +++++++--- drivers/block/drbd/drbd_int.h | 2 +- drivers/block/drbd/drbd_main.c | 2 +- drivers/block/drbd/drbd_nl.c | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index 3390716898d5..695fb64cba00 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c @@ -441,7 +441,7 @@ static void bm_memset(struct drbd_bitmap *b, size_t offset, int c, size_t len) * In case this is actually a resize, we copy the old bitmap into the new one. * Otherwise, the bitmap is initialized to all bits set. */ -int drbd_bm_resize(struct drbd_conf *mdev, sector_t capacity) +int drbd_bm_resize(struct drbd_conf *mdev, sector_t capacity, int set_new_bits) { struct drbd_bitmap *b = mdev->bitmap; unsigned long bits, words, owords, obits, *p_addr, *bm; @@ -526,8 +526,12 @@ int drbd_bm_resize(struct drbd_conf *mdev, sector_t capacity) b->bm_dev_capacity = capacity; if (growing) { - bm_memset(b, owords, 0xff, words-owords); - b->bm_set += bits - obits; + if (set_new_bits) { + bm_memset(b, owords, 0xff, words-owords); + b->bm_set += bits - obits; + } else + bm_memset(b, owords, 0x00, words-owords); + } if (want < have) { diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index f5c56f4fd2a3..37a25a6084dd 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1311,7 +1311,7 @@ struct bm_extent { #define APP_R_HSIZE 15 extern int drbd_bm_init(struct drbd_conf *mdev); -extern int drbd_bm_resize(struct drbd_conf *mdev, sector_t sectors); +extern int drbd_bm_resize(struct drbd_conf *mdev, sector_t sectors, int set_new_bits); extern void drbd_bm_cleanup(struct drbd_conf *mdev); extern void drbd_bm_set_all(struct drbd_conf *mdev); extern void drbd_bm_clear_all(struct drbd_conf *mdev); diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index e181e405e244..65c2a65d3d64 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2688,7 +2688,7 @@ void drbd_mdev_cleanup(struct drbd_conf *mdev) drbd_set_my_capacity(mdev, 0); if (mdev->bitmap) { /* maybe never allocated. */ - drbd_bm_resize(mdev, 0); + drbd_bm_resize(mdev, 0, 1); drbd_bm_cleanup(mdev); } diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 97abbc2acc5c..360e506426b0 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -546,7 +546,7 @@ enum determine_dev_size drbd_determin_dev_size(struct drbd_conf *mdev, enum dds_ if (drbd_get_capacity(mdev->this_bdev) != size || drbd_bm_capacity(mdev) != size) { int err; - err = drbd_bm_resize(mdev, size); + err = drbd_bm_resize(mdev, size, !(flags & DDSF_NO_RESYNC)); if (unlikely(err)) { /* currently there is only one error: ENOMEM! */ size = drbd_bm_capacity(mdev)>>1; -- cgit v1.2.3 From e89b591c3aba0af87f5248b15f56ce7a4f439c16 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Wed, 24 Mar 2010 17:11:33 +0100 Subject: drbd: Implemented flags for the resize packet Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_int.h | 14 ++++++++------ drivers/block/drbd/drbd_main.c | 8 ++++---- drivers/block/drbd/drbd_nl.c | 2 +- drivers/block/drbd/drbd_receiver.c | 19 ++++++++++++------- 4 files changed, 25 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 37a25a6084dd..e09132483980 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -481,7 +481,8 @@ struct p_sizes { u64 u_size; /* user requested size */ u64 c_size; /* current exported size */ u32 max_segment_size; /* Maximal size of a BIO */ - u32 queue_order_type; + u16 queue_order_type; /* not yet implemented in DRBD*/ + u16 dds_flags; /* use enum dds_flags here. */ } __packed; struct p_state { @@ -1081,6 +1082,11 @@ enum chg_state_flags { CS_ORDERED = CS_WAIT_COMPLETE + CS_SERIALIZE, }; +enum dds_flags { + DDSF_FORCED = 1, + DDSF_NO_RESYNC = 2, /* Do not run a resync for the new space */ +}; + extern void drbd_init_set_defaults(struct drbd_conf *mdev); extern int drbd_change_state(struct drbd_conf *mdev, enum chg_state_flags f, union drbd_state mask, union drbd_state val); @@ -1113,7 +1119,7 @@ extern int drbd_send_protocol(struct drbd_conf *mdev); extern int drbd_send_uuids(struct drbd_conf *mdev); extern int drbd_send_uuids_skip_initial_sync(struct drbd_conf *mdev); extern int drbd_send_sync_uuid(struct drbd_conf *mdev, u64 val); -extern int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply); +extern int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_flags flags); extern int _drbd_send_state(struct drbd_conf *mdev); extern int drbd_send_state(struct drbd_conf *mdev); extern int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock, @@ -1382,10 +1388,6 @@ extern void drbd_suspend_io(struct drbd_conf *mdev); extern void drbd_resume_io(struct drbd_conf *mdev); extern char *ppsize(char *buf, unsigned long long size); extern sector_t drbd_new_dev_size(struct drbd_conf *, struct drbd_backing_dev *, int); -enum dds_flags { - DDSF_FORCED = 1, - DDSF_NO_RESYNC = 2, /* Do not run a resync for the new space */ -}; enum determine_dev_size { dev_size_error = -1, unchanged = 0, shrunk = 1, grew = 2 }; extern enum determine_dev_size drbd_determin_dev_size(struct drbd_conf *, enum dds_flags) __must_hold(local); extern void resync_after_online_grow(struct drbd_conf *); diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 65c2a65d3d64..a478dad82dae 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -1240,7 +1240,7 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, os.disk == D_ATTACHING && ns.disk == D_NEGOTIATING) { kfree(mdev->p_uuid); /* We expect to receive up-to-date UUIDs soon. */ mdev->p_uuid = NULL; /* ...to not use the old ones in the mean time */ - drbd_send_sizes(mdev, 0); /* to start sync... */ + drbd_send_sizes(mdev, 0, 0); /* to start sync... */ drbd_send_uuids(mdev); drbd_send_state(mdev); } @@ -1763,7 +1763,7 @@ int drbd_send_sync_uuid(struct drbd_conf *mdev, u64 val) (struct p_header *)&p, sizeof(p)); } -int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply) +int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply, enum dds_flags flags) { struct p_sizes p; sector_t d_size, u_size; @@ -1775,7 +1775,6 @@ int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply) d_size = drbd_get_max_capacity(mdev->ldev); u_size = mdev->ldev->dc.disk_size; q_order_type = drbd_queue_order_type(mdev); - p.queue_order_type = cpu_to_be32(drbd_queue_order_type(mdev)); put_ldev(mdev); } else { d_size = 0; @@ -1787,7 +1786,8 @@ int drbd_send_sizes(struct drbd_conf *mdev, int trigger_reply) p.u_size = cpu_to_be64(u_size); p.c_size = cpu_to_be64(trigger_reply ? 0 : drbd_get_capacity(mdev->this_bdev)); p.max_segment_size = cpu_to_be32(queue_max_segment_size(mdev->rq_queue)); - p.queue_order_type = cpu_to_be32(q_order_type); + p.queue_order_type = cpu_to_be16(q_order_type); + p.dds_flags = cpu_to_be16(flags); ok = drbd_send_cmd(mdev, USE_DATA_SOCKET, P_SIZES, (struct p_header *)&p, sizeof(p)); diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 360e506426b0..6f7933376a11 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -1521,7 +1521,7 @@ static int drbd_nl_resize(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, set_bit(RESIZE_PENDING, &mdev->flags); drbd_send_uuids(mdev); - drbd_send_sizes(mdev, 1); + drbd_send_sizes(mdev, 1, 0); } fail: diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 6876041fc3d8..11b1bafde28b 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -902,7 +902,7 @@ retry: if (!drbd_send_protocol(mdev)) return -1; drbd_send_sync_param(mdev, &mdev->sync_conf); - drbd_send_sizes(mdev, 0); + drbd_send_sizes(mdev, 0, 0); drbd_send_uuids(mdev); drbd_send_state(mdev); clear_bit(USE_DEGR_WFC_T, &mdev->flags); @@ -2866,6 +2866,7 @@ static int receive_sizes(struct drbd_conf *mdev, struct p_header *h) unsigned int max_seg_s; sector_t p_size, p_usize, my_usize; int ldsc = 0; /* local disk size changed */ + enum dds_flags ddsf; ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE; if (drbd_recv(mdev, h->payload, h->length) != h->length) @@ -2921,8 +2922,9 @@ static int receive_sizes(struct drbd_conf *mdev, struct p_header *h) } #undef min_not_zero + ddsf = be16_to_cpu(p->dds_flags); if (get_ldev(mdev)) { - dd = drbd_determin_dev_size(mdev, 0); + dd = drbd_determin_dev_size(mdev, ddsf); put_ldev(mdev); if (dd == dev_size_error) return FALSE; @@ -2942,7 +2944,7 @@ static int receive_sizes(struct drbd_conf *mdev, struct p_header *h) if (max_seg_s != queue_max_segment_size(mdev->rq_queue)) drbd_setup_queue_param(mdev, max_seg_s); - drbd_setup_order_type(mdev, be32_to_cpu(p->queue_order_type)); + drbd_setup_order_type(mdev, be16_to_cpu(p->queue_order_type)); put_ldev(mdev); } @@ -2951,14 +2953,17 @@ static int receive_sizes(struct drbd_conf *mdev, struct p_header *h) drbd_get_capacity(mdev->this_bdev) || ldsc) { /* we have different sizes, probably peer * needs to know my new size... */ - drbd_send_sizes(mdev, 0); + drbd_send_sizes(mdev, 0, ddsf); } if (test_and_clear_bit(RESIZE_PENDING, &mdev->flags) || (dd == grew && mdev->state.conn == C_CONNECTED)) { if (mdev->state.pdsk >= D_INCONSISTENT && - mdev->state.disk >= D_INCONSISTENT) - resync_after_online_grow(mdev); - else + mdev->state.disk >= D_INCONSISTENT) { + if (ddsf & DDSF_NO_RESYNC) + dev_info(DEV, "Resync of new storage suppressed with --assume-clean\n"); + else + resync_after_online_grow(mdev); + } else set_bit(RESYNC_AFTER_NEG, &mdev->flags); } } -- cgit v1.2.3 From fd76438c2421324fa2fb9303e760ec5332ff0b58 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Thu, 1 Apr 2010 09:57:40 +0200 Subject: drbd: Make sure to resync all of the new storage upon online resize Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_bitmap.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index 695fb64cba00..178cf1642b2d 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c @@ -84,6 +84,9 @@ struct drbd_bitmap { #define BM_MD_IO_ERROR 1 #define BM_P_VMALLOCED 2 +int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, + unsigned long e, int val, const enum km_type km); + static int bm_is_locked(struct drbd_bitmap *b) { return test_bit(BM_LOCKED, &b->bm_flags); @@ -529,6 +532,9 @@ int drbd_bm_resize(struct drbd_conf *mdev, sector_t capacity, int set_new_bits) if (set_new_bits) { bm_memset(b, owords, 0xff, words-owords); b->bm_set += bits - obits; + __bm_change_bits_to(mdev, obits, + ALIGN(obits, BITS_PER_LONG), + 1, KM_IRQ1); } else bm_memset(b, owords, 0x00, words-owords); -- cgit v1.2.3 From b4ee79dac3bddc468e21cae0deb00b80ec4ac051 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Thu, 1 Apr 2010 09:57:40 +0200 Subject: drbd: Added some missing statics Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_bitmap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index 178cf1642b2d..aa7e23cf7e22 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c @@ -84,7 +84,7 @@ struct drbd_bitmap { #define BM_MD_IO_ERROR 1 #define BM_P_VMALLOCED 2 -int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, +static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, unsigned long e, int val, const enum km_type km); static int bm_is_locked(struct drbd_bitmap *b) @@ -783,7 +783,7 @@ static void bm_page_io_async(struct drbd_conf *mdev, struct drbd_bitmap *b, int /* nothing to do, on disk == in memory */ # define bm_cpu_to_lel(x) ((void)0) # else -void bm_cpu_to_lel(struct drbd_bitmap *b) +static void bm_cpu_to_lel(struct drbd_bitmap *b) { /* need to cpu_to_lel all the pages ... * this may be optimized by using @@ -1025,7 +1025,7 @@ unsigned long _drbd_bm_find_next_zero(struct drbd_conf *mdev, unsigned long bm_f * wants bitnr, not sector. * expected to be called for only a few bits (e - s about BITS_PER_LONG). * Must hold bitmap lock already. */ -int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, +static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, unsigned long e, int val, const enum km_type km) { struct drbd_bitmap *b = mdev->bitmap; @@ -1063,7 +1063,7 @@ int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, * for val != 0, we change 0 -> 1, return code positive * for val == 0, we change 1 -> 0, return code negative * wants bitnr, not sector */ -int bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, +static int bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, const unsigned long e, int val) { unsigned long flags; -- cgit v1.2.3 From 6495d2c6d04f4c45411fdb1b40527c24015f39d6 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Wed, 24 Mar 2010 16:07:04 +0100 Subject: drbd: Implemented the --assume-clean option for drbdsetup resize Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_nl.c | 11 +++++++++-- include/linux/drbd.h | 3 ++- include/linux/drbd_nl.h | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 6f7933376a11..19b9a2851e7b 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -1479,6 +1479,7 @@ static int drbd_nl_resize(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, int retcode = NO_ERROR; int ldsc = 0; /* local disk size changed */ enum determine_dev_size dd; + enum dds_flags ddsf; memset(&rs, 0, sizeof(struct resize)); if (!resize_from_tags(mdev, nlp->tag_list, &rs)) { @@ -1502,13 +1503,19 @@ static int drbd_nl_resize(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, goto fail; } + if (rs.no_resync && mdev->agreed_pro_version < 93) { + retcode = ERR_NEED_APV_93; + goto fail; + } + if (mdev->ldev->known_size != drbd_get_capacity(mdev->ldev->backing_bdev)) { mdev->ldev->known_size = drbd_get_capacity(mdev->ldev->backing_bdev); ldsc = 1; } mdev->ldev->dc.disk_size = (sector_t)rs.resize_size; - dd = drbd_determin_dev_size(mdev, rs.resize_force ? DDSF_FORCED : 0); + ddsf = (rs.resize_force ? DDSF_FORCED : 0) | (rs.no_resync ? DDSF_NO_RESYNC : 0); + dd = drbd_determin_dev_size(mdev, ddsf); drbd_md_sync(mdev); put_ldev(mdev); if (dd == dev_size_error) { @@ -1521,7 +1528,7 @@ static int drbd_nl_resize(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, set_bit(RESIZE_PENDING, &mdev->flags); drbd_send_uuids(mdev); - drbd_send_sizes(mdev, 1, 0); + drbd_send_sizes(mdev, 1, ddsf); } fail: diff --git a/include/linux/drbd.h b/include/linux/drbd.h index 4341b1a97a34..7944dd36ee3e 100644 --- a/include/linux/drbd.h +++ b/include/linux/drbd.h @@ -56,7 +56,7 @@ extern const char *drbd_buildtag(void); #define REL_VERSION "8.3.7" #define API_VERSION 88 #define PRO_VERSION_MIN 86 -#define PRO_VERSION_MAX 92 +#define PRO_VERSION_MAX 93 enum drbd_io_error_p { @@ -139,6 +139,7 @@ enum drbd_ret_codes { ERR_DATA_NOT_CURRENT = 150, ERR_CONNECTED = 151, /* DRBD 8.3 only */ ERR_PERM = 152, + ERR_NEED_APV_93 = 153, /* insert new ones above this line */ AFTER_LAST_ERR_CODE diff --git a/include/linux/drbd_nl.h b/include/linux/drbd_nl.h index f7431a4ca608..de055c07c2ba 100644 --- a/include/linux/drbd_nl.h +++ b/include/linux/drbd_nl.h @@ -71,6 +71,7 @@ NL_PACKET(disconnect, 6, ) NL_PACKET(resize, 7, NL_INT64( 29, T_MAY_IGNORE, resize_size) NL_BIT( 68, T_MAY_IGNORE, resize_force) + NL_BIT( 69, T_MANDATORY, no_resync) ) NL_PACKET(syncer_conf, 8, -- cgit v1.2.3 From 087c24925cf4209be1a91f8ede9241e17e9734c7 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Fri, 26 Mar 2010 13:49:56 +0100 Subject: drbd: bugfix: Make resize work, if remote's size was limiting and increased in the meantime Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_nl.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 19b9a2851e7b..6cb703686b28 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -1477,7 +1477,6 @@ static int drbd_nl_resize(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, { struct resize rs; int retcode = NO_ERROR; - int ldsc = 0; /* local disk size changed */ enum determine_dev_size dd; enum dds_flags ddsf; @@ -1508,10 +1507,8 @@ static int drbd_nl_resize(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, goto fail; } - if (mdev->ldev->known_size != drbd_get_capacity(mdev->ldev->backing_bdev)) { + if (mdev->ldev->known_size != drbd_get_capacity(mdev->ldev->backing_bdev)) mdev->ldev->known_size = drbd_get_capacity(mdev->ldev->backing_bdev); - ldsc = 1; - } mdev->ldev->dc.disk_size = (sector_t)rs.resize_size; ddsf = (rs.resize_force ? DDSF_FORCED : 0) | (rs.no_resync ? DDSF_NO_RESYNC : 0); @@ -1523,7 +1520,7 @@ static int drbd_nl_resize(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, goto fail; } - if (mdev->state.conn == C_CONNECTED && (dd != unchanged || ldsc)) { + if (mdev->state.conn == C_CONNECTED) { if (dd == grew) set_bit(RESIZE_PENDING, &mdev->flags); -- cgit v1.2.3 From 6b4388ac1f282515db3a651707238cad00b50e80 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Mon, 26 Apr 2010 14:11:45 +0200 Subject: drbd: Added transmission faults to the fault injection code Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_int.h | 1 + drivers/block/drbd/drbd_main.c | 3 ++- drivers/block/drbd/drbd_receiver.c | 8 +++++++- 3 files changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index e09132483980..2409de12f013 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -132,6 +132,7 @@ enum { DRBD_FAULT_DT_RA = 6, /* data read ahead */ DRBD_FAULT_BM_ALLOC = 7, /* bitmap allocation */ DRBD_FAULT_AL_EE = 8, /* alloc ee */ + DRBD_FAULT_RECEIVE = 9, /* Changes some bytes upon receiving a [rs]data block */ DRBD_FAULT_MAX, }; diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index a478dad82dae..7468d2ce7347 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -3668,7 +3668,8 @@ _drbd_fault_str(unsigned int type) { [DRBD_FAULT_DT_RD] = "Data read", [DRBD_FAULT_DT_RA] = "Data read ahead", [DRBD_FAULT_BM_ALLOC] = "BM allocation", - [DRBD_FAULT_AL_EE] = "EE allocation" + [DRBD_FAULT_AL_EE] = "EE allocation", + [DRBD_FAULT_RECEIVE] = "receive data corruption", }; return (type < DRBD_FAULT_MAX) ? _faults[type] : "**Unknown**"; diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 11b1bafde28b..b27f4dd36f89 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -1270,6 +1270,7 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector, int data_size) __ int dgs, ds, i, rr; void *dig_in = mdev->int_dig_in; void *dig_vv = mdev->int_dig_vv; + unsigned long *data; dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_r_tfm) ? crypto_hash_digestsize(mdev->integrity_r_tfm) : 0; @@ -1307,7 +1308,12 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector, int data_size) __ ds = data_size; bio_for_each_segment(bvec, bio, i) { page = bvec->bv_page; - rr = drbd_recv(mdev, kmap(page), min_t(int, ds, PAGE_SIZE)); + data = kmap(page); + rr = drbd_recv(mdev, data, min_t(int, ds, PAGE_SIZE)); + if (FAULT_ACTIVE(mdev, DRBD_FAULT_RECEIVE)) { + dev_err(DEV, "Fault injection: Corrupting data on receive\n"); + data[0] = data[0] ^ (unsigned long)-1; + } kunmap(page); if (rr != min_t(int, ds, PAGE_SIZE)) { drbd_free_ee(mdev, e); -- cgit v1.2.3 From 5223671bb0315d83f9ad7becbbb9e703aa735bbe Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Wed, 28 Apr 2010 14:46:57 +0200 Subject: drbd: Fixed bitmap in case of online-grow without resync The "surplus" bits of the old (smaller) bitmap must be clean in case of online-grow without resync. Note: Reverted 67ae8b80d4a116ab3b7094eb3723506b20c06dff as well, since the lines added by this patch are redundant. The bits get set by the bm_set_surplus(b) call before that. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_bitmap.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index aa7e23cf7e22..e3f88d6e1412 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c @@ -519,7 +519,7 @@ int drbd_bm_resize(struct drbd_conf *mdev, sector_t capacity, int set_new_bits) obits = b->bm_bits; growing = bits > obits; - if (opages) + if (opages && growing && set_new_bits) bm_set_surplus(b); b->bm_pages = npages; @@ -532,9 +532,6 @@ int drbd_bm_resize(struct drbd_conf *mdev, sector_t capacity, int set_new_bits) if (set_new_bits) { bm_memset(b, owords, 0xff, words-owords); b->bm_set += bits - obits; - __bm_change_bits_to(mdev, obits, - ALIGN(obits, BITS_PER_LONG), - 1, KM_IRQ1); } else bm_memset(b, owords, 0x00, words-owords); -- cgit v1.2.3 From 0ced55a3bed25b0e30dcb3c7dce9634ce3c60cf2 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Fri, 30 Apr 2010 15:26:20 +0200 Subject: drbd: Receiving of delay_probes Delay_probes are new packets in the DRBD protocol, which allow DRBD to know the current delay packets have on the data socket. (relative to the meta data socket) Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_int.h | 20 +++++++- drivers/block/drbd/drbd_main.c | 3 ++ drivers/block/drbd/drbd_receiver.c | 96 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 2409de12f013..fd7615f1e526 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -209,8 +209,11 @@ enum drbd_packets { P_RS_IS_IN_SYNC = 0x22, /* meta socket */ P_SYNC_PARAM89 = 0x23, /* data socket, protocol version 89 replacement for P_SYNC_PARAM */ P_COMPRESSED_BITMAP = 0x24, /* compressed or otherwise encoded bitmap transfer */ + /* P_CKPT_FENCE_REQ = 0x25, * currently reserved for protocol D */ + /* P_CKPT_DISABLE_REQ = 0x26, * currently reserved for protocol D */ + P_DELAY_PROBE = 0x27, /* is used on BOTH sockets */ - P_MAX_CMD = 0x25, + P_MAX_CMD = 0x28, P_MAY_IGNORE = 0x100, /* Flag to test if (cmd > P_MAY_IGNORE) ... */ P_MAX_OPT_CMD = 0x101, @@ -540,6 +543,18 @@ struct p_compressed_bm { u8 code[0]; } __packed; +struct p_delay_probe { + struct p_header head; + u32 seq_num; /* sequence number to match the two probe packets */ + u32 offset; /* usecs the probe got sent after the reference time point */ +} __packed; + +struct delay_probe { + struct list_head list; + int seq_num; + struct timeval time; +}; + /* DCBP: Drbd Compressed Bitmap Packet ... */ static inline enum drbd_bitmap_code DCBP_get_code(struct p_compressed_bm *p) @@ -1028,6 +1043,9 @@ struct drbd_conf { u64 ed_uuid; /* UUID of the exposed data */ struct mutex state_mutex; char congestion_reason; /* Why we where congested... */ + struct list_head delay_probes; /* protected by peer_seq_lock */ + int data_delay; /* Delay of packets on the data-sock behind meta-sock */ + atomic_t delay_seq; /* To generate sequence numbers of delay probes */ }; static inline struct drbd_conf *minor_to_mdev(unsigned int minor) diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 7468d2ce7347..3d5fe307a19d 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2608,6 +2608,7 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) atomic_set(&mdev->net_cnt, 0); atomic_set(&mdev->packet_seq, 0); atomic_set(&mdev->pp_in_use, 0); + atomic_set(&mdev->delay_seq, 0); mutex_init(&mdev->md_io_mutex); mutex_init(&mdev->data.mutex); @@ -2636,6 +2637,8 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) INIT_LIST_HEAD(&mdev->unplug_work.list); INIT_LIST_HEAD(&mdev->md_sync_work.list); INIT_LIST_HEAD(&mdev->bm_io_work.w.list); + INIT_LIST_HEAD(&mdev->delay_probes); + mdev->resync_work.cb = w_resync_inactive; mdev->unplug_work.cb = w_send_write_hint; mdev->md_sync_work.cb = w_md_sync; diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index b27f4dd36f89..fee0d249adf7 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -3501,6 +3501,92 @@ static int receive_UnplugRemote(struct drbd_conf *mdev, struct p_header *h) return TRUE; } +static void timeval_sub_us(struct timeval* tv, unsigned int us) +{ + tv->tv_sec -= us / 1000000; + us = us % 1000000; + if (tv->tv_usec > us) { + tv->tv_usec += 1000000; + tv->tv_sec--; + } + tv->tv_usec -= us; +} + +static void got_delay_probe(struct drbd_conf *mdev, int from, struct p_delay_probe *p) +{ + struct delay_probe *dp; + struct list_head *le; + struct timeval now; + int seq_num; + int offset; + int data_delay; + + seq_num = be32_to_cpu(p->seq_num); + offset = be32_to_cpu(p->offset); + + spin_lock(&mdev->peer_seq_lock); + if (!list_empty(&mdev->delay_probes)) { + if (from == USE_DATA_SOCKET) + le = mdev->delay_probes.next; + else + le = mdev->delay_probes.prev; + + dp = list_entry(le, struct delay_probe, list); + + if (dp->seq_num == seq_num) { + list_del(le); + spin_unlock(&mdev->peer_seq_lock); + do_gettimeofday(&now); + timeval_sub_us(&now, offset); + data_delay = + now.tv_usec - dp->time.tv_usec + + (now.tv_sec - dp->time.tv_sec) * 1000000; + + if (data_delay > 0) + mdev->data_delay = data_delay; + + kfree(dp); + return; + } + + if (dp->seq_num > seq_num) { + spin_unlock(&mdev->peer_seq_lock); + dev_warn(DEV, "Previous allocation failure of struct delay_probe?\n"); + return; /* Do not alloca a struct delay_probe.... */ + } + } + spin_unlock(&mdev->peer_seq_lock); + + dp = kmalloc(sizeof(struct delay_probe), GFP_NOIO); + if (!dp) { + dev_warn(DEV, "Failed to allocate a struct delay_probe, do not worry.\n"); + return; + } + + dp->seq_num = seq_num; + do_gettimeofday(&dp->time); + timeval_sub_us(&dp->time, offset); + + spin_lock(&mdev->peer_seq_lock); + if (from == USE_DATA_SOCKET) + list_add(&dp->list, &mdev->delay_probes); + else + list_add_tail(&dp->list, &mdev->delay_probes); + spin_unlock(&mdev->peer_seq_lock); +} + +static int receive_delay_probe(struct drbd_conf *mdev, struct p_header *h) +{ + struct p_delay_probe *p = (struct p_delay_probe *)h; + + ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE; + if (drbd_recv(mdev, h->payload, h->length) != h->length) + return FALSE; + + got_delay_probe(mdev, USE_DATA_SOCKET, p); + return TRUE; +} + typedef int (*drbd_cmd_handler_f)(struct drbd_conf *, struct p_header *); static drbd_cmd_handler_f drbd_default_handler[] = { @@ -3524,6 +3610,7 @@ static drbd_cmd_handler_f drbd_default_handler[] = { [P_OV_REQUEST] = receive_DataRequest, [P_OV_REPLY] = receive_DataRequest, [P_CSUM_RS_REQUEST] = receive_DataRequest, + [P_DELAY_PROBE] = receive_delay_probe, /* anything missing from this table is in * the asender_tbl, see get_asender_cmd */ [P_MAX_CMD] = NULL, @@ -4300,6 +4387,14 @@ static int got_OVResult(struct drbd_conf *mdev, struct p_header *h) return TRUE; } +static int got_delay_probe_m(struct drbd_conf *mdev, struct p_header *h) +{ + struct p_delay_probe *p = (struct p_delay_probe *)h; + + got_delay_probe(mdev, USE_META_SOCKET, p); + return TRUE; +} + struct asender_cmd { size_t pkt_size; int (*process)(struct drbd_conf *mdev, struct p_header *h); @@ -4324,6 +4419,7 @@ static struct asender_cmd *get_asender_cmd(int cmd) [P_BARRIER_ACK] = { sizeof(struct p_barrier_ack), got_BarrierAck }, [P_STATE_CHG_REPLY] = { sizeof(struct p_req_state_reply), got_RqSReply }, [P_RS_IS_IN_SYNC] = { sizeof(struct p_block_ack), got_IsInSync }, + [P_DELAY_PROBE] = { sizeof(struct p_delay_probe), got_delay_probe_m }, [P_MAX_CMD] = { 0, NULL }, }; if (cmd > P_MAX_CMD || asender_tbl[cmd].process == NULL) -- cgit v1.2.3 From 7237bc430f49de1145d761c4b39f2ebae58842d5 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Mon, 3 May 2010 15:10:47 +0200 Subject: drbd: Sending of delay_probes Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_int.h | 1 + drivers/block/drbd/drbd_main.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index fd7615f1e526..3e4d8b574fef 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1046,6 +1046,7 @@ struct drbd_conf { struct list_head delay_probes; /* protected by peer_seq_lock */ int data_delay; /* Delay of packets on the data-sock behind meta-sock */ atomic_t delay_seq; /* To generate sequence numbers of delay probes */ + struct timeval dps_time; /* delay-probes-start-time */ }; static inline struct drbd_conf *minor_to_mdev(unsigned int minor) diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 3d5fe307a19d..710bfebb7b63 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2188,6 +2188,39 @@ int drbd_send_ov_request(struct drbd_conf *mdev, sector_t sector, int size) return ok; } +static int drbd_send_delay_probe(struct drbd_conf *mdev, struct drbd_socket *ds) +{ + struct p_delay_probe dp; + int offset, ok = 0; + struct timeval now; + + mutex_lock(&ds->mutex); + if (likely(ds->socket)) { + do_gettimeofday(&now); + offset = now.tv_usec - mdev->dps_time.tv_usec + + (now.tv_sec - mdev->dps_time.tv_sec) * 1000000; + dp.seq_num = cpu_to_be32(atomic_read(&mdev->delay_seq)); + dp.offset = cpu_to_be32(offset); + + ok = _drbd_send_cmd(mdev, ds->socket, P_DELAY_PROBE, + (struct p_header *)&dp, sizeof(dp), 0); + } + mutex_unlock(&ds->mutex); + + return ok; +} + +static int drbd_send_dalay_probes(struct drbd_conf *mdev) +{ + int ok; + atomic_inc(&mdev->delay_seq); + do_gettimeofday(&mdev->dps_time); + ok = drbd_send_delay_probe(mdev, &mdev->meta); + ok = ok && drbd_send_delay_probe(mdev, &mdev->data); + + return ok; +} + /* called on sndtimeo * returns FALSE if we should retry, * TRUE if we think connection is dead -- cgit v1.2.3 From caa20d974c86af496b419eef70010e63b7fab7ac Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 17 May 2010 16:24:16 -0700 Subject: async_tx: trim dma_async_tx_descriptor in 'no channel switch' case Saves 24 bytes per descriptor (64-bit) when the channel-switching capabilities of async_tx are not required. Signed-off-by: Dan Williams --- crypto/async_tx/async_tx.c | 46 +++++++++++++++-------------------- drivers/dma/dmaengine.c | 16 +++++++------ include/linux/dmaengine.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/crypto/async_tx/async_tx.c b/crypto/async_tx/async_tx.c index f9cdf04fe7c0..7f2c00a45205 100644 --- a/crypto/async_tx/async_tx.c +++ b/crypto/async_tx/async_tx.c @@ -81,18 +81,13 @@ async_tx_channel_switch(struct dma_async_tx_descriptor *depend_tx, struct dma_device *device = chan->device; struct dma_async_tx_descriptor *intr_tx = (void *) ~0; - #ifdef CONFIG_ASYNC_TX_DISABLE_CHANNEL_SWITCH - BUG(); - #endif - /* first check to see if we can still append to depend_tx */ - spin_lock_bh(&depend_tx->lock); - if (depend_tx->parent && depend_tx->chan == tx->chan) { - tx->parent = depend_tx; - depend_tx->next = tx; + txd_lock(depend_tx); + if (txd_parent(depend_tx) && depend_tx->chan == tx->chan) { + txd_chain(depend_tx, tx); intr_tx = NULL; } - spin_unlock_bh(&depend_tx->lock); + txd_unlock(depend_tx); /* attached dependency, flush the parent channel */ if (!intr_tx) { @@ -111,24 +106,22 @@ async_tx_channel_switch(struct dma_async_tx_descriptor *depend_tx, if (intr_tx) { intr_tx->callback = NULL; intr_tx->callback_param = NULL; - tx->parent = intr_tx; - /* safe to set ->next outside the lock since we know we are + /* safe to chain outside the lock since we know we are * not submitted yet */ - intr_tx->next = tx; + txd_chain(intr_tx, tx); /* check if we need to append */ - spin_lock_bh(&depend_tx->lock); - if (depend_tx->parent) { - intr_tx->parent = depend_tx; - depend_tx->next = intr_tx; + txd_lock(depend_tx); + if (txd_parent(depend_tx)) { + txd_chain(depend_tx, intr_tx); async_tx_ack(intr_tx); intr_tx = NULL; } - spin_unlock_bh(&depend_tx->lock); + txd_unlock(depend_tx); if (intr_tx) { - intr_tx->parent = NULL; + txd_clear_parent(intr_tx); intr_tx->tx_submit(intr_tx); async_tx_ack(intr_tx); } @@ -176,21 +169,20 @@ async_tx_submit(struct dma_chan *chan, struct dma_async_tx_descriptor *tx, * 2/ dependencies are 1:1 i.e. two transactions can * not depend on the same parent */ - BUG_ON(async_tx_test_ack(depend_tx) || depend_tx->next || - tx->parent); + BUG_ON(async_tx_test_ack(depend_tx) || txd_next(depend_tx) || + txd_parent(tx)); /* the lock prevents async_tx_run_dependencies from missing * the setting of ->next when ->parent != NULL */ - spin_lock_bh(&depend_tx->lock); - if (depend_tx->parent) { + txd_lock(depend_tx); + if (txd_parent(depend_tx)) { /* we have a parent so we can not submit directly * if we are staying on the same channel: append * else: channel switch */ if (depend_tx->chan == chan) { - tx->parent = depend_tx; - depend_tx->next = tx; + txd_chain(depend_tx, tx); s = ASYNC_TX_SUBMITTED; } else s = ASYNC_TX_CHANNEL_SWITCH; @@ -203,7 +195,7 @@ async_tx_submit(struct dma_chan *chan, struct dma_async_tx_descriptor *tx, else s = ASYNC_TX_CHANNEL_SWITCH; } - spin_unlock_bh(&depend_tx->lock); + txd_unlock(depend_tx); switch (s) { case ASYNC_TX_SUBMITTED: @@ -212,12 +204,12 @@ async_tx_submit(struct dma_chan *chan, struct dma_async_tx_descriptor *tx, async_tx_channel_switch(depend_tx, tx); break; case ASYNC_TX_DIRECT_SUBMIT: - tx->parent = NULL; + txd_clear_parent(tx); tx->tx_submit(tx); break; } } else { - tx->parent = NULL; + txd_clear_parent(tx); tx->tx_submit(tx); } diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index d18b5d069d7e..fcfe1a62ffa5 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -978,7 +978,9 @@ void dma_async_tx_descriptor_init(struct dma_async_tx_descriptor *tx, struct dma_chan *chan) { tx->chan = chan; + #ifndef CONFIG_ASYNC_TX_DISABLE_CHANNEL_SWITCH spin_lock_init(&tx->lock); + #endif } EXPORT_SYMBOL(dma_async_tx_descriptor_init); @@ -1011,7 +1013,7 @@ EXPORT_SYMBOL_GPL(dma_wait_for_async_tx); */ void dma_run_dependencies(struct dma_async_tx_descriptor *tx) { - struct dma_async_tx_descriptor *dep = tx->next; + struct dma_async_tx_descriptor *dep = txd_next(tx); struct dma_async_tx_descriptor *dep_next; struct dma_chan *chan; @@ -1019,7 +1021,7 @@ void dma_run_dependencies(struct dma_async_tx_descriptor *tx) return; /* we'll submit tx->next now, so clear the link */ - tx->next = NULL; + txd_clear_next(tx); chan = dep->chan; /* keep submitting up until a channel switch is detected @@ -1027,14 +1029,14 @@ void dma_run_dependencies(struct dma_async_tx_descriptor *tx) * processing the interrupt from async_tx_channel_switch */ for (; dep; dep = dep_next) { - spin_lock_bh(&dep->lock); - dep->parent = NULL; - dep_next = dep->next; + txd_lock(dep); + txd_clear_parent(dep); + dep_next = txd_next(dep); if (dep_next && dep_next->chan == chan) - dep->next = NULL; /* ->next will be submitted */ + txd_clear_next(dep); /* ->next will be submitted */ else dep_next = NULL; /* submit current dep and terminate */ - spin_unlock_bh(&dep->lock); + txd_unlock(dep); dep->tx_submit(dep); } diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 20ea12c86fd0..cb234979fc6b 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -230,11 +230,71 @@ struct dma_async_tx_descriptor { dma_cookie_t (*tx_submit)(struct dma_async_tx_descriptor *tx); dma_async_tx_callback callback; void *callback_param; +#ifndef CONFIG_ASYNC_TX_DISABLE_CHANNEL_SWITCH struct dma_async_tx_descriptor *next; struct dma_async_tx_descriptor *parent; spinlock_t lock; +#endif }; +#ifdef CONFIG_ASYNC_TX_DISABLE_CHANNEL_SWITCH +static inline void txd_lock(struct dma_async_tx_descriptor *txd) +{ +} +static inline void txd_unlock(struct dma_async_tx_descriptor *txd) +{ +} +static inline void txd_chain(struct dma_async_tx_descriptor *txd, struct dma_async_tx_descriptor *next) +{ + BUG(); +} +static inline void txd_clear_parent(struct dma_async_tx_descriptor *txd) +{ +} +static inline void txd_clear_next(struct dma_async_tx_descriptor *txd) +{ +} +static inline struct dma_async_tx_descriptor *txd_next(struct dma_async_tx_descriptor *txd) +{ + return NULL; +} +static inline struct dma_async_tx_descriptor *txd_parent(struct dma_async_tx_descriptor *txd) +{ + return NULL; +} + +#else +static inline void txd_lock(struct dma_async_tx_descriptor *txd) +{ + spin_lock_bh(&txd->lock); +} +static inline void txd_unlock(struct dma_async_tx_descriptor *txd) +{ + spin_unlock_bh(&txd->lock); +} +static inline void txd_chain(struct dma_async_tx_descriptor *txd, struct dma_async_tx_descriptor *next) +{ + txd->next = next; + next->parent = txd; +} +static inline void txd_clear_parent(struct dma_async_tx_descriptor *txd) +{ + txd->parent = NULL; +} +static inline void txd_clear_next(struct dma_async_tx_descriptor *txd) +{ + txd->next = NULL; +} +static inline struct dma_async_tx_descriptor *txd_parent(struct dma_async_tx_descriptor *txd) +{ + return txd->parent; +} +static inline struct dma_async_tx_descriptor *txd_next(struct dma_async_tx_descriptor *txd) +{ + return txd->next; +} +#endif + /** * struct dma_device - info on the entity supplying DMA services * @chancnt: how many DMA channels are supported -- cgit v1.2.3 From 67c7ddd055c794f0d8e9466ca2d6b5cc0b73d4df Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Tue, 4 May 2010 11:12:00 +0200 Subject: drbd: Four new configuration settings for resync speed control To reasonably control resync speed over drbd-proxy connections, drbd has to measure the current delay of packets transmitted over the (possibly congested) data socket vs the meta-data socket. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_nl.c | 4 ++++ include/linux/drbd_limits.h | 16 ++++++++++++++++ include/linux/drbd_nl.h | 4 ++++ 3 files changed, 24 insertions(+) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 6cb703686b28..93d150661f4b 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -1555,6 +1555,10 @@ static int drbd_nl_syncer_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *n sc.rate = DRBD_RATE_DEF; sc.after = DRBD_AFTER_DEF; sc.al_extents = DRBD_AL_EXTENTS_DEF; + sc.dp_volume = DRBD_DP_VOLUME_DEF; + sc.dp_interval = DRBD_DP_INTERVAL_DEF; + sc.throttle_th = DRBD_RS_THROTTLE_TH_DEF; + sc.hold_off_th = DRBD_RS_HOLD_OFF_TH_DEF; } else memcpy(&sc, &mdev->sync_conf, sizeof(struct syncer_conf)); diff --git a/include/linux/drbd_limits.h b/include/linux/drbd_limits.h index 51f47a586ad8..440b42e38e89 100644 --- a/include/linux/drbd_limits.h +++ b/include/linux/drbd_limits.h @@ -133,5 +133,21 @@ #define DRBD_MAX_BIO_BVECS_MAX 128 #define DRBD_MAX_BIO_BVECS_DEF 0 +#define DRBD_DP_VOLUME_MIN 4 +#define DRBD_DP_VOLUME_MAX 1048576 +#define DRBD_DP_VOLUME_DEF 16384 + +#define DRBD_DP_INTERVAL_MIN 1 +#define DRBD_DP_INTERVAL_MAX 600 +#define DRBD_DP_INTERVAL_DEF 5 + +#define DRBD_RS_THROTTLE_TH_MIN 1 +#define DRBD_RS_THROTTLE_TH_MAX 600 +#define DRBD_RS_THROTTLE_TH_DEF 20 + +#define DRBD_RS_HOLD_OFF_TH_MIN 1 +#define DRBD_RS_HOLD_OFF_TH_MAX 6000 +#define DRBD_RS_HOLD_OFF_TH_DEF 100 + #undef RANGE #endif diff --git a/include/linux/drbd_nl.h b/include/linux/drbd_nl.h index de055c07c2ba..ce77a746fc9d 100644 --- a/include/linux/drbd_nl.h +++ b/include/linux/drbd_nl.h @@ -78,6 +78,10 @@ NL_PACKET(syncer_conf, 8, NL_INTEGER( 30, T_MAY_IGNORE, rate) NL_INTEGER( 31, T_MAY_IGNORE, after) NL_INTEGER( 32, T_MAY_IGNORE, al_extents) + NL_INTEGER( 71, T_MAY_IGNORE, dp_volume) + NL_INTEGER( 72, T_MAY_IGNORE, dp_interval) + NL_INTEGER( 73, T_MAY_IGNORE, throttle_th) + NL_INTEGER( 74, T_MAY_IGNORE, hold_off_th) NL_STRING( 52, T_MAY_IGNORE, verify_alg, SHARED_SECRET_MAX) NL_STRING( 51, T_MAY_IGNORE, cpu_mask, 32) NL_STRING( 64, T_MAY_IGNORE, csums_alg, SHARED_SECRET_MAX) -- cgit v1.2.3 From bd26bfc5b4253425d17aa49648ae1f3e976041c4 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Tue, 4 May 2010 12:33:58 +0200 Subject: drbd: Actually send delay probes Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_int.h | 6 +++++- drivers/block/drbd/drbd_main.c | 43 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 3e4d8b574fef..210870ed8a79 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -925,9 +925,11 @@ struct drbd_conf { unsigned int ko_count; struct drbd_work resync_work, unplug_work, - md_sync_work; + md_sync_work, + delay_probe_work; struct timer_list resync_timer; struct timer_list md_sync_timer; + struct timer_list delay_probe_timer; /* Used after attach while negotiating new disk state. */ union drbd_state new_state_tmp; @@ -1047,6 +1049,8 @@ struct drbd_conf { int data_delay; /* Delay of packets on the data-sock behind meta-sock */ atomic_t delay_seq; /* To generate sequence numbers of delay probes */ struct timeval dps_time; /* delay-probes-start-time */ + int dp_volume_last; /* send_cnt of last delay probe */ + int c_sync_rate; /* current resync rate after delay_probe magic */ }; static inline struct drbd_conf *minor_to_mdev(unsigned int minor) diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 710bfebb7b63..98785d08cf70 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2207,10 +2207,13 @@ static int drbd_send_delay_probe(struct drbd_conf *mdev, struct drbd_socket *ds) } mutex_unlock(&ds->mutex); + mdev->dp_volume_last = mdev->send_cnt; + mod_timer(&mdev->delay_probe_timer, jiffies + mdev->sync_conf.dp_interval * HZ / 10); + return ok; } -static int drbd_send_dalay_probes(struct drbd_conf *mdev) +static int drbd_send_delay_probes(struct drbd_conf *mdev) { int ok; atomic_inc(&mdev->delay_seq); @@ -2350,6 +2353,30 @@ static int _drbd_send_zc_bio(struct drbd_conf *mdev, struct bio *bio) return 1; } +static void consider_delay_probes(struct drbd_conf *mdev) +{ + if (mdev->state.conn != C_SYNC_SOURCE) + return; + + if (mdev->dp_volume_last + mdev->sync_conf.dp_volume * 2 < mdev->send_cnt) + drbd_send_delay_probes(mdev); +} + +static int w_delay_probes(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + if (!cancel && mdev->state.conn == C_SYNC_SOURCE) + drbd_send_delay_probes(mdev); + + return 1; +} + +static void delay_probe_timer_fn(unsigned long data) +{ + struct drbd_conf *mdev = (struct drbd_conf *) data; + + drbd_queue_work(&mdev->data.work, &mdev->delay_probe_work); +} + /* Used to send write requests * R_PRIMARY -> Peer (P_DATA) */ @@ -2412,6 +2439,10 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req) } drbd_put_data_sock(mdev); + + if (ok) + consider_delay_probes(mdev); + return ok; } @@ -2457,6 +2488,10 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd, ok = _drbd_send_zc_bio(mdev, e->private_bio); drbd_put_data_sock(mdev); + + if (ok) + consider_delay_probes(mdev); + return ok; } @@ -2671,17 +2706,23 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) INIT_LIST_HEAD(&mdev->md_sync_work.list); INIT_LIST_HEAD(&mdev->bm_io_work.w.list); INIT_LIST_HEAD(&mdev->delay_probes); + INIT_LIST_HEAD(&mdev->delay_probe_work.list); mdev->resync_work.cb = w_resync_inactive; mdev->unplug_work.cb = w_send_write_hint; mdev->md_sync_work.cb = w_md_sync; mdev->bm_io_work.w.cb = w_bitmap_io; + mdev->delay_probe_work.cb = w_delay_probes; init_timer(&mdev->resync_timer); init_timer(&mdev->md_sync_timer); + init_timer(&mdev->delay_probe_timer); mdev->resync_timer.function = resync_timer_fn; mdev->resync_timer.data = (unsigned long) mdev; mdev->md_sync_timer.function = md_sync_timer_fn; mdev->md_sync_timer.data = (unsigned long) mdev; + mdev->delay_probe_timer.function = delay_probe_timer_fn; + mdev->delay_probe_timer.data = (unsigned long) mdev; + init_waitqueue_head(&mdev->misc_wait); init_waitqueue_head(&mdev->state_wait); -- cgit v1.2.3 From cdd67a74603d0453ddffc24c572aed2ddd1795b8 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Tue, 4 May 2010 16:57:18 +0200 Subject: drbd: Control the actual resync rate based on the queuing delay of data packets In a setup with a high bandwidth and high latency network, eventually involving deep queues in routers, it is beneficial to only fill those queues up to an limited extend with resync data. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_worker.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 44bf6d11197e..0bbecf45b485 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -414,6 +414,18 @@ void resync_timer_fn(unsigned long data) drbd_queue_work(&mdev->data.work, &mdev->resync_work); } +static int calc_resync_rate(struct drbd_conf *mdev) +{ + int d = mdev->data_delay / 1000; /* us -> ms */ + int td = mdev->sync_conf.throttle_th * 100; /* 0.1s -> ms */ + int hd = mdev->sync_conf.hold_off_th * 100; /* 0.1s -> ms */ + int cr = mdev->sync_conf.rate; + + return d <= td ? cr : + d >= hd ? 0 : + cr + (cr * (td - d) / (hd - td)); +} + int w_make_resync_request(struct drbd_conf *mdev, struct drbd_work *w, int cancel) { @@ -446,7 +458,8 @@ int w_make_resync_request(struct drbd_conf *mdev, return 1; } - number = SLEEP_TIME * mdev->sync_conf.rate / ((BM_BLOCK_SIZE/1024)*HZ); + mdev->c_sync_rate = calc_resync_rate(mdev); + number = SLEEP_TIME * mdev->c_sync_rate / ((BM_BLOCK_SIZE / 1024) * HZ); pe = atomic_read(&mdev->rs_pending_cnt); mutex_lock(&mdev->data.mutex); -- cgit v1.2.3 From eedf386ae9d9e80a5669107e960090951e62f3a3 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Tue, 4 May 2010 16:31:03 +0200 Subject: drbd: Proc bits of new resync speed stuff Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_proc.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_proc.c b/drivers/block/drbd/drbd_proc.c index be3374b68460..81dea0a85933 100644 --- a/drivers/block/drbd/drbd_proc.c +++ b/drivers/block/drbd/drbd_proc.c @@ -73,14 +73,22 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq) seq_printf(seq, "sync'ed:%3u.%u%% ", res / 10, res % 10); /* if more than 1 GB display in MB */ if (mdev->rs_total > 0x100000L) - seq_printf(seq, "(%lu/%lu)M\n\t", + seq_printf(seq, "(%lu/%lu)M", (unsigned long) Bit2KB(rs_left >> 10), (unsigned long) Bit2KB(mdev->rs_total >> 10)); else - seq_printf(seq, "(%lu/%lu)K\n\t", + seq_printf(seq, "(%lu/%lu)K", (unsigned long) Bit2KB(rs_left), (unsigned long) Bit2KB(mdev->rs_total)); + if (mdev->state.conn == C_SYNC_TARGET) + seq_printf(seq, " queue_delay: %d.%d ms\n\t", + mdev->data_delay / 1000, + (mdev->data_delay % 1000) / 100); + else if (mdev->state.conn == C_SYNC_SOURCE) + seq_printf(seq, " delay_probe: %d\n\t", + atomic_read(&mdev->delay_seq)); + /* see drivers/md/md.c * We do not want to overflow, so the order of operands and * the * 100 / 100 trick are important. We do a +1 to be @@ -128,6 +136,14 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq) else seq_printf(seq, " (%ld)", dbdt); + if (mdev->state.conn == C_SYNC_TARGET) { + if (mdev->c_sync_rate > 1000) + seq_printf(seq, " want: %d,%03d", + mdev->c_sync_rate / 1000, mdev->c_sync_rate % 1000); + else + seq_printf(seq, " want: %d", mdev->c_sync_rate); + } + seq_printf(seq, " K/sec\n"); } -- cgit v1.2.3 From 078b078f662a8e21d5a6fee81007b5337ab962cd Mon Sep 17 00:00:00 2001 From: Charles Clément Date: Fri, 14 May 2010 19:37:32 -0700 Subject: Staging: vt6655: use ETH_ALEN macro instead of custom one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced custom ethernet address length definition U_ETHER_ADDR_LEN by ETH_ALEN from . Signed-off-by: Charles Clément Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/aes_ccmp.c | 10 +++--- drivers/staging/vt6655/card.c | 4 +-- drivers/staging/vt6655/desc.h | 6 ++-- drivers/staging/vt6655/device.h | 18 +++++----- drivers/staging/vt6655/device_main.c | 14 ++++---- drivers/staging/vt6655/dpc.c | 14 ++++---- drivers/staging/vt6655/ioctl.c | 2 +- drivers/staging/vt6655/key.c | 4 +-- drivers/staging/vt6655/key.h | 2 +- drivers/staging/vt6655/mib.c | 2 +- drivers/staging/vt6655/mib.h | 2 +- drivers/staging/vt6655/rxtx.c | 70 ++++++++++++++++++------------------ drivers/staging/vt6655/srom.c | 4 +-- drivers/staging/vt6655/tether.c | 2 +- drivers/staging/vt6655/tether.h | 22 ++++++------ drivers/staging/vt6655/wctl.c | 4 +-- drivers/staging/vt6655/wmgr.c | 8 ++--- drivers/staging/vt6655/wpa2.c | 2 +- drivers/staging/vt6655/wpactl.c | 2 +- 19 files changed, 96 insertions(+), 96 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/aes_ccmp.c b/drivers/staging/vt6655/aes_ccmp.c index 2614ed380a43..fef1b91c2925 100644 --- a/drivers/staging/vt6655/aes_ccmp.c +++ b/drivers/staging/vt6655/aes_ccmp.c @@ -277,7 +277,7 @@ int ii,jj,kk; pbyPayload = pbyIV + 8; //IV-length abyNonce[0] = 0x00; //now is 0, if Qos here will be priority - memcpy(&(abyNonce[1]), pMACHeader->abyAddr2, U_ETHER_ADDR_LEN); + memcpy(&(abyNonce[1]), pMACHeader->abyAddr2, ETH_ALEN); abyNonce[7] = pbyIV[7]; abyNonce[8] = pbyIV[6]; abyNonce[9] = pbyIV[5]; @@ -299,16 +299,16 @@ int ii,jj,kk; byTmp = (BYTE)(pMACHeader->wFrameCtl >> 8); byTmp &= 0x87; MIC_HDR1[3] = byTmp | 0x40; - memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, U_ETHER_ADDR_LEN); - memcpy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, U_ETHER_ADDR_LEN); + memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, ETH_ALEN); + memcpy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, ETH_ALEN); //MIC_HDR2 - memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, U_ETHER_ADDR_LEN); + memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, ETH_ALEN); byTmp = (BYTE)(pMACHeader->wSeqCtl & 0xff); MIC_HDR2[6] = byTmp & 0x0f; MIC_HDR2[7] = 0; if ( bA4 ) { - memcpy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, U_ETHER_ADDR_LEN); + memcpy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, ETH_ALEN); } else { MIC_HDR2[8] = 0x00; MIC_HDR2[9] = 0x00; diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index b071236607f6..7bc2d7654b07 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -1576,7 +1576,7 @@ CARDbAdd_PMKID_Candidate ( // Update Old Candidate for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) { pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii]; - if ( !memcmp(pCandidateList->BSSID, pbyBSSID, U_ETHER_ADDR_LEN)) { + if ( !memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) { if ((bRSNCapExist == TRUE) && (wRSNCap & BIT0)) { pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; } else { @@ -1593,7 +1593,7 @@ CARDbAdd_PMKID_Candidate ( } else { pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); } - memcpy(pCandidateList->BSSID, pbyBSSID, U_ETHER_ADDR_LEN); + memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN); pDevice->gsPMKIDCandidate.NumCandidates++; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates); return TRUE; diff --git a/drivers/staging/vt6655/desc.h b/drivers/staging/vt6655/desc.h index 0e119492d717..cedb1e7df4fa 100644 --- a/drivers/staging/vt6655/desc.h +++ b/drivers/staging/vt6655/desc.h @@ -446,8 +446,8 @@ typedef const SRrvTime_atim *PCSRrvTime_atim; typedef struct tagSRTSData { WORD wFrameControl; WORD wDurationID; - BYTE abyRA[U_ETHER_ADDR_LEN]; - BYTE abyTA[U_ETHER_ADDR_LEN]; + BYTE abyRA[ETH_ALEN]; + BYTE abyTA[ETH_ALEN]; }__attribute__ ((__packed__)) SRTSData, *PSRTSData; typedef const SRTSData *PCSRTSData; @@ -522,7 +522,7 @@ typedef const SRTS_a_FB *PCSRTS_a_FB; typedef struct tagSCTSData { WORD wFrameControl; WORD wDurationID; - BYTE abyRA[U_ETHER_ADDR_LEN]; + BYTE abyRA[ETH_ALEN]; WORD wReserved; }__attribute__ ((__packed__)) SCTSData, *PSCTSData; diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index 0ea24f25cdf9..40ee4e14237e 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -103,7 +103,7 @@ #define MAC_MAX_CONTEXT_REG (256+128) #define MAX_MULTICAST_ADDRESS_NUM 32 -#define MULTICAST_ADDRESS_LIST_SIZE (MAX_MULTICAST_ADDRESS_NUM * U_ETHER_ADDR_LEN) +#define MULTICAST_ADDRESS_LIST_SIZE (MAX_MULTICAST_ADDRESS_NUM * ETH_ALEN) //#define OP_MODE_INFRASTRUCTURE 0 @@ -304,7 +304,7 @@ typedef enum { // The receive duplicate detection cache entry typedef struct tagSCacheEntry{ WORD wFmSequence; - BYTE abyAddr2[U_ETHER_ADDR_LEN]; + BYTE abyAddr2[ETH_ALEN]; } SCacheEntry, *PSCacheEntry; typedef struct tagSCache{ @@ -321,7 +321,7 @@ typedef struct tagSDeFragControlBlock { WORD wSequence; WORD wFragNum; - BYTE abyAddr2[U_ETHER_ADDR_LEN]; + BYTE abyAddr2[ETH_ALEN]; UINT uLifetime; struct sk_buff* skb; PBYTE pbyRxBuffer; @@ -484,7 +484,7 @@ typedef struct __device_info { BYTE byOriginalZonetype; BYTE abyMacContext[MAC_MAX_CONTEXT_REG]; BOOL bLinkPass; // link status: OK or fail - BYTE abyCurrentNetAddr[U_ETHER_ADDR_LEN]; + BYTE abyCurrentNetAddr[ETH_ALEN]; // Adapter statistics SStatCounter scStatistic; @@ -546,8 +546,8 @@ typedef struct __device_info { BYTE byOpMode; BOOL bBSSIDFilter; WORD wMaxTransmitMSDULifetime; - BYTE abyBSSID[U_ETHER_ADDR_LEN]; - BYTE abyDesireBSSID[U_ETHER_ADDR_LEN]; + BYTE abyBSSID[ETH_ALEN]; + BYTE abyDesireBSSID[ETH_ALEN]; WORD wCTSDuration; // update while speed change WORD wACKDuration; // update while speed change WORD wRTSTransmitLen; // update while speed change @@ -753,9 +753,9 @@ typedef struct __device_info { SEthernetHeader sTxEthHeader; SEthernetHeader sRxEthHeader; - BYTE abyBroadcastAddr[U_ETHER_ADDR_LEN]; - BYTE abySNAP_RFC1042[U_ETHER_ADDR_LEN]; - BYTE abySNAP_Bridgetunnel[U_ETHER_ADDR_LEN]; + BYTE abyBroadcastAddr[ETH_ALEN]; + BYTE abySNAP_RFC1042[ETH_ALEN]; + BYTE abySNAP_Bridgetunnel[ETH_ALEN]; BYTE abyEEPROM[EEP_MAX_CONTEXT_SIZE]; //DWORD alignment // Pre-Authentication & PMK cache SPMKID gsPMKID; diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index a401f2ad62c8..301efc5cbe0d 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -429,14 +429,14 @@ pOpts->flags|=DEVICE_FLAGS_DiversityANT; static void device_set_options(PSDevice pDevice) { - BYTE abyBroadcastAddr[U_ETHER_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - BYTE abySNAP_RFC1042[U_ETHER_ADDR_LEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; - BYTE abySNAP_Bridgetunnel[U_ETHER_ADDR_LEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8}; + BYTE abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + BYTE abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; + BYTE abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8}; - memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, U_ETHER_ADDR_LEN); - memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, U_ETHER_ADDR_LEN); - memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, U_ETHER_ADDR_LEN); + memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, ETH_ALEN); + memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, ETH_ALEN); + memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, ETH_ALEN); pDevice->uChannel = pDevice->sOpts.channel_num; pDevice->wRTSThreshold = pDevice->sOpts.rts_thresh; @@ -1971,7 +1971,7 @@ device_init_rd0_ring(pDevice); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device_init_registers\n"); device_init_registers(pDevice, DEVICE_INIT_COLD); MACvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr); - memcpy(pDevice->pMgmt->abyMACAddr, pDevice->abyCurrentNetAddr, U_ETHER_ADDR_LEN); + memcpy(pDevice->pMgmt->abyMACAddr, pDevice->abyCurrentNetAddr, ETH_ALEN); device_set_multi(pDevice->dev); // Init for Key Management diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index 715be63f21a4..83040f4f6c78 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -236,11 +236,11 @@ s_vProcessRxMACHeader ( } } - cbHeaderSize -= (U_ETHER_ADDR_LEN * 2); + cbHeaderSize -= (ETH_ALEN * 2); pbyRxBuffer = (PBYTE) (pbyRxBufferAddr + cbHeaderSize); - for(ii=0;iisRxEthHeader.abyDstAddr[ii]; - for(ii=0;iisRxEthHeader.abySrcAddr[ii]; *pcbHeadSize = cbHeaderSize; @@ -277,14 +277,14 @@ s_vGetDASA ( if ((pMACHeader->wFrameCtl & FC_TODS) == 0) { if (pMACHeader->wFrameCtl & FC_FROMDS) { - for(ii=0;iiabyDstAddr[ii] = pMACHeader->abyAddr1[ii]; psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr3[ii]; } } else { // IBSS mode - for(ii=0;iiabyDstAddr[ii] = pMACHeader->abyAddr1[ii]; psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii]; } @@ -293,14 +293,14 @@ s_vGetDASA ( else { // Is AP mode.. if (pMACHeader->wFrameCtl & FC_FROMDS) { - for(ii=0;iiabyDstAddr[ii] = pMACHeader->abyAddr3[ii]; psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr4[ii]; cbHeaderSize += 6; } } else { - for(ii=0;iiabyDstAddr[ii] = pMACHeader->abyAddr3[ii]; psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii]; } diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c index e36cd30f642a..404287c60252 100644 --- a/drivers/staging/vt6655/ioctl.c +++ b/drivers/staging/vt6655/ioctl.c @@ -497,7 +497,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) { }; if (sValue.dwValue == 1) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "up wpadev\n"); - memcpy(pDevice->wpadev->dev_addr, pDevice->dev->dev_addr, U_ETHER_ADDR_LEN); + memcpy(pDevice->wpadev->dev_addr, pDevice->dev->dev_addr, ETH_ALEN); pDevice->bWPADEVUp = TRUE; } else { diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c index 2065ee220687..bfc5c509d902 100644 --- a/drivers/staging/vt6655/key.c +++ b/drivers/staging/vt6655/key.c @@ -281,7 +281,7 @@ BOOL KeybSetKey ( } } if (j < (MAX_KEY_TABLE-1)) { - memcpy(pTable->KeyTable[j].abyBSSID,pbyBSSID,U_ETHER_ADDR_LEN); + memcpy(pTable->KeyTable[j].abyBSSID,pbyBSSID,ETH_ALEN); pTable->KeyTable[j].bInUse = TRUE; if ((dwKeyIndex & PAIRWISE_KEY) != 0) { // Pairwise key @@ -656,7 +656,7 @@ BOOL KeybSetDefaultKey ( } pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = TRUE; - for(ii=0;iiKeyTable[MAX_KEY_TABLE-1].abyBSSID[ii] = 0xFF; // Group key diff --git a/drivers/staging/vt6655/key.h b/drivers/staging/vt6655/key.h index db1cbf3c8e7d..39403d93aeb1 100644 --- a/drivers/staging/vt6655/key.h +++ b/drivers/staging/vt6655/key.h @@ -71,7 +71,7 @@ typedef struct tagSKeyItem typedef struct tagSKeyTable { - BYTE abyBSSID[U_ETHER_ADDR_LEN]; //6 + BYTE abyBSSID[ETH_ALEN]; //6 BYTE byReserved0[2]; //8 SKeyItem PairwiseKey; SKeyItem GroupKey[MAX_GROUP_KEY]; //64*5 = 320, 320+8=328 diff --git a/drivers/staging/vt6655/mib.c b/drivers/staging/vt6655/mib.c index fb11595c82cb..e5f06382e4f8 100644 --- a/drivers/staging/vt6655/mib.c +++ b/drivers/staging/vt6655/mib.c @@ -190,7 +190,7 @@ void STAvUpdateRDStatCounter (PSStatCounter pStatistic, pStatistic->ullRsrOK++; - if (cbFrameLength >= U_ETHER_ADDR_LEN) { + if (cbFrameLength >= ETH_ALEN) { // update counters in case that successful transmit if (byRSR & RSR_ADDRBROAD) { pStatistic->ullRxBroadcastFrames++; diff --git a/drivers/staging/vt6655/mib.h b/drivers/staging/vt6655/mib.h index 2aa2b91de72b..2308319a4051 100644 --- a/drivers/staging/vt6655/mib.h +++ b/drivers/staging/vt6655/mib.h @@ -78,7 +78,7 @@ typedef struct tagSMib2Counter { LONG ifType; LONG ifMtu; DWORD ifSpeed; - BYTE ifPhysAddress[U_ETHER_ADDR_LEN]; + BYTE ifPhysAddress[ETH_ALEN]; LONG ifAdminStatus; LONG ifOperStatus; DWORD ifLastChange; diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 6cd10bdf2800..e27fa204962e 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -900,16 +900,16 @@ s_vFillRTSHead ( pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4 if ((pDevice->eOPMode == OP_MODE_ADHOC) || (pDevice->eOPMode == OP_MODE_AP)) { - memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); } else { - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); } if (pDevice->eOPMode == OP_MODE_AP) { - memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); } else { - memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); } } else { @@ -938,17 +938,17 @@ s_vFillRTSHead ( if ((pDevice->eOPMode == OP_MODE_ADHOC) || (pDevice->eOPMode == OP_MODE_AP)) { - memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); } else { - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); } if (pDevice->eOPMode == OP_MODE_AP) { - memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); } else { - memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); } } // if (byFBOption == AUTO_FB_NONE) @@ -969,17 +969,17 @@ s_vFillRTSHead ( if ((pDevice->eOPMode == OP_MODE_ADHOC) || (pDevice->eOPMode == OP_MODE_AP)) { - memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); } else { - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); } if (pDevice->eOPMode == OP_MODE_AP) { - memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); } else { - memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); } } @@ -1000,16 +1000,16 @@ s_vFillRTSHead ( if ((pDevice->eOPMode == OP_MODE_ADHOC) || (pDevice->eOPMode == OP_MODE_AP)) { - memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); } else { - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); } if (pDevice->eOPMode == OP_MODE_AP) { - memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); } else { - memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); } } } @@ -1029,17 +1029,17 @@ s_vFillRTSHead ( if ((pDevice->eOPMode == OP_MODE_ADHOC) || (pDevice->eOPMode == OP_MODE_AP)) { - memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); } else { - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); } if (pDevice->eOPMode == OP_MODE_AP) { - memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); } else { - memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); } } } @@ -1098,7 +1098,7 @@ s_vFillCTSHead ( pBuf->Data.wDurationID = pBuf->wDuration_ba; pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4 pBuf->Data.wReserved = 0x0000; - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), ETH_ALEN); } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) PSCTS pBuf = (PSCTS)pvCTS; @@ -1116,7 +1116,7 @@ s_vFillCTSHead ( pBuf->Data.wDurationID = pBuf->wDuration_ba; pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4 pBuf->Data.wReserved = 0x0000; - memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), U_ETHER_ADDR_LEN); + memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), ETH_ALEN); } } } @@ -2287,21 +2287,21 @@ vGenerateMACHeader ( } if (pDevice->eOPMode == OP_MODE_AP) { - memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); - memcpy(&(pMACHeader->abyAddr2[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); - memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); + memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); + memcpy(&(pMACHeader->abyAddr2[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); + memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); pMACHeader->wFrameCtl |= FC_FROMDS; } else { if (pDevice->eOPMode == OP_MODE_ADHOC) { - memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); - memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); - memcpy(&(pMACHeader->abyAddr3[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); + memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); + memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); + memcpy(&(pMACHeader->abyAddr3[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); } else { - memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN); - memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN); - memcpy(&(pMACHeader->abyAddr1[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN); + memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abyDstAddr[0]), ETH_ALEN); + memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), ETH_ALEN); + memcpy(&(pMACHeader->abyAddr1[0]), &(pDevice->abyBSSID[0]), ETH_ALEN); pMACHeader->wFrameCtl |= FC_TODS; } } @@ -2518,8 +2518,8 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) { memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); - memcpy(&(sEthHeader.abyDstAddr[0]), &(pPacket->p80211Header->sA3.abyAddr1[0]), U_ETHER_ADDR_LEN); - memcpy(&(sEthHeader.abySrcAddr[0]), &(pPacket->p80211Header->sA3.abyAddr2[0]), U_ETHER_ADDR_LEN); + memcpy(&(sEthHeader.abyDstAddr[0]), &(pPacket->p80211Header->sA3.abyAddr1[0]), ETH_ALEN); + memcpy(&(sEthHeader.abySrcAddr[0]), &(pPacket->p80211Header->sA3.abyAddr2[0]), ETH_ALEN); //========================= // No Fragmentation //========================= @@ -3062,8 +3062,8 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU } memset((void *)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize)); - memcpy(&(sEthHeader.abyDstAddr[0]), &(p80211Header->sA3.abyAddr1[0]), U_ETHER_ADDR_LEN); - memcpy(&(sEthHeader.abySrcAddr[0]), &(p80211Header->sA3.abyAddr2[0]), U_ETHER_ADDR_LEN); + memcpy(&(sEthHeader.abyDstAddr[0]), &(p80211Header->sA3.abyAddr1[0]), ETH_ALEN); + memcpy(&(sEthHeader.abySrcAddr[0]), &(p80211Header->sA3.abyAddr2[0]), ETH_ALEN); //========================= // No Fragmentation //========================= diff --git a/drivers/staging/vt6655/srom.c b/drivers/staging/vt6655/srom.c index fb7a6468cab8..418575fdc2c0 100644 --- a/drivers/staging/vt6655/srom.c +++ b/drivers/staging/vt6655/srom.c @@ -320,7 +320,7 @@ void SROMvReadEtherAddress(DWORD_PTR dwIoBase, PBYTE pbyEtherAddress) BYTE ii; /* ii = Rom Address */ - for (ii = 0; ii < U_ETHER_ADDR_LEN; ii++) { + for (ii = 0; ii < ETH_ALEN; ii++) { *pbyEtherAddress = SROMbyReadEmbedded(dwIoBase, ii); pbyEtherAddress++; } @@ -345,7 +345,7 @@ void SROMvWriteEtherAddress(DWORD_PTR dwIoBase, PBYTE pbyEtherAddress) BYTE ii; /* ii = Rom Address */ - for (ii = 0; ii < U_ETHER_ADDR_LEN; ii++) { + for (ii = 0; ii < ETH_ALEN; ii++) { SROMbWriteEmbedded(dwIoBase, ii, *pbyEtherAddress); pbyEtherAddress++; } diff --git a/drivers/staging/vt6655/tether.c b/drivers/staging/vt6655/tether.c index c90b469ad545..d8ba67395cb1 100644 --- a/drivers/staging/vt6655/tether.c +++ b/drivers/staging/vt6655/tether.c @@ -68,7 +68,7 @@ BYTE ETHbyGetHashIndexByCrc32 (PBYTE pbyMultiAddr) BYTE byHash = 0; // get the least 6-bits from CRC generator - byTmpHash = (BYTE)(CRCdwCrc32(pbyMultiAddr, U_ETHER_ADDR_LEN, + byTmpHash = (BYTE)(CRCdwCrc32(pbyMultiAddr, ETH_ALEN, 0xFFFFFFFFL) & 0x3F); // reverse most bit to least bit for (ii = 0; ii < (sizeof(byTmpHash) * 8); ii++) { diff --git a/drivers/staging/vt6655/tether.h b/drivers/staging/vt6655/tether.h index 5a3c326436c6..af119dd82b24 100644 --- a/drivers/staging/vt6655/tether.h +++ b/drivers/staging/vt6655/tether.h @@ -29,17 +29,17 @@ #ifndef __TETHER_H__ #define __TETHER_H__ +#include #include "ttype.h" /*--------------------- Export Definitions -------------------------*/ // // constants // -#define U_ETHER_ADDR_LEN 6 // Ethernet address length #define U_TYPE_LEN 2 // #define U_CRC_LEN 4 // -#define U_HEADER_LEN (U_ETHER_ADDR_LEN * 2 + U_TYPE_LEN) -#define U_ETHER_ADDR_STR_LEN (U_ETHER_ADDR_LEN * 2 + 1) +#define U_HEADER_LEN (ETH_ALEN * 2 + U_TYPE_LEN) +#define U_ETHER_ADDR_STR_LEN (ETH_ALEN * 2 + 1) // Ethernet address string length #define MIN_DATA_LEN 46 // min data length @@ -167,8 +167,8 @@ // Ethernet packet // typedef struct tagSEthernetHeader { - BYTE abyDstAddr[U_ETHER_ADDR_LEN]; - BYTE abySrcAddr[U_ETHER_ADDR_LEN]; + BYTE abyDstAddr[ETH_ALEN]; + BYTE abySrcAddr[ETH_ALEN]; WORD wType; }__attribute__ ((__packed__)) SEthernetHeader, *PSEthernetHeader; @@ -178,8 +178,8 @@ SEthernetHeader, *PSEthernetHeader; // 802_3 packet // typedef struct tagS802_3Header { - BYTE abyDstAddr[U_ETHER_ADDR_LEN]; - BYTE abySrcAddr[U_ETHER_ADDR_LEN]; + BYTE abyDstAddr[ETH_ALEN]; + BYTE abySrcAddr[ETH_ALEN]; WORD wLen; }__attribute__ ((__packed__)) S802_3Header, *PS802_3Header; @@ -190,11 +190,11 @@ S802_3Header, *PS802_3Header; typedef struct tagS802_11Header { WORD wFrameCtl; WORD wDurationID; - BYTE abyAddr1[U_ETHER_ADDR_LEN]; - BYTE abyAddr2[U_ETHER_ADDR_LEN]; - BYTE abyAddr3[U_ETHER_ADDR_LEN]; + BYTE abyAddr1[ETH_ALEN]; + BYTE abyAddr2[ETH_ALEN]; + BYTE abyAddr3[ETH_ALEN]; WORD wSeqCtl; - BYTE abyAddr4[U_ETHER_ADDR_LEN]; + BYTE abyAddr4[ETH_ALEN]; }__attribute__ ((__packed__)) S802_11Header, *PS802_11Header; diff --git a/drivers/staging/vt6655/wctl.c b/drivers/staging/vt6655/wctl.c index 4406f8caa555..64a66b2f1fc5 100644 --- a/drivers/staging/vt6655/wctl.c +++ b/drivers/staging/vt6655/wctl.c @@ -89,7 +89,7 @@ BOOL WCTLbIsDuplicate (PSCache pCache, PS802_11Header pMACHeader) /* Not fount in cache - insert */ pCacheEntry = &pCache->asCacheEntry[pCache->uInPtr]; pCacheEntry->wFmSequence = pMACHeader->wSeqCtl; - memcpy(&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0]), U_ETHER_ADDR_LEN); + memcpy(&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0]), ETH_ALEN); ADD_ONE_WITH_WRAP_AROUND(pCache->uInPtr, DUPLICATE_RX_CACHE_LENGTH); return FALSE; } @@ -151,7 +151,7 @@ UINT ii; pDevice->sRxDFCB[ii].bInUse = TRUE; pDevice->sRxDFCB[ii].wSequence = (pMACHeader->wSeqCtl >> 4); pDevice->sRxDFCB[ii].wFragNum = (pMACHeader->wSeqCtl & 0x000F); - memcpy(&(pDevice->sRxDFCB[ii].abyAddr2[0]), &(pMACHeader->abyAddr2[0]), U_ETHER_ADDR_LEN); + memcpy(&(pDevice->sRxDFCB[ii].abyAddr2[0]), &(pMACHeader->abyAddr2[0]), ETH_ALEN); return(ii); } } diff --git a/drivers/staging/vt6655/wmgr.c b/drivers/staging/vt6655/wmgr.c index 60c00fc1f025..8af356fd139e 100644 --- a/drivers/staging/vt6655/wmgr.c +++ b/drivers/staging/vt6655/wmgr.c @@ -3869,7 +3869,7 @@ s_MgrMakeAssocRequest( *pwPMKID = 0; // Initialize PMKID count pbyRSN += 2; // Point to PMKID list for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) { - if ( !memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, U_ETHER_ADDR_LEN)) { + if ( !memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) { (*pwPMKID) ++; memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16); pbyRSN += 16; @@ -4125,7 +4125,7 @@ s_MgrMakeReAssocRequest( *pwPMKID = 0; // Initialize PMKID count pbyRSN += 2; // Point to PMKID list for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) { - if ( !memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, U_ETHER_ADDR_LEN)) { + if ( !memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) { (*pwPMKID) ++; memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16); pbyRSN += 16; @@ -4831,7 +4831,7 @@ bAdd_PMKID_Candidate ( // Update Old Candidate for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) { pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii]; - if ( !memcmp(pCandidateList->BSSID, pbyBSSID, U_ETHER_ADDR_LEN)) { + if ( !memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) { if ((psRSNCapObj->bRSNCapExist == TRUE) && (psRSNCapObj->wRSNCap & BIT0)) { pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; } else { @@ -4848,7 +4848,7 @@ bAdd_PMKID_Candidate ( } else { pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED); } - memcpy(pCandidateList->BSSID, pbyBSSID, U_ETHER_ADDR_LEN); + memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN); pDevice->gsPMKIDCandidate.NumCandidates++; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates); return TRUE; diff --git a/drivers/staging/vt6655/wpa2.c b/drivers/staging/vt6655/wpa2.c index ff2837938e96..7a42a0aad7d2 100644 --- a/drivers/staging/vt6655/wpa2.c +++ b/drivers/staging/vt6655/wpa2.c @@ -346,7 +346,7 @@ WPA2uSetIEs( *pwPMKID = 0; // Initialize PMKID count pbyBuffer = &pRSNIEs->abyRSN[20]; // Point to PMKID list for (ii = 0; ii < pMgmt->gsPMKIDCache.BSSIDInfoCount; ii++) { - if ( !memcmp(&pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyBSSID[0], pMgmt->abyCurrBSSID, U_ETHER_ADDR_LEN)) { + if ( !memcmp(&pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyBSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) { (*pwPMKID) ++; memcpy(pbyBuffer, pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyPMKID, 16); pbyBuffer += 16; diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c index 9f215dfa86e0..22c2fab3f328 100644 --- a/drivers/staging/vt6655/wpactl.c +++ b/drivers/staging/vt6655/wpactl.c @@ -101,7 +101,7 @@ static int wpa_init_wpadev(PSDevice pDevice) wpadev_priv = netdev_priv(pDevice->wpadev); *wpadev_priv = *pDevice; - memcpy(pDevice->wpadev->dev_addr, dev->dev_addr, U_ETHER_ADDR_LEN); + memcpy(pDevice->wpadev->dev_addr, dev->dev_addr, ETH_ALEN); pDevice->wpadev->base_addr = dev->base_addr; pDevice->wpadev->irq = dev->irq; pDevice->wpadev->mem_start = dev->mem_start; -- cgit v1.2.3 From a8cdfd8d3bf0b6d2bbe792f5e74f54ccc6bc1d4f Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Wed, 5 May 2010 20:53:33 +0200 Subject: drbd: A fixes to the new resync speed code * Mention P_DELAY_PROBE in the packet naming array * Do not corrupt the mdev->data.work list in case the timer goes off before delay_probe_work got handled by the worker * Do not mod_timer() twice for a single delay_probe pair Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_int.h | 1 + drivers/block/drbd/drbd_main.c | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 210870ed8a79..37380d2c869d 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -268,6 +268,7 @@ static inline const char *cmdname(enum drbd_packets cmd) [P_CSUM_RS_REQUEST] = "CsumRSRequest", [P_RS_IS_IN_SYNC] = "CsumRSIsInSync", [P_COMPRESSED_BITMAP] = "CBitmap", + [P_DELAY_PROBE] = "DelayProbe", [P_MAX_CMD] = NULL, }; diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 98785d08cf70..44cc7b415ed4 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2207,9 +2207,6 @@ static int drbd_send_delay_probe(struct drbd_conf *mdev, struct drbd_socket *ds) } mutex_unlock(&ds->mutex); - mdev->dp_volume_last = mdev->send_cnt; - mod_timer(&mdev->delay_probe_timer, jiffies + mdev->sync_conf.dp_interval * HZ / 10); - return ok; } @@ -2221,6 +2218,9 @@ static int drbd_send_delay_probes(struct drbd_conf *mdev) ok = drbd_send_delay_probe(mdev, &mdev->meta); ok = ok && drbd_send_delay_probe(mdev, &mdev->data); + mdev->dp_volume_last = mdev->send_cnt; + mod_timer(&mdev->delay_probe_timer, jiffies + mdev->sync_conf.dp_interval * HZ / 10); + return ok; } @@ -2374,7 +2374,8 @@ static void delay_probe_timer_fn(unsigned long data) { struct drbd_conf *mdev = (struct drbd_conf *) data; - drbd_queue_work(&mdev->data.work, &mdev->delay_probe_work); + if (list_empty(&mdev->delay_probe_work.list)) + drbd_queue_work(&mdev->data.work, &mdev->delay_probe_work); } /* Used to send write requests -- cgit v1.2.3 From 96fe9ee2c2dfe3268961f3873ea6098b9b9f27c2 Mon Sep 17 00:00:00 2001 From: Charles Clément Date: Fri, 14 May 2010 19:37:33 -0700 Subject: Staging: vt6655: use ETH_HLEN macro instead of custom one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced custom header length definition U_HEADER_LEN by ETH_HLEN from . Also remove unused U_TYPE_LEN. Signed-off-by: Charles Clément Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 16 ++++++++-------- drivers/staging/vt6655/tether.h | 6 ++---- drivers/staging/vt6655/wroute.c | 4 ++-- 3 files changed, 12 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 301efc5cbe0d..25894a201b2b 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -2152,8 +2152,8 @@ BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex) { pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP); - memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)(skb->data), U_HEADER_LEN); - cbFrameBodySize = skb->len - U_HEADER_LEN; + memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)(skb->data), ETH_HLEN); + cbFrameBodySize = skb->len - ETH_HLEN; // 802.1H if (ntohs(pDevice->sTxEthHeader.wType) > MAX_DATA_LEN) { @@ -2356,8 +2356,8 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) { pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP); - memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)(skb->data), U_HEADER_LEN); - cbFrameBodySize = skb->len - U_HEADER_LEN; + memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)(skb->data), ETH_HLEN); + cbFrameBodySize = skb->len - ETH_HLEN; // 802.1H if (ntohs(pDevice->sTxEthHeader.wType) > MAX_DATA_LEN) { cbFrameBodySize += 8; @@ -2636,10 +2636,10 @@ pDevice->byTopCCKBasicRate,pDevice->byTopOFDMBasicRate); BYTE Descriptor_type; WORD Key_info; BOOL bTxeapol_key = FALSE; - Protocol_Version = skb->data[U_HEADER_LEN]; - Packet_Type = skb->data[U_HEADER_LEN+1]; - Descriptor_type = skb->data[U_HEADER_LEN+1+1+2]; - Key_info = (skb->data[U_HEADER_LEN+1+1+2+1] << 8)|(skb->data[U_HEADER_LEN+1+1+2+2]); + Protocol_Version = skb->data[ETH_HLEN]; + Packet_Type = skb->data[ETH_HLEN+1]; + Descriptor_type = skb->data[ETH_HLEN+1+1+2]; + Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]); if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) { if(((Protocol_Version==1) ||(Protocol_Version==2)) && (Packet_Type==3)) { //802.1x OR eapol-key challenge frame transfer diff --git a/drivers/staging/vt6655/tether.h b/drivers/staging/vt6655/tether.h index af119dd82b24..4f2af359c063 100644 --- a/drivers/staging/vt6655/tether.h +++ b/drivers/staging/vt6655/tether.h @@ -36,19 +36,17 @@ // // constants // -#define U_TYPE_LEN 2 // #define U_CRC_LEN 4 // -#define U_HEADER_LEN (ETH_ALEN * 2 + U_TYPE_LEN) #define U_ETHER_ADDR_STR_LEN (ETH_ALEN * 2 + 1) // Ethernet address string length #define MIN_DATA_LEN 46 // min data length #define MAX_DATA_LEN 1500 // max data length -#define MIN_PACKET_LEN (MIN_DATA_LEN + U_HEADER_LEN) +#define MIN_PACKET_LEN (MIN_DATA_LEN + ETH_HLEN) // 60 // min total packet length (tx) -#define MAX_PACKET_LEN (MAX_DATA_LEN + U_HEADER_LEN) +#define MAX_PACKET_LEN (MAX_DATA_LEN + ETH_HLEN) // 1514 // max total packet length (tx) diff --git a/drivers/staging/vt6655/wroute.c b/drivers/staging/vt6655/wroute.c index 1d02040e80e0..485e105b0af7 100644 --- a/drivers/staging/vt6655/wroute.c +++ b/drivers/staging/vt6655/wroute.c @@ -91,9 +91,9 @@ BOOL ROUTEbRelay (PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeI pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP); - memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)pbySkbData, U_HEADER_LEN); + memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)pbySkbData, ETH_HLEN); - cbFrameBodySize = uDataLen - U_HEADER_LEN; + cbFrameBodySize = uDataLen - ETH_HLEN; if (ntohs(pDevice->sTxEthHeader.wType) > MAX_DATA_LEN) { cbFrameBodySize += 8; -- cgit v1.2.3 From 162f3ec7f026784ff2e216f19147d67e2f8ccd56 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Thu, 6 May 2010 15:19:30 +0200 Subject: drbd: Fixes to the new delay_probes code * Only send delay_probes with protocol 93 or newer * drbd_send_delay_probes() is called only from worker context, no atomic_t needed for delay_seq Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_int.h | 6 +++--- drivers/block/drbd/drbd_main.c | 8 ++++---- drivers/block/drbd/drbd_proc.c | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 37380d2c869d..45d9a4534c40 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -552,7 +552,7 @@ struct p_delay_probe { struct delay_probe { struct list_head list; - int seq_num; + unsigned int seq_num; struct timeval time; }; @@ -1048,9 +1048,9 @@ struct drbd_conf { char congestion_reason; /* Why we where congested... */ struct list_head delay_probes; /* protected by peer_seq_lock */ int data_delay; /* Delay of packets on the data-sock behind meta-sock */ - atomic_t delay_seq; /* To generate sequence numbers of delay probes */ + unsigned int delay_seq; /* To generate sequence numbers of delay probes */ struct timeval dps_time; /* delay-probes-start-time */ - int dp_volume_last; /* send_cnt of last delay probe */ + unsigned int dp_volume_last; /* send_cnt of last delay probe */ int c_sync_rate; /* current resync rate after delay_probe magic */ }; diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 44cc7b415ed4..3aa0add1c230 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2199,7 +2199,7 @@ static int drbd_send_delay_probe(struct drbd_conf *mdev, struct drbd_socket *ds) do_gettimeofday(&now); offset = now.tv_usec - mdev->dps_time.tv_usec + (now.tv_sec - mdev->dps_time.tv_sec) * 1000000; - dp.seq_num = cpu_to_be32(atomic_read(&mdev->delay_seq)); + dp.seq_num = cpu_to_be32(mdev->delay_seq); dp.offset = cpu_to_be32(offset); ok = _drbd_send_cmd(mdev, ds->socket, P_DELAY_PROBE, @@ -2213,7 +2213,8 @@ static int drbd_send_delay_probe(struct drbd_conf *mdev, struct drbd_socket *ds) static int drbd_send_delay_probes(struct drbd_conf *mdev) { int ok; - atomic_inc(&mdev->delay_seq); + + mdev->delay_seq++; do_gettimeofday(&mdev->dps_time); ok = drbd_send_delay_probe(mdev, &mdev->meta); ok = ok && drbd_send_delay_probe(mdev, &mdev->data); @@ -2355,7 +2356,7 @@ static int _drbd_send_zc_bio(struct drbd_conf *mdev, struct bio *bio) static void consider_delay_probes(struct drbd_conf *mdev) { - if (mdev->state.conn != C_SYNC_SOURCE) + if (mdev->state.conn != C_SYNC_SOURCE || mdev->agreed_pro_version < 93) return; if (mdev->dp_volume_last + mdev->sync_conf.dp_volume * 2 < mdev->send_cnt) @@ -2677,7 +2678,6 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) atomic_set(&mdev->net_cnt, 0); atomic_set(&mdev->packet_seq, 0); atomic_set(&mdev->pp_in_use, 0); - atomic_set(&mdev->delay_seq, 0); mutex_init(&mdev->md_io_mutex); mutex_init(&mdev->data.mutex); diff --git a/drivers/block/drbd/drbd_proc.c b/drivers/block/drbd/drbd_proc.c index 81dea0a85933..d0f1767ea4c3 100644 --- a/drivers/block/drbd/drbd_proc.c +++ b/drivers/block/drbd/drbd_proc.c @@ -86,8 +86,7 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq) mdev->data_delay / 1000, (mdev->data_delay % 1000) / 100); else if (mdev->state.conn == C_SYNC_SOURCE) - seq_printf(seq, " delay_probe: %d\n\t", - atomic_read(&mdev->delay_seq)); + seq_printf(seq, " delay_probe: %u\n\t", mdev->delay_seq); /* see drivers/md/md.c * We do not want to overflow, so the order of operands and -- cgit v1.2.3 From 708d740ed8242b84eefc63df144313a7308c7de5 Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Mon, 3 May 2010 10:38:57 +0200 Subject: drbd: reduce sizeof struct drbd_epoch_entry by 8 byte by aligning members Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_int.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 45d9a4534c40..1bc86ddac38b 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -747,12 +747,8 @@ struct drbd_epoch_entry { struct hlist_node colision; sector_t sector; unsigned int size; - struct drbd_epoch *epoch; - - /* up to here, the struct layout is identical to drbd_request; - * we might be able to use that to our advantage... */ - unsigned int flags; + struct drbd_epoch *epoch; u64 block_id; }; -- cgit v1.2.3 From 058276303dbc4ed089c1f7dad0871810b1f5ddf1 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 17 May 2010 16:30:42 -0700 Subject: DMAENGINE: extend the control command to include an arg This adds an argument to the DMAengine control function, so that we can later provide control commands that need some external data passed in through an argument akin to the ioctl() operation prototype. [dan.j.williams@intel.com: fix up some missed conversions] Signed-off-by: Linus Walleij Signed-off-by: Dan Williams --- drivers/dma/at_hdmac.c | 3 ++- drivers/dma/coh901318.c | 5 +++-- drivers/dma/dw_dmac.c | 3 ++- drivers/dma/fsldma.c | 2 +- drivers/dma/ipu/ipu_idmac.c | 12 +++++++----- drivers/dma/shdma.c | 3 ++- drivers/dma/ste_dma40.c | 3 ++- drivers/dma/timb_dma.c | 3 ++- drivers/dma/txx9dmac.c | 3 ++- drivers/mmc/host/atmel-mci.c | 2 +- drivers/serial/sh-sci.c | 2 +- drivers/video/mx3fb.c | 2 +- include/linux/dmaengine.h | 3 ++- sound/soc/txx9/txx9aclc.c | 7 ++++--- 14 files changed, 32 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 93ed99c84cf1..ee805a43f879 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -759,7 +759,8 @@ err_desc_get: return NULL; } -static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg) { struct at_dma_chan *atchan = to_at_dma_chan(chan); struct at_dma *atdma = to_at_dma(chan->device); diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index 4233440741a2..a724e6be1b4d 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -942,7 +942,7 @@ coh901318_free_chan_resources(struct dma_chan *chan) spin_unlock_irqrestore(&cohc->lock, flags); - chan->device->device_control(chan, DMA_TERMINATE_ALL); + chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); } @@ -1176,7 +1176,8 @@ coh901318_issue_pending(struct dma_chan *chan) } static int -coh901318_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +coh901318_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg) { unsigned long flags; struct coh901318_chan *cohc = to_coh901318_chan(chan); diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 18fb5b41cedf..a3991ab0d67e 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -781,7 +781,8 @@ err_desc_get: return NULL; } -static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg) { struct dw_dma_chan *dwc = to_dw_dma_chan(chan); struct dw_dma *dw = to_dw_dma(chan->device); diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index cb1924f46c9e..005329d496bd 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -775,7 +775,7 @@ fail: } static int fsl_dma_device_control(struct dma_chan *dchan, - enum dma_ctrl_cmd cmd) + enum dma_ctrl_cmd cmd, unsigned long arg) { struct fsldma_chan *chan; unsigned long flags; diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index 246a6143e4a7..cb26ee9773d6 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1472,7 +1472,8 @@ static void idmac_issue_pending(struct dma_chan *chan) */ } -static int __idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +static int __idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg) { struct idmac_channel *ichan = to_idmac_chan(chan); struct idmac *idmac = to_idmac(chan->device); @@ -1513,14 +1514,15 @@ static int __idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) return 0; } -static int idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +static int idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg) { struct idmac_channel *ichan = to_idmac_chan(chan); int ret; mutex_lock(&ichan->chan_mutex); - ret = __idmac_control(chan, cmd); + ret = __idmac_control(chan, cmd, arg); mutex_unlock(&ichan->chan_mutex); @@ -1616,7 +1618,7 @@ static void idmac_free_chan_resources(struct dma_chan *chan) mutex_lock(&ichan->chan_mutex); - __idmac_control(chan, DMA_TERMINATE_ALL); + __idmac_control(chan, DMA_TERMINATE_ALL, 0); if (ichan->status > IPU_CHANNEL_FREE) { #ifdef DEBUG @@ -1709,7 +1711,7 @@ static void __exit ipu_idmac_exit(struct ipu *ipu) for (i = 0; i < IPU_CHANNELS_NUM; i++) { struct idmac_channel *ichan = ipu->channel + i; - idmac_control(&ichan->dma_chan, DMA_TERMINATE_ALL); + idmac_control(&ichan->dma_chan, DMA_TERMINATE_ALL, 0); idmac_prep_slave_sg(&ichan->dma_chan, NULL, 0, DMA_NONE, 0); } diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 98f82cdb404c..e9de1d35c20d 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -580,7 +580,8 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg( direction, flags); } -static int sh_dmae_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +static int sh_dmae_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg) { struct sh_dmae_chan *sh_chan = to_sh_chan(chan); diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 81fec95312b6..c426829f6ab8 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -2065,7 +2065,8 @@ static void d40_issue_pending(struct dma_chan *chan) spin_unlock_irqrestore(&d40c->lock, flags); } -static int d40_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +static int d40_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg) { unsigned long flags; struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index 44b346d8d319..0172fa3c7a2b 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -611,7 +611,8 @@ static struct dma_async_tx_descriptor *td_prep_slave_sg(struct dma_chan *chan, return &td_desc->txd; } -static int td_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +static int td_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg) { struct timb_dma_chan *td_chan = container_of(chan, struct timb_dma_chan, chan); diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c index e523737639aa..d02edb05910e 100644 --- a/drivers/dma/txx9dmac.c +++ b/drivers/dma/txx9dmac.c @@ -938,7 +938,8 @@ txx9dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, return &first->txd; } -static int txx9dmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd) +static int txx9dmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg) { struct txx9dmac_chan *dc = to_txx9dmac_chan(chan); struct txx9dmac_desc *desc, *_desc; diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index ae6d24ba4f08..fd2d24f81478 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -578,7 +578,7 @@ static void atmci_stop_dma(struct atmel_mci *host) struct dma_chan *chan = host->data_chan; if (chan) { - chan->device->device_control(chan, DMA_TERMINATE_ALL); + chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); atmci_dma_cleanup(host); } else { /* Data transfer was stopped by the interrupt handler */ diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 690988237971..882f3d5ed028 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -1087,7 +1087,7 @@ static void work_fn_rx(struct work_struct *work) unsigned long flags; int count; - chan->device->device_control(chan, DMA_TERMINATE_ALL); + chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); dev_dbg(port->dev, "Read %u bytes with cookie %d\n", sh_desc->partial, sh_desc->cookie); diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c index 3aa50bc276eb..7cfc170bce19 100644 --- a/drivers/video/mx3fb.c +++ b/drivers/video/mx3fb.c @@ -388,7 +388,7 @@ static void sdc_disable_channel(struct mx3fb_info *mx3_fbi) spin_unlock_irqrestore(&mx3fb->lock, flags); mx3_fbi->txd->chan->device->device_control(mx3_fbi->txd->chan, - DMA_TERMINATE_ALL); + DMA_TERMINATE_ALL, 0); mx3_fbi->txd = NULL; mx3_fbi->cookie = -EINVAL; } diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 50b7b3e0d572..17456571ff7a 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -347,7 +347,8 @@ struct dma_device { struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, enum dma_data_direction direction, unsigned long flags); - int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd cmd); + int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg); enum dma_status (*device_tx_status)(struct dma_chan *chan, dma_cookie_t cookie, diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c index b35d00706c0e..9398f507f77f 100644 --- a/sound/soc/txx9/txx9aclc.c +++ b/sound/soc/txx9/txx9aclc.c @@ -159,7 +159,7 @@ static void txx9aclc_dma_tasklet(unsigned long data) void __iomem *base = drvdata->base; spin_unlock_irqrestore(&dmadata->dma_lock, flags); - chan->device->device_control(chan, DMA_TERMINATE_ALL); + chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); /* first time */ for (i = 0; i < NR_DMA_CHAIN; i++) { desc = txx9aclc_dma_submit(dmadata, @@ -267,7 +267,7 @@ static int txx9aclc_pcm_close(struct snd_pcm_substream *substream) struct dma_chan *chan = dmadata->dma_chan; dmadata->frag_count = -1; - chan->device->device_control(chan, DMA_TERMINATE_ALL); + chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); return 0; } @@ -396,7 +396,8 @@ static int txx9aclc_pcm_remove(struct platform_device *pdev) struct dma_chan *chan = dmadata->dma_chan; if (chan) { dmadata->frag_count = -1; - chan->device->device_control(chan, DMA_TERMINATE_ALL); + chan->device->device_control(chan, + DMA_TERMINATE_ALL, 0); dma_release_channel(chan); } dev->dmadata[i].dma_chan = NULL; -- cgit v1.2.3 From 94002c07ff0e207a883519ccc35c0b5390b29331 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 15 May 2010 23:21:43 +0200 Subject: Staging: Use kmemdup Use kmemdup when some other buffer is immediately copied into the allocated region. A simplified version of the semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression from,to,size,flag; statement S; @@ - to = \(kmalloc\|kzalloc\)(size,flag); + to = kmemdup(from,size,flag); if (to==NULL || ...) S - memcpy(to, from, size); // Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbdux.c | 3 +-- drivers/staging/comedi/drivers/usbduxfast.c | 3 +-- drivers/staging/hv/vmbus.c | 3 +-- drivers/staging/line6/dumprequest.c | 3 +-- drivers/staging/line6/pod.c | 6 ++---- drivers/staging/line6/variax.c | 5 ++--- drivers/staging/pohmelfs/config.c | 16 ++++++---------- drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c | 4 ++-- drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c | 3 +-- drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c | 4 ++-- drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c | 3 +-- drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c | 4 ++-- drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c | 3 +-- drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c | 7 +++---- drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c | 3 +-- drivers/staging/usbip/stub_rx.c | 4 ++-- 16 files changed, 29 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index df71515c7a30..86f035d00675 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -840,13 +840,12 @@ static int firmwareUpload(struct usbduxsub *usbduxsub, } /* we generate a local buffer for the firmware */ - fwBuf = kzalloc(sizeFirmware, GFP_KERNEL); + fwBuf = kmemdup(firmwareBinary, sizeFirmware, GFP_KERNEL); if (!fwBuf) { dev_err(&usbduxsub->interface->dev, "comedi_: mem alloc for firmware failed\n"); return -ENOMEM; } - memcpy(fwBuf, firmwareBinary, sizeFirmware); ret = usbduxsub_stop(usbduxsub); if (ret < 0) { diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 0d72c416e73b..29c3c016b93a 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -1368,13 +1368,12 @@ static int firmwareUpload(struct usbduxfastsub_s *usbduxfastsub, } /* we generate a local buffer for the firmware */ - fwBuf = kzalloc(sizeFirmware, GFP_KERNEL); + fwBuf = kmemdup(firmwareBinary, sizeFirmware, GFP_KERNEL); if (!fwBuf) { dev_err(&usbduxfastsub->interface->dev, "comedi_: mem alloc for firmware failed\n"); return -ENOMEM; } - memcpy(fwBuf, firmwareBinary, sizeFirmware); ret = usbduxfastsub_stop(usbduxfastsub); if (ret < 0) { diff --git a/drivers/staging/hv/vmbus.c b/drivers/staging/hv/vmbus.c index 0a9d8459db0c..007543bdb410 100644 --- a/drivers/staging/hv/vmbus.c +++ b/drivers/staging/hv/vmbus.c @@ -185,11 +185,10 @@ static void VmbusOnMsgDPC(struct hv_driver *drv) /* no msg */ break; } else { - copied = kmalloc(sizeof(*copied), GFP_ATOMIC); + copied = kmemdup(msg, sizeof(*copied), GFP_ATOMIC); if (copied == NULL) continue; - memcpy(copied, msg, sizeof(*copied)); osd_schedule_callback(gVmbusConnection.WorkQueue, VmbusOnChannelMessage, (void *)copied); diff --git a/drivers/staging/line6/dumprequest.c b/drivers/staging/line6/dumprequest.c index bb8c9da5803f..cd468c39da5c 100644 --- a/drivers/staging/line6/dumprequest.c +++ b/drivers/staging/line6/dumprequest.c @@ -105,10 +105,9 @@ int line6_wait_dump(struct line6_dump_request *l6dr, int nonblock) int line6_dumpreq_initbuf(struct line6_dump_request *l6dr, const void *buf, size_t len, int num) { - l6dr->reqbufs[num].buffer = kmalloc(len, GFP_KERNEL); + l6dr->reqbufs[num].buffer = kmemdup(buf, len, GFP_KERNEL); if (l6dr->reqbufs[num].buffer == NULL) return -ENOMEM; - memcpy(l6dr->reqbufs[num].buffer, buf, len); l6dr->reqbufs[num].length = len; return 0; } diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c index 4983f2b51cf2..28f514611abc 100644 --- a/drivers/staging/line6/pod.c +++ b/drivers/staging/line6/pod.c @@ -1074,7 +1074,8 @@ int pod_init(struct usb_interface *interface, struct usb_line6_pod *pod) return -ENOMEM; } - pod->buffer_versionreq = kmalloc(sizeof(pod_request_version), + pod->buffer_versionreq = kmemdup(pod_request_version, + sizeof(pod_request_version), GFP_KERNEL); if (pod->buffer_versionreq == NULL) { @@ -1083,9 +1084,6 @@ int pod_init(struct usb_interface *interface, struct usb_line6_pod *pod) return -ENOMEM; } - memcpy(pod->buffer_versionreq, pod_request_version, - sizeof(pod_request_version)); - /* create sysfs entries: */ err = pod_create_files2(&interface->dev); if (err < 0) { diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c index 28eb89983f36..58ddbe6393ff 100644 --- a/drivers/staging/line6/variax.c +++ b/drivers/staging/line6/variax.c @@ -486,7 +486,8 @@ int variax_init(struct usb_interface *interface, return err; } - variax->buffer_activate = kmalloc(sizeof(variax_activate), GFP_KERNEL); + variax->buffer_activate = kmemdup(variax_activate, + sizeof(variax_activate), GFP_KERNEL); if (variax->buffer_activate == NULL) { dev_err(&interface->dev, "Out of memory\n"); @@ -494,8 +495,6 @@ int variax_init(struct usb_interface *interface, return -ENOMEM; } - memcpy(variax->buffer_activate, variax_activate, - sizeof(variax_activate)); init_timer(&variax->activate_timer); /* create sysfs entries: */ diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c index 9fdf2de347ea..8c8d1c282e7e 100644 --- a/drivers/staging/pohmelfs/config.c +++ b/drivers/staging/pohmelfs/config.c @@ -204,18 +204,18 @@ int pohmelfs_copy_crypto(struct pohmelfs_sb *psb) } if (g->hash_keysize) { - psb->hash_key = kmalloc(g->hash_keysize, GFP_KERNEL); + psb->hash_key = kmemdup(g->hash_key, g->hash_keysize, + GFP_KERNEL); if (!psb->hash_key) goto err_out_free_cipher_string; - memcpy(psb->hash_key, g->hash_key, g->hash_keysize); psb->hash_keysize = g->hash_keysize; } if (g->cipher_keysize) { - psb->cipher_key = kmalloc(g->cipher_keysize, GFP_KERNEL); + psb->cipher_key = kmemdup(g->cipher_key, g->cipher_keysize, + GFP_KERNEL); if (!psb->cipher_key) goto err_out_free_hash; - memcpy(psb->cipher_key, g->cipher_key, g->cipher_keysize); psb->cipher_keysize = g->cipher_keysize; } @@ -454,14 +454,12 @@ static int pohmelfs_crypto_hash_init(struct pohmelfs_config_group *g, struct poh g->hash_strlen = c->strlen; g->hash_keysize = c->keysize; - g->hash_key = kmalloc(c->keysize, GFP_KERNEL); + g->hash_key = kmemdup(key, c->keysize, GFP_KERNEL); if (!g->hash_key) { kfree(g->hash_string); return -ENOMEM; } - memcpy(g->hash_key, key, c->keysize); - return 0; } @@ -479,14 +477,12 @@ static int pohmelfs_crypto_cipher_init(struct pohmelfs_config_group *g, struct p g->cipher_strlen = c->strlen; g->cipher_keysize = c->keysize; - g->cipher_key = kmalloc(c->keysize, GFP_KERNEL); + g->cipher_key = kmemdup(key, c->keysize, GFP_KERNEL); if (!g->cipher_key) { kfree(g->cipher_string); return -ENOMEM; } - memcpy(g->cipher_key, key, c->keysize); - return 0; } diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index b7426fea5498..1b838a266e0d 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c @@ -2667,11 +2667,11 @@ static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee, return -EINVAL; if (param->u.wpa_ie.len) { - buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL); + buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len, + GFP_KERNEL); if (buf == NULL) return -ENOMEM; - memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len); kfree(ieee->wpa_ie); ieee->wpa_ie = buf; ieee->wpa_ie_len = param->u.wpa_ie.len; diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c index aa3ba450ecef..07d8dbcdca28 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c @@ -727,10 +727,9 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len) printk("len:%zu, ie:%d\n", len, ie[1]); return -EINVAL; } - buf = kmalloc(len, GFP_KERNEL); + buf = kmemdup(ie, len, GFP_KERNEL); if (buf == NULL) return -ENOMEM; - memcpy(buf, ie, len); kfree(ieee->wpa_ie); ieee->wpa_ie = buf; ieee->wpa_ie_len = len; diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index 215542a00ef1..46b6e8c900e9 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -3255,11 +3255,11 @@ static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee, return -EINVAL; if (param->u.wpa_ie.len) { - buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL); + buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len, + GFP_KERNEL); if (buf == NULL) return -ENOMEM; - memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len); kfree(ieee->wpa_ie); ieee->wpa_ie = buf; ieee->wpa_ie_len = param->u.wpa_ie.len; diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c index fcabaf3c88d4..4971b1c8e7d7 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c @@ -979,10 +979,9 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len) printk("len:%zu, ie:%d\n", len, ie[1]); return -EINVAL; } - buf = kmalloc(len, GFP_KERNEL); + buf = kmemdup(ie, len, GFP_KERNEL); if (buf == NULL) return -ENOMEM; - memcpy(buf, ie, len); kfree(ieee->wpa_ie); ieee->wpa_ie = buf; ieee->wpa_ie_len = len; diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c index b9fa15fccb78..4f1f2f08b2d7 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c @@ -2844,11 +2844,11 @@ static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee, return -EINVAL; if (param->u.wpa_ie.len) { - buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL); + buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len, + GFP_KERNEL); if (buf == NULL) return -ENOMEM; - memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len); kfree(ieee->wpa_ie); ieee->wpa_ie = buf; ieee->wpa_ie_len = param->u.wpa_ie.len; diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c index db54ad096da0..2ce5bd543eae 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c @@ -767,10 +767,9 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len) printk("len: %Zd, ie:%d\n", len, ie[1]); return -EINVAL; } - buf = kmalloc(len, GFP_KERNEL); + buf = kmemdup(ie, len, GFP_KERNEL); if (buf == NULL) return -ENOMEM; - memcpy(buf, ie, len); kfree(ieee->wpa_ie); ieee->wpa_ie = buf; ieee->wpa_ie_len = len; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index a6955e2b45c4..a2e84c578579 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -1579,10 +1579,9 @@ static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen) if(*(t++) == MFIE_TYPE_CHALLENGE){ *chlen = *(t++); - *challenge = kmalloc(*chlen, GFP_ATOMIC); + *challenge = kmemdup(t, *chlen, GFP_ATOMIC); if (!*challenge) return -ENOMEM; - memcpy(*challenge, t, *chlen); } } @@ -2870,11 +2869,11 @@ static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee, return -EINVAL; if (param->u.wpa_ie.len) { - buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL); + buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len, + GFP_KERNEL); if (buf == NULL) return -ENOMEM; - memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len); kfree(ieee->wpa_ie); ieee->wpa_ie = buf; ieee->wpa_ie_len = param->u.wpa_ie.len; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c index 79b180f79e80..fb78ed2876e5 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c @@ -847,10 +847,9 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len) printk("len:%zu, ie:%d\n", len, ie[1]); return -EINVAL; } - buf = kmalloc(len, GFP_KERNEL); + buf = kmemdup(ie, len, GFP_KERNEL); if (buf == NULL) return -ENOMEM; - memcpy(buf, ie, len); kfree(ieee->wpa_ie); ieee->wpa_ie = buf; ieee->wpa_ie_len = len; diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c index bc2674086673..feb9fd7a7bb9 100644 --- a/drivers/staging/usbip/stub_rx.c +++ b/drivers/staging/usbip/stub_rx.c @@ -502,13 +502,13 @@ static void stub_recv_cmd_submit(struct stub_device *sdev, } /* set priv->urb->setup_packet */ - priv->urb->setup_packet = kzalloc(8, GFP_KERNEL); + priv->urb->setup_packet = kmemdup(&pdu->u.cmd_submit.setup, 8, + GFP_KERNEL); if (!priv->urb->setup_packet) { dev_err(&sdev->interface->dev, "allocate setup_packet\n"); usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC); return; } - memcpy(priv->urb->setup_packet, &pdu->u.cmd_submit.setup, 8); /* set other members from the base header of pdu */ priv->urb->context = (void *) priv; -- cgit v1.2.3 From 9153f7b997aef3fcfd0bf1eededfd76595c7dc0b Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Sat, 15 May 2010 14:39:58 -0700 Subject: staging: hv: Added heartbeat functionality to hv_utils Add heartbeat functionality to hv_utils/Hyper-V Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel_mgmt.c | 23 ++++++++++++-- drivers/staging/hv/hv_utils.c | 64 +++++++++++++++++++++++++++++++++++++++ drivers/staging/hv/utils.h | 5 +++ drivers/staging/hv/version_info.h | 3 +- 4 files changed, 92 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 6877e8e7f71e..3f53b4d1e4cf 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -33,8 +33,8 @@ struct vmbus_channel_message_table_entry { void (*messageHandler)(struct vmbus_channel_message_header *msg); }; -#define MAX_MSG_TYPES 2 -#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 6 +#define MAX_MSG_TYPES 3 +#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 7 static const struct hv_guid gSupportedDeviceClasses[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = { @@ -89,6 +89,14 @@ static const struct hv_guid 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf } }, + /* {57164f39-9115-4e78-ab55-382f3bd5422d} */ + /* Heartbeat */ + { + .data = { + 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, + 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d + } + }, }; @@ -211,6 +219,17 @@ struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = { .callback = chn_cb_negotiate, .log_msg = "Timesync channel functionality initialized" }, + /* {57164f39-9115-4e78-ab55-382f3bd5422d} */ + /* Heartbeat */ + { + .msg_type = HV_HEARTBEAT_MSG, + .data = { + 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, + 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d + }, + .callback = chn_cb_negotiate, + .log_msg = "Heartbeat channel functionality initialized" + }, }; EXPORT_SYMBOL(hv_cb_utils); diff --git a/drivers/staging/hv/hv_utils.c b/drivers/staging/hv/hv_utils.c index db45d97a3a7c..8a49aafea37a 100644 --- a/drivers/staging/hv/hv_utils.c +++ b/drivers/staging/hv/hv_utils.c @@ -194,6 +194,62 @@ static void timesync_onchannelcallback(void *context) DPRINT_EXIT(VMBUS); } +/* + * Heartbeat functionality. + * Every two seconds, Hyper-V send us a heartbeat request message. + * we respond to this message, and Hyper-V knows we are alive. + */ +static void heartbeat_onchannelcallback(void *context) +{ + struct vmbus_channel *channel = context; + u8 *buf; + u32 buflen, recvlen; + u64 requestid; + struct icmsg_hdr *icmsghdrp; + struct heartbeat_msg_data *heartbeat_msg; + + DPRINT_ENTER(VMBUS); + + buflen = PAGE_SIZE; + buf = kmalloc(buflen, GFP_ATOMIC); + + VmbusChannelRecvPacket(channel, buf, buflen, &recvlen, &requestid); + + if (recvlen > 0) { + DPRINT_DBG(VMBUS, "heartbeat packet: len=%d, requestid=%lld", + recvlen, requestid); + + icmsghdrp = (struct icmsg_hdr *)&buf[ + sizeof(struct vmbuspipe_hdr)]; + + icmsghdrp = (struct icmsg_hdr *)&buf[ + sizeof(struct vmbuspipe_hdr)]; + + if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { + prep_negotiate_resp(icmsghdrp, NULL, buf); + } else { + heartbeat_msg = (struct heartbeat_msg_data *)&buf[ + sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; + + DPRINT_DBG(VMBUS, "heartbeat seq = %lld", + heartbeat_msg->seq_num); + + heartbeat_msg->seq_num += 1; + } + + icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION + | ICMSGHDRFLAG_RESPONSE; + + VmbusChannelSendPacket(channel, buf, + recvlen, requestid, + VmbusPacketTypeDataInBand, 0); + } + + kfree(buf); + + DPRINT_EXIT(VMBUS); +} static int __init init_hyperv_utils(void) { @@ -207,6 +263,10 @@ static int __init init_hyperv_utils(void) ×ync_onchannelcallback; hv_cb_utils[HV_TIMESYNC_MSG].callback = ×ync_onchannelcallback; + hv_cb_utils[HV_HEARTBEAT_MSG].channel->OnChannelCallback = + &heartbeat_onchannelcallback; + hv_cb_utils[HV_HEARTBEAT_MSG].callback = &heartbeat_onchannelcallback; + return 0; } @@ -221,6 +281,10 @@ static void exit_hyperv_utils(void) hv_cb_utils[HV_TIMESYNC_MSG].channel->OnChannelCallback = &chn_cb_negotiate; hv_cb_utils[HV_TIMESYNC_MSG].callback = &chn_cb_negotiate; + + hv_cb_utils[HV_HEARTBEAT_MSG].channel->OnChannelCallback = + &chn_cb_negotiate; + hv_cb_utils[HV_HEARTBEAT_MSG].callback = &chn_cb_negotiate; } module_init(init_hyperv_utils); diff --git a/drivers/staging/hv/utils.h b/drivers/staging/hv/utils.h index a4b9fd06e270..7c0749999a6f 100644 --- a/drivers/staging/hv/utils.h +++ b/drivers/staging/hv/utils.h @@ -75,6 +75,10 @@ struct shutdown_msg_data { u8 display_message[2048]; } __attribute__((packed)); +struct heartbeat_msg_data { + u64 seq_num; + u32 reserved[8]; +} __attribute__((packed)); /* Time Sync IC defs */ #define ICTIMESYNCFLAG_PROBE 0 @@ -97,6 +101,7 @@ struct ictimesync_data{ /* Index for each IC struct in array hv_cb_utils[] */ #define HV_SHUTDOWN_MSG 0 #define HV_TIMESYNC_MSG 1 +#define HV_HEARTBEAT_MSG 2 struct hyperv_service_callback { u8 msg_type; diff --git a/drivers/staging/hv/version_info.h b/drivers/staging/hv/version_info.h index 82e74b1ab150..35178f2c7967 100644 --- a/drivers/staging/hv/version_info.h +++ b/drivers/staging/hv/version_info.h @@ -40,8 +40,9 @@ * Minor Number Changes when new functionality is added * to the Linux IC's that is not a bug fix. * + * 3.1 - Added completed hv_utils driver. Shutdown/Heartbeat/Timesync */ -#define HV_DRV_VERSION "3.0" +#define HV_DRV_VERSION "3.1" #endif -- cgit v1.2.3 From 59497bba59035a2b09ac21f96bb904d1101bd95f Mon Sep 17 00:00:00 2001 From: Christoph Fritz Date: Sun, 16 May 2010 23:45:59 +0200 Subject: Staging: wlan-ng prism2usb: add suspend/resume There is no need trying to load the (even in most cases) not availible firmware after suspend. This saves about 30 secounds on reset waiting for timeout. Signed-off-by: Christoph Fritz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/prism2usb.c | 65 +++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/wlan-ng/prism2usb.c b/drivers/staging/wlan-ng/prism2usb.c index 501d27f74c7d..f5cff751db2f 100644 --- a/drivers/staging/wlan-ng/prism2usb.c +++ b/drivers/staging/wlan-ng/prism2usb.c @@ -285,11 +285,76 @@ exit: usb_set_intfdata(interface, NULL); } +#ifdef CONFIG_PM +static int prism2sta_suspend(struct usb_interface *interface, + pm_message_t message) +{ + hfa384x_t *hw = NULL; + wlandevice_t *wlandev; + wlandev = (wlandevice_t *) usb_get_intfdata(interface); + if (!wlandev) + return -ENODEV; + + hw = wlandev->priv; + if (!hw) + return -ENODEV; + + prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable); + + usb_kill_urb(&hw->rx_urb); + usb_kill_urb(&hw->tx_urb); + usb_kill_urb(&hw->ctlx_urb); + + return 0; +} + +static int prism2sta_resume(struct usb_interface *interface) +{ + int result = 0; + hfa384x_t *hw = NULL; + wlandevice_t *wlandev; + wlandev = (wlandevice_t *) usb_get_intfdata(interface); + if (!wlandev) + return -ENODEV; + + hw = wlandev->priv; + if (!hw) + return -ENODEV; + + /* Do a chip-level reset on the MAC */ + if (prism2_doreset) { + result = hfa384x_corereset(hw, + prism2_reset_holdtime, + prism2_reset_settletime, 0); + if (result != 0) { + unregister_wlandev(wlandev); + hfa384x_destroy(hw); + printk(KERN_ERR + "%s: hfa384x_corereset() failed.\n", dev_info); + kfree(wlandev); + kfree(hw); + wlandev = NULL; + return -ENODEV; + } + } + + prism2sta_ifstate(wlandev, P80211ENUM_ifstate_enable); + + return 0; +} +#else +#define prism2sta_suspend NULL +#define prism2sta_resume NULL +#endif /* CONFIG_PM */ + static struct usb_driver prism2_usb_driver = { .name = "prism2_usb", .probe = prism2sta_probe_usb, .disconnect = prism2sta_disconnect_usb, .id_table = usb_prism_tbl, + .suspend = prism2sta_suspend, + .resume = prism2sta_resume, + .reset_resume = prism2sta_resume, /* fops, minor? */ }; -- cgit v1.2.3 From 45bb912bd5ea4d2b3a270a93cbdf767a0e2df6f5 Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Fri, 14 May 2010 17:10:48 +0200 Subject: drbd: Allow drbd_epoch_entries to use multiple bios. This should allow for better performance if the lower level IO stack of the peers differs in limits exposed either via the queue, or via some merge_bvec_fn. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_int.h | 90 +++++-- drivers/block/drbd/drbd_main.c | 19 +- drivers/block/drbd/drbd_nl.c | 18 +- drivers/block/drbd/drbd_receiver.c | 483 +++++++++++++++++++++---------------- drivers/block/drbd/drbd_worker.c | 178 ++++++++------ drivers/block/drbd/drbd_wrappers.h | 16 +- 6 files changed, 480 insertions(+), 324 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 1bc86ddac38b..4b97f30bb7c6 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -740,18 +740,6 @@ enum epoch_event { EV_CLEANUP = 32, /* used as flag */ }; -struct drbd_epoch_entry { - struct drbd_work w; - struct drbd_conf *mdev; - struct bio *private_bio; - struct hlist_node colision; - sector_t sector; - unsigned int size; - unsigned int flags; - struct drbd_epoch *epoch; - u64 block_id; -}; - struct drbd_wq_barrier { struct drbd_work w; struct completion done; @@ -762,17 +750,49 @@ struct digest_info { void *digest; }; -/* ee flag bits */ +struct drbd_epoch_entry { + struct drbd_work w; + struct hlist_node colision; + struct drbd_epoch *epoch; + struct drbd_conf *mdev; + struct page *pages; + atomic_t pending_bios; + unsigned int size; + /* see comments on ee flag bits below */ + unsigned long flags; + sector_t sector; + u64 block_id; +}; + +/* ee flag bits. + * While corresponding bios are in flight, the only modification will be + * set_bit WAS_ERROR, which has to be atomic. + * If no bios are in flight yet, or all have been completed, + * non-atomic modification to ee->flags is ok. + */ enum { __EE_CALL_AL_COMPLETE_IO, - __EE_CONFLICT_PENDING, __EE_MAY_SET_IN_SYNC, + + /* This epoch entry closes an epoch using a barrier. + * On sucessful completion, the epoch is released, + * and the P_BARRIER_ACK send. */ __EE_IS_BARRIER, + + /* In case a barrier failed, + * we need to resubmit without the barrier flag. */ + __EE_RESUBMITTED, + + /* we may have several bios per epoch entry. + * if any of those fail, we set this flag atomically + * from the endio callback */ + __EE_WAS_ERROR, }; #define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO) -#define EE_CONFLICT_PENDING (1<<__EE_CONFLICT_PENDING) #define EE_MAY_SET_IN_SYNC (1<<__EE_MAY_SET_IN_SYNC) #define EE_IS_BARRIER (1<<__EE_IS_BARRIER) +#define EE_RESUBMITTED (1<<__EE_RESUBMITTED) +#define EE_WAS_ERROR (1<<__EE_WAS_ERROR) /* global flag bits */ enum { @@ -1441,7 +1461,8 @@ static inline void ov_oos_print(struct drbd_conf *mdev) } -extern void drbd_csum(struct drbd_conf *, struct crypto_hash *, struct bio *, void *); +extern void drbd_csum_bio(struct drbd_conf *, struct crypto_hash *, struct bio *, void *); +extern void drbd_csum_ee(struct drbd_conf *, struct crypto_hash *, struct drbd_epoch_entry *, void *); /* worker callbacks */ extern int w_req_cancel_conflict(struct drbd_conf *, struct drbd_work *, int); extern int w_read_retry_remote(struct drbd_conf *, struct drbd_work *, int); @@ -1465,6 +1486,8 @@ extern int w_e_reissue(struct drbd_conf *, struct drbd_work *, int); extern void resync_timer_fn(unsigned long data); /* drbd_receiver.c */ +extern int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, + const unsigned rw, const int fault_type); extern int drbd_release_ee(struct drbd_conf *mdev, struct list_head *list); extern struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev, u64 id, @@ -1620,6 +1643,41 @@ void drbd_bcast_ee(struct drbd_conf *mdev, * inline helper functions *************************/ +/* see also page_chain_add and friends in drbd_receiver.c */ +static inline struct page *page_chain_next(struct page *page) +{ + return (struct page *)page_private(page); +} +#define page_chain_for_each(page) \ + for (; page && ({ prefetch(page_chain_next(page)); 1; }); \ + page = page_chain_next(page)) +#define page_chain_for_each_safe(page, n) \ + for (; page && ({ n = page_chain_next(page); 1; }); page = n) + +static inline int drbd_bio_has_active_page(struct bio *bio) +{ + struct bio_vec *bvec; + int i; + + __bio_for_each_segment(bvec, bio, i, 0) { + if (page_count(bvec->bv_page) > 1) + return 1; + } + + return 0; +} + +static inline int drbd_ee_has_active_page(struct drbd_epoch_entry *e) +{ + struct page *page = e->pages; + page_chain_for_each(page) { + if (page_count(page) > 1) + return 1; + } + return 0; +} + + static inline void drbd_state_lock(struct drbd_conf *mdev) { wait_event(mdev->misc_wait, diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 3aa0add1c230..d0fabace1452 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2354,6 +2354,19 @@ static int _drbd_send_zc_bio(struct drbd_conf *mdev, struct bio *bio) return 1; } +static int _drbd_send_zc_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e) +{ + struct page *page = e->pages; + unsigned len = e->size; + page_chain_for_each(page) { + unsigned l = min_t(unsigned, len, PAGE_SIZE); + if (!_drbd_send_page(mdev, page, 0, l)) + return 0; + len -= l; + } + return 1; +} + static void consider_delay_probes(struct drbd_conf *mdev) { if (mdev->state.conn != C_SYNC_SOURCE || mdev->agreed_pro_version < 93) @@ -2430,7 +2443,7 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req) drbd_send(mdev, mdev->data.socket, &p, sizeof(p), MSG_MORE)); if (ok && dgs) { dgb = mdev->int_dig_out; - drbd_csum(mdev, mdev->integrity_w_tfm, req->master_bio, dgb); + drbd_csum_bio(mdev, mdev->integrity_w_tfm, req->master_bio, dgb); ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, MSG_MORE); } if (ok) { @@ -2483,11 +2496,11 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd, sizeof(p), MSG_MORE); if (ok && dgs) { dgb = mdev->int_dig_out; - drbd_csum(mdev, mdev->integrity_w_tfm, e->private_bio, dgb); + drbd_csum_ee(mdev, mdev->integrity_w_tfm, e, dgb); ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, MSG_MORE); } if (ok) - ok = _drbd_send_zc_bio(mdev, e->private_bio); + ok = _drbd_send_zc_ee(mdev, e); drbd_put_data_sock(mdev); diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 93d150661f4b..28ef76bd5230 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -2215,9 +2215,9 @@ void drbd_bcast_ee(struct drbd_conf *mdev, { struct cn_msg *cn_reply; struct drbd_nl_cfg_reply *reply; - struct bio_vec *bvec; unsigned short *tl; - int i; + struct page *page; + unsigned len; if (!e) return; @@ -2255,11 +2255,15 @@ void drbd_bcast_ee(struct drbd_conf *mdev, put_unaligned(T_ee_data, tl++); put_unaligned(e->size, tl++); - __bio_for_each_segment(bvec, e->private_bio, i, 0) { - void *d = kmap(bvec->bv_page); - memcpy(tl, d + bvec->bv_offset, bvec->bv_len); - kunmap(bvec->bv_page); - tl=(unsigned short*)((char*)tl + bvec->bv_len); + len = e->size; + page = e->pages; + page_chain_for_each(page) { + void *d = kmap_atomic(page, KM_USER0); + unsigned l = min_t(unsigned, len, PAGE_SIZE); + memcpy(tl, d, l); + kunmap_atomic(d, KM_USER0); + tl = (unsigned short*)((char*)tl + l); + len -= l; } put_unaligned(TT_END, tl++); /* Close the tag list */ diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index fee0d249adf7..388a3e8bb0d0 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -80,30 +80,124 @@ static struct drbd_epoch *previous_epoch(struct drbd_conf *mdev, struct drbd_epo #define GFP_TRY (__GFP_HIGHMEM | __GFP_NOWARN) -static struct page *drbd_pp_first_page_or_try_alloc(struct drbd_conf *mdev) +/* + * some helper functions to deal with single linked page lists, + * page->private being our "next" pointer. + */ + +/* If at least n pages are linked at head, get n pages off. + * Otherwise, don't modify head, and return NULL. + * Locking is the responsibility of the caller. + */ +static struct page *page_chain_del(struct page **head, int n) +{ + struct page *page; + struct page *tmp; + + BUG_ON(!n); + BUG_ON(!head); + + page = *head; + while (page) { + tmp = page_chain_next(page); + if (--n == 0) + break; /* found sufficient pages */ + if (tmp == NULL) + /* insufficient pages, don't use any of them. */ + return NULL; + page = tmp; + } + + /* add end of list marker for the returned list */ + set_page_private(page, 0); + /* actual return value, and adjustment of head */ + page = *head; + *head = tmp; + return page; +} + +/* may be used outside of locks to find the tail of a (usually short) + * "private" page chain, before adding it back to a global chain head + * with page_chain_add() under a spinlock. */ +static struct page *page_chain_tail(struct page *page, int *len) +{ + struct page *tmp; + int i = 1; + while ((tmp = page_chain_next(page))) + ++i, page = tmp; + if (len) + *len = i; + return page; +} + +static int page_chain_free(struct page *page) +{ + struct page *tmp; + int i = 0; + page_chain_for_each_safe(page, tmp) { + put_page(page); + ++i; + } + return i; +} + +static void page_chain_add(struct page **head, + struct page *chain_first, struct page *chain_last) +{ +#if 1 + struct page *tmp; + tmp = page_chain_tail(chain_first, NULL); + BUG_ON(tmp != chain_last); +#endif + + /* add chain to head */ + set_page_private(chain_last, (unsigned long)*head); + *head = chain_first; +} + +static struct page *drbd_pp_first_pages_or_try_alloc(struct drbd_conf *mdev, int number) { struct page *page = NULL; + struct page *tmp = NULL; + int i = 0; /* Yes, testing drbd_pp_vacant outside the lock is racy. * So what. It saves a spin_lock. */ - if (drbd_pp_vacant > 0) { + if (drbd_pp_vacant >= number) { spin_lock(&drbd_pp_lock); - page = drbd_pp_pool; - if (page) { - drbd_pp_pool = (struct page *)page_private(page); - set_page_private(page, 0); /* just to be polite */ - drbd_pp_vacant--; - } + page = page_chain_del(&drbd_pp_pool, number); + if (page) + drbd_pp_vacant -= number; spin_unlock(&drbd_pp_lock); + if (page) + return page; } + /* GFP_TRY, because we must not cause arbitrary write-out: in a DRBD * "criss-cross" setup, that might cause write-out on some other DRBD, * which in turn might block on the other node at this very place. */ - if (!page) - page = alloc_page(GFP_TRY); - if (page) - atomic_inc(&mdev->pp_in_use); - return page; + for (i = 0; i < number; i++) { + tmp = alloc_page(GFP_TRY); + if (!tmp) + break; + set_page_private(tmp, (unsigned long)page); + page = tmp; + } + + if (i == number) + return page; + + /* Not enough pages immediately available this time. + * No need to jump around here, drbd_pp_alloc will retry this + * function "soon". */ + if (page) { + tmp = page_chain_tail(page, NULL); + spin_lock(&drbd_pp_lock); + page_chain_add(&drbd_pp_pool, page, tmp); + drbd_pp_vacant += i; + spin_unlock(&drbd_pp_lock); + } + return NULL; } /* kick lower level device, if we have more than (arbitrary number) @@ -127,7 +221,7 @@ static void reclaim_net_ee(struct drbd_conf *mdev, struct list_head *to_be_freed list_for_each_safe(le, tle, &mdev->net_ee) { e = list_entry(le, struct drbd_epoch_entry, w.list); - if (drbd_bio_has_active_page(e->private_bio)) + if (drbd_ee_has_active_page(e)) break; list_move(le, to_be_freed); } @@ -148,32 +242,34 @@ static void drbd_kick_lo_and_reclaim_net(struct drbd_conf *mdev) } /** - * drbd_pp_alloc() - Returns a page, fails only if a signal comes in + * drbd_pp_alloc() - Returns @number pages, retries forever (or until signalled) * @mdev: DRBD device. - * @retry: whether or not to retry allocation forever (or until signalled) + * @number: number of pages requested + * @retry: whether to retry, if not enough pages are available right now + * + * Tries to allocate number pages, first from our own page pool, then from + * the kernel, unless this allocation would exceed the max_buffers setting. + * Possibly retry until DRBD frees sufficient pages somewhere else. * - * Tries to allocate a page, first from our own page pool, then from the - * kernel, unless this allocation would exceed the max_buffers setting. - * If @retry is non-zero, retry until DRBD frees a page somewhere else. + * Returns a page chain linked via page->private. */ -static struct page *drbd_pp_alloc(struct drbd_conf *mdev, int retry) +static struct page *drbd_pp_alloc(struct drbd_conf *mdev, unsigned number, bool retry) { struct page *page = NULL; DEFINE_WAIT(wait); - if (atomic_read(&mdev->pp_in_use) < mdev->net_conf->max_buffers) { - page = drbd_pp_first_page_or_try_alloc(mdev); - if (page) - return page; - } + /* Yes, we may run up to @number over max_buffers. If we + * follow it strictly, the admin will get it wrong anyways. */ + if (atomic_read(&mdev->pp_in_use) < mdev->net_conf->max_buffers) + page = drbd_pp_first_pages_or_try_alloc(mdev, number); - for (;;) { + while (page == NULL) { prepare_to_wait(&drbd_pp_wait, &wait, TASK_INTERRUPTIBLE); drbd_kick_lo_and_reclaim_net(mdev); if (atomic_read(&mdev->pp_in_use) < mdev->net_conf->max_buffers) { - page = drbd_pp_first_page_or_try_alloc(mdev); + page = drbd_pp_first_pages_or_try_alloc(mdev, number); if (page) break; } @@ -190,62 +286,32 @@ static struct page *drbd_pp_alloc(struct drbd_conf *mdev, int retry) } finish_wait(&drbd_pp_wait, &wait); + if (page) + atomic_add(number, &mdev->pp_in_use); return page; } /* Must not be used from irq, as that may deadlock: see drbd_pp_alloc. - * Is also used from inside an other spin_lock_irq(&mdev->req_lock) */ + * Is also used from inside an other spin_lock_irq(&mdev->req_lock); + * Either links the page chain back to the global pool, + * or returns all pages to the system. */ static void drbd_pp_free(struct drbd_conf *mdev, struct page *page) { - int free_it; - - spin_lock(&drbd_pp_lock); - if (drbd_pp_vacant > (DRBD_MAX_SEGMENT_SIZE/PAGE_SIZE)*minor_count) { - free_it = 1; - } else { - set_page_private(page, (unsigned long)drbd_pp_pool); - drbd_pp_pool = page; - drbd_pp_vacant++; - free_it = 0; - } - spin_unlock(&drbd_pp_lock); - - atomic_dec(&mdev->pp_in_use); - - if (free_it) - __free_page(page); - - wake_up(&drbd_pp_wait); -} - -static void drbd_pp_free_bio_pages(struct drbd_conf *mdev, struct bio *bio) -{ - struct page *p_to_be_freed = NULL; - struct page *page; - struct bio_vec *bvec; int i; - - spin_lock(&drbd_pp_lock); - __bio_for_each_segment(bvec, bio, i, 0) { - if (drbd_pp_vacant > (DRBD_MAX_SEGMENT_SIZE/PAGE_SIZE)*minor_count) { - set_page_private(bvec->bv_page, (unsigned long)p_to_be_freed); - p_to_be_freed = bvec->bv_page; - } else { - set_page_private(bvec->bv_page, (unsigned long)drbd_pp_pool); - drbd_pp_pool = bvec->bv_page; - drbd_pp_vacant++; - } - } - spin_unlock(&drbd_pp_lock); - atomic_sub(bio->bi_vcnt, &mdev->pp_in_use); - - while (p_to_be_freed) { - page = p_to_be_freed; - p_to_be_freed = (struct page *)page_private(page); - set_page_private(page, 0); /* just to be polite */ - put_page(page); + if (drbd_pp_vacant > (DRBD_MAX_SEGMENT_SIZE/PAGE_SIZE)*minor_count) + i = page_chain_free(page); + else { + struct page *tmp; + tmp = page_chain_tail(page, &i); + spin_lock(&drbd_pp_lock); + page_chain_add(&drbd_pp_pool, page, tmp); + drbd_pp_vacant += i; + spin_unlock(&drbd_pp_lock); } - + atomic_sub(i, &mdev->pp_in_use); + i = atomic_read(&mdev->pp_in_use); + if (i < 0) + dev_warn(DEV, "ASSERTION FAILED: pp_in_use: %d < 0\n", i); wake_up(&drbd_pp_wait); } @@ -270,11 +336,9 @@ struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev, unsigned int data_size, gfp_t gfp_mask) __must_hold(local) { - struct request_queue *q; struct drbd_epoch_entry *e; struct page *page; - struct bio *bio; - unsigned int ds; + unsigned nr_pages = (data_size + PAGE_SIZE -1) >> PAGE_SHIFT; if (FAULT_ACTIVE(mdev, DRBD_FAULT_AL_EE)) return NULL; @@ -286,84 +350,32 @@ struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev, return NULL; } - bio = bio_alloc(gfp_mask & ~__GFP_HIGHMEM, div_ceil(data_size, PAGE_SIZE)); - if (!bio) { - if (!(gfp_mask & __GFP_NOWARN)) - dev_err(DEV, "alloc_ee: Allocation of a bio failed\n"); - goto fail1; - } - - bio->bi_bdev = mdev->ldev->backing_bdev; - bio->bi_sector = sector; - - ds = data_size; - while (ds) { - page = drbd_pp_alloc(mdev, (gfp_mask & __GFP_WAIT)); - if (!page) { - if (!(gfp_mask & __GFP_NOWARN)) - dev_err(DEV, "alloc_ee: Allocation of a page failed\n"); - goto fail2; - } - if (!bio_add_page(bio, page, min_t(int, ds, PAGE_SIZE), 0)) { - drbd_pp_free(mdev, page); - dev_err(DEV, "alloc_ee: bio_add_page(s=%llu," - "data_size=%u,ds=%u) failed\n", - (unsigned long long)sector, data_size, ds); - - q = bdev_get_queue(bio->bi_bdev); - if (q->merge_bvec_fn) { - struct bvec_merge_data bvm = { - .bi_bdev = bio->bi_bdev, - .bi_sector = bio->bi_sector, - .bi_size = bio->bi_size, - .bi_rw = bio->bi_rw, - }; - int l = q->merge_bvec_fn(q, &bvm, - &bio->bi_io_vec[bio->bi_vcnt]); - dev_err(DEV, "merge_bvec_fn() = %d\n", l); - } - - /* dump more of the bio. */ - dev_err(DEV, "bio->bi_max_vecs = %d\n", bio->bi_max_vecs); - dev_err(DEV, "bio->bi_vcnt = %d\n", bio->bi_vcnt); - dev_err(DEV, "bio->bi_size = %d\n", bio->bi_size); - dev_err(DEV, "bio->bi_phys_segments = %d\n", bio->bi_phys_segments); - - goto fail2; - break; - } - ds -= min_t(int, ds, PAGE_SIZE); - } - - D_ASSERT(data_size == bio->bi_size); - - bio->bi_private = e; - e->mdev = mdev; - e->sector = sector; - e->size = bio->bi_size; + page = drbd_pp_alloc(mdev, nr_pages, (gfp_mask & __GFP_WAIT)); + if (!page) + goto fail; - e->private_bio = bio; - e->block_id = id; INIT_HLIST_NODE(&e->colision); e->epoch = NULL; + e->mdev = mdev; + e->pages = page; + atomic_set(&e->pending_bios, 0); + e->size = data_size; e->flags = 0; + e->sector = sector; + e->sector = sector; + e->block_id = id; return e; - fail2: - drbd_pp_free_bio_pages(mdev, bio); - bio_put(bio); - fail1: + fail: mempool_free(e, drbd_ee_mempool); - return NULL; } void drbd_free_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e) { - struct bio *bio = e->private_bio; - drbd_pp_free_bio_pages(mdev, bio); - bio_put(bio); + drbd_pp_free(mdev, e->pages); + D_ASSERT(atomic_read(&e->pending_bios) == 0); D_ASSERT(hlist_unhashed(&e->colision)); mempool_free(e, drbd_ee_mempool); } @@ -1120,6 +1132,90 @@ void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo) dev_info(DEV, "Method to ensure write ordering: %s\n", write_ordering_str[mdev->write_ordering]); } +/** + * drbd_submit_ee() + * @mdev: DRBD device. + * @e: epoch entry + * @rw: flag field, see bio->bi_rw + */ +/* TODO allocate from our own bio_set. */ +int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, + const unsigned rw, const int fault_type) +{ + struct bio *bios = NULL; + struct bio *bio; + struct page *page = e->pages; + sector_t sector = e->sector; + unsigned ds = e->size; + unsigned n_bios = 0; + unsigned nr_pages = (ds + PAGE_SIZE -1) >> PAGE_SHIFT; + + /* In most cases, we will only need one bio. But in case the lower + * level restrictions happen to be different at this offset on this + * side than those of the sending peer, we may need to submit the + * request in more than one bio. */ +next_bio: + bio = bio_alloc(GFP_NOIO, nr_pages); + if (!bio) { + dev_err(DEV, "submit_ee: Allocation of a bio failed\n"); + goto fail; + } + /* > e->sector, unless this is the first bio */ + bio->bi_sector = sector; + bio->bi_bdev = mdev->ldev->backing_bdev; + /* we special case some flags in the multi-bio case, see below + * (BIO_RW_UNPLUG, BIO_RW_BARRIER) */ + bio->bi_rw = rw; + bio->bi_private = e; + bio->bi_end_io = drbd_endio_sec; + + bio->bi_next = bios; + bios = bio; + ++n_bios; + + page_chain_for_each(page) { + unsigned len = min_t(unsigned, ds, PAGE_SIZE); + if (!bio_add_page(bio, page, len, 0)) { + /* a single page must always be possible! */ + BUG_ON(bio->bi_vcnt == 0); + goto next_bio; + } + ds -= len; + sector += len >> 9; + --nr_pages; + } + D_ASSERT(page == NULL); + D_ASSERT(ds == 0); + + atomic_set(&e->pending_bios, n_bios); + do { + bio = bios; + bios = bios->bi_next; + bio->bi_next = NULL; + + /* strip off BIO_RW_UNPLUG unless it is the last bio */ + if (bios) + bio->bi_rw &= ~(1<bi_next) + bios->bi_rw &= ~(1<bi_next; + bio_put(bio); + } + return -ENOMEM; +} + /** * w_e_reissue() - Worker callback; Resubmit a bio, without BIO_RW_BARRIER set * @mdev: DRBD device. @@ -1129,8 +1225,6 @@ void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo) int w_e_reissue(struct drbd_conf *mdev, struct drbd_work *w, int cancel) __releases(local) { struct drbd_epoch_entry *e = (struct drbd_epoch_entry *)w; - struct bio *bio = e->private_bio; - /* We leave DE_CONTAINS_A_BARRIER and EE_IS_BARRIER in place, (and DE_BARRIER_IN_NEXT_EPOCH_ISSUED in the previous Epoch) so that we can finish that epoch in drbd_may_finish_epoch(). @@ -1144,33 +1238,17 @@ int w_e_reissue(struct drbd_conf *mdev, struct drbd_work *w, int cancel) __relea if (previous_epoch(mdev, e->epoch)) dev_warn(DEV, "Write ordering was not enforced (one time event)\n"); - /* prepare bio for re-submit, - * re-init volatile members */ /* we still have a local reference, * get_ldev was done in receive_Data. */ - bio->bi_bdev = mdev->ldev->backing_bdev; - bio->bi_sector = e->sector; - bio->bi_size = e->size; - bio->bi_idx = 0; - - bio->bi_flags &= ~(BIO_POOL_MASK - 1); - bio->bi_flags |= 1 << BIO_UPTODATE; - - /* don't know whether this is necessary: */ - bio->bi_phys_segments = 0; - bio->bi_next = NULL; - - /* these should be unchanged: */ - /* bio->bi_end_io = drbd_endio_write_sec; */ - /* bio->bi_vcnt = whatever; */ e->w.cb = e_end_block; - - /* This is no longer a barrier request. */ - bio->bi_rw &= ~(1UL << BIO_RW_BARRIER); - - drbd_generic_make_request(mdev, DRBD_FAULT_DT_WR, bio); - + if (drbd_submit_ee(mdev, e, WRITE, DRBD_FAULT_DT_WR) != 0) { + /* drbd_submit_ee fails for one reason only: + * if was not able to allocate sufficient bios. + * requeue, try again later. */ + e->w.cb = w_e_reissue; + drbd_queue_work(&mdev->data.work, &e->w); + } return 1; } @@ -1264,10 +1342,8 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector, int data_size) __ { const sector_t capacity = drbd_get_capacity(mdev->this_bdev); struct drbd_epoch_entry *e; - struct bio_vec *bvec; struct page *page; - struct bio *bio; - int dgs, ds, i, rr; + int dgs, ds, rr; void *dig_in = mdev->int_dig_in; void *dig_vv = mdev->int_dig_vv; unsigned long *data; @@ -1304,28 +1380,29 @@ read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector, int data_size) __ e = drbd_alloc_ee(mdev, id, sector, data_size, GFP_NOIO); if (!e) return NULL; - bio = e->private_bio; + ds = data_size; - bio_for_each_segment(bvec, bio, i) { - page = bvec->bv_page; + page = e->pages; + page_chain_for_each(page) { + unsigned len = min_t(int, ds, PAGE_SIZE); data = kmap(page); - rr = drbd_recv(mdev, data, min_t(int, ds, PAGE_SIZE)); + rr = drbd_recv(mdev, data, len); if (FAULT_ACTIVE(mdev, DRBD_FAULT_RECEIVE)) { dev_err(DEV, "Fault injection: Corrupting data on receive\n"); data[0] = data[0] ^ (unsigned long)-1; } kunmap(page); - if (rr != min_t(int, ds, PAGE_SIZE)) { + if (rr != len) { drbd_free_ee(mdev, e); dev_warn(DEV, "short read receiving data: read %d expected %d\n", - rr, min_t(int, ds, PAGE_SIZE)); + rr, len); return NULL; } ds -= rr; } if (dgs) { - drbd_csum(mdev, mdev->integrity_r_tfm, bio, dig_vv); + drbd_csum_ee(mdev, mdev->integrity_r_tfm, e, dig_vv); if (memcmp(dig_in, dig_vv, dgs)) { dev_err(DEV, "Digest integrity check FAILED.\n"); drbd_bcast_ee(mdev, "digest failed", @@ -1350,7 +1427,7 @@ static int drbd_drain_block(struct drbd_conf *mdev, int data_size) if (!data_size) return TRUE; - page = drbd_pp_alloc(mdev, 1); + page = drbd_pp_alloc(mdev, 1, 1); data = kmap(page); while (data_size) { @@ -1414,7 +1491,7 @@ static int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req, } if (dgs) { - drbd_csum(mdev, mdev->integrity_r_tfm, bio, dig_vv); + drbd_csum_bio(mdev, mdev->integrity_r_tfm, bio, dig_vv); if (memcmp(dig_in, dig_vv, dgs)) { dev_err(DEV, "Digest integrity check FAILED. Broken NICs?\n"); return 0; @@ -1435,7 +1512,7 @@ static int e_end_resync_block(struct drbd_conf *mdev, struct drbd_work *w, int u D_ASSERT(hlist_unhashed(&e->colision)); - if (likely(drbd_bio_uptodate(e->private_bio))) { + if (likely((e->flags & EE_WAS_ERROR) == 0)) { drbd_set_in_sync(mdev, sector, e->size); ok = drbd_send_ack(mdev, P_RS_WRITE_ACK, e); } else { @@ -1454,30 +1531,28 @@ static int recv_resync_read(struct drbd_conf *mdev, sector_t sector, int data_si struct drbd_epoch_entry *e; e = read_in_block(mdev, ID_SYNCER, sector, data_size); - if (!e) { - put_ldev(mdev); - return FALSE; - } + if (!e) + goto fail; dec_rs_pending(mdev); - e->private_bio->bi_end_io = drbd_endio_write_sec; - e->private_bio->bi_rw = WRITE; - e->w.cb = e_end_resync_block; - inc_unacked(mdev); /* corresponding dec_unacked() in e_end_resync_block() * respective _drbd_clear_done_ee */ + e->w.cb = e_end_resync_block; + spin_lock_irq(&mdev->req_lock); list_add(&e->w.list, &mdev->sync_ee); spin_unlock_irq(&mdev->req_lock); - drbd_generic_make_request(mdev, DRBD_FAULT_RS_WR, e->private_bio); - /* accounting done in endio */ + if (drbd_submit_ee(mdev, e, WRITE, DRBD_FAULT_RS_WR) == 0) + return TRUE; - maybe_kick_lo(mdev); - return TRUE; + drbd_free_ee(mdev, e); +fail: + put_ldev(mdev); + return FALSE; } static int receive_DataReply(struct drbd_conf *mdev, struct p_header *h) @@ -1572,7 +1647,7 @@ static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel) } if (mdev->net_conf->wire_protocol == DRBD_PROT_C) { - if (likely(drbd_bio_uptodate(e->private_bio))) { + if (likely((e->flags & EE_WAS_ERROR) == 0)) { pcmd = (mdev->state.conn >= C_SYNC_SOURCE && mdev->state.conn <= C_PAUSED_SYNC_T && e->flags & EE_MAY_SET_IN_SYNC) ? @@ -1718,7 +1793,6 @@ static int receive_Data(struct drbd_conf *mdev, struct p_header *h) return FALSE; } - e->private_bio->bi_end_io = drbd_endio_write_sec; e->w.cb = e_end_block; spin_lock(&mdev->epoch_lock); @@ -1914,12 +1988,8 @@ static int receive_Data(struct drbd_conf *mdev, struct p_header *h) drbd_al_begin_io(mdev, e->sector); } - e->private_bio->bi_rw = rw; - drbd_generic_make_request(mdev, DRBD_FAULT_DT_WR, e->private_bio); - /* accounting done in endio */ - - maybe_kick_lo(mdev); - return TRUE; + if (drbd_submit_ee(mdev, e, rw, DRBD_FAULT_DT_WR) == 0) + return TRUE; out_interrupted: /* yes, the epoch_size now is imbalanced. @@ -1977,9 +2047,6 @@ static int receive_DataRequest(struct drbd_conf *mdev, struct p_header *h) return FALSE; } - e->private_bio->bi_rw = READ; - e->private_bio->bi_end_io = drbd_endio_read_sec; - switch (h->command) { case P_DATA_REQUEST: e->w.cb = w_e_end_data_req; @@ -2073,10 +2140,8 @@ static int receive_DataRequest(struct drbd_conf *mdev, struct p_header *h) inc_unacked(mdev); - drbd_generic_make_request(mdev, fault_type, e->private_bio); - maybe_kick_lo(mdev); - - return TRUE; + if (drbd_submit_ee(mdev, e, READ, fault_type) == 0) + return TRUE; out_free_e: kfree(di); @@ -3837,7 +3902,7 @@ static void drbd_disconnect(struct drbd_conf *mdev) dev_info(DEV, "net_ee not empty, killed %u entries\n", i); i = atomic_read(&mdev->pp_in_use); if (i) - dev_info(DEV, "pp_in_use = %u, expected 0\n", i); + dev_info(DEV, "pp_in_use = %d, expected 0\n", i); D_ASSERT(list_empty(&mdev->read_ee)); D_ASSERT(list_empty(&mdev->active_ee)); diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 0bbecf45b485..d771b1e0424b 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -47,8 +47,7 @@ static int w_make_ov_request(struct drbd_conf *mdev, struct drbd_work *w, int ca /* defined here: drbd_md_io_complete - drbd_endio_write_sec - drbd_endio_read_sec + drbd_endio_sec drbd_endio_pri * more endio handlers: @@ -85,27 +84,10 @@ void drbd_md_io_complete(struct bio *bio, int error) /* reads on behalf of the partner, * "submitted" by the receiver */ -void drbd_endio_read_sec(struct bio *bio, int error) __releases(local) +void drbd_endio_read_sec_final(struct drbd_epoch_entry *e) __releases(local) { unsigned long flags = 0; - struct drbd_epoch_entry *e = NULL; - struct drbd_conf *mdev; - int uptodate = bio_flagged(bio, BIO_UPTODATE); - - e = bio->bi_private; - mdev = e->mdev; - - if (error) - dev_warn(DEV, "read: error=%d s=%llus\n", error, - (unsigned long long)e->sector); - if (!error && !uptodate) { - dev_warn(DEV, "read: setting error to -EIO s=%llus\n", - (unsigned long long)e->sector); - /* strange behavior of some lower level drivers... - * fail the request by clearing the uptodate flag, - * but do not return any error?! */ - error = -EIO; - } + struct drbd_conf *mdev = e->mdev; D_ASSERT(e->block_id != ID_VACANT); @@ -114,49 +96,38 @@ void drbd_endio_read_sec(struct bio *bio, int error) __releases(local) list_del(&e->w.list); if (list_empty(&mdev->read_ee)) wake_up(&mdev->ee_wait); + if (test_bit(__EE_WAS_ERROR, &e->flags)) + __drbd_chk_io_error(mdev, FALSE); spin_unlock_irqrestore(&mdev->req_lock, flags); - drbd_chk_io_error(mdev, error, FALSE); drbd_queue_work(&mdev->data.work, &e->w); put_ldev(mdev); } +static int is_failed_barrier(int ee_flags) +{ + return (ee_flags & (EE_IS_BARRIER|EE_WAS_ERROR|EE_RESUBMITTED)) + == (EE_IS_BARRIER|EE_WAS_ERROR); +} + /* writes on behalf of the partner, or resync writes, - * "submitted" by the receiver. - */ -void drbd_endio_write_sec(struct bio *bio, int error) __releases(local) + * "submitted" by the receiver, final stage. */ +static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(local) { unsigned long flags = 0; - struct drbd_epoch_entry *e = NULL; - struct drbd_conf *mdev; + struct drbd_conf *mdev = e->mdev; sector_t e_sector; int do_wake; int is_syncer_req; int do_al_complete_io; - int uptodate = bio_flagged(bio, BIO_UPTODATE); - int is_barrier = bio_rw_flagged(bio, BIO_RW_BARRIER); - e = bio->bi_private; - mdev = e->mdev; - - if (error) - dev_warn(DEV, "write: error=%d s=%llus\n", error, - (unsigned long long)e->sector); - if (!error && !uptodate) { - dev_warn(DEV, "write: setting error to -EIO s=%llus\n", - (unsigned long long)e->sector); - /* strange behavior of some lower level drivers... - * fail the request by clearing the uptodate flag, - * but do not return any error?! */ - error = -EIO; - } - - /* error == -ENOTSUPP would be a better test, - * alas it is not reliable */ - if (error && is_barrier && e->flags & EE_IS_BARRIER) { + /* if this is a failed barrier request, disable use of barriers, + * and schedule for resubmission */ + if (is_failed_barrier(e->flags)) { drbd_bump_write_ordering(mdev, WO_bdev_flush); spin_lock_irqsave(&mdev->req_lock, flags); list_del(&e->w.list); + e->flags |= EE_RESUBMITTED; e->w.cb = w_e_reissue; /* put_ldev actually happens below, once we come here again. */ __release(local); @@ -167,17 +138,16 @@ void drbd_endio_write_sec(struct bio *bio, int error) __releases(local) D_ASSERT(e->block_id != ID_VACANT); - spin_lock_irqsave(&mdev->req_lock, flags); - mdev->writ_cnt += e->size >> 9; - is_syncer_req = is_syncer_block_id(e->block_id); - /* after we moved e to done_ee, * we may no longer access it, * it may be freed/reused already! * (as soon as we release the req_lock) */ e_sector = e->sector; do_al_complete_io = e->flags & EE_CALL_AL_COMPLETE_IO; + is_syncer_req = is_syncer_block_id(e->block_id); + spin_lock_irqsave(&mdev->req_lock, flags); + mdev->writ_cnt += e->size >> 9; list_del(&e->w.list); /* has been on active_ee or sync_ee */ list_add_tail(&e->w.list, &mdev->done_ee); @@ -190,7 +160,7 @@ void drbd_endio_write_sec(struct bio *bio, int error) __releases(local) ? list_empty(&mdev->sync_ee) : list_empty(&mdev->active_ee); - if (error) + if (test_bit(__EE_WAS_ERROR, &e->flags)) __drbd_chk_io_error(mdev, FALSE); spin_unlock_irqrestore(&mdev->req_lock, flags); @@ -205,7 +175,42 @@ void drbd_endio_write_sec(struct bio *bio, int error) __releases(local) wake_asender(mdev); put_ldev(mdev); +} +/* writes on behalf of the partner, or resync writes, + * "submitted" by the receiver. + */ +void drbd_endio_sec(struct bio *bio, int error) +{ + struct drbd_epoch_entry *e = bio->bi_private; + struct drbd_conf *mdev = e->mdev; + int uptodate = bio_flagged(bio, BIO_UPTODATE); + int is_write = bio_data_dir(bio) == WRITE; + + if (error) + dev_warn(DEV, "%s: error=%d s=%llus\n", + is_write ? "write" : "read", error, + (unsigned long long)e->sector); + if (!error && !uptodate) { + dev_warn(DEV, "%s: setting error to -EIO s=%llus\n", + is_write ? "write" : "read", + (unsigned long long)e->sector); + /* strange behavior of some lower level drivers... + * fail the request by clearing the uptodate flag, + * but do not return any error?! */ + error = -EIO; + } + + if (error) + set_bit(__EE_WAS_ERROR, &e->flags); + + bio_put(bio); /* no need for the bio anymore */ + if (atomic_dec_and_test(&e->pending_bios)) { + if (is_write) + drbd_endio_write_sec_final(e); + else + drbd_endio_read_sec_final(e); + } } /* read, readA or write requests on R_PRIMARY coming from drbd_make_request @@ -295,7 +300,34 @@ int w_resync_inactive(struct drbd_conf *mdev, struct drbd_work *w, int cancel) return 1; /* Simply ignore this! */ } -void drbd_csum(struct drbd_conf *mdev, struct crypto_hash *tfm, struct bio *bio, void *digest) +void drbd_csum_ee(struct drbd_conf *mdev, struct crypto_hash *tfm, struct drbd_epoch_entry *e, void *digest) +{ + struct hash_desc desc; + struct scatterlist sg; + struct page *page = e->pages; + struct page *tmp; + unsigned len; + + desc.tfm = tfm; + desc.flags = 0; + + sg_init_table(&sg, 1); + crypto_hash_init(&desc); + + while ((tmp = page_chain_next(page))) { + /* all but the last page will be fully used */ + sg_set_page(&sg, page, PAGE_SIZE, 0); + crypto_hash_update(&desc, &sg, sg.length); + page = tmp; + } + /* and now the last, possibly only partially used page */ + len = e->size & (PAGE_SIZE - 1); + sg_set_page(&sg, page, len ?: PAGE_SIZE, 0); + crypto_hash_update(&desc, &sg, sg.length); + crypto_hash_final(&desc, digest); +} + +void drbd_csum_bio(struct drbd_conf *mdev, struct crypto_hash *tfm, struct bio *bio, void *digest) { struct hash_desc desc; struct scatterlist sg; @@ -329,11 +361,11 @@ static int w_e_send_csum(struct drbd_conf *mdev, struct drbd_work *w, int cancel return 1; } - if (likely(drbd_bio_uptodate(e->private_bio))) { + if (likely((e->flags & EE_WAS_ERROR) == 0)) { digest_size = crypto_hash_digestsize(mdev->csums_tfm); digest = kmalloc(digest_size, GFP_NOIO); if (digest) { - drbd_csum(mdev, mdev->csums_tfm, e->private_bio, digest); + drbd_csum_ee(mdev, mdev->csums_tfm, e, digest); inc_rs_pending(mdev); ok = drbd_send_drequest_csum(mdev, @@ -369,23 +401,21 @@ static int read_for_csum(struct drbd_conf *mdev, sector_t sector, int size) /* GFP_TRY, because if there is no memory available right now, this may * be rescheduled for later. It is "only" background resync, after all. */ e = drbd_alloc_ee(mdev, DRBD_MAGIC+0xbeef, sector, size, GFP_TRY); - if (!e) { - put_ldev(mdev); - return 2; - } + if (!e) + goto fail; spin_lock_irq(&mdev->req_lock); list_add(&e->w.list, &mdev->read_ee); spin_unlock_irq(&mdev->req_lock); - e->private_bio->bi_end_io = drbd_endio_read_sec; - e->private_bio->bi_rw = READ; e->w.cb = w_e_send_csum; + if (drbd_submit_ee(mdev, e, READ, DRBD_FAULT_RS_RD) == 0) + return 1; - mdev->read_cnt += size >> 9; - drbd_generic_make_request(mdev, DRBD_FAULT_RS_RD, e->private_bio); - - return 1; + drbd_free_ee(mdev, e); +fail: + put_ldev(mdev); + return 2; } void resync_timer_fn(unsigned long data) @@ -819,7 +849,7 @@ out: /* helper */ static void move_to_net_ee_or_free(struct drbd_conf *mdev, struct drbd_epoch_entry *e) { - if (drbd_bio_has_active_page(e->private_bio)) { + if (drbd_ee_has_active_page(e)) { /* This might happen if sendpage() has not finished */ spin_lock_irq(&mdev->req_lock); list_add_tail(&e->w.list, &mdev->net_ee); @@ -845,7 +875,7 @@ int w_e_end_data_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel) return 1; } - if (likely(drbd_bio_uptodate(e->private_bio))) { + if (likely((e->flags & EE_WAS_ERROR) == 0)) { ok = drbd_send_block(mdev, P_DATA_REPLY, e); } else { if (__ratelimit(&drbd_ratelimit_state)) @@ -886,7 +916,7 @@ int w_e_end_rsdata_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel) put_ldev(mdev); } - if (likely(drbd_bio_uptodate(e->private_bio))) { + if (likely((e->flags & EE_WAS_ERROR) == 0)) { if (likely(mdev->state.pdsk >= D_INCONSISTENT)) { inc_rs_pending(mdev); ok = drbd_send_block(mdev, P_RS_DATA_REPLY, e); @@ -934,7 +964,7 @@ int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel) di = (struct digest_info *)(unsigned long)e->block_id; - if (likely(drbd_bio_uptodate(e->private_bio))) { + if (likely((e->flags & EE_WAS_ERROR) == 0)) { /* quick hack to try to avoid a race against reconfiguration. * a real fix would be much more involved, * introducing more locking mechanisms */ @@ -944,7 +974,7 @@ int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel) digest = kmalloc(digest_size, GFP_NOIO); } if (digest) { - drbd_csum(mdev, mdev->csums_tfm, e->private_bio, digest); + drbd_csum_ee(mdev, mdev->csums_tfm, e, digest); eq = !memcmp(digest, di->digest, digest_size); kfree(digest); } @@ -986,14 +1016,14 @@ int w_e_end_ov_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel) if (unlikely(cancel)) goto out; - if (unlikely(!drbd_bio_uptodate(e->private_bio))) + if (unlikely((e->flags & EE_WAS_ERROR) != 0)) goto out; digest_size = crypto_hash_digestsize(mdev->verify_tfm); /* FIXME if this allocation fails, online verify will not terminate! */ digest = kmalloc(digest_size, GFP_NOIO); if (digest) { - drbd_csum(mdev, mdev->verify_tfm, e->private_bio, digest); + drbd_csum_ee(mdev, mdev->verify_tfm, e, digest); inc_rs_pending(mdev); ok = drbd_send_drequest_csum(mdev, e->sector, e->size, digest, digest_size, P_OV_REPLY); @@ -1042,11 +1072,11 @@ int w_e_end_ov_reply(struct drbd_conf *mdev, struct drbd_work *w, int cancel) di = (struct digest_info *)(unsigned long)e->block_id; - if (likely(drbd_bio_uptodate(e->private_bio))) { + if (likely((e->flags & EE_WAS_ERROR) == 0)) { digest_size = crypto_hash_digestsize(mdev->verify_tfm); digest = kmalloc(digest_size, GFP_NOIO); if (digest) { - drbd_csum(mdev, mdev->verify_tfm, e->private_bio, digest); + drbd_csum_ee(mdev, mdev->verify_tfm, e, digest); D_ASSERT(digest_size == di->digest_size); eq = !memcmp(digest, di->digest, digest_size); diff --git a/drivers/block/drbd/drbd_wrappers.h b/drivers/block/drbd/drbd_wrappers.h index f93fa111ce50..defdb5013ea3 100644 --- a/drivers/block/drbd/drbd_wrappers.h +++ b/drivers/block/drbd/drbd_wrappers.h @@ -18,23 +18,9 @@ static inline void drbd_set_my_capacity(struct drbd_conf *mdev, #define drbd_bio_uptodate(bio) bio_flagged(bio, BIO_UPTODATE) -static inline int drbd_bio_has_active_page(struct bio *bio) -{ - struct bio_vec *bvec; - int i; - - __bio_for_each_segment(bvec, bio, i, 0) { - if (page_count(bvec->bv_page) > 1) - return 1; - } - - return 0; -} - /* bi_end_io handlers */ extern void drbd_md_io_complete(struct bio *bio, int error); -extern void drbd_endio_read_sec(struct bio *bio, int error); -extern void drbd_endio_write_sec(struct bio *bio, int error); +extern void drbd_endio_sec(struct bio *bio, int error); extern void drbd_endio_pri(struct bio *bio, int error); /* -- cgit v1.2.3 From bb3d000cb99aa0924b78c1ae5f5943484527868a Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Fri, 14 May 2010 19:08:55 +0200 Subject: drbd: allow resync requests to be larger than max_segment_size this should allow for better background resync performance. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_worker.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index d771b1e0424b..91085c1ab52f 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -462,7 +462,7 @@ int w_make_resync_request(struct drbd_conf *mdev, unsigned long bit; sector_t sector; const sector_t capacity = drbd_get_capacity(mdev->this_bdev); - int max_segment_size = queue_max_segment_size(mdev->rq_queue); + int max_segment_size; int number, i, size, pe, mx; int align, queued, sndbuf; @@ -488,6 +488,11 @@ int w_make_resync_request(struct drbd_conf *mdev, return 1; } + /* starting with drbd 8.3.8, we can handle multi-bio EEs, + * if it should be necessary */ + max_segment_size = mdev->agreed_pro_version < 94 ? + queue_max_segment_size(mdev->rq_queue) : DRBD_MAX_SEGMENT_SIZE; + mdev->c_sync_rate = calc_resync_rate(mdev); number = SLEEP_TIME * mdev->c_sync_rate / ((BM_BLOCK_SIZE / 1024) * HZ); pe = atomic_read(&mdev->rs_pending_cnt); @@ -552,12 +557,6 @@ next_sector: * * Additionally always align bigger requests, in order to * be prepared for all stripe sizes of software RAIDs. - * - * we _do_ care about the agreed-upon q->max_segment_size - * here, as splitting up the requests on the other side is more - * difficult. the consequence is, that on lvm and md and other - * "indirect" devices, this is dead code, since - * q->max_segment_size will be PAGE_SIZE. */ align = 1; for (;;) { -- cgit v1.2.3 From a1c88d0d7aa2ef427f78834c9a3b0a673a19dca6 Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Fri, 14 May 2010 19:16:41 +0200 Subject: drbd: always use_bmbv, ignore setting Now that the peer may handle multi-bio EEs, we can ignore the peer's limit, and concentrate on the limits of the local IO stack. This is safe accross drbd protocol versions, as our queue_max_sectors() will be adjusted accordingly. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_nl.c | 3 --- drivers/block/drbd/drbd_receiver.c | 6 +++++- drivers/block/drbd/drbd_req.c | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 28ef76bd5230..f20336bc59c8 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -704,9 +704,6 @@ void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int max_seg_s) __mu struct request_queue * const b = mdev->ldev->backing_bdev->bd_disk->queue; int max_segments = mdev->ldev->dc.max_bio_bvecs; - if (b->merge_bvec_fn && !mdev->ldev->dc.use_bmbv) - max_seg_s = PAGE_SIZE; - max_seg_s = min(queue_max_sectors(b) * queue_logical_block_size(b), max_seg_s); blk_queue_max_hw_sectors(q, max_seg_s >> 9); diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 388a3e8bb0d0..a04ec01ab3ce 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -3011,7 +3011,11 @@ static int receive_sizes(struct drbd_conf *mdev, struct p_header *h) ldsc = 1; } - max_seg_s = be32_to_cpu(p->max_segment_size); + if (mdev->agreed_pro_version < 94) + max_seg_s = be32_to_cpu(p->max_segment_size); + else /* drbd 8.3.8 onwards */ + max_seg_s = DRBD_MAX_SEGMENT_SIZE; + if (max_seg_s != queue_max_segment_size(mdev->rq_queue)) drbd_setup_queue_param(mdev, max_seg_s); diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index d8d9bbfca3b8..343e0e6dd532 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -1110,7 +1110,7 @@ int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct } else if (limit && get_ldev(mdev)) { struct request_queue * const b = mdev->ldev->backing_bdev->bd_disk->queue; - if (b->merge_bvec_fn && mdev->ldev->dc.use_bmbv) { + if (b->merge_bvec_fn) { backing_limit = b->merge_bvec_fn(b, bvm, bvec); limit = min(limit, backing_limit); } -- cgit v1.2.3 From 9a25a04c8079725c1b1ab756694a8e0757844b40 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Mon, 10 May 2010 16:42:23 +0200 Subject: drbd: If we detect late that IO got frozen, retry after we thawed. If we detect late (= after grabing mdev->req_lock) that IO got frozen, we return 1 to generic_make_request(), which simply will retry to make a request for that bio. In the subsequent call of generic_make_request() into drbd_make_request_26() we sleep in inc_ap_bio(). Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_int.h | 4 ++-- drivers/block/drbd/drbd_req.c | 33 ++++++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 4b97f30bb7c6..c194348a46ed 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -2223,7 +2223,7 @@ static inline int __inc_ap_bio_cond(struct drbd_conf *mdev) /* I'd like to use wait_event_lock_irq, * but I'm not sure when it got introduced, * and not sure when it has 3 or 4 arguments */ -static inline void inc_ap_bio(struct drbd_conf *mdev, int one_or_two) +static inline void inc_ap_bio(struct drbd_conf *mdev, int count) { /* compare with after_state_ch, * os.conn != C_WF_BITMAP_S && ns.conn == C_WF_BITMAP_S */ @@ -2245,7 +2245,7 @@ static inline void inc_ap_bio(struct drbd_conf *mdev, int one_or_two) finish_wait(&mdev->misc_wait, &wait); spin_lock_irq(&mdev->req_lock); } - atomic_add(one_or_two, &mdev->ap_bio_cnt); + atomic_add(count, &mdev->ap_bio_cnt); spin_unlock_irq(&mdev->req_lock); } diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 343e0e6dd532..3397f11d0ba9 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -722,6 +722,7 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio) struct drbd_request *req; int local, remote; int err = -EIO; + int ret = 0; /* allocate outside of all locks; */ req = drbd_req_new(mdev, bio); @@ -784,7 +785,7 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio) (mdev->state.pdsk == D_INCONSISTENT && mdev->state.conn >= C_CONNECTED)); - if (!(local || remote)) { + if (!(local || remote) && !mdev->state.susp) { dev_err(DEV, "IO ERROR: neither local nor remote disk\n"); goto fail_free_complete; } @@ -810,6 +811,16 @@ allocate_barrier: /* GOOD, everything prepared, grab the spin_lock */ spin_lock_irq(&mdev->req_lock); + if (mdev->state.susp) { + /* If we got suspended, use the retry mechanism of + generic_make_request() to restart processing of this + bio. In the next call to drbd_make_request_26 + we sleep in inc_ap_bio() */ + ret = 1; + spin_unlock_irq(&mdev->req_lock); + goto fail_free_complete; + } + if (remote) { remote = (mdev->state.pdsk == D_UP_TO_DATE || (mdev->state.pdsk == D_INCONSISTENT && @@ -947,12 +958,14 @@ fail_and_free_req: req->private_bio = NULL; put_ldev(mdev); } - bio_endio(bio, err); + if (!ret) + bio_endio(bio, err); + drbd_req_free(req); dec_ap_bio(mdev); kfree(b); - return 0; + return ret; } /* helper function for drbd_make_request @@ -1065,15 +1078,21 @@ int drbd_make_request_26(struct request_queue *q, struct bio *bio) /* we need to get a "reference count" (ap_bio_cnt) * to avoid races with the disconnect/reconnect/suspend code. - * In case we need to split the bio here, we need to get two references + * In case we need to split the bio here, we need to get three references * atomically, otherwise we might deadlock when trying to submit the * second one! */ - inc_ap_bio(mdev, 2); + inc_ap_bio(mdev, 3); D_ASSERT(e_enr == s_enr + 1); - drbd_make_request_common(mdev, &bp->bio1); - drbd_make_request_common(mdev, &bp->bio2); + while (drbd_make_request_common(mdev, &bp->bio1)) + inc_ap_bio(mdev, 1); + + while (drbd_make_request_common(mdev, &bp->bio2)) + inc_ap_bio(mdev, 1); + + dec_ap_bio(mdev); + bio_pair_release(bp); } return 0; -- cgit v1.2.3 From 0c3f34516e8c5a1a0ba3585a7777d32bbbdf4ecb Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Mon, 17 May 2010 16:10:43 +0200 Subject: drbd: Create new current UUID as late as possible The choice was to either delay creation of the new UUID until IO got thawed or to delay it until the first IO request. Both are correct, the later is more friendly to users of dual-primary setups, that actually only write on one side. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_int.h | 9 ++++++++- drivers/block/drbd/drbd_main.c | 25 ++++++++++++++++++++----- drivers/block/drbd/drbd_receiver.c | 11 +++++++++++ 3 files changed, 39 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index c194348a46ed..e9654c8d5b62 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -943,7 +943,8 @@ struct drbd_conf { struct drbd_work resync_work, unplug_work, md_sync_work, - delay_probe_work; + delay_probe_work, + uuid_work; struct timer_list resync_timer; struct timer_list md_sync_timer; struct timer_list delay_probe_timer; @@ -1068,6 +1069,7 @@ struct drbd_conf { struct timeval dps_time; /* delay-probes-start-time */ unsigned int dp_volume_last; /* send_cnt of last delay probe */ int c_sync_rate; /* current resync rate after delay_probe magic */ + atomic_t new_c_uuid; }; static inline struct drbd_conf *minor_to_mdev(unsigned int minor) @@ -2217,6 +2219,8 @@ static inline int __inc_ap_bio_cond(struct drbd_conf *mdev) return 0; if (test_bit(BITMAP_IO, &mdev->flags)) return 0; + if (atomic_read(&mdev->new_c_uuid)) + return 0; return 1; } @@ -2237,6 +2241,9 @@ static inline void inc_ap_bio(struct drbd_conf *mdev, int count) * to avoid races with the reconnect code, * we need to atomic_inc within the spinlock. */ + if (atomic_read(&mdev->new_c_uuid) && atomic_add_unless(&mdev->new_c_uuid, -1, 1)) + drbd_queue_work_front(&mdev->data.work, &mdev->uuid_work); + spin_lock_irq(&mdev->req_lock); while (!__inc_ap_bio_cond(mdev)) { prepare_to_wait(&mdev->misc_wait, &wait, TASK_UNINTERRUPTIBLE); diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index d0fabace1452..c144509011b8 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -1217,17 +1217,16 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, mdev->p_uuid = NULL; if (get_ldev(mdev)) { if ((ns.role == R_PRIMARY || ns.peer == R_PRIMARY) && - mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE) { - drbd_uuid_new_current(mdev); - drbd_send_uuids(mdev); - } + mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE) + atomic_set(&mdev->new_c_uuid, 2); put_ldev(mdev); } } if (ns.pdsk < D_INCONSISTENT && get_ldev(mdev)) { + /* Diskless peer becomes primary or got connected do diskless, primary peer. */ if (ns.peer == R_PRIMARY && mdev->ldev->md.uuid[UI_BITMAP] == 0) - drbd_uuid_new_current(mdev); + atomic_set(&mdev->new_c_uuid, 2); /* D_DISKLESS Peer becomes secondary */ if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY) @@ -1351,6 +1350,19 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, drbd_md_sync(mdev); } +static int w_new_current_uuid(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + if (get_ldev(mdev)) { + drbd_uuid_new_current(mdev); + drbd_send_uuids(mdev); + drbd_md_sync(mdev); + put_ldev(mdev); + } + atomic_dec(&mdev->new_c_uuid); + wake_up(&mdev->misc_wait); + + return 1; +} static int drbd_thread_setup(void *arg) { @@ -2691,6 +2703,7 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) atomic_set(&mdev->net_cnt, 0); atomic_set(&mdev->packet_seq, 0); atomic_set(&mdev->pp_in_use, 0); + atomic_set(&mdev->new_c_uuid, 0); mutex_init(&mdev->md_io_mutex); mutex_init(&mdev->data.mutex); @@ -2721,12 +2734,14 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) INIT_LIST_HEAD(&mdev->bm_io_work.w.list); INIT_LIST_HEAD(&mdev->delay_probes); INIT_LIST_HEAD(&mdev->delay_probe_work.list); + INIT_LIST_HEAD(&mdev->uuid_work.list); mdev->resync_work.cb = w_resync_inactive; mdev->unplug_work.cb = w_send_write_hint; mdev->md_sync_work.cb = w_md_sync; mdev->bm_io_work.w.cb = w_bitmap_io; mdev->delay_probe_work.cb = w_delay_probes; + mdev->uuid_work.cb = w_new_current_uuid; init_timer(&mdev->resync_timer); init_timer(&mdev->md_sync_timer); init_timer(&mdev->delay_probe_timer); diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index a04ec01ab3ce..461d9872d4d3 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -1150,6 +1150,17 @@ int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, unsigned n_bios = 0; unsigned nr_pages = (ds + PAGE_SIZE -1) >> PAGE_SHIFT; + if (atomic_read(&mdev->new_c_uuid)) { + if (atomic_add_unless(&mdev->new_c_uuid, -1, 1)) { + drbd_uuid_new_current(mdev); + drbd_md_sync(mdev); + + atomic_dec(&mdev->new_c_uuid); + wake_up(&mdev->misc_wait); + } + wait_event(mdev->misc_wait, !atomic_read(&mdev->new_c_uuid)); + } + /* In most cases, we will only need one bio. But in case the lower * level restrictions happen to be different at this offset on this * side than those of the sending peer, we may need to submit the -- cgit v1.2.3 From 2db4e42eaceabec42f738f3895300632cd375e67 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 13 May 2010 22:02:21 +0200 Subject: drivers/block/drbd: Use kzalloc Use kzalloc rather than the combination of kmalloc and memset. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression x,size,flags; statement S; @@ -x = kmalloc(size,flags); +x = kzalloc(size,flags); if (x == NULL) S -memset(x, 0, size); // Signed-off-by: Julia Lawall Signed-off-by: Philipp Reisner Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg --- drivers/block/drbd/drbd_nl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index f20336bc59c8..632e3245d1bb 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -1196,13 +1196,12 @@ static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, } /* allocation not in the IO path, cqueue thread context */ - new_conf = kmalloc(sizeof(struct net_conf), GFP_KERNEL); + new_conf = kzalloc(sizeof(struct net_conf), GFP_KERNEL); if (!new_conf) { retcode = ERR_NOMEM; goto fail; } - memset(new_conf, 0, sizeof(struct net_conf)); new_conf->timeout = DRBD_TIMEOUT_DEF; new_conf->try_connect_int = DRBD_CONNECT_INT_DEF; new_conf->ping_int = DRBD_PING_INT_DEF; -- cgit v1.2.3 From 964147d5c86d63be79b442c30f3783d49860c078 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 18 May 2010 15:27:13 +1000 Subject: md/raid1: fix counting of write targets. There is a very small race window when writing to a RAID1 such that if a device is marked faulty at exactly the wrong time, the write-in-progress will not be sent to the device, but the bitmap (if present) will be updated to say that the write was sent. Then if the device turned out to still be usable as was re-added to the array, the bitmap-based-resync would skip resyncing that block, possibly leading to corruption. This would only be a problem if no further writes were issued to that area of the device (i.e. that bitmap chunk). Suitable for any pending -stable kernel. Cc: stable@kernel.org Signed-off-by: NeilBrown --- drivers/md/raid1.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index f741f77eeb2b..1ab30f64848f 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -911,9 +911,10 @@ static int make_request(struct request_queue *q, struct bio * bio) if (test_bit(Faulty, &rdev->flags)) { rdev_dec_pending(rdev, mddev); r1_bio->bios[i] = NULL; - } else + } else { r1_bio->bios[i] = bio; - targets++; + targets++; + } } else r1_bio->bios[i] = NULL; } -- cgit v1.2.3 From ee8b81b03dffa1c0075553d01c557714aedb85a1 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 8 Mar 2010 16:02:36 +1100 Subject: md: remove some dead fields from mddev_s These fields have never been used. commit 4b6d287f627b5fb6a49f78f9e81649ff98c62bb7 added them, but also added identical files to bitmap_super_s, and only used the latter. So remove these unused fields. Signed-off-by: NeilBrown --- drivers/md/md.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.h b/drivers/md/md.h index 722f5dfe1953..05145786b50f 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -279,9 +279,6 @@ struct mddev_s atomic_t writes_pending; struct request_queue *queue; /* for plugging ... */ - atomic_t write_behind; /* outstanding async IO */ - unsigned int max_write_behind; /* 0 = sync */ - struct bitmap *bitmap; /* the bitmap for the device */ struct { struct file *file; /* the bitmap file */ -- cgit v1.2.3 From 696fcd535b5a8cfc0617e9cf1d9d69a13895cc1e Mon Sep 17 00:00:00 2001 From: Paul Clements Date: Mon, 8 Mar 2010 16:02:37 +1100 Subject: md: expose max value of behind writes counter Keep track of the maximum number of concurrent write-behind requests for an md array and exposed this number in sysfs at md/bitmap/max_backlog_used Writing any value to this file will clear it. This allows userspace to be involved in tuning bitmap/backlog. Signed-off-by: Paul Clements Signed-off-by: NeilBrown --- drivers/md/bitmap.c | 29 ++++++++++++++++++++++++++++- drivers/md/bitmap.h | 1 + 2 files changed, 29 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 26ac8aad0b19..6279393db64d 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -1292,9 +1292,14 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect if (!bitmap) return 0; if (behind) { + int bw; atomic_inc(&bitmap->behind_writes); + bw = atomic_read(&bitmap->behind_writes); + if (bw > bitmap->behind_writes_used) + bitmap->behind_writes_used = bw; + PRINTK(KERN_DEBUG "inc write-behind count %d/%d\n", - atomic_read(&bitmap->behind_writes), bitmap->max_write_behind); + bw, bitmap->max_write_behind); } while (sectors) { @@ -2006,6 +2011,27 @@ static ssize_t can_clear_store(mddev_t *mddev, const char *buf, size_t len) static struct md_sysfs_entry bitmap_can_clear = __ATTR(can_clear, S_IRUGO|S_IWUSR, can_clear_show, can_clear_store); +static ssize_t +behind_writes_used_show(mddev_t *mddev, char *page) +{ + if (mddev->bitmap == NULL) + return sprintf(page, "0\n"); + return sprintf(page, "%lu\n", + mddev->bitmap->behind_writes_used); +} + +static ssize_t +behind_writes_used_reset(mddev_t *mddev, const char *buf, size_t len) +{ + if (mddev->bitmap) + mddev->bitmap->behind_writes_used = 0; + return len; +} + +static struct md_sysfs_entry max_backlog_used = +__ATTR(max_backlog_used, S_IRUGO | S_IWUSR, + behind_writes_used_show, behind_writes_used_reset); + static struct attribute *md_bitmap_attrs[] = { &bitmap_location.attr, &bitmap_timeout.attr, @@ -2013,6 +2039,7 @@ static struct attribute *md_bitmap_attrs[] = { &bitmap_chunksize.attr, &bitmap_metadata.attr, &bitmap_can_clear.attr, + &max_backlog_used.attr, NULL }; struct attribute_group md_bitmap_group = { diff --git a/drivers/md/bitmap.h b/drivers/md/bitmap.h index cb821d76d1b4..aa82b7caa85f 100644 --- a/drivers/md/bitmap.h +++ b/drivers/md/bitmap.h @@ -227,6 +227,7 @@ struct bitmap { int allclean; atomic_t behind_writes; + unsigned long behind_writes_used; /* highest actual value at runtime */ /* * the bitmap daemon - periodically wakes up and sweeps the bitmap -- cgit v1.2.3 From 7b92813c3c0b6990f14838e3985fb385d2655d0c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 8 Mar 2010 16:02:40 +1100 Subject: drivers/md: Remove unnecessary casts of void * void pointers do not need to be cast to other pointer types. Signed-off-by: H Hartley Sweeten Signed-off-by: NeilBrown --- drivers/md/bitmap.c | 8 ++++---- drivers/md/faulty.c | 6 +++--- drivers/md/multipath.c | 2 +- drivers/md/raid1.c | 8 ++++---- drivers/md/raid10.c | 8 ++++---- drivers/md/raid5.c | 10 +++++----- 6 files changed, 21 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 6279393db64d..49d6080387c8 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -505,7 +505,7 @@ void bitmap_update_sb(struct bitmap *bitmap) return; } spin_unlock_irqrestore(&bitmap->lock, flags); - sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0); + sb = kmap_atomic(bitmap->sb_page, KM_USER0); sb->events = cpu_to_le64(bitmap->mddev->events); if (bitmap->mddev->events < bitmap->events_cleared) { /* rocking back to read-only */ @@ -526,7 +526,7 @@ void bitmap_print_sb(struct bitmap *bitmap) if (!bitmap || !bitmap->sb_page) return; - sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0); + sb = kmap_atomic(bitmap->sb_page, KM_USER0); printk(KERN_DEBUG "%s: bitmap file superblock:\n", bmname(bitmap)); printk(KERN_DEBUG " magic: %08x\n", le32_to_cpu(sb->magic)); printk(KERN_DEBUG " version: %d\n", le32_to_cpu(sb->version)); @@ -575,7 +575,7 @@ static int bitmap_read_sb(struct bitmap *bitmap) return err; } - sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0); + sb = kmap_atomic(bitmap->sb_page, KM_USER0); chunksize = le32_to_cpu(sb->chunksize); daemon_sleep = le32_to_cpu(sb->daemon_sleep) * HZ; @@ -661,7 +661,7 @@ static int bitmap_mask_state(struct bitmap *bitmap, enum bitmap_state bits, return 0; } spin_unlock_irqrestore(&bitmap->lock, flags); - sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0); + sb = kmap_atomic(bitmap->sb_page, KM_USER0); old = le32_to_cpu(sb->state) & bits; switch (op) { case MASK_SET: sb->state |= cpu_to_le32(bits); diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c index 713acd02ab39..608a8d3736e2 100644 --- a/drivers/md/faulty.c +++ b/drivers/md/faulty.c @@ -171,7 +171,7 @@ static void add_sector(conf_t *conf, sector_t start, int mode) static int make_request(struct request_queue *q, struct bio *bio) { mddev_t *mddev = q->queuedata; - conf_t *conf = (conf_t*)mddev->private; + conf_t *conf = mddev->private; int failit = 0; if (bio_data_dir(bio) == WRITE) { @@ -224,7 +224,7 @@ static int make_request(struct request_queue *q, struct bio *bio) static void status(struct seq_file *seq, mddev_t *mddev) { - conf_t *conf = (conf_t*)mddev->private; + conf_t *conf = mddev->private; int n; if ((n=atomic_read(&conf->counters[WriteTransient])) != 0) @@ -327,7 +327,7 @@ static int run(mddev_t *mddev) static int stop(mddev_t *mddev) { - conf_t *conf = (conf_t *)mddev->private; + conf_t *conf = mddev->private; kfree(conf); mddev->private = NULL; diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 5558ebc705c8..97befd5cc0e3 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -84,7 +84,7 @@ static void multipath_end_bh_io (struct multipath_bh *mp_bh, int err) static void multipath_end_request(struct bio *bio, int error) { int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); - struct multipath_bh * mp_bh = (struct multipath_bh *)(bio->bi_private); + struct multipath_bh *mp_bh = bio->bi_private; multipath_conf_t *conf = mp_bh->mddev->private; mdk_rdev_t *rdev = conf->multipaths[mp_bh->path].rdev; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 1ab30f64848f..23a7516abbfd 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -262,7 +262,7 @@ static inline void update_head_pos(int disk, r1bio_t *r1_bio) static void raid1_end_read_request(struct bio *bio, int error) { int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); - r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private); + r1bio_t *r1_bio = bio->bi_private; int mirror; conf_t *conf = r1_bio->mddev->private; @@ -307,7 +307,7 @@ static void raid1_end_read_request(struct bio *bio, int error) static void raid1_end_write_request(struct bio *bio, int error) { int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); - r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private); + r1bio_t *r1_bio = bio->bi_private; int mirror, behind = test_bit(R1BIO_BehindIO, &r1_bio->state); conf_t *conf = r1_bio->mddev->private; struct bio *to_put = NULL; @@ -1223,7 +1223,7 @@ abort: static void end_sync_read(struct bio *bio, int error) { - r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private); + r1bio_t *r1_bio = bio->bi_private; int i; for (i=r1_bio->mddev->raid_disks; i--; ) @@ -1246,7 +1246,7 @@ static void end_sync_read(struct bio *bio, int error) static void end_sync_write(struct bio *bio, int error) { int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); - r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private); + r1bio_t *r1_bio = bio->bi_private; mddev_t *mddev = r1_bio->mddev; conf_t *conf = mddev->private; int i; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index b4ba41ecbd20..b90fef607f63 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -254,7 +254,7 @@ static inline void update_head_pos(int slot, r10bio_t *r10_bio) static void raid10_end_read_request(struct bio *bio, int error) { int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); - r10bio_t * r10_bio = (r10bio_t *)(bio->bi_private); + r10bio_t *r10_bio = bio->bi_private; int slot, dev; conf_t *conf = r10_bio->mddev->private; @@ -295,7 +295,7 @@ static void raid10_end_read_request(struct bio *bio, int error) static void raid10_end_write_request(struct bio *bio, int error) { int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); - r10bio_t * r10_bio = (r10bio_t *)(bio->bi_private); + r10bio_t *r10_bio = bio->bi_private; int slot, dev; conf_t *conf = r10_bio->mddev->private; @@ -1223,7 +1223,7 @@ abort: static void end_sync_read(struct bio *bio, int error) { - r10bio_t * r10_bio = (r10bio_t *)(bio->bi_private); + r10bio_t *r10_bio = bio->bi_private; conf_t *conf = r10_bio->mddev->private; int i,d; @@ -1260,7 +1260,7 @@ static void end_sync_read(struct bio *bio, int error) static void end_sync_write(struct bio *bio, int error) { int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); - r10bio_t * r10_bio = (r10bio_t *)(bio->bi_private); + r10bio_t *r10_bio = bio->bi_private; mddev_t *mddev = r10_bio->mddev; conf_t *conf = mddev->private; int i,d; diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index a361398875d0..10af3715b1fc 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -1618,7 +1618,7 @@ static void raid5_build_block(struct stripe_head *sh, int i, int previous) static void error(mddev_t *mddev, mdk_rdev_t *rdev) { char b[BDEVNAME_SIZE]; - raid5_conf_t *conf = (raid5_conf_t *) mddev->private; + raid5_conf_t *conf = mddev->private; pr_debug("raid5: error called\n"); if (!test_bit(Faulty, &rdev->flags)) { @@ -4057,7 +4057,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped * As the reads complete, handle_stripe will copy the data * into the destination stripe and release that stripe. */ - raid5_conf_t *conf = (raid5_conf_t *) mddev->private; + raid5_conf_t *conf = mddev->private; struct stripe_head *sh; sector_t first_sector, last_sector; int raid_disks = conf->previous_raid_disks; @@ -4266,7 +4266,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped /* FIXME go_faster isn't used */ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster) { - raid5_conf_t *conf = (raid5_conf_t *) mddev->private; + raid5_conf_t *conf = mddev->private; struct stripe_head *sh; sector_t max_sector = mddev->dev_sectors; int sync_blocks; @@ -5132,7 +5132,7 @@ abort: static int stop(mddev_t *mddev) { - raid5_conf_t *conf = (raid5_conf_t *) mddev->private; + raid5_conf_t *conf = mddev->private; md_unregister_thread(mddev->thread); mddev->thread = NULL; @@ -5181,7 +5181,7 @@ static void printall(struct seq_file *seq, raid5_conf_t *conf) static void status(struct seq_file *seq, mddev_t *mddev) { - raid5_conf_t *conf = (raid5_conf_t *) mddev->private; + raid5_conf_t *conf = mddev->private; int i; seq_printf(seq, " level %d, %dk chunk, algorithm %d", mddev->level, -- cgit v1.2.3 From c0cc75f84e0e413bce2dcabea74ef418da45c7c1 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 22 Mar 2010 10:28:51 +1100 Subject: md: discard StateChanged device flag. This was needed when sysfs files could only be 'notified' from process context. Now that we have sys_notify_direct, we can call it directly from an interrupt. Signed-off-by: NeilBrown --- drivers/md/md.c | 7 +------ drivers/md/md.h | 3 --- 2 files changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index e8d238885cd2..2a64cba9ea72 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5970,7 +5970,7 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev) mddev->pers->error_handler(mddev,rdev); if (mddev->degraded) set_bit(MD_RECOVERY_RECOVER, &mddev->recovery); - set_bit(StateChanged, &rdev->flags); + sysfs_notify_dirent(rdev->sysfs_state); set_bit(MD_RECOVERY_INTR, &mddev->recovery); set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); md_wakeup_thread(mddev->thread); @@ -6962,11 +6962,6 @@ void md_check_recovery(mddev_t *mddev) if (mddev->flags) md_update_sb(mddev, 0); - list_for_each_entry(rdev, &mddev->disks, same_set) - if (test_and_clear_bit(StateChanged, &rdev->flags)) - sysfs_notify_dirent(rdev->sysfs_state); - - if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) && !test_bit(MD_RECOVERY_DONE, &mddev->recovery)) { /* resync/recovery still happening */ diff --git a/drivers/md/md.h b/drivers/md/md.h index 05145786b50f..e4836c68b73e 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -74,9 +74,6 @@ struct mdk_rdev_s #define Blocked 8 /* An error occured on an externally * managed array, don't allow writes * until it is cleared */ -#define StateChanged 9 /* Faulty or Blocked has changed during - * interrupt, so it needs to be - * notified by the thread */ wait_queue_head_t blocked_wait; int desc_nr; /* descriptor index in the superblock */ -- cgit v1.2.3 From 84707f38e767ac470fd82af6c45a8cafe2bd1b9a Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 16 Mar 2010 17:23:35 +1100 Subject: md: don't use mddev->raid_disks in raid0 or raid10 while array is active. In a subsequent patch we will make it possible to change mddev->raid_disks while a RAID0 or RAID10 array is active. This is part of the process of reshaping such an array. This means that we cannot use this value while processes requests (it is OK to use it during initialisation as we are locked against changes then). Both RAID0 and RAID10 have the same value stored in the private data structure, so use that value instead. Signed-off-by: NeilBrown --- drivers/md/raid0.c | 15 ++++++++++----- drivers/md/raid10.c | 16 ++++++++-------- 2 files changed, 18 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 377cf2a3c333..c2e0d1d28102 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -28,9 +28,10 @@ static void raid0_unplug(struct request_queue *q) mddev_t *mddev = q->queuedata; raid0_conf_t *conf = mddev->private; mdk_rdev_t **devlist = conf->devlist; + int raid_disks = conf->strip_zone[0].nb_dev; int i; - for (i=0; iraid_disks; i++) { + for (i=0; i < raid_disks; i++) { struct request_queue *r_queue = bdev_get_queue(devlist[i]->bdev); blk_unplug(r_queue); @@ -42,12 +43,13 @@ static int raid0_congested(void *data, int bits) mddev_t *mddev = data; raid0_conf_t *conf = mddev->private; mdk_rdev_t **devlist = conf->devlist; + int raid_disks = conf->strip_zone[0].nb_dev; int i, ret = 0; if (mddev_congested(mddev, bits)) return 1; - for (i = 0; i < mddev->raid_disks && !ret ; i++) { + for (i = 0; i < raid_disks && !ret ; i++) { struct request_queue *q = bdev_get_queue(devlist[i]->bdev); ret |= bdi_congested(&q->backing_dev_info, bits); @@ -65,6 +67,7 @@ static void dump_zones(mddev_t *mddev) sector_t zone_start = 0; char b[BDEVNAME_SIZE]; raid0_conf_t *conf = mddev->private; + int raid_disks = conf->strip_zone[0].nb_dev; printk(KERN_INFO "******* %s configuration *********\n", mdname(mddev)); h = 0; @@ -72,7 +75,7 @@ static void dump_zones(mddev_t *mddev) printk(KERN_INFO "zone%d=[", j); for (k = 0; k < conf->strip_zone[j].nb_dev; k++) printk("%s/", - bdevname(conf->devlist[j*mddev->raid_disks + bdevname(conf->devlist[j*raid_disks + k]->bdev, b)); printk("]\n"); @@ -401,6 +404,7 @@ static mdk_rdev_t *map_sector(mddev_t *mddev, struct strip_zone *zone, unsigned int sect_in_chunk; sector_t chunk; raid0_conf_t *conf = mddev->private; + int raid_disks = conf->strip_zone[0].nb_dev; unsigned int chunk_sects = mddev->chunk_sectors; if (is_power_of_2(chunk_sects)) { @@ -423,7 +427,7 @@ static mdk_rdev_t *map_sector(mddev_t *mddev, struct strip_zone *zone, * + the position in the chunk */ *sector_offset = (chunk * chunk_sects) + sect_in_chunk; - return conf->devlist[(zone - conf->strip_zone)*mddev->raid_disks + return conf->devlist[(zone - conf->strip_zone)*raid_disks + sector_div(sector, zone->nb_dev)]; } @@ -518,6 +522,7 @@ static void raid0_status(struct seq_file *seq, mddev_t *mddev) int j, k, h; char b[BDEVNAME_SIZE]; raid0_conf_t *conf = mddev->private; + int raid_disks = conf->strip_zone[0].nb_dev; sector_t zone_size; sector_t zone_start = 0; @@ -528,7 +533,7 @@ static void raid0_status(struct seq_file *seq, mddev_t *mddev) seq_printf(seq, "=["); for (k = 0; k < conf->strip_zone[j].nb_dev; k++) seq_printf(seq, "%s/", bdevname( - conf->devlist[j*mddev->raid_disks + k] + conf->devlist[j*raid_disks + k] ->bdev, b)); zone_size = conf->strip_zone[j].zone_end - zone_start; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index b90fef607f63..044c1157d98d 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -600,7 +600,7 @@ static void unplug_slaves(mddev_t *mddev) int i; rcu_read_lock(); - for (i=0; iraid_disks; i++) { + for (i=0; i < conf->raid_disks; i++) { mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev); if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) { struct request_queue *r_queue = bdev_get_queue(rdev->bdev); @@ -634,7 +634,7 @@ static int raid10_congested(void *data, int bits) if (mddev_congested(mddev, bits)) return 1; rcu_read_lock(); - for (i = 0; i < mddev->raid_disks && ret == 0; i++) { + for (i = 0; i < conf->raid_disks && ret == 0; i++) { mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev); if (rdev && !test_bit(Faulty, &rdev->flags)) { struct request_queue *q = bdev_get_queue(rdev->bdev); @@ -1131,7 +1131,7 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) int mirror; mirror_info_t *p; int first = 0; - int last = mddev->raid_disks - 1; + int last = conf->raid_disks - 1; if (mddev->recovery_cp < MaxSector) /* only hot-add to in-sync arrays, as recovery is @@ -2139,7 +2139,7 @@ raid10_size(mddev_t *mddev, sector_t sectors, int raid_disks) conf_t *conf = mddev->private; if (!raid_disks) - raid_disks = mddev->raid_disks; + raid_disks = conf->raid_disks; if (!sectors) sectors = mddev->dev_sectors; @@ -2250,7 +2250,7 @@ static int run(mddev_t *mddev) list_for_each_entry(rdev, &mddev->disks, same_set) { disk_idx = rdev->raid_disk; - if (disk_idx >= mddev->raid_disks + if (disk_idx >= conf->raid_disks || disk_idx < 0) continue; disk = conf->mirrors + disk_idx; @@ -2311,8 +2311,8 @@ static int run(mddev_t *mddev) mdname(mddev)); printk(KERN_INFO "raid10: raid set %s active with %d out of %d devices\n", - mdname(mddev), mddev->raid_disks - mddev->degraded, - mddev->raid_disks); + mdname(mddev), conf->raid_disks - mddev->degraded, + conf->raid_disks); /* * Ok, everything is just fine now */ @@ -2335,7 +2335,7 @@ static int run(mddev_t *mddev) mddev->queue->backing_dev_info.ra_pages = 2* stripe; } - if (conf->near_copies < mddev->raid_disks) + if (conf->near_copies < conf->raid_disks) blk_queue_merge_bvec(mddev->queue, raid10_mergeable_bvec); md_integrity_register(mddev); return 0; -- cgit v1.2.3 From 54071b3808ee3dc8624d9d6f1b06c4fd5308fa3b Mon Sep 17 00:00:00 2001 From: Trela Maciej Date: Mon, 8 Mar 2010 16:02:42 +1100 Subject: md:Add support for Raid0->Raid5 takeover Signed-off-by: Maciej Trela Signed-off-by: NeilBrown --- drivers/md/md.c | 14 ++++++++++++++ drivers/md/raid5.c | 26 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 2a64cba9ea72..22c630b7ba6c 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3017,6 +3017,20 @@ level_store(mddev_t *mddev, const char *buf, size_t len) mddev->to_remove = &md_redundancy_group; } + if (mddev->pers->sync_request == NULL && + mddev->external) { + /* We are converting from a no-redundancy array + * to a redundancy array and metadata is managed + * externally so we need to be sure that writes + * won't block due to a need to transition + * clean->dirty + * until external management is started. + */ + mddev->in_sync = 0; + mddev->safemode_delay = 0; + mddev->safemode = 0; + } + module_put(mddev->pers->owner); /* Invalidate devices that are now superfluous */ list_for_each_entry(rdev, &mddev->disks, same_set) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 10af3715b1fc..bb28fd6b44fe 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -52,6 +52,7 @@ #include #include "md.h" #include "raid5.h" +#include "raid0.h" #include "bitmap.h" /* @@ -5619,6 +5620,21 @@ static void raid5_quiesce(mddev_t *mddev, int state) } +static void *raid5_takeover_raid0(mddev_t *mddev) +{ + + mddev->new_level = 5; + mddev->new_layout = ALGORITHM_PARITY_N; + mddev->new_chunk_sectors = mddev->chunk_sectors; + mddev->raid_disks += 1; + mddev->delta_disks = 1; + /* make sure it will be not marked as dirty */ + mddev->recovery_cp = MaxSector; + + return setup_conf(mddev); +} + + static void *raid5_takeover_raid1(mddev_t *mddev) { int chunksect; @@ -5748,6 +5764,16 @@ static void *raid5_takeover(mddev_t *mddev) * raid4 - trivial - just use a raid4 layout. * raid6 - Providing it is a *_6 layout */ + if (mddev->level == 0) { + /* for raid0 takeover only one zone is supported */ + struct raid0_private_data *raid0_priv + = mddev->private; + if (raid0_priv->nr_strip_zones > 1) { + printk(KERN_ERR "md: cannot takeover raid 0 with more than one zone.\n"); + return ERR_PTR(-EINVAL); + } + return raid5_takeover_raid0(mddev); + } if (mddev->level == 1) return raid5_takeover_raid1(mddev); -- cgit v1.2.3 From 9af204cf720cedf369cf823bbd806c350201f7ea Mon Sep 17 00:00:00 2001 From: "Trela, Maciej" Date: Mon, 8 Mar 2010 16:02:44 +1100 Subject: md: Add support for Raid5->Raid0 and Raid10->Raid0 takeover Signed-off-by: Maciej Trela Signed-off-by: NeilBrown --- drivers/md/md.c | 7 +++ drivers/md/raid0.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++--- drivers/md/raid0.h | 3 ++ 3 files changed, 129 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 22c630b7ba6c..7dcc74089550 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3045,6 +3045,13 @@ level_store(mddev_t *mddev, const char *buf, size_t len) mddev->layout = mddev->new_layout; mddev->chunk_sectors = mddev->new_chunk_sectors; mddev->delta_disks = 0; + if (mddev->pers->sync_request == NULL) { + /* this is now an array without redundancy, so + * it must always be in_sync + */ + mddev->in_sync = 1; + del_timer_sync(&mddev->safemode_timer); + } pers->run(mddev); mddev_resume(mddev); set_bit(MD_CHANGE_DEVS, &mddev->flags); diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index c2e0d1d28102..afddf624bad3 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -22,6 +22,7 @@ #include #include "md.h" #include "raid0.h" +#include "raid5.h" static void raid0_unplug(struct request_queue *q) { @@ -90,7 +91,7 @@ static void dump_zones(mddev_t *mddev) printk(KERN_INFO "**********************************\n\n"); } -static int create_strip_zones(mddev_t *mddev) +static int create_strip_zones(mddev_t *mddev, raid0_conf_t **private_conf) { int i, c, err; sector_t curr_zone_end, sectors; @@ -164,6 +165,10 @@ static int create_strip_zones(mddev_t *mddev) list_for_each_entry(rdev1, &mddev->disks, same_set) { int j = rdev1->raid_disk; + if (mddev->level == 10) + /* taking over a raid10-n2 array */ + j /= 2; + if (j < 0 || j >= mddev->raid_disks) { printk(KERN_ERR "raid0: bad disk number %d - " "aborting!\n", j); @@ -264,13 +269,14 @@ static int create_strip_zones(mddev_t *mddev) (mddev->chunk_sectors << 9) * mddev->raid_disks); printk(KERN_INFO "raid0: done.\n"); - mddev->private = conf; + *private_conf = conf; + return 0; abort: kfree(conf->strip_zone); kfree(conf->devlist); kfree(conf); - mddev->private = NULL; + *private_conf = NULL; return err; } @@ -321,6 +327,7 @@ static sector_t raid0_size(mddev_t *mddev, sector_t sectors, int raid_disks) static int raid0_run(mddev_t *mddev) { + raid0_conf_t *conf; int ret; if (mddev->chunk_sectors == 0) { @@ -332,9 +339,20 @@ static int raid0_run(mddev_t *mddev) blk_queue_max_hw_sectors(mddev->queue, mddev->chunk_sectors); mddev->queue->queue_lock = &mddev->queue->__queue_lock; - ret = create_strip_zones(mddev); - if (ret < 0) - return ret; + /* if private is not null, we are here after takeover */ + if (mddev->private == NULL) { + ret = create_strip_zones(mddev, &conf); + if (ret < 0) + return ret; + mddev->private = conf; + } + conf = mddev->private; + if (conf->scale_raid_disks) { + int i; + for (i=0; i < conf->strip_zone[0].nb_dev; i++) + conf->devlist[i]->raid_disk /= conf->scale_raid_disks; + /* FIXME update sysfs rd links */ + } /* calculate array device size */ md_set_array_sectors(mddev, raid0_size(mddev, 0, 0)); @@ -548,6 +566,99 @@ static void raid0_status(struct seq_file *seq, mddev_t *mddev) return; } +static void *raid0_takeover_raid5(mddev_t *mddev) +{ + mdk_rdev_t *rdev; + raid0_conf_t *priv_conf; + + if (mddev->degraded != 1) { + printk(KERN_ERR "md: raid5 must be degraded! Degraded disks: %d\n", + mddev->degraded); + return ERR_PTR(-EINVAL); + } + + list_for_each_entry(rdev, &mddev->disks, same_set) { + /* check slot number for a disk */ + if (rdev->raid_disk == mddev->raid_disks-1) { + printk(KERN_ERR "md: raid5 must have missing parity disk!\n"); + return ERR_PTR(-EINVAL); + } + } + + /* Set new parameters */ + mddev->new_level = 0; + mddev->new_chunk_sectors = mddev->chunk_sectors; + mddev->raid_disks--; + mddev->delta_disks = -1; + /* make sure it will be not marked as dirty */ + mddev->recovery_cp = MaxSector; + + create_strip_zones(mddev, &priv_conf); + return priv_conf; +} + +static void *raid0_takeover_raid10(mddev_t *mddev) +{ + raid0_conf_t *priv_conf; + + /* Check layout: + * - far_copies must be 1 + * - near_copies must be 2 + * - disks number must be even + * - all mirrors must be already degraded + */ + if (mddev->layout != ((1 << 8) + 2)) { + printk(KERN_ERR "md: Raid0 cannot takover layout: %x\n", + mddev->layout); + return ERR_PTR(-EINVAL); + } + if (mddev->raid_disks & 1) { + printk(KERN_ERR "md: Raid0 cannot takover Raid10 with odd disk number.\n"); + return ERR_PTR(-EINVAL); + } + if (mddev->degraded != (mddev->raid_disks>>1)) { + printk(KERN_ERR "md: All mirrors must be already degraded!\n"); + return ERR_PTR(-EINVAL); + } + + /* Set new parameters */ + mddev->new_level = 0; + mddev->new_chunk_sectors = mddev->chunk_sectors; + mddev->delta_disks = - mddev->raid_disks / 2; + mddev->raid_disks += mddev->delta_disks; + mddev->degraded = 0; + /* make sure it will be not marked as dirty */ + mddev->recovery_cp = MaxSector; + + create_strip_zones(mddev, &priv_conf); + priv_conf->scale_raid_disks = 2; + return priv_conf; +} + +static void *raid0_takeover(mddev_t *mddev) +{ + /* raid0 can take over: + * raid5 - providing it is Raid4 layout and one disk is faulty + * raid10 - assuming we have all necessary active disks + */ + if (mddev->level == 5) { + if (mddev->layout == ALGORITHM_PARITY_N) + return raid0_takeover_raid5(mddev); + + printk(KERN_ERR "md: Raid can only takeover Raid5 with layout: %d\n", + ALGORITHM_PARITY_N); + } + + if (mddev->level == 10) + return raid0_takeover_raid10(mddev); + + return ERR_PTR(-EINVAL); +} + +static void raid0_quiesce(mddev_t *mddev, int state) +{ +} + static struct mdk_personality raid0_personality= { .name = "raid0", @@ -558,6 +669,8 @@ static struct mdk_personality raid0_personality= .stop = raid0_stop, .status = raid0_status, .size = raid0_size, + .takeover = raid0_takeover, + .quiesce = raid0_quiesce, }; static int __init raid0_init (void) diff --git a/drivers/md/raid0.h b/drivers/md/raid0.h index 91f8e876ee64..d724e664ca4d 100644 --- a/drivers/md/raid0.h +++ b/drivers/md/raid0.h @@ -13,6 +13,9 @@ struct raid0_private_data struct strip_zone *strip_zone; mdk_rdev_t **devlist; /* lists of rdevs, pointed to by strip_zone->dev */ int nr_strip_zones; + int scale_raid_disks; /* divide rdev->raid_disks by this in run() + * to handle conversion from raid10 + */ }; typedef struct raid0_private_data raid0_conf_t; -- cgit v1.2.3 From dab8b29248b3f14f456651a2a6ee9b8fd16d1b3c Mon Sep 17 00:00:00 2001 From: "Trela, Maciej" Date: Mon, 8 Mar 2010 16:02:45 +1100 Subject: md: Add support for Raid0->Raid10 takeover Signed-off-by: Maciej Trela Signed-off-by: NeilBrown --- drivers/md/raid10.c | 194 ++++++++++++++++++++++++++++++++++++++-------------- drivers/md/raid10.h | 12 ++++ 2 files changed, 155 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 044c1157d98d..57d71d5d88f4 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -23,6 +23,7 @@ #include #include "md.h" #include "raid10.h" +#include "raid0.h" #include "bitmap.h" /* @@ -2141,7 +2142,7 @@ raid10_size(mddev_t *mddev, sector_t sectors, int raid_disks) if (!raid_disks) raid_disks = conf->raid_disks; if (!sectors) - sectors = mddev->dev_sectors; + sectors = conf->dev_sectors; size = sectors >> conf->chunk_shift; sector_div(size, conf->far_copies); @@ -2151,62 +2152,60 @@ raid10_size(mddev_t *mddev, sector_t sectors, int raid_disks) return size << conf->chunk_shift; } -static int run(mddev_t *mddev) + +static conf_t *setup_conf(mddev_t *mddev) { - conf_t *conf; - int i, disk_idx, chunk_size; - mirror_info_t *disk; - mdk_rdev_t *rdev; + conf_t *conf = NULL; int nc, fc, fo; sector_t stride, size; + int err = -EINVAL; if (mddev->chunk_sectors < (PAGE_SIZE >> 9) || !is_power_of_2(mddev->chunk_sectors)) { printk(KERN_ERR "md/raid10: chunk size must be " "at least PAGE_SIZE(%ld) and be a power of 2.\n", PAGE_SIZE); - return -EINVAL; + goto out; } nc = mddev->layout & 255; fc = (mddev->layout >> 8) & 255; fo = mddev->layout & (1<<16); + if ((nc*fc) <2 || (nc*fc) > mddev->raid_disks || (mddev->layout >> 17)) { printk(KERN_ERR "raid10: %s: unsupported raid10 layout: 0x%8x\n", mdname(mddev), mddev->layout); goto out; } - /* - * copy the already verified devices into our private RAID10 - * bookkeeping area. [whatever we allocate in run(), - * should be freed in stop()] - */ + + err = -ENOMEM; conf = kzalloc(sizeof(conf_t), GFP_KERNEL); - mddev->private = conf; - if (!conf) { - printk(KERN_ERR "raid10: couldn't allocate memory for %s\n", - mdname(mddev)); + if (!conf) goto out; - } + conf->mirrors = kzalloc(sizeof(struct mirror_info)*mddev->raid_disks, - GFP_KERNEL); - if (!conf->mirrors) { - printk(KERN_ERR "raid10: couldn't allocate memory for %s\n", - mdname(mddev)); - goto out_free_conf; - } + GFP_KERNEL); + if (!conf->mirrors) + goto out; conf->tmppage = alloc_page(GFP_KERNEL); if (!conf->tmppage) - goto out_free_conf; + goto out; + conf->raid_disks = mddev->raid_disks; conf->near_copies = nc; conf->far_copies = fc; conf->copies = nc*fc; conf->far_offset = fo; - conf->chunk_mask = mddev->chunk_sectors - 1; - conf->chunk_shift = ffz(~mddev->chunk_sectors); + conf->chunk_mask = mddev->new_chunk_sectors - 1; + conf->chunk_shift = ffz(~mddev->new_chunk_sectors); + + conf->r10bio_pool = mempool_create(NR_RAID10_BIOS, r10bio_pool_alloc, + r10bio_pool_free, conf); + if (!conf->r10bio_pool) + goto out; + size = mddev->dev_sectors >> conf->chunk_shift; sector_div(size, fc); size = size * conf->raid_disks; @@ -2220,7 +2219,8 @@ static int run(mddev_t *mddev) */ stride += conf->raid_disks - 1; sector_div(stride, conf->raid_disks); - mddev->dev_sectors = stride << conf->chunk_shift; + + conf->dev_sectors = stride << conf->chunk_shift; if (fo) stride = 1; @@ -2228,18 +2228,63 @@ static int run(mddev_t *mddev) sector_div(stride, fc); conf->stride = stride << conf->chunk_shift; - conf->r10bio_pool = mempool_create(NR_RAID10_BIOS, r10bio_pool_alloc, - r10bio_pool_free, conf); - if (!conf->r10bio_pool) { - printk(KERN_ERR "raid10: couldn't allocate memory for %s\n", - mdname(mddev)); - goto out_free_conf; - } - conf->mddev = mddev; spin_lock_init(&conf->device_lock); + INIT_LIST_HEAD(&conf->retry_list); + + spin_lock_init(&conf->resync_lock); + init_waitqueue_head(&conf->wait_barrier); + + conf->thread = md_register_thread(raid10d, mddev, NULL); + if (!conf->thread) + goto out; + + conf->scale_disks = 0; + conf->mddev = mddev; + return conf; + + out: + printk(KERN_ERR "raid10: couldn't allocate memory for %s\n", + mdname(mddev)); + if (conf) { + if (conf->r10bio_pool) + mempool_destroy(conf->r10bio_pool); + kfree(conf->mirrors); + safe_put_page(conf->tmppage); + kfree(conf); + } + return ERR_PTR(err); +} + +static int run(mddev_t *mddev) +{ + conf_t *conf; + int i, disk_idx, chunk_size; + mirror_info_t *disk; + mdk_rdev_t *rdev; + sector_t size; + + /* + * copy the already verified devices into our private RAID10 + * bookkeeping area. [whatever we allocate in run(), + * should be freed in stop()] + */ + + if (mddev->private == NULL) { + conf = setup_conf(mddev); + if (IS_ERR(conf)) + return PTR_ERR(conf); + mddev->private = conf; + } + conf = mddev->private; + if (!conf) + goto out; + mddev->queue->queue_lock = &conf->device_lock; + mddev->thread = conf->thread; + conf->thread = NULL; + chunk_size = mddev->chunk_sectors << 9; blk_queue_io_min(mddev->queue, chunk_size); if (conf->raid_disks % conf->near_copies) @@ -2253,6 +2298,11 @@ static int run(mddev_t *mddev) if (disk_idx >= conf->raid_disks || disk_idx < 0) continue; + if (conf->scale_disks) { + disk_idx *= conf->scale_disks; + rdev->raid_disk = disk_idx; + /* MOVE 'rd%d' link !! */ + } disk = conf->mirrors + disk_idx; disk->rdev = rdev; @@ -2270,11 +2320,6 @@ static int run(mddev_t *mddev) disk->head_position = 0; } - INIT_LIST_HEAD(&conf->retry_list); - - spin_lock_init(&conf->resync_lock); - init_waitqueue_head(&conf->wait_barrier); - /* need to check that every block has at least one working mirror */ if (!enough(conf)) { printk(KERN_ERR "raid10: not enough operational mirrors for %s\n", @@ -2296,15 +2341,6 @@ static int run(mddev_t *mddev) } } - - mddev->thread = md_register_thread(raid10d, mddev, NULL); - if (!mddev->thread) { - printk(KERN_ERR - "raid10: couldn't allocate thread for %s\n", - mdname(mddev)); - goto out_free_conf; - } - if (mddev->recovery_cp != MaxSector) printk(KERN_NOTICE "raid10: %s is not clean" " -- starting background reconstruction\n", @@ -2316,8 +2352,10 @@ static int run(mddev_t *mddev) /* * Ok, everything is just fine now */ - md_set_array_sectors(mddev, raid10_size(mddev, 0, 0)); - mddev->resync_max_sectors = raid10_size(mddev, 0, 0); + mddev->dev_sectors = conf->dev_sectors; + size = raid10_size(mddev, 0, 0); + md_set_array_sectors(mddev, size); + mddev->resync_max_sectors = size; mddev->queue->unplug_fn = raid10_unplug; mddev->queue->backing_dev_info.congested_fn = raid10_congested; @@ -2347,6 +2385,7 @@ out_free_conf: kfree(conf->mirrors); kfree(conf); mddev->private = NULL; + md_unregister_thread(mddev->thread); out: return -EIO; } @@ -2383,6 +2422,58 @@ static void raid10_quiesce(mddev_t *mddev, int state) } } +static void *raid10_takeover_raid0(mddev_t *mddev) +{ + mdk_rdev_t *rdev; + conf_t *conf; + + if (mddev->degraded > 0) { + printk(KERN_ERR "error: degraded raid0!\n"); + return ERR_PTR(-EINVAL); + } + + /* Update slot numbers to obtain + * degraded raid10 with missing mirrors + */ + list_for_each_entry(rdev, &mddev->disks, same_set) { + rdev->raid_disk *= 2; + } + + /* Set new parameters */ + mddev->new_level = 10; + /* new layout: far_copies = 1, near_copies = 2 */ + mddev->new_layout = (1<<8) + 2; + mddev->new_chunk_sectors = mddev->chunk_sectors; + mddev->delta_disks = mddev->raid_disks; + mddev->degraded = mddev->raid_disks; + mddev->raid_disks *= 2; + /* make sure it will be not marked as dirty */ + mddev->recovery_cp = MaxSector; + + conf = setup_conf(mddev); + conf->scale_disks = 2; + return conf; +} + +static void *raid10_takeover(mddev_t *mddev) +{ + struct raid0_private_data *raid0_priv; + + /* raid10 can take over: + * raid0 - providing it has only two drives + */ + if (mddev->level == 0) { + /* for raid0 takeover only one zone is supported */ + raid0_priv = mddev->private; + if (raid0_priv->nr_strip_zones > 1) { + printk(KERN_ERR "md: cannot takeover raid 0 with more than one zone.\n"); + return ERR_PTR(-EINVAL); + } + return raid10_takeover_raid0(mddev); + } + return ERR_PTR(-EINVAL); +} + static struct mdk_personality raid10_personality = { .name = "raid10", @@ -2399,6 +2490,7 @@ static struct mdk_personality raid10_personality = .sync_request = sync_request, .quiesce = raid10_quiesce, .size = raid10_size, + .takeover = raid10_takeover, }; static int __init raid_init(void) diff --git a/drivers/md/raid10.h b/drivers/md/raid10.h index 59cd1efb8d30..3824a087e17c 100644 --- a/drivers/md/raid10.h +++ b/drivers/md/raid10.h @@ -33,9 +33,16 @@ struct r10_private_data_s { * 1 stripe. */ + sector_t dev_sectors; /* temp copy of mddev->dev_sectors */ + int chunk_shift; /* shift from chunks to sectors */ sector_t chunk_mask; + int scale_disks; /* When starting array, multiply + * each ->raid_disk by this. + * Need for raid0->raid10 migration + */ + struct list_head retry_list; /* queue pending writes and submit them on unplug */ struct bio_list pending_bio_list; @@ -57,6 +64,11 @@ struct r10_private_data_s { mempool_t *r10bio_pool; mempool_t *r10buf_pool; struct page *tmppage; + + /* When taking over an array from a different personality, we store + * the new thread here until we fully activate the array. + */ + struct mdk_thread_s *thread; }; typedef struct r10_private_data_s conf_t; -- cgit v1.2.3 From b71031076e1169e89bdac1b245ad1488587e4730 Mon Sep 17 00:00:00 2001 From: Maciej Trela Date: Wed, 14 Apr 2010 16:58:16 +1000 Subject: md: Correctly handle device removal via sysfs Writing "none" to "../md/dev-xx/slot" removes that device from being an active part of the array, but it didn't set ->raid_disk to -1 to record this fact. Signed-off-by: Maciej Trela Signed-off-by: NeilBrown --- drivers/md/md.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 7dcc74089550..766be8701281 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2385,6 +2385,7 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) return err; sprintf(nm, "rd%d", rdev->raid_disk); sysfs_remove_link(&rdev->mddev->kobj, nm); + rdev->raid_disk = -1; set_bit(MD_RECOVERY_NEEDED, &rdev->mddev->recovery); md_wakeup_thread(rdev->mddev->thread); } else if (rdev->mddev->pers) { -- cgit v1.2.3 From 233fca36bb439eadcad28500b5139fed7c64a0ae Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 14 Apr 2010 17:02:09 +1000 Subject: md: Relax checks on ->max_disks when external metadata handling is used. When metadata is being managed by user-space, md doesn't know what the maximum number of devices allowed in an array is so ->max_disks is 0. In this case we should allow any (+ve) number of disks. Signed-off-by: NeilBrown --- drivers/md/md.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 766be8701281..46bdf4b38be8 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2801,8 +2801,9 @@ static void analyze_sbs(mddev_t * mddev) i = 0; rdev_for_each(rdev, tmp, mddev) { - if (rdev->desc_nr >= mddev->max_disks || - i > mddev->max_disks) { + if (mddev->max_disks && + (rdev->desc_nr >= mddev->max_disks || + i > mddev->max_disks)) { printk(KERN_WARNING "md: %s: %s: only %d devices permitted\n", mdname(mddev), bdevname(rdev->bdev, b), @@ -5406,7 +5407,7 @@ static int update_raid_disks(mddev_t *mddev, int raid_disks) if (mddev->pers->check_reshape == NULL) return -EINVAL; if (raid_disks <= 0 || - raid_disks >= mddev->max_disks) + (mddev->max_disks && raid_disks >= mddev->max_disks)) return -EINVAL; if (mddev->sync_thread || mddev->reshape_position != MaxSector) return -EBUSY; -- cgit v1.2.3 From 5cac7861b2de95a1f714ebdc652813abd0afcc73 Mon Sep 17 00:00:00 2001 From: Maciej Trela Date: Wed, 14 Apr 2010 17:17:39 +1000 Subject: md: notify level changes through sysfs. Level changes can be very significant, so make sure to notify them via sysfs. Signed-off-by: Maciej Trela Signed-off-by: NeilBrown --- drivers/md/md.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 46bdf4b38be8..c5a1b0725c9f 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3059,6 +3059,7 @@ level_store(mddev_t *mddev, const char *buf, size_t len) set_bit(MD_CHANGE_DEVS, &mddev->flags); set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); md_wakeup_thread(mddev->thread); + sysfs_notify(&mddev->kobj, NULL, "level"); return rv; } -- cgit v1.2.3 From a78d38a1a16c8e009aa512caa71d483757fefc1c Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 22 Mar 2010 16:53:49 +1100 Subject: md: add support for raid5 to raid4 conversion This is unlikely to be wanted, but we may as well provide it for completeness. Signed-off-by: NeilBrown --- drivers/md/raid5.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index bb28fd6b44fe..020143dec180 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -5788,6 +5788,18 @@ static void *raid5_takeover(mddev_t *mddev) return ERR_PTR(-EINVAL); } +static void *raid4_takeover(mddev_t *mddev) +{ + /* raid4 can take over raid5 if layout is right. + */ + if (mddev->level == 5 && + mddev->layout == ALGORITHM_PARITY_N) { + mddev->new_layout = 0; + mddev->new_level = 4; + return setup_conf(mddev); + } + return ERR_PTR(-EINVAL); +} static struct mdk_personality raid5_personality; @@ -5903,6 +5915,7 @@ static struct mdk_personality raid4_personality = .start_reshape = raid5_start_reshape, .finish_reshape = raid5_finish_reshape, .quiesce = raid5_quiesce, + .takeover = raid4_takeover, }; static int __init raid5_init(void) -- cgit v1.2.3 From 2b7f22284d71975e37a82db154386348eec0e52c Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 25 Mar 2010 16:06:03 +1100 Subject: md/raid5: small tidyup in raid5_align_endio Diving through ->queue to find mddev is unnecessarily complex - there is an easier path to finding mddev, so use that. Signed-off-by: NeilBrown --- drivers/md/raid5.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 020143dec180..7bfeba3ce1e0 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3713,10 +3713,10 @@ static void raid5_align_endio(struct bio *bi, int error) bio_put(bi); - mddev = raid_bi->bi_bdev->bd_disk->queue->queuedata; - conf = mddev->private; rdev = (void*)raid_bi->bi_next; raid_bi->bi_next = NULL; + mddev = rdev->mddev; + conf = mddev->private; rdev_dec_pending(rdev, conf->mddev); -- cgit v1.2.3 From 490773268cf64f68da2470e07b52c7944da6312d Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 25 Mar 2010 16:20:56 +1100 Subject: md: move io accounting out of personalities into md_make_request While I generally prefer letting personalities do as much as possible, given that we have a central md_make_request anyway we may as well use it to simplify code. Also this centralises knowledge of ->gendisk which will help later. Signed-off-by: NeilBrown --- drivers/md/linear.c | 8 -------- drivers/md/md.c | 11 +++++++++++ drivers/md/multipath.c | 8 -------- drivers/md/raid0.c | 8 -------- drivers/md/raid1.c | 7 ------- drivers/md/raid10.c | 7 ------- drivers/md/raid5.c | 8 +------- 7 files changed, 12 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 9db8ee0614a4..3048c1704f40 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c @@ -288,23 +288,15 @@ static int linear_stop (mddev_t *mddev) static int linear_make_request (struct request_queue *q, struct bio *bio) { - const int rw = bio_data_dir(bio); mddev_t *mddev = q->queuedata; dev_info_t *tmp_dev; sector_t start_sector; - int cpu; if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) { md_barrier_request(mddev, bio); return 0; } - cpu = part_stat_lock(); - part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); - part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], - bio_sectors(bio)); - part_stat_unlock(); - rcu_read_lock(); tmp_dev = which_dev(mddev, bio->bi_sector); start_sector = tmp_dev->end_sector - tmp_dev->rdev->sectors; diff --git a/drivers/md/md.c b/drivers/md/md.c index c5a1b0725c9f..117663d2a4e5 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -214,8 +214,11 @@ static DEFINE_SPINLOCK(all_mddevs_lock); */ static int md_make_request(struct request_queue *q, struct bio *bio) { + const int rw = bio_data_dir(bio); mddev_t *mddev = q->queuedata; int rv; + int cpu; + if (mddev == NULL || mddev->pers == NULL) { bio_io_error(bio); return 0; @@ -236,7 +239,15 @@ static int md_make_request(struct request_queue *q, struct bio *bio) } atomic_inc(&mddev->active_io); rcu_read_unlock(); + rv = mddev->pers->make_request(q, bio); + + cpu = part_stat_lock(); + part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); + part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], + bio_sectors(bio)); + part_stat_unlock(); + if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended) wake_up(&mddev->sb_wait); diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 97befd5cc0e3..5b4e2918663a 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -141,8 +141,6 @@ static int multipath_make_request (struct request_queue *q, struct bio * bio) multipath_conf_t *conf = mddev->private; struct multipath_bh * mp_bh; struct multipath_info *multipath; - const int rw = bio_data_dir(bio); - int cpu; if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) { md_barrier_request(mddev, bio); @@ -154,12 +152,6 @@ static int multipath_make_request (struct request_queue *q, struct bio * bio) mp_bh->master_bio = bio; mp_bh->mddev = mddev; - cpu = part_stat_lock(); - part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); - part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], - bio_sectors(bio)); - part_stat_unlock(); - mp_bh->path = multipath_map(conf); if (mp_bh->path < 0) { bio_endio(bio, -EIO); diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index afddf624bad3..d535f9be39f4 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -472,20 +472,12 @@ static int raid0_make_request(struct request_queue *q, struct bio *bio) sector_t sector_offset; struct strip_zone *zone; mdk_rdev_t *tmp_dev; - const int rw = bio_data_dir(bio); - int cpu; if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) { md_barrier_request(mddev, bio); return 0; } - cpu = part_stat_lock(); - part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); - part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], - bio_sectors(bio)); - part_stat_unlock(); - chunk_sects = mddev->chunk_sectors; if (unlikely(!is_io_in_chunk_boundary(mddev, chunk_sects, bio))) { sector_t sector = bio->bi_sector; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 23a7516abbfd..e277013ac808 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -787,7 +787,6 @@ static int make_request(struct request_queue *q, struct bio * bio) struct page **behind_pages = NULL; const int rw = bio_data_dir(bio); const bool do_sync = bio_rw_flagged(bio, BIO_RW_SYNCIO); - int cpu; bool do_barriers; mdk_rdev_t *blocked_rdev; @@ -833,12 +832,6 @@ static int make_request(struct request_queue *q, struct bio * bio) bitmap = mddev->bitmap; - cpu = part_stat_lock(); - part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); - part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], - bio_sectors(bio)); - part_stat_unlock(); - /* * make_request() can abort the operation when READA is being * used and no empty request is available. diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 57d71d5d88f4..ca313d646fd1 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -795,7 +795,6 @@ static int make_request(struct request_queue *q, struct bio * bio) mirror_info_t *mirror; r10bio_t *r10_bio; struct bio *read_bio; - int cpu; int i; int chunk_sects = conf->chunk_mask + 1; const int rw = bio_data_dir(bio); @@ -850,12 +849,6 @@ static int make_request(struct request_queue *q, struct bio * bio) */ wait_barrier(conf); - cpu = part_stat_lock(); - part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); - part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], - bio_sectors(bio)); - part_stat_unlock(); - r10_bio = mempool_alloc(conf->r10bio_pool, GFP_NOIO); r10_bio->master_bio = bio; diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 7bfeba3ce1e0..c6ae7c194915 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3879,7 +3879,7 @@ static int make_request(struct request_queue *q, struct bio * bi) sector_t logical_sector, last_sector; struct stripe_head *sh; const int rw = bio_data_dir(bi); - int cpu, remaining; + int remaining; if (unlikely(bio_rw_flagged(bi, BIO_RW_BARRIER))) { /* Drain all pending writes. We only really need @@ -3894,12 +3894,6 @@ static int make_request(struct request_queue *q, struct bio * bi) md_write_start(mddev, bi); - cpu = part_stat_lock(); - part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); - part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], - bio_sectors(bi)); - part_stat_unlock(); - if (rw == READ && mddev->reshape_position == MaxSector && chunk_aligned_read(q,bi)) -- cgit v1.2.3 From 49ce6cea85fb8d25ee59486c919406e9cecf1762 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 29 Mar 2010 10:51:42 +1100 Subject: md: don't reference gendisk in getgeo Using ->array_sectors rather than get_capacity() is more direct and is a step towards relaxing the tight connection between mddev and gendisk. Signed-off-by: NeilBrown --- drivers/md/md.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 117663d2a4e5..69f2a8e6ccdf 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5556,7 +5556,7 @@ static int md_getgeo(struct block_device *bdev, struct hd_geometry *geo) geo->heads = 2; geo->sectors = 4; - geo->cylinders = get_capacity(mddev->gendisk) / 8; + geo->cylinders = mddev->array_sectors / 8; return 0; } -- cgit v1.2.3 From b821eaa572fd737faaf6928ba046e571526c36c6 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 29 Mar 2010 11:18:15 +1100 Subject: md: remove ->changed and related code. We set ->changed to 1 and call check_disk_change at the end of md_open so that bd_invalidated would be set and thus partition rescan would happen appropriately. Now that we call revalidate_disk directly, which sets bd_invalidates, that indirection is no longer needed and can be removed. Signed-off-by: NeilBrown --- drivers/md/md.c | 22 +--------------------- drivers/md/md.h | 1 - drivers/md/raid1.c | 1 - drivers/md/raid5.c | 2 -- 4 files changed, 1 insertion(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 69f2a8e6ccdf..f2b30019b1cb 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4501,7 +4501,6 @@ static int do_md_run(mddev_t * mddev) md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */ revalidate_disk(mddev->gendisk); - mddev->changed = 1; md_new_event(mddev); sysfs_notify_dirent(mddev->sysfs_state); if (mddev->sysfs_action) @@ -4620,7 +4619,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) } set_capacity(disk, 0); - mddev->changed = 1; + revalidate_disk(disk); if (mddev->ro) mddev->ro = 0; @@ -4686,7 +4685,6 @@ out: mddev->sync_speed_min = mddev->sync_speed_max = 0; mddev->recovery = 0; mddev->in_sync = 0; - mddev->changed = 0; mddev->degraded = 0; mddev->barriers_work = 0; mddev->safemode = 0; @@ -5850,7 +5848,6 @@ static int md_open(struct block_device *bdev, fmode_t mode) atomic_inc(&mddev->openers); mutex_unlock(&mddev->open_mutex); - check_disk_change(bdev); out: return err; } @@ -5865,21 +5862,6 @@ static int md_release(struct gendisk *disk, fmode_t mode) return 0; } - -static int md_media_changed(struct gendisk *disk) -{ - mddev_t *mddev = disk->private_data; - - return mddev->changed; -} - -static int md_revalidate(struct gendisk *disk) -{ - mddev_t *mddev = disk->private_data; - - mddev->changed = 0; - return 0; -} static const struct block_device_operations md_fops = { .owner = THIS_MODULE, @@ -5890,8 +5872,6 @@ static const struct block_device_operations md_fops = .compat_ioctl = md_compat_ioctl, #endif .getgeo = md_getgeo, - .media_changed = md_media_changed, - .revalidate_disk= md_revalidate, }; static int md_thread(void * arg) diff --git a/drivers/md/md.h b/drivers/md/md.h index e4836c68b73e..3225e25f3c2a 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -237,7 +237,6 @@ struct mddev_s atomic_t active; /* general refcount */ atomic_t openers; /* number of active opens */ - int changed; /* true if we might need to reread partition info */ int degraded; /* whether md should consider * adding a spare */ diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index e277013ac808..eebce166dafe 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -2184,7 +2184,6 @@ static int raid1_resize(mddev_t *mddev, sector_t sectors) if (mddev->array_sectors > raid1_size(mddev, sectors, 0)) return -EINVAL; set_capacity(mddev->gendisk, mddev->array_sectors); - mddev->changed = 1; revalidate_disk(mddev->gendisk); if (sectors > mddev->dev_sectors && mddev->recovery_cp == MaxSector) { diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index c6ae7c194915..231afda1697f 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -5335,7 +5335,6 @@ static int raid5_resize(mddev_t *mddev, sector_t sectors) raid5_size(mddev, sectors, mddev->raid_disks)) return -EINVAL; set_capacity(mddev->gendisk, mddev->array_sectors); - mddev->changed = 1; revalidate_disk(mddev->gendisk); if (sectors > mddev->dev_sectors && mddev->recovery_cp == MaxSector) { mddev->recovery_cp = mddev->dev_sectors; @@ -5549,7 +5548,6 @@ static void raid5_finish_reshape(mddev_t *mddev) if (mddev->delta_disks > 0) { md_set_array_sectors(mddev, raid5_size(mddev, 0, 0)); set_capacity(mddev->gendisk, mddev->array_sectors); - mddev->changed = 1; revalidate_disk(mddev->gendisk); } else { int d; -- cgit v1.2.3 From fe60b0142813002be16dfae28780d9779ee22473 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 29 Mar 2010 11:10:42 +1100 Subject: md: factor do_md_run to separate accesses to ->gendisk As part of relaxing the binding between an mddev and gendisk, we separate do_md_run into two functions. md_run does all the work internal to md do_md_run calls md_run and makes and changes to gendisk that are required. Signed-off-by: NeilBrown --- drivers/md/md.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index f2b30019b1cb..e752332268d2 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4297,11 +4297,10 @@ static void md_safemode_timeout(unsigned long data) static int start_dirty_degraded; -static int do_md_run(mddev_t * mddev) +static int md_run(mddev_t *mddev) { int err; mdk_rdev_t *rdev; - struct gendisk *disk; struct mdk_personality *pers; if (list_empty(&mddev->disks)) @@ -4366,8 +4365,6 @@ static int do_md_run(mddev_t * mddev) sysfs_notify_dirent(rdev->sysfs_state); } - disk = mddev->gendisk; - spin_lock(&pers_lock); pers = find_pers(mddev->level, mddev->clevel); if (!pers || !try_module_get(pers->owner)) { @@ -4495,21 +4492,32 @@ static int do_md_run(mddev_t * mddev) if (mddev->flags) md_update_sb(mddev, 0); - set_capacity(disk, mddev->array_sectors); - md_wakeup_thread(mddev->thread); md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */ - revalidate_disk(mddev->gendisk); md_new_event(mddev); sysfs_notify_dirent(mddev->sysfs_state); if (mddev->sysfs_action) sysfs_notify_dirent(mddev->sysfs_action); sysfs_notify(&mddev->kobj, NULL, "degraded"); - kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE); return 0; } +static int do_md_run(mddev_t *mddev) +{ + int err; + + err = md_run(mddev); + if (err) + goto out; + + set_capacity(mddev->gendisk, mddev->array_sectors); + revalidate_disk(mddev->gendisk); + kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE); +out: + return err; +} + static int restart_array(mddev_t *mddev) { struct gendisk *disk = mddev->gendisk; -- cgit v1.2.3 From 6177b472ab14e1ac88896960370dd54ba577d926 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 29 Mar 2010 11:37:13 +1100 Subject: md: start to refactor do_md_stop do_md_stop is large and clunky, so hard to understand. This is a first step of refactoring, pulling two simple sub-functions out. Signed-off-by: NeilBrown --- drivers/md/md.c | 98 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 55 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index e752332268d2..002d0a34d6ea 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4568,6 +4568,58 @@ void restore_bitmap_write_access(struct file *file) spin_unlock(&inode->i_lock); } +static void md_clean(mddev_t *mddev) +{ + mddev->array_sectors = 0; + mddev->external_size = 0; + mddev->dev_sectors = 0; + mddev->raid_disks = 0; + mddev->recovery_cp = 0; + mddev->resync_min = 0; + mddev->resync_max = MaxSector; + mddev->reshape_position = MaxSector; + mddev->external = 0; + mddev->persistent = 0; + mddev->level = LEVEL_NONE; + mddev->clevel[0] = 0; + mddev->flags = 0; + mddev->ro = 0; + mddev->metadata_type[0] = 0; + mddev->chunk_sectors = 0; + mddev->ctime = mddev->utime = 0; + mddev->layout = 0; + mddev->max_disks = 0; + mddev->events = 0; + mddev->delta_disks = 0; + mddev->new_level = LEVEL_NONE; + mddev->new_layout = 0; + mddev->new_chunk_sectors = 0; + mddev->curr_resync = 0; + mddev->resync_mismatches = 0; + mddev->suspend_lo = mddev->suspend_hi = 0; + mddev->sync_speed_min = mddev->sync_speed_max = 0; + mddev->recovery = 0; + mddev->in_sync = 0; + mddev->degraded = 0; + mddev->barriers_work = 0; + mddev->safemode = 0; + mddev->bitmap_info.offset = 0; + mddev->bitmap_info.default_offset = 0; + mddev->bitmap_info.chunksize = 0; + mddev->bitmap_info.daemon_sleep = 0; + mddev->bitmap_info.max_write_behind = 0; +} + +static void md_stop(mddev_t *mddev) +{ + mddev->pers->stop(mddev); + if (mddev->pers->sync_request && mddev->to_remove == NULL) + mddev->to_remove = &md_redundancy_group; + module_put(mddev->pers->owner); + mddev->pers = NULL; + +} + /* mode: * 0 - completely stop and dis-assemble array * 1 - switch to readonly @@ -4608,14 +4660,11 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) if (mddev->ro) set_disk_ro(disk, 0); - mddev->pers->stop(mddev); + md_stop(mddev); mddev->queue->merge_bvec_fn = NULL; mddev->queue->unplug_fn = NULL; mddev->queue->backing_dev_info.congested_fn = NULL; - module_put(mddev->pers->owner); - if (mddev->pers->sync_request && mddev->to_remove == NULL) - mddev->to_remove = &md_redundancy_group; - mddev->pers = NULL; + /* tell userspace to handle 'inactive' */ sysfs_notify_dirent(mddev->sysfs_state); @@ -4663,44 +4712,7 @@ out: export_array(mddev); - mddev->array_sectors = 0; - mddev->external_size = 0; - mddev->dev_sectors = 0; - mddev->raid_disks = 0; - mddev->recovery_cp = 0; - mddev->resync_min = 0; - mddev->resync_max = MaxSector; - mddev->reshape_position = MaxSector; - mddev->external = 0; - mddev->persistent = 0; - mddev->level = LEVEL_NONE; - mddev->clevel[0] = 0; - mddev->flags = 0; - mddev->ro = 0; - mddev->metadata_type[0] = 0; - mddev->chunk_sectors = 0; - mddev->ctime = mddev->utime = 0; - mddev->layout = 0; - mddev->max_disks = 0; - mddev->events = 0; - mddev->delta_disks = 0; - mddev->new_level = LEVEL_NONE; - mddev->new_layout = 0; - mddev->new_chunk_sectors = 0; - mddev->curr_resync = 0; - mddev->resync_mismatches = 0; - mddev->suspend_lo = mddev->suspend_hi = 0; - mddev->sync_speed_min = mddev->sync_speed_max = 0; - mddev->recovery = 0; - mddev->in_sync = 0; - mddev->degraded = 0; - mddev->barriers_work = 0; - mddev->safemode = 0; - mddev->bitmap_info.offset = 0; - mddev->bitmap_info.default_offset = 0; - mddev->bitmap_info.chunksize = 0; - mddev->bitmap_info.daemon_sleep = 0; - mddev->bitmap_info.max_write_behind = 0; + md_clean(mddev); kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE); if (mddev->hold_active == UNTIL_STOP) mddev->hold_active = 0; -- cgit v1.2.3 From a047e125403112ceb4d41e68307a2e7498ddba4e Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 29 Mar 2010 12:07:53 +1100 Subject: md: factor md_stop_writes out of do_md_stop. Further refactoring of do_md_stop. This one requires some explanation as it takes code from different places in do_md_stop, so some re-ordering happens. We only get into this part of do_md_stop if there are no active opens of the device, so no writes can be happening and the device must have been flushed. In md_stop_writes we want to stop any internal sources of writes - i.e. resync - and flush out the metadata. The only code that was previously before some of this code is code to clean up the queue, the mddev, the gendisk, or sysfs, all of which is probably better after code that makes active changes (i.e. triggers writes). Signed-off-by: NeilBrown --- drivers/md/md.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 002d0a34d6ea..86dfbc361cc0 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4610,6 +4610,27 @@ static void md_clean(mddev_t *mddev) mddev->bitmap_info.max_write_behind = 0; } +static void md_stop_writes(mddev_t *mddev) +{ + if (mddev->sync_thread) { + set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); + set_bit(MD_RECOVERY_INTR, &mddev->recovery); + md_unregister_thread(mddev->sync_thread); + mddev->sync_thread = NULL; + } + + del_timer_sync(&mddev->safemode_timer); + + bitmap_flush(mddev); + md_super_wait(mddev); + + if (!mddev->in_sync || mddev->flags) { + /* mark array as shutdown cleanly */ + mddev->in_sync = 1; + md_update_sb(mddev, 1); + } +} + static void md_stop(mddev_t *mddev) { mddev->pers->stop(mddev); @@ -4637,14 +4658,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) err = -EBUSY; } else if (mddev->pers) { - if (mddev->sync_thread) { - set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); - set_bit(MD_RECOVERY_INTR, &mddev->recovery); - md_unregister_thread(mddev->sync_thread); - mddev->sync_thread = NULL; - } - - del_timer_sync(&mddev->safemode_timer); + md_stop_writes(mddev); switch(mode) { case 1: /* readonly */ @@ -4655,8 +4669,6 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) break; case 0: /* disassemble */ case 2: /* stop */ - bitmap_flush(mddev); - md_super_wait(mddev); if (mddev->ro) set_disk_ro(disk, 0); @@ -4681,11 +4693,6 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) if (mddev->ro) mddev->ro = 0; } - if (!mddev->in_sync || mddev->flags) { - /* mark array as shutdown cleanly */ - mddev->in_sync = 1; - md_update_sb(mddev, 1); - } if (mode == 1) set_disk_ro(disk, 1); clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); -- cgit v1.2.3 From a4bd82d0d03b1485975579f131ccfd0aad6b7d6e Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 29 Mar 2010 13:23:10 +1100 Subject: md: split md_set_readonly out of do_md_stop Using do_md_stop to set an array to read-only is a little confusing. Now most of the common code has been factored out, split md_set_readonly off in to a separate function. Signed-off-by: NeilBrown --- drivers/md/md.c | 90 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 86dfbc361cc0..3a2710a2e104 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3309,6 +3309,7 @@ array_state_show(mddev_t *mddev, char *page) } static int do_md_stop(mddev_t * mddev, int ro, int is_open); +static int md_set_readonly(mddev_t * mddev, int is_open); static int do_md_run(mddev_t * mddev); static int restart_array(mddev_t *mddev); @@ -3339,7 +3340,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) break; /* not supported yet */ case readonly: if (mddev->pers) - err = do_md_stop(mddev, 1, 0); + err = md_set_readonly(mddev, 0); else { mddev->ro = 1; set_disk_ro(mddev->gendisk, 1); @@ -3349,7 +3350,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) case read_auto: if (mddev->pers) { if (mddev->ro == 0) - err = do_md_stop(mddev, 1, 0); + err = md_set_readonly(mddev, 0); else if (mddev->ro == 1) err = restart_array(mddev); if (err == 0) { @@ -4641,9 +4642,34 @@ static void md_stop(mddev_t *mddev) } +static int md_set_readonly(mddev_t *mddev, int is_open) +{ + int err = 0; + mutex_lock(&mddev->open_mutex); + if (atomic_read(&mddev->openers) > is_open) { + printk("md: %s still in use.\n",mdname(mddev)); + err = -EBUSY; + goto out; + } + if (mddev->pers) { + md_stop_writes(mddev); + + err = -ENXIO; + if (mddev->ro==1) + goto out; + mddev->ro = 1; + set_disk_ro(mddev->gendisk, 1); + clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); + sysfs_notify_dirent(mddev->sysfs_state); + err = 0; + } +out: + mutex_unlock(&mddev->open_mutex); + return err; +} + /* mode: * 0 - completely stop and dis-assemble array - * 1 - switch to readonly * 2 - stop but do not disassemble array */ static int do_md_stop(mddev_t * mddev, int mode, int is_open) @@ -4660,45 +4686,33 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) md_stop_writes(mddev); - switch(mode) { - case 1: /* readonly */ - err = -ENXIO; - if (mddev->ro==1) - goto out; - mddev->ro = 1; - break; - case 0: /* disassemble */ - case 2: /* stop */ - if (mddev->ro) - set_disk_ro(disk, 0); + if (mddev->ro) + set_disk_ro(disk, 0); - md_stop(mddev); - mddev->queue->merge_bvec_fn = NULL; - mddev->queue->unplug_fn = NULL; - mddev->queue->backing_dev_info.congested_fn = NULL; + md_stop(mddev); + mddev->queue->merge_bvec_fn = NULL; + mddev->queue->unplug_fn = NULL; + mddev->queue->backing_dev_info.congested_fn = NULL; - /* tell userspace to handle 'inactive' */ - sysfs_notify_dirent(mddev->sysfs_state); + /* tell userspace to handle 'inactive' */ + sysfs_notify_dirent(mddev->sysfs_state); - list_for_each_entry(rdev, &mddev->disks, same_set) - if (rdev->raid_disk >= 0) { - char nm[20]; - sprintf(nm, "rd%d", rdev->raid_disk); - sysfs_remove_link(&mddev->kobj, nm); - } + list_for_each_entry(rdev, &mddev->disks, same_set) + if (rdev->raid_disk >= 0) { + char nm[20]; + sprintf(nm, "rd%d", rdev->raid_disk); + sysfs_remove_link(&mddev->kobj, nm); + } - set_capacity(disk, 0); - revalidate_disk(disk); + set_capacity(disk, 0); + revalidate_disk(disk); - if (mddev->ro) - mddev->ro = 0; - } - if (mode == 1) - set_disk_ro(disk, 1); + if (mddev->ro) + mddev->ro = 0; + clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); err = 0; } -out: mutex_unlock(&mddev->open_mutex); if (err) return err; @@ -4724,9 +4738,7 @@ out: if (mddev->hold_active == UNTIL_STOP) mddev->hold_active = 0; - } else if (mddev->pers) - printk(KERN_INFO "md: %s switched to read-only mode.\n", - mdname(mddev)); + } err = 0; blk_integrity_unregister(disk); md_new_event(mddev); @@ -5724,7 +5736,7 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, goto done_unlock; case STOP_ARRAY_RO: - err = do_md_stop(mddev, 1, 1); + err = md_set_readonly(mddev, 1); goto done_unlock; case BLKROSET: @@ -7140,7 +7152,7 @@ static int md_notify_reboot(struct notifier_block *this, * appears to still be in use. Hence * the '100'. */ - do_md_stop(mddev, 1, 100); + md_set_readonly(mddev, 100); mddev_unlock(mddev); } /* -- cgit v1.2.3 From cca9cf90c504d98644ace52c474770970729f0eb Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 1 Apr 2010 12:08:16 +1100 Subject: md: call md_stop_writes from md_stop This moves the call to the other side of set_readonly, but that should not be an issue. This encapsulates in 'md_stop' all of the functionality for internally stopping the array, leaving all the interactions with externalities (sysfs, request_queue, gendisk) in do_md_stop. Signed-off-by: NeilBrown --- drivers/md/md.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 3a2710a2e104..f48ba419cd7b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -4634,12 +4634,14 @@ static void md_stop_writes(mddev_t *mddev) static void md_stop(mddev_t *mddev) { + md_stop_writes(mddev); + mddev->pers->stop(mddev); if (mddev->pers->sync_request && mddev->to_remove == NULL) mddev->to_remove = &md_redundancy_group; module_put(mddev->pers->owner); mddev->pers = NULL; - + clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); } static int md_set_readonly(mddev_t *mddev, int is_open) @@ -4684,8 +4686,6 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) err = -EBUSY; } else if (mddev->pers) { - md_stop_writes(mddev); - if (mddev->ro) set_disk_ro(disk, 0); @@ -4710,7 +4710,6 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) if (mddev->ro) mddev->ro = 0; - clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); err = 0; } mutex_unlock(&mddev->open_mutex); -- cgit v1.2.3 From 21a52c6d05c15f862797736393915bfa8cd40ee9 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 1 Apr 2010 15:02:13 +1100 Subject: md: pass mddev to make_request functions rather than request_queue We used to pass the personality make_request function direct to the block layer so the first argument had to be a queue. But now we have the intermediary md_make_request so it makes at lot more sense to pass a struct mddev_s. It makes it possible to have an mddev without its own queue too. Signed-off-by: NeilBrown --- drivers/md/faulty.c | 3 +-- drivers/md/linear.c | 7 +++---- drivers/md/md.c | 4 ++-- drivers/md/md.h | 2 +- drivers/md/multipath.c | 3 +-- drivers/md/raid0.c | 7 +++---- drivers/md/raid1.c | 3 +-- drivers/md/raid10.c | 7 +++---- drivers/md/raid5.c | 8 +++----- 9 files changed, 18 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c index 608a8d3736e2..bd4348f6be0b 100644 --- a/drivers/md/faulty.c +++ b/drivers/md/faulty.c @@ -168,9 +168,8 @@ static void add_sector(conf_t *conf, sector_t start, int mode) conf->nfaults = n+1; } -static int make_request(struct request_queue *q, struct bio *bio) +static int make_request(mddev_t *mddev, struct bio *bio) { - mddev_t *mddev = q->queuedata; conf_t *conf = mddev->private; int failit = 0; diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 3048c1704f40..3204a2263f21 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c @@ -286,9 +286,8 @@ static int linear_stop (mddev_t *mddev) return 0; } -static int linear_make_request (struct request_queue *q, struct bio *bio) +static int linear_make_request (mddev_t *mddev, struct bio *bio) { - mddev_t *mddev = q->queuedata; dev_info_t *tmp_dev; sector_t start_sector; @@ -328,9 +327,9 @@ static int linear_make_request (struct request_queue *q, struct bio *bio) bp = bio_split(bio, end_sector - bio->bi_sector); - if (linear_make_request(q, &bp->bio1)) + if (linear_make_request(mddev, &bp->bio1)) generic_make_request(&bp->bio1); - if (linear_make_request(q, &bp->bio2)) + if (linear_make_request(mddev, &bp->bio2)) generic_make_request(&bp->bio2); bio_pair_release(bp); return 0; diff --git a/drivers/md/md.c b/drivers/md/md.c index f48ba419cd7b..2e05b0c2515d 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -240,7 +240,7 @@ static int md_make_request(struct request_queue *q, struct bio *bio) atomic_inc(&mddev->active_io); rcu_read_unlock(); - rv = mddev->pers->make_request(q, bio); + rv = mddev->pers->make_request(mddev, bio); cpu = part_stat_lock(); part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); @@ -354,7 +354,7 @@ static void md_submit_barrier(struct work_struct *ws) bio_endio(bio, 0); else { bio->bi_rw &= ~(1<pers->make_request(mddev->queue, bio)) + if (mddev->pers->make_request(mddev, bio)) generic_make_request(bio); mddev->barrier = POST_REQUEST_BARRIER; submit_barriers(mddev); diff --git a/drivers/md/md.h b/drivers/md/md.h index 3225e25f3c2a..a536f5458097 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -330,7 +330,7 @@ struct mdk_personality int level; struct list_head list; struct module *owner; - int (*make_request)(struct request_queue *q, struct bio *bio); + int (*make_request)(mddev_t *mddev, struct bio *bio); int (*run)(mddev_t *mddev); int (*stop)(mddev_t *mddev); void (*status)(struct seq_file *seq, mddev_t *mddev); diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 5b4e2918663a..50bf8e6f8c7b 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -135,9 +135,8 @@ static void multipath_unplug(struct request_queue *q) } -static int multipath_make_request (struct request_queue *q, struct bio * bio) +static int multipath_make_request(mddev_t *mddev, struct bio * bio) { - mddev_t *mddev = q->queuedata; multipath_conf_t *conf = mddev->private; struct multipath_bh * mp_bh; struct multipath_info *multipath; diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index d535f9be39f4..9f9c6b76ca7c 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -465,9 +465,8 @@ static inline int is_io_in_chunk_boundary(mddev_t *mddev, } } -static int raid0_make_request(struct request_queue *q, struct bio *bio) +static int raid0_make_request(mddev_t *mddev, struct bio *bio) { - mddev_t *mddev = q->queuedata; unsigned int chunk_sects; sector_t sector_offset; struct strip_zone *zone; @@ -495,9 +494,9 @@ static int raid0_make_request(struct request_queue *q, struct bio *bio) else bp = bio_split(bio, chunk_sects - sector_div(sector, chunk_sects)); - if (raid0_make_request(q, &bp->bio1)) + if (raid0_make_request(mddev, &bp->bio1)) generic_make_request(&bp->bio1); - if (raid0_make_request(q, &bp->bio2)) + if (raid0_make_request(mddev, &bp->bio2)) generic_make_request(&bp->bio2); bio_pair_release(bp); diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index eebce166dafe..5ff75c4d3af6 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -773,9 +773,8 @@ do_sync_io: return NULL; } -static int make_request(struct request_queue *q, struct bio * bio) +static int make_request(mddev_t *mddev, struct bio * bio) { - mddev_t *mddev = q->queuedata; conf_t *conf = mddev->private; mirror_info_t *mirror; r1bio_t *r1_bio; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index ca313d646fd1..a1d727610a49 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -788,9 +788,8 @@ static void unfreeze_array(conf_t *conf) spin_unlock_irq(&conf->resync_lock); } -static int make_request(struct request_queue *q, struct bio * bio) +static int make_request(mddev_t *mddev, struct bio * bio) { - mddev_t *mddev = q->queuedata; conf_t *conf = mddev->private; mirror_info_t *mirror; r10bio_t *r10_bio; @@ -824,9 +823,9 @@ static int make_request(struct request_queue *q, struct bio * bio) */ bp = bio_split(bio, chunk_sects - (bio->bi_sector & (chunk_sects - 1)) ); - if (make_request(q, &bp->bio1)) + if (make_request(mddev, &bp->bio1)) generic_make_request(&bp->bio1); - if (make_request(q, &bp->bio2)) + if (make_request(mddev, &bp->bio2)) generic_make_request(&bp->bio2); bio_pair_release(bp); diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 231afda1697f..2882a26646fd 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3753,9 +3753,8 @@ static int bio_fits_rdev(struct bio *bi) } -static int chunk_aligned_read(struct request_queue *q, struct bio * raid_bio) +static int chunk_aligned_read(mddev_t *mddev, struct bio * raid_bio) { - mddev_t *mddev = q->queuedata; raid5_conf_t *conf = mddev->private; int dd_idx; struct bio* align_bi; @@ -3870,9 +3869,8 @@ static struct stripe_head *__get_priority_stripe(raid5_conf_t *conf) return sh; } -static int make_request(struct request_queue *q, struct bio * bi) +static int make_request(mddev_t *mddev, struct bio * bi) { - mddev_t *mddev = q->queuedata; raid5_conf_t *conf = mddev->private; int dd_idx; sector_t new_sector; @@ -3896,7 +3894,7 @@ static int make_request(struct request_queue *q, struct bio * bi) if (rw == READ && mddev->reshape_position == MaxSector && - chunk_aligned_read(q,bi)) + chunk_aligned_read(mddev,bi)) return 0; logical_sector = bi->bi_sector & ~((sector_t)STRIPE_SECTORS-1); -- cgit v1.2.3 From fafd7fb052182e087b5a3c6c408e4ac8c2b5fa14 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 1 Apr 2010 15:55:30 +1100 Subject: md: factor out init code for an mddev This is a simple factorisation that makes mddev_find easier to read. Signed-off-by: NeilBrown --- drivers/md/md.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 2e05b0c2515d..d3579fc9efed 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -416,6 +416,27 @@ static void mddev_put(mddev_t *mddev) spin_unlock(&all_mddevs_lock); } +static void mddev_init(mddev_t *mddev) +{ + mutex_init(&mddev->open_mutex); + mutex_init(&mddev->reconfig_mutex); + mutex_init(&mddev->bitmap_info.mutex); + INIT_LIST_HEAD(&mddev->disks); + INIT_LIST_HEAD(&mddev->all_mddevs); + init_timer(&mddev->safemode_timer); + atomic_set(&mddev->active, 1); + atomic_set(&mddev->openers, 0); + atomic_set(&mddev->active_io, 0); + spin_lock_init(&mddev->write_lock); + atomic_set(&mddev->flush_pending, 0); + init_waitqueue_head(&mddev->sb_wait); + init_waitqueue_head(&mddev->recovery_wait); + mddev->reshape_position = MaxSector; + mddev->resync_min = 0; + mddev->resync_max = MaxSector; + mddev->level = LEVEL_NONE; +} + static mddev_t * mddev_find(dev_t unit) { mddev_t *mddev, *new = NULL; @@ -482,23 +503,7 @@ static mddev_t * mddev_find(dev_t unit) else new->md_minor = MINOR(unit) >> MdpMinorShift; - mutex_init(&new->open_mutex); - mutex_init(&new->reconfig_mutex); - mutex_init(&new->bitmap_info.mutex); - INIT_LIST_HEAD(&new->disks); - INIT_LIST_HEAD(&new->all_mddevs); - init_timer(&new->safemode_timer); - atomic_set(&new->active, 1); - atomic_set(&new->openers, 0); - atomic_set(&new->active_io, 0); - spin_lock_init(&new->write_lock); - atomic_set(&new->flush_pending, 0); - init_waitqueue_head(&new->sb_wait); - init_waitqueue_head(&new->recovery_wait); - new->reshape_position = MaxSector; - new->resync_min = 0; - new->resync_max = MaxSector; - new->level = LEVEL_NONE; + mddev_init(new); goto retry; } -- cgit v1.2.3 From 9e35b99c7efacfddc748c89a0c53b1122b0ee72c Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 6 Apr 2010 14:23:02 +1000 Subject: md: don't unregister the thread in mddev_suspend This is - unnecessary because mddev_suspend is always followed by a call to ->stop, and each ->stop unregisters the thread, and - a problem as it makes it awkwards to suspend and then resume a device as we will want later. Signed-off-by: NeilBrown --- drivers/md/md.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index d3579fc9efed..af0780ae56b5 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -254,6 +254,12 @@ static int md_make_request(struct request_queue *q, struct bio *bio) return rv; } +/* mddev_suspend makes sure no new requests are submitted + * to the device, and that any requests that have been submitted + * are completely handled. + * Once ->stop is called and completes, the module will be completely + * unused. + */ static void mddev_suspend(mddev_t *mddev) { BUG_ON(mddev->suspended); @@ -261,13 +267,6 @@ static void mddev_suspend(mddev_t *mddev) synchronize_rcu(); wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0); mddev->pers->quiesce(mddev, 1); - md_unregister_thread(mddev->thread); - mddev->thread = NULL; - /* we now know that no code is executing in the personality module, - * except possibly the tail end of a ->bi_end_io function, but that - * is certain to complete before the module has a chance to get - * unloaded - */ } static void mddev_resume(mddev_t *mddev) -- cgit v1.2.3 From d754c5ae1ff76b20d3ecde8ad666d7865eada8ae Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 7 Apr 2010 12:14:43 +1000 Subject: md/raid1: fix confusing 'redirect sector' message. This message seems to suggest the named device is the one on which a read failed, however it is actually the device that the read will be redirected to. So make the message a little clearer. Reported-by: Tim Burgess Signed-off-by: NeilBrown --- drivers/md/raid1.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 5ff75c4d3af6..2e08e48b02d9 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1689,10 +1689,10 @@ static void raid1d(mddev_t *mddev) r1_bio->bios[r1_bio->read_disk] = bio; rdev = conf->mirrors[disk].rdev; if (printk_ratelimit()) - printk(KERN_ERR "raid1: %s: redirecting sector %llu to" - " another mirror\n", - bdevname(rdev->bdev,b), - (unsigned long long)r1_bio->sector); + printk(KERN_ERR "raid1: redirecting sector %llu to" + " other mirror: %s\n", + (unsigned long long)r1_bio->sector, + bdevname(rdev->bdev,b)); bio->bi_sector = r1_bio->sector + rdev->data_offset; bio->bi_bdev = rdev->bdev; bio->bi_end_io = raid1_end_read_request; -- cgit v1.2.3 From e555190d82c0f58e825e3cbd9e6ebe2e7ac713bd Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 31 Mar 2010 11:21:44 +1100 Subject: md/raid1: delay reads that could overtake behind-writes. When a raid1 array is configured to support write-behind on some devices, it normally only reads from other devices. If all devices are write-behind (because the rest have failed) it is possible for a read request to be serviced before a behind-write request, which would appear as data corruption. So when forced to read from a WriteMostly device, wait for any write-behind to complete, and don't start any more behind-writes. Signed-off-by: NeilBrown --- drivers/md/bitmap.c | 4 +++- drivers/md/bitmap.h | 1 + drivers/md/raid1.c | 25 ++++++++++++++++++------- 3 files changed, 22 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 49d6080387c8..c9c6a345e17b 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -1356,7 +1356,8 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto { if (!bitmap) return; if (behind) { - atomic_dec(&bitmap->behind_writes); + if (atomic_dec_and_test(&bitmap->behind_writes)) + wake_up(&bitmap->behind_wait); PRINTK(KERN_DEBUG "dec write-behind count %d/%d\n", atomic_read(&bitmap->behind_writes), bitmap->max_write_behind); } @@ -1680,6 +1681,7 @@ int bitmap_create(mddev_t *mddev) atomic_set(&bitmap->pending_writes, 0); init_waitqueue_head(&bitmap->write_wait); init_waitqueue_head(&bitmap->overflow_wait); + init_waitqueue_head(&bitmap->behind_wait); bitmap->mddev = mddev; diff --git a/drivers/md/bitmap.h b/drivers/md/bitmap.h index aa82b7caa85f..3797dea4723a 100644 --- a/drivers/md/bitmap.h +++ b/drivers/md/bitmap.h @@ -240,6 +240,7 @@ struct bitmap { atomic_t pending_writes; /* pending writes to the bitmap file */ wait_queue_head_t write_wait; wait_queue_head_t overflow_wait; + wait_queue_head_t behind_wait; struct sysfs_dirent *sysfs_can_clear; }; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 2e08e48b02d9..cb2da87ad593 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -857,6 +857,15 @@ static int make_request(mddev_t *mddev, struct bio * bio) } mirror = conf->mirrors + rdisk; + if (test_bit(WriteMostly, &mirror->rdev->flags) && + bitmap) { + /* Reading from a write-mostly device must + * take care not to over-take any writes + * that are 'behind' + */ + wait_event(bitmap->behind_wait, + atomic_read(&bitmap->behind_writes) == 0); + } r1_bio->read_disk = rdisk; read_bio = bio_clone(bio, GFP_NOIO); @@ -934,10 +943,14 @@ static int make_request(mddev_t *mddev, struct bio * bio) set_bit(R1BIO_Degraded, &r1_bio->state); } - /* do behind I/O ? */ + /* do behind I/O ? + * Not if there are too many, or cannot allocate memory, + * or a reader on WriteMostly is waiting for behind writes + * to flush */ if (bitmap && (atomic_read(&bitmap->behind_writes) < mddev->bitmap_info.max_write_behind) && + !waitqueue_active(&bitmap->behind_wait) && (behind_pages = alloc_behind_pages(bio)) != NULL) set_bit(R1BIO_BehindIO, &r1_bio->state); @@ -2144,15 +2157,13 @@ static int stop(mddev_t *mddev) { conf_t *conf = mddev->private; struct bitmap *bitmap = mddev->bitmap; - int behind_wait = 0; /* wait for behind writes to complete */ - while (bitmap && atomic_read(&bitmap->behind_writes) > 0) { - behind_wait++; - printk(KERN_INFO "raid1: behind writes in progress on device %s, waiting to stop (%d)\n", mdname(mddev), behind_wait); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ); /* wait a second */ + if (bitmap && atomic_read(&bitmap->behind_writes) > 0) { + printk(KERN_INFO "raid1: behind writes in progress on device %s, waiting to stop.\n", mdname(mddev)); /* need to kick something here to make sure I/O goes? */ + wait_event(bitmap->behind_wait, + atomic_read(&bitmap->behind_writes) == 0); } raise_barrier(conf); -- cgit v1.2.3 From f1b29bcae116409db5e543622aadab43041c9ae9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 1 May 2010 18:09:05 -0700 Subject: md/raid4: permit raid0 takeover For consistency allow raid4 to takeover raid0 in addition to raid5 (with a raid4 layout). Signed-off-by: Dan Williams --- drivers/md/raid5.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 2882a26646fd..81563b7c0357 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -5610,10 +5610,17 @@ static void raid5_quiesce(mddev_t *mddev, int state) } -static void *raid5_takeover_raid0(mddev_t *mddev) +static void *raid45_takeover_raid0(mddev_t *mddev, int level) { + struct raid0_private_data *raid0_priv = mddev->private; - mddev->new_level = 5; + /* for raid0 takeover only one zone is supported */ + if (raid0_priv->nr_strip_zones > 1) { + printk(KERN_ERR "md: cannot takeover raid0 with more than one zone.\n"); + return ERR_PTR(-EINVAL); + } + + mddev->new_level = level; mddev->new_layout = ALGORITHM_PARITY_N; mddev->new_chunk_sectors = mddev->chunk_sectors; mddev->raid_disks += 1; @@ -5749,22 +5756,13 @@ static int raid6_check_reshape(mddev_t *mddev) static void *raid5_takeover(mddev_t *mddev) { /* raid5 can take over: - * raid0 - if all devices are the same - make it a raid4 layout + * raid0 - if there is only one strip zone - make it a raid4 layout * raid1 - if there are two drives. We need to know the chunk size * raid4 - trivial - just use a raid4 layout. * raid6 - Providing it is a *_6 layout */ - if (mddev->level == 0) { - /* for raid0 takeover only one zone is supported */ - struct raid0_private_data *raid0_priv - = mddev->private; - if (raid0_priv->nr_strip_zones > 1) { - printk(KERN_ERR "md: cannot takeover raid 0 with more than one zone.\n"); - return ERR_PTR(-EINVAL); - } - return raid5_takeover_raid0(mddev); - } - + if (mddev->level == 0) + return raid45_takeover_raid0(mddev, 5); if (mddev->level == 1) return raid5_takeover_raid1(mddev); if (mddev->level == 4) { @@ -5780,8 +5778,12 @@ static void *raid5_takeover(mddev_t *mddev) static void *raid4_takeover(mddev_t *mddev) { - /* raid4 can take over raid5 if layout is right. + /* raid4 can take over: + * raid0 - if there is only one strip zone + * raid5 - if layout is right */ + if (mddev->level == 0) + return raid45_takeover_raid0(mddev, 4); if (mddev->level == 5 && mddev->layout == ALGORITHM_PARITY_N) { mddev->new_layout = 0; -- cgit v1.2.3 From bb7f8d2217d8753ab5008c78f16697d9e697d570 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 1 May 2010 18:14:57 -0700 Subject: md: notify mdstat waiters of level change Level modifications change the output of mdstat. The mdmon manager thread is interested in these events for external metadata management. Signed-off-by: Dan Williams --- drivers/md/md.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index af0780ae56b5..69f659e46aa6 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3075,6 +3075,7 @@ level_store(mddev_t *mddev, const char *buf, size_t len) set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); md_wakeup_thread(mddev->thread); sysfs_notify(&mddev->kobj, NULL, "level"); + md_new_event(mddev); return rv; } -- cgit v1.2.3 From f2859af6716ce99cac7f35c5a0c6b7fed346312f Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 2 May 2010 10:04:16 -0700 Subject: md: allow integers to be passed to md/level e.g. allow md to interpret 'echo 4 > md/level' as a request for raid4. Signed-off-by: Dan Williams --- drivers/md/md.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 69f659e46aa6..b8a0fcfb1de1 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2934,9 +2934,10 @@ level_show(mddev_t *mddev, char *page) static ssize_t level_store(mddev_t *mddev, const char *buf, size_t len) { - char level[16]; + char clevel[16]; ssize_t rv = len; struct mdk_personality *pers; + long level; void *priv; mdk_rdev_t *rdev; @@ -2969,19 +2970,22 @@ level_store(mddev_t *mddev, const char *buf, size_t len) } /* Now find the new personality */ - if (len == 0 || len >= sizeof(level)) + if (len == 0 || len >= sizeof(clevel)) return -EINVAL; - strncpy(level, buf, len); - if (level[len-1] == '\n') + strncpy(clevel, buf, len); + if (clevel[len-1] == '\n') len--; - level[len] = 0; + clevel[len] = 0; + if (strict_strtol(clevel, 10, &level)) + level = LEVEL_NONE; - request_module("md-%s", level); + if (request_module("md-%s", clevel) != 0) + request_module("md-level-%s", clevel); spin_lock(&pers_lock); - pers = find_pers(LEVEL_NONE, level); + pers = find_pers(level, clevel); if (!pers || !try_module_get(pers->owner)) { spin_unlock(&pers_lock); - printk(KERN_WARNING "md: personality %s not loaded\n", level); + printk(KERN_WARNING "md: personality %s not loaded\n", clevel); return -EINVAL; } spin_unlock(&pers_lock); @@ -2994,7 +2998,7 @@ level_store(mddev_t *mddev, const char *buf, size_t len) if (!pers->takeover) { module_put(pers->owner); printk(KERN_WARNING "md: %s: %s does not support personality takeover\n", - mdname(mddev), level); + mdname(mddev), clevel); return -EINVAL; } @@ -3010,7 +3014,7 @@ level_store(mddev_t *mddev, const char *buf, size_t len) mddev->delta_disks = 0; module_put(pers->owner); printk(KERN_WARNING "md: %s: %s would not accept array\n", - mdname(mddev), level); + mdname(mddev), clevel); return PTR_ERR(priv); } -- cgit v1.2.3 From 08fb730ca346ff16598ef31911c88fbca6133bf5 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 3 May 2010 13:16:56 +1000 Subject: md: remove EXPERIMENTAL designation from RAID10 RAID10 has been available for quite a while now and is quite well tested, so we can remove the EXPERIMENTAL designation. Reported-by: Eric MSP Veith Signed-off-by: NeilBrown --- drivers/md/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index acb3a4e404ff..4a6feac8c94a 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig @@ -100,8 +100,8 @@ config MD_RAID1 If unsure, say Y. config MD_RAID10 - tristate "RAID-10 (mirrored striping) mode (EXPERIMENTAL)" - depends on BLK_DEV_MD && EXPERIMENTAL + tristate "RAID-10 (mirrored striping) mode" + depends on BLK_DEV_MD ---help--- RAID-10 provides a combination of striping (RAID-0) and mirroring (RAID-1) with easier configuration and more flexible -- cgit v1.2.3 From 0c55e02259115c151e4835dd417cf41467bb02e2 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 3 May 2010 14:09:02 +1000 Subject: md/raid5: improve consistency of error messages. Many 'printk' messages from the raid456 module mention 'raid5' even though it may be a 'raid6' or even 'raid4' array. This can cause confusion. Also the actual array name is not always reported and when it is it is not reported consistently. So change all the messages to start: md/raid:%s: where '%s' becomes e.g. md3 to identify the particular array. Signed-off-by: NeilBrown --- drivers/md/raid5.c | 149 +++++++++++++++++++++++++---------------------------- 1 file changed, 69 insertions(+), 80 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 81563b7c0357..cee9f93b35c4 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -1509,7 +1509,7 @@ static void raid5_end_read_request(struct bio * bi, int error) set_bit(R5_UPTODATE, &sh->dev[i].flags); if (test_bit(R5_ReadError, &sh->dev[i].flags)) { rdev = conf->disks[i].rdev; - printk_rl(KERN_INFO "raid5:%s: read error corrected" + printk_rl(KERN_INFO "md/raid:%s: read error corrected" " (%lu sectors at %llu on %s)\n", mdname(conf->mddev), STRIPE_SECTORS, (unsigned long long)(sh->sector @@ -1529,7 +1529,7 @@ static void raid5_end_read_request(struct bio * bi, int error) atomic_inc(&rdev->read_errors); if (conf->mddev->degraded) printk_rl(KERN_WARNING - "raid5:%s: read error not correctable " + "md/raid:%s: read error not correctable " "(sector %llu on %s).\n", mdname(conf->mddev), (unsigned long long)(sh->sector @@ -1538,7 +1538,7 @@ static void raid5_end_read_request(struct bio * bi, int error) else if (test_bit(R5_ReWrite, &sh->dev[i].flags)) /* Oh, no!!! */ printk_rl(KERN_WARNING - "raid5:%s: read error NOT corrected!! " + "md/raid:%s: read error NOT corrected!! " "(sector %llu on %s).\n", mdname(conf->mddev), (unsigned long long)(sh->sector @@ -1547,7 +1547,7 @@ static void raid5_end_read_request(struct bio * bi, int error) else if (atomic_read(&rdev->read_errors) > conf->max_nr_stripes) printk(KERN_WARNING - "raid5:%s: Too many read errors, failing device %s.\n", + "md/raid:%s: Too many read errors, failing device %s.\n", mdname(conf->mddev), bdn); else retry = 1; @@ -1620,7 +1620,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) { char b[BDEVNAME_SIZE]; raid5_conf_t *conf = mddev->private; - pr_debug("raid5: error called\n"); + pr_debug("raid456: error called\n"); if (!test_bit(Faulty, &rdev->flags)) { set_bit(MD_CHANGE_DEVS, &mddev->flags); @@ -1636,9 +1636,13 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) } set_bit(Faulty, &rdev->flags); printk(KERN_ALERT - "raid5: Disk failure on %s, disabling device.\n" - "raid5: Operation continuing on %d devices.\n", - bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded); + "md/raid:%s: Disk failure on %s, disabling device.\n" + KERN_ALERT + "md/raid:%s: Operation continuing on %d devices.\n", + mdname(mddev), + bdevname(rdev->bdev, b), + mdname(mddev), + conf->raid_disks - mddev->degraded); } } @@ -1719,8 +1723,6 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, pd_idx = data_disks; break; default: - printk(KERN_ERR "raid5: unsupported algorithm %d\n", - algorithm); BUG(); } break; @@ -1836,10 +1838,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, qd_idx = raid_disks - 1; break; - default: - printk(KERN_CRIT "raid6: unsupported algorithm %d\n", - algorithm); BUG(); } break; @@ -1902,8 +1901,6 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous) case ALGORITHM_PARITY_N: break; default: - printk(KERN_ERR "raid5: unsupported algorithm %d\n", - algorithm); BUG(); } break; @@ -1962,8 +1959,6 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous) i -= 1; break; default: - printk(KERN_CRIT "raid6: unsupported algorithm %d\n", - algorithm); BUG(); } break; @@ -1976,7 +1971,8 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous) previous, &dummy1, &sh2); if (check != sh->sector || dummy1 != dd_idx || sh2.pd_idx != sh->pd_idx || sh2.qd_idx != sh->qd_idx) { - printk(KERN_ERR "compute_blocknr: map not correct\n"); + printk(KERN_ERR "md/raid:%s: compute_blocknr: map not correct\n", + mdname(conf->mddev)); return 0; } return r_sector; @@ -3942,7 +3938,7 @@ static int make_request(mddev_t *mddev, struct bio * bi) new_sector = raid5_compute_sector(conf, logical_sector, previous, &dd_idx, NULL); - pr_debug("raid5: make_request, sector %llu logical %llu\n", + pr_debug("raid456: make_request, sector %llu logical %llu\n", (unsigned long long)new_sector, (unsigned long long)logical_sector); @@ -4721,7 +4717,7 @@ static raid5_conf_t *setup_conf(mddev_t *mddev) if (mddev->new_level != 5 && mddev->new_level != 4 && mddev->new_level != 6) { - printk(KERN_ERR "raid5: %s: raid level not set to 4/5/6 (%d)\n", + printk(KERN_ERR "md/raid:%s: raid level not set to 4/5/6 (%d)\n", mdname(mddev), mddev->new_level); return ERR_PTR(-EIO); } @@ -4729,12 +4725,12 @@ static raid5_conf_t *setup_conf(mddev_t *mddev) && !algorithm_valid_raid5(mddev->new_layout)) || (mddev->new_level == 6 && !algorithm_valid_raid6(mddev->new_layout))) { - printk(KERN_ERR "raid5: %s: layout %d not supported\n", + printk(KERN_ERR "md/raid:%s: layout %d not supported\n", mdname(mddev), mddev->new_layout); return ERR_PTR(-EIO); } if (mddev->new_level == 6 && mddev->raid_disks < 4) { - printk(KERN_ERR "raid6: not enough configured devices for %s (%d, minimum 4)\n", + printk(KERN_ERR "md/raid:%s: not enough configured devices (%d, minimum 4)\n", mdname(mddev), mddev->raid_disks); return ERR_PTR(-EINVAL); } @@ -4742,8 +4738,8 @@ static raid5_conf_t *setup_conf(mddev_t *mddev) if (!mddev->new_chunk_sectors || (mddev->new_chunk_sectors << 9) % PAGE_SIZE || !is_power_of_2(mddev->new_chunk_sectors)) { - printk(KERN_ERR "raid5: invalid chunk size %d for %s\n", - mddev->new_chunk_sectors << 9, mdname(mddev)); + printk(KERN_ERR "md/raid:%s: invalid chunk size %d\n", + mdname(mddev), mddev->new_chunk_sectors << 9); return ERR_PTR(-EINVAL); } @@ -4785,7 +4781,7 @@ static raid5_conf_t *setup_conf(mddev_t *mddev) if (raid5_alloc_percpu(conf) != 0) goto abort; - pr_debug("raid5: run(%s) called.\n", mdname(mddev)); + pr_debug("raid456: run(%s) called.\n", mdname(mddev)); list_for_each_entry(rdev, &mddev->disks, same_set) { raid_disk = rdev->raid_disk; @@ -4798,9 +4794,9 @@ static raid5_conf_t *setup_conf(mddev_t *mddev) if (test_bit(In_sync, &rdev->flags)) { char b[BDEVNAME_SIZE]; - printk(KERN_INFO "raid5: device %s operational as raid" - " disk %d\n", bdevname(rdev->bdev,b), - raid_disk); + printk(KERN_INFO "md/raid:%s: device %s operational as raid" + " disk %d\n", + mdname(mddev), bdevname(rdev->bdev, b), raid_disk); } else /* Cannot rely on bitmap to complete recovery */ conf->fullsync = 1; @@ -4824,16 +4820,17 @@ static raid5_conf_t *setup_conf(mddev_t *mddev) max_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024; if (grow_stripes(conf, conf->max_nr_stripes)) { printk(KERN_ERR - "raid5: couldn't allocate %dkB for buffers\n", memory); + "md/raid:%s: couldn't allocate %dkB for buffers\n", + mdname(mddev), memory); goto abort; } else - printk(KERN_INFO "raid5: allocated %dkB for %s\n", - memory, mdname(mddev)); + printk(KERN_INFO "md/raid:%s: allocated %dkB\n", + mdname(mddev), memory); conf->thread = md_register_thread(raid5d, mddev, NULL); if (!conf->thread) { printk(KERN_ERR - "raid5: couldn't allocate thread for %s\n", + "md/raid:%s: couldn't allocate thread.\n", mdname(mddev)); goto abort; } @@ -4884,7 +4881,7 @@ static int run(mddev_t *mddev) sector_t reshape_offset = 0; if (mddev->recovery_cp != MaxSector) - printk(KERN_NOTICE "raid5: %s is not clean" + printk(KERN_NOTICE "md/raid:%s: not clean" " -- starting background reconstruction\n", mdname(mddev)); if (mddev->reshape_position != MaxSector) { @@ -4898,7 +4895,7 @@ static int run(mddev_t *mddev) int max_degraded = (mddev->level == 6 ? 2 : 1); if (mddev->new_level != mddev->level) { - printk(KERN_ERR "raid5: %s: unsupported reshape " + printk(KERN_ERR "md/raid:%s: unsupported reshape " "required - aborting.\n", mdname(mddev)); return -EINVAL; @@ -4911,8 +4908,8 @@ static int run(mddev_t *mddev) here_new = mddev->reshape_position; if (sector_div(here_new, mddev->new_chunk_sectors * (mddev->raid_disks - max_degraded))) { - printk(KERN_ERR "raid5: reshape_position not " - "on a stripe boundary\n"); + printk(KERN_ERR "md/raid:%s: reshape_position not " + "on a stripe boundary\n", mdname(mddev)); return -EINVAL; } reshape_offset = here_new * mddev->new_chunk_sectors; @@ -4933,8 +4930,9 @@ static int run(mddev_t *mddev) if ((here_new * mddev->new_chunk_sectors != here_old * mddev->chunk_sectors) || mddev->ro == 0) { - printk(KERN_ERR "raid5: in-place reshape must be started" - " in read-only mode - aborting\n"); + printk(KERN_ERR "md/raid:%s: in-place reshape must be started" + " in read-only mode - aborting\n", + mdname(mddev)); return -EINVAL; } } else if (mddev->delta_disks < 0 @@ -4943,11 +4941,13 @@ static int run(mddev_t *mddev) : (here_new * mddev->new_chunk_sectors >= here_old * mddev->chunk_sectors)) { /* Reading from the same stripe as writing to - bad */ - printk(KERN_ERR "raid5: reshape_position too early for " - "auto-recovery - aborting.\n"); + printk(KERN_ERR "md/raid:%s: reshape_position too early for " + "auto-recovery - aborting.\n", + mdname(mddev)); return -EINVAL; } - printk(KERN_INFO "raid5: reshape will continue\n"); + printk(KERN_INFO "md/raid:%s: reshape will continue\n", + mdname(mddev)); /* OK, we should be able to continue; */ } else { BUG_ON(mddev->level != mddev->new_level); @@ -4989,18 +4989,6 @@ static int run(mddev_t *mddev) mddev->minor_version > 90) rdev->recovery_offset = reshape_offset; - printk("%d: w=%d pa=%d pr=%d m=%d a=%d r=%d op1=%d op2=%d\n", - rdev->raid_disk, working_disks, conf->prev_algo, - conf->previous_raid_disks, conf->max_degraded, - conf->algorithm, conf->raid_disks, - only_parity(rdev->raid_disk, - conf->prev_algo, - conf->previous_raid_disks, - conf->max_degraded), - only_parity(rdev->raid_disk, - conf->algorithm, - conf->raid_disks, - conf->max_degraded)); if (rdev->recovery_offset < reshape_offset) { /* We need to check old and new layout */ if (!only_parity(rdev->raid_disk, @@ -5021,7 +5009,7 @@ static int run(mddev_t *mddev) - working_disks); if (mddev->degraded > conf->max_degraded) { - printk(KERN_ERR "raid5: not enough operational devices for %s" + printk(KERN_ERR "md/raid:%s: not enough operational devices" " (%d/%d failed)\n", mdname(mddev), mddev->degraded, conf->raid_disks); goto abort; @@ -5035,32 +5023,32 @@ static int run(mddev_t *mddev) mddev->recovery_cp != MaxSector) { if (mddev->ok_start_degraded) printk(KERN_WARNING - "raid5: starting dirty degraded array: %s" - "- data corruption possible.\n", + "md/raid:%s: starting dirty degraded array" + " - data corruption possible.\n", mdname(mddev)); else { printk(KERN_ERR - "raid5: cannot start dirty degraded array for %s\n", + "md/raid:%s: cannot start dirty degraded array.\n", mdname(mddev)); goto abort; } } if (mddev->degraded == 0) - printk("raid5: raid level %d set %s active with %d out of %d" - " devices, algorithm %d\n", conf->level, mdname(mddev), + printk(KERN_INFO "md/raid:%s: raid level %d active with %d out of %d" + " devices, algorithm %d\n", mdname(mddev), conf->level, mddev->raid_disks-mddev->degraded, mddev->raid_disks, mddev->new_layout); else - printk(KERN_ALERT "raid5: raid level %d set %s active with %d" - " out of %d devices, algorithm %d\n", conf->level, - mdname(mddev), mddev->raid_disks - mddev->degraded, - mddev->raid_disks, mddev->new_layout); + printk(KERN_ALERT "md/raid:%s: raid level %d active with %d" + " out of %d devices, algorithm %d\n", + mdname(mddev), conf->level, + mddev->raid_disks - mddev->degraded, + mddev->raid_disks, mddev->new_layout); print_raid5_conf(conf); if (conf->reshape_progress != MaxSector) { - printk("...ok start reshape thread\n"); conf->reshape_safe = conf->reshape_progress; atomic_set(&conf->reshape_stripes, 0); clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); @@ -5087,7 +5075,7 @@ static int run(mddev_t *mddev) mddev->to_remove = NULL; else if (sysfs_create_group(&mddev->kobj, &raid5_attrs_group)) printk(KERN_WARNING - "raid5: failed to create sysfs attributes for %s\n", + "md/raid:%s: failed to create sysfs attributes.\n", mdname(mddev)); mddev->queue->queue_lock = &conf->device_lock; @@ -5117,12 +5105,10 @@ abort: free_conf(conf); } mddev->private = NULL; - printk(KERN_ALERT "raid5: failed to run raid set %s\n", mdname(mddev)); + printk(KERN_ALERT "md/raid:%s: failed to run raid set.\n", mdname(mddev)); return -EIO; } - - static int stop(mddev_t *mddev) { raid5_conf_t *conf = mddev->private; @@ -5196,21 +5182,22 @@ static void print_raid5_conf (raid5_conf_t *conf) int i; struct disk_info *tmp; - printk("RAID5 conf printout:\n"); + printk(KERN_DEBUG "RAID conf printout:\n"); if (!conf) { printk("(conf==NULL)\n"); return; } - printk(" --- rd:%d wd:%d\n", conf->raid_disks, - conf->raid_disks - conf->mddev->degraded); + printk(KERN_DEBUG " --- level:%d rd:%d wd:%d\n", conf->level, + conf->raid_disks, + conf->raid_disks - conf->mddev->degraded); for (i = 0; i < conf->raid_disks; i++) { char b[BDEVNAME_SIZE]; tmp = conf->disks + i; if (tmp->rdev) - printk(" disk %d, o:%d, dev:%s\n", - i, !test_bit(Faulty, &tmp->rdev->flags), - bdevname(tmp->rdev->bdev,b)); + printk(KERN_DEBUG " disk %d, o:%d, dev:%s\n", + i, !test_bit(Faulty, &tmp->rdev->flags), + bdevname(tmp->rdev->bdev, b)); } } @@ -5358,7 +5345,8 @@ static int check_stripe_cache(mddev_t *mddev) > conf->max_nr_stripes || ((mddev->new_chunk_sectors << 9) / STRIPE_SIZE) * 4 > conf->max_nr_stripes) { - printk(KERN_WARNING "raid5: reshape: not enough stripes. Needed %lu\n", + printk(KERN_WARNING "md/raid:%s: reshape: not enough stripes. Needed %lu\n", + mdname(mddev), ((max(mddev->chunk_sectors, mddev->new_chunk_sectors) << 9) / STRIPE_SIZE)*4); return 0; @@ -5429,7 +5417,7 @@ static int raid5_start_reshape(mddev_t *mddev) */ if (raid5_size(mddev, 0, conf->raid_disks + mddev->delta_disks) < mddev->array_sectors) { - printk(KERN_ERR "md: %s: array size must be reduced " + printk(KERN_ERR "md/raid:%s: array size must be reduced " "before number of disks\n", mdname(mddev)); return -EINVAL; } @@ -5467,9 +5455,9 @@ static int raid5_start_reshape(mddev_t *mddev) if (sysfs_create_link(&mddev->kobj, &rdev->kobj, nm)) printk(KERN_WARNING - "raid5: failed to create " - " link %s for %s\n", - nm, mdname(mddev)); + "md/raid:%s: failed to create " + " link %s\n", + mdname(mddev), nm); } else break; } @@ -5616,7 +5604,8 @@ static void *raid45_takeover_raid0(mddev_t *mddev, int level) /* for raid0 takeover only one zone is supported */ if (raid0_priv->nr_strip_zones > 1) { - printk(KERN_ERR "md: cannot takeover raid0 with more than one zone.\n"); + printk(KERN_ERR "md/raid:%s: cannot takeover raid0 with more than one zone.\n", + mdname(mddev)); return ERR_PTR(-EINVAL); } -- cgit v1.2.3 From 9dd1e2faf72f79a2af9dcbd059473c06648726c2 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 3 May 2010 14:30:35 +1000 Subject: md/raid1: improve printk messages Make sure the array name is included in a uniform way in all printk messages. Signed-off-by: NeilBrown --- drivers/md/raid1.c | 57 +++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index cb2da87ad593..1db02c4955a9 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -296,7 +296,8 @@ static void raid1_end_read_request(struct bio *bio, int error) */ char b[BDEVNAME_SIZE]; if (printk_ratelimit()) - printk(KERN_ERR "raid1: %s: rescheduling sector %llu\n", + printk(KERN_ERR "md/raid1:%s: %s: rescheduling sector %llu\n", + mdname(conf->mddev), bdevname(conf->mirrors[mirror].rdev->bdev,b), (unsigned long long)r1_bio->sector); reschedule_retry(r1_bio); } @@ -1075,21 +1076,22 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) } else set_bit(Faulty, &rdev->flags); set_bit(MD_CHANGE_DEVS, &mddev->flags); - printk(KERN_ALERT "raid1: Disk failure on %s, disabling device.\n" - "raid1: Operation continuing on %d devices.\n", - bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded); + printk(KERN_ALERT "md/raid1:%s: Disk failure on %s, disabling device.\n" + KERN_ALERT "md/raid1:%s: Operation continuing on %d devices.\n", + mdname(mddev), bdevname(rdev->bdev, b), + mdname(mddev), conf->raid_disks - mddev->degraded); } static void print_conf(conf_t *conf) { int i; - printk("RAID1 conf printout:\n"); + printk(KERN_DEBUG "RAID1 conf printout:\n"); if (!conf) { - printk("(!conf)\n"); + printk(KERN_DEBUG "(!conf)\n"); return; } - printk(" --- wd:%d rd:%d\n", conf->raid_disks - conf->mddev->degraded, + printk(KERN_DEBUG " --- wd:%d rd:%d\n", conf->raid_disks - conf->mddev->degraded, conf->raid_disks); rcu_read_lock(); @@ -1097,7 +1099,7 @@ static void print_conf(conf_t *conf) char b[BDEVNAME_SIZE]; mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev); if (rdev) - printk(" disk %d, wo:%d, o:%d, dev:%s\n", + printk(KERN_DEBUG " disk %d, wo:%d, o:%d, dev:%s\n", i, !test_bit(In_sync, &rdev->flags), !test_bit(Faulty, &rdev->flags), bdevname(rdev->bdev,b)); @@ -1458,9 +1460,10 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) char b[BDEVNAME_SIZE]; /* Cannot read from anywhere, array is toast */ md_error(mddev, conf->mirrors[r1_bio->read_disk].rdev); - printk(KERN_ALERT "raid1: %s: unrecoverable I/O read error" + printk(KERN_ALERT "md/raid1:%s: %s: unrecoverable I/O read error" " for block %llu\n", - bdevname(bio->bi_bdev,b), + mdname(mddev), + bdevname(bio->bi_bdev, b), (unsigned long long)r1_bio->sector); md_done_sync(mddev, r1_bio->sectors, 0); put_buf(r1_bio); @@ -1582,7 +1585,7 @@ static void fix_read_error(conf_t *conf, int read_disk, else { atomic_add(s, &rdev->corrected_errors); printk(KERN_INFO - "raid1:%s: read error corrected " + "md/raid1:%s: read error corrected " "(%d sectors at %llu on %s)\n", mdname(mddev), s, (unsigned long long)(sect + @@ -1687,8 +1690,9 @@ static void raid1d(mddev_t *mddev) bio = r1_bio->bios[r1_bio->read_disk]; if ((disk=read_balance(conf, r1_bio)) == -1) { - printk(KERN_ALERT "raid1: %s: unrecoverable I/O" + printk(KERN_ALERT "md/raid1:%s: %s: unrecoverable I/O" " read error for block %llu\n", + mdname(mddev), bdevname(bio->bi_bdev,b), (unsigned long long)r1_bio->sector); raid_end_bio_io(r1_bio); @@ -1702,8 +1706,9 @@ static void raid1d(mddev_t *mddev) r1_bio->bios[r1_bio->read_disk] = bio; rdev = conf->mirrors[disk].rdev; if (printk_ratelimit()) - printk(KERN_ERR "raid1: redirecting sector %llu to" + printk(KERN_ERR "md/raid1:%s: redirecting sector %llu to" " other mirror: %s\n", + mdname(mddev), (unsigned long long)r1_bio->sector, bdevname(rdev->bdev,b)); bio->bi_sector = r1_bio->sector + rdev->data_offset; @@ -1760,13 +1765,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i int still_degraded = 0; if (!conf->r1buf_pool) - { -/* - printk("sync start - bitmap %p\n", mddev->bitmap); -*/ if (init_resync(conf)) return 0; - } max_sector = mddev->dev_sectors; if (sector_nr >= max_sector) { @@ -2047,7 +2047,7 @@ static conf_t *setup_conf(mddev_t *mddev) err = -EIO; if (conf->last_used < 0) { - printk(KERN_ERR "raid1: no operational mirrors for %s\n", + printk(KERN_ERR "md/raid1:%s: no operational mirrors\n", mdname(mddev)); goto abort; } @@ -2055,7 +2055,7 @@ static conf_t *setup_conf(mddev_t *mddev) conf->thread = md_register_thread(raid1d, mddev, NULL); if (!conf->thread) { printk(KERN_ERR - "raid1: couldn't allocate thread for %s\n", + "md/raid1:%s: couldn't allocate thread\n", mdname(mddev)); goto abort; } @@ -2081,12 +2081,12 @@ static int run(mddev_t *mddev) mdk_rdev_t *rdev; if (mddev->level != 1) { - printk("raid1: %s: raid level not set to mirroring (%d)\n", + printk(KERN_ERR "md/raid1:%s: raid level not set to mirroring (%d)\n", mdname(mddev), mddev->level); return -EIO; } if (mddev->reshape_position != MaxSector) { - printk("raid1: %s: reshape_position set but not supported\n", + printk(KERN_ERR "md/raid1:%s: reshape_position set but not supported\n", mdname(mddev)); return -EIO; } @@ -2129,11 +2129,11 @@ static int run(mddev_t *mddev) mddev->recovery_cp = MaxSector; if (mddev->recovery_cp != MaxSector) - printk(KERN_NOTICE "raid1: %s is not clean" + printk(KERN_NOTICE "md/raid1:%s: not clean" " -- starting background reconstruction\n", mdname(mddev)); printk(KERN_INFO - "raid1: raid set %s active with %d out of %d mirrors\n", + "md/raid1:%s: active with %d out of %d mirrors\n", mdname(mddev), mddev->raid_disks - mddev->degraded, mddev->raid_disks); @@ -2160,7 +2160,8 @@ static int stop(mddev_t *mddev) /* wait for behind writes to complete */ if (bitmap && atomic_read(&bitmap->behind_writes) > 0) { - printk(KERN_INFO "raid1: behind writes in progress on device %s, waiting to stop.\n", mdname(mddev)); + printk(KERN_INFO "md/raid1:%s: behind writes in progress - waiting to stop.\n", + mdname(mddev)); /* need to kick something here to make sure I/O goes? */ wait_event(bitmap->behind_wait, atomic_read(&bitmap->behind_writes) == 0); @@ -2288,9 +2289,9 @@ static int raid1_reshape(mddev_t *mddev) if (sysfs_create_link(&mddev->kobj, &rdev->kobj, nm)) printk(KERN_WARNING - "md/raid1: cannot register " - "%s for %s\n", - nm, mdname(mddev)); + "md/raid1:%s: cannot register " + "%s\n", + mdname(mddev), nm); } if (rdev) newmirrors[d2++].rdev = rdev; -- cgit v1.2.3 From 128595ed6ff2c7358ae253a560d47a0af463bc99 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 3 May 2010 14:47:14 +1000 Subject: md/raid10: tidy up printk messages. All raid10 printk messages now start md/raid10:md-device-name: Signed-off-by: NeilBrown --- drivers/md/raid10.c | 72 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index a1d727610a49..e0742c439484 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -285,7 +285,8 @@ static void raid10_end_read_request(struct bio *bio, int error) */ char b[BDEVNAME_SIZE]; if (printk_ratelimit()) - printk(KERN_ERR "raid10: %s: rescheduling sector %llu\n", + printk(KERN_ERR "md/raid10:%s: %s: rescheduling sector %llu\n", + mdname(conf->mddev), bdevname(conf->mirrors[dev].rdev->bdev,b), (unsigned long long)r10_bio->sector); reschedule_retry(r10_bio); } @@ -831,8 +832,8 @@ static int make_request(mddev_t *mddev, struct bio * bio) bio_pair_release(bp); return 0; bad_map: - printk("raid10_make_request bug: can't convert block across chunks" - " or bigger than %dk %llu %d\n", chunk_sects/2, + printk("md/raid10:%s: make_request bug: can't convert block across chunks" + " or bigger than %dk %llu %d\n", mdname(mddev), chunk_sects/2, (unsigned long long)bio->bi_sector, bio->bi_size >> 10); bio_io_error(bio); @@ -1031,9 +1032,10 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) } set_bit(Faulty, &rdev->flags); set_bit(MD_CHANGE_DEVS, &mddev->flags); - printk(KERN_ALERT "raid10: Disk failure on %s, disabling device.\n" - "raid10: Operation continuing on %d devices.\n", - bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded); + printk(KERN_ALERT "md/raid10:%s: Disk failure on %s, disabling device.\n" + KERN_ALERT "md/raid10:%s: Operation continuing on %d devices.\n", + mdname(mddev), bdevname(rdev->bdev, b), + mdname(mddev), conf->raid_disks - mddev->degraded); } static void print_conf(conf_t *conf) @@ -1041,19 +1043,19 @@ static void print_conf(conf_t *conf) int i; mirror_info_t *tmp; - printk("RAID10 conf printout:\n"); + printk(KERN_DEBUG "RAID10 conf printout:\n"); if (!conf) { - printk("(!conf)\n"); + printk(KERN_DEBUG "(!conf)\n"); return; } - printk(" --- wd:%d rd:%d\n", conf->raid_disks - conf->mddev->degraded, + printk(KERN_DEBUG " --- wd:%d rd:%d\n", conf->raid_disks - conf->mddev->degraded, conf->raid_disks); for (i = 0; i < conf->raid_disks; i++) { char b[BDEVNAME_SIZE]; tmp = conf->mirrors + i; if (tmp->rdev) - printk(" disk %d, wo:%d, o:%d, dev:%s\n", + printk(KERN_DEBUG " disk %d, wo:%d, o:%d, dev:%s\n", i, !test_bit(In_sync, &tmp->rdev->flags), !test_bit(Faulty, &tmp->rdev->flags), bdevname(tmp->rdev->bdev,b)); @@ -1502,13 +1504,14 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio) if (cur_read_error_count > max_read_errors) { rcu_read_unlock(); printk(KERN_NOTICE - "raid10: %s: Raid device exceeded " + "md/raid10:%s: %s: Raid device exceeded " "read_error threshold " "[cur %d:max %d]\n", + mdname(mddev), b, cur_read_error_count, max_read_errors); printk(KERN_NOTICE - "raid10: %s: Failing raid " - "device\n", b); + "md/raid10:%s: %s: Failing raid " + "device\n", mdname(mddev), b); md_error(mddev, conf->mirrors[d].rdev); return; } @@ -1578,15 +1581,16 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio) == 0) { /* Well, this device is dead */ printk(KERN_NOTICE - "raid10:%s: read correction " + "md/raid10:%s: read correction " "write failed" " (%d sectors at %llu on %s)\n", mdname(mddev), s, (unsigned long long)(sect+ rdev->data_offset), bdevname(rdev->bdev, b)); - printk(KERN_NOTICE "raid10:%s: failing " + printk(KERN_NOTICE "md/raid10:%s: %s: failing " "drive\n", + mdname(mddev), bdevname(rdev->bdev, b)); md_error(mddev, rdev); } @@ -1614,20 +1618,21 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio) READ) == 0) { /* Well, this device is dead */ printk(KERN_NOTICE - "raid10:%s: unable to read back " + "md/raid10:%s: unable to read back " "corrected sectors" " (%d sectors at %llu on %s)\n", mdname(mddev), s, (unsigned long long)(sect+ rdev->data_offset), bdevname(rdev->bdev, b)); - printk(KERN_NOTICE "raid10:%s: failing drive\n", + printk(KERN_NOTICE "md/raid10:%s: %s: failing drive\n", + mdname(mddev), bdevname(rdev->bdev, b)); md_error(mddev, rdev); } else { printk(KERN_INFO - "raid10:%s: read error corrected" + "md/raid10:%s: read error corrected" " (%d sectors at %llu on %s)\n", mdname(mddev), s, (unsigned long long)(sect+ @@ -1702,8 +1707,9 @@ static void raid10d(mddev_t *mddev) mddev->ro ? IO_BLOCKED : NULL; mirror = read_balance(conf, r10_bio); if (mirror == -1) { - printk(KERN_ALERT "raid10: %s: unrecoverable I/O" + printk(KERN_ALERT "md/raid10:%s: %s: unrecoverable I/O" " read error for block %llu\n", + mdname(mddev), bdevname(bio->bi_bdev,b), (unsigned long long)r10_bio->sector); raid_end_bio_io(r10_bio); @@ -1713,8 +1719,9 @@ static void raid10d(mddev_t *mddev) bio_put(bio); rdev = conf->mirrors[mirror].rdev; if (printk_ratelimit()) - printk(KERN_ERR "raid10: %s: redirecting sector %llu to" + printk(KERN_ERR "md/raid10:%s: %s: redirecting sector %llu to" " another mirror\n", + mdname(mddev), bdevname(rdev->bdev,b), (unsigned long long)r10_bio->sector); bio = bio_clone(r10_bio->master_bio, GFP_NOIO); @@ -1972,7 +1979,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i r10_bio = rb2; if (!test_and_set_bit(MD_RECOVERY_INTR, &mddev->recovery)) - printk(KERN_INFO "raid10: %s: insufficient working devices for recovery.\n", + printk(KERN_INFO "md/raid10:%s: insufficient " + "working devices for recovery.\n", mdname(mddev)); break; } @@ -2154,8 +2162,9 @@ static conf_t *setup_conf(mddev_t *mddev) if (mddev->chunk_sectors < (PAGE_SIZE >> 9) || !is_power_of_2(mddev->chunk_sectors)) { - printk(KERN_ERR "md/raid10: chunk size must be " - "at least PAGE_SIZE(%ld) and be a power of 2.\n", PAGE_SIZE); + printk(KERN_ERR "md/raid10:%s: chunk size must be " + "at least PAGE_SIZE(%ld) and be a power of 2.\n", + mdname(mddev), PAGE_SIZE); goto out; } @@ -2165,7 +2174,7 @@ static conf_t *setup_conf(mddev_t *mddev) if ((nc*fc) <2 || (nc*fc) > mddev->raid_disks || (mddev->layout >> 17)) { - printk(KERN_ERR "raid10: %s: unsupported raid10 layout: 0x%8x\n", + printk(KERN_ERR "md/raid10:%s: unsupported raid10 layout: 0x%8x\n", mdname(mddev), mddev->layout); goto out; } @@ -2236,7 +2245,7 @@ static conf_t *setup_conf(mddev_t *mddev) return conf; out: - printk(KERN_ERR "raid10: couldn't allocate memory for %s\n", + printk(KERN_ERR "md/raid10:%s: couldn't allocate memory.\n", mdname(mddev)); if (conf) { if (conf->r10bio_pool) @@ -2314,7 +2323,7 @@ static int run(mddev_t *mddev) } /* need to check that every block has at least one working mirror */ if (!enough(conf)) { - printk(KERN_ERR "raid10: not enough operational mirrors for %s\n", + printk(KERN_ERR "md/raid10:%s: not enough operational mirrors.\n", mdname(mddev)); goto out_free_conf; } @@ -2334,11 +2343,11 @@ static int run(mddev_t *mddev) } if (mddev->recovery_cp != MaxSector) - printk(KERN_NOTICE "raid10: %s is not clean" + printk(KERN_NOTICE "md/raid10:%s: not clean" " -- starting background reconstruction\n", mdname(mddev)); printk(KERN_INFO - "raid10: raid set %s active with %d out of %d devices\n", + "md/raid10:%s: active with %d out of %d devices\n", mdname(mddev), conf->raid_disks - mddev->degraded, conf->raid_disks); /* @@ -2420,7 +2429,8 @@ static void *raid10_takeover_raid0(mddev_t *mddev) conf_t *conf; if (mddev->degraded > 0) { - printk(KERN_ERR "error: degraded raid0!\n"); + printk(KERN_ERR "md/raid10:%s: Error: degraded raid0!\n", + mdname(mddev)); return ERR_PTR(-EINVAL); } @@ -2458,7 +2468,9 @@ static void *raid10_takeover(mddev_t *mddev) /* for raid0 takeover only one zone is supported */ raid0_priv = mddev->private; if (raid0_priv->nr_strip_zones > 1) { - printk(KERN_ERR "md: cannot takeover raid 0 with more than one zone.\n"); + printk(KERN_ERR "md/raid10:%s: cannot takeover raid 0" + " with more than one zone.\n", + mdname(mddev)); return ERR_PTR(-EINVAL); } return raid10_takeover_raid0(mddev); -- cgit v1.2.3 From b5a20961f3479dda48bdc340354ee5469997839d Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 3 May 2010 15:06:27 +1000 Subject: md/raid0: tidy up printk messages. All messages now start md/raid0:md-device-name: Signed-off-by: NeilBrown --- drivers/md/raid0.c | 110 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 65 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 9f9c6b76ca7c..dc38c1a45166 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -75,10 +75,10 @@ static void dump_zones(mddev_t *mddev) for (j = 0; j < conf->nr_strip_zones; j++) { printk(KERN_INFO "zone%d=[", j); for (k = 0; k < conf->strip_zone[j].nb_dev; k++) - printk("%s/", + printk(KERN_CONT "%s/", bdevname(conf->devlist[j*raid_disks + k]->bdev, b)); - printk("]\n"); + printk(KERN_CONT "]\n"); zone_size = conf->strip_zone[j].zone_end - zone_start; printk(KERN_INFO " zone offset=%llukb " @@ -104,8 +104,9 @@ static int create_strip_zones(mddev_t *mddev, raid0_conf_t **private_conf) if (!conf) return -ENOMEM; list_for_each_entry(rdev1, &mddev->disks, same_set) { - printk(KERN_INFO "raid0: looking at %s\n", - bdevname(rdev1->bdev,b)); + printk(KERN_INFO "md/raid0:%s: looking at %s\n", + mdname(mddev), + bdevname(rdev1->bdev, b)); c = 0; /* round size to chunk_size */ @@ -114,14 +115,16 @@ static int create_strip_zones(mddev_t *mddev, raid0_conf_t **private_conf) rdev1->sectors = sectors * mddev->chunk_sectors; list_for_each_entry(rdev2, &mddev->disks, same_set) { - printk(KERN_INFO "raid0: comparing %s(%llu)", + printk(KERN_INFO "md/raid0:%s: comparing %s(%llu)", + mdname(mddev), bdevname(rdev1->bdev,b), (unsigned long long)rdev1->sectors); - printk(KERN_INFO " with %s(%llu)\n", + printk(KERN_CONT " with %s(%llu)\n", bdevname(rdev2->bdev,b), (unsigned long long)rdev2->sectors); if (rdev2 == rdev1) { - printk(KERN_INFO "raid0: END\n"); + printk(KERN_INFO "md/raid0:%s: END\n", + mdname(mddev)); break; } if (rdev2->sectors == rdev1->sectors) { @@ -129,20 +132,24 @@ static int create_strip_zones(mddev_t *mddev, raid0_conf_t **private_conf) * Not unique, don't count it as a new * group */ - printk(KERN_INFO "raid0: EQUAL\n"); + printk(KERN_INFO "md/raid0:%s: EQUAL\n", + mdname(mddev)); c = 1; break; } - printk(KERN_INFO "raid0: NOT EQUAL\n"); + printk(KERN_INFO "md/raid0:%s: NOT EQUAL\n", + mdname(mddev)); } if (!c) { - printk(KERN_INFO "raid0: ==> UNIQUE\n"); + printk(KERN_INFO "md/raid0:%s: ==> UNIQUE\n", + mdname(mddev)); conf->nr_strip_zones++; - printk(KERN_INFO "raid0: %d zones\n", - conf->nr_strip_zones); + printk(KERN_INFO "md/raid0:%s: %d zones\n", + mdname(mddev), conf->nr_strip_zones); } } - printk(KERN_INFO "raid0: FINAL %d zones\n", conf->nr_strip_zones); + printk(KERN_INFO "md/raid0:%s: FINAL %d zones\n", + mdname(mddev), conf->nr_strip_zones); err = -ENOMEM; conf->strip_zone = kzalloc(sizeof(struct strip_zone)* conf->nr_strip_zones, GFP_KERNEL); @@ -170,13 +177,13 @@ static int create_strip_zones(mddev_t *mddev, raid0_conf_t **private_conf) j /= 2; if (j < 0 || j >= mddev->raid_disks) { - printk(KERN_ERR "raid0: bad disk number %d - " - "aborting!\n", j); + printk(KERN_ERR "md/raid0:%s: bad disk number %d - " + "aborting!\n", mdname(mddev), j); goto abort; } if (dev[j]) { - printk(KERN_ERR "raid0: multiple devices for %d - " - "aborting!\n", j); + printk(KERN_ERR "md/raid0:%s: multiple devices for %d - " + "aborting!\n", mdname(mddev), j); goto abort; } dev[j] = rdev1; @@ -198,8 +205,8 @@ static int create_strip_zones(mddev_t *mddev, raid0_conf_t **private_conf) cnt++; } if (cnt != mddev->raid_disks) { - printk(KERN_ERR "raid0: too few disks (%d of %d) - " - "aborting!\n", cnt, mddev->raid_disks); + printk(KERN_ERR "md/raid0:%s: too few disks (%d of %d) - " + "aborting!\n", mdname(mddev), cnt, mddev->raid_disks); goto abort; } zone->nb_dev = cnt; @@ -215,39 +222,44 @@ static int create_strip_zones(mddev_t *mddev, raid0_conf_t **private_conf) zone = conf->strip_zone + i; dev = conf->devlist + i * mddev->raid_disks; - printk(KERN_INFO "raid0: zone %d\n", i); + printk(KERN_INFO "md/raid0:%s: zone %d\n", + mdname(mddev), i); zone->dev_start = smallest->sectors; smallest = NULL; c = 0; for (j=0; jdevlist[j]; - printk(KERN_INFO "raid0: checking %s ...", - bdevname(rdev->bdev, b)); + printk(KERN_INFO "md/raid0:%s: checking %s ...", + mdname(mddev), + bdevname(rdev->bdev, b)); if (rdev->sectors <= zone->dev_start) { - printk(KERN_INFO " nope.\n"); + printk(KERN_CONT " nope.\n"); continue; } - printk(KERN_INFO " contained as device %d\n", c); + printk(KERN_CONT " contained as device %d\n", c); dev[c] = rdev; c++; if (!smallest || rdev->sectors < smallest->sectors) { smallest = rdev; - printk(KERN_INFO " (%llu) is smallest!.\n", - (unsigned long long)rdev->sectors); + printk(KERN_INFO "md/raid0:%s: (%llu) is smallest!.\n", + mdname(mddev), + (unsigned long long)rdev->sectors); } } zone->nb_dev = c; sectors = (smallest->sectors - zone->dev_start) * c; - printk(KERN_INFO "raid0: zone->nb_dev: %d, sectors: %llu\n", - zone->nb_dev, (unsigned long long)sectors); + printk(KERN_INFO "md/raid0:%s: zone->nb_dev: %d, sectors: %llu\n", + mdname(mddev), + zone->nb_dev, (unsigned long long)sectors); curr_zone_end += sectors; zone->zone_end = curr_zone_end; - printk(KERN_INFO "raid0: current zone start: %llu\n", - (unsigned long long)smallest->sectors); + printk(KERN_INFO "md/raid0:%s: current zone start: %llu\n", + mdname(mddev), + (unsigned long long)smallest->sectors); } mddev->queue->unplug_fn = raid0_unplug; mddev->queue->backing_dev_info.congested_fn = raid0_congested; @@ -258,7 +270,7 @@ static int create_strip_zones(mddev_t *mddev, raid0_conf_t **private_conf) * chunk size is a multiple of that sector size */ if ((mddev->chunk_sectors << 9) % queue_logical_block_size(mddev->queue)) { - printk(KERN_ERR "%s chunk_size of %d not valid\n", + printk(KERN_ERR "md/raid0:%s: chunk_size of %d not valid\n", mdname(mddev), mddev->chunk_sectors << 9); goto abort; @@ -268,7 +280,7 @@ static int create_strip_zones(mddev_t *mddev, raid0_conf_t **private_conf) blk_queue_io_opt(mddev->queue, (mddev->chunk_sectors << 9) * mddev->raid_disks); - printk(KERN_INFO "raid0: done.\n"); + printk(KERN_INFO "md/raid0:%s: done.\n", mdname(mddev)); *private_conf = conf; return 0; @@ -331,7 +343,8 @@ static int raid0_run(mddev_t *mddev) int ret; if (mddev->chunk_sectors == 0) { - printk(KERN_ERR "md/raid0: chunk size must be set.\n"); + printk(KERN_ERR "md/raid0:%s: chunk size must be set.\n", + mdname(mddev)); return -EINVAL; } if (md_check_no_bitmap(mddev)) @@ -357,8 +370,9 @@ static int raid0_run(mddev_t *mddev) /* calculate array device size */ md_set_array_sectors(mddev, raid0_size(mddev, 0, 0)); - printk(KERN_INFO "raid0 : md_size is %llu sectors.\n", - (unsigned long long)mddev->array_sectors); + printk(KERN_INFO "md/raid0:%s: md_size is %llu sectors.\n", + mdname(mddev), + (unsigned long long)mddev->array_sectors); /* calculate the max read-ahead size. * For read-ahead of large files to be effective, we need to * readahead at least twice a whole stripe. i.e. number of devices @@ -516,9 +530,10 @@ static int raid0_make_request(mddev_t *mddev, struct bio *bio) return 1; bad_map: - printk("raid0_make_request bug: can't convert block across chunks" - " or bigger than %dk %llu %d\n", chunk_sects / 2, - (unsigned long long)bio->bi_sector, bio->bi_size >> 10); + printk("md/raid0:%s: make_request bug: can't convert block across chunks" + " or bigger than %dk %llu %d\n", + mdname(mddev), chunk_sects / 2, + (unsigned long long)bio->bi_sector, bio->bi_size >> 10); bio_io_error(bio); return 0; @@ -563,7 +578,8 @@ static void *raid0_takeover_raid5(mddev_t *mddev) raid0_conf_t *priv_conf; if (mddev->degraded != 1) { - printk(KERN_ERR "md: raid5 must be degraded! Degraded disks: %d\n", + printk(KERN_ERR "md/raid0:%s: raid5 must be degraded! Degraded disks: %d\n", + mdname(mddev), mddev->degraded); return ERR_PTR(-EINVAL); } @@ -571,7 +587,8 @@ static void *raid0_takeover_raid5(mddev_t *mddev) list_for_each_entry(rdev, &mddev->disks, same_set) { /* check slot number for a disk */ if (rdev->raid_disk == mddev->raid_disks-1) { - printk(KERN_ERR "md: raid5 must have missing parity disk!\n"); + printk(KERN_ERR "md/raid0:%s: raid5 must have missing parity disk!\n", + mdname(mddev)); return ERR_PTR(-EINVAL); } } @@ -599,16 +616,19 @@ static void *raid0_takeover_raid10(mddev_t *mddev) * - all mirrors must be already degraded */ if (mddev->layout != ((1 << 8) + 2)) { - printk(KERN_ERR "md: Raid0 cannot takover layout: %x\n", + printk(KERN_ERR "md/raid0:%s:: Raid0 cannot takover layout: 0x%x\n", + mdname(mddev), mddev->layout); return ERR_PTR(-EINVAL); } if (mddev->raid_disks & 1) { - printk(KERN_ERR "md: Raid0 cannot takover Raid10 with odd disk number.\n"); + printk(KERN_ERR "md/raid0:%s: Raid0 cannot takover Raid10 with odd disk number.\n", + mdname(mddev)); return ERR_PTR(-EINVAL); } if (mddev->degraded != (mddev->raid_disks>>1)) { - printk(KERN_ERR "md: All mirrors must be already degraded!\n"); + printk(KERN_ERR "md/raid0:%s: All mirrors must be already degraded!\n", + mdname(mddev)); return ERR_PTR(-EINVAL); } @@ -636,8 +656,8 @@ static void *raid0_takeover(mddev_t *mddev) if (mddev->layout == ALGORITHM_PARITY_N) return raid0_takeover_raid5(mddev); - printk(KERN_ERR "md: Raid can only takeover Raid5 with layout: %d\n", - ALGORITHM_PARITY_N); + printk(KERN_ERR "md/raid0:%s: Raid can only takeover Raid5 with layout: %d\n", + mdname(mddev), ALGORITHM_PARITY_N); } if (mddev->level == 10) -- cgit v1.2.3 From 2dc40f80945ac3e5ec05c3a6c75baf09b13cee51 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 3 May 2010 15:12:04 +1000 Subject: md/linear: standardise all printk messages md/linear:mdname: Signed-off-by: NeilBrown --- drivers/md/linear.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 3204a2263f21..d5d5064c4a66 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c @@ -158,7 +158,8 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) sector_t sectors; if (j < 0 || j >= raid_disks || disk->rdev) { - printk("linear: disk numbering problem. Aborting!\n"); + printk(KERN_ERR "md/linear:%s: disk numbering problem. Aborting!\n", + mdname(mddev)); goto out; } @@ -186,7 +187,8 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) } if (cnt != raid_disks) { - printk("linear: not enough drives present. Aborting!\n"); + printk(KERN_ERR "md/linear:%s: not enough drives present. Aborting!\n", + mdname(mddev)); goto out; } @@ -305,12 +307,14 @@ static int linear_make_request (mddev_t *mddev, struct bio *bio) || (bio->bi_sector < start_sector))) { char b[BDEVNAME_SIZE]; - printk("linear_make_request: Sector %llu out of bounds on " - "dev %s: %llu sectors, offset %llu\n", - (unsigned long long)bio->bi_sector, - bdevname(tmp_dev->rdev->bdev, b), - (unsigned long long)tmp_dev->rdev->sectors, - (unsigned long long)start_sector); + printk(KERN_ERR + "md/linear:%s: make_request: Sector %llu out of bounds on " + "dev %s: %llu sectors, offset %llu\n", + mdname(mddev), + (unsigned long long)bio->bi_sector, + bdevname(tmp_dev->rdev->bdev, b), + (unsigned long long)tmp_dev->rdev->sectors, + (unsigned long long)start_sector); rcu_read_unlock(); bio_io_error(bio); return 0; -- cgit v1.2.3 From af3a2cd6b8a479345786e7fe5e199ad2f6240e56 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 8 May 2010 08:20:17 +1000 Subject: md: Fix read balancing in RAID1 and RAID10 on drives > 2TB read_balance uses a "unsigned long" for a sector number which will get truncated beyond 2TB. This will cause read-balancing to be non-optimal, and can cause data to be read from the 'wrong' branch during a resync. This has a very small chance of returning wrong data. Reported-by: Jordan Russell Cc: stable@kernel.org Signed-off-by: NeilBrown --- drivers/md/raid1.c | 4 ++-- drivers/md/raid10.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 1db02c4955a9..a9b9972ff703 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -418,7 +418,7 @@ static void raid1_end_write_request(struct bio *bio, int error) */ static int read_balance(conf_t *conf, r1bio_t *r1_bio) { - const unsigned long this_sector = r1_bio->sector; + const sector_t this_sector = r1_bio->sector; int new_disk = conf->last_used, disk = new_disk; int wonly_disk = -1; const int sectors = r1_bio->sectors; @@ -434,7 +434,7 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio) retry: if (conf->mddev->recovery_cp < MaxSector && (this_sector + sectors >= conf->next_resync)) { - /* Choose the first operation device, for consistancy */ + /* Choose the first operational device, for consistancy */ new_disk = 0; for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev); diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index e0742c439484..a1f5fd2d69ce 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -495,7 +495,7 @@ static int raid10_mergeable_bvec(struct request_queue *q, */ static int read_balance(conf_t *conf, r10bio_t *r10_bio) { - const unsigned long this_sector = r10_bio->sector; + const sector_t this_sector = r10_bio->sector; int disk, slot, nslot; const int sectors = r10_bio->sectors; sector_t new_distance, current_distance; -- cgit v1.2.3 From 75a73a29e520a6ce982b0da6dd8b7560ae3faa90 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 7 May 2010 19:44:26 +1000 Subject: md: restore ability of spare drives to spin down. Some time ago we stopped the clean/active metadata updates from being written to a 'spare' device in most cases so that it could spin down and say spun down. Device failure/removal etc are still recorded on spares. However commit 51d5668cb2e3fd1827a55 broke this 50% of the time, depending on whether the event count is even or odd. The change log entry said: This means that the alignment between 'odd/even' and 'clean/dirty' might take a little longer to attain, how ever the code makes no attempt to create that alignment, so it could take arbitrarily long. So when we find that clean/dirty is not aligned with odd/even, force a second metadata-update immediately. There are already cases where a second metadata-update is needed immediately (e.g. when a device fails during the metadata update). We just piggy-back on that. Reported-by: Joe Bryant Signed-off-by: NeilBrown Cc: stable@kernel.org --- drivers/md/md.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index b8a0fcfb1de1..fec4abcb9bb4 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2150,12 +2150,18 @@ repeat: if (!mddev->in_sync || mddev->recovery_cp != MaxSector) { /* not clean */ /* .. if the array isn't clean, an 'even' event must also go * to spares. */ - if ((mddev->events&1)==0) + if ((mddev->events&1)==0) { nospares = 0; + sync_req = 2; /* force a second update to get the + * even/odd in sync */ + } } else { /* otherwise an 'odd' event must go to spares */ - if ((mddev->events&1)) + if ((mddev->events&1)) { nospares = 0; + sync_req = 2; /* force a second update to get the + * even/odd in sync */ + } } } -- cgit v1.2.3 From 7b0bb5368a7195606eca475d9f4e291ab7227052 Mon Sep 17 00:00:00 2001 From: "Gabriele A. Trombetti" Date: Wed, 28 Apr 2010 11:51:17 +1000 Subject: md/raid6: Fix raid-6 read-error correction in degraded state Fix: Raid-6 was not trying to correct a read-error when in singly-degraded state and was instead dropping one more device, going to doubly-degraded state. This patch fixes this behaviour. Tested-by: Janos Haar Signed-off-by: Gabriele A. Trombetti Reported-by: Janos Haar Signed-off-by: NeilBrown Cc: stable@kernel.org --- drivers/md/raid5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index cee9f93b35c4..eacf02a6ec5f 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -1527,7 +1527,7 @@ static void raid5_end_read_request(struct bio * bi, int error) clear_bit(R5_UPTODATE, &sh->dev[i].flags); atomic_inc(&rdev->read_errors); - if (conf->mddev->degraded) + if (conf->mddev->degraded >= conf->max_degraded) printk_rl(KERN_WARNING "md/raid:%s: read error not correctable " "(sector %llu on %s).\n", -- cgit v1.2.3 From a8707c08f4f718bb0ed65499d3f43201f6e41455 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 18 May 2010 09:28:43 +1000 Subject: md: simplify updating of event count to sometimes avoid updating spares. When updating the event count for a simple clean <-> dirty transition, we try to avoid updating the spares so they can safely spin-down. As the event_counts across an array must be +/- 1, this means decrementing the event_count on a dirty->clean transition. This is not always safe and we have to avoid the unsafe time. We current do this with a misguided idea about it being safe or not depending on whether the event_count is odd or even. This approach only works reliably in a few common instances, but easily falls down. So instead, simply keep internal state concerning whether it is safe or not, and always assume it is not safe when an array is first assembled. Signed-off-by: NeilBrown --- drivers/md/md.c | 26 ++++++-------------------- drivers/md/md.h | 6 ++++++ 2 files changed, 12 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index fec4abcb9bb4..9ef21d9b8e27 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2088,7 +2088,6 @@ static void sync_sbs(mddev_t * mddev, int nospares) if (rdev->sb_events == mddev->events || (nospares && rdev->raid_disk < 0 && - (rdev->sb_events&1)==0 && rdev->sb_events+1 == mddev->events)) { /* Don't update this superblock */ rdev->sb_loaded = 2; @@ -2141,28 +2140,14 @@ repeat: * and 'events' is odd, we can roll back to the previous clean state */ if (nospares && (mddev->in_sync && mddev->recovery_cp == MaxSector) - && (mddev->events & 1) - && mddev->events != 1) + && mddev->can_decrease_events + && mddev->events != 1) { mddev->events--; - else { + mddev->can_decrease_events = 0; + } else { /* otherwise we have to go forward and ... */ mddev->events ++; - if (!mddev->in_sync || mddev->recovery_cp != MaxSector) { /* not clean */ - /* .. if the array isn't clean, an 'even' event must also go - * to spares. */ - if ((mddev->events&1)==0) { - nospares = 0; - sync_req = 2; /* force a second update to get the - * even/odd in sync */ - } - } else { - /* otherwise an 'odd' event must go to spares */ - if ((mddev->events&1)) { - nospares = 0; - sync_req = 2; /* force a second update to get the - * even/odd in sync */ - } - } + mddev->can_decrease_events = nospares; } if (!mddev->events) { @@ -4606,6 +4591,7 @@ static void md_clean(mddev_t *mddev) mddev->layout = 0; mddev->max_disks = 0; mddev->events = 0; + mddev->can_decrease_events = 0; mddev->delta_disks = 0; mddev->new_level = LEVEL_NONE; mddev->new_layout = 0; diff --git a/drivers/md/md.h b/drivers/md/md.h index a536f5458097..7ab5ea155452 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -150,6 +150,12 @@ struct mddev_s int external_size; /* size managed * externally */ __u64 events; + /* If the last 'event' was simply a clean->dirty transition, and + * we didn't write it to the spares, then it is safe and simple + * to just decrement the event count on a dirty->clean transition. + * So we record that possibility here. + */ + int can_decrease_events; char uuid[16]; -- cgit v1.2.3 From be6800a73aa2f3dc14744c3b80e676d189789f04 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 18 May 2010 10:17:09 +1000 Subject: md: don't insist on valid event count for spare devices. Devices which know that they are spares do not really need to have an event count that matches the rest of the array, so there are no data-in-sync issues. It is enough that the uuid matches. So remove the requirement that the event count is up-to-date. We currently still write out and event count on spares, but this allows us in a year or 3 to stop doing that completely. Signed-off-by: NeilBrown --- drivers/md/md.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 9ef21d9b8e27..26b3d2879d93 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1070,10 +1070,13 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) mddev->bitmap_info.default_offset; } else if (mddev->pers == NULL) { - /* Insist on good event counter while assembling */ + /* Insist on good event counter while assembling, except + * for spares (which don't need an event count) */ ++ev1; - if (ev1 < mddev->events) - return -EINVAL; + if (sb->disks[rdev->desc_nr].state & ( + (1<events) + return -EINVAL; } else if (mddev->bitmap) { /* if adding to array with a bitmap, then we can accept an * older device ... but not too old. @@ -1469,10 +1472,14 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) } } else if (mddev->pers == NULL) { - /* Insist of good event counter while assembling */ + /* Insist of good event counter while assembling, except for + * spares (which don't need an event count) */ ++ev1; - if (ev1 < mddev->events) - return -EINVAL; + if (rdev->desc_nr >= 0 && + rdev->desc_nr < le32_to_cpu(sb->max_dev) && + le16_to_cpu(sb->dev_roles[rdev->desc_nr]) < 0xfffe) + if (ev1 < mddev->events) + return -EINVAL; } else if (mddev->bitmap) { /* If adding to array with a bitmap, then we can accept an * older device, but not too old. -- cgit v1.2.3 From b4d78bf7a4663c8354ec9432eb9631b144a33ffa Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 17 Mar 2010 13:35:19 +0100 Subject: OMAP: DSS2: Add Kconfig option for DPI display type This allows us to disable DPI on systems that do not have it Signed-off-by: Roger Quadros Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/Kconfig | 6 ++++++ drivers/video/omap2/dss/Makefile | 3 ++- drivers/video/omap2/dss/core.c | 4 ++++ drivers/video/omap2/dss/display.c | 4 ++++ 4 files changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig index 87afb81b2c44..43b64403eaa4 100644 --- a/drivers/video/omap2/dss/Kconfig +++ b/drivers/video/omap2/dss/Kconfig @@ -36,6 +36,12 @@ config OMAP2_DSS_COLLECT_IRQ_STATS /omapdss/dispc_irq for DISPC interrupts, and /omapdss/dsi_irq for DSI interrupts. +config OMAP2_DSS_DPI + bool "DPI support" + default y + help + DPI Interface. This is the Parallel Display Interface. + config OMAP2_DSS_RFBI bool "RFBI support" default n diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile index 980c72c2db98..d71b5d9d71b1 100644 --- a/drivers/video/omap2/dss/Makefile +++ b/drivers/video/omap2/dss/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_OMAP2_DSS) += omapdss.o -omapdss-y := core.o dss.o dispc.o dpi.o display.o manager.o overlay.o +omapdss-y := core.o dss.o dispc.o display.o manager.o overlay.o +omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 7ebe50b335ed..6d54467e5e20 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -526,11 +526,13 @@ static int omap_dss_probe(struct platform_device *pdev) } #endif +#ifdef CONFIG_OMAP2_DSS_DPI r = dpi_init(pdev); if (r) { DSSERR("Failed to initialize dpi\n"); goto fail0; } +#endif r = dispc_init(); if (r) { @@ -601,7 +603,9 @@ static int omap_dss_remove(struct platform_device *pdev) venc_exit(); #endif dispc_exit(); +#ifdef CONFIG_OMAP2_DSS_DPI dpi_exit(); +#endif #ifdef CONFIG_OMAP2_DSS_RFBI rfbi_exit(); #endif diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index 6a74ea116d29..71389630b108 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -392,7 +392,9 @@ void dss_init_device(struct platform_device *pdev, int r; switch (dssdev->type) { +#ifdef CONFIG_OMAP2_DSS_DPI case OMAP_DISPLAY_TYPE_DPI: +#endif #ifdef CONFIG_OMAP2_DSS_RFBI case OMAP_DISPLAY_TYPE_DBI: #endif @@ -413,9 +415,11 @@ void dss_init_device(struct platform_device *pdev, } switch (dssdev->type) { +#ifdef CONFIG_OMAP2_DSS_DPI case OMAP_DISPLAY_TYPE_DPI: r = dpi_init_display(dssdev); break; +#endif #ifdef CONFIG_OMAP2_DSS_RFBI case OMAP_DISPLAY_TYPE_DBI: r = rfbi_init_display(dssdev); -- cgit v1.2.3 From b1d145b6d3c07cb9ccb6afb224c78a9d61f8cd17 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 17 Mar 2010 13:35:20 +0100 Subject: OMAP: DSS2: Remove redundant enable/disable calls from SDI Panel enable/disable is now done via the panel driver, so we should not call the panel driver again Signed-off-by: Roger Quadros Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/sdi.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 12eb4042dd82..3de3c1e559aa 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -115,17 +115,9 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) dssdev->manager->enable(dssdev->manager); - if (dssdev->driver->enable) { - r = dssdev->driver->enable(dssdev); - if (r) - goto err3; - } - sdi.skip_init = 0; return 0; -err3: - dssdev->manager->disable(dssdev->manager); err2: dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); err1: @@ -137,9 +129,6 @@ EXPORT_SYMBOL(omapdss_sdi_display_enable); void omapdss_sdi_display_disable(struct omap_dss_device *dssdev) { - if (dssdev->driver->disable) - dssdev->driver->disable(dssdev); - dssdev->manager->disable(dssdev->manager); dss_sdi_disable(); -- cgit v1.2.3 From 508886cf98c81cee73cd75943b3d0039801327ab Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 17 Mar 2010 13:35:21 +0100 Subject: OMAP: DSS2: Use vdds_sdi regulator supply in SDI This patch enables the use of vdds_sdi regulator in SDI subsystem. We can disable the vdds_sdi voltage when not in use to save power. Signed-off-by: Roger Quadros Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/sdi.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 3de3c1e559aa..ee07a3cc22ef 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -23,13 +23,16 @@ #include #include #include +#include #include +#include #include "dss.h" static struct { bool skip_init; bool update_enabled; + struct regulator *vdds_sdi_reg; } sdi; static void sdi_basic_init(void) @@ -57,6 +60,10 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) goto err0; } + r = regulator_enable(sdi.vdds_sdi_reg); + if (r) + goto err1; + /* In case of skip_init sdi_init has already enabled the clocks */ if (!sdi.skip_init) dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); @@ -120,6 +127,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) return 0; err2: dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + regulator_disable(sdi.vdds_sdi_reg); err1: omap_dss_stop_device(dssdev); err0: @@ -135,6 +143,8 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev) dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + regulator_disable(sdi.vdds_sdi_reg); + omap_dss_stop_device(dssdev); } EXPORT_SYMBOL(omapdss_sdi_display_disable); @@ -151,6 +161,11 @@ int sdi_init(bool skip_init) /* we store this for first display enable, then clear it */ sdi.skip_init = skip_init; + sdi.vdds_sdi_reg = dss_get_vdds_sdi(); + if (IS_ERR(sdi.vdds_sdi_reg)) { + DSSERR("can't get VDDS_SDI regulator\n"); + return PTR_ERR(sdi.vdds_sdi_reg); + } /* * Enable clocks already here, otherwise there would be a toggle * of them until sdi_display_enable is called. -- cgit v1.2.3 From 238a41329ca208d1170962260babb428b6e222c2 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 18 Mar 2010 10:32:05 +0100 Subject: OMAP: DSS2: fix lock_fb_info() and omapfb_lock() locking order Framebuffer ioctl processing forces lock_fb_info() -> omapfb_lock() locking order. Follow that order to avoid possible circular locking dependency, detected by lockdep. Signed-off-by: Jani Nikula Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/omapfb/omapfb-ioctl.c | 4 ++-- drivers/video/omap2/omapfb/omapfb-sysfs.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index 1ffa760b8545..2c0f01c44aab 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c @@ -183,13 +183,13 @@ int omapfb_update_window(struct fb_info *fbi, struct omapfb2_device *fbdev = ofbi->fbdev; int r; - omapfb_lock(fbdev); lock_fb_info(fbi); + omapfb_lock(fbdev); r = omapfb_update_window_nolock(fbi, x, y, w, h); - unlock_fb_info(fbi); omapfb_unlock(fbdev); + unlock_fb_info(fbi); return r; } diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c index 62bb88f5c192..e10445017985 100644 --- a/drivers/video/omap2/omapfb/omapfb-sysfs.c +++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c @@ -137,8 +137,8 @@ static ssize_t show_overlays(struct device *dev, ssize_t l = 0; int t; - omapfb_lock(fbdev); lock_fb_info(fbi); + omapfb_lock(fbdev); for (t = 0; t < ofbi->num_overlays; t++) { struct omap_overlay *ovl = ofbi->overlays[t]; @@ -154,8 +154,8 @@ static ssize_t show_overlays(struct device *dev, l += snprintf(buf + l, PAGE_SIZE - l, "\n"); - unlock_fb_info(fbi); omapfb_unlock(fbdev); + unlock_fb_info(fbi); return l; } @@ -195,8 +195,8 @@ static ssize_t store_overlays(struct device *dev, struct device_attribute *attr, if (buf[len - 1] == '\n') len = len - 1; - omapfb_lock(fbdev); lock_fb_info(fbi); + omapfb_lock(fbdev); if (len > 0) { char *p = (char *)buf; @@ -303,8 +303,8 @@ static ssize_t store_overlays(struct device *dev, struct device_attribute *attr, r = count; out: - unlock_fb_info(fbi); omapfb_unlock(fbdev); + unlock_fb_info(fbi); return r; } -- cgit v1.2.3 From 27b67c92a30967e3a9e9ea082d4ca4bc6882f879 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 18 Mar 2010 10:32:06 +0100 Subject: OMAP: DSS2: check lock_fb_info() return value Give up if lock_fb_info() fails, following the same convention as other lock_fb_info() users. Signed-off-by: Jani Nikula Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/omapfb/omapfb-ioctl.c | 3 ++- drivers/video/omap2/omapfb/omapfb-sysfs.c | 21 ++++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index 2c0f01c44aab..9c7361871d78 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c @@ -183,7 +183,8 @@ int omapfb_update_window(struct fb_info *fbi, struct omapfb2_device *fbdev = ofbi->fbdev; int r; - lock_fb_info(fbi); + if (!lock_fb_info(fbi)) + return -ENODEV; omapfb_lock(fbdev); r = omapfb_update_window_nolock(fbi, x, y, w, h); diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c index e10445017985..5179219128bd 100644 --- a/drivers/video/omap2/omapfb/omapfb-sysfs.c +++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c @@ -57,7 +57,8 @@ static ssize_t store_rotate_type(struct device *dev, if (rot_type != OMAP_DSS_ROT_DMA && rot_type != OMAP_DSS_ROT_VRFB) return -EINVAL; - lock_fb_info(fbi); + if (!lock_fb_info(fbi)) + return -ENODEV; r = 0; if (rot_type == ofbi->rotation_type) @@ -105,7 +106,8 @@ static ssize_t store_mirror(struct device *dev, if (mirror != 0 && mirror != 1) return -EINVAL; - lock_fb_info(fbi); + if (!lock_fb_info(fbi)) + return -ENODEV; ofbi->mirror = mirror; @@ -137,7 +139,8 @@ static ssize_t show_overlays(struct device *dev, ssize_t l = 0; int t; - lock_fb_info(fbi); + if (!lock_fb_info(fbi)) + return -ENODEV; omapfb_lock(fbdev); for (t = 0; t < ofbi->num_overlays; t++) { @@ -195,7 +198,8 @@ static ssize_t store_overlays(struct device *dev, struct device_attribute *attr, if (buf[len - 1] == '\n') len = len - 1; - lock_fb_info(fbi); + if (!lock_fb_info(fbi)) + return -ENODEV; omapfb_lock(fbdev); if (len > 0) { @@ -317,7 +321,8 @@ static ssize_t show_overlays_rotate(struct device *dev, ssize_t l = 0; int t; - lock_fb_info(fbi); + if (!lock_fb_info(fbi)) + return -ENODEV; for (t = 0; t < ofbi->num_overlays; t++) { l += snprintf(buf + l, PAGE_SIZE - l, "%s%d", @@ -345,7 +350,8 @@ static ssize_t store_overlays_rotate(struct device *dev, if (buf[len - 1] == '\n') len = len - 1; - lock_fb_info(fbi); + if (!lock_fb_info(fbi)) + return -ENODEV; if (len > 0) { char *p = (char *)buf; @@ -416,7 +422,8 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr, size = PAGE_ALIGN(simple_strtoul(buf, NULL, 0)); - lock_fb_info(fbi); + if (!lock_fb_info(fbi)) + return -ENODEV; for (i = 0; i < ofbi->num_overlays; i++) { if (ofbi->overlays[i]->info.enabled) { -- cgit v1.2.3 From 35bc42c50432d3dde0119f7630f1e4574bd67519 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 24 Mar 2010 11:59:37 +0100 Subject: OMAP: DSS2: VENC: don't call platform_enable/disable() twice platform_enable/disable() is already called in venc_power_on/off(), so don't do it again in venc_panel_enable/disable(). Signed-off-by: Jani Nikula Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/venc.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index f0ba5732d84a..eff35050e28a 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -479,12 +479,6 @@ static int venc_panel_enable(struct omap_dss_device *dssdev) goto err1; } - if (dssdev->platform_enable) { - r = dssdev->platform_enable(dssdev); - if (r) - goto err2; - } - venc_power_on(dssdev); venc.wss_data = 0; @@ -494,13 +488,9 @@ static int venc_panel_enable(struct omap_dss_device *dssdev) /* wait couple of vsyncs until enabling the LCD */ msleep(50); - mutex_unlock(&venc.venc_lock); - - return r; -err2: - venc_power_off(dssdev); err1: mutex_unlock(&venc.venc_lock); + return r; } @@ -524,9 +514,6 @@ static void venc_panel_disable(struct omap_dss_device *dssdev) /* wait at least 5 vsyncs after disabling the LCD */ msleep(100); - if (dssdev->platform_disable) - dssdev->platform_disable(dssdev); - dssdev->state = OMAP_DSS_DISPLAY_DISABLED; end: mutex_unlock(&venc.venc_lock); -- cgit v1.2.3 From 279fcd48c4a426050422b2d196fd99c2b5ae7d71 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 24 Mar 2010 11:59:38 +0100 Subject: OMAP: DSS2: Fix device disable when driver is not loaded Only call driver disable when device isn't already disabled, which also handles the driver not loaded case. Signed-off-by: Jani Nikula Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/display.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index 71389630b108..ef8c8529dda2 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -545,7 +545,10 @@ int dss_resume_all_devices(void) static int dss_disable_device(struct device *dev, void *data) { struct omap_dss_device *dssdev = to_dss_device(dev); - dssdev->driver->disable(dssdev); + + if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) + dssdev->driver->disable(dssdev); + return 0; } -- cgit v1.2.3 From f49a951f8a2dacbbb145b6199297fcc3e493b90f Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 26 Mar 2010 16:26:37 +0200 Subject: OMAP: DSS2: Make partial update width even MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are some strange problems with DSI and updates with odd widths. One particular problem is that HS TX timeout triggers easily with updates with odd widths. This patch makes the updates widths even, circumventing the problem. There should be no ill side effects with increasing the update area slightly to make the width even. Signed-off-by: Ville Syrjälä Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/manager.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 0820986d4a68..32ec2ff2e9cf 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -940,6 +940,22 @@ static int configure_dispc(void) return r; } +/* Make the coordinates even. There are some strange problems with OMAP and + * partial DSI update when the update widths are odd. */ +static void make_even(u16 *x, u16 *w) +{ + u16 x1, x2; + + x1 = *x; + x2 = *x + *w; + + x1 &= ~1; + x2 = ALIGN(x2, 2); + + *x = x1; + *w = x2 - x1; +} + /* Configure dispc for partial update. Return possibly modified update * area */ void dss_setup_partial_planes(struct omap_dss_device *dssdev, @@ -968,6 +984,8 @@ void dss_setup_partial_planes(struct omap_dss_device *dssdev, return; } + make_even(&x, &w); + spin_lock_irqsave(&dss_cache.lock, flags); /* We need to show the whole overlay if it is scaled. So look for @@ -1029,6 +1047,8 @@ void dss_setup_partial_planes(struct omap_dss_device *dssdev, w = x2 - x1; h = y2 - y1; + make_even(&x, &w); + DSSDBG("changing upd area due to ovl(%d) scaling %d,%d %dx%d\n", i, x, y, w, h); } -- cgit v1.2.3 From a3201a0eaed38dd7ece72393a778b4408ec79627 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 3 Mar 2010 14:31:45 +0200 Subject: OMAP: DSS2: Taal: add mutex to protect panel data Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-taal.c | 140 +++++++++++++++++++++++++----- 1 file changed, 119 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 4f3988a41082..1799096a1388 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -31,6 +31,7 @@ #include #include #include +#include #include @@ -67,6 +68,8 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable); struct taal_data { + struct mutex lock; + struct backlight_device *bldev; unsigned long hw_guard_end; /* next value of jiffies when we can @@ -510,6 +513,8 @@ static int taal_probe(struct omap_dss_device *dssdev) } td->dssdev = dssdev; + mutex_init(&td->lock); + td->esd_wq = create_singlethread_workqueue("taal_esd"); if (td->esd_wq == NULL) { dev_err(&dssdev->dev, "can't create ESD workqueue\n"); @@ -733,54 +738,96 @@ static void taal_power_off(struct omap_dss_device *dssdev) static int taal_enable(struct omap_dss_device *dssdev) { + struct taal_data *td = dev_get_drvdata(&dssdev->dev); int r; + dev_dbg(&dssdev->dev, "enable\n"); - if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) - return -EINVAL; + mutex_lock(&td->lock); + + if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { + r = -EINVAL; + goto err; + } r = taal_power_on(dssdev); if (r) - return r; + goto err; dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + mutex_unlock(&td->lock); + + return 0; +err: + dev_dbg(&dssdev->dev, "enable failed\n"); + mutex_unlock(&td->lock); return r; } static void taal_disable(struct omap_dss_device *dssdev) { + struct taal_data *td = dev_get_drvdata(&dssdev->dev); + dev_dbg(&dssdev->dev, "disable\n"); + mutex_lock(&td->lock); + if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) taal_power_off(dssdev); dssdev->state = OMAP_DSS_DISPLAY_DISABLED; + + mutex_unlock(&td->lock); } static int taal_suspend(struct omap_dss_device *dssdev) { + struct taal_data *td = dev_get_drvdata(&dssdev->dev); + int r; + dev_dbg(&dssdev->dev, "suspend\n"); - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) - return -EINVAL; + mutex_lock(&td->lock); + + if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { + r = -EINVAL; + goto err; + } taal_power_off(dssdev); dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; + mutex_unlock(&td->lock); + return 0; +err: + mutex_unlock(&td->lock); + return r; } static int taal_resume(struct omap_dss_device *dssdev) { + struct taal_data *td = dev_get_drvdata(&dssdev->dev); int r; + dev_dbg(&dssdev->dev, "resume\n"); - if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) - return -EINVAL; + mutex_lock(&td->lock); + + if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) { + r = -EINVAL; + goto err; + } r = taal_power_on(dssdev); dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + mutex_unlock(&td->lock); + + return r; +err: + mutex_unlock(&td->lock); return r; } @@ -799,6 +846,7 @@ static int taal_update(struct omap_dss_device *dssdev, dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h); + mutex_lock(&td->lock); dsi_bus_lock(); if (!td->enabled) { @@ -820,18 +868,24 @@ static int taal_update(struct omap_dss_device *dssdev, goto err; /* note: no bus_unlock here. unlock is in framedone_cb */ + mutex_unlock(&td->lock); return 0; err: dsi_bus_unlock(); + mutex_unlock(&td->lock); return r; } static int taal_sync(struct omap_dss_device *dssdev) { + struct taal_data *td = dev_get_drvdata(&dssdev->dev); + dev_dbg(&dssdev->dev, "sync\n"); + mutex_lock(&td->lock); dsi_bus_lock(); dsi_bus_unlock(); + mutex_unlock(&td->lock); dev_dbg(&dssdev->dev, "sync done\n"); @@ -861,13 +915,16 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable) static int taal_enable_te(struct omap_dss_device *dssdev, bool enable) { + struct taal_data *td = dev_get_drvdata(&dssdev->dev); int r; + mutex_lock(&td->lock); dsi_bus_lock(); r = _taal_enable_te(dssdev, enable); dsi_bus_unlock(); + mutex_unlock(&td->lock); return r; } @@ -875,7 +932,13 @@ static int taal_enable_te(struct omap_dss_device *dssdev, bool enable) static int taal_get_te(struct omap_dss_device *dssdev) { struct taal_data *td = dev_get_drvdata(&dssdev->dev); - return td->te_enabled; + int r; + + mutex_lock(&td->lock); + r = td->te_enabled; + mutex_unlock(&td->lock); + + return r; } static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate) @@ -885,6 +948,7 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate) dev_dbg(&dssdev->dev, "rotate %d\n", rotate); + mutex_lock(&td->lock); dsi_bus_lock(); if (td->enabled) { @@ -896,16 +960,24 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate) td->rotate = rotate; dsi_bus_unlock(); + mutex_unlock(&td->lock); return 0; err: dsi_bus_unlock(); + mutex_unlock(&td->lock); return r; } static u8 taal_get_rotate(struct omap_dss_device *dssdev) { struct taal_data *td = dev_get_drvdata(&dssdev->dev); - return td->rotate; + int r; + + mutex_lock(&td->lock); + r = td->rotate; + mutex_unlock(&td->lock); + + return r; } static int taal_mirror(struct omap_dss_device *dssdev, bool enable) @@ -915,6 +987,7 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable) dev_dbg(&dssdev->dev, "mirror %d\n", enable); + mutex_lock(&td->lock); dsi_bus_lock(); if (td->enabled) { r = taal_set_addr_mode(td->rotate, enable); @@ -925,23 +998,33 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable) td->mirror = enable; dsi_bus_unlock(); + mutex_unlock(&td->lock); return 0; err: dsi_bus_unlock(); + mutex_unlock(&td->lock); return r; } static bool taal_get_mirror(struct omap_dss_device *dssdev) { struct taal_data *td = dev_get_drvdata(&dssdev->dev); - return td->mirror; + int r; + + mutex_lock(&td->lock); + r = td->mirror; + mutex_unlock(&td->lock); + + return r; } static int taal_run_test(struct omap_dss_device *dssdev, int test_num) { + struct taal_data *td = dev_get_drvdata(&dssdev->dev); u8 id1, id2, id3; int r; + mutex_lock(&td->lock); dsi_bus_lock(); r = taal_dcs_read_1(DCS_GET_ID1, &id1); @@ -955,9 +1038,11 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num) goto err; dsi_bus_unlock(); + mutex_unlock(&td->lock); return 0; err: dsi_bus_unlock(); + mutex_unlock(&td->lock); return r; } @@ -971,12 +1056,16 @@ static int taal_memory_read(struct omap_dss_device *dssdev, unsigned buf_used = 0; struct taal_data *td = dev_get_drvdata(&dssdev->dev); - if (!td->enabled) - return -ENODEV; - if (size < w * h * 3) return -ENOMEM; + mutex_lock(&td->lock); + + if (!td->enabled) { + r = -ENODEV; + goto err1; + } + size = min(w * h * 3, dssdev->panel.timings.x_res * dssdev->panel.timings.y_res * 3); @@ -995,7 +1084,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev, r = dsi_vc_set_max_rx_packet_size(TCH, plen); if (r) - goto err0; + goto err2; while (buf_used < size) { u8 dcs_cmd = first ? 0x2e : 0x3e; @@ -1006,7 +1095,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev, if (r < 0) { dev_err(&dssdev->dev, "read error\n"); - goto err; + goto err3; } buf_used += r; @@ -1020,16 +1109,18 @@ static int taal_memory_read(struct omap_dss_device *dssdev, dev_err(&dssdev->dev, "signal pending, " "aborting memory read\n"); r = -ERESTARTSYS; - goto err; + goto err3; } } r = buf_used; -err: +err3: dsi_vc_set_max_rx_packet_size(TCH, 1); -err0: +err2: dsi_bus_unlock(); +err1: + mutex_unlock(&td->lock); return r; } @@ -1041,8 +1132,12 @@ static void taal_esd_work(struct work_struct *work) u8 state1, state2; int r; - if (!td->enabled) + mutex_lock(&td->lock); + + if (!td->enabled) { + mutex_unlock(&td->lock); return; + } dsi_bus_lock(); @@ -1084,16 +1179,19 @@ static void taal_esd_work(struct work_struct *work) queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD); + mutex_unlock(&td->lock); return; err: dev_err(&dssdev->dev, "performing LCD reset\n"); - taal_disable(dssdev); - taal_enable(dssdev); + taal_power_off(dssdev); + taal_power_on(dssdev); dsi_bus_unlock(); queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD); + + mutex_unlock(&td->lock); } static int taal_set_update_mode(struct omap_dss_device *dssdev, -- cgit v1.2.3 From 6df37271f879f14119a0605549f1a2574e83b4fe Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 10 Mar 2010 18:24:54 +0100 Subject: OMAP: DSS2: Taal: Fix DSI bus locking problem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If omapdss_dsi_display_enable() failed the DSI bus was left locked. Also if the operation failed later omapdss_dsi_display_disable() would get called without holding the bus lock. Signed-off-by: Ville Syrjälä Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-taal.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 1799096a1388..aaf5d308a046 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -702,10 +702,9 @@ static int taal_power_on(struct omap_dss_device *dssdev) return 0; err: - dsi_bus_unlock(); - omapdss_dsi_display_disable(dssdev); err0: + dsi_bus_unlock(); if (dssdev->platform_disable) dssdev->platform_disable(dssdev); -- cgit v1.2.3 From 2b88c5bc310dc7a2bf9341b86e9f01cf05e8769e Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Thu, 15 Apr 2010 16:00:00 +0200 Subject: OMAP: LCD LS037V7DW01: Add Backlight driver support Tested on OMAP3EVM for OMAP3530 and AM/DM 3730. Signed-off-by: Vaibhav Hiremath [tomi.valkeinen@nokia.com: added slab.h include] [tomi.valkeinen@nokia.com: added dependency to BACKLIGHT_CLASS_DEVICE] Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/Kconfig | 1 + .../video/omap2/displays/panel-sharp-ls037v7dw01.c | 78 ++++++++++++++++++++++ 2 files changed, 79 insertions(+) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig index dfb57ee50861..ea8ccd362c22 100644 --- a/drivers/video/omap2/displays/Kconfig +++ b/drivers/video/omap2/displays/Kconfig @@ -10,6 +10,7 @@ config PANEL_GENERIC config PANEL_SHARP_LS037V7DW01 tristate "Sharp LS037V7DW01 LCD Panel" depends on OMAP2_DSS + select BACKLIGHT_CLASS_DEVICE help LCD Panel used in TI's SDP3430 and EVM boards diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c index 8d51a5e6341c..7d9eb2b1f5af 100644 --- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c +++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c @@ -20,10 +20,17 @@ #include #include #include +#include +#include #include +#include #include +struct sharp_data { + struct backlight_device *bl; +}; + static struct omap_video_timings sharp_ls_timings = { .x_res = 480, .y_res = 640, @@ -39,18 +46,89 @@ static struct omap_video_timings sharp_ls_timings = { .vbp = 1, }; +static int sharp_ls_bl_update_status(struct backlight_device *bl) +{ + struct omap_dss_device *dssdev = dev_get_drvdata(&bl->dev); + int level; + + if (!dssdev->set_backlight) + return -EINVAL; + + if (bl->props.fb_blank == FB_BLANK_UNBLANK && + bl->props.power == FB_BLANK_UNBLANK) + level = bl->props.brightness; + else + level = 0; + + return dssdev->set_backlight(dssdev, level); +} + +static int sharp_ls_bl_get_brightness(struct backlight_device *bl) +{ + if (bl->props.fb_blank == FB_BLANK_UNBLANK && + bl->props.power == FB_BLANK_UNBLANK) + return bl->props.brightness; + + return 0; +} + +static const struct backlight_ops sharp_ls_bl_ops = { + .get_brightness = sharp_ls_bl_get_brightness, + .update_status = sharp_ls_bl_update_status, +}; + + + static int sharp_ls_panel_probe(struct omap_dss_device *dssdev) { + struct backlight_properties props; + struct backlight_device *bl; + struct sharp_data *sd; + int r; + dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS; dssdev->panel.acb = 0x28; dssdev->panel.timings = sharp_ls_timings; + sd = kzalloc(sizeof(*sd), GFP_KERNEL); + if (!sd) + return -ENOMEM; + + dev_set_drvdata(&dssdev->dev, sd); + + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = dssdev->max_backlight_level; + + bl = backlight_device_register("sharp-ls", &dssdev->dev, dssdev, + &sharp_ls_bl_ops, &props); + if (IS_ERR(bl)) { + r = PTR_ERR(bl); + kfree(sd); + return r; + } + sd->bl = bl; + + bl->props.fb_blank = FB_BLANK_UNBLANK; + bl->props.power = FB_BLANK_UNBLANK; + bl->props.brightness = dssdev->max_backlight_level; + r = sharp_ls_bl_update_status(bl); + if (r < 0) + dev_err(&dssdev->dev, "failed to set lcd brightness\n"); + return 0; } static void sharp_ls_panel_remove(struct omap_dss_device *dssdev) { + struct sharp_data *sd = dev_get_drvdata(&dssdev->dev); + struct backlight_device *bl = sd->bl; + + bl->props.power = FB_BLANK_POWERDOWN; + sharp_ls_bl_update_status(bl); + backlight_device_unregister(bl); + + kfree(sd); } static int sharp_ls_power_on(struct omap_dss_device *dssdev) -- cgit v1.2.3 From a40458eee7ee60a89f89602067921658b87ded73 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Thu, 15 Apr 2010 16:59:03 +0200 Subject: OMAP: DSS2: TPO-TD03MTEA1: fix Kconfig dependency This panel depends on SPI, not I2C. Signed-off-by: Grazvydas Ignotas Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig index ea8ccd362c22..4221957b0d2c 100644 --- a/drivers/video/omap2/displays/Kconfig +++ b/drivers/video/omap2/displays/Kconfig @@ -34,7 +34,7 @@ config PANEL_TOPPOLY_TDO35S config PANEL_TPO_TD043MTEA1 tristate "TPO TD043MTEA1 LCD Panel" - depends on OMAP2_DSS && I2C + depends on OMAP2_DSS && SPI help LCD Panel used in OMAP3 Pandora -- cgit v1.2.3 From 0188352b2774234575a41864fd0945be42975ee5 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 10 Mar 2010 17:32:44 +0200 Subject: OMAP: DSS2: Add ACX565AKM Panel Driver This is the panel used on Nokia N900 Signed-off-by: Roger Quadros Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/Kconfig | 6 + drivers/video/omap2/displays/Makefile | 1 + drivers/video/omap2/displays/panel-acx565akm.c | 819 +++++++++++++++++++++++++ 3 files changed, 826 insertions(+) create mode 100644 drivers/video/omap2/displays/panel-acx565akm.c (limited to 'drivers') diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig index 4221957b0d2c..881c9f77c75a 100644 --- a/drivers/video/omap2/displays/Kconfig +++ b/drivers/video/omap2/displays/Kconfig @@ -38,4 +38,10 @@ config PANEL_TPO_TD043MTEA1 help LCD Panel used in OMAP3 Pandora +config PANEL_ACX565AKM + tristate "ACX565AKM Panel" + depends on OMAP2_DSS_SDI + select BACKLIGHT_CLASS_DEVICE + help + This is the LCD panel used on Nokia N900 endmenu diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile index e2bb32168dee..aa386095d7c4 100644 --- a/drivers/video/omap2/displays/Makefile +++ b/drivers/video/omap2/displays/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_PANEL_SHARP_LQ043T1DG01) += panel-sharp-lq043t1dg01.o obj-$(CONFIG_PANEL_TAAL) += panel-taal.o obj-$(CONFIG_PANEL_TOPPOLY_TDO35S) += panel-toppoly-tdo35s.o obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o +obj-$(CONFIG_PANEL_ACX565AKM) += panel-acx565akm.o diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c new file mode 100644 index 000000000000..1f8eb70e2937 --- /dev/null +++ b/drivers/video/omap2/displays/panel-acx565akm.c @@ -0,0 +1,819 @@ +/* + * Support for ACX565AKM LCD Panel used on Nokia N900 + * + * Copyright (C) 2010 Nokia Corporation + * + * Original Driver Author: Imre Deak + * Based on panel-generic.c by Tomi Valkeinen + * Adapted to new DSS2 framework: Roger Quadros + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MIPID_CMD_READ_DISP_ID 0x04 +#define MIPID_CMD_READ_RED 0x06 +#define MIPID_CMD_READ_GREEN 0x07 +#define MIPID_CMD_READ_BLUE 0x08 +#define MIPID_CMD_READ_DISP_STATUS 0x09 +#define MIPID_CMD_RDDSDR 0x0F +#define MIPID_CMD_SLEEP_IN 0x10 +#define MIPID_CMD_SLEEP_OUT 0x11 +#define MIPID_CMD_DISP_OFF 0x28 +#define MIPID_CMD_DISP_ON 0x29 +#define MIPID_CMD_WRITE_DISP_BRIGHTNESS 0x51 +#define MIPID_CMD_READ_DISP_BRIGHTNESS 0x52 +#define MIPID_CMD_WRITE_CTRL_DISP 0x53 + +#define CTRL_DISP_BRIGHTNESS_CTRL_ON (1 << 5) +#define CTRL_DISP_AMBIENT_LIGHT_CTRL_ON (1 << 4) +#define CTRL_DISP_BACKLIGHT_ON (1 << 2) +#define CTRL_DISP_AUTO_BRIGHTNESS_ON (1 << 1) + +#define MIPID_CMD_READ_CTRL_DISP 0x54 +#define MIPID_CMD_WRITE_CABC 0x55 +#define MIPID_CMD_READ_CABC 0x56 + +#define MIPID_VER_LPH8923 3 +#define MIPID_VER_LS041Y3 4 +#define MIPID_VER_L4F00311 8 +#define MIPID_VER_ACX565AKM 9 + +struct acx565akm_device { + char *name; + int enabled; + int model; + int revision; + u8 display_id[3]; + unsigned has_bc:1; + unsigned has_cabc:1; + unsigned cabc_mode; + unsigned long hw_guard_end; /* next value of jiffies + when we can issue the + next sleep in/out command */ + unsigned long hw_guard_wait; /* max guard time in jiffies */ + + struct spi_device *spi; + struct mutex mutex; + + struct omap_dss_device *dssdev; + struct backlight_device *bl_dev; +}; + +static struct acx565akm_device acx_dev; +static int acx565akm_bl_update_status(struct backlight_device *dev); + +/*--------------------MIPID interface-----------------------------*/ + +static void acx565akm_transfer(struct acx565akm_device *md, int cmd, + const u8 *wbuf, int wlen, u8 *rbuf, int rlen) +{ + struct spi_message m; + struct spi_transfer *x, xfer[5]; + int r; + + BUG_ON(md->spi == NULL); + + spi_message_init(&m); + + memset(xfer, 0, sizeof(xfer)); + x = &xfer[0]; + + cmd &= 0xff; + x->tx_buf = &cmd; + x->bits_per_word = 9; + x->len = 2; + + if (rlen > 1 && wlen == 0) { + /* + * Between the command and the response data there is a + * dummy clock cycle. Add an extra bit after the command + * word to account for this. + */ + x->bits_per_word = 10; + cmd <<= 1; + } + spi_message_add_tail(x, &m); + + if (wlen) { + x++; + x->tx_buf = wbuf; + x->len = wlen; + x->bits_per_word = 9; + spi_message_add_tail(x, &m); + } + + if (rlen) { + x++; + x->rx_buf = rbuf; + x->len = rlen; + spi_message_add_tail(x, &m); + } + + r = spi_sync(md->spi, &m); + if (r < 0) + dev_dbg(&md->spi->dev, "spi_sync %d\n", r); +} + +static inline void acx565akm_cmd(struct acx565akm_device *md, int cmd) +{ + acx565akm_transfer(md, cmd, NULL, 0, NULL, 0); +} + +static inline void acx565akm_write(struct acx565akm_device *md, + int reg, const u8 *buf, int len) +{ + acx565akm_transfer(md, reg, buf, len, NULL, 0); +} + +static inline void acx565akm_read(struct acx565akm_device *md, + int reg, u8 *buf, int len) +{ + acx565akm_transfer(md, reg, NULL, 0, buf, len); +} + +static void hw_guard_start(struct acx565akm_device *md, int guard_msec) +{ + md->hw_guard_wait = msecs_to_jiffies(guard_msec); + md->hw_guard_end = jiffies + md->hw_guard_wait; +} + +static void hw_guard_wait(struct acx565akm_device *md) +{ + unsigned long wait = md->hw_guard_end - jiffies; + + if ((long)wait > 0 && wait <= md->hw_guard_wait) { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(wait); + } +} + +/*----------------------MIPID wrappers----------------------------*/ + +static void set_sleep_mode(struct acx565akm_device *md, int on) +{ + int cmd; + + if (on) + cmd = MIPID_CMD_SLEEP_IN; + else + cmd = MIPID_CMD_SLEEP_OUT; + /* + * We have to keep 120msec between sleep in/out commands. + * (8.2.15, 8.2.16). + */ + hw_guard_wait(md); + acx565akm_cmd(md, cmd); + hw_guard_start(md, 120); +} + +static void set_display_state(struct acx565akm_device *md, int enabled) +{ + int cmd = enabled ? MIPID_CMD_DISP_ON : MIPID_CMD_DISP_OFF; + + acx565akm_cmd(md, cmd); +} + +static int panel_enabled(struct acx565akm_device *md) +{ + u32 disp_status; + int enabled; + + acx565akm_read(md, MIPID_CMD_READ_DISP_STATUS, (u8 *)&disp_status, 4); + disp_status = __be32_to_cpu(disp_status); + enabled = (disp_status & (1 << 17)) && (disp_status & (1 << 10)); + dev_dbg(&md->spi->dev, + "LCD panel %senabled by bootloader (status 0x%04x)\n", + enabled ? "" : "not ", disp_status); + return enabled; +} + +static int panel_detect(struct acx565akm_device *md) +{ + acx565akm_read(md, MIPID_CMD_READ_DISP_ID, md->display_id, 3); + dev_dbg(&md->spi->dev, "MIPI display ID: %02x%02x%02x\n", + md->display_id[0], md->display_id[1], md->display_id[2]); + + switch (md->display_id[0]) { + case 0x10: + md->model = MIPID_VER_ACX565AKM; + md->name = "acx565akm"; + md->has_bc = 1; + md->has_cabc = 1; + break; + case 0x29: + md->model = MIPID_VER_L4F00311; + md->name = "l4f00311"; + break; + case 0x45: + md->model = MIPID_VER_LPH8923; + md->name = "lph8923"; + break; + case 0x83: + md->model = MIPID_VER_LS041Y3; + md->name = "ls041y3"; + break; + default: + md->name = "unknown"; + dev_err(&md->spi->dev, "invalid display ID\n"); + return -ENODEV; + } + + md->revision = md->display_id[1]; + + dev_info(&md->spi->dev, "omapfb: %s rev %02x LCD detected\n", + md->name, md->revision); + + return 0; +} + +/*----------------------Backlight Control-------------------------*/ + +static void enable_backlight_ctrl(struct acx565akm_device *md, int enable) +{ + u16 ctrl; + + acx565akm_read(md, MIPID_CMD_READ_CTRL_DISP, (u8 *)&ctrl, 1); + if (enable) { + ctrl |= CTRL_DISP_BRIGHTNESS_CTRL_ON | + CTRL_DISP_BACKLIGHT_ON; + } else { + ctrl &= ~(CTRL_DISP_BRIGHTNESS_CTRL_ON | + CTRL_DISP_BACKLIGHT_ON); + } + + ctrl |= 1 << 8; + acx565akm_write(md, MIPID_CMD_WRITE_CTRL_DISP, (u8 *)&ctrl, 2); +} + +static void set_cabc_mode(struct acx565akm_device *md, unsigned mode) +{ + u16 cabc_ctrl; + + md->cabc_mode = mode; + if (!md->enabled) + return; + cabc_ctrl = 0; + acx565akm_read(md, MIPID_CMD_READ_CABC, (u8 *)&cabc_ctrl, 1); + cabc_ctrl &= ~3; + cabc_ctrl |= (1 << 8) | (mode & 3); + acx565akm_write(md, MIPID_CMD_WRITE_CABC, (u8 *)&cabc_ctrl, 2); +} + +static unsigned get_cabc_mode(struct acx565akm_device *md) +{ + return md->cabc_mode; +} + +static unsigned get_hw_cabc_mode(struct acx565akm_device *md) +{ + u8 cabc_ctrl; + + acx565akm_read(md, MIPID_CMD_READ_CABC, &cabc_ctrl, 1); + return cabc_ctrl & 3; +} + +static void acx565akm_set_brightness(struct acx565akm_device *md, int level) +{ + int bv; + + bv = level | (1 << 8); + acx565akm_write(md, MIPID_CMD_WRITE_DISP_BRIGHTNESS, (u8 *)&bv, 2); + + if (level) + enable_backlight_ctrl(md, 1); + else + enable_backlight_ctrl(md, 0); +} + +static int acx565akm_get_actual_brightness(struct acx565akm_device *md) +{ + u8 bv; + + acx565akm_read(md, MIPID_CMD_READ_DISP_BRIGHTNESS, &bv, 1); + + return bv; +} + + +static int acx565akm_bl_update_status(struct backlight_device *dev) +{ + struct acx565akm_device *md = dev_get_drvdata(&dev->dev); + int r; + int level; + + dev_dbg(&md->spi->dev, "%s\n", __func__); + + mutex_lock(&md->mutex); + + if (dev->props.fb_blank == FB_BLANK_UNBLANK && + dev->props.power == FB_BLANK_UNBLANK) + level = dev->props.brightness; + else + level = 0; + + r = 0; + if (md->has_bc) + acx565akm_set_brightness(md, level); + else if (md->dssdev->set_backlight) + r = md->dssdev->set_backlight(md->dssdev, level); + else + r = -ENODEV; + + mutex_unlock(&md->mutex); + + return r; +} + +static int acx565akm_bl_get_intensity(struct backlight_device *dev) +{ + struct acx565akm_device *md = dev_get_drvdata(&dev->dev); + + dev_dbg(&dev->dev, "%s\n", __func__); + + if (!md->has_bc && md->dssdev->set_backlight == NULL) + return -ENODEV; + + if (dev->props.fb_blank == FB_BLANK_UNBLANK && + dev->props.power == FB_BLANK_UNBLANK) { + if (md->has_bc) + return acx565akm_get_actual_brightness(md); + else + return dev->props.brightness; + } + + return 0; +} + +static const struct backlight_ops acx565akm_bl_ops = { + .get_brightness = acx565akm_bl_get_intensity, + .update_status = acx565akm_bl_update_status, +}; + +/*--------------------Auto Brightness control via Sysfs---------------------*/ + +static const char *cabc_modes[] = { + "off", /* always used when CABC is not supported */ + "ui", + "still-image", + "moving-image", +}; + +static ssize_t show_cabc_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acx565akm_device *md = dev_get_drvdata(dev); + const char *mode_str; + int mode; + int len; + + if (!md->has_cabc) + mode = 0; + else + mode = get_cabc_mode(md); + mode_str = "unknown"; + if (mode >= 0 && mode < ARRAY_SIZE(cabc_modes)) + mode_str = cabc_modes[mode]; + len = snprintf(buf, PAGE_SIZE, "%s\n", mode_str); + + return len < PAGE_SIZE - 1 ? len : PAGE_SIZE - 1; +} + +static ssize_t store_cabc_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct acx565akm_device *md = dev_get_drvdata(dev); + int i; + + for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) { + const char *mode_str = cabc_modes[i]; + int cmp_len = strlen(mode_str); + + if (count > 0 && buf[count - 1] == '\n') + count--; + if (count != cmp_len) + continue; + + if (strncmp(buf, mode_str, cmp_len) == 0) + break; + } + + if (i == ARRAY_SIZE(cabc_modes)) + return -EINVAL; + + if (!md->has_cabc && i != 0) + return -EINVAL; + + mutex_lock(&md->mutex); + set_cabc_mode(md, i); + mutex_unlock(&md->mutex); + + return count; +} + +static ssize_t show_cabc_available_modes(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acx565akm_device *md = dev_get_drvdata(dev); + int len; + int i; + + if (!md->has_cabc) + return snprintf(buf, PAGE_SIZE, "%s\n", cabc_modes[0]); + + for (i = 0, len = 0; + len < PAGE_SIZE && i < ARRAY_SIZE(cabc_modes); i++) + len += snprintf(&buf[len], PAGE_SIZE - len, "%s%s%s", + i ? " " : "", cabc_modes[i], + i == ARRAY_SIZE(cabc_modes) - 1 ? "\n" : ""); + + return len < PAGE_SIZE ? len : PAGE_SIZE - 1; +} + +static DEVICE_ATTR(cabc_mode, S_IRUGO | S_IWUSR, + show_cabc_mode, store_cabc_mode); +static DEVICE_ATTR(cabc_available_modes, S_IRUGO, + show_cabc_available_modes, NULL); + +static struct attribute *bldev_attrs[] = { + &dev_attr_cabc_mode.attr, + &dev_attr_cabc_available_modes.attr, + NULL, +}; + +static struct attribute_group bldev_attr_group = { + .attrs = bldev_attrs, +}; + + +/*---------------------------ACX Panel----------------------------*/ + +static int acx_get_recommended_bpp(struct omap_dss_device *dssdev) +{ + return 16; +} + +static struct omap_video_timings acx_panel_timings = { + .x_res = 800, + .y_res = 480, + .pixel_clock = 24000, + .hfp = 28, + .hsw = 4, + .hbp = 24, + .vfp = 3, + .vsw = 3, + .vbp = 4, +}; + +static int acx_panel_probe(struct omap_dss_device *dssdev) +{ + int r; + struct acx565akm_device *md = &acx_dev; + struct backlight_device *bldev; + int max_brightness, brightness; + struct backlight_properties props; + + dev_dbg(&dssdev->dev, "%s\n", __func__); + dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | + OMAP_DSS_LCD_IHS; + /* FIXME AC bias ? */ + dssdev->panel.timings = acx_panel_timings; + + if (dssdev->platform_enable) + dssdev->platform_enable(dssdev); + /* + * After reset we have to wait 5 msec before the first + * command can be sent. + */ + msleep(5); + + md->enabled = panel_enabled(md); + + r = panel_detect(md); + if (r) { + dev_err(&dssdev->dev, "%s panel detect error\n", __func__); + if (!md->enabled && dssdev->platform_disable) + dssdev->platform_disable(dssdev); + return r; + } + + mutex_lock(&acx_dev.mutex); + acx_dev.dssdev = dssdev; + mutex_unlock(&acx_dev.mutex); + + if (!md->enabled) { + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + } + + /*------- Backlight control --------*/ + + props.fb_blank = FB_BLANK_UNBLANK; + props.power = FB_BLANK_UNBLANK; + + bldev = backlight_device_register("acx565akm", &md->spi->dev, + md, &acx565akm_bl_ops, &props); + md->bl_dev = bldev; + if (md->has_cabc) { + r = sysfs_create_group(&bldev->dev.kobj, &bldev_attr_group); + if (r) { + dev_err(&bldev->dev, + "%s failed to create sysfs files\n", __func__); + backlight_device_unregister(bldev); + return r; + } + md->cabc_mode = get_hw_cabc_mode(md); + } + + if (md->has_bc) + max_brightness = 255; + else + max_brightness = dssdev->max_backlight_level; + + if (md->has_bc) + brightness = acx565akm_get_actual_brightness(md); + else if (dssdev->get_backlight) + brightness = dssdev->get_backlight(dssdev); + else + brightness = 0; + + bldev->props.max_brightness = max_brightness; + bldev->props.brightness = brightness; + + acx565akm_bl_update_status(bldev); + return 0; +} + +static void acx_panel_remove(struct omap_dss_device *dssdev) +{ + struct acx565akm_device *md = &acx_dev; + + dev_dbg(&dssdev->dev, "%s\n", __func__); + sysfs_remove_group(&md->bl_dev->dev.kobj, &bldev_attr_group); + backlight_device_unregister(md->bl_dev); + mutex_lock(&acx_dev.mutex); + acx_dev.dssdev = NULL; + mutex_unlock(&acx_dev.mutex); +} + +static int acx_panel_power_on(struct omap_dss_device *dssdev) +{ + struct acx565akm_device *md = &acx_dev; + int r; + + dev_dbg(&dssdev->dev, "%s\n", __func__); + + mutex_lock(&md->mutex); + + r = omapdss_sdi_display_enable(dssdev); + if (r) { + pr_err("%s sdi enable failed\n", __func__); + return r; + } + + /*FIXME tweak me */ + msleep(50); + + if (dssdev->platform_enable) { + r = dssdev->platform_enable(dssdev); + if (r) + goto fail; + } + + if (md->enabled) { + dev_dbg(&md->spi->dev, "panel already enabled\n"); + mutex_unlock(&md->mutex); + return 0; + } + + /* + * We have to meet all the following delay requirements: + * 1. tRW: reset pulse width 10usec (7.12.1) + * 2. tRT: reset cancel time 5msec (7.12.1) + * 3. Providing PCLK,HS,VS signals for 2 frames = ~50msec worst + * case (7.6.2) + * 4. 120msec before the sleep out command (7.12.1) + */ + msleep(120); + + set_sleep_mode(md, 0); + md->enabled = 1; + + /* 5msec between sleep out and the next command. (8.2.16) */ + msleep(5); + set_display_state(md, 1); + set_cabc_mode(md, md->cabc_mode); + + mutex_unlock(&md->mutex); + + return acx565akm_bl_update_status(md->bl_dev); +fail: + omapdss_sdi_display_disable(dssdev); + return r; +} + +static void acx_panel_power_off(struct omap_dss_device *dssdev) +{ + struct acx565akm_device *md = &acx_dev; + + dev_dbg(&dssdev->dev, "%s\n", __func__); + + mutex_lock(&md->mutex); + + if (!md->enabled) { + mutex_unlock(&md->mutex); + return; + } + set_display_state(md, 0); + set_sleep_mode(md, 1); + md->enabled = 0; + /* + * We have to provide PCLK,HS,VS signals for 2 frames (worst case + * ~50msec) after sending the sleep in command and asserting the + * reset signal. We probably could assert the reset w/o the delay + * but we still delay to avoid possible artifacts. (7.6.1) + */ + msleep(50); + + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + + /* FIXME need to tweak this delay */ + msleep(100); + + omapdss_sdi_display_disable(dssdev); + + mutex_unlock(&md->mutex); +} + +static int acx_panel_enable(struct omap_dss_device *dssdev) +{ + int r; + + dev_dbg(&dssdev->dev, "%s\n", __func__); + r = acx_panel_power_on(dssdev); + + if (r) + return r; + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + return 0; +} + +static void acx_panel_disable(struct omap_dss_device *dssdev) +{ + dev_dbg(&dssdev->dev, "%s\n", __func__); + acx_panel_power_off(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; +} + +static int acx_panel_suspend(struct omap_dss_device *dssdev) +{ + dev_dbg(&dssdev->dev, "%s\n", __func__); + acx_panel_power_off(dssdev); + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; + return 0; +} + +static int acx_panel_resume(struct omap_dss_device *dssdev) +{ + int r; + + dev_dbg(&dssdev->dev, "%s\n", __func__); + r = acx_panel_power_on(dssdev); + if (r) + return r; + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + return 0; +} + +static void acx_panel_set_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + int r; + + if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) + omapdss_sdi_display_disable(dssdev); + + dssdev->panel.timings = *timings; + + if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { + r = omapdss_sdi_display_enable(dssdev); + if (r) + dev_err(&dssdev->dev, "%s enable failed\n", __func__); + } +} + +static void acx_panel_get_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + *timings = dssdev->panel.timings; +} + +static int acx_panel_check_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + return 0; +} + + +static struct omap_dss_driver acx_panel_driver = { + .probe = acx_panel_probe, + .remove = acx_panel_remove, + + .enable = acx_panel_enable, + .disable = acx_panel_disable, + .suspend = acx_panel_suspend, + .resume = acx_panel_resume, + + .set_timings = acx_panel_set_timings, + .get_timings = acx_panel_get_timings, + .check_timings = acx_panel_check_timings, + + .get_recommended_bpp = acx_get_recommended_bpp, + + .driver = { + .name = "panel-acx565akm", + .owner = THIS_MODULE, + }, +}; + +/*--------------------SPI probe-------------------------*/ + +static int acx565akm_spi_probe(struct spi_device *spi) +{ + struct acx565akm_device *md = &acx_dev; + + dev_dbg(&spi->dev, "%s\n", __func__); + + spi->mode = SPI_MODE_3; + md->spi = spi; + mutex_init(&md->mutex); + dev_set_drvdata(&spi->dev, md); + + omap_dss_register_driver(&acx_panel_driver); + + return 0; +} + +static int acx565akm_spi_remove(struct spi_device *spi) +{ + struct acx565akm_device *md = dev_get_drvdata(&spi->dev); + + dev_dbg(&md->spi->dev, "%s\n", __func__); + omap_dss_unregister_driver(&acx_panel_driver); + + return 0; +} + +static struct spi_driver acx565akm_spi_driver = { + .driver = { + .name = "acx565akm", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = acx565akm_spi_probe, + .remove = __devexit_p(acx565akm_spi_remove), +}; + +static int __init acx565akm_init(void) +{ + return spi_register_driver(&acx565akm_spi_driver); +} + +static void __exit acx565akm_exit(void) +{ + spi_unregister_driver(&acx565akm_spi_driver); +} + +module_init(acx565akm_init); +module_exit(acx565akm_exit); + +MODULE_AUTHOR("Nokia Corporation"); +MODULE_DESCRIPTION("acx565akm LCD Driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From ac01bb7ea06a02c8dc9084b4ed59cb59efeceb39 Mon Sep 17 00:00:00 2001 From: Kishore Y Date: Sun, 25 Apr 2010 16:27:19 +0530 Subject: OMAP3630: DSS2: Updating MAX divider value In DPLL4 M3, M4, M5 and M6 field width has been increased by 1 bit in 3630. So the max divider value that can be achived will be 32 and not 16. In 3630 the functional clock is x1 of DPLL4 and not x2. Hence multiplier 2 is removed. Signed-off-by: Sudeep Basavaraj Signed-off-by: Mukund Mittal Signed-off-by: Kishore Y Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dss.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 54344184dd73..24b18258654f 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -223,7 +223,13 @@ void dss_dump_clocks(struct seq_file *s) seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate); - seq_printf(s, "dss1_alwon_fclk = %lu / %lu * 2 = %lu\n", + if (cpu_is_omap3630()) + seq_printf(s, "dss1_alwon_fclk = %lu / %lu = %lu\n", + dpll4_ck_rate, + dpll4_ck_rate / dpll4_m4_ck_rate, + dss_clk_get_rate(DSS_CLK_FCK1)); + else + seq_printf(s, "dss1_alwon_fclk = %lu / %lu * 2 = %lu\n", dpll4_ck_rate, dpll4_ck_rate / dpll4_m4_ck_rate, dss_clk_get_rate(DSS_CLK_FCK1)); @@ -293,7 +299,8 @@ int dss_calc_clock_rates(struct dss_clock_info *cinfo) { unsigned long prate; - if (cinfo->fck_div > 16 || cinfo->fck_div == 0) + if (cinfo->fck_div > (cpu_is_omap3630() ? 32 : 16) || + cinfo->fck_div == 0) return -EINVAL; prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); @@ -329,7 +336,10 @@ int dss_get_clock_div(struct dss_clock_info *cinfo) if (cpu_is_omap34xx()) { unsigned long prate; prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); - cinfo->fck_div = prate / (cinfo->fck / 2); + if (cpu_is_omap3630()) + cinfo->fck_div = prate / (cinfo->fck); + else + cinfo->fck_div = prate / (cinfo->fck / 2); } else { cinfo->fck_div = 0; } @@ -402,10 +412,14 @@ retry: goto found; } else if (cpu_is_omap34xx()) { - for (fck_div = 16; fck_div > 0; --fck_div) { + for (fck_div = (cpu_is_omap3630() ? 32 : 16); + fck_div > 0; --fck_div) { struct dispc_clock_info cur_dispc; - fck = prate / fck_div * 2; + if (cpu_is_omap3630()) + fck = prate / fck_div; + else + fck = prate / fck_div * 2; if (fck > DISPC_MAX_FCK) continue; -- cgit v1.2.3 From a3bb67a75c0fe5c48def0fd39d2fe9ec043241d4 Mon Sep 17 00:00:00 2001 From: Carlos Lopez Date: Sun, 25 Apr 2010 12:53:35 +0200 Subject: OMAP2: DSS: Add missing line for update bg color The driver set the background color canvas but never writes it in DISPC_DEFAULT_COLOR_m register, which changes the background color on the LCD or TV. This patch adds a line to call to dispc_set_default_color() which is the function in charge to write the DISPC_DEFAULT_COLOR_m register. Signed-off-by: Carlos Lopez Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/manager.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 32ec2ff2e9cf..9e1fbe531bf0 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -843,6 +843,7 @@ static void configure_manager(enum omap_channel channel) c = &dss_cache.manager_cache[channel]; + dispc_set_default_color(channel, c->default_color); dispc_set_trans_key(channel, c->trans_key_type, c->trans_key); dispc_enable_trans_key(channel, c->trans_enabled); dispc_enable_alpha_blending(channel, c->alpha_enabled); -- cgit v1.2.3 From 368a148ea3833b540945fa53a63227c8ce76aa8f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 7 May 2010 11:58:41 +0200 Subject: OMAP: DSS2: omap_dss_probe() conditional compilation cleanup Move a number of #ifdefs from code into dss.h and elsewhere, and conditionally define no-op static inline functions, cleaning up the code. This style is according to Documentation/SubmittingPatches. Signed-off-by: Jani Nikula Acked-by: Kevin Hilman Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 35 ++++++++++------------------- drivers/video/omap2/dss/dss.h | 50 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 6d54467e5e20..92ee06742ece 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -482,6 +482,14 @@ static void dss_uninitialize_debugfs(void) if (dss_debugfs_dir) debugfs_remove_recursive(dss_debugfs_dir); } +#else /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */ +static inline int dss_initialize_debugfs(void) +{ + return 0; +} +static inline void dss_uninitialize_debugfs(void) +{ +} #endif /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */ /* PLATFORM DEVICE */ @@ -518,56 +526,47 @@ static int omap_dss_probe(struct platform_device *pdev) goto fail0; } -#ifdef CONFIG_OMAP2_DSS_RFBI r = rfbi_init(); if (r) { DSSERR("Failed to initialize rfbi\n"); goto fail0; } -#endif -#ifdef CONFIG_OMAP2_DSS_DPI r = dpi_init(pdev); if (r) { DSSERR("Failed to initialize dpi\n"); goto fail0; } -#endif r = dispc_init(); if (r) { DSSERR("Failed to initialize dispc\n"); goto fail0; } -#ifdef CONFIG_OMAP2_DSS_VENC + r = venc_init(pdev); if (r) { DSSERR("Failed to initialize venc\n"); goto fail0; } -#endif + if (cpu_is_omap34xx()) { -#ifdef CONFIG_OMAP2_DSS_SDI r = sdi_init(skip_init); if (r) { DSSERR("Failed to initialize SDI\n"); goto fail0; } -#endif -#ifdef CONFIG_OMAP2_DSS_DSI + r = dsi_init(pdev); if (r) { DSSERR("Failed to initialize DSI\n"); goto fail0; } -#endif } -#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) r = dss_initialize_debugfs(); if (r) goto fail0; -#endif for (i = 0; i < pdata->num_devices; ++i) { struct omap_dss_device *dssdev = pdata->devices[i]; @@ -595,27 +594,15 @@ static int omap_dss_remove(struct platform_device *pdev) int i; int c; -#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) dss_uninitialize_debugfs(); -#endif -#ifdef CONFIG_OMAP2_DSS_VENC venc_exit(); -#endif dispc_exit(); -#ifdef CONFIG_OMAP2_DSS_DPI dpi_exit(); -#endif -#ifdef CONFIG_OMAP2_DSS_RFBI rfbi_exit(); -#endif if (cpu_is_omap34xx()) { -#ifdef CONFIG_OMAP2_DSS_DSI dsi_exit(); -#endif -#ifdef CONFIG_OMAP2_DSS_SDI sdi_exit(); -#endif } dss_exit(); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 24326a5fd292..786f433fd571 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -242,11 +242,22 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck, struct dispc_clock_info *dispc_cinfo); /* SDI */ +#ifdef CONFIG_OMAP2_DSS_SDI int sdi_init(bool skip_init); void sdi_exit(void); int sdi_init_display(struct omap_dss_device *display); +#else +static inline int sdi_init(bool skip_init) +{ + return 0; +} +static inline void sdi_exit(void) +{ +} +#endif /* DSI */ +#ifdef CONFIG_OMAP2_DSS_DSI int dsi_init(struct platform_device *pdev); void dsi_exit(void); @@ -270,11 +281,30 @@ void dsi_pll_uninit(void); void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, u32 fifo_size, enum omap_burst_size *burst_size, u32 *fifo_low, u32 *fifo_high); +#else +static inline int dsi_init(struct platform_device *pdev) +{ + return 0; +} +static inline void dsi_exit(void) +{ +} +#endif /* DPI */ +#ifdef CONFIG_OMAP2_DSS_DPI int dpi_init(struct platform_device *pdev); void dpi_exit(void); int dpi_init_display(struct omap_dss_device *dssdev); +#else +static inline int dpi_init(struct platform_device *pdev) +{ + return 0; +} +static inline void dpi_exit(void) +{ +} +#endif /* DISPC */ int dispc_init(void); @@ -362,12 +392,23 @@ int dispc_get_clock_div(struct dispc_clock_info *cinfo); /* VENC */ +#ifdef CONFIG_OMAP2_DSS_VENC int venc_init(struct platform_device *pdev); void venc_exit(void); void venc_dump_regs(struct seq_file *s); int venc_init_display(struct omap_dss_device *display); +#else +static inline int venc_init(struct platform_device *pdev) +{ + return 0; +} +static inline void venc_exit(void) +{ +} +#endif /* RFBI */ +#ifdef CONFIG_OMAP2_DSS_RFBI int rfbi_init(void); void rfbi_exit(void); void rfbi_dump_regs(struct seq_file *s); @@ -379,6 +420,15 @@ void rfbi_transfer_area(u16 width, u16 height, void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t); unsigned long rfbi_get_max_tx_rate(void); int rfbi_init_display(struct omap_dss_device *display); +#else +static inline int rfbi_init(void) +{ + return 0; +} +static inline void rfbi_exit(void) +{ +} +#endif #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS -- cgit v1.2.3 From fce064cbda85dda330150e8d4d9f6db1a3300023 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 7 May 2010 11:58:42 +0200 Subject: OMAP: DSS2: Fix omap_dss_probe() error path Perform graceful cleanup on errors instead of just bailing out. Signed-off-by: Jani Nikula Tested-by: Kevin Hilman Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 54 ++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 92ee06742ece..b3a498f22d36 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -507,7 +507,7 @@ static int omap_dss_probe(struct platform_device *pdev) r = dss_get_clocks(); if (r) - goto fail0; + goto err_clocks; dss_clk_enable_all_no_ctx(); @@ -523,57 +523,64 @@ static int omap_dss_probe(struct platform_device *pdev) r = dss_init(skip_init); if (r) { DSSERR("Failed to initialize DSS\n"); - goto fail0; + goto err_dss; } r = rfbi_init(); if (r) { DSSERR("Failed to initialize rfbi\n"); - goto fail0; + goto err_rfbi; } r = dpi_init(pdev); if (r) { DSSERR("Failed to initialize dpi\n"); - goto fail0; + goto err_dpi; } r = dispc_init(); if (r) { DSSERR("Failed to initialize dispc\n"); - goto fail0; + goto err_dispc; } r = venc_init(pdev); if (r) { DSSERR("Failed to initialize venc\n"); - goto fail0; + goto err_venc; } if (cpu_is_omap34xx()) { r = sdi_init(skip_init); if (r) { DSSERR("Failed to initialize SDI\n"); - goto fail0; + goto err_sdi; } r = dsi_init(pdev); if (r) { DSSERR("Failed to initialize DSI\n"); - goto fail0; + goto err_dsi; } } r = dss_initialize_debugfs(); if (r) - goto fail0; + goto err_debugfs; for (i = 0; i < pdata->num_devices; ++i) { struct omap_dss_device *dssdev = pdata->devices[i]; r = omap_dss_register_device(dssdev); - if (r) - DSSERR("device reg failed %d\n", i); + if (r) { + DSSERR("device %d %s register failed %d\n", i, + dssdev->name ?: "unnamed", r); + + while (--i >= 0) + omap_dss_unregister_device(pdata->devices[i]); + + goto err_register; + } if (def_disp_name && strcmp(def_disp_name, dssdev->name) == 0) pdata->default_device = dssdev; @@ -583,8 +590,29 @@ static int omap_dss_probe(struct platform_device *pdev) return 0; - /* XXX fail correctly */ -fail0: +err_register: + dss_uninitialize_debugfs(); +err_debugfs: + if (cpu_is_omap34xx()) + dsi_exit(); +err_dsi: + if (cpu_is_omap34xx()) + sdi_exit(); +err_sdi: + venc_exit(); +err_venc: + dispc_exit(); +err_dispc: + dpi_exit(); +err_dpi: + rfbi_exit(); +err_rfbi: + dss_exit(); +err_dss: + dss_clk_disable_all_no_ctx(); + dss_put_clocks(); +err_clocks: + return r; } -- cgit v1.2.3 From 71753e0141a220ecbf9c71a66e0a8acce9705fb5 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 9 Dec 2009 16:55:15 -0300 Subject: EDAC: add __init to i7core_xeon_pci_fixup It's called only from an __init function and is the only user of pcibios_scan_specific_bus which will be marked as __devinit in the next patch. Signed-off-by: Jiri Slaby Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 4d6ecf1291b8..37ade251e9e2 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1170,7 +1170,7 @@ static void i7core_put_all_devices(void) i7core_put_devices(i7core_dev); } -static void i7core_xeon_pci_fixup(int dev_id) +static void __init i7core_xeon_pci_fixup(int dev_id) { struct pci_dev *pdev = NULL; int i; -- cgit v1.2.3 From 2a6fae326713ec84f307c045f6b497d4afaeb1d4 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Thu, 7 Jan 2010 23:27:30 -0300 Subject: i7core_edac: fix memory leak of i7core_dev Free already allocated i7core_dev. Signed-off-by: Alexander Beregalov Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 37ade251e9e2..8e93df637bca 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1249,8 +1249,10 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno, return -ENOMEM; i7core_dev->pdev = kzalloc(sizeof(*i7core_dev->pdev) * n_devs, GFP_KERNEL); - if (!i7core_dev->pdev) + if (!i7core_dev->pdev) { + kfree(i7core_dev); return -ENOMEM; + } i7core_dev->socket = socket; i7core_dev->n_devs = n_devs; list_add_tail(&i7core_dev->list, &i7core_edac_list); -- cgit v1.2.3 From 8a311e179e52d122ac203d8e88014284c18ca8ab Mon Sep 17 00:00:00 2001 From: Vernon Mauery Date: Fri, 16 Apr 2010 19:40:19 -0300 Subject: Always call i7core_[ur]dimm_check_mc_ecc_err This fixes an error in function i7core_check_error In commit ca9c90ba09ca3c9799319f46a56f397afbf617c2 which converts the driver to use double buffering, there is a change in the logic. Before, if mce_count was zero, it skipped over a couple of statements and finished out with a call to the *check_mc_ecc_err function. The current code checks to see if mce_count is 0 and then exits. This change reverts the behavior back to the original where if there are no errors to report, we skip to the end and call the *check_mc_ecc_err function. This fix allows the driver to work again on my Nehalem based blades again. Signed-off-by: Vernon Mauery Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 8e93df637bca..cd51709c4d89 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1670,7 +1670,7 @@ static void i7core_check_error(struct mem_ctl_info *mci) count = (pvt->mce_out + MCE_LOG_LEN - pvt->mce_in) % MCE_LOG_LEN; if (!count) - return; + goto check_ce_error; m = pvt->mce_outentry; if (pvt->mce_in + count > MCE_LOG_LEN) { @@ -1703,6 +1703,7 @@ static void i7core_check_error(struct mem_ctl_info *mci) /* * Now, let's increment CE error counts */ +check_ce_error: if (!pvt->is_registered) i7core_udimm_check_mc_ecc_err(mci); else -- cgit v1.2.3 From a1e50fd4452b2ed57376ece465a17276b59fad9c Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Mon, 17 May 2010 23:46:45 +0400 Subject: power_supply: Add test_power driver Just a handy driver that is used for testing purposes. Signed-off-by: Anton Vorontsov --- drivers/power/Kconfig | 5 ++ drivers/power/Makefile | 1 + drivers/power/test_power.c | 163 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 drivers/power/test_power.c (limited to 'drivers') diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index c59bcb7c6eb0..8e9ba177d817 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -57,6 +57,11 @@ config WM8350_POWER Say Y here to enable support for the power management unit provided by the Wolfson Microelectronics WM8350 PMIC. +config TEST_POWER + tristate "Test power driver" + help + This driver is used for testing. It's safe to say M here. + config BATTERY_DS2760 tristate "DS2760 battery driver (HP iPAQ & others)" select W1 diff --git a/drivers/power/Makefile b/drivers/power/Makefile index a82f292e5c94..00050809a6c7 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_MAX8925_POWER) += max8925_power.o obj-$(CONFIG_WM831X_BACKUP) += wm831x_backup.o obj-$(CONFIG_WM831X_POWER) += wm831x_power.o obj-$(CONFIG_WM8350_POWER) += wm8350_power.o +obj-$(CONFIG_TEST_POWER) += test_power.o obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o obj-$(CONFIG_BATTERY_DS2782) += ds2782_battery.o diff --git a/drivers/power/test_power.c b/drivers/power/test_power.c new file mode 100644 index 000000000000..0cd9f67d33e5 --- /dev/null +++ b/drivers/power/test_power.c @@ -0,0 +1,163 @@ +/* + * Power supply driver for testing. + * + * Copyright 2010 Anton Vorontsov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +static int test_power_ac_online = 1; +static int test_power_battery_status = POWER_SUPPLY_STATUS_CHARGING; + +static int test_power_get_ac_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + val->intval = test_power_ac_online; + break; + default: + return -EINVAL; + } + return 0; +} + +static int test_power_get_battery_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + switch (psp) { + case POWER_SUPPLY_PROP_MODEL_NAME: + val->strval = "Test battery"; + break; + case POWER_SUPPLY_PROP_MANUFACTURER: + val->strval = "Linux"; + break; + case POWER_SUPPLY_PROP_SERIAL_NUMBER: + val->strval = UTS_RELEASE; + break; + case POWER_SUPPLY_PROP_STATUS: + val->intval = test_power_battery_status; + break; + case POWER_SUPPLY_PROP_CHARGE_TYPE: + val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST; + break; + case POWER_SUPPLY_PROP_HEALTH: + val->intval = POWER_SUPPLY_HEALTH_GOOD; + break; + case POWER_SUPPLY_PROP_TECHNOLOGY: + val->intval = POWER_SUPPLY_TECHNOLOGY_LION; + break; + case POWER_SUPPLY_PROP_CAPACITY_LEVEL: + val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; + break; + case POWER_SUPPLY_PROP_CAPACITY: + val->intval = 50; + break; + case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: + case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW: + val->intval = 3600; + break; + default: + pr_info("%s: some properties deliberately report errors.\n", + __func__); + return -EINVAL; + } + return 0; +} + +static enum power_supply_property test_power_ac_props[] = { + POWER_SUPPLY_PROP_ONLINE, +}; + +static enum power_supply_property test_power_battery_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_CHARGE_TYPE, + POWER_SUPPLY_PROP_HEALTH, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_CHARGE_FULL, + POWER_SUPPLY_PROP_CHARGE_EMPTY, + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_CAPACITY_LEVEL, + POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, + POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, + POWER_SUPPLY_PROP_MODEL_NAME, + POWER_SUPPLY_PROP_MANUFACTURER, + POWER_SUPPLY_PROP_SERIAL_NUMBER, +}; + +static char *test_power_ac_supplied_to[] = { + "test_battery", +}; + +static struct power_supply test_power_supplies[] = { + { + .name = "test_ac", + .type = POWER_SUPPLY_TYPE_MAINS, + .supplied_to = test_power_ac_supplied_to, + .num_supplicants = ARRAY_SIZE(test_power_ac_supplied_to), + .properties = test_power_ac_props, + .num_properties = ARRAY_SIZE(test_power_ac_props), + .get_property = test_power_get_ac_property, + }, { + .name = "test_battery", + .type = POWER_SUPPLY_TYPE_BATTERY, + .properties = test_power_battery_props, + .num_properties = ARRAY_SIZE(test_power_battery_props), + .get_property = test_power_get_battery_property, + }, +}; + +static int __init test_power_init(void) +{ + int i; + int ret; + + for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) { + ret = power_supply_register(NULL, &test_power_supplies[i]); + if (ret) { + pr_err("%s: failed to register %s\n", __func__, + test_power_supplies[i].name); + goto failed; + } + } + + return 0; +failed: + while (--i >= 0) + power_supply_unregister(&test_power_supplies[i]); + return ret; +} +module_init(test_power_init); + +static void __exit test_power_exit(void) +{ + int i; + + /* Let's see how we handle changes... */ + test_power_ac_online = 0; + test_power_battery_status = POWER_SUPPLY_STATUS_DISCHARGING; + for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) + power_supply_changed(&test_power_supplies[i]); + pr_info("%s: 'changed' event sent, sleeping for 10 seconds...\n", + __func__); + ssleep(10); + + for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) + power_supply_unregister(&test_power_supplies[i]); +} +module_exit(test_power_exit); + +MODULE_DESCRIPTION("Power supply driver for testing"); +MODULE_AUTHOR("Anton Vorontsov "); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From ac1ececea995fd77c8da6a1299674f22991cecaa Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 May 2010 13:00:31 -0300 Subject: i7core_edac: Add support for X5670 As reported by Vernon Mauery , X5670 (Westmere-EP) uses a different register for one of the uncore PCI devices. Add support for it. Those are the PCI ID's on this new chipset: fe:00.0 0600: 8086:2c70 (rev 02) fe:00.1 0600: 8086:2d81 (rev 02) fe:02.0 0600: 8086:2d90 (rev 02) fe:02.1 0600: 8086:2d91 (rev 02) fe:02.2 0600: 8086:2d92 (rev 02) fe:02.3 0600: 8086:2d93 (rev 02) fe:02.4 0600: 8086:2d94 (rev 02) fe:02.5 0600: 8086:2d95 (rev 02) fe:03.0 0600: 8086:2d98 (rev 02) fe:03.1 0600: 8086:2d99 (rev 02) fe:03.2 0600: 8086:2d9a (rev 02) fe:03.4 0600: 8086:2d9c (rev 02) fe:04.0 0600: 8086:2da0 (rev 02) fe:04.1 0600: 8086:2da1 (rev 02) fe:04.2 0600: 8086:2da2 (rev 02) fe:04.3 0600: 8086:2da3 (rev 02) fe:05.0 0600: 8086:2da8 (rev 02) fe:05.1 0600: 8086:2da9 (rev 02) fe:05.2 0600: 8086:2daa (rev 02) fe:05.3 0600: 8086:2dab (rev 02) fe:06.0 0600: 8086:2db0 (rev 02) fe:06.1 0600: 8086:2db1 (rev 02) fe:06.2 0600: 8086:2db2 (rev 02) fe:06.3 0600: 8086:2db3 (rev 02) (as usual, the same PCI devices repeat at ff: bus) The PCI device 8086:2c70 is shown as: fe:00.0 Host bridge: Intel Corporation QuickPath Architecture Generic Non-core Registers (rev 02) So, for this device to be recognized, it is only a matter of adding this new PCI ID to the driver. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 7 ++++++- include/linux/pci_ids.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index cd51709c4d89..82acfbd01779 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1213,10 +1213,15 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno, pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT, *prev); - if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && !pdev) + if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && !pdev) { pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT, *prev); + if (!pdev) + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_REV2, + *prev); + } if (!pdev) { if (*prev) { diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index e67cb20b8401..46d76e985bac 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2552,6 +2552,7 @@ #define PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT 0x2c40 #define PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE 0x2c50 #define PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT 0x2c51 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_REV2 0x2c70 #define PCI_DEVICE_ID_INTEL_LYNNFIELD_SAD 0x2c81 #define PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_LINK0 0x2c90 #define PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_PHY0 0x2c91 -- cgit v1.2.3 From d4d1ef4515cca074d5bbe1c63420822d6b20fe63 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Tue, 18 May 2010 10:53:25 -0300 Subject: i7core_edac: don't free on success Signed-off-by: Tony Luck Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 82acfbd01779..3e2b5379bc05 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1856,7 +1856,8 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev, } fail: - edac_mc_free(mci); + if (rc < 0) + edac_mc_free(mci); return rc; } -- cgit v1.2.3 From f1d7dbbef51a624ff0ec76f022802d677fdb9888 Mon Sep 17 00:00:00 2001 From: Alexander Kurz Date: Sat, 8 May 2010 12:21:45 +0400 Subject: Staging: comedi: new Kconfig and Makefiles, drivers grouped by bustype. PC/104-drivers went into ISA, PC/104+ went into PCI, Drivers without a bustype went into "misc". In doubt drivers supporting both ISA/PCI went into PCI. Drivers without any detailed hardware info went into ISA, e.g. fl512.c Some NI drivers are used by other NI drivers from different bustypes are grouped seperately in NI_COMMON. [tweaked by gregkh to handle the new driver recently added] Signed-off-by: Alexander Kurz Acked-by: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 1283 +++++++++++++++++++++++++++- drivers/staging/comedi/drivers/Makefile | 247 +++--- drivers/staging/comedi/kcomedilib/Makefile | 2 +- 3 files changed, 1402 insertions(+), 130 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index d63c889ce557..283ea0ceddf0 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -9,27 +9,1296 @@ config COMEDI config COMEDI_DEBUG bool "Comedi debugging" depends on COMEDI != n - help + ---help--- This is an option for use by developers; most people should say N here. This enables comedi core and driver debugging. -config COMEDI_PCI_DRIVERS +menuconfig COMEDI_MISC_DRIVERS + tristate "Comedi misc drivers" + depends on COMEDI + default N + ---help--- + Enable comedi misc drivers to be built + + Note that the answer to this question won't directly affect the + kernel: saying N will just cause the configurator to skip all + the questions about misc non-hardware comedi drivers. + +if COMEDI_MISC_DRIVERS + +config COMEDI_KCOMEDILIB + tristate "Comedi kcomedilib" + ---help--- + Build the kcomedilib + +config COMEDI_BOND + tristate "Device bonding support" + depends on COMEDI_KCOMEDILIB + default N + ---help--- + Enable support for a driver to 'bond' (merge) multiple subdevices + from multiple devices together as one. + + To compile this driver as a module, choose M here: the module will be + called comedi_bond. + +config COMEDI_TEST + tristate "Fake waveform generator support" + select COMEDI_FC + default N + ---help--- + Enable support for the fake waveform generator. + This driver is mainly for testing purposes, but can also be used to + generate sample waveforms on systems that don't have data acquisition + hardware. + + To compile this driver as a module, choose M here: the module will be + called comedi_test. + +config COMEDI_PARPORT + tristate "Parallel port support" + depends on PARPORT_PC + default N + ---help--- + Enable support for the standard parallel port. + A cheap and easy way to get a few more digital I/O lines. Steal + additional parallel ports from old computers or your neighbors' + computers. + + To compile this driver as a module, choose M here: the module will be + called comedi_parport. + +config COMEDI_SERIAL2002 + tristate "Driver for serial connected hardware" + default N + ---help--- + Enable support for serial connected hardware + + To compile this driver as a module, choose M here: the module will be + called serial2002. + +config COMEDI_SKEL + tristate "Comedi skeleton driver" + default N + ---help--- + Build the Skeleton driver, an example for driver writers + + To compile this driver as a module, choose M here: the module will be + called skel. + +endif # COMEDI_MISC_DRIVERS + +menuconfig COMEDI_ISA_DRIVERS + tristate "Comedi ISA and PC/104 drivers" + depends on COMEDI && ISA + default N + ---help--- + Enable comedi ISA and PC/104 drivers to be built + + Note that the answer to this question won't directly affect the + kernel: saying N will just cause the configurator to skip all + the questions about ISA and PC/104 comedi drivers. + +if COMEDI_ISA_DRIVERS && ISA + +config COMEDI_8255 + tristate "Generic 8255 support" + default N + ---help--- + Enable generic 8255 support. + + To compile this driver as a module, choose M here: the module will be + called 8255. + +config COMEDI_ACL7225B + tristate "ADlink NuDAQ ACL-7225b and compatibles support" + default N + ---help--- + Enable support for ADlink NuDAQ ACL-7225b and compatibles, + ADlink ACL-7225b (acl7225b), ICP P16R16DIO (p16r16dio) + + To compile this driver as a module, choose M here: the module will be + called acl7225b. + +config COMEDI_PCL711 + tristate "Advantech PCL-711/711b and ADlink ACL-8112 ISA card support" + default N + ---help--- + Enable support for Advantech PCL-711 and 711b, ADlink ACL-8112 + + To compile this driver as a module, choose M here: the module will be + called pcl711. + +config COMEDI_PCL724 + tristate "Advantech PCL-722/724/731 and ADlink ACL-7122/7124/PET-48DIO" + default N + ---help--- + Enable support for Advantech PCL-724, PCL-722, PCL-731 and + ADlink ACL-7122, ACL-7124, PET-48DIO ISA cards + + To compile this driver as a module, choose M here: the module will be + called pcl724. + +config COMEDI_PCL725 + tristate "Advantech PCL-725 and compatible ISA card support" + default N + ---help--- + Enable support for Advantech PCL-725 and compatible ISA cards. + + To compile this driver as a module, choose M here: the module will be + called pcl725. + +config COMEDI_PCL726 + tristate "Advantech PCL-726 and compatible ISA card support" + default N + ---help--- + Enable support for Advantech PCL-726 and compatible ISA cards. + + To compile this driver as a module, choose M here: the module will be + called pcl726. + +config COMEDI_PCL730 + tristate "Advantech PCL-730 and ADlink ACL-7130 ISA card support" + default N + ---help--- + Enable support for Advantech PCL-730, ICP ISO-730 and ADlink + ACL-7130 ISA cards + + To compile this driver as a module, choose M here: the module will be + called pcl730. + +config COMEDI_PCL812 + tristate "Advantech PCL-812/813 and ADlink ACL-8112/8113/8113/8216" + default N + ---help--- + Enable support for Advantech PCL-812/PG, PCL-813/B, ADLink + ACL-8112DG/HG/PG, ACL-8113, ACL-8216, ICP DAS A-821PGH/PGL/PGL-NDA, + A-822PGH/PGL, A-823PGH/PGL, A-826PG and ICP DAS ISO-813 ISA cards + + To compile this driver as a module, choose M here: the module will be + called pcl812. + +config COMEDI_PCL816 + tristate "Advantech PCL-814 and PCL-816 ISA card support" + default N + ---help--- + Enable support for Advantech PCL-814 and PCL-816 ISA cards + + To compile this driver as a module, choose M here: the module will be + called pcl816. + +config COMEDI_PCL818 + tristate "Advantech PCL-718 and PCL-818 ISA card support" + default N + ---help--- + Enable support for Advantech PCL-818 ISA cards + PCL-818L, PCL-818H, PCL-818HD, PCL-818HG, PCL-818 and PCL-718 + + To compile this driver as a module, choose M here: the module will be + called pcl818. + +config COMEDI_PCM3724 + tristate "Advantech PCM-3724 PC/104 card support" + default N + ---help--- + Enable support for Advantech PCM-3724 PC/104 cards. + + To compile this driver as a module, choose M here: the module will be + called pcm3724. + +config COMEDI_PCM3730 + tristate "Advantech PCM-3730 and clone PC/104 board support" + default N + ---help--- + Enable support for Advantech PCM-3730 and clone PC/104 boards + + To compile this driver as a module, choose M here: the module will be + called pcm3730. + +config COMEDI_RTI800 + tristate "Analog Devices RTI-800/815 ISA card support" + default N + ---help--- + Enable support for Analog Devices RTI-800/815 ISA cards + + To compile this driver as a module, choose M here: the module will be + called rti800. + +config COMEDI_RTI802 + tristate "Analog Devices RTI-802 ISA card support" + default N + ---help--- + Enable support for Analog Devices RTI-802 ISA cards + + To compile this driver as a module, choose M here: the module will be + called rti802. + +config COMEDI_DAS08 + tristate "DAS-08 compatible ISA, PC/104 and PCMCIA card support" + default N + ---help--- + Enable support for Keithley Metrabyte/ComputerBoards DAS08 + and compatible ISA and PC/104 cards + + To compile this driver as a module, choose M here: the module will be + called das08. + +config COMEDI_DAS16M1 + tristate "MeasurementComputing CIO-DAS16/M1DAS-16 ISA card support" + select COMEDI_FC + default N + ---help--- + Enable support for Measurement Computing CIO-DAS16/M1 ISA cards. + + To compile this driver as a module, choose M here: the module will be + called das16m1. + +config COMEDI_DAS16 + tristate "DAS-16 compatible ISA and PC/104 card support" + select COMEDI_FC + default N + ---help--- + Enable support for Keithley Metrabyte/ComputerBoards DAS16 + and compatible ISA and PC/104 cards: + Keithley Metrabyte DAS-16, DAS-16G, DAS-16F, DAS-1201, DAS-1202, + DAS-1401, DAS-1402, DAS-1601, DAS-1602 and + ComputerBoards/MeasurementComputing PC104-DAS16/JR/, + PC104-DAS16JR/16, CIO-DAS16JR/16, CIO-DAS16/JR, CIO-DAS1401/12, + CIO-DAS1402/12, CIO-DAS1402/16, CIO-DAS1601/12, CIO-DAS1602/12, + CIO-DAS1602/16, CIO-DAS16/330 + + To compile this driver as a module, choose M here: the module will be + called das16. + +config COMEDI_DAS800 + tristate "DAS800 and compatible ISA card support" + select COMEDI_FC + default N + ---help--- + Enable support for Keithley Metrabyte DAS800 and compatible ISA cards + Keithley Metrabyte DAS-800, DAS-801, DAS-802 + Measurement Computing CIO-DAS800, CIO-DAS801, CIO-DAS802 and + CIO-DAS802/16 + + To compile this driver as a module, choose M here: the module will be + called das800. + +config COMEDI_DAS1800 + tristate "DAS1800 and compatible ISA card support" + select COMEDI_FC + default N + ---help--- + Enable support for DAS1800 and compatible ISA cards + Keithley Metrabyte DAS-1701ST, DAS-1701ST-DA, DAS-1701/AO, + DAS-1702ST, DAS-1702ST-DA, DAS-1702HR, DAS-1702HR-DA, DAS-1702/AO, + DAS-1801ST, DAS-1801ST-DA, DAS-1801HC, DAS-1801AO, DAS-1802ST, + DAS-1802ST-DA, DAS-1802HR, DAS-1802HR-DA, DAS-1802HC and + DAS-1802AO + + To compile this driver as a module, choose M here: the module will be + called das1800. + +config COMEDI_DAS6402 + tristate "DAS6402 and compatible ISA card support" + default N + ---help--- + Enable support for DAS6402 and compatible ISA cards + Computerboards, Keithley Metrabyte DAS6402 and compatibles + + To compile this driver as a module, choose M here: the module will be + called das6402. + +config COMEDI_DT2801 + tristate "Data Translation DT2801 ISA card support" + default N + ---help--- + Enable support for Data Translation DT2801 ISA cards + + To compile this driver as a module, choose M here: the module will be + called dt2801. + +config COMEDI_DT2811 + tristate "Data Translation DT2811 ISA card support" + default N + ---help--- + Enable support for Data Translation DT2811 ISA cards + + To compile this driver as a module, choose M here: the module will be + called dt2811. + +config COMEDI_DT2814 + tristate "Data Translation DT2814 ISA card support" + default N + ---help--- + Enable support for Data Translation DT2814 ISA cards + + To compile this driver as a module, choose M here: the module will be + called dt2814. + +config COMEDI_DT2815 + tristate "Data Translation DT2815 ISA card support" + default N + ---help--- + Enable support for Data Translation DT2815 ISA cards + + To compile this driver as a module, choose M here: the module will be + called dt2815. + +config COMEDI_DT2817 + tristate "Data Translation DT2817 ISA card support" + default N + ---help--- + Enable support for Data Translation DT2817 ISA cards + + To compile this driver as a module, choose M here: the module will be + called dt2817. + +config COMEDI_DT282X + tristate "Data Translation DT2821 series and DT-EZ ISA card support" + select COMEDI_FC + default N + ---help--- + Enable support for Data Translation DT2821 series including DT-EZ + DT2821, DT2821-F-16SE, DT2821-F-8DI, DT2821-G-16SE, DT2821-G-8DI, + DT2823 (dt2823), DT2824-PGH, DT2824-PGL, DT2825, DT2827, DT2828, + DT21-EZ, DT23-EZ, DT24-EZ and DT24-EZ-PGL + + To compile this driver as a module, choose M here: the module will be + called dt282x. + +config COMEDI_DMM32AT + tristate "Diamond Systems MM-32-AT PC/104 board support" + default N + ---help--- + Enable support for Diamond Systems MM-32-AT PC/104 boards + + To compile this driver as a module, choose M here: the module will be + called dmm32at. + +config COMEDI_FL512 + tristate "FL512 ISA card support" + default N + ---help--- + Enable support for FL512 ISA card + + To compile this driver as a module, choose M here: the module will be + called fl512. + +config COMEDI_AIO_AIO12_8 + tristate "I/O Products PC/104 AIO12-8 Analog I/O Board support" + default N + ---help--- + Enable support for I/O Products PC/104 AIO12-8 Analog I/O Board + + To compile this driver as a module, choose M here: the module will be + called aio_aio12_8. + +config COMEDI_AIO_IIRO_16 + tristate "I/O Products PC/104 IIRO16 Board support" + default N + ---help--- + Enable support for I/O Products PC/104 IIRO16 Relay And Isolated + Input Board + + To compile this driver as a module, choose M here: the module will be + called aio_iiro_16. + +config COMEDI_C6XDIGIO + tristate "Mechatronic Systems Inc. C6x_DIGIO DSP daughter card support" + default N + ---help--- + Enable support for Mechatronic Systems Inc. C6x_DIGIO DSP daughter + card + + To compile this driver as a module, choose M here: the module will be + called c6xdigio. + +config COMEDI_MPC624 + tristate "Micro/sys MPC-624 PC/104 board support" + default N + ---help--- + Enable support for Micro/sys MPC-624 PC/104 board + + To compile this driver as a module, choose M here: the module will be + called mpc624. + +config COMEDI_ADQ12B + tristate "MicroAxial ADQ12-B data acquisition and control card support" + default N + ---help--- + Enable MicroAxial ADQ12-B daq and control card support. + + To compile this driver as a module, choose M here: the module will be + called adq12b. + +config COMEDI_NI_AT_A2150 + tristate "NI AT-A2150 ISA card support" + depends on COMEDI_NI_COMMON + default N + ---help--- + Enable support for National Instruments AT-A2150 cards + + To compile this driver as a module, choose M here: the module will be + called ni_at_a2150. + +config COMEDI_NI_AT_AO + tristate "NI AT-AO-6/10 EISA card support" + depends on COMEDI_NI_COMMON + default N + ---help--- + Enable support for National Instruments AT-AO-6/10 cards + + To compile this driver as a module, choose M here: the module will be + called ni_at_ao. + +config COMEDI_NI_ATMIO + tristate "NI AT-MIO E series ISA-PNP card support" + depends on ISAPNP && COMEDI_NI_TIO && COMEDI_NI_COMMON + default N + ---help--- + Enable support for National Instruments AT-MIO E series cards + National Instruments AT-MIO-16E-1 (ni_atmio), + AT-MIO-16E-2, AT-MIO-16E-10, AT-MIO-16DE-10, AT-MIO-64E-3, + AT-MIO-16XE-50, AT-MIO-16XE-10, AT-AI-16XE-10 + + To compile this driver as a module, choose M here: the module will be + called ni_atmio. + +config COMEDI_NI_ATMIO16D + tristate "NI AT-MIO16/AT-MIO16D series ISA-PNP card support" + depends on ISAPNP && COMEDI_NI_COMMON + default N + ---help--- + Enable support for National Instruments AT-MIO16/AT-MIO16D cards. + + To compile this driver as a module, choose M here: the module will be + called ni_atmio16d. + +config COMEDI_PCMAD + tristate "Winsystems PCM-A/D12 and PCM-A/D16 PC/104 board support" + default N + ---help--- + Enable support for Winsystems PCM-A/D12 and PCM-A/D16 PC/104 boards. + + To compile this driver as a module, choose M here: the module will be + called pcmad. + +config COMEDI_PCMDA12 + tristate "Winsystems PCM-D/A-12 8-channel AO PC/104 board support" + default N + ---help--- + Enable support for Winsystems PCM-D/A-12 8-channel AO PC/104 boards. + Note that the board is not ISA-PNP capable and thus needs the I/O + port comedi_config parameter. + + To compile this driver as a module, choose M here: the module will be + called pcmda12. + +config COMEDI_PCMMIO + tristate "Winsystems PCM-MIO PC/104 board support" + default N + ---help--- + Enable support for Winsystems PCM-MIO multifunction PC/104 boards. + + To compile this driver as a module, choose M here: the module will be + called pcmmio. + +config COMEDI_PCMUIO + tristate "Winsystems PCM-UIO48A and PCM-UIO96A PC/104 board support" + default N + ---help--- + Enable support for PCM-UIO48A and PCM-UIO96A PC/104 boards. + + To compile this driver as a module, choose M here: the module will be + called pcmuio. + +config COMEDI_MULTIQ3 + tristate "Quanser Consulting MultiQ-3 ISA card support" + default N + ---help--- + Enable support for Quanser Consulting MultiQ-3 ISA cards + + To compile this driver as a module, choose M here: the module will be + called multiq3. + +config COMEDI_POC + tristate "Generic driver for very simple devices" + default N + ---help--- + Enable generic support for very simple / POC (Piece of Crap) boards, + Keithley Metrabyte DAC-02 (dac02), Advantech PCL-733 (pcl733) and + PCL-734 (pcl734) + + To compile this driver as a module, choose M here: the module will be + called poc. + +endif # COMEDI_ISA_DRIVERS + +menuconfig COMEDI_PCI_DRIVERS tristate "Comedi PCI drivers" depends on COMEDI && PCI default N ---help--- - Enable lots of comedi PCI drivers to be built + Enable comedi PCI drivers to be built + + Note that the answer to this question won't directly affect the + kernel: saying N will just cause the configurator to skip all + the questions about PCI comedi drivers. + +if COMEDI_PCI_DRIVERS && PCI + +config COMEDI_ADDI_APCI_035 + tristate "ADDI-DATA APCI_035 support" + default N + ---help--- + Enable support for ADDI-DATA APCI_035 cards + + To compile this driver as a module, choose M here: the module will be + called addi_apci_035. + +config COMEDI_ADDI_APCI_1032 + tristate "ADDI-DATA APCI_1032 support" + default N + ---help--- + Enable support for ADDI-DATA APCI_1032 cards + + To compile this driver as a module, choose M here: the module will be + called addi_apci_1032. + +config COMEDI_ADDI_APCI_1500 + tristate "ADDI-DATA APCI_1500 support" + default N + ---help--- + Enable support for ADDI-DATA APCI_1500 cards + + To compile this driver as a module, choose M here: the module will be + called addi_apci_1500. + +config COMEDI_ADDI_APCI_1516 + tristate "ADDI-DATA APCI_1516 support" + default N + ---help--- + Enable support for ADDI-DATA APCI_1516 cards + + To compile this driver as a module, choose M here: the module will be + called addi_apci_1516. + +config COMEDI_ADDI_APCI_1564 + tristate "ADDI-DATA APCI_1564 support" + default N + ---help--- + Enable support for ADDI-DATA APCI_1564 cards + + To compile this driver as a module, choose M here: the module will be + called addi_apci_1564. + +config COMEDI_ADDI_APCI_16XX + tristate "ADDI-DATA APCI_16xx support" + default N + ---help--- + Enable support for ADDI-DATA APCI_16xx cards + + To compile this driver as a module, choose M here: the module will be + called addi_apci_16xx. + +config COMEDI_ADDI_APCI_2016 + tristate "ADDI-DATA APCI_2016 support" + default N + ---help--- + Enable support for ADDI-DATA APCI_2016 cards + + To compile this driver as a module, choose M here: the module will be + called addi_apci_2016. + +config COMEDI_ADDI_APCI_2032 + tristate "ADDI-DATA APCI_2032 support" + default N + ---help--- + Enable support for ADDI-DATA APCI_2032 cards + + To compile this driver as a module, choose M here: the module will be + called addi_apci_2032. + +config COMEDI_ADDI_APCI_2200 + tristate "ADDI-DATA APCI_2200 support" + default N + ---help--- + Enable support for ADDI-DATA APCI_2200 cards + + To compile this driver as a module, choose M here: the module will be + called addi_apci_2200. + +config COMEDI_ADDI_APCI_3001 + tristate "ADDI-DATA APCI_3001 support" + select COMEDI_FC + default N + ---help--- + Enable support for ADDI-DATA APCI_3001 cards + + To compile this driver as a module, choose M here: the module will be + called addi_apci_3001. + +config COMEDI_ADDI_APCI_3120 + tristate "ADDI-DATA APCI_3520 support" + select COMEDI_FC + default N + ---help--- + Enable support for ADDI-DATA APCI_3520 cards + + To compile this driver as a module, choose M here: the module will be + called addi_apci_3120. + +config COMEDI_ADDI_APCI_3501 + tristate "ADDI-DATA APCI_3501 support" + default N + ---help--- + Enable support for ADDI-DATA APCI_3501 cards + + To compile this driver as a module, choose M here: the module will be + called addi_apci_3501. + +config COMEDI_ADDI_APCI_3XXX + tristate "ADDI-DATA APCI_3xxx support" + default N + ---help--- + Enable support for ADDI-DATA APCI_3xxx cards + + To compile this driver as a module, choose M here: the module will be + called addi_apci_3xxx. + +config COMEDI_ADL_PCI6208 + tristate "ADLink PCI-6208A support" + default N + ---help--- + Enable support for ADLink PCI-6208A cards + + To compile this driver as a module, choose M here: the module will be + called adl_pci6208. + +config COMEDI_ADL_PCI7230 + tristate "ADLink PCI-7230 digital io board support" + default N + ---help--- + Enable support for ADlink PCI-7230 digital io board support + + To compile this driver as a module, choose M here: the module will be + called adl_pci7230. + +config COMEDI_ADL_PCI7296 + tristate "ADLink PCI-7296 96 ch. digital io board support" + default N + ---help--- + Enable support for ADlink PCI-7296 96 ch. digital io board support + + To compile this driver as a module, choose M here: the module will be + called adl_pci7296. + +config COMEDI_ADL_PCI7432 + tristate "ADLink PCI-7432 64 ch. isolated digital io board support" + default N + ---help--- + Enable support for ADlink PCI-7432 64 ch. isolated digital io board + + To compile this driver as a module, choose M here: the module will be + called adl_pci7432. + +config COMEDI_ADL_PCI8164 + tristate "ADLink PCI-8164 4 Axes Motion Control board support" + default N + ---help--- + Enable support for ADlink PCI-8164 4 Axes Motion Control board + + To compile this driver as a module, choose M here: the module will be + called adl_pci8164. + +config COMEDI_ADL_PCI9111 + tristate "ADLink PCI-9111HR support" + select COMEDI_FC + default N + ---help--- + Enable support for ADlink PCI9111 cards + + To compile this driver as a module, choose M here: the module will be + called adl_pci9111. + +config COMEDI_ADL_PCI9118 + tristate "ADLink PCI-9118DG, PCI-9118HG, PCI-9118HR support" + select COMEDI_FC + default N + ---help--- + Enable support for ADlink PCI-9118DG, PCI-9118HG, PCI-9118HR cards + + To compile this driver as a module, choose M here: the module will be + called adl_pci9118. + +config COMEDI_ADV_PCI1710 + tristate "Advantech PCI-171x, PCI-1720 and PCI-1731 support" + default N + ---help--- + Enable support for Advantech PCI-1710, PCI-1710HG, PCI-1711, + PCI-1713, PCI-1720 and PCI-1731 + + To compile this driver as a module, choose M here: the module will be + called adv_pci1710. + +config COMEDI_ADV_PCI1723 + tristate "Advantech PCI-1723 support" + default N + ---help--- + Enable support for Advantech PCI-1723 cards + + To compile this driver as a module, choose M here: the module will be + called adv_pci1723. + +config COMEDI_ADV_PCI_DIO + tristate "Advantech PCI DIO card support" + default N + ---help--- + Enable support for Advantech PCI DIO cards + PCI-1730, PCI-1733, PCI-1734, PCI-1736UP, PCI-1750, PCI-1751, + PCI-1752, PCI-1753/E, PCI-1754, PCI-1756 and PCI-1762 + + To compile this driver as a module, choose M here: the module will be + called adv_pci_dio. + +config COMEDI_AMPLC_DIO200 + tristate "Amplicon PC272E and PCI272 DIO board support" + default N + ---help--- + Enable support for Amplicon PC272E and PCI272 DIO boards + + To compile this driver as a module, choose M here: the module will be + called amplc_dio200. + +config COMEDI_AMPLC_PC236 + tristate "Amplicon PC36AT and PCI236 DIO board support" + default N + ---help--- + Enable support for Amplicon PC36AT and PCI236 DIO boards + + To compile this driver as a module, choose M here: the module will be + called amplc_pc236. + +config COMEDI_AMPLC_PC263 + tristate "Amplicon PC263 and PCI263 relay board support" + default N + ---help--- + Enable support for Amplicon PC263 and PCI263 relay boards + + To compile this driver as a module, choose M here: the module will be + called amplc_pc263. + +config COMEDI_AMPLC_PCI224 + tristate "Amplicon PCI224 and PCI234 support" + select COMEDI_FC + default N + ---help--- + Enable support for Amplicon PCI224 and PCI234 AO boards + + To compile this driver as a module, choose M here: the module will be + called amplc_pci224. + +config COMEDI_AMPLC_PCI230 + tristate "Amplicon PCI230 and PCI260 support" + default N + ---help--- + Enable support for Amplicon PCI230 and PCI260 Multifunction I/O + boards + + To compile this driver as a module, choose M here: the module will be + called amplc_pci230. + +config COMEDI_CONTEC_PCI_DIO + tristate "Contec PIO1616L digital I/O board support" + default N + ---help--- + Enable support for the Contec PIO1616L digital I/O board + + To compile this driver as a module, choose M here: the module will be + called contec_pci_dio. + +config COMEDI_DT3000 + tristate "Data Translation DT3000 series support" + default N + ---help--- + Enable support for Data Translation DT3000 series + DT3001, DT3001-PGL, DT3002, DT3003, DT3003-PGL, DT3004, DT3005 and + DT3004-200 + + To compile this driver as a module, choose M here: the module will be + called dt3000. + +config COMEDI_UNIOXX5 + tristate "Fastwel UNIOxx-5 analog and digital io board support" + default N + ---help--- + Enable support for Fastwel UNIOxx-5 (analog and digital i/o) boards + + To compile this driver as a module, choose M here: the module will be + called unioxx5. + +config COMEDI_GSC_HPDI + tristate "General Standards PCI-HPDI32 / PMC-HPDI32 support" + select COMEDI_FC + default N + ---help--- + Enable support for General Standards Corporation high speed parallel + digital interface rs485 boards PCI-HPDI32 and PMC-HPDI32. + Only receive mode works, transmit not supported. + + To compile this driver as a module, choose M here: the module will be + called gsc_hpdi. + +config COMEDI_ICP_MULTI + tristate "Inova ICP_MULTI support" + default N + ---help--- + Enable support for Inova ICP_MULTI card + + To compile this driver as a module, choose M here: the module will be + called icp_multi. + +config COMEDI_II_PCI20KC + tristate "Intelligent Instruments PCI-20001C carrier support" + default N + ---help--- + Enable support for Intelligent Instruments PCI-20001C carrier + PCI-20001, PCI-20006 and PCI-20341 + + To compile this driver as a module, choose M here: the module will be + called ii_pci20kc. + +config COMEDI_DAQBOARD2000 + tristate "IOtech DAQboard/2000 support" + default N + ---help--- + Enable support for the IOtech DAQboard/2000 + + To compile this driver as a module, choose M here: the module will be + called daqboard2000. + +config COMEDI_JR3_PCI + tristate "JR3/PCI force sensor board support" + default N + ---help--- + Enable support for JR3/PCI force sensor boards + + To compile this driver as a module, choose M here: the module will be + called jr3_pci. + +config COMEDI_KE_COUNTER + tristate "Kolter-Electronic PCI Counter 1 card support" + default N + ---help--- + Enable support for Kolter-Electronic PCI Counter 1 cards + + To compile this driver as a module, choose M here: the module will be + called ke_counter. + +config COMEDI_CB_PCIDAS64 + tristate "MeasurementComputing PCI-DAS 64xx, 60xx, and 4020 support" + select COMEDI_FC + default N + ---help--- + Enable support for ComputerBoards/MeasurementComputing PCI-DAS 64xx, + 60xx, and 4020 series with the PLX 9080 PCI controller + + To compile this driver as a module, choose M here: the module will be + called cb_pcidas64. + +config COMEDI_CB_PCIDAS + tristate "MeasurementComputing PCI-DAS support" + select COMEDI_FC + default N + ---help--- + Enable support for ComputerBoards/MeasurementComputing PCI-DAS with + AMCC S5933 PCIcontroller: PCI-DAS1602/16, PCI-DAS1602/16jr, + PCI-DAS1602/12, PCI-DAS1200, PCI-DAS1200jr, PCI-DAS1000, PCI-DAS1001 + and PCI_DAS1002. + + To compile this driver as a module, choose M here: the module will be + called cb_pcidas. + +config COMEDI_CB_PCIDDA + tristate "MeasurementComputing PCI-DDA series support" + default N + ---help--- + Enable support for ComputerBoards/MeasurementComputing PCI-DDA + series: PCI-DDA08/12, PCI-DDA04/12, PCI-DDA02/12, PCI-DDA08/16, + PCI-DDA04/16 and PCI-DDA02/16 + + To compile this driver as a module, choose M here: the module will be + called cb_pcidda. + +config COMEDI_CB_PCIDIO + tristate "MeasurementComputing PCI-DIO series support" + default N + ---help--- + Enable support for ComputerBoards/MeasurementComputing PCI-DIO series + PCI-DIO24, PCI-DIO24H and PCI-DIO48H + + To compile this driver as a module, choose M here: the module will be + called cb_pcidio. + +config COMEDI_CB_PCIMDAS + tristate "MeasurementComputing PCIM-DAS1602/16 support" + default N + ---help--- + Enable support for ComputerBoards/MeasurementComputing PCI Migration + series PCIM-DAS1602/16 + + To compile this driver as a module, choose M here: the module will be + called cb_pcimdas. -config COMEDI_PCMCIA_DRIVERS +config COMEDI_CB_PCIMDDA + tristate "MeasurementComputing PCIM-DDA06-16 support" + default N + ---help--- + Enable support for ComputerBoards/MeasurementComputing PCIM-DDA06-16 + + To compile this driver as a module, choose M here: the module will be + called cb_pcimdda. + +config COMEDI_ME4000 + tristate "Meilhaus ME-4000 support" + default N + ---help--- + Enable support for Meilhaus PCI data acquisition cards + ME-4650, ME-4670i, ME-4680, ME-4680i and ME-4680is + + To compile this driver as a module, choose M here: the module will be + called me4000. + +config COMEDI_ME_DAQ + tristate "Meilhaus ME-2000i, ME-2600i, ME-3000vm1 support" + default N + ---help--- + Enable support for Meilhaus PCI data acquisition cards + ME-2000i, ME-2600i and ME-3000vm1 + + To compile this driver as a module, choose M here: the module will be + called me_daq. + +config COMEDI_NI_6527 + tristate "NI 6527 support" + depends on COMEDI_MITE + default N + ---help--- + Enable support for the National Instruments 6527 PCI card + + To compile this driver as a module, choose M here: the module will be + called ni_6527. + +config COMEDI_NI_65XX + tristate "NI 65xx static dio PCI card support" + depends on COMEDI_MITE + default N + ---help--- + Enable support for National Instruments 65xx static dio boards. + Supported devices: National Instruments PCI-6509 (ni_65xx), + PXI-6509, PCI-6510, PCI-6511, PXI-6511, PCI-6512, PXI-6512, PCI-6513, + PXI-6513, PCI-6514, PXI-6514, PCI-6515, PXI-6515, PCI-6516, PCI-6517, + PCI-6518, PCI-6519, PCI-6520, PCI-6521, PXI-6521, PCI-6528, PXI-6528 + + To compile this driver as a module, choose M here: the module will be + called ni_65xx. + +config COMEDI_NI_660X + tristate "NI 660x counter/timer PCI card support" + depends on COMEDI_NI_TIO && COMEDI_NI_COMMON + default N + ---help--- + Enable support for National Instruments PCI-6601 (ni_660x), PCI-6602, + PXI-6602 and PXI-6608. + + To compile this driver as a module, choose M here: the module will be + called ni_660x. + +config COMEDI_NI_670X + tristate "NI 670x PCI card support" + depends on COMEDI_MITE + default N + ---help--- + Enable support for National Instruments PCI-6703 and PCI-6704 + + To compile this driver as a module, choose M here: the module will be + called ni_670x. + +config COMEDI_NI_PCIDIO + tristate "NI PCI-DIO32HS, PCI-DIO96, PCI-6533, PCI-6503 support" + depends on COMEDI_MITE + default N + ---help--- + Enable support for National Instruments PCI-DIO-32HS, PXI-6533, + PCI-DIO-96, PCI-DIO-96B, PXI-6508, PCI-6503, PCI-6503B, PCI-6503X, + PXI-6503, PCI-6533 and PCI-6534 + The DIO-96 appears as four 8255 subdevices. See the 8255 + driver notes for details. + + To compile this driver as a module, choose M here: the module will be + called ni_pcidio. + +config COMEDI_NI_PCIMIO + tristate "NI PCI-MIO-E series and M series support" + depends on COMEDI_NI_TIO && COMEDI_NI_COMMON + default N + ---help--- + Enable support for National Instruments PCI-MIO-E series and M series + (all boards): PCI-MIO-16XE-10, PXI-6030E, PCI-MIO-16E-1, + PCI-MIO-16E-4, PCI-6014, PCI-6040E, PXI-6040E, PCI-6030E, PCI-6031E, + PCI-6032E, PCI-6033E, PCI-6071E, PCI-6023E, PCI-6024E, PCI-6025E, + PXI-6025E, PCI-6034E, PCI-6035E, PCI-6052E, PCI-6110, PCI-6111, + PCI-6220, PCI-6221, PCI-6224, PXI-6224, PCI-6225, PXI-6225, PCI-6229, + PCI-6250, PCI-6251, PCIe-6251, PCI-6254, PCI-6259, PCIe-6259, + PCI-6280, PCI-6281, PXI-6281, PCI-6284, PCI-6289, PCI-6711, PXI-6711, + PCI-6713, PXI-6713, PXI-6071E, PCI-6070E, PXI-6070E, PXI-6052E, + PCI-6036E, PCI-6731, PCI-6733, PXI-6733, PCI-6143, PXI-6143 + + To compile this driver as a module, choose M here: the module will be + called ni_pcimio. + +config COMEDI_RTD520 + tristate "Real Time Devices PCI4520/DM7520 support" + default N + ---help--- + Enable support for Real Time Devices PCI4520/DM7520 + + To compile this driver as a module, choose M here: the module will be + called rtd520. + +config COMEDI_S526 + tristate "Sensoray s526 support" + default N + ---help--- + Enable support for Sensoray s526 + + To compile this driver as a module, choose M here: the module will be + called s526. + +config COMEDI_S626 + tristate "Sensoray 626 support" + select COMEDI_FC + default N + ---help--- + Enable support for Sensoray 626 + + To compile this driver as a module, choose M here: the module will be + called s626. + +config COMEDI_SSV_DNP + tristate "SSV Embedded Systems DIL/Net-PC support" + default N + ---help--- + Enable support for SSV Embedded Systems DIL/Net-PC + + To compile this driver as a module, choose M here: the module will be + called ssv_dnp. + +endif # COMEDI_PCI_DRIVERS + +menuconfig COMEDI_PCMCIA_DRIVERS tristate "Comedi PCMCIA drivers" depends on COMEDI && PCMCIA && PCCARD default N ---help--- - Enable lots of comedi PCMCIA and PCCARD drivers to be built + Enable comedi PCMCIA and PCCARD drivers to be built + + Note that the answer to this question won't directly affect the + kernel: saying N will just cause the configurator to skip all + the questions about PCMCIA comedi drivers. + +if COMEDI_PCMCIA_DRIVERS && PCMCIA + +config COMEDI_CB_DAS16_CS + tristate "CB DAS16 series PCMCIA support" + default N + ---help--- + Enable support for the ComputerBoards/MeasurementComputing PCMCIA + cards DAS16/16, PCM-DAS16D/12 and PCM-DAS16s/16 + + To compile this driver as a module, choose M here: the module will be + called cb_das16_cs. + +config COMEDI_DAS08_CS + tristate "CB DAS08 PCMCIA support" + select COMEDI_DAS08 + default N + ---help--- + Enable support for the ComputerBoards/MeasurementComputing DAS-08 + PCMCIA card + + To compile this driver as a module, choose M here: the module will be + called das08_cs. -config COMEDI_USB_DRIVERS +config COMEDI_NI_DAQ_700_CS + tristate "NI DAQCard-700 PCMCIA support" + depends on COMEDI_NI_COMMON + default N + ---help--- + Enable support for the National Instruments PCMCIA DAQCard-700 DIO + + To compile this driver as a module, choose M here: the module will be + called ni_daq_700. + +config COMEDI_NI_DAQ_DIO24_CS + tristate "NI DAQ-Card DIO-24 PCMCIA support" + depends on COMEDI_NI_COMMON + default N + ---help--- + Enable support for the National Instruments PCMCIA DAQ-Card DIO-24 + + To compile this driver as a module, choose M here: the module will be + called ni_daq_dio24. + +config COMEDI_NI_LABPC_CS + tristate "NI DAQCard-1200 PCMCIA support" + depends on COMEDI_NI_LABPC + default N + ---help--- + Enable support for the National Instruments PCMCIA DAQCard-1200 + + To compile this driver as a module, choose M here: the module will be + called ni_labpc_cs. + +config COMEDI_NI_MIO_CS + tristate "NI DAQCard E series PCMCIA support" + depends on COMEDI_NI_TIO && COMEDI_NI_COMMON + default N + select COMEDI_FC + ---help--- + Enable support for the National Instruments PCMCIA DAQCard E series + DAQCard-ai-16xe-50, DAQCard-ai-16e-4, DAQCard-6062E, DAQCard-6024E + and DAQCard-6036E + + To compile this driver as a module, choose M here: the module will be + called ni_mio_cs. + +config COMEDI_QUATECH_DAQP_CS + tristate "Quatech DAQP PCMCIA data capture card support" + default N + ---help--- + Enable support for the Quatech DAQP PCMCIA data capture cards + DAQP-208 and DAQP-308 + + To compile this driver as a module, choose M here: the module will be + called quatech_daqp_cs. + +endif # COMEDI_PCMCIA_DRIVERS + +menuconfig COMEDI_USB_DRIVERS tristate "Comedi USB drivers" depends on COMEDI && USB default N ---help--- - Enable lots of comedi USB drivers to be built + Enable comedi USB drivers to be built + + Note that the answer to this question won't directly affect the + kernel: saying N will just cause the configurator to skip all + the questions about USB comedi drivers. + +if COMEDI_USB_DRIVERS && USB + +config COMEDI_DT9812 + tristate "DataTranslation DT9812 USB module support" + default N + ---help--- + Enable support for the Data Translation DT9812 USB module + + To compile this driver as a module, choose M here: the module will be + called dt9812. + +config COMEDI_USBDUX + tristate "ITL USBDUX support" + default N + ---help--- + Enable support for the University of Stirling USB DAQ and INCITE + Technology Limited driver + + To compile this driver as a module, choose M here: the module will be + called usbdux. + +config COMEDI_USBDUXFAST + tristate "ITL USB-DUXfast support" + select COMEDI_FC + default N + ---help--- + Enable support for the University of Stirling USB-DUXfast and INCITE + Technology Limited driver + + To compile this driver as a module, choose M here: the module will be + called usbduxfast. + +config COMEDI_VMK80XX + tristate "Velleman VM110/VM140 USB Board support" + default N + ---help--- + Build the Velleman USB Board Low-Level Driver supporting the + K8055/K8061 aka VM110/VM140 devices + + To compile this driver as a module, choose M here: the module will be + called vmk80xx. + +endif # COMEDI_USB_DRIVERS + +menuconfig COMEDI_NI_COMMON + tristate "Comedi National Instruments card support" + depends on COMEDI + default N + ---help--- + Enable comedi support for National Instruments cards. + Modules in this section are used by many comedi NI drivers. + + Note that the answer to this question won't directly affect the + kernel: saying N will just cause the configurator to skip all + the questions about National Instruments cards. + +if COMEDI_NI_COMMON + +config COMEDI_MITE + tristate "NI Mite PCI interface chip support" + depends on PCI + default N + ---help--- + Enable support for National Instruments Mite PCI interface chip + + To compile this driver as a module, choose M here: the module will be + called mite. + +config COMEDI_NI_TIO + tristate "NI general purpose counter support" + depends on COMEDI_MITE + default N + ---help--- + Enable support for National Instruments general purpose counters. + This module is not used directly by end-users. Rather, it + is used by other drivers (for example ni_660x and ni_pcimio) + to provide support for NI's general purpose counters. + + To compile this driver as a modules, choose M here: two modules will + be build: ni_tio and ni_tiocmd. + +config COMEDI_NI_LABPC + tristate "NI Lab-PC and compatibles ISA and PCI support" + select COMEDI_FC + default N + ---help--- + Enable support for National Instruments Lab-PC and compatibles + Lab-PC-1200, Lab-PC-1200AI, Lab-PC+ and PCI-1200. + Kernel-level ISA plug-and-play support for the lab-pc-1200 boards has + not yet been added to the driver. + + To compile this driver as a module, choose M here: the module will be + called ni_labpc. + +endif # COMEDI_NI_COMMON + +config COMEDI_FC + tristate "Comedi shared functions for low-level driver support" + default N + ---help--- + Enable support for shared functions for low-level drivers. + This module is not used directly by end-users. Rather, it + is used by many other comedi drivers. + + To compile this driver as a module, choose M here: the module will be + called comedi_fc. diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index be995144e20d..bf1b29f7da42 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -2,133 +2,136 @@ # # Comedi "helper" modules -obj-$(CONFIG_COMEDI) += comedi_fc.o -obj-$(CONFIG_COMEDI) += comedi_bond.o -obj-$(CONFIG_COMEDI) += comedi_test.o -obj-$(CONFIG_COMEDI) += comedi_parport.o obj-$(CONFIG_COMEDI) += pcm_common.o +# Comedi misc drivers +obj-$(CONFIG_COMEDI_BOND) += comedi_bond.o +obj-$(CONFIG_COMEDI_TEST) += comedi_test.o +obj-$(CONFIG_COMEDI_PARPORT) += comedi_parport.o +obj-$(CONFIG_COMEDI_SERIAL2002) += serial2002.o +obj-$(CONFIG_COMEDI_SKEL) += skel.o + +# Comedi ISA drivers +obj-$(CONFIG_COMEDI_8255) += 8255.o +obj-$(CONFIG_COMEDI_ACL7225B) += acl7225b.o +obj-$(CONFIG_COMEDI_PCL711) += pcl711.o +obj-$(CONFIG_COMEDI_PCL724) += pcl724.o +obj-$(CONFIG_COMEDI_PCL725) += pcl725.o +obj-$(CONFIG_COMEDI_PCL726) += pcl726.o +obj-$(CONFIG_COMEDI_PCL730) += pcl730.o +obj-$(CONFIG_COMEDI_PCL812) += pcl812.o +obj-$(CONFIG_COMEDI_PCL816) += pcl816.o +obj-$(CONFIG_COMEDI_PCL818) += pcl818.o +obj-$(CONFIG_COMEDI_PCM3724) += pcm3724.o +obj-$(CONFIG_COMEDI_PCM3730) += pcm3730.o +obj-$(CONFIG_COMEDI_RTI800) += rti800.o +obj-$(CONFIG_COMEDI_RTI802) += rti802.o +obj-$(CONFIG_COMEDI_DAS08) += das08.o +obj-$(CONFIG_COMEDI_DAS16M1) += das16m1.o +obj-$(CONFIG_COMEDI_DAS16) += das16.o +obj-$(CONFIG_COMEDI_DAS800) += das800.o +obj-$(CONFIG_COMEDI_DAS1800) += das1800.o +obj-$(CONFIG_COMEDI_DAS6402) += das6402.o +obj-$(CONFIG_COMEDI_DT2801) += dt2801.o +obj-$(CONFIG_COMEDI_DT2811) += dt2811.o +obj-$(CONFIG_COMEDI_DT2814) += dt2814.o +obj-$(CONFIG_COMEDI_DT2815) += dt2815.o +obj-$(CONFIG_COMEDI_DT2817) += dt2817.o +obj-$(CONFIG_COMEDI_DT282X) += dt282x.o +obj-$(CONFIG_COMEDI_DMM32AT) += dmm32at.o +obj-$(CONFIG_COMEDI_FL512) += fl512.o +obj-$(CONFIG_COMEDI_AIO_AIO12_8) += aio_aio12_8.o +obj-$(CONFIG_COMEDI_AIO_IIRO_16) += aio_iiro_16.o +obj-$(CONFIG_COMEDI_C6XDIGIO) += c6xdigio.o +obj-$(CONFIG_COMEDI_MPC624) += mpc624.o +obj-$(CONFIG_COMEDI_ADQ12B) += adq12b.o +obj-$(CONFIG_COMEDI_NI_AT_A2150) += ni_at_a2150.o +obj-$(CONFIG_COMEDI_NI_AT_AO) += ni_at_ao.o +obj-$(CONFIG_COMEDI_NI_ATMIO) += ni_atmio.o +obj-$(CONFIG_COMEDI_NI_ATMIO16D) += ni_atmio16d.o +obj-$(CONFIG_COMEDI_PCMAD) += pcmad.o +obj-$(CONFIG_COMEDI_PCMDA12) += pcmda12.o +obj-$(CONFIG_COMEDI_PCMMIO) += pcmmio.o +obj-$(CONFIG_COMEDI_PCMUIO) += pcmuio.o +obj-$(CONFIG_COMEDI_MULTIQ3) += multiq3.o +obj-$(CONFIG_COMEDI_POC) += poc.o + # Comedi PCI drivers -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += 8255.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += acl7225b.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_035.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_1032.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_1500.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_1516.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_1564.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_16xx.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_2016.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_2032.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_2200.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_3001.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_3120.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_3501.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_3xxx.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci6208.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci7230.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci7296.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci7432.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci8164.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci9111.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci9118.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adq12b.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adv_pci1710.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adv_pci1723.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adv_pci_dio.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += aio_aio12_8.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += aio_iiro_16.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += amplc_dio200.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += amplc_pc236.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += amplc_pc263.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += amplc_pci224.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += amplc_pci230.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += c6xdigio.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcidas64.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcidas.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcidda.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcidio.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcimdas.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcimdda.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_bond.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_parport.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_test.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += contec_pci_dio.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += daqboard2000.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das08.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das16m1.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das16.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das1800.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das6402.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das800.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dmm32at.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt2801.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt2811.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt2814.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt2815.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt2817.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt282x.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt3000.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += fl512.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += gsc_hpdi.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += icp_multi.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ii_pci20kc.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += jr3_pci.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ke_counter.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += me4000.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += me_daq.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += mite.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += mpc624.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += multiq3.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_6527.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_65xx.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_660x.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_670x.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_at_a2150.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_at_ao.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_atmio16d.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_atmio.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_labpc.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_pcidio.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_pcimio.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_tiocmd.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_tio.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl711.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl724.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl725.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl726.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl730.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl812.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl816.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl818.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcm3724.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcm3730.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcmad.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcmda12.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcmmio.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcmuio.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += poc.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += rtd520.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += rti800.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += rti802.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += s526.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += s626.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += serial2002.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += skel.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ssv_dnp.o -obj-$(CONFIG_COMEDI_PCI_DRIVERS) += unioxx5.o +obj-$(CONFIG_COMEDI_ADDI_APCI_035) += addi_apci_035.o +obj-$(CONFIG_COMEDI_ADDI_APCI_1032) += addi_apci_1032.o +obj-$(CONFIG_COMEDI_ADDI_APCI_1500) += addi_apci_1500.o +obj-$(CONFIG_COMEDI_ADDI_APCI_1516) += addi_apci_1516.o +obj-$(CONFIG_COMEDI_ADDI_APCI_1564) += addi_apci_1564.o +obj-$(CONFIG_COMEDI_ADDI_APCI_16XX) += addi_apci_16xx.o +obj-$(CONFIG_COMEDI_ADDI_APCI_2016) += addi_apci_2016.o +obj-$(CONFIG_COMEDI_ADDI_APCI_2032) += addi_apci_2032.o +obj-$(CONFIG_COMEDI_ADDI_APCI_2200) += addi_apci_2200.o +obj-$(CONFIG_COMEDI_ADDI_APCI_3001) += addi_apci_3001.o +obj-$(CONFIG_COMEDI_ADDI_APCI_3120) += addi_apci_3120.o +obj-$(CONFIG_COMEDI_ADDI_APCI_3501) += addi_apci_3501.o +obj-$(CONFIG_COMEDI_ADDI_APCI_3XXX) += addi_apci_3xxx.o +obj-$(CONFIG_COMEDI_ADL_PCI6208) += adl_pci6208.o +obj-$(CONFIG_COMEDI_ADL_PCI7230) += adl_pci7230.o +obj-$(CONFIG_COMEDI_ADL_PCI7296) += adl_pci7296.o +obj-$(CONFIG_COMEDI_ADL_PCI7432) += adl_pci7432.o +obj-$(CONFIG_COMEDI_ADL_PCI8164) += adl_pci8164.o +obj-$(CONFIG_COMEDI_ADL_PCI9111) += adl_pci9111.o +obj-$(CONFIG_COMEDI_ADL_PCI9118) += adl_pci9118.o +obj-$(CONFIG_COMEDI_ADV_PCI1710) += adv_pci1710.o +obj-$(CONFIG_COMEDI_ADV_PCI1723) += adv_pci1723.o +obj-$(CONFIG_COMEDI_ADV_PCI_DIO) += adv_pci_dio.o +obj-$(CONFIG_COMEDI_AMPLC_DIO200) += amplc_dio200.o +obj-$(CONFIG_COMEDI_AMPLC_PC236) += amplc_pc236.o +obj-$(CONFIG_COMEDI_AMPLC_PC263) += amplc_pc263.o +obj-$(CONFIG_COMEDI_AMPLC_PCI224) += amplc_pci224.o +obj-$(CONFIG_COMEDI_AMPLC_PCI230) += amplc_pci230.o +obj-$(CONFIG_COMEDI_CONTEC_PCI_DIO) += contec_pci_dio.o +obj-$(CONFIG_COMEDI_DT3000) += dt3000.o +obj-$(CONFIG_COMEDI_UNIOXX5) += unioxx5.o +obj-$(CONFIG_COMEDI_GSC_HPDI) += gsc_hpdi.o +obj-$(CONFIG_COMEDI_ICP_MULTI) += icp_multi.o +obj-$(CONFIG_COMEDI_II_PCI20KC) += ii_pci20kc.o +obj-$(CONFIG_COMEDI_DAQBOARD2000) += daqboard2000.o +obj-$(CONFIG_COMEDI_JR3_PCI) += jr3_pci.o +obj-$(CONFIG_COMEDI_KE_COUNTER) += ke_counter.o +obj-$(CONFIG_COMEDI_CB_PCIDAS64) += cb_pcidas64.o +obj-$(CONFIG_COMEDI_CB_PCIDAS) += cb_pcidas.o +obj-$(CONFIG_COMEDI_CB_PCIDDA) += cb_pcidda.o +obj-$(CONFIG_COMEDI_CB_PCIDIO) += cb_pcidio.o +obj-$(CONFIG_COMEDI_CB_PCIMDAS) += cb_pcimdas.o +obj-$(CONFIG_COMEDI_CB_PCIMDDA) += cb_pcimdda.o +obj-$(CONFIG_COMEDI_ME4000) += me4000.o +obj-$(CONFIG_COMEDI_ME_DAQ) += me_daq.o +obj-$(CONFIG_COMEDI_NI_6527) += ni_6527.o +obj-$(CONFIG_COMEDI_NI_65XX) += ni_65xx.o +obj-$(CONFIG_COMEDI_NI_660X) += ni_660x.o +obj-$(CONFIG_COMEDI_NI_670X) += ni_670x.o +obj-$(CONFIG_COMEDI_NI_PCIDIO) += ni_pcidio.o +obj-$(CONFIG_COMEDI_NI_PCIMIO) += ni_pcimio.o +obj-$(CONFIG_COMEDI_RTD520) += rtd520.o +obj-$(CONFIG_COMEDI_S526) += s526.o +obj-$(CONFIG_COMEDI_S626) += s626.o +obj-$(CONFIG_COMEDI_SSV_DNP) += ssv_dnp.o # Comedi PCMCIA drivers -obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += cb_das16_cs.o -obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += das08_cs.o -obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += ni_daq_700.o -obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += ni_daq_dio24.o -obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += ni_labpc_cs.o -obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += ni_mio_cs.o -obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += quatech_daqp_cs.o +obj-$(CONFIG_COMEDI_CB_DAS16_CS) += cb_das16_cs.o +obj-$(CONFIG_COMEDI_DAS08_CS) += das08_cs.o +obj-$(CONFIG_COMEDI_NI_DAQ_700_CS) += ni_daq_700.o +obj-$(CONFIG_COMEDI_NI_DAQ_DIO24_CS) += ni_daq_dio24.o +obj-$(CONFIG_COMEDI_NI_LABPC_CS) += ni_labpc_cs.o +obj-$(CONFIG_COMEDI_NI_MIO_CS) += ni_mio_cs.o +obj-$(CONFIG_COMEDI_QUATECH_DAQP_CS) += quatech_daqp_cs.o # Comedi USB drivers -obj-$(CONFIG_COMEDI_USB_DRIVERS) += dt9812.o -obj-$(CONFIG_COMEDI_USB_DRIVERS) += usbdux.o -obj-$(CONFIG_COMEDI_USB_DRIVERS) += usbduxfast.o -obj-$(CONFIG_COMEDI_USB_DRIVERS) += vmk80xx.o +obj-$(CONFIG_COMEDI_DT9812) += dt9812.o +obj-$(CONFIG_COMEDI_USBDUX) += usbdux.o +obj-$(CONFIG_COMEDI_USBDUXFAST) += usbduxfast.o +obj-$(CONFIG_COMEDI_VMK80XX) += vmk80xx.o + +# Comedi NI drivers +obj-$(CONFIG_COMEDI_MITE) += mite.o +obj-$(CONFIG_COMEDI_NI_TIO) += ni_tio.o +obj-$(CONFIG_COMEDI_NI_TIO) += ni_tiocmd.o +obj-$(CONFIG_COMEDI_NI_LABPC) += ni_labpc.o +obj-$(CONFIG_COMEDI_FC) += comedi_fc.o diff --git a/drivers/staging/comedi/kcomedilib/Makefile b/drivers/staging/comedi/kcomedilib/Makefile index 5951f86a840e..18ee99bdde08 100644 --- a/drivers/staging/comedi/kcomedilib/Makefile +++ b/drivers/staging/comedi/kcomedilib/Makefile @@ -1,3 +1,3 @@ -obj-$(CONFIG_COMEDI) += kcomedilib.o +obj-$(CONFIG_COMEDI_KCOMEDILIB) += kcomedilib.o kcomedilib-objs := kcomedilib_main.o -- cgit v1.2.3 From 77f047e25716cdefae7273d4e55f2cf74144c553 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 18 May 2010 14:29:33 -0700 Subject: Staging: comedi: fix up build error from last Kconfig changes We need the 8255 module to be present for some PCI comedi modules. So for now, just build the thing. We need some better Kconfig rules to figure this out properly. Cc: Alexander Kurz Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index bf1b29f7da42..5ccf246e2526 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -57,6 +57,7 @@ obj-$(CONFIG_COMEDI_MULTIQ3) += multiq3.o obj-$(CONFIG_COMEDI_POC) += poc.o # Comedi PCI drivers +obj-$(CONFIG_COMEDI_PCI_DRIVERS) += 8255.o obj-$(CONFIG_COMEDI_ADDI_APCI_035) += addi_apci_035.o obj-$(CONFIG_COMEDI_ADDI_APCI_1032) += addi_apci_1032.o obj-$(CONFIG_COMEDI_ADDI_APCI_1500) += addi_apci_1500.o -- cgit v1.2.3 From ba2450b89bd9dce7d8926d919a67ed515be3e05f Mon Sep 17 00:00:00 2001 From: Alexander Kurz Date: Sat, 15 May 2010 16:09:01 +0400 Subject: Staging: comedi: Kconfig dependancy fixes There are three minor changes I would like to do on my last patch: * Comedi is formally not dependant on any hardware, e.g. it is possible to use comedi_test without (PCI || PCMCIA || PCCARD || USB || ISA) * comedi_parport is not dependant on PARPORT_PC. * indirect ni_mio_cs (16-bit PCMCIA) dependancy on mite PCI-chip may confuse users, thus changing COMEDI_NI_TIO depends on COMEDI_MITE to select COMEDI_MITE. Signed-off-by: Alexander Kurz Cc: Ian Abbott Cc: Frank Mori Hess Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 283ea0ceddf0..8ce307e64b58 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -1,7 +1,7 @@ config COMEDI tristate "Data acquisition support (comedi)" default N - depends on m && (PCI || PCMCIA || PCCARD || USB) + depends on m ---help--- Enable support a wide range of data acquisition devices for Linux. @@ -57,7 +57,6 @@ config COMEDI_TEST config COMEDI_PARPORT tristate "Parallel port support" - depends on PARPORT_PC default N ---help--- Enable support for the standard parallel port. @@ -1266,7 +1265,7 @@ config COMEDI_MITE config COMEDI_NI_TIO tristate "NI general purpose counter support" - depends on COMEDI_MITE + select COMEDI_MITE default N ---help--- Enable support for National Instruments general purpose counters. -- cgit v1.2.3 From e4146bb9088c01c8b6e82be11f0c371f8aff023c Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 16 May 2010 02:28:49 +0100 Subject: PCI: Disable MSI for MCP55 on P5N32-E SLI As reported in , MSI appears to be broken for this on-board device. We already have a quirk for the P5N32-SLI Premium; extend it to cover both variants of the board. Reported-by: Romain DEGEZ Signed-off-by: Ben Hutchings Cc: stable@kernel.org Signed-off-by: Jesse Barnes --- drivers/pci/quirks.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 27c0e6eb7136..480782530218 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2218,15 +2218,16 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE, ht_enable_msi_mapping); -/* The P5N32-SLI Premium motherboard from Asus has a problem with msi +/* The P5N32-SLI motherboards from Asus have a problem with msi * for the MCP55 NIC. It is not yet determined whether the msi problem * also affects other devices. As for now, turn off msi for this device. */ static void __devinit nvenet_msi_disable(struct pci_dev *dev) { - if (dmi_name_in_vendors("P5N32-SLI PREMIUM")) { + if (dmi_name_in_vendors("P5N32-SLI PREMIUM") || + dmi_name_in_vendors("P5N32-E SLI")) { dev_info(&dev->dev, - "Disabling msi for MCP55 NIC on P5N32-SLI Premium\n"); + "Disabling msi for MCP55 NIC on P5N32-SLI\n"); dev->no_msi = 1; } } -- cgit v1.2.3 From 9313ff450400e6a2ab10fe6b9bdb12a828329410 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 18 May 2010 10:42:53 -0400 Subject: PCI quirks: disable msi on AMD rs4xx internal gfx bridges Doesn't work reliably for internal gfx. Fixes kernel bug https://bugzilla.kernel.org/show_bug.cgi?id=15626. Signed-off-by: Alex Deucher Cc: Stable Signed-off-by: Jesse Barnes --- drivers/pci/quirks.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 480782530218..e5861d5a2e4d 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2127,6 +2127,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9602, quirk_disable_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASUSTEK, 0x9602, quirk_disable_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AI, 0x9602, quirk_disable_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0xa238, quirk_disable_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x5a3f, quirk_disable_msi); /* Go through the list of Hypertransport capabilities and * return 1 if a HT MSI capability is found and enabled */ -- cgit v1.2.3 From 06f1962ab475bdee3ae17afbaecee5b23f3cd5f0 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Sun, 16 May 2010 21:11:37 +0100 Subject: Staging: iio: adis16220 vibration sensor driver Signed-off-by: Barry Song Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/Kconfig | 7 + drivers/staging/iio/accel/Makefile | 3 + drivers/staging/iio/accel/accel.h | 6 + drivers/staging/iio/accel/adis16220.h | 150 +++++++ drivers/staging/iio/accel/adis16220_core.c | 664 +++++++++++++++++++++++++++++ 5 files changed, 830 insertions(+) create mode 100644 drivers/staging/iio/accel/adis16220.h create mode 100644 drivers/staging/iio/accel/adis16220_core.c (limited to 'drivers') diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig index 8f3f70f10a38..b4e57d1bc87d 100644 --- a/drivers/staging/iio/accel/Kconfig +++ b/drivers/staging/iio/accel/Kconfig @@ -12,6 +12,13 @@ config ADIS16209 Say yes here to build support for Analog Devices adis16209 dual-axis digital inclinometer and accelerometer. +config ADIS16220 + tristate "Analog Devices ADIS16220 Programmable Digital Vibration Sensor driver" + depends on SPI + help + Say yes here to build support for Analog Devices adis16220 programmable + digital vibration sensor. + config ADIS16240 tristate "Analog Devices ADIS16240 Programmable Impact Sensor and Recorder" depends on SPI diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile index 0e6762c34878..c34b13634c2d 100644 --- a/drivers/staging/iio/accel/Makefile +++ b/drivers/staging/iio/accel/Makefile @@ -5,6 +5,9 @@ adis16209-y := adis16209_core.o adis16209-$(CONFIG_IIO_RING_BUFFER) += adis16209_ring.o adis16209_trigger.o obj-$(CONFIG_ADIS16209) += adis16209.o +adis16220-y := adis16220_core.o +obj-$(CONFIG_ADIS16220) += adis16220.o + adis16240-y := adis16240_core.o adis16240-$(CONFIG_IIO_RING_BUFFER) += adis16240_ring.o adis16240_trigger.o obj-$(CONFIG_ADIS16240) += adis16240.o diff --git a/drivers/staging/iio/accel/accel.h b/drivers/staging/iio/accel/accel.h index 059209c9e339..1b6e37f76200 100644 --- a/drivers/staging/iio/accel/accel.h +++ b/drivers/staging/iio/accel/accel.h @@ -2,6 +2,9 @@ #include "../sysfs.h" /* Accelerometer types of attribute */ +#define IIO_DEV_ATTR_ACCEL_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(accel_offset, _mode, _show, _store, _addr) + #define IIO_DEV_ATTR_ACCEL_X_OFFSET(_mode, _show, _store, _addr) \ IIO_DEVICE_ATTR(accel_x_offset, _mode, _show, _store, _addr) @@ -20,6 +23,9 @@ #define IIO_DEV_ATTR_ACCEL_Z_GAIN(_mode, _show, _store, _addr) \ IIO_DEVICE_ATTR(accel_z_gain, _mode, _show, _store, _addr) +#define IIO_DEV_ATTR_ACCEL(_show, _addr) \ + IIO_DEVICE_ATTR(accel_raw, S_IRUGO, _show, NULL, _addr) + #define IIO_DEV_ATTR_ACCEL_X(_show, _addr) \ IIO_DEVICE_ATTR(accel_x_raw, S_IRUGO, _show, NULL, _addr) diff --git a/drivers/staging/iio/accel/adis16220.h b/drivers/staging/iio/accel/adis16220.h new file mode 100644 index 000000000000..6b49f70eff47 --- /dev/null +++ b/drivers/staging/iio/accel/adis16220.h @@ -0,0 +1,150 @@ +#ifndef SPI_ADIS16220_H_ +#define SPI_ADIS16220_H_ + +#define ADIS16220_STARTUP_DELAY 220 /* ms */ + +#define ADIS16220_READ_REG(a) a +#define ADIS16220_WRITE_REG(a) ((a) | 0x80) + +/* Flash memory write count */ +#define ADIS16220_FLASH_CNT 0x00 +/* Control, acceleration offset adjustment control */ +#define ADIS16220_ACCL_NULL 0x02 +/* Control, AIN1 offset adjustment control */ +#define ADIS16220_AIN1_NULL 0x04 +/* Control, AIN2 offset adjustment control */ +#define ADIS16220_AIN2_NULL 0x06 +/* Output, power supply during capture */ +#define ADIS16220_CAPT_SUPPLY 0x0A +/* Output, temperature during capture */ +#define ADIS16220_CAPT_TEMP 0x0C +/* Output, peak acceleration during capture */ +#define ADIS16220_CAPT_PEAKA 0x0E +/* Output, peak AIN1 level during capture */ +#define ADIS16220_CAPT_PEAK1 0x10 +/* Output, peak AIN2 level during capture */ +#define ADIS16220_CAPT_PEAK2 0x12 +/* Output, capture buffer for acceleration */ +#define ADIS16220_CAPT_BUFA 0x14 +/* Output, capture buffer for AIN1 */ +#define ADIS16220_CAPT_BUF1 0x16 +/* Output, capture buffer for AIN2 */ +#define ADIS16220_CAPT_BUF2 0x18 +/* Control, capture buffer address pointer */ +#define ADIS16220_CAPT_PNTR 0x1A +/* Control, capture control register */ +#define ADIS16220_CAPT_CTRL 0x1C +/* Control, capture period (automatic mode) */ +#define ADIS16220_CAPT_PRD 0x1E +/* Control, Alarm A, acceleration peak threshold */ +#define ADIS16220_ALM_MAGA 0x20 +/* Control, Alarm 1, AIN1 peak threshold */ +#define ADIS16220_ALM_MAG1 0x22 +/* Control, Alarm 2, AIN2 peak threshold */ +#define ADIS16220_ALM_MAG2 0x24 +/* Control, Alarm S, peak threshold */ +#define ADIS16220_ALM_MAGS 0x26 +/* Control, alarm configuration register */ +#define ADIS16220_ALM_CTRL 0x28 +/* Control, general I/O configuration */ +#define ADIS16220_GPIO_CTRL 0x32 +/* Control, self-test control, AIN configuration */ +#define ADIS16220_MSC_CTRL 0x34 +/* Control, digital I/O configuration */ +#define ADIS16220_DIO_CTRL 0x36 +/* Control, filter configuration */ +#define ADIS16220_AVG_CNT 0x38 +/* Status, system status */ +#define ADIS16220_DIAG_STAT 0x3C +/* Control, system commands */ +#define ADIS16220_GLOB_CMD 0x3E +/* Status, self-test response */ +#define ADIS16220_ST_DELTA 0x40 +/* Lot Identification Code 1 */ +#define ADIS16220_LOT_ID1 0x52 +/* Lot Identification Code 2 */ +#define ADIS16220_LOT_ID2 0x54 +/* Product identifier; convert to decimal = 16220 */ +#define ADIS16220_PROD_ID 0x56 +/* Serial number */ +#define ADIS16220_SERIAL_NUM 0x58 + +#define ADIS16220_CAPTURE_SIZE 2048 + +/* MSC_CTRL */ +#define ADIS16220_MSC_CTRL_SELF_TEST_EN (1 << 8) +#define ADIS16220_MSC_CTRL_POWER_SUP_COM_AIN1 (1 << 1) +#define ADIS16220_MSC_CTRL_POWER_SUP_COM_AIN2 (1 << 0) + +/* DIO_CTRL */ +#define ADIS16220_MSC_CTRL_DIO2_BUSY_IND (3<<4) +#define ADIS16220_MSC_CTRL_DIO1_BUSY_IND (3<<2) +#define ADIS16220_MSC_CTRL_DIO2_ACT_HIGH (1<<1) +#define ADIS16220_MSC_CTRL_DIO1_ACT_HIGH (1<<0) + +/* DIAG_STAT */ +/* AIN2 sample > ALM_MAG2 */ +#define ADIS16220_DIAG_STAT_ALM_MAG2 (1<<14) +/* AIN1 sample > ALM_MAG1 */ +#define ADIS16220_DIAG_STAT_ALM_MAG1 (1<<13) +/* Acceleration sample > ALM_MAGA */ +#define ADIS16220_DIAG_STAT_ALM_MAGA (1<<12) +/* Error condition programmed into ALM_MAGS[11:0] and ALM_CTRL[5:4] is true */ +#define ADIS16220_DIAG_STAT_ALM_MAGS (1<<11) +/* |Peak value in AIN2 data capture| > ALM_MAG2 */ +#define ADIS16220_DIAG_STAT_PEAK_AIN2 (1<<10) +/* |Peak value in AIN1 data capture| > ALM_MAG1 */ +#define ADIS16220_DIAG_STAT_PEAK_AIN1 (1<<9) +/* |Peak value in acceleration data capture| > ALM_MAGA */ +#define ADIS16220_DIAG_STAT_PEAK_ACCEL (1<<8) +/* Data ready, capture complete */ +#define ADIS16220_DIAG_STAT_DATA_RDY (1<<7) +#define ADIS16220_DIAG_STAT_FLASH_CHK (1<<6) +#define ADIS16220_DIAG_STAT_SELF_TEST (1<<5) +/* Capture period violation/interruption */ +#define ADIS16220_DIAG_STAT_VIOLATION (1<<4) +/* SPI communications failure */ +#define ADIS16220_DIAG_STAT_SPI_FAIL (1<<3) +/* Flash update failure */ +#define ADIS16220_DIAG_STAT_FLASH_UPT (1<<2) +/* Power supply above 3.625 V */ +#define ADIS16220_DIAG_STAT_POWER_HIGH (1<<1) +/* Power supply below 3.15 V */ +#define ADIS16220_DIAG_STAT_POWER_LOW (1<<0) + +/* GLOB_CMD */ +#define ADIS16220_GLOB_CMD_SW_RESET (1<<7) +#define ADIS16220_GLOB_CMD_SELF_TEST (1<<2) +#define ADIS16220_GLOB_CMD_PWR_DOWN (1<<1) + +#define ADIS16220_MAX_TX 2048 +#define ADIS16220_MAX_RX 2048 + +#define ADIS16220_SPI_BURST (u32)(1000 * 1000) +#define ADIS16220_SPI_FAST (u32)(2000 * 1000) + +/** + * struct adis16220_state - device instance specific data + * @us: actual spi_device + * @work_trigger_to_ring: bh for triggered event handling + * @work_cont_thresh: CLEAN + * @inter: used to check if new interrupt has been triggered + * @last_timestamp: passing timestamp from th to bh of interrupt handler + * @indio_dev: industrial I/O device structure + * @trig: data ready trigger registered with iio + * @tx: transmit buffer + * @rx: recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct adis16220_state { + struct spi_device *us; + struct iio_dev *indio_dev; + u8 *tx; + u8 *rx; + struct bin_attribute accel_bin; + struct bin_attribute adc1_bin; + struct bin_attribute adc2_bin; + struct mutex buf_lock; +}; + +#endif /* SPI_ADIS16220_H_ */ diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c new file mode 100644 index 000000000000..8b845d9b7b9e --- /dev/null +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -0,0 +1,664 @@ +/* + * ADIS16220 Programmable Digital Vibration Sensor driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "accel.h" +#include "../adc/adc.h" + +#include "adis16220.h" + +#define DRIVER_NAME "adis16220" + +static int adis16220_check_status(struct device *dev); + +/** + * adis16220_spi_write_reg_8() - write single byte to a register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the register to be written + * @val: the value to write + **/ +static int adis16220_spi_write_reg_8(struct device *dev, + u8 reg_address, + u8 val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16220_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16220_WRITE_REG(reg_address); + st->tx[1] = val; + + ret = spi_write(st->us, st->tx, 2); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16220_spi_write_reg_16() - write 2 bytes to a pair of registers + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: value to be written + **/ +static int adis16220_spi_write_reg_16(struct device *dev, + u8 lower_reg_address, + u16 value) +{ + int ret; + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16220_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 25, + }, { + .tx_buf = st->tx + 2, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 25, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16220_WRITE_REG(lower_reg_address); + st->tx[1] = value & 0xFF; + st->tx[2] = ADIS16220_WRITE_REG(lower_reg_address + 1); + st->tx[3] = (value >> 8) & 0xFF; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16220_spi_read_reg_16() - read 2 bytes from a 16-bit register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: somewhere to pass back the value read + **/ +static int adis16220_spi_read_reg_16(struct device *dev, + u8 lower_reg_address, + u16 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16220_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 25, + }, { + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 25, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16220_READ_REG(lower_reg_address); + st->tx[1] = 0; + st->tx[2] = 0; + st->tx[3] = 0; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, + "problem when reading 16 bit register 0x%02X", + lower_reg_address); + goto error_ret; + } + *val = (st->rx[0] << 8) | st->rx[1]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static ssize_t adis16220_spi_read_signed(struct device *dev, + struct device_attribute *attr, + char *buf, + unsigned bits) +{ + int ret; + s16 val = 0; + unsigned shift = 16 - bits; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = adis16220_spi_read_reg_16(dev, this_attr->address, (u16 *)&val); + if (ret) + return ret; + + val = ((s16)(val << shift) >> shift); + return sprintf(buf, "%d\n", val); +} + +static ssize_t adis16220_read_12bit_unsigned(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u16 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = adis16220_spi_read_reg_16(dev, this_attr->address, &val); + if (ret) + return ret; + + return sprintf(buf, "%u\n", val & 0x0FFF); +} + +static ssize_t adis16220_read_16bit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + ssize_t ret; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + ret = adis16220_spi_read_signed(dev, attr, buf, 16); + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t adis16220_write_16bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = adis16220_spi_write_reg_16(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static int adis16220_capture(struct device *dev) +{ + int ret; + ret = adis16220_spi_write_reg_16(dev, + ADIS16220_GLOB_CMD, + 0xBF08); /* initiates a manual data capture */ + if (ret) + dev_err(dev, "problem beginning capture"); + + msleep(10); /* delay for capture to finish */ + + return ret; +} + +static int adis16220_reset(struct device *dev) +{ + int ret; + ret = adis16220_spi_write_reg_8(dev, + ADIS16220_GLOB_CMD, + ADIS16220_GLOB_CMD_SW_RESET); + if (ret) + dev_err(dev, "problem resetting device"); + + return ret; +} + +static ssize_t adis16220_write_reset(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + if (len < 1) + return -1; + switch (buf[0]) { + case '1': + case 'y': + case 'Y': + return adis16220_reset(dev) == 0 ? len : -EIO; + } + return -1; +} + +static ssize_t adis16220_write_capture(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + if (len < 1) + return -1; + switch (buf[0]) { + case '1': + case 'y': + case 'Y': + return adis16220_capture(dev) == 0 ? len : -EIO; + } + return -1; +} + +static int adis16220_self_test(struct device *dev) +{ + int ret; + ret = adis16220_spi_write_reg_16(dev, + ADIS16220_MSC_CTRL, + ADIS16220_MSC_CTRL_SELF_TEST_EN); + if (ret) { + dev_err(dev, "problem starting self test"); + goto err_ret; + } + + adis16220_check_status(dev); + +err_ret: + return ret; +} + +static int adis16220_check_status(struct device *dev) +{ + u16 status; + int ret; + + ret = adis16220_spi_read_reg_16(dev, ADIS16220_DIAG_STAT, &status); + + if (ret < 0) { + dev_err(dev, "Reading status failed\n"); + goto error_ret; + } + ret = status & 0x7F; + + if (status & ADIS16220_DIAG_STAT_VIOLATION) + dev_err(dev, "Capture period violation/interruption\n"); + if (status & ADIS16220_DIAG_STAT_SPI_FAIL) + dev_err(dev, "SPI failure\n"); + if (status & ADIS16220_DIAG_STAT_FLASH_UPT) + dev_err(dev, "Flash update failed\n"); + if (status & ADIS16220_DIAG_STAT_POWER_HIGH) + dev_err(dev, "Power supply above 5.25V\n"); + if (status & ADIS16220_DIAG_STAT_POWER_LOW) + dev_err(dev, "Power supply below 4.75V\n"); + +error_ret: + return ret; +} + +static int adis16220_initial_setup(struct adis16220_state *st) +{ + int ret; + struct device *dev = &st->indio_dev->dev; + + /* Do self test */ + ret = adis16220_self_test(dev); + if (ret) { + dev_err(dev, "self test failure"); + goto err_ret; + } + + /* Read status register to check the result */ + ret = adis16220_check_status(dev); + if (ret) { + adis16220_reset(dev); + dev_err(dev, "device not playing ball -> reset"); + msleep(ADIS16220_STARTUP_DELAY); + ret = adis16220_check_status(dev); + if (ret) { + dev_err(dev, "giving up"); + goto err_ret; + } + } + + printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n", + st->us->chip_select, st->us->irq); + +err_ret: + return ret; +} + +static ssize_t adis16220_capture_buffer_read(struct adis16220_state *st, + char *buf, + loff_t off, + size_t count, + int addr) +{ + struct spi_message msg; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 25, + }, { + .tx_buf = st->tx, + .rx_buf = st->rx, + .bits_per_word = 8, + .cs_change = 1, + .delay_usecs = 25, + }, + }; + int ret; + int i; + + if (unlikely(!count)) + return count; + + if ((off >= ADIS16220_CAPTURE_SIZE) || (count & 1) || (off & 1)) + return -EINVAL; + + if (off + count > ADIS16220_CAPTURE_SIZE) + count = ADIS16220_CAPTURE_SIZE - off; + + /* write the begin position of capture buffer */ + ret = adis16220_spi_write_reg_16(&st->indio_dev->dev, + ADIS16220_CAPT_PNTR, + off > 1); + if (ret) + return -EIO; + + /* read count/2 values from capture buffer */ + mutex_lock(&st->buf_lock); + + for (i = 0; i < count; i += 2) { + st->tx[i] = ADIS16220_READ_REG(addr); + st->tx[i + 1] = 0; + } + xfers[1].len = count; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + + mutex_unlock(&st->buf_lock); + return -EIO; + } + + memcpy(buf, st->rx, count); + + mutex_unlock(&st->buf_lock); + return count; +} + +static ssize_t adis16220_accel_bin_read(struct kobject *kobj, + struct bin_attribute *attr, + char *buf, + loff_t off, + size_t count) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16220_state *st = iio_dev_get_devdata(indio_dev); + + return adis16220_capture_buffer_read(st, buf, + off, count, + ADIS16220_CAPT_BUFA); +} + +static ssize_t adis16220_adc1_bin_read(struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, + size_t count) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16220_state *st = iio_dev_get_devdata(indio_dev); + + return adis16220_capture_buffer_read(st, buf, + off, count, + ADIS16220_CAPT_BUF1); +} + +static ssize_t adis16220_adc2_bin_read(struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, + size_t count) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16220_state *st = iio_dev_get_devdata(indio_dev); + + return adis16220_capture_buffer_read(st, buf, + off, count, + ADIS16220_CAPT_BUF2); +} + +static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16220_read_12bit_unsigned, + ADIS16220_CAPT_SUPPLY); +static IIO_CONST_ATTR(in_supply_scale, "0.0012207"); +static IIO_DEV_ATTR_ACCEL(adis16220_read_16bit, ADIS16220_CAPT_BUFA); +static IIO_DEVICE_ATTR(accel_peak_raw, S_IRUGO, adis16220_read_16bit, + NULL, ADIS16220_CAPT_PEAKA); +static IIO_DEV_ATTR_ACCEL_OFFSET(S_IWUSR | S_IRUGO, + adis16220_read_16bit, + adis16220_write_16bit, + ADIS16220_ACCL_NULL); +static IIO_DEV_ATTR_TEMP_RAW(adis16220_read_12bit_unsigned); +static IIO_CONST_ATTR(temp_offset, "25"); +static IIO_CONST_ATTR(temp_scale, "-0.47"); + +static IIO_DEV_ATTR_IN_RAW(0, adis16220_read_16bit, ADIS16220_CAPT_BUF1); +static IIO_DEV_ATTR_IN_RAW(1, adis16220_read_16bit, ADIS16220_CAPT_BUF2); + +static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, + adis16220_write_reset, 0); + +#define IIO_DEV_ATTR_CAPTURE(_store) \ + IIO_DEVICE_ATTR(capture, S_IWUGO, NULL, _store, 0) + +static IIO_DEV_ATTR_CAPTURE(adis16220_write_capture); + +#define IIO_DEV_ATTR_CAPTURE_COUNT(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(capture_count, _mode, _show, _store, _addr) + +static IIO_DEV_ATTR_CAPTURE_COUNT(S_IWUSR | S_IRUGO, + adis16220_read_16bit, + adis16220_write_16bit, + ADIS16220_CAPT_PNTR); + +static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("100200"); + +static IIO_CONST_ATTR(name, "adis16220"); + +static struct attribute *adis16220_attributes[] = { + &iio_dev_attr_in_supply_raw.dev_attr.attr, + &iio_const_attr_in_supply_scale.dev_attr.attr, + &iio_dev_attr_accel_raw.dev_attr.attr, + &iio_dev_attr_accel_offset.dev_attr.attr, + &iio_dev_attr_accel_peak_raw.dev_attr.attr, + &iio_dev_attr_temp_raw.dev_attr.attr, + &iio_dev_attr_in0_raw.dev_attr.attr, + &iio_dev_attr_in1_raw.dev_attr.attr, + &iio_const_attr_temp_offset.dev_attr.attr, + &iio_const_attr_temp_scale.dev_attr.attr, + &iio_const_attr_available_sampling_frequency.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_dev_attr_capture.dev_attr.attr, + &iio_dev_attr_capture_count.dev_attr.attr, + &iio_const_attr_name.dev_attr.attr, + NULL +}; + +static const struct attribute_group adis16220_attribute_group = { + .attrs = adis16220_attributes, +}; + +static int __devinit adis16220_probe(struct spi_device *spi) +{ + int ret, regdone = 0; + struct adis16220_state *st = kzalloc(sizeof *st, GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + goto error_ret; + } + /* this is only used for removal purposes */ + spi_set_drvdata(spi, st); + + /* Allocate the comms buffers */ + st->rx = kzalloc(sizeof(*st->rx)*ADIS16220_MAX_RX, GFP_KERNEL); + if (st->rx == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->tx = kzalloc(sizeof(*st->tx)*ADIS16220_MAX_TX, GFP_KERNEL); + if (st->tx == NULL) { + ret = -ENOMEM; + goto error_free_rx; + } + st->us = spi; + mutex_init(&st->buf_lock); + /* setup the industrialio driver allocated elements */ + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_tx; + } + + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->attrs = &adis16220_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_free_dev; + regdone = 1; + + st->accel_bin.attr.name = "accel_bin"; + st->accel_bin.attr.mode = S_IRUGO; + st->accel_bin.attr.owner = THIS_MODULE; + st->accel_bin.read = adis16220_accel_bin_read; + st->accel_bin.size = ADIS16220_CAPTURE_SIZE; + + ret = sysfs_create_bin_file(&st->indio_dev->dev.kobj, &st->accel_bin); + if (ret) + goto error_free_dev; + + st->adc1_bin.attr.name = "adc1_bin"; + st->adc1_bin.attr.mode = S_IRUGO; + st->adc1_bin.attr.owner = THIS_MODULE; + st->adc1_bin.read = adis16220_adc1_bin_read; + st->adc1_bin.size = ADIS16220_CAPTURE_SIZE; + + ret = sysfs_create_bin_file(&st->indio_dev->dev.kobj, &st->adc1_bin); + if (ret) + goto error_rm_accel_bin; + + st->adc2_bin.attr.name = "adc2_bin"; + st->adc2_bin.attr.mode = S_IRUGO; + st->adc2_bin.attr.owner = THIS_MODULE; + st->adc2_bin.read = adis16220_adc2_bin_read; + st->adc2_bin.size = ADIS16220_CAPTURE_SIZE; + + ret = sysfs_create_bin_file(&st->indio_dev->dev.kobj, &st->adc2_bin); + if (ret) + goto error_rm_adc1_bin; + + /* Get the device into a sane initial state */ + ret = adis16220_initial_setup(st); + if (ret) + goto error_rm_adc2_bin; + return 0; + +error_rm_adc2_bin: + sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &st->adc2_bin); +error_rm_adc1_bin: + sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &st->adc1_bin); +error_rm_accel_bin: + sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &st->accel_bin); +error_free_dev: + if (regdone) + iio_device_unregister(st->indio_dev); + else + iio_free_device(st->indio_dev); +error_free_tx: + kfree(st->tx); +error_free_rx: + kfree(st->rx); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +static int adis16220_remove(struct spi_device *spi) +{ + struct adis16220_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + + flush_scheduled_work(); + + sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &st->adc2_bin); + sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &st->adc1_bin); + sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &st->accel_bin); + iio_device_unregister(indio_dev); + kfree(st->tx); + kfree(st->rx); + kfree(st); + + return 0; +} + +static struct spi_driver adis16220_driver = { + .driver = { + .name = "adis16220", + .owner = THIS_MODULE, + }, + .probe = adis16220_probe, + .remove = __devexit_p(adis16220_remove), +}; + +static __init int adis16220_init(void) +{ + return spi_register_driver(&adis16220_driver); +} +module_init(adis16220_init); + +static __exit void adis16220_exit(void) +{ + spi_unregister_driver(&adis16220_driver); +} +module_exit(adis16220_exit); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADIS16220 Digital Vibration Sensor"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 9a3af585e7fe3df35b233977579b5ab6e4c7005f Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 May 2010 21:11:38 +0100 Subject: Staging: iio: adis16220 extract bin_attribute structures from state Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/adis16220.h | 3 - drivers/staging/iio/accel/adis16220_core.c | 106 +++++++++++++++-------------- 2 files changed, 56 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/adis16220.h b/drivers/staging/iio/accel/adis16220.h index 6b49f70eff47..2abf4850b373 100644 --- a/drivers/staging/iio/accel/adis16220.h +++ b/drivers/staging/iio/accel/adis16220.h @@ -141,9 +141,6 @@ struct adis16220_state { struct iio_dev *indio_dev; u8 *tx; u8 *rx; - struct bin_attribute accel_bin; - struct bin_attribute adc1_bin; - struct bin_attribute adc2_bin; struct mutex buf_lock; }; diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index 8b845d9b7b9e..6de439fd1675 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -27,8 +27,6 @@ #define DRIVER_NAME "adis16220" -static int adis16220_check_status(struct device *dev); - /** * adis16220_spi_write_reg_8() - write single byte to a register * @dev: device associated with child of actual device (iio_dev or iio_trig) @@ -133,8 +131,6 @@ static int adis16220_spi_read_reg_16(struct device *dev, mutex_lock(&st->buf_lock); st->tx[0] = ADIS16220_READ_REG(lower_reg_address); st->tx[1] = 0; - st->tx[2] = 0; - st->tx[3] = 0; spi_message_init(&msg); spi_message_add_tail(&xfers[0], &msg); @@ -275,23 +271,6 @@ static ssize_t adis16220_write_capture(struct device *dev, return -1; } -static int adis16220_self_test(struct device *dev) -{ - int ret; - ret = adis16220_spi_write_reg_16(dev, - ADIS16220_MSC_CTRL, - ADIS16220_MSC_CTRL_SELF_TEST_EN); - if (ret) { - dev_err(dev, "problem starting self test"); - goto err_ret; - } - - adis16220_check_status(dev); - -err_ret: - return ret; -} - static int adis16220_check_status(struct device *dev) { u16 status; @@ -320,6 +299,23 @@ error_ret: return ret; } +static int adis16220_self_test(struct device *dev) +{ + int ret; + ret = adis16220_spi_write_reg_16(dev, + ADIS16220_MSC_CTRL, + ADIS16220_MSC_CTRL_SELF_TEST_EN); + if (ret) { + dev_err(dev, "problem starting self test"); + goto err_ret; + } + + adis16220_check_status(dev); + +err_ret: + return ret; +} + static int adis16220_initial_setup(struct adis16220_state *st) { int ret; @@ -433,6 +429,15 @@ static ssize_t adis16220_accel_bin_read(struct kobject *kobj, ADIS16220_CAPT_BUFA); } +static struct bin_attribute accel_bin = { + .attr = { + .name = "accel_bin", + .mode = S_IRUGO, + }, + .read = adis16220_accel_bin_read, + .size = ADIS16220_CAPTURE_SIZE, +}; + static ssize_t adis16220_adc1_bin_read(struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, @@ -447,6 +452,15 @@ static ssize_t adis16220_adc1_bin_read(struct kobject *kobj, ADIS16220_CAPT_BUF1); } +static struct bin_attribute adc1_bin = { + .attr = { + .name = "in0_bin", + .mode = S_IRUGO, + }, + .read = adis16220_adc1_bin_read, + .size = ADIS16220_CAPTURE_SIZE, +}; + static ssize_t adis16220_adc2_bin_read(struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, @@ -461,6 +475,16 @@ static ssize_t adis16220_adc2_bin_read(struct kobject *kobj, ADIS16220_CAPT_BUF2); } + +static struct bin_attribute adc2_bin = { + .attr = { + .name = "in1_bin", + .mode = S_IRUGO, + }, + .read = adis16220_adc2_bin_read, + .size = ADIS16220_CAPTURE_SIZE, +}; + static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16220_read_12bit_unsigned, ADIS16220_CAPT_SUPPLY); static IIO_CONST_ATTR(in_supply_scale, "0.0012207"); @@ -481,12 +505,12 @@ static IIO_DEV_ATTR_IN_RAW(1, adis16220_read_16bit, ADIS16220_CAPT_BUF2); static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16220_write_reset, 0); -#define IIO_DEV_ATTR_CAPTURE(_store) \ +#define IIO_DEV_ATTR_CAPTURE(_store) \ IIO_DEVICE_ATTR(capture, S_IWUGO, NULL, _store, 0) static IIO_DEV_ATTR_CAPTURE(adis16220_write_capture); -#define IIO_DEV_ATTR_CAPTURE_COUNT(_mode, _show, _store, _addr) \ +#define IIO_DEV_ATTR_CAPTURE_COUNT(_mode, _show, _store, _addr) \ IIO_DEVICE_ATTR(capture_count, _mode, _show, _store, _addr) static IIO_DEV_ATTR_CAPTURE_COUNT(S_IWUSR | S_IRUGO, @@ -563,33 +587,15 @@ static int __devinit adis16220_probe(struct spi_device *spi) goto error_free_dev; regdone = 1; - st->accel_bin.attr.name = "accel_bin"; - st->accel_bin.attr.mode = S_IRUGO; - st->accel_bin.attr.owner = THIS_MODULE; - st->accel_bin.read = adis16220_accel_bin_read; - st->accel_bin.size = ADIS16220_CAPTURE_SIZE; - - ret = sysfs_create_bin_file(&st->indio_dev->dev.kobj, &st->accel_bin); + ret = sysfs_create_bin_file(&st->indio_dev->dev.kobj, &accel_bin); if (ret) goto error_free_dev; - st->adc1_bin.attr.name = "adc1_bin"; - st->adc1_bin.attr.mode = S_IRUGO; - st->adc1_bin.attr.owner = THIS_MODULE; - st->adc1_bin.read = adis16220_adc1_bin_read; - st->adc1_bin.size = ADIS16220_CAPTURE_SIZE; - - ret = sysfs_create_bin_file(&st->indio_dev->dev.kobj, &st->adc1_bin); + ret = sysfs_create_bin_file(&st->indio_dev->dev.kobj, &adc1_bin); if (ret) goto error_rm_accel_bin; - st->adc2_bin.attr.name = "adc2_bin"; - st->adc2_bin.attr.mode = S_IRUGO; - st->adc2_bin.attr.owner = THIS_MODULE; - st->adc2_bin.read = adis16220_adc2_bin_read; - st->adc2_bin.size = ADIS16220_CAPTURE_SIZE; - - ret = sysfs_create_bin_file(&st->indio_dev->dev.kobj, &st->adc2_bin); + ret = sysfs_create_bin_file(&st->indio_dev->dev.kobj, &adc2_bin); if (ret) goto error_rm_adc1_bin; @@ -600,11 +606,11 @@ static int __devinit adis16220_probe(struct spi_device *spi) return 0; error_rm_adc2_bin: - sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &st->adc2_bin); + sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &adc2_bin); error_rm_adc1_bin: - sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &st->adc1_bin); + sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &adc1_bin); error_rm_accel_bin: - sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &st->accel_bin); + sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &accel_bin); error_free_dev: if (regdone) iio_device_unregister(st->indio_dev); @@ -627,9 +633,9 @@ static int adis16220_remove(struct spi_device *spi) flush_scheduled_work(); - sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &st->adc2_bin); - sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &st->adc1_bin); - sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &st->accel_bin); + sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &adc2_bin); + sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &adc1_bin); + sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &accel_bin); iio_device_unregister(indio_dev); kfree(st->tx); kfree(st->rx); -- cgit v1.2.3 From 81b77f94a10b64a3620e32531b5d8dbc495f1727 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 16 May 2010 21:29:25 +0100 Subject: Staging: iio: max1363 Fix two bugs in single_channel_from_ring This patch contains fixes for the two bugs Michael pointed out last week. As the other suggestion Michael made is not a bug fix (just a much more sensible way of handling things), I'll do that as a separate patch soon. The bugs were introduced with the abi changes. Signed-off-by: Jonathan Cameron Reported-by: Michael Hennerich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/max1363_ring.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c index c8aa01109ec2..56688dc9c92f 100644 --- a/drivers/staging/iio/adc/max1363_ring.c +++ b/drivers/staging/iio/adc/max1363_ring.c @@ -51,15 +51,15 @@ int max1363_single_channel_from_ring(long mask, struct max1363_state *st) /* Need a count of channels prior to this one */ mask >>= 1; while (mask) { - if (mask && st->current_mode->modemask) + if (mask & st->current_mode->modemask) count++; mask >>= 1; } if (st->chip_info->bits != 8) - return ((int)(ring_data[count*2 + 0] & 0x0F) << 8) + ret = ((int)(ring_data[count*2 + 0] & 0x0F) << 8) + (int)(ring_data[count*2 + 1]); else - return ring_data[count]; + ret = ring_data[count]; error_free_ring_data: kfree(ring_data); -- cgit v1.2.3 From 5763dcab5cd7de27d6db50efd393c416177c56c7 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Mon, 17 May 2010 11:40:20 +0100 Subject: staging: iio: adis16350 and similar IMU driver This version has the right part number in the commit message. Whilst technically the part I listed last time is also supported by the driver, the commit message might have caused confusion. Another driver from Barry at Analog. Again, I've lifted if from the blackfin tree and done the usual sparse and checkpatch fixes + the abi changes. I actually have one of these, so am particularly pleased to see it supported! Signed-off-by: Barry Song Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/imu/Kconfig | 9 + drivers/staging/iio/imu/Makefile | 4 + drivers/staging/iio/imu/adis16350.h | 193 ++++++++ drivers/staging/iio/imu/adis16350_core.c | 736 ++++++++++++++++++++++++++++ drivers/staging/iio/imu/adis16350_ring.c | 286 +++++++++++ drivers/staging/iio/imu/adis16350_trigger.c | 127 +++++ 6 files changed, 1355 insertions(+) create mode 100644 drivers/staging/iio/imu/adis16350.h create mode 100644 drivers/staging/iio/imu/adis16350_core.c create mode 100644 drivers/staging/iio/imu/adis16350_ring.c create mode 100644 drivers/staging/iio/imu/adis16350_trigger.c (limited to 'drivers') diff --git a/drivers/staging/iio/imu/Kconfig b/drivers/staging/iio/imu/Kconfig index 411804f11a7e..6308d6faad57 100644 --- a/drivers/staging/iio/imu/Kconfig +++ b/drivers/staging/iio/imu/Kconfig @@ -13,6 +13,15 @@ config ADIS16300 Say yes here to build support for Analog Devices adis16300 four degrees of freedom inertial sensor. +config ADIS16350 + tristate "Analog Devices ADIS16350/54/55/60/62/64/65 IMU SPI driver" + depends on SPI + select IIO_TRIGGER if IIO_RING_BUFFER + select IIO_SW_RING if IIO_RING_BUFFER + help + Say yes here to build support for Analog Devices adis16350/54/55/60/62/64/65 + high precision tri-axis inertial sensor. + config ADIS16400 tristate "Analog Devices ADIS16400/5 IMU SPI driver" depends on SPI diff --git a/drivers/staging/iio/imu/Makefile b/drivers/staging/iio/imu/Makefile index de454dd08c6d..31df7359e20f 100644 --- a/drivers/staging/iio/imu/Makefile +++ b/drivers/staging/iio/imu/Makefile @@ -5,6 +5,10 @@ adis16300-y := adis16300_core.o adis16300-$(CONFIG_IIO_RING_BUFFER) += adis16300_ring.o adis16300_trigger.o obj-$(CONFIG_ADIS16300) += adis16300.o +adis16350-y := adis16350_core.o +adis16350-$(CONFIG_IIO_RING_BUFFER) += adis16350_ring.o adis16350_trigger.o +obj-$(CONFIG_ADIS16350) += adis16350.o + adis16400-y := adis16400_core.o adis16400-$(CONFIG_IIO_RING_BUFFER) += adis16400_ring.o adis16400_trigger.o obj-$(CONFIG_ADIS16400) += adis16400.o \ No newline at end of file diff --git a/drivers/staging/iio/imu/adis16350.h b/drivers/staging/iio/imu/adis16350.h new file mode 100644 index 000000000000..334b18ace38e --- /dev/null +++ b/drivers/staging/iio/imu/adis16350.h @@ -0,0 +1,193 @@ +#ifndef SPI_ADIS16350_H_ +#define SPI_ADIS16350_H_ + +#define ADIS16350_STARTUP_DELAY 220 /* ms */ + +#define ADIS16350_READ_REG(a) a +#define ADIS16350_WRITE_REG(a) ((a) | 0x80) + +#define ADIS16350_FLASH_CNT 0x00 /* Flash memory write count */ +#define ADIS16350_SUPPLY_OUT 0x02 /* Power supply measurement */ +#define ADIS16350_XGYRO_OUT 0x04 /* X-axis gyroscope output */ +#define ADIS16350_YGYRO_OUT 0x06 /* Y-axis gyroscope output */ +#define ADIS16350_ZGYRO_OUT 0x08 /* Z-axis gyroscope output */ +#define ADIS16350_XACCL_OUT 0x0A /* X-axis accelerometer output */ +#define ADIS16350_YACCL_OUT 0x0C /* Y-axis accelerometer output */ +#define ADIS16350_ZACCL_OUT 0x0E /* Z-axis accelerometer output */ +#define ADIS16350_XTEMP_OUT 0x10 /* X-axis gyroscope temperature measurement */ +#define ADIS16350_YTEMP_OUT 0x12 /* Y-axis gyroscope temperature measurement */ +#define ADIS16350_ZTEMP_OUT 0x14 /* Z-axis gyroscope temperature measurement */ +#define ADIS16350_AUX_ADC 0x16 /* Auxiliary ADC measurement */ + +/* Calibration parameters */ +#define ADIS16350_XGYRO_OFF 0x1A /* X-axis gyroscope bias offset factor */ +#define ADIS16350_YGYRO_OFF 0x1C /* Y-axis gyroscope bias offset factor */ +#define ADIS16350_ZGYRO_OFF 0x1E /* Z-axis gyroscope bias offset factor */ +#define ADIS16350_XACCL_OFF 0x20 /* X-axis acceleration bias offset factor */ +#define ADIS16350_YACCL_OFF 0x22 /* Y-axis acceleration bias offset factor */ +#define ADIS16350_ZACCL_OFF 0x24 /* Z-axis acceleration bias offset factor */ + +#define ADIS16350_GPIO_CTRL 0x32 /* Auxiliary digital input/output control */ +#define ADIS16350_MSC_CTRL 0x34 /* Miscellaneous control */ +#define ADIS16350_SMPL_PRD 0x36 /* Internal sample period (rate) control */ +#define ADIS16350_SENS_AVG 0x38 /* Dynamic range and digital filter control */ +#define ADIS16350_SLP_CNT 0x3A /* Sleep mode control */ +#define ADIS16350_DIAG_STAT 0x3C /* System status */ + +/* Alarm functions */ +#define ADIS16350_GLOB_CMD 0x3E /* System command */ +#define ADIS16350_ALM_MAG1 0x26 /* Alarm 1 amplitude threshold */ +#define ADIS16350_ALM_MAG2 0x28 /* Alarm 2 amplitude threshold */ +#define ADIS16350_ALM_SMPL1 0x2A /* Alarm 1 sample size */ +#define ADIS16350_ALM_SMPL2 0x2C /* Alarm 2 sample size */ +#define ADIS16350_ALM_CTRL 0x2E /* Alarm control */ +#define ADIS16350_AUX_DAC 0x30 /* Auxiliary DAC data */ + +#define ADIS16350_ERROR_ACTIVE (1<<14) +#define ADIS16350_NEW_DATA (1<<15) + +/* MSC_CTRL */ +#define ADIS16350_MSC_CTRL_MEM_TEST (1<<11) +#define ADIS16350_MSC_CTRL_INT_SELF_TEST (1<<10) +#define ADIS16350_MSC_CTRL_NEG_SELF_TEST (1<<9) +#define ADIS16350_MSC_CTRL_POS_SELF_TEST (1<<8) +#define ADIS16350_MSC_CTRL_GYRO_BIAS (1<<7) +#define ADIS16350_MSC_CTRL_ACCL_ALIGN (1<<6) +#define ADIS16350_MSC_CTRL_DATA_RDY_EN (1<<2) +#define ADIS16350_MSC_CTRL_DATA_RDY_POL_HIGH (1<<1) +#define ADIS16350_MSC_CTRL_DATA_RDY_DIO2 (1<<0) + +/* SMPL_PRD */ +#define ADIS16350_SMPL_PRD_TIME_BASE (1<<7) +#define ADIS16350_SMPL_PRD_DIV_MASK 0x7F + +/* DIAG_STAT */ +#define ADIS16350_DIAG_STAT_ZACCL_FAIL (1<<15) +#define ADIS16350_DIAG_STAT_YACCL_FAIL (1<<14) +#define ADIS16350_DIAG_STAT_XACCL_FAIL (1<<13) +#define ADIS16350_DIAG_STAT_XGYRO_FAIL (1<<12) +#define ADIS16350_DIAG_STAT_YGYRO_FAIL (1<<11) +#define ADIS16350_DIAG_STAT_ZGYRO_FAIL (1<<10) +#define ADIS16350_DIAG_STAT_ALARM2 (1<<9) +#define ADIS16350_DIAG_STAT_ALARM1 (1<<8) +#define ADIS16350_DIAG_STAT_FLASH_CHK (1<<6) +#define ADIS16350_DIAG_STAT_SELF_TEST (1<<5) +#define ADIS16350_DIAG_STAT_OVERFLOW (1<<4) +#define ADIS16350_DIAG_STAT_SPI_FAIL (1<<3) +#define ADIS16350_DIAG_STAT_FLASH_UPT (1<<2) +#define ADIS16350_DIAG_STAT_POWER_HIGH (1<<1) +#define ADIS16350_DIAG_STAT_POWER_LOW (1<<0) + +/* GLOB_CMD */ +#define ADIS16350_GLOB_CMD_SW_RESET (1<<7) +#define ADIS16350_GLOB_CMD_P_AUTO_NULL (1<<4) +#define ADIS16350_GLOB_CMD_FLASH_UPD (1<<3) +#define ADIS16350_GLOB_CMD_DAC_LATCH (1<<2) +#define ADIS16350_GLOB_CMD_FAC_CALIB (1<<1) +#define ADIS16350_GLOB_CMD_AUTO_NULL (1<<0) + +/* SLP_CNT */ +#define ADIS16350_SLP_CNT_POWER_OFF (1<<8) + +#define ADIS16350_MAX_TX 24 +#define ADIS16350_MAX_RX 24 + +#define ADIS16350_SPI_SLOW (u32)(300 * 1000) +#define ADIS16350_SPI_BURST (u32)(1000 * 1000) +#define ADIS16350_SPI_FAST (u32)(2000 * 1000) + +/** + * struct adis16350_state - device instance specific data + * @us: actual spi_device + * @work_trigger_to_ring: bh for triggered event handling + * @work_cont_thresh: CLEAN + * @inter: used to check if new interrupt has been triggered + * @last_timestamp: passing timestamp from th to bh of interrupt handler + * @indio_dev: industrial I/O device structure + * @trig: data ready trigger registered with iio + * @tx: transmit buffer + * @rx: recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct adis16350_state { + struct spi_device *us; + struct work_struct work_trigger_to_ring; + struct iio_work_cont work_cont_data_rdy; + s64 last_timestamp; + struct iio_dev *indio_dev; + struct iio_trigger *trig; + u8 *tx; + u8 *rx; + struct mutex buf_lock; +}; + +int adis16350_set_irq(struct device *dev, bool enable); + +#ifdef CONFIG_IIO_RING_BUFFER + +enum adis16350_scan { + ADIS16350_SCAN_SUPPLY, + ADIS16350_SCAN_GYRO_X, + ADIS16350_SCAN_GYRO_Y, + ADIS16350_SCAN_GYRO_Z, + ADIS16350_SCAN_ACC_X, + ADIS16350_SCAN_ACC_Y, + ADIS16350_SCAN_ACC_Z, + ADIS16350_SCAN_TEMP_X, + ADIS16350_SCAN_TEMP_Y, + ADIS16350_SCAN_TEMP_Z, + ADIS16350_SCAN_ADC_0 +}; + +void adis16350_remove_trigger(struct iio_dev *indio_dev); +int adis16350_probe_trigger(struct iio_dev *indio_dev); + +ssize_t adis16350_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf); + + +int adis16350_configure_ring(struct iio_dev *indio_dev); +void adis16350_unconfigure_ring(struct iio_dev *indio_dev); + +int adis16350_initialize_ring(struct iio_ring_buffer *ring); +void adis16350_uninitialize_ring(struct iio_ring_buffer *ring); +#else /* CONFIG_IIO_RING_BUFFER */ + +static inline void adis16350_remove_trigger(struct iio_dev *indio_dev) +{ +} + +static inline int adis16350_probe_trigger(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline ssize_t +adis16350_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static int adis16350_configure_ring(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline void adis16350_unconfigure_ring(struct iio_dev *indio_dev) +{ +} + +static inline int adis16350_initialize_ring(struct iio_ring_buffer *ring) +{ + return 0; +} + +static inline void adis16350_uninitialize_ring(struct iio_ring_buffer *ring) +{ +} + +#endif /* CONFIG_IIO_RING_BUFFER */ +#endif /* SPI_ADIS16350_H_ */ diff --git a/drivers/staging/iio/imu/adis16350_core.c b/drivers/staging/iio/imu/adis16350_core.c new file mode 100644 index 000000000000..0edde73ce5c2 --- /dev/null +++ b/drivers/staging/iio/imu/adis16350_core.c @@ -0,0 +1,736 @@ +/* + * ADIS16350/54/55/60/62/64/65 high precision tri-axis inertial sensor + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../accel/accel.h" +#include "../adc/adc.h" +#include "../gyro/gyro.h" + +#include "adis16350.h" + +#define DRIVER_NAME "adis16350" + +static int adis16350_check_status(struct device *dev); + +/** + * adis16350_spi_write_reg_8() - write single byte to a register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the register to be written + * @val: the value to write + **/ +static int adis16350_spi_write_reg_8(struct device *dev, + u8 reg_address, + u8 val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16350_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16350_WRITE_REG(reg_address); + st->tx[1] = val; + + ret = spi_write(st->us, st->tx, 2); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16350_spi_write_reg_16() - write 2 bytes to a pair of registers + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: value to be written + **/ +static int adis16350_spi_write_reg_16(struct device *dev, + u8 lower_reg_address, + u16 value) +{ + int ret; + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16350_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 25, + }, { + .tx_buf = st->tx + 2, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 25, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16350_WRITE_REG(lower_reg_address); + st->tx[1] = value & 0xFF; + st->tx[2] = ADIS16350_WRITE_REG(lower_reg_address + 1); + st->tx[3] = (value >> 8) & 0xFF; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16350_spi_read_reg_16() - read 2 bytes from a 16-bit register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: somewhere to pass back the value read + **/ +static int adis16350_spi_read_reg_16(struct device *dev, + u8 lower_reg_address, + u16 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16350_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 25, + }, { + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 25, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16350_READ_REG(lower_reg_address); + st->tx[1] = 0; + st->tx[2] = 0; + st->tx[3] = 0; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, + "problem when reading 16 bit register 0x%02X", + lower_reg_address); + goto error_ret; + } + *val = (st->rx[0] << 8) | st->rx[1]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + + +static ssize_t adis16350_spi_read_signed(struct device *dev, + struct device_attribute *attr, + char *buf, + unsigned bits) +{ + int ret; + s16 val = 0; + unsigned shift = 16 - bits; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = adis16350_spi_read_reg_16(dev, this_attr->address, (u16 *)&val); + if (ret) + return ret; + + if (val & ADIS16350_ERROR_ACTIVE) + adis16350_check_status(dev); + val = ((s16)(val << shift) >> shift); + return sprintf(buf, "%d\n", val); +} + +static ssize_t adis16350_read_12bit_unsigned(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u16 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = adis16350_spi_read_reg_16(dev, this_attr->address, &val); + if (ret) + return ret; + + if (val & ADIS16350_ERROR_ACTIVE) + adis16350_check_status(dev); + + return sprintf(buf, "%u\n", val & 0x0FFF); +} + +static ssize_t adis16350_read_14bit_signed(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + ssize_t ret; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + ret = adis16350_spi_read_signed(dev, attr, buf, 14); + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t adis16350_read_12bit_signed(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + ssize_t ret; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + ret = adis16350_spi_read_signed(dev, attr, buf, 12); + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t adis16350_write_16bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = adis16350_spi_write_reg_16(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static ssize_t adis16350_read_frequency(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret, len = 0; + u16 t; + int sps; + ret = adis16350_spi_read_reg_16(dev, + ADIS16350_SMPL_PRD, + &t); + if (ret) + return ret; + sps = (t & ADIS16350_SMPL_PRD_TIME_BASE) ? 53 : 1638; + sps /= (t & ADIS16350_SMPL_PRD_DIV_MASK) + 1; + len = sprintf(buf, "%d SPS\n", sps); + return len; +} + +static ssize_t adis16350_write_frequency(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16350_state *st = iio_dev_get_devdata(indio_dev); + long val; + int ret; + u8 t; + + ret = strict_strtol(buf, 10, &val); + if (ret) + return ret; + + mutex_lock(&indio_dev->mlock); + + t = (1638 / val); + if (t > 0) + t--; + t &= ADIS16350_SMPL_PRD_DIV_MASK; + if ((t & ADIS16350_SMPL_PRD_DIV_MASK) >= 0x0A) + st->us->max_speed_hz = ADIS16350_SPI_SLOW; + else + st->us->max_speed_hz = ADIS16350_SPI_FAST; + + ret = adis16350_spi_write_reg_8(dev, + ADIS16350_SMPL_PRD, + t); + + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +static int adis16350_reset(struct device *dev) +{ + int ret; + ret = adis16350_spi_write_reg_8(dev, + ADIS16350_GLOB_CMD, + ADIS16350_GLOB_CMD_SW_RESET); + if (ret) + dev_err(dev, "problem resetting device"); + + return ret; +} + +static ssize_t adis16350_write_reset(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + if (len < 1) + return -1; + switch (buf[0]) { + case '1': + case 'y': + case 'Y': + return adis16350_reset(dev); + } + return -1; +} + +int adis16350_set_irq(struct device *dev, bool enable) +{ + int ret; + u16 msc; + ret = adis16350_spi_read_reg_16(dev, ADIS16350_MSC_CTRL, &msc); + if (ret) + goto error_ret; + + msc |= ADIS16350_MSC_CTRL_DATA_RDY_POL_HIGH; + msc &= ~ADIS16350_MSC_CTRL_DATA_RDY_DIO2; + + if (enable) + msc |= ADIS16350_MSC_CTRL_DATA_RDY_EN; + else + msc &= ~ADIS16350_MSC_CTRL_DATA_RDY_EN; + + ret = adis16350_spi_write_reg_16(dev, ADIS16350_MSC_CTRL, msc); + if (ret) + goto error_ret; + +error_ret: + return ret; +} + +/* Power down the device */ +static int adis16350_stop_device(struct device *dev) +{ + int ret; + u16 val = ADIS16350_SLP_CNT_POWER_OFF; + + ret = adis16350_spi_write_reg_16(dev, ADIS16350_SLP_CNT, val); + if (ret) + dev_err(dev, "problem with turning device off: SLP_CNT"); + + return ret; +} + +static int adis16350_self_test(struct device *dev) +{ + int ret; + ret = adis16350_spi_write_reg_16(dev, + ADIS16350_MSC_CTRL, + ADIS16350_MSC_CTRL_MEM_TEST); + if (ret) { + dev_err(dev, "problem starting self test"); + goto err_ret; + } + + adis16350_check_status(dev); + +err_ret: + return ret; +} + +static int adis16350_check_status(struct device *dev) +{ + u16 status; + int ret; + + ret = adis16350_spi_read_reg_16(dev, ADIS16350_DIAG_STAT, &status); + + if (ret < 0) { + dev_err(dev, "Reading status failed\n"); + goto error_ret; + } + ret = status; + if (status & ADIS16350_DIAG_STAT_ZACCL_FAIL) + dev_err(dev, "Z-axis accelerometer self-test failure\n"); + if (status & ADIS16350_DIAG_STAT_YACCL_FAIL) + dev_err(dev, "Y-axis accelerometer self-test failure\n"); + if (status & ADIS16350_DIAG_STAT_XACCL_FAIL) + dev_err(dev, "X-axis accelerometer self-test failure\n"); + if (status & ADIS16350_DIAG_STAT_XGYRO_FAIL) + dev_err(dev, "X-axis gyroscope self-test failure\n"); + if (status & ADIS16350_DIAG_STAT_YGYRO_FAIL) + dev_err(dev, "Y-axis gyroscope self-test failure\n"); + if (status & ADIS16350_DIAG_STAT_ZGYRO_FAIL) + dev_err(dev, "Z-axis gyroscope self-test failure\n"); + if (status & ADIS16350_DIAG_STAT_ALARM2) + dev_err(dev, "Alarm 2 active\n"); + if (status & ADIS16350_DIAG_STAT_ALARM1) + dev_err(dev, "Alarm 1 active\n"); + if (status & ADIS16350_DIAG_STAT_FLASH_CHK) + dev_err(dev, "Flash checksum error\n"); + if (status & ADIS16350_DIAG_STAT_SELF_TEST) + dev_err(dev, "Self test error\n"); + if (status & ADIS16350_DIAG_STAT_OVERFLOW) + dev_err(dev, "Sensor overrange\n"); + if (status & ADIS16350_DIAG_STAT_SPI_FAIL) + dev_err(dev, "SPI failure\n"); + if (status & ADIS16350_DIAG_STAT_FLASH_UPT) + dev_err(dev, "Flash update failed\n"); + if (status & ADIS16350_DIAG_STAT_POWER_HIGH) + dev_err(dev, "Power supply above 5.25V\n"); + if (status & ADIS16350_DIAG_STAT_POWER_LOW) + dev_err(dev, "Power supply below 4.75V\n"); + +error_ret: + return ret; +} + +static int adis16350_initial_setup(struct adis16350_state *st) +{ + int ret; + u16 smp_prd; + struct device *dev = &st->indio_dev->dev; + + /* use low spi speed for init */ + st->us->max_speed_hz = ADIS16350_SPI_SLOW; + st->us->mode = SPI_MODE_3; + spi_setup(st->us); + + /* Disable IRQ */ + ret = adis16350_set_irq(dev, false); + if (ret) { + dev_err(dev, "disable irq failed"); + goto err_ret; + } + + /* Do self test */ + ret = adis16350_self_test(dev); + if (ret) { + dev_err(dev, "self test failure"); + goto err_ret; + } + + /* Read status register to check the result */ + ret = adis16350_check_status(dev); + if (ret) { + adis16350_reset(dev); + dev_err(dev, "device not playing ball -> reset"); + msleep(ADIS16350_STARTUP_DELAY); + ret = adis16350_check_status(dev); + if (ret) { + dev_err(dev, "giving up"); + goto err_ret; + } + } + + printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n", + st->us->chip_select, st->us->irq); + + /* use high spi speed if possible */ + ret = adis16350_spi_read_reg_16(dev, ADIS16350_SMPL_PRD, &smp_prd); + if (!ret && (smp_prd & ADIS16350_SMPL_PRD_DIV_MASK) < 0x0A) { + st->us->max_speed_hz = ADIS16350_SPI_SLOW; + spi_setup(st->us); + } + +err_ret: + return ret; +} + +static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO, + adis16350_read_12bit_signed, + adis16350_write_16bit, + ADIS16350_XACCL_OFF); + +static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO, + adis16350_read_12bit_signed, + adis16350_write_16bit, + ADIS16350_YACCL_OFF); + +static IIO_DEV_ATTR_ACCEL_Z_OFFSET(S_IWUSR | S_IRUGO, + adis16350_read_12bit_signed, + adis16350_write_16bit, + ADIS16350_ZACCL_OFF); + +static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16350_read_12bit_unsigned, + ADIS16350_SUPPLY_OUT); +static IIO_CONST_ATTR(in_supply_scale, "0.002418"); + +static IIO_DEV_ATTR_GYRO_X(adis16350_read_14bit_signed, + ADIS16350_XGYRO_OUT); +static IIO_DEV_ATTR_GYRO_Y(adis16350_read_14bit_signed, + ADIS16350_YGYRO_OUT); +static IIO_DEV_ATTR_GYRO_Z(adis16350_read_14bit_signed, + ADIS16350_ZGYRO_OUT); +static IIO_CONST_ATTR(gyro_scale, "0.05"); + +static IIO_DEV_ATTR_ACCEL_X(adis16350_read_14bit_signed, + ADIS16350_XACCL_OUT); +static IIO_DEV_ATTR_ACCEL_Y(adis16350_read_14bit_signed, + ADIS16350_YACCL_OUT); +static IIO_DEV_ATTR_ACCEL_Z(adis16350_read_14bit_signed, + ADIS16350_ZACCL_OUT); +static IIO_CONST_ATTR(accel_scale, "0.00333"); + +static IIO_DEVICE_ATTR(temp_x_raw, S_IRUGO, adis16350_read_12bit_signed, + NULL, ADIS16350_XTEMP_OUT); +static IIO_DEVICE_ATTR(temp_y_raw, S_IRUGO, adis16350_read_12bit_signed, + NULL, ADIS16350_YTEMP_OUT); +static IIO_DEVICE_ATTR(temp_z_raw, S_IRUGO, adis16350_read_12bit_signed, + NULL, ADIS16350_ZTEMP_OUT); +static IIO_CONST_ATTR(temp_scale, "0.0005"); + +static IIO_DEV_ATTR_IN_RAW(0, adis16350_read_12bit_unsigned, + ADIS16350_AUX_ADC); +static IIO_CONST_ATTR(in0_scale, "0.000806"); + +static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, + adis16350_read_frequency, + adis16350_write_frequency); + +static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, + adis16350_write_reset, 0); + +static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("409 546 819 1638"); + +static IIO_CONST_ATTR(name, "adis16350"); + +static struct attribute *adis16350_attributes[] = { + &iio_dev_attr_accel_x_offset.dev_attr.attr, + &iio_dev_attr_accel_y_offset.dev_attr.attr, + &iio_dev_attr_accel_z_offset.dev_attr.attr, + &iio_dev_attr_in_supply_raw.dev_attr.attr, + &iio_const_attr_in_supply_scale.dev_attr.attr, + &iio_dev_attr_gyro_x_raw.dev_attr.attr, + &iio_dev_attr_gyro_y_raw.dev_attr.attr, + &iio_dev_attr_gyro_z_raw.dev_attr.attr, + &iio_const_attr_gyro_scale.dev_attr.attr, + &iio_dev_attr_accel_x_raw.dev_attr.attr, + &iio_dev_attr_accel_y_raw.dev_attr.attr, + &iio_dev_attr_accel_z_raw.dev_attr.attr, + &iio_const_attr_accel_scale.dev_attr.attr, + &iio_dev_attr_temp_x_raw.dev_attr.attr, + &iio_dev_attr_temp_y_raw.dev_attr.attr, + &iio_dev_attr_temp_z_raw.dev_attr.attr, + &iio_const_attr_temp_scale.dev_attr.attr, + &iio_dev_attr_in0_raw.dev_attr.attr, + &iio_const_attr_in0_scale.dev_attr.attr, + &iio_dev_attr_sampling_frequency.dev_attr.attr, + &iio_const_attr_available_sampling_frequency.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_const_attr_name.dev_attr.attr, + NULL +}; + +static const struct attribute_group adis16350_attribute_group = { + .attrs = adis16350_attributes, +}; + +static struct attribute *adis16350_event_attributes[] = { + NULL, +}; + +static struct attribute_group adis16350_event_attribute_group = { + .attrs = adis16350_event_attributes, +}; + +static int __devinit adis16350_probe(struct spi_device *spi) +{ + int ret, regdone = 0; + struct adis16350_state *st = kzalloc(sizeof *st, GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + goto error_ret; + } + /* this is only used for removal purposes */ + spi_set_drvdata(spi, st); + + /* Allocate the comms buffers */ + st->rx = kzalloc(sizeof(*st->rx)*ADIS16350_MAX_RX, GFP_KERNEL); + if (st->rx == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->tx = kzalloc(sizeof(*st->tx)*ADIS16350_MAX_TX, GFP_KERNEL); + if (st->tx == NULL) { + ret = -ENOMEM; + goto error_free_rx; + } + st->us = spi; + mutex_init(&st->buf_lock); + /* setup the industrialio driver allocated elements */ + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_tx; + } + + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->num_interrupt_lines = 1; + st->indio_dev->event_attrs = &adis16350_event_attribute_group; + st->indio_dev->attrs = &adis16350_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = adis16350_configure_ring(st->indio_dev); + if (ret) + goto error_free_dev; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_unreg_ring_funcs; + regdone = 1; + + ret = adis16350_initialize_ring(st->indio_dev->ring); + if (ret) { + printk(KERN_ERR "failed to initialize the ring\n"); + goto error_unreg_ring_funcs; + } + + if (spi->irq) { + ret = iio_register_interrupt_line(spi->irq, + st->indio_dev, + 0, + IRQF_TRIGGER_RISING, + "adis16350"); + if (ret) + goto error_uninitialize_ring; + + ret = adis16350_probe_trigger(st->indio_dev); + if (ret) + goto error_unregister_line; + } + + /* Get the device into a sane initial state */ + ret = adis16350_initial_setup(st); + if (ret) + goto error_remove_trigger; + return 0; + +error_remove_trigger: + adis16350_remove_trigger(st->indio_dev); +error_unregister_line: + if (spi->irq) + iio_unregister_interrupt_line(st->indio_dev, 0); +error_uninitialize_ring: + adis16350_uninitialize_ring(st->indio_dev->ring); +error_unreg_ring_funcs: + adis16350_unconfigure_ring(st->indio_dev); +error_free_dev: + if (regdone) + iio_device_unregister(st->indio_dev); + else + iio_free_device(st->indio_dev); +error_free_tx: + kfree(st->tx); +error_free_rx: + kfree(st->rx); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +static int adis16350_remove(struct spi_device *spi) +{ + int ret; + struct adis16350_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + + ret = adis16350_stop_device(&(indio_dev->dev)); + if (ret) + goto err_ret; + + flush_scheduled_work(); + + adis16350_remove_trigger(indio_dev); + if (spi->irq) + iio_unregister_interrupt_line(indio_dev, 0); + + adis16350_uninitialize_ring(indio_dev->ring); + iio_device_unregister(indio_dev); + adis16350_unconfigure_ring(indio_dev); + kfree(st->tx); + kfree(st->rx); + kfree(st); + + return 0; + +err_ret: + return ret; +} + +static const struct spi_device_id adis16350_id[] = { + {"adis16350", 0}, + {"adis16354", 0}, + {"adis16355", 0}, + {"adis16360", 0}, + {"adis16362", 0}, + {"adis16364", 0}, + {"adis16365", 0}, + {} +}; + +static struct spi_driver adis16350_driver = { + .driver = { + .name = "adis16350", + .owner = THIS_MODULE, + }, + .probe = adis16350_probe, + .remove = __devexit_p(adis16350_remove), + .id_table = adis16350_id, +}; + +static __init int adis16350_init(void) +{ + return spi_register_driver(&adis16350_driver); +} +module_init(adis16350_init); + +static __exit void adis16350_exit(void) +{ + spi_unregister_driver(&adis16350_driver); +} +module_exit(adis16350_exit); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADIS16350/54/55/60/62/64/65 IMU SPI driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/imu/adis16350_ring.c b/drivers/staging/iio/imu/adis16350_ring.c new file mode 100644 index 000000000000..5e9716ea7c77 --- /dev/null +++ b/drivers/staging/iio/imu/adis16350_ring.c @@ -0,0 +1,286 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../ring_sw.h" +#include "../accel/accel.h" +#include "../trigger.h" +#include "adis16350.h" + +/** + * combine_8_to_16() utility function to munge to u8s into u16 + **/ +static inline u16 combine_8_to_16(u8 lower, u8 upper) +{ + u16 _lower = lower; + u16 _upper = upper; + return _lower | (_upper << 8); +} + +static IIO_SCAN_EL_C(supply, ADIS16350_SCAN_SUPPLY, IIO_UNSIGNED(12), + ADIS16350_SUPPLY_OUT, NULL); + +static IIO_SCAN_EL_C(gyro_x, ADIS16350_SCAN_GYRO_X, IIO_SIGNED(14), + ADIS16350_XGYRO_OUT, NULL); +static IIO_SCAN_EL_C(gyro_y, ADIS16350_SCAN_GYRO_Y, IIO_SIGNED(14), + ADIS16350_YGYRO_OUT, NULL); +static IIO_SCAN_EL_C(gyro_z, ADIS16350_SCAN_GYRO_Z, IIO_SIGNED(14), + ADIS16350_ZGYRO_OUT, NULL); + +static IIO_SCAN_EL_C(accel_x, ADIS16350_SCAN_ACC_X, IIO_SIGNED(14), + ADIS16350_XACCL_OUT, NULL); +static IIO_SCAN_EL_C(accel_y, ADIS16350_SCAN_ACC_Y, IIO_SIGNED(14), + ADIS16350_YACCL_OUT, NULL); +static IIO_SCAN_EL_C(accel_z, ADIS16350_SCAN_ACC_Z, IIO_SIGNED(14), + ADIS16350_ZACCL_OUT, NULL); + +static IIO_SCAN_EL_C(temp_x, ADIS16350_SCAN_TEMP_X, IIO_SIGNED(12), + ADIS16350_XTEMP_OUT, NULL); +static IIO_SCAN_EL_C(temp_y, ADIS16350_SCAN_TEMP_Y, IIO_SIGNED(12), + ADIS16350_YTEMP_OUT, NULL); +static IIO_SCAN_EL_C(temp_z, ADIS16350_SCAN_TEMP_Z, IIO_SIGNED(12), + ADIS16350_ZTEMP_OUT, NULL); + +static IIO_SCAN_EL_C(adc_0, ADIS16350_SCAN_ADC_0, IIO_UNSIGNED(12), + ADIS16350_AUX_ADC, NULL); + +static IIO_SCAN_EL_TIMESTAMP(11); + +static struct attribute *adis16350_scan_el_attrs[] = { + &iio_scan_el_supply.dev_attr.attr, + &iio_scan_el_gyro_x.dev_attr.attr, + &iio_scan_el_gyro_y.dev_attr.attr, + &iio_scan_el_gyro_z.dev_attr.attr, + &iio_scan_el_accel_x.dev_attr.attr, + &iio_scan_el_accel_y.dev_attr.attr, + &iio_scan_el_accel_z.dev_attr.attr, + &iio_scan_el_temp_x.dev_attr.attr, + &iio_scan_el_temp_y.dev_attr.attr, + &iio_scan_el_temp_z.dev_attr.attr, + &iio_scan_el_adc_0.dev_attr.attr, + &iio_scan_el_timestamp.dev_attr.attr, + NULL, +}; + +static struct attribute_group adis16350_scan_el_group = { + .attrs = adis16350_scan_el_attrs, + .name = "scan_elements", +}; + +/** + * adis16350_poll_func_th() top half interrupt handler called by trigger + * @private_data: iio_dev + **/ +static void adis16350_poll_func_th(struct iio_dev *indio_dev) +{ + struct adis16350_state *st = iio_dev_get_devdata(indio_dev); + st->last_timestamp = indio_dev->trig->timestamp; + schedule_work(&st->work_trigger_to_ring); +} + +/** + * adis16350_spi_read_burst() - read all data registers + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @rx: somewhere to pass back the value read (min size is 24 bytes) + **/ +static int adis16350_spi_read_burst(struct device *dev, u8 *rx) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16350_state *st = iio_dev_get_devdata(indio_dev); + u32 old_speed_hz = st->us->max_speed_hz; + int ret; + + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 0, + }, { + .rx_buf = rx, + .bits_per_word = 8, + .len = 22, + .cs_change = 0, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16350_READ_REG(ADIS16350_GLOB_CMD); + st->tx[1] = 0; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + + st->us->max_speed_hz = ADIS16350_SPI_BURST; + spi_setup(st->us); + + ret = spi_sync(st->us, &msg); + if (ret) + dev_err(&st->us->dev, "problem when burst reading"); + + st->us->max_speed_hz = old_speed_hz; + spi_setup(st->us); + mutex_unlock(&st->buf_lock); + return ret; +} + +/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device + * specific to be rolled into the core. + */ +static void adis16350_trigger_bh_to_ring(struct work_struct *work_s) +{ + struct adis16350_state *st + = container_of(work_s, struct adis16350_state, + work_trigger_to_ring); + + int i = 0; + s16 *data; + size_t datasize = st->indio_dev + ->ring->access.get_bpd(st->indio_dev->ring); + + data = kmalloc(datasize , GFP_KERNEL); + if (data == NULL) { + dev_err(&st->us->dev, "memory alloc failed in ring bh"); + return; + } + + if (st->indio_dev->scan_count) + if (adis16350_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0) + for (; i < st->indio_dev->scan_count; i++) { + data[i] = combine_8_to_16(st->rx[i*2+1], + st->rx[i*2]); + } + + /* Guaranteed to be aligned with 8 byte boundary */ + if (st->indio_dev->scan_timestamp) + *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp; + + st->indio_dev->ring->access.store_to(st->indio_dev->ring, + (u8 *)data, + st->last_timestamp); + + iio_trigger_notify_done(st->indio_dev->trig); + kfree(data); + + return; +} + +static int adis16350_data_rdy_ring_preenable(struct iio_dev *indio_dev) +{ + size_t size; + dev_dbg(&indio_dev->dev, "%s\n", __func__); + /* Check if there are any scan elements enabled, if not fail*/ + if (!(indio_dev->scan_count || indio_dev->scan_timestamp)) + return -EINVAL; + + if (indio_dev->ring->access.set_bpd) { + if (indio_dev->scan_timestamp) + if (indio_dev->scan_count) + /* Timestamp (aligned sizeof(s64) and data */ + size = (((indio_dev->scan_count * sizeof(s16)) + + sizeof(s64) - 1) + & ~(sizeof(s64) - 1)) + + sizeof(s64); + else /* Timestamp only */ + size = sizeof(s64); + else /* Data only */ + size = indio_dev->scan_count*sizeof(s16); + indio_dev->ring->access.set_bpd(indio_dev->ring, size); + } + + return 0; +} + +static int adis16350_data_rdy_ring_postenable(struct iio_dev *indio_dev) +{ + return indio_dev->trig + ? iio_trigger_attach_poll_func(indio_dev->trig, + indio_dev->pollfunc) + : 0; +} + +static int adis16350_data_rdy_ring_predisable(struct iio_dev *indio_dev) +{ + return indio_dev->trig + ? iio_trigger_dettach_poll_func(indio_dev->trig, + indio_dev->pollfunc) + : 0; +} + +void adis16350_unconfigure_ring(struct iio_dev *indio_dev) +{ + kfree(indio_dev->pollfunc); + iio_sw_rb_free(indio_dev->ring); +} + +int adis16350_configure_ring(struct iio_dev *indio_dev) +{ + int ret = 0; + struct adis16350_state *st = indio_dev->dev_data; + struct iio_ring_buffer *ring; + INIT_WORK(&st->work_trigger_to_ring, adis16350_trigger_bh_to_ring); + /* Set default scan mode */ + + iio_scan_mask_set(indio_dev, iio_scan_el_supply.number); + iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number); + iio_scan_mask_set(indio_dev, iio_scan_el_gyro_y.number); + iio_scan_mask_set(indio_dev, iio_scan_el_gyro_z.number); + iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number); + iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number); + iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number); + iio_scan_mask_set(indio_dev, iio_scan_el_temp_x.number); + iio_scan_mask_set(indio_dev, iio_scan_el_temp_y.number); + iio_scan_mask_set(indio_dev, iio_scan_el_temp_z.number); + iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number); + indio_dev->scan_timestamp = true; + + indio_dev->scan_el_attrs = &adis16350_scan_el_group; + + ring = iio_sw_rb_allocate(indio_dev); + if (!ring) { + ret = -ENOMEM; + return ret; + } + indio_dev->ring = ring; + /* Effectively select the ring buffer implementation */ + iio_ring_sw_register_funcs(&ring->access); + ring->preenable = &adis16350_data_rdy_ring_preenable; + ring->postenable = &adis16350_data_rdy_ring_postenable; + ring->predisable = &adis16350_data_rdy_ring_predisable; + ring->owner = THIS_MODULE; + + indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL); + if (indio_dev->pollfunc == NULL) { + ret = -ENOMEM; + goto error_iio_sw_rb_free;; + } + indio_dev->pollfunc->poll_func_main = &adis16350_poll_func_th; + indio_dev->pollfunc->private_data = indio_dev; + indio_dev->modes |= INDIO_RING_TRIGGERED; + return 0; + +error_iio_sw_rb_free: + iio_sw_rb_free(indio_dev->ring); + return ret; +} + +int adis16350_initialize_ring(struct iio_ring_buffer *ring) +{ + return iio_ring_buffer_register(ring, 0); +} + +void adis16350_uninitialize_ring(struct iio_ring_buffer *ring) +{ + iio_ring_buffer_unregister(ring); +} diff --git a/drivers/staging/iio/imu/adis16350_trigger.c b/drivers/staging/iio/imu/adis16350_trigger.c new file mode 100644 index 000000000000..1ffa75d05fac --- /dev/null +++ b/drivers/staging/iio/imu/adis16350_trigger.c @@ -0,0 +1,127 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../trigger.h" +#include "adis16350.h" + +/** + * adis16350_data_rdy_trig_poll() the event handler for the data rdy trig + **/ +static int adis16350_data_rdy_trig_poll(struct iio_dev *dev_info, + int index, + s64 timestamp, + int no_test) +{ + struct adis16350_state *st = iio_dev_get_devdata(dev_info); + struct iio_trigger *trig = st->trig; + + trig->timestamp = timestamp; + iio_trigger_poll(trig); + + return IRQ_HANDLED; +} + +IIO_EVENT_SH(data_rdy_trig, &adis16350_data_rdy_trig_poll); + +static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL); + +static struct attribute *adis16350_trigger_attrs[] = { + &dev_attr_name.attr, + NULL, +}; + +static const struct attribute_group adis16350_trigger_attr_group = { + .attrs = adis16350_trigger_attrs, +}; + +/** + * adis16350_data_rdy_trigger_set_state() set datardy interrupt state + **/ +static int adis16350_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct adis16350_state *st = trig->private_data; + struct iio_dev *indio_dev = st->indio_dev; + int ret = 0; + + dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); + ret = adis16350_set_irq(&st->indio_dev->dev, state); + if (state == false) { + iio_remove_event_from_list(&iio_event_data_rdy_trig, + &indio_dev->interrupts[0] + ->ev_list); + /* possible quirk with handler currently worked around + by ensuring the work queue is empty */ + flush_scheduled_work(); + } else { + iio_add_event_to_list(&iio_event_data_rdy_trig, + &indio_dev->interrupts[0]->ev_list); + } + return ret; +} + +/** + * adis16350_trig_try_reen() try renabling irq for data rdy trigger + * @trig: the datardy trigger + **/ +static int adis16350_trig_try_reen(struct iio_trigger *trig) +{ + struct adis16350_state *st = trig->private_data; + enable_irq(st->us->irq); + /* irq reenabled so success! */ + return 0; +} + +int adis16350_probe_trigger(struct iio_dev *indio_dev) +{ + int ret; + struct adis16350_state *st = indio_dev->dev_data; + + st->trig = iio_allocate_trigger(); + st->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL); + if (!st->trig->name) { + ret = -ENOMEM; + goto error_free_trig; + } + snprintf((char *)st->trig->name, + IIO_TRIGGER_NAME_LENGTH, + "adis16350-dev%d", indio_dev->id); + st->trig->dev.parent = &st->us->dev; + st->trig->owner = THIS_MODULE; + st->trig->private_data = st; + st->trig->set_trigger_state = &adis16350_data_rdy_trigger_set_state; + st->trig->try_reenable = &adis16350_trig_try_reen; + st->trig->control_attrs = &adis16350_trigger_attr_group; + ret = iio_trigger_register(st->trig); + + /* select default trigger */ + indio_dev->trig = st->trig; + if (ret) + goto error_free_trig_name; + + return 0; + +error_free_trig_name: + kfree(st->trig->name); +error_free_trig: + iio_free_trigger(st->trig); + + return ret; +} + +void adis16350_remove_trigger(struct iio_dev *indio_dev) +{ + struct adis16350_state *state = indio_dev->dev_data; + + iio_trigger_unregister(state->trig); + kfree(state->trig->name); + iio_free_trigger(state->trig); +} -- cgit v1.2.3 From 026386976067996a6fc084b1926558522126cfdd Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 17 May 2010 19:34:27 +0800 Subject: Staging: comedi: Altered the way printk is used in 8255.c This patch moves around the use of printk calls in 8255.c to include accurate logging levels and in turn fixes a few warnings from checkpatch. Signed-off-by: Mark Rankilor Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index b2e80dd5c266..fe63830bd850 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -396,8 +396,6 @@ static int dev_8255_attach(struct comedi_device *dev, unsigned long iobase; int i; - printk("comedi%d: 8255:", dev->minor); - dev->board_name = "8255"; for (i = 0; i < COMEDI_NDEVCONFOPTS; i++) { @@ -406,13 +404,20 @@ static int dev_8255_attach(struct comedi_device *dev, break; } if (i == 0) { - printk(" no devices specified\n"); + printk(KERN_WARNING + "comedi%d: 8255: no devices specified\n", dev->minor); return -EINVAL; } ret = alloc_subdevices(dev, i); - if (ret < 0) + if (ret < 0) { + /* FIXME this printk call should give a proper message, the + * below line just maintains previous functionality */ + printk("comedi%d: 8255:", dev->minor); return ret; + } + + printk(KERN_INFO "comedi%d: 8255:", dev->minor); for (i = 0; i < dev->n_subdevices; i++) { iobase = it->options[i]; @@ -439,7 +444,7 @@ static int dev_8255_detach(struct comedi_device *dev) unsigned long iobase; struct comedi_subdevice *s; - printk("comedi%d: 8255: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: 8255: remove\n", dev->minor); for (i = 0; i < dev->n_subdevices; i++) { s = dev->subdevices + i; -- cgit v1.2.3 From 213d2e9322ed509c2f80b07d7feb4427ebcd7b0b Mon Sep 17 00:00:00 2001 From: Andres More Date: Mon, 17 May 2010 21:34:00 -0300 Subject: Staging: vt6656: removed custom CHAR/SHORT/INT/LONG typedefs Cleared all checkpatch warnings but one 'do not add new typedefs' Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/bssdb.c | 8 +++--- drivers/staging/vt6656/bssdb.h | 6 ++--- drivers/staging/vt6656/channel.c | 2 +- drivers/staging/vt6656/device.h | 23 +++++++++-------- drivers/staging/vt6656/dpc.c | 18 +++++++------- drivers/staging/vt6656/ioctl.c | 2 +- drivers/staging/vt6656/mib.c | 53 ++++++++++++++++++++++++++++++---------- drivers/staging/vt6656/mib.h | 12 ++++----- drivers/staging/vt6656/rf.c | 4 +-- drivers/staging/vt6656/ttype.h | 5 ---- 10 files changed, 77 insertions(+), 56 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/bssdb.c b/drivers/staging/vt6656/bssdb.c index 8c68e04cf988..a10c46339add 100644 --- a/drivers/staging/vt6656/bssdb.c +++ b/drivers/staging/vt6656/bssdb.c @@ -608,7 +608,7 @@ BOOL BSSbUpdateToBSSList(void *hDeviceContext, PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); PSRxMgmtPacket pRxPacket = (PSRxMgmtPacket)pRxPacketContext; - LONG ldBm, ldBmSum; + signed long ldBm, ldBmSum; BOOL bParsingQuiet = FALSE; // BYTE abyTmpSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; @@ -1550,9 +1550,9 @@ void s_vCheckSensitivity(void *hDeviceContext) ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) { pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID); if (pBSSList != NULL) { - // Updata BB Reg if RSSI is too strong. - LONG LocalldBmAverage = 0; - LONG uNumofdBm = 0; + /* Update BB register if RSSI is too strong */ + signed long LocalldBmAverage = 0; + signed long uNumofdBm = 0; for (ii = 0; ii < RSSI_STAT_COUNT; ii++) { if (pBSSList->ldBmAverage[ii] != 0) { uNumofdBm ++; diff --git a/drivers/staging/vt6656/bssdb.h b/drivers/staging/vt6656/bssdb.h index 8140b9b37fb4..0158b0bdf1a0 100644 --- a/drivers/staging/vt6656/bssdb.h +++ b/drivers/staging/vt6656/bssdb.h @@ -109,9 +109,9 @@ typedef struct tagKnownBSS { // WORD wATIMWindow; BYTE byRSSIStatCnt; - LONG ldBmMAX; - LONG ldBmAverage[RSSI_STAT_COUNT]; - LONG ldBmAverRange; + signed long ldBmMAX; + signed long ldBmAverage[RSSI_STAT_COUNT]; + signed long ldBmAverRange; //For any BSSID selection improvment BOOL bSelected; diff --git a/drivers/staging/vt6656/channel.c b/drivers/staging/vt6656/channel.c index 06a213f3f4df..c9b8b19a1f7b 100644 --- a/drivers/staging/vt6656/channel.c +++ b/drivers/staging/vt6656/channel.c @@ -116,7 +116,7 @@ static SChannelTblElement sChannelTbl[CB_MAX_CHANNEL+1] = static struct { BYTE byChannelCountryCode; /* The country code */ - CHAR chCountryCode[2]; + char chCountryCode[2]; BYTE bChannelIdxList[CB_MAX_CHANNEL]; /* Available channels Index */ BYTE byPower[CB_MAX_CHANNEL]; } ChannelRuleTab[] = diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index b507bb8193d6..eb45ee597644 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -210,7 +210,7 @@ typedef enum _CONTEXT_TYPE { typedef struct _RCB { void *Next; - LONG Ref; + signed long Ref; void *pDevice; struct urb *pUrb; SRxMgmtPacket sMngPacket; @@ -234,16 +234,15 @@ typedef struct _USB_SEND_CONTEXT { } USB_SEND_CONTEXT, *PUSB_SEND_CONTEXT; -//structure got from configuration file as user desired default setting. -typedef struct _DEFAULT_CONFIG{ - INT ZoneType; - INT eConfigMode; - INT eAuthenMode; //open/wep/wpa - INT bShareKeyAlgorithm; //open-open/open-sharekey/wep-sharekey - INT keyidx; //wepkey index - INT eEncryptionStatus; - -}DEFAULT_CONFIG,*PDEFAULT_CONFIG; +/* structure got from configuration file as user-desired default settings */ +typedef struct _DEFAULT_CONFIG { + signed int ZoneType; + signed int eConfigMode; + signed int eAuthenMode; /* open/wep/wpa */ + signed int bShareKeyAlgorithm; /* open-open/{open,wep}-sharekey */ + signed int keyidx; /* wepkey index */ + signed int eEncryptionStatus; +} DEFAULT_CONFIG, *PDEFAULT_CONFIG; // // Structure to keep track of usb interrupt packets @@ -785,7 +784,7 @@ typedef struct __device_info { BYTE byBBVGANew; BYTE byBBVGACurrent; BYTE abyBBVGA[BB_VGA_LEVEL]; - LONG ldBmThreshold[BB_VGA_LEVEL]; + signed long ldBmThreshold[BB_VGA_LEVEL]; BYTE byBBPreEDRSSI; BYTE byBBPreEDIndex; diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index 6982224dfa90..d9a02ba40d84 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -98,7 +98,7 @@ s_vProcessRxMACHeader ( static BOOL s_bAPModeRxCtl( PSDevice pDevice, PBYTE pbyFrame, - INT iSANodeIndex + signed int iSANodeIndex ); @@ -108,8 +108,8 @@ static BOOL s_bAPModeRxData ( struct sk_buff *skb, UINT FrameSize, UINT cbHeaderOffset, - INT iSANodeIndex, - INT iDANodeIndex + signed int iSANodeIndex, + signed int iDANodeIndex ); @@ -336,8 +336,8 @@ RXbBulkInProcessData ( UINT cbHeaderOffset; UINT FrameSize; WORD wEtherType = 0; - INT iSANodeIndex = -1; - INT iDANodeIndex = -1; + signed int iSANodeIndex = -1; + signed int iDANodeIndex = -1; UINT ii; UINT cbIVOffset; PBYTE pbyRxSts; @@ -352,7 +352,7 @@ RXbBulkInProcessData ( DWORD dwRxTSC47_16 = 0; SKeyItem STempKey; // 802.11h RPI - //LONG ldBm = 0; + /* signed long ldBm = 0; */ BOOL bIsWEP = FALSE; BOOL bExtIV = FALSE; DWORD dwWbkStatus; @@ -1023,7 +1023,7 @@ RXbBulkInProcessData ( static BOOL s_bAPModeRxCtl ( PSDevice pDevice, PBYTE pbyFrame, - INT iSANodeIndex + signed int iSANodeIndex ) { PS802_11Header p802_11Header; @@ -1431,8 +1431,8 @@ static BOOL s_bAPModeRxData ( struct sk_buff *skb, UINT FrameSize, UINT cbHeaderOffset, - INT iSANodeIndex, - INT iDANodeIndex + signed int iSANodeIndex, + signed int iDANodeIndex ) { diff --git a/drivers/staging/vt6656/ioctl.c b/drivers/staging/vt6656/ioctl.c index 69d1d735f712..368e49f782fc 100644 --- a/drivers/staging/vt6656/ioctl.c +++ b/drivers/staging/vt6656/ioctl.c @@ -81,7 +81,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) { BYTE abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; DWORD dwKeyIndex= 0; BYTE abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - LONG ldBm; + signed long ldBm; pReq->wResult = 0; diff --git a/drivers/staging/vt6656/mib.c b/drivers/staging/vt6656/mib.c index b6f138efb472..efcd81c042f2 100644 --- a/drivers/staging/vt6656/mib.c +++ b/drivers/staging/vt6656/mib.c @@ -187,87 +187,114 @@ void STAvUpdateRDStatCounter (PSStatCounter pStatistic, if(byRSR & RSR_CRCOK) { pStatistic->CustomStat.ullRsr11MCRCOk++; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"11M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr11M, (INT)pStatistic->CustomStat.ullRsr11MCRCOk, byRSR); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "11M: ALL[%d], OK[%d]:[%02x]\n", + (signed int) pStatistic->CustomStat.ullRsr11M, + (signed int) pStatistic->CustomStat.ullRsr11MCRCOk, byRSR); } else if(byRxRate==11) { pStatistic->CustomStat.ullRsr5M++; if(byRSR & RSR_CRCOK) { pStatistic->CustomStat.ullRsr5MCRCOk++; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 5M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr5M, (INT)pStatistic->CustomStat.ullRsr5MCRCOk, byRSR); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 5M: ALL[%d], OK[%d]:[%02x]\n", + (signed int) pStatistic->CustomStat.ullRsr5M, + (signed int) pStatistic->CustomStat.ullRsr5MCRCOk, byRSR); } else if(byRxRate==4) { pStatistic->CustomStat.ullRsr2M++; if(byRSR & RSR_CRCOK) { pStatistic->CustomStat.ullRsr2MCRCOk++; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 2M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr2M, (INT)pStatistic->CustomStat.ullRsr2MCRCOk, byRSR); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 2M: ALL[%d], OK[%d]:[%02x]\n", + (signed int) pStatistic->CustomStat.ullRsr2M, + (signed int) pStatistic->CustomStat.ullRsr2MCRCOk, byRSR); } else if(byRxRate==2){ pStatistic->CustomStat.ullRsr1M++; if(byRSR & RSR_CRCOK) { pStatistic->CustomStat.ullRsr1MCRCOk++; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 1M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr1M, (INT)pStatistic->CustomStat.ullRsr1MCRCOk, byRSR); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 1M: ALL[%d], OK[%d]:[%02x]\n", + (signed int) pStatistic->CustomStat.ullRsr1M, + (signed int) pStatistic->CustomStat.ullRsr1MCRCOk, byRSR); } else if(byRxRate==12){ pStatistic->CustomStat.ullRsr6M++; if(byRSR & RSR_CRCOK) { pStatistic->CustomStat.ullRsr6MCRCOk++; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 6M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr6M, (INT)pStatistic->CustomStat.ullRsr6MCRCOk); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 6M: ALL[%d], OK[%d]\n", + (signed int) pStatistic->CustomStat.ullRsr6M, + (signed int) pStatistic->CustomStat.ullRsr6MCRCOk); } else if(byRxRate==18){ pStatistic->CustomStat.ullRsr9M++; if(byRSR & RSR_CRCOK) { pStatistic->CustomStat.ullRsr9MCRCOk++; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 9M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr9M, (INT)pStatistic->CustomStat.ullRsr9MCRCOk); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 9M: ALL[%d], OK[%d]\n", + (signed int) pStatistic->CustomStat.ullRsr9M, + (signed int) pStatistic->CustomStat.ullRsr9MCRCOk); } else if(byRxRate==24){ pStatistic->CustomStat.ullRsr12M++; if(byRSR & RSR_CRCOK) { pStatistic->CustomStat.ullRsr12MCRCOk++; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"12M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr12M, (INT)pStatistic->CustomStat.ullRsr12MCRCOk); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "12M: ALL[%d], OK[%d]\n", + (signed int) pStatistic->CustomStat.ullRsr12M, + (signed int) pStatistic->CustomStat.ullRsr12MCRCOk); } else if(byRxRate==36){ pStatistic->CustomStat.ullRsr18M++; if(byRSR & RSR_CRCOK) { pStatistic->CustomStat.ullRsr18MCRCOk++; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"18M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr18M, (INT)pStatistic->CustomStat.ullRsr18MCRCOk); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "18M: ALL[%d], OK[%d]\n", + (signed int) pStatistic->CustomStat.ullRsr18M, + (signed int) pStatistic->CustomStat.ullRsr18MCRCOk); } else if(byRxRate==48){ pStatistic->CustomStat.ullRsr24M++; if(byRSR & RSR_CRCOK) { pStatistic->CustomStat.ullRsr24MCRCOk++; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"24M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr24M, (INT)pStatistic->CustomStat.ullRsr24MCRCOk); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "24M: ALL[%d], OK[%d]\n", + (signed int) pStatistic->CustomStat.ullRsr24M, + (signed int) pStatistic->CustomStat.ullRsr24MCRCOk); } else if(byRxRate==72){ pStatistic->CustomStat.ullRsr36M++; if(byRSR & RSR_CRCOK) { pStatistic->CustomStat.ullRsr36MCRCOk++; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"36M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr36M, (INT)pStatistic->CustomStat.ullRsr36MCRCOk); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "36M: ALL[%d], OK[%d]\n", + (signed int) pStatistic->CustomStat.ullRsr36M, + (signed int) pStatistic->CustomStat.ullRsr36MCRCOk); } else if(byRxRate==96){ pStatistic->CustomStat.ullRsr48M++; if(byRSR & RSR_CRCOK) { pStatistic->CustomStat.ullRsr48MCRCOk++; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"48M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr48M, (INT)pStatistic->CustomStat.ullRsr48MCRCOk); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "48M: ALL[%d], OK[%d]\n", + (signed int) pStatistic->CustomStat.ullRsr48M, + (signed int) pStatistic->CustomStat.ullRsr48MCRCOk); } else if(byRxRate==108){ pStatistic->CustomStat.ullRsr54M++; if(byRSR & RSR_CRCOK) { pStatistic->CustomStat.ullRsr54MCRCOk++; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"54M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr54M, (INT)pStatistic->CustomStat.ullRsr54MCRCOk); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "54M: ALL[%d], OK[%d]\n", + (signed int) pStatistic->CustomStat.ullRsr54M, + (signed int) pStatistic->CustomStat.ullRsr54MCRCOk); } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown: Total[%d], CRCOK[%d]\n", (INT)pStatistic->dwRsrRxPacket+1, (INT)pStatistic->dwRsrCRCOk); + DBG_PRT(MSG_LEVEL_DEBUG, + KERN_INFO "Unknown: Total[%d], CRCOK[%d]\n", + (signed int) pStatistic->dwRsrRxPacket+1, + (signed int)pStatistic->dwRsrCRCOk); } if (byRSR & RSR_BSSIDOK) diff --git a/drivers/staging/vt6656/mib.h b/drivers/staging/vt6656/mib.h index 8a532e877f0f..8cc5b3f0d70e 100644 --- a/drivers/staging/vt6656/mib.h +++ b/drivers/staging/vt6656/mib.h @@ -85,15 +85,15 @@ typedef struct tagSDot11Counters { // MIB2 counter // typedef struct tagSMib2Counter { - LONG ifIndex; + signed long ifIndex; char ifDescr[256]; // max size 255 plus zero ending // e.g. "interface 1" - LONG ifType; - LONG ifMtu; + signed long ifType; + signed long ifMtu; DWORD ifSpeed; BYTE ifPhysAddress[ETH_ALEN]; - LONG ifAdminStatus; - LONG ifOperStatus; + signed long ifAdminStatus; + signed long ifOperStatus; DWORD ifLastChange; DWORD ifInOctets; DWORD ifInUcastPkts; @@ -124,7 +124,7 @@ typedef struct tagSMib2Counter { // RMON counter // typedef struct tagSRmonCounter { - LONG etherStatsIndex; + signed long etherStatsIndex; DWORD etherStatsDataSource; DWORD etherStatsDropEvents; DWORD etherStatsOctets; diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c index 1126cb48f4a1..4c4f5f6dc366 100644 --- a/drivers/staging/vt6656/rf.c +++ b/drivers/staging/vt6656/rf.c @@ -962,8 +962,8 @@ RFvRSSITodBm ( ) { BYTE byIdx = (((byCurrRSSI & 0xC0) >> 6) & 0x03); - LONG b = (byCurrRSSI & 0x3F); - LONG a = 0; + signed long b = (byCurrRSSI & 0x3F); + signed long a = 0; BYTE abyAIROHARF[4] = {0, 18, 0, 40}; switch (pDevice->byRFType) { diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h index 4dfe00acf24a..3a297754233a 100644 --- a/drivers/staging/vt6656/ttype.h +++ b/drivers/staging/vt6656/ttype.h @@ -72,11 +72,6 @@ typedef int BOOL; /****** Simple typedefs ***************************************************/ -typedef char CHAR; -typedef signed short SHORT; -typedef signed int INT; -typedef signed long LONG; - typedef unsigned char UCHAR; typedef unsigned short USHORT; typedef unsigned int UINT; -- cgit v1.2.3 From cc856e61ee4ffb150ff352e3d6940978a2f819e8 Mon Sep 17 00:00:00 2001 From: Andres More Date: Mon, 17 May 2010 21:34:01 -0300 Subject: Staging: vt6656: removed custom UCHAR/USHORT/UINT/ULONG/ULONGLONG typedefs Cleared all checkpatch warnings but 'do not add new typedefs' ones. Signed-off-by: Andres More Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/80211mgr.h | 48 ++++---- drivers/staging/vt6656/baseband.c | 52 ++++----- drivers/staging/vt6656/baseband.h | 6 +- drivers/staging/vt6656/bssdb.c | 109 +++++++++--------- drivers/staging/vt6656/bssdb.h | 48 ++++---- drivers/staging/vt6656/card.c | 14 +-- drivers/staging/vt6656/card.h | 3 +- drivers/staging/vt6656/channel.c | 6 +- drivers/staging/vt6656/channel.h | 6 +- drivers/staging/vt6656/datarate.c | 14 +-- drivers/staging/vt6656/datarate.h | 2 +- drivers/staging/vt6656/device.h | 157 ++++++++++++------------- drivers/staging/vt6656/dpc.c | 49 ++++---- drivers/staging/vt6656/dpc.h | 2 +- drivers/staging/vt6656/hostap.c | 14 +-- drivers/staging/vt6656/ioctl.c | 6 +- drivers/staging/vt6656/ioctl.h | 2 +- drivers/staging/vt6656/iwctl.c | 8 +- drivers/staging/vt6656/key.c | 22 ++-- drivers/staging/vt6656/key.h | 8 +- drivers/staging/vt6656/mac.c | 14 +-- drivers/staging/vt6656/mac.h | 7 +- drivers/staging/vt6656/main_usb.c | 50 ++++---- drivers/staging/vt6656/mib.c | 43 ++++--- drivers/staging/vt6656/mib.h | 171 ++++++++++++++-------------- drivers/staging/vt6656/michael.c | 8 +- drivers/staging/vt6656/michael.h | 2 +- drivers/staging/vt6656/rc4.c | 22 ++-- drivers/staging/vt6656/rc4.h | 11 +- drivers/staging/vt6656/rf.c | 6 +- drivers/staging/vt6656/rf.h | 6 +- drivers/staging/vt6656/rxtx.c | 234 ++++++++++++++++++-------------------- drivers/staging/vt6656/rxtx.h | 17 +-- drivers/staging/vt6656/tcrc.c | 6 +- drivers/staging/vt6656/tcrc.h | 6 +- drivers/staging/vt6656/tether.c | 2 +- drivers/staging/vt6656/tether.h | 2 +- drivers/staging/vt6656/ttype.h | 6 - drivers/staging/vt6656/upc.h | 2 +- drivers/staging/vt6656/usbpipe.c | 15 ++- drivers/staging/vt6656/wcmd.c | 18 +-- drivers/staging/vt6656/wctl.c | 17 +-- drivers/staging/vt6656/wctl.h | 8 +- drivers/staging/vt6656/wmgr.c | 69 +++++------ drivers/staging/vt6656/wmgr.h | 62 +++++----- drivers/staging/vt6656/wpa2.c | 4 +- drivers/staging/vt6656/wpa2.h | 4 +- drivers/staging/vt6656/wpactl.h | 4 +- 48 files changed, 700 insertions(+), 692 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/80211mgr.h b/drivers/staging/vt6656/80211mgr.h index 50982e9f8cdf..c140a957d9df 100644 --- a/drivers/staging/vt6656/80211mgr.h +++ b/drivers/staging/vt6656/80211mgr.h @@ -524,8 +524,8 @@ typedef struct _WLAN_IE_IBSS_DFS { // prototype structure, all mgmt frame types will start with these members typedef struct tagWLAN_FR_MGMT { - UINT uType; - UINT len; + unsigned int uType; + unsigned int len; PBYTE pBuf; PUWLAN_80211HDR pHdr; @@ -534,8 +534,8 @@ typedef struct tagWLAN_FR_MGMT { // Beacon frame typedef struct tagWLAN_FR_BEACON { - UINT uType; - UINT len; + unsigned int uType; + unsigned int len; PBYTE pBuf; PUWLAN_80211HDR pHdr; // fixed fields @@ -566,8 +566,8 @@ typedef struct tagWLAN_FR_BEACON { // IBSS ATIM frame typedef struct tagWLAN_FR_IBSSATIM { - UINT uType; - UINT len; + unsigned int uType; + unsigned int len; PBYTE pBuf; PUWLAN_80211HDR pHdr; @@ -580,8 +580,8 @@ typedef struct tagWLAN_FR_IBSSATIM { // Disassociation typedef struct tagWLAN_FR_DISASSOC { - UINT uType; - UINT len; + unsigned int uType; + unsigned int len; PBYTE pBuf; PUWLAN_80211HDR pHdr; /*-- fixed fields -----------*/ @@ -593,8 +593,8 @@ typedef struct tagWLAN_FR_DISASSOC { // Association Request typedef struct tagWLAN_FR_ASSOCREQ { - UINT uType; - UINT len; + unsigned int uType; + unsigned int len; PBYTE pBuf; PUWLAN_80211HDR pHdr; /*-- fixed fields -----------*/ @@ -617,8 +617,8 @@ typedef struct tagWLAN_FR_ASSOCREQ { // Association Response typedef struct tagWLAN_FR_ASSOCRESP { - UINT uType; - UINT len; + unsigned int uType; + unsigned int len; PBYTE pBuf; PUWLAN_80211HDR pHdr; /*-- fixed fields -----------*/ @@ -634,8 +634,8 @@ typedef struct tagWLAN_FR_ASSOCRESP { // Reassociation Request typedef struct tagWLAN_FR_REASSOCREQ { - UINT uType; - UINT len; + unsigned int uType; + unsigned int len; PBYTE pBuf; PUWLAN_80211HDR pHdr; @@ -659,8 +659,8 @@ typedef struct tagWLAN_FR_REASSOCREQ { // Reassociation Response typedef struct tagWLAN_FR_REASSOCRESP { - UINT uType; - UINT len; + unsigned int uType; + unsigned int len; PBYTE pBuf; PUWLAN_80211HDR pHdr; /*-- fixed fields -----------*/ @@ -676,8 +676,8 @@ typedef struct tagWLAN_FR_REASSOCRESP { // Probe Request typedef struct tagWLAN_FR_PROBEREQ { - UINT uType; - UINT len; + unsigned int uType; + unsigned int len; PBYTE pBuf; PUWLAN_80211HDR pHdr; /*-- fixed fields -----------*/ @@ -691,8 +691,8 @@ typedef struct tagWLAN_FR_PROBEREQ { // Probe Response typedef struct tagWLAN_FR_PROBERESP { - UINT uType; - UINT len; + unsigned int uType; + unsigned int len; PBYTE pBuf; PUWLAN_80211HDR pHdr; /*-- fixed fields -----------*/ @@ -720,8 +720,8 @@ typedef struct tagWLAN_FR_PROBERESP { // Authentication typedef struct tagWLAN_FR_AUTHEN { - UINT uType; - UINT len; + unsigned int uType; + unsigned int len; PBYTE pBuf; PUWLAN_80211HDR pHdr; /*-- fixed fields -----------*/ @@ -736,8 +736,8 @@ typedef struct tagWLAN_FR_AUTHEN { // Deauthenication typedef struct tagWLAN_FR_DEAUTHEN { - UINT uType; - UINT len; + unsigned int uType; + unsigned int len; PBYTE pBuf; PUWLAN_80211HDR pHdr; /*-- fixed fields -----------*/ diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c index 01680e6b0f5b..d3de94f36c6e 100644 --- a/drivers/staging/vt6656/baseband.c +++ b/drivers/staging/vt6656/baseband.c @@ -662,11 +662,11 @@ const WORD awcFrameTime[MAX_RATE] = /* static -ULONG +unsigned long s_ulGetLowSQ3(PSDevice pDevice); static -ULONG +unsigned long s_ulGetRatio(PSDevice pDevice); static @@ -689,19 +689,19 @@ s_vClearSQ3Value(PSDevice pDevice); * Return Value: FrameTime * */ -UINT +unsigned int BBuGetFrameTime ( BYTE byPreambleType, BYTE byPktType, - UINT cbFrameLength, + unsigned int cbFrameLength, WORD wRate ) { - UINT uFrameTime; - UINT uPreamble; - UINT uTmp; - UINT uRateIdx = (UINT)wRate; - UINT uRate = 0; + unsigned int uFrameTime; + unsigned int uPreamble; + unsigned int uTmp; + unsigned int uRateIdx = (unsigned int)wRate; + unsigned int uRate = 0; if (uRateIdx > RATE_54M) { @@ -709,7 +709,7 @@ BBuGetFrameTime ( return 0; } - uRate = (UINT)awcFrameTime[uRateIdx]; + uRate = (unsigned int)awcFrameTime[uRateIdx]; if (uRateIdx <= 3) { //CCK mode @@ -759,7 +759,7 @@ BBuGetFrameTime ( void BBvCaculateParameter ( PSDevice pDevice, - UINT cbFrameLength, + unsigned int cbFrameLength, WORD wRate, BYTE byPacketType, PWORD pwPhyLen, @@ -767,9 +767,9 @@ BBvCaculateParameter ( PBYTE pbyPhySgn ) { - UINT cbBitCount; - UINT cbUsCount = 0; - UINT cbTmp; + unsigned int cbBitCount; + unsigned int cbUsCount = 0; + unsigned int cbTmp; BOOL bExtBit; BYTE byPreambleType = pDevice->byPreambleType; BOOL bCCK = pDevice->bCCK; @@ -1360,13 +1360,11 @@ BBvExitDeepSleep (PSDevice pDevice) } -static -ULONG -s_ulGetLowSQ3(PSDevice pDevice) +static unsigned long s_ulGetLowSQ3(PSDevice pDevice) { -int ii; -ULONG ulSQ3 = 0; -ULONG ulMaxPacket; + int ii; + unsigned long ulSQ3 = 0; + unsigned long ulMaxPacket; ulMaxPacket = pDevice->aulPktNum[RATE_54M]; if ( pDevice->aulPktNum[RATE_54M] != 0 ) { @@ -1382,16 +1380,12 @@ ULONG ulMaxPacket; return ulSQ3; } - - -static -ULONG -s_ulGetRatio (PSDevice pDevice) +static unsigned long s_ulGetRatio(PSDevice pDevice) { -int ii,jj; -ULONG ulRatio = 0; -ULONG ulMaxPacket; -ULONG ulPacketNum; + int ii, jj; + unsigned long ulRatio = 0; + unsigned long ulMaxPacket; + unsigned long ulPacketNum; //This is a thousand-ratio ulMaxPacket = pDevice->aulPktNum[RATE_54M]; diff --git a/drivers/staging/vt6656/baseband.h b/drivers/staging/vt6656/baseband.h index d59992c17ec8..bc4633d5fead 100644 --- a/drivers/staging/vt6656/baseband.h +++ b/drivers/staging/vt6656/baseband.h @@ -96,18 +96,18 @@ /*--------------------- Export Functions --------------------------*/ -UINT +unsigned int BBuGetFrameTime( BYTE byPreambleType, BYTE byFreqType, - UINT cbFrameLength, + unsigned int cbFrameLength, WORD wRate ); void BBvCaculateParameter ( PSDevice pDevice, - UINT cbFrameLength, + unsigned int cbFrameLength, WORD wRate, BYTE byPacketType, PWORD pwPhyLen, diff --git a/drivers/staging/vt6656/bssdb.c b/drivers/staging/vt6656/bssdb.c index a10c46339add..36ed61b595ca 100644 --- a/drivers/staging/vt6656/bssdb.c +++ b/drivers/staging/vt6656/bssdb.c @@ -129,8 +129,8 @@ PKnownBSS BSSpSearchBSSList(void *hDeviceContext, PKnownBSS pCurrBSS = NULL; PKnownBSS pSelect = NULL; BYTE ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00}; - UINT ii = 0; - UINT jj = 0; //DavidWang + unsigned int ii = 0; + unsigned int jj = 0; if (pbyDesireBSSID != NULL) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSpSearchBSSList BSSID[%02X %02X %02X-%02X %02X %02X]\n", *pbyDesireBSSID,*(pbyDesireBSSID+1),*(pbyDesireBSSID+2), @@ -291,7 +291,7 @@ void BSSvClearBSSList(void *hDeviceContext, BOOL bKeepCurrBSSID) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - UINT ii; + unsigned int ii; for (ii = 0; ii < MAX_BSS_NUM; ii++) { if (bKeepCurrBSSID) { @@ -336,7 +336,7 @@ PKnownBSS BSSpAddrIsInBSSList(void *hDeviceContext, PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); PKnownBSS pBSSList = NULL; - UINT ii; + unsigned int ii; for (ii = 0; ii < MAX_BSS_NUM; ii++) { pBSSList = &(pMgmt->sBSSList[ii]); @@ -381,7 +381,7 @@ BOOL BSSbInsertToBSSList(void *hDeviceContext, PWLAN_IE_RSN_EXT pRSNWPA, PWLAN_IE_COUNTRY pIE_Country, PWLAN_IE_QUIET pIE_Quiet, - UINT uIELength, + unsigned int uIELength, PBYTE pbyIEs, void *pRxPacketContext) { @@ -390,7 +390,7 @@ BOOL BSSbInsertToBSSList(void *hDeviceContext, PSMgmtObject pMgmt = &(pDevice->sMgmtObj); PSRxMgmtPacket pRxPacket = (PSRxMgmtPacket)pRxPacketContext; PKnownBSS pBSSList = NULL; - UINT ii; + unsigned int ii; BOOL bParsingQuiet = FALSE; @@ -465,24 +465,27 @@ BOOL BSSbInsertToBSSList(void *hDeviceContext, WPA_ClearRSN(pBSSList); if (pRSNWPA != NULL) { - UINT uLen = pRSNWPA->len + 2; - - if (uLen <= (uIELength - (UINT)(ULONG_PTR)((PBYTE)pRSNWPA - pbyIEs))) { - pBSSList->wWPALen = uLen; - memcpy(pBSSList->byWPAIE, pRSNWPA, uLen); - WPA_ParseRSN(pBSSList, pRSNWPA); - } + unsigned int uLen = pRSNWPA->len + 2; + + if (uLen <= (uIELength - + (unsigned int) (ULONG_PTR) ((PBYTE) pRSNWPA - pbyIEs))) { + pBSSList->wWPALen = uLen; + memcpy(pBSSList->byWPAIE, pRSNWPA, uLen); + WPA_ParseRSN(pBSSList, pRSNWPA); + } } WPA2_ClearRSN(pBSSList); if (pRSN != NULL) { - UINT uLen = pRSN->len + 2; - if (uLen <= (uIELength - (UINT)(ULONG_PTR)((PBYTE)pRSN - pbyIEs))) { - pBSSList->wRSNLen = uLen; - memcpy(pBSSList->byRSNIE, pRSN, uLen); - WPA2vParseRSN(pBSSList, pRSN); - } + unsigned int uLen = pRSN->len + 2; + + if (uLen <= (uIELength - + (unsigned int) (ULONG_PTR) ((PBYTE) pRSN - pbyIEs))) { + pBSSList->wRSNLen = uLen; + memcpy(pBSSList->byRSNIE, pRSN, uLen); + WPA2vParseRSN(pBSSList, pRSN); + } } if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || (pBSSList->bWPA2Valid == TRUE)) { @@ -600,7 +603,7 @@ BOOL BSSbUpdateToBSSList(void *hDeviceContext, PWLAN_IE_COUNTRY pIE_Country, PWLAN_IE_QUIET pIE_Quiet, PKnownBSS pBSSList, - UINT uIELength, + unsigned int uIELength, PBYTE pbyIEs, void *pRxPacketContext) { @@ -667,24 +670,26 @@ BOOL BSSbUpdateToBSSList(void *hDeviceContext, WPA_ClearRSN(pBSSList); //mike update - if (pRSNWPA != NULL) { - UINT uLen = pRSNWPA->len + 2; - if (uLen <= (uIELength - (UINT)(ULONG_PTR)((PBYTE)pRSNWPA - pbyIEs))) { - pBSSList->wWPALen = uLen; - memcpy(pBSSList->byWPAIE, pRSNWPA, uLen); - WPA_ParseRSN(pBSSList, pRSNWPA); - } - } + if (pRSNWPA != NULL) { + unsigned int uLen = pRSNWPA->len + 2; + if (uLen <= (uIELength - + (unsigned int) (ULONG_PTR) ((PBYTE) pRSNWPA - pbyIEs))) { + pBSSList->wWPALen = uLen; + memcpy(pBSSList->byWPAIE, pRSNWPA, uLen); + WPA_ParseRSN(pBSSList, pRSNWPA); + } + } WPA2_ClearRSN(pBSSList); //mike update if (pRSN != NULL) { - UINT uLen = pRSN->len + 2; - if (uLen <= (uIELength - (UINT)(ULONG_PTR)((PBYTE)pRSN - pbyIEs))) { - pBSSList->wRSNLen = uLen; - memcpy(pBSSList->byRSNIE, pRSN, uLen); - WPA2vParseRSN(pBSSList, pRSN); - } + unsigned int uLen = pRSN->len + 2; + if (uLen <= (uIELength - + (unsigned int) (ULONG_PTR) ((PBYTE) pRSN - pbyIEs))) { + pBSSList->wRSNLen = uLen; + memcpy(pBSSList->byRSNIE, pRSN, uLen); + WPA2vParseRSN(pBSSList, pRSN); + } } if (pRxPacket->uRSSI != 0) { @@ -754,7 +759,7 @@ BOOL BSSbIsSTAInNodeDB(void *hDeviceContext, { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - UINT ii; + unsigned int ii; // Index = 0 reserved for AP Node for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) { @@ -786,9 +791,9 @@ void BSSvCreateOneNode(void *hDeviceContext, PUINT puNodeIndex) PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - UINT ii; - UINT BigestCount = 0; - UINT SelectIndex; + unsigned int ii; + unsigned int BigestCount = 0; + unsigned int SelectIndex; struct sk_buff *skb; // Index = 0 reserved for AP Node (In STA mode) // Index = 0 reserved for Broadcast/MultiCast (In AP mode) @@ -843,7 +848,7 @@ void BSSvCreateOneNode(void *hDeviceContext, PUINT puNodeIndex) * -*/ -void BSSvRemoveOneNode(void *hDeviceContext, UINT uNodeIndex) +void BSSvRemoveOneNode(void *hDeviceContext, unsigned int uNodeIndex) { PSDevice pDevice = (PSDevice)hDeviceContext; @@ -879,7 +884,7 @@ void BSSvUpdateAPNode(void *hDeviceContext, { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - UINT uRateLen = WLAN_RATES_MAXLEN; + unsigned int uRateLen = WLAN_RATES_MAXLEN; memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB)); @@ -967,11 +972,11 @@ void BSSvSecondCallBack(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - UINT ii; + unsigned int ii; PWLAN_IE_SSID pItemSSID, pCurrSSID; - UINT uSleepySTACnt = 0; - UINT uNonShortSlotSTACnt = 0; - UINT uLongPreambleSTACnt = 0; + unsigned int uSleepySTACnt = 0; + unsigned int uNonShortSlotSTACnt = 0; + unsigned int uLongPreambleSTACnt = 0; viawget_wpa_header *wpahdr; //DavidWang spin_lock_irq(&pDevice->lock); @@ -1360,12 +1365,12 @@ void BSSvUpdateNodeTxCounter(void *hDeviceContext, { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - UINT uNodeIndex = 0; + unsigned int uNodeIndex = 0; BYTE byTxRetry; WORD wRate; WORD wFallBackRate = RATE_1M; BYTE byFallBack; - UINT ii; + unsigned int ii; PBYTE pbyDestAddr; BYTE byPktNum; WORD wFIFOCtl; @@ -1516,12 +1521,12 @@ void BSSvUpdateNodeTxCounter(void *hDeviceContext, -*/ void BSSvClearNodeDBTable(void *hDeviceContext, - UINT uStartIndex) + unsigned int uStartIndex) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); struct sk_buff *skb; - UINT ii; + unsigned int ii; for (ii = uStartIndex; ii < (MAX_NODE_NUM + 1); ii++) { if (pMgmt->sNodeDBTable[ii].bActive) { @@ -1586,9 +1591,9 @@ void s_vCheckSensitivity(void *hDeviceContext) void s_uCalculateLinkQual(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; - ULONG TxOkRatio, TxCnt; - ULONG RxOkRatio,RxCnt; - ULONG RssiRatio; + unsigned long TxOkRatio, TxCnt; + unsigned long RxOkRatio, RxCnt; + unsigned long RssiRatio; long ldBm; TxCnt = pDevice->scStatistic.TxNoRetryOkCount + @@ -1633,7 +1638,7 @@ void BSSvClearAnyBSSJoinRecord(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - UINT ii; + unsigned int ii; for (ii = 0; ii < MAX_BSS_NUM; ii++) { pMgmt->sBSSList[ii].bSelected = FALSE; diff --git a/drivers/staging/vt6656/bssdb.h b/drivers/staging/vt6656/bssdb.h index 0158b0bdf1a0..9686d8600d63 100644 --- a/drivers/staging/vt6656/bssdb.h +++ b/drivers/staging/vt6656/bssdb.h @@ -97,10 +97,10 @@ typedef struct tagKnownBSS { // BSS info BOOL bActive; BYTE abyBSSID[WLAN_BSSID_LEN]; - UINT uChannel; + unsigned int uChannel; BYTE abySuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; BYTE abyExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; - UINT uRSSI; + unsigned int uRSSI; BYTE bySQ; WORD wBeaconInterval; WORD wCapInfo; @@ -141,9 +141,9 @@ typedef struct tagKnownBSS { WORD wRSNLen; // Clear count - UINT uClearCount; + unsigned int uClearCount; // BYTE abyIEs[WLAN_BEACON_FR_MAXLEN]; - UINT uIELength; + unsigned int uIELength; QWORD qwBSSTimestamp; QWORD qwLocalTSF; // local TSF timer @@ -178,7 +178,7 @@ typedef struct tagKnownNodeDB { BOOL bShortPreamble; BOOL bERPExist; BOOL bShortSlotTime; - UINT uInActiveCount; + unsigned int uInActiveCount; WORD wMaxBasicRate; //Get from byTopOFDMBasicRate or byTopCCKBasicRate which depends on packetTyp. WORD wMaxSuppRate; //Records the highest supported rate getting from SuppRates IE and ExtSuppRates IE in Beacon. WORD wSuppRate; @@ -194,35 +194,35 @@ typedef struct tagKnownNodeDB { BOOL bPSEnable; BOOL bRxPSPoll; BYTE byAuthSequence; - ULONG ulLastRxJiffer; + unsigned long ulLastRxJiffer; BYTE bySuppRate; DWORD dwFlags; WORD wEnQueueCnt; BOOL bOnFly; - ULONGLONG KeyRSC; + unsigned long long KeyRSC; BYTE byKeyIndex; DWORD dwKeyIndex; BYTE byCipherSuite; DWORD dwTSC47_16; WORD wTSC15_0; - UINT uWepKeyLength; + unsigned int uWepKeyLength; BYTE abyWepKey[WLAN_WEPMAX_KEYLEN]; // // Auto rate fallback vars BOOL bIsInFallback; - UINT uAverageRSSI; - UINT uRateRecoveryTimeout; - UINT uRatePollTimeout; - UINT uTxFailures; - UINT uTxAttempts; - - UINT uTxRetry; - UINT uFailureRatio; - UINT uRetryRatio; - UINT uTxOk[MAX_RATE+1]; - UINT uTxFail[MAX_RATE+1]; - UINT uTimeCount; + unsigned int uAverageRSSI; + unsigned int uRateRecoveryTimeout; + unsigned int uRatePollTimeout; + unsigned int uTxFailures; + unsigned int uTxAttempts; + + unsigned int uTxRetry; + unsigned int uFailureRatio; + unsigned int uRetryRatio; + unsigned int uTxOk[MAX_RATE+1]; + unsigned int uTxFail[MAX_RATE+1]; + unsigned int uTimeCount; } KnownNodeDB, *PKnownNodeDB; @@ -253,7 +253,7 @@ BOOL BSSbInsertToBSSList(void *hDeviceContext, PWLAN_IE_RSN_EXT pRSNWPA, PWLAN_IE_COUNTRY pIE_Country, PWLAN_IE_QUIET pIE_Quiet, - UINT uIELength, + unsigned int uIELength, PBYTE pbyIEs, void *pRxPacketContext); @@ -272,7 +272,7 @@ BOOL BSSbUpdateToBSSList(void *hDeviceContext, PWLAN_IE_COUNTRY pIE_Country, PWLAN_IE_QUIET pIE_Quiet, PKnownBSS pBSSList, - UINT uIELength, + unsigned int uIELength, PBYTE pbyIEs, void *pRxPacketContext); @@ -295,12 +295,12 @@ void BSSvUpdateNodeTxCounter(void *hDeviceContext, BYTE byPktNO); void BSSvRemoveOneNode(void *hDeviceContext, - UINT uNodeIndex); + unsigned int uNodeIndex); void BSSvAddMulticastNode(void *hDeviceContext); void BSSvClearNodeDBTable(void *hDeviceContext, - UINT uStartIndex); + unsigned int uStartIndex); void BSSvClearAnyBSSJoinRecord(void *hDeviceContext); diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c index 6baf8696254b..fe4ec913ffea 100644 --- a/drivers/staging/vt6656/card.c +++ b/drivers/staging/vt6656/card.c @@ -95,7 +95,7 @@ const WORD cwRXBCNTSFOff[MAX_RATE] = * Return Value: TRUE if succeeded; FALSE if failed. * */ -BOOL CARDbSetMediaChannel(void *pDeviceHandler, UINT uConnectionChannel) +BOOL CARDbSetMediaChannel(void *pDeviceHandler, unsigned int uConnectionChannel) { PSDevice pDevice = (PSDevice) pDeviceHandler; BOOL bResult = TRUE; @@ -159,7 +159,7 @@ BOOL bResult = TRUE; static WORD swGetCCKControlRate(void *pDeviceHandler, WORD wRateIdx) { PSDevice pDevice = (PSDevice) pDeviceHandler; - UINT ui = (UINT)wRateIdx; + unsigned int ui = (unsigned int)wRateIdx; while (ui > RATE_1M) { if (pDevice->wBasicRate & ((WORD)1 << ui)) { return (WORD)ui; @@ -185,7 +185,7 @@ static WORD swGetCCKControlRate(void *pDeviceHandler, WORD wRateIdx) static WORD swGetOFDMControlRate(void *pDeviceHandler, WORD wRateIdx) { PSDevice pDevice = (PSDevice) pDeviceHandler; - UINT ui = (UINT)wRateIdx; + unsigned int ui = (unsigned int)wRateIdx; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BASIC RATE: %X\n", pDevice->wBasicRate); @@ -508,7 +508,7 @@ void vUpdateIFS(void *pDeviceHandler) else {// PK_TYPE_11GA & PK_TYPE_11GB BYTE byRate = 0; BOOL bOFDMRate = FALSE; - UINT ii = 0; + unsigned int ii = 0; PWLAN_IE_SUPP_RATES pItemRates = NULL; pDevice->uSIFS = C_SIFS_BG; @@ -806,9 +806,9 @@ BOOL CARDbClearCurrentTSF(void *pDeviceHandler) QWORD CARDqGetNextTBTT (QWORD qwTSF, WORD wBeaconInterval) { - UINT uLowNextTBTT; - UINT uHighRemain, uLowRemain; - UINT uBeaconInterval; + unsigned int uLowNextTBTT; + unsigned int uHighRemain, uLowRemain; + unsigned int uBeaconInterval; uBeaconInterval = wBeaconInterval * 1024; // Next TBTT = ((local_current_TSF / beacon_interval) + 1 ) * beacon_interval diff --git a/drivers/staging/vt6656/card.h b/drivers/staging/vt6656/card.h index 963c8ad3d2ee..6c91343d0d14 100644 --- a/drivers/staging/vt6656/card.h +++ b/drivers/staging/vt6656/card.h @@ -60,7 +60,8 @@ typedef enum _CARD_OP_MODE { /*--------------------- Export Functions --------------------------*/ -BOOL CARDbSetMediaChannel(void *pDeviceHandler, UINT uConnectionChannel); +BOOL CARDbSetMediaChannel(void *pDeviceHandler, + unsigned int uConnectionChannel); void CARDvSetRSPINF(void *pDeviceHandler, BYTE byBBType); void vUpdateIFS(void *pDeviceHandler); void CARDvUpdateBasicTopRate(void *pDeviceHandler); diff --git a/drivers/staging/vt6656/channel.c b/drivers/staging/vt6656/channel.c index c9b8b19a1f7b..f49b6e133394 100644 --- a/drivers/staging/vt6656/channel.c +++ b/drivers/staging/vt6656/channel.c @@ -389,7 +389,7 @@ static struct // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56) ************************************************************************/ BOOL -ChannelValid(UINT CountryCode, UINT ChannelIndex) +ChannelValid(unsigned int CountryCode, unsigned int ChannelIndex) { BOOL bValid; @@ -425,7 +425,7 @@ exit: ************************************************************************/ BOOL CHvChannelGetList ( - UINT uCountryCodeIdx, + unsigned int uCountryCodeIdx, PBYTE pbyChannelTable ) { @@ -441,7 +441,7 @@ void CHvInitChannelTable(void *pDeviceHandler) { PSDevice pDevice = (PSDevice) pDeviceHandler; BOOL bMultiBand = FALSE; - UINT ii; + unsigned int ii; for(ii=1;ii<=CB_MAX_CHANNEL;ii++) { sChannelTbl[ii].bValid = FALSE; diff --git a/drivers/staging/vt6656/channel.h b/drivers/staging/vt6656/channel.h index 26d12a0c6db8..91c2ffc6f1f0 100644 --- a/drivers/staging/vt6656/channel.h +++ b/drivers/staging/vt6656/channel.h @@ -37,20 +37,20 @@ /*--------------------- Export Classes ----------------------------*/ typedef struct tagSChannelTblElement { BYTE byChannelNumber; - UINT uFrequency; + unsigned int uFrequency; BOOL bValid; }SChannelTblElement, *PSChannelTblElement; /*--------------------- Export Variables --------------------------*/ /*--------------------- Export Functions --------------------------*/ -BOOL ChannelValid(UINT CountryCode, UINT ChannelNum); +BOOL ChannelValid(unsigned int CountryCode, unsigned int ChannelNum); void CHvInitChannelTable(void *pDeviceHandler); BYTE CHbyGetChannelMapping(BYTE byChannelNumber); BOOL CHvChannelGetList ( - UINT uCountryCodeIdx, + unsigned int uCountryCodeIdx, PBYTE pbyChannelTable ); diff --git a/drivers/staging/vt6656/datarate.c b/drivers/staging/vt6656/datarate.c index 4d2880b8d839..2e183ddbfd0e 100644 --- a/drivers/staging/vt6656/datarate.c +++ b/drivers/staging/vt6656/datarate.c @@ -201,11 +201,11 @@ void RATEvParseMaxRate( ) { PSDevice pDevice = (PSDevice) pDeviceHandler; -UINT ii; +unsigned int ii; BYTE byHighSuppRate = 0; BYTE byRate = 0; WORD wOldBasicRate = pDevice->wBasicRate; -UINT uRateLen; +unsigned int uRateLen; if (pItemRates == NULL) @@ -241,7 +241,7 @@ UINT uRateLen; if ((pItemExtRates != NULL) && (pItemExtRates->byElementID == WLAN_EID_EXTSUPP_RATES) && (pDevice->byBBType != BB_TYPE_11B)) { - UINT uExtRateLen = pItemExtRates->len; + unsigned int uExtRateLen = pItemExtRates->len; if (uExtRateLen > WLAN_RATES_MAXLEN) uExtRateLen = WLAN_RATES_MAXLEN; @@ -311,7 +311,7 @@ PSDevice pDevice = (PSDevice) pDeviceHandler; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); #if 1 //mike fixed old: use packet lose ratio algorithm to control rate WORD wIdxDownRate = 0; -UINT ii; +unsigned int ii; BOOL bAutoRate[MAX_RATE] = {TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE}; DWORD dwThroughputTbl[MAX_RATE] = {10, 20, 55, 110, 60, 90, 120, 180, 240, 360, 480, 540}; DWORD dwThroughput = 0; @@ -392,7 +392,7 @@ DWORD dwTxDiff = 0; #else //mike fixed new: use differ-signal strength to control rate WORD wIdxUpRate = 0; BOOL bAutoRate[MAX_RATE] = {TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE}; -UINT ii; +unsigned int ii; long ldBm; if (pMgmt->eScanState != WMAC_NO_SCANNING) { @@ -468,10 +468,10 @@ BYTE RATEuSetIE ( PWLAN_IE_SUPP_RATES pSrcRates, PWLAN_IE_SUPP_RATES pDstRates, - UINT uRateLen + unsigned int uRateLen ) { - UINT ii, uu, uRateCnt = 0; + unsigned int ii, uu, uRateCnt = 0; if ((pSrcRates == NULL) || (pDstRates == NULL)) return 0; diff --git a/drivers/staging/vt6656/datarate.h b/drivers/staging/vt6656/datarate.h index 7d73a3a53bea..c6f5163ff9b8 100644 --- a/drivers/staging/vt6656/datarate.h +++ b/drivers/staging/vt6656/datarate.h @@ -92,7 +92,7 @@ BYTE RATEuSetIE( PWLAN_IE_SUPP_RATES pSrcRates, PWLAN_IE_SUPP_RATES pDstRates, - UINT uRateLen + unsigned int uRateLen ); WORD diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index eb45ee597644..ef9fd97d3ca7 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -225,12 +225,12 @@ typedef struct _USB_SEND_CONTEXT { void *pDevice; struct sk_buff *pPacket; struct urb *pUrb; - UINT uBufLen; + unsigned int uBufLen; CONTEXT_TYPE Type; SEthernetHeader sEthHeader; void *Next; BOOL bBoolInUse; - UCHAR Data[MAX_TOTAL_SIZE_WITH_ALL_HEADERS]; + unsigned char Data[MAX_TOTAL_SIZE_WITH_ALL_HEADERS]; } USB_SEND_CONTEXT, *PUSB_SEND_CONTEXT; @@ -248,7 +248,7 @@ typedef struct _DEFAULT_CONFIG { // Structure to keep track of usb interrupt packets // typedef struct { - UINT uDataLen; + unsigned int uDataLen; PBYTE pDataBuf; // struct urb *pUrb; BOOL bInUse; @@ -295,7 +295,7 @@ typedef enum __DEVICE_NDIS_STATUS { #define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 // PMKID Structures -typedef UCHAR NDIS_802_11_PMKID_VALUE[16]; +typedef unsigned char NDIS_802_11_PMKID_VALUE[16]; typedef enum _NDIS_802_11_WEP_STATUS @@ -327,7 +327,7 @@ typedef enum _NDIS_802_11_STATUS_TYPE //Added new types for PMKID Candidate lists. typedef struct _PMKID_CANDIDATE { NDIS_802_11_MAC_ADDRESS BSSID; - ULONG Flags; + unsigned long Flags; } PMKID_CANDIDATE, *PPMKID_CANDIDATE; @@ -338,15 +338,15 @@ typedef struct _BSSID_INFO } BSSID_INFO, *PBSSID_INFO; typedef struct tagSPMKID { - ULONG Length; - ULONG BSSIDInfoCount; + unsigned long Length; + unsigned long BSSIDInfoCount; BSSID_INFO BSSIDInfo[MAX_BSSIDINFO_4_PMKID]; } SPMKID, *PSPMKID; typedef struct tagSPMKIDCandidateEvent { NDIS_802_11_STATUS_TYPE StatusType; - ULONG Version; // Version of the structure - ULONG NumCandidates; // No. of pmkid candidates + unsigned long Version; /* Version of the structure */ + unsigned long NumCandidates; /* No. of pmkid candidates */ PMKID_CANDIDATE CandidateList[MAX_PMKIDLIST]; } SPMKIDCandidateEvent, *PSPMKIDCandidateEvent; @@ -376,7 +376,7 @@ typedef struct tagSCache{ /* The receive cache is updated circularly. The next entry to be written is * indexed by the "InPtr". */ - UINT uInPtr; // Place to use next + unsigned int uInPtr; /* Place to use next */ SCacheEntry asCacheEntry[DUPLICATE_RX_CACHE_LENGTH]; } SCache, *PSCache; @@ -387,10 +387,10 @@ typedef struct tagSDeFragControlBlock WORD wSequence; WORD wFragNum; BYTE abyAddr2[ETH_ALEN]; - UINT uLifetime; + unsigned int uLifetime; struct sk_buff* skb; PBYTE pbyRxBuffer; - UINT cbFrameLength; + unsigned int cbFrameLength; BOOL bInUse; } SDeFragControlBlock, *PSDeFragControlBlock; @@ -463,14 +463,14 @@ typedef struct __device_info { BYTE byRevId; u32 flags; - ULONG Flags; + unsigned long Flags; SCache sDupRxCache; SDeFragControlBlock sRxDFCB[CB_MAX_RX_FRAG]; - UINT cbDFCB; - UINT cbFreeDFCB; - UINT uCurrentDFCBIdx; + unsigned int cbDFCB; + unsigned int cbFreeDFCB; + unsigned int uCurrentDFCBIdx; // +++USB @@ -478,29 +478,29 @@ typedef struct __device_info { struct urb *pInterruptURB; struct usb_ctrlrequest sUsbCtlRequest; - UINT int_interval; + unsigned int int_interval; // // Variables to track resources for the BULK In Pipe // PRCB pRCBMem; PRCB apRCB[CB_MAX_RX_DESC]; - UINT cbRD; + unsigned int cbRD; PRCB FirstRecvFreeList; PRCB LastRecvFreeList; - UINT NumRecvFreeList; + unsigned int NumRecvFreeList; PRCB FirstRecvMngList; PRCB LastRecvMngList; - UINT NumRecvMngList; + unsigned int NumRecvMngList; BOOL bIsRxWorkItemQueued; BOOL bIsRxMngWorkItemQueued; - ULONG ulRcvRefCount; // number of packets that have not been returned back + unsigned long ulRcvRefCount; /* packets that have not returned back */ // // Variables to track resources for the BULK Out Pipe // PUSB_SEND_CONTEXT apTD[CB_MAX_TX_DESC]; - UINT cbTD; + unsigned int cbTD; // // Variables to track resources for the Interript In Pipe @@ -517,20 +517,20 @@ typedef struct __device_info { // // Statistic for USB // protect with spinlock - ULONG ulBulkInPosted; - ULONG ulBulkInError; - ULONG ulBulkInContCRCError; - ULONG ulBulkInBytesRead; + unsigned long ulBulkInPosted; + unsigned long ulBulkInError; + unsigned long ulBulkInContCRCError; + unsigned long ulBulkInBytesRead; - ULONG ulBulkOutPosted; - ULONG ulBulkOutError; - ULONG ulBulkOutContCRCError; - ULONG ulBulkOutBytesWrite; + unsigned long ulBulkOutPosted; + unsigned long ulBulkOutError; + unsigned long ulBulkOutContCRCError; + unsigned long ulBulkOutBytesWrite; - ULONG ulIntInPosted; - ULONG ulIntInError; - ULONG ulIntInContCRCError; - ULONG ulIntInBytesRead; + unsigned long ulIntInPosted; + unsigned long ulIntInError; + unsigned long ulIntInContCRCError; + unsigned long ulIntInBytesRead; // Version control @@ -560,24 +560,24 @@ typedef struct __device_info { // // Maintain statistical debug info. // - ULONG packetsReceived; - ULONG packetsReceivedDropped; - ULONG packetsReceivedOverflow; - ULONG packetsSent; - ULONG packetsSentDropped; - ULONG SendContextsInUse; - ULONG RcvBuffersInUse; + unsigned long packetsReceived; + unsigned long packetsReceivedDropped; + unsigned long packetsReceivedOverflow; + unsigned long packetsSent; + unsigned long packetsSentDropped; + unsigned long SendContextsInUse; + unsigned long RcvBuffersInUse; // 802.11 management SMgmtObject sMgmtObj; QWORD qwCurrTSF; - UINT cbBulkInMax; + unsigned int cbBulkInMax; BOOL bPSRxBeacon; // 802.11 MAC specific - UINT uCurrRSSI; + unsigned int uCurrRSSI; BYTE byCurrSQ; @@ -598,30 +598,31 @@ typedef struct __device_info { BOOL bDiversityRegCtlON; BOOL bDiversityEnable; - ULONG ulDiversityNValue; - ULONG ulDiversityMValue; + unsigned long ulDiversityNValue; + unsigned long ulDiversityMValue; BYTE byTMax; BYTE byTMax2; BYTE byTMax3; - ULONG ulSQ3TH; + unsigned long ulSQ3TH; - ULONG uDiversityCnt; + unsigned long uDiversityCnt; BYTE byAntennaState; - ULONG ulRatio_State0; - ULONG ulRatio_State1; - ULONG ulSQ3_State0; - ULONG ulSQ3_State1; - - ULONG aulSQ3Val[MAX_RATE]; - ULONG aulPktNum[MAX_RATE]; - - // IFS & Cw - UINT uSIFS; //Current SIFS - UINT uDIFS; //Current DIFS - UINT uEIFS; //Current EIFS - UINT uSlot; //Current SlotTime - UINT uCwMin; //Current CwMin - UINT uCwMax; //CwMax is fixed on 1023. + unsigned long ulRatio_State0; + unsigned long ulRatio_State1; + unsigned long ulSQ3_State0; + unsigned long ulSQ3_State1; + + unsigned long aulSQ3Val[MAX_RATE]; + unsigned long aulPktNum[MAX_RATE]; + + /* IFS & Cw */ + unsigned int uSIFS; /* Current SIFS */ + unsigned int uDIFS; /* Current DIFS */ + unsigned int uEIFS; /* Current EIFS */ + unsigned int uSlot; /* Current SlotTime */ + unsigned int uCwMin; /* Current CwMin */ + unsigned int uCwMax; /* CwMax is fixed on 1023 */ + // PHY parameter BYTE bySIFS; BYTE byDIFS; @@ -646,7 +647,7 @@ typedef struct __device_info { BYTE byMinChannel; BYTE byMaxChannel; - UINT uConnectionRate; + unsigned int uConnectionRate; BYTE byPreambleType; BYTE byShortPreamble; @@ -700,7 +701,7 @@ typedef struct __device_info { WORD wListenInterval; BOOL bPWBitOn; WMAC_POWER_MODE ePSMode; - ULONG ulPSModeWaitTx; + unsigned long ulPSModeWaitTx; BOOL bPSModeTxBurst; // Beacon releated @@ -709,7 +710,7 @@ typedef struct __device_info { BOOL bBeaconSent; BOOL bFixRate; BYTE byCurrentCh; - UINT uScanTime; + unsigned int uScanTime; CMD_STATE eCommandState; @@ -720,15 +721,15 @@ typedef struct __device_info { BOOL bStopBeacon; BOOL bStopDataPkt; BOOL bStopTx0Pkt; - UINT uAutoReConnectTime; - UINT uIsroamingTime; + unsigned int uAutoReConnectTime; + unsigned int uIsroamingTime; // 802.11 counter CMD_ITEM eCmdQueue[CMD_Q_SIZE]; - UINT uCmdDequeueIdx; - UINT uCmdEnqueueIdx; - UINT cbFreeCmdQueue; + unsigned int uCmdDequeueIdx; + unsigned int uCmdEnqueueIdx; + unsigned int cbFreeCmdQueue; BOOL bCmdRunning; BOOL bCmdClear; BOOL bNeedRadioOFF; @@ -740,7 +741,7 @@ typedef struct __device_info { BYTE bSameBSSCurNum; //DavidWang BOOL bRoaming; BOOL b11hEable; - ULONG ulTxPower; + unsigned long ulTxPower; // Encryption NDIS_802_11_WEP_STATUS eEncryptionStatus; @@ -761,11 +762,11 @@ typedef struct __device_info { BOOL bAES; BYTE byCntMeasure; - UINT uKeyLength; + unsigned int uKeyLength; BYTE abyKey[WLAN_WEP232_KEYLEN]; // for AP mode - UINT uAssocCount; + unsigned int uAssocCount; BOOL bMoreData; // QoS @@ -780,7 +781,7 @@ typedef struct __device_info { // For Update BaseBand VGA Gain Offset BOOL bUpdateBBVGA; - UINT uBBVGADiffCount; + unsigned int uBBVGADiffCount; BYTE byBBVGANew; BYTE byBBVGACurrent; BYTE abyBBVGA[BB_VGA_LEVEL]; @@ -812,7 +813,7 @@ typedef struct __device_info { //2007-0115-01by MikeLiu #ifdef TxInSleep struct timer_list sTimerTxData; - ULONG nTxDataTimeCout; + unsigned long nTxDataTimeCout; BOOL fTxDataInSleep; BOOL IsTxDataTrigger; #endif @@ -863,7 +864,7 @@ typedef struct __device_info { struct net_device *apdev; int (*tx_80211)(struct sk_buff *skb, struct net_device *dev); #endif - UINT uChannel; + unsigned int uChannel; struct iw_statistics wstats; // wireless stats BOOL bCommit; @@ -928,7 +929,9 @@ typedef struct __device_info { /*--------------------- Export Functions --------------------------*/ -//BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex); +/* BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, + * unsigned int uNodeIndex); + */ BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF); #endif diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index d9a02ba40d84..9afe76cacef5 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -89,7 +89,7 @@ void s_vProcessRxMACHeader ( PSDevice pDevice, PBYTE pbyRxBufferAddr, - UINT cbPacketSize, + unsigned int cbPacketSize, BOOL bIsWEP, BOOL bExtIV, PUINT pcbHeadSize @@ -106,8 +106,8 @@ static BOOL s_bAPModeRxCtl( static BOOL s_bAPModeRxData ( PSDevice pDevice, struct sk_buff *skb, - UINT FrameSize, - UINT cbHeaderOffset, + unsigned int FrameSize, + unsigned int cbHeaderOffset, signed int iSANodeIndex, signed int iDANodeIndex ); @@ -116,7 +116,7 @@ static BOOL s_bAPModeRxData ( static BOOL s_bHandleRxEncryption( PSDevice pDevice, PBYTE pbyFrame, - UINT FrameSize, + unsigned int FrameSize, PBYTE pbyRsr, PBYTE pbyNewRsr, PSKeyItem * pKeyOut, @@ -129,7 +129,7 @@ static BOOL s_bHostWepRxEncryption( PSDevice pDevice, PBYTE pbyFrame, - UINT FrameSize, + unsigned int FrameSize, PBYTE pbyRsr, BOOL bOnFly, PSKeyItem pKey, @@ -164,14 +164,14 @@ void s_vProcessRxMACHeader ( PSDevice pDevice, PBYTE pbyRxBufferAddr, - UINT cbPacketSize, + unsigned int cbPacketSize, BOOL bIsWEP, BOOL bExtIV, PUINT pcbHeadSize ) { PBYTE pbyRxBuffer; - UINT cbHeaderSize = 0; + unsigned int cbHeaderSize = 0; PWORD pwType; PS802_11Header pMACHeader; int ii; @@ -266,7 +266,7 @@ s_vGetDASA ( PSEthernetHeader psEthHeader ) { - UINT cbHeaderSize = 0; + unsigned int cbHeaderSize = 0; PS802_11Header pMACHeader; int ii; @@ -318,7 +318,7 @@ BOOL RXbBulkInProcessData ( PSDevice pDevice, PRCB pRCB, - ULONG BytesToIndicate + unsigned long BytesToIndicate ) { @@ -333,20 +333,20 @@ RXbBulkInProcessData ( PQWORD pqwTSFTime; PBYTE pbyFrame; BOOL bDeFragRx = FALSE; - UINT cbHeaderOffset; - UINT FrameSize; + unsigned int cbHeaderOffset; + unsigned int FrameSize; WORD wEtherType = 0; signed int iSANodeIndex = -1; signed int iDANodeIndex = -1; - UINT ii; - UINT cbIVOffset; + unsigned int ii; + unsigned int cbIVOffset; PBYTE pbyRxSts; PBYTE pbyRxRate; PBYTE pbySQ; #ifdef Calcu_LinkQual PBYTE pby3SQ; #endif - UINT cbHeaderSize; + unsigned int cbHeaderSize; PSKeyItem pKey = NULL; WORD wRxTSC15_0 = 0; DWORD dwRxTSC47_16 = 0; @@ -372,7 +372,7 @@ RXbBulkInProcessData ( //[31:16]RcvByteCount ( not include 4-byte Status ) dwWbkStatus = *( (PDWORD)(skb->data) ); - FrameSize = (UINT)(dwWbkStatus >> 16); + FrameSize = (unsigned int)(dwWbkStatus >> 16); FrameSize += 4; if (BytesToIndicate != FrameSize) { @@ -934,9 +934,9 @@ RXbBulkInProcessData ( if (bIsWEP) { WORD wLocalTSC15_0 = 0; DWORD dwLocalTSC47_16 = 0; - ULONGLONG RSC = 0; + unsigned long long RSC = 0; // endian issues - RSC = *((ULONGLONG *) &(pKey->KeyRSC)); + RSC = *((unsigned long long *) &(pKey->KeyRSC)); wLocalTSC15_0 = (WORD) RSC; dwLocalTSC47_16 = (DWORD) (RSC>>16); @@ -1151,7 +1151,7 @@ static BOOL s_bAPModeRxCtl ( static BOOL s_bHandleRxEncryption ( PSDevice pDevice, PBYTE pbyFrame, - UINT FrameSize, + unsigned int FrameSize, PBYTE pbyRsr, PBYTE pbyNewRsr, PSKeyItem * pKeyOut, @@ -1160,7 +1160,7 @@ static BOOL s_bHandleRxEncryption ( PDWORD pdwRxTSC47_16 ) { - UINT PayloadLen = FrameSize; + unsigned int PayloadLen = FrameSize; PBYTE pbyIV; BYTE byKeyIdx; PSKeyItem pKey = NULL; @@ -1297,7 +1297,7 @@ static BOOL s_bHandleRxEncryption ( static BOOL s_bHostWepRxEncryption ( PSDevice pDevice, PBYTE pbyFrame, - UINT FrameSize, + unsigned int FrameSize, PBYTE pbyRsr, BOOL bOnFly, PSKeyItem pKey, @@ -1308,7 +1308,7 @@ static BOOL s_bHostWepRxEncryption ( ) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - UINT PayloadLen = FrameSize; + unsigned int PayloadLen = FrameSize; PBYTE pbyIV; BYTE byKeyIdx; BYTE byDecMode = KEY_CTL_WEP; @@ -1429,8 +1429,8 @@ static BOOL s_bHostWepRxEncryption ( static BOOL s_bAPModeRxData ( PSDevice pDevice, struct sk_buff *skb, - UINT FrameSize, - UINT cbHeaderOffset, + unsigned int FrameSize, + unsigned int cbHeaderOffset, signed int iSANodeIndex, signed int iDANodeIndex ) @@ -1503,7 +1503,8 @@ static BOOL s_bAPModeRxData ( iDANodeIndex = 0; if ((pDevice->uAssocCount > 1) && (iDANodeIndex >= 0)) { - bRelayPacketSend(pDevice, (PBYTE)(skb->data + cbHeaderOffset), FrameSize, (UINT)iDANodeIndex); + bRelayPacketSend(pDevice, (PBYTE) (skb->data + cbHeaderOffset), + FrameSize, (unsigned int) iDANodeIndex); } if (bRelayOnly) diff --git a/drivers/staging/vt6656/dpc.h b/drivers/staging/vt6656/dpc.h index 7ea3ad973417..d4fca43af4fe 100644 --- a/drivers/staging/vt6656/dpc.h +++ b/drivers/staging/vt6656/dpc.h @@ -55,7 +55,7 @@ BOOL RXbBulkInProcessData( PSDevice pDevice, PRCB pRCB, - ULONG BytesToIndicate + unsigned long BytesToIndicate ); #endif /* __RXTX_H__ */ diff --git a/drivers/staging/vt6656/hostap.c b/drivers/staging/vt6656/hostap.c index 93e52a3ebd85..f70e922a615b 100644 --- a/drivers/staging/vt6656/hostap.c +++ b/drivers/staging/vt6656/hostap.c @@ -210,7 +210,7 @@ int vt6656_hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked) static int hostap_remove_sta(PSDevice pDevice, struct viawget_hostapd_param *param) { - UINT uNodeIndex; + unsigned int uNodeIndex; if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) { @@ -239,7 +239,7 @@ static int hostap_add_sta(PSDevice pDevice, struct viawget_hostapd_param *param) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - UINT uNodeIndex; + unsigned int uNodeIndex; if (!BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) { @@ -299,7 +299,7 @@ static int hostap_get_info_sta(PSDevice pDevice, struct viawget_hostapd_param *param) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - UINT uNodeIndex; + unsigned int uNodeIndex; if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) { param->u.get_info_sta.inactive_sec = @@ -333,7 +333,7 @@ static int hostap_reset_txexc_sta(PSDevice pDevice, struct viawget_hostapd_param *param) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - UINT uNodeIndex; + unsigned int uNodeIndex; if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) { pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts = 0; @@ -363,13 +363,13 @@ static int hostap_set_flags_sta(PSDevice pDevice, struct viawget_hostapd_param *param) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - UINT uNodeIndex; + unsigned int uNodeIndex; if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) { pMgmt->sNodeDBTable[uNodeIndex].dwFlags |= param->u.set_flags_sta.flags_or; pMgmt->sNodeDBTable[uNodeIndex].dwFlags &= param->u.set_flags_sta.flags_and; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " dwFlags = %x \n", - (UINT)pMgmt->sNodeDBTable[uNodeIndex].dwFlags); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " dwFlags = %x\n", + (unsigned int) pMgmt->sNodeDBTable[uNodeIndex].dwFlags); } else { return -ENOENT; diff --git a/drivers/staging/vt6656/ioctl.c b/drivers/staging/vt6656/ioctl.c index 368e49f782fc..19a84b66b097 100644 --- a/drivers/staging/vt6656/ioctl.c +++ b/drivers/staging/vt6656/ioctl.c @@ -72,10 +72,10 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) { SNodeList sNodeList; PSBSSIDList pList; PSNodeList pNodeList; - UINT cbListCount; + unsigned int cbListCount; PKnownBSS pBSS; PKnownNodeDB pNode; - UINT ii, jj; + unsigned int ii, jj; SCmdLinkStatus sLinkStatus; BYTE abySuppRates[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16}; BYTE abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; @@ -337,7 +337,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) { pList->sBSSIDList[ii].wBeaconInterval = pBSS->wBeaconInterval; pList->sBSSIDList[ii].wCapInfo = pBSS->wCapInfo; RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm); - pList->sBSSIDList[ii].uRSSI = (UINT)ldBm; + pList->sBSSIDList[ii].uRSSI = (unsigned int) ldBm; // pList->sBSSIDList[ii].uRSSI = pBSS->uRSSI; memcpy(pList->sBSSIDList[ii].abyBSSID, pBSS->abyBSSID, WLAN_BSSID_LEN); pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; diff --git a/drivers/staging/vt6656/ioctl.h b/drivers/staging/vt6656/ioctl.h index b307980999e9..caa4ac963d93 100644 --- a/drivers/staging/vt6656/ioctl.h +++ b/drivers/staging/vt6656/ioctl.h @@ -47,7 +47,7 @@ void vConfigWEPKey ( PSDevice pDevice, DWORD dwKeyIndex, PBYTE pbyKey, - ULONG uKeyLength + unsigned long uKeyLength ); */ diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 4d0db21b1b98..fa40522d4a9a 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -769,7 +769,7 @@ int iwctl_siwap(struct net_device *dev, //mike add: if desired AP is hidden ssid(there are two same BSSID in list), // then ignore,because you don't known which one to be connect with?? { - UINT ii , uSameBssidNum=0; + unsigned int ii, uSameBssidNum = 0; for (ii = 0; ii < MAX_BSS_NUM; ii++) { if (pMgmt->sBSSList[ii].bActive && IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID,pMgmt->abyDesireBSSID)) { @@ -933,7 +933,7 @@ int iwctl_siwessid(struct net_device *dev, { PKnownBSS pCurr = NULL; BYTE abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; - UINT ii , uSameBssidNum=0; + unsigned int ii, uSameBssidNum = 0; memcpy(abyTmpDesireSSID,pMgmt->abyDesireSSID,sizeof(abyTmpDesireSSID)); pCurr = BSSpSearchBSSList(pDevice, @@ -1440,7 +1440,7 @@ int iwctl_giwencode(struct net_device *dev, PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int rc = 0; char abyKey[WLAN_WEP232_KEYLEN]; - UINT index = (UINT)(wrq->flags & IW_ENCODE_INDEX); + unsigned int index = (unsigned int)(wrq->flags & IW_ENCODE_INDEX); PSKeyItem pKey = NULL; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n"); @@ -1486,7 +1486,7 @@ int iwctl_giwencode(struct net_device *dev, PSMgmtObject pMgmt = &(pDevice->sMgmtObj); char abyKey[WLAN_WEP232_KEYLEN]; - UINT index = (UINT)(wrq->flags & IW_ENCODE_INDEX); + unsigned int index = (unsigned int)(wrq->flags & IW_ENCODE_INDEX); PSKeyItem pKey = NULL; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n"); diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c index 7ff420d07c18..b0890c181e7d 100644 --- a/drivers/staging/vt6656/key.c +++ b/drivers/staging/vt6656/key.c @@ -223,7 +223,7 @@ BOOL KeybSetKey( PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyIndex, - ULONG uKeyLength, + unsigned long uKeyLength, PQWORD pKeyRSC, PBYTE pbyKey, BYTE byKeyDecMode @@ -231,9 +231,9 @@ BOOL KeybSetKey( { PSDevice pDevice = (PSDevice) pDeviceHandler; int i,j; - UINT ii; + unsigned int ii; PSKeyItem pKey; - UINT uKeyIdx; + unsigned int uKeyIdx; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetKey: %lX\n", dwKeyIndex); @@ -670,19 +670,19 @@ BOOL KeybSetDefaultKey( void *pDeviceHandler, PSKeyManagement pTable, DWORD dwKeyIndex, - ULONG uKeyLength, + unsigned long uKeyLength, PQWORD pKeyRSC, PBYTE pbyKey, BYTE byKeyDecMode ) { PSDevice pDevice = (PSDevice) pDeviceHandler; - UINT ii; + unsigned int ii; PSKeyItem pKey; - UINT uKeyIdx; - - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetDefaultKey: %1x, %d \n", (int)dwKeyIndex, (int)uKeyLength); + unsigned int uKeyIdx; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enter KeybSetDefaultKey: %1x, %d\n", + (int) dwKeyIndex, (int) uKeyLength); if ((dwKeyIndex & PAIRWISE_KEY) != 0) { // Pairwise key return (FALSE); @@ -778,7 +778,7 @@ BOOL KeybSetAllGroupKey( void *pDeviceHandler, PSKeyManagement pTable, DWORD dwKeyIndex, - ULONG uKeyLength, + unsigned long uKeyLength, PQWORD pKeyRSC, PBYTE pbyKey, BYTE byKeyDecMode @@ -786,9 +786,9 @@ BOOL KeybSetAllGroupKey( { PSDevice pDevice = (PSDevice) pDeviceHandler; int i; - UINT ii; + unsigned int ii; PSKeyItem pKey; - UINT uKeyIdx; + unsigned int uKeyIdx; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetAllGroupKey: %lX\n", dwKeyIndex); diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h index 11fc41edd094..f749c7a027d3 100644 --- a/drivers/staging/vt6656/key.h +++ b/drivers/staging/vt6656/key.h @@ -58,7 +58,7 @@ typedef struct tagSKeyItem { BOOL bKeyValid; - ULONG uKeyLength; + unsigned long uKeyLength; BYTE abyKey[MAX_KEY_LEN]; QWORD KeyRSC; DWORD dwTSC47_16; @@ -107,7 +107,7 @@ BOOL KeybSetKey( PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyIndex, - ULONG uKeyLength, + unsigned long uKeyLength, PQWORD pKeyRSC, PBYTE pbyKey, BYTE byKeyDecMode @@ -146,7 +146,7 @@ BOOL KeybSetDefaultKey( void *pDeviceHandler, PSKeyManagement pTable, DWORD dwKeyIndex, - ULONG uKeyLength, + unsigned long uKeyLength, PQWORD pKeyRSC, PBYTE pbyKey, BYTE byKeyDecMode @@ -156,7 +156,7 @@ BOOL KeybSetAllGroupKey( void *pDeviceHandler, PSKeyManagement pTable, DWORD dwKeyIndex, - ULONG uKeyLength, + unsigned long uKeyLength, PQWORD pKeyRSC, PBYTE pbyKey, BYTE byKeyDecMode diff --git a/drivers/staging/vt6656/mac.c b/drivers/staging/vt6656/mac.c index 71f09663e65d..0ab3db025f33 100644 --- a/drivers/staging/vt6656/mac.c +++ b/drivers/staging/vt6656/mac.c @@ -70,7 +70,7 @@ static int msglevel =MSG_LEVEL_INFO; */ void MACvSetMultiAddrByHash (PSDevice pDevice, BYTE byHashIdx) { - UINT uByteIdx; + unsigned int uByteIdx; BYTE byBitMask; BYTE pbyData[2]; @@ -110,7 +110,7 @@ void MACvSetMultiAddrByHash (PSDevice pDevice, BYTE byHashIdx) * Return Value: none * */ -void MACvWriteMultiAddr(PSDevice pDevice, UINT uByteIdx, BYTE byData) +void MACvWriteMultiAddr(PSDevice pDevice, unsigned int uByteIdx, BYTE byData) { BYTE byData1; @@ -199,7 +199,7 @@ BYTE pbyData[4]; * Return Value: none * */ -void MACvDisableKeyEntry (PSDevice pDevice, UINT uEntryIdx) +void MACvDisableKeyEntry(PSDevice pDevice, unsigned int uEntryIdx) { WORD wOffset; BYTE byData; @@ -239,7 +239,9 @@ BYTE byData; * Return Value: none * */ -void MACvSetKeyEntry (PSDevice pDevice, WORD wKeyCtl, UINT uEntryIdx, UINT uKeyIdx, PBYTE pbyAddr, PDWORD pdwKey) +void MACvSetKeyEntry(PSDevice pDevice, WORD wKeyCtl, + unsigned int uEntryIdx, unsigned int uKeyIdx, + PBYTE pbyAddr, PDWORD pdwKey) { PBYTE pbyKey; WORD wOffset; @@ -247,10 +249,6 @@ DWORD dwData1,dwData2; int ii; BYTE pbyData[24]; - - - - if ( pDevice->byLocalID <= MAC_REVISION_A1 ) { if ( pDevice->sMgmtObj.byCSSPK == KEY_CTL_CCMP ) return; diff --git a/drivers/staging/vt6656/mac.h b/drivers/staging/vt6656/mac.h index 4e3d11b4a8be..775c70928ec7 100644 --- a/drivers/staging/vt6656/mac.h +++ b/drivers/staging/vt6656/mac.h @@ -421,12 +421,13 @@ /*--------------------- Export Functions --------------------------*/ void MACvSetMultiAddrByHash (PSDevice pDevice, BYTE byHashIdx); -void MACvWriteMultiAddr(PSDevice pDevice, UINT uByteIdx, BYTE byData); +void MACvWriteMultiAddr(PSDevice pDevice, unsigned int uByteIdx, BYTE byData); BOOL MACbShutdown(PSDevice pDevice);; void MACvSetBBType(PSDevice pDevice,BYTE byType); void MACvSetMISCFifo (PSDevice pDevice, WORD wOffset, DWORD dwData); -void MACvDisableKeyEntry(PSDevice pDevice, UINT uEntryIdx); -void MACvSetKeyEntry(PSDevice pDevice, WORD wKeyCtl, UINT uEntryIdx, UINT uKeyIdx, PBYTE pbyAddr, PDWORD pdwKey); +void MACvDisableKeyEntry(PSDevice pDevice, unsigned int uEntryIdx); +void MACvSetKeyEntry(PSDevice pDevice, WORD wKeyCtl, unsigned int uEntryIdx, + unsigned int uKeyIdx, PBYTE pbyAddr, PDWORD pdwKey); void MACvRegBitsOff(PSDevice pDevice, BYTE byRegOfs, BYTE byBits); void MACvRegBitsOn(PSDevice pDevice, BYTE byRegOfs, BYTE byBits); diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index e4dc27dd21e7..4e465c465280 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -277,8 +277,10 @@ static void device_free_frag_bufs(PSDevice pDevice); static BOOL device_alloc_bufs(PSDevice pDevice); static int Read_config_file(PSDevice pDevice); -static UCHAR *Config_FileOperation(PSDevice pDevice); -static int Config_FileGetParameter(UCHAR *string, UCHAR *dest,UCHAR *source); +static unsigned char *Config_FileOperation(PSDevice pDevice); +static int Config_FileGetParameter(unsigned char *string, + unsigned char *dest, + unsigned char *source); //2008-0714by Mike Liu static BOOL device_release_WPADEV(PSDevice pDevice); @@ -334,17 +336,17 @@ device_set_options(PSDevice pDevice) { static void device_init_diversity_timer(PSDevice pDevice) { init_timer(&pDevice->TimerSQ3Tmax1); - pDevice->TimerSQ3Tmax1.data = (ULONG)pDevice; + pDevice->TimerSQ3Tmax1.data = (unsigned long)pDevice; pDevice->TimerSQ3Tmax1.function = (TimerFunction)TimerSQ3CallBack; pDevice->TimerSQ3Tmax1.expires = RUN_AT(HZ); init_timer(&pDevice->TimerSQ3Tmax2); - pDevice->TimerSQ3Tmax2.data = (ULONG)pDevice; + pDevice->TimerSQ3Tmax2.data = (unsigned long)pDevice; pDevice->TimerSQ3Tmax2.function = (TimerFunction)TimerSQ3CallBack; pDevice->TimerSQ3Tmax2.expires = RUN_AT(HZ); init_timer(&pDevice->TimerSQ3Tmax3); - pDevice->TimerSQ3Tmax3.data = (ULONG)pDevice; + pDevice->TimerSQ3Tmax3.data = (unsigned long)pDevice; pDevice->TimerSQ3Tmax3.function = (TimerFunction)TimerSQ3Tmax3CallBack; pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ); @@ -362,7 +364,7 @@ static BOOL device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType) u8 abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; u8 abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8}; BYTE byAntenna; - UINT ii; + unsigned int ii; CMD_CARD_INIT sInitCmd; NTSTATUS ntStatus = STATUS_SUCCESS; RSP_CARD_INIT sInitRsp; @@ -1336,7 +1338,7 @@ device_release_WPADEV(pDevice); static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) { PSDevice pDevice=netdev_priv(dev); PBYTE pbMPDU; - UINT cbMPDULen = 0; + unsigned int cbMPDULen = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211\n"); @@ -1411,24 +1413,27 @@ static inline u32 ether_crc(int length, unsigned char *data) } //find out the start position of str2 from str1 -static UCHAR *kstrstr(const UCHAR *str1,const UCHAR *str2) { - int str1_len=strlen(str1); - int str2_len=strlen(str2); +static unsigned char *kstrstr(const unsigned char *str1, + const unsigned char *str2) { + int str1_len = strlen(str1); + int str2_len = strlen(str2); while (str1_len >= str2_len) { str1_len--; if(memcmp(str1,str2,str2_len)==0) - return (UCHAR *)str1; + return (unsigned char *) str1; str1++; } return NULL; } -static int Config_FileGetParameter(UCHAR *string, UCHAR *dest,UCHAR *source) +static int Config_FileGetParameter(unsigned char *string, + unsigned char *dest, + unsigned char *source) { - UCHAR buf1[100]; - UCHAR buf2[100]; - UCHAR *start_p=NULL,*end_p=NULL,*tmp_p=NULL; + unsigned char buf1[100]; + unsigned char buf2[100]; + unsigned char *start_p = NULL, *end_p = NULL, *tmp_p = NULL; int ii; memset(buf1,0,100); @@ -1480,13 +1485,14 @@ for(ii=1;;ii++) { } //if read fail,return NULL,or return data pointer; -static UCHAR *Config_FileOperation(PSDevice pDevice) { - UCHAR *config_path=CONFIG_PATH; - UCHAR *buffer=NULL; +static unsigned char *Config_FileOperation(PSDevice pDevice) +{ + unsigned char *config_path = CONFIG_PATH; + unsigned char *buffer = NULL; struct file *filp=NULL; mm_segment_t old_fs = get_fs(); //int oldfsuid=0,oldfsgid=0; - int result=0; + int result = 0; set_fs (KERNEL_DS); /* Can't do this anymore, so we rely on correct filesystem permissions: @@ -1545,9 +1551,9 @@ if(result!=0) { //return --->-1:fail; >=0:successful static int Read_config_file(PSDevice pDevice) { - int result=0; - UCHAR tmpbuffer[100]; - UCHAR *buffer=NULL; + int result = 0; + unsigned char tmpbuffer[100]; + unsigned char *buffer = NULL; //init config setting pDevice->config_file.ZoneType = -1; diff --git a/drivers/staging/vt6656/mib.c b/drivers/staging/vt6656/mib.c index efcd81c042f2..b694fc86d740 100644 --- a/drivers/staging/vt6656/mib.c +++ b/drivers/staging/vt6656/mib.c @@ -152,9 +152,10 @@ void STAvUpdateIsrStatCounter (PSStatCounter pStatistic, BYTE byIsr0, BYTE byIsr * Return Value: none * */ -void STAvUpdateRDStatCounter (PSStatCounter pStatistic, - BYTE byRSR, BYTE byNewRSR, BYTE byRxSts, BYTE byRxRate, - PBYTE pbyBuffer, UINT cbFrameLength) +void STAvUpdateRDStatCounter(PSStatCounter pStatistic, + BYTE byRSR, BYTE byNewRSR, + BYTE byRxSts, BYTE byRxRate, + PBYTE pbyBuffer, unsigned int cbFrameLength) { /* need change */ PS802_11Header pHeader = (PS802_11Header)pbyBuffer; @@ -169,15 +170,18 @@ void STAvUpdateRDStatCounter (PSStatCounter pStatistic, /* update counters in case of successful transmission */ if (byRSR & RSR_ADDRBROAD) { pStatistic->ullRxBroadcastFrames++; - pStatistic->ullRxBroadcastBytes += (ULONGLONG)cbFrameLength; + pStatistic->ullRxBroadcastBytes += + (unsigned long long) cbFrameLength; } else if (byRSR & RSR_ADDRMULTI) { pStatistic->ullRxMulticastFrames++; - pStatistic->ullRxMulticastBytes += (ULONGLONG)cbFrameLength; + pStatistic->ullRxMulticastBytes += + (unsigned long long) cbFrameLength; } else { pStatistic->ullRxDirectedFrames++; - pStatistic->ullRxDirectedBytes += (ULONGLONG)cbFrameLength; + pStatistic->ullRxDirectedBytes += + (unsigned long long) cbFrameLength; } } } @@ -396,7 +400,7 @@ STAvUpdateRDStatCounterEx ( BYTE byRxSts, BYTE byRxRate, PBYTE pbyBuffer, - UINT cbFrameLength + unsigned int cbFrameLength ) { STAvUpdateRDStatCounter( @@ -536,19 +540,22 @@ STAvUpdate802_11Counter( ) { //p802_11Counter->TransmittedFragmentCount - p802_11Counter->MulticastTransmittedFrameCount = (ULONGLONG) (pStatistic->dwTsrBroadcast + - pStatistic->dwTsrMulticast); - p802_11Counter->FailedCount = (ULONGLONG) (pStatistic->dwTsrErr); - p802_11Counter->RetryCount = (ULONGLONG) (pStatistic->dwTsrRetry); - p802_11Counter->MultipleRetryCount = (ULONGLONG) (pStatistic->dwTsrMoreThanOnceRetry); + p802_11Counter->MulticastTransmittedFrameCount = + (unsigned long long) (pStatistic->dwTsrBroadcast + + pStatistic->dwTsrMulticast); + p802_11Counter->FailedCount = (unsigned long long) (pStatistic->dwTsrErr); + p802_11Counter->RetryCount = (unsigned long long) (pStatistic->dwTsrRetry); + p802_11Counter->MultipleRetryCount = + (unsigned long long) (pStatistic->dwTsrMoreThanOnceRetry); //p802_11Counter->FrameDuplicateCount - p802_11Counter->RTSSuccessCount += (ULONGLONG) byRTSSuccess; - p802_11Counter->RTSFailureCount += (ULONGLONG) byRTSFail; - p802_11Counter->ACKFailureCount += (ULONGLONG) byACKFail; - p802_11Counter->FCSErrorCount += (ULONGLONG) byFCSErr; + p802_11Counter->RTSSuccessCount += (unsigned long long) byRTSSuccess; + p802_11Counter->RTSFailureCount += (unsigned long long) byRTSFail; + p802_11Counter->ACKFailureCount += (unsigned long long) byACKFail; + p802_11Counter->FCSErrorCount += (unsigned long long) byFCSErr; //p802_11Counter->ReceivedFragmentCount - p802_11Counter->MulticastReceivedFrameCount = (ULONGLONG) (pStatistic->dwRsrBroadcast + - pStatistic->dwRsrMulticast); + p802_11Counter->MulticastReceivedFrameCount = + (unsigned long long) (pStatistic->dwRsrBroadcast + + pStatistic->dwRsrMulticast); } /* diff --git a/drivers/staging/vt6656/mib.h b/drivers/staging/vt6656/mib.h index 8cc5b3f0d70e..0455ec9d327d 100644 --- a/drivers/staging/vt6656/mib.h +++ b/drivers/staging/vt6656/mib.h @@ -52,32 +52,34 @@ typedef struct tagSUSBCounter { typedef struct tagSDot11Counters { -// ULONG Length; // Length of structure - ULONGLONG TransmittedFragmentCount; - ULONGLONG MulticastTransmittedFrameCount; - ULONGLONG FailedCount; - ULONGLONG RetryCount; - ULONGLONG MultipleRetryCount; - ULONGLONG RTSSuccessCount; - ULONGLONG RTSFailureCount; - ULONGLONG ACKFailureCount; - ULONGLONG FrameDuplicateCount; - ULONGLONG ReceivedFragmentCount; - ULONGLONG MulticastReceivedFrameCount; - ULONGLONG FCSErrorCount; - ULONGLONG TKIPLocalMICFailures; - ULONGLONG TKIPRemoteMICFailures; - ULONGLONG TKIPICVErrors; - ULONGLONG TKIPCounterMeasuresInvoked; - ULONGLONG TKIPReplays; - ULONGLONG CCMPFormatErrors; - ULONGLONG CCMPReplays; - ULONGLONG CCMPDecryptErrors; - ULONGLONG FourWayHandshakeFailures; -// ULONGLONG WEPUndecryptableCount; -// ULONGLONG WEPICVErrorCount; -// ULONGLONG DecryptSuccessCount; -// ULONGLONG DecryptFailureCount; + /* unsigned long Length; // Length of structure */ + unsigned long long TransmittedFragmentCount; + unsigned long long MulticastTransmittedFrameCount; + unsigned long long FailedCount; + unsigned long long RetryCount; + unsigned long long MultipleRetryCount; + unsigned long long RTSSuccessCount; + unsigned long long RTSFailureCount; + unsigned long long ACKFailureCount; + unsigned long long FrameDuplicateCount; + unsigned long long ReceivedFragmentCount; + unsigned long long MulticastReceivedFrameCount; + unsigned long long FCSErrorCount; + unsigned long long TKIPLocalMICFailures; + unsigned long long TKIPRemoteMICFailures; + unsigned long long TKIPICVErrors; + unsigned long long TKIPCounterMeasuresInvoked; + unsigned long long TKIPReplays; + unsigned long long CCMPFormatErrors; + unsigned long long CCMPReplays; + unsigned long long CCMPDecryptErrors; + unsigned long long FourWayHandshakeFailures; + /* + * unsigned long long WEPUndecryptableCount; + * unsigned long long WEPICVErrorCount; + * unsigned long long DecryptSuccessCount; + * unsigned long long DecryptFailureCount; + */ } SDot11Counters, *PSDot11Counters; @@ -151,37 +153,37 @@ typedef struct tagSRmonCounter { // Custom counter // typedef struct tagSCustomCounters { - ULONG Length; - - ULONGLONG ullTsrAllOK; - - ULONGLONG ullRsr11M; - ULONGLONG ullRsr5M; - ULONGLONG ullRsr2M; - ULONGLONG ullRsr1M; - - ULONGLONG ullRsr11MCRCOk; - ULONGLONG ullRsr5MCRCOk; - ULONGLONG ullRsr2MCRCOk; - ULONGLONG ullRsr1MCRCOk; - - ULONGLONG ullRsr54M; - ULONGLONG ullRsr48M; - ULONGLONG ullRsr36M; - ULONGLONG ullRsr24M; - ULONGLONG ullRsr18M; - ULONGLONG ullRsr12M; - ULONGLONG ullRsr9M; - ULONGLONG ullRsr6M; - - ULONGLONG ullRsr54MCRCOk; - ULONGLONG ullRsr48MCRCOk; - ULONGLONG ullRsr36MCRCOk; - ULONGLONG ullRsr24MCRCOk; - ULONGLONG ullRsr18MCRCOk; - ULONGLONG ullRsr12MCRCOk; - ULONGLONG ullRsr9MCRCOk; - ULONGLONG ullRsr6MCRCOk; + unsigned long Length; + + unsigned long long ullTsrAllOK; + + unsigned long long ullRsr11M; + unsigned long long ullRsr5M; + unsigned long long ullRsr2M; + unsigned long long ullRsr1M; + + unsigned long long ullRsr11MCRCOk; + unsigned long long ullRsr5MCRCOk; + unsigned long long ullRsr2MCRCOk; + unsigned long long ullRsr1MCRCOk; + + unsigned long long ullRsr54M; + unsigned long long ullRsr48M; + unsigned long long ullRsr36M; + unsigned long long ullRsr24M; + unsigned long long ullRsr18M; + unsigned long long ullRsr12M; + unsigned long long ullRsr9M; + unsigned long long ullRsr6M; + + unsigned long long ullRsr54MCRCOk; + unsigned long long ullRsr48MCRCOk; + unsigned long long ullRsr36MCRCOk; + unsigned long long ullRsr24MCRCOk; + unsigned long long ullRsr18MCRCOk; + unsigned long long ullRsr12MCRCOk; + unsigned long long ullRsr9MCRCOk; + unsigned long long ullRsr6MCRCOk; } SCustomCounters, *PSCustomCounters; @@ -190,7 +192,7 @@ typedef struct tagSCustomCounters { // Custom counter // typedef struct tagSISRCounters { - ULONG Length; + unsigned long Length; DWORD dwIsrTx0OK; DWORD dwIsrAC0TxOK; @@ -277,15 +279,15 @@ typedef struct tagSStatCounter { DWORD dwRsrMulticast; DWORD dwRsrDirected; // 64-bit OID - ULONGLONG ullRsrOK; + unsigned long long ullRsrOK; // for some optional OIDs (64 bits) and DMI support - ULONGLONG ullRxBroadcastBytes; - ULONGLONG ullRxMulticastBytes; - ULONGLONG ullRxDirectedBytes; - ULONGLONG ullRxBroadcastFrames; - ULONGLONG ullRxMulticastFrames; - ULONGLONG ullRxDirectedFrames; + unsigned long long ullRxBroadcastBytes; + unsigned long long ullRxMulticastBytes; + unsigned long long ullRxDirectedBytes; + unsigned long long ullRxBroadcastFrames; + unsigned long long ullRxMulticastFrames; + unsigned long long ullRxDirectedFrames; DWORD dwRsrRxFragment; DWORD dwRsrRxFrmLen64; @@ -330,15 +332,15 @@ typedef struct tagSStatCounter { // 64-bit OID - ULONGLONG ullTsrOK; + unsigned long long ullTsrOK; // for some optional OIDs (64 bits) and DMI support - ULONGLONG ullTxBroadcastFrames; - ULONGLONG ullTxMulticastFrames; - ULONGLONG ullTxDirectedFrames; - ULONGLONG ullTxBroadcastBytes; - ULONGLONG ullTxMulticastBytes; - ULONGLONG ullTxDirectedBytes; + unsigned long long ullTxBroadcastFrames; + unsigned long long ullTxMulticastFrames; + unsigned long long ullTxDirectedFrames; + unsigned long long ullTxBroadcastBytes; + unsigned long long ullTxMulticastBytes; + unsigned long long ullTxDirectedBytes; // for autorate DWORD dwTxOk[MAX_RATE+1]; @@ -356,15 +358,15 @@ typedef struct tagSStatCounter { #ifdef Calcu_LinkQual //Tx count: - ULONG TxNoRetryOkCount; //success tx no retry ! - ULONG TxRetryOkCount; //success tx but retry ! - ULONG TxFailCount; //fail tx ? + unsigned long TxNoRetryOkCount; /* success tx no retry ! */ + unsigned long TxRetryOkCount; /* success tx but retry ! */ + unsigned long TxFailCount; /* fail tx ? */ //Rx count: - ULONG RxOkCnt; //success rx ! - ULONG RxFcsErrCnt; //fail rx ? + unsigned long RxOkCnt; /* success rx ! */ + unsigned long RxFcsErrCnt; /* fail rx ? */ //statistic - ULONG SignalStren; - ULONG LinkQuality; + unsigned long SignalStren; + unsigned long LinkQuality; #endif } SStatCounter, *PSStatCounter; @@ -382,13 +384,14 @@ void STAvClearAllCounter(PSStatCounter pStatistic); void STAvUpdateIsrStatCounter (PSStatCounter pStatistic, BYTE byIsr0, BYTE byIsr1); void STAvUpdateRDStatCounter(PSStatCounter pStatistic, - BYTE byRSR, BYTE byNewRSR, BYTE byRxSts, BYTE byRxRate, - PBYTE pbyBuffer, UINT cbFrameLength); + BYTE byRSR, BYTE byNewRSR, BYTE byRxSts, + BYTE byRxRate, PBYTE pbyBuffer, + unsigned int cbFrameLength); void STAvUpdateRDStatCounterEx(PSStatCounter pStatistic, - BYTE byRSR, BYTE byNewRSR, BYTE byRxSts, BYTE byRxRate, - PBYTE pbyBuffer, UINT cbFrameLength); - + BYTE byRSR, BYTE byNewRSR, BYTE byRxSts, + BYTE byRxRate, PBYTE pbyBuffer, + unsigned int cbFrameLength); void STAvUpdateTDStatCounter ( diff --git a/drivers/staging/vt6656/michael.c b/drivers/staging/vt6656/michael.c index d45333fc2420..671a8cf33e23 100644 --- a/drivers/staging/vt6656/michael.c +++ b/drivers/staging/vt6656/michael.c @@ -64,7 +64,7 @@ static void s_vAppendByte(BYTE b); /* Add a single byte to the internal static DWORD L, R; /* Current state */ static DWORD K0, K1; /* Key */ static DWORD M; /* Message accumulator (single word) */ -static UINT nBytesInM; /* # bytes in M */ +static unsigned int nBytesInM; /* # bytes in M */ /*--------------------- Export Functions --------------------------*/ @@ -73,7 +73,7 @@ static DWORD s_dwGetUINT32 (BYTE * p) // Convert from BYTE[] to DWORD in a portable way { DWORD res = 0; - UINT i; + unsigned int i; for(i=0; i<4; i++ ) res |= (*p++) << (8*i); return res; @@ -82,7 +82,7 @@ static DWORD s_dwGetUINT32 (BYTE * p) static void s_vPutUINT32(BYTE *p, DWORD val) // Convert from DWORD to BYTE[] in a portable way { - UINT i; + unsigned int i; for(i=0; i<4; i++ ) { *p++ = (BYTE) (val & 0xff); val >>= 8; @@ -148,7 +148,7 @@ void MIC_vUnInit(void) s_vClear(); } -void MIC_vAppend(PBYTE src, UINT nBytes) +void MIC_vAppend(PBYTE src, unsigned int nBytes) { /* This is simple */ while (nBytes > 0) { diff --git a/drivers/staging/vt6656/michael.h b/drivers/staging/vt6656/michael.h index 52270d314a8b..3ab60928ef35 100644 --- a/drivers/staging/vt6656/michael.h +++ b/drivers/staging/vt6656/michael.h @@ -40,7 +40,7 @@ void MIC_vInit(DWORD dwK0, DWORD dwK1); void MIC_vUnInit(void); // Append bytes to the message to be MICed -void MIC_vAppend(PBYTE src, UINT nBytes); +void MIC_vAppend(PBYTE src, unsigned int nBytes); // Get the MIC result. Destination should accept 8 bytes of result. // This also resets the message to empty. diff --git a/drivers/staging/vt6656/rc4.c b/drivers/staging/vt6656/rc4.c index 487f1dcfd8c4..5c3c2d0552b4 100644 --- a/drivers/staging/vt6656/rc4.c +++ b/drivers/staging/vt6656/rc4.c @@ -32,13 +32,13 @@ #include "rc4.h" -void rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len) +void rc4_init(PRC4Ext pRC4, PBYTE pbyKey, unsigned int cbKey_len) { - UINT ust1, ust2; - UINT keyindex; - UINT stateindex; + unsigned int ust1, ust2; + unsigned int keyindex; + unsigned int stateindex; PBYTE pbyst; - UINT idx; + unsigned int idx; pbyst = pRC4->abystate; pRC4->ux = 0; @@ -58,11 +58,11 @@ void rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len) } } -UINT rc4_byte(PRC4Ext pRC4) +unsigned int rc4_byte(PRC4Ext pRC4) { - UINT ux; - UINT uy; - UINT ustx, usty; + unsigned int ux; + unsigned int uy; + unsigned int ustx, usty; PBYTE pbyst; pbyst = pRC4->abystate; @@ -79,9 +79,9 @@ UINT rc4_byte(PRC4Ext pRC4) } void rc4_encrypt(PRC4Ext pRC4, PBYTE pbyDest, - PBYTE pbySrc, UINT cbData_len) + PBYTE pbySrc, unsigned int cbData_len) { - UINT ii; + unsigned int ii; for (ii = 0; ii < cbData_len; ii++) pbyDest[ii] = (BYTE)(pbySrc[ii] ^ rc4_byte(pRC4)); } diff --git a/drivers/staging/vt6656/rc4.h b/drivers/staging/vt6656/rc4.h index 9cd1db9276bc..d447879c8f99 100644 --- a/drivers/staging/vt6656/rc4.h +++ b/drivers/staging/vt6656/rc4.h @@ -35,13 +35,14 @@ /*--------------------- Export Definitions -------------------------*/ /*--------------------- Export Types ------------------------------*/ typedef struct { - UINT ux; - UINT uy; + unsigned int ux; + unsigned int uy; BYTE abystate[256]; } RC4Ext, *PRC4Ext; -void rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len); -UINT rc4_byte(PRC4Ext pRC4); -void rc4_encrypt(PRC4Ext pRC4, PBYTE pbyDest, PBYTE pbySrc, UINT cbData_len); +void rc4_init(PRC4Ext pRC4, PBYTE pbyKey, unsigned int cbKey_len); +unsigned int rc4_byte(PRC4Ext pRC4); +void rc4_encrypt(PRC4Ext pRC4, PBYTE pbyDest, PBYTE pbySrc, + unsigned int cbData_len); #endif /* __RC4_H__ */ diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c index 4c4f5f6dc366..3fd0478a9a54 100644 --- a/drivers/staging/vt6656/rf.c +++ b/drivers/staging/vt6656/rf.c @@ -758,8 +758,8 @@ BOOL IFRFbWriteEmbeded (PSDevice pDevice, DWORD dwData) */ BOOL RFbSetPower ( PSDevice pDevice, - UINT uRATE, - UINT uCH + unsigned int uRATE, + unsigned int uCH ) { BOOL bResult = TRUE; @@ -813,7 +813,7 @@ BYTE byPwr = pDevice->byCCKPwr; BOOL RFbRawSetPower ( PSDevice pDevice, BYTE byPwr, - UINT uRATE + unsigned int uRATE ) { BOOL bResult = TRUE; diff --git a/drivers/staging/vt6656/rf.h b/drivers/staging/vt6656/rf.h index 7423d4daba01..d4f8b94132b9 100644 --- a/drivers/staging/vt6656/rf.h +++ b/drivers/staging/vt6656/rf.h @@ -66,14 +66,14 @@ extern const BYTE RFaby11aChannelIndex[200]; BOOL IFRFbWriteEmbeded(PSDevice pDevice, DWORD dwData); BOOL RFbSetPower ( PSDevice pDevice, - UINT uRATE, - UINT uCH + unsigned int uRATE, + unsigned int uCH ); BOOL RFbRawSetPower( PSDevice pDevice, BYTE byPwr, - UINT uRATE + unsigned int uRATE ); void diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index bfc786059ad1..6a4b87f09545 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -139,26 +139,24 @@ s_vGenerateTxParameter( void *pvRrvTime, void *pvRTS, void *pvCTS, - UINT cbFrameSize, + unsigned int cbFrameSize, BOOL bNeedACK, - UINT uDMAIdx, + unsigned int uDMAIdx, PSEthernetHeader psEthHeader ); -static -UINT -s_uFillDataHead ( +static unsigned int s_uFillDataHead( PSDevice pDevice, BYTE byPktType, WORD wCurrentRate, void *pTxDataHead, - UINT cbFrameLength, - UINT uDMAIdx, + unsigned int cbFrameLength, + unsigned int uDMAIdx, BOOL bNeedAck, - UINT uFragIdx, - UINT cbLastFragmentSize, - UINT uMACfragNum, + unsigned int uFragIdx, + unsigned int cbLastFragmentSize, + unsigned int uMACfragNum, BYTE byFBOption ); @@ -174,8 +172,8 @@ s_vGenerateMACHeader ( PSEthernetHeader psEthHeader, BOOL bNeedEncrypt, WORD wFragType, - UINT uDMAIdx, - UINT uFragIdx + unsigned int uDMAIdx, + unsigned int uFragIdx ); static @@ -199,24 +197,20 @@ s_vSWencryption ( WORD wPayloadSize ); -static -UINT -s_uGetTxRsvTime ( +static unsigned int s_uGetTxRsvTime( PSDevice pDevice, BYTE byPktType, - UINT cbFrameLength, + unsigned int cbFrameLength, WORD wRate, BOOL bNeedAck ); -static -UINT -s_uGetRTSCTSRsvTime ( +static unsigned int s_uGetRTSCTSRsvTime( PSDevice pDevice, BYTE byRTSRsvType, BYTE byPktType, - UINT cbFrameLength, + unsigned int cbFrameLength, WORD wCurrentRate ); @@ -224,10 +218,10 @@ static void s_vFillCTSHead ( PSDevice pDevice, - UINT uDMAIdx, + unsigned int uDMAIdx, BYTE byPktType, void *pvCTS, - UINT cbFrameLength, + unsigned int cbFrameLength, BOOL bNeedAck, BOOL bDisCRC, WORD wCurrentRate, @@ -240,7 +234,7 @@ s_vFillRTSHead( PSDevice pDevice, BYTE byPktType, void *pvRTS, - UINT cbFrameLength, + unsigned int cbFrameLength, BOOL bNeedAck, BOOL bDisCRC, PSEthernetHeader psEthHeader, @@ -248,28 +242,26 @@ s_vFillRTSHead( BYTE byFBOption ); -static -UINT -s_uGetDataDuration ( +static unsigned int s_uGetDataDuration( PSDevice pDevice, BYTE byDurType, - UINT cbFrameLength, + unsigned int cbFrameLength, BYTE byPktType, WORD wRate, BOOL bNeedAck, - UINT uFragIdx, - UINT cbLastFragmentSize, - UINT uMACfragNum, + unsigned int uFragIdx, + unsigned int cbLastFragmentSize, + unsigned int uMACfragNum, BYTE byFBOption ); static -UINT +unsigned int s_uGetRTSCTSDuration ( PSDevice pDevice, BYTE byDurType, - UINT cbFrameLength, + unsigned int cbFrameLength, BYTE byPktType, WORD wRate, BOOL bNeedAck, @@ -287,7 +279,7 @@ s_vGetFreeContext( { PUSB_SEND_CONTEXT pContext = NULL; PUSB_SEND_CONTEXT pReturnContext = NULL; - UINT ii; + unsigned int ii; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GetFreeContext()\n"); @@ -456,7 +448,7 @@ s_vSWencryption ( WORD wPayloadSize ) { - UINT cbICVlen = 4; + unsigned int cbICVlen = 4; DWORD dwICV = 0xFFFFFFFFL; PDWORD pdwICV; @@ -497,16 +489,16 @@ s_vSWencryption ( PK_TYPE_11GA 3 */ static -UINT +unsigned int s_uGetTxRsvTime ( PSDevice pDevice, BYTE byPktType, - UINT cbFrameLength, + unsigned int cbFrameLength, WORD wRate, BOOL bNeedAck ) { - UINT uDataTime, uAckTime; + unsigned int uDataTime, uAckTime; uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate); if (byPktType == PK_TYPE_11B) {//llb,CCK mode @@ -525,16 +517,16 @@ s_uGetTxRsvTime ( //byFreqType: 0=>5GHZ 1=>2.4GHZ static -UINT +unsigned int s_uGetRTSCTSRsvTime ( PSDevice pDevice, BYTE byRTSRsvType, BYTE byPktType, - UINT cbFrameLength, + unsigned int cbFrameLength, WORD wCurrentRate ) { - UINT uRrvTime , uRTSTime, uCTSTime, uAckTime, uDataTime; + unsigned int uRrvTime , uRTSTime, uCTSTime, uAckTime, uDataTime; uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0; @@ -567,23 +559,22 @@ s_uGetRTSCTSRsvTime ( //byFreqType 0: 5GHz, 1:2.4Ghz static -UINT +unsigned int s_uGetDataDuration ( PSDevice pDevice, BYTE byDurType, - UINT cbFrameLength, + unsigned int cbFrameLength, BYTE byPktType, WORD wRate, BOOL bNeedAck, - UINT uFragIdx, - UINT cbLastFragmentSize, - UINT uMACfragNum, + unsigned int uFragIdx, + unsigned int cbLastFragmentSize, + unsigned int uMACfragNum, BYTE byFBOption ) { BOOL bLastFrag = 0; - UINT uAckTime =0, uNextPktTime = 0; - + unsigned int uAckTime = 0, uNextPktTime = 0; if (uFragIdx == (uMACfragNum-1)) { bLastFrag = 1; @@ -737,18 +728,18 @@ s_uGetDataDuration ( //byFreqType: 0=>5GHZ 1=>2.4GHZ static -UINT +unsigned int s_uGetRTSCTSDuration ( PSDevice pDevice, BYTE byDurType, - UINT cbFrameLength, + unsigned int cbFrameLength, BYTE byPktType, WORD wRate, BOOL bNeedAck, BYTE byFBOption ) { - UINT uCTSTime = 0, uDurTime = 0; + unsigned int uCTSTime = 0, uDurTime = 0; switch (byDurType) { @@ -836,18 +827,18 @@ s_uGetRTSCTSDuration ( static -UINT +unsigned int s_uFillDataHead ( PSDevice pDevice, BYTE byPktType, WORD wCurrentRate, void *pTxDataHead, - UINT cbFrameLength, - UINT uDMAIdx, + unsigned int cbFrameLength, + unsigned int uDMAIdx, BOOL bNeedAck, - UINT uFragIdx, - UINT cbLastFragmentSize, - UINT uMACfragNum, + unsigned int uFragIdx, + unsigned int cbLastFragmentSize, + unsigned int uMACfragNum, BYTE byFBOption ) { @@ -986,7 +977,7 @@ s_vFillRTSHead ( PSDevice pDevice, BYTE byPktType, void *pvRTS, - UINT cbFrameLength, + unsigned int cbFrameLength, BOOL bNeedAck, BOOL bDisCRC, PSEthernetHeader psEthHeader, @@ -994,7 +985,7 @@ s_vFillRTSHead ( BYTE byFBOption ) { - UINT uRTSFrameLen = 20; + unsigned int uRTSFrameLen = 20; WORD wLen = 0x0000; if (pvRTS == NULL) @@ -1212,17 +1203,17 @@ static void s_vFillCTSHead ( PSDevice pDevice, - UINT uDMAIdx, + unsigned int uDMAIdx, BYTE byPktType, void *pvCTS, - UINT cbFrameLength, + unsigned int cbFrameLength, BOOL bNeedAck, BOOL bDisCRC, WORD wCurrentRate, BYTE byFBOption ) { - UINT uCTSFrameLen = 14; + unsigned int uCTSFrameLen = 14; WORD wLen = 0x0000; if (pvCTS == NULL) { @@ -1307,7 +1298,7 @@ s_vFillCTSHead ( * Return Value: none * -*/ -// UINT cbFrameSize,//Hdr+Payload+FCS + static void s_vGenerateTxParameter ( @@ -1318,13 +1309,13 @@ s_vGenerateTxParameter ( void *pvRrvTime, void *pvRTS, void *pvCTS, - UINT cbFrameSize, + unsigned int cbFrameSize, BOOL bNeedACK, - UINT uDMAIdx, + unsigned int uDMAIdx, PSEthernetHeader psEthHeader ) { - UINT cbMACHdLen = WLAN_HDR_ADDR3_LEN; //24 + unsigned int cbMACHdLen = WLAN_HDR_ADDR3_LEN; /* 24 */ WORD wFifoCtl; BOOL bDisCRC = FALSE; BYTE byFBOption = AUTO_FB_NONE; @@ -1422,7 +1413,7 @@ s_vGenerateTxParameter ( /* PBYTE pbyBuffer,//point to pTxBufHead WORD wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last - UINT cbFragmentSize,//Hdr+payoad+FCS + unsigned int cbFragmentSize,//Hdr+payoad+FCS */ @@ -1432,29 +1423,30 @@ s_bPacketToWirelessUsb( BYTE byPktType, PBYTE usbPacketBuf, BOOL bNeedEncryption, - UINT uSkbPacketLen, - UINT uDMAIdx, + unsigned int uSkbPacketLen, + unsigned int uDMAIdx, PSEthernetHeader psEthHeader, PBYTE pPacket, PSKeyItem pTransmitKey, - UINT uNodeIndex, + unsigned int uNodeIndex, WORD wCurrentRate, - UINT *pcbHeaderLen, - UINT *pcbTotalLen + unsigned int *pcbHeaderLen, + unsigned int *pcbTotalLen ) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - UINT cbFrameSize,cbFrameBodySize; + unsigned int cbFrameSize, cbFrameBodySize; PTX_BUFFER pTxBufHead; - UINT cb802_1_H_len; - UINT cbIVlen=0,cbICVlen=0,cbMIClen=0,cbMACHdLen=0,cbFCSlen=4; - UINT cbMICHDR = 0; + unsigned int cb802_1_H_len; + unsigned int cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, + cbMACHdLen = 0, cbFCSlen = 4; + unsigned int cbMICHDR = 0; BOOL bNeedACK,bRTS; PBYTE pbyType,pbyMacHdr,pbyIVHead,pbyPayloadHead,pbyTxBufferAddr; - BYTE abySNAP_RFC1042[6] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; - BYTE abySNAP_Bridgetunnel[6] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8}; - UINT uDuration; - UINT cbHeaderLength= 0,uPadding = 0; + BYTE abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; + BYTE abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8}; + unsigned int uDuration; + unsigned int cbHeaderLength = 0, uPadding = 0; void *pvRrvTime; PSMICHDRHead pMICHDR; void *pvRTS; @@ -1809,7 +1801,7 @@ s_bPacketToWirelessUsb( } if (pDevice->bSoftwareGenCrcErr == TRUE) { - UINT cbLen; + unsigned int cbLen; PDWORD pdwCRC; dwCRC = 0xFFFFFFFFL; @@ -1865,8 +1857,8 @@ s_vGenerateMACHeader ( PSEthernetHeader psEthHeader, BOOL bNeedEncrypt, WORD wFragType, - UINT uDMAIdx, - UINT uFragIdx + unsigned int uDMAIdx, + unsigned int uFragIdx ) { PS802_11Header pMACHeader = (PS802_11Header)pbyBufferAddr; @@ -1968,22 +1960,22 @@ CMD_STATUS csMgmt_xmit( void *pvRTS; PSCTS pCTS; void *pvTxDataHd; - UINT uDuration; - UINT cbReqCount; + unsigned int uDuration; + unsigned int cbReqCount; PS802_11Header pMACHeader; - UINT cbHeaderSize; - UINT cbFrameBodySize; + unsigned int cbHeaderSize; + unsigned int cbFrameBodySize; BOOL bNeedACK; BOOL bIsPSPOLL = FALSE; PSTxBufHead pTxBufHead; - UINT cbFrameSize; - UINT cbIVlen = 0; - UINT cbICVlen = 0; - UINT cbMIClen = 0; - UINT cbFCSlen = 4; - UINT uPadding = 0; + unsigned int cbFrameSize; + unsigned int cbIVlen = 0; + unsigned int cbICVlen = 0; + unsigned int cbMIClen = 0; + unsigned int cbFCSlen = 4; + unsigned int uPadding = 0; WORD wTxBufSize; - UINT cbMacHdLen; + unsigned int cbMacHdLen; SEthernetHeader sEthHeader; void *pvRrvTime; void *pMICHDR; @@ -2258,15 +2250,15 @@ csBeacon_xmit( ) { - UINT cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN; - UINT cbHeaderSize = 0; + unsigned int cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN; + unsigned int cbHeaderSize = 0; WORD wTxBufSize = sizeof(STxShortBufHead); PSTxShortBufHead pTxBufHead; PS802_11Header pMACHeader; PSTxDataHead_ab pTxDataHead; WORD wCurrentRate; - UINT cbFrameBodySize; - UINT cbReqCount; + unsigned int cbFrameBodySize; + unsigned int cbReqCount; PBEACON_BUFFER pTX_Buffer; PBYTE pbyTxBufferAddr; PUSB_SEND_CONTEXT pContext; @@ -2353,41 +2345,41 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb) { void *pvRTS; void *pvCTS; void *pvTxDataHd; - UINT uDuration; - UINT cbReqCount; + unsigned int uDuration; + unsigned int cbReqCount; PS802_11Header pMACHeader; - UINT cbHeaderSize; - UINT cbFrameBodySize; + unsigned int cbHeaderSize; + unsigned int cbFrameBodySize; BOOL bNeedACK; BOOL bIsPSPOLL = FALSE; PSTxBufHead pTxBufHead; - UINT cbFrameSize; - UINT cbIVlen = 0; - UINT cbICVlen = 0; - UINT cbMIClen = 0; - UINT cbFCSlen = 4; - UINT uPadding = 0; - UINT cbMICHDR = 0; - UINT uLength = 0; + unsigned int cbFrameSize; + unsigned int cbIVlen = 0; + unsigned int cbICVlen = 0; + unsigned int cbMIClen = 0; + unsigned int cbFCSlen = 4; + unsigned int uPadding = 0; + unsigned int cbMICHDR = 0; + unsigned int uLength = 0; DWORD dwMICKey0, dwMICKey1; DWORD dwMIC_Priority; PDWORD pdwMIC_L; PDWORD pdwMIC_R; WORD wTxBufSize; - UINT cbMacHdLen; + unsigned int cbMacHdLen; SEthernetHeader sEthHeader; void *pvRrvTime; void *pMICHDR; WORD wCurrentRate = RATE_1M; PUWLAN_80211HDR p80211Header; - UINT uNodeIndex = 0; + unsigned int uNodeIndex = 0; BOOL bNodeExist = FALSE; SKeyItem STempKey; PSKeyItem pTransmitKey = NULL; PBYTE pbyIVHead; PBYTE pbyPayloadHead; PBYTE pbyMacHdr; - UINT cbExtSuppRate = 0; + unsigned int cbExtSuppRate = 0; PTX_BUFFER pTX_Buffer; PUSB_SEND_CONTEXT pContext; // PWLAN_IE pItem; @@ -2754,20 +2746,20 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb) { NTSTATUS nsDMA_tx_packet( PSDevice pDevice, - UINT uDMAIdx, + unsigned int uDMAIdx, struct sk_buff *skb ) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - UINT BytesToWrite =0,uHeaderLen = 0; - UINT uNodeIndex = 0; + unsigned int BytesToWrite = 0, uHeaderLen = 0; + unsigned int uNodeIndex = 0; BYTE byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; WORD wAID; BYTE byPktType; BOOL bNeedEncryption = FALSE; PSKeyItem pTransmitKey = NULL; SKeyItem STempKey; - UINT ii; + unsigned int ii; BOOL bTKIP_UseGTK = FALSE; BOOL bNeedDeAuth = FALSE; PBYTE pbyBSSID; @@ -2775,7 +2767,7 @@ nsDMA_tx_packet( PUSB_SEND_CONTEXT pContext; BOOL fConvertedPacket; PTX_BUFFER pTX_Buffer; - UINT status; + unsigned int status; WORD wKeepRate = pDevice->wCurrentRate; struct net_device_stats* pStats = &pDevice->stats; //#ifdef WPA_SM_Transtatus @@ -3177,12 +3169,12 @@ BOOL bRelayPacketSend ( PSDevice pDevice, PBYTE pbySkbData, - UINT uDataLen, - UINT uNodeIndex + unsigned int uDataLen, + unsigned int uNodeIndex ) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - UINT BytesToWrite =0,uHeaderLen = 0; + unsigned int BytesToWrite = 0, uHeaderLen = 0; BYTE byPktType = PK_TYPE_11B; BOOL bNeedEncryption = FALSE; SKeyItem STempKey; @@ -3192,7 +3184,7 @@ bRelayPacketSend ( BYTE byPktTyp; BOOL fConvertedPacket; PTX_BUFFER pTX_Buffer; - UINT status; + unsigned int status; WORD wKeepRate = pDevice->wCurrentRate; diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h index 64df4a3550d6..f90de42d7abe 100644 --- a/drivers/staging/vt6656/rxtx.h +++ b/drivers/staging/vt6656/rxtx.h @@ -671,21 +671,24 @@ bPacketToWirelessUsb( BYTE byPktType, PBYTE usbPacketBuf, BOOL bNeedEncrypt, - UINT cbPayloadSize, - UINT uDMAIdx, + unsigned int cbPayloadSize, + unsigned int uDMAIdx, PSEthernetHeader psEthHeader, PBYTE pPacket, PSKeyItem pTransmitKey, - UINT uNodeIndex, + unsigned int uNodeIndex, WORD wCurrentRate, - UINT *pcbHeaderLen, - UINT *pcbTotalLen + unsigned int *pcbHeaderLen, + unsigned int *pcbTotalLen ); void vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb); -NTSTATUS nsDMA_tx_packet(PSDevice pDevice, UINT uDMAIdx, struct sk_buff *skb); +NTSTATUS nsDMA_tx_packet(PSDevice pDevice, + unsigned int uDMAIdx, + struct sk_buff *skb); CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket); CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket); -BOOL bRelayPacketSend(PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeIndex); +BOOL bRelayPacketSend(PSDevice pDevice, PBYTE pbySkbData, + unsigned int uDataLen, unsigned int uNodeIndex); #endif /* __RXTX_H__ */ diff --git a/drivers/staging/vt6656/tcrc.c b/drivers/staging/vt6656/tcrc.c index 3464801ede57..e25021e850a0 100644 --- a/drivers/staging/vt6656/tcrc.c +++ b/drivers/staging/vt6656/tcrc.c @@ -132,7 +132,7 @@ static const DWORD s_adwCrc32Table[256] = { * Return Value: CRC-32 * -*/ -DWORD CRCdwCrc32(PBYTE pbyData, UINT cbByte, DWORD dwCrcSeed) +DWORD CRCdwCrc32(PBYTE pbyData, unsigned int cbByte, DWORD dwCrcSeed) { DWORD dwCrc; @@ -165,7 +165,7 @@ DWORD CRCdwCrc32(PBYTE pbyData, UINT cbByte, DWORD dwCrcSeed) * Return Value: CRC-32 * -*/ -DWORD CRCdwGetCrc32(PBYTE pbyData, UINT cbByte) +DWORD CRCdwGetCrc32(PBYTE pbyData, unsigned int cbByte) { return ~CRCdwCrc32(pbyData, cbByte, 0xFFFFFFFFL); } @@ -191,7 +191,7 @@ DWORD CRCdwGetCrc32(PBYTE pbyData, UINT cbByte) * Return Value: CRC-32 * -*/ -DWORD CRCdwGetCrc32Ex(PBYTE pbyData, UINT cbByte, DWORD dwPreCRC) +DWORD CRCdwGetCrc32Ex(PBYTE pbyData, unsigned int cbByte, DWORD dwPreCRC) { return CRCdwCrc32(pbyData, cbByte, dwPreCRC); } diff --git a/drivers/staging/vt6656/tcrc.h b/drivers/staging/vt6656/tcrc.h index a41fc9b56105..4dfd01e477a4 100644 --- a/drivers/staging/vt6656/tcrc.h +++ b/drivers/staging/vt6656/tcrc.h @@ -43,8 +43,8 @@ /*--------------------- Export Functions --------------------------*/ -DWORD CRCdwCrc32(PBYTE pbyData, UINT cbByte, DWORD dwCrcSeed); -DWORD CRCdwGetCrc32(PBYTE pbyData, UINT cbByte); -DWORD CRCdwGetCrc32Ex(PBYTE pbyData, UINT cbByte, DWORD dwPreCRC); +DWORD CRCdwCrc32(PBYTE pbyData, unsigned int cbByte, DWORD dwCrcSeed); +DWORD CRCdwGetCrc32(PBYTE pbyData, unsigned int cbByte); +DWORD CRCdwGetCrc32Ex(PBYTE pbyData, unsigned int cbByte, DWORD dwPreCRC); #endif /* __TCRC_H__ */ diff --git a/drivers/staging/vt6656/tether.c b/drivers/staging/vt6656/tether.c index a7c716f174da..4f368f174b21 100644 --- a/drivers/staging/vt6656/tether.c +++ b/drivers/staging/vt6656/tether.c @@ -96,7 +96,7 @@ BYTE ETHbyGetHashIndexByCrc32(PBYTE pbyMultiAddr) * Return Value: TRUE if ok; FALSE if error. * */ -BOOL ETHbIsBufferCrc32Ok(PBYTE pbyBuffer, UINT cbFrameLength) +BOOL ETHbIsBufferCrc32Ok(PBYTE pbyBuffer, unsigned int cbFrameLength) { DWORD dwCRC; diff --git a/drivers/staging/vt6656/tether.h b/drivers/staging/vt6656/tether.h index 9b26033c585b..f5819a7aee27 100644 --- a/drivers/staging/vt6656/tether.h +++ b/drivers/staging/vt6656/tether.h @@ -228,6 +228,6 @@ S802_11Header, *PS802_11Header; BYTE ETHbyGetHashIndexByCrc32(PBYTE pbyMultiAddr); //BYTE ETHbyGetHashIndexByCrc(PBYTE pbyMultiAddr); -BOOL ETHbIsBufferCrc32Ok(PBYTE pbyBuffer, UINT cbFrameLength); +BOOL ETHbIsBufferCrc32Ok(PBYTE pbyBuffer, unsigned int cbFrameLength); #endif /* __TETHER_H__ */ diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h index 3a297754233a..c27f9858e2e9 100644 --- a/drivers/staging/vt6656/ttype.h +++ b/drivers/staging/vt6656/ttype.h @@ -72,12 +72,6 @@ typedef int BOOL; /****** Simple typedefs ***************************************************/ -typedef unsigned char UCHAR; -typedef unsigned short USHORT; -typedef unsigned int UINT; -typedef unsigned long ULONG; -typedef unsigned long long ULONGLONG; //64 bit - typedef unsigned char BYTE; // 8-bit typedef unsigned short WORD; // 16-bit typedef unsigned long DWORD; // 32-bit diff --git a/drivers/staging/vt6656/upc.h b/drivers/staging/vt6656/upc.h index be386edb3e94..b33aba4b12c9 100644 --- a/drivers/staging/vt6656/upc.h +++ b/drivers/staging/vt6656/upc.h @@ -141,7 +141,7 @@ #define PCAvDelayByIO(uDelayUnit) { \ BYTE byData; \ - ULONG ii; \ + unsigned long ii; \ \ if (uDelayUnit <= 50) { \ udelay(uDelayUnit); \ diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c index ce71f18afd81..fd2355e34fb0 100644 --- a/drivers/staging/vt6656/usbpipe.c +++ b/drivers/staging/vt6656/usbpipe.c @@ -484,12 +484,11 @@ s_nsInterruptUsbIoCompleteRead( pDevice->fKillEventPollingThread = TRUE; // } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"IntUSBIoCompleteControl STATUS = %d\n", ntStatus ); - } - else { - pDevice->ulIntInBytesRead += (ULONG)urb->actual_length; - pDevice->ulIntInContCRCError = 0; - pDevice->bEventAvailable = TRUE; - INTnsProcessData(pDevice); + } else { + pDevice->ulIntInBytesRead += (unsigned long) urb->actual_length; + pDevice->ulIntInContCRCError = 0; + pDevice->bEventAvailable = TRUE; + INTnsProcessData(pDevice); } STAvUpdateUSBCounter(&pDevice->scStatistic.USB_InterruptStat, ntStatus); @@ -614,7 +613,7 @@ s_nsBulkInUsbIoCompleteRead( { PRCB pRCB = (PRCB)urb->context; PSDevice pDevice = (PSDevice)pRCB->pDevice; - ULONG bytesRead; + unsigned long bytesRead; BOOL bIndicateReceive = FALSE; BOOL bReAllocSkb = FALSE; NTSTATUS status; @@ -774,7 +773,7 @@ s_nsBulkOutIoCompleteWrite( PSDevice pDevice; NTSTATUS status; CONTEXT_TYPE ContextType; - ULONG ulBufLen; + unsigned long ulBufLen; PUSB_SEND_CONTEXT pContext; diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c index 6fec9094ccd0..72e21b6f0e88 100644 --- a/drivers/staging/vt6656/wcmd.c +++ b/drivers/staging/vt6656/wcmd.c @@ -219,7 +219,7 @@ s_vProbeChannel( PBYTE pbyRate; PSTxMgmtPacket pTxPacket; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - UINT ii; + unsigned int ii; if (pDevice->byBBType == BB_TYPE_11A) { @@ -316,15 +316,15 @@ s_MgrMakeProbeRequest( return pTxPacket; } -void vCommandTimerWait(void *hDeviceContext, UINT MSecond) +void vCommandTimerWait(void *hDeviceContext, unsigned int MSecond) { PSDevice pDevice = (PSDevice)hDeviceContext; init_timer(&pDevice->sTimerCommand); - pDevice->sTimerCommand.data = (ULONG)pDevice; + pDevice->sTimerCommand.data = (unsigned long)pDevice; pDevice->sTimerCommand.function = (TimerFunction)vRunCommand; // RUN_AT :1 msec ~= (HZ/1024) - pDevice->sTimerCommand.expires = (UINT)RUN_AT((MSecond * HZ) >> 10); + pDevice->sTimerCommand.expires = (unsigned int)RUN_AT((MSecond * HZ) >> 10); add_timer(&pDevice->sTimerCommand); return; } @@ -336,7 +336,7 @@ void vRunCommand(void *hDeviceContext) PWLAN_IE_SSID pItemSSID; PWLAN_IE_SSID pItemSSIDCurr; CMD_STATUS Status; - UINT ii; + unsigned int ii; BYTE byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; struct sk_buff *skb; BYTE byData; @@ -760,7 +760,7 @@ void vRunCommand(void *hDeviceContext) // printk("Re-initial TxDataTimer****\n"); del_timer(&pDevice->sTimerTxData); init_timer(&pDevice->sTimerTxData); - pDevice->sTimerTxData.data = (ULONG)pDevice; + pDevice->sTimerTxData.data = (unsigned long) pDevice; pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData; pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback pDevice->fTxDataInSleep = FALSE; @@ -1264,8 +1264,8 @@ BOOL bScheduleCommand(void *hDeviceContext, static BOOL s_bClearBSSID_SCAN(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; - UINT uCmdDequeueIdx = pDevice->uCmdDequeueIdx; - UINT ii; + unsigned int uCmdDequeueIdx = pDevice->uCmdDequeueIdx; + unsigned int ii; if ((pDevice->cbFreeCmdQueue < CMD_Q_SIZE) && (uCmdDequeueIdx != pDevice->uCmdEnqueueIdx)) { for (ii = 0; ii < (CMD_Q_SIZE - pDevice->cbFreeCmdQueue); ii ++) { @@ -1289,7 +1289,7 @@ void vResetCommandTimer(void *hDeviceContext) del_timer(&pDevice->sTimerCommand); //init timer init_timer(&pDevice->sTimerCommand); - pDevice->sTimerCommand.data = (ULONG)pDevice; + pDevice->sTimerCommand.data = (unsigned long)pDevice; pDevice->sTimerCommand.function = (TimerFunction)vRunCommand; pDevice->sTimerCommand.expires = RUN_AT(HZ); pDevice->cbFreeCmdQueue = CMD_Q_SIZE; diff --git a/drivers/staging/vt6656/wctl.c b/drivers/staging/vt6656/wctl.c index 956add694227..857ce0bc00a4 100644 --- a/drivers/staging/vt6656/wctl.c +++ b/drivers/staging/vt6656/wctl.c @@ -69,8 +69,8 @@ BOOL WCTLbIsDuplicate (PSCache pCache, PS802_11Header pMACHeader) { - UINT uIndex; - UINT ii; + unsigned int uIndex; + unsigned int ii; PSCacheEntry pCacheEntry; if (IS_FC_RETRY(pMACHeader)) { @@ -111,9 +111,9 @@ BOOL WCTLbIsDuplicate (PSCache pCache, PS802_11Header pMACHeader) * Return Value: index number in Defragment Database * */ -UINT WCTLuSearchDFCB (PSDevice pDevice, PS802_11Header pMACHeader) +unsigned int WCTLuSearchDFCB(PSDevice pDevice, PS802_11Header pMACHeader) { -UINT ii; + unsigned int ii; for(ii=0;iicbDFCB;ii++) { if ((pDevice->sRxDFCB[ii].bInUse == TRUE) && @@ -141,9 +141,9 @@ UINT ii; * Return Value: index number in Defragment Database * */ -UINT WCTLuInsertDFCB (PSDevice pDevice, PS802_11Header pMACHeader) +unsigned int WCTLuInsertDFCB(PSDevice pDevice, PS802_11Header pMACHeader) { -UINT ii; + unsigned int ii; if (pDevice->cbFreeDFCB == 0) return(pDevice->cbDFCB); @@ -180,9 +180,10 @@ UINT ii; * Return Value: TRUE if it is valid fragment packet and we have resource to defragment; otherwise FALSE * */ -BOOL WCTLbHandleFragment (PSDevice pDevice, PS802_11Header pMACHeader, UINT cbFrameLength, BOOL bWEP, BOOL bExtIV) +BOOL WCTLbHandleFragment(PSDevice pDevice, PS802_11Header pMACHeader, + unsigned int cbFrameLength, BOOL bWEP, BOOL bExtIV) { -UINT uHeaderSize; +unsigned int uHeaderSize; if (bWEP == TRUE) { diff --git a/drivers/staging/vt6656/wctl.h b/drivers/staging/vt6656/wctl.h index c81dff700e0f..7270af68c89d 100644 --- a/drivers/staging/vt6656/wctl.h +++ b/drivers/staging/vt6656/wctl.h @@ -90,7 +90,6 @@ (uVar)++; \ } - /*--------------------- Export Classes ----------------------------*/ /*--------------------- Export Variables --------------------------*/ @@ -98,8 +97,9 @@ /*--------------------- Export Functions --------------------------*/ BOOL WCTLbIsDuplicate(PSCache pCache, PS802_11Header pMACHeader); -BOOL WCTLbHandleFragment(PSDevice pDevice, PS802_11Header pMACHeader, UINT cbFrameLength, BOOL bWEP, BOOL bExtIV); -UINT WCTLuSearchDFCB(PSDevice pDevice, PS802_11Header pMACHeader); -UINT WCTLuInsertDFCB(PSDevice pDevice, PS802_11Header pMACHeader); +BOOL WCTLbHandleFragment(PSDevice pDevice, PS802_11Header pMACHeader, + unsigned int cbFrameLength, BOOL bWEP, BOOL bExtIV); +unsigned int WCTLuSearchDFCB(PSDevice pDevice, PS802_11Header pMACHeader); +unsigned int WCTLuInsertDFCB(PSDevice pDevice, PS802_11Header pMACHeader); #endif /* __WCTL_H__ */ diff --git a/drivers/staging/vt6656/wmgr.c b/drivers/staging/vt6656/wmgr.c index aaba5221170d..93c15f0580fe 100644 --- a/drivers/staging/vt6656/wmgr.c +++ b/drivers/staging/vt6656/wmgr.c @@ -118,7 +118,7 @@ s_vMgrRxAssocRequest( PSDevice pDevice, PSMgmtObject pMgmt, PSRxMgmtPacket pRxPacket, - UINT uNodeIndex + unsigned int uNodeIndex ); static @@ -242,7 +242,7 @@ s_MgrMakeBeacon( PSMgmtObject pMgmt, WORD wCurrCapInfo, WORD wCurrBeaconPeriod, - UINT uCurrChannel, + unsigned int uCurrChannel, WORD wCurrATIMWinodw, PWLAN_IE_SSID pCurrSSID, PBYTE pCurrBSSID, @@ -287,7 +287,7 @@ s_MgrMakeProbeResponse( PSMgmtObject pMgmt, WORD wCurrCapInfo, WORD wCurrBeaconPeriod, - UINT uCurrChannel, + unsigned int uCurrChannel, WORD wCurrATIMWinodw, PBYTE pDstAddr, PWLAN_IE_SSID pCurrSSID, @@ -310,7 +310,7 @@ static void s_vMgrSynchBSS ( PSDevice pDevice, - UINT uBSSMode, + unsigned int uBSSMode, PKnownBSS pCurr, PCMD_STATUS pStatus ); @@ -364,19 +364,19 @@ void vMgrObjectInit(void *hDeviceContext) BSSvClearBSSList((void *) pDevice, FALSE); init_timer(&pMgmt->sTimerSecondCallback); - pMgmt->sTimerSecondCallback.data = (ULONG)pDevice; + pMgmt->sTimerSecondCallback.data = (unsigned long)pDevice; pMgmt->sTimerSecondCallback.function = (TimerFunction)BSSvSecondCallBack; pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ); init_timer(&pDevice->sTimerCommand); - pDevice->sTimerCommand.data = (ULONG)pDevice; + pDevice->sTimerCommand.data = (unsigned long)pDevice; pDevice->sTimerCommand.function = (TimerFunction)vRunCommand; pDevice->sTimerCommand.expires = RUN_AT(HZ); //2007-0115-10by MikeLiu #ifdef TxInSleep init_timer(&pDevice->sTimerTxData); - pDevice->sTimerTxData.data = (ULONG)pDevice; + pDevice->sTimerTxData.data = (unsigned long)pDevice; pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData; pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback pDevice->fTxDataInSleep = FALSE; @@ -619,7 +619,7 @@ s_vMgrRxAssocRequest( PSDevice pDevice, PSMgmtObject pMgmt, PSRxMgmtPacket pRxPacket, - UINT uNodeIndex + unsigned int uNodeIndex ) { WLAN_FR_ASSOCREQ sFrame; @@ -627,7 +627,7 @@ s_vMgrRxAssocRequest( PSTxMgmtPacket pTxPacket; WORD wAssocStatus = 0; WORD wAssocAID = 0; - UINT uRateLen = WLAN_RATES_MAXLEN; + unsigned int uRateLen = WLAN_RATES_MAXLEN; BYTE abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; BYTE abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; @@ -775,7 +775,7 @@ s_vMgrRxReAssocRequest( PSDevice pDevice, PSMgmtObject pMgmt, PSRxMgmtPacket pRxPacket, - UINT uNodeIndex + unsigned int uNodeIndex ) { WLAN_FR_REASSOCREQ sFrame; @@ -783,7 +783,7 @@ s_vMgrRxReAssocRequest( PSTxMgmtPacket pTxPacket; WORD wAssocStatus = 0; WORD wAssocAID = 0; - UINT uRateLen = WLAN_RATES_MAXLEN; + unsigned int uRateLen = WLAN_RATES_MAXLEN; BYTE abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; BYTE abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; @@ -1257,7 +1257,7 @@ s_vMgrRxAuthenSequence_1( ) { PSTxMgmtPacket pTxPacket = NULL; - UINT uNodeIndex; + unsigned int uNodeIndex; WLAN_FR_AUTHEN sFrame; PSKeyItem pTransmitKey; @@ -1464,8 +1464,8 @@ s_vMgrRxAuthenSequence_3( ) { PSTxMgmtPacket pTxPacket = NULL; - UINT uStatusCode = 0 ; - UINT uNodeIndex = 0; + unsigned int uStatusCode = 0 ; + unsigned int uNodeIndex = 0; WLAN_FR_AUTHEN sFrame; if (!WLAN_GET_FC_ISWEP(pFrame->pHdr->sA3.wFrameCtl)) { @@ -1590,7 +1590,7 @@ s_vMgrRxDisassociation( ) { WLAN_FR_DISASSOC sFrame; - UINT uNodeIndex = 0; + unsigned int uNodeIndex = 0; CMD_STATUS CmdStatus; viawget_wpa_header *wpahdr; @@ -1680,7 +1680,7 @@ s_vMgrRxDeauthentication( ) { WLAN_FR_DEAUTHEN sFrame; - UINT uNodeIndex = 0; + unsigned int uNodeIndex = 0; viawget_wpa_header *wpahdr; @@ -1817,17 +1817,17 @@ s_vMgrRxBeacon( BOOL bUpdateTSF = FALSE; BOOL bIsAPBeacon = FALSE; BOOL bIsChannelEqual = FALSE; - UINT uLocateByteIndex; + unsigned int uLocateByteIndex; BYTE byTIMBitOn = 0; WORD wAIDNumber = 0; - UINT uNodeIndex; + unsigned int uNodeIndex; QWORD qwTimestamp, qwLocalTSF; QWORD qwCurrTSF; WORD wStartIndex = 0; WORD wAIDIndex = 0; BYTE byCurrChannel = pRxPacket->byRxChannel; ERPObject sERP; - UINT uRateLen = WLAN_RATES_MAXLEN; + unsigned int uRateLen = WLAN_RATES_MAXLEN; BOOL bChannelHit = FALSE; BYTE byOldPreambleType; @@ -2336,7 +2336,7 @@ void vMgrCreateOwnIBSS(void *hDeviceContext, BYTE byTopCCKBasicRate; BYTE byTopOFDMBasicRate; QWORD qwCurrTSF; - UINT ii; + unsigned int ii; BYTE abyRATE[] = {0x82, 0x84, 0x8B, 0x96, 0x24, 0x30, 0x48, 0x6C, 0x0C, 0x12, 0x18, 0x60}; BYTE abyCCK_RATE[] = {0x82, 0x84, 0x8B, 0x96}; BYTE abyOFDM_RATE[] = {0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; @@ -2601,11 +2601,11 @@ void vMgrJoinBSSBegin(void *hDeviceContext, PCMD_STATUS pStatus) PSDevice pDevice = (PSDevice)hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); PKnownBSS pCurr = NULL; - UINT ii, uu; + unsigned int ii, uu; PWLAN_IE_SUPP_RATES pItemRates = NULL; PWLAN_IE_SUPP_RATES pItemExtRates = NULL; PWLAN_IE_SSID pItemSSID; - UINT uRateLen = WLAN_RATES_MAXLEN; + unsigned int uRateLen = WLAN_RATES_MAXLEN; WORD wMaxBasicRate = RATE_1M; WORD wMaxSuppRate = RATE_1M; WORD wSuppRate; @@ -2705,9 +2705,10 @@ void vMgrJoinBSSBegin(void *hDeviceContext, PCMD_STATUS pStatus) uRateLen); // Stuffing Rate IE if ((pItemExtRates->len > 0) && (pItemRates->len < 8)) { - for (ii = 0; ii < (UINT)(8 - pItemRates->len); ) { - pItemRates->abyRates[pItemRates->len + ii] = pItemExtRates->abyRates[ii]; - ii ++; + for (ii = 0; ii < (unsigned int) (8 - pItemRates->len); ) { + pItemRates->abyRates[pItemRates->len + ii] = + pItemExtRates->abyRates[ii]; + ii++; if (pItemExtRates->len <= ii) break; } @@ -2931,7 +2932,7 @@ static void s_vMgrSynchBSS ( PSDevice pDevice, - UINT uBSSMode, + unsigned int uBSSMode, PKnownBSS pCurr, PCMD_STATUS pStatus ) @@ -3096,7 +3097,7 @@ s_vMgrSynchBSS ( ) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - // UINT ii , uSameBssidNum=0; + /* unsigned int ii, uSameBssidNum=0; */ // for (ii = 0; ii < MAX_BSS_NUM; ii++) { // if (pMgmt->sBSSList[ii].bActive && @@ -3155,7 +3156,7 @@ s_vMgrFormatTIM( { BYTE byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80}; BYTE byMap; - UINT ii, jj; + unsigned int ii, jj; BOOL bStartFound = FALSE; BOOL bMulticast = FALSE; WORD wStartIndex = 0; @@ -3228,7 +3229,7 @@ s_MgrMakeBeacon( PSMgmtObject pMgmt, WORD wCurrCapInfo, WORD wCurrBeaconPeriod, - UINT uCurrChannel, + unsigned int uCurrChannel, WORD wCurrATIMWinodw, PWLAN_IE_SSID pCurrSSID, PBYTE pCurrBSSID, @@ -3402,7 +3403,7 @@ s_MgrMakeProbeResponse( PSMgmtObject pMgmt, WORD wCurrCapInfo, WORD wCurrBeaconPeriod, - UINT uCurrChannel, + unsigned int uCurrChannel, WORD wCurrATIMWinodw, PBYTE pDstAddr, PWLAN_IE_SSID pCurrSSID, @@ -3672,7 +3673,7 @@ s_MgrMakeAssocRequest( } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) && (pMgmt->pCurrBSS != NULL)) { - UINT ii; + unsigned int ii; PWORD pwPMKID; // WPA IE @@ -3932,7 +3933,7 @@ s_MgrMakeReAssocRequest( } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) && (pMgmt->pCurrBSS != NULL)) { - UINT ii; + unsigned int ii; PWORD pwPMKID; /* WPA IE */ @@ -4422,7 +4423,7 @@ void vMgrRxManagePacket(void *hDeviceContext, { PSDevice pDevice = (PSDevice)hDeviceContext; BOOL bInScan = FALSE; - UINT uNodeIndex = 0; + unsigned int uNodeIndex = 0; NODE_STATE eNodeState = 0; CMD_STATUS Status; @@ -4689,7 +4690,7 @@ BOOL bAdd_PMKID_Candidate(void *hDeviceContext, { PSDevice pDevice = (PSDevice)hDeviceContext; PPMKID_CANDIDATE pCandidateList; - UINT ii = 0; + unsigned int ii = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates); diff --git a/drivers/staging/vt6656/wmgr.h b/drivers/staging/vt6656/wmgr.h index ec2ee7805f4e..1e5b916aea1d 100644 --- a/drivers/staging/vt6656/wmgr.h +++ b/drivers/staging/vt6656/wmgr.h @@ -84,37 +84,37 @@ //mike define: make timer to expire after desired times #define timer_expire(timer,next_tick) mod_timer(&timer, RUN_AT(next_tick)) -typedef void (*TimerFunction)(ULONG); +typedef void (*TimerFunction)(unsigned long); //+++ NDIS related -typedef UCHAR NDIS_802_11_MAC_ADDRESS[6]; +typedef unsigned char NDIS_802_11_MAC_ADDRESS[ETH_ALEN]; typedef struct _NDIS_802_11_AI_REQFI { - USHORT Capabilities; - USHORT ListenInterval; + unsigned short Capabilities; + unsigned short ListenInterval; NDIS_802_11_MAC_ADDRESS CurrentAPAddress; } NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI; typedef struct _NDIS_802_11_AI_RESFI { - USHORT Capabilities; - USHORT StatusCode; - USHORT AssociationId; + unsigned short Capabilities; + unsigned short StatusCode; + unsigned short AssociationId; } NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI; typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION { - ULONG Length; - USHORT AvailableRequestFixedIEs; + unsigned long Length; + unsigned short AvailableRequestFixedIEs; NDIS_802_11_AI_REQFI RequestFixedIEs; - ULONG RequestIELength; - ULONG OffsetRequestIEs; - USHORT AvailableResponseFixedIEs; + unsigned long RequestIELength; + unsigned long OffsetRequestIEs; + unsigned short AvailableResponseFixedIEs; NDIS_802_11_AI_RESFI ResponseFixedIEs; - ULONG ResponseIELength; - ULONG OffsetResponseIEs; + unsigned long ResponseIELength; + unsigned long OffsetResponseIEs; } NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION; @@ -123,7 +123,7 @@ typedef struct tagSAssocInfo { NDIS_802_11_ASSOCIATION_INFORMATION AssocInfo; BYTE abyIEs[WLAN_BEACON_FR_MAXLEN+WLAN_BEACON_FR_MAXLEN]; // store ReqIEs set by OID_802_11_ASSOCIATION_INFORMATION - ULONG RequestIELength; + unsigned long RequestIELength; BYTE abyReqIEs[WLAN_BEACON_FR_MAXLEN]; } SAssocInfo, *PSAssocInfo; //--- @@ -222,8 +222,8 @@ typedef enum tagWMAC_POWER_MODE { typedef struct tagSTxMgmtPacket { PUWLAN_80211HDR p80211Header; - UINT cbMPDULen; - UINT cbPayloadLen; + unsigned int cbMPDULen; + unsigned int cbPayloadLen; } STxMgmtPacket, *PSTxMgmtPacket; @@ -233,9 +233,9 @@ typedef struct tagSRxMgmtPacket { PUWLAN_80211HDR p80211Header; QWORD qwLocalTSF; - UINT cbMPDULen; - UINT cbPayloadLen; - UINT uRSSI; + unsigned int cbMPDULen; + unsigned int cbPayloadLen; + unsigned int uRSSI; BYTE bySQ; BYTE byRxRate; BYTE byRxChannel; @@ -272,21 +272,21 @@ typedef struct tagSMgmtObject BOOL bCurrBSSIDFilterOn; // Current state vars - UINT uCurrChannel; + unsigned int uCurrChannel; BYTE abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; BYTE abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; BYTE abyCurrSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; BYTE abyCurrBSSID[WLAN_BSSID_LEN]; WORD wCurrCapInfo; WORD wCurrAID; - UINT uRSSITrigger; + unsigned int uRSSITrigger; WORD wCurrATIMWindow; WORD wCurrBeaconPeriod; BOOL bIsDS; BYTE byERPContext; CMD_STATE eCommandState; - UINT uScanChannel; + unsigned int uScanChannel; // Desire joinning BSS vars BYTE abyDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; @@ -301,22 +301,22 @@ typedef struct tagSMgmtObject // Adhoc or AP configuration vars WORD wIBSSBeaconPeriod; WORD wIBSSATIMWindow; - UINT uIBSSChannel; + unsigned int uIBSSChannel; BYTE abyIBSSSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1]; BYTE byAPBBType; BYTE abyWPAIE[MAX_WPA_IE_LEN]; WORD wWPAIELen; - UINT uAssocCount; + unsigned int uAssocCount; BOOL bMoreData; // Scan state vars WMAC_SCAN_STATE eScanState; WMAC_SCAN_TYPE eScanType; - UINT uScanStartCh; - UINT uScanEndCh; + unsigned int uScanStartCh; + unsigned int uScanEndCh; WORD wScanSteps; - UINT uScanBSSType; + unsigned int uScanBSSType; // Desire scannig vars BYTE abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; BYTE abyScanBSSID[WLAN_BSSID_LEN]; @@ -344,8 +344,8 @@ typedef struct tagSMgmtObject BYTE abyPSTxMap[MAX_NODE_NUM + 1]; // managment command related - UINT uCmdBusy; - UINT uCmdHostAPBusy; + unsigned int uCmdBusy; + unsigned int uCmdHostAPBusy; // managment packet pool PBYTE pbyMgmtPacketPool; @@ -389,7 +389,7 @@ typedef struct tagSMgmtObject BOOL bSwitchChannel; BYTE byNewChannel; PWLAN_IE_MEASURE_REP pCurrMeasureEIDRep; - UINT uLengthOfRepEIDs; + unsigned int uLengthOfRepEIDs; BYTE abyCurrentMSRReq[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN]; BYTE abyCurrentMSRRep[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN]; BYTE abyIECountry[WLAN_A3FR_MAXLEN]; diff --git a/drivers/staging/vt6656/wpa2.c b/drivers/staging/vt6656/wpa2.c index 9bd6bf5bf37c..6d13190885d1 100644 --- a/drivers/staging/vt6656/wpa2.c +++ b/drivers/staging/vt6656/wpa2.c @@ -260,14 +260,14 @@ WPA2vParseRSN ( * Return Value: length of IEs. * -*/ -UINT +unsigned int WPA2uSetIEs(void *pMgmtHandle, PWLAN_IE_RSN pRSNIEs ) { PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; PBYTE pbyBuffer = NULL; - UINT ii = 0; + unsigned int ii = 0; PWORD pwPMKID = NULL; if (pRSNIEs == NULL) { diff --git a/drivers/staging/vt6656/wpa2.h b/drivers/staging/vt6656/wpa2.h index 79305a79b9da..429a910a5c50 100644 --- a/drivers/staging/vt6656/wpa2.h +++ b/drivers/staging/vt6656/wpa2.h @@ -45,7 +45,7 @@ typedef struct tagsPMKIDInfo { } PMKIDInfo, *PPMKIDInfo; typedef struct tagSPMKIDCache { - ULONG BSSIDInfoCount; + unsigned long BSSIDInfoCount; PMKIDInfo BSSIDInfo[MAX_PMKID_CACHE]; } SPMKIDCache, *PSPMKIDCache; @@ -69,7 +69,7 @@ WPA2vParseRSN ( PWLAN_IE_RSN pRSN ); -UINT +unsigned int WPA2uSetIEs( void *pMgmtHandle, PWLAN_IE_RSN pRSNIEs diff --git a/drivers/staging/vt6656/wpactl.h b/drivers/staging/vt6656/wpactl.h index 3a2f15f3f249..00c8451ab50b 100644 --- a/drivers/staging/vt6656/wpactl.h +++ b/drivers/staging/vt6656/wpactl.h @@ -52,9 +52,7 @@ typedef enum { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, #define GENERIC_INFO_ELEM 0xdd #define RSN_INFO_ELEM 0x30 - - -typedef ULONGLONG NDIS_802_11_KEY_RSC; +typedef unsigned long long NDIS_802_11_KEY_RSC; /*--------------------- Export Classes ----------------------------*/ -- cgit v1.2.3 From 973267a212a6f28c26cbb7929a7ffdd963c16861 Mon Sep 17 00:00:00 2001 From: Adam Latham Date: Sat, 15 May 2010 09:38:44 +0100 Subject: Staging: winbond: Fix for pointer name format issue in mds.c This patch fixes the unnecessary whitespace found in pointer names in the mds.c file found by the checkpatch.pl tool Signed-off-by: Adam Latham Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mds.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c index 65063c33618d..e8320a6f59af 100644 --- a/drivers/staging/winbond/mds.c +++ b/drivers/staging/winbond/mds.c @@ -6,7 +6,7 @@ #include "wblinux_f.h" unsigned char -Mds_initial(struct wbsoft_priv * adapter) +Mds_initial(struct wbsoft_priv *adapter) { struct wb35_mds *pMds = &adapter->Mds; @@ -18,7 +18,7 @@ Mds_initial(struct wbsoft_priv * adapter) } void -Mds_Destroy(struct wbsoft_priv * adapter) +Mds_Destroy(struct wbsoft_priv *adapter) { } @@ -318,7 +318,7 @@ static u16 Mds_BodyCopy(struct wbsoft_priv *adapter, struct wb35_descriptor *pDe return Size; } -static void Mds_HeaderCopy(struct wbsoft_priv * adapter, struct wb35_descriptor *pDes, u8 *TargetBuffer) +static void Mds_HeaderCopy(struct wbsoft_priv *adapter, struct wb35_descriptor *pDes, u8 *TargetBuffer) { struct wb35_mds *pMds = &adapter->Mds; u8 *src_buffer = pDes->buffer_address[0]; /* 931130.5.g */ @@ -414,9 +414,9 @@ static void Mds_HeaderCopy(struct wbsoft_priv * adapter, struct wb35_descriptor } void -Mds_Tx(struct wbsoft_priv * adapter) +Mds_Tx(struct wbsoft_priv *adapter) { - struct hw_data * pHwData = &adapter->sHwData; + struct hw_data *pHwData = &adapter->sHwData; struct wb35_mds *pMds = &adapter->Mds; struct wb35_descriptor TxDes; struct wb35_descriptor *pTxDes = &TxDes; @@ -550,10 +550,10 @@ Mds_Tx(struct wbsoft_priv * adapter) } void -Mds_SendComplete(struct wbsoft_priv * adapter, PT02_DESCRIPTOR pT02) +Mds_SendComplete(struct wbsoft_priv *adapter, PT02_DESCRIPTOR pT02) { struct wb35_mds *pMds = &adapter->Mds; - struct hw_data * pHwData = &adapter->sHwData; + struct hw_data *pHwData = &adapter->sHwData; u8 PacketId = (u8)pT02->T02_Tx_PktID; unsigned char SendOK = true; u8 RetryCount, TxRate; -- cgit v1.2.3 From abfc768d9e374dc30b98206aff99d790e36d06dd Mon Sep 17 00:00:00 2001 From: Lior Dotan Date: Tue, 18 May 2010 12:46:42 +0300 Subject: Staging: crystalhd: Remove typedefs from driver Remove typedefs from driver Signed-of-by: Lior Dotan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/crystalhd/bc_dts_defs.h | 68 +++++------ drivers/staging/crystalhd/bc_dts_glob_lnx.h | 117 +++++++++--------- drivers/staging/crystalhd/crystalhd_cmds.c | 160 ++++++++++++------------ drivers/staging/crystalhd/crystalhd_cmds.h | 21 ++-- drivers/staging/crystalhd/crystalhd_fw_if.h | 60 ++++----- drivers/staging/crystalhd/crystalhd_hw.c | 183 ++++++++++++++-------------- drivers/staging/crystalhd/crystalhd_hw.h | 121 +++++++++--------- drivers/staging/crystalhd/crystalhd_lnx.c | 34 +++--- drivers/staging/crystalhd/crystalhd_lnx.h | 6 +- drivers/staging/crystalhd/crystalhd_misc.c | 80 ++++++------ drivers/staging/crystalhd/crystalhd_misc.h | 54 ++++---- 11 files changed, 442 insertions(+), 462 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/crystalhd/bc_dts_defs.h b/drivers/staging/crystalhd/bc_dts_defs.h index f9dd0e3e240d..778e76af0528 100644 --- a/drivers/staging/crystalhd/bc_dts_defs.h +++ b/drivers/staging/crystalhd/bc_dts_defs.h @@ -26,12 +26,10 @@ #ifndef _BC_DTS_DEFS_H_ #define _BC_DTS_DEFS_H_ -#include "bc_dts_types.h" - /* BIT Mask */ #define BC_BIT(_x) (1 << (_x)) -typedef enum _BC_STATUS { +enum BC_STATUS { BC_STS_SUCCESS = 0, BC_STS_INV_ARG = 1, BC_STS_BUSY = 2, @@ -62,7 +60,7 @@ typedef enum _BC_STATUS { /* Must be the last one.*/ BC_STS_ERROR = -1 -} BC_STATUS; +}; /*------------------------------------------------------* * Registry Key Definitions * @@ -81,14 +79,14 @@ typedef enum _BC_STATUS { * */ -typedef enum _BC_SW_OPTIONS { +enum BC_SW_OPTIONS { BC_OPT_DOSER_OUT_ENCRYPT = BC_BIT(3), BC_OPT_LINK_OUT_ENCRYPT = BC_BIT(29), -} BC_SW_OPTIONS; +}; -typedef struct _BC_REG_CONFIG{ +struct BC_REG_CONFIG{ uint32_t DbgOptions; -} BC_REG_CONFIG; +}; #if defined(__KERNEL__) || defined(__LINUX_USER__) #else @@ -108,7 +106,7 @@ typedef struct _BC_REG_CONFIG{ */ /* To allow multiple apps to open the device. */ -enum _DtsDeviceOpenMode { +enum DtsDeviceOpenMode { DTS_PLAYBACK_MODE = 0, DTS_DIAG_MODE, DTS_MONITOR_MODE, @@ -116,7 +114,7 @@ enum _DtsDeviceOpenMode { }; /* To enable the filter to selectively enable/disable fixes or erratas */ -enum _DtsDeviceFixMode { +enum DtsDeviceFixMode { DTS_LOAD_NEW_FW = BC_BIT(8), DTS_LOAD_FILE_PLAY_FW = BC_BIT(9), DTS_DISK_FMT_BD = BC_BIT(10), @@ -133,7 +131,7 @@ enum _DtsDeviceFixMode { #define DTS_DFLT_CLOCK(x) (x<<19) /* F/W File Version corresponding to S/W Releases */ -enum _FW_FILE_VER { +enum FW_FILE_VER { /* S/W release: 02.04.02 F/W release 2.12.2.0 */ BC_FW_VER_020402 = ((12<<16) | (2<<8) | (0)) }; @@ -141,7 +139,7 @@ enum _FW_FILE_VER { /*------------------------------------------------------* * Stream Types for DtsOpenDecoder() * *------------------------------------------------------*/ -enum _DtsOpenDecStreamTypes { +enum DtsOpenDecStreamTypes { BC_STREAM_TYPE_ES = 0, BC_STREAM_TYPE_PES = 1, BC_STREAM_TYPE_TS = 2, @@ -151,7 +149,7 @@ enum _DtsOpenDecStreamTypes { /*------------------------------------------------------* * Video Algorithms for DtsSetVideoParams() * *------------------------------------------------------*/ -enum _DtsSetVideoParamsAlgo { +enum DtsSetVideoParamsAlgo { BC_VID_ALGO_H264 = 0, BC_VID_ALGO_MPEG2 = 1, BC_VID_ALGO_VC1 = 4, @@ -163,7 +161,7 @@ enum _DtsSetVideoParamsAlgo { *------------------------------------------------------*/ #define BC_MPEG_VALID_PANSCAN (1) -typedef struct _BC_PIB_EXT_MPEG { +struct BC_PIB_EXT_MPEG { uint32_t valid; /* Always valid, defaults to picture size if no * sequence display extension in the stream. */ @@ -175,8 +173,7 @@ typedef struct _BC_PIB_EXT_MPEG { uint32_t offset_count; int32_t horizontal_offset[3]; int32_t vertical_offset[3]; - -} BC_PIB_EXT_MPEG; +}; /*------------------------------------------------------* * H.264 Extension to the PPB * @@ -186,7 +183,7 @@ typedef struct _BC_PIB_EXT_MPEG { #define H264_VALID_SPS_CROP (2) #define H264_VALID_VUI (4) -typedef struct _BC_PIB_EXT_H264 { +struct BC_PIB_EXT_H264 { /* 'valid' specifies which fields (or sets of * fields) below are valid. If the corresponding * bit in 'valid' is NOT set then that field(s) @@ -209,15 +206,14 @@ typedef struct _BC_PIB_EXT_H264 { /* H264_VALID_VUI */ uint32_t chroma_top; uint32_t chroma_bottom; - -} BC_PIB_EXT_H264; +}; /*------------------------------------------------------* * VC1 Extension to the PPB * *------------------------------------------------------*/ #define VC1_VALID_PANSCAN (1) -typedef struct _BC_PIB_EXT_VC1 { +struct BC_PIB_EXT_VC1 { uint32_t valid; /* Always valid, defaults to picture size if no @@ -231,9 +227,7 @@ typedef struct _BC_PIB_EXT_VC1 { int32_t ps_vert_offset[4]; int32_t ps_width[4]; int32_t ps_height[4]; - -} BC_PIB_EXT_VC1; - +}; /*------------------------------------------------------* * Picture Information Block * @@ -366,7 +360,7 @@ enum _BC_OUTPUT_FORMAT { MODE422_UYVY = 0x2, }; -typedef struct _BC_PIC_INFO_BLOCK { +struct BC_PIC_INFO_BLOCK { /* Common fields. */ uint64_t timeStamp; /* Timestamp */ uint32_t picture_number; /* Ordinal display number */ @@ -386,18 +380,18 @@ typedef struct _BC_PIC_INFO_BLOCK { /* Protocol-specific extensions. */ union { - BC_PIB_EXT_H264 h264; - BC_PIB_EXT_MPEG mpeg; - BC_PIB_EXT_VC1 vc1; + struct BC_PIB_EXT_H264 h264; + struct BC_PIB_EXT_MPEG mpeg; + struct BC_PIB_EXT_VC1 vc1; } other; -} BC_PIC_INFO_BLOCK, *PBC_PIC_INFO_BLOCK; +}; /*------------------------------------------------------* * ProcOut Info * *------------------------------------------------------*/ /* Optional flags for ProcOut Interface.*/ -enum _POUT_OPTIONAL_IN_FLAGS_{ +enum POUT_OPTIONAL_IN_FLAGS_{ /* Flags from App to Device */ BC_POUT_FLAGS_YV12 = 0x01, /* Copy Data in YV12 format */ BC_POUT_FLAGS_STRIDE = 0x02, /* Stride size is valid. */ @@ -412,17 +406,13 @@ enum _POUT_OPTIONAL_IN_FLAGS_{ BC_POUT_FLAGS_FLD_BOT = 0x80000, /* Bottom Field data */ }; -#if defined(__KERNEL__) || defined(__LINUX_USER__) -typedef BC_STATUS(*dts_pout_callback)(void *shnd, uint32_t width, uint32_t height, uint32_t stride, void *pOut); -#else -typedef BC_STATUS(*dts_pout_callback)(void *shnd, uint32_t width, uint32_t height, uint32_t stride, struct _BC_DTS_PROC_OUT *pOut); -#endif +typedef enum BC_STATUS(*dts_pout_callback)(void *shnd, uint32_t width, uint32_t height, uint32_t stride, void *pOut); /* Line 21 Closed Caption */ /* User Data */ #define MAX_UD_SIZE 1792 /* 1920 - 128 */ -typedef struct _BC_DTS_PROC_OUT { +struct BC_DTS_PROC_OUT { uint8_t *Ybuff; /* Caller Supplied buffer for Y data */ uint32_t YbuffSz; /* Caller Supplied Y buffer size */ uint32_t YBuffDoneSz; /* Transferred Y datasize */ @@ -436,7 +426,7 @@ typedef struct _BC_DTS_PROC_OUT { uint32_t discCnt; /* Picture discontinuity count */ - BC_PIC_INFO_BLOCK PicInfo; /* Picture Information Block Data */ + struct BC_PIC_INFO_BLOCK PicInfo; /* Picture Information Block Data */ /* Line 21 Closed Caption */ /* User Data */ @@ -450,9 +440,9 @@ typedef struct _BC_DTS_PROC_OUT { uint8_t bPibEnc; /* PIB encrypted */ uint8_t bRevertScramble; -} BC_DTS_PROC_OUT; +}; -typedef struct _BC_DTS_STATUS { +struct BC_DTS_STATUS { uint8_t ReadyListCount; /* Number of frames in ready list (reported by driver) */ uint8_t FreeListCount; /* Number of frame buffers free. (reported by driver) */ uint8_t PowerStateChange; /* Number of active state power transitions (reported by driver) */ @@ -479,7 +469,7 @@ typedef struct _BC_DTS_STATUS { * back from the driver */ uint8_t reserved__[16]; -} BC_DTS_STATUS; +}; #define BC_SWAP32(_v) \ ((((_v) & 0xFF000000)>>24)| \ diff --git a/drivers/staging/crystalhd/bc_dts_glob_lnx.h b/drivers/staging/crystalhd/bc_dts_glob_lnx.h index 0fd34e20dc88..80b7a73a9d46 100644 --- a/drivers/staging/crystalhd/bc_dts_glob_lnx.h +++ b/drivers/staging/crystalhd/bc_dts_glob_lnx.h @@ -58,7 +58,7 @@ * These are SW stack tunable parameters shared * between the driver and the application. */ -enum _BC_DTS_GLOBALS { +enum BC_DTS_GLOBALS { BC_MAX_FW_CMD_BUFF_SZ = 0x40, /* FW passthrough cmd/rsp buffer size */ PCI_CFG_SIZE = 256, /* PCI config size buffer */ BC_IOCTL_DATA_POOL_SIZE = 8, /* BC_IOCTL_DATA Pool size */ @@ -70,62 +70,62 @@ enum _BC_DTS_GLOBALS { BC_INFIFO_THRESHOLD = 0x10000, }; -typedef struct _BC_CMD_REG_ACC { +struct BC_CMD_REG_ACC { uint32_t Offset; uint32_t Value; -} BC_CMD_REG_ACC; +}; -typedef struct _BC_CMD_DEV_MEM { +struct BC_CMD_DEV_MEM { uint32_t StartOff; uint32_t NumDwords; uint32_t Rsrd; -} BC_CMD_DEV_MEM; +}; /* FW Passthrough command structure */ -enum _bc_fw_cmd_flags { +enum bc_fw_cmd_flags { BC_FW_CMD_FLAGS_NONE = 0, BC_FW_CMD_PIB_QS = 0x01, }; -typedef struct _BC_FW_CMD { +struct BC_FW_CMD { uint32_t cmd[BC_MAX_FW_CMD_BUFF_SZ]; uint32_t rsp[BC_MAX_FW_CMD_BUFF_SZ]; uint32_t flags; uint32_t add_data; -} BC_FW_CMD, *PBC_FW_CMD; +}; -typedef struct _BC_HW_TYPE { +struct BC_HW_TYPE { uint16_t PciDevId; uint16_t PciVenId; uint8_t HwRev; uint8_t Align[3]; -} BC_HW_TYPE; +}; -typedef struct _BC_PCI_CFG { +struct BC_PCI_CFG { uint32_t Size; uint32_t Offset; uint8_t pci_cfg_space[PCI_CFG_SIZE]; -} BC_PCI_CFG; +}; -typedef struct _BC_VERSION_INFO_ { +struct BC_VERSION_INFO { uint8_t DriverMajor; uint8_t DriverMinor; uint16_t DriverRevision; -} BC_VERSION_INFO; +}; -typedef struct _BC_START_RX_CAP_ { +struct BC_START_RX_CAP { uint32_t Rsrd; uint32_t StartDeliveryThsh; uint32_t PauseThsh; uint32_t ResumeThsh; -} BC_START_RX_CAP; +}; -typedef struct _BC_FLUSH_RX_CAP_ { +struct BC_FLUSH_RX_CAP { uint32_t Rsrd; uint32_t bDiscardOnly; -} BC_FLUSH_RX_CAP; +}; -typedef struct _BC_DTS_STATS { +struct BC_DTS_STATS { uint8_t drvRLL; uint8_t drvFLL; uint8_t eosDetected; @@ -154,18 +154,18 @@ typedef struct _BC_DTS_STATS { uint32_t DrvRepeatedFrms; uint32_t res1[13]; -} BC_DTS_STATS; +}; -typedef struct _BC_PROC_INPUT_ { +struct BC_PROC_INPUT { uint8_t *pDmaBuff; uint32_t BuffSz; uint8_t Mapped; uint8_t Encrypted; uint8_t Rsrd[2]; uint32_t DramOffset; /* For debug use only */ -} BC_PROC_INPUT, *PBC_PROC_INPUT; +}; -typedef struct _BC_DEC_YUV_BUFFS { +struct BC_DEC_YUV_BUFFS { uint32_t b422Mode; uint8_t *YuvBuff; uint32_t YuvBuffSz; @@ -173,9 +173,9 @@ typedef struct _BC_DEC_YUV_BUFFS { uint32_t YBuffDoneSz; uint32_t UVBuffDoneSz; uint32_t RefCnt; -} BC_DEC_YUV_BUFFS; +}; -enum _DECOUT_COMPLETION_FLAGS{ +enum DECOUT_COMPLETION_FLAGS{ COMP_FLAG_NO_INFO = 0x00, COMP_FLAG_FMT_CHANGE = 0x01, COMP_FLAG_PIB_VALID = 0x02, @@ -184,47 +184,47 @@ enum _DECOUT_COMPLETION_FLAGS{ COMP_FLAG_DATA_BOT = 0x10, }; -typedef struct _BC_DEC_OUT_BUFF{ - BC_DEC_YUV_BUFFS OutPutBuffs; - BC_PIC_INFO_BLOCK PibInfo; +struct BC_DEC_OUT_BUFF{ + struct BC_DEC_YUV_BUFFS OutPutBuffs; + struct BC_PIC_INFO_BLOCK PibInfo; uint32_t Flags; uint32_t BadFrCnt; -} BC_DEC_OUT_BUFF; +}; -typedef struct _BC_NOTIFY_MODE { +struct BC_NOTIFY_MODE { uint32_t Mode; uint32_t Rsvr[3]; -} BC_NOTIFY_MODE; +}; -typedef struct _BC_CLOCK { +struct BC_CLOCK { uint32_t clk; uint32_t Rsvr[3]; -} BC_CLOCK; +}; -typedef struct _BC_IOCTL_DATA { - BC_STATUS RetSts; +struct BC_IOCTL_DATA { + enum BC_STATUS RetSts; uint32_t IoctlDataSz; uint32_t Timeout; union { - BC_CMD_REG_ACC regAcc; - BC_CMD_DEV_MEM devMem; - BC_FW_CMD fwCmd; - BC_HW_TYPE hwType; - BC_PCI_CFG pciCfg; - BC_VERSION_INFO VerInfo; - BC_PROC_INPUT ProcInput; - BC_DEC_YUV_BUFFS RxBuffs; - BC_DEC_OUT_BUFF DecOutData; - BC_START_RX_CAP RxCap; - BC_FLUSH_RX_CAP FlushRxCap; - BC_DTS_STATS drvStat; - BC_NOTIFY_MODE NotifyMode; - BC_CLOCK clockValue; + struct BC_CMD_REG_ACC regAcc; + struct BC_CMD_DEV_MEM devMem; + struct BC_FW_CMD fwCmd; + struct BC_HW_TYPE hwType; + struct BC_PCI_CFG pciCfg; + struct BC_VERSION_INFO VerInfo; + struct BC_PROC_INPUT ProcInput; + struct BC_DEC_YUV_BUFFS RxBuffs; + struct BC_DEC_OUT_BUFF DecOutData; + struct BC_START_RX_CAP RxCap; + struct BC_FLUSH_RX_CAP FlushRxCap; + struct BC_DTS_STATS drvStat; + struct BC_NOTIFY_MODE NotifyMode; + struct BC_CLOCK clockValue; } u; struct _BC_IOCTL_DATA *next; -} BC_IOCTL_DATA; +}; -typedef enum _BC_DRV_CMD{ +enum BC_DRV_CMD { DRV_CMD_VERSION = 0, /* Get SW version */ DRV_CMD_GET_HWTYPE, /* Get HW version and type Dozer/Tank */ DRV_CMD_REG_RD, /* Read Device Register */ @@ -249,12 +249,12 @@ typedef enum _BC_DRV_CMD{ /* MUST be the last one.. */ DRV_CMD_END, /* End of the List.. */ -} BC_DRV_CMD; +}; #define BC_IOC_BASE 'b' #define BC_IOC_VOID _IOC_NONE #define BC_IOC_IOWR(nr, type) _IOWR(BC_IOC_BASE, nr, type) -#define BC_IOCTL_MB BC_IOCTL_DATA +#define BC_IOCTL_MB struct BC_IOCTL_DATA #define BCM_IOC_GET_VERSION BC_IOC_IOWR(DRV_CMD_VERSION, BC_IOCTL_MB) #define BCM_IOC_GET_HWTYPE BC_IOC_IOWR(DRV_CMD_GET_HWTYPE, BC_IOCTL_MB) @@ -280,17 +280,16 @@ typedef enum _BC_DRV_CMD{ #define BCM_IOC_END BC_IOC_VOID /* Wrapper for main IOCTL data */ -typedef struct _crystalhd_ioctl_data { - BC_IOCTL_DATA udata; /* IOCTL from App..*/ +struct crystalhd_ioctl_data { + struct BC_IOCTL_DATA udata; /* IOCTL from App..*/ uint32_t u_id; /* Driver specific user ID */ uint32_t cmd; /* Cmd ID for driver's use. */ void *add_cdata; /* Additional command specific data..*/ uint32_t add_cdata_sz; /* Additional command specific data size */ - struct _crystalhd_ioctl_data *next; /* List/Fifo management */ -} crystalhd_ioctl_data; - + struct crystalhd_ioctl_data *next; /* List/Fifo management */ +}; -enum _crystalhd_kmod_ver{ +enum crystalhd_kmod_ver{ crystalhd_kmod_major = 0, crystalhd_kmod_minor = 9, crystalhd_kmod_rev = 27, diff --git a/drivers/staging/crystalhd/crystalhd_cmds.c b/drivers/staging/crystalhd/crystalhd_cmds.c index 1a7ca8ba7f85..1429608544d6 100644 --- a/drivers/staging/crystalhd/crystalhd_cmds.c +++ b/drivers/staging/crystalhd/crystalhd_cmds.c @@ -69,8 +69,8 @@ static void bc_cproc_mark_pwr_state(struct crystalhd_cmd *ctx) } } -static BC_STATUS bc_cproc_notify_mode(struct crystalhd_cmd *ctx, - crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_notify_mode(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { int rc = 0, i = 0; @@ -111,8 +111,8 @@ static BC_STATUS bc_cproc_notify_mode(struct crystalhd_cmd *ctx, return crystalhd_hw_setup_dma_rings(&ctx->hw_ctx); } -static BC_STATUS bc_cproc_get_version(struct crystalhd_cmd *ctx, - crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_get_version(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { if (!ctx || !idata) { @@ -126,7 +126,8 @@ static BC_STATUS bc_cproc_get_version(struct crystalhd_cmd *ctx, } -static BC_STATUS bc_cproc_get_hwtype(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_get_hwtype(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { if (!ctx || !idata) { BCMLOG_ERR("Invalid Arg!!\n"); @@ -143,8 +144,8 @@ static BC_STATUS bc_cproc_get_hwtype(struct crystalhd_cmd *ctx, crystalhd_ioctl_ return BC_STS_SUCCESS; } -static BC_STATUS bc_cproc_reg_rd(struct crystalhd_cmd *ctx, - crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_reg_rd(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { if (!ctx || !idata) return BC_STS_INV_ARG; @@ -153,8 +154,8 @@ static BC_STATUS bc_cproc_reg_rd(struct crystalhd_cmd *ctx, return BC_STS_SUCCESS; } -static BC_STATUS bc_cproc_reg_wr(struct crystalhd_cmd *ctx, - crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_reg_wr(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { if (!ctx || !idata) return BC_STS_INV_ARG; @@ -165,8 +166,8 @@ static BC_STATUS bc_cproc_reg_wr(struct crystalhd_cmd *ctx, return BC_STS_SUCCESS; } -static BC_STATUS bc_cproc_link_reg_rd(struct crystalhd_cmd *ctx, - crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_link_reg_rd(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { if (!ctx || !idata) return BC_STS_INV_ARG; @@ -176,8 +177,8 @@ static BC_STATUS bc_cproc_link_reg_rd(struct crystalhd_cmd *ctx, return BC_STS_SUCCESS; } -static BC_STATUS bc_cproc_link_reg_wr(struct crystalhd_cmd *ctx, - crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_link_reg_wr(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { if (!ctx || !idata) return BC_STS_INV_ARG; @@ -188,10 +189,10 @@ static BC_STATUS bc_cproc_link_reg_wr(struct crystalhd_cmd *ctx, return BC_STS_SUCCESS; } -static BC_STATUS bc_cproc_mem_rd(struct crystalhd_cmd *ctx, - crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_mem_rd(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { - BC_STATUS sts = BC_STS_SUCCESS; + enum BC_STATUS sts = BC_STS_SUCCESS; if (!ctx || !idata || !idata->add_cdata) return BC_STS_INV_ARG; @@ -207,10 +208,10 @@ static BC_STATUS bc_cproc_mem_rd(struct crystalhd_cmd *ctx, } -static BC_STATUS bc_cproc_mem_wr(struct crystalhd_cmd *ctx, - crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_mem_wr(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { - BC_STATUS sts = BC_STS_SUCCESS; + enum BC_STATUS sts = BC_STS_SUCCESS; if (!ctx || !idata || !idata->add_cdata) return BC_STS_INV_ARG; @@ -226,11 +227,11 @@ static BC_STATUS bc_cproc_mem_wr(struct crystalhd_cmd *ctx, return sts; } -static BC_STATUS bc_cproc_cfg_rd(struct crystalhd_cmd *ctx, - crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_cfg_rd(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { uint32_t ix, cnt, off, len; - BC_STATUS sts = BC_STS_SUCCESS; + enum BC_STATUS sts = BC_STS_SUCCESS; uint32_t *temp; if (!ctx || !idata) @@ -258,11 +259,11 @@ static BC_STATUS bc_cproc_cfg_rd(struct crystalhd_cmd *ctx, return sts; } -static BC_STATUS bc_cproc_cfg_wr(struct crystalhd_cmd *ctx, - crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_cfg_wr(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { uint32_t ix, cnt, off, len; - BC_STATUS sts = BC_STS_SUCCESS; + enum BC_STATUS sts = BC_STS_SUCCESS; uint32_t *temp; if (!ctx || !idata) @@ -290,10 +291,10 @@ static BC_STATUS bc_cproc_cfg_wr(struct crystalhd_cmd *ctx, return sts; } -static BC_STATUS bc_cproc_download_fw(struct crystalhd_cmd *ctx, - crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_download_fw(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { - BC_STATUS sts = BC_STS_SUCCESS; + enum BC_STATUS sts = BC_STS_SUCCESS; if (!ctx || !idata || !idata->add_cdata || !idata->add_cdata_sz) { BCMLOG_ERR("Invalid Arg!!\n"); @@ -329,9 +330,10 @@ static BC_STATUS bc_cproc_download_fw(struct crystalhd_cmd *ctx, * Abort pending input transfers and issue decoder flush command. * */ -static BC_STATUS bc_cproc_do_fw_cmd(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_do_fw_cmd(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { - BC_STATUS sts; + enum BC_STATUS sts; uint32_t *cmd; if (!(ctx->state & BC_LINK_INIT)) { @@ -371,8 +373,8 @@ static BC_STATUS bc_cproc_do_fw_cmd(struct crystalhd_cmd *ctx, crystalhd_ioctl_d return sts; } -static void bc_proc_in_completion(crystalhd_dio_req *dio_hnd, - wait_queue_head_t *event, BC_STATUS sts) +static void bc_proc_in_completion(struct crystalhd_dio_req *dio_hnd, + wait_queue_head_t *event, enum BC_STATUS sts) { if (!dio_hnd || !event) { BCMLOG_ERR("Invalid Arg!!\n"); @@ -386,7 +388,7 @@ static void bc_proc_in_completion(crystalhd_dio_req *dio_hnd, crystalhd_set_event(event); } -static BC_STATUS bc_cproc_codein_sleep(struct crystalhd_cmd *ctx) +static enum BC_STATUS bc_cproc_codein_sleep(struct crystalhd_cmd *ctx) { wait_queue_head_t sleep_ev; int rc = 0; @@ -406,12 +408,12 @@ static BC_STATUS bc_cproc_codein_sleep(struct crystalhd_cmd *ctx) return BC_STS_SUCCESS; } -static BC_STATUS bc_cproc_hw_txdma(struct crystalhd_cmd *ctx, - crystalhd_ioctl_data *idata, - crystalhd_dio_req *dio) +static enum BC_STATUS bc_cproc_hw_txdma(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata, + struct crystalhd_dio_req *dio) { uint32_t tx_listid = 0; - BC_STATUS sts = BC_STS_SUCCESS; + enum BC_STATUS sts = BC_STS_SUCCESS; wait_queue_head_t event; int rc = 0; @@ -471,7 +473,7 @@ static BC_STATUS bc_cproc_hw_txdma(struct crystalhd_cmd *ctx, } /* Helper function to check on user buffers */ -static BC_STATUS bc_cproc_check_inbuffs(bool pin, void *ubuff, uint32_t ub_sz, +static enum BC_STATUS bc_cproc_check_inbuffs(bool pin, void *ubuff, uint32_t ub_sz, uint32_t uv_off, bool en_422) { if (!ubuff || !ub_sz) { @@ -502,12 +504,13 @@ static BC_STATUS bc_cproc_check_inbuffs(bool pin, void *ubuff, uint32_t ub_sz, return BC_STS_SUCCESS; } -static BC_STATUS bc_cproc_proc_input(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_proc_input(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { void *ubuff; uint32_t ub_sz; - crystalhd_dio_req *dio_hnd = NULL; - BC_STATUS sts = BC_STS_SUCCESS; + struct crystalhd_dio_req *dio_hnd = NULL; + enum BC_STATUS sts = BC_STS_SUCCESS; if (!ctx || !idata) { BCMLOG_ERR("Invalid Arg!!\n"); @@ -537,14 +540,14 @@ static BC_STATUS bc_cproc_proc_input(struct crystalhd_cmd *ctx, crystalhd_ioctl_ return sts; } -static BC_STATUS bc_cproc_add_cap_buff(struct crystalhd_cmd *ctx, - crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_add_cap_buff(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { void *ubuff; uint32_t ub_sz, uv_off; bool en_422; - crystalhd_dio_req *dio_hnd = NULL; - BC_STATUS sts = BC_STS_SUCCESS; + struct crystalhd_dio_req *dio_hnd = NULL; + enum BC_STATUS sts = BC_STS_SUCCESS; if (!ctx || !idata) { BCMLOG_ERR("Invalid Arg!!\n"); @@ -579,10 +582,10 @@ static BC_STATUS bc_cproc_add_cap_buff(struct crystalhd_cmd *ctx, return BC_STS_SUCCESS; } -static BC_STATUS bc_cproc_fmt_change(struct crystalhd_cmd *ctx, - crystalhd_dio_req *dio) +static enum BC_STATUS bc_cproc_fmt_change(struct crystalhd_cmd *ctx, + struct crystalhd_dio_req *dio) { - BC_STATUS sts = BC_STS_SUCCESS; + enum BC_STATUS sts = BC_STS_SUCCESS; sts = crystalhd_hw_add_cap_buffer(&ctx->hw_ctx, dio, 0); if (sts != BC_STS_SUCCESS) @@ -595,12 +598,12 @@ static BC_STATUS bc_cproc_fmt_change(struct crystalhd_cmd *ctx, return sts; } -static BC_STATUS bc_cproc_fetch_frame(struct crystalhd_cmd *ctx, - crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_fetch_frame(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { - crystalhd_dio_req *dio = NULL; - BC_STATUS sts = BC_STS_SUCCESS; - BC_DEC_OUT_BUFF *frame; + struct crystalhd_dio_req *dio = NULL; + enum BC_STATUS sts = BC_STS_SUCCESS; + struct BC_DEC_OUT_BUFF *frame; if (!ctx || !idata) { BCMLOG_ERR("Invalid Arg!!\n"); @@ -636,8 +639,8 @@ static BC_STATUS bc_cproc_fetch_frame(struct crystalhd_cmd *ctx, return BC_STS_SUCCESS; } -static BC_STATUS bc_cproc_start_capture(struct crystalhd_cmd *ctx, - crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_start_capture(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { ctx->state |= BC_LINK_CAP_EN; if (ctx->state == BC_LINK_READY) @@ -646,12 +649,12 @@ static BC_STATUS bc_cproc_start_capture(struct crystalhd_cmd *ctx, return BC_STS_SUCCESS; } -static BC_STATUS bc_cproc_flush_cap_buffs(struct crystalhd_cmd *ctx, - crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_flush_cap_buffs(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { - crystalhd_dio_req *dio = NULL; - BC_STATUS sts = BC_STS_SUCCESS; - BC_DEC_OUT_BUFF *frame; + struct crystalhd_dio_req *dio = NULL; + enum BC_STATUS sts = BC_STS_SUCCESS; + struct BC_DEC_OUT_BUFF *frame; uint32_t count; if (!ctx || !idata) { @@ -681,10 +684,10 @@ static BC_STATUS bc_cproc_flush_cap_buffs(struct crystalhd_cmd *ctx, return crystalhd_hw_stop_capture(&ctx->hw_ctx); } -static BC_STATUS bc_cproc_get_stats(struct crystalhd_cmd *ctx, - crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_get_stats(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { - BC_DTS_STATS *stats; + struct BC_DTS_STATS *stats; struct crystalhd_hw_stats hw_stats; if (!ctx || !idata) { @@ -713,20 +716,20 @@ static BC_STATUS bc_cproc_get_stats(struct crystalhd_cmd *ctx, return BC_STS_SUCCESS; } -static BC_STATUS bc_cproc_reset_stats(struct crystalhd_cmd *ctx, - crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_reset_stats(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { crystalhd_hw_stats(&ctx->hw_ctx, NULL); return BC_STS_SUCCESS; } -static BC_STATUS bc_cproc_chg_clk(struct crystalhd_cmd *ctx, - crystalhd_ioctl_data *idata) +static enum BC_STATUS bc_cproc_chg_clk(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { - BC_CLOCK *clock; + struct BC_CLOCK *clock; uint32_t oldClk; - BC_STATUS sts = BC_STS_SUCCESS; + enum BC_STATUS sts = BC_STS_SUCCESS; if (!ctx || !idata) { BCMLOG_ERR("Invalid Arg!!\n"); @@ -749,7 +752,7 @@ static BC_STATUS bc_cproc_chg_clk(struct crystalhd_cmd *ctx, } /*=============== Cmd Proc Table.. ======================================*/ -static const crystalhd_cmd_tbl_t g_crystalhd_cproc_tbl[] = { +static const struct crystalhd_cmd_tbl g_crystalhd_cproc_tbl[] = { { BCM_IOC_GET_VERSION, bc_cproc_get_version, 0}, { BCM_IOC_GET_HWTYPE, bc_cproc_get_hwtype, 0}, { BCM_IOC_REG_RD, bc_cproc_reg_rd, 0}, @@ -796,9 +799,10 @@ static const crystalhd_cmd_tbl_t g_crystalhd_cproc_tbl[] = { * we pass on the power mangement notification to our plug-in by completing * all outstanding requests with BC_STS_IO_USER_ABORT return code. */ -BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata) +enum BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx, + struct crystalhd_ioctl_data *idata) { - BC_STATUS sts = BC_STS_SUCCESS; + enum BC_STATUS sts = BC_STS_SUCCESS; if (!ctx || !idata) { BCMLOG_ERR("Invalid Parameters\n"); @@ -854,7 +858,7 @@ BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *ida * start a new playback session from the pre-suspend clip position. * */ -BC_STATUS crystalhd_resume(struct crystalhd_cmd *ctx) +enum BC_STATUS crystalhd_resume(struct crystalhd_cmd *ctx) { BCMLOG(BCMLOG_DBG, "crystalhd_resume Success %x\n", ctx->state); @@ -875,7 +879,7 @@ BC_STATUS crystalhd_resume(struct crystalhd_cmd *ctx) * application specific resources. HW layer initialization * is done for the first open request. */ -BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx, +enum BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx, struct crystalhd_user **user_ctx) { struct crystalhd_user *uc; @@ -913,7 +917,7 @@ BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx, * Closer aplication handle and release app specific * resources. */ -BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx, struct crystalhd_user *uc) +enum BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx, struct crystalhd_user *uc) { uint32_t mode = uc->mode; @@ -948,7 +952,7 @@ BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx, struct crystalhd_user * * Called at the time of driver load. */ -BC_STATUS __devinit crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx, +enum BC_STATUS __devinit crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx, struct crystalhd_adp *adp) { int i = 0; @@ -983,7 +987,7 @@ BC_STATUS __devinit crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx, * * Called at the time of driver un-load. */ -BC_STATUS __devexit crystalhd_delete_cmd_context(struct crystalhd_cmd *ctx) +enum BC_STATUS __devexit crystalhd_delete_cmd_context(struct crystalhd_cmd *ctx) { BCMLOG(BCMLOG_DBG, "Deleting Command context..\n"); @@ -1021,7 +1025,7 @@ crystalhd_cmd_proc crystalhd_get_cmd_proc(struct crystalhd_cmd *ctx, uint32_t cm return NULL; } - tbl_sz = sizeof(g_crystalhd_cproc_tbl) / sizeof(crystalhd_cmd_tbl_t); + tbl_sz = sizeof(g_crystalhd_cproc_tbl) / sizeof(struct crystalhd_cmd_tbl); for (i = 0; i < tbl_sz; i++) { if (g_crystalhd_cproc_tbl[i].cmd_id == cmd) { if ((uc->mode == DTS_MONITOR_MODE) && diff --git a/drivers/staging/crystalhd/crystalhd_cmds.h b/drivers/staging/crystalhd/crystalhd_cmds.h index 9989038b5c1b..10130296601f 100644 --- a/drivers/staging/crystalhd/crystalhd_cmds.h +++ b/drivers/staging/crystalhd/crystalhd_cmds.h @@ -36,7 +36,7 @@ #include "crystalhd_misc.h" #include "crystalhd_hw.h" -enum _crystalhd_state{ +enum crystalhd_state{ BC_LINK_INVALID = 0x00, BC_LINK_INIT = 0x01, BC_LINK_CAP_EN = 0x02, @@ -66,23 +66,22 @@ struct crystalhd_cmd { struct crystalhd_hw hw_ctx; }; -typedef BC_STATUS(*crystalhd_cmd_proc)(struct crystalhd_cmd *, crystalhd_ioctl_data *); +typedef enum BC_STATUS(*crystalhd_cmd_proc)(struct crystalhd_cmd *, struct crystalhd_ioctl_data *); -typedef struct _crystalhd_cmd_tbl { +struct crystalhd_cmd_tbl { uint32_t cmd_id; const crystalhd_cmd_proc cmd_proc; uint32_t block_mon; -} crystalhd_cmd_tbl_t; - +}; -BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata); -BC_STATUS crystalhd_resume(struct crystalhd_cmd *ctx); +enum BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx, struct crystalhd_ioctl_data *idata); +enum BC_STATUS crystalhd_resume(struct crystalhd_cmd *ctx); crystalhd_cmd_proc crystalhd_get_cmd_proc(struct crystalhd_cmd *ctx, uint32_t cmd, struct crystalhd_user *uc); -BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx, struct crystalhd_user **user_ctx); -BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx, struct crystalhd_user *uc); -BC_STATUS crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx, struct crystalhd_adp *adp); -BC_STATUS crystalhd_delete_cmd_context(struct crystalhd_cmd *ctx); +enum BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx, struct crystalhd_user **user_ctx); +enum BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx, struct crystalhd_user *uc); +enum BC_STATUS crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx, struct crystalhd_adp *adp); +enum BC_STATUS crystalhd_delete_cmd_context(struct crystalhd_cmd *ctx); bool crystalhd_cmd_interrupt(struct crystalhd_cmd *ctx); #endif diff --git a/drivers/staging/crystalhd/crystalhd_fw_if.h b/drivers/staging/crystalhd/crystalhd_fw_if.h index 261cd19a0ee7..77560d4b6802 100644 --- a/drivers/staging/crystalhd/crystalhd_fw_if.h +++ b/drivers/staging/crystalhd/crystalhd_fw_if.h @@ -29,21 +29,17 @@ /* TBD: Pull in only required defs into this file.. */ - - /* User Data Header */ -typedef struct user_data { +struct user_data { struct user_data *next; uint32_t type; uint32_t size; -} UD_HDR; - - +}; /*------------------------------------------------------* * MPEG Extension to the PPB * *------------------------------------------------------*/ -typedef struct { +struct ppb_mpeg { uint32_t to_be_defined; uint32_t valid; @@ -61,15 +57,15 @@ typedef struct { /* MPEG_VALID_USERDATA User data is in the form of a linked list. */ int32_t userDataSize; - UD_HDR *userData; + struct user_data *userData; -} PPB_MPEG; +}; /*------------------------------------------------------* * VC1 Extension to the PPB * *------------------------------------------------------*/ -typedef struct { +struct ppb_vc1 { uint32_t to_be_defined; uint32_t valid; @@ -88,9 +84,9 @@ typedef struct { /* VC1_VALID_USERDATA User data is in the form of a linked list. */ int32_t userDataSize; - UD_HDR *userData; + struct user_data *userData; -} PPB_VC1; +}; /*------------------------------------------------------* * H.264 Extension to the PPB * @@ -108,8 +104,8 @@ typedef struct { /* maximum number of intervals(as many as 256 intervals?) */ #define MAX_FGT_VALUE_INTERVAL (256) -typedef struct FGT_SEI { - struct FGT_SEI *next; +struct fgt_sei { + struct fgt_sei *next; unsigned char model_values[3][MAX_FGT_VALUE_INTERVAL][MAX_FGT_MODEL_VALUE]; unsigned char upper_bound[3][MAX_FGT_VALUE_INTERVAL]; unsigned char lower_bound[3][MAX_FGT_VALUE_INTERVAL]; @@ -134,9 +130,9 @@ typedef struct FGT_SEI { unsigned char num_model_values[3]; /* Number of model values. */ uint16_t repetition_period; /* Repetition period (0-16384) */ -} FGT_SEI; +}; -typedef struct { +struct ppb_h264 { /* 'valid' specifies which fields (or sets of * fields) below are valid. If the corresponding * bit in 'valid' is NOT set then that field(s) @@ -170,14 +166,14 @@ typedef struct { /* H264_VALID_USER */ uint32_t user_data_size; - UD_HDR *user_data; + struct user_data *user_data; /* H264 VALID FGT */ - FGT_SEI *pfgt; + struct fgt_sei *pfgt; -} PPB_H264; +}; -typedef struct { +struct ppb { /* Common fields. */ uint32_t picture_number; /* Ordinal display number */ uint32_t video_buffer; /* Video (picbuf) number */ @@ -215,14 +211,14 @@ typedef struct { /* Protocol-specific extensions. */ union { - PPB_H264 h264; - PPB_MPEG mpeg; - PPB_VC1 vc1; + struct ppb_h264 h264; + struct ppb_mpeg mpeg; + struct ppb_vc1 vc1; } other; -} PPB; +}; -typedef struct { +struct c011_pib { uint32_t bFormatChange; uint32_t resolution; uint32_t channelId; @@ -231,13 +227,11 @@ typedef struct { uint32_t zeroPanscanValid; uint32_t dramOutBufAddr; uint32_t yComponent; - PPB ppb; - -} C011_PIB; - + struct ppb ppb; +}; -typedef struct { +struct dec_rsp_channel_start_video { uint32_t command; uint32_t sequence; uint32_t status; @@ -251,12 +245,12 @@ typedef struct { uint32_t transportStreamCaptureAddr; uint32_t asyncEventQ; -} DecRspChannelStartVideo; +}; #define eCMD_C011_CMD_BASE (0x73763000) /* host commands */ -typedef enum { +enum c011_ts_cmd { eCMD_TS_GET_NEXT_PIC = 0x7376F100, /* debug get next picture */ eCMD_TS_GET_LAST_PIC = 0x7376F102, /* debug get last pic status */ eCMD_TS_READ_WRITE_MEM = 0x7376F104, /* debug read write memory */ @@ -364,6 +358,6 @@ typedef enum { eNOTIFY_C011_ENC_CHAN_EVENT = eCMD_C011_CMD_BASE + 0x210, -} eC011_TS_CMD; +}; #endif diff --git a/drivers/staging/crystalhd/crystalhd_hw.c b/drivers/staging/crystalhd/crystalhd_hw.c index 56d1e42bbad6..f63185790c48 100644 --- a/drivers/staging/crystalhd/crystalhd_hw.c +++ b/drivers/staging/crystalhd/crystalhd_hw.c @@ -61,8 +61,8 @@ static void crystalhd_start_dram(struct crystalhd_adp *adp) static bool crystalhd_bring_out_of_rst(struct crystalhd_adp *adp) { - link_misc_perst_deco_ctrl rst_deco_cntrl; - link_misc_perst_clk_ctrl rst_clk_cntrl; + union link_misc_perst_deco_ctrl rst_deco_cntrl; + union link_misc_perst_clk_ctrl rst_clk_cntrl; uint32_t temp; /* @@ -122,8 +122,8 @@ static bool crystalhd_bring_out_of_rst(struct crystalhd_adp *adp) static bool crystalhd_put_in_reset(struct crystalhd_adp *adp) { - link_misc_perst_deco_ctrl rst_deco_cntrl; - link_misc_perst_clk_ctrl rst_clk_cntrl; + union link_misc_perst_deco_ctrl rst_deco_cntrl; + union link_misc_perst_clk_ctrl rst_clk_cntrl; uint32_t temp; /* @@ -178,7 +178,7 @@ static bool crystalhd_put_in_reset(struct crystalhd_adp *adp) static void crystalhd_disable_interrupts(struct crystalhd_adp *adp) { - intr_mask_reg intr_mask; + union intr_mask_reg intr_mask; intr_mask.whole_reg = crystalhd_reg_rd(adp, INTR_INTR_MSK_STS_REG); intr_mask.mask_pcie_err = 1; intr_mask.mask_pcie_rbusmast_err = 1; @@ -194,7 +194,7 @@ static void crystalhd_disable_interrupts(struct crystalhd_adp *adp) static void crystalhd_enable_interrupts(struct crystalhd_adp *adp) { - intr_mask_reg intr_mask; + union intr_mask_reg intr_mask; intr_mask.whole_reg = crystalhd_reg_rd(adp, INTR_INTR_MSK_STS_REG); intr_mask.mask_pcie_err = 1; intr_mask.mask_pcie_rbusmast_err = 1; @@ -348,10 +348,10 @@ static bool crystalhd_stop_device(struct crystalhd_adp *adp) return true; } -static crystalhd_rx_dma_pkt *crystalhd_hw_alloc_rx_pkt(struct crystalhd_hw *hw) +static struct crystalhd_rx_dma_pkt *crystalhd_hw_alloc_rx_pkt(struct crystalhd_hw *hw) { unsigned long flags = 0; - crystalhd_rx_dma_pkt *temp = NULL; + struct crystalhd_rx_dma_pkt *temp = NULL; if (!hw) return NULL; @@ -370,7 +370,7 @@ static crystalhd_rx_dma_pkt *crystalhd_hw_alloc_rx_pkt(struct crystalhd_hw *hw) } static void crystalhd_hw_free_rx_pkt(struct crystalhd_hw *hw, - crystalhd_rx_dma_pkt *pkt) + struct crystalhd_rx_dma_pkt *pkt) { unsigned long flags = 0; @@ -406,7 +406,7 @@ static void crystalhd_tx_desc_rel_call_back(void *context, void *data) static void crystalhd_rx_pkt_rel_call_back(void *context, void *data) { struct crystalhd_hw *hw = (struct crystalhd_hw *)context; - crystalhd_rx_dma_pkt *pkt = (crystalhd_rx_dma_pkt *)data; + struct crystalhd_rx_dma_pkt *pkt = (struct crystalhd_rx_dma_pkt *)data; if (!pkt || !hw) { BCMLOG_ERR("Invalid arg - %p %p\n", hw, pkt); @@ -453,9 +453,9 @@ do { \ * TX - Active & Free * RX - Active, Ready and Free. */ -static BC_STATUS crystalhd_hw_create_ioqs(struct crystalhd_hw *hw) +static enum BC_STATUS crystalhd_hw_create_ioqs(struct crystalhd_hw *hw) { - BC_STATUS sts = BC_STS_SUCCESS; + enum BC_STATUS sts = BC_STS_SUCCESS; if (!hw) { BCMLOG_ERR("Invalid Arg!!\n"); @@ -523,10 +523,10 @@ static bool crystalhd_code_in_full(struct crystalhd_adp *adp, uint32_t needed_sz return false; } -static BC_STATUS crystalhd_hw_tx_req_complete(struct crystalhd_hw *hw, - uint32_t list_id, BC_STATUS cs) +static enum BC_STATUS crystalhd_hw_tx_req_complete(struct crystalhd_hw *hw, + uint32_t list_id, enum BC_STATUS cs) { - tx_dma_pkt *tx_req; + struct tx_dma_pkt *tx_req; if (!hw || !list_id) { BCMLOG_ERR("Invalid Arg..\n"); @@ -535,7 +535,7 @@ static BC_STATUS crystalhd_hw_tx_req_complete(struct crystalhd_hw *hw, hw->pwr_lock--; - tx_req = (tx_dma_pkt *)crystalhd_dioq_find_and_fetch(hw->tx_actq, list_id); + tx_req = (struct tx_dma_pkt *)crystalhd_dioq_find_and_fetch(hw->tx_actq, list_id); if (!tx_req) { if (cs != BC_STS_IO_USER_ABORT) BCMLOG_ERR("Find and Fetch Did not find req\n"); @@ -654,7 +654,7 @@ static void crystalhd_tx_isr(struct crystalhd_hw *hw, uint32_t int_sts) hw->stats.tx_errors++; } -static void crystalhd_hw_dump_desc(pdma_descriptor p_dma_desc, +static void crystalhd_hw_dump_desc(struct dma_descriptor *p_dma_desc, uint32_t ul_desc_index, uint32_t cnt) { uint32_t ix, ll = 0; @@ -682,15 +682,15 @@ static void crystalhd_hw_dump_desc(pdma_descriptor p_dma_desc, } -static BC_STATUS crystalhd_hw_fill_desc(crystalhd_dio_req *ioreq, - dma_descriptor *desc, +static enum BC_STATUS crystalhd_hw_fill_desc(struct crystalhd_dio_req *ioreq, + struct dma_descriptor *desc, dma_addr_t desc_paddr_base, uint32_t sg_cnt, uint32_t sg_st_ix, uint32_t sg_st_off, uint32_t xfr_sz) { uint32_t count = 0, ix = 0, sg_ix = 0, len = 0, last_desc_ix = 0; dma_addr_t desc_phy_addr = desc_paddr_base; - addr_64 addr_temp; + union addr_64 addr_temp; if (!ioreq || !desc || !desc_paddr_base || !xfr_sz || (!sg_cnt && !ioreq->uinfo.dir_tx)) { @@ -721,7 +721,7 @@ static BC_STATUS crystalhd_hw_fill_desc(crystalhd_dio_req *ioreq, desc[ix].dma_dir = ioreq->uinfo.dir_tx; /* Chain DMA descriptor. */ - addr_temp.full_addr = desc_phy_addr + sizeof(dma_descriptor); + addr_temp.full_addr = desc_phy_addr + sizeof(struct dma_descriptor); desc[ix].next_desc_addr_low = addr_temp.low_part; desc[ix].next_desc_addr_high = addr_temp.high_part; @@ -740,7 +740,7 @@ static BC_STATUS crystalhd_hw_fill_desc(crystalhd_dio_req *ioreq, crystalhd_hw_dump_desc(desc, ix, 1); count += len; - desc_phy_addr += sizeof(dma_descriptor); + desc_phy_addr += sizeof(struct dma_descriptor); } last_desc_ix = ix - 1; @@ -773,15 +773,15 @@ static BC_STATUS crystalhd_hw_fill_desc(crystalhd_dio_req *ioreq, return BC_STS_SUCCESS; } -static BC_STATUS crystalhd_xlat_sgl_to_dma_desc(crystalhd_dio_req *ioreq, - pdma_desc_mem pdesc_mem, +static enum BC_STATUS crystalhd_xlat_sgl_to_dma_desc(struct crystalhd_dio_req *ioreq, + struct dma_desc_mem *pdesc_mem, uint32_t *uv_desc_index) { - dma_descriptor *desc = NULL; + struct dma_descriptor *desc = NULL; dma_addr_t desc_paddr_base = 0; uint32_t sg_cnt = 0, sg_st_ix = 0, sg_st_off = 0; uint32_t xfr_sz = 0; - BC_STATUS sts = BC_STS_SUCCESS; + enum BC_STATUS sts = BC_STS_SUCCESS; /* Check params.. */ if (!ioreq || !pdesc_mem || !uv_desc_index) { @@ -821,7 +821,7 @@ static BC_STATUS crystalhd_xlat_sgl_to_dma_desc(crystalhd_dio_req *ioreq, /* Prepare for UV mapping.. */ desc = &pdesc_mem->pdma_desc_start[sg_cnt]; desc_paddr_base = pdesc_mem->phy_addr + - (sg_cnt * sizeof(dma_descriptor)); + (sg_cnt * sizeof(struct dma_descriptor)); /* Done with desc addr.. now update sg stuff.*/ sg_cnt = ioreq->sg_cnt - ioreq->uinfo.uv_sg_ix; @@ -858,7 +858,7 @@ static void crystalhd_start_tx_dma_engine(struct crystalhd_hw *hw) * Verify if the Stop generates a completion interrupt or not. * if it does not generate an interrupt, then add polling here. */ -static BC_STATUS crystalhd_stop_tx_dma_engine(struct crystalhd_hw *hw) +static enum BC_STATUS crystalhd_stop_tx_dma_engine(struct crystalhd_hw *hw) { uint32_t dma_cntrl, cnt = 30; uint32_t l1 = 1, l2 = 1; @@ -1021,7 +1021,7 @@ static bool crystalhd_rel_addr_to_pib_Q(struct crystalhd_hw *hw, uint32_t addr_t return true; } -static void cpy_pib_to_app(C011_PIB *src_pib, BC_PIC_INFO_BLOCK *dst_pib) +static void cpy_pib_to_app(struct c011_pib *src_pib, struct BC_PIC_INFO_BLOCK *dst_pib) { if (!src_pib || !dst_pib) { BCMLOG_ERR("Invalid Arguments\n"); @@ -1046,10 +1046,10 @@ static void cpy_pib_to_app(C011_PIB *src_pib, BC_PIC_INFO_BLOCK *dst_pib) static void crystalhd_hw_proc_pib(struct crystalhd_hw *hw) { unsigned int cnt; - C011_PIB src_pib; + struct c011_pib src_pib; uint32_t pib_addr, pib_cnt; - BC_PIC_INFO_BLOCK *AppPib; - crystalhd_rx_dma_pkt *rx_pkt = NULL; + struct BC_PIC_INFO_BLOCK *AppPib; + struct crystalhd_rx_dma_pkt *rx_pkt = NULL; pib_cnt = crystalhd_get_pib_avail_cnt(hw); @@ -1059,11 +1059,11 @@ static void crystalhd_hw_proc_pib(struct crystalhd_hw *hw) for (cnt = 0; cnt < pib_cnt; cnt++) { pib_addr = crystalhd_get_addr_from_pib_Q(hw); - crystalhd_mem_rd(hw->adp, pib_addr, sizeof(C011_PIB) / 4, + crystalhd_mem_rd(hw->adp, pib_addr, sizeof(struct c011_pib) / 4, (uint32_t *)&src_pib); if (src_pib.bFormatChange) { - rx_pkt = (crystalhd_rx_dma_pkt *)crystalhd_dioq_fetch(hw->rx_freeq); + rx_pkt = (struct crystalhd_rx_dma_pkt *)crystalhd_dioq_fetch(hw->rx_freeq); if (!rx_pkt) return; rx_pkt->flags = 0; @@ -1168,11 +1168,11 @@ static void crystalhd_stop_rx_dma_engine(struct crystalhd_hw *hw) count, hw->rx_list_sts[0], hw->rx_list_sts[1]); } -static BC_STATUS crystalhd_hw_prog_rxdma(struct crystalhd_hw *hw, crystalhd_rx_dma_pkt *rx_pkt) +static enum BC_STATUS crystalhd_hw_prog_rxdma(struct crystalhd_hw *hw, struct crystalhd_rx_dma_pkt *rx_pkt) { uint32_t y_low_addr_reg, y_high_addr_reg; uint32_t uv_low_addr_reg, uv_high_addr_reg; - addr_64 desc_addr; + union addr_64 desc_addr; unsigned long flags; if (!hw || !rx_pkt) { @@ -1228,10 +1228,10 @@ static BC_STATUS crystalhd_hw_prog_rxdma(struct crystalhd_hw *hw, crystalhd_rx_d return BC_STS_SUCCESS; } -static BC_STATUS crystalhd_hw_post_cap_buff(struct crystalhd_hw *hw, - crystalhd_rx_dma_pkt *rx_pkt) +static enum BC_STATUS crystalhd_hw_post_cap_buff(struct crystalhd_hw *hw, + struct crystalhd_rx_dma_pkt *rx_pkt) { - BC_STATUS sts = crystalhd_hw_prog_rxdma(hw, rx_pkt); + enum BC_STATUS sts = crystalhd_hw_prog_rxdma(hw, rx_pkt); if (sts == BC_STS_BUSY) crystalhd_dioq_add(hw->rx_freeq, (void *)rx_pkt, @@ -1287,12 +1287,12 @@ static void crystalhd_hw_finalize_pause(struct crystalhd_hw *hw) crystalhd_reg_wr(hw->adp, PCIE_DLL_DATA_LINK_CONTROL, aspm); } -static BC_STATUS crystalhd_rx_pkt_done(struct crystalhd_hw *hw, uint32_t list_index, - BC_STATUS comp_sts) +static enum BC_STATUS crystalhd_rx_pkt_done(struct crystalhd_hw *hw, uint32_t list_index, + enum BC_STATUS comp_sts) { - crystalhd_rx_dma_pkt *rx_pkt = NULL; + struct crystalhd_rx_dma_pkt *rx_pkt = NULL; uint32_t y_dw_dnsz, uv_dw_dnsz; - BC_STATUS sts = BC_STS_SUCCESS; + enum BC_STATUS sts = BC_STS_SUCCESS; if (!hw || list_index >= DMA_ENGINE_CNT) { BCMLOG_ERR("Invalid Arguments\n"); @@ -1328,7 +1328,7 @@ static bool crystalhd_rx_list0_handler(struct crystalhd_hw *hw, uint32_t int_sts uint32_t y_err_sts, uint32_t uv_err_sts) { uint32_t tmp; - list_sts tmp_lsts; + enum list_sts tmp_lsts; if (!(y_err_sts & GET_Y0_ERR_MSK) && !(uv_err_sts & GET_UV0_ERR_MSK)) return false; @@ -1396,7 +1396,7 @@ static bool crystalhd_rx_list1_handler(struct crystalhd_hw *hw, uint32_t int_sts uint32_t y_err_sts, uint32_t uv_err_sts) { uint32_t tmp; - list_sts tmp_lsts; + enum list_sts tmp_lsts; if (!(y_err_sts & GET_Y1_ERR_MSK) && !(uv_err_sts & GET_UV1_ERR_MSK)) return false; @@ -1467,7 +1467,7 @@ static void crystalhd_rx_isr(struct crystalhd_hw *hw, uint32_t intr_sts) { unsigned long flags; uint32_t i, list_avail = 0; - BC_STATUS comp_sts = BC_STS_NO_DATA; + enum BC_STATUS comp_sts = BC_STS_NO_DATA; uint32_t y_err_sts, uv_err_sts, y_dn_sz = 0, uv_dn_sz = 0; bool ret = 0; @@ -1535,15 +1535,15 @@ static void crystalhd_rx_isr(struct crystalhd_hw *hw, uint32_t intr_sts) } } -static BC_STATUS crystalhd_fw_cmd_post_proc(struct crystalhd_hw *hw, - BC_FW_CMD *fw_cmd) +static enum BC_STATUS crystalhd_fw_cmd_post_proc(struct crystalhd_hw *hw, + struct BC_FW_CMD *fw_cmd) { - BC_STATUS sts = BC_STS_SUCCESS; - DecRspChannelStartVideo *st_rsp = NULL; + enum BC_STATUS sts = BC_STS_SUCCESS; + struct dec_rsp_channel_start_video *st_rsp = NULL; switch (fw_cmd->cmd[0]) { case eCMD_C011_DEC_CHAN_START_VIDEO: - st_rsp = (DecRspChannelStartVideo *)fw_cmd->rsp; + st_rsp = (struct dec_rsp_channel_start_video *)fw_cmd->rsp; hw->pib_del_Q_addr = st_rsp->picInfoDeliveryQ; hw->pib_rel_Q_addr = st_rsp->picInfoReleaseQ; BCMLOG(BCMLOG_DBG, "DelQAddr:%x RelQAddr:%x\n", @@ -1561,10 +1561,10 @@ static BC_STATUS crystalhd_fw_cmd_post_proc(struct crystalhd_hw *hw, return sts; } -static BC_STATUS crystalhd_put_ddr2sleep(struct crystalhd_hw *hw) +static enum BC_STATUS crystalhd_put_ddr2sleep(struct crystalhd_hw *hw) { uint32_t reg; - link_misc_perst_decoder_ctrl rst_cntrl_reg; + union link_misc_perst_decoder_ctrl rst_cntrl_reg; /* Pulse reset pin of 7412 (MISC_PERST_DECODER_CTRL) */ rst_cntrl_reg.whole_reg = crystalhd_reg_rd(hw->adp, MISC_PERST_DECODER_CTRL); @@ -1622,7 +1622,7 @@ static BC_STATUS crystalhd_put_ddr2sleep(struct crystalhd_hw *hw) ** *************************************************/ -BC_STATUS crystalhd_download_fw(struct crystalhd_adp *adp, void *buffer, uint32_t sz) +enum BC_STATUS crystalhd_download_fw(struct crystalhd_adp *adp, void *buffer, uint32_t sz) { uint32_t reg_data, cnt, *temp_buff; uint32_t fw_sig_len = 36; @@ -1714,13 +1714,14 @@ BC_STATUS crystalhd_download_fw(struct crystalhd_adp *adp, void *buffer, uint32_ return BC_STS_SUCCESS;; } -BC_STATUS crystalhd_do_fw_cmd(struct crystalhd_hw *hw, BC_FW_CMD *fw_cmd) +enum BC_STATUS crystalhd_do_fw_cmd(struct crystalhd_hw *hw, + struct BC_FW_CMD *fw_cmd) { uint32_t cnt = 0, cmd_res_addr; uint32_t *cmd_buff, *res_buff; wait_queue_head_t fw_cmd_event; int rc = 0; - BC_STATUS sts; + enum BC_STATUS sts; crystalhd_create_event(&fw_cmd_event); @@ -1854,7 +1855,7 @@ bool crystalhd_hw_interrupt(struct crystalhd_adp *adp, struct crystalhd_hw *hw) return rc; } -BC_STATUS crystalhd_hw_open(struct crystalhd_hw *hw, struct crystalhd_adp *adp) +enum BC_STATUS crystalhd_hw_open(struct crystalhd_hw *hw, struct crystalhd_adp *adp) { if (!hw || !adp) { BCMLOG_ERR("Invalid Arguments\n"); @@ -1886,7 +1887,7 @@ BC_STATUS crystalhd_hw_open(struct crystalhd_hw *hw, struct crystalhd_adp *adp) return BC_STS_SUCCESS; } -BC_STATUS crystalhd_hw_close(struct crystalhd_hw *hw) +enum BC_STATUS crystalhd_hw_close(struct crystalhd_hw *hw) { if (!hw) { BCMLOG_ERR("Invalid Arguments\n"); @@ -1903,14 +1904,14 @@ BC_STATUS crystalhd_hw_close(struct crystalhd_hw *hw) return BC_STS_SUCCESS; } -BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *hw) +enum BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *hw) { unsigned int i; void *mem; size_t mem_len; dma_addr_t phy_addr; - BC_STATUS sts = BC_STS_SUCCESS; - crystalhd_rx_dma_pkt *rpkt; + enum BC_STATUS sts = BC_STS_SUCCESS; + struct crystalhd_rx_dma_pkt *rpkt; if (!hw || !hw->adp) { BCMLOG_ERR("Invalid Arguments\n"); @@ -1923,7 +1924,7 @@ BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *hw) return sts; } - mem_len = BC_LINK_MAX_SGLS * sizeof(dma_descriptor); + mem_len = BC_LINK_MAX_SGLS * sizeof(struct dma_descriptor); for (i = 0; i < BC_TX_LIST_CNT; i++) { mem = bc_kern_dma_alloc(hw->adp, mem_len, &phy_addr); @@ -1938,7 +1939,7 @@ BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *hw) hw->tx_pkt_pool[i].desc_mem.pdma_desc_start = mem; hw->tx_pkt_pool[i].desc_mem.phy_addr = phy_addr; hw->tx_pkt_pool[i].desc_mem.sz = BC_LINK_MAX_SGLS * - sizeof(dma_descriptor); + sizeof(struct dma_descriptor); hw->tx_pkt_pool[i].list_tag = 0; /* Add TX dma requests to Free Queue..*/ @@ -1968,7 +1969,7 @@ BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *hw) } rpkt->desc_mem.pdma_desc_start = mem; rpkt->desc_mem.phy_addr = phy_addr; - rpkt->desc_mem.sz = BC_LINK_MAX_SGLS * sizeof(dma_descriptor); + rpkt->desc_mem.sz = BC_LINK_MAX_SGLS * sizeof(struct dma_descriptor); rpkt->pkt_tag = hw->rx_pkt_tag_seed + i; crystalhd_hw_free_rx_pkt(hw, rpkt); } @@ -1976,10 +1977,10 @@ BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *hw) return BC_STS_SUCCESS; } -BC_STATUS crystalhd_hw_free_dma_rings(struct crystalhd_hw *hw) +enum BC_STATUS crystalhd_hw_free_dma_rings(struct crystalhd_hw *hw) { unsigned int i; - crystalhd_rx_dma_pkt *rpkt = NULL; + struct crystalhd_rx_dma_pkt *rpkt = NULL; if (!hw || !hw->adp) { BCMLOG_ERR("Invalid Arguments\n"); @@ -2014,16 +2015,16 @@ BC_STATUS crystalhd_hw_free_dma_rings(struct crystalhd_hw *hw) return BC_STS_SUCCESS; } -BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw, crystalhd_dio_req *ioreq, +enum BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw, struct crystalhd_dio_req *ioreq, hw_comp_callback call_back, wait_queue_head_t *cb_event, uint32_t *list_id, uint8_t data_flags) { - tx_dma_pkt *tx_dma_packet = NULL; + struct tx_dma_pkt *tx_dma_packet = NULL; uint32_t first_desc_u_addr, first_desc_l_addr; uint32_t low_addr, high_addr; - addr_64 desc_addr; - BC_STATUS sts, add_sts; + union addr_64 desc_addr; + enum BC_STATUS sts, add_sts; uint32_t dummy_index = 0; unsigned long flags; bool rc; @@ -2048,7 +2049,7 @@ BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw, crystalhd_dio_req *ioreq } /* Get a list from TxFreeQ */ - tx_dma_packet = (tx_dma_pkt *)crystalhd_dioq_fetch(hw->tx_freeq); + tx_dma_packet = (struct tx_dma_pkt *)crystalhd_dioq_fetch(hw->tx_freeq); if (!tx_dma_packet) { BCMLOG_ERR("No empty elements..\n"); return BC_STS_ERR_USAGE; @@ -2121,7 +2122,7 @@ BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw, crystalhd_dio_req *ioreq * * FIX_ME: Not Tested the actual condition.. */ -BC_STATUS crystalhd_hw_cancel_tx(struct crystalhd_hw *hw, uint32_t list_id) +enum BC_STATUS crystalhd_hw_cancel_tx(struct crystalhd_hw *hw, uint32_t list_id) { if (!hw || !list_id) { BCMLOG_ERR("Invalid Arguments\n"); @@ -2134,12 +2135,12 @@ BC_STATUS crystalhd_hw_cancel_tx(struct crystalhd_hw *hw, uint32_t list_id) return BC_STS_SUCCESS; } -BC_STATUS crystalhd_hw_add_cap_buffer(struct crystalhd_hw *hw, - crystalhd_dio_req *ioreq, bool en_post) +enum BC_STATUS crystalhd_hw_add_cap_buffer(struct crystalhd_hw *hw, + struct crystalhd_dio_req *ioreq, bool en_post) { - crystalhd_rx_dma_pkt *rpkt; + struct crystalhd_rx_dma_pkt *rpkt; uint32_t tag, uv_desc_ix = 0; - BC_STATUS sts; + enum BC_STATUS sts; if (!hw || !ioreq) { BCMLOG_ERR("Invalid Arguments\n"); @@ -2164,7 +2165,7 @@ BC_STATUS crystalhd_hw_add_cap_buffer(struct crystalhd_hw *hw, /* Store the address of UV in the rx packet for post*/ if (uv_desc_ix) rpkt->uv_phy_addr = rpkt->desc_mem.phy_addr + - (sizeof(dma_descriptor) * (uv_desc_ix + 1)); + (sizeof(struct dma_descriptor) * (uv_desc_ix + 1)); if (en_post) sts = crystalhd_hw_post_cap_buff(hw, rpkt); @@ -2174,11 +2175,11 @@ BC_STATUS crystalhd_hw_add_cap_buffer(struct crystalhd_hw *hw, return sts; } -BC_STATUS crystalhd_hw_get_cap_buffer(struct crystalhd_hw *hw, - BC_PIC_INFO_BLOCK *pib, - crystalhd_dio_req **ioreq) +enum BC_STATUS crystalhd_hw_get_cap_buffer(struct crystalhd_hw *hw, + struct BC_PIC_INFO_BLOCK *pib, + struct crystalhd_dio_req **ioreq) { - crystalhd_rx_dma_pkt *rpkt; + struct crystalhd_rx_dma_pkt *rpkt; uint32_t timeout = BC_PROC_OUTPUT_TIMEOUT / 1000; uint32_t sig_pending = 0; @@ -2210,10 +2211,10 @@ BC_STATUS crystalhd_hw_get_cap_buffer(struct crystalhd_hw *hw, return BC_STS_SUCCESS; } -BC_STATUS crystalhd_hw_start_capture(struct crystalhd_hw *hw) +enum BC_STATUS crystalhd_hw_start_capture(struct crystalhd_hw *hw) { - crystalhd_rx_dma_pkt *rx_pkt; - BC_STATUS sts; + struct crystalhd_rx_dma_pkt *rx_pkt; + enum BC_STATUS sts; uint32_t i; if (!hw) { @@ -2235,7 +2236,7 @@ BC_STATUS crystalhd_hw_start_capture(struct crystalhd_hw *hw) return BC_STS_SUCCESS; } -BC_STATUS crystalhd_hw_stop_capture(struct crystalhd_hw *hw) +enum BC_STATUS crystalhd_hw_stop_capture(struct crystalhd_hw *hw) { void *temp = NULL; @@ -2255,7 +2256,7 @@ BC_STATUS crystalhd_hw_stop_capture(struct crystalhd_hw *hw) return BC_STS_SUCCESS; } -BC_STATUS crystalhd_hw_pause(struct crystalhd_hw *hw) +enum BC_STATUS crystalhd_hw_pause(struct crystalhd_hw *hw) { hw->stats.pause_cnt++; hw->stop_pending = 1; @@ -2267,9 +2268,9 @@ BC_STATUS crystalhd_hw_pause(struct crystalhd_hw *hw) return BC_STS_SUCCESS; } -BC_STATUS crystalhd_hw_unpause(struct crystalhd_hw *hw) +enum BC_STATUS crystalhd_hw_unpause(struct crystalhd_hw *hw) { - BC_STATUS sts; + enum BC_STATUS sts; uint32_t aspm; hw->stop_pending = 0; @@ -2283,9 +2284,9 @@ BC_STATUS crystalhd_hw_unpause(struct crystalhd_hw *hw) return sts; } -BC_STATUS crystalhd_hw_suspend(struct crystalhd_hw *hw) +enum BC_STATUS crystalhd_hw_suspend(struct crystalhd_hw *hw) { - BC_STATUS sts; + enum BC_STATUS sts; if (!hw) { BCMLOG_ERR("Invalid Arguments\n"); @@ -2324,7 +2325,7 @@ void crystalhd_hw_stats(struct crystalhd_hw *hw, struct crystalhd_hw_stats *stat memcpy(stats, &hw->stats, sizeof(*stats)); } -BC_STATUS crystalhd_hw_set_core_clock(struct crystalhd_hw *hw) +enum BC_STATUS crystalhd_hw_set_core_clock(struct crystalhd_hw *hw) { uint32_t reg, n, i; uint32_t vco_mg, refresh_reg; diff --git a/drivers/staging/crystalhd/crystalhd_hw.h b/drivers/staging/crystalhd/crystalhd_hw.h index 1c6318e912ac..3efbf9d4ff5d 100644 --- a/drivers/staging/crystalhd/crystalhd_hw.h +++ b/drivers/staging/crystalhd/crystalhd_hw.h @@ -109,7 +109,7 @@ #define DecHt_HostSwReset 0x340000 #define BC_DRAM_FW_CFG_ADDR 0x001c2000 -typedef union _addr_64_ { +union addr_64 { struct { uint32_t low_part; uint32_t high_part; @@ -117,9 +117,9 @@ typedef union _addr_64_ { uint64_t full_addr; -} addr_64; +}; -typedef union _intr_mask_reg_ { +union intr_mask_reg { struct { uint32_t mask_tx_done:1; uint32_t mask_tx_err:1; @@ -133,9 +133,9 @@ typedef union _intr_mask_reg_ { uint32_t whole_reg; -} intr_mask_reg; +}; -typedef union _link_misc_perst_deco_ctrl_ { +union link_misc_perst_deco_ctrl { struct { uint32_t bcm7412_rst:1; /* 1 -> BCM7412 is held in reset. Reset value 1.*/ uint32_t reserved0:3; /* Reserved.No Effect*/ @@ -145,9 +145,9 @@ typedef union _link_misc_perst_deco_ctrl_ { uint32_t whole_reg; -} link_misc_perst_deco_ctrl; +}; -typedef union _link_misc_perst_clk_ctrl_ { +union link_misc_perst_clk_ctrl { struct { uint32_t sel_alt_clk:1; /* When set, selects a 6.75MHz clock as the source of core_clk */ uint32_t stop_core_clk:1; /* When set, stops the branch of core_clk that is not needed for low power operation */ @@ -161,10 +161,9 @@ typedef union _link_misc_perst_clk_ctrl_ { uint32_t whole_reg; -} link_misc_perst_clk_ctrl; - +}; -typedef union _link_misc_perst_decoder_ctrl_ { +union link_misc_perst_decoder_ctrl { struct { uint32_t bcm_7412_rst:1; /* 1 -> BCM7412 is held in reset. Reset value 1.*/ uint32_t res0:3; /* Reserved.No Effect*/ @@ -174,10 +173,9 @@ typedef union _link_misc_perst_decoder_ctrl_ { uint32_t whole_reg; -} link_misc_perst_decoder_ctrl; - +}; -typedef union _desc_low_addr_reg_ { +union desc_low_addr_reg { struct { uint32_t list_valid:1; uint32_t reserved:4; @@ -186,9 +184,9 @@ typedef union _desc_low_addr_reg_ { uint32_t whole_reg; -} desc_low_addr_reg; +}; -typedef struct _dma_descriptor_ { /* 8 32-bit values */ +struct dma_descriptor { /* 8 32-bit values */ /* 0th u32 */ uint32_t sdram_buff_addr:28; /* bits 0-27: SDRAM Address */ uint32_t res0:4; /* bits 28-31: Reserved */ @@ -220,24 +218,22 @@ typedef struct _dma_descriptor_ { /* 8 32-bit values */ /* 7th u32 */ uint32_t res8; /* Last 32bits reserved */ -} dma_descriptor, *pdma_descriptor; +}; /* * We will allocate the memory in 4K pages * the linked list will be a list of 32 byte descriptors. * The virtual address will determine what should be freed. */ -typedef struct _dma_desc_mem_ { - pdma_descriptor pdma_desc_start; /* 32-bytes for dma descriptor. should be first element */ +struct dma_desc_mem { + struct dma_descriptor *pdma_desc_start; /* 32-bytes for dma descriptor. should be first element */ dma_addr_t phy_addr; /* physical address of each DMA desc */ uint32_t sz; struct _dma_desc_mem_ *Next; /* points to Next Descriptor in chain */ -} dma_desc_mem, *pdma_desc_mem; - - +}; -typedef enum _list_sts_ { +enum list_sts { sts_free = 0, /* RX-Y Bits 0:7 */ @@ -253,30 +249,27 @@ typedef enum _list_sts_ { rx_y_mask = 0x000000FF, rx_uv_mask = 0x0000FF00, +}; -} list_sts; - -typedef struct _tx_dma_pkt_ { - dma_desc_mem desc_mem; +struct tx_dma_pkt { + struct dma_desc_mem desc_mem; hw_comp_callback call_back; - crystalhd_dio_req *dio_req; + struct crystalhd_dio_req *dio_req; wait_queue_head_t *cb_event; uint32_t list_tag; +}; -} tx_dma_pkt; - -typedef struct _crystalhd_rx_dma_pkt { - dma_desc_mem desc_mem; - crystalhd_dio_req *dio_req; +struct crystalhd_rx_dma_pkt { + struct dma_desc_mem desc_mem; + struct crystalhd_dio_req *dio_req; uint32_t pkt_tag; uint32_t flags; - BC_PIC_INFO_BLOCK pib; + struct BC_PIC_INFO_BLOCK pib; dma_addr_t uv_phy_addr; - struct _crystalhd_rx_dma_pkt *next; - -} crystalhd_rx_dma_pkt; + struct crystalhd_rx_dma_pkt *next; +}; -struct crystalhd_hw_stats{ +struct crystalhd_hw_stats { uint32_t rx_errors; uint32_t tx_errors; uint32_t freeq_count; @@ -288,13 +281,13 @@ struct crystalhd_hw_stats{ }; struct crystalhd_hw { - tx_dma_pkt tx_pkt_pool[DMA_ENGINE_CNT]; + struct tx_dma_pkt tx_pkt_pool[DMA_ENGINE_CNT]; spinlock_t lock; uint32_t tx_ioq_tag_seed; uint32_t tx_list_post_index; - crystalhd_rx_dma_pkt *rx_pkt_pool_head; + struct crystalhd_rx_dma_pkt *rx_pkt_pool_head; uint32_t rx_pkt_tag_seed; bool dev_started; @@ -306,16 +299,16 @@ struct crystalhd_hw { uint32_t pib_del_Q_addr; uint32_t pib_rel_Q_addr; - crystalhd_dioq_t *tx_freeq; - crystalhd_dioq_t *tx_actq; + struct crystalhd_dioq *tx_freeq; + struct crystalhd_dioq *tx_actq; /* Rx DMA Engine Specific Locks */ spinlock_t rx_lock; uint32_t rx_list_post_index; - list_sts rx_list_sts[DMA_ENGINE_CNT]; - crystalhd_dioq_t *rx_rdyq; - crystalhd_dioq_t *rx_freeq; - crystalhd_dioq_t *rx_actq; + enum list_sts rx_list_sts[DMA_ENGINE_CNT]; + struct crystalhd_dioq *rx_rdyq; + struct crystalhd_dioq *rx_freeq; + struct crystalhd_dioq *rx_actq; uint32_t stop_pending; /* HW counters.. */ @@ -364,35 +357,35 @@ struct crystalhd_hw { /**** API Exposed to the other layers ****/ -BC_STATUS crystalhd_download_fw(struct crystalhd_adp *adp, +enum BC_STATUS crystalhd_download_fw(struct crystalhd_adp *adp, void *buffer, uint32_t sz); -BC_STATUS crystalhd_do_fw_cmd(struct crystalhd_hw *hw, BC_FW_CMD *fw_cmd); +enum BC_STATUS crystalhd_do_fw_cmd(struct crystalhd_hw *hw, struct BC_FW_CMD *fw_cmd); bool crystalhd_hw_interrupt(struct crystalhd_adp *adp, struct crystalhd_hw *hw); -BC_STATUS crystalhd_hw_open(struct crystalhd_hw *, struct crystalhd_adp *); -BC_STATUS crystalhd_hw_close(struct crystalhd_hw *); -BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *); -BC_STATUS crystalhd_hw_free_dma_rings(struct crystalhd_hw *); +enum BC_STATUS crystalhd_hw_open(struct crystalhd_hw *, struct crystalhd_adp *); +enum BC_STATUS crystalhd_hw_close(struct crystalhd_hw *); +enum BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *); +enum BC_STATUS crystalhd_hw_free_dma_rings(struct crystalhd_hw *); -BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw, crystalhd_dio_req *ioreq, +enum BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw, struct crystalhd_dio_req *ioreq, hw_comp_callback call_back, wait_queue_head_t *cb_event, uint32_t *list_id, uint8_t data_flags); -BC_STATUS crystalhd_hw_pause(struct crystalhd_hw *hw); -BC_STATUS crystalhd_hw_unpause(struct crystalhd_hw *hw); -BC_STATUS crystalhd_hw_suspend(struct crystalhd_hw *hw); -BC_STATUS crystalhd_hw_cancel_tx(struct crystalhd_hw *hw, uint32_t list_id); -BC_STATUS crystalhd_hw_add_cap_buffer(struct crystalhd_hw *hw, - crystalhd_dio_req *ioreq, bool en_post); -BC_STATUS crystalhd_hw_get_cap_buffer(struct crystalhd_hw *hw, - BC_PIC_INFO_BLOCK *pib, - crystalhd_dio_req **ioreq); -BC_STATUS crystalhd_hw_stop_capture(struct crystalhd_hw *hw); -BC_STATUS crystalhd_hw_start_capture(struct crystalhd_hw *hw); +enum BC_STATUS crystalhd_hw_pause(struct crystalhd_hw *hw); +enum BC_STATUS crystalhd_hw_unpause(struct crystalhd_hw *hw); +enum BC_STATUS crystalhd_hw_suspend(struct crystalhd_hw *hw); +enum BC_STATUS crystalhd_hw_cancel_tx(struct crystalhd_hw *hw, uint32_t list_id); +enum BC_STATUS crystalhd_hw_add_cap_buffer(struct crystalhd_hw *hw, + struct crystalhd_dio_req *ioreq, bool en_post); +enum BC_STATUS crystalhd_hw_get_cap_buffer(struct crystalhd_hw *hw, + struct BC_PIC_INFO_BLOCK *pib, + struct crystalhd_dio_req **ioreq); +enum BC_STATUS crystalhd_hw_stop_capture(struct crystalhd_hw *hw); +enum BC_STATUS crystalhd_hw_start_capture(struct crystalhd_hw *hw); void crystalhd_hw_stats(struct crystalhd_hw *hw, struct crystalhd_hw_stats *stats); /* API to program the core clock on the decoder */ -BC_STATUS crystalhd_hw_set_core_clock(struct crystalhd_hw *); +enum BC_STATUS crystalhd_hw_set_core_clock(struct crystalhd_hw *); #endif diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c index 141a3e38a835..a4ec891328cd 100644 --- a/drivers/staging/crystalhd/crystalhd_lnx.c +++ b/drivers/staging/crystalhd/crystalhd_lnx.c @@ -73,10 +73,10 @@ static int chd_dec_disable_int(struct crystalhd_adp *adp) return 0; } -crystalhd_ioctl_data *chd_dec_alloc_iodata(struct crystalhd_adp *adp, bool isr) +struct crystalhd_ioctl_data *chd_dec_alloc_iodata(struct crystalhd_adp *adp, bool isr) { unsigned long flags = 0; - crystalhd_ioctl_data *temp; + struct crystalhd_ioctl_data *temp; if (!adp) return NULL; @@ -93,7 +93,7 @@ crystalhd_ioctl_data *chd_dec_alloc_iodata(struct crystalhd_adp *adp, bool isr) return temp; } -void chd_dec_free_iodata(struct crystalhd_adp *adp, crystalhd_ioctl_data *iodata, +void chd_dec_free_iodata(struct crystalhd_adp *adp, struct crystalhd_ioctl_data *iodata, bool isr) { unsigned long flags = 0; @@ -129,7 +129,7 @@ static inline int crystalhd_user_data(unsigned long ud, void *dr, int size, int return rc; } -static int chd_dec_fetch_cdata(struct crystalhd_adp *adp, crystalhd_ioctl_data *io, +static int chd_dec_fetch_cdata(struct crystalhd_adp *adp, struct crystalhd_ioctl_data *io, uint32_t m_sz, unsigned long ua) { unsigned long ua_off; @@ -163,7 +163,7 @@ static int chd_dec_fetch_cdata(struct crystalhd_adp *adp, crystalhd_ioctl_data * } static int chd_dec_release_cdata(struct crystalhd_adp *adp, - crystalhd_ioctl_data *io, unsigned long ua) + struct crystalhd_ioctl_data *io, unsigned long ua) { unsigned long ua_off; int rc; @@ -193,7 +193,7 @@ static int chd_dec_release_cdata(struct crystalhd_adp *adp, } static int chd_dec_proc_user_data(struct crystalhd_adp *adp, - crystalhd_ioctl_data *io, + struct crystalhd_ioctl_data *io, unsigned long ua, int set) { int rc; @@ -231,8 +231,8 @@ static int chd_dec_api_cmd(struct crystalhd_adp *adp, unsigned long ua, uint32_t uid, uint32_t cmd, crystalhd_cmd_proc func) { int rc; - crystalhd_ioctl_data *temp; - BC_STATUS sts = BC_STS_SUCCESS; + struct crystalhd_ioctl_data *temp; + enum BC_STATUS sts = BC_STS_SUCCESS; temp = chd_dec_alloc_iodata(adp, 0); if (!temp) { @@ -296,7 +296,7 @@ static int chd_dec_open(struct inode *in, struct file *fd) { struct crystalhd_adp *adp = chd_get_adp(); int rc = 0; - BC_STATUS sts = BC_STS_SUCCESS; + enum BC_STATUS sts = BC_STS_SUCCESS; struct crystalhd_user *uc = NULL; BCMLOG_ENTER; @@ -356,7 +356,7 @@ static const struct file_operations chd_dec_fops = { static int __devinit chd_dec_init_chdev(struct crystalhd_adp *adp) { - crystalhd_ioctl_data *temp; + struct crystalhd_ioctl_data *temp; struct device *dev; int rc = -ENODEV, i = 0; @@ -394,7 +394,7 @@ static int __devinit chd_dec_init_chdev(struct crystalhd_adp *adp) /* Allocate general purpose ioctl pool. */ for (i = 0; i < CHD_IODATA_POOL_SZ; i++) { /* FIXME: jarod: why atomic? */ - temp = kzalloc(sizeof(crystalhd_ioctl_data), GFP_ATOMIC); + temp = kzalloc(sizeof(struct crystalhd_ioctl_data), GFP_ATOMIC); if (!temp) { BCMLOG_ERR("ioctl data pool kzalloc failed\n"); rc = -ENOMEM; @@ -418,7 +418,7 @@ fail: static void __devexit chd_dec_release_chdev(struct crystalhd_adp *adp) { - crystalhd_ioctl_data *temp = NULL; + struct crystalhd_ioctl_data *temp = NULL; if (!adp) return; @@ -513,7 +513,7 @@ static void __devexit chd_pci_release_mem(struct crystalhd_adp *pinfo) static void __devexit chd_dec_pci_remove(struct pci_dev *pdev) { struct crystalhd_adp *pinfo; - BC_STATUS sts = BC_STS_SUCCESS; + enum BC_STATUS sts = BC_STS_SUCCESS; BCMLOG_ENTER; @@ -543,7 +543,7 @@ static int __devinit chd_dec_pci_probe(struct pci_dev *pdev, { struct crystalhd_adp *pinfo; int rc; - BC_STATUS sts = BC_STS_SUCCESS; + enum BC_STATUS sts = BC_STS_SUCCESS; BCMLOG(BCMLOG_DBG, "PCI_INFO: Vendor:0x%04x Device:0x%04x " "s_vendor:0x%04x s_device: 0x%04x\n", @@ -623,8 +623,8 @@ static int __devinit chd_dec_pci_probe(struct pci_dev *pdev, int chd_dec_pci_suspend(struct pci_dev *pdev, pm_message_t state) { struct crystalhd_adp *adp; - crystalhd_ioctl_data *temp; - BC_STATUS sts = BC_STS_SUCCESS; + struct crystalhd_ioctl_data *temp; + enum BC_STATUS sts = BC_STS_SUCCESS; adp = (struct crystalhd_adp *)pci_get_drvdata(pdev); if (!adp) { @@ -657,7 +657,7 @@ int chd_dec_pci_suspend(struct pci_dev *pdev, pm_message_t state) int chd_dec_pci_resume(struct pci_dev *pdev) { struct crystalhd_adp *adp; - BC_STATUS sts = BC_STS_SUCCESS; + enum BC_STATUS sts = BC_STS_SUCCESS; int rc; adp = (struct crystalhd_adp *)pci_get_drvdata(pdev); diff --git a/drivers/staging/crystalhd/crystalhd_lnx.h b/drivers/staging/crystalhd/crystalhd_lnx.h index eee4926f04ea..c951e43cbb3d 100644 --- a/drivers/staging/crystalhd/crystalhd_lnx.h +++ b/drivers/staging/crystalhd/crystalhd_lnx.h @@ -79,12 +79,12 @@ struct crystalhd_adp { unsigned int chd_dec_major; unsigned int cfg_users; - crystalhd_ioctl_data *idata_free_head; /* ioctl data pool */ - crystalhd_elem_t *elem_pool_head; /* Queue element pool */ + struct crystalhd_ioctl_data *idata_free_head; /* ioctl data pool */ + struct crystalhd_elem *elem_pool_head; /* Queue element pool */ struct crystalhd_cmd cmds; - crystalhd_dio_req *ua_map_free_head; + struct crystalhd_dio_req *ua_map_free_head; struct pci_pool *fill_byte_pool; }; diff --git a/drivers/staging/crystalhd/crystalhd_misc.c b/drivers/staging/crystalhd/crystalhd_misc.c index 548dc09f2493..2c5138e4e1b5 100644 --- a/drivers/staging/crystalhd/crystalhd_misc.c +++ b/drivers/staging/crystalhd/crystalhd_misc.c @@ -43,15 +43,15 @@ static inline void crystalhd_dram_wr(struct crystalhd_adp *adp, uint32_t mem_off bc_dec_reg_wr(adp, (0x00380000 | (mem_off & 0x0007FFFF)), val); } -static inline BC_STATUS bc_chk_dram_range(struct crystalhd_adp *adp, uint32_t start_off, uint32_t cnt) +static inline enum BC_STATUS bc_chk_dram_range(struct crystalhd_adp *adp, uint32_t start_off, uint32_t cnt) { return BC_STS_SUCCESS; } -static crystalhd_dio_req *crystalhd_alloc_dio(struct crystalhd_adp *adp) +static struct crystalhd_dio_req *crystalhd_alloc_dio(struct crystalhd_adp *adp) { unsigned long flags = 0; - crystalhd_dio_req *temp = NULL; + struct crystalhd_dio_req *temp = NULL; if (!adp) { BCMLOG_ERR("Invalid Arg!!\n"); @@ -67,7 +67,7 @@ static crystalhd_dio_req *crystalhd_alloc_dio(struct crystalhd_adp *adp) return temp; } -static void crystalhd_free_dio(struct crystalhd_adp *adp, crystalhd_dio_req *dio) +static void crystalhd_free_dio(struct crystalhd_adp *adp, struct crystalhd_dio_req *dio) { unsigned long flags = 0; @@ -83,10 +83,10 @@ static void crystalhd_free_dio(struct crystalhd_adp *adp, crystalhd_dio_req *dio spin_unlock_irqrestore(&adp->lock, flags); } -static crystalhd_elem_t *crystalhd_alloc_elem(struct crystalhd_adp *adp) +static struct crystalhd_elem *crystalhd_alloc_elem(struct crystalhd_adp *adp) { unsigned long flags = 0; - crystalhd_elem_t *temp = NULL; + struct crystalhd_elem *temp = NULL; if (!adp) return temp; @@ -100,7 +100,7 @@ static crystalhd_elem_t *crystalhd_alloc_elem(struct crystalhd_adp *adp) return temp; } -static void crystalhd_free_elem(struct crystalhd_adp *adp, crystalhd_elem_t *elem) +static void crystalhd_free_elem(struct crystalhd_adp *adp, struct crystalhd_elem *elem) { unsigned long flags = 0; @@ -230,7 +230,7 @@ void crystalhd_reg_wr(struct crystalhd_adp *adp, uint32_t reg_off, uint32_t val) * * 7412's Dram read routine. */ -BC_STATUS crystalhd_mem_rd(struct crystalhd_adp *adp, uint32_t start_off, +enum BC_STATUS crystalhd_mem_rd(struct crystalhd_adp *adp, uint32_t start_off, uint32_t dw_cnt, uint32_t *rd_buff) { uint32_t ix = 0; @@ -258,7 +258,7 @@ BC_STATUS crystalhd_mem_rd(struct crystalhd_adp *adp, uint32_t start_off, * * 7412's Dram write routine. */ -BC_STATUS crystalhd_mem_wr(struct crystalhd_adp *adp, uint32_t start_off, +enum BC_STATUS crystalhd_mem_wr(struct crystalhd_adp *adp, uint32_t start_off, uint32_t dw_cnt, uint32_t *wr_buff) { uint32_t ix = 0; @@ -286,10 +286,10 @@ BC_STATUS crystalhd_mem_wr(struct crystalhd_adp *adp, uint32_t start_off, * * Get value from Link's PCIe config space. */ -BC_STATUS crystalhd_pci_cfg_rd(struct crystalhd_adp *adp, uint32_t off, +enum BC_STATUS crystalhd_pci_cfg_rd(struct crystalhd_adp *adp, uint32_t off, uint32_t len, uint32_t *val) { - BC_STATUS sts = BC_STS_SUCCESS; + enum BC_STATUS sts = BC_STS_SUCCESS; int rc = 0; if (!adp || !val) { @@ -331,10 +331,10 @@ BC_STATUS crystalhd_pci_cfg_rd(struct crystalhd_adp *adp, uint32_t off, * * Set value to Link's PCIe config space. */ -BC_STATUS crystalhd_pci_cfg_wr(struct crystalhd_adp *adp, uint32_t off, +enum BC_STATUS crystalhd_pci_cfg_wr(struct crystalhd_adp *adp, uint32_t off, uint32_t len, uint32_t val) { - BC_STATUS sts = BC_STS_SUCCESS; + enum BC_STATUS sts = BC_STS_SUCCESS; int rc = 0; if (!adp || !val) { @@ -429,11 +429,11 @@ void bc_kern_dma_free(struct crystalhd_adp *adp, uint32_t sz, void *ka, * Initialize Generic DIO queue to hold any data. Callback * will be used to free elements while deleting the queue. */ -BC_STATUS crystalhd_create_dioq(struct crystalhd_adp *adp, - crystalhd_dioq_t **dioq_hnd, +enum BC_STATUS crystalhd_create_dioq(struct crystalhd_adp *adp, + struct crystalhd_dioq **dioq_hnd, crystalhd_data_free_cb cb, void *cbctx) { - crystalhd_dioq_t *dioq = NULL; + struct crystalhd_dioq *dioq = NULL; if (!adp || !dioq_hnd) { BCMLOG_ERR("Invalid arg!!\n"); @@ -446,8 +446,8 @@ BC_STATUS crystalhd_create_dioq(struct crystalhd_adp *adp, spin_lock_init(&dioq->lock); dioq->sig = BC_LINK_DIOQ_SIG; - dioq->head = (crystalhd_elem_t *)&dioq->head; - dioq->tail = (crystalhd_elem_t *)&dioq->head; + dioq->head = (struct crystalhd_elem *)&dioq->head; + dioq->tail = (struct crystalhd_elem *)&dioq->head; crystalhd_create_event(&dioq->event); dioq->adp = adp; dioq->data_rel_cb = cb; @@ -470,7 +470,7 @@ BC_STATUS crystalhd_create_dioq(struct crystalhd_adp *adp, * by calling the call back provided during creation. * */ -void crystalhd_delete_dioq(struct crystalhd_adp *adp, crystalhd_dioq_t *dioq) +void crystalhd_delete_dioq(struct crystalhd_adp *adp, struct crystalhd_dioq *dioq) { void *temp; @@ -498,11 +498,11 @@ void crystalhd_delete_dioq(struct crystalhd_adp *adp, crystalhd_dioq_t *dioq) * * Insert new element to Q tail. */ -BC_STATUS crystalhd_dioq_add(crystalhd_dioq_t *ioq, void *data, +enum BC_STATUS crystalhd_dioq_add(struct crystalhd_dioq *ioq, void *data, bool wake, uint32_t tag) { unsigned long flags = 0; - crystalhd_elem_t *tmp; + struct crystalhd_elem *tmp; if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG) || !data) { BCMLOG_ERR("Invalid arg!!\n"); @@ -518,7 +518,7 @@ BC_STATUS crystalhd_dioq_add(crystalhd_dioq_t *ioq, void *data, tmp->data = data; tmp->tag = tag; spin_lock_irqsave(&ioq->lock, flags); - tmp->flink = (crystalhd_elem_t *)&ioq->head; + tmp->flink = (struct crystalhd_elem *)&ioq->head; tmp->blink = ioq->tail; tmp->flink->blink = tmp; tmp->blink->flink = tmp; @@ -540,11 +540,11 @@ BC_STATUS crystalhd_dioq_add(crystalhd_dioq_t *ioq, void *data, * * Remove an element from Queue. */ -void *crystalhd_dioq_fetch(crystalhd_dioq_t *ioq) +void *crystalhd_dioq_fetch(struct crystalhd_dioq *ioq) { unsigned long flags = 0; - crystalhd_elem_t *tmp; - crystalhd_elem_t *ret = NULL; + struct crystalhd_elem *tmp; + struct crystalhd_elem *ret = NULL; void *data = NULL; if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG)) { @@ -554,7 +554,7 @@ void *crystalhd_dioq_fetch(crystalhd_dioq_t *ioq) spin_lock_irqsave(&ioq->lock, flags); tmp = ioq->head; - if (tmp != (crystalhd_elem_t *)&ioq->head) { + if (tmp != (struct crystalhd_elem *)&ioq->head) { ret = tmp; tmp->flink->blink = tmp->blink; tmp->blink->flink = tmp->flink; @@ -578,11 +578,11 @@ void *crystalhd_dioq_fetch(crystalhd_dioq_t *ioq) * * Search TAG and remove the element. */ -void *crystalhd_dioq_find_and_fetch(crystalhd_dioq_t *ioq, uint32_t tag) +void *crystalhd_dioq_find_and_fetch(struct crystalhd_dioq *ioq, uint32_t tag) { unsigned long flags = 0; - crystalhd_elem_t *tmp; - crystalhd_elem_t *ret = NULL; + struct crystalhd_elem *tmp; + struct crystalhd_elem *ret = NULL; void *data = NULL; if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG)) { @@ -592,7 +592,7 @@ void *crystalhd_dioq_find_and_fetch(crystalhd_dioq_t *ioq, uint32_t tag) spin_lock_irqsave(&ioq->lock, flags); tmp = ioq->head; - while (tmp != (crystalhd_elem_t *)&ioq->head) { + while (tmp != (struct crystalhd_elem *)&ioq->head) { if (tmp->tag == tag) { ret = tmp; tmp->flink->blink = tmp->blink; @@ -623,7 +623,7 @@ void *crystalhd_dioq_find_and_fetch(crystalhd_dioq_t *ioq, uint32_t tag) * Return element from head if Q is not empty. Wait for new element * if Q is empty for Timeout seconds. */ -void *crystalhd_dioq_fetch_wait(crystalhd_dioq_t *ioq, uint32_t to_secs, +void *crystalhd_dioq_fetch_wait(struct crystalhd_dioq *ioq, uint32_t to_secs, uint32_t *sig_pend) { unsigned long flags = 0; @@ -673,12 +673,12 @@ out: * This routine maps user address and lock pages for DMA. * */ -BC_STATUS crystalhd_map_dio(struct crystalhd_adp *adp, void *ubuff, +enum BC_STATUS crystalhd_map_dio(struct crystalhd_adp *adp, void *ubuff, uint32_t ubuff_sz, uint32_t uv_offset, bool en_422mode, bool dir_tx, - crystalhd_dio_req **dio_hnd) + struct crystalhd_dio_req **dio_hnd) { - crystalhd_dio_req *dio; + struct crystalhd_dio_req *dio; /* FIXME: jarod: should some of these unsigned longs be uint32_t or uintptr_t? */ unsigned long start = 0, end = 0, uaddr = 0, count = 0; unsigned long spsz = 0, uv_start = 0; @@ -820,7 +820,7 @@ BC_STATUS crystalhd_map_dio(struct crystalhd_adp *adp, void *ubuff, * * This routine is to unmap the user buffer pages. */ -BC_STATUS crystalhd_unmap_dio(struct crystalhd_adp *adp, crystalhd_dio_req *dio) +enum BC_STATUS crystalhd_unmap_dio(struct crystalhd_adp *adp, struct crystalhd_dio_req *dio) { struct page *page = NULL; int j = 0; @@ -864,7 +864,7 @@ int crystalhd_create_dio_pool(struct crystalhd_adp *adp, uint32_t max_pages) { uint32_t asz = 0, i = 0; uint8_t *temp; - crystalhd_dio_req *dio; + struct crystalhd_dio_req *dio; if (!adp || !max_pages) { BCMLOG_ERR("Invalid Arg!!\n"); @@ -893,7 +893,7 @@ int crystalhd_create_dio_pool(struct crystalhd_adp *adp, uint32_t max_pages) return -ENOMEM; } - dio = (crystalhd_dio_req *)temp; + dio = (struct crystalhd_dio_req *)temp; temp += sizeof(*dio); dio->pages = (struct page **)temp; temp += (sizeof(*dio->pages) * max_pages); @@ -923,7 +923,7 @@ int crystalhd_create_dio_pool(struct crystalhd_adp *adp, uint32_t max_pages) */ void crystalhd_destroy_dio_pool(struct crystalhd_adp *adp) { - crystalhd_dio_req *dio; + struct crystalhd_dio_req *dio; int count = 0; if (!adp) { @@ -965,7 +965,7 @@ int __devinit crystalhd_create_elem_pool(struct crystalhd_adp *adp, uint32_t pool_size) { uint32_t i; - crystalhd_elem_t *temp; + struct crystalhd_elem *temp; if (!adp || !pool_size) return -EINVAL; @@ -993,7 +993,7 @@ int __devinit crystalhd_create_elem_pool(struct crystalhd_adp *adp, */ void crystalhd_delete_elem_pool(struct crystalhd_adp *adp) { - crystalhd_elem_t *temp; + struct crystalhd_elem *temp; int dbg_cnt = 0; if (!adp) diff --git a/drivers/staging/crystalhd/crystalhd_misc.h b/drivers/staging/crystalhd/crystalhd_misc.h index 84331cd33273..382078eafa03 100644 --- a/drivers/staging/crystalhd/crystalhd_misc.h +++ b/drivers/staging/crystalhd/crystalhd_misc.h @@ -54,7 +54,7 @@ extern uint32_t g_linklog_level; /* Scatter Gather memory pool size for Tx and Rx */ #define BC_LINK_SG_POOL_SZ (BC_TX_LIST_CNT + BC_RX_LIST_CNT) -enum _crystalhd_dio_sig { +enum crystalhd_dio_sig { crystalhd_dio_inv = 0, crystalhd_dio_locked, crystalhd_dio_sg_mapped, @@ -76,7 +76,7 @@ struct crystalhd_dio_user_info { bool b422mode; }; -typedef struct _crystalhd_dio_req { +struct crystalhd_dio_req { uint32_t sig; uint32_t max_pages; struct page **pages; @@ -88,34 +88,34 @@ typedef struct _crystalhd_dio_req { void *fb_va; uint32_t fb_size; dma_addr_t fb_pa; - struct _crystalhd_dio_req *next; -} crystalhd_dio_req; + struct crystalhd_dio_req *next; +}; #define BC_LINK_DIOQ_SIG (0x09223280) -typedef struct _crystalhd_elem_s { - struct _crystalhd_elem_s *flink; - struct _crystalhd_elem_s *blink; +struct crystalhd_elem { + struct crystalhd_elem *flink; + struct crystalhd_elem *blink; void *data; uint32_t tag; -} crystalhd_elem_t; +}; typedef void (*crystalhd_data_free_cb)(void *context, void *data); -typedef struct _crystalhd_dioq_s { +struct crystalhd_dioq { uint32_t sig; struct crystalhd_adp *adp; - crystalhd_elem_t *head; - crystalhd_elem_t *tail; + struct crystalhd_elem *head; + struct crystalhd_elem *tail; uint32_t count; spinlock_t lock; wait_queue_head_t event; crystalhd_data_free_cb data_rel_cb; void *cb_context; -} crystalhd_dioq_t; +}; -typedef void (*hw_comp_callback)(crystalhd_dio_req *, - wait_queue_head_t *event, BC_STATUS sts); +typedef void (*hw_comp_callback)(struct crystalhd_dio_req *, + wait_queue_head_t *event, enum BC_STATUS sts); /*========= Decoder (7412) register access routines.================= */ uint32_t bc_dec_reg_rd(struct crystalhd_adp *, uint32_t); @@ -126,12 +126,12 @@ uint32_t crystalhd_reg_rd(struct crystalhd_adp *, uint32_t); void crystalhd_reg_wr(struct crystalhd_adp *, uint32_t, uint32_t); /*========= Decoder (7412) memory access routines..=================*/ -BC_STATUS crystalhd_mem_rd(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *); -BC_STATUS crystalhd_mem_wr(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *); +enum BC_STATUS crystalhd_mem_rd(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *); +enum BC_STATUS crystalhd_mem_wr(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *); /*==========Link (70012) PCIe Config access routines.================*/ -BC_STATUS crystalhd_pci_cfg_rd(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *); -BC_STATUS crystalhd_pci_cfg_wr(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t); +enum BC_STATUS crystalhd_pci_cfg_rd(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *); +enum BC_STATUS crystalhd_pci_cfg_wr(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t); /*========= Linux Kernel Interface routines. ======================= */ void *bc_kern_dma_alloc(struct crystalhd_adp *, uint32_t, dma_addr_t *); @@ -167,20 +167,20 @@ do { \ /*================ Direct IO mapping routines ==================*/ extern int crystalhd_create_dio_pool(struct crystalhd_adp *, uint32_t); extern void crystalhd_destroy_dio_pool(struct crystalhd_adp *); -extern BC_STATUS crystalhd_map_dio(struct crystalhd_adp *, void *, uint32_t, - uint32_t, bool, bool, crystalhd_dio_req**); +extern enum BC_STATUS crystalhd_map_dio(struct crystalhd_adp *, void *, uint32_t, + uint32_t, bool, bool, struct crystalhd_dio_req**); -extern BC_STATUS crystalhd_unmap_dio(struct crystalhd_adp *, crystalhd_dio_req*); +extern enum BC_STATUS crystalhd_unmap_dio(struct crystalhd_adp *, struct crystalhd_dio_req*); #define crystalhd_get_sgle_paddr(_dio, _ix) (cpu_to_le64(sg_dma_address(&_dio->sg[_ix]))) #define crystalhd_get_sgle_len(_dio, _ix) (cpu_to_le32(sg_dma_len(&_dio->sg[_ix]))) /*================ General Purpose Queues ==================*/ -extern BC_STATUS crystalhd_create_dioq(struct crystalhd_adp *, crystalhd_dioq_t **, crystalhd_data_free_cb , void *); -extern void crystalhd_delete_dioq(struct crystalhd_adp *, crystalhd_dioq_t *); -extern BC_STATUS crystalhd_dioq_add(crystalhd_dioq_t *ioq, void *data, bool wake, uint32_t tag); -extern void *crystalhd_dioq_fetch(crystalhd_dioq_t *ioq); -extern void *crystalhd_dioq_find_and_fetch(crystalhd_dioq_t *ioq, uint32_t tag); -extern void *crystalhd_dioq_fetch_wait(crystalhd_dioq_t *ioq, uint32_t to_secs, uint32_t *sig_pend); +extern enum BC_STATUS crystalhd_create_dioq(struct crystalhd_adp *, struct crystalhd_dioq **, crystalhd_data_free_cb , void *); +extern void crystalhd_delete_dioq(struct crystalhd_adp *, struct crystalhd_dioq *); +extern enum BC_STATUS crystalhd_dioq_add(struct crystalhd_dioq *ioq, void *data, bool wake, uint32_t tag); +extern void *crystalhd_dioq_fetch(struct crystalhd_dioq *ioq); +extern void *crystalhd_dioq_find_and_fetch(struct crystalhd_dioq *ioq, uint32_t tag); +extern void *crystalhd_dioq_fetch_wait(struct crystalhd_dioq *ioq, uint32_t to_secs, uint32_t *sig_pend); #define crystalhd_dioq_count(_ioq) ((_ioq) ? _ioq->count : 0) -- cgit v1.2.3 From a57941c2e7a79d5143a63c06c06be36f786d5241 Mon Sep 17 00:00:00 2001 From: Marin Mitov Date: Tue, 18 May 2010 13:05:29 +0300 Subject: Staging: dt3155v4l: remove private memory allocator This patch removes the private memory allocator and all conjugated functions. Now the driver uses videobuf-dma-contig module for allocations. Added reserving 4MB coherent memory for private per device allocations at probe time. Signed-off-by: Marin Mitov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dt3155v4l/Kconfig | 2 +- drivers/staging/dt3155v4l/Makefile | 5 +- drivers/staging/dt3155v4l/dt3155-bufs.c | 256 -------------- drivers/staging/dt3155v4l/dt3155-bufs.h | 88 ----- drivers/staging/dt3155v4l/dt3155v4l.c | 603 ++++++-------------------------- drivers/staging/dt3155v4l/dt3155v4l.h | 4 +- 6 files changed, 107 insertions(+), 851 deletions(-) delete mode 100644 drivers/staging/dt3155v4l/dt3155-bufs.c delete mode 100644 drivers/staging/dt3155v4l/dt3155-bufs.h (limited to 'drivers') diff --git a/drivers/staging/dt3155v4l/Kconfig b/drivers/staging/dt3155v4l/Kconfig index f49f4ac035b0..5cd5a575b64d 100644 --- a/drivers/staging/dt3155v4l/Kconfig +++ b/drivers/staging/dt3155v4l/Kconfig @@ -9,7 +9,7 @@ config VIDEO_DT3155 In doubt, say N. To compile this driver as a module, choose M here: the - module will be called dt3155_v4l. + module will be called dt3155v4l. config DT3155_CCIR bool "Selects CCIR/50Hz vertical refresh" diff --git a/drivers/staging/dt3155v4l/Makefile b/drivers/staging/dt3155v4l/Makefile index 3a207ccd3143..ce7a3ec2faf3 100644 --- a/drivers/staging/dt3155v4l/Makefile +++ b/drivers/staging/dt3155v4l/Makefile @@ -1,4 +1 @@ -obj-$(CONFIG_VIDEO_DT3155) += dt3155_v4l.o -dt3155_v4l-objs := \ - dt3155-bufs.o \ - dt3155v4l.o +obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l.o diff --git a/drivers/staging/dt3155v4l/dt3155-bufs.c b/drivers/staging/dt3155v4l/dt3155-bufs.c deleted file mode 100644 index f93e431e786b..000000000000 --- a/drivers/staging/dt3155v4l/dt3155-bufs.c +++ /dev/null @@ -1,256 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006-2010 by Marin Mitov * - * mitov@issp.bas.bg * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#include "dt3155-bufs.h" - -/** - * dt3155_init_chunks_buf - creates a chunk buffer and allocates memory for it - * - * returns: a pointer to the struct dt3155_buf or NULL if failed - * - * Creates a struct dt3155_buf, then allocates a chunk of memory of - * size DT3155_CHUNK_SIZE and sets all the pages in it as Reserved. - * This is done to be able to use remap_pfn_range() on these buffers - * (which do not work on normal memory if Reserved bit is not set) - */ -struct dt3155_buf * -dt3155_init_chunks_buf(void) -{ /* could sleep */ - struct dt3155_buf *buf; - int i; - - buf = kzalloc(sizeof(*buf), GFP_KERNEL); - if (!buf) - return NULL; - buf->cpu = (void *)__get_free_pages(DT3155_CHUNK_FLAGS, - get_order(DT3155_CHUNK_SIZE)); - if (!buf->cpu) { - kfree(buf); - return NULL; - } - for (i = 0; i < DT3155_CHUNK_SIZE; i += PAGE_SIZE) - SetPageReserved(virt_to_page(buf->cpu + i)); - return buf; /* success */ -} - -/** - * dt3155_free_chunks_buf - destroys the specified buffer - * - * @buf: the buffer to be freed - * - * Clears Reserved bit of all pages in the chunk, frees the chunk memory - * and destroys struct dt3155_buf. - */ -void -dt3155_free_chunks_buf(struct dt3155_buf *buf) -{ - int i; - - for (i = 0; i < DT3155_CHUNK_SIZE; i += PAGE_SIZE) - ClearPageReserved(virt_to_page(buf->cpu + i)); - free_pages((unsigned long)buf->cpu, get_order(DT3155_CHUNK_SIZE)); - kfree(buf); -} - -/** - * dt3155_init_fifo - creates and initializes a fifo - * - * returns: a pointer to the crated and initialized struct dt3155_fifo - * or NULL if failed - */ -struct dt3155_fifo * -dt3155_init_fifo(void) -{ /* could sleep */ - struct dt3155_fifo *fifo = kzalloc(sizeof(*fifo), GFP_KERNEL); - if (fifo) - spin_lock_init(&fifo->lock); - return fifo; -} - -/* dt3155_free_fifo(x) defined as macro in dt3155.h */ - -/** - * dt3155_get_buf - gets a buffer from the fifo - * - * @fifo: the fifo to get a buffer from - * - * returns: a pointer to the buffer or NULL if failed - * - * dt3155_get_buf gets the fifo's spin_lock and returns the - * buffer pointed by the head. Could be used in any context. - */ -struct dt3155_buf * -dt3155_get_buf(struct dt3155_fifo *fifo) -{ - unsigned long flags; - struct dt3155_buf *tmp_buf; - - spin_lock_irqsave(&fifo->lock, flags); - tmp_buf = fifo->head; - if (fifo->head) - fifo->head = fifo->head->next; - if (!fifo->head) - fifo->tail = NULL; - spin_unlock_irqrestore(&fifo->lock, flags); - return tmp_buf; -} - -/** - * dt3155_put_buf - puts a buffer into a fifo - * - * @buf: the buffer to put - * @fifo: the fifo to put the buffer in - * - * dt3155_put_buf gets the fifo's spin_lock and puts the buf - * at the tail of the fifo. Could be used in any context. - */ -void -dt3155_put_buf(struct dt3155_buf *buf, struct dt3155_fifo *fifo) -{ - unsigned long flags; - - spin_lock_irqsave(&fifo->lock, flags); - buf->next = NULL; - if (fifo->tail) - fifo->tail->next = buf; - fifo->tail = buf; - if (!fifo->head) - fifo->head = buf; - spin_unlock_irqrestore(&fifo->lock, flags); -} - -/** - * dt3155_init_chunks_fifo - creates and fills a chunks_fifo - * - * returns: a pointer to the fifo or NULL if failed - * - * dt3155_init_chunks_fifo creates and fills the fifo with - * a number of chunks <= DT3155_CHUNK_NUM. The returned fifo - * contains at least one chunk. - */ -struct dt3155_fifo * -dt3155_init_chunks_fifo(void) -{ /* could sleep */ - int i; - - struct dt3155_fifo *chunks; - struct dt3155_buf *tmp_buf; - - chunks = dt3155_init_fifo(); - if (!chunks) - return NULL; - tmp_buf = dt3155_init_chunks_buf(); - if (!tmp_buf) { - dt3155_free_fifo(chunks); - return NULL; - } - dt3155_put_buf(tmp_buf, chunks); - for (i = 1; i < DT3155_CHUNK_NUM; i++) { - tmp_buf = dt3155_init_chunks_buf(); - if (!tmp_buf) - break; - dt3155_put_buf(tmp_buf, chunks); - } - return chunks; -} - -/** - * dt3155_free_chunks_fifo - empties and destroys the chunks_fifo - * - * @chunks: the chunks_fifo to be freed - * - * dt3155_free_chunks_fifo deallocates all chunks in the fifo and - * destroys it. - */ -void -dt3155_free_chunks_fifo(struct dt3155_fifo *chunks) -{ - int buf_count = 0; - struct dt3155_buf *buf; - - while ((buf = dt3155_get_buf(chunks))) { - dt3155_free_chunks_buf(buf); - buf_count++; - } - dt3155_free_fifo(chunks); - printk(KERN_INFO "dt3155: %i chunks freed\n", buf_count); -} - -/** - * dt3155_init_ibufs_fifo - creates and fills an image buffer fifo - * - * @chunks: chunks_fifo to take memory from - * @buf_size: the size of image buffers - * - * returns: a pointer to the fifo filled with image buffers - * - * dt3155_init_ibufs_fifo takes chunks from chunks_fifo, chops them - * into pieces of size buf_size and fills image fifo with them. - */ -struct dt3155_fifo * -dt3155_init_ibufs_fifo(struct dt3155_fifo *chunks, int buf_size) -{ /* could sleep */ - int i, buf_count = 0; - struct dt3155_buf *tmp_ibuf, *chunks_buf, *last_chunk; - struct dt3155_fifo *tmp_fifo; - - tmp_fifo = dt3155_init_fifo(); - if (!tmp_fifo) - return NULL; - last_chunk = chunks->tail; - do { - chunks_buf = dt3155_get_buf(chunks); - dt3155_put_buf(chunks_buf, chunks); - for (i = 0; i < DT3155_CHUNK_SIZE / buf_size; i++) { - tmp_ibuf = kzalloc(sizeof(*tmp_ibuf), GFP_KERNEL); - if (tmp_ibuf) { - tmp_ibuf->cpu = - chunks_buf->cpu + DT3155_BUF_SIZE * i; - dt3155_put_buf(tmp_ibuf, tmp_fifo); - buf_count++; - } else { - if (buf_count) { - goto print_num_bufs; - } else { - dt3155_free_fifo(tmp_fifo); - return NULL; - } - } - } - } while (chunks_buf != last_chunk); -print_num_bufs: - printk(KERN_INFO "dt3155: %i image buffers available\n", buf_count); - return tmp_fifo; -} - -/** - * dt3155_free_ibufs_fifo - empties and destroys an image fifo - * - * @fifo: the fifo to free - */ -void -dt3155_free_ibufs_fifo(struct dt3155_fifo *fifo) -{ - struct dt3155_buf *tmp_ibuf; - - while ((tmp_ibuf = dt3155_get_buf(fifo))) - kfree(tmp_ibuf); - kfree(fifo); -} diff --git a/drivers/staging/dt3155v4l/dt3155-bufs.h b/drivers/staging/dt3155v4l/dt3155-bufs.h deleted file mode 100644 index db6d387231b2..000000000000 --- a/drivers/staging/dt3155v4l/dt3155-bufs.h +++ /dev/null @@ -1,88 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006-2010 by Marin Mitov * - * mitov@issp.bas.bg * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#ifndef _DT3155_BUFS_H_ -#define _DT3155_BUFS_H_ - -#include - -/* 4 chunks of 4MB, 9 buffers each = 36 buffers (> VIDEO_MAX_FRAME) */ -#define DT3155_CHUNK_NUM 4 - -/* DT3155_CHUNK_SIZE should be 4M (2^22) or less, but more than image size */ -#define DT3155_CHUNK_SIZE (1U << 22) -#define DT3155_CHUNK_FLAGS (GFP_KERNEL | GFP_DMA32 | __GFP_COLD | __GFP_NOWARN) - -/* DT3155_BUF_SIZE = 108 * PAGE_SIZE, so each buf is PAGE_SIZE alligned */ -#define DT3155_BUF_SIZE (768 * 576) - -/** - * struct dt3155_buf - image buffer structure - * - * @cpu: virtual kernel address of the buffer - * @dma: dma (bus) address of the buffer - * @next: pointer to the next buffer in the fifo - * @tv: time value when the image has been acquired - */ -struct dt3155_buf { - void *cpu; - dma_addr_t dma; - struct dt3155_buf *next; - struct timeval tv; -}; - -/** - * struct dt3155_fifo - fifo structure - * - * @head: pointer to the head of the fifo - * @tail: pionter to the tail of the fifo - * @lock: spin_lock to protect the fifo - */ -struct dt3155_fifo { - struct dt3155_buf *head; - struct dt3155_buf *tail; - spinlock_t lock; -}; - -struct dt3155_buf * __must_check -dt3155_init_chunks_buf(void); -void -dt3155_free_chunks_buf(struct dt3155_buf *buf); - -struct dt3155_fifo * __must_check -dt3155_init_fifo(void); -#define dt3155_free_fifo(x) kfree(x) - -struct dt3155_buf * __must_check -dt3155_get_buf(struct dt3155_fifo *fifo); -void -dt3155_put_buf(struct dt3155_buf *buf, struct dt3155_fifo *fifo); - -struct dt3155_fifo * __must_check -dt3155_init_chunks_fifo(void); -void -dt3155_free_chunks_fifo(struct dt3155_fifo *chunks); - -struct dt3155_fifo * __must_check -dt3155_init_ibufs_fifo(struct dt3155_fifo *chunks, int buf_size); -void -dt3155_free_ibufs_fifo(struct dt3155_fifo *fifo); - -#endif /* _DT3155_BUFS_H_ */ diff --git a/drivers/staging/dt3155v4l/dt3155v4l.c b/drivers/staging/dt3155v4l/dt3155v4l.c index 308fb45965b3..6dc3af622848 100644 --- a/drivers/staging/dt3155v4l/dt3155v4l.c +++ b/drivers/staging/dt3155v4l/dt3155v4l.c @@ -18,22 +18,26 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#include -#include -#include -#include #include #include #include -#include #include +#include +#include +#include #include "dt3155v4l.h" -#include "dt3155-bufs.h" #define DT3155_VENDOR_ID 0x8086 #define DT3155_DEVICE_ID 0x1223 +/* DT3155_CHUNK_SIZE is 4M (2^22) 8 full size buffers */ +#define DT3155_CHUNK_SIZE (1U << 22) + +#define DT3155_COH_FLAGS (GFP_KERNEL | GFP_DMA32 | __GFP_COLD | __GFP_NOWARN) + +#define DT3155_BUF_SIZE (768 * 576) + /* global initializers (for all boards) */ #ifdef CONFIG_DT3155_CCIR static const u8 csr2_init = VT_50HZ; @@ -190,441 +194,6 @@ static int wait_i2c_reg(void __iomem *addr) return 0; } -/* - * global pointers to a list of 4MB chunks reserved at driver - * load, broken down to contiguous buffers of 768 * 576 bytes - * each to form a pool of buffers for allocations - * FIXME: add spinlock to protect moves between alloc/free lists - */ -static struct dt3155_fifo *dt3155_chunks; /* list of 4MB chuncks */ -static struct dt3155_fifo *dt3155_free_bufs; /* list of free buffers */ -static struct dt3155_fifo *dt3155_alloc_bufs; /* list of allocated buffers */ - -/* same as in */ -struct videobuf_dma_contig_memory { - u32 magic; - void *vaddr; - dma_addr_t dma_handle; - unsigned long size; - int is_userptr; -}; - -#define MAGIC_DC_MEM 0x0733ac61 -#define MAGIC_CHECK(is, should) \ - if (unlikely((is) != (should))) { \ - pr_err("magic mismatch: %x expected %x\n", (is), (should)); \ - BUG(); \ - } - -/* helper functions to allocate/free buffers from the pool */ -static void * -dt3155_alloc_buffer(struct device *dev, size_t size, dma_addr_t *dma_handle, - gfp_t flag) -{ - struct dt3155_buf *buf; - - if (size > DT3155_BUF_SIZE) - return NULL; - size = DT3155_BUF_SIZE; /* same for CCIR & RS-170 */ - buf = dt3155_get_buf(dt3155_free_bufs); - if (!buf) - return NULL; - buf->dma = dma_map_single(dev, buf->cpu, size, DMA_FROM_DEVICE); - if (dma_mapping_error(dev, buf->dma)) { - dt3155_put_buf(buf, dt3155_free_bufs); - return NULL; - } - dt3155_put_buf(buf, dt3155_alloc_bufs); - *dma_handle = buf->dma; - return buf->cpu; -} - -static void -dt3155_free_buffer(struct device *dev, size_t size, void *cpu_addr, - dma_addr_t dma_handle) -{ - struct dt3155_buf *buf, *last; - int found = 0; - - if (!cpu_addr) /* to free NULL is OK */ - return; - last = dt3155_get_buf(dt3155_alloc_bufs); - if (!last) { - printk(KERN_ERR "dt3155: %s(): no alloc buffers\n", __func__); - return; - } - dt3155_put_buf(last, dt3155_alloc_bufs); - do { - buf = dt3155_get_buf(dt3155_alloc_bufs); - if (buf->cpu == cpu_addr && buf->dma == dma_handle) { - found = 1; - break; - } - dt3155_put_buf(buf, dt3155_alloc_bufs); - } while (buf != last); - if (!found) { - printk(KERN_ERR "dt3155: %s(): buffer not found\n", __func__); - return; - } - size = DT3155_BUF_SIZE; /* same for CCIR & RS-170 */ - dma_unmap_single(dev, dma_handle, size, DMA_FROM_DEVICE); - dt3155_put_buf(buf, dt3155_free_bufs); -} - -/* same as videobuf_dma_contig_user_get() */ -static int -dt3155_dma_contig_user_get(struct videobuf_dma_contig_memory *mem, - struct videobuf_buffer *vb) -{ - struct mm_struct *mm = current->mm; - struct vm_area_struct *vma; - unsigned long prev_pfn, this_pfn; - unsigned long pages_done, user_address; - unsigned int offset; - int ret; - - offset = vb->baddr & ~PAGE_MASK; - mem->size = PAGE_ALIGN(vb->size + offset); - mem->is_userptr = 0; - ret = -EINVAL; - - down_read(&mm->mmap_sem); - - vma = find_vma(mm, vb->baddr); - if (!vma) - goto out_up; - - if ((vb->baddr + mem->size) > vma->vm_end) - goto out_up; - - pages_done = 0; - prev_pfn = 0; /* kill warning */ - user_address = vb->baddr; - - while (pages_done < (mem->size >> PAGE_SHIFT)) { - ret = follow_pfn(vma, user_address, &this_pfn); - if (ret) - break; - - if (pages_done == 0) - mem->dma_handle = (this_pfn << PAGE_SHIFT) + offset; - else if (this_pfn != (prev_pfn + 1)) - ret = -EFAULT; - - if (ret) - break; - - prev_pfn = this_pfn; - user_address += PAGE_SIZE; - pages_done++; - } - - if (!ret) - mem->is_userptr = 1; - - out_up: - up_read(¤t->mm->mmap_sem); - - return ret; -} - -/* same as videobuf_dma_contig_user_put() */ -static void -dt3155_dma_contig_user_put(struct videobuf_dma_contig_memory *mem) -{ - mem->is_userptr = 0; - mem->dma_handle = 0; - mem->size = 0; -} - -/* same as videobuf_iolock() but uses allocations from the pool */ -static int -dt3155_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb, - struct v4l2_framebuffer *fbuf) -{ - struct videobuf_dma_contig_memory *mem = vb->priv; - - BUG_ON(!mem); - MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); - - switch (vb->memory) { - case V4L2_MEMORY_MMAP: - dev_dbg(q->dev, "%s memory method MMAP\n", __func__); - - /* All handling should be done by __videobuf_mmap_mapper() */ - if (!mem->vaddr) { - dev_err(q->dev, "memory is not alloced/mmapped.\n"); - return -EINVAL; - } - break; - case V4L2_MEMORY_USERPTR: - dev_dbg(q->dev, "%s memory method USERPTR\n", __func__); - - /* handle pointer from user space */ - if (vb->baddr) - return dt3155_dma_contig_user_get(mem, vb); - - /* allocate memory for the read() method */ - mem->size = PAGE_ALIGN(vb->size); - mem->vaddr = dt3155_alloc_buffer(q->dev, mem->size, - &mem->dma_handle, GFP_KERNEL); - if (!mem->vaddr) { - dev_err(q->dev, "dma_alloc_coherent %ld failed\n", - mem->size); - return -ENOMEM; - } - - dev_dbg(q->dev, "dma_alloc_coherent data is at %p (%ld)\n", - mem->vaddr, mem->size); - break; - case V4L2_MEMORY_OVERLAY: - default: - dev_dbg(q->dev, "%s memory method OVERLAY/unknown\n", - __func__); - return -EINVAL; - } - - return 0; -} - -/* same as videobuf_dma_contig_free() but uses the pool */ -void -dt3155_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf) -{ - struct videobuf_dma_contig_memory *mem = buf->priv; - - /* mmapped memory can't be freed here, otherwise mmapped region - would be released, while still needed. In this case, the memory - release should happen inside videobuf_vm_close(). - So, it should free memory only if the memory were allocated for - read() operation. - */ - if (buf->memory != V4L2_MEMORY_USERPTR) - return; - - if (!mem) - return; - - MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); - - /* handle user space pointer case */ - if (buf->baddr) { - dt3155_dma_contig_user_put(mem); - return; - } - - /* read() method */ - dt3155_free_buffer(q->dev, mem->size, mem->vaddr, mem->dma_handle); - mem->vaddr = NULL; -} - -/* same as videobuf_vm_open() */ -static void -dt3155_vm_open(struct vm_area_struct *vma) -{ - struct videobuf_mapping *map = vma->vm_private_data; - - dev_dbg(map->q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n", - map, map->count, vma->vm_start, vma->vm_end); - - map->count++; -} - -/* same as videobuf_vm_close(), but free to the pool */ -static void -dt3155_vm_close(struct vm_area_struct *vma) -{ - struct videobuf_mapping *map = vma->vm_private_data; - struct videobuf_queue *q = map->q; - int i; - - dev_dbg(q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", - map, map->count, vma->vm_start, vma->vm_end); - - map->count--; - if (0 == map->count) { - struct videobuf_dma_contig_memory *mem; - - dev_dbg(q->dev, "munmap %p q=%p\n", map, q); - mutex_lock(&q->vb_lock); - - /* We need first to cancel streams, before unmapping */ - if (q->streaming) - videobuf_queue_cancel(q); - - for (i = 0; i < VIDEO_MAX_FRAME; i++) { - if (NULL == q->bufs[i]) - continue; - - if (q->bufs[i]->map != map) - continue; - - mem = q->bufs[i]->priv; - if (mem) { - /* This callback is called only if kernel has - allocated memory and this memory is mmapped. - In this case, memory should be freed, - in order to do memory unmap. - */ - - MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); - - /* vfree is not atomic - can't be - called with IRQ's disabled - */ - dev_dbg(q->dev, "buf[%d] freeing %p\n", - i, mem->vaddr); - - dt3155_free_buffer(q->dev, mem->size, - mem->vaddr, mem->dma_handle); - mem->vaddr = NULL; - } - - q->bufs[i]->map = NULL; - q->bufs[i]->baddr = 0; - } - - kfree(map); - - mutex_unlock(&q->vb_lock); - } -} - -static const struct vm_operations_struct dt3155_vm_ops = { - .open = dt3155_vm_open, - .close = dt3155_vm_close, -}; - -/* same as videobuf_mmap_mapper(), but allocates from the pool */ -static int -dt3155_mmap_mapper(struct videobuf_queue *q, struct videobuf_buffer *buf, - struct vm_area_struct *vma) -{ - struct videobuf_dma_contig_memory *mem; - struct videobuf_mapping *map; - int retval; - unsigned long size; - - dev_dbg(q->dev, "%s\n", __func__); - - /* create mapping + update buffer list */ - map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL); - if (!map) - return -ENOMEM; - - buf->map = map; - map->start = vma->vm_start; - map->end = vma->vm_end; - map->q = q; - - buf->baddr = vma->vm_start; - - mem = buf->priv; - BUG_ON(!mem); - MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); - - mem->size = PAGE_ALIGN(buf->bsize); - mem->vaddr = dt3155_alloc_buffer(q->dev, mem->size, - &mem->dma_handle, GFP_KERNEL); - if (!mem->vaddr) { - dev_err(q->dev, "dma_alloc_coherent size %ld failed\n", - mem->size); - goto error; - } - dev_dbg(q->dev, "dma_alloc_coherent data is at addr %p (size %ld)\n", - mem->vaddr, mem->size); - - /* Try to remap memory */ - - size = vma->vm_end - vma->vm_start; - size = (size < mem->size) ? size : mem->size; - - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - retval = remap_pfn_range(vma, vma->vm_start, - mem->dma_handle >> PAGE_SHIFT, - size, vma->vm_page_prot); - if (retval) { - dev_err(q->dev, "mmap: remap failed with error %d. ", retval); - dt3155_free_buffer(q->dev, mem->size, - mem->vaddr, mem->dma_handle); - goto error; - } - - vma->vm_ops = &dt3155_vm_ops; - vma->vm_flags |= VM_DONTEXPAND; - vma->vm_private_data = map; - - dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n", - map, q, vma->vm_start, vma->vm_end, - (long int)buf->bsize, - vma->vm_pgoff, buf->i); - - dt3155_vm_open(vma); - - return 0; - -error: - kfree(map); - return -ENOMEM; -} - -static int -dt3155_sync_for_cpu(struct videobuf_queue *q, struct videobuf_buffer *vb) -{ - struct dt3155_priv *pd = q->priv_data; - struct videobuf_dma_contig_memory *mem = vb->priv; - - BUG_ON(!mem); - MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); - - pci_dma_sync_single_for_cpu(pd->pdev, mem->dma_handle, - mem->size, PCI_DMA_FROMDEVICE); - return 0; -} - -static int -dt3155_sync_for_device(struct videobuf_queue *q, struct videobuf_buffer *vb) -{ - struct dt3155_priv *pd = q->priv_data; - struct videobuf_dma_contig_memory *mem = vb->priv; - - BUG_ON(!mem); - MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); - - pci_dma_sync_single_for_device(pd->pdev, mem->dma_handle, - mem->size, PCI_DMA_FROMDEVICE); - return 0; -} - -/* - * same as videobuf_queue_dma_contig_init(), but after - * initialisation overwrites videobuf_iolock() and - * videobuf_mmap_mapper() with our customized versions - * as well as adds sync() method - */ -static void -dt3155_queue_dma_contig_init(struct videobuf_queue *q, - struct videobuf_queue_ops *ops, - struct device *dev, - spinlock_t *irqlock, - enum v4l2_buf_type type, - enum v4l2_field field, - unsigned int msize, - void *priv) -{ - struct dt3155_priv *pd = priv; - - videobuf_queue_dma_contig_init(q, ops, dev, irqlock, - type, field, msize, priv); - /* replace with local copy */ - pd->qt_ops = *q->int_ops; - q->int_ops = &pd->qt_ops; - /* and overwrite with our methods */ - q->int_ops->iolock = dt3155_iolock; - q->int_ops->mmap_mapper = dt3155_mmap_mapper; - q->int_ops->sync = dt3155_sync_for_cpu; -} - static int dt3155_start_acq(struct dt3155_priv *pd) { @@ -699,7 +268,7 @@ dt3155_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, if (ret) { vb->state = VIDEOBUF_ERROR; printk(KERN_ERR "ERROR: videobuf_iolock() failed\n"); - videobuf_dma_contig_free(q, vb); + videobuf_dma_contig_free(q, vb); /* FIXME: needed? */ } else vb->state = VIDEOBUF_PREPARED; return ret; @@ -713,7 +282,6 @@ dt3155_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) if (vb->state != VIDEOBUF_NEEDS_INIT) { vb->state = VIDEOBUF_QUEUED; - dt3155_sync_for_device(q, vb); list_add_tail(&vb->queue, &pd->dmaq); wake_up_interruptible_sync(&pd->do_dma); } else @@ -726,7 +294,7 @@ dt3155_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb) { if (vb->state == VIDEOBUF_ACTIVE) videobuf_waiton(vb, 0, 0); /* FIXME: cannot be interrupted */ - dt3155_dma_contig_free(q, vb); + videobuf_dma_contig_free(q, vb); vb->state = VIDEOBUF_NEEDS_INIT; } @@ -869,7 +437,7 @@ dt3155_open(struct file *filp) ret = -ENOMEM; goto err_alloc_queue; } - dt3155_queue_dma_contig_init(pd->vidq, &vbq_ops, + videobuf_queue_dma_contig_init(pd->vidq, &vbq_ops, &pd->pdev->dev, &pd->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, sizeof(struct videobuf_buffer), pd); @@ -1317,11 +885,13 @@ static const struct v4l2_ioctl_ops dt3155_ioctl_ops = { static int __devinit dt3155_init_board(struct pci_dev *dev) { + struct dt3155_priv *pd = pci_get_drvdata(dev); + void *buf_cpu; + dma_addr_t buf_dma; int i; u8 tmp; - struct dt3155_buf *buf; - struct dt3155_priv *pd = pci_get_drvdata(dev); - pci_set_master(dev); /* dt3155 needs it */ + + pci_set_master(dev); /* dt3155 needs it */ /* resetting the adapter */ iowrite32(FLD_CRPT_ODD | FLD_CRPT_EVEN | FLD_DN_ODD | FLD_DN_EVEN, @@ -1381,22 +951,16 @@ dt3155_init_board(struct pci_dev *dev) write_i2c_reg(pd->regs, AD_ADDR, AD_CMD_REG); write_i2c_reg(pd->regs, AD_CMD, VIDEO_CNL_1 | SYNC_CNL_1 | SYNC_LVL_3); - /* allocate and pci_map memory, and initialize the DMA machine */ - buf = dt3155_get_buf(dt3155_free_bufs); - if (!buf) { - printk(KERN_ERR "dt3155: dt3155_get_buf " + /* allocate memory, and initialize the DMA machine */ + buf_cpu = dma_alloc_coherent(&dev->dev, DT3155_BUF_SIZE, &buf_dma, + GFP_KERNEL); + if (!buf_cpu) { + printk(KERN_ERR "dt3155: dma_alloc_coherent " "(in dt3155_init_board) failed\n"); return -ENOMEM; } - buf->dma = pci_map_single(dev, buf->cpu, - DT3155_BUF_SIZE, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(dev, buf->dma)) { - printk(KERN_ERR "dt3155: pci_map_single failed\n"); - dt3155_put_buf(buf, dt3155_free_bufs); - return -ENOMEM; - } - iowrite32(buf->dma, pd->regs + EVEN_DMA_START); - iowrite32(buf->dma, pd->regs + ODD_DMA_START); + iowrite32(buf_dma, pd->regs + EVEN_DMA_START); + iowrite32(buf_dma, pd->regs + ODD_DMA_START); iowrite32(0, pd->regs + EVEN_DMA_STRIDE); iowrite32(0, pd->regs + ODD_DMA_STRIDE); @@ -1413,9 +977,8 @@ dt3155_init_board(struct pci_dev *dev) write_i2c_reg(pd->regs, CSR2, pd->csr2); iowrite32(FIFO_EN | SRST | FLD_DN_EVEN | FLD_DN_ODD, pd->regs + CSR1); - /* pci_unmap and deallocate memory */ - pci_unmap_single(dev, buf->dma, DT3155_BUF_SIZE, PCI_DMA_FROMDEVICE); - dt3155_put_buf(buf, dt3155_free_bufs); + /* deallocate memory */ + dma_free_coherent(&dev->dev, DT3155_BUF_SIZE, buf_cpu, buf_dma); if (tmp & BUSY_EVEN) { printk(KERN_ERR "dt3155: BUSY_EVEN not cleared\n"); return -EIO; @@ -1433,17 +996,82 @@ static struct video_device dt3155_vdev = { .current_norm = DT3155_CURRENT_NORM, }; +/* same as in drivers/base/dma-coherent.c */ +struct dma_coherent_mem { + void *virt_base; + u32 device_base; + int size; + int flags; + unsigned long *bitmap; +}; + +static int __devinit +dt3155_alloc_coherent(struct device *dev, size_t size, int flags) +{ + int pages = size >> PAGE_SHIFT; + int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); + + if ((flags & DMA_MEMORY_MAP) == 0) + goto out; + if (!size) + goto out; + if (dev->dma_mem) + goto out; + + dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); + if (!dev->dma_mem) + goto out; + dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL); + if (!dev->dma_mem->bitmap) + goto err_bitmap; + + dev->dma_mem->virt_base = dma_alloc_coherent(dev, size, + &dev->dma_mem->device_base, DT3155_COH_FLAGS); + if (!dev->dma_mem->virt_base) + goto err_coherent; + dev->dma_mem->size = pages; + dev->dma_mem->flags = flags; + return DMA_MEMORY_MAP; + +err_coherent: + kfree(dev->dma_mem->bitmap); +err_bitmap: + kfree(dev->dma_mem); +out: + return 0; +} + +static void __devexit +dt3155_free_coherent(struct device *dev) +{ + struct dma_coherent_mem *mem = dev->dma_mem; + + if (!mem) + return; + dev->dma_mem = NULL; + dma_free_coherent(dev, mem->size << PAGE_SHIFT, + mem->virt_base, mem->device_base); + kfree(mem->bitmap); + kfree(mem); +} + static int __devinit dt3155_probe(struct pci_dev *dev, const struct pci_device_id *id) { - int err = -ENODEV; + int err; struct dt3155_priv *pd; printk(KERN_INFO "dt3155: probe()\n"); - if (pci_set_dma_mask(dev, DMA_BIT_MASK(32))) { + err = dma_set_mask(&dev->dev, DMA_BIT_MASK(32)); + if (err) { printk(KERN_ERR "dt3155: cannot set dma_mask\n"); return -ENODEV; } + err = dma_set_coherent_mask(&dev->dev, DMA_BIT_MASK(32)); + if (err) { + printk(KERN_ERR "dt3155: cannot set dma_coherent_mask\n"); + return -ENODEV; + } pd = kzalloc(sizeof(*pd), GFP_KERNEL); if (!pd) { printk(KERN_ERR "dt3155: cannot allocate dt3155_priv\n"); @@ -1451,12 +1079,12 @@ dt3155_probe(struct pci_dev *dev, const struct pci_device_id *id) } pd->vdev = video_device_alloc(); if (!pd->vdev) { - printk(KERN_ERR "dt3155: cannot allocate vdp structure\n"); + printk(KERN_ERR "dt3155: cannot allocate vdev structure\n"); goto err_video_device_alloc; } *pd->vdev = dt3155_vdev; - pci_set_drvdata(dev, pd); /* for use in dt3155_remove() */ - video_set_drvdata(pd->vdev, pd); /* for use in video_fops */ + pci_set_drvdata(dev, pd); /* for use in dt3155_remove() */ + video_set_drvdata(pd->vdev, pd); /* for use in video_fops */ pd->users = 0; pd->acq_fp = NULL; pd->pdev = dev; @@ -1489,6 +1117,10 @@ dt3155_probe(struct pci_dev *dev, const struct pci_device_id *id) printk(KERN_ERR "dt3155: Cannot register video device\n"); goto err_init_board; } + err = dt3155_alloc_coherent(&dev->dev, DT3155_CHUNK_SIZE, + DMA_MEMORY_MAP); + if (err) + printk(KERN_INFO "dt3155: preallocated 8 buffers\n"); printk(KERN_INFO "dt3155: /dev/video%i is ready\n", pd->vdev->minor); return 0; /* success */ @@ -1511,6 +1143,7 @@ dt3155_remove(struct pci_dev *dev) struct dt3155_priv *pd = pci_get_drvdata(dev); printk(KERN_INFO "dt3155: remove()\n"); + dt3155_free_coherent(&dev->dev); video_unregister_device(pd->vdev); pci_iounmap(dev, pd->regs); pci_release_region(pd->pdev, 0); @@ -1542,48 +1175,18 @@ dt3155_init_module(void) printk(KERN_INFO "dt3155: ==================\n"); printk(KERN_INFO "dt3155: init()\n"); - dt3155_chunks = dt3155_init_chunks_fifo(); - if (!dt3155_chunks) { - err = -ENOMEM; - printk(KERN_ERR "dt3155: cannot init dt3155_chunks_fifo\n"); - goto err_init_chunks_fifo; - } - dt3155_free_bufs = dt3155_init_ibufs_fifo(dt3155_chunks, - DT3155_BUF_SIZE); - if (!dt3155_free_bufs) { - err = -ENOMEM; - printk(KERN_ERR "dt3155: cannot dt3155_init_ibufs_fifo\n"); - goto err_init_ibufs_fifo; - } - dt3155_alloc_bufs = dt3155_init_fifo(); - if (!dt3155_alloc_bufs) { - err = -ENOMEM; - printk(KERN_ERR "dt3155: cannot dt3155_init_fifo\n"); - goto err_init_fifo; - } err = pci_register_driver(&pci_driver); if (err) { printk(KERN_ERR "dt3155: cannot register pci_driver\n"); - goto err_register_driver; + return err; } return 0; /* succes */ -err_register_driver: - dt3155_free_fifo(dt3155_alloc_bufs); -err_init_fifo: - dt3155_free_ibufs_fifo(dt3155_free_bufs); -err_init_ibufs_fifo: - dt3155_free_chunks_fifo(dt3155_chunks); -err_init_chunks_fifo: - return err; } static void __exit dt3155_exit_module(void) { pci_unregister_driver(&pci_driver); - dt3155_free_fifo(dt3155_alloc_bufs); - dt3155_free_ibufs_fifo(dt3155_free_bufs); - dt3155_free_chunks_fifo(dt3155_chunks); printk(KERN_INFO "dt3155: exit()\n"); printk(KERN_INFO "dt3155: ==================\n"); } diff --git a/drivers/staging/dt3155v4l/dt3155v4l.h b/drivers/staging/dt3155v4l/dt3155v4l.h index e65a81e198b9..aa68a6f38aaa 100644 --- a/drivers/staging/dt3155v4l/dt3155v4l.h +++ b/drivers/staging/dt3155v4l/dt3155v4l.h @@ -29,8 +29,8 @@ #define DT3155_NAME "dt3155" #define DT3155_VER_MAJ 1 -#define DT3155_VER_MIN 0 -#define DT3155_VER_EXT 3 +#define DT3155_VER_MIN 1 +#define DT3155_VER_EXT 0 #define DT3155_VERSION __stringify(DT3155_VER_MAJ) "." \ __stringify(DT3155_VER_MIN) "." \ __stringify(DT3155_VER_EXT) -- cgit v1.2.3 From 7ec52ed25013533248d929d4405225d30c4272b2 Mon Sep 17 00:00:00 2001 From: Alessio Igor Bogani Date: Tue, 18 May 2010 13:12:32 +0200 Subject: Staging: comedi: quatech_daqp_cs.c Replace eos semaphore with a completion. Build tested only. Signed-off-by: Alessio Igor Bogani Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/quatech_daqp_cs.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index be62face6a71..d77ae81dd128 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -55,6 +55,8 @@ Devices: [Quatech] DAQP-208 (daqp), DAQP-308 #include #include +#include + /* Maximum number of separate DAQP devices we'll allow */ #define MAX_DEV 4 @@ -67,7 +69,7 @@ struct local_info_t { enum { semaphore, buffer } interrupt_mode; - struct semaphore eos; + struct completion eos; struct comedi_device *dev; struct comedi_subdevice *s; @@ -238,7 +240,7 @@ static int daqp_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) /* Interrupt handler * * Operates in one of two modes. If local->interrupt_mode is - * 'semaphore', just signal the local->eos semaphore and return + * 'semaphore', just signal the local->eos completion and return * (one-shot mode). Otherwise (continuous mode), read data in from * the card, transfer it to the buffer provided by the higher-level * comedi kernel module, and signal various comedi callback routines, @@ -287,7 +289,7 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id) case semaphore: - up(&local->eos); + complete(&local->eos); break; case buffer: @@ -401,8 +403,7 @@ static int daqp_ai_insn_read(struct comedi_device *dev, return -1; } - /* Make sure semaphore is blocked */ - sema_init(&local->eos, 0); + init_completion(&local->eos); local->interrupt_mode = semaphore; local->dev = dev; local->s = s; @@ -413,9 +414,9 @@ static int daqp_ai_insn_read(struct comedi_device *dev, outb(DAQP_COMMAND_ARM | DAQP_COMMAND_FIFO_DATA, dev->iobase + DAQP_COMMAND); - /* Wait for interrupt service routine to unblock semaphore */ + /* Wait for interrupt service routine to unblock completion */ /* Maybe could use a timeout here, but it's interruptible */ - if (down_interruptible(&local->eos)) + if (wait_for_completion_interruptible(&local->eos)) return -EINTR; data[i] = inb(dev->iobase + DAQP_FIFO); -- cgit v1.2.3 From 21ec51f3df9fd3c83ce0a4ac6a18e5083984b8ae Mon Sep 17 00:00:00 2001 From: Charles Clément Date: Tue, 18 May 2010 10:08:14 -0700 Subject: Staging: vt6656: use ETH_HLEN macro instead of custom one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace custom header length definition U_HEADER_LEN by ETH_HLEN from . Also remove unused U_TYPE_LEN. Signed-off-by: Charles Clément Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/rxtx.c | 20 ++++++++++---------- drivers/staging/vt6656/tether.h | 6 ++---- 2 files changed, 12 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index 6a4b87f09545..c41105526a82 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -1483,7 +1483,7 @@ s_bPacketToWirelessUsb( cb802_1_H_len = 0; } - cbFrameBodySize = uSkbPacketLen - U_HEADER_LEN + cb802_1_H_len; + cbFrameBodySize = uSkbPacketLen - ETH_HLEN + cb802_1_H_len; //Set packet type pTxBufHead->wFIFOCtl |= (WORD)(byPktType<<8); @@ -1729,13 +1729,13 @@ s_bPacketToWirelessUsb( if (pPacket != NULL) { // Copy the Packet into a tx Buffer memcpy((pbyPayloadHead + cb802_1_H_len), - (pPacket + U_HEADER_LEN), - uSkbPacketLen - U_HEADER_LEN + (pPacket + ETH_HLEN), + uSkbPacketLen - ETH_HLEN ); } else { // while bRelayPacketSend psEthHeader is point to header+payload - memcpy((pbyPayloadHead + cb802_1_H_len), ((PBYTE)psEthHeader)+U_HEADER_LEN, uSkbPacketLen - U_HEADER_LEN); + memcpy((pbyPayloadHead + cb802_1_H_len), ((PBYTE)psEthHeader) + ETH_HLEN, uSkbPacketLen - ETH_HLEN); } ASSERT(uLength == cbNdisBodySize); @@ -2849,7 +2849,7 @@ nsDMA_tx_packet( return STATUS_RESOURCES; } - memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)(skb->data), U_HEADER_LEN); + memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)(skb->data), ETH_HLEN); //mike add:station mode check eapol-key challenge---> { @@ -2858,10 +2858,10 @@ nsDMA_tx_packet( BYTE Descriptor_type; WORD Key_info; - Protocol_Version = skb->data[U_HEADER_LEN]; - Packet_Type = skb->data[U_HEADER_LEN+1]; - Descriptor_type = skb->data[U_HEADER_LEN+1+1+2]; - Key_info = (skb->data[U_HEADER_LEN+1+1+2+1] << 8)|(skb->data[U_HEADER_LEN+1+1+2+2]); + Protocol_Version = skb->data[ETH_HLEN]; + Packet_Type = skb->data[ETH_HLEN+1]; + Descriptor_type = skb->data[ETH_HLEN+1+1+2]; + Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]); if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) { if(((Protocol_Version==1) ||(Protocol_Version==2)) && (Packet_Type==3)) { //802.1x OR eapol-key challenge frame transfer @@ -3195,7 +3195,7 @@ bRelayPacketSend ( return FALSE; } - memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)pbySkbData, U_HEADER_LEN); + memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)pbySkbData, ETH_HLEN); if (pDevice->bEncryptionEnable == TRUE) { bNeedEncryption = TRUE; diff --git a/drivers/staging/vt6656/tether.h b/drivers/staging/vt6656/tether.h index f5819a7aee27..d63586d5cdb2 100644 --- a/drivers/staging/vt6656/tether.h +++ b/drivers/staging/vt6656/tether.h @@ -36,19 +36,17 @@ // // constants // -#define U_TYPE_LEN 2 // #define U_CRC_LEN 4 // -#define U_HEADER_LEN (ETH_ALEN * 2 + U_TYPE_LEN) #define U_ETHER_ADDR_STR_LEN (ETH_ALEN * 2 + 1) // Ethernet address string length #define MIN_DATA_LEN 46 // min data length #define MAX_DATA_LEN 1500 // max data length -#define MIN_PACKET_LEN (MIN_DATA_LEN + U_HEADER_LEN) +#define MIN_PACKET_LEN (MIN_DATA_LEN + ETH_HLEN) // 60 // min total packet length (tx) -#define MAX_PACKET_LEN (MAX_DATA_LEN + U_HEADER_LEN) +#define MAX_PACKET_LEN (MAX_DATA_LEN + ETH_HLEN) // 1514 // max total packet length (tx) -- cgit v1.2.3 From 855181f51558dca10c8acc27f1f81e0809ddf057 Mon Sep 17 00:00:00 2001 From: Charles Clément Date: Tue, 18 May 2010 10:19:36 -0700 Subject: Staging: vt6655: use ETH_FCS_LEN macro instead of custom one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace custom FCS/CRC length definition U_CRC_LEN by ETH_FCS_LEN from . Signed-off-by: Charles Clément Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/dpc.c | 2 +- drivers/staging/vt6655/tether.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index 83040f4f6c78..6b758a8c1af3 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -569,7 +569,7 @@ device_receive_frame ( // RX OK // //remove the CRC length - FrameSize -= U_CRC_LEN; + FrameSize -= ETH_FCS_LEN; if (( !(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI))) && // unicast address (IS_FRAGMENT_PKT((skb->data+4))) diff --git a/drivers/staging/vt6655/tether.h b/drivers/staging/vt6655/tether.h index 4f2af359c063..bc82a6b425e9 100644 --- a/drivers/staging/vt6655/tether.h +++ b/drivers/staging/vt6655/tether.h @@ -36,7 +36,6 @@ // // constants // -#define U_CRC_LEN 4 // #define U_ETHER_ADDR_STR_LEN (ETH_ALEN * 2 + 1) // Ethernet address string length -- cgit v1.2.3 From 31c21b779181140e0b7eadadbd5e0f518e131488 Mon Sep 17 00:00:00 2001 From: Charles Clément Date: Tue, 18 May 2010 11:30:19 -0700 Subject: Staging: vt6655: use ETH_DATA_LEN macro instead of custom one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace custom maximum data lenght definition MAX_DATA_LEN by ETH_DATA_LEN from . Signed-off-by: Charles Clément Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 4 ++-- drivers/staging/vt6655/rxtx.c | 4 ++-- drivers/staging/vt6655/tether.h | 3 +-- drivers/staging/vt6655/wroute.c | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 25894a201b2b..3005892e807c 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -2156,7 +2156,7 @@ BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex) { cbFrameBodySize = skb->len - ETH_HLEN; // 802.1H - if (ntohs(pDevice->sTxEthHeader.wType) > MAX_DATA_LEN) { + if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) { cbFrameBodySize += 8; } uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader); @@ -2359,7 +2359,7 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) { memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)(skb->data), ETH_HLEN); cbFrameBodySize = skb->len - ETH_HLEN; // 802.1H - if (ntohs(pDevice->sTxEthHeader.wType) > MAX_DATA_LEN) { + if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) { cbFrameBodySize += 8; } diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index e27fa204962e..efd758efc73f 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -1622,7 +1622,7 @@ s_cbFillTxBufHead ( // 802.1H - if (ntohs(psEthHeader->wType) > MAX_DATA_LEN) { + if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) { if ((psEthHeader->wType == TYPE_PKT_IPX) || (psEthHeader->wType == cpu_to_le16(0xF380))) { memcpy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6); @@ -1986,7 +1986,7 @@ s_cbFillTxBufHead ( } // 802.1H - if (ntohs(psEthHeader->wType) > MAX_DATA_LEN) { + if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) { if ((psEthHeader->wType == TYPE_PKT_IPX) || (psEthHeader->wType == cpu_to_le16(0xF380))) { memcpy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6); diff --git a/drivers/staging/vt6655/tether.h b/drivers/staging/vt6655/tether.h index bc82a6b425e9..5ade9b6b51c3 100644 --- a/drivers/staging/vt6655/tether.h +++ b/drivers/staging/vt6655/tether.h @@ -40,12 +40,11 @@ // Ethernet address string length #define MIN_DATA_LEN 46 // min data length -#define MAX_DATA_LEN 1500 // max data length #define MIN_PACKET_LEN (MIN_DATA_LEN + ETH_HLEN) // 60 // min total packet length (tx) -#define MAX_PACKET_LEN (MAX_DATA_LEN + ETH_HLEN) +#define MAX_PACKET_LEN (ETH_DATA_LEN + ETH_HLEN) // 1514 // max total packet length (tx) diff --git a/drivers/staging/vt6655/wroute.c b/drivers/staging/vt6655/wroute.c index 485e105b0af7..bf92fb9908fe 100644 --- a/drivers/staging/vt6655/wroute.c +++ b/drivers/staging/vt6655/wroute.c @@ -95,7 +95,7 @@ BOOL ROUTEbRelay (PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeI cbFrameBodySize = uDataLen - ETH_HLEN; - if (ntohs(pDevice->sTxEthHeader.wType) > MAX_DATA_LEN) { + if (ntohs(pDevice->sTxEthHeader.wType) > ETH_DATA_LEN) { cbFrameBodySize += 8; } -- cgit v1.2.3 From ee6583f6e8f8dad4a53985dbabcd7c242d66a6b6 Mon Sep 17 00:00:00 2001 From: Roman Fietze Date: Tue, 18 May 2010 14:45:47 +0200 Subject: PCI: fix typos pci_device_dis/enable to pci_dis/enable_device in comments This fixes all occurrences of pci_enable_device and pci_disable_device in all comments. There are no code changes involved. Signed-off-by: Roman Fietze Signed-off-by: Jesse Barnes --- drivers/edac/amd76x_edac.c | 2 +- drivers/edac/i82443bxgx_edac.c | 2 +- drivers/edac/r82600_edac.c | 2 +- drivers/pci/pci.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/amd76x_edac.c b/drivers/edac/amd76x_edac.c index f2330f81cb5e..cace0a7b707a 100644 --- a/drivers/edac/amd76x_edac.c +++ b/drivers/edac/amd76x_edac.c @@ -294,7 +294,7 @@ static int __devinit amd76x_init_one(struct pci_dev *pdev, { debugf0("%s()\n", __func__); - /* don't need to call pci_device_enable() */ + /* don't need to call pci_enable_device() */ return amd76x_probe1(pdev, ent->driver_data); } diff --git a/drivers/edac/i82443bxgx_edac.c b/drivers/edac/i82443bxgx_edac.c index 7f3884fcbd46..2bf2c5051bfe 100644 --- a/drivers/edac/i82443bxgx_edac.c +++ b/drivers/edac/i82443bxgx_edac.c @@ -354,7 +354,7 @@ static int __devinit i82443bxgx_edacmc_init_one(struct pci_dev *pdev, debugf0("MC: " __FILE__ ": %s()\n", __func__); - /* don't need to call pci_device_enable() */ + /* don't need to call pci_enable_device() */ rc = i82443bxgx_edacmc_probe1(pdev, ent->driver_data); if (mci_pdev == NULL) diff --git a/drivers/edac/r82600_edac.c b/drivers/edac/r82600_edac.c index d55f8e9de788..6a822c631ef5 100644 --- a/drivers/edac/r82600_edac.c +++ b/drivers/edac/r82600_edac.c @@ -354,7 +354,7 @@ static int __devinit r82600_init_one(struct pci_dev *pdev, { debugf0("%s()\n", __func__); - /* don't need to call pci_device_enable() */ + /* don't need to call pci_enable_device() */ return r82600_probe1(pdev, ent->driver_data); } diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 60fcb6f02c91..264c3f6b8476 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1193,7 +1193,7 @@ void pci_disable_enabled_device(struct pci_dev *dev) * anymore. This only involves disabling PCI bus-mastering, if active. * * Note we don't actually disable the device until all callers of - * pci_device_enable() have called pci_device_disable(). + * pci_enable_device() have called pci_disable_device(). */ void pci_disable_device(struct pci_dev *dev) -- cgit v1.2.3 From f4a68b9388c7f647ba2fd43faf69cad26ca03206 Mon Sep 17 00:00:00 2001 From: Charles Clément Date: Tue, 18 May 2010 11:30:20 -0700 Subject: Staging: vt6655: use ETH_FRAME_LEN macro instead of custom one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace custom maximum packet lenght definition MAX_PACKET_LEN by ETH_FRAME_LEN from . Signed-off-by: Charles Clément Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/mib.c | 4 ++-- drivers/staging/vt6655/tether.h | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6655/mib.c b/drivers/staging/vt6655/mib.c index e5f06382e4f8..4ca7877075b2 100644 --- a/drivers/staging/vt6655/mib.c +++ b/drivers/staging/vt6655/mib.c @@ -359,9 +359,9 @@ void STAvUpdateRDStatCounter (PSStatCounter pStatistic, else if ((512 <= cbFrameLength) && (cbFrameLength <= 1023)) { pStatistic->dwRsrRxFrmLen512_1023++; } - else if ((1024 <= cbFrameLength) && (cbFrameLength <= MAX_PACKET_LEN + 4)) { + else if ((1024 <= cbFrameLength) && (cbFrameLength <= ETH_FRAME_LEN + 4)) { pStatistic->dwRsrRxFrmLen1024_1518++; - } else if (cbFrameLength > MAX_PACKET_LEN + 4) { + } else if (cbFrameLength > ETH_FRAME_LEN + 4) { pStatistic->dwRsrLong++; } diff --git a/drivers/staging/vt6655/tether.h b/drivers/staging/vt6655/tether.h index 5ade9b6b51c3..3c9acd7903a8 100644 --- a/drivers/staging/vt6655/tether.h +++ b/drivers/staging/vt6655/tether.h @@ -44,11 +44,8 @@ #define MIN_PACKET_LEN (MIN_DATA_LEN + ETH_HLEN) // 60 // min total packet length (tx) -#define MAX_PACKET_LEN (ETH_DATA_LEN + ETH_HLEN) - // 1514 - // max total packet length (tx) -#define MAX_LOOKAHEAD_SIZE MAX_PACKET_LEN +#define MAX_LOOKAHEAD_SIZE ETH_FRAME_LEN #define U_MULTI_ADDR_LEN 8 // multicast address length -- cgit v1.2.3 From 5030718ee465c759c2a851851e79039f58b9efb3 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Mon, 17 May 2010 14:25:14 -0400 Subject: PCI: output FW warning in pci_read/write_vpd pci_read/write_vpd() can fail due to a timeout. Usually the command times out because of firmware issues (incorrect vpd length, etc.) on the PCI card. Currently, the timeout occurs silently. Output a message to the user indicating that they should check with their vendor for new firmware. Reviewed-by: Randy Dunlap Signed-off-by: Prarit Bhargava Signed-off-by: Jesse Barnes --- drivers/pci/access.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/access.c b/drivers/pci/access.c index affb83b42ebb..531bc697d800 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -220,8 +220,13 @@ static int pci_vpd_pci22_wait(struct pci_dev *dev) return 0; } - if (time_after(jiffies, timeout)) + if (time_after(jiffies, timeout)) { + dev_printk(KERN_DEBUG, &dev->dev, + "vpd r/w failed. This is likely a firmware " + "bug on this device. Contact the card " + "vendor for a firmware update."); return -ETIMEDOUT; + } if (fatal_signal_pending(current)) return -EINTR; if (!cond_resched()) -- cgit v1.2.3 From 8f6bce3c4f48bd79b57d6ac9f337f5aabee43ea7 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 15 May 2010 23:18:16 +0200 Subject: PCI hotplug: Use kmemdup Use kmemdup when some other buffer is immediately copied into the allocated region. A simplified version of the semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression from,to,size,flag; statement S; @@ - to = \(kmalloc\|kzalloc\)(size,flag); + to = kmemdup(from,size,flag); if (to==NULL || ...) S - memcpy(to, from, size); // Signed-off-by: Julia Lawall Signed-off-by: Jesse Barnes --- drivers/pci/hotplug/cpqphp_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index f184d1d2ecbe..cb7818ffd5cf 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c @@ -1075,13 +1075,12 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* make our own copy of the pci bus structure, * as we like tweaking it a lot */ - ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL); + ctrl->pci_bus = kmemdup(pdev->bus, sizeof(*ctrl->pci_bus), GFP_KERNEL); if (!ctrl->pci_bus) { err("out of memory\n"); rc = -ENOMEM; goto err_free_ctrl; } - memcpy(ctrl->pci_bus, pdev->bus, sizeof(*ctrl->pci_bus)); ctrl->bus = pdev->bus->number; ctrl->rev = pdev->revision; -- cgit v1.2.3 From 753a8970f68594ea69c5fc13fbca18dbd9402996 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 23 Apr 2010 19:27:25 -0400 Subject: firewire: core: Fix tlabel exhaustion problem fw_core_handle_response() was not properly clearing tlabel_mask. This was resulting in premature tlabel exhaustion. Signed-off-by: Peter Hurley This fixes an omission in 2.6.31-rc1 commit 1e626fdc "firewire: core: use more outbound tlabels" which prevented to really use 64 instead of 32 transaction labels, as soon as split transactions occurred that had their AR-resp tasklet run after the AT-req tasklet. Signed-off-by: Stefan Richter --- drivers/firewire/core-transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index 9882240205cd..901669876c25 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c @@ -842,7 +842,7 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) list_for_each_entry(t, &card->transaction_list, link) { if (t->node_id == source && t->tlabel == tlabel) { list_del(&t->link); - card->tlabel_mask &= ~(1 << t->tlabel); + card->tlabel_mask &= ~(1ULL << t->tlabel); break; } } -- cgit v1.2.3 From 107c161b7ddeeb7da43509cc6b29211885ccd9af Mon Sep 17 00:00:00 2001 From: Nitin Gupta Date: Mon, 17 May 2010 11:02:44 +0530 Subject: Staging: ramzswap: Handler for swap slot free callback Install handler for swap_slot_free_notify callback which is called when a swap slot is no longer used. This handler immediately frees memory allocated corresponding to the given swap slot. Signed-off-by: Nitin Gupta Acked-by: Linus Torvalds Acked-by: Nigel Cunningham Acked-by: Pekka Enberg Reviewed-by: Minchan Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ramzswap/TODO | 5 ----- drivers/staging/ramzswap/ramzswap_drv.c | 22 +++++++++++++--------- 2 files changed, 13 insertions(+), 14 deletions(-) delete mode 100644 drivers/staging/ramzswap/TODO (limited to 'drivers') diff --git a/drivers/staging/ramzswap/TODO b/drivers/staging/ramzswap/TODO deleted file mode 100644 index 8d64e28fac0e..000000000000 --- a/drivers/staging/ramzswap/TODO +++ /dev/null @@ -1,5 +0,0 @@ -TODO: - - Add support for swap notifiers - -Please send patches to Greg Kroah-Hartman and -Nitin Gupta diff --git a/drivers/staging/ramzswap/ramzswap_drv.c b/drivers/staging/ramzswap/ramzswap_drv.c index 167f8d17a808..d14bf9129e36 100644 --- a/drivers/staging/ramzswap/ramzswap_drv.c +++ b/drivers/staging/ramzswap/ramzswap_drv.c @@ -335,14 +335,6 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio) src = rzs->compress_buffer; - /* - * System swaps to same sector again when the stored page - * is no longer referenced by any process. So, its now safe - * to free the memory that was allocated for this page. - */ - if (rzs->table[index].page || rzs_test_flag(rzs, index, RZS_ZERO)) - ramzswap_free_page(rzs, index); - mutex_lock(&rzs->lock); user_mem = kmap_atomic(page, KM_USER0); @@ -690,9 +682,21 @@ out: return ret; } +void ramzswap_slot_free_notify(struct block_device *bdev, unsigned long index) +{ + struct ramzswap *rzs; + + rzs = bdev->bd_disk->private_data; + ramzswap_free_page(rzs, index); + rzs_stat64_inc(rzs, &rzs->stats.notify_free); + + return; +} + static struct block_device_operations ramzswap_devops = { .ioctl = ramzswap_ioctl, - .owner = THIS_MODULE, + .swap_slot_free_notify = ramzswap_slot_free_notify, + .owner = THIS_MODULE }; static int create_device(struct ramzswap *rzs, int device_id) -- cgit v1.2.3 From 61c7a080a5a061c976988fd4b844dfb468dda255 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:12:29 -0700 Subject: of: Always use 'struct device.of_node' to get device node pointer. The following structure elements duplicate the information in 'struct device.of_node' and so are being eliminated. This patch makes all readers of these elements use device.of_node instead. (struct of_device *)->node (struct dev_archdata *)->prom_node (sparc) (struct dev_archdata *)->of_node (powerpc & microblaze) Signed-off-by: Grant Likely --- arch/microblaze/kernel/of_device.c | 8 +++---- arch/microblaze/kernel/of_platform.c | 4 ++-- arch/powerpc/include/asm/macio.h | 2 +- arch/powerpc/kernel/ibmebus.c | 4 ++-- arch/powerpc/kernel/of_device.c | 8 +++---- arch/powerpc/kernel/of_platform.c | 16 +++++++------- arch/powerpc/platforms/52xx/mpc52xx_gpio.c | 4 ++-- arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 16 +++++++------- arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c | 6 +++--- arch/powerpc/platforms/82xx/ep8248e.c | 6 +++--- arch/powerpc/platforms/83xx/suspend.c | 2 +- arch/powerpc/platforms/cell/axon_msi.c | 2 +- arch/powerpc/platforms/pasemi/gpio_mdio.c | 2 +- arch/powerpc/sysdev/axonram.c | 6 +++--- arch/powerpc/sysdev/bestcomm/bestcomm.c | 8 +++---- arch/powerpc/sysdev/fsl_msi.c | 14 ++++++------- arch/powerpc/sysdev/fsl_pmc.c | 2 +- arch/powerpc/sysdev/fsl_rio.c | 30 +++++++++++++-------------- arch/powerpc/sysdev/pmi.c | 2 +- arch/sparc/include/asm/fb.h | 2 +- arch/sparc/include/asm/floppy_64.h | 4 ++-- arch/sparc/include/asm/parport.h | 2 +- arch/sparc/kernel/auxio_64.c | 2 +- arch/sparc/kernel/central.c | 4 ++-- arch/sparc/kernel/chmc.c | 10 ++++----- arch/sparc/kernel/ioport.c | 2 +- arch/sparc/kernel/of_device_32.c | 14 ++++++------- arch/sparc/kernel/of_device_64.c | 26 +++++++++++------------ arch/sparc/kernel/of_device_common.c | 4 ++-- arch/sparc/kernel/pci.c | 12 +++++------ arch/sparc/kernel/pci_common.c | 9 ++++---- arch/sparc/kernel/pci_fire.c | 4 ++-- arch/sparc/kernel/pci_msi.c | 18 ++++++++-------- arch/sparc/kernel/pci_psycho.c | 4 ++-- arch/sparc/kernel/pci_sabre.c | 4 ++-- arch/sparc/kernel/pci_schizo.c | 14 ++++++------- arch/sparc/kernel/pci_sun4v.c | 8 +++---- arch/sparc/kernel/power.c | 4 ++-- arch/sparc/kernel/psycho_common.c | 2 +- arch/sparc/kernel/sbus.c | 16 +++++++------- arch/sparc/kernel/time_32.c | 2 +- arch/sparc/kernel/time_64.c | 6 +++--- drivers/ata/pata_macio.c | 2 +- drivers/ata/pata_mpc52xx.c | 10 ++++----- drivers/ata/pata_of_platform.c | 2 +- drivers/ata/sata_fsl.c | 4 ++-- drivers/atm/fore200e.c | 16 +++++++------- drivers/block/swim3.c | 2 +- drivers/block/xsysace.c | 8 +++---- drivers/cdrom/viocd.c | 2 +- drivers/char/hw_random/n2-drv.c | 2 +- drivers/char/hw_random/pasemi-rng.c | 2 +- drivers/char/ipmi/ipmi_si_intf.c | 4 ++-- drivers/char/viotape.c | 2 +- drivers/char/xilinx_hwicap/xilinx_hwicap.c | 6 +++--- drivers/crypto/talitos.c | 2 +- drivers/dma/fsldma.c | 6 +++--- drivers/gpio/pca953x.c | 2 +- drivers/i2c/busses/i2c-cpm.c | 20 +++++++++--------- drivers/i2c/busses/i2c-ibm_iic.c | 4 ++-- drivers/i2c/busses/i2c-mpc.c | 17 ++++++++------- drivers/ide/pmac.c | 10 ++++----- drivers/infiniband/hw/ehca/ehca_main.c | 11 +++++----- drivers/input/serio/i8042-sparcio.h | 2 +- drivers/input/serio/xilinx_ps2.c | 8 +++---- drivers/leds/leds-gpio.c | 2 +- drivers/macintosh/macio_asic.c | 16 +++++++------- drivers/macintosh/macio_sysfs.c | 6 +++--- drivers/macintosh/mediabay.c | 2 +- drivers/macintosh/rack-meter.c | 4 ++-- drivers/macintosh/therm_pm72.c | 2 +- drivers/mmc/host/of_mmc_spi.c | 4 ++-- drivers/mmc/host/sdhci-of-core.c | 2 +- drivers/mtd/maps/physmap_of.c | 6 +++--- drivers/mtd/maps/sun_uflash.c | 2 +- drivers/mtd/nand/fsl_elbc_nand.c | 6 +++--- drivers/mtd/nand/ndfc.c | 10 ++++----- drivers/mtd/nand/pasemi_nand.c | 2 +- drivers/net/can/sja1000/sja1000_of_platform.c | 4 ++-- drivers/net/ehea/ehea_main.c | 14 ++++++------- drivers/net/fec_mpc52xx.c | 12 +++++------ drivers/net/fec_mpc52xx_phy.c | 4 ++-- drivers/net/fs_enet/fs_enet-main.c | 8 +++---- drivers/net/fs_enet/mac-fcc.c | 8 +++---- drivers/net/fs_enet/mac-fec.c | 4 ++-- drivers/net/fs_enet/mac-scc.c | 6 +++--- drivers/net/fs_enet/mii-fec.c | 6 +++--- drivers/net/fsl_pq_mdio.c | 2 +- drivers/net/gianfar.c | 6 +++--- drivers/net/greth.c | 3 ++- drivers/net/ibm_newemac/core.c | 13 ++++++------ drivers/net/ibm_newemac/debug.c | 9 ++++---- drivers/net/ibm_newemac/debug.h | 4 ++-- drivers/net/ibm_newemac/mal.c | 28 ++++++++++++------------- drivers/net/ibm_newemac/rgmii.c | 12 +++++------ drivers/net/ibm_newemac/tah.c | 7 ++++--- drivers/net/ibm_newemac/zmii.c | 9 ++++---- drivers/net/ll_temac_main.c | 10 ++++----- drivers/net/myri_sbus.c | 2 +- drivers/net/niu.c | 10 ++++----- drivers/net/phy/mdio-gpio.c | 6 +++--- drivers/net/sunbmac.c | 6 +++--- drivers/net/sunhme.c | 8 +++---- drivers/net/sunlance.c | 6 +++--- drivers/net/sunqe.c | 6 +++--- drivers/net/ucc_geth.c | 2 +- drivers/net/xilinx_emaclite.c | 10 ++++----- drivers/of/device.c | 20 +++++++++--------- drivers/of/of_i2c.c | 2 +- drivers/of/of_mdio.c | 4 ++-- drivers/pcmcia/electra_cf.c | 2 +- drivers/sbus/char/bbc_envctrl.c | 4 ++-- drivers/sbus/char/bbc_i2c.c | 4 ++-- drivers/sbus/char/display7seg.c | 2 +- drivers/sbus/char/envctrl.c | 2 +- drivers/sbus/char/flash.c | 4 ++-- drivers/sbus/char/uctrl.c | 2 +- drivers/scsi/ibmvscsi/ibmvfc.c | 2 +- drivers/scsi/ibmvscsi/ibmvscsi.c | 2 +- drivers/scsi/qlogicpti.c | 10 ++++----- drivers/scsi/sun_esp.c | 16 +++++++------- drivers/serial/apbuart.c | 2 +- drivers/serial/cpm_uart/cpm_uart_core.c | 2 +- drivers/serial/mpc52xx_uart.c | 8 +++---- drivers/serial/nwpserial.c | 2 +- drivers/serial/of_serial.c | 4 ++-- drivers/serial/pmac_zilog.c | 2 +- drivers/serial/sunhv.c | 2 +- drivers/serial/sunsab.c | 6 +++--- drivers/serial/sunsu.c | 6 +++--- drivers/serial/sunzilog.c | 8 +++---- drivers/serial/uartlite.c | 6 +++--- drivers/serial/ucc_uart.c | 2 +- drivers/spi/mpc52xx_psc_spi.c | 11 +++++----- drivers/spi/mpc52xx_spi.c | 14 ++++++------- drivers/spi/spi_mpc8xxx.c | 8 +++---- drivers/usb/host/ehci-ppc-of.c | 2 +- drivers/usb/host/fhci-hcd.c | 4 ++-- drivers/usb/host/isp1760-if.c | 2 +- drivers/usb/host/ohci-ppc-of.c | 2 +- drivers/video/cg6.c | 2 +- drivers/video/ffb.c | 2 +- drivers/video/fsl-diu-fb.c | 2 +- drivers/video/platinumfb.c | 2 +- drivers/video/sunxvr1000.c | 2 +- drivers/video/xilinxfb.c | 18 ++++++++-------- drivers/watchdog/cpwd.c | 2 +- sound/aoa/fabrics/layout.c | 2 +- sound/aoa/soundbus/core.c | 8 +++---- sound/aoa/soundbus/i2sbus/control.c | 2 +- sound/aoa/soundbus/i2sbus/core.c | 4 ++-- sound/aoa/soundbus/sysfs.c | 4 ++-- sound/soc/fsl/mpc5200_dma.c | 6 +++--- sound/soc/fsl/mpc5200_psc_i2s.c | 2 +- sound/soc/fsl/mpc8610_hpcd.c | 2 +- sound/sparc/cs4231.c | 6 +++--- sound/sparc/dbri.c | 2 +- 157 files changed, 497 insertions(+), 488 deletions(-) (limited to 'drivers') diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c index f6c521898ebf..90d2246e15c0 100644 --- a/arch/microblaze/kernel/of_device.c +++ b/arch/microblaze/kernel/of_device.c @@ -12,7 +12,7 @@ void of_device_make_bus_id(struct of_device *dev) { static atomic_t bus_no_reg_magic; - struct device_node *node = dev->node; + struct device_node *node = dev->dev.of_node; const u32 *reg; u64 addr; int magic; @@ -76,17 +76,17 @@ int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) ofdev = to_of_device(dev); - if (add_uevent_var(env, "OF_NAME=%s", ofdev->node->name)) + if (add_uevent_var(env, "OF_NAME=%s", ofdev->dev.of_node->name)) return -ENOMEM; - if (add_uevent_var(env, "OF_TYPE=%s", ofdev->node->type)) + if (add_uevent_var(env, "OF_TYPE=%s", ofdev->dev.of_node->type)) return -ENOMEM; /* Since the compatible field can contain pretty much anything * it's not really legal to split it out with commas. We split it * up using a number of environment variables instead. */ - compat = of_get_property(ofdev->node, "compatible", &cplen); + compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen); while (compat && *compat && cplen > 0) { if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat)) return -ENOMEM; diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c index 0dc755286d38..46a1e105a6bd 100644 --- a/arch/microblaze/kernel/of_platform.c +++ b/arch/microblaze/kernel/of_platform.c @@ -166,7 +166,7 @@ EXPORT_SYMBOL(of_platform_bus_probe); static int of_dev_node_match(struct device *dev, void *data) { - return to_of_device(dev)->node == data; + return to_of_device(dev)->dev.of_node == data; } struct of_device *of_find_device_by_node(struct device_node *np) @@ -184,7 +184,7 @@ EXPORT_SYMBOL(of_find_device_by_node); static int of_dev_phandle_match(struct device *dev, void *data) { phandle *ph = data; - return to_of_device(dev)->node->phandle == *ph; + return to_of_device(dev)->dev.of_node->phandle == *ph; } struct of_device *of_find_device_by_phandle(phandle ph) diff --git a/arch/powerpc/include/asm/macio.h b/arch/powerpc/include/asm/macio.h index a062c57696d0..19a661b4cb98 100644 --- a/arch/powerpc/include/asm/macio.h +++ b/arch/powerpc/include/asm/macio.h @@ -108,7 +108,7 @@ static inline void* macio_get_drvdata(struct macio_dev *dev) static inline struct device_node *macio_get_of_node(struct macio_dev *mdev) { - return mdev->ofdev.node; + return mdev->ofdev.dev.of_node; } #ifdef CONFIG_PCI diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 71cf280da184..a9f31631a293 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -140,14 +140,14 @@ static struct dma_map_ops ibmebus_dma_ops = { static int ibmebus_match_path(struct device *dev, void *data) { - struct device_node *dn = to_of_device(dev)->node; + struct device_node *dn = to_of_device(dev)->dev.of_node; return (dn->full_name && (strcasecmp((char *)data, dn->full_name) == 0)); } static int ibmebus_match_node(struct device *dev, void *data) { - return to_of_device(dev)->node == data; + return to_of_device(dev)->dev.of_node == data; } static int ibmebus_create_device(struct device_node *dn) diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index 9577e6f4e3bf..285c8490c547 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c @@ -13,7 +13,7 @@ static void of_device_make_bus_id(struct of_device *dev) { static atomic_t bus_no_reg_magic; - struct device_node *node = dev->node; + struct device_node *node = dev->dev.of_node; const u32 *reg; u64 addr; int magic; @@ -96,17 +96,17 @@ int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) ofdev = to_of_device(dev); - if (add_uevent_var(env, "OF_NAME=%s", ofdev->node->name)) + if (add_uevent_var(env, "OF_NAME=%s", ofdev->dev.of_node->name)) return -ENOMEM; - if (add_uevent_var(env, "OF_TYPE=%s", ofdev->node->type)) + if (add_uevent_var(env, "OF_TYPE=%s", ofdev->dev.of_node->type)) return -ENOMEM; /* Since the compatible field can contain pretty much anything * it's not really legal to split it out with commas. We split it * up using a number of environment variables instead. */ - compat = of_get_property(ofdev->node, "compatible", &cplen); + compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen); while (compat && *compat && cplen > 0) { if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat)) return -ENOMEM; diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 6c1dfc3ff8bc..1c747c474415 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -195,7 +195,7 @@ EXPORT_SYMBOL(of_platform_bus_probe); static int of_dev_node_match(struct device *dev, void *data) { - return to_of_device(dev)->node == data; + return to_of_device(dev)->dev.of_node == data; } struct of_device *of_find_device_by_node(struct device_node *np) @@ -213,7 +213,7 @@ EXPORT_SYMBOL(of_find_device_by_node); static int of_dev_phandle_match(struct device *dev, void *data) { phandle *ph = data; - return to_of_device(dev)->node->phandle == *ph; + return to_of_device(dev)->dev.of_node->phandle == *ph; } struct of_device *of_find_device_by_phandle(phandle ph) @@ -246,10 +246,10 @@ static int __devinit of_pci_phb_probe(struct of_device *dev, if (ppc_md.pci_setup_phb == NULL) return -ENODEV; - printk(KERN_INFO "Setting up PCI bus %s\n", dev->node->full_name); + pr_info("Setting up PCI bus %s\n", dev->dev.of_node->full_name); /* Alloc and setup PHB data structure */ - phb = pcibios_alloc_controller(dev->node); + phb = pcibios_alloc_controller(dev->dev.of_node); if (!phb) return -ENODEV; @@ -263,19 +263,19 @@ static int __devinit of_pci_phb_probe(struct of_device *dev, } /* Process "ranges" property */ - pci_process_bridge_OF_ranges(phb, dev->node, 0); + pci_process_bridge_OF_ranges(phb, dev->dev.of_node, 0); /* Init pci_dn data structures */ pci_devs_phb_init_dynamic(phb); /* Register devices with EEH */ #ifdef CONFIG_EEH - if (dev->node->child) - eeh_add_device_tree_early(dev->node); + if (dev->dev.of_node->child) + eeh_add_device_tree_early(dev->dev.of_node); #endif /* CONFIG_EEH */ /* Scan the bus */ - pcibios_scan_phb(phb, dev->node); + pcibios_scan_phb(phb, dev->dev.of_node); if (phb->bus == NULL) return -ENXIO; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c index fda7c2a18282..576669fc4fbf 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c @@ -168,7 +168,7 @@ static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev, ofchip->gc.get = mpc52xx_wkup_gpio_get; ofchip->gc.set = mpc52xx_wkup_gpio_set; - ret = of_mm_gpiochip_add(ofdev->node, &chip->mmchip); + ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); if (ret) return ret; @@ -329,7 +329,7 @@ static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev, ofchip->gc.get = mpc52xx_simple_gpio_get; ofchip->gc.set = mpc52xx_simple_gpio_set; - ret = of_mm_gpiochip_add(ofdev->node, &chip->mmchip); + ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); if (ret) return ret; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index a60ee39d3b78..42c507f9c35b 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -734,8 +734,8 @@ static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev, spin_lock_init(&gpt->lock); gpt->dev = &ofdev->dev; - gpt->ipb_freq = mpc5xxx_get_bus_frequency(ofdev->node); - gpt->regs = of_iomap(ofdev->node, 0); + gpt->ipb_freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node); + gpt->regs = of_iomap(ofdev->dev.of_node, 0); if (!gpt->regs) { kfree(gpt); return -ENOMEM; @@ -743,21 +743,21 @@ static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev, dev_set_drvdata(&ofdev->dev, gpt); - mpc52xx_gpt_gpio_setup(gpt, ofdev->node); - mpc52xx_gpt_irq_setup(gpt, ofdev->node); + mpc52xx_gpt_gpio_setup(gpt, ofdev->dev.of_node); + mpc52xx_gpt_irq_setup(gpt, ofdev->dev.of_node); mutex_lock(&mpc52xx_gpt_list_mutex); list_add(&gpt->list, &mpc52xx_gpt_list); mutex_unlock(&mpc52xx_gpt_list_mutex); /* check if this device could be a watchdog */ - if (of_get_property(ofdev->node, "fsl,has-wdt", NULL) || - of_get_property(ofdev->node, "has-wdt", NULL)) { + if (of_get_property(ofdev->dev.of_node, "fsl,has-wdt", NULL) || + of_get_property(ofdev->dev.of_node, "has-wdt", NULL)) { const u32 *on_boot_wdt; gpt->wdt_mode = MPC52xx_GPT_CAN_WDT; - on_boot_wdt = of_get_property(ofdev->node, "fsl,wdt-on-boot", - NULL); + on_boot_wdt = of_get_property(ofdev->dev.of_node, + "fsl,wdt-on-boot", NULL); if (on_boot_wdt) { dev_info(gpt->dev, "used as watchdog\n"); gpt->wdt_mode |= MPC52xx_GPT_IS_WDT; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c index d4f8be307cd5..17b99ba7a8cc 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c @@ -445,14 +445,14 @@ mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match) if (lpbfifo.dev != NULL) return -ENOSPC; - lpbfifo.irq = irq_of_parse_and_map(op->node, 0); + lpbfifo.irq = irq_of_parse_and_map(op->dev.of_node, 0); if (!lpbfifo.irq) return -ENODEV; - if (of_address_to_resource(op->node, 0, &res)) + if (of_address_to_resource(op->dev.of_node, 0, &res)) return -ENODEV; lpbfifo.regs_phys = res.start; - lpbfifo.regs = of_iomap(op->node, 0); + lpbfifo.regs = of_iomap(op->dev.of_node, 0); if (!lpbfifo.regs) return -ENOMEM; diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c index f21555d3395a..0176ae8249d5 100644 --- a/arch/powerpc/platforms/82xx/ep8248e.c +++ b/arch/powerpc/platforms/82xx/ep8248e.c @@ -119,12 +119,12 @@ static int __devinit ep8248e_mdio_probe(struct of_device *ofdev, struct device_node *node; int ret; - node = of_get_parent(ofdev->node); + node = of_get_parent(ofdev->dev.of_node); of_node_put(node); if (node != ep8248e_bcsr_node) return -ENODEV; - ret = of_address_to_resource(ofdev->node, 0, &res); + ret = of_address_to_resource(ofdev->dev.of_node, 0, &res); if (ret) return ret; @@ -142,7 +142,7 @@ static int __devinit ep8248e_mdio_probe(struct of_device *ofdev, bus->parent = &ofdev->dev; snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start); - ret = of_mdiobus_register(bus, ofdev->node); + ret = of_mdiobus_register(bus, ofdev->dev.of_node); if (ret) goto err_free_irq; diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index 43805348b81e..aa0b764b1cc4 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c @@ -321,7 +321,7 @@ static struct platform_suspend_ops mpc83xx_suspend_ops = { static int pmc_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct resource res; struct pmc_type *type = match->data; int ret = 0; diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 8efe48192f3f..177a4f1369b4 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -345,7 +345,7 @@ static int axon_msi_shutdown(struct of_device *device) static int axon_msi_probe(struct of_device *device, const struct of_device_id *device_id) { - struct device_node *dn = device->node; + struct device_node *dn = device->dev.of_node; struct axon_msic *msic; unsigned int virq; int dcr_base, dcr_len; diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c index 0f881f64583e..c44e1b3b91db 100644 --- a/arch/powerpc/platforms/pasemi/gpio_mdio.c +++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c @@ -220,7 +220,7 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev, const struct of_device_id *match) { struct device *dev = &ofdev->dev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct mii_bus *new_bus; struct gpio_priv *priv; const unsigned int *prop; diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c index 88f4ae787832..88b21fccf0c9 100644 --- a/arch/powerpc/sysdev/axonram.c +++ b/arch/powerpc/sysdev/axonram.c @@ -185,7 +185,7 @@ axon_ram_probe(struct of_device *device, const struct of_device_id *device_id) axon_ram_bank_id++; dev_info(&device->dev, "Found memory controller on %s\n", - device->node->full_name); + device->dev.of_node->full_name); bank = kzalloc(sizeof(struct axon_ram_bank), GFP_KERNEL); if (bank == NULL) { @@ -198,7 +198,7 @@ axon_ram_probe(struct of_device *device, const struct of_device_id *device_id) bank->device = device; - if (of_address_to_resource(device->node, 0, &resource) != 0) { + if (of_address_to_resource(device->dev.of_node, 0, &resource) != 0) { dev_err(&device->dev, "Cannot access device tree\n"); rc = -EFAULT; goto failed; @@ -253,7 +253,7 @@ axon_ram_probe(struct of_device *device, const struct of_device_id *device_id) blk_queue_logical_block_size(bank->disk->queue, AXON_RAM_SECTOR_SIZE); add_disk(bank->disk); - bank->irq_id = irq_of_parse_and_map(device->node, 0); + bank->irq_id = irq_of_parse_and_map(device->dev.of_node, 0); if (bank->irq_id == NO_IRQ) { dev_err(&device->dev, "Cannot access ECC interrupt ID\n"); rc = -EFAULT; diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c index 378ebd9aac18..d32d5389b67a 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm.c +++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c @@ -377,7 +377,7 @@ mpc52xx_bcom_probe(struct of_device *op, const struct of_device_id *match) printk(KERN_INFO "DMA: MPC52xx BestComm driver\n"); /* Get the bestcomm node */ - of_node_get(op->node); + of_node_get(op->dev.of_node); /* Prepare SRAM */ ofn_sram = of_find_matching_node(NULL, mpc52xx_sram_ids); @@ -406,10 +406,10 @@ mpc52xx_bcom_probe(struct of_device *op, const struct of_device_id *match) } /* Save the node */ - bcom_eng->ofnode = op->node; + bcom_eng->ofnode = op->dev.of_node; /* Get, reserve & map io */ - if (of_address_to_resource(op->node, 0, &res_bcom)) { + if (of_address_to_resource(op->dev.of_node, 0, &res_bcom)) { printk(KERN_ERR DRIVER_NAME ": " "Can't get resource\n"); rv = -EINVAL; @@ -453,7 +453,7 @@ error_sramclean: kfree(bcom_eng); bcom_sram_cleanup(); error_ofput: - of_node_put(op->node); + of_node_put(op->dev.of_node); printk(KERN_ERR "DMA: MPC52xx BestComm init failed !\n"); diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 3482e3fd89c0..569dae8ea1ce 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -249,7 +249,7 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, goto error_out; } - msi->irqhost = irq_alloc_host(dev->node, IRQ_HOST_MAP_LINEAR, + msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_HOST_MAP_LINEAR, NR_MSI_IRQS, &fsl_msi_host_ops, 0); if (msi->irqhost == NULL) { @@ -259,10 +259,10 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, } /* Get the MSI reg base */ - err = of_address_to_resource(dev->node, 0, &res); + err = of_address_to_resource(dev->dev.of_node, 0, &res); if (err) { dev_err(&dev->dev, "%s resource error!\n", - dev->node->full_name); + dev->dev.of_node->full_name); goto error_out; } @@ -285,16 +285,16 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, goto error_out; } - p = of_get_property(dev->node, "interrupts", &count); + p = of_get_property(dev->dev.of_node, "interrupts", &count); if (!p) { dev_err(&dev->dev, "no interrupts property found on %s\n", - dev->node->full_name); + dev->dev.of_node->full_name); err = -ENODEV; goto error_out; } if (count % 8 != 0) { dev_err(&dev->dev, "Malformed interrupts property on %s\n", - dev->node->full_name); + dev->dev.of_node->full_name); err = -EINVAL; goto error_out; } @@ -303,7 +303,7 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, for (i = 0; i < count / 2; i++) { if (i > NR_MSI_REG) break; - virt_msir = irq_of_parse_and_map(dev->node, i); + virt_msir = irq_of_parse_and_map(dev->dev.of_node, i); if (virt_msir != NO_IRQ) { set_irq_data(virt_msir, (void *)i); set_irq_chained_handler(virt_msir, fsl_msi_cascade); diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index a7635a993dca..2ebe817ca72f 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c @@ -60,7 +60,7 @@ static struct platform_suspend_ops pmc_suspend_ops = { static int pmc_probe(struct of_device *ofdev, const struct of_device_id *id) { - pmc_regs = of_iomap(ofdev->node, 0); + pmc_regs = of_iomap(ofdev->dev.of_node, 0); if (!pmc_regs) return -ENOMEM; diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 71fba88f50db..a98d51639243 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -1015,41 +1015,41 @@ int fsl_rio_setup(struct of_device *dev) u64 law_start, law_size; int paw, aw, sw; - if (!dev->node) { + if (!dev->dev.of_node) { dev_err(&dev->dev, "Device OF-Node is NULL"); return -EFAULT; } - rc = of_address_to_resource(dev->node, 0, ®s); + rc = of_address_to_resource(dev->dev.of_node, 0, ®s); if (rc) { dev_err(&dev->dev, "Can't get %s property 'reg'\n", - dev->node->full_name); + dev->dev.of_node->full_name); return -EFAULT; } - dev_info(&dev->dev, "Of-device full name %s\n", dev->node->full_name); + dev_info(&dev->dev, "Of-device full name %s\n", dev->dev.of_node->full_name); dev_info(&dev->dev, "Regs: %pR\n", ®s); - dt_range = of_get_property(dev->node, "ranges", &rlen); + dt_range = of_get_property(dev->dev.of_node, "ranges", &rlen); if (!dt_range) { dev_err(&dev->dev, "Can't get %s property 'ranges'\n", - dev->node->full_name); + dev->dev.of_node->full_name); return -EFAULT; } /* Get node address wide */ - cell = of_get_property(dev->node, "#address-cells", NULL); + cell = of_get_property(dev->dev.of_node, "#address-cells", NULL); if (cell) aw = *cell; else - aw = of_n_addr_cells(dev->node); + aw = of_n_addr_cells(dev->dev.of_node); /* Get node size wide */ - cell = of_get_property(dev->node, "#size-cells", NULL); + cell = of_get_property(dev->dev.of_node, "#size-cells", NULL); if (cell) sw = *cell; else - sw = of_n_size_cells(dev->node); + sw = of_n_size_cells(dev->dev.of_node); /* Get parent address wide wide */ - paw = of_n_addr_cells(dev->node); + paw = of_n_addr_cells(dev->dev.of_node); law_start = of_read_number(dt_range + aw, paw); law_size = of_read_number(dt_range + aw + paw, sw); @@ -1089,9 +1089,9 @@ int fsl_rio_setup(struct of_device *dev) port->iores.flags = IORESOURCE_MEM; port->iores.name = "rio_io_win"; - priv->bellirq = irq_of_parse_and_map(dev->node, 2); - priv->txirq = irq_of_parse_and_map(dev->node, 3); - priv->rxirq = irq_of_parse_and_map(dev->node, 4); + priv->bellirq = irq_of_parse_and_map(dev->dev.of_node, 2); + priv->txirq = irq_of_parse_and_map(dev->dev.of_node, 3); + priv->rxirq = irq_of_parse_and_map(dev->dev.of_node, 4); dev_info(&dev->dev, "bellirq: %d, txirq: %d, rxirq %d\n", priv->bellirq, priv->txirq, priv->rxirq); @@ -1195,7 +1195,7 @@ static int __devinit fsl_of_rio_rpn_probe(struct of_device *dev, { int rc; printk(KERN_INFO "Setting up RapidIO peer-to-peer network %s\n", - dev->node->full_name); + dev->dev.of_node->full_name); rc = fsl_rio_setup(dev); if (rc) diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c index 652652db4ce2..ff758bff1b7a 100644 --- a/arch/powerpc/sysdev/pmi.c +++ b/arch/powerpc/sysdev/pmi.c @@ -124,7 +124,7 @@ static void pmi_notify_handlers(struct work_struct *work) static int pmi_of_probe(struct of_device *dev, const struct of_device_id *match) { - struct device_node *np = dev->node; + struct device_node *np = dev->dev.of_node; int rc; if (data) { diff --git a/arch/sparc/include/asm/fb.h b/arch/sparc/include/asm/fb.h index b83e44729655..e834880be204 100644 --- a/arch/sparc/include/asm/fb.h +++ b/arch/sparc/include/asm/fb.h @@ -18,7 +18,7 @@ static inline int fb_is_primary_device(struct fb_info *info) struct device *dev = info->device; struct device_node *node; - node = dev->archdata.prom_node; + node = dev->of_node; if (node && node == of_console_device) return 1; diff --git a/arch/sparc/include/asm/floppy_64.h b/arch/sparc/include/asm/floppy_64.h index 36439d67ad71..8fac3ab22f36 100644 --- a/arch/sparc/include/asm/floppy_64.h +++ b/arch/sparc/include/asm/floppy_64.h @@ -589,7 +589,7 @@ static unsigned long __init sun_floppy_init(void) if (!op) return 0; - state_prop = of_get_property(op->node, "status", NULL); + state_prop = of_get_property(op->dev.of_node, "status", NULL); if (state_prop && !strncmp(state_prop, "disabled", 8)) return 0; @@ -716,7 +716,7 @@ static unsigned long __init sun_floppy_init(void) return sun_floppy_types[0]; } - prop = of_get_property(op->node, "status", NULL); + prop = of_get_property(op->dev.of_node, "status", NULL); if (prop && !strncmp(state, "disabled", 8)) return 0; diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h index ff9ead640c4a..1bb6a41b00f2 100644 --- a/arch/sparc/include/asm/parport.h +++ b/arch/sparc/include/asm/parport.h @@ -113,7 +113,7 @@ static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id struct parport *p; int slot, err; - parent = op->node->parent; + parent = op->dev.of_node->parent; if (!strcmp(parent->name, "dma")) { p = parport_pc_probe_port(base, base + 0x400, op->irqs[0], PARPORT_DMA_NOFIFO, diff --git a/arch/sparc/kernel/auxio_64.c b/arch/sparc/kernel/auxio_64.c index 9f52db2d441c..bd8421a26856 100644 --- a/arch/sparc/kernel/auxio_64.c +++ b/arch/sparc/kernel/auxio_64.c @@ -104,7 +104,7 @@ MODULE_DEVICE_TABLE(of, auxio_match); static int __devinit auxio_probe(struct of_device *dev, const struct of_device_id *match) { - struct device_node *dp = dev->node; + struct device_node *dp = dev->dev.of_node; unsigned long size; if (!strcmp(dp->parent->name, "ebus")) { diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index 415c86d5a8da..d533f3d5d484 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c @@ -168,7 +168,7 @@ static int __devinit fhc_probe(struct of_device *op, goto out; } - if (!strcmp(op->node->parent->name, "central")) + if (!strcmp(op->dev.of_node->parent->name, "central")) p->central = true; p->pregs = of_ioremap(&op->resource[0], 0, @@ -183,7 +183,7 @@ static int __devinit fhc_probe(struct of_device *op, reg = upa_readl(p->pregs + FHC_PREGS_BSR); p->board_num = ((reg >> 16) & 1) | ((reg >> 12) & 0x0e); } else { - p->board_num = of_getintprop_default(op->node, "board#", -1); + p->board_num = of_getintprop_default(op->dev.of_node, "board#", -1); if (p->board_num == -1) { printk(KERN_ERR "fhc: No board# property\n"); goto out_unmap_pregs; diff --git a/arch/sparc/kernel/chmc.c b/arch/sparc/kernel/chmc.c index e1a9598e2a4d..936879639eb6 100644 --- a/arch/sparc/kernel/chmc.c +++ b/arch/sparc/kernel/chmc.c @@ -425,7 +425,7 @@ static int __devinit jbusmc_probe(struct of_device *op, INIT_LIST_HEAD(&p->list); err = -ENODEV; - prop = of_get_property(op->node, "portid", &len); + prop = of_get_property(op->dev.of_node, "portid", &len); if (!prop || len != 4) { printk(KERN_ERR PFX "Cannot find portid.\n"); goto out_free; @@ -433,7 +433,7 @@ static int __devinit jbusmc_probe(struct of_device *op, p->portid = *prop; - prop = of_get_property(op->node, "memory-control-register-1", &len); + prop = of_get_property(op->dev.of_node, "memory-control-register-1", &len); if (!prop || len != 8) { printk(KERN_ERR PFX "Cannot get memory control register 1.\n"); goto out_free; @@ -449,7 +449,7 @@ static int __devinit jbusmc_probe(struct of_device *op, } err = -ENODEV; - ml = of_get_property(op->node, "memory-layout", &p->layout_len); + ml = of_get_property(op->dev.of_node, "memory-layout", &p->layout_len); if (!ml) { printk(KERN_ERR PFX "Cannot get memory layout property.\n"); goto out_iounmap; @@ -466,7 +466,7 @@ static int __devinit jbusmc_probe(struct of_device *op, mc_list_add(&p->list); printk(KERN_INFO PFX "UltraSPARC-IIIi memory controller at %s\n", - op->node->full_name); + op->dev.of_node->full_name); dev_set_drvdata(&op->dev, p); @@ -693,7 +693,7 @@ static void chmc_fetch_decode_regs(struct chmc *p) static int __devinit chmc_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; unsigned long ver; const void *pval; int len, portid; diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 84e5386714cd..703e4aa9bc38 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -290,7 +290,7 @@ static void *sbus_alloc_coherent(struct device *dev, size_t len, if (mmu_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0) goto err_noiommu; - res->name = op->node->name; + res->name = op->dev.of_node->name; return (void *)(unsigned long)res->start; diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index 4926c1babd84..707311716142 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c @@ -254,10 +254,10 @@ static void __init build_device_resources(struct of_device *op, return; p_op = to_of_device(parent); - bus = of_match_bus(p_op->node); - bus->count_cells(op->node, &na, &ns); + bus = of_match_bus(p_op->dev.of_node); + bus->count_cells(op->dev.of_node, &na, &ns); - preg = of_get_property(op->node, bus->addr_prop_name, &num_reg); + preg = of_get_property(op->dev.of_node, bus->addr_prop_name, &num_reg); if (!preg || num_reg == 0) return; @@ -271,8 +271,8 @@ static void __init build_device_resources(struct of_device *op, struct resource *r = &op->resource[index]; u32 addr[OF_MAX_ADDR_CELLS]; const u32 *reg = (preg + (index * ((na + ns) * 4))); - struct device_node *dp = op->node; - struct device_node *pp = p_op->node; + struct device_node *dp = op->dev.of_node; + struct device_node *pp = p_op->dev.of_node; struct of_bus *pbus, *dbus; u64 size, result = OF_BAD_ADDR; unsigned long flags; @@ -321,7 +321,7 @@ static void __init build_device_resources(struct of_device *op, if (of_resource_verbose) printk("%s reg[%d] -> %llx\n", - op->node->full_name, index, + op->dev.of_node->full_name, index, result); if (result != OF_BAD_ADDR) { @@ -329,7 +329,7 @@ static void __init build_device_resources(struct of_device *op, r->end = result + size - 1; r->flags = flags | ((result >> 32ULL) & 0xffUL); } - r->name = op->node->name; + r->name = op->dev.of_node->name; } } diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index 5bc74161667c..c8e352e0a098 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -323,10 +323,10 @@ static void __init build_device_resources(struct of_device *op, return; p_op = to_of_device(parent); - bus = of_match_bus(p_op->node); - bus->count_cells(op->node, &na, &ns); + bus = of_match_bus(p_op->dev.of_node); + bus->count_cells(op->dev.of_node, &na, &ns); - preg = of_get_property(op->node, bus->addr_prop_name, &num_reg); + preg = of_get_property(op->dev.of_node, bus->addr_prop_name, &num_reg); if (!preg || num_reg == 0) return; @@ -340,7 +340,7 @@ static void __init build_device_resources(struct of_device *op, if (num_reg > PROMREG_MAX) { printk(KERN_WARNING "%s: Too many regs (%d), " "limiting to %d.\n", - op->node->full_name, num_reg, PROMREG_MAX); + op->dev.of_node->full_name, num_reg, PROMREG_MAX); num_reg = PROMREG_MAX; } @@ -348,8 +348,8 @@ static void __init build_device_resources(struct of_device *op, struct resource *r = &op->resource[index]; u32 addr[OF_MAX_ADDR_CELLS]; const u32 *reg = (preg + (index * ((na + ns) * 4))); - struct device_node *dp = op->node; - struct device_node *pp = p_op->node; + struct device_node *dp = op->dev.of_node; + struct device_node *pp = p_op->dev.of_node; struct of_bus *pbus, *dbus; u64 size, result = OF_BAD_ADDR; unsigned long flags; @@ -397,7 +397,7 @@ static void __init build_device_resources(struct of_device *op, if (of_resource_verbose) printk("%s reg[%d] -> %llx\n", - op->node->full_name, index, + op->dev.of_node->full_name, index, result); if (result != OF_BAD_ADDR) { @@ -408,7 +408,7 @@ static void __init build_device_resources(struct of_device *op, r->end = result + size - 1; r->flags = flags; } - r->name = op->node->name; + r->name = op->dev.of_node->name; } } @@ -530,7 +530,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op, struct device *parent, unsigned int irq) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct device_node *pp, *ip; unsigned int orig_irq = irq; int nid; @@ -575,7 +575,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op, if (of_irq_verbose) printk("%s: Apply [%s:%x] imap --> [%s:%x]\n", - op->node->full_name, + op->dev.of_node->full_name, pp->full_name, this_orig_irq, (iret ? iret->full_name : "NULL"), irq); @@ -594,7 +594,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op, if (of_irq_verbose) printk("%s: PCI swizzle [%s] " "%x --> %x\n", - op->node->full_name, + op->dev.of_node->full_name, pp->full_name, this_orig_irq, irq); @@ -611,11 +611,11 @@ static unsigned int __init build_one_device_irq(struct of_device *op, if (!ip) return orig_irq; - irq = ip->irq_trans->irq_build(op->node, irq, + irq = ip->irq_trans->irq_build(op->dev.of_node, irq, ip->irq_trans->data); if (of_irq_verbose) printk("%s: Apply IRQ trans [%s] %x --> %x\n", - op->node->full_name, ip->full_name, orig_irq, irq); + op->dev.of_node->full_name, ip->full_name, orig_irq, irq); out: nid = of_node_to_nid(dp); diff --git a/arch/sparc/kernel/of_device_common.c b/arch/sparc/kernel/of_device_common.c index 0247e68210b3..10c6c36a6e75 100644 --- a/arch/sparc/kernel/of_device_common.c +++ b/arch/sparc/kernel/of_device_common.c @@ -16,7 +16,7 @@ static int node_match(struct device *dev, void *data) struct of_device *op = to_of_device(dev); struct device_node *dp = data; - return (op->node == dp); + return (op->dev.of_node == dp); } struct of_device *of_find_device_by_node(struct device_node *dp) @@ -48,7 +48,7 @@ EXPORT_SYMBOL(irq_of_parse_and_map); void of_propagate_archdata(struct of_device *bus) { struct dev_archdata *bus_sd = &bus->dev.archdata; - struct device_node *bus_dp = bus->node; + struct device_node *bus_dp = bus->dev.of_node; struct device_node *dp; for (dp = bus_dp->child; dp; dp = dp->sibling) { diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 0c920147b4ef..c7a214ec5aff 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -654,7 +654,7 @@ show_pciobppath_attr(struct device * dev, struct device_attribute * attr, char * struct device_node *dp; pdev = to_pci_dev(dev); - dp = pdev->dev.archdata.prom_node; + dp = pdev->dev.of_node; return snprintf (buf, PAGE_SIZE, "%s\n", dp->full_name); } @@ -684,7 +684,7 @@ static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus) struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm, struct device *parent) { - struct device_node *node = pbm->op->node; + struct device_node *node = pbm->op->dev.of_node; struct pci_bus *bus; printk("PCI: Scanning PBM %s\n", node->full_name); @@ -1023,7 +1023,7 @@ void arch_teardown_msi_irq(unsigned int virt_irq) struct device_node *pci_device_to_OF_node(struct pci_dev *pdev) { - return pdev->dev.archdata.prom_node; + return pdev->dev.of_node; } EXPORT_SYMBOL(pci_device_to_OF_node); @@ -1152,15 +1152,13 @@ static int __init of_pci_slot_init(void) struct device_node *node; if (pbus->self) { - struct dev_archdata *sd = pbus->self->sysdata; - /* PCI->PCI bridge */ - node = sd->prom_node; + node = pbus->self->dev.of_node; } else { struct pci_pbm_info *pbm = pbus->sysdata; /* Host PCI controller */ - node = pbm->op->node; + node = pbm->op->dev.of_node; } pci_bus_slot_names(node, pbus); diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c index 8a000583b5cf..6c7a33af3ba6 100644 --- a/arch/sparc/kernel/pci_common.c +++ b/arch/sparc/kernel/pci_common.c @@ -314,12 +314,12 @@ struct pci_ops sun4v_pci_ops = { void pci_get_pbm_props(struct pci_pbm_info *pbm) { - const u32 *val = of_get_property(pbm->op->node, "bus-range", NULL); + const u32 *val = of_get_property(pbm->op->dev.of_node, "bus-range", NULL); pbm->pci_first_busno = val[0]; pbm->pci_last_busno = val[1]; - val = of_get_property(pbm->op->node, "ino-bitmap", NULL); + val = of_get_property(pbm->op->dev.of_node, "ino-bitmap", NULL); if (val) { pbm->ino_bitmap = (((u64)val[1] << 32UL) | ((u64)val[0] << 0UL)); @@ -365,7 +365,8 @@ static void pci_register_legacy_regions(struct resource *io_res, static void pci_register_iommu_region(struct pci_pbm_info *pbm) { - const u32 *vdma = of_get_property(pbm->op->node, "virtual-dma", NULL); + const u32 *vdma = of_get_property(pbm->op->dev.of_node, "virtual-dma", + NULL); if (vdma) { struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL); @@ -394,7 +395,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm) int num_pbm_ranges; saw_mem = saw_io = 0; - pbm_ranges = of_get_property(pbm->op->node, "ranges", &i); + pbm_ranges = of_get_property(pbm->op->dev.of_node, "ranges", &i); if (!pbm_ranges) { prom_printf("PCI: Fatal error, missing PBM ranges property " " for %s\n", diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c index d53f45bc7dda..ff844baa28e6 100644 --- a/arch/sparc/kernel/pci_fire.c +++ b/arch/sparc/kernel/pci_fire.c @@ -413,7 +413,7 @@ static int __devinit pci_fire_pbm_init(struct pci_pbm_info *pbm, struct of_device *op, u32 portid) { const struct linux_prom64_registers *regs; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; int err; pbm->numa_node = -1; @@ -458,7 +458,7 @@ static int __devinit pci_fire_pbm_init(struct pci_pbm_info *pbm, static int __devinit fire_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct pci_pbm_info *pbm; struct iommu *iommu; u32 portid; diff --git a/arch/sparc/kernel/pci_msi.c b/arch/sparc/kernel/pci_msi.c index e0ef847219c3..548b8ca9c210 100644 --- a/arch/sparc/kernel/pci_msi.c +++ b/arch/sparc/kernel/pci_msi.c @@ -324,7 +324,7 @@ void sparc64_pbm_msi_init(struct pci_pbm_info *pbm, const u32 *val; int len; - val = of_get_property(pbm->op->node, "#msi-eqs", &len); + val = of_get_property(pbm->op->dev.of_node, "#msi-eqs", &len); if (!val || len != 4) goto no_msi; pbm->msiq_num = *val; @@ -347,16 +347,16 @@ void sparc64_pbm_msi_init(struct pci_pbm_info *pbm, u32 msi64_len; } *arng; - val = of_get_property(pbm->op->node, "msi-eq-size", &len); + val = of_get_property(pbm->op->dev.of_node, "msi-eq-size", &len); if (!val || len != 4) goto no_msi; pbm->msiq_ent_count = *val; - mqp = of_get_property(pbm->op->node, + mqp = of_get_property(pbm->op->dev.of_node, "msi-eq-to-devino", &len); if (!mqp) - mqp = of_get_property(pbm->op->node, + mqp = of_get_property(pbm->op->dev.of_node, "msi-eq-devino", &len); if (!mqp || len != sizeof(struct msiq_prop)) goto no_msi; @@ -364,27 +364,27 @@ void sparc64_pbm_msi_init(struct pci_pbm_info *pbm, pbm->msiq_first = mqp->first_msiq; pbm->msiq_first_devino = mqp->first_devino; - val = of_get_property(pbm->op->node, "#msi", &len); + val = of_get_property(pbm->op->dev.of_node, "#msi", &len); if (!val || len != 4) goto no_msi; pbm->msi_num = *val; - mrng = of_get_property(pbm->op->node, "msi-ranges", &len); + mrng = of_get_property(pbm->op->dev.of_node, "msi-ranges", &len); if (!mrng || len != sizeof(struct msi_range_prop)) goto no_msi; pbm->msi_first = mrng->first_msi; - val = of_get_property(pbm->op->node, "msi-data-mask", &len); + val = of_get_property(pbm->op->dev.of_node, "msi-data-mask", &len); if (!val || len != 4) goto no_msi; pbm->msi_data_mask = *val; - val = of_get_property(pbm->op->node, "msix-data-width", &len); + val = of_get_property(pbm->op->dev.of_node, "msix-data-width", &len); if (!val || len != 4) goto no_msi; pbm->msix_data_width = *val; - arng = of_get_property(pbm->op->node, "msi-address-ranges", + arng = of_get_property(pbm->op->dev.of_node, "msi-address-ranges", &len); if (!arng || len != sizeof(struct addr_range_prop)) goto no_msi; diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c index 142b9d6984a8..e675e21c6df6 100644 --- a/arch/sparc/kernel/pci_psycho.c +++ b/arch/sparc/kernel/pci_psycho.c @@ -285,7 +285,7 @@ static irqreturn_t psycho_ce_intr(int irq, void *dev_id) #define PSYCHO_ECCCTRL_CE 0x2000000000000000UL /* Enable CE INterrupts */ static void psycho_register_error_handlers(struct pci_pbm_info *pbm) { - struct of_device *op = of_find_device_by_node(pbm->op->node); + struct of_device *op = of_find_device_by_node(pbm->op->dev.of_node); unsigned long base = pbm->controller_regs; u64 tmp; int err; @@ -507,7 +507,7 @@ static int __devinit psycho_probe(struct of_device *op, const struct of_device_id *match) { const struct linux_prom64_registers *pr_regs; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct pci_pbm_info *pbm; struct iommu *iommu; int is_pbm_a, err; diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c index ba6fbeba3e2c..5048498daade 100644 --- a/arch/sparc/kernel/pci_sabre.c +++ b/arch/sparc/kernel/pci_sabre.c @@ -310,7 +310,7 @@ static irqreturn_t sabre_ce_intr(int irq, void *dev_id) static void sabre_register_error_handlers(struct pci_pbm_info *pbm) { - struct device_node *dp = pbm->op->node; + struct device_node *dp = pbm->op->dev.of_node; struct of_device *op; unsigned long base = pbm->controller_regs; u64 tmp; @@ -456,7 +456,7 @@ static int __devinit sabre_probe(struct of_device *op, const struct of_device_id *match) { const struct linux_prom64_registers *pr_regs; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct pci_pbm_info *pbm; u32 upa_portid, dma_mask; struct iommu *iommu; diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c index 2b5cdde77af7..2f3f9212b063 100644 --- a/arch/sparc/kernel/pci_schizo.c +++ b/arch/sparc/kernel/pci_schizo.c @@ -844,7 +844,7 @@ static int pbm_routes_this_ino(struct pci_pbm_info *pbm, u32 ino) */ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm) { - struct of_device *op = of_find_device_by_node(pbm->op->node); + struct of_device *op = of_find_device_by_node(pbm->op->dev.of_node); u64 tmp, err_mask, err_no_mask; int err; @@ -939,7 +939,7 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm) static void schizo_register_error_handlers(struct pci_pbm_info *pbm) { - struct of_device *op = of_find_device_by_node(pbm->op->node); + struct of_device *op = of_find_device_by_node(pbm->op->dev.of_node); u64 tmp, err_mask, err_no_mask; int err; @@ -1068,7 +1068,7 @@ static void __devinit schizo_scan_bus(struct pci_pbm_info *pbm, { pbm_config_busmastering(pbm); pbm->is_66mhz_capable = - (of_find_property(pbm->op->node, "66mhz-capable", NULL) + (of_find_property(pbm->op->dev.of_node, "66mhz-capable", NULL) != NULL); pbm->pci_bus = pci_scan_one_pbm(pbm, parent); @@ -1138,7 +1138,7 @@ static int schizo_pbm_iommu_init(struct pci_pbm_info *pbm) u32 dma_mask; u64 control; - vdma = of_get_property(pbm->op->node, "virtual-dma", NULL); + vdma = of_get_property(pbm->op->dev.of_node, "virtual-dma", NULL); if (!vdma) vdma = vdma_default; @@ -1268,7 +1268,7 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) pbm->chip_version >= 0x2) tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT; - if (!of_find_property(pbm->op->node, "no-bus-parking", NULL)) + if (!of_find_property(pbm->op->dev.of_node, "no-bus-parking", NULL)) tmp |= SCHIZO_PCICTRL_PARK; else tmp &= ~SCHIZO_PCICTRL_PARK; @@ -1311,7 +1311,7 @@ static int __devinit schizo_pbm_init(struct pci_pbm_info *pbm, int chip_type) { const struct linux_prom64_registers *regs; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; const char *chipset_name; int is_pbm_a, err; @@ -1415,7 +1415,7 @@ static struct pci_pbm_info * __devinit schizo_find_sibling(u32 portid, static int __devinit __schizo_init(struct of_device *op, unsigned long chip_type) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct pci_pbm_info *pbm; struct iommu *iommu; u32 portid; diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 23c33ff9c31e..5c11f56cedf8 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -540,7 +540,7 @@ static void __devinit pci_sun4v_scan_bus(struct pci_pbm_info *pbm, struct property *prop; struct device_node *dp; - dp = pbm->op->node; + dp = pbm->op->dev.of_node; prop = of_find_property(dp, "66mhz-capable", NULL); pbm->is_66mhz_capable = (prop != NULL); pbm->pci_bus = pci_scan_one_pbm(pbm, parent); @@ -584,7 +584,7 @@ static int __devinit pci_sun4v_iommu_init(struct pci_pbm_info *pbm) u32 dma_mask, dma_offset; const u32 *vdma; - vdma = of_get_property(pbm->op->node, "virtual-dma", NULL); + vdma = of_get_property(pbm->op->dev.of_node, "virtual-dma", NULL); if (!vdma) vdma = vdma_default; @@ -881,7 +881,7 @@ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) static int __devinit pci_sun4v_pbm_init(struct pci_pbm_info *pbm, struct of_device *op, u32 devhandle) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; int err; pbm->numa_node = of_node_to_nid(dp); @@ -929,7 +929,7 @@ static int __devinit pci_sun4v_probe(struct of_device *op, u32 devhandle; int i, err; - dp = op->node; + dp = op->dev.of_node; if (!hvapi_negotiated++) { err = sun4v_hvapi_register(HV_GRP_PCI, diff --git a/arch/sparc/kernel/power.c b/arch/sparc/kernel/power.c index e2a045c235a1..e3f806a7423b 100644 --- a/arch/sparc/kernel/power.c +++ b/arch/sparc/kernel/power.c @@ -41,9 +41,9 @@ static int __devinit power_probe(struct of_device *op, const struct of_device_id power_reg = of_ioremap(res, 0, 0x4, "power"); printk(KERN_INFO "%s: Control reg at %llx\n", - op->node->name, res->start); + op->dev.of_node->name, res->start); - if (has_button_interrupt(irq, op->node)) { + if (has_button_interrupt(irq, op->dev.of_node)) { if (request_irq(irq, power_handler, 0, "power", NULL) < 0) printk(KERN_ERR "power: Cannot setup IRQ handler.\n"); diff --git a/arch/sparc/kernel/psycho_common.c b/arch/sparc/kernel/psycho_common.c index 8f1478475421..3f34ac853931 100644 --- a/arch/sparc/kernel/psycho_common.c +++ b/arch/sparc/kernel/psycho_common.c @@ -450,7 +450,7 @@ int psycho_iommu_init(struct pci_pbm_info *pbm, int tsbsize, void psycho_pbm_init_common(struct pci_pbm_info *pbm, struct of_device *op, const char *chip_name, int chip_type) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; pbm->name = dp->full_name; pbm->numa_node = -1; diff --git a/arch/sparc/kernel/sbus.c b/arch/sparc/kernel/sbus.c index 406e0872504e..cfeaf04b9cdf 100644 --- a/arch/sparc/kernel/sbus.c +++ b/arch/sparc/kernel/sbus.c @@ -63,10 +63,10 @@ void sbus_set_sbus64(struct device *dev, int bursts) int slot; u64 val; - regs = of_get_property(op->node, "reg", NULL); + regs = of_get_property(op->dev.of_node, "reg", NULL); if (!regs) { printk(KERN_ERR "sbus_set_sbus64: Cannot find regs for %s\n", - op->node->full_name); + op->dev.of_node->full_name); return; } slot = regs->which_io; @@ -287,7 +287,7 @@ static irqreturn_t sysio_ue_handler(int irq, void *dev_id) SYSIO_UEAFSR_SPIO | SYSIO_UEAFSR_SDRD | SYSIO_UEAFSR_SDWR); upa_writeq(error_bits, afsr_reg); - portid = of_getintprop_default(op->node, "portid", -1); + portid = of_getintprop_default(op->dev.of_node, "portid", -1); /* Log the error. */ printk("SYSIO[%x]: Uncorrectable ECC Error, primary error type[%s]\n", @@ -361,7 +361,7 @@ static irqreturn_t sysio_ce_handler(int irq, void *dev_id) SYSIO_CEAFSR_SPIO | SYSIO_CEAFSR_SDRD | SYSIO_CEAFSR_SDWR); upa_writeq(error_bits, afsr_reg); - portid = of_getintprop_default(op->node, "portid", -1); + portid = of_getintprop_default(op->dev.of_node, "portid", -1); printk("SYSIO[%x]: Correctable ECC Error, primary error type[%s]\n", portid, @@ -439,7 +439,7 @@ static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id) SYSIO_SBAFSR_SLE | SYSIO_SBAFSR_STO | SYSIO_SBAFSR_SBERR); upa_writeq(error_bits, afsr_reg); - portid = of_getintprop_default(op->node, "portid", -1); + portid = of_getintprop_default(op->dev.of_node, "portid", -1); /* Log the error. */ printk("SYSIO[%x]: SBUS Error, primary error type[%s] read(%d)\n", @@ -496,7 +496,7 @@ static void __init sysio_register_error_handlers(struct of_device *op) u64 control; int portid; - portid = of_getintprop_default(op->node, "portid", -1); + portid = of_getintprop_default(op->dev.of_node, "portid", -1); irq = sbus_build_irq(op, SYSIO_UE_INO); if (request_irq(irq, sysio_ue_handler, 0, @@ -537,7 +537,7 @@ static void __init sysio_register_error_handlers(struct of_device *op) static void __init sbus_iommu_init(struct of_device *op) { const struct linux_prom64_registers *pr; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct iommu *iommu; struct strbuf *strbuf; unsigned long regs, reg_base; @@ -589,7 +589,7 @@ static void __init sbus_iommu_init(struct of_device *op) */ iommu->write_complete_reg = regs + 0x2000UL; - portid = of_getintprop_default(op->node, "portid", -1); + portid = of_getintprop_default(op->dev.of_node, "portid", -1); printk(KERN_INFO "SYSIO: UPA portID %x, at %016lx\n", portid, regs); diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index 0d4c09b15efc..e0dbed9503d4 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c @@ -152,7 +152,7 @@ static struct platform_device m48t59_rtc = { static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; const char *model = of_get_property(dp, "model", NULL); if (!model) diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index c7bbe6cf7b85..9099ca095641 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -424,7 +424,7 @@ static int __devinit rtc_probe(struct of_device *op, const struct of_device_id * struct resource *r; printk(KERN_INFO "%s: RTC regs at 0x%llx\n", - op->node->full_name, op->resource[0].start); + op->dev.of_node->full_name, op->resource[0].start); /* The CMOS RTC driver only accepts IORESOURCE_IO, so cons * up a fake resource so that the probe works for all cases. @@ -480,7 +480,7 @@ static int __devinit bq4802_probe(struct of_device *op, const struct of_device_i { printk(KERN_INFO "%s: BQ4802 regs at 0x%llx\n", - op->node->full_name, op->resource[0].start); + op->dev.of_node->full_name, op->resource[0].start); rtc_bq4802_device.resource = &op->resource[0]; return platform_device_register(&rtc_bq4802_device); @@ -534,7 +534,7 @@ static struct platform_device m48t59_rtc = { static int __devinit mostek_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; /* On an Enterprise system there can be multiple mostek clocks. * We should only match the one that is on the central FHC bus. diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c index 211b6438b3a0..c74f13bc9876 100644 --- a/drivers/ata/pata_macio.c +++ b/drivers/ata/pata_macio.c @@ -1139,7 +1139,7 @@ static int __devinit pata_macio_attach(struct macio_dev *mdev, "Failed to allocate private memory\n"); return -ENOMEM; } - priv->node = of_node_get(mdev->ofdev.node); + priv->node = of_node_get(mdev->ofdev.dev.of_node); priv->mdev = mdev; priv->dev = &mdev->ofdev.dev; diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index 9f5b053611dd..4cce719add3f 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -694,7 +694,7 @@ mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match) struct bcom_task *dmatsk = NULL; /* Get ipb frequency */ - ipb_freq = mpc5xxx_get_bus_frequency(op->node); + ipb_freq = mpc5xxx_get_bus_frequency(op->dev.of_node); if (!ipb_freq) { dev_err(&op->dev, "could not determine IPB bus frequency\n"); return -ENODEV; @@ -702,7 +702,7 @@ mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match) /* Get device base address from device tree, request the region * and ioremap it. */ - rv = of_address_to_resource(op->node, 0, &res_mem); + rv = of_address_to_resource(op->dev.of_node, 0, &res_mem); if (rv) { dev_err(&op->dev, "could not determine device base address\n"); return rv; @@ -735,14 +735,14 @@ mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match) * The MPC5200 ATA controller supports MWDMA modes 0, 1 and 2 and * UDMA modes 0, 1 and 2. */ - prop = of_get_property(op->node, "mwdma-mode", &proplen); + prop = of_get_property(op->dev.of_node, "mwdma-mode", &proplen); if ((prop) && (proplen >= 4)) mwdma_mask = ATA_MWDMA2 & ((1 << (*prop + 1)) - 1); - prop = of_get_property(op->node, "udma-mode", &proplen); + prop = of_get_property(op->dev.of_node, "udma-mode", &proplen); if ((prop) && (proplen >= 4)) udma_mask = ATA_UDMA2 & ((1 << (*prop + 1)) - 1); - ata_irq = irq_of_parse_and_map(op->node, 0); + ata_irq = irq_of_parse_and_map(op->dev.of_node, 0); if (ata_irq == NO_IRQ) { dev_err(&op->dev, "error mapping irq\n"); return -EINVAL; diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c index 1f18ad9e4fe1..19da29f011db 100644 --- a/drivers/ata/pata_of_platform.c +++ b/drivers/ata/pata_of_platform.c @@ -18,7 +18,7 @@ static int __devinit pata_of_platform_probe(struct of_device *ofdev, const struct of_device_id *match) { int ret; - struct device_node *dn = ofdev->node; + struct device_node *dn = ofdev->dev.of_node; struct resource io_res; struct resource ctl_res; struct resource irq_res; diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index a69192b38b43..e3339e25b152 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -1313,7 +1313,7 @@ static int sata_fsl_probe(struct of_device *ofdev, dev_printk(KERN_INFO, &ofdev->dev, "Sata FSL Platform/CSB Driver init\n"); - hcr_base = of_iomap(ofdev->node, 0); + hcr_base = of_iomap(ofdev->dev.of_node, 0); if (!hcr_base) goto error_exit_with_cleanup; @@ -1332,7 +1332,7 @@ static int sata_fsl_probe(struct of_device *ofdev, host_priv->ssr_base = ssr_base; host_priv->csr_base = csr_base; - irq = irq_of_parse_and_map(ofdev->node, 0); + irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); if (irq < 0) { dev_printk(KERN_ERR, &ofdev->dev, "invalid irq from platform\n"); goto error_exit_with_cleanup; diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index f7d6ebaa0418..593a03a376e4 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -789,7 +789,7 @@ static int __init fore200e_sba_map(struct fore200e *fore200e) fore200e->bus->write(0x02, fore200e->regs.sba.isr); /* XXX hardwired interrupt level */ /* get the supported DVMA burst sizes */ - bursts = of_getintprop_default(op->node->parent, "burst-sizes", 0x00); + bursts = of_getintprop_default(op->dev.of_node->parent, "burst-sizes", 0x00); if (sbus_can_dma_64bit()) sbus_set_sbus64(&op->dev, bursts); @@ -820,18 +820,20 @@ static int __init fore200e_sba_prom_read(struct fore200e *fore200e, struct prom_ const u8 *prop; int len; - prop = of_get_property(op->node, "madaddrlo2", &len); + prop = of_get_property(op->dev.of_node, "madaddrlo2", &len); if (!prop) return -ENODEV; memcpy(&prom->mac_addr[4], prop, 4); - prop = of_get_property(op->node, "madaddrhi4", &len); + prop = of_get_property(op->dev.of_node, "madaddrhi4", &len); if (!prop) return -ENODEV; memcpy(&prom->mac_addr[2], prop, 4); - prom->serial_number = of_getintprop_default(op->node, "serialnumber", 0); - prom->hw_revision = of_getintprop_default(op->node, "promversion", 0); + prom->serial_number = of_getintprop_default(op->dev.of_node, + "serialnumber", 0); + prom->hw_revision = of_getintprop_default(op->dev.of_node, + "promversion", 0); return 0; } @@ -841,10 +843,10 @@ static int fore200e_sba_proc_read(struct fore200e *fore200e, char *page) struct of_device *op = fore200e->bus_dev; const struct linux_prom_registers *regs; - regs = of_get_property(op->node, "reg", NULL); + regs = of_get_property(op->dev.of_node, "reg", NULL); return sprintf(page, " SBUS slot/device:\t\t%d/'%s'\n", - (regs ? regs->which_io : 0), op->node->name); + (regs ? regs->which_io : 0), op->dev.of_node->name); } #endif /* CONFIG_SBUS */ diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index 59ca2b77b574..52f2d11bc7b9 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c @@ -1004,7 +1004,7 @@ static const struct block_device_operations floppy_fops = { static int swim3_add_device(struct macio_dev *mdev, int index) { - struct device_node *swim = mdev->ofdev.node; + struct device_node *swim = mdev->ofdev.dev.of_node; struct floppy_state *fs = &floppy_states[index]; int rc = -EBUSY; diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index e1c95e208a66..3094909b0613 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -1198,10 +1198,10 @@ ace_of_probe(struct of_device *op, const struct of_device_id *match) dev_dbg(&op->dev, "ace_of_probe(%p, %p)\n", op, match); /* device id */ - id = of_get_property(op->node, "port-number", NULL); + id = of_get_property(op->dev.of_node, "port-number", NULL); /* physaddr */ - rc = of_address_to_resource(op->node, 0, &res); + rc = of_address_to_resource(op->dev.of_node, 0, &res); if (rc) { dev_err(&op->dev, "invalid address\n"); return rc; @@ -1209,11 +1209,11 @@ ace_of_probe(struct of_device *op, const struct of_device_id *match) physaddr = res.start; /* irq */ - irq = irq_of_parse_and_map(op->node, 0); + irq = irq_of_parse_and_map(op->dev.of_node, 0); /* bus width */ bus_width = ACE_BUS_WIDTH_16; - if (of_find_property(op->node, "8-bit", NULL)) + if (of_find_property(op->dev.of_node, "8-bit", NULL)) bus_width = ACE_BUS_WIDTH_8; /* Call the bus-independant setup code */ diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index cc435be0bc13..451cd7071b1d 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -567,7 +567,7 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) struct disk_info *d; struct cdrom_device_info *c; struct request_queue *q; - struct device_node *node = vdev->dev.archdata.of_node; + struct device_node *node = vdev->dev.of_node; deviceno = vdev->unit_address; if (deviceno >= VIOCD_MAX_CD) diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index 10f868eefaa6..0861d99cd75b 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c @@ -660,7 +660,7 @@ static int __devinit n2rng_probe(struct of_device *op, np->hvapi_major); goto out_hvapi_unregister; } - np->num_units = of_getintprop_default(op->node, + np->num_units = of_getintprop_default(op->dev.of_node, "rng-#units", 0); if (!np->num_units) { dev_err(&op->dev, "VF RNG lacks rng-#units property\n"); diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c index 7fa61dd1d9d9..b213855bae68 100644 --- a/drivers/char/hw_random/pasemi-rng.c +++ b/drivers/char/hw_random/pasemi-rng.c @@ -98,7 +98,7 @@ static int __devinit rng_probe(struct of_device *ofdev, const struct of_device_id *match) { void __iomem *rng_regs; - struct device_node *rng_np = ofdev->node; + struct device_node *rng_np = ofdev->dev.of_node; struct resource res; int err = 0; diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 4462b113ba3f..2b44a0e1b988 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2469,7 +2469,7 @@ static int __devinit ipmi_of_probe(struct of_device *dev, struct smi_info *info; struct resource resource; const int *regsize, *regspacing, *regshift; - struct device_node *np = dev->node; + struct device_node *np = dev->dev.of_node; int ret; int proplen; @@ -2525,7 +2525,7 @@ static int __devinit ipmi_of_probe(struct of_device *dev, info->io.regspacing = regspacing ? *regspacing : DEFAULT_REGSPACING; info->io.regshift = regshift ? *regshift : 0; - info->irq = irq_of_parse_and_map(dev->node, 0); + info->irq = irq_of_parse_and_map(dev->dev.of_node, 0); info->dev = &dev->dev; dev_dbg(&dev->dev, "addr 0x%lx regsize %d spacing %d irq %x\n", diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index 1144a04cda6e..42f7fa442ff8 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c @@ -866,7 +866,7 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id) { int i = vdev->unit_address; int j; - struct device_node *node = vdev->dev.archdata.of_node; + struct device_node *node = vdev->dev.of_node; if (i >= VIOTAPE_MAX_TAPE) return -ENODEV; diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 7261b8d9087c..5a0a31e2029c 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -772,18 +772,18 @@ hwicap_of_probe(struct of_device *op, const struct of_device_id *match) dev_dbg(&op->dev, "hwicap_of_probe(%p, %p)\n", op, match); - rc = of_address_to_resource(op->node, 0, &res); + rc = of_address_to_resource(op->dev.of_node, 0, &res); if (rc) { dev_err(&op->dev, "invalid address\n"); return rc; } - id = of_get_property(op->node, "port-number", NULL); + id = of_get_property(op->dev.of_node, "port-number", NULL); /* It's most likely that we're using V4, if the family is not specified */ regs = &v4_config_registers; - family = of_get_property(op->node, "xlnx,family", NULL); + family = of_get_property(op->dev.of_node, "xlnx,family", NULL); if (family) { if (!strcmp(family, "virtex2p")) { diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index dc558a097311..5a02f3482dba 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -1807,7 +1807,7 @@ static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match) { struct device *dev = &ofdev->dev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct talitos_private *priv; const unsigned int *prop; int i, err; diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 88f470f0d820..0e376eb37417 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -1313,7 +1313,7 @@ static int __devinit fsldma_of_probe(struct of_device *op, INIT_LIST_HEAD(&fdev->common.channels); /* ioremap the registers for use */ - fdev->regs = of_iomap(op->node, 0); + fdev->regs = of_iomap(op->dev.of_node, 0); if (!fdev->regs) { dev_err(&op->dev, "unable to ioremap registers\n"); err = -ENOMEM; @@ -1321,7 +1321,7 @@ static int __devinit fsldma_of_probe(struct of_device *op, } /* map the channel IRQ if it exists, but don't hookup the handler yet */ - fdev->irq = irq_of_parse_and_map(op->node, 0); + fdev->irq = irq_of_parse_and_map(op->dev.of_node, 0); dma_cap_set(DMA_MEMCPY, fdev->common.cap_mask); dma_cap_set(DMA_INTERRUPT, fdev->common.cap_mask); @@ -1343,7 +1343,7 @@ static int __devinit fsldma_of_probe(struct of_device *op, * of_platform_bus_remove(). Instead, we manually instantiate every DMA * channel object. */ - for_each_child_of_node(op->node, child) { + for_each_child_of_node(op->dev.of_node, child) { if (of_device_is_compatible(child, "fsl,eloplus-dma-channel")) { fsl_dma_chan_probe(fdev, child, FSL_DMA_IP_85XX | FSL_DMA_BIG_ENDIAN, diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index 7d521e1d17e1..1db114b09990 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c @@ -437,7 +437,7 @@ pca953x_get_alt_pdata(struct i2c_client *client) struct device_node *node; const uint16_t *val; - node = dev_archdata_get_node(&client->dev.archdata); + node = client->dev.of_node; if (node == NULL) return NULL; diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index 9c2e10082b79..48d2c1a0d4ce 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -440,7 +440,7 @@ static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) init_waitqueue_head(&cpm->i2c_wait); - cpm->irq = of_irq_to_resource(ofdev->node, 0, NULL); + cpm->irq = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); if (cpm->irq == NO_IRQ) return -EINVAL; @@ -451,13 +451,13 @@ static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) return ret; /* I2C parameter RAM */ - i2c_base = of_iomap(ofdev->node, 1); + i2c_base = of_iomap(ofdev->dev.of_node, 1); if (i2c_base == NULL) { ret = -EINVAL; goto out_irq; } - if (of_device_is_compatible(ofdev->node, "fsl,cpm1-i2c")) { + if (of_device_is_compatible(ofdev->dev.of_node, "fsl,cpm1-i2c")) { /* Check for and use a microcode relocation patch. */ cpm->i2c_ram = i2c_base; @@ -474,7 +474,7 @@ static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) cpm->version = 1; - } else if (of_device_is_compatible(ofdev->node, "fsl,cpm2-i2c")) { + } else if (of_device_is_compatible(ofdev->dev.of_node, "fsl,cpm2-i2c")) { cpm->i2c_addr = cpm_muram_alloc(sizeof(struct i2c_ram), 64); cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr); out_be16(i2c_base, cpm->i2c_addr); @@ -489,24 +489,24 @@ static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) } /* I2C control/status registers */ - cpm->i2c_reg = of_iomap(ofdev->node, 0); + cpm->i2c_reg = of_iomap(ofdev->dev.of_node, 0); if (cpm->i2c_reg == NULL) { ret = -EINVAL; goto out_ram; } - data = of_get_property(ofdev->node, "fsl,cpm-command", &len); + data = of_get_property(ofdev->dev.of_node, "fsl,cpm-command", &len); if (!data || len != 4) { ret = -EINVAL; goto out_reg; } cpm->cp_command = *data; - data = of_get_property(ofdev->node, "linux,i2c-class", &len); + data = of_get_property(ofdev->dev.of_node, "linux,i2c-class", &len); if (data && len == 4) cpm->adap.class = *data; - data = of_get_property(ofdev->node, "clock-frequency", &len); + data = of_get_property(ofdev->dev.of_node, "clock-frequency", &len); if (data && len == 4) cpm->freq = *data; else @@ -661,7 +661,7 @@ static int __devinit cpm_i2c_probe(struct of_device *ofdev, /* register new adapter to i2c module... */ - data = of_get_property(ofdev->node, "linux,i2c-index", &len); + data = of_get_property(ofdev->dev.of_node, "linux,i2c-index", &len); if (data && len == 4) { cpm->adap.nr = *data; result = i2c_add_numbered_adapter(&cpm->adap); @@ -679,7 +679,7 @@ static int __devinit cpm_i2c_probe(struct of_device *ofdev, /* * register OF I2C devices */ - of_register_i2c_devices(&cpm->adap, ofdev->node); + of_register_i2c_devices(&cpm->adap, ofdev->dev.of_node); return 0; out_shut: diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index b1bc6e277d2a..e66dc83953c5 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -664,7 +664,7 @@ static inline u8 iic_clckdiv(unsigned int opb) static int __devinit iic_request_irq(struct of_device *ofdev, struct ibm_iic_private *dev) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; int irq; if (iic_force_poll) @@ -695,7 +695,7 @@ static int __devinit iic_request_irq(struct of_device *ofdev, static int __devinit iic_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct ibm_iic_private *dev; struct i2c_adapter *adap; const u32 *freq; diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index f1321f763789..69473b6c260c 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -560,14 +560,14 @@ static int __devinit fsl_i2c_probe(struct of_device *op, init_waitqueue_head(&i2c->queue); - i2c->base = of_iomap(op->node, 0); + i2c->base = of_iomap(op->dev.of_node, 0); if (!i2c->base) { dev_err(i2c->dev, "failed to map controller\n"); result = -ENOMEM; goto fail_map; } - i2c->irq = irq_of_parse_and_map(op->node, 0); + i2c->irq = irq_of_parse_and_map(op->dev.of_node, 0); if (i2c->irq != NO_IRQ) { /* i2c->irq = NO_IRQ implies polling */ result = request_irq(i2c->irq, mpc_i2c_isr, IRQF_SHARED, "i2c-mpc", i2c); @@ -577,21 +577,22 @@ static int __devinit fsl_i2c_probe(struct of_device *op, } } - if (of_get_property(op->node, "fsl,preserve-clocking", NULL)) { + if (of_get_property(op->dev.of_node, "fsl,preserve-clocking", NULL)) { clock = MPC_I2C_CLOCK_PRESERVE; } else { - prop = of_get_property(op->node, "clock-frequency", &plen); + prop = of_get_property(op->dev.of_node, "clock-frequency", + &plen); if (prop && plen == sizeof(u32)) clock = *prop; } if (match->data) { struct mpc_i2c_data *data = match->data; - data->setup(op->node, i2c, clock, data->prescaler); + data->setup(op->dev.of_node, i2c, clock, data->prescaler); } else { /* Backwards compatibility */ - if (of_get_property(op->node, "dfsrr", NULL)) - mpc_i2c_setup_8xxx(op->node, i2c, clock, 0); + if (of_get_property(op->dev.of_node, "dfsrr", NULL)) + mpc_i2c_setup_8xxx(op->dev.of_node, i2c, clock, 0); } dev_set_drvdata(&op->dev, i2c); @@ -605,7 +606,7 @@ static int __devinit fsl_i2c_probe(struct of_device *op, dev_err(i2c->dev, "failed to add adapter\n"); goto fail_add; } - of_register_i2c_devices(&i2c->adap, op->node); + of_register_i2c_devices(&i2c->adap, op->dev.of_node); return result; diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c index 159955d16c47..183fa38760d8 100644 --- a/drivers/ide/pmac.c +++ b/drivers/ide/pmac.c @@ -1153,7 +1153,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) if (macio_resource_count(mdev) == 0) { printk(KERN_WARNING "ide-pmac: no address for %s\n", - mdev->ofdev.node->full_name); + mdev->ofdev.dev.of_node->full_name); rc = -ENXIO; goto out_free_pmif; } @@ -1161,7 +1161,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) /* Request memory resource for IO ports */ if (macio_request_resource(mdev, 0, "ide-pmac (ports)")) { printk(KERN_ERR "ide-pmac: can't request MMIO resource for " - "%s!\n", mdev->ofdev.node->full_name); + "%s!\n", mdev->ofdev.dev.of_node->full_name); rc = -EBUSY; goto out_free_pmif; } @@ -1173,7 +1173,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) */ if (macio_irq_count(mdev) == 0) { printk(KERN_WARNING "ide-pmac: no intrs for device %s, using " - "13\n", mdev->ofdev.node->full_name); + "13\n", mdev->ofdev.dev.of_node->full_name); irq = irq_create_mapping(NULL, 13); } else irq = macio_irq(mdev, 0); @@ -1182,7 +1182,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) regbase = (unsigned long) base; pmif->mdev = mdev; - pmif->node = mdev->ofdev.node; + pmif->node = mdev->ofdev.dev.of_node; pmif->regbase = regbase; pmif->irq = irq; pmif->kauai_fcr = NULL; @@ -1191,7 +1191,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) if (macio_request_resource(mdev, 1, "ide-pmac (dma)")) printk(KERN_WARNING "ide-pmac: can't request DMA " "resource for %s!\n", - mdev->ofdev.node->full_name); + mdev->ofdev.dev.of_node->full_name); else pmif->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x1000); } else diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 129a6bebd6e3..26391853277f 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c @@ -291,8 +291,9 @@ static int ehca_sense_attributes(struct ehca_shca *shca) }; ehca_gen_dbg("Probing adapter %s...", - shca->ofdev->node->full_name); - loc_code = of_get_property(shca->ofdev->node, "ibm,loc-code", NULL); + shca->ofdev->dev.of_node->full_name); + loc_code = of_get_property(shca->ofdev->dev.of_node, "ibm,loc-code", + NULL); if (loc_code) ehca_gen_dbg(" ... location lode=%s", loc_code); @@ -720,16 +721,16 @@ static int __devinit ehca_probe(struct of_device *dev, int ret, i, eq_size; unsigned long flags; - handle = of_get_property(dev->node, "ibm,hca-handle", NULL); + handle = of_get_property(dev->dev.of_node, "ibm,hca-handle", NULL); if (!handle) { ehca_gen_err("Cannot get eHCA handle for adapter: %s.", - dev->node->full_name); + dev->dev.of_node->full_name); return -ENODEV; } if (!(*handle)) { ehca_gen_err("Wrong eHCA handle for adapter: %s.", - dev->node->full_name); + dev->dev.of_node->full_name); return -ENODEV; } diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h index 5071af2c0604..29e17698b2a4 100644 --- a/drivers/input/serio/i8042-sparcio.h +++ b/drivers/input/serio/i8042-sparcio.h @@ -51,7 +51,7 @@ static inline void i8042_write_command(int val) static int __devinit sparc_i8042_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; dp = dp->child; while (dp) { diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index f84f8e32e3f1..7a288c0ef1a6 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -244,17 +244,17 @@ static int __devinit xps2_of_probe(struct of_device *ofdev, int error; dev_info(dev, "Device Tree Probing \'%s\'\n", - ofdev->node->name); + ofdev->dev.of_node->name); /* Get iospace for the device */ - error = of_address_to_resource(ofdev->node, 0, &r_mem); + error = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem); if (error) { dev_err(dev, "invalid address\n"); return error; } /* Get IRQ for the device */ - if (of_irq_to_resource(ofdev->node, 0, &r_irq) == NO_IRQ) { + if (of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq) == NO_IRQ) { dev_err(dev, "no IRQ found\n"); return -ENODEV; } @@ -342,7 +342,7 @@ static int __devexit xps2_of_remove(struct of_device *of_dev) iounmap(drvdata->base_address); /* Get iospace of the device */ - if (of_address_to_resource(of_dev->node, 0, &r_mem)) + if (of_address_to_resource(of_dev->dev.of_node, 0, &r_mem)) dev_err(dev, "invalid address\n"); else release_mem_region(r_mem.start, resource_size(&r_mem)); diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index c6e4b772b757..a77a23e783db 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -211,7 +211,7 @@ struct gpio_led_of_platform_data { static int __devinit of_gpio_leds_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node, *child; + struct device_node *np = ofdev->dev.of_node, *child; struct gpio_led_of_platform_data *pdata; int count = 0, ret; diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 26a303a1d1ab..67fe13ffe90b 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -248,7 +248,7 @@ static void macio_create_fixup_irq(struct macio_dev *dev, int index, static void macio_add_missing_resources(struct macio_dev *dev) { - struct device_node *np = dev->ofdev.node; + struct device_node *np = dev->ofdev.dev.of_node; unsigned int irq_base; /* Gatwick has some missing interrupts on child nodes */ @@ -289,7 +289,7 @@ static void macio_add_missing_resources(struct macio_dev *dev) static void macio_setup_interrupts(struct macio_dev *dev) { - struct device_node *np = dev->ofdev.node; + struct device_node *np = dev->ofdev.dev.of_node; unsigned int irq; int i = 0, j = 0; @@ -317,7 +317,7 @@ static void macio_setup_interrupts(struct macio_dev *dev) static void macio_setup_resources(struct macio_dev *dev, struct resource *parent_res) { - struct device_node *np = dev->ofdev.node; + struct device_node *np = dev->ofdev.dev.of_node; struct resource r; int index; @@ -373,7 +373,7 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, dev->bus = &chip->lbus; dev->media_bay = in_bay; - dev->ofdev.node = np; + dev->ofdev.dev.of_node = np; dev->ofdev.dma_mask = 0xffffffffUL; dev->ofdev.dev.dma_mask = &dev->ofdev.dma_mask; dev->ofdev.dev.parent = parent; @@ -494,9 +494,9 @@ static void macio_pci_add_devices(struct macio_chip *chip) } /* Add media bay devices if any */ + pnode = mbdev->ofdev.dev.of_node; if (mbdev) - for (np = NULL; (np = of_get_next_child(mbdev->ofdev.node, np)) - != NULL;) { + for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) { if (macio_skip_device(np)) continue; of_node_get(np); @@ -506,9 +506,9 @@ static void macio_pci_add_devices(struct macio_chip *chip) } /* Add serial ports if any */ + pnode = sdev->ofdev.dev.of_node; if (sdev) { - for (np = NULL; (np = of_get_next_child(sdev->ofdev.node, np)) - != NULL;) { + for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) { if (macio_skip_device(np)) continue; of_node_get(np); diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c index 9e9453b58425..6999ce59fd10 100644 --- a/drivers/macintosh/macio_sysfs.c +++ b/drivers/macintosh/macio_sysfs.c @@ -9,7 +9,7 @@ field##_show (struct device *dev, struct device_attribute *attr, \ char *buf) \ { \ struct macio_dev *mdev = to_macio_device (dev); \ - return sprintf (buf, format_string, mdev->ofdev.node->field); \ + return sprintf (buf, format_string, mdev->ofdev.dev.of_node->field); \ } static ssize_t @@ -21,7 +21,7 @@ compatible_show (struct device *dev, struct device_attribute *attr, char *buf) int length = 0; of = &to_macio_device (dev)->ofdev; - compat = of_get_property(of->node, "compatible", &cplen); + compat = of_get_property(of->dev.of_node, "compatible", &cplen); if (!compat) { *buf = '\0'; return 0; @@ -58,7 +58,7 @@ static ssize_t devspec_show(struct device *dev, struct of_device *ofdev; ofdev = to_of_device(dev); - return sprintf(buf, "%s\n", ofdev->node->full_name); + return sprintf(buf, "%s\n", ofdev->dev.of_node->full_name); } macio_config_of_attr (name, "%s\n"); diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index 08002b88f342..288acce76b74 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c @@ -564,7 +564,7 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_de unsigned long base; int i; - ofnode = mdev->ofdev.node; + ofnode = mdev->ofdev.dev.of_node; if (macio_resource_count(mdev) < 1) return -ENODEV; diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c index 7c54d80c4fb2..12946c5f583f 100644 --- a/drivers/macintosh/rack-meter.c +++ b/drivers/macintosh/rack-meter.c @@ -375,7 +375,7 @@ static int __devinit rackmeter_probe(struct macio_dev* mdev, pr_debug("rackmeter_probe()\n"); /* Get i2s-a node */ - while ((i2s = of_get_next_child(mdev->ofdev.node, i2s)) != NULL) + while ((i2s = of_get_next_child(mdev->ofdev.dev.of_node, i2s)) != NULL) if (strcmp(i2s->name, "i2s-a") == 0) break; if (i2s == NULL) { @@ -431,7 +431,7 @@ static int __devinit rackmeter_probe(struct macio_dev* mdev, of_address_to_resource(i2s, 1, &rdma)) { printk(KERN_ERR "rackmeter: found match but lacks resources: %s", - mdev->ofdev.node->full_name); + mdev->ofdev.dev.of_node->full_name); rc = -ENXIO; goto bail_free; } diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index b18fa948f3d1..9314be9a2fc8 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -2215,7 +2215,7 @@ static int fcu_of_probe(struct of_device* dev, const struct of_device_id *match) state = state_detached; /* Lookup the fans in the device tree */ - fcu_lookup_fans(dev->node); + fcu_lookup_fans(dev->dev.of_node); /* Add the driver */ return i2c_add_driver(&therm_pm72_driver); diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c index bb6cc54b558e..1247e5de9faa 100644 --- a/drivers/mmc/host/of_mmc_spi.c +++ b/drivers/mmc/host/of_mmc_spi.c @@ -64,7 +64,7 @@ static int of_mmc_spi_get_ro(struct device *dev) struct mmc_spi_platform_data *mmc_spi_get_pdata(struct spi_device *spi) { struct device *dev = &spi->dev; - struct device_node *np = dev_archdata_get_node(&dev->archdata); + struct device_node *np = dev->of_node; struct of_mmc_spi *oms; const u32 *voltage_ranges; int num_ranges; @@ -135,7 +135,7 @@ EXPORT_SYMBOL(mmc_spi_get_pdata); void mmc_spi_put_pdata(struct spi_device *spi) { struct device *dev = &spi->dev; - struct device_node *np = dev_archdata_get_node(&dev->archdata); + struct device_node *np = dev->of_node; struct of_mmc_spi *oms = to_of_mmc_spi(dev); int i; diff --git a/drivers/mmc/host/sdhci-of-core.c b/drivers/mmc/host/sdhci-of-core.c index 55e33135edb4..dfe5ceae6794 100644 --- a/drivers/mmc/host/sdhci-of-core.c +++ b/drivers/mmc/host/sdhci-of-core.c @@ -118,7 +118,7 @@ static bool __devinit sdhci_of_wp_inverted(struct device_node *np) static int __devinit sdhci_of_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct sdhci_of_data *sdhci_of_data = match->data; struct sdhci_host *host; struct sdhci_of_host *of_host; diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 101ee6ead05c..3dc7a2fbf025 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -143,7 +143,7 @@ static int of_flash_remove(struct of_device *dev) static struct mtd_info * __devinit obsolete_probe(struct of_device *dev, struct map_info *map) { - struct device_node *dp = dev->node; + struct device_node *dp = dev->dev.of_node; const char *of_probe; struct mtd_info *mtd; static const char *rom_probe_types[] @@ -180,7 +180,7 @@ static int __devinit of_flash_probe(struct of_device *dev, static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; #endif - struct device_node *dp = dev->node; + struct device_node *dp = dev->dev.of_node; struct resource res; struct of_flash *info; const char *probe_type = match->data; @@ -204,7 +204,7 @@ static int __devinit of_flash_probe(struct of_device *dev, p = of_get_property(dp, "reg", &count); if (count % reg_tuple_size != 0) { dev_err(&dev->dev, "Malformed reg property on %s\n", - dev->node->full_name); + dev->dev.of_node->full_name); err = -EINVAL; goto err_flash_remove; } diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c index fadc4c45b455..5945a23e681f 100644 --- a/drivers/mtd/maps/sun_uflash.c +++ b/drivers/mtd/maps/sun_uflash.c @@ -110,7 +110,7 @@ int uflash_devinit(struct of_device *op, struct device_node *dp) static int __devinit uflash_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; /* Flashprom must have the "user" property in order to * be used by this driver. diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index ae30fb6eed97..4a6079588ab2 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -1030,14 +1030,14 @@ static int __devinit fsl_elbc_ctrl_probe(struct of_device *ofdev, init_waitqueue_head(&ctrl->controller.wq); init_waitqueue_head(&ctrl->irq_wait); - ctrl->regs = of_iomap(ofdev->node, 0); + ctrl->regs = of_iomap(ofdev->dev.of_node, 0); if (!ctrl->regs) { dev_err(&ofdev->dev, "failed to get memory region\n"); ret = -ENODEV; goto err; } - ctrl->irq = of_irq_to_resource(ofdev->node, 0, NULL); + ctrl->irq = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); if (ctrl->irq == NO_IRQ) { dev_err(&ofdev->dev, "failed to get irq resource\n"); ret = -ENODEV; @@ -1058,7 +1058,7 @@ static int __devinit fsl_elbc_ctrl_probe(struct of_device *ofdev, goto err; } - for_each_child_of_node(ofdev->node, child) + for_each_child_of_node(ofdev->dev.of_node, child) if (of_device_is_compatible(child, "fsl,elbc-fcm-nand")) fsl_elbc_chip_probe(ctrl, child); diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index b983cae8c298..c0e05f5ff8a4 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -239,14 +239,14 @@ static int __devinit ndfc_probe(struct of_device *ofdev, dev_set_drvdata(&ofdev->dev, ndfc); /* Read the reg property to get the chip select */ - reg = of_get_property(ofdev->node, "reg", &len); + reg = of_get_property(ofdev->dev.of_node, "reg", &len); if (reg == NULL || len != 12) { dev_err(&ofdev->dev, "unable read reg property (%d)\n", len); return -ENOENT; } ndfc->chip_select = reg[0]; - ndfc->ndfcbase = of_iomap(ofdev->node, 0); + ndfc->ndfcbase = of_iomap(ofdev->dev.of_node, 0); if (!ndfc->ndfcbase) { dev_err(&ofdev->dev, "failed to get memory\n"); return -EIO; @@ -255,20 +255,20 @@ static int __devinit ndfc_probe(struct of_device *ofdev, ccr = NDFC_CCR_BS(ndfc->chip_select); /* It is ok if ccr does not exist - just default to 0 */ - reg = of_get_property(ofdev->node, "ccr", NULL); + reg = of_get_property(ofdev->dev.of_node, "ccr", NULL); if (reg) ccr |= *reg; out_be32(ndfc->ndfcbase + NDFC_CCR, ccr); /* Set the bank settings if given */ - reg = of_get_property(ofdev->node, "bank-settings", NULL); + reg = of_get_property(ofdev->dev.of_node, "bank-settings", NULL); if (reg) { int offset = NDFC_BCFG0 + (ndfc->chip_select << 2); out_be32(ndfc->ndfcbase + offset, *reg); } - err = ndfc_chip_init(ndfc, ofdev->node); + err = ndfc_chip_init(ndfc, ofdev->dev.of_node); if (err) { iounmap(ndfc->ndfcbase); return err; diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index a8b9376cf324..edfc27b78513 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c @@ -93,7 +93,7 @@ static int __devinit pasemi_nand_probe(struct of_device *ofdev, const struct of_device_id *match) { struct pci_dev *pdev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct resource res; struct nand_chip *chip; int err = 0; diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c index 9dd076a626a5..dc5f20cdf93c 100644 --- a/drivers/net/can/sja1000/sja1000_of_platform.c +++ b/drivers/net/can/sja1000/sja1000_of_platform.c @@ -72,7 +72,7 @@ static int __devexit sja1000_ofp_remove(struct of_device *ofdev) { struct net_device *dev = dev_get_drvdata(&ofdev->dev); struct sja1000_priv *priv = netdev_priv(dev); - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct resource res; dev_set_drvdata(&ofdev->dev, NULL); @@ -91,7 +91,7 @@ static int __devexit sja1000_ofp_remove(struct of_device *ofdev) static int __devinit sja1000_ofp_probe(struct of_device *ofdev, const struct of_device_id *id) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct net_device *dev; struct sja1000_priv *priv; struct resource res; diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 809ccc9ff09c..59dac232006c 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -3035,7 +3035,7 @@ static DEVICE_ATTR(log_port_id, S_IRUSR | S_IRGRP | S_IROTH, ehea_show_port_id, static void __devinit logical_port_release(struct device *dev) { struct ehea_port *port = container_of(dev, struct ehea_port, ofdev.dev); - of_node_put(port->ofdev.node); + of_node_put(port->ofdev.dev.of_node); } static struct device *ehea_register_port(struct ehea_port *port, @@ -3043,7 +3043,7 @@ static struct device *ehea_register_port(struct ehea_port *port, { int ret; - port->ofdev.node = of_node_get(dn); + port->ofdev.dev.of_node = of_node_get(dn); port->ofdev.dev.parent = &port->adapter->ofdev->dev; port->ofdev.dev.bus = &ibmebus_bus_type; @@ -3210,7 +3210,7 @@ static int ehea_setup_ports(struct ehea_adapter *adapter) const u32 *dn_log_port_id; int i = 0; - lhea_dn = adapter->ofdev->node; + lhea_dn = adapter->ofdev->dev.of_node; while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no", @@ -3249,7 +3249,7 @@ static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter, struct device_node *eth_dn = NULL; const u32 *dn_log_port_id; - lhea_dn = adapter->ofdev->node; + lhea_dn = adapter->ofdev->dev.of_node; while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no", @@ -3379,7 +3379,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev, const u64 *adapter_handle; int ret; - if (!dev || !dev->node) { + if (!dev || !dev->dev.of_node) { ehea_error("Invalid ibmebus device probed"); return -EINVAL; } @@ -3395,14 +3395,14 @@ static int __devinit ehea_probe_adapter(struct of_device *dev, adapter->ofdev = dev; - adapter_handle = of_get_property(dev->node, "ibm,hea-handle", + adapter_handle = of_get_property(dev->dev.of_node, "ibm,hea-handle", NULL); if (adapter_handle) adapter->handle = *adapter_handle; if (!adapter->handle) { dev_err(&dev->dev, "failed getting handle for adapter" - " '%s'\n", dev->node->full_name); + " '%s'\n", dev->dev.of_node->full_name); ret = -ENODEV; goto out_free_ad; } diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index 4a43e56b7394..3342056f8aac 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -873,7 +873,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) priv->ndev = ndev; /* Reserve FEC control zone */ - rv = of_address_to_resource(op->node, 0, &mem); + rv = of_address_to_resource(op->dev.of_node, 0, &mem); if (rv) { printk(KERN_ERR DRIVER_NAME ": " "Error while parsing device node resource\n" ); @@ -921,7 +921,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) /* Get the IRQ we need one by one */ /* Control */ - ndev->irq = irq_of_parse_and_map(op->node, 0); + ndev->irq = irq_of_parse_and_map(op->dev.of_node, 0); /* RX */ priv->r_irq = bcom_get_task_irq(priv->rx_dmatsk); @@ -944,20 +944,20 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) /* Start with safe defaults for link connection */ priv->speed = 100; priv->duplex = DUPLEX_HALF; - priv->mdio_speed = ((mpc5xxx_get_bus_frequency(op->node) >> 20) / 5) << 1; + priv->mdio_speed = ((mpc5xxx_get_bus_frequency(op->dev.of_node) >> 20) / 5) << 1; /* The current speed preconfigures the speed of the MII link */ - prop = of_get_property(op->node, "current-speed", &prop_size); + prop = of_get_property(op->dev.of_node, "current-speed", &prop_size); if (prop && (prop_size >= sizeof(u32) * 2)) { priv->speed = prop[0]; priv->duplex = prop[1] ? DUPLEX_FULL : DUPLEX_HALF; } /* If there is a phy handle, then get the PHY node */ - priv->phy_node = of_parse_phandle(op->node, "phy-handle", 0); + priv->phy_node = of_parse_phandle(op->dev.of_node, "phy-handle", 0); /* the 7-wire property means don't use MII mode */ - if (of_find_property(op->node, "fsl,7-wire-mode", NULL)) { + if (of_find_property(op->dev.of_node, "fsl,7-wire-mode", NULL)) { priv->seven_wire_mode = 1; dev_info(&ndev->dev, "using 7-wire PHY mode\n"); } diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c index 7658a082e390..0d099e5a652d 100644 --- a/drivers/net/fec_mpc52xx_phy.c +++ b/drivers/net/fec_mpc52xx_phy.c @@ -66,7 +66,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, const struct of_device_id *match) { struct device *dev = &of->dev; - struct device_node *np = of->node; + struct device_node *np = of->dev.of_node; struct mii_bus *bus; struct mpc52xx_fec_mdio_priv *priv; struct resource res = {}; @@ -107,7 +107,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, /* set MII speed */ out_be32(&priv->regs->mii_speed, - ((mpc5xxx_get_bus_frequency(of->node) >> 20) / 5) << 1); + ((mpc5xxx_get_bus_frequency(of->dev.of_node) >> 20) / 5) << 1); err = of_mdiobus_register(bus, np); if (err) diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 0770e2f6da6b..caeb88b67bc6 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -1015,7 +1015,7 @@ static int __devinit fs_enet_probe(struct of_device *ofdev, return -ENOMEM; if (!IS_FEC(match)) { - data = of_get_property(ofdev->node, "fsl,cpm-command", &len); + data = of_get_property(ofdev->dev.of_node, "fsl,cpm-command", &len); if (!data || len != 4) goto out_free_fpi; @@ -1027,8 +1027,8 @@ static int __devinit fs_enet_probe(struct of_device *ofdev, fpi->rx_copybreak = 240; fpi->use_napi = 1; fpi->napi_weight = 17; - fpi->phy_node = of_parse_phandle(ofdev->node, "phy-handle", 0); - if ((!fpi->phy_node) && (!of_get_property(ofdev->node, "fixed-link", + fpi->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-handle", 0); + if ((!fpi->phy_node) && (!of_get_property(ofdev->dev.of_node, "fixed-link", NULL))) goto out_free_fpi; @@ -1061,7 +1061,7 @@ static int __devinit fs_enet_probe(struct of_device *ofdev, spin_lock_init(&fep->lock); spin_lock_init(&fep->tx_lock); - mac_addr = of_get_mac_address(ofdev->node); + mac_addr = of_get_mac_address(ofdev->dev.of_node); if (mac_addr) memcpy(ndev->dev_addr, mac_addr, 6); diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c index 0a973e71876b..9d4f272137d6 100644 --- a/drivers/net/fs_enet/mac-fcc.c +++ b/drivers/net/fs_enet/mac-fcc.c @@ -88,19 +88,19 @@ static int do_pd_setup(struct fs_enet_private *fep) struct fs_platform_info *fpi = fep->fpi; int ret = -EINVAL; - fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); + fep->interrupt = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); if (fep->interrupt == NO_IRQ) goto out; - fep->fcc.fccp = of_iomap(ofdev->node, 0); + fep->fcc.fccp = of_iomap(ofdev->dev.of_node, 0); if (!fep->fcc.fccp) goto out; - fep->fcc.ep = of_iomap(ofdev->node, 1); + fep->fcc.ep = of_iomap(ofdev->dev.of_node, 1); if (!fep->fcc.ep) goto out_fccp; - fep->fcc.fcccp = of_iomap(ofdev->node, 2); + fep->fcc.fcccp = of_iomap(ofdev->dev.of_node, 2); if (!fep->fcc.fcccp) goto out_ep; diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c index ec81f50d5919..bd7a6e7064bb 100644 --- a/drivers/net/fs_enet/mac-fec.c +++ b/drivers/net/fs_enet/mac-fec.c @@ -98,11 +98,11 @@ static int do_pd_setup(struct fs_enet_private *fep) { struct of_device *ofdev = to_of_device(fep->dev); - fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); + fep->interrupt = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); if (fep->interrupt == NO_IRQ) return -EINVAL; - fep->fec.fecp = of_iomap(ofdev->node, 0); + fep->fec.fecp = of_iomap(ofdev->dev.of_node, 0); if (!fep->fcc.fccp) return -EINVAL; diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c index 34d3da751eb4..49a4d8c60168 100644 --- a/drivers/net/fs_enet/mac-scc.c +++ b/drivers/net/fs_enet/mac-scc.c @@ -98,15 +98,15 @@ static int do_pd_setup(struct fs_enet_private *fep) { struct of_device *ofdev = to_of_device(fep->dev); - fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL); + fep->interrupt = of_irq_to_resource(ofdev->dev.of_node, 0, NULL); if (fep->interrupt == NO_IRQ) return -EINVAL; - fep->scc.sccp = of_iomap(ofdev->node, 0); + fep->scc.sccp = of_iomap(ofdev->dev.of_node, 0); if (!fep->scc.sccp) return -EINVAL; - fep->scc.ep = of_iomap(ofdev->node, 1); + fep->scc.ep = of_iomap(ofdev->dev.of_node, 1); if (!fep->scc.ep) { iounmap(fep->scc.sccp); return -EINVAL; diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c index 5944b65082cb..dc862e779c1f 100644 --- a/drivers/net/fs_enet/mii-fec.c +++ b/drivers/net/fs_enet/mii-fec.c @@ -124,7 +124,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, new_bus->write = &fs_enet_fec_mii_write; new_bus->reset = &fs_enet_fec_mii_reset; - ret = of_address_to_resource(ofdev->node, 0, &res); + ret = of_address_to_resource(ofdev->dev.of_node, 0, &res); if (ret) goto out_res; @@ -135,7 +135,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, goto out_fec; if (get_bus_freq) { - clock = get_bus_freq(ofdev->node); + clock = get_bus_freq(ofdev->dev.of_node); if (!clock) { /* Use maximum divider if clock is unknown */ dev_warn(&ofdev->dev, "could not determine IPS clock\n"); @@ -172,7 +172,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, new_bus->parent = &ofdev->dev; dev_set_drvdata(&ofdev->dev, new_bus); - ret = of_mdiobus_register(new_bus, ofdev->node); + ret = of_mdiobus_register(new_bus, ofdev->dev.of_node); if (ret) goto out_free_irqs; diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index d5160edf2fcf..72489a213bf7 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -271,7 +271,7 @@ static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id) static int fsl_pq_mdio_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct device_node *tbi; struct fsl_pq_mdio_priv *priv; struct fsl_pq_mdio __iomem *regs = NULL; diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 080d1cea5b26..b71bba91064c 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -603,7 +603,7 @@ static int gfar_of_init(struct of_device *ofdev, struct net_device **pdev) int err = 0, i; struct net_device *dev = NULL; struct gfar_private *priv = NULL; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct device_node *child = NULL; const u32 *stash; const u32 *stash_len; @@ -641,7 +641,7 @@ static int gfar_of_init(struct of_device *ofdev, struct net_device **pdev) return -ENOMEM; priv = netdev_priv(dev); - priv->node = ofdev->node; + priv->node = ofdev->dev.of_node; priv->ndev = dev; dev->num_tx_queues = num_tx_qs; @@ -888,7 +888,7 @@ static int gfar_probe(struct of_device *ofdev, priv = netdev_priv(dev); priv->ndev = dev; priv->ofdev = ofdev; - priv->node = ofdev->node; + priv->node = ofdev->dev.of_node; SET_NETDEV_DEV(dev, &ofdev->dev); spin_lock_init(&priv->bflock); diff --git a/drivers/net/greth.c b/drivers/net/greth.c index 3a90430de918..61fd54d35f63 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -1500,7 +1500,8 @@ static int __devinit greth_of_probe(struct of_device *ofdev, const struct of_dev if (i == 6) { const unsigned char *addr; int len; - addr = of_get_property(ofdev->node, "local-mac-address", &len); + addr = of_get_property(ofdev->dev.of_node, "local-mac-address", + &len); if (addr != NULL && len == 6) { for (i = 0; i < 6; i++) macaddr[i] = (unsigned int) addr[i]; diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index dd873cc41c2b..cda2ba891344 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -136,7 +136,8 @@ static inline void emac_report_timeout_error(struct emac_instance *dev, EMAC_FTR_440EP_PHY_CLK_FIX)) DBG(dev, "%s" NL, error); else if (net_ratelimit()) - printk(KERN_ERR "%s: %s\n", dev->ofdev->node->full_name, error); + printk(KERN_ERR "%s: %s\n", dev->ofdev->dev.of_node->full_name, + error); } /* EMAC PHY clock workaround: @@ -2185,7 +2186,7 @@ static void emac_ethtool_get_drvinfo(struct net_device *ndev, strcpy(info->version, DRV_VERSION); info->fw_version[0] = '\0'; sprintf(info->bus_info, "PPC 4xx EMAC-%d %s", - dev->cell_index, dev->ofdev->node->full_name); + dev->cell_index, dev->ofdev->dev.of_node->full_name); info->regdump_len = emac_ethtool_get_regs_len(ndev); } @@ -2379,7 +2380,7 @@ static int __devinit emac_read_uint_prop(struct device_node *np, const char *nam static int __devinit emac_init_phy(struct emac_instance *dev) { - struct device_node *np = dev->ofdev->node; + struct device_node *np = dev->ofdev->dev.of_node; struct net_device *ndev = dev->ndev; u32 phy_map, adv; int i; @@ -2514,7 +2515,7 @@ static int __devinit emac_init_phy(struct emac_instance *dev) static int __devinit emac_init_config(struct emac_instance *dev) { - struct device_node *np = dev->ofdev->node; + struct device_node *np = dev->ofdev->dev.of_node; const void *p; unsigned int plen; const char *pm, *phy_modes[] = { @@ -2723,7 +2724,7 @@ static int __devinit emac_probe(struct of_device *ofdev, { struct net_device *ndev; struct emac_instance *dev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct device_node **blist = NULL; int err, i; @@ -2810,7 +2811,7 @@ static int __devinit emac_probe(struct of_device *ofdev, err = mal_register_commac(dev->mal, &dev->commac); if (err) { printk(KERN_ERR "%s: failed to register with mal %s!\n", - np->full_name, dev->mal_dev->node->full_name); + np->full_name, dev->mal_dev->dev.of_node->full_name); goto err_rel_deps; } dev->rx_skb_size = emac_rx_skb_size(ndev->mtu); diff --git a/drivers/net/ibm_newemac/debug.c b/drivers/net/ibm_newemac/debug.c index 775c850a425a..3995fafc1e08 100644 --- a/drivers/net/ibm_newemac/debug.c +++ b/drivers/net/ibm_newemac/debug.c @@ -33,7 +33,7 @@ static void emac_desc_dump(struct emac_instance *p) int i; printk("** EMAC %s TX BDs **\n" " tx_cnt = %d tx_slot = %d ack_slot = %d\n", - p->ofdev->node->full_name, + p->ofdev->dev.of_node->full_name, p->tx_cnt, p->tx_slot, p->ack_slot); for (i = 0; i < NUM_TX_BUFF / 2; ++i) printk @@ -49,7 +49,7 @@ static void emac_desc_dump(struct emac_instance *p) printk("** EMAC %s RX BDs **\n" " rx_slot = %d flags = 0x%lx rx_skb_size = %d rx_sync_size = %d\n" " rx_sg_skb = 0x%p\n", - p->ofdev->node->full_name, + p->ofdev->dev.of_node->full_name, p->rx_slot, p->commac.flags, p->rx_skb_size, p->rx_sync_size, p->rx_sg_skb); for (i = 0; i < NUM_RX_BUFF / 2; ++i) @@ -77,7 +77,8 @@ static void emac_mac_dump(struct emac_instance *dev) "MR0 = 0x%08x MR1 = 0x%08x TMR0 = 0x%08x TMR1 = 0x%08x\n" "RMR = 0x%08x ISR = 0x%08x ISER = 0x%08x\n" "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n", - dev->ofdev->node->full_name, in_be32(&p->mr0), in_be32(&p->mr1), + dev->ofdev->dev.of_node->full_name, + in_be32(&p->mr0), in_be32(&p->mr1), in_be32(&p->tmr0), in_be32(&p->tmr1), in_be32(&p->rmr), in_be32(&p->isr), in_be32(&p->iser), in_be32(&p->iahr), in_be32(&p->ialr), in_be32(&p->vtpid), @@ -128,7 +129,7 @@ static void emac_mal_dump(struct mal_instance *mal) "CFG = 0x%08x ESR = 0x%08x IER = 0x%08x\n" "TX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n" "RX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n", - mal->ofdev->node->full_name, + mal->ofdev->dev.of_node->full_name, get_mal_dcrn(mal, MAL_CFG), get_mal_dcrn(mal, MAL_ESR), get_mal_dcrn(mal, MAL_IER), get_mal_dcrn(mal, MAL_TXCASR), get_mal_dcrn(mal, MAL_TXCARR), diff --git a/drivers/net/ibm_newemac/debug.h b/drivers/net/ibm_newemac/debug.h index b631842ec8d0..e596c77ccdf7 100644 --- a/drivers/net/ibm_newemac/debug.h +++ b/drivers/net/ibm_newemac/debug.h @@ -53,8 +53,8 @@ extern void emac_dbg_dump_all(void); #endif -#define EMAC_DBG(dev, name, fmt, arg...) \ - printk(KERN_DEBUG #name "%s: " fmt, dev->ofdev->node->full_name, ## arg) +#define EMAC_DBG(d, name, fmt, arg...) \ + printk(KERN_DEBUG #name "%s: " fmt, d->ofdev->dev.of_node->full_name, ## arg) #if DBG_LEVEL > 0 # define DBG(d,f,x...) EMAC_DBG(d, emac, f, ##x) diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c index 5b3d94419fe6..aba17947e208 100644 --- a/drivers/net/ibm_newemac/mal.c +++ b/drivers/net/ibm_newemac/mal.c @@ -538,11 +538,11 @@ static int __devinit mal_probe(struct of_device *ofdev, } mal->index = index; mal->ofdev = ofdev; - mal->version = of_device_is_compatible(ofdev->node, "ibm,mcmal2") ? 2 : 1; + mal->version = of_device_is_compatible(ofdev->dev.of_node, "ibm,mcmal2") ? 2 : 1; MAL_DBG(mal, "probe" NL); - prop = of_get_property(ofdev->node, "num-tx-chans", NULL); + prop = of_get_property(ofdev->dev.of_node, "num-tx-chans", NULL); if (prop == NULL) { printk(KERN_ERR "mal%d: can't find MAL num-tx-chans property!\n", @@ -552,7 +552,7 @@ static int __devinit mal_probe(struct of_device *ofdev, } mal->num_tx_chans = prop[0]; - prop = of_get_property(ofdev->node, "num-rx-chans", NULL); + prop = of_get_property(ofdev->dev.of_node, "num-rx-chans", NULL); if (prop == NULL) { printk(KERN_ERR "mal%d: can't find MAL num-rx-chans property!\n", @@ -562,14 +562,14 @@ static int __devinit mal_probe(struct of_device *ofdev, } mal->num_rx_chans = prop[0]; - dcr_base = dcr_resource_start(ofdev->node, 0); + dcr_base = dcr_resource_start(ofdev->dev.of_node, 0); if (dcr_base == 0) { printk(KERN_ERR "mal%d: can't find DCR resource!\n", index); err = -ENODEV; goto fail; } - mal->dcr_host = dcr_map(ofdev->node, dcr_base, 0x100); + mal->dcr_host = dcr_map(ofdev->dev.of_node, dcr_base, 0x100); if (!DCR_MAP_OK(mal->dcr_host)) { printk(KERN_ERR "mal%d: failed to map DCRs !\n", index); @@ -577,28 +577,28 @@ static int __devinit mal_probe(struct of_device *ofdev, goto fail; } - if (of_device_is_compatible(ofdev->node, "ibm,mcmal-405ez")) { + if (of_device_is_compatible(ofdev->dev.of_node, "ibm,mcmal-405ez")) { #if defined(CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT) && \ defined(CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR) mal->features |= (MAL_FTR_CLEAR_ICINTSTAT | MAL_FTR_COMMON_ERR_INT); #else printk(KERN_ERR "%s: Support for 405EZ not enabled!\n", - ofdev->node->full_name); + ofdev->dev.of_node->full_name); err = -ENODEV; goto fail; #endif } - mal->txeob_irq = irq_of_parse_and_map(ofdev->node, 0); - mal->rxeob_irq = irq_of_parse_and_map(ofdev->node, 1); - mal->serr_irq = irq_of_parse_and_map(ofdev->node, 2); + mal->txeob_irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); + mal->rxeob_irq = irq_of_parse_and_map(ofdev->dev.of_node, 1); + mal->serr_irq = irq_of_parse_and_map(ofdev->dev.of_node, 2); if (mal_has_feature(mal, MAL_FTR_COMMON_ERR_INT)) { mal->txde_irq = mal->rxde_irq = mal->serr_irq; } else { - mal->txde_irq = irq_of_parse_and_map(ofdev->node, 3); - mal->rxde_irq = irq_of_parse_and_map(ofdev->node, 4); + mal->txde_irq = irq_of_parse_and_map(ofdev->dev.of_node, 3); + mal->rxde_irq = irq_of_parse_and_map(ofdev->dev.of_node, 4); } if (mal->txeob_irq == NO_IRQ || mal->rxeob_irq == NO_IRQ || @@ -629,7 +629,7 @@ static int __devinit mal_probe(struct of_device *ofdev, /* Current Axon is not happy with priority being non-0, it can * deadlock, fix it up here */ - if (of_device_is_compatible(ofdev->node, "ibm,mcmal-axon")) + if (of_device_is_compatible(ofdev->dev.of_node, "ibm,mcmal-axon")) cfg &= ~(MAL2_CFG_RPP_10 | MAL2_CFG_WPP_10); /* Apply configuration */ @@ -701,7 +701,7 @@ static int __devinit mal_probe(struct of_device *ofdev, printk(KERN_INFO "MAL v%d %s, %d TX channels, %d RX channels\n", - mal->version, ofdev->node->full_name, + mal->version, ofdev->dev.of_node->full_name, mal->num_tx_chans, mal->num_rx_chans); /* Advertise this instance to the rest of the world */ diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c index 5b90d34c8455..6ab630a79e31 100644 --- a/drivers/net/ibm_newemac/rgmii.c +++ b/drivers/net/ibm_newemac/rgmii.c @@ -103,7 +103,7 @@ int __devinit rgmii_attach(struct of_device *ofdev, int input, int mode) /* Check if we need to attach to a RGMII */ if (input < 0 || !rgmii_valid_mode(mode)) { printk(KERN_ERR "%s: unsupported settings !\n", - ofdev->node->full_name); + ofdev->dev.of_node->full_name); return -ENODEV; } @@ -113,7 +113,7 @@ int __devinit rgmii_attach(struct of_device *ofdev, int input, int mode) out_be32(&p->fer, in_be32(&p->fer) | rgmii_mode_mask(mode, input)); printk(KERN_NOTICE "%s: input %d in %s mode\n", - ofdev->node->full_name, input, rgmii_mode_name(mode)); + ofdev->dev.of_node->full_name, input, rgmii_mode_name(mode)); ++dev->users; @@ -231,7 +231,7 @@ void *rgmii_dump_regs(struct of_device *ofdev, void *buf) static int __devinit rgmii_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct rgmii_instance *dev; struct resource regs; int rc; @@ -264,11 +264,11 @@ static int __devinit rgmii_probe(struct of_device *ofdev, } /* Check for RGMII flags */ - if (of_get_property(ofdev->node, "has-mdio", NULL)) + if (of_get_property(ofdev->dev.of_node, "has-mdio", NULL)) dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO; /* CAB lacks the right properties, fix this up */ - if (of_device_is_compatible(ofdev->node, "ibm,rgmii-axon")) + if (of_device_is_compatible(ofdev->dev.of_node, "ibm,rgmii-axon")) dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO; DBG2(dev, " Boot FER = 0x%08x, SSR = 0x%08x\n", @@ -279,7 +279,7 @@ static int __devinit rgmii_probe(struct of_device *ofdev, printk(KERN_INFO "RGMII %s initialized with%s MDIO support\n", - ofdev->node->full_name, + ofdev->dev.of_node->full_name, (dev->flags & EMAC_RGMII_FLAG_HAS_MDIO) ? "" : "out"); wmb(); diff --git a/drivers/net/ibm_newemac/tah.c b/drivers/net/ibm_newemac/tah.c index 30173a9fb557..4f64b00dd5e8 100644 --- a/drivers/net/ibm_newemac/tah.c +++ b/drivers/net/ibm_newemac/tah.c @@ -57,7 +57,8 @@ void tah_reset(struct of_device *ofdev) --n; if (unlikely(!n)) - printk(KERN_ERR "%s: reset timeout\n", ofdev->node->full_name); + printk(KERN_ERR "%s: reset timeout\n", + ofdev->dev.of_node->full_name); /* 10KB TAH TX FIFO accomodates the max MTU of 9000 */ out_be32(&p->mr, @@ -89,7 +90,7 @@ void *tah_dump_regs(struct of_device *ofdev, void *buf) static int __devinit tah_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct tah_instance *dev; struct resource regs; int rc; @@ -127,7 +128,7 @@ static int __devinit tah_probe(struct of_device *ofdev, tah_reset(ofdev); printk(KERN_INFO - "TAH %s initialized\n", ofdev->node->full_name); + "TAH %s initialized\n", ofdev->dev.of_node->full_name); wmb(); return 0; diff --git a/drivers/net/ibm_newemac/zmii.c b/drivers/net/ibm_newemac/zmii.c index 1f038f808ab3..b4fa823ed201 100644 --- a/drivers/net/ibm_newemac/zmii.c +++ b/drivers/net/ibm_newemac/zmii.c @@ -121,13 +121,14 @@ int __devinit zmii_attach(struct of_device *ofdev, int input, int *mode) dev->mode = *mode; printk(KERN_NOTICE "%s: bridge in %s mode\n", - ofdev->node->full_name, zmii_mode_name(dev->mode)); + ofdev->dev.of_node->full_name, + zmii_mode_name(dev->mode)); } else { /* All inputs must use the same mode */ if (*mode != PHY_MODE_NA && *mode != dev->mode) { printk(KERN_ERR "%s: invalid mode %d specified for input %d\n", - ofdev->node->full_name, *mode, input); + ofdev->dev.of_node->full_name, *mode, input); mutex_unlock(&dev->lock); return -EINVAL; } @@ -233,7 +234,7 @@ void *zmii_dump_regs(struct of_device *ofdev, void *buf) static int __devinit zmii_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct zmii_instance *dev; struct resource regs; int rc; @@ -273,7 +274,7 @@ static int __devinit zmii_probe(struct of_device *ofdev, out_be32(&dev->base->fer, 0); printk(KERN_INFO - "ZMII %s initialized\n", ofdev->node->full_name); + "ZMII %s initialized\n", ofdev->dev.of_node->full_name); wmb(); dev_set_drvdata(&ofdev->dev, dev); diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index ba617e3cf1bb..9c7395c10e44 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -858,14 +858,14 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) mutex_init(&lp->indirect_mutex); /* map device registers */ - lp->regs = of_iomap(op->node, 0); + lp->regs = of_iomap(op->dev.of_node, 0); if (!lp->regs) { dev_err(&op->dev, "could not map temac regs.\n"); goto nodev; } /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */ - np = of_parse_phandle(op->node, "llink-connected", 0); + np = of_parse_phandle(op->dev.of_node, "llink-connected", 0); if (!np) { dev_err(&op->dev, "could not find DMA node\n"); goto nodev; @@ -890,7 +890,7 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) of_node_put(np); /* Finished with the DMA node; drop the reference */ /* Retrieve the MAC address */ - addr = of_get_property(op->node, "local-mac-address", &size); + addr = of_get_property(op->dev.of_node, "local-mac-address", &size); if ((!addr) || (size != 6)) { dev_err(&op->dev, "could not find MAC address\n"); rc = -ENODEV; @@ -898,11 +898,11 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) } temac_set_mac_address(ndev, (void *)addr); - rc = temac_mdio_setup(lp, op->node); + rc = temac_mdio_setup(lp, op->dev.of_node); if (rc) dev_warn(&op->dev, "error registering MDIO bus\n"); - lp->phy_node = of_parse_phandle(op->node, "phy-handle", 0); + lp->phy_node = of_parse_phandle(op->dev.of_node, "phy-handle", 0); if (lp->phy_node) dev_dbg(lp->dev, "using PHY node %s (%p)\n", np->full_name, np); diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index b72e749afdf1..e21439f1e775 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -928,7 +928,7 @@ static const struct net_device_ops myri_ops = { static int __devinit myri_sbus_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; static unsigned version_printed; struct net_device *dev; struct myri_eth *mp; diff --git a/drivers/net/niu.c b/drivers/net/niu.c index d5cd16bfc907..9c1604c04450 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -9094,7 +9094,7 @@ static int __devinit niu_n2_irq_init(struct niu *np, u8 *ldg_num_map) const u32 *int_prop; int i; - int_prop = of_get_property(op->node, "interrupts", NULL); + int_prop = of_get_property(op->dev.of_node, "interrupts", NULL); if (!int_prop) return -ENODEV; @@ -9245,7 +9245,7 @@ static int __devinit niu_get_of_props(struct niu *np) int prop_len; if (np->parent->plat_type == PLAT_TYPE_NIU) - dp = np->op->node; + dp = np->op->dev.of_node; else dp = pci_device_to_OF_node(np->pdev); @@ -10056,10 +10056,10 @@ static int __devinit niu_of_probe(struct of_device *op, niu_driver_version(); - reg = of_get_property(op->node, "reg", NULL); + reg = of_get_property(op->dev.of_node, "reg", NULL); if (!reg) { dev_err(&op->dev, "%s: No 'reg' property, aborting\n", - op->node->full_name); + op->dev.of_node->full_name); return -ENODEV; } @@ -10072,7 +10072,7 @@ static int __devinit niu_of_probe(struct of_device *op, np = netdev_priv(dev); memset(&parent_id, 0, sizeof(parent_id)); - parent_id.of = of_get_parent(op->node); + parent_id.of = of_get_parent(op->dev.of_node); np->parent = niu_get_parent(np, &parent_id, PLAT_TYPE_NIU); diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 35897134a5dd..641973ca2417 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c @@ -199,12 +199,12 @@ static int __devinit mdio_ofgpio_probe(struct of_device *ofdev, if (!pdata) return -ENOMEM; - ret = of_get_gpio(ofdev->node, 0); + ret = of_get_gpio(ofdev->dev.of_node, 0); if (ret < 0) goto out_free; pdata->mdc = ret; - ret = of_get_gpio(ofdev->node, 1); + ret = of_get_gpio(ofdev->dev.of_node, 1); if (ret < 0) goto out_free; pdata->mdio = ret; @@ -213,7 +213,7 @@ static int __devinit mdio_ofgpio_probe(struct of_device *ofdev, if (!new_bus) goto out_free; - ret = of_mdiobus_register(new_bus, ofdev->node); + ret = of_mdiobus_register(new_bus, ofdev->dev.of_node); if (ret) mdio_gpio_bus_deinit(&ofdev->dev); diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index ed7865a0b5b2..bd286ec5abd9 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -1133,8 +1133,8 @@ static int __devinit bigmac_ether_init(struct of_device *op, goto fail_and_cleanup; /* Get supported SBUS burst sizes. */ - bsizes = of_getintprop_default(qec_op->node, "burst-sizes", 0xff); - bsizes_more = of_getintprop_default(qec_op->node, "burst-sizes", 0xff); + bsizes = of_getintprop_default(qec_op->dev.of_node, "burst-sizes", 0xff); + bsizes_more = of_getintprop_default(qec_op->dev.of_node, "burst-sizes", 0xff); bsizes &= 0xff; if (bsizes_more != 0xff) @@ -1186,7 +1186,7 @@ static int __devinit bigmac_ether_init(struct of_device *op, } /* Get the board revision of this BigMAC. */ - bp->board_rev = of_getintprop_default(bp->bigmac_op->node, + bp->board_rev = of_getintprop_default(bp->bigmac_op->dev.of_node, "board-version", 1); /* Init auto-negotiation timer state. */ diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index b17dbb11bd67..c6463f71c916 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -2483,7 +2483,7 @@ static void hme_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info else { const struct linux_prom_registers *regs; struct of_device *op = hp->happy_dev; - regs = of_get_property(op->node, "regs", NULL); + regs = of_get_property(op->dev.of_node, "regs", NULL); if (regs) sprintf(info->bus_info, "SBUS:%d", regs->which_io); @@ -2643,14 +2643,14 @@ static const struct net_device_ops hme_netdev_ops = { #ifdef CONFIG_SBUS static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe) { - struct device_node *dp = op->node, *sbus_dp; + struct device_node *dp = op->dev.of_node, *sbus_dp; struct quattro *qp = NULL; struct happy_meal *hp; struct net_device *dev; int i, qfe_slot = -1; int err = -ENODEV; - sbus_dp = to_of_device(op->dev.parent)->node; + sbus_dp = to_of_device(op->dev.parent)->dev.of_node; /* We can match PCI devices too, do not accept those here. */ if (strcmp(sbus_dp->name, "sbus")) @@ -3241,7 +3241,7 @@ static void happy_meal_pci_exit(void) #ifdef CONFIG_SBUS static int __devinit hme_sbus_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; const char *model = of_get_property(dp, "model", NULL); int is_qfe = (match->data != NULL); diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 0c21653ff9f9..28afc86e0694 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -1324,7 +1324,7 @@ static int __devinit sparc_lance_probe_one(struct of_device *op, struct of_device *ledma, struct of_device *lebuffer) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; static unsigned version_printed; struct lance_private *lp; struct net_device *dev; @@ -1411,7 +1411,7 @@ static int __devinit sparc_lance_probe_one(struct of_device *op, lp->burst_sizes = 0; if (lp->ledma) { - struct device_node *ledma_dp = ledma->node; + struct device_node *ledma_dp = ledma->dev.of_node; struct device_node *sbus_dp; unsigned int sbmask; const char *prop; @@ -1507,7 +1507,7 @@ fail: static int __devinit sunlance_sbus_probe(struct of_device *op, const struct of_device_id *match) { struct of_device *parent = to_of_device(op->dev.parent); - struct device_node *parent_dp = parent->node; + struct device_node *parent_dp = parent->dev.of_node; int err; if (!strcmp(parent_dp->name, "ledma")) { diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index be637dce944c..9864f4fa69d5 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c @@ -696,7 +696,7 @@ static void qe_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) strcpy(info->version, "3.0"); op = qep->op; - regs = of_get_property(op->node, "reg", NULL); + regs = of_get_property(op->dev.of_node, "reg", NULL); if (regs) sprintf(info->bus_info, "SBUS:%d", regs->which_io); @@ -800,7 +800,7 @@ static struct sunqec * __devinit get_qec(struct of_device *child) if (qec_global_reset(qecp->gregs)) goto fail; - qecp->qec_bursts = qec_get_burst(op->node); + qecp->qec_bursts = qec_get_burst(op->dev.of_node); qec_init_once(qecp, op); @@ -858,7 +858,7 @@ static int __devinit qec_ether_init(struct of_device *op) res = -ENODEV; - i = of_getintprop_default(op->node, "channel#", -1); + i = of_getintprop_default(op->dev.of_node, "channel#", -1); if (i == -1) goto fail; qe->channel = i; diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 1b0aef37e495..88ebfc976735 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3721,7 +3721,7 @@ static const struct net_device_ops ucc_geth_netdev_ops = { static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *match) { struct device *device = &ofdev->dev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct net_device *dev = NULL; struct ucc_geth_private *ugeth = NULL; struct ucc_geth_info *ug_info; diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index 1e783ccc306e..3dd2416db540 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -1090,7 +1090,7 @@ static void xemaclite_remove_ndev(struct net_device *ndev) */ static bool get_bool(struct of_device *ofdev, const char *s) { - u32 *p = (u32 *)of_get_property(ofdev->node, s, NULL); + u32 *p = (u32 *)of_get_property(ofdev->dev.of_node, s, NULL); if (p) { return (bool)*p; @@ -1132,14 +1132,14 @@ static int __devinit xemaclite_of_probe(struct of_device *ofdev, dev_info(dev, "Device Tree Probing\n"); /* Get iospace for the device */ - rc = of_address_to_resource(ofdev->node, 0, &r_mem); + rc = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem); if (rc) { dev_err(dev, "invalid address\n"); return rc; } /* Get IRQ for the device */ - rc = of_irq_to_resource(ofdev->node, 0, &r_irq); + rc = of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq); if (rc == NO_IRQ) { dev_err(dev, "no IRQ found\n"); return rc; @@ -1184,7 +1184,7 @@ static int __devinit xemaclite_of_probe(struct of_device *ofdev, lp->next_rx_buf_to_use = 0x0; lp->tx_ping_pong = get_bool(ofdev, "xlnx,tx-ping-pong"); lp->rx_ping_pong = get_bool(ofdev, "xlnx,rx-ping-pong"); - mac_address = of_get_mac_address(ofdev->node); + mac_address = of_get_mac_address(ofdev->dev.of_node); if (mac_address) /* Set the MAC address. */ @@ -1199,7 +1199,7 @@ static int __devinit xemaclite_of_probe(struct of_device *ofdev, /* Set the MAC address in the EmacLite device */ xemaclite_update_address(lp, ndev->dev_addr); - lp->phy_node = of_parse_phandle(ofdev->node, "phy-handle", 0); + lp->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-handle", 0); rc = xemaclite_mdio_setup(lp, &ofdev->dev); if (rc) dev_warn(&ofdev->dev, "error registering MDIO bus\n"); diff --git a/drivers/of/device.c b/drivers/of/device.c index 224ae6bc67b6..24068bbbce1a 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -21,9 +21,9 @@ const struct of_device_id *of_match_device(const struct of_device_id *matches, const struct of_device *dev) { - if (!dev->node) + if (!dev->dev.of_node) return NULL; - return of_match_node(matches, dev->node); + return of_match_node(matches, dev->dev.of_node); } EXPORT_SYMBOL(of_match_device); @@ -54,7 +54,7 @@ static ssize_t devspec_show(struct device *dev, struct of_device *ofdev; ofdev = to_of_device(dev); - return sprintf(buf, "%s\n", ofdev->node->full_name); + return sprintf(buf, "%s\n", ofdev->dev.of_node->full_name); } static ssize_t name_show(struct device *dev, @@ -63,7 +63,7 @@ static ssize_t name_show(struct device *dev, struct of_device *ofdev; ofdev = to_of_device(dev); - return sprintf(buf, "%s\n", ofdev->node->name); + return sprintf(buf, "%s\n", ofdev->dev.of_node->name); } static ssize_t modalias_show(struct device *dev, @@ -97,14 +97,14 @@ void of_release_dev(struct device *dev) struct of_device *ofdev; ofdev = to_of_device(dev); - of_node_put(ofdev->node); + of_node_put(ofdev->dev.of_node); kfree(ofdev); } EXPORT_SYMBOL(of_release_dev); int of_device_register(struct of_device *ofdev) { - BUG_ON(ofdev->node == NULL); + BUG_ON(ofdev->dev.of_node == NULL); device_initialize(&ofdev->dev); @@ -112,7 +112,7 @@ int of_device_register(struct of_device *ofdev) * the parent. If there is no parent defined, set the node * explicitly */ if (!ofdev->dev.parent) - set_dev_node(&ofdev->dev, of_node_to_nid(ofdev->node)); + set_dev_node(&ofdev->dev, of_node_to_nid(ofdev->dev.of_node)); return device_add(&ofdev->dev); } @@ -132,11 +132,11 @@ ssize_t of_device_get_modalias(struct of_device *ofdev, ssize_t tsize, csize, repend; /* Name & Type */ - csize = snprintf(str, len, "of:N%sT%s", - ofdev->node->name, ofdev->node->type); + csize = snprintf(str, len, "of:N%sT%s", ofdev->dev.of_node->name, + ofdev->dev.of_node->type); /* Get compatible property if any */ - compat = of_get_property(ofdev->node, "compatible", &cplen); + compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen); if (!compat) return csize; diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index e690a2aa6fef..604ba966e1c9 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c @@ -69,7 +69,7 @@ EXPORT_SYMBOL(of_register_i2c_devices); static int of_dev_node_match(struct device *dev, void *data) { - return dev_archdata_get_node(&dev->archdata) == data; + return dev->of_node == data; } /* must call put_device() when done with returned i2c_client device */ diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 12090f57dc87..01d794abe105 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -101,7 +101,7 @@ EXPORT_SYMBOL(of_mdiobus_register); /* Helper function for of_phy_find_device */ static int of_phy_match(struct device *dev, void *phy_np) { - return dev_archdata_get_node(&dev->archdata) == phy_np; + return dev->of_node == phy_np; } /** @@ -167,7 +167,7 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev, if (!dev->dev.parent) return NULL; - net_np = dev_archdata_get_node(&dev->dev.parent->archdata); + net_np = dev->dev.parent->of_node; if (!net_np) return NULL; diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index 2e59fe947d28..a22d32d71bf2 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c @@ -185,7 +185,7 @@ static int __devinit electra_cf_probe(struct of_device *ofdev, const struct of_device_id *match) { struct device *device = &ofdev->dev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct electra_cf_socket *cf; struct resource mem, io; int status; diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c index b4951eb0358e..103fdf6b0b89 100644 --- a/drivers/sbus/char/bbc_envctrl.c +++ b/drivers/sbus/char/bbc_envctrl.c @@ -565,9 +565,9 @@ int bbc_envctrl_init(struct bbc_i2c_bus *bp) int devidx = 0; while ((op = bbc_i2c_getdev(bp, devidx++)) != NULL) { - if (!strcmp(op->node->name, "temperature")) + if (!strcmp(op->dev.of_node->name, "temperature")) attach_one_temp(bp, op, temp_index++); - if (!strcmp(op->node->name, "fan-control")) + if (!strcmp(op->dev.of_node->name, "fan-control")) attach_one_fan(bp, op, fan_index++); } if (temp_index != 0 && fan_index != 0) { diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c index 7e30e5f6e032..1543ac32b79b 100644 --- a/drivers/sbus/char/bbc_i2c.c +++ b/drivers/sbus/char/bbc_i2c.c @@ -97,7 +97,7 @@ struct bbc_i2c_client *bbc_i2c_attach(struct bbc_i2c_bus *bp, struct of_device * client->bp = bp; client->op = op; - reg = of_get_property(op->node, "reg", NULL); + reg = of_get_property(op->dev.of_node, "reg", NULL); if (!reg) { kfree(client); return NULL; @@ -327,7 +327,7 @@ static struct bbc_i2c_bus * __init attach_one_i2c(struct of_device *op, int inde spin_lock_init(&bp->lock); entry = 0; - for (dp = op->node->child; + for (dp = op->dev.of_node->child; dp && entry < 8; dp = dp->sibling, entry++) { struct of_device *child_op; diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c index 3e59189f4137..7fc7f34f3466 100644 --- a/drivers/sbus/char/display7seg.c +++ b/drivers/sbus/char/display7seg.c @@ -216,7 +216,7 @@ static int __devinit d7s_probe(struct of_device *op, writeb(regs, p->regs); printk(KERN_INFO PFX "7-Segment Display%s at [%s:0x%llx] %s\n", - op->node->full_name, + op->dev.of_node->full_name, (regs & D7S_FLIP) ? " (FLIPPED)" : "", op->resource[0].start, sol_compat ? "in sol_compat mode" : ""); diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index c6e2eff19409..a5fe20faf4f7 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c @@ -1043,7 +1043,7 @@ static int __devinit envctrl_probe(struct of_device *op, return -ENOMEM; index = 0; - dp = op->node->child; + dp = op->dev.of_node->child; while (dp) { if (!strcmp(dp->name, "gpio")) { i2c_childlist[index].i2ctype = I2C_GPIO; diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index 19f255b97c86..202ff8f75afb 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c @@ -162,7 +162,7 @@ static struct miscdevice flash_dev = { FLASH_MINOR, "flash", &flash_fops }; static int __devinit flash_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct device_node *parent; parent = dp->parent; @@ -184,7 +184,7 @@ static int __devinit flash_probe(struct of_device *op, flash.busy = 0; printk(KERN_INFO "%s: OBP Flash, RD %lx[%lx] WR %lx[%lx]\n", - op->node->full_name, + op->dev.of_node->full_name, flash.read_base, flash.read_size, flash.write_base, flash.write_size); diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c index 2c56fd56ec63..acc6738aa61f 100644 --- a/drivers/sbus/char/uctrl.c +++ b/drivers/sbus/char/uctrl.c @@ -382,7 +382,7 @@ static int __devinit uctrl_probe(struct of_device *op, sbus_writel(UCTRL_INTR_RXNE_REQ|UCTRL_INTR_RXNE_MSK, &p->regs->uctrl_intr); printk(KERN_INFO "%s: uctrl regs[0x%p] (irq %d)\n", - op->node->full_name, p->regs, p->irq); + op->dev.of_node->full_name, p->regs, p->irq); uctrl_get_event_status(p); uctrl_get_external_status(p); diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index c2eea711a5ce..60cd4ec51eae 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -1157,7 +1157,7 @@ static void ibmvfc_gather_partition_info(struct ibmvfc_host *vhost) static void ibmvfc_set_login_info(struct ibmvfc_host *vhost) { struct ibmvfc_npiv_login *login_info = &vhost->login_info; - struct device_node *of_node = vhost->dev->archdata.of_node; + struct device_node *of_node = vhost->dev->of_node; const char *location; memset(login_info, 0, sizeof(*login_info)); diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index ff5ec5ac1fb5..cc38fefc2612 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -957,7 +957,7 @@ static void send_mad_capabilities(struct ibmvscsi_host_data *hostdata) struct viosrp_capabilities *req; struct srp_event_struct *evt_struct; unsigned long flags; - struct device_node *of_node = hostdata->dev->archdata.of_node; + struct device_node *of_node = hostdata->dev->of_node; const char *location; evt_struct = get_event_struct(&hostdata->pool); diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index aa406497eebc..35433d23b7ce 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -755,7 +755,7 @@ static void __devinit qpti_get_scsi_id(struct qlogicpti *qpti) struct of_device *op = qpti->op; struct device_node *dp; - dp = op->node; + dp = op->dev.of_node; qpti->scsi_id = of_getintprop_default(dp, "initiator-id", -1); if (qpti->scsi_id == -1) @@ -776,8 +776,8 @@ static void qpti_get_bursts(struct qlogicpti *qpti) struct of_device *op = qpti->op; u8 bursts, bmask; - bursts = of_getintprop_default(op->node, "burst-sizes", 0xff); - bmask = of_getintprop_default(op->node->parent, "burst-sizes", 0xff); + bursts = of_getintprop_default(op->dev.of_node, "burst-sizes", 0xff); + bmask = of_getintprop_default(op->dev.of_node->parent, "burst-sizes", 0xff); if (bmask != 0xff) bursts &= bmask; if (bursts == 0xff || @@ -1293,7 +1293,7 @@ static struct scsi_host_template qpti_template = { static int __devinit qpti_sbus_probe(struct of_device *op, const struct of_device_id *match) { struct scsi_host_template *tpnt = match->data; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct Scsi_Host *host; struct qlogicpti *qpti; static int nqptis; @@ -1315,7 +1315,7 @@ static int __devinit qpti_sbus_probe(struct of_device *op, const struct of_devic qpti->qhost = host; qpti->op = op; qpti->qpti_id = nqptis; - strcpy(qpti->prom_name, op->node->name); + strcpy(qpti->prom_name, op->dev.of_node->name); qpti->is_pti = strcmp(qpti->prom_name, "QLGC,isp"); if (qpti_map_regs(qpti) < 0) diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c index fc23d273fb1a..151df73df475 100644 --- a/drivers/scsi/sun_esp.c +++ b/drivers/scsi/sun_esp.c @@ -125,7 +125,7 @@ static void __devinit esp_get_scsi_id(struct esp *esp, struct of_device *espdma) struct of_device *op = esp->dev; struct device_node *dp; - dp = op->node; + dp = op->dev.of_node; esp->scsi_id = of_getintprop_default(dp, "initiator-id", 0xff); if (esp->scsi_id != 0xff) goto done; @@ -134,7 +134,7 @@ static void __devinit esp_get_scsi_id(struct esp *esp, struct of_device *espdma) if (esp->scsi_id != 0xff) goto done; - esp->scsi_id = of_getintprop_default(espdma->node, + esp->scsi_id = of_getintprop_default(espdma->dev.of_node, "scsi-initiator-id", 7); done: @@ -147,7 +147,7 @@ static void __devinit esp_get_differential(struct esp *esp) struct of_device *op = esp->dev; struct device_node *dp; - dp = op->node; + dp = op->dev.of_node; if (of_find_property(dp, "differential", NULL)) esp->flags |= ESP_FLAG_DIFFERENTIAL; else @@ -160,7 +160,7 @@ static void __devinit esp_get_clock_params(struct esp *esp) struct device_node *bus_dp, *dp; int fmhz; - dp = op->node; + dp = op->dev.of_node; bus_dp = dp->parent; fmhz = of_getintprop_default(dp, "clock-frequency", 0); @@ -172,12 +172,12 @@ static void __devinit esp_get_clock_params(struct esp *esp) static void __devinit esp_get_bursts(struct esp *esp, struct of_device *dma_of) { - struct device_node *dma_dp = dma_of->node; + struct device_node *dma_dp = dma_of->dev.of_node; struct of_device *op = esp->dev; struct device_node *dp; u8 bursts, val; - dp = op->node; + dp = op->dev.of_node; bursts = of_getintprop_default(dp, "burst-sizes", 0xff); val = of_getintprop_default(dma_dp, "burst-sizes", 0xff); if (val != 0xff) @@ -565,7 +565,7 @@ fail: static int __devinit esp_sbus_probe(struct of_device *op, const struct of_device_id *match) { struct device_node *dma_node = NULL; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct of_device *dma_of = NULL; int hme = 0; @@ -574,7 +574,7 @@ static int __devinit esp_sbus_probe(struct of_device *op, const struct of_device !strcmp(dp->parent->name, "dma"))) dma_node = dp->parent; else if (!strcmp(dp->name, "SUNW,fas")) { - dma_node = op->node; + dma_node = op->dev.of_node; hme = 1; } if (dma_node) diff --git a/drivers/serial/apbuart.c b/drivers/serial/apbuart.c index fe91319b5f65..52015d7031bb 100644 --- a/drivers/serial/apbuart.c +++ b/drivers/serial/apbuart.c @@ -559,7 +559,7 @@ static int __devinit apbuart_probe(struct of_device *op, i = 0; for (i = 0; i < grlib_apbuart_port_nr; i++) { - if (op->node == grlib_apbuart_nodes[i]) + if (op->dev.of_node == grlib_apbuart_nodes[i]) break; } diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 300cea768d74..7866cdf8a754 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -1342,7 +1342,7 @@ static int __devinit cpm_uart_probe(struct of_device *ofdev, /* initialize the device pointer for the port */ pinfo->port.dev = &ofdev->dev; - ret = cpm_uart_init_port(ofdev->node, pinfo); + ret = cpm_uart_init_port(ofdev->dev.of_node, pinfo); if (ret) return ret; diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 3119fddaedb5..cb079387c5ae 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c @@ -1328,14 +1328,14 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) /* Check validity & presence */ for (idx = 0; idx < MPC52xx_PSC_MAXNUM; idx++) - if (mpc52xx_uart_nodes[idx] == op->node) + if (mpc52xx_uart_nodes[idx] == op->dev.of_node) break; if (idx >= MPC52xx_PSC_MAXNUM) return -EINVAL; pr_debug("Found %s assigned to ttyPSC%x\n", mpc52xx_uart_nodes[idx]->full_name, idx); - uartclk = psc_ops->getuartclk(op->node); + uartclk = psc_ops->getuartclk(op->dev.of_node); if (uartclk == 0) { dev_dbg(&op->dev, "Could not find uart clock frequency!\n"); return -EINVAL; @@ -1355,7 +1355,7 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) port->dev = &op->dev; /* Search for IRQ and mapbase */ - ret = of_address_to_resource(op->node, 0, &res); + ret = of_address_to_resource(op->dev.of_node, 0, &res); if (ret) return ret; @@ -1365,7 +1365,7 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) return -EINVAL; } - psc_ops->get_irq(port, op->node); + psc_ops->get_irq(port, op->dev.of_node); if (port->irq == NO_IRQ) { dev_dbg(&op->dev, "Could not get irq\n"); return -EINVAL; diff --git a/drivers/serial/nwpserial.c b/drivers/serial/nwpserial.c index e1ab8ec0a4a6..3c02fa96f282 100644 --- a/drivers/serial/nwpserial.c +++ b/drivers/serial/nwpserial.c @@ -344,7 +344,7 @@ int nwpserial_register_port(struct uart_port *port) mutex_lock(&nwpserial_mutex); - dn = to_of_device(port->dev)->node; + dn = to_of_device(port->dev)->dev.of_node; if (dn == NULL) goto out; diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c index 4abfebdb0fcc..29539805e593 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/serial/of_serial.c @@ -31,7 +31,7 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev, int type, struct uart_port *port) { struct resource resource; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; const unsigned int *clk, *spd; const u32 *prop; int ret, prop_size; @@ -88,7 +88,7 @@ static int __devinit of_platform_serial_probe(struct of_device *ofdev, int port_type; int ret; - if (of_find_property(ofdev->node, "used-by-rtas", NULL)) + if (of_find_property(ofdev->dev.of_node, "used-by-rtas", NULL)) return -EBUSY; info = kmalloc(sizeof(*info), GFP_KERNEL); diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 4eaa043ca2a8..1e43bf59c44d 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c @@ -1609,7 +1609,7 @@ static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match) /* Iterate the pmz_ports array to find a matching entry */ for (i = 0; i < MAX_ZS_PORTS; i++) - if (pmz_ports[i].node == mdev->ofdev.node) { + if (pmz_ports[i].node == mdev->ofdev.dev.of_node) { struct uart_pmac_port *uap = &pmz_ports[i]; uap->dev = mdev; diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c index d14cca7fb88d..d1eedf13d85c 100644 --- a/drivers/serial/sunhv.c +++ b/drivers/serial/sunhv.c @@ -565,7 +565,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m if (err) goto out_free_con_read_page; - sunserial_console_match(&sunhv_console, op->node, + sunserial_console_match(&sunhv_console, op->dev.of_node, &sunhv_reg, port->line, false); err = uart_add_one_port(&sunhv_reg, port); diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index d2e0321049e2..9176c41b74ad 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c @@ -883,7 +883,7 @@ static int sunsab_console_setup(struct console *con, char *options) printk("Console: ttyS%d (SAB82532)\n", (sunsab_reg.minor - 64) + con->index); - sunserial_console_termios(con, to_of_device(up->port.dev)->node); + sunserial_console_termios(con, to_of_device(up->port.dev)->dev.of_node); switch (con->cflag & CBAUD) { case B150: baud = 150; break; @@ -1026,11 +1026,11 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id * if (err) goto out1; - sunserial_console_match(SUNSAB_CONSOLE(), op->node, + sunserial_console_match(SUNSAB_CONSOLE(), op->dev.of_node, &sunsab_reg, up[0].port.line, false); - sunserial_console_match(SUNSAB_CONSOLE(), op->node, + sunserial_console_match(SUNSAB_CONSOLE(), op->dev.of_node, &sunsab_reg, up[1].port.line, false); diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 01f7731e59b8..a647b2448071 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -1200,7 +1200,7 @@ static int __devinit sunsu_kbd_ms_init(struct uart_sunsu_port *up) return -ENODEV; printk("%s: %s port at %llx, irq %u\n", - to_of_device(up->port.dev)->node->full_name, + to_of_device(up->port.dev)->dev.of_node->full_name, (up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse", (unsigned long long) up->port.mapbase, up->port.irq); @@ -1352,7 +1352,7 @@ static int __init sunsu_console_setup(struct console *co, char *options) spin_lock_init(&port->lock); /* Get firmware console settings. */ - sunserial_console_termios(co, to_of_device(port->dev)->node); + sunserial_console_termios(co, to_of_device(port->dev)->dev.of_node); memset(&termios, 0, sizeof(struct ktermios)); termios.c_cflag = co->cflag; @@ -1409,7 +1409,7 @@ static enum su_type __devinit su_get_type(struct device_node *dp) static int __devinit su_probe(struct of_device *op, const struct of_device_id *match) { static int inst; - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct uart_sunsu_port *up; struct resource *rp; enum su_type type; diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 2c7a66af4f52..20f9be8cd949 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c @@ -1180,7 +1180,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options) (sunzilog_reg.minor - 64) + con->index, con->index); /* Get firmware console settings. */ - sunserial_console_termios(con, to_of_device(up->port.dev)->node); + sunserial_console_termios(con, to_of_device(up->port.dev)->dev.of_node); /* Firmware console speed is limited to 150-->38400 baud so * this hackish cflag thing is OK. @@ -1358,7 +1358,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m int keyboard_mouse = 0; int err; - if (of_find_property(op->node, "keyboard", NULL)) + if (of_find_property(op->dev.of_node, "keyboard", NULL)) keyboard_mouse = 1; /* uarts must come before keyboards/mice */ @@ -1415,7 +1415,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m sunzilog_init_hw(&up[1]); if (!keyboard_mouse) { - if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, + if (sunserial_console_match(SUNZILOG_CONSOLE(), op->dev.of_node, &sunzilog_reg, up[0].port.line, false)) up->flags |= SUNZILOG_FLAG_IS_CONS; @@ -1425,7 +1425,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m rp, sizeof(struct zilog_layout)); return err; } - if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, + if (sunserial_console_match(SUNZILOG_CONSOLE(), op->dev.of_node, &sunzilog_reg, up[1].port.line, false)) up->flags |= SUNZILOG_FLAG_IS_CONS; diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index f0a6c61b17f7..8fc2583d06ff 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c @@ -591,15 +591,15 @@ ulite_of_probe(struct of_device *op, const struct of_device_id *match) dev_dbg(&op->dev, "%s(%p, %p)\n", __func__, op, match); - rc = of_address_to_resource(op->node, 0, &res); + rc = of_address_to_resource(op->dev.of_node, 0, &res); if (rc) { dev_err(&op->dev, "invalid address\n"); return rc; } - irq = irq_of_parse_and_map(op->node, 0); + irq = irq_of_parse_and_map(op->dev.of_node, 0); - id = of_get_property(op->node, "port-number", NULL); + id = of_get_property(op->dev.of_node, "port-number", NULL); return ulite_assign(&op->dev, id ? *id : -1, res.start+3, irq); } diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c index 074904912f64..529890f044e2 100644 --- a/drivers/serial/ucc_uart.c +++ b/drivers/serial/ucc_uart.c @@ -1197,7 +1197,7 @@ static void uart_firmware_cont(const struct firmware *fw, void *context) static int ucc_uart_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; const unsigned int *iprop; /* Integer OF properties */ const char *sprop; /* String OF properties */ struct uart_qe_port *qe_port = NULL; diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 77d4cc88edea..7fcf28405860 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c @@ -472,18 +472,18 @@ static int __init mpc52xx_psc_spi_of_probe(struct of_device *op, s16 id = -1; int rc; - regaddr_p = of_get_address(op->node, 0, &size64, NULL); + regaddr_p = of_get_address(op->dev.of_node, 0, &size64, NULL); if (!regaddr_p) { dev_err(&op->dev, "Invalid PSC address\n"); return -EINVAL; } - regaddr64 = of_translate_address(op->node, regaddr_p); + regaddr64 = of_translate_address(op->dev.of_node, regaddr_p); /* get PSC id (1..6, used by port_config) */ if (op->dev.platform_data == NULL) { const u32 *psc_nump; - psc_nump = of_get_property(op->node, "cell-index", NULL); + psc_nump = of_get_property(op->dev.of_node, "cell-index", NULL); if (!psc_nump || *psc_nump > 5) { dev_err(&op->dev, "Invalid cell-index property\n"); return -EINVAL; @@ -492,9 +492,10 @@ static int __init mpc52xx_psc_spi_of_probe(struct of_device *op, } rc = mpc52xx_psc_spi_do_probe(&op->dev, (u32)regaddr64, (u32)size64, - irq_of_parse_and_map(op->node, 0), id); + irq_of_parse_and_map(op->dev.of_node, 0), id); if (rc == 0) - of_register_spi_devices(dev_get_drvdata(&op->dev), op->node); + of_register_spi_devices(dev_get_drvdata(&op->dev), + op->dev.of_node); return rc; } diff --git a/drivers/spi/mpc52xx_spi.c b/drivers/spi/mpc52xx_spi.c index cd68f1ce5cc3..6573233bf7c9 100644 --- a/drivers/spi/mpc52xx_spi.c +++ b/drivers/spi/mpc52xx_spi.c @@ -403,7 +403,7 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op, /* MMIO registers */ dev_dbg(&op->dev, "probing mpc5200 SPI device\n"); - regs = of_iomap(op->node, 0); + regs = of_iomap(op->dev.of_node, 0); if (!regs) return -ENODEV; @@ -445,11 +445,11 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op, ms = spi_master_get_devdata(master); ms->master = master; ms->regs = regs; - ms->irq0 = irq_of_parse_and_map(op->node, 0); - ms->irq1 = irq_of_parse_and_map(op->node, 1); + ms->irq0 = irq_of_parse_and_map(op->dev.of_node, 0); + ms->irq1 = irq_of_parse_and_map(op->dev.of_node, 1); ms->state = mpc52xx_spi_fsmstate_idle; - ms->ipb_freq = mpc5xxx_get_bus_frequency(op->node); - ms->gpio_cs_count = of_gpio_count(op->node); + ms->ipb_freq = mpc5xxx_get_bus_frequency(op->dev.of_node); + ms->gpio_cs_count = of_gpio_count(op->dev.of_node); if (ms->gpio_cs_count > 0) { master->num_chipselect = ms->gpio_cs_count; ms->gpio_cs = kmalloc(ms->gpio_cs_count * sizeof(unsigned int), @@ -460,7 +460,7 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op, } for (i = 0; i < ms->gpio_cs_count; i++) { - gpio_cs = of_get_gpio(op->node, i); + gpio_cs = of_get_gpio(op->dev.of_node, i); if (gpio_cs < 0) { dev_err(&op->dev, "could not parse the gpio field " @@ -512,7 +512,7 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op, if (rc) goto err_register; - of_register_spi_devices(master, op->node); + of_register_spi_devices(master, op->dev.of_node); dev_info(&ms->master->dev, "registered MPC5200 SPI bus\n"); return rc; diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c index 14d052316502..7572f98a419e 100644 --- a/drivers/spi/spi_mpc8xxx.c +++ b/drivers/spi/spi_mpc8xxx.c @@ -797,7 +797,7 @@ static void mpc8xxx_spi_free_dummy_rx(void) static unsigned long mpc8xxx_spi_cpm_get_pram(struct mpc8xxx_spi *mspi) { struct device *dev = mspi->dev; - struct device_node *np = dev_archdata_get_node(&dev->archdata); + struct device_node *np = dev->of_node; const u32 *iprop; int size; unsigned long spi_base_ofs; @@ -851,7 +851,7 @@ static unsigned long mpc8xxx_spi_cpm_get_pram(struct mpc8xxx_spi *mspi) static int mpc8xxx_spi_cpm_init(struct mpc8xxx_spi *mspi) { struct device *dev = mspi->dev; - struct device_node *np = dev_archdata_get_node(&dev->archdata); + struct device_node *np = dev->of_node; const u32 *iprop; int size; unsigned long pram_ofs; @@ -1123,7 +1123,7 @@ static void mpc8xxx_spi_cs_control(struct spi_device *spi, bool on) static int of_mpc8xxx_spi_get_chipselects(struct device *dev) { - struct device_node *np = dev_archdata_get_node(&dev->archdata); + struct device_node *np = dev->of_node; struct fsl_spi_platform_data *pdata = dev->platform_data; struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata); unsigned int ngpios; @@ -1224,7 +1224,7 @@ static int __devinit of_mpc8xxx_spi_probe(struct of_device *ofdev, const struct of_device_id *ofid) { struct device *dev = &ofdev->dev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct mpc8xxx_spi_probe_info *pinfo; struct fsl_spi_platform_data *pdata; struct spi_master *master; diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index 8df33b8a634c..ad0662354a5e 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c @@ -108,7 +108,7 @@ ppc44x_enable_bmt(struct device_node *dn) static int __devinit ehci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dn = op->node; + struct device_node *dn = op->dev.of_node; struct usb_hcd *hcd; struct ehci_hcd *ehci = NULL; struct resource res; diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 15379c636143..6135732d8057 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -565,7 +565,7 @@ static int __devinit of_fhci_probe(struct of_device *ofdev, const struct of_device_id *ofid) { struct device *dev = &ofdev->dev; - struct device_node *node = ofdev->node; + struct device_node *node = dev->of_node; struct usb_hcd *hcd; struct fhci_hcd *fhci; struct resource usb_regs; @@ -670,7 +670,7 @@ static int __devinit of_fhci_probe(struct of_device *ofdev, } for (j = 0; j < NUM_PINS; j++) { - fhci->pins[j] = qe_pin_request(ofdev->node, j); + fhci->pins[j] = qe_pin_request(node, j); if (IS_ERR(fhci->pins[j])) { ret = PTR_ERR(fhci->pins[j]); dev_err(dev, "can't get pin %d: %d\n", j, ret); diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 4293cfd28d61..36360e24a9b9 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -31,7 +31,7 @@ static int of_isp1760_probe(struct of_device *dev, const struct of_device_id *match) { struct usb_hcd *hcd; - struct device_node *dp = dev->node; + struct device_node *dp = dev->dev.of_node; struct resource *res; struct resource memory; struct of_irq oirq; diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index 103263c230cf..003aea21c35e 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c @@ -83,7 +83,7 @@ static const struct hc_driver ohci_ppc_of_hc_driver = { static int __devinit ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dn = op->node; + struct device_node *dn = op->dev.of_node; struct usb_hcd *hcd; struct ohci_hcd *ohci; struct resource res; diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index 6d0fcb43696e..7f59b0fe5dc2 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c @@ -740,7 +740,7 @@ static void cg6_unmap_regs(struct of_device *op, struct fb_info *info, static int __devinit cg6_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct fb_info *info; struct cg6_par *par; int linebytes, err; diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c index a42fabab69df..ddd46f71e250 100644 --- a/drivers/video/ffb.c +++ b/drivers/video/ffb.c @@ -896,7 +896,7 @@ static void ffb_init_fix(struct fb_info *info) static int __devinit ffb_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct ffb_fbc __iomem *fbc; struct ffb_dac __iomem *dac; struct fb_info *info; diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 994358a4f302..930a2522a631 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c @@ -1421,7 +1421,7 @@ static ssize_t show_monitor(struct device *device, static int __devinit fsl_diu_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct mfb_info *mfbi; phys_addr_t dummy_ad_addr; int ret, i, error = 0; diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index 8a204e7a5b5b..69d78d50f0f6 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c @@ -536,7 +536,7 @@ static int __init platinumfb_setup(char *options) static int __devinit platinumfb_probe(struct of_device* odev, const struct of_device_id *match) { - struct device_node *dp = odev->node; + struct device_node *dp = odev->dev.of_node; struct fb_info *info; struct fb_info_platinum *pinfo; volatile __u8 *fbuffer; diff --git a/drivers/video/sunxvr1000.c b/drivers/video/sunxvr1000.c index 23e69e834a18..ad92a200fafa 100644 --- a/drivers/video/sunxvr1000.c +++ b/drivers/video/sunxvr1000.c @@ -114,7 +114,7 @@ static int __devinit gfb_set_fbinfo(struct gfb_info *gp) static int __devinit gfb_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct fb_info *info; struct gfb_info *gp; int err; diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index 3fcb83f03881..6fcec553662c 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -423,7 +423,7 @@ xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match) * To check whether the core is connected directly to DCR or PLB * interface and initialize the tft_access accordingly. */ - p = (u32 *)of_get_property(op->node, "xlnx,dcr-splb-slave-if", NULL); + p = (u32 *)of_get_property(op->dev.of_node, "xlnx,dcr-splb-slave-if", NULL); tft_access = p ? *p : 0; /* @@ -432,41 +432,41 @@ xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match) */ if (tft_access) { drvdata->flags |= PLB_ACCESS_FLAG; - rc = of_address_to_resource(op->node, 0, &res); + rc = of_address_to_resource(op->dev.of_node, 0, &res); if (rc) { dev_err(&op->dev, "invalid address\n"); goto err; } } else { res.start = 0; - start = dcr_resource_start(op->node, 0); - drvdata->dcr_len = dcr_resource_len(op->node, 0); - drvdata->dcr_host = dcr_map(op->node, start, drvdata->dcr_len); + start = dcr_resource_start(op->dev.of_node, 0); + drvdata->dcr_len = dcr_resource_len(op->dev.of_node, 0); + drvdata->dcr_host = dcr_map(op->dev.of_node, start, drvdata->dcr_len); if (!DCR_MAP_OK(drvdata->dcr_host)) { dev_err(&op->dev, "invalid DCR address\n"); goto err; } } - prop = of_get_property(op->node, "phys-size", &size); + prop = of_get_property(op->dev.of_node, "phys-size", &size); if ((prop) && (size >= sizeof(u32)*2)) { pdata.screen_width_mm = prop[0]; pdata.screen_height_mm = prop[1]; } - prop = of_get_property(op->node, "resolution", &size); + prop = of_get_property(op->dev.of_node, "resolution", &size); if ((prop) && (size >= sizeof(u32)*2)) { pdata.xres = prop[0]; pdata.yres = prop[1]; } - prop = of_get_property(op->node, "virtual-resolution", &size); + prop = of_get_property(op->dev.of_node, "virtual-resolution", &size); if ((prop) && (size >= sizeof(u32)*2)) { pdata.xvirt = prop[0]; pdata.yvirt = prop[1]; } - if (of_find_property(op->node, "rotate-display", NULL)) + if (of_find_property(op->dev.of_node, "rotate-display", NULL)) pdata.rotate_screen = 1; dev_set_drvdata(&op->dev, drvdata); diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index ba2efce4b40e..2fcc3cf7ef62 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c @@ -577,7 +577,7 @@ static int __devinit cpwd_probe(struct of_device *op, * interrupt_mask register cannot be written, so no timer * interrupts can be masked within the PLD. */ - str_prop = of_get_property(op->node, "model", NULL); + str_prop = of_get_property(op->dev.of_node, "model", NULL); p->broken = (str_prop && !strcmp(str_prop, WD_BADMODEL)); if (!p->enabled) diff --git a/sound/aoa/fabrics/layout.c b/sound/aoa/fabrics/layout.c index 1cd9b301df03..3fd1a7e24928 100644 --- a/sound/aoa/fabrics/layout.c +++ b/sound/aoa/fabrics/layout.c @@ -992,7 +992,7 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev) return -ENODEV; /* by breaking out we keep a reference */ - while ((sound = of_get_next_child(sdev->ofdev.node, sound))) { + while ((sound = of_get_next_child(sdev->ofdev.dev.of_node, sound))) { if (sound->type && strcasecmp(sound->type, "soundchip") == 0) break; } diff --git a/sound/aoa/soundbus/core.c b/sound/aoa/soundbus/core.c index fa8ab2815a98..99ca7120e269 100644 --- a/sound/aoa/soundbus/core.c +++ b/sound/aoa/soundbus/core.c @@ -74,11 +74,11 @@ static int soundbus_uevent(struct device *dev, struct kobj_uevent_env *env) of = &soundbus_dev->ofdev; /* stuff we want to pass to /sbin/hotplug */ - retval = add_uevent_var(env, "OF_NAME=%s", of->node->name); + retval = add_uevent_var(env, "OF_NAME=%s", of->dev.of_node->name); if (retval) return retval; - retval = add_uevent_var(env, "OF_TYPE=%s", of->node->type); + retval = add_uevent_var(env, "OF_TYPE=%s", of->dev.of_node->type); if (retval) return retval; @@ -86,7 +86,7 @@ static int soundbus_uevent(struct device *dev, struct kobj_uevent_env *env) * it's not really legal to split it out with commas. We split it * up using a number of environment variables instead. */ - compat = of_get_property(of->node, "compatible", &cplen); + compat = of_get_property(of->dev.of_node, "compatible", &cplen); while (compat && cplen > 0) { int tmp = env->buflen; retval = add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat); @@ -169,7 +169,7 @@ int soundbus_add_one(struct soundbus_dev *dev) /* sanity checks */ if (!dev->attach_codec || - !dev->ofdev.node || + !dev->ofdev.dev.of_node || dev->pcmname || dev->pcmid != -1) { printk(KERN_ERR "soundbus: adding device failed sanity check!\n"); diff --git a/sound/aoa/soundbus/i2sbus/control.c b/sound/aoa/soundbus/i2sbus/control.c index 47f854c2001f..4dc9b49c02cf 100644 --- a/sound/aoa/soundbus/i2sbus/control.c +++ b/sound/aoa/soundbus/i2sbus/control.c @@ -42,7 +42,7 @@ int i2sbus_control_add_dev(struct i2sbus_control *c, { struct device_node *np; - np = i2sdev->sound.ofdev.node; + np = i2sdev->sound.ofdev.dev.of_node; i2sdev->enable = pmf_find_function(np, "enable"); i2sdev->cell_enable = pmf_find_function(np, "cell-enable"); i2sdev->clock_enable = pmf_find_function(np, "clock-enable"); diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c index 9d6f3b176ed1..7672b4d145ae 100644 --- a/sound/aoa/soundbus/i2sbus/core.c +++ b/sound/aoa/soundbus/i2sbus/core.c @@ -221,8 +221,8 @@ static int i2sbus_add_dev(struct macio_dev *macio, mutex_init(&dev->lock); spin_lock_init(&dev->low_lock); - dev->sound.ofdev.node = np; dev->sound.ofdev.dma_mask = macio->ofdev.dma_mask; + dev->sound.ofdev.dev.of_node = np; dev->sound.ofdev.dev.dma_mask = &dev->sound.ofdev.dma_mask; dev->sound.ofdev.dev.parent = &macio->ofdev.dev; dev->sound.ofdev.dev.release = i2sbus_release_dev; @@ -346,7 +346,7 @@ static int i2sbus_probe(struct macio_dev* dev, const struct of_device_id *match) return -ENODEV; } - while ((np = of_get_next_child(dev->ofdev.node, np))) { + while ((np = of_get_next_child(dev->ofdev.dev.of_node, np))) { if (of_device_is_compatible(np, "i2sbus") || of_device_is_compatible(np, "i2s-modem")) { got += i2sbus_add_dev(dev, control, np); diff --git a/sound/aoa/soundbus/sysfs.c b/sound/aoa/soundbus/sysfs.c index f580942b5c09..6496e754f00a 100644 --- a/sound/aoa/soundbus/sysfs.c +++ b/sound/aoa/soundbus/sysfs.c @@ -9,7 +9,7 @@ field##_show (struct device *dev, struct device_attribute *attr, \ char *buf) \ { \ struct soundbus_dev *mdev = to_soundbus_device (dev); \ - return sprintf (buf, format_string, mdev->ofdev.node->field); \ + return sprintf (buf, format_string, mdev->ofdev.dev.of_node->field); \ } static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, @@ -25,7 +25,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, length = strlen(buf); } else { length = sprintf(buf, "of:N%sT%s\n", - of->node->name, of->node->type); + of->dev.of_node->name, of->dev.of_node->type); } return length; diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c index d639e55c5124..1d4e7164e80a 100644 --- a/sound/soc/fsl/mpc5200_dma.c +++ b/sound/soc/fsl/mpc5200_dma.c @@ -380,8 +380,8 @@ int mpc5200_audio_dma_create(struct of_device *op) int ret; /* Fetch the registers and IRQ of the PSC */ - irq = irq_of_parse_and_map(op->node, 0); - if (of_address_to_resource(op->node, 0, &res)) { + irq = irq_of_parse_and_map(op->dev.of_node, 0); + if (of_address_to_resource(op->dev.of_node, 0, &res)) { dev_err(&op->dev, "Missing reg property\n"); return -ENODEV; } @@ -399,7 +399,7 @@ int mpc5200_audio_dma_create(struct of_device *op) } /* Get the PSC ID */ - prop = of_get_property(op->node, "cell-index", &size); + prop = of_get_property(op->dev.of_node, "cell-index", &size); if (!prop || size < sizeof *prop) { ret = -ENODEV; goto out_free; diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c index ce8de90fb94a..748cc0f0df38 100644 --- a/sound/soc/fsl/mpc5200_psc_i2s.c +++ b/sound/soc/fsl/mpc5200_psc_i2s.c @@ -181,7 +181,7 @@ static int __devinit psc_i2s_of_probe(struct of_device *op, /* Check for the codec handle. If it is not present then we * are done */ - if (!of_get_property(op->node, "codec-handle", NULL)) + if (!of_get_property(op->dev.of_node, "codec-handle", NULL)) return 0; /* Due to errata in the dma mode; need to line up enabling diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index 83de1c81c8c4..e3f78f255a60 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c @@ -203,7 +203,7 @@ static struct snd_soc_ops mpc8610_hpcd_ops = { static int mpc8610_hpcd_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct device_node *codec_np = NULL; struct device_node *guts_np = NULL; struct device_node *dma_np = NULL; diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 7dcc06512e86..6a4c872e00df 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -2075,12 +2075,12 @@ static int __devinit cs4231_ebus_probe(struct of_device *op, const struct of_dev static int __devinit cs4231_probe(struct of_device *op, const struct of_device_id *match) { #ifdef EBUS_SUPPORT - if (!strcmp(op->node->parent->name, "ebus")) + if (!strcmp(op->dev.of_node->parent->name, "ebus")) return cs4231_ebus_probe(op, match); #endif #ifdef SBUS_SUPPORT - if (!strcmp(op->node->parent->name, "sbus") || - !strcmp(op->node->parent->name, "sbi")) + if (!strcmp(op->dev.of_node->parent->name, "sbus") || + !strcmp(op->dev.of_node->parent->name, "sbi")) return cs4231_sbus_probe(op, match); #endif return -ENODEV; diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index 2eab6ce48852..1b5192eb5ae5 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c @@ -2651,7 +2651,7 @@ static int __devinit dbri_probe(struct of_device *op, const struct of_device_id printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n", dev, dbri->regs, - dbri->irq, op->node->name[9], dbri->mm.version); + dbri->irq, op->dev.of_node->name[9], dbri->mm.version); dev++; return 0; -- cgit v1.2.3 From 58f9b0b02414062eaff46716bc04b47d7e79add5 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:12:56 -0700 Subject: of: eliminate of_device->node and dev_archdata->{of,prom}_node This patch eliminates the node pointer from struct of_device and the of_node (or prom_node) pointer from struct dev_archdata since the node pointer is now part of struct device proper when CONFIG_OF is set, and all users of the old pointer locations have already been converted over to use device->of_node. Also remove dev_archdata_{get,set}_node() as it is no longer used by anything. Signed-off-by: Grant Likely --- arch/microblaze/include/asm/device.h | 15 --------------- arch/microblaze/include/asm/of_device.h | 1 - arch/microblaze/kernel/of_device.c | 4 +--- arch/powerpc/include/asm/device.h | 15 --------------- arch/powerpc/include/asm/of_device.h | 1 - arch/powerpc/kernel/of_device.c | 4 +--- arch/powerpc/kernel/pci-common.c | 1 - arch/powerpc/kernel/vio.c | 17 ++++++++--------- arch/powerpc/platforms/cell/iommu.c | 5 ++--- arch/powerpc/platforms/pasemi/setup.c | 4 ++-- arch/powerpc/platforms/ps3/system-bus.c | 1 - arch/powerpc/platforms/pseries/iommu.c | 2 +- arch/sparc/include/asm/device.h | 15 --------------- arch/sparc/include/asm/of_device.h | 1 - arch/sparc/kernel/of_device_32.c | 2 -- arch/sparc/kernel/of_device_64.c | 2 -- arch/sparc/kernel/pci.c | 3 +-- drivers/of/of_i2c.c | 1 - drivers/of/of_mdio.c | 1 - drivers/of/of_spi.c | 1 - 20 files changed, 16 insertions(+), 80 deletions(-) (limited to 'drivers') diff --git a/arch/microblaze/include/asm/device.h b/arch/microblaze/include/asm/device.h index 402b46e630f6..15b0058aa7ff 100644 --- a/arch/microblaze/include/asm/device.h +++ b/arch/microblaze/include/asm/device.h @@ -12,9 +12,6 @@ struct device_node; struct dev_archdata { - /* Optional pointer to an OF device node */ - struct device_node *of_node; - /* DMA operations on that device */ struct dma_map_ops *dma_ops; void *dma_data; @@ -23,18 +20,6 @@ struct dev_archdata { struct pdev_archdata { }; -static inline void dev_archdata_set_node(struct dev_archdata *ad, - struct device_node *np) -{ - ad->of_node = np; -} - -static inline struct device_node * -dev_archdata_get_node(const struct dev_archdata *ad) -{ - return ad->of_node; -} - #endif /* _ASM_MICROBLAZE_DEVICE_H */ diff --git a/arch/microblaze/include/asm/of_device.h b/arch/microblaze/include/asm/of_device.h index ba917cfaefe6..ab25a40b481c 100644 --- a/arch/microblaze/include/asm/of_device.h +++ b/arch/microblaze/include/asm/of_device.h @@ -21,7 +21,6 @@ * probed using OF properties. */ struct of_device { - struct device_node *node; /* to be obsoleted */ u64 dma_mask; /* DMA mask */ struct device dev; /* Generic device interface */ }; diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c index 90d2246e15c0..ac7e6e10d0ab 100644 --- a/arch/microblaze/kernel/of_device.c +++ b/arch/microblaze/kernel/of_device.c @@ -49,12 +49,10 @@ struct of_device *of_device_alloc(struct device_node *np, if (!dev) return NULL; - dev->node = of_node_get(np); + dev->dev.of_node = of_node_get(np); dev->dev.dma_mask = &dev->dma_mask; dev->dev.parent = parent; dev->dev.release = of_release_dev; - dev->dev.archdata.of_node = np; - dev->dev.of_node = np; if (bus_id) dev_set_name(&dev->dev, bus_id); diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h index 6d94d27ed850..f23f8d8bd68d 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h @@ -10,9 +10,6 @@ struct dma_map_ops; struct device_node; struct dev_archdata { - /* Optional pointer to an OF device node */ - struct device_node *of_node; - /* DMA operations on that device */ struct dma_map_ops *dma_ops; @@ -30,18 +27,6 @@ struct dev_archdata { #endif }; -static inline void dev_archdata_set_node(struct dev_archdata *ad, - struct device_node *np) -{ - ad->of_node = np; -} - -static inline struct device_node * -dev_archdata_get_node(const struct dev_archdata *ad) -{ - return ad->of_node; -} - struct pdev_archdata { }; diff --git a/arch/powerpc/include/asm/of_device.h b/arch/powerpc/include/asm/of_device.h index a64debf177dc..8b26f96b9f9e 100644 --- a/arch/powerpc/include/asm/of_device.h +++ b/arch/powerpc/include/asm/of_device.h @@ -12,7 +12,6 @@ */ struct of_device { - struct device_node *node; /* to be obsoleted */ u64 dma_mask; /* DMA mask */ struct device dev; /* Generic device interface */ }; diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index 285c8490c547..20b3474b6f6b 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c @@ -69,12 +69,10 @@ struct of_device *of_device_alloc(struct device_node *np, if (!dev) return NULL; - dev->node = of_node_get(np); + dev->dev.of_node = of_node_get(np); dev->dev.dma_mask = &dev->dma_mask; dev->dev.parent = parent; dev->dev.release = of_release_dev; - dev->dev.archdata.of_node = np; - dev->dev.of_node = np; if (bus_id) dev_set_name(&dev->dev, "%s", bus_id); diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 88da282047c3..6646005dffb1 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1098,7 +1098,6 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) continue; /* Setup OF node pointer in the device */ - sd->of_node = pci_device_to_OF_node(dev); dev->dev.of_node = pci_device_to_OF_node(dev); /* Fixup NUMA node as it may not be setup yet by the generic diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index d6708da114ee..4cdd0f6df8bf 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -705,7 +705,7 @@ static int vio_cmo_bus_probe(struct vio_dev *viodev) * Check to see that device has a DMA window and configure * entitlement for the device. */ - if (of_get_property(viodev->dev.archdata.of_node, + if (of_get_property(viodev->dev.of_node, "ibm,my-dma-window", NULL)) { /* Check that the driver is CMO enabled and get desired DMA */ if (!viodrv->get_desired_dma) { @@ -1049,7 +1049,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) if (firmware_has_feature(FW_FEATURE_ISERIES)) return vio_build_iommu_table_iseries(dev); - dma_window = of_get_property(dev->dev.archdata.of_node, + dma_window = of_get_property(dev->dev.of_node, "ibm,my-dma-window", NULL); if (!dma_window) return NULL; @@ -1058,7 +1058,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) if (tbl == NULL) return NULL; - of_parse_dma_window(dev->dev.archdata.of_node, dma_window, + of_parse_dma_window(dev->dev.of_node, dma_window, &tbl->it_index, &offset, &size); /* TCE table size - measured in tce entries */ @@ -1086,7 +1086,7 @@ static const struct vio_device_id *vio_match_device( { while (ids->type[0] != '\0') { if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) && - of_device_is_compatible(dev->dev.archdata.of_node, + of_device_is_compatible(dev->dev.of_node, ids->compat)) return ids; ids++; @@ -1179,7 +1179,7 @@ EXPORT_SYMBOL(vio_unregister_driver); static void __devinit vio_dev_release(struct device *dev) { /* XXX should free TCE table */ - of_node_put(dev->archdata.of_node); + of_node_put(dev->of_node); kfree(to_vio_dev(dev)); } @@ -1231,7 +1231,6 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) viodev->unit_address = *unit_address; } viodev->dev.of_node = of_node_get(of_node); - viodev->dev.archdata.of_node = viodev->dev.of_node; if (firmware_has_feature(FW_FEATURE_CMO)) vio_cmo_set_dma_ops(viodev); @@ -1316,7 +1315,7 @@ static ssize_t name_show(struct device *dev, static ssize_t devspec_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct device_node *of_node = dev->archdata.of_node; + struct device_node *of_node = dev->of_node; return sprintf(buf, "%s\n", of_node ? of_node->full_name : "none"); } @@ -1348,7 +1347,7 @@ static int vio_hotplug(struct device *dev, struct kobj_uevent_env *env) struct device_node *dn; const char *cp; - dn = dev->archdata.of_node; + dn = dev->of_node; if (!dn) return -ENODEV; cp = of_get_property(dn, "compatible", NULL); @@ -1379,7 +1378,7 @@ static struct bus_type vio_bus_type = { */ const void *vio_get_attribute(struct vio_dev *vdev, char *which, int *length) { - return of_get_property(vdev->dev.archdata.of_node, which, length); + return of_get_property(vdev->dev.of_node, which, length); } EXPORT_SYMBOL(vio_get_attribute); diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index e3ec4976fae7..22667a09d40e 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -545,7 +545,6 @@ static struct iommu_table *cell_get_iommu_table(struct device *dev) { struct iommu_window *window; struct cbe_iommu *iommu; - struct dev_archdata *archdata = &dev->archdata; /* Current implementation uses the first window available in that * node's iommu. We -might- do something smarter later though it may @@ -554,7 +553,7 @@ static struct iommu_table *cell_get_iommu_table(struct device *dev) iommu = cell_iommu_for_node(dev_to_node(dev)); if (iommu == NULL || list_empty(&iommu->windows)) { printk(KERN_ERR "iommu: missing iommu for %s (node %d)\n", - archdata->of_node ? archdata->of_node->full_name : "?", + dev->of_node ? dev->of_node->full_name : "?", dev_to_node(dev)); return NULL; } @@ -897,7 +896,7 @@ static u64 cell_iommu_get_fixed_address(struct device *dev) const u32 *ranges = NULL; int i, len, best, naddr, nsize, pna, range_size; - np = of_node_get(dev->archdata.of_node); + np = of_node_get(dev->of_node); while (1) { naddr = of_n_addr_cells(np); nsize = of_n_size_cells(np); diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c index ac6fdd973291..f372ec1691a3 100644 --- a/arch/powerpc/platforms/pasemi/setup.c +++ b/arch/powerpc/platforms/pasemi/setup.c @@ -360,10 +360,10 @@ static int pcmcia_notify(struct notifier_block *nb, unsigned long action, /* We know electra_cf devices will always have of_node set, since * electra_cf is an of_platform driver. */ - if (!parent->archdata.of_node) + if (!parent->of_node) return 0; - if (!of_device_is_compatible(parent->archdata.of_node, "electra-cf")) + if (!of_device_is_compatible(parent->of_node, "electra-cf")) return 0; /* We use the direct ops for localbus */ diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index e546c86a539b..23083c397528 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c @@ -767,7 +767,6 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev) }; dev->core.of_node = NULL; - dev->core.archdata.of_node = NULL; set_dev_node(&dev->core, 0); pr_debug("%s:%d add %s\n", __func__, __LINE__, dev_name(&dev->core)); diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 1a0000a4b6d6..d26182d42cbf 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -468,7 +468,7 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev) pr_debug("pci_dma_dev_setup_pSeries: %s\n", pci_name(dev)); - dn = dev->dev.archdata.of_node; + dn = dev->dev.of_node; /* If we're the direct child of a root bus, then we need to allocate * an iommu table ourselves. The bus setup code should have setup diff --git a/arch/sparc/include/asm/device.h b/arch/sparc/include/asm/device.h index f3b85b6b0b76..d4c452147412 100644 --- a/arch/sparc/include/asm/device.h +++ b/arch/sparc/include/asm/device.h @@ -13,25 +13,10 @@ struct dev_archdata { void *iommu; void *stc; void *host_controller; - - struct device_node *prom_node; struct of_device *op; - int numa_node; }; -static inline void dev_archdata_set_node(struct dev_archdata *ad, - struct device_node *np) -{ - ad->prom_node = np; -} - -static inline struct device_node * -dev_archdata_get_node(const struct dev_archdata *ad) -{ - return ad->prom_node; -} - struct pdev_archdata { }; diff --git a/arch/sparc/include/asm/of_device.h b/arch/sparc/include/asm/of_device.h index a5d9811f9697..f320246a0586 100644 --- a/arch/sparc/include/asm/of_device.h +++ b/arch/sparc/include/asm/of_device.h @@ -14,7 +14,6 @@ */ struct of_device { - struct device_node *node; struct device dev; struct resource resource[PROMREG_MAX]; unsigned int irqs[PROMINTR_MAX]; diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index 707311716142..47e63f1e719c 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c @@ -345,11 +345,9 @@ static struct of_device * __init scan_one_device(struct device_node *dp, return NULL; sd = &op->dev.archdata; - sd->prom_node = dp; sd->op = op; op->dev.of_node = dp; - op->node = dp; op->clock_freq = of_getintprop_default(dp, "clock-frequency", (25*1000*1000)); diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index c8e352e0a098..1dae8079f728 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -640,11 +640,9 @@ static struct of_device * __init scan_one_device(struct device_node *dp, return NULL; sd = &op->dev.archdata; - sd->prom_node = dp; sd->op = op; op->dev.of_node = dp; - op->node = dp; op->clock_freq = of_getintprop_default(dp, "clock-frequency", (25*1000*1000)); diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index c7a214ec5aff..8a8363adb8bd 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -261,8 +261,6 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, sd->iommu = pbm->iommu; sd->stc = &pbm->stc; sd->host_controller = pbm; - sd->prom_node = node; - dev->dev.of_node = node; sd->op = op = of_find_device_by_node(node); sd->numa_node = pbm->numa_node; @@ -286,6 +284,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, dev->sysdata = node; dev->dev.parent = bus->bridge; dev->dev.bus = &pci_bus_type; + dev->dev.of_node = node; dev->devfn = devfn; dev->multifunction = 0; /* maybe a lie? */ set_pcie_port_type(dev); diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index 604ba966e1c9..ab6522c8e4fe 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c @@ -42,7 +42,6 @@ void of_register_i2c_devices(struct i2c_adapter *adap, info.addr = be32_to_cpup(addr); - dev_archdata_set_node(&dev_ad, node); info.of_node = node; info.archdata = &dev_ad; diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 01d794abe105..794fbc2ef73d 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -79,7 +79,6 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) /* Associate the OF node with the device structure so it * can be looked up later */ of_node_get(child); - dev_archdata_set_node(&phy->dev.archdata, child); phy->dev.of_node = child; /* All data is now stored in the phy struct; register it */ diff --git a/drivers/of/of_spi.c b/drivers/of/of_spi.c index f3119a0836af..5fed7e3c7da3 100644 --- a/drivers/of/of_spi.c +++ b/drivers/of/of_spi.c @@ -80,7 +80,6 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np) /* Store a pointer to the node in the device structure */ of_node_get(nc); spi->dev.of_node = nc; - spi->dev.archdata.of_node = nc; /* Register the new device */ request_module(spi->modalias); -- cgit v1.2.3 From 5c40cbfefa828208c671e2f58789e4dd04f79563 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 27 Apr 2010 09:07:00 +0200 Subject: firewire: core: use separate timeout for each transaction Using a single timeout for all transaction that need to be flushed does not work if the submission of new transactions can defer the timeout indefinitely into the future. We need to have timeouts that do not change due to other transactions; the simplest way to do this is with a separate timer for each transaction. Signed-off-by: Clemens Ladisch Signed-off-by: Stefan Richter (+ one lockdep annotation) --- drivers/firewire/core-card.c | 11 ------ drivers/firewire/core-transaction.c | 70 ++++++++++++++++++++----------------- drivers/firewire/core.h | 1 - include/linux/firewire.h | 3 +- 4 files changed, 39 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index 42cf911b73cf..9dcb30466ec0 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -408,13 +407,6 @@ static void fw_card_bm_work(struct work_struct *work) fw_card_put(card); } -static void flush_timer_callback(unsigned long data) -{ - struct fw_card *card = (struct fw_card *)data; - - fw_flush_transactions(card); -} - void fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver, struct device *device) @@ -433,8 +425,6 @@ void fw_card_initialize(struct fw_card *card, init_completion(&card->done); INIT_LIST_HEAD(&card->transaction_list); spin_lock_init(&card->lock); - setup_timer(&card->flush_timer, - flush_timer_callback, (unsigned long)card); card->local_node = NULL; @@ -559,7 +549,6 @@ void fw_core_remove_card(struct fw_card *card) wait_for_completion(&card->done); WARN_ON(!list_empty(&card->transaction_list)); - del_timer_sync(&card->flush_timer); } EXPORT_SYMBOL(fw_core_remove_card); diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index 901669876c25..fdc33ff06dc1 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c @@ -81,7 +81,7 @@ static int close_transaction(struct fw_transaction *transaction, spin_lock_irqsave(&card->lock, flags); list_for_each_entry(t, &card->transaction_list, link) { if (t == transaction) { - list_del(&t->link); + list_del_init(&t->link); card->tlabel_mask &= ~(1ULL << t->tlabel); break; } @@ -89,6 +89,7 @@ static int close_transaction(struct fw_transaction *transaction, spin_unlock_irqrestore(&card->lock, flags); if (&t->link != &card->transaction_list) { + del_timer_sync(&t->split_timeout_timer); t->callback(card, rcode, NULL, 0, t->callback_data); return 0; } @@ -121,6 +122,31 @@ int fw_cancel_transaction(struct fw_card *card, } EXPORT_SYMBOL(fw_cancel_transaction); +static void split_transaction_timeout_callback(unsigned long data) +{ + struct fw_transaction *t = (struct fw_transaction *)data; + struct fw_card *card = t->card; + unsigned long flags; + + spin_lock_irqsave(&card->lock, flags); + if (list_empty(&t->link)) { + spin_unlock_irqrestore(&card->lock, flags); + return; + } + list_del(&t->link); + card->tlabel_mask &= ~(1ULL << t->tlabel); + spin_unlock_irqrestore(&card->lock, flags); + + card->driver->cancel_packet(card, &t->packet); + + /* + * At this point cancel_packet will never call the transaction + * callback, since we just took the transaction out of the list. + * So do it here. + */ + t->callback(card, RCODE_CANCELLED, NULL, 0, t->callback_data); +} + static void transmit_complete_callback(struct fw_packet *packet, struct fw_card *card, int status) { @@ -293,13 +319,6 @@ void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode, unsigned long flags; int tlabel; - /* - * Bump the flush timer up 100ms first of all so we - * don't race with a flush timer callback. - */ - - mod_timer(&card->flush_timer, jiffies + DIV_ROUND_UP(HZ, 10)); - /* * Allocate tlabel from the bitmap and put the transaction on * the list while holding the card spinlock. @@ -316,6 +335,11 @@ void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode, t->node_id = destination_id; t->tlabel = tlabel; + t->card = card; + setup_timer(&t->split_timeout_timer, + split_transaction_timeout_callback, (unsigned long)t); + /* FIXME: start this timer later, relative to t->timestamp */ + mod_timer(&t->split_timeout_timer, jiffies + DIV_ROUND_UP(HZ, 10)); t->callback = callback; t->callback_data = callback_data; @@ -361,11 +385,13 @@ int fw_run_transaction(struct fw_card *card, int tcode, int destination_id, struct transaction_callback_data d; struct fw_transaction t; + init_timer_on_stack(&t.split_timeout_timer); init_completion(&d.done); d.payload = payload; fw_send_request(card, &t, tcode, destination_id, generation, speed, offset, payload, length, transaction_callback, &d); wait_for_completion(&d.done); + destroy_timer_on_stack(&t.split_timeout_timer); return d.rcode; } @@ -408,30 +434,6 @@ void fw_send_phy_config(struct fw_card *card, mutex_unlock(&phy_config_mutex); } -void fw_flush_transactions(struct fw_card *card) -{ - struct fw_transaction *t, *next; - struct list_head list; - unsigned long flags; - - INIT_LIST_HEAD(&list); - spin_lock_irqsave(&card->lock, flags); - list_splice_init(&card->transaction_list, &list); - card->tlabel_mask = 0; - spin_unlock_irqrestore(&card->lock, flags); - - list_for_each_entry_safe(t, next, &list, link) { - card->driver->cancel_packet(card, &t->packet); - - /* - * At this point cancel_packet will never call the - * transaction callback, since we just took all the - * transactions out of the list. So do it here. - */ - t->callback(card, RCODE_CANCELLED, NULL, 0, t->callback_data); - } -} - static struct fw_address_handler *lookup_overlapping_address_handler( struct list_head *list, unsigned long long offset, size_t length) { @@ -841,7 +843,7 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) spin_lock_irqsave(&card->lock, flags); list_for_each_entry(t, &card->transaction_list, link) { if (t->node_id == source && t->tlabel == tlabel) { - list_del(&t->link); + list_del_init(&t->link); card->tlabel_mask &= ~(1ULL << t->tlabel); break; } @@ -883,6 +885,8 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) break; } + del_timer_sync(&t->split_timeout_timer); + /* * The response handler may be executed while the request handler * is still pending. Cancel the request handler. diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index 7a9759bf6837..0ecfcd95f4c5 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h @@ -220,7 +220,6 @@ void fw_core_handle_request(struct fw_card *card, struct fw_packet *request); void fw_core_handle_response(struct fw_card *card, struct fw_packet *packet); void fw_fill_response(struct fw_packet *response, u32 *request_header, int rcode, void *payload, size_t length); -void fw_flush_transactions(struct fw_card *card); void fw_send_phy_config(struct fw_card *card, int node_id, int generation, int gap_count); diff --git a/include/linux/firewire.h b/include/linux/firewire.h index a527d73f9966..72e2b8ac2a5a 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -87,7 +87,6 @@ struct fw_card { int current_tlabel; u64 tlabel_mask; struct list_head transaction_list; - struct timer_list flush_timer; unsigned long reset_jiffies; unsigned long long guid; @@ -288,6 +287,8 @@ struct fw_transaction { int tlabel; int timestamp; struct list_head link; + struct fw_card *card; + struct timer_list split_timeout_timer; struct fw_packet packet; -- cgit v1.2.3 From bd9e19ca46b54fa85141c4d20afd668379d94c81 Mon Sep 17 00:00:00 2001 From: Vernon Mauery Date: Tue, 18 May 2010 19:02:50 -0300 Subject: Add support for Westmere to i7core_edac driver This adds new PCI IDs for the Westmere's memory controller devices and modifies the i7core_edac driver to be able to probe both Nehalem and Westmere processors. Signed-off-by: Vernon Mauery Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 117 +++++++++++++++++++++++++++++++-------------- include/linux/pci_ids.h | 16 +++++++ 2 files changed, 96 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 3e2b5379bc05..8d63b0046480 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -206,6 +206,11 @@ struct pci_id_descr { int optional; }; +struct pci_id_table { + struct pci_id_descr *descr; + int n_devs; +}; + struct i7core_dev { struct list_head list; u8 socket; @@ -262,7 +267,7 @@ static DEFINE_MUTEX(i7core_edac_lock); .func = (function), \ .dev_id = (device_id) -struct pci_id_descr pci_dev_descr_i7core[] = { +struct pci_id_descr pci_dev_descr_i7core_nehalem[] = { /* Memory controller */ { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) }, { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) }, @@ -321,6 +326,44 @@ struct pci_id_descr pci_dev_descr_lynnfield[] = { { PCI_DESCR( 0, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE) }, }; +struct pci_id_descr pci_dev_descr_i7core_westmere[] = { + /* Memory controller */ + { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MCR_REV2) }, + { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TAD_REV2) }, + /* Exists only for RDIMM */ + { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_RAS_REV2), .optional = 1 }, + { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TEST_REV2) }, + + /* Channel 0 */ + { PCI_DESCR(4, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_CTRL_REV2) }, + { PCI_DESCR(4, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_ADDR_REV2) }, + { PCI_DESCR(4, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_RANK_REV2) }, + { PCI_DESCR(4, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_TC_REV2) }, + + /* Channel 1 */ + { PCI_DESCR(5, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_CTRL_REV2) }, + { PCI_DESCR(5, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR_REV2) }, + { PCI_DESCR(5, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK_REV2) }, + { PCI_DESCR(5, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC_REV2) }, + + /* Channel 2 */ + { PCI_DESCR(6, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_CTRL_REV2) }, + { PCI_DESCR(6, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_ADDR_REV2) }, + { PCI_DESCR(6, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_RANK_REV2) }, + { PCI_DESCR(6, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_TC_REV2) }, + + /* Generic Non-core registers */ + { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_REV2) }, + +}; + +#define PCI_ID_TABLE_ENTRY(A) { A, ARRAY_SIZE(A) } +struct pci_id_table pci_dev_table[] = { + PCI_ID_TABLE_ENTRY(pci_dev_descr_i7core_nehalem), + PCI_ID_TABLE_ENTRY(pci_dev_descr_lynnfield), + PCI_ID_TABLE_ENTRY(pci_dev_descr_i7core_westmere), +}; + /* * pci_device_id table for which devices we are looking for */ @@ -1170,7 +1213,7 @@ static void i7core_put_all_devices(void) i7core_put_devices(i7core_dev); } -static void __init i7core_xeon_pci_fixup(int dev_id) +static void __init i7core_xeon_pci_fixup(struct pci_id_table *table) { struct pci_dev *pdev = NULL; int i; @@ -1179,10 +1222,13 @@ static void __init i7core_xeon_pci_fixup(int dev_id) * aren't announced by acpi. So, we need to use a legacy scan probing * to detect them */ - pdev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, NULL); - if (unlikely(!pdev)) { - for (i = 0; i < MAX_SOCKET_BUSES; i++) - pcibios_scan_specific_bus(255-i); + while (table && table->descr) { + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, table->descr[0].dev_id, NULL); + if (unlikely(!pdev)) { + for (i = 0; i < MAX_SOCKET_BUSES; i++) + pcibios_scan_specific_bus(255-i); + } + table++; } } @@ -1213,15 +1259,10 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno, pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT, *prev); - if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && !pdev) { + if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && !pdev) pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT, *prev); - if (!pdev) - pdev = pci_get_device(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_REV2, - *prev); - } if (!pdev) { if (*prev) { @@ -1232,6 +1273,9 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno, if (dev_descr->optional) return 0; + if (devno == 0) + return -ENODEV; + i7core_printk(KERN_ERR, "Device not found: dev %02x.%d PCI ID %04x:%04x\n", dev_descr->dev, dev_descr->func, @@ -1307,24 +1351,34 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno, return 0; } -static int i7core_get_devices(struct pci_id_descr dev_descr[], unsigned n_devs) +static int i7core_get_devices(struct pci_id_table *table) { int i, rc; struct pci_dev *pdev = NULL; - - for (i = 0; i < n_devs; i++) { - pdev = NULL; - do { - rc = i7core_get_onedevice(&pdev, i, &dev_descr[i], - n_devs); - if (rc < 0) { - i7core_put_all_devices(); - return -ENODEV; - } - } while (pdev); + struct pci_id_descr *dev_descr; + + while (table && table->descr) { + dev_descr = table->descr; + for (i = 0; i < table->n_devs; i++) { + pdev = NULL; + do { + rc = i7core_get_onedevice(&pdev, i, &dev_descr[i], + table->n_devs); + if (rc < 0) { + if (i == 0) { + i = table->n_devs; + break; + } + i7core_put_all_devices(); + return -ENODEV; + } + } while (pdev); + } + table++; } return 0; + return 0; } static int mci_bind_devs(struct mem_ctl_info *mci, @@ -1884,18 +1938,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, /* get the pci devices we want to reserve for our use */ mutex_lock(&i7core_edac_lock); - if (pdev->device == PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_LINK0) { - printk(KERN_INFO "i7core_edac: detected a " - "Lynnfield processor\n"); - rc = i7core_get_devices(pci_dev_descr_lynnfield, - ARRAY_SIZE(pci_dev_descr_lynnfield)); - } else { - printk(KERN_INFO "i7core_edac: detected a " - "Nehalem/Nehalem-EP processor\n"); - rc = i7core_get_devices(pci_dev_descr_i7core, - ARRAY_SIZE(pci_dev_descr_i7core)); - } - + rc = i7core_get_devices(pci_dev_table); if (unlikely(rc < 0)) goto fail0; @@ -1994,7 +2037,7 @@ static int __init i7core_init(void) /* Ensure that the OPSTATE is set correctly for POLL or NMI */ opstate_init(); - i7core_xeon_pci_fixup(pci_dev_descr_i7core[0].dev_id); + i7core_xeon_pci_fixup(pci_dev_table); pci_rc = pci_register_driver(&i7core_driver); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 46d76e985bac..413fab765a5f 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2567,6 +2567,22 @@ #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR 0x2ca9 #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK 0x2caa #define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC 0x2cab +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MCR_REV2 0x2d98 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TAD_REV2 0x2d99 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_RAS_REV2 0x2d9a +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TEST_REV2 0x2d9c +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_CTRL_REV2 0x2da0 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_ADDR_REV2 0x2da1 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_RANK_REV2 0x2da2 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH0_TC_REV2 0x2da3 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_CTRL_REV2 0x2da8 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR_REV2 0x2da9 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK_REV2 0x2daa +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC_REV2 0x2dab +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_CTRL_REV2 0x2db0 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_ADDR_REV2 0x2db1 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_RANK_REV2 0x2db2 +#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_TC_REV2 0x2db3 #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340 #define PCI_DEVICE_ID_INTEL_IOAT_TBG4 0x3429 #define PCI_DEVICE_ID_INTEL_IOAT_TBG5 0x342a -- cgit v1.2.3 From 52707f918cca231f8461d45e78a60014795f20d9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 18 May 2010 20:43:52 -0300 Subject: i7core_edac: Better describe the supported devices Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7core_edac.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 8d63b0046480..6b8b7b41ec5f 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1,9 +1,14 @@ -/* Intel 7 core Memory Controller kernel module (Nehalem) +/* Intel i7 core/Nehalem Memory Controller kernel module + * + * This driver supports yhe memory controllers found on the Intel + * processor families i7core, i7core 7xx/8xx, i5core, Xeon 35xx, + * Xeon 55xx and Xeon 56xx also known as Nehalem, Nehalem-EP, Lynnfield + * and Westmere-EP. * * This file may be distributed under the terms of the * GNU General Public License version 2 only. * - * Copyright (c) 2009 by: + * Copyright (c) 2009-2010 by: * Mauro Carvalho Chehab * * Red Hat Inc. http://www.redhat.com -- cgit v1.2.3 From 3385329a0a0f1d31ca1d011c7887006a7e5a9902 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 19 May 2010 13:56:37 +1000 Subject: crypto: hifn_795x - Rename ablkcipher_walk to hifn_cipher_walk This is in preparation for the generic ablkcipher_walk helpers that will be added to the crypto layer. Signed-off-by: David S. Miller Signed-off-by: Herbert Xu --- drivers/crypto/hifn_795x.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index 73e8b1713b54..16fce3aadf4d 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -638,7 +638,7 @@ struct hifn_crypto_alg #define ASYNC_FLAGS_MISALIGNED (1<<0) -struct ablkcipher_walk +struct hifn_cipher_walk { struct scatterlist cache[ASYNC_SCATTERLIST_CACHE]; u32 flags; @@ -657,7 +657,7 @@ struct hifn_request_context u8 *iv; unsigned int ivsize; u8 op, type, mode, unused; - struct ablkcipher_walk walk; + struct hifn_cipher_walk walk; }; #define crypto_alg_to_hifn(a) container_of(a, struct hifn_crypto_alg, alg) @@ -1417,7 +1417,7 @@ static int hifn_setup_dma(struct hifn_device *dev, return 0; } -static int ablkcipher_walk_init(struct ablkcipher_walk *w, +static int hifn_cipher_walk_init(struct hifn_cipher_walk *w, int num, gfp_t gfp_flags) { int i; @@ -1442,7 +1442,7 @@ static int ablkcipher_walk_init(struct ablkcipher_walk *w, return i; } -static void ablkcipher_walk_exit(struct ablkcipher_walk *w) +static void hifn_cipher_walk_exit(struct hifn_cipher_walk *w) { int i; @@ -1486,8 +1486,8 @@ static int ablkcipher_add(unsigned int *drestp, struct scatterlist *dst, return idx; } -static int ablkcipher_walk(struct ablkcipher_request *req, - struct ablkcipher_walk *w) +static int hifn_cipher_walk(struct ablkcipher_request *req, + struct hifn_cipher_walk *w) { struct scatterlist *dst, *t; unsigned int nbytes = req->nbytes, offset, copy, diff; @@ -1600,12 +1600,12 @@ static int hifn_setup_session(struct ablkcipher_request *req) } if (rctx->walk.flags & ASYNC_FLAGS_MISALIGNED) { - err = ablkcipher_walk_init(&rctx->walk, idx, GFP_ATOMIC); + err = hifn_cipher_walk_init(&rctx->walk, idx, GFP_ATOMIC); if (err < 0) return err; } - sg_num = ablkcipher_walk(req, &rctx->walk); + sg_num = hifn_cipher_walk(req, &rctx->walk); if (sg_num < 0) { err = sg_num; goto err_out_exit; @@ -1806,7 +1806,7 @@ static void hifn_process_ready(struct ablkcipher_request *req, int error) kunmap_atomic(saddr, KM_SOFTIRQ0); } - ablkcipher_walk_exit(&rctx->walk); + hifn_cipher_walk_exit(&rctx->walk); } req->base.complete(&req->base, error); -- cgit v1.2.3 From 0a625fd2abaa0aa0a6852b153d429dbc784748cc Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 19 May 2010 14:14:04 +1000 Subject: crypto: n2 - Add Niagara2 crypto driver Current deficiencies: 1) No HMAC hash support yet. 2) Although the algs are registered as ASYNC they always run synchronously. Signed-off-by: David S. Miller Signed-off-by: Herbert Xu --- drivers/crypto/Kconfig | 12 + drivers/crypto/Makefile | 2 + drivers/crypto/n2_asm.S | 95 +++ drivers/crypto/n2_core.c | 2083 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/crypto/n2_core.h | 231 +++++ 5 files changed, 2423 insertions(+) create mode 100644 drivers/crypto/n2_asm.S create mode 100644 drivers/crypto/n2_core.c create mode 100644 drivers/crypto/n2_core.h (limited to 'drivers') diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 9073aa05123e..fbf94cf496f0 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -170,6 +170,18 @@ config CRYPTO_DEV_MV_CESA Currently the driver supports AES in ECB and CBC mode without DMA. +config CRYPTO_DEV_NIAGARA2 + tristate "Niagara2 Stream Processing Unit driver" + select CRYPTO_ALGAPI + depends on SPARC64 + help + Each core of a Niagara2 processor contains a Stream + Processing Unit, which itself contains several cryptographic + sub-units. One set provides the Modular Arithmetic Unit, + used for SSL offload. The other set provides the Cipher + Group, which can perform encryption, decryption, hashing, + checksumming, and raw copies. + config CRYPTO_DEV_HIFN_795X tristate "Driver HIFN 795x crypto accelerator chips" select CRYPTO_DES diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index c9494e163402..6dbbe00c4524 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -1,6 +1,8 @@ obj-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o obj-$(CONFIG_CRYPTO_DEV_PADLOCK_SHA) += padlock-sha.o obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o +obj-$(CONFIG_CRYPTO_DEV_NIAGARA2) += n2_crypto.o +n2_crypto-objs := n2_core.o n2_asm.o obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o obj-$(CONFIG_CRYPTO_DEV_MV_CESA) += mv_cesa.o obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o diff --git a/drivers/crypto/n2_asm.S b/drivers/crypto/n2_asm.S new file mode 100644 index 000000000000..f7c793745a1e --- /dev/null +++ b/drivers/crypto/n2_asm.S @@ -0,0 +1,95 @@ +/* n2_asm.S: Hypervisor calls for NCS support. + * + * Copyright (C) 2009 David S. Miller + */ + +#include +#include +#include "n2_core.h" + + /* o0: queue type + * o1: RA of queue + * o2: num entries in queue + * o3: address of queue handle return + */ +ENTRY(sun4v_ncs_qconf) + mov HV_FAST_NCS_QCONF, %o5 + ta HV_FAST_TRAP + stx %o1, [%o3] + retl + nop +ENDPROC(sun4v_ncs_qconf) + + /* %o0: queue handle + * %o1: address of queue type return + * %o2: address of queue base address return + * %o3: address of queue num entries return + */ +ENTRY(sun4v_ncs_qinfo) + mov %o1, %g1 + mov %o2, %g2 + mov %o3, %g3 + mov HV_FAST_NCS_QINFO, %o5 + ta HV_FAST_TRAP + stx %o1, [%g1] + stx %o2, [%g2] + stx %o3, [%g3] + retl + nop +ENDPROC(sun4v_ncs_qinfo) + + /* %o0: queue handle + * %o1: address of head offset return + */ +ENTRY(sun4v_ncs_gethead) + mov %o1, %o2 + mov HV_FAST_NCS_GETHEAD, %o5 + ta HV_FAST_TRAP + stx %o1, [%o2] + retl + nop +ENDPROC(sun4v_ncs_gethead) + + /* %o0: queue handle + * %o1: address of tail offset return + */ +ENTRY(sun4v_ncs_gettail) + mov %o1, %o2 + mov HV_FAST_NCS_GETTAIL, %o5 + ta HV_FAST_TRAP + stx %o1, [%o2] + retl + nop +ENDPROC(sun4v_ncs_gettail) + + /* %o0: queue handle + * %o1: new tail offset + */ +ENTRY(sun4v_ncs_settail) + mov HV_FAST_NCS_SETTAIL, %o5 + ta HV_FAST_TRAP + retl + nop +ENDPROC(sun4v_ncs_settail) + + /* %o0: queue handle + * %o1: address of devino return + */ +ENTRY(sun4v_ncs_qhandle_to_devino) + mov %o1, %o2 + mov HV_FAST_NCS_QHANDLE_TO_DEVINO, %o5 + ta HV_FAST_TRAP + stx %o1, [%o2] + retl + nop +ENDPROC(sun4v_ncs_qhandle_to_devino) + + /* %o0: queue handle + * %o1: new head offset + */ +ENTRY(sun4v_ncs_sethead_marker) + mov HV_FAST_NCS_SETHEAD_MARKER, %o5 + ta HV_FAST_TRAP + retl + nop +ENDPROC(sun4v_ncs_sethead_marker) diff --git a/drivers/crypto/n2_core.c b/drivers/crypto/n2_core.c new file mode 100644 index 000000000000..8566be832f51 --- /dev/null +++ b/drivers/crypto/n2_core.c @@ -0,0 +1,2083 @@ +/* n2_core.c: Niagara2 Stream Processing Unit (SPU) crypto support. + * + * Copyright (C) 2010 David S. Miller + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "n2_core.h" + +#define DRV_MODULE_NAME "n2_crypto" +#define DRV_MODULE_VERSION "0.1" +#define DRV_MODULE_RELDATE "April 29, 2010" + +static char version[] __devinitdata = + DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; + +MODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); +MODULE_DESCRIPTION("Niagara2 Crypto driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_MODULE_VERSION); + +#define N2_CRA_PRIORITY 300 + +static DEFINE_MUTEX(spu_lock); + +struct spu_queue { + cpumask_t sharing; + unsigned long qhandle; + + spinlock_t lock; + u8 q_type; + void *q; + unsigned long head; + unsigned long tail; + struct list_head jobs; + + unsigned long devino; + + char irq_name[32]; + unsigned int irq; + + struct list_head list; +}; + +static struct spu_queue **cpu_to_cwq; +static struct spu_queue **cpu_to_mau; + +static unsigned long spu_next_offset(struct spu_queue *q, unsigned long off) +{ + if (q->q_type == HV_NCS_QTYPE_MAU) { + off += MAU_ENTRY_SIZE; + if (off == (MAU_ENTRY_SIZE * MAU_NUM_ENTRIES)) + off = 0; + } else { + off += CWQ_ENTRY_SIZE; + if (off == (CWQ_ENTRY_SIZE * CWQ_NUM_ENTRIES)) + off = 0; + } + return off; +} + +struct n2_request_common { + struct list_head entry; + unsigned int offset; +}; +#define OFFSET_NOT_RUNNING (~(unsigned int)0) + +/* An async job request records the final tail value it used in + * n2_request_common->offset, test to see if that offset is in + * the range old_head, new_head, inclusive. + */ +static inline bool job_finished(struct spu_queue *q, unsigned int offset, + unsigned long old_head, unsigned long new_head) +{ + if (old_head <= new_head) { + if (offset > old_head && offset <= new_head) + return true; + } else { + if (offset > old_head || offset <= new_head) + return true; + } + return false; +} + +/* When the HEAD marker is unequal to the actual HEAD, we get + * a virtual device INO interrupt. We should process the + * completed CWQ entries and adjust the HEAD marker to clear + * the IRQ. + */ +static irqreturn_t cwq_intr(int irq, void *dev_id) +{ + unsigned long off, new_head, hv_ret; + struct spu_queue *q = dev_id; + + pr_err("CPU[%d]: Got CWQ interrupt for qhdl[%lx]\n", + smp_processor_id(), q->qhandle); + + spin_lock(&q->lock); + + hv_ret = sun4v_ncs_gethead(q->qhandle, &new_head); + + pr_err("CPU[%d]: CWQ gethead[%lx] hv_ret[%lu]\n", + smp_processor_id(), new_head, hv_ret); + + for (off = q->head; off != new_head; off = spu_next_offset(q, off)) { + /* XXX ... XXX */ + } + + hv_ret = sun4v_ncs_sethead_marker(q->qhandle, new_head); + if (hv_ret == HV_EOK) + q->head = new_head; + + spin_unlock(&q->lock); + + return IRQ_HANDLED; +} + +static irqreturn_t mau_intr(int irq, void *dev_id) +{ + struct spu_queue *q = dev_id; + unsigned long head, hv_ret; + + spin_lock(&q->lock); + + pr_err("CPU[%d]: Got MAU interrupt for qhdl[%lx]\n", + smp_processor_id(), q->qhandle); + + hv_ret = sun4v_ncs_gethead(q->qhandle, &head); + + pr_err("CPU[%d]: MAU gethead[%lx] hv_ret[%lu]\n", + smp_processor_id(), head, hv_ret); + + sun4v_ncs_sethead_marker(q->qhandle, head); + + spin_unlock(&q->lock); + + return IRQ_HANDLED; +} + +static void *spu_queue_next(struct spu_queue *q, void *cur) +{ + return q->q + spu_next_offset(q, cur - q->q); +} + +static int spu_queue_num_free(struct spu_queue *q) +{ + unsigned long head = q->head; + unsigned long tail = q->tail; + unsigned long end = (CWQ_ENTRY_SIZE * CWQ_NUM_ENTRIES); + unsigned long diff; + + if (head > tail) + diff = head - tail; + else + diff = (end - tail) + head; + + return (diff / CWQ_ENTRY_SIZE) - 1; +} + +static void *spu_queue_alloc(struct spu_queue *q, int num_entries) +{ + int avail = spu_queue_num_free(q); + + if (avail >= num_entries) + return q->q + q->tail; + + return NULL; +} + +static unsigned long spu_queue_submit(struct spu_queue *q, void *last) +{ + unsigned long hv_ret, new_tail; + + new_tail = spu_next_offset(q, last - q->q); + + hv_ret = sun4v_ncs_settail(q->qhandle, new_tail); + if (hv_ret == HV_EOK) + q->tail = new_tail; + return hv_ret; +} + +static u64 control_word_base(unsigned int len, unsigned int hmac_key_len, + int enc_type, int auth_type, + unsigned int hash_len, + bool sfas, bool sob, bool eob, bool encrypt, + int opcode) +{ + u64 word = (len - 1) & CONTROL_LEN; + + word |= ((u64) opcode << CONTROL_OPCODE_SHIFT); + word |= ((u64) enc_type << CONTROL_ENC_TYPE_SHIFT); + word |= ((u64) auth_type << CONTROL_AUTH_TYPE_SHIFT); + if (sfas) + word |= CONTROL_STORE_FINAL_AUTH_STATE; + if (sob) + word |= CONTROL_START_OF_BLOCK; + if (eob) + word |= CONTROL_END_OF_BLOCK; + if (encrypt) + word |= CONTROL_ENCRYPT; + if (hmac_key_len) + word |= ((u64) (hmac_key_len - 1)) << CONTROL_HMAC_KEY_LEN_SHIFT; + if (hash_len) + word |= ((u64) (hash_len - 1)) << CONTROL_HASH_LEN_SHIFT; + + return word; +} + +#if 0 +static inline bool n2_should_run_async(struct spu_queue *qp, int this_len) +{ + if (this_len >= 64 || + qp->head != qp->tail) + return true; + return false; +} +#endif + +struct n2_base_ctx { + struct list_head list; +}; + +static void n2_base_ctx_init(struct n2_base_ctx *ctx) +{ + INIT_LIST_HEAD(&ctx->list); +} + +struct n2_hash_ctx { + struct n2_base_ctx base; + + struct crypto_ahash *fallback; + + /* These next three members must match the layout created by + * crypto_init_shash_ops_async. This allows us to properly + * plumb requests we can't do in hardware down to the fallback + * operation, providing all of the data structures and layouts + * expected by those paths. + */ + struct ahash_request fallback_req; + struct shash_desc fallback_desc; + union { + struct md5_state md5; + struct sha1_state sha1; + struct sha256_state sha256; + } u; + + unsigned char hash_key[64]; + unsigned char keyed_zero_hash[32]; +}; + +static int n2_hash_async_init(struct ahash_request *req) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); + + ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback); + ctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; + + return crypto_ahash_init(&ctx->fallback_req); +} + +static int n2_hash_async_update(struct ahash_request *req) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); + + ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback); + ctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; + ctx->fallback_req.nbytes = req->nbytes; + ctx->fallback_req.src = req->src; + + return crypto_ahash_update(&ctx->fallback_req); +} + +static int n2_hash_async_final(struct ahash_request *req) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); + + ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback); + ctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; + ctx->fallback_req.result = req->result; + + return crypto_ahash_final(&ctx->fallback_req); +} + +static int n2_hash_async_finup(struct ahash_request *req) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); + + ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback); + ctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; + ctx->fallback_req.nbytes = req->nbytes; + ctx->fallback_req.src = req->src; + ctx->fallback_req.result = req->result; + + return crypto_ahash_finup(&ctx->fallback_req); +} + +static int n2_hash_cra_init(struct crypto_tfm *tfm) +{ + const char *fallback_driver_name = tfm->__crt_alg->cra_name; + struct crypto_ahash *ahash = __crypto_ahash_cast(tfm); + struct n2_hash_ctx *ctx = crypto_ahash_ctx(ahash); + struct crypto_ahash *fallback_tfm; + int err; + + fallback_tfm = crypto_alloc_ahash(fallback_driver_name, 0, + CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(fallback_tfm)) { + pr_warning("Fallback driver '%s' could not be loaded!\n", + fallback_driver_name); + err = PTR_ERR(fallback_tfm); + goto out; + } + + ctx->fallback = fallback_tfm; + return 0; + +out: + return err; +} + +static void n2_hash_cra_exit(struct crypto_tfm *tfm) +{ + struct crypto_ahash *ahash = __crypto_ahash_cast(tfm); + struct n2_hash_ctx *ctx = crypto_ahash_ctx(ahash); + + crypto_free_ahash(ctx->fallback); +} + +static unsigned long wait_for_tail(struct spu_queue *qp) +{ + unsigned long head, hv_ret; + + do { + hv_ret = sun4v_ncs_gethead(qp->qhandle, &head); + if (hv_ret != HV_EOK) { + pr_err("Hypervisor error on gethead\n"); + break; + } + if (head == qp->tail) { + qp->head = head; + break; + } + } while (1); + return hv_ret; +} + +static unsigned long submit_and_wait_for_tail(struct spu_queue *qp, + struct cwq_initial_entry *ent) +{ + unsigned long hv_ret = spu_queue_submit(qp, ent); + + if (hv_ret == HV_EOK) + hv_ret = wait_for_tail(qp); + + return hv_ret; +} + +static int n2_hash_async_digest(struct ahash_request *req, + unsigned int auth_type, unsigned int digest_size, + unsigned int result_size, void *hash_loc) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); + struct cwq_initial_entry *ent; + struct crypto_hash_walk walk; + struct spu_queue *qp; + unsigned long flags; + int err = -ENODEV; + int nbytes, cpu; + + /* The total effective length of the operation may not + * exceed 2^16. + */ + if (unlikely(req->nbytes > (1 << 16))) { + ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback); + ctx->fallback_req.base.flags = + req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; + ctx->fallback_req.nbytes = req->nbytes; + ctx->fallback_req.src = req->src; + ctx->fallback_req.result = req->result; + + return crypto_ahash_digest(&ctx->fallback_req); + } + + n2_base_ctx_init(&ctx->base); + + nbytes = crypto_hash_walk_first(req, &walk); + + cpu = get_cpu(); + qp = cpu_to_cwq[cpu]; + if (!qp) + goto out; + + spin_lock_irqsave(&qp->lock, flags); + + /* XXX can do better, improve this later by doing a by-hand scatterlist + * XXX walk, etc. + */ + ent = qp->q + qp->tail; + + ent->control = control_word_base(nbytes, 0, 0, + auth_type, digest_size, + false, true, false, false, + OPCODE_INPLACE_BIT | + OPCODE_AUTH_MAC); + ent->src_addr = __pa(walk.data); + ent->auth_key_addr = 0UL; + ent->auth_iv_addr = __pa(hash_loc); + ent->final_auth_state_addr = 0UL; + ent->enc_key_addr = 0UL; + ent->enc_iv_addr = 0UL; + ent->dest_addr = __pa(hash_loc); + + nbytes = crypto_hash_walk_done(&walk, 0); + while (nbytes > 0) { + ent = spu_queue_next(qp, ent); + + ent->control = (nbytes - 1); + ent->src_addr = __pa(walk.data); + ent->auth_key_addr = 0UL; + ent->auth_iv_addr = 0UL; + ent->final_auth_state_addr = 0UL; + ent->enc_key_addr = 0UL; + ent->enc_iv_addr = 0UL; + ent->dest_addr = 0UL; + + nbytes = crypto_hash_walk_done(&walk, 0); + } + ent->control |= CONTROL_END_OF_BLOCK; + + if (submit_and_wait_for_tail(qp, ent) != HV_EOK) + err = -EINVAL; + else + err = 0; + + spin_unlock_irqrestore(&qp->lock, flags); + + if (!err) + memcpy(req->result, hash_loc, result_size); +out: + put_cpu(); + + return err; +} + +static int n2_md5_async_digest(struct ahash_request *req) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); + struct md5_state *m = &ctx->u.md5; + + if (unlikely(req->nbytes == 0)) { + static const char md5_zero[MD5_DIGEST_SIZE] = { + 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, + 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e, + }; + + memcpy(req->result, md5_zero, MD5_DIGEST_SIZE); + return 0; + } + m->hash[0] = cpu_to_le32(0x67452301); + m->hash[1] = cpu_to_le32(0xefcdab89); + m->hash[2] = cpu_to_le32(0x98badcfe); + m->hash[3] = cpu_to_le32(0x10325476); + + return n2_hash_async_digest(req, AUTH_TYPE_MD5, + MD5_DIGEST_SIZE, MD5_DIGEST_SIZE, + m->hash); +} + +static int n2_sha1_async_digest(struct ahash_request *req) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); + struct sha1_state *s = &ctx->u.sha1; + + if (unlikely(req->nbytes == 0)) { + static const char sha1_zero[SHA1_DIGEST_SIZE] = { + 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, + 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, + 0x07, 0x09 + }; + + memcpy(req->result, sha1_zero, SHA1_DIGEST_SIZE); + return 0; + } + s->state[0] = SHA1_H0; + s->state[1] = SHA1_H1; + s->state[2] = SHA1_H2; + s->state[3] = SHA1_H3; + s->state[4] = SHA1_H4; + + return n2_hash_async_digest(req, AUTH_TYPE_SHA1, + SHA1_DIGEST_SIZE, SHA1_DIGEST_SIZE, + s->state); +} + +static int n2_sha256_async_digest(struct ahash_request *req) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); + struct sha256_state *s = &ctx->u.sha256; + + if (req->nbytes == 0) { + static const char sha256_zero[SHA256_DIGEST_SIZE] = { + 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, + 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, + 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, + 0x1b, 0x78, 0x52, 0xb8, 0x55 + }; + + memcpy(req->result, sha256_zero, SHA256_DIGEST_SIZE); + return 0; + } + s->state[0] = SHA256_H0; + s->state[1] = SHA256_H1; + s->state[2] = SHA256_H2; + s->state[3] = SHA256_H3; + s->state[4] = SHA256_H4; + s->state[5] = SHA256_H5; + s->state[6] = SHA256_H6; + s->state[7] = SHA256_H7; + + return n2_hash_async_digest(req, AUTH_TYPE_SHA256, + SHA256_DIGEST_SIZE, SHA256_DIGEST_SIZE, + s->state); +} + +static int n2_sha224_async_digest(struct ahash_request *req) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); + struct sha256_state *s = &ctx->u.sha256; + + if (req->nbytes == 0) { + static const char sha224_zero[SHA224_DIGEST_SIZE] = { + 0xd1, 0x4a, 0x02, 0x8c, 0x2a, 0x3a, 0x2b, 0xc9, 0x47, + 0x61, 0x02, 0xbb, 0x28, 0x82, 0x34, 0xc4, 0x15, 0xa2, + 0xb0, 0x1f, 0x82, 0x8e, 0xa6, 0x2a, 0xc5, 0xb3, 0xe4, + 0x2f + }; + + memcpy(req->result, sha224_zero, SHA224_DIGEST_SIZE); + return 0; + } + s->state[0] = SHA224_H0; + s->state[1] = SHA224_H1; + s->state[2] = SHA224_H2; + s->state[3] = SHA224_H3; + s->state[4] = SHA224_H4; + s->state[5] = SHA224_H5; + s->state[6] = SHA224_H6; + s->state[7] = SHA224_H7; + + return n2_hash_async_digest(req, AUTH_TYPE_SHA256, + SHA256_DIGEST_SIZE, SHA224_DIGEST_SIZE, + s->state); +} + +struct n2_cipher_context { + int key_len; + int enc_type; + union { + u8 aes[AES_MAX_KEY_SIZE]; + u8 des[DES_KEY_SIZE]; + u8 des3[3 * DES_KEY_SIZE]; + u8 arc4[258]; /* S-box, X, Y */ + } key; +}; + +#define N2_CHUNK_ARR_LEN 16 + +struct n2_crypto_chunk { + struct list_head entry; + unsigned long iv_paddr : 44; + unsigned long arr_len : 20; + unsigned long dest_paddr; + unsigned long dest_final; + struct { + unsigned long src_paddr : 44; + unsigned long src_len : 20; + } arr[N2_CHUNK_ARR_LEN]; +}; + +struct n2_request_context { + struct ablkcipher_walk walk; + struct list_head chunk_list; + struct n2_crypto_chunk chunk; + u8 temp_iv[16]; +}; + +/* The SPU allows some level of flexibility for partial cipher blocks + * being specified in a descriptor. + * + * It merely requires that every descriptor's length field is at least + * as large as the cipher block size. This means that a cipher block + * can span at most 2 descriptors. However, this does not allow a + * partial block to span into the final descriptor as that would + * violate the rule (since every descriptor's length must be at lest + * the block size). So, for example, assuming an 8 byte block size: + * + * 0xe --> 0xa --> 0x8 + * + * is a valid length sequence, whereas: + * + * 0xe --> 0xb --> 0x7 + * + * is not a valid sequence. + */ + +struct n2_cipher_alg { + struct list_head entry; + u8 enc_type; + struct crypto_alg alg; +}; + +static inline struct n2_cipher_alg *n2_cipher_alg(struct crypto_tfm *tfm) +{ + struct crypto_alg *alg = tfm->__crt_alg; + + return container_of(alg, struct n2_cipher_alg, alg); +} + +struct n2_cipher_request_context { + struct ablkcipher_walk walk; +}; + +static int n2_aes_setkey(struct crypto_ablkcipher *cipher, const u8 *key, + unsigned int keylen) +{ + struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); + struct n2_cipher_context *ctx = crypto_tfm_ctx(tfm); + struct n2_cipher_alg *n2alg = n2_cipher_alg(tfm); + + ctx->enc_type = (n2alg->enc_type & ENC_TYPE_CHAINING_MASK); + + switch (keylen) { + case AES_KEYSIZE_128: + ctx->enc_type |= ENC_TYPE_ALG_AES128; + break; + case AES_KEYSIZE_192: + ctx->enc_type |= ENC_TYPE_ALG_AES192; + break; + case AES_KEYSIZE_256: + ctx->enc_type |= ENC_TYPE_ALG_AES256; + break; + default: + crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + + ctx->key_len = keylen; + memcpy(ctx->key.aes, key, keylen); + return 0; +} + +static int n2_des_setkey(struct crypto_ablkcipher *cipher, const u8 *key, + unsigned int keylen) +{ + struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); + struct n2_cipher_context *ctx = crypto_tfm_ctx(tfm); + struct n2_cipher_alg *n2alg = n2_cipher_alg(tfm); + u32 tmp[DES_EXPKEY_WORDS]; + int err; + + ctx->enc_type = n2alg->enc_type; + + if (keylen != DES_KEY_SIZE) { + crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + + err = des_ekey(tmp, key); + if (err == 0 && (tfm->crt_flags & CRYPTO_TFM_REQ_WEAK_KEY)) { + tfm->crt_flags |= CRYPTO_TFM_RES_WEAK_KEY; + return -EINVAL; + } + + ctx->key_len = keylen; + memcpy(ctx->key.des, key, keylen); + return 0; +} + +static int n2_3des_setkey(struct crypto_ablkcipher *cipher, const u8 *key, + unsigned int keylen) +{ + struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); + struct n2_cipher_context *ctx = crypto_tfm_ctx(tfm); + struct n2_cipher_alg *n2alg = n2_cipher_alg(tfm); + + ctx->enc_type = n2alg->enc_type; + + if (keylen != (3 * DES_KEY_SIZE)) { + crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + ctx->key_len = keylen; + memcpy(ctx->key.des3, key, keylen); + return 0; +} + +static int n2_arc4_setkey(struct crypto_ablkcipher *cipher, const u8 *key, + unsigned int keylen) +{ + struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher); + struct n2_cipher_context *ctx = crypto_tfm_ctx(tfm); + struct n2_cipher_alg *n2alg = n2_cipher_alg(tfm); + u8 *s = ctx->key.arc4; + u8 *x = s + 256; + u8 *y = x + 1; + int i, j, k; + + ctx->enc_type = n2alg->enc_type; + + j = k = 0; + *x = 0; + *y = 0; + for (i = 0; i < 256; i++) + s[i] = i; + for (i = 0; i < 256; i++) { + u8 a = s[i]; + j = (j + key[k] + a) & 0xff; + s[i] = s[j]; + s[j] = a; + if (++k >= keylen) + k = 0; + } + + return 0; +} + +static inline int cipher_descriptor_len(int nbytes, unsigned int block_size) +{ + int this_len = nbytes; + + this_len -= (nbytes & (block_size - 1)); + return this_len > (1 << 16) ? (1 << 16) : this_len; +} + +static int __n2_crypt_chunk(struct crypto_tfm *tfm, struct n2_crypto_chunk *cp, + struct spu_queue *qp, bool encrypt) +{ + struct n2_cipher_context *ctx = crypto_tfm_ctx(tfm); + struct cwq_initial_entry *ent; + bool in_place; + int i; + + ent = spu_queue_alloc(qp, cp->arr_len); + if (!ent) { + pr_info("queue_alloc() of %d fails\n", + cp->arr_len); + return -EBUSY; + } + + in_place = (cp->dest_paddr == cp->arr[0].src_paddr); + + ent->control = control_word_base(cp->arr[0].src_len, + 0, ctx->enc_type, 0, 0, + false, true, false, encrypt, + OPCODE_ENCRYPT | + (in_place ? OPCODE_INPLACE_BIT : 0)); + ent->src_addr = cp->arr[0].src_paddr; + ent->auth_key_addr = 0UL; + ent->auth_iv_addr = 0UL; + ent->final_auth_state_addr = 0UL; + ent->enc_key_addr = __pa(&ctx->key); + ent->enc_iv_addr = cp->iv_paddr; + ent->dest_addr = (in_place ? 0UL : cp->dest_paddr); + + for (i = 1; i < cp->arr_len; i++) { + ent = spu_queue_next(qp, ent); + + ent->control = cp->arr[i].src_len - 1; + ent->src_addr = cp->arr[i].src_paddr; + ent->auth_key_addr = 0UL; + ent->auth_iv_addr = 0UL; + ent->final_auth_state_addr = 0UL; + ent->enc_key_addr = 0UL; + ent->enc_iv_addr = 0UL; + ent->dest_addr = 0UL; + } + ent->control |= CONTROL_END_OF_BLOCK; + + return (spu_queue_submit(qp, ent) != HV_EOK) ? -EINVAL : 0; +} + +static int n2_compute_chunks(struct ablkcipher_request *req) +{ + struct n2_request_context *rctx = ablkcipher_request_ctx(req); + struct ablkcipher_walk *walk = &rctx->walk; + struct n2_crypto_chunk *chunk; + unsigned long dest_prev; + unsigned int tot_len; + bool prev_in_place; + int err, nbytes; + + ablkcipher_walk_init(walk, req->dst, req->src, req->nbytes); + err = ablkcipher_walk_phys(req, walk); + if (err) + return err; + + INIT_LIST_HEAD(&rctx->chunk_list); + + chunk = &rctx->chunk; + INIT_LIST_HEAD(&chunk->entry); + + chunk->iv_paddr = 0UL; + chunk->arr_len = 0; + chunk->dest_paddr = 0UL; + + prev_in_place = false; + dest_prev = ~0UL; + tot_len = 0; + + while ((nbytes = walk->nbytes) != 0) { + unsigned long dest_paddr, src_paddr; + bool in_place; + int this_len; + + src_paddr = (page_to_phys(walk->src.page) + + walk->src.offset); + dest_paddr = (page_to_phys(walk->dst.page) + + walk->dst.offset); + in_place = (src_paddr == dest_paddr); + this_len = cipher_descriptor_len(nbytes, walk->blocksize); + + if (chunk->arr_len != 0) { + if (in_place != prev_in_place || + (!prev_in_place && + dest_paddr != dest_prev) || + chunk->arr_len == N2_CHUNK_ARR_LEN || + tot_len + this_len > (1 << 16)) { + chunk->dest_final = dest_prev; + list_add_tail(&chunk->entry, + &rctx->chunk_list); + chunk = kzalloc(sizeof(*chunk), GFP_ATOMIC); + if (!chunk) { + err = -ENOMEM; + break; + } + INIT_LIST_HEAD(&chunk->entry); + } + } + if (chunk->arr_len == 0) { + chunk->dest_paddr = dest_paddr; + tot_len = 0; + } + chunk->arr[chunk->arr_len].src_paddr = src_paddr; + chunk->arr[chunk->arr_len].src_len = this_len; + chunk->arr_len++; + + dest_prev = dest_paddr + this_len; + prev_in_place = in_place; + tot_len += this_len; + + err = ablkcipher_walk_done(req, walk, nbytes - this_len); + if (err) + break; + } + if (!err && chunk->arr_len != 0) { + chunk->dest_final = dest_prev; + list_add_tail(&chunk->entry, &rctx->chunk_list); + } + + return err; +} + +static void n2_chunk_complete(struct ablkcipher_request *req, void *final_iv) +{ + struct n2_request_context *rctx = ablkcipher_request_ctx(req); + struct n2_crypto_chunk *c, *tmp; + + if (final_iv) + memcpy(rctx->walk.iv, final_iv, rctx->walk.blocksize); + + ablkcipher_walk_complete(&rctx->walk); + list_for_each_entry_safe(c, tmp, &rctx->chunk_list, entry) { + list_del(&c->entry); + if (unlikely(c != &rctx->chunk)) + kfree(c); + } + +} + +static int n2_do_ecb(struct ablkcipher_request *req, bool encrypt) +{ + struct n2_request_context *rctx = ablkcipher_request_ctx(req); + struct crypto_tfm *tfm = req->base.tfm; + int err = n2_compute_chunks(req); + struct n2_crypto_chunk *c, *tmp; + unsigned long flags, hv_ret; + struct spu_queue *qp; + + if (err) + return err; + + qp = cpu_to_cwq[get_cpu()]; + err = -ENODEV; + if (!qp) + goto out; + + spin_lock_irqsave(&qp->lock, flags); + + list_for_each_entry_safe(c, tmp, &rctx->chunk_list, entry) { + err = __n2_crypt_chunk(tfm, c, qp, encrypt); + if (err) + break; + list_del(&c->entry); + if (unlikely(c != &rctx->chunk)) + kfree(c); + } + if (!err) { + hv_ret = wait_for_tail(qp); + if (hv_ret != HV_EOK) + err = -EINVAL; + } + + spin_unlock_irqrestore(&qp->lock, flags); + + put_cpu(); + +out: + n2_chunk_complete(req, NULL); + return err; +} + +static int n2_encrypt_ecb(struct ablkcipher_request *req) +{ + return n2_do_ecb(req, true); +} + +static int n2_decrypt_ecb(struct ablkcipher_request *req) +{ + return n2_do_ecb(req, false); +} + +static int n2_do_chaining(struct ablkcipher_request *req, bool encrypt) +{ + struct n2_request_context *rctx = ablkcipher_request_ctx(req); + struct crypto_tfm *tfm = req->base.tfm; + unsigned long flags, hv_ret, iv_paddr; + int err = n2_compute_chunks(req); + struct n2_crypto_chunk *c, *tmp; + struct spu_queue *qp; + void *final_iv_addr; + + final_iv_addr = NULL; + + if (err) + return err; + + qp = cpu_to_cwq[get_cpu()]; + err = -ENODEV; + if (!qp) + goto out; + + spin_lock_irqsave(&qp->lock, flags); + + if (encrypt) { + iv_paddr = __pa(rctx->walk.iv); + list_for_each_entry_safe(c, tmp, &rctx->chunk_list, + entry) { + c->iv_paddr = iv_paddr; + err = __n2_crypt_chunk(tfm, c, qp, true); + if (err) + break; + iv_paddr = c->dest_final - rctx->walk.blocksize; + list_del(&c->entry); + if (unlikely(c != &rctx->chunk)) + kfree(c); + } + final_iv_addr = __va(iv_paddr); + } else { + list_for_each_entry_safe_reverse(c, tmp, &rctx->chunk_list, + entry) { + if (c == &rctx->chunk) { + iv_paddr = __pa(rctx->walk.iv); + } else { + iv_paddr = (tmp->arr[tmp->arr_len-1].src_paddr + + tmp->arr[tmp->arr_len-1].src_len - + rctx->walk.blocksize); + } + if (!final_iv_addr) { + unsigned long pa; + + pa = (c->arr[c->arr_len-1].src_paddr + + c->arr[c->arr_len-1].src_len - + rctx->walk.blocksize); + final_iv_addr = rctx->temp_iv; + memcpy(rctx->temp_iv, __va(pa), + rctx->walk.blocksize); + } + c->iv_paddr = iv_paddr; + err = __n2_crypt_chunk(tfm, c, qp, false); + if (err) + break; + list_del(&c->entry); + if (unlikely(c != &rctx->chunk)) + kfree(c); + } + } + if (!err) { + hv_ret = wait_for_tail(qp); + if (hv_ret != HV_EOK) + err = -EINVAL; + } + + spin_unlock_irqrestore(&qp->lock, flags); + + put_cpu(); + +out: + n2_chunk_complete(req, err ? NULL : final_iv_addr); + return err; +} + +static int n2_encrypt_chaining(struct ablkcipher_request *req) +{ + return n2_do_chaining(req, true); +} + +static int n2_decrypt_chaining(struct ablkcipher_request *req) +{ + return n2_do_chaining(req, false); +} + +struct n2_cipher_tmpl { + const char *name; + const char *drv_name; + u8 block_size; + u8 enc_type; + struct ablkcipher_alg ablkcipher; +}; + +static const struct n2_cipher_tmpl cipher_tmpls[] = { + /* ARC4: only ECB is supported (chaining bits ignored) */ + { .name = "ecb(arc4)", + .drv_name = "ecb-arc4", + .block_size = 1, + .enc_type = (ENC_TYPE_ALG_RC4_STREAM | + ENC_TYPE_CHAINING_ECB), + .ablkcipher = { + .min_keysize = 1, + .max_keysize = 256, + .setkey = n2_arc4_setkey, + .encrypt = n2_encrypt_ecb, + .decrypt = n2_decrypt_ecb, + }, + }, + + /* DES: ECB CBC and CFB are supported */ + { .name = "ecb(des)", + .drv_name = "ecb-des", + .block_size = DES_BLOCK_SIZE, + .enc_type = (ENC_TYPE_ALG_DES | + ENC_TYPE_CHAINING_ECB), + .ablkcipher = { + .min_keysize = DES_KEY_SIZE, + .max_keysize = DES_KEY_SIZE, + .setkey = n2_des_setkey, + .encrypt = n2_encrypt_ecb, + .decrypt = n2_decrypt_ecb, + }, + }, + { .name = "cbc(des)", + .drv_name = "cbc-des", + .block_size = DES_BLOCK_SIZE, + .enc_type = (ENC_TYPE_ALG_DES | + ENC_TYPE_CHAINING_CBC), + .ablkcipher = { + .ivsize = DES_BLOCK_SIZE, + .min_keysize = DES_KEY_SIZE, + .max_keysize = DES_KEY_SIZE, + .setkey = n2_des_setkey, + .encrypt = n2_encrypt_chaining, + .decrypt = n2_decrypt_chaining, + }, + }, + { .name = "cfb(des)", + .drv_name = "cfb-des", + .block_size = DES_BLOCK_SIZE, + .enc_type = (ENC_TYPE_ALG_DES | + ENC_TYPE_CHAINING_CFB), + .ablkcipher = { + .min_keysize = DES_KEY_SIZE, + .max_keysize = DES_KEY_SIZE, + .setkey = n2_des_setkey, + .encrypt = n2_encrypt_chaining, + .decrypt = n2_decrypt_chaining, + }, + }, + + /* 3DES: ECB CBC and CFB are supported */ + { .name = "ecb(des3_ede)", + .drv_name = "ecb-3des", + .block_size = DES_BLOCK_SIZE, + .enc_type = (ENC_TYPE_ALG_3DES | + ENC_TYPE_CHAINING_ECB), + .ablkcipher = { + .min_keysize = 3 * DES_KEY_SIZE, + .max_keysize = 3 * DES_KEY_SIZE, + .setkey = n2_3des_setkey, + .encrypt = n2_encrypt_ecb, + .decrypt = n2_decrypt_ecb, + }, + }, + { .name = "cbc(des3_ede)", + .drv_name = "cbc-3des", + .block_size = DES_BLOCK_SIZE, + .enc_type = (ENC_TYPE_ALG_3DES | + ENC_TYPE_CHAINING_CBC), + .ablkcipher = { + .ivsize = DES_BLOCK_SIZE, + .min_keysize = 3 * DES_KEY_SIZE, + .max_keysize = 3 * DES_KEY_SIZE, + .setkey = n2_3des_setkey, + .encrypt = n2_encrypt_chaining, + .decrypt = n2_decrypt_chaining, + }, + }, + { .name = "cfb(des3_ede)", + .drv_name = "cfb-3des", + .block_size = DES_BLOCK_SIZE, + .enc_type = (ENC_TYPE_ALG_3DES | + ENC_TYPE_CHAINING_CFB), + .ablkcipher = { + .min_keysize = 3 * DES_KEY_SIZE, + .max_keysize = 3 * DES_KEY_SIZE, + .setkey = n2_3des_setkey, + .encrypt = n2_encrypt_chaining, + .decrypt = n2_decrypt_chaining, + }, + }, + /* AES: ECB CBC and CTR are supported */ + { .name = "ecb(aes)", + .drv_name = "ecb-aes", + .block_size = AES_BLOCK_SIZE, + .enc_type = (ENC_TYPE_ALG_AES128 | + ENC_TYPE_CHAINING_ECB), + .ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .setkey = n2_aes_setkey, + .encrypt = n2_encrypt_ecb, + .decrypt = n2_decrypt_ecb, + }, + }, + { .name = "cbc(aes)", + .drv_name = "cbc-aes", + .block_size = AES_BLOCK_SIZE, + .enc_type = (ENC_TYPE_ALG_AES128 | + ENC_TYPE_CHAINING_CBC), + .ablkcipher = { + .ivsize = AES_BLOCK_SIZE, + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .setkey = n2_aes_setkey, + .encrypt = n2_encrypt_chaining, + .decrypt = n2_decrypt_chaining, + }, + }, + { .name = "ctr(aes)", + .drv_name = "ctr-aes", + .block_size = AES_BLOCK_SIZE, + .enc_type = (ENC_TYPE_ALG_AES128 | + ENC_TYPE_CHAINING_COUNTER), + .ablkcipher = { + .ivsize = AES_BLOCK_SIZE, + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .setkey = n2_aes_setkey, + .encrypt = n2_encrypt_chaining, + .decrypt = n2_encrypt_chaining, + }, + }, + +}; +#define NUM_CIPHER_TMPLS ARRAY_SIZE(cipher_tmpls) + +static LIST_HEAD(cipher_algs); + +struct n2_hash_tmpl { + const char *name; + int (*digest)(struct ahash_request *req); + u8 digest_size; + u8 block_size; +}; +static const struct n2_hash_tmpl hash_tmpls[] = { + { .name = "md5", + .digest = n2_md5_async_digest, + .digest_size = MD5_DIGEST_SIZE, + .block_size = MD5_HMAC_BLOCK_SIZE }, + { .name = "sha1", + .digest = n2_sha1_async_digest, + .digest_size = SHA1_DIGEST_SIZE, + .block_size = SHA1_BLOCK_SIZE }, + { .name = "sha256", + .digest = n2_sha256_async_digest, + .digest_size = SHA256_DIGEST_SIZE, + .block_size = SHA256_BLOCK_SIZE }, + { .name = "sha224", + .digest = n2_sha224_async_digest, + .digest_size = SHA224_DIGEST_SIZE, + .block_size = SHA224_BLOCK_SIZE }, +}; +#define NUM_HASH_TMPLS ARRAY_SIZE(hash_tmpls) + +struct n2_ahash_alg { + struct list_head entry; + struct ahash_alg alg; +}; +static LIST_HEAD(ahash_algs); + +static int algs_registered; + +static void __n2_unregister_algs(void) +{ + struct n2_cipher_alg *cipher, *cipher_tmp; + struct n2_ahash_alg *alg, *alg_tmp; + + list_for_each_entry_safe(cipher, cipher_tmp, &cipher_algs, entry) { + crypto_unregister_alg(&cipher->alg); + list_del(&cipher->entry); + kfree(cipher); + } + list_for_each_entry_safe(alg, alg_tmp, &ahash_algs, entry) { + crypto_unregister_ahash(&alg->alg); + list_del(&alg->entry); + kfree(alg); + } +} + +static int n2_cipher_cra_init(struct crypto_tfm *tfm) +{ + tfm->crt_ablkcipher.reqsize = sizeof(struct n2_request_context); + return 0; +} + +static int __devinit __n2_register_one_cipher(const struct n2_cipher_tmpl *tmpl) +{ + struct n2_cipher_alg *p = kzalloc(sizeof(*p), GFP_KERNEL); + struct crypto_alg *alg; + int err; + + if (!p) + return -ENOMEM; + + alg = &p->alg; + + snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", tmpl->name); + snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s-n2", tmpl->drv_name); + alg->cra_priority = N2_CRA_PRIORITY; + alg->cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC; + alg->cra_blocksize = tmpl->block_size; + p->enc_type = tmpl->enc_type; + alg->cra_ctxsize = sizeof(struct n2_cipher_context); + alg->cra_type = &crypto_ablkcipher_type; + alg->cra_u.ablkcipher = tmpl->ablkcipher; + alg->cra_init = n2_cipher_cra_init; + alg->cra_module = THIS_MODULE; + + list_add(&p->entry, &cipher_algs); + err = crypto_register_alg(alg); + if (err) { + list_del(&p->entry); + kfree(p); + } + return err; +} + +static int __devinit __n2_register_one_ahash(const struct n2_hash_tmpl *tmpl) +{ + struct n2_ahash_alg *p = kzalloc(sizeof(*p), GFP_KERNEL); + struct hash_alg_common *halg; + struct crypto_alg *base; + struct ahash_alg *ahash; + int err; + + if (!p) + return -ENOMEM; + + ahash = &p->alg; + ahash->init = n2_hash_async_init; + ahash->update = n2_hash_async_update; + ahash->final = n2_hash_async_final; + ahash->finup = n2_hash_async_finup; + ahash->digest = tmpl->digest; + + halg = &ahash->halg; + halg->digestsize = tmpl->digest_size; + + base = &halg->base; + snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, "%s", tmpl->name); + snprintf(base->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s-n2", tmpl->name); + base->cra_priority = N2_CRA_PRIORITY; + base->cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_NEED_FALLBACK; + base->cra_blocksize = tmpl->block_size; + base->cra_ctxsize = sizeof(struct n2_hash_ctx); + base->cra_module = THIS_MODULE; + base->cra_init = n2_hash_cra_init; + base->cra_exit = n2_hash_cra_exit; + + list_add(&p->entry, &ahash_algs); + err = crypto_register_ahash(ahash); + if (err) { + list_del(&p->entry); + kfree(p); + } + return err; +} + +static int __devinit n2_register_algs(void) +{ + int i, err = 0; + + mutex_lock(&spu_lock); + if (algs_registered++) + goto out; + + for (i = 0; i < NUM_HASH_TMPLS; i++) { + err = __n2_register_one_ahash(&hash_tmpls[i]); + if (err) { + __n2_unregister_algs(); + goto out; + } + } + for (i = 0; i < NUM_CIPHER_TMPLS; i++) { + err = __n2_register_one_cipher(&cipher_tmpls[i]); + if (err) { + __n2_unregister_algs(); + goto out; + } + } + +out: + mutex_unlock(&spu_lock); + return err; +} + +static void __exit n2_unregister_algs(void) +{ + mutex_lock(&spu_lock); + if (!--algs_registered) + __n2_unregister_algs(); + mutex_unlock(&spu_lock); +} + +/* To map CWQ queues to interrupt sources, the hypervisor API provides + * a devino. This isn't very useful to us because all of the + * interrupts listed in the of_device node have been translated to + * Linux virtual IRQ cookie numbers. + * + * So we have to back-translate, going through the 'intr' and 'ino' + * property tables of the n2cp MDESC node, matching it with the OF + * 'interrupts' property entries, in order to to figure out which + * devino goes to which already-translated IRQ. + */ +static int find_devino_index(struct of_device *dev, struct spu_mdesc_info *ip, + unsigned long dev_ino) +{ + const unsigned int *dev_intrs; + unsigned int intr; + int i; + + for (i = 0; i < ip->num_intrs; i++) { + if (ip->ino_table[i].ino == dev_ino) + break; + } + if (i == ip->num_intrs) + return -ENODEV; + + intr = ip->ino_table[i].intr; + + dev_intrs = of_get_property(dev->node, "interrupts", NULL); + if (!dev_intrs) + return -ENODEV; + + for (i = 0; i < dev->num_irqs; i++) { + if (dev_intrs[i] == intr) + return i; + } + + return -ENODEV; +} + +static int spu_map_ino(struct of_device *dev, struct spu_mdesc_info *ip, + const char *irq_name, struct spu_queue *p, + irq_handler_t handler) +{ + unsigned long herr; + int index; + + herr = sun4v_ncs_qhandle_to_devino(p->qhandle, &p->devino); + if (herr) + return -EINVAL; + + index = find_devino_index(dev, ip, p->devino); + if (index < 0) + return index; + + p->irq = dev->irqs[index]; + + sprintf(p->irq_name, "%s-%d", irq_name, index); + + return request_irq(p->irq, handler, IRQF_SAMPLE_RANDOM, + p->irq_name, p); +} + +static struct kmem_cache *queue_cache[2]; + +static void *new_queue(unsigned long q_type) +{ + return kmem_cache_zalloc(queue_cache[q_type - 1], GFP_KERNEL); +} + +static void free_queue(void *p, unsigned long q_type) +{ + return kmem_cache_free(queue_cache[q_type - 1], p); +} + +static int queue_cache_init(void) +{ + if (!queue_cache[HV_NCS_QTYPE_MAU - 1]) + queue_cache[HV_NCS_QTYPE_MAU - 1] = + kmem_cache_create("cwq_queue", + (MAU_NUM_ENTRIES * + MAU_ENTRY_SIZE), + MAU_ENTRY_SIZE, 0, NULL); + if (!queue_cache[HV_NCS_QTYPE_MAU - 1]) + return -ENOMEM; + + if (!queue_cache[HV_NCS_QTYPE_CWQ - 1]) + queue_cache[HV_NCS_QTYPE_CWQ - 1] = + kmem_cache_create("cwq_queue", + (CWQ_NUM_ENTRIES * + CWQ_ENTRY_SIZE), + CWQ_ENTRY_SIZE, 0, NULL); + if (!queue_cache[HV_NCS_QTYPE_CWQ - 1]) { + kmem_cache_destroy(queue_cache[HV_NCS_QTYPE_MAU - 1]); + return -ENOMEM; + } + return 0; +} + +static void queue_cache_destroy(void) +{ + kmem_cache_destroy(queue_cache[HV_NCS_QTYPE_MAU - 1]); + kmem_cache_destroy(queue_cache[HV_NCS_QTYPE_CWQ - 1]); +} + +static int spu_queue_register(struct spu_queue *p, unsigned long q_type) +{ + cpumask_var_t old_allowed; + unsigned long hv_ret; + + if (cpumask_empty(&p->sharing)) + return -EINVAL; + + if (!alloc_cpumask_var(&old_allowed, GFP_KERNEL)) + return -ENOMEM; + + cpumask_copy(old_allowed, ¤t->cpus_allowed); + + set_cpus_allowed_ptr(current, &p->sharing); + + hv_ret = sun4v_ncs_qconf(q_type, __pa(p->q), + CWQ_NUM_ENTRIES, &p->qhandle); + if (!hv_ret) + sun4v_ncs_sethead_marker(p->qhandle, 0); + + set_cpus_allowed_ptr(current, old_allowed); + + free_cpumask_var(old_allowed); + + return (hv_ret ? -EINVAL : 0); +} + +static int spu_queue_setup(struct spu_queue *p) +{ + int err; + + p->q = new_queue(p->q_type); + if (!p->q) + return -ENOMEM; + + err = spu_queue_register(p, p->q_type); + if (err) { + free_queue(p->q, p->q_type); + p->q = NULL; + } + + return err; +} + +static void spu_queue_destroy(struct spu_queue *p) +{ + unsigned long hv_ret; + + if (!p->q) + return; + + hv_ret = sun4v_ncs_qconf(p->q_type, p->qhandle, 0, &p->qhandle); + + if (!hv_ret) + free_queue(p->q, p->q_type); +} + +static void spu_list_destroy(struct list_head *list) +{ + struct spu_queue *p, *n; + + list_for_each_entry_safe(p, n, list, list) { + int i; + + for (i = 0; i < NR_CPUS; i++) { + if (cpu_to_cwq[i] == p) + cpu_to_cwq[i] = NULL; + } + + if (p->irq) { + free_irq(p->irq, p); + p->irq = 0; + } + spu_queue_destroy(p); + list_del(&p->list); + kfree(p); + } +} + +/* Walk the backward arcs of a CWQ 'exec-unit' node, + * gathering cpu membership information. + */ +static int spu_mdesc_walk_arcs(struct mdesc_handle *mdesc, + struct of_device *dev, + u64 node, struct spu_queue *p, + struct spu_queue **table) +{ + u64 arc; + + mdesc_for_each_arc(arc, mdesc, node, MDESC_ARC_TYPE_BACK) { + u64 tgt = mdesc_arc_target(mdesc, arc); + const char *name = mdesc_node_name(mdesc, tgt); + const u64 *id; + + if (strcmp(name, "cpu")) + continue; + id = mdesc_get_property(mdesc, tgt, "id", NULL); + if (table[*id] != NULL) { + dev_err(&dev->dev, "%s: SPU cpu slot already set.\n", + dev->node->full_name); + return -EINVAL; + } + cpu_set(*id, p->sharing); + table[*id] = p; + } + return 0; +} + +/* Process an 'exec-unit' MDESC node of type 'cwq'. */ +static int handle_exec_unit(struct spu_mdesc_info *ip, struct list_head *list, + struct of_device *dev, struct mdesc_handle *mdesc, + u64 node, const char *iname, unsigned long q_type, + irq_handler_t handler, struct spu_queue **table) +{ + struct spu_queue *p; + int err; + + p = kzalloc(sizeof(struct spu_queue), GFP_KERNEL); + if (!p) { + dev_err(&dev->dev, "%s: Could not allocate SPU queue.\n", + dev->node->full_name); + return -ENOMEM; + } + + cpus_clear(p->sharing); + spin_lock_init(&p->lock); + p->q_type = q_type; + INIT_LIST_HEAD(&p->jobs); + list_add(&p->list, list); + + err = spu_mdesc_walk_arcs(mdesc, dev, node, p, table); + if (err) + return err; + + err = spu_queue_setup(p); + if (err) + return err; + + return spu_map_ino(dev, ip, iname, p, handler); +} + +static int spu_mdesc_scan(struct mdesc_handle *mdesc, struct of_device *dev, + struct spu_mdesc_info *ip, struct list_head *list, + const char *exec_name, unsigned long q_type, + irq_handler_t handler, struct spu_queue **table) +{ + int err = 0; + u64 node; + + mdesc_for_each_node_by_name(mdesc, node, "exec-unit") { + const char *type; + + type = mdesc_get_property(mdesc, node, "type", NULL); + if (!type || strcmp(type, exec_name)) + continue; + + err = handle_exec_unit(ip, list, dev, mdesc, node, + exec_name, q_type, handler, table); + if (err) { + spu_list_destroy(list); + break; + } + } + + return err; +} + +static int __devinit get_irq_props(struct mdesc_handle *mdesc, u64 node, + struct spu_mdesc_info *ip) +{ + const u64 *intr, *ino; + int intr_len, ino_len; + int i; + + intr = mdesc_get_property(mdesc, node, "intr", &intr_len); + if (!intr) + return -ENODEV; + + ino = mdesc_get_property(mdesc, node, "ino", &ino_len); + if (!intr) + return -ENODEV; + + if (intr_len != ino_len) + return -EINVAL; + + ip->num_intrs = intr_len / sizeof(u64); + ip->ino_table = kzalloc((sizeof(struct ino_blob) * + ip->num_intrs), + GFP_KERNEL); + if (!ip->ino_table) + return -ENOMEM; + + for (i = 0; i < ip->num_intrs; i++) { + struct ino_blob *b = &ip->ino_table[i]; + b->intr = intr[i]; + b->ino = ino[i]; + } + + return 0; +} + +static int __devinit grab_mdesc_irq_props(struct mdesc_handle *mdesc, + struct of_device *dev, + struct spu_mdesc_info *ip, + const char *node_name) +{ + const unsigned int *reg; + u64 node; + + reg = of_get_property(dev->node, "reg", NULL); + if (!reg) + return -ENODEV; + + mdesc_for_each_node_by_name(mdesc, node, "virtual-device") { + const char *name; + const u64 *chdl; + + name = mdesc_get_property(mdesc, node, "name", NULL); + if (!name || strcmp(name, node_name)) + continue; + chdl = mdesc_get_property(mdesc, node, "cfg-handle", NULL); + if (!chdl || (*chdl != *reg)) + continue; + ip->cfg_handle = *chdl; + return get_irq_props(mdesc, node, ip); + } + + return -ENODEV; +} + +static unsigned long n2_spu_hvapi_major; +static unsigned long n2_spu_hvapi_minor; + +static int __devinit n2_spu_hvapi_register(void) +{ + int err; + + n2_spu_hvapi_major = 2; + n2_spu_hvapi_minor = 0; + + err = sun4v_hvapi_register(HV_GRP_NCS, + n2_spu_hvapi_major, + &n2_spu_hvapi_minor); + + if (!err) + pr_info("Registered NCS HVAPI version %lu.%lu\n", + n2_spu_hvapi_major, + n2_spu_hvapi_minor); + + return err; +} + +static void n2_spu_hvapi_unregister(void) +{ + sun4v_hvapi_unregister(HV_GRP_NCS); +} + +static int global_ref; + +static int __devinit grab_global_resources(void) +{ + int err = 0; + + mutex_lock(&spu_lock); + + if (global_ref++) + goto out; + + err = n2_spu_hvapi_register(); + if (err) + goto out; + + err = queue_cache_init(); + if (err) + goto out_hvapi_release; + + err = -ENOMEM; + cpu_to_cwq = kzalloc(sizeof(struct spu_queue *) * NR_CPUS, + GFP_KERNEL); + if (!cpu_to_cwq) + goto out_queue_cache_destroy; + + cpu_to_mau = kzalloc(sizeof(struct spu_queue *) * NR_CPUS, + GFP_KERNEL); + if (!cpu_to_mau) + goto out_free_cwq_table; + + err = 0; + +out: + if (err) + global_ref--; + mutex_unlock(&spu_lock); + return err; + +out_free_cwq_table: + kfree(cpu_to_cwq); + cpu_to_cwq = NULL; + +out_queue_cache_destroy: + queue_cache_destroy(); + +out_hvapi_release: + n2_spu_hvapi_unregister(); + goto out; +} + +static void release_global_resources(void) +{ + mutex_lock(&spu_lock); + if (!--global_ref) { + kfree(cpu_to_cwq); + cpu_to_cwq = NULL; + + kfree(cpu_to_mau); + cpu_to_mau = NULL; + + queue_cache_destroy(); + n2_spu_hvapi_unregister(); + } + mutex_unlock(&spu_lock); +} + +static struct n2_crypto * __devinit alloc_n2cp(void) +{ + struct n2_crypto *np = kzalloc(sizeof(struct n2_crypto), GFP_KERNEL); + + if (np) + INIT_LIST_HEAD(&np->cwq_list); + + return np; +} + +static void free_n2cp(struct n2_crypto *np) +{ + if (np->cwq_info.ino_table) { + kfree(np->cwq_info.ino_table); + np->cwq_info.ino_table = NULL; + } + + kfree(np); +} + +static void __devinit n2_spu_driver_version(void) +{ + static int n2_spu_version_printed; + + if (n2_spu_version_printed++ == 0) + pr_info("%s", version); +} + +static int __devinit n2_crypto_probe(struct of_device *dev, + const struct of_device_id *match) +{ + struct mdesc_handle *mdesc; + const char *full_name; + struct n2_crypto *np; + int err; + + n2_spu_driver_version(); + + full_name = dev->node->full_name; + pr_info("Found N2CP at %s\n", full_name); + + np = alloc_n2cp(); + if (!np) { + dev_err(&dev->dev, "%s: Unable to allocate n2cp.\n", + full_name); + return -ENOMEM; + } + + err = grab_global_resources(); + if (err) { + dev_err(&dev->dev, "%s: Unable to grab " + "global resources.\n", full_name); + goto out_free_n2cp; + } + + mdesc = mdesc_grab(); + + if (!mdesc) { + dev_err(&dev->dev, "%s: Unable to grab MDESC.\n", + full_name); + err = -ENODEV; + goto out_free_global; + } + err = grab_mdesc_irq_props(mdesc, dev, &np->cwq_info, "n2cp"); + if (err) { + dev_err(&dev->dev, "%s: Unable to grab IRQ props.\n", + full_name); + mdesc_release(mdesc); + goto out_free_global; + } + + err = spu_mdesc_scan(mdesc, dev, &np->cwq_info, &np->cwq_list, + "cwq", HV_NCS_QTYPE_CWQ, cwq_intr, + cpu_to_cwq); + mdesc_release(mdesc); + + if (err) { + dev_err(&dev->dev, "%s: CWQ MDESC scan failed.\n", + full_name); + goto out_free_global; + } + + err = n2_register_algs(); + if (err) { + dev_err(&dev->dev, "%s: Unable to register algorithms.\n", + full_name); + goto out_free_spu_list; + } + + dev_set_drvdata(&dev->dev, np); + + return 0; + +out_free_spu_list: + spu_list_destroy(&np->cwq_list); + +out_free_global: + release_global_resources(); + +out_free_n2cp: + free_n2cp(np); + + return err; +} + +static int __devexit n2_crypto_remove(struct of_device *dev) +{ + struct n2_crypto *np = dev_get_drvdata(&dev->dev); + + n2_unregister_algs(); + + spu_list_destroy(&np->cwq_list); + + release_global_resources(); + + free_n2cp(np); + + return 0; +} + +static struct n2_mau * __devinit alloc_ncp(void) +{ + struct n2_mau *mp = kzalloc(sizeof(struct n2_mau), GFP_KERNEL); + + if (mp) + INIT_LIST_HEAD(&mp->mau_list); + + return mp; +} + +static void free_ncp(struct n2_mau *mp) +{ + if (mp->mau_info.ino_table) { + kfree(mp->mau_info.ino_table); + mp->mau_info.ino_table = NULL; + } + + kfree(mp); +} + +static int __devinit n2_mau_probe(struct of_device *dev, + const struct of_device_id *match) +{ + struct mdesc_handle *mdesc; + const char *full_name; + struct n2_mau *mp; + int err; + + n2_spu_driver_version(); + + full_name = dev->node->full_name; + pr_info("Found NCP at %s\n", full_name); + + mp = alloc_ncp(); + if (!mp) { + dev_err(&dev->dev, "%s: Unable to allocate ncp.\n", + full_name); + return -ENOMEM; + } + + err = grab_global_resources(); + if (err) { + dev_err(&dev->dev, "%s: Unable to grab " + "global resources.\n", full_name); + goto out_free_ncp; + } + + mdesc = mdesc_grab(); + + if (!mdesc) { + dev_err(&dev->dev, "%s: Unable to grab MDESC.\n", + full_name); + err = -ENODEV; + goto out_free_global; + } + + err = grab_mdesc_irq_props(mdesc, dev, &mp->mau_info, "ncp"); + if (err) { + dev_err(&dev->dev, "%s: Unable to grab IRQ props.\n", + full_name); + mdesc_release(mdesc); + goto out_free_global; + } + + err = spu_mdesc_scan(mdesc, dev, &mp->mau_info, &mp->mau_list, + "mau", HV_NCS_QTYPE_MAU, mau_intr, + cpu_to_mau); + mdesc_release(mdesc); + + if (err) { + dev_err(&dev->dev, "%s: MAU MDESC scan failed.\n", + full_name); + goto out_free_global; + } + + dev_set_drvdata(&dev->dev, mp); + + return 0; + +out_free_global: + release_global_resources(); + +out_free_ncp: + free_ncp(mp); + + return err; +} + +static int __devexit n2_mau_remove(struct of_device *dev) +{ + struct n2_mau *mp = dev_get_drvdata(&dev->dev); + + spu_list_destroy(&mp->mau_list); + + release_global_resources(); + + free_ncp(mp); + + return 0; +} + +static struct of_device_id n2_crypto_match[] = { + { + .name = "n2cp", + .compatible = "SUNW,n2-cwq", + }, + { + .name = "n2cp", + .compatible = "SUNW,vf-cwq", + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, n2_crypto_match); + +static struct of_platform_driver n2_crypto_driver = { + .name = "n2cp", + .match_table = n2_crypto_match, + .probe = n2_crypto_probe, + .remove = __devexit_p(n2_crypto_remove), +}; + +static struct of_device_id n2_mau_match[] = { + { + .name = "ncp", + .compatible = "SUNW,n2-mau", + }, + { + .name = "ncp", + .compatible = "SUNW,vf-mau", + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, n2_mau_match); + +static struct of_platform_driver n2_mau_driver = { + .name = "ncp", + .match_table = n2_mau_match, + .probe = n2_mau_probe, + .remove = __devexit_p(n2_mau_remove), +}; + +static int __init n2_init(void) +{ + int err = of_register_driver(&n2_crypto_driver, &of_bus_type); + + if (!err) { + err = of_register_driver(&n2_mau_driver, &of_bus_type); + if (err) + of_unregister_driver(&n2_crypto_driver); + } + return err; +} + +static void __exit n2_exit(void) +{ + of_unregister_driver(&n2_mau_driver); + of_unregister_driver(&n2_crypto_driver); +} + +module_init(n2_init); +module_exit(n2_exit); diff --git a/drivers/crypto/n2_core.h b/drivers/crypto/n2_core.h new file mode 100644 index 000000000000..4bcbbeae98f5 --- /dev/null +++ b/drivers/crypto/n2_core.h @@ -0,0 +1,231 @@ +#ifndef _N2_CORE_H +#define _N2_CORE_H + +#ifndef __ASSEMBLY__ + +struct ino_blob { + u64 intr; + u64 ino; +}; + +struct spu_mdesc_info { + u64 cfg_handle; + struct ino_blob *ino_table; + int num_intrs; +}; + +struct n2_crypto { + struct spu_mdesc_info cwq_info; + struct list_head cwq_list; +}; + +struct n2_mau { + struct spu_mdesc_info mau_info; + struct list_head mau_list; +}; + +#define CWQ_ENTRY_SIZE 64 +#define CWQ_NUM_ENTRIES 64 + +#define MAU_ENTRY_SIZE 64 +#define MAU_NUM_ENTRIES 64 + +struct cwq_initial_entry { + u64 control; + u64 src_addr; + u64 auth_key_addr; + u64 auth_iv_addr; + u64 final_auth_state_addr; + u64 enc_key_addr; + u64 enc_iv_addr; + u64 dest_addr; +}; + +struct cwq_ext_entry { + u64 len; + u64 src_addr; + u64 resv1; + u64 resv2; + u64 resv3; + u64 resv4; + u64 resv5; + u64 resv6; +}; + +struct cwq_final_entry { + u64 control; + u64 src_addr; + u64 resv1; + u64 resv2; + u64 resv3; + u64 resv4; + u64 resv5; + u64 resv6; +}; + +#define CONTROL_LEN 0x000000000000ffffULL +#define CONTROL_LEN_SHIFT 0 +#define CONTROL_HMAC_KEY_LEN 0x0000000000ff0000ULL +#define CONTROL_HMAC_KEY_LEN_SHIFT 16 +#define CONTROL_ENC_TYPE 0x00000000ff000000ULL +#define CONTROL_ENC_TYPE_SHIFT 24 +#define ENC_TYPE_ALG_RC4_STREAM 0x00ULL +#define ENC_TYPE_ALG_RC4_NOSTREAM 0x04ULL +#define ENC_TYPE_ALG_DES 0x08ULL +#define ENC_TYPE_ALG_3DES 0x0cULL +#define ENC_TYPE_ALG_AES128 0x10ULL +#define ENC_TYPE_ALG_AES192 0x14ULL +#define ENC_TYPE_ALG_AES256 0x18ULL +#define ENC_TYPE_ALG_RESERVED 0x1cULL +#define ENC_TYPE_ALG_MASK 0x1cULL +#define ENC_TYPE_CHAINING_ECB 0x00ULL +#define ENC_TYPE_CHAINING_CBC 0x01ULL +#define ENC_TYPE_CHAINING_CFB 0x02ULL +#define ENC_TYPE_CHAINING_COUNTER 0x03ULL +#define ENC_TYPE_CHAINING_MASK 0x03ULL +#define CONTROL_AUTH_TYPE 0x0000001f00000000ULL +#define CONTROL_AUTH_TYPE_SHIFT 32 +#define AUTH_TYPE_RESERVED 0x00ULL +#define AUTH_TYPE_MD5 0x01ULL +#define AUTH_TYPE_SHA1 0x02ULL +#define AUTH_TYPE_SHA256 0x03ULL +#define AUTH_TYPE_CRC32 0x04ULL +#define AUTH_TYPE_HMAC_MD5 0x05ULL +#define AUTH_TYPE_HMAC_SHA1 0x06ULL +#define AUTH_TYPE_HMAC_SHA256 0x07ULL +#define AUTH_TYPE_TCP_CHECKSUM 0x08ULL +#define AUTH_TYPE_SSL_HMAC_MD5 0x09ULL +#define AUTH_TYPE_SSL_HMAC_SHA1 0x0aULL +#define AUTH_TYPE_SSL_HMAC_SHA256 0x0bULL +#define CONTROL_STRAND 0x000000e000000000ULL +#define CONTROL_STRAND_SHIFT 37 +#define CONTROL_HASH_LEN 0x0000ff0000000000ULL +#define CONTROL_HASH_LEN_SHIFT 40 +#define CONTROL_INTERRUPT 0x0001000000000000ULL +#define CONTROL_STORE_FINAL_AUTH_STATE 0x0002000000000000ULL +#define CONTROL_RESERVED 0x001c000000000000ULL +#define CONTROL_HV_DONE 0x0004000000000000ULL +#define CONTROL_HV_PROTOCOL_ERROR 0x0008000000000000ULL +#define CONTROL_HV_HARDWARE_ERROR 0x0010000000000000ULL +#define CONTROL_END_OF_BLOCK 0x0020000000000000ULL +#define CONTROL_START_OF_BLOCK 0x0040000000000000ULL +#define CONTROL_ENCRYPT 0x0080000000000000ULL +#define CONTROL_OPCODE 0xff00000000000000ULL +#define CONTROL_OPCODE_SHIFT 56 +#define OPCODE_INPLACE_BIT 0x80ULL +#define OPCODE_SSL_KEYBLOCK 0x10ULL +#define OPCODE_COPY 0x20ULL +#define OPCODE_ENCRYPT 0x40ULL +#define OPCODE_AUTH_MAC 0x41ULL + +#endif /* !(__ASSEMBLY__) */ + +/* NCS v2.0 hypervisor interfaces */ +#define HV_NCS_QTYPE_MAU 0x01 +#define HV_NCS_QTYPE_CWQ 0x02 + +/* ncs_qconf() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_NCS_QCONF + * ARG0: Queue type (HV_NCS_QTYPE_{MAU,CWQ}) + * ARG1: Real address of queue, or handle for unconfigure + * ARG2: Number of entries in queue, zero for unconfigure + * RET0: status + * RET1: queue handle + * + * Configure a queue in the stream processing unit. + * + * The real address given as the base must be 64-byte + * aligned. + * + * The queue size can range from a minimum of 2 to a maximum + * of 64. The queue size must be a power of two. + * + * To unconfigure a queue, specify a length of zero and place + * the queue handle into ARG1. + * + * On configure success the hypervisor will set the FIRST, HEAD, + * and TAIL registers to the address of the first entry in the + * queue. The LAST register will be set to point to the last + * entry in the queue. + */ +#define HV_FAST_NCS_QCONF 0x111 + +/* ncs_qinfo() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_NCS_QINFO + * ARG0: Queue handle + * RET0: status + * RET1: Queue type (HV_NCS_QTYPE_{MAU,CWQ}) + * RET2: Queue base address + * RET3: Number of entries + */ +#define HV_FAST_NCS_QINFO 0x112 + +/* ncs_gethead() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_NCS_GETHEAD + * ARG0: Queue handle + * RET0: status + * RET1: queue head offset + */ +#define HV_FAST_NCS_GETHEAD 0x113 + +/* ncs_gettail() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_NCS_GETTAIL + * ARG0: Queue handle + * RET0: status + * RET1: queue tail offset + */ +#define HV_FAST_NCS_GETTAIL 0x114 + +/* ncs_settail() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_NCS_SETTAIL + * ARG0: Queue handle + * ARG1: New tail offset + * RET0: status + */ +#define HV_FAST_NCS_SETTAIL 0x115 + +/* ncs_qhandle_to_devino() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_NCS_QHANDLE_TO_DEVINO + * ARG0: Queue handle + * RET0: status + * RET1: devino + */ +#define HV_FAST_NCS_QHANDLE_TO_DEVINO 0x116 + +/* ncs_sethead_marker() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_NCS_SETHEAD_MARKER + * ARG0: Queue handle + * ARG1: New head offset + * RET0: status + */ +#define HV_FAST_NCS_SETHEAD_MARKER 0x117 + +#ifndef __ASSEMBLY__ +extern unsigned long sun4v_ncs_qconf(unsigned long queue_type, + unsigned long queue_ra, + unsigned long num_entries, + unsigned long *qhandle); +extern unsigned long sun4v_ncs_qinfo(unsigned long qhandle, + unsigned long *queue_type, + unsigned long *queue_ra, + unsigned long *num_entries); +extern unsigned long sun4v_ncs_gethead(unsigned long qhandle, + unsigned long *head); +extern unsigned long sun4v_ncs_gettail(unsigned long qhandle, + unsigned long *tail); +extern unsigned long sun4v_ncs_settail(unsigned long qhandle, + unsigned long tail); +extern unsigned long sun4v_ncs_qhandle_to_devino(unsigned long qhandle, + unsigned long *devino); +extern unsigned long sun4v_ncs_sethead_marker(unsigned long qhandle, + unsigned long head); +#endif /* !(__ASSEMBLY__) */ + +#endif /* _N2_CORE_H */ -- cgit v1.2.3 From 3a8663ee6171e1e61f5c139ed65aa0a769380f00 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 3 Apr 2010 19:37:23 +0100 Subject: intel-iommu: Combine the BIOS DMAR table warning messages We have nearly the same code for warnings repeated four times. Move it into a separate function. Signed-off-by: Ben Hutchings Signed-off-by: David Woodhouse --- drivers/pci/dmar.c | 48 ++++++++++++++---------------------------------- 1 file changed, 14 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 7771b2dd5978..1959cdadad51 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -618,7 +618,15 @@ int __init dmar_table_init(void) return 0; } -static int bios_warned; +static void warn_invalid_dmar(u64 addr, const char *message) +{ + WARN_ONCE(1, "Your BIOS is broken; DMAR reported at address %llx%s!\n" + "BIOS vendor: %s; Ver: %s; Product Version: %s\n", + addr, message, + dmi_get_system_info(DMI_BIOS_VENDOR), + dmi_get_system_info(DMI_BIOS_VERSION), + dmi_get_system_info(DMI_PRODUCT_VERSION)); +} int __init check_zero_address(void) { @@ -644,13 +652,7 @@ int __init check_zero_address(void) drhd = (void *)entry_header; if (!drhd->address) { - /* Promote an attitude of violence to a BIOS engineer today */ - WARN(1, "Your BIOS is broken; DMAR reported at address zero!\n" - "BIOS vendor: %s; Ver: %s; Product Version: %s\n", - dmi_get_system_info(DMI_BIOS_VENDOR), - dmi_get_system_info(DMI_BIOS_VERSION), - dmi_get_system_info(DMI_PRODUCT_VERSION)); - bios_warned = 1; + warn_invalid_dmar(0, ""); goto failed; } @@ -663,14 +665,8 @@ int __init check_zero_address(void) ecap = dmar_readq(addr + DMAR_ECAP_REG); early_iounmap(addr, VTD_PAGE_SIZE); if (cap == (uint64_t)-1 && ecap == (uint64_t)-1) { - /* Promote an attitude of violence to a BIOS engineer today */ - WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n" - "BIOS vendor: %s; Ver: %s; Product Version: %s\n", - drhd->address, - dmi_get_system_info(DMI_BIOS_VENDOR), - dmi_get_system_info(DMI_BIOS_VERSION), - dmi_get_system_info(DMI_PRODUCT_VERSION)); - bios_warned = 1; + warn_invalid_dmar(drhd->address, + " returns all ones"); goto failed; } } @@ -735,14 +731,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) int msagaw = 0; if (!drhd->reg_base_addr) { - if (!bios_warned) { - WARN(1, "Your BIOS is broken; DMAR reported at address zero!\n" - "BIOS vendor: %s; Ver: %s; Product Version: %s\n", - dmi_get_system_info(DMI_BIOS_VENDOR), - dmi_get_system_info(DMI_BIOS_VERSION), - dmi_get_system_info(DMI_PRODUCT_VERSION)); - bios_warned = 1; - } + warn_invalid_dmar(0, ""); return -EINVAL; } @@ -762,16 +751,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) { - if (!bios_warned) { - /* Promote an attitude of violence to a BIOS engineer today */ - WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n" - "BIOS vendor: %s; Ver: %s; Product Version: %s\n", - drhd->reg_base_addr, - dmi_get_system_info(DMI_BIOS_VENDOR), - dmi_get_system_info(DMI_BIOS_VERSION), - dmi_get_system_info(DMI_PRODUCT_VERSION)); - bios_warned = 1; - } + warn_invalid_dmar(drhd->reg_base_addr, " returns all ones"); goto err_unmap; } -- cgit v1.2.3 From fd0c8894893cba722bdea12de25b49f980795d06 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 3 Apr 2010 19:38:43 +0100 Subject: intel-iommu: Set a more specific taint flag for invalid BIOS DMAR tables We now know how to deal with these tables so that they are harmless. Set TAINT_FIRMWARE_WORKAROUND instead of the default TAINT_WARN. Signed-off-by: Ben Hutchings Signed-off-by: David Woodhouse --- drivers/pci/dmar.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 1959cdadad51..f4c51709d132 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -360,12 +360,14 @@ dmar_parse_one_rhsa(struct acpi_dmar_header *header) return 0; } } - WARN(1, "Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n" - "BIOS vendor: %s; Ver: %s; Product Version: %s\n", - drhd->reg_base_addr, - dmi_get_system_info(DMI_BIOS_VENDOR), - dmi_get_system_info(DMI_BIOS_VERSION), - dmi_get_system_info(DMI_PRODUCT_VERSION)); + WARN_TAINT( + 1, TAINT_FIRMWARE_WORKAROUND, + "Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n" + "BIOS vendor: %s; Ver: %s; Product Version: %s\n", + drhd->reg_base_addr, + dmi_get_system_info(DMI_BIOS_VENDOR), + dmi_get_system_info(DMI_BIOS_VERSION), + dmi_get_system_info(DMI_PRODUCT_VERSION)); return 0; } @@ -620,12 +622,14 @@ int __init dmar_table_init(void) static void warn_invalid_dmar(u64 addr, const char *message) { - WARN_ONCE(1, "Your BIOS is broken; DMAR reported at address %llx%s!\n" - "BIOS vendor: %s; Ver: %s; Product Version: %s\n", - addr, message, - dmi_get_system_info(DMI_BIOS_VENDOR), - dmi_get_system_info(DMI_BIOS_VERSION), - dmi_get_system_info(DMI_PRODUCT_VERSION)); + WARN_TAINT_ONCE( + 1, TAINT_FIRMWARE_WORKAROUND, + "Your BIOS is broken; DMAR reported at address %llx%s!\n" + "BIOS vendor: %s; Ver: %s; Product Version: %s\n", + addr, message, + dmi_get_system_info(DMI_BIOS_VENDOR), + dmi_get_system_info(DMI_BIOS_VERSION), + dmi_get_system_info(DMI_PRODUCT_VERSION)); } int __init check_zero_address(void) -- cgit v1.2.3 From 031ffd1711bd8bf334ebcbe8ebe34845e6d4678f Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 19 May 2010 17:33:38 -0600 Subject: hisax_fcpcipnp: fix broken isapnp device table. Found that drivers/isdn/hisax/hisax_fcpcipnp.c has broken pnp device table - wrong type (isapnp instead of pnp) and also ending record missing. Signed-off-by: Ondrej Zary Signed-off-by: Rusty Russell (split patch) --- drivers/isdn/hisax/hisax_fcpcipnp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c index 1925118122f8..8b0a7d86b30f 100644 --- a/drivers/isdn/hisax/hisax_fcpcipnp.c +++ b/drivers/isdn/hisax/hisax_fcpcipnp.c @@ -74,9 +74,10 @@ static struct pnp_device_id fcpnp_ids[] __devinitdata = { .id = "AVM0900", .driver_data = (unsigned long) "Fritz!Card PnP", }, + { .id = "" } }; -MODULE_DEVICE_TABLE(isapnp, fcpnp_ids); +MODULE_DEVICE_TABLE(pnp, fcpnp_ids); #endif static int protocol = 2; /* EURO-ISDN Default */ -- cgit v1.2.3 From 5f487cd34f4337f9bc27ca19da72a39d1b0a0ab4 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 18 May 2010 21:49:51 +0200 Subject: power_supply: Use attribute groups This fixes a race between power supply device and initial attributes creation, plus makes it possible to implement writable properties. [Daniel Mack - removed superflous return statement and dropped .mode attribute from POWER_SUPPLY_ATTR] Suggested-by: Greg KH Suggested-by: Kay Sievers Signed-off-by: Anton Vorontsov Tested-by: Daniel Mack --- drivers/power/power_supply.h | 7 +-- drivers/power/power_supply_core.c | 48 +++++++++++----- drivers/power/power_supply_sysfs.c | 115 ++++++++++++------------------------- include/linux/power_supply.h | 1 + 4 files changed, 75 insertions(+), 96 deletions(-) (limited to 'drivers') diff --git a/drivers/power/power_supply.h b/drivers/power/power_supply.h index f38ba482be75..018de2b26998 100644 --- a/drivers/power/power_supply.h +++ b/drivers/power/power_supply.h @@ -12,15 +12,12 @@ #ifdef CONFIG_SYSFS -extern int power_supply_create_attrs(struct power_supply *psy); -extern void power_supply_remove_attrs(struct power_supply *psy); +extern void power_supply_init_attrs(struct device_type *dev_type); extern int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env); #else -static inline int power_supply_create_attrs(struct power_supply *psy) -{ return 0; } -static inline void power_supply_remove_attrs(struct power_supply *psy) {} +static inline void power_supply_init_attrs(struct device_type *dev_type) {} #define power_supply_uevent NULL #endif /* CONFIG_SYSFS */ diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c index cce75b40b435..91606bb55318 100644 --- a/drivers/power/power_supply_core.c +++ b/drivers/power/power_supply_core.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +23,8 @@ struct class *power_supply_class; EXPORT_SYMBOL_GPL(power_supply_class); +static struct device_type power_supply_dev_type; + static int __power_supply_changed_work(struct device *dev, void *data) { struct power_supply *psy = (struct power_supply *)data; @@ -144,22 +147,39 @@ struct power_supply *power_supply_get_by_name(char *name) } EXPORT_SYMBOL_GPL(power_supply_get_by_name); +static void power_supply_dev_release(struct device *dev) +{ + pr_debug("device: '%s': %s\n", dev_name(dev), __func__); + kfree(dev); +} + int power_supply_register(struct device *parent, struct power_supply *psy) { - int rc = 0; + struct device *dev; + int rc; - psy->dev = device_create(power_supply_class, parent, 0, psy, - "%s", psy->name); - if (IS_ERR(psy->dev)) { - rc = PTR_ERR(psy->dev); - goto dev_create_failed; - } + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; - INIT_WORK(&psy->changed_work, power_supply_changed_work); + device_initialize(dev); - rc = power_supply_create_attrs(psy); + dev->class = power_supply_class; + dev->type = &power_supply_dev_type; + dev->parent = parent; + dev->release = power_supply_dev_release; + dev_set_drvdata(dev, psy); + psy->dev = dev; + + rc = kobject_set_name(&dev->kobj, "%s", psy->name); + if (rc) + goto kobject_set_name_failed; + + rc = device_add(dev); if (rc) - goto create_attrs_failed; + goto device_add_failed; + + INIT_WORK(&psy->changed_work, power_supply_changed_work); rc = power_supply_create_triggers(psy); if (rc) @@ -170,10 +190,10 @@ int power_supply_register(struct device *parent, struct power_supply *psy) goto success; create_triggers_failed: - power_supply_remove_attrs(psy); -create_attrs_failed: device_unregister(psy->dev); -dev_create_failed: +kobject_set_name_failed: +device_add_failed: + kfree(dev); success: return rc; } @@ -183,7 +203,6 @@ void power_supply_unregister(struct power_supply *psy) { flush_scheduled_work(); power_supply_remove_triggers(psy); - power_supply_remove_attrs(psy); device_unregister(psy->dev); } EXPORT_SYMBOL_GPL(power_supply_unregister); @@ -196,6 +215,7 @@ static int __init power_supply_class_init(void) return PTR_ERR(power_supply_class); power_supply_class->dev_uevent = power_supply_uevent; + power_supply_init_attrs(&power_supply_dev_type); return 0; } diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index 5b6e352ac7c1..7d7593cad7d9 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c @@ -31,7 +31,7 @@ #define POWER_SUPPLY_ATTR(_name) \ { \ - .attr = { .name = #_name, .mode = 0444 }, \ + .attr = { .name = #_name }, \ .show = power_supply_show_property, \ .store = NULL, \ } @@ -41,6 +41,9 @@ static struct device_attribute power_supply_attrs[]; static ssize_t power_supply_show_property(struct device *dev, struct device_attribute *attr, char *buf) { + static char *type_text[] = { + "Battery", "UPS", "Mains", "USB" + }; static char *status_text[] = { "Unknown", "Charging", "Discharging", "Not charging", "Full" }; @@ -58,12 +61,15 @@ static ssize_t power_supply_show_property(struct device *dev, static char *capacity_level_text[] = { "Unknown", "Critical", "Low", "Normal", "High", "Full" }; - ssize_t ret; + ssize_t ret = 0; struct power_supply *psy = dev_get_drvdata(dev); const ptrdiff_t off = attr - power_supply_attrs; union power_supply_propval value; - ret = psy->get_property(psy, off, &value); + if (off == POWER_SUPPLY_PROP_TYPE) + value.intval = psy->type; + else + ret = psy->get_property(psy, off, &value); if (ret < 0) { if (ret == -ENODATA) @@ -85,6 +91,8 @@ static ssize_t power_supply_show_property(struct device *dev, return sprintf(buf, "%s\n", technology_text[value.intval]); else if (off == POWER_SUPPLY_PROP_CAPACITY_LEVEL) return sprintf(buf, "%s\n", capacity_level_text[value.intval]); + else if (off == POWER_SUPPLY_PROP_TYPE) + return sprintf(buf, "%s\n", type_text[value.intval]); else if (off >= POWER_SUPPLY_PROP_MODEL_NAME) return sprintf(buf, "%s\n", value.strval); @@ -132,67 +140,50 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(time_to_empty_avg), POWER_SUPPLY_ATTR(time_to_full_now), POWER_SUPPLY_ATTR(time_to_full_avg), + POWER_SUPPLY_ATTR(type), /* Properties of type `const char *' */ POWER_SUPPLY_ATTR(model_name), POWER_SUPPLY_ATTR(manufacturer), POWER_SUPPLY_ATTR(serial_number), }; -static ssize_t power_supply_show_static_attrs(struct device *dev, - struct device_attribute *attr, - char *buf) { - static char *type_text[] = { "Battery", "UPS", "Mains", "USB" }; - struct power_supply *psy = dev_get_drvdata(dev); - - return sprintf(buf, "%s\n", type_text[psy->type]); -} - -static struct device_attribute power_supply_static_attrs[] = { - __ATTR(type, 0444, power_supply_show_static_attrs, NULL), -}; +static struct attribute * +__power_supply_attrs[ARRAY_SIZE(power_supply_attrs) + 1]; -int power_supply_create_attrs(struct power_supply *psy) +static mode_t power_supply_attr_is_visible(struct kobject *kobj, + struct attribute *attr, + int attrno) { - int rc = 0; - int i, j; - - for (i = 0; i < ARRAY_SIZE(power_supply_static_attrs); i++) { - rc = device_create_file(psy->dev, - &power_supply_static_attrs[i]); - if (rc) - goto statics_failed; - } + struct device *dev = container_of(kobj, struct device, kobj); + struct power_supply *psy = dev_get_drvdata(dev); + int i; - for (j = 0; j < psy->num_properties; j++) { - rc = device_create_file(psy->dev, - &power_supply_attrs[psy->properties[j]]); - if (rc) - goto dynamics_failed; + for (i = 0; i < psy->num_properties; i++) { + if (psy->properties[i] == attrno) + return 0444; } - goto succeed; - -dynamics_failed: - while (j--) - device_remove_file(psy->dev, - &power_supply_attrs[psy->properties[j]]); -statics_failed: - while (i--) - device_remove_file(psy->dev, &power_supply_static_attrs[i]); -succeed: - return rc; + return 0; } -void power_supply_remove_attrs(struct power_supply *psy) +static struct attribute_group power_supply_attr_group = { + .attrs = __power_supply_attrs, + .is_visible = power_supply_attr_is_visible, +}; + +static const struct attribute_group *power_supply_attr_groups[] = { + &power_supply_attr_group, + NULL, +}; + +void power_supply_init_attrs(struct device_type *dev_type) { int i; - for (i = 0; i < ARRAY_SIZE(power_supply_static_attrs); i++) - device_remove_file(psy->dev, &power_supply_static_attrs[i]); + dev_type->groups = power_supply_attr_groups; - for (i = 0; i < psy->num_properties; i++) - device_remove_file(psy->dev, - &power_supply_attrs[psy->properties[i]]); + for (i = 0; i < ARRAY_SIZE(power_supply_attrs); i++) + __power_supply_attrs[i] = &power_supply_attrs[i].attr; } static char *kstruprdup(const char *str, gfp_t gfp) @@ -236,36 +227,6 @@ int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env) if (!prop_buf) return -ENOMEM; - for (j = 0; j < ARRAY_SIZE(power_supply_static_attrs); j++) { - struct device_attribute *attr; - char *line; - - attr = &power_supply_static_attrs[j]; - - ret = power_supply_show_static_attrs(dev, attr, prop_buf); - if (ret < 0) - goto out; - - line = strchr(prop_buf, '\n'); - if (line) - *line = 0; - - attrname = kstruprdup(attr->attr.name, GFP_KERNEL); - if (!attrname) { - ret = -ENOMEM; - goto out; - } - - dev_dbg(dev, "Static prop %s=%s\n", attrname, prop_buf); - - ret = add_uevent_var(env, "POWER_SUPPLY_%s=%s", attrname, prop_buf); - kfree(attrname); - if (ret) - goto out; - } - - dev_dbg(dev, "%zd dynamic props\n", psy->num_properties); - for (j = 0; j < psy->num_properties; j++) { struct device_attribute *attr; char *line; diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index ebd2b8fb00d0..c5f73a3ab3ab 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -114,6 +114,7 @@ enum power_supply_property { POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, + POWER_SUPPLY_PROP_TYPE, /* use power_supply.type instead */ /* Properties of type `const char *' */ POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_MANUFACTURER, -- cgit v1.2.3 From 0011d2d4a5f7bb5666dcfb9f9b3dbdb084ab98f1 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 18 May 2010 21:49:52 +0200 Subject: power_supply: Add support for writeable properties This patch adds support for writeable power supply properties and exposes them as writeable to sysfs. A power supply implementation must implement two new function calls in order to use that feature: int set_property(struct power_supply *psy, enum power_supply_property psp, const union power_supply_propval *val); int property_is_writeable(struct power_supply *psy, enum power_supply_property psp); Signed-off-by: Daniel Mack Cc: David Woodhouse Cc: Alexey Starikovskiy Cc: Len Brown Cc: Mark Brown Cc: Matt Reimer Cc: Evgeniy Polyakov Cc: Tejun Heo Signed-off-by: Anton Vorontsov --- drivers/power/power_supply_sysfs.c | 38 +++++++++++++++++++++++++++++++++++--- include/linux/power_supply.h | 5 +++++ 2 files changed, 40 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index 7d7593cad7d9..6a86cdfd79fa 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c @@ -33,7 +33,7 @@ { \ .attr = { .name = #_name }, \ .show = power_supply_show_property, \ - .store = NULL, \ + .store = power_supply_store_property, \ } static struct device_attribute power_supply_attrs[]; @@ -99,6 +99,29 @@ static ssize_t power_supply_show_property(struct device *dev, return sprintf(buf, "%d\n", value.intval); } +static ssize_t power_supply_store_property(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { + ssize_t ret; + struct power_supply *psy = dev_get_drvdata(dev); + const ptrdiff_t off = attr - power_supply_attrs; + union power_supply_propval value; + long long_val; + + /* TODO: support other types than int */ + ret = strict_strtol(buf, 10, &long_val); + if (ret < 0) + return ret; + + value.intval = long_val; + + ret = psy->set_property(psy, off, &value); + if (ret < 0) + return ret; + + return count; +} + /* Must be in the same order as POWER_SUPPLY_PROP_* */ static struct device_attribute power_supply_attrs[] = { /* Properties of type `int' */ @@ -159,8 +182,17 @@ static mode_t power_supply_attr_is_visible(struct kobject *kobj, int i; for (i = 0; i < psy->num_properties; i++) { - if (psy->properties[i] == attrno) - return 0444; + int property = psy->properties[i]; + + if (property == attrno) { + mode_t mode = S_IRUSR | S_IRGRP | S_IROTH; + + if (psy->property_is_writeable && + psy->property_is_writeable(psy, property) > 0) + mode |= S_IWUSR; + + return mode; + } } return 0; diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index c5f73a3ab3ab..30083a896f36 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -145,6 +145,11 @@ struct power_supply { int (*get_property)(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val); + int (*set_property)(struct power_supply *psy, + enum power_supply_property psp, + const union power_supply_propval *val); + int (*property_is_writeable)(struct power_supply *psy, + enum power_supply_property psp); void (*external_power_changed)(struct power_supply *psy); void (*set_charged)(struct power_supply *psy); -- cgit v1.2.3 From bd52ca555ef36bf5b790178cfe8b7d42b5c16ca6 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 18 May 2010 21:49:53 +0200 Subject: ds2760_battery: Make charge_now and charge_full writeable For userspace tools and daemons, it might be necessary to adjust the charge_now and charge_full properties of the ds2760 battery monitor, for example for unavoidable corrections due to aging batteries. Signed-off-by: Daniel Mack Cc: Matt Reimer Cc: Evgeniy Polyakov Cc: Tejun Heo Cc: David Woodhouse Cc: Alexey Starikovskiy Cc: Len Brown Cc: Mark Brown Signed-off-by: Anton Vorontsov --- drivers/power/ds2760_battery.c | 64 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'drivers') diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c index 3bf8d1f622e3..4d3b27228a2e 100644 --- a/drivers/power/ds2760_battery.c +++ b/drivers/power/ds2760_battery.c @@ -304,6 +304,28 @@ static void ds2760_battery_write_rated_capacity(struct ds2760_device_info *di, w1_ds2760_recall_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1); } +static void ds2760_battery_write_active_full(struct ds2760_device_info *di, + int active_full) +{ + unsigned char tmp[2] = { + active_full >> 8, + active_full & 0xff + }; + + if (tmp[0] == di->raw[DS2760_ACTIVE_FULL] && + tmp[1] == di->raw[DS2760_ACTIVE_FULL + 1]) + return; + + w1_ds2760_write(di->w1_dev, tmp, DS2760_ACTIVE_FULL, sizeof(tmp)); + w1_ds2760_store_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK0); + w1_ds2760_recall_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK0); + + /* Write to the di->raw[] buffer directly - the DS2760_ACTIVE_FULL + * values won't be read back by ds2760_battery_read_status() */ + di->raw[DS2760_ACTIVE_FULL] = tmp[0]; + di->raw[DS2760_ACTIVE_FULL + 1] = tmp[1]; +} + static void ds2760_battery_work(struct work_struct *work) { struct ds2760_device_info *di = container_of(work, @@ -426,6 +448,45 @@ static int ds2760_battery_get_property(struct power_supply *psy, return 0; } +static int ds2760_battery_set_property(struct power_supply *psy, + enum power_supply_property psp, + const union power_supply_propval *val) +{ + struct ds2760_device_info *di = to_ds2760_device_info(psy); + + switch (psp) { + case POWER_SUPPLY_PROP_CHARGE_FULL: + /* the interface counts in uAh, convert the value */ + ds2760_battery_write_active_full(di, val->intval / 1000L); + break; + + case POWER_SUPPLY_PROP_CHARGE_NOW: + /* ds2760_battery_set_current_accum() does the conversion */ + ds2760_battery_set_current_accum(di, val->intval); + break; + + default: + return -EPERM; + } + + return 0; +} + +static int ds2760_battery_property_is_writeable(struct power_supply *psy, + enum power_supply_property psp) +{ + switch (psp) { + case POWER_SUPPLY_PROP_CHARGE_FULL: + case POWER_SUPPLY_PROP_CHARGE_NOW: + return 1; + + default: + break; + } + + return 0; +} + static enum power_supply_property ds2760_battery_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_VOLTAGE_NOW, @@ -460,6 +521,9 @@ static int ds2760_battery_probe(struct platform_device *pdev) di->bat.properties = ds2760_battery_props; di->bat.num_properties = ARRAY_SIZE(ds2760_battery_props); di->bat.get_property = ds2760_battery_get_property; + di->bat.set_property = ds2760_battery_set_property; + di->bat.property_is_writeable = + ds2760_battery_property_is_writeable; di->bat.set_charged = ds2760_battery_set_charged; di->bat.external_power_changed = ds2760_battery_external_power_changed; -- cgit v1.2.3 From d5e4aaefd99797929e4455db48d8f9a8728f05f4 Mon Sep 17 00:00:00 2001 From: Lee Nipper Date: Wed, 19 May 2010 19:18:38 +1000 Subject: crypto: talitos - prepare for adding ahash algorithms No functional changes. Use a union in talitos_alg_template for the crypto_alg so that we can add a member later for ahash_alg. Signed-off-by: Lee Nipper Acked-By: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/talitos.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index dc558a097311..ce38b05c8def 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -1479,14 +1479,17 @@ static int ablkcipher_decrypt(struct ablkcipher_request *areq) } struct talitos_alg_template { - struct crypto_alg alg; + u32 type; + union { + struct crypto_alg crypto; + } alg; __be32 desc_hdr_template; }; static struct talitos_alg_template driver_algs[] = { /* AEAD algorithms. These use a single-pass ipsec_esp descriptor */ - { - .alg = { + { .type = CRYPTO_ALG_TYPE_AEAD, + .alg.crypto = { .cra_name = "authenc(hmac(sha1),cbc(aes))", .cra_driver_name = "authenc-hmac-sha1-cbc-aes-talitos", .cra_blocksize = AES_BLOCK_SIZE, @@ -1511,8 +1514,8 @@ static struct talitos_alg_template driver_algs[] = { DESC_HDR_MODE1_MDEU_PAD | DESC_HDR_MODE1_MDEU_SHA1_HMAC, }, - { - .alg = { + { .type = CRYPTO_ALG_TYPE_AEAD, + .alg.crypto = { .cra_name = "authenc(hmac(sha1),cbc(des3_ede))", .cra_driver_name = "authenc-hmac-sha1-cbc-3des-talitos", .cra_blocksize = DES3_EDE_BLOCK_SIZE, @@ -1538,8 +1541,8 @@ static struct talitos_alg_template driver_algs[] = { DESC_HDR_MODE1_MDEU_PAD | DESC_HDR_MODE1_MDEU_SHA1_HMAC, }, - { - .alg = { + { .type = CRYPTO_ALG_TYPE_AEAD, + .alg.crypto = { .cra_name = "authenc(hmac(sha256),cbc(aes))", .cra_driver_name = "authenc-hmac-sha256-cbc-aes-talitos", .cra_blocksize = AES_BLOCK_SIZE, @@ -1564,8 +1567,8 @@ static struct talitos_alg_template driver_algs[] = { DESC_HDR_MODE1_MDEU_PAD | DESC_HDR_MODE1_MDEU_SHA256_HMAC, }, - { - .alg = { + { .type = CRYPTO_ALG_TYPE_AEAD, + .alg.crypto = { .cra_name = "authenc(hmac(sha256),cbc(des3_ede))", .cra_driver_name = "authenc-hmac-sha256-cbc-3des-talitos", .cra_blocksize = DES3_EDE_BLOCK_SIZE, @@ -1591,8 +1594,8 @@ static struct talitos_alg_template driver_algs[] = { DESC_HDR_MODE1_MDEU_PAD | DESC_HDR_MODE1_MDEU_SHA256_HMAC, }, - { - .alg = { + { .type = CRYPTO_ALG_TYPE_AEAD, + .alg.crypto = { .cra_name = "authenc(hmac(md5),cbc(aes))", .cra_driver_name = "authenc-hmac-md5-cbc-aes-talitos", .cra_blocksize = AES_BLOCK_SIZE, @@ -1617,8 +1620,8 @@ static struct talitos_alg_template driver_algs[] = { DESC_HDR_MODE1_MDEU_PAD | DESC_HDR_MODE1_MDEU_MD5_HMAC, }, - { - .alg = { + { .type = CRYPTO_ALG_TYPE_AEAD, + .alg.crypto = { .cra_name = "authenc(hmac(md5),cbc(des3_ede))", .cra_driver_name = "authenc-hmac-md5-cbc-3des-talitos", .cra_blocksize = DES3_EDE_BLOCK_SIZE, @@ -1645,8 +1648,8 @@ static struct talitos_alg_template driver_algs[] = { DESC_HDR_MODE1_MDEU_MD5_HMAC, }, /* ABLKCIPHER algorithms. */ - { - .alg = { + { .type = CRYPTO_ALG_TYPE_ABLKCIPHER, + .alg.crypto = { .cra_name = "cbc(aes)", .cra_driver_name = "cbc-aes-talitos", .cra_blocksize = AES_BLOCK_SIZE, @@ -1667,8 +1670,8 @@ static struct talitos_alg_template driver_algs[] = { DESC_HDR_SEL0_AESU | DESC_HDR_MODE0_AESU_CBC, }, - { - .alg = { + { .type = CRYPTO_ALG_TYPE_ABLKCIPHER, + .alg.crypto = { .cra_name = "cbc(des3_ede)", .cra_driver_name = "cbc-3des-talitos", .cra_blocksize = DES3_EDE_BLOCK_SIZE, @@ -1789,7 +1792,7 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev, return ERR_PTR(-ENOMEM); alg = &t_alg->crypto_alg; - *alg = template->alg; + *alg = template->alg.crypto; alg->cra_module = THIS_MODULE; alg->cra_init = talitos_cra_init; -- cgit v1.2.3 From acbf7c627fb59dfea975f7aafeaba97921085061 Mon Sep 17 00:00:00 2001 From: Lee Nipper Date: Wed, 19 May 2010 19:19:33 +1000 Subject: crypto: talitos - second prepare step for adding ahash algorithms Used talitos_alg_template in talitos_crypto_alg so that it will accommodate ahash algorithms. Added some preparation code for ahash allocation and removal. No actual algorithms yet. Signed-off-by: Lee Nipper Acked-By: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/talitos.c | 55 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index ce38b05c8def..4e8153a839a4 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -46,6 +46,8 @@ #include #include #include +#include +#include #include #include "talitos.h" @@ -1482,6 +1484,7 @@ struct talitos_alg_template { u32 type; union { struct crypto_alg crypto; + struct ahash_alg hash; } alg; __be32 desc_hdr_template; }; @@ -1698,8 +1701,7 @@ static struct talitos_alg_template driver_algs[] = { struct talitos_crypto_alg { struct list_head entry; struct device *dev; - __be32 desc_hdr_template; - struct crypto_alg crypto_alg; + struct talitos_alg_template algt; }; static int talitos_cra_init(struct crypto_tfm *tfm) @@ -1708,13 +1710,14 @@ static int talitos_cra_init(struct crypto_tfm *tfm) struct talitos_crypto_alg *talitos_alg; struct talitos_ctx *ctx = crypto_tfm_ctx(tfm); - talitos_alg = container_of(alg, struct talitos_crypto_alg, crypto_alg); + talitos_alg = container_of(alg, struct talitos_crypto_alg, + algt.alg.crypto); /* update context with ptr to dev */ ctx->dev = talitos_alg->dev; /* copy descriptor header template value */ - ctx->desc_hdr_template = talitos_alg->desc_hdr_template; + ctx->desc_hdr_template = talitos_alg->algt.desc_hdr_template; /* random first IV */ get_random_bytes(ctx->iv, TALITOS_MAX_IV_LENGTH); @@ -1750,7 +1753,15 @@ static int talitos_remove(struct of_device *ofdev) int i; list_for_each_entry_safe(t_alg, n, &priv->alg_list, entry) { - crypto_unregister_alg(&t_alg->crypto_alg); + switch (t_alg->algt.type) { + case CRYPTO_ALG_TYPE_ABLKCIPHER: + case CRYPTO_ALG_TYPE_AEAD: + crypto_unregister_alg(&t_alg->algt.alg.crypto); + break; + case CRYPTO_ALG_TYPE_AHASH: + crypto_unregister_ahash(&t_alg->algt.alg.hash); + break; + } list_del(&t_alg->entry); kfree(t_alg); } @@ -1791,8 +1802,16 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev, if (!t_alg) return ERR_PTR(-ENOMEM); - alg = &t_alg->crypto_alg; - *alg = template->alg.crypto; + t_alg->algt = *template; + + switch (t_alg->algt.type) { + case CRYPTO_ALG_TYPE_ABLKCIPHER: + case CRYPTO_ALG_TYPE_AEAD: + alg = &t_alg->algt.alg.crypto; + break; + case CRYPTO_ALG_TYPE_AHASH: + alg = &t_alg->algt.alg.hash.halg.base; + } alg->cra_module = THIS_MODULE; alg->cra_init = talitos_cra_init; @@ -1800,7 +1819,6 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev, alg->cra_alignmask = 0; alg->cra_ctxsize = sizeof(struct talitos_ctx); - t_alg->desc_hdr_template = template->desc_hdr_template; t_alg->dev = dev; return t_alg; @@ -1934,6 +1952,7 @@ static int talitos_probe(struct of_device *ofdev, for (i = 0; i < ARRAY_SIZE(driver_algs); i++) { if (hw_supports(dev, driver_algs[i].desc_hdr_template)) { struct talitos_crypto_alg *t_alg; + char *name = NULL; t_alg = talitos_alg_alloc(dev, &driver_algs[i]); if (IS_ERR(t_alg)) { @@ -1941,15 +1960,27 @@ static int talitos_probe(struct of_device *ofdev, goto err_out; } - err = crypto_register_alg(&t_alg->crypto_alg); + switch (t_alg->algt.type) { + case CRYPTO_ALG_TYPE_ABLKCIPHER: + case CRYPTO_ALG_TYPE_AEAD: + err = crypto_register_alg( + &t_alg->algt.alg.crypto); + name = t_alg->algt.alg.crypto.cra_driver_name; + break; + case CRYPTO_ALG_TYPE_AHASH: + err = crypto_register_ahash( + &t_alg->algt.alg.hash); + name = + t_alg->algt.alg.hash.halg.base.cra_driver_name; + break; + } if (err) { dev_err(dev, "%s alg registration failed\n", - t_alg->crypto_alg.cra_driver_name); + name); kfree(t_alg); } else { list_add_tail(&t_alg->entry, &priv->alg_list); - dev_info(dev, "%s\n", - t_alg->crypto_alg.cra_driver_name); + dev_info(dev, "%s\n", name); } } } -- cgit v1.2.3 From 497f2e6b8b21407625a4fb34bc04b50eff098085 Mon Sep 17 00:00:00 2001 From: Lee Nipper Date: Wed, 19 May 2010 19:20:36 +1000 Subject: crypto: talitos - add hash algorithms Add the following alorithms to talitos: md5, sha1, sha256, sha384, sha512. These are all type ahash. Signed-off-by: Lee Nipper Acked-By: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/talitos.c | 544 +++++++++++++++++++++++++++++++++++++++++++++-- drivers/crypto/talitos.h | 8 + 2 files changed, 534 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 4e8153a839a4..1b08a3951fb4 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -67,6 +68,13 @@ struct talitos_ptr { __be32 ptr; /* address */ }; +static const struct talitos_ptr zero_entry = { + .len = 0, + .j_extent = 0, + .eptr = 0, + .ptr = 0 +}; + /* descriptor */ struct talitos_desc { __be32 hdr; /* header high bits */ @@ -694,7 +702,7 @@ static void talitos_unregister_rng(struct device *dev) #define TALITOS_MAX_KEY_SIZE 64 #define TALITOS_MAX_IV_LENGTH 16 /* max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */ -#define MD5_DIGEST_SIZE 16 +#define MD5_BLOCK_SIZE 64 struct talitos_ctx { struct device *dev; @@ -707,6 +715,22 @@ struct talitos_ctx { unsigned int authsize; }; +#define HASH_MAX_BLOCK_SIZE SHA512_BLOCK_SIZE +#define TALITOS_MDEU_MAX_CONTEXT_SIZE TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512 + +struct talitos_ahash_req_ctx { + u64 count; + u8 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE]; + unsigned int hw_context_size; + u8 buf[HASH_MAX_BLOCK_SIZE]; + u8 bufnext[HASH_MAX_BLOCK_SIZE]; + unsigned int first; + unsigned int last; + unsigned int to_hash_later; + struct scatterlist bufsl[2]; + struct scatterlist *psrc; +}; + static int aead_setauthsize(struct crypto_aead *authenc, unsigned int authsize) { @@ -823,10 +847,14 @@ static void talitos_sg_unmap(struct device *dev, else dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE); - if (edesc->dst_is_chained) - talitos_unmap_sg_chain(dev, dst, DMA_FROM_DEVICE); - else - dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE); + if (dst) { + if (edesc->dst_is_chained) + talitos_unmap_sg_chain(dev, dst, + DMA_FROM_DEVICE); + else + dma_unmap_sg(dev, dst, dst_nents, + DMA_FROM_DEVICE); + } } else if (edesc->src_is_chained) talitos_unmap_sg_chain(dev, src, DMA_BIDIRECTIONAL); @@ -1116,12 +1144,67 @@ static int sg_count(struct scatterlist *sg_list, int nbytes, int *chained) return sg_nents; } +/** + * sg_copy_end_to_buffer - Copy end data from SG list to a linear buffer + * @sgl: The SG list + * @nents: Number of SG entries + * @buf: Where to copy to + * @buflen: The number of bytes to copy + * @skip: The number of bytes to skip before copying. + * Note: skip + buflen should equal SG total size. + * + * Returns the number of copied bytes. + * + **/ +static size_t sg_copy_end_to_buffer(struct scatterlist *sgl, unsigned int nents, + void *buf, size_t buflen, unsigned int skip) +{ + unsigned int offset = 0; + unsigned int boffset = 0; + struct sg_mapping_iter miter; + unsigned long flags; + unsigned int sg_flags = SG_MITER_ATOMIC; + size_t total_buffer = buflen + skip; + + sg_flags |= SG_MITER_FROM_SG; + + sg_miter_start(&miter, sgl, nents, sg_flags); + + local_irq_save(flags); + + while (sg_miter_next(&miter) && offset < total_buffer) { + unsigned int len; + unsigned int ignore; + + if ((offset + miter.length) > skip) { + if (offset < skip) { + /* Copy part of this segment */ + ignore = skip - offset; + len = miter.length - ignore; + memcpy(buf + boffset, miter.addr + ignore, len); + } else { + /* Copy all of this segment */ + len = miter.length; + memcpy(buf + boffset, miter.addr, len); + } + boffset += len; + } + offset += miter.length; + } + + sg_miter_stop(&miter); + + local_irq_restore(flags); + return boffset; +} + /* * allocate and map the extended descriptor */ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev, struct scatterlist *src, struct scatterlist *dst, + int hash_result, unsigned int cryptlen, unsigned int authsize, int icv_stashing, @@ -1141,11 +1224,16 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev, src_nents = sg_count(src, cryptlen + authsize, &src_chained); src_nents = (src_nents == 1) ? 0 : src_nents; - if (dst == src) { - dst_nents = src_nents; + if (hash_result) { + dst_nents = 0; } else { - dst_nents = sg_count(dst, cryptlen + authsize, &dst_chained); - dst_nents = (dst_nents == 1) ? 0 : dst_nents; + if (dst == src) { + dst_nents = src_nents; + } else { + dst_nents = sg_count(dst, cryptlen + authsize, + &dst_chained); + dst_nents = (dst_nents == 1) ? 0 : dst_nents; + } } /* @@ -1174,8 +1262,10 @@ static struct talitos_edesc *talitos_edesc_alloc(struct device *dev, edesc->src_is_chained = src_chained; edesc->dst_is_chained = dst_chained; edesc->dma_len = dma_len; - edesc->dma_link_tbl = dma_map_single(dev, &edesc->link_tbl[0], - edesc->dma_len, DMA_BIDIRECTIONAL); + if (dma_len) + edesc->dma_link_tbl = dma_map_single(dev, &edesc->link_tbl[0], + edesc->dma_len, + DMA_BIDIRECTIONAL); return edesc; } @@ -1186,7 +1276,7 @@ static struct talitos_edesc *aead_edesc_alloc(struct aead_request *areq, struct crypto_aead *authenc = crypto_aead_reqtfm(areq); struct talitos_ctx *ctx = crypto_aead_ctx(authenc); - return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst, + return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst, 0, areq->cryptlen, ctx->authsize, icv_stashing, areq->base.flags); } @@ -1443,8 +1533,8 @@ static struct talitos_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request * struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq); struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher); - return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst, areq->nbytes, - 0, 0, areq->base.flags); + return talitos_edesc_alloc(ctx->dev, areq->src, areq->dst, 0, + areq->nbytes, 0, 0, areq->base.flags); } static int ablkcipher_encrypt(struct ablkcipher_request *areq) @@ -1480,6 +1570,286 @@ static int ablkcipher_decrypt(struct ablkcipher_request *areq) return common_nonsnoop(edesc, areq, NULL, ablkcipher_done); } +static void common_nonsnoop_hash_unmap(struct device *dev, + struct talitos_edesc *edesc, + struct ahash_request *areq) +{ + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); + + unmap_single_talitos_ptr(dev, &edesc->desc.ptr[5], DMA_FROM_DEVICE); + + /* When using hashctx-in, must unmap it. */ + if (edesc->desc.ptr[1].len) + unmap_single_talitos_ptr(dev, &edesc->desc.ptr[1], + DMA_TO_DEVICE); + + if (edesc->desc.ptr[2].len) + unmap_single_talitos_ptr(dev, &edesc->desc.ptr[2], + DMA_TO_DEVICE); + + talitos_sg_unmap(dev, edesc, req_ctx->psrc, NULL); + + if (edesc->dma_len) + dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len, + DMA_BIDIRECTIONAL); + +} + +static void ahash_done(struct device *dev, + struct talitos_desc *desc, void *context, + int err) +{ + struct ahash_request *areq = context; + struct talitos_edesc *edesc = + container_of(desc, struct talitos_edesc, desc); + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); + + if (!req_ctx->last && req_ctx->to_hash_later) { + /* Position any partial block for next update/final/finup */ + memcpy(req_ctx->buf, req_ctx->bufnext, req_ctx->to_hash_later); + } + common_nonsnoop_hash_unmap(dev, edesc, areq); + + kfree(edesc); + + areq->base.complete(&areq->base, err); +} + +static int common_nonsnoop_hash(struct talitos_edesc *edesc, + struct ahash_request *areq, unsigned int length, + void (*callback) (struct device *dev, + struct talitos_desc *desc, + void *context, int error)) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct talitos_ctx *ctx = crypto_ahash_ctx(tfm); + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); + struct device *dev = ctx->dev; + struct talitos_desc *desc = &edesc->desc; + int sg_count, ret; + + /* first DWORD empty */ + desc->ptr[0] = zero_entry; + + /* hash context in (if not first) */ + if (!req_ctx->first) { + map_single_talitos_ptr(dev, &desc->ptr[1], + req_ctx->hw_context_size, + (char *)req_ctx->hw_context, 0, + DMA_TO_DEVICE); + } else { + desc->ptr[1] = zero_entry; + /* Indicate next op is not the first. */ + req_ctx->first = 0; + } + + /* HMAC key */ + if (ctx->keylen) + map_single_talitos_ptr(dev, &desc->ptr[2], ctx->keylen, + (char *)&ctx->key, 0, DMA_TO_DEVICE); + else + desc->ptr[2] = zero_entry; + + /* + * data in + */ + desc->ptr[3].len = cpu_to_be16(length); + desc->ptr[3].j_extent = 0; + + sg_count = talitos_map_sg(dev, req_ctx->psrc, + edesc->src_nents ? : 1, + DMA_TO_DEVICE, + edesc->src_is_chained); + + if (sg_count == 1) { + to_talitos_ptr(&desc->ptr[3], sg_dma_address(req_ctx->psrc)); + } else { + sg_count = sg_to_link_tbl(req_ctx->psrc, sg_count, length, + &edesc->link_tbl[0]); + if (sg_count > 1) { + desc->ptr[3].j_extent |= DESC_PTR_LNKTBL_JUMP; + to_talitos_ptr(&desc->ptr[3], edesc->dma_link_tbl); + dma_sync_single_for_device(ctx->dev, + edesc->dma_link_tbl, + edesc->dma_len, + DMA_BIDIRECTIONAL); + } else { + /* Only one segment now, so no link tbl needed */ + to_talitos_ptr(&desc->ptr[3], + sg_dma_address(req_ctx->psrc)); + } + } + + /* fifth DWORD empty */ + desc->ptr[4] = zero_entry; + + /* hash/HMAC out -or- hash context out */ + if (req_ctx->last) + map_single_talitos_ptr(dev, &desc->ptr[5], + crypto_ahash_digestsize(tfm), + areq->result, 0, DMA_FROM_DEVICE); + else + map_single_talitos_ptr(dev, &desc->ptr[5], + req_ctx->hw_context_size, + req_ctx->hw_context, 0, DMA_FROM_DEVICE); + + /* last DWORD empty */ + desc->ptr[6] = zero_entry; + + ret = talitos_submit(dev, desc, callback, areq); + if (ret != -EINPROGRESS) { + common_nonsnoop_hash_unmap(dev, edesc, areq); + kfree(edesc); + } + return ret; +} + +static struct talitos_edesc *ahash_edesc_alloc(struct ahash_request *areq, + unsigned int nbytes) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct talitos_ctx *ctx = crypto_ahash_ctx(tfm); + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); + + return talitos_edesc_alloc(ctx->dev, req_ctx->psrc, NULL, 1, + nbytes, 0, 0, areq->base.flags); +} + +static int ahash_init(struct ahash_request *areq) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); + + /* Initialize the context */ + req_ctx->count = 0; + req_ctx->first = 1; /* first indicates h/w must init it's context */ + req_ctx->hw_context_size = + (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE) + ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256 + : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512; + + return 0; +} + +static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes) +{ + struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); + struct talitos_ctx *ctx = crypto_ahash_ctx(tfm); + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); + struct talitos_edesc *edesc; + unsigned int blocksize = + crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); + unsigned int nbytes_to_hash; + unsigned int to_hash_later; + unsigned int index; + int chained; + + index = req_ctx->count & (blocksize - 1); + req_ctx->count += nbytes; + + if (!req_ctx->last && (index + nbytes) < blocksize) { + /* Buffer the partial block */ + sg_copy_to_buffer(areq->src, + sg_count(areq->src, nbytes, &chained), + req_ctx->buf + index, nbytes); + return 0; + } + + if (index) { + /* partial block from previous update; chain it in. */ + sg_init_table(req_ctx->bufsl, (nbytes) ? 2 : 1); + sg_set_buf(req_ctx->bufsl, req_ctx->buf, index); + if (nbytes) + scatterwalk_sg_chain(req_ctx->bufsl, 2, + areq->src); + req_ctx->psrc = req_ctx->bufsl; + } else { + req_ctx->psrc = areq->src; + } + nbytes_to_hash = index + nbytes; + if (!req_ctx->last) { + to_hash_later = (nbytes_to_hash & (blocksize - 1)); + if (to_hash_later) { + int nents; + /* Must copy to_hash_later bytes from the end + * to bufnext (a partial block) for later. + */ + nents = sg_count(areq->src, nbytes, &chained); + sg_copy_end_to_buffer(areq->src, nents, + req_ctx->bufnext, + to_hash_later, + nbytes - to_hash_later); + + /* Adjust count for what will be hashed now */ + nbytes_to_hash -= to_hash_later; + } + req_ctx->to_hash_later = to_hash_later; + } + + /* allocate extended descriptor */ + edesc = ahash_edesc_alloc(areq, nbytes_to_hash); + if (IS_ERR(edesc)) + return PTR_ERR(edesc); + + edesc->desc.hdr = ctx->desc_hdr_template; + + /* On last one, request SEC to pad; otherwise continue */ + if (req_ctx->last) + edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_PAD; + else + edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT; + + /* On first one, request SEC to INIT hash. */ + if (req_ctx->first) + edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT; + + /* When the tfm context has a keylen, it's an HMAC. + * A first or last (ie. not middle) descriptor must request HMAC. + */ + if (ctx->keylen && (req_ctx->first || req_ctx->last)) + edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_HMAC; + + return common_nonsnoop_hash(edesc, areq, nbytes_to_hash, + ahash_done); +} + +static int ahash_update(struct ahash_request *areq) +{ + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); + + req_ctx->last = 0; + + return ahash_process_req(areq, areq->nbytes); +} + +static int ahash_final(struct ahash_request *areq) +{ + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); + + req_ctx->last = 1; + + return ahash_process_req(areq, 0); +} + +static int ahash_finup(struct ahash_request *areq) +{ + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); + + req_ctx->last = 1; + + return ahash_process_req(areq, areq->nbytes); +} + +static int ahash_digest(struct ahash_request *areq) +{ + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); + + ahash_init(areq); + req_ctx->last = 1; + + return ahash_process_req(areq, areq->nbytes); +} + struct talitos_alg_template { u32 type; union { @@ -1695,7 +2065,113 @@ static struct talitos_alg_template driver_algs[] = { DESC_HDR_SEL0_DEU | DESC_HDR_MODE0_DEU_CBC | DESC_HDR_MODE0_DEU_3DES, - } + }, + /* AHASH algorithms. */ + { .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .init = ahash_init, + .update = ahash_update, + .final = ahash_final, + .finup = ahash_finup, + .digest = ahash_digest, + .halg.digestsize = MD5_DIGEST_SIZE, + .halg.base = { + .cra_name = "md5", + .cra_driver_name = "md5-talitos", + .cra_blocksize = MD5_BLOCK_SIZE, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC, + .cra_type = &crypto_ahash_type + } + }, + .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | + DESC_HDR_SEL0_MDEUA | + DESC_HDR_MODE0_MDEU_MD5, + }, + { .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .init = ahash_init, + .update = ahash_update, + .final = ahash_final, + .finup = ahash_finup, + .digest = ahash_digest, + .halg.digestsize = SHA1_DIGEST_SIZE, + .halg.base = { + .cra_name = "sha1", + .cra_driver_name = "sha1-talitos", + .cra_blocksize = SHA1_BLOCK_SIZE, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC, + .cra_type = &crypto_ahash_type + } + }, + .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | + DESC_HDR_SEL0_MDEUA | + DESC_HDR_MODE0_MDEU_SHA1, + }, + { .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .init = ahash_init, + .update = ahash_update, + .final = ahash_final, + .finup = ahash_finup, + .digest = ahash_digest, + .halg.digestsize = SHA256_DIGEST_SIZE, + .halg.base = { + .cra_name = "sha256", + .cra_driver_name = "sha256-talitos", + .cra_blocksize = SHA256_BLOCK_SIZE, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC, + .cra_type = &crypto_ahash_type + } + }, + .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | + DESC_HDR_SEL0_MDEUA | + DESC_HDR_MODE0_MDEU_SHA256, + }, + { .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .init = ahash_init, + .update = ahash_update, + .final = ahash_final, + .finup = ahash_finup, + .digest = ahash_digest, + .halg.digestsize = SHA384_DIGEST_SIZE, + .halg.base = { + .cra_name = "sha384", + .cra_driver_name = "sha384-talitos", + .cra_blocksize = SHA384_BLOCK_SIZE, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC, + .cra_type = &crypto_ahash_type + } + }, + .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | + DESC_HDR_SEL0_MDEUB | + DESC_HDR_MODE0_MDEUB_SHA384, + }, + { .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .init = ahash_init, + .update = ahash_update, + .final = ahash_final, + .finup = ahash_finup, + .digest = ahash_digest, + .halg.digestsize = SHA512_DIGEST_SIZE, + .halg.base = { + .cra_name = "sha512", + .cra_driver_name = "sha512-talitos", + .cra_blocksize = SHA512_BLOCK_SIZE, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC, + .cra_type = &crypto_ahash_type + } + }, + .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | + DESC_HDR_SEL0_MDEUB | + DESC_HDR_MODE0_MDEUB_SHA512, + }, }; struct talitos_crypto_alg { @@ -1710,8 +2186,13 @@ static int talitos_cra_init(struct crypto_tfm *tfm) struct talitos_crypto_alg *talitos_alg; struct talitos_ctx *ctx = crypto_tfm_ctx(tfm); - talitos_alg = container_of(alg, struct talitos_crypto_alg, - algt.alg.crypto); + if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_AHASH) + talitos_alg = container_of(__crypto_ahash_alg(alg), + struct talitos_crypto_alg, + algt.alg.hash); + else + talitos_alg = container_of(alg, struct talitos_crypto_alg, + algt.alg.crypto); /* update context with ptr to dev */ ctx->dev = talitos_alg->dev; @@ -1719,12 +2200,34 @@ static int talitos_cra_init(struct crypto_tfm *tfm) /* copy descriptor header template value */ ctx->desc_hdr_template = talitos_alg->algt.desc_hdr_template; + return 0; +} + +static int talitos_cra_init_aead(struct crypto_tfm *tfm) +{ + struct talitos_ctx *ctx = crypto_tfm_ctx(tfm); + + talitos_cra_init(tfm); + /* random first IV */ get_random_bytes(ctx->iv, TALITOS_MAX_IV_LENGTH); return 0; } +static int talitos_cra_init_ahash(struct crypto_tfm *tfm) +{ + struct talitos_ctx *ctx = crypto_tfm_ctx(tfm); + + talitos_cra_init(tfm); + + ctx->keylen = 0; + crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), + sizeof(struct talitos_ahash_req_ctx)); + + return 0; +} + /* * given the alg's descriptor header template, determine whether descriptor * type and primary/secondary execution units required match the hw @@ -1806,15 +2309,20 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev, switch (t_alg->algt.type) { case CRYPTO_ALG_TYPE_ABLKCIPHER: + alg = &t_alg->algt.alg.crypto; + alg->cra_init = talitos_cra_init; + break; case CRYPTO_ALG_TYPE_AEAD: alg = &t_alg->algt.alg.crypto; + alg->cra_init = talitos_cra_init_aead; break; case CRYPTO_ALG_TYPE_AHASH: alg = &t_alg->algt.alg.hash.halg.base; + alg->cra_init = talitos_cra_init_ahash; + break; } alg->cra_module = THIS_MODULE; - alg->cra_init = talitos_cra_init; alg->cra_priority = TALITOS_CRA_PRIORITY; alg->cra_alignmask = 0; alg->cra_ctxsize = sizeof(struct talitos_ctx); diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h index ff5a1450e145..05c57b730e99 100644 --- a/drivers/crypto/talitos.h +++ b/drivers/crypto/talitos.h @@ -130,6 +130,9 @@ #define TALITOS_CRCUISR 0xf030 /* cyclic redundancy check unit*/ #define TALITOS_CRCUISR_LO 0xf034 +#define TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256 0x28 +#define TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512 0x48 + /* * talitos descriptor header (hdr) bits */ @@ -157,12 +160,15 @@ #define DESC_HDR_MODE0_AESU_CBC cpu_to_be32(0x00200000) #define DESC_HDR_MODE0_DEU_CBC cpu_to_be32(0x00400000) #define DESC_HDR_MODE0_DEU_3DES cpu_to_be32(0x00200000) +#define DESC_HDR_MODE0_MDEU_CONT cpu_to_be32(0x08000000) #define DESC_HDR_MODE0_MDEU_INIT cpu_to_be32(0x01000000) #define DESC_HDR_MODE0_MDEU_HMAC cpu_to_be32(0x00800000) #define DESC_HDR_MODE0_MDEU_PAD cpu_to_be32(0x00400000) #define DESC_HDR_MODE0_MDEU_MD5 cpu_to_be32(0x00200000) #define DESC_HDR_MODE0_MDEU_SHA256 cpu_to_be32(0x00100000) #define DESC_HDR_MODE0_MDEU_SHA1 cpu_to_be32(0x00000000) +#define DESC_HDR_MODE0_MDEUB_SHA384 cpu_to_be32(0x00000000) +#define DESC_HDR_MODE0_MDEUB_SHA512 cpu_to_be32(0x00200000) #define DESC_HDR_MODE0_MDEU_MD5_HMAC (DESC_HDR_MODE0_MDEU_MD5 | \ DESC_HDR_MODE0_MDEU_HMAC) #define DESC_HDR_MODE0_MDEU_SHA256_HMAC (DESC_HDR_MODE0_MDEU_SHA256 | \ @@ -184,6 +190,8 @@ #define DESC_HDR_MODE1_MDEU_MD5 cpu_to_be32(0x00000200) #define DESC_HDR_MODE1_MDEU_SHA256 cpu_to_be32(0x00000100) #define DESC_HDR_MODE1_MDEU_SHA1 cpu_to_be32(0x00000000) +#define DESC_HDR_MODE1_MDEUB_SHA384 cpu_to_be32(0x00000000) +#define DESC_HDR_MODE1_MDEUB_SHA512 cpu_to_be32(0x00000200) #define DESC_HDR_MODE1_MDEU_MD5_HMAC (DESC_HDR_MODE1_MDEU_MD5 | \ DESC_HDR_MODE1_MDEU_HMAC) #define DESC_HDR_MODE1_MDEU_SHA256_HMAC (DESC_HDR_MODE1_MDEU_SHA256 | \ -- cgit v1.2.3 From 60f208d7836216885cdcd6f77a02f31dbc66f169 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Wed, 19 May 2010 19:21:53 +1000 Subject: crypto: talitos - add support for sha224 SEC h/w versions 2.1 and above support sha224 via explicit instruction. Performing sha224 ahashes on earlier versions is still possible because they support sha256 (sha224 is sha256 with different initial constants and a different truncation length). We do this by overriding hardware context self-initialization, and perform it manually in s/w instead. Thanks to Lee for his fixes for correct execution on actual sec2.0 h/w. Signed-off-by: Kim Phillips Signed-off by: Lee Nipper Signed-off-by: Herbert Xu --- drivers/crypto/talitos.c | 81 ++++++++++++++++++++++++++++++++++++++++++------ drivers/crypto/talitos.h | 4 ++- 2 files changed, 75 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 1b08a3951fb4..6a0f59d1fc5c 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -1,7 +1,7 @@ /* * talitos - Freescale Integrated Security Engine (SEC) device driver * - * Copyright (c) 2008 Freescale Semiconductor, Inc. + * Copyright (c) 2008-2010 Freescale Semiconductor, Inc. * * Scatterlist Crypto API glue code copied from files with the following: * Copyright (c) 2006-2007 Herbert Xu @@ -156,6 +156,7 @@ struct talitos_private { /* .features flag */ #define TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT 0x00000001 #define TALITOS_FTR_HW_AUTH_CHECK 0x00000002 +#define TALITOS_FTR_SHA224_HWINIT 0x00000004 static void to_talitos_ptr(struct talitos_ptr *talitos_ptr, dma_addr_t dma_addr) { @@ -720,10 +721,11 @@ struct talitos_ctx { struct talitos_ahash_req_ctx { u64 count; - u8 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE]; + u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)]; unsigned int hw_context_size; u8 buf[HASH_MAX_BLOCK_SIZE]; u8 bufnext[HASH_MAX_BLOCK_SIZE]; + unsigned int swinit; unsigned int first; unsigned int last; unsigned int to_hash_later; @@ -1631,12 +1633,13 @@ static int common_nonsnoop_hash(struct talitos_edesc *edesc, /* first DWORD empty */ desc->ptr[0] = zero_entry; - /* hash context in (if not first) */ - if (!req_ctx->first) { + /* hash context in */ + if (!req_ctx->first || req_ctx->swinit) { map_single_talitos_ptr(dev, &desc->ptr[1], req_ctx->hw_context_size, (char *)req_ctx->hw_context, 0, DMA_TO_DEVICE); + req_ctx->swinit = 0; } else { desc->ptr[1] = zero_entry; /* Indicate next op is not the first. */ @@ -1722,7 +1725,8 @@ static int ahash_init(struct ahash_request *areq) /* Initialize the context */ req_ctx->count = 0; - req_ctx->first = 1; /* first indicates h/w must init it's context */ + req_ctx->first = 1; /* first indicates h/w must init its context */ + req_ctx->swinit = 0; /* assume h/w init of context */ req_ctx->hw_context_size = (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE) ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256 @@ -1731,6 +1735,33 @@ static int ahash_init(struct ahash_request *areq) return 0; } +/* + * on h/w without explicit sha224 support, we initialize h/w context + * manually with sha224 constants, and tell it to run sha256. + */ +static int ahash_init_sha224_swinit(struct ahash_request *areq) +{ + struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); + + ahash_init(areq); + req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/ + + req_ctx->hw_context[0] = cpu_to_be32(SHA224_H0); + req_ctx->hw_context[1] = cpu_to_be32(SHA224_H1); + req_ctx->hw_context[2] = cpu_to_be32(SHA224_H2); + req_ctx->hw_context[3] = cpu_to_be32(SHA224_H3); + req_ctx->hw_context[4] = cpu_to_be32(SHA224_H4); + req_ctx->hw_context[5] = cpu_to_be32(SHA224_H5); + req_ctx->hw_context[6] = cpu_to_be32(SHA224_H6); + req_ctx->hw_context[7] = cpu_to_be32(SHA224_H7); + + /* init 64-bit count */ + req_ctx->hw_context[8] = 0; + req_ctx->hw_context[9] = 0; + + return 0; +} + static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes) { struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); @@ -1799,8 +1830,8 @@ static int ahash_process_req(struct ahash_request *areq, unsigned int nbytes) else edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_CONT; - /* On first one, request SEC to INIT hash. */ - if (req_ctx->first) + /* request SEC to INIT hash. */ + if (req_ctx->first && !req_ctx->swinit) edesc->desc.hdr |= DESC_HDR_MODE0_MDEU_INIT; /* When the tfm context has a keylen, it's an HMAC. @@ -1843,8 +1874,9 @@ static int ahash_finup(struct ahash_request *areq) static int ahash_digest(struct ahash_request *areq) { struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); + struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq); - ahash_init(areq); + ahash->init(areq); req_ctx->last = 1; return ahash_process_req(areq, areq->nbytes); @@ -2109,6 +2141,27 @@ static struct talitos_alg_template driver_algs[] = { DESC_HDR_SEL0_MDEUA | DESC_HDR_MODE0_MDEU_SHA1, }, + { .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .init = ahash_init, + .update = ahash_update, + .final = ahash_final, + .finup = ahash_finup, + .digest = ahash_digest, + .halg.digestsize = SHA224_DIGEST_SIZE, + .halg.base = { + .cra_name = "sha224", + .cra_driver_name = "sha224-talitos", + .cra_blocksize = SHA224_BLOCK_SIZE, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC, + .cra_type = &crypto_ahash_type + } + }, + .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | + DESC_HDR_SEL0_MDEUA | + DESC_HDR_MODE0_MDEU_SHA224, + }, { .type = CRYPTO_ALG_TYPE_AHASH, .alg.hash = { .init = ahash_init, @@ -2298,6 +2351,7 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev, struct talitos_alg_template *template) { + struct talitos_private *priv = dev_get_drvdata(dev); struct talitos_crypto_alg *t_alg; struct crypto_alg *alg; @@ -2319,6 +2373,14 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev, case CRYPTO_ALG_TYPE_AHASH: alg = &t_alg->algt.alg.hash.halg.base; alg->cra_init = talitos_cra_init_ahash; + if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) && + !strcmp(alg->cra_name, "sha224")) { + t_alg->algt.alg.hash.init = ahash_init_sha224_swinit; + t_alg->algt.desc_hdr_template = + DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU | + DESC_HDR_SEL0_MDEUA | + DESC_HDR_MODE0_MDEU_SHA256; + } break; } @@ -2406,7 +2468,8 @@ static int talitos_probe(struct of_device *ofdev, priv->features |= TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT; if (of_device_is_compatible(np, "fsl,sec2.1")) - priv->features |= TALITOS_FTR_HW_AUTH_CHECK; + priv->features |= TALITOS_FTR_HW_AUTH_CHECK | + TALITOS_FTR_SHA224_HWINIT; priv->chan = kzalloc(sizeof(struct talitos_channel) * priv->num_channels, GFP_KERNEL); diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h index 05c57b730e99..0b746aca4587 100644 --- a/drivers/crypto/talitos.h +++ b/drivers/crypto/talitos.h @@ -1,7 +1,7 @@ /* * Freescale SEC (talitos) device register and descriptor header defines * - * Copyright (c) 2006-2008 Freescale Semiconductor, Inc. + * Copyright (c) 2006-2010 Freescale Semiconductor, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -164,6 +164,7 @@ #define DESC_HDR_MODE0_MDEU_INIT cpu_to_be32(0x01000000) #define DESC_HDR_MODE0_MDEU_HMAC cpu_to_be32(0x00800000) #define DESC_HDR_MODE0_MDEU_PAD cpu_to_be32(0x00400000) +#define DESC_HDR_MODE0_MDEU_SHA224 cpu_to_be32(0x00300000) #define DESC_HDR_MODE0_MDEU_MD5 cpu_to_be32(0x00200000) #define DESC_HDR_MODE0_MDEU_SHA256 cpu_to_be32(0x00100000) #define DESC_HDR_MODE0_MDEU_SHA1 cpu_to_be32(0x00000000) @@ -187,6 +188,7 @@ #define DESC_HDR_MODE1_MDEU_INIT cpu_to_be32(0x00001000) #define DESC_HDR_MODE1_MDEU_HMAC cpu_to_be32(0x00000800) #define DESC_HDR_MODE1_MDEU_PAD cpu_to_be32(0x00000400) +#define DESC_HDR_MODE1_MDEU_SHA224 cpu_to_be32(0x00000300) #define DESC_HDR_MODE1_MDEU_MD5 cpu_to_be32(0x00000200) #define DESC_HDR_MODE1_MDEU_SHA256 cpu_to_be32(0x00000100) #define DESC_HDR_MODE1_MDEU_SHA1 cpu_to_be32(0x00000000) -- cgit v1.2.3 From 4cb2ea28c55cf5e5ef83aec535099ffce3c583df Mon Sep 17 00:00:00 2001 From: john cooper Date: Thu, 25 Mar 2010 01:33:33 -0400 Subject: Add virtio disk identification support Add virtio-blk device id (s/n) support via virtio request. Signed-off-by: john cooper Signed-off-by: Rusty Russell --- drivers/block/virtio_blk.c | 30 ++++++++++++++++++++++++++++++ include/linux/virtio_blk.h | 5 +++++ 2 files changed, 35 insertions(+) (limited to 'drivers') diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 2138a7ae050c..759dee8330ac 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -70,6 +70,8 @@ static void blk_done(struct virtqueue *vq) vbr->req->sense_len = vbr->in_hdr.sense_len; vbr->req->errors = vbr->in_hdr.errors; } + if (blk_special_request(vbr->req)) + vbr->req->errors = (error != 0); __blk_end_request_all(vbr->req, error); list_del(&vbr->list); @@ -103,6 +105,11 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, vbr->out_hdr.sector = 0; vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); break; + case REQ_TYPE_SPECIAL: + vbr->out_hdr.type = VIRTIO_BLK_T_GET_ID; + vbr->out_hdr.sector = 0; + vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); + break; case REQ_TYPE_LINUX_BLOCK: if (req->cmd[0] == REQ_LB_OP_FLUSH) { vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH; @@ -189,6 +196,29 @@ static void virtblk_prepare_flush(struct request_queue *q, struct request *req) req->cmd[0] = REQ_LB_OP_FLUSH; } +/* return id (s/n) string for *disk to *id_str + */ +static int virtblk_get_id(struct gendisk *disk, char *id_str) +{ + struct virtio_blk *vblk = disk->private_data; + struct request *req; + struct bio *bio; + + bio = bio_map_kern(vblk->disk->queue, id_str, VIRTIO_BLK_ID_BYTES, + GFP_KERNEL); + if (IS_ERR(bio)) + return PTR_ERR(bio); + + req = blk_make_request(vblk->disk->queue, bio, GFP_KERNEL); + if (IS_ERR(req)) { + bio_put(bio); + return PTR_ERR(req); + } + + req->cmd_type = REQ_TYPE_SPECIAL; + return blk_execute_rq(vblk->disk->queue, vblk->disk, req, false); +} + static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long data) { diff --git a/include/linux/virtio_blk.h b/include/linux/virtio_blk.h index e52029e98919..167720d695ed 100644 --- a/include/linux/virtio_blk.h +++ b/include/linux/virtio_blk.h @@ -17,6 +17,8 @@ #define VIRTIO_BLK_F_FLUSH 9 /* Cache flush command support */ #define VIRTIO_BLK_F_TOPOLOGY 10 /* Topology information is available */ +#define VIRTIO_BLK_ID_BYTES 20 /* ID string length */ + struct virtio_blk_config { /* The capacity (in 512-byte sectors). */ __u64 capacity; @@ -67,6 +69,9 @@ struct virtio_blk_config { /* Cache flush command */ #define VIRTIO_BLK_T_FLUSH 4 +/* Get device ID command */ +#define VIRTIO_BLK_T_GET_ID 8 + /* Barrier before this op. */ #define VIRTIO_BLK_T_BARRIER 0x80000000 -- cgit v1.2.3 From 234f2725a5d03f78539f1d36cb32f2c4f9b1822c Mon Sep 17 00:00:00 2001 From: john cooper Date: Thu, 25 Mar 2010 01:34:02 -0400 Subject: Add virtio disk identification ioctl Return serial string to the guest application via ioctl driver call. Note this form of interface to the guest userland was the consensus when the prior version using the ATA_IDENTIFY came under dispute. Signed-off-by: john cooper Signed-off-by: Rusty Russell --- drivers/block/virtio_blk.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 759dee8330ac..67dcb193ab2e 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -225,6 +225,16 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, struct gendisk *disk = bdev->bd_disk; struct virtio_blk *vblk = disk->private_data; + if (cmd == 'VBID') { + void __user *usr_data = (void __user *)data; + char id_str[VIRTIO_BLK_ID_BYTES]; + int err; + + err = virtblk_get_id(disk, id_str); + if (!err && copy_to_user(usr_data, id_str, VIRTIO_BLK_ID_BYTES)) + err = -EFAULT; + return err; + } /* * Only allow the generic SCSI ioctls if the host can support it. */ -- cgit v1.2.3 From bdb4a1305723f985249210a803105dbc48e86b64 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 19 May 2010 22:15:40 -0600 Subject: virtio_blk: remove multichar constant. drivers/block/virtio_blk.c:228:13: warning: multi-character character constant Signed-off-by: Rusty Russell Cc: john cooper --- drivers/block/virtio_blk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 67dcb193ab2e..e32b24b7a3a2 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -225,7 +225,7 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, struct gendisk *disk = bdev->bd_disk; struct virtio_blk *vblk = disk->private_data; - if (cmd == 'VBID') { + if (cmd == 0x56424944) { /* 'VBID' */ void __user *usr_data = (void __user *)data; char id_str[VIRTIO_BLK_ID_BYTES]; int err; -- cgit v1.2.3 From 946cfe0e05664543b22ed674fff3764f41a372c7 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 12 Apr 2010 16:18:28 +0300 Subject: virtio_balloon: use virtqueue_xxx wrappers Switch virtio_balloon to new virtqueue_xxx wrappers. Signed-off-by: Michael S. Tsirkin Signed-off-by: Rusty Russell --- drivers/virtio/virtio_balloon.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index bfec7c29486d..0f1da45ba47d 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -75,7 +75,7 @@ static void balloon_ack(struct virtqueue *vq) struct virtio_balloon *vb; unsigned int len; - vb = vq->vq_ops->get_buf(vq, &len); + vb = virtqueue_get_buf(vq, &len); if (vb) complete(&vb->acked); } @@ -89,9 +89,9 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq) init_completion(&vb->acked); /* We should always be able to add one buffer to an empty queue. */ - if (vq->vq_ops->add_buf(vq, &sg, 1, 0, vb) < 0) + if (virtqueue_add_buf(vq, &sg, 1, 0, vb) < 0) BUG(); - vq->vq_ops->kick(vq); + virtqueue_kick(vq); /* When host has read buffer, this completes via balloon_ack */ wait_for_completion(&vb->acked); @@ -204,7 +204,7 @@ static void stats_request(struct virtqueue *vq) struct virtio_balloon *vb; unsigned int len; - vb = vq->vq_ops->get_buf(vq, &len); + vb = virtqueue_get_buf(vq, &len); if (!vb) return; vb->need_stats_update = 1; @@ -221,9 +221,9 @@ static void stats_handle_request(struct virtio_balloon *vb) vq = vb->stats_vq; sg_init_one(&sg, vb->stats, sizeof(vb->stats)); - if (vq->vq_ops->add_buf(vq, &sg, 1, 0, vb) < 0) + if (virtqueue_add_buf(vq, &sg, 1, 0, vb) < 0) BUG(); - vq->vq_ops->kick(vq); + virtqueue_kick(vq); } static void virtballoon_changed(struct virtio_device *vdev) @@ -314,10 +314,9 @@ static int virtballoon_probe(struct virtio_device *vdev) * use it to signal us later. */ sg_init_one(&sg, vb->stats, sizeof vb->stats); - if (vb->stats_vq->vq_ops->add_buf(vb->stats_vq, - &sg, 1, 0, vb) < 0) + if (virtqueue_add_buf(vb->stats_vq, &sg, 1, 0, vb) < 0) BUG(); - vb->stats_vq->vq_ops->kick(vb->stats_vq); + virtqueue_kick(vb->stats_vq); } vb->thread = kthread_run(balloon, vb, "vballoon"); -- cgit v1.2.3 From 505b0451c47699ca63db70bd5ec3bba187ec4bfd Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 12 Apr 2010 16:18:32 +0300 Subject: virtio_console: use virtqueue_xxx wrappers Switch virtio_console to new virtqueue_xxx wrappers. Signed-off-by: Michael S. Tsirkin Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 196428c2287a..48ce834306b5 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -328,7 +328,7 @@ static void *get_inbuf(struct port *port) unsigned int len; vq = port->in_vq; - buf = vq->vq_ops->get_buf(vq, &len); + buf = virtqueue_get_buf(vq, &len); if (buf) { buf->len = len; buf->offset = 0; @@ -349,8 +349,8 @@ static int add_inbuf(struct virtqueue *vq, struct port_buffer *buf) sg_init_one(sg, buf->buf, buf->size); - ret = vq->vq_ops->add_buf(vq, sg, 0, 1, buf); - vq->vq_ops->kick(vq); + ret = virtqueue_add_buf(vq, sg, 0, 1, buf); + virtqueue_kick(vq); return ret; } @@ -366,7 +366,7 @@ static void discard_port_data(struct port *port) if (port->inbuf) buf = port->inbuf; else - buf = vq->vq_ops->get_buf(vq, &len); + buf = virtqueue_get_buf(vq, &len); ret = 0; while (buf) { @@ -374,7 +374,7 @@ static void discard_port_data(struct port *port) ret++; free_buf(buf); } - buf = vq->vq_ops->get_buf(vq, &len); + buf = virtqueue_get_buf(vq, &len); } port->inbuf = NULL; if (ret) @@ -421,9 +421,9 @@ static ssize_t send_control_msg(struct port *port, unsigned int event, vq = port->portdev->c_ovq; sg_init_one(sg, &cpkt, sizeof(cpkt)); - if (vq->vq_ops->add_buf(vq, sg, 1, 0, &cpkt) >= 0) { - vq->vq_ops->kick(vq); - while (!vq->vq_ops->get_buf(vq, &len)) + if (virtqueue_add_buf(vq, sg, 1, 0, &cpkt) >= 0) { + virtqueue_kick(vq); + while (!virtqueue_get_buf(vq, &len)) cpu_relax(); } return 0; @@ -439,10 +439,10 @@ static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count) out_vq = port->out_vq; sg_init_one(sg, in_buf, in_count); - ret = out_vq->vq_ops->add_buf(out_vq, sg, 1, 0, in_buf); + ret = virtqueue_add_buf(out_vq, sg, 1, 0, in_buf); /* Tell Host to go! */ - out_vq->vq_ops->kick(out_vq); + virtqueue_kick(out_vq); if (ret < 0) { in_count = 0; @@ -450,7 +450,7 @@ static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count) } /* Wait till the host acknowledges it pushed out the data we sent. */ - while (!out_vq->vq_ops->get_buf(out_vq, &len)) + while (!virtqueue_get_buf(out_vq, &len)) cpu_relax(); fail: /* We're expected to return the amount of data we wrote */ @@ -901,7 +901,7 @@ static int remove_port(struct port *port) discard_port_data(port); /* Remove buffers we queued up for the Host to send us data in. */ - while ((buf = port->in_vq->vq_ops->detach_unused_buf(port->in_vq))) + while ((buf = virtqueue_detach_unused_buf(port->in_vq))) free_buf(buf); kfree(port->name); @@ -1030,7 +1030,7 @@ static void control_work_handler(struct work_struct *work) vq = portdev->c_ivq; spin_lock(&portdev->cvq_lock); - while ((buf = vq->vq_ops->get_buf(vq, &len))) { + while ((buf = virtqueue_get_buf(vq, &len))) { spin_unlock(&portdev->cvq_lock); buf->len = len; @@ -1224,7 +1224,7 @@ static int add_port(struct ports_device *portdev, u32 id) return 0; free_inbufs: - while ((buf = port->in_vq->vq_ops->detach_unused_buf(port->in_vq))) + while ((buf = virtqueue_detach_unused_buf(port->in_vq))) free_buf(buf); free_device: device_destroy(pdrvdata.class, port->dev->devt); @@ -1536,10 +1536,10 @@ static void virtcons_remove(struct virtio_device *vdev) unregister_chrdev(portdev->chr_major, "virtio-portsdev"); - while ((buf = portdev->c_ivq->vq_ops->get_buf(portdev->c_ivq, &len))) + while ((buf = virtqueue_get_buf(portdev->c_ivq, &len))) free_buf(buf); - while ((buf = portdev->c_ivq->vq_ops->detach_unused_buf(portdev->c_ivq))) + while ((buf = virtqueue_detach_unused_buf(portdev->c_ivq))) free_buf(buf); vdev->config->del_vqs(vdev); -- cgit v1.2.3 From 09ec6b69d2b97d6fca16cfe91b4634506f4db0a7 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 12 Apr 2010 16:18:36 +0300 Subject: virtio_blk: use virtqueue_xxx wrappers Switch virtio_blk to new virtqueue_xxx wrappers. Signed-off-by: Michael S. Tsirkin Signed-off-by: Rusty Russell --- drivers/block/virtio_blk.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index e32b24b7a3a2..83fa09a836ca 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -50,7 +50,7 @@ static void blk_done(struct virtqueue *vq) unsigned long flags; spin_lock_irqsave(&vblk->lock, flags); - while ((vbr = vblk->vq->vq_ops->get_buf(vblk->vq, &len)) != NULL) { + while ((vbr = virtqueue_get_buf(vblk->vq, &len)) != NULL) { int error; switch (vbr->status) { @@ -158,7 +158,7 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, } } - if (vblk->vq->vq_ops->add_buf(vblk->vq, vblk->sg, out, in, vbr) < 0) { + if (virtqueue_add_buf(vblk->vq, vblk->sg, out, in, vbr) < 0) { mempool_free(vbr, vblk->pool); return false; } @@ -187,7 +187,7 @@ static void do_virtblk_request(struct request_queue *q) } if (issued) - vblk->vq->vq_ops->kick(vblk->vq); + virtqueue_kick(vblk->vq); } static void virtblk_prepare_flush(struct request_queue *q, struct request *req) -- cgit v1.2.3 From 1915a712f210f0b63d10bc4f875e8e66aac7a2c4 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 12 Apr 2010 16:19:04 +0300 Subject: virtio_net: use virtqueue_xxx wrappers Switch virtio_net to new virtqueue_xxx wrappers. Signed-off-by: Michael S. Tsirkin Signed-off-by: Rusty Russell --- drivers/net/virtio_net.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index b0577dd1a42d..91738d83dbdc 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -119,7 +119,7 @@ static void skb_xmit_done(struct virtqueue *svq) struct virtnet_info *vi = svq->vdev->priv; /* Suppress further interrupts. */ - svq->vq_ops->disable_cb(svq); + virtqueue_disable_cb(svq); /* We were probably waiting for more output buffers. */ netif_wake_queue(vi->dev); @@ -207,7 +207,7 @@ static int receive_mergeable(struct virtnet_info *vi, struct sk_buff *skb) return -EINVAL; } - page = vi->rvq->vq_ops->get_buf(vi->rvq, &len); + page = virtqueue_get_buf(vi->rvq, &len); if (!page) { pr_debug("%s: rx error: %d buffers missing\n", skb->dev->name, hdr->mhdr.num_buffers); @@ -339,7 +339,7 @@ static int add_recvbuf_small(struct virtnet_info *vi, gfp_t gfp) skb_to_sgvec(skb, sg + 1, 0, skb->len); - err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, 2, skb); + err = virtqueue_add_buf(vi->rvq, sg, 0, 2, skb); if (err < 0) dev_kfree_skb(skb); @@ -386,7 +386,7 @@ static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp) /* chain first in list head */ first->private = (unsigned long)list; - err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, MAX_SKB_FRAGS + 2, + err = virtqueue_add_buf(vi->rvq, sg, 0, MAX_SKB_FRAGS + 2, first); if (err < 0) give_pages(vi, first); @@ -406,7 +406,7 @@ static int add_recvbuf_mergeable(struct virtnet_info *vi, gfp_t gfp) sg_init_one(&sg, page_address(page), PAGE_SIZE); - err = vi->rvq->vq_ops->add_buf(vi->rvq, &sg, 0, 1, page); + err = virtqueue_add_buf(vi->rvq, &sg, 0, 1, page); if (err < 0) give_pages(vi, page); @@ -435,7 +435,7 @@ static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp) } while (err > 0); if (unlikely(vi->num > vi->max)) vi->max = vi->num; - vi->rvq->vq_ops->kick(vi->rvq); + virtqueue_kick(vi->rvq); return !oom; } @@ -444,7 +444,7 @@ static void skb_recv_done(struct virtqueue *rvq) struct virtnet_info *vi = rvq->vdev->priv; /* Schedule NAPI, Suppress further interrupts if successful. */ if (napi_schedule_prep(&vi->napi)) { - rvq->vq_ops->disable_cb(rvq); + virtqueue_disable_cb(rvq); __napi_schedule(&vi->napi); } } @@ -473,7 +473,7 @@ static int virtnet_poll(struct napi_struct *napi, int budget) again: while (received < budget && - (buf = vi->rvq->vq_ops->get_buf(vi->rvq, &len)) != NULL) { + (buf = virtqueue_get_buf(vi->rvq, &len)) != NULL) { receive_buf(vi->dev, buf, len); --vi->num; received++; @@ -487,9 +487,9 @@ again: /* Out of packets? */ if (received < budget) { napi_complete(napi); - if (unlikely(!vi->rvq->vq_ops->enable_cb(vi->rvq)) && + if (unlikely(!virtqueue_enable_cb(vi->rvq)) && napi_schedule_prep(napi)) { - vi->rvq->vq_ops->disable_cb(vi->rvq); + virtqueue_disable_cb(vi->rvq); __napi_schedule(napi); goto again; } @@ -503,7 +503,7 @@ static unsigned int free_old_xmit_skbs(struct virtnet_info *vi) struct sk_buff *skb; unsigned int len, tot_sgs = 0; - while ((skb = vi->svq->vq_ops->get_buf(vi->svq, &len)) != NULL) { + while ((skb = virtqueue_get_buf(vi->svq, &len)) != NULL) { pr_debug("Sent skb %p\n", skb); vi->dev->stats.tx_bytes += skb->len; vi->dev->stats.tx_packets++; @@ -559,7 +559,7 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) sg_set_buf(sg, &hdr->hdr, sizeof hdr->hdr); hdr->num_sg = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; - return vi->svq->vq_ops->add_buf(vi->svq, sg, hdr->num_sg, 0, skb); + return virtqueue_add_buf(vi->svq, sg, hdr->num_sg, 0, skb); } static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) @@ -578,14 +578,14 @@ again: if (unlikely(capacity < 0)) { netif_stop_queue(dev); dev_warn(&dev->dev, "Unexpected full queue\n"); - if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) { - vi->svq->vq_ops->disable_cb(vi->svq); + if (unlikely(!virtqueue_enable_cb(vi->svq))) { + virtqueue_disable_cb(vi->svq); netif_start_queue(dev); goto again; } return NETDEV_TX_BUSY; } - vi->svq->vq_ops->kick(vi->svq); + virtqueue_kick(vi->svq); /* Don't wait up for transmitted skbs to be freed. */ skb_orphan(skb); @@ -595,12 +595,12 @@ again: * before it gets out of hand. Naturally, this wastes entries. */ if (capacity < 2+MAX_SKB_FRAGS) { netif_stop_queue(dev); - if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) { + if (unlikely(!virtqueue_enable_cb(vi->svq))) { /* More just got used, free them then recheck. */ capacity += free_old_xmit_skbs(vi); if (capacity >= 2+MAX_SKB_FRAGS) { netif_start_queue(dev); - vi->svq->vq_ops->disable_cb(vi->svq); + virtqueue_disable_cb(vi->svq); } } } @@ -645,7 +645,7 @@ static int virtnet_open(struct net_device *dev) * now. virtnet_poll wants re-enable the queue, so we disable here. * We synchronize against interrupts via NAPI_STATE_SCHED */ if (napi_schedule_prep(&vi->napi)) { - vi->rvq->vq_ops->disable_cb(vi->rvq); + virtqueue_disable_cb(vi->rvq); __napi_schedule(&vi->napi); } return 0; @@ -682,15 +682,15 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd, sg_set_buf(&sg[i + 1], sg_virt(s), s->length); sg_set_buf(&sg[out + in - 1], &status, sizeof(status)); - BUG_ON(vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi) < 0); + BUG_ON(virtqueue_add_buf(vi->cvq, sg, out, in, vi) < 0); - vi->cvq->vq_ops->kick(vi->cvq); + virtqueue_kick(vi->cvq); /* * Spin for a response, the kick causes an ioport write, trapping * into the hypervisor, so the request should be handled immediately. */ - while (!vi->cvq->vq_ops->get_buf(vi->cvq, &tmp)) + while (!virtqueue_get_buf(vi->cvq, &tmp)) cpu_relax(); return status == VIRTIO_NET_OK; @@ -1006,13 +1006,13 @@ static void free_unused_bufs(struct virtnet_info *vi) { void *buf; while (1) { - buf = vi->svq->vq_ops->detach_unused_buf(vi->svq); + buf = virtqueue_detach_unused_buf(vi->svq); if (!buf) break; dev_kfree_skb(buf); } while (1) { - buf = vi->rvq->vq_ops->detach_unused_buf(vi->rvq); + buf = virtqueue_detach_unused_buf(vi->rvq); if (!buf) break; if (vi->mergeable_rx_bufs || vi->big_packets) -- cgit v1.2.3 From 7c5e9ed0c84e7d70d887878574590638d5572659 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 12 Apr 2010 16:19:07 +0300 Subject: virtio_ring: remove a level of indirection We have a single virtqueue_ops implementation, and it seems unlikely we'll get another one at this point. So let's remove an unnecessary level of indirection: it would be very easy to re-add it if another implementation surfaces. Signed-off-by: Michael S. Tsirkin Signed-off-by: Rusty Russell --- drivers/virtio/virtio_ring.c | 36 ++++++++++------------ include/linux/virtio.h | 71 +++++++++++--------------------------------- 2 files changed, 34 insertions(+), 73 deletions(-) (limited to 'drivers') diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 0f90634bcb85..0717b5b000bb 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -155,11 +155,11 @@ static int vring_add_indirect(struct vring_virtqueue *vq, return head; } -static int vring_add_buf(struct virtqueue *_vq, - struct scatterlist sg[], - unsigned int out, - unsigned int in, - void *data) +int virtqueue_add_buf(struct virtqueue *_vq, + struct scatterlist sg[], + unsigned int out, + unsigned int in, + void *data) { struct vring_virtqueue *vq = to_vvq(_vq); unsigned int i, avail, head, uninitialized_var(prev); @@ -232,8 +232,9 @@ add_head: return vq->num_free ? vq->vring.num : 0; return vq->num_free; } +EXPORT_SYMBOL_GPL(virtqueue_add_buf); -static void vring_kick(struct virtqueue *_vq) +void virtqueue_kick(struct virtqueue *_vq) { struct vring_virtqueue *vq = to_vvq(_vq); START_USE(vq); @@ -253,6 +254,7 @@ static void vring_kick(struct virtqueue *_vq) END_USE(vq); } +EXPORT_SYMBOL_GPL(virtqueue_kick); static void detach_buf(struct vring_virtqueue *vq, unsigned int head) { @@ -284,7 +286,7 @@ static inline bool more_used(const struct vring_virtqueue *vq) return vq->last_used_idx != vq->vring.used->idx; } -static void *vring_get_buf(struct virtqueue *_vq, unsigned int *len) +void *virtqueue_get_buf(struct virtqueue *_vq, unsigned int *len) { struct vring_virtqueue *vq = to_vvq(_vq); void *ret; @@ -325,15 +327,17 @@ static void *vring_get_buf(struct virtqueue *_vq, unsigned int *len) END_USE(vq); return ret; } +EXPORT_SYMBOL_GPL(virtqueue_get_buf); -static void vring_disable_cb(struct virtqueue *_vq) +void virtqueue_disable_cb(struct virtqueue *_vq) { struct vring_virtqueue *vq = to_vvq(_vq); vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; } +EXPORT_SYMBOL_GPL(virtqueue_disable_cb); -static bool vring_enable_cb(struct virtqueue *_vq) +bool virtqueue_enable_cb(struct virtqueue *_vq) { struct vring_virtqueue *vq = to_vvq(_vq); @@ -351,8 +355,9 @@ static bool vring_enable_cb(struct virtqueue *_vq) END_USE(vq); return true; } +EXPORT_SYMBOL_GPL(virtqueue_enable_cb); -static void *vring_detach_unused_buf(struct virtqueue *_vq) +void *virtqueue_detach_unused_buf(struct virtqueue *_vq) { struct vring_virtqueue *vq = to_vvq(_vq); unsigned int i; @@ -375,6 +380,7 @@ static void *vring_detach_unused_buf(struct virtqueue *_vq) END_USE(vq); return NULL; } +EXPORT_SYMBOL_GPL(virtqueue_detach_unused_buf); irqreturn_t vring_interrupt(int irq, void *_vq) { @@ -396,15 +402,6 @@ irqreturn_t vring_interrupt(int irq, void *_vq) } EXPORT_SYMBOL_GPL(vring_interrupt); -static struct virtqueue_ops vring_vq_ops = { - .add_buf = vring_add_buf, - .get_buf = vring_get_buf, - .kick = vring_kick, - .disable_cb = vring_disable_cb, - .enable_cb = vring_enable_cb, - .detach_unused_buf = vring_detach_unused_buf, -}; - struct virtqueue *vring_new_virtqueue(unsigned int num, unsigned int vring_align, struct virtio_device *vdev, @@ -429,7 +426,6 @@ struct virtqueue *vring_new_virtqueue(unsigned int num, vring_init(&vq->vring, num, pages, vring_align); vq->vq.callback = callback; vq->vq.vdev = vdev; - vq->vq.vq_ops = &vring_vq_ops; vq->vq.name = name; vq->notify = notify; vq->broken = false; diff --git a/include/linux/virtio.h b/include/linux/virtio.h index 18ccc686a429..5b0fce0d2aa2 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -14,7 +14,6 @@ * @callback: the function to call when buffers are consumed (can be NULL). * @name: the name of this virtqueue (mainly for debugging) * @vdev: the virtio device this queue was created for. - * @vq_ops: the operations for this virtqueue (see below). * @priv: a pointer for the virtqueue implementation to use. */ struct virtqueue { @@ -22,94 +21,60 @@ struct virtqueue { void (*callback)(struct virtqueue *vq); const char *name; struct virtio_device *vdev; - struct virtqueue_ops *vq_ops; void *priv; }; /** - * virtqueue_ops - operations for virtqueue abstraction layer - * @add_buf: expose buffer to other end + * operations for virtqueue + * virtqueue_add_buf: expose buffer to other end * vq: the struct virtqueue we're talking about. * sg: the description of the buffer(s). * out_num: the number of sg readable by other side * in_num: the number of sg which are writable (after readable ones) * data: the token identifying the buffer. * Returns remaining capacity of queue (sg segments) or a negative error. - * @kick: update after add_buf + * virtqueue_kick: update after add_buf * vq: the struct virtqueue * After one or more add_buf calls, invoke this to kick the other side. - * @get_buf: get the next used buffer + * virtqueue_get_buf: get the next used buffer * vq: the struct virtqueue we're talking about. * len: the length written into the buffer * Returns NULL or the "data" token handed to add_buf. - * @disable_cb: disable callbacks + * virtqueue_disable_cb: disable callbacks * vq: the struct virtqueue we're talking about. * Note that this is not necessarily synchronous, hence unreliable and only * useful as an optimization. - * @enable_cb: restart callbacks after disable_cb. + * virtqueue_enable_cb: restart callbacks after disable_cb. * vq: the struct virtqueue we're talking about. * This re-enables callbacks; it returns "false" if there are pending * buffers in the queue, to detect a possible race between the driver * checking for more work, and enabling callbacks. - * @detach_unused_buf: detach first unused buffer + * virtqueue_detach_unused_buf: detach first unused buffer * vq: the struct virtqueue we're talking about. * Returns NULL or the "data" token handed to add_buf * * Locking rules are straightforward: the driver is responsible for * locking. No two operations may be invoked simultaneously, with the exception - * of @disable_cb. + * of virtqueue_disable_cb. * * All operations can be called in any context. */ -struct virtqueue_ops { - int (*add_buf)(struct virtqueue *vq, - struct scatterlist sg[], - unsigned int out_num, - unsigned int in_num, - void *data); - void (*kick)(struct virtqueue *vq); +int virtqueue_add_buf(struct virtqueue *vq, + struct scatterlist sg[], + unsigned int out_num, + unsigned int in_num, + void *data); - void *(*get_buf)(struct virtqueue *vq, unsigned int *len); +void virtqueue_kick(struct virtqueue *vq); - void (*disable_cb)(struct virtqueue *vq); - bool (*enable_cb)(struct virtqueue *vq); - void *(*detach_unused_buf)(struct virtqueue *vq); -}; - -static inline int virtqueue_add_buf(struct virtqueue *vq, - struct scatterlist sg[], - unsigned int out_num, - unsigned int in_num, - void *data) -{ - return vq->vq_ops->add_buf(vq, sg, out_num, in_num, data); -} - -static inline int void virtqueue_kick(struct virtqueue *vq) -{ - return vq->vq_ops->kick(vq); -} - -static inline void *virtqueue_get_buf(struct virtqueue *vq, unsigned int *len) -{ - return vq->vq_ops->get_buf(vq, len); -} +void *virtqueue_get_buf(struct virtqueue *vq, unsigned int *len); -static inline void virtqueue_disable_cb(struct virtqueue *vq) -{ - vq->vq_ops->disable_cb(vq); -} +void virtqueue_disable_cb(struct virtqueue *vq); -static inline bool virtqueue_enable_cb(struct virtqueue *vq) -{ - return vq->vq_ops->enable_cb(vq); -} +bool virtqueue_enable_cb(struct virtqueue *vq); -static inline void *virtqueue_detach_unused_buf(struct virtqueue *vq) -{ - return vq->vq_ops->detach_unused_buf(vq); -} +void *virtqueue_detach_unused_buf(struct virtqueue *vq); /** * virtio_device - representation of a device using virtio -- cgit v1.2.3 From 28cfc828e7e1efc620df70b99519784333abcffd Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 13 Apr 2010 16:11:42 +0300 Subject: virtio-rng: use virtqueue_xxx wrappers Switch virtio-rng to new virtqueue_xxx wrappers. Signed-off-by: Michael S. Tsirkin Signed-off-by: Rusty Russell --- drivers/char/hw_random/virtio-rng.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index 64fe0a793efd..75f1cbd61c17 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -32,7 +32,7 @@ static bool busy; static void random_recv_done(struct virtqueue *vq) { /* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */ - if (!vq->vq_ops->get_buf(vq, &data_avail)) + if (!virtqueue_get_buf(vq, &data_avail)) return; complete(&have_data); @@ -46,10 +46,10 @@ static void register_buffer(u8 *buf, size_t size) sg_init_one(&sg, buf, size); /* There should always be room for one buffer. */ - if (vq->vq_ops->add_buf(vq, &sg, 0, 1, buf) < 0) + if (virtqueue_add_buf(vq, &sg, 0, 1, buf) < 0) BUG(); - vq->vq_ops->kick(vq); + virtqueue_kick(vq); } static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) -- cgit v1.2.3 From bbd603efb4238cf78083c00f0a81adfa8994aa33 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 29 Apr 2010 17:26:37 +0300 Subject: virtio: add_buf_gfp Add an add_buf variant that gets gfp parameter. Use that to allocate indirect buffers. Signed-off-by: Michael S. Tsirkin Signed-off-by: Rusty Russell --- drivers/virtio/virtio_ring.c | 20 +++++++++++--------- include/linux/virtio.h | 22 +++++++++++++++++----- 2 files changed, 28 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 0717b5b000bb..1ca88908723b 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -110,13 +110,14 @@ struct vring_virtqueue static int vring_add_indirect(struct vring_virtqueue *vq, struct scatterlist sg[], unsigned int out, - unsigned int in) + unsigned int in, + gfp_t gfp) { struct vring_desc *desc; unsigned head; int i; - desc = kmalloc((out + in) * sizeof(struct vring_desc), GFP_ATOMIC); + desc = kmalloc((out + in) * sizeof(struct vring_desc), gfp); if (!desc) return vq->vring.num; @@ -155,11 +156,12 @@ static int vring_add_indirect(struct vring_virtqueue *vq, return head; } -int virtqueue_add_buf(struct virtqueue *_vq, - struct scatterlist sg[], - unsigned int out, - unsigned int in, - void *data) +int virtqueue_add_buf_gfp(struct virtqueue *_vq, + struct scatterlist sg[], + unsigned int out, + unsigned int in, + void *data, + gfp_t gfp) { struct vring_virtqueue *vq = to_vvq(_vq); unsigned int i, avail, head, uninitialized_var(prev); @@ -171,7 +173,7 @@ int virtqueue_add_buf(struct virtqueue *_vq, /* If the host supports indirect descriptor tables, and we have multiple * buffers, then go indirect. FIXME: tune this threshold */ if (vq->indirect && (out + in) > 1 && vq->num_free) { - head = vring_add_indirect(vq, sg, out, in); + head = vring_add_indirect(vq, sg, out, in, gfp); if (head != vq->vring.num) goto add_head; } @@ -232,7 +234,7 @@ add_head: return vq->num_free ? vq->vring.num : 0; return vq->num_free; } -EXPORT_SYMBOL_GPL(virtqueue_add_buf); +EXPORT_SYMBOL_GPL(virtqueue_add_buf_gfp); void virtqueue_kick(struct virtqueue *_vq) { diff --git a/include/linux/virtio.h b/include/linux/virtio.h index 5b0fce0d2aa2..aff5b4f74041 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -7,6 +7,7 @@ #include #include #include +#include /** * virtqueue - a queue to register buffers for sending or receiving. @@ -32,6 +33,7 @@ struct virtqueue { * out_num: the number of sg readable by other side * in_num: the number of sg which are writable (after readable ones) * data: the token identifying the buffer. + * gfp: how to do memory allocations (if necessary). * Returns remaining capacity of queue (sg segments) or a negative error. * virtqueue_kick: update after add_buf * vq: the struct virtqueue @@ -60,11 +62,21 @@ struct virtqueue { * All operations can be called in any context. */ -int virtqueue_add_buf(struct virtqueue *vq, - struct scatterlist sg[], - unsigned int out_num, - unsigned int in_num, - void *data); +int virtqueue_add_buf_gfp(struct virtqueue *vq, + struct scatterlist sg[], + unsigned int out_num, + unsigned int in_num, + void *data, + gfp_t gfp); + +static inline int virtqueue_add_buf(struct virtqueue *vq, + struct scatterlist sg[], + unsigned int out_num, + unsigned int in_num, + void *data) +{ + return virtqueue_add_buf_gfp(vq, sg, out_num, in_num, data, GFP_ATOMIC); +} void virtqueue_kick(struct virtqueue *vq); -- cgit v1.2.3 From b99fa815d71023b2e330d63cd7f47d6247ffa321 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Wed, 19 May 2010 22:15:46 -0600 Subject: virtio: Revert "virtio: disable multiport console support." This reverts commit b7a413015d2986edf020fba765c906cc9cbcbfc9. Multiport support was disabled for 2.6.34 because we wanted to introduce a new ABI and since we didn't have any released kernel with the older ABI and were out of the merge window, it didn't make sense keeping the older ABI around. Now we revert the patch disabling multiport and rework the ABI in the following patches. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 49 +++++++----------------------------------- include/linux/virtio_console.h | 23 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 48ce834306b5..e53c52b904fb 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -33,35 +33,6 @@ #include #include "hvc_console.h" -/* Moved here from .h file in order to disable MULTIPORT. */ -#define VIRTIO_CONSOLE_F_MULTIPORT 1 /* Does host provide multiple ports? */ - -struct virtio_console_multiport_conf { - struct virtio_console_config config; - /* max. number of ports this device can hold */ - __u32 max_nr_ports; - /* number of ports added so far */ - __u32 nr_ports; -} __attribute__((packed)); - -/* - * A message that's passed between the Host and the Guest for a - * particular port. - */ -struct virtio_console_control { - __u32 id; /* Port number */ - __u16 event; /* The kind of control event (see below) */ - __u16 value; /* Extra information for the key */ -}; - -/* Some events for control messages */ -#define VIRTIO_CONSOLE_PORT_READY 0 -#define VIRTIO_CONSOLE_CONSOLE_PORT 1 -#define VIRTIO_CONSOLE_RESIZE 2 -#define VIRTIO_CONSOLE_PORT_OPEN 3 -#define VIRTIO_CONSOLE_PORT_NAME 4 -#define VIRTIO_CONSOLE_PORT_REMOVE 5 - /* * This is a global struct for storing common data for all the devices * this driver handles. @@ -150,7 +121,7 @@ struct ports_device { spinlock_t cvq_lock; /* The current config space is stored here */ - struct virtio_console_multiport_conf config; + struct virtio_console_config config; /* The virtio device we're associated with */ struct virtio_device *vdev; @@ -1243,7 +1214,7 @@ fail: */ static void config_work_handler(struct work_struct *work) { - struct virtio_console_multiport_conf virtconconf; + struct virtio_console_config virtconconf; struct ports_device *portdev; struct virtio_device *vdev; int err; @@ -1252,8 +1223,7 @@ static void config_work_handler(struct work_struct *work) vdev = portdev->vdev; vdev->config->get(vdev, - offsetof(struct virtio_console_multiport_conf, - nr_ports), + offsetof(struct virtio_console_config, nr_ports), &virtconconf.nr_ports, sizeof(virtconconf.nr_ports)); @@ -1445,19 +1415,16 @@ static int __devinit virtcons_probe(struct virtio_device *vdev) multiport = false; portdev->config.nr_ports = 1; portdev->config.max_nr_ports = 1; -#if 0 /* Multiport is not quite ready yet --RR */ if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT)) { multiport = true; vdev->features[0] |= 1 << VIRTIO_CONSOLE_F_MULTIPORT; - vdev->config->get(vdev, - offsetof(struct virtio_console_multiport_conf, - nr_ports), + vdev->config->get(vdev, offsetof(struct virtio_console_config, + nr_ports), &portdev->config.nr_ports, sizeof(portdev->config.nr_ports)); - vdev->config->get(vdev, - offsetof(struct virtio_console_multiport_conf, - max_nr_ports), + vdev->config->get(vdev, offsetof(struct virtio_console_config, + max_nr_ports), &portdev->config.max_nr_ports, sizeof(portdev->config.max_nr_ports)); if (portdev->config.nr_ports > portdev->config.max_nr_ports) { @@ -1473,7 +1440,6 @@ static int __devinit virtcons_probe(struct virtio_device *vdev) /* Let the Host know we support multiple ports.*/ vdev->config->finalize_features(vdev); -#endif err = init_vqs(portdev); if (err < 0) { @@ -1556,6 +1522,7 @@ static struct virtio_device_id id_table[] = { static unsigned int features[] = { VIRTIO_CONSOLE_F_SIZE, + VIRTIO_CONSOLE_F_MULTIPORT, }; static struct virtio_driver virtio_console = { diff --git a/include/linux/virtio_console.h b/include/linux/virtio_console.h index 92228a8fbcbc..ae4f039515b4 100644 --- a/include/linux/virtio_console.h +++ b/include/linux/virtio_console.h @@ -12,14 +12,37 @@ /* Feature bits */ #define VIRTIO_CONSOLE_F_SIZE 0 /* Does host provide console size? */ +#define VIRTIO_CONSOLE_F_MULTIPORT 1 /* Does host provide multiple ports? */ struct virtio_console_config { /* colums of the screens */ __u16 cols; /* rows of the screens */ __u16 rows; + /* max. number of ports this device can hold */ + __u32 max_nr_ports; + /* number of ports added so far */ + __u32 nr_ports; } __attribute__((packed)); +/* + * A message that's passed between the Host and the Guest for a + * particular port. + */ +struct virtio_console_control { + __u32 id; /* Port number */ + __u16 event; /* The kind of control event (see below) */ + __u16 value; /* Extra information for the key */ +}; + +/* Some events for control messages */ +#define VIRTIO_CONSOLE_PORT_READY 0 +#define VIRTIO_CONSOLE_CONSOLE_PORT 1 +#define VIRTIO_CONSOLE_RESIZE 2 +#define VIRTIO_CONSOLE_PORT_OPEN 3 +#define VIRTIO_CONSOLE_PORT_NAME 4 +#define VIRTIO_CONSOLE_PORT_REMOVE 5 + #ifdef __KERNEL__ int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int)); #endif /* __KERNEL__ */ -- cgit v1.2.3 From 3425e706bf6faa2965c4e99f39085f7367a8f4e2 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Wed, 19 May 2010 22:15:46 -0600 Subject: virtio: console: Add a __send_control_msg() that can send messages without a valid port We will introduce control messages that operate on the device as a whole rather than just ports. Make send_control_msg() a wrapper around __send_control_msg() which does not need a valid port. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index e53c52b904fb..8c24b86aadc9 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -374,22 +374,22 @@ out: return ret; } -static ssize_t send_control_msg(struct port *port, unsigned int event, - unsigned int value) +static ssize_t __send_control_msg(struct ports_device *portdev, u32 port_id, + unsigned int event, unsigned int value) { struct scatterlist sg[1]; struct virtio_console_control cpkt; struct virtqueue *vq; unsigned int len; - if (!use_multiport(port->portdev)) + if (!use_multiport(portdev)) return 0; - cpkt.id = port->id; + cpkt.id = port_id; cpkt.event = event; cpkt.value = value; - vq = port->portdev->c_ovq; + vq = portdev->c_ovq; sg_init_one(sg, &cpkt, sizeof(cpkt)); if (virtqueue_add_buf(vq, sg, 1, 0, &cpkt) >= 0) { @@ -400,6 +400,12 @@ static ssize_t send_control_msg(struct port *port, unsigned int event, return 0; } +static ssize_t send_control_msg(struct port *port, unsigned int event, + unsigned int value) +{ + return __send_control_msg(port->portdev, port->id, event, value); +} + static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count) { struct scatterlist sg[1]; -- cgit v1.2.3 From eaeff9608a8cf43a676b6f4b6235ea9d76192230 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Wed, 19 May 2010 22:15:47 -0600 Subject: virtio: console: Let host know of port or device add failures The host may want to know and let management apps notify of port or device add failures. Send a control message saying the device or port is not ready in this case. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 5 +++++ include/linux/virtio_console.h | 3 +++ 2 files changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 8c24b86aadc9..f63bf77a4825 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1210,6 +1210,8 @@ free_cdev: free_port: kfree(port); fail: + /* The host might want to notify management sw about port add failure */ + send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 0); return err; } @@ -1488,6 +1490,9 @@ free_chrdev: free: kfree(portdev); fail: + /* The host might want to notify mgmt sw about device add failure */ + __send_control_msg(portdev, VIRTIO_CONSOLE_BAD_ID, + VIRTIO_CONSOLE_DEVICE_READY, 0); return err; } diff --git a/include/linux/virtio_console.h b/include/linux/virtio_console.h index ae4f039515b4..015736113c25 100644 --- a/include/linux/virtio_console.h +++ b/include/linux/virtio_console.h @@ -14,6 +14,8 @@ #define VIRTIO_CONSOLE_F_SIZE 0 /* Does host provide console size? */ #define VIRTIO_CONSOLE_F_MULTIPORT 1 /* Does host provide multiple ports? */ +#define VIRTIO_CONSOLE_BAD_ID (~(u32)0) + struct virtio_console_config { /* colums of the screens */ __u16 cols; @@ -42,6 +44,7 @@ struct virtio_console_control { #define VIRTIO_CONSOLE_PORT_OPEN 3 #define VIRTIO_CONSOLE_PORT_NAME 4 #define VIRTIO_CONSOLE_PORT_REMOVE 5 +#define VIRTIO_CONSOLE_DEVICE_READY 6 #ifdef __KERNEL__ int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int)); -- cgit v1.2.3 From 6dc69f970231387d8fe646a831920da26408b5f5 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Wed, 19 May 2010 22:15:47 -0600 Subject: virtio: console: Return -EPIPE to hvc_console if we lost the connection hvc_console handles -EPIPE properly when the connection to the host is lost. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index f63bf77a4825..11a9573f901e 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -653,7 +653,7 @@ static int put_chars(u32 vtermno, const char *buf, int count) port = find_port_by_vtermno(vtermno); if (!port) - return 0; + return -EPIPE; return send_buf(port, (void *)buf, count); } @@ -669,9 +669,13 @@ static int get_chars(u32 vtermno, char *buf, int count) { struct port *port; + /* If we've not set up the port yet, we have no input to give. */ + if (unlikely(early_put_chars)) + return 0; + port = find_port_by_vtermno(vtermno); if (!port) - return 0; + return -EPIPE; /* If we don't have an input queue yet, we can't get input. */ BUG_ON(!port->in_vq); -- cgit v1.2.3 From 69eb9a9f69572c0ebe08a0a46f56bdfdcdaa19a0 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Wed, 19 May 2010 22:15:47 -0600 Subject: virtio: console: Don't call hvc_remove() on unplugging console ports hvc_remove() has some bug which freezes other active hvc ports when one port is removed. So disable calling of hvc_remove() which deregisters a port with the hvc_console. If the hvc_console code calls into our get_chars() routine as a result of a poll operation, we will return -EPIPE and the hvc_console code will then do the necessary cleanup. This call will be restored when the bug in hvc_remove() is found and fixed. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 11a9573f901e..9a698707e14b 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -869,7 +869,18 @@ static int remove_port(struct port *port) spin_lock_irq(&pdrvdata_lock); list_del(&port->cons.list); spin_unlock_irq(&pdrvdata_lock); +#if 0 + /* + * hvc_remove() not called as removing one hvc port + * results in other hvc ports getting frozen. + * + * Once this is resolved in hvc, this functionality + * will be enabled. Till that is done, the -EPIPE + * return from get_chars() above will help + * hvc_console.c to clean up on ports we remove here. + */ hvc_remove(port->cons.hvc); +#endif } if (port->guest_connected) send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 0); -- cgit v1.2.3 From 99f905f88a5b8478755605e08ed4bce40034cc6c Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Wed, 19 May 2010 22:15:48 -0600 Subject: virtio: console: Remove config work handler We're going to switch to using control messages for port hot-plug and initial port discovery. Remove the config work handler which handled port hot-plug so far. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 64 +------------------------------------------ 1 file changed, 1 insertion(+), 63 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 9a698707e14b..e1f92a0c5c5f 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -110,7 +110,6 @@ struct ports_device { * notification */ struct work_struct control_work; - struct work_struct config_work; struct list_head ports; @@ -1084,10 +1083,7 @@ static void config_intr(struct virtio_device *vdev) struct ports_device *portdev; portdev = vdev->priv; - if (use_multiport(portdev)) { - /* Handle port hot-add */ - schedule_work(&portdev->config_work); - } + /* * We'll use this way of resizing only for legacy support. * For newer userspace (VIRTIO_CONSOLE_F_MULTPORT+), use @@ -1230,62 +1226,6 @@ fail: return err; } -/* - * The workhandler for config-space updates. - * - * This is called when ports are hot-added. - */ -static void config_work_handler(struct work_struct *work) -{ - struct virtio_console_config virtconconf; - struct ports_device *portdev; - struct virtio_device *vdev; - int err; - - portdev = container_of(work, struct ports_device, config_work); - - vdev = portdev->vdev; - vdev->config->get(vdev, - offsetof(struct virtio_console_config, nr_ports), - &virtconconf.nr_ports, - sizeof(virtconconf.nr_ports)); - - if (portdev->config.nr_ports == virtconconf.nr_ports) { - /* - * Port 0 got hot-added. Since we already did all the - * other initialisation for it, just tell the Host - * that the port is ready if we find the port. In - * case the port was hot-removed earlier, we call - * add_port to add the port. - */ - struct port *port; - - port = find_port_by_id(portdev, 0); - if (!port) - add_port(portdev, 0); - else - send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1); - return; - } - if (virtconconf.nr_ports > portdev->config.max_nr_ports) { - dev_warn(&vdev->dev, - "More ports specified (%u) than allowed (%u)", - portdev->config.nr_ports + 1, - portdev->config.max_nr_ports); - return; - } - if (virtconconf.nr_ports < portdev->config.nr_ports) - return; - - /* Hot-add ports */ - while (virtconconf.nr_ports - portdev->config.nr_ports) { - err = add_port(portdev, portdev->config.nr_ports); - if (err) - break; - portdev->config.nr_ports++; - } -} - static int init_vqs(struct ports_device *portdev) { vq_callback_t **io_callbacks; @@ -1478,7 +1418,6 @@ static int __devinit virtcons_probe(struct virtio_device *vdev) spin_lock_init(&portdev->cvq_lock); INIT_WORK(&portdev->control_work, &control_work_handler); - INIT_WORK(&portdev->config_work, &config_work_handler); nr_added_bufs = fill_queue(portdev->c_ivq, &portdev->cvq_lock); if (!nr_added_bufs) { @@ -1521,7 +1460,6 @@ static void virtcons_remove(struct virtio_device *vdev) portdev = vdev->priv; cancel_work_sync(&portdev->control_work); - cancel_work_sync(&portdev->config_work); list_for_each_entry_safe(port, port2, &portdev->ports, list) remove_port(port); -- cgit v1.2.3 From c446f8fcc9fba3369bffb894b31756cf7a09f783 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Wed, 19 May 2010 22:15:48 -0600 Subject: virtio: console: Move code around for future patches We're going to use add_port() from handle_control_message() in the next patch. Move the add_port() and fill_queue(), which depends on it, above handle_control_message() to avoid forward declarations. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 266 +++++++++++++++++++++--------------------- 1 file changed, 133 insertions(+), 133 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index e1f92a0c5c5f..237eee26fbc3 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -855,6 +855,139 @@ static const struct file_operations port_debugfs_ops = { .read = debugfs_read, }; +static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock) +{ + struct port_buffer *buf; + unsigned int nr_added_bufs; + int ret; + + nr_added_bufs = 0; + do { + buf = alloc_buf(PAGE_SIZE); + if (!buf) + break; + + spin_lock_irq(lock); + ret = add_inbuf(vq, buf); + if (ret < 0) { + spin_unlock_irq(lock); + free_buf(buf); + break; + } + nr_added_bufs++; + spin_unlock_irq(lock); + } while (ret > 0); + + return nr_added_bufs; +} + +static int add_port(struct ports_device *portdev, u32 id) +{ + char debugfs_name[16]; + struct port *port; + struct port_buffer *buf; + dev_t devt; + unsigned int nr_added_bufs; + int err; + + port = kmalloc(sizeof(*port), GFP_KERNEL); + if (!port) { + err = -ENOMEM; + goto fail; + } + + port->portdev = portdev; + port->id = id; + + port->name = NULL; + port->inbuf = NULL; + port->cons.hvc = NULL; + + port->host_connected = port->guest_connected = false; + + port->in_vq = portdev->in_vqs[port->id]; + port->out_vq = portdev->out_vqs[port->id]; + + cdev_init(&port->cdev, &port_fops); + + devt = MKDEV(portdev->chr_major, id); + err = cdev_add(&port->cdev, devt, 1); + if (err < 0) { + dev_err(&port->portdev->vdev->dev, + "Error %d adding cdev for port %u\n", err, id); + goto free_port; + } + port->dev = device_create(pdrvdata.class, &port->portdev->vdev->dev, + devt, port, "vport%up%u", + port->portdev->drv_index, id); + if (IS_ERR(port->dev)) { + err = PTR_ERR(port->dev); + dev_err(&port->portdev->vdev->dev, + "Error %d creating device for port %u\n", + err, id); + goto free_cdev; + } + + spin_lock_init(&port->inbuf_lock); + init_waitqueue_head(&port->waitqueue); + + /* Fill the in_vq with buffers so the host can send us data. */ + nr_added_bufs = fill_queue(port->in_vq, &port->inbuf_lock); + if (!nr_added_bufs) { + dev_err(port->dev, "Error allocating inbufs\n"); + err = -ENOMEM; + goto free_device; + } + + /* + * If we're not using multiport support, this has to be a console port + */ + if (!use_multiport(port->portdev)) { + err = init_port_console(port); + if (err) + goto free_inbufs; + } + + spin_lock_irq(&portdev->ports_lock); + list_add_tail(&port->list, &port->portdev->ports); + spin_unlock_irq(&portdev->ports_lock); + + /* + * Tell the Host we're set so that it can send us various + * configuration parameters for this port (eg, port name, + * caching, whether this is a console port, etc.) + */ + send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1); + + if (pdrvdata.debugfs_dir) { + /* + * Finally, create the debugfs file that we can use to + * inspect a port's state at any time + */ + sprintf(debugfs_name, "vport%up%u", + port->portdev->drv_index, id); + port->debugfs_file = debugfs_create_file(debugfs_name, 0444, + pdrvdata.debugfs_dir, + port, + &port_debugfs_ops); + } + return 0; + +free_inbufs: + while ((buf = virtqueue_detach_unused_buf(port->in_vq))) + free_buf(buf); +free_device: + device_destroy(pdrvdata.class, port->dev->devt); +free_cdev: + cdev_del(&port->cdev); +free_port: + kfree(port); +fail: + /* The host might want to notify management sw about port add failure */ + send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 0); + return err; +} + /* Remove all port-specific data. */ static int remove_port(struct port *port) { @@ -1093,139 +1226,6 @@ static void config_intr(struct virtio_device *vdev) resize_console(find_port_by_id(portdev, 0)); } -static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock) -{ - struct port_buffer *buf; - unsigned int nr_added_bufs; - int ret; - - nr_added_bufs = 0; - do { - buf = alloc_buf(PAGE_SIZE); - if (!buf) - break; - - spin_lock_irq(lock); - ret = add_inbuf(vq, buf); - if (ret < 0) { - spin_unlock_irq(lock); - free_buf(buf); - break; - } - nr_added_bufs++; - spin_unlock_irq(lock); - } while (ret > 0); - - return nr_added_bufs; -} - -static int add_port(struct ports_device *portdev, u32 id) -{ - char debugfs_name[16]; - struct port *port; - struct port_buffer *buf; - dev_t devt; - unsigned int nr_added_bufs; - int err; - - port = kmalloc(sizeof(*port), GFP_KERNEL); - if (!port) { - err = -ENOMEM; - goto fail; - } - - port->portdev = portdev; - port->id = id; - - port->name = NULL; - port->inbuf = NULL; - port->cons.hvc = NULL; - - port->host_connected = port->guest_connected = false; - - port->in_vq = portdev->in_vqs[port->id]; - port->out_vq = portdev->out_vqs[port->id]; - - cdev_init(&port->cdev, &port_fops); - - devt = MKDEV(portdev->chr_major, id); - err = cdev_add(&port->cdev, devt, 1); - if (err < 0) { - dev_err(&port->portdev->vdev->dev, - "Error %d adding cdev for port %u\n", err, id); - goto free_port; - } - port->dev = device_create(pdrvdata.class, &port->portdev->vdev->dev, - devt, port, "vport%up%u", - port->portdev->drv_index, id); - if (IS_ERR(port->dev)) { - err = PTR_ERR(port->dev); - dev_err(&port->portdev->vdev->dev, - "Error %d creating device for port %u\n", - err, id); - goto free_cdev; - } - - spin_lock_init(&port->inbuf_lock); - init_waitqueue_head(&port->waitqueue); - - /* Fill the in_vq with buffers so the host can send us data. */ - nr_added_bufs = fill_queue(port->in_vq, &port->inbuf_lock); - if (!nr_added_bufs) { - dev_err(port->dev, "Error allocating inbufs\n"); - err = -ENOMEM; - goto free_device; - } - - /* - * If we're not using multiport support, this has to be a console port - */ - if (!use_multiport(port->portdev)) { - err = init_port_console(port); - if (err) - goto free_inbufs; - } - - spin_lock_irq(&portdev->ports_lock); - list_add_tail(&port->list, &port->portdev->ports); - spin_unlock_irq(&portdev->ports_lock); - - /* - * Tell the Host we're set so that it can send us various - * configuration parameters for this port (eg, port name, - * caching, whether this is a console port, etc.) - */ - send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1); - - if (pdrvdata.debugfs_dir) { - /* - * Finally, create the debugfs file that we can use to - * inspect a port's state at any time - */ - sprintf(debugfs_name, "vport%up%u", - port->portdev->drv_index, id); - port->debugfs_file = debugfs_create_file(debugfs_name, 0444, - pdrvdata.debugfs_dir, - port, - &port_debugfs_ops); - } - return 0; - -free_inbufs: - while ((buf = virtqueue_detach_unused_buf(port->in_vq))) - free_buf(buf); -free_device: - device_destroy(pdrvdata.class, port->dev->devt); -free_cdev: - cdev_del(&port->cdev); -free_port: - kfree(port); -fail: - /* The host might want to notify management sw about port add failure */ - send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 0); - return err; -} - static int init_vqs(struct ports_device *portdev) { vq_callback_t **io_callbacks; -- cgit v1.2.3 From f909f850d666e3dbac1ee7c9d5d83416bd02f84e Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Wed, 19 May 2010 22:15:48 -0600 Subject: virtio: console: Use a control message to add ports Instead of the host and guest independently enumerating ports, switch to a control message to add ports where the host supplies the port number so there's no ambiguity or a possibility of a race between the host and the guest port numbers. We now no longer need the 'nr_ports' config value. Since no kernel has been released with the MULTIPORT changes yet, we have a chance to fiddle with the config space without adding compatibility features. This is beneficial for management software, which would now be able to instantiate ports at known locations and avoid problems that arise with implicit numbering in the host and the guest. This removes the 'guessing game' part of it, and management software can now actually indicate which id to spawn a particular port on. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 77 ++++++++++++++++++------------------------ include/linux/virtio_console.h | 17 +++++----- 2 files changed, 41 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 237eee26fbc3..7671914be172 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1048,7 +1048,7 @@ static void handle_control_message(struct ports_device *portdev, cpkt = (struct virtio_console_control *)(buf->buf + buf->offset); port = find_port_by_id(portdev, cpkt->id); - if (!port) { + if (!port && cpkt->event != VIRTIO_CONSOLE_PORT_ADD) { /* No valid header at start of buffer. Drop it. */ dev_dbg(&portdev->vdev->dev, "Invalid index %u in control packet\n", cpkt->id); @@ -1056,6 +1056,30 @@ static void handle_control_message(struct ports_device *portdev, } switch (cpkt->event) { + case VIRTIO_CONSOLE_PORT_ADD: + if (port) { + /* + * This can happen for port 0: we have to + * create a console port during probe() as was + * the behaviour before the MULTIPORT feature. + * On a newer host, when the host tells us + * that a port 0 is available, we should just + * say we have the port all set up. + */ + send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1); + break; + } + if (cpkt->id >= portdev->config.max_nr_ports) { + dev_warn(&portdev->vdev->dev, + "Request for adding port with out-of-bound id %u, max. supported id: %u\n", + cpkt->id, portdev->config.max_nr_ports - 1); + break; + } + add_port(portdev, cpkt->id); + break; + case VIRTIO_CONSOLE_PORT_REMOVE: + remove_port(port); + break; case VIRTIO_CONSOLE_CONSOLE_PORT: if (!cpkt->value) break; @@ -1114,32 +1138,6 @@ static void handle_control_message(struct ports_device *portdev, kobject_uevent(&port->dev->kobj, KOBJ_CHANGE); } break; - case VIRTIO_CONSOLE_PORT_REMOVE: - /* - * Hot unplug the port. We don't decrement nr_ports - * since we don't want to deal with extra complexities - * of using the lowest-available port id: We can just - * pick up the nr_ports number as the id and not have - * userspace send it to us. This helps us in two - * ways: - * - * - We don't need to have a 'port_id' field in the - * config space when a port is hot-added. This is a - * good thing as we might queue up multiple hotplug - * requests issued in our workqueue. - * - * - Another way to deal with this would have been to - * use a bitmap of the active ports and select the - * lowest non-active port from that map. That - * bloats the already tight config space and we - * would end up artificially limiting the - * max. number of ports to sizeof(bitmap). Right - * now we can support 2^32 ports (as the port id is - * stored in a u32 type). - * - */ - remove_port(port); - break; } } @@ -1347,7 +1345,6 @@ static const struct file_operations portdev_fops = { static int __devinit virtcons_probe(struct virtio_device *vdev) { struct ports_device *portdev; - u32 i; int err; bool multiport; @@ -1376,29 +1373,15 @@ static int __devinit virtcons_probe(struct virtio_device *vdev) } multiport = false; - portdev->config.nr_ports = 1; portdev->config.max_nr_ports = 1; if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT)) { multiport = true; vdev->features[0] |= 1 << VIRTIO_CONSOLE_F_MULTIPORT; - vdev->config->get(vdev, offsetof(struct virtio_console_config, - nr_ports), - &portdev->config.nr_ports, - sizeof(portdev->config.nr_ports)); vdev->config->get(vdev, offsetof(struct virtio_console_config, max_nr_ports), &portdev->config.max_nr_ports, sizeof(portdev->config.max_nr_ports)); - if (portdev->config.nr_ports > portdev->config.max_nr_ports) { - dev_warn(&vdev->dev, - "More ports (%u) specified than allowed (%u). Will init %u ports.", - portdev->config.nr_ports, - portdev->config.max_nr_ports, - portdev->config.max_nr_ports); - - portdev->config.nr_ports = portdev->config.max_nr_ports; - } } /* Let the Host know we support multiple ports.*/ @@ -1428,11 +1411,17 @@ static int __devinit virtcons_probe(struct virtio_device *vdev) } } - for (i = 0; i < portdev->config.nr_ports; i++) - add_port(portdev, i); + /* + * For backward compatibility: if we're running on an older + * host, we always want to create a console port. + */ + add_port(portdev, 0); /* Start using the new console output. */ early_put_chars = NULL; + + __send_control_msg(portdev, VIRTIO_CONSOLE_BAD_ID, + VIRTIO_CONSOLE_DEVICE_READY, 1); return 0; free_vqs: diff --git a/include/linux/virtio_console.h b/include/linux/virtio_console.h index 015736113c25..a85064db8f94 100644 --- a/include/linux/virtio_console.h +++ b/include/linux/virtio_console.h @@ -23,8 +23,6 @@ struct virtio_console_config { __u16 rows; /* max. number of ports this device can hold */ __u32 max_nr_ports; - /* number of ports added so far */ - __u32 nr_ports; } __attribute__((packed)); /* @@ -38,13 +36,14 @@ struct virtio_console_control { }; /* Some events for control messages */ -#define VIRTIO_CONSOLE_PORT_READY 0 -#define VIRTIO_CONSOLE_CONSOLE_PORT 1 -#define VIRTIO_CONSOLE_RESIZE 2 -#define VIRTIO_CONSOLE_PORT_OPEN 3 -#define VIRTIO_CONSOLE_PORT_NAME 4 -#define VIRTIO_CONSOLE_PORT_REMOVE 5 -#define VIRTIO_CONSOLE_DEVICE_READY 6 +#define VIRTIO_CONSOLE_DEVICE_READY 0 +#define VIRTIO_CONSOLE_PORT_ADD 1 +#define VIRTIO_CONSOLE_PORT_REMOVE 2 +#define VIRTIO_CONSOLE_PORT_READY 3 +#define VIRTIO_CONSOLE_CONSOLE_PORT 4 +#define VIRTIO_CONSOLE_RESIZE 5 +#define VIRTIO_CONSOLE_PORT_OPEN 6 +#define VIRTIO_CONSOLE_PORT_NAME 7 #ifdef __KERNEL__ int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int)); -- cgit v1.2.3 From 1d05160be743c506b1d6926e7c637496fa750cd3 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Wed, 19 May 2010 22:15:49 -0600 Subject: virtio: console: Don't always create a port 0 if using multiport If we're using multiport, there's no point in always creating a console port. Create the console port only if the host doesn't support multiport. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 7671914be172..6207e3729923 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -784,6 +784,13 @@ int init_port_console(struct port *port) spin_unlock_irq(&pdrvdata_lock); port->guest_connected = true; + /* + * Start using the new console output if this is the first + * console to come up. + */ + if (early_put_chars) + early_put_chars = NULL; + /* Notify host of port being opened */ send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 1); @@ -1058,14 +1065,8 @@ static void handle_control_message(struct ports_device *portdev, switch (cpkt->event) { case VIRTIO_CONSOLE_PORT_ADD: if (port) { - /* - * This can happen for port 0: we have to - * create a console port during probe() as was - * the behaviour before the MULTIPORT feature. - * On a newer host, when the host tells us - * that a port 0 is available, we should just - * say we have the port all set up. - */ + dev_dbg(&portdev->vdev->dev, + "Port %u already added\n", port->id); send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1); break; } @@ -1409,17 +1410,14 @@ static int __devinit virtcons_probe(struct virtio_device *vdev) err = -ENOMEM; goto free_vqs; } + } else { + /* + * For backward compatibility: Create a console port + * if we're running on older host. + */ + add_port(portdev, 0); } - /* - * For backward compatibility: if we're running on an older - * host, we always want to create a console port. - */ - add_port(portdev, 0); - - /* Start using the new console output. */ - early_put_chars = NULL; - __send_control_msg(portdev, VIRTIO_CONSOLE_BAD_ID, VIRTIO_CONSOLE_DEVICE_READY, 1); return 0; -- cgit v1.2.3 From 60caacd3eeab68672961e88db01e26735527d521 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Wed, 19 May 2010 22:15:49 -0600 Subject: virtio: console: Rename wait_is_over() to will_read_block() We'll introduce a function that checks if write will block. Have function names that are similar for the two cases. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 6207e3729923..a39bf191da02 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -479,9 +479,9 @@ static ssize_t fill_readbuf(struct port *port, char *out_buf, size_t out_count, } /* The condition that must be true for polling to end */ -static bool wait_is_over(struct port *port) +static bool will_read_block(struct port *port) { - return port_has_data(port) || !port->host_connected; + return !port_has_data(port) && port->host_connected; } static ssize_t port_fops_read(struct file *filp, char __user *ubuf, @@ -504,7 +504,7 @@ static ssize_t port_fops_read(struct file *filp, char __user *ubuf, return -EAGAIN; ret = wait_event_interruptible(port->waitqueue, - wait_is_over(port)); + !will_read_block(port)); if (ret < 0) return ret; } -- cgit v1.2.3 From cdfadfc1adb87fc7e8a631b1f299715feacbde90 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Wed, 19 May 2010 22:15:50 -0600 Subject: virtio: console: Add support for nonblocking write()s If the host port is not open, a write() should either just return if the file is opened in non-blocking mode, or block till the host port is opened. Also, don't spin till host consumes data for nonblocking ports. For non-blocking ports, we can do away with the spinning and reclaim the buffers consumed by the host on the next write call or on the condition that'll make poll return. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 119 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 111 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index a39bf191da02..4175a2ae972f 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -159,6 +159,9 @@ struct port { */ spinlock_t inbuf_lock; + /* Protect the operations on the out_vq. */ + spinlock_t outvq_lock; + /* The IO vqs for this port */ struct virtqueue *in_vq, *out_vq; @@ -184,6 +187,8 @@ struct port { /* The 'id' to identify the port with the Host */ u32 id; + bool outvq_full; + /* Is the host device open */ bool host_connected; @@ -405,15 +410,33 @@ static ssize_t send_control_msg(struct port *port, unsigned int event, return __send_control_msg(port->portdev, port->id, event, value); } -static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count) +/* Callers must take the port->outvq_lock */ +static void reclaim_consumed_buffers(struct port *port) +{ + void *buf; + unsigned int len; + + while ((buf = virtqueue_get_buf(port->out_vq, &len))) { + kfree(buf); + port->outvq_full = false; + } +} + +static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count, + bool nonblock) { struct scatterlist sg[1]; struct virtqueue *out_vq; ssize_t ret; + unsigned long flags; unsigned int len; out_vq = port->out_vq; + spin_lock_irqsave(&port->outvq_lock, flags); + + reclaim_consumed_buffers(port); + sg_init_one(sg, in_buf, in_count); ret = virtqueue_add_buf(out_vq, sg, 1, 0, in_buf); @@ -422,14 +445,29 @@ static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count) if (ret < 0) { in_count = 0; - goto fail; + goto done; } - /* Wait till the host acknowledges it pushed out the data we sent. */ + if (ret == 0) + port->outvq_full = true; + + if (nonblock) + goto done; + + /* + * Wait till the host acknowledges it pushed out the data we + * sent. This is done for ports in blocking mode or for data + * from the hvc_console; the tty operations are performed with + * spinlocks held so we can't sleep here. + */ while (!virtqueue_get_buf(out_vq, &len)) cpu_relax(); -fail: - /* We're expected to return the amount of data we wrote */ +done: + spin_unlock_irqrestore(&port->outvq_lock, flags); + /* + * We're expected to return the amount of data we wrote -- all + * of it + */ return in_count; } @@ -484,6 +522,25 @@ static bool will_read_block(struct port *port) return !port_has_data(port) && port->host_connected; } +static bool will_write_block(struct port *port) +{ + bool ret; + + if (!port->host_connected) + return true; + + spin_lock_irq(&port->outvq_lock); + /* + * Check if the Host has consumed any buffers since we last + * sent data (this is only applicable for nonblocking ports). + */ + reclaim_consumed_buffers(port); + ret = port->outvq_full; + spin_unlock_irq(&port->outvq_lock); + + return ret; +} + static ssize_t port_fops_read(struct file *filp, char __user *ubuf, size_t count, loff_t *offp) { @@ -530,9 +587,22 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf, struct port *port; char *buf; ssize_t ret; + bool nonblock; port = filp->private_data; + nonblock = filp->f_flags & O_NONBLOCK; + + if (will_write_block(port)) { + if (nonblock) + return -EAGAIN; + + ret = wait_event_interruptible(port->waitqueue, + !will_write_block(port)); + if (ret < 0) + return ret; + } + count = min((size_t)(32 * 1024), count); buf = kmalloc(count, GFP_KERNEL); @@ -545,9 +615,14 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf, goto free_buf; } - ret = send_buf(port, buf, count); + ret = send_buf(port, buf, count, nonblock); + + if (nonblock && ret > 0) + goto out; + free_buf: kfree(buf); +out: return ret; } @@ -562,7 +637,7 @@ static unsigned int port_fops_poll(struct file *filp, poll_table *wait) ret = 0; if (port->inbuf) ret |= POLLIN | POLLRDNORM; - if (port->host_connected) + if (!will_write_block(port)) ret |= POLLOUT; if (!port->host_connected) ret |= POLLHUP; @@ -586,6 +661,10 @@ static int port_fops_release(struct inode *inode, struct file *filp) spin_unlock_irq(&port->inbuf_lock); + spin_lock_irq(&port->outvq_lock); + reclaim_consumed_buffers(port); + spin_unlock_irq(&port->outvq_lock); + return 0; } @@ -614,6 +693,15 @@ static int port_fops_open(struct inode *inode, struct file *filp) port->guest_connected = true; spin_unlock_irq(&port->inbuf_lock); + spin_lock_irq(&port->outvq_lock); + /* + * There might be a chance that we missed reclaiming a few + * buffers in the window of the port getting previously closed + * and opening now. + */ + reclaim_consumed_buffers(port); + spin_unlock_irq(&port->outvq_lock); + /* Notify host of port being opened */ send_control_msg(filp->private_data, VIRTIO_CONSOLE_PORT_OPEN, 1); @@ -654,7 +742,7 @@ static int put_chars(u32 vtermno, const char *buf, int count) if (!port) return -EPIPE; - return send_buf(port, (void *)buf, count); + return send_buf(port, (void *)buf, count, false); } /* @@ -845,6 +933,8 @@ static ssize_t debugfs_read(struct file *filp, char __user *ubuf, "guest_connected: %d\n", port->guest_connected); out_offset += snprintf(buf + out_offset, out_count - out_offset, "host_connected: %d\n", port->host_connected); + out_offset += snprintf(buf + out_offset, out_count - out_offset, + "outvq_full: %d\n", port->outvq_full); out_offset += snprintf(buf + out_offset, out_count - out_offset, "is_console: %s\n", is_console_port(port) ? "yes" : "no"); @@ -912,6 +1002,8 @@ static int add_port(struct ports_device *portdev, u32 id) port->host_connected = port->guest_connected = false; + port->outvq_full = false; + port->in_vq = portdev->in_vqs[port->id]; port->out_vq = portdev->out_vqs[port->id]; @@ -936,6 +1028,7 @@ static int add_port(struct ports_device *portdev, u32 id) } spin_lock_init(&port->inbuf_lock); + spin_lock_init(&port->outvq_lock); init_waitqueue_head(&port->waitqueue); /* Fill the in_vq with buffers so the host can send us data. */ @@ -1031,6 +1124,8 @@ static int remove_port(struct port *port) /* Remove unused data this port might have received. */ discard_port_data(port); + reclaim_consumed_buffers(port); + /* Remove buffers we queued up for the Host to send us data in. */ while ((buf = virtqueue_detach_unused_buf(port->in_vq))) free_buf(buf); @@ -1102,6 +1197,14 @@ static void handle_control_message(struct ports_device *portdev, case VIRTIO_CONSOLE_PORT_OPEN: port->host_connected = cpkt->value; wake_up_interruptible(&port->waitqueue); + /* + * If the host port got closed and the host had any + * unconsumed buffers, we'll be able to reclaim them + * now. + */ + spin_lock_irq(&port->outvq_lock); + reclaim_consumed_buffers(port); + spin_unlock_irq(&port->outvq_lock); break; case VIRTIO_CONSOLE_PORT_NAME: /* -- cgit v1.2.3 From 4038f5b767a610c5a5d92d7047755c663ead1568 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Thu, 6 May 2010 02:05:07 +0530 Subject: virtio: console: Resize console port 0 on config intr only if multiport is off When using multiport, we'll use control messages. Ensure we don't accidentally update port 0 size on config interrupts. Signed-off-by: Amit Shah CC: Christian Borntraeger CC: linuxppc-dev@ozlabs.org CC: Kusanagi Kouichi Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 4175a2ae972f..1e3f4674da4a 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1319,13 +1319,16 @@ static void config_intr(struct virtio_device *vdev) portdev = vdev->priv; - /* - * We'll use this way of resizing only for legacy support. - * For newer userspace (VIRTIO_CONSOLE_F_MULTPORT+), use - * control messages to indicate console size changes so that - * it can be done per-port - */ - resize_console(find_port_by_id(portdev, 0)); + if (!use_multiport(portdev)) { + /* + * We'll use this way of resizing only for legacy + * support. For newer userspace + * (VIRTIO_CONSOLE_F_MULTPORT+), use control messages + * to indicate console size changes so that it can be + * done per-port. + */ + resize_console(find_port_by_id(portdev, 0)); + } } static int init_vqs(struct ports_device *portdev) -- cgit v1.2.3 From 9778829cffd4d8d68c7e457645f958a82d4c4d8b Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Thu, 6 May 2010 02:05:08 +0530 Subject: virtio: console: Store each console's size in the console structure With support for multiple consoles, just using one {rows,cols} pair in the config space is not going to suffice. Store each console's size as part of the console struct. This changes the behaviour for one case when multiport is not enabled: when notifier_add_vio() is called, the console size is taken from that of the last config-space update instead of fetching it afresh from the config space. Also add a helper to update the size in the console struct as we'll need to use the same code to update the size via control messages when multiport support is enabled. Signed-off-by: Amit Shah CC: Christian Borntraeger CC: linuxppc-dev@ozlabs.org CC: Kusanagi Kouichi Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 1e3f4674da4a..f1fe11a344e9 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -78,6 +78,9 @@ struct console { /* The hvc device associated with this console port */ struct hvc_struct *hvc; + /* The size of the console */ + struct winsize ws; + /* * This number identifies the number that we used to register * with hvc in hvc_instantiate() and hvc_alloc(); this is the @@ -773,22 +776,14 @@ static int get_chars(u32 vtermno, char *buf, int count) static void resize_console(struct port *port) { struct virtio_device *vdev; - struct winsize ws; /* The port could have been hot-unplugged */ - if (!port) + if (!port || !is_console_port(port)) return; vdev = port->portdev->vdev; - if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE)) { - vdev->config->get(vdev, - offsetof(struct virtio_console_config, cols), - &ws.ws_col, sizeof(u16)); - vdev->config->get(vdev, - offsetof(struct virtio_console_config, rows), - &ws.ws_row, sizeof(u16)); - hvc_resize(port->cons.hvc, ws); - } + if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE)) + hvc_resize(port->cons.hvc, port->cons.ws); } /* We set the configuration at this point, since we now have a tty */ @@ -952,6 +947,15 @@ static const struct file_operations port_debugfs_ops = { .read = debugfs_read, }; +static void set_console_size(struct port *port, u16 rows, u16 cols) +{ + if (!port || !is_console_port(port)) + return; + + port->cons.ws.ws_row = rows; + port->cons.ws.ws_col = cols; +} + static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock) { struct port_buffer *buf; @@ -1000,6 +1004,8 @@ static int add_port(struct ports_device *portdev, u32 id) port->inbuf = NULL; port->cons.hvc = NULL; + port->cons.ws.ws_row = port->cons.ws.ws_col = 0; + port->host_connected = port->guest_connected = false; port->outvq_full = false; @@ -1320,6 +1326,19 @@ static void config_intr(struct virtio_device *vdev) portdev = vdev->priv; if (!use_multiport(portdev)) { + struct port *port; + u16 rows, cols; + + vdev->config->get(vdev, + offsetof(struct virtio_console_config, cols), + &cols, sizeof(u16)); + vdev->config->get(vdev, + offsetof(struct virtio_console_config, rows), + &rows, sizeof(u16)); + + port = find_port_by_id(portdev, 0); + set_console_size(port, rows, cols); + /* * We'll use this way of resizing only for legacy * support. For newer userspace @@ -1327,7 +1346,7 @@ static void config_intr(struct virtio_device *vdev) * to indicate console size changes so that it can be * done per-port. */ - resize_console(find_port_by_id(portdev, 0)); + resize_console(port); } } -- cgit v1.2.3 From 8345adbf96fc1bde7d9846aadbe5af9b2ae90882 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Thu, 6 May 2010 02:05:09 +0530 Subject: virtio: console: Accept console size along with resize control message The VIRTIO_CONSOLE_RESIZE control message sent to us by the host now contains the new {rows, cols} values for the console. This ensures each console port gets its own size, and we don't depend on the config-space rows and cols values at all now. Signed-off-by: Amit Shah CC: Christian Borntraeger CC: linuxppc-dev@ozlabs.org CC: Kusanagi Kouichi Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index f1fe11a344e9..458d907e3621 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1194,12 +1194,23 @@ static void handle_control_message(struct ports_device *portdev, * have to notify the host first. */ break; - case VIRTIO_CONSOLE_RESIZE: + case VIRTIO_CONSOLE_RESIZE: { + struct { + __u16 rows; + __u16 cols; + } size; + if (!is_console_port(port)) break; + + memcpy(&size, buf->buf + buf->offset + sizeof(*cpkt), + sizeof(size)); + set_console_size(port, size.rows, size.cols); + port->cons.hvc->irq_requested = 1; resize_console(port); break; + } case VIRTIO_CONSOLE_PORT_OPEN: port->host_connected = cpkt->value; wake_up_interruptible(&port->waitqueue); -- cgit v1.2.3 From 0643e4c6e4fd67778fa886a89e6ec2320e0ff4d3 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 15 May 2010 11:45:53 +0200 Subject: drivers/char: Eliminate use after free In each case, the first argument to send_control_msg or __send_control_msg, respectively, has either not been successfully allocated or has been freed at the point of the call. In the first case, the first argument, port, is only used to access the portdev and id fields, in order to call __send_control_msg. Thus it seems possible instead to call __send_control_msg directly. In the second case, the call to __send_control_msg is moved up to a place where it seems like the first argument, portdev, has been initialized sufficiently to make the call to __send_control_msg meaningful. This has only been compile tested. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @free@ expression E; position p; @@ kfree@p(E) @@ expression free.E, subE<=free.E, E1; position free.p; @@ kfree@p(E) ... ( subE = E1 | * E ) // Signed-off-by: Julia Lawall Acked-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 458d907e3621..8c99bf1b5e9f 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1090,7 +1090,7 @@ free_port: kfree(port); fail: /* The host might want to notify management sw about port add failure */ - send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 0); + __send_control_msg(portdev, id, VIRTIO_CONSOLE_PORT_READY, 0); return err; } @@ -1559,6 +1559,9 @@ static int __devinit virtcons_probe(struct virtio_device *vdev) return 0; free_vqs: + /* The host might want to notify mgmt sw about device add failure */ + __send_control_msg(portdev, VIRTIO_CONSOLE_BAD_ID, + VIRTIO_CONSOLE_DEVICE_READY, 0); vdev->config->del_vqs(vdev); kfree(portdev->in_vqs); kfree(portdev->out_vqs); @@ -1567,9 +1570,6 @@ free_chrdev: free: kfree(portdev); fail: - /* The host might want to notify mgmt sw about device add failure */ - __send_control_msg(portdev, VIRTIO_CONSOLE_BAD_ID, - VIRTIO_CONSOLE_DEVICE_READY, 0); return err; } -- cgit v1.2.3 From 15651291a2f8c11e7e6a42d8bfde7a213ff13262 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Tue, 18 May 2010 14:35:11 +0800 Subject: ACPI, IO memory pre-mapping and atomic accessing Some ACPI IO accessing need to be done in atomic context. For example, APEI ERST operations may be used for permanent storage in hardware error handler. That is, it may be called in atomic contexts such as IRQ or NMI, etc. And, ERST/EINJ implement their operations via IO memory/port accessing. But the IO memory accessing method provided by ACPI (acpi_read/acpi_write) maps the IO memory during it is accessed, so it can not be used in atomic context. To solve the issue, the IO memory should be pre-mapped during EINJ/ERST initializing. A linked list is used to record which memory area has been mapped, when memory is accessed in hardware error handler, search the linked list for the mapped virtual address from the given physical address. Signed-off-by: Huang Ying Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/Makefile | 1 + drivers/acpi/atomicio.c | 360 ++++++++++++++++++++++++++++++++++++++++++++++++ include/acpi/atomicio.h | 10 ++ 3 files changed, 371 insertions(+) create mode 100644 drivers/acpi/atomicio.c create mode 100644 include/acpi/atomicio.h (limited to 'drivers') diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index a8d8998dd5c5..93251fb599fa 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -19,6 +19,7 @@ obj-y += acpi.o \ # All the builtin files are in the "acpi." module_param namespace. acpi-y += osl.o utils.o reboot.o +acpi-y += atomicio.o acpi-y += hest.o # sleep related files diff --git a/drivers/acpi/atomicio.c b/drivers/acpi/atomicio.c new file mode 100644 index 000000000000..814b19249616 --- /dev/null +++ b/drivers/acpi/atomicio.c @@ -0,0 +1,360 @@ +/* + * atomicio.c - ACPI IO memory pre-mapping/post-unmapping, then + * accessing in atomic context. + * + * This is used for NMI handler to access IO memory area, because + * ioremap/iounmap can not be used in NMI handler. The IO memory area + * is pre-mapped in process context and accessed in NMI handler. + * + * Copyright (C) 2009-2010, Intel Corp. + * Author: Huang Ying + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ACPI_PFX "ACPI: " + +static LIST_HEAD(acpi_iomaps); +/* + * Used for mutual exclusion between writers of acpi_iomaps list, for + * synchronization between readers and writer, RCU is used. + */ +static DEFINE_SPINLOCK(acpi_iomaps_lock); + +struct acpi_iomap { + struct list_head list; + void __iomem *vaddr; + unsigned long size; + phys_addr_t paddr; + struct kref ref; +}; + +/* acpi_iomaps_lock or RCU read lock must be held before calling */ +static struct acpi_iomap *__acpi_find_iomap(phys_addr_t paddr, + unsigned long size) +{ + struct acpi_iomap *map; + + list_for_each_entry_rcu(map, &acpi_iomaps, list) { + if (map->paddr + map->size >= paddr + size && + map->paddr <= paddr) + return map; + } + return NULL; +} + +/* + * Atomic "ioremap" used by NMI handler, if the specified IO memory + * area is not pre-mapped, NULL will be returned. + * + * acpi_iomaps_lock or RCU read lock must be held before calling + */ +static void __iomem *__acpi_ioremap_fast(phys_addr_t paddr, + unsigned long size) +{ + struct acpi_iomap *map; + + map = __acpi_find_iomap(paddr, size); + if (map) + return map->vaddr + (paddr - map->paddr); + else + return NULL; +} + +/* acpi_iomaps_lock must be held before calling */ +static void __iomem *__acpi_try_ioremap(phys_addr_t paddr, + unsigned long size) +{ + struct acpi_iomap *map; + + map = __acpi_find_iomap(paddr, size); + if (map) { + kref_get(&map->ref); + return map->vaddr + (paddr - map->paddr); + } else + return NULL; +} + +/* + * Used to pre-map the specified IO memory area. First try to find + * whether the area is already pre-mapped, if it is, increase the + * reference count (in __acpi_try_ioremap) and return; otherwise, do + * the real ioremap, and add the mapping into acpi_iomaps list. + */ +static void __iomem *acpi_pre_map(phys_addr_t paddr, + unsigned long size) +{ + void __iomem *vaddr; + struct acpi_iomap *map; + unsigned long pg_sz, flags; + phys_addr_t pg_off; + + spin_lock_irqsave(&acpi_iomaps_lock, flags); + vaddr = __acpi_try_ioremap(paddr, size); + spin_unlock_irqrestore(&acpi_iomaps_lock, flags); + if (vaddr) + return vaddr; + + pg_off = paddr & PAGE_MASK; + pg_sz = ((paddr + size + PAGE_SIZE - 1) & PAGE_MASK) - pg_off; + vaddr = ioremap(pg_off, pg_sz); + if (!vaddr) + return NULL; + map = kmalloc(sizeof(*map), GFP_KERNEL); + if (!map) + goto err_unmap; + INIT_LIST_HEAD(&map->list); + map->paddr = pg_off; + map->size = pg_sz; + map->vaddr = vaddr; + kref_init(&map->ref); + + spin_lock_irqsave(&acpi_iomaps_lock, flags); + vaddr = __acpi_try_ioremap(paddr, size); + if (vaddr) { + spin_unlock_irqrestore(&acpi_iomaps_lock, flags); + iounmap(map->vaddr); + kfree(map); + return vaddr; + } + list_add_tail_rcu(&map->list, &acpi_iomaps); + spin_unlock_irqrestore(&acpi_iomaps_lock, flags); + + return vaddr + (paddr - pg_off); +err_unmap: + iounmap(vaddr); + return NULL; +} + +/* acpi_iomaps_lock must be held before calling */ +static void __acpi_kref_del_iomap(struct kref *ref) +{ + struct acpi_iomap *map; + + map = container_of(ref, struct acpi_iomap, ref); + list_del_rcu(&map->list); +} + +/* + * Used to post-unmap the specified IO memory area. The iounmap is + * done only if the reference count goes zero. + */ +static void acpi_post_unmap(phys_addr_t paddr, unsigned long size) +{ + struct acpi_iomap *map; + unsigned long flags; + int del; + + spin_lock_irqsave(&acpi_iomaps_lock, flags); + map = __acpi_find_iomap(paddr, size); + BUG_ON(!map); + del = kref_put(&map->ref, __acpi_kref_del_iomap); + spin_unlock_irqrestore(&acpi_iomaps_lock, flags); + + if (!del) + return; + + synchronize_rcu(); + iounmap(map->vaddr); + kfree(map); +} + +/* In NMI handler, should set silent = 1 */ +static int acpi_check_gar(struct acpi_generic_address *reg, + u64 *paddr, int silent) +{ + u32 width, space_id; + + width = reg->bit_width; + space_id = reg->space_id; + /* Handle possible alignment issues */ + memcpy(paddr, ®->address, sizeof(*paddr)); + if (!*paddr) { + if (!silent) + pr_warning(FW_BUG ACPI_PFX + "Invalid physical address in GAR [0x%llx/%u/%u]\n", + *paddr, width, space_id); + return -EINVAL; + } + + if ((width != 8) && (width != 16) && (width != 32) && (width != 64)) { + if (!silent) + pr_warning(FW_BUG ACPI_PFX + "Invalid bit width in GAR [0x%llx/%u/%u]\n", + *paddr, width, space_id); + return -EINVAL; + } + + if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY && + space_id != ACPI_ADR_SPACE_SYSTEM_IO) { + if (!silent) + pr_warning(FW_BUG ACPI_PFX + "Invalid address space type in GAR [0x%llx/%u/%u]\n", + *paddr, width, space_id); + return -EINVAL; + } + + return 0; +} + +/* Pre-map, working on GAR */ +int acpi_pre_map_gar(struct acpi_generic_address *reg) +{ + u64 paddr; + void __iomem *vaddr; + int rc; + + if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) + return 0; + + rc = acpi_check_gar(reg, &paddr, 0); + if (rc) + return rc; + + vaddr = acpi_pre_map(paddr, reg->bit_width / 8); + if (!vaddr) + return -EIO; + + return 0; +} +EXPORT_SYMBOL_GPL(acpi_pre_map_gar); + +/* Post-unmap, working on GAR */ +int acpi_post_unmap_gar(struct acpi_generic_address *reg) +{ + u64 paddr; + int rc; + + if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) + return 0; + + rc = acpi_check_gar(reg, &paddr, 0); + if (rc) + return rc; + + acpi_post_unmap(paddr, reg->bit_width / 8); + + return 0; +} +EXPORT_SYMBOL_GPL(acpi_post_unmap_gar); + +/* + * Can be used in atomic (including NMI) or process context. RCU read + * lock can only be released after the IO memory area accessing. + */ +static int acpi_atomic_read_mem(u64 paddr, u64 *val, u32 width) +{ + void __iomem *addr; + + rcu_read_lock(); + addr = __acpi_ioremap_fast(paddr, width); + switch (width) { + case 8: + *val = readb(addr); + break; + case 16: + *val = readw(addr); + break; + case 32: + *val = readl(addr); + break; + case 64: + *val = readq(addr); + break; + default: + return -EINVAL; + } + rcu_read_unlock(); + + return 0; +} + +static int acpi_atomic_write_mem(u64 paddr, u64 val, u32 width) +{ + void __iomem *addr; + + rcu_read_lock(); + addr = __acpi_ioremap_fast(paddr, width); + switch (width) { + case 8: + writeb(val, addr); + break; + case 16: + writew(val, addr); + break; + case 32: + writel(val, addr); + break; + case 64: + writeq(val, addr); + break; + default: + return -EINVAL; + } + rcu_read_unlock(); + + return 0; +} + +/* GAR accessing in atomic (including NMI) or process context */ +int acpi_atomic_read(u64 *val, struct acpi_generic_address *reg) +{ + u64 paddr; + int rc; + + rc = acpi_check_gar(reg, &paddr, 1); + if (rc) + return rc; + + *val = 0; + switch (reg->space_id) { + case ACPI_ADR_SPACE_SYSTEM_MEMORY: + return acpi_atomic_read_mem(paddr, val, reg->bit_width); + case ACPI_ADR_SPACE_SYSTEM_IO: + return acpi_os_read_port(paddr, (u32 *)val, reg->bit_width); + default: + return -EINVAL; + } +} +EXPORT_SYMBOL_GPL(acpi_atomic_read); + +int acpi_atomic_write(u64 val, struct acpi_generic_address *reg) +{ + u64 paddr; + int rc; + + rc = acpi_check_gar(reg, &paddr, 1); + if (rc) + return rc; + + switch (reg->space_id) { + case ACPI_ADR_SPACE_SYSTEM_MEMORY: + return acpi_atomic_write_mem(paddr, val, reg->bit_width); + case ACPI_ADR_SPACE_SYSTEM_IO: + return acpi_os_write_port(paddr, val, reg->bit_width); + default: + return -EINVAL; + } +} +EXPORT_SYMBOL_GPL(acpi_atomic_write); diff --git a/include/acpi/atomicio.h b/include/acpi/atomicio.h new file mode 100644 index 000000000000..8b9fb4b0b9ce --- /dev/null +++ b/include/acpi/atomicio.h @@ -0,0 +1,10 @@ +#ifndef ACPI_ATOMIC_IO_H +#define ACPI_ATOMIC_IO_H + +int acpi_pre_map_gar(struct acpi_generic_address *reg); +int acpi_post_unmap_gar(struct acpi_generic_address *reg); + +int acpi_atomic_read(u64 *val, struct acpi_generic_address *reg); +int acpi_atomic_write(u64 val, struct acpi_generic_address *reg); + +#endif -- cgit v1.2.3 From a643ce207f3e70030bdb431e2a363cc111a60c1a Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Tue, 18 May 2010 14:35:12 +0800 Subject: ACPI, APEI, APEI supporting infrastructure APEI stands for ACPI Platform Error Interface, which allows to report errors (for example from the chipset) to the operating system. This improves NMI handling especially. In addition it supports error serialization and error injection. For more information about APEI, please refer to ACPI Specification version 4.0, chapter 17. This patch provides some common functions used by more than one APEI tables, mainly framework of interpreter for EINJ and ERST. A machine readable language is defined for EINJ and ERST for OS to execute, and so to drive the firmware to fulfill the corresponding functions. The machine language for EINJ and ERST is compatible, so a common framework is defined for them. Signed-off-by: Huang Ying Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/Kconfig | 2 + drivers/acpi/Makefile | 2 + drivers/acpi/apei/Kconfig | 8 + drivers/acpi/apei/Makefile | 3 + drivers/acpi/apei/apei-base.c | 593 ++++++++++++++++++++++++++++++++++++++ drivers/acpi/apei/apei-internal.h | 95 ++++++ 6 files changed, 703 insertions(+) create mode 100644 drivers/acpi/apei/Kconfig create mode 100644 drivers/acpi/apei/Makefile create mode 100644 drivers/acpi/apei/apei-base.c create mode 100644 drivers/acpi/apei/apei-internal.h (limited to 'drivers') diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 93d2c7971df6..191cf2bf408c 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -360,4 +360,6 @@ config ACPI_SBS To compile this driver as a module, choose M here: the modules will be called sbs and sbshc. +source "drivers/acpi/apei/Kconfig" + endif # ACPI diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 93251fb599fa..d90af7fe8b98 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -67,3 +67,5 @@ processor-y += processor_idle.o processor_thermal.o processor-$(CONFIG_CPU_FREQ) += processor_perflib.o obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o + +obj-$(CONFIG_ACPI_APEI) += apei/ diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig new file mode 100644 index 000000000000..d61c851533c9 --- /dev/null +++ b/drivers/acpi/apei/Kconfig @@ -0,0 +1,8 @@ +config ACPI_APEI + bool "ACPI Platform Error Interface (APEI)" + depends on X86 + help + APEI allows to report errors (for example from the chipset) + to the operating system. This improves NMI handling + especially. In addition it supports error serialization and + error injection. diff --git a/drivers/acpi/apei/Makefile b/drivers/acpi/apei/Makefile new file mode 100644 index 000000000000..6f41dfca4566 --- /dev/null +++ b/drivers/acpi/apei/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_ACPI_APEI) += apei.o + +apei-y := apei-base.o diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c new file mode 100644 index 000000000000..db3946e9c66b --- /dev/null +++ b/drivers/acpi/apei/apei-base.c @@ -0,0 +1,593 @@ +/* + * apei-base.c - ACPI Platform Error Interface (APEI) supporting + * infrastructure + * + * APEI allows to report errors (for example from the chipset) to the + * the operating system. This improves NMI handling especially. In + * addition it supports error serialization and error injection. + * + * For more information about APEI, please refer to ACPI Specification + * version 4.0, chapter 17. + * + * This file has Common functions used by more than one APEI table, + * including framework of interpreter for ERST and EINJ; resource + * management for APEI registers. + * + * Copyright (C) 2009, Intel Corp. + * Author: Huang Ying + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "apei-internal.h" + +#define APEI_PFX "APEI: " + +/* + * APEI ERST (Error Record Serialization Table) and EINJ (Error + * INJection) interpreter framework. + */ + +#define APEI_EXEC_PRESERVE_REGISTER 0x1 + +void apei_exec_ctx_init(struct apei_exec_context *ctx, + struct apei_exec_ins_type *ins_table, + u32 instructions, + struct acpi_whea_header *action_table, + u32 entries) +{ + ctx->ins_table = ins_table; + ctx->instructions = instructions; + ctx->action_table = action_table; + ctx->entries = entries; +} +EXPORT_SYMBOL_GPL(apei_exec_ctx_init); + +int __apei_exec_read_register(struct acpi_whea_header *entry, u64 *val) +{ + int rc; + + rc = acpi_atomic_read(val, &entry->register_region); + if (rc) + return rc; + *val >>= entry->register_region.bit_offset; + *val &= entry->mask; + + return 0; +} + +int apei_exec_read_register(struct apei_exec_context *ctx, + struct acpi_whea_header *entry) +{ + int rc; + u64 val = 0; + + rc = __apei_exec_read_register(entry, &val); + if (rc) + return rc; + ctx->value = val; + + return 0; +} +EXPORT_SYMBOL_GPL(apei_exec_read_register); + +int apei_exec_read_register_value(struct apei_exec_context *ctx, + struct acpi_whea_header *entry) +{ + int rc; + + rc = apei_exec_read_register(ctx, entry); + if (rc) + return rc; + ctx->value = (ctx->value == entry->value); + + return 0; +} +EXPORT_SYMBOL_GPL(apei_exec_read_register_value); + +int __apei_exec_write_register(struct acpi_whea_header *entry, u64 val) +{ + int rc; + + val &= entry->mask; + val <<= entry->register_region.bit_offset; + if (entry->flags & APEI_EXEC_PRESERVE_REGISTER) { + u64 valr = 0; + rc = acpi_atomic_read(&valr, &entry->register_region); + if (rc) + return rc; + valr &= ~(entry->mask << entry->register_region.bit_offset); + val |= valr; + } + rc = acpi_atomic_write(val, &entry->register_region); + + return rc; +} + +int apei_exec_write_register(struct apei_exec_context *ctx, + struct acpi_whea_header *entry) +{ + return __apei_exec_write_register(entry, ctx->value); +} +EXPORT_SYMBOL_GPL(apei_exec_write_register); + +int apei_exec_write_register_value(struct apei_exec_context *ctx, + struct acpi_whea_header *entry) +{ + int rc; + + ctx->value = entry->value; + rc = apei_exec_write_register(ctx, entry); + + return rc; +} +EXPORT_SYMBOL_GPL(apei_exec_write_register_value); + +int apei_exec_noop(struct apei_exec_context *ctx, + struct acpi_whea_header *entry) +{ + return 0; +} +EXPORT_SYMBOL_GPL(apei_exec_noop); + +/* + * Interpret the specified action. Go through whole action table, + * execute all instructions belong to the action. + */ +int apei_exec_run(struct apei_exec_context *ctx, u8 action) +{ + int rc; + u32 i, ip; + struct acpi_whea_header *entry; + apei_exec_ins_func_t run; + + ctx->ip = 0; + + /* + * "ip" is the instruction pointer of current instruction, + * "ctx->ip" specifies the next instruction to executed, + * instruction "run" function may change the "ctx->ip" to + * implement "goto" semantics. + */ +rewind: + ip = 0; + for (i = 0; i < ctx->entries; i++) { + entry = &ctx->action_table[i]; + if (entry->action != action) + continue; + if (ip == ctx->ip) { + if (entry->instruction >= ctx->instructions || + !ctx->ins_table[entry->instruction].run) { + pr_warning(FW_WARN APEI_PFX + "Invalid action table, unknown instruction type: %d\n", + entry->instruction); + return -EINVAL; + } + run = ctx->ins_table[entry->instruction].run; + rc = run(ctx, entry); + if (rc < 0) + return rc; + else if (rc != APEI_EXEC_SET_IP) + ctx->ip++; + } + ip++; + if (ctx->ip < ip) + goto rewind; + } + + return 0; +} +EXPORT_SYMBOL_GPL(apei_exec_run); + +typedef int (*apei_exec_entry_func_t)(struct apei_exec_context *ctx, + struct acpi_whea_header *entry, + void *data); + +static int apei_exec_for_each_entry(struct apei_exec_context *ctx, + apei_exec_entry_func_t func, + void *data, + int *end) +{ + u8 ins; + int i, rc; + struct acpi_whea_header *entry; + struct apei_exec_ins_type *ins_table = ctx->ins_table; + + for (i = 0; i < ctx->entries; i++) { + entry = ctx->action_table + i; + ins = entry->instruction; + if (end) + *end = i; + if (ins >= ctx->instructions || !ins_table[ins].run) { + pr_warning(FW_WARN APEI_PFX + "Invalid action table, unknown instruction type: %d\n", + ins); + return -EINVAL; + } + rc = func(ctx, entry, data); + if (rc) + return rc; + } + + return 0; +} + +static int pre_map_gar_callback(struct apei_exec_context *ctx, + struct acpi_whea_header *entry, + void *data) +{ + u8 ins = entry->instruction; + + if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER) + return acpi_pre_map_gar(&entry->register_region); + + return 0; +} + +/* + * Pre-map all GARs in action table to make it possible to access them + * in NMI handler. + */ +int apei_exec_pre_map_gars(struct apei_exec_context *ctx) +{ + int rc, end; + + rc = apei_exec_for_each_entry(ctx, pre_map_gar_callback, + NULL, &end); + if (rc) { + struct apei_exec_context ctx_unmap; + memcpy(&ctx_unmap, ctx, sizeof(*ctx)); + ctx_unmap.entries = end; + apei_exec_post_unmap_gars(&ctx_unmap); + } + + return rc; +} +EXPORT_SYMBOL_GPL(apei_exec_pre_map_gars); + +static int post_unmap_gar_callback(struct apei_exec_context *ctx, + struct acpi_whea_header *entry, + void *data) +{ + u8 ins = entry->instruction; + + if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER) + acpi_post_unmap_gar(&entry->register_region); + + return 0; +} + +/* Post-unmap all GAR in action table. */ +int apei_exec_post_unmap_gars(struct apei_exec_context *ctx) +{ + return apei_exec_for_each_entry(ctx, post_unmap_gar_callback, + NULL, NULL); +} +EXPORT_SYMBOL_GPL(apei_exec_post_unmap_gars); + +/* + * Resource management for GARs in APEI + */ +struct apei_res { + struct list_head list; + unsigned long start; + unsigned long end; +}; + +/* Collect all resources requested, to avoid conflict */ +struct apei_resources apei_resources_all = { + .iomem = LIST_HEAD_INIT(apei_resources_all.iomem), + .ioport = LIST_HEAD_INIT(apei_resources_all.ioport), +}; + +static int apei_res_add(struct list_head *res_list, + unsigned long start, unsigned long size) +{ + struct apei_res *res, *resn, *res_ins = NULL; + unsigned long end = start + size; + + if (end <= start) + return 0; +repeat: + list_for_each_entry_safe(res, resn, res_list, list) { + if (res->start > end || res->end < start) + continue; + else if (end <= res->end && start >= res->start) { + kfree(res_ins); + return 0; + } + list_del(&res->list); + res->start = start = min(res->start, start); + res->end = end = max(res->end, end); + kfree(res_ins); + res_ins = res; + goto repeat; + } + + if (res_ins) + list_add(&res_ins->list, res_list); + else { + res_ins = kmalloc(sizeof(*res), GFP_KERNEL); + if (!res_ins) + return -ENOMEM; + res_ins->start = start; + res_ins->end = end; + list_add(&res_ins->list, res_list); + } + + return 0; +} + +static int apei_res_sub(struct list_head *res_list1, + struct list_head *res_list2) +{ + struct apei_res *res1, *resn1, *res2, *res; + res1 = list_entry(res_list1->next, struct apei_res, list); + resn1 = list_entry(res1->list.next, struct apei_res, list); + while (&res1->list != res_list1) { + list_for_each_entry(res2, res_list2, list) { + if (res1->start >= res2->end || + res1->end <= res2->start) + continue; + else if (res1->end <= res2->end && + res1->start >= res2->start) { + list_del(&res1->list); + kfree(res1); + break; + } else if (res1->end > res2->end && + res1->start < res2->start) { + res = kmalloc(sizeof(*res), GFP_KERNEL); + if (!res) + return -ENOMEM; + res->start = res2->end; + res->end = res1->end; + res1->end = res2->start; + list_add(&res->list, &res1->list); + resn1 = res; + } else { + if (res1->start < res2->start) + res1->end = res2->start; + else + res1->start = res2->end; + } + } + res1 = resn1; + resn1 = list_entry(resn1->list.next, struct apei_res, list); + } + + return 0; +} + +static void apei_res_clean(struct list_head *res_list) +{ + struct apei_res *res, *resn; + + list_for_each_entry_safe(res, resn, res_list, list) { + list_del(&res->list); + kfree(res); + } +} + +void apei_resources_fini(struct apei_resources *resources) +{ + apei_res_clean(&resources->iomem); + apei_res_clean(&resources->ioport); +} +EXPORT_SYMBOL_GPL(apei_resources_fini); + +static int apei_resources_merge(struct apei_resources *resources1, + struct apei_resources *resources2) +{ + int rc; + struct apei_res *res; + + list_for_each_entry(res, &resources2->iomem, list) { + rc = apei_res_add(&resources1->iomem, res->start, + res->end - res->start); + if (rc) + return rc; + } + list_for_each_entry(res, &resources2->ioport, list) { + rc = apei_res_add(&resources1->ioport, res->start, + res->end - res->start); + if (rc) + return rc; + } + + return 0; +} + +/* + * EINJ has two groups of GARs (EINJ table entry and trigger table + * entry), so common resources are subtracted from the trigger table + * resources before the second requesting. + */ +int apei_resources_sub(struct apei_resources *resources1, + struct apei_resources *resources2) +{ + int rc; + + rc = apei_res_sub(&resources1->iomem, &resources2->iomem); + if (rc) + return rc; + return apei_res_sub(&resources1->ioport, &resources2->ioport); +} +EXPORT_SYMBOL_GPL(apei_resources_sub); + +/* + * IO memory/port rersource management mechanism is used to check + * whether memory/port area used by GARs conflicts with normal memory + * or IO memory/port of devices. + */ +int apei_resources_request(struct apei_resources *resources, + const char *desc) +{ + struct apei_res *res, *res_bak; + struct resource *r; + + apei_resources_sub(resources, &apei_resources_all); + + list_for_each_entry(res, &resources->iomem, list) { + r = request_mem_region(res->start, res->end - res->start, + desc); + if (!r) { + pr_err(APEI_PFX + "Can not request iomem region <%016llx-%016llx> for GARs.\n", + (unsigned long long)res->start, + (unsigned long long)res->end); + res_bak = res; + goto err_unmap_iomem; + } + } + + list_for_each_entry(res, &resources->ioport, list) { + r = request_region(res->start, res->end - res->start, desc); + if (!r) { + pr_err(APEI_PFX + "Can not request ioport region <%016llx-%016llx> for GARs.\n", + (unsigned long long)res->start, + (unsigned long long)res->end); + res_bak = res; + goto err_unmap_ioport; + } + } + + apei_resources_merge(&apei_resources_all, resources); + + return 0; +err_unmap_ioport: + list_for_each_entry(res, &resources->ioport, list) { + if (res == res_bak) + break; + release_mem_region(res->start, res->end - res->start); + } + res_bak = NULL; +err_unmap_iomem: + list_for_each_entry(res, &resources->iomem, list) { + if (res == res_bak) + break; + release_region(res->start, res->end - res->start); + } + return -EINVAL; +} +EXPORT_SYMBOL_GPL(apei_resources_request); + +void apei_resources_release(struct apei_resources *resources) +{ + struct apei_res *res; + + list_for_each_entry(res, &resources->iomem, list) + release_mem_region(res->start, res->end - res->start); + list_for_each_entry(res, &resources->ioport, list) + release_region(res->start, res->end - res->start); + + apei_resources_sub(&apei_resources_all, resources); +} +EXPORT_SYMBOL_GPL(apei_resources_release); + +static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr) +{ + u32 width, space_id; + + width = reg->bit_width; + space_id = reg->space_id; + /* Handle possible alignment issues */ + memcpy(paddr, ®->address, sizeof(*paddr)); + if (!*paddr) { + pr_warning(FW_BUG APEI_PFX + "Invalid physical address in GAR [0x%llx/%u/%u]\n", + *paddr, width, space_id); + return -EINVAL; + } + + if ((width != 8) && (width != 16) && (width != 32) && (width != 64)) { + pr_warning(FW_BUG APEI_PFX + "Invalid bit width in GAR [0x%llx/%u/%u]\n", + *paddr, width, space_id); + return -EINVAL; + } + + if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY && + space_id != ACPI_ADR_SPACE_SYSTEM_IO) { + pr_warning(FW_BUG APEI_PFX + "Invalid address space type in GAR [0x%llx/%u/%u]\n", + *paddr, width, space_id); + return -EINVAL; + } + + return 0; +} + +static int collect_res_callback(struct apei_exec_context *ctx, + struct acpi_whea_header *entry, + void *data) +{ + struct apei_resources *resources = data; + struct acpi_generic_address *reg = &entry->register_region; + u8 ins = entry->instruction; + u64 paddr; + int rc; + + if (!(ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER)) + return 0; + + rc = apei_check_gar(reg, &paddr); + if (rc) + return rc; + + switch (reg->space_id) { + case ACPI_ADR_SPACE_SYSTEM_MEMORY: + return apei_res_add(&resources->iomem, paddr, + reg->bit_width / 8); + case ACPI_ADR_SPACE_SYSTEM_IO: + return apei_res_add(&resources->ioport, paddr, + reg->bit_width / 8); + default: + return -EINVAL; + } +} + +/* + * Same register may be used by multiple instructions in GARs, so + * resources are collected before requesting. + */ +int apei_exec_collect_resources(struct apei_exec_context *ctx, + struct apei_resources *resources) +{ + return apei_exec_for_each_entry(ctx, collect_res_callback, + resources, NULL); +} +EXPORT_SYMBOL_GPL(apei_exec_collect_resources); + +struct dentry *apei_get_debugfs_dir(void) +{ + static struct dentry *dapei; + + if (!dapei) + dapei = debugfs_create_dir("apei", NULL); + + return dapei; +} +EXPORT_SYMBOL_GPL(apei_get_debugfs_dir); diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h new file mode 100644 index 000000000000..86e041a42c44 --- /dev/null +++ b/drivers/acpi/apei/apei-internal.h @@ -0,0 +1,95 @@ +/* + * apei-internal.h - ACPI Platform Error Interface internal + * definations. + */ + +#ifndef APEI_INTERNAL_H +#define APEI_INTERNAL_H + +struct apei_exec_context; + +typedef int (*apei_exec_ins_func_t)(struct apei_exec_context *ctx, + struct acpi_whea_header *entry); + +#define APEI_EXEC_INS_ACCESS_REGISTER 0x0001 + +struct apei_exec_ins_type { + u32 flags; + apei_exec_ins_func_t run; +}; + +struct apei_exec_context { + u32 ip; + u64 value; + u64 var1; + u64 var2; + u64 src_base; + u64 dst_base; + struct apei_exec_ins_type *ins_table; + u32 instructions; + struct acpi_whea_header *action_table; + u32 entries; +}; + +void apei_exec_ctx_init(struct apei_exec_context *ctx, + struct apei_exec_ins_type *ins_table, + u32 instructions, + struct acpi_whea_header *action_table, + u32 entries); + +static inline void apei_exec_ctx_set_input(struct apei_exec_context *ctx, + u64 input) +{ + ctx->value = input; +} + +static inline u64 apei_exec_ctx_get_output(struct apei_exec_context *ctx) +{ + return ctx->value; +} + +int apei_exec_run(struct apei_exec_context *ctx, u8 action); + +/* Common instruction implementation */ + +/* IP has been set in instruction function */ +#define APEI_EXEC_SET_IP 1 + +int __apei_exec_read_register(struct acpi_whea_header *entry, u64 *val); +int __apei_exec_write_register(struct acpi_whea_header *entry, u64 val); +int apei_exec_read_register(struct apei_exec_context *ctx, + struct acpi_whea_header *entry); +int apei_exec_read_register_value(struct apei_exec_context *ctx, + struct acpi_whea_header *entry); +int apei_exec_write_register(struct apei_exec_context *ctx, + struct acpi_whea_header *entry); +int apei_exec_write_register_value(struct apei_exec_context *ctx, + struct acpi_whea_header *entry); +int apei_exec_noop(struct apei_exec_context *ctx, + struct acpi_whea_header *entry); +int apei_exec_pre_map_gars(struct apei_exec_context *ctx); +int apei_exec_post_unmap_gars(struct apei_exec_context *ctx); + +struct apei_resources { + struct list_head iomem; + struct list_head ioport; +}; + +static inline void apei_resources_init(struct apei_resources *resources) +{ + INIT_LIST_HEAD(&resources->iomem); + INIT_LIST_HEAD(&resources->ioport); +} + +void apei_resources_fini(struct apei_resources *resources); +int apei_resources_sub(struct apei_resources *resources1, + struct apei_resources *resources2); +int apei_resources_request(struct apei_resources *resources, + const char *desc); +void apei_resources_release(struct apei_resources *resources); +int apei_exec_collect_resources(struct apei_exec_context *ctx, + struct apei_resources *resources); + +struct dentry; +struct dentry *apei_get_debugfs_dir(void); +#endif -- cgit v1.2.3 From 9dc966641677795f4d6b0a9ba630d6a3a3e24a57 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Tue, 18 May 2010 14:35:13 +0800 Subject: ACPI, APEI, HEST table parsing HEST describes error sources in detail; communicating operational parameters (i.e. severity levels, masking bits, and threshold values) to OS as necessary. It also allows the platform to report error sources for which OS would typically not implement support (for example, chipset-specific error registers). HEST information may be needed by other subsystems. For example, HEST PCIE AER error source information describes whether a PCIE root port works in "firmware first" mode, this is needed by general PCIE AER error subsystem. So a public HEST tabling parsing interface is provided. Signed-off-by: Huang Ying Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/apei/Makefile | 2 +- drivers/acpi/apei/hest.c | 173 +++++++++++++++++++++++++++++++++++++++++++++ include/acpi/apei.h | 13 ++++ 3 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 drivers/acpi/apei/hest.c create mode 100644 include/acpi/apei.h (limited to 'drivers') diff --git a/drivers/acpi/apei/Makefile b/drivers/acpi/apei/Makefile index 6f41dfca4566..a8832929835f 100644 --- a/drivers/acpi/apei/Makefile +++ b/drivers/acpi/apei/Makefile @@ -1,3 +1,3 @@ obj-$(CONFIG_ACPI_APEI) += apei.o -apei-y := apei-base.o +apei-y := apei-base.o hest.o diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c new file mode 100644 index 000000000000..e7f40d362cb3 --- /dev/null +++ b/drivers/acpi/apei/hest.c @@ -0,0 +1,173 @@ +/* + * APEI Hardware Error Souce Table support + * + * HEST describes error sources in detail; communicates operational + * parameters (i.e. severity levels, masking bits, and threshold + * values) to Linux as necessary. It also allows the BIOS to report + * non-standard error sources to Linux (for example, chipset-specific + * error registers). + * + * For more information about HEST, please refer to ACPI Specification + * version 4.0, section 17.3.2. + * + * Copyright 2009 Intel Corp. + * Author: Huang Ying + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "apei-internal.h" + +#define HEST_PFX "HEST: " + +int hest_disable; +EXPORT_SYMBOL_GPL(hest_disable); + +/* HEST table parsing */ + +static struct acpi_table_hest *hest_tab; + +static int hest_void_parse(struct acpi_hest_header *hest_hdr, void *data) +{ + return 0; +} + +static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { + [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */ + [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1, + [ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi), + [ACPI_HEST_TYPE_AER_ROOT_PORT] = sizeof(struct acpi_hest_aer_root), + [ACPI_HEST_TYPE_AER_ENDPOINT] = sizeof(struct acpi_hest_aer), + [ACPI_HEST_TYPE_AER_BRIDGE] = sizeof(struct acpi_hest_aer_bridge), + [ACPI_HEST_TYPE_GENERIC_ERROR] = sizeof(struct acpi_hest_generic), +}; + +static int hest_esrc_len(struct acpi_hest_header *hest_hdr) +{ + u16 hest_type = hest_hdr->type; + int len; + + if (hest_type >= ACPI_HEST_TYPE_RESERVED) + return 0; + + len = hest_esrc_len_tab[hest_type]; + + if (hest_type == ACPI_HEST_TYPE_IA32_CORRECTED_CHECK) { + struct acpi_hest_ia_corrected *cmc; + cmc = (struct acpi_hest_ia_corrected *)hest_hdr; + len = sizeof(*cmc) + cmc->num_hardware_banks * + sizeof(struct acpi_hest_ia_error_bank); + } else if (hest_type == ACPI_HEST_TYPE_IA32_CHECK) { + struct acpi_hest_ia_machine_check *mc; + mc = (struct acpi_hest_ia_machine_check *)hest_hdr; + len = sizeof(*mc) + mc->num_hardware_banks * + sizeof(struct acpi_hest_ia_error_bank); + } + BUG_ON(len == -1); + + return len; +}; + +int apei_hest_parse(apei_hest_func_t func, void *data) +{ + struct acpi_hest_header *hest_hdr; + int i, rc, len; + + if (hest_disable) + return -EINVAL; + + hest_hdr = (struct acpi_hest_header *)(hest_tab + 1); + for (i = 0; i < hest_tab->error_source_count; i++) { + len = hest_esrc_len(hest_hdr); + if (!len) { + pr_warning(FW_WARN HEST_PFX + "Unknown or unused hardware error source " + "type: %d for hardware error source: %d.\n", + hest_hdr->type, hest_hdr->source_id); + return -EINVAL; + } + if ((void *)hest_hdr + len > + (void *)hest_tab + hest_tab->header.length) { + pr_warning(FW_BUG HEST_PFX + "Table contents overflow for hardware error source: %d.\n", + hest_hdr->source_id); + return -EINVAL; + } + + rc = func(hest_hdr, data); + if (rc) + return rc; + + hest_hdr = (void *)hest_hdr + len; + } + + return 0; +} +EXPORT_SYMBOL_GPL(apei_hest_parse); + +static int __init setup_hest_disable(char *str) +{ + hest_disable = 1; + return 0; +} + +__setup("hest_disable", setup_hest_disable); + +static int __init hest_init(void) +{ + acpi_status status; + int rc = -ENODEV; + + if (acpi_disabled) + goto err; + + if (hest_disable) { + pr_info(HEST_PFX "HEST tabling parsing is disabled.\n"); + goto err; + } + + status = acpi_get_table(ACPI_SIG_HEST, 0, + (struct acpi_table_header **)&hest_tab); + if (status == AE_NOT_FOUND) { + pr_info(HEST_PFX "Table is not found!\n"); + goto err; + } else if (ACPI_FAILURE(status)) { + const char *msg = acpi_format_exception(status); + pr_err(HEST_PFX "Failed to get table, %s\n", msg); + rc = -EINVAL; + goto err; + } + + rc = apei_hest_parse(hest_void_parse, NULL); + if (rc) + goto err; + + pr_info(HEST_PFX "HEST table parsing is initialized.\n"); + + return 0; +err: + hest_disable = 1; + return rc; +} + +subsys_initcall(hest_init); diff --git a/include/acpi/apei.h b/include/acpi/apei.h new file mode 100644 index 000000000000..631a1ad2d108 --- /dev/null +++ b/include/acpi/apei.h @@ -0,0 +1,13 @@ +/* + * apei.h - ACPI Platform Error Interface + */ + +#ifndef ACPI_APEI_H +#define ACPI_APEI_H + +extern int hest_disable; + +typedef int (*apei_hest_func_t)(struct acpi_hest_header *hest_hdr, void *data); +int apei_hest_parse(apei_hest_func_t func, void *data); + +#endif -- cgit v1.2.3 From e40213450b53157967a1f83eda50e9a941c13a08 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Tue, 18 May 2010 14:35:14 +0800 Subject: ACPI, APEI, EINJ support EINJ provides a hardware error injection mechanism, this is useful for debugging and testing of other APEI and RAS features. Signed-off-by: Huang Ying Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/apei/Kconfig | 8 + drivers/acpi/apei/Makefile | 1 + drivers/acpi/apei/einj.c | 486 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 495 insertions(+) create mode 100644 drivers/acpi/apei/einj.c (limited to 'drivers') diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index d61c851533c9..5f0a41c2bc62 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig @@ -6,3 +6,11 @@ config ACPI_APEI to the operating system. This improves NMI handling especially. In addition it supports error serialization and error injection. + +config ACPI_APEI_EINJ + tristate "APEI Error INJection (EINJ)" + depends on ACPI_APEI && DEBUG_FS + help + EINJ provides a hardware error injection mechanism, it is + mainly used for debugging and testing the other parts of + APEI and some other RAS features. diff --git a/drivers/acpi/apei/Makefile b/drivers/acpi/apei/Makefile index a8832929835f..fea86a9c3c2b 100644 --- a/drivers/acpi/apei/Makefile +++ b/drivers/acpi/apei/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_ACPI_APEI) += apei.o +obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o apei-y := apei-base.o hest.o diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c new file mode 100644 index 000000000000..4ccebd8f930a --- /dev/null +++ b/drivers/acpi/apei/einj.c @@ -0,0 +1,486 @@ +/* + * APEI Error INJection support + * + * EINJ provides a hardware error injection mechanism, this is useful + * for debugging and testing of other APEI and RAS features. + * + * For more information about EINJ, please refer to ACPI Specification + * version 4.0, section 17.5. + * + * Copyright 2009 Intel Corp. + * Author: Huang Ying + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "apei-internal.h" + +#define EINJ_PFX "EINJ: " + +#define SPIN_UNIT 100 /* 100ns */ +/* Firmware should respond within 1 miliseconds */ +#define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC) + +#define EINJ_OP_BUSY 0x1 +#define EINJ_STATUS_SUCCESS 0x0 +#define EINJ_STATUS_FAIL 0x1 +#define EINJ_STATUS_INVAL 0x2 + +#define EINJ_TAB_ENTRY(tab) \ + ((struct acpi_whea_header *)((char *)(tab) + \ + sizeof(struct acpi_table_einj))) + +static struct acpi_table_einj *einj_tab; + +static struct apei_resources einj_resources; + +static struct apei_exec_ins_type einj_ins_type[] = { + [ACPI_EINJ_READ_REGISTER] = { + .flags = APEI_EXEC_INS_ACCESS_REGISTER, + .run = apei_exec_read_register, + }, + [ACPI_EINJ_READ_REGISTER_VALUE] = { + .flags = APEI_EXEC_INS_ACCESS_REGISTER, + .run = apei_exec_read_register_value, + }, + [ACPI_EINJ_WRITE_REGISTER] = { + .flags = APEI_EXEC_INS_ACCESS_REGISTER, + .run = apei_exec_write_register, + }, + [ACPI_EINJ_WRITE_REGISTER_VALUE] = { + .flags = APEI_EXEC_INS_ACCESS_REGISTER, + .run = apei_exec_write_register_value, + }, + [ACPI_EINJ_NOOP] = { + .flags = 0, + .run = apei_exec_noop, + }, +}; + +/* + * Prevent EINJ interpreter to run simultaneously, because the + * corresponding firmware implementation may not work properly when + * invoked simultaneously. + */ +static DEFINE_MUTEX(einj_mutex); + +static void einj_exec_ctx_init(struct apei_exec_context *ctx) +{ + apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type), + EINJ_TAB_ENTRY(einj_tab), einj_tab->entries); +} + +static int __einj_get_available_error_type(u32 *type) +{ + struct apei_exec_context ctx; + int rc; + + einj_exec_ctx_init(&ctx); + rc = apei_exec_run(&ctx, ACPI_EINJ_GET_ERROR_TYPE); + if (rc) + return rc; + *type = apei_exec_ctx_get_output(&ctx); + + return 0; +} + +/* Get error injection capabilities of the platform */ +static int einj_get_available_error_type(u32 *type) +{ + int rc; + + mutex_lock(&einj_mutex); + rc = __einj_get_available_error_type(type); + mutex_unlock(&einj_mutex); + + return rc; +} + +static int einj_timedout(u64 *t) +{ + if ((s64)*t < SPIN_UNIT) { + pr_warning(FW_WARN EINJ_PFX + "Firmware does not respond in time\n"); + return 1; + } + *t -= SPIN_UNIT; + ndelay(SPIN_UNIT); + touch_nmi_watchdog(); + return 0; +} + +/* do sanity check to trigger table */ +static int einj_check_trigger_header(struct acpi_einj_trigger *trigger_tab) +{ + if (trigger_tab->header_size != sizeof(struct acpi_einj_trigger)) + return -EINVAL; + if (trigger_tab->table_size > PAGE_SIZE || + trigger_tab->table_size <= trigger_tab->header_size) + return -EINVAL; + if (trigger_tab->entry_count != + (trigger_tab->table_size - trigger_tab->header_size) / + sizeof(struct acpi_einj_entry)) + return -EINVAL; + + return 0; +} + +/* Execute instructions in trigger error action table */ +static int __einj_error_trigger(u64 trigger_paddr) +{ + struct acpi_einj_trigger *trigger_tab = NULL; + struct apei_exec_context trigger_ctx; + struct apei_resources trigger_resources; + struct acpi_whea_header *trigger_entry; + struct resource *r; + u32 table_size; + int rc = -EIO; + + r = request_mem_region(trigger_paddr, sizeof(*trigger_tab), + "APEI EINJ Trigger Table"); + if (!r) { + pr_err(EINJ_PFX + "Can not request iomem region <%016llx-%016llx> for Trigger table.\n", + (unsigned long long)trigger_paddr, + (unsigned long long)trigger_paddr+sizeof(*trigger_tab)); + goto out; + } + trigger_tab = ioremap_cache(trigger_paddr, sizeof(*trigger_tab)); + if (!trigger_tab) { + pr_err(EINJ_PFX "Failed to map trigger table!\n"); + goto out_rel_header; + } + rc = einj_check_trigger_header(trigger_tab); + if (rc) { + pr_warning(FW_BUG EINJ_PFX + "The trigger error action table is invalid\n"); + goto out_rel_header; + } + rc = -EIO; + table_size = trigger_tab->table_size; + r = request_mem_region(trigger_paddr + sizeof(*trigger_tab), + table_size - sizeof(*trigger_tab), + "APEI EINJ Trigger Table"); + if (!r) { + pr_err(EINJ_PFX +"Can not request iomem region <%016llx-%016llx> for Trigger Table Entry.\n", + (unsigned long long)trigger_paddr+sizeof(*trigger_tab), + (unsigned long long)trigger_paddr + table_size); + goto out_rel_header; + } + iounmap(trigger_tab); + trigger_tab = ioremap_cache(trigger_paddr, table_size); + if (!trigger_tab) { + pr_err(EINJ_PFX "Failed to map trigger table!\n"); + goto out_rel_entry; + } + trigger_entry = (struct acpi_whea_header *) + ((char *)trigger_tab + sizeof(struct acpi_einj_trigger)); + apei_resources_init(&trigger_resources); + apei_exec_ctx_init(&trigger_ctx, einj_ins_type, + ARRAY_SIZE(einj_ins_type), + trigger_entry, trigger_tab->entry_count); + rc = apei_exec_collect_resources(&trigger_ctx, &trigger_resources); + if (rc) + goto out_fini; + rc = apei_resources_sub(&trigger_resources, &einj_resources); + if (rc) + goto out_fini; + rc = apei_resources_request(&trigger_resources, "APEI EINJ Trigger"); + if (rc) + goto out_fini; + rc = apei_exec_pre_map_gars(&trigger_ctx); + if (rc) + goto out_release; + + rc = apei_exec_run(&trigger_ctx, ACPI_EINJ_TRIGGER_ERROR); + + apei_exec_post_unmap_gars(&trigger_ctx); +out_release: + apei_resources_release(&trigger_resources); +out_fini: + apei_resources_fini(&trigger_resources); +out_rel_entry: + release_mem_region(trigger_paddr + sizeof(*trigger_tab), + table_size - sizeof(*trigger_tab)); +out_rel_header: + release_mem_region(trigger_paddr, sizeof(*trigger_tab)); +out: + if (trigger_tab) + iounmap(trigger_tab); + + return rc; +} + +static int __einj_error_inject(u32 type) +{ + struct apei_exec_context ctx; + u64 val, trigger_paddr, timeout = FIRMWARE_TIMEOUT; + int rc; + + einj_exec_ctx_init(&ctx); + + rc = apei_exec_run(&ctx, ACPI_EINJ_BEGIN_OPERATION); + if (rc) + return rc; + apei_exec_ctx_set_input(&ctx, type); + rc = apei_exec_run(&ctx, ACPI_EINJ_SET_ERROR_TYPE); + if (rc) + return rc; + rc = apei_exec_run(&ctx, ACPI_EINJ_EXECUTE_OPERATION); + if (rc) + return rc; + for (;;) { + rc = apei_exec_run(&ctx, ACPI_EINJ_CHECK_BUSY_STATUS); + if (rc) + return rc; + val = apei_exec_ctx_get_output(&ctx); + if (!(val & EINJ_OP_BUSY)) + break; + if (einj_timedout(&timeout)) + return -EIO; + } + rc = apei_exec_run(&ctx, ACPI_EINJ_GET_COMMAND_STATUS); + if (rc) + return rc; + val = apei_exec_ctx_get_output(&ctx); + if (val != EINJ_STATUS_SUCCESS) + return -EBUSY; + + rc = apei_exec_run(&ctx, ACPI_EINJ_GET_TRIGGER_TABLE); + if (rc) + return rc; + trigger_paddr = apei_exec_ctx_get_output(&ctx); + rc = __einj_error_trigger(trigger_paddr); + if (rc) + return rc; + rc = apei_exec_run(&ctx, ACPI_EINJ_END_OPERATION); + + return rc; +} + +/* Inject the specified hardware error */ +static int einj_error_inject(u32 type) +{ + int rc; + + mutex_lock(&einj_mutex); + rc = __einj_error_inject(type); + mutex_unlock(&einj_mutex); + + return rc; +} + +static u32 error_type; +static struct dentry *einj_debug_dir; + +static int available_error_type_show(struct seq_file *m, void *v) +{ + int rc; + u32 available_error_type = 0; + + rc = einj_get_available_error_type(&available_error_type); + if (rc) + return rc; + if (available_error_type & 0x0001) + seq_printf(m, "0x00000001\tProcessor Correctable\n"); + if (available_error_type & 0x0002) + seq_printf(m, "0x00000002\tProcessor Uncorrectable non-fatal\n"); + if (available_error_type & 0x0004) + seq_printf(m, "0x00000004\tProcessor Uncorrectable fatal\n"); + if (available_error_type & 0x0008) + seq_printf(m, "0x00000008\tMemory Correctable\n"); + if (available_error_type & 0x0010) + seq_printf(m, "0x00000010\tMemory Uncorrectable non-fatal\n"); + if (available_error_type & 0x0020) + seq_printf(m, "0x00000020\tMemory Uncorrectable fatal\n"); + if (available_error_type & 0x0040) + seq_printf(m, "0x00000040\tPCI Express Correctable\n"); + if (available_error_type & 0x0080) + seq_printf(m, "0x00000080\tPCI Express Uncorrectable non-fatal\n"); + if (available_error_type & 0x0100) + seq_printf(m, "0x00000100\tPCI Express Uncorrectable fatal\n"); + if (available_error_type & 0x0200) + seq_printf(m, "0x00000200\tPlatform Correctable\n"); + if (available_error_type & 0x0400) + seq_printf(m, "0x00000400\tPlatform Uncorrectable non-fatal\n"); + if (available_error_type & 0x0800) + seq_printf(m, "0x00000800\tPlatform Uncorrectable fatal\n"); + + return 0; +} + +static int available_error_type_open(struct inode *inode, struct file *file) +{ + return single_open(file, available_error_type_show, NULL); +} + +static const struct file_operations available_error_type_fops = { + .open = available_error_type_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int error_type_get(void *data, u64 *val) +{ + *val = error_type; + + return 0; +} + +static int error_type_set(void *data, u64 val) +{ + int rc; + u32 available_error_type = 0; + + /* Only one error type can be specified */ + if (val & (val - 1)) + return -EINVAL; + rc = einj_get_available_error_type(&available_error_type); + if (rc) + return rc; + if (!(val & available_error_type)) + return -EINVAL; + error_type = val; + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(error_type_fops, error_type_get, + error_type_set, "0x%llx\n"); + +static int error_inject_set(void *data, u64 val) +{ + if (!error_type) + return -EINVAL; + + return einj_error_inject(error_type); +} + +DEFINE_SIMPLE_ATTRIBUTE(error_inject_fops, NULL, + error_inject_set, "%llu\n"); + +static int einj_check_table(struct acpi_table_einj *einj_tab) +{ + if (einj_tab->header_length != sizeof(struct acpi_table_einj)) + return -EINVAL; + if (einj_tab->header.length < sizeof(struct acpi_table_einj)) + return -EINVAL; + if (einj_tab->entries != + (einj_tab->header.length - sizeof(struct acpi_table_einj)) / + sizeof(struct acpi_einj_entry)) + return -EINVAL; + + return 0; +} + +static int __init einj_init(void) +{ + int rc; + acpi_status status; + struct dentry *fentry; + struct apei_exec_context ctx; + + if (acpi_disabled) + return -ENODEV; + + status = acpi_get_table(ACPI_SIG_EINJ, 0, + (struct acpi_table_header **)&einj_tab); + if (status == AE_NOT_FOUND) { + pr_info(EINJ_PFX "Table is not found!\n"); + return -ENODEV; + } else if (ACPI_FAILURE(status)) { + const char *msg = acpi_format_exception(status); + pr_err(EINJ_PFX "Failed to get table, %s\n", msg); + return -EINVAL; + } + + rc = einj_check_table(einj_tab); + if (rc) { + pr_warning(FW_BUG EINJ_PFX "EINJ table is invalid\n"); + return -EINVAL; + } + + rc = -ENOMEM; + einj_debug_dir = debugfs_create_dir("einj", apei_get_debugfs_dir()); + if (!einj_debug_dir) + goto err_cleanup; + fentry = debugfs_create_file("available_error_type", S_IRUSR, + einj_debug_dir, NULL, + &available_error_type_fops); + if (!fentry) + goto err_cleanup; + fentry = debugfs_create_file("error_type", S_IRUSR | S_IWUSR, + einj_debug_dir, NULL, &error_type_fops); + if (!fentry) + goto err_cleanup; + fentry = debugfs_create_file("error_inject", S_IWUSR, + einj_debug_dir, NULL, &error_inject_fops); + if (!fentry) + goto err_cleanup; + + apei_resources_init(&einj_resources); + einj_exec_ctx_init(&ctx); + rc = apei_exec_collect_resources(&ctx, &einj_resources); + if (rc) + goto err_fini; + rc = apei_resources_request(&einj_resources, "APEI EINJ"); + if (rc) + goto err_fini; + rc = apei_exec_pre_map_gars(&ctx); + if (rc) + goto err_release; + + pr_info(EINJ_PFX "Error INJection is initialized.\n"); + + return 0; + +err_release: + apei_resources_release(&einj_resources); +err_fini: + apei_resources_fini(&einj_resources); +err_cleanup: + debugfs_remove_recursive(einj_debug_dir); + + return rc; +} + +static void __exit einj_exit(void) +{ + struct apei_exec_context ctx; + + einj_exec_ctx_init(&ctx); + apei_exec_post_unmap_gars(&ctx); + apei_resources_release(&einj_resources); + apei_resources_fini(&einj_resources); + debugfs_remove_recursive(einj_debug_dir); +} + +module_init(einj_init); +module_exit(einj_exit); + +MODULE_AUTHOR("Huang Ying"); +MODULE_DESCRIPTION("APEI Error INJection support"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From affb72c3a8984ba55e055b0a0228c3ea1a056758 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Tue, 18 May 2010 14:35:16 +0800 Subject: ACPI, APEI, PCIE AER, use general HEST table parsing in AER firmware_first setup Now, a dedicated HEST tabling parsing code is used for PCIE AER firmware_first setup. It is rebased on general HEST tabling parsing code of APEI. The firmware_first setup code is moved from PCI core to AER driver too, because it is only AER related. Signed-off-by: Huang Ying Signed-off-by: Andi Kleen Reviewed-by: Hidetoshi Seto Acked-by: Jesse Barnes Signed-off-by: Len Brown --- drivers/acpi/Makefile | 1 - drivers/acpi/hest.c | 139 ------------------------------------- drivers/pci/pcie/aer/aerdrv.h | 17 +++++ drivers/pci/pcie/aer/aerdrv_acpi.c | 77 ++++++++++++++++++++ drivers/pci/pcie/aer/aerdrv_core.c | 8 +-- drivers/pci/probe.c | 8 --- include/acpi/acpi_hest.h | 12 ---- include/linux/pci.h | 3 +- 8 files changed, 100 insertions(+), 165 deletions(-) delete mode 100644 drivers/acpi/hest.c delete mode 100644 include/acpi/acpi_hest.h (limited to 'drivers') diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index d90af7fe8b98..e7cd919548e9 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -20,7 +20,6 @@ obj-y += acpi.o \ # All the builtin files are in the "acpi." module_param namespace. acpi-y += osl.o utils.o reboot.o acpi-y += atomicio.o -acpi-y += hest.o # sleep related files acpi-y += wakeup.o diff --git a/drivers/acpi/hest.c b/drivers/acpi/hest.c deleted file mode 100644 index 1c527a192872..000000000000 --- a/drivers/acpi/hest.c +++ /dev/null @@ -1,139 +0,0 @@ -#include -#include - -#define PREFIX "ACPI: " - -static inline unsigned long parse_acpi_hest_ia_machine_check(struct acpi_hest_ia_machine_check *p) -{ - return sizeof(*p) + - (sizeof(struct acpi_hest_ia_error_bank) * p->num_hardware_banks); -} - -static inline unsigned long parse_acpi_hest_ia_corrected(struct acpi_hest_ia_corrected *p) -{ - return sizeof(*p) + - (sizeof(struct acpi_hest_ia_error_bank) * p->num_hardware_banks); -} - -static inline unsigned long parse_acpi_hest_ia_nmi(struct acpi_hest_ia_nmi *p) -{ - return sizeof(*p); -} - -static inline unsigned long parse_acpi_hest_generic(struct acpi_hest_generic *p) -{ - return sizeof(*p); -} - -static inline unsigned int hest_match_pci(struct acpi_hest_aer_common *p, struct pci_dev *pci) -{ - return (0 == pci_domain_nr(pci->bus) && - p->bus == pci->bus->number && - p->device == PCI_SLOT(pci->devfn) && - p->function == PCI_FUNC(pci->devfn)); -} - -static unsigned long parse_acpi_hest_aer(void *hdr, int type, struct pci_dev *pci, int *firmware_first) -{ - struct acpi_hest_aer_common *p = hdr + sizeof(struct acpi_hest_header); - unsigned long rc=0; - u8 pcie_type = 0; - u8 bridge = 0; - switch (type) { - case ACPI_HEST_TYPE_AER_ROOT_PORT: - rc = sizeof(struct acpi_hest_aer_root); - pcie_type = PCI_EXP_TYPE_ROOT_PORT; - break; - case ACPI_HEST_TYPE_AER_ENDPOINT: - rc = sizeof(struct acpi_hest_aer); - pcie_type = PCI_EXP_TYPE_ENDPOINT; - break; - case ACPI_HEST_TYPE_AER_BRIDGE: - rc = sizeof(struct acpi_hest_aer_bridge); - if ((pci->class >> 16) == PCI_BASE_CLASS_BRIDGE) - bridge = 1; - break; - } - - if (p->flags & ACPI_HEST_GLOBAL) { - if ((pci->is_pcie && (pci->pcie_type == pcie_type)) || bridge) - *firmware_first = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST); - } - else - if (hest_match_pci(p, pci)) - *firmware_first = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST); - return rc; -} - -static int acpi_hest_firmware_first(struct acpi_table_header *stdheader, struct pci_dev *pci) -{ - struct acpi_table_hest *hest = (struct acpi_table_hest *)stdheader; - void *p = (void *)hest + sizeof(*hest); /* defined by the ACPI 4.0 spec */ - struct acpi_hest_header *hdr = p; - - int i; - int firmware_first = 0; - static unsigned char printed_unused = 0; - static unsigned char printed_reserved = 0; - - for (i=0, hdr=p; p < (((void *)hest) + hest->header.length) && i < hest->error_source_count; i++) { - switch (hdr->type) { - case ACPI_HEST_TYPE_IA32_CHECK: - p += parse_acpi_hest_ia_machine_check(p); - break; - case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: - p += parse_acpi_hest_ia_corrected(p); - break; - case ACPI_HEST_TYPE_IA32_NMI: - p += parse_acpi_hest_ia_nmi(p); - break; - /* These three should never appear */ - case ACPI_HEST_TYPE_NOT_USED3: - case ACPI_HEST_TYPE_NOT_USED4: - case ACPI_HEST_TYPE_NOT_USED5: - if (!printed_unused) { - printk(KERN_DEBUG PREFIX - "HEST Error Source list contains an obsolete type (%d).\n", hdr->type); - printed_unused = 1; - } - break; - case ACPI_HEST_TYPE_AER_ROOT_PORT: - case ACPI_HEST_TYPE_AER_ENDPOINT: - case ACPI_HEST_TYPE_AER_BRIDGE: - p += parse_acpi_hest_aer(p, hdr->type, pci, &firmware_first); - break; - case ACPI_HEST_TYPE_GENERIC_ERROR: - p += parse_acpi_hest_generic(p); - break; - /* These should never appear either */ - case ACPI_HEST_TYPE_RESERVED: - default: - if (!printed_reserved) { - printk(KERN_DEBUG PREFIX - "HEST Error Source list contains a reserved type (%d).\n", hdr->type); - printed_reserved = 1; - } - break; - } - } - return firmware_first; -} - -int acpi_hest_firmware_first_pci(struct pci_dev *pci) -{ - acpi_status status = AE_NOT_FOUND; - struct acpi_table_header *hest = NULL; - - if (acpi_disabled) - return 0; - - status = acpi_get_table(ACPI_SIG_HEST, 1, &hest); - - if (ACPI_SUCCESS(status)) { - if (acpi_hest_firmware_first(hest, pci)) { - return 1; - } - } - return 0; -} -EXPORT_SYMBOL_GPL(acpi_hest_firmware_first_pci); diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h index bd833ea3ba49..7182c337aef1 100644 --- a/drivers/pci/pcie/aer/aerdrv.h +++ b/drivers/pci/pcie/aer/aerdrv.h @@ -134,4 +134,21 @@ static inline int aer_osc_setup(struct pcie_device *pciedev) } #endif +#ifdef CONFIG_ACPI_APEI +extern int pcie_aer_get_firmware_first(struct pci_dev *pci_dev); +#else +static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev) +{ + if (pci_dev->__aer_firmware_first_valid) + return pci_dev->__aer_firmware_first; + return 0; +} +#endif + +static inline void pcie_aer_force_firmware_first(struct pci_dev *pci_dev, + int enable) +{ + pci_dev->__aer_firmware_first = !!enable; + pci_dev->__aer_firmware_first_valid = 1; +} #endif /* _AERDRV_H_ */ diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c index 04814087658d..f278d7b0d95d 100644 --- a/drivers/pci/pcie/aer/aerdrv_acpi.c +++ b/drivers/pci/pcie/aer/aerdrv_acpi.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "aerdrv.h" /** @@ -53,3 +54,79 @@ int aer_osc_setup(struct pcie_device *pciedev) return 0; } + +#ifdef CONFIG_ACPI_APEI +static inline int hest_match_pci(struct acpi_hest_aer_common *p, + struct pci_dev *pci) +{ + return (0 == pci_domain_nr(pci->bus) && + p->bus == pci->bus->number && + p->device == PCI_SLOT(pci->devfn) && + p->function == PCI_FUNC(pci->devfn)); +} + +struct aer_hest_parse_info { + struct pci_dev *pci_dev; + int firmware_first; +}; + +static int aer_hest_parse(struct acpi_hest_header *hest_hdr, void *data) +{ + struct aer_hest_parse_info *info = data; + struct acpi_hest_aer_common *p; + u8 pcie_type = 0; + u8 bridge = 0; + int ff = 0; + + switch (hest_hdr->type) { + case ACPI_HEST_TYPE_AER_ROOT_PORT: + pcie_type = PCI_EXP_TYPE_ROOT_PORT; + break; + case ACPI_HEST_TYPE_AER_ENDPOINT: + pcie_type = PCI_EXP_TYPE_ENDPOINT; + break; + case ACPI_HEST_TYPE_AER_BRIDGE: + if ((info->pci_dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) + bridge = 1; + break; + default: + return 0; + } + + p = (struct acpi_hest_aer_common *)(hest_hdr + 1); + if (p->flags & ACPI_HEST_GLOBAL) { + if ((info->pci_dev->is_pcie && + info->pci_dev->pcie_type == pcie_type) || bridge) + ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST); + } else + if (hest_match_pci(p, info->pci_dev)) + ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST); + info->firmware_first = ff; + + return 0; +} + +static void aer_set_firmware_first(struct pci_dev *pci_dev) +{ + int rc; + struct aer_hest_parse_info info = { + .pci_dev = pci_dev, + .firmware_first = 0, + }; + + rc = apei_hest_parse(aer_hest_parse, &info); + + if (rc) + pci_dev->__aer_firmware_first = 0; + else + pci_dev->__aer_firmware_first = info.firmware_first; + pci_dev->__aer_firmware_first_valid = 1; +} + +int pcie_aer_get_firmware_first(struct pci_dev *dev) +{ + if (!dev->__aer_firmware_first_valid) + aer_set_firmware_first(dev); + return dev->__aer_firmware_first; +} +#endif diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index aceb04b67b60..586b6713e417 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -36,7 +36,7 @@ int pci_enable_pcie_error_reporting(struct pci_dev *dev) u16 reg16 = 0; int pos; - if (dev->aer_firmware_first) + if (pcie_aer_get_firmware_first(dev)) return -EIO; pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); @@ -64,7 +64,7 @@ int pci_disable_pcie_error_reporting(struct pci_dev *dev) u16 reg16 = 0; int pos; - if (dev->aer_firmware_first) + if (pcie_aer_get_firmware_first(dev)) return -EIO; pos = pci_pcie_cap(dev); @@ -859,7 +859,7 @@ void aer_delete_rootport(struct aer_rpc *rpc) */ int aer_init(struct pcie_device *dev) { - if (dev->port->aer_firmware_first) { + if (pcie_aer_get_firmware_first(dev->port)) { dev_printk(KERN_DEBUG, &dev->device, "PCIe errors handled by platform firmware.\n"); goto out; @@ -873,7 +873,7 @@ out: if (forceload) { dev_printk(KERN_DEBUG, &dev->device, "aerdrv forceload requested.\n"); - dev->port->aer_firmware_first = 0; + pcie_aer_force_firmware_first(dev->port, 0); return 0; } return -ENXIO; diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index c82548afcd5c..f4adba2d1dd3 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -10,7 +10,6 @@ #include #include #include -#include #include "pci.h" #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ @@ -904,12 +903,6 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev) pdev->is_hotplug_bridge = 1; } -static void set_pci_aer_firmware_first(struct pci_dev *pdev) -{ - if (acpi_hest_firmware_first_pci(pdev)) - pdev->aer_firmware_first = 1; -} - #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) /** @@ -939,7 +932,6 @@ int pci_setup_device(struct pci_dev *dev) dev->multifunction = !!(hdr_type & 0x80); dev->error_state = pci_channel_io_normal; set_pcie_port_type(dev); - set_pci_aer_firmware_first(dev); list_for_each_entry(slot, &dev->bus->slots, list) if (PCI_SLOT(dev->devfn) == slot->number) diff --git a/include/acpi/acpi_hest.h b/include/acpi/acpi_hest.h deleted file mode 100644 index 63194d03cb2d..000000000000 --- a/include/acpi/acpi_hest.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __ACPI_HEST_H -#define __ACPI_HEST_H - -#include - -#ifdef CONFIG_ACPI -extern int acpi_hest_firmware_first_pci(struct pci_dev *pci); -#else -static inline int acpi_hest_firmware_first_pci(struct pci_dev *pci) { return 0; } -#endif - -#endif diff --git a/include/linux/pci.h b/include/linux/pci.h index a788fa12ff31..63967e877f20 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -311,7 +311,8 @@ struct pci_dev { unsigned int is_virtfn:1; unsigned int reset_fn:1; unsigned int is_hotplug_bridge:1; - unsigned int aer_firmware_first:1; + unsigned int __aer_firmware_first_valid:1; + unsigned int __aer_firmware_first:1; pci_dev_flags_t dev_flags; atomic_t enable_cnt; /* pci_enable_device has been called */ -- cgit v1.2.3 From 801eab8118f61255d8e2be35939c572042618742 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Tue, 18 May 2010 14:35:17 +0800 Subject: ACPI Hardware Error Device (PNP0C33) support Hardware Error Device (PNP0C33) is used to report some hardware errors notified via SCI, mainly the corrected errors. Some APEI Generic Hardware Error Source (GHES) may use SCI on hardware error device to notify hardware error to kernel. After receiving notification from ACPI core, it is forwarded to all listeners via a notifier chain. The listener such as APEI GHES should check corresponding error source for new events when notified. Signed-off-by: Huang Ying Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/Kconfig | 7 ++++ drivers/acpi/Makefile | 1 + drivers/acpi/hed.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/acpi/hed.h | 18 ++++++++ 4 files changed, 138 insertions(+) create mode 100644 drivers/acpi/hed.c create mode 100644 include/acpi/hed.h (limited to 'drivers') diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 191cf2bf408c..746411518802 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -360,6 +360,13 @@ config ACPI_SBS To compile this driver as a module, choose M here: the modules will be called sbs and sbshc. +config ACPI_HED + tristate "Hardware Error Device" + help + This driver supports the Hardware Error Device (PNP0C33), + which is used to report some hardware errors notified via + SCI, mainly the corrected errors. + source "drivers/acpi/apei/Kconfig" endif # ACPI diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index e7cd919548e9..6ee33169e1dc 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -59,6 +59,7 @@ obj-$(CONFIG_ACPI_BATTERY) += battery.o obj-$(CONFIG_ACPI_SBS) += sbshc.o obj-$(CONFIG_ACPI_SBS) += sbs.o obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o +obj-$(CONFIG_ACPI_HED) += hed.o # processor has its own "processor." module_param namespace processor-y := processor_driver.o processor_throttling.o diff --git a/drivers/acpi/hed.c b/drivers/acpi/hed.c new file mode 100644 index 000000000000..d0c1967f7597 --- /dev/null +++ b/drivers/acpi/hed.c @@ -0,0 +1,112 @@ +/* + * ACPI Hardware Error Device (PNP0C33) Driver + * + * Copyright (C) 2010, Intel Corp. + * Author: Huang Ying + * + * ACPI Hardware Error Device is used to report some hardware errors + * notified via SCI, mainly the corrected errors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +static struct acpi_device_id acpi_hed_ids[] = { + {"PNP0C33", 0}, + {"", 0}, +}; +MODULE_DEVICE_TABLE(acpi, acpi_hed_ids); + +static acpi_handle hed_handle; + +static BLOCKING_NOTIFIER_HEAD(acpi_hed_notify_list); + +int register_acpi_hed_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&acpi_hed_notify_list, nb); +} +EXPORT_SYMBOL_GPL(register_acpi_hed_notifier); + +void unregister_acpi_hed_notifier(struct notifier_block *nb) +{ + blocking_notifier_chain_unregister(&acpi_hed_notify_list, nb); +} +EXPORT_SYMBOL_GPL(unregister_acpi_hed_notifier); + +/* + * SCI to report hardware error is forwarded to the listeners of HED, + * it is used by HEST Generic Hardware Error Source with notify type + * SCI. + */ +static void acpi_hed_notify(struct acpi_device *device, u32 event) +{ + blocking_notifier_call_chain(&acpi_hed_notify_list, 0, NULL); +} + +static int __devinit acpi_hed_add(struct acpi_device *device) +{ + /* Only one hardware error device */ + if (hed_handle) + return -EINVAL; + hed_handle = device->handle; + return 0; +} + +static int __devexit acpi_hed_remove(struct acpi_device *device, int type) +{ + hed_handle = NULL; + return 0; +} + +static struct acpi_driver acpi_hed_driver = { + .name = "hardware_error_device", + .class = "hardware_error", + .ids = acpi_hed_ids, + .ops = { + .add = acpi_hed_add, + .remove = acpi_hed_remove, + .notify = acpi_hed_notify, + }, +}; + +static int __init acpi_hed_init(void) +{ + if (acpi_disabled) + return -ENODEV; + + if (acpi_bus_register_driver(&acpi_hed_driver) < 0) + return -ENODEV; + + return 0; +} + +static void __exit acpi_hed_exit(void) +{ + acpi_bus_unregister_driver(&acpi_hed_driver); +} + +module_init(acpi_hed_init); +module_exit(acpi_hed_exit); + +ACPI_MODULE_NAME("hed"); +MODULE_AUTHOR("Huang Ying"); +MODULE_DESCRIPTION("ACPI Hardware Error Device Driver"); +MODULE_LICENSE("GPL"); diff --git a/include/acpi/hed.h b/include/acpi/hed.h new file mode 100644 index 000000000000..46e1249b70cc --- /dev/null +++ b/include/acpi/hed.h @@ -0,0 +1,18 @@ +/* + * hed.h - ACPI Hardware Error Device + * + * Copyright (C) 2009, Intel Corp. + * Author: Huang Ying + * + * This file is released under the GPLv2. + */ + +#ifndef ACPI_HED_H +#define ACPI_HED_H + +#include + +int register_acpi_hed_notifier(struct notifier_block *nb); +void unregister_acpi_hed_notifier(struct notifier_block *nb); + +#endif -- cgit v1.2.3 From 06d65deade9aabba58e0518df86dcd324e86b832 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Tue, 18 May 2010 14:35:19 +0800 Subject: ACPI, APEI, UEFI Common Platform Error Record (CPER) header CPER stands for Common Platform Error Record, it is the hardware error record format used to describe platform hardware error by various APEI tables, such as ERST, BERT and HEST etc. For more information about CPER, please refer to Appendix N of UEFI Specification version 2.3. This patch mainly includes the data structure difinition header file used by other files. Signed-off-by: Huang Ying Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/apei/Makefile | 2 +- drivers/acpi/apei/apei-internal.h | 19 +++ drivers/acpi/apei/cper.c | 84 ++++++++++ include/linux/cper.h | 314 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 418 insertions(+), 1 deletion(-) create mode 100644 drivers/acpi/apei/cper.c create mode 100644 include/linux/cper.h (limited to 'drivers') diff --git a/drivers/acpi/apei/Makefile b/drivers/acpi/apei/Makefile index fea86a9c3c2b..fef963ec5362 100644 --- a/drivers/acpi/apei/Makefile +++ b/drivers/acpi/apei/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_ACPI_APEI) += apei.o obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o -apei-y := apei-base.o hest.o +apei-y := apei-base.o hest.o cper.o diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h index 86e041a42c44..18df1e940276 100644 --- a/drivers/acpi/apei/apei-internal.h +++ b/drivers/acpi/apei/apei-internal.h @@ -6,6 +6,8 @@ #ifndef APEI_INTERNAL_H #define APEI_INTERNAL_H +#include + struct apei_exec_context; typedef int (*apei_exec_ins_func_t)(struct apei_exec_context *ctx, @@ -92,4 +94,21 @@ int apei_exec_collect_resources(struct apei_exec_context *ctx, struct dentry; struct dentry *apei_get_debugfs_dir(void); + +#define apei_estatus_for_each_section(estatus, section) \ + for (section = (struct acpi_hest_generic_data *)(estatus + 1); \ + (void *)section - (void *)estatus < estatus->data_length; \ + section = (void *)(section+1) + section->error_data_length) + +static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus) +{ + if (estatus->raw_data_length) + return estatus->raw_data_offset + \ + estatus->raw_data_length; + else + return sizeof(*estatus) + estatus->data_length; +} + +int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus); +int apei_estatus_check(const struct acpi_hest_generic_status *estatus); #endif diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c new file mode 100644 index 000000000000..f4cf2fc4c8c1 --- /dev/null +++ b/drivers/acpi/apei/cper.c @@ -0,0 +1,84 @@ +/* + * UEFI Common Platform Error Record (CPER) support + * + * Copyright (C) 2010, Intel Corp. + * Author: Huang Ying + * + * CPER is the format used to describe platform hardware error by + * various APEI tables, such as ERST, BERT and HEST etc. + * + * For more information about CPER, please refer to Appendix N of UEFI + * Specification version 2.3. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +/* + * CPER record ID need to be unique even after reboot, because record + * ID is used as index for ERST storage, while CPER records from + * multiple boot may co-exist in ERST. + */ +u64 cper_next_record_id(void) +{ + static atomic64_t seq; + + if (!atomic64_read(&seq)) + atomic64_set(&seq, ((u64)get_seconds()) << 32); + + return atomic64_inc_return(&seq); +} +EXPORT_SYMBOL_GPL(cper_next_record_id); + +int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus) +{ + if (estatus->data_length && + estatus->data_length < sizeof(struct acpi_hest_generic_data)) + return -EINVAL; + if (estatus->raw_data_length && + estatus->raw_data_offset < sizeof(*estatus) + estatus->data_length) + return -EINVAL; + + return 0; +} +EXPORT_SYMBOL_GPL(apei_estatus_check_header); + +int apei_estatus_check(const struct acpi_hest_generic_status *estatus) +{ + struct acpi_hest_generic_data *gdata; + unsigned int data_len, gedata_len; + int rc; + + rc = apei_estatus_check_header(estatus); + if (rc) + return rc; + data_len = estatus->data_length; + gdata = (struct acpi_hest_generic_data *)(estatus + 1); + while (data_len > sizeof(*gdata)) { + gedata_len = gdata->error_data_length; + if (gedata_len > data_len - sizeof(*gdata)) + return -EINVAL; + data_len -= gedata_len + sizeof(*gdata); + } + if (data_len) + return -EINVAL; + + return 0; +} +EXPORT_SYMBOL_GPL(apei_estatus_check); diff --git a/include/linux/cper.h b/include/linux/cper.h new file mode 100644 index 000000000000..4b38f905b705 --- /dev/null +++ b/include/linux/cper.h @@ -0,0 +1,314 @@ +/* + * UEFI Common Platform Error Record + * + * Copyright (C) 2010, Intel Corp. + * Author: Huang Ying + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef LINUX_CPER_H +#define LINUX_CPER_H + +#include + +/* CPER record signature and the size */ +#define CPER_SIG_RECORD "CPER" +#define CPER_SIG_SIZE 4 +/* Used in signature_end field in struct cper_record_header */ +#define CPER_SIG_END 0xffffffff + +/* + * CPER record header revision, used in revision field in struct + * cper_record_header + */ +#define CPER_RECORD_REV 0x0100 + +/* + * Severity difinition for error_severity in struct cper_record_header + * and section_severity in struct cper_section_descriptor + */ +#define CPER_SER_RECOVERABLE 0x0 +#define CPER_SER_FATAL 0x1 +#define CPER_SER_CORRECTED 0x2 +#define CPER_SER_INFORMATIONAL 0x3 + +/* + * Validation bits difinition for validation_bits in struct + * cper_record_header. If set, corresponding fields in struct + * cper_record_header contain valid information. + * + * corresponds platform_id + */ +#define CPER_VALID_PLATFORM_ID 0x0001 +/* corresponds timestamp */ +#define CPER_VALID_TIMESTAMP 0x0002 +/* corresponds partition_id */ +#define CPER_VALID_PARTITION_ID 0x0004 + +/* + * Notification type used to generate error record, used in + * notification_type in struct cper_record_header + * + * Corrected Machine Check + */ +#define CPER_NOTIFY_CMC \ + UUID_LE(0x2DCE8BB1, 0xBDD7, 0x450e, 0xB9, 0xAD, 0x9C, 0xF4, \ + 0xEB, 0xD4, 0xF8, 0x90) +/* Corrected Platform Error */ +#define CPER_NOTIFY_CPE \ + UUID_LE(0x4E292F96, 0xD843, 0x4a55, 0xA8, 0xC2, 0xD4, 0x81, \ + 0xF2, 0x7E, 0xBE, 0xEE) +/* Machine Check Exception */ +#define CPER_NOTIFY_MCE \ + UUID_LE(0xE8F56FFE, 0x919C, 0x4cc5, 0xBA, 0x88, 0x65, 0xAB, \ + 0xE1, 0x49, 0x13, 0xBB) +/* PCI Express Error */ +#define CPER_NOTIFY_PCIE \ + UUID_LE(0xCF93C01F, 0x1A16, 0x4dfc, 0xB8, 0xBC, 0x9C, 0x4D, \ + 0xAF, 0x67, 0xC1, 0x04) +/* INIT Record (for IPF) */ +#define CPER_NOTIFY_INIT \ + UUID_LE(0xCC5263E8, 0x9308, 0x454a, 0x89, 0xD0, 0x34, 0x0B, \ + 0xD3, 0x9B, 0xC9, 0x8E) +/* Non-Maskable Interrupt */ +#define CPER_NOTIFY_NMI \ + UUID_LE(0x5BAD89FF, 0xB7E6, 0x42c9, 0x81, 0x4A, 0xCF, 0x24, \ + 0x85, 0xD6, 0xE9, 0x8A) +/* BOOT Error Record */ +#define CPER_NOTIFY_BOOT \ + UUID_LE(0x3D61A466, 0xAB40, 0x409a, 0xA6, 0x98, 0xF3, 0x62, \ + 0xD4, 0x64, 0xB3, 0x8F) +/* DMA Remapping Error */ +#define CPER_NOTIFY_DMAR \ + UUID_LE(0x667DD791, 0xC6B3, 0x4c27, 0x8A, 0x6B, 0x0F, 0x8E, \ + 0x72, 0x2D, 0xEB, 0x41) + +/* + * Flags bits definitions for flags in struct cper_record_header + * If set, the error has been recovered + */ +#define CPER_HW_ERROR_FLAGS_RECOVERED 0x1 +/* If set, the error is for previous boot */ +#define CPER_HW_ERROR_FLAGS_PREVERR 0x2 +/* If set, the error is injected for testing */ +#define CPER_HW_ERROR_FLAGS_SIMULATED 0x4 + +/* + * CPER section header revision, used in revision field in struct + * cper_section_descriptor + */ +#define CPER_SEC_REV 0x0100 + +/* + * Validation bits difinition for validation_bits in struct + * cper_section_descriptor. If set, corresponding fields in struct + * cper_section_descriptor contain valid information. + * + * corresponds fru_id + */ +#define CPER_SEC_VALID_FRU_ID 0x1 +/* corresponds fru_text */ +#define CPER_SEC_VALID_FRU_TEXT 0x2 + +/* + * Flags bits definitions for flags in struct cper_section_descriptor + * + * If set, the section is associated with the error condition + * directly, and should be focused on + */ +#define CPER_SEC_PRIMARY 0x0001 +/* + * If set, the error was not contained within the processor or memory + * hierarchy and the error may have propagated to persistent storage + * or network + */ +#define CPER_SEC_CONTAINMENT_WARNING 0x0002 +/* If set, the component must be re-initialized or re-enabled prior to use */ +#define CPER_SEC_RESET 0x0004 +/* If set, Linux may choose to discontinue use of the resource */ +#define CPER_SEC_ERROR_THRESHOLD_EXCEEDED 0x0008 +/* + * If set, resource could not be queried for error information due to + * conflicts with other system software or resources. Some fields of + * the section will be invalid + */ +#define CPER_SEC_RESOURCE_NOT_ACCESSIBLE 0x0010 +/* + * If set, action has been taken to ensure error containment (such as + * poisoning data), but the error has not been fully corrected and the + * data has not been consumed. Linux may choose to take further + * corrective action before the data is consumed + */ +#define CPER_SEC_LATENT_ERROR 0x0020 + +/* + * Section type definitions, used in section_type field in struct + * cper_section_descriptor + * + * Processor Generic + */ +#define CPER_SEC_PROC_GENERIC \ + UUID_LE(0x9876CCAD, 0x47B4, 0x4bdb, 0xB6, 0x5E, 0x16, 0xF1, \ + 0x93, 0xC4, 0xF3, 0xDB) +/* Processor Specific: X86/X86_64 */ +#define CPER_SEC_PROC_IA \ + UUID_LE(0xDC3EA0B0, 0xA144, 0x4797, 0xB9, 0x5B, 0x53, 0xFA, \ + 0x24, 0x2B, 0x6E, 0x1D) +/* Processor Specific: IA64 */ +#define CPER_SEC_PROC_IPF \ + UUID_LE(0xE429FAF1, 0x3CB7, 0x11D4, 0x0B, 0xCA, 0x07, 0x00, \ + 0x80, 0xC7, 0x3C, 0x88, 0x81) +/* Platform Memory */ +#define CPER_SEC_PLATFORM_MEM \ + UUID_LE(0xA5BC1114, 0x6F64, 0x4EDE, 0xB8, 0x63, 0x3E, 0x83, \ + 0xED, 0x7C, 0x83, 0xB1) +#define CPER_SEC_PCIE \ + UUID_LE(0xD995E954, 0xBBC1, 0x430F, 0xAD, 0x91, 0xB4, 0x4D, \ + 0xCB, 0x3C, 0x6F, 0x35) +/* Firmware Error Record Reference */ +#define CPER_SEC_FW_ERR_REC_REF \ + UUID_LE(0x81212A96, 0x09ED, 0x4996, 0x94, 0x71, 0x8D, 0x72, \ + 0x9C, 0x8E, 0x69, 0xED) +/* PCI/PCI-X Bus */ +#define CPER_SEC_PCI_X_BUS \ + UUID_LE(0xC5753963, 0x3B84, 0x4095, 0xBF, 0x78, 0xED, 0xDA, \ + 0xD3, 0xF9, 0xC9, 0xDD) +/* PCI Component/Device */ +#define CPER_SEC_PCI_DEV \ + UUID_LE(0xEB5E4685, 0xCA66, 0x4769, 0xB6, 0xA2, 0x26, 0x06, \ + 0x8B, 0x00, 0x13, 0x26) +#define CPER_SEC_DMAR_GENERIC \ + UUID_LE(0x5B51FEF7, 0xC79D, 0x4434, 0x8F, 0x1B, 0xAA, 0x62, \ + 0xDE, 0x3E, 0x2C, 0x64) +/* Intel VT for Directed I/O specific DMAr */ +#define CPER_SEC_DMAR_VT \ + UUID_LE(0x71761D37, 0x32B2, 0x45cd, 0xA7, 0xD0, 0xB0, 0xFE, \ + 0xDD, 0x93, 0xE8, 0xCF) +/* IOMMU specific DMAr */ +#define CPER_SEC_DMAR_IOMMU \ + UUID_LE(0x036F84E1, 0x7F37, 0x428c, 0xA7, 0x9E, 0x57, 0x5F, \ + 0xDF, 0xAA, 0x84, 0xEC) + +/* + * All tables and structs must be byte-packed to match CPER + * specification, since the tables are provided by the system BIOS + */ +#pragma pack(1) + +struct cper_record_header { + char signature[CPER_SIG_SIZE]; /* must be CPER_SIG_RECORD */ + __u16 revision; /* must be CPER_RECORD_REV */ + __u32 signature_end; /* must be CPER_SIG_END */ + __u16 section_count; + __u32 error_severity; + __u32 validation_bits; + __u32 record_length; + __u64 timestamp; + uuid_le platform_id; + uuid_le partition_id; + uuid_le creator_id; + uuid_le notification_type; + __u64 record_id; + __u32 flags; + __u64 persistence_information; + __u8 reserved[12]; /* must be zero */ +}; + +struct cper_section_descriptor { + __u32 section_offset; /* Offset in bytes of the + * section body from the base + * of the record header */ + __u32 section_length; + __u16 revision; /* must be CPER_RECORD_REV */ + __u8 validation_bits; + __u8 reserved; /* must be zero */ + __u32 flags; + uuid_le section_type; + uuid_le fru_id; + __u32 section_severity; + __u8 fru_text[20]; +}; + +/* Generic Processor Error Section */ +struct cper_sec_proc_generic { + __u64 validation_bits; + __u8 proc_type; + __u8 proc_isa; + __u8 proc_error_type; + __u8 operation; + __u8 flags; + __u8 level; + __u16 reserved; + __u64 cpu_version; + char cpu_brand[128]; + __u64 proc_id; + __u64 target_addr; + __u64 requestor_id; + __u64 responder_id; + __u64 ip; +}; + +/* IA32/X64 Processor Error Section */ +struct cper_sec_proc_ia { + __u64 validation_bits; + __u8 lapic_id; + __u8 cpuid[48]; +}; + +/* IA32/X64 Processor Error Infomation Structure */ +struct cper_ia_err_info { + uuid_le err_type; + __u64 validation_bits; + __u64 check_info; + __u64 target_id; + __u64 requestor_id; + __u64 responder_id; + __u64 ip; +}; + +/* IA32/X64 Processor Context Information Structure */ +struct cper_ia_proc_ctx { + __u16 reg_ctx_type; + __u16 reg_arr_size; + __u32 msr_addr; + __u64 mm_reg_addr; +}; + +/* Memory Error Section */ +struct cper_sec_mem_err { + __u64 validation_bits; + __u64 error_status; + __u64 physical_addr; + __u64 physical_addr_mask; + __u16 node; + __u16 card; + __u16 module; + __u16 bank; + __u16 device; + __u16 row; + __u16 column; + __u16 bit_pos; + __u64 requestor_id; + __u64 responder_id; + __u64 target_id; + __u8 error_type; +}; + +/* Reset to default packing */ +#pragma pack() + +u64 cper_next_record_id(void); + +#endif -- cgit v1.2.3 From d334a49113a4a33109fd24e46073280ecd1bea0d Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Tue, 18 May 2010 14:35:20 +0800 Subject: ACPI, APEI, Generic Hardware Error Source memory error support Generic Hardware Error Source provides a way to report platform hardware errors (such as that from chipset). It works in so called "Firmware First" mode, that is, hardware errors are reported to firmware firstly, then reported to Linux by firmware. This way, some non-standard hardware error registers or non-standard hardware link can be checked by firmware to produce more valuable hardware error information for Linux. Now, only SCI notification type and memory errors are supported. More notification type and hardware error type will be added later. These memory errors are reported to user space through /dev/mcelog via faking a corrected Machine Check, so that the error memory page can be offlined by /sbin/mcelog if the error count for one page is beyond the threshold. On some machines, Machine Check can not report physical address for some corrected memory errors, but GHES can do that. So this simplified GHES is implemented firstly. Signed-off-by: Huang Ying Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- arch/x86/include/asm/mce.h | 8 + arch/x86/kernel/cpu/mcheck/Makefile | 2 + arch/x86/kernel/cpu/mcheck/mce-apei.c | 52 +++++ drivers/acpi/apei/Kconfig | 14 ++ drivers/acpi/apei/Makefile | 1 + drivers/acpi/apei/ghes.c | 427 ++++++++++++++++++++++++++++++++++ 6 files changed, 504 insertions(+) create mode 100644 arch/x86/kernel/cpu/mcheck/mce-apei.c create mode 100644 drivers/acpi/apei/ghes.c (limited to 'drivers') diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index 6c3fdd631ed3..f32a4301c4d4 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h @@ -225,5 +225,13 @@ extern void mcheck_intel_therm_init(void); static inline void mcheck_intel_therm_init(void) { } #endif +/* + * Used by APEI to report memory error via /dev/mcelog + */ + +struct cper_sec_mem_err; +extern void apei_mce_report_mem_error(int corrected, + struct cper_sec_mem_err *mem_err); + #endif /* __KERNEL__ */ #endif /* _ASM_X86_MCE_H */ diff --git a/arch/x86/kernel/cpu/mcheck/Makefile b/arch/x86/kernel/cpu/mcheck/Makefile index 4ac6d48fe11b..bb34b03af252 100644 --- a/arch/x86/kernel/cpu/mcheck/Makefile +++ b/arch/x86/kernel/cpu/mcheck/Makefile @@ -7,3 +7,5 @@ obj-$(CONFIG_X86_MCE_THRESHOLD) += threshold.o obj-$(CONFIG_X86_MCE_INJECT) += mce-inject.o obj-$(CONFIG_X86_THERMAL_VECTOR) += therm_throt.o + +obj-$(CONFIG_ACPI_APEI) += mce-apei.o diff --git a/arch/x86/kernel/cpu/mcheck/mce-apei.c b/arch/x86/kernel/cpu/mcheck/mce-apei.c new file mode 100644 index 000000000000..4eccd1fadb14 --- /dev/null +++ b/arch/x86/kernel/cpu/mcheck/mce-apei.c @@ -0,0 +1,52 @@ +/* + * Bridge between MCE and APEI + * + * On some machine, corrected memory errors are reported via APEI + * generic hardware error source (GHES) instead of corrected Machine + * Check. These corrected memory errors can be reported to user space + * through /dev/mcelog via faking a corrected Machine Check, so that + * the error memory page can be offlined by /sbin/mcelog if the error + * count for one page is beyond the threshold. + * + * Copyright 2010 Intel Corp. + * Author: Huang Ying + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +#include "mce-internal.h" + +void apei_mce_report_mem_error(int corrected, struct cper_sec_mem_err *mem_err) +{ + struct mce m; + + /* Only corrected MC is reported */ + if (!corrected) + return; + + mce_setup(&m); + m.bank = 1; + /* Fake a memory read corrected error with unknown channel */ + m.status = MCI_STATUS_VAL | MCI_STATUS_EN | MCI_STATUS_ADDRV | 0x9f; + m.addr = mem_err->physical_addr; + mce_log(&m); + mce_notify_irq(); +} +EXPORT_SYMBOL_GPL(apei_mce_report_mem_error); diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index 5f0a41c2bc62..f8c668f27b5a 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig @@ -7,6 +7,20 @@ config ACPI_APEI especially. In addition it supports error serialization and error injection. +config ACPI_APEI_GHES + tristate "APEI Generic Hardware Error Source" + depends on ACPI_APEI && X86 + select ACPI_HED + help + Generic Hardware Error Source provides a way to report + platform hardware errors (such as that from chipset). It + works in so called "Firmware First" mode, that is, hardware + errors are reported to firmware firstly, then reported to + Linux by firmware. This way, some non-standard hardware + error registers or non-standard hardware link can be checked + by firmware to produce more valuable hardware error + information for Linux. + config ACPI_APEI_EINJ tristate "APEI Error INJection (EINJ)" depends on ACPI_APEI && DEBUG_FS diff --git a/drivers/acpi/apei/Makefile b/drivers/acpi/apei/Makefile index fef963ec5362..41c61db4c51c 100644 --- a/drivers/acpi/apei/Makefile +++ b/drivers/acpi/apei/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_ACPI_APEI) += apei.o +obj-$(CONFIG_ACPI_APEI_GHES) += ghes.o obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o apei-y := apei-base.o hest.o cper.o diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c new file mode 100644 index 000000000000..fd0cc016a099 --- /dev/null +++ b/drivers/acpi/apei/ghes.c @@ -0,0 +1,427 @@ +/* + * APEI Generic Hardware Error Source support + * + * Generic Hardware Error Source provides a way to report platform + * hardware errors (such as that from chipset). It works in so called + * "Firmware First" mode, that is, hardware errors are reported to + * firmware firstly, then reported to Linux by firmware. This way, + * some non-standard hardware error registers or non-standard hardware + * link can be checked by firmware to produce more hardware error + * information for Linux. + * + * For more information about Generic Hardware Error Source, please + * refer to ACPI Specification version 4.0, section 17.3.2.6 + * + * Now, only SCI notification type and memory errors are + * supported. More notification type and hardware error type will be + * added later. + * + * Copyright 2010 Intel Corp. + * Author: Huang Ying + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "apei-internal.h" + +#define GHES_PFX "GHES: " + +#define GHES_ESTATUS_MAX_SIZE 65536 + +/* + * One struct ghes is created for each generic hardware error + * source. + * + * It provides the context for APEI hardware error timer/IRQ/SCI/NMI + * handler. Handler for one generic hardware error source is only + * triggered after the previous one is done. So handler can uses + * struct ghes without locking. + * + * estatus: memory buffer for error status block, allocated during + * HEST parsing. + */ +#define GHES_TO_CLEAR 0x0001 + +struct ghes { + struct acpi_hest_generic *generic; + struct acpi_hest_generic_status *estatus; + struct list_head list; + u64 buffer_paddr; + unsigned long flags; +}; + +/* + * Error source lists, one list for each notification method. The + * members in lists are struct ghes. + * + * The list members are only added in HEST parsing and deleted during + * module_exit, that is, single-threaded. So no lock is needed for + * that. + * + * But the mutual exclusion is needed between members adding/deleting + * and timer/IRQ/SCI/NMI handler, which may traverse the list. RCU is + * used for that. + */ +static LIST_HEAD(ghes_sci); + +static struct ghes *ghes_new(struct acpi_hest_generic *generic) +{ + struct ghes *ghes; + unsigned int error_block_length; + int rc; + + ghes = kzalloc(sizeof(*ghes), GFP_KERNEL); + if (!ghes) + return ERR_PTR(-ENOMEM); + ghes->generic = generic; + INIT_LIST_HEAD(&ghes->list); + rc = acpi_pre_map_gar(&generic->error_status_address); + if (rc) + goto err_free; + error_block_length = generic->error_block_length; + if (error_block_length > GHES_ESTATUS_MAX_SIZE) { + pr_warning(FW_WARN GHES_PFX + "Error status block length is too long: %u for " + "generic hardware error source: %d.\n", + error_block_length, generic->header.source_id); + error_block_length = GHES_ESTATUS_MAX_SIZE; + } + ghes->estatus = kmalloc(error_block_length, GFP_KERNEL); + if (!ghes->estatus) { + rc = -ENOMEM; + goto err_unmap; + } + + return ghes; + +err_unmap: + acpi_post_unmap_gar(&generic->error_status_address); +err_free: + kfree(ghes); + return ERR_PTR(rc); +} + +static void ghes_fini(struct ghes *ghes) +{ + kfree(ghes->estatus); + acpi_post_unmap_gar(&ghes->generic->error_status_address); +} + +enum { + GHES_SER_NO = 0x0, + GHES_SER_CORRECTED = 0x1, + GHES_SER_RECOVERABLE = 0x2, + GHES_SER_PANIC = 0x3, +}; + +static inline int ghes_severity(int severity) +{ + switch (severity) { + case CPER_SER_INFORMATIONAL: + return GHES_SER_NO; + case CPER_SER_CORRECTED: + return GHES_SER_CORRECTED; + case CPER_SER_RECOVERABLE: + return GHES_SER_RECOVERABLE; + case CPER_SER_FATAL: + return GHES_SER_PANIC; + default: + /* Unkown, go panic */ + return GHES_SER_PANIC; + } +} + +/* SCI handler run in work queue, so ioremap can be used here */ +static int ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len, + int from_phys) +{ + void *vaddr; + + vaddr = ioremap_cache(paddr, len); + if (!vaddr) + return -ENOMEM; + if (from_phys) + memcpy(buffer, vaddr, len); + else + memcpy(vaddr, buffer, len); + iounmap(vaddr); + + return 0; +} + +static int ghes_read_estatus(struct ghes *ghes, int silent) +{ + struct acpi_hest_generic *g = ghes->generic; + u64 buf_paddr; + u32 len; + int rc; + + rc = acpi_atomic_read(&buf_paddr, &g->error_status_address); + if (rc) { + if (!silent && printk_ratelimit()) + pr_warning(FW_WARN GHES_PFX +"Failed to read error status block address for hardware error source: %d.\n", + g->header.source_id); + return -EIO; + } + if (!buf_paddr) + return -ENOENT; + + rc = ghes_copy_tofrom_phys(ghes->estatus, buf_paddr, + sizeof(*ghes->estatus), 1); + if (rc) + return rc; + if (!ghes->estatus->block_status) + return -ENOENT; + + ghes->buffer_paddr = buf_paddr; + ghes->flags |= GHES_TO_CLEAR; + + rc = -EIO; + len = apei_estatus_len(ghes->estatus); + if (len < sizeof(*ghes->estatus)) + goto err_read_block; + if (len > ghes->generic->error_block_length) + goto err_read_block; + if (apei_estatus_check_header(ghes->estatus)) + goto err_read_block; + rc = ghes_copy_tofrom_phys(ghes->estatus + 1, + buf_paddr + sizeof(*ghes->estatus), + len - sizeof(*ghes->estatus), 1); + if (rc) + return rc; + if (apei_estatus_check(ghes->estatus)) + goto err_read_block; + rc = 0; + +err_read_block: + if (rc && !silent) + pr_warning(FW_WARN GHES_PFX + "Failed to read error status block!\n"); + return rc; +} + +static void ghes_clear_estatus(struct ghes *ghes) +{ + ghes->estatus->block_status = 0; + if (!(ghes->flags & GHES_TO_CLEAR)) + return; + ghes_copy_tofrom_phys(ghes->estatus, ghes->buffer_paddr, + sizeof(ghes->estatus->block_status), 0); + ghes->flags &= ~GHES_TO_CLEAR; +} + +static void ghes_do_proc(struct ghes *ghes) +{ + int ser, processed = 0; + struct acpi_hest_generic_data *gdata; + + ser = ghes_severity(ghes->estatus->error_severity); + apei_estatus_for_each_section(ghes->estatus, gdata) { +#ifdef CONFIG_X86_MCE + if (!uuid_le_cmp(*(uuid_le *)gdata->section_type, + CPER_SEC_PLATFORM_MEM)) { + apei_mce_report_mem_error( + ser == GHES_SER_CORRECTED, + (struct cper_sec_mem_err *)(gdata+1)); + processed = 1; + } +#endif + } + + if (!processed && printk_ratelimit()) + pr_warning(GHES_PFX + "Unknown error record from generic hardware error source: %d\n", + ghes->generic->header.source_id); +} + +static int ghes_proc(struct ghes *ghes) +{ + int rc; + + rc = ghes_read_estatus(ghes, 0); + if (rc) + goto out; + ghes_do_proc(ghes); + +out: + ghes_clear_estatus(ghes); + return 0; +} + +static int ghes_notify_sci(struct notifier_block *this, + unsigned long event, void *data) +{ + struct ghes *ghes; + int ret = NOTIFY_DONE; + + rcu_read_lock(); + list_for_each_entry_rcu(ghes, &ghes_sci, list) { + if (!ghes_proc(ghes)) + ret = NOTIFY_OK; + } + rcu_read_unlock(); + + return ret; +} + +static struct notifier_block ghes_notifier_sci = { + .notifier_call = ghes_notify_sci, +}; + +static int hest_ghes_parse(struct acpi_hest_header *hest_hdr, void *data) +{ + struct acpi_hest_generic *generic; + struct ghes *ghes = NULL; + int rc = 0; + + if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) + return 0; + + generic = (struct acpi_hest_generic *)hest_hdr; + if (!generic->enabled) + return 0; + + if (generic->error_block_length < + sizeof(struct acpi_hest_generic_status)) { + pr_warning(FW_BUG GHES_PFX +"Invalid error block length: %u for generic hardware error source: %d\n", + generic->error_block_length, + generic->header.source_id); + goto err; + } + if (generic->records_to_preallocate == 0) { + pr_warning(FW_BUG GHES_PFX +"Invalid records to preallocate: %u for generic hardware error source: %d\n", + generic->records_to_preallocate, + generic->header.source_id); + goto err; + } + ghes = ghes_new(generic); + if (IS_ERR(ghes)) { + rc = PTR_ERR(ghes); + ghes = NULL; + goto err; + } + switch (generic->notify.type) { + case ACPI_HEST_NOTIFY_POLLED: + pr_warning(GHES_PFX +"Generic hardware error source: %d notified via POLL is not supported!\n", + generic->header.source_id); + break; + case ACPI_HEST_NOTIFY_EXTERNAL: + case ACPI_HEST_NOTIFY_LOCAL: + pr_warning(GHES_PFX +"Generic hardware error source: %d notified via IRQ is not supported!\n", + generic->header.source_id); + break; + case ACPI_HEST_NOTIFY_SCI: + if (list_empty(&ghes_sci)) + register_acpi_hed_notifier(&ghes_notifier_sci); + list_add_rcu(&ghes->list, &ghes_sci); + break; + case ACPI_HEST_NOTIFY_NMI: + pr_warning(GHES_PFX +"Generic hardware error source: %d notified via NMI is not supported!\n", + generic->header.source_id); + break; + default: + pr_warning(FW_WARN GHES_PFX + "Unknown notification type: %u for generic hardware error source: %d\n", + generic->notify.type, generic->header.source_id); + break; + } + + return 0; +err: + if (ghes) + ghes_fini(ghes); + return rc; +} + +static void ghes_cleanup(void) +{ + struct ghes *ghes, *nghes; + + if (!list_empty(&ghes_sci)) + unregister_acpi_hed_notifier(&ghes_notifier_sci); + + synchronize_rcu(); + + list_for_each_entry_safe(ghes, nghes, &ghes_sci, list) { + list_del(&ghes->list); + ghes_fini(ghes); + kfree(ghes); + } +} + +static int __init ghes_init(void) +{ + int rc; + + if (acpi_disabled) + return -ENODEV; + + if (hest_disable) { + pr_info(GHES_PFX "HEST is not enabled!\n"); + return -EINVAL; + } + + rc = apei_hest_parse(hest_ghes_parse, NULL); + if (rc) { + pr_err(GHES_PFX + "Error during parsing HEST generic hardware error sources.\n"); + goto err_cleanup; + } + + if (list_empty(&ghes_sci)) { + pr_info(GHES_PFX + "No functional generic hardware error sources.\n"); + rc = -ENODEV; + goto err_cleanup; + } + + pr_info(GHES_PFX + "Generic Hardware Error Source support is initialized.\n"); + + return 0; +err_cleanup: + ghes_cleanup(); + return rc; +} + +static void __exit ghes_exit(void) +{ + ghes_cleanup(); +} + +module_init(ghes_init); +module_exit(ghes_exit); + +MODULE_AUTHOR("Huang Ying"); +MODULE_DESCRIPTION("APEI Generic Hardware Error Source support"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From a08f82d08053fb6e3aa3635c2c26456d96337c8b Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Tue, 18 May 2010 14:35:21 +0800 Subject: ACPI, APEI, Error Record Serialization Table (ERST) support ERST is a way provided by APEI to save and retrieve hardware error record to and from some simple persistent storage (such as flash). The Linux kernel support implementation is quite simple and workable in NMI context. So it can be used to save hardware error record into flash in hardware error exception or NMI handler, where other more complex persistent storage such as disk is not usable. After saving hardware error records via ERST in hardware error exception or NMI handler, the error records can be retrieved and logged into disk or network after a clean reboot. For more information about ERST, please refer to ACPI Specification version 4.0, section 17.4. This patch incorporate fixes from Jin Dongming. Signed-off-by: Huang Ying Signed-off-by: Andi Kleen CC: Jin Dongming Signed-off-by: Len Brown --- Documentation/kernel-parameters.txt | 4 + drivers/acpi/apei/Makefile | 2 +- drivers/acpi/apei/erst.c | 855 ++++++++++++++++++++++++++++++++++++ include/acpi/apei.h | 21 + 4 files changed, 881 insertions(+), 1 deletion(-) create mode 100644 drivers/acpi/apei/erst.c (limited to 'drivers') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 47a0e1ba5e64..42d77735fd45 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -750,6 +750,10 @@ and is between 256 and 4096 characters. It is defined in the file Default value is 0. Value can be changed at runtime via /selinux/enforce. + erst_disable [ACPI] + Disable Error Record Serialization Table (ERST) + support. + ether= [HW,NET] Ethernet cards parameters This option is obsoleted by the "netdev=" option, which has equivalent usage. See its documentation for details. diff --git a/drivers/acpi/apei/Makefile b/drivers/acpi/apei/Makefile index 41c61db4c51c..b13b03a17789 100644 --- a/drivers/acpi/apei/Makefile +++ b/drivers/acpi/apei/Makefile @@ -2,4 +2,4 @@ obj-$(CONFIG_ACPI_APEI) += apei.o obj-$(CONFIG_ACPI_APEI_GHES) += ghes.o obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o -apei-y := apei-base.o hest.o cper.o +apei-y := apei-base.o hest.o cper.o erst.o diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c new file mode 100644 index 000000000000..2ebc39115507 --- /dev/null +++ b/drivers/acpi/apei/erst.c @@ -0,0 +1,855 @@ +/* + * APEI Error Record Serialization Table support + * + * ERST is a way provided by APEI to save and retrieve hardware error + * infomation to and from a persistent store. + * + * For more information about ERST, please refer to ACPI Specification + * version 4.0, section 17.4. + * + * Copyright 2010 Intel Corp. + * Author: Huang Ying + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "apei-internal.h" + +#define ERST_PFX "ERST: " + +/* ERST command status */ +#define ERST_STATUS_SUCCESS 0x0 +#define ERST_STATUS_NOT_ENOUGH_SPACE 0x1 +#define ERST_STATUS_HARDWARE_NOT_AVAILABLE 0x2 +#define ERST_STATUS_FAILED 0x3 +#define ERST_STATUS_RECORD_STORE_EMPTY 0x4 +#define ERST_STATUS_RECORD_NOT_FOUND 0x5 + +#define ERST_TAB_ENTRY(tab) \ + ((struct acpi_whea_header *)((char *)(tab) + \ + sizeof(struct acpi_table_erst))) + +#define SPIN_UNIT 100 /* 100ns */ +/* Firmware should respond within 1 miliseconds */ +#define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC) +#define FIRMWARE_MAX_STALL 50 /* 50us */ + +int erst_disable; +EXPORT_SYMBOL_GPL(erst_disable); + +static struct acpi_table_erst *erst_tab; + +/* ERST Error Log Address Range atrributes */ +#define ERST_RANGE_RESERVED 0x0001 +#define ERST_RANGE_NVRAM 0x0002 +#define ERST_RANGE_SLOW 0x0004 + +/* + * ERST Error Log Address Range, used as buffer for reading/writing + * error records. + */ +static struct erst_erange { + u64 base; + u64 size; + void __iomem *vaddr; + u32 attr; +} erst_erange; + +/* + * Prevent ERST interpreter to run simultaneously, because the + * corresponding firmware implementation may not work properly when + * invoked simultaneously. + * + * It is used to provide exclusive accessing for ERST Error Log + * Address Range too. + */ +static DEFINE_SPINLOCK(erst_lock); + +static inline int erst_errno(int command_status) +{ + switch (command_status) { + case ERST_STATUS_SUCCESS: + return 0; + case ERST_STATUS_HARDWARE_NOT_AVAILABLE: + return -ENODEV; + case ERST_STATUS_NOT_ENOUGH_SPACE: + return -ENOSPC; + case ERST_STATUS_RECORD_STORE_EMPTY: + case ERST_STATUS_RECORD_NOT_FOUND: + return -ENOENT; + default: + return -EINVAL; + } +} + +static int erst_timedout(u64 *t, u64 spin_unit) +{ + if ((s64)*t < spin_unit) { + pr_warning(FW_WARN ERST_PFX + "Firmware does not respond in time\n"); + return 1; + } + *t -= spin_unit; + ndelay(spin_unit); + touch_nmi_watchdog(); + return 0; +} + +static int erst_exec_load_var1(struct apei_exec_context *ctx, + struct acpi_whea_header *entry) +{ + return __apei_exec_read_register(entry, &ctx->var1); +} + +static int erst_exec_load_var2(struct apei_exec_context *ctx, + struct acpi_whea_header *entry) +{ + return __apei_exec_read_register(entry, &ctx->var2); +} + +static int erst_exec_store_var1(struct apei_exec_context *ctx, + struct acpi_whea_header *entry) +{ + return __apei_exec_write_register(entry, ctx->var1); +} + +static int erst_exec_add(struct apei_exec_context *ctx, + struct acpi_whea_header *entry) +{ + ctx->var1 += ctx->var2; + return 0; +} + +static int erst_exec_subtract(struct apei_exec_context *ctx, + struct acpi_whea_header *entry) +{ + ctx->var1 -= ctx->var2; + return 0; +} + +static int erst_exec_add_value(struct apei_exec_context *ctx, + struct acpi_whea_header *entry) +{ + int rc; + u64 val; + + rc = __apei_exec_read_register(entry, &val); + if (rc) + return rc; + val += ctx->value; + rc = __apei_exec_write_register(entry, val); + return rc; +} + +static int erst_exec_subtract_value(struct apei_exec_context *ctx, + struct acpi_whea_header *entry) +{ + int rc; + u64 val; + + rc = __apei_exec_read_register(entry, &val); + if (rc) + return rc; + val -= ctx->value; + rc = __apei_exec_write_register(entry, val); + return rc; +} + +static int erst_exec_stall(struct apei_exec_context *ctx, + struct acpi_whea_header *entry) +{ + u64 stall_time; + + if (ctx->value > FIRMWARE_MAX_STALL) { + if (!in_nmi()) + pr_warning(FW_WARN ERST_PFX + "Too long stall time for stall instruction: %llx.\n", + ctx->value); + stall_time = FIRMWARE_MAX_STALL; + } else + stall_time = ctx->value; + udelay(stall_time); + return 0; +} + +static int erst_exec_stall_while_true(struct apei_exec_context *ctx, + struct acpi_whea_header *entry) +{ + int rc; + u64 val; + u64 timeout = FIRMWARE_TIMEOUT; + u64 stall_time; + + if (ctx->var1 > FIRMWARE_MAX_STALL) { + if (!in_nmi()) + pr_warning(FW_WARN ERST_PFX + "Too long stall time for stall while true instruction: %llx.\n", + ctx->var1); + stall_time = FIRMWARE_MAX_STALL; + } else + stall_time = ctx->var1; + + for (;;) { + rc = __apei_exec_read_register(entry, &val); + if (rc) + return rc; + if (val != ctx->value) + break; + if (erst_timedout(&timeout, stall_time * NSEC_PER_USEC)) + return -EIO; + } + return 0; +} + +static int erst_exec_skip_next_instruction_if_true( + struct apei_exec_context *ctx, + struct acpi_whea_header *entry) +{ + int rc; + u64 val; + + rc = __apei_exec_read_register(entry, &val); + if (rc) + return rc; + if (val == ctx->value) { + ctx->ip += 2; + return APEI_EXEC_SET_IP; + } + + return 0; +} + +static int erst_exec_goto(struct apei_exec_context *ctx, + struct acpi_whea_header *entry) +{ + ctx->ip = ctx->value; + return APEI_EXEC_SET_IP; +} + +static int erst_exec_set_src_address_base(struct apei_exec_context *ctx, + struct acpi_whea_header *entry) +{ + return __apei_exec_read_register(entry, &ctx->src_base); +} + +static int erst_exec_set_dst_address_base(struct apei_exec_context *ctx, + struct acpi_whea_header *entry) +{ + return __apei_exec_read_register(entry, &ctx->dst_base); +} + +static int erst_exec_move_data(struct apei_exec_context *ctx, + struct acpi_whea_header *entry) +{ + int rc; + u64 offset; + + rc = __apei_exec_read_register(entry, &offset); + if (rc) + return rc; + memmove((void *)ctx->dst_base + offset, + (void *)ctx->src_base + offset, + ctx->var2); + + return 0; +} + +static struct apei_exec_ins_type erst_ins_type[] = { + [ACPI_ERST_READ_REGISTER] = { + .flags = APEI_EXEC_INS_ACCESS_REGISTER, + .run = apei_exec_read_register, + }, + [ACPI_ERST_READ_REGISTER_VALUE] = { + .flags = APEI_EXEC_INS_ACCESS_REGISTER, + .run = apei_exec_read_register_value, + }, + [ACPI_ERST_WRITE_REGISTER] = { + .flags = APEI_EXEC_INS_ACCESS_REGISTER, + .run = apei_exec_write_register, + }, + [ACPI_ERST_WRITE_REGISTER_VALUE] = { + .flags = APEI_EXEC_INS_ACCESS_REGISTER, + .run = apei_exec_write_register_value, + }, + [ACPI_ERST_NOOP] = { + .flags = 0, + .run = apei_exec_noop, + }, + [ACPI_ERST_LOAD_VAR1] = { + .flags = APEI_EXEC_INS_ACCESS_REGISTER, + .run = erst_exec_load_var1, + }, + [ACPI_ERST_LOAD_VAR2] = { + .flags = APEI_EXEC_INS_ACCESS_REGISTER, + .run = erst_exec_load_var2, + }, + [ACPI_ERST_STORE_VAR1] = { + .flags = APEI_EXEC_INS_ACCESS_REGISTER, + .run = erst_exec_store_var1, + }, + [ACPI_ERST_ADD] = { + .flags = 0, + .run = erst_exec_add, + }, + [ACPI_ERST_SUBTRACT] = { + .flags = 0, + .run = erst_exec_subtract, + }, + [ACPI_ERST_ADD_VALUE] = { + .flags = APEI_EXEC_INS_ACCESS_REGISTER, + .run = erst_exec_add_value, + }, + [ACPI_ERST_SUBTRACT_VALUE] = { + .flags = APEI_EXEC_INS_ACCESS_REGISTER, + .run = erst_exec_subtract_value, + }, + [ACPI_ERST_STALL] = { + .flags = 0, + .run = erst_exec_stall, + }, + [ACPI_ERST_STALL_WHILE_TRUE] = { + .flags = APEI_EXEC_INS_ACCESS_REGISTER, + .run = erst_exec_stall_while_true, + }, + [ACPI_ERST_SKIP_NEXT_IF_TRUE] = { + .flags = APEI_EXEC_INS_ACCESS_REGISTER, + .run = erst_exec_skip_next_instruction_if_true, + }, + [ACPI_ERST_GOTO] = { + .flags = 0, + .run = erst_exec_goto, + }, + [ACPI_ERST_SET_SRC_ADDRESS_BASE] = { + .flags = APEI_EXEC_INS_ACCESS_REGISTER, + .run = erst_exec_set_src_address_base, + }, + [ACPI_ERST_SET_DST_ADDRESS_BASE] = { + .flags = APEI_EXEC_INS_ACCESS_REGISTER, + .run = erst_exec_set_dst_address_base, + }, + [ACPI_ERST_MOVE_DATA] = { + .flags = APEI_EXEC_INS_ACCESS_REGISTER, + .run = erst_exec_move_data, + }, +}; + +static inline void erst_exec_ctx_init(struct apei_exec_context *ctx) +{ + apei_exec_ctx_init(ctx, erst_ins_type, ARRAY_SIZE(erst_ins_type), + ERST_TAB_ENTRY(erst_tab), erst_tab->entries); +} + +static int erst_get_erange(struct erst_erange *range) +{ + struct apei_exec_context ctx; + int rc; + + erst_exec_ctx_init(&ctx); + rc = apei_exec_run(&ctx, ACPI_ERST_GET_ERROR_RANGE); + if (rc) + return rc; + range->base = apei_exec_ctx_get_output(&ctx); + rc = apei_exec_run(&ctx, ACPI_ERST_GET_ERROR_LENGTH); + if (rc) + return rc; + range->size = apei_exec_ctx_get_output(&ctx); + rc = apei_exec_run(&ctx, ACPI_ERST_GET_ERROR_ATTRIBUTES); + if (rc) + return rc; + range->attr = apei_exec_ctx_get_output(&ctx); + + return 0; +} + +static ssize_t __erst_get_record_count(void) +{ + struct apei_exec_context ctx; + int rc; + + erst_exec_ctx_init(&ctx); + rc = apei_exec_run(&ctx, ACPI_ERST_GET_RECORD_COUNT); + if (rc) + return rc; + return apei_exec_ctx_get_output(&ctx); +} + +ssize_t erst_get_record_count(void) +{ + ssize_t count; + unsigned long flags; + + if (erst_disable) + return -ENODEV; + + spin_lock_irqsave(&erst_lock, flags); + count = __erst_get_record_count(); + spin_unlock_irqrestore(&erst_lock, flags); + + return count; +} +EXPORT_SYMBOL_GPL(erst_get_record_count); + +static int __erst_get_next_record_id(u64 *record_id) +{ + struct apei_exec_context ctx; + int rc; + + erst_exec_ctx_init(&ctx); + rc = apei_exec_run(&ctx, ACPI_ERST_GET_RECORD_ID); + if (rc) + return rc; + *record_id = apei_exec_ctx_get_output(&ctx); + + return 0; +} + +/* + * Get the record ID of an existing error record on the persistent + * storage. If there is no error record on the persistent storage, the + * returned record_id is APEI_ERST_INVALID_RECORD_ID. + */ +int erst_get_next_record_id(u64 *record_id) +{ + int rc; + unsigned long flags; + + if (erst_disable) + return -ENODEV; + + spin_lock_irqsave(&erst_lock, flags); + rc = __erst_get_next_record_id(record_id); + spin_unlock_irqrestore(&erst_lock, flags); + + return rc; +} +EXPORT_SYMBOL_GPL(erst_get_next_record_id); + +static int __erst_write_to_storage(u64 offset) +{ + struct apei_exec_context ctx; + u64 timeout = FIRMWARE_TIMEOUT; + u64 val; + int rc; + + erst_exec_ctx_init(&ctx); + rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_WRITE); + if (rc) + return rc; + apei_exec_ctx_set_input(&ctx, offset); + rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_OFFSET); + if (rc) + return rc; + rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_OPERATION); + if (rc) + return rc; + for (;;) { + rc = apei_exec_run(&ctx, ACPI_ERST_CHECK_BUSY_STATUS); + if (rc) + return rc; + val = apei_exec_ctx_get_output(&ctx); + if (!val) + break; + if (erst_timedout(&timeout, SPIN_UNIT)) + return -EIO; + } + rc = apei_exec_run(&ctx, ACPI_ERST_GET_COMMAND_STATUS); + if (rc) + return rc; + val = apei_exec_ctx_get_output(&ctx); + rc = apei_exec_run(&ctx, ACPI_ERST_END); + if (rc) + return rc; + + return erst_errno(val); +} + +static int __erst_read_from_storage(u64 record_id, u64 offset) +{ + struct apei_exec_context ctx; + u64 timeout = FIRMWARE_TIMEOUT; + u64 val; + int rc; + + erst_exec_ctx_init(&ctx); + rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_READ); + if (rc) + return rc; + apei_exec_ctx_set_input(&ctx, offset); + rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_OFFSET); + if (rc) + return rc; + apei_exec_ctx_set_input(&ctx, record_id); + rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_ID); + if (rc) + return rc; + rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_OPERATION); + if (rc) + return rc; + for (;;) { + rc = apei_exec_run(&ctx, ACPI_ERST_CHECK_BUSY_STATUS); + if (rc) + return rc; + val = apei_exec_ctx_get_output(&ctx); + if (!val) + break; + if (erst_timedout(&timeout, SPIN_UNIT)) + return -EIO; + }; + rc = apei_exec_run(&ctx, ACPI_ERST_GET_COMMAND_STATUS); + if (rc) + return rc; + val = apei_exec_ctx_get_output(&ctx); + rc = apei_exec_run(&ctx, ACPI_ERST_END); + if (rc) + return rc; + + return erst_errno(val); +} + +static int __erst_clear_from_storage(u64 record_id) +{ + struct apei_exec_context ctx; + u64 timeout = FIRMWARE_TIMEOUT; + u64 val; + int rc; + + erst_exec_ctx_init(&ctx); + rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_CLEAR); + if (rc) + return rc; + apei_exec_ctx_set_input(&ctx, record_id); + rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_ID); + if (rc) + return rc; + rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_OPERATION); + if (rc) + return rc; + for (;;) { + rc = apei_exec_run(&ctx, ACPI_ERST_CHECK_BUSY_STATUS); + if (rc) + return rc; + val = apei_exec_ctx_get_output(&ctx); + if (!val) + break; + if (erst_timedout(&timeout, SPIN_UNIT)) + return -EIO; + } + rc = apei_exec_run(&ctx, ACPI_ERST_GET_COMMAND_STATUS); + if (rc) + return rc; + val = apei_exec_ctx_get_output(&ctx); + rc = apei_exec_run(&ctx, ACPI_ERST_END); + if (rc) + return rc; + + return erst_errno(val); +} + +/* NVRAM ERST Error Log Address Range is not supported yet */ +static void pr_unimpl_nvram(void) +{ + if (printk_ratelimit()) + pr_warning(ERST_PFX + "NVRAM ERST Log Address Range is not implemented yet\n"); +} + +static int __erst_write_to_nvram(const struct cper_record_header *record) +{ + /* do not print message, because printk is not safe for NMI */ + return -ENOSYS; +} + +static int __erst_read_to_erange_from_nvram(u64 record_id, u64 *offset) +{ + pr_unimpl_nvram(); + return -ENOSYS; +} + +static int __erst_clear_from_nvram(u64 record_id) +{ + pr_unimpl_nvram(); + return -ENOSYS; +} + +int erst_write(const struct cper_record_header *record) +{ + int rc; + unsigned long flags; + struct cper_record_header *rcd_erange; + + if (erst_disable) + return -ENODEV; + + if (memcmp(record->signature, CPER_SIG_RECORD, CPER_SIG_SIZE)) + return -EINVAL; + + if (erst_erange.attr & ERST_RANGE_NVRAM) { + if (!spin_trylock_irqsave(&erst_lock, flags)) + return -EBUSY; + rc = __erst_write_to_nvram(record); + spin_unlock_irqrestore(&erst_lock, flags); + return rc; + } + + if (record->record_length > erst_erange.size) + return -EINVAL; + + if (!spin_trylock_irqsave(&erst_lock, flags)) + return -EBUSY; + memcpy(erst_erange.vaddr, record, record->record_length); + rcd_erange = erst_erange.vaddr; + /* signature for serialization system */ + memcpy(&rcd_erange->persistence_information, "ER", 2); + + rc = __erst_write_to_storage(0); + spin_unlock_irqrestore(&erst_lock, flags); + + return rc; +} +EXPORT_SYMBOL_GPL(erst_write); + +static int __erst_read_to_erange(u64 record_id, u64 *offset) +{ + int rc; + + if (erst_erange.attr & ERST_RANGE_NVRAM) + return __erst_read_to_erange_from_nvram( + record_id, offset); + + rc = __erst_read_from_storage(record_id, 0); + if (rc) + return rc; + *offset = 0; + + return 0; +} + +static ssize_t __erst_read(u64 record_id, struct cper_record_header *record, + size_t buflen) +{ + int rc; + u64 offset, len = 0; + struct cper_record_header *rcd_tmp; + + rc = __erst_read_to_erange(record_id, &offset); + if (rc) + return rc; + rcd_tmp = erst_erange.vaddr + offset; + len = rcd_tmp->record_length; + if (len <= buflen) + memcpy(record, rcd_tmp, len); + + return len; +} + +/* + * If return value > buflen, the buffer size is not big enough, + * else if return value < 0, something goes wrong, + * else everything is OK, and return value is record length + */ +ssize_t erst_read(u64 record_id, struct cper_record_header *record, + size_t buflen) +{ + ssize_t len; + unsigned long flags; + + if (erst_disable) + return -ENODEV; + + spin_lock_irqsave(&erst_lock, flags); + len = __erst_read(record_id, record, buflen); + spin_unlock_irqrestore(&erst_lock, flags); + return len; +} +EXPORT_SYMBOL_GPL(erst_read); + +/* + * If return value > buflen, the buffer size is not big enough, + * else if return value = 0, there is no more record to read, + * else if return value < 0, something goes wrong, + * else everything is OK, and return value is record length + */ +ssize_t erst_read_next(struct cper_record_header *record, size_t buflen) +{ + int rc; + ssize_t len; + unsigned long flags; + u64 record_id; + + if (erst_disable) + return -ENODEV; + + spin_lock_irqsave(&erst_lock, flags); + rc = __erst_get_next_record_id(&record_id); + if (rc) { + spin_unlock_irqrestore(&erst_lock, flags); + return rc; + } + /* no more record */ + if (record_id == APEI_ERST_INVALID_RECORD_ID) { + spin_unlock_irqrestore(&erst_lock, flags); + return 0; + } + + len = __erst_read(record_id, record, buflen); + spin_unlock_irqrestore(&erst_lock, flags); + + return len; +} +EXPORT_SYMBOL_GPL(erst_read_next); + +int erst_clear(u64 record_id) +{ + int rc; + unsigned long flags; + + if (erst_disable) + return -ENODEV; + + spin_lock_irqsave(&erst_lock, flags); + if (erst_erange.attr & ERST_RANGE_NVRAM) + rc = __erst_clear_from_nvram(record_id); + else + rc = __erst_clear_from_storage(record_id); + spin_unlock_irqrestore(&erst_lock, flags); + + return rc; +} +EXPORT_SYMBOL_GPL(erst_clear); + +static int __init setup_erst_disable(char *str) +{ + erst_disable = 1; + return 0; +} + +__setup("erst_disable", setup_erst_disable); + +static int erst_check_table(struct acpi_table_erst *erst_tab) +{ + if (erst_tab->header_length != sizeof(struct acpi_table_erst)) + return -EINVAL; + if (erst_tab->header.length < sizeof(struct acpi_table_erst)) + return -EINVAL; + if (erst_tab->entries != + (erst_tab->header.length - sizeof(struct acpi_table_erst)) / + sizeof(struct acpi_erst_entry)) + return -EINVAL; + + return 0; +} + +static int __init erst_init(void) +{ + int rc = 0; + acpi_status status; + struct apei_exec_context ctx; + struct apei_resources erst_resources; + struct resource *r; + + if (acpi_disabled) + goto err; + + if (erst_disable) { + pr_info(ERST_PFX + "Error Record Serialization Table (ERST) support is disabled.\n"); + goto err; + } + + status = acpi_get_table(ACPI_SIG_ERST, 0, + (struct acpi_table_header **)&erst_tab); + if (status == AE_NOT_FOUND) { + pr_err(ERST_PFX "Table is not found!\n"); + goto err; + } else if (ACPI_FAILURE(status)) { + const char *msg = acpi_format_exception(status); + pr_err(ERST_PFX "Failed to get table, %s\n", msg); + rc = -EINVAL; + goto err; + } + + rc = erst_check_table(erst_tab); + if (rc) { + pr_err(FW_BUG ERST_PFX "ERST table is invalid\n"); + goto err; + } + + apei_resources_init(&erst_resources); + erst_exec_ctx_init(&ctx); + rc = apei_exec_collect_resources(&ctx, &erst_resources); + if (rc) + goto err_fini; + rc = apei_resources_request(&erst_resources, "APEI ERST"); + if (rc) + goto err_fini; + rc = apei_exec_pre_map_gars(&ctx); + if (rc) + goto err_release; + rc = erst_get_erange(&erst_erange); + if (rc) { + if (rc == -ENODEV) + pr_info(ERST_PFX + "The corresponding hardware device or firmware implementation " + "is not available.\n"); + else + pr_err(ERST_PFX + "Failed to get Error Log Address Range.\n"); + goto err_unmap_reg; + } + + r = request_mem_region(erst_erange.base, erst_erange.size, "APEI ERST"); + if (!r) { + pr_err(ERST_PFX + "Can not request iomem region <0x%16llx-0x%16llx> for ERST.\n", + (unsigned long long)erst_erange.base, + (unsigned long long)erst_erange.base + erst_erange.size); + rc = -EIO; + goto err_unmap_reg; + } + rc = -ENOMEM; + erst_erange.vaddr = ioremap_cache(erst_erange.base, + erst_erange.size); + if (!erst_erange.vaddr) + goto err_release_erange; + + pr_info(ERST_PFX + "Error Record Serialization Table (ERST) support is initialized.\n"); + + return 0; + +err_release_erange: + release_mem_region(erst_erange.base, erst_erange.size); +err_unmap_reg: + apei_exec_post_unmap_gars(&ctx); +err_release: + apei_resources_release(&erst_resources); +err_fini: + apei_resources_fini(&erst_resources); +err: + erst_disable = 1; + return rc; +} + +device_initcall(erst_init); diff --git a/include/acpi/apei.h b/include/acpi/apei.h index 631a1ad2d108..b3365025ff8d 100644 --- a/include/acpi/apei.h +++ b/include/acpi/apei.h @@ -5,9 +5,30 @@ #ifndef ACPI_APEI_H #define ACPI_APEI_H +#include +#include +#include + +#define APEI_ERST_INVALID_RECORD_ID 0xffffffffffffffffULL + +#define APEI_ERST_CLEAR_RECORD _IOW('E', 1, u64) +#define APEI_ERST_GET_RECORD_COUNT _IOR('E', 2, u32) + +#ifdef __KERNEL__ + extern int hest_disable; +extern int erst_disable; typedef int (*apei_hest_func_t)(struct acpi_hest_header *hest_hdr, void *data); int apei_hest_parse(apei_hest_func_t func, void *data); +int erst_write(const struct cper_record_header *record); +ssize_t erst_get_record_count(void); +int erst_get_next_record_id(u64 *record_id); +ssize_t erst_read(u64 record_id, struct cper_record_header *record, + size_t buflen); +ssize_t erst_read_next(struct cper_record_header *record, size_t buflen); +int erst_clear(u64 record_id); + +#endif #endif -- cgit v1.2.3 From 6e320ec1d98f9eb93d5b2a5d70e2f40dce923f1b Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Tue, 18 May 2010 14:35:24 +0800 Subject: ACPI, APEI, EINJ injection parameters support Some hardware error injection needs parameters, for example, it is useful to specify memory address and memory address mask for memory errors. Some BIOSes allow parameters to be specified via an unpublished extension. This patch adds support to it. The parameters will be ignored on machines without necessary BIOS support. Signed-off-by: Huang Ying Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- Documentation/acpi/apei/einj.txt | 10 ++++++ drivers/acpi/apei/einj.c | 72 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 77 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/Documentation/acpi/apei/einj.txt b/Documentation/acpi/apei/einj.txt index 838b7f0d5e11..dfab71848dc8 100644 --- a/Documentation/acpi/apei/einj.txt +++ b/Documentation/acpi/apei/einj.txt @@ -45,5 +45,15 @@ directory apei/einj. The following files are provided. injection. Before this, please specify all necessary error parameters. +- param1 + This file is used to set the first error parameter value. Effect of + parameter depends on error_type specified. For memory error, this is + physical memory address. + +- param2 + This file is used to set the second error parameter value. Effect of + parameter depends on error_type specified. For memory error, this is + physical memory address mask. + For more information about EINJ, please refer to ACPI specification version 4.0, section 17.5. diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index 4ccebd8f930a..465c885938ee 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c @@ -7,7 +7,7 @@ * For more information about EINJ, please refer to ACPI Specification * version 4.0, section 17.5. * - * Copyright 2009 Intel Corp. + * Copyright 2009-2010 Intel Corp. * Author: Huang Ying * * This program is free software; you can redistribute it and/or @@ -42,6 +42,20 @@ /* Firmware should respond within 1 miliseconds */ #define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC) +/* + * Some BIOSes allow parameters to the SET_ERROR_TYPE entries in the + * EINJ table through an unpublished extension. Use with caution as + * most will ignore the parameter and make their own choice of address + * for error injection. + */ +struct einj_parameter { + u64 type; + u64 reserved1; + u64 reserved2; + u64 param1; + u64 param2; +}; + #define EINJ_OP_BUSY 0x1 #define EINJ_STATUS_SUCCESS 0x0 #define EINJ_STATUS_FAIL 0x1 @@ -85,6 +99,8 @@ static struct apei_exec_ins_type einj_ins_type[] = { */ static DEFINE_MUTEX(einj_mutex); +static struct einj_parameter *einj_param; + static void einj_exec_ctx_init(struct apei_exec_context *ctx) { apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type), @@ -130,6 +146,26 @@ static int einj_timedout(u64 *t) return 0; } +static u64 einj_get_parameter_address(void) +{ + int i; + u64 paddr = 0; + struct acpi_whea_header *entry; + + entry = EINJ_TAB_ENTRY(einj_tab); + for (i = 0; i < einj_tab->entries; i++) { + if (entry->action == ACPI_EINJ_SET_ERROR_TYPE && + entry->instruction == ACPI_EINJ_WRITE_REGISTER && + entry->register_region.space_id == + ACPI_ADR_SPACE_SYSTEM_MEMORY) + memcpy(&paddr, &entry->register_region.address, + sizeof(paddr)); + entry++; + } + + return paddr; +} + /* do sanity check to trigger table */ static int einj_check_trigger_header(struct acpi_einj_trigger *trigger_tab) { @@ -233,7 +269,7 @@ out: return rc; } -static int __einj_error_inject(u32 type) +static int __einj_error_inject(u32 type, u64 param1, u64 param2) { struct apei_exec_context ctx; u64 val, trigger_paddr, timeout = FIRMWARE_TIMEOUT; @@ -248,6 +284,10 @@ static int __einj_error_inject(u32 type) rc = apei_exec_run(&ctx, ACPI_EINJ_SET_ERROR_TYPE); if (rc) return rc; + if (einj_param) { + writeq(param1, &einj_param->param1); + writeq(param2, &einj_param->param2); + } rc = apei_exec_run(&ctx, ACPI_EINJ_EXECUTE_OPERATION); if (rc) return rc; @@ -281,18 +321,20 @@ static int __einj_error_inject(u32 type) } /* Inject the specified hardware error */ -static int einj_error_inject(u32 type) +static int einj_error_inject(u32 type, u64 param1, u64 param2) { int rc; mutex_lock(&einj_mutex); - rc = __einj_error_inject(type); + rc = __einj_error_inject(type, param1, param2); mutex_unlock(&einj_mutex); return rc; } static u32 error_type; +static u64 error_param1; +static u64 error_param2; static struct dentry *einj_debug_dir; static int available_error_type_show(struct seq_file *m, void *v) @@ -376,7 +418,7 @@ static int error_inject_set(void *data, u64 val) if (!error_type) return -EINVAL; - return einj_error_inject(error_type); + return einj_error_inject(error_type, error_param1, error_param2); } DEFINE_SIMPLE_ATTRIBUTE(error_inject_fops, NULL, @@ -399,6 +441,7 @@ static int einj_check_table(struct acpi_table_einj *einj_tab) static int __init einj_init(void) { int rc; + u64 param_paddr; acpi_status status; struct dentry *fentry; struct apei_exec_context ctx; @@ -436,6 +479,14 @@ static int __init einj_init(void) einj_debug_dir, NULL, &error_type_fops); if (!fentry) goto err_cleanup; + fentry = debugfs_create_x64("param1", S_IRUSR | S_IWUSR, + einj_debug_dir, &error_param1); + if (!fentry) + goto err_cleanup; + fentry = debugfs_create_x64("param2", S_IRUSR | S_IWUSR, + einj_debug_dir, &error_param2); + if (!fentry) + goto err_cleanup; fentry = debugfs_create_file("error_inject", S_IWUSR, einj_debug_dir, NULL, &error_inject_fops); if (!fentry) @@ -452,11 +503,20 @@ static int __init einj_init(void) rc = apei_exec_pre_map_gars(&ctx); if (rc) goto err_release; + param_paddr = einj_get_parameter_address(); + if (param_paddr) { + einj_param = ioremap(param_paddr, sizeof(*einj_param)); + rc = -ENOMEM; + if (!einj_param) + goto err_unmap; + } pr_info(EINJ_PFX "Error INJection is initialized.\n"); return 0; +err_unmap: + apei_exec_post_unmap_gars(&ctx); err_release: apei_resources_release(&einj_resources); err_fini: @@ -471,6 +531,8 @@ static void __exit einj_exit(void) { struct apei_exec_context ctx; + if (einj_param) + iounmap(einj_param); einj_exec_ctx_init(&ctx); apei_exec_post_unmap_gars(&ctx); apei_resources_release(&einj_resources); -- cgit v1.2.3 From aeb834d95e771499cb0492d127aec3246d1595c8 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 27 Apr 2010 14:06:04 -0700 Subject: drivers/acpi: use kasprintf kasprintf combines kmalloc and sprintf, and takes care of the size calculation itself. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression a,flag; expression list args; statement S; @@ a = - \(kmalloc\|kzalloc\)(...,flag) + kasprintf(flag,args) <... when != a if (a == NULL || ...) S ...> - sprintf(a,args); // [akpm@linux-foundation.org: don't change handling of `count'] Signed-off-by: Julia Lawall Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/video.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index a0c93b321482..1a6b305006ef 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -1007,11 +1007,11 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) result = acpi_video_init_brightness(device); if (result) return; - name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); + name = kasprintf(GFP_KERNEL, "acpi_video%d", count); if (!name) return; + count++; - sprintf(name, "acpi_video%d", count++); memset(&props, 0, sizeof(struct backlight_properties)); props.max_brightness = device->brightness->count - 3; device->backlight = backlight_device_register(name, NULL, device, @@ -1067,10 +1067,10 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) if (device->cap._DCS && device->cap._DSS) { static int count; char *name; - name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); + name = kasprintf(GFP_KERNEL, "acpi_video%d", count); if (!name) return; - sprintf(name, "acpi_video%d", count++); + count++; device->output_dev = video_output_register(name, NULL, device, &acpi_output_properties); kfree(name); -- cgit v1.2.3 From d6bd535d88429b4804d6d917ab4f586306f9a855 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 15 May 2010 23:16:21 +0200 Subject: ACPI: EC: Use kmemdup Use kmemdup when some other buffer is immediately copied into the allocated region. A simplified version of the semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression from,to,size,flag; statement S; @@ - to = \(kmalloc\|kzalloc\)(size,flag); + to = kmemdup(from,size,flag); if (to==NULL || ...) S - memcpy(to, from, size); // Signed-off-by: Julia Lawall Acked-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/ec.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index f2234db85da0..e61d4f8e62a5 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -1027,10 +1027,9 @@ int __init acpi_ec_ecdt_probe(void) /* Don't trust ECDT, which comes from ASUSTek */ if (!EC_FLAGS_VALIDATE_ECDT) goto install; - saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); + saved_ec = kmemdup(boot_ec, sizeof(struct acpi_ec), GFP_KERNEL); if (!saved_ec) return -ENOMEM; - memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec)); /* fall through */ } -- cgit v1.2.3 From eeb4bcb4771679d7b3446c0293334faee11b090a Mon Sep 17 00:00:00 2001 From: Kamal Mostafa Date: Sat, 1 May 2010 12:09:49 -0700 Subject: ACPI: video: fix acpi_backlight=video Make "acpi_backlight=video" param enable ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO as intended, instead of incorrectly enabling video output switching. BugLink: http://bugs.launchpad.net/bugs/573120 Signed-off-by: Kamal Mostafa Acked-by: Zhang Rui Cc: Bjorn Helgaas Cc: Jiri Kosina Cc: Acked-by: Thomas Renninger Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/video_detect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index fc2f26b9b407..c5fef01b3c95 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -250,7 +250,7 @@ static int __init acpi_backlight(char *str) ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR; if (!strcmp("video", str)) acpi_video_support |= - ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO; + ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO; } return 1; } -- cgit v1.2.3 From e954bc91bdd4bb08b8325478c5004b24a23a3522 Mon Sep 17 00:00:00 2001 From: Matt Mackall Date: Thu, 20 May 2010 19:55:01 +1000 Subject: random: simplify fips mode Rather than dynamically allocate 10 bytes, move it to static allocation. This saves space and avoids the need for error checking. Signed-off-by: Matt Mackall Signed-off-by: Herbert Xu --- drivers/char/random.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/char/random.c b/drivers/char/random.c index 2fd3d39995d5..8d85587b6d4f 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -257,6 +257,7 @@ #define INPUT_POOL_WORDS 128 #define OUTPUT_POOL_WORDS 32 #define SEC_XFER_SIZE 512 +#define EXTRACT_SIZE 10 /* * The minimum number of bits of entropy before we wake up a read on @@ -414,7 +415,7 @@ struct entropy_store { unsigned add_ptr; int entropy_count; int input_rotate; - __u8 *last_data; + __u8 last_data[EXTRACT_SIZE]; }; static __u32 input_pool_data[INPUT_POOL_WORDS]; @@ -714,8 +715,6 @@ void add_disk_randomness(struct gendisk *disk) } #endif -#define EXTRACT_SIZE 10 - /********************************************************************* * * Entropy extraction routines @@ -862,7 +861,7 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, while (nbytes) { extract_buf(r, tmp); - if (r->last_data) { + if (fips_enabled) { spin_lock_irqsave(&r->lock, flags); if (!memcmp(tmp, r->last_data, EXTRACT_SIZE)) panic("Hardware RNG duplicated output!\n"); @@ -951,9 +950,6 @@ static void init_std_data(struct entropy_store *r) now = ktime_get_real(); mix_pool_bytes(r, &now, sizeof(now)); mix_pool_bytes(r, utsname(), sizeof(*(utsname()))); - /* Enable continuous test in fips mode */ - if (fips_enabled) - r->last_data = kmalloc(EXTRACT_SIZE, GFP_KERNEL); } static int rand_initialize(void) -- cgit v1.2.3 From 6c75dd0f965b7b3480d0e0e9b8d9747988dfe815 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 13 May 2010 22:06:20 +0200 Subject: drivers/platform/x86: Use kzalloc Use kzalloc rather than the combination of kmalloc and memset. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression x,size,flags; statement S; @@ -x = kmalloc(size,flags); +x = kzalloc(size,flags); if (x == NULL) S -memset(x, 0, size); // Signed-off-by: Julia Lawall --- drivers/platform/x86/fujitsu-laptop.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index 47b4fd75aa34..e325aeb37d2e 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -1090,10 +1090,9 @@ static int __init fujitsu_init(void) if (acpi_disabled) return -ENODEV; - fujitsu = kmalloc(sizeof(struct fujitsu_t), GFP_KERNEL); + fujitsu = kzalloc(sizeof(struct fujitsu_t), GFP_KERNEL); if (!fujitsu) return -ENOMEM; - memset(fujitsu, 0, sizeof(struct fujitsu_t)); fujitsu->keycode1 = KEY_PROG1; fujitsu->keycode2 = KEY_PROG2; fujitsu->keycode3 = KEY_PROG3; @@ -1150,12 +1149,11 @@ static int __init fujitsu_init(void) /* Register hotkey driver */ - fujitsu_hotkey = kmalloc(sizeof(struct fujitsu_hotkey_t), GFP_KERNEL); + fujitsu_hotkey = kzalloc(sizeof(struct fujitsu_hotkey_t), GFP_KERNEL); if (!fujitsu_hotkey) { ret = -ENOMEM; goto fail_hotkey; } - memset(fujitsu_hotkey, 0, sizeof(struct fujitsu_hotkey_t)); result = acpi_bus_register_driver(&acpi_fujitsu_hotkey_driver); if (result < 0) { -- cgit v1.2.3 From 2c6719a3ef2f7da59a622ba1176ad41d553f8f43 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 15 May 2010 23:22:18 +0200 Subject: drivers/platform/x86: Use kmemdup Use kmemdup when some other buffer is immediately copied into the allocated region. A simplified version of the semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression from,to,size,flag; statement S; @@ - to = \(kmalloc\|kzalloc\)(size,flag); + to = kmemdup(from,size,flag); if (to==NULL || ...) S - memcpy(to, from, size); // Signed-off-by: Julia Lawall --- drivers/platform/x86/wmi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 39ec5b6c2e3a..17df134a6f03 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -756,12 +756,10 @@ static __init acpi_status parse_wdg(acpi_handle handle) total = obj->buffer.length / sizeof(struct guid_block); - gblock = kzalloc(obj->buffer.length, GFP_KERNEL); + gblock = kmemdup(obj->buffer.pointer, obj->buffer.length, GFP_KERNEL); if (!gblock) return AE_NO_MEMORY; - memcpy(gblock, obj->buffer.pointer, obj->buffer.length); - for (i = 0; i < total; i++) { /* Some WMI devices, like those for nVidia hooks, have a -- cgit v1.2.3 From d0a4aa2b2603d85353450a30a6a3ea2010b041da Mon Sep 17 00:00:00 2001 From: "Lee, Chun-Yi" Date: Wed, 12 May 2010 09:58:07 -0700 Subject: msi-laptop: Add N014 N051 dmi information to scm models table Add new MSI netbook N014 and N051 dmi information to scm models table. Signed-off-by: Lee, Chun-Yi Signed-off-by: Greg Kroah-Hartman --- drivers/platform/x86/msi-laptop.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'drivers') diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index 996223a7c009..bcd9c0d23b39 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c @@ -469,6 +469,26 @@ static struct dmi_system_id __initdata msi_dmi_table[] = { }, .callback = dmi_check_cb }, + { + .ident = "MSI N051", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "MICRO-STAR INTERNATIONAL CO., LTD"), + DMI_MATCH(DMI_PRODUCT_NAME, "MS-N051"), + DMI_MATCH(DMI_CHASSIS_VENDOR, + "MICRO-STAR INTERNATIONAL CO., LTD") + }, + .callback = dmi_check_cb + }, + { + .ident = "MSI N014", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "MICRO-STAR INTERNATIONAL CO., LTD"), + DMI_MATCH(DMI_PRODUCT_NAME, "MS-N014"), + }, + .callback = dmi_check_cb + }, { } }; @@ -788,3 +808,5 @@ MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1058:pvr0581:rvnMSI:rnMS-105 MODULE_ALIAS("dmi:*:svnMicro-StarInternational:pnMS-1412:*:rvnMSI:rnMS-1412:*:cvnMICRO-STARINT'LCO.,LTD:ct10:*"); MODULE_ALIAS("dmi:*:svnNOTEBOOK:pnSAM2000:pvr0131*:cvnMICRO-STARINT'LCO.,LTD:ct10:*"); MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N034:*"); +MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N051:*"); +MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N014:*"); -- cgit v1.2.3 From 1f27e17bfa2ad34a2dbb61cd097d9ecf506639df Mon Sep 17 00:00:00 2001 From: "Lee, Chun-Yi" Date: Wed, 12 May 2010 09:58:08 -0700 Subject: msi-laptop: Add MSI CR620 notebook dmi information to scm models table Add new MSI notebook CR620 dmi information to scm models table. Signed-off-by: Lee, Chun-Yi Signed-off-by: Greg Kroah-Hartman --- drivers/platform/x86/msi-laptop.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index bcd9c0d23b39..45197d75db91 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c @@ -489,6 +489,15 @@ static struct dmi_system_id __initdata msi_dmi_table[] = { }, .callback = dmi_check_cb }, + { + .ident = "MSI CR620", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "Micro-Star International"), + DMI_MATCH(DMI_PRODUCT_NAME, "CR620"), + }, + .callback = dmi_check_cb + }, { } }; @@ -810,3 +819,4 @@ MODULE_ALIAS("dmi:*:svnNOTEBOOK:pnSAM2000:pvr0131*:cvnMICRO-STARINT'LCO.,LTD:ct1 MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N034:*"); MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N051:*"); MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N014:*"); +MODULE_ALIAS("dmi:*:svnMicro-StarInternational*:pnCR620:*"); -- cgit v1.2.3 From 3bb970214fce6495573843e4b7b786f8ea94cd70 Mon Sep 17 00:00:00 2001 From: "Lee, Chun-Yi" Date: Wed, 12 May 2010 09:58:09 -0700 Subject: msi-laptop: Set rfkill init state when msi-laptop intiial Setup Wlan/Bluetooth/3G rfkill initial state to sync with the hardware state from EC 0x2e address. Signed-off-by: Lee, Chun-Yi Signed-off-by: Greg Kroah-Hartman --- drivers/platform/x86/msi-laptop.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers') diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index 45197d75db91..34bec2e26843 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c @@ -581,11 +581,31 @@ static void rfkill_cleanup(void) } } +static void msi_init_rfkill(struct work_struct *ignored) +{ + if (rfk_wlan) { + rfkill_set_sw_state(rfk_wlan, !wlan_s); + rfkill_wlan_set(NULL, !wlan_s); + } + if (rfk_bluetooth) { + rfkill_set_sw_state(rfk_bluetooth, !bluetooth_s); + rfkill_bluetooth_set(NULL, !bluetooth_s); + } + if (rfk_threeg) { + rfkill_set_sw_state(rfk_threeg, !threeg_s); + rfkill_threeg_set(NULL, !threeg_s); + } +} +static DECLARE_DELAYED_WORK(msi_rfkill_init, msi_init_rfkill); + static int rfkill_init(struct platform_device *sdev) { /* add rfkill */ int retval; + /* keep the hardware wireless state */ + get_wireless_state_ec_standard(); + rfk_bluetooth = rfkill_alloc("msi-bluetooth", &sdev->dev, RFKILL_TYPE_BLUETOOTH, &rfkill_bluetooth_ops, NULL); @@ -619,6 +639,10 @@ static int rfkill_init(struct platform_device *sdev) goto err_threeg; } + /* schedule to run rfkill state initial */ + schedule_delayed_work(&msi_rfkill_init, + round_jiffies_relative(1 * HZ)); + return 0; err_threeg: -- cgit v1.2.3 From 339e75329a447363658d08833bf9f98909f419cd Mon Sep 17 00:00:00 2001 From: "Lee, Chun-Yi" Date: Wed, 12 May 2010 09:58:10 -0700 Subject: msi-laptop: Add i8042 filter to sync sw state with BIOS when function key pressed There have some MSI netbook change devices state by EC when user press wlan/bluetooth/wwan function keys. So, add a i8042 filter to sync sw state with BIOS when function keys pressed. Signed-off-by: Lee, Chun-Yi Signed-off-by: Greg Kroah-Hartman --- drivers/platform/x86/msi-laptop.c | 59 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index 34bec2e26843..b08a108c9776 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c @@ -59,6 +59,7 @@ #include #include #include +#include #define MSI_DRIVER_VERSION "0.5" @@ -581,6 +582,46 @@ static void rfkill_cleanup(void) } } +static void msi_update_rfkill(struct work_struct *ignored) +{ + get_wireless_state_ec_standard(); + + if (rfk_wlan) + rfkill_set_sw_state(rfk_wlan, !wlan_s); + if (rfk_bluetooth) + rfkill_set_sw_state(rfk_bluetooth, !bluetooth_s); + if (rfk_threeg) + rfkill_set_sw_state(rfk_threeg, !threeg_s); +} +static DECLARE_DELAYED_WORK(msi_rfkill_work, msi_update_rfkill); + +static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str, + struct serio *port) +{ + static bool extended; + + if (str & 0x20) + return false; + + /* 0x54 wwan, 0x62 bluetooth, 0x76 wlan*/ + if (unlikely(data == 0xe0)) { + extended = true; + return false; + } else if (unlikely(extended)) { + switch (data) { + case 0x54: + case 0x62: + case 0x76: + schedule_delayed_work(&msi_rfkill_work, + round_jiffies_relative(0.5 * HZ)); + break; + } + extended = false; + } + + return false; +} + static void msi_init_rfkill(struct work_struct *ignored) { if (rfk_wlan) { @@ -706,9 +747,24 @@ static int load_scm_model_init(struct platform_device *sdev) /* initial rfkill */ result = rfkill_init(sdev); if (result < 0) - return result; + goto fail_rfkill; + + result = i8042_install_filter(msi_laptop_i8042_filter); + if (result) { + printk(KERN_ERR + "msi-laptop: Unable to install key filter\n"); + goto fail_filter; + } return 0; + +fail_filter: + rfkill_cleanup(); + +fail_rfkill: + + return result; + } static int __init msi_init(void) @@ -819,6 +875,7 @@ static void __exit msi_cleanup(void) platform_driver_unregister(&msipf_driver); backlight_device_unregister(msibl_device); + i8042_remove_filter(msi_laptop_i8042_filter); rfkill_cleanup(); /* Enable automatic brightness control again */ -- cgit v1.2.3 From 1ac34072bda53e889ac1c5a73ea59f42a769485a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 12 May 2010 12:03:00 -0700 Subject: msi-laptop: fix up some coding style issues found by checkpatch Cc: Lee, Chun-Yi Signed-off-by: Greg Kroah-Hartman --- drivers/platform/x86/msi-laptop.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index b08a108c9776..5822d0ac68d2 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c @@ -119,7 +119,8 @@ static int set_lcd_level(int level) buf[0] = 0x80; buf[1] = (u8) (level*31); - return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, buf, sizeof(buf), NULL, 0, 1); + return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, buf, sizeof(buf), + NULL, 0, 1); } static int get_lcd_level(void) @@ -127,7 +128,8 @@ static int get_lcd_level(void) u8 wdata = 0, rdata; int result; - result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1, 1); + result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, + &rdata, 1, 1); if (result < 0) return result; @@ -139,7 +141,8 @@ static int get_auto_brightness(void) u8 wdata = 4, rdata; int result; - result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1, 1); + result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, + &rdata, 1, 1); if (result < 0) return result; @@ -153,14 +156,16 @@ static int set_auto_brightness(int enable) wdata[0] = 4; - result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 1, &rdata, 1, 1); + result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 1, + &rdata, 1, 1); if (result < 0) return result; wdata[0] = 0x84; wdata[1] = (rdata & 0xF7) | (enable ? 8 : 0); - return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, NULL, 0, 1); + return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, + NULL, 0, 1); } static ssize_t set_device_state(const char *buf, size_t count, u8 mask) @@ -255,7 +260,7 @@ static int bl_update_status(struct backlight_device *b) return set_lcd_level(b->props.brightness); } -static struct backlight_ops msibl_ops = { +static const struct backlight_ops msibl_ops = { .get_brightness = bl_get_brightness, .update_status = bl_update_status, }; @@ -354,7 +359,8 @@ static ssize_t store_lcd_level(struct device *dev, int level, ret; - if (sscanf(buf, "%i", &level) != 1 || (level < 0 || level >= MSI_LCD_LEVEL_MAX)) + if (sscanf(buf, "%i", &level) != 1 || + (level < 0 || level >= MSI_LCD_LEVEL_MAX)) return -EINVAL; ret = set_lcd_level(level); @@ -394,7 +400,8 @@ static ssize_t store_auto_brightness(struct device *dev, } static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level); -static DEVICE_ATTR(auto_brightness, 0644, show_auto_brightness, store_auto_brightness); +static DEVICE_ATTR(auto_brightness, 0644, show_auto_brightness, + store_auto_brightness); static DEVICE_ATTR(bluetooth, 0444, show_bluetooth, NULL); static DEVICE_ATTR(wlan, 0444, show_wlan, NULL); static DEVICE_ATTR(threeg, 0444, show_threeg, NULL); @@ -425,8 +432,9 @@ static struct platform_device *msipf_device; static int dmi_check_cb(const struct dmi_system_id *id) { - printk("msi-laptop: Identified laptop model '%s'.\n", id->ident); - return 0; + printk(KERN_INFO "msi-laptop: Identified laptop model '%s'.\n", + id->ident); + return 0; } static struct dmi_system_id __initdata msi_dmi_table[] = { @@ -436,7 +444,8 @@ static struct dmi_system_id __initdata msi_dmi_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD"), DMI_MATCH(DMI_PRODUCT_NAME, "MS-1013"), DMI_MATCH(DMI_PRODUCT_VERSION, "0131"), - DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT'L CO.,LTD") + DMI_MATCH(DMI_CHASSIS_VENDOR, + "MICRO-STAR INT'L CO.,LTD") }, .callback = dmi_check_cb }, @@ -466,7 +475,8 @@ static struct dmi_system_id __initdata msi_dmi_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "NOTEBOOK"), DMI_MATCH(DMI_PRODUCT_NAME, "SAM2000"), DMI_MATCH(DMI_PRODUCT_VERSION, "0131"), - DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT'L CO.,LTD") + DMI_MATCH(DMI_CHASSIS_VENDOR, + "MICRO-STAR INT'L CO.,LTD") }, .callback = dmi_check_cb }, @@ -823,7 +833,8 @@ static int __init msi_init(void) goto fail_platform_device1; } - ret = sysfs_create_group(&msipf_device->dev.kobj, &msipf_attribute_group); + ret = sysfs_create_group(&msipf_device->dev.kobj, + &msipf_attribute_group); if (ret) goto fail_platform_device2; -- cgit v1.2.3 From 7ab52521f2d850e922f33e5586a47e6c83ec6f11 Mon Sep 17 00:00:00 2001 From: "Lee, Chun-Yi" Date: Sat, 15 May 2010 06:18:54 +0800 Subject: Clean up all objects used by scm model when driver initial fail or exit Clean up i8042 filter, rfkill and cancel delayed work when msi-laptop driver initial fail or exit on MSI scm model. Signed-off-by: Lee, Chun-Yi --- drivers/platform/x86/msi-laptop.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index 5822d0ac68d2..704b5faac599 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c @@ -859,6 +859,11 @@ static int __init msi_init(void) fail_platform_device2: + if (load_scm_model) { + i8042_remove_filter(msi_laptop_i8042_filter); + cancel_delayed_work_sync(&msi_rfkill_work); + rfkill_cleanup(); + } platform_device_del(msipf_device); fail_platform_device1: @@ -878,6 +883,11 @@ fail_backlight: static void __exit msi_cleanup(void) { + if (load_scm_model) { + i8042_remove_filter(msi_laptop_i8042_filter); + cancel_delayed_work_sync(&msi_rfkill_work); + rfkill_cleanup(); + } sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group); if (!old_ec_model && threeg_exists) @@ -886,9 +896,6 @@ static void __exit msi_cleanup(void) platform_driver_unregister(&msipf_driver); backlight_device_unregister(msibl_device); - i8042_remove_filter(msi_laptop_i8042_filter); - rfkill_cleanup(); - /* Enable automatic brightness control again */ if (auto_brightness != 2) set_auto_brightness(1); -- cgit v1.2.3 From fc3155b2c6419a442c6f8b34a3bf31f8efe0fe33 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Mon, 3 May 2010 15:30:15 +0200 Subject: X86 platform wmi: Introduce debug param to log all WMI events To give people easily an idea what could be WMI driven on their system. Introduces: wmi.debug=[01] Tested on an acer: ACPI: WMI: DEBUG Event INTEGER_TYPE - 65535 Situation where a driver registers for specific event and debug handler gets overridden and set again if the registering driver gets unloaded again is untested, but should work. Signed-off-by: Thomas Renninger CC: platform-driver-x86@vger.kernel.org CC: mjg59@srcf.ucam.org CC: corentin.chary@gmail.com Signed-off-by: Carlos Corbacho Signed-off-by: Matthew Garrett --- drivers/platform/x86/wmi.c | 58 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 17df134a6f03..e820f4cddb61 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -81,6 +81,11 @@ static struct wmi_block wmi_blocks; #define ACPI_WMI_STRING 0x4 /* GUID takes & returns a string */ #define ACPI_WMI_EVENT 0x8 /* GUID is an event */ +static int debug_event; +module_param(debug_event, bool, 0444); +MODULE_PARM_DESC(debug_event, + "Log WMI Events [0/1]"); + static int acpi_wmi_remove(struct acpi_device *device, int type); static int acpi_wmi_add(struct acpi_device *device); static void acpi_wmi_notify(struct acpi_device *device, u32 event); @@ -477,6 +482,37 @@ const struct acpi_buffer *in) } EXPORT_SYMBOL_GPL(wmi_set_block); +static void wmi_notify_debug(u32 value, void *context) +{ + struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *obj; + + wmi_get_event_data(value, &response); + + obj = (union acpi_object *)response.pointer; + + if (!obj) + return; + + printk(KERN_INFO PREFIX "DEBUG Event "); + switch(obj->type) { + case ACPI_TYPE_BUFFER: + printk("BUFFER_TYPE - length %d\n", obj->buffer.length); + break; + case ACPI_TYPE_STRING: + printk("STRING_TYPE - %s\n", obj->string.pointer); + break; + case ACPI_TYPE_INTEGER: + printk("INTEGER_TYPE - %llu\n", obj->integer.value); + break; + case ACPI_TYPE_PACKAGE: + printk("PACKAGE_TYPE - %d elements\n", obj->package.count); + break; + default: + printk("object type 0x%X\n", obj->type); + } +} + /** * wmi_install_notify_handler - Register handler for WMI events * @handler: Function to handle notifications @@ -496,7 +532,7 @@ wmi_notify_handler handler, void *data) if (!find_guid(guid, &block)) return AE_NOT_EXIST; - if (block->handler) + if (block->handler && block->handler != wmi_notify_debug) return AE_ALREADY_ACQUIRED; block->handler = handler; @@ -516,7 +552,7 @@ EXPORT_SYMBOL_GPL(wmi_install_notify_handler); acpi_status wmi_remove_notify_handler(const char *guid) { struct wmi_block *block; - acpi_status status; + acpi_status status = AE_OK; if (!guid) return AE_BAD_PARAMETER; @@ -524,14 +560,16 @@ acpi_status wmi_remove_notify_handler(const char *guid) if (!find_guid(guid, &block)) return AE_NOT_EXIST; - if (!block->handler) + if (!block->handler || block->handler == wmi_notify_debug) return AE_NULL_ENTRY; - status = wmi_method_enable(block, 0); - - block->handler = NULL; - block->handler_data = NULL; - + if (debug_event) { + block->handler = wmi_notify_debug; + } else { + status = wmi_method_enable(block, 0); + block->handler = NULL; + block->handler_data = NULL; + } return status; } EXPORT_SYMBOL_GPL(wmi_remove_notify_handler); @@ -780,6 +818,10 @@ static __init acpi_status parse_wdg(acpi_handle handle) wblock->gblock = gblock[i]; wblock->handle = handle; + if (debug_event) { + wblock->handler = wmi_notify_debug; + status = wmi_method_enable(wblock, 1); + } list_add_tail(&wblock->list, &wmi_blocks.list); } -- cgit v1.2.3 From 7715348cbe28da80fd5372fd68748e852a9d8468 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Mon, 3 May 2010 15:30:16 +0200 Subject: X86 platform wmi: Also log GUID string when an event happens and debug is set Output in log with debug=1: ACPI: WMI: DEBUG Event INTEGER_TYPE - 65535 ACPI: WMI: DEBUG Event GUID: CC1A61AC-4256-41A3-B9E0-05A445ADE2F5 Signed-off-by: Thomas Renninger CC: platform-driver-x86@vger.kernel.org CC: mjg59@srcf.ucam.org CC: corentin.chary@gmail.com Signed-off-by: Carlos Corbacho Signed-off-by: Matthew Garrett --- drivers/platform/x86/wmi.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index e820f4cddb61..f16768db4468 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -880,6 +880,7 @@ static void acpi_wmi_notify(struct acpi_device *device, u32 event) struct guid_block *block; struct wmi_block *wblock; struct list_head *p; + char guid_string[37]; list_for_each(p, &wmi_blocks.list) { wblock = list_entry(p, struct wmi_block, list); @@ -889,6 +890,11 @@ static void acpi_wmi_notify(struct acpi_device *device, u32 event) (block->notify_id == event)) { if (wblock->handler) wblock->handler(event, wblock->handler_data); + if (debug_event) { + wmi_gtoa(wblock->gblock.guid, guid_string); + printk(KERN_INFO PREFIX "DEBUG Event GUID:" + " %s\n", guid_string); + } acpi_bus_generate_netlink_event( device->pnp.device_class, dev_name(&device->dev), -- cgit v1.2.3 From a929aae0e0a91d89b60774316ede6c1e2e10dc4e Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Mon, 3 May 2010 15:30:17 +0200 Subject: X86 platfrom wmi: Add debug facility to dump WMI data in a readable way Signed-off-by: Thomas Renninger CC: platform-driver-x86@vger.kernel.org CC: mjg59@srcf.ucam.org CC: corentin.chary@gmail.com Signed-off-by: Carlos Corbacho Signed-off-by: Matthew Garrett --- drivers/platform/x86/wmi.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'drivers') diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index f16768db4468..e4eaa14ed987 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -86,6 +86,11 @@ module_param(debug_event, bool, 0444); MODULE_PARM_DESC(debug_event, "Log WMI Events [0/1]"); +static int debug_dump_wdg; +module_param(debug_dump_wdg, bool, 0444); +MODULE_PARM_DESC(debug_dump_wdg, + "Dump available WMI interfaces [0/1]"); + static int acpi_wmi_remove(struct acpi_device *device, int type); static int acpi_wmi_add(struct acpi_device *device); static void acpi_wmi_notify(struct acpi_device *device, u32 event); @@ -482,6 +487,33 @@ const struct acpi_buffer *in) } EXPORT_SYMBOL_GPL(wmi_set_block); +static void wmi_dump_wdg(struct guid_block *g) +{ + char guid_string[37]; + + wmi_gtoa(g->guid, guid_string); + printk(KERN_INFO PREFIX "%s:\n", guid_string); + printk(KERN_INFO PREFIX "\tobject_id: %c%c\n", + g->object_id[0], g->object_id[1]); + printk(KERN_INFO PREFIX "\tnotify_id: %02X\n", g->notify_id); + printk(KERN_INFO PREFIX "\treserved: %02X\n", g->reserved); + printk(KERN_INFO PREFIX "\tinstance_count: %d\n", g->instance_count); + printk(KERN_INFO PREFIX "\tflags: %#x", g->flags); + if (g->flags) { + printk(" "); + if (g->flags & ACPI_WMI_EXPENSIVE) + printk("ACPI_WMI_EXPENSIVE "); + if (g->flags & ACPI_WMI_METHOD) + printk("ACPI_WMI_METHOD "); + if (g->flags & ACPI_WMI_STRING) + printk("ACPI_WMI_STRING "); + if (g->flags & ACPI_WMI_EVENT) + printk("ACPI_WMI_EVENT "); + } + printk("\n"); + +} + static void wmi_notify_debug(u32 value, void *context) { struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; @@ -812,6 +844,9 @@ static __init acpi_status parse_wdg(acpi_handle handle) guid_string); continue; } + if (debug_dump_wdg) + wmi_dump_wdg(&gblock[i]); + wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL); if (!wblock) return AE_NO_MEMORY; -- cgit v1.2.3 From b7670ed6509f322713bbd96eed0301c322f2ae02 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 19 May 2010 12:37:01 +0200 Subject: drivers/platform/x86/eeepc-wmi.c: fix build warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/platform/x86/eeepc-wmi.c: In function ‘eeepc_wmi_notify’: drivers/platform/x86/eeepc-wmi.c:209: warning: ‘new’ may be used uninitialized in this function drivers/platform/x86/eeepc-wmi.c:209: note: ‘new’ was declared here Signed-off-by: Daniel Mack Cc: Matthew Garrett Cc: Yong Wang Cc: Corentin Chary Cc: Dmitry Torokhov Cc: Tejun Heo Cc: platform-driver-x86@vger.kernel.org Acked-By: Corentin Chary Signed-off-by: Matthew Garrett --- drivers/platform/x86/eeepc-wmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c index b227eb469f49..9dc50fbf3d0b 100644 --- a/drivers/platform/x86/eeepc-wmi.c +++ b/drivers/platform/x86/eeepc-wmi.c @@ -206,7 +206,7 @@ static int eeepc_wmi_backlight_notify(struct eeepc_wmi *eeepc, int code) { struct backlight_device *bd = eeepc->backlight_device; int old = bd->props.brightness; - int new; + int new = old; if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX) new = code - NOTIFY_BRNUP_MIN + 1; -- cgit v1.2.3 From 785cfc0324b9321efb85b0935af2b474d615daa1 Mon Sep 17 00:00:00 2001 From: "Lee, Chun-Yi" Date: Wed, 19 May 2010 20:03:05 +0800 Subject: Move N014, N051 and CR620 dmi information to load scm dmi table Found the N014, N051 and CR620 are must the same with N034 there are load scm serial model. So, this patch move N014, N051 and CR620 dmi information to right dmi table: msi_load_scm_models_dmi_table[] Signed-off-by: Lee, Chun-Yi --- drivers/platform/x86/msi-laptop.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index 704b5faac599..afd762b58ad9 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c @@ -480,6 +480,21 @@ static struct dmi_system_id __initdata msi_dmi_table[] = { }, .callback = dmi_check_cb }, + { } +}; + +static struct dmi_system_id __initdata msi_load_scm_models_dmi_table[] = { + { + .ident = "MSI N034", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, + "MICRO-STAR INTERNATIONAL CO., LTD"), + DMI_MATCH(DMI_PRODUCT_NAME, "MS-N034"), + DMI_MATCH(DMI_CHASSIS_VENDOR, + "MICRO-STAR INTERNATIONAL CO., LTD") + }, + .callback = dmi_check_cb + }, { .ident = "MSI N051", .matches = { @@ -512,21 +527,6 @@ static struct dmi_system_id __initdata msi_dmi_table[] = { { } }; -static struct dmi_system_id __initdata msi_load_scm_models_dmi_table[] = { - { - .ident = "MSI N034", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, - "MICRO-STAR INTERNATIONAL CO., LTD"), - DMI_MATCH(DMI_PRODUCT_NAME, "MS-N034"), - DMI_MATCH(DMI_CHASSIS_VENDOR, - "MICRO-STAR INTERNATIONAL CO., LTD") - }, - .callback = dmi_check_cb - }, - { } -}; - static int rfkill_bluetooth_set(void *data, bool blocked) { /* Do something with blocked...*/ -- cgit v1.2.3 From 3a24934f065d23145f1c9c70da9f630c7a37795f Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Thu, 20 May 2010 12:27:58 -0700 Subject: wimax/i2400m: fix bad race condition check in RX path The i2400m->rx_roq data structure is protected against race conditions with a reference count (i2400m->rx_roq_refcount); the pointer can be read-referenced under the i2400m->rx_lock spinlock. The code in i2400m_rx_edata() wasn't properly following access protocol, performing an invalid check on i2400m->rx_roq (which is cleared to NULL when the refcount drops to zero). As such, it was missing to detect when the data structure is no longer valid and oopsing with a NULL pointer dereference. This commit fixes said check by verifying, under the rx_lock spinlock, that i2400m->rx_roq is non-NULL and then increasing the reference count before dropping the spinlock. Signed-off-by: Inaky Perez-Gonzalez --- drivers/net/wimax/i2400m/rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c index c835ae8b89ce..6cd12d64fc7a 100644 --- a/drivers/net/wimax/i2400m/rx.c +++ b/drivers/net/wimax/i2400m/rx.c @@ -1033,12 +1033,12 @@ void i2400m_rx_edata(struct i2400m *i2400m, struct sk_buff *skb_rx, ro_sn = (reorder >> I2400M_RO_SN_SHIFT) & I2400M_RO_SN; spin_lock_irqsave(&i2400m->rx_lock, flags); - roq = &i2400m->rx_roq[ro_cin]; - if (roq == NULL) { + if (i2400m->rx_roq == NULL) { kfree_skb(skb); /* rx_roq is already destroyed */ spin_unlock_irqrestore(&i2400m->rx_lock, flags); goto error; } + roq = &i2400m->rx_roq[ro_cin]; kref_get(&i2400m->rx_roq_refcount); spin_unlock_irqrestore(&i2400m->rx_lock, flags); -- cgit v1.2.3 From 1944cc894fd4d2ecce9bab6940e464afbde4fef0 Mon Sep 17 00:00:00 2001 From: Srinidhi Kasagar Date: Wed, 19 May 2010 06:49:13 +0100 Subject: ARM: 6137/1: nomadik hwrng: Add clock support This adds the clock support to the Nomadik RNG driver Signed-off-by: srinidhi kasagar Acked-by: Linus walleij Acked-by: Alessandro Rubini Acked-by: Herbert Xu Signed-off-by: Russell King --- arch/arm/mach-nomadik/clock.c | 1 + drivers/char/hw_random/nomadik-rng.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) (limited to 'drivers') diff --git a/arch/arm/mach-nomadik/clock.c b/arch/arm/mach-nomadik/clock.c index 60f5bee09f2e..2c471fc451d7 100644 --- a/arch/arm/mach-nomadik/clock.c +++ b/arch/arm/mach-nomadik/clock.c @@ -56,6 +56,7 @@ static struct clk_lookup lookups[] = { CLK(&clk_default, "gpio.1"), CLK(&clk_default, "gpio.2"), CLK(&clk_default, "gpio.3"), + CLK(&clk_default, "rng"), }; static int __init clk_init(void) diff --git a/drivers/char/hw_random/nomadik-rng.c b/drivers/char/hw_random/nomadik-rng.c index a8b4c4010144..a348c7e9aa0b 100644 --- a/drivers/char/hw_random/nomadik-rng.c +++ b/drivers/char/hw_random/nomadik-rng.c @@ -15,6 +15,10 @@ #include #include #include +#include +#include + +static struct clk *rng_clk; static int nmk_rng_read(struct hwrng *rng, void *data, size_t max, bool wait) { @@ -40,6 +44,15 @@ static int nmk_rng_probe(struct amba_device *dev, struct amba_id *id) void __iomem *base; int ret; + rng_clk = clk_get(&dev->dev, NULL); + if (IS_ERR(rng_clk)) { + dev_err(&dev->dev, "could not get rng clock\n"); + ret = PTR_ERR(rng_clk); + return ret; + } + + clk_enable(rng_clk); + ret = amba_request_regions(dev, dev->dev.init_name); if (ret) return ret; @@ -57,6 +70,8 @@ out_unmap: iounmap(base); out_release: amba_release_regions(dev); + clk_disable(rng_clk); + clk_put(rng_clk); return ret; } @@ -66,6 +81,8 @@ static int nmk_rng_remove(struct amba_device *dev) hwrng_unregister(&nmk_rng); iounmap(base); amba_release_regions(dev); + clk_disable(rng_clk); + clk_put(rng_clk); return 0; } -- cgit v1.2.3 From c0dc72bad9cf21071f5e4005de46f7c8b67a138a Mon Sep 17 00:00:00 2001 From: Sebastien Dugue Date: Thu, 20 May 2010 15:58:22 -0700 Subject: mlx4_core: Fix possible chunk sg list overflow in mlx4_alloc_icm() If the number of sg entries in the ICM chunk reaches MLX4_ICM_CHUNK_LEN, we must set chunk to NULL even for coherent mappings so that the next time through the loop will allocate another chunk. Otherwise we'll overflow the sg list the next time through the loop. This will lead to memory corruption if this case is hit. mthca does not have this bug. Signed-off-by: Sebastien Dugue Cc: Signed-off-by: Roland Dreier --- drivers/net/mlx4/icm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/mlx4/icm.c b/drivers/net/mlx4/icm.c index 57288ca1395f..ef62f1749b8a 100644 --- a/drivers/net/mlx4/icm.c +++ b/drivers/net/mlx4/icm.c @@ -175,9 +175,10 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages, if (chunk->nsg <= 0) goto fail; + } + if (chunk->npages == MLX4_ICM_CHUNK_LEN) chunk = NULL; - } npages -= 1 << cur_order; } else { -- cgit v1.2.3 From c050def076bfbc4513ee961c77fde6ba3d401158 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 20 May 2010 15:58:22 -0700 Subject: mlx4_core: Clean up mlx4_alloc_icm() a bit Handle the allocation error case first, so that we don't have further nested if for handling the common case of success. Signed-off-by: Roland Dreier --- drivers/net/mlx4/icm.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/mlx4/icm.c b/drivers/net/mlx4/icm.c index ef62f1749b8a..b07e4dee80aa 100644 --- a/drivers/net/mlx4/icm.c +++ b/drivers/net/mlx4/icm.c @@ -163,29 +163,30 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages, ret = mlx4_alloc_icm_pages(&chunk->mem[chunk->npages], cur_order, gfp_mask); - if (!ret) { - ++chunk->npages; - - if (coherent) - ++chunk->nsg; - else if (chunk->npages == MLX4_ICM_CHUNK_LEN) { - chunk->nsg = pci_map_sg(dev->pdev, chunk->mem, - chunk->npages, - PCI_DMA_BIDIRECTIONAL); - - if (chunk->nsg <= 0) - goto fail; - } + if (ret) { + if (--cur_order < 0) + goto fail; + else + continue; + } - if (chunk->npages == MLX4_ICM_CHUNK_LEN) - chunk = NULL; + ++chunk->npages; - npages -= 1 << cur_order; - } else { - --cur_order; - if (cur_order < 0) + if (coherent) + ++chunk->nsg; + else if (chunk->npages == MLX4_ICM_CHUNK_LEN) { + chunk->nsg = pci_map_sg(dev->pdev, chunk->mem, + chunk->npages, + PCI_DMA_BIDIRECTIONAL); + + if (chunk->nsg <= 0) goto fail; } + + if (chunk->npages == MLX4_ICM_CHUNK_LEN) + chunk = NULL; + + npages -= 1 << cur_order; } if (!coherent && chunk) { -- cgit v1.2.3 From 81c2a3ba497835797332b517ebf2de7b7f2a7c80 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 20 May 2010 22:52:58 -0700 Subject: Input: use ABS_CNT rather than (ABS_MAX + 1) Signed-off-by: Daniel Mack Signed-off-by: Dmitry Torokhov --- drivers/hid/hid-debug.c | 2 +- drivers/input/joydev.c | 10 +++++----- drivers/input/misc/uinput.c | 4 ++-- include/linux/input.h | 12 ++++++------ include/linux/joystick.h | 4 ++-- include/linux/uinput.h | 10 +++++----- 6 files changed, 21 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index 56f314fbd4f9..c94026768570 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -811,7 +811,7 @@ static const char *relatives[REL_MAX + 1] = { [REL_WHEEL] = "Wheel", [REL_MISC] = "Misc", }; -static const char *absolutes[ABS_MAX + 1] = { +static const char *absolutes[ABS_CNT] = { [ABS_X] = "X", [ABS_Y] = "Y", [ABS_Z] = "Z", [ABS_RX] = "Rx", [ABS_RY] = "Ry", [ABS_RZ] = "Rz", diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 423e0e6031ab..34157bb97ed6 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -47,15 +47,15 @@ struct joydev { struct mutex mutex; struct device dev; - struct js_corr corr[ABS_MAX + 1]; + struct js_corr corr[ABS_CNT]; struct JS_DATA_SAVE_TYPE glue; int nabs; int nkey; __u16 keymap[KEY_MAX - BTN_MISC + 1]; __u16 keypam[KEY_MAX - BTN_MISC + 1]; - __u8 absmap[ABS_MAX + 1]; - __u8 abspam[ABS_MAX + 1]; - __s16 abs[ABS_MAX + 1]; + __u8 absmap[ABS_CNT]; + __u8 abspam[ABS_CNT]; + __s16 abs[ABS_CNT]; }; struct joydev_client { @@ -826,7 +826,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, joydev->handle.handler = handler; joydev->handle.private = joydev; - for (i = 0; i < ABS_MAX + 1; i++) + for (i = 0; i < ABS_CNT; i++) if (test_bit(i, dev->absbit)) { joydev->absmap[i] = joydev->nabs; joydev->abspam[joydev->nabs] = i; diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 1477466076ad..b71eb55f2dbc 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -300,7 +300,7 @@ static int uinput_validate_absbits(struct input_dev *dev) unsigned int cnt; int retval = 0; - for (cnt = 0; cnt < ABS_MAX + 1; cnt++) { + for (cnt = 0; cnt < ABS_CNT; cnt++) { if (!test_bit(cnt, dev->absbit)) continue; @@ -387,7 +387,7 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu dev->id.product = user_dev->id.product; dev->id.version = user_dev->id.version; - size = sizeof(int) * (ABS_MAX + 1); + size = sizeof(int) * ABS_CNT; memcpy(dev->absmax, user_dev->absmax, size); memcpy(dev->absmin, user_dev->absmin, size); memcpy(dev->absfuzz, user_dev->absfuzz, size); diff --git a/include/linux/input.h b/include/linux/input.h index 83524e4f3290..6fcc9101beeb 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -1155,7 +1155,7 @@ struct input_dev { int sync; - int abs[ABS_MAX + 1]; + int abs[ABS_CNT]; int rep[REP_MAX + 1]; unsigned long key[BITS_TO_LONGS(KEY_CNT)]; @@ -1163,11 +1163,11 @@ struct input_dev { unsigned long snd[BITS_TO_LONGS(SND_CNT)]; unsigned long sw[BITS_TO_LONGS(SW_CNT)]; - int absmax[ABS_MAX + 1]; - int absmin[ABS_MAX + 1]; - int absfuzz[ABS_MAX + 1]; - int absflat[ABS_MAX + 1]; - int absres[ABS_MAX + 1]; + int absmax[ABS_CNT]; + int absmin[ABS_CNT]; + int absfuzz[ABS_CNT]; + int absflat[ABS_CNT]; + int absres[ABS_CNT]; int (*open)(struct input_dev *dev); void (*close)(struct input_dev *dev); diff --git a/include/linux/joystick.h b/include/linux/joystick.h index 9e20c29c1e14..47199b13e0eb 100644 --- a/include/linux/joystick.h +++ b/include/linux/joystick.h @@ -64,8 +64,8 @@ struct js_event { #define JSIOCSCORR _IOW('j', 0x21, struct js_corr) /* set correction values */ #define JSIOCGCORR _IOR('j', 0x22, struct js_corr) /* get correction values */ -#define JSIOCSAXMAP _IOW('j', 0x31, __u8[ABS_MAX + 1]) /* set axis mapping */ -#define JSIOCGAXMAP _IOR('j', 0x32, __u8[ABS_MAX + 1]) /* get axis mapping */ +#define JSIOCSAXMAP _IOW('j', 0x31, __u8[ABS_CNT]) /* set axis mapping */ +#define JSIOCGAXMAP _IOR('j', 0x32, __u8[ABS_CNT]) /* get axis mapping */ #define JSIOCSBTNMAP _IOW('j', 0x33, __u16[KEY_MAX - BTN_MISC + 1]) /* set button mapping */ #define JSIOCGBTNMAP _IOR('j', 0x34, __u16[KEY_MAX - BTN_MISC + 1]) /* get button mapping */ diff --git a/include/linux/uinput.h b/include/linux/uinput.h index 15ddd4483b09..60c81da77f0f 100644 --- a/include/linux/uinput.h +++ b/include/linux/uinput.h @@ -166,11 +166,11 @@ struct uinput_ff_erase { struct uinput_user_dev { char name[UINPUT_MAX_NAME_SIZE]; struct input_id id; - int ff_effects_max; - int absmax[ABS_MAX + 1]; - int absmin[ABS_MAX + 1]; - int absfuzz[ABS_MAX + 1]; - int absflat[ABS_MAX + 1]; + int ff_effects_max; + int absmax[ABS_CNT]; + int absmin[ABS_CNT]; + int absfuzz[ABS_CNT]; + int absflat[ABS_CNT]; }; #endif /* __UINPUT_H_ */ -- cgit v1.2.3 From 119fc60a2d20b63439fdae99f0c7022d3dd99def Mon Sep 17 00:00:00 2001 From: Mallikarjuna R Chilakala Date: Thu, 20 May 2010 23:07:06 -0700 Subject: ixgbe:add support for a new 82599 10G Base-T device This adds support for a new copper device for 82599, device id 0x151c. This 82599 10GBase-T device uses the PHY's internal temperature sensor to guard against over-temp conditions. In this scenario the PHY will be put in a low power mode and link will no longer be able to transmit or receive any data. When this occurs, the over-temp interrupt is latched and driver logs this error message. A HW reset or power cycle is required to clear this status. Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe.h | 3 ++ drivers/net/ixgbe/ixgbe_82598.c | 1 + drivers/net/ixgbe/ixgbe_82599.c | 1 + drivers/net/ixgbe/ixgbe_main.c | 69 +++++++++++++++++++++++++++++++++++++++++ drivers/net/ixgbe/ixgbe_phy.c | 30 ++++++++++++++++++ drivers/net/ixgbe/ixgbe_phy.h | 3 ++ drivers/net/ixgbe/ixgbe_type.h | 4 +++ 7 files changed, 111 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index d0ea3d6dea95..ffae480587ae 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -360,6 +360,7 @@ struct ixgbe_adapter { u32 flags2; #define IXGBE_FLAG2_RSC_CAPABLE (u32)(1) #define IXGBE_FLAG2_RSC_ENABLED (u32)(1 << 1) +#define IXGBE_FLAG2_TEMP_SENSOR_CAPABLE (u32)(1 << 2) /* default to trying for four seconds */ #define IXGBE_TRY_LINK_TIMEOUT (4 * HZ) @@ -407,6 +408,8 @@ struct ixgbe_adapter { u16 eeprom_version; int node; + struct work_struct check_overtemp_task; + u32 interrupt_event; /* SR-IOV */ DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS); diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index f2b7ff44215b..9c02d6014cc4 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -1236,6 +1236,7 @@ static struct ixgbe_phy_operations phy_ops_82598 = { .setup_link = &ixgbe_setup_phy_link_generic, .setup_link_speed = &ixgbe_setup_phy_link_speed_generic, .read_i2c_eeprom = &ixgbe_read_i2c_eeprom_82598, + .check_overtemp = &ixgbe_tn_check_overtemp, }; struct ixgbe_info ixgbe_82598_info = { diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index e9706eb8e4ff..a4e2901f2f08 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -2395,6 +2395,7 @@ static struct ixgbe_phy_operations phy_ops_82599 = { .write_i2c_byte = &ixgbe_write_i2c_byte_generic, .read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic, .write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic, + .check_overtemp = &ixgbe_tn_check_overtemp, }; struct ixgbe_info ixgbe_82599_info = { diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 9551cbb7bf01..d571d101de08 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -108,6 +108,8 @@ static DEFINE_PCI_DEVICE_TABLE(ixgbe_pci_tbl) = { board_82599 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_CX4), board_82599 }, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_T3_LOM), + board_82599 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_COMBO_BACKPLANE), board_82599 }, @@ -1618,6 +1620,48 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) } } +/** + * ixgbe_check_overtemp_task - worker thread to check over tempurature + * @work: pointer to work_struct containing our data + **/ +static void ixgbe_check_overtemp_task(struct work_struct *work) +{ + struct ixgbe_adapter *adapter = container_of(work, + struct ixgbe_adapter, + check_overtemp_task); + struct ixgbe_hw *hw = &adapter->hw; + u32 eicr = adapter->interrupt_event; + + if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) { + switch (hw->device_id) { + case IXGBE_DEV_ID_82599_T3_LOM: { + u32 autoneg; + bool link_up = false; + + if (hw->mac.ops.check_link) + hw->mac.ops.check_link(hw, &autoneg, &link_up, false); + + if (((eicr & IXGBE_EICR_GPI_SDP0) && (!link_up)) || + (eicr & IXGBE_EICR_LSC)) + /* Check if this is due to overtemp */ + if (hw->phy.ops.check_overtemp(hw) == IXGBE_ERR_OVERTEMP) + break; + } + return; + default: + if (!(eicr & IXGBE_EICR_GPI_SDP0)) + return; + break; + } + DPRINTK(DRV, ERR, "Network adapter has been stopped because it " + "has over heated. Restart the computer. If the problem " + "persists, power off the system and replace the " + "adapter\n"); + /* write to clear the interrupt */ + IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0); + } +} + static void ixgbe_check_fan_failure(struct ixgbe_adapter *adapter, u32 eicr) { struct ixgbe_hw *hw = &adapter->hw; @@ -1689,6 +1733,10 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data) if (hw->mac.type == ixgbe_mac_82599EB) { ixgbe_check_sfp_event(adapter, eicr); + adapter->interrupt_event = eicr; + if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) && + ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) + schedule_work(&adapter->check_overtemp_task); /* Handle Flow Director Full threshold interrupt */ if (eicr & IXGBE_EICR_FLOW_DIR) { @@ -2190,6 +2238,8 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter) u32 mask; mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE); + if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) + mask |= IXGBE_EIMS_GPI_SDP0; if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) mask |= IXGBE_EIMS_GPI_SDP1; if (adapter->hw.mac.type == ixgbe_mac_82599EB) { @@ -2250,6 +2300,9 @@ static irqreturn_t ixgbe_intr(int irq, void *data) ixgbe_check_sfp_event(adapter, eicr); ixgbe_check_fan_failure(adapter, eicr); + if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) && + ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) + schedule_work(&adapter->check_overtemp_task); if (napi_schedule_prep(&(q_vector->napi))) { adapter->tx_ring[0]->total_packets = 0; @@ -3265,6 +3318,13 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE); } + /* Enable Thermal over heat sensor interrupt */ + if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) { + gpie = IXGBE_READ_REG(hw, IXGBE_GPIE); + gpie |= IXGBE_SDP0_GPIEN; + IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); + } + /* Enable fan failure interrupt if media type is copper */ if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) { gpie = IXGBE_READ_REG(hw, IXGBE_GPIE); @@ -3666,6 +3726,9 @@ void ixgbe_down(struct ixgbe_adapter *adapter) adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) cancel_work_sync(&adapter->fdir_reinit_task); + if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) + cancel_work_sync(&adapter->check_overtemp_task); + /* disable transmits in the hardware now that interrupts are off */ for (i = 0; i < adapter->num_tx_queues; i++) { j = adapter->tx_ring[i]->reg_idx; @@ -4645,6 +4708,8 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599; adapter->flags2 |= IXGBE_FLAG2_RSC_CAPABLE; adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED; + if (hw->device_id == IXGBE_DEV_ID_82599_T3_LOM) + adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE; if (dev->features & NETIF_F_NTUPLE) { /* Flow Director perfect filter enabled */ adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE; @@ -6561,7 +6626,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, } /* reset_hw fills in the perm_addr as well */ + hw->phy.reset_if_overtemp = true; err = hw->mac.ops.reset_hw(hw); + hw->phy.reset_if_overtemp = false; if (err == IXGBE_ERR_SFP_NOT_PRESENT && hw->mac.type == ixgbe_mac_82598EB) { /* @@ -6730,6 +6797,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) INIT_WORK(&adapter->fdir_reinit_task, ixgbe_fdir_reinit_task); + if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) + INIT_WORK(&adapter->check_overtemp_task, ixgbe_check_overtemp_task); #ifdef CONFIG_IXGBE_DCA if (dca_add_requester(&pdev->dev) == 0) { adapter->flags |= IXGBE_FLAG_DCA_ENABLED; diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index 22d21af14783..09e1911ff510 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -135,6 +135,11 @@ static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id) **/ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw) { + /* Don't reset PHY if it's shut down due to overtemp. */ + if (!hw->phy.reset_if_overtemp && + (IXGBE_ERR_OVERTEMP == hw->phy.ops.check_overtemp(hw))) + return 0; + /* * Perform soft PHY reset to the PHY_XS. * This will cause a soft reset to the PHY @@ -1345,3 +1350,28 @@ s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, return status; } +/** + * ixgbe_tn_check_overtemp - Checks if an overtemp occured. + * @hw: pointer to hardware structure + * + * Checks if the LASI temp alarm status was triggered due to overtemp + **/ +s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw) +{ + s32 status = 0; + u16 phy_data = 0; + + if (hw->device_id != IXGBE_DEV_ID_82599_T3_LOM) + goto out; + + /* Check that the LASI temp alarm status was triggered */ + hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG, + MDIO_MMD_PMAPMD, &phy_data); + + if (!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM)) + goto out; + + status = IXGBE_ERR_OVERTEMP; +out: + return status; +} diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h index c9c545941407..ef4ba834c593 100644 --- a/drivers/net/ixgbe/ixgbe_phy.h +++ b/drivers/net/ixgbe/ixgbe_phy.h @@ -80,6 +80,8 @@ #define IXGBE_I2C_T_SU_STO 4 #define IXGBE_I2C_T_BUF 5 +#define IXGBE_TN_LASI_STATUS_REG 0x9005 +#define IXGBE_TN_LASI_STATUS_TEMP_ALARM 0x0008 s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw); s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw); @@ -106,6 +108,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw); s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, u16 *list_offset, u16 *data_offset); +s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw); s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, u8 *data); s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 39b9be897439..2eb6e151016c 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -51,6 +51,7 @@ #define IXGBE_DEV_ID_82599_KX4 0x10F7 #define IXGBE_DEV_ID_82599_KX4_MEZZ 0x1514 #define IXGBE_DEV_ID_82599_KR 0x1517 +#define IXGBE_DEV_ID_82599_T3_LOM 0x151C #define IXGBE_DEV_ID_82599_CX4 0x10F9 #define IXGBE_DEV_ID_82599_SFP 0x10FB #define IXGBE_DEV_ID_82599_SFP_EM 0x1507 @@ -2470,6 +2471,7 @@ struct ixgbe_phy_operations { s32 (*write_i2c_byte)(struct ixgbe_hw *, u8, u8, u8); s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *); s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8); + s32 (*check_overtemp)(struct ixgbe_hw *); }; struct ixgbe_eeprom_info { @@ -2518,6 +2520,7 @@ struct ixgbe_phy_info { enum ixgbe_smart_speed smart_speed; bool smart_speed_active; bool multispeed_fiber; + bool reset_if_overtemp; }; #include "ixgbe_mbx.h" @@ -2605,6 +2608,7 @@ struct ixgbe_info { #define IXGBE_ERR_FDIR_REINIT_FAILED -23 #define IXGBE_ERR_EEPROM_VERSION -24 #define IXGBE_ERR_NO_SPACE -25 +#define IXGBE_ERR_OVERTEMP -26 #define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF #endif /* _IXGBE_TYPE_H_ */ -- cgit v1.2.3 From 0f0b405cd16f7aaff84a935984cae421897d725d Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Thu, 20 May 2010 04:00:59 +0000 Subject: sh_eth: Fix memleak in sh_mdio_release Allocated memory for IRQs should be freed when releasing the mii_bus Signed-off-by: Denis Kirjanov Acked-by: Nobuhiro Iwamatsu Signed-off-by: David S. Miller --- drivers/net/sh_eth.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 586ed0915a29..501a55ffce57 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -1294,6 +1294,9 @@ static int sh_mdio_release(struct net_device *ndev) /* remove mdio bus info from net_device */ dev_set_drvdata(&ndev->dev, NULL); + /* free interrupts memory */ + kfree(bus->irq); + /* free bitbang info */ free_mdio_bitbang(bus); -- cgit v1.2.3 From 1f01bfd202bc539bccd282befa2bbdb8d6ad80ee Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Wed, 19 May 2010 06:46:38 +0000 Subject: can: SJA1000 add missing spin_lock_init() As remarked by Sam Ravnborg the spin_lock variable, that has been introduced in commit 57c8a456640fa3ca777652f11f2db4179a3e66b6 ("can: Fix SJA1000 command register writes on SMP systems") has not been initialized properly. This patch adds the initialization to allow spinlock debugging. Signed-off-by: Oliver Hartkopp CC: Sam Ravnborg Signed-off-by: David S. Miller --- drivers/net/can/sja1000/sja1000.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index 85f7cbfe8e5f..0a8de01d52f7 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c @@ -599,6 +599,8 @@ struct net_device *alloc_sja1000dev(int sizeof_priv) priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_BERR_REPORTING; + spin_lock_init(&priv->cmdreg_lock); + if (sizeof_priv) priv->priv = (void *)priv + sizeof(struct sja1000_priv); -- cgit v1.2.3 From 9a6edb60ec10d86b1025a0cdad68fd89f1ddaf02 Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Thu, 6 May 2010 17:03:25 -0700 Subject: IB/core: Allow device-specific per-port sysfs files Add a new parameter to ib_register_device() so that low-level device drivers can pass in a pointer to a callback function that will be called for each port that is registered in sysfs. This allows low-level device drivers to create files in /sys/class/infiniband//ports// without having to poke through the internals of the RDMA sysfs handling. There is no need for an unregister function since the kobject reference will go to zero when ib_unregister_device() is called. Signed-off-by: Ralph Campbell Signed-off-by: Roland Dreier --- drivers/infiniband/core/core_priv.h | 4 +++- drivers/infiniband/core/device.c | 6 ++++-- drivers/infiniband/core/sysfs.c | 21 +++++++++++++++++---- drivers/infiniband/hw/amso1100/c2_provider.c | 2 +- drivers/infiniband/hw/cxgb3/iwch_provider.c | 2 +- drivers/infiniband/hw/cxgb4/provider.c | 2 +- drivers/infiniband/hw/ehca/ehca_main.c | 2 +- drivers/infiniband/hw/ipath/ipath_verbs.c | 2 +- drivers/infiniband/hw/mlx4/main.c | 2 +- drivers/infiniband/hw/mthca/mthca_provider.c | 2 +- drivers/infiniband/hw/nes/nes_verbs.c | 2 +- include/rdma/ib_verbs.h | 4 +++- 12 files changed, 35 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h index 05ac36e6acdb..a565af5c2d2e 100644 --- a/drivers/infiniband/core/core_priv.h +++ b/drivers/infiniband/core/core_priv.h @@ -38,7 +38,9 @@ #include -int ib_device_register_sysfs(struct ib_device *device); +int ib_device_register_sysfs(struct ib_device *device, + int (*port_callback)(struct ib_device *, + u8, struct kobject *)); void ib_device_unregister_sysfs(struct ib_device *device); int ib_sysfs_setup(void); diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index d1fba4153332..a19effad0811 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -267,7 +267,9 @@ out: * callback for each device that is added. @device must be allocated * with ib_alloc_device(). */ -int ib_register_device(struct ib_device *device) +int ib_register_device(struct ib_device *device, + int (*port_callback)(struct ib_device *, + u8, struct kobject *)) { int ret; @@ -296,7 +298,7 @@ int ib_register_device(struct ib_device *device) goto out; } - ret = ib_device_register_sysfs(device); + ret = ib_device_register_sysfs(device, port_callback); if (ret) { printk(KERN_WARNING "Couldn't register device %s with driver model\n", device->name); diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index f901957abc8b..3627300e2a10 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c @@ -475,7 +475,9 @@ err: return NULL; } -static int add_port(struct ib_device *device, int port_num) +static int add_port(struct ib_device *device, int port_num, + int (*port_callback)(struct ib_device *, + u8, struct kobject *)) { struct ib_port *p; struct ib_port_attr attr; @@ -522,11 +524,20 @@ static int add_port(struct ib_device *device, int port_num) if (ret) goto err_free_pkey; + if (port_callback) { + ret = port_callback(device, port_num, &p->kobj); + if (ret) + goto err_remove_pkey; + } + list_add_tail(&p->kobj.entry, &device->port_list); kobject_uevent(&p->kobj, KOBJ_ADD); return 0; +err_remove_pkey: + sysfs_remove_group(&p->kobj, &p->pkey_group); + err_free_pkey: for (i = 0; i < attr.pkey_tbl_len; ++i) kfree(p->pkey_group.attrs[i]); @@ -754,7 +765,9 @@ static struct attribute_group iw_stats_group = { .attrs = iw_proto_stats_attrs, }; -int ib_device_register_sysfs(struct ib_device *device) +int ib_device_register_sysfs(struct ib_device *device, + int (*port_callback)(struct ib_device *, + u8, struct kobject *)) { struct device *class_dev = &device->dev; int ret; @@ -785,12 +798,12 @@ int ib_device_register_sysfs(struct ib_device *device) } if (device->node_type == RDMA_NODE_IB_SWITCH) { - ret = add_port(device, 0); + ret = add_port(device, 0, port_callback); if (ret) goto err_put; } else { for (i = 1; i <= device->phys_port_cnt; ++i) { - ret = add_port(device, i); + ret = add_port(device, i, port_callback); if (ret) goto err_put; } diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c index c47f618d12e8..aeebc4d37e33 100644 --- a/drivers/infiniband/hw/amso1100/c2_provider.c +++ b/drivers/infiniband/hw/amso1100/c2_provider.c @@ -865,7 +865,7 @@ int c2_register_device(struct c2_dev *dev) dev->ibdev.iwcm->create_listen = c2_service_create; dev->ibdev.iwcm->destroy_listen = c2_service_destroy; - ret = ib_register_device(&dev->ibdev); + ret = ib_register_device(&dev->ibdev, NULL); if (ret) goto out_free_iwcm; diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index 19b1c4a62a23..fca0b4b747e4 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c @@ -1428,7 +1428,7 @@ int iwch_register_device(struct iwch_dev *dev) dev->ibdev.iwcm->rem_ref = iwch_qp_rem_ref; dev->ibdev.iwcm->get_qp = iwch_get_qp; - ret = ib_register_device(&dev->ibdev); + ret = ib_register_device(&dev->ibdev, NULL); if (ret) goto bail1; diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c index dfc49020bb9c..cd3d6e2c7edf 100644 --- a/drivers/infiniband/hw/cxgb4/provider.c +++ b/drivers/infiniband/hw/cxgb4/provider.c @@ -486,7 +486,7 @@ int c4iw_register_device(struct c4iw_dev *dev) dev->ibdev.iwcm->rem_ref = c4iw_qp_rem_ref; dev->ibdev.iwcm->get_qp = c4iw_get_qp; - ret = ib_register_device(&dev->ibdev); + ret = ib_register_device(&dev->ibdev, NULL); if (ret) goto bail1; diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 129a6bebd6e3..d1a92785c9ee 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c @@ -798,7 +798,7 @@ static int __devinit ehca_probe(struct of_device *dev, goto probe5; } - ret = ib_register_device(&shca->ib_device); + ret = ib_register_device(&shca->ib_device, NULL); if (ret) { ehca_err(&shca->ib_device, "ib_register_device() failed ret=%i", ret); diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c index 559f39be0dcc..dd7f26d04d46 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/drivers/infiniband/hw/ipath/ipath_verbs.c @@ -2182,7 +2182,7 @@ int ipath_register_ib_device(struct ipath_devdata *dd) snprintf(dev->node_desc, sizeof(dev->node_desc), IPATH_IDSTR " %s", init_utsname()->nodename); - ret = ib_register_device(dev); + ret = ib_register_device(dev, NULL); if (ret) goto err_reg; diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 39051417054c..4e94e360e43b 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -662,7 +662,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) spin_lock_init(&ibdev->sm_lock); mutex_init(&ibdev->cap_mask_mutex); - if (ib_register_device(&ibdev->ib_dev)) + if (ib_register_device(&ibdev->ib_dev, NULL)) goto err_map; if (mlx4_ib_mad_init(ibdev)) diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index f080a784bc79..1e0b4b6074ad 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c @@ -1403,7 +1403,7 @@ int mthca_register_device(struct mthca_dev *dev) mutex_init(&dev->cap_mask_mutex); - ret = ib_register_device(&dev->ib_dev); + ret = ib_register_device(&dev->ib_dev, NULL); if (ret) return ret; diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 925e1f2d1d55..9bc2d744b2ea 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -3962,7 +3962,7 @@ int nes_register_ofa_device(struct nes_ib_device *nesibdev) struct nes_adapter *nesadapter = nesdev->nesadapter; int i, ret; - ret = ib_register_device(&nesvnic->nesibdev->ibdev); + ret = ib_register_device(&nesvnic->nesibdev->ibdev, NULL); if (ret) { return ret; } diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 310d31474034..f3e8f3c07725 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -1172,7 +1172,9 @@ struct ib_client { struct ib_device *ib_alloc_device(size_t size); void ib_dealloc_device(struct ib_device *device); -int ib_register_device (struct ib_device *device); +int ib_register_device(struct ib_device *device, + int (*port_callback)(struct ib_device *, + u8, struct kobject *)); void ib_unregister_device(struct ib_device *device); int ib_register_client (struct ib_client *client); -- cgit v1.2.3 From c3e33e043f5e9c583aa59d5591a614b2a8243d3a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 15 May 2010 20:09:29 +0200 Subject: block,ide: simplify bdops->set_capacity() to ->unlock_native_capacity() bdops->set_capacity() is unnecessarily generic. All that's required is a simple one way notification to lower level driver telling it to try to unlock native capacity. There's no reason to pass in target capacity or return the new capacity. The former is always the inherent native capacity and the latter can be handled via the usual device resize / revalidation path. In fact, the current API is always used that way. Replace ->set_capacity() with ->unlock_native_capacity() which take only @disk and doesn't return anything. IDE which is the only current user of the API is converted accordingly. Signed-off-by: Tejun Heo Cc: Ben Hutchings Cc: Bartlomiej Zolnierkiewicz Acked-by: David S. Miller Signed-off-by: Jens Axboe --- drivers/ide/ide-disk.c | 40 ++++++++++++++++------------------------ drivers/ide/ide-gd.c | 11 ++++------- fs/partitions/check.c | 4 ++-- include/linux/blkdev.h | 3 +-- include/linux/ide.h | 2 +- 5 files changed, 24 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 3b128dce9c3a..33d65039cce9 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -407,32 +407,24 @@ static int ide_disk_get_capacity(ide_drive_t *drive) return 0; } -static u64 ide_disk_set_capacity(ide_drive_t *drive, u64 capacity) +static void ide_disk_unlock_native_capacity(ide_drive_t *drive) { - u64 set = min(capacity, drive->probed_capacity); u16 *id = drive->id; int lba48 = ata_id_lba48_enabled(id); if ((drive->dev_flags & IDE_DFLAG_LBA) == 0 || ata_id_hpa_enabled(id) == 0) - goto out; + return; /* * according to the spec the SET MAX ADDRESS command shall be * immediately preceded by a READ NATIVE MAX ADDRESS command */ - capacity = ide_disk_hpa_get_native_capacity(drive, lba48); - if (capacity == 0) - goto out; - - set = ide_disk_hpa_set_capacity(drive, set, lba48); - if (set) { - /* needed for ->resume to disable HPA */ - drive->dev_flags |= IDE_DFLAG_NOHPA; - return set; - } -out: - return drive->capacity64; + if (!ide_disk_hpa_get_native_capacity(drive, lba48)) + return; + + if (ide_disk_hpa_set_capacity(drive, drive->probed_capacity, lba48)) + drive->dev_flags |= IDE_DFLAG_NOHPA; /* disable HPA on resume */ } static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) @@ -783,13 +775,13 @@ static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk, } const struct ide_disk_ops ide_ata_disk_ops = { - .check = ide_disk_check, - .set_capacity = ide_disk_set_capacity, - .get_capacity = ide_disk_get_capacity, - .setup = ide_disk_setup, - .flush = ide_disk_flush, - .init_media = ide_disk_init_media, - .set_doorlock = ide_disk_set_doorlock, - .do_request = ide_do_rw_disk, - .ioctl = ide_disk_ioctl, + .check = ide_disk_check, + .unlock_native_capacity = ide_disk_unlock_native_capacity, + .get_capacity = ide_disk_get_capacity, + .setup = ide_disk_setup, + .flush = ide_disk_flush, + .init_media = ide_disk_init_media, + .set_doorlock = ide_disk_set_doorlock, + .do_request = ide_do_rw_disk, + .ioctl = ide_disk_ioctl, }; diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c index c32d83996ae1..c102d23d9b38 100644 --- a/drivers/ide/ide-gd.c +++ b/drivers/ide/ide-gd.c @@ -288,17 +288,14 @@ static int ide_gd_media_changed(struct gendisk *disk) return ret; } -static unsigned long long ide_gd_set_capacity(struct gendisk *disk, - unsigned long long capacity) +static void ide_gd_unlock_native_capacity(struct gendisk *disk) { struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); ide_drive_t *drive = idkp->drive; const struct ide_disk_ops *disk_ops = drive->disk_ops; - if (disk_ops->set_capacity) - return disk_ops->set_capacity(drive, capacity); - - return drive->capacity64; + if (disk_ops->unlock_native_capacity) + disk_ops->unlock_native_capacity(drive); } static int ide_gd_revalidate_disk(struct gendisk *disk) @@ -329,7 +326,7 @@ static const struct block_device_operations ide_gd_ops = { .locked_ioctl = ide_gd_ioctl, .getgeo = ide_gd_getgeo, .media_changed = ide_gd_media_changed, - .set_capacity = ide_gd_set_capacity, + .unlock_native_capacity = ide_gd_unlock_native_capacity, .revalidate_disk = ide_gd_revalidate_disk }; diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 8f01df354f04..4f1fee0355ad 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -601,10 +601,10 @@ rescan: "%s: p%d size %llu exceeds device capacity, ", disk->disk_name, p, (unsigned long long) size); - if (bdops->set_capacity && + if (bdops->unlock_native_capacity && (disk->flags & GENHD_FL_NATIVE_CAPACITY) == 0) { printk(KERN_CONT "enabling native capacity\n"); - bdops->set_capacity(disk, ~0ULL); + bdops->unlock_native_capacity(disk); disk->flags |= GENHD_FL_NATIVE_CAPACITY; /* free state and restart */ kfree(state); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 346fd4856733..be411c12ebbe 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1330,8 +1330,7 @@ struct block_device_operations { int (*direct_access) (struct block_device *, sector_t, void **, unsigned long *); int (*media_changed) (struct gendisk *); - unsigned long long (*set_capacity) (struct gendisk *, - unsigned long long); + void (*unlock_native_capacity) (struct gendisk *); int (*revalidate_disk) (struct gendisk *); int (*getgeo)(struct block_device *, struct hd_geometry *); struct module *owner; diff --git a/include/linux/ide.h b/include/linux/ide.h index 3239d1c10acb..b6d448048ae2 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -362,7 +362,7 @@ struct ide_drive_s; struct ide_disk_ops { int (*check)(struct ide_drive_s *, const char *); int (*get_capacity)(struct ide_drive_s *); - u64 (*set_capacity)(struct ide_drive_s *, u64); + void (*unlock_native_capacity)(struct ide_drive_s *); void (*setup)(struct ide_drive_s *); void (*flush)(struct ide_drive_s *); int (*init_media)(struct ide_drive_s *, struct gendisk *); -- cgit v1.2.3 From 073d5eab6fc85b6c278d507a5633b759a85dc878 Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Thu, 13 May 2010 14:49:44 -0700 Subject: iwlwifi: fix internal scan race It is possible for internal scan to race against itself if the device is not returning the scan results from first requests. What happens in this case is the cleanup done during the abort of the first internal scan also cleans up part of the new scan, causing it to access memory it shouldn't. Here are details: * First internal scan is triggered and scan command sent to device. * After seven seconds there is no scan results so the watchdog timer triggers a scan abort. * The scan abort succeeds and a SCAN_COMPLETE_NOTIFICATION is received for failed scan. * During processing of SCAN_COMPLETE_NOTIFICATION we clear STATUS_SCANNING and queue the "scan_completed" work. ** At this time, since the problem that caused the internal scan in first place is still present, a new internal scan is triggered. The behavior at this point is a bit different between 2.6.34 and 2.6.35 since 2.6.35 has a lot of this synchronized. The rest of the race description will thus be generalized. ** As part of preparing for the scan "is_internal_short_scan" is set to true. * At this point the completion work for fist scan is run. As part of this there is some locking missing around the "is_internal_short_scan" variable and it is set to "false". ** Now the second scan runs and it considers itself a real (not internal0 scan and thus causes problems with wrong memory being accessed. The fix is twofold. * Since "is_internal_short_scan" should be protected by mutex, fix this in scan completion work so that changes to it can be serialized. * Do not queue a new internal scan if one is in progress. This fixes https://bugzilla.kernel.org/show_bug.cgi?id=15824 Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-scan.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 107e173112f6..5d3f51ff2f0d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -376,6 +376,11 @@ void iwl_bg_start_internal_scan(struct work_struct *work) mutex_lock(&priv->mutex); + if (priv->is_internal_short_scan == true) { + IWL_DEBUG_SCAN(priv, "Internal scan already in progress\n"); + goto unlock; + } + if (!iwl_is_ready_rf(priv)) { IWL_DEBUG_SCAN(priv, "not ready or exit pending\n"); goto unlock; @@ -497,17 +502,27 @@ void iwl_bg_scan_completed(struct work_struct *work) { struct iwl_priv *priv = container_of(work, struct iwl_priv, scan_completed); + bool internal = false; IWL_DEBUG_SCAN(priv, "SCAN complete scan\n"); cancel_delayed_work(&priv->scan_check); - if (!priv->is_internal_short_scan) - ieee80211_scan_completed(priv->hw, false); - else { + mutex_lock(&priv->mutex); + if (priv->is_internal_short_scan) { priv->is_internal_short_scan = false; IWL_DEBUG_SCAN(priv, "internal short scan completed\n"); + internal = true; } + mutex_unlock(&priv->mutex); + + /* + * Do not hold mutex here since this will cause mac80211 to call + * into driver again into functions that will attempt to take + * mutex. + */ + if (!internal) + ieee80211_scan_completed(priv->hw, false); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; -- cgit v1.2.3 From b9f2e39d4c2bcd8e94f73ae14450d7764f930a41 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Fri, 14 May 2010 10:46:24 +0300 Subject: wl1271: Fix RX data path frame lengths The current frame length used by the driver for RX frames is the SPI bus transfer length. This length has padding bytes, which do not belong to the WLAN frame. As there is no other length information in the WLAN frame except the skb length this problem caused for instance extra ESSID's to be listed at the end of scan results (IE id 0) with zero length. Fix the frame length by removing padding. Signed-off-by: Juuso Oikarinen Reviewed-by: Luciano Coelho Signed-off-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1271_rx.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c index 57f4bfd959c8..b98fb643fab0 100644 --- a/drivers/net/wireless/wl12xx/wl1271_rx.c +++ b/drivers/net/wireless/wl12xx/wl1271_rx.c @@ -113,6 +113,8 @@ static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length) wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len, beacon ? "beacon" : ""); + skb_trim(skb, skb->len - desc->pad_len); + memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); ieee80211_rx_ni(wl->hw, skb); } -- cgit v1.2.3 From ab1d864431a557580945387477bcbcb9dc7f7135 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 17 May 2010 13:15:30 -0400 Subject: ath9k: remove AR9003 from PCI IDs for now We tried to squeeze as much AR9003 support into this kernel release cycle but there are a few features which are still being tested and developed. Some of these features are critical to the stable operation of AR9003 so for now disable AR9003 support all together. This will get re-enabled once all necessary features are in place but very likely will not happen for 2.6.35. Reviewed-by: Don Breslin Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/pci.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 257b10ba6f57..1ec836cf1c0d 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -28,7 +28,6 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */ { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */ { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */ - { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */ { 0 } }; -- cgit v1.2.3 From b6411fc23c70d7a9f57a0bfb35212ad92b5c2b5e Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Tue, 18 May 2010 11:20:51 +0300 Subject: rndis_wlan: replace wireless_send_event with cfg80211_disconnected MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove (hopefully) last use of WEXT in rndis_wlan. Replace wireless_send_event with missing cfg80211_disconnected in rndis_wlan_do_link_down_work. Reported-by: "Rogério Brito" Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 2d2890878dea..4bd61ee627c0 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2572,14 +2572,18 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) static void rndis_wlan_do_link_down_work(struct usbnet *usbdev) { - union iwreq_data evt; + struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); - netif_carrier_off(usbdev->net); + if (priv->connected) { + priv->connected = false; + memset(priv->bssid, 0, ETH_ALEN); + + deauthenticate(usbdev); - evt.data.flags = 0; - evt.data.length = 0; - memset(evt.ap_addr.sa_data, 0, ETH_ALEN); - wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL); + cfg80211_disconnected(usbdev->net, 0, NULL, 0, GFP_KERNEL); + } + + netif_carrier_off(usbdev->net); } static void rndis_wlan_worker(struct work_struct *work) -- cgit v1.2.3 From 31a31dccdd308d5ec7f9a1197a7875a246a348dc Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Wed, 19 May 2010 16:28:28 +0200 Subject: drbd: Do not Oops when C_STANDALONE when uuid gets generated Got introduces with commit 0c3f34516e8c5a1a0ba3585a7777d32bbbdf4ecb Author: Philipp Reisner Date: Mon May 17 16:10:43 2010 +0200 drbd: Create new current UUID as late as possible Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index c144509011b8..7e057b074bbd 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -1354,7 +1354,10 @@ static int w_new_current_uuid(struct drbd_conf *mdev, struct drbd_work *w, int c { if (get_ldev(mdev)) { drbd_uuid_new_current(mdev); - drbd_send_uuids(mdev); + if (get_net_conf(mdev)) { + drbd_send_uuids(mdev); + put_net_conf(mdev); + } drbd_md_sync(mdev); put_ldev(mdev); } -- cgit v1.2.3 From 4604d6366859f781ad16c07a6c65b16fc96e26c5 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Wed, 19 May 2010 17:37:02 +0200 Subject: drbd: Ensure to not trigger late-new-UUID creation multiple times Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_main.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 7e057b074bbd..a949fc45f7ef 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -1217,7 +1217,8 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, mdev->p_uuid = NULL; if (get_ldev(mdev)) { if ((ns.role == R_PRIMARY || ns.peer == R_PRIMARY) && - mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE) + mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE && + !atomic_read(&mdev->new_c_uuid)) atomic_set(&mdev->new_c_uuid, 2); put_ldev(mdev); } @@ -1225,7 +1226,8 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, if (ns.pdsk < D_INCONSISTENT && get_ldev(mdev)) { /* Diskless peer becomes primary or got connected do diskless, primary peer. */ - if (ns.peer == R_PRIMARY && mdev->ldev->md.uuid[UI_BITMAP] == 0) + if (ns.peer == R_PRIMARY && mdev->ldev->md.uuid[UI_BITMAP] == 0 && + !atomic_read(&mdev->new_c_uuid)) atomic_set(&mdev->new_c_uuid, 2); /* D_DISKLESS Peer becomes secondary */ @@ -1353,12 +1355,14 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, static int w_new_current_uuid(struct drbd_conf *mdev, struct drbd_work *w, int cancel) { if (get_ldev(mdev)) { - drbd_uuid_new_current(mdev); - if (get_net_conf(mdev)) { - drbd_send_uuids(mdev); - put_net_conf(mdev); + if (mdev->ldev->md.uuid[UI_BITMAP] == 0) { + drbd_uuid_new_current(mdev); + if (get_net_conf(mdev)) { + drbd_send_uuids(mdev); + put_net_conf(mdev); + } + drbd_md_sync(mdev); } - drbd_md_sync(mdev); put_ldev(mdev); } atomic_dec(&mdev->new_c_uuid); -- cgit v1.2.3 From fc8ce1941d668c70e57a07f13f5a63e73e5dbff3 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Thu, 20 May 2010 10:04:17 +0200 Subject: drbd: Fix: Do not detach, if a bio with a barrier fails Introduced a few days ago: commit 45bb912bd5ea4d2b3a270a93cbdf767a0e2df6f5 Author: Lars Ellenberg Date: Fri May 14 17:10:48 2010 +0200 Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_worker.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 91085c1ab52f..15c96207e626 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -127,7 +127,7 @@ static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(lo drbd_bump_write_ordering(mdev, WO_bdev_flush); spin_lock_irqsave(&mdev->req_lock, flags); list_del(&e->w.list); - e->flags |= EE_RESUBMITTED; + e->flags = (e->flags & ~EE_WAS_ERROR) | EE_RESUBMITTED; e->w.cb = w_e_reissue; /* put_ldev actually happens below, once we come here again. */ __release(local); -- cgit v1.2.3 From 23ce422748def9652fdc019f740cd7900fa2fe3b Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Thu, 20 May 2010 13:35:31 +0200 Subject: drbd: Null pointer deref fix to the large "multi bio rewrite" Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_receiver.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 461d9872d4d3..bc9ab7fb2cc7 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -98,6 +98,10 @@ static struct page *page_chain_del(struct page **head, int n) BUG_ON(!head); page = *head; + + if (!page) + return NULL; + while (page) { tmp = page_chain_next(page); if (--n == 0) -- cgit v1.2.3 From 4e23a59ed1c5f12e14f7899855f8379b3d42e578 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Thu, 20 May 2010 14:45:07 +0200 Subject: drbd: Do not free p_uuid early, this is done in the exit code of the receiver Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_main.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index a949fc45f7ef..be2d2da9cdba 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -1213,8 +1213,6 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, && (ns.pdsk < D_INCONSISTENT || ns.pdsk == D_UNKNOWN || ns.pdsk == D_OUTDATED)) { - kfree(mdev->p_uuid); - mdev->p_uuid = NULL; if (get_ldev(mdev)) { if ((ns.role == R_PRIMARY || ns.peer == R_PRIMARY) && mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE && -- cgit v1.2.3 From 3804a89bfb84fb8849c72e3bbafddaee539b3430 Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Thu, 29 Apr 2010 11:58:44 +0200 Subject: RTC: rtc-cmos: Fix binary mode support As a follow-up to the thread about RTC support for some Loongson 2E/2F boards, this patch tries to address the "REVISIT"/"FIXME" comments about rtc binary mode handling and allow rtc to work with rtc in binary mode. I've also raised the message about 24-h mode not supported to warning otherwise, one may end up with no rtc without any message in the kernel log. Signed-off-by: Arnaud Patard To: linux-mips@linux-mips.org To: rtc-linux@googlegroups.com Cc: david-b@pacbell.net Cc: a.zummo@towertech.it Cc: akpm@linux-foundation.org Patchwork: http://patchwork.linux-mips.org/patch/1158/ Signed-off-by: Ralf Baechle --- drivers/rtc/rtc-cmos.c | 83 ++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index ece4dbddc0ea..96e8e70fbf1e 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -238,31 +238,32 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) rtc_control = CMOS_READ(RTC_CONTROL); spin_unlock_irq(&rtc_lock); - /* REVISIT this assumes PC style usage: always BCD */ - - if (((unsigned)t->time.tm_sec) < 0x60) - t->time.tm_sec = bcd2bin(t->time.tm_sec); - else - t->time.tm_sec = -1; - if (((unsigned)t->time.tm_min) < 0x60) - t->time.tm_min = bcd2bin(t->time.tm_min); - else - t->time.tm_min = -1; - if (((unsigned)t->time.tm_hour) < 0x24) - t->time.tm_hour = bcd2bin(t->time.tm_hour); - else - t->time.tm_hour = -1; - - if (cmos->day_alrm) { - if (((unsigned)t->time.tm_mday) <= 0x31) - t->time.tm_mday = bcd2bin(t->time.tm_mday); + if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + if (((unsigned)t->time.tm_sec) < 0x60) + t->time.tm_sec = bcd2bin(t->time.tm_sec); else - t->time.tm_mday = -1; - if (cmos->mon_alrm) { - if (((unsigned)t->time.tm_mon) <= 0x12) - t->time.tm_mon = bcd2bin(t->time.tm_mon) - 1; + t->time.tm_sec = -1; + if (((unsigned)t->time.tm_min) < 0x60) + t->time.tm_min = bcd2bin(t->time.tm_min); + else + t->time.tm_min = -1; + if (((unsigned)t->time.tm_hour) < 0x24) + t->time.tm_hour = bcd2bin(t->time.tm_hour); + else + t->time.tm_hour = -1; + + if (cmos->day_alrm) { + if (((unsigned)t->time.tm_mday) <= 0x31) + t->time.tm_mday = bcd2bin(t->time.tm_mday); else - t->time.tm_mon = -1; + t->time.tm_mday = -1; + + if (cmos->mon_alrm) { + if (((unsigned)t->time.tm_mon) <= 0x12) + t->time.tm_mon = bcd2bin(t->time.tm_mon)-1; + else + t->time.tm_mon = -1; + } } } t->time.tm_year = -1; @@ -322,29 +323,26 @@ static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask) static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) { struct cmos_rtc *cmos = dev_get_drvdata(dev); - unsigned char mon, mday, hrs, min, sec; + unsigned char mon, mday, hrs, min, sec, rtc_control; if (!is_valid_irq(cmos->irq)) return -EIO; - /* REVISIT this assumes PC style usage: always BCD */ - - /* Writing 0xff means "don't care" or "match all". */ - mon = t->time.tm_mon + 1; - mon = (mon <= 12) ? bin2bcd(mon) : 0xff; - mday = t->time.tm_mday; - mday = (mday >= 1 && mday <= 31) ? bin2bcd(mday) : 0xff; - hrs = t->time.tm_hour; - hrs = (hrs < 24) ? bin2bcd(hrs) : 0xff; - min = t->time.tm_min; - min = (min < 60) ? bin2bcd(min) : 0xff; - sec = t->time.tm_sec; - sec = (sec < 60) ? bin2bcd(sec) : 0xff; + + rtc_control = CMOS_READ(RTC_CONTROL); + if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + /* Writing 0xff means "don't care" or "match all". */ + mon = (mon <= 12) ? bin2bcd(mon) : 0xff; + mday = (mday >= 1 && mday <= 31) ? bin2bcd(mday) : 0xff; + hrs = (hrs < 24) ? bin2bcd(hrs) : 0xff; + min = (min < 60) ? bin2bcd(min) : 0xff; + sec = (sec < 60) ? bin2bcd(sec) : 0xff; + } spin_lock_irq(&rtc_lock); @@ -478,7 +476,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq) "update_IRQ\t: %s\n" "HPET_emulated\t: %s\n" // "square_wave\t: %s\n" - // "BCD\t\t: %s\n" + "BCD\t\t: %s\n" "DST_enable\t: %s\n" "periodic_freq\t: %d\n" "batt_status\t: %s\n", @@ -486,7 +484,7 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq) (rtc_control & RTC_UIE) ? "yes" : "no", is_hpet_enabled() ? "yes" : "no", // (rtc_control & RTC_SQWE) ? "yes" : "no", - // (rtc_control & RTC_DM_BINARY) ? "no" : "yes", + (rtc_control & RTC_DM_BINARY) ? "no" : "yes", (rtc_control & RTC_DST_EN) ? "yes" : "no", cmos->rtc->irq_freq, (valid & RTC_VRT) ? "okay" : "dead"); @@ -751,12 +749,11 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) spin_unlock_irq(&rtc_lock); - /* FIXME teach the alarm code how to handle binary mode; + /* FIXME: * doesn't know 12-hour mode either. */ - if (is_valid_irq(rtc_irq) && - (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY)))) { - dev_dbg(dev, "only 24-hr BCD mode supported\n"); + if (is_valid_irq(rtc_irq) && !(rtc_control & RTC_24H)) { + dev_warn(dev, "only 24-hr supported\n"); retval = -ENXIO; goto cleanup1; } -- cgit v1.2.3 From 3322340a9db2251ac9d09bc7b8d49e872298ae95 Mon Sep 17 00:00:00 2001 From: Felix Radensky Date: Sun, 28 Mar 2010 16:02:02 +0300 Subject: PCI: Allow manual resource allocation for PCI hotplug bridges At the moment only PCI-E briges can be flagged as hotplug, thus allowing manual resource preallocation via pci=hpmemsize=nnM and pci=hpiosize=nnM kernel parameters. Some PCI hotplug bridges, e.g. PLX 6254 can also benefit from this functionalily, as kernel fails to properly allocate their resources when hotplug device is added and PCI bus is rescanned. This patch adds header quirk for PLX 6254 that marks this bridge as hotplug. Other PCI bridges with similar problems can use it as well. Signed-off-by: Felix Radensky Signed-off-by: Jesse Barnes --- drivers/pci/quirks.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index e5861d5a2e4d..b7512cf08c58 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2554,6 +2554,19 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1518, quirk_i82576_sriov); #endif /* CONFIG_PCI_IOV */ +/* Allow manual resource allocation for PCI hotplug bridges + * via pci=hpmemsize=nnM and pci=hpiosize=nnM parameters. For + * some PCI-PCI hotplug bridges, like PLX 6254 (former HINT HB6), + * kernel fails to allocate resources when hotplug device is + * inserted and PCI bus is rescanned. + */ +static void __devinit quirk_hotplug_bridge(struct pci_dev *dev) +{ + dev->is_hotplug_bridge = 1; +} + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HINT, 0x0020, quirk_hotplug_bridge); + /* * This is a quirk for the Ricoh MMC controller found as a part of * some mulifunction chips. -- cgit v1.2.3 From ac81860ea073daed50246af54db706c6e491f240 Mon Sep 17 00:00:00 2001 From: Praveen Kalamegham Date: Wed, 19 May 2010 17:03:12 -0500 Subject: PCI: hotplug: pciehp: Removed check for hotplug of display devices Removed check to prevent hotplug of display devices within pciehp. Originally this was thought to have been required within the PCI Hotplug specification for some legacy devices. However there is no such requirement in the most recent revision. The check prevents hotplug of not only display devices but also computational GPUs which require serviceability. Signed-off-by: Praveen Kalamegham Signed-off-by: Jesse Barnes --- drivers/pci/hotplug/pciehp_pci.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 0a16444c14c9..2fce726758d2 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -84,12 +84,6 @@ int pciehp_configure_device(struct slot *p_slot) dev = pci_get_slot(parent, PCI_DEVFN(0, fn)); if (!dev) continue; - if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { - ctrl_err(ctrl, "Cannot hot-add display device %s\n", - pci_name(dev)); - pci_dev_put(dev); - continue; - } if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { pciehp_add_bridge(dev); @@ -133,15 +127,9 @@ int pciehp_unconfigure_device(struct slot *p_slot) presence = 0; for (j = 0; j < 8; j++) { - struct pci_dev* temp = pci_get_slot(parent, PCI_DEVFN(0, j)); + struct pci_dev *temp = pci_get_slot(parent, PCI_DEVFN(0, j)); if (!temp) continue; - if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) { - ctrl_err(ctrl, "Cannot remove display device %s\n", - pci_name(temp)); - pci_dev_put(temp); - continue; - } if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl); if (bctl & PCI_BRIDGE_CTL_VGA) { @@ -149,7 +137,8 @@ int pciehp_unconfigure_device(struct slot *p_slot) "Cannot remove display device %s\n", pci_name(temp)); pci_dev_put(temp); - continue; + rc = EINVAL; + break; } } pci_remove_bus_device(temp); -- cgit v1.2.3 From 8018ab057480974e7f26a387bf4ce040e9a5f6f1 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 22 Mar 2010 17:32:25 +0100 Subject: sanitize vfs_fsync calling conventions Now that the last user passing a NULL file pointer is gone we can remove the redundant dentry argument and associated hacks inside vfs_fsynmc_range. The next step will be removig the dentry argument from ->fsync, but given the luck with the last round of method prototype changes I'd rather defer this until after the main merge window. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- drivers/block/loop.c | 4 ++-- drivers/md/bitmap.c | 2 +- drivers/usb/gadget/storage_common.c | 2 +- fs/ceph/file.c | 3 +-- fs/coda/file.c | 2 +- fs/ecryptfs/file.c | 4 +--- fs/nfsd/nfs4recover.c | 6 +++--- fs/nfsd/vfs.c | 5 ++--- fs/sync.c | 42 +++++++------------------------------ include/linux/fs.h | 6 +++--- mm/msync.c | 2 +- 11 files changed, 24 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/block/loop.c b/drivers/block/loop.c index a90e83c9be96..6120922f459f 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -485,7 +485,7 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) goto out; } - ret = vfs_fsync(file, file->f_path.dentry, 0); + ret = vfs_fsync(file, 0); if (unlikely(ret)) { ret = -EIO; goto out; @@ -495,7 +495,7 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) ret = lo_send(lo, bio, pos); if (barrier && !ret) { - ret = vfs_fsync(file, file->f_path.dentry, 0); + ret = vfs_fsync(file, 0); if (unlikely(ret)) ret = -EIO; } diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index f084249295d9..53e8bea295e2 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -1692,7 +1692,7 @@ int bitmap_create(mddev_t *mddev) * and bypass the page cache, we must sync the file * first. */ - vfs_fsync(file, file->f_dentry, 1); + vfs_fsync(file, 1); } /* read superblock from bitmap file (this sets mddev->bitmap_info.chunksize) */ if (!mddev->bitmap_info.external) diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 868d8ee86756..04c462ff0ea6 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -654,7 +654,7 @@ static int fsg_lun_fsync_sub(struct fsg_lun *curlun) if (curlun->ro || !filp) return 0; - return vfs_fsync(filp, filp->f_path.dentry, 1); + return vfs_fsync(filp, 1); } static void store_cdrom_address(u8 *dest, int msf, u32 addr) diff --git a/fs/ceph/file.c b/fs/ceph/file.c index ed6f19721d6e..7d634938edc9 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -844,8 +844,7 @@ retry_snap: if ((ret >= 0 || ret == -EIOCBQUEUED) && ((file->f_flags & O_SYNC) || IS_SYNC(file->f_mapping->host) || ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_NEARFULL))) { - err = vfs_fsync_range(file, file->f_path.dentry, - pos, pos + ret - 1, 1); + err = vfs_fsync_range(file, pos, pos + ret - 1, 1); if (err < 0) ret = err; } diff --git a/fs/coda/file.c b/fs/coda/file.c index 4c813f2cdc52..7196077b1688 100644 --- a/fs/coda/file.c +++ b/fs/coda/file.c @@ -217,7 +217,7 @@ int coda_fsync(struct file *coda_file, struct dentry *coda_dentry, int datasync) BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); host_file = cfi->cfi_container; - err = vfs_fsync(host_file, host_file->f_path.dentry, datasync); + err = vfs_fsync(host_file, datasync); if ( !err && !datasync ) { lock_kernel(); err = venus_fsync(coda_inode->i_sb, coda_i2f(coda_inode)); diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index e7440a6f5ebf..3bdddbcc785f 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c @@ -276,9 +276,7 @@ static int ecryptfs_release(struct inode *inode, struct file *file) static int ecryptfs_fsync(struct file *file, struct dentry *dentry, int datasync) { - return vfs_fsync(ecryptfs_file_to_lower(file), - ecryptfs_dentry_to_lower(dentry), - datasync); + return vfs_fsync(ecryptfs_file_to_lower(file), datasync); } static int ecryptfs_fasync(int fd, struct file *file, int flag) diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index dada03f2c13b..7e26caab2a26 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -158,7 +158,7 @@ out_unlock: mutex_unlock(&dir->d_inode->i_mutex); if (status == 0) { clp->cl_firststate = 1; - vfs_fsync(rec_file, rec_file->f_path.dentry, 0); + vfs_fsync(rec_file, 0); } nfs4_reset_creds(original_cred); dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status); @@ -288,7 +288,7 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp) status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1); nfs4_reset_creds(original_cred); if (status == 0) - vfs_fsync(rec_file, rec_file->f_path.dentry, 0); + vfs_fsync(rec_file, 0); mnt_drop_write(rec_file->f_path.mnt); out: if (status) @@ -325,7 +325,7 @@ nfsd4_recdir_purge_old(void) { goto out; status = nfsd4_list_rec_dir(rec_file->f_path.dentry, purge_old); if (status == 0) - vfs_fsync(rec_file, rec_file->f_path.dentry, 0); + vfs_fsync(rec_file, 0); mnt_drop_write(rec_file->f_path.mnt); out: if (status) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 23c06f77f4ca..ebbf3b6b2457 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -999,7 +999,7 @@ static int wait_for_concurrent_writes(struct file *file) if (inode->i_state & I_DIRTY) { dprintk("nfsd: write sync %d\n", task_pid_nr(current)); - err = vfs_fsync(file, file->f_path.dentry, 0); + err = vfs_fsync(file, 0); } last_ino = inode->i_ino; last_dev = inode->i_sb->s_dev; @@ -1175,8 +1175,7 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, if (err) goto out; if (EX_ISSYNC(fhp->fh_export)) { - int err2 = vfs_fsync_range(file, file->f_path.dentry, - offset, end, 0); + int err2 = vfs_fsync_range(file, offset, end, 0); if (err2 != -EINVAL) err = nfserrno(err2); diff --git a/fs/sync.c b/fs/sync.c index d5369203f8e4..5a537ccd2e85 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -158,7 +158,6 @@ EXPORT_SYMBOL(file_fsync); /** * vfs_fsync_range - helper to sync a range of data & metadata to disk * @file: file to sync - * @dentry: dentry of @file * @start: offset in bytes of the beginning of data range to sync * @end: offset in bytes of the end of data range (inclusive) * @datasync: perform only datasync @@ -166,32 +165,13 @@ EXPORT_SYMBOL(file_fsync); * Write back data in range @start..@end and metadata for @file to disk. If * @datasync is set only metadata needed to access modified file data is * written. - * - * In case this function is called from nfsd @file may be %NULL and - * only @dentry is set. This can only happen when the filesystem - * implements the export_operations API. */ -int vfs_fsync_range(struct file *file, struct dentry *dentry, loff_t start, - loff_t end, int datasync) +int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync) { - const struct file_operations *fop; - struct address_space *mapping; + struct address_space *mapping = file->f_mapping; int err, ret; - /* - * Get mapping and operations from the file in case we have - * as file, or get the default values for them in case we - * don't have a struct file available. Damn nfsd.. - */ - if (file) { - mapping = file->f_mapping; - fop = file->f_op; - } else { - mapping = dentry->d_inode->i_mapping; - fop = dentry->d_inode->i_fop; - } - - if (!fop || !fop->fsync) { + if (!file->f_op || !file->f_op->fsync) { ret = -EINVAL; goto out; } @@ -203,7 +183,7 @@ int vfs_fsync_range(struct file *file, struct dentry *dentry, loff_t start, * livelocks in fsync_buffers_list(). */ mutex_lock(&mapping->host->i_mutex); - err = fop->fsync(file, dentry, datasync); + err = file->f_op->fsync(file, file->f_path.dentry, datasync); if (!ret) ret = err; mutex_unlock(&mapping->host->i_mutex); @@ -216,19 +196,14 @@ EXPORT_SYMBOL(vfs_fsync_range); /** * vfs_fsync - perform a fsync or fdatasync on a file * @file: file to sync - * @dentry: dentry of @file * @datasync: only perform a fdatasync operation * * Write back data and metadata for @file to disk. If @datasync is * set only metadata needed to access modified file data is written. - * - * In case this function is called from nfsd @file may be %NULL and - * only @dentry is set. This can only happen when the filesystem - * implements the export_operations API. */ -int vfs_fsync(struct file *file, struct dentry *dentry, int datasync) +int vfs_fsync(struct file *file, int datasync) { - return vfs_fsync_range(file, dentry, 0, LLONG_MAX, datasync); + return vfs_fsync_range(file, 0, LLONG_MAX, datasync); } EXPORT_SYMBOL(vfs_fsync); @@ -239,7 +214,7 @@ static int do_fsync(unsigned int fd, int datasync) file = fget(fd); if (file) { - ret = vfs_fsync(file, file->f_path.dentry, datasync); + ret = vfs_fsync(file, datasync); fput(file); } return ret; @@ -267,8 +242,7 @@ int generic_write_sync(struct file *file, loff_t pos, loff_t count) { if (!(file->f_flags & O_DSYNC) && !IS_SYNC(file->f_mapping->host)) return 0; - return vfs_fsync_range(file, file->f_path.dentry, pos, - pos + count - 1, + return vfs_fsync_range(file, pos, pos + count - 1, (file->f_flags & __O_SYNC) ? 0 : 1); } EXPORT_SYMBOL(generic_write_sync); diff --git a/include/linux/fs.h b/include/linux/fs.h index 6660db898c41..f3e108314c93 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2084,9 +2084,9 @@ extern int __filemap_fdatawrite_range(struct address_space *mapping, extern int filemap_fdatawrite_range(struct address_space *mapping, loff_t start, loff_t end); -extern int vfs_fsync_range(struct file *file, struct dentry *dentry, - loff_t start, loff_t end, int datasync); -extern int vfs_fsync(struct file *file, struct dentry *dentry, int datasync); +extern int vfs_fsync_range(struct file *file, loff_t start, loff_t end, + int datasync); +extern int vfs_fsync(struct file *file, int datasync); extern int generic_write_sync(struct file *file, loff_t pos, loff_t count); extern void sync_supers(void); extern void emergency_sync(void); diff --git a/mm/msync.c b/mm/msync.c index 4083209b7f02..632df4527c01 100644 --- a/mm/msync.c +++ b/mm/msync.c @@ -82,7 +82,7 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags) (vma->vm_flags & VM_SHARED)) { get_file(file); up_read(&mm->mmap_sem); - error = vfs_fsync(file, file->f_path.dentry, 0); + error = vfs_fsync(file, 0); fput(file); if (error || start >= end) goto out; -- cgit v1.2.3 From 34a18d6fe5430184e4ca96eeb074ee671d89fe7b Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 21 May 2010 19:40:02 -0400 Subject: ACPI: delete unused c-state promotion/demotion data strucutures These were used before cpuidle by the native ACPI idle driver, which tracked promotion and demotion between states. The code was referenced by CONFIG_ACPI_PROCFS for /proc/acpi/processor/*/power, but as we no longer do promotion/demotion, that reference has been a NOP since the transition. Signed-off-by: Len Brown --- drivers/acpi/processor_idle.c | 16 +++------------- include/acpi/processor.h | 13 ------------- 2 files changed, 3 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 5939e7f7d8e9..63a3d4b8c238 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -727,19 +727,9 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) break; } - if (pr->power.states[i].promotion.state) - seq_printf(seq, "promotion[C%zd] ", - (pr->power.states[i].promotion.state - - pr->power.states)); - else - seq_puts(seq, "promotion[--] "); - - if (pr->power.states[i].demotion.state) - seq_printf(seq, "demotion[C%zd] ", - (pr->power.states[i].demotion.state - - pr->power.states)); - else - seq_puts(seq, "demotion[--] "); + seq_puts(seq, "promotion[--] "); + + seq_puts(seq, "demotion[--] "); seq_printf(seq, "latency[%03d] usage[%08d] duration[%020llu]\n", pr->power.states[i].latency, diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 86825ddbe14e..da565a48240e 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -52,17 +52,6 @@ struct acpi_power_register { u64 address; } __attribute__ ((packed)); -struct acpi_processor_cx_policy { - u32 count; - struct acpi_processor_cx *state; - struct { - u32 time; - u32 ticks; - u32 count; - u32 bm; - } threshold; -}; - struct acpi_processor_cx { u8 valid; u8 type; @@ -74,8 +63,6 @@ struct acpi_processor_cx { u32 power; u32 usage; u64 time; - struct acpi_processor_cx_policy promotion; - struct acpi_processor_cx_policy demotion; char desc[ACPI_CX_DESC_LEN]; }; -- cgit v1.2.3 From f4b87dee923342505e1ddba8d34ce9de33e75050 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 21 May 2010 12:44:47 -0700 Subject: fbmem: avoid printk format warning with 32-bit resources Fix printk formats: drivers/video/fbmem.c: In function 'fb_do_apertures_overlap': drivers/video/fbmem.c:1494: warning: format '%llx' expects type 'long long unsigned int', but argument 2 has type 'resource_size_t' drivers/video/fbmem.c:1494: warning: format '%llx' expects type 'long long unsigned int', but argument 3 has type 'resource_size_t' drivers/video/fbmem.c:1494: warning: format '%llx' expects type 'long long unsigned int', but argument 4 has type 'resource_size_t' drivers/video/fbmem.c:1494: warning: format '%llx' expects type 'long long unsigned int', but argument 5 has type 'resource_size_t' Signed-off-by: Randy Dunlap Signed-off-by: Linus Torvalds --- drivers/video/fbmem.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index e08b7b5cb326..731fce64df9d 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1491,7 +1491,10 @@ static bool fb_do_apertures_overlap(struct apertures_struct *gena, for (j = 0; j < gena->count; ++j) { struct aperture *g = &gena->ranges[j]; printk(KERN_DEBUG "checking generic (%llx %llx) vs hw (%llx %llx)\n", - g->base, g->size, h->base, h->size); + (unsigned long long)g->base, + (unsigned long long)g->size, + (unsigned long long)h->base, + (unsigned long long)h->size); if (apertures_overlap(g, h)) return true; } -- cgit v1.2.3 From cb6dc512b745292eaf123fedf437c211e27fb680 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:12:59 -0700 Subject: arch/powerpc: Move dma_mask from of_device into pdev_archdata By moving dma_mask into pdev_archdata, and adding archdata to struct of_device, it makes it possible to substitute of_device with struct platform_device, which is a stepping stone to removing the of_platform bus entirely. Signed-off-by: Grant Likely --- arch/powerpc/include/asm/device.h | 1 + arch/powerpc/include/asm/of_device.h | 2 +- arch/powerpc/kernel/of_device.c | 2 +- arch/powerpc/kernel/of_platform.c | 2 +- drivers/macintosh/macio_asic.c | 4 ++-- sound/aoa/soundbus/i2sbus/core.c | 4 ++-- 6 files changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h index f23f8d8bd68d..a3954e4fcbe2 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h @@ -28,6 +28,7 @@ struct dev_archdata { }; struct pdev_archdata { + u64 dma_mask; }; #endif /* _ASM_POWERPC_DEVICE_H */ diff --git a/arch/powerpc/include/asm/of_device.h b/arch/powerpc/include/asm/of_device.h index 8b26f96b9f9e..444e97e2982e 100644 --- a/arch/powerpc/include/asm/of_device.h +++ b/arch/powerpc/include/asm/of_device.h @@ -12,8 +12,8 @@ */ struct of_device { - u64 dma_mask; /* DMA mask */ struct device dev; /* Generic device interface */ + struct pdev_archdata archdata; }; extern struct of_device *of_device_alloc(struct device_node *np, diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index 20b3474b6f6b..df78e0236a02 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c @@ -70,7 +70,7 @@ struct of_device *of_device_alloc(struct device_node *np, return NULL; dev->dev.of_node = of_node_get(np); - dev->dev.dma_mask = &dev->dma_mask; + dev->dev.dma_mask = &dev->archdata.dma_mask; dev->dev.parent = parent; dev->dev.release = of_release_dev; diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 1c747c474415..218853466510 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -74,7 +74,7 @@ struct of_device* of_platform_device_create(struct device_node *np, if (!dev) return NULL; - dev->dma_mask = 0xffffffffUL; + dev->archdata.dma_mask = 0xffffffffUL; dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); dev->dev.bus = &of_platform_bus_type; diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 67fe13ffe90b..48a5f0406865 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -374,8 +374,8 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, dev->bus = &chip->lbus; dev->media_bay = in_bay; dev->ofdev.dev.of_node = np; - dev->ofdev.dma_mask = 0xffffffffUL; - dev->ofdev.dev.dma_mask = &dev->ofdev.dma_mask; + dev->ofdev.archdata.dma_mask = 0xffffffffUL; + dev->ofdev.dev.dma_mask = &dev->ofdev.archdata.dma_mask; dev->ofdev.dev.parent = parent; dev->ofdev.dev.bus = &macio_bus_type; dev->ofdev.dev.release = macio_release_dev; diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c index 7672b4d145ae..678933721735 100644 --- a/sound/aoa/soundbus/i2sbus/core.c +++ b/sound/aoa/soundbus/i2sbus/core.c @@ -221,9 +221,9 @@ static int i2sbus_add_dev(struct macio_dev *macio, mutex_init(&dev->lock); spin_lock_init(&dev->low_lock); - dev->sound.ofdev.dma_mask = macio->ofdev.dma_mask; + dev->sound.ofdev.archdata.dma_mask = macio->ofdev.archdata.dma_mask; dev->sound.ofdev.dev.of_node = np; - dev->sound.ofdev.dev.dma_mask = &dev->sound.ofdev.dma_mask; + dev->sound.ofdev.dev.dma_mask = &dev->sound.ofdev.archdata.dma_mask; dev->sound.ofdev.dev.parent = &macio->ofdev.dev; dev->sound.ofdev.dev.release = i2sbus_release_dev; dev->sound.attach_codec = i2sbus_attach_codec; -- cgit v1.2.3 From 597b9d1e44e9ba69f2454a5318bbe7a6d5e6930a Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:13:01 -0700 Subject: drivercore: Add of_match_table to the common device drivers OF-style matching can be available to any device, on any type of bus. This patch allows any driver to provide an OF match table when CONFIG_OF is enabled so that drivers can be bound against devices described in the device tree. Signed-off-by: Grant Likely Acked-by: Greg Kroah-Hartman --- arch/powerpc/kernel/ibmebus.c | 5 ++++- drivers/macintosh/macio_asic.c | 5 ++--- drivers/of/platform.c | 7 ++++--- include/linux/device.h | 4 ++++ 4 files changed, 14 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index a9f31631a293..355257bb149d 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -201,8 +201,11 @@ static int ibmebus_create_devices(const struct of_device_id *matches) int ibmebus_register_driver(struct of_platform_driver *drv) { + if (!drv->driver.of_match_table) + drv->driver.of_match_table = drv->match_table; + /* If the driver uses devices that ibmebus doesn't know, add them */ - ibmebus_create_devices(drv->match_table); + ibmebus_create_devices(drv->driver.of_match_table); return of_register_driver(drv, &ibmebus_bus_type); } diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 48a5f0406865..e3ba1d8001a3 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -40,8 +40,7 @@ static struct macio_chip *macio_on_hold; static int macio_bus_match(struct device *dev, struct device_driver *drv) { struct macio_dev * macio_dev = to_macio_device(dev); - struct macio_driver * macio_drv = to_macio_driver(drv); - const struct of_device_id * matches = macio_drv->match_table; + const struct of_device_id * matches = drv->of_match_table; if (!matches) return 0; @@ -84,7 +83,7 @@ static int macio_device_probe(struct device *dev) macio_dev_get(macio_dev); - match = of_match_device(drv->match_table, &macio_dev->ofdev); + match = of_match_device(drv->driver.of_match_table, &macio_dev->ofdev); if (match) error = drv->probe(macio_dev, match); if (error) diff --git a/drivers/of/platform.c b/drivers/of/platform.c index d58ade170c4b..9fd7f7d0a0d1 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -22,8 +22,7 @@ extern struct device_attribute of_platform_device_attrs[]; static int of_platform_bus_match(struct device *dev, struct device_driver *drv) { struct of_device *of_dev = to_of_device(dev); - struct of_platform_driver *of_drv = to_of_platform_driver(drv); - const struct of_device_id *matches = of_drv->match_table; + const struct of_device_id *matches = drv->of_match_table; if (!matches) return 0; @@ -46,7 +45,7 @@ static int of_platform_device_probe(struct device *dev) of_dev_get(of_dev); - match = of_match_device(drv->match_table, of_dev); + match = of_match_device(drv->driver.of_match_table, of_dev); if (match) error = drv->probe(of_dev, match); if (error) @@ -391,6 +390,8 @@ int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) drv->driver.name = drv->name; if (!drv->driver.owner) drv->driver.owner = drv->owner; + if (!drv->driver.of_match_table) + drv->driver.of_match_table = drv->match_table; drv->driver.bus = bus; /* register with core */ diff --git a/include/linux/device.h b/include/linux/device.h index 7a968bdb02e2..cd7534cc42ab 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -129,6 +129,10 @@ struct device_driver { bool suppress_bind_attrs; /* disables bind/unbind via sysfs */ +#if defined(CONFIG_OF) + const struct of_device_id *of_match_table; +#endif + int (*probe) (struct device *dev); int (*remove) (struct device *dev); void (*shutdown) (struct device *dev); -- cgit v1.2.3 From 4018294b53d1dae026880e45f174c1cc63b5d435 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:13:02 -0700 Subject: of: Remove duplicate fields from of_platform_driver .name, .match_table and .owner are duplicated in both of_platform_driver and device_driver. This patch is a removes the extra copies from struct of_platform_driver and converts all users to the device_driver members. This patch is a pretty mechanical change. The usage model doesn't change and if any drivers have been missed, or if anything has been fixed up incorrectly, then it will fail with a compile time error, and the fixup will be trivial. This patch looks big and scary because it touches so many files, but it should be pretty safe. Signed-off-by: Grant Likely Acked-by: Sean MacLennan --- arch/powerpc/kernel/ibmebus.c | 3 --- arch/powerpc/kernel/of_platform.c | 3 ++- arch/powerpc/platforms/52xx/mpc52xx_gpio.c | 14 +++++++++---- arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 7 +++++-- arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c | 8 ++++--- arch/powerpc/platforms/82xx/ep8248e.c | 3 ++- arch/powerpc/platforms/83xx/suspend.c | 7 +++++-- arch/powerpc/platforms/cell/axon_msi.c | 7 ++++--- arch/powerpc/platforms/pasemi/gpio_mdio.c | 7 ++++--- arch/powerpc/sysdev/axonram.c | 8 +++---- arch/powerpc/sysdev/bestcomm/bestcomm.c | 10 ++++----- arch/powerpc/sysdev/fsl_msi.c | 7 +++++-- arch/powerpc/sysdev/fsl_pmc.c | 7 +++++-- arch/powerpc/sysdev/fsl_rio.c | 7 +++++-- arch/powerpc/sysdev/pmi.c | 7 ++++--- arch/powerpc/sysdev/qe_lib/qe.c | 7 +++++-- arch/sparc/include/asm/parport.h | 7 +++++-- arch/sparc/kernel/apc.c | 7 +++++-- arch/sparc/kernel/auxio_64.c | 7 ++++--- arch/sparc/kernel/central.c | 14 +++++++------ arch/sparc/kernel/chmc.c | 7 +++++-- arch/sparc/kernel/pci_fire.c | 7 +++++-- arch/sparc/kernel/pci_psycho.c | 7 +++++-- arch/sparc/kernel/pci_sabre.c | 7 +++++-- arch/sparc/kernel/pci_schizo.c | 7 +++++-- arch/sparc/kernel/pci_sun4v.c | 7 +++++-- arch/sparc/kernel/pmc.c | 7 +++++-- arch/sparc/kernel/power.c | 7 ++++--- arch/sparc/kernel/time_32.c | 7 ++++--- arch/sparc/kernel/time_64.c | 21 +++++++++++-------- drivers/ata/pata_mpc52xx.c | 4 +--- drivers/ata/pata_of_platform.c | 7 +++++-- drivers/ata/sata_fsl.c | 7 +++++-- drivers/atm/fore200e.c | 7 +++++-- drivers/block/xsysace.c | 5 ++--- drivers/char/hw_random/n2-drv.c | 7 +++++-- drivers/char/hw_random/pasemi-rng.c | 7 +++++-- drivers/char/ipmi/ipmi_si_intf.c | 7 +++++-- drivers/char/xilinx_hwicap/xilinx_hwicap.c | 5 ++--- drivers/crypto/amcc/crypto4xx_core.c | 7 +++++-- drivers/crypto/talitos.c | 7 +++++-- drivers/dma/fsldma.c | 11 ++++++---- drivers/dma/ppc4xx/adma.c | 2 +- drivers/edac/mpc85xx_edac.c | 30 +++++++++++---------------- drivers/edac/ppc4xx_edac.c | 10 ++++----- drivers/hwmon/ultra45_env.c | 7 +++++-- drivers/i2c/busses/i2c-cpm.c | 10 ++++----- drivers/i2c/busses/i2c-ibm_iic.c | 7 +++++-- drivers/i2c/busses/i2c-mpc.c | 8 +++---- drivers/infiniband/hw/ehca/ehca_main.c | 7 ++++--- drivers/input/misc/sparcspkr.c | 14 +++++++++---- drivers/input/serio/i8042-sparcio.h | 7 +++++-- drivers/input/serio/xilinx_ps2.c | 7 +++++-- drivers/leds/leds-gpio.c | 2 +- drivers/macintosh/smu.c | 7 +++++-- drivers/macintosh/therm_pm72.c | 7 +++++-- drivers/macintosh/therm_windtunnel.c | 7 +++++-- drivers/mmc/host/sdhci-of-core.c | 7 +++++-- drivers/mtd/maps/physmap_of.c | 7 +++++-- drivers/mtd/maps/sun_uflash.c | 7 +++++-- drivers/mtd/nand/fsl_elbc_nand.c | 5 +++-- drivers/mtd/nand/fsl_upm.c | 7 +++++-- drivers/mtd/nand/ndfc.c | 5 +++-- drivers/mtd/nand/pasemi_nand.c | 7 +++++-- drivers/mtd/nand/socrates_nand.c | 7 +++++-- drivers/net/can/mscan/mpc5xxx_can.c | 8 ++++--- drivers/net/can/sja1000/sja1000_of_platform.c | 8 ++++--- drivers/net/ehea/ehea_main.c | 7 +++++-- drivers/net/fec_mpc52xx.c | 8 ++++--- drivers/net/fec_mpc52xx_phy.c | 7 +++++-- drivers/net/fs_enet/fs_enet-main.c | 7 +++++-- drivers/net/fs_enet/mii-bitbang.c | 7 +++++-- drivers/net/fs_enet/mii-fec.c | 7 +++++-- drivers/net/fsl_pq_mdio.c | 7 +++++-- drivers/net/gianfar.c | 10 +++++---- drivers/net/ibm_newemac/core.c | 8 ++++--- drivers/net/ibm_newemac/mal.c | 8 ++++--- drivers/net/ibm_newemac/rgmii.c | 8 ++++--- drivers/net/ibm_newemac/tah.c | 8 ++++--- drivers/net/ibm_newemac/zmii.c | 8 ++++--- drivers/net/ll_temac_main.c | 2 +- drivers/net/myri_sbus.c | 7 +++++-- drivers/net/niu.c | 7 +++++-- drivers/net/phy/mdio-gpio.c | 7 +++++-- drivers/net/sunbmac.c | 7 +++++-- drivers/net/sunhme.c | 7 +++++-- drivers/net/sunlance.c | 7 +++++-- drivers/net/sunqe.c | 7 +++++-- drivers/net/ucc_geth.c | 7 +++++-- drivers/net/xilinx_emaclite.c | 7 +++++-- drivers/of/platform.c | 7 ------- drivers/parport/parport_sunbpp.c | 7 +++++-- drivers/pcmcia/electra_cf.c | 7 +++++-- drivers/pcmcia/m8xx_pcmcia.c | 7 +++++-- drivers/sbus/char/bbc_i2c.c | 7 +++++-- drivers/sbus/char/display7seg.c | 7 +++++-- drivers/sbus/char/envctrl.c | 7 +++++-- drivers/sbus/char/flash.c | 7 +++++-- drivers/sbus/char/uctrl.c | 7 +++++-- drivers/scsi/qlogicpti.c | 7 +++++-- drivers/scsi/sun_esp.c | 7 +++++-- drivers/serial/apbuart.c | 8 +++---- drivers/serial/cpm_uart/cpm_uart_core.c | 7 +++++-- drivers/serial/mpc52xx_uart.c | 7 ++++--- drivers/serial/of_serial.c | 8 ++++--- drivers/serial/sunhv.c | 7 +++++-- drivers/serial/sunsab.c | 7 +++++-- drivers/serial/sunsu.c | 7 +++++-- drivers/serial/sunzilog.c | 7 +++++-- drivers/serial/uartlite.c | 5 ++--- drivers/serial/ucc_uart.c | 8 ++++--- drivers/spi/mpc52xx_psc_spi.c | 4 +--- drivers/spi/mpc52xx_spi.c | 8 ++++--- drivers/spi/spi_mpc8xxx.c | 7 +++++-- drivers/spi/spi_ppc4xx.c | 2 +- drivers/spi/xilinx_spi_of.c | 2 +- drivers/usb/gadget/fsl_qe_udc.c | 7 +++++-- drivers/usb/host/ehci-ppc-of.c | 9 ++++---- drivers/usb/host/ehci-xilinx-of.c | 9 ++++---- drivers/usb/host/fhci-hcd.c | 7 +++++-- drivers/usb/host/isp1760-if.c | 7 +++++-- drivers/usb/host/ohci-ppc-of.c | 13 ++++-------- drivers/video/bw2.c | 7 +++++-- drivers/video/cg14.c | 7 +++++-- drivers/video/cg3.c | 7 +++++-- drivers/video/cg6.c | 7 +++++-- drivers/video/ffb.c | 7 +++++-- drivers/video/fsl-diu-fb.c | 8 ++++--- drivers/video/leo.c | 7 +++++-- drivers/video/mb862xx/mb862xxfb.c | 8 ++++--- drivers/video/p9100.c | 7 +++++-- drivers/video/platinumfb.c | 7 +++++-- drivers/video/sunxvr1000.c | 7 +++++-- drivers/video/tcx.c | 7 +++++-- drivers/video/xilinxfb.c | 5 ++--- drivers/watchdog/cpwd.c | 7 +++++-- drivers/watchdog/gef_wdt.c | 8 ++++--- drivers/watchdog/mpc8xxx_wdt.c | 8 +++---- drivers/watchdog/riowd.c | 7 +++++-- include/linux/of_platform.h | 4 ---- sound/soc/fsl/mpc5200_psc_ac97.c | 2 +- sound/soc/fsl/mpc5200_psc_i2s.c | 2 +- sound/soc/fsl/mpc8610_hpcd.c | 8 ++++--- sound/sparc/amd7930.c | 7 +++++-- sound/sparc/cs4231.c | 7 +++++-- sound/sparc/dbri.c | 7 +++++-- 146 files changed, 671 insertions(+), 387 deletions(-) (limited to 'drivers') diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 355257bb149d..21266abfbda6 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -201,9 +201,6 @@ static int ibmebus_create_devices(const struct of_device_id *matches) int ibmebus_register_driver(struct of_platform_driver *drv) { - if (!drv->driver.of_match_table) - drv->driver.of_match_table = drv->match_table; - /* If the driver uses devices that ibmebus doesn't know, add them */ ibmebus_create_devices(drv->driver.of_match_table); diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 218853466510..487a98851ba6 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -306,10 +306,11 @@ static struct of_device_id of_pci_phb_ids[] = { }; static struct of_platform_driver of_pci_phb_driver = { - .match_table = of_pci_phb_ids, .probe = of_pci_phb_probe, .driver = { .name = "of-pci", + .owner = THIS_MODULE, + .of_match_table = of_pci_phb_ids, }, }; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c index 576669fc4fbf..ca5305a5bd61 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c @@ -193,8 +193,11 @@ static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = { }; static struct of_platform_driver mpc52xx_wkup_gpiochip_driver = { - .name = "gpio_wkup", - .match_table = mpc52xx_wkup_gpiochip_match, + .driver = { + .name = "gpio_wkup", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_wkup_gpiochip_match, + }, .probe = mpc52xx_wkup_gpiochip_probe, .remove = mpc52xx_gpiochip_remove, }; @@ -349,8 +352,11 @@ static const struct of_device_id mpc52xx_simple_gpiochip_match[] = { }; static struct of_platform_driver mpc52xx_simple_gpiochip_driver = { - .name = "gpio", - .match_table = mpc52xx_simple_gpiochip_match, + .driver = { + .name = "gpio", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_simple_gpiochip_match, + }, .probe = mpc52xx_simple_gpiochip_probe, .remove = mpc52xx_gpiochip_remove, }; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index 42c507f9c35b..46c93578cbf0 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -784,8 +784,11 @@ static const struct of_device_id mpc52xx_gpt_match[] = { }; static struct of_platform_driver mpc52xx_gpt_driver = { - .name = "mpc52xx-gpt", - .match_table = mpc52xx_gpt_match, + .driver = { + .name = "mpc52xx-gpt", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_gpt_match, + }, .probe = mpc52xx_gpt_probe, .remove = mpc52xx_gpt_remove, }; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c index 17b99ba7a8cc..e86aec644501 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c @@ -537,9 +537,11 @@ static struct of_device_id mpc52xx_lpbfifo_match[] __devinitconst = { }; static struct of_platform_driver mpc52xx_lpbfifo_driver = { - .owner = THIS_MODULE, - .name = "mpc52xx-lpbfifo", - .match_table = mpc52xx_lpbfifo_match, + .driver = { + .name = "mpc52xx-lpbfifo", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_lpbfifo_match, + }, .probe = mpc52xx_lpbfifo_probe, .remove = __devexit_p(mpc52xx_lpbfifo_remove), }; diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c index 0176ae8249d5..9f2e52b36f91 100644 --- a/arch/powerpc/platforms/82xx/ep8248e.c +++ b/arch/powerpc/platforms/82xx/ep8248e.c @@ -170,8 +170,9 @@ static const struct of_device_id ep8248e_mdio_match[] = { static struct of_platform_driver ep8248e_mdio_driver = { .driver = { .name = "ep8248e-mdio-bitbang", + .owner = THIS_MODULE, + .of_match_table = ep8248e_mdio_match, }, - .match_table = ep8248e_mdio_match, .probe = ep8248e_mdio_probe, .remove = ep8248e_mdio_remove, }; diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index aa0b764b1cc4..ebe6c3537209 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c @@ -423,8 +423,11 @@ static struct of_device_id pmc_match[] = { }; static struct of_platform_driver pmc_driver = { - .name = "mpc83xx-pmc", - .match_table = pmc_match, + .driver = { + .name = "mpc83xx-pmc", + .owner = THIS_MODULE, + .of_match_table = pmc_match, + }, .probe = pmc_probe, .remove = pmc_remove }; diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 177a4f1369b4..6257e5378615 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -447,11 +447,12 @@ static const struct of_device_id axon_msi_device_id[] = { }; static struct of_platform_driver axon_msi_driver = { - .match_table = axon_msi_device_id, .probe = axon_msi_probe, .shutdown = axon_msi_shutdown, - .driver = { - .name = "axon-msi" + .driver = { + .name = "axon-msi", + .owner = THIS_MODULE, + .of_match_table = axon_msi_device_id, }, }; diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c index c44e1b3b91db..627ee089e75d 100644 --- a/arch/powerpc/platforms/pasemi/gpio_mdio.c +++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c @@ -301,11 +301,12 @@ MODULE_DEVICE_TABLE(of, gpio_mdio_match); static struct of_platform_driver gpio_mdio_driver = { - .match_table = gpio_mdio_match, .probe = gpio_mdio_probe, .remove = gpio_mdio_remove, - .driver = { - .name = "gpio-mdio-bitbang", + .driver = { + .name = "gpio-mdio-bitbang", + .owner = THIS_MODULE, + .of_match_table = gpio_mdio_match, }, }; diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c index 88b21fccf0c9..402d2212162f 100644 --- a/arch/powerpc/sysdev/axonram.c +++ b/arch/powerpc/sysdev/axonram.c @@ -327,12 +327,12 @@ static struct of_device_id axon_ram_device_id[] = { }; static struct of_platform_driver axon_ram_driver = { - .match_table = axon_ram_device_id, .probe = axon_ram_probe, .remove = axon_ram_remove, - .driver = { - .owner = THIS_MODULE, - .name = AXON_RAM_MODULE_NAME, + .driver = { + .name = AXON_RAM_MODULE_NAME, + .owner = THIS_MODULE, + .of_match_table = axon_ram_device_id, }, }; diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c index d32d5389b67a..a7c5c470af14 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm.c +++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c @@ -494,14 +494,12 @@ MODULE_DEVICE_TABLE(of, mpc52xx_bcom_of_match); static struct of_platform_driver mpc52xx_bcom_of_platform_driver = { - .owner = THIS_MODULE, - .name = DRIVER_NAME, - .match_table = mpc52xx_bcom_of_match, .probe = mpc52xx_bcom_probe, .remove = mpc52xx_bcom_remove, - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = mpc52xx_bcom_of_match, }, }; diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 569dae8ea1ce..a7be144f5874 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -345,8 +345,11 @@ static const struct of_device_id fsl_of_msi_ids[] = { }; static struct of_platform_driver fsl_of_msi_driver = { - .name = "fsl-msi", - .match_table = fsl_of_msi_ids, + .driver = { + .name = "fsl-msi", + .owner = THIS_MODULE, + .of_match_table = fsl_of_msi_ids, + }, .probe = fsl_of_msi_probe, }; diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index 2ebe817ca72f..9082eb921ad9 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c @@ -76,8 +76,11 @@ static const struct of_device_id pmc_ids[] = { }; static struct of_platform_driver pmc_driver = { - .driver.name = "fsl-pmc", - .match_table = pmc_ids, + .driver = { + .name = "fsl-pmc", + .owner = THIS_MODULE, + .of_match_table = pmc_ids, + }, .probe = pmc_probe, }; diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index a98d51639243..6a1fde0d22b0 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -1215,8 +1215,11 @@ static const struct of_device_id fsl_of_rio_rpn_ids[] = { }; static struct of_platform_driver fsl_of_rio_rpn_driver = { - .name = "fsl-of-rio", - .match_table = fsl_of_rio_rpn_ids, + .driver = { + .name = "fsl-of-rio", + .owner = THIS_MODULE, + .of_match_table = fsl_of_rio_rpn_ids, + }, .probe = fsl_of_rio_rpn_probe, }; diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c index ff758bff1b7a..d07137a07d75 100644 --- a/arch/powerpc/sysdev/pmi.c +++ b/arch/powerpc/sysdev/pmi.c @@ -206,11 +206,12 @@ static int pmi_of_remove(struct of_device *dev) } static struct of_platform_driver pmi_of_platform_driver = { - .match_table = pmi_match, .probe = pmi_of_probe, .remove = pmi_of_remove, - .driver = { - .name = "pmi", + .driver = { + .name = "pmi", + .owner = THIS_MODULE, + .of_match_table = pmi_match, }, }; diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 149393c02c3f..093e0ae1a941 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c @@ -669,8 +669,11 @@ static const struct of_device_id qe_ids[] = { }; static struct of_platform_driver qe_driver = { - .driver.name = "fsl-qe", - .match_table = qe_ids, + .driver = { + .name = "fsl-qe", + .owner = THIS_MODULE, + .of_match_table = qe_ids, + }, .probe = qe_probe, .resume = qe_resume, }; diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h index 1bb6a41b00f2..c333b8d0949b 100644 --- a/arch/sparc/include/asm/parport.h +++ b/arch/sparc/include/asm/parport.h @@ -232,8 +232,11 @@ static const struct of_device_id ecpp_match[] = { }; static struct of_platform_driver ecpp_driver = { - .name = "ecpp", - .match_table = ecpp_match, + .driver = { + .name = "ecpp", + .owner = THIS_MODULE, + .of_match_table = ecpp_match, + }, .probe = ecpp_probe, .remove = __devexit_p(ecpp_remove), }; diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c index 71ec90b9e316..b27476caa133 100644 --- a/arch/sparc/kernel/apc.c +++ b/arch/sparc/kernel/apc.c @@ -174,8 +174,11 @@ static struct of_device_id __initdata apc_match[] = { MODULE_DEVICE_TABLE(of, apc_match); static struct of_platform_driver apc_driver = { - .name = "apc", - .match_table = apc_match, + .driver = { + .name = "apc", + .owner = THIS_MODULE, + .of_match_table = apc_match, + }, .probe = apc_probe, }; diff --git a/arch/sparc/kernel/auxio_64.c b/arch/sparc/kernel/auxio_64.c index bd8421a26856..ddc84128b3c2 100644 --- a/arch/sparc/kernel/auxio_64.c +++ b/arch/sparc/kernel/auxio_64.c @@ -132,10 +132,11 @@ static int __devinit auxio_probe(struct of_device *dev, const struct of_device_i } static struct of_platform_driver auxio_driver = { - .match_table = auxio_match, .probe = auxio_probe, - .driver = { - .name = "auxio", + .driver = { + .name = "auxio", + .owner = THIS_MODULE, + .of_match_table = auxio_match, }, }; diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index d533f3d5d484..434335f65823 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c @@ -149,10 +149,11 @@ static struct of_device_id __initdata clock_board_match[] = { }; static struct of_platform_driver clock_board_driver = { - .match_table = clock_board_match, .probe = clock_board_probe, - .driver = { - .name = "clock_board", + .driver = { + .name = "clock_board", + .owner = THIS_MODULE, + .of_match_table = clock_board_match, }, }; @@ -254,10 +255,11 @@ static struct of_device_id __initdata fhc_match[] = { }; static struct of_platform_driver fhc_driver = { - .match_table = fhc_match, .probe = fhc_probe, - .driver = { - .name = "fhc", + .driver = { + .name = "fhc", + .owner = THIS_MODULE, + .of_match_table = fhc_match, }, }; diff --git a/arch/sparc/kernel/chmc.c b/arch/sparc/kernel/chmc.c index 936879639eb6..870cb65b3f21 100644 --- a/arch/sparc/kernel/chmc.c +++ b/arch/sparc/kernel/chmc.c @@ -811,8 +811,11 @@ static const struct of_device_id us3mc_match[] = { MODULE_DEVICE_TABLE(of, us3mc_match); static struct of_platform_driver us3mc_driver = { - .name = "us3mc", - .match_table = us3mc_match, + .driver = { + .name = "us3mc", + .owner = THIS_MODULE, + .of_match_table = us3mc_match, + }, .probe = us3mc_probe, .remove = __devexit_p(us3mc_remove), }; diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c index ff844baa28e6..51cfa09e392a 100644 --- a/arch/sparc/kernel/pci_fire.c +++ b/arch/sparc/kernel/pci_fire.c @@ -508,8 +508,11 @@ static struct of_device_id __initdata fire_match[] = { }; static struct of_platform_driver fire_driver = { - .name = DRIVER_NAME, - .match_table = fire_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = fire_match, + }, .probe = fire_probe, }; diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c index e675e21c6df6..558a70512824 100644 --- a/arch/sparc/kernel/pci_psycho.c +++ b/arch/sparc/kernel/pci_psycho.c @@ -602,8 +602,11 @@ static struct of_device_id __initdata psycho_match[] = { }; static struct of_platform_driver psycho_driver = { - .name = DRIVER_NAME, - .match_table = psycho_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = psycho_match, + }, .probe = psycho_probe, }; diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c index 5048498daade..6dad8e3b7506 100644 --- a/arch/sparc/kernel/pci_sabre.c +++ b/arch/sparc/kernel/pci_sabre.c @@ -596,8 +596,11 @@ static struct of_device_id __initdata sabre_match[] = { }; static struct of_platform_driver sabre_driver = { - .name = DRIVER_NAME, - .match_table = sabre_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = sabre_match, + }, .probe = sabre_probe, }; diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c index 2f3f9212b063..97a1ae2e1c02 100644 --- a/arch/sparc/kernel/pci_schizo.c +++ b/arch/sparc/kernel/pci_schizo.c @@ -1491,8 +1491,11 @@ static struct of_device_id __initdata schizo_match[] = { }; static struct of_platform_driver schizo_driver = { - .name = DRIVER_NAME, - .match_table = schizo_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = schizo_match, + }, .probe = schizo_probe, }; diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 5c11f56cedf8..a24af6f7e17f 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -1009,8 +1009,11 @@ static struct of_device_id __initdata pci_sun4v_match[] = { }; static struct of_platform_driver pci_sun4v_driver = { - .name = DRIVER_NAME, - .match_table = pci_sun4v_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = pci_sun4v_match, + }, .probe = pci_sun4v_probe, }; diff --git a/arch/sparc/kernel/pmc.c b/arch/sparc/kernel/pmc.c index 5e4563d86f19..9589d8b9b0c1 100644 --- a/arch/sparc/kernel/pmc.c +++ b/arch/sparc/kernel/pmc.c @@ -79,8 +79,11 @@ static struct of_device_id __initdata pmc_match[] = { MODULE_DEVICE_TABLE(of, pmc_match); static struct of_platform_driver pmc_driver = { - .name = "pmc", - .match_table = pmc_match, + .driver = { + .name = "pmc", + .owner = THIS_MODULE, + .of_match_table = pmc_match, + }, .probe = pmc_probe, }; diff --git a/arch/sparc/kernel/power.c b/arch/sparc/kernel/power.c index e3f806a7423b..168d4cb63f5b 100644 --- a/arch/sparc/kernel/power.c +++ b/arch/sparc/kernel/power.c @@ -60,10 +60,11 @@ static struct of_device_id __initdata power_match[] = { }; static struct of_platform_driver power_driver = { - .match_table = power_match, .probe = power_probe, - .driver = { - .name = "power", + .driver = { + .name = "power", + .owner = THIS_MODULE, + .of_match_table = power_match, }, }; diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index e0dbed9503d4..217ba275cabf 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c @@ -185,10 +185,11 @@ static struct of_device_id __initdata clock_match[] = { }; static struct of_platform_driver clock_driver = { - .match_table = clock_match, .probe = clock_probe, - .driver = { - .name = "rtc", + .driver = { + .name = "rtc", + .owner = THIS_MODULE, + .of_match_table = clock_match, }, }; diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index 9099ca095641..21e9fcae0668 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -463,10 +463,11 @@ static struct of_device_id __initdata rtc_match[] = { }; static struct of_platform_driver rtc_driver = { - .match_table = rtc_match, .probe = rtc_probe, - .driver = { - .name = "rtc", + .driver = { + .name = "rtc", + .owner = THIS_MODULE, + .of_match_table = rtc_match, }, }; @@ -495,10 +496,11 @@ static struct of_device_id __initdata bq4802_match[] = { }; static struct of_platform_driver bq4802_driver = { - .match_table = bq4802_match, .probe = bq4802_probe, - .driver = { - .name = "bq4802", + .driver = { + .name = "bq4802", + .owner = THIS_MODULE, + .of_match_table = bq4802_match, }, }; @@ -558,10 +560,11 @@ static struct of_device_id __initdata mostek_match[] = { }; static struct of_platform_driver mostek_driver = { - .match_table = mostek_match, .probe = mostek_probe, - .driver = { - .name = "mostek", + .driver = { + .name = "mostek", + .owner = THIS_MODULE, + .of_match_table = mostek_match, }, }; diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index 4cce719add3f..88e6b6008bd6 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -884,9 +884,6 @@ static struct of_device_id mpc52xx_ata_of_match[] = { static struct of_platform_driver mpc52xx_ata_of_platform_driver = { - .owner = THIS_MODULE, - .name = DRV_NAME, - .match_table = mpc52xx_ata_of_match, .probe = mpc52xx_ata_probe, .remove = mpc52xx_ata_remove, #ifdef CONFIG_PM @@ -896,6 +893,7 @@ static struct of_platform_driver mpc52xx_ata_of_platform_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, + .of_match_table = mpc52xx_ata_of_match, }, }; diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c index 19da29f011db..5a1b82c08be9 100644 --- a/drivers/ata/pata_of_platform.c +++ b/drivers/ata/pata_of_platform.c @@ -91,8 +91,11 @@ static struct of_device_id pata_of_platform_match[] = { MODULE_DEVICE_TABLE(of, pata_of_platform_match); static struct of_platform_driver pata_of_platform_driver = { - .name = "pata_of_platform", - .match_table = pata_of_platform_match, + .driver = { + .name = "pata_of_platform", + .owner = THIS_MODULE, + .of_match_table = pata_of_platform_match, + }, .probe = pata_of_platform_probe, .remove = __devexit_p(pata_of_platform_remove), }; diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index e3339e25b152..61c89b54ea23 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -1427,8 +1427,11 @@ static struct of_device_id fsl_sata_match[] = { MODULE_DEVICE_TABLE(of, fsl_sata_match); static struct of_platform_driver fsl_sata_driver = { - .name = "fsl-sata", - .match_table = fsl_sata_match, + .driver = { + .name = "fsl-sata", + .owner = THIS_MODULE, + .of_match_table = fsl_sata_match, + }, .probe = sata_fsl_probe, .remove = sata_fsl_remove, #ifdef CONFIG_PM diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index 593a03a376e4..da8f176c051e 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -2695,8 +2695,11 @@ static const struct of_device_id fore200e_sba_match[] = { MODULE_DEVICE_TABLE(of, fore200e_sba_match); static struct of_platform_driver fore200e_sba_driver = { - .name = "fore_200e", - .match_table = fore200e_sba_match, + .driver = { + .name = "fore_200e", + .owner = THIS_MODULE, + .of_match_table = fore200e_sba_match, + }, .probe = fore200e_sba_probe, .remove = __devexit_p(fore200e_sba_remove), }; diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 3094909b0613..a7b83c0a7eb5 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -1237,13 +1237,12 @@ static const struct of_device_id ace_of_match[] __devinitconst = { MODULE_DEVICE_TABLE(of, ace_of_match); static struct of_platform_driver ace_of_driver = { - .owner = THIS_MODULE, - .name = "xsysace", - .match_table = ace_of_match, .probe = ace_of_probe, .remove = __devexit_p(ace_of_remove), .driver = { .name = "xsysace", + .owner = THIS_MODULE, + .of_match_table = ace_of_match, }, }; diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index 0861d99cd75b..0f9cbf1aaf15 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c @@ -751,8 +751,11 @@ static const struct of_device_id n2rng_match[] = { MODULE_DEVICE_TABLE(of, n2rng_match); static struct of_platform_driver n2rng_driver = { - .name = "n2rng", - .match_table = n2rng_match, + .driver = { + .name = "n2rng", + .owner = THIS_MODULE, + .of_match_table = n2rng_match, + }, .probe = n2rng_probe, .remove = __devexit_p(n2rng_remove), }; diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c index b213855bae68..261ba8f22b8b 100644 --- a/drivers/char/hw_random/pasemi-rng.c +++ b/drivers/char/hw_random/pasemi-rng.c @@ -140,8 +140,11 @@ static struct of_device_id rng_match[] = { }; static struct of_platform_driver rng_driver = { - .name = "pasemi-rng", - .match_table = rng_match, + .driver = { + .name = "pasemi-rng", + .owner = THIS_MODULE, + .of_match_table = rng_match, + }, .probe = rng_probe, .remove = rng_remove, }; diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 2b44a0e1b988..47ffe4a90a95 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2555,8 +2555,11 @@ static struct of_device_id ipmi_match[] = }; static struct of_platform_driver ipmi_of_platform_driver = { - .name = "ipmi", - .match_table = ipmi_match, + .driver = { + .name = "ipmi", + .owner = THIS_MODULE, + .of_match_table = ipmi_match, + }, .probe = ipmi_of_probe, .remove = __devexit_p(ipmi_of_remove), }; diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 5a0a31e2029c..ed8a9cec2a05 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -812,13 +812,12 @@ static const struct of_device_id __devinitconst hwicap_of_match[] = { MODULE_DEVICE_TABLE(of, hwicap_of_match); static struct of_platform_driver hwicap_of_driver = { - .owner = THIS_MODULE, - .name = DRIVER_NAME, - .match_table = hwicap_of_match, .probe = hwicap_of_probe, .remove = __devexit_p(hwicap_of_remove), .driver = { .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = hwicap_of_match, }, }; diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c index 6c4c8b7ce3aa..9d65b371de64 100644 --- a/drivers/crypto/amcc/crypto4xx_core.c +++ b/drivers/crypto/amcc/crypto4xx_core.c @@ -1281,8 +1281,11 @@ static const struct of_device_id crypto4xx_match[] = { }; static struct of_platform_driver crypto4xx_driver = { - .name = "crypto4xx", - .match_table = crypto4xx_match, + .driver = { + .name = "crypto4xx", + .owner = THIS_MODULE, + .of_match_table = crypto4xx_match, + }, .probe = crypto4xx_probe, .remove = crypto4xx_remove, }; diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 5a02f3482dba..7e4e42d85fe4 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -1968,8 +1968,11 @@ static const struct of_device_id talitos_match[] = { MODULE_DEVICE_TABLE(of, talitos_match); static struct of_platform_driver talitos_driver = { - .name = "talitos", - .match_table = talitos_match, + .driver = { + .name = "talitos", + .owner = THIS_MODULE, + .of_match_table = talitos_match, + }, .probe = talitos_probe, .remove = talitos_remove, }; diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 0e376eb37417..c3d74697f5a9 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -1409,10 +1409,13 @@ static const struct of_device_id fsldma_of_ids[] = { }; static struct of_platform_driver fsldma_of_driver = { - .name = "fsl-elo-dma", - .match_table = fsldma_of_ids, - .probe = fsldma_of_probe, - .remove = fsldma_of_remove, + .driver = { + .name = "fsl-elo-dma", + .owner = THIS_MODULE, + .of_match_table = fsldma_of_ids, + }, + .probe = fsldma_of_probe, + .remove = fsldma_of_remove, }; /*----------------------------------------------------------------------------*/ diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index d44626fa35ad..a7b05447e0ab 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -4949,12 +4949,12 @@ static const struct of_device_id ppc440spe_adma_of_match[] __devinitconst = { MODULE_DEVICE_TABLE(of, ppc440spe_adma_of_match); static struct of_platform_driver ppc440spe_adma_driver = { - .match_table = ppc440spe_adma_of_match, .probe = ppc440spe_adma_probe, .remove = __devexit_p(ppc440spe_adma_remove), .driver = { .name = "PPC440SP(E)-ADMA", .owner = THIS_MODULE, + .of_match_table = ppc440spe_adma_of_match, }, }; diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index 4471647b4807..6c1886b497ff 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c @@ -338,15 +338,13 @@ static struct of_device_id mpc85xx_pci_err_of_match[] = { }; static struct of_platform_driver mpc85xx_pci_err_driver = { - .owner = THIS_MODULE, - .name = "mpc85xx_pci_err", - .match_table = mpc85xx_pci_err_of_match, .probe = mpc85xx_pci_err_probe, .remove = __devexit_p(mpc85xx_pci_err_remove), .driver = { - .name = "mpc85xx_pci_err", - .owner = THIS_MODULE, - }, + .name = "mpc85xx_pci_err", + .owner = THIS_MODULE, + .of_match_table = mpc85xx_pci_err_of_match, + }, }; #endif /* CONFIG_PCI */ @@ -654,15 +652,13 @@ static struct of_device_id mpc85xx_l2_err_of_match[] = { }; static struct of_platform_driver mpc85xx_l2_err_driver = { - .owner = THIS_MODULE, - .name = "mpc85xx_l2_err", - .match_table = mpc85xx_l2_err_of_match, .probe = mpc85xx_l2_err_probe, .remove = mpc85xx_l2_err_remove, .driver = { - .name = "mpc85xx_l2_err", - .owner = THIS_MODULE, - }, + .name = "mpc85xx_l2_err", + .owner = THIS_MODULE, + .of_match_table = mpc85xx_l2_err_of_match, + }, }; /**************************** MC Err device ***************************/ @@ -1131,15 +1127,13 @@ static struct of_device_id mpc85xx_mc_err_of_match[] = { }; static struct of_platform_driver mpc85xx_mc_err_driver = { - .owner = THIS_MODULE, - .name = "mpc85xx_mc_err", - .match_table = mpc85xx_mc_err_of_match, .probe = mpc85xx_mc_err_probe, .remove = mpc85xx_mc_err_remove, .driver = { - .name = "mpc85xx_mc_err", - .owner = THIS_MODULE, - }, + .name = "mpc85xx_mc_err", + .owner = THIS_MODULE, + .of_match_table = mpc85xx_mc_err_of_match, + }, }; #ifdef CONFIG_MPC85xx diff --git a/drivers/edac/ppc4xx_edac.c b/drivers/edac/ppc4xx_edac.c index 11f2172aa1e6..9d6f6783328c 100644 --- a/drivers/edac/ppc4xx_edac.c +++ b/drivers/edac/ppc4xx_edac.c @@ -202,13 +202,13 @@ static struct of_device_id ppc4xx_edac_match[] = { }; static struct of_platform_driver ppc4xx_edac_driver = { - .match_table = ppc4xx_edac_match, .probe = ppc4xx_edac_probe, .remove = ppc4xx_edac_remove, - .driver = { - .owner = THIS_MODULE, - .name = PPC4XX_EDAC_MODULE_NAME - } + .driver = { + .owner = THIS_MODULE, + .name = PPC4XX_EDAC_MODULE_NAME + .of_match_table = ppc4xx_edac_match, + }, }; /* diff --git a/drivers/hwmon/ultra45_env.c b/drivers/hwmon/ultra45_env.c index 68e90abeba96..5da5942cf970 100644 --- a/drivers/hwmon/ultra45_env.c +++ b/drivers/hwmon/ultra45_env.c @@ -300,8 +300,11 @@ static const struct of_device_id env_match[] = { MODULE_DEVICE_TABLE(of, env_match); static struct of_platform_driver env_driver = { - .name = "ultra45_env", - .match_table = env_match, + .driver = { + .name = "ultra45_env", + .owner = THIS_MODULE, + .of_match_table = env_match, + }, .probe = env_probe, .remove = __devexit_p(env_remove), }; diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index 48d2c1a0d4ce..7637e1234142 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -718,13 +718,13 @@ static const struct of_device_id cpm_i2c_match[] = { MODULE_DEVICE_TABLE(of, cpm_i2c_match); static struct of_platform_driver cpm_i2c_driver = { - .match_table = cpm_i2c_match, .probe = cpm_i2c_probe, .remove = __devexit_p(cpm_i2c_remove), - .driver = { - .name = "fsl-i2c-cpm", - .owner = THIS_MODULE, - } + .driver = { + .name = "fsl-i2c-cpm", + .owner = THIS_MODULE, + .of_match_table = cpm_i2c_match, + }, }; static int __init cpm_i2c_init(void) diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index e66dc83953c5..3876f993fe76 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -807,8 +807,11 @@ static const struct of_device_id ibm_iic_match[] = { }; static struct of_platform_driver ibm_iic_driver = { - .name = "ibm-iic", - .match_table = ibm_iic_match, + .driver = { + .name = "ibm-iic", + .owner = THIS_MODULE, + .of_match_table = ibm_iic_match, + }, .probe = iic_probe, .remove = __devexit_p(iic_remove), }; diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 69473b6c260c..791b71f46f7b 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -675,12 +675,12 @@ MODULE_DEVICE_TABLE(of, mpc_i2c_of_match); /* Structure for a device driver */ static struct of_platform_driver mpc_i2c_driver = { - .match_table = mpc_i2c_of_match, .probe = fsl_i2c_probe, .remove = __devexit_p(fsl_i2c_remove), - .driver = { - .owner = THIS_MODULE, - .name = DRV_NAME, + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, + .of_match_table = mpc_i2c_of_match, }, }; diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 26391853277f..252489e88369 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c @@ -937,12 +937,13 @@ static struct of_device_id ehca_device_table[] = MODULE_DEVICE_TABLE(of, ehca_device_table); static struct of_platform_driver ehca_driver = { - .name = "ehca", - .match_table = ehca_device_table, .probe = ehca_probe, .remove = ehca_remove, - .driver = { + .driver = { + .name = "ehca", + .owner = THIS_MODULE, .groups = ehca_drv_attr_groups, + .of_match_table = ehca_device_table, }, }; diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index 0d45422f8095..1dacae4b43f0 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c @@ -259,8 +259,11 @@ static const struct of_device_id bbc_beep_match[] = { }; static struct of_platform_driver bbc_beep_driver = { - .name = "bbcbeep", - .match_table = bbc_beep_match, + .driver = { + .name = "bbcbeep", + .owner = THIS_MODULE, + .of_match_table = bbc_beep_match, + }, .probe = bbc_beep_probe, .remove = __devexit_p(bbc_remove), .shutdown = sparcspkr_shutdown, @@ -338,8 +341,11 @@ static const struct of_device_id grover_beep_match[] = { }; static struct of_platform_driver grover_beep_driver = { - .name = "groverbeep", - .match_table = grover_beep_match, + .driver = { + .name = "groverbeep", + .owner = THIS_MODULE, + .of_match_table = grover_beep_match, + }, .probe = grover_beep_probe, .remove = __devexit_p(grover_remove), .shutdown = sparcspkr_shutdown, diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h index 29e17698b2a4..04e32f2d1241 100644 --- a/drivers/input/serio/i8042-sparcio.h +++ b/drivers/input/serio/i8042-sparcio.h @@ -96,8 +96,11 @@ static const struct of_device_id sparc_i8042_match[] = { MODULE_DEVICE_TABLE(of, sparc_i8042_match); static struct of_platform_driver sparc_i8042_driver = { - .name = "i8042", - .match_table = sparc_i8042_match, + .driver = { + .name = "i8042", + .owner = THIS_MODULE, + .of_match_table = sparc_i8042_match, + }, .probe = sparc_i8042_probe, .remove = __devexit_p(sparc_i8042_remove), }; diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index 7a288c0ef1a6..e2c028d2638f 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -362,8 +362,11 @@ static const struct of_device_id xps2_of_match[] __devinitconst = { MODULE_DEVICE_TABLE(of, xps2_of_match); static struct of_platform_driver xps2_of_driver = { - .name = DRIVER_NAME, - .match_table = xps2_of_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = xps2_of_match, + }, .probe = xps2_of_probe, .remove = __devexit_p(xps2_of_remove), }; diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index a77a23e783db..6d94b0b9979c 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -291,8 +291,8 @@ static struct of_platform_driver of_gpio_leds_driver = { .driver = { .name = "of_gpio_leds", .owner = THIS_MODULE, + .of_match_table = of_gpio_leds_match, }, - .match_table = of_gpio_leds_match, .probe = of_gpio_leds_probe, .remove = __devexit_p(of_gpio_leds_remove), }; diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index 888448cf7f1f..ef1f3330a10e 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c @@ -671,8 +671,11 @@ static const struct of_device_id smu_platform_match[] = static struct of_platform_driver smu_of_platform_driver = { - .name = "smu", - .match_table = smu_platform_match, + .driver = { + .name = "smu", + .owner = THIS_MODULE, + .of_match_table = smu_platform_match, + }, .probe = smu_platform_probe, }; diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index 9314be9a2fc8..e60605bd0ea9 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -2238,8 +2238,11 @@ static const struct of_device_id fcu_match[] = static struct of_platform_driver fcu_of_platform_driver = { - .name = "temperature", - .match_table = fcu_match, + .driver = { + .name = "temperature", + .owner = THIS_MODULE, + .of_match_table = fcu_match, + }, .probe = fcu_of_probe, .remove = fcu_of_remove }; diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index 0839770e4ec5..5c9367acf0cf 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c @@ -463,8 +463,11 @@ static const struct of_device_id therm_of_match[] = {{ }; static struct of_platform_driver therm_of_driver = { - .name = "temperature", - .match_table = therm_of_match, + .driver = { + .name = "temperature", + .owner = THIS_MODULE, + .of_match_table = therm_of_match, + }, .probe = therm_of_probe, .remove = therm_of_remove, }; diff --git a/drivers/mmc/host/sdhci-of-core.c b/drivers/mmc/host/sdhci-of-core.c index dfe5ceae6794..7802a543d8fc 100644 --- a/drivers/mmc/host/sdhci-of-core.c +++ b/drivers/mmc/host/sdhci-of-core.c @@ -205,8 +205,11 @@ static const struct of_device_id sdhci_of_match[] = { MODULE_DEVICE_TABLE(of, sdhci_of_match); static struct of_platform_driver sdhci_of_driver = { - .driver.name = "sdhci-of", - .match_table = sdhci_of_match, + .driver = { + .name = "sdhci-of", + .owner = THIS_MODULE, + .of_match_table = sdhci_of_match, + }, .probe = sdhci_of_probe, .remove = __devexit_p(sdhci_of_remove), .suspend = sdhci_of_suspend, diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 3dc7a2fbf025..4147fe328c55 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -375,8 +375,11 @@ static struct of_device_id of_flash_match[] = { MODULE_DEVICE_TABLE(of, of_flash_match); static struct of_platform_driver of_flash_driver = { - .name = "of-flash", - .match_table = of_flash_match, + .driver = { + .name = "of-flash", + .owner = THIS_MODULE, + .of_match_table = of_flash_match, + }, .probe = of_flash_probe, .remove = of_flash_remove, }; diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c index 5945a23e681f..0391c2527bd7 100644 --- a/drivers/mtd/maps/sun_uflash.c +++ b/drivers/mtd/maps/sun_uflash.c @@ -149,8 +149,11 @@ static const struct of_device_id uflash_match[] = { MODULE_DEVICE_TABLE(of, uflash_match); static struct of_platform_driver uflash_driver = { - .name = DRIVER_NAME, - .match_table = uflash_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = uflash_match, + }, .probe = uflash_probe, .remove = __devexit_p(uflash_remove), }; diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 4a6079588ab2..f45a8d0c1508 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -1078,9 +1078,10 @@ static const struct of_device_id fsl_elbc_match[] = { static struct of_platform_driver fsl_elbc_ctrl_driver = { .driver = { - .name = "fsl-elbc", + .name = "fsl-elbc", + .owner = THIS_MODULE, + .of_match_table = fsl_elbc_match, }, - .match_table = fsl_elbc_match, .probe = fsl_elbc_ctrl_probe, .remove = fsl_elbc_ctrl_remove, }; diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index 4b96296af321..b7ab5a0ec35d 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c @@ -357,8 +357,11 @@ static struct of_device_id of_fun_match[] = { MODULE_DEVICE_TABLE(of, of_fun_match); static struct of_platform_driver of_fun_driver = { - .name = "fsl,upm-nand", - .match_table = of_fun_match, + .driver = { + .name = "fsl,upm-nand", + .owner = THIS_MODULE, + .of_match_table = of_fun_match, + }, .probe = fun_probe, .remove = __devexit_p(fun_remove), }; diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index c0e05f5ff8a4..98fd2bdf8be1 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -294,9 +294,10 @@ MODULE_DEVICE_TABLE(of, ndfc_match); static struct of_platform_driver ndfc_driver = { .driver = { - .name = "ndfc", + .name = "ndfc", + .owner = THIS_MODULE, + .of_match_table = ndfc_match, }, - .match_table = ndfc_match, .probe = ndfc_probe, .remove = __devexit_p(ndfc_remove), }; diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index edfc27b78513..a97e9c95ab6a 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c @@ -221,8 +221,11 @@ MODULE_DEVICE_TABLE(of, pasemi_nand_match); static struct of_platform_driver pasemi_nand_driver = { - .name = (char*)driver_name, - .match_table = pasemi_nand_match, + .driver = { + .name = (char*)driver_name, + .owner = THIS_MODULE, + .of_match_table = pasemi_nand_match, + }, .probe = pasemi_nand_probe, .remove = pasemi_nand_remove, }; diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c index a4519a7bd683..edb9b1384143 100644 --- a/drivers/mtd/nand/socrates_nand.c +++ b/drivers/mtd/nand/socrates_nand.c @@ -301,8 +301,11 @@ static struct of_device_id socrates_nand_match[] = MODULE_DEVICE_TABLE(of, socrates_nand_match); static struct of_platform_driver socrates_nand_driver = { - .name = "socrates_nand", - .match_table = socrates_nand_match, + .driver = { + .name = "socrates_nand", + .owner = THIS_MODULE, + .of_match_table = socrates_nand_match, + }, .probe = socrates_nand_probe, .remove = __devexit_p(socrates_nand_remove), }; diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c index 03e7c48465a2..2120784f8db4 100644 --- a/drivers/net/can/mscan/mpc5xxx_can.c +++ b/drivers/net/can/mscan/mpc5xxx_can.c @@ -393,15 +393,17 @@ static struct of_device_id __devinitdata mpc5xxx_can_table[] = { }; static struct of_platform_driver mpc5xxx_can_driver = { - .owner = THIS_MODULE, - .name = "mpc5xxx_can", + .driver = { + .name = "mpc5xxx_can", + .owner = THIS_MODULE, + .of_match_table = mpc5xxx_can_table, + }, .probe = mpc5xxx_can_probe, .remove = __devexit_p(mpc5xxx_can_remove), #ifdef CONFIG_PM .suspend = mpc5xxx_can_suspend, .resume = mpc5xxx_can_resume, #endif - .match_table = mpc5xxx_can_table, }; static int __init mpc5xxx_can_init(void) diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c index dc5f20cdf93c..158b76ebf3ea 100644 --- a/drivers/net/can/sja1000/sja1000_of_platform.c +++ b/drivers/net/can/sja1000/sja1000_of_platform.c @@ -216,11 +216,13 @@ static struct of_device_id __devinitdata sja1000_ofp_table[] = { MODULE_DEVICE_TABLE(of, sja1000_ofp_table); static struct of_platform_driver sja1000_ofp_driver = { - .owner = THIS_MODULE, - .name = DRV_NAME, + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, + .of_match_table = sja1000_ofp_table, + }, .probe = sja1000_ofp_probe, .remove = __devexit_p(sja1000_ofp_remove), - .match_table = sja1000_ofp_table, }; static int __init sja1000_ofp_init(void) diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 59dac232006c..b23173864c60 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -122,8 +122,11 @@ static struct of_device_id ehea_device_table[] = { MODULE_DEVICE_TABLE(of, ehea_device_table); static struct of_platform_driver ehea_driver = { - .name = "ehea", - .match_table = ehea_device_table, + .driver = { + .name = "ehea", + .owner = THIS_MODULE, + .of_match_table = ehea_device_table, + }, .probe = ehea_probe_adapter, .remove = ehea_remove, }; diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index 3342056f8aac..be540b67ea57 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -1065,9 +1065,11 @@ static struct of_device_id mpc52xx_fec_match[] = { MODULE_DEVICE_TABLE(of, mpc52xx_fec_match); static struct of_platform_driver mpc52xx_fec_driver = { - .owner = THIS_MODULE, - .name = DRIVER_NAME, - .match_table = mpc52xx_fec_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = mpc52xx_fec_match, + }, .probe = mpc52xx_fec_probe, .remove = mpc52xx_fec_remove, #ifdef CONFIG_PM diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c index 0d099e5a652d..006f64d9f96a 100644 --- a/drivers/net/fec_mpc52xx_phy.c +++ b/drivers/net/fec_mpc52xx_phy.c @@ -159,10 +159,13 @@ static struct of_device_id mpc52xx_fec_mdio_match[] = { MODULE_DEVICE_TABLE(of, mpc52xx_fec_mdio_match); struct of_platform_driver mpc52xx_fec_mdio_driver = { - .name = "mpc5200b-fec-phy", + .driver = { + .name = "mpc5200b-fec-phy", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_fec_mdio_match, + }, .probe = mpc52xx_fec_mdio_probe, .remove = mpc52xx_fec_mdio_remove, - .match_table = mpc52xx_fec_mdio_match, }; /* let fec driver call it, since this has to be registered before it */ diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index caeb88b67bc6..cae2d16858d1 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -1158,8 +1158,11 @@ static struct of_device_id fs_enet_match[] = { MODULE_DEVICE_TABLE(of, fs_enet_match); static struct of_platform_driver fs_enet_driver = { - .name = "fs_enet", - .match_table = fs_enet_match, + .driver = { + .owner = THIS_MODULE, + .name = "fs_enet", + .of_match_table = fs_enet_match, + }, .probe = fs_enet_probe, .remove = fs_enet_remove, }; diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c index 24ff9f43a62b..0f90685d3d19 100644 --- a/drivers/net/fs_enet/mii-bitbang.c +++ b/drivers/net/fs_enet/mii-bitbang.c @@ -224,8 +224,11 @@ static struct of_device_id fs_enet_mdio_bb_match[] = { MODULE_DEVICE_TABLE(of, fs_enet_mdio_bb_match); static struct of_platform_driver fs_enet_bb_mdio_driver = { - .name = "fsl-bb-mdio", - .match_table = fs_enet_mdio_bb_match, + .driver = { + .name = "fsl-bb-mdio", + .owner = THIS_MODULE, + .of_match_table = fs_enet_mdio_bb_match, + }, .probe = fs_enet_mdio_probe, .remove = fs_enet_mdio_remove, }; diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c index dc862e779c1f..bddffd169b93 100644 --- a/drivers/net/fs_enet/mii-fec.c +++ b/drivers/net/fs_enet/mii-fec.c @@ -222,8 +222,11 @@ static struct of_device_id fs_enet_mdio_fec_match[] = { MODULE_DEVICE_TABLE(of, fs_enet_mdio_fec_match); static struct of_platform_driver fs_enet_fec_mdio_driver = { - .name = "fsl-fec-mdio", - .match_table = fs_enet_mdio_fec_match, + .driver = { + .name = "fsl-fec-mdio", + .owner = THIS_MODULE, + .of_match_table = fs_enet_mdio_fec_match, + }, .probe = fs_enet_mdio_probe, .remove = fs_enet_mdio_remove, }; diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index 72489a213bf7..16508535720a 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -461,10 +461,13 @@ static struct of_device_id fsl_pq_mdio_match[] = { MODULE_DEVICE_TABLE(of, fsl_pq_mdio_match); static struct of_platform_driver fsl_pq_mdio_driver = { - .name = "fsl-pq_mdio", + .driver = { + .name = "fsl-pq_mdio", + .owner = THIS_MODULE, + .of_match_table = fsl_pq_mdio_match, + }, .probe = fsl_pq_mdio_probe, .remove = fsl_pq_mdio_remove, - .match_table = fsl_pq_mdio_match, }; int __init fsl_pq_mdio_init(void) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index b71bba91064c..c3b292a31328 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -3054,14 +3054,16 @@ MODULE_DEVICE_TABLE(of, gfar_match); /* Structure for a device driver */ static struct of_platform_driver gfar_driver = { - .name = "fsl-gianfar", - .match_table = gfar_match, - + .driver = { + .name = "fsl-gianfar", + .owner = THIS_MODULE, + .pm = GFAR_PM_OPS, + .of_match_table = gfar_match, + }, .probe = gfar_probe, .remove = gfar_remove, .suspend = gfar_legacy_suspend, .resume = gfar_legacy_resume, - .driver.pm = GFAR_PM_OPS, }; static int __init gfar_init(void) diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index cda2ba891344..f8c36a5eb4d7 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -2996,9 +2996,11 @@ static struct of_device_id emac_match[] = MODULE_DEVICE_TABLE(of, emac_match); static struct of_platform_driver emac_driver = { - .name = "emac", - .match_table = emac_match, - + .driver = { + .name = "emac", + .owner = THIS_MODULE, + .of_match_table = emac_match, + }, .probe = emac_probe, .remove = emac_remove, }; diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c index aba17947e208..fcff9e0bd382 100644 --- a/drivers/net/ibm_newemac/mal.c +++ b/drivers/net/ibm_newemac/mal.c @@ -790,9 +790,11 @@ static struct of_device_id mal_platform_match[] = }; static struct of_platform_driver mal_of_driver = { - .name = "mcmal", - .match_table = mal_platform_match, - + .driver = { + .name = "mcmal", + .owner = THIS_MODULE, + .of_match_table = mal_platform_match, + }, .probe = mal_probe, .remove = mal_remove, }; diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c index 6ab630a79e31..108919bcdf13 100644 --- a/drivers/net/ibm_newemac/rgmii.c +++ b/drivers/net/ibm_newemac/rgmii.c @@ -319,9 +319,11 @@ static struct of_device_id rgmii_match[] = }; static struct of_platform_driver rgmii_driver = { - .name = "emac-rgmii", - .match_table = rgmii_match, - + .driver = { + .name = "emac-rgmii", + .owner = THIS_MODULE, + .of_match_table = rgmii_match, + }, .probe = rgmii_probe, .remove = rgmii_remove, }; diff --git a/drivers/net/ibm_newemac/tah.c b/drivers/net/ibm_newemac/tah.c index 4f64b00dd5e8..044637144c43 100644 --- a/drivers/net/ibm_newemac/tah.c +++ b/drivers/net/ibm_newemac/tah.c @@ -166,9 +166,11 @@ static struct of_device_id tah_match[] = }; static struct of_platform_driver tah_driver = { - .name = "emac-tah", - .match_table = tah_match, - + .driver = { + .name = "emac-tah", + .owner = THIS_MODULE, + .of_match_table = tah_match, + }, .probe = tah_probe, .remove = tah_remove, }; diff --git a/drivers/net/ibm_newemac/zmii.c b/drivers/net/ibm_newemac/zmii.c index b4fa823ed201..046dcd069c45 100644 --- a/drivers/net/ibm_newemac/zmii.c +++ b/drivers/net/ibm_newemac/zmii.c @@ -313,9 +313,11 @@ static struct of_device_id zmii_match[] = }; static struct of_platform_driver zmii_driver = { - .name = "emac-zmii", - .match_table = zmii_match, - + .driver = { + .name = "emac-zmii", + .owner = THIS_MODULE, + .of_match_table = zmii_match, + }, .probe = zmii_probe, .remove = zmii_remove, }; diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index 9c7395c10e44..dc318330ec79 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -955,12 +955,12 @@ static struct of_device_id temac_of_match[] __devinitdata = { MODULE_DEVICE_TABLE(of, temac_of_match); static struct of_platform_driver temac_of_driver = { - .match_table = temac_of_match, .probe = temac_of_probe, .remove = __devexit_p(temac_of_remove), .driver = { .owner = THIS_MODULE, .name = "xilinx_temac", + .of_match_table = temac_of_match, }, }; diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index e21439f1e775..77835df4d013 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -1161,8 +1161,11 @@ static const struct of_device_id myri_sbus_match[] = { MODULE_DEVICE_TABLE(of, myri_sbus_match); static struct of_platform_driver myri_sbus_driver = { - .name = "myri", - .match_table = myri_sbus_match, + .driver = { + .name = "myri", + .owner = THIS_MODULE, + .of_match_table = myri_sbus_match, + }, .probe = myri_sbus_probe, .remove = __devexit_p(myri_sbus_remove), }; diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 9c1604c04450..406d72c4eb71 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -10207,8 +10207,11 @@ static const struct of_device_id niu_match[] = { MODULE_DEVICE_TABLE(of, niu_match); static struct of_platform_driver niu_of_driver = { - .name = "niu", - .match_table = niu_match, + .driver = { + .name = "niu", + .owner = THIS_MODULE, + .of_match_table = niu_match, + }, .probe = niu_of_probe, .remove = __devexit_p(niu_of_remove), }; diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 641973ca2417..fc5fef2a8175 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c @@ -241,8 +241,11 @@ static struct of_device_id mdio_ofgpio_match[] = { MODULE_DEVICE_TABLE(of, mdio_ofgpio_match); static struct of_platform_driver mdio_ofgpio_driver = { - .name = "mdio-gpio", - .match_table = mdio_ofgpio_match, + .driver = { + .name = "mdio-gpio", + .owner = THIS_MODULE, + .of_match_table = mdio_ofgpio_match, + }, .probe = mdio_ofgpio_probe, .remove = __devexit_p(mdio_ofgpio_remove), }; diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index bd286ec5abd9..5f0ec390d6fc 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -1292,8 +1292,11 @@ static const struct of_device_id bigmac_sbus_match[] = { MODULE_DEVICE_TABLE(of, bigmac_sbus_match); static struct of_platform_driver bigmac_sbus_driver = { - .name = "sunbmac", - .match_table = bigmac_sbus_match, + .driver = { + .name = "sunbmac", + .owner = THIS_MODULE, + .of_match_table = bigmac_sbus_match, + }, .probe = bigmac_sbus_probe, .remove = __devexit_p(bigmac_sbus_remove), }; diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index c6463f71c916..ad2cfc5bb9e1 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -3295,8 +3295,11 @@ static const struct of_device_id hme_sbus_match[] = { MODULE_DEVICE_TABLE(of, hme_sbus_match); static struct of_platform_driver hme_sbus_driver = { - .name = "hme", - .match_table = hme_sbus_match, + .driver = { + .name = "hme", + .owner = THIS_MODULE, + .of_match_table = hme_sbus_match, + }, .probe = hme_sbus_probe, .remove = __devexit_p(hme_sbus_remove), }; diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 28afc86e0694..0fc014ef9e98 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -1546,8 +1546,11 @@ static const struct of_device_id sunlance_sbus_match[] = { MODULE_DEVICE_TABLE(of, sunlance_sbus_match); static struct of_platform_driver sunlance_sbus_driver = { - .name = "sunlance", - .match_table = sunlance_sbus_match, + .driver = { + .name = "sunlance", + .owner = THIS_MODULE, + .of_match_table = sunlance_sbus_match, + }, .probe = sunlance_sbus_probe, .remove = __devexit_p(sunlance_sbus_remove), }; diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index 9864f4fa69d5..8fe86b287e51 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c @@ -978,8 +978,11 @@ static const struct of_device_id qec_sbus_match[] = { MODULE_DEVICE_TABLE(of, qec_sbus_match); static struct of_platform_driver qec_sbus_driver = { - .name = "qec", - .match_table = qec_sbus_match, + .driver = { + .name = "qec", + .owner = THIS_MODULE, + .of_match_table = qec_sbus_match, + }, .probe = qec_sbus_probe, .remove = __devexit_p(qec_sbus_remove), }; diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 88ebfc976735..0ab51037bf88 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3965,8 +3965,11 @@ static struct of_device_id ucc_geth_match[] = { MODULE_DEVICE_TABLE(of, ucc_geth_match); static struct of_platform_driver ucc_geth_driver = { - .name = DRV_NAME, - .match_table = ucc_geth_match, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = ucc_geth_match, + }, .probe = ucc_geth_probe, .remove = ucc_geth_remove, .suspend = ucc_geth_suspend, diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index 3dd2416db540..67f9237237dd 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -1293,8 +1293,11 @@ static struct of_device_id xemaclite_of_match[] __devinitdata = { MODULE_DEVICE_TABLE(of, xemaclite_of_match); static struct of_platform_driver xemaclite_of_driver = { - .name = DRIVER_NAME, - .match_table = xemaclite_of_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = xemaclite_of_match, + }, .probe = xemaclite_of_probe, .remove = __devexit_p(xemaclite_of_remove), }; diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 9fd7f7d0a0d1..ba402c613ede 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -385,13 +385,6 @@ int of_bus_type_init(struct bus_type *bus, const char *name) int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) { - /* initialize common driver fields */ - if (!drv->driver.name) - drv->driver.name = drv->name; - if (!drv->driver.owner) - drv->driver.owner = drv->owner; - if (!drv->driver.of_match_table) - drv->driver.of_match_table = drv->match_table; drv->driver.bus = bus; /* register with core */ diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c index 065f229580d5..9a5b4b894161 100644 --- a/drivers/parport/parport_sunbpp.c +++ b/drivers/parport/parport_sunbpp.c @@ -382,8 +382,11 @@ static const struct of_device_id bpp_match[] = { MODULE_DEVICE_TABLE(of, bpp_match); static struct of_platform_driver bpp_sbus_driver = { - .name = "bpp", - .match_table = bpp_match, + .driver = { + .name = "bpp", + .owner = THIS_MODULE, + .of_match_table = bpp_match, + }, .probe = bpp_probe, .remove = __devexit_p(bpp_remove), }; diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index a22d32d71bf2..f94d8281cfb0 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c @@ -357,8 +357,11 @@ static const struct of_device_id electra_cf_match[] = { MODULE_DEVICE_TABLE(of, electra_cf_match); static struct of_platform_driver electra_cf_driver = { - .name = (char *)driver_name, - .match_table = electra_cf_match, + .driver = { + .name = (char *)driver_name, + .owner = THIS_MODULE, + .of_match_table = electra_cf_match, + }, .probe = electra_cf_probe, .remove = electra_cf_remove, }; diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 41cc954a5ffe..1a648b90b634 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c @@ -1298,8 +1298,11 @@ static const struct of_device_id m8xx_pcmcia_match[] = { MODULE_DEVICE_TABLE(of, m8xx_pcmcia_match); static struct of_platform_driver m8xx_pcmcia_driver = { - .name = driver_name, - .match_table = m8xx_pcmcia_match, + .driver = { + .name = driver_name, + .owner = THIS_MODULE, + .match_table = m8xx_pcmcia_match, + }, .probe = m8xx_probe, .remove = m8xx_remove, }; diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c index 1543ac32b79b..8bfdd63a1fcb 100644 --- a/drivers/sbus/char/bbc_i2c.c +++ b/drivers/sbus/char/bbc_i2c.c @@ -414,8 +414,11 @@ static const struct of_device_id bbc_i2c_match[] = { MODULE_DEVICE_TABLE(of, bbc_i2c_match); static struct of_platform_driver bbc_i2c_driver = { - .name = "bbc_i2c", - .match_table = bbc_i2c_match, + .driver = { + .name = "bbc_i2c", + .owner = THIS_MODULE, + .of_match_table = bbc_i2c_match, + }, .probe = bbc_i2c_probe, .remove = __devexit_p(bbc_i2c_remove), }; diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c index 7fc7f34f3466..7baf1b644039 100644 --- a/drivers/sbus/char/display7seg.c +++ b/drivers/sbus/char/display7seg.c @@ -266,8 +266,11 @@ static const struct of_device_id d7s_match[] = { MODULE_DEVICE_TABLE(of, d7s_match); static struct of_platform_driver d7s_driver = { - .name = DRIVER_NAME, - .match_table = d7s_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = d7s_match, + }, .probe = d7s_probe, .remove = __devexit_p(d7s_remove), }; diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index a5fe20faf4f7..c8166ecf5276 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c @@ -1131,8 +1131,11 @@ static const struct of_device_id envctrl_match[] = { MODULE_DEVICE_TABLE(of, envctrl_match); static struct of_platform_driver envctrl_driver = { - .name = DRIVER_NAME, - .match_table = envctrl_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = envctrl_match, + }, .probe = envctrl_probe, .remove = __devexit_p(envctrl_remove), }; diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index 202ff8f75afb..0427e586975f 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c @@ -207,8 +207,11 @@ static const struct of_device_id flash_match[] = { MODULE_DEVICE_TABLE(of, flash_match); static struct of_platform_driver flash_driver = { - .name = "flash", - .match_table = flash_match, + .driver = { + .name = "flash", + .owner = THIS_MODULE, + .of_match_table = flash_match, + }, .probe = flash_probe, .remove = __devexit_p(flash_remove), }; diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c index acc6738aa61f..5f253665a1da 100644 --- a/drivers/sbus/char/uctrl.c +++ b/drivers/sbus/char/uctrl.c @@ -425,8 +425,11 @@ static const struct of_device_id uctrl_match[] = { MODULE_DEVICE_TABLE(of, uctrl_match); static struct of_platform_driver uctrl_driver = { - .name = "uctrl", - .match_table = uctrl_match, + .driver = { + .name = "uctrl", + .owner = THIS_MODULE, + .of_match_table = uctrl_match, + }, .probe = uctrl_probe, .remove = __devexit_p(uctrl_remove), }; diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index 35433d23b7ce..ca5c15c779cf 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -1456,8 +1456,11 @@ static const struct of_device_id qpti_match[] = { MODULE_DEVICE_TABLE(of, qpti_match); static struct of_platform_driver qpti_sbus_driver = { - .name = "qpti", - .match_table = qpti_match, + .driver = { + .name = "qpti", + .owner = THIS_MODULE, + .of_match_table = qpti_match, + }, .probe = qpti_sbus_probe, .remove = __devexit_p(qpti_sbus_remove), }; diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c index 151df73df475..386dd9d602b6 100644 --- a/drivers/scsi/sun_esp.c +++ b/drivers/scsi/sun_esp.c @@ -633,8 +633,11 @@ static const struct of_device_id esp_match[] = { MODULE_DEVICE_TABLE(of, esp_match); static struct of_platform_driver esp_sbus_driver = { - .name = "esp", - .match_table = esp_match, + .driver = { + .name = "esp", + .owner = THIS_MODULE, + .of_match_table = esp_match, + }, .probe = esp_sbus_probe, .remove = __devexit_p(esp_sbus_remove), }; diff --git a/drivers/serial/apbuart.c b/drivers/serial/apbuart.c index 52015d7031bb..0099b8692b60 100644 --- a/drivers/serial/apbuart.c +++ b/drivers/serial/apbuart.c @@ -584,12 +584,12 @@ static struct of_device_id __initdata apbuart_match[] = { }; static struct of_platform_driver grlib_apbuart_of_driver = { - .match_table = apbuart_match, .probe = apbuart_probe, .driver = { - .owner = THIS_MODULE, - .name = "grlib-apbuart", - }, + .owner = THIS_MODULE, + .name = "grlib-apbuart", + .of_match_table = apbuart_match, + }, }; diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 7866cdf8a754..9eb62a256e9a 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -1372,8 +1372,11 @@ static struct of_device_id cpm_uart_match[] = { }; static struct of_platform_driver cpm_uart_driver = { - .name = "cpm_uart", - .match_table = cpm_uart_match, + .driver = { + .name = "cpm_uart", + .owner = THIS_MODULE, + .of_match_table = cpm_uart_match, + }, .probe = cpm_uart_probe, .remove = cpm_uart_remove, }; diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index cb079387c5ae..4fb32e3748c2 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c @@ -1464,15 +1464,16 @@ mpc52xx_uart_of_enumerate(void) MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match); static struct of_platform_driver mpc52xx_uart_of_driver = { - .match_table = mpc52xx_uart_of_match, .probe = mpc52xx_uart_of_probe, .remove = mpc52xx_uart_of_remove, #ifdef CONFIG_PM .suspend = mpc52xx_uart_of_suspend, .resume = mpc52xx_uart_of_resume, #endif - .driver = { - .name = "mpc52xx-psc-uart", + .driver = { + .name = "mpc52xx-psc-uart", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_uart_of_match, }, }; diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c index 29539805e593..a48d9080f552 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/serial/of_serial.c @@ -175,11 +175,13 @@ static struct of_device_id __devinitdata of_platform_serial_table[] = { }; static struct of_platform_driver of_platform_serial_driver = { - .owner = THIS_MODULE, - .name = "of_serial", + .driver = { + .name = "of_serial", + .owner = THIS_MODULE, + .of_match_table = of_platform_serial_table, + }, .probe = of_platform_serial_probe, .remove = of_platform_serial_remove, - .match_table = of_platform_serial_table, }; static int __init of_platform_serial_init(void) diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c index d1eedf13d85c..890f91742962 100644 --- a/drivers/serial/sunhv.c +++ b/drivers/serial/sunhv.c @@ -630,8 +630,11 @@ static const struct of_device_id hv_match[] = { MODULE_DEVICE_TABLE(of, hv_match); static struct of_platform_driver hv_driver = { - .name = "hv", - .match_table = hv_match, + .driver = { + .name = "hv", + .owner = THIS_MODULE, + .of_match_table = hv_match, + }, .probe = hv_probe, .remove = __devexit_p(hv_remove), }; diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index 9176c41b74ad..5e81bc6b48b0 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c @@ -1093,8 +1093,11 @@ static const struct of_device_id sab_match[] = { MODULE_DEVICE_TABLE(of, sab_match); static struct of_platform_driver sab_driver = { - .name = "sab", - .match_table = sab_match, + .driver = { + .name = "sab", + .owner = THIS_MODULE, + .of_match_table = sab_match, + }, .probe = sab_probe, .remove = __devexit_p(sab_remove), }; diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index a647b2448071..234459c2f012 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -1539,8 +1539,11 @@ static const struct of_device_id su_match[] = { MODULE_DEVICE_TABLE(of, su_match); static struct of_platform_driver su_driver = { - .name = "su", - .match_table = su_match, + .driver = { + .name = "su", + .owner = THIS_MODULE, + .of_match_table = su_match, + }, .probe = su_probe, .remove = __devexit_p(su_remove), }; diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 20f9be8cd949..34fb8e84504f 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c @@ -1491,8 +1491,11 @@ static const struct of_device_id zs_match[] = { MODULE_DEVICE_TABLE(of, zs_match); static struct of_platform_driver zs_driver = { - .name = "zs", - .match_table = zs_match, + .driver = { + .name = "zs", + .owner = THIS_MODULE, + .of_match_table = zs_match, + }, .probe = zs_probe, .remove = __devexit_p(zs_remove), }; diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index 8fc2583d06ff..81073e3426e0 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c @@ -610,13 +610,12 @@ static int __devexit ulite_of_remove(struct of_device *op) } static struct of_platform_driver ulite_of_driver = { - .owner = THIS_MODULE, - .name = "uartlite", - .match_table = ulite_of_match, .probe = ulite_of_probe, .remove = __devexit_p(ulite_of_remove), .driver = { .name = "uartlite", + .owner = THIS_MODULE, + .of_match_table = ulite_of_match, }, }; diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c index 529890f044e2..907b06f5c447 100644 --- a/drivers/serial/ucc_uart.c +++ b/drivers/serial/ucc_uart.c @@ -1486,9 +1486,11 @@ static struct of_device_id ucc_uart_match[] = { MODULE_DEVICE_TABLE(of, ucc_uart_match); static struct of_platform_driver ucc_uart_of_driver = { - .owner = THIS_MODULE, - .name = "ucc_uart", - .match_table = ucc_uart_match, + .driver = { + .name = "ucc_uart", + .owner = THIS_MODULE, + .of_match_table = ucc_uart_match, + }, .probe = ucc_uart_probe, .remove = ucc_uart_remove, }; diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 7fcf28405860..7104cb739da7 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c @@ -514,14 +514,12 @@ static const struct of_device_id mpc52xx_psc_spi_of_match[] = { MODULE_DEVICE_TABLE(of, mpc52xx_psc_spi_of_match); static struct of_platform_driver mpc52xx_psc_spi_of_driver = { - .owner = THIS_MODULE, - .name = "mpc52xx-psc-spi", - .match_table = mpc52xx_psc_spi_of_match, .probe = mpc52xx_psc_spi_of_probe, .remove = __exit_p(mpc52xx_psc_spi_of_remove), .driver = { .name = "mpc52xx-psc-spi", .owner = THIS_MODULE, + .of_match_table = mpc52xx_psc_spi_of_match, }, }; diff --git a/drivers/spi/mpc52xx_spi.c b/drivers/spi/mpc52xx_spi.c index 6573233bf7c9..b1a76bff775f 100644 --- a/drivers/spi/mpc52xx_spi.c +++ b/drivers/spi/mpc52xx_spi.c @@ -558,9 +558,11 @@ static const struct of_device_id mpc52xx_spi_match[] __devinitconst = { MODULE_DEVICE_TABLE(of, mpc52xx_spi_match); static struct of_platform_driver mpc52xx_spi_of_driver = { - .owner = THIS_MODULE, - .name = "mpc52xx-spi", - .match_table = mpc52xx_spi_match, + .driver = { + .name = "mpc52xx-spi", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_spi_match, + }, .probe = mpc52xx_spi_probe, .remove = __exit_p(mpc52xx_spi_remove), }; diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c index 7572f98a419e..77ab15e330d0 100644 --- a/drivers/spi/spi_mpc8xxx.c +++ b/drivers/spi/spi_mpc8xxx.c @@ -1312,8 +1312,11 @@ static const struct of_device_id of_mpc8xxx_spi_match[] = { MODULE_DEVICE_TABLE(of, of_mpc8xxx_spi_match); static struct of_platform_driver of_mpc8xxx_spi_driver = { - .name = "mpc8xxx_spi", - .match_table = of_mpc8xxx_spi_match, + .driver = { + .name = "mpc8xxx_spi", + .owner = THIS_MODULE, + .of_match_table = of_mpc8xxx_spi_match, + }, .probe = of_mpc8xxx_spi_probe, .remove = __devexit_p(of_mpc8xxx_spi_remove), }; diff --git a/drivers/spi/spi_ppc4xx.c b/drivers/spi/spi_ppc4xx.c index 7cb5ff37f6e2..19c0b3b34fce 100644 --- a/drivers/spi/spi_ppc4xx.c +++ b/drivers/spi/spi_ppc4xx.c @@ -587,12 +587,12 @@ static const struct of_device_id spi_ppc4xx_of_match[] = { MODULE_DEVICE_TABLE(of, spi_ppc4xx_of_match); static struct of_platform_driver spi_ppc4xx_of_driver = { - .match_table = spi_ppc4xx_of_match, .probe = spi_ppc4xx_of_probe, .remove = __exit_p(spi_ppc4xx_of_remove), .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, + .of_match_table = spi_ppc4xx_of_match, }, }; diff --git a/drivers/spi/xilinx_spi_of.c b/drivers/spi/xilinx_spi_of.c index 748d33a76d29..55c58012a028 100644 --- a/drivers/spi/xilinx_spi_of.c +++ b/drivers/spi/xilinx_spi_of.c @@ -109,12 +109,12 @@ static const struct of_device_id xilinx_spi_of_match[] = { MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); static struct of_platform_driver xilinx_spi_of_driver = { - .match_table = xilinx_spi_of_match, .probe = xilinx_spi_of_probe, .remove = __exit_p(xilinx_spi_of_remove), .driver = { .name = "xilinx-xps-spi", .owner = THIS_MODULE, + .of_match_table = xilinx_spi_of_match, }, }; diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index 3537d51073b2..2928523268b5 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -2768,8 +2768,11 @@ static const struct of_device_id qe_udc_match[] __devinitconst = { MODULE_DEVICE_TABLE(of, qe_udc_match); static struct of_platform_driver udc_driver = { - .name = (char *)driver_name, - .match_table = qe_udc_match, + .driver = { + .name = (char *)driver_name, + .owner = THIS_MODULE, + .of_match_table = qe_udc_match, + }, .probe = qe_udc_probe, .remove = __devexit_p(qe_udc_remove), #ifdef CONFIG_PM diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index ad0662354a5e..5aec92866ab3 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c @@ -274,13 +274,12 @@ MODULE_DEVICE_TABLE(of, ehci_hcd_ppc_of_match); static struct of_platform_driver ehci_hcd_ppc_of_driver = { - .name = "ppc-of-ehci", - .match_table = ehci_hcd_ppc_of_match, .probe = ehci_hcd_ppc_of_probe, .remove = ehci_hcd_ppc_of_remove, .shutdown = ehci_hcd_ppc_of_shutdown, - .driver = { - .name = "ppc-of-ehci", - .owner = THIS_MODULE, + .driver = { + .name = "ppc-of-ehci", + .owner = THIS_MODULE, + .of_match_table = ehci_hcd_ppc_of_match, }, }; diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c index f603bb2c0a8e..013972bbde57 100644 --- a/drivers/usb/host/ehci-xilinx-of.c +++ b/drivers/usb/host/ehci-xilinx-of.c @@ -288,13 +288,12 @@ static const struct of_device_id ehci_hcd_xilinx_of_match[] = { MODULE_DEVICE_TABLE(of, ehci_hcd_xilinx_of_match); static struct of_platform_driver ehci_hcd_xilinx_of_driver = { - .name = "xilinx-of-ehci", - .match_table = ehci_hcd_xilinx_of_match, .probe = ehci_hcd_xilinx_of_probe, .remove = ehci_hcd_xilinx_of_remove, .shutdown = ehci_hcd_xilinx_of_shutdown, - .driver = { - .name = "xilinx-of-ehci", - .owner = THIS_MODULE, + .driver = { + .name = "xilinx-of-ehci", + .owner = THIS_MODULE, + .of_match_table = ehci_hcd_xilinx_of_match, }, }; diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 6135732d8057..7b5c62654bfd 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -813,8 +813,11 @@ static const struct of_device_id of_fhci_match[] = { MODULE_DEVICE_TABLE(of, of_fhci_match); static struct of_platform_driver of_fhci_driver = { - .name = "fsl,usb-fhci", - .match_table = of_fhci_match, + .driver = { + .name = "fsl,usb-fhci", + .owner = THIS_MODULE, + .of_match_table = of_fhci_match, + }, .probe = of_fhci_probe, .remove = __devexit_p(of_fhci_remove), }; diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 36360e24a9b9..100d5faebe3c 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -121,8 +121,11 @@ static const struct of_device_id of_isp1760_match[] = { MODULE_DEVICE_TABLE(of, of_isp1760_match); static struct of_platform_driver isp1760_of_driver = { - .name = "nxp-isp1760", - .match_table = of_isp1760_match, + .driver = { + .name = "nxp-isp1760", + .owner = THIS_MODULE, + .of_match_table = of_isp1760_match, + }, .probe = of_isp1760_probe, .remove = of_isp1760_remove, }; diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index 003aea21c35e..df165917412a 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c @@ -244,18 +244,13 @@ MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_match); static struct of_platform_driver ohci_hcd_ppc_of_driver = { - .name = "ppc-of-ohci", - .match_table = ohci_hcd_ppc_of_match, .probe = ohci_hcd_ppc_of_probe, .remove = ohci_hcd_ppc_of_remove, .shutdown = ohci_hcd_ppc_of_shutdown, -#ifdef CONFIG_PM - /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/ - /*.resume = ohci_hcd_ppc_soc_drv_resume,*/ -#endif - .driver = { - .name = "ppc-of-ohci", - .owner = THIS_MODULE, + .driver = { + .name = "ppc-of-ohci", + .owner = THIS_MODULE, + .of_match_table = ohci_hcd_ppc_of_match, }, }; diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c index 43320925c4ce..2c371c07f0da 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/bw2.c @@ -376,8 +376,11 @@ static const struct of_device_id bw2_match[] = { MODULE_DEVICE_TABLE(of, bw2_match); static struct of_platform_driver bw2_driver = { - .name = "bw2", - .match_table = bw2_match, + .driver = { + .name = "bw2", + .owner = THIS_MODULE, + .of_match_table = bw2_match, + }, .probe = bw2_probe, .remove = __devexit_p(bw2_remove), }; diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c index 77a040af20a7..d12e05b6e63f 100644 --- a/drivers/video/cg14.c +++ b/drivers/video/cg14.c @@ -596,8 +596,11 @@ static const struct of_device_id cg14_match[] = { MODULE_DEVICE_TABLE(of, cg14_match); static struct of_platform_driver cg14_driver = { - .name = "cg14", - .match_table = cg14_match, + .driver = { + .name = "cg14", + .owner = THIS_MODULE, + .of_match_table = cg14_match, + }, .probe = cg14_probe, .remove = __devexit_p(cg14_remove), }; diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c index 30eedf79322c..b98f93f7f663 100644 --- a/drivers/video/cg3.c +++ b/drivers/video/cg3.c @@ -463,8 +463,11 @@ static const struct of_device_id cg3_match[] = { MODULE_DEVICE_TABLE(of, cg3_match); static struct of_platform_driver cg3_driver = { - .name = "cg3", - .match_table = cg3_match, + .driver = { + .name = "cg3", + .owner = THIS_MODULE, + .of_match_table = cg3_match, + }, .probe = cg3_probe, .remove = __devexit_p(cg3_remove), }; diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index 7f59b0fe5dc2..480d761a27a8 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c @@ -856,8 +856,11 @@ static const struct of_device_id cg6_match[] = { MODULE_DEVICE_TABLE(of, cg6_match); static struct of_platform_driver cg6_driver = { - .name = "cg6", - .match_table = cg6_match, + .driver = { + .name = "cg6", + .owner = THIS_MODULE, + .of_match_table = cg6_match, + }, .probe = cg6_probe, .remove = __devexit_p(cg6_remove), }; diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c index ddd46f71e250..95c0227f47fc 100644 --- a/drivers/video/ffb.c +++ b/drivers/video/ffb.c @@ -1053,8 +1053,11 @@ static const struct of_device_id ffb_match[] = { MODULE_DEVICE_TABLE(of, ffb_match); static struct of_platform_driver ffb_driver = { - .name = "ffb", - .match_table = ffb_match, + .driver = { + .name = "ffb", + .owner = THIS_MODULE, + .of_match_table = ffb_match, + }, .probe = ffb_probe, .remove = __devexit_p(ffb_remove), }; diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index 930a2522a631..27455ce298b7 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c @@ -1647,9 +1647,11 @@ static struct of_device_id fsl_diu_match[] = { MODULE_DEVICE_TABLE(of, fsl_diu_match); static struct of_platform_driver fsl_diu_driver = { - .owner = THIS_MODULE, - .name = "fsl_diu", - .match_table = fsl_diu_match, + .driver = { + .name = "fsl_diu", + .owner = THIS_MODULE, + .of_match_table = fsl_diu_match, + }, .probe = fsl_diu_probe, .remove = fsl_diu_remove, .suspend = fsl_diu_suspend, diff --git a/drivers/video/leo.c b/drivers/video/leo.c index 1db55f128490..3d7895316eaf 100644 --- a/drivers/video/leo.c +++ b/drivers/video/leo.c @@ -663,8 +663,11 @@ static const struct of_device_id leo_match[] = { MODULE_DEVICE_TABLE(of, leo_match); static struct of_platform_driver leo_driver = { - .name = "leo", - .match_table = leo_match, + .driver = { + .name = "leo", + .owner = THIS_MODULE, + .of_match_table = leo_match, + }, .probe = leo_probe, .remove = __devexit_p(leo_remove), }; diff --git a/drivers/video/mb862xx/mb862xxfb.c b/drivers/video/mb862xx/mb862xxfb.c index 8280a58a0e55..0540de4f5cb4 100644 --- a/drivers/video/mb862xx/mb862xxfb.c +++ b/drivers/video/mb862xx/mb862xxfb.c @@ -718,9 +718,11 @@ static struct of_device_id __devinitdata of_platform_mb862xx_tbl[] = { }; static struct of_platform_driver of_platform_mb862xxfb_driver = { - .owner = THIS_MODULE, - .name = DRV_NAME, - .match_table = of_platform_mb862xx_tbl, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = of_platform_mb862xx_tbl, + }, .probe = of_platform_mb862xx_probe, .remove = __devexit_p(of_platform_mb862xx_remove), }; diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c index 81440f2b9091..c85dd408a9b8 100644 --- a/drivers/video/p9100.c +++ b/drivers/video/p9100.c @@ -353,8 +353,11 @@ static const struct of_device_id p9100_match[] = { MODULE_DEVICE_TABLE(of, p9100_match); static struct of_platform_driver p9100_driver = { - .name = "p9100", - .match_table = p9100_match, + .driver = { + .name = "p9100", + .owner = THIS_MODULE, + .of_match_table = p9100_match, + }, .probe = p9100_probe, .remove = __devexit_p(p9100_remove), }; diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index 69d78d50f0f6..72a1f4c04732 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c @@ -679,8 +679,11 @@ static struct of_device_id platinumfb_match[] = static struct of_platform_driver platinum_driver = { - .name = "platinumfb", - .match_table = platinumfb_match, + .driver = { + .name = "platinumfb", + .owner = THIS_MODULE, + .of_match_table = platinumfb_match, + }, .probe = platinumfb_probe, .remove = platinumfb_remove, }; diff --git a/drivers/video/sunxvr1000.c b/drivers/video/sunxvr1000.c index ad92a200fafa..489b44e8db81 100644 --- a/drivers/video/sunxvr1000.c +++ b/drivers/video/sunxvr1000.c @@ -199,10 +199,13 @@ static const struct of_device_id gfb_match[] = { MODULE_DEVICE_TABLE(of, ffb_match); static struct of_platform_driver gfb_driver = { - .name = "gfb", - .match_table = gfb_match, .probe = gfb_probe, .remove = __devexit_p(gfb_remove), + .driver = { + .name = "gfb", + .owner = THIS_MODULE, + .of_match_table = gfb_match, + }, }; static int __init gfb_init(void) diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c index c0c2b18fcdcf..ef7a7bd8b503 100644 --- a/drivers/video/tcx.c +++ b/drivers/video/tcx.c @@ -512,8 +512,11 @@ static const struct of_device_id tcx_match[] = { MODULE_DEVICE_TABLE(of, tcx_match); static struct of_platform_driver tcx_driver = { - .name = "tcx", - .match_table = tcx_match, + .driver = { + .name = "tcx", + .owner = THIS_MODULE, + .of_match_table = tcx_match, + }, .probe = tcx_probe, .remove = __devexit_p(tcx_remove), }; diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index 6fcec553662c..574dc54e12d4 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -492,13 +492,12 @@ static struct of_device_id xilinxfb_of_match[] __devinitdata = { MODULE_DEVICE_TABLE(of, xilinxfb_of_match); static struct of_platform_driver xilinxfb_of_driver = { - .owner = THIS_MODULE, - .name = DRIVER_NAME, - .match_table = xilinxfb_of_match, .probe = xilinxfb_of_probe, .remove = __devexit_p(xilinxfb_of_remove), .driver = { .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = xilinxfb_of_match, }, }; diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index 2fcc3cf7ef62..d62b9ce8f773 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c @@ -677,8 +677,11 @@ static const struct of_device_id cpwd_match[] = { MODULE_DEVICE_TABLE(of, cpwd_match); static struct of_platform_driver cpwd_driver = { - .name = DRIVER_NAME, - .match_table = cpwd_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = cpwd_match, + }, .probe = cpwd_probe, .remove = __devexit_p(cpwd_remove), }; diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c index abdbad034a6c..ca0f4c6cf5ab 100644 --- a/drivers/watchdog/gef_wdt.c +++ b/drivers/watchdog/gef_wdt.c @@ -303,9 +303,11 @@ static const struct of_device_id gef_wdt_ids[] = { }; static struct of_platform_driver gef_wdt_driver = { - .owner = THIS_MODULE, - .name = "gef_wdt", - .match_table = gef_wdt_ids, + .driver = { + .name = "gef_wdt", + .owner = THIS_MODULE, + .of_match_table = gef_wdt_ids, + }, .probe = gef_wdt_probe, }; diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c index 4e3941c5e293..7b55974191dd 100644 --- a/drivers/watchdog/mpc8xxx_wdt.c +++ b/drivers/watchdog/mpc8xxx_wdt.c @@ -273,12 +273,12 @@ static const struct of_device_id mpc8xxx_wdt_match[] = { MODULE_DEVICE_TABLE(of, mpc8xxx_wdt_match); static struct of_platform_driver mpc8xxx_wdt_driver = { - .match_table = mpc8xxx_wdt_match, .probe = mpc8xxx_wdt_probe, .remove = __devexit_p(mpc8xxx_wdt_remove), - .driver = { - .name = "mpc8xxx_wdt", - .owner = THIS_MODULE, + .driver = { + .name = "mpc8xxx_wdt", + .owner = THIS_MODULE, + .of_match_table = mpc8xxx_wdt_match, }, }; diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c index ea7f803f6248..5dceeddc8859 100644 --- a/drivers/watchdog/riowd.c +++ b/drivers/watchdog/riowd.c @@ -239,8 +239,11 @@ static const struct of_device_id riowd_match[] = { MODULE_DEVICE_TABLE(of, riowd_match); static struct of_platform_driver riowd_driver = { - .name = DRIVER_NAME, - .match_table = riowd_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = riowd_match, + }, .probe = riowd_probe, .remove = __devexit_p(riowd_remove), }; diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index ac3ae0758fbe..1643d3761eb4 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -31,10 +31,6 @@ extern struct bus_type of_platform_bus_type; */ struct of_platform_driver { - const char *name; - const struct of_device_id *match_table; - struct module *owner; - int (*probe)(struct of_device* dev, const struct of_device_id *match); int (*remove)(struct of_device* dev); diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c index 3dbc7f7cd7b9..e2ee220bfb7e 100644 --- a/sound/soc/fsl/mpc5200_psc_ac97.c +++ b/sound/soc/fsl/mpc5200_psc_ac97.c @@ -317,12 +317,12 @@ static struct of_device_id psc_ac97_match[] __devinitdata = { MODULE_DEVICE_TABLE(of, psc_ac97_match); static struct of_platform_driver psc_ac97_driver = { - .match_table = psc_ac97_match, .probe = psc_ac97_of_probe, .remove = __devexit_p(psc_ac97_of_remove), .driver = { .name = "mpc5200-psc-ac97", .owner = THIS_MODULE, + .of_match_table = psc_ac97_match, }, }; diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c index 748cc0f0df38..4f455bd6851f 100644 --- a/sound/soc/fsl/mpc5200_psc_i2s.c +++ b/sound/soc/fsl/mpc5200_psc_i2s.c @@ -220,12 +220,12 @@ static struct of_device_id psc_i2s_match[] __devinitdata = { MODULE_DEVICE_TABLE(of, psc_i2s_match); static struct of_platform_driver psc_i2s_driver = { - .match_table = psc_i2s_match, .probe = psc_i2s_of_probe, .remove = __devexit_p(psc_i2s_of_remove), .driver = { .name = "mpc5200-psc-i2s", .owner = THIS_MODULE, + .of_match_table = psc_i2s_match, }, }; diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index e3f78f255a60..6a2764ee8203 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c @@ -580,9 +580,11 @@ static struct of_device_id mpc8610_hpcd_match[] = { MODULE_DEVICE_TABLE(of, mpc8610_hpcd_match); static struct of_platform_driver mpc8610_hpcd_of_driver = { - .owner = THIS_MODULE, - .name = "mpc8610_hpcd", - .match_table = mpc8610_hpcd_match, + .driver = { + .name = "mpc8610_hpcd", + .owner = THIS_MODULE, + .of_match_table = mpc8610_hpcd_match, + }, .probe = mpc8610_hpcd_probe, .remove = mpc8610_hpcd_remove, }; diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c index 574af56ba8a6..71221fd20944 100644 --- a/sound/sparc/amd7930.c +++ b/sound/sparc/amd7930.c @@ -1065,8 +1065,11 @@ static const struct of_device_id amd7930_match[] = { }; static struct of_platform_driver amd7930_sbus_driver = { - .name = "audio", - .match_table = amd7930_match, + .driver = { + .name = "audio", + .owner = THIS_MODULE, + .of_match_table = amd7930_match, + }, .probe = amd7930_sbus_probe, }; diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 6a4c872e00df..fb4c6f2f29e5 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -2109,8 +2109,11 @@ static const struct of_device_id cs4231_match[] = { MODULE_DEVICE_TABLE(of, cs4231_match); static struct of_platform_driver cs4231_driver = { - .name = "audio", - .match_table = cs4231_match, + .driver = { + .name = "audio", + .owner = THIS_MODULE, + .of_match_table = cs4231_match, + }, .probe = cs4231_probe, .remove = __devexit_p(cs4231_remove), }; diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index 1b5192eb5ae5..1557bf132e73 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c @@ -2687,8 +2687,11 @@ static const struct of_device_id dbri_match[] = { MODULE_DEVICE_TABLE(of, dbri_match); static struct of_platform_driver dbri_sbus_driver = { - .name = "dbri", - .match_table = dbri_match, + .driver = { + .name = "dbri", + .owner = THIS_MODULE, + .of_match_table = dbri_match, + }, .probe = dbri_probe, .remove = __devexit_p(dbri_remove), }; -- cgit v1.2.3 From 44504b2bebf8b5823c59484e73096a7d6574471d Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:13:22 -0700 Subject: of: change of_match_device to work with struct device The of_node pointer is now stored directly in struct device, so of_match_device() should work with any device, not just struct of_device. This patch changes the interface to of_match_device() to accept a struct device instead of struct of_device. Signed-off-by: Grant Likely --- drivers/macintosh/macio_asic.c | 5 ++--- drivers/of/device.c | 9 ++++----- drivers/of/platform.c | 5 ++--- include/linux/of_device.h | 2 +- 4 files changed, 9 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index e3ba1d8001a3..97147804a49c 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -39,13 +39,12 @@ static struct macio_chip *macio_on_hold; static int macio_bus_match(struct device *dev, struct device_driver *drv) { - struct macio_dev * macio_dev = to_macio_device(dev); const struct of_device_id * matches = drv->of_match_table; if (!matches) return 0; - return of_match_device(matches, &macio_dev->ofdev) != NULL; + return of_match_device(matches, dev) != NULL; } struct macio_dev *macio_dev_get(struct macio_dev *dev) @@ -83,7 +82,7 @@ static int macio_device_probe(struct device *dev) macio_dev_get(macio_dev); - match = of_match_device(drv->driver.of_match_table, &macio_dev->ofdev); + match = of_match_device(drv->driver.of_match_table, dev); if (match) error = drv->probe(macio_dev, match); if (error) diff --git a/drivers/of/device.c b/drivers/of/device.c index 24068bbbce1a..7d18f8e0b013 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -10,8 +10,7 @@ #include /** - * of_match_device - Tell if an of_device structure has a matching - * of_match structure + * of_match_device - Tell if a struct device matches an of_device_id list * @ids: array of of device match structures to search in * @dev: the of device structure to match against * @@ -19,11 +18,11 @@ * system is in its list of supported devices. */ const struct of_device_id *of_match_device(const struct of_device_id *matches, - const struct of_device *dev) + const struct device *dev) { - if (!dev->dev.of_node) + if (!dev->of_node) return NULL; - return of_match_node(matches, dev->dev.of_node); + return of_match_node(matches, dev->of_node); } EXPORT_SYMBOL(of_match_device); diff --git a/drivers/of/platform.c b/drivers/of/platform.c index ba402c613ede..7dacc1ebe91e 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -21,13 +21,12 @@ extern struct device_attribute of_platform_device_attrs[]; static int of_platform_bus_match(struct device *dev, struct device_driver *drv) { - struct of_device *of_dev = to_of_device(dev); const struct of_device_id *matches = drv->of_match_table; if (!matches) return 0; - return of_match_device(matches, of_dev) != NULL; + return of_match_device(matches, dev) != NULL; } static int of_platform_device_probe(struct device *dev) @@ -45,7 +44,7 @@ static int of_platform_device_probe(struct device *dev) of_dev_get(of_dev); - match = of_match_device(drv->driver.of_match_table, of_dev); + match = of_match_device(drv->driver.of_match_table, dev); if (match) error = drv->probe(of_dev, match); if (error) diff --git a/include/linux/of_device.h b/include/linux/of_device.h index e7904a9cd3a3..11651facc5f1 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -11,7 +11,7 @@ #define to_of_device(d) container_of(d, struct of_device, dev) extern const struct of_device_id *of_match_device( - const struct of_device_id *matches, const struct of_device *dev); + const struct of_device_id *matches, const struct device *dev); extern struct of_device *of_dev_get(struct of_device *dev); extern void of_dev_put(struct of_device *dev); -- cgit v1.2.3 From 056676dabd9f4c69a6adcad208e9aa2ca7241400 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 19 May 2010 18:34:16 +0000 Subject: sh: prepare the SDHI MFD driver to pass DMA configuration to tmio_mmc.c Pass DMA slave IDs from platform down to the tmio_mmc driver, to be used for dmaengine configuration. Signed-off-by: Guennadi Liakhovetski Acked-by: Samuel Ortiz Signed-off-by: Paul Mundt --- drivers/mfd/sh_mobile_sdhi.c | 24 ++++++++++++++++++++---- include/linux/mfd/sh_mobile_sdhi.h | 2 ++ 2 files changed, 22 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/sh_mobile_sdhi.c b/drivers/mfd/sh_mobile_sdhi.c index 497f91b6138e..555374db8662 100644 --- a/drivers/mfd/sh_mobile_sdhi.c +++ b/drivers/mfd/sh_mobile_sdhi.c @@ -26,11 +26,15 @@ #include #include #include +#include struct sh_mobile_sdhi { struct clk *clk; struct tmio_mmc_data mmc_data; struct mfd_cell cell_mmc; + struct sh_dmae_slave param_tx; + struct sh_dmae_slave param_rx; + struct tmio_mmc_dma dma_priv; }; static struct resource sh_mobile_sdhi_resources[] = { @@ -64,6 +68,8 @@ static void sh_mobile_sdhi_set_pwr(struct platform_device *tmio, int state) static int __init sh_mobile_sdhi_probe(struct platform_device *pdev) { struct sh_mobile_sdhi *priv; + struct tmio_mmc_data *mmc_data; + struct sh_mobile_sdhi_info *p = pdev->dev.platform_data; struct resource *mem; char clk_name[8]; int ret, irq; @@ -85,6 +91,8 @@ static int __init sh_mobile_sdhi_probe(struct platform_device *pdev) return -ENOMEM; } + mmc_data = &priv->mmc_data; + snprintf(clk_name, sizeof(clk_name), "sdhi%d", pdev->id); priv->clk = clk_get(&pdev->dev, clk_name); if (IS_ERR(priv->clk)) { @@ -96,12 +104,20 @@ static int __init sh_mobile_sdhi_probe(struct platform_device *pdev) clk_enable(priv->clk); - priv->mmc_data.hclk = clk_get_rate(priv->clk); - priv->mmc_data.set_pwr = sh_mobile_sdhi_set_pwr; - priv->mmc_data.capabilities = MMC_CAP_MMC_HIGHSPEED; + mmc_data->hclk = clk_get_rate(priv->clk); + mmc_data->set_pwr = sh_mobile_sdhi_set_pwr; + mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED; + + if (p && p->dma_slave_tx >= 0 && p->dma_slave_rx >= 0) { + priv->param_tx.slave_id = p->dma_slave_tx; + priv->param_rx.slave_id = p->dma_slave_rx; + priv->dma_priv.chan_priv_tx = &priv->param_tx; + priv->dma_priv.chan_priv_rx = &priv->param_rx; + mmc_data->dma = &priv->dma_priv; + } memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc)); - priv->cell_mmc.driver_data = &priv->mmc_data; + priv->cell_mmc.driver_data = mmc_data; priv->cell_mmc.platform_data = &priv->cell_mmc; priv->cell_mmc.data_size = sizeof(priv->cell_mmc); diff --git a/include/linux/mfd/sh_mobile_sdhi.h b/include/linux/mfd/sh_mobile_sdhi.h index 3bcd7163485c..c305461e7f47 100644 --- a/include/linux/mfd/sh_mobile_sdhi.h +++ b/include/linux/mfd/sh_mobile_sdhi.h @@ -2,6 +2,8 @@ #define __SH_MOBILE_SDHI_H__ struct sh_mobile_sdhi_info { + int dma_slave_tx; + int dma_slave_rx; void (*set_pwr)(struct platform_device *pdev, int state); }; -- cgit v1.2.3 From 311f3ac76826bfd8ed6213ded91ec947df164def Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 19 May 2010 18:34:22 +0000 Subject: mmc: add DMA support to tmio_mmc driver, when used on SuperH SDHI controllers on SuperH, served by the tmio_mmc driver, can use slave DMA for data transfer. This patch adds support for the dmaengine API to the tmio_mmc driver. Signed-off-by: Guennadi Liakhovetski Acked-by: Ian Molton Signed-off-by: Paul Mundt --- drivers/mfd/Kconfig | 6 + drivers/mmc/host/tmio_mmc.c | 359 ++++++++++++++++++++++++++++++++++++++++---- drivers/mmc/host/tmio_mmc.h | 13 ++ 3 files changed, 348 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index de3e74cde51c..3c6a9860dd9c 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -49,6 +49,7 @@ config MFD_SH_MOBILE_SDHI bool "Support for SuperH Mobile SDHI" depends on SUPERH || ARCH_SHMOBILE select MFD_CORE + select TMIO_MMC_DMA ---help--- This driver supports the SDHI hardware block found in many SuperH Mobile SoCs. @@ -162,6 +163,11 @@ config MFD_TMIO bool default n +config TMIO_MMC_DMA + bool + select DMA_ENGINE + select DMADEVICES + config MFD_T7L66XB bool "Support Toshiba T7L66XB" depends on ARM && HAVE_CLK diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index b2b577f6afd4..3ecd41875fac 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -131,8 +132,8 @@ tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd) host->cmd = cmd; -/* FIXME - this seems to be ok comented out but the spec suggest this bit should - * be set when issuing app commands. +/* FIXME - this seems to be ok commented out but the spec suggest this bit + * should be set when issuing app commands. * if(cmd->flags & MMC_FLAG_ACMD) * c |= APP_CMD; */ @@ -155,12 +156,12 @@ tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd) return 0; } -/* This chip always returns (at least?) as much data as you ask for. +/* + * This chip always returns (at least?) as much data as you ask for. * I'm unsure what happens if you ask for less than a block. This should be * looked into to ensure that a funny length read doesnt hose the controller. - * */ -static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host) +static void tmio_mmc_pio_irq(struct tmio_mmc_host *host) { struct mmc_data *data = host->data; unsigned short *buf; @@ -180,7 +181,7 @@ static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host) count = data->blksz; pr_debug("count: %08x offset: %08x flags %08x\n", - count, host->sg_off, data->flags); + count, host->sg_off, data->flags); /* Transfer the data */ if (data->flags & MMC_DATA_READ) @@ -198,7 +199,7 @@ static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host) return; } -static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) +static void tmio_mmc_do_data_irq(struct tmio_mmc_host *host) { struct mmc_data *data = host->data; struct mmc_command *stop; @@ -206,7 +207,7 @@ static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) host->data = NULL; if (!data) { - pr_debug("Spurious data end IRQ\n"); + dev_warn(&host->pdev->dev, "Spurious data end IRQ\n"); return; } stop = data->stop; @@ -219,7 +220,8 @@ static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) pr_debug("Completed data request\n"); - /*FIXME - other drivers allow an optional stop command of any given type + /* + * FIXME: other drivers allow an optional stop command of any given type * which we dont do, as the chip can auto generate them. * Perhaps we can be smarter about when to use auto CMD12 and * only issue the auto request when we know this is the desired @@ -227,10 +229,17 @@ static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) * upper layers expect. For now, we do what works. */ - if (data->flags & MMC_DATA_READ) - disable_mmc_irqs(host, TMIO_MASK_READOP); - else - disable_mmc_irqs(host, TMIO_MASK_WRITEOP); + if (data->flags & MMC_DATA_READ) { + if (!host->chan_rx) + disable_mmc_irqs(host, TMIO_MASK_READOP); + dev_dbg(&host->pdev->dev, "Complete Rx request %p\n", + host->mrq); + } else { + if (!host->chan_tx) + disable_mmc_irqs(host, TMIO_MASK_WRITEOP); + dev_dbg(&host->pdev->dev, "Complete Tx request %p\n", + host->mrq); + } if (stop) { if (stop->opcode == 12 && !stop->arg) @@ -242,7 +251,35 @@ static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) tmio_mmc_finish_request(host); } -static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, +static void tmio_mmc_data_irq(struct tmio_mmc_host *host) +{ + struct mmc_data *data = host->data; + + if (!data) + return; + + if (host->chan_tx && (data->flags & MMC_DATA_WRITE)) { + /* + * Has all data been written out yet? Testing on SuperH showed, + * that in most cases the first interrupt comes already with the + * BUSY status bit clear, but on some operations, like mount or + * in the beginning of a write / sync / umount, there is one + * DATAEND interrupt with the BUSY bit set, in this cases + * waiting for one more interrupt fixes the problem. + */ + if (!(sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_CMD_BUSY)) { + disable_mmc_irqs(host, TMIO_STAT_DATAEND); + tasklet_schedule(&host->dma_complete); + } + } else if (host->chan_rx && (data->flags & MMC_DATA_READ)) { + disable_mmc_irqs(host, TMIO_STAT_DATAEND); + tasklet_schedule(&host->dma_complete); + } else { + tmio_mmc_do_data_irq(host); + } +} + +static void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, unsigned int stat) { struct mmc_command *cmd = host->cmd; @@ -282,10 +319,16 @@ static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, * If theres no data or we encountered an error, finish now. */ if (host->data && !cmd->error) { - if (host->data->flags & MMC_DATA_READ) - enable_mmc_irqs(host, TMIO_MASK_READOP); - else - enable_mmc_irqs(host, TMIO_MASK_WRITEOP); + if (host->data->flags & MMC_DATA_READ) { + if (!host->chan_rx) + enable_mmc_irqs(host, TMIO_MASK_READOP); + } else { + struct dma_chan *chan = host->chan_tx; + if (!chan) + enable_mmc_irqs(host, TMIO_MASK_WRITEOP); + else + tasklet_schedule(&host->dma_issue); + } } else { tmio_mmc_finish_request(host); } @@ -293,7 +336,6 @@ static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, return; } - static irqreturn_t tmio_mmc_irq(int irq, void *devid) { struct tmio_mmc_host *host = devid; @@ -311,7 +353,7 @@ static irqreturn_t tmio_mmc_irq(int irq, void *devid) if (!ireg) { disable_mmc_irqs(host, status & ~irq_mask); - pr_debug("tmio_mmc: Spurious irq, disabling! " + pr_warning("tmio_mmc: Spurious irq, disabling! " "0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg); pr_debug_status(status); @@ -363,16 +405,265 @@ out: return IRQ_HANDLED; } +#ifdef CONFIG_TMIO_MMC_DMA +static void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable) +{ +#if defined(CONFIG_SUPERH) || defined(CONFIG_ARCH_SHMOBILE) + /* Switch DMA mode on or off - SuperH specific? */ + sd_ctrl_write16(host, 0xd8, enable ? 2 : 0); +#endif +} + +static void tmio_dma_complete(void *arg) +{ + struct tmio_mmc_host *host = arg; + + dev_dbg(&host->pdev->dev, "Command completed\n"); + + if (!host->data) + dev_warn(&host->pdev->dev, "NULL data in DMA completion!\n"); + else + enable_mmc_irqs(host, TMIO_STAT_DATAEND); +} + +static int tmio_mmc_start_dma_rx(struct tmio_mmc_host *host) +{ + struct scatterlist *sg = host->sg_ptr; + struct dma_async_tx_descriptor *desc = NULL; + struct dma_chan *chan = host->chan_rx; + int ret; + + ret = dma_map_sg(&host->pdev->dev, sg, host->sg_len, DMA_FROM_DEVICE); + if (ret > 0) { + host->dma_sglen = ret; + desc = chan->device->device_prep_slave_sg(chan, sg, ret, + DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + } + + if (desc) { + host->desc = desc; + desc->callback = tmio_dma_complete; + desc->callback_param = host; + host->cookie = desc->tx_submit(desc); + if (host->cookie < 0) { + host->desc = NULL; + ret = host->cookie; + } else { + chan->device->device_issue_pending(chan); + } + } + dev_dbg(&host->pdev->dev, "%s(): mapped %d -> %d, cookie %d, rq %p\n", + __func__, host->sg_len, ret, host->cookie, host->mrq); + + if (!host->desc) { + /* DMA failed, fall back to PIO */ + if (ret >= 0) + ret = -EIO; + host->chan_rx = NULL; + dma_release_channel(chan); + /* Free the Tx channel too */ + chan = host->chan_tx; + if (chan) { + host->chan_tx = NULL; + dma_release_channel(chan); + } + dev_warn(&host->pdev->dev, + "DMA failed: %d, falling back to PIO\n", ret); + tmio_mmc_enable_dma(host, false); + reset(host); + /* Fail this request, let above layers recover */ + host->mrq->cmd->error = ret; + tmio_mmc_finish_request(host); + } + + dev_dbg(&host->pdev->dev, "%s(): desc %p, cookie %d, sg[%d]\n", __func__, + desc, host->cookie, host->sg_len); + + return ret > 0 ? 0 : ret; +} + +static int tmio_mmc_start_dma_tx(struct tmio_mmc_host *host) +{ + struct scatterlist *sg = host->sg_ptr; + struct dma_async_tx_descriptor *desc = NULL; + struct dma_chan *chan = host->chan_tx; + int ret; + + ret = dma_map_sg(&host->pdev->dev, sg, host->sg_len, DMA_TO_DEVICE); + if (ret > 0) { + host->dma_sglen = ret; + desc = chan->device->device_prep_slave_sg(chan, sg, ret, + DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + } + + if (desc) { + host->desc = desc; + desc->callback = tmio_dma_complete; + desc->callback_param = host; + host->cookie = desc->tx_submit(desc); + if (host->cookie < 0) { + host->desc = NULL; + ret = host->cookie; + } + } + dev_dbg(&host->pdev->dev, "%s(): mapped %d -> %d, cookie %d, rq %p\n", + __func__, host->sg_len, ret, host->cookie, host->mrq); + + if (!host->desc) { + /* DMA failed, fall back to PIO */ + if (ret >= 0) + ret = -EIO; + host->chan_tx = NULL; + dma_release_channel(chan); + /* Free the Rx channel too */ + chan = host->chan_rx; + if (chan) { + host->chan_rx = NULL; + dma_release_channel(chan); + } + dev_warn(&host->pdev->dev, + "DMA failed: %d, falling back to PIO\n", ret); + tmio_mmc_enable_dma(host, false); + reset(host); + /* Fail this request, let above layers recover */ + host->mrq->cmd->error = ret; + tmio_mmc_finish_request(host); + } + + dev_dbg(&host->pdev->dev, "%s(): desc %p, cookie %d\n", __func__, + desc, host->cookie); + + return ret > 0 ? 0 : ret; +} + +static int tmio_mmc_start_dma(struct tmio_mmc_host *host, + struct mmc_data *data) +{ + if (data->flags & MMC_DATA_READ) { + if (host->chan_rx) + return tmio_mmc_start_dma_rx(host); + } else { + if (host->chan_tx) + return tmio_mmc_start_dma_tx(host); + } + + return 0; +} + +static void tmio_issue_tasklet_fn(unsigned long priv) +{ + struct tmio_mmc_host *host = (struct tmio_mmc_host *)priv; + struct dma_chan *chan = host->chan_tx; + + chan->device->device_issue_pending(chan); +} + +static void tmio_tasklet_fn(unsigned long arg) +{ + struct tmio_mmc_host *host = (struct tmio_mmc_host *)arg; + + if (host->data->flags & MMC_DATA_READ) + dma_unmap_sg(&host->pdev->dev, host->sg_ptr, host->dma_sglen, + DMA_FROM_DEVICE); + else + dma_unmap_sg(&host->pdev->dev, host->sg_ptr, host->dma_sglen, + DMA_TO_DEVICE); + + tmio_mmc_do_data_irq(host); +} + +/* It might be necessary to make filter MFD specific */ +static bool tmio_mmc_filter(struct dma_chan *chan, void *arg) +{ + dev_dbg(chan->device->dev, "%s: slave data %p\n", __func__, arg); + chan->private = arg; + return true; +} + +static void tmio_mmc_request_dma(struct tmio_mmc_host *host, + struct tmio_mmc_data *pdata) +{ + host->cookie = -EINVAL; + host->desc = NULL; + + /* We can only either use DMA for both Tx and Rx or not use it at all */ + if (pdata->dma) { + dma_cap_mask_t mask; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + + host->chan_tx = dma_request_channel(mask, tmio_mmc_filter, + pdata->dma->chan_priv_tx); + dev_dbg(&host->pdev->dev, "%s: TX: got channel %p\n", __func__, + host->chan_tx); + + if (!host->chan_tx) + return; + + host->chan_rx = dma_request_channel(mask, tmio_mmc_filter, + pdata->dma->chan_priv_rx); + dev_dbg(&host->pdev->dev, "%s: RX: got channel %p\n", __func__, + host->chan_rx); + + if (!host->chan_rx) { + dma_release_channel(host->chan_tx); + host->chan_tx = NULL; + return; + } + + tasklet_init(&host->dma_complete, tmio_tasklet_fn, (unsigned long)host); + tasklet_init(&host->dma_issue, tmio_issue_tasklet_fn, (unsigned long)host); + + tmio_mmc_enable_dma(host, true); + } +} + +static void tmio_mmc_release_dma(struct tmio_mmc_host *host) +{ + if (host->chan_tx) { + struct dma_chan *chan = host->chan_tx; + host->chan_tx = NULL; + dma_release_channel(chan); + } + if (host->chan_rx) { + struct dma_chan *chan = host->chan_rx; + host->chan_rx = NULL; + dma_release_channel(chan); + } + + host->cookie = -EINVAL; + host->desc = NULL; +} +#else +static int tmio_mmc_start_dma(struct tmio_mmc_host *host, + struct mmc_data *data) +{ + return 0; +} + +static void tmio_mmc_request_dma(struct tmio_mmc_host *host, + struct tmio_mmc_data *pdata) +{ + host->chan_tx = NULL; + host->chan_rx = NULL; +} + +static void tmio_mmc_release_dma(struct tmio_mmc_host *host) +{ +} +#endif + static int tmio_mmc_start_data(struct tmio_mmc_host *host, struct mmc_data *data) { pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n", - data->blksz, data->blocks); + data->blksz, data->blocks); /* Hardware cannot perform 1 and 2 byte requests in 4 bit mode */ if (data->blksz < 4 && host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) { - printk(KERN_ERR "%s: %d byte block unsupported in 4 bit mode\n", - mmc_hostname(host->mmc), data->blksz); + pr_err("%s: %d byte block unsupported in 4 bit mode\n", + mmc_hostname(host->mmc), data->blksz); return -EINVAL; } @@ -383,7 +674,7 @@ static int tmio_mmc_start_data(struct tmio_mmc_host *host, sd_ctrl_write16(host, CTL_SD_XFER_LEN, data->blksz); sd_ctrl_write16(host, CTL_XFER_BLK_COUNT, data->blocks); - return 0; + return tmio_mmc_start_dma(host, data); } /* Process requests from the MMC layer */ @@ -404,7 +695,6 @@ static void tmio_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) } ret = tmio_mmc_start_command(host, mrq->cmd); - if (!ret) return; @@ -459,10 +749,10 @@ static int tmio_mmc_get_ro(struct mmc_host *mmc) { struct tmio_mmc_host *host = mmc_priv(mmc); - return (sd_ctrl_read16(host, CTL_STATUS) & TMIO_STAT_WRPROTECT) ? 0 : 1; + return (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT) ? 0 : 1; } -static struct mmc_host_ops tmio_mmc_ops = { +static const struct mmc_host_ops tmio_mmc_ops = { .request = tmio_mmc_request, .set_ios = tmio_mmc_set_ios, .get_ro = tmio_mmc_get_ro, @@ -515,6 +805,7 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) struct tmio_mmc_host *host; struct mmc_host *mmc; int ret = -EINVAL; + u32 irq_mask = TMIO_MASK_CMD; if (dev->num_resources != 2) goto out; @@ -578,13 +869,20 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) if (ret) goto cell_disable; + /* See if we also get DMA */ + tmio_mmc_request_dma(host, pdata); + mmc_add_host(mmc); - printk(KERN_INFO "%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc), - (unsigned long)host->ctl, host->irq); + pr_info("%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc), + (unsigned long)host->ctl, host->irq); /* Unmask the IRQs we want to know about */ - enable_mmc_irqs(host, TMIO_MASK_IRQ); + if (!host->chan_rx) + irq_mask |= TMIO_MASK_READOP; + if (!host->chan_tx) + irq_mask |= TMIO_MASK_WRITEOP; + enable_mmc_irqs(host, irq_mask); return 0; @@ -609,6 +907,7 @@ static int __devexit tmio_mmc_remove(struct platform_device *dev) if (mmc) { struct tmio_mmc_host *host = mmc_priv(mmc); mmc_remove_host(mmc); + tmio_mmc_release_dma(host); free_irq(host->irq, host); if (cell->disable) cell->disable(dev); diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index dafecfbcd91a..64f7d5dfc106 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h @@ -10,6 +10,8 @@ */ #include +#include +#include #define CTL_SD_CMD 0x00 #define CTL_ARG_REG 0x04 @@ -106,6 +108,17 @@ struct tmio_mmc_host { unsigned int sg_off; struct platform_device *pdev; + + /* DMA support */ + struct dma_chan *chan_rx; + struct dma_chan *chan_tx; + struct tasklet_struct dma_complete; + struct tasklet_struct dma_issue; +#ifdef CONFIG_TMIO_MMC_DMA + struct dma_async_tx_descriptor *desc; + unsigned int dma_sglen; + dma_cookie_t cookie; +#endif }; #include -- cgit v1.2.3 From 3734574cac1002e4cf037e3591cf222b1e04dfa4 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Sat, 22 May 2010 00:57:26 -0700 Subject: Input: enable onkey driver of max8925 When ONKEY is held for 3 seconds, KEY_POWER event is reported. Signed-off-by: Haojian Zhuang Signed-off-by: Dmitry Torokhov --- drivers/input/misc/Kconfig | 10 +++ drivers/input/misc/Makefile | 1 + drivers/input/misc/max8925_onkey.c | 148 +++++++++++++++++++++++++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 drivers/input/misc/max8925_onkey.c (limited to 'drivers') diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 48cdabec372a..c44b9eafc556 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -80,6 +80,16 @@ config INPUT_M68K_BEEP tristate "M68k Beeper support" depends on M68K +config INPUT_MAX8925_ONKEY + tristate "MAX8925 ONKEY support" + depends on MFD_MAX8925 + help + Support the ONKEY of MAX8925 PMICs as an input device + reporting power button status. + + To compile this driver as a module, choose M here: the module + will be called max8925_onkey. + config INPUT_APANEL tristate "Fujitsu Lifebook Application Panel buttons" depends on X86 && I2C && LEDS_CLASS diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index f9f577031e06..71fe57d8023f 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o +obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o obj-$(CONFIG_INPUT_PCAP) += pcap_keys.o obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o obj-$(CONFIG_INPUT_PCF8574) += pcf8574_keypad.o diff --git a/drivers/input/misc/max8925_onkey.c b/drivers/input/misc/max8925_onkey.c new file mode 100644 index 000000000000..80af44608018 --- /dev/null +++ b/drivers/input/misc/max8925_onkey.c @@ -0,0 +1,148 @@ +/** + * max8925_onkey.c - MAX8925 ONKEY driver + * + * Copyright (C) 2009 Marvell International Ltd. + * Haojian Zhuang + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file "COPYING" in the main directory of this + * archive for more details. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define HARDRESET_EN (1 << 7) +#define PWREN_EN (1 << 7) + +struct max8925_onkey_info { + struct input_dev *idev; + struct i2c_client *i2c; + int irq; +}; + +/* + * MAX8925 gives us an interrupt when ONKEY is held for 3 seconds. + * max8925_set_bits() operates I2C bus and may sleep. So implement + * it in thread IRQ handler. + */ +static irqreturn_t max8925_onkey_handler(int irq, void *data) +{ + struct max8925_onkey_info *info = data; + + input_report_key(info->idev, KEY_POWER, 1); + input_sync(info->idev); + + /* Enable hardreset to halt if system isn't shutdown on time */ + max8925_set_bits(info->i2c, MAX8925_SYSENSEL, + HARDRESET_EN, HARDRESET_EN); + + return IRQ_HANDLED; +} + +static int __devinit max8925_onkey_probe(struct platform_device *pdev) +{ + struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); + struct max8925_onkey_info *info; + int error; + + info = kzalloc(sizeof(struct max8925_onkey_info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->i2c = chip->i2c; + info->irq = chip->irq_base + MAX8925_IRQ_GPM_SW_3SEC; + + info->idev = input_allocate_device(); + if (!info->idev) { + dev_err(chip->dev, "Failed to allocate input dev\n"); + error = -ENOMEM; + goto out_input; + } + + info->idev->name = "max8925_on"; + info->idev->phys = "max8925_on/input0"; + info->idev->id.bustype = BUS_I2C; + info->idev->dev.parent = &pdev->dev; + info->idev->evbit[0] = BIT_MASK(EV_KEY); + info->idev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER); + + error = request_threaded_irq(info->irq, NULL, max8925_onkey_handler, + IRQF_ONESHOT, "onkey", info); + if (error < 0) { + dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", + info->irq, error); + goto out_irq; + } + + error = input_register_device(info->idev); + if (error) { + dev_err(chip->dev, "Can't register input device: %d\n", error); + goto out; + } + + platform_set_drvdata(pdev, info); + + return 0; + +out: + free_irq(info->irq, info); +out_irq: + input_free_device(info->idev); +out_input: + kfree(info); + return error; +} + +static int __devexit max8925_onkey_remove(struct platform_device *pdev) +{ + struct max8925_onkey_info *info = platform_get_drvdata(pdev); + + free_irq(info->irq, info); + input_unregister_device(info->idev); + kfree(info); + + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct platform_driver max8925_onkey_driver = { + .driver = { + .name = "max8925-onkey", + .owner = THIS_MODULE, + }, + .probe = max8925_onkey_probe, + .remove = __devexit_p(max8925_onkey_remove), +}; + +static int __init max8925_onkey_init(void) +{ + return platform_driver_register(&max8925_onkey_driver); +} +module_init(max8925_onkey_init); + +static void __exit max8925_onkey_exit(void) +{ + platform_driver_unregister(&max8925_onkey_driver); +} +module_exit(max8925_onkey_exit); + +MODULE_DESCRIPTION("Maxim MAX8925 ONKEY driver"); +MODULE_AUTHOR("Haojian Zhuang "); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From f2126a99675a930b3ab5258698d82b2a3c69af3f Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Sat, 22 May 2010 00:57:26 -0700 Subject: Input: twl4030-vibra - correct the power down sequence It is better to turn off the first APLL, than the codec. Signed-off-by: Peter Ujfalusi Signed-off-by: Dmitry Torokhov --- drivers/input/misc/twl4030-vibra.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c index fee9eac8e04a..4f9b2afc24e8 100644 --- a/drivers/input/misc/twl4030-vibra.c +++ b/drivers/input/misc/twl4030-vibra.c @@ -90,8 +90,8 @@ static void vibra_disable(struct vibra_info *info) twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, (reg & ~TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL); - twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER); twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL); + twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER); info->enabled = false; } -- cgit v1.2.3 From ac8fb3e8627d5494f3d2221925a82be4c1778b0e Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 19 May 2010 18:36:02 +0000 Subject: tmio: add a platform flag to disable card write-protection detection Write-protection status is not always available, e.g., micro-SD cards do not have a write-protection switch at all. This patch adds a flag to let platforms force tmio_mmc to consider the card writable. Signed-off-by: Guennadi Liakhovetski Acked-by: Ian Molton Signed-off-by: Paul Mundt --- drivers/mmc/host/tmio_mmc.c | 5 ++++- include/linux/mfd/tmio.h | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index 3ecd41875fac..faa16b7d9412 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c @@ -748,8 +748,11 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) static int tmio_mmc_get_ro(struct mmc_host *mmc) { struct tmio_mmc_host *host = mmc_priv(mmc); + struct mfd_cell *cell = host->pdev->dev.platform_data; + struct tmio_mmc_data *pdata = cell->driver_data; - return (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT) ? 0 : 1; + return ((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) || + (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT)) ? 0 : 1; } static const struct mmc_host_ops tmio_mmc_ops = { diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h index 360fc953d7bb..feeed0b9ee70 100644 --- a/include/linux/mfd/tmio.h +++ b/include/linux/mfd/tmio.h @@ -50,6 +50,9 @@ tmio_iowrite16((val) >> 16, (base) + ((reg + 2) << (shift))); \ } while (0) +/* tmio MMC platform flags */ +#define TMIO_MMC_WRPROTECT_DISABLE (1 << 0) + int tmio_core_mmc_enable(void __iomem *cnf, int shift, unsigned long base); int tmio_core_mmc_resume(void __iomem *cnf, int shift, unsigned long base); void tmio_core_mmc_pwr(void __iomem *cnf, int shift, int state); @@ -66,6 +69,7 @@ struct tmio_mmc_dma { struct tmio_mmc_data { unsigned int hclk; unsigned long capabilities; + unsigned long flags; struct tmio_mmc_dma *dma; void (*set_pwr)(struct platform_device *host, int state); void (*set_clk_div)(struct platform_device *host, int state); -- cgit v1.2.3 From f87c20a9db43f6f731270eeef616e1bcc266c2d4 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 19 May 2010 18:36:08 +0000 Subject: mfd: pass platform flags down to the tmio_mmc driver Signed-off-by: Guennadi Liakhovetski Acked-by: Ian Molton Signed-off-by: Paul Mundt --- drivers/mfd/sh_mobile_sdhi.c | 2 ++ include/linux/mfd/sh_mobile_sdhi.h | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/mfd/sh_mobile_sdhi.c b/drivers/mfd/sh_mobile_sdhi.c index 555374db8662..19e0d48a599a 100644 --- a/drivers/mfd/sh_mobile_sdhi.c +++ b/drivers/mfd/sh_mobile_sdhi.c @@ -107,6 +107,8 @@ static int __init sh_mobile_sdhi_probe(struct platform_device *pdev) mmc_data->hclk = clk_get_rate(priv->clk); mmc_data->set_pwr = sh_mobile_sdhi_set_pwr; mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED; + if (p) + mmc_data->flags = p->tmio_flags; if (p && p->dma_slave_tx >= 0 && p->dma_slave_rx >= 0) { priv->param_tx.slave_id = p->dma_slave_tx; diff --git a/include/linux/mfd/sh_mobile_sdhi.h b/include/linux/mfd/sh_mobile_sdhi.h index c305461e7f47..c7b47f8ad650 100644 --- a/include/linux/mfd/sh_mobile_sdhi.h +++ b/include/linux/mfd/sh_mobile_sdhi.h @@ -4,6 +4,7 @@ struct sh_mobile_sdhi_info { int dma_slave_tx; int dma_slave_rx; + unsigned long tmio_flags; void (*set_pwr)(struct platform_device *pdev, int state); }; -- cgit v1.2.3 From a2b14dc9615c215a8cf4f2041f6c0c3fff5fc486 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 19 May 2010 18:37:25 +0000 Subject: mmc: let MFD's provide supported Vdd card voltages to tmio_mmc Signed-off-by: Guennadi Liakhovetski Acked-by: Ian Molton Signed-off-by: Paul Mundt --- drivers/mmc/host/tmio_mmc.c | 5 ++++- include/linux/mfd/tmio.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index faa16b7d9412..883fcac21004 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c @@ -847,7 +847,10 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) mmc->caps |= pdata->capabilities; mmc->f_max = pdata->hclk; mmc->f_min = mmc->f_max / 512; - mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; + if (pdata->ocr_mask) + mmc->ocr_avail = pdata->ocr_mask; + else + mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; /* Tell the MFD core we are ready to be enabled */ if (cell->enable) { diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h index feeed0b9ee70..f07425bc3dcd 100644 --- a/include/linux/mfd/tmio.h +++ b/include/linux/mfd/tmio.h @@ -70,6 +70,7 @@ struct tmio_mmc_data { unsigned int hclk; unsigned long capabilities; unsigned long flags; + u32 ocr_mask; /* available voltages */ struct tmio_mmc_dma *dma; void (*set_pwr)(struct platform_device *host, int state); void (*set_clk_div)(struct platform_device *host, int state); -- cgit v1.2.3 From bb0fe533514c1d480c6c16f8bad070270a73a96c Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 19 May 2010 18:37:36 +0000 Subject: sh: allow platforms to specify SD-card supported voltages Boards can have different supplied voltages on different SD card slots. This information has to be passed down to the SD/MMC driver. Signed-off-by: Guennadi Liakhovetski Acked-by: Ian Molton Signed-off-by: Paul Mundt --- drivers/mfd/sh_mobile_sdhi.c | 4 +++- include/linux/mfd/sh_mobile_sdhi.h | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mfd/sh_mobile_sdhi.c b/drivers/mfd/sh_mobile_sdhi.c index 19e0d48a599a..cd164595f08a 100644 --- a/drivers/mfd/sh_mobile_sdhi.c +++ b/drivers/mfd/sh_mobile_sdhi.c @@ -107,8 +107,10 @@ static int __init sh_mobile_sdhi_probe(struct platform_device *pdev) mmc_data->hclk = clk_get_rate(priv->clk); mmc_data->set_pwr = sh_mobile_sdhi_set_pwr; mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED; - if (p) + if (p) { mmc_data->flags = p->tmio_flags; + mmc_data->ocr_mask = p->tmio_ocr_mask; + } if (p && p->dma_slave_tx >= 0 && p->dma_slave_rx >= 0) { priv->param_tx.slave_id = p->dma_slave_tx; diff --git a/include/linux/mfd/sh_mobile_sdhi.h b/include/linux/mfd/sh_mobile_sdhi.h index c7b47f8ad650..49067802a6d7 100644 --- a/include/linux/mfd/sh_mobile_sdhi.h +++ b/include/linux/mfd/sh_mobile_sdhi.h @@ -1,10 +1,13 @@ #ifndef __SH_MOBILE_SDHI_H__ #define __SH_MOBILE_SDHI_H__ +#include + struct sh_mobile_sdhi_info { int dma_slave_tx; int dma_slave_rx; unsigned long tmio_flags; + u32 tmio_ocr_mask; /* available MMC voltages */ void (*set_pwr)(struct platform_device *pdev, int state); }; -- cgit v1.2.3 From 85b8e3ffc47b2a1913be3079e9f1c1f66a6240b2 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 21 May 2010 15:22:40 +0000 Subject: sh: fix Oops in the serial SCI driver Fix an Oops, triggering, if the DMA buffer allocation for the Rx channel in sh-sci.c fails. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- drivers/serial/sh-sci.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 4f73fb756745..5f90fcd7d107 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -1004,8 +1004,9 @@ static void sci_rx_dma_release(struct sci_port *s, bool enable_pio) s->chan_rx = NULL; s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL; dma_release_channel(chan); - dma_free_coherent(port->dev, s->buf_len_rx * 2, - sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0])); + if (sg_dma_address(&s->sg_rx[0])) + dma_free_coherent(port->dev, s->buf_len_rx * 2, + sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0])); if (enable_pio) sci_start_rx(port); } -- cgit v1.2.3 From 7a5c106a0e8fd03a806d0da77eef10b4045c43a6 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 21 May 2010 15:28:51 +0000 Subject: sh: prevent the DMA driver from unloading, while in use This prevents the driver from unloading, while it is in use. Unloading of the driver, while its DMA channels are held, leads to a kernel Oops. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- drivers/dma/shdma.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index a1727522343e..427d514796dd 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -1188,6 +1188,7 @@ static struct platform_driver sh_dmae_driver = { .remove = __exit_p(sh_dmae_remove), .shutdown = sh_dmae_shutdown, .driver = { + .owner = THIS_MODULE, .name = "sh-dma-engine", }, }; -- cgit v1.2.3 From 9255f1deec151ac0e84871d06bc27406cb81f26f Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 21 May 2010 15:30:12 +0000 Subject: sh: guard cookie consistency across termination in the DMA driver If all descriptors on a channel are terminated or the channel is released, update the completed cookie counter to match the last cookie. This prevents inconsistency warning on resumed DMA operation. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- drivers/dma/shdma.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 427d514796dd..a2a519fd2a24 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -722,6 +722,10 @@ static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all) { while (__ld_cleanup(sh_chan, all)) ; + + if (all) + /* Terminating - forgive uncompleted cookies */ + sh_chan->completed_cookie = sh_chan->common.cookie; } static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan) -- cgit v1.2.3 From f9218c2a60facc6ff9a793a9d9ab956194d70012 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Sat, 22 May 2010 02:18:02 -0600 Subject: spi/spi_mpc8xxx: fix potential memory corruption. tx_dma/rx_dma are already set to a dummy buffer when no tx/rx buffer and t->tx_dma/t->rx_dma does not contain a dma address, but NULL. This may lead to corruption of kernel memory. Fix this by leaving tx_dma/rx_dma alone. Do not INIT_TX_RX while controller is enabled, this is bad according to the MPC8321 manual. Signed-off-by: Joakim Tjernlund Acked-by: Anton Vorontsov Signed-off-by: Grant Likely --- drivers/spi/spi_mpc8xxx.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c index 14d052316502..0dfc482bbff5 100644 --- a/drivers/spi/spi_mpc8xxx.c +++ b/drivers/spi/spi_mpc8xxx.c @@ -241,7 +241,6 @@ static void mpc8xxx_spi_change_mode(struct spi_device *spi) /* Turn off SPI unit prior changing mode */ mpc8xxx_spi_write_reg(mode, cs->hw_mode & ~SPMODE_ENABLE); - mpc8xxx_spi_write_reg(mode, cs->hw_mode); /* When in CPM mode, we need to reinit tx and rx. */ if (mspi->flags & SPI_CPM_MODE) { @@ -258,7 +257,7 @@ static void mpc8xxx_spi_change_mode(struct spi_device *spi) } } } - + mpc8xxx_spi_write_reg(mode, cs->hw_mode); local_irq_restore(flags); } @@ -438,7 +437,7 @@ static int mpc8xxx_spi_cpm_bufs(struct mpc8xxx_spi *mspi, dev_err(dev, "unable to map tx dma\n"); return -ENOMEM; } - } else { + } else if (t->tx_buf) { mspi->tx_dma = t->tx_dma; } @@ -449,7 +448,7 @@ static int mpc8xxx_spi_cpm_bufs(struct mpc8xxx_spi *mspi, dev_err(dev, "unable to map rx dma\n"); goto err_rx_dma; } - } else { + } else if (t->rx_buf) { mspi->rx_dma = t->rx_dma; } -- cgit v1.2.3 From df1f1d1cb43b4ffdef5ba5f0623e2f73e94ce030 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 22 May 2010 10:22:49 +0200 Subject: drivers/mtd: Use memdup_user Use memdup_user when user data is immediately copied into the allocated region. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression from,to,size,flag; position p; identifier l1,l2; @@ - to = \(kmalloc@p\|kzalloc@p\)(size,flag); + to = memdup_user(from,size); if ( - to==NULL + IS_ERR(to) || ...) { <+... when != goto l1; - -ENOMEM + PTR_ERR(to) ...+> } - if (copy_from_user(to, from, size) != 0) { - <+... when != goto l2; - -EFAULT - ...+> - } // Signed-off-by: Julia Lawall Signed-off-by: David Woodhouse --- drivers/mtd/mtdchar.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 8bb5e4a66328..8b223c0343ee 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -404,14 +404,9 @@ static int mtd_do_writeoob(struct file *file, struct mtd_info *mtd, if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs)) return -EINVAL; - ops.oobbuf = kmalloc(length, GFP_KERNEL); - if (!ops.oobbuf) - return -ENOMEM; - - if (copy_from_user(ops.oobbuf, ptr, length)) { - kfree(ops.oobbuf); - return -EFAULT; - } + ops.oobbuf = memdup_user(ptr, length); + if (IS_ERR(ops.oobbuf)) + return PTR_ERR(ops.oobbuf); start &= ~((uint64_t)mtd->oobsize - 1); ret = mtd->write_oob(mtd, start, &ops); -- cgit v1.2.3 From 10b06122afcc78468bd1d009633cb71e528acdc5 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Fri, 21 May 2010 18:48:54 +0200 Subject: drm/radeon/kms: release AGP bridge at suspend I think it's good to release the AGP bridge at suspend and reacquire it at resume. Also fix : https://bugzilla.kernel.org/show_bug.cgi?id=15969 Signed-off-by: Jerome Glisse Cc: stable Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_agp.c | 5 +++++ drivers/gpu/drm/radeon/radeon_device.c | 2 ++ 3 files changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 66a37fb75839..669feb689bfc 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -576,6 +576,7 @@ typedef int (*radeon_packet3_check_t)(struct radeon_cs_parser *p, */ int radeon_agp_init(struct radeon_device *rdev); void radeon_agp_resume(struct radeon_device *rdev); +void radeon_agp_suspend(struct radeon_device *rdev); void radeon_agp_fini(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index 28e473f1f56f..f40dfb77f9b1 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c @@ -270,3 +270,8 @@ void radeon_agp_fini(struct radeon_device *rdev) } #endif } + +void radeon_agp_suspend(struct radeon_device *rdev) +{ + radeon_agp_fini(rdev); +} diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index a20b612ffe75..fdc3fdf78acb 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -754,6 +754,8 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) /* evict remaining vram memory */ radeon_bo_evict_vram(rdev); + radeon_agp_suspend(rdev); + pci_save_state(dev->pdev); if (state.event == PM_EVENT_SUSPEND) { /* Shut down the device */ -- cgit v1.2.3 From 579766020d2eee2f1c51af1641ef9a7dbc6a5798 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 23 May 2010 17:00:40 -0700 Subject: nouveau: fix acpi_lid_open undefined When CONFIG_ACPI_BUTTON=m (and probably when ACPI_BUTTON is not enabled) and NOUVEAU is built-in (not as a loadable module): nouveau_connector.c:(.text+0xe17ce): undefined reference to `acpi_lid_open' Signed-off-by: Randy Dunlap Acked-by: Ben Skeggs Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/nouveau_connector.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 7e663a79829f..266b0ff441af 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -241,7 +241,8 @@ nouveau_connector_detect(struct drm_connector *connector) if (nv_encoder && nv_connector->native_mode) { unsigned status = connector_status_connected; -#ifdef CONFIG_ACPI +#if defined(CONFIG_ACPI_BUTTON) || \ + (defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE)) if (!nouveau_ignorelid && !acpi_lid_open()) status = connector_status_unknown; #endif -- cgit v1.2.3 From f49d273df9087d92e20c485fe9f8355d4f55b933 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Mon, 24 May 2010 10:24:07 +1000 Subject: drm: Fixes linux-next & linux-2.6 checkstack warnings: drivers/gpu/drm/nouveau/nv40_graph.c: In function `nv40_graph_init': drivers/gpu/drm/nouveau/nv40_graph.c:400: warning: the frame size of 1184 bytes is larger than 1024 bytes drivers/gpu/drm/radeon/radeon_atombios.c: In function `radeon_get_atom_connector_info_from_supported_devices_table': drivers/gpu/drm/radeon/radeon_atombios.c:857: warning: the frame size of 1872 bytes is larger than 1024 bytes Signed-off-by: Prarit Bhargava Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/nv40_graph.c | 8 +++++++- drivers/gpu/drm/radeon/radeon_atombios.c | 13 +++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index 0616c96e4b67..704a25d04ac9 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c @@ -253,7 +253,11 @@ nv40_graph_init(struct drm_device *dev) if (!dev_priv->engine.graph.ctxprog) { struct nouveau_grctx ctx = {}; - uint32_t cp[256]; + uint32_t *cp; + + cp = kmalloc(sizeof(*cp) * 256, GFP_KERNEL); + if (!cp) + return -ENOMEM; ctx.dev = dev; ctx.mode = NOUVEAU_GRCTX_PROG; @@ -265,6 +269,8 @@ nv40_graph_init(struct drm_device *dev) nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); for (i = 0; i < ctx.ctxprog_len; i++) nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]); + + kfree(cp); } /* No context present currently */ diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 6e733fdc3349..24ea683f7cf5 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -680,10 +680,18 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct uint8_t dac; union atom_supported_devices *supported_devices; int i, j, max_device; - struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE]; + struct bios_connector *bios_connectors; + size_t bc_size = sizeof(*bios_connectors) * ATOM_MAX_SUPPORTED_DEVICE; - if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset)) + bios_connectors = kzalloc(bc_size, GFP_KERNEL); + if (!bios_connectors) + return false; + + if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, + &data_offset)) { + kfree(bios_connectors); return false; + } supported_devices = (union atom_supported_devices *)(ctx->bios + data_offset); @@ -851,6 +859,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct radeon_link_encoder_connector(dev); + kfree(bios_connectors); return true; } -- cgit v1.2.3 From b3040e40675ec2c43542331cd30d4ee3dae797e8 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Sun, 23 May 2010 20:28:19 -0700 Subject: DMA: PL330: Add dma api driver Add DMA Engine API driver for the PL330 DMAC. This driver is supposed to be reusable by various platforms that have one or more PL330 DMACs. Atm, DMA_SLAVE and DMA_MEMCPY capabilities have been implemented. Signed-off-by: Jassi Brar Reviewed-by: Linus Walleij [dan.j.williams@intel.com: missing slab.h and ->device_control() fixups] Signed-off-by: Dan Williams --- drivers/dma/Kconfig | 9 + drivers/dma/Makefile | 1 + drivers/dma/pl330.c | 866 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/amba/pl330.h | 45 +++ 4 files changed, 921 insertions(+) create mode 100644 drivers/dma/pl330.c create mode 100644 include/linux/amba/pl330.h (limited to 'drivers') diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 1b8877922fb0..9e01e96fee94 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -166,6 +166,15 @@ config TIMB_DMA config ARCH_HAS_ASYNC_TX_FIND_CHANNEL bool +config PL330_DMA + tristate "DMA API Driver for PL330" + select DMA_ENGINE + depends on PL330 + help + Select if your platform has one or more PL330 DMACs. + You need to provide platform specific settings via + platform_data for a dma-pl330 device. + config DMA_ENGINE bool diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 20881426c1ac..0fe5ebbfda5d 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -22,3 +22,4 @@ obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o obj-$(CONFIG_AMCC_PPC440SPE_ADMA) += ppc4xx/ obj-$(CONFIG_TIMB_DMA) += timb_dma.o obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o +obj-$(CONFIG_PL330_DMA) += pl330.o diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c new file mode 100644 index 000000000000..7c50f6dfd3f4 --- /dev/null +++ b/drivers/dma/pl330.c @@ -0,0 +1,866 @@ +/* linux/drivers/dma/pl330.c + * + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define NR_DEFAULT_DESC 16 + +enum desc_status { + /* In the DMAC pool */ + FREE, + /* + * Allocted to some channel during prep_xxx + * Also may be sitting on the work_list. + */ + PREP, + /* + * Sitting on the work_list and already submitted + * to the PL330 core. Not more than two descriptors + * of a channel can be BUSY at any time. + */ + BUSY, + /* + * Sitting on the channel work_list but xfer done + * by PL330 core + */ + DONE, +}; + +struct dma_pl330_chan { + /* Schedule desc completion */ + struct tasklet_struct task; + + /* DMA-Engine Channel */ + struct dma_chan chan; + + /* Last completed cookie */ + dma_cookie_t completed; + + /* List of to be xfered descriptors */ + struct list_head work_list; + + /* Pointer to the DMAC that manages this channel, + * NULL if the channel is available to be acquired. + * As the parent, this DMAC also provides descriptors + * to the channel. + */ + struct dma_pl330_dmac *dmac; + + /* To protect channel manipulation */ + spinlock_t lock; + + /* Token of a hardware channel thread of PL330 DMAC + * NULL if the channel is available to be acquired. + */ + void *pl330_chid; +}; + +struct dma_pl330_dmac { + struct pl330_info pif; + + /* DMA-Engine Device */ + struct dma_device ddma; + + /* Pool of descriptors available for the DMAC's channels */ + struct list_head desc_pool; + /* To protect desc_pool manipulation */ + spinlock_t pool_lock; + + /* Peripheral channels connected to this DMAC */ + struct dma_pl330_chan peripherals[0]; /* keep at end */ +}; + +struct dma_pl330_desc { + /* To attach to a queue as child */ + struct list_head node; + + /* Descriptor for the DMA Engine API */ + struct dma_async_tx_descriptor txd; + + /* Xfer for PL330 core */ + struct pl330_xfer px; + + struct pl330_reqcfg rqcfg; + struct pl330_req req; + + enum desc_status status; + + /* The channel which currently holds this desc */ + struct dma_pl330_chan *pchan; +}; + +static inline struct dma_pl330_chan * +to_pchan(struct dma_chan *ch) +{ + if (!ch) + return NULL; + + return container_of(ch, struct dma_pl330_chan, chan); +} + +static inline struct dma_pl330_desc * +to_desc(struct dma_async_tx_descriptor *tx) +{ + return container_of(tx, struct dma_pl330_desc, txd); +} + +static inline void free_desc_list(struct list_head *list) +{ + struct dma_pl330_dmac *pdmac; + struct dma_pl330_desc *desc; + struct dma_pl330_chan *pch; + unsigned long flags; + + if (list_empty(list)) + return; + + /* Finish off the work list */ + list_for_each_entry(desc, list, node) { + dma_async_tx_callback callback; + void *param; + + /* All desc in a list belong to same channel */ + pch = desc->pchan; + callback = desc->txd.callback; + param = desc->txd.callback_param; + + if (callback) + callback(param); + + desc->pchan = NULL; + } + + pdmac = pch->dmac; + + spin_lock_irqsave(&pdmac->pool_lock, flags); + list_splice_tail_init(list, &pdmac->desc_pool); + spin_unlock_irqrestore(&pdmac->pool_lock, flags); +} + +static inline void fill_queue(struct dma_pl330_chan *pch) +{ + struct dma_pl330_desc *desc; + int ret; + + list_for_each_entry(desc, &pch->work_list, node) { + + /* If already submitted */ + if (desc->status == BUSY) + break; + + ret = pl330_submit_req(pch->pl330_chid, + &desc->req); + if (!ret) { + desc->status = BUSY; + break; + } else if (ret == -EAGAIN) { + /* QFull or DMAC Dying */ + break; + } else { + /* Unacceptable request */ + desc->status = DONE; + dev_err(pch->dmac->pif.dev, "%s:%d Bad Desc(%d)\n", + __func__, __LINE__, desc->txd.cookie); + tasklet_schedule(&pch->task); + } + } +} + +static void pl330_tasklet(unsigned long data) +{ + struct dma_pl330_chan *pch = (struct dma_pl330_chan *)data; + struct dma_pl330_desc *desc, *_dt; + unsigned long flags; + LIST_HEAD(list); + + spin_lock_irqsave(&pch->lock, flags); + + /* Pick up ripe tomatoes */ + list_for_each_entry_safe(desc, _dt, &pch->work_list, node) + if (desc->status == DONE) { + pch->completed = desc->txd.cookie; + list_move_tail(&desc->node, &list); + } + + /* Try to submit a req imm. next to the last completed cookie */ + fill_queue(pch); + + /* Make sure the PL330 Channel thread is active */ + pl330_chan_ctrl(pch->pl330_chid, PL330_OP_START); + + spin_unlock_irqrestore(&pch->lock, flags); + + free_desc_list(&list); +} + +static void dma_pl330_rqcb(void *token, enum pl330_op_err err) +{ + struct dma_pl330_desc *desc = token; + struct dma_pl330_chan *pch = desc->pchan; + unsigned long flags; + + /* If desc aborted */ + if (!pch) + return; + + spin_lock_irqsave(&pch->lock, flags); + + desc->status = DONE; + + spin_unlock_irqrestore(&pch->lock, flags); + + tasklet_schedule(&pch->task); +} + +static int pl330_alloc_chan_resources(struct dma_chan *chan) +{ + struct dma_pl330_chan *pch = to_pchan(chan); + struct dma_pl330_dmac *pdmac = pch->dmac; + unsigned long flags; + + spin_lock_irqsave(&pch->lock, flags); + + pch->completed = chan->cookie = 1; + + pch->pl330_chid = pl330_request_channel(&pdmac->pif); + if (!pch->pl330_chid) { + spin_unlock_irqrestore(&pch->lock, flags); + return 0; + } + + tasklet_init(&pch->task, pl330_tasklet, (unsigned long) pch); + + spin_unlock_irqrestore(&pch->lock, flags); + + return 1; +} + +static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned long arg) +{ + struct dma_pl330_chan *pch = to_pchan(chan); + struct dma_pl330_desc *desc; + unsigned long flags; + + /* Only supports DMA_TERMINATE_ALL */ + if (cmd != DMA_TERMINATE_ALL) + return -ENXIO; + + spin_lock_irqsave(&pch->lock, flags); + + /* FLUSH the PL330 Channel thread */ + pl330_chan_ctrl(pch->pl330_chid, PL330_OP_FLUSH); + + /* Mark all desc done */ + list_for_each_entry(desc, &pch->work_list, node) + desc->status = DONE; + + spin_unlock_irqrestore(&pch->lock, flags); + + pl330_tasklet((unsigned long) pch); + + return 0; +} + +static void pl330_free_chan_resources(struct dma_chan *chan) +{ + struct dma_pl330_chan *pch = to_pchan(chan); + unsigned long flags; + + spin_lock_irqsave(&pch->lock, flags); + + tasklet_kill(&pch->task); + + pl330_release_channel(pch->pl330_chid); + pch->pl330_chid = NULL; + + spin_unlock_irqrestore(&pch->lock, flags); +} + +static enum dma_status +pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + struct dma_tx_state *txstate) +{ + struct dma_pl330_chan *pch = to_pchan(chan); + dma_cookie_t last_done, last_used; + int ret; + + last_done = pch->completed; + last_used = chan->cookie; + + ret = dma_async_is_complete(cookie, last_done, last_used); + + dma_set_tx_state(txstate, last_done, last_used, 0); + + return ret; +} + +static void pl330_issue_pending(struct dma_chan *chan) +{ + pl330_tasklet((unsigned long) to_pchan(chan)); +} + +/* + * We returned the last one of the circular list of descriptor(s) + * from prep_xxx, so the argument to submit corresponds to the last + * descriptor of the list. + */ +static dma_cookie_t pl330_tx_submit(struct dma_async_tx_descriptor *tx) +{ + struct dma_pl330_desc *desc, *last = to_desc(tx); + struct dma_pl330_chan *pch = to_pchan(tx->chan); + dma_cookie_t cookie; + unsigned long flags; + + spin_lock_irqsave(&pch->lock, flags); + + /* Assign cookies to all nodes */ + cookie = tx->chan->cookie; + + while (!list_empty(&last->node)) { + desc = list_entry(last->node.next, struct dma_pl330_desc, node); + + if (++cookie < 0) + cookie = 1; + desc->txd.cookie = cookie; + + list_move_tail(&desc->node, &pch->work_list); + } + + if (++cookie < 0) + cookie = 1; + last->txd.cookie = cookie; + + list_add_tail(&last->node, &pch->work_list); + + tx->chan->cookie = cookie; + + spin_unlock_irqrestore(&pch->lock, flags); + + return cookie; +} + +static inline void _init_desc(struct dma_pl330_desc *desc) +{ + desc->pchan = NULL; + desc->req.x = &desc->px; + desc->req.token = desc; + desc->rqcfg.swap = SWAP_NO; + desc->rqcfg.privileged = 0; + desc->rqcfg.insnaccess = 0; + desc->rqcfg.scctl = SCCTRL0; + desc->rqcfg.dcctl = DCCTRL0; + desc->req.cfg = &desc->rqcfg; + desc->req.xfer_cb = dma_pl330_rqcb; + desc->txd.tx_submit = pl330_tx_submit; + + INIT_LIST_HEAD(&desc->node); +} + +/* Returns the number of descriptors added to the DMAC pool */ +int add_desc(struct dma_pl330_dmac *pdmac, gfp_t flg, int count) +{ + struct dma_pl330_desc *desc; + unsigned long flags; + int i; + + if (!pdmac) + return 0; + + desc = kmalloc(count * sizeof(*desc), flg); + if (!desc) + return 0; + + spin_lock_irqsave(&pdmac->pool_lock, flags); + + for (i = 0; i < count; i++) { + _init_desc(&desc[i]); + list_add_tail(&desc[i].node, &pdmac->desc_pool); + } + + spin_unlock_irqrestore(&pdmac->pool_lock, flags); + + return count; +} + +static struct dma_pl330_desc * +pluck_desc(struct dma_pl330_dmac *pdmac) +{ + struct dma_pl330_desc *desc = NULL; + unsigned long flags; + + if (!pdmac) + return NULL; + + spin_lock_irqsave(&pdmac->pool_lock, flags); + + if (!list_empty(&pdmac->desc_pool)) { + desc = list_entry(pdmac->desc_pool.next, + struct dma_pl330_desc, node); + + list_del_init(&desc->node); + + desc->status = PREP; + desc->txd.callback = NULL; + } + + spin_unlock_irqrestore(&pdmac->pool_lock, flags); + + return desc; +} + +static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch) +{ + struct dma_pl330_dmac *pdmac = pch->dmac; + struct dma_pl330_peri *peri = pch->chan.private; + struct dma_pl330_desc *desc; + + /* Pluck one desc from the pool of DMAC */ + desc = pluck_desc(pdmac); + + /* If the DMAC pool is empty, alloc new */ + if (!desc) { + if (!add_desc(pdmac, GFP_ATOMIC, 1)) + return NULL; + + /* Try again */ + desc = pluck_desc(pdmac); + if (!desc) { + dev_err(pch->dmac->pif.dev, + "%s:%d ALERT!\n", __func__, __LINE__); + return NULL; + } + } + + /* Initialize the descriptor */ + desc->pchan = pch; + desc->txd.cookie = 0; + async_tx_ack(&desc->txd); + + desc->req.rqtype = peri->rqtype; + desc->req.peri = peri->peri_id; + + dma_async_tx_descriptor_init(&desc->txd, &pch->chan); + + return desc; +} + +static inline void fill_px(struct pl330_xfer *px, + dma_addr_t dst, dma_addr_t src, size_t len) +{ + px->next = NULL; + px->bytes = len; + px->dst_addr = dst; + px->src_addr = src; +} + +static struct dma_pl330_desc * +__pl330_prep_dma_memcpy(struct dma_pl330_chan *pch, dma_addr_t dst, + dma_addr_t src, size_t len) +{ + struct dma_pl330_desc *desc = pl330_get_desc(pch); + + if (!desc) { + dev_err(pch->dmac->pif.dev, "%s:%d Unable to fetch desc\n", + __func__, __LINE__); + return NULL; + } + + /* + * Ideally we should lookout for reqs bigger than + * those that can be programmed with 256 bytes of + * MC buffer, but considering a req size is seldom + * going to be word-unaligned and more than 200MB, + * we take it easy. + * Also, should the limit is reached we'd rather + * have the platform increase MC buffer size than + * complicating this API driver. + */ + fill_px(&desc->px, dst, src, len); + + return desc; +} + +/* Call after fixing burst size */ +static inline int get_burst_len(struct dma_pl330_desc *desc, size_t len) +{ + struct dma_pl330_chan *pch = desc->pchan; + struct pl330_info *pi = &pch->dmac->pif; + int burst_len; + + burst_len = pi->pcfg.data_bus_width / 8; + burst_len *= pi->pcfg.data_buf_dep; + burst_len >>= desc->rqcfg.brst_size; + + /* src/dst_burst_len can't be more than 16 */ + if (burst_len > 16) + burst_len = 16; + + while (burst_len > 1) { + if (!(len % (burst_len << desc->rqcfg.brst_size))) + break; + burst_len--; + } + + return burst_len; +} + +static struct dma_async_tx_descriptor * +pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst, + dma_addr_t src, size_t len, unsigned long flags) +{ + struct dma_pl330_desc *desc; + struct dma_pl330_chan *pch = to_pchan(chan); + struct dma_pl330_peri *peri = chan->private; + struct pl330_info *pi; + int burst; + + if (unlikely(!pch || !len || !peri)) + return NULL; + + if (peri->rqtype != MEMTOMEM) + return NULL; + + pi = &pch->dmac->pif; + + desc = __pl330_prep_dma_memcpy(pch, dst, src, len); + if (!desc) + return NULL; + + desc->rqcfg.src_inc = 1; + desc->rqcfg.dst_inc = 1; + + /* Select max possible burst size */ + burst = pi->pcfg.data_bus_width / 8; + + while (burst > 1) { + if (!(len % burst)) + break; + burst /= 2; + } + + desc->rqcfg.brst_size = 0; + while (burst != (1 << desc->rqcfg.brst_size)) + desc->rqcfg.brst_size++; + + desc->rqcfg.brst_len = get_burst_len(desc, len); + + desc->txd.flags = flags; + + return &desc->txd; +} + +static struct dma_async_tx_descriptor * +pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, + unsigned int sg_len, enum dma_data_direction direction, + unsigned long flg) +{ + struct dma_pl330_desc *first, *desc = NULL; + struct dma_pl330_chan *pch = to_pchan(chan); + struct dma_pl330_peri *peri = chan->private; + struct scatterlist *sg; + unsigned long flags; + int i, burst_size; + dma_addr_t addr; + + if (unlikely(!pch || !sgl || !sg_len)) + return NULL; + + /* Make sure the direction is consistent */ + if ((direction == DMA_TO_DEVICE && + peri->rqtype != MEMTODEV) || + (direction == DMA_FROM_DEVICE && + peri->rqtype != DEVTOMEM)) { + dev_err(pch->dmac->pif.dev, "%s:%d Invalid Direction\n", + __func__, __LINE__); + return NULL; + } + + addr = peri->fifo_addr; + burst_size = peri->burst_sz; + + first = NULL; + + for_each_sg(sgl, sg, sg_len, i) { + + desc = pl330_get_desc(pch); + if (!desc) { + struct dma_pl330_dmac *pdmac = pch->dmac; + + dev_err(pch->dmac->pif.dev, + "%s:%d Unable to fetch desc\n", + __func__, __LINE__); + if (!first) + return NULL; + + spin_lock_irqsave(&pdmac->pool_lock, flags); + + while (!list_empty(&first->node)) { + desc = list_entry(first->node.next, + struct dma_pl330_desc, node); + list_move_tail(&desc->node, &pdmac->desc_pool); + } + + list_move_tail(&first->node, &pdmac->desc_pool); + + spin_unlock_irqrestore(&pdmac->pool_lock, flags); + + return NULL; + } + + if (!first) + first = desc; + else + list_add_tail(&desc->node, &first->node); + + if (direction == DMA_TO_DEVICE) { + desc->rqcfg.src_inc = 1; + desc->rqcfg.dst_inc = 0; + fill_px(&desc->px, + addr, sg_dma_address(sg), sg_dma_len(sg)); + } else { + desc->rqcfg.src_inc = 0; + desc->rqcfg.dst_inc = 1; + fill_px(&desc->px, + sg_dma_address(sg), addr, sg_dma_len(sg)); + } + + desc->rqcfg.brst_size = burst_size; + desc->rqcfg.brst_len = 1; + } + + /* Return the last desc in the chain */ + desc->txd.flags = flg; + return &desc->txd; +} + +static irqreturn_t pl330_irq_handler(int irq, void *data) +{ + if (pl330_update(data)) + return IRQ_HANDLED; + else + return IRQ_NONE; +} + +static int __devinit +pl330_probe(struct amba_device *adev, struct amba_id *id) +{ + struct dma_pl330_platdata *pdat; + struct dma_pl330_dmac *pdmac; + struct dma_pl330_chan *pch; + struct pl330_info *pi; + struct dma_device *pd; + struct resource *res; + int i, ret, irq; + + pdat = adev->dev.platform_data; + + if (!pdat || !pdat->nr_valid_peri) { + dev_err(&adev->dev, "platform data missing\n"); + return -ENODEV; + } + + /* Allocate a new DMAC and its Channels */ + pdmac = kzalloc(pdat->nr_valid_peri * sizeof(*pch) + + sizeof(*pdmac), GFP_KERNEL); + if (!pdmac) { + dev_err(&adev->dev, "unable to allocate mem\n"); + return -ENOMEM; + } + + pi = &pdmac->pif; + pi->dev = &adev->dev; + pi->pl330_data = NULL; + pi->mcbufsz = pdat->mcbuf_sz; + + res = &adev->res; + request_mem_region(res->start, resource_size(res), "dma-pl330"); + + pi->base = ioremap(res->start, resource_size(res)); + if (!pi->base) { + ret = -ENXIO; + goto probe_err1; + } + + irq = adev->irq[0]; + ret = request_irq(irq, pl330_irq_handler, 0, + dev_name(&adev->dev), pi); + if (ret) + goto probe_err2; + + ret = pl330_add(pi); + if (ret) + goto probe_err3; + + INIT_LIST_HEAD(&pdmac->desc_pool); + spin_lock_init(&pdmac->pool_lock); + + /* Create a descriptor pool of default size */ + if (!add_desc(pdmac, GFP_KERNEL, NR_DEFAULT_DESC)) + dev_warn(&adev->dev, "unable to allocate desc\n"); + + pd = &pdmac->ddma; + INIT_LIST_HEAD(&pd->channels); + + /* Initialize channel parameters */ + for (i = 0; i < pdat->nr_valid_peri; i++) { + struct dma_pl330_peri *peri = &pdat->peri[i]; + pch = &pdmac->peripherals[i]; + + switch (peri->rqtype) { + case MEMTOMEM: + dma_cap_set(DMA_MEMCPY, pd->cap_mask); + break; + case MEMTODEV: + case DEVTOMEM: + dma_cap_set(DMA_SLAVE, pd->cap_mask); + break; + default: + dev_err(&adev->dev, "DEVTODEV Not Supported\n"); + continue; + } + + INIT_LIST_HEAD(&pch->work_list); + spin_lock_init(&pch->lock); + pch->pl330_chid = NULL; + pch->chan.private = peri; + pch->chan.device = pd; + pch->chan.chan_id = i; + pch->dmac = pdmac; + + /* Add the channel to the DMAC list */ + pd->chancnt++; + list_add_tail(&pch->chan.device_node, &pd->channels); + } + + pd->dev = &adev->dev; + + pd->device_alloc_chan_resources = pl330_alloc_chan_resources; + pd->device_free_chan_resources = pl330_free_chan_resources; + pd->device_prep_dma_memcpy = pl330_prep_dma_memcpy; + pd->device_tx_status = pl330_tx_status; + pd->device_prep_slave_sg = pl330_prep_slave_sg; + pd->device_control = pl330_control; + pd->device_issue_pending = pl330_issue_pending; + + ret = dma_async_device_register(pd); + if (ret) { + dev_err(&adev->dev, "unable to register DMAC\n"); + goto probe_err4; + } + + amba_set_drvdata(adev, pdmac); + + dev_info(&adev->dev, + "Loaded driver for PL330 DMAC-%d\n", adev->periphid); + dev_info(&adev->dev, + "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n", + pi->pcfg.data_buf_dep, + pi->pcfg.data_bus_width / 8, pi->pcfg.num_chan, + pi->pcfg.num_peri, pi->pcfg.num_events); + + return 0; + +probe_err4: + pl330_del(pi); +probe_err3: + free_irq(irq, pi); +probe_err2: + iounmap(pi->base); +probe_err1: + release_mem_region(res->start, resource_size(res)); + kfree(pdmac); + + return ret; +} + +static int __devexit pl330_remove(struct amba_device *adev) +{ + struct dma_pl330_dmac *pdmac = amba_get_drvdata(adev); + struct dma_pl330_chan *pch, *_p; + struct pl330_info *pi; + struct resource *res; + int irq; + + if (!pdmac) + return 0; + + amba_set_drvdata(adev, NULL); + + /* Idle the DMAC */ + list_for_each_entry_safe(pch, _p, &pdmac->ddma.channels, + chan.device_node) { + + /* Remove the channel */ + list_del(&pch->chan.device_node); + + /* Flush the channel */ + pl330_control(&pch->chan, DMA_TERMINATE_ALL, 0); + pl330_free_chan_resources(&pch->chan); + } + + pi = &pdmac->pif; + + pl330_del(pi); + + irq = adev->irq[0]; + free_irq(irq, pi); + + iounmap(pi->base); + + res = &adev->res; + release_mem_region(res->start, resource_size(res)); + + kfree(pdmac); + + return 0; +} + +static struct amba_id pl330_ids[] = { + { + .id = 0x00041330, + .mask = 0x000fffff, + }, + { 0, 0 }, +}; + +static struct amba_driver pl330_driver = { + .drv = { + .owner = THIS_MODULE, + .name = "dma-pl330", + }, + .id_table = pl330_ids, + .probe = pl330_probe, + .remove = pl330_remove, +}; + +static int __init pl330_init(void) +{ + return amba_driver_register(&pl330_driver); +} +module_init(pl330_init); + +static void __exit pl330_exit(void) +{ + amba_driver_unregister(&pl330_driver); + return; +} +module_exit(pl330_exit); + +MODULE_AUTHOR("Jaswinder Singh "); +MODULE_DESCRIPTION("API Driver for PL330 DMAC"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h new file mode 100644 index 000000000000..cbee7de7dd36 --- /dev/null +++ b/include/linux/amba/pl330.h @@ -0,0 +1,45 @@ +/* linux/include/linux/amba/pl330.h + * + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __AMBA_PL330_H_ +#define __AMBA_PL330_H_ + +#include + +struct dma_pl330_peri { + /* + * Peri_Req i/f of the DMAC that is + * peripheral could be reached from. + */ + u8 peri_id; /* {0, 31} */ + enum pl330_reqtype rqtype; + + /* For M->D and D->M Channels */ + int burst_sz; /* in power of 2 */ + dma_addr_t fifo_addr; +}; + +struct dma_pl330_platdata { + /* + * Number of valid peripherals connected to DMAC. + * This may be different from the value read from + * CR0, as the PL330 implementation might have 'holes' + * in the peri list or the peri could also be reached + * from another DMAC which the platform prefers. + */ + u8 nr_valid_peri; + /* Array of valid peripherals */ + struct dma_pl330_peri *peri; + /* Bytes to allocate for MC buffer */ + unsigned mcbuf_sz; +}; + +#endif /* __AMBA_PL330_H_ */ -- cgit v1.2.3 From 1693395511a2840f67dd3184212a072ac7f07524 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Sun, 23 May 2010 21:39:31 -0700 Subject: IB/mad: Make needlessly global mad_sendq_size/mad_recvq_size static Signed-off-by: Roland Dreier --- drivers/infiniband/core/mad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 6dc7b77d5d29..ef1304f151dc 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -47,8 +47,8 @@ MODULE_DESCRIPTION("kernel IB MAD API"); MODULE_AUTHOR("Hal Rosenstock"); MODULE_AUTHOR("Sean Hefty"); -int mad_sendq_size = IB_MAD_QP_SEND_SIZE; -int mad_recvq_size = IB_MAD_QP_RECV_SIZE; +static int mad_sendq_size = IB_MAD_QP_SEND_SIZE; +static int mad_recvq_size = IB_MAD_QP_RECV_SIZE; module_param_named(send_queue_size, mad_sendq_size, int, 0444); MODULE_PARM_DESC(send_queue_size, "Size of send queue in number of work requests"); -- cgit v1.2.3 From f931551bafe1f10ded7f5282e2aa162c267a2e5d Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Sun, 23 May 2010 21:44:54 -0700 Subject: IB/qib: Add new qib driver for QLogic PCIe InfiniBand adapters Add a low-level IB driver for QLogic PCIe adapters. Signed-off-by: Ralph Campbell Signed-off-by: Roland Dreier --- drivers/infiniband/Kconfig | 1 + drivers/infiniband/Makefile | 1 + drivers/infiniband/hw/qib/Kconfig | 7 + drivers/infiniband/hw/qib/Makefile | 15 + drivers/infiniband/hw/qib/qib.h | 1439 +++++ drivers/infiniband/hw/qib/qib_6120_regs.h | 977 ++++ drivers/infiniband/hw/qib/qib_7220.h | 156 + drivers/infiniband/hw/qib/qib_7220_regs.h | 1496 +++++ drivers/infiniband/hw/qib/qib_7322_regs.h | 3163 +++++++++++ drivers/infiniband/hw/qib/qib_common.h | 758 +++ drivers/infiniband/hw/qib/qib_cq.c | 484 ++ drivers/infiniband/hw/qib/qib_diag.c | 894 +++ drivers/infiniband/hw/qib/qib_dma.c | 182 + drivers/infiniband/hw/qib/qib_driver.c | 665 +++ drivers/infiniband/hw/qib/qib_eeprom.c | 451 ++ drivers/infiniband/hw/qib/qib_file_ops.c | 2317 ++++++++ drivers/infiniband/hw/qib/qib_fs.c | 613 ++ drivers/infiniband/hw/qib/qib_iba6120.c | 3588 ++++++++++++ drivers/infiniband/hw/qib/qib_iba7220.c | 4618 +++++++++++++++ drivers/infiniband/hw/qib/qib_iba7322.c | 8058 +++++++++++++++++++++++++++ drivers/infiniband/hw/qib/qib_init.c | 1580 ++++++ drivers/infiniband/hw/qib/qib_intr.c | 236 + drivers/infiniband/hw/qib/qib_keys.c | 328 ++ drivers/infiniband/hw/qib/qib_mad.c | 2173 ++++++++ drivers/infiniband/hw/qib/qib_mad.h | 373 ++ drivers/infiniband/hw/qib/qib_mmap.c | 174 + drivers/infiniband/hw/qib/qib_mr.c | 503 ++ drivers/infiniband/hw/qib/qib_pcie.c | 738 +++ drivers/infiniband/hw/qib/qib_pio_copy.c | 64 + drivers/infiniband/hw/qib/qib_qp.c | 1255 +++++ drivers/infiniband/hw/qib/qib_qsfp.c | 564 ++ drivers/infiniband/hw/qib/qib_qsfp.h | 184 + drivers/infiniband/hw/qib/qib_rc.c | 2288 ++++++++ drivers/infiniband/hw/qib/qib_ruc.c | 817 +++ drivers/infiniband/hw/qib/qib_sd7220.c | 1413 +++++ drivers/infiniband/hw/qib/qib_sd7220_img.c | 1081 ++++ drivers/infiniband/hw/qib/qib_sdma.c | 973 ++++ drivers/infiniband/hw/qib/qib_srq.c | 375 ++ drivers/infiniband/hw/qib/qib_sysfs.c | 691 +++ drivers/infiniband/hw/qib/qib_twsi.c | 498 ++ drivers/infiniband/hw/qib/qib_tx.c | 557 ++ drivers/infiniband/hw/qib/qib_uc.c | 555 ++ drivers/infiniband/hw/qib/qib_ud.c | 607 ++ drivers/infiniband/hw/qib/qib_user_pages.c | 157 + drivers/infiniband/hw/qib/qib_user_sdma.c | 897 +++ drivers/infiniband/hw/qib/qib_user_sdma.h | 52 + drivers/infiniband/hw/qib/qib_verbs.c | 2248 ++++++++ drivers/infiniband/hw/qib/qib_verbs.h | 1100 ++++ drivers/infiniband/hw/qib/qib_verbs_mcast.c | 368 ++ drivers/infiniband/hw/qib/qib_wc_ppc64.c | 62 + drivers/infiniband/hw/qib/qib_wc_x86_64.c | 171 + 51 files changed, 52965 insertions(+) create mode 100644 drivers/infiniband/hw/qib/Kconfig create mode 100644 drivers/infiniband/hw/qib/Makefile create mode 100644 drivers/infiniband/hw/qib/qib.h create mode 100644 drivers/infiniband/hw/qib/qib_6120_regs.h create mode 100644 drivers/infiniband/hw/qib/qib_7220.h create mode 100644 drivers/infiniband/hw/qib/qib_7220_regs.h create mode 100644 drivers/infiniband/hw/qib/qib_7322_regs.h create mode 100644 drivers/infiniband/hw/qib/qib_common.h create mode 100644 drivers/infiniband/hw/qib/qib_cq.c create mode 100644 drivers/infiniband/hw/qib/qib_diag.c create mode 100644 drivers/infiniband/hw/qib/qib_dma.c create mode 100644 drivers/infiniband/hw/qib/qib_driver.c create mode 100644 drivers/infiniband/hw/qib/qib_eeprom.c create mode 100644 drivers/infiniband/hw/qib/qib_file_ops.c create mode 100644 drivers/infiniband/hw/qib/qib_fs.c create mode 100644 drivers/infiniband/hw/qib/qib_iba6120.c create mode 100644 drivers/infiniband/hw/qib/qib_iba7220.c create mode 100644 drivers/infiniband/hw/qib/qib_iba7322.c create mode 100644 drivers/infiniband/hw/qib/qib_init.c create mode 100644 drivers/infiniband/hw/qib/qib_intr.c create mode 100644 drivers/infiniband/hw/qib/qib_keys.c create mode 100644 drivers/infiniband/hw/qib/qib_mad.c create mode 100644 drivers/infiniband/hw/qib/qib_mad.h create mode 100644 drivers/infiniband/hw/qib/qib_mmap.c create mode 100644 drivers/infiniband/hw/qib/qib_mr.c create mode 100644 drivers/infiniband/hw/qib/qib_pcie.c create mode 100644 drivers/infiniband/hw/qib/qib_pio_copy.c create mode 100644 drivers/infiniband/hw/qib/qib_qp.c create mode 100644 drivers/infiniband/hw/qib/qib_qsfp.c create mode 100644 drivers/infiniband/hw/qib/qib_qsfp.h create mode 100644 drivers/infiniband/hw/qib/qib_rc.c create mode 100644 drivers/infiniband/hw/qib/qib_ruc.c create mode 100644 drivers/infiniband/hw/qib/qib_sd7220.c create mode 100644 drivers/infiniband/hw/qib/qib_sd7220_img.c create mode 100644 drivers/infiniband/hw/qib/qib_sdma.c create mode 100644 drivers/infiniband/hw/qib/qib_srq.c create mode 100644 drivers/infiniband/hw/qib/qib_sysfs.c create mode 100644 drivers/infiniband/hw/qib/qib_twsi.c create mode 100644 drivers/infiniband/hw/qib/qib_tx.c create mode 100644 drivers/infiniband/hw/qib/qib_uc.c create mode 100644 drivers/infiniband/hw/qib/qib_ud.c create mode 100644 drivers/infiniband/hw/qib/qib_user_pages.c create mode 100644 drivers/infiniband/hw/qib/qib_user_sdma.c create mode 100644 drivers/infiniband/hw/qib/qib_user_sdma.h create mode 100644 drivers/infiniband/hw/qib/qib_verbs.c create mode 100644 drivers/infiniband/hw/qib/qib_verbs.h create mode 100644 drivers/infiniband/hw/qib/qib_verbs_mcast.c create mode 100644 drivers/infiniband/hw/qib/qib_wc_ppc64.c create mode 100644 drivers/infiniband/hw/qib/qib_wc_x86_64.c (limited to 'drivers') diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig index 330d2a423362..89d70de5e235 100644 --- a/drivers/infiniband/Kconfig +++ b/drivers/infiniband/Kconfig @@ -43,6 +43,7 @@ config INFINIBAND_ADDR_TRANS source "drivers/infiniband/hw/mthca/Kconfig" source "drivers/infiniband/hw/ipath/Kconfig" +source "drivers/infiniband/hw/qib/Kconfig" source "drivers/infiniband/hw/ehca/Kconfig" source "drivers/infiniband/hw/amso1100/Kconfig" source "drivers/infiniband/hw/cxgb3/Kconfig" diff --git a/drivers/infiniband/Makefile b/drivers/infiniband/Makefile index 0c4e589d746e..9cc7a47d3e67 100644 --- a/drivers/infiniband/Makefile +++ b/drivers/infiniband/Makefile @@ -1,6 +1,7 @@ obj-$(CONFIG_INFINIBAND) += core/ obj-$(CONFIG_INFINIBAND_MTHCA) += hw/mthca/ obj-$(CONFIG_INFINIBAND_IPATH) += hw/ipath/ +obj-$(CONFIG_INFINIBAND_QIB) += hw/qib/ obj-$(CONFIG_INFINIBAND_EHCA) += hw/ehca/ obj-$(CONFIG_INFINIBAND_AMSO1100) += hw/amso1100/ obj-$(CONFIG_INFINIBAND_CXGB3) += hw/cxgb3/ diff --git a/drivers/infiniband/hw/qib/Kconfig b/drivers/infiniband/hw/qib/Kconfig new file mode 100644 index 000000000000..7c03a70c55a2 --- /dev/null +++ b/drivers/infiniband/hw/qib/Kconfig @@ -0,0 +1,7 @@ +config INFINIBAND_QIB + tristate "QLogic PCIe HCA support" + depends on 64BIT && NET + ---help--- + This is a low-level driver for QLogic PCIe QLE InfiniBand host + channel adapters. This driver does not support the QLogic + HyperTransport card (model QHT7140). diff --git a/drivers/infiniband/hw/qib/Makefile b/drivers/infiniband/hw/qib/Makefile new file mode 100644 index 000000000000..c6515a1b9a6a --- /dev/null +++ b/drivers/infiniband/hw/qib/Makefile @@ -0,0 +1,15 @@ +obj-$(CONFIG_INFINIBAND_QIB) += ib_qib.o + +ib_qib-y := qib_cq.o qib_diag.o qib_dma.o qib_driver.o qib_eeprom.o \ + qib_file_ops.o qib_fs.o qib_init.o qib_intr.o qib_keys.o \ + qib_mad.o qib_mmap.o qib_mr.o qib_pcie.o qib_pio_copy.o \ + qib_qp.o qib_qsfp.o qib_rc.o qib_ruc.o qib_sdma.o qib_srq.o \ + qib_sysfs.o qib_twsi.o qib_tx.o qib_uc.o qib_ud.o \ + qib_user_pages.o qib_user_sdma.o qib_verbs_mcast.o qib_iba7220.o \ + qib_sd7220.o qib_sd7220_img.o qib_iba7322.o qib_verbs.o + +# 6120 has no fallback if no MSI interrupts, others can do INTx +ib_qib-$(CONFIG_PCI_MSI) += qib_iba6120.o + +ib_qib-$(CONFIG_X86_64) += qib_wc_x86_64.o +ib_qib-$(CONFIG_PPC64) += qib_wc_ppc64.o diff --git a/drivers/infiniband/hw/qib/qib.h b/drivers/infiniband/hw/qib/qib.h new file mode 100644 index 000000000000..32d9208efcff --- /dev/null +++ b/drivers/infiniband/hw/qib/qib.h @@ -0,0 +1,1439 @@ +#ifndef _QIB_KERNEL_H +#define _QIB_KERNEL_H +/* + * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation. + * All rights reserved. + * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * This header file is the base header file for qlogic_ib kernel code + * qib_user.h serves a similar purpose for user code. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qib_common.h" +#include "qib_verbs.h" + +/* only s/w major version of QLogic_IB we can handle */ +#define QIB_CHIP_VERS_MAJ 2U + +/* don't care about this except printing */ +#define QIB_CHIP_VERS_MIN 0U + +/* The Organization Unique Identifier (Mfg code), and its position in GUID */ +#define QIB_OUI 0x001175 +#define QIB_OUI_LSB 40 + +/* + * per driver stats, either not device nor port-specific, or + * summed over all of the devices and ports. + * They are described by name via ipathfs filesystem, so layout + * and number of elements can change without breaking compatibility. + * If members are added or deleted qib_statnames[] in qib_fs.c must + * change to match. + */ +struct qlogic_ib_stats { + __u64 sps_ints; /* number of interrupts handled */ + __u64 sps_errints; /* number of error interrupts */ + __u64 sps_txerrs; /* tx-related packet errors */ + __u64 sps_rcverrs; /* non-crc rcv packet errors */ + __u64 sps_hwerrs; /* hardware errors reported (parity, etc.) */ + __u64 sps_nopiobufs; /* no pio bufs avail from kernel */ + __u64 sps_ctxts; /* number of contexts currently open */ + __u64 sps_lenerrs; /* number of kernel packets where RHF != LRH len */ + __u64 sps_buffull; + __u64 sps_hdrfull; +}; + +extern struct qlogic_ib_stats qib_stats; +extern struct pci_error_handlers qib_pci_err_handler; +extern struct pci_driver qib_driver; + +#define QIB_CHIP_SWVERSION QIB_CHIP_VERS_MAJ +/* + * First-cut critierion for "device is active" is + * two thousand dwords combined Tx, Rx traffic per + * 5-second interval. SMA packets are 64 dwords, + * and occur "a few per second", presumably each way. + */ +#define QIB_TRAFFIC_ACTIVE_THRESHOLD (2000) + +/* + * Struct used to indicate which errors are logged in each of the + * error-counters that are logged to EEPROM. A counter is incremented + * _once_ (saturating at 255) for each event with any bits set in + * the error or hwerror register masks below. + */ +#define QIB_EEP_LOG_CNT (4) +struct qib_eep_log_mask { + u64 errs_to_log; + u64 hwerrs_to_log; +}; + +/* + * Below contains all data related to a single context (formerly called port). + */ +struct qib_ctxtdata { + void **rcvegrbuf; + dma_addr_t *rcvegrbuf_phys; + /* rcvhdrq base, needs mmap before useful */ + void *rcvhdrq; + /* kernel virtual address where hdrqtail is updated */ + void *rcvhdrtail_kvaddr; + /* + * temp buffer for expected send setup, allocated at open, instead + * of each setup call + */ + void *tid_pg_list; + /* + * Shared page for kernel to signal user processes that send buffers + * need disarming. The process should call QIB_CMD_DISARM_BUFS + * or QIB_CMD_ACK_EVENT with IPATH_EVENT_DISARM_BUFS set. + */ + unsigned long *user_event_mask; + /* when waiting for rcv or pioavail */ + wait_queue_head_t wait; + /* + * rcvegr bufs base, physical, must fit + * in 44 bits so 32 bit programs mmap64 44 bit works) + */ + dma_addr_t rcvegr_phys; + /* mmap of hdrq, must fit in 44 bits */ + dma_addr_t rcvhdrq_phys; + dma_addr_t rcvhdrqtailaddr_phys; + + /* + * number of opens (including slave sub-contexts) on this instance + * (ignoring forks, dup, etc. for now) + */ + int cnt; + /* + * how much space to leave at start of eager TID entries for + * protocol use, on each TID + */ + /* instead of calculating it */ + unsigned ctxt; + /* non-zero if ctxt is being shared. */ + u16 subctxt_cnt; + /* non-zero if ctxt is being shared. */ + u16 subctxt_id; + /* number of eager TID entries. */ + u16 rcvegrcnt; + /* index of first eager TID entry. */ + u16 rcvegr_tid_base; + /* number of pio bufs for this ctxt (all procs, if shared) */ + u32 piocnt; + /* first pio buffer for this ctxt */ + u32 pio_base; + /* chip offset of PIO buffers for this ctxt */ + u32 piobufs; + /* how many alloc_pages() chunks in rcvegrbuf_pages */ + u32 rcvegrbuf_chunks; + /* how many egrbufs per chunk */ + u32 rcvegrbufs_perchunk; + /* order for rcvegrbuf_pages */ + size_t rcvegrbuf_size; + /* rcvhdrq size (for freeing) */ + size_t rcvhdrq_size; + /* per-context flags for fileops/intr communication */ + unsigned long flag; + /* next expected TID to check when looking for free */ + u32 tidcursor; + /* WAIT_RCV that timed out, no interrupt */ + u32 rcvwait_to; + /* WAIT_PIO that timed out, no interrupt */ + u32 piowait_to; + /* WAIT_RCV already happened, no wait */ + u32 rcvnowait; + /* WAIT_PIO already happened, no wait */ + u32 pionowait; + /* total number of polled urgent packets */ + u32 urgent; + /* saved total number of polled urgent packets for poll edge trigger */ + u32 urgent_poll; + /* pid of process using this ctxt */ + pid_t pid; + pid_t subpid[QLOGIC_IB_MAX_SUBCTXT]; + /* same size as task_struct .comm[], command that opened context */ + char comm[16]; + /* pkeys set by this use of this ctxt */ + u16 pkeys[4]; + /* so file ops can get at unit */ + struct qib_devdata *dd; + /* so funcs that need physical port can get it easily */ + struct qib_pportdata *ppd; + /* A page of memory for rcvhdrhead, rcvegrhead, rcvegrtail * N */ + void *subctxt_uregbase; + /* An array of pages for the eager receive buffers * N */ + void *subctxt_rcvegrbuf; + /* An array of pages for the eager header queue entries * N */ + void *subctxt_rcvhdr_base; + /* The version of the library which opened this ctxt */ + u32 userversion; + /* Bitmask of active slaves */ + u32 active_slaves; + /* Type of packets or conditions we want to poll for */ + u16 poll_type; + /* receive packet sequence counter */ + u8 seq_cnt; + u8 redirect_seq_cnt; + /* ctxt rcvhdrq head offset */ + u32 head; + u32 pkt_count; + /* QPs waiting for context processing */ + struct list_head qp_wait_list; +}; + +struct qib_sge_state; + +struct qib_sdma_txreq { + int flags; + int sg_count; + dma_addr_t addr; + void (*callback)(struct qib_sdma_txreq *, int); + u16 start_idx; /* sdma private */ + u16 next_descq_idx; /* sdma private */ + struct list_head list; /* sdma private */ +}; + +struct qib_sdma_desc { + __le64 qw[2]; +}; + +struct qib_verbs_txreq { + struct qib_sdma_txreq txreq; + struct qib_qp *qp; + struct qib_swqe *wqe; + u32 dwords; + u16 hdr_dwords; + u16 hdr_inx; + struct qib_pio_header *align_buf; + struct qib_mregion *mr; + struct qib_sge_state *ss; +}; + +#define QIB_SDMA_TXREQ_F_USELARGEBUF 0x1 +#define QIB_SDMA_TXREQ_F_HEADTOHOST 0x2 +#define QIB_SDMA_TXREQ_F_INTREQ 0x4 +#define QIB_SDMA_TXREQ_F_FREEBUF 0x8 +#define QIB_SDMA_TXREQ_F_FREEDESC 0x10 + +#define QIB_SDMA_TXREQ_S_OK 0 +#define QIB_SDMA_TXREQ_S_SENDERROR 1 +#define QIB_SDMA_TXREQ_S_ABORTED 2 +#define QIB_SDMA_TXREQ_S_SHUTDOWN 3 + +/* + * Get/Set IB link-level config parameters for f_get/set_ib_cfg() + * Mostly for MADs that set or query link parameters, also ipath + * config interfaces + */ +#define QIB_IB_CFG_LIDLMC 0 /* LID (LS16b) and Mask (MS16b) */ +#define QIB_IB_CFG_LWID_ENB 2 /* allowed Link-width */ +#define QIB_IB_CFG_LWID 3 /* currently active Link-width */ +#define QIB_IB_CFG_SPD_ENB 4 /* allowed Link speeds */ +#define QIB_IB_CFG_SPD 5 /* current Link spd */ +#define QIB_IB_CFG_RXPOL_ENB 6 /* Auto-RX-polarity enable */ +#define QIB_IB_CFG_LREV_ENB 7 /* Auto-Lane-reversal enable */ +#define QIB_IB_CFG_LINKLATENCY 8 /* Link Latency (IB1.2 only) */ +#define QIB_IB_CFG_HRTBT 9 /* IB heartbeat off/enable/auto; DDR/QDR only */ +#define QIB_IB_CFG_OP_VLS 10 /* operational VLs */ +#define QIB_IB_CFG_VL_HIGH_CAP 11 /* num of VL high priority weights */ +#define QIB_IB_CFG_VL_LOW_CAP 12 /* num of VL low priority weights */ +#define QIB_IB_CFG_OVERRUN_THRESH 13 /* IB overrun threshold */ +#define QIB_IB_CFG_PHYERR_THRESH 14 /* IB PHY error threshold */ +#define QIB_IB_CFG_LINKDEFAULT 15 /* IB link default (sleep/poll) */ +#define QIB_IB_CFG_PKEYS 16 /* update partition keys */ +#define QIB_IB_CFG_MTU 17 /* update MTU in IBC */ +#define QIB_IB_CFG_LSTATE 18 /* update linkcmd and linkinitcmd in IBC */ +#define QIB_IB_CFG_VL_HIGH_LIMIT 19 +#define QIB_IB_CFG_PMA_TICKS 20 /* PMA sample tick resolution */ +#define QIB_IB_CFG_PORT 21 /* switch port we are connected to */ + +/* + * for CFG_LSTATE: LINKCMD in upper 16 bits, LINKINITCMD in lower 16 + * IB_LINKINITCMD_POLL and SLEEP are also used as set/get values for + * QIB_IB_CFG_LINKDEFAULT cmd + */ +#define IB_LINKCMD_DOWN (0 << 16) +#define IB_LINKCMD_ARMED (1 << 16) +#define IB_LINKCMD_ACTIVE (2 << 16) +#define IB_LINKINITCMD_NOP 0 +#define IB_LINKINITCMD_POLL 1 +#define IB_LINKINITCMD_SLEEP 2 +#define IB_LINKINITCMD_DISABLE 3 + +/* + * valid states passed to qib_set_linkstate() user call + */ +#define QIB_IB_LINKDOWN 0 +#define QIB_IB_LINKARM 1 +#define QIB_IB_LINKACTIVE 2 +#define QIB_IB_LINKDOWN_ONLY 3 +#define QIB_IB_LINKDOWN_SLEEP 4 +#define QIB_IB_LINKDOWN_DISABLE 5 + +/* + * These 7 values (SDR, DDR, and QDR may be ORed for auto-speed + * negotiation) are used for the 3rd argument to path_f_set_ib_cfg + * with cmd QIB_IB_CFG_SPD_ENB, by direct calls or via sysfs. They + * are also the the possible values for qib_link_speed_enabled and active + * The values were chosen to match values used within the IB spec. + */ +#define QIB_IB_SDR 1 +#define QIB_IB_DDR 2 +#define QIB_IB_QDR 4 + +#define QIB_DEFAULT_MTU 4096 + +/* + * Possible IB config parameters for f_get/set_ib_table() + */ +#define QIB_IB_TBL_VL_HIGH_ARB 1 /* Get/set VL high priority weights */ +#define QIB_IB_TBL_VL_LOW_ARB 2 /* Get/set VL low priority weights */ + +/* + * Possible "operations" for f_rcvctrl(ppd, op, ctxt) + * these are bits so they can be combined, e.g. + * QIB_RCVCTRL_INTRAVAIL_ENB | QIB_RCVCTRL_CTXT_ENB + */ +#define QIB_RCVCTRL_TAILUPD_ENB 0x01 +#define QIB_RCVCTRL_TAILUPD_DIS 0x02 +#define QIB_RCVCTRL_CTXT_ENB 0x04 +#define QIB_RCVCTRL_CTXT_DIS 0x08 +#define QIB_RCVCTRL_INTRAVAIL_ENB 0x10 +#define QIB_RCVCTRL_INTRAVAIL_DIS 0x20 +#define QIB_RCVCTRL_PKEY_ENB 0x40 /* Note, default is enabled */ +#define QIB_RCVCTRL_PKEY_DIS 0x80 +#define QIB_RCVCTRL_BP_ENB 0x0100 +#define QIB_RCVCTRL_BP_DIS 0x0200 +#define QIB_RCVCTRL_TIDFLOW_ENB 0x0400 +#define QIB_RCVCTRL_TIDFLOW_DIS 0x0800 + +/* + * Possible "operations" for f_sendctrl(ppd, op, var) + * these are bits so they can be combined, e.g. + * QIB_SENDCTRL_BUFAVAIL_ENB | QIB_SENDCTRL_ENB + * Some operations (e.g. DISARM, ABORT) are known to + * be "one-shot", so do not modify shadow. + */ +#define QIB_SENDCTRL_DISARM (0x1000) +#define QIB_SENDCTRL_DISARM_BUF(bufn) ((bufn) | QIB_SENDCTRL_DISARM) + /* available (0x2000) */ +#define QIB_SENDCTRL_AVAIL_DIS (0x4000) +#define QIB_SENDCTRL_AVAIL_ENB (0x8000) +#define QIB_SENDCTRL_AVAIL_BLIP (0x10000) +#define QIB_SENDCTRL_SEND_DIS (0x20000) +#define QIB_SENDCTRL_SEND_ENB (0x40000) +#define QIB_SENDCTRL_FLUSH (0x80000) +#define QIB_SENDCTRL_CLEAR (0x100000) +#define QIB_SENDCTRL_DISARM_ALL (0x200000) + +/* + * These are the generic indices for requesting per-port + * counter values via the f_portcntr function. They + * are always returned as 64 bit values, although most + * are 32 bit counters. + */ +/* send-related counters */ +#define QIBPORTCNTR_PKTSEND 0U +#define QIBPORTCNTR_WORDSEND 1U +#define QIBPORTCNTR_PSXMITDATA 2U +#define QIBPORTCNTR_PSXMITPKTS 3U +#define QIBPORTCNTR_PSXMITWAIT 4U +#define QIBPORTCNTR_SENDSTALL 5U +/* receive-related counters */ +#define QIBPORTCNTR_PKTRCV 6U +#define QIBPORTCNTR_PSRCVDATA 7U +#define QIBPORTCNTR_PSRCVPKTS 8U +#define QIBPORTCNTR_RCVEBP 9U +#define QIBPORTCNTR_RCVOVFL 10U +#define QIBPORTCNTR_WORDRCV 11U +/* IB link related error counters */ +#define QIBPORTCNTR_RXLOCALPHYERR 12U +#define QIBPORTCNTR_RXVLERR 13U +#define QIBPORTCNTR_ERRICRC 14U +#define QIBPORTCNTR_ERRVCRC 15U +#define QIBPORTCNTR_ERRLPCRC 16U +#define QIBPORTCNTR_BADFORMAT 17U +#define QIBPORTCNTR_ERR_RLEN 18U +#define QIBPORTCNTR_IBSYMBOLERR 19U +#define QIBPORTCNTR_INVALIDRLEN 20U +#define QIBPORTCNTR_UNSUPVL 21U +#define QIBPORTCNTR_EXCESSBUFOVFL 22U +#define QIBPORTCNTR_ERRLINK 23U +#define QIBPORTCNTR_IBLINKDOWN 24U +#define QIBPORTCNTR_IBLINKERRRECOV 25U +#define QIBPORTCNTR_LLI 26U +/* other error counters */ +#define QIBPORTCNTR_RXDROPPKT 27U +#define QIBPORTCNTR_VL15PKTDROP 28U +#define QIBPORTCNTR_ERRPKEY 29U +#define QIBPORTCNTR_KHDROVFL 30U +/* sampling counters (these are actually control registers) */ +#define QIBPORTCNTR_PSINTERVAL 31U +#define QIBPORTCNTR_PSSTART 32U +#define QIBPORTCNTR_PSSTAT 33U + +/* how often we check for packet activity for "power on hours (in seconds) */ +#define ACTIVITY_TIMER 5 + +/* Below is an opaque struct. Each chip (device) can maintain + * private data needed for its operation, but not germane to the + * rest of the driver. For convenience, we define another that + * is chip-specific, per-port + */ +struct qib_chip_specific; +struct qib_chipport_specific; + +enum qib_sdma_states { + qib_sdma_state_s00_hw_down, + qib_sdma_state_s10_hw_start_up_wait, + qib_sdma_state_s20_idle, + qib_sdma_state_s30_sw_clean_up_wait, + qib_sdma_state_s40_hw_clean_up_wait, + qib_sdma_state_s50_hw_halt_wait, + qib_sdma_state_s99_running, +}; + +enum qib_sdma_events { + qib_sdma_event_e00_go_hw_down, + qib_sdma_event_e10_go_hw_start, + qib_sdma_event_e20_hw_started, + qib_sdma_event_e30_go_running, + qib_sdma_event_e40_sw_cleaned, + qib_sdma_event_e50_hw_cleaned, + qib_sdma_event_e60_hw_halted, + qib_sdma_event_e70_go_idle, + qib_sdma_event_e7220_err_halted, + qib_sdma_event_e7322_err_halted, + qib_sdma_event_e90_timer_tick, +}; + +extern char *qib_sdma_state_names[]; +extern char *qib_sdma_event_names[]; + +struct sdma_set_state_action { + unsigned op_enable:1; + unsigned op_intenable:1; + unsigned op_halt:1; + unsigned op_drain:1; + unsigned go_s99_running_tofalse:1; + unsigned go_s99_running_totrue:1; +}; + +struct qib_sdma_state { + struct kref kref; + struct completion comp; + enum qib_sdma_states current_state; + struct sdma_set_state_action *set_state_action; + unsigned current_op; + unsigned go_s99_running; + unsigned first_sendbuf; + unsigned last_sendbuf; /* really last +1 */ + /* debugging/devel */ + enum qib_sdma_states previous_state; + unsigned previous_op; + enum qib_sdma_events last_event; +}; + +struct xmit_wait { + struct timer_list timer; + u64 counter; + u8 flags; + struct cache { + u64 psxmitdata; + u64 psrcvdata; + u64 psxmitpkts; + u64 psrcvpkts; + u64 psxmitwait; + } counter_cache; +}; + +/* + * The structure below encapsulates data relevant to a physical IB Port. + * Current chips support only one such port, but the separation + * clarifies things a bit. Note that to conform to IB conventions, + * port-numbers are one-based. The first or only port is port1. + */ +struct qib_pportdata { + struct qib_ibport ibport_data; + + struct qib_devdata *dd; + struct qib_chippport_specific *cpspec; /* chip-specific per-port */ + struct kobject pport_kobj; + struct kobject sl2vl_kobj; + struct kobject diagc_kobj; + + /* GUID for this interface, in network order */ + __be64 guid; + + /* QIB_POLL, etc. link-state specific flags, per port */ + u32 lflags; + /* qib_lflags driver is waiting for */ + u32 state_wanted; + spinlock_t lflags_lock; + /* number of (port-specific) interrupts for this port -- saturates... */ + u32 int_counter; + + /* ref count for each pkey */ + atomic_t pkeyrefs[4]; + + /* + * this address is mapped readonly into user processes so they can + * get status cheaply, whenever they want. One qword of status per port + */ + u64 *statusp; + + /* SendDMA related entries */ + spinlock_t sdma_lock; + struct qib_sdma_state sdma_state; + unsigned long sdma_buf_jiffies; + struct qib_sdma_desc *sdma_descq; + u64 sdma_descq_added; + u64 sdma_descq_removed; + u16 sdma_descq_cnt; + u16 sdma_descq_tail; + u16 sdma_descq_head; + u16 sdma_next_intr; + u16 sdma_reset_wait; + u8 sdma_generation; + struct tasklet_struct sdma_sw_clean_up_task; + struct list_head sdma_activelist; + + dma_addr_t sdma_descq_phys; + volatile __le64 *sdma_head_dma; /* DMA'ed by chip */ + dma_addr_t sdma_head_phys; + + wait_queue_head_t state_wait; /* for state_wanted */ + + /* HoL blocking for SMP replies */ + unsigned hol_state; + struct timer_list hol_timer; + + /* + * Shadow copies of registers; size indicates read access size. + * Most of them are readonly, but some are write-only register, + * where we manipulate the bits in the shadow copy, and then write + * the shadow copy to qlogic_ib. + * + * We deliberately make most of these 32 bits, since they have + * restricted range. For any that we read, we won't to generate 32 + * bit accesses, since Opteron will generate 2 separate 32 bit HT + * transactions for a 64 bit read, and we want to avoid unnecessary + * bus transactions. + */ + + /* This is the 64 bit group */ + /* last ibcstatus. opaque outside chip-specific code */ + u64 lastibcstat; + + /* these are the "32 bit" regs */ + + /* + * the following two are 32-bit bitmasks, but {test,clear,set}_bit + * all expect bit fields to be "unsigned long" + */ + unsigned long p_rcvctrl; /* shadow per-port rcvctrl */ + unsigned long p_sendctrl; /* shadow per-port sendctrl */ + + u32 ibmtu; /* The MTU programmed for this unit */ + /* + * Current max size IB packet (in bytes) including IB headers, that + * we can send. Changes when ibmtu changes. + */ + u32 ibmaxlen; + /* + * ibmaxlen at init time, limited by chip and by receive buffer + * size. Not changed after init. + */ + u32 init_ibmaxlen; + /* LID programmed for this instance */ + u16 lid; + /* list of pkeys programmed; 0 if not set */ + u16 pkeys[4]; + /* LID mask control */ + u8 lmc; + u8 link_width_supported; + u8 link_speed_supported; + u8 link_width_enabled; + u8 link_speed_enabled; + u8 link_width_active; + u8 link_speed_active; + u8 vls_supported; + u8 vls_operational; + /* Rx Polarity inversion (compensate for ~tx on partner) */ + u8 rx_pol_inv; + + u8 hw_pidx; /* physical port index */ + u8 port; /* IB port number and index into dd->pports - 1 */ + + u8 delay_mult; + + /* used to override LED behavior */ + u8 led_override; /* Substituted for normal value, if non-zero */ + u16 led_override_timeoff; /* delta to next timer event */ + u8 led_override_vals[2]; /* Alternates per blink-frame */ + u8 led_override_phase; /* Just counts, LSB picks from vals[] */ + atomic_t led_override_timer_active; + /* Used to flash LEDs in override mode */ + struct timer_list led_override_timer; + struct xmit_wait cong_stats; + struct timer_list symerr_clear_timer; +}; + +/* Observers. Not to be taken lightly, possibly not to ship. */ +/* + * If a diag read or write is to (bottom <= offset <= top), + * the "hoook" is called, allowing, e.g. shadows to be + * updated in sync with the driver. struct diag_observer + * is the "visible" part. + */ +struct diag_observer; + +typedef int (*diag_hook) (struct qib_devdata *dd, + const struct diag_observer *op, + u32 offs, u64 *data, u64 mask, int only_32); + +struct diag_observer { + diag_hook hook; + u32 bottom; + u32 top; +}; + +extern int qib_register_observer(struct qib_devdata *dd, + const struct diag_observer *op); + +/* Only declared here, not defined. Private to diags */ +struct diag_observer_list_elt; + +/* device data struct now contains only "general per-device" info. + * fields related to a physical IB port are in a qib_pportdata struct, + * described above) while fields only used by a particualr chip-type are in + * a qib_chipdata struct, whose contents are opaque to this file. + */ +struct qib_devdata { + struct qib_ibdev verbs_dev; /* must be first */ + struct list_head list; + /* pointers to related structs for this device */ + /* pci access data structure */ + struct pci_dev *pcidev; + struct cdev *user_cdev; + struct cdev *diag_cdev; + struct device *user_device; + struct device *diag_device; + + /* mem-mapped pointer to base of chip regs */ + u64 __iomem *kregbase; + /* end of mem-mapped chip space excluding sendbuf and user regs */ + u64 __iomem *kregend; + /* physical address of chip for io_remap, etc. */ + resource_size_t physaddr; + /* qib_cfgctxts pointers */ + struct qib_ctxtdata **rcd; /* Receive Context Data */ + + /* qib_pportdata, points to array of (physical) port-specific + * data structs, indexed by pidx (0..n-1) + */ + struct qib_pportdata *pport; + struct qib_chip_specific *cspec; /* chip-specific */ + + /* kvirt address of 1st 2k pio buffer */ + void __iomem *pio2kbase; + /* kvirt address of 1st 4k pio buffer */ + void __iomem *pio4kbase; + /* mem-mapped pointer to base of PIO buffers (if using WC PAT) */ + void __iomem *piobase; + /* mem-mapped pointer to base of user chip regs (if using WC PAT) */ + u64 __iomem *userbase; + /* + * points to area where PIOavail registers will be DMA'ed. + * Has to be on a page of it's own, because the page will be + * mapped into user program space. This copy is *ONLY* ever + * written by DMA, not by the driver! Need a copy per device + * when we get to multiple devices + */ + volatile __le64 *pioavailregs_dma; /* DMA'ed by chip */ + /* physical address where updates occur */ + dma_addr_t pioavailregs_phys; + + /* device-specific implementations of functions needed by + * common code. Contrary to previous consensus, we can't + * really just point to a device-specific table, because we + * may need to "bend", e.g. *_f_put_tid + */ + /* fallback to alternate interrupt type if possible */ + int (*f_intr_fallback)(struct qib_devdata *); + /* hard reset chip */ + int (*f_reset)(struct qib_devdata *); + void (*f_quiet_serdes)(struct qib_pportdata *); + int (*f_bringup_serdes)(struct qib_pportdata *); + int (*f_early_init)(struct qib_devdata *); + void (*f_clear_tids)(struct qib_devdata *, struct qib_ctxtdata *); + void (*f_put_tid)(struct qib_devdata *, u64 __iomem*, + u32, unsigned long); + void (*f_cleanup)(struct qib_devdata *); + void (*f_setextled)(struct qib_pportdata *, u32); + /* fill out chip-specific fields */ + int (*f_get_base_info)(struct qib_ctxtdata *, struct qib_base_info *); + /* free irq */ + void (*f_free_irq)(struct qib_devdata *); + struct qib_message_header *(*f_get_msgheader) + (struct qib_devdata *, __le32 *); + void (*f_config_ctxts)(struct qib_devdata *); + int (*f_get_ib_cfg)(struct qib_pportdata *, int); + int (*f_set_ib_cfg)(struct qib_pportdata *, int, u32); + int (*f_set_ib_loopback)(struct qib_pportdata *, const char *); + int (*f_get_ib_table)(struct qib_pportdata *, int, void *); + int (*f_set_ib_table)(struct qib_pportdata *, int, void *); + u32 (*f_iblink_state)(u64); + u8 (*f_ibphys_portstate)(u64); + void (*f_xgxs_reset)(struct qib_pportdata *); + /* per chip actions needed for IB Link up/down changes */ + int (*f_ib_updown)(struct qib_pportdata *, int, u64); + u32 __iomem *(*f_getsendbuf)(struct qib_pportdata *, u64, u32 *); + /* Read/modify/write of GPIO pins (potentially chip-specific */ + int (*f_gpio_mod)(struct qib_devdata *dd, u32 out, u32 dir, + u32 mask); + /* Enable writes to config EEPROM (if supported) */ + int (*f_eeprom_wen)(struct qib_devdata *dd, int wen); + /* + * modify rcvctrl shadow[s] and write to appropriate chip-regs. + * see above QIB_RCVCTRL_xxx_ENB/DIS for operations. + * (ctxt == -1) means "all contexts", only meaningful for + * clearing. Could remove if chip_spec shutdown properly done. + */ + void (*f_rcvctrl)(struct qib_pportdata *, unsigned int op, + int ctxt); + /* Read/modify/write sendctrl appropriately for op and port. */ + void (*f_sendctrl)(struct qib_pportdata *, u32 op); + void (*f_set_intr_state)(struct qib_devdata *, u32); + void (*f_set_armlaunch)(struct qib_devdata *, u32); + void (*f_wantpiobuf_intr)(struct qib_devdata *, u32); + int (*f_late_initreg)(struct qib_devdata *); + int (*f_init_sdma_regs)(struct qib_pportdata *); + u16 (*f_sdma_gethead)(struct qib_pportdata *); + int (*f_sdma_busy)(struct qib_pportdata *); + void (*f_sdma_update_tail)(struct qib_pportdata *, u16); + void (*f_sdma_set_desc_cnt)(struct qib_pportdata *, unsigned); + void (*f_sdma_sendctrl)(struct qib_pportdata *, unsigned); + void (*f_sdma_hw_clean_up)(struct qib_pportdata *); + void (*f_sdma_hw_start_up)(struct qib_pportdata *); + void (*f_sdma_init_early)(struct qib_pportdata *); + void (*f_set_cntr_sample)(struct qib_pportdata *, u32, u32); + void (*f_update_usrhead)(struct qib_ctxtdata *, u64, u32, u32); + u32 (*f_hdrqempty)(struct qib_ctxtdata *); + u64 (*f_portcntr)(struct qib_pportdata *, u32); + u32 (*f_read_cntrs)(struct qib_devdata *, loff_t, char **, + u64 **); + u32 (*f_read_portcntrs)(struct qib_devdata *, loff_t, u32, + char **, u64 **); + u32 (*f_setpbc_control)(struct qib_pportdata *, u32, u8, u8); + void (*f_initvl15_bufs)(struct qib_devdata *); + void (*f_init_ctxt)(struct qib_ctxtdata *); + void (*f_txchk_change)(struct qib_devdata *, u32, u32, u32, + struct qib_ctxtdata *); + void (*f_writescratch)(struct qib_devdata *, u32); + int (*f_tempsense_rd)(struct qib_devdata *, int regnum); + + char *boardname; /* human readable board info */ + + /* template for writing TIDs */ + u64 tidtemplate; + /* value to write to free TIDs */ + u64 tidinvalid; + + /* number of registers used for pioavail */ + u32 pioavregs; + /* device (not port) flags, basically device capabilities */ + u32 flags; + /* last buffer for user use */ + u32 lastctxt_piobuf; + + /* saturating counter of (non-port-specific) device interrupts */ + u32 int_counter; + + /* pio bufs allocated per ctxt */ + u32 pbufsctxt; + /* if remainder on bufs/ctxt, ctxts < extrabuf get 1 extra */ + u32 ctxts_extrabuf; + /* + * number of ctxts configured as max; zero is set to number chip + * supports, less gives more pio bufs/ctxt, etc. + */ + u32 cfgctxts; + + /* + * hint that we should update pioavailshadow before + * looking for a PIO buffer + */ + u32 upd_pio_shadow; + + /* internal debugging stats */ + u32 maxpkts_call; + u32 avgpkts_call; + u64 nopiobufs; + + /* PCI Vendor ID (here for NodeInfo) */ + u16 vendorid; + /* PCI Device ID (here for NodeInfo) */ + u16 deviceid; + /* for write combining settings */ + unsigned long wc_cookie; + unsigned long wc_base; + unsigned long wc_len; + + /* shadow copy of struct page *'s for exp tid pages */ + struct page **pageshadow; + /* shadow copy of dma handles for exp tid pages */ + dma_addr_t *physshadow; + u64 __iomem *egrtidbase; + spinlock_t sendctrl_lock; /* protect changes to sendctrl shadow */ + /* around rcd and (user ctxts) ctxt_cnt use (intr vs free) */ + spinlock_t uctxt_lock; /* rcd and user context changes */ + /* + * per unit status, see also portdata statusp + * mapped readonly into user processes so they can get unit and + * IB link status cheaply + */ + u64 *devstatusp; + char *freezemsg; /* freeze msg if hw error put chip in freeze */ + u32 freezelen; /* max length of freezemsg */ + /* timer used to prevent stats overflow, error throttling, etc. */ + struct timer_list stats_timer; + + /* timer to verify interrupts work, and fallback if possible */ + struct timer_list intrchk_timer; + unsigned long ureg_align; /* user register alignment */ + + /* + * Protects pioavailshadow, pioavailkernel, pio_need_disarm, and + * pio_writing. + */ + spinlock_t pioavail_lock; + + /* + * Shadow copies of registers; size indicates read access size. + * Most of them are readonly, but some are write-only register, + * where we manipulate the bits in the shadow copy, and then write + * the shadow copy to qlogic_ib. + * + * We deliberately make most of these 32 bits, since they have + * restricted range. For any that we read, we won't to generate 32 + * bit accesses, since Opteron will generate 2 separate 32 bit HT + * transactions for a 64 bit read, and we want to avoid unnecessary + * bus transactions. + */ + + /* This is the 64 bit group */ + + unsigned long pioavailshadow[6]; + /* bitmap of send buffers available for the kernel to use with PIO. */ + unsigned long pioavailkernel[6]; + /* bitmap of send buffers which need to be disarmed. */ + unsigned long pio_need_disarm[3]; + /* bitmap of send buffers which are being written to. */ + unsigned long pio_writing[3]; + /* kr_revision shadow */ + u64 revision; + /* Base GUID for device (from eeprom, network order) */ + __be64 base_guid; + + /* + * kr_sendpiobufbase value (chip offset of pio buffers), and the + * base of the 2KB buffer s(user processes only use 2K) + */ + u64 piobufbase; + u32 pio2k_bufbase; + + /* these are the "32 bit" regs */ + + /* number of GUIDs in the flash for this interface */ + u32 nguid; + /* + * the following two are 32-bit bitmasks, but {test,clear,set}_bit + * all expect bit fields to be "unsigned long" + */ + unsigned long rcvctrl; /* shadow per device rcvctrl */ + unsigned long sendctrl; /* shadow per device sendctrl */ + + /* value we put in kr_rcvhdrcnt */ + u32 rcvhdrcnt; + /* value we put in kr_rcvhdrsize */ + u32 rcvhdrsize; + /* value we put in kr_rcvhdrentsize */ + u32 rcvhdrentsize; + /* kr_ctxtcnt value */ + u32 ctxtcnt; + /* kr_pagealign value */ + u32 palign; + /* number of "2KB" PIO buffers */ + u32 piobcnt2k; + /* size in bytes of "2KB" PIO buffers */ + u32 piosize2k; + /* max usable size in dwords of a "2KB" PIO buffer before going "4KB" */ + u32 piosize2kmax_dwords; + /* number of "4KB" PIO buffers */ + u32 piobcnt4k; + /* size in bytes of "4KB" PIO buffers */ + u32 piosize4k; + /* kr_rcvegrbase value */ + u32 rcvegrbase; + /* kr_rcvtidbase value */ + u32 rcvtidbase; + /* kr_rcvtidcnt value */ + u32 rcvtidcnt; + /* kr_userregbase */ + u32 uregbase; + /* shadow the control register contents */ + u32 control; + + /* chip address space used by 4k pio buffers */ + u32 align4k; + /* size of each rcvegrbuffer */ + u32 rcvegrbufsize; + /* localbus width (1, 2,4,8,16,32) from config space */ + u32 lbus_width; + /* localbus speed in MHz */ + u32 lbus_speed; + int unit; /* unit # of this chip */ + + /* start of CHIP_SPEC move to chipspec, but need code changes */ + /* low and high portions of MSI capability/vector */ + u32 msi_lo; + /* saved after PCIe init for restore after reset */ + u32 msi_hi; + /* MSI data (vector) saved for restore */ + u16 msi_data; + /* so we can rewrite it after a chip reset */ + u32 pcibar0; + /* so we can rewrite it after a chip reset */ + u32 pcibar1; + u64 rhdrhead_intr_off; + + /* + * ASCII serial number, from flash, large enough for original + * all digit strings, and longer QLogic serial number format + */ + u8 serial[16]; + /* human readable board version */ + u8 boardversion[96]; + u8 lbus_info[32]; /* human readable localbus info */ + /* chip major rev, from qib_revision */ + u8 majrev; + /* chip minor rev, from qib_revision */ + u8 minrev; + + /* Misc small ints */ + /* Number of physical ports available */ + u8 num_pports; + /* Lowest context number which can be used by user processes */ + u8 first_user_ctxt; + u8 n_krcv_queues; + u8 qpn_mask; + u8 skip_kctxt_mask; + + u16 rhf_offset; /* offset of RHF within receive header entry */ + + /* + * GPIO pins for twsi-connected devices, and device code for eeprom + */ + u8 gpio_sda_num; + u8 gpio_scl_num; + u8 twsi_eeprom_dev; + u8 board_atten; + + /* Support (including locks) for EEPROM logging of errors and time */ + /* control access to actual counters, timer */ + spinlock_t eep_st_lock; + /* control high-level access to EEPROM */ + struct mutex eep_lock; + uint64_t traffic_wds; + /* active time is kept in seconds, but logged in hours */ + atomic_t active_time; + /* Below are nominal shadow of EEPROM, new since last EEPROM update */ + uint8_t eep_st_errs[QIB_EEP_LOG_CNT]; + uint8_t eep_st_new_errs[QIB_EEP_LOG_CNT]; + uint16_t eep_hrs; + /* + * masks for which bits of errs, hwerrs that cause + * each of the counters to increment. + */ + struct qib_eep_log_mask eep_st_masks[QIB_EEP_LOG_CNT]; + struct qib_diag_client *diag_client; + spinlock_t qib_diag_trans_lock; /* protect diag observer ops */ + struct diag_observer_list_elt *diag_observer_list; + + u8 psxmitwait_supported; + /* cycle length of PS* counters in HW (in picoseconds) */ + u16 psxmitwait_check_rate; +}; + +/* hol_state values */ +#define QIB_HOL_UP 0 +#define QIB_HOL_INIT 1 + +#define QIB_SDMA_SENDCTRL_OP_ENABLE (1U << 0) +#define QIB_SDMA_SENDCTRL_OP_INTENABLE (1U << 1) +#define QIB_SDMA_SENDCTRL_OP_HALT (1U << 2) +#define QIB_SDMA_SENDCTRL_OP_CLEANUP (1U << 3) +#define QIB_SDMA_SENDCTRL_OP_DRAIN (1U << 4) + +/* operation types for f_txchk_change() */ +#define TXCHK_CHG_TYPE_DIS1 3 +#define TXCHK_CHG_TYPE_ENAB1 2 +#define TXCHK_CHG_TYPE_KERN 1 +#define TXCHK_CHG_TYPE_USER 0 + +#define QIB_CHASE_TIME msecs_to_jiffies(145) +#define QIB_CHASE_DIS_TIME msecs_to_jiffies(160) + +/* Private data for file operations */ +struct qib_filedata { + struct qib_ctxtdata *rcd; + unsigned subctxt; + unsigned tidcursor; + struct qib_user_sdma_queue *pq; + int rec_cpu_num; /* for cpu affinity; -1 if none */ +}; + +extern struct list_head qib_dev_list; +extern spinlock_t qib_devs_lock; +extern struct qib_devdata *qib_lookup(int unit); +extern u32 qib_cpulist_count; +extern unsigned long *qib_cpulist; + +extern unsigned qib_wc_pat; +int qib_init(struct qib_devdata *, int); +int init_chip_wc_pat(struct qib_devdata *dd, u32); +int qib_enable_wc(struct qib_devdata *dd); +void qib_disable_wc(struct qib_devdata *dd); +int qib_count_units(int *npresentp, int *nupp); +int qib_count_active_units(void); + +int qib_cdev_init(int minor, const char *name, + const struct file_operations *fops, + struct cdev **cdevp, struct device **devp); +void qib_cdev_cleanup(struct cdev **cdevp, struct device **devp); +int qib_dev_init(void); +void qib_dev_cleanup(void); + +int qib_diag_add(struct qib_devdata *); +void qib_diag_remove(struct qib_devdata *); +void qib_handle_e_ibstatuschanged(struct qib_pportdata *, u64); +void qib_sdma_update_tail(struct qib_pportdata *, u16); /* hold sdma_lock */ + +int qib_decode_err(struct qib_devdata *dd, char *buf, size_t blen, u64 err); +void qib_bad_intrstatus(struct qib_devdata *); +void qib_handle_urcv(struct qib_devdata *, u64); + +/* clean up any per-chip chip-specific stuff */ +void qib_chip_cleanup(struct qib_devdata *); +/* clean up any chip type-specific stuff */ +void qib_chip_done(void); + +/* check to see if we have to force ordering for write combining */ +int qib_unordered_wc(void); +void qib_pio_copy(void __iomem *to, const void *from, size_t count); + +void qib_disarm_piobufs(struct qib_devdata *, unsigned, unsigned); +int qib_disarm_piobufs_ifneeded(struct qib_ctxtdata *); +void qib_disarm_piobufs_set(struct qib_devdata *, unsigned long *, unsigned); +void qib_cancel_sends(struct qib_pportdata *); + +int qib_create_rcvhdrq(struct qib_devdata *, struct qib_ctxtdata *); +int qib_setup_eagerbufs(struct qib_ctxtdata *); +void qib_set_ctxtcnt(struct qib_devdata *); +int qib_create_ctxts(struct qib_devdata *dd); +struct qib_ctxtdata *qib_create_ctxtdata(struct qib_pportdata *, u32); +void qib_init_pportdata(struct qib_pportdata *, struct qib_devdata *, u8, u8); +void qib_free_ctxtdata(struct qib_devdata *, struct qib_ctxtdata *); + +u32 qib_kreceive(struct qib_ctxtdata *, u32 *, u32 *); +int qib_reset_device(int); +int qib_wait_linkstate(struct qib_pportdata *, u32, int); +int qib_set_linkstate(struct qib_pportdata *, u8); +int qib_set_mtu(struct qib_pportdata *, u16); +int qib_set_lid(struct qib_pportdata *, u32, u8); +void qib_hol_down(struct qib_pportdata *); +void qib_hol_init(struct qib_pportdata *); +void qib_hol_up(struct qib_pportdata *); +void qib_hol_event(unsigned long); +void qib_disable_after_error(struct qib_devdata *); +int qib_set_uevent_bits(struct qib_pportdata *, const int); + +/* for use in system calls, where we want to know device type, etc. */ +#define ctxt_fp(fp) \ + (((struct qib_filedata *)(fp)->private_data)->rcd) +#define subctxt_fp(fp) \ + (((struct qib_filedata *)(fp)->private_data)->subctxt) +#define tidcursor_fp(fp) \ + (((struct qib_filedata *)(fp)->private_data)->tidcursor) +#define user_sdma_queue_fp(fp) \ + (((struct qib_filedata *)(fp)->private_data)->pq) + +static inline struct qib_devdata *dd_from_ppd(struct qib_pportdata *ppd) +{ + return ppd->dd; +} + +static inline struct qib_devdata *dd_from_dev(struct qib_ibdev *dev) +{ + return container_of(dev, struct qib_devdata, verbs_dev); +} + +static inline struct qib_devdata *dd_from_ibdev(struct ib_device *ibdev) +{ + return dd_from_dev(to_idev(ibdev)); +} + +static inline struct qib_pportdata *ppd_from_ibp(struct qib_ibport *ibp) +{ + return container_of(ibp, struct qib_pportdata, ibport_data); +} + +static inline struct qib_ibport *to_iport(struct ib_device *ibdev, u8 port) +{ + struct qib_devdata *dd = dd_from_ibdev(ibdev); + unsigned pidx = port - 1; /* IB number port from 1, hdw from 0 */ + + WARN_ON(pidx >= dd->num_pports); + return &dd->pport[pidx].ibport_data; +} + +/* + * values for dd->flags (_device_ related flags) and + */ +#define QIB_HAS_LINK_LATENCY 0x1 /* supports link latency (IB 1.2) */ +#define QIB_INITTED 0x2 /* chip and driver up and initted */ +#define QIB_DOING_RESET 0x4 /* in the middle of doing chip reset */ +#define QIB_PRESENT 0x8 /* chip accesses can be done */ +#define QIB_PIO_FLUSH_WC 0x10 /* Needs Write combining flush for PIO */ +#define QIB_HAS_THRESH_UPDATE 0x40 +#define QIB_HAS_SDMA_TIMEOUT 0x80 +#define QIB_USE_SPCL_TRIG 0x100 /* SpecialTrigger launch enabled */ +#define QIB_NODMA_RTAIL 0x200 /* rcvhdrtail register DMA enabled */ +#define QIB_HAS_INTX 0x800 /* Supports INTx interrupts */ +#define QIB_HAS_SEND_DMA 0x1000 /* Supports Send DMA */ +#define QIB_HAS_VLSUPP 0x2000 /* Supports multiple VLs; PBC different */ +#define QIB_HAS_HDRSUPP 0x4000 /* Supports header suppression */ +#define QIB_BADINTR 0x8000 /* severe interrupt problems */ +#define QIB_DCA_ENABLED 0x10000 /* Direct Cache Access enabled */ +#define QIB_HAS_QSFP 0x20000 /* device (card instance) has QSFP */ + +/* + * values for ppd->lflags (_ib_port_ related flags) + */ +#define QIBL_LINKV 0x1 /* IB link state valid */ +#define QIBL_LINKDOWN 0x8 /* IB link is down */ +#define QIBL_LINKINIT 0x10 /* IB link level is up */ +#define QIBL_LINKARMED 0x20 /* IB link is ARMED */ +#define QIBL_LINKACTIVE 0x40 /* IB link is ACTIVE */ +/* leave a gap for more IB-link state */ +#define QIBL_IB_AUTONEG_INPROG 0x1000 /* non-IBTA DDR/QDR neg active */ +#define QIBL_IB_AUTONEG_FAILED 0x2000 /* non-IBTA DDR/QDR neg failed */ +#define QIBL_IB_LINK_DISABLED 0x4000 /* Linkdown-disable forced, + * Do not try to bring up */ +#define QIBL_IB_FORCE_NOTIFY 0x8000 /* force notify on next ib change */ + +/* IB dword length mask in PBC (lower 11 bits); same for all chips */ +#define QIB_PBC_LENGTH_MASK ((1 << 11) - 1) + + +/* ctxt_flag bit offsets */ + /* waiting for a packet to arrive */ +#define QIB_CTXT_WAITING_RCV 2 + /* master has not finished initializing */ +#define QIB_CTXT_MASTER_UNINIT 4 + /* waiting for an urgent packet to arrive */ +#define QIB_CTXT_WAITING_URG 5 + +/* free up any allocated data at closes */ +void qib_free_data(struct qib_ctxtdata *dd); +void qib_chg_pioavailkernel(struct qib_devdata *, unsigned, unsigned, + u32, struct qib_ctxtdata *); +struct qib_devdata *qib_init_iba7322_funcs(struct pci_dev *, + const struct pci_device_id *); +struct qib_devdata *qib_init_iba7220_funcs(struct pci_dev *, + const struct pci_device_id *); +struct qib_devdata *qib_init_iba6120_funcs(struct pci_dev *, + const struct pci_device_id *); +void qib_free_devdata(struct qib_devdata *); +struct qib_devdata *qib_alloc_devdata(struct pci_dev *pdev, size_t extra); + +#define QIB_TWSI_NO_DEV 0xFF +/* Below qib_twsi_ functions must be called with eep_lock held */ +int qib_twsi_reset(struct qib_devdata *dd); +int qib_twsi_blk_rd(struct qib_devdata *dd, int dev, int addr, void *buffer, + int len); +int qib_twsi_blk_wr(struct qib_devdata *dd, int dev, int addr, + const void *buffer, int len); +void qib_get_eeprom_info(struct qib_devdata *); +int qib_update_eeprom_log(struct qib_devdata *dd); +void qib_inc_eeprom_err(struct qib_devdata *dd, u32 eidx, u32 incr); +void qib_dump_lookup_output_queue(struct qib_devdata *); +void qib_force_pio_avail_update(struct qib_devdata *); +void qib_clear_symerror_on_linkup(unsigned long opaque); + +/* + * Set LED override, only the two LSBs have "public" meaning, but + * any non-zero value substitutes them for the Link and LinkTrain + * LED states. + */ +#define QIB_LED_PHYS 1 /* Physical (linktraining) GREEN LED */ +#define QIB_LED_LOG 2 /* Logical (link) YELLOW LED */ +void qib_set_led_override(struct qib_pportdata *ppd, unsigned int val); + +/* send dma routines */ +int qib_setup_sdma(struct qib_pportdata *); +void qib_teardown_sdma(struct qib_pportdata *); +void __qib_sdma_intr(struct qib_pportdata *); +void qib_sdma_intr(struct qib_pportdata *); +int qib_sdma_verbs_send(struct qib_pportdata *, struct qib_sge_state *, + u32, struct qib_verbs_txreq *); +/* ppd->sdma_lock should be locked before calling this. */ +int qib_sdma_make_progress(struct qib_pportdata *dd); + +/* must be called under qib_sdma_lock */ +static inline u16 qib_sdma_descq_freecnt(const struct qib_pportdata *ppd) +{ + return ppd->sdma_descq_cnt - + (ppd->sdma_descq_added - ppd->sdma_descq_removed) - 1; +} + +static inline int __qib_sdma_running(struct qib_pportdata *ppd) +{ + return ppd->sdma_state.current_state == qib_sdma_state_s99_running; +} +int qib_sdma_running(struct qib_pportdata *); + +void __qib_sdma_process_event(struct qib_pportdata *, enum qib_sdma_events); +void qib_sdma_process_event(struct qib_pportdata *, enum qib_sdma_events); + +/* + * number of words used for protocol header if not set by qib_userinit(); + */ +#define QIB_DFLT_RCVHDRSIZE 9 + +/* + * We need to be able to handle an IB header of at least 24 dwords. + * We need the rcvhdrq large enough to handle largest IB header, but + * still have room for a 2KB MTU standard IB packet. + * Additionally, some processor/memory controller combinations + * benefit quite strongly from having the DMA'ed data be cacheline + * aligned and a cacheline multiple, so we set the size to 32 dwords + * (2 64-byte primary cachelines for pretty much all processors of + * interest). The alignment hurts nothing, other than using somewhat + * more memory. + */ +#define QIB_RCVHDR_ENTSIZE 32 + +int qib_get_user_pages(unsigned long, size_t, struct page **); +void qib_release_user_pages(struct page **, size_t); +int qib_eeprom_read(struct qib_devdata *, u8, void *, int); +int qib_eeprom_write(struct qib_devdata *, u8, const void *, int); +u32 __iomem *qib_getsendbuf_range(struct qib_devdata *, u32 *, u32, u32); +void qib_sendbuf_done(struct qib_devdata *, unsigned); + +static inline void qib_clear_rcvhdrtail(const struct qib_ctxtdata *rcd) +{ + *((u64 *) rcd->rcvhdrtail_kvaddr) = 0ULL; +} + +static inline u32 qib_get_rcvhdrtail(const struct qib_ctxtdata *rcd) +{ + /* + * volatile because it's a DMA target from the chip, routine is + * inlined, and don't want register caching or reordering. + */ + return (u32) le64_to_cpu( + *((volatile __le64 *)rcd->rcvhdrtail_kvaddr)); /* DMA'ed */ +} + +static inline u32 qib_get_hdrqtail(const struct qib_ctxtdata *rcd) +{ + const struct qib_devdata *dd = rcd->dd; + u32 hdrqtail; + + if (dd->flags & QIB_NODMA_RTAIL) { + __le32 *rhf_addr; + u32 seq; + + rhf_addr = (__le32 *) rcd->rcvhdrq + + rcd->head + dd->rhf_offset; + seq = qib_hdrget_seq(rhf_addr); + hdrqtail = rcd->head; + if (seq == rcd->seq_cnt) + hdrqtail++; + } else + hdrqtail = qib_get_rcvhdrtail(rcd); + + return hdrqtail; +} + +/* + * sysfs interface. + */ + +extern const char ib_qib_version[]; + +int qib_device_create(struct qib_devdata *); +void qib_device_remove(struct qib_devdata *); + +int qib_create_port_files(struct ib_device *ibdev, u8 port_num, + struct kobject *kobj); +int qib_verbs_register_sysfs(struct qib_devdata *); +void qib_verbs_unregister_sysfs(struct qib_devdata *); +/* Hook for sysfs read of QSFP */ +extern int qib_qsfp_dump(struct qib_pportdata *ppd, char *buf, int len); + +int __init qib_init_qibfs(void); +int __exit qib_exit_qibfs(void); + +int qibfs_add(struct qib_devdata *); +int qibfs_remove(struct qib_devdata *); + +int qib_pcie_init(struct pci_dev *, const struct pci_device_id *); +int qib_pcie_ddinit(struct qib_devdata *, struct pci_dev *, + const struct pci_device_id *); +void qib_pcie_ddcleanup(struct qib_devdata *); +int qib_pcie_params(struct qib_devdata *, u32, u32 *, struct msix_entry *); +int qib_reinit_intr(struct qib_devdata *); +void qib_enable_intx(struct pci_dev *); +void qib_nomsi(struct qib_devdata *); +void qib_nomsix(struct qib_devdata *); +void qib_pcie_getcmd(struct qib_devdata *, u16 *, u8 *, u8 *); +void qib_pcie_reenable(struct qib_devdata *, u16, u8, u8); + +/* + * dma_addr wrappers - all 0's invalid for hw + */ +dma_addr_t qib_map_page(struct pci_dev *, struct page *, unsigned long, + size_t, int); +const char *qib_get_unit_name(int unit); + +/* + * Flush write combining store buffers (if present) and perform a write + * barrier. + */ +#if defined(CONFIG_X86_64) +#define qib_flush_wc() asm volatile("sfence" : : : "memory") +#else +#define qib_flush_wc() wmb() /* no reorder around wc flush */ +#endif + +/* global module parameter variables */ +extern unsigned qib_ibmtu; +extern ushort qib_cfgctxts; +extern ushort qib_num_cfg_vls; +extern ushort qib_mini_init; /* If set, do few (ideally 0) writes to chip */ +extern unsigned qib_n_krcv_queues; +extern unsigned qib_sdma_fetch_arb; +extern unsigned qib_compat_ddr_negotiate; +extern int qib_special_trigger; + +extern struct mutex qib_mutex; + +/* Number of seconds before our card status check... */ +#define STATUS_TIMEOUT 60 + +#define QIB_DRV_NAME "ib_qib" +#define QIB_USER_MINOR_BASE 0 +#define QIB_TRACE_MINOR 127 +#define QIB_DIAGPKT_MINOR 128 +#define QIB_DIAG_MINOR_BASE 129 +#define QIB_NMINORS 255 + +#define PCI_VENDOR_ID_PATHSCALE 0x1fc1 +#define PCI_VENDOR_ID_QLOGIC 0x1077 +#define PCI_DEVICE_ID_QLOGIC_IB_6120 0x10 +#define PCI_DEVICE_ID_QLOGIC_IB_7220 0x7220 +#define PCI_DEVICE_ID_QLOGIC_IB_7322 0x7322 + +/* + * qib_early_err is used (only!) to print early errors before devdata is + * allocated, or when dd->pcidev may not be valid, and at the tail end of + * cleanup when devdata may have been freed, etc. qib_dev_porterr is + * the same as qib_dev_err, but is used when the message really needs + * the IB port# to be definitive as to what's happening.. + * All of these go to the trace log, and the trace log entry is done + * first to avoid possible serial port delays from printk. + */ +#define qib_early_err(dev, fmt, ...) \ + do { \ + dev_info(dev, KERN_ERR QIB_DRV_NAME ": " fmt, ##__VA_ARGS__); \ + } while (0) + +#define qib_dev_err(dd, fmt, ...) \ + do { \ + dev_err(&(dd)->pcidev->dev, "%s: " fmt, \ + qib_get_unit_name((dd)->unit), ##__VA_ARGS__); \ + } while (0) + +#define qib_dev_porterr(dd, port, fmt, ...) \ + do { \ + dev_err(&(dd)->pcidev->dev, "%s: IB%u:%u " fmt, \ + qib_get_unit_name((dd)->unit), (dd)->unit, (port), \ + ##__VA_ARGS__); \ + } while (0) + +#define qib_devinfo(pcidev, fmt, ...) \ + do { \ + dev_info(&(pcidev)->dev, fmt, ##__VA_ARGS__); \ + } while (0) + +/* + * this is used for formatting hw error messages... + */ +struct qib_hwerror_msgs { + u64 mask; + const char *msg; +}; + +#define QLOGIC_IB_HWE_MSG(a, b) { .mask = a, .msg = b } + +/* in qib_intr.c... */ +void qib_format_hwerrors(u64 hwerrs, + const struct qib_hwerror_msgs *hwerrmsgs, + size_t nhwerrmsgs, char *msg, size_t lmsg); +#endif /* _QIB_KERNEL_H */ diff --git a/drivers/infiniband/hw/qib/qib_6120_regs.h b/drivers/infiniband/hw/qib/qib_6120_regs.h new file mode 100644 index 000000000000..e16cb6f7de2c --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_6120_regs.h @@ -0,0 +1,977 @@ +/* + * Copyright (c) 2008, 2009, 2010 QLogic Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* This file is mechanically generated from RTL. Any hand-edits will be lost! */ + +#define QIB_6120_Revision_OFFS 0x0 +#define QIB_6120_Revision_R_Simulator_LSB 0x3F +#define QIB_6120_Revision_R_Simulator_RMASK 0x1 +#define QIB_6120_Revision_Reserved_LSB 0x28 +#define QIB_6120_Revision_Reserved_RMASK 0x7FFFFF +#define QIB_6120_Revision_BoardID_LSB 0x20 +#define QIB_6120_Revision_BoardID_RMASK 0xFF +#define QIB_6120_Revision_R_SW_LSB 0x18 +#define QIB_6120_Revision_R_SW_RMASK 0xFF +#define QIB_6120_Revision_R_Arch_LSB 0x10 +#define QIB_6120_Revision_R_Arch_RMASK 0xFF +#define QIB_6120_Revision_R_ChipRevMajor_LSB 0x8 +#define QIB_6120_Revision_R_ChipRevMajor_RMASK 0xFF +#define QIB_6120_Revision_R_ChipRevMinor_LSB 0x0 +#define QIB_6120_Revision_R_ChipRevMinor_RMASK 0xFF + +#define QIB_6120_Control_OFFS 0x8 +#define QIB_6120_Control_TxLatency_LSB 0x4 +#define QIB_6120_Control_TxLatency_RMASK 0x1 +#define QIB_6120_Control_PCIERetryBufDiagEn_LSB 0x3 +#define QIB_6120_Control_PCIERetryBufDiagEn_RMASK 0x1 +#define QIB_6120_Control_LinkEn_LSB 0x2 +#define QIB_6120_Control_LinkEn_RMASK 0x1 +#define QIB_6120_Control_FreezeMode_LSB 0x1 +#define QIB_6120_Control_FreezeMode_RMASK 0x1 +#define QIB_6120_Control_SyncReset_LSB 0x0 +#define QIB_6120_Control_SyncReset_RMASK 0x1 + +#define QIB_6120_PageAlign_OFFS 0x10 + +#define QIB_6120_PortCnt_OFFS 0x18 + +#define QIB_6120_SendRegBase_OFFS 0x30 + +#define QIB_6120_UserRegBase_OFFS 0x38 + +#define QIB_6120_CntrRegBase_OFFS 0x40 + +#define QIB_6120_Scratch_OFFS 0x48 +#define QIB_6120_Scratch_TopHalf_LSB 0x20 +#define QIB_6120_Scratch_TopHalf_RMASK 0xFFFFFFFF +#define QIB_6120_Scratch_BottomHalf_LSB 0x0 +#define QIB_6120_Scratch_BottomHalf_RMASK 0xFFFFFFFF + +#define QIB_6120_IntBlocked_OFFS 0x60 +#define QIB_6120_IntBlocked_ErrorIntBlocked_LSB 0x1F +#define QIB_6120_IntBlocked_ErrorIntBlocked_RMASK 0x1 +#define QIB_6120_IntBlocked_PioSetIntBlocked_LSB 0x1E +#define QIB_6120_IntBlocked_PioSetIntBlocked_RMASK 0x1 +#define QIB_6120_IntBlocked_PioBufAvailIntBlocked_LSB 0x1D +#define QIB_6120_IntBlocked_PioBufAvailIntBlocked_RMASK 0x1 +#define QIB_6120_IntBlocked_assertGPIOIntBlocked_LSB 0x1C +#define QIB_6120_IntBlocked_assertGPIOIntBlocked_RMASK 0x1 +#define QIB_6120_IntBlocked_Reserved_LSB 0xF +#define QIB_6120_IntBlocked_Reserved_RMASK 0x1FFF +#define QIB_6120_IntBlocked_RcvAvail4IntBlocked_LSB 0x10 +#define QIB_6120_IntBlocked_RcvAvail4IntBlocked_RMASK 0x1 +#define QIB_6120_IntBlocked_RcvAvail3IntBlocked_LSB 0xF +#define QIB_6120_IntBlocked_RcvAvail3IntBlocked_RMASK 0x1 +#define QIB_6120_IntBlocked_RcvAvail2IntBlocked_LSB 0xE +#define QIB_6120_IntBlocked_RcvAvail2IntBlocked_RMASK 0x1 +#define QIB_6120_IntBlocked_RcvAvail1IntBlocked_LSB 0xD +#define QIB_6120_IntBlocked_RcvAvail1IntBlocked_RMASK 0x1 +#define QIB_6120_IntBlocked_RcvAvail0IntBlocked_LSB 0xC +#define QIB_6120_IntBlocked_RcvAvail0IntBlocked_RMASK 0x1 +#define QIB_6120_IntBlocked_Reserved1_LSB 0x5 +#define QIB_6120_IntBlocked_Reserved1_RMASK 0x7F +#define QIB_6120_IntBlocked_RcvUrg4IntBlocked_LSB 0x4 +#define QIB_6120_IntBlocked_RcvUrg4IntBlocked_RMASK 0x1 +#define QIB_6120_IntBlocked_RcvUrg3IntBlocked_LSB 0x3 +#define QIB_6120_IntBlocked_RcvUrg3IntBlocked_RMASK 0x1 +#define QIB_6120_IntBlocked_RcvUrg2IntBlocked_LSB 0x2 +#define QIB_6120_IntBlocked_RcvUrg2IntBlocked_RMASK 0x1 +#define QIB_6120_IntBlocked_RcvUrg1IntBlocked_LSB 0x1 +#define QIB_6120_IntBlocked_RcvUrg1IntBlocked_RMASK 0x1 +#define QIB_6120_IntBlocked_RcvUrg0IntBlocked_LSB 0x0 +#define QIB_6120_IntBlocked_RcvUrg0IntBlocked_RMASK 0x1 + +#define QIB_6120_IntMask_OFFS 0x68 +#define QIB_6120_IntMask_ErrorIntMask_LSB 0x1F +#define QIB_6120_IntMask_ErrorIntMask_RMASK 0x1 +#define QIB_6120_IntMask_PioSetIntMask_LSB 0x1E +#define QIB_6120_IntMask_PioSetIntMask_RMASK 0x1 +#define QIB_6120_IntMask_PioBufAvailIntMask_LSB 0x1D +#define QIB_6120_IntMask_PioBufAvailIntMask_RMASK 0x1 +#define QIB_6120_IntMask_assertGPIOIntMask_LSB 0x1C +#define QIB_6120_IntMask_assertGPIOIntMask_RMASK 0x1 +#define QIB_6120_IntMask_Reserved_LSB 0x11 +#define QIB_6120_IntMask_Reserved_RMASK 0x7FF +#define QIB_6120_IntMask_RcvAvail4IntMask_LSB 0x10 +#define QIB_6120_IntMask_RcvAvail4IntMask_RMASK 0x1 +#define QIB_6120_IntMask_RcvAvail3IntMask_LSB 0xF +#define QIB_6120_IntMask_RcvAvail3IntMask_RMASK 0x1 +#define QIB_6120_IntMask_RcvAvail2IntMask_LSB 0xE +#define QIB_6120_IntMask_RcvAvail2IntMask_RMASK 0x1 +#define QIB_6120_IntMask_RcvAvail1IntMask_LSB 0xD +#define QIB_6120_IntMask_RcvAvail1IntMask_RMASK 0x1 +#define QIB_6120_IntMask_RcvAvail0IntMask_LSB 0xC +#define QIB_6120_IntMask_RcvAvail0IntMask_RMASK 0x1 +#define QIB_6120_IntMask_Reserved1_LSB 0x5 +#define QIB_6120_IntMask_Reserved1_RMASK 0x7F +#define QIB_6120_IntMask_RcvUrg4IntMask_LSB 0x4 +#define QIB_6120_IntMask_RcvUrg4IntMask_RMASK 0x1 +#define QIB_6120_IntMask_RcvUrg3IntMask_LSB 0x3 +#define QIB_6120_IntMask_RcvUrg3IntMask_RMASK 0x1 +#define QIB_6120_IntMask_RcvUrg2IntMask_LSB 0x2 +#define QIB_6120_IntMask_RcvUrg2IntMask_RMASK 0x1 +#define QIB_6120_IntMask_RcvUrg1IntMask_LSB 0x1 +#define QIB_6120_IntMask_RcvUrg1IntMask_RMASK 0x1 +#define QIB_6120_IntMask_RcvUrg0IntMask_LSB 0x0 +#define QIB_6120_IntMask_RcvUrg0IntMask_RMASK 0x1 + +#define QIB_6120_IntStatus_OFFS 0x70 +#define QIB_6120_IntStatus_Error_LSB 0x1F +#define QIB_6120_IntStatus_Error_RMASK 0x1 +#define QIB_6120_IntStatus_PioSent_LSB 0x1E +#define QIB_6120_IntStatus_PioSent_RMASK 0x1 +#define QIB_6120_IntStatus_PioBufAvail_LSB 0x1D +#define QIB_6120_IntStatus_PioBufAvail_RMASK 0x1 +#define QIB_6120_IntStatus_assertGPIO_LSB 0x1C +#define QIB_6120_IntStatus_assertGPIO_RMASK 0x1 +#define QIB_6120_IntStatus_Reserved_LSB 0xF +#define QIB_6120_IntStatus_Reserved_RMASK 0x1FFF +#define QIB_6120_IntStatus_RcvAvail4_LSB 0x10 +#define QIB_6120_IntStatus_RcvAvail4_RMASK 0x1 +#define QIB_6120_IntStatus_RcvAvail3_LSB 0xF +#define QIB_6120_IntStatus_RcvAvail3_RMASK 0x1 +#define QIB_6120_IntStatus_RcvAvail2_LSB 0xE +#define QIB_6120_IntStatus_RcvAvail2_RMASK 0x1 +#define QIB_6120_IntStatus_RcvAvail1_LSB 0xD +#define QIB_6120_IntStatus_RcvAvail1_RMASK 0x1 +#define QIB_6120_IntStatus_RcvAvail0_LSB 0xC +#define QIB_6120_IntStatus_RcvAvail0_RMASK 0x1 +#define QIB_6120_IntStatus_Reserved1_LSB 0x5 +#define QIB_6120_IntStatus_Reserved1_RMASK 0x7F +#define QIB_6120_IntStatus_RcvUrg4_LSB 0x4 +#define QIB_6120_IntStatus_RcvUrg4_RMASK 0x1 +#define QIB_6120_IntStatus_RcvUrg3_LSB 0x3 +#define QIB_6120_IntStatus_RcvUrg3_RMASK 0x1 +#define QIB_6120_IntStatus_RcvUrg2_LSB 0x2 +#define QIB_6120_IntStatus_RcvUrg2_RMASK 0x1 +#define QIB_6120_IntStatus_RcvUrg1_LSB 0x1 +#define QIB_6120_IntStatus_RcvUrg1_RMASK 0x1 +#define QIB_6120_IntStatus_RcvUrg0_LSB 0x0 +#define QIB_6120_IntStatus_RcvUrg0_RMASK 0x1 + +#define QIB_6120_IntClear_OFFS 0x78 +#define QIB_6120_IntClear_ErrorIntClear_LSB 0x1F +#define QIB_6120_IntClear_ErrorIntClear_RMASK 0x1 +#define QIB_6120_IntClear_PioSetIntClear_LSB 0x1E +#define QIB_6120_IntClear_PioSetIntClear_RMASK 0x1 +#define QIB_6120_IntClear_PioBufAvailIntClear_LSB 0x1D +#define QIB_6120_IntClear_PioBufAvailIntClear_RMASK 0x1 +#define QIB_6120_IntClear_assertGPIOIntClear_LSB 0x1C +#define QIB_6120_IntClear_assertGPIOIntClear_RMASK 0x1 +#define QIB_6120_IntClear_Reserved_LSB 0xF +#define QIB_6120_IntClear_Reserved_RMASK 0x1FFF +#define QIB_6120_IntClear_RcvAvail4IntClear_LSB 0x10 +#define QIB_6120_IntClear_RcvAvail4IntClear_RMASK 0x1 +#define QIB_6120_IntClear_RcvAvail3IntClear_LSB 0xF +#define QIB_6120_IntClear_RcvAvail3IntClear_RMASK 0x1 +#define QIB_6120_IntClear_RcvAvail2IntClear_LSB 0xE +#define QIB_6120_IntClear_RcvAvail2IntClear_RMASK 0x1 +#define QIB_6120_IntClear_RcvAvail1IntClear_LSB 0xD +#define QIB_6120_IntClear_RcvAvail1IntClear_RMASK 0x1 +#define QIB_6120_IntClear_RcvAvail0IntClear_LSB 0xC +#define QIB_6120_IntClear_RcvAvail0IntClear_RMASK 0x1 +#define QIB_6120_IntClear_Reserved1_LSB 0x5 +#define QIB_6120_IntClear_Reserved1_RMASK 0x7F +#define QIB_6120_IntClear_RcvUrg4IntClear_LSB 0x4 +#define QIB_6120_IntClear_RcvUrg4IntClear_RMASK 0x1 +#define QIB_6120_IntClear_RcvUrg3IntClear_LSB 0x3 +#define QIB_6120_IntClear_RcvUrg3IntClear_RMASK 0x1 +#define QIB_6120_IntClear_RcvUrg2IntClear_LSB 0x2 +#define QIB_6120_IntClear_RcvUrg2IntClear_RMASK 0x1 +#define QIB_6120_IntClear_RcvUrg1IntClear_LSB 0x1 +#define QIB_6120_IntClear_RcvUrg1IntClear_RMASK 0x1 +#define QIB_6120_IntClear_RcvUrg0IntClear_LSB 0x0 +#define QIB_6120_IntClear_RcvUrg0IntClear_RMASK 0x1 + +#define QIB_6120_ErrMask_OFFS 0x80 +#define QIB_6120_ErrMask_Reserved_LSB 0x34 +#define QIB_6120_ErrMask_Reserved_RMASK 0xFFF +#define QIB_6120_ErrMask_HardwareErrMask_LSB 0x33 +#define QIB_6120_ErrMask_HardwareErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_ResetNegatedMask_LSB 0x32 +#define QIB_6120_ErrMask_ResetNegatedMask_RMASK 0x1 +#define QIB_6120_ErrMask_InvalidAddrErrMask_LSB 0x31 +#define QIB_6120_ErrMask_InvalidAddrErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_IBStatusChangedMask_LSB 0x30 +#define QIB_6120_ErrMask_IBStatusChangedMask_RMASK 0x1 +#define QIB_6120_ErrMask_Reserved1_LSB 0x26 +#define QIB_6120_ErrMask_Reserved1_RMASK 0x3FF +#define QIB_6120_ErrMask_SendUnsupportedVLErrMask_LSB 0x25 +#define QIB_6120_ErrMask_SendUnsupportedVLErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_SendUnexpectedPktNumErrMask_LSB 0x24 +#define QIB_6120_ErrMask_SendUnexpectedPktNumErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_SendPioArmLaunchErrMask_LSB 0x23 +#define QIB_6120_ErrMask_SendPioArmLaunchErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_SendDroppedDataPktErrMask_LSB 0x22 +#define QIB_6120_ErrMask_SendDroppedDataPktErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_SendDroppedSmpPktErrMask_LSB 0x21 +#define QIB_6120_ErrMask_SendDroppedSmpPktErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_SendPktLenErrMask_LSB 0x20 +#define QIB_6120_ErrMask_SendPktLenErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_SendUnderRunErrMask_LSB 0x1F +#define QIB_6120_ErrMask_SendUnderRunErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_SendMaxPktLenErrMask_LSB 0x1E +#define QIB_6120_ErrMask_SendMaxPktLenErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_SendMinPktLenErrMask_LSB 0x1D +#define QIB_6120_ErrMask_SendMinPktLenErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_Reserved2_LSB 0x12 +#define QIB_6120_ErrMask_Reserved2_RMASK 0x7FF +#define QIB_6120_ErrMask_RcvIBLostLinkErrMask_LSB 0x11 +#define QIB_6120_ErrMask_RcvIBLostLinkErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_RcvHdrErrMask_LSB 0x10 +#define QIB_6120_ErrMask_RcvHdrErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_RcvHdrLenErrMask_LSB 0xF +#define QIB_6120_ErrMask_RcvHdrLenErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_RcvBadTidErrMask_LSB 0xE +#define QIB_6120_ErrMask_RcvBadTidErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_RcvHdrFullErrMask_LSB 0xD +#define QIB_6120_ErrMask_RcvHdrFullErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_RcvEgrFullErrMask_LSB 0xC +#define QIB_6120_ErrMask_RcvEgrFullErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_RcvBadVersionErrMask_LSB 0xB +#define QIB_6120_ErrMask_RcvBadVersionErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_RcvIBFlowErrMask_LSB 0xA +#define QIB_6120_ErrMask_RcvIBFlowErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_RcvEBPErrMask_LSB 0x9 +#define QIB_6120_ErrMask_RcvEBPErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_RcvUnsupportedVLErrMask_LSB 0x8 +#define QIB_6120_ErrMask_RcvUnsupportedVLErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_RcvUnexpectedCharErrMask_LSB 0x7 +#define QIB_6120_ErrMask_RcvUnexpectedCharErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_RcvShortPktLenErrMask_LSB 0x6 +#define QIB_6120_ErrMask_RcvShortPktLenErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_RcvLongPktLenErrMask_LSB 0x5 +#define QIB_6120_ErrMask_RcvLongPktLenErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_RcvMaxPktLenErrMask_LSB 0x4 +#define QIB_6120_ErrMask_RcvMaxPktLenErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_RcvMinPktLenErrMask_LSB 0x3 +#define QIB_6120_ErrMask_RcvMinPktLenErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_RcvICRCErrMask_LSB 0x2 +#define QIB_6120_ErrMask_RcvICRCErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_RcvVCRCErrMask_LSB 0x1 +#define QIB_6120_ErrMask_RcvVCRCErrMask_RMASK 0x1 +#define QIB_6120_ErrMask_RcvFormatErrMask_LSB 0x0 +#define QIB_6120_ErrMask_RcvFormatErrMask_RMASK 0x1 + +#define QIB_6120_ErrStatus_OFFS 0x88 +#define QIB_6120_ErrStatus_Reserved_LSB 0x34 +#define QIB_6120_ErrStatus_Reserved_RMASK 0xFFF +#define QIB_6120_ErrStatus_HardwareErr_LSB 0x33 +#define QIB_6120_ErrStatus_HardwareErr_RMASK 0x1 +#define QIB_6120_ErrStatus_ResetNegated_LSB 0x32 +#define QIB_6120_ErrStatus_ResetNegated_RMASK 0x1 +#define QIB_6120_ErrStatus_InvalidAddrErr_LSB 0x31 +#define QIB_6120_ErrStatus_InvalidAddrErr_RMASK 0x1 +#define QIB_6120_ErrStatus_IBStatusChanged_LSB 0x30 +#define QIB_6120_ErrStatus_IBStatusChanged_RMASK 0x1 +#define QIB_6120_ErrStatus_Reserved1_LSB 0x26 +#define QIB_6120_ErrStatus_Reserved1_RMASK 0x3FF +#define QIB_6120_ErrStatus_SendUnsupportedVLErr_LSB 0x25 +#define QIB_6120_ErrStatus_SendUnsupportedVLErr_RMASK 0x1 +#define QIB_6120_ErrStatus_SendUnexpectedPktNumErr_LSB 0x24 +#define QIB_6120_ErrStatus_SendUnexpectedPktNumErr_RMASK 0x1 +#define QIB_6120_ErrStatus_SendPioArmLaunchErr_LSB 0x23 +#define QIB_6120_ErrStatus_SendPioArmLaunchErr_RMASK 0x1 +#define QIB_6120_ErrStatus_SendDroppedDataPktErr_LSB 0x22 +#define QIB_6120_ErrStatus_SendDroppedDataPktErr_RMASK 0x1 +#define QIB_6120_ErrStatus_SendDroppedSmpPktErr_LSB 0x21 +#define QIB_6120_ErrStatus_SendDroppedSmpPktErr_RMASK 0x1 +#define QIB_6120_ErrStatus_SendPktLenErr_LSB 0x20 +#define QIB_6120_ErrStatus_SendPktLenErr_RMASK 0x1 +#define QIB_6120_ErrStatus_SendUnderRunErr_LSB 0x1F +#define QIB_6120_ErrStatus_SendUnderRunErr_RMASK 0x1 +#define QIB_6120_ErrStatus_SendMaxPktLenErr_LSB 0x1E +#define QIB_6120_ErrStatus_SendMaxPktLenErr_RMASK 0x1 +#define QIB_6120_ErrStatus_SendMinPktLenErr_LSB 0x1D +#define QIB_6120_ErrStatus_SendMinPktLenErr_RMASK 0x1 +#define QIB_6120_ErrStatus_Reserved2_LSB 0x12 +#define QIB_6120_ErrStatus_Reserved2_RMASK 0x7FF +#define QIB_6120_ErrStatus_RcvIBLostLinkErr_LSB 0x11 +#define QIB_6120_ErrStatus_RcvIBLostLinkErr_RMASK 0x1 +#define QIB_6120_ErrStatus_RcvHdrErr_LSB 0x10 +#define QIB_6120_ErrStatus_RcvHdrErr_RMASK 0x1 +#define QIB_6120_ErrStatus_RcvHdrLenErr_LSB 0xF +#define QIB_6120_ErrStatus_RcvHdrLenErr_RMASK 0x1 +#define QIB_6120_ErrStatus_RcvBadTidErr_LSB 0xE +#define QIB_6120_ErrStatus_RcvBadTidErr_RMASK 0x1 +#define QIB_6120_ErrStatus_RcvHdrFullErr_LSB 0xD +#define QIB_6120_ErrStatus_RcvHdrFullErr_RMASK 0x1 +#define QIB_6120_ErrStatus_RcvEgrFullErr_LSB 0xC +#define QIB_6120_ErrStatus_RcvEgrFullErr_RMASK 0x1 +#define QIB_6120_ErrStatus_RcvBadVersionErr_LSB 0xB +#define QIB_6120_ErrStatus_RcvBadVersionErr_RMASK 0x1 +#define QIB_6120_ErrStatus_RcvIBFlowErr_LSB 0xA +#define QIB_6120_ErrStatus_RcvIBFlowErr_RMASK 0x1 +#define QIB_6120_ErrStatus_RcvEBPErr_LSB 0x9 +#define QIB_6120_ErrStatus_RcvEBPErr_RMASK 0x1 +#define QIB_6120_ErrStatus_RcvUnsupportedVLErr_LSB 0x8 +#define QIB_6120_ErrStatus_RcvUnsupportedVLErr_RMASK 0x1 +#define QIB_6120_ErrStatus_RcvUnexpectedCharErr_LSB 0x7 +#define QIB_6120_ErrStatus_RcvUnexpectedCharErr_RMASK 0x1 +#define QIB_6120_ErrStatus_RcvShortPktLenErr_LSB 0x6 +#define QIB_6120_ErrStatus_RcvShortPktLenErr_RMASK 0x1 +#define QIB_6120_ErrStatus_RcvLongPktLenErr_LSB 0x5 +#define QIB_6120_ErrStatus_RcvLongPktLenErr_RMASK 0x1 +#define QIB_6120_ErrStatus_RcvMaxPktLenErr_LSB 0x4 +#define QIB_6120_ErrStatus_RcvMaxPktLenErr_RMASK 0x1 +#define QIB_6120_ErrStatus_RcvMinPktLenErr_LSB 0x3 +#define QIB_6120_ErrStatus_RcvMinPktLenErr_RMASK 0x1 +#define QIB_6120_ErrStatus_RcvICRCErr_LSB 0x2 +#define QIB_6120_ErrStatus_RcvICRCErr_RMASK 0x1 +#define QIB_6120_ErrStatus_RcvVCRCErr_LSB 0x1 +#define QIB_6120_ErrStatus_RcvVCRCErr_RMASK 0x1 +#define QIB_6120_ErrStatus_RcvFormatErr_LSB 0x0 +#define QIB_6120_ErrStatus_RcvFormatErr_RMASK 0x1 + +#define QIB_6120_ErrClear_OFFS 0x90 +#define QIB_6120_ErrClear_Reserved_LSB 0x34 +#define QIB_6120_ErrClear_Reserved_RMASK 0xFFF +#define QIB_6120_ErrClear_HardwareErrClear_LSB 0x33 +#define QIB_6120_ErrClear_HardwareErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_ResetNegatedClear_LSB 0x32 +#define QIB_6120_ErrClear_ResetNegatedClear_RMASK 0x1 +#define QIB_6120_ErrClear_InvalidAddrErrClear_LSB 0x31 +#define QIB_6120_ErrClear_InvalidAddrErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_IBStatusChangedClear_LSB 0x30 +#define QIB_6120_ErrClear_IBStatusChangedClear_RMASK 0x1 +#define QIB_6120_ErrClear_Reserved1_LSB 0x26 +#define QIB_6120_ErrClear_Reserved1_RMASK 0x3FF +#define QIB_6120_ErrClear_SendUnsupportedVLErrClear_LSB 0x25 +#define QIB_6120_ErrClear_SendUnsupportedVLErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_SendUnexpectedPktNumErrClear_LSB 0x24 +#define QIB_6120_ErrClear_SendUnexpectedPktNumErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_SendPioArmLaunchErrClear_LSB 0x23 +#define QIB_6120_ErrClear_SendPioArmLaunchErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_SendDroppedDataPktErrClear_LSB 0x22 +#define QIB_6120_ErrClear_SendDroppedDataPktErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_SendDroppedSmpPktErrClear_LSB 0x21 +#define QIB_6120_ErrClear_SendDroppedSmpPktErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_SendPktLenErrClear_LSB 0x20 +#define QIB_6120_ErrClear_SendPktLenErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_SendUnderRunErrClear_LSB 0x1F +#define QIB_6120_ErrClear_SendUnderRunErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_SendMaxPktLenErrClear_LSB 0x1E +#define QIB_6120_ErrClear_SendMaxPktLenErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_SendMinPktLenErrClear_LSB 0x1D +#define QIB_6120_ErrClear_SendMinPktLenErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_Reserved2_LSB 0x12 +#define QIB_6120_ErrClear_Reserved2_RMASK 0x7FF +#define QIB_6120_ErrClear_RcvIBLostLinkErrClear_LSB 0x11 +#define QIB_6120_ErrClear_RcvIBLostLinkErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_RcvHdrErrClear_LSB 0x10 +#define QIB_6120_ErrClear_RcvHdrErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_RcvHdrLenErrClear_LSB 0xF +#define QIB_6120_ErrClear_RcvHdrLenErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_RcvBadTidErrClear_LSB 0xE +#define QIB_6120_ErrClear_RcvBadTidErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_RcvHdrFullErrClear_LSB 0xD +#define QIB_6120_ErrClear_RcvHdrFullErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_RcvEgrFullErrClear_LSB 0xC +#define QIB_6120_ErrClear_RcvEgrFullErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_RcvBadVersionErrClear_LSB 0xB +#define QIB_6120_ErrClear_RcvBadVersionErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_RcvIBFlowErrClear_LSB 0xA +#define QIB_6120_ErrClear_RcvIBFlowErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_RcvEBPErrClear_LSB 0x9 +#define QIB_6120_ErrClear_RcvEBPErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_RcvUnsupportedVLErrClear_LSB 0x8 +#define QIB_6120_ErrClear_RcvUnsupportedVLErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_RcvUnexpectedCharErrClear_LSB 0x7 +#define QIB_6120_ErrClear_RcvUnexpectedCharErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_RcvShortPktLenErrClear_LSB 0x6 +#define QIB_6120_ErrClear_RcvShortPktLenErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_RcvLongPktLenErrClear_LSB 0x5 +#define QIB_6120_ErrClear_RcvLongPktLenErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_RcvMaxPktLenErrClear_LSB 0x4 +#define QIB_6120_ErrClear_RcvMaxPktLenErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_RcvMinPktLenErrClear_LSB 0x3 +#define QIB_6120_ErrClear_RcvMinPktLenErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_RcvICRCErrClear_LSB 0x2 +#define QIB_6120_ErrClear_RcvICRCErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_RcvVCRCErrClear_LSB 0x1 +#define QIB_6120_ErrClear_RcvVCRCErrClear_RMASK 0x1 +#define QIB_6120_ErrClear_RcvFormatErrClear_LSB 0x0 +#define QIB_6120_ErrClear_RcvFormatErrClear_RMASK 0x1 + +#define QIB_6120_HwErrMask_OFFS 0x98 +#define QIB_6120_HwErrMask_IBCBusFromSPCParityErrMask_LSB 0x3F +#define QIB_6120_HwErrMask_IBCBusFromSPCParityErrMask_RMASK 0x1 +#define QIB_6120_HwErrMask_IBCBusToSPCParityErrMask_LSB 0x3E +#define QIB_6120_HwErrMask_IBCBusToSPCParityErrMask_RMASK 0x1 +#define QIB_6120_HwErrMask_Reserved_LSB 0x3D +#define QIB_6120_HwErrMask_Reserved_RMASK 0x1 +#define QIB_6120_HwErrMask_IBSerdesPClkNotDetectMask_LSB 0x3C +#define QIB_6120_HwErrMask_IBSerdesPClkNotDetectMask_RMASK 0x1 +#define QIB_6120_HwErrMask_PCIESerdesQ0PClkNotDetectMask_LSB 0x3B +#define QIB_6120_HwErrMask_PCIESerdesQ0PClkNotDetectMask_RMASK 0x1 +#define QIB_6120_HwErrMask_PCIESerdesQ1PClkNotDetectMask_LSB 0x3A +#define QIB_6120_HwErrMask_PCIESerdesQ1PClkNotDetectMask_RMASK 0x1 +#define QIB_6120_HwErrMask_Reserved1_LSB 0x39 +#define QIB_6120_HwErrMask_Reserved1_RMASK 0x1 +#define QIB_6120_HwErrMask_IBPLLrfSlipMask_LSB 0x38 +#define QIB_6120_HwErrMask_IBPLLrfSlipMask_RMASK 0x1 +#define QIB_6120_HwErrMask_IBPLLfbSlipMask_LSB 0x37 +#define QIB_6120_HwErrMask_IBPLLfbSlipMask_RMASK 0x1 +#define QIB_6120_HwErrMask_PowerOnBISTFailedMask_LSB 0x36 +#define QIB_6120_HwErrMask_PowerOnBISTFailedMask_RMASK 0x1 +#define QIB_6120_HwErrMask_Reserved2_LSB 0x33 +#define QIB_6120_HwErrMask_Reserved2_RMASK 0x7 +#define QIB_6120_HwErrMask_RXEMemParityErrMask_LSB 0x2C +#define QIB_6120_HwErrMask_RXEMemParityErrMask_RMASK 0x7F +#define QIB_6120_HwErrMask_TXEMemParityErrMask_LSB 0x28 +#define QIB_6120_HwErrMask_TXEMemParityErrMask_RMASK 0xF +#define QIB_6120_HwErrMask_Reserved3_LSB 0x22 +#define QIB_6120_HwErrMask_Reserved3_RMASK 0x3F +#define QIB_6120_HwErrMask_PCIeBusParityErrMask_LSB 0x1F +#define QIB_6120_HwErrMask_PCIeBusParityErrMask_RMASK 0x7 +#define QIB_6120_HwErrMask_PcieCplTimeoutMask_LSB 0x1E +#define QIB_6120_HwErrMask_PcieCplTimeoutMask_RMASK 0x1 +#define QIB_6120_HwErrMask_PoisonedTLPMask_LSB 0x1D +#define QIB_6120_HwErrMask_PoisonedTLPMask_RMASK 0x1 +#define QIB_6120_HwErrMask_Reserved4_LSB 0x6 +#define QIB_6120_HwErrMask_Reserved4_RMASK 0x7FFFFF +#define QIB_6120_HwErrMask_PCIeMemParityErrMask_LSB 0x0 +#define QIB_6120_HwErrMask_PCIeMemParityErrMask_RMASK 0x3F + +#define QIB_6120_HwErrStatus_OFFS 0xA0 +#define QIB_6120_HwErrStatus_IBCBusFromSPCParityErr_LSB 0x3F +#define QIB_6120_HwErrStatus_IBCBusFromSPCParityErr_RMASK 0x1 +#define QIB_6120_HwErrStatus_IBCBusToSPCParityErr_LSB 0x3E +#define QIB_6120_HwErrStatus_IBCBusToSPCParityErr_RMASK 0x1 +#define QIB_6120_HwErrStatus_Reserved_LSB 0x3D +#define QIB_6120_HwErrStatus_Reserved_RMASK 0x1 +#define QIB_6120_HwErrStatus_IBSerdesPClkNotDetect_LSB 0x3C +#define QIB_6120_HwErrStatus_IBSerdesPClkNotDetect_RMASK 0x1 +#define QIB_6120_HwErrStatus_PCIESerdesQ0PClkNotDetect_LSB 0x3B +#define QIB_6120_HwErrStatus_PCIESerdesQ0PClkNotDetect_RMASK 0x1 +#define QIB_6120_HwErrStatus_PCIESerdesQ1PClkNotDetect_LSB 0x3A +#define QIB_6120_HwErrStatus_PCIESerdesQ1PClkNotDetect_RMASK 0x1 +#define QIB_6120_HwErrStatus_Reserved1_LSB 0x39 +#define QIB_6120_HwErrStatus_Reserved1_RMASK 0x1 +#define QIB_6120_HwErrStatus_IBPLLrfSlip_LSB 0x38 +#define QIB_6120_HwErrStatus_IBPLLrfSlip_RMASK 0x1 +#define QIB_6120_HwErrStatus_IBPLLfbSlip_LSB 0x37 +#define QIB_6120_HwErrStatus_IBPLLfbSlip_RMASK 0x1 +#define QIB_6120_HwErrStatus_PowerOnBISTFailed_LSB 0x36 +#define QIB_6120_HwErrStatus_PowerOnBISTFailed_RMASK 0x1 +#define QIB_6120_HwErrStatus_Reserved2_LSB 0x33 +#define QIB_6120_HwErrStatus_Reserved2_RMASK 0x7 +#define QIB_6120_HwErrStatus_RXEMemParity_LSB 0x2C +#define QIB_6120_HwErrStatus_RXEMemParity_RMASK 0x7F +#define QIB_6120_HwErrStatus_TXEMemParity_LSB 0x28 +#define QIB_6120_HwErrStatus_TXEMemParity_RMASK 0xF +#define QIB_6120_HwErrStatus_Reserved3_LSB 0x22 +#define QIB_6120_HwErrStatus_Reserved3_RMASK 0x3F +#define QIB_6120_HwErrStatus_PCIeBusParity_LSB 0x1F +#define QIB_6120_HwErrStatus_PCIeBusParity_RMASK 0x7 +#define QIB_6120_HwErrStatus_PcieCplTimeout_LSB 0x1E +#define QIB_6120_HwErrStatus_PcieCplTimeout_RMASK 0x1 +#define QIB_6120_HwErrStatus_PoisenedTLP_LSB 0x1D +#define QIB_6120_HwErrStatus_PoisenedTLP_RMASK 0x1 +#define QIB_6120_HwErrStatus_Reserved4_LSB 0x6 +#define QIB_6120_HwErrStatus_Reserved4_RMASK 0x7FFFFF +#define QIB_6120_HwErrStatus_PCIeMemParity_LSB 0x0 +#define QIB_6120_HwErrStatus_PCIeMemParity_RMASK 0x3F + +#define QIB_6120_HwErrClear_OFFS 0xA8 +#define QIB_6120_HwErrClear_IBCBusFromSPCParityErrClear_LSB 0x3F +#define QIB_6120_HwErrClear_IBCBusFromSPCParityErrClear_RMASK 0x1 +#define QIB_6120_HwErrClear_IBCBusToSPCparityErrClear_LSB 0x3E +#define QIB_6120_HwErrClear_IBCBusToSPCparityErrClear_RMASK 0x1 +#define QIB_6120_HwErrClear_Reserved_LSB 0x3D +#define QIB_6120_HwErrClear_Reserved_RMASK 0x1 +#define QIB_6120_HwErrClear_IBSerdesPClkNotDetectClear_LSB 0x3C +#define QIB_6120_HwErrClear_IBSerdesPClkNotDetectClear_RMASK 0x1 +#define QIB_6120_HwErrClear_PCIESerdesQ0PClkNotDetectClear_LSB 0x3B +#define QIB_6120_HwErrClear_PCIESerdesQ0PClkNotDetectClear_RMASK 0x1 +#define QIB_6120_HwErrClear_PCIESerdesQ1PClkNotDetectClear_LSB 0x3A +#define QIB_6120_HwErrClear_PCIESerdesQ1PClkNotDetectClear_RMASK 0x1 +#define QIB_6120_HwErrClear_Reserved1_LSB 0x39 +#define QIB_6120_HwErrClear_Reserved1_RMASK 0x1 +#define QIB_6120_HwErrClear_IBPLLrfSlipClear_LSB 0x38 +#define QIB_6120_HwErrClear_IBPLLrfSlipClear_RMASK 0x1 +#define QIB_6120_HwErrClear_IBPLLfbSlipClear_LSB 0x37 +#define QIB_6120_HwErrClear_IBPLLfbSlipClear_RMASK 0x1 +#define QIB_6120_HwErrClear_PowerOnBISTFailedClear_LSB 0x36 +#define QIB_6120_HwErrClear_PowerOnBISTFailedClear_RMASK 0x1 +#define QIB_6120_HwErrClear_Reserved2_LSB 0x33 +#define QIB_6120_HwErrClear_Reserved2_RMASK 0x7 +#define QIB_6120_HwErrClear_RXEMemParityClear_LSB 0x2C +#define QIB_6120_HwErrClear_RXEMemParityClear_RMASK 0x7F +#define QIB_6120_HwErrClear_TXEMemParityClear_LSB 0x28 +#define QIB_6120_HwErrClear_TXEMemParityClear_RMASK 0xF +#define QIB_6120_HwErrClear_Reserved3_LSB 0x22 +#define QIB_6120_HwErrClear_Reserved3_RMASK 0x3F +#define QIB_6120_HwErrClear_PCIeBusParityClr_LSB 0x1F +#define QIB_6120_HwErrClear_PCIeBusParityClr_RMASK 0x7 +#define QIB_6120_HwErrClear_PcieCplTimeoutClear_LSB 0x1E +#define QIB_6120_HwErrClear_PcieCplTimeoutClear_RMASK 0x1 +#define QIB_6120_HwErrClear_PoisonedTLPClear_LSB 0x1D +#define QIB_6120_HwErrClear_PoisonedTLPClear_RMASK 0x1 +#define QIB_6120_HwErrClear_Reserved4_LSB 0x6 +#define QIB_6120_HwErrClear_Reserved4_RMASK 0x7FFFFF +#define QIB_6120_HwErrClear_PCIeMemParityClr_LSB 0x0 +#define QIB_6120_HwErrClear_PCIeMemParityClr_RMASK 0x3F + +#define QIB_6120_HwDiagCtrl_OFFS 0xB0 +#define QIB_6120_HwDiagCtrl_ForceIBCBusFromSPCParityErr_LSB 0x3F +#define QIB_6120_HwDiagCtrl_ForceIBCBusFromSPCParityErr_RMASK 0x1 +#define QIB_6120_HwDiagCtrl_ForceIBCBusToSPCParityErr_LSB 0x3E +#define QIB_6120_HwDiagCtrl_ForceIBCBusToSPCParityErr_RMASK 0x1 +#define QIB_6120_HwDiagCtrl_CounterWrEnable_LSB 0x3D +#define QIB_6120_HwDiagCtrl_CounterWrEnable_RMASK 0x1 +#define QIB_6120_HwDiagCtrl_CounterDisable_LSB 0x3C +#define QIB_6120_HwDiagCtrl_CounterDisable_RMASK 0x1 +#define QIB_6120_HwDiagCtrl_Reserved_LSB 0x33 +#define QIB_6120_HwDiagCtrl_Reserved_RMASK 0x1FF +#define QIB_6120_HwDiagCtrl_ForceRxMemParityErr_LSB 0x2C +#define QIB_6120_HwDiagCtrl_ForceRxMemParityErr_RMASK 0x7F +#define QIB_6120_HwDiagCtrl_ForceTxMemparityErr_LSB 0x28 +#define QIB_6120_HwDiagCtrl_ForceTxMemparityErr_RMASK 0xF +#define QIB_6120_HwDiagCtrl_Reserved1_LSB 0x23 +#define QIB_6120_HwDiagCtrl_Reserved1_RMASK 0x1F +#define QIB_6120_HwDiagCtrl_forcePCIeBusParity_LSB 0x1F +#define QIB_6120_HwDiagCtrl_forcePCIeBusParity_RMASK 0xF +#define QIB_6120_HwDiagCtrl_Reserved2_LSB 0x6 +#define QIB_6120_HwDiagCtrl_Reserved2_RMASK 0x1FFFFFF +#define QIB_6120_HwDiagCtrl_forcePCIeMemParity_LSB 0x0 +#define QIB_6120_HwDiagCtrl_forcePCIeMemParity_RMASK 0x3F + +#define QIB_6120_IBCStatus_OFFS 0xC0 +#define QIB_6120_IBCStatus_TxCreditOk_LSB 0x1F +#define QIB_6120_IBCStatus_TxCreditOk_RMASK 0x1 +#define QIB_6120_IBCStatus_TxReady_LSB 0x1E +#define QIB_6120_IBCStatus_TxReady_RMASK 0x1 +#define QIB_6120_IBCStatus_Reserved_LSB 0x7 +#define QIB_6120_IBCStatus_Reserved_RMASK 0x7FFFFF +#define QIB_6120_IBCStatus_LinkState_LSB 0x4 +#define QIB_6120_IBCStatus_LinkState_RMASK 0x7 +#define QIB_6120_IBCStatus_LinkTrainingState_LSB 0x0 +#define QIB_6120_IBCStatus_LinkTrainingState_RMASK 0xF + +#define QIB_6120_IBCCtrl_OFFS 0xC8 +#define QIB_6120_IBCCtrl_Loopback_LSB 0x3F +#define QIB_6120_IBCCtrl_Loopback_RMASK 0x1 +#define QIB_6120_IBCCtrl_LinkDownDefaultState_LSB 0x3E +#define QIB_6120_IBCCtrl_LinkDownDefaultState_RMASK 0x1 +#define QIB_6120_IBCCtrl_Reserved_LSB 0x2B +#define QIB_6120_IBCCtrl_Reserved_RMASK 0x7FFFF +#define QIB_6120_IBCCtrl_CreditScale_LSB 0x28 +#define QIB_6120_IBCCtrl_CreditScale_RMASK 0x7 +#define QIB_6120_IBCCtrl_OverrunThreshold_LSB 0x24 +#define QIB_6120_IBCCtrl_OverrunThreshold_RMASK 0xF +#define QIB_6120_IBCCtrl_PhyerrThreshold_LSB 0x20 +#define QIB_6120_IBCCtrl_PhyerrThreshold_RMASK 0xF +#define QIB_6120_IBCCtrl_Reserved1_LSB 0x1F +#define QIB_6120_IBCCtrl_Reserved1_RMASK 0x1 +#define QIB_6120_IBCCtrl_MaxPktLen_LSB 0x14 +#define QIB_6120_IBCCtrl_MaxPktLen_RMASK 0x7FF +#define QIB_6120_IBCCtrl_LinkCmd_LSB 0x12 +#define QIB_6120_IBCCtrl_LinkCmd_RMASK 0x3 +#define QIB_6120_IBCCtrl_LinkInitCmd_LSB 0x10 +#define QIB_6120_IBCCtrl_LinkInitCmd_RMASK 0x3 +#define QIB_6120_IBCCtrl_FlowCtrlWaterMark_LSB 0x8 +#define QIB_6120_IBCCtrl_FlowCtrlWaterMark_RMASK 0xFF +#define QIB_6120_IBCCtrl_FlowCtrlPeriod_LSB 0x0 +#define QIB_6120_IBCCtrl_FlowCtrlPeriod_RMASK 0xFF + +#define QIB_6120_EXTStatus_OFFS 0xD0 +#define QIB_6120_EXTStatus_GPIOIn_LSB 0x30 +#define QIB_6120_EXTStatus_GPIOIn_RMASK 0xFFFF +#define QIB_6120_EXTStatus_Reserved_LSB 0x20 +#define QIB_6120_EXTStatus_Reserved_RMASK 0xFFFF +#define QIB_6120_EXTStatus_Reserved1_LSB 0x10 +#define QIB_6120_EXTStatus_Reserved1_RMASK 0xFFFF +#define QIB_6120_EXTStatus_MemBISTFoundErr_LSB 0xF +#define QIB_6120_EXTStatus_MemBISTFoundErr_RMASK 0x1 +#define QIB_6120_EXTStatus_MemBISTEndTest_LSB 0xE +#define QIB_6120_EXTStatus_MemBISTEndTest_RMASK 0x1 +#define QIB_6120_EXTStatus_Reserved2_LSB 0x0 +#define QIB_6120_EXTStatus_Reserved2_RMASK 0x3FFF + +#define QIB_6120_EXTCtrl_OFFS 0xD8 +#define QIB_6120_EXTCtrl_GPIOOe_LSB 0x30 +#define QIB_6120_EXTCtrl_GPIOOe_RMASK 0xFFFF +#define QIB_6120_EXTCtrl_GPIOInvert_LSB 0x20 +#define QIB_6120_EXTCtrl_GPIOInvert_RMASK 0xFFFF +#define QIB_6120_EXTCtrl_Reserved_LSB 0x4 +#define QIB_6120_EXTCtrl_Reserved_RMASK 0xFFFFFFF +#define QIB_6120_EXTCtrl_LEDPriPortGreenOn_LSB 0x3 +#define QIB_6120_EXTCtrl_LEDPriPortGreenOn_RMASK 0x1 +#define QIB_6120_EXTCtrl_LEDPriPortYellowOn_LSB 0x2 +#define QIB_6120_EXTCtrl_LEDPriPortYellowOn_RMASK 0x1 +#define QIB_6120_EXTCtrl_LEDGblOkGreenOn_LSB 0x1 +#define QIB_6120_EXTCtrl_LEDGblOkGreenOn_RMASK 0x1 +#define QIB_6120_EXTCtrl_LEDGblErrRedOff_LSB 0x0 +#define QIB_6120_EXTCtrl_LEDGblErrRedOff_RMASK 0x1 + +#define QIB_6120_GPIOOut_OFFS 0xE0 + +#define QIB_6120_GPIOMask_OFFS 0xE8 + +#define QIB_6120_GPIOStatus_OFFS 0xF0 + +#define QIB_6120_GPIOClear_OFFS 0xF8 + +#define QIB_6120_RcvCtrl_OFFS 0x100 +#define QIB_6120_RcvCtrl_TailUpd_LSB 0x1F +#define QIB_6120_RcvCtrl_TailUpd_RMASK 0x1 +#define QIB_6120_RcvCtrl_RcvPartitionKeyDisable_LSB 0x1E +#define QIB_6120_RcvCtrl_RcvPartitionKeyDisable_RMASK 0x1 +#define QIB_6120_RcvCtrl_Reserved_LSB 0x15 +#define QIB_6120_RcvCtrl_Reserved_RMASK 0x1FF +#define QIB_6120_RcvCtrl_IntrAvail_LSB 0x10 +#define QIB_6120_RcvCtrl_IntrAvail_RMASK 0x1F +#define QIB_6120_RcvCtrl_Reserved1_LSB 0x9 +#define QIB_6120_RcvCtrl_Reserved1_RMASK 0x7F +#define QIB_6120_RcvCtrl_Reserved2_LSB 0x5 +#define QIB_6120_RcvCtrl_Reserved2_RMASK 0xF +#define QIB_6120_RcvCtrl_PortEnable_LSB 0x0 +#define QIB_6120_RcvCtrl_PortEnable_RMASK 0x1F + +#define QIB_6120_RcvBTHQP_OFFS 0x108 +#define QIB_6120_RcvBTHQP_BTHQP_Mask_LSB 0x1E +#define QIB_6120_RcvBTHQP_BTHQP_Mask_RMASK 0x3 +#define QIB_6120_RcvBTHQP_Reserved_LSB 0x18 +#define QIB_6120_RcvBTHQP_Reserved_RMASK 0x3F +#define QIB_6120_RcvBTHQP_RcvBTHQP_LSB 0x0 +#define QIB_6120_RcvBTHQP_RcvBTHQP_RMASK 0xFFFFFF + +#define QIB_6120_RcvHdrSize_OFFS 0x110 + +#define QIB_6120_RcvHdrCnt_OFFS 0x118 + +#define QIB_6120_RcvHdrEntSize_OFFS 0x120 + +#define QIB_6120_RcvTIDBase_OFFS 0x128 + +#define QIB_6120_RcvTIDCnt_OFFS 0x130 + +#define QIB_6120_RcvEgrBase_OFFS 0x138 + +#define QIB_6120_RcvEgrCnt_OFFS 0x140 + +#define QIB_6120_RcvBufBase_OFFS 0x148 + +#define QIB_6120_RcvBufSize_OFFS 0x150 + +#define QIB_6120_RxIntMemBase_OFFS 0x158 + +#define QIB_6120_RxIntMemSize_OFFS 0x160 + +#define QIB_6120_RcvPartitionKey_OFFS 0x168 + +#define QIB_6120_RcvPktLEDCnt_OFFS 0x178 +#define QIB_6120_RcvPktLEDCnt_ONperiod_LSB 0x20 +#define QIB_6120_RcvPktLEDCnt_ONperiod_RMASK 0xFFFFFFFF +#define QIB_6120_RcvPktLEDCnt_OFFperiod_LSB 0x0 +#define QIB_6120_RcvPktLEDCnt_OFFperiod_RMASK 0xFFFFFFFF + +#define QIB_6120_SendCtrl_OFFS 0x1C0 +#define QIB_6120_SendCtrl_Disarm_LSB 0x1F +#define QIB_6120_SendCtrl_Disarm_RMASK 0x1 +#define QIB_6120_SendCtrl_Reserved_LSB 0x17 +#define QIB_6120_SendCtrl_Reserved_RMASK 0xFF +#define QIB_6120_SendCtrl_DisarmPIOBuf_LSB 0x10 +#define QIB_6120_SendCtrl_DisarmPIOBuf_RMASK 0x7F +#define QIB_6120_SendCtrl_Reserved1_LSB 0x4 +#define QIB_6120_SendCtrl_Reserved1_RMASK 0xFFF +#define QIB_6120_SendCtrl_PIOEnable_LSB 0x3 +#define QIB_6120_SendCtrl_PIOEnable_RMASK 0x1 +#define QIB_6120_SendCtrl_PIOBufAvailUpd_LSB 0x2 +#define QIB_6120_SendCtrl_PIOBufAvailUpd_RMASK 0x1 +#define QIB_6120_SendCtrl_PIOIntBufAvail_LSB 0x1 +#define QIB_6120_SendCtrl_PIOIntBufAvail_RMASK 0x1 +#define QIB_6120_SendCtrl_Abort_LSB 0x0 +#define QIB_6120_SendCtrl_Abort_RMASK 0x1 + +#define QIB_6120_SendPIOBufBase_OFFS 0x1C8 +#define QIB_6120_SendPIOBufBase_Reserved_LSB 0x35 +#define QIB_6120_SendPIOBufBase_Reserved_RMASK 0x7FF +#define QIB_6120_SendPIOBufBase_BaseAddr_LargePIO_LSB 0x20 +#define QIB_6120_SendPIOBufBase_BaseAddr_LargePIO_RMASK 0x1FFFFF +#define QIB_6120_SendPIOBufBase_Reserved1_LSB 0x15 +#define QIB_6120_SendPIOBufBase_Reserved1_RMASK 0x7FF +#define QIB_6120_SendPIOBufBase_BaseAddr_SmallPIO_LSB 0x0 +#define QIB_6120_SendPIOBufBase_BaseAddr_SmallPIO_RMASK 0x1FFFFF + +#define QIB_6120_SendPIOSize_OFFS 0x1D0 +#define QIB_6120_SendPIOSize_Reserved_LSB 0x2D +#define QIB_6120_SendPIOSize_Reserved_RMASK 0xFFFFF +#define QIB_6120_SendPIOSize_Size_LargePIO_LSB 0x20 +#define QIB_6120_SendPIOSize_Size_LargePIO_RMASK 0x1FFF +#define QIB_6120_SendPIOSize_Reserved1_LSB 0xC +#define QIB_6120_SendPIOSize_Reserved1_RMASK 0xFFFFF +#define QIB_6120_SendPIOSize_Size_SmallPIO_LSB 0x0 +#define QIB_6120_SendPIOSize_Size_SmallPIO_RMASK 0xFFF + +#define QIB_6120_SendPIOBufCnt_OFFS 0x1D8 +#define QIB_6120_SendPIOBufCnt_Reserved_LSB 0x24 +#define QIB_6120_SendPIOBufCnt_Reserved_RMASK 0xFFFFFFF +#define QIB_6120_SendPIOBufCnt_Num_LargePIO_LSB 0x20 +#define QIB_6120_SendPIOBufCnt_Num_LargePIO_RMASK 0xF +#define QIB_6120_SendPIOBufCnt_Reserved1_LSB 0x9 +#define QIB_6120_SendPIOBufCnt_Reserved1_RMASK 0x7FFFFF +#define QIB_6120_SendPIOBufCnt_Num_SmallPIO_LSB 0x0 +#define QIB_6120_SendPIOBufCnt_Num_SmallPIO_RMASK 0x1FF + +#define QIB_6120_SendPIOAvailAddr_OFFS 0x1E0 +#define QIB_6120_SendPIOAvailAddr_SendPIOAvailAddr_LSB 0x6 +#define QIB_6120_SendPIOAvailAddr_SendPIOAvailAddr_RMASK 0x3FFFFFFFF +#define QIB_6120_SendPIOAvailAddr_Reserved_LSB 0x0 +#define QIB_6120_SendPIOAvailAddr_Reserved_RMASK 0x3F + +#define QIB_6120_SendBufErr0_OFFS 0x240 +#define QIB_6120_SendBufErr0_SendBufErrPIO_63_0_LSB 0x0 +#define QIB_6120_SendBufErr0_SendBufErrPIO_63_0_RMASK 0x0 + +#define QIB_6120_RcvHdrAddr0_OFFS 0x280 +#define QIB_6120_RcvHdrAddr0_RcvHdrAddr0_LSB 0x2 +#define QIB_6120_RcvHdrAddr0_RcvHdrAddr0_RMASK 0x3FFFFFFFFF +#define QIB_6120_RcvHdrAddr0_Reserved_LSB 0x0 +#define QIB_6120_RcvHdrAddr0_Reserved_RMASK 0x3 + +#define QIB_6120_RcvHdrTailAddr0_OFFS 0x300 +#define QIB_6120_RcvHdrTailAddr0_RcvHdrTailAddr0_LSB 0x2 +#define QIB_6120_RcvHdrTailAddr0_RcvHdrTailAddr0_RMASK 0x3FFFFFFFFF +#define QIB_6120_RcvHdrTailAddr0_Reserved_LSB 0x0 +#define QIB_6120_RcvHdrTailAddr0_Reserved_RMASK 0x3 + +#define QIB_6120_SerdesCfg0_OFFS 0x3C0 +#define QIB_6120_SerdesCfg0_DisableIBTxIdleDetect_LSB 0x3F +#define QIB_6120_SerdesCfg0_DisableIBTxIdleDetect_RMASK 0x1 +#define QIB_6120_SerdesCfg0_Reserved_LSB 0x38 +#define QIB_6120_SerdesCfg0_Reserved_RMASK 0x7F +#define QIB_6120_SerdesCfg0_RxEqCtl_LSB 0x36 +#define QIB_6120_SerdesCfg0_RxEqCtl_RMASK 0x3 +#define QIB_6120_SerdesCfg0_TxTermAdj_LSB 0x34 +#define QIB_6120_SerdesCfg0_TxTermAdj_RMASK 0x3 +#define QIB_6120_SerdesCfg0_RxTermAdj_LSB 0x32 +#define QIB_6120_SerdesCfg0_RxTermAdj_RMASK 0x3 +#define QIB_6120_SerdesCfg0_TermAdj1_LSB 0x31 +#define QIB_6120_SerdesCfg0_TermAdj1_RMASK 0x1 +#define QIB_6120_SerdesCfg0_TermAdj0_LSB 0x30 +#define QIB_6120_SerdesCfg0_TermAdj0_RMASK 0x1 +#define QIB_6120_SerdesCfg0_LPBKA_LSB 0x2F +#define QIB_6120_SerdesCfg0_LPBKA_RMASK 0x1 +#define QIB_6120_SerdesCfg0_LPBKB_LSB 0x2E +#define QIB_6120_SerdesCfg0_LPBKB_RMASK 0x1 +#define QIB_6120_SerdesCfg0_LPBKC_LSB 0x2D +#define QIB_6120_SerdesCfg0_LPBKC_RMASK 0x1 +#define QIB_6120_SerdesCfg0_LPBKD_LSB 0x2C +#define QIB_6120_SerdesCfg0_LPBKD_RMASK 0x1 +#define QIB_6120_SerdesCfg0_PW_LSB 0x2B +#define QIB_6120_SerdesCfg0_PW_RMASK 0x1 +#define QIB_6120_SerdesCfg0_RefSel_LSB 0x29 +#define QIB_6120_SerdesCfg0_RefSel_RMASK 0x3 +#define QIB_6120_SerdesCfg0_ParReset_LSB 0x28 +#define QIB_6120_SerdesCfg0_ParReset_RMASK 0x1 +#define QIB_6120_SerdesCfg0_ParLPBK_LSB 0x27 +#define QIB_6120_SerdesCfg0_ParLPBK_RMASK 0x1 +#define QIB_6120_SerdesCfg0_OffsetEn_LSB 0x26 +#define QIB_6120_SerdesCfg0_OffsetEn_RMASK 0x1 +#define QIB_6120_SerdesCfg0_Offset_LSB 0x1E +#define QIB_6120_SerdesCfg0_Offset_RMASK 0xFF +#define QIB_6120_SerdesCfg0_L2PwrDn_LSB 0x1D +#define QIB_6120_SerdesCfg0_L2PwrDn_RMASK 0x1 +#define QIB_6120_SerdesCfg0_ResetPLL_LSB 0x1C +#define QIB_6120_SerdesCfg0_ResetPLL_RMASK 0x1 +#define QIB_6120_SerdesCfg0_RxTermEnX_LSB 0x18 +#define QIB_6120_SerdesCfg0_RxTermEnX_RMASK 0xF +#define QIB_6120_SerdesCfg0_BeaconTxEnX_LSB 0x14 +#define QIB_6120_SerdesCfg0_BeaconTxEnX_RMASK 0xF +#define QIB_6120_SerdesCfg0_RxDetEnX_LSB 0x10 +#define QIB_6120_SerdesCfg0_RxDetEnX_RMASK 0xF +#define QIB_6120_SerdesCfg0_TxIdeEnX_LSB 0xC +#define QIB_6120_SerdesCfg0_TxIdeEnX_RMASK 0xF +#define QIB_6120_SerdesCfg0_RxIdleEnX_LSB 0x8 +#define QIB_6120_SerdesCfg0_RxIdleEnX_RMASK 0xF +#define QIB_6120_SerdesCfg0_L1PwrDnA_LSB 0x7 +#define QIB_6120_SerdesCfg0_L1PwrDnA_RMASK 0x1 +#define QIB_6120_SerdesCfg0_L1PwrDnB_LSB 0x6 +#define QIB_6120_SerdesCfg0_L1PwrDnB_RMASK 0x1 +#define QIB_6120_SerdesCfg0_L1PwrDnC_LSB 0x5 +#define QIB_6120_SerdesCfg0_L1PwrDnC_RMASK 0x1 +#define QIB_6120_SerdesCfg0_L1PwrDnD_LSB 0x4 +#define QIB_6120_SerdesCfg0_L1PwrDnD_RMASK 0x1 +#define QIB_6120_SerdesCfg0_ResetA_LSB 0x3 +#define QIB_6120_SerdesCfg0_ResetA_RMASK 0x1 +#define QIB_6120_SerdesCfg0_ResetB_LSB 0x2 +#define QIB_6120_SerdesCfg0_ResetB_RMASK 0x1 +#define QIB_6120_SerdesCfg0_ResetC_LSB 0x1 +#define QIB_6120_SerdesCfg0_ResetC_RMASK 0x1 +#define QIB_6120_SerdesCfg0_ResetD_LSB 0x0 +#define QIB_6120_SerdesCfg0_ResetD_RMASK 0x1 + +#define QIB_6120_SerdesStat_OFFS 0x3D0 +#define QIB_6120_SerdesStat_Reserved_LSB 0xC +#define QIB_6120_SerdesStat_Reserved_RMASK 0xFFFFFFFFFFFFF +#define QIB_6120_SerdesStat_BeaconDetA_LSB 0xB +#define QIB_6120_SerdesStat_BeaconDetA_RMASK 0x1 +#define QIB_6120_SerdesStat_BeaconDetB_LSB 0xA +#define QIB_6120_SerdesStat_BeaconDetB_RMASK 0x1 +#define QIB_6120_SerdesStat_BeaconDetC_LSB 0x9 +#define QIB_6120_SerdesStat_BeaconDetC_RMASK 0x1 +#define QIB_6120_SerdesStat_BeaconDetD_LSB 0x8 +#define QIB_6120_SerdesStat_BeaconDetD_RMASK 0x1 +#define QIB_6120_SerdesStat_RxDetA_LSB 0x7 +#define QIB_6120_SerdesStat_RxDetA_RMASK 0x1 +#define QIB_6120_SerdesStat_RxDetB_LSB 0x6 +#define QIB_6120_SerdesStat_RxDetB_RMASK 0x1 +#define QIB_6120_SerdesStat_RxDetC_LSB 0x5 +#define QIB_6120_SerdesStat_RxDetC_RMASK 0x1 +#define QIB_6120_SerdesStat_RxDetD_LSB 0x4 +#define QIB_6120_SerdesStat_RxDetD_RMASK 0x1 +#define QIB_6120_SerdesStat_TxIdleDetA_LSB 0x3 +#define QIB_6120_SerdesStat_TxIdleDetA_RMASK 0x1 +#define QIB_6120_SerdesStat_TxIdleDetB_LSB 0x2 +#define QIB_6120_SerdesStat_TxIdleDetB_RMASK 0x1 +#define QIB_6120_SerdesStat_TxIdleDetC_LSB 0x1 +#define QIB_6120_SerdesStat_TxIdleDetC_RMASK 0x1 +#define QIB_6120_SerdesStat_TxIdleDetD_LSB 0x0 +#define QIB_6120_SerdesStat_TxIdleDetD_RMASK 0x1 + +#define QIB_6120_XGXSCfg_OFFS 0x3D8 +#define QIB_6120_XGXSCfg_ArmLaunchErrorDisable_LSB 0x3F +#define QIB_6120_XGXSCfg_ArmLaunchErrorDisable_RMASK 0x1 +#define QIB_6120_XGXSCfg_Reserved_LSB 0x17 +#define QIB_6120_XGXSCfg_Reserved_RMASK 0xFFFFFFFFFF +#define QIB_6120_XGXSCfg_polarity_inv_LSB 0x13 +#define QIB_6120_XGXSCfg_polarity_inv_RMASK 0xF +#define QIB_6120_XGXSCfg_link_sync_mask_LSB 0x9 +#define QIB_6120_XGXSCfg_link_sync_mask_RMASK 0x3FF +#define QIB_6120_XGXSCfg_port_addr_LSB 0x4 +#define QIB_6120_XGXSCfg_port_addr_RMASK 0x1F +#define QIB_6120_XGXSCfg_mdd_30_LSB 0x3 +#define QIB_6120_XGXSCfg_mdd_30_RMASK 0x1 +#define QIB_6120_XGXSCfg_xcv_resetn_LSB 0x2 +#define QIB_6120_XGXSCfg_xcv_resetn_RMASK 0x1 +#define QIB_6120_XGXSCfg_Reserved1_LSB 0x1 +#define QIB_6120_XGXSCfg_Reserved1_RMASK 0x1 +#define QIB_6120_XGXSCfg_tx_rx_resetn_LSB 0x0 +#define QIB_6120_XGXSCfg_tx_rx_resetn_RMASK 0x1 + +#define QIB_6120_LBIntCnt_OFFS 0x12000 + +#define QIB_6120_LBFlowStallCnt_OFFS 0x12008 + +#define QIB_6120_TxUnsupVLErrCnt_OFFS 0x12018 + +#define QIB_6120_TxDataPktCnt_OFFS 0x12020 + +#define QIB_6120_TxFlowPktCnt_OFFS 0x12028 + +#define QIB_6120_TxDwordCnt_OFFS 0x12030 + +#define QIB_6120_TxLenErrCnt_OFFS 0x12038 + +#define QIB_6120_TxMaxMinLenErrCnt_OFFS 0x12040 + +#define QIB_6120_TxUnderrunCnt_OFFS 0x12048 + +#define QIB_6120_TxFlowStallCnt_OFFS 0x12050 + +#define QIB_6120_TxDroppedPktCnt_OFFS 0x12058 + +#define QIB_6120_RxDroppedPktCnt_OFFS 0x12060 + +#define QIB_6120_RxDataPktCnt_OFFS 0x12068 + +#define QIB_6120_RxFlowPktCnt_OFFS 0x12070 + +#define QIB_6120_RxDwordCnt_OFFS 0x12078 + +#define QIB_6120_RxLenErrCnt_OFFS 0x12080 + +#define QIB_6120_RxMaxMinLenErrCnt_OFFS 0x12088 + +#define QIB_6120_RxICRCErrCnt_OFFS 0x12090 + +#define QIB_6120_RxVCRCErrCnt_OFFS 0x12098 + +#define QIB_6120_RxFlowCtrlErrCnt_OFFS 0x120A0 + +#define QIB_6120_RxBadFormatCnt_OFFS 0x120A8 + +#define QIB_6120_RxLinkProblemCnt_OFFS 0x120B0 + +#define QIB_6120_RxEBPCnt_OFFS 0x120B8 + +#define QIB_6120_RxLPCRCErrCnt_OFFS 0x120C0 + +#define QIB_6120_RxBufOvflCnt_OFFS 0x120C8 + +#define QIB_6120_RxTIDFullErrCnt_OFFS 0x120D0 + +#define QIB_6120_RxTIDValidErrCnt_OFFS 0x120D8 + +#define QIB_6120_RxPKeyMismatchCnt_OFFS 0x120E0 + +#define QIB_6120_RxP0HdrEgrOvflCnt_OFFS 0x120E8 + +#define QIB_6120_IBStatusChangeCnt_OFFS 0x12140 + +#define QIB_6120_IBLinkErrRecoveryCnt_OFFS 0x12148 + +#define QIB_6120_IBLinkDownedCnt_OFFS 0x12150 + +#define QIB_6120_IBSymbolErrCnt_OFFS 0x12158 + +#define QIB_6120_PcieRetryBufDiagQwordCnt_OFFS 0x12170 + +#define QIB_6120_RcvEgrArray0_OFFS 0x14000 + +#define QIB_6120_RcvTIDArray0_OFFS 0x54000 + +#define QIB_6120_PIOLaunchFIFO_OFFS 0x64000 + +#define QIB_6120_SendPIOpbcCache_OFFS 0x64800 + +#define QIB_6120_RcvBuf1_OFFS 0x72000 + +#define QIB_6120_RcvBuf2_OFFS 0x75000 + +#define QIB_6120_RcvFlags_OFFS 0x77000 + +#define QIB_6120_RcvLookupBuf1_OFFS 0x79000 + +#define QIB_6120_RcvDMABuf_OFFS 0x7B000 + +#define QIB_6120_MiscRXEIntMem_OFFS 0x7C000 + +#define QIB_6120_PCIERcvBuf_OFFS 0x80000 + +#define QIB_6120_PCIERetryBuf_OFFS 0x82000 + +#define QIB_6120_PCIERcvBufRdToWrAddr_OFFS 0x84000 + +#define QIB_6120_PIOBuf0_MA_OFFS 0x100000 diff --git a/drivers/infiniband/hw/qib/qib_7220.h b/drivers/infiniband/hw/qib/qib_7220.h new file mode 100644 index 000000000000..ea0bfd896f92 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_7220.h @@ -0,0 +1,156 @@ +#ifndef _QIB_7220_H +#define _QIB_7220_H +/* + * Copyright (c) 2007, 2009, 2010 QLogic Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* grab register-defs auto-generated by HW */ +#include "qib_7220_regs.h" + +/* The number of eager receive TIDs for context zero. */ +#define IBA7220_KRCVEGRCNT 2048U + +#define IB_7220_LT_STATE_CFGRCVFCFG 0x09 +#define IB_7220_LT_STATE_CFGWAITRMT 0x0a +#define IB_7220_LT_STATE_TXREVLANES 0x0d +#define IB_7220_LT_STATE_CFGENH 0x10 + +struct qib_chip_specific { + u64 __iomem *cregbase; + u64 *cntrs; + u64 *portcntrs; + spinlock_t sdepb_lock; /* serdes EPB bus */ + spinlock_t rcvmod_lock; /* protect rcvctrl shadow changes */ + spinlock_t gpio_lock; /* RMW of shadows/regs for ExtCtrl and GPIO */ + u64 hwerrmask; + u64 errormask; + u64 gpio_out; /* shadow of kr_gpio_out, for rmw ops */ + u64 gpio_mask; /* shadow the gpio mask register */ + u64 extctrl; /* shadow the gpio output enable, etc... */ + u32 ncntrs; + u32 nportcntrs; + u32 cntrnamelen; + u32 portcntrnamelen; + u32 numctxts; + u32 rcvegrcnt; + u32 autoneg_tries; + u32 serdes_first_init_done; + u32 sdmabufcnt; + u32 lastbuf_for_pio; + u32 updthresh; /* current AvailUpdThld */ + u32 updthresh_dflt; /* default AvailUpdThld */ + int irq; + u8 presets_needed; + u8 relock_timer_active; + char emsgbuf[128]; + char sdmamsgbuf[192]; + char bitsmsgbuf[64]; + struct timer_list relock_timer; + unsigned int relock_interval; /* in jiffies */ +}; + +struct qib_chippport_specific { + struct qib_pportdata pportdata; + wait_queue_head_t autoneg_wait; + struct delayed_work autoneg_work; + struct timer_list chase_timer; + /* + * these 5 fields are used to establish deltas for IB symbol + * errors and linkrecovery errors. They can be reported on + * some chips during link negotiation prior to INIT, and with + * DDR when faking DDR negotiations with non-IBTA switches. + * The chip counters are adjusted at driver unload if there is + * a non-zero delta. + */ + u64 ibdeltainprog; + u64 ibsymdelta; + u64 ibsymsnap; + u64 iblnkerrdelta; + u64 iblnkerrsnap; + u64 ibcctrl; /* kr_ibcctrl shadow */ + u64 ibcddrctrl; /* kr_ibcddrctrl shadow */ + u64 chase_end; + u32 last_delay_mult; +}; + +/* + * This header file provides the declarations and common definitions + * for (mostly) manipulation of the SerDes blocks within the IBA7220. + * the functions declared should only be called from within other + * 7220-related files such as qib_iba7220.c or qib_sd7220.c. + */ +int qib_sd7220_presets(struct qib_devdata *dd); +int qib_sd7220_init(struct qib_devdata *dd); +int qib_sd7220_prog_ld(struct qib_devdata *dd, int sdnum, u8 *img, + int len, int offset); +int qib_sd7220_prog_vfy(struct qib_devdata *dd, int sdnum, const u8 *img, + int len, int offset); +void qib_sd7220_clr_ibpar(struct qib_devdata *); +/* + * Below used for sdnum parameter, selecting one of the two sections + * used for PCIe, or the single SerDes used for IB, which is the + * only one currently used + */ +#define IB_7220_SERDES 2 + +int qib_sd7220_ib_load(struct qib_devdata *dd); +int qib_sd7220_ib_vfy(struct qib_devdata *dd); + +static inline u32 qib_read_kreg32(const struct qib_devdata *dd, + const u16 regno) +{ + if (!dd->kregbase || !(dd->flags & QIB_PRESENT)) + return -1; + return readl((u32 __iomem *)&dd->kregbase[regno]); +} + +static inline u64 qib_read_kreg64(const struct qib_devdata *dd, + const u16 regno) +{ + if (!dd->kregbase || !(dd->flags & QIB_PRESENT)) + return -1; + + return readq(&dd->kregbase[regno]); +} + +static inline void qib_write_kreg(const struct qib_devdata *dd, + const u16 regno, u64 value) +{ + if (dd->kregbase) + writeq(value, &dd->kregbase[regno]); +} + +void set_7220_relock_poll(struct qib_devdata *, int); +void shutdown_7220_relock_poll(struct qib_devdata *); +void toggle_7220_rclkrls(struct qib_devdata *); + + +#endif /* _QIB_7220_H */ diff --git a/drivers/infiniband/hw/qib/qib_7220_regs.h b/drivers/infiniband/hw/qib/qib_7220_regs.h new file mode 100644 index 000000000000..0da5bb750e52 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_7220_regs.h @@ -0,0 +1,1496 @@ +/* + * Copyright (c) 2008, 2009, 2010 QLogic Corporation. All rights reserved. + * + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +/* This file is mechanically generated from RTL. Any hand-edits will be lost! */ + +#define QIB_7220_Revision_OFFS 0x0 +#define QIB_7220_Revision_R_Simulator_LSB 0x3F +#define QIB_7220_Revision_R_Simulator_RMASK 0x1 +#define QIB_7220_Revision_R_Emulation_LSB 0x3E +#define QIB_7220_Revision_R_Emulation_RMASK 0x1 +#define QIB_7220_Revision_R_Emulation_Revcode_LSB 0x28 +#define QIB_7220_Revision_R_Emulation_Revcode_RMASK 0x3FFFFF +#define QIB_7220_Revision_BoardID_LSB 0x20 +#define QIB_7220_Revision_BoardID_RMASK 0xFF +#define QIB_7220_Revision_R_SW_LSB 0x18 +#define QIB_7220_Revision_R_SW_RMASK 0xFF +#define QIB_7220_Revision_R_Arch_LSB 0x10 +#define QIB_7220_Revision_R_Arch_RMASK 0xFF +#define QIB_7220_Revision_R_ChipRevMajor_LSB 0x8 +#define QIB_7220_Revision_R_ChipRevMajor_RMASK 0xFF +#define QIB_7220_Revision_R_ChipRevMinor_LSB 0x0 +#define QIB_7220_Revision_R_ChipRevMinor_RMASK 0xFF + +#define QIB_7220_Control_OFFS 0x8 +#define QIB_7220_Control_SyncResetExceptPcieIRAMRST_LSB 0x7 +#define QIB_7220_Control_SyncResetExceptPcieIRAMRST_RMASK 0x1 +#define QIB_7220_Control_PCIECplQDiagEn_LSB 0x6 +#define QIB_7220_Control_PCIECplQDiagEn_RMASK 0x1 +#define QIB_7220_Control_Reserved_LSB 0x5 +#define QIB_7220_Control_Reserved_RMASK 0x1 +#define QIB_7220_Control_TxLatency_LSB 0x4 +#define QIB_7220_Control_TxLatency_RMASK 0x1 +#define QIB_7220_Control_PCIERetryBufDiagEn_LSB 0x3 +#define QIB_7220_Control_PCIERetryBufDiagEn_RMASK 0x1 +#define QIB_7220_Control_LinkEn_LSB 0x2 +#define QIB_7220_Control_LinkEn_RMASK 0x1 +#define QIB_7220_Control_FreezeMode_LSB 0x1 +#define QIB_7220_Control_FreezeMode_RMASK 0x1 +#define QIB_7220_Control_SyncReset_LSB 0x0 +#define QIB_7220_Control_SyncReset_RMASK 0x1 + +#define QIB_7220_PageAlign_OFFS 0x10 + +#define QIB_7220_PortCnt_OFFS 0x18 + +#define QIB_7220_SendRegBase_OFFS 0x30 + +#define QIB_7220_UserRegBase_OFFS 0x38 + +#define QIB_7220_CntrRegBase_OFFS 0x40 + +#define QIB_7220_Scratch_OFFS 0x48 + +#define QIB_7220_IntMask_OFFS 0x68 +#define QIB_7220_IntMask_SDmaIntMask_LSB 0x3F +#define QIB_7220_IntMask_SDmaIntMask_RMASK 0x1 +#define QIB_7220_IntMask_SDmaDisabledMasked_LSB 0x3E +#define QIB_7220_IntMask_SDmaDisabledMasked_RMASK 0x1 +#define QIB_7220_IntMask_Reserved_LSB 0x31 +#define QIB_7220_IntMask_Reserved_RMASK 0x1FFF +#define QIB_7220_IntMask_RcvUrg16IntMask_LSB 0x30 +#define QIB_7220_IntMask_RcvUrg16IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvUrg15IntMask_LSB 0x2F +#define QIB_7220_IntMask_RcvUrg15IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvUrg14IntMask_LSB 0x2E +#define QIB_7220_IntMask_RcvUrg14IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvUrg13IntMask_LSB 0x2D +#define QIB_7220_IntMask_RcvUrg13IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvUrg12IntMask_LSB 0x2C +#define QIB_7220_IntMask_RcvUrg12IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvUrg11IntMask_LSB 0x2B +#define QIB_7220_IntMask_RcvUrg11IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvUrg10IntMask_LSB 0x2A +#define QIB_7220_IntMask_RcvUrg10IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvUrg9IntMask_LSB 0x29 +#define QIB_7220_IntMask_RcvUrg9IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvUrg8IntMask_LSB 0x28 +#define QIB_7220_IntMask_RcvUrg8IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvUrg7IntMask_LSB 0x27 +#define QIB_7220_IntMask_RcvUrg7IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvUrg6IntMask_LSB 0x26 +#define QIB_7220_IntMask_RcvUrg6IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvUrg5IntMask_LSB 0x25 +#define QIB_7220_IntMask_RcvUrg5IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvUrg4IntMask_LSB 0x24 +#define QIB_7220_IntMask_RcvUrg4IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvUrg3IntMask_LSB 0x23 +#define QIB_7220_IntMask_RcvUrg3IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvUrg2IntMask_LSB 0x22 +#define QIB_7220_IntMask_RcvUrg2IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvUrg1IntMask_LSB 0x21 +#define QIB_7220_IntMask_RcvUrg1IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvUrg0IntMask_LSB 0x20 +#define QIB_7220_IntMask_RcvUrg0IntMask_RMASK 0x1 +#define QIB_7220_IntMask_ErrorIntMask_LSB 0x1F +#define QIB_7220_IntMask_ErrorIntMask_RMASK 0x1 +#define QIB_7220_IntMask_PioSetIntMask_LSB 0x1E +#define QIB_7220_IntMask_PioSetIntMask_RMASK 0x1 +#define QIB_7220_IntMask_PioBufAvailIntMask_LSB 0x1D +#define QIB_7220_IntMask_PioBufAvailIntMask_RMASK 0x1 +#define QIB_7220_IntMask_assertGPIOIntMask_LSB 0x1C +#define QIB_7220_IntMask_assertGPIOIntMask_RMASK 0x1 +#define QIB_7220_IntMask_IBSerdesTrimDoneIntMask_LSB 0x1B +#define QIB_7220_IntMask_IBSerdesTrimDoneIntMask_RMASK 0x1 +#define QIB_7220_IntMask_JIntMask_LSB 0x1A +#define QIB_7220_IntMask_JIntMask_RMASK 0x1 +#define QIB_7220_IntMask_Reserved1_LSB 0x11 +#define QIB_7220_IntMask_Reserved1_RMASK 0x1FF +#define QIB_7220_IntMask_RcvAvail16IntMask_LSB 0x10 +#define QIB_7220_IntMask_RcvAvail16IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvAvail15IntMask_LSB 0xF +#define QIB_7220_IntMask_RcvAvail15IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvAvail14IntMask_LSB 0xE +#define QIB_7220_IntMask_RcvAvail14IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvAvail13IntMask_LSB 0xD +#define QIB_7220_IntMask_RcvAvail13IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvAvail12IntMask_LSB 0xC +#define QIB_7220_IntMask_RcvAvail12IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvAvail11IntMask_LSB 0xB +#define QIB_7220_IntMask_RcvAvail11IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvAvail10IntMask_LSB 0xA +#define QIB_7220_IntMask_RcvAvail10IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvAvail9IntMask_LSB 0x9 +#define QIB_7220_IntMask_RcvAvail9IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvAvail8IntMask_LSB 0x8 +#define QIB_7220_IntMask_RcvAvail8IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvAvail7IntMask_LSB 0x7 +#define QIB_7220_IntMask_RcvAvail7IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvAvail6IntMask_LSB 0x6 +#define QIB_7220_IntMask_RcvAvail6IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvAvail5IntMask_LSB 0x5 +#define QIB_7220_IntMask_RcvAvail5IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvAvail4IntMask_LSB 0x4 +#define QIB_7220_IntMask_RcvAvail4IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvAvail3IntMask_LSB 0x3 +#define QIB_7220_IntMask_RcvAvail3IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvAvail2IntMask_LSB 0x2 +#define QIB_7220_IntMask_RcvAvail2IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvAvail1IntMask_LSB 0x1 +#define QIB_7220_IntMask_RcvAvail1IntMask_RMASK 0x1 +#define QIB_7220_IntMask_RcvAvail0IntMask_LSB 0x0 +#define QIB_7220_IntMask_RcvAvail0IntMask_RMASK 0x1 + +#define QIB_7220_IntStatus_OFFS 0x70 +#define QIB_7220_IntStatus_SDmaInt_LSB 0x3F +#define QIB_7220_IntStatus_SDmaInt_RMASK 0x1 +#define QIB_7220_IntStatus_SDmaDisabled_LSB 0x3E +#define QIB_7220_IntStatus_SDmaDisabled_RMASK 0x1 +#define QIB_7220_IntStatus_Reserved_LSB 0x31 +#define QIB_7220_IntStatus_Reserved_RMASK 0x1FFF +#define QIB_7220_IntStatus_RcvUrg16_LSB 0x30 +#define QIB_7220_IntStatus_RcvUrg16_RMASK 0x1 +#define QIB_7220_IntStatus_RcvUrg15_LSB 0x2F +#define QIB_7220_IntStatus_RcvUrg15_RMASK 0x1 +#define QIB_7220_IntStatus_RcvUrg14_LSB 0x2E +#define QIB_7220_IntStatus_RcvUrg14_RMASK 0x1 +#define QIB_7220_IntStatus_RcvUrg13_LSB 0x2D +#define QIB_7220_IntStatus_RcvUrg13_RMASK 0x1 +#define QIB_7220_IntStatus_RcvUrg12_LSB 0x2C +#define QIB_7220_IntStatus_RcvUrg12_RMASK 0x1 +#define QIB_7220_IntStatus_RcvUrg11_LSB 0x2B +#define QIB_7220_IntStatus_RcvUrg11_RMASK 0x1 +#define QIB_7220_IntStatus_RcvUrg10_LSB 0x2A +#define QIB_7220_IntStatus_RcvUrg10_RMASK 0x1 +#define QIB_7220_IntStatus_RcvUrg9_LSB 0x29 +#define QIB_7220_IntStatus_RcvUrg9_RMASK 0x1 +#define QIB_7220_IntStatus_RcvUrg8_LSB 0x28 +#define QIB_7220_IntStatus_RcvUrg8_RMASK 0x1 +#define QIB_7220_IntStatus_RcvUrg7_LSB 0x27 +#define QIB_7220_IntStatus_RcvUrg7_RMASK 0x1 +#define QIB_7220_IntStatus_RcvUrg6_LSB 0x26 +#define QIB_7220_IntStatus_RcvUrg6_RMASK 0x1 +#define QIB_7220_IntStatus_RcvUrg5_LSB 0x25 +#define QIB_7220_IntStatus_RcvUrg5_RMASK 0x1 +#define QIB_7220_IntStatus_RcvUrg4_LSB 0x24 +#define QIB_7220_IntStatus_RcvUrg4_RMASK 0x1 +#define QIB_7220_IntStatus_RcvUrg3_LSB 0x23 +#define QIB_7220_IntStatus_RcvUrg3_RMASK 0x1 +#define QIB_7220_IntStatus_RcvUrg2_LSB 0x22 +#define QIB_7220_IntStatus_RcvUrg2_RMASK 0x1 +#define QIB_7220_IntStatus_RcvUrg1_LSB 0x21 +#define QIB_7220_IntStatus_RcvUrg1_RMASK 0x1 +#define QIB_7220_IntStatus_RcvUrg0_LSB 0x20 +#define QIB_7220_IntStatus_RcvUrg0_RMASK 0x1 +#define QIB_7220_IntStatus_Error_LSB 0x1F +#define QIB_7220_IntStatus_Error_RMASK 0x1 +#define QIB_7220_IntStatus_PioSent_LSB 0x1E +#define QIB_7220_IntStatus_PioSent_RMASK 0x1 +#define QIB_7220_IntStatus_PioBufAvail_LSB 0x1D +#define QIB_7220_IntStatus_PioBufAvail_RMASK 0x1 +#define QIB_7220_IntStatus_assertGPIO_LSB 0x1C +#define QIB_7220_IntStatus_assertGPIO_RMASK 0x1 +#define QIB_7220_IntStatus_IBSerdesTrimDone_LSB 0x1B +#define QIB_7220_IntStatus_IBSerdesTrimDone_RMASK 0x1 +#define QIB_7220_IntStatus_JInt_LSB 0x1A +#define QIB_7220_IntStatus_JInt_RMASK 0x1 +#define QIB_7220_IntStatus_Reserved1_LSB 0x11 +#define QIB_7220_IntStatus_Reserved1_RMASK 0x1FF +#define QIB_7220_IntStatus_RcvAvail16_LSB 0x10 +#define QIB_7220_IntStatus_RcvAvail16_RMASK 0x1 +#define QIB_7220_IntStatus_RcvAvail15_LSB 0xF +#define QIB_7220_IntStatus_RcvAvail15_RMASK 0x1 +#define QIB_7220_IntStatus_RcvAvail14_LSB 0xE +#define QIB_7220_IntStatus_RcvAvail14_RMASK 0x1 +#define QIB_7220_IntStatus_RcvAvail13_LSB 0xD +#define QIB_7220_IntStatus_RcvAvail13_RMASK 0x1 +#define QIB_7220_IntStatus_RcvAvail12_LSB 0xC +#define QIB_7220_IntStatus_RcvAvail12_RMASK 0x1 +#define QIB_7220_IntStatus_RcvAvail11_LSB 0xB +#define QIB_7220_IntStatus_RcvAvail11_RMASK 0x1 +#define QIB_7220_IntStatus_RcvAvail10_LSB 0xA +#define QIB_7220_IntStatus_RcvAvail10_RMASK 0x1 +#define QIB_7220_IntStatus_RcvAvail9_LSB 0x9 +#define QIB_7220_IntStatus_RcvAvail9_RMASK 0x1 +#define QIB_7220_IntStatus_RcvAvail8_LSB 0x8 +#define QIB_7220_IntStatus_RcvAvail8_RMASK 0x1 +#define QIB_7220_IntStatus_RcvAvail7_LSB 0x7 +#define QIB_7220_IntStatus_RcvAvail7_RMASK 0x1 +#define QIB_7220_IntStatus_RcvAvail6_LSB 0x6 +#define QIB_7220_IntStatus_RcvAvail6_RMASK 0x1 +#define QIB_7220_IntStatus_RcvAvail5_LSB 0x5 +#define QIB_7220_IntStatus_RcvAvail5_RMASK 0x1 +#define QIB_7220_IntStatus_RcvAvail4_LSB 0x4 +#define QIB_7220_IntStatus_RcvAvail4_RMASK 0x1 +#define QIB_7220_IntStatus_RcvAvail3_LSB 0x3 +#define QIB_7220_IntStatus_RcvAvail3_RMASK 0x1 +#define QIB_7220_IntStatus_RcvAvail2_LSB 0x2 +#define QIB_7220_IntStatus_RcvAvail2_RMASK 0x1 +#define QIB_7220_IntStatus_RcvAvail1_LSB 0x1 +#define QIB_7220_IntStatus_RcvAvail1_RMASK 0x1 +#define QIB_7220_IntStatus_RcvAvail0_LSB 0x0 +#define QIB_7220_IntStatus_RcvAvail0_RMASK 0x1 + +#define QIB_7220_IntClear_OFFS 0x78 +#define QIB_7220_IntClear_SDmaIntClear_LSB 0x3F +#define QIB_7220_IntClear_SDmaIntClear_RMASK 0x1 +#define QIB_7220_IntClear_SDmaDisabledClear_LSB 0x3E +#define QIB_7220_IntClear_SDmaDisabledClear_RMASK 0x1 +#define QIB_7220_IntClear_Reserved_LSB 0x31 +#define QIB_7220_IntClear_Reserved_RMASK 0x1FFF +#define QIB_7220_IntClear_RcvUrg16IntClear_LSB 0x30 +#define QIB_7220_IntClear_RcvUrg16IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvUrg15IntClear_LSB 0x2F +#define QIB_7220_IntClear_RcvUrg15IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvUrg14IntClear_LSB 0x2E +#define QIB_7220_IntClear_RcvUrg14IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvUrg13IntClear_LSB 0x2D +#define QIB_7220_IntClear_RcvUrg13IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvUrg12IntClear_LSB 0x2C +#define QIB_7220_IntClear_RcvUrg12IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvUrg11IntClear_LSB 0x2B +#define QIB_7220_IntClear_RcvUrg11IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvUrg10IntClear_LSB 0x2A +#define QIB_7220_IntClear_RcvUrg10IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvUrg9IntClear_LSB 0x29 +#define QIB_7220_IntClear_RcvUrg9IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvUrg8IntClear_LSB 0x28 +#define QIB_7220_IntClear_RcvUrg8IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvUrg7IntClear_LSB 0x27 +#define QIB_7220_IntClear_RcvUrg7IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvUrg6IntClear_LSB 0x26 +#define QIB_7220_IntClear_RcvUrg6IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvUrg5IntClear_LSB 0x25 +#define QIB_7220_IntClear_RcvUrg5IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvUrg4IntClear_LSB 0x24 +#define QIB_7220_IntClear_RcvUrg4IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvUrg3IntClear_LSB 0x23 +#define QIB_7220_IntClear_RcvUrg3IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvUrg2IntClear_LSB 0x22 +#define QIB_7220_IntClear_RcvUrg2IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvUrg1IntClear_LSB 0x21 +#define QIB_7220_IntClear_RcvUrg1IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvUrg0IntClear_LSB 0x20 +#define QIB_7220_IntClear_RcvUrg0IntClear_RMASK 0x1 +#define QIB_7220_IntClear_ErrorIntClear_LSB 0x1F +#define QIB_7220_IntClear_ErrorIntClear_RMASK 0x1 +#define QIB_7220_IntClear_PioSetIntClear_LSB 0x1E +#define QIB_7220_IntClear_PioSetIntClear_RMASK 0x1 +#define QIB_7220_IntClear_PioBufAvailIntClear_LSB 0x1D +#define QIB_7220_IntClear_PioBufAvailIntClear_RMASK 0x1 +#define QIB_7220_IntClear_assertGPIOIntClear_LSB 0x1C +#define QIB_7220_IntClear_assertGPIOIntClear_RMASK 0x1 +#define QIB_7220_IntClear_IBSerdesTrimDoneClear_LSB 0x1B +#define QIB_7220_IntClear_IBSerdesTrimDoneClear_RMASK 0x1 +#define QIB_7220_IntClear_JIntClear_LSB 0x1A +#define QIB_7220_IntClear_JIntClear_RMASK 0x1 +#define QIB_7220_IntClear_Reserved1_LSB 0x11 +#define QIB_7220_IntClear_Reserved1_RMASK 0x1FF +#define QIB_7220_IntClear_RcvAvail16IntClear_LSB 0x10 +#define QIB_7220_IntClear_RcvAvail16IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvAvail15IntClear_LSB 0xF +#define QIB_7220_IntClear_RcvAvail15IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvAvail14IntClear_LSB 0xE +#define QIB_7220_IntClear_RcvAvail14IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvAvail13IntClear_LSB 0xD +#define QIB_7220_IntClear_RcvAvail13IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvAvail12IntClear_LSB 0xC +#define QIB_7220_IntClear_RcvAvail12IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvAvail11IntClear_LSB 0xB +#define QIB_7220_IntClear_RcvAvail11IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvAvail10IntClear_LSB 0xA +#define QIB_7220_IntClear_RcvAvail10IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvAvail9IntClear_LSB 0x9 +#define QIB_7220_IntClear_RcvAvail9IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvAvail8IntClear_LSB 0x8 +#define QIB_7220_IntClear_RcvAvail8IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvAvail7IntClear_LSB 0x7 +#define QIB_7220_IntClear_RcvAvail7IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvAvail6IntClear_LSB 0x6 +#define QIB_7220_IntClear_RcvAvail6IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvAvail5IntClear_LSB 0x5 +#define QIB_7220_IntClear_RcvAvail5IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvAvail4IntClear_LSB 0x4 +#define QIB_7220_IntClear_RcvAvail4IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvAvail3IntClear_LSB 0x3 +#define QIB_7220_IntClear_RcvAvail3IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvAvail2IntClear_LSB 0x2 +#define QIB_7220_IntClear_RcvAvail2IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvAvail1IntClear_LSB 0x1 +#define QIB_7220_IntClear_RcvAvail1IntClear_RMASK 0x1 +#define QIB_7220_IntClear_RcvAvail0IntClear_LSB 0x0 +#define QIB_7220_IntClear_RcvAvail0IntClear_RMASK 0x1 + +#define QIB_7220_ErrMask_OFFS 0x80 +#define QIB_7220_ErrMask_Reserved_LSB 0x36 +#define QIB_7220_ErrMask_Reserved_RMASK 0x3FF +#define QIB_7220_ErrMask_InvalidEEPCmdMask_LSB 0x35 +#define QIB_7220_ErrMask_InvalidEEPCmdMask_RMASK 0x1 +#define QIB_7220_ErrMask_SDmaDescAddrMisalignErrMask_LSB 0x34 +#define QIB_7220_ErrMask_SDmaDescAddrMisalignErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_HardwareErrMask_LSB 0x33 +#define QIB_7220_ErrMask_HardwareErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_ResetNegatedMask_LSB 0x32 +#define QIB_7220_ErrMask_ResetNegatedMask_RMASK 0x1 +#define QIB_7220_ErrMask_InvalidAddrErrMask_LSB 0x31 +#define QIB_7220_ErrMask_InvalidAddrErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_IBStatusChangedMask_LSB 0x30 +#define QIB_7220_ErrMask_IBStatusChangedMask_RMASK 0x1 +#define QIB_7220_ErrMask_SDmaUnexpDataErrMask_LSB 0x2F +#define QIB_7220_ErrMask_SDmaUnexpDataErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_SDmaMissingDwErrMask_LSB 0x2E +#define QIB_7220_ErrMask_SDmaMissingDwErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_SDmaDwEnErrMask_LSB 0x2D +#define QIB_7220_ErrMask_SDmaDwEnErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_SDmaRpyTagErrMask_LSB 0x2C +#define QIB_7220_ErrMask_SDmaRpyTagErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_SDma1stDescErrMask_LSB 0x2B +#define QIB_7220_ErrMask_SDma1stDescErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_SDmaBaseErrMask_LSB 0x2A +#define QIB_7220_ErrMask_SDmaBaseErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_SDmaTailOutOfBoundErrMask_LSB 0x29 +#define QIB_7220_ErrMask_SDmaTailOutOfBoundErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_SDmaOutOfBoundErrMask_LSB 0x28 +#define QIB_7220_ErrMask_SDmaOutOfBoundErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_SDmaGenMismatchErrMask_LSB 0x27 +#define QIB_7220_ErrMask_SDmaGenMismatchErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_SendBufMisuseErrMask_LSB 0x26 +#define QIB_7220_ErrMask_SendBufMisuseErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_SendUnsupportedVLErrMask_LSB 0x25 +#define QIB_7220_ErrMask_SendUnsupportedVLErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_SendUnexpectedPktNumErrMask_LSB 0x24 +#define QIB_7220_ErrMask_SendUnexpectedPktNumErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_SendPioArmLaunchErrMask_LSB 0x23 +#define QIB_7220_ErrMask_SendPioArmLaunchErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_SendDroppedDataPktErrMask_LSB 0x22 +#define QIB_7220_ErrMask_SendDroppedDataPktErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_SendDroppedSmpPktErrMask_LSB 0x21 +#define QIB_7220_ErrMask_SendDroppedSmpPktErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_SendPktLenErrMask_LSB 0x20 +#define QIB_7220_ErrMask_SendPktLenErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_SendUnderRunErrMask_LSB 0x1F +#define QIB_7220_ErrMask_SendUnderRunErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_SendMaxPktLenErrMask_LSB 0x1E +#define QIB_7220_ErrMask_SendMaxPktLenErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_SendMinPktLenErrMask_LSB 0x1D +#define QIB_7220_ErrMask_SendMinPktLenErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_SDmaDisabledErrMask_LSB 0x1C +#define QIB_7220_ErrMask_SDmaDisabledErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_SendSpecialTriggerErrMask_LSB 0x1B +#define QIB_7220_ErrMask_SendSpecialTriggerErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_Reserved1_LSB 0x12 +#define QIB_7220_ErrMask_Reserved1_RMASK 0x1FF +#define QIB_7220_ErrMask_RcvIBLostLinkErrMask_LSB 0x11 +#define QIB_7220_ErrMask_RcvIBLostLinkErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_RcvHdrErrMask_LSB 0x10 +#define QIB_7220_ErrMask_RcvHdrErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_RcvHdrLenErrMask_LSB 0xF +#define QIB_7220_ErrMask_RcvHdrLenErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_RcvBadTidErrMask_LSB 0xE +#define QIB_7220_ErrMask_RcvBadTidErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_RcvHdrFullErrMask_LSB 0xD +#define QIB_7220_ErrMask_RcvHdrFullErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_RcvEgrFullErrMask_LSB 0xC +#define QIB_7220_ErrMask_RcvEgrFullErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_RcvBadVersionErrMask_LSB 0xB +#define QIB_7220_ErrMask_RcvBadVersionErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_RcvIBFlowErrMask_LSB 0xA +#define QIB_7220_ErrMask_RcvIBFlowErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_RcvEBPErrMask_LSB 0x9 +#define QIB_7220_ErrMask_RcvEBPErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_RcvUnsupportedVLErrMask_LSB 0x8 +#define QIB_7220_ErrMask_RcvUnsupportedVLErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_RcvUnexpectedCharErrMask_LSB 0x7 +#define QIB_7220_ErrMask_RcvUnexpectedCharErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_RcvShortPktLenErrMask_LSB 0x6 +#define QIB_7220_ErrMask_RcvShortPktLenErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_RcvLongPktLenErrMask_LSB 0x5 +#define QIB_7220_ErrMask_RcvLongPktLenErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_RcvMaxPktLenErrMask_LSB 0x4 +#define QIB_7220_ErrMask_RcvMaxPktLenErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_RcvMinPktLenErrMask_LSB 0x3 +#define QIB_7220_ErrMask_RcvMinPktLenErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_RcvICRCErrMask_LSB 0x2 +#define QIB_7220_ErrMask_RcvICRCErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_RcvVCRCErrMask_LSB 0x1 +#define QIB_7220_ErrMask_RcvVCRCErrMask_RMASK 0x1 +#define QIB_7220_ErrMask_RcvFormatErrMask_LSB 0x0 +#define QIB_7220_ErrMask_RcvFormatErrMask_RMASK 0x1 + +#define QIB_7220_ErrStatus_OFFS 0x88 +#define QIB_7220_ErrStatus_Reserved_LSB 0x36 +#define QIB_7220_ErrStatus_Reserved_RMASK 0x3FF +#define QIB_7220_ErrStatus_InvalidEEPCmdErr_LSB 0x35 +#define QIB_7220_ErrStatus_InvalidEEPCmdErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SDmaDescAddrMisalignErr_LSB 0x34 +#define QIB_7220_ErrStatus_SDmaDescAddrMisalignErr_RMASK 0x1 +#define QIB_7220_ErrStatus_HardwareErr_LSB 0x33 +#define QIB_7220_ErrStatus_HardwareErr_RMASK 0x1 +#define QIB_7220_ErrStatus_ResetNegated_LSB 0x32 +#define QIB_7220_ErrStatus_ResetNegated_RMASK 0x1 +#define QIB_7220_ErrStatus_InvalidAddrErr_LSB 0x31 +#define QIB_7220_ErrStatus_InvalidAddrErr_RMASK 0x1 +#define QIB_7220_ErrStatus_IBStatusChanged_LSB 0x30 +#define QIB_7220_ErrStatus_IBStatusChanged_RMASK 0x1 +#define QIB_7220_ErrStatus_SDmaUnexpDataErr_LSB 0x2F +#define QIB_7220_ErrStatus_SDmaUnexpDataErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SDmaMissingDwErr_LSB 0x2E +#define QIB_7220_ErrStatus_SDmaMissingDwErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SDmaDwEnErr_LSB 0x2D +#define QIB_7220_ErrStatus_SDmaDwEnErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SDmaRpyTagErr_LSB 0x2C +#define QIB_7220_ErrStatus_SDmaRpyTagErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SDma1stDescErr_LSB 0x2B +#define QIB_7220_ErrStatus_SDma1stDescErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SDmaBaseErr_LSB 0x2A +#define QIB_7220_ErrStatus_SDmaBaseErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SDmaTailOutOfBoundErr_LSB 0x29 +#define QIB_7220_ErrStatus_SDmaTailOutOfBoundErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SDmaOutOfBoundErr_LSB 0x28 +#define QIB_7220_ErrStatus_SDmaOutOfBoundErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SDmaGenMismatchErr_LSB 0x27 +#define QIB_7220_ErrStatus_SDmaGenMismatchErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SendBufMisuseErr_LSB 0x26 +#define QIB_7220_ErrStatus_SendBufMisuseErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SendUnsupportedVLErr_LSB 0x25 +#define QIB_7220_ErrStatus_SendUnsupportedVLErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SendUnexpectedPktNumErr_LSB 0x24 +#define QIB_7220_ErrStatus_SendUnexpectedPktNumErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SendPioArmLaunchErr_LSB 0x23 +#define QIB_7220_ErrStatus_SendPioArmLaunchErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SendDroppedDataPktErr_LSB 0x22 +#define QIB_7220_ErrStatus_SendDroppedDataPktErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SendDroppedSmpPktErr_LSB 0x21 +#define QIB_7220_ErrStatus_SendDroppedSmpPktErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SendPktLenErr_LSB 0x20 +#define QIB_7220_ErrStatus_SendPktLenErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SendUnderRunErr_LSB 0x1F +#define QIB_7220_ErrStatus_SendUnderRunErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SendMaxPktLenErr_LSB 0x1E +#define QIB_7220_ErrStatus_SendMaxPktLenErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SendMinPktLenErr_LSB 0x1D +#define QIB_7220_ErrStatus_SendMinPktLenErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SDmaDisabledErr_LSB 0x1C +#define QIB_7220_ErrStatus_SDmaDisabledErr_RMASK 0x1 +#define QIB_7220_ErrStatus_SendSpecialTriggerErr_LSB 0x1B +#define QIB_7220_ErrStatus_SendSpecialTriggerErr_RMASK 0x1 +#define QIB_7220_ErrStatus_Reserved1_LSB 0x12 +#define QIB_7220_ErrStatus_Reserved1_RMASK 0x1FF +#define QIB_7220_ErrStatus_RcvIBLostLinkErr_LSB 0x11 +#define QIB_7220_ErrStatus_RcvIBLostLinkErr_RMASK 0x1 +#define QIB_7220_ErrStatus_RcvHdrErr_LSB 0x10 +#define QIB_7220_ErrStatus_RcvHdrErr_RMASK 0x1 +#define QIB_7220_ErrStatus_RcvHdrLenErr_LSB 0xF +#define QIB_7220_ErrStatus_RcvHdrLenErr_RMASK 0x1 +#define QIB_7220_ErrStatus_RcvBadTidErr_LSB 0xE +#define QIB_7220_ErrStatus_RcvBadTidErr_RMASK 0x1 +#define QIB_7220_ErrStatus_RcvHdrFullErr_LSB 0xD +#define QIB_7220_ErrStatus_RcvHdrFullErr_RMASK 0x1 +#define QIB_7220_ErrStatus_RcvEgrFullErr_LSB 0xC +#define QIB_7220_ErrStatus_RcvEgrFullErr_RMASK 0x1 +#define QIB_7220_ErrStatus_RcvBadVersionErr_LSB 0xB +#define QIB_7220_ErrStatus_RcvBadVersionErr_RMASK 0x1 +#define QIB_7220_ErrStatus_RcvIBFlowErr_LSB 0xA +#define QIB_7220_ErrStatus_RcvIBFlowErr_RMASK 0x1 +#define QIB_7220_ErrStatus_RcvEBPErr_LSB 0x9 +#define QIB_7220_ErrStatus_RcvEBPErr_RMASK 0x1 +#define QIB_7220_ErrStatus_RcvUnsupportedVLErr_LSB 0x8 +#define QIB_7220_ErrStatus_RcvUnsupportedVLErr_RMASK 0x1 +#define QIB_7220_ErrStatus_RcvUnexpectedCharErr_LSB 0x7 +#define QIB_7220_ErrStatus_RcvUnexpectedCharErr_RMASK 0x1 +#define QIB_7220_ErrStatus_RcvShortPktLenErr_LSB 0x6 +#define QIB_7220_ErrStatus_RcvShortPktLenErr_RMASK 0x1 +#define QIB_7220_ErrStatus_RcvLongPktLenErr_LSB 0x5 +#define QIB_7220_ErrStatus_RcvLongPktLenErr_RMASK 0x1 +#define QIB_7220_ErrStatus_RcvMaxPktLenErr_LSB 0x4 +#define QIB_7220_ErrStatus_RcvMaxPktLenErr_RMASK 0x1 +#define QIB_7220_ErrStatus_RcvMinPktLenErr_LSB 0x3 +#define QIB_7220_ErrStatus_RcvMinPktLenErr_RMASK 0x1 +#define QIB_7220_ErrStatus_RcvICRCErr_LSB 0x2 +#define QIB_7220_ErrStatus_RcvICRCErr_RMASK 0x1 +#define QIB_7220_ErrStatus_RcvVCRCErr_LSB 0x1 +#define QIB_7220_ErrStatus_RcvVCRCErr_RMASK 0x1 +#define QIB_7220_ErrStatus_RcvFormatErr_LSB 0x0 +#define QIB_7220_ErrStatus_RcvFormatErr_RMASK 0x1 + +#define QIB_7220_ErrClear_OFFS 0x90 +#define QIB_7220_ErrClear_Reserved_LSB 0x36 +#define QIB_7220_ErrClear_Reserved_RMASK 0x3FF +#define QIB_7220_ErrClear_InvalidEEPCmdErrClear_LSB 0x35 +#define QIB_7220_ErrClear_InvalidEEPCmdErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SDmaDescAddrMisalignErrClear_LSB 0x34 +#define QIB_7220_ErrClear_SDmaDescAddrMisalignErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_HardwareErrClear_LSB 0x33 +#define QIB_7220_ErrClear_HardwareErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_ResetNegatedClear_LSB 0x32 +#define QIB_7220_ErrClear_ResetNegatedClear_RMASK 0x1 +#define QIB_7220_ErrClear_InvalidAddrErrClear_LSB 0x31 +#define QIB_7220_ErrClear_InvalidAddrErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_IBStatusChangedClear_LSB 0x30 +#define QIB_7220_ErrClear_IBStatusChangedClear_RMASK 0x1 +#define QIB_7220_ErrClear_SDmaUnexpDataErrClear_LSB 0x2F +#define QIB_7220_ErrClear_SDmaUnexpDataErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SDmaMissingDwErrClear_LSB 0x2E +#define QIB_7220_ErrClear_SDmaMissingDwErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SDmaDwEnErrClear_LSB 0x2D +#define QIB_7220_ErrClear_SDmaDwEnErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SDmaRpyTagErrClear_LSB 0x2C +#define QIB_7220_ErrClear_SDmaRpyTagErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SDma1stDescErrClear_LSB 0x2B +#define QIB_7220_ErrClear_SDma1stDescErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SDmaBaseErrClear_LSB 0x2A +#define QIB_7220_ErrClear_SDmaBaseErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SDmaTailOutOfBoundErrClear_LSB 0x29 +#define QIB_7220_ErrClear_SDmaTailOutOfBoundErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SDmaOutOfBoundErrClear_LSB 0x28 +#define QIB_7220_ErrClear_SDmaOutOfBoundErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SDmaGenMismatchErrClear_LSB 0x27 +#define QIB_7220_ErrClear_SDmaGenMismatchErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SendBufMisuseErrClear_LSB 0x26 +#define QIB_7220_ErrClear_SendBufMisuseErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SendUnsupportedVLErrClear_LSB 0x25 +#define QIB_7220_ErrClear_SendUnsupportedVLErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SendUnexpectedPktNumErrClear_LSB 0x24 +#define QIB_7220_ErrClear_SendUnexpectedPktNumErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SendPioArmLaunchErrClear_LSB 0x23 +#define QIB_7220_ErrClear_SendPioArmLaunchErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SendDroppedDataPktErrClear_LSB 0x22 +#define QIB_7220_ErrClear_SendDroppedDataPktErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SendDroppedSmpPktErrClear_LSB 0x21 +#define QIB_7220_ErrClear_SendDroppedSmpPktErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SendPktLenErrClear_LSB 0x20 +#define QIB_7220_ErrClear_SendPktLenErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SendUnderRunErrClear_LSB 0x1F +#define QIB_7220_ErrClear_SendUnderRunErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SendMaxPktLenErrClear_LSB 0x1E +#define QIB_7220_ErrClear_SendMaxPktLenErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SendMinPktLenErrClear_LSB 0x1D +#define QIB_7220_ErrClear_SendMinPktLenErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SDmaDisabledErrClear_LSB 0x1C +#define QIB_7220_ErrClear_SDmaDisabledErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_SendSpecialTriggerErrClear_LSB 0x1B +#define QIB_7220_ErrClear_SendSpecialTriggerErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_Reserved1_LSB 0x12 +#define QIB_7220_ErrClear_Reserved1_RMASK 0x1FF +#define QIB_7220_ErrClear_RcvIBLostLinkErrClear_LSB 0x11 +#define QIB_7220_ErrClear_RcvIBLostLinkErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_RcvHdrErrClear_LSB 0x10 +#define QIB_7220_ErrClear_RcvHdrErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_RcvHdrLenErrClear_LSB 0xF +#define QIB_7220_ErrClear_RcvHdrLenErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_RcvBadTidErrClear_LSB 0xE +#define QIB_7220_ErrClear_RcvBadTidErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_RcvHdrFullErrClear_LSB 0xD +#define QIB_7220_ErrClear_RcvHdrFullErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_RcvEgrFullErrClear_LSB 0xC +#define QIB_7220_ErrClear_RcvEgrFullErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_RcvBadVersionErrClear_LSB 0xB +#define QIB_7220_ErrClear_RcvBadVersionErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_RcvIBFlowErrClear_LSB 0xA +#define QIB_7220_ErrClear_RcvIBFlowErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_RcvEBPErrClear_LSB 0x9 +#define QIB_7220_ErrClear_RcvEBPErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_RcvUnsupportedVLErrClear_LSB 0x8 +#define QIB_7220_ErrClear_RcvUnsupportedVLErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_RcvUnexpectedCharErrClear_LSB 0x7 +#define QIB_7220_ErrClear_RcvUnexpectedCharErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_RcvShortPktLenErrClear_LSB 0x6 +#define QIB_7220_ErrClear_RcvShortPktLenErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_RcvLongPktLenErrClear_LSB 0x5 +#define QIB_7220_ErrClear_RcvLongPktLenErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_RcvMaxPktLenErrClear_LSB 0x4 +#define QIB_7220_ErrClear_RcvMaxPktLenErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_RcvMinPktLenErrClear_LSB 0x3 +#define QIB_7220_ErrClear_RcvMinPktLenErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_RcvICRCErrClear_LSB 0x2 +#define QIB_7220_ErrClear_RcvICRCErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_RcvVCRCErrClear_LSB 0x1 +#define QIB_7220_ErrClear_RcvVCRCErrClear_RMASK 0x1 +#define QIB_7220_ErrClear_RcvFormatErrClear_LSB 0x0 +#define QIB_7220_ErrClear_RcvFormatErrClear_RMASK 0x1 + +#define QIB_7220_HwErrMask_OFFS 0x98 +#define QIB_7220_HwErrMask_IBCBusFromSPCParityErrMask_LSB 0x3F +#define QIB_7220_HwErrMask_IBCBusFromSPCParityErrMask_RMASK 0x1 +#define QIB_7220_HwErrMask_IBCBusToSPCParityErrMask_LSB 0x3E +#define QIB_7220_HwErrMask_IBCBusToSPCParityErrMask_RMASK 0x1 +#define QIB_7220_HwErrMask_Clk_uC_PLLNotLockedMask_LSB 0x3D +#define QIB_7220_HwErrMask_Clk_uC_PLLNotLockedMask_RMASK 0x1 +#define QIB_7220_HwErrMask_IBSerdesPClkNotDetectMask_LSB 0x3C +#define QIB_7220_HwErrMask_IBSerdesPClkNotDetectMask_RMASK 0x1 +#define QIB_7220_HwErrMask_PCIESerdesQ3PClkNotDetectMask_LSB 0x3B +#define QIB_7220_HwErrMask_PCIESerdesQ3PClkNotDetectMask_RMASK 0x1 +#define QIB_7220_HwErrMask_PCIESerdesQ2PClkNotDetectMask_LSB 0x3A +#define QIB_7220_HwErrMask_PCIESerdesQ2PClkNotDetectMask_RMASK 0x1 +#define QIB_7220_HwErrMask_PCIESerdesQ1PClkNotDetectMask_LSB 0x39 +#define QIB_7220_HwErrMask_PCIESerdesQ1PClkNotDetectMask_RMASK 0x1 +#define QIB_7220_HwErrMask_PCIESerdesQ0PClkNotDetectMask_LSB 0x38 +#define QIB_7220_HwErrMask_PCIESerdesQ0PClkNotDetectMask_RMASK 0x1 +#define QIB_7220_HwErrMask_Reserved_LSB 0x37 +#define QIB_7220_HwErrMask_Reserved_RMASK 0x1 +#define QIB_7220_HwErrMask_PowerOnBISTFailedMask_LSB 0x36 +#define QIB_7220_HwErrMask_PowerOnBISTFailedMask_RMASK 0x1 +#define QIB_7220_HwErrMask_Reserved1_LSB 0x33 +#define QIB_7220_HwErrMask_Reserved1_RMASK 0x7 +#define QIB_7220_HwErrMask_RXEMemParityErrMask_LSB 0x2C +#define QIB_7220_HwErrMask_RXEMemParityErrMask_RMASK 0x7F +#define QIB_7220_HwErrMask_TXEMemParityErrMask_LSB 0x28 +#define QIB_7220_HwErrMask_TXEMemParityErrMask_RMASK 0xF +#define QIB_7220_HwErrMask_DDSRXEQMemoryParityErrMask_LSB 0x27 +#define QIB_7220_HwErrMask_DDSRXEQMemoryParityErrMask_RMASK 0x1 +#define QIB_7220_HwErrMask_IB_uC_MemoryParityErrMask_LSB 0x26 +#define QIB_7220_HwErrMask_IB_uC_MemoryParityErrMask_RMASK 0x1 +#define QIB_7220_HwErrMask_PCIEOct1_uC_MemoryParityErrMask_LSB 0x25 +#define QIB_7220_HwErrMask_PCIEOct1_uC_MemoryParityErrMask_RMASK 0x1 +#define QIB_7220_HwErrMask_PCIEOct0_uC_MemoryParityErrMask_LSB 0x24 +#define QIB_7220_HwErrMask_PCIEOct0_uC_MemoryParityErrMask_RMASK 0x1 +#define QIB_7220_HwErrMask_Reserved2_LSB 0x22 +#define QIB_7220_HwErrMask_Reserved2_RMASK 0x3 +#define QIB_7220_HwErrMask_PCIeBusParityErrMask_LSB 0x1F +#define QIB_7220_HwErrMask_PCIeBusParityErrMask_RMASK 0x7 +#define QIB_7220_HwErrMask_PcieCplTimeoutMask_LSB 0x1E +#define QIB_7220_HwErrMask_PcieCplTimeoutMask_RMASK 0x1 +#define QIB_7220_HwErrMask_PoisonedTLPMask_LSB 0x1D +#define QIB_7220_HwErrMask_PoisonedTLPMask_RMASK 0x1 +#define QIB_7220_HwErrMask_SDmaMemReadErrMask_LSB 0x1C +#define QIB_7220_HwErrMask_SDmaMemReadErrMask_RMASK 0x1 +#define QIB_7220_HwErrMask_Reserved3_LSB 0x8 +#define QIB_7220_HwErrMask_Reserved3_RMASK 0xFFFFF +#define QIB_7220_HwErrMask_PCIeMemParityErrMask_LSB 0x0 +#define QIB_7220_HwErrMask_PCIeMemParityErrMask_RMASK 0xFF + +#define QIB_7220_HwErrStatus_OFFS 0xA0 +#define QIB_7220_HwErrStatus_IBCBusFromSPCParityErr_LSB 0x3F +#define QIB_7220_HwErrStatus_IBCBusFromSPCParityErr_RMASK 0x1 +#define QIB_7220_HwErrStatus_IBCBusToSPCParityErr_LSB 0x3E +#define QIB_7220_HwErrStatus_IBCBusToSPCParityErr_RMASK 0x1 +#define QIB_7220_HwErrStatus_Clk_uC_PLLNotLocked_LSB 0x3D +#define QIB_7220_HwErrStatus_Clk_uC_PLLNotLocked_RMASK 0x1 +#define QIB_7220_HwErrStatus_IBSerdesPClkNotDetect_LSB 0x3C +#define QIB_7220_HwErrStatus_IBSerdesPClkNotDetect_RMASK 0x1 +#define QIB_7220_HwErrStatus_PCIESerdesQ3PClkNotDetect_LSB 0x3B +#define QIB_7220_HwErrStatus_PCIESerdesQ3PClkNotDetect_RMASK 0x1 +#define QIB_7220_HwErrStatus_PCIESerdesQ2PClkNotDetect_LSB 0x3A +#define QIB_7220_HwErrStatus_PCIESerdesQ2PClkNotDetect_RMASK 0x1 +#define QIB_7220_HwErrStatus_PCIESerdesQ1PClkNotDetect_LSB 0x39 +#define QIB_7220_HwErrStatus_PCIESerdesQ1PClkNotDetect_RMASK 0x1 +#define QIB_7220_HwErrStatus_PCIESerdesQ0PClkNotDetect_LSB 0x38 +#define QIB_7220_HwErrStatus_PCIESerdesQ0PClkNotDetect_RMASK 0x1 +#define QIB_7220_HwErrStatus_Reserved_LSB 0x37 +#define QIB_7220_HwErrStatus_Reserved_RMASK 0x1 +#define QIB_7220_HwErrStatus_PowerOnBISTFailed_LSB 0x36 +#define QIB_7220_HwErrStatus_PowerOnBISTFailed_RMASK 0x1 +#define QIB_7220_HwErrStatus_Reserved1_LSB 0x33 +#define QIB_7220_HwErrStatus_Reserved1_RMASK 0x7 +#define QIB_7220_HwErrStatus_RXEMemParity_LSB 0x2C +#define QIB_7220_HwErrStatus_RXEMemParity_RMASK 0x7F +#define QIB_7220_HwErrStatus_TXEMemParity_LSB 0x28 +#define QIB_7220_HwErrStatus_TXEMemParity_RMASK 0xF +#define QIB_7220_HwErrStatus_DDSRXEQMemoryParityErr_LSB 0x27 +#define QIB_7220_HwErrStatus_DDSRXEQMemoryParityErr_RMASK 0x1 +#define QIB_7220_HwErrStatus_IB_uC_MemoryParityErr_LSB 0x26 +#define QIB_7220_HwErrStatus_IB_uC_MemoryParityErr_RMASK 0x1 +#define QIB_7220_HwErrStatus_PCIE_uC_Oct1MemoryParityErr_LSB 0x25 +#define QIB_7220_HwErrStatus_PCIE_uC_Oct1MemoryParityErr_RMASK 0x1 +#define QIB_7220_HwErrStatus_PCIE_uC_Oct0MemoryParityErr_LSB 0x24 +#define QIB_7220_HwErrStatus_PCIE_uC_Oct0MemoryParityErr_RMASK 0x1 +#define QIB_7220_HwErrStatus_Reserved2_LSB 0x22 +#define QIB_7220_HwErrStatus_Reserved2_RMASK 0x3 +#define QIB_7220_HwErrStatus_PCIeBusParity_LSB 0x1F +#define QIB_7220_HwErrStatus_PCIeBusParity_RMASK 0x7 +#define QIB_7220_HwErrStatus_PcieCplTimeout_LSB 0x1E +#define QIB_7220_HwErrStatus_PcieCplTimeout_RMASK 0x1 +#define QIB_7220_HwErrStatus_PoisenedTLP_LSB 0x1D +#define QIB_7220_HwErrStatus_PoisenedTLP_RMASK 0x1 +#define QIB_7220_HwErrStatus_SDmaMemReadErr_LSB 0x1C +#define QIB_7220_HwErrStatus_SDmaMemReadErr_RMASK 0x1 +#define QIB_7220_HwErrStatus_Reserved3_LSB 0x8 +#define QIB_7220_HwErrStatus_Reserved3_RMASK 0xFFFFF +#define QIB_7220_HwErrStatus_PCIeMemParity_LSB 0x0 +#define QIB_7220_HwErrStatus_PCIeMemParity_RMASK 0xFF + +#define QIB_7220_HwErrClear_OFFS 0xA8 +#define QIB_7220_HwErrClear_IBCBusFromSPCParityErrClear_LSB 0x3F +#define QIB_7220_HwErrClear_IBCBusFromSPCParityErrClear_RMASK 0x1 +#define QIB_7220_HwErrClear_IBCBusToSPCparityErrClear_LSB 0x3E +#define QIB_7220_HwErrClear_IBCBusToSPCparityErrClear_RMASK 0x1 +#define QIB_7220_HwErrClear_Clk_uC_PLLNotLockedClear_LSB 0x3D +#define QIB_7220_HwErrClear_Clk_uC_PLLNotLockedClear_RMASK 0x1 +#define QIB_7220_HwErrClear_IBSerdesPClkNotDetectClear_LSB 0x3C +#define QIB_7220_HwErrClear_IBSerdesPClkNotDetectClear_RMASK 0x1 +#define QIB_7220_HwErrClear_PCIESerdesQ3PClkNotDetectClear_LSB 0x3B +#define QIB_7220_HwErrClear_PCIESerdesQ3PClkNotDetectClear_RMASK 0x1 +#define QIB_7220_HwErrClear_PCIESerdesQ2PClkNotDetectClear_LSB 0x3A +#define QIB_7220_HwErrClear_PCIESerdesQ2PClkNotDetectClear_RMASK 0x1 +#define QIB_7220_HwErrClear_PCIESerdesQ1PClkNotDetectClear_LSB 0x39 +#define QIB_7220_HwErrClear_PCIESerdesQ1PClkNotDetectClear_RMASK 0x1 +#define QIB_7220_HwErrClear_PCIESerdesQ0PClkNotDetectClear_LSB 0x38 +#define QIB_7220_HwErrClear_PCIESerdesQ0PClkNotDetectClear_RMASK 0x1 +#define QIB_7220_HwErrClear_Reserved_LSB 0x37 +#define QIB_7220_HwErrClear_Reserved_RMASK 0x1 +#define QIB_7220_HwErrClear_PowerOnBISTFailedClear_LSB 0x36 +#define QIB_7220_HwErrClear_PowerOnBISTFailedClear_RMASK 0x1 +#define QIB_7220_HwErrClear_Reserved1_LSB 0x33 +#define QIB_7220_HwErrClear_Reserved1_RMASK 0x7 +#define QIB_7220_HwErrClear_RXEMemParityClear_LSB 0x2C +#define QIB_7220_HwErrClear_RXEMemParityClear_RMASK 0x7F +#define QIB_7220_HwErrClear_TXEMemParityClear_LSB 0x28 +#define QIB_7220_HwErrClear_TXEMemParityClear_RMASK 0xF +#define QIB_7220_HwErrClear_DDSRXEQMemoryParityErrClear_LSB 0x27 +#define QIB_7220_HwErrClear_DDSRXEQMemoryParityErrClear_RMASK 0x1 +#define QIB_7220_HwErrClear_IB_uC_MemoryParityErrClear_LSB 0x26 +#define QIB_7220_HwErrClear_IB_uC_MemoryParityErrClear_RMASK 0x1 +#define QIB_7220_HwErrClear_PCIE_uC_Oct1MemoryParityErrClear_LSB 0x25 +#define QIB_7220_HwErrClear_PCIE_uC_Oct1MemoryParityErrClear_RMASK 0x1 +#define QIB_7220_HwErrClear_PCIE_uC_Oct0MemoryParityErrClear_LSB 0x24 +#define QIB_7220_HwErrClear_PCIE_uC_Oct0MemoryParityErrClear_RMASK 0x1 +#define QIB_7220_HwErrClear_Reserved2_LSB 0x22 +#define QIB_7220_HwErrClear_Reserved2_RMASK 0x3 +#define QIB_7220_HwErrClear_PCIeBusParityClr_LSB 0x1F +#define QIB_7220_HwErrClear_PCIeBusParityClr_RMASK 0x7 +#define QIB_7220_HwErrClear_PcieCplTimeoutClear_LSB 0x1E +#define QIB_7220_HwErrClear_PcieCplTimeoutClear_RMASK 0x1 +#define QIB_7220_HwErrClear_PoisonedTLPClear_LSB 0x1D +#define QIB_7220_HwErrClear_PoisonedTLPClear_RMASK 0x1 +#define QIB_7220_HwErrClear_SDmaMemReadErrClear_LSB 0x1C +#define QIB_7220_HwErrClear_SDmaMemReadErrClear_RMASK 0x1 +#define QIB_7220_HwErrClear_Reserved3_LSB 0x8 +#define QIB_7220_HwErrClear_Reserved3_RMASK 0xFFFFF +#define QIB_7220_HwErrClear_PCIeMemParityClr_LSB 0x0 +#define QIB_7220_HwErrClear_PCIeMemParityClr_RMASK 0xFF + +#define QIB_7220_HwDiagCtrl_OFFS 0xB0 +#define QIB_7220_HwDiagCtrl_ForceIBCBusFromSPCParityErr_LSB 0x3F +#define QIB_7220_HwDiagCtrl_ForceIBCBusFromSPCParityErr_RMASK 0x1 +#define QIB_7220_HwDiagCtrl_ForceIBCBusToSPCParityErr_LSB 0x3E +#define QIB_7220_HwDiagCtrl_ForceIBCBusToSPCParityErr_RMASK 0x1 +#define QIB_7220_HwDiagCtrl_CounterWrEnable_LSB 0x3D +#define QIB_7220_HwDiagCtrl_CounterWrEnable_RMASK 0x1 +#define QIB_7220_HwDiagCtrl_CounterDisable_LSB 0x3C +#define QIB_7220_HwDiagCtrl_CounterDisable_RMASK 0x1 +#define QIB_7220_HwDiagCtrl_Reserved_LSB 0x33 +#define QIB_7220_HwDiagCtrl_Reserved_RMASK 0x1FF +#define QIB_7220_HwDiagCtrl_ForceRxMemParityErr_LSB 0x2C +#define QIB_7220_HwDiagCtrl_ForceRxMemParityErr_RMASK 0x7F +#define QIB_7220_HwDiagCtrl_ForceTxMemparityErr_LSB 0x28 +#define QIB_7220_HwDiagCtrl_ForceTxMemparityErr_RMASK 0xF +#define QIB_7220_HwDiagCtrl_ForceDDSRXEQMemoryParityErr_LSB 0x27 +#define QIB_7220_HwDiagCtrl_ForceDDSRXEQMemoryParityErr_RMASK 0x1 +#define QIB_7220_HwDiagCtrl_ForceIB_uC_MemoryParityErr_LSB 0x26 +#define QIB_7220_HwDiagCtrl_ForceIB_uC_MemoryParityErr_RMASK 0x1 +#define QIB_7220_HwDiagCtrl_ForcePCIE_uC_Oct1MemoryParityErr_LSB 0x25 +#define QIB_7220_HwDiagCtrl_ForcePCIE_uC_Oct1MemoryParityErr_RMASK 0x1 +#define QIB_7220_HwDiagCtrl_ForcePCIE_uC_Oct0MemoryParityErr_LSB 0x24 +#define QIB_7220_HwDiagCtrl_ForcePCIE_uC_Oct0MemoryParityErr_RMASK 0x1 +#define QIB_7220_HwDiagCtrl_Reserved1_LSB 0x23 +#define QIB_7220_HwDiagCtrl_Reserved1_RMASK 0x1 +#define QIB_7220_HwDiagCtrl_forcePCIeBusParity_LSB 0x1F +#define QIB_7220_HwDiagCtrl_forcePCIeBusParity_RMASK 0xF +#define QIB_7220_HwDiagCtrl_Reserved2_LSB 0x8 +#define QIB_7220_HwDiagCtrl_Reserved2_RMASK 0x7FFFFF +#define QIB_7220_HwDiagCtrl_forcePCIeMemParity_LSB 0x0 +#define QIB_7220_HwDiagCtrl_forcePCIeMemParity_RMASK 0xFF + +#define QIB_7220_REG_0000B8_OFFS 0xB8 + +#define QIB_7220_IBCStatus_OFFS 0xC0 +#define QIB_7220_IBCStatus_TxCreditOk_LSB 0x1F +#define QIB_7220_IBCStatus_TxCreditOk_RMASK 0x1 +#define QIB_7220_IBCStatus_TxReady_LSB 0x1E +#define QIB_7220_IBCStatus_TxReady_RMASK 0x1 +#define QIB_7220_IBCStatus_Reserved_LSB 0xE +#define QIB_7220_IBCStatus_Reserved_RMASK 0xFFFF +#define QIB_7220_IBCStatus_IBTxLaneReversed_LSB 0xD +#define QIB_7220_IBCStatus_IBTxLaneReversed_RMASK 0x1 +#define QIB_7220_IBCStatus_IBRxLaneReversed_LSB 0xC +#define QIB_7220_IBCStatus_IBRxLaneReversed_RMASK 0x1 +#define QIB_7220_IBCStatus_IB_SERDES_TRIM_DONE_LSB 0xB +#define QIB_7220_IBCStatus_IB_SERDES_TRIM_DONE_RMASK 0x1 +#define QIB_7220_IBCStatus_DDS_RXEQ_FAIL_LSB 0xA +#define QIB_7220_IBCStatus_DDS_RXEQ_FAIL_RMASK 0x1 +#define QIB_7220_IBCStatus_LinkWidthActive_LSB 0x9 +#define QIB_7220_IBCStatus_LinkWidthActive_RMASK 0x1 +#define QIB_7220_IBCStatus_LinkSpeedActive_LSB 0x8 +#define QIB_7220_IBCStatus_LinkSpeedActive_RMASK 0x1 +#define QIB_7220_IBCStatus_LinkState_LSB 0x5 +#define QIB_7220_IBCStatus_LinkState_RMASK 0x7 +#define QIB_7220_IBCStatus_LinkTrainingState_LSB 0x0 +#define QIB_7220_IBCStatus_LinkTrainingState_RMASK 0x1F + +#define QIB_7220_IBCCtrl_OFFS 0xC8 +#define QIB_7220_IBCCtrl_Loopback_LSB 0x3F +#define QIB_7220_IBCCtrl_Loopback_RMASK 0x1 +#define QIB_7220_IBCCtrl_LinkDownDefaultState_LSB 0x3E +#define QIB_7220_IBCCtrl_LinkDownDefaultState_RMASK 0x1 +#define QIB_7220_IBCCtrl_Reserved_LSB 0x2B +#define QIB_7220_IBCCtrl_Reserved_RMASK 0x7FFFF +#define QIB_7220_IBCCtrl_CreditScale_LSB 0x28 +#define QIB_7220_IBCCtrl_CreditScale_RMASK 0x7 +#define QIB_7220_IBCCtrl_OverrunThreshold_LSB 0x24 +#define QIB_7220_IBCCtrl_OverrunThreshold_RMASK 0xF +#define QIB_7220_IBCCtrl_PhyerrThreshold_LSB 0x20 +#define QIB_7220_IBCCtrl_PhyerrThreshold_RMASK 0xF +#define QIB_7220_IBCCtrl_MaxPktLen_LSB 0x15 +#define QIB_7220_IBCCtrl_MaxPktLen_RMASK 0x7FF +#define QIB_7220_IBCCtrl_LinkCmd_LSB 0x13 +#define QIB_7220_IBCCtrl_LinkCmd_RMASK 0x3 +#define QIB_7220_IBCCtrl_LinkInitCmd_LSB 0x10 +#define QIB_7220_IBCCtrl_LinkInitCmd_RMASK 0x7 +#define QIB_7220_IBCCtrl_FlowCtrlWaterMark_LSB 0x8 +#define QIB_7220_IBCCtrl_FlowCtrlWaterMark_RMASK 0xFF +#define QIB_7220_IBCCtrl_FlowCtrlPeriod_LSB 0x0 +#define QIB_7220_IBCCtrl_FlowCtrlPeriod_RMASK 0xFF + +#define QIB_7220_EXTStatus_OFFS 0xD0 +#define QIB_7220_EXTStatus_GPIOIn_LSB 0x30 +#define QIB_7220_EXTStatus_GPIOIn_RMASK 0xFFFF +#define QIB_7220_EXTStatus_Reserved_LSB 0x20 +#define QIB_7220_EXTStatus_Reserved_RMASK 0xFFFF +#define QIB_7220_EXTStatus_Reserved1_LSB 0x10 +#define QIB_7220_EXTStatus_Reserved1_RMASK 0xFFFF +#define QIB_7220_EXTStatus_MemBISTDisabled_LSB 0xF +#define QIB_7220_EXTStatus_MemBISTDisabled_RMASK 0x1 +#define QIB_7220_EXTStatus_MemBISTEndTest_LSB 0xE +#define QIB_7220_EXTStatus_MemBISTEndTest_RMASK 0x1 +#define QIB_7220_EXTStatus_Reserved2_LSB 0x0 +#define QIB_7220_EXTStatus_Reserved2_RMASK 0x3FFF + +#define QIB_7220_EXTCtrl_OFFS 0xD8 +#define QIB_7220_EXTCtrl_GPIOOe_LSB 0x30 +#define QIB_7220_EXTCtrl_GPIOOe_RMASK 0xFFFF +#define QIB_7220_EXTCtrl_GPIOInvert_LSB 0x20 +#define QIB_7220_EXTCtrl_GPIOInvert_RMASK 0xFFFF +#define QIB_7220_EXTCtrl_Reserved_LSB 0x4 +#define QIB_7220_EXTCtrl_Reserved_RMASK 0xFFFFFFF +#define QIB_7220_EXTCtrl_LEDPriPortGreenOn_LSB 0x3 +#define QIB_7220_EXTCtrl_LEDPriPortGreenOn_RMASK 0x1 +#define QIB_7220_EXTCtrl_LEDPriPortYellowOn_LSB 0x2 +#define QIB_7220_EXTCtrl_LEDPriPortYellowOn_RMASK 0x1 +#define QIB_7220_EXTCtrl_LEDGblOkGreenOn_LSB 0x1 +#define QIB_7220_EXTCtrl_LEDGblOkGreenOn_RMASK 0x1 +#define QIB_7220_EXTCtrl_LEDGblErrRedOff_LSB 0x0 +#define QIB_7220_EXTCtrl_LEDGblErrRedOff_RMASK 0x1 + +#define QIB_7220_GPIOOut_OFFS 0xE0 + +#define QIB_7220_GPIOMask_OFFS 0xE8 + +#define QIB_7220_GPIOStatus_OFFS 0xF0 + +#define QIB_7220_GPIOClear_OFFS 0xF8 + +#define QIB_7220_RcvCtrl_OFFS 0x100 +#define QIB_7220_RcvCtrl_Reserved_LSB 0x27 +#define QIB_7220_RcvCtrl_Reserved_RMASK 0x1FFFFFF +#define QIB_7220_RcvCtrl_RcvQPMapEnable_LSB 0x26 +#define QIB_7220_RcvCtrl_RcvQPMapEnable_RMASK 0x1 +#define QIB_7220_RcvCtrl_PortCfg_LSB 0x24 +#define QIB_7220_RcvCtrl_PortCfg_RMASK 0x3 +#define QIB_7220_RcvCtrl_TailUpd_LSB 0x23 +#define QIB_7220_RcvCtrl_TailUpd_RMASK 0x1 +#define QIB_7220_RcvCtrl_RcvPartitionKeyDisable_LSB 0x22 +#define QIB_7220_RcvCtrl_RcvPartitionKeyDisable_RMASK 0x1 +#define QIB_7220_RcvCtrl_IntrAvail_LSB 0x11 +#define QIB_7220_RcvCtrl_IntrAvail_RMASK 0x1FFFF +#define QIB_7220_RcvCtrl_PortEnable_LSB 0x0 +#define QIB_7220_RcvCtrl_PortEnable_RMASK 0x1FFFF + +#define QIB_7220_RcvBTHQP_OFFS 0x108 +#define QIB_7220_RcvBTHQP_Reserved_LSB 0x18 +#define QIB_7220_RcvBTHQP_Reserved_RMASK 0xFF +#define QIB_7220_RcvBTHQP_RcvBTHQP_LSB 0x0 +#define QIB_7220_RcvBTHQP_RcvBTHQP_RMASK 0xFFFFFF + +#define QIB_7220_RcvHdrSize_OFFS 0x110 + +#define QIB_7220_RcvHdrCnt_OFFS 0x118 + +#define QIB_7220_RcvHdrEntSize_OFFS 0x120 + +#define QIB_7220_RcvTIDBase_OFFS 0x128 + +#define QIB_7220_RcvTIDCnt_OFFS 0x130 + +#define QIB_7220_RcvEgrBase_OFFS 0x138 + +#define QIB_7220_RcvEgrCnt_OFFS 0x140 + +#define QIB_7220_RcvBufBase_OFFS 0x148 + +#define QIB_7220_RcvBufSize_OFFS 0x150 + +#define QIB_7220_RxIntMemBase_OFFS 0x158 + +#define QIB_7220_RxIntMemSize_OFFS 0x160 + +#define QIB_7220_RcvPartitionKey_OFFS 0x168 + +#define QIB_7220_RcvQPMulticastPort_OFFS 0x170 +#define QIB_7220_RcvQPMulticastPort_Reserved_LSB 0x5 +#define QIB_7220_RcvQPMulticastPort_Reserved_RMASK 0x7FFFFFFFFFFFFFF +#define QIB_7220_RcvQPMulticastPort_RcvQpMcPort_LSB 0x0 +#define QIB_7220_RcvQPMulticastPort_RcvQpMcPort_RMASK 0x1F + +#define QIB_7220_RcvPktLEDCnt_OFFS 0x178 +#define QIB_7220_RcvPktLEDCnt_ONperiod_LSB 0x20 +#define QIB_7220_RcvPktLEDCnt_ONperiod_RMASK 0xFFFFFFFF +#define QIB_7220_RcvPktLEDCnt_OFFperiod_LSB 0x0 +#define QIB_7220_RcvPktLEDCnt_OFFperiod_RMASK 0xFFFFFFFF + +#define QIB_7220_IBCDDRCtrl_OFFS 0x180 +#define QIB_7220_IBCDDRCtrl_IB_DLID_MASK_LSB 0x30 +#define QIB_7220_IBCDDRCtrl_IB_DLID_MASK_RMASK 0xFFFF +#define QIB_7220_IBCDDRCtrl_IB_DLID_LSB 0x20 +#define QIB_7220_IBCDDRCtrl_IB_DLID_RMASK 0xFFFF +#define QIB_7220_IBCDDRCtrl_Reserved_LSB 0x1B +#define QIB_7220_IBCDDRCtrl_Reserved_RMASK 0x1F +#define QIB_7220_IBCDDRCtrl_HRTBT_REQ_LSB 0x1A +#define QIB_7220_IBCDDRCtrl_HRTBT_REQ_RMASK 0x1 +#define QIB_7220_IBCDDRCtrl_HRTBT_PORT_LSB 0x12 +#define QIB_7220_IBCDDRCtrl_HRTBT_PORT_RMASK 0xFF +#define QIB_7220_IBCDDRCtrl_HRTBT_AUTO_LSB 0x11 +#define QIB_7220_IBCDDRCtrl_HRTBT_AUTO_RMASK 0x1 +#define QIB_7220_IBCDDRCtrl_HRTBT_ENB_LSB 0x10 +#define QIB_7220_IBCDDRCtrl_HRTBT_ENB_RMASK 0x1 +#define QIB_7220_IBCDDRCtrl_SD_DDS_LSB 0xC +#define QIB_7220_IBCDDRCtrl_SD_DDS_RMASK 0xF +#define QIB_7220_IBCDDRCtrl_SD_DDSV_LSB 0xB +#define QIB_7220_IBCDDRCtrl_SD_DDSV_RMASK 0x1 +#define QIB_7220_IBCDDRCtrl_SD_ADD_ENB_LSB 0xA +#define QIB_7220_IBCDDRCtrl_SD_ADD_ENB_RMASK 0x1 +#define QIB_7220_IBCDDRCtrl_SD_RX_EQUAL_ENABLE_LSB 0x9 +#define QIB_7220_IBCDDRCtrl_SD_RX_EQUAL_ENABLE_RMASK 0x1 +#define QIB_7220_IBCDDRCtrl_IB_LANE_REV_SUPPORTED_LSB 0x8 +#define QIB_7220_IBCDDRCtrl_IB_LANE_REV_SUPPORTED_RMASK 0x1 +#define QIB_7220_IBCDDRCtrl_IB_POLARITY_REV_SUPP_LSB 0x7 +#define QIB_7220_IBCDDRCtrl_IB_POLARITY_REV_SUPP_RMASK 0x1 +#define QIB_7220_IBCDDRCtrl_IB_NUM_CHANNELS_LSB 0x5 +#define QIB_7220_IBCDDRCtrl_IB_NUM_CHANNELS_RMASK 0x3 +#define QIB_7220_IBCDDRCtrl_SD_SPEED_QDR_LSB 0x4 +#define QIB_7220_IBCDDRCtrl_SD_SPEED_QDR_RMASK 0x1 +#define QIB_7220_IBCDDRCtrl_SD_SPEED_DDR_LSB 0x3 +#define QIB_7220_IBCDDRCtrl_SD_SPEED_DDR_RMASK 0x1 +#define QIB_7220_IBCDDRCtrl_SD_SPEED_SDR_LSB 0x2 +#define QIB_7220_IBCDDRCtrl_SD_SPEED_SDR_RMASK 0x1 +#define QIB_7220_IBCDDRCtrl_SD_SPEED_LSB 0x1 +#define QIB_7220_IBCDDRCtrl_SD_SPEED_RMASK 0x1 +#define QIB_7220_IBCDDRCtrl_IB_ENHANCED_MODE_LSB 0x0 +#define QIB_7220_IBCDDRCtrl_IB_ENHANCED_MODE_RMASK 0x1 + +#define QIB_7220_HRTBT_GUID_OFFS 0x188 + +#define QIB_7220_IBCDDRCtrl2_OFFS 0x1A0 +#define QIB_7220_IBCDDRCtrl2_IB_BACK_PORCH_LSB 0x5 +#define QIB_7220_IBCDDRCtrl2_IB_BACK_PORCH_RMASK 0x1F +#define QIB_7220_IBCDDRCtrl2_IB_FRONT_PORCH_LSB 0x0 +#define QIB_7220_IBCDDRCtrl2_IB_FRONT_PORCH_RMASK 0x1F + +#define QIB_7220_IBCDDRStatus_OFFS 0x1A8 +#define QIB_7220_IBCDDRStatus_heartbeat_timed_out_LSB 0x24 +#define QIB_7220_IBCDDRStatus_heartbeat_timed_out_RMASK 0x1 +#define QIB_7220_IBCDDRStatus_heartbeat_crosstalk_LSB 0x20 +#define QIB_7220_IBCDDRStatus_heartbeat_crosstalk_RMASK 0xF +#define QIB_7220_IBCDDRStatus_RxEqLocalDevice_LSB 0x1E +#define QIB_7220_IBCDDRStatus_RxEqLocalDevice_RMASK 0x3 +#define QIB_7220_IBCDDRStatus_ReqDDSLocalFromRmt_LSB 0x1A +#define QIB_7220_IBCDDRStatus_ReqDDSLocalFromRmt_RMASK 0xF +#define QIB_7220_IBCDDRStatus_LinkRoundTripLatency_LSB 0x0 +#define QIB_7220_IBCDDRStatus_LinkRoundTripLatency_RMASK 0x3FFFFFF + +#define QIB_7220_JIntReload_OFFS 0x1B0 +#define QIB_7220_JIntReload_J_limit_reload_LSB 0x10 +#define QIB_7220_JIntReload_J_limit_reload_RMASK 0xFFFF +#define QIB_7220_JIntReload_J_reload_LSB 0x0 +#define QIB_7220_JIntReload_J_reload_RMASK 0xFFFF + +#define QIB_7220_IBNCModeCtrl_OFFS 0x1B8 +#define QIB_7220_IBNCModeCtrl_Reserved_LSB 0x1A +#define QIB_7220_IBNCModeCtrl_Reserved_RMASK 0x3FFFFFFFFF +#define QIB_7220_IBNCModeCtrl_TSMCode_TS2_LSB 0x11 +#define QIB_7220_IBNCModeCtrl_TSMCode_TS2_RMASK 0x1FF +#define QIB_7220_IBNCModeCtrl_TSMCode_TS1_LSB 0x8 +#define QIB_7220_IBNCModeCtrl_TSMCode_TS1_RMASK 0x1FF +#define QIB_7220_IBNCModeCtrl_Reserved1_LSB 0x3 +#define QIB_7220_IBNCModeCtrl_Reserved1_RMASK 0x1F +#define QIB_7220_IBNCModeCtrl_TSMEnable_ignore_TSM_on_rx_LSB 0x2 +#define QIB_7220_IBNCModeCtrl_TSMEnable_ignore_TSM_on_rx_RMASK 0x1 +#define QIB_7220_IBNCModeCtrl_TSMEnable_send_TS2_LSB 0x1 +#define QIB_7220_IBNCModeCtrl_TSMEnable_send_TS2_RMASK 0x1 +#define QIB_7220_IBNCModeCtrl_TSMEnable_send_TS1_LSB 0x0 +#define QIB_7220_IBNCModeCtrl_TSMEnable_send_TS1_RMASK 0x1 + +#define QIB_7220_SendCtrl_OFFS 0x1C0 +#define QIB_7220_SendCtrl_Disarm_LSB 0x1F +#define QIB_7220_SendCtrl_Disarm_RMASK 0x1 +#define QIB_7220_SendCtrl_Reserved_LSB 0x1D +#define QIB_7220_SendCtrl_Reserved_RMASK 0x3 +#define QIB_7220_SendCtrl_AvailUpdThld_LSB 0x18 +#define QIB_7220_SendCtrl_AvailUpdThld_RMASK 0x1F +#define QIB_7220_SendCtrl_DisarmPIOBuf_LSB 0x10 +#define QIB_7220_SendCtrl_DisarmPIOBuf_RMASK 0xFF +#define QIB_7220_SendCtrl_Reserved1_LSB 0xD +#define QIB_7220_SendCtrl_Reserved1_RMASK 0x7 +#define QIB_7220_SendCtrl_SDmaHalt_LSB 0xC +#define QIB_7220_SendCtrl_SDmaHalt_RMASK 0x1 +#define QIB_7220_SendCtrl_SDmaEnable_LSB 0xB +#define QIB_7220_SendCtrl_SDmaEnable_RMASK 0x1 +#define QIB_7220_SendCtrl_SDmaSingleDescriptor_LSB 0xA +#define QIB_7220_SendCtrl_SDmaSingleDescriptor_RMASK 0x1 +#define QIB_7220_SendCtrl_SDmaIntEnable_LSB 0x9 +#define QIB_7220_SendCtrl_SDmaIntEnable_RMASK 0x1 +#define QIB_7220_SendCtrl_Reserved2_LSB 0x5 +#define QIB_7220_SendCtrl_Reserved2_RMASK 0xF +#define QIB_7220_SendCtrl_SSpecialTriggerEn_LSB 0x4 +#define QIB_7220_SendCtrl_SSpecialTriggerEn_RMASK 0x1 +#define QIB_7220_SendCtrl_SPioEnable_LSB 0x3 +#define QIB_7220_SendCtrl_SPioEnable_RMASK 0x1 +#define QIB_7220_SendCtrl_SendBufAvailUpd_LSB 0x2 +#define QIB_7220_SendCtrl_SendBufAvailUpd_RMASK 0x1 +#define QIB_7220_SendCtrl_SendIntBufAvail_LSB 0x1 +#define QIB_7220_SendCtrl_SendIntBufAvail_RMASK 0x1 +#define QIB_7220_SendCtrl_Abort_LSB 0x0 +#define QIB_7220_SendCtrl_Abort_RMASK 0x1 + +#define QIB_7220_SendBufBase_OFFS 0x1C8 +#define QIB_7220_SendBufBase_Reserved_LSB 0x35 +#define QIB_7220_SendBufBase_Reserved_RMASK 0x7FF +#define QIB_7220_SendBufBase_BaseAddr_LargePIO_LSB 0x20 +#define QIB_7220_SendBufBase_BaseAddr_LargePIO_RMASK 0x1FFFFF +#define QIB_7220_SendBufBase_Reserved1_LSB 0x15 +#define QIB_7220_SendBufBase_Reserved1_RMASK 0x7FF +#define QIB_7220_SendBufBase_BaseAddr_SmallPIO_LSB 0x0 +#define QIB_7220_SendBufBase_BaseAddr_SmallPIO_RMASK 0x1FFFFF + +#define QIB_7220_SendBufSize_OFFS 0x1D0 +#define QIB_7220_SendBufSize_Reserved_LSB 0x2D +#define QIB_7220_SendBufSize_Reserved_RMASK 0xFFFFF +#define QIB_7220_SendBufSize_Size_LargePIO_LSB 0x20 +#define QIB_7220_SendBufSize_Size_LargePIO_RMASK 0x1FFF +#define QIB_7220_SendBufSize_Reserved1_LSB 0xC +#define QIB_7220_SendBufSize_Reserved1_RMASK 0xFFFFF +#define QIB_7220_SendBufSize_Size_SmallPIO_LSB 0x0 +#define QIB_7220_SendBufSize_Size_SmallPIO_RMASK 0xFFF + +#define QIB_7220_SendBufCnt_OFFS 0x1D8 +#define QIB_7220_SendBufCnt_Reserved_LSB 0x24 +#define QIB_7220_SendBufCnt_Reserved_RMASK 0xFFFFFFF +#define QIB_7220_SendBufCnt_Num_LargeBuffers_LSB 0x20 +#define QIB_7220_SendBufCnt_Num_LargeBuffers_RMASK 0xF +#define QIB_7220_SendBufCnt_Reserved1_LSB 0x9 +#define QIB_7220_SendBufCnt_Reserved1_RMASK 0x7FFFFF +#define QIB_7220_SendBufCnt_Num_SmallBuffers_LSB 0x0 +#define QIB_7220_SendBufCnt_Num_SmallBuffers_RMASK 0x1FF + +#define QIB_7220_SendBufAvailAddr_OFFS 0x1E0 +#define QIB_7220_SendBufAvailAddr_SendBufAvailAddr_LSB 0x6 +#define QIB_7220_SendBufAvailAddr_SendBufAvailAddr_RMASK 0x3FFFFFFFF +#define QIB_7220_SendBufAvailAddr_Reserved_LSB 0x0 +#define QIB_7220_SendBufAvailAddr_Reserved_RMASK 0x3F + +#define QIB_7220_TxIntMemBase_OFFS 0x1E8 + +#define QIB_7220_TxIntMemSize_OFFS 0x1F0 + +#define QIB_7220_SendDmaBase_OFFS 0x1F8 +#define QIB_7220_SendDmaBase_Reserved_LSB 0x30 +#define QIB_7220_SendDmaBase_Reserved_RMASK 0xFFFF +#define QIB_7220_SendDmaBase_SendDmaBase_LSB 0x0 +#define QIB_7220_SendDmaBase_SendDmaBase_RMASK 0xFFFFFFFFFFFF + +#define QIB_7220_SendDmaLenGen_OFFS 0x200 +#define QIB_7220_SendDmaLenGen_Reserved_LSB 0x13 +#define QIB_7220_SendDmaLenGen_Reserved_RMASK 0x1FFFFFFFFFFF +#define QIB_7220_SendDmaLenGen_Generation_LSB 0x10 +#define QIB_7220_SendDmaLenGen_Generation_MSB 0x12 +#define QIB_7220_SendDmaLenGen_Generation_RMASK 0x7 +#define QIB_7220_SendDmaLenGen_Length_LSB 0x0 +#define QIB_7220_SendDmaLenGen_Length_RMASK 0xFFFF + +#define QIB_7220_SendDmaTail_OFFS 0x208 +#define QIB_7220_SendDmaTail_Reserved_LSB 0x10 +#define QIB_7220_SendDmaTail_Reserved_RMASK 0xFFFFFFFFFFFF +#define QIB_7220_SendDmaTail_SendDmaTail_LSB 0x0 +#define QIB_7220_SendDmaTail_SendDmaTail_RMASK 0xFFFF + +#define QIB_7220_SendDmaHead_OFFS 0x210 +#define QIB_7220_SendDmaHead_Reserved_LSB 0x30 +#define QIB_7220_SendDmaHead_Reserved_RMASK 0xFFFF +#define QIB_7220_SendDmaHead_InternalSendDmaHead_LSB 0x20 +#define QIB_7220_SendDmaHead_InternalSendDmaHead_RMASK 0xFFFF +#define QIB_7220_SendDmaHead_Reserved1_LSB 0x10 +#define QIB_7220_SendDmaHead_Reserved1_RMASK 0xFFFF +#define QIB_7220_SendDmaHead_SendDmaHead_LSB 0x0 +#define QIB_7220_SendDmaHead_SendDmaHead_RMASK 0xFFFF + +#define QIB_7220_SendDmaHeadAddr_OFFS 0x218 +#define QIB_7220_SendDmaHeadAddr_Reserved_LSB 0x30 +#define QIB_7220_SendDmaHeadAddr_Reserved_RMASK 0xFFFF +#define QIB_7220_SendDmaHeadAddr_SendDmaHeadAddr_LSB 0x0 +#define QIB_7220_SendDmaHeadAddr_SendDmaHeadAddr_RMASK 0xFFFFFFFFFFFF + +#define QIB_7220_SendDmaBufMask0_OFFS 0x220 +#define QIB_7220_SendDmaBufMask0_BufMask_63_0_LSB 0x0 +#define QIB_7220_SendDmaBufMask0_BufMask_63_0_RMASK 0x0 + +#define QIB_7220_SendDmaStatus_OFFS 0x238 +#define QIB_7220_SendDmaStatus_ScoreBoardDrainInProg_LSB 0x3F +#define QIB_7220_SendDmaStatus_ScoreBoardDrainInProg_RMASK 0x1 +#define QIB_7220_SendDmaStatus_AbortInProg_LSB 0x3E +#define QIB_7220_SendDmaStatus_AbortInProg_RMASK 0x1 +#define QIB_7220_SendDmaStatus_InternalSDmaEnable_LSB 0x3D +#define QIB_7220_SendDmaStatus_InternalSDmaEnable_RMASK 0x1 +#define QIB_7220_SendDmaStatus_ScbDescIndex_13_0_LSB 0x2F +#define QIB_7220_SendDmaStatus_ScbDescIndex_13_0_RMASK 0x3FFF +#define QIB_7220_SendDmaStatus_RpyLowAddr_6_0_LSB 0x28 +#define QIB_7220_SendDmaStatus_RpyLowAddr_6_0_RMASK 0x7F +#define QIB_7220_SendDmaStatus_RpyTag_7_0_LSB 0x20 +#define QIB_7220_SendDmaStatus_RpyTag_7_0_RMASK 0xFF +#define QIB_7220_SendDmaStatus_ScbFull_LSB 0x1F +#define QIB_7220_SendDmaStatus_ScbFull_RMASK 0x1 +#define QIB_7220_SendDmaStatus_ScbEmpty_LSB 0x1E +#define QIB_7220_SendDmaStatus_ScbEmpty_RMASK 0x1 +#define QIB_7220_SendDmaStatus_ScbEntryValid_LSB 0x1D +#define QIB_7220_SendDmaStatus_ScbEntryValid_RMASK 0x1 +#define QIB_7220_SendDmaStatus_ScbFetchDescFlag_LSB 0x1C +#define QIB_7220_SendDmaStatus_ScbFetchDescFlag_RMASK 0x1 +#define QIB_7220_SendDmaStatus_SplFifoReadyToGo_LSB 0x1B +#define QIB_7220_SendDmaStatus_SplFifoReadyToGo_RMASK 0x1 +#define QIB_7220_SendDmaStatus_SplFifoDisarmed_LSB 0x1A +#define QIB_7220_SendDmaStatus_SplFifoDisarmed_RMASK 0x1 +#define QIB_7220_SendDmaStatus_SplFifoEmpty_LSB 0x19 +#define QIB_7220_SendDmaStatus_SplFifoEmpty_RMASK 0x1 +#define QIB_7220_SendDmaStatus_SplFifoFull_LSB 0x18 +#define QIB_7220_SendDmaStatus_SplFifoFull_RMASK 0x1 +#define QIB_7220_SendDmaStatus_SplFifoBufNum_LSB 0x10 +#define QIB_7220_SendDmaStatus_SplFifoBufNum_RMASK 0xFF +#define QIB_7220_SendDmaStatus_SplFifoDescIndex_LSB 0x0 +#define QIB_7220_SendDmaStatus_SplFifoDescIndex_RMASK 0xFFFF + +#define QIB_7220_SendBufErr0_OFFS 0x240 +#define QIB_7220_SendBufErr0_SendBufErr_63_0_LSB 0x0 +#define QIB_7220_SendBufErr0_SendBufErr_63_0_RMASK 0x0 + +#define QIB_7220_RcvHdrAddr0_OFFS 0x270 +#define QIB_7220_RcvHdrAddr0_RcvHdrAddr0_LSB 0x2 +#define QIB_7220_RcvHdrAddr0_RcvHdrAddr0_RMASK 0x3FFFFFFFFF +#define QIB_7220_RcvHdrAddr0_Reserved_LSB 0x0 +#define QIB_7220_RcvHdrAddr0_Reserved_RMASK 0x3 + +#define QIB_7220_RcvHdrTailAddr0_OFFS 0x300 +#define QIB_7220_RcvHdrTailAddr0_RcvHdrTailAddr0_LSB 0x2 +#define QIB_7220_RcvHdrTailAddr0_RcvHdrTailAddr0_RMASK 0x3FFFFFFFFF +#define QIB_7220_RcvHdrTailAddr0_Reserved_LSB 0x0 +#define QIB_7220_RcvHdrTailAddr0_Reserved_RMASK 0x3 + +#define QIB_7220_ibsd_epb_access_ctrl_OFFS 0x3C0 +#define QIB_7220_ibsd_epb_access_ctrl_sw_ib_epb_req_granted_LSB 0x8 +#define QIB_7220_ibsd_epb_access_ctrl_sw_ib_epb_req_granted_RMASK 0x1 +#define QIB_7220_ibsd_epb_access_ctrl_Reserved_LSB 0x1 +#define QIB_7220_ibsd_epb_access_ctrl_Reserved_RMASK 0x7F +#define QIB_7220_ibsd_epb_access_ctrl_sw_ib_epb_req_LSB 0x0 +#define QIB_7220_ibsd_epb_access_ctrl_sw_ib_epb_req_RMASK 0x1 + +#define QIB_7220_ibsd_epb_transaction_reg_OFFS 0x3C8 +#define QIB_7220_ibsd_epb_transaction_reg_ib_epb_rdy_LSB 0x1F +#define QIB_7220_ibsd_epb_transaction_reg_ib_epb_rdy_RMASK 0x1 +#define QIB_7220_ibsd_epb_transaction_reg_ib_epb_req_error_LSB 0x1E +#define QIB_7220_ibsd_epb_transaction_reg_ib_epb_req_error_RMASK 0x1 +#define QIB_7220_ibsd_epb_transaction_reg_Reserved_LSB 0x1D +#define QIB_7220_ibsd_epb_transaction_reg_Reserved_RMASK 0x1 +#define QIB_7220_ibsd_epb_transaction_reg_mem_data_parity_LSB 0x1C +#define QIB_7220_ibsd_epb_transaction_reg_mem_data_parity_RMASK 0x1 +#define QIB_7220_ibsd_epb_transaction_reg_Reserved1_LSB 0x1B +#define QIB_7220_ibsd_epb_transaction_reg_Reserved1_RMASK 0x1 +#define QIB_7220_ibsd_epb_transaction_reg_ib_epb_cs_LSB 0x19 +#define QIB_7220_ibsd_epb_transaction_reg_ib_epb_cs_RMASK 0x3 +#define QIB_7220_ibsd_epb_transaction_reg_ib_epb_read_write_LSB 0x18 +#define QIB_7220_ibsd_epb_transaction_reg_ib_epb_read_write_RMASK 0x1 +#define QIB_7220_ibsd_epb_transaction_reg_Reserved2_LSB 0x17 +#define QIB_7220_ibsd_epb_transaction_reg_Reserved2_RMASK 0x1 +#define QIB_7220_ibsd_epb_transaction_reg_ib_epb_address_LSB 0x8 +#define QIB_7220_ibsd_epb_transaction_reg_ib_epb_address_RMASK 0x7FFF +#define QIB_7220_ibsd_epb_transaction_reg_ib_epb_data_LSB 0x0 +#define QIB_7220_ibsd_epb_transaction_reg_ib_epb_data_RMASK 0xFF + +#define QIB_7220_XGXSCfg_OFFS 0x3D8 +#define QIB_7220_XGXSCfg_sel_link_down_for_fctrl_lane_sync_reset_LSB 0x3F +#define QIB_7220_XGXSCfg_sel_link_down_for_fctrl_lane_sync_reset_RMASK 0x1 +#define QIB_7220_XGXSCfg_Reserved_LSB 0x13 +#define QIB_7220_XGXSCfg_Reserved_RMASK 0xFFFFFFFFFFF +#define QIB_7220_XGXSCfg_link_sync_mask_LSB 0x9 +#define QIB_7220_XGXSCfg_link_sync_mask_RMASK 0x3FF +#define QIB_7220_XGXSCfg_Reserved1_LSB 0x3 +#define QIB_7220_XGXSCfg_Reserved1_RMASK 0x3F +#define QIB_7220_XGXSCfg_xcv_reset_LSB 0x2 +#define QIB_7220_XGXSCfg_xcv_reset_RMASK 0x1 +#define QIB_7220_XGXSCfg_Reserved2_LSB 0x1 +#define QIB_7220_XGXSCfg_Reserved2_RMASK 0x1 +#define QIB_7220_XGXSCfg_tx_rx_reset_LSB 0x0 +#define QIB_7220_XGXSCfg_tx_rx_reset_RMASK 0x1 + +#define QIB_7220_IBSerDesCtrl_OFFS 0x3E0 +#define QIB_7220_IBSerDesCtrl_Reserved_LSB 0x2D +#define QIB_7220_IBSerDesCtrl_Reserved_RMASK 0x7FFFF +#define QIB_7220_IBSerDesCtrl_INT_uC_LSB 0x2C +#define QIB_7220_IBSerDesCtrl_INT_uC_RMASK 0x1 +#define QIB_7220_IBSerDesCtrl_CKSEL_uC_LSB 0x2A +#define QIB_7220_IBSerDesCtrl_CKSEL_uC_RMASK 0x3 +#define QIB_7220_IBSerDesCtrl_PLLN_LSB 0x28 +#define QIB_7220_IBSerDesCtrl_PLLN_RMASK 0x3 +#define QIB_7220_IBSerDesCtrl_PLLM_LSB 0x25 +#define QIB_7220_IBSerDesCtrl_PLLM_RMASK 0x7 +#define QIB_7220_IBSerDesCtrl_TXOBPD_LSB 0x24 +#define QIB_7220_IBSerDesCtrl_TXOBPD_RMASK 0x1 +#define QIB_7220_IBSerDesCtrl_TWC_LSB 0x23 +#define QIB_7220_IBSerDesCtrl_TWC_RMASK 0x1 +#define QIB_7220_IBSerDesCtrl_RXIDLE_LSB 0x22 +#define QIB_7220_IBSerDesCtrl_RXIDLE_RMASK 0x1 +#define QIB_7220_IBSerDesCtrl_RXINV_LSB 0x21 +#define QIB_7220_IBSerDesCtrl_RXINV_RMASK 0x1 +#define QIB_7220_IBSerDesCtrl_TXINV_LSB 0x20 +#define QIB_7220_IBSerDesCtrl_TXINV_RMASK 0x1 +#define QIB_7220_IBSerDesCtrl_Reserved1_LSB 0x12 +#define QIB_7220_IBSerDesCtrl_Reserved1_RMASK 0x3FFF +#define QIB_7220_IBSerDesCtrl_NumSerDesRegsToWrForRXEQ_LSB 0xD +#define QIB_7220_IBSerDesCtrl_NumSerDesRegsToWrForRXEQ_RMASK 0x1F +#define QIB_7220_IBSerDesCtrl_NumSerDesRegsToWrForDDS_LSB 0x8 +#define QIB_7220_IBSerDesCtrl_NumSerDesRegsToWrForDDS_RMASK 0x1F +#define QIB_7220_IBSerDesCtrl_Reserved2_LSB 0x1 +#define QIB_7220_IBSerDesCtrl_Reserved2_RMASK 0x7F +#define QIB_7220_IBSerDesCtrl_ResetIB_uC_Core_LSB 0x0 +#define QIB_7220_IBSerDesCtrl_ResetIB_uC_Core_RMASK 0x1 + +#define QIB_7220_pciesd_epb_access_ctrl_OFFS 0x400 +#define QIB_7220_pciesd_epb_access_ctrl_sw_pcie_epb_req_granted_LSB 0x8 +#define QIB_7220_pciesd_epb_access_ctrl_sw_pcie_epb_req_granted_RMASK 0x1 +#define QIB_7220_pciesd_epb_access_ctrl_Reserved_LSB 0x3 +#define QIB_7220_pciesd_epb_access_ctrl_Reserved_RMASK 0x1F +#define QIB_7220_pciesd_epb_access_ctrl_sw_pcieepb_star_en_LSB 0x1 +#define QIB_7220_pciesd_epb_access_ctrl_sw_pcieepb_star_en_RMASK 0x3 +#define QIB_7220_pciesd_epb_access_ctrl_sw_pcie_epb_req_LSB 0x0 +#define QIB_7220_pciesd_epb_access_ctrl_sw_pcie_epb_req_RMASK 0x1 + +#define QIB_7220_pciesd_epb_transaction_reg_OFFS 0x408 +#define QIB_7220_pciesd_epb_transaction_reg_pcie_epb_rdy_LSB 0x1F +#define QIB_7220_pciesd_epb_transaction_reg_pcie_epb_rdy_RMASK 0x1 +#define QIB_7220_pciesd_epb_transaction_reg_pcie_epb_req_error_LSB 0x1E +#define QIB_7220_pciesd_epb_transaction_reg_pcie_epb_req_error_RMASK 0x1 +#define QIB_7220_pciesd_epb_transaction_reg_Reserved_LSB 0x1D +#define QIB_7220_pciesd_epb_transaction_reg_Reserved_RMASK 0x1 +#define QIB_7220_pciesd_epb_transaction_reg_mem_data_parity_LSB 0x1C +#define QIB_7220_pciesd_epb_transaction_reg_mem_data_parity_RMASK 0x1 +#define QIB_7220_pciesd_epb_transaction_reg_pcie_epb_cs_LSB 0x19 +#define QIB_7220_pciesd_epb_transaction_reg_pcie_epb_cs_RMASK 0x7 +#define QIB_7220_pciesd_epb_transaction_reg_pcie_epb_read_write_LSB 0x18 +#define QIB_7220_pciesd_epb_transaction_reg_pcie_epb_read_write_RMASK 0x1 +#define QIB_7220_pciesd_epb_transaction_reg_Reserved1_LSB 0x17 +#define QIB_7220_pciesd_epb_transaction_reg_Reserved1_RMASK 0x1 +#define QIB_7220_pciesd_epb_transaction_reg_pcie_epb_address_LSB 0x8 +#define QIB_7220_pciesd_epb_transaction_reg_pcie_epb_address_RMASK 0x7FFF +#define QIB_7220_pciesd_epb_transaction_reg_pcie_epb_data_LSB 0x0 +#define QIB_7220_pciesd_epb_transaction_reg_pcie_epb_data_RMASK 0xFF + +#define QIB_7220_SerDes_DDSRXEQ0_OFFS 0x500 +#define QIB_7220_SerDes_DDSRXEQ0_reg_addr_LSB 0x4 +#define QIB_7220_SerDes_DDSRXEQ0_reg_addr_RMASK 0x3F +#define QIB_7220_SerDes_DDSRXEQ0_element_num_LSB 0x0 +#define QIB_7220_SerDes_DDSRXEQ0_element_num_RMASK 0xF + +#define QIB_7220_LBIntCnt_OFFS 0x13000 + +#define QIB_7220_LBFlowStallCnt_OFFS 0x13008 + +#define QIB_7220_TxSDmaDescCnt_OFFS 0x13010 + +#define QIB_7220_TxUnsupVLErrCnt_OFFS 0x13018 + +#define QIB_7220_TxDataPktCnt_OFFS 0x13020 + +#define QIB_7220_TxFlowPktCnt_OFFS 0x13028 + +#define QIB_7220_TxDwordCnt_OFFS 0x13030 + +#define QIB_7220_TxLenErrCnt_OFFS 0x13038 + +#define QIB_7220_TxMaxMinLenErrCnt_OFFS 0x13040 + +#define QIB_7220_TxUnderrunCnt_OFFS 0x13048 + +#define QIB_7220_TxFlowStallCnt_OFFS 0x13050 + +#define QIB_7220_TxDroppedPktCnt_OFFS 0x13058 + +#define QIB_7220_RxDroppedPktCnt_OFFS 0x13060 + +#define QIB_7220_RxDataPktCnt_OFFS 0x13068 + +#define QIB_7220_RxFlowPktCnt_OFFS 0x13070 + +#define QIB_7220_RxDwordCnt_OFFS 0x13078 + +#define QIB_7220_RxLenErrCnt_OFFS 0x13080 + +#define QIB_7220_RxMaxMinLenErrCnt_OFFS 0x13088 + +#define QIB_7220_RxICRCErrCnt_OFFS 0x13090 + +#define QIB_7220_RxVCRCErrCnt_OFFS 0x13098 + +#define QIB_7220_RxFlowCtrlViolCnt_OFFS 0x130A0 + +#define QIB_7220_RxVersionErrCnt_OFFS 0x130A8 + +#define QIB_7220_RxLinkMalformCnt_OFFS 0x130B0 + +#define QIB_7220_RxEBPCnt_OFFS 0x130B8 + +#define QIB_7220_RxLPCRCErrCnt_OFFS 0x130C0 + +#define QIB_7220_RxBufOvflCnt_OFFS 0x130C8 + +#define QIB_7220_RxTIDFullErrCnt_OFFS 0x130D0 + +#define QIB_7220_RxTIDValidErrCnt_OFFS 0x130D8 + +#define QIB_7220_RxPKeyMismatchCnt_OFFS 0x130E0 + +#define QIB_7220_RxP0HdrEgrOvflCnt_OFFS 0x130E8 + +#define QIB_7220_IBStatusChangeCnt_OFFS 0x13170 + +#define QIB_7220_IBLinkErrRecoveryCnt_OFFS 0x13178 + +#define QIB_7220_IBLinkDownedCnt_OFFS 0x13180 + +#define QIB_7220_IBSymbolErrCnt_OFFS 0x13188 + +#define QIB_7220_RxVL15DroppedPktCnt_OFFS 0x13190 + +#define QIB_7220_RxOtherLocalPhyErrCnt_OFFS 0x13198 + +#define QIB_7220_PcieRetryBufDiagQwordCnt_OFFS 0x131A0 + +#define QIB_7220_ExcessBufferOvflCnt_OFFS 0x131A8 + +#define QIB_7220_LocalLinkIntegrityErrCnt_OFFS 0x131B0 + +#define QIB_7220_RxVlErrCnt_OFFS 0x131B8 + +#define QIB_7220_RxDlidFltrCnt_OFFS 0x131C0 + +#define QIB_7220_CNT_0131C8_OFFS 0x131C8 + +#define QIB_7220_PSStat_OFFS 0x13200 + +#define QIB_7220_PSStart_OFFS 0x13208 + +#define QIB_7220_PSInterval_OFFS 0x13210 + +#define QIB_7220_PSRcvDataCount_OFFS 0x13218 + +#define QIB_7220_PSRcvPktsCount_OFFS 0x13220 + +#define QIB_7220_PSXmitDataCount_OFFS 0x13228 + +#define QIB_7220_PSXmitPktsCount_OFFS 0x13230 + +#define QIB_7220_PSXmitWaitCount_OFFS 0x13238 + +#define QIB_7220_CNT_013240_OFFS 0x13240 + +#define QIB_7220_RcvEgrArray_OFFS 0x14000 + +#define QIB_7220_MEM_038000_OFFS 0x38000 + +#define QIB_7220_RcvTIDArray0_OFFS 0x53000 + +#define QIB_7220_PIOLaunchFIFO_OFFS 0x64000 + +#define QIB_7220_MEM_064480_OFFS 0x64480 + +#define QIB_7220_SendPIOpbcCache_OFFS 0x64800 + +#define QIB_7220_MEM_064C80_OFFS 0x64C80 + +#define QIB_7220_PreLaunchFIFO_OFFS 0x65000 + +#define QIB_7220_MEM_065080_OFFS 0x65080 + +#define QIB_7220_ScoreBoard_OFFS 0x65400 + +#define QIB_7220_MEM_065440_OFFS 0x65440 + +#define QIB_7220_DescriptorFIFO_OFFS 0x65800 + +#define QIB_7220_MEM_065880_OFFS 0x65880 + +#define QIB_7220_RcvBuf1_OFFS 0x72000 + +#define QIB_7220_MEM_074800_OFFS 0x74800 + +#define QIB_7220_RcvBuf2_OFFS 0x75000 + +#define QIB_7220_MEM_076400_OFFS 0x76400 + +#define QIB_7220_RcvFlags_OFFS 0x77000 + +#define QIB_7220_MEM_078400_OFFS 0x78400 + +#define QIB_7220_RcvLookupBuf1_OFFS 0x79000 + +#define QIB_7220_MEM_07A400_OFFS 0x7A400 + +#define QIB_7220_RcvDMADatBuf_OFFS 0x7B000 + +#define QIB_7220_RcvDMAHdrBuf_OFFS 0x7B800 + +#define QIB_7220_MiscRXEIntMem_OFFS 0x7C000 + +#define QIB_7220_MEM_07D400_OFFS 0x7D400 + +#define QIB_7220_PCIERcvBuf_OFFS 0x80000 + +#define QIB_7220_PCIERetryBuf_OFFS 0x84000 + +#define QIB_7220_PCIERcvBufRdToWrAddr_OFFS 0x88000 + +#define QIB_7220_PCIECplBuf_OFFS 0x90000 + +#define QIB_7220_IBSerDesMappTable_OFFS 0x94000 + +#define QIB_7220_MEM_095000_OFFS 0x95000 + +#define QIB_7220_SendBuf0_MA_OFFS 0x100000 + +#define QIB_7220_MEM_1A0000_OFFS 0x1A0000 diff --git a/drivers/infiniband/hw/qib/qib_7322_regs.h b/drivers/infiniband/hw/qib/qib_7322_regs.h new file mode 100644 index 000000000000..a97440ba924c --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_7322_regs.h @@ -0,0 +1,3163 @@ +/* + * Copyright (c) 2008, 2009, 2010 QLogic Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* This file is mechanically generated from RTL. Any hand-edits will be lost! */ + +#define QIB_7322_Revision_OFFS 0x0 +#define QIB_7322_Revision_DEF 0x0000000002010601 +#define QIB_7322_Revision_R_Simulator_LSB 0x3F +#define QIB_7322_Revision_R_Simulator_MSB 0x3F +#define QIB_7322_Revision_R_Simulator_RMASK 0x1 +#define QIB_7322_Revision_R_Emulation_LSB 0x3E +#define QIB_7322_Revision_R_Emulation_MSB 0x3E +#define QIB_7322_Revision_R_Emulation_RMASK 0x1 +#define QIB_7322_Revision_R_Emulation_Revcode_LSB 0x28 +#define QIB_7322_Revision_R_Emulation_Revcode_MSB 0x3D +#define QIB_7322_Revision_R_Emulation_Revcode_RMASK 0x3FFFFF +#define QIB_7322_Revision_BoardID_LSB 0x20 +#define QIB_7322_Revision_BoardID_MSB 0x27 +#define QIB_7322_Revision_BoardID_RMASK 0xFF +#define QIB_7322_Revision_R_SW_LSB 0x18 +#define QIB_7322_Revision_R_SW_MSB 0x1F +#define QIB_7322_Revision_R_SW_RMASK 0xFF +#define QIB_7322_Revision_R_Arch_LSB 0x10 +#define QIB_7322_Revision_R_Arch_MSB 0x17 +#define QIB_7322_Revision_R_Arch_RMASK 0xFF +#define QIB_7322_Revision_R_ChipRevMajor_LSB 0x8 +#define QIB_7322_Revision_R_ChipRevMajor_MSB 0xF +#define QIB_7322_Revision_R_ChipRevMajor_RMASK 0xFF +#define QIB_7322_Revision_R_ChipRevMinor_LSB 0x0 +#define QIB_7322_Revision_R_ChipRevMinor_MSB 0x7 +#define QIB_7322_Revision_R_ChipRevMinor_RMASK 0xFF + +#define QIB_7322_Control_OFFS 0x8 +#define QIB_7322_Control_DEF 0x0000000000000000 +#define QIB_7322_Control_PCIECplQDiagEn_LSB 0x6 +#define QIB_7322_Control_PCIECplQDiagEn_MSB 0x6 +#define QIB_7322_Control_PCIECplQDiagEn_RMASK 0x1 +#define QIB_7322_Control_PCIEPostQDiagEn_LSB 0x5 +#define QIB_7322_Control_PCIEPostQDiagEn_MSB 0x5 +#define QIB_7322_Control_PCIEPostQDiagEn_RMASK 0x1 +#define QIB_7322_Control_SDmaDescFetchPriorityEn_LSB 0x4 +#define QIB_7322_Control_SDmaDescFetchPriorityEn_MSB 0x4 +#define QIB_7322_Control_SDmaDescFetchPriorityEn_RMASK 0x1 +#define QIB_7322_Control_PCIERetryBufDiagEn_LSB 0x3 +#define QIB_7322_Control_PCIERetryBufDiagEn_MSB 0x3 +#define QIB_7322_Control_PCIERetryBufDiagEn_RMASK 0x1 +#define QIB_7322_Control_FreezeMode_LSB 0x1 +#define QIB_7322_Control_FreezeMode_MSB 0x1 +#define QIB_7322_Control_FreezeMode_RMASK 0x1 +#define QIB_7322_Control_SyncReset_LSB 0x0 +#define QIB_7322_Control_SyncReset_MSB 0x0 +#define QIB_7322_Control_SyncReset_RMASK 0x1 + +#define QIB_7322_PageAlign_OFFS 0x10 +#define QIB_7322_PageAlign_DEF 0x0000000000001000 + +#define QIB_7322_ContextCnt_OFFS 0x18 +#define QIB_7322_ContextCnt_DEF 0x0000000000000012 + +#define QIB_7322_Scratch_OFFS 0x20 +#define QIB_7322_Scratch_DEF 0x0000000000000000 + +#define QIB_7322_CntrRegBase_OFFS 0x28 +#define QIB_7322_CntrRegBase_DEF 0x0000000000011000 + +#define QIB_7322_SendRegBase_OFFS 0x30 +#define QIB_7322_SendRegBase_DEF 0x0000000000003000 + +#define QIB_7322_UserRegBase_OFFS 0x38 +#define QIB_7322_UserRegBase_DEF 0x0000000000200000 + +#define QIB_7322_IntMask_OFFS 0x68 +#define QIB_7322_IntMask_DEF 0x0000000000000000 +#define QIB_7322_IntMask_SDmaIntMask_1_LSB 0x3F +#define QIB_7322_IntMask_SDmaIntMask_1_MSB 0x3F +#define QIB_7322_IntMask_SDmaIntMask_1_RMASK 0x1 +#define QIB_7322_IntMask_SDmaIntMask_0_LSB 0x3E +#define QIB_7322_IntMask_SDmaIntMask_0_MSB 0x3E +#define QIB_7322_IntMask_SDmaIntMask_0_RMASK 0x1 +#define QIB_7322_IntMask_SDmaProgressIntMask_1_LSB 0x3D +#define QIB_7322_IntMask_SDmaProgressIntMask_1_MSB 0x3D +#define QIB_7322_IntMask_SDmaProgressIntMask_1_RMASK 0x1 +#define QIB_7322_IntMask_SDmaProgressIntMask_0_LSB 0x3C +#define QIB_7322_IntMask_SDmaProgressIntMask_0_MSB 0x3C +#define QIB_7322_IntMask_SDmaProgressIntMask_0_RMASK 0x1 +#define QIB_7322_IntMask_SDmaIdleIntMask_1_LSB 0x3B +#define QIB_7322_IntMask_SDmaIdleIntMask_1_MSB 0x3B +#define QIB_7322_IntMask_SDmaIdleIntMask_1_RMASK 0x1 +#define QIB_7322_IntMask_SDmaIdleIntMask_0_LSB 0x3A +#define QIB_7322_IntMask_SDmaIdleIntMask_0_MSB 0x3A +#define QIB_7322_IntMask_SDmaIdleIntMask_0_RMASK 0x1 +#define QIB_7322_IntMask_SDmaCleanupDoneMask_1_LSB 0x39 +#define QIB_7322_IntMask_SDmaCleanupDoneMask_1_MSB 0x39 +#define QIB_7322_IntMask_SDmaCleanupDoneMask_1_RMASK 0x1 +#define QIB_7322_IntMask_SDmaCleanupDoneMask_0_LSB 0x38 +#define QIB_7322_IntMask_SDmaCleanupDoneMask_0_MSB 0x38 +#define QIB_7322_IntMask_SDmaCleanupDoneMask_0_RMASK 0x1 +#define QIB_7322_IntMask_RcvUrg17IntMask_LSB 0x31 +#define QIB_7322_IntMask_RcvUrg17IntMask_MSB 0x31 +#define QIB_7322_IntMask_RcvUrg17IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvUrg16IntMask_LSB 0x30 +#define QIB_7322_IntMask_RcvUrg16IntMask_MSB 0x30 +#define QIB_7322_IntMask_RcvUrg16IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvUrg15IntMask_LSB 0x2F +#define QIB_7322_IntMask_RcvUrg15IntMask_MSB 0x2F +#define QIB_7322_IntMask_RcvUrg15IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvUrg14IntMask_LSB 0x2E +#define QIB_7322_IntMask_RcvUrg14IntMask_MSB 0x2E +#define QIB_7322_IntMask_RcvUrg14IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvUrg13IntMask_LSB 0x2D +#define QIB_7322_IntMask_RcvUrg13IntMask_MSB 0x2D +#define QIB_7322_IntMask_RcvUrg13IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvUrg12IntMask_LSB 0x2C +#define QIB_7322_IntMask_RcvUrg12IntMask_MSB 0x2C +#define QIB_7322_IntMask_RcvUrg12IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvUrg11IntMask_LSB 0x2B +#define QIB_7322_IntMask_RcvUrg11IntMask_MSB 0x2B +#define QIB_7322_IntMask_RcvUrg11IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvUrg10IntMask_LSB 0x2A +#define QIB_7322_IntMask_RcvUrg10IntMask_MSB 0x2A +#define QIB_7322_IntMask_RcvUrg10IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvUrg9IntMask_LSB 0x29 +#define QIB_7322_IntMask_RcvUrg9IntMask_MSB 0x29 +#define QIB_7322_IntMask_RcvUrg9IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvUrg8IntMask_LSB 0x28 +#define QIB_7322_IntMask_RcvUrg8IntMask_MSB 0x28 +#define QIB_7322_IntMask_RcvUrg8IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvUrg7IntMask_LSB 0x27 +#define QIB_7322_IntMask_RcvUrg7IntMask_MSB 0x27 +#define QIB_7322_IntMask_RcvUrg7IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvUrg6IntMask_LSB 0x26 +#define QIB_7322_IntMask_RcvUrg6IntMask_MSB 0x26 +#define QIB_7322_IntMask_RcvUrg6IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvUrg5IntMask_LSB 0x25 +#define QIB_7322_IntMask_RcvUrg5IntMask_MSB 0x25 +#define QIB_7322_IntMask_RcvUrg5IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvUrg4IntMask_LSB 0x24 +#define QIB_7322_IntMask_RcvUrg4IntMask_MSB 0x24 +#define QIB_7322_IntMask_RcvUrg4IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvUrg3IntMask_LSB 0x23 +#define QIB_7322_IntMask_RcvUrg3IntMask_MSB 0x23 +#define QIB_7322_IntMask_RcvUrg3IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvUrg2IntMask_LSB 0x22 +#define QIB_7322_IntMask_RcvUrg2IntMask_MSB 0x22 +#define QIB_7322_IntMask_RcvUrg2IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvUrg1IntMask_LSB 0x21 +#define QIB_7322_IntMask_RcvUrg1IntMask_MSB 0x21 +#define QIB_7322_IntMask_RcvUrg1IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvUrg0IntMask_LSB 0x20 +#define QIB_7322_IntMask_RcvUrg0IntMask_MSB 0x20 +#define QIB_7322_IntMask_RcvUrg0IntMask_RMASK 0x1 +#define QIB_7322_IntMask_ErrIntMask_1_LSB 0x1F +#define QIB_7322_IntMask_ErrIntMask_1_MSB 0x1F +#define QIB_7322_IntMask_ErrIntMask_1_RMASK 0x1 +#define QIB_7322_IntMask_ErrIntMask_0_LSB 0x1E +#define QIB_7322_IntMask_ErrIntMask_0_MSB 0x1E +#define QIB_7322_IntMask_ErrIntMask_0_RMASK 0x1 +#define QIB_7322_IntMask_ErrIntMask_LSB 0x1D +#define QIB_7322_IntMask_ErrIntMask_MSB 0x1D +#define QIB_7322_IntMask_ErrIntMask_RMASK 0x1 +#define QIB_7322_IntMask_AssertGPIOIntMask_LSB 0x1C +#define QIB_7322_IntMask_AssertGPIOIntMask_MSB 0x1C +#define QIB_7322_IntMask_AssertGPIOIntMask_RMASK 0x1 +#define QIB_7322_IntMask_SendDoneIntMask_1_LSB 0x19 +#define QIB_7322_IntMask_SendDoneIntMask_1_MSB 0x19 +#define QIB_7322_IntMask_SendDoneIntMask_1_RMASK 0x1 +#define QIB_7322_IntMask_SendDoneIntMask_0_LSB 0x18 +#define QIB_7322_IntMask_SendDoneIntMask_0_MSB 0x18 +#define QIB_7322_IntMask_SendDoneIntMask_0_RMASK 0x1 +#define QIB_7322_IntMask_SendBufAvailIntMask_LSB 0x17 +#define QIB_7322_IntMask_SendBufAvailIntMask_MSB 0x17 +#define QIB_7322_IntMask_SendBufAvailIntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvAvail17IntMask_LSB 0x11 +#define QIB_7322_IntMask_RcvAvail17IntMask_MSB 0x11 +#define QIB_7322_IntMask_RcvAvail17IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvAvail16IntMask_LSB 0x10 +#define QIB_7322_IntMask_RcvAvail16IntMask_MSB 0x10 +#define QIB_7322_IntMask_RcvAvail16IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvAvail15IntMask_LSB 0xF +#define QIB_7322_IntMask_RcvAvail15IntMask_MSB 0xF +#define QIB_7322_IntMask_RcvAvail15IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvAvail14IntMask_LSB 0xE +#define QIB_7322_IntMask_RcvAvail14IntMask_MSB 0xE +#define QIB_7322_IntMask_RcvAvail14IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvAvail13IntMask_LSB 0xD +#define QIB_7322_IntMask_RcvAvail13IntMask_MSB 0xD +#define QIB_7322_IntMask_RcvAvail13IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvAvail12IntMask_LSB 0xC +#define QIB_7322_IntMask_RcvAvail12IntMask_MSB 0xC +#define QIB_7322_IntMask_RcvAvail12IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvAvail11IntMask_LSB 0xB +#define QIB_7322_IntMask_RcvAvail11IntMask_MSB 0xB +#define QIB_7322_IntMask_RcvAvail11IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvAvail10IntMask_LSB 0xA +#define QIB_7322_IntMask_RcvAvail10IntMask_MSB 0xA +#define QIB_7322_IntMask_RcvAvail10IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvAvail9IntMask_LSB 0x9 +#define QIB_7322_IntMask_RcvAvail9IntMask_MSB 0x9 +#define QIB_7322_IntMask_RcvAvail9IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvAvail8IntMask_LSB 0x8 +#define QIB_7322_IntMask_RcvAvail8IntMask_MSB 0x8 +#define QIB_7322_IntMask_RcvAvail8IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvAvail7IntMask_LSB 0x7 +#define QIB_7322_IntMask_RcvAvail7IntMask_MSB 0x7 +#define QIB_7322_IntMask_RcvAvail7IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvAvail6IntMask_LSB 0x6 +#define QIB_7322_IntMask_RcvAvail6IntMask_MSB 0x6 +#define QIB_7322_IntMask_RcvAvail6IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvAvail5IntMask_LSB 0x5 +#define QIB_7322_IntMask_RcvAvail5IntMask_MSB 0x5 +#define QIB_7322_IntMask_RcvAvail5IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvAvail4IntMask_LSB 0x4 +#define QIB_7322_IntMask_RcvAvail4IntMask_MSB 0x4 +#define QIB_7322_IntMask_RcvAvail4IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvAvail3IntMask_LSB 0x3 +#define QIB_7322_IntMask_RcvAvail3IntMask_MSB 0x3 +#define QIB_7322_IntMask_RcvAvail3IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvAvail2IntMask_LSB 0x2 +#define QIB_7322_IntMask_RcvAvail2IntMask_MSB 0x2 +#define QIB_7322_IntMask_RcvAvail2IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvAvail1IntMask_LSB 0x1 +#define QIB_7322_IntMask_RcvAvail1IntMask_MSB 0x1 +#define QIB_7322_IntMask_RcvAvail1IntMask_RMASK 0x1 +#define QIB_7322_IntMask_RcvAvail0IntMask_LSB 0x0 +#define QIB_7322_IntMask_RcvAvail0IntMask_MSB 0x0 +#define QIB_7322_IntMask_RcvAvail0IntMask_RMASK 0x1 + +#define QIB_7322_IntStatus_OFFS 0x70 +#define QIB_7322_IntStatus_DEF 0x0000000000000000 +#define QIB_7322_IntStatus_SDmaInt_1_LSB 0x3F +#define QIB_7322_IntStatus_SDmaInt_1_MSB 0x3F +#define QIB_7322_IntStatus_SDmaInt_1_RMASK 0x1 +#define QIB_7322_IntStatus_SDmaInt_0_LSB 0x3E +#define QIB_7322_IntStatus_SDmaInt_0_MSB 0x3E +#define QIB_7322_IntStatus_SDmaInt_0_RMASK 0x1 +#define QIB_7322_IntStatus_SDmaProgressInt_1_LSB 0x3D +#define QIB_7322_IntStatus_SDmaProgressInt_1_MSB 0x3D +#define QIB_7322_IntStatus_SDmaProgressInt_1_RMASK 0x1 +#define QIB_7322_IntStatus_SDmaProgressInt_0_LSB 0x3C +#define QIB_7322_IntStatus_SDmaProgressInt_0_MSB 0x3C +#define QIB_7322_IntStatus_SDmaProgressInt_0_RMASK 0x1 +#define QIB_7322_IntStatus_SDmaIdleInt_1_LSB 0x3B +#define QIB_7322_IntStatus_SDmaIdleInt_1_MSB 0x3B +#define QIB_7322_IntStatus_SDmaIdleInt_1_RMASK 0x1 +#define QIB_7322_IntStatus_SDmaIdleInt_0_LSB 0x3A +#define QIB_7322_IntStatus_SDmaIdleInt_0_MSB 0x3A +#define QIB_7322_IntStatus_SDmaIdleInt_0_RMASK 0x1 +#define QIB_7322_IntStatus_SDmaCleanupDone_1_LSB 0x39 +#define QIB_7322_IntStatus_SDmaCleanupDone_1_MSB 0x39 +#define QIB_7322_IntStatus_SDmaCleanupDone_1_RMASK 0x1 +#define QIB_7322_IntStatus_SDmaCleanupDone_0_LSB 0x38 +#define QIB_7322_IntStatus_SDmaCleanupDone_0_MSB 0x38 +#define QIB_7322_IntStatus_SDmaCleanupDone_0_RMASK 0x1 +#define QIB_7322_IntStatus_RcvUrg17_LSB 0x31 +#define QIB_7322_IntStatus_RcvUrg17_MSB 0x31 +#define QIB_7322_IntStatus_RcvUrg17_RMASK 0x1 +#define QIB_7322_IntStatus_RcvUrg16_LSB 0x30 +#define QIB_7322_IntStatus_RcvUrg16_MSB 0x30 +#define QIB_7322_IntStatus_RcvUrg16_RMASK 0x1 +#define QIB_7322_IntStatus_RcvUrg15_LSB 0x2F +#define QIB_7322_IntStatus_RcvUrg15_MSB 0x2F +#define QIB_7322_IntStatus_RcvUrg15_RMASK 0x1 +#define QIB_7322_IntStatus_RcvUrg14_LSB 0x2E +#define QIB_7322_IntStatus_RcvUrg14_MSB 0x2E +#define QIB_7322_IntStatus_RcvUrg14_RMASK 0x1 +#define QIB_7322_IntStatus_RcvUrg13_LSB 0x2D +#define QIB_7322_IntStatus_RcvUrg13_MSB 0x2D +#define QIB_7322_IntStatus_RcvUrg13_RMASK 0x1 +#define QIB_7322_IntStatus_RcvUrg12_LSB 0x2C +#define QIB_7322_IntStatus_RcvUrg12_MSB 0x2C +#define QIB_7322_IntStatus_RcvUrg12_RMASK 0x1 +#define QIB_7322_IntStatus_RcvUrg11_LSB 0x2B +#define QIB_7322_IntStatus_RcvUrg11_MSB 0x2B +#define QIB_7322_IntStatus_RcvUrg11_RMASK 0x1 +#define QIB_7322_IntStatus_RcvUrg10_LSB 0x2A +#define QIB_7322_IntStatus_RcvUrg10_MSB 0x2A +#define QIB_7322_IntStatus_RcvUrg10_RMASK 0x1 +#define QIB_7322_IntStatus_RcvUrg9_LSB 0x29 +#define QIB_7322_IntStatus_RcvUrg9_MSB 0x29 +#define QIB_7322_IntStatus_RcvUrg9_RMASK 0x1 +#define QIB_7322_IntStatus_RcvUrg8_LSB 0x28 +#define QIB_7322_IntStatus_RcvUrg8_MSB 0x28 +#define QIB_7322_IntStatus_RcvUrg8_RMASK 0x1 +#define QIB_7322_IntStatus_RcvUrg7_LSB 0x27 +#define QIB_7322_IntStatus_RcvUrg7_MSB 0x27 +#define QIB_7322_IntStatus_RcvUrg7_RMASK 0x1 +#define QIB_7322_IntStatus_RcvUrg6_LSB 0x26 +#define QIB_7322_IntStatus_RcvUrg6_MSB 0x26 +#define QIB_7322_IntStatus_RcvUrg6_RMASK 0x1 +#define QIB_7322_IntStatus_RcvUrg5_LSB 0x25 +#define QIB_7322_IntStatus_RcvUrg5_MSB 0x25 +#define QIB_7322_IntStatus_RcvUrg5_RMASK 0x1 +#define QIB_7322_IntStatus_RcvUrg4_LSB 0x24 +#define QIB_7322_IntStatus_RcvUrg4_MSB 0x24 +#define QIB_7322_IntStatus_RcvUrg4_RMASK 0x1 +#define QIB_7322_IntStatus_RcvUrg3_LSB 0x23 +#define QIB_7322_IntStatus_RcvUrg3_MSB 0x23 +#define QIB_7322_IntStatus_RcvUrg3_RMASK 0x1 +#define QIB_7322_IntStatus_RcvUrg2_LSB 0x22 +#define QIB_7322_IntStatus_RcvUrg2_MSB 0x22 +#define QIB_7322_IntStatus_RcvUrg2_RMASK 0x1 +#define QIB_7322_IntStatus_RcvUrg1_LSB 0x21 +#define QIB_7322_IntStatus_RcvUrg1_MSB 0x21 +#define QIB_7322_IntStatus_RcvUrg1_RMASK 0x1 +#define QIB_7322_IntStatus_RcvUrg0_LSB 0x20 +#define QIB_7322_IntStatus_RcvUrg0_MSB 0x20 +#define QIB_7322_IntStatus_RcvUrg0_RMASK 0x1 +#define QIB_7322_IntStatus_Err_1_LSB 0x1F +#define QIB_7322_IntStatus_Err_1_MSB 0x1F +#define QIB_7322_IntStatus_Err_1_RMASK 0x1 +#define QIB_7322_IntStatus_Err_0_LSB 0x1E +#define QIB_7322_IntStatus_Err_0_MSB 0x1E +#define QIB_7322_IntStatus_Err_0_RMASK 0x1 +#define QIB_7322_IntStatus_Err_LSB 0x1D +#define QIB_7322_IntStatus_Err_MSB 0x1D +#define QIB_7322_IntStatus_Err_RMASK 0x1 +#define QIB_7322_IntStatus_AssertGPIO_LSB 0x1C +#define QIB_7322_IntStatus_AssertGPIO_MSB 0x1C +#define QIB_7322_IntStatus_AssertGPIO_RMASK 0x1 +#define QIB_7322_IntStatus_SendDone_1_LSB 0x19 +#define QIB_7322_IntStatus_SendDone_1_MSB 0x19 +#define QIB_7322_IntStatus_SendDone_1_RMASK 0x1 +#define QIB_7322_IntStatus_SendDone_0_LSB 0x18 +#define QIB_7322_IntStatus_SendDone_0_MSB 0x18 +#define QIB_7322_IntStatus_SendDone_0_RMASK 0x1 +#define QIB_7322_IntStatus_SendBufAvail_LSB 0x17 +#define QIB_7322_IntStatus_SendBufAvail_MSB 0x17 +#define QIB_7322_IntStatus_SendBufAvail_RMASK 0x1 +#define QIB_7322_IntStatus_RcvAvail17_LSB 0x11 +#define QIB_7322_IntStatus_RcvAvail17_MSB 0x11 +#define QIB_7322_IntStatus_RcvAvail17_RMASK 0x1 +#define QIB_7322_IntStatus_RcvAvail16_LSB 0x10 +#define QIB_7322_IntStatus_RcvAvail16_MSB 0x10 +#define QIB_7322_IntStatus_RcvAvail16_RMASK 0x1 +#define QIB_7322_IntStatus_RcvAvail15_LSB 0xF +#define QIB_7322_IntStatus_RcvAvail15_MSB 0xF +#define QIB_7322_IntStatus_RcvAvail15_RMASK 0x1 +#define QIB_7322_IntStatus_RcvAvail14_LSB 0xE +#define QIB_7322_IntStatus_RcvAvail14_MSB 0xE +#define QIB_7322_IntStatus_RcvAvail14_RMASK 0x1 +#define QIB_7322_IntStatus_RcvAvail13_LSB 0xD +#define QIB_7322_IntStatus_RcvAvail13_MSB 0xD +#define QIB_7322_IntStatus_RcvAvail13_RMASK 0x1 +#define QIB_7322_IntStatus_RcvAvail12_LSB 0xC +#define QIB_7322_IntStatus_RcvAvail12_MSB 0xC +#define QIB_7322_IntStatus_RcvAvail12_RMASK 0x1 +#define QIB_7322_IntStatus_RcvAvail11_LSB 0xB +#define QIB_7322_IntStatus_RcvAvail11_MSB 0xB +#define QIB_7322_IntStatus_RcvAvail11_RMASK 0x1 +#define QIB_7322_IntStatus_RcvAvail10_LSB 0xA +#define QIB_7322_IntStatus_RcvAvail10_MSB 0xA +#define QIB_7322_IntStatus_RcvAvail10_RMASK 0x1 +#define QIB_7322_IntStatus_RcvAvail9_LSB 0x9 +#define QIB_7322_IntStatus_RcvAvail9_MSB 0x9 +#define QIB_7322_IntStatus_RcvAvail9_RMASK 0x1 +#define QIB_7322_IntStatus_RcvAvail8_LSB 0x8 +#define QIB_7322_IntStatus_RcvAvail8_MSB 0x8 +#define QIB_7322_IntStatus_RcvAvail8_RMASK 0x1 +#define QIB_7322_IntStatus_RcvAvail7_LSB 0x7 +#define QIB_7322_IntStatus_RcvAvail7_MSB 0x7 +#define QIB_7322_IntStatus_RcvAvail7_RMASK 0x1 +#define QIB_7322_IntStatus_RcvAvail6_LSB 0x6 +#define QIB_7322_IntStatus_RcvAvail6_MSB 0x6 +#define QIB_7322_IntStatus_RcvAvail6_RMASK 0x1 +#define QIB_7322_IntStatus_RcvAvail5_LSB 0x5 +#define QIB_7322_IntStatus_RcvAvail5_MSB 0x5 +#define QIB_7322_IntStatus_RcvAvail5_RMASK 0x1 +#define QIB_7322_IntStatus_RcvAvail4_LSB 0x4 +#define QIB_7322_IntStatus_RcvAvail4_MSB 0x4 +#define QIB_7322_IntStatus_RcvAvail4_RMASK 0x1 +#define QIB_7322_IntStatus_RcvAvail3_LSB 0x3 +#define QIB_7322_IntStatus_RcvAvail3_MSB 0x3 +#define QIB_7322_IntStatus_RcvAvail3_RMASK 0x1 +#define QIB_7322_IntStatus_RcvAvail2_LSB 0x2 +#define QIB_7322_IntStatus_RcvAvail2_MSB 0x2 +#define QIB_7322_IntStatus_RcvAvail2_RMASK 0x1 +#define QIB_7322_IntStatus_RcvAvail1_LSB 0x1 +#define QIB_7322_IntStatus_RcvAvail1_MSB 0x1 +#define QIB_7322_IntStatus_RcvAvail1_RMASK 0x1 +#define QIB_7322_IntStatus_RcvAvail0_LSB 0x0 +#define QIB_7322_IntStatus_RcvAvail0_MSB 0x0 +#define QIB_7322_IntStatus_RcvAvail0_RMASK 0x1 + +#define QIB_7322_IntClear_OFFS 0x78 +#define QIB_7322_IntClear_DEF 0x0000000000000000 +#define QIB_7322_IntClear_SDmaIntClear_1_LSB 0x3F +#define QIB_7322_IntClear_SDmaIntClear_1_MSB 0x3F +#define QIB_7322_IntClear_SDmaIntClear_1_RMASK 0x1 +#define QIB_7322_IntClear_SDmaIntClear_0_LSB 0x3E +#define QIB_7322_IntClear_SDmaIntClear_0_MSB 0x3E +#define QIB_7322_IntClear_SDmaIntClear_0_RMASK 0x1 +#define QIB_7322_IntClear_SDmaProgressIntClear_1_LSB 0x3D +#define QIB_7322_IntClear_SDmaProgressIntClear_1_MSB 0x3D +#define QIB_7322_IntClear_SDmaProgressIntClear_1_RMASK 0x1 +#define QIB_7322_IntClear_SDmaProgressIntClear_0_LSB 0x3C +#define QIB_7322_IntClear_SDmaProgressIntClear_0_MSB 0x3C +#define QIB_7322_IntClear_SDmaProgressIntClear_0_RMASK 0x1 +#define QIB_7322_IntClear_SDmaIdleIntClear_1_LSB 0x3B +#define QIB_7322_IntClear_SDmaIdleIntClear_1_MSB 0x3B +#define QIB_7322_IntClear_SDmaIdleIntClear_1_RMASK 0x1 +#define QIB_7322_IntClear_SDmaIdleIntClear_0_LSB 0x3A +#define QIB_7322_IntClear_SDmaIdleIntClear_0_MSB 0x3A +#define QIB_7322_IntClear_SDmaIdleIntClear_0_RMASK 0x1 +#define QIB_7322_IntClear_SDmaCleanupDoneClear_1_LSB 0x39 +#define QIB_7322_IntClear_SDmaCleanupDoneClear_1_MSB 0x39 +#define QIB_7322_IntClear_SDmaCleanupDoneClear_1_RMASK 0x1 +#define QIB_7322_IntClear_SDmaCleanupDoneClear_0_LSB 0x38 +#define QIB_7322_IntClear_SDmaCleanupDoneClear_0_MSB 0x38 +#define QIB_7322_IntClear_SDmaCleanupDoneClear_0_RMASK 0x1 +#define QIB_7322_IntClear_RcvUrg17IntClear_LSB 0x31 +#define QIB_7322_IntClear_RcvUrg17IntClear_MSB 0x31 +#define QIB_7322_IntClear_RcvUrg17IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvUrg16IntClear_LSB 0x30 +#define QIB_7322_IntClear_RcvUrg16IntClear_MSB 0x30 +#define QIB_7322_IntClear_RcvUrg16IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvUrg15IntClear_LSB 0x2F +#define QIB_7322_IntClear_RcvUrg15IntClear_MSB 0x2F +#define QIB_7322_IntClear_RcvUrg15IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvUrg14IntClear_LSB 0x2E +#define QIB_7322_IntClear_RcvUrg14IntClear_MSB 0x2E +#define QIB_7322_IntClear_RcvUrg14IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvUrg13IntClear_LSB 0x2D +#define QIB_7322_IntClear_RcvUrg13IntClear_MSB 0x2D +#define QIB_7322_IntClear_RcvUrg13IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvUrg12IntClear_LSB 0x2C +#define QIB_7322_IntClear_RcvUrg12IntClear_MSB 0x2C +#define QIB_7322_IntClear_RcvUrg12IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvUrg11IntClear_LSB 0x2B +#define QIB_7322_IntClear_RcvUrg11IntClear_MSB 0x2B +#define QIB_7322_IntClear_RcvUrg11IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvUrg10IntClear_LSB 0x2A +#define QIB_7322_IntClear_RcvUrg10IntClear_MSB 0x2A +#define QIB_7322_IntClear_RcvUrg10IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvUrg9IntClear_LSB 0x29 +#define QIB_7322_IntClear_RcvUrg9IntClear_MSB 0x29 +#define QIB_7322_IntClear_RcvUrg9IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvUrg8IntClear_LSB 0x28 +#define QIB_7322_IntClear_RcvUrg8IntClear_MSB 0x28 +#define QIB_7322_IntClear_RcvUrg8IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvUrg7IntClear_LSB 0x27 +#define QIB_7322_IntClear_RcvUrg7IntClear_MSB 0x27 +#define QIB_7322_IntClear_RcvUrg7IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvUrg6IntClear_LSB 0x26 +#define QIB_7322_IntClear_RcvUrg6IntClear_MSB 0x26 +#define QIB_7322_IntClear_RcvUrg6IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvUrg5IntClear_LSB 0x25 +#define QIB_7322_IntClear_RcvUrg5IntClear_MSB 0x25 +#define QIB_7322_IntClear_RcvUrg5IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvUrg4IntClear_LSB 0x24 +#define QIB_7322_IntClear_RcvUrg4IntClear_MSB 0x24 +#define QIB_7322_IntClear_RcvUrg4IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvUrg3IntClear_LSB 0x23 +#define QIB_7322_IntClear_RcvUrg3IntClear_MSB 0x23 +#define QIB_7322_IntClear_RcvUrg3IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvUrg2IntClear_LSB 0x22 +#define QIB_7322_IntClear_RcvUrg2IntClear_MSB 0x22 +#define QIB_7322_IntClear_RcvUrg2IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvUrg1IntClear_LSB 0x21 +#define QIB_7322_IntClear_RcvUrg1IntClear_MSB 0x21 +#define QIB_7322_IntClear_RcvUrg1IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvUrg0IntClear_LSB 0x20 +#define QIB_7322_IntClear_RcvUrg0IntClear_MSB 0x20 +#define QIB_7322_IntClear_RcvUrg0IntClear_RMASK 0x1 +#define QIB_7322_IntClear_ErrIntClear_1_LSB 0x1F +#define QIB_7322_IntClear_ErrIntClear_1_MSB 0x1F +#define QIB_7322_IntClear_ErrIntClear_1_RMASK 0x1 +#define QIB_7322_IntClear_ErrIntClear_0_LSB 0x1E +#define QIB_7322_IntClear_ErrIntClear_0_MSB 0x1E +#define QIB_7322_IntClear_ErrIntClear_0_RMASK 0x1 +#define QIB_7322_IntClear_ErrIntClear_LSB 0x1D +#define QIB_7322_IntClear_ErrIntClear_MSB 0x1D +#define QIB_7322_IntClear_ErrIntClear_RMASK 0x1 +#define QIB_7322_IntClear_AssertGPIOIntClear_LSB 0x1C +#define QIB_7322_IntClear_AssertGPIOIntClear_MSB 0x1C +#define QIB_7322_IntClear_AssertGPIOIntClear_RMASK 0x1 +#define QIB_7322_IntClear_SendDoneIntClear_1_LSB 0x19 +#define QIB_7322_IntClear_SendDoneIntClear_1_MSB 0x19 +#define QIB_7322_IntClear_SendDoneIntClear_1_RMASK 0x1 +#define QIB_7322_IntClear_SendDoneIntClear_0_LSB 0x18 +#define QIB_7322_IntClear_SendDoneIntClear_0_MSB 0x18 +#define QIB_7322_IntClear_SendDoneIntClear_0_RMASK 0x1 +#define QIB_7322_IntClear_SendBufAvailIntClear_LSB 0x17 +#define QIB_7322_IntClear_SendBufAvailIntClear_MSB 0x17 +#define QIB_7322_IntClear_SendBufAvailIntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvAvail17IntClear_LSB 0x11 +#define QIB_7322_IntClear_RcvAvail17IntClear_MSB 0x11 +#define QIB_7322_IntClear_RcvAvail17IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvAvail16IntClear_LSB 0x10 +#define QIB_7322_IntClear_RcvAvail16IntClear_MSB 0x10 +#define QIB_7322_IntClear_RcvAvail16IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvAvail15IntClear_LSB 0xF +#define QIB_7322_IntClear_RcvAvail15IntClear_MSB 0xF +#define QIB_7322_IntClear_RcvAvail15IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvAvail14IntClear_LSB 0xE +#define QIB_7322_IntClear_RcvAvail14IntClear_MSB 0xE +#define QIB_7322_IntClear_RcvAvail14IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvAvail13IntClear_LSB 0xD +#define QIB_7322_IntClear_RcvAvail13IntClear_MSB 0xD +#define QIB_7322_IntClear_RcvAvail13IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvAvail12IntClear_LSB 0xC +#define QIB_7322_IntClear_RcvAvail12IntClear_MSB 0xC +#define QIB_7322_IntClear_RcvAvail12IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvAvail11IntClear_LSB 0xB +#define QIB_7322_IntClear_RcvAvail11IntClear_MSB 0xB +#define QIB_7322_IntClear_RcvAvail11IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvAvail10IntClear_LSB 0xA +#define QIB_7322_IntClear_RcvAvail10IntClear_MSB 0xA +#define QIB_7322_IntClear_RcvAvail10IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvAvail9IntClear_LSB 0x9 +#define QIB_7322_IntClear_RcvAvail9IntClear_MSB 0x9 +#define QIB_7322_IntClear_RcvAvail9IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvAvail8IntClear_LSB 0x8 +#define QIB_7322_IntClear_RcvAvail8IntClear_MSB 0x8 +#define QIB_7322_IntClear_RcvAvail8IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvAvail7IntClear_LSB 0x7 +#define QIB_7322_IntClear_RcvAvail7IntClear_MSB 0x7 +#define QIB_7322_IntClear_RcvAvail7IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvAvail6IntClear_LSB 0x6 +#define QIB_7322_IntClear_RcvAvail6IntClear_MSB 0x6 +#define QIB_7322_IntClear_RcvAvail6IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvAvail5IntClear_LSB 0x5 +#define QIB_7322_IntClear_RcvAvail5IntClear_MSB 0x5 +#define QIB_7322_IntClear_RcvAvail5IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvAvail4IntClear_LSB 0x4 +#define QIB_7322_IntClear_RcvAvail4IntClear_MSB 0x4 +#define QIB_7322_IntClear_RcvAvail4IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvAvail3IntClear_LSB 0x3 +#define QIB_7322_IntClear_RcvAvail3IntClear_MSB 0x3 +#define QIB_7322_IntClear_RcvAvail3IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvAvail2IntClear_LSB 0x2 +#define QIB_7322_IntClear_RcvAvail2IntClear_MSB 0x2 +#define QIB_7322_IntClear_RcvAvail2IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvAvail1IntClear_LSB 0x1 +#define QIB_7322_IntClear_RcvAvail1IntClear_MSB 0x1 +#define QIB_7322_IntClear_RcvAvail1IntClear_RMASK 0x1 +#define QIB_7322_IntClear_RcvAvail0IntClear_LSB 0x0 +#define QIB_7322_IntClear_RcvAvail0IntClear_MSB 0x0 +#define QIB_7322_IntClear_RcvAvail0IntClear_RMASK 0x1 + +#define QIB_7322_ErrMask_OFFS 0x80 +#define QIB_7322_ErrMask_DEF 0x0000000000000000 +#define QIB_7322_ErrMask_ResetNegatedMask_LSB 0x3F +#define QIB_7322_ErrMask_ResetNegatedMask_MSB 0x3F +#define QIB_7322_ErrMask_ResetNegatedMask_RMASK 0x1 +#define QIB_7322_ErrMask_HardwareErrMask_LSB 0x3E +#define QIB_7322_ErrMask_HardwareErrMask_MSB 0x3E +#define QIB_7322_ErrMask_HardwareErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_InvalidAddrErrMask_LSB 0x3D +#define QIB_7322_ErrMask_InvalidAddrErrMask_MSB 0x3D +#define QIB_7322_ErrMask_InvalidAddrErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_SDmaVL15ErrMask_LSB 0x38 +#define QIB_7322_ErrMask_SDmaVL15ErrMask_MSB 0x38 +#define QIB_7322_ErrMask_SDmaVL15ErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_SBufVL15MisUseErrMask_LSB 0x37 +#define QIB_7322_ErrMask_SBufVL15MisUseErrMask_MSB 0x37 +#define QIB_7322_ErrMask_SBufVL15MisUseErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_InvalidEEPCmdMask_LSB 0x35 +#define QIB_7322_ErrMask_InvalidEEPCmdMask_MSB 0x35 +#define QIB_7322_ErrMask_InvalidEEPCmdMask_RMASK 0x1 +#define QIB_7322_ErrMask_RcvContextShareErrMask_LSB 0x34 +#define QIB_7322_ErrMask_RcvContextShareErrMask_MSB 0x34 +#define QIB_7322_ErrMask_RcvContextShareErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_SendVLMismatchErrMask_LSB 0x24 +#define QIB_7322_ErrMask_SendVLMismatchErrMask_MSB 0x24 +#define QIB_7322_ErrMask_SendVLMismatchErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_SendArmLaunchErrMask_LSB 0x23 +#define QIB_7322_ErrMask_SendArmLaunchErrMask_MSB 0x23 +#define QIB_7322_ErrMask_SendArmLaunchErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_SendSpecialTriggerErrMask_LSB 0x1B +#define QIB_7322_ErrMask_SendSpecialTriggerErrMask_MSB 0x1B +#define QIB_7322_ErrMask_SendSpecialTriggerErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_SDmaWrongPortErrMask_LSB 0x1A +#define QIB_7322_ErrMask_SDmaWrongPortErrMask_MSB 0x1A +#define QIB_7322_ErrMask_SDmaWrongPortErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_SDmaBufMaskDuplicateErrMask_LSB 0x19 +#define QIB_7322_ErrMask_SDmaBufMaskDuplicateErrMask_MSB 0x19 +#define QIB_7322_ErrMask_SDmaBufMaskDuplicateErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_RcvHdrFullErrMask_LSB 0xD +#define QIB_7322_ErrMask_RcvHdrFullErrMask_MSB 0xD +#define QIB_7322_ErrMask_RcvHdrFullErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_RcvEgrFullErrMask_LSB 0xC +#define QIB_7322_ErrMask_RcvEgrFullErrMask_MSB 0xC +#define QIB_7322_ErrMask_RcvEgrFullErrMask_RMASK 0x1 + +#define QIB_7322_ErrStatus_OFFS 0x88 +#define QIB_7322_ErrStatus_DEF 0x0000000000000000 +#define QIB_7322_ErrStatus_ResetNegated_LSB 0x3F +#define QIB_7322_ErrStatus_ResetNegated_MSB 0x3F +#define QIB_7322_ErrStatus_ResetNegated_RMASK 0x1 +#define QIB_7322_ErrStatus_HardwareErr_LSB 0x3E +#define QIB_7322_ErrStatus_HardwareErr_MSB 0x3E +#define QIB_7322_ErrStatus_HardwareErr_RMASK 0x1 +#define QIB_7322_ErrStatus_InvalidAddrErr_LSB 0x3D +#define QIB_7322_ErrStatus_InvalidAddrErr_MSB 0x3D +#define QIB_7322_ErrStatus_InvalidAddrErr_RMASK 0x1 +#define QIB_7322_ErrStatus_SDmaVL15Err_LSB 0x38 +#define QIB_7322_ErrStatus_SDmaVL15Err_MSB 0x38 +#define QIB_7322_ErrStatus_SDmaVL15Err_RMASK 0x1 +#define QIB_7322_ErrStatus_SBufVL15MisUseErr_LSB 0x37 +#define QIB_7322_ErrStatus_SBufVL15MisUseErr_MSB 0x37 +#define QIB_7322_ErrStatus_SBufVL15MisUseErr_RMASK 0x1 +#define QIB_7322_ErrStatus_InvalidEEPCmdErr_LSB 0x35 +#define QIB_7322_ErrStatus_InvalidEEPCmdErr_MSB 0x35 +#define QIB_7322_ErrStatus_InvalidEEPCmdErr_RMASK 0x1 +#define QIB_7322_ErrStatus_RcvContextShareErr_LSB 0x34 +#define QIB_7322_ErrStatus_RcvContextShareErr_MSB 0x34 +#define QIB_7322_ErrStatus_RcvContextShareErr_RMASK 0x1 +#define QIB_7322_ErrStatus_SendVLMismatchErr_LSB 0x24 +#define QIB_7322_ErrStatus_SendVLMismatchErr_MSB 0x24 +#define QIB_7322_ErrStatus_SendVLMismatchErr_RMASK 0x1 +#define QIB_7322_ErrStatus_SendArmLaunchErr_LSB 0x23 +#define QIB_7322_ErrStatus_SendArmLaunchErr_MSB 0x23 +#define QIB_7322_ErrStatus_SendArmLaunchErr_RMASK 0x1 +#define QIB_7322_ErrStatus_SendSpecialTriggerErr_LSB 0x1B +#define QIB_7322_ErrStatus_SendSpecialTriggerErr_MSB 0x1B +#define QIB_7322_ErrStatus_SendSpecialTriggerErr_RMASK 0x1 +#define QIB_7322_ErrStatus_SDmaWrongPortErr_LSB 0x1A +#define QIB_7322_ErrStatus_SDmaWrongPortErr_MSB 0x1A +#define QIB_7322_ErrStatus_SDmaWrongPortErr_RMASK 0x1 +#define QIB_7322_ErrStatus_SDmaBufMaskDuplicateErr_LSB 0x19 +#define QIB_7322_ErrStatus_SDmaBufMaskDuplicateErr_MSB 0x19 +#define QIB_7322_ErrStatus_SDmaBufMaskDuplicateErr_RMASK 0x1 +#define QIB_7322_ErrStatus_RcvHdrFullErr_LSB 0xD +#define QIB_7322_ErrStatus_RcvHdrFullErr_MSB 0xD +#define QIB_7322_ErrStatus_RcvHdrFullErr_RMASK 0x1 +#define QIB_7322_ErrStatus_RcvEgrFullErr_LSB 0xC +#define QIB_7322_ErrStatus_RcvEgrFullErr_MSB 0xC +#define QIB_7322_ErrStatus_RcvEgrFullErr_RMASK 0x1 + +#define QIB_7322_ErrClear_OFFS 0x90 +#define QIB_7322_ErrClear_DEF 0x0000000000000000 +#define QIB_7322_ErrClear_ResetNegatedClear_LSB 0x3F +#define QIB_7322_ErrClear_ResetNegatedClear_MSB 0x3F +#define QIB_7322_ErrClear_ResetNegatedClear_RMASK 0x1 +#define QIB_7322_ErrClear_HardwareErrClear_LSB 0x3E +#define QIB_7322_ErrClear_HardwareErrClear_MSB 0x3E +#define QIB_7322_ErrClear_HardwareErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_InvalidAddrErrClear_LSB 0x3D +#define QIB_7322_ErrClear_InvalidAddrErrClear_MSB 0x3D +#define QIB_7322_ErrClear_InvalidAddrErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_SDmaVL15ErrClear_LSB 0x38 +#define QIB_7322_ErrClear_SDmaVL15ErrClear_MSB 0x38 +#define QIB_7322_ErrClear_SDmaVL15ErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_SBufVL15MisUseErrClear_LSB 0x37 +#define QIB_7322_ErrClear_SBufVL15MisUseErrClear_MSB 0x37 +#define QIB_7322_ErrClear_SBufVL15MisUseErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_InvalidEEPCmdErrClear_LSB 0x35 +#define QIB_7322_ErrClear_InvalidEEPCmdErrClear_MSB 0x35 +#define QIB_7322_ErrClear_InvalidEEPCmdErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_RcvContextShareErrClear_LSB 0x34 +#define QIB_7322_ErrClear_RcvContextShareErrClear_MSB 0x34 +#define QIB_7322_ErrClear_RcvContextShareErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_SendVLMismatchErrMask_LSB 0x24 +#define QIB_7322_ErrClear_SendVLMismatchErrMask_MSB 0x24 +#define QIB_7322_ErrClear_SendVLMismatchErrMask_RMASK 0x1 +#define QIB_7322_ErrClear_SendArmLaunchErrClear_LSB 0x23 +#define QIB_7322_ErrClear_SendArmLaunchErrClear_MSB 0x23 +#define QIB_7322_ErrClear_SendArmLaunchErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_SendSpecialTriggerErrClear_LSB 0x1B +#define QIB_7322_ErrClear_SendSpecialTriggerErrClear_MSB 0x1B +#define QIB_7322_ErrClear_SendSpecialTriggerErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_SDmaWrongPortErrClear_LSB 0x1A +#define QIB_7322_ErrClear_SDmaWrongPortErrClear_MSB 0x1A +#define QIB_7322_ErrClear_SDmaWrongPortErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_SDmaBufMaskDuplicateErrClear_LSB 0x19 +#define QIB_7322_ErrClear_SDmaBufMaskDuplicateErrClear_MSB 0x19 +#define QIB_7322_ErrClear_SDmaBufMaskDuplicateErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_RcvHdrFullErrClear_LSB 0xD +#define QIB_7322_ErrClear_RcvHdrFullErrClear_MSB 0xD +#define QIB_7322_ErrClear_RcvHdrFullErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_RcvEgrFullErrClear_LSB 0xC +#define QIB_7322_ErrClear_RcvEgrFullErrClear_MSB 0xC +#define QIB_7322_ErrClear_RcvEgrFullErrClear_RMASK 0x1 + +#define QIB_7322_HwErrMask_OFFS 0x98 +#define QIB_7322_HwErrMask_DEF 0x0000000000000000 +#define QIB_7322_HwErrMask_IBSerdesPClkNotDetectMask_1_LSB 0x3F +#define QIB_7322_HwErrMask_IBSerdesPClkNotDetectMask_1_MSB 0x3F +#define QIB_7322_HwErrMask_IBSerdesPClkNotDetectMask_1_RMASK 0x1 +#define QIB_7322_HwErrMask_IBSerdesPClkNotDetectMask_0_LSB 0x3E +#define QIB_7322_HwErrMask_IBSerdesPClkNotDetectMask_0_MSB 0x3E +#define QIB_7322_HwErrMask_IBSerdesPClkNotDetectMask_0_RMASK 0x1 +#define QIB_7322_HwErrMask_PCIESerdesPClkNotDetectMask_LSB 0x37 +#define QIB_7322_HwErrMask_PCIESerdesPClkNotDetectMask_MSB 0x37 +#define QIB_7322_HwErrMask_PCIESerdesPClkNotDetectMask_RMASK 0x1 +#define QIB_7322_HwErrMask_PowerOnBISTFailedMask_LSB 0x36 +#define QIB_7322_HwErrMask_PowerOnBISTFailedMask_MSB 0x36 +#define QIB_7322_HwErrMask_PowerOnBISTFailedMask_RMASK 0x1 +#define QIB_7322_HwErrMask_TempsenseTholdReachedMask_LSB 0x35 +#define QIB_7322_HwErrMask_TempsenseTholdReachedMask_MSB 0x35 +#define QIB_7322_HwErrMask_TempsenseTholdReachedMask_RMASK 0x1 +#define QIB_7322_HwErrMask_MemoryErrMask_LSB 0x30 +#define QIB_7322_HwErrMask_MemoryErrMask_MSB 0x30 +#define QIB_7322_HwErrMask_MemoryErrMask_RMASK 0x1 +#define QIB_7322_HwErrMask_pcie_phy_txParityErr_LSB 0x22 +#define QIB_7322_HwErrMask_pcie_phy_txParityErr_MSB 0x22 +#define QIB_7322_HwErrMask_pcie_phy_txParityErr_RMASK 0x1 +#define QIB_7322_HwErrMask_PCIeBusParityErrMask_LSB 0x1F +#define QIB_7322_HwErrMask_PCIeBusParityErrMask_MSB 0x21 +#define QIB_7322_HwErrMask_PCIeBusParityErrMask_RMASK 0x7 +#define QIB_7322_HwErrMask_PcieCplTimeoutMask_LSB 0x1E +#define QIB_7322_HwErrMask_PcieCplTimeoutMask_MSB 0x1E +#define QIB_7322_HwErrMask_PcieCplTimeoutMask_RMASK 0x1 +#define QIB_7322_HwErrMask_PciePoisonedTLPMask_LSB 0x1D +#define QIB_7322_HwErrMask_PciePoisonedTLPMask_MSB 0x1D +#define QIB_7322_HwErrMask_PciePoisonedTLPMask_RMASK 0x1 +#define QIB_7322_HwErrMask_SDmaMemReadErrMask_1_LSB 0x1C +#define QIB_7322_HwErrMask_SDmaMemReadErrMask_1_MSB 0x1C +#define QIB_7322_HwErrMask_SDmaMemReadErrMask_1_RMASK 0x1 +#define QIB_7322_HwErrMask_SDmaMemReadErrMask_0_LSB 0x1B +#define QIB_7322_HwErrMask_SDmaMemReadErrMask_0_MSB 0x1B +#define QIB_7322_HwErrMask_SDmaMemReadErrMask_0_RMASK 0x1 +#define QIB_7322_HwErrMask_IBCBusFromSPCParityErrMask_1_LSB 0xF +#define QIB_7322_HwErrMask_IBCBusFromSPCParityErrMask_1_MSB 0xF +#define QIB_7322_HwErrMask_IBCBusFromSPCParityErrMask_1_RMASK 0x1 +#define QIB_7322_HwErrMask_statusValidNoEopMask_1_LSB 0xE +#define QIB_7322_HwErrMask_statusValidNoEopMask_1_MSB 0xE +#define QIB_7322_HwErrMask_statusValidNoEopMask_1_RMASK 0x1 +#define QIB_7322_HwErrMask_IBCBusFromSPCParityErrMask_0_LSB 0xD +#define QIB_7322_HwErrMask_IBCBusFromSPCParityErrMask_0_MSB 0xD +#define QIB_7322_HwErrMask_IBCBusFromSPCParityErrMask_0_RMASK 0x1 +#define QIB_7322_HwErrMask_statusValidNoEopMask_0_LSB 0xC +#define QIB_7322_HwErrMask_statusValidNoEopMask_0_MSB 0xC +#define QIB_7322_HwErrMask_statusValidNoEopMask_0_RMASK 0x1 +#define QIB_7322_HwErrMask_LATriggeredMask_LSB 0xB +#define QIB_7322_HwErrMask_LATriggeredMask_MSB 0xB +#define QIB_7322_HwErrMask_LATriggeredMask_RMASK 0x1 + +#define QIB_7322_HwErrStatus_OFFS 0xA0 +#define QIB_7322_HwErrStatus_DEF 0x0000000000000000 +#define QIB_7322_HwErrStatus_IBSerdesPClkNotDetect_1_LSB 0x3F +#define QIB_7322_HwErrStatus_IBSerdesPClkNotDetect_1_MSB 0x3F +#define QIB_7322_HwErrStatus_IBSerdesPClkNotDetect_1_RMASK 0x1 +#define QIB_7322_HwErrStatus_IBSerdesPClkNotDetect_0_LSB 0x3E +#define QIB_7322_HwErrStatus_IBSerdesPClkNotDetect_0_MSB 0x3E +#define QIB_7322_HwErrStatus_IBSerdesPClkNotDetect_0_RMASK 0x1 +#define QIB_7322_HwErrStatus_PCIESerdesPClkNotDetect_LSB 0x37 +#define QIB_7322_HwErrStatus_PCIESerdesPClkNotDetect_MSB 0x37 +#define QIB_7322_HwErrStatus_PCIESerdesPClkNotDetect_RMASK 0x1 +#define QIB_7322_HwErrStatus_PowerOnBISTFailed_LSB 0x36 +#define QIB_7322_HwErrStatus_PowerOnBISTFailed_MSB 0x36 +#define QIB_7322_HwErrStatus_PowerOnBISTFailed_RMASK 0x1 +#define QIB_7322_HwErrStatus_TempsenseTholdReached_LSB 0x35 +#define QIB_7322_HwErrStatus_TempsenseTholdReached_MSB 0x35 +#define QIB_7322_HwErrStatus_TempsenseTholdReached_RMASK 0x1 +#define QIB_7322_HwErrStatus_MemoryErr_LSB 0x30 +#define QIB_7322_HwErrStatus_MemoryErr_MSB 0x30 +#define QIB_7322_HwErrStatus_MemoryErr_RMASK 0x1 +#define QIB_7322_HwErrStatus_pcie_phy_txParityErr_LSB 0x22 +#define QIB_7322_HwErrStatus_pcie_phy_txParityErr_MSB 0x22 +#define QIB_7322_HwErrStatus_pcie_phy_txParityErr_RMASK 0x1 +#define QIB_7322_HwErrStatus_PCIeBusParity_LSB 0x1F +#define QIB_7322_HwErrStatus_PCIeBusParity_MSB 0x21 +#define QIB_7322_HwErrStatus_PCIeBusParity_RMASK 0x7 +#define QIB_7322_HwErrStatus_PcieCplTimeout_LSB 0x1E +#define QIB_7322_HwErrStatus_PcieCplTimeout_MSB 0x1E +#define QIB_7322_HwErrStatus_PcieCplTimeout_RMASK 0x1 +#define QIB_7322_HwErrStatus_PciePoisonedTLP_LSB 0x1D +#define QIB_7322_HwErrStatus_PciePoisonedTLP_MSB 0x1D +#define QIB_7322_HwErrStatus_PciePoisonedTLP_RMASK 0x1 +#define QIB_7322_HwErrStatus_SDmaMemReadErr_1_LSB 0x1C +#define QIB_7322_HwErrStatus_SDmaMemReadErr_1_MSB 0x1C +#define QIB_7322_HwErrStatus_SDmaMemReadErr_1_RMASK 0x1 +#define QIB_7322_HwErrStatus_SDmaMemReadErr_0_LSB 0x1B +#define QIB_7322_HwErrStatus_SDmaMemReadErr_0_MSB 0x1B +#define QIB_7322_HwErrStatus_SDmaMemReadErr_0_RMASK 0x1 +#define QIB_7322_HwErrStatus_IBCBusFromSPCParityErr_1_LSB 0xF +#define QIB_7322_HwErrStatus_IBCBusFromSPCParityErr_1_MSB 0xF +#define QIB_7322_HwErrStatus_IBCBusFromSPCParityErr_1_RMASK 0x1 +#define QIB_7322_HwErrStatus_statusValidNoEop_1_LSB 0xE +#define QIB_7322_HwErrStatus_statusValidNoEop_1_MSB 0xE +#define QIB_7322_HwErrStatus_statusValidNoEop_1_RMASK 0x1 +#define QIB_7322_HwErrStatus_IBCBusFromSPCParityErr_0_LSB 0xD +#define QIB_7322_HwErrStatus_IBCBusFromSPCParityErr_0_MSB 0xD +#define QIB_7322_HwErrStatus_IBCBusFromSPCParityErr_0_RMASK 0x1 +#define QIB_7322_HwErrStatus_statusValidNoEop_0_LSB 0xC +#define QIB_7322_HwErrStatus_statusValidNoEop_0_MSB 0xC +#define QIB_7322_HwErrStatus_statusValidNoEop_0_RMASK 0x1 +#define QIB_7322_HwErrStatus_LATriggered_LSB 0xB +#define QIB_7322_HwErrStatus_LATriggered_MSB 0xB +#define QIB_7322_HwErrStatus_LATriggered_RMASK 0x1 + +#define QIB_7322_HwErrClear_OFFS 0xA8 +#define QIB_7322_HwErrClear_DEF 0x0000000000000000 +#define QIB_7322_HwErrClear_IBSerdesPClkNotDetectClear_1_LSB 0x3F +#define QIB_7322_HwErrClear_IBSerdesPClkNotDetectClear_1_MSB 0x3F +#define QIB_7322_HwErrClear_IBSerdesPClkNotDetectClear_1_RMASK 0x1 +#define QIB_7322_HwErrClear_IBSerdesPClkNotDetectClear_0_LSB 0x3E +#define QIB_7322_HwErrClear_IBSerdesPClkNotDetectClear_0_MSB 0x3E +#define QIB_7322_HwErrClear_IBSerdesPClkNotDetectClear_0_RMASK 0x1 +#define QIB_7322_HwErrClear_PCIESerdesPClkNotDetectClear_LSB 0x37 +#define QIB_7322_HwErrClear_PCIESerdesPClkNotDetectClear_MSB 0x37 +#define QIB_7322_HwErrClear_PCIESerdesPClkNotDetectClear_RMASK 0x1 +#define QIB_7322_HwErrClear_PowerOnBISTFailedClear_LSB 0x36 +#define QIB_7322_HwErrClear_PowerOnBISTFailedClear_MSB 0x36 +#define QIB_7322_HwErrClear_PowerOnBISTFailedClear_RMASK 0x1 +#define QIB_7322_HwErrClear_TempsenseTholdReachedClear_LSB 0x35 +#define QIB_7322_HwErrClear_TempsenseTholdReachedClear_MSB 0x35 +#define QIB_7322_HwErrClear_TempsenseTholdReachedClear_RMASK 0x1 +#define QIB_7322_HwErrClear_MemoryErrClear_LSB 0x30 +#define QIB_7322_HwErrClear_MemoryErrClear_MSB 0x30 +#define QIB_7322_HwErrClear_MemoryErrClear_RMASK 0x1 +#define QIB_7322_HwErrClear_pcie_phy_txParityErr_LSB 0x22 +#define QIB_7322_HwErrClear_pcie_phy_txParityErr_MSB 0x22 +#define QIB_7322_HwErrClear_pcie_phy_txParityErr_RMASK 0x1 +#define QIB_7322_HwErrClear_PCIeBusParityClear_LSB 0x1F +#define QIB_7322_HwErrClear_PCIeBusParityClear_MSB 0x21 +#define QIB_7322_HwErrClear_PCIeBusParityClear_RMASK 0x7 +#define QIB_7322_HwErrClear_PcieCplTimeoutClear_LSB 0x1E +#define QIB_7322_HwErrClear_PcieCplTimeoutClear_MSB 0x1E +#define QIB_7322_HwErrClear_PcieCplTimeoutClear_RMASK 0x1 +#define QIB_7322_HwErrClear_PciePoisonedTLPClear_LSB 0x1D +#define QIB_7322_HwErrClear_PciePoisonedTLPClear_MSB 0x1D +#define QIB_7322_HwErrClear_PciePoisonedTLPClear_RMASK 0x1 +#define QIB_7322_HwErrClear_SDmaMemReadErrClear_1_LSB 0x1C +#define QIB_7322_HwErrClear_SDmaMemReadErrClear_1_MSB 0x1C +#define QIB_7322_HwErrClear_SDmaMemReadErrClear_1_RMASK 0x1 +#define QIB_7322_HwErrClear_SDmaMemReadErrClear_0_LSB 0x1B +#define QIB_7322_HwErrClear_SDmaMemReadErrClear_0_MSB 0x1B +#define QIB_7322_HwErrClear_SDmaMemReadErrClear_0_RMASK 0x1 +#define QIB_7322_HwErrClear_IBCBusFromSPCParityErrClear_1_LSB 0xF +#define QIB_7322_HwErrClear_IBCBusFromSPCParityErrClear_1_MSB 0xF +#define QIB_7322_HwErrClear_IBCBusFromSPCParityErrClear_1_RMASK 0x1 +#define QIB_7322_HwErrClear_IBCBusToSPCparityErrClear_1_LSB 0xE +#define QIB_7322_HwErrClear_IBCBusToSPCparityErrClear_1_MSB 0xE +#define QIB_7322_HwErrClear_IBCBusToSPCparityErrClear_1_RMASK 0x1 +#define QIB_7322_HwErrClear_IBCBusFromSPCParityErrClear_0_LSB 0xD +#define QIB_7322_HwErrClear_IBCBusFromSPCParityErrClear_0_MSB 0xD +#define QIB_7322_HwErrClear_IBCBusFromSPCParityErrClear_0_RMASK 0x1 +#define QIB_7322_HwErrClear_IBCBusToSPCparityErrClear_0_LSB 0xC +#define QIB_7322_HwErrClear_IBCBusToSPCparityErrClear_0_MSB 0xC +#define QIB_7322_HwErrClear_IBCBusToSPCparityErrClear_0_RMASK 0x1 +#define QIB_7322_HwErrClear_LATriggeredClear_LSB 0xB +#define QIB_7322_HwErrClear_LATriggeredClear_MSB 0xB +#define QIB_7322_HwErrClear_LATriggeredClear_RMASK 0x1 + +#define QIB_7322_HwDiagCtrl_OFFS 0xB0 +#define QIB_7322_HwDiagCtrl_DEF 0x0000000000000000 +#define QIB_7322_HwDiagCtrl_Diagnostic_LSB 0x3F +#define QIB_7322_HwDiagCtrl_Diagnostic_MSB 0x3F +#define QIB_7322_HwDiagCtrl_Diagnostic_RMASK 0x1 +#define QIB_7322_HwDiagCtrl_CounterWrEnable_LSB 0x3D +#define QIB_7322_HwDiagCtrl_CounterWrEnable_MSB 0x3D +#define QIB_7322_HwDiagCtrl_CounterWrEnable_RMASK 0x1 +#define QIB_7322_HwDiagCtrl_CounterDisable_LSB 0x3C +#define QIB_7322_HwDiagCtrl_CounterDisable_MSB 0x3C +#define QIB_7322_HwDiagCtrl_CounterDisable_RMASK 0x1 +#define QIB_7322_HwDiagCtrl_forcePCIeBusParity_LSB 0x1F +#define QIB_7322_HwDiagCtrl_forcePCIeBusParity_MSB 0x22 +#define QIB_7322_HwDiagCtrl_forcePCIeBusParity_RMASK 0xF +#define QIB_7322_HwDiagCtrl_ForceIBCBusFromSPCParityErr_1_LSB 0xF +#define QIB_7322_HwDiagCtrl_ForceIBCBusFromSPCParityErr_1_MSB 0xF +#define QIB_7322_HwDiagCtrl_ForceIBCBusFromSPCParityErr_1_RMASK 0x1 +#define QIB_7322_HwDiagCtrl_ForcestatusValidNoEop_1_LSB 0xE +#define QIB_7322_HwDiagCtrl_ForcestatusValidNoEop_1_MSB 0xE +#define QIB_7322_HwDiagCtrl_ForcestatusValidNoEop_1_RMASK 0x1 +#define QIB_7322_HwDiagCtrl_ForceIBCBusFromSPCParityErr_0_LSB 0xD +#define QIB_7322_HwDiagCtrl_ForceIBCBusFromSPCParityErr_0_MSB 0xD +#define QIB_7322_HwDiagCtrl_ForceIBCBusFromSPCParityErr_0_RMASK 0x1 +#define QIB_7322_HwDiagCtrl_ForcestatusValidNoEop_0_LSB 0xC +#define QIB_7322_HwDiagCtrl_ForcestatusValidNoEop_0_MSB 0xC +#define QIB_7322_HwDiagCtrl_ForcestatusValidNoEop_0_RMASK 0x1 + +#define QIB_7322_EXTStatus_OFFS 0xC0 +#define QIB_7322_EXTStatus_DEF 0x000000000000X000 +#define QIB_7322_EXTStatus_GPIOIn_LSB 0x30 +#define QIB_7322_EXTStatus_GPIOIn_MSB 0x3F +#define QIB_7322_EXTStatus_GPIOIn_RMASK 0xFFFF +#define QIB_7322_EXTStatus_MemBISTDisabled_LSB 0xF +#define QIB_7322_EXTStatus_MemBISTDisabled_MSB 0xF +#define QIB_7322_EXTStatus_MemBISTDisabled_RMASK 0x1 +#define QIB_7322_EXTStatus_MemBISTEndTest_LSB 0xE +#define QIB_7322_EXTStatus_MemBISTEndTest_MSB 0xE +#define QIB_7322_EXTStatus_MemBISTEndTest_RMASK 0x1 + +#define QIB_7322_EXTCtrl_OFFS 0xC8 +#define QIB_7322_EXTCtrl_DEF 0x0000000000000000 +#define QIB_7322_EXTCtrl_GPIOOe_LSB 0x30 +#define QIB_7322_EXTCtrl_GPIOOe_MSB 0x3F +#define QIB_7322_EXTCtrl_GPIOOe_RMASK 0xFFFF +#define QIB_7322_EXTCtrl_GPIOInvert_LSB 0x20 +#define QIB_7322_EXTCtrl_GPIOInvert_MSB 0x2F +#define QIB_7322_EXTCtrl_GPIOInvert_RMASK 0xFFFF +#define QIB_7322_EXTCtrl_LEDPort1GreenOn_LSB 0x3 +#define QIB_7322_EXTCtrl_LEDPort1GreenOn_MSB 0x3 +#define QIB_7322_EXTCtrl_LEDPort1GreenOn_RMASK 0x1 +#define QIB_7322_EXTCtrl_LEDPort1YellowOn_LSB 0x2 +#define QIB_7322_EXTCtrl_LEDPort1YellowOn_MSB 0x2 +#define QIB_7322_EXTCtrl_LEDPort1YellowOn_RMASK 0x1 +#define QIB_7322_EXTCtrl_LEDPort0GreenOn_LSB 0x1 +#define QIB_7322_EXTCtrl_LEDPort0GreenOn_MSB 0x1 +#define QIB_7322_EXTCtrl_LEDPort0GreenOn_RMASK 0x1 +#define QIB_7322_EXTCtrl_LEDPort0YellowOn_LSB 0x0 +#define QIB_7322_EXTCtrl_LEDPort0YellowOn_MSB 0x0 +#define QIB_7322_EXTCtrl_LEDPort0YellowOn_RMASK 0x1 + +#define QIB_7322_GPIOOut_OFFS 0xE0 +#define QIB_7322_GPIOOut_DEF 0x0000000000000000 + +#define QIB_7322_GPIOMask_OFFS 0xE8 +#define QIB_7322_GPIOMask_DEF 0x0000000000000000 + +#define QIB_7322_GPIOStatus_OFFS 0xF0 +#define QIB_7322_GPIOStatus_DEF 0x0000000000000000 + +#define QIB_7322_GPIOClear_OFFS 0xF8 +#define QIB_7322_GPIOClear_DEF 0x0000000000000000 + +#define QIB_7322_RcvCtrl_OFFS 0x100 +#define QIB_7322_RcvCtrl_DEF 0x0000000000000000 +#define QIB_7322_RcvCtrl_TidReDirect_LSB 0x30 +#define QIB_7322_RcvCtrl_TidReDirect_MSB 0x3F +#define QIB_7322_RcvCtrl_TidReDirect_RMASK 0xFFFF +#define QIB_7322_RcvCtrl_TailUpd_LSB 0x2F +#define QIB_7322_RcvCtrl_TailUpd_MSB 0x2F +#define QIB_7322_RcvCtrl_TailUpd_RMASK 0x1 +#define QIB_7322_RcvCtrl_XrcTypeCode_LSB 0x2C +#define QIB_7322_RcvCtrl_XrcTypeCode_MSB 0x2E +#define QIB_7322_RcvCtrl_XrcTypeCode_RMASK 0x7 +#define QIB_7322_RcvCtrl_TidFlowEnable_LSB 0x2B +#define QIB_7322_RcvCtrl_TidFlowEnable_MSB 0x2B +#define QIB_7322_RcvCtrl_TidFlowEnable_RMASK 0x1 +#define QIB_7322_RcvCtrl_ContextCfg_LSB 0x29 +#define QIB_7322_RcvCtrl_ContextCfg_MSB 0x2A +#define QIB_7322_RcvCtrl_ContextCfg_RMASK 0x3 +#define QIB_7322_RcvCtrl_IntrAvail_LSB 0x14 +#define QIB_7322_RcvCtrl_IntrAvail_MSB 0x25 +#define QIB_7322_RcvCtrl_IntrAvail_RMASK 0x3FFFF +#define QIB_7322_RcvCtrl_dontDropRHQFull_LSB 0x0 +#define QIB_7322_RcvCtrl_dontDropRHQFull_MSB 0x11 +#define QIB_7322_RcvCtrl_dontDropRHQFull_RMASK 0x3FFFF + +#define QIB_7322_RcvHdrSize_OFFS 0x110 +#define QIB_7322_RcvHdrSize_DEF 0x0000000000000000 + +#define QIB_7322_RcvHdrCnt_OFFS 0x118 +#define QIB_7322_RcvHdrCnt_DEF 0x0000000000000000 + +#define QIB_7322_RcvHdrEntSize_OFFS 0x120 +#define QIB_7322_RcvHdrEntSize_DEF 0x0000000000000000 + +#define QIB_7322_RcvTIDBase_OFFS 0x128 +#define QIB_7322_RcvTIDBase_DEF 0x0000000000050000 + +#define QIB_7322_RcvTIDCnt_OFFS 0x130 +#define QIB_7322_RcvTIDCnt_DEF 0x0000000000000200 + +#define QIB_7322_RcvEgrBase_OFFS 0x138 +#define QIB_7322_RcvEgrBase_DEF 0x0000000000014000 + +#define QIB_7322_RcvEgrCnt_OFFS 0x140 +#define QIB_7322_RcvEgrCnt_DEF 0x0000000000001000 + +#define QIB_7322_RcvBufBase_OFFS 0x148 +#define QIB_7322_RcvBufBase_DEF 0x0000000000080000 + +#define QIB_7322_RcvBufSize_OFFS 0x150 +#define QIB_7322_RcvBufSize_DEF 0x0000000000005000 + +#define QIB_7322_RxIntMemBase_OFFS 0x158 +#define QIB_7322_RxIntMemBase_DEF 0x0000000000077000 + +#define QIB_7322_RxIntMemSize_OFFS 0x160 +#define QIB_7322_RxIntMemSize_DEF 0x0000000000007000 + +#define QIB_7322_feature_mask_OFFS 0x190 +#define QIB_7322_feature_mask_DEF 0x00000000000000XX + +#define QIB_7322_active_feature_mask_OFFS 0x198 +#define QIB_7322_active_feature_mask_DEF 0x00000000000000XX +#define QIB_7322_active_feature_mask_Port1_QDR_Enabled_LSB 0x5 +#define QIB_7322_active_feature_mask_Port1_QDR_Enabled_MSB 0x5 +#define QIB_7322_active_feature_mask_Port1_QDR_Enabled_RMASK 0x1 +#define QIB_7322_active_feature_mask_Port1_DDR_Enabled_LSB 0x4 +#define QIB_7322_active_feature_mask_Port1_DDR_Enabled_MSB 0x4 +#define QIB_7322_active_feature_mask_Port1_DDR_Enabled_RMASK 0x1 +#define QIB_7322_active_feature_mask_Port1_SDR_Enabled_LSB 0x3 +#define QIB_7322_active_feature_mask_Port1_SDR_Enabled_MSB 0x3 +#define QIB_7322_active_feature_mask_Port1_SDR_Enabled_RMASK 0x1 +#define QIB_7322_active_feature_mask_Port0_QDR_Enabled_LSB 0x2 +#define QIB_7322_active_feature_mask_Port0_QDR_Enabled_MSB 0x2 +#define QIB_7322_active_feature_mask_Port0_QDR_Enabled_RMASK 0x1 +#define QIB_7322_active_feature_mask_Port0_DDR_Enabled_LSB 0x1 +#define QIB_7322_active_feature_mask_Port0_DDR_Enabled_MSB 0x1 +#define QIB_7322_active_feature_mask_Port0_DDR_Enabled_RMASK 0x1 +#define QIB_7322_active_feature_mask_Port0_SDR_Enabled_LSB 0x0 +#define QIB_7322_active_feature_mask_Port0_SDR_Enabled_MSB 0x0 +#define QIB_7322_active_feature_mask_Port0_SDR_Enabled_RMASK 0x1 + +#define QIB_7322_SendCtrl_OFFS 0x1C0 +#define QIB_7322_SendCtrl_DEF 0x0000000000000000 +#define QIB_7322_SendCtrl_Disarm_LSB 0x1F +#define QIB_7322_SendCtrl_Disarm_MSB 0x1F +#define QIB_7322_SendCtrl_Disarm_RMASK 0x1 +#define QIB_7322_SendCtrl_SendBufAvailPad64Byte_LSB 0x1D +#define QIB_7322_SendCtrl_SendBufAvailPad64Byte_MSB 0x1D +#define QIB_7322_SendCtrl_SendBufAvailPad64Byte_RMASK 0x1 +#define QIB_7322_SendCtrl_AvailUpdThld_LSB 0x18 +#define QIB_7322_SendCtrl_AvailUpdThld_MSB 0x1C +#define QIB_7322_SendCtrl_AvailUpdThld_RMASK 0x1F +#define QIB_7322_SendCtrl_DisarmSendBuf_LSB 0x10 +#define QIB_7322_SendCtrl_DisarmSendBuf_MSB 0x17 +#define QIB_7322_SendCtrl_DisarmSendBuf_RMASK 0xFF +#define QIB_7322_SendCtrl_SpecialTriggerEn_LSB 0x4 +#define QIB_7322_SendCtrl_SpecialTriggerEn_MSB 0x4 +#define QIB_7322_SendCtrl_SpecialTriggerEn_RMASK 0x1 +#define QIB_7322_SendCtrl_SendBufAvailUpd_LSB 0x2 +#define QIB_7322_SendCtrl_SendBufAvailUpd_MSB 0x2 +#define QIB_7322_SendCtrl_SendBufAvailUpd_RMASK 0x1 +#define QIB_7322_SendCtrl_SendIntBufAvail_LSB 0x1 +#define QIB_7322_SendCtrl_SendIntBufAvail_MSB 0x1 +#define QIB_7322_SendCtrl_SendIntBufAvail_RMASK 0x1 + +#define QIB_7322_SendBufBase_OFFS 0x1C8 +#define QIB_7322_SendBufBase_DEF 0x0018000000100000 +#define QIB_7322_SendBufBase_BaseAddr_LargePIO_LSB 0x20 +#define QIB_7322_SendBufBase_BaseAddr_LargePIO_MSB 0x34 +#define QIB_7322_SendBufBase_BaseAddr_LargePIO_RMASK 0x1FFFFF +#define QIB_7322_SendBufBase_BaseAddr_SmallPIO_LSB 0x0 +#define QIB_7322_SendBufBase_BaseAddr_SmallPIO_MSB 0x14 +#define QIB_7322_SendBufBase_BaseAddr_SmallPIO_RMASK 0x1FFFFF + +#define QIB_7322_SendBufSize_OFFS 0x1D0 +#define QIB_7322_SendBufSize_DEF 0x0000108000000880 +#define QIB_7322_SendBufSize_Size_LargePIO_LSB 0x20 +#define QIB_7322_SendBufSize_Size_LargePIO_MSB 0x2C +#define QIB_7322_SendBufSize_Size_LargePIO_RMASK 0x1FFF +#define QIB_7322_SendBufSize_Size_SmallPIO_LSB 0x0 +#define QIB_7322_SendBufSize_Size_SmallPIO_MSB 0xB +#define QIB_7322_SendBufSize_Size_SmallPIO_RMASK 0xFFF + +#define QIB_7322_SendBufCnt_OFFS 0x1D8 +#define QIB_7322_SendBufCnt_DEF 0x0000002000000080 +#define QIB_7322_SendBufCnt_Num_LargeBuffers_LSB 0x20 +#define QIB_7322_SendBufCnt_Num_LargeBuffers_MSB 0x25 +#define QIB_7322_SendBufCnt_Num_LargeBuffers_RMASK 0x3F +#define QIB_7322_SendBufCnt_Num_SmallBuffers_LSB 0x0 +#define QIB_7322_SendBufCnt_Num_SmallBuffers_MSB 0x8 +#define QIB_7322_SendBufCnt_Num_SmallBuffers_RMASK 0x1FF + +#define QIB_7322_SendBufAvailAddr_OFFS 0x1E0 +#define QIB_7322_SendBufAvailAddr_DEF 0x0000000000000000 +#define QIB_7322_SendBufAvailAddr_SendBufAvailAddr_LSB 0x6 +#define QIB_7322_SendBufAvailAddr_SendBufAvailAddr_MSB 0x27 +#define QIB_7322_SendBufAvailAddr_SendBufAvailAddr_RMASK 0x3FFFFFFFF + +#define QIB_7322_SendBufErr0_OFFS 0x240 +#define QIB_7322_SendBufErr0_DEF 0x0000000000000000 +#define QIB_7322_SendBufErr0_SendBufErr_63_0_LSB 0x0 +#define QIB_7322_SendBufErr0_SendBufErr_63_0_MSB 0x3F +#define QIB_7322_SendBufErr0_SendBufErr_63_0_RMASK 0x0 + +#define QIB_7322_AvailUpdCount_OFFS 0x268 +#define QIB_7322_AvailUpdCount_DEF 0x0000000000000000 +#define QIB_7322_AvailUpdCount_AvailUpdCount_LSB 0x0 +#define QIB_7322_AvailUpdCount_AvailUpdCount_MSB 0x4 +#define QIB_7322_AvailUpdCount_AvailUpdCount_RMASK 0x1F + +#define QIB_7322_RcvHdrAddr0_OFFS 0x280 +#define QIB_7322_RcvHdrAddr0_DEF 0x0000000000000000 +#define QIB_7322_RcvHdrAddr0_RcvHdrAddr_LSB 0x2 +#define QIB_7322_RcvHdrAddr0_RcvHdrAddr_MSB 0x27 +#define QIB_7322_RcvHdrAddr0_RcvHdrAddr_RMASK 0x3FFFFFFFFF + +#define QIB_7322_RcvHdrTailAddr0_OFFS 0x340 +#define QIB_7322_RcvHdrTailAddr0_DEF 0x0000000000000000 +#define QIB_7322_RcvHdrTailAddr0_RcvHdrTailAddr_LSB 0x2 +#define QIB_7322_RcvHdrTailAddr0_RcvHdrTailAddr_MSB 0x27 +#define QIB_7322_RcvHdrTailAddr0_RcvHdrTailAddr_RMASK 0x3FFFFFFFFF + +#define QIB_7322_ahb_access_ctrl_OFFS 0x460 +#define QIB_7322_ahb_access_ctrl_DEF 0x0000000000000000 +#define QIB_7322_ahb_access_ctrl_sw_sel_ahb_trgt_LSB 0x1 +#define QIB_7322_ahb_access_ctrl_sw_sel_ahb_trgt_MSB 0x2 +#define QIB_7322_ahb_access_ctrl_sw_sel_ahb_trgt_RMASK 0x3 +#define QIB_7322_ahb_access_ctrl_sw_ahb_sel_LSB 0x0 +#define QIB_7322_ahb_access_ctrl_sw_ahb_sel_MSB 0x0 +#define QIB_7322_ahb_access_ctrl_sw_ahb_sel_RMASK 0x1 + +#define QIB_7322_ahb_transaction_reg_OFFS 0x468 +#define QIB_7322_ahb_transaction_reg_DEF 0x0000000080000000 +#define QIB_7322_ahb_transaction_reg_ahb_data_LSB 0x20 +#define QIB_7322_ahb_transaction_reg_ahb_data_MSB 0x3F +#define QIB_7322_ahb_transaction_reg_ahb_data_RMASK 0xFFFFFFFF +#define QIB_7322_ahb_transaction_reg_ahb_rdy_LSB 0x1F +#define QIB_7322_ahb_transaction_reg_ahb_rdy_MSB 0x1F +#define QIB_7322_ahb_transaction_reg_ahb_rdy_RMASK 0x1 +#define QIB_7322_ahb_transaction_reg_ahb_req_err_LSB 0x1E +#define QIB_7322_ahb_transaction_reg_ahb_req_err_MSB 0x1E +#define QIB_7322_ahb_transaction_reg_ahb_req_err_RMASK 0x1 +#define QIB_7322_ahb_transaction_reg_write_not_read_LSB 0x1B +#define QIB_7322_ahb_transaction_reg_write_not_read_MSB 0x1B +#define QIB_7322_ahb_transaction_reg_write_not_read_RMASK 0x1 +#define QIB_7322_ahb_transaction_reg_ahb_address_LSB 0x10 +#define QIB_7322_ahb_transaction_reg_ahb_address_MSB 0x1A +#define QIB_7322_ahb_transaction_reg_ahb_address_RMASK 0x7FF + +#define QIB_7322_SPC_JTAG_ACCESS_REG_OFFS 0x470 +#define QIB_7322_SPC_JTAG_ACCESS_REG_DEF 0x0000000000000001 +#define QIB_7322_SPC_JTAG_ACCESS_REG_SPC_JTAG_ACCESS_EN_LSB 0xA +#define QIB_7322_SPC_JTAG_ACCESS_REG_SPC_JTAG_ACCESS_EN_MSB 0xA +#define QIB_7322_SPC_JTAG_ACCESS_REG_SPC_JTAG_ACCESS_EN_RMASK 0x1 +#define QIB_7322_SPC_JTAG_ACCESS_REG_bist_en_LSB 0x5 +#define QIB_7322_SPC_JTAG_ACCESS_REG_bist_en_MSB 0x9 +#define QIB_7322_SPC_JTAG_ACCESS_REG_bist_en_RMASK 0x1F +#define QIB_7322_SPC_JTAG_ACCESS_REG_opcode_LSB 0x3 +#define QIB_7322_SPC_JTAG_ACCESS_REG_opcode_MSB 0x4 +#define QIB_7322_SPC_JTAG_ACCESS_REG_opcode_RMASK 0x3 +#define QIB_7322_SPC_JTAG_ACCESS_REG_tdi_LSB 0x2 +#define QIB_7322_SPC_JTAG_ACCESS_REG_tdi_MSB 0x2 +#define QIB_7322_SPC_JTAG_ACCESS_REG_tdi_RMASK 0x1 +#define QIB_7322_SPC_JTAG_ACCESS_REG_tdo_LSB 0x1 +#define QIB_7322_SPC_JTAG_ACCESS_REG_tdo_MSB 0x1 +#define QIB_7322_SPC_JTAG_ACCESS_REG_tdo_RMASK 0x1 +#define QIB_7322_SPC_JTAG_ACCESS_REG_rdy_LSB 0x0 +#define QIB_7322_SPC_JTAG_ACCESS_REG_rdy_MSB 0x0 +#define QIB_7322_SPC_JTAG_ACCESS_REG_rdy_RMASK 0x1 + +#define QIB_7322_SendCheckMask0_OFFS 0x4C0 +#define QIB_7322_SendCheckMask0_DEF 0x0000000000000000 +#define QIB_7322_SendCheckMask0_SendCheckMask_63_32_LSB 0x0 +#define QIB_7322_SendCheckMask0_SendCheckMask_63_32_MSB 0x3F +#define QIB_7322_SendCheckMask0_SendCheckMask_63_32_RMASK 0x0 + +#define QIB_7322_SendGRHCheckMask0_OFFS 0x4E0 +#define QIB_7322_SendGRHCheckMask0_DEF 0x0000000000000000 +#define QIB_7322_SendGRHCheckMask0_SendGRHCheckMask_63_32_LSB 0x0 +#define QIB_7322_SendGRHCheckMask0_SendGRHCheckMask_63_32_MSB 0x3F +#define QIB_7322_SendGRHCheckMask0_SendGRHCheckMask_63_32_RMASK 0x0 + +#define QIB_7322_SendIBPacketMask0_OFFS 0x500 +#define QIB_7322_SendIBPacketMask0_DEF 0x0000000000000000 +#define QIB_7322_SendIBPacketMask0_SendIBPacketMask_63_32_LSB 0x0 +#define QIB_7322_SendIBPacketMask0_SendIBPacketMask_63_32_MSB 0x3F +#define QIB_7322_SendIBPacketMask0_SendIBPacketMask_63_32_RMASK 0x0 + +#define QIB_7322_IntRedirect0_OFFS 0x540 +#define QIB_7322_IntRedirect0_DEF 0x0000000000000000 +#define QIB_7322_IntRedirect0_vec11_LSB 0x37 +#define QIB_7322_IntRedirect0_vec11_MSB 0x3B +#define QIB_7322_IntRedirect0_vec11_RMASK 0x1F +#define QIB_7322_IntRedirect0_vec10_LSB 0x32 +#define QIB_7322_IntRedirect0_vec10_MSB 0x36 +#define QIB_7322_IntRedirect0_vec10_RMASK 0x1F +#define QIB_7322_IntRedirect0_vec9_LSB 0x2D +#define QIB_7322_IntRedirect0_vec9_MSB 0x31 +#define QIB_7322_IntRedirect0_vec9_RMASK 0x1F +#define QIB_7322_IntRedirect0_vec8_LSB 0x28 +#define QIB_7322_IntRedirect0_vec8_MSB 0x2C +#define QIB_7322_IntRedirect0_vec8_RMASK 0x1F +#define QIB_7322_IntRedirect0_vec7_LSB 0x23 +#define QIB_7322_IntRedirect0_vec7_MSB 0x27 +#define QIB_7322_IntRedirect0_vec7_RMASK 0x1F +#define QIB_7322_IntRedirect0_vec6_LSB 0x1E +#define QIB_7322_IntRedirect0_vec6_MSB 0x22 +#define QIB_7322_IntRedirect0_vec6_RMASK 0x1F +#define QIB_7322_IntRedirect0_vec5_LSB 0x19 +#define QIB_7322_IntRedirect0_vec5_MSB 0x1D +#define QIB_7322_IntRedirect0_vec5_RMASK 0x1F +#define QIB_7322_IntRedirect0_vec4_LSB 0x14 +#define QIB_7322_IntRedirect0_vec4_MSB 0x18 +#define QIB_7322_IntRedirect0_vec4_RMASK 0x1F +#define QIB_7322_IntRedirect0_vec3_LSB 0xF +#define QIB_7322_IntRedirect0_vec3_MSB 0x13 +#define QIB_7322_IntRedirect0_vec3_RMASK 0x1F +#define QIB_7322_IntRedirect0_vec2_LSB 0xA +#define QIB_7322_IntRedirect0_vec2_MSB 0xE +#define QIB_7322_IntRedirect0_vec2_RMASK 0x1F +#define QIB_7322_IntRedirect0_vec1_LSB 0x5 +#define QIB_7322_IntRedirect0_vec1_MSB 0x9 +#define QIB_7322_IntRedirect0_vec1_RMASK 0x1F +#define QIB_7322_IntRedirect0_vec0_LSB 0x0 +#define QIB_7322_IntRedirect0_vec0_MSB 0x4 +#define QIB_7322_IntRedirect0_vec0_RMASK 0x1F + +#define QIB_7322_Int_Granted_OFFS 0x570 +#define QIB_7322_Int_Granted_DEF 0x0000000000000000 + +#define QIB_7322_vec_clr_without_int_OFFS 0x578 +#define QIB_7322_vec_clr_without_int_DEF 0x0000000000000000 + +#define QIB_7322_DCACtrlA_OFFS 0x580 +#define QIB_7322_DCACtrlA_DEF 0x0000000000000000 +#define QIB_7322_DCACtrlA_SendDMAHead1DCAEnable_LSB 0x4 +#define QIB_7322_DCACtrlA_SendDMAHead1DCAEnable_MSB 0x4 +#define QIB_7322_DCACtrlA_SendDMAHead1DCAEnable_RMASK 0x1 +#define QIB_7322_DCACtrlA_SendDMAHead0DCAEnable_LSB 0x3 +#define QIB_7322_DCACtrlA_SendDMAHead0DCAEnable_MSB 0x3 +#define QIB_7322_DCACtrlA_SendDMAHead0DCAEnable_RMASK 0x1 +#define QIB_7322_DCACtrlA_RcvTailUpdDCAEnable_LSB 0x2 +#define QIB_7322_DCACtrlA_RcvTailUpdDCAEnable_MSB 0x2 +#define QIB_7322_DCACtrlA_RcvTailUpdDCAEnable_RMASK 0x1 +#define QIB_7322_DCACtrlA_EagerDCAEnable_LSB 0x1 +#define QIB_7322_DCACtrlA_EagerDCAEnable_MSB 0x1 +#define QIB_7322_DCACtrlA_EagerDCAEnable_RMASK 0x1 +#define QIB_7322_DCACtrlA_RcvHdrqDCAEnable_LSB 0x0 +#define QIB_7322_DCACtrlA_RcvHdrqDCAEnable_MSB 0x0 +#define QIB_7322_DCACtrlA_RcvHdrqDCAEnable_RMASK 0x1 + +#define QIB_7322_DCACtrlB_OFFS 0x588 +#define QIB_7322_DCACtrlB_DEF 0x0000000000000000 +#define QIB_7322_DCACtrlB_RcvHdrq3DCAXfrCnt_LSB 0x36 +#define QIB_7322_DCACtrlB_RcvHdrq3DCAXfrCnt_MSB 0x3B +#define QIB_7322_DCACtrlB_RcvHdrq3DCAXfrCnt_RMASK 0x3F +#define QIB_7322_DCACtrlB_RcvHdrq3DCAOPH_LSB 0x2E +#define QIB_7322_DCACtrlB_RcvHdrq3DCAOPH_MSB 0x35 +#define QIB_7322_DCACtrlB_RcvHdrq3DCAOPH_RMASK 0xFF +#define QIB_7322_DCACtrlB_RcvHdrq2DCAXfrCnt_LSB 0x28 +#define QIB_7322_DCACtrlB_RcvHdrq2DCAXfrCnt_MSB 0x2D +#define QIB_7322_DCACtrlB_RcvHdrq2DCAXfrCnt_RMASK 0x3F +#define QIB_7322_DCACtrlB_RcvHdrq2DCAOPH_LSB 0x20 +#define QIB_7322_DCACtrlB_RcvHdrq2DCAOPH_MSB 0x27 +#define QIB_7322_DCACtrlB_RcvHdrq2DCAOPH_RMASK 0xFF +#define QIB_7322_DCACtrlB_RcvHdrq1DCAXfrCnt_LSB 0x16 +#define QIB_7322_DCACtrlB_RcvHdrq1DCAXfrCnt_MSB 0x1B +#define QIB_7322_DCACtrlB_RcvHdrq1DCAXfrCnt_RMASK 0x3F +#define QIB_7322_DCACtrlB_RcvHdrq1DCAOPH_LSB 0xE +#define QIB_7322_DCACtrlB_RcvHdrq1DCAOPH_MSB 0x15 +#define QIB_7322_DCACtrlB_RcvHdrq1DCAOPH_RMASK 0xFF +#define QIB_7322_DCACtrlB_RcvHdrq0DCAXfrCnt_LSB 0x8 +#define QIB_7322_DCACtrlB_RcvHdrq0DCAXfrCnt_MSB 0xD +#define QIB_7322_DCACtrlB_RcvHdrq0DCAXfrCnt_RMASK 0x3F +#define QIB_7322_DCACtrlB_RcvHdrq0DCAOPH_LSB 0x0 +#define QIB_7322_DCACtrlB_RcvHdrq0DCAOPH_MSB 0x7 +#define QIB_7322_DCACtrlB_RcvHdrq0DCAOPH_RMASK 0xFF + +#define QIB_7322_DCACtrlC_OFFS 0x590 +#define QIB_7322_DCACtrlC_DEF 0x0000000000000000 +#define QIB_7322_DCACtrlC_RcvHdrq7DCAXfrCnt_LSB 0x36 +#define QIB_7322_DCACtrlC_RcvHdrq7DCAXfrCnt_MSB 0x3B +#define QIB_7322_DCACtrlC_RcvHdrq7DCAXfrCnt_RMASK 0x3F +#define QIB_7322_DCACtrlC_RcvHdrq7DCAOPH_LSB 0x2E +#define QIB_7322_DCACtrlC_RcvHdrq7DCAOPH_MSB 0x35 +#define QIB_7322_DCACtrlC_RcvHdrq7DCAOPH_RMASK 0xFF +#define QIB_7322_DCACtrlC_RcvHdrq6DCAXfrCnt_LSB 0x28 +#define QIB_7322_DCACtrlC_RcvHdrq6DCAXfrCnt_MSB 0x2D +#define QIB_7322_DCACtrlC_RcvHdrq6DCAXfrCnt_RMASK 0x3F +#define QIB_7322_DCACtrlC_RcvHdrq6DCAOPH_LSB 0x20 +#define QIB_7322_DCACtrlC_RcvHdrq6DCAOPH_MSB 0x27 +#define QIB_7322_DCACtrlC_RcvHdrq6DCAOPH_RMASK 0xFF +#define QIB_7322_DCACtrlC_RcvHdrq5DCAXfrCnt_LSB 0x16 +#define QIB_7322_DCACtrlC_RcvHdrq5DCAXfrCnt_MSB 0x1B +#define QIB_7322_DCACtrlC_RcvHdrq5DCAXfrCnt_RMASK 0x3F +#define QIB_7322_DCACtrlC_RcvHdrq5DCAOPH_LSB 0xE +#define QIB_7322_DCACtrlC_RcvHdrq5DCAOPH_MSB 0x15 +#define QIB_7322_DCACtrlC_RcvHdrq5DCAOPH_RMASK 0xFF +#define QIB_7322_DCACtrlC_RcvHdrq4DCAXfrCnt_LSB 0x8 +#define QIB_7322_DCACtrlC_RcvHdrq4DCAXfrCnt_MSB 0xD +#define QIB_7322_DCACtrlC_RcvHdrq4DCAXfrCnt_RMASK 0x3F +#define QIB_7322_DCACtrlC_RcvHdrq4DCAOPH_LSB 0x0 +#define QIB_7322_DCACtrlC_RcvHdrq4DCAOPH_MSB 0x7 +#define QIB_7322_DCACtrlC_RcvHdrq4DCAOPH_RMASK 0xFF + +#define QIB_7322_DCACtrlD_OFFS 0x598 +#define QIB_7322_DCACtrlD_DEF 0x0000000000000000 +#define QIB_7322_DCACtrlD_RcvHdrq11DCAXfrCnt_LSB 0x36 +#define QIB_7322_DCACtrlD_RcvHdrq11DCAXfrCnt_MSB 0x3B +#define QIB_7322_DCACtrlD_RcvHdrq11DCAXfrCnt_RMASK 0x3F +#define QIB_7322_DCACtrlD_RcvHdrq11DCAOPH_LSB 0x2E +#define QIB_7322_DCACtrlD_RcvHdrq11DCAOPH_MSB 0x35 +#define QIB_7322_DCACtrlD_RcvHdrq11DCAOPH_RMASK 0xFF +#define QIB_7322_DCACtrlD_RcvHdrq10DCAXfrCnt_LSB 0x28 +#define QIB_7322_DCACtrlD_RcvHdrq10DCAXfrCnt_MSB 0x2D +#define QIB_7322_DCACtrlD_RcvHdrq10DCAXfrCnt_RMASK 0x3F +#define QIB_7322_DCACtrlD_RcvHdrq10DCAOPH_LSB 0x20 +#define QIB_7322_DCACtrlD_RcvHdrq10DCAOPH_MSB 0x27 +#define QIB_7322_DCACtrlD_RcvHdrq10DCAOPH_RMASK 0xFF +#define QIB_7322_DCACtrlD_RcvHdrq9DCAXfrCnt_LSB 0x16 +#define QIB_7322_DCACtrlD_RcvHdrq9DCAXfrCnt_MSB 0x1B +#define QIB_7322_DCACtrlD_RcvHdrq9DCAXfrCnt_RMASK 0x3F +#define QIB_7322_DCACtrlD_RcvHdrq9DCAOPH_LSB 0xE +#define QIB_7322_DCACtrlD_RcvHdrq9DCAOPH_MSB 0x15 +#define QIB_7322_DCACtrlD_RcvHdrq9DCAOPH_RMASK 0xFF +#define QIB_7322_DCACtrlD_RcvHdrq8DCAXfrCnt_LSB 0x8 +#define QIB_7322_DCACtrlD_RcvHdrq8DCAXfrCnt_MSB 0xD +#define QIB_7322_DCACtrlD_RcvHdrq8DCAXfrCnt_RMASK 0x3F +#define QIB_7322_DCACtrlD_RcvHdrq8DCAOPH_LSB 0x0 +#define QIB_7322_DCACtrlD_RcvHdrq8DCAOPH_MSB 0x7 +#define QIB_7322_DCACtrlD_RcvHdrq8DCAOPH_RMASK 0xFF + +#define QIB_7322_DCACtrlE_OFFS 0x5A0 +#define QIB_7322_DCACtrlE_DEF 0x0000000000000000 +#define QIB_7322_DCACtrlE_RcvHdrq15DCAXfrCnt_LSB 0x36 +#define QIB_7322_DCACtrlE_RcvHdrq15DCAXfrCnt_MSB 0x3B +#define QIB_7322_DCACtrlE_RcvHdrq15DCAXfrCnt_RMASK 0x3F +#define QIB_7322_DCACtrlE_RcvHdrq15DCAOPH_LSB 0x2E +#define QIB_7322_DCACtrlE_RcvHdrq15DCAOPH_MSB 0x35 +#define QIB_7322_DCACtrlE_RcvHdrq15DCAOPH_RMASK 0xFF +#define QIB_7322_DCACtrlE_RcvHdrq14DCAXfrCnt_LSB 0x28 +#define QIB_7322_DCACtrlE_RcvHdrq14DCAXfrCnt_MSB 0x2D +#define QIB_7322_DCACtrlE_RcvHdrq14DCAXfrCnt_RMASK 0x3F +#define QIB_7322_DCACtrlE_RcvHdrq14DCAOPH_LSB 0x20 +#define QIB_7322_DCACtrlE_RcvHdrq14DCAOPH_MSB 0x27 +#define QIB_7322_DCACtrlE_RcvHdrq14DCAOPH_RMASK 0xFF +#define QIB_7322_DCACtrlE_RcvHdrq13DCAXfrCnt_LSB 0x16 +#define QIB_7322_DCACtrlE_RcvHdrq13DCAXfrCnt_MSB 0x1B +#define QIB_7322_DCACtrlE_RcvHdrq13DCAXfrCnt_RMASK 0x3F +#define QIB_7322_DCACtrlE_RcvHdrq13DCAOPH_LSB 0xE +#define QIB_7322_DCACtrlE_RcvHdrq13DCAOPH_MSB 0x15 +#define QIB_7322_DCACtrlE_RcvHdrq13DCAOPH_RMASK 0xFF +#define QIB_7322_DCACtrlE_RcvHdrq12DCAXfrCnt_LSB 0x8 +#define QIB_7322_DCACtrlE_RcvHdrq12DCAXfrCnt_MSB 0xD +#define QIB_7322_DCACtrlE_RcvHdrq12DCAXfrCnt_RMASK 0x3F +#define QIB_7322_DCACtrlE_RcvHdrq12DCAOPH_LSB 0x0 +#define QIB_7322_DCACtrlE_RcvHdrq12DCAOPH_MSB 0x7 +#define QIB_7322_DCACtrlE_RcvHdrq12DCAOPH_RMASK 0xFF + +#define QIB_7322_DCACtrlF_OFFS 0x5A8 +#define QIB_7322_DCACtrlF_DEF 0x0000000000000000 +#define QIB_7322_DCACtrlF_SendDma1DCAOPH_LSB 0x28 +#define QIB_7322_DCACtrlF_SendDma1DCAOPH_MSB 0x2F +#define QIB_7322_DCACtrlF_SendDma1DCAOPH_RMASK 0xFF +#define QIB_7322_DCACtrlF_SendDma0DCAOPH_LSB 0x20 +#define QIB_7322_DCACtrlF_SendDma0DCAOPH_MSB 0x27 +#define QIB_7322_DCACtrlF_SendDma0DCAOPH_RMASK 0xFF +#define QIB_7322_DCACtrlF_RcvHdrq17DCAXfrCnt_LSB 0x16 +#define QIB_7322_DCACtrlF_RcvHdrq17DCAXfrCnt_MSB 0x1B +#define QIB_7322_DCACtrlF_RcvHdrq17DCAXfrCnt_RMASK 0x3F +#define QIB_7322_DCACtrlF_RcvHdrq17DCAOPH_LSB 0xE +#define QIB_7322_DCACtrlF_RcvHdrq17DCAOPH_MSB 0x15 +#define QIB_7322_DCACtrlF_RcvHdrq17DCAOPH_RMASK 0xFF +#define QIB_7322_DCACtrlF_RcvHdrq16DCAXfrCnt_LSB 0x8 +#define QIB_7322_DCACtrlF_RcvHdrq16DCAXfrCnt_MSB 0xD +#define QIB_7322_DCACtrlF_RcvHdrq16DCAXfrCnt_RMASK 0x3F +#define QIB_7322_DCACtrlF_RcvHdrq16DCAOPH_LSB 0x0 +#define QIB_7322_DCACtrlF_RcvHdrq16DCAOPH_MSB 0x7 +#define QIB_7322_DCACtrlF_RcvHdrq16DCAOPH_RMASK 0xFF + +#define QIB_7322_RcvAvailTimeOut0_OFFS 0xC00 +#define QIB_7322_RcvAvailTimeOut0_DEF 0x0000000000000000 +#define QIB_7322_RcvAvailTimeOut0_RcvAvailTOCount_LSB 0x10 +#define QIB_7322_RcvAvailTimeOut0_RcvAvailTOCount_MSB 0x1F +#define QIB_7322_RcvAvailTimeOut0_RcvAvailTOCount_RMASK 0xFFFF +#define QIB_7322_RcvAvailTimeOut0_RcvAvailTOReload_LSB 0x0 +#define QIB_7322_RcvAvailTimeOut0_RcvAvailTOReload_MSB 0xF +#define QIB_7322_RcvAvailTimeOut0_RcvAvailTOReload_RMASK 0xFFFF + +#define QIB_7322_CntrRegBase_0_OFFS 0x1028 +#define QIB_7322_CntrRegBase_0_DEF 0x0000000000012000 + +#define QIB_7322_ErrMask_0_OFFS 0x1080 +#define QIB_7322_ErrMask_0_DEF 0x0000000000000000 +#define QIB_7322_ErrMask_0_IBStatusChangedMask_LSB 0x3A +#define QIB_7322_ErrMask_0_IBStatusChangedMask_MSB 0x3A +#define QIB_7322_ErrMask_0_IBStatusChangedMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SHeadersErrMask_LSB 0x39 +#define QIB_7322_ErrMask_0_SHeadersErrMask_MSB 0x39 +#define QIB_7322_ErrMask_0_SHeadersErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_VL15BufMisuseErrMask_LSB 0x36 +#define QIB_7322_ErrMask_0_VL15BufMisuseErrMask_MSB 0x36 +#define QIB_7322_ErrMask_0_VL15BufMisuseErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SDmaHaltErrMask_LSB 0x31 +#define QIB_7322_ErrMask_0_SDmaHaltErrMask_MSB 0x31 +#define QIB_7322_ErrMask_0_SDmaHaltErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SDmaDescAddrMisalignErrMask_LSB 0x30 +#define QIB_7322_ErrMask_0_SDmaDescAddrMisalignErrMask_MSB 0x30 +#define QIB_7322_ErrMask_0_SDmaDescAddrMisalignErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SDmaUnexpDataErrMask_LSB 0x2F +#define QIB_7322_ErrMask_0_SDmaUnexpDataErrMask_MSB 0x2F +#define QIB_7322_ErrMask_0_SDmaUnexpDataErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SDmaMissingDwErrMask_LSB 0x2E +#define QIB_7322_ErrMask_0_SDmaMissingDwErrMask_MSB 0x2E +#define QIB_7322_ErrMask_0_SDmaMissingDwErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SDmaDwEnErrMask_LSB 0x2D +#define QIB_7322_ErrMask_0_SDmaDwEnErrMask_MSB 0x2D +#define QIB_7322_ErrMask_0_SDmaDwEnErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SDmaRpyTagErrMask_LSB 0x2C +#define QIB_7322_ErrMask_0_SDmaRpyTagErrMask_MSB 0x2C +#define QIB_7322_ErrMask_0_SDmaRpyTagErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SDma1stDescErrMask_LSB 0x2B +#define QIB_7322_ErrMask_0_SDma1stDescErrMask_MSB 0x2B +#define QIB_7322_ErrMask_0_SDma1stDescErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SDmaBaseErrMask_LSB 0x2A +#define QIB_7322_ErrMask_0_SDmaBaseErrMask_MSB 0x2A +#define QIB_7322_ErrMask_0_SDmaBaseErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SDmaTailOutOfBoundErrMask_LSB 0x29 +#define QIB_7322_ErrMask_0_SDmaTailOutOfBoundErrMask_MSB 0x29 +#define QIB_7322_ErrMask_0_SDmaTailOutOfBoundErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SDmaOutOfBoundErrMask_LSB 0x28 +#define QIB_7322_ErrMask_0_SDmaOutOfBoundErrMask_MSB 0x28 +#define QIB_7322_ErrMask_0_SDmaOutOfBoundErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SDmaGenMismatchErrMask_LSB 0x27 +#define QIB_7322_ErrMask_0_SDmaGenMismatchErrMask_MSB 0x27 +#define QIB_7322_ErrMask_0_SDmaGenMismatchErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SendBufMisuseErrMask_LSB 0x26 +#define QIB_7322_ErrMask_0_SendBufMisuseErrMask_MSB 0x26 +#define QIB_7322_ErrMask_0_SendBufMisuseErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SendUnsupportedVLErrMask_LSB 0x25 +#define QIB_7322_ErrMask_0_SendUnsupportedVLErrMask_MSB 0x25 +#define QIB_7322_ErrMask_0_SendUnsupportedVLErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SendUnexpectedPktNumErrMask_LSB 0x24 +#define QIB_7322_ErrMask_0_SendUnexpectedPktNumErrMask_MSB 0x24 +#define QIB_7322_ErrMask_0_SendUnexpectedPktNumErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SendDroppedDataPktErrMask_LSB 0x22 +#define QIB_7322_ErrMask_0_SendDroppedDataPktErrMask_MSB 0x22 +#define QIB_7322_ErrMask_0_SendDroppedDataPktErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SendDroppedSmpPktErrMask_LSB 0x21 +#define QIB_7322_ErrMask_0_SendDroppedSmpPktErrMask_MSB 0x21 +#define QIB_7322_ErrMask_0_SendDroppedSmpPktErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SendPktLenErrMask_LSB 0x20 +#define QIB_7322_ErrMask_0_SendPktLenErrMask_MSB 0x20 +#define QIB_7322_ErrMask_0_SendPktLenErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SendUnderRunErrMask_LSB 0x1F +#define QIB_7322_ErrMask_0_SendUnderRunErrMask_MSB 0x1F +#define QIB_7322_ErrMask_0_SendUnderRunErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SendMaxPktLenErrMask_LSB 0x1E +#define QIB_7322_ErrMask_0_SendMaxPktLenErrMask_MSB 0x1E +#define QIB_7322_ErrMask_0_SendMaxPktLenErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_SendMinPktLenErrMask_LSB 0x1D +#define QIB_7322_ErrMask_0_SendMinPktLenErrMask_MSB 0x1D +#define QIB_7322_ErrMask_0_SendMinPktLenErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_RcvIBLostLinkErrMask_LSB 0x11 +#define QIB_7322_ErrMask_0_RcvIBLostLinkErrMask_MSB 0x11 +#define QIB_7322_ErrMask_0_RcvIBLostLinkErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_RcvHdrErrMask_LSB 0x10 +#define QIB_7322_ErrMask_0_RcvHdrErrMask_MSB 0x10 +#define QIB_7322_ErrMask_0_RcvHdrErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_RcvHdrLenErrMask_LSB 0xF +#define QIB_7322_ErrMask_0_RcvHdrLenErrMask_MSB 0xF +#define QIB_7322_ErrMask_0_RcvHdrLenErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_RcvBadTidErrMask_LSB 0xE +#define QIB_7322_ErrMask_0_RcvBadTidErrMask_MSB 0xE +#define QIB_7322_ErrMask_0_RcvBadTidErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_RcvBadVersionErrMask_LSB 0xB +#define QIB_7322_ErrMask_0_RcvBadVersionErrMask_MSB 0xB +#define QIB_7322_ErrMask_0_RcvBadVersionErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_RcvIBFlowErrMask_LSB 0xA +#define QIB_7322_ErrMask_0_RcvIBFlowErrMask_MSB 0xA +#define QIB_7322_ErrMask_0_RcvIBFlowErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_RcvEBPErrMask_LSB 0x9 +#define QIB_7322_ErrMask_0_RcvEBPErrMask_MSB 0x9 +#define QIB_7322_ErrMask_0_RcvEBPErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_RcvUnsupportedVLErrMask_LSB 0x8 +#define QIB_7322_ErrMask_0_RcvUnsupportedVLErrMask_MSB 0x8 +#define QIB_7322_ErrMask_0_RcvUnsupportedVLErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_RcvUnexpectedCharErrMask_LSB 0x7 +#define QIB_7322_ErrMask_0_RcvUnexpectedCharErrMask_MSB 0x7 +#define QIB_7322_ErrMask_0_RcvUnexpectedCharErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_RcvShortPktLenErrMask_LSB 0x6 +#define QIB_7322_ErrMask_0_RcvShortPktLenErrMask_MSB 0x6 +#define QIB_7322_ErrMask_0_RcvShortPktLenErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_RcvLongPktLenErrMask_LSB 0x5 +#define QIB_7322_ErrMask_0_RcvLongPktLenErrMask_MSB 0x5 +#define QIB_7322_ErrMask_0_RcvLongPktLenErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_RcvMaxPktLenErrMask_LSB 0x4 +#define QIB_7322_ErrMask_0_RcvMaxPktLenErrMask_MSB 0x4 +#define QIB_7322_ErrMask_0_RcvMaxPktLenErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_RcvMinPktLenErrMask_LSB 0x3 +#define QIB_7322_ErrMask_0_RcvMinPktLenErrMask_MSB 0x3 +#define QIB_7322_ErrMask_0_RcvMinPktLenErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_RcvICRCErrMask_LSB 0x2 +#define QIB_7322_ErrMask_0_RcvICRCErrMask_MSB 0x2 +#define QIB_7322_ErrMask_0_RcvICRCErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_RcvVCRCErrMask_LSB 0x1 +#define QIB_7322_ErrMask_0_RcvVCRCErrMask_MSB 0x1 +#define QIB_7322_ErrMask_0_RcvVCRCErrMask_RMASK 0x1 +#define QIB_7322_ErrMask_0_RcvFormatErrMask_LSB 0x0 +#define QIB_7322_ErrMask_0_RcvFormatErrMask_MSB 0x0 +#define QIB_7322_ErrMask_0_RcvFormatErrMask_RMASK 0x1 + +#define QIB_7322_ErrStatus_0_OFFS 0x1088 +#define QIB_7322_ErrStatus_0_DEF 0x0000000000000000 +#define QIB_7322_ErrStatus_0_IBStatusChanged_LSB 0x3A +#define QIB_7322_ErrStatus_0_IBStatusChanged_MSB 0x3A +#define QIB_7322_ErrStatus_0_IBStatusChanged_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SHeadersErr_LSB 0x39 +#define QIB_7322_ErrStatus_0_SHeadersErr_MSB 0x39 +#define QIB_7322_ErrStatus_0_SHeadersErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_VL15BufMisuseErr_LSB 0x36 +#define QIB_7322_ErrStatus_0_VL15BufMisuseErr_MSB 0x36 +#define QIB_7322_ErrStatus_0_VL15BufMisuseErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SDmaHaltErr_LSB 0x31 +#define QIB_7322_ErrStatus_0_SDmaHaltErr_MSB 0x31 +#define QIB_7322_ErrStatus_0_SDmaHaltErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SDmaDescAddrMisalignErr_LSB 0x30 +#define QIB_7322_ErrStatus_0_SDmaDescAddrMisalignErr_MSB 0x30 +#define QIB_7322_ErrStatus_0_SDmaDescAddrMisalignErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SDmaUnexpDataErr_LSB 0x2F +#define QIB_7322_ErrStatus_0_SDmaUnexpDataErr_MSB 0x2F +#define QIB_7322_ErrStatus_0_SDmaUnexpDataErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SDmaMissingDwErr_LSB 0x2E +#define QIB_7322_ErrStatus_0_SDmaMissingDwErr_MSB 0x2E +#define QIB_7322_ErrStatus_0_SDmaMissingDwErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SDmaDwEnErr_LSB 0x2D +#define QIB_7322_ErrStatus_0_SDmaDwEnErr_MSB 0x2D +#define QIB_7322_ErrStatus_0_SDmaDwEnErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SDmaRpyTagErr_LSB 0x2C +#define QIB_7322_ErrStatus_0_SDmaRpyTagErr_MSB 0x2C +#define QIB_7322_ErrStatus_0_SDmaRpyTagErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SDma1stDescErr_LSB 0x2B +#define QIB_7322_ErrStatus_0_SDma1stDescErr_MSB 0x2B +#define QIB_7322_ErrStatus_0_SDma1stDescErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SDmaBaseErr_LSB 0x2A +#define QIB_7322_ErrStatus_0_SDmaBaseErr_MSB 0x2A +#define QIB_7322_ErrStatus_0_SDmaBaseErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SDmaTailOutOfBoundErr_LSB 0x29 +#define QIB_7322_ErrStatus_0_SDmaTailOutOfBoundErr_MSB 0x29 +#define QIB_7322_ErrStatus_0_SDmaTailOutOfBoundErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SDmaOutOfBoundErr_LSB 0x28 +#define QIB_7322_ErrStatus_0_SDmaOutOfBoundErr_MSB 0x28 +#define QIB_7322_ErrStatus_0_SDmaOutOfBoundErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SDmaGenMismatchErr_LSB 0x27 +#define QIB_7322_ErrStatus_0_SDmaGenMismatchErr_MSB 0x27 +#define QIB_7322_ErrStatus_0_SDmaGenMismatchErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SendBufMisuseErr_LSB 0x26 +#define QIB_7322_ErrStatus_0_SendBufMisuseErr_MSB 0x26 +#define QIB_7322_ErrStatus_0_SendBufMisuseErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SendUnsupportedVLErr_LSB 0x25 +#define QIB_7322_ErrStatus_0_SendUnsupportedVLErr_MSB 0x25 +#define QIB_7322_ErrStatus_0_SendUnsupportedVLErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SendUnexpectedPktNumErr_LSB 0x24 +#define QIB_7322_ErrStatus_0_SendUnexpectedPktNumErr_MSB 0x24 +#define QIB_7322_ErrStatus_0_SendUnexpectedPktNumErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SendDroppedDataPktErr_LSB 0x22 +#define QIB_7322_ErrStatus_0_SendDroppedDataPktErr_MSB 0x22 +#define QIB_7322_ErrStatus_0_SendDroppedDataPktErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SendDroppedSmpPktErr_LSB 0x21 +#define QIB_7322_ErrStatus_0_SendDroppedSmpPktErr_MSB 0x21 +#define QIB_7322_ErrStatus_0_SendDroppedSmpPktErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SendPktLenErr_LSB 0x20 +#define QIB_7322_ErrStatus_0_SendPktLenErr_MSB 0x20 +#define QIB_7322_ErrStatus_0_SendPktLenErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SendUnderRunErr_LSB 0x1F +#define QIB_7322_ErrStatus_0_SendUnderRunErr_MSB 0x1F +#define QIB_7322_ErrStatus_0_SendUnderRunErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SendMaxPktLenErr_LSB 0x1E +#define QIB_7322_ErrStatus_0_SendMaxPktLenErr_MSB 0x1E +#define QIB_7322_ErrStatus_0_SendMaxPktLenErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_SendMinPktLenErr_LSB 0x1D +#define QIB_7322_ErrStatus_0_SendMinPktLenErr_MSB 0x1D +#define QIB_7322_ErrStatus_0_SendMinPktLenErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_RcvIBLostLinkErr_LSB 0x11 +#define QIB_7322_ErrStatus_0_RcvIBLostLinkErr_MSB 0x11 +#define QIB_7322_ErrStatus_0_RcvIBLostLinkErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_RcvHdrErr_LSB 0x10 +#define QIB_7322_ErrStatus_0_RcvHdrErr_MSB 0x10 +#define QIB_7322_ErrStatus_0_RcvHdrErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_RcvHdrLenErr_LSB 0xF +#define QIB_7322_ErrStatus_0_RcvHdrLenErr_MSB 0xF +#define QIB_7322_ErrStatus_0_RcvHdrLenErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_RcvBadTidErr_LSB 0xE +#define QIB_7322_ErrStatus_0_RcvBadTidErr_MSB 0xE +#define QIB_7322_ErrStatus_0_RcvBadTidErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_RcvBadVersionErr_LSB 0xB +#define QIB_7322_ErrStatus_0_RcvBadVersionErr_MSB 0xB +#define QIB_7322_ErrStatus_0_RcvBadVersionErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_RcvIBFlowErr_LSB 0xA +#define QIB_7322_ErrStatus_0_RcvIBFlowErr_MSB 0xA +#define QIB_7322_ErrStatus_0_RcvIBFlowErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_RcvEBPErr_LSB 0x9 +#define QIB_7322_ErrStatus_0_RcvEBPErr_MSB 0x9 +#define QIB_7322_ErrStatus_0_RcvEBPErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_RcvUnsupportedVLErr_LSB 0x8 +#define QIB_7322_ErrStatus_0_RcvUnsupportedVLErr_MSB 0x8 +#define QIB_7322_ErrStatus_0_RcvUnsupportedVLErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_RcvUnexpectedCharErr_LSB 0x7 +#define QIB_7322_ErrStatus_0_RcvUnexpectedCharErr_MSB 0x7 +#define QIB_7322_ErrStatus_0_RcvUnexpectedCharErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_RcvShortPktLenErr_LSB 0x6 +#define QIB_7322_ErrStatus_0_RcvShortPktLenErr_MSB 0x6 +#define QIB_7322_ErrStatus_0_RcvShortPktLenErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_RcvLongPktLenErr_LSB 0x5 +#define QIB_7322_ErrStatus_0_RcvLongPktLenErr_MSB 0x5 +#define QIB_7322_ErrStatus_0_RcvLongPktLenErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_RcvMaxPktLenErr_LSB 0x4 +#define QIB_7322_ErrStatus_0_RcvMaxPktLenErr_MSB 0x4 +#define QIB_7322_ErrStatus_0_RcvMaxPktLenErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_RcvMinPktLenErr_LSB 0x3 +#define QIB_7322_ErrStatus_0_RcvMinPktLenErr_MSB 0x3 +#define QIB_7322_ErrStatus_0_RcvMinPktLenErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_RcvICRCErr_LSB 0x2 +#define QIB_7322_ErrStatus_0_RcvICRCErr_MSB 0x2 +#define QIB_7322_ErrStatus_0_RcvICRCErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_RcvVCRCErr_LSB 0x1 +#define QIB_7322_ErrStatus_0_RcvVCRCErr_MSB 0x1 +#define QIB_7322_ErrStatus_0_RcvVCRCErr_RMASK 0x1 +#define QIB_7322_ErrStatus_0_RcvFormatErr_LSB 0x0 +#define QIB_7322_ErrStatus_0_RcvFormatErr_MSB 0x0 +#define QIB_7322_ErrStatus_0_RcvFormatErr_RMASK 0x1 + +#define QIB_7322_ErrClear_0_OFFS 0x1090 +#define QIB_7322_ErrClear_0_DEF 0x0000000000000000 +#define QIB_7322_ErrClear_0_IBStatusChangedClear_LSB 0x3A +#define QIB_7322_ErrClear_0_IBStatusChangedClear_MSB 0x3A +#define QIB_7322_ErrClear_0_IBStatusChangedClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SHeadersErrClear_LSB 0x39 +#define QIB_7322_ErrClear_0_SHeadersErrClear_MSB 0x39 +#define QIB_7322_ErrClear_0_SHeadersErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_VL15BufMisuseErrClear_LSB 0x36 +#define QIB_7322_ErrClear_0_VL15BufMisuseErrClear_MSB 0x36 +#define QIB_7322_ErrClear_0_VL15BufMisuseErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SDmaHaltErrClear_LSB 0x31 +#define QIB_7322_ErrClear_0_SDmaHaltErrClear_MSB 0x31 +#define QIB_7322_ErrClear_0_SDmaHaltErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SDmaDescAddrMisalignErrClear_LSB 0x30 +#define QIB_7322_ErrClear_0_SDmaDescAddrMisalignErrClear_MSB 0x30 +#define QIB_7322_ErrClear_0_SDmaDescAddrMisalignErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SDmaUnexpDataErrClear_LSB 0x2F +#define QIB_7322_ErrClear_0_SDmaUnexpDataErrClear_MSB 0x2F +#define QIB_7322_ErrClear_0_SDmaUnexpDataErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SDmaMissingDwErrClear_LSB 0x2E +#define QIB_7322_ErrClear_0_SDmaMissingDwErrClear_MSB 0x2E +#define QIB_7322_ErrClear_0_SDmaMissingDwErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SDmaDwEnErrClear_LSB 0x2D +#define QIB_7322_ErrClear_0_SDmaDwEnErrClear_MSB 0x2D +#define QIB_7322_ErrClear_0_SDmaDwEnErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SDmaRpyTagErrClear_LSB 0x2C +#define QIB_7322_ErrClear_0_SDmaRpyTagErrClear_MSB 0x2C +#define QIB_7322_ErrClear_0_SDmaRpyTagErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SDma1stDescErrClear_LSB 0x2B +#define QIB_7322_ErrClear_0_SDma1stDescErrClear_MSB 0x2B +#define QIB_7322_ErrClear_0_SDma1stDescErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SDmaBaseErrClear_LSB 0x2A +#define QIB_7322_ErrClear_0_SDmaBaseErrClear_MSB 0x2A +#define QIB_7322_ErrClear_0_SDmaBaseErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SDmaTailOutOfBoundErrClear_LSB 0x29 +#define QIB_7322_ErrClear_0_SDmaTailOutOfBoundErrClear_MSB 0x29 +#define QIB_7322_ErrClear_0_SDmaTailOutOfBoundErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SDmaOutOfBoundErrClear_LSB 0x28 +#define QIB_7322_ErrClear_0_SDmaOutOfBoundErrClear_MSB 0x28 +#define QIB_7322_ErrClear_0_SDmaOutOfBoundErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SDmaGenMismatchErrClear_LSB 0x27 +#define QIB_7322_ErrClear_0_SDmaGenMismatchErrClear_MSB 0x27 +#define QIB_7322_ErrClear_0_SDmaGenMismatchErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SendBufMisuseErrClear_LSB 0x26 +#define QIB_7322_ErrClear_0_SendBufMisuseErrClear_MSB 0x26 +#define QIB_7322_ErrClear_0_SendBufMisuseErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SendUnsupportedVLErrClear_LSB 0x25 +#define QIB_7322_ErrClear_0_SendUnsupportedVLErrClear_MSB 0x25 +#define QIB_7322_ErrClear_0_SendUnsupportedVLErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SendUnexpectedPktNumErrClear_LSB 0x24 +#define QIB_7322_ErrClear_0_SendUnexpectedPktNumErrClear_MSB 0x24 +#define QIB_7322_ErrClear_0_SendUnexpectedPktNumErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SendDroppedDataPktErrClear_LSB 0x22 +#define QIB_7322_ErrClear_0_SendDroppedDataPktErrClear_MSB 0x22 +#define QIB_7322_ErrClear_0_SendDroppedDataPktErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SendDroppedSmpPktErrClear_LSB 0x21 +#define QIB_7322_ErrClear_0_SendDroppedSmpPktErrClear_MSB 0x21 +#define QIB_7322_ErrClear_0_SendDroppedSmpPktErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SendPktLenErrClear_LSB 0x20 +#define QIB_7322_ErrClear_0_SendPktLenErrClear_MSB 0x20 +#define QIB_7322_ErrClear_0_SendPktLenErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SendUnderRunErrClear_LSB 0x1F +#define QIB_7322_ErrClear_0_SendUnderRunErrClear_MSB 0x1F +#define QIB_7322_ErrClear_0_SendUnderRunErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SendMaxPktLenErrClear_LSB 0x1E +#define QIB_7322_ErrClear_0_SendMaxPktLenErrClear_MSB 0x1E +#define QIB_7322_ErrClear_0_SendMaxPktLenErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_SendMinPktLenErrClear_LSB 0x1D +#define QIB_7322_ErrClear_0_SendMinPktLenErrClear_MSB 0x1D +#define QIB_7322_ErrClear_0_SendMinPktLenErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_RcvIBLostLinkErrClear_LSB 0x11 +#define QIB_7322_ErrClear_0_RcvIBLostLinkErrClear_MSB 0x11 +#define QIB_7322_ErrClear_0_RcvIBLostLinkErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_RcvHdrErrClear_LSB 0x10 +#define QIB_7322_ErrClear_0_RcvHdrErrClear_MSB 0x10 +#define QIB_7322_ErrClear_0_RcvHdrErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_RcvHdrLenErrClear_LSB 0xF +#define QIB_7322_ErrClear_0_RcvHdrLenErrClear_MSB 0xF +#define QIB_7322_ErrClear_0_RcvHdrLenErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_RcvBadTidErrClear_LSB 0xE +#define QIB_7322_ErrClear_0_RcvBadTidErrClear_MSB 0xE +#define QIB_7322_ErrClear_0_RcvBadTidErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_RcvBadVersionErrClear_LSB 0xB +#define QIB_7322_ErrClear_0_RcvBadVersionErrClear_MSB 0xB +#define QIB_7322_ErrClear_0_RcvBadVersionErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_RcvIBFlowErrClear_LSB 0xA +#define QIB_7322_ErrClear_0_RcvIBFlowErrClear_MSB 0xA +#define QIB_7322_ErrClear_0_RcvIBFlowErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_RcvEBPErrClear_LSB 0x9 +#define QIB_7322_ErrClear_0_RcvEBPErrClear_MSB 0x9 +#define QIB_7322_ErrClear_0_RcvEBPErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_RcvUnsupportedVLErrClear_LSB 0x8 +#define QIB_7322_ErrClear_0_RcvUnsupportedVLErrClear_MSB 0x8 +#define QIB_7322_ErrClear_0_RcvUnsupportedVLErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_RcvUnexpectedCharErrClear_LSB 0x7 +#define QIB_7322_ErrClear_0_RcvUnexpectedCharErrClear_MSB 0x7 +#define QIB_7322_ErrClear_0_RcvUnexpectedCharErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_RcvShortPktLenErrClear_LSB 0x6 +#define QIB_7322_ErrClear_0_RcvShortPktLenErrClear_MSB 0x6 +#define QIB_7322_ErrClear_0_RcvShortPktLenErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_RcvLongPktLenErrClear_LSB 0x5 +#define QIB_7322_ErrClear_0_RcvLongPktLenErrClear_MSB 0x5 +#define QIB_7322_ErrClear_0_RcvLongPktLenErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_RcvMaxPktLenErrClear_LSB 0x4 +#define QIB_7322_ErrClear_0_RcvMaxPktLenErrClear_MSB 0x4 +#define QIB_7322_ErrClear_0_RcvMaxPktLenErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_RcvMinPktLenErrClear_LSB 0x3 +#define QIB_7322_ErrClear_0_RcvMinPktLenErrClear_MSB 0x3 +#define QIB_7322_ErrClear_0_RcvMinPktLenErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_RcvICRCErrClear_LSB 0x2 +#define QIB_7322_ErrClear_0_RcvICRCErrClear_MSB 0x2 +#define QIB_7322_ErrClear_0_RcvICRCErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_RcvVCRCErrClear_LSB 0x1 +#define QIB_7322_ErrClear_0_RcvVCRCErrClear_MSB 0x1 +#define QIB_7322_ErrClear_0_RcvVCRCErrClear_RMASK 0x1 +#define QIB_7322_ErrClear_0_RcvFormatErrClear_LSB 0x0 +#define QIB_7322_ErrClear_0_RcvFormatErrClear_MSB 0x0 +#define QIB_7322_ErrClear_0_RcvFormatErrClear_RMASK 0x1 + +#define QIB_7322_TXEStatus_0_OFFS 0x10B8 +#define QIB_7322_TXEStatus_0_DEF 0x0000000XC00080FF +#define QIB_7322_TXEStatus_0_TXE_IBC_Idle_LSB 0x1F +#define QIB_7322_TXEStatus_0_TXE_IBC_Idle_MSB 0x1F +#define QIB_7322_TXEStatus_0_TXE_IBC_Idle_RMASK 0x1 +#define QIB_7322_TXEStatus_0_RmFifoEmpty_LSB 0x1E +#define QIB_7322_TXEStatus_0_RmFifoEmpty_MSB 0x1E +#define QIB_7322_TXEStatus_0_RmFifoEmpty_RMASK 0x1 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL15_LSB 0xF +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL15_MSB 0xF +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL15_RMASK 0x1 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL7_LSB 0x7 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL7_MSB 0x7 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL7_RMASK 0x1 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL6_LSB 0x6 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL6_MSB 0x6 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL6_RMASK 0x1 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL5_LSB 0x5 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL5_MSB 0x5 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL5_RMASK 0x1 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL4_LSB 0x4 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL4_MSB 0x4 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL4_RMASK 0x1 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL3_LSB 0x3 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL3_MSB 0x3 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL3_RMASK 0x1 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL2_LSB 0x2 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL2_MSB 0x2 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL2_RMASK 0x1 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL1_LSB 0x1 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL1_MSB 0x1 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL1_RMASK 0x1 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL0_LSB 0x0 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL0_MSB 0x0 +#define QIB_7322_TXEStatus_0_LaFifoEmpty_VL0_RMASK 0x1 + +#define QIB_7322_RcvCtrl_0_OFFS 0x1100 +#define QIB_7322_RcvCtrl_0_DEF 0x0000000000000000 +#define QIB_7322_RcvCtrl_0_RcvResetCredit_LSB 0x2A +#define QIB_7322_RcvCtrl_0_RcvResetCredit_MSB 0x2A +#define QIB_7322_RcvCtrl_0_RcvResetCredit_RMASK 0x1 +#define QIB_7322_RcvCtrl_0_RcvPartitionKeyDisable_LSB 0x29 +#define QIB_7322_RcvCtrl_0_RcvPartitionKeyDisable_MSB 0x29 +#define QIB_7322_RcvCtrl_0_RcvPartitionKeyDisable_RMASK 0x1 +#define QIB_7322_RcvCtrl_0_RcvQPMapEnable_LSB 0x28 +#define QIB_7322_RcvCtrl_0_RcvQPMapEnable_MSB 0x28 +#define QIB_7322_RcvCtrl_0_RcvQPMapEnable_RMASK 0x1 +#define QIB_7322_RcvCtrl_0_RcvIBPortEnable_LSB 0x27 +#define QIB_7322_RcvCtrl_0_RcvIBPortEnable_MSB 0x27 +#define QIB_7322_RcvCtrl_0_RcvIBPortEnable_RMASK 0x1 +#define QIB_7322_RcvCtrl_0_ContextEnableUser_LSB 0x2 +#define QIB_7322_RcvCtrl_0_ContextEnableUser_MSB 0x11 +#define QIB_7322_RcvCtrl_0_ContextEnableUser_RMASK 0xFFFF +#define QIB_7322_RcvCtrl_0_ContextEnableKernel_LSB 0x0 +#define QIB_7322_RcvCtrl_0_ContextEnableKernel_MSB 0x0 +#define QIB_7322_RcvCtrl_0_ContextEnableKernel_RMASK 0x1 + +#define QIB_7322_RcvBTHQP_0_OFFS 0x1108 +#define QIB_7322_RcvBTHQP_0_DEF 0x0000000000000000 +#define QIB_7322_RcvBTHQP_0_RcvBTHQP_LSB 0x0 +#define QIB_7322_RcvBTHQP_0_RcvBTHQP_MSB 0x17 +#define QIB_7322_RcvBTHQP_0_RcvBTHQP_RMASK 0xFFFFFF + +#define QIB_7322_RcvQPMapTableA_0_OFFS 0x1110 +#define QIB_7322_RcvQPMapTableA_0_DEF 0x0000000000000000 +#define QIB_7322_RcvQPMapTableA_0_RcvQPMapContext5_LSB 0x19 +#define QIB_7322_RcvQPMapTableA_0_RcvQPMapContext5_MSB 0x1D +#define QIB_7322_RcvQPMapTableA_0_RcvQPMapContext5_RMASK 0x1F +#define QIB_7322_RcvQPMapTableA_0_RcvQPMapContext4_LSB 0x14 +#define QIB_7322_RcvQPMapTableA_0_RcvQPMapContext4_MSB 0x18 +#define QIB_7322_RcvQPMapTableA_0_RcvQPMapContext4_RMASK 0x1F +#define QIB_7322_RcvQPMapTableA_0_RcvQPMapContext3_LSB 0xF +#define QIB_7322_RcvQPMapTableA_0_RcvQPMapContext3_MSB 0x13 +#define QIB_7322_RcvQPMapTableA_0_RcvQPMapContext3_RMASK 0x1F +#define QIB_7322_RcvQPMapTableA_0_RcvQPMapContext2_LSB 0xA +#define QIB_7322_RcvQPMapTableA_0_RcvQPMapContext2_MSB 0xE +#define QIB_7322_RcvQPMapTableA_0_RcvQPMapContext2_RMASK 0x1F +#define QIB_7322_RcvQPMapTableA_0_RcvQPMapContext1_LSB 0x5 +#define QIB_7322_RcvQPMapTableA_0_RcvQPMapContext1_MSB 0x9 +#define QIB_7322_RcvQPMapTableA_0_RcvQPMapContext1_RMASK 0x1F +#define QIB_7322_RcvQPMapTableA_0_RcvQPMapContext0_LSB 0x0 +#define QIB_7322_RcvQPMapTableA_0_RcvQPMapContext0_MSB 0x4 +#define QIB_7322_RcvQPMapTableA_0_RcvQPMapContext0_RMASK 0x1F + +#define QIB_7322_RcvQPMapTableB_0_OFFS 0x1118 +#define QIB_7322_RcvQPMapTableB_0_DEF 0x0000000000000000 +#define QIB_7322_RcvQPMapTableB_0_RcvQPMapContext11_LSB 0x19 +#define QIB_7322_RcvQPMapTableB_0_RcvQPMapContext11_MSB 0x1D +#define QIB_7322_RcvQPMapTableB_0_RcvQPMapContext11_RMASK 0x1F +#define QIB_7322_RcvQPMapTableB_0_RcvQPMapContext10_LSB 0x14 +#define QIB_7322_RcvQPMapTableB_0_RcvQPMapContext10_MSB 0x18 +#define QIB_7322_RcvQPMapTableB_0_RcvQPMapContext10_RMASK 0x1F +#define QIB_7322_RcvQPMapTableB_0_RcvQPMapContext9_LSB 0xF +#define QIB_7322_RcvQPMapTableB_0_RcvQPMapContext9_MSB 0x13 +#define QIB_7322_RcvQPMapTableB_0_RcvQPMapContext9_RMASK 0x1F +#define QIB_7322_RcvQPMapTableB_0_RcvQPMapContext8_LSB 0xA +#define QIB_7322_RcvQPMapTableB_0_RcvQPMapContext8_MSB 0xE +#define QIB_7322_RcvQPMapTableB_0_RcvQPMapContext8_RMASK 0x1F +#define QIB_7322_RcvQPMapTableB_0_RcvQPMapContext7_LSB 0x5 +#define QIB_7322_RcvQPMapTableB_0_RcvQPMapContext7_MSB 0x9 +#define QIB_7322_RcvQPMapTableB_0_RcvQPMapContext7_RMASK 0x1F +#define QIB_7322_RcvQPMapTableB_0_RcvQPMapContext6_LSB 0x0 +#define QIB_7322_RcvQPMapTableB_0_RcvQPMapContext6_MSB 0x4 +#define QIB_7322_RcvQPMapTableB_0_RcvQPMapContext6_RMASK 0x1F + +#define QIB_7322_RcvQPMapTableC_0_OFFS 0x1120 +#define QIB_7322_RcvQPMapTableC_0_DEF 0x0000000000000000 +#define QIB_7322_RcvQPMapTableC_0_RcvQPMapContext17_LSB 0x19 +#define QIB_7322_RcvQPMapTableC_0_RcvQPMapContext17_MSB 0x1D +#define QIB_7322_RcvQPMapTableC_0_RcvQPMapContext17_RMASK 0x1F +#define QIB_7322_RcvQPMapTableC_0_RcvQPMapContext16_LSB 0x14 +#define QIB_7322_RcvQPMapTableC_0_RcvQPMapContext16_MSB 0x18 +#define QIB_7322_RcvQPMapTableC_0_RcvQPMapContext16_RMASK 0x1F +#define QIB_7322_RcvQPMapTableC_0_RcvQPMapContext15_LSB 0xF +#define QIB_7322_RcvQPMapTableC_0_RcvQPMapContext15_MSB 0x13 +#define QIB_7322_RcvQPMapTableC_0_RcvQPMapContext15_RMASK 0x1F +#define QIB_7322_RcvQPMapTableC_0_RcvQPMapContext14_LSB 0xA +#define QIB_7322_RcvQPMapTableC_0_RcvQPMapContext14_MSB 0xE +#define QIB_7322_RcvQPMapTableC_0_RcvQPMapContext14_RMASK 0x1F +#define QIB_7322_RcvQPMapTableC_0_RcvQPMapContext13_LSB 0x5 +#define QIB_7322_RcvQPMapTableC_0_RcvQPMapContext13_MSB 0x9 +#define QIB_7322_RcvQPMapTableC_0_RcvQPMapContext13_RMASK 0x1F +#define QIB_7322_RcvQPMapTableC_0_RcvQPMapContext12_LSB 0x0 +#define QIB_7322_RcvQPMapTableC_0_RcvQPMapContext12_MSB 0x4 +#define QIB_7322_RcvQPMapTableC_0_RcvQPMapContext12_RMASK 0x1F + +#define QIB_7322_RcvQPMapTableD_0_OFFS 0x1128 +#define QIB_7322_RcvQPMapTableD_0_DEF 0x0000000000000000 +#define QIB_7322_RcvQPMapTableD_0_RcvQPMapContext23_LSB 0x19 +#define QIB_7322_RcvQPMapTableD_0_RcvQPMapContext23_MSB 0x1D +#define QIB_7322_RcvQPMapTableD_0_RcvQPMapContext23_RMASK 0x1F +#define QIB_7322_RcvQPMapTableD_0_RcvQPMapContext22_LSB 0x14 +#define QIB_7322_RcvQPMapTableD_0_RcvQPMapContext22_MSB 0x18 +#define QIB_7322_RcvQPMapTableD_0_RcvQPMapContext22_RMASK 0x1F +#define QIB_7322_RcvQPMapTableD_0_RcvQPMapContext21_LSB 0xF +#define QIB_7322_RcvQPMapTableD_0_RcvQPMapContext21_MSB 0x13 +#define QIB_7322_RcvQPMapTableD_0_RcvQPMapContext21_RMASK 0x1F +#define QIB_7322_RcvQPMapTableD_0_RcvQPMapContext20_LSB 0xA +#define QIB_7322_RcvQPMapTableD_0_RcvQPMapContext20_MSB 0xE +#define QIB_7322_RcvQPMapTableD_0_RcvQPMapContext20_RMASK 0x1F +#define QIB_7322_RcvQPMapTableD_0_RcvQPMapContext19_LSB 0x5 +#define QIB_7322_RcvQPMapTableD_0_RcvQPMapContext19_MSB 0x9 +#define QIB_7322_RcvQPMapTableD_0_RcvQPMapContext19_RMASK 0x1F +#define QIB_7322_RcvQPMapTableD_0_RcvQPMapContext18_LSB 0x0 +#define QIB_7322_RcvQPMapTableD_0_RcvQPMapContext18_MSB 0x4 +#define QIB_7322_RcvQPMapTableD_0_RcvQPMapContext18_RMASK 0x1F + +#define QIB_7322_RcvQPMapTableE_0_OFFS 0x1130 +#define QIB_7322_RcvQPMapTableE_0_DEF 0x0000000000000000 +#define QIB_7322_RcvQPMapTableE_0_RcvQPMapContext29_LSB 0x19 +#define QIB_7322_RcvQPMapTableE_0_RcvQPMapContext29_MSB 0x1D +#define QIB_7322_RcvQPMapTableE_0_RcvQPMapContext29_RMASK 0x1F +#define QIB_7322_RcvQPMapTableE_0_RcvQPMapContext28_LSB 0x14 +#define QIB_7322_RcvQPMapTableE_0_RcvQPMapContext28_MSB 0x18 +#define QIB_7322_RcvQPMapTableE_0_RcvQPMapContext28_RMASK 0x1F +#define QIB_7322_RcvQPMapTableE_0_RcvQPMapContext27_LSB 0xF +#define QIB_7322_RcvQPMapTableE_0_RcvQPMapContext27_MSB 0x13 +#define QIB_7322_RcvQPMapTableE_0_RcvQPMapContext27_RMASK 0x1F +#define QIB_7322_RcvQPMapTableE_0_RcvQPMapContext26_LSB 0xA +#define QIB_7322_RcvQPMapTableE_0_RcvQPMapContext26_MSB 0xE +#define QIB_7322_RcvQPMapTableE_0_RcvQPMapContext26_RMASK 0x1F +#define QIB_7322_RcvQPMapTableE_0_RcvQPMapContext25_LSB 0x5 +#define QIB_7322_RcvQPMapTableE_0_RcvQPMapContext25_MSB 0x9 +#define QIB_7322_RcvQPMapTableE_0_RcvQPMapContext25_RMASK 0x1F +#define QIB_7322_RcvQPMapTableE_0_RcvQPMapContext24_LSB 0x0 +#define QIB_7322_RcvQPMapTableE_0_RcvQPMapContext24_MSB 0x4 +#define QIB_7322_RcvQPMapTableE_0_RcvQPMapContext24_RMASK 0x1F + +#define QIB_7322_RcvQPMapTableF_0_OFFS 0x1138 +#define QIB_7322_RcvQPMapTableF_0_DEF 0x0000000000000000 +#define QIB_7322_RcvQPMapTableF_0_RcvQPMapContext31_LSB 0x5 +#define QIB_7322_RcvQPMapTableF_0_RcvQPMapContext31_MSB 0x9 +#define QIB_7322_RcvQPMapTableF_0_RcvQPMapContext31_RMASK 0x1F +#define QIB_7322_RcvQPMapTableF_0_RcvQPMapContext30_LSB 0x0 +#define QIB_7322_RcvQPMapTableF_0_RcvQPMapContext30_MSB 0x4 +#define QIB_7322_RcvQPMapTableF_0_RcvQPMapContext30_RMASK 0x1F + +#define QIB_7322_PSStat_0_OFFS 0x1140 +#define QIB_7322_PSStat_0_DEF 0x0000000000000000 + +#define QIB_7322_PSStart_0_OFFS 0x1148 +#define QIB_7322_PSStart_0_DEF 0x0000000000000000 + +#define QIB_7322_PSInterval_0_OFFS 0x1150 +#define QIB_7322_PSInterval_0_DEF 0x0000000000000000 + +#define QIB_7322_RcvStatus_0_OFFS 0x1160 +#define QIB_7322_RcvStatus_0_DEF 0x0000000000000000 +#define QIB_7322_RcvStatus_0_DmaeqBlockingContext_LSB 0x1 +#define QIB_7322_RcvStatus_0_DmaeqBlockingContext_MSB 0x5 +#define QIB_7322_RcvStatus_0_DmaeqBlockingContext_RMASK 0x1F +#define QIB_7322_RcvStatus_0_RxPktInProgress_LSB 0x0 +#define QIB_7322_RcvStatus_0_RxPktInProgress_MSB 0x0 +#define QIB_7322_RcvStatus_0_RxPktInProgress_RMASK 0x1 + +#define QIB_7322_RcvPartitionKey_0_OFFS 0x1168 +#define QIB_7322_RcvPartitionKey_0_DEF 0x0000000000000000 + +#define QIB_7322_RcvQPMulticastContext_0_OFFS 0x1170 +#define QIB_7322_RcvQPMulticastContext_0_DEF 0x0000000000000000 +#define QIB_7322_RcvQPMulticastContext_0_RcvQpMcContext_LSB 0x0 +#define QIB_7322_RcvQPMulticastContext_0_RcvQpMcContext_MSB 0x4 +#define QIB_7322_RcvQPMulticastContext_0_RcvQpMcContext_RMASK 0x1F + +#define QIB_7322_RcvPktLEDCnt_0_OFFS 0x1178 +#define QIB_7322_RcvPktLEDCnt_0_DEF 0x0000000000000000 +#define QIB_7322_RcvPktLEDCnt_0_ONperiod_LSB 0x20 +#define QIB_7322_RcvPktLEDCnt_0_ONperiod_MSB 0x3F +#define QIB_7322_RcvPktLEDCnt_0_ONperiod_RMASK 0xFFFFFFFF +#define QIB_7322_RcvPktLEDCnt_0_OFFperiod_LSB 0x0 +#define QIB_7322_RcvPktLEDCnt_0_OFFperiod_MSB 0x1F +#define QIB_7322_RcvPktLEDCnt_0_OFFperiod_RMASK 0xFFFFFFFF + +#define QIB_7322_SendDmaIdleCnt_0_OFFS 0x1180 +#define QIB_7322_SendDmaIdleCnt_0_DEF 0x0000000000000000 +#define QIB_7322_SendDmaIdleCnt_0_SendDmaIdleCnt_LSB 0x0 +#define QIB_7322_SendDmaIdleCnt_0_SendDmaIdleCnt_MSB 0xF +#define QIB_7322_SendDmaIdleCnt_0_SendDmaIdleCnt_RMASK 0xFFFF + +#define QIB_7322_SendDmaReloadCnt_0_OFFS 0x1188 +#define QIB_7322_SendDmaReloadCnt_0_DEF 0x0000000000000000 +#define QIB_7322_SendDmaReloadCnt_0_SendDmaReloadCnt_LSB 0x0 +#define QIB_7322_SendDmaReloadCnt_0_SendDmaReloadCnt_MSB 0xF +#define QIB_7322_SendDmaReloadCnt_0_SendDmaReloadCnt_RMASK 0xFFFF + +#define QIB_7322_SendDmaDescCnt_0_OFFS 0x1190 +#define QIB_7322_SendDmaDescCnt_0_DEF 0x0000000000000000 +#define QIB_7322_SendDmaDescCnt_0_SendDmaDescCnt_LSB 0x0 +#define QIB_7322_SendDmaDescCnt_0_SendDmaDescCnt_MSB 0xF +#define QIB_7322_SendDmaDescCnt_0_SendDmaDescCnt_RMASK 0xFFFF + +#define QIB_7322_SendCtrl_0_OFFS 0x11C0 +#define QIB_7322_SendCtrl_0_DEF 0x0000000000000000 +#define QIB_7322_SendCtrl_0_IBVLArbiterEn_LSB 0xF +#define QIB_7322_SendCtrl_0_IBVLArbiterEn_MSB 0xF +#define QIB_7322_SendCtrl_0_IBVLArbiterEn_RMASK 0x1 +#define QIB_7322_SendCtrl_0_TxeDrainRmFifo_LSB 0xE +#define QIB_7322_SendCtrl_0_TxeDrainRmFifo_MSB 0xE +#define QIB_7322_SendCtrl_0_TxeDrainRmFifo_RMASK 0x1 +#define QIB_7322_SendCtrl_0_TxeDrainLaFifo_LSB 0xD +#define QIB_7322_SendCtrl_0_TxeDrainLaFifo_MSB 0xD +#define QIB_7322_SendCtrl_0_TxeDrainLaFifo_RMASK 0x1 +#define QIB_7322_SendCtrl_0_SDmaHalt_LSB 0xC +#define QIB_7322_SendCtrl_0_SDmaHalt_MSB 0xC +#define QIB_7322_SendCtrl_0_SDmaHalt_RMASK 0x1 +#define QIB_7322_SendCtrl_0_SDmaEnable_LSB 0xB +#define QIB_7322_SendCtrl_0_SDmaEnable_MSB 0xB +#define QIB_7322_SendCtrl_0_SDmaEnable_RMASK 0x1 +#define QIB_7322_SendCtrl_0_SDmaSingleDescriptor_LSB 0xA +#define QIB_7322_SendCtrl_0_SDmaSingleDescriptor_MSB 0xA +#define QIB_7322_SendCtrl_0_SDmaSingleDescriptor_RMASK 0x1 +#define QIB_7322_SendCtrl_0_SDmaIntEnable_LSB 0x9 +#define QIB_7322_SendCtrl_0_SDmaIntEnable_MSB 0x9 +#define QIB_7322_SendCtrl_0_SDmaIntEnable_RMASK 0x1 +#define QIB_7322_SendCtrl_0_SDmaCleanup_LSB 0x8 +#define QIB_7322_SendCtrl_0_SDmaCleanup_MSB 0x8 +#define QIB_7322_SendCtrl_0_SDmaCleanup_RMASK 0x1 +#define QIB_7322_SendCtrl_0_ForceCreditUpToDate_LSB 0x7 +#define QIB_7322_SendCtrl_0_ForceCreditUpToDate_MSB 0x7 +#define QIB_7322_SendCtrl_0_ForceCreditUpToDate_RMASK 0x1 +#define QIB_7322_SendCtrl_0_SendEnable_LSB 0x3 +#define QIB_7322_SendCtrl_0_SendEnable_MSB 0x3 +#define QIB_7322_SendCtrl_0_SendEnable_RMASK 0x1 +#define QIB_7322_SendCtrl_0_TxeBypassIbc_LSB 0x1 +#define QIB_7322_SendCtrl_0_TxeBypassIbc_MSB 0x1 +#define QIB_7322_SendCtrl_0_TxeBypassIbc_RMASK 0x1 +#define QIB_7322_SendCtrl_0_TxeAbortIbc_LSB 0x0 +#define QIB_7322_SendCtrl_0_TxeAbortIbc_MSB 0x0 +#define QIB_7322_SendCtrl_0_TxeAbortIbc_RMASK 0x1 + +#define QIB_7322_SendDmaBase_0_OFFS 0x11F8 +#define QIB_7322_SendDmaBase_0_DEF 0x0000000000000000 +#define QIB_7322_SendDmaBase_0_SendDmaBase_LSB 0x0 +#define QIB_7322_SendDmaBase_0_SendDmaBase_MSB 0x2F +#define QIB_7322_SendDmaBase_0_SendDmaBase_RMASK 0xFFFFFFFFFFFF + +#define QIB_7322_SendDmaLenGen_0_OFFS 0x1200 +#define QIB_7322_SendDmaLenGen_0_DEF 0x0000000000000000 +#define QIB_7322_SendDmaLenGen_0_Generation_LSB 0x10 +#define QIB_7322_SendDmaLenGen_0_Generation_MSB 0x12 +#define QIB_7322_SendDmaLenGen_0_Generation_RMASK 0x7 +#define QIB_7322_SendDmaLenGen_0_Length_LSB 0x0 +#define QIB_7322_SendDmaLenGen_0_Length_MSB 0xF +#define QIB_7322_SendDmaLenGen_0_Length_RMASK 0xFFFF + +#define QIB_7322_SendDmaTail_0_OFFS 0x1208 +#define QIB_7322_SendDmaTail_0_DEF 0x0000000000000000 +#define QIB_7322_SendDmaTail_0_SendDmaTail_LSB 0x0 +#define QIB_7322_SendDmaTail_0_SendDmaTail_MSB 0xF +#define QIB_7322_SendDmaTail_0_SendDmaTail_RMASK 0xFFFF + +#define QIB_7322_SendDmaHead_0_OFFS 0x1210 +#define QIB_7322_SendDmaHead_0_DEF 0x0000000000000000 +#define QIB_7322_SendDmaHead_0_InternalSendDmaHead_LSB 0x20 +#define QIB_7322_SendDmaHead_0_InternalSendDmaHead_MSB 0x2F +#define QIB_7322_SendDmaHead_0_InternalSendDmaHead_RMASK 0xFFFF +#define QIB_7322_SendDmaHead_0_SendDmaHead_LSB 0x0 +#define QIB_7322_SendDmaHead_0_SendDmaHead_MSB 0xF +#define QIB_7322_SendDmaHead_0_SendDmaHead_RMASK 0xFFFF + +#define QIB_7322_SendDmaHeadAddr_0_OFFS 0x1218 +#define QIB_7322_SendDmaHeadAddr_0_DEF 0x0000000000000000 +#define QIB_7322_SendDmaHeadAddr_0_SendDmaHeadAddr_LSB 0x0 +#define QIB_7322_SendDmaHeadAddr_0_SendDmaHeadAddr_MSB 0x2F +#define QIB_7322_SendDmaHeadAddr_0_SendDmaHeadAddr_RMASK 0xFFFFFFFFFFFF + +#define QIB_7322_SendDmaBufMask0_0_OFFS 0x1220 +#define QIB_7322_SendDmaBufMask0_0_DEF 0x0000000000000000 +#define QIB_7322_SendDmaBufMask0_0_BufMask_63_0_LSB 0x0 +#define QIB_7322_SendDmaBufMask0_0_BufMask_63_0_MSB 0x3F +#define QIB_7322_SendDmaBufMask0_0_BufMask_63_0_RMASK 0x0 + +#define QIB_7322_SendDmaStatus_0_OFFS 0x1238 +#define QIB_7322_SendDmaStatus_0_DEF 0x0000000042000000 +#define QIB_7322_SendDmaStatus_0_ScoreBoardDrainInProg_LSB 0x3F +#define QIB_7322_SendDmaStatus_0_ScoreBoardDrainInProg_MSB 0x3F +#define QIB_7322_SendDmaStatus_0_ScoreBoardDrainInProg_RMASK 0x1 +#define QIB_7322_SendDmaStatus_0_HaltInProg_LSB 0x3E +#define QIB_7322_SendDmaStatus_0_HaltInProg_MSB 0x3E +#define QIB_7322_SendDmaStatus_0_HaltInProg_RMASK 0x1 +#define QIB_7322_SendDmaStatus_0_InternalSDmaHalt_LSB 0x3D +#define QIB_7322_SendDmaStatus_0_InternalSDmaHalt_MSB 0x3D +#define QIB_7322_SendDmaStatus_0_InternalSDmaHalt_RMASK 0x1 +#define QIB_7322_SendDmaStatus_0_ScbDescIndex_13_0_LSB 0x2F +#define QIB_7322_SendDmaStatus_0_ScbDescIndex_13_0_MSB 0x3C +#define QIB_7322_SendDmaStatus_0_ScbDescIndex_13_0_RMASK 0x3FFF +#define QIB_7322_SendDmaStatus_0_RpyLowAddr_6_0_LSB 0x28 +#define QIB_7322_SendDmaStatus_0_RpyLowAddr_6_0_MSB 0x2E +#define QIB_7322_SendDmaStatus_0_RpyLowAddr_6_0_RMASK 0x7F +#define QIB_7322_SendDmaStatus_0_RpyTag_7_0_LSB 0x20 +#define QIB_7322_SendDmaStatus_0_RpyTag_7_0_MSB 0x27 +#define QIB_7322_SendDmaStatus_0_RpyTag_7_0_RMASK 0xFF +#define QIB_7322_SendDmaStatus_0_ScbFull_LSB 0x1F +#define QIB_7322_SendDmaStatus_0_ScbFull_MSB 0x1F +#define QIB_7322_SendDmaStatus_0_ScbFull_RMASK 0x1 +#define QIB_7322_SendDmaStatus_0_ScbEmpty_LSB 0x1E +#define QIB_7322_SendDmaStatus_0_ScbEmpty_MSB 0x1E +#define QIB_7322_SendDmaStatus_0_ScbEmpty_RMASK 0x1 +#define QIB_7322_SendDmaStatus_0_ScbEntryValid_LSB 0x1D +#define QIB_7322_SendDmaStatus_0_ScbEntryValid_MSB 0x1D +#define QIB_7322_SendDmaStatus_0_ScbEntryValid_RMASK 0x1 +#define QIB_7322_SendDmaStatus_0_ScbFetchDescFlag_LSB 0x1C +#define QIB_7322_SendDmaStatus_0_ScbFetchDescFlag_MSB 0x1C +#define QIB_7322_SendDmaStatus_0_ScbFetchDescFlag_RMASK 0x1 +#define QIB_7322_SendDmaStatus_0_SplFifoReadyToGo_LSB 0x1B +#define QIB_7322_SendDmaStatus_0_SplFifoReadyToGo_MSB 0x1B +#define QIB_7322_SendDmaStatus_0_SplFifoReadyToGo_RMASK 0x1 +#define QIB_7322_SendDmaStatus_0_SplFifoDisarmed_LSB 0x1A +#define QIB_7322_SendDmaStatus_0_SplFifoDisarmed_MSB 0x1A +#define QIB_7322_SendDmaStatus_0_SplFifoDisarmed_RMASK 0x1 +#define QIB_7322_SendDmaStatus_0_SplFifoEmpty_LSB 0x19 +#define QIB_7322_SendDmaStatus_0_SplFifoEmpty_MSB 0x19 +#define QIB_7322_SendDmaStatus_0_SplFifoEmpty_RMASK 0x1 +#define QIB_7322_SendDmaStatus_0_SplFifoFull_LSB 0x18 +#define QIB_7322_SendDmaStatus_0_SplFifoFull_MSB 0x18 +#define QIB_7322_SendDmaStatus_0_SplFifoFull_RMASK 0x1 +#define QIB_7322_SendDmaStatus_0_SplFifoBufNum_LSB 0x10 +#define QIB_7322_SendDmaStatus_0_SplFifoBufNum_MSB 0x17 +#define QIB_7322_SendDmaStatus_0_SplFifoBufNum_RMASK 0xFF +#define QIB_7322_SendDmaStatus_0_SplFifoDescIndex_LSB 0x0 +#define QIB_7322_SendDmaStatus_0_SplFifoDescIndex_MSB 0xF +#define QIB_7322_SendDmaStatus_0_SplFifoDescIndex_RMASK 0xFFFF + +#define QIB_7322_SendDmaPriorityThld_0_OFFS 0x1258 +#define QIB_7322_SendDmaPriorityThld_0_DEF 0x0000000000000000 +#define QIB_7322_SendDmaPriorityThld_0_PriorityThreshold_LSB 0x0 +#define QIB_7322_SendDmaPriorityThld_0_PriorityThreshold_MSB 0x3 +#define QIB_7322_SendDmaPriorityThld_0_PriorityThreshold_RMASK 0xF + +#define QIB_7322_SendHdrErrSymptom_0_OFFS 0x1260 +#define QIB_7322_SendHdrErrSymptom_0_DEF 0x0000000000000000 +#define QIB_7322_SendHdrErrSymptom_0_NonKeyPacket_LSB 0x6 +#define QIB_7322_SendHdrErrSymptom_0_NonKeyPacket_MSB 0x6 +#define QIB_7322_SendHdrErrSymptom_0_NonKeyPacket_RMASK 0x1 +#define QIB_7322_SendHdrErrSymptom_0_GRHFail_LSB 0x5 +#define QIB_7322_SendHdrErrSymptom_0_GRHFail_MSB 0x5 +#define QIB_7322_SendHdrErrSymptom_0_GRHFail_RMASK 0x1 +#define QIB_7322_SendHdrErrSymptom_0_PkeyFail_LSB 0x4 +#define QIB_7322_SendHdrErrSymptom_0_PkeyFail_MSB 0x4 +#define QIB_7322_SendHdrErrSymptom_0_PkeyFail_RMASK 0x1 +#define QIB_7322_SendHdrErrSymptom_0_QPFail_LSB 0x3 +#define QIB_7322_SendHdrErrSymptom_0_QPFail_MSB 0x3 +#define QIB_7322_SendHdrErrSymptom_0_QPFail_RMASK 0x1 +#define QIB_7322_SendHdrErrSymptom_0_SLIDFail_LSB 0x2 +#define QIB_7322_SendHdrErrSymptom_0_SLIDFail_MSB 0x2 +#define QIB_7322_SendHdrErrSymptom_0_SLIDFail_RMASK 0x1 +#define QIB_7322_SendHdrErrSymptom_0_RawIPV6_LSB 0x1 +#define QIB_7322_SendHdrErrSymptom_0_RawIPV6_MSB 0x1 +#define QIB_7322_SendHdrErrSymptom_0_RawIPV6_RMASK 0x1 +#define QIB_7322_SendHdrErrSymptom_0_PacketTooSmall_LSB 0x0 +#define QIB_7322_SendHdrErrSymptom_0_PacketTooSmall_MSB 0x0 +#define QIB_7322_SendHdrErrSymptom_0_PacketTooSmall_RMASK 0x1 + +#define QIB_7322_RxCreditVL0_0_OFFS 0x1280 +#define QIB_7322_RxCreditVL0_0_DEF 0x0000000000000000 +#define QIB_7322_RxCreditVL0_0_RxBufrConsumedVL_LSB 0x10 +#define QIB_7322_RxCreditVL0_0_RxBufrConsumedVL_MSB 0x1B +#define QIB_7322_RxCreditVL0_0_RxBufrConsumedVL_RMASK 0xFFF +#define QIB_7322_RxCreditVL0_0_RxMaxCreditVL_LSB 0x0 +#define QIB_7322_RxCreditVL0_0_RxMaxCreditVL_MSB 0xB +#define QIB_7322_RxCreditVL0_0_RxMaxCreditVL_RMASK 0xFFF + +#define QIB_7322_SendDmaBufUsed0_0_OFFS 0x1480 +#define QIB_7322_SendDmaBufUsed0_0_DEF 0x0000000000000000 +#define QIB_7322_SendDmaBufUsed0_0_BufUsed_63_0_LSB 0x0 +#define QIB_7322_SendDmaBufUsed0_0_BufUsed_63_0_MSB 0x3F +#define QIB_7322_SendDmaBufUsed0_0_BufUsed_63_0_RMASK 0x0 + +#define QIB_7322_SendCheckControl_0_OFFS 0x14A8 +#define QIB_7322_SendCheckControl_0_DEF 0x0000000000000000 +#define QIB_7322_SendCheckControl_0_PKey_En_LSB 0x4 +#define QIB_7322_SendCheckControl_0_PKey_En_MSB 0x4 +#define QIB_7322_SendCheckControl_0_PKey_En_RMASK 0x1 +#define QIB_7322_SendCheckControl_0_BTHQP_En_LSB 0x3 +#define QIB_7322_SendCheckControl_0_BTHQP_En_MSB 0x3 +#define QIB_7322_SendCheckControl_0_BTHQP_En_RMASK 0x1 +#define QIB_7322_SendCheckControl_0_SLID_En_LSB 0x2 +#define QIB_7322_SendCheckControl_0_SLID_En_MSB 0x2 +#define QIB_7322_SendCheckControl_0_SLID_En_RMASK 0x1 +#define QIB_7322_SendCheckControl_0_RawIPV6_En_LSB 0x1 +#define QIB_7322_SendCheckControl_0_RawIPV6_En_MSB 0x1 +#define QIB_7322_SendCheckControl_0_RawIPV6_En_RMASK 0x1 +#define QIB_7322_SendCheckControl_0_PacketTooSmall_En_LSB 0x0 +#define QIB_7322_SendCheckControl_0_PacketTooSmall_En_MSB 0x0 +#define QIB_7322_SendCheckControl_0_PacketTooSmall_En_RMASK 0x1 + +#define QIB_7322_SendIBSLIDMask_0_OFFS 0x14B0 +#define QIB_7322_SendIBSLIDMask_0_DEF 0x0000000000000000 +#define QIB_7322_SendIBSLIDMask_0_SendIBSLIDMask_15_0_LSB 0x0 +#define QIB_7322_SendIBSLIDMask_0_SendIBSLIDMask_15_0_MSB 0xF +#define QIB_7322_SendIBSLIDMask_0_SendIBSLIDMask_15_0_RMASK 0xFFFF + +#define QIB_7322_SendIBSLIDAssign_0_OFFS 0x14B8 +#define QIB_7322_SendIBSLIDAssign_0_DEF 0x0000000000000000 +#define QIB_7322_SendIBSLIDAssign_0_SendIBSLIDAssign_15_0_LSB 0x0 +#define QIB_7322_SendIBSLIDAssign_0_SendIBSLIDAssign_15_0_MSB 0xF +#define QIB_7322_SendIBSLIDAssign_0_SendIBSLIDAssign_15_0_RMASK 0xFFFF + +#define QIB_7322_IBCStatusA_0_OFFS 0x1540 +#define QIB_7322_IBCStatusA_0_DEF 0x0000000000000X02 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL7_LSB 0x27 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL7_MSB 0x27 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL7_RMASK 0x1 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL6_LSB 0x26 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL6_MSB 0x26 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL6_RMASK 0x1 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL5_LSB 0x25 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL5_MSB 0x25 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL5_RMASK 0x1 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL4_LSB 0x24 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL4_MSB 0x24 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL4_RMASK 0x1 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL3_LSB 0x23 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL3_MSB 0x23 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL3_RMASK 0x1 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL2_LSB 0x22 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL2_MSB 0x22 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL2_RMASK 0x1 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL1_LSB 0x21 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL1_MSB 0x21 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL1_RMASK 0x1 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL0_LSB 0x20 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL0_MSB 0x20 +#define QIB_7322_IBCStatusA_0_TxCreditOk_VL0_RMASK 0x1 +#define QIB_7322_IBCStatusA_0_TxReady_LSB 0x1E +#define QIB_7322_IBCStatusA_0_TxReady_MSB 0x1E +#define QIB_7322_IBCStatusA_0_TxReady_RMASK 0x1 +#define QIB_7322_IBCStatusA_0_LinkSpeedQDR_LSB 0x1D +#define QIB_7322_IBCStatusA_0_LinkSpeedQDR_MSB 0x1D +#define QIB_7322_IBCStatusA_0_LinkSpeedQDR_RMASK 0x1 +#define QIB_7322_IBCStatusA_0_ScrambleCapRemote_LSB 0xF +#define QIB_7322_IBCStatusA_0_ScrambleCapRemote_MSB 0xF +#define QIB_7322_IBCStatusA_0_ScrambleCapRemote_RMASK 0x1 +#define QIB_7322_IBCStatusA_0_ScrambleEn_LSB 0xE +#define QIB_7322_IBCStatusA_0_ScrambleEn_MSB 0xE +#define QIB_7322_IBCStatusA_0_ScrambleEn_RMASK 0x1 +#define QIB_7322_IBCStatusA_0_IBTxLaneReversed_LSB 0xD +#define QIB_7322_IBCStatusA_0_IBTxLaneReversed_MSB 0xD +#define QIB_7322_IBCStatusA_0_IBTxLaneReversed_RMASK 0x1 +#define QIB_7322_IBCStatusA_0_IBRxLaneReversed_LSB 0xC +#define QIB_7322_IBCStatusA_0_IBRxLaneReversed_MSB 0xC +#define QIB_7322_IBCStatusA_0_IBRxLaneReversed_RMASK 0x1 +#define QIB_7322_IBCStatusA_0_DDS_RXEQ_FAIL_LSB 0xA +#define QIB_7322_IBCStatusA_0_DDS_RXEQ_FAIL_MSB 0xA +#define QIB_7322_IBCStatusA_0_DDS_RXEQ_FAIL_RMASK 0x1 +#define QIB_7322_IBCStatusA_0_LinkWidthActive_LSB 0x9 +#define QIB_7322_IBCStatusA_0_LinkWidthActive_MSB 0x9 +#define QIB_7322_IBCStatusA_0_LinkWidthActive_RMASK 0x1 +#define QIB_7322_IBCStatusA_0_LinkSpeedActive_LSB 0x8 +#define QIB_7322_IBCStatusA_0_LinkSpeedActive_MSB 0x8 +#define QIB_7322_IBCStatusA_0_LinkSpeedActive_RMASK 0x1 +#define QIB_7322_IBCStatusA_0_LinkState_LSB 0x5 +#define QIB_7322_IBCStatusA_0_LinkState_MSB 0x7 +#define QIB_7322_IBCStatusA_0_LinkState_RMASK 0x7 +#define QIB_7322_IBCStatusA_0_LinkTrainingState_LSB 0x0 +#define QIB_7322_IBCStatusA_0_LinkTrainingState_MSB 0x4 +#define QIB_7322_IBCStatusA_0_LinkTrainingState_RMASK 0x1F + +#define QIB_7322_IBCStatusB_0_OFFS 0x1548 +#define QIB_7322_IBCStatusB_0_DEF 0x00000000XXXXXXXX +#define QIB_7322_IBCStatusB_0_ibsd_adaptation_timer_debug_LSB 0x27 +#define QIB_7322_IBCStatusB_0_ibsd_adaptation_timer_debug_MSB 0x27 +#define QIB_7322_IBCStatusB_0_ibsd_adaptation_timer_debug_RMASK 0x1 +#define QIB_7322_IBCStatusB_0_ibsd_adaptation_timer_reached_threshold_LSB 0x26 +#define QIB_7322_IBCStatusB_0_ibsd_adaptation_timer_reached_threshold_MSB 0x26 +#define QIB_7322_IBCStatusB_0_ibsd_adaptation_timer_reached_threshold_RMASK 0x1 +#define QIB_7322_IBCStatusB_0_ibsd_adaptation_timer_started_LSB 0x25 +#define QIB_7322_IBCStatusB_0_ibsd_adaptation_timer_started_MSB 0x25 +#define QIB_7322_IBCStatusB_0_ibsd_adaptation_timer_started_RMASK 0x1 +#define QIB_7322_IBCStatusB_0_heartbeat_timed_out_LSB 0x24 +#define QIB_7322_IBCStatusB_0_heartbeat_timed_out_MSB 0x24 +#define QIB_7322_IBCStatusB_0_heartbeat_timed_out_RMASK 0x1 +#define QIB_7322_IBCStatusB_0_heartbeat_crosstalk_LSB 0x20 +#define QIB_7322_IBCStatusB_0_heartbeat_crosstalk_MSB 0x23 +#define QIB_7322_IBCStatusB_0_heartbeat_crosstalk_RMASK 0xF +#define QIB_7322_IBCStatusB_0_RxEqLocalDevice_LSB 0x1E +#define QIB_7322_IBCStatusB_0_RxEqLocalDevice_MSB 0x1F +#define QIB_7322_IBCStatusB_0_RxEqLocalDevice_RMASK 0x3 +#define QIB_7322_IBCStatusB_0_ReqDDSLocalFromRmt_LSB 0x1A +#define QIB_7322_IBCStatusB_0_ReqDDSLocalFromRmt_MSB 0x1D +#define QIB_7322_IBCStatusB_0_ReqDDSLocalFromRmt_RMASK 0xF +#define QIB_7322_IBCStatusB_0_LinkRoundTripLatency_LSB 0x0 +#define QIB_7322_IBCStatusB_0_LinkRoundTripLatency_MSB 0x19 +#define QIB_7322_IBCStatusB_0_LinkRoundTripLatency_RMASK 0x3FFFFFF + +#define QIB_7322_IBCCtrlA_0_OFFS 0x1560 +#define QIB_7322_IBCCtrlA_0_DEF 0x0000000000000000 +#define QIB_7322_IBCCtrlA_0_Loopback_LSB 0x3F +#define QIB_7322_IBCCtrlA_0_Loopback_MSB 0x3F +#define QIB_7322_IBCCtrlA_0_Loopback_RMASK 0x1 +#define QIB_7322_IBCCtrlA_0_LinkDownDefaultState_LSB 0x3E +#define QIB_7322_IBCCtrlA_0_LinkDownDefaultState_MSB 0x3E +#define QIB_7322_IBCCtrlA_0_LinkDownDefaultState_RMASK 0x1 +#define QIB_7322_IBCCtrlA_0_IBLinkEn_LSB 0x3D +#define QIB_7322_IBCCtrlA_0_IBLinkEn_MSB 0x3D +#define QIB_7322_IBCCtrlA_0_IBLinkEn_RMASK 0x1 +#define QIB_7322_IBCCtrlA_0_IBStatIntReductionEn_LSB 0x3C +#define QIB_7322_IBCCtrlA_0_IBStatIntReductionEn_MSB 0x3C +#define QIB_7322_IBCCtrlA_0_IBStatIntReductionEn_RMASK 0x1 +#define QIB_7322_IBCCtrlA_0_NumVLane_LSB 0x30 +#define QIB_7322_IBCCtrlA_0_NumVLane_MSB 0x32 +#define QIB_7322_IBCCtrlA_0_NumVLane_RMASK 0x7 +#define QIB_7322_IBCCtrlA_0_OverrunThreshold_LSB 0x24 +#define QIB_7322_IBCCtrlA_0_OverrunThreshold_MSB 0x27 +#define QIB_7322_IBCCtrlA_0_OverrunThreshold_RMASK 0xF +#define QIB_7322_IBCCtrlA_0_PhyerrThreshold_LSB 0x20 +#define QIB_7322_IBCCtrlA_0_PhyerrThreshold_MSB 0x23 +#define QIB_7322_IBCCtrlA_0_PhyerrThreshold_RMASK 0xF +#define QIB_7322_IBCCtrlA_0_MaxPktLen_LSB 0x15 +#define QIB_7322_IBCCtrlA_0_MaxPktLen_MSB 0x1F +#define QIB_7322_IBCCtrlA_0_MaxPktLen_RMASK 0x7FF +#define QIB_7322_IBCCtrlA_0_LinkCmd_LSB 0x13 +#define QIB_7322_IBCCtrlA_0_LinkCmd_MSB 0x14 +#define QIB_7322_IBCCtrlA_0_LinkCmd_RMASK 0x3 +#define QIB_7322_IBCCtrlA_0_LinkInitCmd_LSB 0x10 +#define QIB_7322_IBCCtrlA_0_LinkInitCmd_MSB 0x12 +#define QIB_7322_IBCCtrlA_0_LinkInitCmd_RMASK 0x7 +#define QIB_7322_IBCCtrlA_0_FlowCtrlWaterMark_LSB 0x8 +#define QIB_7322_IBCCtrlA_0_FlowCtrlWaterMark_MSB 0xF +#define QIB_7322_IBCCtrlA_0_FlowCtrlWaterMark_RMASK 0xFF +#define QIB_7322_IBCCtrlA_0_FlowCtrlPeriod_LSB 0x0 +#define QIB_7322_IBCCtrlA_0_FlowCtrlPeriod_MSB 0x7 +#define QIB_7322_IBCCtrlA_0_FlowCtrlPeriod_RMASK 0xFF + +#define QIB_7322_IBCCtrlB_0_OFFS 0x1568 +#define QIB_7322_IBCCtrlB_0_DEF 0x00000000000305FF +#define QIB_7322_IBCCtrlB_0_IB_DLID_MASK_LSB 0x30 +#define QIB_7322_IBCCtrlB_0_IB_DLID_MASK_MSB 0x3F +#define QIB_7322_IBCCtrlB_0_IB_DLID_MASK_RMASK 0xFFFF +#define QIB_7322_IBCCtrlB_0_IB_DLID_LSB 0x20 +#define QIB_7322_IBCCtrlB_0_IB_DLID_MSB 0x2F +#define QIB_7322_IBCCtrlB_0_IB_DLID_RMASK 0xFFFF +#define QIB_7322_IBCCtrlB_0_IB_ENABLE_FILT_DPKT_LSB 0x1B +#define QIB_7322_IBCCtrlB_0_IB_ENABLE_FILT_DPKT_MSB 0x1B +#define QIB_7322_IBCCtrlB_0_IB_ENABLE_FILT_DPKT_RMASK 0x1 +#define QIB_7322_IBCCtrlB_0_HRTBT_REQ_LSB 0x1A +#define QIB_7322_IBCCtrlB_0_HRTBT_REQ_MSB 0x1A +#define QIB_7322_IBCCtrlB_0_HRTBT_REQ_RMASK 0x1 +#define QIB_7322_IBCCtrlB_0_HRTBT_PORT_LSB 0x12 +#define QIB_7322_IBCCtrlB_0_HRTBT_PORT_MSB 0x19 +#define QIB_7322_IBCCtrlB_0_HRTBT_PORT_RMASK 0xFF +#define QIB_7322_IBCCtrlB_0_HRTBT_AUTO_LSB 0x11 +#define QIB_7322_IBCCtrlB_0_HRTBT_AUTO_MSB 0x11 +#define QIB_7322_IBCCtrlB_0_HRTBT_AUTO_RMASK 0x1 +#define QIB_7322_IBCCtrlB_0_HRTBT_ENB_LSB 0x10 +#define QIB_7322_IBCCtrlB_0_HRTBT_ENB_MSB 0x10 +#define QIB_7322_IBCCtrlB_0_HRTBT_ENB_RMASK 0x1 +#define QIB_7322_IBCCtrlB_0_SD_DDS_LSB 0xC +#define QIB_7322_IBCCtrlB_0_SD_DDS_MSB 0xF +#define QIB_7322_IBCCtrlB_0_SD_DDS_RMASK 0xF +#define QIB_7322_IBCCtrlB_0_SD_DDSV_LSB 0xB +#define QIB_7322_IBCCtrlB_0_SD_DDSV_MSB 0xB +#define QIB_7322_IBCCtrlB_0_SD_DDSV_RMASK 0x1 +#define QIB_7322_IBCCtrlB_0_SD_ADD_ENB_LSB 0xA +#define QIB_7322_IBCCtrlB_0_SD_ADD_ENB_MSB 0xA +#define QIB_7322_IBCCtrlB_0_SD_ADD_ENB_RMASK 0x1 +#define QIB_7322_IBCCtrlB_0_SD_RX_EQUAL_ENABLE_LSB 0x9 +#define QIB_7322_IBCCtrlB_0_SD_RX_EQUAL_ENABLE_MSB 0x9 +#define QIB_7322_IBCCtrlB_0_SD_RX_EQUAL_ENABLE_RMASK 0x1 +#define QIB_7322_IBCCtrlB_0_IB_LANE_REV_SUPPORTED_LSB 0x8 +#define QIB_7322_IBCCtrlB_0_IB_LANE_REV_SUPPORTED_MSB 0x8 +#define QIB_7322_IBCCtrlB_0_IB_LANE_REV_SUPPORTED_RMASK 0x1 +#define QIB_7322_IBCCtrlB_0_IB_POLARITY_REV_SUPP_LSB 0x7 +#define QIB_7322_IBCCtrlB_0_IB_POLARITY_REV_SUPP_MSB 0x7 +#define QIB_7322_IBCCtrlB_0_IB_POLARITY_REV_SUPP_RMASK 0x1 +#define QIB_7322_IBCCtrlB_0_IB_NUM_CHANNELS_LSB 0x5 +#define QIB_7322_IBCCtrlB_0_IB_NUM_CHANNELS_MSB 0x6 +#define QIB_7322_IBCCtrlB_0_IB_NUM_CHANNELS_RMASK 0x3 +#define QIB_7322_IBCCtrlB_0_SD_SPEED_QDR_LSB 0x4 +#define QIB_7322_IBCCtrlB_0_SD_SPEED_QDR_MSB 0x4 +#define QIB_7322_IBCCtrlB_0_SD_SPEED_QDR_RMASK 0x1 +#define QIB_7322_IBCCtrlB_0_SD_SPEED_DDR_LSB 0x3 +#define QIB_7322_IBCCtrlB_0_SD_SPEED_DDR_MSB 0x3 +#define QIB_7322_IBCCtrlB_0_SD_SPEED_DDR_RMASK 0x1 +#define QIB_7322_IBCCtrlB_0_SD_SPEED_SDR_LSB 0x2 +#define QIB_7322_IBCCtrlB_0_SD_SPEED_SDR_MSB 0x2 +#define QIB_7322_IBCCtrlB_0_SD_SPEED_SDR_RMASK 0x1 +#define QIB_7322_IBCCtrlB_0_SD_SPEED_LSB 0x1 +#define QIB_7322_IBCCtrlB_0_SD_SPEED_MSB 0x1 +#define QIB_7322_IBCCtrlB_0_SD_SPEED_RMASK 0x1 +#define QIB_7322_IBCCtrlB_0_IB_ENHANCED_MODE_LSB 0x0 +#define QIB_7322_IBCCtrlB_0_IB_ENHANCED_MODE_MSB 0x0 +#define QIB_7322_IBCCtrlB_0_IB_ENHANCED_MODE_RMASK 0x1 + +#define QIB_7322_IBCCtrlC_0_OFFS 0x1570 +#define QIB_7322_IBCCtrlC_0_DEF 0x0000000000000301 +#define QIB_7322_IBCCtrlC_0_IB_BACK_PORCH_LSB 0x5 +#define QIB_7322_IBCCtrlC_0_IB_BACK_PORCH_MSB 0x9 +#define QIB_7322_IBCCtrlC_0_IB_BACK_PORCH_RMASK 0x1F +#define QIB_7322_IBCCtrlC_0_IB_FRONT_PORCH_LSB 0x0 +#define QIB_7322_IBCCtrlC_0_IB_FRONT_PORCH_MSB 0x4 +#define QIB_7322_IBCCtrlC_0_IB_FRONT_PORCH_RMASK 0x1F + +#define QIB_7322_HRTBT_GUID_0_OFFS 0x1588 +#define QIB_7322_HRTBT_GUID_0_DEF 0x0000000000000000 + +#define QIB_7322_IB_SDTEST_IF_TX_0_OFFS 0x1590 +#define QIB_7322_IB_SDTEST_IF_TX_0_DEF 0x0000000000000000 +#define QIB_7322_IB_SDTEST_IF_TX_0_TS_TX_RX_CFG_LSB 0x30 +#define QIB_7322_IB_SDTEST_IF_TX_0_TS_TX_RX_CFG_MSB 0x3F +#define QIB_7322_IB_SDTEST_IF_TX_0_TS_TX_RX_CFG_RMASK 0xFFFF +#define QIB_7322_IB_SDTEST_IF_TX_0_TS_TX_TX_CFG_LSB 0x20 +#define QIB_7322_IB_SDTEST_IF_TX_0_TS_TX_TX_CFG_MSB 0x2F +#define QIB_7322_IB_SDTEST_IF_TX_0_TS_TX_TX_CFG_RMASK 0xFFFF +#define QIB_7322_IB_SDTEST_IF_TX_0_TS_TX_SPEED_LSB 0xD +#define QIB_7322_IB_SDTEST_IF_TX_0_TS_TX_SPEED_MSB 0xF +#define QIB_7322_IB_SDTEST_IF_TX_0_TS_TX_SPEED_RMASK 0x7 +#define QIB_7322_IB_SDTEST_IF_TX_0_TS_TX_OPCODE_LSB 0xB +#define QIB_7322_IB_SDTEST_IF_TX_0_TS_TX_OPCODE_MSB 0xC +#define QIB_7322_IB_SDTEST_IF_TX_0_TS_TX_OPCODE_RMASK 0x3 +#define QIB_7322_IB_SDTEST_IF_TX_0_CREDIT_CHANGE_LSB 0x4 +#define QIB_7322_IB_SDTEST_IF_TX_0_CREDIT_CHANGE_MSB 0x4 +#define QIB_7322_IB_SDTEST_IF_TX_0_CREDIT_CHANGE_RMASK 0x1 +#define QIB_7322_IB_SDTEST_IF_TX_0_VL_CAP_LSB 0x2 +#define QIB_7322_IB_SDTEST_IF_TX_0_VL_CAP_MSB 0x3 +#define QIB_7322_IB_SDTEST_IF_TX_0_VL_CAP_RMASK 0x3 +#define QIB_7322_IB_SDTEST_IF_TX_0_TS_3_TX_VALID_LSB 0x1 +#define QIB_7322_IB_SDTEST_IF_TX_0_TS_3_TX_VALID_MSB 0x1 +#define QIB_7322_IB_SDTEST_IF_TX_0_TS_3_TX_VALID_RMASK 0x1 +#define QIB_7322_IB_SDTEST_IF_TX_0_TS_T_TX_VALID_LSB 0x0 +#define QIB_7322_IB_SDTEST_IF_TX_0_TS_T_TX_VALID_MSB 0x0 +#define QIB_7322_IB_SDTEST_IF_TX_0_TS_T_TX_VALID_RMASK 0x1 + +#define QIB_7322_IB_SDTEST_IF_RX_0_OFFS 0x1598 +#define QIB_7322_IB_SDTEST_IF_RX_0_DEF 0x0000000000000000 +#define QIB_7322_IB_SDTEST_IF_RX_0_TS_RX_RX_CFG_LSB 0x30 +#define QIB_7322_IB_SDTEST_IF_RX_0_TS_RX_RX_CFG_MSB 0x3F +#define QIB_7322_IB_SDTEST_IF_RX_0_TS_RX_RX_CFG_RMASK 0xFFFF +#define QIB_7322_IB_SDTEST_IF_RX_0_TS_RX_TX_CFG_LSB 0x20 +#define QIB_7322_IB_SDTEST_IF_RX_0_TS_RX_TX_CFG_MSB 0x2F +#define QIB_7322_IB_SDTEST_IF_RX_0_TS_RX_TX_CFG_RMASK 0xFFFF +#define QIB_7322_IB_SDTEST_IF_RX_0_TS_RX_B_LSB 0x18 +#define QIB_7322_IB_SDTEST_IF_RX_0_TS_RX_B_MSB 0x1F +#define QIB_7322_IB_SDTEST_IF_RX_0_TS_RX_B_RMASK 0xFF +#define QIB_7322_IB_SDTEST_IF_RX_0_TS_RX_A_LSB 0x10 +#define QIB_7322_IB_SDTEST_IF_RX_0_TS_RX_A_MSB 0x17 +#define QIB_7322_IB_SDTEST_IF_RX_0_TS_RX_A_RMASK 0xFF +#define QIB_7322_IB_SDTEST_IF_RX_0_TS_3_RX_VALID_LSB 0x1 +#define QIB_7322_IB_SDTEST_IF_RX_0_TS_3_RX_VALID_MSB 0x1 +#define QIB_7322_IB_SDTEST_IF_RX_0_TS_3_RX_VALID_RMASK 0x1 +#define QIB_7322_IB_SDTEST_IF_RX_0_TS_T_RX_VALID_LSB 0x0 +#define QIB_7322_IB_SDTEST_IF_RX_0_TS_T_RX_VALID_MSB 0x0 +#define QIB_7322_IB_SDTEST_IF_RX_0_TS_T_RX_VALID_RMASK 0x1 + +#define QIB_7322_IBNCModeCtrl_0_OFFS 0x15B8 +#define QIB_7322_IBNCModeCtrl_0_DEF 0x0000000000000000 +#define QIB_7322_IBNCModeCtrl_0_ScrambleCapRemoteForce_LSB 0x22 +#define QIB_7322_IBNCModeCtrl_0_ScrambleCapRemoteForce_MSB 0x22 +#define QIB_7322_IBNCModeCtrl_0_ScrambleCapRemoteForce_RMASK 0x1 +#define QIB_7322_IBNCModeCtrl_0_ScrambleCapRemoteMask_LSB 0x21 +#define QIB_7322_IBNCModeCtrl_0_ScrambleCapRemoteMask_MSB 0x21 +#define QIB_7322_IBNCModeCtrl_0_ScrambleCapRemoteMask_RMASK 0x1 +#define QIB_7322_IBNCModeCtrl_0_ScrambleCapLocal_LSB 0x20 +#define QIB_7322_IBNCModeCtrl_0_ScrambleCapLocal_MSB 0x20 +#define QIB_7322_IBNCModeCtrl_0_ScrambleCapLocal_RMASK 0x1 +#define QIB_7322_IBNCModeCtrl_0_TSMCode_TS2_LSB 0x11 +#define QIB_7322_IBNCModeCtrl_0_TSMCode_TS2_MSB 0x19 +#define QIB_7322_IBNCModeCtrl_0_TSMCode_TS2_RMASK 0x1FF +#define QIB_7322_IBNCModeCtrl_0_TSMCode_TS1_LSB 0x8 +#define QIB_7322_IBNCModeCtrl_0_TSMCode_TS1_MSB 0x10 +#define QIB_7322_IBNCModeCtrl_0_TSMCode_TS1_RMASK 0x1FF +#define QIB_7322_IBNCModeCtrl_0_TSMEnable_ignore_TSM_on_rx_LSB 0x2 +#define QIB_7322_IBNCModeCtrl_0_TSMEnable_ignore_TSM_on_rx_MSB 0x2 +#define QIB_7322_IBNCModeCtrl_0_TSMEnable_ignore_TSM_on_rx_RMASK 0x1 +#define QIB_7322_IBNCModeCtrl_0_TSMEnable_send_TS2_LSB 0x1 +#define QIB_7322_IBNCModeCtrl_0_TSMEnable_send_TS2_MSB 0x1 +#define QIB_7322_IBNCModeCtrl_0_TSMEnable_send_TS2_RMASK 0x1 +#define QIB_7322_IBNCModeCtrl_0_TSMEnable_send_TS1_LSB 0x0 +#define QIB_7322_IBNCModeCtrl_0_TSMEnable_send_TS1_MSB 0x0 +#define QIB_7322_IBNCModeCtrl_0_TSMEnable_send_TS1_RMASK 0x1 + +#define QIB_7322_IBSerdesStatus_0_OFFS 0x15D0 +#define QIB_7322_IBSerdesStatus_0_DEF 0x0000000000000000 + +#define QIB_7322_IBPCSConfig_0_OFFS 0x15D8 +#define QIB_7322_IBPCSConfig_0_DEF 0x0000000000000007 +#define QIB_7322_IBPCSConfig_0_link_sync_mask_LSB 0x9 +#define QIB_7322_IBPCSConfig_0_link_sync_mask_MSB 0x12 +#define QIB_7322_IBPCSConfig_0_link_sync_mask_RMASK 0x3FF +#define QIB_7322_IBPCSConfig_0_xcv_rreset_LSB 0x2 +#define QIB_7322_IBPCSConfig_0_xcv_rreset_MSB 0x2 +#define QIB_7322_IBPCSConfig_0_xcv_rreset_RMASK 0x1 +#define QIB_7322_IBPCSConfig_0_xcv_treset_LSB 0x1 +#define QIB_7322_IBPCSConfig_0_xcv_treset_MSB 0x1 +#define QIB_7322_IBPCSConfig_0_xcv_treset_RMASK 0x1 +#define QIB_7322_IBPCSConfig_0_tx_rx_reset_LSB 0x0 +#define QIB_7322_IBPCSConfig_0_tx_rx_reset_MSB 0x0 +#define QIB_7322_IBPCSConfig_0_tx_rx_reset_RMASK 0x1 + +#define QIB_7322_IBSerdesCtrl_0_OFFS 0x15E0 +#define QIB_7322_IBSerdesCtrl_0_DEF 0x0000000000FFA00F +#define QIB_7322_IBSerdesCtrl_0_DISABLE_RXLATOFF_QDR_LSB 0x1A +#define QIB_7322_IBSerdesCtrl_0_DISABLE_RXLATOFF_QDR_MSB 0x1A +#define QIB_7322_IBSerdesCtrl_0_DISABLE_RXLATOFF_QDR_RMASK 0x1 +#define QIB_7322_IBSerdesCtrl_0_DISABLE_RXLATOFF_DDR_LSB 0x19 +#define QIB_7322_IBSerdesCtrl_0_DISABLE_RXLATOFF_DDR_MSB 0x19 +#define QIB_7322_IBSerdesCtrl_0_DISABLE_RXLATOFF_DDR_RMASK 0x1 +#define QIB_7322_IBSerdesCtrl_0_DISABLE_RXLATOFF_SDR_LSB 0x18 +#define QIB_7322_IBSerdesCtrl_0_DISABLE_RXLATOFF_SDR_MSB 0x18 +#define QIB_7322_IBSerdesCtrl_0_DISABLE_RXLATOFF_SDR_RMASK 0x1 +#define QIB_7322_IBSerdesCtrl_0_CHANNEL_RESET_N_LSB 0x14 +#define QIB_7322_IBSerdesCtrl_0_CHANNEL_RESET_N_MSB 0x17 +#define QIB_7322_IBSerdesCtrl_0_CHANNEL_RESET_N_RMASK 0xF +#define QIB_7322_IBSerdesCtrl_0_CGMODE_LSB 0x10 +#define QIB_7322_IBSerdesCtrl_0_CGMODE_MSB 0x13 +#define QIB_7322_IBSerdesCtrl_0_CGMODE_RMASK 0xF +#define QIB_7322_IBSerdesCtrl_0_IB_LAT_MODE_LSB 0xF +#define QIB_7322_IBSerdesCtrl_0_IB_LAT_MODE_MSB 0xF +#define QIB_7322_IBSerdesCtrl_0_IB_LAT_MODE_RMASK 0x1 +#define QIB_7322_IBSerdesCtrl_0_RXLOSEN_LSB 0xD +#define QIB_7322_IBSerdesCtrl_0_RXLOSEN_MSB 0xD +#define QIB_7322_IBSerdesCtrl_0_RXLOSEN_RMASK 0x1 +#define QIB_7322_IBSerdesCtrl_0_LPEN_LSB 0xC +#define QIB_7322_IBSerdesCtrl_0_LPEN_MSB 0xC +#define QIB_7322_IBSerdesCtrl_0_LPEN_RMASK 0x1 +#define QIB_7322_IBSerdesCtrl_0_PLLPD_LSB 0xB +#define QIB_7322_IBSerdesCtrl_0_PLLPD_MSB 0xB +#define QIB_7322_IBSerdesCtrl_0_PLLPD_RMASK 0x1 +#define QIB_7322_IBSerdesCtrl_0_TXPD_LSB 0xA +#define QIB_7322_IBSerdesCtrl_0_TXPD_MSB 0xA +#define QIB_7322_IBSerdesCtrl_0_TXPD_RMASK 0x1 +#define QIB_7322_IBSerdesCtrl_0_RXPD_LSB 0x9 +#define QIB_7322_IBSerdesCtrl_0_RXPD_MSB 0x9 +#define QIB_7322_IBSerdesCtrl_0_RXPD_RMASK 0x1 +#define QIB_7322_IBSerdesCtrl_0_TXIDLE_LSB 0x8 +#define QIB_7322_IBSerdesCtrl_0_TXIDLE_MSB 0x8 +#define QIB_7322_IBSerdesCtrl_0_TXIDLE_RMASK 0x1 +#define QIB_7322_IBSerdesCtrl_0_CMODE_LSB 0x0 +#define QIB_7322_IBSerdesCtrl_0_CMODE_MSB 0x6 +#define QIB_7322_IBSerdesCtrl_0_CMODE_RMASK 0x7F + +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_OFFS 0x1600 +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_DEF 0x0000000000000000 +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_tx_override_deemphasis_select_LSB 0x1F +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_tx_override_deemphasis_select_MSB 0x1F +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_tx_override_deemphasis_select_RMASK 0x1 +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_reset_tx_deemphasis_override_LSB 0x1E +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_reset_tx_deemphasis_override_MSB 0x1E +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_reset_tx_deemphasis_override_RMASK 0x1 +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_txampcntl_d2a_LSB 0xE +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_txampcntl_d2a_MSB 0x11 +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_txampcntl_d2a_RMASK 0xF +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_txc0_ena_LSB 0x9 +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_txc0_ena_MSB 0xD +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_txc0_ena_RMASK 0x1F +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_txcp1_ena_LSB 0x5 +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_txcp1_ena_MSB 0x8 +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_txcp1_ena_RMASK 0xF +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_txcn1_xtra_emph0_LSB 0x3 +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_txcn1_xtra_emph0_MSB 0x4 +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_txcn1_xtra_emph0_RMASK 0x3 +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_txcn1_ena_LSB 0x0 +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_txcn1_ena_MSB 0x2 +#define QIB_7322_IBSD_TX_DEEMPHASIS_OVERRIDE_0_txcn1_ena_RMASK 0x7 + +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_OFFS 0x1640 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_DEF 0x0000000000000000 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenagain_sdr_ch3_LSB 0x27 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenagain_sdr_ch3_MSB 0x27 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenagain_sdr_ch3_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenagain_sdr_ch2_LSB 0x26 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenagain_sdr_ch2_MSB 0x26 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenagain_sdr_ch2_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenagain_sdr_ch1_LSB 0x25 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenagain_sdr_ch1_MSB 0x25 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenagain_sdr_ch1_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenagain_sdr_ch0_LSB 0x24 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenagain_sdr_ch0_MSB 0x24 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenagain_sdr_ch0_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenale_sdr_ch3_LSB 0x23 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenale_sdr_ch3_MSB 0x23 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenale_sdr_ch3_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenale_sdr_ch2_LSB 0x22 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenale_sdr_ch2_MSB 0x22 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenale_sdr_ch2_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenale_sdr_ch1_LSB 0x21 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenale_sdr_ch1_MSB 0x21 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenale_sdr_ch1_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenale_sdr_ch0_LSB 0x20 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenale_sdr_ch0_MSB 0x20 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenale_sdr_ch0_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenadfe_sdr_ch3_LSB 0x18 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenadfe_sdr_ch3_MSB 0x1F +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenadfe_sdr_ch3_RMASK 0xFF +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenadfe_sdr_ch2_LSB 0x10 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenadfe_sdr_ch2_MSB 0x17 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenadfe_sdr_ch2_RMASK 0xFF +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenadfe_sdr_ch1_LSB 0x8 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenadfe_sdr_ch1_MSB 0xF +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenadfe_sdr_ch1_RMASK 0xFF +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenadfe_sdr_ch0_LSB 0x0 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenadfe_sdr_ch0_MSB 0x7 +#define QIB_7322_ADAPT_DISABLE_STATIC_SDR_0_static_disable_rxenadfe_sdr_ch0_RMASK 0xFF + +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_OFFS 0x1648 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_DEF 0x0000000000000000 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenagain_sdr_ch3_LSB 0x27 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenagain_sdr_ch3_MSB 0x27 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenagain_sdr_ch3_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenagain_sdr_ch2_LSB 0x26 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenagain_sdr_ch2_MSB 0x26 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenagain_sdr_ch2_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenagain_sdr_ch1_LSB 0x25 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenagain_sdr_ch1_MSB 0x25 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenagain_sdr_ch1_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenagain_sdr_ch0_LSB 0x24 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenagain_sdr_ch0_MSB 0x24 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenagain_sdr_ch0_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenale_sdr_ch3_LSB 0x23 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenale_sdr_ch3_MSB 0x23 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenale_sdr_ch3_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenale_sdr_ch2_LSB 0x22 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenale_sdr_ch2_MSB 0x22 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenale_sdr_ch2_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenale_sdr_ch1_LSB 0x21 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenale_sdr_ch1_MSB 0x21 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenale_sdr_ch1_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenale_sdr_ch0_LSB 0x20 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenale_sdr_ch0_MSB 0x20 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenale_sdr_ch0_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenadfe_sdr_ch3_LSB 0x18 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenadfe_sdr_ch3_MSB 0x1F +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenadfe_sdr_ch3_RMASK 0xFF +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenadfe_sdr_ch2_LSB 0x10 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenadfe_sdr_ch2_MSB 0x17 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenadfe_sdr_ch2_RMASK 0xFF +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenadfe_sdr_ch1_LSB 0x8 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenadfe_sdr_ch1_MSB 0xF +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenadfe_sdr_ch1_RMASK 0xFF +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenadfe_sdr_ch0_LSB 0x0 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenadfe_sdr_ch0_MSB 0x7 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_SDR_0_dyn_disable_rxenadfe_sdr_ch0_RMASK 0xFF + +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_OFFS 0x1650 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_DEF 0x0000000000000000 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenagain_ddr_ch3_LSB 0x27 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenagain_ddr_ch3_MSB 0x27 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenagain_ddr_ch3_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenagain_ddr_ch2_LSB 0x26 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenagain_ddr_ch2_MSB 0x26 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenagain_ddr_ch2_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenagain_ddr_ch1_LSB 0x25 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenagain_ddr_ch1_MSB 0x25 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenagain_ddr_ch1_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenagain_ddr_ch0_LSB 0x24 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenagain_ddr_ch0_MSB 0x24 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenagain_ddr_ch0_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenale_ddr_ch3_LSB 0x23 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenale_ddr_ch3_MSB 0x23 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenale_ddr_ch3_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenale_ddr_ch2_LSB 0x22 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenale_ddr_ch2_MSB 0x22 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenale_ddr_ch2_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenale_ddr_ch1_LSB 0x21 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenale_ddr_ch1_MSB 0x21 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenale_ddr_ch1_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenale_ddr_ch0_LSB 0x20 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenale_ddr_ch0_MSB 0x20 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenale_ddr_ch0_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenadfe_ddr_ch3_LSB 0x18 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenadfe_ddr_ch3_MSB 0x1F +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenadfe_ddr_ch3_RMASK 0xFF +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenadfe_ddr_ch2_LSB 0x10 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenadfe_ddr_ch2_MSB 0x17 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenadfe_ddr_ch2_RMASK 0xFF +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenadfe_ddr_ch1_LSB 0x8 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenadfe_ddr_ch1_MSB 0xF +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenadfe_ddr_ch1_RMASK 0xFF +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenadfe_ddr_ch0_LSB 0x0 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenadfe_ddr_ch0_MSB 0x7 +#define QIB_7322_ADAPT_DISABLE_STATIC_DDR_0_static_disable_rxenadfe_ddr_ch0_RMASK 0xFF + +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_OFFS 0x1658 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_DEF 0x0000000000000000 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenagain_ddr_ch3_LSB 0x27 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenagain_ddr_ch3_MSB 0x27 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenagain_ddr_ch3_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenagain_ddr_ch2_LSB 0x26 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenagain_ddr_ch2_MSB 0x26 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenagain_ddr_ch2_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenagain_ddr_ch1_LSB 0x25 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenagain_ddr_ch1_MSB 0x25 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenagain_ddr_ch1_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenagain_ddr_ch0_LSB 0x24 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenagain_ddr_ch0_MSB 0x24 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenagain_ddr_ch0_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenale_ddr_ch3_LSB 0x23 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenale_ddr_ch3_MSB 0x23 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenale_ddr_ch3_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenale_ddr_ch2_LSB 0x22 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenale_ddr_ch2_MSB 0x22 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenale_ddr_ch2_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenale_ddr_ch1_LSB 0x21 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenale_ddr_ch1_MSB 0x21 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenale_ddr_ch1_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenale_ddr_ch0_LSB 0x20 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenale_ddr_ch0_MSB 0x20 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenale_ddr_ch0_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenadfe_ddr_ch3_LSB 0x18 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenadfe_ddr_ch3_MSB 0x1F +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenadfe_ddr_ch3_RMASK 0xFF +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenadfe_ddr_ch2_LSB 0x10 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenadfe_ddr_ch2_MSB 0x17 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenadfe_ddr_ch2_RMASK 0xFF +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenadfe_ddr_ch1_LSB 0x8 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenadfe_ddr_ch1_MSB 0xF +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenadfe_ddr_ch1_RMASK 0xFF +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenadfe_ddr_ch0_LSB 0x0 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenadfe_ddr_ch0_MSB 0x7 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_DDR_0_dyn_disable_rxenadfe_ddr_ch0_RMASK 0xFF + +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_OFFS 0x1660 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_DEF 0x0000000000000000 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenagain_qdr_ch3_LSB 0x27 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenagain_qdr_ch3_MSB 0x27 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenagain_qdr_ch3_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenagain_qdr_ch2_LSB 0x26 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenagain_qdr_ch2_MSB 0x26 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenagain_qdr_ch2_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenagain_qdr_ch1_LSB 0x25 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenagain_qdr_ch1_MSB 0x25 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenagain_qdr_ch1_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenagain_qdr_ch0_LSB 0x24 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenagain_qdr_ch0_MSB 0x24 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenagain_qdr_ch0_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenale_qdr_ch3_LSB 0x23 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenale_qdr_ch3_MSB 0x23 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenale_qdr_ch3_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenale_qdr_ch2_LSB 0x22 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenale_qdr_ch2_MSB 0x22 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenale_qdr_ch2_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenale_qdr_ch1_LSB 0x21 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenale_qdr_ch1_MSB 0x21 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenale_qdr_ch1_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenale_qdr_ch0_LSB 0x20 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenale_qdr_ch0_MSB 0x20 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenale_qdr_ch0_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenadfe_qdr_ch3_LSB 0x18 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenadfe_qdr_ch3_MSB 0x1F +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenadfe_qdr_ch3_RMASK 0xFF +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenadfe_qdr_ch2_LSB 0x10 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenadfe_qdr_ch2_MSB 0x17 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenadfe_qdr_ch2_RMASK 0xFF +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenadfe_qdr_ch1_LSB 0x8 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenadfe_qdr_ch1_MSB 0xF +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenadfe_qdr_ch1_RMASK 0xFF +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenadfe_qdr_ch0_LSB 0x0 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenadfe_qdr_ch0_MSB 0x7 +#define QIB_7322_ADAPT_DISABLE_STATIC_QDR_0_static_disable_rxenadfe_qdr_ch0_RMASK 0xFF + +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_OFFS 0x1668 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_DEF 0x0000000000000000 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenagain_qdr_ch3_LSB 0x27 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenagain_qdr_ch3_MSB 0x27 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenagain_qdr_ch3_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenagain_qdr_ch2_LSB 0x26 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenagain_qdr_ch2_MSB 0x26 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenagain_qdr_ch2_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenagain_qdr_ch1_LSB 0x25 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenagain_qdr_ch1_MSB 0x25 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenagain_qdr_ch1_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenagain_qdr_ch0_LSB 0x24 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenagain_qdr_ch0_MSB 0x24 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenagain_qdr_ch0_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenale_qdr_ch3_LSB 0x23 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenale_qdr_ch3_MSB 0x23 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenale_qdr_ch3_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenale_qdr_ch2_LSB 0x22 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenale_qdr_ch2_MSB 0x22 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenale_qdr_ch2_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenale_qdr_ch1_LSB 0x21 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenale_qdr_ch1_MSB 0x21 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenale_qdr_ch1_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenale_qdr_ch0_LSB 0x20 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenale_qdr_ch0_MSB 0x20 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenale_qdr_ch0_RMASK 0x1 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenadfe_qdr_ch3_LSB 0x18 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenadfe_qdr_ch3_MSB 0x1F +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenadfe_qdr_ch3_RMASK 0xFF +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenadfe_qdr_ch2_LSB 0x10 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenadfe_qdr_ch2_MSB 0x17 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenadfe_qdr_ch2_RMASK 0xFF +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenadfe_qdr_ch1_LSB 0x8 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenadfe_qdr_ch1_MSB 0xF +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenadfe_qdr_ch1_RMASK 0xFF +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenadfe_qdr_ch0_LSB 0x0 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenadfe_qdr_ch0_MSB 0x7 +#define QIB_7322_ADAPT_DISABLE_DYNAMIC_QDR_0_dyn_disable_rxenadfe_qdr_ch0_RMASK 0xFF + +#define QIB_7322_ADAPT_DISABLE_TIMER_THRESHOLD_0_OFFS 0x1670 +#define QIB_7322_ADAPT_DISABLE_TIMER_THRESHOLD_0_DEF 0x0000000000000000 + +#define QIB_7322_HighPriorityLimit_0_OFFS 0x1BC0 +#define QIB_7322_HighPriorityLimit_0_DEF 0x0000000000000000 +#define QIB_7322_HighPriorityLimit_0_Limit_LSB 0x0 +#define QIB_7322_HighPriorityLimit_0_Limit_MSB 0x7 +#define QIB_7322_HighPriorityLimit_0_Limit_RMASK 0xFF + +#define QIB_7322_LowPriority0_0_OFFS 0x1C00 +#define QIB_7322_LowPriority0_0_DEF 0x0000000000000000 +#define QIB_7322_LowPriority0_0_VirtualLane_LSB 0x10 +#define QIB_7322_LowPriority0_0_VirtualLane_MSB 0x12 +#define QIB_7322_LowPriority0_0_VirtualLane_RMASK 0x7 +#define QIB_7322_LowPriority0_0_Weight_LSB 0x0 +#define QIB_7322_LowPriority0_0_Weight_MSB 0x7 +#define QIB_7322_LowPriority0_0_Weight_RMASK 0xFF + +#define QIB_7322_HighPriority0_0_OFFS 0x1E00 +#define QIB_7322_HighPriority0_0_DEF 0x0000000000000000 +#define QIB_7322_HighPriority0_0_VirtualLane_LSB 0x10 +#define QIB_7322_HighPriority0_0_VirtualLane_MSB 0x12 +#define QIB_7322_HighPriority0_0_VirtualLane_RMASK 0x7 +#define QIB_7322_HighPriority0_0_Weight_LSB 0x0 +#define QIB_7322_HighPriority0_0_Weight_MSB 0x7 +#define QIB_7322_HighPriority0_0_Weight_RMASK 0xFF + +#define QIB_7322_CntrRegBase_1_OFFS 0x2028 +#define QIB_7322_CntrRegBase_1_DEF 0x0000000000013000 + +#define QIB_7322_RcvQPMulticastContext_1_OFFS 0x2170 + +#define QIB_7322_SendCtrl_1_OFFS 0x21C0 + +#define QIB_7322_SendBufAvail0_OFFS 0x3000 +#define QIB_7322_SendBufAvail0_DEF 0x0000000000000000 +#define QIB_7322_SendBufAvail0_SendBuf_31_0_LSB 0x0 +#define QIB_7322_SendBufAvail0_SendBuf_31_0_MSB 0x3F +#define QIB_7322_SendBufAvail0_SendBuf_31_0_RMASK 0x0 + +#define QIB_7322_MsixTable_OFFS 0x8000 +#define QIB_7322_MsixTable_DEF 0x0000000000000000 + +#define QIB_7322_MsixPba_OFFS 0x9000 +#define QIB_7322_MsixPba_DEF 0x0000000000000000 + +#define QIB_7322_LAMemory_OFFS 0xA000 +#define QIB_7322_LAMemory_DEF 0x0000000000000000 + +#define QIB_7322_LBIntCnt_OFFS 0x11000 +#define QIB_7322_LBIntCnt_DEF 0x0000000000000000 + +#define QIB_7322_LBFlowStallCnt_OFFS 0x11008 +#define QIB_7322_LBFlowStallCnt_DEF 0x0000000000000000 + +#define QIB_7322_RxTIDFullErrCnt_OFFS 0x110D0 +#define QIB_7322_RxTIDFullErrCnt_DEF 0x0000000000000000 + +#define QIB_7322_RxTIDValidErrCnt_OFFS 0x110D8 +#define QIB_7322_RxTIDValidErrCnt_DEF 0x0000000000000000 + +#define QIB_7322_RxP0HdrEgrOvflCnt_OFFS 0x110E8 +#define QIB_7322_RxP0HdrEgrOvflCnt_DEF 0x0000000000000000 + +#define QIB_7322_PcieRetryBufDiagQwordCnt_OFFS 0x111A0 +#define QIB_7322_PcieRetryBufDiagQwordCnt_DEF 0x0000000000000000 + +#define QIB_7322_RxTidFlowDropCnt_OFFS 0x111E0 +#define QIB_7322_RxTidFlowDropCnt_DEF 0x0000000000000000 + +#define QIB_7322_LBIntCnt_0_OFFS 0x12000 +#define QIB_7322_LBIntCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_TxCreditUpToDateTimeOut_0_OFFS 0x12008 +#define QIB_7322_TxCreditUpToDateTimeOut_0_DEF 0x0000000000000000 + +#define QIB_7322_TxSDmaDescCnt_0_OFFS 0x12010 +#define QIB_7322_TxSDmaDescCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_TxUnsupVLErrCnt_0_OFFS 0x12018 +#define QIB_7322_TxUnsupVLErrCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_TxDataPktCnt_0_OFFS 0x12020 +#define QIB_7322_TxDataPktCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_TxFlowPktCnt_0_OFFS 0x12028 +#define QIB_7322_TxFlowPktCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_TxDwordCnt_0_OFFS 0x12030 +#define QIB_7322_TxDwordCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_TxLenErrCnt_0_OFFS 0x12038 +#define QIB_7322_TxLenErrCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_TxMaxMinLenErrCnt_0_OFFS 0x12040 +#define QIB_7322_TxMaxMinLenErrCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_TxUnderrunCnt_0_OFFS 0x12048 +#define QIB_7322_TxUnderrunCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_TxFlowStallCnt_0_OFFS 0x12050 +#define QIB_7322_TxFlowStallCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_TxDroppedPktCnt_0_OFFS 0x12058 +#define QIB_7322_TxDroppedPktCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxDroppedPktCnt_0_OFFS 0x12060 +#define QIB_7322_RxDroppedPktCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxDataPktCnt_0_OFFS 0x12068 +#define QIB_7322_RxDataPktCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxFlowPktCnt_0_OFFS 0x12070 +#define QIB_7322_RxFlowPktCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxDwordCnt_0_OFFS 0x12078 +#define QIB_7322_RxDwordCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxLenErrCnt_0_OFFS 0x12080 +#define QIB_7322_RxLenErrCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxMaxMinLenErrCnt_0_OFFS 0x12088 +#define QIB_7322_RxMaxMinLenErrCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxICRCErrCnt_0_OFFS 0x12090 +#define QIB_7322_RxICRCErrCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxVCRCErrCnt_0_OFFS 0x12098 +#define QIB_7322_RxVCRCErrCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxFlowCtrlViolCnt_0_OFFS 0x120A0 +#define QIB_7322_RxFlowCtrlViolCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxVersionErrCnt_0_OFFS 0x120A8 +#define QIB_7322_RxVersionErrCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxLinkMalformCnt_0_OFFS 0x120B0 +#define QIB_7322_RxLinkMalformCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxEBPCnt_0_OFFS 0x120B8 +#define QIB_7322_RxEBPCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxLPCRCErrCnt_0_OFFS 0x120C0 +#define QIB_7322_RxLPCRCErrCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxBufOvflCnt_0_OFFS 0x120C8 +#define QIB_7322_RxBufOvflCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxLenTruncateCnt_0_OFFS 0x120D0 +#define QIB_7322_RxLenTruncateCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxPKeyMismatchCnt_0_OFFS 0x120E0 +#define QIB_7322_RxPKeyMismatchCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_IBLinkDownedCnt_0_OFFS 0x12180 +#define QIB_7322_IBLinkDownedCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_IBSymbolErrCnt_0_OFFS 0x12188 +#define QIB_7322_IBSymbolErrCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_IBStatusChangeCnt_0_OFFS 0x12190 +#define QIB_7322_IBStatusChangeCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_IBLinkErrRecoveryCnt_0_OFFS 0x12198 +#define QIB_7322_IBLinkErrRecoveryCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_ExcessBufferOvflCnt_0_OFFS 0x121A8 +#define QIB_7322_ExcessBufferOvflCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_LocalLinkIntegrityErrCnt_0_OFFS 0x121B0 +#define QIB_7322_LocalLinkIntegrityErrCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxVlErrCnt_0_OFFS 0x121B8 +#define QIB_7322_RxVlErrCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxDlidFltrCnt_0_OFFS 0x121C0 +#define QIB_7322_RxDlidFltrCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxVL15DroppedPktCnt_0_OFFS 0x121C8 +#define QIB_7322_RxVL15DroppedPktCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxOtherLocalPhyErrCnt_0_OFFS 0x121D0 +#define QIB_7322_RxOtherLocalPhyErrCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_RxQPInvalidContextCnt_0_OFFS 0x121D8 +#define QIB_7322_RxQPInvalidContextCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_TxHeadersErrCnt_0_OFFS 0x121F8 +#define QIB_7322_TxHeadersErrCnt_0_DEF 0x0000000000000000 + +#define QIB_7322_PSRcvDataCount_0_OFFS 0x12218 +#define QIB_7322_PSRcvDataCount_0_DEF 0x0000000000000000 + +#define QIB_7322_PSRcvPktsCount_0_OFFS 0x12220 +#define QIB_7322_PSRcvPktsCount_0_DEF 0x0000000000000000 + +#define QIB_7322_PSXmitDataCount_0_OFFS 0x12228 +#define QIB_7322_PSXmitDataCount_0_DEF 0x0000000000000000 + +#define QIB_7322_PSXmitPktsCount_0_OFFS 0x12230 +#define QIB_7322_PSXmitPktsCount_0_DEF 0x0000000000000000 + +#define QIB_7322_PSXmitWaitCount_0_OFFS 0x12238 +#define QIB_7322_PSXmitWaitCount_0_DEF 0x0000000000000000 + +#define QIB_7322_LBIntCnt_1_OFFS 0x13000 +#define QIB_7322_LBIntCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_TxCreditUpToDateTimeOut_1_OFFS 0x13008 +#define QIB_7322_TxCreditUpToDateTimeOut_1_DEF 0x0000000000000000 + +#define QIB_7322_TxSDmaDescCnt_1_OFFS 0x13010 +#define QIB_7322_TxSDmaDescCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_TxUnsupVLErrCnt_1_OFFS 0x13018 +#define QIB_7322_TxUnsupVLErrCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_TxDataPktCnt_1_OFFS 0x13020 +#define QIB_7322_TxDataPktCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_TxFlowPktCnt_1_OFFS 0x13028 +#define QIB_7322_TxFlowPktCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_TxDwordCnt_1_OFFS 0x13030 +#define QIB_7322_TxDwordCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_TxLenErrCnt_1_OFFS 0x13038 +#define QIB_7322_TxLenErrCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_TxMaxMinLenErrCnt_1_OFFS 0x13040 +#define QIB_7322_TxMaxMinLenErrCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_TxUnderrunCnt_1_OFFS 0x13048 +#define QIB_7322_TxUnderrunCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_TxFlowStallCnt_1_OFFS 0x13050 +#define QIB_7322_TxFlowStallCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_TxDroppedPktCnt_1_OFFS 0x13058 +#define QIB_7322_TxDroppedPktCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxDroppedPktCnt_1_OFFS 0x13060 +#define QIB_7322_RxDroppedPktCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxDataPktCnt_1_OFFS 0x13068 +#define QIB_7322_RxDataPktCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxFlowPktCnt_1_OFFS 0x13070 +#define QIB_7322_RxFlowPktCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxDwordCnt_1_OFFS 0x13078 +#define QIB_7322_RxDwordCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxLenErrCnt_1_OFFS 0x13080 +#define QIB_7322_RxLenErrCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxMaxMinLenErrCnt_1_OFFS 0x13088 +#define QIB_7322_RxMaxMinLenErrCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxICRCErrCnt_1_OFFS 0x13090 +#define QIB_7322_RxICRCErrCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxVCRCErrCnt_1_OFFS 0x13098 +#define QIB_7322_RxVCRCErrCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxFlowCtrlViolCnt_1_OFFS 0x130A0 +#define QIB_7322_RxFlowCtrlViolCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxVersionErrCnt_1_OFFS 0x130A8 +#define QIB_7322_RxVersionErrCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxLinkMalformCnt_1_OFFS 0x130B0 +#define QIB_7322_RxLinkMalformCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxEBPCnt_1_OFFS 0x130B8 +#define QIB_7322_RxEBPCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxLPCRCErrCnt_1_OFFS 0x130C0 +#define QIB_7322_RxLPCRCErrCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxBufOvflCnt_1_OFFS 0x130C8 +#define QIB_7322_RxBufOvflCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxLenTruncateCnt_1_OFFS 0x130D0 +#define QIB_7322_RxLenTruncateCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxPKeyMismatchCnt_1_OFFS 0x130E0 +#define QIB_7322_RxPKeyMismatchCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_IBLinkDownedCnt_1_OFFS 0x13180 +#define QIB_7322_IBLinkDownedCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_IBSymbolErrCnt_1_OFFS 0x13188 +#define QIB_7322_IBSymbolErrCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_IBStatusChangeCnt_1_OFFS 0x13190 +#define QIB_7322_IBStatusChangeCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_IBLinkErrRecoveryCnt_1_OFFS 0x13198 +#define QIB_7322_IBLinkErrRecoveryCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_ExcessBufferOvflCnt_1_OFFS 0x131A8 +#define QIB_7322_ExcessBufferOvflCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_LocalLinkIntegrityErrCnt_1_OFFS 0x131B0 +#define QIB_7322_LocalLinkIntegrityErrCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxVlErrCnt_1_OFFS 0x131B8 +#define QIB_7322_RxVlErrCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxDlidFltrCnt_1_OFFS 0x131C0 +#define QIB_7322_RxDlidFltrCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxVL15DroppedPktCnt_1_OFFS 0x131C8 +#define QIB_7322_RxVL15DroppedPktCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxOtherLocalPhyErrCnt_1_OFFS 0x131D0 +#define QIB_7322_RxOtherLocalPhyErrCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_RxQPInvalidContextCnt_1_OFFS 0x131D8 +#define QIB_7322_RxQPInvalidContextCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_TxHeadersErrCnt_1_OFFS 0x131F8 +#define QIB_7322_TxHeadersErrCnt_1_DEF 0x0000000000000000 + +#define QIB_7322_PSRcvDataCount_1_OFFS 0x13218 +#define QIB_7322_PSRcvDataCount_1_DEF 0x0000000000000000 + +#define QIB_7322_PSRcvPktsCount_1_OFFS 0x13220 +#define QIB_7322_PSRcvPktsCount_1_DEF 0x0000000000000000 + +#define QIB_7322_PSXmitDataCount_1_OFFS 0x13228 +#define QIB_7322_PSXmitDataCount_1_DEF 0x0000000000000000 + +#define QIB_7322_PSXmitPktsCount_1_OFFS 0x13230 +#define QIB_7322_PSXmitPktsCount_1_DEF 0x0000000000000000 + +#define QIB_7322_PSXmitWaitCount_1_OFFS 0x13238 +#define QIB_7322_PSXmitWaitCount_1_DEF 0x0000000000000000 + +#define QIB_7322_RcvEgrArray_OFFS 0x14000 +#define QIB_7322_RcvEgrArray_DEF 0x0000000000000000 +#define QIB_7322_RcvEgrArray_RT_BufSize_LSB 0x25 +#define QIB_7322_RcvEgrArray_RT_BufSize_MSB 0x27 +#define QIB_7322_RcvEgrArray_RT_BufSize_RMASK 0x7 +#define QIB_7322_RcvEgrArray_RT_Addr_LSB 0x0 +#define QIB_7322_RcvEgrArray_RT_Addr_MSB 0x24 +#define QIB_7322_RcvEgrArray_RT_Addr_RMASK 0x1FFFFFFFFF + +#define QIB_7322_RcvTIDArray0_OFFS 0x50000 +#define QIB_7322_RcvTIDArray0_DEF 0x0000000000000000 +#define QIB_7322_RcvTIDArray0_RT_BufSize_LSB 0x25 +#define QIB_7322_RcvTIDArray0_RT_BufSize_MSB 0x27 +#define QIB_7322_RcvTIDArray0_RT_BufSize_RMASK 0x7 +#define QIB_7322_RcvTIDArray0_RT_Addr_LSB 0x0 +#define QIB_7322_RcvTIDArray0_RT_Addr_MSB 0x24 +#define QIB_7322_RcvTIDArray0_RT_Addr_RMASK 0x1FFFFFFFFF + +#define QIB_7322_IBSD_DDS_MAP_TABLE_0_OFFS 0xD0000 +#define QIB_7322_IBSD_DDS_MAP_TABLE_0_DEF 0x0000000000000000 + +#define QIB_7322_RcvHdrTail0_OFFS 0x200000 +#define QIB_7322_RcvHdrTail0_DEF 0x0000000000000000 + +#define QIB_7322_RcvHdrHead0_OFFS 0x200008 +#define QIB_7322_RcvHdrHead0_DEF 0x0000000000000000 +#define QIB_7322_RcvHdrHead0_counter_LSB 0x20 +#define QIB_7322_RcvHdrHead0_counter_MSB 0x2F +#define QIB_7322_RcvHdrHead0_counter_RMASK 0xFFFF +#define QIB_7322_RcvHdrHead0_RcvHeadPointer_LSB 0x0 +#define QIB_7322_RcvHdrHead0_RcvHeadPointer_MSB 0x1F +#define QIB_7322_RcvHdrHead0_RcvHeadPointer_RMASK 0xFFFFFFFF + +#define QIB_7322_RcvEgrIndexTail0_OFFS 0x200010 +#define QIB_7322_RcvEgrIndexTail0_DEF 0x0000000000000000 + +#define QIB_7322_RcvEgrIndexHead0_OFFS 0x200018 +#define QIB_7322_RcvEgrIndexHead0_DEF 0x0000000000000000 + +#define QIB_7322_RcvTIDFlowTable0_OFFS 0x201000 +#define QIB_7322_RcvTIDFlowTable0_DEF 0x0000000000000000 +#define QIB_7322_RcvTIDFlowTable0_GenMismatch_LSB 0x1C +#define QIB_7322_RcvTIDFlowTable0_GenMismatch_MSB 0x1C +#define QIB_7322_RcvTIDFlowTable0_GenMismatch_RMASK 0x1 +#define QIB_7322_RcvTIDFlowTable0_SeqMismatch_LSB 0x1B +#define QIB_7322_RcvTIDFlowTable0_SeqMismatch_MSB 0x1B +#define QIB_7322_RcvTIDFlowTable0_SeqMismatch_RMASK 0x1 +#define QIB_7322_RcvTIDFlowTable0_KeepOnGenErr_LSB 0x16 +#define QIB_7322_RcvTIDFlowTable0_KeepOnGenErr_MSB 0x16 +#define QIB_7322_RcvTIDFlowTable0_KeepOnGenErr_RMASK 0x1 +#define QIB_7322_RcvTIDFlowTable0_KeepAfterSeqErr_LSB 0x15 +#define QIB_7322_RcvTIDFlowTable0_KeepAfterSeqErr_MSB 0x15 +#define QIB_7322_RcvTIDFlowTable0_KeepAfterSeqErr_RMASK 0x1 +#define QIB_7322_RcvTIDFlowTable0_HdrSuppEnabled_LSB 0x14 +#define QIB_7322_RcvTIDFlowTable0_HdrSuppEnabled_MSB 0x14 +#define QIB_7322_RcvTIDFlowTable0_HdrSuppEnabled_RMASK 0x1 +#define QIB_7322_RcvTIDFlowTable0_FlowValid_LSB 0x13 +#define QIB_7322_RcvTIDFlowTable0_FlowValid_MSB 0x13 +#define QIB_7322_RcvTIDFlowTable0_FlowValid_RMASK 0x1 +#define QIB_7322_RcvTIDFlowTable0_GenVal_LSB 0xB +#define QIB_7322_RcvTIDFlowTable0_GenVal_MSB 0x12 +#define QIB_7322_RcvTIDFlowTable0_GenVal_RMASK 0xFF +#define QIB_7322_RcvTIDFlowTable0_SeqNum_LSB 0x0 +#define QIB_7322_RcvTIDFlowTable0_SeqNum_MSB 0xA +#define QIB_7322_RcvTIDFlowTable0_SeqNum_RMASK 0x7FF diff --git a/drivers/infiniband/hw/qib/qib_common.h b/drivers/infiniband/hw/qib/qib_common.h new file mode 100644 index 000000000000..b3955ed8f794 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_common.h @@ -0,0 +1,758 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation. + * All rights reserved. + * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _QIB_COMMON_H +#define _QIB_COMMON_H + +/* + * This file contains defines, structures, etc. that are used + * to communicate between kernel and user code. + */ + +/* This is the IEEE-assigned OUI for QLogic Inc. QLogic_IB */ +#define QIB_SRC_OUI_1 0x00 +#define QIB_SRC_OUI_2 0x11 +#define QIB_SRC_OUI_3 0x75 + +/* version of protocol header (known to chip also). In the long run, + * we should be able to generate and accept a range of version numbers; + * for now we only accept one, and it's compiled in. + */ +#define IPS_PROTO_VERSION 2 + +/* + * These are compile time constants that you may want to enable or disable + * if you are trying to debug problems with code or performance. + * QIB_VERBOSE_TRACING define as 1 if you want additional tracing in + * fastpath code + * QIB_TRACE_REGWRITES define as 1 if you want register writes to be + * traced in faspath code + * _QIB_TRACING define as 0 if you want to remove all tracing in a + * compilation unit + */ + +/* + * The value in the BTH QP field that QLogic_IB uses to differentiate + * an qlogic_ib protocol IB packet vs standard IB transport + * This it needs to be even (0x656b78), because the LSB is sometimes + * used for the MSB of context. The change may cause a problem + * interoperating with older software. + */ +#define QIB_KD_QP 0x656b78 + +/* + * These are the status bits readable (in ascii form, 64bit value) + * from the "status" sysfs file. For binary compatibility, values + * must remain as is; removed states can be reused for different + * purposes. + */ +#define QIB_STATUS_INITTED 0x1 /* basic initialization done */ +/* Chip has been found and initted */ +#define QIB_STATUS_CHIP_PRESENT 0x20 +/* IB link is at ACTIVE, usable for data traffic */ +#define QIB_STATUS_IB_READY 0x40 +/* link is configured, LID, MTU, etc. have been set */ +#define QIB_STATUS_IB_CONF 0x80 +/* A Fatal hardware error has occurred. */ +#define QIB_STATUS_HWERROR 0x200 + +/* + * The list of usermode accessible registers. Also see Reg_* later in file. + */ +enum qib_ureg { + /* (RO) DMA RcvHdr to be used next. */ + ur_rcvhdrtail = 0, + /* (RW) RcvHdr entry to be processed next by host. */ + ur_rcvhdrhead = 1, + /* (RO) Index of next Eager index to use. */ + ur_rcvegrindextail = 2, + /* (RW) Eager TID to be processed next */ + ur_rcvegrindexhead = 3, + /* For internal use only; max register number. */ + _QIB_UregMax +}; + +/* bit values for spi_runtime_flags */ +#define QIB_RUNTIME_PCIE 0x0002 +#define QIB_RUNTIME_FORCE_WC_ORDER 0x0004 +#define QIB_RUNTIME_RCVHDR_COPY 0x0008 +#define QIB_RUNTIME_MASTER 0x0010 +#define QIB_RUNTIME_RCHK 0x0020 +#define QIB_RUNTIME_NODMA_RTAIL 0x0080 +#define QIB_RUNTIME_SPECIAL_TRIGGER 0x0100 +#define QIB_RUNTIME_SDMA 0x0200 +#define QIB_RUNTIME_FORCE_PIOAVAIL 0x0400 +#define QIB_RUNTIME_PIO_REGSWAPPED 0x0800 +#define QIB_RUNTIME_CTXT_MSB_IN_QP 0x1000 +#define QIB_RUNTIME_CTXT_REDIRECT 0x2000 +#define QIB_RUNTIME_HDRSUPP 0x4000 + +/* + * This structure is returned by qib_userinit() immediately after + * open to get implementation-specific info, and info specific to this + * instance. + * + * This struct must have explict pad fields where type sizes + * may result in different alignments between 32 and 64 bit + * programs, since the 64 bit * bit kernel requires the user code + * to have matching offsets + */ +struct qib_base_info { + /* version of hardware, for feature checking. */ + __u32 spi_hw_version; + /* version of software, for feature checking. */ + __u32 spi_sw_version; + /* QLogic_IB context assigned, goes into sent packets */ + __u16 spi_ctxt; + __u16 spi_subctxt; + /* + * IB MTU, packets IB data must be less than this. + * The MTU is in bytes, and will be a multiple of 4 bytes. + */ + __u32 spi_mtu; + /* + * Size of a PIO buffer. Any given packet's total size must be less + * than this (in words). Included is the starting control word, so + * if 513 is returned, then total pkt size is 512 words or less. + */ + __u32 spi_piosize; + /* size of the TID cache in qlogic_ib, in entries */ + __u32 spi_tidcnt; + /* size of the TID Eager list in qlogic_ib, in entries */ + __u32 spi_tidegrcnt; + /* size of a single receive header queue entry in words. */ + __u32 spi_rcvhdrent_size; + /* + * Count of receive header queue entries allocated. + * This may be less than the spu_rcvhdrcnt passed in!. + */ + __u32 spi_rcvhdr_cnt; + + /* per-chip and other runtime features bitmap (QIB_RUNTIME_*) */ + __u32 spi_runtime_flags; + + /* address where hardware receive header queue is mapped */ + __u64 spi_rcvhdr_base; + + /* user program. */ + + /* base address of eager TID receive buffers used by hardware. */ + __u64 spi_rcv_egrbufs; + + /* Allocated by initialization code, not by protocol. */ + + /* + * Size of each TID buffer in host memory, starting at + * spi_rcv_egrbufs. The buffers are virtually contiguous. + */ + __u32 spi_rcv_egrbufsize; + /* + * The special QP (queue pair) value that identifies an qlogic_ib + * protocol packet from standard IB packets. More, probably much + * more, to be added. + */ + __u32 spi_qpair; + + /* + * User register base for init code, not to be used directly by + * protocol or applications. Always points to chip registers, + * for normal or shared context. + */ + __u64 spi_uregbase; + /* + * Maximum buffer size in bytes that can be used in a single TID + * entry (assuming the buffer is aligned to this boundary). This is + * the minimum of what the hardware and software support Guaranteed + * to be a power of 2. + */ + __u32 spi_tid_maxsize; + /* + * alignment of each pio send buffer (byte count + * to add to spi_piobufbase to get to second buffer) + */ + __u32 spi_pioalign; + /* + * The index of the first pio buffer available to this process; + * needed to do lookup in spi_pioavailaddr; not added to + * spi_piobufbase. + */ + __u32 spi_pioindex; + /* number of buffers mapped for this process */ + __u32 spi_piocnt; + + /* + * Base address of writeonly pio buffers for this process. + * Each buffer has spi_piosize words, and is aligned on spi_pioalign + * boundaries. spi_piocnt buffers are mapped from this address + */ + __u64 spi_piobufbase; + + /* + * Base address of readonly memory copy of the pioavail registers. + * There are 2 bits for each buffer. + */ + __u64 spi_pioavailaddr; + + /* + * Address where driver updates a copy of the interface and driver + * status (QIB_STATUS_*) as a 64 bit value. It's followed by a + * link status qword (formerly combined with driver status), then a + * string indicating hardware error, if there was one. + */ + __u64 spi_status; + + /* number of chip ctxts available to user processes */ + __u32 spi_nctxts; + __u16 spi_unit; /* unit number of chip we are using */ + __u16 spi_port; /* IB port number we are using */ + /* num bufs in each contiguous set */ + __u32 spi_rcv_egrperchunk; + /* size in bytes of each contiguous set */ + __u32 spi_rcv_egrchunksize; + /* total size of mmap to cover full rcvegrbuffers */ + __u32 spi_rcv_egrbuftotlen; + __u32 spi_rhf_offset; /* dword offset in hdrqent for rcvhdr flags */ + /* address of readonly memory copy of the rcvhdrq tail register. */ + __u64 spi_rcvhdr_tailaddr; + + /* + * shared memory pages for subctxts if ctxt is shared; these cover + * all the processes in the group sharing a single context. + * all have enough space for the num_subcontexts value on this job. + */ + __u64 spi_subctxt_uregbase; + __u64 spi_subctxt_rcvegrbuf; + __u64 spi_subctxt_rcvhdr_base; + + /* shared memory page for send buffer disarm status */ + __u64 spi_sendbuf_status; +} __attribute__ ((aligned(8))); + +/* + * This version number is given to the driver by the user code during + * initialization in the spu_userversion field of qib_user_info, so + * the driver can check for compatibility with user code. + * + * The major version changes when data structures + * change in an incompatible way. The driver must be the same or higher + * for initialization to succeed. In some cases, a higher version + * driver will not interoperate with older software, and initialization + * will return an error. + */ +#define QIB_USER_SWMAJOR 1 + +/* + * Minor version differences are always compatible + * a within a major version, however if user software is larger + * than driver software, some new features and/or structure fields + * may not be implemented; the user code must deal with this if it + * cares, or it must abort after initialization reports the difference. + */ +#define QIB_USER_SWMINOR 10 + +#define QIB_USER_SWVERSION ((QIB_USER_SWMAJOR << 16) | QIB_USER_SWMINOR) + +#ifndef QIB_KERN_TYPE +#define QIB_KERN_TYPE 0 +#define QIB_IDSTR "QLogic kernel.org driver" +#endif + +/* + * Similarly, this is the kernel version going back to the user. It's + * slightly different, in that we want to tell if the driver was built as + * part of a QLogic release, or from the driver from openfabrics.org, + * kernel.org, or a standard distribution, for support reasons. + * The high bit is 0 for non-QLogic and 1 for QLogic-built/supplied. + * + * It's returned by the driver to the user code during initialization in the + * spi_sw_version field of qib_base_info, so the user code can in turn + * check for compatibility with the kernel. +*/ +#define QIB_KERN_SWVERSION ((QIB_KERN_TYPE << 31) | QIB_USER_SWVERSION) + +/* + * This structure is passed to qib_userinit() to tell the driver where + * user code buffers are, sizes, etc. The offsets and sizes of the + * fields must remain unchanged, for binary compatibility. It can + * be extended, if userversion is changed so user code can tell, if needed + */ +struct qib_user_info { + /* + * version of user software, to detect compatibility issues. + * Should be set to QIB_USER_SWVERSION. + */ + __u32 spu_userversion; + + __u32 _spu_unused2; + + /* size of struct base_info to write to */ + __u32 spu_base_info_size; + + __u32 _spu_unused3; + + /* + * If two or more processes wish to share a context, each process + * must set the spu_subctxt_cnt and spu_subctxt_id to the same + * values. The only restriction on the spu_subctxt_id is that + * it be unique for a given node. + */ + __u16 spu_subctxt_cnt; + __u16 spu_subctxt_id; + + __u32 spu_port; /* IB port requested by user if > 0 */ + + /* + * address of struct base_info to write to + */ + __u64 spu_base_info; + +} __attribute__ ((aligned(8))); + +/* User commands. */ + +/* 16 available, was: old set up userspace (for old user code) */ +#define QIB_CMD_CTXT_INFO 17 /* find out what resources we got */ +#define QIB_CMD_RECV_CTRL 18 /* control receipt of packets */ +#define QIB_CMD_TID_UPDATE 19 /* update expected TID entries */ +#define QIB_CMD_TID_FREE 20 /* free expected TID entries */ +#define QIB_CMD_SET_PART_KEY 21 /* add partition key */ +/* 22 available, was: return info on slave processes (for old user code) */ +#define QIB_CMD_ASSIGN_CTXT 23 /* allocate HCA and ctxt */ +#define QIB_CMD_USER_INIT 24 /* set up userspace */ +#define QIB_CMD_UNUSED_1 25 +#define QIB_CMD_UNUSED_2 26 +#define QIB_CMD_PIOAVAILUPD 27 /* force an update of PIOAvail reg */ +#define QIB_CMD_POLL_TYPE 28 /* set the kind of polling we want */ +#define QIB_CMD_ARMLAUNCH_CTRL 29 /* armlaunch detection control */ +/* 30 is unused */ +#define QIB_CMD_SDMA_INFLIGHT 31 /* sdma inflight counter request */ +#define QIB_CMD_SDMA_COMPLETE 32 /* sdma completion counter request */ +/* 33 available, was a testing feature */ +#define QIB_CMD_DISARM_BUFS 34 /* disarm send buffers w/ errors */ +#define QIB_CMD_ACK_EVENT 35 /* ack & clear bits */ +#define QIB_CMD_CPUS_LIST 36 /* list of cpus allocated, for pinned + * processes: qib_cpus_list */ + +/* + * QIB_CMD_ACK_EVENT obsoletes QIB_CMD_DISARM_BUFS, but we keep it for + * compatibility with libraries from previous release. The ACK_EVENT + * will take appropriate driver action (if any, just DISARM for now), + * then clear the bits passed in as part of the mask. These bits are + * in the first 64bit word at spi_sendbuf_status, and are passed to + * the driver in the event_mask union as well. + */ +#define _QIB_EVENT_DISARM_BUFS_BIT 0 +#define _QIB_EVENT_LINKDOWN_BIT 1 +#define _QIB_EVENT_LID_CHANGE_BIT 2 +#define _QIB_EVENT_LMC_CHANGE_BIT 3 +#define _QIB_EVENT_SL2VL_CHANGE_BIT 4 +#define _QIB_MAX_EVENT_BIT _QIB_EVENT_SL2VL_CHANGE_BIT + +#define QIB_EVENT_DISARM_BUFS_BIT (1UL << _QIB_EVENT_DISARM_BUFS_BIT) +#define QIB_EVENT_LINKDOWN_BIT (1UL << _QIB_EVENT_LINKDOWN_BIT) +#define QIB_EVENT_LID_CHANGE_BIT (1UL << _QIB_EVENT_LID_CHANGE_BIT) +#define QIB_EVENT_LMC_CHANGE_BIT (1UL << _QIB_EVENT_LMC_CHANGE_BIT) +#define QIB_EVENT_SL2VL_CHANGE_BIT (1UL << _QIB_EVENT_SL2VL_CHANGE_BIT) + + +/* + * Poll types + */ +#define QIB_POLL_TYPE_ANYRCV 0x0 +#define QIB_POLL_TYPE_URGENT 0x1 + +struct qib_ctxt_info { + __u16 num_active; /* number of active units */ + __u16 unit; /* unit (chip) assigned to caller */ + __u16 port; /* IB port assigned to caller (1-based) */ + __u16 ctxt; /* ctxt on unit assigned to caller */ + __u16 subctxt; /* subctxt on unit assigned to caller */ + __u16 num_ctxts; /* number of ctxts available on unit */ + __u16 num_subctxts; /* number of subctxts opened on ctxt */ + __u16 rec_cpu; /* cpu # for affinity (ffff if none) */ +}; + +struct qib_tid_info { + __u32 tidcnt; + /* make structure same size in 32 and 64 bit */ + __u32 tid__unused; + /* virtual address of first page in transfer */ + __u64 tidvaddr; + /* pointer (same size 32/64 bit) to __u16 tid array */ + __u64 tidlist; + + /* + * pointer (same size 32/64 bit) to bitmap of TIDs used + * for this call; checked for being large enough at open + */ + __u64 tidmap; +}; + +struct qib_cmd { + __u32 type; /* command type */ + union { + struct qib_tid_info tid_info; + struct qib_user_info user_info; + + /* + * address in userspace where we should put the sdma + * inflight counter + */ + __u64 sdma_inflight; + /* + * address in userspace where we should put the sdma + * completion counter + */ + __u64 sdma_complete; + /* address in userspace of struct qib_ctxt_info to + write result to */ + __u64 ctxt_info; + /* enable/disable receipt of packets */ + __u32 recv_ctrl; + /* enable/disable armlaunch errors (non-zero to enable) */ + __u32 armlaunch_ctrl; + /* partition key to set */ + __u16 part_key; + /* user address of __u32 bitmask of active slaves */ + __u64 slave_mask_addr; + /* type of polling we want */ + __u16 poll_type; + /* back pressure enable bit for one particular context */ + __u8 ctxt_bp; + /* qib_user_event_ack(), IPATH_EVENT_* bits */ + __u64 event_mask; + } cmd; +}; + +struct qib_iovec { + /* Pointer to data, but same size 32 and 64 bit */ + __u64 iov_base; + + /* + * Length of data; don't need 64 bits, but want + * qib_sendpkt to remain same size as before 32 bit changes, so... + */ + __u64 iov_len; +}; + +/* + * Describes a single packet for send. Each packet can have one or more + * buffers, but the total length (exclusive of IB headers) must be less + * than the MTU, and if using the PIO method, entire packet length, + * including IB headers, must be less than the qib_piosize value (words). + * Use of this necessitates including sys/uio.h + */ +struct __qib_sendpkt { + __u32 sps_flags; /* flags for packet (TBD) */ + __u32 sps_cnt; /* number of entries to use in sps_iov */ + /* array of iov's describing packet. TEMPORARY */ + struct qib_iovec sps_iov[4]; +}; + +/* + * Diagnostics can send a packet by "writing" the following + * structs to the diag data special file. + * This allows a custom + * pbc (+ static rate) qword, so that special modes and deliberate + * changes to CRCs can be used. The elements were also re-ordered + * for better alignment and to avoid padding issues. + */ +#define _DIAG_XPKT_VERS 3 +struct qib_diag_xpkt { + __u16 version; + __u16 unit; + __u16 port; + __u16 len; + __u64 data; + __u64 pbc_wd; +}; + +/* + * Data layout in I2C flash (for GUID, etc.) + * All fields are little-endian binary unless otherwise stated + */ +#define QIB_FLASH_VERSION 2 +struct qib_flash { + /* flash layout version (QIB_FLASH_VERSION) */ + __u8 if_fversion; + /* checksum protecting if_length bytes */ + __u8 if_csum; + /* + * valid length (in use, protected by if_csum), including + * if_fversion and if_csum themselves) + */ + __u8 if_length; + /* the GUID, in network order */ + __u8 if_guid[8]; + /* number of GUIDs to use, starting from if_guid */ + __u8 if_numguid; + /* the (last 10 characters of) board serial number, in ASCII */ + char if_serial[12]; + /* board mfg date (YYYYMMDD ASCII) */ + char if_mfgdate[8]; + /* last board rework/test date (YYYYMMDD ASCII) */ + char if_testdate[8]; + /* logging of error counts, TBD */ + __u8 if_errcntp[4]; + /* powered on hours, updated at driver unload */ + __u8 if_powerhour[2]; + /* ASCII free-form comment field */ + char if_comment[32]; + /* Backwards compatible prefix for longer QLogic Serial Numbers */ + char if_sprefix[4]; + /* 82 bytes used, min flash size is 128 bytes */ + __u8 if_future[46]; +}; + +/* + * These are the counters implemented in the chip, and are listed in order. + * The InterCaps naming is taken straight from the chip spec. + */ +struct qlogic_ib_counters { + __u64 LBIntCnt; + __u64 LBFlowStallCnt; + __u64 TxSDmaDescCnt; /* was Reserved1 */ + __u64 TxUnsupVLErrCnt; + __u64 TxDataPktCnt; + __u64 TxFlowPktCnt; + __u64 TxDwordCnt; + __u64 TxLenErrCnt; + __u64 TxMaxMinLenErrCnt; + __u64 TxUnderrunCnt; + __u64 TxFlowStallCnt; + __u64 TxDroppedPktCnt; + __u64 RxDroppedPktCnt; + __u64 RxDataPktCnt; + __u64 RxFlowPktCnt; + __u64 RxDwordCnt; + __u64 RxLenErrCnt; + __u64 RxMaxMinLenErrCnt; + __u64 RxICRCErrCnt; + __u64 RxVCRCErrCnt; + __u64 RxFlowCtrlErrCnt; + __u64 RxBadFormatCnt; + __u64 RxLinkProblemCnt; + __u64 RxEBPCnt; + __u64 RxLPCRCErrCnt; + __u64 RxBufOvflCnt; + __u64 RxTIDFullErrCnt; + __u64 RxTIDValidErrCnt; + __u64 RxPKeyMismatchCnt; + __u64 RxP0HdrEgrOvflCnt; + __u64 RxP1HdrEgrOvflCnt; + __u64 RxP2HdrEgrOvflCnt; + __u64 RxP3HdrEgrOvflCnt; + __u64 RxP4HdrEgrOvflCnt; + __u64 RxP5HdrEgrOvflCnt; + __u64 RxP6HdrEgrOvflCnt; + __u64 RxP7HdrEgrOvflCnt; + __u64 RxP8HdrEgrOvflCnt; + __u64 RxP9HdrEgrOvflCnt; + __u64 RxP10HdrEgrOvflCnt; + __u64 RxP11HdrEgrOvflCnt; + __u64 RxP12HdrEgrOvflCnt; + __u64 RxP13HdrEgrOvflCnt; + __u64 RxP14HdrEgrOvflCnt; + __u64 RxP15HdrEgrOvflCnt; + __u64 RxP16HdrEgrOvflCnt; + __u64 IBStatusChangeCnt; + __u64 IBLinkErrRecoveryCnt; + __u64 IBLinkDownedCnt; + __u64 IBSymbolErrCnt; + __u64 RxVL15DroppedPktCnt; + __u64 RxOtherLocalPhyErrCnt; + __u64 PcieRetryBufDiagQwordCnt; + __u64 ExcessBufferOvflCnt; + __u64 LocalLinkIntegrityErrCnt; + __u64 RxVlErrCnt; + __u64 RxDlidFltrCnt; +}; + +/* + * The next set of defines are for packet headers, and chip register + * and memory bits that are visible to and/or used by user-mode software. + */ + +/* RcvHdrFlags bits */ +#define QLOGIC_IB_RHF_LENGTH_MASK 0x7FF +#define QLOGIC_IB_RHF_LENGTH_SHIFT 0 +#define QLOGIC_IB_RHF_RCVTYPE_MASK 0x7 +#define QLOGIC_IB_RHF_RCVTYPE_SHIFT 11 +#define QLOGIC_IB_RHF_EGRINDEX_MASK 0xFFF +#define QLOGIC_IB_RHF_EGRINDEX_SHIFT 16 +#define QLOGIC_IB_RHF_SEQ_MASK 0xF +#define QLOGIC_IB_RHF_SEQ_SHIFT 0 +#define QLOGIC_IB_RHF_HDRQ_OFFSET_MASK 0x7FF +#define QLOGIC_IB_RHF_HDRQ_OFFSET_SHIFT 4 +#define QLOGIC_IB_RHF_H_ICRCERR 0x80000000 +#define QLOGIC_IB_RHF_H_VCRCERR 0x40000000 +#define QLOGIC_IB_RHF_H_PARITYERR 0x20000000 +#define QLOGIC_IB_RHF_H_LENERR 0x10000000 +#define QLOGIC_IB_RHF_H_MTUERR 0x08000000 +#define QLOGIC_IB_RHF_H_IHDRERR 0x04000000 +#define QLOGIC_IB_RHF_H_TIDERR 0x02000000 +#define QLOGIC_IB_RHF_H_MKERR 0x01000000 +#define QLOGIC_IB_RHF_H_IBERR 0x00800000 +#define QLOGIC_IB_RHF_H_ERR_MASK 0xFF800000 +#define QLOGIC_IB_RHF_L_USE_EGR 0x80000000 +#define QLOGIC_IB_RHF_L_SWA 0x00008000 +#define QLOGIC_IB_RHF_L_SWB 0x00004000 + +/* qlogic_ib header fields */ +#define QLOGIC_IB_I_VERS_MASK 0xF +#define QLOGIC_IB_I_VERS_SHIFT 28 +#define QLOGIC_IB_I_CTXT_MASK 0xF +#define QLOGIC_IB_I_CTXT_SHIFT 24 +#define QLOGIC_IB_I_TID_MASK 0x7FF +#define QLOGIC_IB_I_TID_SHIFT 13 +#define QLOGIC_IB_I_OFFSET_MASK 0x1FFF +#define QLOGIC_IB_I_OFFSET_SHIFT 0 + +/* K_PktFlags bits */ +#define QLOGIC_IB_KPF_INTR 0x1 +#define QLOGIC_IB_KPF_SUBCTXT_MASK 0x3 +#define QLOGIC_IB_KPF_SUBCTXT_SHIFT 1 + +#define QLOGIC_IB_MAX_SUBCTXT 4 + +/* SendPIO per-buffer control */ +#define QLOGIC_IB_SP_TEST 0x40 +#define QLOGIC_IB_SP_TESTEBP 0x20 +#define QLOGIC_IB_SP_TRIGGER_SHIFT 15 + +/* SendPIOAvail bits */ +#define QLOGIC_IB_SENDPIOAVAIL_BUSY_SHIFT 1 +#define QLOGIC_IB_SENDPIOAVAIL_CHECK_SHIFT 0 + +/* qlogic_ib header format */ +struct qib_header { + /* + * Version - 4 bits, Context - 4 bits, TID - 10 bits and Offset - + * 14 bits before ECO change ~28 Dec 03. After that, Vers 4, + * Context 4, TID 11, offset 13. + */ + __le32 ver_ctxt_tid_offset; + __le16 chksum; + __le16 pkt_flags; +}; + +/* + * qlogic_ib user message header format. + * This structure contains the first 4 fields common to all protocols + * that employ qlogic_ib. + */ +struct qib_message_header { + __be16 lrh[4]; + __be32 bth[3]; + /* fields below this point are in host byte order */ + struct qib_header iph; + __u8 sub_opcode; +}; + +/* IB - LRH header consts */ +#define QIB_LRH_GRH 0x0003 /* 1. word of IB LRH - next header: GRH */ +#define QIB_LRH_BTH 0x0002 /* 1. word of IB LRH - next header: BTH */ + +/* misc. */ +#define SIZE_OF_CRC 1 + +#define QIB_DEFAULT_P_KEY 0xFFFF +#define QIB_PERMISSIVE_LID 0xFFFF +#define QIB_AETH_CREDIT_SHIFT 24 +#define QIB_AETH_CREDIT_MASK 0x1F +#define QIB_AETH_CREDIT_INVAL 0x1F +#define QIB_PSN_MASK 0xFFFFFF +#define QIB_MSN_MASK 0xFFFFFF +#define QIB_QPN_MASK 0xFFFFFF +#define QIB_MULTICAST_LID_BASE 0xC000 +#define QIB_EAGER_TID_ID QLOGIC_IB_I_TID_MASK +#define QIB_MULTICAST_QPN 0xFFFFFF + +/* Receive Header Queue: receive type (from qlogic_ib) */ +#define RCVHQ_RCV_TYPE_EXPECTED 0 +#define RCVHQ_RCV_TYPE_EAGER 1 +#define RCVHQ_RCV_TYPE_NON_KD 2 +#define RCVHQ_RCV_TYPE_ERROR 3 + +#define QIB_HEADER_QUEUE_WORDS 9 + +/* functions for extracting fields from rcvhdrq entries for the driver. + */ +static inline __u32 qib_hdrget_err_flags(const __le32 *rbuf) +{ + return __le32_to_cpu(rbuf[1]) & QLOGIC_IB_RHF_H_ERR_MASK; +} + +static inline __u32 qib_hdrget_rcv_type(const __le32 *rbuf) +{ + return (__le32_to_cpu(rbuf[0]) >> QLOGIC_IB_RHF_RCVTYPE_SHIFT) & + QLOGIC_IB_RHF_RCVTYPE_MASK; +} + +static inline __u32 qib_hdrget_length_in_bytes(const __le32 *rbuf) +{ + return ((__le32_to_cpu(rbuf[0]) >> QLOGIC_IB_RHF_LENGTH_SHIFT) & + QLOGIC_IB_RHF_LENGTH_MASK) << 2; +} + +static inline __u32 qib_hdrget_index(const __le32 *rbuf) +{ + return (__le32_to_cpu(rbuf[0]) >> QLOGIC_IB_RHF_EGRINDEX_SHIFT) & + QLOGIC_IB_RHF_EGRINDEX_MASK; +} + +static inline __u32 qib_hdrget_seq(const __le32 *rbuf) +{ + return (__le32_to_cpu(rbuf[1]) >> QLOGIC_IB_RHF_SEQ_SHIFT) & + QLOGIC_IB_RHF_SEQ_MASK; +} + +static inline __u32 qib_hdrget_offset(const __le32 *rbuf) +{ + return (__le32_to_cpu(rbuf[1]) >> QLOGIC_IB_RHF_HDRQ_OFFSET_SHIFT) & + QLOGIC_IB_RHF_HDRQ_OFFSET_MASK; +} + +static inline __u32 qib_hdrget_use_egr_buf(const __le32 *rbuf) +{ + return __le32_to_cpu(rbuf[0]) & QLOGIC_IB_RHF_L_USE_EGR; +} + +static inline __u32 qib_hdrget_qib_ver(__le32 hdrword) +{ + return (__le32_to_cpu(hdrword) >> QLOGIC_IB_I_VERS_SHIFT) & + QLOGIC_IB_I_VERS_MASK; +} + +#endif /* _QIB_COMMON_H */ diff --git a/drivers/infiniband/hw/qib/qib_cq.c b/drivers/infiniband/hw/qib/qib_cq.c new file mode 100644 index 000000000000..a86cbf880f98 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_cq.c @@ -0,0 +1,484 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2010 QLogic Corporation. All rights reserved. + * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include + +#include "qib_verbs.h" + +/** + * qib_cq_enter - add a new entry to the completion queue + * @cq: completion queue + * @entry: work completion entry to add + * @sig: true if @entry is a solicitated entry + * + * This may be called with qp->s_lock held. + */ +void qib_cq_enter(struct qib_cq *cq, struct ib_wc *entry, int solicited) +{ + struct qib_cq_wc *wc; + unsigned long flags; + u32 head; + u32 next; + + spin_lock_irqsave(&cq->lock, flags); + + /* + * Note that the head pointer might be writable by user processes. + * Take care to verify it is a sane value. + */ + wc = cq->queue; + head = wc->head; + if (head >= (unsigned) cq->ibcq.cqe) { + head = cq->ibcq.cqe; + next = 0; + } else + next = head + 1; + if (unlikely(next == wc->tail)) { + spin_unlock_irqrestore(&cq->lock, flags); + if (cq->ibcq.event_handler) { + struct ib_event ev; + + ev.device = cq->ibcq.device; + ev.element.cq = &cq->ibcq; + ev.event = IB_EVENT_CQ_ERR; + cq->ibcq.event_handler(&ev, cq->ibcq.cq_context); + } + return; + } + if (cq->ip) { + wc->uqueue[head].wr_id = entry->wr_id; + wc->uqueue[head].status = entry->status; + wc->uqueue[head].opcode = entry->opcode; + wc->uqueue[head].vendor_err = entry->vendor_err; + wc->uqueue[head].byte_len = entry->byte_len; + wc->uqueue[head].ex.imm_data = + (__u32 __force)entry->ex.imm_data; + wc->uqueue[head].qp_num = entry->qp->qp_num; + wc->uqueue[head].src_qp = entry->src_qp; + wc->uqueue[head].wc_flags = entry->wc_flags; + wc->uqueue[head].pkey_index = entry->pkey_index; + wc->uqueue[head].slid = entry->slid; + wc->uqueue[head].sl = entry->sl; + wc->uqueue[head].dlid_path_bits = entry->dlid_path_bits; + wc->uqueue[head].port_num = entry->port_num; + /* Make sure entry is written before the head index. */ + smp_wmb(); + } else + wc->kqueue[head] = *entry; + wc->head = next; + + if (cq->notify == IB_CQ_NEXT_COMP || + (cq->notify == IB_CQ_SOLICITED && solicited)) { + cq->notify = IB_CQ_NONE; + cq->triggered++; + /* + * This will cause send_complete() to be called in + * another thread. + */ + queue_work(qib_cq_wq, &cq->comptask); + } + + spin_unlock_irqrestore(&cq->lock, flags); +} + +/** + * qib_poll_cq - poll for work completion entries + * @ibcq: the completion queue to poll + * @num_entries: the maximum number of entries to return + * @entry: pointer to array where work completions are placed + * + * Returns the number of completion entries polled. + * + * This may be called from interrupt context. Also called by ib_poll_cq() + * in the generic verbs code. + */ +int qib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) +{ + struct qib_cq *cq = to_icq(ibcq); + struct qib_cq_wc *wc; + unsigned long flags; + int npolled; + u32 tail; + + /* The kernel can only poll a kernel completion queue */ + if (cq->ip) { + npolled = -EINVAL; + goto bail; + } + + spin_lock_irqsave(&cq->lock, flags); + + wc = cq->queue; + tail = wc->tail; + if (tail > (u32) cq->ibcq.cqe) + tail = (u32) cq->ibcq.cqe; + for (npolled = 0; npolled < num_entries; ++npolled, ++entry) { + if (tail == wc->head) + break; + /* The kernel doesn't need a RMB since it has the lock. */ + *entry = wc->kqueue[tail]; + if (tail >= cq->ibcq.cqe) + tail = 0; + else + tail++; + } + wc->tail = tail; + + spin_unlock_irqrestore(&cq->lock, flags); + +bail: + return npolled; +} + +static void send_complete(struct work_struct *work) +{ + struct qib_cq *cq = container_of(work, struct qib_cq, comptask); + + /* + * The completion handler will most likely rearm the notification + * and poll for all pending entries. If a new completion entry + * is added while we are in this routine, queue_work() + * won't call us again until we return so we check triggered to + * see if we need to call the handler again. + */ + for (;;) { + u8 triggered = cq->triggered; + + /* + * IPoIB connected mode assumes the callback is from a + * soft IRQ. We simulate this by blocking "bottom halves". + * See the implementation for ipoib_cm_handle_tx_wc(), + * netif_tx_lock_bh() and netif_tx_lock(). + */ + local_bh_disable(); + cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context); + local_bh_enable(); + + if (cq->triggered == triggered) + return; + } +} + +/** + * qib_create_cq - create a completion queue + * @ibdev: the device this completion queue is attached to + * @entries: the minimum size of the completion queue + * @context: unused by the QLogic_IB driver + * @udata: user data for libibverbs.so + * + * Returns a pointer to the completion queue or negative errno values + * for failure. + * + * Called by ib_create_cq() in the generic verbs code. + */ +struct ib_cq *qib_create_cq(struct ib_device *ibdev, int entries, + int comp_vector, struct ib_ucontext *context, + struct ib_udata *udata) +{ + struct qib_ibdev *dev = to_idev(ibdev); + struct qib_cq *cq; + struct qib_cq_wc *wc; + struct ib_cq *ret; + u32 sz; + + if (entries < 1 || entries > ib_qib_max_cqes) { + ret = ERR_PTR(-EINVAL); + goto done; + } + + /* Allocate the completion queue structure. */ + cq = kmalloc(sizeof(*cq), GFP_KERNEL); + if (!cq) { + ret = ERR_PTR(-ENOMEM); + goto done; + } + + /* + * Allocate the completion queue entries and head/tail pointers. + * This is allocated separately so that it can be resized and + * also mapped into user space. + * We need to use vmalloc() in order to support mmap and large + * numbers of entries. + */ + sz = sizeof(*wc); + if (udata && udata->outlen >= sizeof(__u64)) + sz += sizeof(struct ib_uverbs_wc) * (entries + 1); + else + sz += sizeof(struct ib_wc) * (entries + 1); + wc = vmalloc_user(sz); + if (!wc) { + ret = ERR_PTR(-ENOMEM); + goto bail_cq; + } + + /* + * Return the address of the WC as the offset to mmap. + * See qib_mmap() for details. + */ + if (udata && udata->outlen >= sizeof(__u64)) { + int err; + + cq->ip = qib_create_mmap_info(dev, sz, context, wc); + if (!cq->ip) { + ret = ERR_PTR(-ENOMEM); + goto bail_wc; + } + + err = ib_copy_to_udata(udata, &cq->ip->offset, + sizeof(cq->ip->offset)); + if (err) { + ret = ERR_PTR(err); + goto bail_ip; + } + } else + cq->ip = NULL; + + spin_lock(&dev->n_cqs_lock); + if (dev->n_cqs_allocated == ib_qib_max_cqs) { + spin_unlock(&dev->n_cqs_lock); + ret = ERR_PTR(-ENOMEM); + goto bail_ip; + } + + dev->n_cqs_allocated++; + spin_unlock(&dev->n_cqs_lock); + + if (cq->ip) { + spin_lock_irq(&dev->pending_lock); + list_add(&cq->ip->pending_mmaps, &dev->pending_mmaps); + spin_unlock_irq(&dev->pending_lock); + } + + /* + * ib_create_cq() will initialize cq->ibcq except for cq->ibcq.cqe. + * The number of entries should be >= the number requested or return + * an error. + */ + cq->ibcq.cqe = entries; + cq->notify = IB_CQ_NONE; + cq->triggered = 0; + spin_lock_init(&cq->lock); + INIT_WORK(&cq->comptask, send_complete); + wc->head = 0; + wc->tail = 0; + cq->queue = wc; + + ret = &cq->ibcq; + + goto done; + +bail_ip: + kfree(cq->ip); +bail_wc: + vfree(wc); +bail_cq: + kfree(cq); +done: + return ret; +} + +/** + * qib_destroy_cq - destroy a completion queue + * @ibcq: the completion queue to destroy. + * + * Returns 0 for success. + * + * Called by ib_destroy_cq() in the generic verbs code. + */ +int qib_destroy_cq(struct ib_cq *ibcq) +{ + struct qib_ibdev *dev = to_idev(ibcq->device); + struct qib_cq *cq = to_icq(ibcq); + + flush_work(&cq->comptask); + spin_lock(&dev->n_cqs_lock); + dev->n_cqs_allocated--; + spin_unlock(&dev->n_cqs_lock); + if (cq->ip) + kref_put(&cq->ip->ref, qib_release_mmap_info); + else + vfree(cq->queue); + kfree(cq); + + return 0; +} + +/** + * qib_req_notify_cq - change the notification type for a completion queue + * @ibcq: the completion queue + * @notify_flags: the type of notification to request + * + * Returns 0 for success. + * + * This may be called from interrupt context. Also called by + * ib_req_notify_cq() in the generic verbs code. + */ +int qib_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags notify_flags) +{ + struct qib_cq *cq = to_icq(ibcq); + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&cq->lock, flags); + /* + * Don't change IB_CQ_NEXT_COMP to IB_CQ_SOLICITED but allow + * any other transitions (see C11-31 and C11-32 in ch. 11.4.2.2). + */ + if (cq->notify != IB_CQ_NEXT_COMP) + cq->notify = notify_flags & IB_CQ_SOLICITED_MASK; + + if ((notify_flags & IB_CQ_REPORT_MISSED_EVENTS) && + cq->queue->head != cq->queue->tail) + ret = 1; + + spin_unlock_irqrestore(&cq->lock, flags); + + return ret; +} + +/** + * qib_resize_cq - change the size of the CQ + * @ibcq: the completion queue + * + * Returns 0 for success. + */ +int qib_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata) +{ + struct qib_cq *cq = to_icq(ibcq); + struct qib_cq_wc *old_wc; + struct qib_cq_wc *wc; + u32 head, tail, n; + int ret; + u32 sz; + + if (cqe < 1 || cqe > ib_qib_max_cqes) { + ret = -EINVAL; + goto bail; + } + + /* + * Need to use vmalloc() if we want to support large #s of entries. + */ + sz = sizeof(*wc); + if (udata && udata->outlen >= sizeof(__u64)) + sz += sizeof(struct ib_uverbs_wc) * (cqe + 1); + else + sz += sizeof(struct ib_wc) * (cqe + 1); + wc = vmalloc_user(sz); + if (!wc) { + ret = -ENOMEM; + goto bail; + } + + /* Check that we can write the offset to mmap. */ + if (udata && udata->outlen >= sizeof(__u64)) { + __u64 offset = 0; + + ret = ib_copy_to_udata(udata, &offset, sizeof(offset)); + if (ret) + goto bail_free; + } + + spin_lock_irq(&cq->lock); + /* + * Make sure head and tail are sane since they + * might be user writable. + */ + old_wc = cq->queue; + head = old_wc->head; + if (head > (u32) cq->ibcq.cqe) + head = (u32) cq->ibcq.cqe; + tail = old_wc->tail; + if (tail > (u32) cq->ibcq.cqe) + tail = (u32) cq->ibcq.cqe; + if (head < tail) + n = cq->ibcq.cqe + 1 + head - tail; + else + n = head - tail; + if (unlikely((u32)cqe < n)) { + ret = -EINVAL; + goto bail_unlock; + } + for (n = 0; tail != head; n++) { + if (cq->ip) + wc->uqueue[n] = old_wc->uqueue[tail]; + else + wc->kqueue[n] = old_wc->kqueue[tail]; + if (tail == (u32) cq->ibcq.cqe) + tail = 0; + else + tail++; + } + cq->ibcq.cqe = cqe; + wc->head = n; + wc->tail = 0; + cq->queue = wc; + spin_unlock_irq(&cq->lock); + + vfree(old_wc); + + if (cq->ip) { + struct qib_ibdev *dev = to_idev(ibcq->device); + struct qib_mmap_info *ip = cq->ip; + + qib_update_mmap_info(dev, ip, sz, wc); + + /* + * Return the offset to mmap. + * See qib_mmap() for details. + */ + if (udata && udata->outlen >= sizeof(__u64)) { + ret = ib_copy_to_udata(udata, &ip->offset, + sizeof(ip->offset)); + if (ret) + goto bail; + } + + spin_lock_irq(&dev->pending_lock); + if (list_empty(&ip->pending_mmaps)) + list_add(&ip->pending_mmaps, &dev->pending_mmaps); + spin_unlock_irq(&dev->pending_lock); + } + + ret = 0; + goto bail; + +bail_unlock: + spin_unlock_irq(&cq->lock); +bail_free: + vfree(wc); +bail: + return ret; +} diff --git a/drivers/infiniband/hw/qib/qib_diag.c b/drivers/infiniband/hw/qib/qib_diag.c new file mode 100644 index 000000000000..ca98dd523752 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_diag.c @@ -0,0 +1,894 @@ +/* + * Copyright (c) 2010 QLogic Corporation. All rights reserved. + * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. + * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * This file contains support for diagnostic functions. It is accessed by + * opening the qib_diag device, normally minor number 129. Diagnostic use + * of the QLogic_IB chip may render the chip or board unusable until the + * driver is unloaded, or in some cases, until the system is rebooted. + * + * Accesses to the chip through this interface are not similar to going + * through the /sys/bus/pci resource mmap interface. + */ + +#include +#include +#include +#include +#include +#include + +#include "qib.h" +#include "qib_common.h" + +/* + * Each client that opens the diag device must read then write + * offset 0, to prevent lossage from random cat or od. diag_state + * sequences this "handshake". + */ +enum diag_state { UNUSED = 0, OPENED, INIT, READY }; + +/* State for an individual client. PID so children cannot abuse handshake */ +static struct qib_diag_client { + struct qib_diag_client *next; + struct qib_devdata *dd; + pid_t pid; + enum diag_state state; +} *client_pool; + +/* + * Get a client struct. Recycled if possible, else kmalloc. + * Must be called with qib_mutex held + */ +static struct qib_diag_client *get_client(struct qib_devdata *dd) +{ + struct qib_diag_client *dc; + + dc = client_pool; + if (dc) + /* got from pool remove it and use */ + client_pool = dc->next; + else + /* None in pool, alloc and init */ + dc = kmalloc(sizeof *dc, GFP_KERNEL); + + if (dc) { + dc->next = NULL; + dc->dd = dd; + dc->pid = current->pid; + dc->state = OPENED; + } + return dc; +} + +/* + * Return to pool. Must be called with qib_mutex held + */ +static void return_client(struct qib_diag_client *dc) +{ + struct qib_devdata *dd = dc->dd; + struct qib_diag_client *tdc, *rdc; + + rdc = NULL; + if (dc == dd->diag_client) { + dd->diag_client = dc->next; + rdc = dc; + } else { + tdc = dc->dd->diag_client; + while (tdc) { + if (dc == tdc->next) { + tdc->next = dc->next; + rdc = dc; + break; + } + tdc = tdc->next; + } + } + if (rdc) { + rdc->state = UNUSED; + rdc->dd = NULL; + rdc->pid = 0; + rdc->next = client_pool; + client_pool = rdc; + } +} + +static int qib_diag_open(struct inode *in, struct file *fp); +static int qib_diag_release(struct inode *in, struct file *fp); +static ssize_t qib_diag_read(struct file *fp, char __user *data, + size_t count, loff_t *off); +static ssize_t qib_diag_write(struct file *fp, const char __user *data, + size_t count, loff_t *off); + +static const struct file_operations diag_file_ops = { + .owner = THIS_MODULE, + .write = qib_diag_write, + .read = qib_diag_read, + .open = qib_diag_open, + .release = qib_diag_release +}; + +static atomic_t diagpkt_count = ATOMIC_INIT(0); +static struct cdev *diagpkt_cdev; +static struct device *diagpkt_device; + +static ssize_t qib_diagpkt_write(struct file *fp, const char __user *data, + size_t count, loff_t *off); + +static const struct file_operations diagpkt_file_ops = { + .owner = THIS_MODULE, + .write = qib_diagpkt_write, +}; + +int qib_diag_add(struct qib_devdata *dd) +{ + char name[16]; + int ret = 0; + + if (atomic_inc_return(&diagpkt_count) == 1) { + ret = qib_cdev_init(QIB_DIAGPKT_MINOR, "ipath_diagpkt", + &diagpkt_file_ops, &diagpkt_cdev, + &diagpkt_device); + if (ret) + goto done; + } + + snprintf(name, sizeof(name), "ipath_diag%d", dd->unit); + ret = qib_cdev_init(QIB_DIAG_MINOR_BASE + dd->unit, name, + &diag_file_ops, &dd->diag_cdev, + &dd->diag_device); +done: + return ret; +} + +static void qib_unregister_observers(struct qib_devdata *dd); + +void qib_diag_remove(struct qib_devdata *dd) +{ + struct qib_diag_client *dc; + + if (atomic_dec_and_test(&diagpkt_count)) + qib_cdev_cleanup(&diagpkt_cdev, &diagpkt_device); + + qib_cdev_cleanup(&dd->diag_cdev, &dd->diag_device); + + /* + * Return all diag_clients of this device. There should be none, + * as we are "guaranteed" that no clients are still open + */ + while (dd->diag_client) + return_client(dd->diag_client); + + /* Now clean up all unused client structs */ + while (client_pool) { + dc = client_pool; + client_pool = dc->next; + kfree(dc); + } + /* Clean up observer list */ + qib_unregister_observers(dd); +} + +/* qib_remap_ioaddr32 - remap an offset into chip address space to __iomem * + * + * @dd: the qlogic_ib device + * @offs: the offset in chip-space + * @cntp: Pointer to max (byte) count for transfer starting at offset + * This returns a u32 __iomem * so it can be used for both 64 and 32-bit + * mapping. It is needed because with the use of PAT for control of + * write-combining, the logically contiguous address-space of the chip + * may be split into virtually non-contiguous spaces, with different + * attributes, which are them mapped to contiguous physical space + * based from the first BAR. + * + * The code below makes the same assumptions as were made in + * init_chip_wc_pat() (qib_init.c), copied here: + * Assumes chip address space looks like: + * - kregs + sregs + cregs + uregs (in any order) + * - piobufs (2K and 4K bufs in either order) + * or: + * - kregs + sregs + cregs (in any order) + * - piobufs (2K and 4K bufs in either order) + * - uregs + * + * If cntp is non-NULL, returns how many bytes from offset can be accessed + * Returns 0 if the offset is not mapped. + */ +static u32 __iomem *qib_remap_ioaddr32(struct qib_devdata *dd, u32 offset, + u32 *cntp) +{ + u32 kreglen; + u32 snd_bottom, snd_lim = 0; + u32 __iomem *krb32 = (u32 __iomem *)dd->kregbase; + u32 __iomem *map = NULL; + u32 cnt = 0; + + /* First, simplest case, offset is within the first map. */ + kreglen = (dd->kregend - dd->kregbase) * sizeof(u64); + if (offset < kreglen) { + map = krb32 + (offset / sizeof(u32)); + cnt = kreglen - offset; + goto mapped; + } + + /* + * Next check for user regs, the next most common case, + * and a cheap check because if they are not in the first map + * they are last in chip. + */ + if (dd->userbase) { + /* If user regs mapped, they are after send, so set limit. */ + u32 ulim = (dd->cfgctxts * dd->ureg_align) + dd->uregbase; + snd_lim = dd->uregbase; + krb32 = (u32 __iomem *)dd->userbase; + if (offset >= dd->uregbase && offset < ulim) { + map = krb32 + (offset - dd->uregbase) / sizeof(u32); + cnt = ulim - offset; + goto mapped; + } + } + + /* + * Lastly, check for offset within Send Buffers. + * This is gnarly because struct devdata is deliberately vague + * about things like 7322 VL15 buffers, and we are not in + * chip-specific code here, so should not make many assumptions. + * The one we _do_ make is that the only chip that has more sndbufs + * than we admit is the 7322, and it has userregs above that, so + * we know the snd_lim. + */ + /* Assume 2K buffers are first. */ + snd_bottom = dd->pio2k_bufbase; + if (snd_lim == 0) { + u32 tot2k = dd->piobcnt2k * ALIGN(dd->piosize2k, dd->palign); + snd_lim = snd_bottom + tot2k; + } + /* If 4k buffers exist, account for them by bumping + * appropriate limit. + */ + if (dd->piobcnt4k) { + u32 tot4k = dd->piobcnt4k * dd->align4k; + u32 offs4k = dd->piobufbase >> 32; + if (snd_bottom > offs4k) + snd_bottom = offs4k; + else { + /* 4k above 2k. Bump snd_lim, if needed*/ + if (!dd->userbase) + snd_lim = offs4k + tot4k; + } + } + /* + * Judgement call: can we ignore the space between SendBuffs and + * UserRegs, where we would like to see vl15 buffs, but not more? + */ + if (offset >= snd_bottom && offset < snd_lim) { + offset -= snd_bottom; + map = (u32 __iomem *)dd->piobase + (offset / sizeof(u32)); + cnt = snd_lim - offset; + } + +mapped: + if (cntp) + *cntp = cnt; + return map; +} + +/* + * qib_read_umem64 - read a 64-bit quantity from the chip into user space + * @dd: the qlogic_ib device + * @uaddr: the location to store the data in user memory + * @regoffs: the offset from BAR0 (_NOT_ full pointer, anymore) + * @count: number of bytes to copy (multiple of 32 bits) + * + * This function also localizes all chip memory accesses. + * The copy should be written such that we read full cacheline packets + * from the chip. This is usually used for a single qword + * + * NOTE: This assumes the chip address is 64-bit aligned. + */ +static int qib_read_umem64(struct qib_devdata *dd, void __user *uaddr, + u32 regoffs, size_t count) +{ + const u64 __iomem *reg_addr; + const u64 __iomem *reg_end; + u32 limit; + int ret; + + reg_addr = (const u64 __iomem *)qib_remap_ioaddr32(dd, regoffs, &limit); + if (reg_addr == NULL || limit == 0 || !(dd->flags & QIB_PRESENT)) { + ret = -EINVAL; + goto bail; + } + if (count >= limit) + count = limit; + reg_end = reg_addr + (count / sizeof(u64)); + + /* not very efficient, but it works for now */ + while (reg_addr < reg_end) { + u64 data = readq(reg_addr); + + if (copy_to_user(uaddr, &data, sizeof(u64))) { + ret = -EFAULT; + goto bail; + } + reg_addr++; + uaddr += sizeof(u64); + } + ret = 0; +bail: + return ret; +} + +/* + * qib_write_umem64 - write a 64-bit quantity to the chip from user space + * @dd: the qlogic_ib device + * @regoffs: the offset from BAR0 (_NOT_ full pointer, anymore) + * @uaddr: the source of the data in user memory + * @count: the number of bytes to copy (multiple of 32 bits) + * + * This is usually used for a single qword + * NOTE: This assumes the chip address is 64-bit aligned. + */ + +static int qib_write_umem64(struct qib_devdata *dd, u32 regoffs, + const void __user *uaddr, size_t count) +{ + u64 __iomem *reg_addr; + const u64 __iomem *reg_end; + u32 limit; + int ret; + + reg_addr = (u64 __iomem *)qib_remap_ioaddr32(dd, regoffs, &limit); + if (reg_addr == NULL || limit == 0 || !(dd->flags & QIB_PRESENT)) { + ret = -EINVAL; + goto bail; + } + if (count >= limit) + count = limit; + reg_end = reg_addr + (count / sizeof(u64)); + + /* not very efficient, but it works for now */ + while (reg_addr < reg_end) { + u64 data; + if (copy_from_user(&data, uaddr, sizeof(data))) { + ret = -EFAULT; + goto bail; + } + writeq(data, reg_addr); + + reg_addr++; + uaddr += sizeof(u64); + } + ret = 0; +bail: + return ret; +} + +/* + * qib_read_umem32 - read a 32-bit quantity from the chip into user space + * @dd: the qlogic_ib device + * @uaddr: the location to store the data in user memory + * @regoffs: the offset from BAR0 (_NOT_ full pointer, anymore) + * @count: number of bytes to copy + * + * read 32 bit values, not 64 bit; for memories that only + * support 32 bit reads; usually a single dword. + */ +static int qib_read_umem32(struct qib_devdata *dd, void __user *uaddr, + u32 regoffs, size_t count) +{ + const u32 __iomem *reg_addr; + const u32 __iomem *reg_end; + u32 limit; + int ret; + + reg_addr = qib_remap_ioaddr32(dd, regoffs, &limit); + if (reg_addr == NULL || limit == 0 || !(dd->flags & QIB_PRESENT)) { + ret = -EINVAL; + goto bail; + } + if (count >= limit) + count = limit; + reg_end = reg_addr + (count / sizeof(u32)); + + /* not very efficient, but it works for now */ + while (reg_addr < reg_end) { + u32 data = readl(reg_addr); + + if (copy_to_user(uaddr, &data, sizeof(data))) { + ret = -EFAULT; + goto bail; + } + + reg_addr++; + uaddr += sizeof(u32); + + } + ret = 0; +bail: + return ret; +} + +/* + * qib_write_umem32 - write a 32-bit quantity to the chip from user space + * @dd: the qlogic_ib device + * @regoffs: the offset from BAR0 (_NOT_ full pointer, anymore) + * @uaddr: the source of the data in user memory + * @count: number of bytes to copy + * + * write 32 bit values, not 64 bit; for memories that only + * support 32 bit write; usually a single dword. + */ + +static int qib_write_umem32(struct qib_devdata *dd, u32 regoffs, + const void __user *uaddr, size_t count) +{ + u32 __iomem *reg_addr; + const u32 __iomem *reg_end; + u32 limit; + int ret; + + reg_addr = qib_remap_ioaddr32(dd, regoffs, &limit); + if (reg_addr == NULL || limit == 0 || !(dd->flags & QIB_PRESENT)) { + ret = -EINVAL; + goto bail; + } + if (count >= limit) + count = limit; + reg_end = reg_addr + (count / sizeof(u32)); + + while (reg_addr < reg_end) { + u32 data; + + if (copy_from_user(&data, uaddr, sizeof(data))) { + ret = -EFAULT; + goto bail; + } + writel(data, reg_addr); + + reg_addr++; + uaddr += sizeof(u32); + } + ret = 0; +bail: + return ret; +} + +static int qib_diag_open(struct inode *in, struct file *fp) +{ + int unit = iminor(in) - QIB_DIAG_MINOR_BASE; + struct qib_devdata *dd; + struct qib_diag_client *dc; + int ret; + + mutex_lock(&qib_mutex); + + dd = qib_lookup(unit); + + if (dd == NULL || !(dd->flags & QIB_PRESENT) || + !dd->kregbase) { + ret = -ENODEV; + goto bail; + } + + dc = get_client(dd); + if (!dc) { + ret = -ENOMEM; + goto bail; + } + dc->next = dd->diag_client; + dd->diag_client = dc; + fp->private_data = dc; + ret = 0; +bail: + mutex_unlock(&qib_mutex); + + return ret; +} + +/** + * qib_diagpkt_write - write an IB packet + * @fp: the diag data device file pointer + * @data: qib_diag_pkt structure saying where to get the packet + * @count: size of data to write + * @off: unused by this code + */ +static ssize_t qib_diagpkt_write(struct file *fp, + const char __user *data, + size_t count, loff_t *off) +{ + u32 __iomem *piobuf; + u32 plen, clen, pbufn; + struct qib_diag_xpkt dp; + u32 *tmpbuf = NULL; + struct qib_devdata *dd; + struct qib_pportdata *ppd; + ssize_t ret = 0; + + if (count != sizeof(dp)) { + ret = -EINVAL; + goto bail; + } + if (copy_from_user(&dp, data, sizeof(dp))) { + ret = -EFAULT; + goto bail; + } + + dd = qib_lookup(dp.unit); + if (!dd || !(dd->flags & QIB_PRESENT) || !dd->kregbase) { + ret = -ENODEV; + goto bail; + } + if (!(dd->flags & QIB_INITTED)) { + /* no hardware, freeze, etc. */ + ret = -ENODEV; + goto bail; + } + + if (dp.version != _DIAG_XPKT_VERS) { + qib_dev_err(dd, "Invalid version %u for diagpkt_write\n", + dp.version); + ret = -EINVAL; + goto bail; + } + /* send count must be an exact number of dwords */ + if (dp.len & 3) { + ret = -EINVAL; + goto bail; + } + if (!dp.port || dp.port > dd->num_pports) { + ret = -EINVAL; + goto bail; + } + ppd = &dd->pport[dp.port - 1]; + + /* need total length before first word written */ + /* +1 word is for the qword padding */ + plen = sizeof(u32) + dp.len; + clen = dp.len >> 2; + + if ((plen + 4) > ppd->ibmaxlen) { + ret = -EINVAL; + goto bail; /* before writing pbc */ + } + tmpbuf = vmalloc(plen); + if (!tmpbuf) { + qib_devinfo(dd->pcidev, "Unable to allocate tmp buffer, " + "failing\n"); + ret = -ENOMEM; + goto bail; + } + + if (copy_from_user(tmpbuf, + (const void __user *) (unsigned long) dp.data, + dp.len)) { + ret = -EFAULT; + goto bail; + } + + plen >>= 2; /* in dwords */ + + if (dp.pbc_wd == 0) + dp.pbc_wd = plen; + + piobuf = dd->f_getsendbuf(ppd, dp.pbc_wd, &pbufn); + if (!piobuf) { + ret = -EBUSY; + goto bail; + } + /* disarm it just to be extra sure */ + dd->f_sendctrl(dd->pport, QIB_SENDCTRL_DISARM_BUF(pbufn)); + + /* disable header check on pbufn for this packet */ + dd->f_txchk_change(dd, pbufn, 1, TXCHK_CHG_TYPE_DIS1, NULL); + + writeq(dp.pbc_wd, piobuf); + /* + * Copy all but the trigger word, then flush, so it's written + * to chip before trigger word, then write trigger word, then + * flush again, so packet is sent. + */ + if (dd->flags & QIB_PIO_FLUSH_WC) { + qib_flush_wc(); + qib_pio_copy(piobuf + 2, tmpbuf, clen - 1); + qib_flush_wc(); + __raw_writel(tmpbuf[clen - 1], piobuf + clen + 1); + } else + qib_pio_copy(piobuf + 2, tmpbuf, clen); + + if (dd->flags & QIB_USE_SPCL_TRIG) { + u32 spcl_off = (pbufn >= dd->piobcnt2k) ? 2047 : 1023; + + qib_flush_wc(); + __raw_writel(0xaebecede, piobuf + spcl_off); + } + + /* + * Ensure buffer is written to the chip, then re-enable + * header checks (if supported by chip). The txchk + * code will ensure seen by chip before returning. + */ + qib_flush_wc(); + qib_sendbuf_done(dd, pbufn); + dd->f_txchk_change(dd, pbufn, 1, TXCHK_CHG_TYPE_ENAB1, NULL); + + ret = sizeof(dp); + +bail: + vfree(tmpbuf); + return ret; +} + +static int qib_diag_release(struct inode *in, struct file *fp) +{ + mutex_lock(&qib_mutex); + return_client(fp->private_data); + fp->private_data = NULL; + mutex_unlock(&qib_mutex); + return 0; +} + +/* + * Chip-specific code calls to register its interest in + * a specific range. + */ +struct diag_observer_list_elt { + struct diag_observer_list_elt *next; + const struct diag_observer *op; +}; + +int qib_register_observer(struct qib_devdata *dd, + const struct diag_observer *op) +{ + struct diag_observer_list_elt *olp; + int ret = -EINVAL; + + if (!dd || !op) + goto bail; + ret = -ENOMEM; + olp = vmalloc(sizeof *olp); + if (!olp) { + printk(KERN_ERR QIB_DRV_NAME ": vmalloc for observer failed\n"); + goto bail; + } + if (olp) { + unsigned long flags; + + spin_lock_irqsave(&dd->qib_diag_trans_lock, flags); + olp->op = op; + olp->next = dd->diag_observer_list; + dd->diag_observer_list = olp; + spin_unlock_irqrestore(&dd->qib_diag_trans_lock, flags); + ret = 0; + } +bail: + return ret; +} + +/* Remove all registered observers when device is closed */ +static void qib_unregister_observers(struct qib_devdata *dd) +{ + struct diag_observer_list_elt *olp; + unsigned long flags; + + spin_lock_irqsave(&dd->qib_diag_trans_lock, flags); + olp = dd->diag_observer_list; + while (olp) { + /* Pop one observer, let go of lock */ + dd->diag_observer_list = olp->next; + spin_unlock_irqrestore(&dd->qib_diag_trans_lock, flags); + vfree(olp); + /* try again. */ + spin_lock_irqsave(&dd->qib_diag_trans_lock, flags); + olp = dd->diag_observer_list; + } + spin_unlock_irqrestore(&dd->qib_diag_trans_lock, flags); +} + +/* + * Find the observer, if any, for the specified address. Initial implementation + * is simple stack of observers. This must be called with diag transaction + * lock held. + */ +static const struct diag_observer *diag_get_observer(struct qib_devdata *dd, + u32 addr) +{ + struct diag_observer_list_elt *olp; + const struct diag_observer *op = NULL; + + olp = dd->diag_observer_list; + while (olp) { + op = olp->op; + if (addr >= op->bottom && addr <= op->top) + break; + olp = olp->next; + } + if (!olp) + op = NULL; + + return op; +} + +static ssize_t qib_diag_read(struct file *fp, char __user *data, + size_t count, loff_t *off) +{ + struct qib_diag_client *dc = fp->private_data; + struct qib_devdata *dd = dc->dd; + void __iomem *kreg_base; + ssize_t ret; + + if (dc->pid != current->pid) { + ret = -EPERM; + goto bail; + } + + kreg_base = dd->kregbase; + + if (count == 0) + ret = 0; + else if ((count % 4) || (*off % 4)) + /* address or length is not 32-bit aligned, hence invalid */ + ret = -EINVAL; + else if (dc->state < READY && (*off || count != 8)) + ret = -EINVAL; /* prevent cat /dev/qib_diag* */ + else { + unsigned long flags; + u64 data64 = 0; + int use_32; + const struct diag_observer *op; + + use_32 = (count % 8) || (*off % 8); + ret = -1; + spin_lock_irqsave(&dd->qib_diag_trans_lock, flags); + /* + * Check for observer on this address range. + * we only support a single 32 or 64-bit read + * via observer, currently. + */ + op = diag_get_observer(dd, *off); + if (op) { + u32 offset = *off; + ret = op->hook(dd, op, offset, &data64, 0, use_32); + } + /* + * We need to release lock before any copy_to_user(), + * whether implicit in qib_read_umem* or explicit below. + */ + spin_unlock_irqrestore(&dd->qib_diag_trans_lock, flags); + if (!op) { + if (use_32) + /* + * Address or length is not 64-bit aligned; + * do 32-bit rd + */ + ret = qib_read_umem32(dd, data, (u32) *off, + count); + else + ret = qib_read_umem64(dd, data, (u32) *off, + count); + } else if (ret == count) { + /* Below finishes case where observer existed */ + ret = copy_to_user(data, &data64, use_32 ? + sizeof(u32) : sizeof(u64)); + if (ret) + ret = -EFAULT; + } + } + + if (ret >= 0) { + *off += count; + ret = count; + if (dc->state == OPENED) + dc->state = INIT; + } +bail: + return ret; +} + +static ssize_t qib_diag_write(struct file *fp, const char __user *data, + size_t count, loff_t *off) +{ + struct qib_diag_client *dc = fp->private_data; + struct qib_devdata *dd = dc->dd; + void __iomem *kreg_base; + ssize_t ret; + + if (dc->pid != current->pid) { + ret = -EPERM; + goto bail; + } + + kreg_base = dd->kregbase; + + if (count == 0) + ret = 0; + else if ((count % 4) || (*off % 4)) + /* address or length is not 32-bit aligned, hence invalid */ + ret = -EINVAL; + else if (dc->state < READY && + ((*off || count != 8) || dc->state != INIT)) + /* No writes except second-step of init seq */ + ret = -EINVAL; /* before any other write allowed */ + else { + unsigned long flags; + const struct diag_observer *op = NULL; + int use_32 = (count % 8) || (*off % 8); + + /* + * Check for observer on this address range. + * We only support a single 32 or 64-bit write + * via observer, currently. This helps, because + * we would otherwise have to jump through hoops + * to make "diag transaction" meaningful when we + * cannot do a copy_from_user while holding the lock. + */ + if (count == 4 || count == 8) { + u64 data64; + u32 offset = *off; + ret = copy_from_user(&data64, data, count); + if (ret) { + ret = -EFAULT; + goto bail; + } + spin_lock_irqsave(&dd->qib_diag_trans_lock, flags); + op = diag_get_observer(dd, *off); + if (op) + ret = op->hook(dd, op, offset, &data64, ~0Ull, + use_32); + spin_unlock_irqrestore(&dd->qib_diag_trans_lock, flags); + } + + if (!op) { + if (use_32) + /* + * Address or length is not 64-bit aligned; + * do 32-bit write + */ + ret = qib_write_umem32(dd, (u32) *off, data, + count); + else + ret = qib_write_umem64(dd, (u32) *off, data, + count); + } + } + + if (ret >= 0) { + *off += count; + ret = count; + if (dc->state == INIT) + dc->state = READY; /* all read/write OK now */ + } +bail: + return ret; +} diff --git a/drivers/infiniband/hw/qib/qib_dma.c b/drivers/infiniband/hw/qib/qib_dma.c new file mode 100644 index 000000000000..2920bb39a65b --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_dma.c @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2006, 2009, 2010 QLogic, Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include +#include + +#include "qib_verbs.h" + +#define BAD_DMA_ADDRESS ((u64) 0) + +/* + * The following functions implement driver specific replacements + * for the ib_dma_*() functions. + * + * These functions return kernel virtual addresses instead of + * device bus addresses since the driver uses the CPU to copy + * data instead of using hardware DMA. + */ + +static int qib_mapping_error(struct ib_device *dev, u64 dma_addr) +{ + return dma_addr == BAD_DMA_ADDRESS; +} + +static u64 qib_dma_map_single(struct ib_device *dev, void *cpu_addr, + size_t size, enum dma_data_direction direction) +{ + BUG_ON(!valid_dma_direction(direction)); + return (u64) cpu_addr; +} + +static void qib_dma_unmap_single(struct ib_device *dev, u64 addr, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(!valid_dma_direction(direction)); +} + +static u64 qib_dma_map_page(struct ib_device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ + u64 addr; + + BUG_ON(!valid_dma_direction(direction)); + + if (offset + size > PAGE_SIZE) { + addr = BAD_DMA_ADDRESS; + goto done; + } + + addr = (u64) page_address(page); + if (addr) + addr += offset; + /* TODO: handle highmem pages */ + +done: + return addr; +} + +static void qib_dma_unmap_page(struct ib_device *dev, u64 addr, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(!valid_dma_direction(direction)); +} + +static int qib_map_sg(struct ib_device *dev, struct scatterlist *sgl, + int nents, enum dma_data_direction direction) +{ + struct scatterlist *sg; + u64 addr; + int i; + int ret = nents; + + BUG_ON(!valid_dma_direction(direction)); + + for_each_sg(sgl, sg, nents, i) { + addr = (u64) page_address(sg_page(sg)); + /* TODO: handle highmem pages */ + if (!addr) { + ret = 0; + break; + } + } + return ret; +} + +static void qib_unmap_sg(struct ib_device *dev, + struct scatterlist *sg, int nents, + enum dma_data_direction direction) +{ + BUG_ON(!valid_dma_direction(direction)); +} + +static u64 qib_sg_dma_address(struct ib_device *dev, struct scatterlist *sg) +{ + u64 addr = (u64) page_address(sg_page(sg)); + + if (addr) + addr += sg->offset; + return addr; +} + +static unsigned int qib_sg_dma_len(struct ib_device *dev, + struct scatterlist *sg) +{ + return sg->length; +} + +static void qib_sync_single_for_cpu(struct ib_device *dev, u64 addr, + size_t size, enum dma_data_direction dir) +{ +} + +static void qib_sync_single_for_device(struct ib_device *dev, u64 addr, + size_t size, + enum dma_data_direction dir) +{ +} + +static void *qib_dma_alloc_coherent(struct ib_device *dev, size_t size, + u64 *dma_handle, gfp_t flag) +{ + struct page *p; + void *addr = NULL; + + p = alloc_pages(flag, get_order(size)); + if (p) + addr = page_address(p); + if (dma_handle) + *dma_handle = (u64) addr; + return addr; +} + +static void qib_dma_free_coherent(struct ib_device *dev, size_t size, + void *cpu_addr, u64 dma_handle) +{ + free_pages((unsigned long) cpu_addr, get_order(size)); +} + +struct ib_dma_mapping_ops qib_dma_mapping_ops = { + .mapping_error = qib_mapping_error, + .map_single = qib_dma_map_single, + .unmap_single = qib_dma_unmap_single, + .map_page = qib_dma_map_page, + .unmap_page = qib_dma_unmap_page, + .map_sg = qib_map_sg, + .unmap_sg = qib_unmap_sg, + .dma_address = qib_sg_dma_address, + .dma_len = qib_sg_dma_len, + .sync_single_for_cpu = qib_sync_single_for_cpu, + .sync_single_for_device = qib_sync_single_for_device, + .alloc_coherent = qib_dma_alloc_coherent, + .free_coherent = qib_dma_free_coherent +}; diff --git a/drivers/infiniband/hw/qib/qib_driver.c b/drivers/infiniband/hw/qib/qib_driver.c new file mode 100644 index 000000000000..f15ce076ac49 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_driver.c @@ -0,0 +1,665 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. + * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include "qib.h" + +/* + * The size has to be longer than this string, so we can append + * board/chip information to it in the init code. + */ +const char ib_qib_version[] = QIB_IDSTR "\n"; + +DEFINE_SPINLOCK(qib_devs_lock); +LIST_HEAD(qib_dev_list); +DEFINE_MUTEX(qib_mutex); /* general driver use */ + +unsigned qib_ibmtu; +module_param_named(ibmtu, qib_ibmtu, uint, S_IRUGO); +MODULE_PARM_DESC(ibmtu, "Set max IB MTU (0=2KB, 1=256, 2=512, ... 5=4096"); + +unsigned qib_compat_ddr_negotiate = 1; +module_param_named(compat_ddr_negotiate, qib_compat_ddr_negotiate, uint, + S_IWUSR | S_IRUGO); +MODULE_PARM_DESC(compat_ddr_negotiate, + "Attempt pre-IBTA 1.2 DDR speed negotiation"); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("QLogic "); +MODULE_DESCRIPTION("QLogic IB driver"); + +/* + * QIB_PIO_MAXIBHDR is the max IB header size allowed for in our + * PIO send buffers. This is well beyond anything currently + * defined in the InfiniBand spec. + */ +#define QIB_PIO_MAXIBHDR 128 + +struct qlogic_ib_stats qib_stats; + +const char *qib_get_unit_name(int unit) +{ + static char iname[16]; + + snprintf(iname, sizeof iname, "infinipath%u", unit); + return iname; +} + +/* + * Return count of units with at least one port ACTIVE. + */ +int qib_count_active_units(void) +{ + struct qib_devdata *dd; + struct qib_pportdata *ppd; + unsigned long flags; + int pidx, nunits_active = 0; + + spin_lock_irqsave(&qib_devs_lock, flags); + list_for_each_entry(dd, &qib_dev_list, list) { + if (!(dd->flags & QIB_PRESENT) || !dd->kregbase) + continue; + for (pidx = 0; pidx < dd->num_pports; ++pidx) { + ppd = dd->pport + pidx; + if (ppd->lid && (ppd->lflags & (QIBL_LINKINIT | + QIBL_LINKARMED | QIBL_LINKACTIVE))) { + nunits_active++; + break; + } + } + } + spin_unlock_irqrestore(&qib_devs_lock, flags); + return nunits_active; +} + +/* + * Return count of all units, optionally return in arguments + * the number of usable (present) units, and the number of + * ports that are up. + */ +int qib_count_units(int *npresentp, int *nupp) +{ + int nunits = 0, npresent = 0, nup = 0; + struct qib_devdata *dd; + unsigned long flags; + int pidx; + struct qib_pportdata *ppd; + + spin_lock_irqsave(&qib_devs_lock, flags); + + list_for_each_entry(dd, &qib_dev_list, list) { + nunits++; + if ((dd->flags & QIB_PRESENT) && dd->kregbase) + npresent++; + for (pidx = 0; pidx < dd->num_pports; ++pidx) { + ppd = dd->pport + pidx; + if (ppd->lid && (ppd->lflags & (QIBL_LINKINIT | + QIBL_LINKARMED | QIBL_LINKACTIVE))) + nup++; + } + } + + spin_unlock_irqrestore(&qib_devs_lock, flags); + + if (npresentp) + *npresentp = npresent; + if (nupp) + *nupp = nup; + + return nunits; +} + +/** + * qib_wait_linkstate - wait for an IB link state change to occur + * @dd: the qlogic_ib device + * @state: the state to wait for + * @msecs: the number of milliseconds to wait + * + * wait up to msecs milliseconds for IB link state change to occur for + * now, take the easy polling route. Currently used only by + * qib_set_linkstate. Returns 0 if state reached, otherwise + * -ETIMEDOUT state can have multiple states set, for any of several + * transitions. + */ +int qib_wait_linkstate(struct qib_pportdata *ppd, u32 state, int msecs) +{ + int ret; + unsigned long flags; + + spin_lock_irqsave(&ppd->lflags_lock, flags); + if (ppd->state_wanted) { + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + ret = -EBUSY; + goto bail; + } + ppd->state_wanted = state; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + wait_event_interruptible_timeout(ppd->state_wait, + (ppd->lflags & state), + msecs_to_jiffies(msecs)); + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->state_wanted = 0; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + + if (!(ppd->lflags & state)) + ret = -ETIMEDOUT; + else + ret = 0; +bail: + return ret; +} + +int qib_set_linkstate(struct qib_pportdata *ppd, u8 newstate) +{ + u32 lstate; + int ret; + struct qib_devdata *dd = ppd->dd; + unsigned long flags; + + switch (newstate) { + case QIB_IB_LINKDOWN_ONLY: + dd->f_set_ib_cfg(ppd, QIB_IB_CFG_LSTATE, + IB_LINKCMD_DOWN | IB_LINKINITCMD_NOP); + /* don't wait */ + ret = 0; + goto bail; + + case QIB_IB_LINKDOWN: + dd->f_set_ib_cfg(ppd, QIB_IB_CFG_LSTATE, + IB_LINKCMD_DOWN | IB_LINKINITCMD_POLL); + /* don't wait */ + ret = 0; + goto bail; + + case QIB_IB_LINKDOWN_SLEEP: + dd->f_set_ib_cfg(ppd, QIB_IB_CFG_LSTATE, + IB_LINKCMD_DOWN | IB_LINKINITCMD_SLEEP); + /* don't wait */ + ret = 0; + goto bail; + + case QIB_IB_LINKDOWN_DISABLE: + dd->f_set_ib_cfg(ppd, QIB_IB_CFG_LSTATE, + IB_LINKCMD_DOWN | IB_LINKINITCMD_DISABLE); + /* don't wait */ + ret = 0; + goto bail; + + case QIB_IB_LINKARM: + if (ppd->lflags & QIBL_LINKARMED) { + ret = 0; + goto bail; + } + if (!(ppd->lflags & (QIBL_LINKINIT | QIBL_LINKACTIVE))) { + ret = -EINVAL; + goto bail; + } + /* + * Since the port can be ACTIVE when we ask for ARMED, + * clear QIBL_LINKV so we can wait for a transition. + * If the link isn't ARMED, then something else happened + * and there is no point waiting for ARMED. + */ + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags &= ~QIBL_LINKV; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + dd->f_set_ib_cfg(ppd, QIB_IB_CFG_LSTATE, + IB_LINKCMD_ARMED | IB_LINKINITCMD_NOP); + lstate = QIBL_LINKV; + break; + + case QIB_IB_LINKACTIVE: + if (ppd->lflags & QIBL_LINKACTIVE) { + ret = 0; + goto bail; + } + if (!(ppd->lflags & QIBL_LINKARMED)) { + ret = -EINVAL; + goto bail; + } + dd->f_set_ib_cfg(ppd, QIB_IB_CFG_LSTATE, + IB_LINKCMD_ACTIVE | IB_LINKINITCMD_NOP); + lstate = QIBL_LINKACTIVE; + break; + + default: + ret = -EINVAL; + goto bail; + } + ret = qib_wait_linkstate(ppd, lstate, 10); + +bail: + return ret; +} + +/* + * Get address of eager buffer from it's index (allocated in chunks, not + * contiguous). + */ +static inline void *qib_get_egrbuf(const struct qib_ctxtdata *rcd, u32 etail) +{ + const u32 chunk = etail / rcd->rcvegrbufs_perchunk; + const u32 idx = etail % rcd->rcvegrbufs_perchunk; + + return rcd->rcvegrbuf[chunk] + idx * rcd->dd->rcvegrbufsize; +} + +/* + * Returns 1 if error was a CRC, else 0. + * Needed for some chip's synthesized error counters. + */ +static u32 qib_rcv_hdrerr(struct qib_pportdata *ppd, u32 ctxt, + u32 eflags, u32 l, u32 etail, __le32 *rhf_addr, + struct qib_message_header *hdr) +{ + u32 ret = 0; + + if (eflags & (QLOGIC_IB_RHF_H_ICRCERR | QLOGIC_IB_RHF_H_VCRCERR)) + ret = 1; + return ret; +} + +/* + * qib_kreceive - receive a packet + * @rcd: the qlogic_ib context + * @llic: gets count of good packets needed to clear lli, + * (used with chips that need need to track crcs for lli) + * + * called from interrupt handler for errors or receive interrupt + * Returns number of CRC error packets, needed by some chips for + * local link integrity tracking. crcs are adjusted down by following + * good packets, if any, and count of good packets is also tracked. + */ +u32 qib_kreceive(struct qib_ctxtdata *rcd, u32 *llic, u32 *npkts) +{ + struct qib_devdata *dd = rcd->dd; + struct qib_pportdata *ppd = rcd->ppd; + __le32 *rhf_addr; + void *ebuf; + const u32 rsize = dd->rcvhdrentsize; /* words */ + const u32 maxcnt = dd->rcvhdrcnt * rsize; /* words */ + u32 etail = -1, l, hdrqtail; + struct qib_message_header *hdr; + u32 eflags, etype, tlen, i = 0, updegr = 0, crcs = 0; + int last; + u64 lval; + struct qib_qp *qp, *nqp; + + l = rcd->head; + rhf_addr = (__le32 *) rcd->rcvhdrq + l + dd->rhf_offset; + if (dd->flags & QIB_NODMA_RTAIL) { + u32 seq = qib_hdrget_seq(rhf_addr); + if (seq != rcd->seq_cnt) + goto bail; + hdrqtail = 0; + } else { + hdrqtail = qib_get_rcvhdrtail(rcd); + if (l == hdrqtail) + goto bail; + smp_rmb(); /* prevent speculative reads of dma'ed hdrq */ + } + + for (last = 0, i = 1; !last; i += !last) { + hdr = dd->f_get_msgheader(dd, rhf_addr); + eflags = qib_hdrget_err_flags(rhf_addr); + etype = qib_hdrget_rcv_type(rhf_addr); + /* total length */ + tlen = qib_hdrget_length_in_bytes(rhf_addr); + ebuf = NULL; + if ((dd->flags & QIB_NODMA_RTAIL) ? + qib_hdrget_use_egr_buf(rhf_addr) : + (etype != RCVHQ_RCV_TYPE_EXPECTED)) { + etail = qib_hdrget_index(rhf_addr); + updegr = 1; + if (tlen > sizeof(*hdr) || + etype >= RCVHQ_RCV_TYPE_NON_KD) + ebuf = qib_get_egrbuf(rcd, etail); + } + if (!eflags) { + u16 lrh_len = be16_to_cpu(hdr->lrh[2]) << 2; + + if (lrh_len != tlen) { + qib_stats.sps_lenerrs++; + goto move_along; + } + } + if (etype == RCVHQ_RCV_TYPE_NON_KD && !eflags && + ebuf == NULL && + tlen > (dd->rcvhdrentsize - 2 + 1 - + qib_hdrget_offset(rhf_addr)) << 2) { + goto move_along; + } + + /* + * Both tiderr and qibhdrerr are set for all plain IB + * packets; only qibhdrerr should be set. + */ + if (unlikely(eflags)) + crcs += qib_rcv_hdrerr(ppd, rcd->ctxt, eflags, l, + etail, rhf_addr, hdr); + else if (etype == RCVHQ_RCV_TYPE_NON_KD) { + qib_ib_rcv(rcd, hdr, ebuf, tlen); + if (crcs) + crcs--; + else if (llic && *llic) + --*llic; + } +move_along: + l += rsize; + if (l >= maxcnt) + l = 0; + rhf_addr = (__le32 *) rcd->rcvhdrq + l + dd->rhf_offset; + if (dd->flags & QIB_NODMA_RTAIL) { + u32 seq = qib_hdrget_seq(rhf_addr); + + if (++rcd->seq_cnt > 13) + rcd->seq_cnt = 1; + if (seq != rcd->seq_cnt) + last = 1; + } else if (l == hdrqtail) + last = 1; + /* + * Update head regs etc., every 16 packets, if not last pkt, + * to help prevent rcvhdrq overflows, when many packets + * are processed and queue is nearly full. + * Don't request an interrupt for intermediate updates. + */ + lval = l; + if (!last && !(i & 0xf)) { + dd->f_update_usrhead(rcd, lval, updegr, etail); + updegr = 0; + } + } + + rcd->head = l; + rcd->pkt_count += i; + + /* + * Iterate over all QPs waiting to respond. + * The list won't change since the IRQ is only run on one CPU. + */ + list_for_each_entry_safe(qp, nqp, &rcd->qp_wait_list, rspwait) { + list_del_init(&qp->rspwait); + if (qp->r_flags & QIB_R_RSP_NAK) { + qp->r_flags &= ~QIB_R_RSP_NAK; + qib_send_rc_ack(qp); + } + if (qp->r_flags & QIB_R_RSP_SEND) { + unsigned long flags; + + qp->r_flags &= ~QIB_R_RSP_SEND; + spin_lock_irqsave(&qp->s_lock, flags); + if (ib_qib_state_ops[qp->state] & + QIB_PROCESS_OR_FLUSH_SEND) + qib_schedule_send(qp); + spin_unlock_irqrestore(&qp->s_lock, flags); + } + if (atomic_dec_and_test(&qp->refcount)) + wake_up(&qp->wait); + } + +bail: + /* Report number of packets consumed */ + if (npkts) + *npkts = i; + + /* + * Always write head at end, and setup rcv interrupt, even + * if no packets were processed. + */ + lval = (u64)rcd->head | dd->rhdrhead_intr_off; + dd->f_update_usrhead(rcd, lval, updegr, etail); + return crcs; +} + +/** + * qib_set_mtu - set the MTU + * @ppd: the perport data + * @arg: the new MTU + * + * We can handle "any" incoming size, the issue here is whether we + * need to restrict our outgoing size. For now, we don't do any + * sanity checking on this, and we don't deal with what happens to + * programs that are already running when the size changes. + * NOTE: changing the MTU will usually cause the IBC to go back to + * link INIT state... + */ +int qib_set_mtu(struct qib_pportdata *ppd, u16 arg) +{ + u32 piosize; + int ret, chk; + + if (arg != 256 && arg != 512 && arg != 1024 && arg != 2048 && + arg != 4096) { + ret = -EINVAL; + goto bail; + } + chk = ib_mtu_enum_to_int(qib_ibmtu); + if (chk > 0 && arg > chk) { + ret = -EINVAL; + goto bail; + } + + piosize = ppd->ibmaxlen; + ppd->ibmtu = arg; + + if (arg >= (piosize - QIB_PIO_MAXIBHDR)) { + /* Only if it's not the initial value (or reset to it) */ + if (piosize != ppd->init_ibmaxlen) { + if (arg > piosize && arg <= ppd->init_ibmaxlen) + piosize = ppd->init_ibmaxlen - 2 * sizeof(u32); + ppd->ibmaxlen = piosize; + } + } else if ((arg + QIB_PIO_MAXIBHDR) != ppd->ibmaxlen) { + piosize = arg + QIB_PIO_MAXIBHDR - 2 * sizeof(u32); + ppd->ibmaxlen = piosize; + } + + ppd->dd->f_set_ib_cfg(ppd, QIB_IB_CFG_MTU, 0); + + ret = 0; + +bail: + return ret; +} + +int qib_set_lid(struct qib_pportdata *ppd, u32 lid, u8 lmc) +{ + struct qib_devdata *dd = ppd->dd; + ppd->lid = lid; + ppd->lmc = lmc; + + dd->f_set_ib_cfg(ppd, QIB_IB_CFG_LIDLMC, + lid | (~((1U << lmc) - 1)) << 16); + + qib_devinfo(dd->pcidev, "IB%u:%u got a lid: 0x%x\n", + dd->unit, ppd->port, lid); + + return 0; +} + +/* + * Following deal with the "obviously simple" task of overriding the state + * of the LEDS, which normally indicate link physical and logical status. + * The complications arise in dealing with different hardware mappings + * and the board-dependent routine being called from interrupts. + * and then there's the requirement to _flash_ them. + */ +#define LED_OVER_FREQ_SHIFT 8 +#define LED_OVER_FREQ_MASK (0xFF<dd; + int timeoff; + int ph_idx; + + if (!(dd->flags & QIB_INITTED)) + return; + + ph_idx = ppd->led_override_phase++ & 1; + ppd->led_override = ppd->led_override_vals[ph_idx]; + timeoff = ppd->led_override_timeoff; + + dd->f_setextled(ppd, 1); + /* + * don't re-fire the timer if user asked for it to be off; we let + * it fire one more time after they turn it off to simplify + */ + if (ppd->led_override_vals[0] || ppd->led_override_vals[1]) + mod_timer(&ppd->led_override_timer, jiffies + timeoff); +} + +void qib_set_led_override(struct qib_pportdata *ppd, unsigned int val) +{ + struct qib_devdata *dd = ppd->dd; + int timeoff, freq; + + if (!(dd->flags & QIB_INITTED)) + return; + + /* First check if we are blinking. If not, use 1HZ polling */ + timeoff = HZ; + freq = (val & LED_OVER_FREQ_MASK) >> LED_OVER_FREQ_SHIFT; + + if (freq) { + /* For blink, set each phase from one nybble of val */ + ppd->led_override_vals[0] = val & 0xF; + ppd->led_override_vals[1] = (val >> 4) & 0xF; + timeoff = (HZ << 4)/freq; + } else { + /* Non-blink set both phases the same. */ + ppd->led_override_vals[0] = val & 0xF; + ppd->led_override_vals[1] = val & 0xF; + } + ppd->led_override_timeoff = timeoff; + + /* + * If the timer has not already been started, do so. Use a "quick" + * timeout so the function will be called soon, to look at our request. + */ + if (atomic_inc_return(&ppd->led_override_timer_active) == 1) { + /* Need to start timer */ + init_timer(&ppd->led_override_timer); + ppd->led_override_timer.function = qib_run_led_override; + ppd->led_override_timer.data = (unsigned long) ppd; + ppd->led_override_timer.expires = jiffies + 1; + add_timer(&ppd->led_override_timer); + } else { + if (ppd->led_override_vals[0] || ppd->led_override_vals[1]) + mod_timer(&ppd->led_override_timer, jiffies + 1); + atomic_dec(&ppd->led_override_timer_active); + } +} + +/** + * qib_reset_device - reset the chip if possible + * @unit: the device to reset + * + * Whether or not reset is successful, we attempt to re-initialize the chip + * (that is, much like a driver unload/reload). We clear the INITTED flag + * so that the various entry points will fail until we reinitialize. For + * now, we only allow this if no user contexts are open that use chip resources + */ +int qib_reset_device(int unit) +{ + int ret, i; + struct qib_devdata *dd = qib_lookup(unit); + struct qib_pportdata *ppd; + unsigned long flags; + int pidx; + + if (!dd) { + ret = -ENODEV; + goto bail; + } + + qib_devinfo(dd->pcidev, "Reset on unit %u requested\n", unit); + + if (!dd->kregbase || !(dd->flags & QIB_PRESENT)) { + qib_devinfo(dd->pcidev, "Invalid unit number %u or " + "not initialized or not present\n", unit); + ret = -ENXIO; + goto bail; + } + + spin_lock_irqsave(&dd->uctxt_lock, flags); + if (dd->rcd) + for (i = dd->first_user_ctxt; i < dd->cfgctxts; i++) { + if (!dd->rcd[i] || !dd->rcd[i]->cnt) + continue; + spin_unlock_irqrestore(&dd->uctxt_lock, flags); + ret = -EBUSY; + goto bail; + } + spin_unlock_irqrestore(&dd->uctxt_lock, flags); + + for (pidx = 0; pidx < dd->num_pports; ++pidx) { + ppd = dd->pport + pidx; + if (atomic_read(&ppd->led_override_timer_active)) { + /* Need to stop LED timer, _then_ shut off LEDs */ + del_timer_sync(&ppd->led_override_timer); + atomic_set(&ppd->led_override_timer_active, 0); + } + + /* Shut off LEDs after we are sure timer is not running */ + ppd->led_override = LED_OVER_BOTH_OFF; + dd->f_setextled(ppd, 0); + if (dd->flags & QIB_HAS_SEND_DMA) + qib_teardown_sdma(ppd); + } + + ret = dd->f_reset(dd); + if (ret == 1) + ret = qib_init(dd, 1); + else + ret = -EAGAIN; + if (ret) + qib_dev_err(dd, "Reinitialize unit %u after " + "reset failed with %d\n", unit, ret); + else + qib_devinfo(dd->pcidev, "Reinitialized unit %u after " + "resetting\n", unit); + +bail: + return ret; +} diff --git a/drivers/infiniband/hw/qib/qib_eeprom.c b/drivers/infiniband/hw/qib/qib_eeprom.c new file mode 100644 index 000000000000..92d9cfe98a68 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_eeprom.c @@ -0,0 +1,451 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. + * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include + +#include "qib.h" + +/* + * Functions specific to the serial EEPROM on cards handled by ib_qib. + * The actual serail interface code is in qib_twsi.c. This file is a client + */ + +/** + * qib_eeprom_read - receives bytes from the eeprom via I2C + * @dd: the qlogic_ib device + * @eeprom_offset: address to read from + * @buffer: where to store result + * @len: number of bytes to receive + */ +int qib_eeprom_read(struct qib_devdata *dd, u8 eeprom_offset, + void *buff, int len) +{ + int ret; + + ret = mutex_lock_interruptible(&dd->eep_lock); + if (!ret) { + ret = qib_twsi_reset(dd); + if (ret) + qib_dev_err(dd, "EEPROM Reset for read failed\n"); + else + ret = qib_twsi_blk_rd(dd, dd->twsi_eeprom_dev, + eeprom_offset, buff, len); + mutex_unlock(&dd->eep_lock); + } + + return ret; +} + +/* + * Actually update the eeprom, first doing write enable if + * needed, then restoring write enable state. + * Must be called with eep_lock held + */ +static int eeprom_write_with_enable(struct qib_devdata *dd, u8 offset, + const void *buf, int len) +{ + int ret, pwen; + + pwen = dd->f_eeprom_wen(dd, 1); + ret = qib_twsi_reset(dd); + if (ret) + qib_dev_err(dd, "EEPROM Reset for write failed\n"); + else + ret = qib_twsi_blk_wr(dd, dd->twsi_eeprom_dev, + offset, buf, len); + dd->f_eeprom_wen(dd, pwen); + return ret; +} + +/** + * qib_eeprom_write - writes data to the eeprom via I2C + * @dd: the qlogic_ib device + * @eeprom_offset: where to place data + * @buffer: data to write + * @len: number of bytes to write + */ +int qib_eeprom_write(struct qib_devdata *dd, u8 eeprom_offset, + const void *buff, int len) +{ + int ret; + + ret = mutex_lock_interruptible(&dd->eep_lock); + if (!ret) { + ret = eeprom_write_with_enable(dd, eeprom_offset, buff, len); + mutex_unlock(&dd->eep_lock); + } + + return ret; +} + +static u8 flash_csum(struct qib_flash *ifp, int adjust) +{ + u8 *ip = (u8 *) ifp; + u8 csum = 0, len; + + /* + * Limit length checksummed to max length of actual data. + * Checksum of erased eeprom will still be bad, but we avoid + * reading past the end of the buffer we were passed. + */ + len = ifp->if_length; + if (len > sizeof(struct qib_flash)) + len = sizeof(struct qib_flash); + while (len--) + csum += *ip++; + csum -= ifp->if_csum; + csum = ~csum; + if (adjust) + ifp->if_csum = csum; + + return csum; +} + +/** + * qib_get_eeprom_info- get the GUID et al. from the TSWI EEPROM device + * @dd: the qlogic_ib device + * + * We have the capability to use the nguid field, and get + * the guid from the first chip's flash, to use for all of them. + */ +void qib_get_eeprom_info(struct qib_devdata *dd) +{ + void *buf; + struct qib_flash *ifp; + __be64 guid; + int len, eep_stat; + u8 csum, *bguid; + int t = dd->unit; + struct qib_devdata *dd0 = qib_lookup(0); + + if (t && dd0->nguid > 1 && t <= dd0->nguid) { + u8 oguid; + dd->base_guid = dd0->base_guid; + bguid = (u8 *) &dd->base_guid; + + oguid = bguid[7]; + bguid[7] += t; + if (oguid > bguid[7]) { + if (bguid[6] == 0xff) { + if (bguid[5] == 0xff) { + qib_dev_err(dd, "Can't set %s GUID" + " from base, wraps to" + " OUI!\n", + qib_get_unit_name(t)); + dd->base_guid = 0; + goto bail; + } + bguid[5]++; + } + bguid[6]++; + } + dd->nguid = 1; + goto bail; + } + + /* + * Read full flash, not just currently used part, since it may have + * been written with a newer definition. + * */ + len = sizeof(struct qib_flash); + buf = vmalloc(len); + if (!buf) { + qib_dev_err(dd, "Couldn't allocate memory to read %u " + "bytes from eeprom for GUID\n", len); + goto bail; + } + + /* + * Use "public" eeprom read function, which does locking and + * figures out device. This will migrate to chip-specific. + */ + eep_stat = qib_eeprom_read(dd, 0, buf, len); + + if (eep_stat) { + qib_dev_err(dd, "Failed reading GUID from eeprom\n"); + goto done; + } + ifp = (struct qib_flash *)buf; + + csum = flash_csum(ifp, 0); + if (csum != ifp->if_csum) { + qib_devinfo(dd->pcidev, "Bad I2C flash checksum: " + "0x%x, not 0x%x\n", csum, ifp->if_csum); + goto done; + } + if (*(__be64 *) ifp->if_guid == cpu_to_be64(0) || + *(__be64 *) ifp->if_guid == ~cpu_to_be64(0)) { + qib_dev_err(dd, "Invalid GUID %llx from flash; ignoring\n", + *(unsigned long long *) ifp->if_guid); + /* don't allow GUID if all 0 or all 1's */ + goto done; + } + + /* complain, but allow it */ + if (*(u64 *) ifp->if_guid == 0x100007511000000ULL) + qib_devinfo(dd->pcidev, "Warning, GUID %llx is " + "default, probably not correct!\n", + *(unsigned long long *) ifp->if_guid); + + bguid = ifp->if_guid; + if (!bguid[0] && !bguid[1] && !bguid[2]) { + /* + * Original incorrect GUID format in flash; fix in + * core copy, by shifting up 2 octets; don't need to + * change top octet, since both it and shifted are 0. + */ + bguid[1] = bguid[3]; + bguid[2] = bguid[4]; + bguid[3] = 0; + bguid[4] = 0; + guid = *(__be64 *) ifp->if_guid; + } else + guid = *(__be64 *) ifp->if_guid; + dd->base_guid = guid; + dd->nguid = ifp->if_numguid; + /* + * Things are slightly complicated by the desire to transparently + * support both the Pathscale 10-digit serial number and the QLogic + * 13-character version. + */ + if ((ifp->if_fversion > 1) && ifp->if_sprefix[0] && + ((u8 *) ifp->if_sprefix)[0] != 0xFF) { + char *snp = dd->serial; + + /* + * This board has a Serial-prefix, which is stored + * elsewhere for backward-compatibility. + */ + memcpy(snp, ifp->if_sprefix, sizeof ifp->if_sprefix); + snp[sizeof ifp->if_sprefix] = '\0'; + len = strlen(snp); + snp += len; + len = (sizeof dd->serial) - len; + if (len > sizeof ifp->if_serial) + len = sizeof ifp->if_serial; + memcpy(snp, ifp->if_serial, len); + } else + memcpy(dd->serial, ifp->if_serial, + sizeof ifp->if_serial); + if (!strstr(ifp->if_comment, "Tested successfully")) + qib_dev_err(dd, "Board SN %s did not pass functional " + "test: %s\n", dd->serial, ifp->if_comment); + + memcpy(&dd->eep_st_errs, &ifp->if_errcntp, QIB_EEP_LOG_CNT); + /* + * Power-on (actually "active") hours are kept as little-endian value + * in EEPROM, but as seconds in a (possibly as small as 24-bit) + * atomic_t while running. + */ + atomic_set(&dd->active_time, 0); + dd->eep_hrs = ifp->if_powerhour[0] | (ifp->if_powerhour[1] << 8); + +done: + vfree(buf); + +bail:; +} + +/** + * qib_update_eeprom_log - copy active-time and error counters to eeprom + * @dd: the qlogic_ib device + * + * Although the time is kept as seconds in the qib_devdata struct, it is + * rounded to hours for re-write, as we have only 16 bits in EEPROM. + * First-cut code reads whole (expected) struct qib_flash, modifies, + * re-writes. Future direction: read/write only what we need, assuming + * that the EEPROM had to have been "good enough" for driver init, and + * if not, we aren't making it worse. + * + */ +int qib_update_eeprom_log(struct qib_devdata *dd) +{ + void *buf; + struct qib_flash *ifp; + int len, hi_water; + uint32_t new_time, new_hrs; + u8 csum; + int ret, idx; + unsigned long flags; + + /* first, check if we actually need to do anything. */ + ret = 0; + for (idx = 0; idx < QIB_EEP_LOG_CNT; ++idx) { + if (dd->eep_st_new_errs[idx]) { + ret = 1; + break; + } + } + new_time = atomic_read(&dd->active_time); + + if (ret == 0 && new_time < 3600) + goto bail; + + /* + * The quick-check above determined that there is something worthy + * of logging, so get current contents and do a more detailed idea. + * read full flash, not just currently used part, since it may have + * been written with a newer definition + */ + len = sizeof(struct qib_flash); + buf = vmalloc(len); + ret = 1; + if (!buf) { + qib_dev_err(dd, "Couldn't allocate memory to read %u " + "bytes from eeprom for logging\n", len); + goto bail; + } + + /* Grab semaphore and read current EEPROM. If we get an + * error, let go, but if not, keep it until we finish write. + */ + ret = mutex_lock_interruptible(&dd->eep_lock); + if (ret) { + qib_dev_err(dd, "Unable to acquire EEPROM for logging\n"); + goto free_bail; + } + ret = qib_twsi_blk_rd(dd, dd->twsi_eeprom_dev, 0, buf, len); + if (ret) { + mutex_unlock(&dd->eep_lock); + qib_dev_err(dd, "Unable read EEPROM for logging\n"); + goto free_bail; + } + ifp = (struct qib_flash *)buf; + + csum = flash_csum(ifp, 0); + if (csum != ifp->if_csum) { + mutex_unlock(&dd->eep_lock); + qib_dev_err(dd, "EEPROM cks err (0x%02X, S/B 0x%02X)\n", + csum, ifp->if_csum); + ret = 1; + goto free_bail; + } + hi_water = 0; + spin_lock_irqsave(&dd->eep_st_lock, flags); + for (idx = 0; idx < QIB_EEP_LOG_CNT; ++idx) { + int new_val = dd->eep_st_new_errs[idx]; + if (new_val) { + /* + * If we have seen any errors, add to EEPROM values + * We need to saturate at 0xFF (255) and we also + * would need to adjust the checksum if we were + * trying to minimize EEPROM traffic + * Note that we add to actual current count in EEPROM, + * in case it was altered while we were running. + */ + new_val += ifp->if_errcntp[idx]; + if (new_val > 0xFF) + new_val = 0xFF; + if (ifp->if_errcntp[idx] != new_val) { + ifp->if_errcntp[idx] = new_val; + hi_water = offsetof(struct qib_flash, + if_errcntp) + idx; + } + /* + * update our shadow (used to minimize EEPROM + * traffic), to match what we are about to write. + */ + dd->eep_st_errs[idx] = new_val; + dd->eep_st_new_errs[idx] = 0; + } + } + /* + * Now update active-time. We would like to round to the nearest hour + * but unless atomic_t are sure to be proper signed ints we cannot, + * because we need to account for what we "transfer" to EEPROM and + * if we log an hour at 31 minutes, then we would need to set + * active_time to -29 to accurately count the _next_ hour. + */ + if (new_time >= 3600) { + new_hrs = new_time / 3600; + atomic_sub((new_hrs * 3600), &dd->active_time); + new_hrs += dd->eep_hrs; + if (new_hrs > 0xFFFF) + new_hrs = 0xFFFF; + dd->eep_hrs = new_hrs; + if ((new_hrs & 0xFF) != ifp->if_powerhour[0]) { + ifp->if_powerhour[0] = new_hrs & 0xFF; + hi_water = offsetof(struct qib_flash, if_powerhour); + } + if ((new_hrs >> 8) != ifp->if_powerhour[1]) { + ifp->if_powerhour[1] = new_hrs >> 8; + hi_water = offsetof(struct qib_flash, if_powerhour) + 1; + } + } + /* + * There is a tiny possibility that we could somehow fail to write + * the EEPROM after updating our shadows, but problems from holding + * the spinlock too long are a much bigger issue. + */ + spin_unlock_irqrestore(&dd->eep_st_lock, flags); + if (hi_water) { + /* we made some change to the data, uopdate cksum and write */ + csum = flash_csum(ifp, 1); + ret = eeprom_write_with_enable(dd, 0, buf, hi_water + 1); + } + mutex_unlock(&dd->eep_lock); + if (ret) + qib_dev_err(dd, "Failed updating EEPROM\n"); + +free_bail: + vfree(buf); +bail: + return ret; +} + +/** + * qib_inc_eeprom_err - increment one of the four error counters + * that are logged to EEPROM. + * @dd: the qlogic_ib device + * @eidx: 0..3, the counter to increment + * @incr: how much to add + * + * Each counter is 8-bits, and saturates at 255 (0xFF). They + * are copied to the EEPROM (aka flash) whenever qib_update_eeprom_log() + * is called, but it can only be called in a context that allows sleep. + * This function can be called even at interrupt level. + */ +void qib_inc_eeprom_err(struct qib_devdata *dd, u32 eidx, u32 incr) +{ + uint new_val; + unsigned long flags; + + spin_lock_irqsave(&dd->eep_st_lock, flags); + new_val = dd->eep_st_new_errs[eidx] + incr; + if (new_val > 255) + new_val = 255; + dd->eep_st_new_errs[eidx] = new_val; + spin_unlock_irqrestore(&dd->eep_st_lock, flags); +} diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c b/drivers/infiniband/hw/qib/qib_file_ops.c new file mode 100644 index 000000000000..a142a9eb5226 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_file_ops.c @@ -0,0 +1,2317 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation. + * All rights reserved. + * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qib.h" +#include "qib_common.h" +#include "qib_user_sdma.h" + +static int qib_open(struct inode *, struct file *); +static int qib_close(struct inode *, struct file *); +static ssize_t qib_write(struct file *, const char __user *, size_t, loff_t *); +static ssize_t qib_aio_write(struct kiocb *, const struct iovec *, + unsigned long, loff_t); +static unsigned int qib_poll(struct file *, struct poll_table_struct *); +static int qib_mmapf(struct file *, struct vm_area_struct *); + +static const struct file_operations qib_file_ops = { + .owner = THIS_MODULE, + .write = qib_write, + .aio_write = qib_aio_write, + .open = qib_open, + .release = qib_close, + .poll = qib_poll, + .mmap = qib_mmapf +}; + +/* + * Convert kernel virtual addresses to physical addresses so they don't + * potentially conflict with the chip addresses used as mmap offsets. + * It doesn't really matter what mmap offset we use as long as we can + * interpret it correctly. + */ +static u64 cvt_kvaddr(void *p) +{ + struct page *page; + u64 paddr = 0; + + page = vmalloc_to_page(p); + if (page) + paddr = page_to_pfn(page) << PAGE_SHIFT; + + return paddr; +} + +static int qib_get_base_info(struct file *fp, void __user *ubase, + size_t ubase_size) +{ + struct qib_ctxtdata *rcd = ctxt_fp(fp); + int ret = 0; + struct qib_base_info *kinfo = NULL; + struct qib_devdata *dd = rcd->dd; + struct qib_pportdata *ppd = rcd->ppd; + unsigned subctxt_cnt; + int shared, master; + size_t sz; + + subctxt_cnt = rcd->subctxt_cnt; + if (!subctxt_cnt) { + shared = 0; + master = 0; + subctxt_cnt = 1; + } else { + shared = 1; + master = !subctxt_fp(fp); + } + + sz = sizeof(*kinfo); + /* If context sharing is not requested, allow the old size structure */ + if (!shared) + sz -= 7 * sizeof(u64); + if (ubase_size < sz) { + ret = -EINVAL; + goto bail; + } + + kinfo = kzalloc(sizeof(*kinfo), GFP_KERNEL); + if (kinfo == NULL) { + ret = -ENOMEM; + goto bail; + } + + ret = dd->f_get_base_info(rcd, kinfo); + if (ret < 0) + goto bail; + + kinfo->spi_rcvhdr_cnt = dd->rcvhdrcnt; + kinfo->spi_rcvhdrent_size = dd->rcvhdrentsize; + kinfo->spi_tidegrcnt = rcd->rcvegrcnt; + kinfo->spi_rcv_egrbufsize = dd->rcvegrbufsize; + /* + * have to mmap whole thing + */ + kinfo->spi_rcv_egrbuftotlen = + rcd->rcvegrbuf_chunks * rcd->rcvegrbuf_size; + kinfo->spi_rcv_egrperchunk = rcd->rcvegrbufs_perchunk; + kinfo->spi_rcv_egrchunksize = kinfo->spi_rcv_egrbuftotlen / + rcd->rcvegrbuf_chunks; + kinfo->spi_tidcnt = dd->rcvtidcnt / subctxt_cnt; + if (master) + kinfo->spi_tidcnt += dd->rcvtidcnt % subctxt_cnt; + /* + * for this use, may be cfgctxts summed over all chips that + * are are configured and present + */ + kinfo->spi_nctxts = dd->cfgctxts; + /* unit (chip/board) our context is on */ + kinfo->spi_unit = dd->unit; + kinfo->spi_port = ppd->port; + /* for now, only a single page */ + kinfo->spi_tid_maxsize = PAGE_SIZE; + + /* + * Doing this per context, and based on the skip value, etc. This has + * to be the actual buffer size, since the protocol code treats it + * as an array. + * + * These have to be set to user addresses in the user code via mmap. + * These values are used on return to user code for the mmap target + * addresses only. For 32 bit, same 44 bit address problem, so use + * the physical address, not virtual. Before 2.6.11, using the + * page_address() macro worked, but in 2.6.11, even that returns the + * full 64 bit address (upper bits all 1's). So far, using the + * physical addresses (or chip offsets, for chip mapping) works, but + * no doubt some future kernel release will change that, and we'll be + * on to yet another method of dealing with this. + * Normally only one of rcvhdr_tailaddr or rhf_offset is useful + * since the chips with non-zero rhf_offset don't normally + * enable tail register updates to host memory, but for testing, + * both can be enabled and used. + */ + kinfo->spi_rcvhdr_base = (u64) rcd->rcvhdrq_phys; + kinfo->spi_rcvhdr_tailaddr = (u64) rcd->rcvhdrqtailaddr_phys; + kinfo->spi_rhf_offset = dd->rhf_offset; + kinfo->spi_rcv_egrbufs = (u64) rcd->rcvegr_phys; + kinfo->spi_pioavailaddr = (u64) dd->pioavailregs_phys; + /* setup per-unit (not port) status area for user programs */ + kinfo->spi_status = (u64) kinfo->spi_pioavailaddr + + (char *) ppd->statusp - + (char *) dd->pioavailregs_dma; + kinfo->spi_uregbase = (u64) dd->uregbase + dd->ureg_align * rcd->ctxt; + if (!shared) { + kinfo->spi_piocnt = rcd->piocnt; + kinfo->spi_piobufbase = (u64) rcd->piobufs; + kinfo->spi_sendbuf_status = cvt_kvaddr(rcd->user_event_mask); + } else if (master) { + kinfo->spi_piocnt = (rcd->piocnt / subctxt_cnt) + + (rcd->piocnt % subctxt_cnt); + /* Master's PIO buffers are after all the slave's */ + kinfo->spi_piobufbase = (u64) rcd->piobufs + + dd->palign * + (rcd->piocnt - kinfo->spi_piocnt); + } else { + unsigned slave = subctxt_fp(fp) - 1; + + kinfo->spi_piocnt = rcd->piocnt / subctxt_cnt; + kinfo->spi_piobufbase = (u64) rcd->piobufs + + dd->palign * kinfo->spi_piocnt * slave; + } + + if (shared) { + kinfo->spi_sendbuf_status = + cvt_kvaddr(&rcd->user_event_mask[subctxt_fp(fp)]); + /* only spi_subctxt_* fields should be set in this block! */ + kinfo->spi_subctxt_uregbase = cvt_kvaddr(rcd->subctxt_uregbase); + + kinfo->spi_subctxt_rcvegrbuf = + cvt_kvaddr(rcd->subctxt_rcvegrbuf); + kinfo->spi_subctxt_rcvhdr_base = + cvt_kvaddr(rcd->subctxt_rcvhdr_base); + } + + /* + * All user buffers are 2KB buffers. If we ever support + * giving 4KB buffers to user processes, this will need some + * work. Can't use piobufbase directly, because it has + * both 2K and 4K buffer base values. + */ + kinfo->spi_pioindex = (kinfo->spi_piobufbase - dd->pio2k_bufbase) / + dd->palign; + kinfo->spi_pioalign = dd->palign; + kinfo->spi_qpair = QIB_KD_QP; + /* + * user mode PIO buffers are always 2KB, even when 4KB can + * be received, and sent via the kernel; this is ibmaxlen + * for 2K MTU. + */ + kinfo->spi_piosize = dd->piosize2k - 2 * sizeof(u32); + kinfo->spi_mtu = ppd->ibmaxlen; /* maxlen, not ibmtu */ + kinfo->spi_ctxt = rcd->ctxt; + kinfo->spi_subctxt = subctxt_fp(fp); + kinfo->spi_sw_version = QIB_KERN_SWVERSION; + kinfo->spi_sw_version |= 1U << 31; /* QLogic-built, not kernel.org */ + kinfo->spi_hw_version = dd->revision; + + if (master) + kinfo->spi_runtime_flags |= QIB_RUNTIME_MASTER; + + sz = (ubase_size < sizeof(*kinfo)) ? ubase_size : sizeof(*kinfo); + if (copy_to_user(ubase, kinfo, sz)) + ret = -EFAULT; +bail: + kfree(kinfo); + return ret; +} + +/** + * qib_tid_update - update a context TID + * @rcd: the context + * @fp: the qib device file + * @ti: the TID information + * + * The new implementation as of Oct 2004 is that the driver assigns + * the tid and returns it to the caller. To reduce search time, we + * keep a cursor for each context, walking the shadow tid array to find + * one that's not in use. + * + * For now, if we can't allocate the full list, we fail, although + * in the long run, we'll allocate as many as we can, and the + * caller will deal with that by trying the remaining pages later. + * That means that when we fail, we have to mark the tids as not in + * use again, in our shadow copy. + * + * It's up to the caller to free the tids when they are done. + * We'll unlock the pages as they free them. + * + * Also, right now we are locking one page at a time, but since + * the intended use of this routine is for a single group of + * virtually contiguous pages, that should change to improve + * performance. + */ +static int qib_tid_update(struct qib_ctxtdata *rcd, struct file *fp, + const struct qib_tid_info *ti) +{ + int ret = 0, ntids; + u32 tid, ctxttid, cnt, i, tidcnt, tidoff; + u16 *tidlist; + struct qib_devdata *dd = rcd->dd; + u64 physaddr; + unsigned long vaddr; + u64 __iomem *tidbase; + unsigned long tidmap[8]; + struct page **pagep = NULL; + unsigned subctxt = subctxt_fp(fp); + + if (!dd->pageshadow) { + ret = -ENOMEM; + goto done; + } + + cnt = ti->tidcnt; + if (!cnt) { + ret = -EFAULT; + goto done; + } + ctxttid = rcd->ctxt * dd->rcvtidcnt; + if (!rcd->subctxt_cnt) { + tidcnt = dd->rcvtidcnt; + tid = rcd->tidcursor; + tidoff = 0; + } else if (!subctxt) { + tidcnt = (dd->rcvtidcnt / rcd->subctxt_cnt) + + (dd->rcvtidcnt % rcd->subctxt_cnt); + tidoff = dd->rcvtidcnt - tidcnt; + ctxttid += tidoff; + tid = tidcursor_fp(fp); + } else { + tidcnt = dd->rcvtidcnt / rcd->subctxt_cnt; + tidoff = tidcnt * (subctxt - 1); + ctxttid += tidoff; + tid = tidcursor_fp(fp); + } + if (cnt > tidcnt) { + /* make sure it all fits in tid_pg_list */ + qib_devinfo(dd->pcidev, "Process tried to allocate %u " + "TIDs, only trying max (%u)\n", cnt, tidcnt); + cnt = tidcnt; + } + pagep = (struct page **) rcd->tid_pg_list; + tidlist = (u16 *) &pagep[dd->rcvtidcnt]; + pagep += tidoff; + tidlist += tidoff; + + memset(tidmap, 0, sizeof(tidmap)); + /* before decrement; chip actual # */ + ntids = tidcnt; + tidbase = (u64 __iomem *) (((char __iomem *) dd->kregbase) + + dd->rcvtidbase + + ctxttid * sizeof(*tidbase)); + + /* virtual address of first page in transfer */ + vaddr = ti->tidvaddr; + if (!access_ok(VERIFY_WRITE, (void __user *) vaddr, + cnt * PAGE_SIZE)) { + ret = -EFAULT; + goto done; + } + ret = qib_get_user_pages(vaddr, cnt, pagep); + if (ret) { + /* + * if (ret == -EBUSY) + * We can't continue because the pagep array won't be + * initialized. This should never happen, + * unless perhaps the user has mpin'ed the pages + * themselves. + */ + qib_devinfo(dd->pcidev, + "Failed to lock addr %p, %u pages: " + "errno %d\n", (void *) vaddr, cnt, -ret); + goto done; + } + for (i = 0; i < cnt; i++, vaddr += PAGE_SIZE) { + for (; ntids--; tid++) { + if (tid == tidcnt) + tid = 0; + if (!dd->pageshadow[ctxttid + tid]) + break; + } + if (ntids < 0) { + /* + * Oops, wrapped all the way through their TIDs, + * and didn't have enough free; see comments at + * start of routine + */ + i--; /* last tidlist[i] not filled in */ + ret = -ENOMEM; + break; + } + tidlist[i] = tid + tidoff; + /* we "know" system pages and TID pages are same size */ + dd->pageshadow[ctxttid + tid] = pagep[i]; + dd->physshadow[ctxttid + tid] = + qib_map_page(dd->pcidev, pagep[i], 0, PAGE_SIZE, + PCI_DMA_FROMDEVICE); + /* + * don't need atomic or it's overhead + */ + __set_bit(tid, tidmap); + physaddr = dd->physshadow[ctxttid + tid]; + /* PERFORMANCE: below should almost certainly be cached */ + dd->f_put_tid(dd, &tidbase[tid], + RCVHQ_RCV_TYPE_EXPECTED, physaddr); + /* + * don't check this tid in qib_ctxtshadow, since we + * just filled it in; start with the next one. + */ + tid++; + } + + if (ret) { + u32 limit; +cleanup: + /* jump here if copy out of updated info failed... */ + /* same code that's in qib_free_tid() */ + limit = sizeof(tidmap) * BITS_PER_BYTE; + if (limit > tidcnt) + /* just in case size changes in future */ + limit = tidcnt; + tid = find_first_bit((const unsigned long *)tidmap, limit); + for (; tid < limit; tid++) { + if (!test_bit(tid, tidmap)) + continue; + if (dd->pageshadow[ctxttid + tid]) { + dma_addr_t phys; + + phys = dd->physshadow[ctxttid + tid]; + dd->physshadow[ctxttid + tid] = dd->tidinvalid; + /* PERFORMANCE: below should almost certainly + * be cached + */ + dd->f_put_tid(dd, &tidbase[tid], + RCVHQ_RCV_TYPE_EXPECTED, + dd->tidinvalid); + pci_unmap_page(dd->pcidev, phys, PAGE_SIZE, + PCI_DMA_FROMDEVICE); + dd->pageshadow[ctxttid + tid] = NULL; + } + } + qib_release_user_pages(pagep, cnt); + } else { + /* + * Copy the updated array, with qib_tid's filled in, back + * to user. Since we did the copy in already, this "should + * never fail" If it does, we have to clean up... + */ + if (copy_to_user((void __user *) + (unsigned long) ti->tidlist, + tidlist, cnt * sizeof(*tidlist))) { + ret = -EFAULT; + goto cleanup; + } + if (copy_to_user((void __user *) (unsigned long) ti->tidmap, + tidmap, sizeof tidmap)) { + ret = -EFAULT; + goto cleanup; + } + if (tid == tidcnt) + tid = 0; + if (!rcd->subctxt_cnt) + rcd->tidcursor = tid; + else + tidcursor_fp(fp) = tid; + } + +done: + return ret; +} + +/** + * qib_tid_free - free a context TID + * @rcd: the context + * @subctxt: the subcontext + * @ti: the TID info + * + * right now we are unlocking one page at a time, but since + * the intended use of this routine is for a single group of + * virtually contiguous pages, that should change to improve + * performance. We check that the TID is in range for this context + * but otherwise don't check validity; if user has an error and + * frees the wrong tid, it's only their own data that can thereby + * be corrupted. We do check that the TID was in use, for sanity + * We always use our idea of the saved address, not the address that + * they pass in to us. + */ +static int qib_tid_free(struct qib_ctxtdata *rcd, unsigned subctxt, + const struct qib_tid_info *ti) +{ + int ret = 0; + u32 tid, ctxttid, cnt, limit, tidcnt; + struct qib_devdata *dd = rcd->dd; + u64 __iomem *tidbase; + unsigned long tidmap[8]; + + if (!dd->pageshadow) { + ret = -ENOMEM; + goto done; + } + + if (copy_from_user(tidmap, (void __user *)(unsigned long)ti->tidmap, + sizeof tidmap)) { + ret = -EFAULT; + goto done; + } + + ctxttid = rcd->ctxt * dd->rcvtidcnt; + if (!rcd->subctxt_cnt) + tidcnt = dd->rcvtidcnt; + else if (!subctxt) { + tidcnt = (dd->rcvtidcnt / rcd->subctxt_cnt) + + (dd->rcvtidcnt % rcd->subctxt_cnt); + ctxttid += dd->rcvtidcnt - tidcnt; + } else { + tidcnt = dd->rcvtidcnt / rcd->subctxt_cnt; + ctxttid += tidcnt * (subctxt - 1); + } + tidbase = (u64 __iomem *) ((char __iomem *)(dd->kregbase) + + dd->rcvtidbase + + ctxttid * sizeof(*tidbase)); + + limit = sizeof(tidmap) * BITS_PER_BYTE; + if (limit > tidcnt) + /* just in case size changes in future */ + limit = tidcnt; + tid = find_first_bit(tidmap, limit); + for (cnt = 0; tid < limit; tid++) { + /* + * small optimization; if we detect a run of 3 or so without + * any set, use find_first_bit again. That's mainly to + * accelerate the case where we wrapped, so we have some at + * the beginning, and some at the end, and a big gap + * in the middle. + */ + if (!test_bit(tid, tidmap)) + continue; + cnt++; + if (dd->pageshadow[ctxttid + tid]) { + struct page *p; + dma_addr_t phys; + + p = dd->pageshadow[ctxttid + tid]; + dd->pageshadow[ctxttid + tid] = NULL; + phys = dd->physshadow[ctxttid + tid]; + dd->physshadow[ctxttid + tid] = dd->tidinvalid; + /* PERFORMANCE: below should almost certainly be + * cached + */ + dd->f_put_tid(dd, &tidbase[tid], + RCVHQ_RCV_TYPE_EXPECTED, dd->tidinvalid); + pci_unmap_page(dd->pcidev, phys, PAGE_SIZE, + PCI_DMA_FROMDEVICE); + qib_release_user_pages(&p, 1); + } + } +done: + return ret; +} + +/** + * qib_set_part_key - set a partition key + * @rcd: the context + * @key: the key + * + * We can have up to 4 active at a time (other than the default, which is + * always allowed). This is somewhat tricky, since multiple contexts may set + * the same key, so we reference count them, and clean up at exit. All 4 + * partition keys are packed into a single qlogic_ib register. It's an + * error for a process to set the same pkey multiple times. We provide no + * mechanism to de-allocate a pkey at this time, we may eventually need to + * do that. I've used the atomic operations, and no locking, and only make + * a single pass through what's available. This should be more than + * adequate for some time. I'll think about spinlocks or the like if and as + * it's necessary. + */ +static int qib_set_part_key(struct qib_ctxtdata *rcd, u16 key) +{ + struct qib_pportdata *ppd = rcd->ppd; + int i, any = 0, pidx = -1; + u16 lkey = key & 0x7FFF; + int ret; + + if (lkey == (QIB_DEFAULT_P_KEY & 0x7FFF)) { + /* nothing to do; this key always valid */ + ret = 0; + goto bail; + } + + if (!lkey) { + ret = -EINVAL; + goto bail; + } + + /* + * Set the full membership bit, because it has to be + * set in the register or the packet, and it seems + * cleaner to set in the register than to force all + * callers to set it. + */ + key |= 0x8000; + + for (i = 0; i < ARRAY_SIZE(rcd->pkeys); i++) { + if (!rcd->pkeys[i] && pidx == -1) + pidx = i; + if (rcd->pkeys[i] == key) { + ret = -EEXIST; + goto bail; + } + } + if (pidx == -1) { + ret = -EBUSY; + goto bail; + } + for (any = i = 0; i < ARRAY_SIZE(ppd->pkeys); i++) { + if (!ppd->pkeys[i]) { + any++; + continue; + } + if (ppd->pkeys[i] == key) { + atomic_t *pkrefs = &ppd->pkeyrefs[i]; + + if (atomic_inc_return(pkrefs) > 1) { + rcd->pkeys[pidx] = key; + ret = 0; + goto bail; + } else { + /* + * lost race, decrement count, catch below + */ + atomic_dec(pkrefs); + any++; + } + } + if ((ppd->pkeys[i] & 0x7FFF) == lkey) { + /* + * It makes no sense to have both the limited and + * full membership PKEY set at the same time since + * the unlimited one will disable the limited one. + */ + ret = -EEXIST; + goto bail; + } + } + if (!any) { + ret = -EBUSY; + goto bail; + } + for (any = i = 0; i < ARRAY_SIZE(ppd->pkeys); i++) { + if (!ppd->pkeys[i] && + atomic_inc_return(&ppd->pkeyrefs[i]) == 1) { + rcd->pkeys[pidx] = key; + ppd->pkeys[i] = key; + (void) ppd->dd->f_set_ib_cfg(ppd, QIB_IB_CFG_PKEYS, 0); + ret = 0; + goto bail; + } + } + ret = -EBUSY; + +bail: + return ret; +} + +/** + * qib_manage_rcvq - manage a context's receive queue + * @rcd: the context + * @subctxt: the subcontext + * @start_stop: action to carry out + * + * start_stop == 0 disables receive on the context, for use in queue + * overflow conditions. start_stop==1 re-enables, to be used to + * re-init the software copy of the head register + */ +static int qib_manage_rcvq(struct qib_ctxtdata *rcd, unsigned subctxt, + int start_stop) +{ + struct qib_devdata *dd = rcd->dd; + unsigned int rcvctrl_op; + + if (subctxt) + goto bail; + /* atomically clear receive enable ctxt. */ + if (start_stop) { + /* + * On enable, force in-memory copy of the tail register to + * 0, so that protocol code doesn't have to worry about + * whether or not the chip has yet updated the in-memory + * copy or not on return from the system call. The chip + * always resets it's tail register back to 0 on a + * transition from disabled to enabled. + */ + if (rcd->rcvhdrtail_kvaddr) + qib_clear_rcvhdrtail(rcd); + rcvctrl_op = QIB_RCVCTRL_CTXT_ENB; + } else + rcvctrl_op = QIB_RCVCTRL_CTXT_DIS; + dd->f_rcvctrl(rcd->ppd, rcvctrl_op, rcd->ctxt); + /* always; new head should be equal to new tail; see above */ +bail: + return 0; +} + +static void qib_clean_part_key(struct qib_ctxtdata *rcd, + struct qib_devdata *dd) +{ + int i, j, pchanged = 0; + u64 oldpkey; + struct qib_pportdata *ppd = rcd->ppd; + + /* for debugging only */ + oldpkey = (u64) ppd->pkeys[0] | + ((u64) ppd->pkeys[1] << 16) | + ((u64) ppd->pkeys[2] << 32) | + ((u64) ppd->pkeys[3] << 48); + + for (i = 0; i < ARRAY_SIZE(rcd->pkeys); i++) { + if (!rcd->pkeys[i]) + continue; + for (j = 0; j < ARRAY_SIZE(ppd->pkeys); j++) { + /* check for match independent of the global bit */ + if ((ppd->pkeys[j] & 0x7fff) != + (rcd->pkeys[i] & 0x7fff)) + continue; + if (atomic_dec_and_test(&ppd->pkeyrefs[j])) { + ppd->pkeys[j] = 0; + pchanged++; + } + break; + } + rcd->pkeys[i] = 0; + } + if (pchanged) + (void) ppd->dd->f_set_ib_cfg(ppd, QIB_IB_CFG_PKEYS, 0); +} + +/* common code for the mappings on dma_alloc_coherent mem */ +static int qib_mmap_mem(struct vm_area_struct *vma, struct qib_ctxtdata *rcd, + unsigned len, void *kvaddr, u32 write_ok, char *what) +{ + struct qib_devdata *dd = rcd->dd; + unsigned long pfn; + int ret; + + if ((vma->vm_end - vma->vm_start) > len) { + qib_devinfo(dd->pcidev, + "FAIL on %s: len %lx > %x\n", what, + vma->vm_end - vma->vm_start, len); + ret = -EFAULT; + goto bail; + } + + /* + * shared context user code requires rcvhdrq mapped r/w, others + * only allowed readonly mapping. + */ + if (!write_ok) { + if (vma->vm_flags & VM_WRITE) { + qib_devinfo(dd->pcidev, + "%s must be mapped readonly\n", what); + ret = -EPERM; + goto bail; + } + + /* don't allow them to later change with mprotect */ + vma->vm_flags &= ~VM_MAYWRITE; + } + + pfn = virt_to_phys(kvaddr) >> PAGE_SHIFT; + ret = remap_pfn_range(vma, vma->vm_start, pfn, + len, vma->vm_page_prot); + if (ret) + qib_devinfo(dd->pcidev, "%s ctxt%u mmap of %lx, %x " + "bytes failed: %d\n", what, rcd->ctxt, + pfn, len, ret); +bail: + return ret; +} + +static int mmap_ureg(struct vm_area_struct *vma, struct qib_devdata *dd, + u64 ureg) +{ + unsigned long phys; + unsigned long sz; + int ret; + + /* + * This is real hardware, so use io_remap. This is the mechanism + * for the user process to update the head registers for their ctxt + * in the chip. + */ + sz = dd->flags & QIB_HAS_HDRSUPP ? 2 * PAGE_SIZE : PAGE_SIZE; + if ((vma->vm_end - vma->vm_start) > sz) { + qib_devinfo(dd->pcidev, "FAIL mmap userreg: reqlen " + "%lx > PAGE\n", vma->vm_end - vma->vm_start); + ret = -EFAULT; + } else { + phys = dd->physaddr + ureg; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND; + ret = io_remap_pfn_range(vma, vma->vm_start, + phys >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot); + } + return ret; +} + +static int mmap_piobufs(struct vm_area_struct *vma, + struct qib_devdata *dd, + struct qib_ctxtdata *rcd, + unsigned piobufs, unsigned piocnt) +{ + unsigned long phys; + int ret; + + /* + * When we map the PIO buffers in the chip, we want to map them as + * writeonly, no read possible; unfortunately, x86 doesn't allow + * for this in hardware, but we still prevent users from asking + * for it. + */ + if ((vma->vm_end - vma->vm_start) > (piocnt * dd->palign)) { + qib_devinfo(dd->pcidev, "FAIL mmap piobufs: " + "reqlen %lx > PAGE\n", + vma->vm_end - vma->vm_start); + ret = -EINVAL; + goto bail; + } + + phys = dd->physaddr + piobufs; + +#if defined(__powerpc__) + /* There isn't a generic way to specify writethrough mappings */ + pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; + pgprot_val(vma->vm_page_prot) |= _PAGE_WRITETHRU; + pgprot_val(vma->vm_page_prot) &= ~_PAGE_GUARDED; +#endif + + /* + * don't allow them to later change to readable with mprotect (for when + * not initially mapped readable, as is normally the case) + */ + vma->vm_flags &= ~VM_MAYREAD; + vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND; + + if (qib_wc_pat) + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + + ret = io_remap_pfn_range(vma, vma->vm_start, phys >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot); +bail: + return ret; +} + +static int mmap_rcvegrbufs(struct vm_area_struct *vma, + struct qib_ctxtdata *rcd) +{ + struct qib_devdata *dd = rcd->dd; + unsigned long start, size; + size_t total_size, i; + unsigned long pfn; + int ret; + + size = rcd->rcvegrbuf_size; + total_size = rcd->rcvegrbuf_chunks * size; + if ((vma->vm_end - vma->vm_start) > total_size) { + qib_devinfo(dd->pcidev, "FAIL on egr bufs: " + "reqlen %lx > actual %lx\n", + vma->vm_end - vma->vm_start, + (unsigned long) total_size); + ret = -EINVAL; + goto bail; + } + + if (vma->vm_flags & VM_WRITE) { + qib_devinfo(dd->pcidev, "Can't map eager buffers as " + "writable (flags=%lx)\n", vma->vm_flags); + ret = -EPERM; + goto bail; + } + /* don't allow them to later change to writeable with mprotect */ + vma->vm_flags &= ~VM_MAYWRITE; + + start = vma->vm_start; + + for (i = 0; i < rcd->rcvegrbuf_chunks; i++, start += size) { + pfn = virt_to_phys(rcd->rcvegrbuf[i]) >> PAGE_SHIFT; + ret = remap_pfn_range(vma, start, pfn, size, + vma->vm_page_prot); + if (ret < 0) + goto bail; + } + ret = 0; + +bail: + return ret; +} + +/* + * qib_file_vma_fault - handle a VMA page fault. + */ +static int qib_file_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + struct page *page; + + page = vmalloc_to_page((void *)(vmf->pgoff << PAGE_SHIFT)); + if (!page) + return VM_FAULT_SIGBUS; + + get_page(page); + vmf->page = page; + + return 0; +} + +static struct vm_operations_struct qib_file_vm_ops = { + .fault = qib_file_vma_fault, +}; + +static int mmap_kvaddr(struct vm_area_struct *vma, u64 pgaddr, + struct qib_ctxtdata *rcd, unsigned subctxt) +{ + struct qib_devdata *dd = rcd->dd; + unsigned subctxt_cnt; + unsigned long len; + void *addr; + size_t size; + int ret = 0; + + subctxt_cnt = rcd->subctxt_cnt; + size = rcd->rcvegrbuf_chunks * rcd->rcvegrbuf_size; + + /* + * Each process has all the subctxt uregbase, rcvhdrq, and + * rcvegrbufs mmapped - as an array for all the processes, + * and also separately for this process. + */ + if (pgaddr == cvt_kvaddr(rcd->subctxt_uregbase)) { + addr = rcd->subctxt_uregbase; + size = PAGE_SIZE * subctxt_cnt; + } else if (pgaddr == cvt_kvaddr(rcd->subctxt_rcvhdr_base)) { + addr = rcd->subctxt_rcvhdr_base; + size = rcd->rcvhdrq_size * subctxt_cnt; + } else if (pgaddr == cvt_kvaddr(rcd->subctxt_rcvegrbuf)) { + addr = rcd->subctxt_rcvegrbuf; + size *= subctxt_cnt; + } else if (pgaddr == cvt_kvaddr(rcd->subctxt_uregbase + + PAGE_SIZE * subctxt)) { + addr = rcd->subctxt_uregbase + PAGE_SIZE * subctxt; + size = PAGE_SIZE; + } else if (pgaddr == cvt_kvaddr(rcd->subctxt_rcvhdr_base + + rcd->rcvhdrq_size * subctxt)) { + addr = rcd->subctxt_rcvhdr_base + + rcd->rcvhdrq_size * subctxt; + size = rcd->rcvhdrq_size; + } else if (pgaddr == cvt_kvaddr(&rcd->user_event_mask[subctxt])) { + addr = rcd->user_event_mask; + size = PAGE_SIZE; + } else if (pgaddr == cvt_kvaddr(rcd->subctxt_rcvegrbuf + + size * subctxt)) { + addr = rcd->subctxt_rcvegrbuf + size * subctxt; + /* rcvegrbufs are read-only on the slave */ + if (vma->vm_flags & VM_WRITE) { + qib_devinfo(dd->pcidev, + "Can't map eager buffers as " + "writable (flags=%lx)\n", vma->vm_flags); + ret = -EPERM; + goto bail; + } + /* + * Don't allow permission to later change to writeable + * with mprotect. + */ + vma->vm_flags &= ~VM_MAYWRITE; + } else + goto bail; + len = vma->vm_end - vma->vm_start; + if (len > size) { + ret = -EINVAL; + goto bail; + } + + vma->vm_pgoff = (unsigned long) addr >> PAGE_SHIFT; + vma->vm_ops = &qib_file_vm_ops; + vma->vm_flags |= VM_RESERVED | VM_DONTEXPAND; + ret = 1; + +bail: + return ret; +} + +/** + * qib_mmapf - mmap various structures into user space + * @fp: the file pointer + * @vma: the VM area + * + * We use this to have a shared buffer between the kernel and the user code + * for the rcvhdr queue, egr buffers, and the per-context user regs and pio + * buffers in the chip. We have the open and close entries so we can bump + * the ref count and keep the driver from being unloaded while still mapped. + */ +static int qib_mmapf(struct file *fp, struct vm_area_struct *vma) +{ + struct qib_ctxtdata *rcd; + struct qib_devdata *dd; + u64 pgaddr, ureg; + unsigned piobufs, piocnt; + int ret, match = 1; + + rcd = ctxt_fp(fp); + if (!rcd || !(vma->vm_flags & VM_SHARED)) { + ret = -EINVAL; + goto bail; + } + dd = rcd->dd; + + /* + * This is the qib_do_user_init() code, mapping the shared buffers + * and per-context user registers into the user process. The address + * referred to by vm_pgoff is the file offset passed via mmap(). + * For shared contexts, this is the kernel vmalloc() address of the + * pages to share with the master. + * For non-shared or master ctxts, this is a physical address. + * We only do one mmap for each space mapped. + */ + pgaddr = vma->vm_pgoff << PAGE_SHIFT; + + /* + * Check for 0 in case one of the allocations failed, but user + * called mmap anyway. + */ + if (!pgaddr) { + ret = -EINVAL; + goto bail; + } + + /* + * Physical addresses must fit in 40 bits for our hardware. + * Check for kernel virtual addresses first, anything else must + * match a HW or memory address. + */ + ret = mmap_kvaddr(vma, pgaddr, rcd, subctxt_fp(fp)); + if (ret) { + if (ret > 0) + ret = 0; + goto bail; + } + + ureg = dd->uregbase + dd->ureg_align * rcd->ctxt; + if (!rcd->subctxt_cnt) { + /* ctxt is not shared */ + piocnt = rcd->piocnt; + piobufs = rcd->piobufs; + } else if (!subctxt_fp(fp)) { + /* caller is the master */ + piocnt = (rcd->piocnt / rcd->subctxt_cnt) + + (rcd->piocnt % rcd->subctxt_cnt); + piobufs = rcd->piobufs + + dd->palign * (rcd->piocnt - piocnt); + } else { + unsigned slave = subctxt_fp(fp) - 1; + + /* caller is a slave */ + piocnt = rcd->piocnt / rcd->subctxt_cnt; + piobufs = rcd->piobufs + dd->palign * piocnt * slave; + } + + if (pgaddr == ureg) + ret = mmap_ureg(vma, dd, ureg); + else if (pgaddr == piobufs) + ret = mmap_piobufs(vma, dd, rcd, piobufs, piocnt); + else if (pgaddr == dd->pioavailregs_phys) + /* in-memory copy of pioavail registers */ + ret = qib_mmap_mem(vma, rcd, PAGE_SIZE, + (void *) dd->pioavailregs_dma, 0, + "pioavail registers"); + else if (pgaddr == rcd->rcvegr_phys) + ret = mmap_rcvegrbufs(vma, rcd); + else if (pgaddr == (u64) rcd->rcvhdrq_phys) + /* + * The rcvhdrq itself; multiple pages, contiguous + * from an i/o perspective. Shared contexts need + * to map r/w, so we allow writing. + */ + ret = qib_mmap_mem(vma, rcd, rcd->rcvhdrq_size, + rcd->rcvhdrq, 1, "rcvhdrq"); + else if (pgaddr == (u64) rcd->rcvhdrqtailaddr_phys) + /* in-memory copy of rcvhdrq tail register */ + ret = qib_mmap_mem(vma, rcd, PAGE_SIZE, + rcd->rcvhdrtail_kvaddr, 0, + "rcvhdrq tail"); + else + match = 0; + if (!match) + ret = -EINVAL; + + vma->vm_private_data = NULL; + + if (ret < 0) + qib_devinfo(dd->pcidev, + "mmap Failure %d: off %llx len %lx\n", + -ret, (unsigned long long)pgaddr, + vma->vm_end - vma->vm_start); +bail: + return ret; +} + +static unsigned int qib_poll_urgent(struct qib_ctxtdata *rcd, + struct file *fp, + struct poll_table_struct *pt) +{ + struct qib_devdata *dd = rcd->dd; + unsigned pollflag; + + poll_wait(fp, &rcd->wait, pt); + + spin_lock_irq(&dd->uctxt_lock); + if (rcd->urgent != rcd->urgent_poll) { + pollflag = POLLIN | POLLRDNORM; + rcd->urgent_poll = rcd->urgent; + } else { + pollflag = 0; + set_bit(QIB_CTXT_WAITING_URG, &rcd->flag); + } + spin_unlock_irq(&dd->uctxt_lock); + + return pollflag; +} + +static unsigned int qib_poll_next(struct qib_ctxtdata *rcd, + struct file *fp, + struct poll_table_struct *pt) +{ + struct qib_devdata *dd = rcd->dd; + unsigned pollflag; + + poll_wait(fp, &rcd->wait, pt); + + spin_lock_irq(&dd->uctxt_lock); + if (dd->f_hdrqempty(rcd)) { + set_bit(QIB_CTXT_WAITING_RCV, &rcd->flag); + dd->f_rcvctrl(rcd->ppd, QIB_RCVCTRL_INTRAVAIL_ENB, rcd->ctxt); + pollflag = 0; + } else + pollflag = POLLIN | POLLRDNORM; + spin_unlock_irq(&dd->uctxt_lock); + + return pollflag; +} + +static unsigned int qib_poll(struct file *fp, struct poll_table_struct *pt) +{ + struct qib_ctxtdata *rcd; + unsigned pollflag; + + rcd = ctxt_fp(fp); + if (!rcd) + pollflag = POLLERR; + else if (rcd->poll_type == QIB_POLL_TYPE_URGENT) + pollflag = qib_poll_urgent(rcd, fp, pt); + else if (rcd->poll_type == QIB_POLL_TYPE_ANYRCV) + pollflag = qib_poll_next(rcd, fp, pt); + else /* invalid */ + pollflag = POLLERR; + + return pollflag; +} + +/* + * Check that userland and driver are compatible for subcontexts. + */ +static int qib_compatible_subctxts(int user_swmajor, int user_swminor) +{ + /* this code is written long-hand for clarity */ + if (QIB_USER_SWMAJOR != user_swmajor) { + /* no promise of compatibility if major mismatch */ + return 0; + } + if (QIB_USER_SWMAJOR == 1) { + switch (QIB_USER_SWMINOR) { + case 0: + case 1: + case 2: + /* no subctxt implementation so cannot be compatible */ + return 0; + case 3: + /* 3 is only compatible with itself */ + return user_swminor == 3; + default: + /* >= 4 are compatible (or are expected to be) */ + return user_swminor >= 4; + } + } + /* make no promises yet for future major versions */ + return 0; +} + +static int init_subctxts(struct qib_devdata *dd, + struct qib_ctxtdata *rcd, + const struct qib_user_info *uinfo) +{ + int ret = 0; + unsigned num_subctxts; + size_t size; + + /* + * If the user is requesting zero subctxts, + * skip the subctxt allocation. + */ + if (uinfo->spu_subctxt_cnt <= 0) + goto bail; + num_subctxts = uinfo->spu_subctxt_cnt; + + /* Check for subctxt compatibility */ + if (!qib_compatible_subctxts(uinfo->spu_userversion >> 16, + uinfo->spu_userversion & 0xffff)) { + qib_devinfo(dd->pcidev, + "Mismatched user version (%d.%d) and driver " + "version (%d.%d) while context sharing. Ensure " + "that driver and library are from the same " + "release.\n", + (int) (uinfo->spu_userversion >> 16), + (int) (uinfo->spu_userversion & 0xffff), + QIB_USER_SWMAJOR, QIB_USER_SWMINOR); + goto bail; + } + if (num_subctxts > QLOGIC_IB_MAX_SUBCTXT) { + ret = -EINVAL; + goto bail; + } + + rcd->subctxt_uregbase = vmalloc_user(PAGE_SIZE * num_subctxts); + if (!rcd->subctxt_uregbase) { + ret = -ENOMEM; + goto bail; + } + /* Note: rcd->rcvhdrq_size isn't initialized yet. */ + size = ALIGN(dd->rcvhdrcnt * dd->rcvhdrentsize * + sizeof(u32), PAGE_SIZE) * num_subctxts; + rcd->subctxt_rcvhdr_base = vmalloc_user(size); + if (!rcd->subctxt_rcvhdr_base) { + ret = -ENOMEM; + goto bail_ureg; + } + + rcd->subctxt_rcvegrbuf = vmalloc_user(rcd->rcvegrbuf_chunks * + rcd->rcvegrbuf_size * + num_subctxts); + if (!rcd->subctxt_rcvegrbuf) { + ret = -ENOMEM; + goto bail_rhdr; + } + + rcd->subctxt_cnt = uinfo->spu_subctxt_cnt; + rcd->subctxt_id = uinfo->spu_subctxt_id; + rcd->active_slaves = 1; + rcd->redirect_seq_cnt = 1; + set_bit(QIB_CTXT_MASTER_UNINIT, &rcd->flag); + goto bail; + +bail_rhdr: + vfree(rcd->subctxt_rcvhdr_base); +bail_ureg: + vfree(rcd->subctxt_uregbase); + rcd->subctxt_uregbase = NULL; +bail: + return ret; +} + +static int setup_ctxt(struct qib_pportdata *ppd, int ctxt, + struct file *fp, const struct qib_user_info *uinfo) +{ + struct qib_devdata *dd = ppd->dd; + struct qib_ctxtdata *rcd; + void *ptmp = NULL; + int ret; + + rcd = qib_create_ctxtdata(ppd, ctxt); + + /* + * Allocate memory for use in qib_tid_update() at open to + * reduce cost of expected send setup per message segment + */ + if (rcd) + ptmp = kmalloc(dd->rcvtidcnt * sizeof(u16) + + dd->rcvtidcnt * sizeof(struct page **), + GFP_KERNEL); + + if (!rcd || !ptmp) { + qib_dev_err(dd, "Unable to allocate ctxtdata " + "memory, failing open\n"); + ret = -ENOMEM; + goto bailerr; + } + rcd->userversion = uinfo->spu_userversion; + ret = init_subctxts(dd, rcd, uinfo); + if (ret) + goto bailerr; + rcd->tid_pg_list = ptmp; + rcd->pid = current->pid; + init_waitqueue_head(&dd->rcd[ctxt]->wait); + strlcpy(rcd->comm, current->comm, sizeof(rcd->comm)); + ctxt_fp(fp) = rcd; + qib_stats.sps_ctxts++; + ret = 0; + goto bail; + +bailerr: + dd->rcd[ctxt] = NULL; + kfree(rcd); + kfree(ptmp); +bail: + return ret; +} + +static inline int usable(struct qib_pportdata *ppd, int active_only) +{ + struct qib_devdata *dd = ppd->dd; + u32 linkok = active_only ? QIBL_LINKACTIVE : + (QIBL_LINKINIT | QIBL_LINKARMED | QIBL_LINKACTIVE); + + return dd && (dd->flags & QIB_PRESENT) && dd->kregbase && ppd->lid && + (ppd->lflags & linkok); +} + +static int find_free_ctxt(int unit, struct file *fp, + const struct qib_user_info *uinfo) +{ + struct qib_devdata *dd = qib_lookup(unit); + struct qib_pportdata *ppd = NULL; + int ret; + u32 ctxt; + + if (!dd || (uinfo->spu_port && uinfo->spu_port > dd->num_pports)) { + ret = -ENODEV; + goto bail; + } + + /* + * If users requests specific port, only try that one port, else + * select "best" port below, based on context. + */ + if (uinfo->spu_port) { + ppd = dd->pport + uinfo->spu_port - 1; + if (!usable(ppd, 0)) { + ret = -ENETDOWN; + goto bail; + } + } + + for (ctxt = dd->first_user_ctxt; ctxt < dd->cfgctxts; ctxt++) { + if (dd->rcd[ctxt]) + continue; + /* + * The setting and clearing of user context rcd[x] protected + * by the qib_mutex + */ + if (!ppd) { + /* choose port based on ctxt, if up, else 1st up */ + ppd = dd->pport + (ctxt % dd->num_pports); + if (!usable(ppd, 0)) { + int i; + for (i = 0; i < dd->num_pports; i++) { + ppd = dd->pport + i; + if (usable(ppd, 0)) + break; + } + if (i == dd->num_pports) { + ret = -ENETDOWN; + goto bail; + } + } + } + ret = setup_ctxt(ppd, ctxt, fp, uinfo); + goto bail; + } + ret = -EBUSY; + +bail: + return ret; +} + +static int get_a_ctxt(struct file *fp, const struct qib_user_info *uinfo) +{ + struct qib_pportdata *ppd; + int ret = 0, devmax; + int npresent, nup; + int ndev; + u32 port = uinfo->spu_port, ctxt; + + devmax = qib_count_units(&npresent, &nup); + + for (ndev = 0; ndev < devmax; ndev++) { + struct qib_devdata *dd = qib_lookup(ndev); + + /* device portion of usable() */ + if (!(dd && (dd->flags & QIB_PRESENT) && dd->kregbase)) + continue; + for (ctxt = dd->first_user_ctxt; ctxt < dd->cfgctxts; ctxt++) { + if (dd->rcd[ctxt]) + continue; + if (port) { + if (port > dd->num_pports) + continue; + ppd = dd->pport + port - 1; + if (!usable(ppd, 0)) + continue; + } else { + /* + * choose port based on ctxt, if up, else + * first port that's up for multi-port HCA + */ + ppd = dd->pport + (ctxt % dd->num_pports); + if (!usable(ppd, 0)) { + int j; + + ppd = NULL; + for (j = 0; j < dd->num_pports && + !ppd; j++) + if (usable(dd->pport + j, 0)) + ppd = dd->pport + j; + if (!ppd) + continue; /* to next unit */ + } + } + ret = setup_ctxt(ppd, ctxt, fp, uinfo); + goto done; + } + } + + if (npresent) { + if (nup == 0) + ret = -ENETDOWN; + else + ret = -EBUSY; + } else + ret = -ENXIO; + +done: + return ret; +} + +static int find_shared_ctxt(struct file *fp, + const struct qib_user_info *uinfo) +{ + int devmax, ndev, i; + int ret = 0; + + devmax = qib_count_units(NULL, NULL); + + for (ndev = 0; ndev < devmax; ndev++) { + struct qib_devdata *dd = qib_lookup(ndev); + + /* device portion of usable() */ + if (!(dd && (dd->flags & QIB_PRESENT) && dd->kregbase)) + continue; + for (i = dd->first_user_ctxt; i < dd->cfgctxts; i++) { + struct qib_ctxtdata *rcd = dd->rcd[i]; + + /* Skip ctxts which are not yet open */ + if (!rcd || !rcd->cnt) + continue; + /* Skip ctxt if it doesn't match the requested one */ + if (rcd->subctxt_id != uinfo->spu_subctxt_id) + continue; + /* Verify the sharing process matches the master */ + if (rcd->subctxt_cnt != uinfo->spu_subctxt_cnt || + rcd->userversion != uinfo->spu_userversion || + rcd->cnt >= rcd->subctxt_cnt) { + ret = -EINVAL; + goto done; + } + ctxt_fp(fp) = rcd; + subctxt_fp(fp) = rcd->cnt++; + rcd->subpid[subctxt_fp(fp)] = current->pid; + tidcursor_fp(fp) = 0; + rcd->active_slaves |= 1 << subctxt_fp(fp); + ret = 1; + goto done; + } + } + +done: + return ret; +} + +static int qib_open(struct inode *in, struct file *fp) +{ + /* The real work is performed later in qib_assign_ctxt() */ + fp->private_data = kzalloc(sizeof(struct qib_filedata), GFP_KERNEL); + if (fp->private_data) /* no cpu affinity by default */ + ((struct qib_filedata *)fp->private_data)->rec_cpu_num = -1; + return fp->private_data ? 0 : -ENOMEM; +} + +/* + * Get ctxt early, so can set affinity prior to memory allocation. + */ +static int qib_assign_ctxt(struct file *fp, const struct qib_user_info *uinfo) +{ + int ret; + int i_minor; + unsigned swmajor, swminor; + + /* Check to be sure we haven't already initialized this file */ + if (ctxt_fp(fp)) { + ret = -EINVAL; + goto done; + } + + /* for now, if major version is different, bail */ + swmajor = uinfo->spu_userversion >> 16; + if (swmajor != QIB_USER_SWMAJOR) { + ret = -ENODEV; + goto done; + } + + swminor = uinfo->spu_userversion & 0xffff; + + mutex_lock(&qib_mutex); + + if (qib_compatible_subctxts(swmajor, swminor) && + uinfo->spu_subctxt_cnt) { + ret = find_shared_ctxt(fp, uinfo); + if (ret) { + if (ret > 0) + ret = 0; + goto done_chk_sdma; + } + } + + i_minor = iminor(fp->f_dentry->d_inode) - QIB_USER_MINOR_BASE; + if (i_minor) + ret = find_free_ctxt(i_minor - 1, fp, uinfo); + else + ret = get_a_ctxt(fp, uinfo); + +done_chk_sdma: + if (!ret) { + struct qib_filedata *fd = fp->private_data; + const struct qib_ctxtdata *rcd = fd->rcd; + const struct qib_devdata *dd = rcd->dd; + + if (dd->flags & QIB_HAS_SEND_DMA) { + fd->pq = qib_user_sdma_queue_create(&dd->pcidev->dev, + dd->unit, + rcd->ctxt, + fd->subctxt); + if (!fd->pq) + ret = -ENOMEM; + } + + /* + * If process has NOT already set it's affinity, select and + * reserve a processor for it, as a rendevous for all + * users of the driver. If they don't actually later + * set affinity to this cpu, or set it to some other cpu, + * it just means that sooner or later we don't recommend + * a cpu, and let the scheduler do it's best. + */ + if (!ret && cpus_weight(current->cpus_allowed) >= + qib_cpulist_count) { + int cpu; + cpu = find_first_zero_bit(qib_cpulist, + qib_cpulist_count); + if (cpu != qib_cpulist_count) { + __set_bit(cpu, qib_cpulist); + fd->rec_cpu_num = cpu; + } + } else if (cpus_weight(current->cpus_allowed) == 1 && + test_bit(first_cpu(current->cpus_allowed), + qib_cpulist)) + qib_devinfo(dd->pcidev, "%s PID %u affinity " + "set to cpu %d; already allocated\n", + current->comm, current->pid, + first_cpu(current->cpus_allowed)); + } + + mutex_unlock(&qib_mutex); + +done: + return ret; +} + + +static int qib_do_user_init(struct file *fp, + const struct qib_user_info *uinfo) +{ + int ret; + struct qib_ctxtdata *rcd = ctxt_fp(fp); + struct qib_devdata *dd; + unsigned uctxt; + + /* Subctxts don't need to initialize anything since master did it. */ + if (subctxt_fp(fp)) { + ret = wait_event_interruptible(rcd->wait, + !test_bit(QIB_CTXT_MASTER_UNINIT, &rcd->flag)); + goto bail; + } + + dd = rcd->dd; + + /* some ctxts may get extra buffers, calculate that here */ + uctxt = rcd->ctxt - dd->first_user_ctxt; + if (uctxt < dd->ctxts_extrabuf) { + rcd->piocnt = dd->pbufsctxt + 1; + rcd->pio_base = rcd->piocnt * uctxt; + } else { + rcd->piocnt = dd->pbufsctxt; + rcd->pio_base = rcd->piocnt * uctxt + + dd->ctxts_extrabuf; + } + + /* + * All user buffers are 2KB buffers. If we ever support + * giving 4KB buffers to user processes, this will need some + * work. Can't use piobufbase directly, because it has + * both 2K and 4K buffer base values. So check and handle. + */ + if ((rcd->pio_base + rcd->piocnt) > dd->piobcnt2k) { + if (rcd->pio_base >= dd->piobcnt2k) { + qib_dev_err(dd, + "%u:ctxt%u: no 2KB buffers available\n", + dd->unit, rcd->ctxt); + ret = -ENOBUFS; + goto bail; + } + rcd->piocnt = dd->piobcnt2k - rcd->pio_base; + qib_dev_err(dd, "Ctxt%u: would use 4KB bufs, using %u\n", + rcd->ctxt, rcd->piocnt); + } + + rcd->piobufs = dd->pio2k_bufbase + rcd->pio_base * dd->palign; + qib_chg_pioavailkernel(dd, rcd->pio_base, rcd->piocnt, + TXCHK_CHG_TYPE_USER, rcd); + /* + * try to ensure that processes start up with consistent avail update + * for their own range, at least. If system very quiet, it might + * have the in-memory copy out of date at startup for this range of + * buffers, when a context gets re-used. Do after the chg_pioavail + * and before the rest of setup, so it's "almost certain" the dma + * will have occurred (can't 100% guarantee, but should be many + * decimals of 9s, with this ordering), given how much else happens + * after this. + */ + dd->f_sendctrl(dd->pport, QIB_SENDCTRL_AVAIL_BLIP); + + /* + * Now allocate the rcvhdr Q and eager TIDs; skip the TID + * array for time being. If rcd->ctxt > chip-supported, + * we need to do extra stuff here to handle by handling overflow + * through ctxt 0, someday + */ + ret = qib_create_rcvhdrq(dd, rcd); + if (!ret) + ret = qib_setup_eagerbufs(rcd); + if (ret) + goto bail_pio; + + rcd->tidcursor = 0; /* start at beginning after open */ + + /* initialize poll variables... */ + rcd->urgent = 0; + rcd->urgent_poll = 0; + + /* + * Now enable the ctxt for receive. + * For chips that are set to DMA the tail register to memory + * when they change (and when the update bit transitions from + * 0 to 1. So for those chips, we turn it off and then back on. + * This will (very briefly) affect any other open ctxts, but the + * duration is very short, and therefore isn't an issue. We + * explictly set the in-memory tail copy to 0 beforehand, so we + * don't have to wait to be sure the DMA update has happened + * (chip resets head/tail to 0 on transition to enable). + */ + if (rcd->rcvhdrtail_kvaddr) + qib_clear_rcvhdrtail(rcd); + + dd->f_rcvctrl(rcd->ppd, QIB_RCVCTRL_CTXT_ENB | QIB_RCVCTRL_TIDFLOW_ENB, + rcd->ctxt); + + /* Notify any waiting slaves */ + if (rcd->subctxt_cnt) { + clear_bit(QIB_CTXT_MASTER_UNINIT, &rcd->flag); + wake_up(&rcd->wait); + } + return 0; + +bail_pio: + qib_chg_pioavailkernel(dd, rcd->pio_base, rcd->piocnt, + TXCHK_CHG_TYPE_KERN, rcd); +bail: + return ret; +} + +/** + * unlock_exptid - unlock any expected TID entries context still had in use + * @rcd: ctxt + * + * We don't actually update the chip here, because we do a bulk update + * below, using f_clear_tids. + */ +static void unlock_expected_tids(struct qib_ctxtdata *rcd) +{ + struct qib_devdata *dd = rcd->dd; + int ctxt_tidbase = rcd->ctxt * dd->rcvtidcnt; + int i, cnt = 0, maxtid = ctxt_tidbase + dd->rcvtidcnt; + + for (i = ctxt_tidbase; i < maxtid; i++) { + struct page *p = dd->pageshadow[i]; + dma_addr_t phys; + + if (!p) + continue; + + phys = dd->physshadow[i]; + dd->physshadow[i] = dd->tidinvalid; + dd->pageshadow[i] = NULL; + pci_unmap_page(dd->pcidev, phys, PAGE_SIZE, + PCI_DMA_FROMDEVICE); + qib_release_user_pages(&p, 1); + cnt++; + } +} + +static int qib_close(struct inode *in, struct file *fp) +{ + int ret = 0; + struct qib_filedata *fd; + struct qib_ctxtdata *rcd; + struct qib_devdata *dd; + unsigned long flags; + unsigned ctxt; + pid_t pid; + + mutex_lock(&qib_mutex); + + fd = (struct qib_filedata *) fp->private_data; + fp->private_data = NULL; + rcd = fd->rcd; + if (!rcd) { + mutex_unlock(&qib_mutex); + goto bail; + } + + dd = rcd->dd; + + /* ensure all pio buffer writes in progress are flushed */ + qib_flush_wc(); + + /* drain user sdma queue */ + if (fd->pq) { + qib_user_sdma_queue_drain(rcd->ppd, fd->pq); + qib_user_sdma_queue_destroy(fd->pq); + } + + if (fd->rec_cpu_num != -1) + __clear_bit(fd->rec_cpu_num, qib_cpulist); + + if (--rcd->cnt) { + /* + * XXX If the master closes the context before the slave(s), + * revoke the mmap for the eager receive queue so + * the slave(s) don't wait for receive data forever. + */ + rcd->active_slaves &= ~(1 << fd->subctxt); + rcd->subpid[fd->subctxt] = 0; + mutex_unlock(&qib_mutex); + goto bail; + } + + /* early; no interrupt users after this */ + spin_lock_irqsave(&dd->uctxt_lock, flags); + ctxt = rcd->ctxt; + dd->rcd[ctxt] = NULL; + pid = rcd->pid; + rcd->pid = 0; + spin_unlock_irqrestore(&dd->uctxt_lock, flags); + + if (rcd->rcvwait_to || rcd->piowait_to || + rcd->rcvnowait || rcd->pionowait) { + rcd->rcvwait_to = 0; + rcd->piowait_to = 0; + rcd->rcvnowait = 0; + rcd->pionowait = 0; + } + if (rcd->flag) + rcd->flag = 0; + + if (dd->kregbase) { + /* atomically clear receive enable ctxt and intr avail. */ + dd->f_rcvctrl(rcd->ppd, QIB_RCVCTRL_CTXT_DIS | + QIB_RCVCTRL_INTRAVAIL_DIS, ctxt); + + /* clean up the pkeys for this ctxt user */ + qib_clean_part_key(rcd, dd); + qib_disarm_piobufs(dd, rcd->pio_base, rcd->piocnt); + qib_chg_pioavailkernel(dd, rcd->pio_base, + rcd->piocnt, TXCHK_CHG_TYPE_KERN, NULL); + + dd->f_clear_tids(dd, rcd); + + if (dd->pageshadow) + unlock_expected_tids(rcd); + qib_stats.sps_ctxts--; + } + + mutex_unlock(&qib_mutex); + qib_free_ctxtdata(dd, rcd); /* after releasing the mutex */ + +bail: + kfree(fd); + return ret; +} + +static int qib_ctxt_info(struct file *fp, struct qib_ctxt_info __user *uinfo) +{ + struct qib_ctxt_info info; + int ret; + size_t sz; + struct qib_ctxtdata *rcd = ctxt_fp(fp); + struct qib_filedata *fd; + + fd = (struct qib_filedata *) fp->private_data; + + info.num_active = qib_count_active_units(); + info.unit = rcd->dd->unit; + info.port = rcd->ppd->port; + info.ctxt = rcd->ctxt; + info.subctxt = subctxt_fp(fp); + /* Number of user ctxts available for this device. */ + info.num_ctxts = rcd->dd->cfgctxts - rcd->dd->first_user_ctxt; + info.num_subctxts = rcd->subctxt_cnt; + info.rec_cpu = fd->rec_cpu_num; + sz = sizeof(info); + + if (copy_to_user(uinfo, &info, sz)) { + ret = -EFAULT; + goto bail; + } + ret = 0; + +bail: + return ret; +} + +static int qib_sdma_get_inflight(struct qib_user_sdma_queue *pq, + u32 __user *inflightp) +{ + const u32 val = qib_user_sdma_inflight_counter(pq); + + if (put_user(val, inflightp)) + return -EFAULT; + + return 0; +} + +static int qib_sdma_get_complete(struct qib_pportdata *ppd, + struct qib_user_sdma_queue *pq, + u32 __user *completep) +{ + u32 val; + int err; + + if (!pq) + return -EINVAL; + + err = qib_user_sdma_make_progress(ppd, pq); + if (err < 0) + return err; + + val = qib_user_sdma_complete_counter(pq); + if (put_user(val, completep)) + return -EFAULT; + + return 0; +} + +static int disarm_req_delay(struct qib_ctxtdata *rcd) +{ + int ret = 0; + + if (!usable(rcd->ppd, 1)) { + int i; + /* + * if link is down, or otherwise not usable, delay + * the caller up to 30 seconds, so we don't thrash + * in trying to get the chip back to ACTIVE, and + * set flag so they make the call again. + */ + if (rcd->user_event_mask) { + /* + * subctxt_cnt is 0 if not shared, so do base + * separately, first, then remaining subctxt, if any + */ + set_bit(_QIB_EVENT_DISARM_BUFS_BIT, + &rcd->user_event_mask[0]); + for (i = 1; i < rcd->subctxt_cnt; i++) + set_bit(_QIB_EVENT_DISARM_BUFS_BIT, + &rcd->user_event_mask[i]); + } + for (i = 0; !usable(rcd->ppd, 1) && i < 300; i++) + msleep(100); + ret = -ENETDOWN; + } + return ret; +} + +/* + * Find all user contexts in use, and set the specified bit in their + * event mask. + * See also find_ctxt() for a similar use, that is specific to send buffers. + */ +int qib_set_uevent_bits(struct qib_pportdata *ppd, const int evtbit) +{ + struct qib_ctxtdata *rcd; + unsigned ctxt; + int ret = 0; + + spin_lock(&ppd->dd->uctxt_lock); + for (ctxt = ppd->dd->first_user_ctxt; ctxt < ppd->dd->cfgctxts; + ctxt++) { + rcd = ppd->dd->rcd[ctxt]; + if (!rcd) + continue; + if (rcd->user_event_mask) { + int i; + /* + * subctxt_cnt is 0 if not shared, so do base + * separately, first, then remaining subctxt, if any + */ + set_bit(evtbit, &rcd->user_event_mask[0]); + for (i = 1; i < rcd->subctxt_cnt; i++) + set_bit(evtbit, &rcd->user_event_mask[i]); + } + ret = 1; + break; + } + spin_unlock(&ppd->dd->uctxt_lock); + + return ret; +} + +/* + * clear the event notifier events for this context. + * For the DISARM_BUFS case, we also take action (this obsoletes + * the older QIB_CMD_DISARM_BUFS, but we keep it for backwards + * compatibility. + * Other bits don't currently require actions, just atomically clear. + * User process then performs actions appropriate to bit having been + * set, if desired, and checks again in future. + */ +static int qib_user_event_ack(struct qib_ctxtdata *rcd, int subctxt, + unsigned long events) +{ + int ret = 0, i; + + for (i = 0; i <= _QIB_MAX_EVENT_BIT; i++) { + if (!test_bit(i, &events)) + continue; + if (i == _QIB_EVENT_DISARM_BUFS_BIT) { + (void)qib_disarm_piobufs_ifneeded(rcd); + ret = disarm_req_delay(rcd); + } else + clear_bit(i, &rcd->user_event_mask[subctxt]); + } + return ret; +} + +static ssize_t qib_write(struct file *fp, const char __user *data, + size_t count, loff_t *off) +{ + const struct qib_cmd __user *ucmd; + struct qib_ctxtdata *rcd; + const void __user *src; + size_t consumed, copy = 0; + struct qib_cmd cmd; + ssize_t ret = 0; + void *dest; + + if (count < sizeof(cmd.type)) { + ret = -EINVAL; + goto bail; + } + + ucmd = (const struct qib_cmd __user *) data; + + if (copy_from_user(&cmd.type, &ucmd->type, sizeof(cmd.type))) { + ret = -EFAULT; + goto bail; + } + + consumed = sizeof(cmd.type); + + switch (cmd.type) { + case QIB_CMD_ASSIGN_CTXT: + case QIB_CMD_USER_INIT: + copy = sizeof(cmd.cmd.user_info); + dest = &cmd.cmd.user_info; + src = &ucmd->cmd.user_info; + break; + + case QIB_CMD_RECV_CTRL: + copy = sizeof(cmd.cmd.recv_ctrl); + dest = &cmd.cmd.recv_ctrl; + src = &ucmd->cmd.recv_ctrl; + break; + + case QIB_CMD_CTXT_INFO: + copy = sizeof(cmd.cmd.ctxt_info); + dest = &cmd.cmd.ctxt_info; + src = &ucmd->cmd.ctxt_info; + break; + + case QIB_CMD_TID_UPDATE: + case QIB_CMD_TID_FREE: + copy = sizeof(cmd.cmd.tid_info); + dest = &cmd.cmd.tid_info; + src = &ucmd->cmd.tid_info; + break; + + case QIB_CMD_SET_PART_KEY: + copy = sizeof(cmd.cmd.part_key); + dest = &cmd.cmd.part_key; + src = &ucmd->cmd.part_key; + break; + + case QIB_CMD_DISARM_BUFS: + case QIB_CMD_PIOAVAILUPD: /* force an update of PIOAvail reg */ + copy = 0; + src = NULL; + dest = NULL; + break; + + case QIB_CMD_POLL_TYPE: + copy = sizeof(cmd.cmd.poll_type); + dest = &cmd.cmd.poll_type; + src = &ucmd->cmd.poll_type; + break; + + case QIB_CMD_ARMLAUNCH_CTRL: + copy = sizeof(cmd.cmd.armlaunch_ctrl); + dest = &cmd.cmd.armlaunch_ctrl; + src = &ucmd->cmd.armlaunch_ctrl; + break; + + case QIB_CMD_SDMA_INFLIGHT: + copy = sizeof(cmd.cmd.sdma_inflight); + dest = &cmd.cmd.sdma_inflight; + src = &ucmd->cmd.sdma_inflight; + break; + + case QIB_CMD_SDMA_COMPLETE: + copy = sizeof(cmd.cmd.sdma_complete); + dest = &cmd.cmd.sdma_complete; + src = &ucmd->cmd.sdma_complete; + break; + + case QIB_CMD_ACK_EVENT: + copy = sizeof(cmd.cmd.event_mask); + dest = &cmd.cmd.event_mask; + src = &ucmd->cmd.event_mask; + break; + + default: + ret = -EINVAL; + goto bail; + } + + if (copy) { + if ((count - consumed) < copy) { + ret = -EINVAL; + goto bail; + } + if (copy_from_user(dest, src, copy)) { + ret = -EFAULT; + goto bail; + } + consumed += copy; + } + + rcd = ctxt_fp(fp); + if (!rcd && cmd.type != QIB_CMD_ASSIGN_CTXT) { + ret = -EINVAL; + goto bail; + } + + switch (cmd.type) { + case QIB_CMD_ASSIGN_CTXT: + ret = qib_assign_ctxt(fp, &cmd.cmd.user_info); + if (ret) + goto bail; + break; + + case QIB_CMD_USER_INIT: + ret = qib_do_user_init(fp, &cmd.cmd.user_info); + if (ret) + goto bail; + ret = qib_get_base_info(fp, (void __user *) (unsigned long) + cmd.cmd.user_info.spu_base_info, + cmd.cmd.user_info.spu_base_info_size); + break; + + case QIB_CMD_RECV_CTRL: + ret = qib_manage_rcvq(rcd, subctxt_fp(fp), cmd.cmd.recv_ctrl); + break; + + case QIB_CMD_CTXT_INFO: + ret = qib_ctxt_info(fp, (struct qib_ctxt_info __user *) + (unsigned long) cmd.cmd.ctxt_info); + break; + + case QIB_CMD_TID_UPDATE: + ret = qib_tid_update(rcd, fp, &cmd.cmd.tid_info); + break; + + case QIB_CMD_TID_FREE: + ret = qib_tid_free(rcd, subctxt_fp(fp), &cmd.cmd.tid_info); + break; + + case QIB_CMD_SET_PART_KEY: + ret = qib_set_part_key(rcd, cmd.cmd.part_key); + break; + + case QIB_CMD_DISARM_BUFS: + (void)qib_disarm_piobufs_ifneeded(rcd); + ret = disarm_req_delay(rcd); + break; + + case QIB_CMD_PIOAVAILUPD: + qib_force_pio_avail_update(rcd->dd); + break; + + case QIB_CMD_POLL_TYPE: + rcd->poll_type = cmd.cmd.poll_type; + break; + + case QIB_CMD_ARMLAUNCH_CTRL: + rcd->dd->f_set_armlaunch(rcd->dd, cmd.cmd.armlaunch_ctrl); + break; + + case QIB_CMD_SDMA_INFLIGHT: + ret = qib_sdma_get_inflight(user_sdma_queue_fp(fp), + (u32 __user *) (unsigned long) + cmd.cmd.sdma_inflight); + break; + + case QIB_CMD_SDMA_COMPLETE: + ret = qib_sdma_get_complete(rcd->ppd, + user_sdma_queue_fp(fp), + (u32 __user *) (unsigned long) + cmd.cmd.sdma_complete); + break; + + case QIB_CMD_ACK_EVENT: + ret = qib_user_event_ack(rcd, subctxt_fp(fp), + cmd.cmd.event_mask); + break; + } + + if (ret >= 0) + ret = consumed; + +bail: + return ret; +} + +static ssize_t qib_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long dim, loff_t off) +{ + struct qib_filedata *fp = iocb->ki_filp->private_data; + struct qib_ctxtdata *rcd = ctxt_fp(iocb->ki_filp); + struct qib_user_sdma_queue *pq = fp->pq; + + if (!dim || !pq) + return -EINVAL; + + return qib_user_sdma_writev(rcd, pq, iov, dim); +} + +static struct class *qib_class; +static dev_t qib_dev; + +int qib_cdev_init(int minor, const char *name, + const struct file_operations *fops, + struct cdev **cdevp, struct device **devp) +{ + const dev_t dev = MKDEV(MAJOR(qib_dev), minor); + struct cdev *cdev; + struct device *device = NULL; + int ret; + + cdev = cdev_alloc(); + if (!cdev) { + printk(KERN_ERR QIB_DRV_NAME + ": Could not allocate cdev for minor %d, %s\n", + minor, name); + ret = -ENOMEM; + goto done; + } + + cdev->owner = THIS_MODULE; + cdev->ops = fops; + kobject_set_name(&cdev->kobj, name); + + ret = cdev_add(cdev, dev, 1); + if (ret < 0) { + printk(KERN_ERR QIB_DRV_NAME + ": Could not add cdev for minor %d, %s (err %d)\n", + minor, name, -ret); + goto err_cdev; + } + + device = device_create(qib_class, NULL, dev, NULL, name); + if (!IS_ERR(device)) + goto done; + ret = PTR_ERR(device); + device = NULL; + printk(KERN_ERR QIB_DRV_NAME ": Could not create " + "device for minor %d, %s (err %d)\n", + minor, name, -ret); +err_cdev: + cdev_del(cdev); + cdev = NULL; +done: + *cdevp = cdev; + *devp = device; + return ret; +} + +void qib_cdev_cleanup(struct cdev **cdevp, struct device **devp) +{ + struct device *device = *devp; + + if (device) { + device_unregister(device); + *devp = NULL; + } + + if (*cdevp) { + cdev_del(*cdevp); + *cdevp = NULL; + } +} + +static struct cdev *wildcard_cdev; +static struct device *wildcard_device; + +int __init qib_dev_init(void) +{ + int ret; + + ret = alloc_chrdev_region(&qib_dev, 0, QIB_NMINORS, QIB_DRV_NAME); + if (ret < 0) { + printk(KERN_ERR QIB_DRV_NAME ": Could not allocate " + "chrdev region (err %d)\n", -ret); + goto done; + } + + qib_class = class_create(THIS_MODULE, "ipath"); + if (IS_ERR(qib_class)) { + ret = PTR_ERR(qib_class); + printk(KERN_ERR QIB_DRV_NAME ": Could not create " + "device class (err %d)\n", -ret); + unregister_chrdev_region(qib_dev, QIB_NMINORS); + } + +done: + return ret; +} + +void qib_dev_cleanup(void) +{ + if (qib_class) { + class_destroy(qib_class); + qib_class = NULL; + } + + unregister_chrdev_region(qib_dev, QIB_NMINORS); +} + +static atomic_t user_count = ATOMIC_INIT(0); + +static void qib_user_remove(struct qib_devdata *dd) +{ + if (atomic_dec_return(&user_count) == 0) + qib_cdev_cleanup(&wildcard_cdev, &wildcard_device); + + qib_cdev_cleanup(&dd->user_cdev, &dd->user_device); +} + +static int qib_user_add(struct qib_devdata *dd) +{ + char name[10]; + int ret; + + if (atomic_inc_return(&user_count) == 1) { + ret = qib_cdev_init(0, "ipath", &qib_file_ops, + &wildcard_cdev, &wildcard_device); + if (ret) + goto done; + } + + snprintf(name, sizeof(name), "ipath%d", dd->unit); + ret = qib_cdev_init(dd->unit + 1, name, &qib_file_ops, + &dd->user_cdev, &dd->user_device); + if (ret) + qib_user_remove(dd); +done: + return ret; +} + +/* + * Create per-unit files in /dev + */ +int qib_device_create(struct qib_devdata *dd) +{ + int r, ret; + + r = qib_user_add(dd); + ret = qib_diag_add(dd); + if (r && !ret) + ret = r; + return ret; +} + +/* + * Remove per-unit files in /dev + * void, core kernel returns no errors for this stuff + */ +void qib_device_remove(struct qib_devdata *dd) +{ + qib_user_remove(dd); + qib_diag_remove(dd); +} diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c new file mode 100644 index 000000000000..755470440ef1 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_fs.c @@ -0,0 +1,613 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. + * Copyright (c) 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include "qib.h" + +#define QIBFS_MAGIC 0x726a77 + +static struct super_block *qib_super; + +#define private2dd(file) ((file)->f_dentry->d_inode->i_private) + +static int qibfs_mknod(struct inode *dir, struct dentry *dentry, + int mode, const struct file_operations *fops, + void *data) +{ + int error; + struct inode *inode = new_inode(dir->i_sb); + + if (!inode) { + error = -EPERM; + goto bail; + } + + inode->i_mode = mode; + inode->i_uid = 0; + inode->i_gid = 0; + inode->i_blocks = 0; + inode->i_atime = CURRENT_TIME; + inode->i_mtime = inode->i_atime; + inode->i_ctime = inode->i_atime; + inode->i_private = data; + if ((mode & S_IFMT) == S_IFDIR) { + inode->i_op = &simple_dir_inode_operations; + inc_nlink(inode); + inc_nlink(dir); + } + + inode->i_fop = fops; + + d_instantiate(dentry, inode); + error = 0; + +bail: + return error; +} + +static int create_file(const char *name, mode_t mode, + struct dentry *parent, struct dentry **dentry, + const struct file_operations *fops, void *data) +{ + int error; + + *dentry = NULL; + mutex_lock(&parent->d_inode->i_mutex); + *dentry = lookup_one_len(name, parent, strlen(name)); + if (!IS_ERR(*dentry)) + error = qibfs_mknod(parent->d_inode, *dentry, + mode, fops, data); + else + error = PTR_ERR(*dentry); + mutex_unlock(&parent->d_inode->i_mutex); + + return error; +} + +static ssize_t driver_stats_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + return simple_read_from_buffer(buf, count, ppos, &qib_stats, + sizeof qib_stats); +} + +/* + * driver stats field names, one line per stat, single string. Used by + * programs like ipathstats to print the stats in a way which works for + * different versions of drivers, without changing program source. + * if qlogic_ib_stats changes, this needs to change. Names need to be + * 12 chars or less (w/o newline), for proper display by ipathstats utility. + */ +static const char qib_statnames[] = + "KernIntr\n" + "ErrorIntr\n" + "Tx_Errs\n" + "Rcv_Errs\n" + "H/W_Errs\n" + "NoPIOBufs\n" + "CtxtsOpen\n" + "RcvLen_Errs\n" + "EgrBufFull\n" + "EgrHdrFull\n" + ; + +static ssize_t driver_names_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + return simple_read_from_buffer(buf, count, ppos, qib_statnames, + sizeof qib_statnames - 1); /* no null */ +} + +static const struct file_operations driver_ops[] = { + { .read = driver_stats_read, }, + { .read = driver_names_read, }, +}; + +/* read the per-device counters */ +static ssize_t dev_counters_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + u64 *counters; + struct qib_devdata *dd = private2dd(file); + + return simple_read_from_buffer(buf, count, ppos, counters, + dd->f_read_cntrs(dd, *ppos, NULL, &counters)); +} + +/* read the per-device counters */ +static ssize_t dev_names_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + char *names; + struct qib_devdata *dd = private2dd(file); + + return simple_read_from_buffer(buf, count, ppos, names, + dd->f_read_cntrs(dd, *ppos, &names, NULL)); +} + +static const struct file_operations cntr_ops[] = { + { .read = dev_counters_read, }, + { .read = dev_names_read, }, +}; + +/* + * Could use file->f_dentry->d_inode->i_ino to figure out which file, + * instead of separate routine for each, but for now, this works... + */ + +/* read the per-port names (same for each port) */ +static ssize_t portnames_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + char *names; + struct qib_devdata *dd = private2dd(file); + + return simple_read_from_buffer(buf, count, ppos, names, + dd->f_read_portcntrs(dd, *ppos, 0, &names, NULL)); +} + +/* read the per-port counters for port 1 (pidx 0) */ +static ssize_t portcntrs_1_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + u64 *counters; + struct qib_devdata *dd = private2dd(file); + + return simple_read_from_buffer(buf, count, ppos, counters, + dd->f_read_portcntrs(dd, *ppos, 0, NULL, &counters)); +} + +/* read the per-port counters for port 2 (pidx 1) */ +static ssize_t portcntrs_2_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + u64 *counters; + struct qib_devdata *dd = private2dd(file); + + return simple_read_from_buffer(buf, count, ppos, counters, + dd->f_read_portcntrs(dd, *ppos, 1, NULL, &counters)); +} + +static const struct file_operations portcntr_ops[] = { + { .read = portnames_read, }, + { .read = portcntrs_1_read, }, + { .read = portcntrs_2_read, }, +}; + +/* + * read the per-port QSFP data for port 1 (pidx 0) + */ +static ssize_t qsfp_1_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct qib_devdata *dd = private2dd(file); + char *tmp; + int ret; + + tmp = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + ret = qib_qsfp_dump(dd->pport, tmp, PAGE_SIZE); + if (ret > 0) + ret = simple_read_from_buffer(buf, count, ppos, tmp, ret); + kfree(tmp); + return ret; +} + +/* + * read the per-port QSFP data for port 2 (pidx 1) + */ +static ssize_t qsfp_2_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct qib_devdata *dd = private2dd(file); + char *tmp; + int ret; + + if (dd->num_pports < 2) + return -ENODEV; + + tmp = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + ret = qib_qsfp_dump(dd->pport + 1, tmp, PAGE_SIZE); + if (ret > 0) + ret = simple_read_from_buffer(buf, count, ppos, tmp, ret); + kfree(tmp); + return ret; +} + +static const struct file_operations qsfp_ops[] = { + { .read = qsfp_1_read, }, + { .read = qsfp_2_read, }, +}; + +static ssize_t flash_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct qib_devdata *dd; + ssize_t ret; + loff_t pos; + char *tmp; + + pos = *ppos; + + if (pos < 0) { + ret = -EINVAL; + goto bail; + } + + if (pos >= sizeof(struct qib_flash)) { + ret = 0; + goto bail; + } + + if (count > sizeof(struct qib_flash) - pos) + count = sizeof(struct qib_flash) - pos; + + tmp = kmalloc(count, GFP_KERNEL); + if (!tmp) { + ret = -ENOMEM; + goto bail; + } + + dd = private2dd(file); + if (qib_eeprom_read(dd, pos, tmp, count)) { + qib_dev_err(dd, "failed to read from flash\n"); + ret = -ENXIO; + goto bail_tmp; + } + + if (copy_to_user(buf, tmp, count)) { + ret = -EFAULT; + goto bail_tmp; + } + + *ppos = pos + count; + ret = count; + +bail_tmp: + kfree(tmp); + +bail: + return ret; +} + +static ssize_t flash_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct qib_devdata *dd; + ssize_t ret; + loff_t pos; + char *tmp; + + pos = *ppos; + + if (pos != 0) { + ret = -EINVAL; + goto bail; + } + + if (count != sizeof(struct qib_flash)) { + ret = -EINVAL; + goto bail; + } + + tmp = kmalloc(count, GFP_KERNEL); + if (!tmp) { + ret = -ENOMEM; + goto bail; + } + + if (copy_from_user(tmp, buf, count)) { + ret = -EFAULT; + goto bail_tmp; + } + + dd = private2dd(file); + if (qib_eeprom_write(dd, pos, tmp, count)) { + ret = -ENXIO; + qib_dev_err(dd, "failed to write to flash\n"); + goto bail_tmp; + } + + *ppos = pos + count; + ret = count; + +bail_tmp: + kfree(tmp); + +bail: + return ret; +} + +static const struct file_operations flash_ops = { + .read = flash_read, + .write = flash_write, +}; + +static int add_cntr_files(struct super_block *sb, struct qib_devdata *dd) +{ + struct dentry *dir, *tmp; + char unit[10]; + int ret, i; + + /* create the per-unit directory */ + snprintf(unit, sizeof unit, "%u", dd->unit); + ret = create_file(unit, S_IFDIR|S_IRUGO|S_IXUGO, sb->s_root, &dir, + &simple_dir_operations, dd); + if (ret) { + printk(KERN_ERR "create_file(%s) failed: %d\n", unit, ret); + goto bail; + } + + /* create the files in the new directory */ + ret = create_file("counters", S_IFREG|S_IRUGO, dir, &tmp, + &cntr_ops[0], dd); + if (ret) { + printk(KERN_ERR "create_file(%s/counters) failed: %d\n", + unit, ret); + goto bail; + } + ret = create_file("counter_names", S_IFREG|S_IRUGO, dir, &tmp, + &cntr_ops[1], dd); + if (ret) { + printk(KERN_ERR "create_file(%s/counter_names) failed: %d\n", + unit, ret); + goto bail; + } + ret = create_file("portcounter_names", S_IFREG|S_IRUGO, dir, &tmp, + &portcntr_ops[0], dd); + if (ret) { + printk(KERN_ERR "create_file(%s/%s) failed: %d\n", + unit, "portcounter_names", ret); + goto bail; + } + for (i = 1; i <= dd->num_pports; i++) { + char fname[24]; + + sprintf(fname, "port%dcounters", i); + /* create the files in the new directory */ + ret = create_file(fname, S_IFREG|S_IRUGO, dir, &tmp, + &portcntr_ops[i], dd); + if (ret) { + printk(KERN_ERR "create_file(%s/%s) failed: %d\n", + unit, fname, ret); + goto bail; + } + if (!(dd->flags & QIB_HAS_QSFP)) + continue; + sprintf(fname, "qsfp%d", i); + ret = create_file(fname, S_IFREG|S_IRUGO, dir, &tmp, + &qsfp_ops[i - 1], dd); + if (ret) { + printk(KERN_ERR "create_file(%s/%s) failed: %d\n", + unit, fname, ret); + goto bail; + } + } + + ret = create_file("flash", S_IFREG|S_IWUSR|S_IRUGO, dir, &tmp, + &flash_ops, dd); + if (ret) + printk(KERN_ERR "create_file(%s/flash) failed: %d\n", + unit, ret); +bail: + return ret; +} + +static int remove_file(struct dentry *parent, char *name) +{ + struct dentry *tmp; + int ret; + + tmp = lookup_one_len(name, parent, strlen(name)); + + if (IS_ERR(tmp)) { + ret = PTR_ERR(tmp); + goto bail; + } + + spin_lock(&dcache_lock); + spin_lock(&tmp->d_lock); + if (!(d_unhashed(tmp) && tmp->d_inode)) { + dget_locked(tmp); + __d_drop(tmp); + spin_unlock(&tmp->d_lock); + spin_unlock(&dcache_lock); + simple_unlink(parent->d_inode, tmp); + } else { + spin_unlock(&tmp->d_lock); + spin_unlock(&dcache_lock); + } + + ret = 0; +bail: + /* + * We don't expect clients to care about the return value, but + * it's there if they need it. + */ + return ret; +} + +static int remove_device_files(struct super_block *sb, + struct qib_devdata *dd) +{ + struct dentry *dir, *root; + char unit[10]; + int ret, i; + + root = dget(sb->s_root); + mutex_lock(&root->d_inode->i_mutex); + snprintf(unit, sizeof unit, "%u", dd->unit); + dir = lookup_one_len(unit, root, strlen(unit)); + + if (IS_ERR(dir)) { + ret = PTR_ERR(dir); + printk(KERN_ERR "Lookup of %s failed\n", unit); + goto bail; + } + + remove_file(dir, "counters"); + remove_file(dir, "counter_names"); + remove_file(dir, "portcounter_names"); + for (i = 0; i < dd->num_pports; i++) { + char fname[24]; + + sprintf(fname, "port%dcounters", i + 1); + remove_file(dir, fname); + if (dd->flags & QIB_HAS_QSFP) { + sprintf(fname, "qsfp%d", i + 1); + remove_file(dir, fname); + } + } + remove_file(dir, "flash"); + d_delete(dir); + ret = simple_rmdir(root->d_inode, dir); + +bail: + mutex_unlock(&root->d_inode->i_mutex); + dput(root); + return ret; +} + +/* + * This fills everything in when the fs is mounted, to handle umount/mount + * after device init. The direct add_cntr_files() call handles adding + * them from the init code, when the fs is already mounted. + */ +static int qibfs_fill_super(struct super_block *sb, void *data, int silent) +{ + struct qib_devdata *dd, *tmp; + unsigned long flags; + int ret; + + static struct tree_descr files[] = { + [2] = {"driver_stats", &driver_ops[0], S_IRUGO}, + [3] = {"driver_stats_names", &driver_ops[1], S_IRUGO}, + {""}, + }; + + ret = simple_fill_super(sb, QIBFS_MAGIC, files); + if (ret) { + printk(KERN_ERR "simple_fill_super failed: %d\n", ret); + goto bail; + } + + spin_lock_irqsave(&qib_devs_lock, flags); + + list_for_each_entry_safe(dd, tmp, &qib_dev_list, list) { + spin_unlock_irqrestore(&qib_devs_lock, flags); + ret = add_cntr_files(sb, dd); + if (ret) { + deactivate_super(sb); + goto bail; + } + spin_lock_irqsave(&qib_devs_lock, flags); + } + + spin_unlock_irqrestore(&qib_devs_lock, flags); + +bail: + return ret; +} + +static int qibfs_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, struct vfsmount *mnt) +{ + int ret = get_sb_single(fs_type, flags, data, + qibfs_fill_super, mnt); + if (ret >= 0) + qib_super = mnt->mnt_sb; + return ret; +} + +static void qibfs_kill_super(struct super_block *s) +{ + kill_litter_super(s); + qib_super = NULL; +} + +int qibfs_add(struct qib_devdata *dd) +{ + int ret; + + /* + * On first unit initialized, qib_super will not yet exist + * because nobody has yet tried to mount the filesystem, so + * we can't consider that to be an error; if an error occurs + * during the mount, that will get a complaint, so this is OK. + * add_cntr_files() for all units is done at mount from + * qibfs_fill_super(), so one way or another, everything works. + */ + if (qib_super == NULL) + ret = 0; + else + ret = add_cntr_files(qib_super, dd); + return ret; +} + +int qibfs_remove(struct qib_devdata *dd) +{ + int ret = 0; + + if (qib_super) + ret = remove_device_files(qib_super, dd); + + return ret; +} + +static struct file_system_type qibfs_fs_type = { + .owner = THIS_MODULE, + .name = "ipathfs", + .get_sb = qibfs_get_sb, + .kill_sb = qibfs_kill_super, +}; + +int __init qib_init_qibfs(void) +{ + return register_filesystem(&qibfs_fs_type); +} + +int __exit qib_exit_qibfs(void) +{ + return unregister_filesystem(&qibfs_fs_type); +} diff --git a/drivers/infiniband/hw/qib/qib_iba6120.c b/drivers/infiniband/hw/qib/qib_iba6120.c new file mode 100644 index 000000000000..7b6549fd429b --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_iba6120.c @@ -0,0 +1,3588 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation. + * All rights reserved. + * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +/* + * This file contains all of the code that is specific to the + * QLogic_IB 6120 PCIe chip. + */ + +#include +#include +#include +#include + +#include "qib.h" +#include "qib_6120_regs.h" + +static void qib_6120_setup_setextled(struct qib_pportdata *, u32); +static void sendctrl_6120_mod(struct qib_pportdata *ppd, u32 op); +static u8 qib_6120_phys_portstate(u64); +static u32 qib_6120_iblink_state(u64); + +/* + * This file contains all the chip-specific register information and + * access functions for the QLogic QLogic_IB PCI-Express chip. + * + */ + +/* KREG_IDX uses machine-generated #defines */ +#define KREG_IDX(regname) (QIB_6120_##regname##_OFFS / sizeof(u64)) + +/* Use defines to tie machine-generated names to lower-case names */ +#define kr_extctrl KREG_IDX(EXTCtrl) +#define kr_extstatus KREG_IDX(EXTStatus) +#define kr_gpio_clear KREG_IDX(GPIOClear) +#define kr_gpio_mask KREG_IDX(GPIOMask) +#define kr_gpio_out KREG_IDX(GPIOOut) +#define kr_gpio_status KREG_IDX(GPIOStatus) +#define kr_rcvctrl KREG_IDX(RcvCtrl) +#define kr_sendctrl KREG_IDX(SendCtrl) +#define kr_partitionkey KREG_IDX(RcvPartitionKey) +#define kr_hwdiagctrl KREG_IDX(HwDiagCtrl) +#define kr_ibcstatus KREG_IDX(IBCStatus) +#define kr_ibcctrl KREG_IDX(IBCCtrl) +#define kr_sendbuffererror KREG_IDX(SendBufErr0) +#define kr_rcvbthqp KREG_IDX(RcvBTHQP) +#define kr_counterregbase KREG_IDX(CntrRegBase) +#define kr_palign KREG_IDX(PageAlign) +#define kr_rcvegrbase KREG_IDX(RcvEgrBase) +#define kr_rcvegrcnt KREG_IDX(RcvEgrCnt) +#define kr_rcvhdrcnt KREG_IDX(RcvHdrCnt) +#define kr_rcvhdrentsize KREG_IDX(RcvHdrEntSize) +#define kr_rcvhdrsize KREG_IDX(RcvHdrSize) +#define kr_rcvtidbase KREG_IDX(RcvTIDBase) +#define kr_rcvtidcnt KREG_IDX(RcvTIDCnt) +#define kr_scratch KREG_IDX(Scratch) +#define kr_sendctrl KREG_IDX(SendCtrl) +#define kr_sendpioavailaddr KREG_IDX(SendPIOAvailAddr) +#define kr_sendpiobufbase KREG_IDX(SendPIOBufBase) +#define kr_sendpiobufcnt KREG_IDX(SendPIOBufCnt) +#define kr_sendpiosize KREG_IDX(SendPIOSize) +#define kr_sendregbase KREG_IDX(SendRegBase) +#define kr_userregbase KREG_IDX(UserRegBase) +#define kr_control KREG_IDX(Control) +#define kr_intclear KREG_IDX(IntClear) +#define kr_intmask KREG_IDX(IntMask) +#define kr_intstatus KREG_IDX(IntStatus) +#define kr_errclear KREG_IDX(ErrClear) +#define kr_errmask KREG_IDX(ErrMask) +#define kr_errstatus KREG_IDX(ErrStatus) +#define kr_hwerrclear KREG_IDX(HwErrClear) +#define kr_hwerrmask KREG_IDX(HwErrMask) +#define kr_hwerrstatus KREG_IDX(HwErrStatus) +#define kr_revision KREG_IDX(Revision) +#define kr_portcnt KREG_IDX(PortCnt) +#define kr_serdes_cfg0 KREG_IDX(SerdesCfg0) +#define kr_serdes_cfg1 (kr_serdes_cfg0 + 1) +#define kr_serdes_stat KREG_IDX(SerdesStat) +#define kr_xgxs_cfg KREG_IDX(XGXSCfg) + +/* These must only be written via qib_write_kreg_ctxt() */ +#define kr_rcvhdraddr KREG_IDX(RcvHdrAddr0) +#define kr_rcvhdrtailaddr KREG_IDX(RcvHdrTailAddr0) + +#define CREG_IDX(regname) ((QIB_6120_##regname##_OFFS - \ + QIB_6120_LBIntCnt_OFFS) / sizeof(u64)) + +#define cr_badformat CREG_IDX(RxBadFormatCnt) +#define cr_erricrc CREG_IDX(RxICRCErrCnt) +#define cr_errlink CREG_IDX(RxLinkProblemCnt) +#define cr_errlpcrc CREG_IDX(RxLPCRCErrCnt) +#define cr_errpkey CREG_IDX(RxPKeyMismatchCnt) +#define cr_rcvflowctrl_err CREG_IDX(RxFlowCtrlErrCnt) +#define cr_err_rlen CREG_IDX(RxLenErrCnt) +#define cr_errslen CREG_IDX(TxLenErrCnt) +#define cr_errtidfull CREG_IDX(RxTIDFullErrCnt) +#define cr_errtidvalid CREG_IDX(RxTIDValidErrCnt) +#define cr_errvcrc CREG_IDX(RxVCRCErrCnt) +#define cr_ibstatuschange CREG_IDX(IBStatusChangeCnt) +#define cr_lbint CREG_IDX(LBIntCnt) +#define cr_invalidrlen CREG_IDX(RxMaxMinLenErrCnt) +#define cr_invalidslen CREG_IDX(TxMaxMinLenErrCnt) +#define cr_lbflowstall CREG_IDX(LBFlowStallCnt) +#define cr_pktrcv CREG_IDX(RxDataPktCnt) +#define cr_pktrcvflowctrl CREG_IDX(RxFlowPktCnt) +#define cr_pktsend CREG_IDX(TxDataPktCnt) +#define cr_pktsendflow CREG_IDX(TxFlowPktCnt) +#define cr_portovfl CREG_IDX(RxP0HdrEgrOvflCnt) +#define cr_rcvebp CREG_IDX(RxEBPCnt) +#define cr_rcvovfl CREG_IDX(RxBufOvflCnt) +#define cr_senddropped CREG_IDX(TxDroppedPktCnt) +#define cr_sendstall CREG_IDX(TxFlowStallCnt) +#define cr_sendunderrun CREG_IDX(TxUnderrunCnt) +#define cr_wordrcv CREG_IDX(RxDwordCnt) +#define cr_wordsend CREG_IDX(TxDwordCnt) +#define cr_txunsupvl CREG_IDX(TxUnsupVLErrCnt) +#define cr_rxdroppkt CREG_IDX(RxDroppedPktCnt) +#define cr_iblinkerrrecov CREG_IDX(IBLinkErrRecoveryCnt) +#define cr_iblinkdown CREG_IDX(IBLinkDownedCnt) +#define cr_ibsymbolerr CREG_IDX(IBSymbolErrCnt) + +#define SYM_RMASK(regname, fldname) ((u64) \ + QIB_6120_##regname##_##fldname##_RMASK) +#define SYM_MASK(regname, fldname) ((u64) \ + QIB_6120_##regname##_##fldname##_RMASK << \ + QIB_6120_##regname##_##fldname##_LSB) +#define SYM_LSB(regname, fldname) (QIB_6120_##regname##_##fldname##_LSB) + +#define SYM_FIELD(value, regname, fldname) ((u64) \ + (((value) >> SYM_LSB(regname, fldname)) & \ + SYM_RMASK(regname, fldname))) +#define ERR_MASK(fldname) SYM_MASK(ErrMask, fldname##Mask) +#define HWE_MASK(fldname) SYM_MASK(HwErrMask, fldname##Mask) + +/* link training states, from IBC */ +#define IB_6120_LT_STATE_DISABLED 0x00 +#define IB_6120_LT_STATE_LINKUP 0x01 +#define IB_6120_LT_STATE_POLLACTIVE 0x02 +#define IB_6120_LT_STATE_POLLQUIET 0x03 +#define IB_6120_LT_STATE_SLEEPDELAY 0x04 +#define IB_6120_LT_STATE_SLEEPQUIET 0x05 +#define IB_6120_LT_STATE_CFGDEBOUNCE 0x08 +#define IB_6120_LT_STATE_CFGRCVFCFG 0x09 +#define IB_6120_LT_STATE_CFGWAITRMT 0x0a +#define IB_6120_LT_STATE_CFGIDLE 0x0b +#define IB_6120_LT_STATE_RECOVERRETRAIN 0x0c +#define IB_6120_LT_STATE_RECOVERWAITRMT 0x0e +#define IB_6120_LT_STATE_RECOVERIDLE 0x0f + +/* link state machine states from IBC */ +#define IB_6120_L_STATE_DOWN 0x0 +#define IB_6120_L_STATE_INIT 0x1 +#define IB_6120_L_STATE_ARM 0x2 +#define IB_6120_L_STATE_ACTIVE 0x3 +#define IB_6120_L_STATE_ACT_DEFER 0x4 + +static const u8 qib_6120_physportstate[0x20] = { + [IB_6120_LT_STATE_DISABLED] = IB_PHYSPORTSTATE_DISABLED, + [IB_6120_LT_STATE_LINKUP] = IB_PHYSPORTSTATE_LINKUP, + [IB_6120_LT_STATE_POLLACTIVE] = IB_PHYSPORTSTATE_POLL, + [IB_6120_LT_STATE_POLLQUIET] = IB_PHYSPORTSTATE_POLL, + [IB_6120_LT_STATE_SLEEPDELAY] = IB_PHYSPORTSTATE_SLEEP, + [IB_6120_LT_STATE_SLEEPQUIET] = IB_PHYSPORTSTATE_SLEEP, + [IB_6120_LT_STATE_CFGDEBOUNCE] = + IB_PHYSPORTSTATE_CFG_TRAIN, + [IB_6120_LT_STATE_CFGRCVFCFG] = + IB_PHYSPORTSTATE_CFG_TRAIN, + [IB_6120_LT_STATE_CFGWAITRMT] = + IB_PHYSPORTSTATE_CFG_TRAIN, + [IB_6120_LT_STATE_CFGIDLE] = IB_PHYSPORTSTATE_CFG_TRAIN, + [IB_6120_LT_STATE_RECOVERRETRAIN] = + IB_PHYSPORTSTATE_LINK_ERR_RECOVER, + [IB_6120_LT_STATE_RECOVERWAITRMT] = + IB_PHYSPORTSTATE_LINK_ERR_RECOVER, + [IB_6120_LT_STATE_RECOVERIDLE] = + IB_PHYSPORTSTATE_LINK_ERR_RECOVER, + [0x10] = IB_PHYSPORTSTATE_CFG_TRAIN, + [0x11] = IB_PHYSPORTSTATE_CFG_TRAIN, + [0x12] = IB_PHYSPORTSTATE_CFG_TRAIN, + [0x13] = IB_PHYSPORTSTATE_CFG_TRAIN, + [0x14] = IB_PHYSPORTSTATE_CFG_TRAIN, + [0x15] = IB_PHYSPORTSTATE_CFG_TRAIN, + [0x16] = IB_PHYSPORTSTATE_CFG_TRAIN, + [0x17] = IB_PHYSPORTSTATE_CFG_TRAIN +}; + + +struct qib_chip_specific { + u64 __iomem *cregbase; + u64 *cntrs; + u64 *portcntrs; + void *dummy_hdrq; /* used after ctxt close */ + dma_addr_t dummy_hdrq_phys; + spinlock_t kernel_tid_lock; /* no back to back kernel TID writes */ + spinlock_t user_tid_lock; /* no back to back user TID writes */ + spinlock_t rcvmod_lock; /* protect rcvctrl shadow changes */ + spinlock_t gpio_lock; /* RMW of shadows/regs for ExtCtrl and GPIO */ + u64 hwerrmask; + u64 errormask; + u64 gpio_out; /* shadow of kr_gpio_out, for rmw ops */ + u64 gpio_mask; /* shadow the gpio mask register */ + u64 extctrl; /* shadow the gpio output enable, etc... */ + /* + * these 5 fields are used to establish deltas for IB symbol + * errors and linkrecovery errors. They can be reported on + * some chips during link negotiation prior to INIT, and with + * DDR when faking DDR negotiations with non-IBTA switches. + * The chip counters are adjusted at driver unload if there is + * a non-zero delta. + */ + u64 ibdeltainprog; + u64 ibsymdelta; + u64 ibsymsnap; + u64 iblnkerrdelta; + u64 iblnkerrsnap; + u64 ibcctrl; /* shadow for kr_ibcctrl */ + u32 lastlinkrecov; /* link recovery issue */ + int irq; + u32 cntrnamelen; + u32 portcntrnamelen; + u32 ncntrs; + u32 nportcntrs; + /* used with gpio interrupts to implement IB counters */ + u32 rxfc_unsupvl_errs; + u32 overrun_thresh_errs; + /* + * these count only cases where _successive_ LocalLinkIntegrity + * errors were seen in the receive headers of IB standard packets + */ + u32 lli_errs; + u32 lli_counter; + u64 lli_thresh; + u64 sword; /* total dwords sent (sample result) */ + u64 rword; /* total dwords received (sample result) */ + u64 spkts; /* total packets sent (sample result) */ + u64 rpkts; /* total packets received (sample result) */ + u64 xmit_wait; /* # of ticks no data sent (sample result) */ + struct timer_list pma_timer; + char emsgbuf[128]; + char bitsmsgbuf[64]; + u8 pma_sample_status; +}; + +/* ibcctrl bits */ +#define QLOGIC_IB_IBCC_LINKINITCMD_DISABLE 1 +/* cycle through TS1/TS2 till OK */ +#define QLOGIC_IB_IBCC_LINKINITCMD_POLL 2 +/* wait for TS1, then go on */ +#define QLOGIC_IB_IBCC_LINKINITCMD_SLEEP 3 +#define QLOGIC_IB_IBCC_LINKINITCMD_SHIFT 16 + +#define QLOGIC_IB_IBCC_LINKCMD_DOWN 1 /* move to 0x11 */ +#define QLOGIC_IB_IBCC_LINKCMD_ARMED 2 /* move to 0x21 */ +#define QLOGIC_IB_IBCC_LINKCMD_ACTIVE 3 /* move to 0x31 */ +#define QLOGIC_IB_IBCC_LINKCMD_SHIFT 18 + +/* + * We could have a single register get/put routine, that takes a group type, + * but this is somewhat clearer and cleaner. It also gives us some error + * checking. 64 bit register reads should always work, but are inefficient + * on opteron (the northbridge always generates 2 separate HT 32 bit reads), + * so we use kreg32 wherever possible. User register and counter register + * reads are always 32 bit reads, so only one form of those routines. + */ + +/** + * qib_read_ureg32 - read 32-bit virtualized per-context register + * @dd: device + * @regno: register number + * @ctxt: context number + * + * Return the contents of a register that is virtualized to be per context. + * Returns -1 on errors (not distinguishable from valid contents at + * runtime; we may add a separate error variable at some point). + */ +static inline u32 qib_read_ureg32(const struct qib_devdata *dd, + enum qib_ureg regno, int ctxt) +{ + if (!dd->kregbase || !(dd->flags & QIB_PRESENT)) + return 0; + + if (dd->userbase) + return readl(regno + (u64 __iomem *) + ((char __iomem *)dd->userbase + + dd->ureg_align * ctxt)); + else + return readl(regno + (u64 __iomem *) + (dd->uregbase + + (char __iomem *)dd->kregbase + + dd->ureg_align * ctxt)); +} + +/** + * qib_write_ureg - write 32-bit virtualized per-context register + * @dd: device + * @regno: register number + * @value: value + * @ctxt: context + * + * Write the contents of a register that is virtualized to be per context. + */ +static inline void qib_write_ureg(const struct qib_devdata *dd, + enum qib_ureg regno, u64 value, int ctxt) +{ + u64 __iomem *ubase; + if (dd->userbase) + ubase = (u64 __iomem *) + ((char __iomem *) dd->userbase + + dd->ureg_align * ctxt); + else + ubase = (u64 __iomem *) + (dd->uregbase + + (char __iomem *) dd->kregbase + + dd->ureg_align * ctxt); + + if (dd->kregbase && (dd->flags & QIB_PRESENT)) + writeq(value, &ubase[regno]); +} + +static inline u32 qib_read_kreg32(const struct qib_devdata *dd, + const u16 regno) +{ + if (!dd->kregbase || !(dd->flags & QIB_PRESENT)) + return -1; + return readl((u32 __iomem *)&dd->kregbase[regno]); +} + +static inline u64 qib_read_kreg64(const struct qib_devdata *dd, + const u16 regno) +{ + if (!dd->kregbase || !(dd->flags & QIB_PRESENT)) + return -1; + + return readq(&dd->kregbase[regno]); +} + +static inline void qib_write_kreg(const struct qib_devdata *dd, + const u16 regno, u64 value) +{ + if (dd->kregbase && (dd->flags & QIB_PRESENT)) + writeq(value, &dd->kregbase[regno]); +} + +/** + * qib_write_kreg_ctxt - write a device's per-ctxt 64-bit kernel register + * @dd: the qlogic_ib device + * @regno: the register number to write + * @ctxt: the context containing the register + * @value: the value to write + */ +static inline void qib_write_kreg_ctxt(const struct qib_devdata *dd, + const u16 regno, unsigned ctxt, + u64 value) +{ + qib_write_kreg(dd, regno + ctxt, value); +} + +static inline void write_6120_creg(const struct qib_devdata *dd, + u16 regno, u64 value) +{ + if (dd->cspec->cregbase && (dd->flags & QIB_PRESENT)) + writeq(value, &dd->cspec->cregbase[regno]); +} + +static inline u64 read_6120_creg(const struct qib_devdata *dd, u16 regno) +{ + if (!dd->cspec->cregbase || !(dd->flags & QIB_PRESENT)) + return 0; + return readq(&dd->cspec->cregbase[regno]); +} + +static inline u32 read_6120_creg32(const struct qib_devdata *dd, u16 regno) +{ + if (!dd->cspec->cregbase || !(dd->flags & QIB_PRESENT)) + return 0; + return readl(&dd->cspec->cregbase[regno]); +} + +/* kr_control bits */ +#define QLOGIC_IB_C_RESET 1U + +/* kr_intstatus, kr_intclear, kr_intmask bits */ +#define QLOGIC_IB_I_RCVURG_MASK ((1U << 5) - 1) +#define QLOGIC_IB_I_RCVURG_SHIFT 0 +#define QLOGIC_IB_I_RCVAVAIL_MASK ((1U << 5) - 1) +#define QLOGIC_IB_I_RCVAVAIL_SHIFT 12 + +#define QLOGIC_IB_C_FREEZEMODE 0x00000002 +#define QLOGIC_IB_C_LINKENABLE 0x00000004 +#define QLOGIC_IB_I_ERROR 0x0000000080000000ULL +#define QLOGIC_IB_I_SPIOSENT 0x0000000040000000ULL +#define QLOGIC_IB_I_SPIOBUFAVAIL 0x0000000020000000ULL +#define QLOGIC_IB_I_GPIO 0x0000000010000000ULL +#define QLOGIC_IB_I_BITSEXTANT \ + ((QLOGIC_IB_I_RCVURG_MASK << QLOGIC_IB_I_RCVURG_SHIFT) | \ + (QLOGIC_IB_I_RCVAVAIL_MASK << \ + QLOGIC_IB_I_RCVAVAIL_SHIFT) | \ + QLOGIC_IB_I_ERROR | QLOGIC_IB_I_SPIOSENT | \ + QLOGIC_IB_I_SPIOBUFAVAIL | QLOGIC_IB_I_GPIO) + +/* kr_hwerrclear, kr_hwerrmask, kr_hwerrstatus, bits */ +#define QLOGIC_IB_HWE_PCIEMEMPARITYERR_MASK 0x000000000000003fULL +#define QLOGIC_IB_HWE_PCIEMEMPARITYERR_SHIFT 0 +#define QLOGIC_IB_HWE_PCIEPOISONEDTLP 0x0000000010000000ULL +#define QLOGIC_IB_HWE_PCIECPLTIMEOUT 0x0000000020000000ULL +#define QLOGIC_IB_HWE_PCIEBUSPARITYXTLH 0x0000000040000000ULL +#define QLOGIC_IB_HWE_PCIEBUSPARITYXADM 0x0000000080000000ULL +#define QLOGIC_IB_HWE_PCIEBUSPARITYRADM 0x0000000100000000ULL +#define QLOGIC_IB_HWE_COREPLL_FBSLIP 0x0080000000000000ULL +#define QLOGIC_IB_HWE_COREPLL_RFSLIP 0x0100000000000000ULL +#define QLOGIC_IB_HWE_PCIE1PLLFAILED 0x0400000000000000ULL +#define QLOGIC_IB_HWE_PCIE0PLLFAILED 0x0800000000000000ULL +#define QLOGIC_IB_HWE_SERDESPLLFAILED 0x1000000000000000ULL + + +/* kr_extstatus bits */ +#define QLOGIC_IB_EXTS_FREQSEL 0x2 +#define QLOGIC_IB_EXTS_SERDESSEL 0x4 +#define QLOGIC_IB_EXTS_MEMBIST_ENDTEST 0x0000000000004000 +#define QLOGIC_IB_EXTS_MEMBIST_FOUND 0x0000000000008000 + +/* kr_xgxsconfig bits */ +#define QLOGIC_IB_XGXS_RESET 0x5ULL + +#define _QIB_GPIO_SDA_NUM 1 +#define _QIB_GPIO_SCL_NUM 0 + +/* Bits in GPIO for the added IB link interrupts */ +#define GPIO_RXUVL_BIT 3 +#define GPIO_OVRUN_BIT 4 +#define GPIO_LLI_BIT 5 +#define GPIO_ERRINTR_MASK 0x38 + + +#define QLOGIC_IB_RT_BUFSIZE_MASK 0xe0000000ULL +#define QLOGIC_IB_RT_BUFSIZE_SHIFTVAL(tid) \ + ((((tid) & QLOGIC_IB_RT_BUFSIZE_MASK) >> 29) + 11 - 1) +#define QLOGIC_IB_RT_BUFSIZE(tid) (1 << QLOGIC_IB_RT_BUFSIZE_SHIFTVAL(tid)) +#define QLOGIC_IB_RT_IS_VALID(tid) \ + (((tid) & QLOGIC_IB_RT_BUFSIZE_MASK) && \ + ((((tid) & QLOGIC_IB_RT_BUFSIZE_MASK) != QLOGIC_IB_RT_BUFSIZE_MASK))) +#define QLOGIC_IB_RT_ADDR_MASK 0x1FFFFFFFULL /* 29 bits valid */ +#define QLOGIC_IB_RT_ADDR_SHIFT 10 + +#define QLOGIC_IB_R_INTRAVAIL_SHIFT 16 +#define QLOGIC_IB_R_TAILUPD_SHIFT 31 +#define IBA6120_R_PKEY_DIS_SHIFT 30 + +#define PBC_6120_VL15_SEND_CTRL (1ULL << 31) /* pbc; VL15; link_buf only */ + +#define IBCBUSFRSPCPARITYERR HWE_MASK(IBCBusFromSPCParityErr) +#define IBCBUSTOSPCPARITYERR HWE_MASK(IBCBusToSPCParityErr) + +#define SYM_MASK_BIT(regname, fldname, bit) ((u64) \ + ((1ULL << (SYM_LSB(regname, fldname) + (bit))))) + +#define TXEMEMPARITYERR_PIOBUF \ + SYM_MASK_BIT(HwErrMask, TXEMemParityErrMask, 0) +#define TXEMEMPARITYERR_PIOPBC \ + SYM_MASK_BIT(HwErrMask, TXEMemParityErrMask, 1) +#define TXEMEMPARITYERR_PIOLAUNCHFIFO \ + SYM_MASK_BIT(HwErrMask, TXEMemParityErrMask, 2) + +#define RXEMEMPARITYERR_RCVBUF \ + SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 0) +#define RXEMEMPARITYERR_LOOKUPQ \ + SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 1) +#define RXEMEMPARITYERR_EXPTID \ + SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 2) +#define RXEMEMPARITYERR_EAGERTID \ + SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 3) +#define RXEMEMPARITYERR_FLAGBUF \ + SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 4) +#define RXEMEMPARITYERR_DATAINFO \ + SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 5) +#define RXEMEMPARITYERR_HDRINFO \ + SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 6) + +/* 6120 specific hardware errors... */ +static const struct qib_hwerror_msgs qib_6120_hwerror_msgs[] = { + /* generic hardware errors */ + QLOGIC_IB_HWE_MSG(IBCBUSFRSPCPARITYERR, "QIB2IB Parity"), + QLOGIC_IB_HWE_MSG(IBCBUSTOSPCPARITYERR, "IB2QIB Parity"), + + QLOGIC_IB_HWE_MSG(TXEMEMPARITYERR_PIOBUF, + "TXE PIOBUF Memory Parity"), + QLOGIC_IB_HWE_MSG(TXEMEMPARITYERR_PIOPBC, + "TXE PIOPBC Memory Parity"), + QLOGIC_IB_HWE_MSG(TXEMEMPARITYERR_PIOLAUNCHFIFO, + "TXE PIOLAUNCHFIFO Memory Parity"), + + QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_RCVBUF, + "RXE RCVBUF Memory Parity"), + QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_LOOKUPQ, + "RXE LOOKUPQ Memory Parity"), + QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_EAGERTID, + "RXE EAGERTID Memory Parity"), + QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_EXPTID, + "RXE EXPTID Memory Parity"), + QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_FLAGBUF, + "RXE FLAGBUF Memory Parity"), + QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_DATAINFO, + "RXE DATAINFO Memory Parity"), + QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_HDRINFO, + "RXE HDRINFO Memory Parity"), + + /* chip-specific hardware errors */ + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIEPOISONEDTLP, + "PCIe Poisoned TLP"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIECPLTIMEOUT, + "PCIe completion timeout"), + /* + * In practice, it's unlikely wthat we'll see PCIe PLL, or bus + * parity or memory parity error failures, because most likely we + * won't be able to talk to the core of the chip. Nonetheless, we + * might see them, if they are in parts of the PCIe core that aren't + * essential. + */ + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIE1PLLFAILED, + "PCIePLL1"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIE0PLLFAILED, + "PCIePLL0"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIEBUSPARITYXTLH, + "PCIe XTLH core parity"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIEBUSPARITYXADM, + "PCIe ADM TX core parity"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIEBUSPARITYRADM, + "PCIe ADM RX core parity"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_SERDESPLLFAILED, + "SerDes PLL"), +}; + +#define TXE_PIO_PARITY (TXEMEMPARITYERR_PIOBUF | TXEMEMPARITYERR_PIOPBC) +#define _QIB_PLL_FAIL (QLOGIC_IB_HWE_COREPLL_FBSLIP | \ + QLOGIC_IB_HWE_COREPLL_RFSLIP) + + /* variables for sanity checking interrupt and errors */ +#define IB_HWE_BITSEXTANT \ + (HWE_MASK(RXEMemParityErr) | \ + HWE_MASK(TXEMemParityErr) | \ + (QLOGIC_IB_HWE_PCIEMEMPARITYERR_MASK << \ + QLOGIC_IB_HWE_PCIEMEMPARITYERR_SHIFT) | \ + QLOGIC_IB_HWE_PCIE1PLLFAILED | \ + QLOGIC_IB_HWE_PCIE0PLLFAILED | \ + QLOGIC_IB_HWE_PCIEPOISONEDTLP | \ + QLOGIC_IB_HWE_PCIECPLTIMEOUT | \ + QLOGIC_IB_HWE_PCIEBUSPARITYXTLH | \ + QLOGIC_IB_HWE_PCIEBUSPARITYXADM | \ + QLOGIC_IB_HWE_PCIEBUSPARITYRADM | \ + HWE_MASK(PowerOnBISTFailed) | \ + QLOGIC_IB_HWE_COREPLL_FBSLIP | \ + QLOGIC_IB_HWE_COREPLL_RFSLIP | \ + QLOGIC_IB_HWE_SERDESPLLFAILED | \ + HWE_MASK(IBCBusToSPCParityErr) | \ + HWE_MASK(IBCBusFromSPCParityErr)) + +#define IB_E_BITSEXTANT \ + (ERR_MASK(RcvFormatErr) | ERR_MASK(RcvVCRCErr) | \ + ERR_MASK(RcvICRCErr) | ERR_MASK(RcvMinPktLenErr) | \ + ERR_MASK(RcvMaxPktLenErr) | ERR_MASK(RcvLongPktLenErr) | \ + ERR_MASK(RcvShortPktLenErr) | ERR_MASK(RcvUnexpectedCharErr) | \ + ERR_MASK(RcvUnsupportedVLErr) | ERR_MASK(RcvEBPErr) | \ + ERR_MASK(RcvIBFlowErr) | ERR_MASK(RcvBadVersionErr) | \ + ERR_MASK(RcvEgrFullErr) | ERR_MASK(RcvHdrFullErr) | \ + ERR_MASK(RcvBadTidErr) | ERR_MASK(RcvHdrLenErr) | \ + ERR_MASK(RcvHdrErr) | ERR_MASK(RcvIBLostLinkErr) | \ + ERR_MASK(SendMinPktLenErr) | ERR_MASK(SendMaxPktLenErr) | \ + ERR_MASK(SendUnderRunErr) | ERR_MASK(SendPktLenErr) | \ + ERR_MASK(SendDroppedSmpPktErr) | \ + ERR_MASK(SendDroppedDataPktErr) | \ + ERR_MASK(SendPioArmLaunchErr) | \ + ERR_MASK(SendUnexpectedPktNumErr) | \ + ERR_MASK(SendUnsupportedVLErr) | ERR_MASK(IBStatusChanged) | \ + ERR_MASK(InvalidAddrErr) | ERR_MASK(ResetNegated) | \ + ERR_MASK(HardwareErr)) + +#define QLOGIC_IB_E_PKTERRS ( \ + ERR_MASK(SendPktLenErr) | \ + ERR_MASK(SendDroppedDataPktErr) | \ + ERR_MASK(RcvVCRCErr) | \ + ERR_MASK(RcvICRCErr) | \ + ERR_MASK(RcvShortPktLenErr) | \ + ERR_MASK(RcvEBPErr)) + +/* These are all rcv-related errors which we want to count for stats */ +#define E_SUM_PKTERRS \ + (ERR_MASK(RcvHdrLenErr) | ERR_MASK(RcvBadTidErr) | \ + ERR_MASK(RcvBadVersionErr) | ERR_MASK(RcvHdrErr) | \ + ERR_MASK(RcvLongPktLenErr) | ERR_MASK(RcvShortPktLenErr) | \ + ERR_MASK(RcvMaxPktLenErr) | ERR_MASK(RcvMinPktLenErr) | \ + ERR_MASK(RcvFormatErr) | ERR_MASK(RcvUnsupportedVLErr) | \ + ERR_MASK(RcvUnexpectedCharErr) | ERR_MASK(RcvEBPErr)) + +/* These are all send-related errors which we want to count for stats */ +#define E_SUM_ERRS \ + (ERR_MASK(SendPioArmLaunchErr) | \ + ERR_MASK(SendUnexpectedPktNumErr) | \ + ERR_MASK(SendDroppedDataPktErr) | \ + ERR_MASK(SendDroppedSmpPktErr) | \ + ERR_MASK(SendMaxPktLenErr) | ERR_MASK(SendUnsupportedVLErr) | \ + ERR_MASK(SendMinPktLenErr) | ERR_MASK(SendPktLenErr) | \ + ERR_MASK(InvalidAddrErr)) + +/* + * this is similar to E_SUM_ERRS, but can't ignore armlaunch, don't ignore + * errors not related to freeze and cancelling buffers. Can't ignore + * armlaunch because could get more while still cleaning up, and need + * to cancel those as they happen. + */ +#define E_SPKT_ERRS_IGNORE \ + (ERR_MASK(SendDroppedDataPktErr) | \ + ERR_MASK(SendDroppedSmpPktErr) | \ + ERR_MASK(SendMaxPktLenErr) | ERR_MASK(SendMinPktLenErr) | \ + ERR_MASK(SendPktLenErr)) + +/* + * these are errors that can occur when the link changes state while + * a packet is being sent or received. This doesn't cover things + * like EBP or VCRC that can be the result of a sending having the + * link change state, so we receive a "known bad" packet. + */ +#define E_SUM_LINK_PKTERRS \ + (ERR_MASK(SendDroppedDataPktErr) | \ + ERR_MASK(SendDroppedSmpPktErr) | \ + ERR_MASK(SendMinPktLenErr) | ERR_MASK(SendPktLenErr) | \ + ERR_MASK(RcvShortPktLenErr) | ERR_MASK(RcvMinPktLenErr) | \ + ERR_MASK(RcvUnexpectedCharErr)) + +static void qib_6120_put_tid_2(struct qib_devdata *, u64 __iomem *, + u32, unsigned long); + +/* + * On platforms using this chip, and not having ordered WC stores, we + * can get TXE parity errors due to speculative reads to the PIO buffers, + * and this, due to a chip issue can result in (many) false parity error + * reports. So it's a debug print on those, and an info print on systems + * where the speculative reads don't occur. + */ +static void qib_6120_txe_recover(struct qib_devdata *dd) +{ + if (!qib_unordered_wc()) + qib_devinfo(dd->pcidev, + "Recovering from TXE PIO parity error\n"); +} + +/* enable/disable chip from delivering interrupts */ +static void qib_6120_set_intr_state(struct qib_devdata *dd, u32 enable) +{ + if (enable) { + if (dd->flags & QIB_BADINTR) + return; + qib_write_kreg(dd, kr_intmask, ~0ULL); + /* force re-interrupt of any pending interrupts. */ + qib_write_kreg(dd, kr_intclear, 0ULL); + } else + qib_write_kreg(dd, kr_intmask, 0ULL); +} + +/* + * Try to cleanup as much as possible for anything that might have gone + * wrong while in freeze mode, such as pio buffers being written by user + * processes (causing armlaunch), send errors due to going into freeze mode, + * etc., and try to avoid causing extra interrupts while doing so. + * Forcibly update the in-memory pioavail register copies after cleanup + * because the chip won't do it while in freeze mode (the register values + * themselves are kept correct). + * Make sure that we don't lose any important interrupts by using the chip + * feature that says that writing 0 to a bit in *clear that is set in + * *status will cause an interrupt to be generated again (if allowed by + * the *mask value). + * This is in chip-specific code because of all of the register accesses, + * even though the details are similar on most chips + */ +static void qib_6120_clear_freeze(struct qib_devdata *dd) +{ + /* disable error interrupts, to avoid confusion */ + qib_write_kreg(dd, kr_errmask, 0ULL); + + /* also disable interrupts; errormask is sometimes overwriten */ + qib_6120_set_intr_state(dd, 0); + + qib_cancel_sends(dd->pport); + + /* clear the freeze, and be sure chip saw it */ + qib_write_kreg(dd, kr_control, dd->control); + qib_read_kreg32(dd, kr_scratch); + + /* force in-memory update now we are out of freeze */ + qib_force_pio_avail_update(dd); + + /* + * force new interrupt if any hwerr, error or interrupt bits are + * still set, and clear "safe" send packet errors related to freeze + * and cancelling sends. Re-enable error interrupts before possible + * force of re-interrupt on pending interrupts. + */ + qib_write_kreg(dd, kr_hwerrclear, 0ULL); + qib_write_kreg(dd, kr_errclear, E_SPKT_ERRS_IGNORE); + qib_write_kreg(dd, kr_errmask, dd->cspec->errormask); + qib_6120_set_intr_state(dd, 1); +} + +/** + * qib_handle_6120_hwerrors - display hardware errors. + * @dd: the qlogic_ib device + * @msg: the output buffer + * @msgl: the size of the output buffer + * + * Use same msg buffer as regular errors to avoid excessive stack + * use. Most hardware errors are catastrophic, but for right now, + * we'll print them and continue. Reuse the same message buffer as + * handle_6120_errors() to avoid excessive stack usage. + */ +static void qib_handle_6120_hwerrors(struct qib_devdata *dd, char *msg, + size_t msgl) +{ + u64 hwerrs; + u32 bits, ctrl; + int isfatal = 0; + char *bitsmsg; + int log_idx; + + hwerrs = qib_read_kreg64(dd, kr_hwerrstatus); + if (!hwerrs) + return; + if (hwerrs == ~0ULL) { + qib_dev_err(dd, "Read of hardware error status failed " + "(all bits set); ignoring\n"); + return; + } + qib_stats.sps_hwerrs++; + + /* Always clear the error status register, except MEMBISTFAIL, + * regardless of whether we continue or stop using the chip. + * We want that set so we know it failed, even across driver reload. + * We'll still ignore it in the hwerrmask. We do this partly for + * diagnostics, but also for support */ + qib_write_kreg(dd, kr_hwerrclear, + hwerrs & ~HWE_MASK(PowerOnBISTFailed)); + + hwerrs &= dd->cspec->hwerrmask; + + /* We log some errors to EEPROM, check if we have any of those. */ + for (log_idx = 0; log_idx < QIB_EEP_LOG_CNT; ++log_idx) + if (hwerrs & dd->eep_st_masks[log_idx].hwerrs_to_log) + qib_inc_eeprom_err(dd, log_idx, 1); + + /* + * Make sure we get this much out, unless told to be quiet, + * or it's occurred within the last 5 seconds. + */ + if (hwerrs & ~(TXE_PIO_PARITY | RXEMEMPARITYERR_EAGERTID)) + qib_devinfo(dd->pcidev, "Hardware error: hwerr=0x%llx " + "(cleared)\n", (unsigned long long) hwerrs); + + if (hwerrs & ~IB_HWE_BITSEXTANT) + qib_dev_err(dd, "hwerror interrupt with unknown errors " + "%llx set\n", (unsigned long long) + (hwerrs & ~IB_HWE_BITSEXTANT)); + + ctrl = qib_read_kreg32(dd, kr_control); + if ((ctrl & QLOGIC_IB_C_FREEZEMODE) && !dd->diag_client) { + /* + * Parity errors in send memory are recoverable, + * just cancel the send (if indicated in * sendbuffererror), + * count the occurrence, unfreeze (if no other handled + * hardware error bits are set), and continue. They can + * occur if a processor speculative read is done to the PIO + * buffer while we are sending a packet, for example. + */ + if (hwerrs & TXE_PIO_PARITY) { + qib_6120_txe_recover(dd); + hwerrs &= ~TXE_PIO_PARITY; + } + + if (!hwerrs) { + static u32 freeze_cnt; + + freeze_cnt++; + qib_6120_clear_freeze(dd); + } else + isfatal = 1; + } + + *msg = '\0'; + + if (hwerrs & HWE_MASK(PowerOnBISTFailed)) { + isfatal = 1; + strlcat(msg, "[Memory BIST test failed, InfiniPath hardware" + " unusable]", msgl); + /* ignore from now on, so disable until driver reloaded */ + dd->cspec->hwerrmask &= ~HWE_MASK(PowerOnBISTFailed); + qib_write_kreg(dd, kr_hwerrmask, dd->cspec->hwerrmask); + } + + qib_format_hwerrors(hwerrs, qib_6120_hwerror_msgs, + ARRAY_SIZE(qib_6120_hwerror_msgs), msg, msgl); + + bitsmsg = dd->cspec->bitsmsgbuf; + if (hwerrs & (QLOGIC_IB_HWE_PCIEMEMPARITYERR_MASK << + QLOGIC_IB_HWE_PCIEMEMPARITYERR_SHIFT)) { + bits = (u32) ((hwerrs >> + QLOGIC_IB_HWE_PCIEMEMPARITYERR_SHIFT) & + QLOGIC_IB_HWE_PCIEMEMPARITYERR_MASK); + snprintf(bitsmsg, sizeof dd->cspec->bitsmsgbuf, + "[PCIe Mem Parity Errs %x] ", bits); + strlcat(msg, bitsmsg, msgl); + } + + if (hwerrs & _QIB_PLL_FAIL) { + isfatal = 1; + snprintf(bitsmsg, sizeof dd->cspec->bitsmsgbuf, + "[PLL failed (%llx), InfiniPath hardware unusable]", + (unsigned long long) hwerrs & _QIB_PLL_FAIL); + strlcat(msg, bitsmsg, msgl); + /* ignore from now on, so disable until driver reloaded */ + dd->cspec->hwerrmask &= ~(hwerrs & _QIB_PLL_FAIL); + qib_write_kreg(dd, kr_hwerrmask, dd->cspec->hwerrmask); + } + + if (hwerrs & QLOGIC_IB_HWE_SERDESPLLFAILED) { + /* + * If it occurs, it is left masked since the external + * interface is unused + */ + dd->cspec->hwerrmask &= ~QLOGIC_IB_HWE_SERDESPLLFAILED; + qib_write_kreg(dd, kr_hwerrmask, dd->cspec->hwerrmask); + } + + if (hwerrs) + /* + * if any set that we aren't ignoring; only + * make the complaint once, in case it's stuck + * or recurring, and we get here multiple + * times. + */ + qib_dev_err(dd, "%s hardware error\n", msg); + else + *msg = 0; /* recovered from all of them */ + + if (isfatal && !dd->diag_client) { + qib_dev_err(dd, "Fatal Hardware Error, no longer" + " usable, SN %.16s\n", dd->serial); + /* + * for /sys status file and user programs to print; if no + * trailing brace is copied, we'll know it was truncated. + */ + if (dd->freezemsg) + snprintf(dd->freezemsg, dd->freezelen, + "{%s}", msg); + qib_disable_after_error(dd); + } +} + +/* + * Decode the error status into strings, deciding whether to always + * print * it or not depending on "normal packet errors" vs everything + * else. Return 1 if "real" errors, otherwise 0 if only packet + * errors, so caller can decide what to print with the string. + */ +static int qib_decode_6120_err(struct qib_devdata *dd, char *buf, size_t blen, + u64 err) +{ + int iserr = 1; + + *buf = '\0'; + if (err & QLOGIC_IB_E_PKTERRS) { + if (!(err & ~QLOGIC_IB_E_PKTERRS)) + iserr = 0; + if ((err & ERR_MASK(RcvICRCErr)) && + !(err&(ERR_MASK(RcvVCRCErr)|ERR_MASK(RcvEBPErr)))) + strlcat(buf, "CRC ", blen); + if (!iserr) + goto done; + } + if (err & ERR_MASK(RcvHdrLenErr)) + strlcat(buf, "rhdrlen ", blen); + if (err & ERR_MASK(RcvBadTidErr)) + strlcat(buf, "rbadtid ", blen); + if (err & ERR_MASK(RcvBadVersionErr)) + strlcat(buf, "rbadversion ", blen); + if (err & ERR_MASK(RcvHdrErr)) + strlcat(buf, "rhdr ", blen); + if (err & ERR_MASK(RcvLongPktLenErr)) + strlcat(buf, "rlongpktlen ", blen); + if (err & ERR_MASK(RcvMaxPktLenErr)) + strlcat(buf, "rmaxpktlen ", blen); + if (err & ERR_MASK(RcvMinPktLenErr)) + strlcat(buf, "rminpktlen ", blen); + if (err & ERR_MASK(SendMinPktLenErr)) + strlcat(buf, "sminpktlen ", blen); + if (err & ERR_MASK(RcvFormatErr)) + strlcat(buf, "rformaterr ", blen); + if (err & ERR_MASK(RcvUnsupportedVLErr)) + strlcat(buf, "runsupvl ", blen); + if (err & ERR_MASK(RcvUnexpectedCharErr)) + strlcat(buf, "runexpchar ", blen); + if (err & ERR_MASK(RcvIBFlowErr)) + strlcat(buf, "ribflow ", blen); + if (err & ERR_MASK(SendUnderRunErr)) + strlcat(buf, "sunderrun ", blen); + if (err & ERR_MASK(SendPioArmLaunchErr)) + strlcat(buf, "spioarmlaunch ", blen); + if (err & ERR_MASK(SendUnexpectedPktNumErr)) + strlcat(buf, "sunexperrpktnum ", blen); + if (err & ERR_MASK(SendDroppedSmpPktErr)) + strlcat(buf, "sdroppedsmppkt ", blen); + if (err & ERR_MASK(SendMaxPktLenErr)) + strlcat(buf, "smaxpktlen ", blen); + if (err & ERR_MASK(SendUnsupportedVLErr)) + strlcat(buf, "sunsupVL ", blen); + if (err & ERR_MASK(InvalidAddrErr)) + strlcat(buf, "invalidaddr ", blen); + if (err & ERR_MASK(RcvEgrFullErr)) + strlcat(buf, "rcvegrfull ", blen); + if (err & ERR_MASK(RcvHdrFullErr)) + strlcat(buf, "rcvhdrfull ", blen); + if (err & ERR_MASK(IBStatusChanged)) + strlcat(buf, "ibcstatuschg ", blen); + if (err & ERR_MASK(RcvIBLostLinkErr)) + strlcat(buf, "riblostlink ", blen); + if (err & ERR_MASK(HardwareErr)) + strlcat(buf, "hardware ", blen); + if (err & ERR_MASK(ResetNegated)) + strlcat(buf, "reset ", blen); +done: + return iserr; +} + +/* + * Called when we might have an error that is specific to a particular + * PIO buffer, and may need to cancel that buffer, so it can be re-used. + */ +static void qib_disarm_6120_senderrbufs(struct qib_pportdata *ppd) +{ + unsigned long sbuf[2]; + struct qib_devdata *dd = ppd->dd; + + /* + * It's possible that sendbuffererror could have bits set; might + * have already done this as a result of hardware error handling. + */ + sbuf[0] = qib_read_kreg64(dd, kr_sendbuffererror); + sbuf[1] = qib_read_kreg64(dd, kr_sendbuffererror + 1); + + if (sbuf[0] || sbuf[1]) + qib_disarm_piobufs_set(dd, sbuf, + dd->piobcnt2k + dd->piobcnt4k); +} + +static int chk_6120_linkrecovery(struct qib_devdata *dd, u64 ibcs) +{ + int ret = 1; + u32 ibstate = qib_6120_iblink_state(ibcs); + u32 linkrecov = read_6120_creg32(dd, cr_iblinkerrrecov); + + if (linkrecov != dd->cspec->lastlinkrecov) { + /* and no more until active again */ + dd->cspec->lastlinkrecov = 0; + qib_set_linkstate(dd->pport, QIB_IB_LINKDOWN); + ret = 0; + } + if (ibstate == IB_PORT_ACTIVE) + dd->cspec->lastlinkrecov = + read_6120_creg32(dd, cr_iblinkerrrecov); + return ret; +} + +static void handle_6120_errors(struct qib_devdata *dd, u64 errs) +{ + char *msg; + u64 ignore_this_time = 0; + u64 iserr = 0; + int log_idx; + struct qib_pportdata *ppd = dd->pport; + u64 mask; + + /* don't report errors that are masked */ + errs &= dd->cspec->errormask; + msg = dd->cspec->emsgbuf; + + /* do these first, they are most important */ + if (errs & ERR_MASK(HardwareErr)) + qib_handle_6120_hwerrors(dd, msg, sizeof dd->cspec->emsgbuf); + else + for (log_idx = 0; log_idx < QIB_EEP_LOG_CNT; ++log_idx) + if (errs & dd->eep_st_masks[log_idx].errs_to_log) + qib_inc_eeprom_err(dd, log_idx, 1); + + if (errs & ~IB_E_BITSEXTANT) + qib_dev_err(dd, "error interrupt with unknown errors " + "%llx set\n", + (unsigned long long) (errs & ~IB_E_BITSEXTANT)); + + if (errs & E_SUM_ERRS) { + qib_disarm_6120_senderrbufs(ppd); + if ((errs & E_SUM_LINK_PKTERRS) && + !(ppd->lflags & QIBL_LINKACTIVE)) { + /* + * This can happen when trying to bring the link + * up, but the IB link changes state at the "wrong" + * time. The IB logic then complains that the packet + * isn't valid. We don't want to confuse people, so + * we just don't print them, except at debug + */ + ignore_this_time = errs & E_SUM_LINK_PKTERRS; + } + } else if ((errs & E_SUM_LINK_PKTERRS) && + !(ppd->lflags & QIBL_LINKACTIVE)) { + /* + * This can happen when SMA is trying to bring the link + * up, but the IB link changes state at the "wrong" time. + * The IB logic then complains that the packet isn't + * valid. We don't want to confuse people, so we just + * don't print them, except at debug + */ + ignore_this_time = errs & E_SUM_LINK_PKTERRS; + } + + qib_write_kreg(dd, kr_errclear, errs); + + errs &= ~ignore_this_time; + if (!errs) + goto done; + + /* + * The ones we mask off are handled specially below + * or above. + */ + mask = ERR_MASK(IBStatusChanged) | ERR_MASK(RcvEgrFullErr) | + ERR_MASK(RcvHdrFullErr) | ERR_MASK(HardwareErr); + qib_decode_6120_err(dd, msg, sizeof dd->cspec->emsgbuf, errs & ~mask); + + if (errs & E_SUM_PKTERRS) + qib_stats.sps_rcverrs++; + if (errs & E_SUM_ERRS) + qib_stats.sps_txerrs++; + + iserr = errs & ~(E_SUM_PKTERRS | QLOGIC_IB_E_PKTERRS); + + if (errs & ERR_MASK(IBStatusChanged)) { + u64 ibcs = qib_read_kreg64(dd, kr_ibcstatus); + u32 ibstate = qib_6120_iblink_state(ibcs); + int handle = 1; + + if (ibstate != IB_PORT_INIT && dd->cspec->lastlinkrecov) + handle = chk_6120_linkrecovery(dd, ibcs); + /* + * Since going into a recovery state causes the link state + * to go down and since recovery is transitory, it is better + * if we "miss" ever seeing the link training state go into + * recovery (i.e., ignore this transition for link state + * special handling purposes) without updating lastibcstat. + */ + if (handle && qib_6120_phys_portstate(ibcs) == + IB_PHYSPORTSTATE_LINK_ERR_RECOVER) + handle = 0; + if (handle) + qib_handle_e_ibstatuschanged(ppd, ibcs); + } + + if (errs & ERR_MASK(ResetNegated)) { + qib_dev_err(dd, "Got reset, requires re-init " + "(unload and reload driver)\n"); + dd->flags &= ~QIB_INITTED; /* needs re-init */ + /* mark as having had error */ + *dd->devstatusp |= QIB_STATUS_HWERROR; + *dd->pport->statusp &= ~QIB_STATUS_IB_CONF; + } + + if (*msg && iserr) + qib_dev_porterr(dd, ppd->port, "%s error\n", msg); + + if (ppd->state_wanted & ppd->lflags) + wake_up_interruptible(&ppd->state_wait); + + /* + * If there were hdrq or egrfull errors, wake up any processes + * waiting in poll. We used to try to check which contexts had + * the overflow, but given the cost of that and the chip reads + * to support it, it's better to just wake everybody up if we + * get an overflow; waiters can poll again if it's not them. + */ + if (errs & (ERR_MASK(RcvEgrFullErr) | ERR_MASK(RcvHdrFullErr))) { + qib_handle_urcv(dd, ~0U); + if (errs & ERR_MASK(RcvEgrFullErr)) + qib_stats.sps_buffull++; + else + qib_stats.sps_hdrfull++; + } +done: + return; +} + +/** + * qib_6120_init_hwerrors - enable hardware errors + * @dd: the qlogic_ib device + * + * now that we have finished initializing everything that might reasonably + * cause a hardware error, and cleared those errors bits as they occur, + * we can enable hardware errors in the mask (potentially enabling + * freeze mode), and enable hardware errors as errors (along with + * everything else) in errormask + */ +static void qib_6120_init_hwerrors(struct qib_devdata *dd) +{ + u64 val; + u64 extsval; + + extsval = qib_read_kreg64(dd, kr_extstatus); + + if (!(extsval & QLOGIC_IB_EXTS_MEMBIST_ENDTEST)) + qib_dev_err(dd, "MemBIST did not complete!\n"); + + /* init so all hwerrors interrupt, and enter freeze, ajdust below */ + val = ~0ULL; + if (dd->minrev < 2) { + /* + * Avoid problem with internal interface bus parity + * checking. Fixed in Rev2. + */ + val &= ~QLOGIC_IB_HWE_PCIEBUSPARITYRADM; + } + /* avoid some intel cpu's speculative read freeze mode issue */ + val &= ~TXEMEMPARITYERR_PIOBUF; + + dd->cspec->hwerrmask = val; + + qib_write_kreg(dd, kr_hwerrclear, ~HWE_MASK(PowerOnBISTFailed)); + qib_write_kreg(dd, kr_hwerrmask, dd->cspec->hwerrmask); + + /* clear all */ + qib_write_kreg(dd, kr_errclear, ~0ULL); + /* enable errors that are masked, at least this first time. */ + qib_write_kreg(dd, kr_errmask, ~0ULL); + dd->cspec->errormask = qib_read_kreg64(dd, kr_errmask); + /* clear any interrupts up to this point (ints still not enabled) */ + qib_write_kreg(dd, kr_intclear, ~0ULL); + + qib_write_kreg(dd, kr_rcvbthqp, + dd->qpn_mask << (QIB_6120_RcvBTHQP_BTHQP_Mask_LSB - 1) | + QIB_KD_QP); +} + +/* + * Disable and enable the armlaunch error. Used for PIO bandwidth testing + * on chips that are count-based, rather than trigger-based. There is no + * reference counting, but that's also fine, given the intended use. + * Only chip-specific because it's all register accesses + */ +static void qib_set_6120_armlaunch(struct qib_devdata *dd, u32 enable) +{ + if (enable) { + qib_write_kreg(dd, kr_errclear, + ERR_MASK(SendPioArmLaunchErr)); + dd->cspec->errormask |= ERR_MASK(SendPioArmLaunchErr); + } else + dd->cspec->errormask &= ~ERR_MASK(SendPioArmLaunchErr); + qib_write_kreg(dd, kr_errmask, dd->cspec->errormask); +} + +/* + * Formerly took parameter in pre-shifted, + * pre-merged form with LinkCmd and LinkInitCmd + * together, and assuming the zero was NOP. + */ +static void qib_set_ib_6120_lstate(struct qib_pportdata *ppd, u16 linkcmd, + u16 linitcmd) +{ + u64 mod_wd; + struct qib_devdata *dd = ppd->dd; + unsigned long flags; + + if (linitcmd == QLOGIC_IB_IBCC_LINKINITCMD_DISABLE) { + /* + * If we are told to disable, note that so link-recovery + * code does not attempt to bring us back up. + */ + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags |= QIBL_IB_LINK_DISABLED; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + } else if (linitcmd || linkcmd == QLOGIC_IB_IBCC_LINKCMD_DOWN) { + /* + * Any other linkinitcmd will lead to LINKDOWN and then + * to INIT (if all is well), so clear flag to let + * link-recovery code attempt to bring us back up. + */ + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags &= ~QIBL_IB_LINK_DISABLED; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + } + + mod_wd = (linkcmd << QLOGIC_IB_IBCC_LINKCMD_SHIFT) | + (linitcmd << QLOGIC_IB_IBCC_LINKINITCMD_SHIFT); + + qib_write_kreg(dd, kr_ibcctrl, dd->cspec->ibcctrl | mod_wd); + /* write to chip to prevent back-to-back writes of control reg */ + qib_write_kreg(dd, kr_scratch, 0); +} + +/** + * qib_6120_bringup_serdes - bring up the serdes + * @dd: the qlogic_ib device + */ +static int qib_6120_bringup_serdes(struct qib_pportdata *ppd) +{ + struct qib_devdata *dd = ppd->dd; + u64 val, config1, prev_val, hwstat, ibc; + + /* Put IBC in reset, sends disabled */ + dd->control &= ~QLOGIC_IB_C_LINKENABLE; + qib_write_kreg(dd, kr_control, 0ULL); + + dd->cspec->ibdeltainprog = 1; + dd->cspec->ibsymsnap = read_6120_creg32(dd, cr_ibsymbolerr); + dd->cspec->iblnkerrsnap = read_6120_creg32(dd, cr_iblinkerrrecov); + + /* flowcontrolwatermark is in units of KBytes */ + ibc = 0x5ULL << SYM_LSB(IBCCtrl, FlowCtrlWaterMark); + /* + * How often flowctrl sent. More or less in usecs; balance against + * watermark value, so that in theory senders always get a flow + * control update in time to not let the IB link go idle. + */ + ibc |= 0x3ULL << SYM_LSB(IBCCtrl, FlowCtrlPeriod); + /* max error tolerance */ + dd->cspec->lli_thresh = 0xf; + ibc |= (u64) dd->cspec->lli_thresh << SYM_LSB(IBCCtrl, PhyerrThreshold); + /* use "real" buffer space for */ + ibc |= 4ULL << SYM_LSB(IBCCtrl, CreditScale); + /* IB credit flow control. */ + ibc |= 0xfULL << SYM_LSB(IBCCtrl, OverrunThreshold); + /* + * set initial max size pkt IBC will send, including ICRC; it's the + * PIO buffer size in dwords, less 1; also see qib_set_mtu() + */ + ibc |= ((u64)(ppd->ibmaxlen >> 2) + 1) << SYM_LSB(IBCCtrl, MaxPktLen); + dd->cspec->ibcctrl = ibc; /* without linkcmd or linkinitcmd! */ + + /* initially come up waiting for TS1, without sending anything. */ + val = dd->cspec->ibcctrl | (QLOGIC_IB_IBCC_LINKINITCMD_DISABLE << + QLOGIC_IB_IBCC_LINKINITCMD_SHIFT); + qib_write_kreg(dd, kr_ibcctrl, val); + + val = qib_read_kreg64(dd, kr_serdes_cfg0); + config1 = qib_read_kreg64(dd, kr_serdes_cfg1); + + /* + * Force reset on, also set rxdetect enable. Must do before reading + * serdesstatus at least for simulation, or some of the bits in + * serdes status will come back as undefined and cause simulation + * failures + */ + val |= SYM_MASK(SerdesCfg0, ResetPLL) | + SYM_MASK(SerdesCfg0, RxDetEnX) | + (SYM_MASK(SerdesCfg0, L1PwrDnA) | + SYM_MASK(SerdesCfg0, L1PwrDnB) | + SYM_MASK(SerdesCfg0, L1PwrDnC) | + SYM_MASK(SerdesCfg0, L1PwrDnD)); + qib_write_kreg(dd, kr_serdes_cfg0, val); + /* be sure chip saw it */ + qib_read_kreg64(dd, kr_scratch); + udelay(5); /* need pll reset set at least for a bit */ + /* + * after PLL is reset, set the per-lane Resets and TxIdle and + * clear the PLL reset and rxdetect (to get falling edge). + * Leave L1PWR bits set (permanently) + */ + val &= ~(SYM_MASK(SerdesCfg0, RxDetEnX) | + SYM_MASK(SerdesCfg0, ResetPLL) | + (SYM_MASK(SerdesCfg0, L1PwrDnA) | + SYM_MASK(SerdesCfg0, L1PwrDnB) | + SYM_MASK(SerdesCfg0, L1PwrDnC) | + SYM_MASK(SerdesCfg0, L1PwrDnD))); + val |= (SYM_MASK(SerdesCfg0, ResetA) | + SYM_MASK(SerdesCfg0, ResetB) | + SYM_MASK(SerdesCfg0, ResetC) | + SYM_MASK(SerdesCfg0, ResetD)) | + SYM_MASK(SerdesCfg0, TxIdeEnX); + qib_write_kreg(dd, kr_serdes_cfg0, val); + /* be sure chip saw it */ + (void) qib_read_kreg64(dd, kr_scratch); + /* need PLL reset clear for at least 11 usec before lane + * resets cleared; give it a few more to be sure */ + udelay(15); + val &= ~((SYM_MASK(SerdesCfg0, ResetA) | + SYM_MASK(SerdesCfg0, ResetB) | + SYM_MASK(SerdesCfg0, ResetC) | + SYM_MASK(SerdesCfg0, ResetD)) | + SYM_MASK(SerdesCfg0, TxIdeEnX)); + + qib_write_kreg(dd, kr_serdes_cfg0, val); + /* be sure chip saw it */ + (void) qib_read_kreg64(dd, kr_scratch); + + val = qib_read_kreg64(dd, kr_xgxs_cfg); + prev_val = val; + if (val & QLOGIC_IB_XGXS_RESET) + val &= ~QLOGIC_IB_XGXS_RESET; + if (SYM_FIELD(val, XGXSCfg, polarity_inv) != ppd->rx_pol_inv) { + /* need to compensate for Tx inversion in partner */ + val &= ~SYM_MASK(XGXSCfg, polarity_inv); + val |= (u64)ppd->rx_pol_inv << SYM_LSB(XGXSCfg, polarity_inv); + } + if (val != prev_val) + qib_write_kreg(dd, kr_xgxs_cfg, val); + + val = qib_read_kreg64(dd, kr_serdes_cfg0); + + /* clear current and de-emphasis bits */ + config1 &= ~0x0ffffffff00ULL; + /* set current to 20ma */ + config1 |= 0x00000000000ULL; + /* set de-emphasis to -5.68dB */ + config1 |= 0x0cccc000000ULL; + qib_write_kreg(dd, kr_serdes_cfg1, config1); + + /* base and port guid same for single port */ + ppd->guid = dd->base_guid; + + /* + * the process of setting and un-resetting the serdes normally + * causes a serdes PLL error, so check for that and clear it + * here. Also clearr hwerr bit in errstatus, but not others. + */ + hwstat = qib_read_kreg64(dd, kr_hwerrstatus); + if (hwstat) { + /* should just have PLL, clear all set, in an case */ + if (hwstat & ~QLOGIC_IB_HWE_SERDESPLLFAILED) + qib_write_kreg(dd, kr_hwerrclear, hwstat); + qib_write_kreg(dd, kr_errclear, ERR_MASK(HardwareErr)); + } + + dd->control |= QLOGIC_IB_C_LINKENABLE; + dd->control &= ~QLOGIC_IB_C_FREEZEMODE; + qib_write_kreg(dd, kr_control, dd->control); + + return 0; +} + +/** + * qib_6120_quiet_serdes - set serdes to txidle + * @ppd: physical port of the qlogic_ib device + * Called when driver is being unloaded + */ +static void qib_6120_quiet_serdes(struct qib_pportdata *ppd) +{ + struct qib_devdata *dd = ppd->dd; + u64 val; + + qib_set_ib_6120_lstate(ppd, 0, QLOGIC_IB_IBCC_LINKINITCMD_DISABLE); + + /* disable IBC */ + dd->control &= ~QLOGIC_IB_C_LINKENABLE; + qib_write_kreg(dd, kr_control, + dd->control | QLOGIC_IB_C_FREEZEMODE); + + if (dd->cspec->ibsymdelta || dd->cspec->iblnkerrdelta || + dd->cspec->ibdeltainprog) { + u64 diagc; + + /* enable counter writes */ + diagc = qib_read_kreg64(dd, kr_hwdiagctrl); + qib_write_kreg(dd, kr_hwdiagctrl, + diagc | SYM_MASK(HwDiagCtrl, CounterWrEnable)); + + if (dd->cspec->ibsymdelta || dd->cspec->ibdeltainprog) { + val = read_6120_creg32(dd, cr_ibsymbolerr); + if (dd->cspec->ibdeltainprog) + val -= val - dd->cspec->ibsymsnap; + val -= dd->cspec->ibsymdelta; + write_6120_creg(dd, cr_ibsymbolerr, val); + } + if (dd->cspec->iblnkerrdelta || dd->cspec->ibdeltainprog) { + val = read_6120_creg32(dd, cr_iblinkerrrecov); + if (dd->cspec->ibdeltainprog) + val -= val - dd->cspec->iblnkerrsnap; + val -= dd->cspec->iblnkerrdelta; + write_6120_creg(dd, cr_iblinkerrrecov, val); + } + + /* and disable counter writes */ + qib_write_kreg(dd, kr_hwdiagctrl, diagc); + } + + val = qib_read_kreg64(dd, kr_serdes_cfg0); + val |= SYM_MASK(SerdesCfg0, TxIdeEnX); + qib_write_kreg(dd, kr_serdes_cfg0, val); +} + +/** + * qib_6120_setup_setextled - set the state of the two external LEDs + * @dd: the qlogic_ib device + * @on: whether the link is up or not + * + * The exact combo of LEDs if on is true is determined by looking + * at the ibcstatus. + + * These LEDs indicate the physical and logical state of IB link. + * For this chip (at least with recommended board pinouts), LED1 + * is Yellow (logical state) and LED2 is Green (physical state), + * + * Note: We try to match the Mellanox HCA LED behavior as best + * we can. Green indicates physical link state is OK (something is + * plugged in, and we can train). + * Amber indicates the link is logically up (ACTIVE). + * Mellanox further blinks the amber LED to indicate data packet + * activity, but we have no hardware support for that, so it would + * require waking up every 10-20 msecs and checking the counters + * on the chip, and then turning the LED off if appropriate. That's + * visible overhead, so not something we will do. + * + */ +static void qib_6120_setup_setextled(struct qib_pportdata *ppd, u32 on) +{ + u64 extctl, val, lst, ltst; + unsigned long flags; + struct qib_devdata *dd = ppd->dd; + + /* + * The diags use the LED to indicate diag info, so we leave + * the external LED alone when the diags are running. + */ + if (dd->diag_client) + return; + + /* Allow override of LED display for, e.g. Locating system in rack */ + if (ppd->led_override) { + ltst = (ppd->led_override & QIB_LED_PHYS) ? + IB_PHYSPORTSTATE_LINKUP : IB_PHYSPORTSTATE_DISABLED, + lst = (ppd->led_override & QIB_LED_LOG) ? + IB_PORT_ACTIVE : IB_PORT_DOWN; + } else if (on) { + val = qib_read_kreg64(dd, kr_ibcstatus); + ltst = qib_6120_phys_portstate(val); + lst = qib_6120_iblink_state(val); + } else { + ltst = 0; + lst = 0; + } + + spin_lock_irqsave(&dd->cspec->gpio_lock, flags); + extctl = dd->cspec->extctrl & ~(SYM_MASK(EXTCtrl, LEDPriPortGreenOn) | + SYM_MASK(EXTCtrl, LEDPriPortYellowOn)); + + if (ltst == IB_PHYSPORTSTATE_LINKUP) + extctl |= SYM_MASK(EXTCtrl, LEDPriPortYellowOn); + if (lst == IB_PORT_ACTIVE) + extctl |= SYM_MASK(EXTCtrl, LEDPriPortGreenOn); + dd->cspec->extctrl = extctl; + qib_write_kreg(dd, kr_extctrl, extctl); + spin_unlock_irqrestore(&dd->cspec->gpio_lock, flags); +} + +static void qib_6120_free_irq(struct qib_devdata *dd) +{ + if (dd->cspec->irq) { + free_irq(dd->cspec->irq, dd); + dd->cspec->irq = 0; + } + qib_nomsi(dd); +} + +/** + * qib_6120_setup_cleanup - clean up any per-chip chip-specific stuff + * @dd: the qlogic_ib device + * + * This is called during driver unload. +*/ +static void qib_6120_setup_cleanup(struct qib_devdata *dd) +{ + qib_6120_free_irq(dd); + kfree(dd->cspec->cntrs); + kfree(dd->cspec->portcntrs); + if (dd->cspec->dummy_hdrq) { + dma_free_coherent(&dd->pcidev->dev, + ALIGN(dd->rcvhdrcnt * + dd->rcvhdrentsize * + sizeof(u32), PAGE_SIZE), + dd->cspec->dummy_hdrq, + dd->cspec->dummy_hdrq_phys); + dd->cspec->dummy_hdrq = NULL; + } +} + +static void qib_wantpiobuf_6120_intr(struct qib_devdata *dd, u32 needint) +{ + unsigned long flags; + + spin_lock_irqsave(&dd->sendctrl_lock, flags); + if (needint) + dd->sendctrl |= SYM_MASK(SendCtrl, PIOIntBufAvail); + else + dd->sendctrl &= ~SYM_MASK(SendCtrl, PIOIntBufAvail); + qib_write_kreg(dd, kr_sendctrl, dd->sendctrl); + qib_write_kreg(dd, kr_scratch, 0ULL); + spin_unlock_irqrestore(&dd->sendctrl_lock, flags); +} + +/* + * handle errors and unusual events first, separate function + * to improve cache hits for fast path interrupt handling + */ +static noinline void unlikely_6120_intr(struct qib_devdata *dd, u64 istat) +{ + if (unlikely(istat & ~QLOGIC_IB_I_BITSEXTANT)) + qib_dev_err(dd, "interrupt with unknown interrupts %Lx set\n", + istat & ~QLOGIC_IB_I_BITSEXTANT); + + if (istat & QLOGIC_IB_I_ERROR) { + u64 estat = 0; + + qib_stats.sps_errints++; + estat = qib_read_kreg64(dd, kr_errstatus); + if (!estat) + qib_devinfo(dd->pcidev, "error interrupt (%Lx), " + "but no error bits set!\n", istat); + handle_6120_errors(dd, estat); + } + + if (istat & QLOGIC_IB_I_GPIO) { + u32 gpiostatus; + u32 to_clear = 0; + + /* + * GPIO_3..5 on IBA6120 Rev2 chips indicate + * errors that we need to count. + */ + gpiostatus = qib_read_kreg32(dd, kr_gpio_status); + /* First the error-counter case. */ + if (gpiostatus & GPIO_ERRINTR_MASK) { + /* want to clear the bits we see asserted. */ + to_clear |= (gpiostatus & GPIO_ERRINTR_MASK); + + /* + * Count appropriately, clear bits out of our copy, + * as they have been "handled". + */ + if (gpiostatus & (1 << GPIO_RXUVL_BIT)) + dd->cspec->rxfc_unsupvl_errs++; + if (gpiostatus & (1 << GPIO_OVRUN_BIT)) + dd->cspec->overrun_thresh_errs++; + if (gpiostatus & (1 << GPIO_LLI_BIT)) + dd->cspec->lli_errs++; + gpiostatus &= ~GPIO_ERRINTR_MASK; + } + if (gpiostatus) { + /* + * Some unexpected bits remain. If they could have + * caused the interrupt, complain and clear. + * To avoid repetition of this condition, also clear + * the mask. It is almost certainly due to error. + */ + const u32 mask = qib_read_kreg32(dd, kr_gpio_mask); + + /* + * Also check that the chip reflects our shadow, + * and report issues, If they caused the interrupt. + * we will suppress by refreshing from the shadow. + */ + if (mask & gpiostatus) { + to_clear |= (gpiostatus & mask); + dd->cspec->gpio_mask &= ~(gpiostatus & mask); + qib_write_kreg(dd, kr_gpio_mask, + dd->cspec->gpio_mask); + } + } + if (to_clear) + qib_write_kreg(dd, kr_gpio_clear, (u64) to_clear); + } +} + +static irqreturn_t qib_6120intr(int irq, void *data) +{ + struct qib_devdata *dd = data; + irqreturn_t ret; + u32 istat, ctxtrbits, rmask, crcs = 0; + unsigned i; + + if ((dd->flags & (QIB_PRESENT | QIB_BADINTR)) != QIB_PRESENT) { + /* + * This return value is not great, but we do not want the + * interrupt core code to remove our interrupt handler + * because we don't appear to be handling an interrupt + * during a chip reset. + */ + ret = IRQ_HANDLED; + goto bail; + } + + istat = qib_read_kreg32(dd, kr_intstatus); + + if (unlikely(!istat)) { + ret = IRQ_NONE; /* not our interrupt, or already handled */ + goto bail; + } + if (unlikely(istat == -1)) { + qib_bad_intrstatus(dd); + /* don't know if it was our interrupt or not */ + ret = IRQ_NONE; + goto bail; + } + + qib_stats.sps_ints++; + if (dd->int_counter != (u32) -1) + dd->int_counter++; + + if (unlikely(istat & (~QLOGIC_IB_I_BITSEXTANT | + QLOGIC_IB_I_GPIO | QLOGIC_IB_I_ERROR))) + unlikely_6120_intr(dd, istat); + + /* + * Clear the interrupt bits we found set, relatively early, so we + * "know" know the chip will have seen this by the time we process + * the queue, and will re-interrupt if necessary. The processor + * itself won't take the interrupt again until we return. + */ + qib_write_kreg(dd, kr_intclear, istat); + + /* + * Handle kernel receive queues before checking for pio buffers + * available since receives can overflow; piobuf waiters can afford + * a few extra cycles, since they were waiting anyway. + */ + ctxtrbits = istat & + ((QLOGIC_IB_I_RCVAVAIL_MASK << QLOGIC_IB_I_RCVAVAIL_SHIFT) | + (QLOGIC_IB_I_RCVURG_MASK << QLOGIC_IB_I_RCVURG_SHIFT)); + if (ctxtrbits) { + rmask = (1U << QLOGIC_IB_I_RCVAVAIL_SHIFT) | + (1U << QLOGIC_IB_I_RCVURG_SHIFT); + for (i = 0; i < dd->first_user_ctxt; i++) { + if (ctxtrbits & rmask) { + ctxtrbits &= ~rmask; + crcs += qib_kreceive(dd->rcd[i], + &dd->cspec->lli_counter, + NULL); + } + rmask <<= 1; + } + if (crcs) { + u32 cntr = dd->cspec->lli_counter; + cntr += crcs; + if (cntr) { + if (cntr > dd->cspec->lli_thresh) { + dd->cspec->lli_counter = 0; + dd->cspec->lli_errs++; + } else + dd->cspec->lli_counter += cntr; + } + } + + + if (ctxtrbits) { + ctxtrbits = + (ctxtrbits >> QLOGIC_IB_I_RCVAVAIL_SHIFT) | + (ctxtrbits >> QLOGIC_IB_I_RCVURG_SHIFT); + qib_handle_urcv(dd, ctxtrbits); + } + } + + if ((istat & QLOGIC_IB_I_SPIOBUFAVAIL) && (dd->flags & QIB_INITTED)) + qib_ib_piobufavail(dd); + + ret = IRQ_HANDLED; +bail: + return ret; +} + +/* + * Set up our chip-specific interrupt handler + * The interrupt type has already been setup, so + * we just need to do the registration and error checking. + */ +static void qib_setup_6120_interrupt(struct qib_devdata *dd) +{ + /* + * If the chip supports added error indication via GPIO pins, + * enable interrupts on those bits so the interrupt routine + * can count the events. Also set flag so interrupt routine + * can know they are expected. + */ + if (SYM_FIELD(dd->revision, Revision_R, + ChipRevMinor) > 1) { + /* Rev2+ reports extra errors via internal GPIO pins */ + dd->cspec->gpio_mask |= GPIO_ERRINTR_MASK; + qib_write_kreg(dd, kr_gpio_mask, dd->cspec->gpio_mask); + } + + if (!dd->cspec->irq) + qib_dev_err(dd, "irq is 0, BIOS error? Interrupts won't " + "work\n"); + else { + int ret; + ret = request_irq(dd->cspec->irq, qib_6120intr, 0, + QIB_DRV_NAME, dd); + if (ret) + qib_dev_err(dd, "Couldn't setup interrupt " + "(irq=%d): %d\n", dd->cspec->irq, + ret); + } +} + +/** + * pe_boardname - fill in the board name + * @dd: the qlogic_ib device + * + * info is based on the board revision register + */ +static void pe_boardname(struct qib_devdata *dd) +{ + char *n; + u32 boardid, namelen; + + boardid = SYM_FIELD(dd->revision, Revision, + BoardID); + + switch (boardid) { + case 2: + n = "InfiniPath_QLE7140"; + break; + default: + qib_dev_err(dd, "Unknown 6120 board with ID %u\n", boardid); + n = "Unknown_InfiniPath_6120"; + break; + } + namelen = strlen(n) + 1; + dd->boardname = kmalloc(namelen, GFP_KERNEL); + if (!dd->boardname) + qib_dev_err(dd, "Failed allocation for board name: %s\n", n); + else + snprintf(dd->boardname, namelen, "%s", n); + + if (dd->majrev != 4 || !dd->minrev || dd->minrev > 2) + qib_dev_err(dd, "Unsupported InfiniPath hardware revision " + "%u.%u!\n", dd->majrev, dd->minrev); + + snprintf(dd->boardversion, sizeof(dd->boardversion), + "ChipABI %u.%u, %s, InfiniPath%u %u.%u, SW Compat %u\n", + QIB_CHIP_VERS_MAJ, QIB_CHIP_VERS_MIN, dd->boardname, + (unsigned)SYM_FIELD(dd->revision, Revision_R, Arch), + dd->majrev, dd->minrev, + (unsigned)SYM_FIELD(dd->revision, Revision_R, SW)); + +} + +/* + * This routine sleeps, so it can only be called from user context, not + * from interrupt context. If we need interrupt context, we can split + * it into two routines. + */ +static int qib_6120_setup_reset(struct qib_devdata *dd) +{ + u64 val; + int i; + int ret; + u16 cmdval; + u8 int_line, clinesz; + + qib_pcie_getcmd(dd, &cmdval, &int_line, &clinesz); + + /* Use ERROR so it shows up in logs, etc. */ + qib_dev_err(dd, "Resetting InfiniPath unit %u\n", dd->unit); + + /* no interrupts till re-initted */ + qib_6120_set_intr_state(dd, 0); + + dd->cspec->ibdeltainprog = 0; + dd->cspec->ibsymdelta = 0; + dd->cspec->iblnkerrdelta = 0; + + /* + * Keep chip from being accessed until we are ready. Use + * writeq() directly, to allow the write even though QIB_PRESENT + * isnt' set. + */ + dd->flags &= ~(QIB_INITTED | QIB_PRESENT); + dd->int_counter = 0; /* so we check interrupts work again */ + val = dd->control | QLOGIC_IB_C_RESET; + writeq(val, &dd->kregbase[kr_control]); + mb(); /* prevent compiler re-ordering around actual reset */ + + for (i = 1; i <= 5; i++) { + /* + * Allow MBIST, etc. to complete; longer on each retry. + * We sometimes get machine checks from bus timeout if no + * response, so for now, make it *really* long. + */ + msleep(1000 + (1 + i) * 2000); + + qib_pcie_reenable(dd, cmdval, int_line, clinesz); + + /* + * Use readq directly, so we don't need to mark it as PRESENT + * until we get a successful indication that all is well. + */ + val = readq(&dd->kregbase[kr_revision]); + if (val == dd->revision) { + dd->flags |= QIB_PRESENT; /* it's back */ + ret = qib_reinit_intr(dd); + goto bail; + } + } + ret = 0; /* failed */ + +bail: + if (ret) { + if (qib_pcie_params(dd, dd->lbus_width, NULL, NULL)) + qib_dev_err(dd, "Reset failed to setup PCIe or " + "interrupts; continuing anyway\n"); + /* clear the reset error, init error/hwerror mask */ + qib_6120_init_hwerrors(dd); + /* for Rev2 error interrupts; nop for rev 1 */ + qib_write_kreg(dd, kr_gpio_mask, dd->cspec->gpio_mask); + /* clear the reset error, init error/hwerror mask */ + qib_6120_init_hwerrors(dd); + } + return ret; +} + +/** + * qib_6120_put_tid - write a TID in chip + * @dd: the qlogic_ib device + * @tidptr: pointer to the expected TID (in chip) to update + * @tidtype: RCVHQ_RCV_TYPE_EAGER (1) for eager, RCVHQ_RCV_TYPE_EXPECTED (0) + * for expected + * @pa: physical address of in memory buffer; tidinvalid if freeing + * + * This exists as a separate routine to allow for special locking etc. + * It's used for both the full cleanup on exit, as well as the normal + * setup and teardown. + */ +static void qib_6120_put_tid(struct qib_devdata *dd, u64 __iomem *tidptr, + u32 type, unsigned long pa) +{ + u32 __iomem *tidp32 = (u32 __iomem *)tidptr; + unsigned long flags; + int tidx; + spinlock_t *tidlockp; /* select appropriate spinlock */ + + if (!dd->kregbase) + return; + + if (pa != dd->tidinvalid) { + if (pa & ((1U << 11) - 1)) { + qib_dev_err(dd, "Physaddr %lx not 2KB aligned!\n", + pa); + return; + } + pa >>= 11; + if (pa & ~QLOGIC_IB_RT_ADDR_MASK) { + qib_dev_err(dd, "Physical page address 0x%lx " + "larger than supported\n", pa); + return; + } + + if (type == RCVHQ_RCV_TYPE_EAGER) + pa |= dd->tidtemplate; + else /* for now, always full 4KB page */ + pa |= 2 << 29; + } + + /* + * Avoid chip issue by writing the scratch register + * before and after the TID, and with an io write barrier. + * We use a spinlock around the writes, so they can't intermix + * with other TID (eager or expected) writes (the chip problem + * is triggered by back to back TID writes). Unfortunately, this + * call can be done from interrupt level for the ctxt 0 eager TIDs, + * so we have to use irqsave locks. + */ + /* + * Assumes tidptr always > egrtidbase + * if type == RCVHQ_RCV_TYPE_EAGER. + */ + tidx = tidptr - dd->egrtidbase; + + tidlockp = (type == RCVHQ_RCV_TYPE_EAGER && tidx < dd->rcvhdrcnt) + ? &dd->cspec->kernel_tid_lock : &dd->cspec->user_tid_lock; + spin_lock_irqsave(tidlockp, flags); + qib_write_kreg(dd, kr_scratch, 0xfeeddeaf); + writel(pa, tidp32); + qib_write_kreg(dd, kr_scratch, 0xdeadbeef); + mmiowb(); + spin_unlock_irqrestore(tidlockp, flags); +} + +/** + * qib_6120_put_tid_2 - write a TID in chip, Revision 2 or higher + * @dd: the qlogic_ib device + * @tidptr: pointer to the expected TID (in chip) to update + * @tidtype: RCVHQ_RCV_TYPE_EAGER (1) for eager, RCVHQ_RCV_TYPE_EXPECTED (0) + * for expected + * @pa: physical address of in memory buffer; tidinvalid if freeing + * + * This exists as a separate routine to allow for selection of the + * appropriate "flavor". The static calls in cleanup just use the + * revision-agnostic form, as they are not performance critical. + */ +static void qib_6120_put_tid_2(struct qib_devdata *dd, u64 __iomem *tidptr, + u32 type, unsigned long pa) +{ + u32 __iomem *tidp32 = (u32 __iomem *)tidptr; + u32 tidx; + + if (!dd->kregbase) + return; + + if (pa != dd->tidinvalid) { + if (pa & ((1U << 11) - 1)) { + qib_dev_err(dd, "Physaddr %lx not 2KB aligned!\n", + pa); + return; + } + pa >>= 11; + if (pa & ~QLOGIC_IB_RT_ADDR_MASK) { + qib_dev_err(dd, "Physical page address 0x%lx " + "larger than supported\n", pa); + return; + } + + if (type == RCVHQ_RCV_TYPE_EAGER) + pa |= dd->tidtemplate; + else /* for now, always full 4KB page */ + pa |= 2 << 29; + } + tidx = tidptr - dd->egrtidbase; + writel(pa, tidp32); + mmiowb(); +} + + +/** + * qib_6120_clear_tids - clear all TID entries for a context, expected and eager + * @dd: the qlogic_ib device + * @ctxt: the context + * + * clear all TID entries for a context, expected and eager. + * Used from qib_close(). On this chip, TIDs are only 32 bits, + * not 64, but they are still on 64 bit boundaries, so tidbase + * is declared as u64 * for the pointer math, even though we write 32 bits + */ +static void qib_6120_clear_tids(struct qib_devdata *dd, + struct qib_ctxtdata *rcd) +{ + u64 __iomem *tidbase; + unsigned long tidinv; + u32 ctxt; + int i; + + if (!dd->kregbase || !rcd) + return; + + ctxt = rcd->ctxt; + + tidinv = dd->tidinvalid; + tidbase = (u64 __iomem *) + ((char __iomem *)(dd->kregbase) + + dd->rcvtidbase + + ctxt * dd->rcvtidcnt * sizeof(*tidbase)); + + for (i = 0; i < dd->rcvtidcnt; i++) + /* use func pointer because could be one of two funcs */ + dd->f_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EXPECTED, + tidinv); + + tidbase = (u64 __iomem *) + ((char __iomem *)(dd->kregbase) + + dd->rcvegrbase + + rcd->rcvegr_tid_base * sizeof(*tidbase)); + + for (i = 0; i < rcd->rcvegrcnt; i++) + /* use func pointer because could be one of two funcs */ + dd->f_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EAGER, + tidinv); +} + +/** + * qib_6120_tidtemplate - setup constants for TID updates + * @dd: the qlogic_ib device + * + * We setup stuff that we use a lot, to avoid calculating each time + */ +static void qib_6120_tidtemplate(struct qib_devdata *dd) +{ + u32 egrsize = dd->rcvegrbufsize; + + /* + * For now, we always allocate 4KB buffers (at init) so we can + * receive max size packets. We may want a module parameter to + * specify 2KB or 4KB and/or make be per ctxt instead of per device + * for those who want to reduce memory footprint. Note that the + * rcvhdrentsize size must be large enough to hold the largest + * IB header (currently 96 bytes) that we expect to handle (plus of + * course the 2 dwords of RHF). + */ + if (egrsize == 2048) + dd->tidtemplate = 1U << 29; + else if (egrsize == 4096) + dd->tidtemplate = 2U << 29; + dd->tidinvalid = 0; +} + +int __attribute__((weak)) qib_unordered_wc(void) +{ + return 0; +} + +/** + * qib_6120_get_base_info - set chip-specific flags for user code + * @rcd: the qlogic_ib ctxt + * @kbase: qib_base_info pointer + * + * We set the PCIE flag because the lower bandwidth on PCIe vs + * HyperTransport can affect some user packet algorithms. + */ +static int qib_6120_get_base_info(struct qib_ctxtdata *rcd, + struct qib_base_info *kinfo) +{ + if (qib_unordered_wc()) + kinfo->spi_runtime_flags |= QIB_RUNTIME_FORCE_WC_ORDER; + + kinfo->spi_runtime_flags |= QIB_RUNTIME_PCIE | + QIB_RUNTIME_FORCE_PIOAVAIL | QIB_RUNTIME_PIO_REGSWAPPED; + return 0; +} + + +static struct qib_message_header * +qib_6120_get_msgheader(struct qib_devdata *dd, __le32 *rhf_addr) +{ + return (struct qib_message_header *) + &rhf_addr[sizeof(u64) / sizeof(u32)]; +} + +static void qib_6120_config_ctxts(struct qib_devdata *dd) +{ + dd->ctxtcnt = qib_read_kreg32(dd, kr_portcnt); + if (qib_n_krcv_queues > 1) { + dd->first_user_ctxt = qib_n_krcv_queues * dd->num_pports; + if (dd->first_user_ctxt > dd->ctxtcnt) + dd->first_user_ctxt = dd->ctxtcnt; + dd->qpn_mask = dd->first_user_ctxt <= 2 ? 2 : 6; + } else + dd->first_user_ctxt = dd->num_pports; + dd->n_krcv_queues = dd->first_user_ctxt; +} + +static void qib_update_6120_usrhead(struct qib_ctxtdata *rcd, u64 hd, + u32 updegr, u32 egrhd) +{ + qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); + if (updegr) + qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt); +} + +static u32 qib_6120_hdrqempty(struct qib_ctxtdata *rcd) +{ + u32 head, tail; + + head = qib_read_ureg32(rcd->dd, ur_rcvhdrhead, rcd->ctxt); + if (rcd->rcvhdrtail_kvaddr) + tail = qib_get_rcvhdrtail(rcd); + else + tail = qib_read_ureg32(rcd->dd, ur_rcvhdrtail, rcd->ctxt); + return head == tail; +} + +/* + * Used when we close any ctxt, for DMA already in flight + * at close. Can't be done until we know hdrq size, so not + * early in chip init. + */ +static void alloc_dummy_hdrq(struct qib_devdata *dd) +{ + dd->cspec->dummy_hdrq = dma_alloc_coherent(&dd->pcidev->dev, + dd->rcd[0]->rcvhdrq_size, + &dd->cspec->dummy_hdrq_phys, + GFP_KERNEL | __GFP_COMP); + if (!dd->cspec->dummy_hdrq) { + qib_devinfo(dd->pcidev, "Couldn't allocate dummy hdrq\n"); + /* fallback to just 0'ing */ + dd->cspec->dummy_hdrq_phys = 0UL; + } +} + +/* + * Modify the RCVCTRL register in chip-specific way. This + * is a function because bit positions and (future) register + * location is chip-specific, but the needed operations are + * generic. is a bit-mask because we often want to + * do multiple modifications. + */ +static void rcvctrl_6120_mod(struct qib_pportdata *ppd, unsigned int op, + int ctxt) +{ + struct qib_devdata *dd = ppd->dd; + u64 mask, val; + unsigned long flags; + + spin_lock_irqsave(&dd->cspec->rcvmod_lock, flags); + + if (op & QIB_RCVCTRL_TAILUPD_ENB) + dd->rcvctrl |= (1ULL << QLOGIC_IB_R_TAILUPD_SHIFT); + if (op & QIB_RCVCTRL_TAILUPD_DIS) + dd->rcvctrl &= ~(1ULL << QLOGIC_IB_R_TAILUPD_SHIFT); + if (op & QIB_RCVCTRL_PKEY_ENB) + dd->rcvctrl &= ~(1ULL << IBA6120_R_PKEY_DIS_SHIFT); + if (op & QIB_RCVCTRL_PKEY_DIS) + dd->rcvctrl |= (1ULL << IBA6120_R_PKEY_DIS_SHIFT); + if (ctxt < 0) + mask = (1ULL << dd->ctxtcnt) - 1; + else + mask = (1ULL << ctxt); + if (op & QIB_RCVCTRL_CTXT_ENB) { + /* always done for specific ctxt */ + dd->rcvctrl |= (mask << SYM_LSB(RcvCtrl, PortEnable)); + if (!(dd->flags & QIB_NODMA_RTAIL)) + dd->rcvctrl |= 1ULL << QLOGIC_IB_R_TAILUPD_SHIFT; + /* Write these registers before the context is enabled. */ + qib_write_kreg_ctxt(dd, kr_rcvhdrtailaddr, ctxt, + dd->rcd[ctxt]->rcvhdrqtailaddr_phys); + qib_write_kreg_ctxt(dd, kr_rcvhdraddr, ctxt, + dd->rcd[ctxt]->rcvhdrq_phys); + + if (ctxt == 0 && !dd->cspec->dummy_hdrq) + alloc_dummy_hdrq(dd); + } + if (op & QIB_RCVCTRL_CTXT_DIS) + dd->rcvctrl &= ~(mask << SYM_LSB(RcvCtrl, PortEnable)); + if (op & QIB_RCVCTRL_INTRAVAIL_ENB) + dd->rcvctrl |= (mask << QLOGIC_IB_R_INTRAVAIL_SHIFT); + if (op & QIB_RCVCTRL_INTRAVAIL_DIS) + dd->rcvctrl &= ~(mask << QLOGIC_IB_R_INTRAVAIL_SHIFT); + qib_write_kreg(dd, kr_rcvctrl, dd->rcvctrl); + if ((op & QIB_RCVCTRL_INTRAVAIL_ENB) && dd->rhdrhead_intr_off) { + /* arm rcv interrupt */ + val = qib_read_ureg32(dd, ur_rcvhdrhead, ctxt) | + dd->rhdrhead_intr_off; + qib_write_ureg(dd, ur_rcvhdrhead, val, ctxt); + } + if (op & QIB_RCVCTRL_CTXT_ENB) { + /* + * Init the context registers also; if we were + * disabled, tail and head should both be zero + * already from the enable, but since we don't + * know, we have to do it explictly. + */ + val = qib_read_ureg32(dd, ur_rcvegrindextail, ctxt); + qib_write_ureg(dd, ur_rcvegrindexhead, val, ctxt); + + val = qib_read_ureg32(dd, ur_rcvhdrtail, ctxt); + dd->rcd[ctxt]->head = val; + /* If kctxt, interrupt on next receive. */ + if (ctxt < dd->first_user_ctxt) + val |= dd->rhdrhead_intr_off; + qib_write_ureg(dd, ur_rcvhdrhead, val, ctxt); + } + if (op & QIB_RCVCTRL_CTXT_DIS) { + /* + * Be paranoid, and never write 0's to these, just use an + * unused page. Of course, + * rcvhdraddr points to a large chunk of memory, so this + * could still trash things, but at least it won't trash + * page 0, and by disabling the ctxt, it should stop "soon", + * even if a packet or two is in already in flight after we + * disabled the ctxt. Only 6120 has this issue. + */ + if (ctxt >= 0) { + qib_write_kreg_ctxt(dd, kr_rcvhdrtailaddr, ctxt, + dd->cspec->dummy_hdrq_phys); + qib_write_kreg_ctxt(dd, kr_rcvhdraddr, ctxt, + dd->cspec->dummy_hdrq_phys); + } else { + unsigned i; + + for (i = 0; i < dd->cfgctxts; i++) { + qib_write_kreg_ctxt(dd, kr_rcvhdrtailaddr, + i, dd->cspec->dummy_hdrq_phys); + qib_write_kreg_ctxt(dd, kr_rcvhdraddr, + i, dd->cspec->dummy_hdrq_phys); + } + } + } + spin_unlock_irqrestore(&dd->cspec->rcvmod_lock, flags); +} + +/* + * Modify the SENDCTRL register in chip-specific way. This + * is a function there may be multiple such registers with + * slightly different layouts. Only operations actually used + * are implemented yet. + * Chip requires no back-back sendctrl writes, so write + * scratch register after writing sendctrl + */ +static void sendctrl_6120_mod(struct qib_pportdata *ppd, u32 op) +{ + struct qib_devdata *dd = ppd->dd; + u64 tmp_dd_sendctrl; + unsigned long flags; + + spin_lock_irqsave(&dd->sendctrl_lock, flags); + + /* First the ones that are "sticky", saved in shadow */ + if (op & QIB_SENDCTRL_CLEAR) + dd->sendctrl = 0; + if (op & QIB_SENDCTRL_SEND_DIS) + dd->sendctrl &= ~SYM_MASK(SendCtrl, PIOEnable); + else if (op & QIB_SENDCTRL_SEND_ENB) + dd->sendctrl |= SYM_MASK(SendCtrl, PIOEnable); + if (op & QIB_SENDCTRL_AVAIL_DIS) + dd->sendctrl &= ~SYM_MASK(SendCtrl, PIOBufAvailUpd); + else if (op & QIB_SENDCTRL_AVAIL_ENB) + dd->sendctrl |= SYM_MASK(SendCtrl, PIOBufAvailUpd); + + if (op & QIB_SENDCTRL_DISARM_ALL) { + u32 i, last; + + tmp_dd_sendctrl = dd->sendctrl; + /* + * disarm any that are not yet launched, disabling sends + * and updates until done. + */ + last = dd->piobcnt2k + dd->piobcnt4k; + tmp_dd_sendctrl &= + ~(SYM_MASK(SendCtrl, PIOEnable) | + SYM_MASK(SendCtrl, PIOBufAvailUpd)); + for (i = 0; i < last; i++) { + qib_write_kreg(dd, kr_sendctrl, tmp_dd_sendctrl | + SYM_MASK(SendCtrl, Disarm) | i); + qib_write_kreg(dd, kr_scratch, 0); + } + } + + tmp_dd_sendctrl = dd->sendctrl; + + if (op & QIB_SENDCTRL_FLUSH) + tmp_dd_sendctrl |= SYM_MASK(SendCtrl, Abort); + if (op & QIB_SENDCTRL_DISARM) + tmp_dd_sendctrl |= SYM_MASK(SendCtrl, Disarm) | + ((op & QIB_6120_SendCtrl_DisarmPIOBuf_RMASK) << + SYM_LSB(SendCtrl, DisarmPIOBuf)); + if (op & QIB_SENDCTRL_AVAIL_BLIP) + tmp_dd_sendctrl &= ~SYM_MASK(SendCtrl, PIOBufAvailUpd); + + qib_write_kreg(dd, kr_sendctrl, tmp_dd_sendctrl); + qib_write_kreg(dd, kr_scratch, 0); + + if (op & QIB_SENDCTRL_AVAIL_BLIP) { + qib_write_kreg(dd, kr_sendctrl, dd->sendctrl); + qib_write_kreg(dd, kr_scratch, 0); + } + + spin_unlock_irqrestore(&dd->sendctrl_lock, flags); + + if (op & QIB_SENDCTRL_FLUSH) { + u32 v; + /* + * ensure writes have hit chip, then do a few + * more reads, to allow DMA of pioavail registers + * to occur, so in-memory copy is in sync with + * the chip. Not always safe to sleep. + */ + v = qib_read_kreg32(dd, kr_scratch); + qib_write_kreg(dd, kr_scratch, v); + v = qib_read_kreg32(dd, kr_scratch); + qib_write_kreg(dd, kr_scratch, v); + qib_read_kreg32(dd, kr_scratch); + } +} + +/** + * qib_portcntr_6120 - read a per-port counter + * @dd: the qlogic_ib device + * @creg: the counter to snapshot + */ +static u64 qib_portcntr_6120(struct qib_pportdata *ppd, u32 reg) +{ + u64 ret = 0ULL; + struct qib_devdata *dd = ppd->dd; + u16 creg; + /* 0xffff for unimplemented or synthesized counters */ + static const u16 xlator[] = { + [QIBPORTCNTR_PKTSEND] = cr_pktsend, + [QIBPORTCNTR_WORDSEND] = cr_wordsend, + [QIBPORTCNTR_PSXMITDATA] = 0xffff, + [QIBPORTCNTR_PSXMITPKTS] = 0xffff, + [QIBPORTCNTR_PSXMITWAIT] = 0xffff, + [QIBPORTCNTR_SENDSTALL] = cr_sendstall, + [QIBPORTCNTR_PKTRCV] = cr_pktrcv, + [QIBPORTCNTR_PSRCVDATA] = 0xffff, + [QIBPORTCNTR_PSRCVPKTS] = 0xffff, + [QIBPORTCNTR_RCVEBP] = cr_rcvebp, + [QIBPORTCNTR_RCVOVFL] = cr_rcvovfl, + [QIBPORTCNTR_WORDRCV] = cr_wordrcv, + [QIBPORTCNTR_RXDROPPKT] = cr_rxdroppkt, + [QIBPORTCNTR_RXLOCALPHYERR] = 0xffff, + [QIBPORTCNTR_RXVLERR] = 0xffff, + [QIBPORTCNTR_ERRICRC] = cr_erricrc, + [QIBPORTCNTR_ERRVCRC] = cr_errvcrc, + [QIBPORTCNTR_ERRLPCRC] = cr_errlpcrc, + [QIBPORTCNTR_BADFORMAT] = cr_badformat, + [QIBPORTCNTR_ERR_RLEN] = cr_err_rlen, + [QIBPORTCNTR_IBSYMBOLERR] = cr_ibsymbolerr, + [QIBPORTCNTR_INVALIDRLEN] = cr_invalidrlen, + [QIBPORTCNTR_UNSUPVL] = cr_txunsupvl, + [QIBPORTCNTR_EXCESSBUFOVFL] = 0xffff, + [QIBPORTCNTR_ERRLINK] = cr_errlink, + [QIBPORTCNTR_IBLINKDOWN] = cr_iblinkdown, + [QIBPORTCNTR_IBLINKERRRECOV] = cr_iblinkerrrecov, + [QIBPORTCNTR_LLI] = 0xffff, + [QIBPORTCNTR_PSINTERVAL] = 0xffff, + [QIBPORTCNTR_PSSTART] = 0xffff, + [QIBPORTCNTR_PSSTAT] = 0xffff, + [QIBPORTCNTR_VL15PKTDROP] = 0xffff, + [QIBPORTCNTR_ERRPKEY] = cr_errpkey, + [QIBPORTCNTR_KHDROVFL] = 0xffff, + }; + + if (reg >= ARRAY_SIZE(xlator)) { + qib_devinfo(ppd->dd->pcidev, + "Unimplemented portcounter %u\n", reg); + goto done; + } + creg = xlator[reg]; + + /* handle counters requests not implemented as chip counters */ + if (reg == QIBPORTCNTR_LLI) + ret = dd->cspec->lli_errs; + else if (reg == QIBPORTCNTR_EXCESSBUFOVFL) + ret = dd->cspec->overrun_thresh_errs; + else if (reg == QIBPORTCNTR_KHDROVFL) { + int i; + + /* sum over all kernel contexts */ + for (i = 0; i < dd->first_user_ctxt; i++) + ret += read_6120_creg32(dd, cr_portovfl + i); + } else if (reg == QIBPORTCNTR_PSSTAT) + ret = dd->cspec->pma_sample_status; + if (creg == 0xffff) + goto done; + + /* + * only fast incrementing counters are 64bit; use 32 bit reads to + * avoid two independent reads when on opteron + */ + if (creg == cr_wordsend || creg == cr_wordrcv || + creg == cr_pktsend || creg == cr_pktrcv) + ret = read_6120_creg(dd, creg); + else + ret = read_6120_creg32(dd, creg); + if (creg == cr_ibsymbolerr) { + if (dd->cspec->ibdeltainprog) + ret -= ret - dd->cspec->ibsymsnap; + ret -= dd->cspec->ibsymdelta; + } else if (creg == cr_iblinkerrrecov) { + if (dd->cspec->ibdeltainprog) + ret -= ret - dd->cspec->iblnkerrsnap; + ret -= dd->cspec->iblnkerrdelta; + } + if (reg == QIBPORTCNTR_RXDROPPKT) /* add special cased count */ + ret += dd->cspec->rxfc_unsupvl_errs; + +done: + return ret; +} + +/* + * Device counter names (not port-specific), one line per stat, + * single string. Used by utilities like ipathstats to print the stats + * in a way which works for different versions of drivers, without changing + * the utility. Names need to be 12 chars or less (w/o newline), for proper + * display by utility. + * Non-error counters are first. + * Start of "error" conters is indicated by a leading "E " on the first + * "error" counter, and doesn't count in label length. + * The EgrOvfl list needs to be last so we truncate them at the configured + * context count for the device. + * cntr6120indices contains the corresponding register indices. + */ +static const char cntr6120names[] = + "Interrupts\n" + "HostBusStall\n" + "E RxTIDFull\n" + "RxTIDInvalid\n" + "Ctxt0EgrOvfl\n" + "Ctxt1EgrOvfl\n" + "Ctxt2EgrOvfl\n" + "Ctxt3EgrOvfl\n" + "Ctxt4EgrOvfl\n"; + +static const size_t cntr6120indices[] = { + cr_lbint, + cr_lbflowstall, + cr_errtidfull, + cr_errtidvalid, + cr_portovfl + 0, + cr_portovfl + 1, + cr_portovfl + 2, + cr_portovfl + 3, + cr_portovfl + 4, +}; + +/* + * same as cntr6120names and cntr6120indices, but for port-specific counters. + * portcntr6120indices is somewhat complicated by some registers needing + * adjustments of various kinds, and those are ORed with _PORT_VIRT_FLAG + */ +static const char portcntr6120names[] = + "TxPkt\n" + "TxFlowPkt\n" + "TxWords\n" + "RxPkt\n" + "RxFlowPkt\n" + "RxWords\n" + "TxFlowStall\n" + "E IBStatusChng\n" + "IBLinkDown\n" + "IBLnkRecov\n" + "IBRxLinkErr\n" + "IBSymbolErr\n" + "RxLLIErr\n" + "RxBadFormat\n" + "RxBadLen\n" + "RxBufOvrfl\n" + "RxEBP\n" + "RxFlowCtlErr\n" + "RxICRCerr\n" + "RxLPCRCerr\n" + "RxVCRCerr\n" + "RxInvalLen\n" + "RxInvalPKey\n" + "RxPktDropped\n" + "TxBadLength\n" + "TxDropped\n" + "TxInvalLen\n" + "TxUnderrun\n" + "TxUnsupVL\n" + ; + +#define _PORT_VIRT_FLAG 0x8000 /* "virtual", need adjustments */ +static const size_t portcntr6120indices[] = { + QIBPORTCNTR_PKTSEND | _PORT_VIRT_FLAG, + cr_pktsendflow, + QIBPORTCNTR_WORDSEND | _PORT_VIRT_FLAG, + QIBPORTCNTR_PKTRCV | _PORT_VIRT_FLAG, + cr_pktrcvflowctrl, + QIBPORTCNTR_WORDRCV | _PORT_VIRT_FLAG, + QIBPORTCNTR_SENDSTALL | _PORT_VIRT_FLAG, + cr_ibstatuschange, + QIBPORTCNTR_IBLINKDOWN | _PORT_VIRT_FLAG, + QIBPORTCNTR_IBLINKERRRECOV | _PORT_VIRT_FLAG, + QIBPORTCNTR_ERRLINK | _PORT_VIRT_FLAG, + QIBPORTCNTR_IBSYMBOLERR | _PORT_VIRT_FLAG, + QIBPORTCNTR_LLI | _PORT_VIRT_FLAG, + QIBPORTCNTR_BADFORMAT | _PORT_VIRT_FLAG, + QIBPORTCNTR_ERR_RLEN | _PORT_VIRT_FLAG, + QIBPORTCNTR_RCVOVFL | _PORT_VIRT_FLAG, + QIBPORTCNTR_RCVEBP | _PORT_VIRT_FLAG, + cr_rcvflowctrl_err, + QIBPORTCNTR_ERRICRC | _PORT_VIRT_FLAG, + QIBPORTCNTR_ERRLPCRC | _PORT_VIRT_FLAG, + QIBPORTCNTR_ERRVCRC | _PORT_VIRT_FLAG, + QIBPORTCNTR_INVALIDRLEN | _PORT_VIRT_FLAG, + QIBPORTCNTR_ERRPKEY | _PORT_VIRT_FLAG, + QIBPORTCNTR_RXDROPPKT | _PORT_VIRT_FLAG, + cr_invalidslen, + cr_senddropped, + cr_errslen, + cr_sendunderrun, + cr_txunsupvl, +}; + +/* do all the setup to make the counter reads efficient later */ +static void init_6120_cntrnames(struct qib_devdata *dd) +{ + int i, j = 0; + char *s; + + for (i = 0, s = (char *)cntr6120names; s && j <= dd->cfgctxts; + i++) { + /* we always have at least one counter before the egrovfl */ + if (!j && !strncmp("Ctxt0EgrOvfl", s + 1, 12)) + j = 1; + s = strchr(s + 1, '\n'); + if (s && j) + j++; + } + dd->cspec->ncntrs = i; + if (!s) + /* full list; size is without terminating null */ + dd->cspec->cntrnamelen = sizeof(cntr6120names) - 1; + else + dd->cspec->cntrnamelen = 1 + s - cntr6120names; + dd->cspec->cntrs = kmalloc(dd->cspec->ncntrs + * sizeof(u64), GFP_KERNEL); + if (!dd->cspec->cntrs) + qib_dev_err(dd, "Failed allocation for counters\n"); + + for (i = 0, s = (char *)portcntr6120names; s; i++) + s = strchr(s + 1, '\n'); + dd->cspec->nportcntrs = i - 1; + dd->cspec->portcntrnamelen = sizeof(portcntr6120names) - 1; + dd->cspec->portcntrs = kmalloc(dd->cspec->nportcntrs + * sizeof(u64), GFP_KERNEL); + if (!dd->cspec->portcntrs) + qib_dev_err(dd, "Failed allocation for portcounters\n"); +} + +static u32 qib_read_6120cntrs(struct qib_devdata *dd, loff_t pos, char **namep, + u64 **cntrp) +{ + u32 ret; + + if (namep) { + ret = dd->cspec->cntrnamelen; + if (pos >= ret) + ret = 0; /* final read after getting everything */ + else + *namep = (char *)cntr6120names; + } else { + u64 *cntr = dd->cspec->cntrs; + int i; + + ret = dd->cspec->ncntrs * sizeof(u64); + if (!cntr || pos >= ret) { + /* everything read, or couldn't get memory */ + ret = 0; + goto done; + } + if (pos >= ret) { + ret = 0; /* final read after getting everything */ + goto done; + } + *cntrp = cntr; + for (i = 0; i < dd->cspec->ncntrs; i++) + *cntr++ = read_6120_creg32(dd, cntr6120indices[i]); + } +done: + return ret; +} + +static u32 qib_read_6120portcntrs(struct qib_devdata *dd, loff_t pos, u32 port, + char **namep, u64 **cntrp) +{ + u32 ret; + + if (namep) { + ret = dd->cspec->portcntrnamelen; + if (pos >= ret) + ret = 0; /* final read after getting everything */ + else + *namep = (char *)portcntr6120names; + } else { + u64 *cntr = dd->cspec->portcntrs; + struct qib_pportdata *ppd = &dd->pport[port]; + int i; + + ret = dd->cspec->nportcntrs * sizeof(u64); + if (!cntr || pos >= ret) { + /* everything read, or couldn't get memory */ + ret = 0; + goto done; + } + *cntrp = cntr; + for (i = 0; i < dd->cspec->nportcntrs; i++) { + if (portcntr6120indices[i] & _PORT_VIRT_FLAG) + *cntr++ = qib_portcntr_6120(ppd, + portcntr6120indices[i] & + ~_PORT_VIRT_FLAG); + else + *cntr++ = read_6120_creg32(dd, + portcntr6120indices[i]); + } + } +done: + return ret; +} + +static void qib_chk_6120_errormask(struct qib_devdata *dd) +{ + static u32 fixed; + u32 ctrl; + unsigned long errormask; + unsigned long hwerrs; + + if (!dd->cspec->errormask || !(dd->flags & QIB_INITTED)) + return; + + errormask = qib_read_kreg64(dd, kr_errmask); + + if (errormask == dd->cspec->errormask) + return; + fixed++; + + hwerrs = qib_read_kreg64(dd, kr_hwerrstatus); + ctrl = qib_read_kreg32(dd, kr_control); + + qib_write_kreg(dd, kr_errmask, + dd->cspec->errormask); + + if ((hwerrs & dd->cspec->hwerrmask) || + (ctrl & QLOGIC_IB_C_FREEZEMODE)) { + qib_write_kreg(dd, kr_hwerrclear, 0ULL); + qib_write_kreg(dd, kr_errclear, 0ULL); + /* force re-interrupt of pending events, just in case */ + qib_write_kreg(dd, kr_intclear, 0ULL); + qib_devinfo(dd->pcidev, + "errormask fixed(%u) %lx->%lx, ctrl %x hwerr %lx\n", + fixed, errormask, (unsigned long)dd->cspec->errormask, + ctrl, hwerrs); + } +} + +/** + * qib_get_faststats - get word counters from chip before they overflow + * @opaque - contains a pointer to the qlogic_ib device qib_devdata + * + * This needs more work; in particular, decision on whether we really + * need traffic_wds done the way it is + * called from add_timer + */ +static void qib_get_6120_faststats(unsigned long opaque) +{ + struct qib_devdata *dd = (struct qib_devdata *) opaque; + struct qib_pportdata *ppd = dd->pport; + unsigned long flags; + u64 traffic_wds; + + /* + * don't access the chip while running diags, or memory diags can + * fail + */ + if (!(dd->flags & QIB_INITTED) || dd->diag_client) + /* but re-arm the timer, for diags case; won't hurt other */ + goto done; + + /* + * We now try to maintain an activity timer, based on traffic + * exceeding a threshold, so we need to check the word-counts + * even if they are 64-bit. + */ + traffic_wds = qib_portcntr_6120(ppd, cr_wordsend) + + qib_portcntr_6120(ppd, cr_wordrcv); + spin_lock_irqsave(&dd->eep_st_lock, flags); + traffic_wds -= dd->traffic_wds; + dd->traffic_wds += traffic_wds; + if (traffic_wds >= QIB_TRAFFIC_ACTIVE_THRESHOLD) + atomic_add(5, &dd->active_time); /* S/B #define */ + spin_unlock_irqrestore(&dd->eep_st_lock, flags); + + qib_chk_6120_errormask(dd); +done: + mod_timer(&dd->stats_timer, jiffies + HZ * ACTIVITY_TIMER); +} + +/* no interrupt fallback for these chips */ +static int qib_6120_nointr_fallback(struct qib_devdata *dd) +{ + return 0; +} + +/* + * reset the XGXS (between serdes and IBC). Slightly less intrusive + * than resetting the IBC or external link state, and useful in some + * cases to cause some retraining. To do this right, we reset IBC + * as well. + */ +static void qib_6120_xgxs_reset(struct qib_pportdata *ppd) +{ + u64 val, prev_val; + struct qib_devdata *dd = ppd->dd; + + prev_val = qib_read_kreg64(dd, kr_xgxs_cfg); + val = prev_val | QLOGIC_IB_XGXS_RESET; + prev_val &= ~QLOGIC_IB_XGXS_RESET; /* be sure */ + qib_write_kreg(dd, kr_control, + dd->control & ~QLOGIC_IB_C_LINKENABLE); + qib_write_kreg(dd, kr_xgxs_cfg, val); + qib_read_kreg32(dd, kr_scratch); + qib_write_kreg(dd, kr_xgxs_cfg, prev_val); + qib_write_kreg(dd, kr_control, dd->control); +} + +static int qib_6120_get_ib_cfg(struct qib_pportdata *ppd, int which) +{ + int ret; + + switch (which) { + case QIB_IB_CFG_LWID: + ret = ppd->link_width_active; + break; + + case QIB_IB_CFG_SPD: + ret = ppd->link_speed_active; + break; + + case QIB_IB_CFG_LWID_ENB: + ret = ppd->link_width_enabled; + break; + + case QIB_IB_CFG_SPD_ENB: + ret = ppd->link_speed_enabled; + break; + + case QIB_IB_CFG_OP_VLS: + ret = ppd->vls_operational; + break; + + case QIB_IB_CFG_VL_HIGH_CAP: + ret = 0; + break; + + case QIB_IB_CFG_VL_LOW_CAP: + ret = 0; + break; + + case QIB_IB_CFG_OVERRUN_THRESH: /* IB overrun threshold */ + ret = SYM_FIELD(ppd->dd->cspec->ibcctrl, IBCCtrl, + OverrunThreshold); + break; + + case QIB_IB_CFG_PHYERR_THRESH: /* IB PHY error threshold */ + ret = SYM_FIELD(ppd->dd->cspec->ibcctrl, IBCCtrl, + PhyerrThreshold); + break; + + case QIB_IB_CFG_LINKDEFAULT: /* IB link default (sleep/poll) */ + /* will only take effect when the link state changes */ + ret = (ppd->dd->cspec->ibcctrl & + SYM_MASK(IBCCtrl, LinkDownDefaultState)) ? + IB_LINKINITCMD_SLEEP : IB_LINKINITCMD_POLL; + break; + + case QIB_IB_CFG_HRTBT: /* Get Heartbeat off/enable/auto */ + ret = 0; /* no heartbeat on this chip */ + break; + + case QIB_IB_CFG_PMA_TICKS: + ret = 250; /* 1 usec. */ + break; + + default: + ret = -EINVAL; + break; + } + return ret; +} + +/* + * We assume range checking is already done, if needed. + */ +static int qib_6120_set_ib_cfg(struct qib_pportdata *ppd, int which, u32 val) +{ + struct qib_devdata *dd = ppd->dd; + int ret = 0; + u64 val64; + u16 lcmd, licmd; + + switch (which) { + case QIB_IB_CFG_LWID_ENB: + ppd->link_width_enabled = val; + break; + + case QIB_IB_CFG_SPD_ENB: + ppd->link_speed_enabled = val; + break; + + case QIB_IB_CFG_OVERRUN_THRESH: /* IB overrun threshold */ + val64 = SYM_FIELD(dd->cspec->ibcctrl, IBCCtrl, + OverrunThreshold); + if (val64 != val) { + dd->cspec->ibcctrl &= + ~SYM_MASK(IBCCtrl, OverrunThreshold); + dd->cspec->ibcctrl |= (u64) val << + SYM_LSB(IBCCtrl, OverrunThreshold); + qib_write_kreg(dd, kr_ibcctrl, dd->cspec->ibcctrl); + qib_write_kreg(dd, kr_scratch, 0); + } + break; + + case QIB_IB_CFG_PHYERR_THRESH: /* IB PHY error threshold */ + val64 = SYM_FIELD(dd->cspec->ibcctrl, IBCCtrl, + PhyerrThreshold); + if (val64 != val) { + dd->cspec->ibcctrl &= + ~SYM_MASK(IBCCtrl, PhyerrThreshold); + dd->cspec->ibcctrl |= (u64) val << + SYM_LSB(IBCCtrl, PhyerrThreshold); + qib_write_kreg(dd, kr_ibcctrl, dd->cspec->ibcctrl); + qib_write_kreg(dd, kr_scratch, 0); + } + break; + + case QIB_IB_CFG_PKEYS: /* update pkeys */ + val64 = (u64) ppd->pkeys[0] | ((u64) ppd->pkeys[1] << 16) | + ((u64) ppd->pkeys[2] << 32) | + ((u64) ppd->pkeys[3] << 48); + qib_write_kreg(dd, kr_partitionkey, val64); + break; + + case QIB_IB_CFG_LINKDEFAULT: /* IB link default (sleep/poll) */ + /* will only take effect when the link state changes */ + if (val == IB_LINKINITCMD_POLL) + dd->cspec->ibcctrl &= + ~SYM_MASK(IBCCtrl, LinkDownDefaultState); + else /* SLEEP */ + dd->cspec->ibcctrl |= + SYM_MASK(IBCCtrl, LinkDownDefaultState); + qib_write_kreg(dd, kr_ibcctrl, dd->cspec->ibcctrl); + qib_write_kreg(dd, kr_scratch, 0); + break; + + case QIB_IB_CFG_MTU: /* update the MTU in IBC */ + /* + * Update our housekeeping variables, and set IBC max + * size, same as init code; max IBC is max we allow in + * buffer, less the qword pbc, plus 1 for ICRC, in dwords + * Set even if it's unchanged, print debug message only + * on changes. + */ + val = (ppd->ibmaxlen >> 2) + 1; + dd->cspec->ibcctrl &= ~SYM_MASK(IBCCtrl, MaxPktLen); + dd->cspec->ibcctrl |= (u64)val << + SYM_LSB(IBCCtrl, MaxPktLen); + qib_write_kreg(dd, kr_ibcctrl, dd->cspec->ibcctrl); + qib_write_kreg(dd, kr_scratch, 0); + break; + + case QIB_IB_CFG_LSTATE: /* set the IB link state */ + switch (val & 0xffff0000) { + case IB_LINKCMD_DOWN: + lcmd = QLOGIC_IB_IBCC_LINKCMD_DOWN; + if (!dd->cspec->ibdeltainprog) { + dd->cspec->ibdeltainprog = 1; + dd->cspec->ibsymsnap = + read_6120_creg32(dd, cr_ibsymbolerr); + dd->cspec->iblnkerrsnap = + read_6120_creg32(dd, cr_iblinkerrrecov); + } + break; + + case IB_LINKCMD_ARMED: + lcmd = QLOGIC_IB_IBCC_LINKCMD_ARMED; + break; + + case IB_LINKCMD_ACTIVE: + lcmd = QLOGIC_IB_IBCC_LINKCMD_ACTIVE; + break; + + default: + ret = -EINVAL; + qib_dev_err(dd, "bad linkcmd req 0x%x\n", val >> 16); + goto bail; + } + switch (val & 0xffff) { + case IB_LINKINITCMD_NOP: + licmd = 0; + break; + + case IB_LINKINITCMD_POLL: + licmd = QLOGIC_IB_IBCC_LINKINITCMD_POLL; + break; + + case IB_LINKINITCMD_SLEEP: + licmd = QLOGIC_IB_IBCC_LINKINITCMD_SLEEP; + break; + + case IB_LINKINITCMD_DISABLE: + licmd = QLOGIC_IB_IBCC_LINKINITCMD_DISABLE; + break; + + default: + ret = -EINVAL; + qib_dev_err(dd, "bad linkinitcmd req 0x%x\n", + val & 0xffff); + goto bail; + } + qib_set_ib_6120_lstate(ppd, lcmd, licmd); + goto bail; + + case QIB_IB_CFG_HRTBT: + ret = -EINVAL; + break; + + default: + ret = -EINVAL; + } +bail: + return ret; +} + +static int qib_6120_set_loopback(struct qib_pportdata *ppd, const char *what) +{ + int ret = 0; + if (!strncmp(what, "ibc", 3)) { + ppd->dd->cspec->ibcctrl |= SYM_MASK(IBCCtrl, Loopback); + qib_devinfo(ppd->dd->pcidev, "Enabling IB%u:%u IBC loopback\n", + ppd->dd->unit, ppd->port); + } else if (!strncmp(what, "off", 3)) { + ppd->dd->cspec->ibcctrl &= ~SYM_MASK(IBCCtrl, Loopback); + qib_devinfo(ppd->dd->pcidev, "Disabling IB%u:%u IBC loopback " + "(normal)\n", ppd->dd->unit, ppd->port); + } else + ret = -EINVAL; + if (!ret) { + qib_write_kreg(ppd->dd, kr_ibcctrl, ppd->dd->cspec->ibcctrl); + qib_write_kreg(ppd->dd, kr_scratch, 0); + } + return ret; +} + +static void pma_6120_timer(unsigned long data) +{ + struct qib_pportdata *ppd = (struct qib_pportdata *)data; + struct qib_chip_specific *cs = ppd->dd->cspec; + struct qib_ibport *ibp = &ppd->ibport_data; + unsigned long flags; + + spin_lock_irqsave(&ibp->lock, flags); + if (cs->pma_sample_status == IB_PMA_SAMPLE_STATUS_STARTED) { + cs->pma_sample_status = IB_PMA_SAMPLE_STATUS_RUNNING; + qib_snapshot_counters(ppd, &cs->sword, &cs->rword, + &cs->spkts, &cs->rpkts, &cs->xmit_wait); + mod_timer(&cs->pma_timer, + jiffies + usecs_to_jiffies(ibp->pma_sample_interval)); + } else if (cs->pma_sample_status == IB_PMA_SAMPLE_STATUS_RUNNING) { + u64 ta, tb, tc, td, te; + + cs->pma_sample_status = IB_PMA_SAMPLE_STATUS_DONE; + qib_snapshot_counters(ppd, &ta, &tb, &tc, &td, &te); + + cs->sword = ta - cs->sword; + cs->rword = tb - cs->rword; + cs->spkts = tc - cs->spkts; + cs->rpkts = td - cs->rpkts; + cs->xmit_wait = te - cs->xmit_wait; + } + spin_unlock_irqrestore(&ibp->lock, flags); +} + +/* + * Note that the caller has the ibp->lock held. + */ +static void qib_set_cntr_6120_sample(struct qib_pportdata *ppd, u32 intv, + u32 start) +{ + struct qib_chip_specific *cs = ppd->dd->cspec; + + if (start && intv) { + cs->pma_sample_status = IB_PMA_SAMPLE_STATUS_STARTED; + mod_timer(&cs->pma_timer, jiffies + usecs_to_jiffies(start)); + } else if (intv) { + cs->pma_sample_status = IB_PMA_SAMPLE_STATUS_RUNNING; + qib_snapshot_counters(ppd, &cs->sword, &cs->rword, + &cs->spkts, &cs->rpkts, &cs->xmit_wait); + mod_timer(&cs->pma_timer, jiffies + usecs_to_jiffies(intv)); + } else { + cs->pma_sample_status = IB_PMA_SAMPLE_STATUS_DONE; + cs->sword = 0; + cs->rword = 0; + cs->spkts = 0; + cs->rpkts = 0; + cs->xmit_wait = 0; + } +} + +static u32 qib_6120_iblink_state(u64 ibcs) +{ + u32 state = (u32)SYM_FIELD(ibcs, IBCStatus, LinkState); + + switch (state) { + case IB_6120_L_STATE_INIT: + state = IB_PORT_INIT; + break; + case IB_6120_L_STATE_ARM: + state = IB_PORT_ARMED; + break; + case IB_6120_L_STATE_ACTIVE: + /* fall through */ + case IB_6120_L_STATE_ACT_DEFER: + state = IB_PORT_ACTIVE; + break; + default: /* fall through */ + case IB_6120_L_STATE_DOWN: + state = IB_PORT_DOWN; + break; + } + return state; +} + +/* returns the IBTA port state, rather than the IBC link training state */ +static u8 qib_6120_phys_portstate(u64 ibcs) +{ + u8 state = (u8)SYM_FIELD(ibcs, IBCStatus, LinkTrainingState); + return qib_6120_physportstate[state]; +} + +static int qib_6120_ib_updown(struct qib_pportdata *ppd, int ibup, u64 ibcs) +{ + unsigned long flags; + + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags &= ~QIBL_IB_FORCE_NOTIFY; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + + if (ibup) { + if (ppd->dd->cspec->ibdeltainprog) { + ppd->dd->cspec->ibdeltainprog = 0; + ppd->dd->cspec->ibsymdelta += + read_6120_creg32(ppd->dd, cr_ibsymbolerr) - + ppd->dd->cspec->ibsymsnap; + ppd->dd->cspec->iblnkerrdelta += + read_6120_creg32(ppd->dd, cr_iblinkerrrecov) - + ppd->dd->cspec->iblnkerrsnap; + } + qib_hol_init(ppd); + } else { + ppd->dd->cspec->lli_counter = 0; + if (!ppd->dd->cspec->ibdeltainprog) { + ppd->dd->cspec->ibdeltainprog = 1; + ppd->dd->cspec->ibsymsnap = + read_6120_creg32(ppd->dd, cr_ibsymbolerr); + ppd->dd->cspec->iblnkerrsnap = + read_6120_creg32(ppd->dd, cr_iblinkerrrecov); + } + qib_hol_down(ppd); + } + + qib_6120_setup_setextled(ppd, ibup); + + return 0; +} + +/* Does read/modify/write to appropriate registers to + * set output and direction bits selected by mask. + * these are in their canonical postions (e.g. lsb of + * dir will end up in D48 of extctrl on existing chips). + * returns contents of GP Inputs. + */ +static int gpio_6120_mod(struct qib_devdata *dd, u32 out, u32 dir, u32 mask) +{ + u64 read_val, new_out; + unsigned long flags; + + if (mask) { + /* some bits being written, lock access to GPIO */ + dir &= mask; + out &= mask; + spin_lock_irqsave(&dd->cspec->gpio_lock, flags); + dd->cspec->extctrl &= ~((u64)mask << SYM_LSB(EXTCtrl, GPIOOe)); + dd->cspec->extctrl |= ((u64) dir << SYM_LSB(EXTCtrl, GPIOOe)); + new_out = (dd->cspec->gpio_out & ~mask) | out; + + qib_write_kreg(dd, kr_extctrl, dd->cspec->extctrl); + qib_write_kreg(dd, kr_gpio_out, new_out); + dd->cspec->gpio_out = new_out; + spin_unlock_irqrestore(&dd->cspec->gpio_lock, flags); + } + /* + * It is unlikely that a read at this time would get valid + * data on a pin whose direction line was set in the same + * call to this function. We include the read here because + * that allows us to potentially combine a change on one pin with + * a read on another, and because the old code did something like + * this. + */ + read_val = qib_read_kreg64(dd, kr_extstatus); + return SYM_FIELD(read_val, EXTStatus, GPIOIn); +} + +/* + * Read fundamental info we need to use the chip. These are + * the registers that describe chip capabilities, and are + * saved in shadow registers. + */ +static void get_6120_chip_params(struct qib_devdata *dd) +{ + u64 val; + u32 piobufs; + int mtu; + + dd->uregbase = qib_read_kreg32(dd, kr_userregbase); + + dd->rcvtidcnt = qib_read_kreg32(dd, kr_rcvtidcnt); + dd->rcvtidbase = qib_read_kreg32(dd, kr_rcvtidbase); + dd->rcvegrbase = qib_read_kreg32(dd, kr_rcvegrbase); + dd->palign = qib_read_kreg32(dd, kr_palign); + dd->piobufbase = qib_read_kreg64(dd, kr_sendpiobufbase); + dd->pio2k_bufbase = dd->piobufbase & 0xffffffff; + + dd->rcvhdrcnt = qib_read_kreg32(dd, kr_rcvegrcnt); + + val = qib_read_kreg64(dd, kr_sendpiosize); + dd->piosize2k = val & ~0U; + dd->piosize4k = val >> 32; + + mtu = ib_mtu_enum_to_int(qib_ibmtu); + if (mtu == -1) + mtu = QIB_DEFAULT_MTU; + dd->pport->ibmtu = (u32)mtu; + + val = qib_read_kreg64(dd, kr_sendpiobufcnt); + dd->piobcnt2k = val & ~0U; + dd->piobcnt4k = val >> 32; + /* these may be adjusted in init_chip_wc_pat() */ + dd->pio2kbase = (u32 __iomem *) + (((char __iomem *)dd->kregbase) + dd->pio2k_bufbase); + if (dd->piobcnt4k) { + dd->pio4kbase = (u32 __iomem *) + (((char __iomem *) dd->kregbase) + + (dd->piobufbase >> 32)); + /* + * 4K buffers take 2 pages; we use roundup just to be + * paranoid; we calculate it once here, rather than on + * ever buf allocate + */ + dd->align4k = ALIGN(dd->piosize4k, dd->palign); + } + + piobufs = dd->piobcnt4k + dd->piobcnt2k; + + dd->pioavregs = ALIGN(piobufs, sizeof(u64) * BITS_PER_BYTE / 2) / + (sizeof(u64) * BITS_PER_BYTE / 2); +} + +/* + * The chip base addresses in cspec and cpspec have to be set + * after possible init_chip_wc_pat(), rather than in + * get_6120_chip_params(), so split out as separate function + */ +static void set_6120_baseaddrs(struct qib_devdata *dd) +{ + u32 cregbase; + cregbase = qib_read_kreg32(dd, kr_counterregbase); + dd->cspec->cregbase = (u64 __iomem *) + ((char __iomem *) dd->kregbase + cregbase); + + dd->egrtidbase = (u64 __iomem *) + ((char __iomem *) dd->kregbase + dd->rcvegrbase); +} + +/* + * Write the final few registers that depend on some of the + * init setup. Done late in init, just before bringing up + * the serdes. + */ +static int qib_late_6120_initreg(struct qib_devdata *dd) +{ + int ret = 0; + u64 val; + + qib_write_kreg(dd, kr_rcvhdrentsize, dd->rcvhdrentsize); + qib_write_kreg(dd, kr_rcvhdrsize, dd->rcvhdrsize); + qib_write_kreg(dd, kr_rcvhdrcnt, dd->rcvhdrcnt); + qib_write_kreg(dd, kr_sendpioavailaddr, dd->pioavailregs_phys); + val = qib_read_kreg64(dd, kr_sendpioavailaddr); + if (val != dd->pioavailregs_phys) { + qib_dev_err(dd, "Catastrophic software error, " + "SendPIOAvailAddr written as %lx, " + "read back as %llx\n", + (unsigned long) dd->pioavailregs_phys, + (unsigned long long) val); + ret = -EINVAL; + } + return ret; +} + +static int init_6120_variables(struct qib_devdata *dd) +{ + int ret = 0; + struct qib_pportdata *ppd; + u32 sbufs; + + ppd = (struct qib_pportdata *)(dd + 1); + dd->pport = ppd; + dd->num_pports = 1; + + dd->cspec = (struct qib_chip_specific *)(ppd + dd->num_pports); + ppd->cpspec = NULL; /* not used in this chip */ + + spin_lock_init(&dd->cspec->kernel_tid_lock); + spin_lock_init(&dd->cspec->user_tid_lock); + spin_lock_init(&dd->cspec->rcvmod_lock); + spin_lock_init(&dd->cspec->gpio_lock); + + /* we haven't yet set QIB_PRESENT, so use read directly */ + dd->revision = readq(&dd->kregbase[kr_revision]); + + if ((dd->revision & 0xffffffffU) == 0xffffffffU) { + qib_dev_err(dd, "Revision register read failure, " + "giving up initialization\n"); + ret = -ENODEV; + goto bail; + } + dd->flags |= QIB_PRESENT; /* now register routines work */ + + dd->majrev = (u8) SYM_FIELD(dd->revision, Revision_R, + ChipRevMajor); + dd->minrev = (u8) SYM_FIELD(dd->revision, Revision_R, + ChipRevMinor); + + get_6120_chip_params(dd); + pe_boardname(dd); /* fill in boardname */ + + /* + * GPIO bits for TWSI data and clock, + * used for serial EEPROM. + */ + dd->gpio_sda_num = _QIB_GPIO_SDA_NUM; + dd->gpio_scl_num = _QIB_GPIO_SCL_NUM; + dd->twsi_eeprom_dev = QIB_TWSI_NO_DEV; + + if (qib_unordered_wc()) + dd->flags |= QIB_PIO_FLUSH_WC; + + /* + * EEPROM error log 0 is TXE Parity errors. 1 is RXE Parity. + * 2 is Some Misc, 3 is reserved for future. + */ + dd->eep_st_masks[0].hwerrs_to_log = HWE_MASK(TXEMemParityErr); + + /* Ignore errors in PIO/PBC on systems with unordered write-combining */ + if (qib_unordered_wc()) + dd->eep_st_masks[0].hwerrs_to_log &= ~TXE_PIO_PARITY; + + dd->eep_st_masks[1].hwerrs_to_log = HWE_MASK(RXEMemParityErr); + + dd->eep_st_masks[2].errs_to_log = ERR_MASK(ResetNegated); + + qib_init_pportdata(ppd, dd, 0, 1); + ppd->link_width_supported = IB_WIDTH_1X | IB_WIDTH_4X; + ppd->link_speed_supported = QIB_IB_SDR; + ppd->link_width_enabled = IB_WIDTH_4X; + ppd->link_speed_enabled = ppd->link_speed_supported; + /* these can't change for this chip, so set once */ + ppd->link_width_active = ppd->link_width_enabled; + ppd->link_speed_active = ppd->link_speed_enabled; + ppd->vls_supported = IB_VL_VL0; + ppd->vls_operational = ppd->vls_supported; + + dd->rcvhdrentsize = QIB_RCVHDR_ENTSIZE; + dd->rcvhdrsize = QIB_DFLT_RCVHDRSIZE; + dd->rhf_offset = 0; + + /* we always allocate at least 2048 bytes for eager buffers */ + ret = ib_mtu_enum_to_int(qib_ibmtu); + dd->rcvegrbufsize = ret != -1 ? max(ret, 2048) : QIB_DEFAULT_MTU; + + qib_6120_tidtemplate(dd); + + /* + * We can request a receive interrupt for 1 or + * more packets from current offset. For now, we set this + * up for a single packet. + */ + dd->rhdrhead_intr_off = 1ULL << 32; + + /* setup the stats timer; the add_timer is done at end of init */ + init_timer(&dd->stats_timer); + dd->stats_timer.function = qib_get_6120_faststats; + dd->stats_timer.data = (unsigned long) dd; + + init_timer(&dd->cspec->pma_timer); + dd->cspec->pma_timer.function = pma_6120_timer; + dd->cspec->pma_timer.data = (unsigned long) ppd; + + dd->ureg_align = qib_read_kreg32(dd, kr_palign); + + dd->piosize2kmax_dwords = dd->piosize2k >> 2; + qib_6120_config_ctxts(dd); + qib_set_ctxtcnt(dd); + + if (qib_wc_pat) { + ret = init_chip_wc_pat(dd, 0); + if (ret) + goto bail; + } + set_6120_baseaddrs(dd); /* set chip access pointers now */ + + ret = 0; + if (qib_mini_init) + goto bail; + + qib_num_cfg_vls = 1; /* if any 6120's, only one VL */ + + ret = qib_create_ctxts(dd); + init_6120_cntrnames(dd); + + /* use all of 4KB buffers for the kernel, otherwise 16 */ + sbufs = dd->piobcnt4k ? dd->piobcnt4k : 16; + + dd->lastctxt_piobuf = dd->piobcnt2k + dd->piobcnt4k - sbufs; + dd->pbufsctxt = dd->lastctxt_piobuf / + (dd->cfgctxts - dd->first_user_ctxt); + + if (ret) + goto bail; +bail: + return ret; +} + +/* + * For this chip, we want to use the same buffer every time + * when we are trying to bring the link up (they are always VL15 + * packets). At that link state the packet should always go out immediately + * (or at least be discarded at the tx interface if the link is down). + * If it doesn't, and the buffer isn't available, that means some other + * sender has gotten ahead of us, and is preventing our packet from going + * out. In that case, we flush all packets, and try again. If that still + * fails, we fail the request, and hope things work the next time around. + * + * We don't need very complicated heuristics on whether the packet had + * time to go out or not, since even at SDR 1X, it goes out in very short + * time periods, covered by the chip reads done here and as part of the + * flush. + */ +static u32 __iomem *get_6120_link_buf(struct qib_pportdata *ppd, u32 *bnum) +{ + u32 __iomem *buf; + u32 lbuf = ppd->dd->piobcnt2k + ppd->dd->piobcnt4k - 1; + + /* + * always blip to get avail list updated, since it's almost + * always needed, and is fairly cheap. + */ + sendctrl_6120_mod(ppd->dd->pport, QIB_SENDCTRL_AVAIL_BLIP); + qib_read_kreg64(ppd->dd, kr_scratch); /* extra chip flush */ + buf = qib_getsendbuf_range(ppd->dd, bnum, lbuf, lbuf); + if (buf) + goto done; + + sendctrl_6120_mod(ppd, QIB_SENDCTRL_DISARM_ALL | QIB_SENDCTRL_FLUSH | + QIB_SENDCTRL_AVAIL_BLIP); + ppd->dd->upd_pio_shadow = 1; /* update our idea of what's busy */ + qib_read_kreg64(ppd->dd, kr_scratch); /* extra chip flush */ + buf = qib_getsendbuf_range(ppd->dd, bnum, lbuf, lbuf); +done: + return buf; +} + +static u32 __iomem *qib_6120_getsendbuf(struct qib_pportdata *ppd, u64 pbc, + u32 *pbufnum) +{ + u32 first, last, plen = pbc & QIB_PBC_LENGTH_MASK; + struct qib_devdata *dd = ppd->dd; + u32 __iomem *buf; + + if (((pbc >> 32) & PBC_6120_VL15_SEND_CTRL) && + !(ppd->lflags & (QIBL_IB_AUTONEG_INPROG | QIBL_LINKACTIVE))) + buf = get_6120_link_buf(ppd, pbufnum); + else { + + if ((plen + 1) > dd->piosize2kmax_dwords) + first = dd->piobcnt2k; + else + first = 0; + /* try 4k if all 2k busy, so same last for both sizes */ + last = dd->piobcnt2k + dd->piobcnt4k - 1; + buf = qib_getsendbuf_range(dd, pbufnum, first, last); + } + return buf; +} + +static int init_sdma_6120_regs(struct qib_pportdata *ppd) +{ + return -ENODEV; +} + +static u16 qib_sdma_6120_gethead(struct qib_pportdata *ppd) +{ + return 0; +} + +static int qib_sdma_6120_busy(struct qib_pportdata *ppd) +{ + return 0; +} + +static void qib_sdma_update_6120_tail(struct qib_pportdata *ppd, u16 tail) +{ +} + +static void qib_6120_sdma_sendctrl(struct qib_pportdata *ppd, unsigned op) +{ +} + +static void qib_sdma_set_6120_desc_cnt(struct qib_pportdata *ppd, unsigned cnt) +{ +} + +/* + * the pbc doesn't need a VL15 indicator, but we need it for link_buf. + * The chip ignores the bit if set. + */ +static u32 qib_6120_setpbc_control(struct qib_pportdata *ppd, u32 plen, + u8 srate, u8 vl) +{ + return vl == 15 ? PBC_6120_VL15_SEND_CTRL : 0; +} + +static void qib_6120_initvl15_bufs(struct qib_devdata *dd) +{ +} + +static void qib_6120_init_ctxt(struct qib_ctxtdata *rcd) +{ + rcd->rcvegrcnt = rcd->dd->rcvhdrcnt; + rcd->rcvegr_tid_base = rcd->ctxt * rcd->rcvegrcnt; +} + +static void qib_6120_txchk_change(struct qib_devdata *dd, u32 start, + u32 len, u32 avail, struct qib_ctxtdata *rcd) +{ +} + +static void writescratch(struct qib_devdata *dd, u32 val) +{ + (void) qib_write_kreg(dd, kr_scratch, val); +} + +static int qib_6120_tempsense_rd(struct qib_devdata *dd, int regnum) +{ + return -ENXIO; +} + +/* Dummy function, as 6120 boards never disable EEPROM Write */ +static int qib_6120_eeprom_wen(struct qib_devdata *dd, int wen) +{ + return 1; +} + +/** + * qib_init_iba6120_funcs - set up the chip-specific function pointers + * @pdev: pci_dev of the qlogic_ib device + * @ent: pci_device_id matching this chip + * + * This is global, and is called directly at init to set up the + * chip-specific function pointers for later use. + * + * It also allocates/partially-inits the qib_devdata struct for + * this device. + */ +struct qib_devdata *qib_init_iba6120_funcs(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct qib_devdata *dd; + int ret; + +#ifndef CONFIG_PCI_MSI + qib_early_err(&pdev->dev, "QLogic PCIE device 0x%x cannot " + "work if CONFIG_PCI_MSI is not enabled\n", + ent->device); + dd = ERR_PTR(-ENODEV); + goto bail; +#endif + + dd = qib_alloc_devdata(pdev, sizeof(struct qib_pportdata) + + sizeof(struct qib_chip_specific)); + if (IS_ERR(dd)) + goto bail; + + dd->f_bringup_serdes = qib_6120_bringup_serdes; + dd->f_cleanup = qib_6120_setup_cleanup; + dd->f_clear_tids = qib_6120_clear_tids; + dd->f_free_irq = qib_6120_free_irq; + dd->f_get_base_info = qib_6120_get_base_info; + dd->f_get_msgheader = qib_6120_get_msgheader; + dd->f_getsendbuf = qib_6120_getsendbuf; + dd->f_gpio_mod = gpio_6120_mod; + dd->f_eeprom_wen = qib_6120_eeprom_wen; + dd->f_hdrqempty = qib_6120_hdrqempty; + dd->f_ib_updown = qib_6120_ib_updown; + dd->f_init_ctxt = qib_6120_init_ctxt; + dd->f_initvl15_bufs = qib_6120_initvl15_bufs; + dd->f_intr_fallback = qib_6120_nointr_fallback; + dd->f_late_initreg = qib_late_6120_initreg; + dd->f_setpbc_control = qib_6120_setpbc_control; + dd->f_portcntr = qib_portcntr_6120; + dd->f_put_tid = (dd->minrev >= 2) ? + qib_6120_put_tid_2 : + qib_6120_put_tid; + dd->f_quiet_serdes = qib_6120_quiet_serdes; + dd->f_rcvctrl = rcvctrl_6120_mod; + dd->f_read_cntrs = qib_read_6120cntrs; + dd->f_read_portcntrs = qib_read_6120portcntrs; + dd->f_reset = qib_6120_setup_reset; + dd->f_init_sdma_regs = init_sdma_6120_regs; + dd->f_sdma_busy = qib_sdma_6120_busy; + dd->f_sdma_gethead = qib_sdma_6120_gethead; + dd->f_sdma_sendctrl = qib_6120_sdma_sendctrl; + dd->f_sdma_set_desc_cnt = qib_sdma_set_6120_desc_cnt; + dd->f_sdma_update_tail = qib_sdma_update_6120_tail; + dd->f_sendctrl = sendctrl_6120_mod; + dd->f_set_armlaunch = qib_set_6120_armlaunch; + dd->f_set_cntr_sample = qib_set_cntr_6120_sample; + dd->f_iblink_state = qib_6120_iblink_state; + dd->f_ibphys_portstate = qib_6120_phys_portstate; + dd->f_get_ib_cfg = qib_6120_get_ib_cfg; + dd->f_set_ib_cfg = qib_6120_set_ib_cfg; + dd->f_set_ib_loopback = qib_6120_set_loopback; + dd->f_set_intr_state = qib_6120_set_intr_state; + dd->f_setextled = qib_6120_setup_setextled; + dd->f_txchk_change = qib_6120_txchk_change; + dd->f_update_usrhead = qib_update_6120_usrhead; + dd->f_wantpiobuf_intr = qib_wantpiobuf_6120_intr; + dd->f_xgxs_reset = qib_6120_xgxs_reset; + dd->f_writescratch = writescratch; + dd->f_tempsense_rd = qib_6120_tempsense_rd; + /* + * Do remaining pcie setup and save pcie values in dd. + * Any error printing is already done by the init code. + * On return, we have the chip mapped and accessible, + * but chip registers are not set up until start of + * init_6120_variables. + */ + ret = qib_pcie_ddinit(dd, pdev, ent); + if (ret < 0) + goto bail_free; + + /* initialize chip-specific variables */ + ret = init_6120_variables(dd); + if (ret) + goto bail_cleanup; + + if (qib_mini_init) + goto bail; + +#ifndef CONFIG_PCI_MSI + qib_dev_err(dd, "PCI_MSI not configured, NO interrupts\n"); +#endif + + if (qib_pcie_params(dd, 8, NULL, NULL)) + qib_dev_err(dd, "Failed to setup PCIe or interrupts; " + "continuing anyway\n"); + dd->cspec->irq = pdev->irq; /* save IRQ */ + + /* clear diagctrl register, in case diags were running and crashed */ + qib_write_kreg(dd, kr_hwdiagctrl, 0); + + if (qib_read_kreg64(dd, kr_hwerrstatus) & + QLOGIC_IB_HWE_SERDESPLLFAILED) + qib_write_kreg(dd, kr_hwerrclear, + QLOGIC_IB_HWE_SERDESPLLFAILED); + + /* setup interrupt handler (interrupt type handled above) */ + qib_setup_6120_interrupt(dd); + /* Note that qpn_mask is set by qib_6120_config_ctxts() first */ + qib_6120_init_hwerrors(dd); + + goto bail; + +bail_cleanup: + qib_pcie_ddcleanup(dd); +bail_free: + qib_free_devdata(dd); + dd = ERR_PTR(ret); +bail: + return dd; +} diff --git a/drivers/infiniband/hw/qib/qib_iba7220.c b/drivers/infiniband/hw/qib/qib_iba7220.c new file mode 100644 index 000000000000..6fd8d74e7392 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_iba7220.c @@ -0,0 +1,4618 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation. + * All rights reserved. + * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +/* + * This file contains all of the code that is specific to the + * QLogic_IB 7220 chip (except that specific to the SerDes) + */ + +#include +#include +#include +#include +#include + +#include "qib.h" +#include "qib_7220.h" + +static void qib_setup_7220_setextled(struct qib_pportdata *, u32); +static void qib_7220_handle_hwerrors(struct qib_devdata *, char *, size_t); +static void sendctrl_7220_mod(struct qib_pportdata *ppd, u32 op); +static u32 qib_7220_iblink_state(u64); +static u8 qib_7220_phys_portstate(u64); +static void qib_sdma_update_7220_tail(struct qib_pportdata *, u16); +static void qib_set_ib_7220_lstate(struct qib_pportdata *, u16, u16); + +/* + * This file contains almost all the chip-specific register information and + * access functions for the QLogic QLogic_IB 7220 PCI-Express chip, with the + * exception of SerDes support, which in in qib_sd7220.c. + */ + +/* Below uses machine-generated qib_chipnum_regs.h file */ +#define KREG_IDX(regname) (QIB_7220_##regname##_OFFS / sizeof(u64)) + +/* Use defines to tie machine-generated names to lower-case names */ +#define kr_control KREG_IDX(Control) +#define kr_counterregbase KREG_IDX(CntrRegBase) +#define kr_errclear KREG_IDX(ErrClear) +#define kr_errmask KREG_IDX(ErrMask) +#define kr_errstatus KREG_IDX(ErrStatus) +#define kr_extctrl KREG_IDX(EXTCtrl) +#define kr_extstatus KREG_IDX(EXTStatus) +#define kr_gpio_clear KREG_IDX(GPIOClear) +#define kr_gpio_mask KREG_IDX(GPIOMask) +#define kr_gpio_out KREG_IDX(GPIOOut) +#define kr_gpio_status KREG_IDX(GPIOStatus) +#define kr_hrtbt_guid KREG_IDX(HRTBT_GUID) +#define kr_hwdiagctrl KREG_IDX(HwDiagCtrl) +#define kr_hwerrclear KREG_IDX(HwErrClear) +#define kr_hwerrmask KREG_IDX(HwErrMask) +#define kr_hwerrstatus KREG_IDX(HwErrStatus) +#define kr_ibcctrl KREG_IDX(IBCCtrl) +#define kr_ibcddrctrl KREG_IDX(IBCDDRCtrl) +#define kr_ibcddrstatus KREG_IDX(IBCDDRStatus) +#define kr_ibcstatus KREG_IDX(IBCStatus) +#define kr_ibserdesctrl KREG_IDX(IBSerDesCtrl) +#define kr_intclear KREG_IDX(IntClear) +#define kr_intmask KREG_IDX(IntMask) +#define kr_intstatus KREG_IDX(IntStatus) +#define kr_ncmodectrl KREG_IDX(IBNCModeCtrl) +#define kr_palign KREG_IDX(PageAlign) +#define kr_partitionkey KREG_IDX(RcvPartitionKey) +#define kr_portcnt KREG_IDX(PortCnt) +#define kr_rcvbthqp KREG_IDX(RcvBTHQP) +#define kr_rcvctrl KREG_IDX(RcvCtrl) +#define kr_rcvegrbase KREG_IDX(RcvEgrBase) +#define kr_rcvegrcnt KREG_IDX(RcvEgrCnt) +#define kr_rcvhdrcnt KREG_IDX(RcvHdrCnt) +#define kr_rcvhdrentsize KREG_IDX(RcvHdrEntSize) +#define kr_rcvhdrsize KREG_IDX(RcvHdrSize) +#define kr_rcvpktledcnt KREG_IDX(RcvPktLEDCnt) +#define kr_rcvtidbase KREG_IDX(RcvTIDBase) +#define kr_rcvtidcnt KREG_IDX(RcvTIDCnt) +#define kr_revision KREG_IDX(Revision) +#define kr_scratch KREG_IDX(Scratch) +#define kr_sendbuffererror KREG_IDX(SendBufErr0) +#define kr_sendctrl KREG_IDX(SendCtrl) +#define kr_senddmabase KREG_IDX(SendDmaBase) +#define kr_senddmabufmask0 KREG_IDX(SendDmaBufMask0) +#define kr_senddmabufmask1 (KREG_IDX(SendDmaBufMask0) + 1) +#define kr_senddmabufmask2 (KREG_IDX(SendDmaBufMask0) + 2) +#define kr_senddmahead KREG_IDX(SendDmaHead) +#define kr_senddmaheadaddr KREG_IDX(SendDmaHeadAddr) +#define kr_senddmalengen KREG_IDX(SendDmaLenGen) +#define kr_senddmastatus KREG_IDX(SendDmaStatus) +#define kr_senddmatail KREG_IDX(SendDmaTail) +#define kr_sendpioavailaddr KREG_IDX(SendBufAvailAddr) +#define kr_sendpiobufbase KREG_IDX(SendBufBase) +#define kr_sendpiobufcnt KREG_IDX(SendBufCnt) +#define kr_sendpiosize KREG_IDX(SendBufSize) +#define kr_sendregbase KREG_IDX(SendRegBase) +#define kr_userregbase KREG_IDX(UserRegBase) +#define kr_xgxs_cfg KREG_IDX(XGXSCfg) + +/* These must only be written via qib_write_kreg_ctxt() */ +#define kr_rcvhdraddr KREG_IDX(RcvHdrAddr0) +#define kr_rcvhdrtailaddr KREG_IDX(RcvHdrTailAddr0) + + +#define CREG_IDX(regname) ((QIB_7220_##regname##_OFFS - \ + QIB_7220_LBIntCnt_OFFS) / sizeof(u64)) + +#define cr_badformat CREG_IDX(RxVersionErrCnt) +#define cr_erricrc CREG_IDX(RxICRCErrCnt) +#define cr_errlink CREG_IDX(RxLinkMalformCnt) +#define cr_errlpcrc CREG_IDX(RxLPCRCErrCnt) +#define cr_errpkey CREG_IDX(RxPKeyMismatchCnt) +#define cr_rcvflowctrl_err CREG_IDX(RxFlowCtrlViolCnt) +#define cr_err_rlen CREG_IDX(RxLenErrCnt) +#define cr_errslen CREG_IDX(TxLenErrCnt) +#define cr_errtidfull CREG_IDX(RxTIDFullErrCnt) +#define cr_errtidvalid CREG_IDX(RxTIDValidErrCnt) +#define cr_errvcrc CREG_IDX(RxVCRCErrCnt) +#define cr_ibstatuschange CREG_IDX(IBStatusChangeCnt) +#define cr_lbint CREG_IDX(LBIntCnt) +#define cr_invalidrlen CREG_IDX(RxMaxMinLenErrCnt) +#define cr_invalidslen CREG_IDX(TxMaxMinLenErrCnt) +#define cr_lbflowstall CREG_IDX(LBFlowStallCnt) +#define cr_pktrcv CREG_IDX(RxDataPktCnt) +#define cr_pktrcvflowctrl CREG_IDX(RxFlowPktCnt) +#define cr_pktsend CREG_IDX(TxDataPktCnt) +#define cr_pktsendflow CREG_IDX(TxFlowPktCnt) +#define cr_portovfl CREG_IDX(RxP0HdrEgrOvflCnt) +#define cr_rcvebp CREG_IDX(RxEBPCnt) +#define cr_rcvovfl CREG_IDX(RxBufOvflCnt) +#define cr_senddropped CREG_IDX(TxDroppedPktCnt) +#define cr_sendstall CREG_IDX(TxFlowStallCnt) +#define cr_sendunderrun CREG_IDX(TxUnderrunCnt) +#define cr_wordrcv CREG_IDX(RxDwordCnt) +#define cr_wordsend CREG_IDX(TxDwordCnt) +#define cr_txunsupvl CREG_IDX(TxUnsupVLErrCnt) +#define cr_rxdroppkt CREG_IDX(RxDroppedPktCnt) +#define cr_iblinkerrrecov CREG_IDX(IBLinkErrRecoveryCnt) +#define cr_iblinkdown CREG_IDX(IBLinkDownedCnt) +#define cr_ibsymbolerr CREG_IDX(IBSymbolErrCnt) +#define cr_vl15droppedpkt CREG_IDX(RxVL15DroppedPktCnt) +#define cr_rxotherlocalphyerr CREG_IDX(RxOtherLocalPhyErrCnt) +#define cr_excessbufferovfl CREG_IDX(ExcessBufferOvflCnt) +#define cr_locallinkintegrityerr CREG_IDX(LocalLinkIntegrityErrCnt) +#define cr_rxvlerr CREG_IDX(RxVlErrCnt) +#define cr_rxdlidfltr CREG_IDX(RxDlidFltrCnt) +#define cr_psstat CREG_IDX(PSStat) +#define cr_psstart CREG_IDX(PSStart) +#define cr_psinterval CREG_IDX(PSInterval) +#define cr_psrcvdatacount CREG_IDX(PSRcvDataCount) +#define cr_psrcvpktscount CREG_IDX(PSRcvPktsCount) +#define cr_psxmitdatacount CREG_IDX(PSXmitDataCount) +#define cr_psxmitpktscount CREG_IDX(PSXmitPktsCount) +#define cr_psxmitwaitcount CREG_IDX(PSXmitWaitCount) +#define cr_txsdmadesc CREG_IDX(TxSDmaDescCnt) +#define cr_pcieretrydiag CREG_IDX(PcieRetryBufDiagQwordCnt) + +#define SYM_RMASK(regname, fldname) ((u64) \ + QIB_7220_##regname##_##fldname##_RMASK) +#define SYM_MASK(regname, fldname) ((u64) \ + QIB_7220_##regname##_##fldname##_RMASK << \ + QIB_7220_##regname##_##fldname##_LSB) +#define SYM_LSB(regname, fldname) (QIB_7220_##regname##_##fldname##_LSB) +#define SYM_FIELD(value, regname, fldname) ((u64) \ + (((value) >> SYM_LSB(regname, fldname)) & \ + SYM_RMASK(regname, fldname))) +#define ERR_MASK(fldname) SYM_MASK(ErrMask, fldname##Mask) +#define HWE_MASK(fldname) SYM_MASK(HwErrMask, fldname##Mask) + +/* ibcctrl bits */ +#define QLOGIC_IB_IBCC_LINKINITCMD_DISABLE 1 +/* cycle through TS1/TS2 till OK */ +#define QLOGIC_IB_IBCC_LINKINITCMD_POLL 2 +/* wait for TS1, then go on */ +#define QLOGIC_IB_IBCC_LINKINITCMD_SLEEP 3 +#define QLOGIC_IB_IBCC_LINKINITCMD_SHIFT 16 + +#define QLOGIC_IB_IBCC_LINKCMD_DOWN 1 /* move to 0x11 */ +#define QLOGIC_IB_IBCC_LINKCMD_ARMED 2 /* move to 0x21 */ +#define QLOGIC_IB_IBCC_LINKCMD_ACTIVE 3 /* move to 0x31 */ + +#define BLOB_7220_IBCHG 0x81 + +/* + * We could have a single register get/put routine, that takes a group type, + * but this is somewhat clearer and cleaner. It also gives us some error + * checking. 64 bit register reads should always work, but are inefficient + * on opteron (the northbridge always generates 2 separate HT 32 bit reads), + * so we use kreg32 wherever possible. User register and counter register + * reads are always 32 bit reads, so only one form of those routines. + */ + +/** + * qib_read_ureg32 - read 32-bit virtualized per-context register + * @dd: device + * @regno: register number + * @ctxt: context number + * + * Return the contents of a register that is virtualized to be per context. + * Returns -1 on errors (not distinguishable from valid contents at + * runtime; we may add a separate error variable at some point). + */ +static inline u32 qib_read_ureg32(const struct qib_devdata *dd, + enum qib_ureg regno, int ctxt) +{ + if (!dd->kregbase || !(dd->flags & QIB_PRESENT)) + return 0; + + if (dd->userbase) + return readl(regno + (u64 __iomem *) + ((char __iomem *)dd->userbase + + dd->ureg_align * ctxt)); + else + return readl(regno + (u64 __iomem *) + (dd->uregbase + + (char __iomem *)dd->kregbase + + dd->ureg_align * ctxt)); +} + +/** + * qib_write_ureg - write 32-bit virtualized per-context register + * @dd: device + * @regno: register number + * @value: value + * @ctxt: context + * + * Write the contents of a register that is virtualized to be per context. + */ +static inline void qib_write_ureg(const struct qib_devdata *dd, + enum qib_ureg regno, u64 value, int ctxt) +{ + u64 __iomem *ubase; + + if (dd->userbase) + ubase = (u64 __iomem *) + ((char __iomem *) dd->userbase + + dd->ureg_align * ctxt); + else + ubase = (u64 __iomem *) + (dd->uregbase + + (char __iomem *) dd->kregbase + + dd->ureg_align * ctxt); + + if (dd->kregbase && (dd->flags & QIB_PRESENT)) + writeq(value, &ubase[regno]); +} + +/** + * qib_write_kreg_ctxt - write a device's per-ctxt 64-bit kernel register + * @dd: the qlogic_ib device + * @regno: the register number to write + * @ctxt: the context containing the register + * @value: the value to write + */ +static inline void qib_write_kreg_ctxt(const struct qib_devdata *dd, + const u16 regno, unsigned ctxt, + u64 value) +{ + qib_write_kreg(dd, regno + ctxt, value); +} + +static inline void write_7220_creg(const struct qib_devdata *dd, + u16 regno, u64 value) +{ + if (dd->cspec->cregbase && (dd->flags & QIB_PRESENT)) + writeq(value, &dd->cspec->cregbase[regno]); +} + +static inline u64 read_7220_creg(const struct qib_devdata *dd, u16 regno) +{ + if (!dd->cspec->cregbase || !(dd->flags & QIB_PRESENT)) + return 0; + return readq(&dd->cspec->cregbase[regno]); +} + +static inline u32 read_7220_creg32(const struct qib_devdata *dd, u16 regno) +{ + if (!dd->cspec->cregbase || !(dd->flags & QIB_PRESENT)) + return 0; + return readl(&dd->cspec->cregbase[regno]); +} + +/* kr_revision bits */ +#define QLOGIC_IB_R_EMULATORREV_MASK ((1ULL << 22) - 1) +#define QLOGIC_IB_R_EMULATORREV_SHIFT 40 + +/* kr_control bits */ +#define QLOGIC_IB_C_RESET (1U << 7) + +/* kr_intstatus, kr_intclear, kr_intmask bits */ +#define QLOGIC_IB_I_RCVURG_MASK ((1ULL << 17) - 1) +#define QLOGIC_IB_I_RCVURG_SHIFT 32 +#define QLOGIC_IB_I_RCVAVAIL_MASK ((1ULL << 17) - 1) +#define QLOGIC_IB_I_RCVAVAIL_SHIFT 0 +#define QLOGIC_IB_I_SERDESTRIMDONE (1ULL << 27) + +#define QLOGIC_IB_C_FREEZEMODE 0x00000002 +#define QLOGIC_IB_C_LINKENABLE 0x00000004 + +#define QLOGIC_IB_I_SDMAINT 0x8000000000000000ULL +#define QLOGIC_IB_I_SDMADISABLED 0x4000000000000000ULL +#define QLOGIC_IB_I_ERROR 0x0000000080000000ULL +#define QLOGIC_IB_I_SPIOSENT 0x0000000040000000ULL +#define QLOGIC_IB_I_SPIOBUFAVAIL 0x0000000020000000ULL +#define QLOGIC_IB_I_GPIO 0x0000000010000000ULL + +/* variables for sanity checking interrupt and errors */ +#define QLOGIC_IB_I_BITSEXTANT \ + (QLOGIC_IB_I_SDMAINT | QLOGIC_IB_I_SDMADISABLED | \ + (QLOGIC_IB_I_RCVURG_MASK << QLOGIC_IB_I_RCVURG_SHIFT) | \ + (QLOGIC_IB_I_RCVAVAIL_MASK << \ + QLOGIC_IB_I_RCVAVAIL_SHIFT) | \ + QLOGIC_IB_I_ERROR | QLOGIC_IB_I_SPIOSENT | \ + QLOGIC_IB_I_SPIOBUFAVAIL | QLOGIC_IB_I_GPIO | \ + QLOGIC_IB_I_SERDESTRIMDONE) + +#define IB_HWE_BITSEXTANT \ + (HWE_MASK(RXEMemParityErr) | \ + HWE_MASK(TXEMemParityErr) | \ + (QLOGIC_IB_HWE_PCIEMEMPARITYERR_MASK << \ + QLOGIC_IB_HWE_PCIEMEMPARITYERR_SHIFT) | \ + QLOGIC_IB_HWE_PCIE1PLLFAILED | \ + QLOGIC_IB_HWE_PCIE0PLLFAILED | \ + QLOGIC_IB_HWE_PCIEPOISONEDTLP | \ + QLOGIC_IB_HWE_PCIECPLTIMEOUT | \ + QLOGIC_IB_HWE_PCIEBUSPARITYXTLH | \ + QLOGIC_IB_HWE_PCIEBUSPARITYXADM | \ + QLOGIC_IB_HWE_PCIEBUSPARITYRADM | \ + HWE_MASK(PowerOnBISTFailed) | \ + QLOGIC_IB_HWE_COREPLL_FBSLIP | \ + QLOGIC_IB_HWE_COREPLL_RFSLIP | \ + QLOGIC_IB_HWE_SERDESPLLFAILED | \ + HWE_MASK(IBCBusToSPCParityErr) | \ + HWE_MASK(IBCBusFromSPCParityErr) | \ + QLOGIC_IB_HWE_PCIECPLDATAQUEUEERR | \ + QLOGIC_IB_HWE_PCIECPLHDRQUEUEERR | \ + QLOGIC_IB_HWE_SDMAMEMREADERR | \ + QLOGIC_IB_HWE_CLK_UC_PLLNOTLOCKED | \ + QLOGIC_IB_HWE_PCIESERDESQ0PCLKNOTDETECT | \ + QLOGIC_IB_HWE_PCIESERDESQ1PCLKNOTDETECT | \ + QLOGIC_IB_HWE_PCIESERDESQ2PCLKNOTDETECT | \ + QLOGIC_IB_HWE_PCIESERDESQ3PCLKNOTDETECT | \ + QLOGIC_IB_HWE_DDSRXEQMEMORYPARITYERR | \ + QLOGIC_IB_HWE_IB_UC_MEMORYPARITYERR | \ + QLOGIC_IB_HWE_PCIE_UC_OCT0MEMORYPARITYERR | \ + QLOGIC_IB_HWE_PCIE_UC_OCT1MEMORYPARITYERR) + +#define IB_E_BITSEXTANT \ + (ERR_MASK(RcvFormatErr) | ERR_MASK(RcvVCRCErr) | \ + ERR_MASK(RcvICRCErr) | ERR_MASK(RcvMinPktLenErr) | \ + ERR_MASK(RcvMaxPktLenErr) | ERR_MASK(RcvLongPktLenErr) | \ + ERR_MASK(RcvShortPktLenErr) | ERR_MASK(RcvUnexpectedCharErr) | \ + ERR_MASK(RcvUnsupportedVLErr) | ERR_MASK(RcvEBPErr) | \ + ERR_MASK(RcvIBFlowErr) | ERR_MASK(RcvBadVersionErr) | \ + ERR_MASK(RcvEgrFullErr) | ERR_MASK(RcvHdrFullErr) | \ + ERR_MASK(RcvBadTidErr) | ERR_MASK(RcvHdrLenErr) | \ + ERR_MASK(RcvHdrErr) | ERR_MASK(RcvIBLostLinkErr) | \ + ERR_MASK(SendSpecialTriggerErr) | \ + ERR_MASK(SDmaDisabledErr) | ERR_MASK(SendMinPktLenErr) | \ + ERR_MASK(SendMaxPktLenErr) | ERR_MASK(SendUnderRunErr) | \ + ERR_MASK(SendPktLenErr) | ERR_MASK(SendDroppedSmpPktErr) | \ + ERR_MASK(SendDroppedDataPktErr) | \ + ERR_MASK(SendPioArmLaunchErr) | \ + ERR_MASK(SendUnexpectedPktNumErr) | \ + ERR_MASK(SendUnsupportedVLErr) | ERR_MASK(SendBufMisuseErr) | \ + ERR_MASK(SDmaGenMismatchErr) | ERR_MASK(SDmaOutOfBoundErr) | \ + ERR_MASK(SDmaTailOutOfBoundErr) | ERR_MASK(SDmaBaseErr) | \ + ERR_MASK(SDma1stDescErr) | ERR_MASK(SDmaRpyTagErr) | \ + ERR_MASK(SDmaDwEnErr) | ERR_MASK(SDmaMissingDwErr) | \ + ERR_MASK(SDmaUnexpDataErr) | \ + ERR_MASK(IBStatusChanged) | ERR_MASK(InvalidAddrErr) | \ + ERR_MASK(ResetNegated) | ERR_MASK(HardwareErr) | \ + ERR_MASK(SDmaDescAddrMisalignErr) | \ + ERR_MASK(InvalidEEPCmd)) + +/* kr_hwerrclear, kr_hwerrmask, kr_hwerrstatus, bits */ +#define QLOGIC_IB_HWE_PCIEMEMPARITYERR_MASK 0x00000000000000ffULL +#define QLOGIC_IB_HWE_PCIEMEMPARITYERR_SHIFT 0 +#define QLOGIC_IB_HWE_PCIEPOISONEDTLP 0x0000000010000000ULL +#define QLOGIC_IB_HWE_PCIECPLTIMEOUT 0x0000000020000000ULL +#define QLOGIC_IB_HWE_PCIEBUSPARITYXTLH 0x0000000040000000ULL +#define QLOGIC_IB_HWE_PCIEBUSPARITYXADM 0x0000000080000000ULL +#define QLOGIC_IB_HWE_PCIEBUSPARITYRADM 0x0000000100000000ULL +#define QLOGIC_IB_HWE_COREPLL_FBSLIP 0x0080000000000000ULL +#define QLOGIC_IB_HWE_COREPLL_RFSLIP 0x0100000000000000ULL +#define QLOGIC_IB_HWE_PCIE1PLLFAILED 0x0400000000000000ULL +#define QLOGIC_IB_HWE_PCIE0PLLFAILED 0x0800000000000000ULL +#define QLOGIC_IB_HWE_SERDESPLLFAILED 0x1000000000000000ULL +/* specific to this chip */ +#define QLOGIC_IB_HWE_PCIECPLDATAQUEUEERR 0x0000000000000040ULL +#define QLOGIC_IB_HWE_PCIECPLHDRQUEUEERR 0x0000000000000080ULL +#define QLOGIC_IB_HWE_SDMAMEMREADERR 0x0000000010000000ULL +#define QLOGIC_IB_HWE_CLK_UC_PLLNOTLOCKED 0x2000000000000000ULL +#define QLOGIC_IB_HWE_PCIESERDESQ0PCLKNOTDETECT 0x0100000000000000ULL +#define QLOGIC_IB_HWE_PCIESERDESQ1PCLKNOTDETECT 0x0200000000000000ULL +#define QLOGIC_IB_HWE_PCIESERDESQ2PCLKNOTDETECT 0x0400000000000000ULL +#define QLOGIC_IB_HWE_PCIESERDESQ3PCLKNOTDETECT 0x0800000000000000ULL +#define QLOGIC_IB_HWE_DDSRXEQMEMORYPARITYERR 0x0000008000000000ULL +#define QLOGIC_IB_HWE_IB_UC_MEMORYPARITYERR 0x0000004000000000ULL +#define QLOGIC_IB_HWE_PCIE_UC_OCT0MEMORYPARITYERR 0x0000001000000000ULL +#define QLOGIC_IB_HWE_PCIE_UC_OCT1MEMORYPARITYERR 0x0000002000000000ULL + +#define IBA7220_IBCC_LINKCMD_SHIFT 19 + +/* kr_ibcddrctrl bits */ +#define IBA7220_IBC_DLIDLMC_MASK 0xFFFFFFFFUL +#define IBA7220_IBC_DLIDLMC_SHIFT 32 + +#define IBA7220_IBC_HRTBT_MASK (SYM_RMASK(IBCDDRCtrl, HRTBT_AUTO) | \ + SYM_RMASK(IBCDDRCtrl, HRTBT_ENB)) +#define IBA7220_IBC_HRTBT_SHIFT SYM_LSB(IBCDDRCtrl, HRTBT_ENB) + +#define IBA7220_IBC_LANE_REV_SUPPORTED (1<<8) +#define IBA7220_IBC_LREV_MASK 1 +#define IBA7220_IBC_LREV_SHIFT 8 +#define IBA7220_IBC_RXPOL_MASK 1 +#define IBA7220_IBC_RXPOL_SHIFT 7 +#define IBA7220_IBC_WIDTH_SHIFT 5 +#define IBA7220_IBC_WIDTH_MASK 0x3 +#define IBA7220_IBC_WIDTH_1X_ONLY (0 << IBA7220_IBC_WIDTH_SHIFT) +#define IBA7220_IBC_WIDTH_4X_ONLY (1 << IBA7220_IBC_WIDTH_SHIFT) +#define IBA7220_IBC_WIDTH_AUTONEG (2 << IBA7220_IBC_WIDTH_SHIFT) +#define IBA7220_IBC_SPEED_AUTONEG (1 << 1) +#define IBA7220_IBC_SPEED_SDR (1 << 2) +#define IBA7220_IBC_SPEED_DDR (1 << 3) +#define IBA7220_IBC_SPEED_AUTONEG_MASK (0x7 << 1) +#define IBA7220_IBC_IBTA_1_2_MASK (1) + +/* kr_ibcddrstatus */ +/* link latency shift is 0, don't bother defining */ +#define IBA7220_DDRSTAT_LINKLAT_MASK 0x3ffffff + +/* kr_extstatus bits */ +#define QLOGIC_IB_EXTS_FREQSEL 0x2 +#define QLOGIC_IB_EXTS_SERDESSEL 0x4 +#define QLOGIC_IB_EXTS_MEMBIST_ENDTEST 0x0000000000004000 +#define QLOGIC_IB_EXTS_MEMBIST_DISABLED 0x0000000000008000 + +/* kr_xgxsconfig bits */ +#define QLOGIC_IB_XGXS_RESET 0x5ULL +#define QLOGIC_IB_XGXS_FC_SAFE (1ULL << 63) + +/* kr_rcvpktledcnt */ +#define IBA7220_LEDBLINK_ON_SHIFT 32 /* 4ns period on after packet */ +#define IBA7220_LEDBLINK_OFF_SHIFT 0 /* 4ns period off before next on */ + +#define _QIB_GPIO_SDA_NUM 1 +#define _QIB_GPIO_SCL_NUM 0 +#define QIB_TWSI_EEPROM_DEV 0xA2 /* All Production 7220 cards. */ +#define QIB_TWSI_TEMP_DEV 0x98 + +/* HW counter clock is at 4nsec */ +#define QIB_7220_PSXMITWAIT_CHECK_RATE 4000 + +#define IBA7220_R_INTRAVAIL_SHIFT 17 +#define IBA7220_R_PKEY_DIS_SHIFT 34 +#define IBA7220_R_TAILUPD_SHIFT 35 +#define IBA7220_R_CTXTCFG_SHIFT 36 + +#define IBA7220_HDRHEAD_PKTINT_SHIFT 32 /* interrupt cnt in upper 32 bits */ + +/* + * the size bits give us 2^N, in KB units. 0 marks as invalid, + * and 7 is reserved. We currently use only 2KB and 4KB + */ +#define IBA7220_TID_SZ_SHIFT 37 /* shift to 3bit size selector */ +#define IBA7220_TID_SZ_2K (1UL << IBA7220_TID_SZ_SHIFT) /* 2KB */ +#define IBA7220_TID_SZ_4K (2UL << IBA7220_TID_SZ_SHIFT) /* 4KB */ +#define IBA7220_TID_PA_SHIFT 11U /* TID addr in chip stored w/o low bits */ +#define PBC_7220_VL15_SEND (1ULL << 63) /* pbc; VL15, no credit check */ +#define PBC_7220_VL15_SEND_CTRL (1ULL << 31) /* control version of same */ + +#define AUTONEG_TRIES 5 /* sequential retries to negotiate DDR */ + +/* packet rate matching delay multiplier */ +static u8 rate_to_delay[2][2] = { + /* 1x, 4x */ + { 8, 2 }, /* SDR */ + { 4, 1 } /* DDR */ +}; + +static u8 ib_rate_to_delay[IB_RATE_120_GBPS + 1] = { + [IB_RATE_2_5_GBPS] = 8, + [IB_RATE_5_GBPS] = 4, + [IB_RATE_10_GBPS] = 2, + [IB_RATE_20_GBPS] = 1 +}; + +#define IBA7220_LINKSPEED_SHIFT SYM_LSB(IBCStatus, LinkSpeedActive) +#define IBA7220_LINKWIDTH_SHIFT SYM_LSB(IBCStatus, LinkWidthActive) + +/* link training states, from IBC */ +#define IB_7220_LT_STATE_DISABLED 0x00 +#define IB_7220_LT_STATE_LINKUP 0x01 +#define IB_7220_LT_STATE_POLLACTIVE 0x02 +#define IB_7220_LT_STATE_POLLQUIET 0x03 +#define IB_7220_LT_STATE_SLEEPDELAY 0x04 +#define IB_7220_LT_STATE_SLEEPQUIET 0x05 +#define IB_7220_LT_STATE_CFGDEBOUNCE 0x08 +#define IB_7220_LT_STATE_CFGRCVFCFG 0x09 +#define IB_7220_LT_STATE_CFGWAITRMT 0x0a +#define IB_7220_LT_STATE_CFGIDLE 0x0b +#define IB_7220_LT_STATE_RECOVERRETRAIN 0x0c +#define IB_7220_LT_STATE_RECOVERWAITRMT 0x0e +#define IB_7220_LT_STATE_RECOVERIDLE 0x0f + +/* link state machine states from IBC */ +#define IB_7220_L_STATE_DOWN 0x0 +#define IB_7220_L_STATE_INIT 0x1 +#define IB_7220_L_STATE_ARM 0x2 +#define IB_7220_L_STATE_ACTIVE 0x3 +#define IB_7220_L_STATE_ACT_DEFER 0x4 + +static const u8 qib_7220_physportstate[0x20] = { + [IB_7220_LT_STATE_DISABLED] = IB_PHYSPORTSTATE_DISABLED, + [IB_7220_LT_STATE_LINKUP] = IB_PHYSPORTSTATE_LINKUP, + [IB_7220_LT_STATE_POLLACTIVE] = IB_PHYSPORTSTATE_POLL, + [IB_7220_LT_STATE_POLLQUIET] = IB_PHYSPORTSTATE_POLL, + [IB_7220_LT_STATE_SLEEPDELAY] = IB_PHYSPORTSTATE_SLEEP, + [IB_7220_LT_STATE_SLEEPQUIET] = IB_PHYSPORTSTATE_SLEEP, + [IB_7220_LT_STATE_CFGDEBOUNCE] = + IB_PHYSPORTSTATE_CFG_TRAIN, + [IB_7220_LT_STATE_CFGRCVFCFG] = + IB_PHYSPORTSTATE_CFG_TRAIN, + [IB_7220_LT_STATE_CFGWAITRMT] = + IB_PHYSPORTSTATE_CFG_TRAIN, + [IB_7220_LT_STATE_CFGIDLE] = IB_PHYSPORTSTATE_CFG_TRAIN, + [IB_7220_LT_STATE_RECOVERRETRAIN] = + IB_PHYSPORTSTATE_LINK_ERR_RECOVER, + [IB_7220_LT_STATE_RECOVERWAITRMT] = + IB_PHYSPORTSTATE_LINK_ERR_RECOVER, + [IB_7220_LT_STATE_RECOVERIDLE] = + IB_PHYSPORTSTATE_LINK_ERR_RECOVER, + [0x10] = IB_PHYSPORTSTATE_CFG_TRAIN, + [0x11] = IB_PHYSPORTSTATE_CFG_TRAIN, + [0x12] = IB_PHYSPORTSTATE_CFG_TRAIN, + [0x13] = IB_PHYSPORTSTATE_CFG_TRAIN, + [0x14] = IB_PHYSPORTSTATE_CFG_TRAIN, + [0x15] = IB_PHYSPORTSTATE_CFG_TRAIN, + [0x16] = IB_PHYSPORTSTATE_CFG_TRAIN, + [0x17] = IB_PHYSPORTSTATE_CFG_TRAIN +}; + +int qib_special_trigger; +module_param_named(special_trigger, qib_special_trigger, int, S_IRUGO); +MODULE_PARM_DESC(special_trigger, "Enable SpecialTrigger arm/launch"); + +#define IBCBUSFRSPCPARITYERR HWE_MASK(IBCBusFromSPCParityErr) +#define IBCBUSTOSPCPARITYERR HWE_MASK(IBCBusToSPCParityErr) + +#define SYM_MASK_BIT(regname, fldname, bit) ((u64) \ + (1ULL << (SYM_LSB(regname, fldname) + (bit)))) + +#define TXEMEMPARITYERR_PIOBUF \ + SYM_MASK_BIT(HwErrMask, TXEMemParityErrMask, 0) +#define TXEMEMPARITYERR_PIOPBC \ + SYM_MASK_BIT(HwErrMask, TXEMemParityErrMask, 1) +#define TXEMEMPARITYERR_PIOLAUNCHFIFO \ + SYM_MASK_BIT(HwErrMask, TXEMemParityErrMask, 2) + +#define RXEMEMPARITYERR_RCVBUF \ + SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 0) +#define RXEMEMPARITYERR_LOOKUPQ \ + SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 1) +#define RXEMEMPARITYERR_EXPTID \ + SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 2) +#define RXEMEMPARITYERR_EAGERTID \ + SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 3) +#define RXEMEMPARITYERR_FLAGBUF \ + SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 4) +#define RXEMEMPARITYERR_DATAINFO \ + SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 5) +#define RXEMEMPARITYERR_HDRINFO \ + SYM_MASK_BIT(HwErrMask, RXEMemParityErrMask, 6) + +/* 7220 specific hardware errors... */ +static const struct qib_hwerror_msgs qib_7220_hwerror_msgs[] = { + /* generic hardware errors */ + QLOGIC_IB_HWE_MSG(IBCBUSFRSPCPARITYERR, "QIB2IB Parity"), + QLOGIC_IB_HWE_MSG(IBCBUSTOSPCPARITYERR, "IB2QIB Parity"), + + QLOGIC_IB_HWE_MSG(TXEMEMPARITYERR_PIOBUF, + "TXE PIOBUF Memory Parity"), + QLOGIC_IB_HWE_MSG(TXEMEMPARITYERR_PIOPBC, + "TXE PIOPBC Memory Parity"), + QLOGIC_IB_HWE_MSG(TXEMEMPARITYERR_PIOLAUNCHFIFO, + "TXE PIOLAUNCHFIFO Memory Parity"), + + QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_RCVBUF, + "RXE RCVBUF Memory Parity"), + QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_LOOKUPQ, + "RXE LOOKUPQ Memory Parity"), + QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_EAGERTID, + "RXE EAGERTID Memory Parity"), + QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_EXPTID, + "RXE EXPTID Memory Parity"), + QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_FLAGBUF, + "RXE FLAGBUF Memory Parity"), + QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_DATAINFO, + "RXE DATAINFO Memory Parity"), + QLOGIC_IB_HWE_MSG(RXEMEMPARITYERR_HDRINFO, + "RXE HDRINFO Memory Parity"), + + /* chip-specific hardware errors */ + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIEPOISONEDTLP, + "PCIe Poisoned TLP"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIECPLTIMEOUT, + "PCIe completion timeout"), + /* + * In practice, it's unlikely wthat we'll see PCIe PLL, or bus + * parity or memory parity error failures, because most likely we + * won't be able to talk to the core of the chip. Nonetheless, we + * might see them, if they are in parts of the PCIe core that aren't + * essential. + */ + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIE1PLLFAILED, + "PCIePLL1"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIE0PLLFAILED, + "PCIePLL0"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIEBUSPARITYXTLH, + "PCIe XTLH core parity"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIEBUSPARITYXADM, + "PCIe ADM TX core parity"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIEBUSPARITYRADM, + "PCIe ADM RX core parity"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_SERDESPLLFAILED, + "SerDes PLL"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIECPLDATAQUEUEERR, + "PCIe cpl header queue"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIECPLHDRQUEUEERR, + "PCIe cpl data queue"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_SDMAMEMREADERR, + "Send DMA memory read"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_CLK_UC_PLLNOTLOCKED, + "uC PLL clock not locked"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIESERDESQ0PCLKNOTDETECT, + "PCIe serdes Q0 no clock"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIESERDESQ1PCLKNOTDETECT, + "PCIe serdes Q1 no clock"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIESERDESQ2PCLKNOTDETECT, + "PCIe serdes Q2 no clock"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIESERDESQ3PCLKNOTDETECT, + "PCIe serdes Q3 no clock"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_DDSRXEQMEMORYPARITYERR, + "DDS RXEQ memory parity"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_IB_UC_MEMORYPARITYERR, + "IB uC memory parity"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIE_UC_OCT0MEMORYPARITYERR, + "PCIe uC oct0 memory parity"), + QLOGIC_IB_HWE_MSG(QLOGIC_IB_HWE_PCIE_UC_OCT1MEMORYPARITYERR, + "PCIe uC oct1 memory parity"), +}; + +#define RXE_PARITY (RXEMEMPARITYERR_EAGERTID|RXEMEMPARITYERR_EXPTID) + +#define QLOGIC_IB_E_PKTERRS (\ + ERR_MASK(SendPktLenErr) | \ + ERR_MASK(SendDroppedDataPktErr) | \ + ERR_MASK(RcvVCRCErr) | \ + ERR_MASK(RcvICRCErr) | \ + ERR_MASK(RcvShortPktLenErr) | \ + ERR_MASK(RcvEBPErr)) + +/* Convenience for decoding Send DMA errors */ +#define QLOGIC_IB_E_SDMAERRS ( \ + ERR_MASK(SDmaGenMismatchErr) | \ + ERR_MASK(SDmaOutOfBoundErr) | \ + ERR_MASK(SDmaTailOutOfBoundErr) | ERR_MASK(SDmaBaseErr) | \ + ERR_MASK(SDma1stDescErr) | ERR_MASK(SDmaRpyTagErr) | \ + ERR_MASK(SDmaDwEnErr) | ERR_MASK(SDmaMissingDwErr) | \ + ERR_MASK(SDmaUnexpDataErr) | \ + ERR_MASK(SDmaDescAddrMisalignErr) | \ + ERR_MASK(SDmaDisabledErr) | \ + ERR_MASK(SendBufMisuseErr)) + +/* These are all rcv-related errors which we want to count for stats */ +#define E_SUM_PKTERRS \ + (ERR_MASK(RcvHdrLenErr) | ERR_MASK(RcvBadTidErr) | \ + ERR_MASK(RcvBadVersionErr) | ERR_MASK(RcvHdrErr) | \ + ERR_MASK(RcvLongPktLenErr) | ERR_MASK(RcvShortPktLenErr) | \ + ERR_MASK(RcvMaxPktLenErr) | ERR_MASK(RcvMinPktLenErr) | \ + ERR_MASK(RcvFormatErr) | ERR_MASK(RcvUnsupportedVLErr) | \ + ERR_MASK(RcvUnexpectedCharErr) | ERR_MASK(RcvEBPErr)) + +/* These are all send-related errors which we want to count for stats */ +#define E_SUM_ERRS \ + (ERR_MASK(SendPioArmLaunchErr) | ERR_MASK(SendUnexpectedPktNumErr) | \ + ERR_MASK(SendDroppedDataPktErr) | ERR_MASK(SendDroppedSmpPktErr) | \ + ERR_MASK(SendMaxPktLenErr) | ERR_MASK(SendUnsupportedVLErr) | \ + ERR_MASK(SendMinPktLenErr) | ERR_MASK(SendPktLenErr) | \ + ERR_MASK(InvalidAddrErr)) + +/* + * this is similar to E_SUM_ERRS, but can't ignore armlaunch, don't ignore + * errors not related to freeze and cancelling buffers. Can't ignore + * armlaunch because could get more while still cleaning up, and need + * to cancel those as they happen. + */ +#define E_SPKT_ERRS_IGNORE \ + (ERR_MASK(SendDroppedDataPktErr) | ERR_MASK(SendDroppedSmpPktErr) | \ + ERR_MASK(SendMaxPktLenErr) | ERR_MASK(SendMinPktLenErr) | \ + ERR_MASK(SendPktLenErr)) + +/* + * these are errors that can occur when the link changes state while + * a packet is being sent or received. This doesn't cover things + * like EBP or VCRC that can be the result of a sending having the + * link change state, so we receive a "known bad" packet. + */ +#define E_SUM_LINK_PKTERRS \ + (ERR_MASK(SendDroppedDataPktErr) | ERR_MASK(SendDroppedSmpPktErr) | \ + ERR_MASK(SendMinPktLenErr) | ERR_MASK(SendPktLenErr) | \ + ERR_MASK(RcvShortPktLenErr) | ERR_MASK(RcvMinPktLenErr) | \ + ERR_MASK(RcvUnexpectedCharErr)) + +static void autoneg_7220_work(struct work_struct *); +static u32 __iomem *qib_7220_getsendbuf(struct qib_pportdata *, u64, u32 *); + +/* + * Called when we might have an error that is specific to a particular + * PIO buffer, and may need to cancel that buffer, so it can be re-used. + * because we don't need to force the update of pioavail. + */ +static void qib_disarm_7220_senderrbufs(struct qib_pportdata *ppd) +{ + unsigned long sbuf[3]; + struct qib_devdata *dd = ppd->dd; + + /* + * It's possible that sendbuffererror could have bits set; might + * have already done this as a result of hardware error handling. + */ + /* read these before writing errorclear */ + sbuf[0] = qib_read_kreg64(dd, kr_sendbuffererror); + sbuf[1] = qib_read_kreg64(dd, kr_sendbuffererror + 1); + sbuf[2] = qib_read_kreg64(dd, kr_sendbuffererror + 2); + + if (sbuf[0] || sbuf[1] || sbuf[2]) + qib_disarm_piobufs_set(dd, sbuf, + dd->piobcnt2k + dd->piobcnt4k); +} + +static void qib_7220_txe_recover(struct qib_devdata *dd) +{ + qib_devinfo(dd->pcidev, "Recovering from TXE PIO parity error\n"); + qib_disarm_7220_senderrbufs(dd->pport); +} + +/* + * This is called with interrupts disabled and sdma_lock held. + */ +static void qib_7220_sdma_sendctrl(struct qib_pportdata *ppd, unsigned op) +{ + struct qib_devdata *dd = ppd->dd; + u64 set_sendctrl = 0; + u64 clr_sendctrl = 0; + + if (op & QIB_SDMA_SENDCTRL_OP_ENABLE) + set_sendctrl |= SYM_MASK(SendCtrl, SDmaEnable); + else + clr_sendctrl |= SYM_MASK(SendCtrl, SDmaEnable); + + if (op & QIB_SDMA_SENDCTRL_OP_INTENABLE) + set_sendctrl |= SYM_MASK(SendCtrl, SDmaIntEnable); + else + clr_sendctrl |= SYM_MASK(SendCtrl, SDmaIntEnable); + + if (op & QIB_SDMA_SENDCTRL_OP_HALT) + set_sendctrl |= SYM_MASK(SendCtrl, SDmaHalt); + else + clr_sendctrl |= SYM_MASK(SendCtrl, SDmaHalt); + + spin_lock(&dd->sendctrl_lock); + + dd->sendctrl |= set_sendctrl; + dd->sendctrl &= ~clr_sendctrl; + + qib_write_kreg(dd, kr_sendctrl, dd->sendctrl); + qib_write_kreg(dd, kr_scratch, 0); + + spin_unlock(&dd->sendctrl_lock); +} + +static void qib_decode_7220_sdma_errs(struct qib_pportdata *ppd, + u64 err, char *buf, size_t blen) +{ + static const struct { + u64 err; + const char *msg; + } errs[] = { + { ERR_MASK(SDmaGenMismatchErr), + "SDmaGenMismatch" }, + { ERR_MASK(SDmaOutOfBoundErr), + "SDmaOutOfBound" }, + { ERR_MASK(SDmaTailOutOfBoundErr), + "SDmaTailOutOfBound" }, + { ERR_MASK(SDmaBaseErr), + "SDmaBase" }, + { ERR_MASK(SDma1stDescErr), + "SDma1stDesc" }, + { ERR_MASK(SDmaRpyTagErr), + "SDmaRpyTag" }, + { ERR_MASK(SDmaDwEnErr), + "SDmaDwEn" }, + { ERR_MASK(SDmaMissingDwErr), + "SDmaMissingDw" }, + { ERR_MASK(SDmaUnexpDataErr), + "SDmaUnexpData" }, + { ERR_MASK(SDmaDescAddrMisalignErr), + "SDmaDescAddrMisalign" }, + { ERR_MASK(SendBufMisuseErr), + "SendBufMisuse" }, + { ERR_MASK(SDmaDisabledErr), + "SDmaDisabled" }, + }; + int i; + size_t bidx = 0; + + for (i = 0; i < ARRAY_SIZE(errs); i++) { + if (err & errs[i].err) + bidx += scnprintf(buf + bidx, blen - bidx, + "%s ", errs[i].msg); + } +} + +/* + * This is called as part of link down clean up so disarm and flush + * all send buffers so that SMP packets can be sent. + */ +static void qib_7220_sdma_hw_clean_up(struct qib_pportdata *ppd) +{ + /* This will trigger the Abort interrupt */ + sendctrl_7220_mod(ppd, QIB_SENDCTRL_DISARM_ALL | QIB_SENDCTRL_FLUSH | + QIB_SENDCTRL_AVAIL_BLIP); + ppd->dd->upd_pio_shadow = 1; /* update our idea of what's busy */ +} + +static void qib_sdma_7220_setlengen(struct qib_pportdata *ppd) +{ + /* + * Set SendDmaLenGen and clear and set + * the MSB of the generation count to enable generation checking + * and load the internal generation counter. + */ + qib_write_kreg(ppd->dd, kr_senddmalengen, ppd->sdma_descq_cnt); + qib_write_kreg(ppd->dd, kr_senddmalengen, + ppd->sdma_descq_cnt | + (1ULL << QIB_7220_SendDmaLenGen_Generation_MSB)); +} + +static void qib_7220_sdma_hw_start_up(struct qib_pportdata *ppd) +{ + qib_sdma_7220_setlengen(ppd); + qib_sdma_update_7220_tail(ppd, 0); /* Set SendDmaTail */ + ppd->sdma_head_dma[0] = 0; +} + +#define DISABLES_SDMA ( \ + ERR_MASK(SDmaDisabledErr) | \ + ERR_MASK(SDmaBaseErr) | \ + ERR_MASK(SDmaTailOutOfBoundErr) | \ + ERR_MASK(SDmaOutOfBoundErr) | \ + ERR_MASK(SDma1stDescErr) | \ + ERR_MASK(SDmaRpyTagErr) | \ + ERR_MASK(SDmaGenMismatchErr) | \ + ERR_MASK(SDmaDescAddrMisalignErr) | \ + ERR_MASK(SDmaMissingDwErr) | \ + ERR_MASK(SDmaDwEnErr)) + +static void sdma_7220_errors(struct qib_pportdata *ppd, u64 errs) +{ + unsigned long flags; + struct qib_devdata *dd = ppd->dd; + char *msg; + + errs &= QLOGIC_IB_E_SDMAERRS; + + msg = dd->cspec->sdmamsgbuf; + qib_decode_7220_sdma_errs(ppd, errs, msg, sizeof dd->cspec->sdmamsgbuf); + spin_lock_irqsave(&ppd->sdma_lock, flags); + + if (errs & ERR_MASK(SendBufMisuseErr)) { + unsigned long sbuf[3]; + + sbuf[0] = qib_read_kreg64(dd, kr_sendbuffererror); + sbuf[1] = qib_read_kreg64(dd, kr_sendbuffererror + 1); + sbuf[2] = qib_read_kreg64(dd, kr_sendbuffererror + 2); + + qib_dev_err(ppd->dd, + "IB%u:%u SendBufMisuse: %04lx %016lx %016lx\n", + ppd->dd->unit, ppd->port, sbuf[2], sbuf[1], + sbuf[0]); + } + + if (errs & ERR_MASK(SDmaUnexpDataErr)) + qib_dev_err(dd, "IB%u:%u SDmaUnexpData\n", ppd->dd->unit, + ppd->port); + + switch (ppd->sdma_state.current_state) { + case qib_sdma_state_s00_hw_down: + /* not expecting any interrupts */ + break; + + case qib_sdma_state_s10_hw_start_up_wait: + /* handled in intr path */ + break; + + case qib_sdma_state_s20_idle: + /* not expecting any interrupts */ + break; + + case qib_sdma_state_s30_sw_clean_up_wait: + /* not expecting any interrupts */ + break; + + case qib_sdma_state_s40_hw_clean_up_wait: + if (errs & ERR_MASK(SDmaDisabledErr)) + __qib_sdma_process_event(ppd, + qib_sdma_event_e50_hw_cleaned); + break; + + case qib_sdma_state_s50_hw_halt_wait: + /* handled in intr path */ + break; + + case qib_sdma_state_s99_running: + if (errs & DISABLES_SDMA) + __qib_sdma_process_event(ppd, + qib_sdma_event_e7220_err_halted); + break; + } + + spin_unlock_irqrestore(&ppd->sdma_lock, flags); +} + +/* + * Decode the error status into strings, deciding whether to always + * print * it or not depending on "normal packet errors" vs everything + * else. Return 1 if "real" errors, otherwise 0 if only packet + * errors, so caller can decide what to print with the string. + */ +static int qib_decode_7220_err(struct qib_devdata *dd, char *buf, size_t blen, + u64 err) +{ + int iserr = 1; + + *buf = '\0'; + if (err & QLOGIC_IB_E_PKTERRS) { + if (!(err & ~QLOGIC_IB_E_PKTERRS)) + iserr = 0; + if ((err & ERR_MASK(RcvICRCErr)) && + !(err & (ERR_MASK(RcvVCRCErr) | ERR_MASK(RcvEBPErr)))) + strlcat(buf, "CRC ", blen); + if (!iserr) + goto done; + } + if (err & ERR_MASK(RcvHdrLenErr)) + strlcat(buf, "rhdrlen ", blen); + if (err & ERR_MASK(RcvBadTidErr)) + strlcat(buf, "rbadtid ", blen); + if (err & ERR_MASK(RcvBadVersionErr)) + strlcat(buf, "rbadversion ", blen); + if (err & ERR_MASK(RcvHdrErr)) + strlcat(buf, "rhdr ", blen); + if (err & ERR_MASK(SendSpecialTriggerErr)) + strlcat(buf, "sendspecialtrigger ", blen); + if (err & ERR_MASK(RcvLongPktLenErr)) + strlcat(buf, "rlongpktlen ", blen); + if (err & ERR_MASK(RcvMaxPktLenErr)) + strlcat(buf, "rmaxpktlen ", blen); + if (err & ERR_MASK(RcvMinPktLenErr)) + strlcat(buf, "rminpktlen ", blen); + if (err & ERR_MASK(SendMinPktLenErr)) + strlcat(buf, "sminpktlen ", blen); + if (err & ERR_MASK(RcvFormatErr)) + strlcat(buf, "rformaterr ", blen); + if (err & ERR_MASK(RcvUnsupportedVLErr)) + strlcat(buf, "runsupvl ", blen); + if (err & ERR_MASK(RcvUnexpectedCharErr)) + strlcat(buf, "runexpchar ", blen); + if (err & ERR_MASK(RcvIBFlowErr)) + strlcat(buf, "ribflow ", blen); + if (err & ERR_MASK(SendUnderRunErr)) + strlcat(buf, "sunderrun ", blen); + if (err & ERR_MASK(SendPioArmLaunchErr)) + strlcat(buf, "spioarmlaunch ", blen); + if (err & ERR_MASK(SendUnexpectedPktNumErr)) + strlcat(buf, "sunexperrpktnum ", blen); + if (err & ERR_MASK(SendDroppedSmpPktErr)) + strlcat(buf, "sdroppedsmppkt ", blen); + if (err & ERR_MASK(SendMaxPktLenErr)) + strlcat(buf, "smaxpktlen ", blen); + if (err & ERR_MASK(SendUnsupportedVLErr)) + strlcat(buf, "sunsupVL ", blen); + if (err & ERR_MASK(InvalidAddrErr)) + strlcat(buf, "invalidaddr ", blen); + if (err & ERR_MASK(RcvEgrFullErr)) + strlcat(buf, "rcvegrfull ", blen); + if (err & ERR_MASK(RcvHdrFullErr)) + strlcat(buf, "rcvhdrfull ", blen); + if (err & ERR_MASK(IBStatusChanged)) + strlcat(buf, "ibcstatuschg ", blen); + if (err & ERR_MASK(RcvIBLostLinkErr)) + strlcat(buf, "riblostlink ", blen); + if (err & ERR_MASK(HardwareErr)) + strlcat(buf, "hardware ", blen); + if (err & ERR_MASK(ResetNegated)) + strlcat(buf, "reset ", blen); + if (err & QLOGIC_IB_E_SDMAERRS) + qib_decode_7220_sdma_errs(dd->pport, err, buf, blen); + if (err & ERR_MASK(InvalidEEPCmd)) + strlcat(buf, "invalideepromcmd ", blen); +done: + return iserr; +} + +static void reenable_7220_chase(unsigned long opaque) +{ + struct qib_pportdata *ppd = (struct qib_pportdata *)opaque; + ppd->cpspec->chase_timer.expires = 0; + qib_set_ib_7220_lstate(ppd, QLOGIC_IB_IBCC_LINKCMD_DOWN, + QLOGIC_IB_IBCC_LINKINITCMD_POLL); +} + +static void handle_7220_chase(struct qib_pportdata *ppd, u64 ibcst) +{ + u8 ibclt; + u64 tnow; + + ibclt = (u8)SYM_FIELD(ibcst, IBCStatus, LinkTrainingState); + + /* + * Detect and handle the state chase issue, where we can + * get stuck if we are unlucky on timing on both sides of + * the link. If we are, we disable, set a timer, and + * then re-enable. + */ + switch (ibclt) { + case IB_7220_LT_STATE_CFGRCVFCFG: + case IB_7220_LT_STATE_CFGWAITRMT: + case IB_7220_LT_STATE_TXREVLANES: + case IB_7220_LT_STATE_CFGENH: + tnow = get_jiffies_64(); + if (ppd->cpspec->chase_end && + time_after64(tnow, ppd->cpspec->chase_end)) { + ppd->cpspec->chase_end = 0; + qib_set_ib_7220_lstate(ppd, + QLOGIC_IB_IBCC_LINKCMD_DOWN, + QLOGIC_IB_IBCC_LINKINITCMD_DISABLE); + ppd->cpspec->chase_timer.expires = jiffies + + QIB_CHASE_DIS_TIME; + add_timer(&ppd->cpspec->chase_timer); + } else if (!ppd->cpspec->chase_end) + ppd->cpspec->chase_end = tnow + QIB_CHASE_TIME; + break; + + default: + ppd->cpspec->chase_end = 0; + break; + } +} + +static void handle_7220_errors(struct qib_devdata *dd, u64 errs) +{ + char *msg; + u64 ignore_this_time = 0; + u64 iserr = 0; + int log_idx; + struct qib_pportdata *ppd = dd->pport; + u64 mask; + + /* don't report errors that are masked */ + errs &= dd->cspec->errormask; + msg = dd->cspec->emsgbuf; + + /* do these first, they are most important */ + if (errs & ERR_MASK(HardwareErr)) + qib_7220_handle_hwerrors(dd, msg, sizeof dd->cspec->emsgbuf); + else + for (log_idx = 0; log_idx < QIB_EEP_LOG_CNT; ++log_idx) + if (errs & dd->eep_st_masks[log_idx].errs_to_log) + qib_inc_eeprom_err(dd, log_idx, 1); + + if (errs & QLOGIC_IB_E_SDMAERRS) + sdma_7220_errors(ppd, errs); + + if (errs & ~IB_E_BITSEXTANT) + qib_dev_err(dd, "error interrupt with unknown errors " + "%llx set\n", (unsigned long long) + (errs & ~IB_E_BITSEXTANT)); + + if (errs & E_SUM_ERRS) { + qib_disarm_7220_senderrbufs(ppd); + if ((errs & E_SUM_LINK_PKTERRS) && + !(ppd->lflags & QIBL_LINKACTIVE)) { + /* + * This can happen when trying to bring the link + * up, but the IB link changes state at the "wrong" + * time. The IB logic then complains that the packet + * isn't valid. We don't want to confuse people, so + * we just don't print them, except at debug + */ + ignore_this_time = errs & E_SUM_LINK_PKTERRS; + } + } else if ((errs & E_SUM_LINK_PKTERRS) && + !(ppd->lflags & QIBL_LINKACTIVE)) { + /* + * This can happen when SMA is trying to bring the link + * up, but the IB link changes state at the "wrong" time. + * The IB logic then complains that the packet isn't + * valid. We don't want to confuse people, so we just + * don't print them, except at debug + */ + ignore_this_time = errs & E_SUM_LINK_PKTERRS; + } + + qib_write_kreg(dd, kr_errclear, errs); + + errs &= ~ignore_this_time; + if (!errs) + goto done; + + /* + * The ones we mask off are handled specially below + * or above. Also mask SDMADISABLED by default as it + * is too chatty. + */ + mask = ERR_MASK(IBStatusChanged) | + ERR_MASK(RcvEgrFullErr) | ERR_MASK(RcvHdrFullErr) | + ERR_MASK(HardwareErr) | ERR_MASK(SDmaDisabledErr); + + qib_decode_7220_err(dd, msg, sizeof dd->cspec->emsgbuf, errs & ~mask); + + if (errs & E_SUM_PKTERRS) + qib_stats.sps_rcverrs++; + if (errs & E_SUM_ERRS) + qib_stats.sps_txerrs++; + iserr = errs & ~(E_SUM_PKTERRS | QLOGIC_IB_E_PKTERRS | + ERR_MASK(SDmaDisabledErr)); + + if (errs & ERR_MASK(IBStatusChanged)) { + u64 ibcs; + + ibcs = qib_read_kreg64(dd, kr_ibcstatus); + if (!(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) + handle_7220_chase(ppd, ibcs); + + /* Update our picture of width and speed from chip */ + ppd->link_width_active = + ((ibcs >> IBA7220_LINKWIDTH_SHIFT) & 1) ? + IB_WIDTH_4X : IB_WIDTH_1X; + ppd->link_speed_active = + ((ibcs >> IBA7220_LINKSPEED_SHIFT) & 1) ? + QIB_IB_DDR : QIB_IB_SDR; + + /* + * Since going into a recovery state causes the link state + * to go down and since recovery is transitory, it is better + * if we "miss" ever seeing the link training state go into + * recovery (i.e., ignore this transition for link state + * special handling purposes) without updating lastibcstat. + */ + if (qib_7220_phys_portstate(ibcs) != + IB_PHYSPORTSTATE_LINK_ERR_RECOVER) + qib_handle_e_ibstatuschanged(ppd, ibcs); + } + + if (errs & ERR_MASK(ResetNegated)) { + qib_dev_err(dd, "Got reset, requires re-init " + "(unload and reload driver)\n"); + dd->flags &= ~QIB_INITTED; /* needs re-init */ + /* mark as having had error */ + *dd->devstatusp |= QIB_STATUS_HWERROR; + *dd->pport->statusp &= ~QIB_STATUS_IB_CONF; + } + + if (*msg && iserr) + qib_dev_porterr(dd, ppd->port, "%s error\n", msg); + + if (ppd->state_wanted & ppd->lflags) + wake_up_interruptible(&ppd->state_wait); + + /* + * If there were hdrq or egrfull errors, wake up any processes + * waiting in poll. We used to try to check which contexts had + * the overflow, but given the cost of that and the chip reads + * to support it, it's better to just wake everybody up if we + * get an overflow; waiters can poll again if it's not them. + */ + if (errs & (ERR_MASK(RcvEgrFullErr) | ERR_MASK(RcvHdrFullErr))) { + qib_handle_urcv(dd, ~0U); + if (errs & ERR_MASK(RcvEgrFullErr)) + qib_stats.sps_buffull++; + else + qib_stats.sps_hdrfull++; + } +done: + return; +} + +/* enable/disable chip from delivering interrupts */ +static void qib_7220_set_intr_state(struct qib_devdata *dd, u32 enable) +{ + if (enable) { + if (dd->flags & QIB_BADINTR) + return; + qib_write_kreg(dd, kr_intmask, ~0ULL); + /* force re-interrupt of any pending interrupts. */ + qib_write_kreg(dd, kr_intclear, 0ULL); + } else + qib_write_kreg(dd, kr_intmask, 0ULL); +} + +/* + * Try to cleanup as much as possible for anything that might have gone + * wrong while in freeze mode, such as pio buffers being written by user + * processes (causing armlaunch), send errors due to going into freeze mode, + * etc., and try to avoid causing extra interrupts while doing so. + * Forcibly update the in-memory pioavail register copies after cleanup + * because the chip won't do it while in freeze mode (the register values + * themselves are kept correct). + * Make sure that we don't lose any important interrupts by using the chip + * feature that says that writing 0 to a bit in *clear that is set in + * *status will cause an interrupt to be generated again (if allowed by + * the *mask value). + * This is in chip-specific code because of all of the register accesses, + * even though the details are similar on most chips. + */ +static void qib_7220_clear_freeze(struct qib_devdata *dd) +{ + /* disable error interrupts, to avoid confusion */ + qib_write_kreg(dd, kr_errmask, 0ULL); + + /* also disable interrupts; errormask is sometimes overwriten */ + qib_7220_set_intr_state(dd, 0); + + qib_cancel_sends(dd->pport); + + /* clear the freeze, and be sure chip saw it */ + qib_write_kreg(dd, kr_control, dd->control); + qib_read_kreg32(dd, kr_scratch); + + /* force in-memory update now we are out of freeze */ + qib_force_pio_avail_update(dd); + + /* + * force new interrupt if any hwerr, error or interrupt bits are + * still set, and clear "safe" send packet errors related to freeze + * and cancelling sends. Re-enable error interrupts before possible + * force of re-interrupt on pending interrupts. + */ + qib_write_kreg(dd, kr_hwerrclear, 0ULL); + qib_write_kreg(dd, kr_errclear, E_SPKT_ERRS_IGNORE); + qib_write_kreg(dd, kr_errmask, dd->cspec->errormask); + qib_7220_set_intr_state(dd, 1); +} + +/** + * qib_7220_handle_hwerrors - display hardware errors. + * @dd: the qlogic_ib device + * @msg: the output buffer + * @msgl: the size of the output buffer + * + * Use same msg buffer as regular errors to avoid excessive stack + * use. Most hardware errors are catastrophic, but for right now, + * we'll print them and continue. We reuse the same message buffer as + * handle_7220_errors() to avoid excessive stack usage. + */ +static void qib_7220_handle_hwerrors(struct qib_devdata *dd, char *msg, + size_t msgl) +{ + u64 hwerrs; + u32 bits, ctrl; + int isfatal = 0; + char *bitsmsg; + int log_idx; + + hwerrs = qib_read_kreg64(dd, kr_hwerrstatus); + if (!hwerrs) + goto bail; + if (hwerrs == ~0ULL) { + qib_dev_err(dd, "Read of hardware error status failed " + "(all bits set); ignoring\n"); + goto bail; + } + qib_stats.sps_hwerrs++; + + /* + * Always clear the error status register, except MEMBISTFAIL, + * regardless of whether we continue or stop using the chip. + * We want that set so we know it failed, even across driver reload. + * We'll still ignore it in the hwerrmask. We do this partly for + * diagnostics, but also for support. + */ + qib_write_kreg(dd, kr_hwerrclear, + hwerrs & ~HWE_MASK(PowerOnBISTFailed)); + + hwerrs &= dd->cspec->hwerrmask; + + /* We log some errors to EEPROM, check if we have any of those. */ + for (log_idx = 0; log_idx < QIB_EEP_LOG_CNT; ++log_idx) + if (hwerrs & dd->eep_st_masks[log_idx].hwerrs_to_log) + qib_inc_eeprom_err(dd, log_idx, 1); + if (hwerrs & ~(TXEMEMPARITYERR_PIOBUF | TXEMEMPARITYERR_PIOPBC | + RXE_PARITY)) + qib_devinfo(dd->pcidev, "Hardware error: hwerr=0x%llx " + "(cleared)\n", (unsigned long long) hwerrs); + + if (hwerrs & ~IB_HWE_BITSEXTANT) + qib_dev_err(dd, "hwerror interrupt with unknown errors " + "%llx set\n", (unsigned long long) + (hwerrs & ~IB_HWE_BITSEXTANT)); + + if (hwerrs & QLOGIC_IB_HWE_IB_UC_MEMORYPARITYERR) + qib_sd7220_clr_ibpar(dd); + + ctrl = qib_read_kreg32(dd, kr_control); + if ((ctrl & QLOGIC_IB_C_FREEZEMODE) && !dd->diag_client) { + /* + * Parity errors in send memory are recoverable by h/w + * just do housekeeping, exit freeze mode and continue. + */ + if (hwerrs & (TXEMEMPARITYERR_PIOBUF | + TXEMEMPARITYERR_PIOPBC)) { + qib_7220_txe_recover(dd); + hwerrs &= ~(TXEMEMPARITYERR_PIOBUF | + TXEMEMPARITYERR_PIOPBC); + } + if (hwerrs) + isfatal = 1; + else + qib_7220_clear_freeze(dd); + } + + *msg = '\0'; + + if (hwerrs & HWE_MASK(PowerOnBISTFailed)) { + isfatal = 1; + strlcat(msg, "[Memory BIST test failed, " + "InfiniPath hardware unusable]", msgl); + /* ignore from now on, so disable until driver reloaded */ + dd->cspec->hwerrmask &= ~HWE_MASK(PowerOnBISTFailed); + qib_write_kreg(dd, kr_hwerrmask, dd->cspec->hwerrmask); + } + + qib_format_hwerrors(hwerrs, qib_7220_hwerror_msgs, + ARRAY_SIZE(qib_7220_hwerror_msgs), msg, msgl); + + bitsmsg = dd->cspec->bitsmsgbuf; + if (hwerrs & (QLOGIC_IB_HWE_PCIEMEMPARITYERR_MASK << + QLOGIC_IB_HWE_PCIEMEMPARITYERR_SHIFT)) { + bits = (u32) ((hwerrs >> + QLOGIC_IB_HWE_PCIEMEMPARITYERR_SHIFT) & + QLOGIC_IB_HWE_PCIEMEMPARITYERR_MASK); + snprintf(bitsmsg, sizeof dd->cspec->bitsmsgbuf, + "[PCIe Mem Parity Errs %x] ", bits); + strlcat(msg, bitsmsg, msgl); + } + +#define _QIB_PLL_FAIL (QLOGIC_IB_HWE_COREPLL_FBSLIP | \ + QLOGIC_IB_HWE_COREPLL_RFSLIP) + + if (hwerrs & _QIB_PLL_FAIL) { + isfatal = 1; + snprintf(bitsmsg, sizeof dd->cspec->bitsmsgbuf, + "[PLL failed (%llx), InfiniPath hardware unusable]", + (unsigned long long) hwerrs & _QIB_PLL_FAIL); + strlcat(msg, bitsmsg, msgl); + /* ignore from now on, so disable until driver reloaded */ + dd->cspec->hwerrmask &= ~(hwerrs & _QIB_PLL_FAIL); + qib_write_kreg(dd, kr_hwerrmask, dd->cspec->hwerrmask); + } + + if (hwerrs & QLOGIC_IB_HWE_SERDESPLLFAILED) { + /* + * If it occurs, it is left masked since the eternal + * interface is unused. + */ + dd->cspec->hwerrmask &= ~QLOGIC_IB_HWE_SERDESPLLFAILED; + qib_write_kreg(dd, kr_hwerrmask, dd->cspec->hwerrmask); + } + + qib_dev_err(dd, "%s hardware error\n", msg); + + if (isfatal && !dd->diag_client) { + qib_dev_err(dd, "Fatal Hardware Error, no longer" + " usable, SN %.16s\n", dd->serial); + /* + * For /sys status file and user programs to print; if no + * trailing brace is copied, we'll know it was truncated. + */ + if (dd->freezemsg) + snprintf(dd->freezemsg, dd->freezelen, + "{%s}", msg); + qib_disable_after_error(dd); + } +bail:; +} + +/** + * qib_7220_init_hwerrors - enable hardware errors + * @dd: the qlogic_ib device + * + * now that we have finished initializing everything that might reasonably + * cause a hardware error, and cleared those errors bits as they occur, + * we can enable hardware errors in the mask (potentially enabling + * freeze mode), and enable hardware errors as errors (along with + * everything else) in errormask + */ +static void qib_7220_init_hwerrors(struct qib_devdata *dd) +{ + u64 val; + u64 extsval; + + extsval = qib_read_kreg64(dd, kr_extstatus); + + if (!(extsval & (QLOGIC_IB_EXTS_MEMBIST_ENDTEST | + QLOGIC_IB_EXTS_MEMBIST_DISABLED))) + qib_dev_err(dd, "MemBIST did not complete!\n"); + if (extsval & QLOGIC_IB_EXTS_MEMBIST_DISABLED) + qib_devinfo(dd->pcidev, "MemBIST is disabled.\n"); + + val = ~0ULL; /* default to all hwerrors become interrupts, */ + + val &= ~QLOGIC_IB_HWE_IB_UC_MEMORYPARITYERR; + dd->cspec->hwerrmask = val; + + qib_write_kreg(dd, kr_hwerrclear, ~HWE_MASK(PowerOnBISTFailed)); + qib_write_kreg(dd, kr_hwerrmask, dd->cspec->hwerrmask); + + /* clear all */ + qib_write_kreg(dd, kr_errclear, ~0ULL); + /* enable errors that are masked, at least this first time. */ + qib_write_kreg(dd, kr_errmask, ~0ULL); + dd->cspec->errormask = qib_read_kreg64(dd, kr_errmask); + /* clear any interrupts up to this point (ints still not enabled) */ + qib_write_kreg(dd, kr_intclear, ~0ULL); +} + +/* + * Disable and enable the armlaunch error. Used for PIO bandwidth testing + * on chips that are count-based, rather than trigger-based. There is no + * reference counting, but that's also fine, given the intended use. + * Only chip-specific because it's all register accesses + */ +static void qib_set_7220_armlaunch(struct qib_devdata *dd, u32 enable) +{ + if (enable) { + qib_write_kreg(dd, kr_errclear, ERR_MASK(SendPioArmLaunchErr)); + dd->cspec->errormask |= ERR_MASK(SendPioArmLaunchErr); + } else + dd->cspec->errormask &= ~ERR_MASK(SendPioArmLaunchErr); + qib_write_kreg(dd, kr_errmask, dd->cspec->errormask); +} + +/* + * Formerly took parameter in pre-shifted, + * pre-merged form with LinkCmd and LinkInitCmd + * together, and assuming the zero was NOP. + */ +static void qib_set_ib_7220_lstate(struct qib_pportdata *ppd, u16 linkcmd, + u16 linitcmd) +{ + u64 mod_wd; + struct qib_devdata *dd = ppd->dd; + unsigned long flags; + + if (linitcmd == QLOGIC_IB_IBCC_LINKINITCMD_DISABLE) { + /* + * If we are told to disable, note that so link-recovery + * code does not attempt to bring us back up. + */ + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags |= QIBL_IB_LINK_DISABLED; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + } else if (linitcmd || linkcmd == QLOGIC_IB_IBCC_LINKCMD_DOWN) { + /* + * Any other linkinitcmd will lead to LINKDOWN and then + * to INIT (if all is well), so clear flag to let + * link-recovery code attempt to bring us back up. + */ + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags &= ~QIBL_IB_LINK_DISABLED; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + } + + mod_wd = (linkcmd << IBA7220_IBCC_LINKCMD_SHIFT) | + (linitcmd << QLOGIC_IB_IBCC_LINKINITCMD_SHIFT); + + qib_write_kreg(dd, kr_ibcctrl, ppd->cpspec->ibcctrl | mod_wd); + /* write to chip to prevent back-to-back writes of ibc reg */ + qib_write_kreg(dd, kr_scratch, 0); +} + +/* + * All detailed interaction with the SerDes has been moved to qib_sd7220.c + * + * The portion of IBA7220-specific bringup_serdes() that actually deals with + * registers and memory within the SerDes itself is qib_sd7220_init(). + */ + +/** + * qib_7220_bringup_serdes - bring up the serdes + * @ppd: physical port on the qlogic_ib device + */ +static int qib_7220_bringup_serdes(struct qib_pportdata *ppd) +{ + struct qib_devdata *dd = ppd->dd; + u64 val, prev_val, guid, ibc; + int ret = 0; + + /* Put IBC in reset, sends disabled */ + dd->control &= ~QLOGIC_IB_C_LINKENABLE; + qib_write_kreg(dd, kr_control, 0ULL); + + if (qib_compat_ddr_negotiate) { + ppd->cpspec->ibdeltainprog = 1; + ppd->cpspec->ibsymsnap = read_7220_creg32(dd, cr_ibsymbolerr); + ppd->cpspec->iblnkerrsnap = + read_7220_creg32(dd, cr_iblinkerrrecov); + } + + /* flowcontrolwatermark is in units of KBytes */ + ibc = 0x5ULL << SYM_LSB(IBCCtrl, FlowCtrlWaterMark); + /* + * How often flowctrl sent. More or less in usecs; balance against + * watermark value, so that in theory senders always get a flow + * control update in time to not let the IB link go idle. + */ + ibc |= 0x3ULL << SYM_LSB(IBCCtrl, FlowCtrlPeriod); + /* max error tolerance */ + ibc |= 0xfULL << SYM_LSB(IBCCtrl, PhyerrThreshold); + /* use "real" buffer space for */ + ibc |= 4ULL << SYM_LSB(IBCCtrl, CreditScale); + /* IB credit flow control. */ + ibc |= 0xfULL << SYM_LSB(IBCCtrl, OverrunThreshold); + /* + * set initial max size pkt IBC will send, including ICRC; it's the + * PIO buffer size in dwords, less 1; also see qib_set_mtu() + */ + ibc |= ((u64)(ppd->ibmaxlen >> 2) + 1) << SYM_LSB(IBCCtrl, MaxPktLen); + ppd->cpspec->ibcctrl = ibc; /* without linkcmd or linkinitcmd! */ + + /* initially come up waiting for TS1, without sending anything. */ + val = ppd->cpspec->ibcctrl | (QLOGIC_IB_IBCC_LINKINITCMD_DISABLE << + QLOGIC_IB_IBCC_LINKINITCMD_SHIFT); + qib_write_kreg(dd, kr_ibcctrl, val); + + if (!ppd->cpspec->ibcddrctrl) { + /* not on re-init after reset */ + ppd->cpspec->ibcddrctrl = qib_read_kreg64(dd, kr_ibcddrctrl); + + if (ppd->link_speed_enabled == (QIB_IB_SDR | QIB_IB_DDR)) + ppd->cpspec->ibcddrctrl |= + IBA7220_IBC_SPEED_AUTONEG_MASK | + IBA7220_IBC_IBTA_1_2_MASK; + else + ppd->cpspec->ibcddrctrl |= + ppd->link_speed_enabled == QIB_IB_DDR ? + IBA7220_IBC_SPEED_DDR : IBA7220_IBC_SPEED_SDR; + if ((ppd->link_width_enabled & (IB_WIDTH_1X | IB_WIDTH_4X)) == + (IB_WIDTH_1X | IB_WIDTH_4X)) + ppd->cpspec->ibcddrctrl |= IBA7220_IBC_WIDTH_AUTONEG; + else + ppd->cpspec->ibcddrctrl |= + ppd->link_width_enabled == IB_WIDTH_4X ? + IBA7220_IBC_WIDTH_4X_ONLY : + IBA7220_IBC_WIDTH_1X_ONLY; + + /* always enable these on driver reload, not sticky */ + ppd->cpspec->ibcddrctrl |= + IBA7220_IBC_RXPOL_MASK << IBA7220_IBC_RXPOL_SHIFT; + ppd->cpspec->ibcddrctrl |= + IBA7220_IBC_HRTBT_MASK << IBA7220_IBC_HRTBT_SHIFT; + + /* enable automatic lane reversal detection for receive */ + ppd->cpspec->ibcddrctrl |= IBA7220_IBC_LANE_REV_SUPPORTED; + } else + /* write to chip to prevent back-to-back writes of ibc reg */ + qib_write_kreg(dd, kr_scratch, 0); + + qib_write_kreg(dd, kr_ibcddrctrl, ppd->cpspec->ibcddrctrl); + qib_write_kreg(dd, kr_scratch, 0); + + qib_write_kreg(dd, kr_ncmodectrl, 0Ull); + qib_write_kreg(dd, kr_scratch, 0); + + ret = qib_sd7220_init(dd); + + val = qib_read_kreg64(dd, kr_xgxs_cfg); + prev_val = val; + val |= QLOGIC_IB_XGXS_FC_SAFE; + if (val != prev_val) { + qib_write_kreg(dd, kr_xgxs_cfg, val); + qib_read_kreg32(dd, kr_scratch); + } + if (val & QLOGIC_IB_XGXS_RESET) + val &= ~QLOGIC_IB_XGXS_RESET; + if (val != prev_val) + qib_write_kreg(dd, kr_xgxs_cfg, val); + + /* first time through, set port guid */ + if (!ppd->guid) + ppd->guid = dd->base_guid; + guid = be64_to_cpu(ppd->guid); + + qib_write_kreg(dd, kr_hrtbt_guid, guid); + if (!ret) { + dd->control |= QLOGIC_IB_C_LINKENABLE; + qib_write_kreg(dd, kr_control, dd->control); + } else + /* write to chip to prevent back-to-back writes of ibc reg */ + qib_write_kreg(dd, kr_scratch, 0); + return ret; +} + +/** + * qib_7220_quiet_serdes - set serdes to txidle + * @ppd: physical port of the qlogic_ib device + * Called when driver is being unloaded + */ +static void qib_7220_quiet_serdes(struct qib_pportdata *ppd) +{ + u64 val; + struct qib_devdata *dd = ppd->dd; + unsigned long flags; + + /* disable IBC */ + dd->control &= ~QLOGIC_IB_C_LINKENABLE; + qib_write_kreg(dd, kr_control, + dd->control | QLOGIC_IB_C_FREEZEMODE); + + ppd->cpspec->chase_end = 0; + if (ppd->cpspec->chase_timer.data) /* if initted */ + del_timer_sync(&ppd->cpspec->chase_timer); + + if (ppd->cpspec->ibsymdelta || ppd->cpspec->iblnkerrdelta || + ppd->cpspec->ibdeltainprog) { + u64 diagc; + + /* enable counter writes */ + diagc = qib_read_kreg64(dd, kr_hwdiagctrl); + qib_write_kreg(dd, kr_hwdiagctrl, + diagc | SYM_MASK(HwDiagCtrl, CounterWrEnable)); + + if (ppd->cpspec->ibsymdelta || ppd->cpspec->ibdeltainprog) { + val = read_7220_creg32(dd, cr_ibsymbolerr); + if (ppd->cpspec->ibdeltainprog) + val -= val - ppd->cpspec->ibsymsnap; + val -= ppd->cpspec->ibsymdelta; + write_7220_creg(dd, cr_ibsymbolerr, val); + } + if (ppd->cpspec->iblnkerrdelta || ppd->cpspec->ibdeltainprog) { + val = read_7220_creg32(dd, cr_iblinkerrrecov); + if (ppd->cpspec->ibdeltainprog) + val -= val - ppd->cpspec->iblnkerrsnap; + val -= ppd->cpspec->iblnkerrdelta; + write_7220_creg(dd, cr_iblinkerrrecov, val); + } + + /* and disable counter writes */ + qib_write_kreg(dd, kr_hwdiagctrl, diagc); + } + qib_set_ib_7220_lstate(ppd, 0, QLOGIC_IB_IBCC_LINKINITCMD_DISABLE); + + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags &= ~QIBL_IB_AUTONEG_INPROG; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + wake_up(&ppd->cpspec->autoneg_wait); + cancel_delayed_work(&ppd->cpspec->autoneg_work); + flush_scheduled_work(); + + shutdown_7220_relock_poll(ppd->dd); + val = qib_read_kreg64(ppd->dd, kr_xgxs_cfg); + val |= QLOGIC_IB_XGXS_RESET; + qib_write_kreg(ppd->dd, kr_xgxs_cfg, val); +} + +/** + * qib_setup_7220_setextled - set the state of the two external LEDs + * @dd: the qlogic_ib device + * @on: whether the link is up or not + * + * The exact combo of LEDs if on is true is determined by looking + * at the ibcstatus. + * + * These LEDs indicate the physical and logical state of IB link. + * For this chip (at least with recommended board pinouts), LED1 + * is Yellow (logical state) and LED2 is Green (physical state), + * + * Note: We try to match the Mellanox HCA LED behavior as best + * we can. Green indicates physical link state is OK (something is + * plugged in, and we can train). + * Amber indicates the link is logically up (ACTIVE). + * Mellanox further blinks the amber LED to indicate data packet + * activity, but we have no hardware support for that, so it would + * require waking up every 10-20 msecs and checking the counters + * on the chip, and then turning the LED off if appropriate. That's + * visible overhead, so not something we will do. + * + */ +static void qib_setup_7220_setextled(struct qib_pportdata *ppd, u32 on) +{ + struct qib_devdata *dd = ppd->dd; + u64 extctl, ledblink = 0, val, lst, ltst; + unsigned long flags; + + /* + * The diags use the LED to indicate diag info, so we leave + * the external LED alone when the diags are running. + */ + if (dd->diag_client) + return; + + if (ppd->led_override) { + ltst = (ppd->led_override & QIB_LED_PHYS) ? + IB_PHYSPORTSTATE_LINKUP : IB_PHYSPORTSTATE_DISABLED, + lst = (ppd->led_override & QIB_LED_LOG) ? + IB_PORT_ACTIVE : IB_PORT_DOWN; + } else if (on) { + val = qib_read_kreg64(dd, kr_ibcstatus); + ltst = qib_7220_phys_portstate(val); + lst = qib_7220_iblink_state(val); + } else { + ltst = 0; + lst = 0; + } + + spin_lock_irqsave(&dd->cspec->gpio_lock, flags); + extctl = dd->cspec->extctrl & ~(SYM_MASK(EXTCtrl, LEDPriPortGreenOn) | + SYM_MASK(EXTCtrl, LEDPriPortYellowOn)); + if (ltst == IB_PHYSPORTSTATE_LINKUP) { + extctl |= SYM_MASK(EXTCtrl, LEDPriPortGreenOn); + /* + * counts are in chip clock (4ns) periods. + * This is 1/16 sec (66.6ms) on, + * 3/16 sec (187.5 ms) off, with packets rcvd + */ + ledblink = ((66600 * 1000UL / 4) << IBA7220_LEDBLINK_ON_SHIFT) + | ((187500 * 1000UL / 4) << IBA7220_LEDBLINK_OFF_SHIFT); + } + if (lst == IB_PORT_ACTIVE) + extctl |= SYM_MASK(EXTCtrl, LEDPriPortYellowOn); + dd->cspec->extctrl = extctl; + qib_write_kreg(dd, kr_extctrl, extctl); + spin_unlock_irqrestore(&dd->cspec->gpio_lock, flags); + + if (ledblink) /* blink the LED on packet receive */ + qib_write_kreg(dd, kr_rcvpktledcnt, ledblink); +} + +static void qib_7220_free_irq(struct qib_devdata *dd) +{ + if (dd->cspec->irq) { + free_irq(dd->cspec->irq, dd); + dd->cspec->irq = 0; + } + qib_nomsi(dd); +} + +/* + * qib_setup_7220_cleanup - clean up any per-chip chip-specific stuff + * @dd: the qlogic_ib device + * + * This is called during driver unload. + * + */ +static void qib_setup_7220_cleanup(struct qib_devdata *dd) +{ + qib_7220_free_irq(dd); + kfree(dd->cspec->cntrs); + kfree(dd->cspec->portcntrs); +} + +/* + * This is only called for SDmaInt. + * SDmaDisabled is handled on the error path. + */ +static void sdma_7220_intr(struct qib_pportdata *ppd, u64 istat) +{ + unsigned long flags; + + spin_lock_irqsave(&ppd->sdma_lock, flags); + + switch (ppd->sdma_state.current_state) { + case qib_sdma_state_s00_hw_down: + break; + + case qib_sdma_state_s10_hw_start_up_wait: + __qib_sdma_process_event(ppd, qib_sdma_event_e20_hw_started); + break; + + case qib_sdma_state_s20_idle: + break; + + case qib_sdma_state_s30_sw_clean_up_wait: + break; + + case qib_sdma_state_s40_hw_clean_up_wait: + break; + + case qib_sdma_state_s50_hw_halt_wait: + __qib_sdma_process_event(ppd, qib_sdma_event_e60_hw_halted); + break; + + case qib_sdma_state_s99_running: + /* too chatty to print here */ + __qib_sdma_intr(ppd); + break; + } + spin_unlock_irqrestore(&ppd->sdma_lock, flags); +} + +static void qib_wantpiobuf_7220_intr(struct qib_devdata *dd, u32 needint) +{ + unsigned long flags; + + spin_lock_irqsave(&dd->sendctrl_lock, flags); + if (needint) { + if (!(dd->sendctrl & SYM_MASK(SendCtrl, SendBufAvailUpd))) + goto done; + /* + * blip the availupd off, next write will be on, so + * we ensure an avail update, regardless of threshold or + * buffers becoming free, whenever we want an interrupt + */ + qib_write_kreg(dd, kr_sendctrl, dd->sendctrl & + ~SYM_MASK(SendCtrl, SendBufAvailUpd)); + qib_write_kreg(dd, kr_scratch, 0ULL); + dd->sendctrl |= SYM_MASK(SendCtrl, SendIntBufAvail); + } else + dd->sendctrl &= ~SYM_MASK(SendCtrl, SendIntBufAvail); + qib_write_kreg(dd, kr_sendctrl, dd->sendctrl); + qib_write_kreg(dd, kr_scratch, 0ULL); +done: + spin_unlock_irqrestore(&dd->sendctrl_lock, flags); +} + +/* + * Handle errors and unusual events first, separate function + * to improve cache hits for fast path interrupt handling. + */ +static noinline void unlikely_7220_intr(struct qib_devdata *dd, u64 istat) +{ + if (unlikely(istat & ~QLOGIC_IB_I_BITSEXTANT)) + qib_dev_err(dd, + "interrupt with unknown interrupts %Lx set\n", + istat & ~QLOGIC_IB_I_BITSEXTANT); + + if (istat & QLOGIC_IB_I_GPIO) { + u32 gpiostatus; + + /* + * Boards for this chip currently don't use GPIO interrupts, + * so clear by writing GPIOstatus to GPIOclear, and complain + * to alert developer. To avoid endless repeats, clear + * the bits in the mask, since there is some kind of + * programming error or chip problem. + */ + gpiostatus = qib_read_kreg32(dd, kr_gpio_status); + /* + * In theory, writing GPIOstatus to GPIOclear could + * have a bad side-effect on some diagnostic that wanted + * to poll for a status-change, but the various shadows + * make that problematic at best. Diags will just suppress + * all GPIO interrupts during such tests. + */ + qib_write_kreg(dd, kr_gpio_clear, gpiostatus); + + if (gpiostatus) { + const u32 mask = qib_read_kreg32(dd, kr_gpio_mask); + u32 gpio_irq = mask & gpiostatus; + + /* + * A bit set in status and (chip) Mask register + * would cause an interrupt. Since we are not + * expecting any, report it. Also check that the + * chip reflects our shadow, report issues, + * and refresh from the shadow. + */ + /* + * Clear any troublemakers, and update chip + * from shadow + */ + dd->cspec->gpio_mask &= ~gpio_irq; + qib_write_kreg(dd, kr_gpio_mask, dd->cspec->gpio_mask); + } + } + + if (istat & QLOGIC_IB_I_ERROR) { + u64 estat; + + qib_stats.sps_errints++; + estat = qib_read_kreg64(dd, kr_errstatus); + if (!estat) + qib_devinfo(dd->pcidev, "error interrupt (%Lx), " + "but no error bits set!\n", istat); + else + handle_7220_errors(dd, estat); + } +} + +static irqreturn_t qib_7220intr(int irq, void *data) +{ + struct qib_devdata *dd = data; + irqreturn_t ret; + u64 istat; + u64 ctxtrbits; + u64 rmask; + unsigned i; + + if ((dd->flags & (QIB_PRESENT | QIB_BADINTR)) != QIB_PRESENT) { + /* + * This return value is not great, but we do not want the + * interrupt core code to remove our interrupt handler + * because we don't appear to be handling an interrupt + * during a chip reset. + */ + ret = IRQ_HANDLED; + goto bail; + } + + istat = qib_read_kreg64(dd, kr_intstatus); + + if (unlikely(!istat)) { + ret = IRQ_NONE; /* not our interrupt, or already handled */ + goto bail; + } + if (unlikely(istat == -1)) { + qib_bad_intrstatus(dd); + /* don't know if it was our interrupt or not */ + ret = IRQ_NONE; + goto bail; + } + + qib_stats.sps_ints++; + if (dd->int_counter != (u32) -1) + dd->int_counter++; + + if (unlikely(istat & (~QLOGIC_IB_I_BITSEXTANT | + QLOGIC_IB_I_GPIO | QLOGIC_IB_I_ERROR))) + unlikely_7220_intr(dd, istat); + + /* + * Clear the interrupt bits we found set, relatively early, so we + * "know" know the chip will have seen this by the time we process + * the queue, and will re-interrupt if necessary. The processor + * itself won't take the interrupt again until we return. + */ + qib_write_kreg(dd, kr_intclear, istat); + + /* + * Handle kernel receive queues before checking for pio buffers + * available since receives can overflow; piobuf waiters can afford + * a few extra cycles, since they were waiting anyway. + */ + ctxtrbits = istat & + ((QLOGIC_IB_I_RCVAVAIL_MASK << QLOGIC_IB_I_RCVAVAIL_SHIFT) | + (QLOGIC_IB_I_RCVURG_MASK << QLOGIC_IB_I_RCVURG_SHIFT)); + if (ctxtrbits) { + rmask = (1ULL << QLOGIC_IB_I_RCVAVAIL_SHIFT) | + (1ULL << QLOGIC_IB_I_RCVURG_SHIFT); + for (i = 0; i < dd->first_user_ctxt; i++) { + if (ctxtrbits & rmask) { + ctxtrbits &= ~rmask; + qib_kreceive(dd->rcd[i], NULL, NULL); + } + rmask <<= 1; + } + if (ctxtrbits) { + ctxtrbits = + (ctxtrbits >> QLOGIC_IB_I_RCVAVAIL_SHIFT) | + (ctxtrbits >> QLOGIC_IB_I_RCVURG_SHIFT); + qib_handle_urcv(dd, ctxtrbits); + } + } + + /* only call for SDmaInt */ + if (istat & QLOGIC_IB_I_SDMAINT) + sdma_7220_intr(dd->pport, istat); + + if ((istat & QLOGIC_IB_I_SPIOBUFAVAIL) && (dd->flags & QIB_INITTED)) + qib_ib_piobufavail(dd); + + ret = IRQ_HANDLED; +bail: + return ret; +} + +/* + * Set up our chip-specific interrupt handler. + * The interrupt type has already been setup, so + * we just need to do the registration and error checking. + * If we are using MSI interrupts, we may fall back to + * INTx later, if the interrupt handler doesn't get called + * within 1/2 second (see verify_interrupt()). + */ +static void qib_setup_7220_interrupt(struct qib_devdata *dd) +{ + if (!dd->cspec->irq) + qib_dev_err(dd, "irq is 0, BIOS error? Interrupts won't " + "work\n"); + else { + int ret = request_irq(dd->cspec->irq, qib_7220intr, + dd->msi_lo ? 0 : IRQF_SHARED, + QIB_DRV_NAME, dd); + + if (ret) + qib_dev_err(dd, "Couldn't setup %s interrupt " + "(irq=%d): %d\n", dd->msi_lo ? + "MSI" : "INTx", dd->cspec->irq, ret); + } +} + +/** + * qib_7220_boardname - fill in the board name + * @dd: the qlogic_ib device + * + * info is based on the board revision register + */ +static void qib_7220_boardname(struct qib_devdata *dd) +{ + char *n; + u32 boardid, namelen; + + boardid = SYM_FIELD(dd->revision, Revision, + BoardID); + + switch (boardid) { + case 1: + n = "InfiniPath_QLE7240"; + break; + case 2: + n = "InfiniPath_QLE7280"; + break; + default: + qib_dev_err(dd, "Unknown 7220 board with ID %u\n", boardid); + n = "Unknown_InfiniPath_7220"; + break; + } + + namelen = strlen(n) + 1; + dd->boardname = kmalloc(namelen, GFP_KERNEL); + if (!dd->boardname) + qib_dev_err(dd, "Failed allocation for board name: %s\n", n); + else + snprintf(dd->boardname, namelen, "%s", n); + + if (dd->majrev != 5 || !dd->minrev || dd->minrev > 2) + qib_dev_err(dd, "Unsupported InfiniPath hardware " + "revision %u.%u!\n", + dd->majrev, dd->minrev); + + snprintf(dd->boardversion, sizeof(dd->boardversion), + "ChipABI %u.%u, %s, InfiniPath%u %u.%u, SW Compat %u\n", + QIB_CHIP_VERS_MAJ, QIB_CHIP_VERS_MIN, dd->boardname, + (unsigned)SYM_FIELD(dd->revision, Revision_R, Arch), + dd->majrev, dd->minrev, + (unsigned)SYM_FIELD(dd->revision, Revision_R, SW)); +} + +/* + * This routine sleeps, so it can only be called from user context, not + * from interrupt context. + */ +static int qib_setup_7220_reset(struct qib_devdata *dd) +{ + u64 val; + int i; + int ret; + u16 cmdval; + u8 int_line, clinesz; + unsigned long flags; + + qib_pcie_getcmd(dd, &cmdval, &int_line, &clinesz); + + /* Use dev_err so it shows up in logs, etc. */ + qib_dev_err(dd, "Resetting InfiniPath unit %u\n", dd->unit); + + /* no interrupts till re-initted */ + qib_7220_set_intr_state(dd, 0); + + dd->pport->cpspec->ibdeltainprog = 0; + dd->pport->cpspec->ibsymdelta = 0; + dd->pport->cpspec->iblnkerrdelta = 0; + + /* + * Keep chip from being accessed until we are ready. Use + * writeq() directly, to allow the write even though QIB_PRESENT + * isnt' set. + */ + dd->flags &= ~(QIB_INITTED | QIB_PRESENT); + dd->int_counter = 0; /* so we check interrupts work again */ + val = dd->control | QLOGIC_IB_C_RESET; + writeq(val, &dd->kregbase[kr_control]); + mb(); /* prevent compiler reordering around actual reset */ + + for (i = 1; i <= 5; i++) { + /* + * Allow MBIST, etc. to complete; longer on each retry. + * We sometimes get machine checks from bus timeout if no + * response, so for now, make it *really* long. + */ + msleep(1000 + (1 + i) * 2000); + + qib_pcie_reenable(dd, cmdval, int_line, clinesz); + + /* + * Use readq directly, so we don't need to mark it as PRESENT + * until we get a successful indication that all is well. + */ + val = readq(&dd->kregbase[kr_revision]); + if (val == dd->revision) { + dd->flags |= QIB_PRESENT; /* it's back */ + ret = qib_reinit_intr(dd); + goto bail; + } + } + ret = 0; /* failed */ + +bail: + if (ret) { + if (qib_pcie_params(dd, dd->lbus_width, NULL, NULL)) + qib_dev_err(dd, "Reset failed to setup PCIe or " + "interrupts; continuing anyway\n"); + + /* hold IBC in reset, no sends, etc till later */ + qib_write_kreg(dd, kr_control, 0ULL); + + /* clear the reset error, init error/hwerror mask */ + qib_7220_init_hwerrors(dd); + + /* do setup similar to speed or link-width changes */ + if (dd->pport->cpspec->ibcddrctrl & IBA7220_IBC_IBTA_1_2_MASK) + dd->cspec->presets_needed = 1; + spin_lock_irqsave(&dd->pport->lflags_lock, flags); + dd->pport->lflags |= QIBL_IB_FORCE_NOTIFY; + dd->pport->lflags &= ~QIBL_IB_AUTONEG_FAILED; + spin_unlock_irqrestore(&dd->pport->lflags_lock, flags); + } + + return ret; +} + +/** + * qib_7220_put_tid - write a TID to the chip + * @dd: the qlogic_ib device + * @tidptr: pointer to the expected TID (in chip) to update + * @tidtype: 0 for eager, 1 for expected + * @pa: physical address of in memory buffer; tidinvalid if freeing + */ +static void qib_7220_put_tid(struct qib_devdata *dd, u64 __iomem *tidptr, + u32 type, unsigned long pa) +{ + if (pa != dd->tidinvalid) { + u64 chippa = pa >> IBA7220_TID_PA_SHIFT; + + /* paranoia checks */ + if (pa != (chippa << IBA7220_TID_PA_SHIFT)) { + qib_dev_err(dd, "Physaddr %lx not 2KB aligned!\n", + pa); + return; + } + if (chippa >= (1UL << IBA7220_TID_SZ_SHIFT)) { + qib_dev_err(dd, "Physical page address 0x%lx " + "larger than supported\n", pa); + return; + } + + if (type == RCVHQ_RCV_TYPE_EAGER) + chippa |= dd->tidtemplate; + else /* for now, always full 4KB page */ + chippa |= IBA7220_TID_SZ_4K; + pa = chippa; + } + writeq(pa, tidptr); + mmiowb(); +} + +/** + * qib_7220_clear_tids - clear all TID entries for a ctxt, expected and eager + * @dd: the qlogic_ib device + * @ctxt: the ctxt + * + * clear all TID entries for a ctxt, expected and eager. + * Used from qib_close(). On this chip, TIDs are only 32 bits, + * not 64, but they are still on 64 bit boundaries, so tidbase + * is declared as u64 * for the pointer math, even though we write 32 bits + */ +static void qib_7220_clear_tids(struct qib_devdata *dd, + struct qib_ctxtdata *rcd) +{ + u64 __iomem *tidbase; + unsigned long tidinv; + u32 ctxt; + int i; + + if (!dd->kregbase || !rcd) + return; + + ctxt = rcd->ctxt; + + tidinv = dd->tidinvalid; + tidbase = (u64 __iomem *) + ((char __iomem *)(dd->kregbase) + + dd->rcvtidbase + + ctxt * dd->rcvtidcnt * sizeof(*tidbase)); + + for (i = 0; i < dd->rcvtidcnt; i++) + qib_7220_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EXPECTED, + tidinv); + + tidbase = (u64 __iomem *) + ((char __iomem *)(dd->kregbase) + + dd->rcvegrbase + + rcd->rcvegr_tid_base * sizeof(*tidbase)); + + for (i = 0; i < rcd->rcvegrcnt; i++) + qib_7220_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EAGER, + tidinv); +} + +/** + * qib_7220_tidtemplate - setup constants for TID updates + * @dd: the qlogic_ib device + * + * We setup stuff that we use a lot, to avoid calculating each time + */ +static void qib_7220_tidtemplate(struct qib_devdata *dd) +{ + if (dd->rcvegrbufsize == 2048) + dd->tidtemplate = IBA7220_TID_SZ_2K; + else if (dd->rcvegrbufsize == 4096) + dd->tidtemplate = IBA7220_TID_SZ_4K; + dd->tidinvalid = 0; +} + +/** + * qib_init_7220_get_base_info - set chip-specific flags for user code + * @rcd: the qlogic_ib ctxt + * @kbase: qib_base_info pointer + * + * We set the PCIE flag because the lower bandwidth on PCIe vs + * HyperTransport can affect some user packet algorithims. + */ +static int qib_7220_get_base_info(struct qib_ctxtdata *rcd, + struct qib_base_info *kinfo) +{ + kinfo->spi_runtime_flags |= QIB_RUNTIME_PCIE | + QIB_RUNTIME_NODMA_RTAIL | QIB_RUNTIME_SDMA; + + if (rcd->dd->flags & QIB_USE_SPCL_TRIG) + kinfo->spi_runtime_flags |= QIB_RUNTIME_SPECIAL_TRIGGER; + + return 0; +} + +static struct qib_message_header * +qib_7220_get_msgheader(struct qib_devdata *dd, __le32 *rhf_addr) +{ + u32 offset = qib_hdrget_offset(rhf_addr); + + return (struct qib_message_header *) + (rhf_addr - dd->rhf_offset + offset); +} + +static void qib_7220_config_ctxts(struct qib_devdata *dd) +{ + unsigned long flags; + u32 nchipctxts; + + nchipctxts = qib_read_kreg32(dd, kr_portcnt); + dd->cspec->numctxts = nchipctxts; + if (qib_n_krcv_queues > 1) { + dd->qpn_mask = 0x3f; + dd->first_user_ctxt = qib_n_krcv_queues * dd->num_pports; + if (dd->first_user_ctxt > nchipctxts) + dd->first_user_ctxt = nchipctxts; + } else + dd->first_user_ctxt = dd->num_pports; + dd->n_krcv_queues = dd->first_user_ctxt; + + if (!qib_cfgctxts) { + int nctxts = dd->first_user_ctxt + num_online_cpus(); + + if (nctxts <= 5) + dd->ctxtcnt = 5; + else if (nctxts <= 9) + dd->ctxtcnt = 9; + else if (nctxts <= nchipctxts) + dd->ctxtcnt = nchipctxts; + } else if (qib_cfgctxts <= nchipctxts) + dd->ctxtcnt = qib_cfgctxts; + if (!dd->ctxtcnt) /* none of the above, set to max */ + dd->ctxtcnt = nchipctxts; + + /* + * Chip can be configured for 5, 9, or 17 ctxts, and choice + * affects number of eager TIDs per ctxt (1K, 2K, 4K). + * Lock to be paranoid about later motion, etc. + */ + spin_lock_irqsave(&dd->cspec->rcvmod_lock, flags); + if (dd->ctxtcnt > 9) + dd->rcvctrl |= 2ULL << IBA7220_R_CTXTCFG_SHIFT; + else if (dd->ctxtcnt > 5) + dd->rcvctrl |= 1ULL << IBA7220_R_CTXTCFG_SHIFT; + /* else configure for default 5 receive ctxts */ + if (dd->qpn_mask) + dd->rcvctrl |= 1ULL << QIB_7220_RcvCtrl_RcvQPMapEnable_LSB; + qib_write_kreg(dd, kr_rcvctrl, dd->rcvctrl); + spin_unlock_irqrestore(&dd->cspec->rcvmod_lock, flags); + + /* kr_rcvegrcnt changes based on the number of contexts enabled */ + dd->cspec->rcvegrcnt = qib_read_kreg32(dd, kr_rcvegrcnt); + dd->rcvhdrcnt = max(dd->cspec->rcvegrcnt, IBA7220_KRCVEGRCNT); +} + +static int qib_7220_get_ib_cfg(struct qib_pportdata *ppd, int which) +{ + int lsb, ret = 0; + u64 maskr; /* right-justified mask */ + + switch (which) { + case QIB_IB_CFG_LWID_ENB: /* Get allowed Link-width */ + ret = ppd->link_width_enabled; + goto done; + + case QIB_IB_CFG_LWID: /* Get currently active Link-width */ + ret = ppd->link_width_active; + goto done; + + case QIB_IB_CFG_SPD_ENB: /* Get allowed Link speeds */ + ret = ppd->link_speed_enabled; + goto done; + + case QIB_IB_CFG_SPD: /* Get current Link spd */ + ret = ppd->link_speed_active; + goto done; + + case QIB_IB_CFG_RXPOL_ENB: /* Get Auto-RX-polarity enable */ + lsb = IBA7220_IBC_RXPOL_SHIFT; + maskr = IBA7220_IBC_RXPOL_MASK; + break; + + case QIB_IB_CFG_LREV_ENB: /* Get Auto-Lane-reversal enable */ + lsb = IBA7220_IBC_LREV_SHIFT; + maskr = IBA7220_IBC_LREV_MASK; + break; + + case QIB_IB_CFG_LINKLATENCY: + ret = qib_read_kreg64(ppd->dd, kr_ibcddrstatus) + & IBA7220_DDRSTAT_LINKLAT_MASK; + goto done; + + case QIB_IB_CFG_OP_VLS: + ret = ppd->vls_operational; + goto done; + + case QIB_IB_CFG_VL_HIGH_CAP: + ret = 0; + goto done; + + case QIB_IB_CFG_VL_LOW_CAP: + ret = 0; + goto done; + + case QIB_IB_CFG_OVERRUN_THRESH: /* IB overrun threshold */ + ret = SYM_FIELD(ppd->cpspec->ibcctrl, IBCCtrl, + OverrunThreshold); + goto done; + + case QIB_IB_CFG_PHYERR_THRESH: /* IB PHY error threshold */ + ret = SYM_FIELD(ppd->cpspec->ibcctrl, IBCCtrl, + PhyerrThreshold); + goto done; + + case QIB_IB_CFG_LINKDEFAULT: /* IB link default (sleep/poll) */ + /* will only take effect when the link state changes */ + ret = (ppd->cpspec->ibcctrl & + SYM_MASK(IBCCtrl, LinkDownDefaultState)) ? + IB_LINKINITCMD_SLEEP : IB_LINKINITCMD_POLL; + goto done; + + case QIB_IB_CFG_HRTBT: /* Get Heartbeat off/enable/auto */ + lsb = IBA7220_IBC_HRTBT_SHIFT; + maskr = IBA7220_IBC_HRTBT_MASK; + break; + + case QIB_IB_CFG_PMA_TICKS: + /* + * 0x00 = 10x link transfer rate or 4 nsec. for 2.5Gbs + * Since the clock is always 250MHz, the value is 1 or 0. + */ + ret = (ppd->link_speed_active == QIB_IB_DDR); + goto done; + + default: + ret = -EINVAL; + goto done; + } + ret = (int)((ppd->cpspec->ibcddrctrl >> lsb) & maskr); +done: + return ret; +} + +static int qib_7220_set_ib_cfg(struct qib_pportdata *ppd, int which, u32 val) +{ + struct qib_devdata *dd = ppd->dd; + u64 maskr; /* right-justified mask */ + int lsb, ret = 0, setforce = 0; + u16 lcmd, licmd; + unsigned long flags; + + switch (which) { + case QIB_IB_CFG_LIDLMC: + /* + * Set LID and LMC. Combined to avoid possible hazard + * caller puts LMC in 16MSbits, DLID in 16LSbits of val + */ + lsb = IBA7220_IBC_DLIDLMC_SHIFT; + maskr = IBA7220_IBC_DLIDLMC_MASK; + break; + + case QIB_IB_CFG_LWID_ENB: /* set allowed Link-width */ + /* + * As with speed, only write the actual register if + * the link is currently down, otherwise takes effect + * on next link change. + */ + ppd->link_width_enabled = val; + if (!(ppd->lflags & QIBL_LINKDOWN)) + goto bail; + /* + * We set the QIBL_IB_FORCE_NOTIFY bit so updown + * will get called because we want update + * link_width_active, and the change may not take + * effect for some time (if we are in POLL), so this + * flag will force the updown routine to be called + * on the next ibstatuschange down interrupt, even + * if it's not an down->up transition. + */ + val--; /* convert from IB to chip */ + maskr = IBA7220_IBC_WIDTH_MASK; + lsb = IBA7220_IBC_WIDTH_SHIFT; + setforce = 1; + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags |= QIBL_IB_FORCE_NOTIFY; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + break; + + case QIB_IB_CFG_SPD_ENB: /* set allowed Link speeds */ + /* + * If we turn off IB1.2, need to preset SerDes defaults, + * but not right now. Set a flag for the next time + * we command the link down. As with width, only write the + * actual register if the link is currently down, otherwise + * takes effect on next link change. Since setting is being + * explictly requested (via MAD or sysfs), clear autoneg + * failure status if speed autoneg is enabled. + */ + ppd->link_speed_enabled = val; + if ((ppd->cpspec->ibcddrctrl & IBA7220_IBC_IBTA_1_2_MASK) && + !(val & (val - 1))) + dd->cspec->presets_needed = 1; + if (!(ppd->lflags & QIBL_LINKDOWN)) + goto bail; + /* + * We set the QIBL_IB_FORCE_NOTIFY bit so updown + * will get called because we want update + * link_speed_active, and the change may not take + * effect for some time (if we are in POLL), so this + * flag will force the updown routine to be called + * on the next ibstatuschange down interrupt, even + * if it's not an down->up transition. + */ + if (val == (QIB_IB_SDR | QIB_IB_DDR)) { + val = IBA7220_IBC_SPEED_AUTONEG_MASK | + IBA7220_IBC_IBTA_1_2_MASK; + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags &= ~QIBL_IB_AUTONEG_FAILED; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + } else + val = val == QIB_IB_DDR ? + IBA7220_IBC_SPEED_DDR : IBA7220_IBC_SPEED_SDR; + maskr = IBA7220_IBC_SPEED_AUTONEG_MASK | + IBA7220_IBC_IBTA_1_2_MASK; + /* IBTA 1.2 mode + speed bits are contiguous */ + lsb = SYM_LSB(IBCDDRCtrl, IB_ENHANCED_MODE); + setforce = 1; + break; + + case QIB_IB_CFG_RXPOL_ENB: /* set Auto-RX-polarity enable */ + lsb = IBA7220_IBC_RXPOL_SHIFT; + maskr = IBA7220_IBC_RXPOL_MASK; + break; + + case QIB_IB_CFG_LREV_ENB: /* set Auto-Lane-reversal enable */ + lsb = IBA7220_IBC_LREV_SHIFT; + maskr = IBA7220_IBC_LREV_MASK; + break; + + case QIB_IB_CFG_OVERRUN_THRESH: /* IB overrun threshold */ + maskr = SYM_FIELD(ppd->cpspec->ibcctrl, IBCCtrl, + OverrunThreshold); + if (maskr != val) { + ppd->cpspec->ibcctrl &= + ~SYM_MASK(IBCCtrl, OverrunThreshold); + ppd->cpspec->ibcctrl |= (u64) val << + SYM_LSB(IBCCtrl, OverrunThreshold); + qib_write_kreg(dd, kr_ibcctrl, ppd->cpspec->ibcctrl); + qib_write_kreg(dd, kr_scratch, 0); + } + goto bail; + + case QIB_IB_CFG_PHYERR_THRESH: /* IB PHY error threshold */ + maskr = SYM_FIELD(ppd->cpspec->ibcctrl, IBCCtrl, + PhyerrThreshold); + if (maskr != val) { + ppd->cpspec->ibcctrl &= + ~SYM_MASK(IBCCtrl, PhyerrThreshold); + ppd->cpspec->ibcctrl |= (u64) val << + SYM_LSB(IBCCtrl, PhyerrThreshold); + qib_write_kreg(dd, kr_ibcctrl, ppd->cpspec->ibcctrl); + qib_write_kreg(dd, kr_scratch, 0); + } + goto bail; + + case QIB_IB_CFG_PKEYS: /* update pkeys */ + maskr = (u64) ppd->pkeys[0] | ((u64) ppd->pkeys[1] << 16) | + ((u64) ppd->pkeys[2] << 32) | + ((u64) ppd->pkeys[3] << 48); + qib_write_kreg(dd, kr_partitionkey, maskr); + goto bail; + + case QIB_IB_CFG_LINKDEFAULT: /* IB link default (sleep/poll) */ + /* will only take effect when the link state changes */ + if (val == IB_LINKINITCMD_POLL) + ppd->cpspec->ibcctrl &= + ~SYM_MASK(IBCCtrl, LinkDownDefaultState); + else /* SLEEP */ + ppd->cpspec->ibcctrl |= + SYM_MASK(IBCCtrl, LinkDownDefaultState); + qib_write_kreg(dd, kr_ibcctrl, ppd->cpspec->ibcctrl); + qib_write_kreg(dd, kr_scratch, 0); + goto bail; + + case QIB_IB_CFG_MTU: /* update the MTU in IBC */ + /* + * Update our housekeeping variables, and set IBC max + * size, same as init code; max IBC is max we allow in + * buffer, less the qword pbc, plus 1 for ICRC, in dwords + * Set even if it's unchanged, print debug message only + * on changes. + */ + val = (ppd->ibmaxlen >> 2) + 1; + ppd->cpspec->ibcctrl &= ~SYM_MASK(IBCCtrl, MaxPktLen); + ppd->cpspec->ibcctrl |= (u64)val << SYM_LSB(IBCCtrl, MaxPktLen); + qib_write_kreg(dd, kr_ibcctrl, ppd->cpspec->ibcctrl); + qib_write_kreg(dd, kr_scratch, 0); + goto bail; + + case QIB_IB_CFG_LSTATE: /* set the IB link state */ + switch (val & 0xffff0000) { + case IB_LINKCMD_DOWN: + lcmd = QLOGIC_IB_IBCC_LINKCMD_DOWN; + if (!ppd->cpspec->ibdeltainprog && + qib_compat_ddr_negotiate) { + ppd->cpspec->ibdeltainprog = 1; + ppd->cpspec->ibsymsnap = + read_7220_creg32(dd, cr_ibsymbolerr); + ppd->cpspec->iblnkerrsnap = + read_7220_creg32(dd, cr_iblinkerrrecov); + } + break; + + case IB_LINKCMD_ARMED: + lcmd = QLOGIC_IB_IBCC_LINKCMD_ARMED; + break; + + case IB_LINKCMD_ACTIVE: + lcmd = QLOGIC_IB_IBCC_LINKCMD_ACTIVE; + break; + + default: + ret = -EINVAL; + qib_dev_err(dd, "bad linkcmd req 0x%x\n", val >> 16); + goto bail; + } + switch (val & 0xffff) { + case IB_LINKINITCMD_NOP: + licmd = 0; + break; + + case IB_LINKINITCMD_POLL: + licmd = QLOGIC_IB_IBCC_LINKINITCMD_POLL; + break; + + case IB_LINKINITCMD_SLEEP: + licmd = QLOGIC_IB_IBCC_LINKINITCMD_SLEEP; + break; + + case IB_LINKINITCMD_DISABLE: + licmd = QLOGIC_IB_IBCC_LINKINITCMD_DISABLE; + ppd->cpspec->chase_end = 0; + /* + * stop state chase counter and timer, if running. + * wait forpending timer, but don't clear .data (ppd)! + */ + if (ppd->cpspec->chase_timer.expires) { + del_timer_sync(&ppd->cpspec->chase_timer); + ppd->cpspec->chase_timer.expires = 0; + } + break; + + default: + ret = -EINVAL; + qib_dev_err(dd, "bad linkinitcmd req 0x%x\n", + val & 0xffff); + goto bail; + } + qib_set_ib_7220_lstate(ppd, lcmd, licmd); + goto bail; + + case QIB_IB_CFG_HRTBT: /* set Heartbeat off/enable/auto */ + if (val > IBA7220_IBC_HRTBT_MASK) { + ret = -EINVAL; + goto bail; + } + lsb = IBA7220_IBC_HRTBT_SHIFT; + maskr = IBA7220_IBC_HRTBT_MASK; + break; + + default: + ret = -EINVAL; + goto bail; + } + ppd->cpspec->ibcddrctrl &= ~(maskr << lsb); + ppd->cpspec->ibcddrctrl |= (((u64) val & maskr) << lsb); + qib_write_kreg(dd, kr_ibcddrctrl, ppd->cpspec->ibcddrctrl); + qib_write_kreg(dd, kr_scratch, 0); + if (setforce) { + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags |= QIBL_IB_FORCE_NOTIFY; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + } +bail: + return ret; +} + +static int qib_7220_set_loopback(struct qib_pportdata *ppd, const char *what) +{ + int ret = 0; + u64 val, ddr; + + if (!strncmp(what, "ibc", 3)) { + ppd->cpspec->ibcctrl |= SYM_MASK(IBCCtrl, Loopback); + val = 0; /* disable heart beat, so link will come up */ + qib_devinfo(ppd->dd->pcidev, "Enabling IB%u:%u IBC loopback\n", + ppd->dd->unit, ppd->port); + } else if (!strncmp(what, "off", 3)) { + ppd->cpspec->ibcctrl &= ~SYM_MASK(IBCCtrl, Loopback); + /* enable heart beat again */ + val = IBA7220_IBC_HRTBT_MASK << IBA7220_IBC_HRTBT_SHIFT; + qib_devinfo(ppd->dd->pcidev, "Disabling IB%u:%u IBC loopback " + "(normal)\n", ppd->dd->unit, ppd->port); + } else + ret = -EINVAL; + if (!ret) { + qib_write_kreg(ppd->dd, kr_ibcctrl, ppd->cpspec->ibcctrl); + ddr = ppd->cpspec->ibcddrctrl & ~(IBA7220_IBC_HRTBT_MASK + << IBA7220_IBC_HRTBT_SHIFT); + ppd->cpspec->ibcddrctrl = ddr | val; + qib_write_kreg(ppd->dd, kr_ibcddrctrl, + ppd->cpspec->ibcddrctrl); + qib_write_kreg(ppd->dd, kr_scratch, 0); + } + return ret; +} + +static void qib_update_7220_usrhead(struct qib_ctxtdata *rcd, u64 hd, + u32 updegr, u32 egrhd) +{ + qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); + if (updegr) + qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt); +} + +static u32 qib_7220_hdrqempty(struct qib_ctxtdata *rcd) +{ + u32 head, tail; + + head = qib_read_ureg32(rcd->dd, ur_rcvhdrhead, rcd->ctxt); + if (rcd->rcvhdrtail_kvaddr) + tail = qib_get_rcvhdrtail(rcd); + else + tail = qib_read_ureg32(rcd->dd, ur_rcvhdrtail, rcd->ctxt); + return head == tail; +} + +/* + * Modify the RCVCTRL register in chip-specific way. This + * is a function because bit positions and (future) register + * location is chip-specifc, but the needed operations are + * generic. is a bit-mask because we often want to + * do multiple modifications. + */ +static void rcvctrl_7220_mod(struct qib_pportdata *ppd, unsigned int op, + int ctxt) +{ + struct qib_devdata *dd = ppd->dd; + u64 mask, val; + unsigned long flags; + + spin_lock_irqsave(&dd->cspec->rcvmod_lock, flags); + if (op & QIB_RCVCTRL_TAILUPD_ENB) + dd->rcvctrl |= (1ULL << IBA7220_R_TAILUPD_SHIFT); + if (op & QIB_RCVCTRL_TAILUPD_DIS) + dd->rcvctrl &= ~(1ULL << IBA7220_R_TAILUPD_SHIFT); + if (op & QIB_RCVCTRL_PKEY_ENB) + dd->rcvctrl &= ~(1ULL << IBA7220_R_PKEY_DIS_SHIFT); + if (op & QIB_RCVCTRL_PKEY_DIS) + dd->rcvctrl |= (1ULL << IBA7220_R_PKEY_DIS_SHIFT); + if (ctxt < 0) + mask = (1ULL << dd->ctxtcnt) - 1; + else + mask = (1ULL << ctxt); + if (op & QIB_RCVCTRL_CTXT_ENB) { + /* always done for specific ctxt */ + dd->rcvctrl |= (mask << SYM_LSB(RcvCtrl, PortEnable)); + if (!(dd->flags & QIB_NODMA_RTAIL)) + dd->rcvctrl |= 1ULL << IBA7220_R_TAILUPD_SHIFT; + /* Write these registers before the context is enabled. */ + qib_write_kreg_ctxt(dd, kr_rcvhdrtailaddr, ctxt, + dd->rcd[ctxt]->rcvhdrqtailaddr_phys); + qib_write_kreg_ctxt(dd, kr_rcvhdraddr, ctxt, + dd->rcd[ctxt]->rcvhdrq_phys); + dd->rcd[ctxt]->seq_cnt = 1; + } + if (op & QIB_RCVCTRL_CTXT_DIS) + dd->rcvctrl &= ~(mask << SYM_LSB(RcvCtrl, PortEnable)); + if (op & QIB_RCVCTRL_INTRAVAIL_ENB) + dd->rcvctrl |= (mask << IBA7220_R_INTRAVAIL_SHIFT); + if (op & QIB_RCVCTRL_INTRAVAIL_DIS) + dd->rcvctrl &= ~(mask << IBA7220_R_INTRAVAIL_SHIFT); + qib_write_kreg(dd, kr_rcvctrl, dd->rcvctrl); + if ((op & QIB_RCVCTRL_INTRAVAIL_ENB) && dd->rhdrhead_intr_off) { + /* arm rcv interrupt */ + val = qib_read_ureg32(dd, ur_rcvhdrhead, ctxt) | + dd->rhdrhead_intr_off; + qib_write_ureg(dd, ur_rcvhdrhead, val, ctxt); + } + if (op & QIB_RCVCTRL_CTXT_ENB) { + /* + * Init the context registers also; if we were + * disabled, tail and head should both be zero + * already from the enable, but since we don't + * know, we have to do it explictly. + */ + val = qib_read_ureg32(dd, ur_rcvegrindextail, ctxt); + qib_write_ureg(dd, ur_rcvegrindexhead, val, ctxt); + + val = qib_read_ureg32(dd, ur_rcvhdrtail, ctxt); + dd->rcd[ctxt]->head = val; + /* If kctxt, interrupt on next receive. */ + if (ctxt < dd->first_user_ctxt) + val |= dd->rhdrhead_intr_off; + qib_write_ureg(dd, ur_rcvhdrhead, val, ctxt); + } + if (op & QIB_RCVCTRL_CTXT_DIS) { + if (ctxt >= 0) { + qib_write_kreg_ctxt(dd, kr_rcvhdrtailaddr, ctxt, 0); + qib_write_kreg_ctxt(dd, kr_rcvhdraddr, ctxt, 0); + } else { + unsigned i; + + for (i = 0; i < dd->cfgctxts; i++) { + qib_write_kreg_ctxt(dd, kr_rcvhdrtailaddr, + i, 0); + qib_write_kreg_ctxt(dd, kr_rcvhdraddr, i, 0); + } + } + } + spin_unlock_irqrestore(&dd->cspec->rcvmod_lock, flags); +} + +/* + * Modify the SENDCTRL register in chip-specific way. This + * is a function there may be multiple such registers with + * slightly different layouts. To start, we assume the + * "canonical" register layout of the first chips. + * Chip requires no back-back sendctrl writes, so write + * scratch register after writing sendctrl + */ +static void sendctrl_7220_mod(struct qib_pportdata *ppd, u32 op) +{ + struct qib_devdata *dd = ppd->dd; + u64 tmp_dd_sendctrl; + unsigned long flags; + + spin_lock_irqsave(&dd->sendctrl_lock, flags); + + /* First the ones that are "sticky", saved in shadow */ + if (op & QIB_SENDCTRL_CLEAR) + dd->sendctrl = 0; + if (op & QIB_SENDCTRL_SEND_DIS) + dd->sendctrl &= ~SYM_MASK(SendCtrl, SPioEnable); + else if (op & QIB_SENDCTRL_SEND_ENB) { + dd->sendctrl |= SYM_MASK(SendCtrl, SPioEnable); + if (dd->flags & QIB_USE_SPCL_TRIG) + dd->sendctrl |= SYM_MASK(SendCtrl, + SSpecialTriggerEn); + } + if (op & QIB_SENDCTRL_AVAIL_DIS) + dd->sendctrl &= ~SYM_MASK(SendCtrl, SendBufAvailUpd); + else if (op & QIB_SENDCTRL_AVAIL_ENB) + dd->sendctrl |= SYM_MASK(SendCtrl, SendBufAvailUpd); + + if (op & QIB_SENDCTRL_DISARM_ALL) { + u32 i, last; + + tmp_dd_sendctrl = dd->sendctrl; + /* + * disarm any that are not yet launched, disabling sends + * and updates until done. + */ + last = dd->piobcnt2k + dd->piobcnt4k; + tmp_dd_sendctrl &= + ~(SYM_MASK(SendCtrl, SPioEnable) | + SYM_MASK(SendCtrl, SendBufAvailUpd)); + for (i = 0; i < last; i++) { + qib_write_kreg(dd, kr_sendctrl, + tmp_dd_sendctrl | + SYM_MASK(SendCtrl, Disarm) | i); + qib_write_kreg(dd, kr_scratch, 0); + } + } + + tmp_dd_sendctrl = dd->sendctrl; + + if (op & QIB_SENDCTRL_FLUSH) + tmp_dd_sendctrl |= SYM_MASK(SendCtrl, Abort); + if (op & QIB_SENDCTRL_DISARM) + tmp_dd_sendctrl |= SYM_MASK(SendCtrl, Disarm) | + ((op & QIB_7220_SendCtrl_DisarmPIOBuf_RMASK) << + SYM_LSB(SendCtrl, DisarmPIOBuf)); + if ((op & QIB_SENDCTRL_AVAIL_BLIP) && + (dd->sendctrl & SYM_MASK(SendCtrl, SendBufAvailUpd))) + tmp_dd_sendctrl &= ~SYM_MASK(SendCtrl, SendBufAvailUpd); + + qib_write_kreg(dd, kr_sendctrl, tmp_dd_sendctrl); + qib_write_kreg(dd, kr_scratch, 0); + + if (op & QIB_SENDCTRL_AVAIL_BLIP) { + qib_write_kreg(dd, kr_sendctrl, dd->sendctrl); + qib_write_kreg(dd, kr_scratch, 0); + } + + spin_unlock_irqrestore(&dd->sendctrl_lock, flags); + + if (op & QIB_SENDCTRL_FLUSH) { + u32 v; + /* + * ensure writes have hit chip, then do a few + * more reads, to allow DMA of pioavail registers + * to occur, so in-memory copy is in sync with + * the chip. Not always safe to sleep. + */ + v = qib_read_kreg32(dd, kr_scratch); + qib_write_kreg(dd, kr_scratch, v); + v = qib_read_kreg32(dd, kr_scratch); + qib_write_kreg(dd, kr_scratch, v); + qib_read_kreg32(dd, kr_scratch); + } +} + +/** + * qib_portcntr_7220 - read a per-port counter + * @dd: the qlogic_ib device + * @creg: the counter to snapshot + */ +static u64 qib_portcntr_7220(struct qib_pportdata *ppd, u32 reg) +{ + u64 ret = 0ULL; + struct qib_devdata *dd = ppd->dd; + u16 creg; + /* 0xffff for unimplemented or synthesized counters */ + static const u16 xlator[] = { + [QIBPORTCNTR_PKTSEND] = cr_pktsend, + [QIBPORTCNTR_WORDSEND] = cr_wordsend, + [QIBPORTCNTR_PSXMITDATA] = cr_psxmitdatacount, + [QIBPORTCNTR_PSXMITPKTS] = cr_psxmitpktscount, + [QIBPORTCNTR_PSXMITWAIT] = cr_psxmitwaitcount, + [QIBPORTCNTR_SENDSTALL] = cr_sendstall, + [QIBPORTCNTR_PKTRCV] = cr_pktrcv, + [QIBPORTCNTR_PSRCVDATA] = cr_psrcvdatacount, + [QIBPORTCNTR_PSRCVPKTS] = cr_psrcvpktscount, + [QIBPORTCNTR_RCVEBP] = cr_rcvebp, + [QIBPORTCNTR_RCVOVFL] = cr_rcvovfl, + [QIBPORTCNTR_WORDRCV] = cr_wordrcv, + [QIBPORTCNTR_RXDROPPKT] = cr_rxdroppkt, + [QIBPORTCNTR_RXLOCALPHYERR] = cr_rxotherlocalphyerr, + [QIBPORTCNTR_RXVLERR] = cr_rxvlerr, + [QIBPORTCNTR_ERRICRC] = cr_erricrc, + [QIBPORTCNTR_ERRVCRC] = cr_errvcrc, + [QIBPORTCNTR_ERRLPCRC] = cr_errlpcrc, + [QIBPORTCNTR_BADFORMAT] = cr_badformat, + [QIBPORTCNTR_ERR_RLEN] = cr_err_rlen, + [QIBPORTCNTR_IBSYMBOLERR] = cr_ibsymbolerr, + [QIBPORTCNTR_INVALIDRLEN] = cr_invalidrlen, + [QIBPORTCNTR_UNSUPVL] = cr_txunsupvl, + [QIBPORTCNTR_EXCESSBUFOVFL] = cr_excessbufferovfl, + [QIBPORTCNTR_ERRLINK] = cr_errlink, + [QIBPORTCNTR_IBLINKDOWN] = cr_iblinkdown, + [QIBPORTCNTR_IBLINKERRRECOV] = cr_iblinkerrrecov, + [QIBPORTCNTR_LLI] = cr_locallinkintegrityerr, + [QIBPORTCNTR_PSINTERVAL] = cr_psinterval, + [QIBPORTCNTR_PSSTART] = cr_psstart, + [QIBPORTCNTR_PSSTAT] = cr_psstat, + [QIBPORTCNTR_VL15PKTDROP] = cr_vl15droppedpkt, + [QIBPORTCNTR_ERRPKEY] = cr_errpkey, + [QIBPORTCNTR_KHDROVFL] = 0xffff, + }; + + if (reg >= ARRAY_SIZE(xlator)) { + qib_devinfo(ppd->dd->pcidev, + "Unimplemented portcounter %u\n", reg); + goto done; + } + creg = xlator[reg]; + + if (reg == QIBPORTCNTR_KHDROVFL) { + int i; + + /* sum over all kernel contexts */ + for (i = 0; i < dd->first_user_ctxt; i++) + ret += read_7220_creg32(dd, cr_portovfl + i); + } + if (creg == 0xffff) + goto done; + + /* + * only fast incrementing counters are 64bit; use 32 bit reads to + * avoid two independent reads when on opteron + */ + if ((creg == cr_wordsend || creg == cr_wordrcv || + creg == cr_pktsend || creg == cr_pktrcv)) + ret = read_7220_creg(dd, creg); + else + ret = read_7220_creg32(dd, creg); + if (creg == cr_ibsymbolerr) { + if (dd->pport->cpspec->ibdeltainprog) + ret -= ret - ppd->cpspec->ibsymsnap; + ret -= dd->pport->cpspec->ibsymdelta; + } else if (creg == cr_iblinkerrrecov) { + if (dd->pport->cpspec->ibdeltainprog) + ret -= ret - ppd->cpspec->iblnkerrsnap; + ret -= dd->pport->cpspec->iblnkerrdelta; + } +done: + return ret; +} + +/* + * Device counter names (not port-specific), one line per stat, + * single string. Used by utilities like ipathstats to print the stats + * in a way which works for different versions of drivers, without changing + * the utility. Names need to be 12 chars or less (w/o newline), for proper + * display by utility. + * Non-error counters are first. + * Start of "error" conters is indicated by a leading "E " on the first + * "error" counter, and doesn't count in label length. + * The EgrOvfl list needs to be last so we truncate them at the configured + * context count for the device. + * cntr7220indices contains the corresponding register indices. + */ +static const char cntr7220names[] = + "Interrupts\n" + "HostBusStall\n" + "E RxTIDFull\n" + "RxTIDInvalid\n" + "Ctxt0EgrOvfl\n" + "Ctxt1EgrOvfl\n" + "Ctxt2EgrOvfl\n" + "Ctxt3EgrOvfl\n" + "Ctxt4EgrOvfl\n" + "Ctxt5EgrOvfl\n" + "Ctxt6EgrOvfl\n" + "Ctxt7EgrOvfl\n" + "Ctxt8EgrOvfl\n" + "Ctxt9EgrOvfl\n" + "Ctx10EgrOvfl\n" + "Ctx11EgrOvfl\n" + "Ctx12EgrOvfl\n" + "Ctx13EgrOvfl\n" + "Ctx14EgrOvfl\n" + "Ctx15EgrOvfl\n" + "Ctx16EgrOvfl\n"; + +static const size_t cntr7220indices[] = { + cr_lbint, + cr_lbflowstall, + cr_errtidfull, + cr_errtidvalid, + cr_portovfl + 0, + cr_portovfl + 1, + cr_portovfl + 2, + cr_portovfl + 3, + cr_portovfl + 4, + cr_portovfl + 5, + cr_portovfl + 6, + cr_portovfl + 7, + cr_portovfl + 8, + cr_portovfl + 9, + cr_portovfl + 10, + cr_portovfl + 11, + cr_portovfl + 12, + cr_portovfl + 13, + cr_portovfl + 14, + cr_portovfl + 15, + cr_portovfl + 16, +}; + +/* + * same as cntr7220names and cntr7220indices, but for port-specific counters. + * portcntr7220indices is somewhat complicated by some registers needing + * adjustments of various kinds, and those are ORed with _PORT_VIRT_FLAG + */ +static const char portcntr7220names[] = + "TxPkt\n" + "TxFlowPkt\n" + "TxWords\n" + "RxPkt\n" + "RxFlowPkt\n" + "RxWords\n" + "TxFlowStall\n" + "TxDmaDesc\n" /* 7220 and 7322-only */ + "E RxDlidFltr\n" /* 7220 and 7322-only */ + "IBStatusChng\n" + "IBLinkDown\n" + "IBLnkRecov\n" + "IBRxLinkErr\n" + "IBSymbolErr\n" + "RxLLIErr\n" + "RxBadFormat\n" + "RxBadLen\n" + "RxBufOvrfl\n" + "RxEBP\n" + "RxFlowCtlErr\n" + "RxICRCerr\n" + "RxLPCRCerr\n" + "RxVCRCerr\n" + "RxInvalLen\n" + "RxInvalPKey\n" + "RxPktDropped\n" + "TxBadLength\n" + "TxDropped\n" + "TxInvalLen\n" + "TxUnderrun\n" + "TxUnsupVL\n" + "RxLclPhyErr\n" /* 7220 and 7322-only */ + "RxVL15Drop\n" /* 7220 and 7322-only */ + "RxVlErr\n" /* 7220 and 7322-only */ + "XcessBufOvfl\n" /* 7220 and 7322-only */ + ; + +#define _PORT_VIRT_FLAG 0x8000 /* "virtual", need adjustments */ +static const size_t portcntr7220indices[] = { + QIBPORTCNTR_PKTSEND | _PORT_VIRT_FLAG, + cr_pktsendflow, + QIBPORTCNTR_WORDSEND | _PORT_VIRT_FLAG, + QIBPORTCNTR_PKTRCV | _PORT_VIRT_FLAG, + cr_pktrcvflowctrl, + QIBPORTCNTR_WORDRCV | _PORT_VIRT_FLAG, + QIBPORTCNTR_SENDSTALL | _PORT_VIRT_FLAG, + cr_txsdmadesc, + cr_rxdlidfltr, + cr_ibstatuschange, + QIBPORTCNTR_IBLINKDOWN | _PORT_VIRT_FLAG, + QIBPORTCNTR_IBLINKERRRECOV | _PORT_VIRT_FLAG, + QIBPORTCNTR_ERRLINK | _PORT_VIRT_FLAG, + QIBPORTCNTR_IBSYMBOLERR | _PORT_VIRT_FLAG, + QIBPORTCNTR_LLI | _PORT_VIRT_FLAG, + QIBPORTCNTR_BADFORMAT | _PORT_VIRT_FLAG, + QIBPORTCNTR_ERR_RLEN | _PORT_VIRT_FLAG, + QIBPORTCNTR_RCVOVFL | _PORT_VIRT_FLAG, + QIBPORTCNTR_RCVEBP | _PORT_VIRT_FLAG, + cr_rcvflowctrl_err, + QIBPORTCNTR_ERRICRC | _PORT_VIRT_FLAG, + QIBPORTCNTR_ERRLPCRC | _PORT_VIRT_FLAG, + QIBPORTCNTR_ERRVCRC | _PORT_VIRT_FLAG, + QIBPORTCNTR_INVALIDRLEN | _PORT_VIRT_FLAG, + QIBPORTCNTR_ERRPKEY | _PORT_VIRT_FLAG, + QIBPORTCNTR_RXDROPPKT | _PORT_VIRT_FLAG, + cr_invalidslen, + cr_senddropped, + cr_errslen, + cr_sendunderrun, + cr_txunsupvl, + QIBPORTCNTR_RXLOCALPHYERR | _PORT_VIRT_FLAG, + QIBPORTCNTR_VL15PKTDROP | _PORT_VIRT_FLAG, + QIBPORTCNTR_RXVLERR | _PORT_VIRT_FLAG, + QIBPORTCNTR_EXCESSBUFOVFL | _PORT_VIRT_FLAG, +}; + +/* do all the setup to make the counter reads efficient later */ +static void init_7220_cntrnames(struct qib_devdata *dd) +{ + int i, j = 0; + char *s; + + for (i = 0, s = (char *)cntr7220names; s && j <= dd->cfgctxts; + i++) { + /* we always have at least one counter before the egrovfl */ + if (!j && !strncmp("Ctxt0EgrOvfl", s + 1, 12)) + j = 1; + s = strchr(s + 1, '\n'); + if (s && j) + j++; + } + dd->cspec->ncntrs = i; + if (!s) + /* full list; size is without terminating null */ + dd->cspec->cntrnamelen = sizeof(cntr7220names) - 1; + else + dd->cspec->cntrnamelen = 1 + s - cntr7220names; + dd->cspec->cntrs = kmalloc(dd->cspec->ncntrs + * sizeof(u64), GFP_KERNEL); + if (!dd->cspec->cntrs) + qib_dev_err(dd, "Failed allocation for counters\n"); + + for (i = 0, s = (char *)portcntr7220names; s; i++) + s = strchr(s + 1, '\n'); + dd->cspec->nportcntrs = i - 1; + dd->cspec->portcntrnamelen = sizeof(portcntr7220names) - 1; + dd->cspec->portcntrs = kmalloc(dd->cspec->nportcntrs + * sizeof(u64), GFP_KERNEL); + if (!dd->cspec->portcntrs) + qib_dev_err(dd, "Failed allocation for portcounters\n"); +} + +static u32 qib_read_7220cntrs(struct qib_devdata *dd, loff_t pos, char **namep, + u64 **cntrp) +{ + u32 ret; + + if (!dd->cspec->cntrs) { + ret = 0; + goto done; + } + + if (namep) { + *namep = (char *)cntr7220names; + ret = dd->cspec->cntrnamelen; + if (pos >= ret) + ret = 0; /* final read after getting everything */ + } else { + u64 *cntr = dd->cspec->cntrs; + int i; + + ret = dd->cspec->ncntrs * sizeof(u64); + if (!cntr || pos >= ret) { + /* everything read, or couldn't get memory */ + ret = 0; + goto done; + } + + *cntrp = cntr; + for (i = 0; i < dd->cspec->ncntrs; i++) + *cntr++ = read_7220_creg32(dd, cntr7220indices[i]); + } +done: + return ret; +} + +static u32 qib_read_7220portcntrs(struct qib_devdata *dd, loff_t pos, u32 port, + char **namep, u64 **cntrp) +{ + u32 ret; + + if (!dd->cspec->portcntrs) { + ret = 0; + goto done; + } + if (namep) { + *namep = (char *)portcntr7220names; + ret = dd->cspec->portcntrnamelen; + if (pos >= ret) + ret = 0; /* final read after getting everything */ + } else { + u64 *cntr = dd->cspec->portcntrs; + struct qib_pportdata *ppd = &dd->pport[port]; + int i; + + ret = dd->cspec->nportcntrs * sizeof(u64); + if (!cntr || pos >= ret) { + /* everything read, or couldn't get memory */ + ret = 0; + goto done; + } + *cntrp = cntr; + for (i = 0; i < dd->cspec->nportcntrs; i++) { + if (portcntr7220indices[i] & _PORT_VIRT_FLAG) + *cntr++ = qib_portcntr_7220(ppd, + portcntr7220indices[i] & + ~_PORT_VIRT_FLAG); + else + *cntr++ = read_7220_creg32(dd, + portcntr7220indices[i]); + } + } +done: + return ret; +} + +/** + * qib_get_7220_faststats - get word counters from chip before they overflow + * @opaque - contains a pointer to the qlogic_ib device qib_devdata + * + * This needs more work; in particular, decision on whether we really + * need traffic_wds done the way it is + * called from add_timer + */ +static void qib_get_7220_faststats(unsigned long opaque) +{ + struct qib_devdata *dd = (struct qib_devdata *) opaque; + struct qib_pportdata *ppd = dd->pport; + unsigned long flags; + u64 traffic_wds; + + /* + * don't access the chip while running diags, or memory diags can + * fail + */ + if (!(dd->flags & QIB_INITTED) || dd->diag_client) + /* but re-arm the timer, for diags case; won't hurt other */ + goto done; + + /* + * We now try to maintain an activity timer, based on traffic + * exceeding a threshold, so we need to check the word-counts + * even if they are 64-bit. + */ + traffic_wds = qib_portcntr_7220(ppd, cr_wordsend) + + qib_portcntr_7220(ppd, cr_wordrcv); + spin_lock_irqsave(&dd->eep_st_lock, flags); + traffic_wds -= dd->traffic_wds; + dd->traffic_wds += traffic_wds; + if (traffic_wds >= QIB_TRAFFIC_ACTIVE_THRESHOLD) + atomic_add(5, &dd->active_time); /* S/B #define */ + spin_unlock_irqrestore(&dd->eep_st_lock, flags); +done: + mod_timer(&dd->stats_timer, jiffies + HZ * ACTIVITY_TIMER); +} + +/* + * If we are using MSI, try to fallback to INTx. + */ +static int qib_7220_intr_fallback(struct qib_devdata *dd) +{ + if (!dd->msi_lo) + return 0; + + qib_devinfo(dd->pcidev, "MSI interrupt not detected," + " trying INTx interrupts\n"); + qib_7220_free_irq(dd); + qib_enable_intx(dd->pcidev); + /* + * Some newer kernels require free_irq before disable_msi, + * and irq can be changed during disable and INTx enable + * and we need to therefore use the pcidev->irq value, + * not our saved MSI value. + */ + dd->cspec->irq = dd->pcidev->irq; + qib_setup_7220_interrupt(dd); + return 1; +} + +/* + * Reset the XGXS (between serdes and IBC). Slightly less intrusive + * than resetting the IBC or external link state, and useful in some + * cases to cause some retraining. To do this right, we reset IBC + * as well. + */ +static void qib_7220_xgxs_reset(struct qib_pportdata *ppd) +{ + u64 val, prev_val; + struct qib_devdata *dd = ppd->dd; + + prev_val = qib_read_kreg64(dd, kr_xgxs_cfg); + val = prev_val | QLOGIC_IB_XGXS_RESET; + prev_val &= ~QLOGIC_IB_XGXS_RESET; /* be sure */ + qib_write_kreg(dd, kr_control, + dd->control & ~QLOGIC_IB_C_LINKENABLE); + qib_write_kreg(dd, kr_xgxs_cfg, val); + qib_read_kreg32(dd, kr_scratch); + qib_write_kreg(dd, kr_xgxs_cfg, prev_val); + qib_write_kreg(dd, kr_control, dd->control); +} + +/* + * For this chip, we want to use the same buffer every time + * when we are trying to bring the link up (they are always VL15 + * packets). At that link state the packet should always go out immediately + * (or at least be discarded at the tx interface if the link is down). + * If it doesn't, and the buffer isn't available, that means some other + * sender has gotten ahead of us, and is preventing our packet from going + * out. In that case, we flush all packets, and try again. If that still + * fails, we fail the request, and hope things work the next time around. + * + * We don't need very complicated heuristics on whether the packet had + * time to go out or not, since even at SDR 1X, it goes out in very short + * time periods, covered by the chip reads done here and as part of the + * flush. + */ +static u32 __iomem *get_7220_link_buf(struct qib_pportdata *ppd, u32 *bnum) +{ + u32 __iomem *buf; + u32 lbuf = ppd->dd->cspec->lastbuf_for_pio; + int do_cleanup; + unsigned long flags; + + /* + * always blip to get avail list updated, since it's almost + * always needed, and is fairly cheap. + */ + sendctrl_7220_mod(ppd->dd->pport, QIB_SENDCTRL_AVAIL_BLIP); + qib_read_kreg64(ppd->dd, kr_scratch); /* extra chip flush */ + buf = qib_getsendbuf_range(ppd->dd, bnum, lbuf, lbuf); + if (buf) + goto done; + + spin_lock_irqsave(&ppd->sdma_lock, flags); + if (ppd->sdma_state.current_state == qib_sdma_state_s20_idle && + ppd->sdma_state.current_state != qib_sdma_state_s00_hw_down) { + __qib_sdma_process_event(ppd, qib_sdma_event_e00_go_hw_down); + do_cleanup = 0; + } else { + do_cleanup = 1; + qib_7220_sdma_hw_clean_up(ppd); + } + spin_unlock_irqrestore(&ppd->sdma_lock, flags); + + if (do_cleanup) { + qib_read_kreg64(ppd->dd, kr_scratch); /* extra chip flush */ + buf = qib_getsendbuf_range(ppd->dd, bnum, lbuf, lbuf); + } +done: + return buf; +} + +/* + * This code for non-IBTA-compliant IB speed negotiation is only known to + * work for the SDR to DDR transition, and only between an HCA and a switch + * with recent firmware. It is based on observed heuristics, rather than + * actual knowledge of the non-compliant speed negotiation. + * It has a number of hard-coded fields, since the hope is to rewrite this + * when a spec is available on how the negoation is intended to work. + */ +static void autoneg_7220_sendpkt(struct qib_pportdata *ppd, u32 *hdr, + u32 dcnt, u32 *data) +{ + int i; + u64 pbc; + u32 __iomem *piobuf; + u32 pnum; + struct qib_devdata *dd = ppd->dd; + + i = 0; + pbc = 7 + dcnt + 1; /* 7 dword header, dword data, icrc */ + pbc |= PBC_7220_VL15_SEND; + while (!(piobuf = get_7220_link_buf(ppd, &pnum))) { + if (i++ > 5) + return; + udelay(2); + } + sendctrl_7220_mod(dd->pport, QIB_SENDCTRL_DISARM_BUF(pnum)); + writeq(pbc, piobuf); + qib_flush_wc(); + qib_pio_copy(piobuf + 2, hdr, 7); + qib_pio_copy(piobuf + 9, data, dcnt); + if (dd->flags & QIB_USE_SPCL_TRIG) { + u32 spcl_off = (pnum >= dd->piobcnt2k) ? 2047 : 1023; + + qib_flush_wc(); + __raw_writel(0xaebecede, piobuf + spcl_off); + } + qib_flush_wc(); + qib_sendbuf_done(dd, pnum); +} + +/* + * _start packet gets sent twice at start, _done gets sent twice at end + */ +static void autoneg_7220_send(struct qib_pportdata *ppd, int which) +{ + struct qib_devdata *dd = ppd->dd; + static u32 swapped; + u32 dw, i, hcnt, dcnt, *data; + static u32 hdr[7] = { 0xf002ffff, 0x48ffff, 0x6400abba }; + static u32 madpayload_start[0x40] = { + 0x1810103, 0x1, 0x0, 0x0, 0x2c90000, 0x2c9, 0x0, 0x0, + 0xffffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x1388, 0x15e, 0x1, /* rest 0's */ + }; + static u32 madpayload_done[0x40] = { + 0x1810103, 0x1, 0x0, 0x0, 0x2c90000, 0x2c9, 0x0, 0x0, + 0xffffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x40000001, 0x1388, 0x15e, /* rest 0's */ + }; + + dcnt = ARRAY_SIZE(madpayload_start); + hcnt = ARRAY_SIZE(hdr); + if (!swapped) { + /* for maintainability, do it at runtime */ + for (i = 0; i < hcnt; i++) { + dw = (__force u32) cpu_to_be32(hdr[i]); + hdr[i] = dw; + } + for (i = 0; i < dcnt; i++) { + dw = (__force u32) cpu_to_be32(madpayload_start[i]); + madpayload_start[i] = dw; + dw = (__force u32) cpu_to_be32(madpayload_done[i]); + madpayload_done[i] = dw; + } + swapped = 1; + } + + data = which ? madpayload_done : madpayload_start; + + autoneg_7220_sendpkt(ppd, hdr, dcnt, data); + qib_read_kreg64(dd, kr_scratch); + udelay(2); + autoneg_7220_sendpkt(ppd, hdr, dcnt, data); + qib_read_kreg64(dd, kr_scratch); + udelay(2); +} + +/* + * Do the absolute minimum to cause an IB speed change, and make it + * ready, but don't actually trigger the change. The caller will + * do that when ready (if link is in Polling training state, it will + * happen immediately, otherwise when link next goes down) + * + * This routine should only be used as part of the DDR autonegotation + * code for devices that are not compliant with IB 1.2 (or code that + * fixes things up for same). + * + * When link has gone down, and autoneg enabled, or autoneg has + * failed and we give up until next time we set both speeds, and + * then we want IBTA enabled as well as "use max enabled speed. + */ +static void set_7220_ibspeed_fast(struct qib_pportdata *ppd, u32 speed) +{ + ppd->cpspec->ibcddrctrl &= ~(IBA7220_IBC_SPEED_AUTONEG_MASK | + IBA7220_IBC_IBTA_1_2_MASK); + + if (speed == (QIB_IB_SDR | QIB_IB_DDR)) + ppd->cpspec->ibcddrctrl |= IBA7220_IBC_SPEED_AUTONEG_MASK | + IBA7220_IBC_IBTA_1_2_MASK; + else + ppd->cpspec->ibcddrctrl |= speed == QIB_IB_DDR ? + IBA7220_IBC_SPEED_DDR : IBA7220_IBC_SPEED_SDR; + + qib_write_kreg(ppd->dd, kr_ibcddrctrl, ppd->cpspec->ibcddrctrl); + qib_write_kreg(ppd->dd, kr_scratch, 0); +} + +/* + * This routine is only used when we are not talking to another + * IB 1.2-compliant device that we think can do DDR. + * (This includes all existing switch chips as of Oct 2007.) + * 1.2-compliant devices go directly to DDR prior to reaching INIT + */ +static void try_7220_autoneg(struct qib_pportdata *ppd) +{ + unsigned long flags; + + /* + * Required for older non-IB1.2 DDR switches. Newer + * non-IB-compliant switches don't need it, but so far, + * aren't bothered by it either. "Magic constant" + */ + qib_write_kreg(ppd->dd, kr_ncmodectrl, 0x3b9dc07); + + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags |= QIBL_IB_AUTONEG_INPROG; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + autoneg_7220_send(ppd, 0); + set_7220_ibspeed_fast(ppd, QIB_IB_DDR); + + toggle_7220_rclkrls(ppd->dd); + /* 2 msec is minimum length of a poll cycle */ + schedule_delayed_work(&ppd->cpspec->autoneg_work, + msecs_to_jiffies(2)); +} + +/* + * Handle the empirically determined mechanism for auto-negotiation + * of DDR speed with switches. + */ +static void autoneg_7220_work(struct work_struct *work) +{ + struct qib_pportdata *ppd; + struct qib_devdata *dd; + u64 startms; + u32 i; + unsigned long flags; + + ppd = &container_of(work, struct qib_chippport_specific, + autoneg_work.work)->pportdata; + dd = ppd->dd; + + startms = jiffies_to_msecs(jiffies); + + /* + * Busy wait for this first part, it should be at most a + * few hundred usec, since we scheduled ourselves for 2msec. + */ + for (i = 0; i < 25; i++) { + if (SYM_FIELD(ppd->lastibcstat, IBCStatus, LinkTrainingState) + == IB_7220_LT_STATE_POLLQUIET) { + qib_set_linkstate(ppd, QIB_IB_LINKDOWN_DISABLE); + break; + } + udelay(100); + } + + if (!(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) + goto done; /* we got there early or told to stop */ + + /* we expect this to timeout */ + if (wait_event_timeout(ppd->cpspec->autoneg_wait, + !(ppd->lflags & QIBL_IB_AUTONEG_INPROG), + msecs_to_jiffies(90))) + goto done; + + toggle_7220_rclkrls(dd); + + /* we expect this to timeout */ + if (wait_event_timeout(ppd->cpspec->autoneg_wait, + !(ppd->lflags & QIBL_IB_AUTONEG_INPROG), + msecs_to_jiffies(1700))) + goto done; + + set_7220_ibspeed_fast(ppd, QIB_IB_SDR); + toggle_7220_rclkrls(dd); + + /* + * Wait up to 250 msec for link to train and get to INIT at DDR; + * this should terminate early. + */ + wait_event_timeout(ppd->cpspec->autoneg_wait, + !(ppd->lflags & QIBL_IB_AUTONEG_INPROG), + msecs_to_jiffies(250)); +done: + if (ppd->lflags & QIBL_IB_AUTONEG_INPROG) { + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags &= ~QIBL_IB_AUTONEG_INPROG; + if (dd->cspec->autoneg_tries == AUTONEG_TRIES) { + ppd->lflags |= QIBL_IB_AUTONEG_FAILED; + dd->cspec->autoneg_tries = 0; + } + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + set_7220_ibspeed_fast(ppd, ppd->link_speed_enabled); + } +} + +static u32 qib_7220_iblink_state(u64 ibcs) +{ + u32 state = (u32)SYM_FIELD(ibcs, IBCStatus, LinkState); + + switch (state) { + case IB_7220_L_STATE_INIT: + state = IB_PORT_INIT; + break; + case IB_7220_L_STATE_ARM: + state = IB_PORT_ARMED; + break; + case IB_7220_L_STATE_ACTIVE: + /* fall through */ + case IB_7220_L_STATE_ACT_DEFER: + state = IB_PORT_ACTIVE; + break; + default: /* fall through */ + case IB_7220_L_STATE_DOWN: + state = IB_PORT_DOWN; + break; + } + return state; +} + +/* returns the IBTA port state, rather than the IBC link training state */ +static u8 qib_7220_phys_portstate(u64 ibcs) +{ + u8 state = (u8)SYM_FIELD(ibcs, IBCStatus, LinkTrainingState); + return qib_7220_physportstate[state]; +} + +static int qib_7220_ib_updown(struct qib_pportdata *ppd, int ibup, u64 ibcs) +{ + int ret = 0, symadj = 0; + struct qib_devdata *dd = ppd->dd; + unsigned long flags; + + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags &= ~QIBL_IB_FORCE_NOTIFY; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + + if (!ibup) { + /* + * When the link goes down we don't want AEQ running, so it + * won't interfere with IBC training, etc., and we need + * to go back to the static SerDes preset values. + */ + if (!(ppd->lflags & (QIBL_IB_AUTONEG_FAILED | + QIBL_IB_AUTONEG_INPROG))) + set_7220_ibspeed_fast(ppd, ppd->link_speed_enabled); + if (!(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) { + qib_sd7220_presets(dd); + qib_cancel_sends(ppd); /* initial disarm, etc. */ + spin_lock_irqsave(&ppd->sdma_lock, flags); + if (__qib_sdma_running(ppd)) + __qib_sdma_process_event(ppd, + qib_sdma_event_e70_go_idle); + spin_unlock_irqrestore(&ppd->sdma_lock, flags); + } + /* this might better in qib_sd7220_presets() */ + set_7220_relock_poll(dd, ibup); + } else { + if (qib_compat_ddr_negotiate && + !(ppd->lflags & (QIBL_IB_AUTONEG_FAILED | + QIBL_IB_AUTONEG_INPROG)) && + ppd->link_speed_active == QIB_IB_SDR && + (ppd->link_speed_enabled & (QIB_IB_DDR | QIB_IB_SDR)) == + (QIB_IB_DDR | QIB_IB_SDR) && + dd->cspec->autoneg_tries < AUTONEG_TRIES) { + /* we are SDR, and DDR auto-negotiation enabled */ + ++dd->cspec->autoneg_tries; + if (!ppd->cpspec->ibdeltainprog) { + ppd->cpspec->ibdeltainprog = 1; + ppd->cpspec->ibsymsnap = read_7220_creg32(dd, + cr_ibsymbolerr); + ppd->cpspec->iblnkerrsnap = read_7220_creg32(dd, + cr_iblinkerrrecov); + } + try_7220_autoneg(ppd); + ret = 1; /* no other IB status change processing */ + } else if ((ppd->lflags & QIBL_IB_AUTONEG_INPROG) && + ppd->link_speed_active == QIB_IB_SDR) { + autoneg_7220_send(ppd, 1); + set_7220_ibspeed_fast(ppd, QIB_IB_DDR); + udelay(2); + toggle_7220_rclkrls(dd); + ret = 1; /* no other IB status change processing */ + } else { + if ((ppd->lflags & QIBL_IB_AUTONEG_INPROG) && + (ppd->link_speed_active & QIB_IB_DDR)) { + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags &= ~(QIBL_IB_AUTONEG_INPROG | + QIBL_IB_AUTONEG_FAILED); + spin_unlock_irqrestore(&ppd->lflags_lock, + flags); + dd->cspec->autoneg_tries = 0; + /* re-enable SDR, for next link down */ + set_7220_ibspeed_fast(ppd, + ppd->link_speed_enabled); + wake_up(&ppd->cpspec->autoneg_wait); + symadj = 1; + } else if (ppd->lflags & QIBL_IB_AUTONEG_FAILED) { + /* + * Clear autoneg failure flag, and do setup + * so we'll try next time link goes down and + * back to INIT (possibly connected to a + * different device). + */ + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags &= ~QIBL_IB_AUTONEG_FAILED; + spin_unlock_irqrestore(&ppd->lflags_lock, + flags); + ppd->cpspec->ibcddrctrl |= + IBA7220_IBC_IBTA_1_2_MASK; + qib_write_kreg(dd, kr_ncmodectrl, 0); + symadj = 1; + } + } + + if (!(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) + symadj = 1; + + if (!ret) { + ppd->delay_mult = rate_to_delay + [(ibcs >> IBA7220_LINKSPEED_SHIFT) & 1] + [(ibcs >> IBA7220_LINKWIDTH_SHIFT) & 1]; + + set_7220_relock_poll(dd, ibup); + spin_lock_irqsave(&ppd->sdma_lock, flags); + /* + * Unlike 7322, the 7220 needs this, due to lack of + * interrupt in some cases when we have sdma active + * when the link goes down. + */ + if (ppd->sdma_state.current_state != + qib_sdma_state_s20_idle) + __qib_sdma_process_event(ppd, + qib_sdma_event_e00_go_hw_down); + spin_unlock_irqrestore(&ppd->sdma_lock, flags); + } + } + + if (symadj) { + if (ppd->cpspec->ibdeltainprog) { + ppd->cpspec->ibdeltainprog = 0; + ppd->cpspec->ibsymdelta += read_7220_creg32(ppd->dd, + cr_ibsymbolerr) - ppd->cpspec->ibsymsnap; + ppd->cpspec->iblnkerrdelta += read_7220_creg32(ppd->dd, + cr_iblinkerrrecov) - ppd->cpspec->iblnkerrsnap; + } + } else if (!ibup && qib_compat_ddr_negotiate && + !ppd->cpspec->ibdeltainprog && + !(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) { + ppd->cpspec->ibdeltainprog = 1; + ppd->cpspec->ibsymsnap = read_7220_creg32(ppd->dd, + cr_ibsymbolerr); + ppd->cpspec->iblnkerrsnap = read_7220_creg32(ppd->dd, + cr_iblinkerrrecov); + } + + if (!ret) + qib_setup_7220_setextled(ppd, ibup); + return ret; +} + +/* + * Does read/modify/write to appropriate registers to + * set output and direction bits selected by mask. + * these are in their canonical postions (e.g. lsb of + * dir will end up in D48 of extctrl on existing chips). + * returns contents of GP Inputs. + */ +static int gpio_7220_mod(struct qib_devdata *dd, u32 out, u32 dir, u32 mask) +{ + u64 read_val, new_out; + unsigned long flags; + + if (mask) { + /* some bits being written, lock access to GPIO */ + dir &= mask; + out &= mask; + spin_lock_irqsave(&dd->cspec->gpio_lock, flags); + dd->cspec->extctrl &= ~((u64)mask << SYM_LSB(EXTCtrl, GPIOOe)); + dd->cspec->extctrl |= ((u64) dir << SYM_LSB(EXTCtrl, GPIOOe)); + new_out = (dd->cspec->gpio_out & ~mask) | out; + + qib_write_kreg(dd, kr_extctrl, dd->cspec->extctrl); + qib_write_kreg(dd, kr_gpio_out, new_out); + dd->cspec->gpio_out = new_out; + spin_unlock_irqrestore(&dd->cspec->gpio_lock, flags); + } + /* + * It is unlikely that a read at this time would get valid + * data on a pin whose direction line was set in the same + * call to this function. We include the read here because + * that allows us to potentially combine a change on one pin with + * a read on another, and because the old code did something like + * this. + */ + read_val = qib_read_kreg64(dd, kr_extstatus); + return SYM_FIELD(read_val, EXTStatus, GPIOIn); +} + +/* + * Read fundamental info we need to use the chip. These are + * the registers that describe chip capabilities, and are + * saved in shadow registers. + */ +static void get_7220_chip_params(struct qib_devdata *dd) +{ + u64 val; + u32 piobufs; + int mtu; + + dd->uregbase = qib_read_kreg32(dd, kr_userregbase); + + dd->rcvtidcnt = qib_read_kreg32(dd, kr_rcvtidcnt); + dd->rcvtidbase = qib_read_kreg32(dd, kr_rcvtidbase); + dd->rcvegrbase = qib_read_kreg32(dd, kr_rcvegrbase); + dd->palign = qib_read_kreg32(dd, kr_palign); + dd->piobufbase = qib_read_kreg64(dd, kr_sendpiobufbase); + dd->pio2k_bufbase = dd->piobufbase & 0xffffffff; + + val = qib_read_kreg64(dd, kr_sendpiosize); + dd->piosize2k = val & ~0U; + dd->piosize4k = val >> 32; + + mtu = ib_mtu_enum_to_int(qib_ibmtu); + if (mtu == -1) + mtu = QIB_DEFAULT_MTU; + dd->pport->ibmtu = (u32)mtu; + + val = qib_read_kreg64(dd, kr_sendpiobufcnt); + dd->piobcnt2k = val & ~0U; + dd->piobcnt4k = val >> 32; + /* these may be adjusted in init_chip_wc_pat() */ + dd->pio2kbase = (u32 __iomem *) + ((char __iomem *) dd->kregbase + dd->pio2k_bufbase); + if (dd->piobcnt4k) { + dd->pio4kbase = (u32 __iomem *) + ((char __iomem *) dd->kregbase + + (dd->piobufbase >> 32)); + /* + * 4K buffers take 2 pages; we use roundup just to be + * paranoid; we calculate it once here, rather than on + * ever buf allocate + */ + dd->align4k = ALIGN(dd->piosize4k, dd->palign); + } + + piobufs = dd->piobcnt4k + dd->piobcnt2k; + + dd->pioavregs = ALIGN(piobufs, sizeof(u64) * BITS_PER_BYTE / 2) / + (sizeof(u64) * BITS_PER_BYTE / 2); +} + +/* + * The chip base addresses in cspec and cpspec have to be set + * after possible init_chip_wc_pat(), rather than in + * qib_get_7220_chip_params(), so split out as separate function + */ +static void set_7220_baseaddrs(struct qib_devdata *dd) +{ + u32 cregbase; + /* init after possible re-map in init_chip_wc_pat() */ + cregbase = qib_read_kreg32(dd, kr_counterregbase); + dd->cspec->cregbase = (u64 __iomem *) + ((char __iomem *) dd->kregbase + cregbase); + + dd->egrtidbase = (u64 __iomem *) + ((char __iomem *) dd->kregbase + dd->rcvegrbase); +} + + +#define SENDCTRL_SHADOWED (SYM_MASK(SendCtrl, SendIntBufAvail) | \ + SYM_MASK(SendCtrl, SPioEnable) | \ + SYM_MASK(SendCtrl, SSpecialTriggerEn) | \ + SYM_MASK(SendCtrl, SendBufAvailUpd) | \ + SYM_MASK(SendCtrl, AvailUpdThld) | \ + SYM_MASK(SendCtrl, SDmaEnable) | \ + SYM_MASK(SendCtrl, SDmaIntEnable) | \ + SYM_MASK(SendCtrl, SDmaHalt) | \ + SYM_MASK(SendCtrl, SDmaSingleDescriptor)) + +static int sendctrl_hook(struct qib_devdata *dd, + const struct diag_observer *op, + u32 offs, u64 *data, u64 mask, int only_32) +{ + unsigned long flags; + unsigned idx = offs / sizeof(u64); + u64 local_data, all_bits; + + if (idx != kr_sendctrl) { + qib_dev_err(dd, "SendCtrl Hook called with offs %X, %s-bit\n", + offs, only_32 ? "32" : "64"); + return 0; + } + + all_bits = ~0ULL; + if (only_32) + all_bits >>= 32; + spin_lock_irqsave(&dd->sendctrl_lock, flags); + if ((mask & all_bits) != all_bits) { + /* + * At least some mask bits are zero, so we need + * to read. The judgement call is whether from + * reg or shadow. First-cut: read reg, and complain + * if any bits which should be shadowed are different + * from their shadowed value. + */ + if (only_32) + local_data = (u64)qib_read_kreg32(dd, idx); + else + local_data = qib_read_kreg64(dd, idx); + qib_dev_err(dd, "Sendctrl -> %X, Shad -> %X\n", + (u32)local_data, (u32)dd->sendctrl); + if ((local_data & SENDCTRL_SHADOWED) != + (dd->sendctrl & SENDCTRL_SHADOWED)) + qib_dev_err(dd, "Sendctrl read: %X shadow is %X\n", + (u32)local_data, (u32) dd->sendctrl); + *data = (local_data & ~mask) | (*data & mask); + } + if (mask) { + /* + * At least some mask bits are one, so we need + * to write, but only shadow some bits. + */ + u64 sval, tval; /* Shadowed, transient */ + + /* + * New shadow val is bits we don't want to touch, + * ORed with bits we do, that are intended for shadow. + */ + sval = (dd->sendctrl & ~mask); + sval |= *data & SENDCTRL_SHADOWED & mask; + dd->sendctrl = sval; + tval = sval | (*data & ~SENDCTRL_SHADOWED & mask); + qib_dev_err(dd, "Sendctrl <- %X, Shad <- %X\n", + (u32)tval, (u32)sval); + qib_write_kreg(dd, kr_sendctrl, tval); + qib_write_kreg(dd, kr_scratch, 0Ull); + } + spin_unlock_irqrestore(&dd->sendctrl_lock, flags); + + return only_32 ? 4 : 8; +} + +static const struct diag_observer sendctrl_observer = { + sendctrl_hook, kr_sendctrl * sizeof(u64), + kr_sendctrl * sizeof(u64) +}; + +/* + * write the final few registers that depend on some of the + * init setup. Done late in init, just before bringing up + * the serdes. + */ +static int qib_late_7220_initreg(struct qib_devdata *dd) +{ + int ret = 0; + u64 val; + + qib_write_kreg(dd, kr_rcvhdrentsize, dd->rcvhdrentsize); + qib_write_kreg(dd, kr_rcvhdrsize, dd->rcvhdrsize); + qib_write_kreg(dd, kr_rcvhdrcnt, dd->rcvhdrcnt); + qib_write_kreg(dd, kr_sendpioavailaddr, dd->pioavailregs_phys); + val = qib_read_kreg64(dd, kr_sendpioavailaddr); + if (val != dd->pioavailregs_phys) { + qib_dev_err(dd, "Catastrophic software error, " + "SendPIOAvailAddr written as %lx, " + "read back as %llx\n", + (unsigned long) dd->pioavailregs_phys, + (unsigned long long) val); + ret = -EINVAL; + } + qib_register_observer(dd, &sendctrl_observer); + return ret; +} + +static int qib_init_7220_variables(struct qib_devdata *dd) +{ + struct qib_chippport_specific *cpspec; + struct qib_pportdata *ppd; + int ret = 0; + u32 sbufs, updthresh; + + cpspec = (struct qib_chippport_specific *)(dd + 1); + ppd = &cpspec->pportdata; + dd->pport = ppd; + dd->num_pports = 1; + + dd->cspec = (struct qib_chip_specific *)(cpspec + dd->num_pports); + ppd->cpspec = cpspec; + + spin_lock_init(&dd->cspec->sdepb_lock); + spin_lock_init(&dd->cspec->rcvmod_lock); + spin_lock_init(&dd->cspec->gpio_lock); + + /* we haven't yet set QIB_PRESENT, so use read directly */ + dd->revision = readq(&dd->kregbase[kr_revision]); + + if ((dd->revision & 0xffffffffU) == 0xffffffffU) { + qib_dev_err(dd, "Revision register read failure, " + "giving up initialization\n"); + ret = -ENODEV; + goto bail; + } + dd->flags |= QIB_PRESENT; /* now register routines work */ + + dd->majrev = (u8) SYM_FIELD(dd->revision, Revision_R, + ChipRevMajor); + dd->minrev = (u8) SYM_FIELD(dd->revision, Revision_R, + ChipRevMinor); + + get_7220_chip_params(dd); + qib_7220_boardname(dd); + + /* + * GPIO bits for TWSI data and clock, + * used for serial EEPROM. + */ + dd->gpio_sda_num = _QIB_GPIO_SDA_NUM; + dd->gpio_scl_num = _QIB_GPIO_SCL_NUM; + dd->twsi_eeprom_dev = QIB_TWSI_EEPROM_DEV; + + dd->flags |= QIB_HAS_INTX | QIB_HAS_LINK_LATENCY | + QIB_NODMA_RTAIL | QIB_HAS_THRESH_UPDATE; + dd->flags |= qib_special_trigger ? + QIB_USE_SPCL_TRIG : QIB_HAS_SEND_DMA; + + /* + * EEPROM error log 0 is TXE Parity errors. 1 is RXE Parity. + * 2 is Some Misc, 3 is reserved for future. + */ + dd->eep_st_masks[0].hwerrs_to_log = HWE_MASK(TXEMemParityErr); + + dd->eep_st_masks[1].hwerrs_to_log = HWE_MASK(RXEMemParityErr); + + dd->eep_st_masks[2].errs_to_log = ERR_MASK(ResetNegated); + + init_waitqueue_head(&cpspec->autoneg_wait); + INIT_DELAYED_WORK(&cpspec->autoneg_work, autoneg_7220_work); + + qib_init_pportdata(ppd, dd, 0, 1); + ppd->link_width_supported = IB_WIDTH_1X | IB_WIDTH_4X; + ppd->link_speed_supported = QIB_IB_SDR | QIB_IB_DDR; + + ppd->link_width_enabled = ppd->link_width_supported; + ppd->link_speed_enabled = ppd->link_speed_supported; + /* + * Set the initial values to reasonable default, will be set + * for real when link is up. + */ + ppd->link_width_active = IB_WIDTH_4X; + ppd->link_speed_active = QIB_IB_SDR; + ppd->delay_mult = rate_to_delay[0][1]; + ppd->vls_supported = IB_VL_VL0; + ppd->vls_operational = ppd->vls_supported; + + if (!qib_mini_init) + qib_write_kreg(dd, kr_rcvbthqp, QIB_KD_QP); + + init_timer(&ppd->cpspec->chase_timer); + ppd->cpspec->chase_timer.function = reenable_7220_chase; + ppd->cpspec->chase_timer.data = (unsigned long)ppd; + + qib_num_cfg_vls = 1; /* if any 7220's, only one VL */ + + dd->rcvhdrentsize = QIB_RCVHDR_ENTSIZE; + dd->rcvhdrsize = QIB_DFLT_RCVHDRSIZE; + dd->rhf_offset = + dd->rcvhdrentsize - sizeof(u64) / sizeof(u32); + + /* we always allocate at least 2048 bytes for eager buffers */ + ret = ib_mtu_enum_to_int(qib_ibmtu); + dd->rcvegrbufsize = ret != -1 ? max(ret, 2048) : QIB_DEFAULT_MTU; + + qib_7220_tidtemplate(dd); + + /* + * We can request a receive interrupt for 1 or + * more packets from current offset. For now, we set this + * up for a single packet. + */ + dd->rhdrhead_intr_off = 1ULL << 32; + + /* setup the stats timer; the add_timer is done at end of init */ + init_timer(&dd->stats_timer); + dd->stats_timer.function = qib_get_7220_faststats; + dd->stats_timer.data = (unsigned long) dd; + dd->stats_timer.expires = jiffies + ACTIVITY_TIMER * HZ; + + /* + * Control[4] has been added to change the arbitration within + * the SDMA engine between favoring data fetches over descriptor + * fetches. qib_sdma_fetch_arb==0 gives data fetches priority. + */ + if (qib_sdma_fetch_arb) + dd->control |= 1 << 4; + + dd->ureg_align = 0x10000; /* 64KB alignment */ + + dd->piosize2kmax_dwords = (dd->piosize2k >> 2)-1; + qib_7220_config_ctxts(dd); + qib_set_ctxtcnt(dd); /* needed for PAT setup */ + + if (qib_wc_pat) { + ret = init_chip_wc_pat(dd, 0); + if (ret) + goto bail; + } + set_7220_baseaddrs(dd); /* set chip access pointers now */ + + ret = 0; + if (qib_mini_init) + goto bail; + + ret = qib_create_ctxts(dd); + init_7220_cntrnames(dd); + + /* use all of 4KB buffers for the kernel SDMA, zero if !SDMA. + * reserve the update threshold amount for other kernel use, such + * as sending SMI, MAD, and ACKs, or 3, whichever is greater, + * unless we aren't enabling SDMA, in which case we want to use + * all the 4k bufs for the kernel. + * if this was less than the update threshold, we could wait + * a long time for an update. Coded this way because we + * sometimes change the update threshold for various reasons, + * and we want this to remain robust. + */ + updthresh = 8U; /* update threshold */ + if (dd->flags & QIB_HAS_SEND_DMA) { + dd->cspec->sdmabufcnt = dd->piobcnt4k; + sbufs = updthresh > 3 ? updthresh : 3; + } else { + dd->cspec->sdmabufcnt = 0; + sbufs = dd->piobcnt4k; + } + + dd->cspec->lastbuf_for_pio = dd->piobcnt2k + dd->piobcnt4k - + dd->cspec->sdmabufcnt; + dd->lastctxt_piobuf = dd->cspec->lastbuf_for_pio - sbufs; + dd->cspec->lastbuf_for_pio--; /* range is <= , not < */ + dd->pbufsctxt = dd->lastctxt_piobuf / + (dd->cfgctxts - dd->first_user_ctxt); + + /* + * if we are at 16 user contexts, we will have one 7 sbufs + * per context, so drop the update threshold to match. We + * want to update before we actually run out, at low pbufs/ctxt + * so give ourselves some margin + */ + if ((dd->pbufsctxt - 2) < updthresh) + updthresh = dd->pbufsctxt - 2; + + dd->cspec->updthresh_dflt = updthresh; + dd->cspec->updthresh = updthresh; + + /* before full enable, no interrupts, no locking needed */ + dd->sendctrl |= (updthresh & SYM_RMASK(SendCtrl, AvailUpdThld)) + << SYM_LSB(SendCtrl, AvailUpdThld); + + dd->psxmitwait_supported = 1; + dd->psxmitwait_check_rate = QIB_7220_PSXMITWAIT_CHECK_RATE; +bail: + return ret; +} + +static u32 __iomem *qib_7220_getsendbuf(struct qib_pportdata *ppd, u64 pbc, + u32 *pbufnum) +{ + u32 first, last, plen = pbc & QIB_PBC_LENGTH_MASK; + struct qib_devdata *dd = ppd->dd; + u32 __iomem *buf; + + if (((pbc >> 32) & PBC_7220_VL15_SEND_CTRL) && + !(ppd->lflags & (QIBL_IB_AUTONEG_INPROG | QIBL_LINKACTIVE))) + buf = get_7220_link_buf(ppd, pbufnum); + else { + if ((plen + 1) > dd->piosize2kmax_dwords) + first = dd->piobcnt2k; + else + first = 0; + /* try 4k if all 2k busy, so same last for both sizes */ + last = dd->cspec->lastbuf_for_pio; + buf = qib_getsendbuf_range(dd, pbufnum, first, last); + } + return buf; +} + +/* these 2 "counters" are really control registers, and are always RW */ +static void qib_set_cntr_7220_sample(struct qib_pportdata *ppd, u32 intv, + u32 start) +{ + write_7220_creg(ppd->dd, cr_psinterval, intv); + write_7220_creg(ppd->dd, cr_psstart, start); +} + +/* + * NOTE: no real attempt is made to generalize the SDMA stuff. + * At some point "soon" we will have a new more generalized + * set of sdma interface, and then we'll clean this up. + */ + +/* Must be called with sdma_lock held, or before init finished */ +static void qib_sdma_update_7220_tail(struct qib_pportdata *ppd, u16 tail) +{ + /* Commit writes to memory and advance the tail on the chip */ + wmb(); + ppd->sdma_descq_tail = tail; + qib_write_kreg(ppd->dd, kr_senddmatail, tail); +} + +static void qib_sdma_set_7220_desc_cnt(struct qib_pportdata *ppd, unsigned cnt) +{ +} + +static struct sdma_set_state_action sdma_7220_action_table[] = { + [qib_sdma_state_s00_hw_down] = { + .op_enable = 0, + .op_intenable = 0, + .op_halt = 0, + .go_s99_running_tofalse = 1, + }, + [qib_sdma_state_s10_hw_start_up_wait] = { + .op_enable = 1, + .op_intenable = 1, + .op_halt = 1, + }, + [qib_sdma_state_s20_idle] = { + .op_enable = 1, + .op_intenable = 1, + .op_halt = 1, + }, + [qib_sdma_state_s30_sw_clean_up_wait] = { + .op_enable = 0, + .op_intenable = 1, + .op_halt = 0, + }, + [qib_sdma_state_s40_hw_clean_up_wait] = { + .op_enable = 1, + .op_intenable = 1, + .op_halt = 1, + }, + [qib_sdma_state_s50_hw_halt_wait] = { + .op_enable = 1, + .op_intenable = 1, + .op_halt = 1, + }, + [qib_sdma_state_s99_running] = { + .op_enable = 1, + .op_intenable = 1, + .op_halt = 0, + .go_s99_running_totrue = 1, + }, +}; + +static void qib_7220_sdma_init_early(struct qib_pportdata *ppd) +{ + ppd->sdma_state.set_state_action = sdma_7220_action_table; +} + +static int init_sdma_7220_regs(struct qib_pportdata *ppd) +{ + struct qib_devdata *dd = ppd->dd; + unsigned i, n; + u64 senddmabufmask[3] = { 0 }; + + /* Set SendDmaBase */ + qib_write_kreg(dd, kr_senddmabase, ppd->sdma_descq_phys); + qib_sdma_7220_setlengen(ppd); + qib_sdma_update_7220_tail(ppd, 0); /* Set SendDmaTail */ + /* Set SendDmaHeadAddr */ + qib_write_kreg(dd, kr_senddmaheadaddr, ppd->sdma_head_phys); + + /* + * Reserve all the former "kernel" piobufs, using high number range + * so we get as many 4K buffers as possible + */ + n = dd->piobcnt2k + dd->piobcnt4k; + i = n - dd->cspec->sdmabufcnt; + + for (; i < n; ++i) { + unsigned word = i / 64; + unsigned bit = i & 63; + + BUG_ON(word >= 3); + senddmabufmask[word] |= 1ULL << bit; + } + qib_write_kreg(dd, kr_senddmabufmask0, senddmabufmask[0]); + qib_write_kreg(dd, kr_senddmabufmask1, senddmabufmask[1]); + qib_write_kreg(dd, kr_senddmabufmask2, senddmabufmask[2]); + + ppd->sdma_state.first_sendbuf = i; + ppd->sdma_state.last_sendbuf = n; + + return 0; +} + +/* sdma_lock must be held */ +static u16 qib_sdma_7220_gethead(struct qib_pportdata *ppd) +{ + struct qib_devdata *dd = ppd->dd; + int sane; + int use_dmahead; + u16 swhead; + u16 swtail; + u16 cnt; + u16 hwhead; + + use_dmahead = __qib_sdma_running(ppd) && + (dd->flags & QIB_HAS_SDMA_TIMEOUT); +retry: + hwhead = use_dmahead ? + (u16)le64_to_cpu(*ppd->sdma_head_dma) : + (u16)qib_read_kreg32(dd, kr_senddmahead); + + swhead = ppd->sdma_descq_head; + swtail = ppd->sdma_descq_tail; + cnt = ppd->sdma_descq_cnt; + + if (swhead < swtail) { + /* not wrapped */ + sane = (hwhead >= swhead) & (hwhead <= swtail); + } else if (swhead > swtail) { + /* wrapped around */ + sane = ((hwhead >= swhead) && (hwhead < cnt)) || + (hwhead <= swtail); + } else { + /* empty */ + sane = (hwhead == swhead); + } + + if (unlikely(!sane)) { + if (use_dmahead) { + /* try one more time, directly from the register */ + use_dmahead = 0; + goto retry; + } + /* assume no progress */ + hwhead = swhead; + } + + return hwhead; +} + +static int qib_sdma_7220_busy(struct qib_pportdata *ppd) +{ + u64 hwstatus = qib_read_kreg64(ppd->dd, kr_senddmastatus); + + return (hwstatus & SYM_MASK(SendDmaStatus, ScoreBoardDrainInProg)) || + (hwstatus & SYM_MASK(SendDmaStatus, AbortInProg)) || + (hwstatus & SYM_MASK(SendDmaStatus, InternalSDmaEnable)) || + !(hwstatus & SYM_MASK(SendDmaStatus, ScbEmpty)); +} + +/* + * Compute the amount of delay before sending the next packet if the + * port's send rate differs from the static rate set for the QP. + * Since the delay affects this packet but the amount of the delay is + * based on the length of the previous packet, use the last delay computed + * and save the delay count for this packet to be used next time + * we get here. + */ +static u32 qib_7220_setpbc_control(struct qib_pportdata *ppd, u32 plen, + u8 srate, u8 vl) +{ + u8 snd_mult = ppd->delay_mult; + u8 rcv_mult = ib_rate_to_delay[srate]; + u32 ret = ppd->cpspec->last_delay_mult; + + ppd->cpspec->last_delay_mult = (rcv_mult > snd_mult) ? + (plen * (rcv_mult - snd_mult) + 1) >> 1 : 0; + + /* Indicate VL15, if necessary */ + if (vl == 15) + ret |= PBC_7220_VL15_SEND_CTRL; + return ret; +} + +static void qib_7220_initvl15_bufs(struct qib_devdata *dd) +{ +} + +static void qib_7220_init_ctxt(struct qib_ctxtdata *rcd) +{ + if (!rcd->ctxt) { + rcd->rcvegrcnt = IBA7220_KRCVEGRCNT; + rcd->rcvegr_tid_base = 0; + } else { + rcd->rcvegrcnt = rcd->dd->cspec->rcvegrcnt; + rcd->rcvegr_tid_base = IBA7220_KRCVEGRCNT + + (rcd->ctxt - 1) * rcd->rcvegrcnt; + } +} + +static void qib_7220_txchk_change(struct qib_devdata *dd, u32 start, + u32 len, u32 which, struct qib_ctxtdata *rcd) +{ + int i; + unsigned long flags; + + switch (which) { + case TXCHK_CHG_TYPE_KERN: + /* see if we need to raise avail update threshold */ + spin_lock_irqsave(&dd->uctxt_lock, flags); + for (i = dd->first_user_ctxt; + dd->cspec->updthresh != dd->cspec->updthresh_dflt + && i < dd->cfgctxts; i++) + if (dd->rcd[i] && dd->rcd[i]->subctxt_cnt && + ((dd->rcd[i]->piocnt / dd->rcd[i]->subctxt_cnt) - 1) + < dd->cspec->updthresh_dflt) + break; + spin_unlock_irqrestore(&dd->uctxt_lock, flags); + if (i == dd->cfgctxts) { + spin_lock_irqsave(&dd->sendctrl_lock, flags); + dd->cspec->updthresh = dd->cspec->updthresh_dflt; + dd->sendctrl &= ~SYM_MASK(SendCtrl, AvailUpdThld); + dd->sendctrl |= (dd->cspec->updthresh & + SYM_RMASK(SendCtrl, AvailUpdThld)) << + SYM_LSB(SendCtrl, AvailUpdThld); + spin_unlock_irqrestore(&dd->sendctrl_lock, flags); + sendctrl_7220_mod(dd->pport, QIB_SENDCTRL_AVAIL_BLIP); + } + break; + case TXCHK_CHG_TYPE_USER: + spin_lock_irqsave(&dd->sendctrl_lock, flags); + if (rcd && rcd->subctxt_cnt && ((rcd->piocnt + / rcd->subctxt_cnt) - 1) < dd->cspec->updthresh) { + dd->cspec->updthresh = (rcd->piocnt / + rcd->subctxt_cnt) - 1; + dd->sendctrl &= ~SYM_MASK(SendCtrl, AvailUpdThld); + dd->sendctrl |= (dd->cspec->updthresh & + SYM_RMASK(SendCtrl, AvailUpdThld)) + << SYM_LSB(SendCtrl, AvailUpdThld); + spin_unlock_irqrestore(&dd->sendctrl_lock, flags); + sendctrl_7220_mod(dd->pport, QIB_SENDCTRL_AVAIL_BLIP); + } else + spin_unlock_irqrestore(&dd->sendctrl_lock, flags); + break; + } +} + +static void writescratch(struct qib_devdata *dd, u32 val) +{ + qib_write_kreg(dd, kr_scratch, val); +} + +#define VALID_TS_RD_REG_MASK 0xBF +/** + * qib_7220_tempsense_read - read register of temp sensor via TWSI + * @dd: the qlogic_ib device + * @regnum: register to read from + * + * returns reg contents (0..255) or < 0 for error + */ +static int qib_7220_tempsense_rd(struct qib_devdata *dd, int regnum) +{ + int ret; + u8 rdata; + + if (regnum > 7) { + ret = -EINVAL; + goto bail; + } + + /* return a bogus value for (the one) register we do not have */ + if (!((1 << regnum) & VALID_TS_RD_REG_MASK)) { + ret = 0; + goto bail; + } + + ret = mutex_lock_interruptible(&dd->eep_lock); + if (ret) + goto bail; + + ret = qib_twsi_blk_rd(dd, QIB_TWSI_TEMP_DEV, regnum, &rdata, 1); + if (!ret) + ret = rdata; + + mutex_unlock(&dd->eep_lock); + + /* + * There are three possibilities here: + * ret is actual value (0..255) + * ret is -ENXIO or -EINVAL from twsi code or this file + * ret is -EINTR from mutex_lock_interruptible. + */ +bail: + return ret; +} + +/* Dummy function, as 7220 boards never disable EEPROM Write */ +static int qib_7220_eeprom_wen(struct qib_devdata *dd, int wen) +{ + return 1; +} + +/** + * qib_init_iba7220_funcs - set up the chip-specific function pointers + * @dev: the pci_dev for qlogic_ib device + * @ent: pci_device_id struct for this dev + * + * This is global, and is called directly at init to set up the + * chip-specific function pointers for later use. + */ +struct qib_devdata *qib_init_iba7220_funcs(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct qib_devdata *dd; + int ret; + u32 boardid, minwidth; + + dd = qib_alloc_devdata(pdev, sizeof(struct qib_chip_specific) + + sizeof(struct qib_chippport_specific)); + if (IS_ERR(dd)) + goto bail; + + dd->f_bringup_serdes = qib_7220_bringup_serdes; + dd->f_cleanup = qib_setup_7220_cleanup; + dd->f_clear_tids = qib_7220_clear_tids; + dd->f_free_irq = qib_7220_free_irq; + dd->f_get_base_info = qib_7220_get_base_info; + dd->f_get_msgheader = qib_7220_get_msgheader; + dd->f_getsendbuf = qib_7220_getsendbuf; + dd->f_gpio_mod = gpio_7220_mod; + dd->f_eeprom_wen = qib_7220_eeprom_wen; + dd->f_hdrqempty = qib_7220_hdrqempty; + dd->f_ib_updown = qib_7220_ib_updown; + dd->f_init_ctxt = qib_7220_init_ctxt; + dd->f_initvl15_bufs = qib_7220_initvl15_bufs; + dd->f_intr_fallback = qib_7220_intr_fallback; + dd->f_late_initreg = qib_late_7220_initreg; + dd->f_setpbc_control = qib_7220_setpbc_control; + dd->f_portcntr = qib_portcntr_7220; + dd->f_put_tid = qib_7220_put_tid; + dd->f_quiet_serdes = qib_7220_quiet_serdes; + dd->f_rcvctrl = rcvctrl_7220_mod; + dd->f_read_cntrs = qib_read_7220cntrs; + dd->f_read_portcntrs = qib_read_7220portcntrs; + dd->f_reset = qib_setup_7220_reset; + dd->f_init_sdma_regs = init_sdma_7220_regs; + dd->f_sdma_busy = qib_sdma_7220_busy; + dd->f_sdma_gethead = qib_sdma_7220_gethead; + dd->f_sdma_sendctrl = qib_7220_sdma_sendctrl; + dd->f_sdma_set_desc_cnt = qib_sdma_set_7220_desc_cnt; + dd->f_sdma_update_tail = qib_sdma_update_7220_tail; + dd->f_sdma_hw_clean_up = qib_7220_sdma_hw_clean_up; + dd->f_sdma_hw_start_up = qib_7220_sdma_hw_start_up; + dd->f_sdma_init_early = qib_7220_sdma_init_early; + dd->f_sendctrl = sendctrl_7220_mod; + dd->f_set_armlaunch = qib_set_7220_armlaunch; + dd->f_set_cntr_sample = qib_set_cntr_7220_sample; + dd->f_iblink_state = qib_7220_iblink_state; + dd->f_ibphys_portstate = qib_7220_phys_portstate; + dd->f_get_ib_cfg = qib_7220_get_ib_cfg; + dd->f_set_ib_cfg = qib_7220_set_ib_cfg; + dd->f_set_ib_loopback = qib_7220_set_loopback; + dd->f_set_intr_state = qib_7220_set_intr_state; + dd->f_setextled = qib_setup_7220_setextled; + dd->f_txchk_change = qib_7220_txchk_change; + dd->f_update_usrhead = qib_update_7220_usrhead; + dd->f_wantpiobuf_intr = qib_wantpiobuf_7220_intr; + dd->f_xgxs_reset = qib_7220_xgxs_reset; + dd->f_writescratch = writescratch; + dd->f_tempsense_rd = qib_7220_tempsense_rd; + /* + * Do remaining pcie setup and save pcie values in dd. + * Any error printing is already done by the init code. + * On return, we have the chip mapped, but chip registers + * are not set up until start of qib_init_7220_variables. + */ + ret = qib_pcie_ddinit(dd, pdev, ent); + if (ret < 0) + goto bail_free; + + /* initialize chip-specific variables */ + ret = qib_init_7220_variables(dd); + if (ret) + goto bail_cleanup; + + if (qib_mini_init) + goto bail; + + boardid = SYM_FIELD(dd->revision, Revision, + BoardID); + switch (boardid) { + case 0: + case 2: + case 10: + case 12: + minwidth = 16; /* x16 capable boards */ + break; + default: + minwidth = 8; /* x8 capable boards */ + break; + } + if (qib_pcie_params(dd, minwidth, NULL, NULL)) + qib_dev_err(dd, "Failed to setup PCIe or interrupts; " + "continuing anyway\n"); + + /* save IRQ for possible later use */ + dd->cspec->irq = pdev->irq; + + if (qib_read_kreg64(dd, kr_hwerrstatus) & + QLOGIC_IB_HWE_SERDESPLLFAILED) + qib_write_kreg(dd, kr_hwerrclear, + QLOGIC_IB_HWE_SERDESPLLFAILED); + + /* setup interrupt handler (interrupt type handled above) */ + qib_setup_7220_interrupt(dd); + qib_7220_init_hwerrors(dd); + + /* clear diagctrl register, in case diags were running and crashed */ + qib_write_kreg(dd, kr_hwdiagctrl, 0); + + goto bail; + +bail_cleanup: + qib_pcie_ddcleanup(dd); +bail_free: + qib_free_devdata(dd); + dd = ERR_PTR(ret); +bail: + return dd; +} diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c new file mode 100644 index 000000000000..2c24eab35b54 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_iba7322.c @@ -0,0 +1,8058 @@ +/* + * Copyright (c) 2008, 2009, 2010 QLogic Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * This file contains all of the code that is specific to the + * InfiniPath 7322 chip + */ + +#include +#include +#include +#include +#include +#include +#include +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) +#include +#endif + +#include "qib.h" +#include "qib_7322_regs.h" +#include "qib_qsfp.h" + +#include "qib_mad.h" + +static void qib_setup_7322_setextled(struct qib_pportdata *, u32); +static void qib_7322_handle_hwerrors(struct qib_devdata *, char *, size_t); +static void sendctrl_7322_mod(struct qib_pportdata *ppd, u32 op); +static irqreturn_t qib_7322intr(int irq, void *data); +static irqreturn_t qib_7322bufavail(int irq, void *data); +static irqreturn_t sdma_intr(int irq, void *data); +static irqreturn_t sdma_idle_intr(int irq, void *data); +static irqreturn_t sdma_progress_intr(int irq, void *data); +static irqreturn_t sdma_cleanup_intr(int irq, void *data); +static void qib_7322_txchk_change(struct qib_devdata *, u32, u32, u32, + struct qib_ctxtdata *rcd); +static u8 qib_7322_phys_portstate(u64); +static u32 qib_7322_iblink_state(u64); +static void qib_set_ib_7322_lstate(struct qib_pportdata *ppd, u16 linkcmd, + u16 linitcmd); +static void force_h1(struct qib_pportdata *); +static void adj_tx_serdes(struct qib_pportdata *); +static u32 qib_7322_setpbc_control(struct qib_pportdata *, u32, u8, u8); +static void qib_7322_mini_pcs_reset(struct qib_pportdata *); + +static u32 ahb_mod(struct qib_devdata *, int, int, int, u32, u32); +static void ibsd_wr_allchans(struct qib_pportdata *, int, unsigned, unsigned); + +#define BMASK(msb, lsb) (((1 << ((msb) + 1 - (lsb))) - 1) << (lsb)) + +/* LE2 serdes values for different cases */ +#define LE2_DEFAULT 5 +#define LE2_5m 4 +#define LE2_QME 0 + +/* Below is special-purpose, so only really works for the IB SerDes blocks. */ +#define IBSD(hw_pidx) (hw_pidx + 2) + +/* these are variables for documentation and experimentation purposes */ +static const unsigned rcv_int_timeout = 375; +static const unsigned rcv_int_count = 16; +static const unsigned sdma_idle_cnt = 64; + +/* Time to stop altering Rx Equalization parameters, after link up. */ +#define RXEQ_DISABLE_MSECS 2500 + +/* + * Number of VLs we are configured to use (to allow for more + * credits per vl, etc.) + */ +ushort qib_num_cfg_vls = 2; +module_param_named(num_vls, qib_num_cfg_vls, ushort, S_IRUGO); +MODULE_PARM_DESC(num_vls, "Set number of Virtual Lanes to use (1-8)"); + +static ushort qib_chase = 1; +module_param_named(chase, qib_chase, ushort, S_IRUGO); +MODULE_PARM_DESC(chase, "Enable state chase handling"); + +static ushort qib_long_atten = 10; /* 10 dB ~= 5m length */ +module_param_named(long_attenuation, qib_long_atten, ushort, S_IRUGO); +MODULE_PARM_DESC(long_attenuation, \ + "attenuation cutoff (dB) for long copper cable setup"); + +static ushort qib_singleport; +module_param_named(singleport, qib_singleport, ushort, S_IRUGO); +MODULE_PARM_DESC(singleport, "Use only IB port 1; more per-port buffer space"); + + +/* + * Setup QMH7342 receive and transmit parameters, necessary because + * each bay, Mez connector, and IB port need different tuning, beyond + * what the switch and HCA can do automatically. + * It's expected to be done by cat'ing files to the modules file, + * rather than setting up as a module parameter. + * It's a "write-only" file, returns 0 when read back. + * The unit, port, bay (if given), and values MUST be done as a single write. + * The unit, port, and bay must precede the values to be effective. + */ +static int setup_qmh_params(const char *, struct kernel_param *); +static unsigned dummy_qmh_params; +module_param_call(qmh_serdes_setup, setup_qmh_params, param_get_uint, + &dummy_qmh_params, S_IWUSR | S_IRUGO); + +/* similarly for QME7342, but it's simpler */ +static int setup_qme_params(const char *, struct kernel_param *); +static unsigned dummy_qme_params; +module_param_call(qme_serdes_setup, setup_qme_params, param_get_uint, + &dummy_qme_params, S_IWUSR | S_IRUGO); + +#define MAX_ATTEN_LEN 64 /* plenty for any real system */ +/* for read back, default index is ~5m copper cable */ +static char cable_atten_list[MAX_ATTEN_LEN] = "10"; +static struct kparam_string kp_cable_atten = { + .string = cable_atten_list, + .maxlen = MAX_ATTEN_LEN +}; +static int setup_cable_atten(const char *, struct kernel_param *); +module_param_call(cable_atten, setup_cable_atten, param_get_string, + &kp_cable_atten, S_IWUSR | S_IRUGO); +MODULE_PARM_DESC(cable_atten, \ + "cable attenuation indices for cables with invalid EEPROM"); + +#define BOARD_QME7342 5 +#define BOARD_QMH7342 6 +#define IS_QMH(dd) (SYM_FIELD((dd)->revision, Revision, BoardID) == \ + BOARD_QMH7342) +#define IS_QME(dd) (SYM_FIELD((dd)->revision, Revision, BoardID) == \ + BOARD_QME7342) + +#define KREG_IDX(regname) (QIB_7322_##regname##_OFFS / sizeof(u64)) + +#define KREG_IBPORT_IDX(regname) ((QIB_7322_##regname##_0_OFFS / sizeof(u64))) + +#define MASK_ACROSS(lsb, msb) \ + (((1ULL << ((msb) + 1 - (lsb))) - 1) << (lsb)) + +#define SYM_RMASK(regname, fldname) ((u64) \ + QIB_7322_##regname##_##fldname##_RMASK) + +#define SYM_MASK(regname, fldname) ((u64) \ + QIB_7322_##regname##_##fldname##_RMASK << \ + QIB_7322_##regname##_##fldname##_LSB) + +#define SYM_FIELD(value, regname, fldname) ((u64) \ + (((value) >> SYM_LSB(regname, fldname)) & \ + SYM_RMASK(regname, fldname))) + +/* useful for things like LaFifoEmpty_0...7, TxCreditOK_0...7, etc. */ +#define SYM_FIELD_ACROSS(value, regname, fldname, nbits) \ + (((value) >> SYM_LSB(regname, fldname)) & MASK_ACROSS(0, nbits)) + +#define HWE_MASK(fldname) SYM_MASK(HwErrMask, fldname##Mask) +#define ERR_MASK(fldname) SYM_MASK(ErrMask, fldname##Mask) +#define ERR_MASK_N(fldname) SYM_MASK(ErrMask_0, fldname##Mask) +#define INT_MASK(fldname) SYM_MASK(IntMask, fldname##IntMask) +#define INT_MASK_P(fldname, port) SYM_MASK(IntMask, fldname##IntMask##_##port) +/* Below because most, but not all, fields of IntMask have that full suffix */ +#define INT_MASK_PM(fldname, port) SYM_MASK(IntMask, fldname##Mask##_##port) + + +#define SYM_LSB(regname, fldname) (QIB_7322_##regname##_##fldname##_LSB) + +/* + * the size bits give us 2^N, in KB units. 0 marks as invalid, + * and 7 is reserved. We currently use only 2KB and 4KB + */ +#define IBA7322_TID_SZ_SHIFT QIB_7322_RcvTIDArray0_RT_BufSize_LSB +#define IBA7322_TID_SZ_2K (1UL<kregbase || !(dd->flags & QIB_PRESENT)) + return 0; + return readl(regno + (u64 __iomem *)( + (dd->ureg_align * ctxt) + (dd->userbase ? + (char __iomem *)dd->userbase : + (char __iomem *)dd->kregbase + dd->uregbase))); +} + +/** + * qib_read_ureg - read virtualized per-context register + * @dd: device + * @regno: register number + * @ctxt: context number + * + * Return the contents of a register that is virtualized to be per context. + * Returns -1 on errors (not distinguishable from valid contents at + * runtime; we may add a separate error variable at some point). + */ +static inline u64 qib_read_ureg(const struct qib_devdata *dd, + enum qib_ureg regno, int ctxt) +{ + + if (!dd->kregbase || !(dd->flags & QIB_PRESENT)) + return 0; + return readq(regno + (u64 __iomem *)( + (dd->ureg_align * ctxt) + (dd->userbase ? + (char __iomem *)dd->userbase : + (char __iomem *)dd->kregbase + dd->uregbase))); +} + +/** + * qib_write_ureg - write virtualized per-context register + * @dd: device + * @regno: register number + * @value: value + * @ctxt: context + * + * Write the contents of a register that is virtualized to be per context. + */ +static inline void qib_write_ureg(const struct qib_devdata *dd, + enum qib_ureg regno, u64 value, int ctxt) +{ + u64 __iomem *ubase; + if (dd->userbase) + ubase = (u64 __iomem *) + ((char __iomem *) dd->userbase + + dd->ureg_align * ctxt); + else + ubase = (u64 __iomem *) + (dd->uregbase + + (char __iomem *) dd->kregbase + + dd->ureg_align * ctxt); + + if (dd->kregbase && (dd->flags & QIB_PRESENT)) + writeq(value, &ubase[regno]); +} + +static inline u32 qib_read_kreg32(const struct qib_devdata *dd, + const u32 regno) +{ + if (!dd->kregbase || !(dd->flags & QIB_PRESENT)) + return -1; + return readl((u32 __iomem *) &dd->kregbase[regno]); +} + +static inline u64 qib_read_kreg64(const struct qib_devdata *dd, + const u32 regno) +{ + if (!dd->kregbase || !(dd->flags & QIB_PRESENT)) + return -1; + return readq(&dd->kregbase[regno]); +} + +static inline void qib_write_kreg(const struct qib_devdata *dd, + const u32 regno, u64 value) +{ + if (dd->kregbase && (dd->flags & QIB_PRESENT)) + writeq(value, &dd->kregbase[regno]); +} + +/* + * not many sanity checks for the port-specific kernel register routines, + * since they are only used when it's known to be safe. +*/ +static inline u64 qib_read_kreg_port(const struct qib_pportdata *ppd, + const u16 regno) +{ + if (!ppd->cpspec->kpregbase || !(ppd->dd->flags & QIB_PRESENT)) + return 0ULL; + return readq(&ppd->cpspec->kpregbase[regno]); +} + +static inline void qib_write_kreg_port(const struct qib_pportdata *ppd, + const u16 regno, u64 value) +{ + if (ppd->cpspec && ppd->dd && ppd->cpspec->kpregbase && + (ppd->dd->flags & QIB_PRESENT)) + writeq(value, &ppd->cpspec->kpregbase[regno]); +} + +/** + * qib_write_kreg_ctxt - write a device's per-ctxt 64-bit kernel register + * @dd: the qlogic_ib device + * @regno: the register number to write + * @ctxt: the context containing the register + * @value: the value to write + */ +static inline void qib_write_kreg_ctxt(const struct qib_devdata *dd, + const u16 regno, unsigned ctxt, + u64 value) +{ + qib_write_kreg(dd, regno + ctxt, value); +} + +static inline u64 read_7322_creg(const struct qib_devdata *dd, u16 regno) +{ + if (!dd->cspec->cregbase || !(dd->flags & QIB_PRESENT)) + return 0; + return readq(&dd->cspec->cregbase[regno]); + + +} + +static inline u32 read_7322_creg32(const struct qib_devdata *dd, u16 regno) +{ + if (!dd->cspec->cregbase || !(dd->flags & QIB_PRESENT)) + return 0; + return readl(&dd->cspec->cregbase[regno]); + + +} + +static inline void write_7322_creg_port(const struct qib_pportdata *ppd, + u16 regno, u64 value) +{ + if (ppd->cpspec && ppd->cpspec->cpregbase && + (ppd->dd->flags & QIB_PRESENT)) + writeq(value, &ppd->cpspec->cpregbase[regno]); +} + +static inline u64 read_7322_creg_port(const struct qib_pportdata *ppd, + u16 regno) +{ + if (!ppd->cpspec || !ppd->cpspec->cpregbase || + !(ppd->dd->flags & QIB_PRESENT)) + return 0; + return readq(&ppd->cpspec->cpregbase[regno]); +} + +static inline u32 read_7322_creg32_port(const struct qib_pportdata *ppd, + u16 regno) +{ + if (!ppd->cpspec || !ppd->cpspec->cpregbase || + !(ppd->dd->flags & QIB_PRESENT)) + return 0; + return readl(&ppd->cpspec->cpregbase[regno]); +} + +/* bits in Control register */ +#define QLOGIC_IB_C_RESET SYM_MASK(Control, SyncReset) +#define QLOGIC_IB_C_SDMAFETCHPRIOEN SYM_MASK(Control, SDmaDescFetchPriorityEn) + +/* bits in general interrupt regs */ +#define QIB_I_RCVURG_LSB SYM_LSB(IntMask, RcvUrg0IntMask) +#define QIB_I_RCVURG_RMASK MASK_ACROSS(0, 17) +#define QIB_I_RCVURG_MASK (QIB_I_RCVURG_RMASK << QIB_I_RCVURG_LSB) +#define QIB_I_RCVAVAIL_LSB SYM_LSB(IntMask, RcvAvail0IntMask) +#define QIB_I_RCVAVAIL_RMASK MASK_ACROSS(0, 17) +#define QIB_I_RCVAVAIL_MASK (QIB_I_RCVAVAIL_RMASK << QIB_I_RCVAVAIL_LSB) +#define QIB_I_C_ERROR INT_MASK(Err) + +#define QIB_I_SPIOSENT (INT_MASK_P(SendDone, 0) | INT_MASK_P(SendDone, 1)) +#define QIB_I_SPIOBUFAVAIL INT_MASK(SendBufAvail) +#define QIB_I_GPIO INT_MASK(AssertGPIO) +#define QIB_I_P_SDMAINT(pidx) \ + (INT_MASK_P(SDma, pidx) | INT_MASK_P(SDmaIdle, pidx) | \ + INT_MASK_P(SDmaProgress, pidx) | \ + INT_MASK_PM(SDmaCleanupDone, pidx)) + +/* Interrupt bits that are "per port" */ +#define QIB_I_P_BITSEXTANT(pidx) \ + (INT_MASK_P(Err, pidx) | INT_MASK_P(SendDone, pidx) | \ + INT_MASK_P(SDma, pidx) | INT_MASK_P(SDmaIdle, pidx) | \ + INT_MASK_P(SDmaProgress, pidx) | \ + INT_MASK_PM(SDmaCleanupDone, pidx)) + +/* Interrupt bits that are common to a device */ +/* currently unused: QIB_I_SPIOSENT */ +#define QIB_I_C_BITSEXTANT \ + (QIB_I_RCVURG_MASK | QIB_I_RCVAVAIL_MASK | \ + QIB_I_SPIOSENT | \ + QIB_I_C_ERROR | QIB_I_SPIOBUFAVAIL | QIB_I_GPIO) + +#define QIB_I_BITSEXTANT (QIB_I_C_BITSEXTANT | \ + QIB_I_P_BITSEXTANT(0) | QIB_I_P_BITSEXTANT(1)) + +/* + * Error bits that are "per port". + */ +#define QIB_E_P_IBSTATUSCHANGED ERR_MASK_N(IBStatusChanged) +#define QIB_E_P_SHDR ERR_MASK_N(SHeadersErr) +#define QIB_E_P_VL15_BUF_MISUSE ERR_MASK_N(VL15BufMisuseErr) +#define QIB_E_P_SND_BUF_MISUSE ERR_MASK_N(SendBufMisuseErr) +#define QIB_E_P_SUNSUPVL ERR_MASK_N(SendUnsupportedVLErr) +#define QIB_E_P_SUNEXP_PKTNUM ERR_MASK_N(SendUnexpectedPktNumErr) +#define QIB_E_P_SDROP_DATA ERR_MASK_N(SendDroppedDataPktErr) +#define QIB_E_P_SDROP_SMP ERR_MASK_N(SendDroppedSmpPktErr) +#define QIB_E_P_SPKTLEN ERR_MASK_N(SendPktLenErr) +#define QIB_E_P_SUNDERRUN ERR_MASK_N(SendUnderRunErr) +#define QIB_E_P_SMAXPKTLEN ERR_MASK_N(SendMaxPktLenErr) +#define QIB_E_P_SMINPKTLEN ERR_MASK_N(SendMinPktLenErr) +#define QIB_E_P_RIBLOSTLINK ERR_MASK_N(RcvIBLostLinkErr) +#define QIB_E_P_RHDR ERR_MASK_N(RcvHdrErr) +#define QIB_E_P_RHDRLEN ERR_MASK_N(RcvHdrLenErr) +#define QIB_E_P_RBADTID ERR_MASK_N(RcvBadTidErr) +#define QIB_E_P_RBADVERSION ERR_MASK_N(RcvBadVersionErr) +#define QIB_E_P_RIBFLOW ERR_MASK_N(RcvIBFlowErr) +#define QIB_E_P_REBP ERR_MASK_N(RcvEBPErr) +#define QIB_E_P_RUNSUPVL ERR_MASK_N(RcvUnsupportedVLErr) +#define QIB_E_P_RUNEXPCHAR ERR_MASK_N(RcvUnexpectedCharErr) +#define QIB_E_P_RSHORTPKTLEN ERR_MASK_N(RcvShortPktLenErr) +#define QIB_E_P_RLONGPKTLEN ERR_MASK_N(RcvLongPktLenErr) +#define QIB_E_P_RMAXPKTLEN ERR_MASK_N(RcvMaxPktLenErr) +#define QIB_E_P_RMINPKTLEN ERR_MASK_N(RcvMinPktLenErr) +#define QIB_E_P_RICRC ERR_MASK_N(RcvICRCErr) +#define QIB_E_P_RVCRC ERR_MASK_N(RcvVCRCErr) +#define QIB_E_P_RFORMATERR ERR_MASK_N(RcvFormatErr) + +#define QIB_E_P_SDMA1STDESC ERR_MASK_N(SDma1stDescErr) +#define QIB_E_P_SDMABASE ERR_MASK_N(SDmaBaseErr) +#define QIB_E_P_SDMADESCADDRMISALIGN ERR_MASK_N(SDmaDescAddrMisalignErr) +#define QIB_E_P_SDMADWEN ERR_MASK_N(SDmaDwEnErr) +#define QIB_E_P_SDMAGENMISMATCH ERR_MASK_N(SDmaGenMismatchErr) +#define QIB_E_P_SDMAHALT ERR_MASK_N(SDmaHaltErr) +#define QIB_E_P_SDMAMISSINGDW ERR_MASK_N(SDmaMissingDwErr) +#define QIB_E_P_SDMAOUTOFBOUND ERR_MASK_N(SDmaOutOfBoundErr) +#define QIB_E_P_SDMARPYTAG ERR_MASK_N(SDmaRpyTagErr) +#define QIB_E_P_SDMATAILOUTOFBOUND ERR_MASK_N(SDmaTailOutOfBoundErr) +#define QIB_E_P_SDMAUNEXPDATA ERR_MASK_N(SDmaUnexpDataErr) + +/* Error bits that are common to a device */ +#define QIB_E_RESET ERR_MASK(ResetNegated) +#define QIB_E_HARDWARE ERR_MASK(HardwareErr) +#define QIB_E_INVALIDADDR ERR_MASK(InvalidAddrErr) + + +/* + * Per chip (rather than per-port) errors. Most either do + * nothing but trigger a print (because they self-recover, or + * always occur in tandem with other errors that handle the + * issue), or because they indicate errors with no recovery, + * but we want to know that they happened. + */ +#define QIB_E_SBUF_VL15_MISUSE ERR_MASK(SBufVL15MisUseErr) +#define QIB_E_BADEEP ERR_MASK(InvalidEEPCmd) +#define QIB_E_VLMISMATCH ERR_MASK(SendVLMismatchErr) +#define QIB_E_ARMLAUNCH ERR_MASK(SendArmLaunchErr) +#define QIB_E_SPCLTRIG ERR_MASK(SendSpecialTriggerErr) +#define QIB_E_RRCVHDRFULL ERR_MASK(RcvHdrFullErr) +#define QIB_E_RRCVEGRFULL ERR_MASK(RcvEgrFullErr) +#define QIB_E_RCVCTXTSHARE ERR_MASK(RcvContextShareErr) + +/* SDMA chip errors (not per port) + * QIB_E_SDMA_BUF_DUP needs no special handling, because we will also get + * the SDMAHALT error immediately, so we just print the dup error via the + * E_AUTO mechanism. This is true of most of the per-port fatal errors + * as well, but since this is port-independent, by definition, it's + * handled a bit differently. SDMA_VL15 and SDMA_WRONG_PORT are per + * packet send errors, and so are handled in the same manner as other + * per-packet errors. + */ +#define QIB_E_SDMA_VL15 ERR_MASK(SDmaVL15Err) +#define QIB_E_SDMA_WRONG_PORT ERR_MASK(SDmaWrongPortErr) +#define QIB_E_SDMA_BUF_DUP ERR_MASK(SDmaBufMaskDuplicateErr) + +/* + * Below functionally equivalent to legacy QLOGIC_IB_E_PKTERRS + * it is used to print "common" packet errors. + */ +#define QIB_E_P_PKTERRS (QIB_E_P_SPKTLEN |\ + QIB_E_P_SDROP_DATA | QIB_E_P_RVCRC |\ + QIB_E_P_RICRC | QIB_E_P_RSHORTPKTLEN |\ + QIB_E_P_VL15_BUF_MISUSE | QIB_E_P_SHDR | \ + QIB_E_P_REBP) + +/* Error Bits that Packet-related (Receive, per-port) */ +#define QIB_E_P_RPKTERRS (\ + QIB_E_P_RHDRLEN | QIB_E_P_RBADTID | \ + QIB_E_P_RBADVERSION | QIB_E_P_RHDR | \ + QIB_E_P_RLONGPKTLEN | QIB_E_P_RSHORTPKTLEN |\ + QIB_E_P_RMAXPKTLEN | QIB_E_P_RMINPKTLEN | \ + QIB_E_P_RFORMATERR | QIB_E_P_RUNSUPVL | \ + QIB_E_P_RUNEXPCHAR | QIB_E_P_RIBFLOW | QIB_E_P_REBP) + +/* + * Error bits that are Send-related (per port) + * (ARMLAUNCH excluded from E_SPKTERRS because it gets special handling). + * All of these potentially need to have a buffer disarmed + */ +#define QIB_E_P_SPKTERRS (\ + QIB_E_P_SUNEXP_PKTNUM |\ + QIB_E_P_SDROP_DATA | QIB_E_P_SDROP_SMP |\ + QIB_E_P_SMAXPKTLEN |\ + QIB_E_P_VL15_BUF_MISUSE | QIB_E_P_SHDR | \ + QIB_E_P_SMINPKTLEN | QIB_E_P_SPKTLEN | \ + QIB_E_P_SND_BUF_MISUSE | QIB_E_P_SUNSUPVL) + +#define QIB_E_SPKTERRS ( \ + QIB_E_SBUF_VL15_MISUSE | QIB_E_VLMISMATCH | \ + ERR_MASK_N(SendUnsupportedVLErr) | \ + QIB_E_SPCLTRIG | QIB_E_SDMA_VL15 | QIB_E_SDMA_WRONG_PORT) + +#define QIB_E_P_SDMAERRS ( \ + QIB_E_P_SDMAHALT | \ + QIB_E_P_SDMADESCADDRMISALIGN | \ + QIB_E_P_SDMAUNEXPDATA | \ + QIB_E_P_SDMAMISSINGDW | \ + QIB_E_P_SDMADWEN | \ + QIB_E_P_SDMARPYTAG | \ + QIB_E_P_SDMA1STDESC | \ + QIB_E_P_SDMABASE | \ + QIB_E_P_SDMATAILOUTOFBOUND | \ + QIB_E_P_SDMAOUTOFBOUND | \ + QIB_E_P_SDMAGENMISMATCH) + +/* + * This sets some bits more than once, but makes it more obvious which + * bits are not handled under other categories, and the repeat definition + * is not a problem. + */ +#define QIB_E_P_BITSEXTANT ( \ + QIB_E_P_SPKTERRS | QIB_E_P_PKTERRS | QIB_E_P_RPKTERRS | \ + QIB_E_P_RIBLOSTLINK | QIB_E_P_IBSTATUSCHANGED | \ + QIB_E_P_SND_BUF_MISUSE | QIB_E_P_SUNDERRUN | \ + QIB_E_P_SHDR | QIB_E_P_VL15_BUF_MISUSE | QIB_E_P_SDMAERRS \ + ) + +/* + * These are errors that can occur when the link + * changes state while a packet is being sent or received. This doesn't + * cover things like EBP or VCRC that can be the result of a sending + * having the link change state, so we receive a "known bad" packet. + * All of these are "per port", so renamed: + */ +#define QIB_E_P_LINK_PKTERRS (\ + QIB_E_P_SDROP_DATA | QIB_E_P_SDROP_SMP |\ + QIB_E_P_SMINPKTLEN | QIB_E_P_SPKTLEN |\ + QIB_E_P_RSHORTPKTLEN | QIB_E_P_RMINPKTLEN |\ + QIB_E_P_RUNEXPCHAR) + +/* + * This sets some bits more than once, but makes it more obvious which + * bits are not handled under other categories (such as QIB_E_SPKTERRS), + * and the repeat definition is not a problem. + */ +#define QIB_E_C_BITSEXTANT (\ + QIB_E_HARDWARE | QIB_E_INVALIDADDR | QIB_E_BADEEP |\ + QIB_E_ARMLAUNCH | QIB_E_VLMISMATCH | QIB_E_RRCVHDRFULL |\ + QIB_E_RRCVEGRFULL | QIB_E_RESET | QIB_E_SBUF_VL15_MISUSE) + +/* Likewise Neuter E_SPKT_ERRS_IGNORE */ +#define E_SPKT_ERRS_IGNORE 0 + +#define QIB_EXTS_MEMBIST_DISABLED \ + SYM_MASK(EXTStatus, MemBISTDisabled) +#define QIB_EXTS_MEMBIST_ENDTEST \ + SYM_MASK(EXTStatus, MemBISTEndTest) + +#define QIB_E_SPIOARMLAUNCH \ + ERR_MASK(SendArmLaunchErr) + +#define IBA7322_IBCC_LINKINITCMD_MASK SYM_RMASK(IBCCtrlA_0, LinkInitCmd) +#define IBA7322_IBCC_LINKCMD_SHIFT SYM_LSB(IBCCtrlA_0, LinkCmd) + +/* + * IBTA_1_2 is set when multiple speeds are enabled (normal), + * and also if forced QDR (only QDR enabled). It's enabled for the + * forced QDR case so that scrambling will be enabled by the TS3 + * exchange, when supported by both sides of the link. + */ +#define IBA7322_IBC_IBTA_1_2_MASK SYM_MASK(IBCCtrlB_0, IB_ENHANCED_MODE) +#define IBA7322_IBC_MAX_SPEED_MASK SYM_MASK(IBCCtrlB_0, SD_SPEED) +#define IBA7322_IBC_SPEED_QDR SYM_MASK(IBCCtrlB_0, SD_SPEED_QDR) +#define IBA7322_IBC_SPEED_DDR SYM_MASK(IBCCtrlB_0, SD_SPEED_DDR) +#define IBA7322_IBC_SPEED_SDR SYM_MASK(IBCCtrlB_0, SD_SPEED_SDR) +#define IBA7322_IBC_SPEED_MASK (SYM_MASK(IBCCtrlB_0, SD_SPEED_SDR) | \ + SYM_MASK(IBCCtrlB_0, SD_SPEED_DDR) | SYM_MASK(IBCCtrlB_0, SD_SPEED_QDR)) +#define IBA7322_IBC_SPEED_LSB SYM_LSB(IBCCtrlB_0, SD_SPEED_SDR) + +#define IBA7322_LEDBLINK_OFF_SHIFT SYM_LSB(RcvPktLEDCnt_0, OFFperiod) +#define IBA7322_LEDBLINK_ON_SHIFT SYM_LSB(RcvPktLEDCnt_0, ONperiod) + +#define IBA7322_IBC_WIDTH_AUTONEG SYM_MASK(IBCCtrlB_0, IB_NUM_CHANNELS) +#define IBA7322_IBC_WIDTH_4X_ONLY (1<> \ + SYM_LSB(IBCCtrlB_0, HRTBT_ENB)) +#define IBA7322_IBC_HRTBT_LSB SYM_LSB(IBCCtrlB_0, HRTBT_ENB) + +#define IBA7322_REDIRECT_VEC_PER_REG 12 + +#define IBA7322_SENDCHK_PKEY SYM_MASK(SendCheckControl_0, PKey_En) +#define IBA7322_SENDCHK_BTHQP SYM_MASK(SendCheckControl_0, BTHQP_En) +#define IBA7322_SENDCHK_SLID SYM_MASK(SendCheckControl_0, SLID_En) +#define IBA7322_SENDCHK_RAW_IPV6 SYM_MASK(SendCheckControl_0, RawIPV6_En) +#define IBA7322_SENDCHK_MINSZ SYM_MASK(SendCheckControl_0, PacketTooSmall_En) + +#define AUTONEG_TRIES 3 /* sequential retries to negotiate DDR */ + +#define HWE_AUTO(fldname) { .mask = SYM_MASK(HwErrMask, fldname##Mask), \ + .msg = #fldname } +#define HWE_AUTO_P(fldname, port) { .mask = SYM_MASK(HwErrMask, \ + fldname##Mask##_##port), .msg = #fldname } +static const struct qib_hwerror_msgs qib_7322_hwerror_msgs[] = { + HWE_AUTO_P(IBSerdesPClkNotDetect, 1), + HWE_AUTO_P(IBSerdesPClkNotDetect, 0), + HWE_AUTO(PCIESerdesPClkNotDetect), + HWE_AUTO(PowerOnBISTFailed), + HWE_AUTO(TempsenseTholdReached), + HWE_AUTO(MemoryErr), + HWE_AUTO(PCIeBusParityErr), + HWE_AUTO(PcieCplTimeout), + HWE_AUTO(PciePoisonedTLP), + HWE_AUTO_P(SDmaMemReadErr, 1), + HWE_AUTO_P(SDmaMemReadErr, 0), + HWE_AUTO_P(IBCBusFromSPCParityErr, 1), + HWE_AUTO_P(IBCBusFromSPCParityErr, 0), + HWE_AUTO_P(statusValidNoEop, 1), + HWE_AUTO_P(statusValidNoEop, 0), + HWE_AUTO(LATriggered), + { .mask = 0 } +}; + +#define E_AUTO(fldname) { .mask = SYM_MASK(ErrMask, fldname##Mask), \ + .msg = #fldname } +#define E_P_AUTO(fldname) { .mask = SYM_MASK(ErrMask_0, fldname##Mask), \ + .msg = #fldname } +static const struct qib_hwerror_msgs qib_7322error_msgs[] = { + E_AUTO(ResetNegated), + E_AUTO(HardwareErr), + E_AUTO(InvalidAddrErr), + E_AUTO(SDmaVL15Err), + E_AUTO(SBufVL15MisUseErr), + E_AUTO(InvalidEEPCmd), + E_AUTO(RcvContextShareErr), + E_AUTO(SendVLMismatchErr), + E_AUTO(SendArmLaunchErr), + E_AUTO(SendSpecialTriggerErr), + E_AUTO(SDmaWrongPortErr), + E_AUTO(SDmaBufMaskDuplicateErr), + E_AUTO(RcvHdrFullErr), + E_AUTO(RcvEgrFullErr), + { .mask = 0 } +}; + +static const struct qib_hwerror_msgs qib_7322p_error_msgs[] = { + E_P_AUTO(IBStatusChanged), + E_P_AUTO(SHeadersErr), + E_P_AUTO(VL15BufMisuseErr), + /* + * SDmaHaltErr is not really an error, make it clearer; + */ + {.mask = SYM_MASK(ErrMask_0, SDmaHaltErrMask), .msg = "SDmaHalted"}, + E_P_AUTO(SDmaDescAddrMisalignErr), + E_P_AUTO(SDmaUnexpDataErr), + E_P_AUTO(SDmaMissingDwErr), + E_P_AUTO(SDmaDwEnErr), + E_P_AUTO(SDmaRpyTagErr), + E_P_AUTO(SDma1stDescErr), + E_P_AUTO(SDmaBaseErr), + E_P_AUTO(SDmaTailOutOfBoundErr), + E_P_AUTO(SDmaOutOfBoundErr), + E_P_AUTO(SDmaGenMismatchErr), + E_P_AUTO(SendBufMisuseErr), + E_P_AUTO(SendUnsupportedVLErr), + E_P_AUTO(SendUnexpectedPktNumErr), + E_P_AUTO(SendDroppedDataPktErr), + E_P_AUTO(SendDroppedSmpPktErr), + E_P_AUTO(SendPktLenErr), + E_P_AUTO(SendUnderRunErr), + E_P_AUTO(SendMaxPktLenErr), + E_P_AUTO(SendMinPktLenErr), + E_P_AUTO(RcvIBLostLinkErr), + E_P_AUTO(RcvHdrErr), + E_P_AUTO(RcvHdrLenErr), + E_P_AUTO(RcvBadTidErr), + E_P_AUTO(RcvBadVersionErr), + E_P_AUTO(RcvIBFlowErr), + E_P_AUTO(RcvEBPErr), + E_P_AUTO(RcvUnsupportedVLErr), + E_P_AUTO(RcvUnexpectedCharErr), + E_P_AUTO(RcvShortPktLenErr), + E_P_AUTO(RcvLongPktLenErr), + E_P_AUTO(RcvMaxPktLenErr), + E_P_AUTO(RcvMinPktLenErr), + E_P_AUTO(RcvICRCErr), + E_P_AUTO(RcvVCRCErr), + E_P_AUTO(RcvFormatErr), + { .mask = 0 } +}; + +/* + * Below generates "auto-message" for interrupts not specific to any port or + * context + */ +#define INTR_AUTO(fldname) { .mask = SYM_MASK(IntMask, fldname##Mask), \ + .msg = #fldname } +/* Below generates "auto-message" for interrupts specific to a port */ +#define INTR_AUTO_P(fldname) { .mask = MASK_ACROSS(\ + SYM_LSB(IntMask, fldname##Mask##_0), \ + SYM_LSB(IntMask, fldname##Mask##_1)), \ + .msg = #fldname "_P" } +/* For some reason, the SerDesTrimDone bits are reversed */ +#define INTR_AUTO_PI(fldname) { .mask = MASK_ACROSS(\ + SYM_LSB(IntMask, fldname##Mask##_1), \ + SYM_LSB(IntMask, fldname##Mask##_0)), \ + .msg = #fldname "_P" } +/* + * Below generates "auto-message" for interrupts specific to a context, + * with ctxt-number appended + */ +#define INTR_AUTO_C(fldname) { .mask = MASK_ACROSS(\ + SYM_LSB(IntMask, fldname##0IntMask), \ + SYM_LSB(IntMask, fldname##17IntMask)), \ + .msg = #fldname "_C"} + +static const struct qib_hwerror_msgs qib_7322_intr_msgs[] = { + INTR_AUTO_P(SDmaInt), + INTR_AUTO_P(SDmaProgressInt), + INTR_AUTO_P(SDmaIdleInt), + INTR_AUTO_P(SDmaCleanupDone), + INTR_AUTO_C(RcvUrg), + INTR_AUTO_P(ErrInt), + INTR_AUTO(ErrInt), /* non-port-specific errs */ + INTR_AUTO(AssertGPIOInt), + INTR_AUTO_P(SendDoneInt), + INTR_AUTO(SendBufAvailInt), + INTR_AUTO_C(RcvAvail), + { .mask = 0 } +}; + +#define TXSYMPTOM_AUTO_P(fldname) \ + { .mask = SYM_MASK(SendHdrErrSymptom_0, fldname), .msg = #fldname } +static const struct qib_hwerror_msgs hdrchk_msgs[] = { + TXSYMPTOM_AUTO_P(NonKeyPacket), + TXSYMPTOM_AUTO_P(GRHFail), + TXSYMPTOM_AUTO_P(PkeyFail), + TXSYMPTOM_AUTO_P(QPFail), + TXSYMPTOM_AUTO_P(SLIDFail), + TXSYMPTOM_AUTO_P(RawIPV6), + TXSYMPTOM_AUTO_P(PacketTooSmall), + { .mask = 0 } +}; + +#define IBA7322_HDRHEAD_PKTINT_SHIFT 32 /* interrupt cnt in upper 32 bits */ + +/* + * Called when we might have an error that is specific to a particular + * PIO buffer, and may need to cancel that buffer, so it can be re-used, + * because we don't need to force the update of pioavail + */ +static void qib_disarm_7322_senderrbufs(struct qib_pportdata *ppd) +{ + struct qib_devdata *dd = ppd->dd; + u32 i; + int any; + u32 piobcnt = dd->piobcnt2k + dd->piobcnt4k + NUM_VL15_BUFS; + u32 regcnt = (piobcnt + BITS_PER_LONG - 1) / BITS_PER_LONG; + unsigned long sbuf[4]; + + /* + * It's possible that sendbuffererror could have bits set; might + * have already done this as a result of hardware error handling. + */ + any = 0; + for (i = 0; i < regcnt; ++i) { + sbuf[i] = qib_read_kreg64(dd, kr_sendbuffererror + i); + if (sbuf[i]) { + any = 1; + qib_write_kreg(dd, kr_sendbuffererror + i, sbuf[i]); + } + } + + if (any) + qib_disarm_piobufs_set(dd, sbuf, piobcnt); +} + +/* No txe_recover yet, if ever */ + +/* No decode__errors yet */ +static void err_decode(char *msg, size_t len, u64 errs, + const struct qib_hwerror_msgs *msp) +{ + u64 these, lmask; + int took, multi, n = 0; + + while (msp && msp->mask) { + multi = (msp->mask & (msp->mask - 1)); + while (errs & msp->mask) { + these = (errs & msp->mask); + lmask = (these & (these - 1)) ^ these; + if (len) { + if (n++) { + /* separate the strings */ + *msg++ = ','; + len--; + } + took = scnprintf(msg, len, "%s", msp->msg); + len -= took; + msg += took; + } + errs &= ~lmask; + if (len && multi) { + /* More than one bit this mask */ + int idx = -1; + + while (lmask & msp->mask) { + ++idx; + lmask >>= 1; + } + took = scnprintf(msg, len, "_%d", idx); + len -= took; + msg += took; + } + } + ++msp; + } + /* If some bits are left, show in hex. */ + if (len && errs) + snprintf(msg, len, "%sMORE:%llX", n ? "," : "", + (unsigned long long) errs); +} + +/* only called if r1 set */ +static void flush_fifo(struct qib_pportdata *ppd) +{ + struct qib_devdata *dd = ppd->dd; + u32 __iomem *piobuf; + u32 bufn; + u32 *hdr; + u64 pbc; + const unsigned hdrwords = 7; + static struct qib_ib_header ibhdr = { + .lrh[0] = cpu_to_be16(0xF000 | QIB_LRH_BTH), + .lrh[1] = IB_LID_PERMISSIVE, + .lrh[2] = cpu_to_be16(hdrwords + SIZE_OF_CRC), + .lrh[3] = IB_LID_PERMISSIVE, + .u.oth.bth[0] = cpu_to_be32( + (IB_OPCODE_UD_SEND_ONLY << 24) | QIB_DEFAULT_P_KEY), + .u.oth.bth[1] = cpu_to_be32(0), + .u.oth.bth[2] = cpu_to_be32(0), + .u.oth.u.ud.deth[0] = cpu_to_be32(0), + .u.oth.u.ud.deth[1] = cpu_to_be32(0), + }; + + /* + * Send a dummy VL15 packet to flush the launch FIFO. + * This will not actually be sent since the TxeBypassIbc bit is set. + */ + pbc = PBC_7322_VL15_SEND | + (((u64)ppd->hw_pidx) << (PBC_PORT_SEL_LSB + 32)) | + (hdrwords + SIZE_OF_CRC); + piobuf = qib_7322_getsendbuf(ppd, pbc, &bufn); + if (!piobuf) + return; + writeq(pbc, piobuf); + hdr = (u32 *) &ibhdr; + if (dd->flags & QIB_PIO_FLUSH_WC) { + qib_flush_wc(); + qib_pio_copy(piobuf + 2, hdr, hdrwords - 1); + qib_flush_wc(); + __raw_writel(hdr[hdrwords - 1], piobuf + hdrwords + 1); + qib_flush_wc(); + } else + qib_pio_copy(piobuf + 2, hdr, hdrwords); + qib_sendbuf_done(dd, bufn); +} + +/* + * This is called with interrupts disabled and sdma_lock held. + */ +static void qib_7322_sdma_sendctrl(struct qib_pportdata *ppd, unsigned op) +{ + struct qib_devdata *dd = ppd->dd; + u64 set_sendctrl = 0; + u64 clr_sendctrl = 0; + + if (op & QIB_SDMA_SENDCTRL_OP_ENABLE) + set_sendctrl |= SYM_MASK(SendCtrl_0, SDmaEnable); + else + clr_sendctrl |= SYM_MASK(SendCtrl_0, SDmaEnable); + + if (op & QIB_SDMA_SENDCTRL_OP_INTENABLE) + set_sendctrl |= SYM_MASK(SendCtrl_0, SDmaIntEnable); + else + clr_sendctrl |= SYM_MASK(SendCtrl_0, SDmaIntEnable); + + if (op & QIB_SDMA_SENDCTRL_OP_HALT) + set_sendctrl |= SYM_MASK(SendCtrl_0, SDmaHalt); + else + clr_sendctrl |= SYM_MASK(SendCtrl_0, SDmaHalt); + + if (op & QIB_SDMA_SENDCTRL_OP_DRAIN) + set_sendctrl |= SYM_MASK(SendCtrl_0, TxeBypassIbc) | + SYM_MASK(SendCtrl_0, TxeAbortIbc) | + SYM_MASK(SendCtrl_0, TxeDrainRmFifo); + else + clr_sendctrl |= SYM_MASK(SendCtrl_0, TxeBypassIbc) | + SYM_MASK(SendCtrl_0, TxeAbortIbc) | + SYM_MASK(SendCtrl_0, TxeDrainRmFifo); + + spin_lock(&dd->sendctrl_lock); + + /* If we are draining everything, block sends first */ + if (op & QIB_SDMA_SENDCTRL_OP_DRAIN) { + ppd->p_sendctrl &= ~SYM_MASK(SendCtrl_0, SendEnable); + qib_write_kreg_port(ppd, krp_sendctrl, ppd->p_sendctrl); + qib_write_kreg(dd, kr_scratch, 0); + } + + ppd->p_sendctrl |= set_sendctrl; + ppd->p_sendctrl &= ~clr_sendctrl; + + if (op & QIB_SDMA_SENDCTRL_OP_CLEANUP) + qib_write_kreg_port(ppd, krp_sendctrl, + ppd->p_sendctrl | + SYM_MASK(SendCtrl_0, SDmaCleanup)); + else + qib_write_kreg_port(ppd, krp_sendctrl, ppd->p_sendctrl); + qib_write_kreg(dd, kr_scratch, 0); + + if (op & QIB_SDMA_SENDCTRL_OP_DRAIN) { + ppd->p_sendctrl |= SYM_MASK(SendCtrl_0, SendEnable); + qib_write_kreg_port(ppd, krp_sendctrl, ppd->p_sendctrl); + qib_write_kreg(dd, kr_scratch, 0); + } + + spin_unlock(&dd->sendctrl_lock); + + if ((op & QIB_SDMA_SENDCTRL_OP_DRAIN) && ppd->dd->cspec->r1) + flush_fifo(ppd); +} + +static void qib_7322_sdma_hw_clean_up(struct qib_pportdata *ppd) +{ + __qib_sdma_process_event(ppd, qib_sdma_event_e50_hw_cleaned); +} + +static void qib_sdma_7322_setlengen(struct qib_pportdata *ppd) +{ + /* + * Set SendDmaLenGen and clear and set + * the MSB of the generation count to enable generation checking + * and load the internal generation counter. + */ + qib_write_kreg_port(ppd, krp_senddmalengen, ppd->sdma_descq_cnt); + qib_write_kreg_port(ppd, krp_senddmalengen, + ppd->sdma_descq_cnt | + (1ULL << QIB_7322_SendDmaLenGen_0_Generation_MSB)); +} + +/* + * Must be called with sdma_lock held, or before init finished. + */ +static void qib_sdma_update_7322_tail(struct qib_pportdata *ppd, u16 tail) +{ + /* Commit writes to memory and advance the tail on the chip */ + wmb(); + ppd->sdma_descq_tail = tail; + qib_write_kreg_port(ppd, krp_senddmatail, tail); +} + +/* + * This is called with interrupts disabled and sdma_lock held. + */ +static void qib_7322_sdma_hw_start_up(struct qib_pportdata *ppd) +{ + /* + * Drain all FIFOs. + * The hardware doesn't require this but we do it so that verbs + * and user applications don't wait for link active to send stale + * data. + */ + sendctrl_7322_mod(ppd, QIB_SENDCTRL_FLUSH); + + qib_sdma_7322_setlengen(ppd); + qib_sdma_update_7322_tail(ppd, 0); /* Set SendDmaTail */ + ppd->sdma_head_dma[0] = 0; + qib_7322_sdma_sendctrl(ppd, + ppd->sdma_state.current_op | QIB_SDMA_SENDCTRL_OP_CLEANUP); +} + +#define DISABLES_SDMA ( \ + QIB_E_P_SDMAHALT | \ + QIB_E_P_SDMADESCADDRMISALIGN | \ + QIB_E_P_SDMAMISSINGDW | \ + QIB_E_P_SDMADWEN | \ + QIB_E_P_SDMARPYTAG | \ + QIB_E_P_SDMA1STDESC | \ + QIB_E_P_SDMABASE | \ + QIB_E_P_SDMATAILOUTOFBOUND | \ + QIB_E_P_SDMAOUTOFBOUND | \ + QIB_E_P_SDMAGENMISMATCH) + +static void sdma_7322_p_errors(struct qib_pportdata *ppd, u64 errs) +{ + unsigned long flags; + struct qib_devdata *dd = ppd->dd; + + errs &= QIB_E_P_SDMAERRS; + + if (errs & QIB_E_P_SDMAUNEXPDATA) + qib_dev_err(dd, "IB%u:%u SDmaUnexpData\n", dd->unit, + ppd->port); + + spin_lock_irqsave(&ppd->sdma_lock, flags); + + switch (ppd->sdma_state.current_state) { + case qib_sdma_state_s00_hw_down: + break; + + case qib_sdma_state_s10_hw_start_up_wait: + if (errs & QIB_E_P_SDMAHALT) + __qib_sdma_process_event(ppd, + qib_sdma_event_e20_hw_started); + break; + + case qib_sdma_state_s20_idle: + break; + + case qib_sdma_state_s30_sw_clean_up_wait: + break; + + case qib_sdma_state_s40_hw_clean_up_wait: + if (errs & QIB_E_P_SDMAHALT) + __qib_sdma_process_event(ppd, + qib_sdma_event_e50_hw_cleaned); + break; + + case qib_sdma_state_s50_hw_halt_wait: + if (errs & QIB_E_P_SDMAHALT) + __qib_sdma_process_event(ppd, + qib_sdma_event_e60_hw_halted); + break; + + case qib_sdma_state_s99_running: + __qib_sdma_process_event(ppd, qib_sdma_event_e7322_err_halted); + __qib_sdma_process_event(ppd, qib_sdma_event_e60_hw_halted); + break; + } + + spin_unlock_irqrestore(&ppd->sdma_lock, flags); +} + +/* + * handle per-device errors (not per-port errors) + */ +static noinline void handle_7322_errors(struct qib_devdata *dd) +{ + char *msg; + u64 iserr = 0; + u64 errs; + u64 mask; + int log_idx; + + qib_stats.sps_errints++; + errs = qib_read_kreg64(dd, kr_errstatus); + if (!errs) { + qib_devinfo(dd->pcidev, "device error interrupt, " + "but no error bits set!\n"); + goto done; + } + + /* don't report errors that are masked */ + errs &= dd->cspec->errormask; + msg = dd->cspec->emsgbuf; + + /* do these first, they are most important */ + if (errs & QIB_E_HARDWARE) { + *msg = '\0'; + qib_7322_handle_hwerrors(dd, msg, sizeof dd->cspec->emsgbuf); + } else + for (log_idx = 0; log_idx < QIB_EEP_LOG_CNT; ++log_idx) + if (errs & dd->eep_st_masks[log_idx].errs_to_log) + qib_inc_eeprom_err(dd, log_idx, 1); + + if (errs & QIB_E_SPKTERRS) { + qib_disarm_7322_senderrbufs(dd->pport); + qib_stats.sps_txerrs++; + } else if (errs & QIB_E_INVALIDADDR) + qib_stats.sps_txerrs++; + else if (errs & QIB_E_ARMLAUNCH) { + qib_stats.sps_txerrs++; + qib_disarm_7322_senderrbufs(dd->pport); + } + qib_write_kreg(dd, kr_errclear, errs); + + /* + * The ones we mask off are handled specially below + * or above. Also mask SDMADISABLED by default as it + * is too chatty. + */ + mask = QIB_E_HARDWARE; + *msg = '\0'; + + err_decode(msg, sizeof dd->cspec->emsgbuf, errs & ~mask, + qib_7322error_msgs); + + /* + * Getting reset is a tragedy for all ports. Mark the device + * _and_ the ports as "offline" in way meaningful to each. + */ + if (errs & QIB_E_RESET) { + int pidx; + + qib_dev_err(dd, "Got reset, requires re-init " + "(unload and reload driver)\n"); + dd->flags &= ~QIB_INITTED; /* needs re-init */ + /* mark as having had error */ + *dd->devstatusp |= QIB_STATUS_HWERROR; + for (pidx = 0; pidx < dd->num_pports; ++pidx) + if (dd->pport[pidx].link_speed_supported) + *dd->pport[pidx].statusp &= ~QIB_STATUS_IB_CONF; + } + + if (*msg && iserr) + qib_dev_err(dd, "%s error\n", msg); + + /* + * If there were hdrq or egrfull errors, wake up any processes + * waiting in poll. We used to try to check which contexts had + * the overflow, but given the cost of that and the chip reads + * to support it, it's better to just wake everybody up if we + * get an overflow; waiters can poll again if it's not them. + */ + if (errs & (ERR_MASK(RcvEgrFullErr) | ERR_MASK(RcvHdrFullErr))) { + qib_handle_urcv(dd, ~0U); + if (errs & ERR_MASK(RcvEgrFullErr)) + qib_stats.sps_buffull++; + else + qib_stats.sps_hdrfull++; + } + +done: + return; +} + +static void reenable_chase(unsigned long opaque) +{ + struct qib_pportdata *ppd = (struct qib_pportdata *)opaque; + + ppd->cpspec->chase_timer.expires = 0; + qib_set_ib_7322_lstate(ppd, QLOGIC_IB_IBCC_LINKCMD_DOWN, + QLOGIC_IB_IBCC_LINKINITCMD_POLL); +} + +static void disable_chase(struct qib_pportdata *ppd, u64 tnow, u8 ibclt) +{ + ppd->cpspec->chase_end = 0; + + if (!qib_chase) + return; + + qib_set_ib_7322_lstate(ppd, QLOGIC_IB_IBCC_LINKCMD_DOWN, + QLOGIC_IB_IBCC_LINKINITCMD_DISABLE); + ppd->cpspec->chase_timer.expires = jiffies + QIB_CHASE_DIS_TIME; + add_timer(&ppd->cpspec->chase_timer); +} + +static void handle_serdes_issues(struct qib_pportdata *ppd, u64 ibcst) +{ + u8 ibclt; + u64 tnow; + + ibclt = (u8)SYM_FIELD(ibcst, IBCStatusA_0, LinkTrainingState); + + /* + * Detect and handle the state chase issue, where we can + * get stuck if we are unlucky on timing on both sides of + * the link. If we are, we disable, set a timer, and + * then re-enable. + */ + switch (ibclt) { + case IB_7322_LT_STATE_CFGRCVFCFG: + case IB_7322_LT_STATE_CFGWAITRMT: + case IB_7322_LT_STATE_TXREVLANES: + case IB_7322_LT_STATE_CFGENH: + tnow = get_jiffies_64(); + if (ppd->cpspec->chase_end && + time_after64(tnow, ppd->cpspec->chase_end)) + disable_chase(ppd, tnow, ibclt); + else if (!ppd->cpspec->chase_end) + ppd->cpspec->chase_end = tnow + QIB_CHASE_TIME; + break; + default: + ppd->cpspec->chase_end = 0; + break; + } + + if (ibclt == IB_7322_LT_STATE_CFGTEST && + (ibcst & SYM_MASK(IBCStatusA_0, LinkSpeedQDR))) { + force_h1(ppd); + ppd->cpspec->qdr_reforce = 1; + } else if (ppd->cpspec->qdr_reforce && + (ibcst & SYM_MASK(IBCStatusA_0, LinkSpeedQDR)) && + (ibclt == IB_7322_LT_STATE_CFGENH || + ibclt == IB_7322_LT_STATE_CFGIDLE || + ibclt == IB_7322_LT_STATE_LINKUP)) + force_h1(ppd); + + if ((IS_QMH(ppd->dd) || IS_QME(ppd->dd)) && + ppd->link_speed_enabled == QIB_IB_QDR && + (ibclt == IB_7322_LT_STATE_CFGTEST || + ibclt == IB_7322_LT_STATE_CFGENH || + (ibclt >= IB_7322_LT_STATE_POLLACTIVE && + ibclt <= IB_7322_LT_STATE_SLEEPQUIET))) + adj_tx_serdes(ppd); + + if (!ppd->cpspec->qdr_dfe_on && ibclt != IB_7322_LT_STATE_LINKUP && + ibclt <= IB_7322_LT_STATE_SLEEPQUIET) { + ppd->cpspec->qdr_dfe_on = 1; + ppd->cpspec->qdr_dfe_time = 0; + /* On link down, reenable QDR adaptation */ + qib_write_kreg_port(ppd, krp_static_adapt_dis(2), + ppd->dd->cspec->r1 ? + QDR_STATIC_ADAPT_DOWN_R1 : + QDR_STATIC_ADAPT_DOWN); + } +} + +/* + * This is per-pport error handling. + * will likely get it's own MSIx interrupt (one for each port, + * although just a single handler). + */ +static noinline void handle_7322_p_errors(struct qib_pportdata *ppd) +{ + char *msg; + u64 ignore_this_time = 0, iserr = 0, errs, fmask; + struct qib_devdata *dd = ppd->dd; + + /* do this as soon as possible */ + fmask = qib_read_kreg64(dd, kr_act_fmask); + if (!fmask) + check_7322_rxe_status(ppd); + + errs = qib_read_kreg_port(ppd, krp_errstatus); + if (!errs) + qib_devinfo(dd->pcidev, + "Port%d error interrupt, but no error bits set!\n", + ppd->port); + if (!fmask) + errs &= ~QIB_E_P_IBSTATUSCHANGED; + if (!errs) + goto done; + + msg = ppd->cpspec->epmsgbuf; + *msg = '\0'; + + if (errs & ~QIB_E_P_BITSEXTANT) { + err_decode(msg, sizeof ppd->cpspec->epmsgbuf, + errs & ~QIB_E_P_BITSEXTANT, qib_7322p_error_msgs); + if (!*msg) + snprintf(msg, sizeof ppd->cpspec->epmsgbuf, + "no others"); + qib_dev_porterr(dd, ppd->port, "error interrupt with unknown" + " errors 0x%016Lx set (and %s)\n", + (errs & ~QIB_E_P_BITSEXTANT), msg); + *msg = '\0'; + } + + if (errs & QIB_E_P_SHDR) { + u64 symptom; + + /* determine cause, then write to clear */ + symptom = qib_read_kreg_port(ppd, krp_sendhdrsymptom); + qib_write_kreg_port(ppd, krp_sendhdrsymptom, 0); + err_decode(msg, sizeof ppd->cpspec->epmsgbuf, symptom, + hdrchk_msgs); + *msg = '\0'; + /* senderrbuf cleared in SPKTERRS below */ + } + + if (errs & QIB_E_P_SPKTERRS) { + if ((errs & QIB_E_P_LINK_PKTERRS) && + !(ppd->lflags & QIBL_LINKACTIVE)) { + /* + * This can happen when trying to bring the link + * up, but the IB link changes state at the "wrong" + * time. The IB logic then complains that the packet + * isn't valid. We don't want to confuse people, so + * we just don't print them, except at debug + */ + err_decode(msg, sizeof ppd->cpspec->epmsgbuf, + (errs & QIB_E_P_LINK_PKTERRS), + qib_7322p_error_msgs); + *msg = '\0'; + ignore_this_time = errs & QIB_E_P_LINK_PKTERRS; + } + qib_disarm_7322_senderrbufs(ppd); + } else if ((errs & QIB_E_P_LINK_PKTERRS) && + !(ppd->lflags & QIBL_LINKACTIVE)) { + /* + * This can happen when SMA is trying to bring the link + * up, but the IB link changes state at the "wrong" time. + * The IB logic then complains that the packet isn't + * valid. We don't want to confuse people, so we just + * don't print them, except at debug + */ + err_decode(msg, sizeof ppd->cpspec->epmsgbuf, errs, + qib_7322p_error_msgs); + ignore_this_time = errs & QIB_E_P_LINK_PKTERRS; + *msg = '\0'; + } + + qib_write_kreg_port(ppd, krp_errclear, errs); + + errs &= ~ignore_this_time; + if (!errs) + goto done; + + if (errs & QIB_E_P_RPKTERRS) + qib_stats.sps_rcverrs++; + if (errs & QIB_E_P_SPKTERRS) + qib_stats.sps_txerrs++; + + iserr = errs & ~(QIB_E_P_RPKTERRS | QIB_E_P_PKTERRS); + + if (errs & QIB_E_P_SDMAERRS) + sdma_7322_p_errors(ppd, errs); + + if (errs & QIB_E_P_IBSTATUSCHANGED) { + u64 ibcs; + u8 ltstate; + + ibcs = qib_read_kreg_port(ppd, krp_ibcstatus_a); + ltstate = qib_7322_phys_portstate(ibcs); + + if (!(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) + handle_serdes_issues(ppd, ibcs); + if (!(ppd->cpspec->ibcctrl_a & + SYM_MASK(IBCCtrlA_0, IBStatIntReductionEn))) { + /* + * We got our interrupt, so init code should be + * happy and not try alternatives. Now squelch + * other "chatter" from link-negotiation (pre Init) + */ + ppd->cpspec->ibcctrl_a |= + SYM_MASK(IBCCtrlA_0, IBStatIntReductionEn); + qib_write_kreg_port(ppd, krp_ibcctrl_a, + ppd->cpspec->ibcctrl_a); + } + + /* Update our picture of width and speed from chip */ + ppd->link_width_active = + (ibcs & SYM_MASK(IBCStatusA_0, LinkWidthActive)) ? + IB_WIDTH_4X : IB_WIDTH_1X; + ppd->link_speed_active = (ibcs & SYM_MASK(IBCStatusA_0, + LinkSpeedQDR)) ? QIB_IB_QDR : (ibcs & + SYM_MASK(IBCStatusA_0, LinkSpeedActive)) ? + QIB_IB_DDR : QIB_IB_SDR; + + if ((ppd->lflags & QIBL_IB_LINK_DISABLED) && ltstate != + IB_PHYSPORTSTATE_DISABLED) + qib_set_ib_7322_lstate(ppd, 0, + QLOGIC_IB_IBCC_LINKINITCMD_DISABLE); + else + /* + * Since going into a recovery state causes the link + * state to go down and since recovery is transitory, + * it is better if we "miss" ever seeing the link + * training state go into recovery (i.e., ignore this + * transition for link state special handling purposes) + * without updating lastibcstat. + */ + if (ltstate != IB_PHYSPORTSTATE_LINK_ERR_RECOVER && + ltstate != IB_PHYSPORTSTATE_RECOVERY_RETRAIN && + ltstate != IB_PHYSPORTSTATE_RECOVERY_WAITRMT && + ltstate != IB_PHYSPORTSTATE_RECOVERY_IDLE) + qib_handle_e_ibstatuschanged(ppd, ibcs); + } + if (*msg && iserr) + qib_dev_porterr(dd, ppd->port, "%s error\n", msg); + + if (ppd->state_wanted & ppd->lflags) + wake_up_interruptible(&ppd->state_wait); +done: + return; +} + +/* enable/disable chip from delivering interrupts */ +static void qib_7322_set_intr_state(struct qib_devdata *dd, u32 enable) +{ + if (enable) { + if (dd->flags & QIB_BADINTR) + return; + qib_write_kreg(dd, kr_intmask, dd->cspec->int_enable_mask); + /* cause any pending enabled interrupts to be re-delivered */ + qib_write_kreg(dd, kr_intclear, 0ULL); + if (dd->cspec->num_msix_entries) { + /* and same for MSIx */ + u64 val = qib_read_kreg64(dd, kr_intgranted); + if (val) + qib_write_kreg(dd, kr_intgranted, val); + } + } else + qib_write_kreg(dd, kr_intmask, 0ULL); +} + +/* + * Try to cleanup as much as possible for anything that might have gone + * wrong while in freeze mode, such as pio buffers being written by user + * processes (causing armlaunch), send errors due to going into freeze mode, + * etc., and try to avoid causing extra interrupts while doing so. + * Forcibly update the in-memory pioavail register copies after cleanup + * because the chip won't do it while in freeze mode (the register values + * themselves are kept correct). + * Make sure that we don't lose any important interrupts by using the chip + * feature that says that writing 0 to a bit in *clear that is set in + * *status will cause an interrupt to be generated again (if allowed by + * the *mask value). + * This is in chip-specific code because of all of the register accesses, + * even though the details are similar on most chips. + */ +static void qib_7322_clear_freeze(struct qib_devdata *dd) +{ + int pidx; + + /* disable error interrupts, to avoid confusion */ + qib_write_kreg(dd, kr_errmask, 0ULL); + + for (pidx = 0; pidx < dd->num_pports; ++pidx) + if (dd->pport[pidx].link_speed_supported) + qib_write_kreg_port(dd->pport + pidx, krp_errmask, + 0ULL); + + /* also disable interrupts; errormask is sometimes overwriten */ + qib_7322_set_intr_state(dd, 0); + + /* clear the freeze, and be sure chip saw it */ + qib_write_kreg(dd, kr_control, dd->control); + qib_read_kreg32(dd, kr_scratch); + + /* + * Force new interrupt if any hwerr, error or interrupt bits are + * still set, and clear "safe" send packet errors related to freeze + * and cancelling sends. Re-enable error interrupts before possible + * force of re-interrupt on pending interrupts. + */ + qib_write_kreg(dd, kr_hwerrclear, 0ULL); + qib_write_kreg(dd, kr_errclear, E_SPKT_ERRS_IGNORE); + qib_write_kreg(dd, kr_errmask, dd->cspec->errormask); + /* We need to purge per-port errs and reset mask, too */ + for (pidx = 0; pidx < dd->num_pports; ++pidx) { + if (!dd->pport[pidx].link_speed_supported) + continue; + qib_write_kreg_port(dd->pport + pidx, krp_errclear, ~0Ull); + qib_write_kreg_port(dd->pport + pidx, krp_errmask, ~0Ull); + } + qib_7322_set_intr_state(dd, 1); +} + +/* no error handling to speak of */ +/** + * qib_7322_handle_hwerrors - display hardware errors. + * @dd: the qlogic_ib device + * @msg: the output buffer + * @msgl: the size of the output buffer + * + * Use same msg buffer as regular errors to avoid excessive stack + * use. Most hardware errors are catastrophic, but for right now, + * we'll print them and continue. We reuse the same message buffer as + * qib_handle_errors() to avoid excessive stack usage. + */ +static void qib_7322_handle_hwerrors(struct qib_devdata *dd, char *msg, + size_t msgl) +{ + u64 hwerrs; + u32 ctrl; + int isfatal = 0; + + hwerrs = qib_read_kreg64(dd, kr_hwerrstatus); + if (!hwerrs) + goto bail; + if (hwerrs == ~0ULL) { + qib_dev_err(dd, "Read of hardware error status failed " + "(all bits set); ignoring\n"); + goto bail; + } + qib_stats.sps_hwerrs++; + + /* Always clear the error status register, except BIST fail */ + qib_write_kreg(dd, kr_hwerrclear, hwerrs & + ~HWE_MASK(PowerOnBISTFailed)); + + hwerrs &= dd->cspec->hwerrmask; + + /* no EEPROM logging, yet */ + + if (hwerrs) + qib_devinfo(dd->pcidev, "Hardware error: hwerr=0x%llx " + "(cleared)\n", (unsigned long long) hwerrs); + + ctrl = qib_read_kreg32(dd, kr_control); + if ((ctrl & SYM_MASK(Control, FreezeMode)) && !dd->diag_client) { + /* + * No recovery yet... + */ + if ((hwerrs & ~HWE_MASK(LATriggered)) || + dd->cspec->stay_in_freeze) { + /* + * If any set that we aren't ignoring only make the + * complaint once, in case it's stuck or recurring, + * and we get here multiple times + * Force link down, so switch knows, and + * LEDs are turned off. + */ + if (dd->flags & QIB_INITTED) + isfatal = 1; + } else + qib_7322_clear_freeze(dd); + } + + if (hwerrs & HWE_MASK(PowerOnBISTFailed)) { + isfatal = 1; + strlcpy(msg, "[Memory BIST test failed, " + "InfiniPath hardware unusable]", msgl); + /* ignore from now on, so disable until driver reloaded */ + dd->cspec->hwerrmask &= ~HWE_MASK(PowerOnBISTFailed); + qib_write_kreg(dd, kr_hwerrmask, dd->cspec->hwerrmask); + } + + err_decode(msg, msgl, hwerrs, qib_7322_hwerror_msgs); + + /* Ignore esoteric PLL failures et al. */ + + qib_dev_err(dd, "%s hardware error\n", msg); + + if (isfatal && !dd->diag_client) { + qib_dev_err(dd, "Fatal Hardware Error, no longer" + " usable, SN %.16s\n", dd->serial); + /* + * for /sys status file and user programs to print; if no + * trailing brace is copied, we'll know it was truncated. + */ + if (dd->freezemsg) + snprintf(dd->freezemsg, dd->freezelen, + "{%s}", msg); + qib_disable_after_error(dd); + } +bail:; +} + +/** + * qib_7322_init_hwerrors - enable hardware errors + * @dd: the qlogic_ib device + * + * now that we have finished initializing everything that might reasonably + * cause a hardware error, and cleared those errors bits as they occur, + * we can enable hardware errors in the mask (potentially enabling + * freeze mode), and enable hardware errors as errors (along with + * everything else) in errormask + */ +static void qib_7322_init_hwerrors(struct qib_devdata *dd) +{ + int pidx; + u64 extsval; + + extsval = qib_read_kreg64(dd, kr_extstatus); + if (!(extsval & (QIB_EXTS_MEMBIST_DISABLED | + QIB_EXTS_MEMBIST_ENDTEST))) + qib_dev_err(dd, "MemBIST did not complete!\n"); + + /* never clear BIST failure, so reported on each driver load */ + qib_write_kreg(dd, kr_hwerrclear, ~HWE_MASK(PowerOnBISTFailed)); + qib_write_kreg(dd, kr_hwerrmask, dd->cspec->hwerrmask); + + /* clear all */ + qib_write_kreg(dd, kr_errclear, ~0ULL); + /* enable errors that are masked, at least this first time. */ + qib_write_kreg(dd, kr_errmask, ~0ULL); + dd->cspec->errormask = qib_read_kreg64(dd, kr_errmask); + for (pidx = 0; pidx < dd->num_pports; ++pidx) + if (dd->pport[pidx].link_speed_supported) + qib_write_kreg_port(dd->pport + pidx, krp_errmask, + ~0ULL); +} + +/* + * Disable and enable the armlaunch error. Used for PIO bandwidth testing + * on chips that are count-based, rather than trigger-based. There is no + * reference counting, but that's also fine, given the intended use. + * Only chip-specific because it's all register accesses + */ +static void qib_set_7322_armlaunch(struct qib_devdata *dd, u32 enable) +{ + if (enable) { + qib_write_kreg(dd, kr_errclear, QIB_E_SPIOARMLAUNCH); + dd->cspec->errormask |= QIB_E_SPIOARMLAUNCH; + } else + dd->cspec->errormask &= ~QIB_E_SPIOARMLAUNCH; + qib_write_kreg(dd, kr_errmask, dd->cspec->errormask); +} + +/* + * Formerly took parameter in pre-shifted, + * pre-merged form with LinkCmd and LinkInitCmd + * together, and assuming the zero was NOP. + */ +static void qib_set_ib_7322_lstate(struct qib_pportdata *ppd, u16 linkcmd, + u16 linitcmd) +{ + u64 mod_wd; + struct qib_devdata *dd = ppd->dd; + unsigned long flags; + + if (linitcmd == QLOGIC_IB_IBCC_LINKINITCMD_DISABLE) { + /* + * If we are told to disable, note that so link-recovery + * code does not attempt to bring us back up. + * Also reset everything that we can, so we start + * completely clean when re-enabled (before we + * actually issue the disable to the IBC) + */ + qib_7322_mini_pcs_reset(ppd); + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags |= QIBL_IB_LINK_DISABLED; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + } else if (linitcmd || linkcmd == QLOGIC_IB_IBCC_LINKCMD_DOWN) { + /* + * Any other linkinitcmd will lead to LINKDOWN and then + * to INIT (if all is well), so clear flag to let + * link-recovery code attempt to bring us back up. + */ + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags &= ~QIBL_IB_LINK_DISABLED; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + /* + * Clear status change interrupt reduction so the + * new state is seen. + */ + ppd->cpspec->ibcctrl_a &= + ~SYM_MASK(IBCCtrlA_0, IBStatIntReductionEn); + } + + mod_wd = (linkcmd << IBA7322_IBCC_LINKCMD_SHIFT) | + (linitcmd << QLOGIC_IB_IBCC_LINKINITCMD_SHIFT); + + qib_write_kreg_port(ppd, krp_ibcctrl_a, ppd->cpspec->ibcctrl_a | + mod_wd); + /* write to chip to prevent back-to-back writes of ibc reg */ + qib_write_kreg(dd, kr_scratch, 0); + +} + +/* + * The total RCV buffer memory is 64KB, used for both ports, and is + * in units of 64 bytes (same as IB flow control credit unit). + * The consumedVL unit in the same registers are in 32 byte units! + * So, a VL15 packet needs 4.50 IB credits, and 9 rx buffer chunks, + * and we can therefore allocate just 9 IB credits for 2 VL15 packets + * in krp_rxcreditvl15, rather than 10. + */ +#define RCV_BUF_UNITSZ 64 +#define NUM_RCV_BUF_UNITS(dd) ((64 * 1024) / (RCV_BUF_UNITSZ * dd->num_pports)) + +static void set_vls(struct qib_pportdata *ppd) +{ + int i, numvls, totcred, cred_vl, vl0extra; + struct qib_devdata *dd = ppd->dd; + u64 val; + + numvls = qib_num_vls(ppd->vls_operational); + + /* + * Set up per-VL credits. Below is kluge based on these assumptions: + * 1) port is disabled at the time early_init is called. + * 2) give VL15 17 credits, for two max-plausible packets. + * 3) Give VL0-N the rest, with any rounding excess used for VL0 + */ + /* 2 VL15 packets @ 288 bytes each (including IB headers) */ + totcred = NUM_RCV_BUF_UNITS(dd); + cred_vl = (2 * 288 + RCV_BUF_UNITSZ - 1) / RCV_BUF_UNITSZ; + totcred -= cred_vl; + qib_write_kreg_port(ppd, krp_rxcreditvl15, (u64) cred_vl); + cred_vl = totcred / numvls; + vl0extra = totcred - cred_vl * numvls; + qib_write_kreg_port(ppd, krp_rxcreditvl0, cred_vl + vl0extra); + for (i = 1; i < numvls; i++) + qib_write_kreg_port(ppd, krp_rxcreditvl0 + i, cred_vl); + for (; i < 8; i++) /* no buffer space for other VLs */ + qib_write_kreg_port(ppd, krp_rxcreditvl0 + i, 0); + + /* Notify IBC that credits need to be recalculated */ + val = qib_read_kreg_port(ppd, krp_ibsdtestiftx); + val |= SYM_MASK(IB_SDTEST_IF_TX_0, CREDIT_CHANGE); + qib_write_kreg_port(ppd, krp_ibsdtestiftx, val); + qib_write_kreg(dd, kr_scratch, 0ULL); + val &= ~SYM_MASK(IB_SDTEST_IF_TX_0, CREDIT_CHANGE); + qib_write_kreg_port(ppd, krp_ibsdtestiftx, val); + + for (i = 0; i < numvls; i++) + val = qib_read_kreg_port(ppd, krp_rxcreditvl0 + i); + val = qib_read_kreg_port(ppd, krp_rxcreditvl15); + + /* Change the number of operational VLs */ + ppd->cpspec->ibcctrl_a = (ppd->cpspec->ibcctrl_a & + ~SYM_MASK(IBCCtrlA_0, NumVLane)) | + ((u64)(numvls - 1) << SYM_LSB(IBCCtrlA_0, NumVLane)); + qib_write_kreg_port(ppd, krp_ibcctrl_a, ppd->cpspec->ibcctrl_a); + qib_write_kreg(dd, kr_scratch, 0ULL); +} + +/* + * The code that deals with actual SerDes is in serdes_7322_init(). + * Compared to the code for iba7220, it is minimal. + */ +static int serdes_7322_init(struct qib_pportdata *ppd); + +/** + * qib_7322_bringup_serdes - bring up the serdes + * @ppd: physical port on the qlogic_ib device + */ +static int qib_7322_bringup_serdes(struct qib_pportdata *ppd) +{ + struct qib_devdata *dd = ppd->dd; + u64 val, guid, ibc; + unsigned long flags; + int ret = 0; + + /* + * SerDes model not in Pd, but still need to + * set up much of IBCCtrl and IBCDDRCtrl; move elsewhere + * eventually. + */ + /* Put IBC in reset, sends disabled (should be in reset already) */ + ppd->cpspec->ibcctrl_a &= ~SYM_MASK(IBCCtrlA_0, IBLinkEn); + qib_write_kreg_port(ppd, krp_ibcctrl_a, ppd->cpspec->ibcctrl_a); + qib_write_kreg(dd, kr_scratch, 0ULL); + + if (qib_compat_ddr_negotiate) { + ppd->cpspec->ibdeltainprog = 1; + ppd->cpspec->ibsymsnap = read_7322_creg32_port(ppd, + crp_ibsymbolerr); + ppd->cpspec->iblnkerrsnap = read_7322_creg32_port(ppd, + crp_iblinkerrrecov); + } + + /* flowcontrolwatermark is in units of KBytes */ + ibc = 0x5ULL << SYM_LSB(IBCCtrlA_0, FlowCtrlWaterMark); + /* + * Flow control is sent this often, even if no changes in + * buffer space occur. Units are 128ns for this chip. + * Set to 3usec. + */ + ibc |= 24ULL << SYM_LSB(IBCCtrlA_0, FlowCtrlPeriod); + /* max error tolerance */ + ibc |= 0xfULL << SYM_LSB(IBCCtrlA_0, PhyerrThreshold); + /* IB credit flow control. */ + ibc |= 0xfULL << SYM_LSB(IBCCtrlA_0, OverrunThreshold); + /* + * set initial max size pkt IBC will send, including ICRC; it's the + * PIO buffer size in dwords, less 1; also see qib_set_mtu() + */ + ibc |= ((u64)(ppd->ibmaxlen >> 2) + 1) << + SYM_LSB(IBCCtrlA_0, MaxPktLen); + ppd->cpspec->ibcctrl_a = ibc; /* without linkcmd or linkinitcmd! */ + + /* initially come up waiting for TS1, without sending anything. */ + val = ppd->cpspec->ibcctrl_a | (QLOGIC_IB_IBCC_LINKINITCMD_DISABLE << + QLOGIC_IB_IBCC_LINKINITCMD_SHIFT); + + /* + * Reset the PCS interface to the serdes (and also ibc, which is still + * in reset from above). Writes new value of ibcctrl_a as last step. + */ + qib_7322_mini_pcs_reset(ppd); + qib_write_kreg(dd, kr_scratch, 0ULL); + + if (!ppd->cpspec->ibcctrl_b) { + unsigned lse = ppd->link_speed_enabled; + + /* + * Not on re-init after reset, establish shadow + * and force initial config. + */ + ppd->cpspec->ibcctrl_b = qib_read_kreg_port(ppd, + krp_ibcctrl_b); + ppd->cpspec->ibcctrl_b &= ~(IBA7322_IBC_SPEED_QDR | + IBA7322_IBC_SPEED_DDR | + IBA7322_IBC_SPEED_SDR | + IBA7322_IBC_WIDTH_AUTONEG | + SYM_MASK(IBCCtrlB_0, IB_LANE_REV_SUPPORTED)); + if (lse & (lse - 1)) /* Muliple speeds enabled */ + ppd->cpspec->ibcctrl_b |= + (lse << IBA7322_IBC_SPEED_LSB) | + IBA7322_IBC_IBTA_1_2_MASK | + IBA7322_IBC_MAX_SPEED_MASK; + else + ppd->cpspec->ibcctrl_b |= (lse == QIB_IB_QDR) ? + IBA7322_IBC_SPEED_QDR | + IBA7322_IBC_IBTA_1_2_MASK : + (lse == QIB_IB_DDR) ? + IBA7322_IBC_SPEED_DDR : + IBA7322_IBC_SPEED_SDR; + if ((ppd->link_width_enabled & (IB_WIDTH_1X | IB_WIDTH_4X)) == + (IB_WIDTH_1X | IB_WIDTH_4X)) + ppd->cpspec->ibcctrl_b |= IBA7322_IBC_WIDTH_AUTONEG; + else + ppd->cpspec->ibcctrl_b |= + ppd->link_width_enabled == IB_WIDTH_4X ? + IBA7322_IBC_WIDTH_4X_ONLY : + IBA7322_IBC_WIDTH_1X_ONLY; + + /* always enable these on driver reload, not sticky */ + ppd->cpspec->ibcctrl_b |= (IBA7322_IBC_RXPOL_MASK | + IBA7322_IBC_HRTBT_MASK); + } + qib_write_kreg_port(ppd, krp_ibcctrl_b, ppd->cpspec->ibcctrl_b); + + /* setup so we have more time at CFGTEST to change H1 */ + val = qib_read_kreg_port(ppd, krp_ibcctrl_c); + val &= ~SYM_MASK(IBCCtrlC_0, IB_FRONT_PORCH); + val |= 0xfULL << SYM_LSB(IBCCtrlC_0, IB_FRONT_PORCH); + qib_write_kreg_port(ppd, krp_ibcctrl_c, val); + + serdes_7322_init(ppd); + + guid = be64_to_cpu(ppd->guid); + if (!guid) { + if (dd->base_guid) + guid = be64_to_cpu(dd->base_guid) + ppd->port - 1; + ppd->guid = cpu_to_be64(guid); + } + + qib_write_kreg_port(ppd, krp_hrtbt_guid, guid); + /* write to chip to prevent back-to-back writes of ibc reg */ + qib_write_kreg(dd, kr_scratch, 0); + + /* Enable port */ + ppd->cpspec->ibcctrl_a |= SYM_MASK(IBCCtrlA_0, IBLinkEn); + set_vls(ppd); + + /* be paranoid against later code motion, etc. */ + spin_lock_irqsave(&dd->cspec->rcvmod_lock, flags); + ppd->p_rcvctrl |= SYM_MASK(RcvCtrl_0, RcvIBPortEnable); + qib_write_kreg_port(ppd, krp_rcvctrl, ppd->p_rcvctrl); + spin_unlock_irqrestore(&dd->cspec->rcvmod_lock, flags); + + /* Also enable IBSTATUSCHG interrupt. */ + val = qib_read_kreg_port(ppd, krp_errmask); + qib_write_kreg_port(ppd, krp_errmask, + val | ERR_MASK_N(IBStatusChanged)); + + /* Always zero until we start messing with SerDes for real */ + return ret; +} + +/** + * qib_7322_quiet_serdes - set serdes to txidle + * @dd: the qlogic_ib device + * Called when driver is being unloaded + */ +static void qib_7322_mini_quiet_serdes(struct qib_pportdata *ppd) +{ + u64 val; + unsigned long flags; + + qib_set_ib_7322_lstate(ppd, 0, QLOGIC_IB_IBCC_LINKINITCMD_DISABLE); + + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags &= ~QIBL_IB_AUTONEG_INPROG; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + wake_up(&ppd->cpspec->autoneg_wait); + cancel_delayed_work(&ppd->cpspec->autoneg_work); + if (ppd->dd->cspec->r1) + cancel_delayed_work(&ppd->cpspec->ipg_work); + flush_scheduled_work(); + + ppd->cpspec->chase_end = 0; + if (ppd->cpspec->chase_timer.data) /* if initted */ + del_timer_sync(&ppd->cpspec->chase_timer); + + /* + * Despite the name, actually disables IBC as well. Do it when + * we are as sure as possible that no more packets can be + * received, following the down and the PCS reset. + * The actual disabling happens in qib_7322_mini_pci_reset(), + * along with the PCS being reset. + */ + ppd->cpspec->ibcctrl_a &= ~SYM_MASK(IBCCtrlA_0, IBLinkEn); + qib_7322_mini_pcs_reset(ppd); + + /* + * Update the adjusted counters so the adjustment persists + * across driver reload. + */ + if (ppd->cpspec->ibsymdelta || ppd->cpspec->iblnkerrdelta || + ppd->cpspec->ibdeltainprog || ppd->cpspec->iblnkdowndelta) { + struct qib_devdata *dd = ppd->dd; + u64 diagc; + + /* enable counter writes */ + diagc = qib_read_kreg64(dd, kr_hwdiagctrl); + qib_write_kreg(dd, kr_hwdiagctrl, + diagc | SYM_MASK(HwDiagCtrl, CounterWrEnable)); + + if (ppd->cpspec->ibsymdelta || ppd->cpspec->ibdeltainprog) { + val = read_7322_creg32_port(ppd, crp_ibsymbolerr); + if (ppd->cpspec->ibdeltainprog) + val -= val - ppd->cpspec->ibsymsnap; + val -= ppd->cpspec->ibsymdelta; + write_7322_creg_port(ppd, crp_ibsymbolerr, val); + } + if (ppd->cpspec->iblnkerrdelta || ppd->cpspec->ibdeltainprog) { + val = read_7322_creg32_port(ppd, crp_iblinkerrrecov); + if (ppd->cpspec->ibdeltainprog) + val -= val - ppd->cpspec->iblnkerrsnap; + val -= ppd->cpspec->iblnkerrdelta; + write_7322_creg_port(ppd, crp_iblinkerrrecov, val); + } + if (ppd->cpspec->iblnkdowndelta) { + val = read_7322_creg32_port(ppd, crp_iblinkdown); + val += ppd->cpspec->iblnkdowndelta; + write_7322_creg_port(ppd, crp_iblinkdown, val); + } + /* + * No need to save ibmalfdelta since IB perfcounters + * are cleared on driver reload. + */ + + /* and disable counter writes */ + qib_write_kreg(dd, kr_hwdiagctrl, diagc); + } +} + +/** + * qib_setup_7322_setextled - set the state of the two external LEDs + * @ppd: physical port on the qlogic_ib device + * @on: whether the link is up or not + * + * The exact combo of LEDs if on is true is determined by looking + * at the ibcstatus. + * + * These LEDs indicate the physical and logical state of IB link. + * For this chip (at least with recommended board pinouts), LED1 + * is Yellow (logical state) and LED2 is Green (physical state), + * + * Note: We try to match the Mellanox HCA LED behavior as best + * we can. Green indicates physical link state is OK (something is + * plugged in, and we can train). + * Amber indicates the link is logically up (ACTIVE). + * Mellanox further blinks the amber LED to indicate data packet + * activity, but we have no hardware support for that, so it would + * require waking up every 10-20 msecs and checking the counters + * on the chip, and then turning the LED off if appropriate. That's + * visible overhead, so not something we will do. + */ +static void qib_setup_7322_setextled(struct qib_pportdata *ppd, u32 on) +{ + struct qib_devdata *dd = ppd->dd; + u64 extctl, ledblink = 0, val; + unsigned long flags; + int yel, grn; + + /* + * The diags use the LED to indicate diag info, so we leave + * the external LED alone when the diags are running. + */ + if (dd->diag_client) + return; + + /* Allow override of LED display for, e.g. Locating system in rack */ + if (ppd->led_override) { + grn = (ppd->led_override & QIB_LED_PHYS); + yel = (ppd->led_override & QIB_LED_LOG); + } else if (on) { + val = qib_read_kreg_port(ppd, krp_ibcstatus_a); + grn = qib_7322_phys_portstate(val) == + IB_PHYSPORTSTATE_LINKUP; + yel = qib_7322_iblink_state(val) == IB_PORT_ACTIVE; + } else { + grn = 0; + yel = 0; + } + + spin_lock_irqsave(&dd->cspec->gpio_lock, flags); + extctl = dd->cspec->extctrl & (ppd->port == 1 ? + ~ExtLED_IB1_MASK : ~ExtLED_IB2_MASK); + if (grn) { + extctl |= ppd->port == 1 ? ExtLED_IB1_GRN : ExtLED_IB2_GRN; + /* + * Counts are in chip clock (4ns) periods. + * This is 1/16 sec (66.6ms) on, + * 3/16 sec (187.5 ms) off, with packets rcvd. + */ + ledblink = ((66600 * 1000UL / 4) << IBA7322_LEDBLINK_ON_SHIFT) | + ((187500 * 1000UL / 4) << IBA7322_LEDBLINK_OFF_SHIFT); + } + if (yel) + extctl |= ppd->port == 1 ? ExtLED_IB1_YEL : ExtLED_IB2_YEL; + dd->cspec->extctrl = extctl; + qib_write_kreg(dd, kr_extctrl, dd->cspec->extctrl); + spin_unlock_irqrestore(&dd->cspec->gpio_lock, flags); + + if (ledblink) /* blink the LED on packet receive */ + qib_write_kreg_port(ppd, krp_rcvpktledcnt, ledblink); +} + +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) +static void qib_update_rhdrq_dca(struct qib_ctxtdata *rcd) +{ + struct qib_devdata *dd = rcd->dd; + struct qib_chip_specific *cspec = dd->cspec; + int cpu = get_cpu(); + + if (cspec->rhdr_cpu[rcd->ctxt] != cpu) { + const struct dca_reg_map *rmp; + + cspec->rhdr_cpu[rcd->ctxt] = cpu; + rmp = &dca_rcvhdr_reg_map[rcd->ctxt]; + cspec->dca_rcvhdr_ctrl[rmp->shadow_inx] &= rmp->mask; + cspec->dca_rcvhdr_ctrl[rmp->shadow_inx] |= + (u64) dca3_get_tag(&dd->pcidev->dev, cpu) << rmp->lsb; + qib_write_kreg(dd, rmp->regno, + cspec->dca_rcvhdr_ctrl[rmp->shadow_inx]); + cspec->dca_ctrl |= SYM_MASK(DCACtrlA, RcvHdrqDCAEnable); + qib_write_kreg(dd, KREG_IDX(DCACtrlA), cspec->dca_ctrl); + } + put_cpu(); +} + +static void qib_update_sdma_dca(struct qib_pportdata *ppd) +{ + struct qib_devdata *dd = ppd->dd; + struct qib_chip_specific *cspec = dd->cspec; + int cpu = get_cpu(); + unsigned pidx = ppd->port - 1; + + if (cspec->sdma_cpu[pidx] != cpu) { + cspec->sdma_cpu[pidx] = cpu; + cspec->dca_rcvhdr_ctrl[4] &= ~(ppd->hw_pidx ? + SYM_MASK(DCACtrlF, SendDma1DCAOPH) : + SYM_MASK(DCACtrlF, SendDma0DCAOPH)); + cspec->dca_rcvhdr_ctrl[4] |= + (u64) dca3_get_tag(&dd->pcidev->dev, cpu) << + (ppd->hw_pidx ? + SYM_LSB(DCACtrlF, SendDma1DCAOPH) : + SYM_LSB(DCACtrlF, SendDma0DCAOPH)); + qib_write_kreg(dd, KREG_IDX(DCACtrlF), + cspec->dca_rcvhdr_ctrl[4]); + cspec->dca_ctrl |= ppd->hw_pidx ? + SYM_MASK(DCACtrlA, SendDMAHead1DCAEnable) : + SYM_MASK(DCACtrlA, SendDMAHead0DCAEnable); + qib_write_kreg(dd, KREG_IDX(DCACtrlA), cspec->dca_ctrl); + } + put_cpu(); +} + +static void qib_setup_dca(struct qib_devdata *dd) +{ + struct qib_chip_specific *cspec = dd->cspec; + int i; + + for (i = 0; i < ARRAY_SIZE(cspec->rhdr_cpu); i++) + cspec->rhdr_cpu[i] = -1; + for (i = 0; i < ARRAY_SIZE(cspec->sdma_cpu); i++) + cspec->sdma_cpu[i] = -1; + cspec->dca_rcvhdr_ctrl[0] = + (1ULL << SYM_LSB(DCACtrlB, RcvHdrq0DCAXfrCnt)) | + (1ULL << SYM_LSB(DCACtrlB, RcvHdrq1DCAXfrCnt)) | + (1ULL << SYM_LSB(DCACtrlB, RcvHdrq2DCAXfrCnt)) | + (1ULL << SYM_LSB(DCACtrlB, RcvHdrq3DCAXfrCnt)); + cspec->dca_rcvhdr_ctrl[1] = + (1ULL << SYM_LSB(DCACtrlC, RcvHdrq4DCAXfrCnt)) | + (1ULL << SYM_LSB(DCACtrlC, RcvHdrq5DCAXfrCnt)) | + (1ULL << SYM_LSB(DCACtrlC, RcvHdrq6DCAXfrCnt)) | + (1ULL << SYM_LSB(DCACtrlC, RcvHdrq7DCAXfrCnt)); + cspec->dca_rcvhdr_ctrl[2] = + (1ULL << SYM_LSB(DCACtrlD, RcvHdrq8DCAXfrCnt)) | + (1ULL << SYM_LSB(DCACtrlD, RcvHdrq9DCAXfrCnt)) | + (1ULL << SYM_LSB(DCACtrlD, RcvHdrq10DCAXfrCnt)) | + (1ULL << SYM_LSB(DCACtrlD, RcvHdrq11DCAXfrCnt)); + cspec->dca_rcvhdr_ctrl[3] = + (1ULL << SYM_LSB(DCACtrlE, RcvHdrq12DCAXfrCnt)) | + (1ULL << SYM_LSB(DCACtrlE, RcvHdrq13DCAXfrCnt)) | + (1ULL << SYM_LSB(DCACtrlE, RcvHdrq14DCAXfrCnt)) | + (1ULL << SYM_LSB(DCACtrlE, RcvHdrq15DCAXfrCnt)); + cspec->dca_rcvhdr_ctrl[4] = + (1ULL << SYM_LSB(DCACtrlF, RcvHdrq16DCAXfrCnt)) | + (1ULL << SYM_LSB(DCACtrlF, RcvHdrq17DCAXfrCnt)); + for (i = 0; i < ARRAY_SIZE(cspec->sdma_cpu); i++) + qib_write_kreg(dd, KREG_IDX(DCACtrlB) + i, + cspec->dca_rcvhdr_ctrl[i]); +} + +#endif + +/* + * Disable MSIx interrupt if enabled, call generic MSIx code + * to cleanup, and clear pending MSIx interrupts. + * Used for fallback to INTx, after reset, and when MSIx setup fails. + */ +static void qib_7322_nomsix(struct qib_devdata *dd) +{ + u64 intgranted; + int n; + + dd->cspec->main_int_mask = ~0ULL; + n = dd->cspec->num_msix_entries; + if (n) { + int i; + + dd->cspec->num_msix_entries = 0; + for (i = 0; i < n; i++) + free_irq(dd->cspec->msix_entries[i].vector, + dd->cspec->msix_arg[i]); + qib_nomsix(dd); + } + /* make sure no MSIx interrupts are left pending */ + intgranted = qib_read_kreg64(dd, kr_intgranted); + if (intgranted) + qib_write_kreg(dd, kr_intgranted, intgranted); +} + +static void qib_7322_free_irq(struct qib_devdata *dd) +{ + if (dd->cspec->irq) { + free_irq(dd->cspec->irq, dd); + dd->cspec->irq = 0; + } + qib_7322_nomsix(dd); +} + +static void qib_setup_7322_cleanup(struct qib_devdata *dd) +{ + int i; + +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) + if (dd->flags & QIB_DCA_ENABLED) { + dca_remove_requester(&dd->pcidev->dev); + dd->flags &= ~QIB_DCA_ENABLED; + dd->cspec->dca_ctrl = 0; + qib_write_kreg(dd, KREG_IDX(DCACtrlA), dd->cspec->dca_ctrl); + } +#endif + + qib_7322_free_irq(dd); + kfree(dd->cspec->cntrs); + kfree(dd->cspec->sendchkenable); + kfree(dd->cspec->sendgrhchk); + kfree(dd->cspec->sendibchk); + kfree(dd->cspec->msix_entries); + kfree(dd->cspec->msix_arg); + for (i = 0; i < dd->num_pports; i++) { + unsigned long flags; + u32 mask = QSFP_GPIO_MOD_PRS_N | + (QSFP_GPIO_MOD_PRS_N << QSFP_GPIO_PORT2_SHIFT); + + kfree(dd->pport[i].cpspec->portcntrs); + if (dd->flags & QIB_HAS_QSFP) { + spin_lock_irqsave(&dd->cspec->gpio_lock, flags); + dd->cspec->gpio_mask &= ~mask; + qib_write_kreg(dd, kr_gpio_mask, dd->cspec->gpio_mask); + spin_unlock_irqrestore(&dd->cspec->gpio_lock, flags); + qib_qsfp_deinit(&dd->pport[i].cpspec->qsfp_data); + } + if (dd->pport[i].ibport_data.smi_ah) + ib_destroy_ah(&dd->pport[i].ibport_data.smi_ah->ibah); + } +} + +/* handle SDMA interrupts */ +static void sdma_7322_intr(struct qib_devdata *dd, u64 istat) +{ + struct qib_pportdata *ppd0 = &dd->pport[0]; + struct qib_pportdata *ppd1 = &dd->pport[1]; + u64 intr0 = istat & (INT_MASK_P(SDma, 0) | + INT_MASK_P(SDmaIdle, 0) | INT_MASK_P(SDmaProgress, 0)); + u64 intr1 = istat & (INT_MASK_P(SDma, 1) | + INT_MASK_P(SDmaIdle, 1) | INT_MASK_P(SDmaProgress, 1)); + + if (intr0) + qib_sdma_intr(ppd0); + if (intr1) + qib_sdma_intr(ppd1); + + if (istat & INT_MASK_PM(SDmaCleanupDone, 0)) + qib_sdma_process_event(ppd0, qib_sdma_event_e20_hw_started); + if (istat & INT_MASK_PM(SDmaCleanupDone, 1)) + qib_sdma_process_event(ppd1, qib_sdma_event_e20_hw_started); +} + +/* + * Set or clear the Send buffer available interrupt enable bit. + */ +static void qib_wantpiobuf_7322_intr(struct qib_devdata *dd, u32 needint) +{ + unsigned long flags; + + spin_lock_irqsave(&dd->sendctrl_lock, flags); + if (needint) + dd->sendctrl |= SYM_MASK(SendCtrl, SendIntBufAvail); + else + dd->sendctrl &= ~SYM_MASK(SendCtrl, SendIntBufAvail); + qib_write_kreg(dd, kr_sendctrl, dd->sendctrl); + qib_write_kreg(dd, kr_scratch, 0ULL); + spin_unlock_irqrestore(&dd->sendctrl_lock, flags); +} + +/* + * Somehow got an interrupt with reserved bits set in interrupt status. + * Print a message so we know it happened, then clear them. + * keep mainline interrupt handler cache-friendly + */ +static noinline void unknown_7322_ibits(struct qib_devdata *dd, u64 istat) +{ + u64 kills; + char msg[128]; + + kills = istat & ~QIB_I_BITSEXTANT; + qib_dev_err(dd, "Clearing reserved interrupt(s) 0x%016llx:" + " %s\n", (unsigned long long) kills, msg); + qib_write_kreg(dd, kr_intmask, (dd->cspec->int_enable_mask & ~kills)); +} + +/* keep mainline interrupt handler cache-friendly */ +static noinline void unknown_7322_gpio_intr(struct qib_devdata *dd) +{ + u32 gpiostatus; + int handled = 0; + int pidx; + + /* + * Boards for this chip currently don't use GPIO interrupts, + * so clear by writing GPIOstatus to GPIOclear, and complain + * to developer. To avoid endless repeats, clear + * the bits in the mask, since there is some kind of + * programming error or chip problem. + */ + gpiostatus = qib_read_kreg32(dd, kr_gpio_status); + /* + * In theory, writing GPIOstatus to GPIOclear could + * have a bad side-effect on some diagnostic that wanted + * to poll for a status-change, but the various shadows + * make that problematic at best. Diags will just suppress + * all GPIO interrupts during such tests. + */ + qib_write_kreg(dd, kr_gpio_clear, gpiostatus); + /* + * Check for QSFP MOD_PRS changes + * only works for single port if IB1 != pidx1 + */ + for (pidx = 0; pidx < dd->num_pports && (dd->flags & QIB_HAS_QSFP); + ++pidx) { + struct qib_pportdata *ppd; + struct qib_qsfp_data *qd; + u32 mask; + if (!dd->pport[pidx].link_speed_supported) + continue; + mask = QSFP_GPIO_MOD_PRS_N; + ppd = dd->pport + pidx; + mask <<= (QSFP_GPIO_PORT2_SHIFT * ppd->hw_pidx); + if (gpiostatus & dd->cspec->gpio_mask & mask) { + u64 pins; + qd = &ppd->cpspec->qsfp_data; + gpiostatus &= ~mask; + pins = qib_read_kreg64(dd, kr_extstatus); + pins >>= SYM_LSB(EXTStatus, GPIOIn); + if (!(pins & mask)) { + ++handled; + qd->t_insert = get_jiffies_64(); + schedule_work(&qd->work); + } + } + } + + if (gpiostatus && !handled) { + const u32 mask = qib_read_kreg32(dd, kr_gpio_mask); + u32 gpio_irq = mask & gpiostatus; + + /* + * Clear any troublemakers, and update chip from shadow + */ + dd->cspec->gpio_mask &= ~gpio_irq; + qib_write_kreg(dd, kr_gpio_mask, dd->cspec->gpio_mask); + } +} + +/* + * Handle errors and unusual events first, separate function + * to improve cache hits for fast path interrupt handling. + */ +static noinline void unlikely_7322_intr(struct qib_devdata *dd, u64 istat) +{ + if (istat & ~QIB_I_BITSEXTANT) + unknown_7322_ibits(dd, istat); + if (istat & QIB_I_GPIO) + unknown_7322_gpio_intr(dd); + if (istat & QIB_I_C_ERROR) + handle_7322_errors(dd); + if (istat & INT_MASK_P(Err, 0) && dd->rcd[0]) + handle_7322_p_errors(dd->rcd[0]->ppd); + if (istat & INT_MASK_P(Err, 1) && dd->rcd[1]) + handle_7322_p_errors(dd->rcd[1]->ppd); +} + +/* + * Dynamically adjust the rcv int timeout for a context based on incoming + * packet rate. + */ +static void adjust_rcv_timeout(struct qib_ctxtdata *rcd, int npkts) +{ + struct qib_devdata *dd = rcd->dd; + u32 timeout = dd->cspec->rcvavail_timeout[rcd->ctxt]; + + /* + * Dynamically adjust idle timeout on chip + * based on number of packets processed. + */ + if (npkts < rcv_int_count && timeout > 2) + timeout >>= 1; + else if (npkts >= rcv_int_count && timeout < rcv_int_timeout) + timeout = min(timeout << 1, rcv_int_timeout); + else + return; + + dd->cspec->rcvavail_timeout[rcd->ctxt] = timeout; + qib_write_kreg(dd, kr_rcvavailtimeout + rcd->ctxt, timeout); +} + +/* + * This is the main interrupt handler. + * It will normally only be used for low frequency interrupts but may + * have to handle all interrupts if INTx is enabled or fewer than normal + * MSIx interrupts were allocated. + * This routine should ignore the interrupt bits for any of the + * dedicated MSIx handlers. + */ +static irqreturn_t qib_7322intr(int irq, void *data) +{ + struct qib_devdata *dd = data; + irqreturn_t ret; + u64 istat; + u64 ctxtrbits; + u64 rmask; + unsigned i; + u32 npkts; + + if ((dd->flags & (QIB_PRESENT | QIB_BADINTR)) != QIB_PRESENT) { + /* + * This return value is not great, but we do not want the + * interrupt core code to remove our interrupt handler + * because we don't appear to be handling an interrupt + * during a chip reset. + */ + ret = IRQ_HANDLED; + goto bail; + } + + istat = qib_read_kreg64(dd, kr_intstatus); + + if (unlikely(istat == ~0ULL)) { + qib_bad_intrstatus(dd); + qib_dev_err(dd, "Interrupt status all f's, skipping\n"); + /* don't know if it was our interrupt or not */ + ret = IRQ_NONE; + goto bail; + } + + istat &= dd->cspec->main_int_mask; + if (unlikely(!istat)) { + /* already handled, or shared and not us */ + ret = IRQ_NONE; + goto bail; + } + + qib_stats.sps_ints++; + if (dd->int_counter != (u32) -1) + dd->int_counter++; + + /* handle "errors" of various kinds first, device ahead of port */ + if (unlikely(istat & (~QIB_I_BITSEXTANT | QIB_I_GPIO | + QIB_I_C_ERROR | INT_MASK_P(Err, 0) | + INT_MASK_P(Err, 1)))) + unlikely_7322_intr(dd, istat); + + /* + * Clear the interrupt bits we found set, relatively early, so we + * "know" know the chip will have seen this by the time we process + * the queue, and will re-interrupt if necessary. The processor + * itself won't take the interrupt again until we return. + */ + qib_write_kreg(dd, kr_intclear, istat); + + /* + * Handle kernel receive queues before checking for pio buffers + * available since receives can overflow; piobuf waiters can afford + * a few extra cycles, since they were waiting anyway. + */ + ctxtrbits = istat & (QIB_I_RCVAVAIL_MASK | QIB_I_RCVURG_MASK); + if (ctxtrbits) { + rmask = (1ULL << QIB_I_RCVAVAIL_LSB) | + (1ULL << QIB_I_RCVURG_LSB); + for (i = 0; i < dd->first_user_ctxt; i++) { + if (ctxtrbits & rmask) { + ctxtrbits &= ~rmask; + if (dd->rcd[i]) { + qib_kreceive(dd->rcd[i], NULL, &npkts); + adjust_rcv_timeout(dd->rcd[i], npkts); + } + } + rmask <<= 1; + } + if (ctxtrbits) { + ctxtrbits = (ctxtrbits >> QIB_I_RCVAVAIL_LSB) | + (ctxtrbits >> QIB_I_RCVURG_LSB); + qib_handle_urcv(dd, ctxtrbits); + } + } + + if (istat & (QIB_I_P_SDMAINT(0) | QIB_I_P_SDMAINT(1))) + sdma_7322_intr(dd, istat); + + if ((istat & QIB_I_SPIOBUFAVAIL) && (dd->flags & QIB_INITTED)) + qib_ib_piobufavail(dd); + + ret = IRQ_HANDLED; +bail: + return ret; +} + +/* + * Dedicated receive packet available interrupt handler. + */ +static irqreturn_t qib_7322pintr(int irq, void *data) +{ + struct qib_ctxtdata *rcd = data; + struct qib_devdata *dd = rcd->dd; + u32 npkts; + + if ((dd->flags & (QIB_PRESENT | QIB_BADINTR)) != QIB_PRESENT) + /* + * This return value is not great, but we do not want the + * interrupt core code to remove our interrupt handler + * because we don't appear to be handling an interrupt + * during a chip reset. + */ + return IRQ_HANDLED; + + qib_stats.sps_ints++; + if (dd->int_counter != (u32) -1) + dd->int_counter++; + +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) + if (dd->flags & QIB_DCA_ENABLED) + qib_update_rhdrq_dca(rcd); +#endif + + /* Clear the interrupt bit we expect to be set. */ + qib_write_kreg(dd, kr_intclear, ((1ULL << QIB_I_RCVAVAIL_LSB) | + (1ULL << QIB_I_RCVURG_LSB)) << rcd->ctxt); + + qib_kreceive(rcd, NULL, &npkts); + adjust_rcv_timeout(rcd, npkts); + + return IRQ_HANDLED; +} + +/* + * Dedicated Send buffer available interrupt handler. + */ +static irqreturn_t qib_7322bufavail(int irq, void *data) +{ + struct qib_devdata *dd = data; + + if ((dd->flags & (QIB_PRESENT | QIB_BADINTR)) != QIB_PRESENT) + /* + * This return value is not great, but we do not want the + * interrupt core code to remove our interrupt handler + * because we don't appear to be handling an interrupt + * during a chip reset. + */ + return IRQ_HANDLED; + + qib_stats.sps_ints++; + if (dd->int_counter != (u32) -1) + dd->int_counter++; + + /* Clear the interrupt bit we expect to be set. */ + qib_write_kreg(dd, kr_intclear, QIB_I_SPIOBUFAVAIL); + + /* qib_ib_piobufavail() will clear the want PIO interrupt if needed */ + if (dd->flags & QIB_INITTED) + qib_ib_piobufavail(dd); + else + qib_wantpiobuf_7322_intr(dd, 0); + + return IRQ_HANDLED; +} + +/* + * Dedicated Send DMA interrupt handler. + */ +static irqreturn_t sdma_intr(int irq, void *data) +{ + struct qib_pportdata *ppd = data; + struct qib_devdata *dd = ppd->dd; + + if ((dd->flags & (QIB_PRESENT | QIB_BADINTR)) != QIB_PRESENT) + /* + * This return value is not great, but we do not want the + * interrupt core code to remove our interrupt handler + * because we don't appear to be handling an interrupt + * during a chip reset. + */ + return IRQ_HANDLED; + + qib_stats.sps_ints++; + if (dd->int_counter != (u32) -1) + dd->int_counter++; + +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) + if (dd->flags & QIB_DCA_ENABLED) + qib_update_sdma_dca(ppd); +#endif + + /* Clear the interrupt bit we expect to be set. */ + qib_write_kreg(dd, kr_intclear, ppd->hw_pidx ? + INT_MASK_P(SDma, 1) : INT_MASK_P(SDma, 0)); + qib_sdma_intr(ppd); + + return IRQ_HANDLED; +} + +/* + * Dedicated Send DMA idle interrupt handler. + */ +static irqreturn_t sdma_idle_intr(int irq, void *data) +{ + struct qib_pportdata *ppd = data; + struct qib_devdata *dd = ppd->dd; + + if ((dd->flags & (QIB_PRESENT | QIB_BADINTR)) != QIB_PRESENT) + /* + * This return value is not great, but we do not want the + * interrupt core code to remove our interrupt handler + * because we don't appear to be handling an interrupt + * during a chip reset. + */ + return IRQ_HANDLED; + + qib_stats.sps_ints++; + if (dd->int_counter != (u32) -1) + dd->int_counter++; + +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) + if (dd->flags & QIB_DCA_ENABLED) + qib_update_sdma_dca(ppd); +#endif + + /* Clear the interrupt bit we expect to be set. */ + qib_write_kreg(dd, kr_intclear, ppd->hw_pidx ? + INT_MASK_P(SDmaIdle, 1) : INT_MASK_P(SDmaIdle, 0)); + qib_sdma_intr(ppd); + + return IRQ_HANDLED; +} + +/* + * Dedicated Send DMA progress interrupt handler. + */ +static irqreturn_t sdma_progress_intr(int irq, void *data) +{ + struct qib_pportdata *ppd = data; + struct qib_devdata *dd = ppd->dd; + + if ((dd->flags & (QIB_PRESENT | QIB_BADINTR)) != QIB_PRESENT) + /* + * This return value is not great, but we do not want the + * interrupt core code to remove our interrupt handler + * because we don't appear to be handling an interrupt + * during a chip reset. + */ + return IRQ_HANDLED; + + qib_stats.sps_ints++; + if (dd->int_counter != (u32) -1) + dd->int_counter++; + +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) + if (dd->flags & QIB_DCA_ENABLED) + qib_update_sdma_dca(ppd); +#endif + + /* Clear the interrupt bit we expect to be set. */ + qib_write_kreg(dd, kr_intclear, ppd->hw_pidx ? + INT_MASK_P(SDmaProgress, 1) : + INT_MASK_P(SDmaProgress, 0)); + qib_sdma_intr(ppd); + + return IRQ_HANDLED; +} + +/* + * Dedicated Send DMA cleanup interrupt handler. + */ +static irqreturn_t sdma_cleanup_intr(int irq, void *data) +{ + struct qib_pportdata *ppd = data; + struct qib_devdata *dd = ppd->dd; + + if ((dd->flags & (QIB_PRESENT | QIB_BADINTR)) != QIB_PRESENT) + /* + * This return value is not great, but we do not want the + * interrupt core code to remove our interrupt handler + * because we don't appear to be handling an interrupt + * during a chip reset. + */ + return IRQ_HANDLED; + + qib_stats.sps_ints++; + if (dd->int_counter != (u32) -1) + dd->int_counter++; + +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) + if (dd->flags & QIB_DCA_ENABLED) + qib_update_sdma_dca(ppd); +#endif + + /* Clear the interrupt bit we expect to be set. */ + qib_write_kreg(dd, kr_intclear, ppd->hw_pidx ? + INT_MASK_PM(SDmaCleanupDone, 1) : + INT_MASK_PM(SDmaCleanupDone, 0)); + qib_sdma_process_event(ppd, qib_sdma_event_e20_hw_started); + + return IRQ_HANDLED; +} + +/* + * Set up our chip-specific interrupt handler. + * The interrupt type has already been setup, so + * we just need to do the registration and error checking. + * If we are using MSIx interrupts, we may fall back to + * INTx later, if the interrupt handler doesn't get called + * within 1/2 second (see verify_interrupt()). + */ +static void qib_setup_7322_interrupt(struct qib_devdata *dd, int clearpend) +{ + int ret, i, msixnum; + u64 redirect[6]; + u64 mask; + + if (!dd->num_pports) + return; + + if (clearpend) { + /* + * if not switching interrupt types, be sure interrupts are + * disabled, and then clear anything pending at this point, + * because we are starting clean. + */ + qib_7322_set_intr_state(dd, 0); + + /* clear the reset error, init error/hwerror mask */ + qib_7322_init_hwerrors(dd); + + /* clear any interrupt bits that might be set */ + qib_write_kreg(dd, kr_intclear, ~0ULL); + + /* make sure no pending MSIx intr, and clear diag reg */ + qib_write_kreg(dd, kr_intgranted, ~0ULL); + qib_write_kreg(dd, kr_vecclr_wo_int, ~0ULL); + } + + if (!dd->cspec->num_msix_entries) { + /* Try to get INTx interrupt */ +try_intx: + if (!dd->pcidev->irq) { + qib_dev_err(dd, "irq is 0, BIOS error? " + "Interrupts won't work\n"); + goto bail; + } + ret = request_irq(dd->pcidev->irq, qib_7322intr, + IRQF_SHARED, QIB_DRV_NAME, dd); + if (ret) { + qib_dev_err(dd, "Couldn't setup INTx " + "interrupt (irq=%d): %d\n", + dd->pcidev->irq, ret); + goto bail; + } + dd->cspec->irq = dd->pcidev->irq; + dd->cspec->main_int_mask = ~0ULL; + goto bail; + } + + /* Try to get MSIx interrupts */ + memset(redirect, 0, sizeof redirect); + mask = ~0ULL; + msixnum = 0; + for (i = 0; msixnum < dd->cspec->num_msix_entries; i++) { + irq_handler_t handler; + const char *name; + void *arg; + u64 val; + int lsb, reg, sh; + + if (i < ARRAY_SIZE(irq_table)) { + if (irq_table[i].port) { + /* skip if for a non-configured port */ + if (irq_table[i].port > dd->num_pports) + continue; + arg = dd->pport + irq_table[i].port - 1; + } else + arg = dd; + lsb = irq_table[i].lsb; + handler = irq_table[i].handler; + name = irq_table[i].name; + } else { + unsigned ctxt; + + ctxt = i - ARRAY_SIZE(irq_table); + /* per krcvq context receive interrupt */ + arg = dd->rcd[ctxt]; + if (!arg) + continue; + lsb = QIB_I_RCVAVAIL_LSB + ctxt; + handler = qib_7322pintr; + name = QIB_DRV_NAME " (kctx)"; + } + ret = request_irq(dd->cspec->msix_entries[msixnum].vector, + handler, 0, name, arg); + if (ret) { + /* + * Shouldn't happen since the enable said we could + * have as many as we are trying to setup here. + */ + qib_dev_err(dd, "Couldn't setup MSIx " + "interrupt (vec=%d, irq=%d): %d\n", msixnum, + dd->cspec->msix_entries[msixnum].vector, + ret); + qib_7322_nomsix(dd); + goto try_intx; + } + dd->cspec->msix_arg[msixnum] = arg; + if (lsb >= 0) { + reg = lsb / IBA7322_REDIRECT_VEC_PER_REG; + sh = (lsb % IBA7322_REDIRECT_VEC_PER_REG) * + SYM_LSB(IntRedirect0, vec1); + mask &= ~(1ULL << lsb); + redirect[reg] |= ((u64) msixnum) << sh; + } + val = qib_read_kreg64(dd, 2 * msixnum + 1 + + (QIB_7322_MsixTable_OFFS / sizeof(u64))); + msixnum++; + } + /* Initialize the vector mapping */ + for (i = 0; i < ARRAY_SIZE(redirect); i++) + qib_write_kreg(dd, kr_intredirect + i, redirect[i]); + dd->cspec->main_int_mask = mask; +bail:; +} + +/** + * qib_7322_boardname - fill in the board name and note features + * @dd: the qlogic_ib device + * + * info will be based on the board revision register + */ +static unsigned qib_7322_boardname(struct qib_devdata *dd) +{ + /* Will need enumeration of board-types here */ + char *n; + u32 boardid, namelen; + unsigned features = DUAL_PORT_CAP; + + boardid = SYM_FIELD(dd->revision, Revision, BoardID); + + switch (boardid) { + case 0: + n = "InfiniPath_QLE7342_Emulation"; + break; + case 1: + n = "InfiniPath_QLE7340"; + dd->flags |= QIB_HAS_QSFP; + features = PORT_SPD_CAP; + break; + case 2: + n = "InfiniPath_QLE7342"; + dd->flags |= QIB_HAS_QSFP; + break; + case 3: + n = "InfiniPath_QMI7342"; + break; + case 4: + n = "InfiniPath_Unsupported7342"; + qib_dev_err(dd, "Unsupported version of QMH7342\n"); + features = 0; + break; + case BOARD_QMH7342: + n = "InfiniPath_QMH7342"; + features = 0x24; + break; + case BOARD_QME7342: + n = "InfiniPath_QME7342"; + break; + case 15: + n = "InfiniPath_QLE7342_TEST"; + dd->flags |= QIB_HAS_QSFP; + break; + default: + n = "InfiniPath_QLE73xy_UNKNOWN"; + qib_dev_err(dd, "Unknown 7322 board type %u\n", boardid); + break; + } + dd->board_atten = 1; /* index into txdds_Xdr */ + + namelen = strlen(n) + 1; + dd->boardname = kmalloc(namelen, GFP_KERNEL); + if (!dd->boardname) + qib_dev_err(dd, "Failed allocation for board name: %s\n", n); + else + snprintf(dd->boardname, namelen, "%s", n); + + snprintf(dd->boardversion, sizeof(dd->boardversion), + "ChipABI %u.%u, %s, InfiniPath%u %u.%u, SW Compat %u\n", + QIB_CHIP_VERS_MAJ, QIB_CHIP_VERS_MIN, dd->boardname, + (unsigned)SYM_FIELD(dd->revision, Revision_R, Arch), + dd->majrev, dd->minrev, + (unsigned)SYM_FIELD(dd->revision, Revision_R, SW)); + + if (qib_singleport && (features >> PORT_SPD_CAP_SHIFT) & PORT_SPD_CAP) { + qib_devinfo(dd->pcidev, "IB%u: Forced to single port mode" + " by module parameter\n", dd->unit); + features &= PORT_SPD_CAP; + } + + return features; +} + +/* + * This routine sleeps, so it can only be called from user context, not + * from interrupt context. + */ +static int qib_do_7322_reset(struct qib_devdata *dd) +{ + u64 val; + u64 *msix_vecsave; + int i, msix_entries, ret = 1; + u16 cmdval; + u8 int_line, clinesz; + unsigned long flags; + + /* Use dev_err so it shows up in logs, etc. */ + qib_dev_err(dd, "Resetting InfiniPath unit %u\n", dd->unit); + + qib_pcie_getcmd(dd, &cmdval, &int_line, &clinesz); + + msix_entries = dd->cspec->num_msix_entries; + + /* no interrupts till re-initted */ + qib_7322_set_intr_state(dd, 0); + + if (msix_entries) { + qib_7322_nomsix(dd); + /* can be up to 512 bytes, too big for stack */ + msix_vecsave = kmalloc(2 * dd->cspec->num_msix_entries * + sizeof(u64), GFP_KERNEL); + if (!msix_vecsave) + qib_dev_err(dd, "No mem to save MSIx data\n"); + } else + msix_vecsave = NULL; + + /* + * Core PCI (as of 2.6.18) doesn't save or rewrite the full vector + * info that is set up by the BIOS, so we have to save and restore + * it ourselves. There is some risk something could change it, + * after we save it, but since we have disabled the MSIx, it + * shouldn't be touched... + */ + for (i = 0; i < msix_entries; i++) { + u64 vecaddr, vecdata; + vecaddr = qib_read_kreg64(dd, 2 * i + + (QIB_7322_MsixTable_OFFS / sizeof(u64))); + vecdata = qib_read_kreg64(dd, 1 + 2 * i + + (QIB_7322_MsixTable_OFFS / sizeof(u64))); + if (msix_vecsave) { + msix_vecsave[2 * i] = vecaddr; + /* save it without the masked bit set */ + msix_vecsave[1 + 2 * i] = vecdata & ~0x100000000ULL; + } + } + + dd->pport->cpspec->ibdeltainprog = 0; + dd->pport->cpspec->ibsymdelta = 0; + dd->pport->cpspec->iblnkerrdelta = 0; + dd->pport->cpspec->ibmalfdelta = 0; + dd->int_counter = 0; /* so we check interrupts work again */ + + /* + * Keep chip from being accessed until we are ready. Use + * writeq() directly, to allow the write even though QIB_PRESENT + * isnt' set. + */ + dd->flags &= ~(QIB_INITTED | QIB_PRESENT | QIB_BADINTR); + dd->flags |= QIB_DOING_RESET; + val = dd->control | QLOGIC_IB_C_RESET; + writeq(val, &dd->kregbase[kr_control]); + + for (i = 1; i <= 5; i++) { + /* + * Allow MBIST, etc. to complete; longer on each retry. + * We sometimes get machine checks from bus timeout if no + * response, so for now, make it *really* long. + */ + msleep(1000 + (1 + i) * 3000); + + qib_pcie_reenable(dd, cmdval, int_line, clinesz); + + /* + * Use readq directly, so we don't need to mark it as PRESENT + * until we get a successful indication that all is well. + */ + val = readq(&dd->kregbase[kr_revision]); + if (val == dd->revision) + break; + if (i == 5) { + qib_dev_err(dd, "Failed to initialize after reset, " + "unusable\n"); + ret = 0; + goto bail; + } + } + + dd->flags |= QIB_PRESENT; /* it's back */ + + if (msix_entries) { + /* restore the MSIx vector address and data if saved above */ + for (i = 0; i < msix_entries; i++) { + dd->cspec->msix_entries[i].entry = i; + if (!msix_vecsave || !msix_vecsave[2 * i]) + continue; + qib_write_kreg(dd, 2 * i + + (QIB_7322_MsixTable_OFFS / sizeof(u64)), + msix_vecsave[2 * i]); + qib_write_kreg(dd, 1 + 2 * i + + (QIB_7322_MsixTable_OFFS / sizeof(u64)), + msix_vecsave[1 + 2 * i]); + } + } + + /* initialize the remaining registers. */ + for (i = 0; i < dd->num_pports; ++i) + write_7322_init_portregs(&dd->pport[i]); + write_7322_initregs(dd); + + if (qib_pcie_params(dd, dd->lbus_width, + &dd->cspec->num_msix_entries, + dd->cspec->msix_entries)) + qib_dev_err(dd, "Reset failed to setup PCIe or interrupts; " + "continuing anyway\n"); + + qib_setup_7322_interrupt(dd, 1); + + for (i = 0; i < dd->num_pports; ++i) { + struct qib_pportdata *ppd = &dd->pport[i]; + + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags |= QIBL_IB_FORCE_NOTIFY; + ppd->lflags &= ~QIBL_IB_AUTONEG_FAILED; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + } + +bail: + dd->flags &= ~QIB_DOING_RESET; /* OK or not, no longer resetting */ + kfree(msix_vecsave); + return ret; +} + +/** + * qib_7322_put_tid - write a TID to the chip + * @dd: the qlogic_ib device + * @tidptr: pointer to the expected TID (in chip) to update + * @tidtype: 0 for eager, 1 for expected + * @pa: physical address of in memory buffer; tidinvalid if freeing + */ +static void qib_7322_put_tid(struct qib_devdata *dd, u64 __iomem *tidptr, + u32 type, unsigned long pa) +{ + if (!(dd->flags & QIB_PRESENT)) + return; + if (pa != dd->tidinvalid) { + u64 chippa = pa >> IBA7322_TID_PA_SHIFT; + + /* paranoia checks */ + if (pa != (chippa << IBA7322_TID_PA_SHIFT)) { + qib_dev_err(dd, "Physaddr %lx not 2KB aligned!\n", + pa); + return; + } + if (chippa >= (1UL << IBA7322_TID_SZ_SHIFT)) { + qib_dev_err(dd, "Physical page address 0x%lx " + "larger than supported\n", pa); + return; + } + + if (type == RCVHQ_RCV_TYPE_EAGER) + chippa |= dd->tidtemplate; + else /* for now, always full 4KB page */ + chippa |= IBA7322_TID_SZ_4K; + pa = chippa; + } + writeq(pa, tidptr); + mmiowb(); +} + +/** + * qib_7322_clear_tids - clear all TID entries for a ctxt, expected and eager + * @dd: the qlogic_ib device + * @ctxt: the ctxt + * + * clear all TID entries for a ctxt, expected and eager. + * Used from qib_close(). + */ +static void qib_7322_clear_tids(struct qib_devdata *dd, + struct qib_ctxtdata *rcd) +{ + u64 __iomem *tidbase; + unsigned long tidinv; + u32 ctxt; + int i; + + if (!dd->kregbase || !rcd) + return; + + ctxt = rcd->ctxt; + + tidinv = dd->tidinvalid; + tidbase = (u64 __iomem *) + ((char __iomem *) dd->kregbase + + dd->rcvtidbase + + ctxt * dd->rcvtidcnt * sizeof(*tidbase)); + + for (i = 0; i < dd->rcvtidcnt; i++) + qib_7322_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EXPECTED, + tidinv); + + tidbase = (u64 __iomem *) + ((char __iomem *) dd->kregbase + + dd->rcvegrbase + + rcd->rcvegr_tid_base * sizeof(*tidbase)); + + for (i = 0; i < rcd->rcvegrcnt; i++) + qib_7322_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EAGER, + tidinv); +} + +/** + * qib_7322_tidtemplate - setup constants for TID updates + * @dd: the qlogic_ib device + * + * We setup stuff that we use a lot, to avoid calculating each time + */ +static void qib_7322_tidtemplate(struct qib_devdata *dd) +{ + /* + * For now, we always allocate 4KB buffers (at init) so we can + * receive max size packets. We may want a module parameter to + * specify 2KB or 4KB and/or make it per port instead of per device + * for those who want to reduce memory footprint. Note that the + * rcvhdrentsize size must be large enough to hold the largest + * IB header (currently 96 bytes) that we expect to handle (plus of + * course the 2 dwords of RHF). + */ + if (dd->rcvegrbufsize == 2048) + dd->tidtemplate = IBA7322_TID_SZ_2K; + else if (dd->rcvegrbufsize == 4096) + dd->tidtemplate = IBA7322_TID_SZ_4K; + dd->tidinvalid = 0; +} + +/** + * qib_init_7322_get_base_info - set chip-specific flags for user code + * @rcd: the qlogic_ib ctxt + * @kbase: qib_base_info pointer + * + * We set the PCIE flag because the lower bandwidth on PCIe vs + * HyperTransport can affect some user packet algorithims. + */ + +static int qib_7322_get_base_info(struct qib_ctxtdata *rcd, + struct qib_base_info *kinfo) +{ + kinfo->spi_runtime_flags |= QIB_RUNTIME_CTXT_MSB_IN_QP | + QIB_RUNTIME_PCIE | QIB_RUNTIME_NODMA_RTAIL | + QIB_RUNTIME_HDRSUPP | QIB_RUNTIME_SDMA; + if (rcd->dd->cspec->r1) + kinfo->spi_runtime_flags |= QIB_RUNTIME_RCHK; + if (rcd->dd->flags & QIB_USE_SPCL_TRIG) + kinfo->spi_runtime_flags |= QIB_RUNTIME_SPECIAL_TRIGGER; + + return 0; +} + +static struct qib_message_header * +qib_7322_get_msgheader(struct qib_devdata *dd, __le32 *rhf_addr) +{ + u32 offset = qib_hdrget_offset(rhf_addr); + + return (struct qib_message_header *) + (rhf_addr - dd->rhf_offset + offset); +} + +/* + * Configure number of contexts. + */ +static void qib_7322_config_ctxts(struct qib_devdata *dd) +{ + unsigned long flags; + u32 nchipctxts; + + nchipctxts = qib_read_kreg32(dd, kr_contextcnt); + dd->cspec->numctxts = nchipctxts; + if (qib_n_krcv_queues > 1 && dd->num_pports) { + /* + * Set the mask for which bits from the QPN are used + * to select a context number. + */ + dd->qpn_mask = 0x3f; + dd->first_user_ctxt = NUM_IB_PORTS + + (qib_n_krcv_queues - 1) * dd->num_pports; + if (dd->first_user_ctxt > nchipctxts) + dd->first_user_ctxt = nchipctxts; + dd->n_krcv_queues = dd->first_user_ctxt / dd->num_pports; + } else { + dd->first_user_ctxt = NUM_IB_PORTS; + dd->n_krcv_queues = 1; + } + + if (!qib_cfgctxts) { + int nctxts = dd->first_user_ctxt + num_online_cpus(); + + if (nctxts <= 6) + dd->ctxtcnt = 6; + else if (nctxts <= 10) + dd->ctxtcnt = 10; + else if (nctxts <= nchipctxts) + dd->ctxtcnt = nchipctxts; + } else if (qib_cfgctxts < dd->num_pports) + dd->ctxtcnt = dd->num_pports; + else if (qib_cfgctxts <= nchipctxts) + dd->ctxtcnt = qib_cfgctxts; + if (!dd->ctxtcnt) /* none of the above, set to max */ + dd->ctxtcnt = nchipctxts; + + /* + * Chip can be configured for 6, 10, or 18 ctxts, and choice + * affects number of eager TIDs per ctxt (1K, 2K, 4K). + * Lock to be paranoid about later motion, etc. + */ + spin_lock_irqsave(&dd->cspec->rcvmod_lock, flags); + if (dd->ctxtcnt > 10) + dd->rcvctrl |= 2ULL << SYM_LSB(RcvCtrl, ContextCfg); + else if (dd->ctxtcnt > 6) + dd->rcvctrl |= 1ULL << SYM_LSB(RcvCtrl, ContextCfg); + /* else configure for default 6 receive ctxts */ + + /* The XRC opcode is 5. */ + dd->rcvctrl |= 5ULL << SYM_LSB(RcvCtrl, XrcTypeCode); + + /* + * RcvCtrl *must* be written here so that the + * chip understands how to change rcvegrcnt below. + */ + qib_write_kreg(dd, kr_rcvctrl, dd->rcvctrl); + spin_unlock_irqrestore(&dd->cspec->rcvmod_lock, flags); + + /* kr_rcvegrcnt changes based on the number of contexts enabled */ + dd->cspec->rcvegrcnt = qib_read_kreg32(dd, kr_rcvegrcnt); + dd->rcvhdrcnt = max(dd->cspec->rcvegrcnt, + dd->num_pports > 1 ? 1024U : 2048U); +} + +static int qib_7322_get_ib_cfg(struct qib_pportdata *ppd, int which) +{ + + int lsb, ret = 0; + u64 maskr; /* right-justified mask */ + + switch (which) { + + case QIB_IB_CFG_LWID_ENB: /* Get allowed Link-width */ + ret = ppd->link_width_enabled; + goto done; + + case QIB_IB_CFG_LWID: /* Get currently active Link-width */ + ret = ppd->link_width_active; + goto done; + + case QIB_IB_CFG_SPD_ENB: /* Get allowed Link speeds */ + ret = ppd->link_speed_enabled; + goto done; + + case QIB_IB_CFG_SPD: /* Get current Link spd */ + ret = ppd->link_speed_active; + goto done; + + case QIB_IB_CFG_RXPOL_ENB: /* Get Auto-RX-polarity enable */ + lsb = SYM_LSB(IBCCtrlB_0, IB_POLARITY_REV_SUPP); + maskr = SYM_RMASK(IBCCtrlB_0, IB_POLARITY_REV_SUPP); + break; + + case QIB_IB_CFG_LREV_ENB: /* Get Auto-Lane-reversal enable */ + lsb = SYM_LSB(IBCCtrlB_0, IB_LANE_REV_SUPPORTED); + maskr = SYM_RMASK(IBCCtrlB_0, IB_LANE_REV_SUPPORTED); + break; + + case QIB_IB_CFG_LINKLATENCY: + ret = qib_read_kreg_port(ppd, krp_ibcstatus_b) & + SYM_MASK(IBCStatusB_0, LinkRoundTripLatency); + goto done; + + case QIB_IB_CFG_OP_VLS: + ret = ppd->vls_operational; + goto done; + + case QIB_IB_CFG_VL_HIGH_CAP: + ret = 16; + goto done; + + case QIB_IB_CFG_VL_LOW_CAP: + ret = 16; + goto done; + + case QIB_IB_CFG_OVERRUN_THRESH: /* IB overrun threshold */ + ret = SYM_FIELD(ppd->cpspec->ibcctrl_a, IBCCtrlA_0, + OverrunThreshold); + goto done; + + case QIB_IB_CFG_PHYERR_THRESH: /* IB PHY error threshold */ + ret = SYM_FIELD(ppd->cpspec->ibcctrl_a, IBCCtrlA_0, + PhyerrThreshold); + goto done; + + case QIB_IB_CFG_LINKDEFAULT: /* IB link default (sleep/poll) */ + /* will only take effect when the link state changes */ + ret = (ppd->cpspec->ibcctrl_a & + SYM_MASK(IBCCtrlA_0, LinkDownDefaultState)) ? + IB_LINKINITCMD_SLEEP : IB_LINKINITCMD_POLL; + goto done; + + case QIB_IB_CFG_HRTBT: /* Get Heartbeat off/enable/auto */ + lsb = IBA7322_IBC_HRTBT_LSB; + maskr = IBA7322_IBC_HRTBT_RMASK; /* OR of AUTO and ENB */ + break; + + case QIB_IB_CFG_PMA_TICKS: + /* + * 0x00 = 10x link transfer rate or 4 nsec. for 2.5Gbs + * Since the clock is always 250MHz, the value is 3, 1 or 0. + */ + if (ppd->link_speed_active == QIB_IB_QDR) + ret = 3; + else if (ppd->link_speed_active == QIB_IB_DDR) + ret = 1; + else + ret = 0; + goto done; + + default: + ret = -EINVAL; + goto done; + } + ret = (int)((ppd->cpspec->ibcctrl_b >> lsb) & maskr); +done: + return ret; +} + +/* + * Below again cribbed liberally from older version. Do not lean + * heavily on it. + */ +#define IBA7322_IBC_DLIDLMC_SHIFT QIB_7322_IBCCtrlB_0_IB_DLID_LSB +#define IBA7322_IBC_DLIDLMC_MASK (QIB_7322_IBCCtrlB_0_IB_DLID_RMASK \ + | (QIB_7322_IBCCtrlB_0_IB_DLID_MASK_RMASK << 16)) + +static int qib_7322_set_ib_cfg(struct qib_pportdata *ppd, int which, u32 val) +{ + struct qib_devdata *dd = ppd->dd; + u64 maskr; /* right-justified mask */ + int lsb, ret = 0; + u16 lcmd, licmd; + unsigned long flags; + + switch (which) { + case QIB_IB_CFG_LIDLMC: + /* + * Set LID and LMC. Combined to avoid possible hazard + * caller puts LMC in 16MSbits, DLID in 16LSbits of val + */ + lsb = IBA7322_IBC_DLIDLMC_SHIFT; + maskr = IBA7322_IBC_DLIDLMC_MASK; + /* + * For header-checking, the SLID in the packet will + * be masked with SendIBSLMCMask, and compared + * with SendIBSLIDAssignMask. Make sure we do not + * set any bits not covered by the mask, or we get + * false-positives. + */ + qib_write_kreg_port(ppd, krp_sendslid, + val & (val >> 16) & SendIBSLIDAssignMask); + qib_write_kreg_port(ppd, krp_sendslidmask, + (val >> 16) & SendIBSLMCMask); + break; + + case QIB_IB_CFG_LWID_ENB: /* set allowed Link-width */ + ppd->link_width_enabled = val; + /* convert IB value to chip register value */ + if (val == IB_WIDTH_1X) + val = 0; + else if (val == IB_WIDTH_4X) + val = 1; + else + val = 3; + maskr = SYM_RMASK(IBCCtrlB_0, IB_NUM_CHANNELS); + lsb = SYM_LSB(IBCCtrlB_0, IB_NUM_CHANNELS); + break; + + case QIB_IB_CFG_SPD_ENB: /* set allowed Link speeds */ + /* + * As with width, only write the actual register if the + * link is currently down, otherwise takes effect on next + * link change. Since setting is being explictly requested + * (via MAD or sysfs), clear autoneg failure status if speed + * autoneg is enabled. + */ + ppd->link_speed_enabled = val; + val <<= IBA7322_IBC_SPEED_LSB; + maskr = IBA7322_IBC_SPEED_MASK | IBA7322_IBC_IBTA_1_2_MASK | + IBA7322_IBC_MAX_SPEED_MASK; + if (val & (val - 1)) { + /* Muliple speeds enabled */ + val |= IBA7322_IBC_IBTA_1_2_MASK | + IBA7322_IBC_MAX_SPEED_MASK; + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags &= ~QIBL_IB_AUTONEG_FAILED; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + } else if (val & IBA7322_IBC_SPEED_QDR) + val |= IBA7322_IBC_IBTA_1_2_MASK; + /* IBTA 1.2 mode + min/max + speed bits are contiguous */ + lsb = SYM_LSB(IBCCtrlB_0, IB_ENHANCED_MODE); + break; + + case QIB_IB_CFG_RXPOL_ENB: /* set Auto-RX-polarity enable */ + lsb = SYM_LSB(IBCCtrlB_0, IB_POLARITY_REV_SUPP); + maskr = SYM_RMASK(IBCCtrlB_0, IB_POLARITY_REV_SUPP); + break; + + case QIB_IB_CFG_LREV_ENB: /* set Auto-Lane-reversal enable */ + lsb = SYM_LSB(IBCCtrlB_0, IB_LANE_REV_SUPPORTED); + maskr = SYM_RMASK(IBCCtrlB_0, IB_LANE_REV_SUPPORTED); + break; + + case QIB_IB_CFG_OVERRUN_THRESH: /* IB overrun threshold */ + maskr = SYM_FIELD(ppd->cpspec->ibcctrl_a, IBCCtrlA_0, + OverrunThreshold); + if (maskr != val) { + ppd->cpspec->ibcctrl_a &= + ~SYM_MASK(IBCCtrlA_0, OverrunThreshold); + ppd->cpspec->ibcctrl_a |= (u64) val << + SYM_LSB(IBCCtrlA_0, OverrunThreshold); + qib_write_kreg_port(ppd, krp_ibcctrl_a, + ppd->cpspec->ibcctrl_a); + qib_write_kreg(dd, kr_scratch, 0ULL); + } + goto bail; + + case QIB_IB_CFG_PHYERR_THRESH: /* IB PHY error threshold */ + maskr = SYM_FIELD(ppd->cpspec->ibcctrl_a, IBCCtrlA_0, + PhyerrThreshold); + if (maskr != val) { + ppd->cpspec->ibcctrl_a &= + ~SYM_MASK(IBCCtrlA_0, PhyerrThreshold); + ppd->cpspec->ibcctrl_a |= (u64) val << + SYM_LSB(IBCCtrlA_0, PhyerrThreshold); + qib_write_kreg_port(ppd, krp_ibcctrl_a, + ppd->cpspec->ibcctrl_a); + qib_write_kreg(dd, kr_scratch, 0ULL); + } + goto bail; + + case QIB_IB_CFG_PKEYS: /* update pkeys */ + maskr = (u64) ppd->pkeys[0] | ((u64) ppd->pkeys[1] << 16) | + ((u64) ppd->pkeys[2] << 32) | + ((u64) ppd->pkeys[3] << 48); + qib_write_kreg_port(ppd, krp_partitionkey, maskr); + goto bail; + + case QIB_IB_CFG_LINKDEFAULT: /* IB link default (sleep/poll) */ + /* will only take effect when the link state changes */ + if (val == IB_LINKINITCMD_POLL) + ppd->cpspec->ibcctrl_a &= + ~SYM_MASK(IBCCtrlA_0, LinkDownDefaultState); + else /* SLEEP */ + ppd->cpspec->ibcctrl_a |= + SYM_MASK(IBCCtrlA_0, LinkDownDefaultState); + qib_write_kreg_port(ppd, krp_ibcctrl_a, ppd->cpspec->ibcctrl_a); + qib_write_kreg(dd, kr_scratch, 0ULL); + goto bail; + + case QIB_IB_CFG_MTU: /* update the MTU in IBC */ + /* + * Update our housekeeping variables, and set IBC max + * size, same as init code; max IBC is max we allow in + * buffer, less the qword pbc, plus 1 for ICRC, in dwords + * Set even if it's unchanged, print debug message only + * on changes. + */ + val = (ppd->ibmaxlen >> 2) + 1; + ppd->cpspec->ibcctrl_a &= ~SYM_MASK(IBCCtrlA_0, MaxPktLen); + ppd->cpspec->ibcctrl_a |= (u64)val << + SYM_LSB(IBCCtrlA_0, MaxPktLen); + qib_write_kreg_port(ppd, krp_ibcctrl_a, + ppd->cpspec->ibcctrl_a); + qib_write_kreg(dd, kr_scratch, 0ULL); + goto bail; + + case QIB_IB_CFG_LSTATE: /* set the IB link state */ + switch (val & 0xffff0000) { + case IB_LINKCMD_DOWN: + lcmd = QLOGIC_IB_IBCC_LINKCMD_DOWN; + ppd->cpspec->ibmalfusesnap = 1; + ppd->cpspec->ibmalfsnap = read_7322_creg32_port(ppd, + crp_errlink); + if (!ppd->cpspec->ibdeltainprog && + qib_compat_ddr_negotiate) { + ppd->cpspec->ibdeltainprog = 1; + ppd->cpspec->ibsymsnap = + read_7322_creg32_port(ppd, + crp_ibsymbolerr); + ppd->cpspec->iblnkerrsnap = + read_7322_creg32_port(ppd, + crp_iblinkerrrecov); + } + break; + + case IB_LINKCMD_ARMED: + lcmd = QLOGIC_IB_IBCC_LINKCMD_ARMED; + if (ppd->cpspec->ibmalfusesnap) { + ppd->cpspec->ibmalfusesnap = 0; + ppd->cpspec->ibmalfdelta += + read_7322_creg32_port(ppd, + crp_errlink) - + ppd->cpspec->ibmalfsnap; + } + break; + + case IB_LINKCMD_ACTIVE: + lcmd = QLOGIC_IB_IBCC_LINKCMD_ACTIVE; + break; + + default: + ret = -EINVAL; + qib_dev_err(dd, "bad linkcmd req 0x%x\n", val >> 16); + goto bail; + } + switch (val & 0xffff) { + case IB_LINKINITCMD_NOP: + licmd = 0; + break; + + case IB_LINKINITCMD_POLL: + licmd = QLOGIC_IB_IBCC_LINKINITCMD_POLL; + break; + + case IB_LINKINITCMD_SLEEP: + licmd = QLOGIC_IB_IBCC_LINKINITCMD_SLEEP; + break; + + case IB_LINKINITCMD_DISABLE: + licmd = QLOGIC_IB_IBCC_LINKINITCMD_DISABLE; + ppd->cpspec->chase_end = 0; + /* + * stop state chase counter and timer, if running. + * wait forpending timer, but don't clear .data (ppd)! + */ + if (ppd->cpspec->chase_timer.expires) { + del_timer_sync(&ppd->cpspec->chase_timer); + ppd->cpspec->chase_timer.expires = 0; + } + break; + + default: + ret = -EINVAL; + qib_dev_err(dd, "bad linkinitcmd req 0x%x\n", + val & 0xffff); + goto bail; + } + qib_set_ib_7322_lstate(ppd, lcmd, licmd); + goto bail; + + case QIB_IB_CFG_OP_VLS: + if (ppd->vls_operational != val) { + ppd->vls_operational = val; + set_vls(ppd); + } + goto bail; + + case QIB_IB_CFG_VL_HIGH_LIMIT: + qib_write_kreg_port(ppd, krp_highprio_limit, val); + goto bail; + + case QIB_IB_CFG_HRTBT: /* set Heartbeat off/enable/auto */ + if (val > 3) { + ret = -EINVAL; + goto bail; + } + lsb = IBA7322_IBC_HRTBT_LSB; + maskr = IBA7322_IBC_HRTBT_RMASK; /* OR of AUTO and ENB */ + break; + + case QIB_IB_CFG_PORT: + /* val is the port number of the switch we are connected to. */ + if (ppd->dd->cspec->r1) { + cancel_delayed_work(&ppd->cpspec->ipg_work); + ppd->cpspec->ipg_tries = 0; + } + goto bail; + + default: + ret = -EINVAL; + goto bail; + } + ppd->cpspec->ibcctrl_b &= ~(maskr << lsb); + ppd->cpspec->ibcctrl_b |= (((u64) val & maskr) << lsb); + qib_write_kreg_port(ppd, krp_ibcctrl_b, ppd->cpspec->ibcctrl_b); + qib_write_kreg(dd, kr_scratch, 0); +bail: + return ret; +} + +static int qib_7322_set_loopback(struct qib_pportdata *ppd, const char *what) +{ + int ret = 0; + u64 val, ctrlb; + + /* only IBC loopback, may add serdes and xgxs loopbacks later */ + if (!strncmp(what, "ibc", 3)) { + ppd->cpspec->ibcctrl_a |= SYM_MASK(IBCCtrlA_0, + Loopback); + val = 0; /* disable heart beat, so link will come up */ + qib_devinfo(ppd->dd->pcidev, "Enabling IB%u:%u IBC loopback\n", + ppd->dd->unit, ppd->port); + } else if (!strncmp(what, "off", 3)) { + ppd->cpspec->ibcctrl_a &= ~SYM_MASK(IBCCtrlA_0, + Loopback); + /* enable heart beat again */ + val = IBA7322_IBC_HRTBT_RMASK << IBA7322_IBC_HRTBT_LSB; + qib_devinfo(ppd->dd->pcidev, "Disabling IB%u:%u IBC loopback " + "(normal)\n", ppd->dd->unit, ppd->port); + } else + ret = -EINVAL; + if (!ret) { + qib_write_kreg_port(ppd, krp_ibcctrl_a, + ppd->cpspec->ibcctrl_a); + ctrlb = ppd->cpspec->ibcctrl_b & ~(IBA7322_IBC_HRTBT_MASK + << IBA7322_IBC_HRTBT_LSB); + ppd->cpspec->ibcctrl_b = ctrlb | val; + qib_write_kreg_port(ppd, krp_ibcctrl_b, + ppd->cpspec->ibcctrl_b); + qib_write_kreg(ppd->dd, kr_scratch, 0); + } + return ret; +} + +static void get_vl_weights(struct qib_pportdata *ppd, unsigned regno, + struct ib_vl_weight_elem *vl) +{ + unsigned i; + + for (i = 0; i < 16; i++, regno++, vl++) { + u32 val = qib_read_kreg_port(ppd, regno); + + vl->vl = (val >> SYM_LSB(LowPriority0_0, VirtualLane)) & + SYM_RMASK(LowPriority0_0, VirtualLane); + vl->weight = (val >> SYM_LSB(LowPriority0_0, Weight)) & + SYM_RMASK(LowPriority0_0, Weight); + } +} + +static void set_vl_weights(struct qib_pportdata *ppd, unsigned regno, + struct ib_vl_weight_elem *vl) +{ + unsigned i; + + for (i = 0; i < 16; i++, regno++, vl++) { + u64 val; + + val = ((vl->vl & SYM_RMASK(LowPriority0_0, VirtualLane)) << + SYM_LSB(LowPriority0_0, VirtualLane)) | + ((vl->weight & SYM_RMASK(LowPriority0_0, Weight)) << + SYM_LSB(LowPriority0_0, Weight)); + qib_write_kreg_port(ppd, regno, val); + } + if (!(ppd->p_sendctrl & SYM_MASK(SendCtrl_0, IBVLArbiterEn))) { + struct qib_devdata *dd = ppd->dd; + unsigned long flags; + + spin_lock_irqsave(&dd->sendctrl_lock, flags); + ppd->p_sendctrl |= SYM_MASK(SendCtrl_0, IBVLArbiterEn); + qib_write_kreg_port(ppd, krp_sendctrl, ppd->p_sendctrl); + qib_write_kreg(dd, kr_scratch, 0); + spin_unlock_irqrestore(&dd->sendctrl_lock, flags); + } +} + +static int qib_7322_get_ib_table(struct qib_pportdata *ppd, int which, void *t) +{ + switch (which) { + case QIB_IB_TBL_VL_HIGH_ARB: + get_vl_weights(ppd, krp_highprio_0, t); + break; + + case QIB_IB_TBL_VL_LOW_ARB: + get_vl_weights(ppd, krp_lowprio_0, t); + break; + + default: + return -EINVAL; + } + return 0; +} + +static int qib_7322_set_ib_table(struct qib_pportdata *ppd, int which, void *t) +{ + switch (which) { + case QIB_IB_TBL_VL_HIGH_ARB: + set_vl_weights(ppd, krp_highprio_0, t); + break; + + case QIB_IB_TBL_VL_LOW_ARB: + set_vl_weights(ppd, krp_lowprio_0, t); + break; + + default: + return -EINVAL; + } + return 0; +} + +static void qib_update_7322_usrhead(struct qib_ctxtdata *rcd, u64 hd, + u32 updegr, u32 egrhd) +{ + qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); + qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt); + if (updegr) + qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt); +} + +static u32 qib_7322_hdrqempty(struct qib_ctxtdata *rcd) +{ + u32 head, tail; + + head = qib_read_ureg32(rcd->dd, ur_rcvhdrhead, rcd->ctxt); + if (rcd->rcvhdrtail_kvaddr) + tail = qib_get_rcvhdrtail(rcd); + else + tail = qib_read_ureg32(rcd->dd, ur_rcvhdrtail, rcd->ctxt); + return head == tail; +} + +#define RCVCTRL_COMMON_MODS (QIB_RCVCTRL_CTXT_ENB | \ + QIB_RCVCTRL_CTXT_DIS | \ + QIB_RCVCTRL_TIDFLOW_ENB | \ + QIB_RCVCTRL_TIDFLOW_DIS | \ + QIB_RCVCTRL_TAILUPD_ENB | \ + QIB_RCVCTRL_TAILUPD_DIS | \ + QIB_RCVCTRL_INTRAVAIL_ENB | \ + QIB_RCVCTRL_INTRAVAIL_DIS | \ + QIB_RCVCTRL_BP_ENB | \ + QIB_RCVCTRL_BP_DIS) + +#define RCVCTRL_PORT_MODS (QIB_RCVCTRL_CTXT_ENB | \ + QIB_RCVCTRL_CTXT_DIS | \ + QIB_RCVCTRL_PKEY_DIS | \ + QIB_RCVCTRL_PKEY_ENB) + +/* + * Modify the RCVCTRL register in chip-specific way. This + * is a function because bit positions and (future) register + * location is chip-specifc, but the needed operations are + * generic. is a bit-mask because we often want to + * do multiple modifications. + */ +static void rcvctrl_7322_mod(struct qib_pportdata *ppd, unsigned int op, + int ctxt) +{ + struct qib_devdata *dd = ppd->dd; + struct qib_ctxtdata *rcd; + u64 mask, val; + unsigned long flags; + + spin_lock_irqsave(&dd->cspec->rcvmod_lock, flags); + + if (op & QIB_RCVCTRL_TIDFLOW_ENB) + dd->rcvctrl |= SYM_MASK(RcvCtrl, TidFlowEnable); + if (op & QIB_RCVCTRL_TIDFLOW_DIS) + dd->rcvctrl &= ~SYM_MASK(RcvCtrl, TidFlowEnable); + if (op & QIB_RCVCTRL_TAILUPD_ENB) + dd->rcvctrl |= SYM_MASK(RcvCtrl, TailUpd); + if (op & QIB_RCVCTRL_TAILUPD_DIS) + dd->rcvctrl &= ~SYM_MASK(RcvCtrl, TailUpd); + if (op & QIB_RCVCTRL_PKEY_ENB) + ppd->p_rcvctrl &= ~SYM_MASK(RcvCtrl_0, RcvPartitionKeyDisable); + if (op & QIB_RCVCTRL_PKEY_DIS) + ppd->p_rcvctrl |= SYM_MASK(RcvCtrl_0, RcvPartitionKeyDisable); + if (ctxt < 0) { + mask = (1ULL << dd->ctxtcnt) - 1; + rcd = NULL; + } else { + mask = (1ULL << ctxt); + rcd = dd->rcd[ctxt]; + } + if ((op & QIB_RCVCTRL_CTXT_ENB) && rcd) { + ppd->p_rcvctrl |= + (mask << SYM_LSB(RcvCtrl_0, ContextEnableKernel)); + if (!(dd->flags & QIB_NODMA_RTAIL)) { + op |= QIB_RCVCTRL_TAILUPD_ENB; /* need reg write */ + dd->rcvctrl |= SYM_MASK(RcvCtrl, TailUpd); + } + /* Write these registers before the context is enabled. */ + qib_write_kreg_ctxt(dd, krc_rcvhdrtailaddr, ctxt, + rcd->rcvhdrqtailaddr_phys); + qib_write_kreg_ctxt(dd, krc_rcvhdraddr, ctxt, + rcd->rcvhdrq_phys); + rcd->seq_cnt = 1; +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) + if (dd->flags & QIB_DCA_ENABLED) + qib_update_rhdrq_dca(rcd); +#endif + } + if (op & QIB_RCVCTRL_CTXT_DIS) + ppd->p_rcvctrl &= + ~(mask << SYM_LSB(RcvCtrl_0, ContextEnableKernel)); + if (op & QIB_RCVCTRL_BP_ENB) + dd->rcvctrl |= mask << SYM_LSB(RcvCtrl, dontDropRHQFull); + if (op & QIB_RCVCTRL_BP_DIS) + dd->rcvctrl &= ~(mask << SYM_LSB(RcvCtrl, dontDropRHQFull)); + if (op & QIB_RCVCTRL_INTRAVAIL_ENB) + dd->rcvctrl |= (mask << SYM_LSB(RcvCtrl, IntrAvail)); + if (op & QIB_RCVCTRL_INTRAVAIL_DIS) + dd->rcvctrl &= ~(mask << SYM_LSB(RcvCtrl, IntrAvail)); + /* + * Decide which registers to write depending on the ops enabled. + * Special case is "flush" (no bits set at all) + * which needs to write both. + */ + if (op == 0 || (op & RCVCTRL_COMMON_MODS)) + qib_write_kreg(dd, kr_rcvctrl, dd->rcvctrl); + if (op == 0 || (op & RCVCTRL_PORT_MODS)) + qib_write_kreg_port(ppd, krp_rcvctrl, ppd->p_rcvctrl); + if ((op & QIB_RCVCTRL_CTXT_ENB) && dd->rcd[ctxt]) { + /* + * Init the context registers also; if we were + * disabled, tail and head should both be zero + * already from the enable, but since we don't + * know, we have to do it explictly. + */ + val = qib_read_ureg32(dd, ur_rcvegrindextail, ctxt); + qib_write_ureg(dd, ur_rcvegrindexhead, val, ctxt); + + /* be sure enabling write seen; hd/tl should be 0 */ + (void) qib_read_kreg32(dd, kr_scratch); + val = qib_read_ureg32(dd, ur_rcvhdrtail, ctxt); + dd->rcd[ctxt]->head = val; + /* If kctxt, interrupt on next receive. */ + if (ctxt < dd->first_user_ctxt) + val |= dd->rhdrhead_intr_off; + qib_write_ureg(dd, ur_rcvhdrhead, val, ctxt); + } else if ((op & QIB_RCVCTRL_INTRAVAIL_ENB) && + dd->rcd[ctxt] && dd->rhdrhead_intr_off) { + /* arm rcv interrupt */ + val = dd->rcd[ctxt]->head | dd->rhdrhead_intr_off; + qib_write_ureg(dd, ur_rcvhdrhead, val, ctxt); + } + if (op & QIB_RCVCTRL_CTXT_DIS) { + unsigned f; + + /* Now that the context is disabled, clear these registers. */ + if (ctxt >= 0) { + qib_write_kreg_ctxt(dd, krc_rcvhdrtailaddr, ctxt, 0); + qib_write_kreg_ctxt(dd, krc_rcvhdraddr, ctxt, 0); + for (f = 0; f < NUM_TIDFLOWS_CTXT; f++) + qib_write_ureg(dd, ur_rcvflowtable + f, + TIDFLOW_ERRBITS, ctxt); + } else { + unsigned i; + + for (i = 0; i < dd->cfgctxts; i++) { + qib_write_kreg_ctxt(dd, krc_rcvhdrtailaddr, + i, 0); + qib_write_kreg_ctxt(dd, krc_rcvhdraddr, i, 0); + for (f = 0; f < NUM_TIDFLOWS_CTXT; f++) + qib_write_ureg(dd, ur_rcvflowtable + f, + TIDFLOW_ERRBITS, i); + } + } + } + spin_unlock_irqrestore(&dd->cspec->rcvmod_lock, flags); +} + +/* + * Modify the SENDCTRL register in chip-specific way. This + * is a function where there are multiple such registers with + * slightly different layouts. + * The chip doesn't allow back-to-back sendctrl writes, so write + * the scratch register after writing sendctrl. + * + * Which register is written depends on the operation. + * Most operate on the common register, while + * SEND_ENB and SEND_DIS operate on the per-port ones. + * SEND_ENB is included in common because it can change SPCL_TRIG + */ +#define SENDCTRL_COMMON_MODS (\ + QIB_SENDCTRL_CLEAR | \ + QIB_SENDCTRL_AVAIL_DIS | \ + QIB_SENDCTRL_AVAIL_ENB | \ + QIB_SENDCTRL_AVAIL_BLIP | \ + QIB_SENDCTRL_DISARM | \ + QIB_SENDCTRL_DISARM_ALL | \ + QIB_SENDCTRL_SEND_ENB) + +#define SENDCTRL_PORT_MODS (\ + QIB_SENDCTRL_CLEAR | \ + QIB_SENDCTRL_SEND_ENB | \ + QIB_SENDCTRL_SEND_DIS | \ + QIB_SENDCTRL_FLUSH) + +static void sendctrl_7322_mod(struct qib_pportdata *ppd, u32 op) +{ + struct qib_devdata *dd = ppd->dd; + u64 tmp_dd_sendctrl; + unsigned long flags; + + spin_lock_irqsave(&dd->sendctrl_lock, flags); + + /* First the dd ones that are "sticky", saved in shadow */ + if (op & QIB_SENDCTRL_CLEAR) + dd->sendctrl = 0; + if (op & QIB_SENDCTRL_AVAIL_DIS) + dd->sendctrl &= ~SYM_MASK(SendCtrl, SendBufAvailUpd); + else if (op & QIB_SENDCTRL_AVAIL_ENB) { + dd->sendctrl |= SYM_MASK(SendCtrl, SendBufAvailUpd); + if (dd->flags & QIB_USE_SPCL_TRIG) + dd->sendctrl |= SYM_MASK(SendCtrl, SpecialTriggerEn); + } + + /* Then the ppd ones that are "sticky", saved in shadow */ + if (op & QIB_SENDCTRL_SEND_DIS) + ppd->p_sendctrl &= ~SYM_MASK(SendCtrl_0, SendEnable); + else if (op & QIB_SENDCTRL_SEND_ENB) + ppd->p_sendctrl |= SYM_MASK(SendCtrl_0, SendEnable); + + if (op & QIB_SENDCTRL_DISARM_ALL) { + u32 i, last; + + tmp_dd_sendctrl = dd->sendctrl; + last = dd->piobcnt2k + dd->piobcnt4k + NUM_VL15_BUFS; + /* + * Disarm any buffers that are not yet launched, + * disabling updates until done. + */ + tmp_dd_sendctrl &= ~SYM_MASK(SendCtrl, SendBufAvailUpd); + for (i = 0; i < last; i++) { + qib_write_kreg(dd, kr_sendctrl, + tmp_dd_sendctrl | + SYM_MASK(SendCtrl, Disarm) | i); + qib_write_kreg(dd, kr_scratch, 0); + } + } + + if (op & QIB_SENDCTRL_FLUSH) { + u64 tmp_ppd_sendctrl = ppd->p_sendctrl; + + /* + * Now drain all the fifos. The Abort bit should never be + * needed, so for now, at least, we don't use it. + */ + tmp_ppd_sendctrl |= + SYM_MASK(SendCtrl_0, TxeDrainRmFifo) | + SYM_MASK(SendCtrl_0, TxeDrainLaFifo) | + SYM_MASK(SendCtrl_0, TxeBypassIbc); + qib_write_kreg_port(ppd, krp_sendctrl, tmp_ppd_sendctrl); + qib_write_kreg(dd, kr_scratch, 0); + } + + tmp_dd_sendctrl = dd->sendctrl; + + if (op & QIB_SENDCTRL_DISARM) + tmp_dd_sendctrl |= SYM_MASK(SendCtrl, Disarm) | + ((op & QIB_7322_SendCtrl_DisarmSendBuf_RMASK) << + SYM_LSB(SendCtrl, DisarmSendBuf)); + if ((op & QIB_SENDCTRL_AVAIL_BLIP) && + (dd->sendctrl & SYM_MASK(SendCtrl, SendBufAvailUpd))) + tmp_dd_sendctrl &= ~SYM_MASK(SendCtrl, SendBufAvailUpd); + + if (op == 0 || (op & SENDCTRL_COMMON_MODS)) { + qib_write_kreg(dd, kr_sendctrl, tmp_dd_sendctrl); + qib_write_kreg(dd, kr_scratch, 0); + } + + if (op == 0 || (op & SENDCTRL_PORT_MODS)) { + qib_write_kreg_port(ppd, krp_sendctrl, ppd->p_sendctrl); + qib_write_kreg(dd, kr_scratch, 0); + } + + if (op & QIB_SENDCTRL_AVAIL_BLIP) { + qib_write_kreg(dd, kr_sendctrl, dd->sendctrl); + qib_write_kreg(dd, kr_scratch, 0); + } + + spin_unlock_irqrestore(&dd->sendctrl_lock, flags); + + if (op & QIB_SENDCTRL_FLUSH) { + u32 v; + /* + * ensure writes have hit chip, then do a few + * more reads, to allow DMA of pioavail registers + * to occur, so in-memory copy is in sync with + * the chip. Not always safe to sleep. + */ + v = qib_read_kreg32(dd, kr_scratch); + qib_write_kreg(dd, kr_scratch, v); + v = qib_read_kreg32(dd, kr_scratch); + qib_write_kreg(dd, kr_scratch, v); + qib_read_kreg32(dd, kr_scratch); + } +} + +#define _PORT_VIRT_FLAG 0x8000U /* "virtual", need adjustments */ +#define _PORT_64BIT_FLAG 0x10000U /* not "virtual", but 64bit */ +#define _PORT_CNTR_IDXMASK 0x7fffU /* mask off flags above */ + +/** + * qib_portcntr_7322 - read a per-port chip counter + * @ppd: the qlogic_ib pport + * @creg: the counter to read (not a chip offset) + */ +static u64 qib_portcntr_7322(struct qib_pportdata *ppd, u32 reg) +{ + struct qib_devdata *dd = ppd->dd; + u64 ret = 0ULL; + u16 creg; + /* 0xffff for unimplemented or synthesized counters */ + static const u32 xlator[] = { + [QIBPORTCNTR_PKTSEND] = crp_pktsend | _PORT_64BIT_FLAG, + [QIBPORTCNTR_WORDSEND] = crp_wordsend | _PORT_64BIT_FLAG, + [QIBPORTCNTR_PSXMITDATA] = crp_psxmitdatacount, + [QIBPORTCNTR_PSXMITPKTS] = crp_psxmitpktscount, + [QIBPORTCNTR_PSXMITWAIT] = crp_psxmitwaitcount, + [QIBPORTCNTR_SENDSTALL] = crp_sendstall, + [QIBPORTCNTR_PKTRCV] = crp_pktrcv | _PORT_64BIT_FLAG, + [QIBPORTCNTR_PSRCVDATA] = crp_psrcvdatacount, + [QIBPORTCNTR_PSRCVPKTS] = crp_psrcvpktscount, + [QIBPORTCNTR_RCVEBP] = crp_rcvebp, + [QIBPORTCNTR_RCVOVFL] = crp_rcvovfl, + [QIBPORTCNTR_WORDRCV] = crp_wordrcv | _PORT_64BIT_FLAG, + [QIBPORTCNTR_RXDROPPKT] = 0xffff, /* not needed for 7322 */ + [QIBPORTCNTR_RXLOCALPHYERR] = crp_rxotherlocalphyerr, + [QIBPORTCNTR_RXVLERR] = crp_rxvlerr, + [QIBPORTCNTR_ERRICRC] = crp_erricrc, + [QIBPORTCNTR_ERRVCRC] = crp_errvcrc, + [QIBPORTCNTR_ERRLPCRC] = crp_errlpcrc, + [QIBPORTCNTR_BADFORMAT] = crp_badformat, + [QIBPORTCNTR_ERR_RLEN] = crp_err_rlen, + [QIBPORTCNTR_IBSYMBOLERR] = crp_ibsymbolerr, + [QIBPORTCNTR_INVALIDRLEN] = crp_invalidrlen, + [QIBPORTCNTR_UNSUPVL] = crp_txunsupvl, + [QIBPORTCNTR_EXCESSBUFOVFL] = crp_excessbufferovfl, + [QIBPORTCNTR_ERRLINK] = crp_errlink, + [QIBPORTCNTR_IBLINKDOWN] = crp_iblinkdown, + [QIBPORTCNTR_IBLINKERRRECOV] = crp_iblinkerrrecov, + [QIBPORTCNTR_LLI] = crp_locallinkintegrityerr, + [QIBPORTCNTR_VL15PKTDROP] = crp_vl15droppedpkt, + [QIBPORTCNTR_ERRPKEY] = crp_errpkey, + /* + * the next 3 aren't really counters, but were implemented + * as counters in older chips, so still get accessed as + * though they were counters from this code. + */ + [QIBPORTCNTR_PSINTERVAL] = krp_psinterval, + [QIBPORTCNTR_PSSTART] = krp_psstart, + [QIBPORTCNTR_PSSTAT] = krp_psstat, + /* pseudo-counter, summed for all ports */ + [QIBPORTCNTR_KHDROVFL] = 0xffff, + }; + + if (reg >= ARRAY_SIZE(xlator)) { + qib_devinfo(ppd->dd->pcidev, + "Unimplemented portcounter %u\n", reg); + goto done; + } + creg = xlator[reg] & _PORT_CNTR_IDXMASK; + + /* handle non-counters and special cases first */ + if (reg == QIBPORTCNTR_KHDROVFL) { + int i; + + /* sum over all kernel contexts (skip if mini_init) */ + for (i = 0; dd->rcd && i < dd->first_user_ctxt; i++) { + struct qib_ctxtdata *rcd = dd->rcd[i]; + + if (!rcd || rcd->ppd != ppd) + continue; + ret += read_7322_creg32(dd, cr_base_egrovfl + i); + } + goto done; + } else if (reg == QIBPORTCNTR_RXDROPPKT) { + /* + * Used as part of the synthesis of port_rcv_errors + * in the verbs code for IBTA counters. Not needed for 7322, + * because all the errors are already counted by other cntrs. + */ + goto done; + } else if (reg == QIBPORTCNTR_PSINTERVAL || + reg == QIBPORTCNTR_PSSTART || reg == QIBPORTCNTR_PSSTAT) { + /* were counters in older chips, now per-port kernel regs */ + ret = qib_read_kreg_port(ppd, creg); + goto done; + } + + /* + * Only fast increment counters are 64 bits; use 32 bit reads to + * avoid two independent reads when on Opteron. + */ + if (xlator[reg] & _PORT_64BIT_FLAG) + ret = read_7322_creg_port(ppd, creg); + else + ret = read_7322_creg32_port(ppd, creg); + if (creg == crp_ibsymbolerr) { + if (ppd->cpspec->ibdeltainprog) + ret -= ret - ppd->cpspec->ibsymsnap; + ret -= ppd->cpspec->ibsymdelta; + } else if (creg == crp_iblinkerrrecov) { + if (ppd->cpspec->ibdeltainprog) + ret -= ret - ppd->cpspec->iblnkerrsnap; + ret -= ppd->cpspec->iblnkerrdelta; + } else if (creg == crp_errlink) + ret -= ppd->cpspec->ibmalfdelta; + else if (creg == crp_iblinkdown) + ret += ppd->cpspec->iblnkdowndelta; +done: + return ret; +} + +/* + * Device counter names (not port-specific), one line per stat, + * single string. Used by utilities like ipathstats to print the stats + * in a way which works for different versions of drivers, without changing + * the utility. Names need to be 12 chars or less (w/o newline), for proper + * display by utility. + * Non-error counters are first. + * Start of "error" conters is indicated by a leading "E " on the first + * "error" counter, and doesn't count in label length. + * The EgrOvfl list needs to be last so we truncate them at the configured + * context count for the device. + * cntr7322indices contains the corresponding register indices. + */ +static const char cntr7322names[] = + "Interrupts\n" + "HostBusStall\n" + "E RxTIDFull\n" + "RxTIDInvalid\n" + "RxTIDFloDrop\n" /* 7322 only */ + "Ctxt0EgrOvfl\n" + "Ctxt1EgrOvfl\n" + "Ctxt2EgrOvfl\n" + "Ctxt3EgrOvfl\n" + "Ctxt4EgrOvfl\n" + "Ctxt5EgrOvfl\n" + "Ctxt6EgrOvfl\n" + "Ctxt7EgrOvfl\n" + "Ctxt8EgrOvfl\n" + "Ctxt9EgrOvfl\n" + "Ctx10EgrOvfl\n" + "Ctx11EgrOvfl\n" + "Ctx12EgrOvfl\n" + "Ctx13EgrOvfl\n" + "Ctx14EgrOvfl\n" + "Ctx15EgrOvfl\n" + "Ctx16EgrOvfl\n" + "Ctx17EgrOvfl\n" + ; + +static const u32 cntr7322indices[] = { + cr_lbint | _PORT_64BIT_FLAG, + cr_lbstall | _PORT_64BIT_FLAG, + cr_tidfull, + cr_tidinvalid, + cr_rxtidflowdrop, + cr_base_egrovfl + 0, + cr_base_egrovfl + 1, + cr_base_egrovfl + 2, + cr_base_egrovfl + 3, + cr_base_egrovfl + 4, + cr_base_egrovfl + 5, + cr_base_egrovfl + 6, + cr_base_egrovfl + 7, + cr_base_egrovfl + 8, + cr_base_egrovfl + 9, + cr_base_egrovfl + 10, + cr_base_egrovfl + 11, + cr_base_egrovfl + 12, + cr_base_egrovfl + 13, + cr_base_egrovfl + 14, + cr_base_egrovfl + 15, + cr_base_egrovfl + 16, + cr_base_egrovfl + 17, +}; + +/* + * same as cntr7322names and cntr7322indices, but for port-specific counters. + * portcntr7322indices is somewhat complicated by some registers needing + * adjustments of various kinds, and those are ORed with _PORT_VIRT_FLAG + */ +static const char portcntr7322names[] = + "TxPkt\n" + "TxFlowPkt\n" + "TxWords\n" + "RxPkt\n" + "RxFlowPkt\n" + "RxWords\n" + "TxFlowStall\n" + "TxDmaDesc\n" /* 7220 and 7322-only */ + "E RxDlidFltr\n" /* 7220 and 7322-only */ + "IBStatusChng\n" + "IBLinkDown\n" + "IBLnkRecov\n" + "IBRxLinkErr\n" + "IBSymbolErr\n" + "RxLLIErr\n" + "RxBadFormat\n" + "RxBadLen\n" + "RxBufOvrfl\n" + "RxEBP\n" + "RxFlowCtlErr\n" + "RxICRCerr\n" + "RxLPCRCerr\n" + "RxVCRCerr\n" + "RxInvalLen\n" + "RxInvalPKey\n" + "RxPktDropped\n" + "TxBadLength\n" + "TxDropped\n" + "TxInvalLen\n" + "TxUnderrun\n" + "TxUnsupVL\n" + "RxLclPhyErr\n" /* 7220 and 7322-only from here down */ + "RxVL15Drop\n" + "RxVlErr\n" + "XcessBufOvfl\n" + "RxQPBadCtxt\n" /* 7322-only from here down */ + "TXBadHeader\n" + ; + +static const u32 portcntr7322indices[] = { + QIBPORTCNTR_PKTSEND | _PORT_VIRT_FLAG, + crp_pktsendflow, + QIBPORTCNTR_WORDSEND | _PORT_VIRT_FLAG, + QIBPORTCNTR_PKTRCV | _PORT_VIRT_FLAG, + crp_pktrcvflowctrl, + QIBPORTCNTR_WORDRCV | _PORT_VIRT_FLAG, + QIBPORTCNTR_SENDSTALL | _PORT_VIRT_FLAG, + crp_txsdmadesc | _PORT_64BIT_FLAG, + crp_rxdlidfltr, + crp_ibstatuschange, + QIBPORTCNTR_IBLINKDOWN | _PORT_VIRT_FLAG, + QIBPORTCNTR_IBLINKERRRECOV | _PORT_VIRT_FLAG, + QIBPORTCNTR_ERRLINK | _PORT_VIRT_FLAG, + QIBPORTCNTR_IBSYMBOLERR | _PORT_VIRT_FLAG, + QIBPORTCNTR_LLI | _PORT_VIRT_FLAG, + QIBPORTCNTR_BADFORMAT | _PORT_VIRT_FLAG, + QIBPORTCNTR_ERR_RLEN | _PORT_VIRT_FLAG, + QIBPORTCNTR_RCVOVFL | _PORT_VIRT_FLAG, + QIBPORTCNTR_RCVEBP | _PORT_VIRT_FLAG, + crp_rcvflowctrlviol, + QIBPORTCNTR_ERRICRC | _PORT_VIRT_FLAG, + QIBPORTCNTR_ERRLPCRC | _PORT_VIRT_FLAG, + QIBPORTCNTR_ERRVCRC | _PORT_VIRT_FLAG, + QIBPORTCNTR_INVALIDRLEN | _PORT_VIRT_FLAG, + QIBPORTCNTR_ERRPKEY | _PORT_VIRT_FLAG, + QIBPORTCNTR_RXDROPPKT | _PORT_VIRT_FLAG, + crp_txminmaxlenerr, + crp_txdroppedpkt, + crp_txlenerr, + crp_txunderrun, + crp_txunsupvl, + QIBPORTCNTR_RXLOCALPHYERR | _PORT_VIRT_FLAG, + QIBPORTCNTR_VL15PKTDROP | _PORT_VIRT_FLAG, + QIBPORTCNTR_RXVLERR | _PORT_VIRT_FLAG, + QIBPORTCNTR_EXCESSBUFOVFL | _PORT_VIRT_FLAG, + crp_rxqpinvalidctxt, + crp_txhdrerr, +}; + +/* do all the setup to make the counter reads efficient later */ +static void init_7322_cntrnames(struct qib_devdata *dd) +{ + int i, j = 0; + char *s; + + for (i = 0, s = (char *)cntr7322names; s && j <= dd->cfgctxts; + i++) { + /* we always have at least one counter before the egrovfl */ + if (!j && !strncmp("Ctxt0EgrOvfl", s + 1, 12)) + j = 1; + s = strchr(s + 1, '\n'); + if (s && j) + j++; + } + dd->cspec->ncntrs = i; + if (!s) + /* full list; size is without terminating null */ + dd->cspec->cntrnamelen = sizeof(cntr7322names) - 1; + else + dd->cspec->cntrnamelen = 1 + s - cntr7322names; + dd->cspec->cntrs = kmalloc(dd->cspec->ncntrs + * sizeof(u64), GFP_KERNEL); + if (!dd->cspec->cntrs) + qib_dev_err(dd, "Failed allocation for counters\n"); + + for (i = 0, s = (char *)portcntr7322names; s; i++) + s = strchr(s + 1, '\n'); + dd->cspec->nportcntrs = i - 1; + dd->cspec->portcntrnamelen = sizeof(portcntr7322names) - 1; + for (i = 0; i < dd->num_pports; ++i) { + dd->pport[i].cpspec->portcntrs = kmalloc(dd->cspec->nportcntrs + * sizeof(u64), GFP_KERNEL); + if (!dd->pport[i].cpspec->portcntrs) + qib_dev_err(dd, "Failed allocation for" + " portcounters\n"); + } +} + +static u32 qib_read_7322cntrs(struct qib_devdata *dd, loff_t pos, char **namep, + u64 **cntrp) +{ + u32 ret; + + if (namep) { + ret = dd->cspec->cntrnamelen; + if (pos >= ret) + ret = 0; /* final read after getting everything */ + else + *namep = (char *) cntr7322names; + } else { + u64 *cntr = dd->cspec->cntrs; + int i; + + ret = dd->cspec->ncntrs * sizeof(u64); + if (!cntr || pos >= ret) { + /* everything read, or couldn't get memory */ + ret = 0; + goto done; + } + *cntrp = cntr; + for (i = 0; i < dd->cspec->ncntrs; i++) + if (cntr7322indices[i] & _PORT_64BIT_FLAG) + *cntr++ = read_7322_creg(dd, + cntr7322indices[i] & + _PORT_CNTR_IDXMASK); + else + *cntr++ = read_7322_creg32(dd, + cntr7322indices[i]); + } +done: + return ret; +} + +static u32 qib_read_7322portcntrs(struct qib_devdata *dd, loff_t pos, u32 port, + char **namep, u64 **cntrp) +{ + u32 ret; + + if (namep) { + ret = dd->cspec->portcntrnamelen; + if (pos >= ret) + ret = 0; /* final read after getting everything */ + else + *namep = (char *)portcntr7322names; + } else { + struct qib_pportdata *ppd = &dd->pport[port]; + u64 *cntr = ppd->cpspec->portcntrs; + int i; + + ret = dd->cspec->nportcntrs * sizeof(u64); + if (!cntr || pos >= ret) { + /* everything read, or couldn't get memory */ + ret = 0; + goto done; + } + *cntrp = cntr; + for (i = 0; i < dd->cspec->nportcntrs; i++) { + if (portcntr7322indices[i] & _PORT_VIRT_FLAG) + *cntr++ = qib_portcntr_7322(ppd, + portcntr7322indices[i] & + _PORT_CNTR_IDXMASK); + else if (portcntr7322indices[i] & _PORT_64BIT_FLAG) + *cntr++ = read_7322_creg_port(ppd, + portcntr7322indices[i] & + _PORT_CNTR_IDXMASK); + else + *cntr++ = read_7322_creg32_port(ppd, + portcntr7322indices[i]); + } + } +done: + return ret; +} + +/** + * qib_get_7322_faststats - get word counters from chip before they overflow + * @opaque - contains a pointer to the qlogic_ib device qib_devdata + * + * VESTIGIAL IBA7322 has no "small fast counters", so the only + * real purpose of this function is to maintain the notion of + * "active time", which in turn is only logged into the eeprom, + * which we don;t have, yet, for 7322-based boards. + * + * called from add_timer + */ +static void qib_get_7322_faststats(unsigned long opaque) +{ + struct qib_devdata *dd = (struct qib_devdata *) opaque; + struct qib_pportdata *ppd; + unsigned long flags; + u64 traffic_wds; + int pidx; + + for (pidx = 0; pidx < dd->num_pports; ++pidx) { + ppd = dd->pport + pidx; + + /* + * If port isn't enabled or not operational ports, or + * diags is running (can cause memory diags to fail) + * skip this port this time. + */ + if (!ppd->link_speed_supported || !(dd->flags & QIB_INITTED) + || dd->diag_client) + continue; + + /* + * Maintain an activity timer, based on traffic + * exceeding a threshold, so we need to check the word-counts + * even if they are 64-bit. + */ + traffic_wds = qib_portcntr_7322(ppd, QIBPORTCNTR_WORDRCV) + + qib_portcntr_7322(ppd, QIBPORTCNTR_WORDSEND); + spin_lock_irqsave(&ppd->dd->eep_st_lock, flags); + traffic_wds -= ppd->dd->traffic_wds; + ppd->dd->traffic_wds += traffic_wds; + if (traffic_wds >= QIB_TRAFFIC_ACTIVE_THRESHOLD) + atomic_add(ACTIVITY_TIMER, &ppd->dd->active_time); + spin_unlock_irqrestore(&ppd->dd->eep_st_lock, flags); + if (ppd->cpspec->qdr_dfe_on && (ppd->link_speed_active & + QIB_IB_QDR) && + (ppd->lflags & (QIBL_LINKINIT | QIBL_LINKARMED | + QIBL_LINKACTIVE)) && + ppd->cpspec->qdr_dfe_time && + time_after64(get_jiffies_64(), ppd->cpspec->qdr_dfe_time)) { + ppd->cpspec->qdr_dfe_on = 0; + + qib_write_kreg_port(ppd, krp_static_adapt_dis(2), + ppd->dd->cspec->r1 ? + QDR_STATIC_ADAPT_INIT_R1 : + QDR_STATIC_ADAPT_INIT); + force_h1(ppd); + } + } + mod_timer(&dd->stats_timer, jiffies + HZ * ACTIVITY_TIMER); +} + +/* + * If we were using MSIx, try to fallback to INTx. + */ +static int qib_7322_intr_fallback(struct qib_devdata *dd) +{ + if (!dd->cspec->num_msix_entries) + return 0; /* already using INTx */ + + qib_devinfo(dd->pcidev, "MSIx interrupt not detected," + " trying INTx interrupts\n"); + qib_7322_nomsix(dd); + qib_enable_intx(dd->pcidev); + qib_setup_7322_interrupt(dd, 0); + return 1; +} + +/* + * Reset the XGXS (between serdes and IBC). Slightly less intrusive + * than resetting the IBC or external link state, and useful in some + * cases to cause some retraining. To do this right, we reset IBC + * as well, then return to previous state (which may be still in reset) + * NOTE: some callers of this "know" this writes the current value + * of cpspec->ibcctrl_a as part of it's operation, so if that changes, + * check all callers. + */ +static void qib_7322_mini_pcs_reset(struct qib_pportdata *ppd) +{ + u64 val; + struct qib_devdata *dd = ppd->dd; + const u64 reset_bits = SYM_MASK(IBPCSConfig_0, xcv_rreset) | + SYM_MASK(IBPCSConfig_0, xcv_treset) | + SYM_MASK(IBPCSConfig_0, tx_rx_reset); + + val = qib_read_kreg_port(ppd, krp_ib_pcsconfig); + qib_write_kreg_port(ppd, krp_ibcctrl_a, + ppd->cpspec->ibcctrl_a & + ~SYM_MASK(IBCCtrlA_0, IBLinkEn)); + + qib_write_kreg_port(ppd, krp_ib_pcsconfig, val | reset_bits); + qib_read_kreg32(dd, kr_scratch); + qib_write_kreg_port(ppd, krp_ib_pcsconfig, val & ~reset_bits); + qib_write_kreg_port(ppd, krp_ibcctrl_a, ppd->cpspec->ibcctrl_a); + qib_write_kreg(dd, kr_scratch, 0ULL); +} + +/* + * This code for non-IBTA-compliant IB speed negotiation is only known to + * work for the SDR to DDR transition, and only between an HCA and a switch + * with recent firmware. It is based on observed heuristics, rather than + * actual knowledge of the non-compliant speed negotiation. + * It has a number of hard-coded fields, since the hope is to rewrite this + * when a spec is available on how the negoation is intended to work. + */ +static void autoneg_7322_sendpkt(struct qib_pportdata *ppd, u32 *hdr, + u32 dcnt, u32 *data) +{ + int i; + u64 pbc; + u32 __iomem *piobuf; + u32 pnum, control, len; + struct qib_devdata *dd = ppd->dd; + + i = 0; + len = 7 + dcnt + 1; /* 7 dword header, dword data, icrc */ + control = qib_7322_setpbc_control(ppd, len, 0, 15); + pbc = ((u64) control << 32) | len; + while (!(piobuf = qib_7322_getsendbuf(ppd, pbc, &pnum))) { + if (i++ > 15) + return; + udelay(2); + } + /* disable header check on this packet, since it can't be valid */ + dd->f_txchk_change(dd, pnum, 1, TXCHK_CHG_TYPE_DIS1, NULL); + writeq(pbc, piobuf); + qib_flush_wc(); + qib_pio_copy(piobuf + 2, hdr, 7); + qib_pio_copy(piobuf + 9, data, dcnt); + if (dd->flags & QIB_USE_SPCL_TRIG) { + u32 spcl_off = (pnum >= dd->piobcnt2k) ? 2047 : 1023; + + qib_flush_wc(); + __raw_writel(0xaebecede, piobuf + spcl_off); + } + qib_flush_wc(); + qib_sendbuf_done(dd, pnum); + /* and re-enable hdr check */ + dd->f_txchk_change(dd, pnum, 1, TXCHK_CHG_TYPE_ENAB1, NULL); +} + +/* + * _start packet gets sent twice at start, _done gets sent twice at end + */ +static void qib_autoneg_7322_send(struct qib_pportdata *ppd, int which) +{ + struct qib_devdata *dd = ppd->dd; + static u32 swapped; + u32 dw, i, hcnt, dcnt, *data; + static u32 hdr[7] = { 0xf002ffff, 0x48ffff, 0x6400abba }; + static u32 madpayload_start[0x40] = { + 0x1810103, 0x1, 0x0, 0x0, 0x2c90000, 0x2c9, 0x0, 0x0, + 0xffffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x1388, 0x15e, 0x1, /* rest 0's */ + }; + static u32 madpayload_done[0x40] = { + 0x1810103, 0x1, 0x0, 0x0, 0x2c90000, 0x2c9, 0x0, 0x0, + 0xffffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x40000001, 0x1388, 0x15e, /* rest 0's */ + }; + + dcnt = ARRAY_SIZE(madpayload_start); + hcnt = ARRAY_SIZE(hdr); + if (!swapped) { + /* for maintainability, do it at runtime */ + for (i = 0; i < hcnt; i++) { + dw = (__force u32) cpu_to_be32(hdr[i]); + hdr[i] = dw; + } + for (i = 0; i < dcnt; i++) { + dw = (__force u32) cpu_to_be32(madpayload_start[i]); + madpayload_start[i] = dw; + dw = (__force u32) cpu_to_be32(madpayload_done[i]); + madpayload_done[i] = dw; + } + swapped = 1; + } + + data = which ? madpayload_done : madpayload_start; + + autoneg_7322_sendpkt(ppd, hdr, dcnt, data); + qib_read_kreg64(dd, kr_scratch); + udelay(2); + autoneg_7322_sendpkt(ppd, hdr, dcnt, data); + qib_read_kreg64(dd, kr_scratch); + udelay(2); +} + +/* + * Do the absolute minimum to cause an IB speed change, and make it + * ready, but don't actually trigger the change. The caller will + * do that when ready (if link is in Polling training state, it will + * happen immediately, otherwise when link next goes down) + * + * This routine should only be used as part of the DDR autonegotation + * code for devices that are not compliant with IB 1.2 (or code that + * fixes things up for same). + * + * When link has gone down, and autoneg enabled, or autoneg has + * failed and we give up until next time we set both speeds, and + * then we want IBTA enabled as well as "use max enabled speed. + */ +static void set_7322_ibspeed_fast(struct qib_pportdata *ppd, u32 speed) +{ + u64 newctrlb; + newctrlb = ppd->cpspec->ibcctrl_b & ~(IBA7322_IBC_SPEED_MASK | + IBA7322_IBC_IBTA_1_2_MASK | + IBA7322_IBC_MAX_SPEED_MASK); + + if (speed & (speed - 1)) /* multiple speeds */ + newctrlb |= (speed << IBA7322_IBC_SPEED_LSB) | + IBA7322_IBC_IBTA_1_2_MASK | + IBA7322_IBC_MAX_SPEED_MASK; + else + newctrlb |= speed == QIB_IB_QDR ? + IBA7322_IBC_SPEED_QDR | IBA7322_IBC_IBTA_1_2_MASK : + ((speed == QIB_IB_DDR ? + IBA7322_IBC_SPEED_DDR : IBA7322_IBC_SPEED_SDR)); + + if (newctrlb == ppd->cpspec->ibcctrl_b) + return; + + ppd->cpspec->ibcctrl_b = newctrlb; + qib_write_kreg_port(ppd, krp_ibcctrl_b, ppd->cpspec->ibcctrl_b); + qib_write_kreg(ppd->dd, kr_scratch, 0); +} + +/* + * This routine is only used when we are not talking to another + * IB 1.2-compliant device that we think can do DDR. + * (This includes all existing switch chips as of Oct 2007.) + * 1.2-compliant devices go directly to DDR prior to reaching INIT + */ +static void try_7322_autoneg(struct qib_pportdata *ppd) +{ + unsigned long flags; + + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags |= QIBL_IB_AUTONEG_INPROG; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + qib_autoneg_7322_send(ppd, 0); + set_7322_ibspeed_fast(ppd, QIB_IB_DDR); + qib_7322_mini_pcs_reset(ppd); + /* 2 msec is minimum length of a poll cycle */ + schedule_delayed_work(&ppd->cpspec->autoneg_work, + msecs_to_jiffies(2)); +} + +/* + * Handle the empirically determined mechanism for auto-negotiation + * of DDR speed with switches. + */ +static void autoneg_7322_work(struct work_struct *work) +{ + struct qib_pportdata *ppd; + struct qib_devdata *dd; + u64 startms; + u32 i; + unsigned long flags; + + ppd = container_of(work, struct qib_chippport_specific, + autoneg_work.work)->ppd; + dd = ppd->dd; + + startms = jiffies_to_msecs(jiffies); + + /* + * Busy wait for this first part, it should be at most a + * few hundred usec, since we scheduled ourselves for 2msec. + */ + for (i = 0; i < 25; i++) { + if (SYM_FIELD(ppd->lastibcstat, IBCStatusA_0, LinkState) + == IB_7322_LT_STATE_POLLQUIET) { + qib_set_linkstate(ppd, QIB_IB_LINKDOWN_DISABLE); + break; + } + udelay(100); + } + + if (!(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) + goto done; /* we got there early or told to stop */ + + /* we expect this to timeout */ + if (wait_event_timeout(ppd->cpspec->autoneg_wait, + !(ppd->lflags & QIBL_IB_AUTONEG_INPROG), + msecs_to_jiffies(90))) + goto done; + qib_7322_mini_pcs_reset(ppd); + + /* we expect this to timeout */ + if (wait_event_timeout(ppd->cpspec->autoneg_wait, + !(ppd->lflags & QIBL_IB_AUTONEG_INPROG), + msecs_to_jiffies(1700))) + goto done; + qib_7322_mini_pcs_reset(ppd); + + set_7322_ibspeed_fast(ppd, QIB_IB_SDR); + + /* + * Wait up to 250 msec for link to train and get to INIT at DDR; + * this should terminate early. + */ + wait_event_timeout(ppd->cpspec->autoneg_wait, + !(ppd->lflags & QIBL_IB_AUTONEG_INPROG), + msecs_to_jiffies(250)); +done: + if (ppd->lflags & QIBL_IB_AUTONEG_INPROG) { + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags &= ~QIBL_IB_AUTONEG_INPROG; + if (ppd->cpspec->autoneg_tries == AUTONEG_TRIES) { + ppd->lflags |= QIBL_IB_AUTONEG_FAILED; + ppd->cpspec->autoneg_tries = 0; + } + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + set_7322_ibspeed_fast(ppd, ppd->link_speed_enabled); + } +} + +/* + * This routine is used to request IPG set in the QLogic switch. + * Only called if r1. + */ +static void try_7322_ipg(struct qib_pportdata *ppd) +{ + struct qib_ibport *ibp = &ppd->ibport_data; + struct ib_mad_send_buf *send_buf; + struct ib_mad_agent *agent; + struct ib_smp *smp; + unsigned delay; + int ret; + + agent = ibp->send_agent; + if (!agent) + goto retry; + + send_buf = ib_create_send_mad(agent, 0, 0, 0, IB_MGMT_MAD_HDR, + IB_MGMT_MAD_DATA, GFP_ATOMIC); + if (IS_ERR(send_buf)) + goto retry; + + if (!ibp->smi_ah) { + struct ib_ah_attr attr; + struct ib_ah *ah; + + memset(&attr, 0, sizeof attr); + attr.dlid = be16_to_cpu(IB_LID_PERMISSIVE); + attr.port_num = ppd->port; + ah = ib_create_ah(ibp->qp0->ibqp.pd, &attr); + if (IS_ERR(ah)) + ret = -EINVAL; + else { + send_buf->ah = ah; + ibp->smi_ah = to_iah(ah); + ret = 0; + } + } else { + send_buf->ah = &ibp->smi_ah->ibah; + ret = 0; + } + + smp = send_buf->mad; + smp->base_version = IB_MGMT_BASE_VERSION; + smp->mgmt_class = IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE; + smp->class_version = 1; + smp->method = IB_MGMT_METHOD_SEND; + smp->hop_cnt = 1; + smp->attr_id = QIB_VENDOR_IPG; + smp->attr_mod = 0; + + if (!ret) + ret = ib_post_send_mad(send_buf, NULL); + if (ret) + ib_free_send_mad(send_buf); +retry: + delay = 2 << ppd->cpspec->ipg_tries; + schedule_delayed_work(&ppd->cpspec->ipg_work, msecs_to_jiffies(delay)); +} + +/* + * Timeout handler for setting IPG. + * Only called if r1. + */ +static void ipg_7322_work(struct work_struct *work) +{ + struct qib_pportdata *ppd; + + ppd = container_of(work, struct qib_chippport_specific, + ipg_work.work)->ppd; + if ((ppd->lflags & (QIBL_LINKINIT | QIBL_LINKARMED | QIBL_LINKACTIVE)) + && ++ppd->cpspec->ipg_tries <= 10) + try_7322_ipg(ppd); +} + +static u32 qib_7322_iblink_state(u64 ibcs) +{ + u32 state = (u32)SYM_FIELD(ibcs, IBCStatusA_0, LinkState); + + switch (state) { + case IB_7322_L_STATE_INIT: + state = IB_PORT_INIT; + break; + case IB_7322_L_STATE_ARM: + state = IB_PORT_ARMED; + break; + case IB_7322_L_STATE_ACTIVE: + /* fall through */ + case IB_7322_L_STATE_ACT_DEFER: + state = IB_PORT_ACTIVE; + break; + default: /* fall through */ + case IB_7322_L_STATE_DOWN: + state = IB_PORT_DOWN; + break; + } + return state; +} + +/* returns the IBTA port state, rather than the IBC link training state */ +static u8 qib_7322_phys_portstate(u64 ibcs) +{ + u8 state = (u8)SYM_FIELD(ibcs, IBCStatusA_0, LinkTrainingState); + return qib_7322_physportstate[state]; +} + +static int qib_7322_ib_updown(struct qib_pportdata *ppd, int ibup, u64 ibcs) +{ + int ret = 0, symadj = 0; + unsigned long flags; + int mult; + + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags &= ~QIBL_IB_FORCE_NOTIFY; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + + /* Update our picture of width and speed from chip */ + if (ibcs & SYM_MASK(IBCStatusA_0, LinkSpeedQDR)) { + ppd->link_speed_active = QIB_IB_QDR; + mult = 4; + } else if (ibcs & SYM_MASK(IBCStatusA_0, LinkSpeedActive)) { + ppd->link_speed_active = QIB_IB_DDR; + mult = 2; + } else { + ppd->link_speed_active = QIB_IB_SDR; + mult = 1; + } + if (ibcs & SYM_MASK(IBCStatusA_0, LinkWidthActive)) { + ppd->link_width_active = IB_WIDTH_4X; + mult *= 4; + } else + ppd->link_width_active = IB_WIDTH_1X; + ppd->delay_mult = ib_rate_to_delay[mult_to_ib_rate(mult)]; + + if (!ibup) { + u64 clr; + + /* Link went down. */ + /* do IPG MAD again after linkdown, even if last time failed */ + ppd->cpspec->ipg_tries = 0; + clr = qib_read_kreg_port(ppd, krp_ibcstatus_b) & + (SYM_MASK(IBCStatusB_0, heartbeat_timed_out) | + SYM_MASK(IBCStatusB_0, heartbeat_crosstalk)); + if (clr) + qib_write_kreg_port(ppd, krp_ibcstatus_b, clr); + if (!(ppd->lflags & (QIBL_IB_AUTONEG_FAILED | + QIBL_IB_AUTONEG_INPROG))) + set_7322_ibspeed_fast(ppd, ppd->link_speed_enabled); + if (!(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) { + qib_cancel_sends(ppd); + spin_lock_irqsave(&ppd->sdma_lock, flags); + if (__qib_sdma_running(ppd)) + __qib_sdma_process_event(ppd, + qib_sdma_event_e70_go_idle); + spin_unlock_irqrestore(&ppd->sdma_lock, flags); + } + clr = read_7322_creg32_port(ppd, crp_iblinkdown); + if (clr == ppd->cpspec->iblnkdownsnap) + ppd->cpspec->iblnkdowndelta++; + } else { + if (qib_compat_ddr_negotiate && + !(ppd->lflags & (QIBL_IB_AUTONEG_FAILED | + QIBL_IB_AUTONEG_INPROG)) && + ppd->link_speed_active == QIB_IB_SDR && + (ppd->link_speed_enabled & QIB_IB_DDR) + && ppd->cpspec->autoneg_tries < AUTONEG_TRIES) { + /* we are SDR, and auto-negotiation enabled */ + ++ppd->cpspec->autoneg_tries; + if (!ppd->cpspec->ibdeltainprog) { + ppd->cpspec->ibdeltainprog = 1; + ppd->cpspec->ibsymdelta += + read_7322_creg32_port(ppd, + crp_ibsymbolerr) - + ppd->cpspec->ibsymsnap; + ppd->cpspec->iblnkerrdelta += + read_7322_creg32_port(ppd, + crp_iblinkerrrecov) - + ppd->cpspec->iblnkerrsnap; + } + try_7322_autoneg(ppd); + ret = 1; /* no other IB status change processing */ + } else if ((ppd->lflags & QIBL_IB_AUTONEG_INPROG) && + ppd->link_speed_active == QIB_IB_SDR) { + qib_autoneg_7322_send(ppd, 1); + set_7322_ibspeed_fast(ppd, QIB_IB_DDR); + qib_7322_mini_pcs_reset(ppd); + udelay(2); + ret = 1; /* no other IB status change processing */ + } else if ((ppd->lflags & QIBL_IB_AUTONEG_INPROG) && + (ppd->link_speed_active & QIB_IB_DDR)) { + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags &= ~(QIBL_IB_AUTONEG_INPROG | + QIBL_IB_AUTONEG_FAILED); + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + ppd->cpspec->autoneg_tries = 0; + /* re-enable SDR, for next link down */ + set_7322_ibspeed_fast(ppd, ppd->link_speed_enabled); + wake_up(&ppd->cpspec->autoneg_wait); + symadj = 1; + } else if (ppd->lflags & QIBL_IB_AUTONEG_FAILED) { + /* + * Clear autoneg failure flag, and do setup + * so we'll try next time link goes down and + * back to INIT (possibly connected to a + * different device). + */ + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags &= ~QIBL_IB_AUTONEG_FAILED; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + ppd->cpspec->ibcctrl_b |= IBA7322_IBC_IBTA_1_2_MASK; + symadj = 1; + } + if (!(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) { + symadj = 1; + if (ppd->dd->cspec->r1 && ppd->cpspec->ipg_tries <= 10) + try_7322_ipg(ppd); + if (!ppd->cpspec->recovery_init) + setup_7322_link_recovery(ppd, 0); + ppd->cpspec->qdr_dfe_time = jiffies + + msecs_to_jiffies(QDR_DFE_DISABLE_DELAY); + } + ppd->cpspec->ibmalfusesnap = 0; + ppd->cpspec->ibmalfsnap = read_7322_creg32_port(ppd, + crp_errlink); + } + if (symadj) { + ppd->cpspec->iblnkdownsnap = + read_7322_creg32_port(ppd, crp_iblinkdown); + if (ppd->cpspec->ibdeltainprog) { + ppd->cpspec->ibdeltainprog = 0; + ppd->cpspec->ibsymdelta += read_7322_creg32_port(ppd, + crp_ibsymbolerr) - ppd->cpspec->ibsymsnap; + ppd->cpspec->iblnkerrdelta += read_7322_creg32_port(ppd, + crp_iblinkerrrecov) - ppd->cpspec->iblnkerrsnap; + } + } else if (!ibup && qib_compat_ddr_negotiate && + !ppd->cpspec->ibdeltainprog && + !(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) { + ppd->cpspec->ibdeltainprog = 1; + ppd->cpspec->ibsymsnap = read_7322_creg32_port(ppd, + crp_ibsymbolerr); + ppd->cpspec->iblnkerrsnap = read_7322_creg32_port(ppd, + crp_iblinkerrrecov); + } + + if (!ret) + qib_setup_7322_setextled(ppd, ibup); + return ret; +} + +/* + * Does read/modify/write to appropriate registers to + * set output and direction bits selected by mask. + * these are in their canonical postions (e.g. lsb of + * dir will end up in D48 of extctrl on existing chips). + * returns contents of GP Inputs. + */ +static int gpio_7322_mod(struct qib_devdata *dd, u32 out, u32 dir, u32 mask) +{ + u64 read_val, new_out; + unsigned long flags; + + if (mask) { + /* some bits being written, lock access to GPIO */ + dir &= mask; + out &= mask; + spin_lock_irqsave(&dd->cspec->gpio_lock, flags); + dd->cspec->extctrl &= ~((u64)mask << SYM_LSB(EXTCtrl, GPIOOe)); + dd->cspec->extctrl |= ((u64) dir << SYM_LSB(EXTCtrl, GPIOOe)); + new_out = (dd->cspec->gpio_out & ~mask) | out; + + qib_write_kreg(dd, kr_extctrl, dd->cspec->extctrl); + qib_write_kreg(dd, kr_gpio_out, new_out); + dd->cspec->gpio_out = new_out; + spin_unlock_irqrestore(&dd->cspec->gpio_lock, flags); + } + /* + * It is unlikely that a read at this time would get valid + * data on a pin whose direction line was set in the same + * call to this function. We include the read here because + * that allows us to potentially combine a change on one pin with + * a read on another, and because the old code did something like + * this. + */ + read_val = qib_read_kreg64(dd, kr_extstatus); + return SYM_FIELD(read_val, EXTStatus, GPIOIn); +} + +/* Enable writes to config EEPROM, if possible. Returns previous state */ +static int qib_7322_eeprom_wen(struct qib_devdata *dd, int wen) +{ + int prev_wen; + u32 mask; + + mask = 1 << QIB_EEPROM_WEN_NUM; + prev_wen = ~gpio_7322_mod(dd, 0, 0, 0) >> QIB_EEPROM_WEN_NUM; + gpio_7322_mod(dd, wen ? 0 : mask, mask, mask); + + return prev_wen & 1; +} + +/* + * Read fundamental info we need to use the chip. These are + * the registers that describe chip capabilities, and are + * saved in shadow registers. + */ +static void get_7322_chip_params(struct qib_devdata *dd) +{ + u64 val; + u32 piobufs; + int mtu; + + dd->palign = qib_read_kreg32(dd, kr_pagealign); + + dd->uregbase = qib_read_kreg32(dd, kr_userregbase); + + dd->rcvtidcnt = qib_read_kreg32(dd, kr_rcvtidcnt); + dd->rcvtidbase = qib_read_kreg32(dd, kr_rcvtidbase); + dd->rcvegrbase = qib_read_kreg32(dd, kr_rcvegrbase); + dd->piobufbase = qib_read_kreg64(dd, kr_sendpiobufbase); + dd->pio2k_bufbase = dd->piobufbase & 0xffffffff; + + val = qib_read_kreg64(dd, kr_sendpiobufcnt); + dd->piobcnt2k = val & ~0U; + dd->piobcnt4k = val >> 32; + val = qib_read_kreg64(dd, kr_sendpiosize); + dd->piosize2k = val & ~0U; + dd->piosize4k = val >> 32; + + mtu = ib_mtu_enum_to_int(qib_ibmtu); + if (mtu == -1) + mtu = QIB_DEFAULT_MTU; + dd->pport[0].ibmtu = (u32)mtu; + dd->pport[1].ibmtu = (u32)mtu; + + /* these may be adjusted in init_chip_wc_pat() */ + dd->pio2kbase = (u32 __iomem *) + ((char __iomem *) dd->kregbase + dd->pio2k_bufbase); + dd->pio4kbase = (u32 __iomem *) + ((char __iomem *) dd->kregbase + + (dd->piobufbase >> 32)); + /* + * 4K buffers take 2 pages; we use roundup just to be + * paranoid; we calculate it once here, rather than on + * ever buf allocate + */ + dd->align4k = ALIGN(dd->piosize4k, dd->palign); + + piobufs = dd->piobcnt4k + dd->piobcnt2k + NUM_VL15_BUFS; + + dd->pioavregs = ALIGN(piobufs, sizeof(u64) * BITS_PER_BYTE / 2) / + (sizeof(u64) * BITS_PER_BYTE / 2); +} + +/* + * The chip base addresses in cspec and cpspec have to be set + * after possible init_chip_wc_pat(), rather than in + * get_7322_chip_params(), so split out as separate function + */ +static void qib_7322_set_baseaddrs(struct qib_devdata *dd) +{ + u32 cregbase; + cregbase = qib_read_kreg32(dd, kr_counterregbase); + + dd->cspec->cregbase = (u64 __iomem *)(cregbase + + (char __iomem *)dd->kregbase); + + dd->egrtidbase = (u64 __iomem *) + ((char __iomem *) dd->kregbase + dd->rcvegrbase); + + /* port registers are defined as relative to base of chip */ + dd->pport[0].cpspec->kpregbase = + (u64 __iomem *)((char __iomem *)dd->kregbase); + dd->pport[1].cpspec->kpregbase = + (u64 __iomem *)(dd->palign + + (char __iomem *)dd->kregbase); + dd->pport[0].cpspec->cpregbase = + (u64 __iomem *)(qib_read_kreg_port(&dd->pport[0], + kr_counterregbase) + (char __iomem *)dd->kregbase); + dd->pport[1].cpspec->cpregbase = + (u64 __iomem *)(qib_read_kreg_port(&dd->pport[1], + kr_counterregbase) + (char __iomem *)dd->kregbase); +} + +/* + * This is a fairly special-purpose observer, so we only support + * the port-specific parts of SendCtrl + */ + +#define SENDCTRL_SHADOWED (SYM_MASK(SendCtrl_0, SendEnable) | \ + SYM_MASK(SendCtrl_0, SDmaEnable) | \ + SYM_MASK(SendCtrl_0, SDmaIntEnable) | \ + SYM_MASK(SendCtrl_0, SDmaSingleDescriptor) | \ + SYM_MASK(SendCtrl_0, SDmaHalt) | \ + SYM_MASK(SendCtrl_0, IBVLArbiterEn) | \ + SYM_MASK(SendCtrl_0, ForceCreditUpToDate)) + +static int sendctrl_hook(struct qib_devdata *dd, + const struct diag_observer *op, u32 offs, + u64 *data, u64 mask, int only_32) +{ + unsigned long flags; + unsigned idx; + unsigned pidx; + struct qib_pportdata *ppd = NULL; + u64 local_data, all_bits; + + /* + * The fixed correspondence between Physical ports and pports is + * severed. We need to hunt for the ppd that corresponds + * to the offset we got. And we have to do that without admitting + * we know the stride, apparently. + */ + for (pidx = 0; pidx < dd->num_pports; ++pidx) { + u64 __iomem *psptr; + u32 psoffs; + + ppd = dd->pport + pidx; + if (!ppd->cpspec->kpregbase) + continue; + + psptr = ppd->cpspec->kpregbase + krp_sendctrl; + psoffs = (u32) (psptr - dd->kregbase) * sizeof(*psptr); + if (psoffs == offs) + break; + } + + /* If pport is not being managed by driver, just avoid shadows. */ + if (pidx >= dd->num_pports) + ppd = NULL; + + /* In any case, "idx" is flat index in kreg space */ + idx = offs / sizeof(u64); + + all_bits = ~0ULL; + if (only_32) + all_bits >>= 32; + + spin_lock_irqsave(&dd->sendctrl_lock, flags); + if (!ppd || (mask & all_bits) != all_bits) { + /* + * At least some mask bits are zero, so we need + * to read. The judgement call is whether from + * reg or shadow. First-cut: read reg, and complain + * if any bits which should be shadowed are different + * from their shadowed value. + */ + if (only_32) + local_data = (u64)qib_read_kreg32(dd, idx); + else + local_data = qib_read_kreg64(dd, idx); + *data = (local_data & ~mask) | (*data & mask); + } + if (mask) { + /* + * At least some mask bits are one, so we need + * to write, but only shadow some bits. + */ + u64 sval, tval; /* Shadowed, transient */ + + /* + * New shadow val is bits we don't want to touch, + * ORed with bits we do, that are intended for shadow. + */ + if (ppd) { + sval = ppd->p_sendctrl & ~mask; + sval |= *data & SENDCTRL_SHADOWED & mask; + ppd->p_sendctrl = sval; + } else + sval = *data & SENDCTRL_SHADOWED & mask; + tval = sval | (*data & ~SENDCTRL_SHADOWED & mask); + qib_write_kreg(dd, idx, tval); + qib_write_kreg(dd, kr_scratch, 0Ull); + } + spin_unlock_irqrestore(&dd->sendctrl_lock, flags); + return only_32 ? 4 : 8; +} + +static const struct diag_observer sendctrl_0_observer = { + sendctrl_hook, KREG_IDX(SendCtrl_0) * sizeof(u64), + KREG_IDX(SendCtrl_0) * sizeof(u64) +}; + +static const struct diag_observer sendctrl_1_observer = { + sendctrl_hook, KREG_IDX(SendCtrl_1) * sizeof(u64), + KREG_IDX(SendCtrl_1) * sizeof(u64) +}; + +static ushort sdma_fetch_prio = 8; +module_param_named(sdma_fetch_prio, sdma_fetch_prio, ushort, S_IRUGO); +MODULE_PARM_DESC(sdma_fetch_prio, "SDMA descriptor fetch priority"); + +/* Besides logging QSFP events, we set appropriate TxDDS values */ +static void init_txdds_table(struct qib_pportdata *ppd, int override); + +static void qsfp_7322_event(struct work_struct *work) +{ + struct qib_qsfp_data *qd; + struct qib_pportdata *ppd; + u64 pwrup; + int ret; + u32 le2; + + qd = container_of(work, struct qib_qsfp_data, work); + ppd = qd->ppd; + pwrup = qd->t_insert + msecs_to_jiffies(QSFP_PWR_LAG_MSEC); + + /* + * Some QSFP's not only do not respond until the full power-up + * time, but may behave badly if we try. So hold off responding + * to insertion. + */ + while (1) { + u64 now = get_jiffies_64(); + if (time_after64(now, pwrup)) + break; + msleep(1); + } + ret = qib_refresh_qsfp_cache(ppd, &qd->cache); + /* + * Need to change LE2 back to defaults if we couldn't + * read the cable type (to handle cable swaps), so do this + * even on failure to read cable information. We don't + * get here for QME, so IS_QME check not needed here. + */ + le2 = (!ret && qd->cache.atten[1] >= qib_long_atten && + !ppd->dd->cspec->r1 && QSFP_IS_CU(qd->cache.tech)) ? + LE2_5m : LE2_DEFAULT; + ibsd_wr_allchans(ppd, 13, (le2 << 7), BMASK(9, 7)); + init_txdds_table(ppd, 0); +} + +/* + * There is little we can do but complain to the user if QSFP + * initialization fails. + */ +static void qib_init_7322_qsfp(struct qib_pportdata *ppd) +{ + unsigned long flags; + struct qib_qsfp_data *qd = &ppd->cpspec->qsfp_data; + struct qib_devdata *dd = ppd->dd; + u64 mod_prs_bit = QSFP_GPIO_MOD_PRS_N; + + mod_prs_bit <<= (QSFP_GPIO_PORT2_SHIFT * ppd->hw_pidx); + qd->ppd = ppd; + qib_qsfp_init(qd, qsfp_7322_event); + spin_lock_irqsave(&dd->cspec->gpio_lock, flags); + dd->cspec->extctrl |= (mod_prs_bit << SYM_LSB(EXTCtrl, GPIOInvert)); + dd->cspec->gpio_mask |= mod_prs_bit; + qib_write_kreg(dd, kr_extctrl, dd->cspec->extctrl); + qib_write_kreg(dd, kr_gpio_mask, dd->cspec->gpio_mask); + spin_unlock_irqrestore(&dd->cspec->gpio_lock, flags); +} + +/* + * called at device initialization time, and also if the cable_atten + * module parameter is changed. This is used for cables that don't + * have valid QSFP EEPROMs (not present, or attenuation is zero). + * We initialize to the default, then if there is a specific + * unit,port match, we use that. + * String format is "default# unit#,port#=# ... u,p=#", separators must + * be a SPACE character. A newline terminates. + * The last specific match is used (actually, all are used, but last + * one is the one that winds up set); if none at all, fall back on default. + */ +static void set_no_qsfp_atten(struct qib_devdata *dd, int change) +{ + char *nxt, *str; + int pidx, unit, port, deflt; + unsigned long val; + int any = 0; + + str = cable_atten_list; + + /* default number is validated in setup_cable_atten() */ + deflt = simple_strtoul(str, &nxt, 0); + for (pidx = 0; pidx < dd->num_pports; ++pidx) + dd->pport[pidx].cpspec->no_eep = deflt; + + while (*nxt && nxt[1]) { + str = ++nxt; + unit = simple_strtoul(str, &nxt, 0); + if (nxt == str || !*nxt || *nxt != ',') { + while (*nxt && *nxt++ != ' ') /* skip to next, if any */ + ; + continue; + } + str = ++nxt; + port = simple_strtoul(str, &nxt, 0); + if (nxt == str || *nxt != '=') { + while (*nxt && *nxt++ != ' ') /* skip to next, if any */ + ; + continue; + } + str = ++nxt; + val = simple_strtoul(str, &nxt, 0); + if (nxt == str) { + while (*nxt && *nxt++ != ' ') /* skip to next, if any */ + ; + continue; + } + if (val >= TXDDS_TABLE_SZ) + continue; + for (pidx = 0; dd->unit == unit && pidx < dd->num_pports; + ++pidx) { + if (dd->pport[pidx].port != port || + !dd->pport[pidx].link_speed_supported) + continue; + dd->pport[pidx].cpspec->no_eep = val; + /* now change the IBC and serdes, overriding generic */ + init_txdds_table(&dd->pport[pidx], 1); + any++; + } + if (*nxt == '\n') + break; /* done */ + } + if (change && !any) { + /* no specific setting, use the default. + * Change the IBC and serdes, but since it's + * general, don't override specific settings. + */ + for (pidx = 0; pidx < dd->num_pports; ++pidx) { + if (!dd->pport[pidx].link_speed_supported) + continue; + init_txdds_table(&dd->pport[pidx], 0); + } + } +} + +/* handle the cable_atten parameter changing */ +static int setup_cable_atten(const char *str, struct kernel_param *kp) +{ + struct qib_devdata *dd; + unsigned long val; + char *n; + if (strlen(str) >= MAX_ATTEN_LEN) { + printk(KERN_INFO QIB_DRV_NAME " cable_atten_values string " + "too long\n"); + return -ENOSPC; + } + val = simple_strtoul(str, &n, 0); + if (n == str || val >= TXDDS_TABLE_SZ) { + printk(KERN_INFO QIB_DRV_NAME + "cable_atten_values must start with a number\n"); + return -EINVAL; + } + strcpy(cable_atten_list, str); + + list_for_each_entry(dd, &qib_dev_list, list) + set_no_qsfp_atten(dd, 1); + return 0; +} + +/* + * Write the final few registers that depend on some of the + * init setup. Done late in init, just before bringing up + * the serdes. + */ +static int qib_late_7322_initreg(struct qib_devdata *dd) +{ + int ret = 0, n; + u64 val; + + qib_write_kreg(dd, kr_rcvhdrentsize, dd->rcvhdrentsize); + qib_write_kreg(dd, kr_rcvhdrsize, dd->rcvhdrsize); + qib_write_kreg(dd, kr_rcvhdrcnt, dd->rcvhdrcnt); + qib_write_kreg(dd, kr_sendpioavailaddr, dd->pioavailregs_phys); + val = qib_read_kreg64(dd, kr_sendpioavailaddr); + if (val != dd->pioavailregs_phys) { + qib_dev_err(dd, "Catastrophic software error, " + "SendPIOAvailAddr written as %lx, " + "read back as %llx\n", + (unsigned long) dd->pioavailregs_phys, + (unsigned long long) val); + ret = -EINVAL; + } + + n = dd->piobcnt2k + dd->piobcnt4k + NUM_VL15_BUFS; + qib_7322_txchk_change(dd, 0, n, TXCHK_CHG_TYPE_KERN, NULL); + /* driver sends get pkey, lid, etc. checking also, to catch bugs */ + qib_7322_txchk_change(dd, 0, n, TXCHK_CHG_TYPE_ENAB1, NULL); + + qib_register_observer(dd, &sendctrl_0_observer); + qib_register_observer(dd, &sendctrl_1_observer); + + dd->control &= ~QLOGIC_IB_C_SDMAFETCHPRIOEN; + qib_write_kreg(dd, kr_control, dd->control); + /* + * Set SendDmaFetchPriority and init Tx params, including + * QSFP handler on boards that have QSFP. + * First set our default attenuation entry for cables that + * don't have valid attenuation. + */ + set_no_qsfp_atten(dd, 0); + for (n = 0; n < dd->num_pports; ++n) { + struct qib_pportdata *ppd = dd->pport + n; + + qib_write_kreg_port(ppd, krp_senddmaprioritythld, + sdma_fetch_prio & 0xf); + /* Initialize qsfp if present on board. */ + if (dd->flags & QIB_HAS_QSFP) + qib_init_7322_qsfp(ppd); + } + dd->control |= QLOGIC_IB_C_SDMAFETCHPRIOEN; + qib_write_kreg(dd, kr_control, dd->control); + + return ret; +} + +/* per IB port errors. */ +#define SENDCTRL_PIBP (MASK_ACROSS(0, 1) | MASK_ACROSS(3, 3) | \ + MASK_ACROSS(8, 15)) +#define RCVCTRL_PIBP (MASK_ACROSS(0, 17) | MASK_ACROSS(39, 41)) +#define ERRS_PIBP (MASK_ACROSS(57, 58) | MASK_ACROSS(54, 54) | \ + MASK_ACROSS(36, 49) | MASK_ACROSS(29, 34) | MASK_ACROSS(14, 17) | \ + MASK_ACROSS(0, 11)) + +/* + * Write the initialization per-port registers that need to be done at + * driver load and after reset completes (i.e., that aren't done as part + * of other init procedures called from qib_init.c). + * Some of these should be redundant on reset, but play safe. + */ +static void write_7322_init_portregs(struct qib_pportdata *ppd) +{ + u64 val; + int i; + + if (!ppd->link_speed_supported) { + /* no buffer credits for this port */ + for (i = 1; i < 8; i++) + qib_write_kreg_port(ppd, krp_rxcreditvl0 + i, 0); + qib_write_kreg_port(ppd, krp_ibcctrl_b, 0); + qib_write_kreg(ppd->dd, kr_scratch, 0); + return; + } + + /* + * Set the number of supported virtual lanes in IBC, + * for flow control packet handling on unsupported VLs + */ + val = qib_read_kreg_port(ppd, krp_ibsdtestiftx); + val &= ~SYM_MASK(IB_SDTEST_IF_TX_0, VL_CAP); + val |= (u64)(ppd->vls_supported - 1) << + SYM_LSB(IB_SDTEST_IF_TX_0, VL_CAP); + qib_write_kreg_port(ppd, krp_ibsdtestiftx, val); + + qib_write_kreg_port(ppd, krp_rcvbthqp, QIB_KD_QP); + + /* enable tx header checking */ + qib_write_kreg_port(ppd, krp_sendcheckcontrol, IBA7322_SENDCHK_PKEY | + IBA7322_SENDCHK_BTHQP | IBA7322_SENDCHK_SLID | + IBA7322_SENDCHK_RAW_IPV6 | IBA7322_SENDCHK_MINSZ); + + qib_write_kreg_port(ppd, krp_ncmodectrl, + SYM_MASK(IBNCModeCtrl_0, ScrambleCapLocal)); + + /* + * Unconditionally clear the bufmask bits. If SDMA is + * enabled, we'll set them appropriately later. + */ + qib_write_kreg_port(ppd, krp_senddmabufmask0, 0); + qib_write_kreg_port(ppd, krp_senddmabufmask1, 0); + qib_write_kreg_port(ppd, krp_senddmabufmask2, 0); + if (ppd->dd->cspec->r1) + ppd->p_sendctrl |= SYM_MASK(SendCtrl_0, ForceCreditUpToDate); +} + +/* + * Write the initialization per-device registers that need to be done at + * driver load and after reset completes (i.e., that aren't done as part + * of other init procedures called from qib_init.c). Also write per-port + * registers that are affected by overall device config, such as QP mapping + * Some of these should be redundant on reset, but play safe. + */ +static void write_7322_initregs(struct qib_devdata *dd) +{ + struct qib_pportdata *ppd; + int i, pidx; + u64 val; + + /* Set Multicast QPs received by port 2 to map to context one. */ + qib_write_kreg(dd, KREG_IDX(RcvQPMulticastContext_1), 1); + + for (pidx = 0; pidx < dd->num_pports; ++pidx) { + unsigned n, regno; + unsigned long flags; + + if (!dd->qpn_mask || !dd->pport[pidx].link_speed_supported) + continue; + + ppd = &dd->pport[pidx]; + + /* be paranoid against later code motion, etc. */ + spin_lock_irqsave(&dd->cspec->rcvmod_lock, flags); + ppd->p_rcvctrl |= SYM_MASK(RcvCtrl_0, RcvQPMapEnable); + spin_unlock_irqrestore(&dd->cspec->rcvmod_lock, flags); + + /* Initialize QP to context mapping */ + regno = krp_rcvqpmaptable; + val = 0; + if (dd->num_pports > 1) + n = dd->first_user_ctxt / dd->num_pports; + else + n = dd->first_user_ctxt - 1; + for (i = 0; i < 32; ) { + unsigned ctxt; + + if (dd->num_pports > 1) + ctxt = (i % n) * dd->num_pports + pidx; + else if (i % n) + ctxt = (i % n) + 1; + else + ctxt = ppd->hw_pidx; + val |= ctxt << (5 * (i % 6)); + i++; + if (i % 6 == 0) { + qib_write_kreg_port(ppd, regno, val); + val = 0; + regno++; + } + } + qib_write_kreg_port(ppd, regno, val); + } + + /* + * Setup up interrupt mitigation for kernel contexts, but + * not user contexts (user contexts use interrupts when + * stalled waiting for any packet, so want those interrupts + * right away). + */ + for (i = 0; i < dd->first_user_ctxt; i++) { + dd->cspec->rcvavail_timeout[i] = rcv_int_timeout; + qib_write_kreg(dd, kr_rcvavailtimeout + i, rcv_int_timeout); + } + + /* + * Initialize as (disabled) rcvflow tables. Application code + * will setup each flow as it uses the flow. + * Doesn't clear any of the error bits that might be set. + */ + val = TIDFLOW_ERRBITS; /* these are W1C */ + for (i = 0; i < dd->ctxtcnt; i++) { + int flow; + for (flow = 0; flow < NUM_TIDFLOWS_CTXT; flow++) + qib_write_ureg(dd, ur_rcvflowtable+flow, val, i); + } + + /* + * dual cards init to dual port recovery, single port cards to + * the one port. Dual port cards may later adjust to 1 port, + * and then back to dual port if both ports are connected + * */ + if (dd->num_pports) + setup_7322_link_recovery(dd->pport, dd->num_pports > 1); +} + +static int qib_init_7322_variables(struct qib_devdata *dd) +{ + struct qib_pportdata *ppd; + unsigned features, pidx, sbufcnt; + int ret, mtu; + u32 sbufs, updthresh; + + /* pport structs are contiguous, allocated after devdata */ + ppd = (struct qib_pportdata *)(dd + 1); + dd->pport = ppd; + ppd[0].dd = dd; + ppd[1].dd = dd; + + dd->cspec = (struct qib_chip_specific *)(ppd + 2); + + ppd[0].cpspec = (struct qib_chippport_specific *)(dd->cspec + 1); + ppd[1].cpspec = &ppd[0].cpspec[1]; + ppd[0].cpspec->ppd = &ppd[0]; /* for autoneg_7322_work() */ + ppd[1].cpspec->ppd = &ppd[1]; /* for autoneg_7322_work() */ + + spin_lock_init(&dd->cspec->rcvmod_lock); + spin_lock_init(&dd->cspec->gpio_lock); + + /* we haven't yet set QIB_PRESENT, so use read directly */ + dd->revision = readq(&dd->kregbase[kr_revision]); + + if ((dd->revision & 0xffffffffU) == 0xffffffffU) { + qib_dev_err(dd, "Revision register read failure, " + "giving up initialization\n"); + ret = -ENODEV; + goto bail; + } + dd->flags |= QIB_PRESENT; /* now register routines work */ + + dd->majrev = (u8) SYM_FIELD(dd->revision, Revision_R, ChipRevMajor); + dd->minrev = (u8) SYM_FIELD(dd->revision, Revision_R, ChipRevMinor); + dd->cspec->r1 = dd->minrev == 1; + + get_7322_chip_params(dd); + features = qib_7322_boardname(dd); + + /* now that piobcnt2k and 4k set, we can allocate these */ + sbufcnt = dd->piobcnt2k + dd->piobcnt4k + + NUM_VL15_BUFS + BITS_PER_LONG - 1; + sbufcnt /= BITS_PER_LONG; + dd->cspec->sendchkenable = kmalloc(sbufcnt * + sizeof(*dd->cspec->sendchkenable), GFP_KERNEL); + dd->cspec->sendgrhchk = kmalloc(sbufcnt * + sizeof(*dd->cspec->sendgrhchk), GFP_KERNEL); + dd->cspec->sendibchk = kmalloc(sbufcnt * + sizeof(*dd->cspec->sendibchk), GFP_KERNEL); + if (!dd->cspec->sendchkenable || !dd->cspec->sendgrhchk || + !dd->cspec->sendibchk) { + qib_dev_err(dd, "Failed allocation for hdrchk bitmaps\n"); + ret = -ENOMEM; + goto bail; + } + + ppd = dd->pport; + + /* + * GPIO bits for TWSI data and clock, + * used for serial EEPROM. + */ + dd->gpio_sda_num = _QIB_GPIO_SDA_NUM; + dd->gpio_scl_num = _QIB_GPIO_SCL_NUM; + dd->twsi_eeprom_dev = QIB_TWSI_EEPROM_DEV; + + dd->flags |= QIB_HAS_INTX | QIB_HAS_LINK_LATENCY | + QIB_NODMA_RTAIL | QIB_HAS_VLSUPP | QIB_HAS_HDRSUPP | + QIB_HAS_THRESH_UPDATE | + (sdma_idle_cnt ? QIB_HAS_SDMA_TIMEOUT : 0); + dd->flags |= qib_special_trigger ? + QIB_USE_SPCL_TRIG : QIB_HAS_SEND_DMA; + + /* + * Setup initial values. These may change when PAT is enabled, but + * we need these to do initial chip register accesses. + */ + qib_7322_set_baseaddrs(dd); + + mtu = ib_mtu_enum_to_int(qib_ibmtu); + if (mtu == -1) + mtu = QIB_DEFAULT_MTU; + + dd->cspec->int_enable_mask = QIB_I_BITSEXTANT; + /* all hwerrors become interrupts, unless special purposed */ + dd->cspec->hwerrmask = ~0ULL; + /* link_recovery setup causes these errors, so ignore them, + * other than clearing them when they occur */ + dd->cspec->hwerrmask &= + ~(SYM_MASK(HwErrMask, IBSerdesPClkNotDetectMask_0) | + SYM_MASK(HwErrMask, IBSerdesPClkNotDetectMask_1) | + HWE_MASK(LATriggered)); + + for (pidx = 0; pidx < NUM_IB_PORTS; ++pidx) { + struct qib_chippport_specific *cp = ppd->cpspec; + ppd->link_speed_supported = features & PORT_SPD_CAP; + features >>= PORT_SPD_CAP_SHIFT; + if (!ppd->link_speed_supported) { + /* single port mode (7340, or configured) */ + dd->skip_kctxt_mask |= 1 << pidx; + if (pidx == 0) { + /* Make sure port is disabled. */ + qib_write_kreg_port(ppd, krp_rcvctrl, 0); + qib_write_kreg_port(ppd, krp_ibcctrl_a, 0); + ppd[0] = ppd[1]; + dd->cspec->hwerrmask &= ~(SYM_MASK(HwErrMask, + IBSerdesPClkNotDetectMask_0) + | SYM_MASK(HwErrMask, + SDmaMemReadErrMask_0)); + dd->cspec->int_enable_mask &= ~( + SYM_MASK(IntMask, SDmaCleanupDoneMask_0) | + SYM_MASK(IntMask, SDmaIdleIntMask_0) | + SYM_MASK(IntMask, SDmaProgressIntMask_0) | + SYM_MASK(IntMask, SDmaIntMask_0) | + SYM_MASK(IntMask, ErrIntMask_0) | + SYM_MASK(IntMask, SendDoneIntMask_0)); + } else { + /* Make sure port is disabled. */ + qib_write_kreg_port(ppd, krp_rcvctrl, 0); + qib_write_kreg_port(ppd, krp_ibcctrl_a, 0); + dd->cspec->hwerrmask &= ~(SYM_MASK(HwErrMask, + IBSerdesPClkNotDetectMask_1) + | SYM_MASK(HwErrMask, + SDmaMemReadErrMask_1)); + dd->cspec->int_enable_mask &= ~( + SYM_MASK(IntMask, SDmaCleanupDoneMask_1) | + SYM_MASK(IntMask, SDmaIdleIntMask_1) | + SYM_MASK(IntMask, SDmaProgressIntMask_1) | + SYM_MASK(IntMask, SDmaIntMask_1) | + SYM_MASK(IntMask, ErrIntMask_1) | + SYM_MASK(IntMask, SendDoneIntMask_1)); + } + continue; + } + + dd->num_pports++; + qib_init_pportdata(ppd, dd, pidx, dd->num_pports); + + ppd->link_width_supported = IB_WIDTH_1X | IB_WIDTH_4X; + ppd->link_width_enabled = IB_WIDTH_4X; + ppd->link_speed_enabled = ppd->link_speed_supported; + /* + * Set the initial values to reasonable default, will be set + * for real when link is up. + */ + ppd->link_width_active = IB_WIDTH_4X; + ppd->link_speed_active = QIB_IB_SDR; + ppd->delay_mult = ib_rate_to_delay[IB_RATE_10_GBPS]; + switch (qib_num_cfg_vls) { + case 1: + ppd->vls_supported = IB_VL_VL0; + break; + case 2: + ppd->vls_supported = IB_VL_VL0_1; + break; + default: + qib_devinfo(dd->pcidev, + "Invalid num_vls %u, using 4 VLs\n", + qib_num_cfg_vls); + qib_num_cfg_vls = 4; + /* fall through */ + case 4: + ppd->vls_supported = IB_VL_VL0_3; + break; + case 8: + if (mtu <= 2048) + ppd->vls_supported = IB_VL_VL0_7; + else { + qib_devinfo(dd->pcidev, + "Invalid num_vls %u for MTU %d " + ", using 4 VLs\n", + qib_num_cfg_vls, mtu); + ppd->vls_supported = IB_VL_VL0_3; + qib_num_cfg_vls = 4; + } + break; + } + ppd->vls_operational = ppd->vls_supported; + + init_waitqueue_head(&cp->autoneg_wait); + INIT_DELAYED_WORK(&cp->autoneg_work, + autoneg_7322_work); + if (ppd->dd->cspec->r1) + INIT_DELAYED_WORK(&cp->ipg_work, ipg_7322_work); + + /* + * For Mez and similar cards, no qsfp info, so do + * the "cable info" setup here. Can be overridden + * in adapter-specific routines. + */ + if (!(ppd->dd->flags & QIB_HAS_QSFP)) { + int i; + const struct txdds_ent *txdds; + + if (!IS_QMH(ppd->dd) && !IS_QME(ppd->dd)) + qib_devinfo(ppd->dd->pcidev, "IB%u:%u: " + "Unknown mezzanine card type\n", + ppd->dd->unit, ppd->port); + txdds = IS_QMH(ppd->dd) ? &qmh_qdr_txdds : + &qme_qdr_txdds; + + /* + * set values in case link comes up + * before table is written to driver. + */ + cp->h1_val = IS_QMH(ppd->dd) ? H1_FORCE_QMH : + H1_FORCE_QME; + for (i = 0; i < SERDES_CHANS; i++) { + cp->amp[i] = txdds->amp; + cp->pre[i] = txdds->pre; + cp->mainv[i] = txdds->main; + cp->post[i] = txdds->post; + } + } else + cp->h1_val = H1_FORCE_VAL; + + /* Avoid writes to chip for mini_init */ + if (!qib_mini_init) + write_7322_init_portregs(ppd); + + init_timer(&cp->chase_timer); + cp->chase_timer.function = reenable_chase; + cp->chase_timer.data = (unsigned long)ppd; + + ppd++; + } + + dd->rcvhdrentsize = QIB_RCVHDR_ENTSIZE; + dd->rcvhdrsize = QIB_DFLT_RCVHDRSIZE; + dd->rhf_offset = + dd->rcvhdrentsize - sizeof(u64) / sizeof(u32); + + /* we always allocate at least 2048 bytes for eager buffers */ + dd->rcvegrbufsize = max(mtu, 2048); + + qib_7322_tidtemplate(dd); + + /* + * We can request a receive interrupt for 1 or + * more packets from current offset. + */ + dd->rhdrhead_intr_off = + (u64) rcv_int_count << IBA7322_HDRHEAD_PKTINT_SHIFT; + + /* setup the stats timer; the add_timer is done at end of init */ + init_timer(&dd->stats_timer); + dd->stats_timer.function = qib_get_7322_faststats; + dd->stats_timer.data = (unsigned long) dd; + + dd->ureg_align = 0x10000; /* 64KB alignment */ + + dd->piosize2kmax_dwords = dd->piosize2k >> 2; + + qib_7322_config_ctxts(dd); + qib_set_ctxtcnt(dd); + + if (qib_wc_pat) { + ret = init_chip_wc_pat(dd, NUM_VL15_BUFS * dd->align4k); + if (ret) + goto bail; + } + qib_7322_set_baseaddrs(dd); /* set chip access pointers now */ + + ret = 0; + if (qib_mini_init) + goto bail; + if (!dd->num_pports) { + qib_dev_err(dd, "No ports enabled, giving up initialization\n"); + goto bail; /* no error, so can still figure out why err */ + } + + write_7322_initregs(dd); + ret = qib_create_ctxts(dd); + init_7322_cntrnames(dd); + + updthresh = 8U; /* update threshold */ + + /* use all of 4KB buffers for the kernel SDMA, zero if !SDMA. + * reserve the update threshold amount for other kernel use, such + * as sending SMI, MAD, and ACKs, or 3, whichever is greater, + * unless we aren't enabling SDMA, in which case we want to use + * all the 4k bufs for the kernel. + * if this was less than the update threshold, we could wait + * a long time for an update. Coded this way because we + * sometimes change the update threshold for various reasons, + * and we want this to remain robust. + */ + if (dd->flags & QIB_HAS_SEND_DMA) { + dd->cspec->sdmabufcnt = dd->piobcnt4k; + sbufs = updthresh > 3 ? updthresh : 3; + } else { + dd->cspec->sdmabufcnt = 0; + sbufs = dd->piobcnt4k; + } + dd->cspec->lastbuf_for_pio = dd->piobcnt2k + dd->piobcnt4k - + dd->cspec->sdmabufcnt; + dd->lastctxt_piobuf = dd->cspec->lastbuf_for_pio - sbufs; + dd->cspec->lastbuf_for_pio--; /* range is <= , not < */ + dd->pbufsctxt = (dd->cfgctxts > dd->first_user_ctxt) ? + dd->lastctxt_piobuf / (dd->cfgctxts - dd->first_user_ctxt) : 0; + + /* + * If we have 16 user contexts, we will have 7 sbufs + * per context, so reduce the update threshold to match. We + * want to update before we actually run out, at low pbufs/ctxt + * so give ourselves some margin. + */ + if (dd->pbufsctxt >= 2 && dd->pbufsctxt - 2 < updthresh) + updthresh = dd->pbufsctxt - 2; + dd->cspec->updthresh_dflt = updthresh; + dd->cspec->updthresh = updthresh; + + /* before full enable, no interrupts, no locking needed */ + dd->sendctrl |= ((updthresh & SYM_RMASK(SendCtrl, AvailUpdThld)) + << SYM_LSB(SendCtrl, AvailUpdThld)) | + SYM_MASK(SendCtrl, SendBufAvailPad64Byte); + + dd->psxmitwait_supported = 1; + dd->psxmitwait_check_rate = QIB_7322_PSXMITWAIT_CHECK_RATE; +bail: + if (!dd->ctxtcnt) + dd->ctxtcnt = 1; /* for other initialization code */ + + return ret; +} + +static u32 __iomem *qib_7322_getsendbuf(struct qib_pportdata *ppd, u64 pbc, + u32 *pbufnum) +{ + u32 first, last, plen = pbc & QIB_PBC_LENGTH_MASK; + struct qib_devdata *dd = ppd->dd; + + /* last is same for 2k and 4k, because we use 4k if all 2k busy */ + if (pbc & PBC_7322_VL15_SEND) { + first = dd->piobcnt2k + dd->piobcnt4k + ppd->hw_pidx; + last = first; + } else { + if ((plen + 1) > dd->piosize2kmax_dwords) + first = dd->piobcnt2k; + else + first = 0; + last = dd->cspec->lastbuf_for_pio; + } + return qib_getsendbuf_range(dd, pbufnum, first, last); +} + +static void qib_set_cntr_7322_sample(struct qib_pportdata *ppd, u32 intv, + u32 start) +{ + qib_write_kreg_port(ppd, krp_psinterval, intv); + qib_write_kreg_port(ppd, krp_psstart, start); +} + +/* + * Must be called with sdma_lock held, or before init finished. + */ +static void qib_sdma_set_7322_desc_cnt(struct qib_pportdata *ppd, unsigned cnt) +{ + qib_write_kreg_port(ppd, krp_senddmadesccnt, cnt); +} + +static struct sdma_set_state_action sdma_7322_action_table[] = { + [qib_sdma_state_s00_hw_down] = { + .go_s99_running_tofalse = 1, + .op_enable = 0, + .op_intenable = 0, + .op_halt = 0, + .op_drain = 0, + }, + [qib_sdma_state_s10_hw_start_up_wait] = { + .op_enable = 0, + .op_intenable = 1, + .op_halt = 1, + .op_drain = 0, + }, + [qib_sdma_state_s20_idle] = { + .op_enable = 1, + .op_intenable = 1, + .op_halt = 1, + .op_drain = 0, + }, + [qib_sdma_state_s30_sw_clean_up_wait] = { + .op_enable = 0, + .op_intenable = 1, + .op_halt = 1, + .op_drain = 0, + }, + [qib_sdma_state_s40_hw_clean_up_wait] = { + .op_enable = 1, + .op_intenable = 1, + .op_halt = 1, + .op_drain = 0, + }, + [qib_sdma_state_s50_hw_halt_wait] = { + .op_enable = 1, + .op_intenable = 1, + .op_halt = 1, + .op_drain = 1, + }, + [qib_sdma_state_s99_running] = { + .op_enable = 1, + .op_intenable = 1, + .op_halt = 0, + .op_drain = 0, + .go_s99_running_totrue = 1, + }, +}; + +static void qib_7322_sdma_init_early(struct qib_pportdata *ppd) +{ + ppd->sdma_state.set_state_action = sdma_7322_action_table; +} + +static int init_sdma_7322_regs(struct qib_pportdata *ppd) +{ + struct qib_devdata *dd = ppd->dd; + unsigned lastbuf, erstbuf; + u64 senddmabufmask[3] = { 0 }; + int n, ret = 0; + + qib_write_kreg_port(ppd, krp_senddmabase, ppd->sdma_descq_phys); + qib_sdma_7322_setlengen(ppd); + qib_sdma_update_7322_tail(ppd, 0); /* Set SendDmaTail */ + qib_write_kreg_port(ppd, krp_senddmareloadcnt, sdma_idle_cnt); + qib_write_kreg_port(ppd, krp_senddmadesccnt, 0); + qib_write_kreg_port(ppd, krp_senddmaheadaddr, ppd->sdma_head_phys); + + if (dd->num_pports) + n = dd->cspec->sdmabufcnt / dd->num_pports; /* no remainder */ + else + n = dd->cspec->sdmabufcnt; /* failsafe for init */ + erstbuf = (dd->piobcnt2k + dd->piobcnt4k) - + ((dd->num_pports == 1 || ppd->port == 2) ? n : + dd->cspec->sdmabufcnt); + lastbuf = erstbuf + n; + + ppd->sdma_state.first_sendbuf = erstbuf; + ppd->sdma_state.last_sendbuf = lastbuf; + for (; erstbuf < lastbuf; ++erstbuf) { + unsigned word = erstbuf / BITS_PER_LONG; + unsigned bit = erstbuf & (BITS_PER_LONG - 1); + + BUG_ON(word >= 3); + senddmabufmask[word] |= 1ULL << bit; + } + qib_write_kreg_port(ppd, krp_senddmabufmask0, senddmabufmask[0]); + qib_write_kreg_port(ppd, krp_senddmabufmask1, senddmabufmask[1]); + qib_write_kreg_port(ppd, krp_senddmabufmask2, senddmabufmask[2]); + return ret; +} + +/* sdma_lock must be held */ +static u16 qib_sdma_7322_gethead(struct qib_pportdata *ppd) +{ + struct qib_devdata *dd = ppd->dd; + int sane; + int use_dmahead; + u16 swhead; + u16 swtail; + u16 cnt; + u16 hwhead; + + use_dmahead = __qib_sdma_running(ppd) && + (dd->flags & QIB_HAS_SDMA_TIMEOUT); +retry: + hwhead = use_dmahead ? + (u16) le64_to_cpu(*ppd->sdma_head_dma) : + (u16) qib_read_kreg_port(ppd, krp_senddmahead); + + swhead = ppd->sdma_descq_head; + swtail = ppd->sdma_descq_tail; + cnt = ppd->sdma_descq_cnt; + + if (swhead < swtail) + /* not wrapped */ + sane = (hwhead >= swhead) & (hwhead <= swtail); + else if (swhead > swtail) + /* wrapped around */ + sane = ((hwhead >= swhead) && (hwhead < cnt)) || + (hwhead <= swtail); + else + /* empty */ + sane = (hwhead == swhead); + + if (unlikely(!sane)) { + if (use_dmahead) { + /* try one more time, directly from the register */ + use_dmahead = 0; + goto retry; + } + /* proceed as if no progress */ + hwhead = swhead; + } + + return hwhead; +} + +static int qib_sdma_7322_busy(struct qib_pportdata *ppd) +{ + u64 hwstatus = qib_read_kreg_port(ppd, krp_senddmastatus); + + return (hwstatus & SYM_MASK(SendDmaStatus_0, ScoreBoardDrainInProg)) || + (hwstatus & SYM_MASK(SendDmaStatus_0, HaltInProg)) || + !(hwstatus & SYM_MASK(SendDmaStatus_0, InternalSDmaHalt)) || + !(hwstatus & SYM_MASK(SendDmaStatus_0, ScbEmpty)); +} + +/* + * Compute the amount of delay before sending the next packet if the + * port's send rate differs from the static rate set for the QP. + * The delay affects the next packet and the amount of the delay is + * based on the length of the this packet. + */ +static u32 qib_7322_setpbc_control(struct qib_pportdata *ppd, u32 plen, + u8 srate, u8 vl) +{ + u8 snd_mult = ppd->delay_mult; + u8 rcv_mult = ib_rate_to_delay[srate]; + u32 ret; + + ret = rcv_mult > snd_mult ? ((plen + 1) >> 1) * snd_mult : 0; + + /* Indicate VL15, else set the VL in the control word */ + if (vl == 15) + ret |= PBC_7322_VL15_SEND_CTRL; + else + ret |= vl << PBC_VL_NUM_LSB; + ret |= ((u32)(ppd->hw_pidx)) << PBC_PORT_SEL_LSB; + + return ret; +} + +/* + * Enable the per-port VL15 send buffers for use. + * They follow the rest of the buffers, without a config parameter. + * This was in initregs, but that is done before the shadow + * is set up, and this has to be done after the shadow is + * set up. + */ +static void qib_7322_initvl15_bufs(struct qib_devdata *dd) +{ + unsigned vl15bufs; + + vl15bufs = dd->piobcnt2k + dd->piobcnt4k; + qib_chg_pioavailkernel(dd, vl15bufs, NUM_VL15_BUFS, + TXCHK_CHG_TYPE_KERN, NULL); +} + +static void qib_7322_init_ctxt(struct qib_ctxtdata *rcd) +{ + if (rcd->ctxt < NUM_IB_PORTS) { + if (rcd->dd->num_pports > 1) { + rcd->rcvegrcnt = KCTXT0_EGRCNT / 2; + rcd->rcvegr_tid_base = rcd->ctxt ? rcd->rcvegrcnt : 0; + } else { + rcd->rcvegrcnt = KCTXT0_EGRCNT; + rcd->rcvegr_tid_base = 0; + } + } else { + rcd->rcvegrcnt = rcd->dd->cspec->rcvegrcnt; + rcd->rcvegr_tid_base = KCTXT0_EGRCNT + + (rcd->ctxt - NUM_IB_PORTS) * rcd->rcvegrcnt; + } +} + +#define QTXSLEEPS 5000 +static void qib_7322_txchk_change(struct qib_devdata *dd, u32 start, + u32 len, u32 which, struct qib_ctxtdata *rcd) +{ + int i; + const int last = start + len - 1; + const int lastr = last / BITS_PER_LONG; + u32 sleeps = 0; + int wait = rcd != NULL; + unsigned long flags; + + while (wait) { + unsigned long shadow; + int cstart, previ = -1; + + /* + * when flipping from kernel to user, we can't change + * the checking type if the buffer is allocated to the + * driver. It's OK the other direction, because it's + * from close, and we have just disarm'ed all the + * buffers. All the kernel to kernel changes are also + * OK. + */ + for (cstart = start; cstart <= last; cstart++) { + i = ((2 * cstart) + QLOGIC_IB_SENDPIOAVAIL_BUSY_SHIFT) + / BITS_PER_LONG; + if (i != previ) { + shadow = (unsigned long) + le64_to_cpu(dd->pioavailregs_dma[i]); + previ = i; + } + if (test_bit(((2 * cstart) + + QLOGIC_IB_SENDPIOAVAIL_BUSY_SHIFT) + % BITS_PER_LONG, &shadow)) + break; + } + + if (cstart > last) + break; + + if (sleeps == QTXSLEEPS) + break; + /* make sure we see an updated copy next time around */ + sendctrl_7322_mod(dd->pport, QIB_SENDCTRL_AVAIL_BLIP); + sleeps++; + msleep(1); + } + + switch (which) { + case TXCHK_CHG_TYPE_DIS1: + /* + * disable checking on a range; used by diags; just + * one buffer, but still written generically + */ + for (i = start; i <= last; i++) + clear_bit(i, dd->cspec->sendchkenable); + break; + + case TXCHK_CHG_TYPE_ENAB1: + /* + * (re)enable checking on a range; used by diags; just + * one buffer, but still written generically; read + * scratch to be sure buffer actually triggered, not + * just flushed from processor. + */ + qib_read_kreg32(dd, kr_scratch); + for (i = start; i <= last; i++) + set_bit(i, dd->cspec->sendchkenable); + break; + + case TXCHK_CHG_TYPE_KERN: + /* usable by kernel */ + for (i = start; i <= last; i++) { + set_bit(i, dd->cspec->sendibchk); + clear_bit(i, dd->cspec->sendgrhchk); + } + spin_lock_irqsave(&dd->uctxt_lock, flags); + /* see if we need to raise avail update threshold */ + for (i = dd->first_user_ctxt; + dd->cspec->updthresh != dd->cspec->updthresh_dflt + && i < dd->cfgctxts; i++) + if (dd->rcd[i] && dd->rcd[i]->subctxt_cnt && + ((dd->rcd[i]->piocnt / dd->rcd[i]->subctxt_cnt) - 1) + < dd->cspec->updthresh_dflt) + break; + spin_unlock_irqrestore(&dd->uctxt_lock, flags); + if (i == dd->cfgctxts) { + spin_lock_irqsave(&dd->sendctrl_lock, flags); + dd->cspec->updthresh = dd->cspec->updthresh_dflt; + dd->sendctrl &= ~SYM_MASK(SendCtrl, AvailUpdThld); + dd->sendctrl |= (dd->cspec->updthresh & + SYM_RMASK(SendCtrl, AvailUpdThld)) << + SYM_LSB(SendCtrl, AvailUpdThld); + spin_unlock_irqrestore(&dd->sendctrl_lock, flags); + sendctrl_7322_mod(dd->pport, QIB_SENDCTRL_AVAIL_BLIP); + } + break; + + case TXCHK_CHG_TYPE_USER: + /* for user process */ + for (i = start; i <= last; i++) { + clear_bit(i, dd->cspec->sendibchk); + set_bit(i, dd->cspec->sendgrhchk); + } + spin_lock_irqsave(&dd->sendctrl_lock, flags); + if (rcd && rcd->subctxt_cnt && ((rcd->piocnt + / rcd->subctxt_cnt) - 1) < dd->cspec->updthresh) { + dd->cspec->updthresh = (rcd->piocnt / + rcd->subctxt_cnt) - 1; + dd->sendctrl &= ~SYM_MASK(SendCtrl, AvailUpdThld); + dd->sendctrl |= (dd->cspec->updthresh & + SYM_RMASK(SendCtrl, AvailUpdThld)) + << SYM_LSB(SendCtrl, AvailUpdThld); + spin_unlock_irqrestore(&dd->sendctrl_lock, flags); + sendctrl_7322_mod(dd->pport, QIB_SENDCTRL_AVAIL_BLIP); + } else + spin_unlock_irqrestore(&dd->sendctrl_lock, flags); + break; + + default: + break; + } + + for (i = start / BITS_PER_LONG; which >= 2 && i <= lastr; ++i) + qib_write_kreg(dd, kr_sendcheckmask + i, + dd->cspec->sendchkenable[i]); + + for (i = start / BITS_PER_LONG; which < 2 && i <= lastr; ++i) { + qib_write_kreg(dd, kr_sendgrhcheckmask + i, + dd->cspec->sendgrhchk[i]); + qib_write_kreg(dd, kr_sendibpktmask + i, + dd->cspec->sendibchk[i]); + } + + /* + * Be sure whatever we did was seen by the chip and acted upon, + * before we return. Mostly important for which >= 2. + */ + qib_read_kreg32(dd, kr_scratch); +} + + +/* useful for trigger analyzers, etc. */ +static void writescratch(struct qib_devdata *dd, u32 val) +{ + qib_write_kreg(dd, kr_scratch, val); +} + +/* Dummy for now, use chip regs soon */ +static int qib_7322_tempsense_rd(struct qib_devdata *dd, int regnum) +{ + return -ENXIO; +} + +/** + * qib_init_iba7322_funcs - set up the chip-specific function pointers + * @dev: the pci_dev for qlogic_ib device + * @ent: pci_device_id struct for this dev + * + * Also allocates, inits, and returns the devdata struct for this + * device instance + * + * This is global, and is called directly at init to set up the + * chip-specific function pointers for later use. + */ +struct qib_devdata *qib_init_iba7322_funcs(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct qib_devdata *dd; + int ret, i; + u32 tabsize, actual_cnt = 0; + + dd = qib_alloc_devdata(pdev, + NUM_IB_PORTS * sizeof(struct qib_pportdata) + + sizeof(struct qib_chip_specific) + + NUM_IB_PORTS * sizeof(struct qib_chippport_specific)); + if (IS_ERR(dd)) + goto bail; + + dd->f_bringup_serdes = qib_7322_bringup_serdes; + dd->f_cleanup = qib_setup_7322_cleanup; + dd->f_clear_tids = qib_7322_clear_tids; + dd->f_free_irq = qib_7322_free_irq; + dd->f_get_base_info = qib_7322_get_base_info; + dd->f_get_msgheader = qib_7322_get_msgheader; + dd->f_getsendbuf = qib_7322_getsendbuf; + dd->f_gpio_mod = gpio_7322_mod; + dd->f_eeprom_wen = qib_7322_eeprom_wen; + dd->f_hdrqempty = qib_7322_hdrqempty; + dd->f_ib_updown = qib_7322_ib_updown; + dd->f_init_ctxt = qib_7322_init_ctxt; + dd->f_initvl15_bufs = qib_7322_initvl15_bufs; + dd->f_intr_fallback = qib_7322_intr_fallback; + dd->f_late_initreg = qib_late_7322_initreg; + dd->f_setpbc_control = qib_7322_setpbc_control; + dd->f_portcntr = qib_portcntr_7322; + dd->f_put_tid = qib_7322_put_tid; + dd->f_quiet_serdes = qib_7322_mini_quiet_serdes; + dd->f_rcvctrl = rcvctrl_7322_mod; + dd->f_read_cntrs = qib_read_7322cntrs; + dd->f_read_portcntrs = qib_read_7322portcntrs; + dd->f_reset = qib_do_7322_reset; + dd->f_init_sdma_regs = init_sdma_7322_regs; + dd->f_sdma_busy = qib_sdma_7322_busy; + dd->f_sdma_gethead = qib_sdma_7322_gethead; + dd->f_sdma_sendctrl = qib_7322_sdma_sendctrl; + dd->f_sdma_set_desc_cnt = qib_sdma_set_7322_desc_cnt; + dd->f_sdma_update_tail = qib_sdma_update_7322_tail; + dd->f_sendctrl = sendctrl_7322_mod; + dd->f_set_armlaunch = qib_set_7322_armlaunch; + dd->f_set_cntr_sample = qib_set_cntr_7322_sample; + dd->f_iblink_state = qib_7322_iblink_state; + dd->f_ibphys_portstate = qib_7322_phys_portstate; + dd->f_get_ib_cfg = qib_7322_get_ib_cfg; + dd->f_set_ib_cfg = qib_7322_set_ib_cfg; + dd->f_set_ib_loopback = qib_7322_set_loopback; + dd->f_get_ib_table = qib_7322_get_ib_table; + dd->f_set_ib_table = qib_7322_set_ib_table; + dd->f_set_intr_state = qib_7322_set_intr_state; + dd->f_setextled = qib_setup_7322_setextled; + dd->f_txchk_change = qib_7322_txchk_change; + dd->f_update_usrhead = qib_update_7322_usrhead; + dd->f_wantpiobuf_intr = qib_wantpiobuf_7322_intr; + dd->f_xgxs_reset = qib_7322_mini_pcs_reset; + dd->f_sdma_hw_clean_up = qib_7322_sdma_hw_clean_up; + dd->f_sdma_hw_start_up = qib_7322_sdma_hw_start_up; + dd->f_sdma_init_early = qib_7322_sdma_init_early; + dd->f_writescratch = writescratch; + dd->f_tempsense_rd = qib_7322_tempsense_rd; + /* + * Do remaining PCIe setup and save PCIe values in dd. + * Any error printing is already done by the init code. + * On return, we have the chip mapped, but chip registers + * are not set up until start of qib_init_7322_variables. + */ + ret = qib_pcie_ddinit(dd, pdev, ent); + if (ret < 0) + goto bail_free; + + /* initialize chip-specific variables */ + ret = qib_init_7322_variables(dd); + if (ret) + goto bail_cleanup; + + if (qib_mini_init || !dd->num_pports) + goto bail; + + /* + * Determine number of vectors we want; depends on port count + * and number of configured kernel receive queues actually used. + * Should also depend on whether sdma is enabled or not, but + * that's such a rare testing case it's not worth worrying about. + */ + tabsize = dd->first_user_ctxt + ARRAY_SIZE(irq_table); + for (i = 0; i < tabsize; i++) + if ((i < ARRAY_SIZE(irq_table) && + irq_table[i].port <= dd->num_pports) || + (i >= ARRAY_SIZE(irq_table) && + dd->rcd[i - ARRAY_SIZE(irq_table)])) + actual_cnt++; + tabsize = actual_cnt; + dd->cspec->msix_entries = kmalloc(tabsize * + sizeof(struct msix_entry), GFP_KERNEL); + dd->cspec->msix_arg = kmalloc(tabsize * + sizeof(void *), GFP_KERNEL); + if (!dd->cspec->msix_entries || !dd->cspec->msix_arg) { + qib_dev_err(dd, "No memory for MSIx table\n"); + tabsize = 0; + } + for (i = 0; i < tabsize; i++) + dd->cspec->msix_entries[i].entry = i; + + if (qib_pcie_params(dd, 8, &tabsize, dd->cspec->msix_entries)) + qib_dev_err(dd, "Failed to setup PCIe or interrupts; " + "continuing anyway\n"); + /* may be less than we wanted, if not enough available */ + dd->cspec->num_msix_entries = tabsize; + + /* setup interrupt handler */ + qib_setup_7322_interrupt(dd, 1); + + /* clear diagctrl register, in case diags were running and crashed */ + qib_write_kreg(dd, kr_hwdiagctrl, 0); + +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) + ret = dca_add_requester(&pdev->dev); + if (!ret) { + dd->flags |= QIB_DCA_ENABLED; + qib_setup_dca(dd); + } +#endif + goto bail; + +bail_cleanup: + qib_pcie_ddcleanup(dd); +bail_free: + qib_free_devdata(dd); + dd = ERR_PTR(ret); +bail: + return dd; +} + +/* + * Set the table entry at the specified index from the table specifed. + * There are 3 * TXDDS_TABLE_SZ entries in all per port, with the first + * TXDDS_TABLE_SZ for SDR, the next for DDR, and the last for QDR. + * 'idx' below addresses the correct entry, while its 4 LSBs select the + * corresponding entry (one of TXDDS_TABLE_SZ) from the selected table. + */ +#define DDS_ENT_AMP_LSB 14 +#define DDS_ENT_MAIN_LSB 9 +#define DDS_ENT_POST_LSB 5 +#define DDS_ENT_PRE_XTRA_LSB 3 +#define DDS_ENT_PRE_LSB 0 + +/* + * Set one entry in the TxDDS table for spec'd port + * ridx picks one of the entries, while tp points + * to the appropriate table entry. + */ +static void set_txdds(struct qib_pportdata *ppd, int ridx, + const struct txdds_ent *tp) +{ + struct qib_devdata *dd = ppd->dd; + u32 pack_ent; + int regidx; + + /* Get correct offset in chip-space, and in source table */ + regidx = KREG_IBPORT_IDX(IBSD_DDS_MAP_TABLE) + ridx; + /* + * We do not use qib_write_kreg_port() because it was intended + * only for registers in the lower "port specific" pages. + * So do index calculation by hand. + */ + if (ppd->hw_pidx) + regidx += (dd->palign / sizeof(u64)); + + pack_ent = tp->amp << DDS_ENT_AMP_LSB; + pack_ent |= tp->main << DDS_ENT_MAIN_LSB; + pack_ent |= tp->pre << DDS_ENT_PRE_LSB; + pack_ent |= tp->post << DDS_ENT_POST_LSB; + qib_write_kreg(dd, regidx, pack_ent); + /* Prevent back-to-back writes by hitting scratch */ + qib_write_kreg(ppd->dd, kr_scratch, 0); +} + +static const struct vendor_txdds_ent vendor_txdds[] = { + { /* Amphenol 1m 30awg NoEq */ + { 0x41, 0x50, 0x48 }, "584470002 ", + { 10, 0, 0, 5 }, { 10, 0, 0, 9 }, { 7, 1, 0, 13 }, + }, + { /* Amphenol 3m 28awg NoEq */ + { 0x41, 0x50, 0x48 }, "584470004 ", + { 0, 0, 0, 8 }, { 0, 0, 0, 11 }, { 0, 1, 7, 15 }, + }, + { /* Finisar 3m OM2 Optical */ + { 0x00, 0x90, 0x65 }, "FCBG410QB1C03-QL", + { 0, 0, 0, 3 }, { 0, 0, 0, 4 }, { 0, 0, 0, 13 }, + }, + { /* Finisar 30m OM2 Optical */ + { 0x00, 0x90, 0x65 }, "FCBG410QB1C30-QL", + { 0, 0, 0, 1 }, { 0, 0, 0, 5 }, { 0, 0, 0, 11 }, + }, + { /* Finisar Default OM2 Optical */ + { 0x00, 0x90, 0x65 }, NULL, + { 0, 0, 0, 2 }, { 0, 0, 0, 5 }, { 0, 0, 0, 12 }, + }, + { /* Gore 1m 30awg NoEq */ + { 0x00, 0x21, 0x77 }, "QSN3300-1 ", + { 0, 0, 0, 6 }, { 0, 0, 0, 9 }, { 0, 1, 0, 15 }, + }, + { /* Gore 2m 30awg NoEq */ + { 0x00, 0x21, 0x77 }, "QSN3300-2 ", + { 0, 0, 0, 8 }, { 0, 0, 0, 10 }, { 0, 1, 7, 15 }, + }, + { /* Gore 1m 28awg NoEq */ + { 0x00, 0x21, 0x77 }, "QSN3800-1 ", + { 0, 0, 0, 6 }, { 0, 0, 0, 8 }, { 0, 1, 0, 15 }, + }, + { /* Gore 3m 28awg NoEq */ + { 0x00, 0x21, 0x77 }, "QSN3800-3 ", + { 0, 0, 0, 9 }, { 0, 0, 0, 13 }, { 0, 1, 7, 15 }, + }, + { /* Gore 5m 24awg Eq */ + { 0x00, 0x21, 0x77 }, "QSN7000-5 ", + { 0, 0, 0, 7 }, { 0, 0, 0, 9 }, { 0, 1, 3, 15 }, + }, + { /* Gore 7m 24awg Eq */ + { 0x00, 0x21, 0x77 }, "QSN7000-7 ", + { 0, 0, 0, 9 }, { 0, 0, 0, 11 }, { 0, 2, 6, 15 }, + }, + { /* Gore 5m 26awg Eq */ + { 0x00, 0x21, 0x77 }, "QSN7600-5 ", + { 0, 0, 0, 8 }, { 0, 0, 0, 11 }, { 0, 1, 9, 13 }, + }, + { /* Gore 7m 26awg Eq */ + { 0x00, 0x21, 0x77 }, "QSN7600-7 ", + { 0, 0, 0, 8 }, { 0, 0, 0, 11 }, { 10, 1, 8, 15 }, + }, + { /* Intersil 12m 24awg Active */ + { 0x00, 0x30, 0xB4 }, "QLX4000CQSFP1224", + { 0, 0, 0, 2 }, { 0, 0, 0, 5 }, { 0, 3, 0, 9 }, + }, + { /* Intersil 10m 28awg Active */ + { 0x00, 0x30, 0xB4 }, "QLX4000CQSFP1028", + { 0, 0, 0, 6 }, { 0, 0, 0, 4 }, { 0, 2, 0, 2 }, + }, + { /* Intersil 7m 30awg Active */ + { 0x00, 0x30, 0xB4 }, "QLX4000CQSFP0730", + { 0, 0, 0, 6 }, { 0, 0, 0, 4 }, { 0, 1, 0, 3 }, + }, + { /* Intersil 5m 32awg Active */ + { 0x00, 0x30, 0xB4 }, "QLX4000CQSFP0532", + { 0, 0, 0, 6 }, { 0, 0, 0, 6 }, { 0, 2, 0, 8 }, + }, + { /* Intersil Default Active */ + { 0x00, 0x30, 0xB4 }, NULL, + { 0, 0, 0, 6 }, { 0, 0, 0, 5 }, { 0, 2, 0, 5 }, + }, + { /* Luxtera 20m Active Optical */ + { 0x00, 0x25, 0x63 }, NULL, + { 0, 0, 0, 5 }, { 0, 0, 0, 8 }, { 0, 2, 0, 12 }, + }, + { /* Molex 1M Cu loopback */ + { 0x00, 0x09, 0x3A }, "74763-0025 ", + { 2, 2, 6, 15 }, { 2, 2, 6, 15 }, { 2, 2, 6, 15 }, + }, + { /* Molex 2m 28awg NoEq */ + { 0x00, 0x09, 0x3A }, "74757-2201 ", + { 0, 0, 0, 6 }, { 0, 0, 0, 9 }, { 0, 1, 1, 15 }, + }, +}; + +static const struct txdds_ent txdds_sdr[TXDDS_TABLE_SZ] = { + /* amp, pre, main, post */ + { 2, 2, 15, 6 }, /* Loopback */ + { 0, 0, 0, 1 }, /* 2 dB */ + { 0, 0, 0, 2 }, /* 3 dB */ + { 0, 0, 0, 3 }, /* 4 dB */ + { 0, 0, 0, 4 }, /* 5 dB */ + { 0, 0, 0, 5 }, /* 6 dB */ + { 0, 0, 0, 6 }, /* 7 dB */ + { 0, 0, 0, 7 }, /* 8 dB */ + { 0, 0, 0, 8 }, /* 9 dB */ + { 0, 0, 0, 9 }, /* 10 dB */ + { 0, 0, 0, 10 }, /* 11 dB */ + { 0, 0, 0, 11 }, /* 12 dB */ + { 0, 0, 0, 12 }, /* 13 dB */ + { 0, 0, 0, 13 }, /* 14 dB */ + { 0, 0, 0, 14 }, /* 15 dB */ + { 0, 0, 0, 15 }, /* 16 dB */ +}; + +static const struct txdds_ent txdds_ddr[TXDDS_TABLE_SZ] = { + /* amp, pre, main, post */ + { 2, 2, 15, 6 }, /* Loopback */ + { 0, 0, 0, 8 }, /* 2 dB */ + { 0, 0, 0, 8 }, /* 3 dB */ + { 0, 0, 0, 9 }, /* 4 dB */ + { 0, 0, 0, 9 }, /* 5 dB */ + { 0, 0, 0, 10 }, /* 6 dB */ + { 0, 0, 0, 10 }, /* 7 dB */ + { 0, 0, 0, 11 }, /* 8 dB */ + { 0, 0, 0, 11 }, /* 9 dB */ + { 0, 0, 0, 12 }, /* 10 dB */ + { 0, 0, 0, 12 }, /* 11 dB */ + { 0, 0, 0, 13 }, /* 12 dB */ + { 0, 0, 0, 13 }, /* 13 dB */ + { 0, 0, 0, 14 }, /* 14 dB */ + { 0, 0, 0, 14 }, /* 15 dB */ + { 0, 0, 0, 15 }, /* 16 dB */ +}; + +static const struct txdds_ent txdds_qdr[TXDDS_TABLE_SZ] = { + /* amp, pre, main, post */ + { 2, 2, 15, 6 }, /* Loopback */ + { 0, 1, 0, 7 }, /* 2 dB */ + { 0, 1, 0, 9 }, /* 3 dB */ + { 0, 1, 0, 11 }, /* 4 dB */ + { 0, 1, 0, 13 }, /* 5 dB */ + { 0, 1, 0, 15 }, /* 6 dB */ + { 0, 1, 3, 15 }, /* 7 dB */ + { 0, 1, 7, 15 }, /* 8 dB */ + { 0, 1, 7, 15 }, /* 9 dB */ + { 0, 1, 8, 15 }, /* 10 dB */ + { 0, 1, 9, 15 }, /* 11 dB */ + { 0, 1, 10, 15 }, /* 12 dB */ + { 0, 2, 6, 15 }, /* 13 dB */ + { 0, 2, 7, 15 }, /* 14 dB */ + { 0, 2, 8, 15 }, /* 15 dB */ + { 0, 2, 9, 15 }, /* 16 dB */ +}; + +static const struct txdds_ent *get_atten_table(const struct txdds_ent *txdds, + unsigned atten) +{ + /* + * The attenuation table starts at 2dB for entry 1, + * with entry 0 being the loopback entry. + */ + if (atten <= 2) + atten = 1; + else if (atten > TXDDS_TABLE_SZ) + atten = TXDDS_TABLE_SZ - 1; + else + atten--; + return txdds + atten; +} + +/* + * if override is set, the module parameter cable_atten has a value + * for this specific port, so use it, rather than our normal mechanism. + */ +static void find_best_ent(struct qib_pportdata *ppd, + const struct txdds_ent **sdr_dds, + const struct txdds_ent **ddr_dds, + const struct txdds_ent **qdr_dds, int override) +{ + struct qib_qsfp_cache *qd = &ppd->cpspec->qsfp_data.cache; + int idx; + + /* Search table of known cables */ + for (idx = 0; !override && idx < ARRAY_SIZE(vendor_txdds); ++idx) { + const struct vendor_txdds_ent *v = vendor_txdds + idx; + + if (!memcmp(v->oui, qd->oui, QSFP_VOUI_LEN) && + (!v->partnum || + !memcmp(v->partnum, qd->partnum, QSFP_PN_LEN))) { + *sdr_dds = &v->sdr; + *ddr_dds = &v->ddr; + *qdr_dds = &v->qdr; + return; + } + } + + /* Lookup serdes setting by cable type and attenuation */ + if (!override && QSFP_IS_ACTIVE(qd->tech)) { + *sdr_dds = txdds_sdr + ppd->dd->board_atten; + *ddr_dds = txdds_ddr + ppd->dd->board_atten; + *qdr_dds = txdds_qdr + ppd->dd->board_atten; + return; + } + + if (!override && QSFP_HAS_ATTEN(qd->tech) && (qd->atten[0] || + qd->atten[1])) { + *sdr_dds = get_atten_table(txdds_sdr, qd->atten[0]); + *ddr_dds = get_atten_table(txdds_ddr, qd->atten[0]); + *qdr_dds = get_atten_table(txdds_qdr, qd->atten[1]); + return; + } else { + /* + * If we have no (or incomplete) data from the cable + * EEPROM, or no QSFP, use the module parameter value + * to index into the attentuation table. + */ + *sdr_dds = &txdds_sdr[ppd->cpspec->no_eep]; + *ddr_dds = &txdds_ddr[ppd->cpspec->no_eep]; + *qdr_dds = &txdds_qdr[ppd->cpspec->no_eep]; + } +} + +static void init_txdds_table(struct qib_pportdata *ppd, int override) +{ + const struct txdds_ent *sdr_dds, *ddr_dds, *qdr_dds; + struct txdds_ent *dds; + int idx; + int single_ent = 0; + + if (IS_QMH(ppd->dd)) { + /* normally will be overridden, via setup_qmh() */ + sdr_dds = &qmh_sdr_txdds; + ddr_dds = &qmh_ddr_txdds; + qdr_dds = &qmh_qdr_txdds; + single_ent = 1; + } else if (IS_QME(ppd->dd)) { + sdr_dds = &qme_sdr_txdds; + ddr_dds = &qme_ddr_txdds; + qdr_dds = &qme_qdr_txdds; + single_ent = 1; + } else + find_best_ent(ppd, &sdr_dds, &ddr_dds, &qdr_dds, override); + + /* Fill in the first entry with the best entry found. */ + set_txdds(ppd, 0, sdr_dds); + set_txdds(ppd, TXDDS_TABLE_SZ, ddr_dds); + set_txdds(ppd, 2 * TXDDS_TABLE_SZ, qdr_dds); + + /* + * for our current speed, also write that value into the + * tx serdes registers. + */ + dds = (struct txdds_ent *)(ppd->link_speed_active == QIB_IB_QDR ? + qdr_dds : (ppd->link_speed_active == + QIB_IB_DDR ? ddr_dds : sdr_dds)); + write_tx_serdes_param(ppd, dds); + + /* Fill in the remaining entries with the default table values. */ + for (idx = 1; idx < ARRAY_SIZE(txdds_sdr); ++idx) { + set_txdds(ppd, idx, single_ent ? sdr_dds : txdds_sdr + idx); + set_txdds(ppd, idx + TXDDS_TABLE_SZ, + single_ent ? ddr_dds : txdds_ddr + idx); + set_txdds(ppd, idx + 2 * TXDDS_TABLE_SZ, + single_ent ? qdr_dds : txdds_qdr + idx); + } +} + +#define KR_AHB_ACC KREG_IDX(ahb_access_ctrl) +#define KR_AHB_TRANS KREG_IDX(ahb_transaction_reg) +#define AHB_TRANS_RDY SYM_MASK(ahb_transaction_reg, ahb_rdy) +#define AHB_ADDR_LSB SYM_LSB(ahb_transaction_reg, ahb_address) +#define AHB_DATA_LSB SYM_LSB(ahb_transaction_reg, ahb_data) +#define AHB_WR SYM_MASK(ahb_transaction_reg, write_not_read) +#define AHB_TRANS_TRIES 10 + +/* + * The chan argument is 0=chan0, 1=chan1, 2=pll, 3=chan2, 4=chan4, + * 5=subsystem which is why most calls have "chan + chan >> 1" + * for the channel argument. + */ +static u32 ahb_mod(struct qib_devdata *dd, int quad, int chan, int addr, + u32 data, u32 mask) +{ + u32 rd_data, wr_data, sz_mask; + u64 trans, acc, prev_acc; + u32 ret = 0xBAD0BAD; + int tries; + + prev_acc = qib_read_kreg64(dd, KR_AHB_ACC); + /* From this point on, make sure we return access */ + acc = (quad << 1) | 1; + qib_write_kreg(dd, KR_AHB_ACC, acc); + + for (tries = 1; tries < AHB_TRANS_TRIES; ++tries) { + trans = qib_read_kreg64(dd, KR_AHB_TRANS); + if (trans & AHB_TRANS_RDY) + break; + } + if (tries >= AHB_TRANS_TRIES) { + qib_dev_err(dd, "No ahb_rdy in %d tries\n", AHB_TRANS_TRIES); + goto bail; + } + + /* If mask is not all 1s, we need to read, but different SerDes + * entities have different sizes + */ + sz_mask = (1UL << ((quad == 1) ? 32 : 16)) - 1; + wr_data = data & mask & sz_mask; + if ((~mask & sz_mask) != 0) { + trans = ((chan << 6) | addr) << (AHB_ADDR_LSB + 1); + qib_write_kreg(dd, KR_AHB_TRANS, trans); + + for (tries = 1; tries < AHB_TRANS_TRIES; ++tries) { + trans = qib_read_kreg64(dd, KR_AHB_TRANS); + if (trans & AHB_TRANS_RDY) + break; + } + if (tries >= AHB_TRANS_TRIES) { + qib_dev_err(dd, "No Rd ahb_rdy in %d tries\n", + AHB_TRANS_TRIES); + goto bail; + } + /* Re-read in case host split reads and read data first */ + trans = qib_read_kreg64(dd, KR_AHB_TRANS); + rd_data = (uint32_t)(trans >> AHB_DATA_LSB); + wr_data |= (rd_data & ~mask & sz_mask); + } + + /* If mask is not zero, we need to write. */ + if (mask & sz_mask) { + trans = ((chan << 6) | addr) << (AHB_ADDR_LSB + 1); + trans |= ((uint64_t)wr_data << AHB_DATA_LSB); + trans |= AHB_WR; + qib_write_kreg(dd, KR_AHB_TRANS, trans); + + for (tries = 1; tries < AHB_TRANS_TRIES; ++tries) { + trans = qib_read_kreg64(dd, KR_AHB_TRANS); + if (trans & AHB_TRANS_RDY) + break; + } + if (tries >= AHB_TRANS_TRIES) { + qib_dev_err(dd, "No Wr ahb_rdy in %d tries\n", + AHB_TRANS_TRIES); + goto bail; + } + } + ret = wr_data; +bail: + qib_write_kreg(dd, KR_AHB_ACC, prev_acc); + return ret; +} + +static void ibsd_wr_allchans(struct qib_pportdata *ppd, int addr, unsigned data, + unsigned mask) +{ + struct qib_devdata *dd = ppd->dd; + int chan; + u32 rbc; + + for (chan = 0; chan < SERDES_CHANS; ++chan) { + ahb_mod(dd, IBSD(ppd->hw_pidx), (chan + (chan >> 1)), addr, + data, mask); + rbc = ahb_mod(dd, IBSD(ppd->hw_pidx), (chan + (chan >> 1)), + addr, 0, 0); + } +} + +static int serdes_7322_init(struct qib_pportdata *ppd) +{ + u64 data; + u32 le_val; + + /* + * Initialize the Tx DDS tables. Also done every QSFP event, + * for adapters with QSFP + */ + init_txdds_table(ppd, 0); + + /* Patch some SerDes defaults to "Better for IB" */ + /* Timing Loop Bandwidth: cdr_timing[11:9] = 0 */ + ibsd_wr_allchans(ppd, 2, 0, BMASK(11, 9)); + + /* Termination: rxtermctrl_r2d addr 11 bits [12:11] = 1 */ + ibsd_wr_allchans(ppd, 11, (1 << 11), BMASK(12, 11)); + /* Enable LE2: rxle2en_r2a addr 13 bit [6] = 1 */ + ibsd_wr_allchans(ppd, 13, (1 << 6), (1 << 6)); + + /* May be overridden in qsfp_7322_event */ + le_val = IS_QME(ppd->dd) ? LE2_QME : LE2_DEFAULT; + ibsd_wr_allchans(ppd, 13, (le_val << 7), BMASK(9, 7)); + + /* enable LE1 adaptation for all but QME, which is disabled */ + le_val = IS_QME(ppd->dd) ? 0 : 1; + ibsd_wr_allchans(ppd, 13, (le_val << 5), (1 << 5)); + + /* Clear cmode-override, may be set from older driver */ + ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), 5, 10, 0 << 14, 1 << 14); + + /* Timing Recovery: rxtapsel addr 5 bits [9:8] = 0 */ + ibsd_wr_allchans(ppd, 5, (0 << 8), BMASK(9, 8)); + + /* setup LoS params; these are subsystem, so chan == 5 */ + /* LoS filter threshold_count on, ch 0-3, set to 8 */ + ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), 5, 5, 8 << 11, BMASK(14, 11)); + ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), 5, 7, 8 << 4, BMASK(7, 4)); + ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), 5, 8, 8 << 11, BMASK(14, 11)); + ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), 5, 10, 8 << 4, BMASK(7, 4)); + + /* LoS filter threshold_count off, ch 0-3, set to 4 */ + ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), 5, 6, 4 << 0, BMASK(3, 0)); + ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), 5, 7, 4 << 8, BMASK(11, 8)); + ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), 5, 9, 4 << 0, BMASK(3, 0)); + ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), 5, 10, 4 << 8, BMASK(11, 8)); + + /* LoS filter select enabled */ + ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), 5, 9, 1 << 15, 1 << 15); + + /* LoS target data: SDR=4, DDR=2, QDR=1 */ + ibsd_wr_allchans(ppd, 14, (1 << 3), BMASK(5, 3)); /* QDR */ + ibsd_wr_allchans(ppd, 20, (2 << 10), BMASK(12, 10)); /* DDR */ + ibsd_wr_allchans(ppd, 20, (4 << 13), BMASK(15, 13)); /* SDR */ + + data = qib_read_kreg_port(ppd, krp_serdesctrl); + qib_write_kreg_port(ppd, krp_serdesctrl, data | + SYM_MASK(IBSerdesCtrl_0, RXLOSEN)); + + /* rxbistena; set 0 to avoid effects of it switch later */ + ibsd_wr_allchans(ppd, 9, 0 << 15, 1 << 15); + + /* Configure 4 DFE taps, and only they adapt */ + ibsd_wr_allchans(ppd, 16, 0 << 0, BMASK(1, 0)); + + /* gain hi stop 32 (22) (6:1) lo stop 7 (10:7) target 22 (13) (15:11) */ + le_val = (ppd->dd->cspec->r1 || IS_QME(ppd->dd)) ? 0xb6c0 : 0x6bac; + ibsd_wr_allchans(ppd, 21, le_val, 0xfffe); + + /* + * Set receive adaptation mode. SDR and DDR adaptation are + * always on, and QDR is initially enabled; later disabled. + */ + qib_write_kreg_port(ppd, krp_static_adapt_dis(0), 0ULL); + qib_write_kreg_port(ppd, krp_static_adapt_dis(1), 0ULL); + qib_write_kreg_port(ppd, krp_static_adapt_dis(2), + ppd->dd->cspec->r1 ? + QDR_STATIC_ADAPT_DOWN_R1 : QDR_STATIC_ADAPT_DOWN); + ppd->cpspec->qdr_dfe_on = 1; + + /* (FLoop LOS gate: PPM filter enabled */ + ibsd_wr_allchans(ppd, 38, 0 << 10, 1 << 10); + + /* rx offset center enabled */ + ibsd_wr_allchans(ppd, 12, 1 << 4, 1 << 4); + + if (!ppd->dd->cspec->r1) { + ibsd_wr_allchans(ppd, 12, 1 << 12, 1 << 12); + ibsd_wr_allchans(ppd, 12, 2 << 8, 0x0f << 8); + } + + /* Set the frequency loop bandwidth to 15 */ + ibsd_wr_allchans(ppd, 2, 15 << 5, BMASK(8, 5)); + + return 0; +} + +/* start adjust QMH serdes parameters */ + +static void set_man_code(struct qib_pportdata *ppd, int chan, int code) +{ + ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), (chan + (chan >> 1)), + 9, code << 9, 0x3f << 9); +} + +static void set_man_mode_h1(struct qib_pportdata *ppd, int chan, + int enable, u32 tapenable) +{ + if (enable) + ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), (chan + (chan >> 1)), + 1, 3 << 10, 0x1f << 10); + else + ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), (chan + (chan >> 1)), + 1, 0, 0x1f << 10); +} + +/* Set clock to 1, 0, 1, 0 */ +static void clock_man(struct qib_pportdata *ppd, int chan) +{ + ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), (chan + (chan >> 1)), + 4, 0x4000, 0x4000); + ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), (chan + (chan >> 1)), + 4, 0, 0x4000); + ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), (chan + (chan >> 1)), + 4, 0x4000, 0x4000); + ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), (chan + (chan >> 1)), + 4, 0, 0x4000); +} + +/* + * write the current Tx serdes pre,post,main,amp settings into the serdes. + * The caller must pass the settings appropriate for the current speed, + * or not care if they are correct for the current speed. + */ +static void write_tx_serdes_param(struct qib_pportdata *ppd, + struct txdds_ent *txdds) +{ + u64 deemph; + + deemph = qib_read_kreg_port(ppd, krp_tx_deemph_override); + /* field names for amp, main, post, pre, respectively */ + deemph &= ~(SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, txampcntl_d2a) | + SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, txc0_ena) | + SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, txcp1_ena) | + SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, txcn1_ena)); + deemph |= 1ULL << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, + tx_override_deemphasis_select); + deemph |= txdds->amp << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, + txampcntl_d2a); + deemph |= txdds->main << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, + txc0_ena); + deemph |= txdds->post << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, + txcp1_ena); + deemph |= txdds->pre << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, + txcn1_ena); + qib_write_kreg_port(ppd, krp_tx_deemph_override, deemph); +} + +/* + * set per-bay, per channel parameters. For now, we ignore + * do_tx, and always set tx parameters, and set them with the same value + * for all channels, using the channel 0 value. We may switch to + * per-channel settings in the future, and that method only needs + * to be done once. + * Because this also writes the IBC txdds table with a single set + * of values, it should be called only for cases where we want to completely + * force a specific setting, typically only for mez cards. + */ +static void adj_tx_serdes(struct qib_pportdata *ppd) +{ + struct txdds_ent txdds; + int i; + u8 *amp, *pre, *mainv, *post; + + /* + * Because we use TX_DEEMPHASIS_OVERRIDE, we need to + * always do tx side, just like H1, since it is cleared + * by link down + */ + amp = ppd->cpspec->amp; + pre = ppd->cpspec->pre; + mainv = ppd->cpspec->mainv; + post = ppd->cpspec->post; + + amp[0] &= SYM_RMASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, + txampcntl_d2a); + mainv[0] &= SYM_RMASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, + txc0_ena); + post[0] &= SYM_RMASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, + txcp1_ena); + pre[0] &= SYM_RMASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, + txcn1_ena); + + /* + * Use the channel zero values, only, for now, for + * all channels + */ + txdds.amp = amp[0]; + txdds.pre = pre[0]; + txdds.main = mainv[0]; + txdds.post = post[0]; + + /* write the QDR table for IBC use, as backup for link down */ + for (i = 0; i < ARRAY_SIZE(txdds_qdr); ++i) + set_txdds(ppd, i + 32, &txdds); + + write_tx_serdes_param(ppd, &txdds); +} + +/* set QDR forced value for H1, if needed */ +static void force_h1(struct qib_pportdata *ppd) +{ + int chan; + + ppd->cpspec->qdr_reforce = 0; + if (!ppd->dd->cspec->r1) + return; + + for (chan = 0; chan < SERDES_CHANS; chan++) { + set_man_mode_h1(ppd, chan, 1, 0); + set_man_code(ppd, chan, ppd->cpspec->h1_val); + clock_man(ppd, chan); + set_man_mode_h1(ppd, chan, 0, 0); + } +} + +/* + * Parse the parameters for the QMH7342, to get rx and tx serdes + * settings for that Bay, for both possible mez connectors (PCIe bus) + * and IB link (one link on mez1, two possible on mez2). + * + * Data is comma or white space separated. + * + * A set of data has 7 groups, rx and tx groups have SERDES_CHANS values, + * one per IB lane (serdes channel). + * The groups are Bay, bus# H1 rcv, and amp, pre, post, main Tx values (QDR). + * The Bay # is used only for debugging currently. + * H1 values are set whenever the link goes down, or is at cfg_test or + * cfg_wait_enh. Tx values are programmed once, when this routine is called + * (and with default values at chip initialization). Values are any base, in + * strtoul style, and values are seperated by comma, or any white space + * (space, tab, newline). + * + * An example set might look like this (white space vs + * comma used for human ease of reading) + * The ordering is a set of Bay# Bus# H1, amp, pre, post, and main for mez1 IB1, + * repeat for mez2 IB1, then mez2 IB2. + * + * B B H1:0 amp:0 pre:0 post: 0 main:0 + * a u H1: 1 amp: 1 pre: 1 post: 1 main: 1 + * y s H1: 2 amp: 2 pre: 2 post: 2 main: 2 + * H1: 4 amp: 3 pre: 3 post: 3 main: 3 + * 1 3 8,6,5,6 0,0,0,0 1,1,1,1 10,10,10,10 3,3,3,3 + * 1 6 7,6,6,7 0,0,0,0 1,1,1,1 10,10,10,10 3,3,3,3 + * 1 6 9,7,7,8 0,0,0,0 1,1,1,1 10,10,10,10 3,3,3,3 + */ +#define N_QMH_FIELDS 22 +static int setup_qmh_params(const char *str, struct kernel_param *kp) +{ + char *abuf, *v, *nv, *nvp; + struct qib_devdata *dd; + struct qib_pportdata *ppd; + u32 mez, vlen, nf, port, bay; + int ret = 0, found = 0; + + vlen = strlen(str) + 1; + abuf = kmalloc(vlen, GFP_KERNEL); + if (!abuf) { + printk(KERN_INFO QIB_DRV_NAME + " Unable to allocate QMH param buffer; ignoring\n"); + return 0; + } + memcpy(abuf, str, vlen); + v = abuf; + + /* these 3 are because gcc can't know they are set before used */ + port = 1; + mez = 1; /* used only for debugging */ + bay = 0; /* used only for debugging */ + ppd = NULL; + for (nf = 0; (nv = strsep(&v, ", \t\n\r")) && + nf < (N_QMH_FIELDS * 3);) { + u32 val; + + if (!*nv) + /* allow for multiple separators */ + continue; + + val = simple_strtoul(nv, &nvp, 0); + if (nv == nvp) { + printk(KERN_INFO QIB_DRV_NAME + " Bay%u, mez%u IB%u non-numeric value (%s) " + "field #%u, ignoring rest\n", bay, mez, + port, nv, nf % (N_QMH_FIELDS * 3)); + ret = -EINVAL; + goto bail; + } + if (!(nf % N_QMH_FIELDS)) { + ppd = NULL; + bay = val; + if (!bay || bay > 16) { + printk(KERN_INFO QIB_DRV_NAME + " Invalid bay # %u, field %u, " + "ignoring rest\n", bay, nf); + ret = -EINVAL; + goto bail; + } + } else if ((nf % N_QMH_FIELDS) == 1) { + u32 bus = val; + if (nf == 1) { + mez = 1; + port = 1; + } else if (nf == (N_QMH_FIELDS + 1)) { + mez = 2; + port = 1; + } else { + mez = 2; + port = 2; + } + list_for_each_entry(dd, &qib_dev_list, list) { + if (dd->deviceid != PCI_DEVICE_ID_QLOGIC_IB_7322 + || !IS_QMH(dd)) + continue; /* only for QMH cards */ + if (dd->pcidev->bus->number == bus) { + found++; + ppd = &dd->pport[port - 1]; + } + } + } else if (ppd) { + u32 parm = (nf % N_QMH_FIELDS) - 2; + if (parm < SERDES_CHANS && !(parm % SERDES_CHANS)) + ppd->cpspec->h1_val = val; + else if (parm < (2 * SERDES_CHANS)) + ppd->cpspec->amp[parm % SERDES_CHANS] = val; + else if (parm < (3 * SERDES_CHANS)) + ppd->cpspec->pre[parm % SERDES_CHANS] = val; + else if (parm < (4 * SERDES_CHANS)) + ppd->cpspec->post[parm % SERDES_CHANS] = val; + else { + ppd->cpspec->mainv[parm % SERDES_CHANS] = val; + /* At the end of a port, set params */ + if (parm == ((5 * SERDES_CHANS) - 1)) + adj_tx_serdes(ppd); + } + } + nf++; + } + if (!found) { + printk(KERN_ERR QIB_DRV_NAME + ": No match found for qmh_serdes_setup parameter\n"); + ret = -EINVAL; + } +bail: + kfree(abuf); + return ret; +} + +/* + * Similarly for QME7342, but the format is simpler, values are the + * same for all mez card positions in a blade (2 or 4 per blade), but + * are different for some blades vs others, and we don't need to + * specify different parameters for different serdes channels or different + * IB ports. + * Format is: h1 amp,pre,post,main + * Alternate format (so ports can be different): Pport# h1 amp,pre,post,main + */ +#define N_QME_FIELDS 5 +static int setup_qme_params(const char *str, struct kernel_param *kp) +{ + char *abuf, *v, *nv, *nvp; + struct qib_devdata *dd; + u32 vlen, nf, port = 0; + u8 h1, tx[4]; /* amp, pre, post, main */ + int ret = -EINVAL; + char *seplist; + + vlen = strlen(str) + 1; + abuf = kmalloc(vlen, GFP_KERNEL); + if (!abuf) { + printk(KERN_INFO QIB_DRV_NAME + " Unable to allocate QME param buffer; ignoring\n"); + return 0; + } + strncpy(abuf, str, vlen); + + v = abuf; + seplist = " \t"; + h1 = H1_FORCE_QME; /* gcc can't figure out always set before used */ + + for (nf = 0; (nv = strsep(&v, seplist)); ) { + u32 val; + + if (!*nv) + /* allow for multiple separators */ + continue; + + if (!nf && *nv == 'P') { + /* alternate format with port */ + val = simple_strtoul(++nv, &nvp, 0); + if (nv == nvp || port >= NUM_IB_PORTS) { + printk(KERN_INFO QIB_DRV_NAME + " %s: non-numeric port value (%s) " + "ignoring rest\n", __func__, nv); + goto done; + } + port = val; + continue; /* without incrementing nf */ + } + val = simple_strtoul(nv, &nvp, 0); + if (nv == nvp) { + printk(KERN_INFO QIB_DRV_NAME + " %s: non-numeric value (%s) " + "field #%u, ignoring rest\n", __func__, + nv, nf); + goto done; + } + if (!nf) { + h1 = val; + seplist = ","; + } else + tx[nf - 1] = val; + if (++nf == N_QME_FIELDS) { + list_for_each_entry(dd, &qib_dev_list, list) { + int pidx, i; + if (dd->deviceid != PCI_DEVICE_ID_QLOGIC_IB_7322 + || !IS_QME(dd)) + continue; /* only for QME cards */ + for (pidx = 0; pidx < dd->num_pports; ++pidx) { + struct qib_pportdata *ppd; + ppd = &dd->pport[pidx]; + if ((port && ppd->port != port) || + !ppd->link_speed_supported) + continue; + ppd->cpspec->h1_val = h1; + for (i = 0; i < SERDES_CHANS; i++) { + ppd->cpspec->amp[i] = tx[0]; + ppd->cpspec->pre[i] = tx[1]; + ppd->cpspec->post[i] = tx[2]; + ppd->cpspec->mainv[i] = tx[3]; + } + adj_tx_serdes(ppd); + } + } + ret = 0; + goto done; + } + } + printk(KERN_INFO QIB_DRV_NAME + " %s: Only %u of %u fields provided, skipping\n", + __func__, nf, N_QME_FIELDS); +done: + kfree(abuf); + return ret; +} + +#define SJA_EN SYM_MASK(SPC_JTAG_ACCESS_REG, SPC_JTAG_ACCESS_EN) +#define BISTEN_LSB SYM_LSB(SPC_JTAG_ACCESS_REG, bist_en) + +#define R_OPCODE_LSB 3 +#define R_OP_NOP 0 +#define R_OP_SHIFT 2 +#define R_OP_UPDATE 3 +#define R_TDI_LSB 2 +#define R_TDO_LSB 1 +#define R_RDY 1 + +static int qib_r_grab(struct qib_devdata *dd) +{ + u64 val; + val = SJA_EN; + qib_write_kreg(dd, kr_r_access, val); + qib_read_kreg32(dd, kr_scratch); + return 0; +} + +/* qib_r_wait_for_rdy() not only waits for the ready bit, it + * returns the current state of R_TDO + */ +static int qib_r_wait_for_rdy(struct qib_devdata *dd) +{ + u64 val; + int timeout; + for (timeout = 0; timeout < 100 ; ++timeout) { + val = qib_read_kreg32(dd, kr_r_access); + if (val & R_RDY) + return (val >> R_TDO_LSB) & 1; + } + return -1; +} + +static int qib_r_shift(struct qib_devdata *dd, int bisten, + int len, u8 *inp, u8 *outp) +{ + u64 valbase, val; + int ret, pos; + + valbase = SJA_EN | (bisten << BISTEN_LSB) | + (R_OP_SHIFT << R_OPCODE_LSB); + ret = qib_r_wait_for_rdy(dd); + if (ret < 0) + goto bail; + for (pos = 0; pos < len; ++pos) { + val = valbase; + if (outp) { + outp[pos >> 3] &= ~(1 << (pos & 7)); + outp[pos >> 3] |= (ret << (pos & 7)); + } + if (inp) { + int tdi = inp[pos >> 3] >> (pos & 7); + val |= ((tdi & 1) << R_TDI_LSB); + } + qib_write_kreg(dd, kr_r_access, val); + qib_read_kreg32(dd, kr_scratch); + ret = qib_r_wait_for_rdy(dd); + if (ret < 0) + break; + } + /* Restore to NOP between operations. */ + val = SJA_EN | (bisten << BISTEN_LSB); + qib_write_kreg(dd, kr_r_access, val); + qib_read_kreg32(dd, kr_scratch); + ret = qib_r_wait_for_rdy(dd); + + if (ret >= 0) + ret = pos; +bail: + return ret; +} + +static int qib_r_update(struct qib_devdata *dd, int bisten) +{ + u64 val; + int ret; + + val = SJA_EN | (bisten << BISTEN_LSB) | (R_OP_UPDATE << R_OPCODE_LSB); + ret = qib_r_wait_for_rdy(dd); + if (ret >= 0) { + qib_write_kreg(dd, kr_r_access, val); + qib_read_kreg32(dd, kr_scratch); + } + return ret; +} + +#define BISTEN_PORT_SEL 15 +#define LEN_PORT_SEL 625 +#define BISTEN_AT 17 +#define LEN_AT 156 +#define BISTEN_ETM 16 +#define LEN_ETM 632 + +#define BIT2BYTE(x) (((x) + BITS_PER_BYTE - 1) / BITS_PER_BYTE) + +/* these are common for all IB port use cases. */ +static u8 reset_at[BIT2BYTE(LEN_AT)] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, +}; +static u8 reset_atetm[BIT2BYTE(LEN_ETM)] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0xe3, 0x81, 0x73, 0x3c, 0x70, 0x8e, + 0x07, 0xce, 0xf1, 0xc0, 0x39, 0x1e, 0x38, 0xc7, 0x03, 0xe7, + 0x78, 0xe0, 0x1c, 0x0f, 0x9c, 0x7f, 0x80, 0x73, 0x0f, 0x70, + 0xde, 0x01, 0xce, 0x39, 0xc0, 0xf9, 0x06, 0x38, 0xd7, 0x00, + 0xe7, 0x19, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, +}; +static u8 at[BIT2BYTE(LEN_AT)] = { + 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, +}; + +/* used for IB1 or IB2, only one in use */ +static u8 atetm_1port[BIT2BYTE(LEN_ETM)] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0xf2, 0x80, 0x83, 0x1e, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x50, 0xf4, 0x41, 0x00, 0x18, 0x78, 0xc8, 0x03, + 0x07, 0x7b, 0xa0, 0x3e, 0x00, 0x02, 0x00, 0x00, 0x18, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, +}; + +/* used when both IB1 and IB2 are in use */ +static u8 atetm_2port[BIT2BYTE(LEN_ETM)] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0x80, 0x83, 0x1e, 0x38, 0xe0, 0x03, 0x05, + 0x7b, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xa2, 0x0f, 0x50, 0xf4, 0x41, 0x00, 0x18, 0x78, 0xd1, 0x07, + 0x02, 0x7c, 0x80, 0x3e, 0x00, 0x02, 0x00, 0x00, 0x3e, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, +}; + +/* used when only IB1 is in use */ +static u8 portsel_port1[BIT2BYTE(LEN_PORT_SEL)] = { + 0x32, 0x65, 0xa4, 0x7b, 0x10, 0x98, 0xdc, 0xfe, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x73, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x78, 0x78, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x74, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x14, 0x14, 0x9f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +/* used when only IB2 is in use */ +static u8 portsel_port2[BIT2BYTE(LEN_PORT_SEL)] = { + 0x32, 0x65, 0xa4, 0x7b, 0x10, 0x98, 0xdc, 0xfe, 0x39, 0x39, + 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x73, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, + 0x39, 0x78, 0x78, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, + 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x74, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, + 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, + 0x3a, 0x3a, 0x9f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, +}; + +/* used when both IB1 and IB2 are in use */ +static u8 portsel_2port[BIT2BYTE(LEN_PORT_SEL)] = { + 0x32, 0xba, 0x54, 0x76, 0x10, 0x98, 0xdc, 0xfe, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x73, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x74, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x14, 0x14, 0x14, 0x14, 0x14, 0x3a, + 0x3a, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, + 0x14, 0x14, 0x9f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +/* + * Do setup to properly handle IB link recovery; if port is zero, we + * are initializing to cover both ports; otherwise we are initializing + * to cover a single port card, or the port has reached INIT and we may + * need to switch coverage types. + */ +static void setup_7322_link_recovery(struct qib_pportdata *ppd, u32 both) +{ + u8 *portsel, *etm; + struct qib_devdata *dd = ppd->dd; + + if (!ppd->dd->cspec->r1) + return; + if (!both) { + dd->cspec->recovery_ports_initted++; + ppd->cpspec->recovery_init = 1; + } + if (!both && dd->cspec->recovery_ports_initted == 1) { + portsel = ppd->port == 1 ? portsel_port1 : portsel_port2; + etm = atetm_1port; + } else { + portsel = portsel_2port; + etm = atetm_2port; + } + + if (qib_r_grab(dd) < 0 || + qib_r_shift(dd, BISTEN_ETM, LEN_ETM, reset_atetm, NULL) < 0 || + qib_r_update(dd, BISTEN_ETM) < 0 || + qib_r_shift(dd, BISTEN_AT, LEN_AT, reset_at, NULL) < 0 || + qib_r_update(dd, BISTEN_AT) < 0 || + qib_r_shift(dd, BISTEN_PORT_SEL, LEN_PORT_SEL, + portsel, NULL) < 0 || + qib_r_update(dd, BISTEN_PORT_SEL) < 0 || + qib_r_shift(dd, BISTEN_AT, LEN_AT, at, NULL) < 0 || + qib_r_update(dd, BISTEN_AT) < 0 || + qib_r_shift(dd, BISTEN_ETM, LEN_ETM, etm, NULL) < 0 || + qib_r_update(dd, BISTEN_ETM) < 0) + qib_dev_err(dd, "Failed IB link recovery setup\n"); +} + +static void check_7322_rxe_status(struct qib_pportdata *ppd) +{ + struct qib_devdata *dd = ppd->dd; + u64 fmask; + + if (dd->cspec->recovery_ports_initted != 1) + return; /* rest doesn't apply to dualport */ + qib_write_kreg(dd, kr_control, dd->control | + SYM_MASK(Control, FreezeMode)); + (void)qib_read_kreg64(dd, kr_scratch); + udelay(3); /* ibcreset asserted 400ns, be sure that's over */ + fmask = qib_read_kreg64(dd, kr_act_fmask); + if (!fmask) { + /* + * require a powercycle before we'll work again, and make + * sure we get no more interrupts, and don't turn off + * freeze. + */ + ppd->dd->cspec->stay_in_freeze = 1; + qib_7322_set_intr_state(ppd->dd, 0); + qib_write_kreg(dd, kr_fmask, 0ULL); + qib_dev_err(dd, "HCA unusable until powercycled\n"); + return; /* eventually reset */ + } + + qib_write_kreg(ppd->dd, kr_hwerrclear, + SYM_MASK(HwErrClear, IBSerdesPClkNotDetectClear_1)); + + /* don't do the full clear_freeze(), not needed for this */ + qib_write_kreg(dd, kr_control, dd->control); + qib_read_kreg32(dd, kr_scratch); + /* take IBC out of reset */ + if (ppd->link_speed_supported) { + ppd->cpspec->ibcctrl_a &= + ~SYM_MASK(IBCCtrlA_0, IBStatIntReductionEn); + qib_write_kreg_port(ppd, krp_ibcctrl_a, + ppd->cpspec->ibcctrl_a); + qib_read_kreg32(dd, kr_scratch); + if (ppd->lflags & QIBL_IB_LINK_DISABLED) + qib_set_ib_7322_lstate(ppd, 0, + QLOGIC_IB_IBCC_LINKINITCMD_DISABLE); + } +} diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c new file mode 100644 index 000000000000..c0139c07e97e --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_init.c @@ -0,0 +1,1580 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation. + * All rights reserved. + * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include "qib.h" +#include "qib_common.h" + +/* + * min buffers we want to have per context, after driver + */ +#define QIB_MIN_USER_CTXT_BUFCNT 7 + +#define QLOGIC_IB_R_SOFTWARE_MASK 0xFF +#define QLOGIC_IB_R_SOFTWARE_SHIFT 24 +#define QLOGIC_IB_R_EMULATOR_MASK (1ULL<<62) + +/* + * Number of ctxts we are configured to use (to allow for more pio + * buffers per ctxt, etc.) Zero means use chip value. + */ +ushort qib_cfgctxts; +module_param_named(cfgctxts, qib_cfgctxts, ushort, S_IRUGO); +MODULE_PARM_DESC(cfgctxts, "Set max number of contexts to use"); + +/* + * If set, do not write to any regs if avoidable, hack to allow + * check for deranged default register values. + */ +ushort qib_mini_init; +module_param_named(mini_init, qib_mini_init, ushort, S_IRUGO); +MODULE_PARM_DESC(mini_init, "If set, do minimal diag init"); + +unsigned qib_n_krcv_queues; +module_param_named(krcvqs, qib_n_krcv_queues, uint, S_IRUGO); +MODULE_PARM_DESC(krcvqs, "number of kernel receive queues per IB port"); + +/* + * qib_wc_pat parameter: + * 0 is WC via MTRR + * 1 is WC via PAT + * If PAT initialization fails, code reverts back to MTRR + */ +unsigned qib_wc_pat = 1; /* default (1) is to use PAT, not MTRR */ +module_param_named(wc_pat, qib_wc_pat, uint, S_IRUGO); +MODULE_PARM_DESC(wc_pat, "enable write-combining via PAT mechanism"); + +struct workqueue_struct *qib_wq; +struct workqueue_struct *qib_cq_wq; + +static void verify_interrupt(unsigned long); + +static struct idr qib_unit_table; +u32 qib_cpulist_count; +unsigned long *qib_cpulist; + +/* set number of contexts we'll actually use */ +void qib_set_ctxtcnt(struct qib_devdata *dd) +{ + if (!qib_cfgctxts) + dd->cfgctxts = dd->ctxtcnt; + else if (qib_cfgctxts < dd->num_pports) + dd->cfgctxts = dd->ctxtcnt; + else if (qib_cfgctxts <= dd->ctxtcnt) + dd->cfgctxts = qib_cfgctxts; + else + dd->cfgctxts = dd->ctxtcnt; +} + +/* + * Common code for creating the receive context array. + */ +int qib_create_ctxts(struct qib_devdata *dd) +{ + unsigned i; + int ret; + + /* + * Allocate full ctxtcnt array, rather than just cfgctxts, because + * cleanup iterates across all possible ctxts. + */ + dd->rcd = kzalloc(sizeof(*dd->rcd) * dd->ctxtcnt, GFP_KERNEL); + if (!dd->rcd) { + qib_dev_err(dd, "Unable to allocate ctxtdata array, " + "failing\n"); + ret = -ENOMEM; + goto done; + } + + /* create (one or more) kctxt */ + for (i = 0; i < dd->first_user_ctxt; ++i) { + struct qib_pportdata *ppd; + struct qib_ctxtdata *rcd; + + if (dd->skip_kctxt_mask & (1 << i)) + continue; + + ppd = dd->pport + (i % dd->num_pports); + rcd = qib_create_ctxtdata(ppd, i); + if (!rcd) { + qib_dev_err(dd, "Unable to allocate ctxtdata" + " for Kernel ctxt, failing\n"); + ret = -ENOMEM; + goto done; + } + rcd->pkeys[0] = QIB_DEFAULT_P_KEY; + rcd->seq_cnt = 1; + } + ret = 0; +done: + return ret; +} + +/* + * Common code for user and kernel context setup. + */ +struct qib_ctxtdata *qib_create_ctxtdata(struct qib_pportdata *ppd, u32 ctxt) +{ + struct qib_devdata *dd = ppd->dd; + struct qib_ctxtdata *rcd; + + rcd = kzalloc(sizeof(*rcd), GFP_KERNEL); + if (rcd) { + INIT_LIST_HEAD(&rcd->qp_wait_list); + rcd->ppd = ppd; + rcd->dd = dd; + rcd->cnt = 1; + rcd->ctxt = ctxt; + dd->rcd[ctxt] = rcd; + + dd->f_init_ctxt(rcd); + + /* + * To avoid wasting a lot of memory, we allocate 32KB chunks + * of physically contiguous memory, advance through it until + * used up and then allocate more. Of course, we need + * memory to store those extra pointers, now. 32KB seems to + * be the most that is "safe" under memory pressure + * (creating large files and then copying them over + * NFS while doing lots of MPI jobs). The OOM killer can + * get invoked, even though we say we can sleep and this can + * cause significant system problems.... + */ + rcd->rcvegrbuf_size = 0x8000; + rcd->rcvegrbufs_perchunk = + rcd->rcvegrbuf_size / dd->rcvegrbufsize; + rcd->rcvegrbuf_chunks = (rcd->rcvegrcnt + + rcd->rcvegrbufs_perchunk - 1) / + rcd->rcvegrbufs_perchunk; + } + return rcd; +} + +/* + * Common code for initializing the physical port structure. + */ +void qib_init_pportdata(struct qib_pportdata *ppd, struct qib_devdata *dd, + u8 hw_pidx, u8 port) +{ + ppd->dd = dd; + ppd->hw_pidx = hw_pidx; + ppd->port = port; /* IB port number, not index */ + + spin_lock_init(&ppd->sdma_lock); + spin_lock_init(&ppd->lflags_lock); + init_waitqueue_head(&ppd->state_wait); + + init_timer(&ppd->symerr_clear_timer); + ppd->symerr_clear_timer.function = qib_clear_symerror_on_linkup; + ppd->symerr_clear_timer.data = (unsigned long)ppd; +} + +static int init_pioavailregs(struct qib_devdata *dd) +{ + int ret, pidx; + u64 *status_page; + + dd->pioavailregs_dma = dma_alloc_coherent( + &dd->pcidev->dev, PAGE_SIZE, &dd->pioavailregs_phys, + GFP_KERNEL); + if (!dd->pioavailregs_dma) { + qib_dev_err(dd, "failed to allocate PIOavail reg area " + "in memory\n"); + ret = -ENOMEM; + goto done; + } + + /* + * We really want L2 cache aligned, but for current CPUs of + * interest, they are the same. + */ + status_page = (u64 *) + ((char *) dd->pioavailregs_dma + + ((2 * L1_CACHE_BYTES + + dd->pioavregs * sizeof(u64)) & ~L1_CACHE_BYTES)); + /* device status comes first, for backwards compatibility */ + dd->devstatusp = status_page; + *status_page++ = 0; + for (pidx = 0; pidx < dd->num_pports; ++pidx) { + dd->pport[pidx].statusp = status_page; + *status_page++ = 0; + } + + /* + * Setup buffer to hold freeze and other messages, accessible to + * apps, following statusp. This is per-unit, not per port. + */ + dd->freezemsg = (char *) status_page; + *dd->freezemsg = 0; + /* length of msg buffer is "whatever is left" */ + ret = (char *) status_page - (char *) dd->pioavailregs_dma; + dd->freezelen = PAGE_SIZE - ret; + + ret = 0; + +done: + return ret; +} + +/** + * init_shadow_tids - allocate the shadow TID array + * @dd: the qlogic_ib device + * + * allocate the shadow TID array, so we can qib_munlock previous + * entries. It may make more sense to move the pageshadow to the + * ctxt data structure, so we only allocate memory for ctxts actually + * in use, since we at 8k per ctxt, now. + * We don't want failures here to prevent use of the driver/chip, + * so no return value. + */ +static void init_shadow_tids(struct qib_devdata *dd) +{ + struct page **pages; + dma_addr_t *addrs; + + pages = vmalloc(dd->cfgctxts * dd->rcvtidcnt * sizeof(struct page *)); + if (!pages) { + qib_dev_err(dd, "failed to allocate shadow page * " + "array, no expected sends!\n"); + goto bail; + } + + addrs = vmalloc(dd->cfgctxts * dd->rcvtidcnt * sizeof(dma_addr_t)); + if (!addrs) { + qib_dev_err(dd, "failed to allocate shadow dma handle " + "array, no expected sends!\n"); + goto bail_free; + } + + memset(pages, 0, dd->cfgctxts * dd->rcvtidcnt * sizeof(struct page *)); + memset(addrs, 0, dd->cfgctxts * dd->rcvtidcnt * sizeof(dma_addr_t)); + + dd->pageshadow = pages; + dd->physshadow = addrs; + return; + +bail_free: + vfree(pages); +bail: + dd->pageshadow = NULL; +} + +/* + * Do initialization for device that is only needed on + * first detect, not on resets. + */ +static int loadtime_init(struct qib_devdata *dd) +{ + int ret = 0; + + if (((dd->revision >> QLOGIC_IB_R_SOFTWARE_SHIFT) & + QLOGIC_IB_R_SOFTWARE_MASK) != QIB_CHIP_SWVERSION) { + qib_dev_err(dd, "Driver only handles version %d, " + "chip swversion is %d (%llx), failng\n", + QIB_CHIP_SWVERSION, + (int)(dd->revision >> + QLOGIC_IB_R_SOFTWARE_SHIFT) & + QLOGIC_IB_R_SOFTWARE_MASK, + (unsigned long long) dd->revision); + ret = -ENOSYS; + goto done; + } + + if (dd->revision & QLOGIC_IB_R_EMULATOR_MASK) + qib_devinfo(dd->pcidev, "%s", dd->boardversion); + + spin_lock_init(&dd->pioavail_lock); + spin_lock_init(&dd->sendctrl_lock); + spin_lock_init(&dd->uctxt_lock); + spin_lock_init(&dd->qib_diag_trans_lock); + spin_lock_init(&dd->eep_st_lock); + mutex_init(&dd->eep_lock); + + if (qib_mini_init) + goto done; + + ret = init_pioavailregs(dd); + init_shadow_tids(dd); + + qib_get_eeprom_info(dd); + + /* setup time (don't start yet) to verify we got interrupt */ + init_timer(&dd->intrchk_timer); + dd->intrchk_timer.function = verify_interrupt; + dd->intrchk_timer.data = (unsigned long) dd; + +done: + return ret; +} + +/** + * init_after_reset - re-initialize after a reset + * @dd: the qlogic_ib device + * + * sanity check at least some of the values after reset, and + * ensure no receive or transmit (explictly, in case reset + * failed + */ +static int init_after_reset(struct qib_devdata *dd) +{ + int i; + + /* + * Ensure chip does no sends or receives, tail updates, or + * pioavail updates while we re-initialize. This is mostly + * for the driver data structures, not chip registers. + */ + for (i = 0; i < dd->num_pports; ++i) { + /* + * ctxt == -1 means "all contexts". Only really safe for + * _dis_abling things, as here. + */ + dd->f_rcvctrl(dd->pport + i, QIB_RCVCTRL_CTXT_DIS | + QIB_RCVCTRL_INTRAVAIL_DIS | + QIB_RCVCTRL_TAILUPD_DIS, -1); + /* Redundant across ports for some, but no big deal. */ + dd->f_sendctrl(dd->pport + i, QIB_SENDCTRL_SEND_DIS | + QIB_SENDCTRL_AVAIL_DIS); + } + + return 0; +} + +static void enable_chip(struct qib_devdata *dd) +{ + u64 rcvmask; + int i; + + /* + * Enable PIO send, and update of PIOavail regs to memory. + */ + for (i = 0; i < dd->num_pports; ++i) + dd->f_sendctrl(dd->pport + i, QIB_SENDCTRL_SEND_ENB | + QIB_SENDCTRL_AVAIL_ENB); + /* + * Enable kernel ctxts' receive and receive interrupt. + * Other ctxts done as user opens and inits them. + */ + rcvmask = QIB_RCVCTRL_CTXT_ENB | QIB_RCVCTRL_INTRAVAIL_ENB; + rcvmask |= (dd->flags & QIB_NODMA_RTAIL) ? + QIB_RCVCTRL_TAILUPD_DIS : QIB_RCVCTRL_TAILUPD_ENB; + for (i = 0; dd->rcd && i < dd->first_user_ctxt; ++i) { + struct qib_ctxtdata *rcd = dd->rcd[i]; + + if (rcd) + dd->f_rcvctrl(rcd->ppd, rcvmask, i); + } +} + +static void verify_interrupt(unsigned long opaque) +{ + struct qib_devdata *dd = (struct qib_devdata *) opaque; + + if (!dd) + return; /* being torn down */ + + /* + * If we don't have a lid or any interrupts, let the user know and + * don't bother checking again. + */ + if (dd->int_counter == 0) { + if (!dd->f_intr_fallback(dd)) + dev_err(&dd->pcidev->dev, "No interrupts detected, " + "not usable.\n"); + else /* re-arm the timer to see if fallback works */ + mod_timer(&dd->intrchk_timer, jiffies + HZ/2); + } +} + +static void init_piobuf_state(struct qib_devdata *dd) +{ + int i, pidx; + u32 uctxts; + + /* + * Ensure all buffers are free, and fifos empty. Buffers + * are common, so only do once for port 0. + * + * After enable and qib_chg_pioavailkernel so we can safely + * enable pioavail updates and PIOENABLE. After this, packets + * are ready and able to go out. + */ + dd->f_sendctrl(dd->pport, QIB_SENDCTRL_DISARM_ALL); + for (pidx = 0; pidx < dd->num_pports; ++pidx) + dd->f_sendctrl(dd->pport + pidx, QIB_SENDCTRL_FLUSH); + + /* + * If not all sendbufs are used, add the one to each of the lower + * numbered contexts. pbufsctxt and lastctxt_piobuf are + * calculated in chip-specific code because it may cause some + * chip-specific adjustments to be made. + */ + uctxts = dd->cfgctxts - dd->first_user_ctxt; + dd->ctxts_extrabuf = dd->pbufsctxt ? + dd->lastctxt_piobuf - (dd->pbufsctxt * uctxts) : 0; + + /* + * Set up the shadow copies of the piobufavail registers, + * which we compare against the chip registers for now, and + * the in memory DMA'ed copies of the registers. + * By now pioavail updates to memory should have occurred, so + * copy them into our working/shadow registers; this is in + * case something went wrong with abort, but mostly to get the + * initial values of the generation bit correct. + */ + for (i = 0; i < dd->pioavregs; i++) { + __le64 tmp; + + tmp = dd->pioavailregs_dma[i]; + /* + * Don't need to worry about pioavailkernel here + * because we will call qib_chg_pioavailkernel() later + * in initialization, to busy out buffers as needed. + */ + dd->pioavailshadow[i] = le64_to_cpu(tmp); + } + while (i < ARRAY_SIZE(dd->pioavailshadow)) + dd->pioavailshadow[i++] = 0; /* for debugging sanity */ + + /* after pioavailshadow is setup */ + qib_chg_pioavailkernel(dd, 0, dd->piobcnt2k + dd->piobcnt4k, + TXCHK_CHG_TYPE_KERN, NULL); + dd->f_initvl15_bufs(dd); +} + +/** + * qib_init - do the actual initialization sequence on the chip + * @dd: the qlogic_ib device + * @reinit: reinitializing, so don't allocate new memory + * + * Do the actual initialization sequence on the chip. This is done + * both from the init routine called from the PCI infrastructure, and + * when we reset the chip, or detect that it was reset internally, + * or it's administratively re-enabled. + * + * Memory allocation here and in called routines is only done in + * the first case (reinit == 0). We have to be careful, because even + * without memory allocation, we need to re-write all the chip registers + * TIDs, etc. after the reset or enable has completed. + */ +int qib_init(struct qib_devdata *dd, int reinit) +{ + int ret = 0, pidx, lastfail = 0; + u32 portok = 0; + unsigned i; + struct qib_ctxtdata *rcd; + struct qib_pportdata *ppd; + unsigned long flags; + + /* Set linkstate to unknown, so we can watch for a transition. */ + for (pidx = 0; pidx < dd->num_pports; ++pidx) { + ppd = dd->pport + pidx; + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags &= ~(QIBL_LINKACTIVE | QIBL_LINKARMED | + QIBL_LINKDOWN | QIBL_LINKINIT | + QIBL_LINKV); + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + } + + if (reinit) + ret = init_after_reset(dd); + else + ret = loadtime_init(dd); + if (ret) + goto done; + + /* Bypass most chip-init, to get to device creation */ + if (qib_mini_init) + return 0; + + ret = dd->f_late_initreg(dd); + if (ret) + goto done; + + /* dd->rcd can be NULL if early init failed */ + for (i = 0; dd->rcd && i < dd->first_user_ctxt; ++i) { + /* + * Set up the (kernel) rcvhdr queue and egr TIDs. If doing + * re-init, the simplest way to handle this is to free + * existing, and re-allocate. + * Need to re-create rest of ctxt 0 ctxtdata as well. + */ + rcd = dd->rcd[i]; + if (!rcd) + continue; + + lastfail = qib_create_rcvhdrq(dd, rcd); + if (!lastfail) + lastfail = qib_setup_eagerbufs(rcd); + if (lastfail) { + qib_dev_err(dd, "failed to allocate kernel ctxt's " + "rcvhdrq and/or egr bufs\n"); + continue; + } + } + + for (pidx = 0; pidx < dd->num_pports; ++pidx) { + int mtu; + if (lastfail) + ret = lastfail; + ppd = dd->pport + pidx; + mtu = ib_mtu_enum_to_int(qib_ibmtu); + if (mtu == -1) { + mtu = QIB_DEFAULT_MTU; + qib_ibmtu = 0; /* don't leave invalid value */ + } + /* set max we can ever have for this driver load */ + ppd->init_ibmaxlen = min(mtu > 2048 ? + dd->piosize4k : dd->piosize2k, + dd->rcvegrbufsize + + (dd->rcvhdrentsize << 2)); + /* + * Have to initialize ibmaxlen, but this will normally + * change immediately in qib_set_mtu(). + */ + ppd->ibmaxlen = ppd->init_ibmaxlen; + qib_set_mtu(ppd, mtu); + + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags |= QIBL_IB_LINK_DISABLED; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + + lastfail = dd->f_bringup_serdes(ppd); + if (lastfail) { + qib_devinfo(dd->pcidev, + "Failed to bringup IB port %u\n", ppd->port); + lastfail = -ENETDOWN; + continue; + } + + /* let link come up, and enable IBC */ + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags &= ~QIBL_IB_LINK_DISABLED; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + portok++; + } + + if (!portok) { + /* none of the ports initialized */ + if (!ret && lastfail) + ret = lastfail; + else if (!ret) + ret = -ENETDOWN; + /* but continue on, so we can debug cause */ + } + + enable_chip(dd); + + init_piobuf_state(dd); + +done: + if (!ret) { + /* chip is OK for user apps; mark it as initialized */ + for (pidx = 0; pidx < dd->num_pports; ++pidx) { + ppd = dd->pport + pidx; + /* + * Set status even if port serdes is not initialized + * so that diags will work. + */ + *ppd->statusp |= QIB_STATUS_CHIP_PRESENT | + QIB_STATUS_INITTED; + if (!ppd->link_speed_enabled) + continue; + if (dd->flags & QIB_HAS_SEND_DMA) + ret = qib_setup_sdma(ppd); + init_timer(&ppd->hol_timer); + ppd->hol_timer.function = qib_hol_event; + ppd->hol_timer.data = (unsigned long)ppd; + ppd->hol_state = QIB_HOL_UP; + } + + /* now we can enable all interrupts from the chip */ + dd->f_set_intr_state(dd, 1); + + /* + * Setup to verify we get an interrupt, and fallback + * to an alternate if necessary and possible. + */ + mod_timer(&dd->intrchk_timer, jiffies + HZ/2); + /* start stats retrieval timer */ + mod_timer(&dd->stats_timer, jiffies + HZ * ACTIVITY_TIMER); + } + + /* if ret is non-zero, we probably should do some cleanup here... */ + return ret; +} + +/* + * These next two routines are placeholders in case we don't have per-arch + * code for controlling write combining. If explicit control of write + * combining is not available, performance will probably be awful. + */ + +int __attribute__((weak)) qib_enable_wc(struct qib_devdata *dd) +{ + return -EOPNOTSUPP; +} + +void __attribute__((weak)) qib_disable_wc(struct qib_devdata *dd) +{ +} + +static inline struct qib_devdata *__qib_lookup(int unit) +{ + return idr_find(&qib_unit_table, unit); +} + +struct qib_devdata *qib_lookup(int unit) +{ + struct qib_devdata *dd; + unsigned long flags; + + spin_lock_irqsave(&qib_devs_lock, flags); + dd = __qib_lookup(unit); + spin_unlock_irqrestore(&qib_devs_lock, flags); + + return dd; +} + +/* + * Stop the timers during unit shutdown, or after an error late + * in initialization. + */ +static void qib_stop_timers(struct qib_devdata *dd) +{ + struct qib_pportdata *ppd; + int pidx; + + if (dd->stats_timer.data) { + del_timer_sync(&dd->stats_timer); + dd->stats_timer.data = 0; + } + if (dd->intrchk_timer.data) { + del_timer_sync(&dd->intrchk_timer); + dd->intrchk_timer.data = 0; + } + for (pidx = 0; pidx < dd->num_pports; ++pidx) { + ppd = dd->pport + pidx; + if (ppd->hol_timer.data) + del_timer_sync(&ppd->hol_timer); + if (ppd->led_override_timer.data) { + del_timer_sync(&ppd->led_override_timer); + atomic_set(&ppd->led_override_timer_active, 0); + } + if (ppd->symerr_clear_timer.data) + del_timer_sync(&ppd->symerr_clear_timer); + } +} + +/** + * qib_shutdown_device - shut down a device + * @dd: the qlogic_ib device + * + * This is called to make the device quiet when we are about to + * unload the driver, and also when the device is administratively + * disabled. It does not free any data structures. + * Everything it does has to be setup again by qib_init(dd, 1) + */ +static void qib_shutdown_device(struct qib_devdata *dd) +{ + struct qib_pportdata *ppd; + unsigned pidx; + + for (pidx = 0; pidx < dd->num_pports; ++pidx) { + ppd = dd->pport + pidx; + + spin_lock_irq(&ppd->lflags_lock); + ppd->lflags &= ~(QIBL_LINKDOWN | QIBL_LINKINIT | + QIBL_LINKARMED | QIBL_LINKACTIVE | + QIBL_LINKV); + spin_unlock_irq(&ppd->lflags_lock); + *ppd->statusp &= ~(QIB_STATUS_IB_CONF | QIB_STATUS_IB_READY); + } + dd->flags &= ~QIB_INITTED; + + /* mask interrupts, but not errors */ + dd->f_set_intr_state(dd, 0); + + for (pidx = 0; pidx < dd->num_pports; ++pidx) { + ppd = dd->pport + pidx; + dd->f_rcvctrl(ppd, QIB_RCVCTRL_TAILUPD_DIS | + QIB_RCVCTRL_CTXT_DIS | + QIB_RCVCTRL_INTRAVAIL_DIS | + QIB_RCVCTRL_PKEY_ENB, -1); + /* + * Gracefully stop all sends allowing any in progress to + * trickle out first. + */ + dd->f_sendctrl(ppd, QIB_SENDCTRL_CLEAR); + } + + /* + * Enough for anything that's going to trickle out to have actually + * done so. + */ + udelay(20); + + for (pidx = 0; pidx < dd->num_pports; ++pidx) { + ppd = dd->pport + pidx; + dd->f_setextled(ppd, 0); /* make sure LEDs are off */ + + if (dd->flags & QIB_HAS_SEND_DMA) + qib_teardown_sdma(ppd); + + dd->f_sendctrl(ppd, QIB_SENDCTRL_AVAIL_DIS | + QIB_SENDCTRL_SEND_DIS); + /* + * Clear SerdesEnable. + * We can't count on interrupts since we are stopping. + */ + dd->f_quiet_serdes(ppd); + } + + qib_update_eeprom_log(dd); +} + +/** + * qib_free_ctxtdata - free a context's allocated data + * @dd: the qlogic_ib device + * @rcd: the ctxtdata structure + * + * free up any allocated data for a context + * This should not touch anything that would affect a simultaneous + * re-allocation of context data, because it is called after qib_mutex + * is released (and can be called from reinit as well). + * It should never change any chip state, or global driver state. + */ +void qib_free_ctxtdata(struct qib_devdata *dd, struct qib_ctxtdata *rcd) +{ + if (!rcd) + return; + + if (rcd->rcvhdrq) { + dma_free_coherent(&dd->pcidev->dev, rcd->rcvhdrq_size, + rcd->rcvhdrq, rcd->rcvhdrq_phys); + rcd->rcvhdrq = NULL; + if (rcd->rcvhdrtail_kvaddr) { + dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE, + rcd->rcvhdrtail_kvaddr, + rcd->rcvhdrqtailaddr_phys); + rcd->rcvhdrtail_kvaddr = NULL; + } + } + if (rcd->rcvegrbuf) { + unsigned e; + + for (e = 0; e < rcd->rcvegrbuf_chunks; e++) { + void *base = rcd->rcvegrbuf[e]; + size_t size = rcd->rcvegrbuf_size; + + dma_free_coherent(&dd->pcidev->dev, size, + base, rcd->rcvegrbuf_phys[e]); + } + kfree(rcd->rcvegrbuf); + rcd->rcvegrbuf = NULL; + kfree(rcd->rcvegrbuf_phys); + rcd->rcvegrbuf_phys = NULL; + rcd->rcvegrbuf_chunks = 0; + } + + kfree(rcd->tid_pg_list); + vfree(rcd->user_event_mask); + vfree(rcd->subctxt_uregbase); + vfree(rcd->subctxt_rcvegrbuf); + vfree(rcd->subctxt_rcvhdr_base); + kfree(rcd); +} + +/* + * Perform a PIO buffer bandwidth write test, to verify proper system + * configuration. Even when all the setup calls work, occasionally + * BIOS or other issues can prevent write combining from working, or + * can cause other bandwidth problems to the chip. + * + * This test simply writes the same buffer over and over again, and + * measures close to the peak bandwidth to the chip (not testing + * data bandwidth to the wire). On chips that use an address-based + * trigger to send packets to the wire, this is easy. On chips that + * use a count to trigger, we want to make sure that the packet doesn't + * go out on the wire, or trigger flow control checks. + */ +static void qib_verify_pioperf(struct qib_devdata *dd) +{ + u32 pbnum, cnt, lcnt; + u32 __iomem *piobuf; + u32 *addr; + u64 msecs, emsecs; + + piobuf = dd->f_getsendbuf(dd->pport, 0ULL, &pbnum); + if (!piobuf) { + qib_devinfo(dd->pcidev, + "No PIObufs for checking perf, skipping\n"); + return; + } + + /* + * Enough to give us a reasonable test, less than piobuf size, and + * likely multiple of store buffer length. + */ + cnt = 1024; + + addr = vmalloc(cnt); + if (!addr) { + qib_devinfo(dd->pcidev, + "Couldn't get memory for checking PIO perf," + " skipping\n"); + goto done; + } + + preempt_disable(); /* we want reasonably accurate elapsed time */ + msecs = 1 + jiffies_to_msecs(jiffies); + for (lcnt = 0; lcnt < 10000U; lcnt++) { + /* wait until we cross msec boundary */ + if (jiffies_to_msecs(jiffies) >= msecs) + break; + udelay(1); + } + + dd->f_set_armlaunch(dd, 0); + + /* + * length 0, no dwords actually sent + */ + writeq(0, piobuf); + qib_flush_wc(); + + /* + * This is only roughly accurate, since even with preempt we + * still take interrupts that could take a while. Running for + * >= 5 msec seems to get us "close enough" to accurate values. + */ + msecs = jiffies_to_msecs(jiffies); + for (emsecs = lcnt = 0; emsecs <= 5UL; lcnt++) { + qib_pio_copy(piobuf + 64, addr, cnt >> 2); + emsecs = jiffies_to_msecs(jiffies) - msecs; + } + + /* 1 GiB/sec, slightly over IB SDR line rate */ + if (lcnt < (emsecs * 1024U)) + qib_dev_err(dd, + "Performance problem: bandwidth to PIO buffers is " + "only %u MiB/sec\n", + lcnt / (u32) emsecs); + + preempt_enable(); + + vfree(addr); + +done: + /* disarm piobuf, so it's available again */ + dd->f_sendctrl(dd->pport, QIB_SENDCTRL_DISARM_BUF(pbnum)); + qib_sendbuf_done(dd, pbnum); + dd->f_set_armlaunch(dd, 1); +} + + +void qib_free_devdata(struct qib_devdata *dd) +{ + unsigned long flags; + + spin_lock_irqsave(&qib_devs_lock, flags); + idr_remove(&qib_unit_table, dd->unit); + list_del(&dd->list); + spin_unlock_irqrestore(&qib_devs_lock, flags); + + ib_dealloc_device(&dd->verbs_dev.ibdev); +} + +/* + * Allocate our primary per-unit data structure. Must be done via verbs + * allocator, because the verbs cleanup process both does cleanup and + * free of the data structure. + * "extra" is for chip-specific data. + * + * Use the idr mechanism to get a unit number for this unit. + */ +struct qib_devdata *qib_alloc_devdata(struct pci_dev *pdev, size_t extra) +{ + unsigned long flags; + struct qib_devdata *dd; + int ret; + + if (!idr_pre_get(&qib_unit_table, GFP_KERNEL)) { + dd = ERR_PTR(-ENOMEM); + goto bail; + } + + dd = (struct qib_devdata *) ib_alloc_device(sizeof(*dd) + extra); + if (!dd) { + dd = ERR_PTR(-ENOMEM); + goto bail; + } + + spin_lock_irqsave(&qib_devs_lock, flags); + ret = idr_get_new(&qib_unit_table, dd, &dd->unit); + if (ret >= 0) + list_add(&dd->list, &qib_dev_list); + spin_unlock_irqrestore(&qib_devs_lock, flags); + + if (ret < 0) { + qib_early_err(&pdev->dev, + "Could not allocate unit ID: error %d\n", -ret); + ib_dealloc_device(&dd->verbs_dev.ibdev); + dd = ERR_PTR(ret); + goto bail; + } + + if (!qib_cpulist_count) { + u32 count = num_online_cpus(); + qib_cpulist = kzalloc(BITS_TO_LONGS(count) * + sizeof(long), GFP_KERNEL); + if (qib_cpulist) + qib_cpulist_count = count; + else + qib_early_err(&pdev->dev, "Could not alloc cpulist " + "info, cpu affinity might be wrong\n"); + } + +bail: + return dd; +} + +/* + * Called from freeze mode handlers, and from PCI error + * reporting code. Should be paranoid about state of + * system and data structures. + */ +void qib_disable_after_error(struct qib_devdata *dd) +{ + if (dd->flags & QIB_INITTED) { + u32 pidx; + + dd->flags &= ~QIB_INITTED; + if (dd->pport) + for (pidx = 0; pidx < dd->num_pports; ++pidx) { + struct qib_pportdata *ppd; + + ppd = dd->pport + pidx; + if (dd->flags & QIB_PRESENT) { + qib_set_linkstate(ppd, + QIB_IB_LINKDOWN_DISABLE); + dd->f_setextled(ppd, 0); + } + *ppd->statusp &= ~QIB_STATUS_IB_READY; + } + } + + /* + * Mark as having had an error for driver, and also + * for /sys and status word mapped to user programs. + * This marks unit as not usable, until reset. + */ + if (dd->devstatusp) + *dd->devstatusp |= QIB_STATUS_HWERROR; +} + +static void __devexit qib_remove_one(struct pci_dev *); +static int __devinit qib_init_one(struct pci_dev *, + const struct pci_device_id *); + +#define DRIVER_LOAD_MSG "QLogic " QIB_DRV_NAME " loaded: " +#define PFX QIB_DRV_NAME ": " + +static const struct pci_device_id qib_pci_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_QLOGIC_IB_6120) }, + { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_IB_7220) }, + { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_IB_7322) }, + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, qib_pci_tbl); + +struct pci_driver qib_driver = { + .name = QIB_DRV_NAME, + .probe = qib_init_one, + .remove = __devexit_p(qib_remove_one), + .id_table = qib_pci_tbl, + .err_handler = &qib_pci_err_handler, +}; + +/* + * Do all the generic driver unit- and chip-independent memory + * allocation and initialization. + */ +static int __init qlogic_ib_init(void) +{ + int ret; + + ret = qib_dev_init(); + if (ret) + goto bail; + + /* + * We create our own workqueue mainly because we want to be + * able to flush it when devices are being removed. We can't + * use schedule_work()/flush_scheduled_work() because both + * unregister_netdev() and linkwatch_event take the rtnl lock, + * so flush_scheduled_work() can deadlock during device + * removal. + */ + qib_wq = create_workqueue("qib"); + if (!qib_wq) { + ret = -ENOMEM; + goto bail_dev; + } + + qib_cq_wq = create_workqueue("qib_cq"); + if (!qib_cq_wq) { + ret = -ENOMEM; + goto bail_wq; + } + + /* + * These must be called before the driver is registered with + * the PCI subsystem. + */ + idr_init(&qib_unit_table); + if (!idr_pre_get(&qib_unit_table, GFP_KERNEL)) { + printk(KERN_ERR QIB_DRV_NAME ": idr_pre_get() failed\n"); + ret = -ENOMEM; + goto bail_cq_wq; + } + + ret = pci_register_driver(&qib_driver); + if (ret < 0) { + printk(KERN_ERR QIB_DRV_NAME + ": Unable to register driver: error %d\n", -ret); + goto bail_unit; + } + + /* not fatal if it doesn't work */ + if (qib_init_qibfs()) + printk(KERN_ERR QIB_DRV_NAME ": Unable to register ipathfs\n"); + goto bail; /* all OK */ + +bail_unit: + idr_destroy(&qib_unit_table); +bail_cq_wq: + destroy_workqueue(qib_cq_wq); +bail_wq: + destroy_workqueue(qib_wq); +bail_dev: + qib_dev_cleanup(); +bail: + return ret; +} + +module_init(qlogic_ib_init); + +/* + * Do the non-unit driver cleanup, memory free, etc. at unload. + */ +static void __exit qlogic_ib_cleanup(void) +{ + int ret; + + ret = qib_exit_qibfs(); + if (ret) + printk(KERN_ERR QIB_DRV_NAME ": " + "Unable to cleanup counter filesystem: " + "error %d\n", -ret); + + pci_unregister_driver(&qib_driver); + + destroy_workqueue(qib_wq); + destroy_workqueue(qib_cq_wq); + + qib_cpulist_count = 0; + kfree(qib_cpulist); + + idr_destroy(&qib_unit_table); + qib_dev_cleanup(); +} + +module_exit(qlogic_ib_cleanup); + +/* this can only be called after a successful initialization */ +static void cleanup_device_data(struct qib_devdata *dd) +{ + int ctxt; + int pidx; + struct qib_ctxtdata **tmp; + unsigned long flags; + + /* users can't do anything more with chip */ + for (pidx = 0; pidx < dd->num_pports; ++pidx) + if (dd->pport[pidx].statusp) + *dd->pport[pidx].statusp &= ~QIB_STATUS_CHIP_PRESENT; + + if (!qib_wc_pat) + qib_disable_wc(dd); + + if (dd->pioavailregs_dma) { + dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE, + (void *) dd->pioavailregs_dma, + dd->pioavailregs_phys); + dd->pioavailregs_dma = NULL; + } + + if (dd->pageshadow) { + struct page **tmpp = dd->pageshadow; + dma_addr_t *tmpd = dd->physshadow; + int i, cnt = 0; + + for (ctxt = 0; ctxt < dd->cfgctxts; ctxt++) { + int ctxt_tidbase = ctxt * dd->rcvtidcnt; + int maxtid = ctxt_tidbase + dd->rcvtidcnt; + + for (i = ctxt_tidbase; i < maxtid; i++) { + if (!tmpp[i]) + continue; + pci_unmap_page(dd->pcidev, tmpd[i], + PAGE_SIZE, PCI_DMA_FROMDEVICE); + qib_release_user_pages(&tmpp[i], 1); + tmpp[i] = NULL; + cnt++; + } + } + + tmpp = dd->pageshadow; + dd->pageshadow = NULL; + vfree(tmpp); + } + + /* + * Free any resources still in use (usually just kernel contexts) + * at unload; we do for ctxtcnt, because that's what we allocate. + * We acquire lock to be really paranoid that rcd isn't being + * accessed from some interrupt-related code (that should not happen, + * but best to be sure). + */ + spin_lock_irqsave(&dd->uctxt_lock, flags); + tmp = dd->rcd; + dd->rcd = NULL; + spin_unlock_irqrestore(&dd->uctxt_lock, flags); + for (ctxt = 0; tmp && ctxt < dd->ctxtcnt; ctxt++) { + struct qib_ctxtdata *rcd = tmp[ctxt]; + + tmp[ctxt] = NULL; /* debugging paranoia */ + qib_free_ctxtdata(dd, rcd); + } + kfree(tmp); + kfree(dd->boardname); +} + +/* + * Clean up on unit shutdown, or error during unit load after + * successful initialization. + */ +static void qib_postinit_cleanup(struct qib_devdata *dd) +{ + /* + * Clean up chip-specific stuff. + * We check for NULL here, because it's outside + * the kregbase check, and we need to call it + * after the free_irq. Thus it's possible that + * the function pointers were never initialized. + */ + if (dd->f_cleanup) + dd->f_cleanup(dd); + + qib_pcie_ddcleanup(dd); + + cleanup_device_data(dd); + + qib_free_devdata(dd); +} + +static int __devinit qib_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int ret, j, pidx, initfail; + struct qib_devdata *dd = NULL; + + ret = qib_pcie_init(pdev, ent); + if (ret) + goto bail; + + /* + * Do device-specific initialiation, function table setup, dd + * allocation, etc. + */ + switch (ent->device) { + case PCI_DEVICE_ID_QLOGIC_IB_6120: + dd = qib_init_iba6120_funcs(pdev, ent); + break; + + case PCI_DEVICE_ID_QLOGIC_IB_7220: + dd = qib_init_iba7220_funcs(pdev, ent); + break; + + case PCI_DEVICE_ID_QLOGIC_IB_7322: + dd = qib_init_iba7322_funcs(pdev, ent); + break; + + default: + qib_early_err(&pdev->dev, "Failing on unknown QLogic " + "deviceid 0x%x\n", ent->device); + ret = -ENODEV; + } + + if (IS_ERR(dd)) + ret = PTR_ERR(dd); + if (ret) + goto bail; /* error already printed */ + + /* do the generic initialization */ + initfail = qib_init(dd, 0); + + ret = qib_register_ib_device(dd); + + /* + * Now ready for use. this should be cleared whenever we + * detect a reset, or initiate one. If earlier failure, + * we still create devices, so diags, etc. can be used + * to determine cause of problem. + */ + if (!qib_mini_init && !initfail && !ret) + dd->flags |= QIB_INITTED; + + j = qib_device_create(dd); + if (j) + qib_dev_err(dd, "Failed to create /dev devices: %d\n", -j); + j = qibfs_add(dd); + if (j) + qib_dev_err(dd, "Failed filesystem setup for counters: %d\n", + -j); + + if (qib_mini_init || initfail || ret) { + qib_stop_timers(dd); + for (pidx = 0; pidx < dd->num_pports; ++pidx) + dd->f_quiet_serdes(dd->pport + pidx); + if (initfail) + ret = initfail; + goto bail; + } + + if (!qib_wc_pat) { + ret = qib_enable_wc(dd); + if (ret) { + qib_dev_err(dd, "Write combining not enabled " + "(err %d): performance may be poor\n", + -ret); + ret = 0; + } + } + + qib_verify_pioperf(dd); +bail: + return ret; +} + +static void __devexit qib_remove_one(struct pci_dev *pdev) +{ + struct qib_devdata *dd = pci_get_drvdata(pdev); + int ret; + + /* unregister from IB core */ + qib_unregister_ib_device(dd); + + /* + * Disable the IB link, disable interrupts on the device, + * clear dma engines, etc. + */ + if (!qib_mini_init) + qib_shutdown_device(dd); + + qib_stop_timers(dd); + + /* wait until all of our (qsfp) schedule_work() calls complete */ + flush_scheduled_work(); + + ret = qibfs_remove(dd); + if (ret) + qib_dev_err(dd, "Failed counters filesystem cleanup: %d\n", + -ret); + + qib_device_remove(dd); + + qib_postinit_cleanup(dd); +} + +/** + * qib_create_rcvhdrq - create a receive header queue + * @dd: the qlogic_ib device + * @rcd: the context data + * + * This must be contiguous memory (from an i/o perspective), and must be + * DMA'able (which means for some systems, it will go through an IOMMU, + * or be forced into a low address range). + */ +int qib_create_rcvhdrq(struct qib_devdata *dd, struct qib_ctxtdata *rcd) +{ + unsigned amt; + + if (!rcd->rcvhdrq) { + dma_addr_t phys_hdrqtail; + gfp_t gfp_flags; + + amt = ALIGN(dd->rcvhdrcnt * dd->rcvhdrentsize * + sizeof(u32), PAGE_SIZE); + gfp_flags = (rcd->ctxt >= dd->first_user_ctxt) ? + GFP_USER : GFP_KERNEL; + rcd->rcvhdrq = dma_alloc_coherent( + &dd->pcidev->dev, amt, &rcd->rcvhdrq_phys, + gfp_flags | __GFP_COMP); + + if (!rcd->rcvhdrq) { + qib_dev_err(dd, "attempt to allocate %d bytes " + "for ctxt %u rcvhdrq failed\n", + amt, rcd->ctxt); + goto bail; + } + + if (rcd->ctxt >= dd->first_user_ctxt) { + rcd->user_event_mask = vmalloc_user(PAGE_SIZE); + if (!rcd->user_event_mask) + goto bail_free_hdrq; + } + + if (!(dd->flags & QIB_NODMA_RTAIL)) { + rcd->rcvhdrtail_kvaddr = dma_alloc_coherent( + &dd->pcidev->dev, PAGE_SIZE, &phys_hdrqtail, + gfp_flags); + if (!rcd->rcvhdrtail_kvaddr) + goto bail_free; + rcd->rcvhdrqtailaddr_phys = phys_hdrqtail; + } + + rcd->rcvhdrq_size = amt; + } + + /* clear for security and sanity on each use */ + memset(rcd->rcvhdrq, 0, rcd->rcvhdrq_size); + if (rcd->rcvhdrtail_kvaddr) + memset(rcd->rcvhdrtail_kvaddr, 0, PAGE_SIZE); + return 0; + +bail_free: + qib_dev_err(dd, "attempt to allocate 1 page for ctxt %u " + "rcvhdrqtailaddr failed\n", rcd->ctxt); + vfree(rcd->user_event_mask); + rcd->user_event_mask = NULL; +bail_free_hdrq: + dma_free_coherent(&dd->pcidev->dev, amt, rcd->rcvhdrq, + rcd->rcvhdrq_phys); + rcd->rcvhdrq = NULL; +bail: + return -ENOMEM; +} + +/** + * allocate eager buffers, both kernel and user contexts. + * @rcd: the context we are setting up. + * + * Allocate the eager TID buffers and program them into hip. + * They are no longer completely contiguous, we do multiple allocation + * calls. Otherwise we get the OOM code involved, by asking for too + * much per call, with disastrous results on some kernels. + */ +int qib_setup_eagerbufs(struct qib_ctxtdata *rcd) +{ + struct qib_devdata *dd = rcd->dd; + unsigned e, egrcnt, egrperchunk, chunk, egrsize, egroff; + size_t size; + gfp_t gfp_flags; + + /* + * GFP_USER, but without GFP_FS, so buffer cache can be + * coalesced (we hope); otherwise, even at order 4, + * heavy filesystem activity makes these fail, and we can + * use compound pages. + */ + gfp_flags = __GFP_WAIT | __GFP_IO | __GFP_COMP; + + egrcnt = rcd->rcvegrcnt; + egroff = rcd->rcvegr_tid_base; + egrsize = dd->rcvegrbufsize; + + chunk = rcd->rcvegrbuf_chunks; + egrperchunk = rcd->rcvegrbufs_perchunk; + size = rcd->rcvegrbuf_size; + if (!rcd->rcvegrbuf) { + rcd->rcvegrbuf = + kzalloc(chunk * sizeof(rcd->rcvegrbuf[0]), + GFP_KERNEL); + if (!rcd->rcvegrbuf) + goto bail; + } + if (!rcd->rcvegrbuf_phys) { + rcd->rcvegrbuf_phys = + kmalloc(chunk * sizeof(rcd->rcvegrbuf_phys[0]), + GFP_KERNEL); + if (!rcd->rcvegrbuf_phys) + goto bail_rcvegrbuf; + } + for (e = 0; e < rcd->rcvegrbuf_chunks; e++) { + if (rcd->rcvegrbuf[e]) + continue; + rcd->rcvegrbuf[e] = + dma_alloc_coherent(&dd->pcidev->dev, size, + &rcd->rcvegrbuf_phys[e], + gfp_flags); + if (!rcd->rcvegrbuf[e]) + goto bail_rcvegrbuf_phys; + } + + rcd->rcvegr_phys = rcd->rcvegrbuf_phys[0]; + + for (e = chunk = 0; chunk < rcd->rcvegrbuf_chunks; chunk++) { + dma_addr_t pa = rcd->rcvegrbuf_phys[chunk]; + unsigned i; + + for (i = 0; e < egrcnt && i < egrperchunk; e++, i++) { + dd->f_put_tid(dd, e + egroff + + (u64 __iomem *) + ((char __iomem *) + dd->kregbase + + dd->rcvegrbase), + RCVHQ_RCV_TYPE_EAGER, pa); + pa += egrsize; + } + cond_resched(); /* don't hog the cpu */ + } + + return 0; + +bail_rcvegrbuf_phys: + for (e = 0; e < rcd->rcvegrbuf_chunks && rcd->rcvegrbuf[e]; e++) + dma_free_coherent(&dd->pcidev->dev, size, + rcd->rcvegrbuf[e], rcd->rcvegrbuf_phys[e]); + kfree(rcd->rcvegrbuf_phys); + rcd->rcvegrbuf_phys = NULL; +bail_rcvegrbuf: + kfree(rcd->rcvegrbuf); + rcd->rcvegrbuf = NULL; +bail: + return -ENOMEM; +} + +int init_chip_wc_pat(struct qib_devdata *dd, u32 vl15buflen) +{ + u64 __iomem *qib_kregbase = NULL; + void __iomem *qib_piobase = NULL; + u64 __iomem *qib_userbase = NULL; + u64 qib_kreglen; + u64 qib_pio2koffset = dd->piobufbase & 0xffffffff; + u64 qib_pio4koffset = dd->piobufbase >> 32; + u64 qib_pio2klen = dd->piobcnt2k * dd->palign; + u64 qib_pio4klen = dd->piobcnt4k * dd->align4k; + u64 qib_physaddr = dd->physaddr; + u64 qib_piolen; + u64 qib_userlen = 0; + + /* + * Free the old mapping because the kernel will try to reuse the + * old mapping and not create a new mapping with the + * write combining attribute. + */ + iounmap(dd->kregbase); + dd->kregbase = NULL; + + /* + * Assumes chip address space looks like: + * - kregs + sregs + cregs + uregs (in any order) + * - piobufs (2K and 4K bufs in either order) + * or: + * - kregs + sregs + cregs (in any order) + * - piobufs (2K and 4K bufs in either order) + * - uregs + */ + if (dd->piobcnt4k == 0) { + qib_kreglen = qib_pio2koffset; + qib_piolen = qib_pio2klen; + } else if (qib_pio2koffset < qib_pio4koffset) { + qib_kreglen = qib_pio2koffset; + qib_piolen = qib_pio4koffset + qib_pio4klen - qib_kreglen; + } else { + qib_kreglen = qib_pio4koffset; + qib_piolen = qib_pio2koffset + qib_pio2klen - qib_kreglen; + } + qib_piolen += vl15buflen; + /* Map just the configured ports (not all hw ports) */ + if (dd->uregbase > qib_kreglen) + qib_userlen = dd->ureg_align * dd->cfgctxts; + + /* Sanity checks passed, now create the new mappings */ + qib_kregbase = ioremap_nocache(qib_physaddr, qib_kreglen); + if (!qib_kregbase) + goto bail; + + qib_piobase = ioremap_wc(qib_physaddr + qib_kreglen, qib_piolen); + if (!qib_piobase) + goto bail_kregbase; + + if (qib_userlen) { + qib_userbase = ioremap_nocache(qib_physaddr + dd->uregbase, + qib_userlen); + if (!qib_userbase) + goto bail_piobase; + } + + dd->kregbase = qib_kregbase; + dd->kregend = (u64 __iomem *) + ((char __iomem *) qib_kregbase + qib_kreglen); + dd->piobase = qib_piobase; + dd->pio2kbase = (void __iomem *) + (((char __iomem *) dd->piobase) + + qib_pio2koffset - qib_kreglen); + if (dd->piobcnt4k) + dd->pio4kbase = (void __iomem *) + (((char __iomem *) dd->piobase) + + qib_pio4koffset - qib_kreglen); + if (qib_userlen) + /* ureg will now be accessed relative to dd->userbase */ + dd->userbase = qib_userbase; + return 0; + +bail_piobase: + iounmap(qib_piobase); +bail_kregbase: + iounmap(qib_kregbase); +bail: + return -ENOMEM; +} diff --git a/drivers/infiniband/hw/qib/qib_intr.c b/drivers/infiniband/hw/qib/qib_intr.c new file mode 100644 index 000000000000..54a40828a106 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_intr.c @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation. + * All rights reserved. + * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include + +#include "qib.h" +#include "qib_common.h" + +/** + * qib_format_hwmsg - format a single hwerror message + * @msg message buffer + * @msgl length of message buffer + * @hwmsg message to add to message buffer + */ +static void qib_format_hwmsg(char *msg, size_t msgl, const char *hwmsg) +{ + strlcat(msg, "[", msgl); + strlcat(msg, hwmsg, msgl); + strlcat(msg, "]", msgl); +} + +/** + * qib_format_hwerrors - format hardware error messages for display + * @hwerrs hardware errors bit vector + * @hwerrmsgs hardware error descriptions + * @nhwerrmsgs number of hwerrmsgs + * @msg message buffer + * @msgl message buffer length + */ +void qib_format_hwerrors(u64 hwerrs, const struct qib_hwerror_msgs *hwerrmsgs, + size_t nhwerrmsgs, char *msg, size_t msgl) +{ + int i; + + for (i = 0; i < nhwerrmsgs; i++) + if (hwerrs & hwerrmsgs[i].mask) + qib_format_hwmsg(msg, msgl, hwerrmsgs[i].msg); +} + +static void signal_ib_event(struct qib_pportdata *ppd, enum ib_event_type ev) +{ + struct ib_event event; + struct qib_devdata *dd = ppd->dd; + + event.device = &dd->verbs_dev.ibdev; + event.element.port_num = ppd->port; + event.event = ev; + ib_dispatch_event(&event); +} + +void qib_handle_e_ibstatuschanged(struct qib_pportdata *ppd, u64 ibcs) +{ + struct qib_devdata *dd = ppd->dd; + unsigned long flags; + u32 lstate; + u8 ltstate; + enum ib_event_type ev = 0; + + lstate = dd->f_iblink_state(ibcs); /* linkstate */ + ltstate = dd->f_ibphys_portstate(ibcs); + + /* + * If linkstate transitions into INIT from any of the various down + * states, or if it transitions from any of the up (INIT or better) + * states into any of the down states (except link recovery), then + * call the chip-specific code to take appropriate actions. + */ + if (lstate >= IB_PORT_INIT && (ppd->lflags & QIBL_LINKDOWN) && + ltstate == IB_PHYSPORTSTATE_LINKUP) { + /* transitioned to UP */ + if (dd->f_ib_updown(ppd, 1, ibcs)) + goto skip_ibchange; /* chip-code handled */ + } else if (ppd->lflags & (QIBL_LINKINIT | QIBL_LINKARMED | + QIBL_LINKACTIVE | QIBL_IB_FORCE_NOTIFY)) { + if (ltstate != IB_PHYSPORTSTATE_LINKUP && + ltstate <= IB_PHYSPORTSTATE_CFG_TRAIN && + dd->f_ib_updown(ppd, 0, ibcs)) + goto skip_ibchange; /* chip-code handled */ + qib_set_uevent_bits(ppd, _QIB_EVENT_LINKDOWN_BIT); + } + + if (lstate != IB_PORT_DOWN) { + /* lstate is INIT, ARMED, or ACTIVE */ + if (lstate != IB_PORT_ACTIVE) { + *ppd->statusp &= ~QIB_STATUS_IB_READY; + if (ppd->lflags & QIBL_LINKACTIVE) + ev = IB_EVENT_PORT_ERR; + spin_lock_irqsave(&ppd->lflags_lock, flags); + if (lstate == IB_PORT_ARMED) { + ppd->lflags |= QIBL_LINKARMED | QIBL_LINKV; + ppd->lflags &= ~(QIBL_LINKINIT | + QIBL_LINKDOWN | QIBL_LINKACTIVE); + } else { + ppd->lflags |= QIBL_LINKINIT | QIBL_LINKV; + ppd->lflags &= ~(QIBL_LINKARMED | + QIBL_LINKDOWN | QIBL_LINKACTIVE); + } + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + /* start a 75msec timer to clear symbol errors */ + mod_timer(&ppd->symerr_clear_timer, + msecs_to_jiffies(75)); + } else if (ltstate == IB_PHYSPORTSTATE_LINKUP) { + /* active, but not active defered */ + qib_hol_up(ppd); /* useful only for 6120 now */ + *ppd->statusp |= + QIB_STATUS_IB_READY | QIB_STATUS_IB_CONF; + qib_clear_symerror_on_linkup((unsigned long)ppd); + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags |= QIBL_LINKACTIVE | QIBL_LINKV; + ppd->lflags &= ~(QIBL_LINKINIT | + QIBL_LINKDOWN | QIBL_LINKARMED); + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + if (dd->flags & QIB_HAS_SEND_DMA) + qib_sdma_process_event(ppd, + qib_sdma_event_e30_go_running); + ev = IB_EVENT_PORT_ACTIVE; + dd->f_setextled(ppd, 1); + } + } else { /* down */ + if (ppd->lflags & QIBL_LINKACTIVE) + ev = IB_EVENT_PORT_ERR; + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags |= QIBL_LINKDOWN | QIBL_LINKV; + ppd->lflags &= ~(QIBL_LINKINIT | + QIBL_LINKACTIVE | QIBL_LINKARMED); + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + *ppd->statusp &= ~QIB_STATUS_IB_READY; + } + +skip_ibchange: + ppd->lastibcstat = ibcs; + if (ev) + signal_ib_event(ppd, ev); + return; +} + +void qib_clear_symerror_on_linkup(unsigned long opaque) +{ + struct qib_pportdata *ppd = (struct qib_pportdata *)opaque; + + if (ppd->lflags & QIBL_LINKACTIVE) + return; + + ppd->ibport_data.z_symbol_error_counter = + ppd->dd->f_portcntr(ppd, QIBPORTCNTR_IBSYMBOLERR); +} + +/* + * Handle receive interrupts for user ctxts; this means a user + * process was waiting for a packet to arrive, and didn't want + * to poll. + */ +void qib_handle_urcv(struct qib_devdata *dd, u64 ctxtr) +{ + struct qib_ctxtdata *rcd; + unsigned long flags; + int i; + + spin_lock_irqsave(&dd->uctxt_lock, flags); + for (i = dd->first_user_ctxt; dd->rcd && i < dd->cfgctxts; i++) { + if (!(ctxtr & (1ULL << i))) + continue; + rcd = dd->rcd[i]; + if (!rcd || !rcd->cnt) + continue; + + if (test_and_clear_bit(QIB_CTXT_WAITING_RCV, &rcd->flag)) { + wake_up_interruptible(&rcd->wait); + dd->f_rcvctrl(rcd->ppd, QIB_RCVCTRL_INTRAVAIL_DIS, + rcd->ctxt); + } else if (test_and_clear_bit(QIB_CTXT_WAITING_URG, + &rcd->flag)) { + rcd->urgent++; + wake_up_interruptible(&rcd->wait); + } + } + spin_unlock_irqrestore(&dd->uctxt_lock, flags); +} + +void qib_bad_intrstatus(struct qib_devdata *dd) +{ + static int allbits; + + /* separate routine, for better optimization of qib_intr() */ + + /* + * We print the message and disable interrupts, in hope of + * having a better chance of debugging the problem. + */ + qib_dev_err(dd, "Read of chip interrupt status failed" + " disabling interrupts\n"); + if (allbits++) { + /* disable interrupt delivery, something is very wrong */ + if (allbits == 2) + dd->f_set_intr_state(dd, 0); + if (allbits == 3) { + qib_dev_err(dd, "2nd bad interrupt status, " + "unregistering interrupts\n"); + dd->flags |= QIB_BADINTR; + dd->flags &= ~QIB_INITTED; + dd->f_free_irq(dd); + } + } +} diff --git a/drivers/infiniband/hw/qib/qib_keys.c b/drivers/infiniband/hw/qib/qib_keys.c new file mode 100644 index 000000000000..4b80eb153d57 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_keys.c @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2006, 2007, 2009 QLogic Corporation. All rights reserved. + * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "qib.h" + +/** + * qib_alloc_lkey - allocate an lkey + * @rkt: lkey table in which to allocate the lkey + * @mr: memory region that this lkey protects + * + * Returns 1 if successful, otherwise returns 0. + */ + +int qib_alloc_lkey(struct qib_lkey_table *rkt, struct qib_mregion *mr) +{ + unsigned long flags; + u32 r; + u32 n; + int ret; + + spin_lock_irqsave(&rkt->lock, flags); + + /* Find the next available LKEY */ + r = rkt->next; + n = r; + for (;;) { + if (rkt->table[r] == NULL) + break; + r = (r + 1) & (rkt->max - 1); + if (r == n) { + spin_unlock_irqrestore(&rkt->lock, flags); + ret = 0; + goto bail; + } + } + rkt->next = (r + 1) & (rkt->max - 1); + /* + * Make sure lkey is never zero which is reserved to indicate an + * unrestricted LKEY. + */ + rkt->gen++; + mr->lkey = (r << (32 - ib_qib_lkey_table_size)) | + ((((1 << (24 - ib_qib_lkey_table_size)) - 1) & rkt->gen) + << 8); + if (mr->lkey == 0) { + mr->lkey |= 1 << 8; + rkt->gen++; + } + rkt->table[r] = mr; + spin_unlock_irqrestore(&rkt->lock, flags); + + ret = 1; + +bail: + return ret; +} + +/** + * qib_free_lkey - free an lkey + * @rkt: table from which to free the lkey + * @lkey: lkey id to free + */ +int qib_free_lkey(struct qib_ibdev *dev, struct qib_mregion *mr) +{ + unsigned long flags; + u32 lkey = mr->lkey; + u32 r; + int ret; + + spin_lock_irqsave(&dev->lk_table.lock, flags); + if (lkey == 0) { + if (dev->dma_mr && dev->dma_mr == mr) { + ret = atomic_read(&dev->dma_mr->refcount); + if (!ret) + dev->dma_mr = NULL; + } else + ret = 0; + } else { + r = lkey >> (32 - ib_qib_lkey_table_size); + ret = atomic_read(&dev->lk_table.table[r]->refcount); + if (!ret) + dev->lk_table.table[r] = NULL; + } + spin_unlock_irqrestore(&dev->lk_table.lock, flags); + + if (ret) + ret = -EBUSY; + return ret; +} + +/** + * qib_lkey_ok - check IB SGE for validity and initialize + * @rkt: table containing lkey to check SGE against + * @isge: outgoing internal SGE + * @sge: SGE to check + * @acc: access flags + * + * Return 1 if valid and successful, otherwise returns 0. + * + * Check the IB SGE for validity and initialize our internal version + * of it. + */ +int qib_lkey_ok(struct qib_lkey_table *rkt, struct qib_pd *pd, + struct qib_sge *isge, struct ib_sge *sge, int acc) +{ + struct qib_mregion *mr; + unsigned n, m; + size_t off; + int ret = 0; + unsigned long flags; + + /* + * We use LKEY == zero for kernel virtual addresses + * (see qib_get_dma_mr and qib_dma.c). + */ + spin_lock_irqsave(&rkt->lock, flags); + if (sge->lkey == 0) { + struct qib_ibdev *dev = to_idev(pd->ibpd.device); + + if (pd->user) + goto bail; + if (!dev->dma_mr) + goto bail; + atomic_inc(&dev->dma_mr->refcount); + isge->mr = dev->dma_mr; + isge->vaddr = (void *) sge->addr; + isge->length = sge->length; + isge->sge_length = sge->length; + isge->m = 0; + isge->n = 0; + goto ok; + } + mr = rkt->table[(sge->lkey >> (32 - ib_qib_lkey_table_size))]; + if (unlikely(mr == NULL || mr->lkey != sge->lkey || + mr->pd != &pd->ibpd)) + goto bail; + + off = sge->addr - mr->user_base; + if (unlikely(sge->addr < mr->user_base || + off + sge->length > mr->length || + (mr->access_flags & acc) != acc)) + goto bail; + + off += mr->offset; + m = 0; + n = 0; + while (off >= mr->map[m]->segs[n].length) { + off -= mr->map[m]->segs[n].length; + n++; + if (n >= QIB_SEGSZ) { + m++; + n = 0; + } + } + atomic_inc(&mr->refcount); + isge->mr = mr; + isge->vaddr = mr->map[m]->segs[n].vaddr + off; + isge->length = mr->map[m]->segs[n].length - off; + isge->sge_length = sge->length; + isge->m = m; + isge->n = n; +ok: + ret = 1; +bail: + spin_unlock_irqrestore(&rkt->lock, flags); + return ret; +} + +/** + * qib_rkey_ok - check the IB virtual address, length, and RKEY + * @dev: infiniband device + * @ss: SGE state + * @len: length of data + * @vaddr: virtual address to place data + * @rkey: rkey to check + * @acc: access flags + * + * Return 1 if successful, otherwise 0. + */ +int qib_rkey_ok(struct qib_qp *qp, struct qib_sge *sge, + u32 len, u64 vaddr, u32 rkey, int acc) +{ + struct qib_lkey_table *rkt = &to_idev(qp->ibqp.device)->lk_table; + struct qib_mregion *mr; + unsigned n, m; + size_t off; + int ret = 0; + unsigned long flags; + + /* + * We use RKEY == zero for kernel virtual addresses + * (see qib_get_dma_mr and qib_dma.c). + */ + spin_lock_irqsave(&rkt->lock, flags); + if (rkey == 0) { + struct qib_pd *pd = to_ipd(qp->ibqp.pd); + struct qib_ibdev *dev = to_idev(pd->ibpd.device); + + if (pd->user) + goto bail; + if (!dev->dma_mr) + goto bail; + atomic_inc(&dev->dma_mr->refcount); + sge->mr = dev->dma_mr; + sge->vaddr = (void *) vaddr; + sge->length = len; + sge->sge_length = len; + sge->m = 0; + sge->n = 0; + goto ok; + } + + mr = rkt->table[(rkey >> (32 - ib_qib_lkey_table_size))]; + if (unlikely(mr == NULL || mr->lkey != rkey || qp->ibqp.pd != mr->pd)) + goto bail; + + off = vaddr - mr->iova; + if (unlikely(vaddr < mr->iova || off + len > mr->length || + (mr->access_flags & acc) == 0)) + goto bail; + + off += mr->offset; + m = 0; + n = 0; + while (off >= mr->map[m]->segs[n].length) { + off -= mr->map[m]->segs[n].length; + n++; + if (n >= QIB_SEGSZ) { + m++; + n = 0; + } + } + atomic_inc(&mr->refcount); + sge->mr = mr; + sge->vaddr = mr->map[m]->segs[n].vaddr + off; + sge->length = mr->map[m]->segs[n].length - off; + sge->sge_length = len; + sge->m = m; + sge->n = n; +ok: + ret = 1; +bail: + spin_unlock_irqrestore(&rkt->lock, flags); + return ret; +} + +/* + * Initialize the memory region specified by the work reqeust. + */ +int qib_fast_reg_mr(struct qib_qp *qp, struct ib_send_wr *wr) +{ + struct qib_lkey_table *rkt = &to_idev(qp->ibqp.device)->lk_table; + struct qib_pd *pd = to_ipd(qp->ibqp.pd); + struct qib_mregion *mr; + u32 rkey = wr->wr.fast_reg.rkey; + unsigned i, n, m; + int ret = -EINVAL; + unsigned long flags; + u64 *page_list; + size_t ps; + + spin_lock_irqsave(&rkt->lock, flags); + if (pd->user || rkey == 0) + goto bail; + + mr = rkt->table[(rkey >> (32 - ib_qib_lkey_table_size))]; + if (unlikely(mr == NULL || qp->ibqp.pd != mr->pd)) + goto bail; + + if (wr->wr.fast_reg.page_list_len > mr->max_segs) + goto bail; + + ps = 1UL << wr->wr.fast_reg.page_shift; + if (wr->wr.fast_reg.length > ps * wr->wr.fast_reg.page_list_len) + goto bail; + + mr->user_base = wr->wr.fast_reg.iova_start; + mr->iova = wr->wr.fast_reg.iova_start; + mr->lkey = rkey; + mr->length = wr->wr.fast_reg.length; + mr->access_flags = wr->wr.fast_reg.access_flags; + page_list = wr->wr.fast_reg.page_list->page_list; + m = 0; + n = 0; + for (i = 0; i < wr->wr.fast_reg.page_list_len; i++) { + mr->map[m]->segs[n].vaddr = (void *) page_list[i]; + mr->map[m]->segs[n].length = ps; + if (++n == QIB_SEGSZ) { + m++; + n = 0; + } + } + + ret = 0; +bail: + spin_unlock_irqrestore(&rkt->lock, flags); + return ret; +} diff --git a/drivers/infiniband/hw/qib/qib_mad.c b/drivers/infiniband/hw/qib/qib_mad.c new file mode 100644 index 000000000000..94b0d1f3a8f0 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_mad.c @@ -0,0 +1,2173 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation. + * All rights reserved. + * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include + +#include "qib.h" +#include "qib_mad.h" + +static int reply(struct ib_smp *smp) +{ + /* + * The verbs framework will handle the directed/LID route + * packet changes. + */ + smp->method = IB_MGMT_METHOD_GET_RESP; + if (smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) + smp->status |= IB_SMP_DIRECTION; + return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY; +} + +static void qib_send_trap(struct qib_ibport *ibp, void *data, unsigned len) +{ + struct ib_mad_send_buf *send_buf; + struct ib_mad_agent *agent; + struct ib_smp *smp; + int ret; + unsigned long flags; + unsigned long timeout; + + agent = ibp->send_agent; + if (!agent) + return; + + /* o14-3.2.1 */ + if (!(ppd_from_ibp(ibp)->lflags & QIBL_LINKACTIVE)) + return; + + /* o14-2 */ + if (ibp->trap_timeout && time_before(jiffies, ibp->trap_timeout)) + return; + + send_buf = ib_create_send_mad(agent, 0, 0, 0, IB_MGMT_MAD_HDR, + IB_MGMT_MAD_DATA, GFP_ATOMIC); + if (IS_ERR(send_buf)) + return; + + smp = send_buf->mad; + smp->base_version = IB_MGMT_BASE_VERSION; + smp->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; + smp->class_version = 1; + smp->method = IB_MGMT_METHOD_TRAP; + ibp->tid++; + smp->tid = cpu_to_be64(ibp->tid); + smp->attr_id = IB_SMP_ATTR_NOTICE; + /* o14-1: smp->mkey = 0; */ + memcpy(smp->data, data, len); + + spin_lock_irqsave(&ibp->lock, flags); + if (!ibp->sm_ah) { + if (ibp->sm_lid != be16_to_cpu(IB_LID_PERMISSIVE)) { + struct ib_ah *ah; + struct ib_ah_attr attr; + + memset(&attr, 0, sizeof attr); + attr.dlid = ibp->sm_lid; + attr.port_num = ppd_from_ibp(ibp)->port; + ah = ib_create_ah(ibp->qp0->ibqp.pd, &attr); + if (IS_ERR(ah)) + ret = -EINVAL; + else { + send_buf->ah = ah; + ibp->sm_ah = to_iah(ah); + ret = 0; + } + } else + ret = -EINVAL; + } else { + send_buf->ah = &ibp->sm_ah->ibah; + ret = 0; + } + spin_unlock_irqrestore(&ibp->lock, flags); + + if (!ret) + ret = ib_post_send_mad(send_buf, NULL); + if (!ret) { + /* 4.096 usec. */ + timeout = (4096 * (1UL << ibp->subnet_timeout)) / 1000; + ibp->trap_timeout = jiffies + usecs_to_jiffies(timeout); + } else { + ib_free_send_mad(send_buf); + ibp->trap_timeout = 0; + } +} + +/* + * Send a bad [PQ]_Key trap (ch. 14.3.8). + */ +void qib_bad_pqkey(struct qib_ibport *ibp, __be16 trap_num, u32 key, u32 sl, + u32 qp1, u32 qp2, __be16 lid1, __be16 lid2) +{ + struct ib_mad_notice_attr data; + + if (trap_num == IB_NOTICE_TRAP_BAD_PKEY) + ibp->pkey_violations++; + else + ibp->qkey_violations++; + ibp->n_pkt_drops++; + + /* Send violation trap */ + data.generic_type = IB_NOTICE_TYPE_SECURITY; + data.prod_type_msb = 0; + data.prod_type_lsb = IB_NOTICE_PROD_CA; + data.trap_num = trap_num; + data.issuer_lid = cpu_to_be16(ppd_from_ibp(ibp)->lid); + data.toggle_count = 0; + memset(&data.details, 0, sizeof data.details); + data.details.ntc_257_258.lid1 = lid1; + data.details.ntc_257_258.lid2 = lid2; + data.details.ntc_257_258.key = cpu_to_be32(key); + data.details.ntc_257_258.sl_qp1 = cpu_to_be32((sl << 28) | qp1); + data.details.ntc_257_258.qp2 = cpu_to_be32(qp2); + + qib_send_trap(ibp, &data, sizeof data); +} + +/* + * Send a bad M_Key trap (ch. 14.3.9). + */ +static void qib_bad_mkey(struct qib_ibport *ibp, struct ib_smp *smp) +{ + struct ib_mad_notice_attr data; + + /* Send violation trap */ + data.generic_type = IB_NOTICE_TYPE_SECURITY; + data.prod_type_msb = 0; + data.prod_type_lsb = IB_NOTICE_PROD_CA; + data.trap_num = IB_NOTICE_TRAP_BAD_MKEY; + data.issuer_lid = cpu_to_be16(ppd_from_ibp(ibp)->lid); + data.toggle_count = 0; + memset(&data.details, 0, sizeof data.details); + data.details.ntc_256.lid = data.issuer_lid; + data.details.ntc_256.method = smp->method; + data.details.ntc_256.attr_id = smp->attr_id; + data.details.ntc_256.attr_mod = smp->attr_mod; + data.details.ntc_256.mkey = smp->mkey; + if (smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) { + u8 hop_cnt; + + data.details.ntc_256.dr_slid = smp->dr_slid; + data.details.ntc_256.dr_trunc_hop = IB_NOTICE_TRAP_DR_NOTICE; + hop_cnt = smp->hop_cnt; + if (hop_cnt > ARRAY_SIZE(data.details.ntc_256.dr_rtn_path)) { + data.details.ntc_256.dr_trunc_hop |= + IB_NOTICE_TRAP_DR_TRUNC; + hop_cnt = ARRAY_SIZE(data.details.ntc_256.dr_rtn_path); + } + data.details.ntc_256.dr_trunc_hop |= hop_cnt; + memcpy(data.details.ntc_256.dr_rtn_path, smp->return_path, + hop_cnt); + } + + qib_send_trap(ibp, &data, sizeof data); +} + +/* + * Send a Port Capability Mask Changed trap (ch. 14.3.11). + */ +void qib_cap_mask_chg(struct qib_ibport *ibp) +{ + struct ib_mad_notice_attr data; + + data.generic_type = IB_NOTICE_TYPE_INFO; + data.prod_type_msb = 0; + data.prod_type_lsb = IB_NOTICE_PROD_CA; + data.trap_num = IB_NOTICE_TRAP_CAP_MASK_CHG; + data.issuer_lid = cpu_to_be16(ppd_from_ibp(ibp)->lid); + data.toggle_count = 0; + memset(&data.details, 0, sizeof data.details); + data.details.ntc_144.lid = data.issuer_lid; + data.details.ntc_144.new_cap_mask = cpu_to_be32(ibp->port_cap_flags); + + qib_send_trap(ibp, &data, sizeof data); +} + +/* + * Send a System Image GUID Changed trap (ch. 14.3.12). + */ +void qib_sys_guid_chg(struct qib_ibport *ibp) +{ + struct ib_mad_notice_attr data; + + data.generic_type = IB_NOTICE_TYPE_INFO; + data.prod_type_msb = 0; + data.prod_type_lsb = IB_NOTICE_PROD_CA; + data.trap_num = IB_NOTICE_TRAP_SYS_GUID_CHG; + data.issuer_lid = cpu_to_be16(ppd_from_ibp(ibp)->lid); + data.toggle_count = 0; + memset(&data.details, 0, sizeof data.details); + data.details.ntc_145.lid = data.issuer_lid; + data.details.ntc_145.new_sys_guid = ib_qib_sys_image_guid; + + qib_send_trap(ibp, &data, sizeof data); +} + +/* + * Send a Node Description Changed trap (ch. 14.3.13). + */ +void qib_node_desc_chg(struct qib_ibport *ibp) +{ + struct ib_mad_notice_attr data; + + data.generic_type = IB_NOTICE_TYPE_INFO; + data.prod_type_msb = 0; + data.prod_type_lsb = IB_NOTICE_PROD_CA; + data.trap_num = IB_NOTICE_TRAP_CAP_MASK_CHG; + data.issuer_lid = cpu_to_be16(ppd_from_ibp(ibp)->lid); + data.toggle_count = 0; + memset(&data.details, 0, sizeof data.details); + data.details.ntc_144.lid = data.issuer_lid; + data.details.ntc_144.local_changes = 1; + data.details.ntc_144.change_flags = IB_NOTICE_TRAP_NODE_DESC_CHG; + + qib_send_trap(ibp, &data, sizeof data); +} + +static int subn_get_nodedescription(struct ib_smp *smp, + struct ib_device *ibdev) +{ + if (smp->attr_mod) + smp->status |= IB_SMP_INVALID_FIELD; + + memcpy(smp->data, ibdev->node_desc, sizeof(smp->data)); + + return reply(smp); +} + +static int subn_get_nodeinfo(struct ib_smp *smp, struct ib_device *ibdev, + u8 port) +{ + struct ib_node_info *nip = (struct ib_node_info *)&smp->data; + struct qib_devdata *dd = dd_from_ibdev(ibdev); + u32 vendor, majrev, minrev; + unsigned pidx = port - 1; /* IB number port from 1, hdw from 0 */ + + /* GUID 0 is illegal */ + if (smp->attr_mod || pidx >= dd->num_pports || + dd->pport[pidx].guid == 0) + smp->status |= IB_SMP_INVALID_FIELD; + else + nip->port_guid = dd->pport[pidx].guid; + + nip->base_version = 1; + nip->class_version = 1; + nip->node_type = 1; /* channel adapter */ + nip->num_ports = ibdev->phys_port_cnt; + /* This is already in network order */ + nip->sys_guid = ib_qib_sys_image_guid; + nip->node_guid = dd->pport->guid; /* Use first-port GUID as node */ + nip->partition_cap = cpu_to_be16(qib_get_npkeys(dd)); + nip->device_id = cpu_to_be16(dd->deviceid); + majrev = dd->majrev; + minrev = dd->minrev; + nip->revision = cpu_to_be32((majrev << 16) | minrev); + nip->local_port_num = port; + vendor = dd->vendorid; + nip->vendor_id[0] = QIB_SRC_OUI_1; + nip->vendor_id[1] = QIB_SRC_OUI_2; + nip->vendor_id[2] = QIB_SRC_OUI_3; + + return reply(smp); +} + +static int subn_get_guidinfo(struct ib_smp *smp, struct ib_device *ibdev, + u8 port) +{ + struct qib_devdata *dd = dd_from_ibdev(ibdev); + u32 startgx = 8 * be32_to_cpu(smp->attr_mod); + __be64 *p = (__be64 *) smp->data; + unsigned pidx = port - 1; /* IB number port from 1, hdw from 0 */ + + /* 32 blocks of 8 64-bit GUIDs per block */ + + memset(smp->data, 0, sizeof(smp->data)); + + if (startgx == 0 && pidx < dd->num_pports) { + struct qib_pportdata *ppd = dd->pport + pidx; + struct qib_ibport *ibp = &ppd->ibport_data; + __be64 g = ppd->guid; + unsigned i; + + /* GUID 0 is illegal */ + if (g == 0) + smp->status |= IB_SMP_INVALID_FIELD; + else { + /* The first is a copy of the read-only HW GUID. */ + p[0] = g; + for (i = 1; i < QIB_GUIDS_PER_PORT; i++) + p[i] = ibp->guids[i - 1]; + } + } else + smp->status |= IB_SMP_INVALID_FIELD; + + return reply(smp); +} + +static void set_link_width_enabled(struct qib_pportdata *ppd, u32 w) +{ + (void) ppd->dd->f_set_ib_cfg(ppd, QIB_IB_CFG_LWID_ENB, w); +} + +static void set_link_speed_enabled(struct qib_pportdata *ppd, u32 s) +{ + (void) ppd->dd->f_set_ib_cfg(ppd, QIB_IB_CFG_SPD_ENB, s); +} + +static int get_overrunthreshold(struct qib_pportdata *ppd) +{ + return ppd->dd->f_get_ib_cfg(ppd, QIB_IB_CFG_OVERRUN_THRESH); +} + +/** + * set_overrunthreshold - set the overrun threshold + * @ppd: the physical port data + * @n: the new threshold + * + * Note that this will only take effect when the link state changes. + */ +static int set_overrunthreshold(struct qib_pportdata *ppd, unsigned n) +{ + (void) ppd->dd->f_set_ib_cfg(ppd, QIB_IB_CFG_OVERRUN_THRESH, + (u32)n); + return 0; +} + +static int get_phyerrthreshold(struct qib_pportdata *ppd) +{ + return ppd->dd->f_get_ib_cfg(ppd, QIB_IB_CFG_PHYERR_THRESH); +} + +/** + * set_phyerrthreshold - set the physical error threshold + * @ppd: the physical port data + * @n: the new threshold + * + * Note that this will only take effect when the link state changes. + */ +static int set_phyerrthreshold(struct qib_pportdata *ppd, unsigned n) +{ + (void) ppd->dd->f_set_ib_cfg(ppd, QIB_IB_CFG_PHYERR_THRESH, + (u32)n); + return 0; +} + +/** + * get_linkdowndefaultstate - get the default linkdown state + * @ppd: the physical port data + * + * Returns zero if the default is POLL, 1 if the default is SLEEP. + */ +static int get_linkdowndefaultstate(struct qib_pportdata *ppd) +{ + return ppd->dd->f_get_ib_cfg(ppd, QIB_IB_CFG_LINKDEFAULT) == + IB_LINKINITCMD_SLEEP; +} + +static int check_mkey(struct qib_ibport *ibp, struct ib_smp *smp, int mad_flags) +{ + int ret = 0; + + /* Is the mkey in the process of expiring? */ + if (ibp->mkey_lease_timeout && + time_after_eq(jiffies, ibp->mkey_lease_timeout)) { + /* Clear timeout and mkey protection field. */ + ibp->mkey_lease_timeout = 0; + ibp->mkeyprot = 0; + } + + /* M_Key checking depends on Portinfo:M_Key_protect_bits */ + if ((mad_flags & IB_MAD_IGNORE_MKEY) == 0 && ibp->mkey != 0 && + ibp->mkey != smp->mkey && + (smp->method == IB_MGMT_METHOD_SET || + smp->method == IB_MGMT_METHOD_TRAP_REPRESS || + (smp->method == IB_MGMT_METHOD_GET && ibp->mkeyprot >= 2))) { + if (ibp->mkey_violations != 0xFFFF) + ++ibp->mkey_violations; + if (!ibp->mkey_lease_timeout && ibp->mkey_lease_period) + ibp->mkey_lease_timeout = jiffies + + ibp->mkey_lease_period * HZ; + /* Generate a trap notice. */ + qib_bad_mkey(ibp, smp); + ret = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED; + } else if (ibp->mkey_lease_timeout) + ibp->mkey_lease_timeout = 0; + + return ret; +} + +static int subn_get_portinfo(struct ib_smp *smp, struct ib_device *ibdev, + u8 port) +{ + struct qib_devdata *dd; + struct qib_pportdata *ppd; + struct qib_ibport *ibp; + struct ib_port_info *pip = (struct ib_port_info *)smp->data; + u16 lid; + u8 mtu; + int ret; + u32 state; + u32 port_num = be32_to_cpu(smp->attr_mod); + + if (port_num == 0) + port_num = port; + else { + if (port_num > ibdev->phys_port_cnt) { + smp->status |= IB_SMP_INVALID_FIELD; + ret = reply(smp); + goto bail; + } + if (port_num != port) { + ibp = to_iport(ibdev, port_num); + ret = check_mkey(ibp, smp, 0); + if (ret) + goto bail; + } + } + + dd = dd_from_ibdev(ibdev); + /* IB numbers ports from 1, hdw from 0 */ + ppd = dd->pport + (port_num - 1); + ibp = &ppd->ibport_data; + + /* Clear all fields. Only set the non-zero fields. */ + memset(smp->data, 0, sizeof(smp->data)); + + /* Only return the mkey if the protection field allows it. */ + if (smp->method == IB_MGMT_METHOD_SET || ibp->mkey == smp->mkey || + ibp->mkeyprot == 0) + pip->mkey = ibp->mkey; + pip->gid_prefix = ibp->gid_prefix; + lid = ppd->lid; + pip->lid = lid ? cpu_to_be16(lid) : IB_LID_PERMISSIVE; + pip->sm_lid = cpu_to_be16(ibp->sm_lid); + pip->cap_mask = cpu_to_be32(ibp->port_cap_flags); + /* pip->diag_code; */ + pip->mkey_lease_period = cpu_to_be16(ibp->mkey_lease_period); + pip->local_port_num = port; + pip->link_width_enabled = ppd->link_width_enabled; + pip->link_width_supported = ppd->link_width_supported; + pip->link_width_active = ppd->link_width_active; + state = dd->f_iblink_state(ppd->lastibcstat); + pip->linkspeed_portstate = ppd->link_speed_supported << 4 | state; + + pip->portphysstate_linkdown = + (dd->f_ibphys_portstate(ppd->lastibcstat) << 4) | + (get_linkdowndefaultstate(ppd) ? 1 : 2); + pip->mkeyprot_resv_lmc = (ibp->mkeyprot << 6) | ppd->lmc; + pip->linkspeedactive_enabled = (ppd->link_speed_active << 4) | + ppd->link_speed_enabled; + switch (ppd->ibmtu) { + default: /* something is wrong; fall through */ + case 4096: + mtu = IB_MTU_4096; + break; + case 2048: + mtu = IB_MTU_2048; + break; + case 1024: + mtu = IB_MTU_1024; + break; + case 512: + mtu = IB_MTU_512; + break; + case 256: + mtu = IB_MTU_256; + break; + } + pip->neighbormtu_mastersmsl = (mtu << 4) | ibp->sm_sl; + pip->vlcap_inittype = ppd->vls_supported << 4; /* InitType = 0 */ + pip->vl_high_limit = ibp->vl_high_limit; + pip->vl_arb_high_cap = + dd->f_get_ib_cfg(ppd, QIB_IB_CFG_VL_HIGH_CAP); + pip->vl_arb_low_cap = + dd->f_get_ib_cfg(ppd, QIB_IB_CFG_VL_LOW_CAP); + /* InitTypeReply = 0 */ + pip->inittypereply_mtucap = qib_ibmtu ? qib_ibmtu : IB_MTU_4096; + /* HCAs ignore VLStallCount and HOQLife */ + /* pip->vlstallcnt_hoqlife; */ + pip->operationalvl_pei_peo_fpi_fpo = + dd->f_get_ib_cfg(ppd, QIB_IB_CFG_OP_VLS) << 4; + pip->mkey_violations = cpu_to_be16(ibp->mkey_violations); + /* P_KeyViolations are counted by hardware. */ + pip->pkey_violations = cpu_to_be16(ibp->pkey_violations); + pip->qkey_violations = cpu_to_be16(ibp->qkey_violations); + /* Only the hardware GUID is supported for now */ + pip->guid_cap = QIB_GUIDS_PER_PORT; + pip->clientrereg_resv_subnetto = ibp->subnet_timeout; + /* 32.768 usec. response time (guessing) */ + pip->resv_resptimevalue = 3; + pip->localphyerrors_overrunerrors = + (get_phyerrthreshold(ppd) << 4) | + get_overrunthreshold(ppd); + /* pip->max_credit_hint; */ + if (ibp->port_cap_flags & IB_PORT_LINK_LATENCY_SUP) { + u32 v; + + v = dd->f_get_ib_cfg(ppd, QIB_IB_CFG_LINKLATENCY); + pip->link_roundtrip_latency[0] = v >> 16; + pip->link_roundtrip_latency[1] = v >> 8; + pip->link_roundtrip_latency[2] = v; + } + + ret = reply(smp); + +bail: + return ret; +} + +/** + * get_pkeys - return the PKEY table + * @dd: the qlogic_ib device + * @port: the IB port number + * @pkeys: the pkey table is placed here + */ +static int get_pkeys(struct qib_devdata *dd, u8 port, u16 *pkeys) +{ + struct qib_pportdata *ppd = dd->pport + port - 1; + /* + * always a kernel context, no locking needed. + * If we get here with ppd setup, no need to check + * that pd is valid. + */ + struct qib_ctxtdata *rcd = dd->rcd[ppd->hw_pidx]; + + memcpy(pkeys, rcd->pkeys, sizeof(rcd->pkeys)); + + return 0; +} + +static int subn_get_pkeytable(struct ib_smp *smp, struct ib_device *ibdev, + u8 port) +{ + u32 startpx = 32 * (be32_to_cpu(smp->attr_mod) & 0xffff); + u16 *p = (u16 *) smp->data; + __be16 *q = (__be16 *) smp->data; + + /* 64 blocks of 32 16-bit P_Key entries */ + + memset(smp->data, 0, sizeof(smp->data)); + if (startpx == 0) { + struct qib_devdata *dd = dd_from_ibdev(ibdev); + unsigned i, n = qib_get_npkeys(dd); + + get_pkeys(dd, port, p); + + for (i = 0; i < n; i++) + q[i] = cpu_to_be16(p[i]); + } else + smp->status |= IB_SMP_INVALID_FIELD; + + return reply(smp); +} + +static int subn_set_guidinfo(struct ib_smp *smp, struct ib_device *ibdev, + u8 port) +{ + struct qib_devdata *dd = dd_from_ibdev(ibdev); + u32 startgx = 8 * be32_to_cpu(smp->attr_mod); + __be64 *p = (__be64 *) smp->data; + unsigned pidx = port - 1; /* IB number port from 1, hdw from 0 */ + + /* 32 blocks of 8 64-bit GUIDs per block */ + + if (startgx == 0 && pidx < dd->num_pports) { + struct qib_pportdata *ppd = dd->pport + pidx; + struct qib_ibport *ibp = &ppd->ibport_data; + unsigned i; + + /* The first entry is read-only. */ + for (i = 1; i < QIB_GUIDS_PER_PORT; i++) + ibp->guids[i - 1] = p[i]; + } else + smp->status |= IB_SMP_INVALID_FIELD; + + /* The only GUID we support is the first read-only entry. */ + return subn_get_guidinfo(smp, ibdev, port); +} + +/** + * subn_set_portinfo - set port information + * @smp: the incoming SM packet + * @ibdev: the infiniband device + * @port: the port on the device + * + * Set Portinfo (see ch. 14.2.5.6). + */ +static int subn_set_portinfo(struct ib_smp *smp, struct ib_device *ibdev, + u8 port) +{ + struct ib_port_info *pip = (struct ib_port_info *)smp->data; + struct ib_event event; + struct qib_devdata *dd; + struct qib_pportdata *ppd; + struct qib_ibport *ibp; + char clientrereg = 0; + unsigned long flags; + u16 lid, smlid; + u8 lwe; + u8 lse; + u8 state; + u8 vls; + u8 msl; + u16 lstate; + int ret, ore, mtu; + u32 port_num = be32_to_cpu(smp->attr_mod); + + if (port_num == 0) + port_num = port; + else { + if (port_num > ibdev->phys_port_cnt) + goto err; + /* Port attributes can only be set on the receiving port */ + if (port_num != port) + goto get_only; + } + + dd = dd_from_ibdev(ibdev); + /* IB numbers ports from 1, hdw from 0 */ + ppd = dd->pport + (port_num - 1); + ibp = &ppd->ibport_data; + event.device = ibdev; + event.element.port_num = port; + + ibp->mkey = pip->mkey; + ibp->gid_prefix = pip->gid_prefix; + ibp->mkey_lease_period = be16_to_cpu(pip->mkey_lease_period); + + lid = be16_to_cpu(pip->lid); + /* Must be a valid unicast LID address. */ + if (lid == 0 || lid >= QIB_MULTICAST_LID_BASE) + goto err; + if (ppd->lid != lid || ppd->lmc != (pip->mkeyprot_resv_lmc & 7)) { + if (ppd->lid != lid) + qib_set_uevent_bits(ppd, _QIB_EVENT_LID_CHANGE_BIT); + if (ppd->lmc != (pip->mkeyprot_resv_lmc & 7)) + qib_set_uevent_bits(ppd, _QIB_EVENT_LMC_CHANGE_BIT); + qib_set_lid(ppd, lid, pip->mkeyprot_resv_lmc & 7); + event.event = IB_EVENT_LID_CHANGE; + ib_dispatch_event(&event); + } + + smlid = be16_to_cpu(pip->sm_lid); + msl = pip->neighbormtu_mastersmsl & 0xF; + /* Must be a valid unicast LID address. */ + if (smlid == 0 || smlid >= QIB_MULTICAST_LID_BASE) + goto err; + if (smlid != ibp->sm_lid || msl != ibp->sm_sl) { + spin_lock_irqsave(&ibp->lock, flags); + if (ibp->sm_ah) { + if (smlid != ibp->sm_lid) + ibp->sm_ah->attr.dlid = smlid; + if (msl != ibp->sm_sl) + ibp->sm_ah->attr.sl = msl; + } + spin_unlock_irqrestore(&ibp->lock, flags); + if (smlid != ibp->sm_lid) + ibp->sm_lid = smlid; + if (msl != ibp->sm_sl) + ibp->sm_sl = msl; + event.event = IB_EVENT_SM_CHANGE; + ib_dispatch_event(&event); + } + + /* Allow 1x or 4x to be set (see 14.2.6.6). */ + lwe = pip->link_width_enabled; + if (lwe) { + if (lwe == 0xFF) + lwe = ppd->link_width_supported; + else if (lwe >= 16 || (lwe & ~ppd->link_width_supported)) + goto err; + set_link_width_enabled(ppd, lwe); + } + + lse = pip->linkspeedactive_enabled & 0xF; + if (lse) { + /* + * The IB 1.2 spec. only allows link speed values + * 1, 3, 5, 7, 15. 1.2.1 extended to allow specific + * speeds. + */ + if (lse == 15) + lse = ppd->link_speed_supported; + else if (lse >= 8 || (lse & ~ppd->link_speed_supported)) + goto err; + set_link_speed_enabled(ppd, lse); + } + + /* Set link down default state. */ + switch (pip->portphysstate_linkdown & 0xF) { + case 0: /* NOP */ + break; + case 1: /* SLEEP */ + (void) dd->f_set_ib_cfg(ppd, QIB_IB_CFG_LINKDEFAULT, + IB_LINKINITCMD_SLEEP); + break; + case 2: /* POLL */ + (void) dd->f_set_ib_cfg(ppd, QIB_IB_CFG_LINKDEFAULT, + IB_LINKINITCMD_POLL); + break; + default: + goto err; + } + + ibp->mkeyprot = pip->mkeyprot_resv_lmc >> 6; + ibp->vl_high_limit = pip->vl_high_limit; + (void) dd->f_set_ib_cfg(ppd, QIB_IB_CFG_VL_HIGH_LIMIT, + ibp->vl_high_limit); + + mtu = ib_mtu_enum_to_int((pip->neighbormtu_mastersmsl >> 4) & 0xF); + if (mtu == -1) + goto err; + qib_set_mtu(ppd, mtu); + + /* Set operational VLs */ + vls = (pip->operationalvl_pei_peo_fpi_fpo >> 4) & 0xF; + if (vls) { + if (vls > ppd->vls_supported) + goto err; + (void) dd->f_set_ib_cfg(ppd, QIB_IB_CFG_OP_VLS, vls); + } + + if (pip->mkey_violations == 0) + ibp->mkey_violations = 0; + + if (pip->pkey_violations == 0) + ibp->pkey_violations = 0; + + if (pip->qkey_violations == 0) + ibp->qkey_violations = 0; + + ore = pip->localphyerrors_overrunerrors; + if (set_phyerrthreshold(ppd, (ore >> 4) & 0xF)) + goto err; + + if (set_overrunthreshold(ppd, (ore & 0xF))) + goto err; + + ibp->subnet_timeout = pip->clientrereg_resv_subnetto & 0x1F; + + if (pip->clientrereg_resv_subnetto & 0x80) { + clientrereg = 1; + event.event = IB_EVENT_CLIENT_REREGISTER; + ib_dispatch_event(&event); + } + + /* + * Do the port state change now that the other link parameters + * have been set. + * Changing the port physical state only makes sense if the link + * is down or is being set to down. + */ + state = pip->linkspeed_portstate & 0xF; + lstate = (pip->portphysstate_linkdown >> 4) & 0xF; + if (lstate && !(state == IB_PORT_DOWN || state == IB_PORT_NOP)) + goto err; + + /* + * Only state changes of DOWN, ARM, and ACTIVE are valid + * and must be in the correct state to take effect (see 7.2.6). + */ + switch (state) { + case IB_PORT_NOP: + if (lstate == 0) + break; + /* FALLTHROUGH */ + case IB_PORT_DOWN: + if (lstate == 0) + lstate = QIB_IB_LINKDOWN_ONLY; + else if (lstate == 1) + lstate = QIB_IB_LINKDOWN_SLEEP; + else if (lstate == 2) + lstate = QIB_IB_LINKDOWN; + else if (lstate == 3) + lstate = QIB_IB_LINKDOWN_DISABLE; + else + goto err; + spin_lock_irqsave(&ppd->lflags_lock, flags); + ppd->lflags &= ~QIBL_LINKV; + spin_unlock_irqrestore(&ppd->lflags_lock, flags); + qib_set_linkstate(ppd, lstate); + /* + * Don't send a reply if the response would be sent + * through the disabled port. + */ + if (lstate == QIB_IB_LINKDOWN_DISABLE && smp->hop_cnt) { + ret = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED; + goto done; + } + qib_wait_linkstate(ppd, QIBL_LINKV, 10); + break; + case IB_PORT_ARMED: + qib_set_linkstate(ppd, QIB_IB_LINKARM); + break; + case IB_PORT_ACTIVE: + qib_set_linkstate(ppd, QIB_IB_LINKACTIVE); + break; + default: + /* XXX We have already partially updated our state! */ + goto err; + } + + ret = subn_get_portinfo(smp, ibdev, port); + + if (clientrereg) + pip->clientrereg_resv_subnetto |= 0x80; + + goto done; + +err: + smp->status |= IB_SMP_INVALID_FIELD; +get_only: + ret = subn_get_portinfo(smp, ibdev, port); +done: + return ret; +} + +/** + * rm_pkey - decrecment the reference count for the given PKEY + * @dd: the qlogic_ib device + * @key: the PKEY index + * + * Return true if this was the last reference and the hardware table entry + * needs to be changed. + */ +static int rm_pkey(struct qib_pportdata *ppd, u16 key) +{ + int i; + int ret; + + for (i = 0; i < ARRAY_SIZE(ppd->pkeys); i++) { + if (ppd->pkeys[i] != key) + continue; + if (atomic_dec_and_test(&ppd->pkeyrefs[i])) { + ppd->pkeys[i] = 0; + ret = 1; + goto bail; + } + break; + } + + ret = 0; + +bail: + return ret; +} + +/** + * add_pkey - add the given PKEY to the hardware table + * @dd: the qlogic_ib device + * @key: the PKEY + * + * Return an error code if unable to add the entry, zero if no change, + * or 1 if the hardware PKEY register needs to be updated. + */ +static int add_pkey(struct qib_pportdata *ppd, u16 key) +{ + int i; + u16 lkey = key & 0x7FFF; + int any = 0; + int ret; + + if (lkey == 0x7FFF) { + ret = 0; + goto bail; + } + + /* Look for an empty slot or a matching PKEY. */ + for (i = 0; i < ARRAY_SIZE(ppd->pkeys); i++) { + if (!ppd->pkeys[i]) { + any++; + continue; + } + /* If it matches exactly, try to increment the ref count */ + if (ppd->pkeys[i] == key) { + if (atomic_inc_return(&ppd->pkeyrefs[i]) > 1) { + ret = 0; + goto bail; + } + /* Lost the race. Look for an empty slot below. */ + atomic_dec(&ppd->pkeyrefs[i]); + any++; + } + /* + * It makes no sense to have both the limited and unlimited + * PKEY set at the same time since the unlimited one will + * disable the limited one. + */ + if ((ppd->pkeys[i] & 0x7FFF) == lkey) { + ret = -EEXIST; + goto bail; + } + } + if (!any) { + ret = -EBUSY; + goto bail; + } + for (i = 0; i < ARRAY_SIZE(ppd->pkeys); i++) { + if (!ppd->pkeys[i] && + atomic_inc_return(&ppd->pkeyrefs[i]) == 1) { + /* for qibstats, etc. */ + ppd->pkeys[i] = key; + ret = 1; + goto bail; + } + } + ret = -EBUSY; + +bail: + return ret; +} + +/** + * set_pkeys - set the PKEY table for ctxt 0 + * @dd: the qlogic_ib device + * @port: the IB port number + * @pkeys: the PKEY table + */ +static int set_pkeys(struct qib_devdata *dd, u8 port, u16 *pkeys) +{ + struct qib_pportdata *ppd; + struct qib_ctxtdata *rcd; + int i; + int changed = 0; + + /* + * IB port one/two always maps to context zero/one, + * always a kernel context, no locking needed + * If we get here with ppd setup, no need to check + * that rcd is valid. + */ + ppd = dd->pport + (port - 1); + rcd = dd->rcd[ppd->hw_pidx]; + + for (i = 0; i < ARRAY_SIZE(rcd->pkeys); i++) { + u16 key = pkeys[i]; + u16 okey = rcd->pkeys[i]; + + if (key == okey) + continue; + /* + * The value of this PKEY table entry is changing. + * Remove the old entry in the hardware's array of PKEYs. + */ + if (okey & 0x7FFF) + changed |= rm_pkey(ppd, okey); + if (key & 0x7FFF) { + int ret = add_pkey(ppd, key); + + if (ret < 0) + key = 0; + else + changed |= ret; + } + rcd->pkeys[i] = key; + } + if (changed) { + struct ib_event event; + + (void) dd->f_set_ib_cfg(ppd, QIB_IB_CFG_PKEYS, 0); + + event.event = IB_EVENT_PKEY_CHANGE; + event.device = &dd->verbs_dev.ibdev; + event.element.port_num = 1; + ib_dispatch_event(&event); + } + return 0; +} + +static int subn_set_pkeytable(struct ib_smp *smp, struct ib_device *ibdev, + u8 port) +{ + u32 startpx = 32 * (be32_to_cpu(smp->attr_mod) & 0xffff); + __be16 *p = (__be16 *) smp->data; + u16 *q = (u16 *) smp->data; + struct qib_devdata *dd = dd_from_ibdev(ibdev); + unsigned i, n = qib_get_npkeys(dd); + + for (i = 0; i < n; i++) + q[i] = be16_to_cpu(p[i]); + + if (startpx != 0 || set_pkeys(dd, port, q) != 0) + smp->status |= IB_SMP_INVALID_FIELD; + + return subn_get_pkeytable(smp, ibdev, port); +} + +static int subn_get_sl_to_vl(struct ib_smp *smp, struct ib_device *ibdev, + u8 port) +{ + struct qib_ibport *ibp = to_iport(ibdev, port); + u8 *p = (u8 *) smp->data; + unsigned i; + + memset(smp->data, 0, sizeof(smp->data)); + + if (!(ibp->port_cap_flags & IB_PORT_SL_MAP_SUP)) + smp->status |= IB_SMP_UNSUP_METHOD; + else + for (i = 0; i < ARRAY_SIZE(ibp->sl_to_vl); i += 2) + *p++ = (ibp->sl_to_vl[i] << 4) | ibp->sl_to_vl[i + 1]; + + return reply(smp); +} + +static int subn_set_sl_to_vl(struct ib_smp *smp, struct ib_device *ibdev, + u8 port) +{ + struct qib_ibport *ibp = to_iport(ibdev, port); + u8 *p = (u8 *) smp->data; + unsigned i; + + if (!(ibp->port_cap_flags & IB_PORT_SL_MAP_SUP)) { + smp->status |= IB_SMP_UNSUP_METHOD; + return reply(smp); + } + + for (i = 0; i < ARRAY_SIZE(ibp->sl_to_vl); i += 2, p++) { + ibp->sl_to_vl[i] = *p >> 4; + ibp->sl_to_vl[i + 1] = *p & 0xF; + } + qib_set_uevent_bits(ppd_from_ibp(to_iport(ibdev, port)), + _QIB_EVENT_SL2VL_CHANGE_BIT); + + return subn_get_sl_to_vl(smp, ibdev, port); +} + +static int subn_get_vl_arb(struct ib_smp *smp, struct ib_device *ibdev, + u8 port) +{ + unsigned which = be32_to_cpu(smp->attr_mod) >> 16; + struct qib_pportdata *ppd = ppd_from_ibp(to_iport(ibdev, port)); + + memset(smp->data, 0, sizeof(smp->data)); + + if (ppd->vls_supported == IB_VL_VL0) + smp->status |= IB_SMP_UNSUP_METHOD; + else if (which == IB_VLARB_LOWPRI_0_31) + (void) ppd->dd->f_get_ib_table(ppd, QIB_IB_TBL_VL_LOW_ARB, + smp->data); + else if (which == IB_VLARB_HIGHPRI_0_31) + (void) ppd->dd->f_get_ib_table(ppd, QIB_IB_TBL_VL_HIGH_ARB, + smp->data); + else + smp->status |= IB_SMP_INVALID_FIELD; + + return reply(smp); +} + +static int subn_set_vl_arb(struct ib_smp *smp, struct ib_device *ibdev, + u8 port) +{ + unsigned which = be32_to_cpu(smp->attr_mod) >> 16; + struct qib_pportdata *ppd = ppd_from_ibp(to_iport(ibdev, port)); + + if (ppd->vls_supported == IB_VL_VL0) + smp->status |= IB_SMP_UNSUP_METHOD; + else if (which == IB_VLARB_LOWPRI_0_31) + (void) ppd->dd->f_set_ib_table(ppd, QIB_IB_TBL_VL_LOW_ARB, + smp->data); + else if (which == IB_VLARB_HIGHPRI_0_31) + (void) ppd->dd->f_set_ib_table(ppd, QIB_IB_TBL_VL_HIGH_ARB, + smp->data); + else + smp->status |= IB_SMP_INVALID_FIELD; + + return subn_get_vl_arb(smp, ibdev, port); +} + +static int subn_trap_repress(struct ib_smp *smp, struct ib_device *ibdev, + u8 port) +{ + /* + * For now, we only send the trap once so no need to process this. + * o13-6, o13-7, + * o14-3.a4 The SMA shall not send any message in response to a valid + * SubnTrapRepress() message. + */ + return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED; +} + +static int pma_get_classportinfo(struct ib_perf *pmp, + struct ib_device *ibdev) +{ + struct ib_pma_classportinfo *p = + (struct ib_pma_classportinfo *)pmp->data; + struct qib_devdata *dd = dd_from_ibdev(ibdev); + + memset(pmp->data, 0, sizeof(pmp->data)); + + if (pmp->attr_mod != 0) + pmp->status |= IB_SMP_INVALID_FIELD; + + /* Note that AllPortSelect is not valid */ + p->base_version = 1; + p->class_version = 1; + p->cap_mask = IB_PMA_CLASS_CAP_EXT_WIDTH; + /* + * Set the most significant bit of CM2 to indicate support for + * congestion statistics + */ + p->reserved[0] = dd->psxmitwait_supported << 7; + /* + * Expected response time is 4.096 usec. * 2^18 == 1.073741824 sec. + */ + p->resp_time_value = 18; + + return reply((struct ib_smp *) pmp); +} + +static int pma_get_portsamplescontrol(struct ib_perf *pmp, + struct ib_device *ibdev, u8 port) +{ + struct ib_pma_portsamplescontrol *p = + (struct ib_pma_portsamplescontrol *)pmp->data; + struct qib_ibdev *dev = to_idev(ibdev); + struct qib_devdata *dd = dd_from_dev(dev); + struct qib_ibport *ibp = to_iport(ibdev, port); + struct qib_pportdata *ppd = ppd_from_ibp(ibp); + unsigned long flags; + u8 port_select = p->port_select; + + memset(pmp->data, 0, sizeof(pmp->data)); + + p->port_select = port_select; + if (pmp->attr_mod != 0 || port_select != port) { + pmp->status |= IB_SMP_INVALID_FIELD; + goto bail; + } + spin_lock_irqsave(&ibp->lock, flags); + p->tick = dd->f_get_ib_cfg(ppd, QIB_IB_CFG_PMA_TICKS); + p->sample_status = dd->f_portcntr(ppd, QIBPORTCNTR_PSSTAT); + p->counter_width = 4; /* 32 bit counters */ + p->counter_mask0_9 = COUNTER_MASK0_9; + p->sample_start = cpu_to_be32(ibp->pma_sample_start); + p->sample_interval = cpu_to_be32(ibp->pma_sample_interval); + p->tag = cpu_to_be16(ibp->pma_tag); + p->counter_select[0] = ibp->pma_counter_select[0]; + p->counter_select[1] = ibp->pma_counter_select[1]; + p->counter_select[2] = ibp->pma_counter_select[2]; + p->counter_select[3] = ibp->pma_counter_select[3]; + p->counter_select[4] = ibp->pma_counter_select[4]; + spin_unlock_irqrestore(&ibp->lock, flags); + +bail: + return reply((struct ib_smp *) pmp); +} + +static int pma_set_portsamplescontrol(struct ib_perf *pmp, + struct ib_device *ibdev, u8 port) +{ + struct ib_pma_portsamplescontrol *p = + (struct ib_pma_portsamplescontrol *)pmp->data; + struct qib_ibdev *dev = to_idev(ibdev); + struct qib_devdata *dd = dd_from_dev(dev); + struct qib_ibport *ibp = to_iport(ibdev, port); + struct qib_pportdata *ppd = ppd_from_ibp(ibp); + unsigned long flags; + u8 status, xmit_flags; + int ret; + + if (pmp->attr_mod != 0 || p->port_select != port) { + pmp->status |= IB_SMP_INVALID_FIELD; + ret = reply((struct ib_smp *) pmp); + goto bail; + } + + spin_lock_irqsave(&ibp->lock, flags); + + /* Port Sampling code owns the PS* HW counters */ + xmit_flags = ppd->cong_stats.flags; + ppd->cong_stats.flags = IB_PMA_CONG_HW_CONTROL_SAMPLE; + status = dd->f_portcntr(ppd, QIBPORTCNTR_PSSTAT); + if (status == IB_PMA_SAMPLE_STATUS_DONE || + (status == IB_PMA_SAMPLE_STATUS_RUNNING && + xmit_flags == IB_PMA_CONG_HW_CONTROL_TIMER)) { + ibp->pma_sample_start = be32_to_cpu(p->sample_start); + ibp->pma_sample_interval = be32_to_cpu(p->sample_interval); + ibp->pma_tag = be16_to_cpu(p->tag); + ibp->pma_counter_select[0] = p->counter_select[0]; + ibp->pma_counter_select[1] = p->counter_select[1]; + ibp->pma_counter_select[2] = p->counter_select[2]; + ibp->pma_counter_select[3] = p->counter_select[3]; + ibp->pma_counter_select[4] = p->counter_select[4]; + dd->f_set_cntr_sample(ppd, ibp->pma_sample_interval, + ibp->pma_sample_start); + } + spin_unlock_irqrestore(&ibp->lock, flags); + + ret = pma_get_portsamplescontrol(pmp, ibdev, port); + +bail: + return ret; +} + +static u64 get_counter(struct qib_ibport *ibp, struct qib_pportdata *ppd, + __be16 sel) +{ + u64 ret; + + switch (sel) { + case IB_PMA_PORT_XMIT_DATA: + ret = ppd->dd->f_portcntr(ppd, QIBPORTCNTR_PSXMITDATA); + break; + case IB_PMA_PORT_RCV_DATA: + ret = ppd->dd->f_portcntr(ppd, QIBPORTCNTR_PSRCVDATA); + break; + case IB_PMA_PORT_XMIT_PKTS: + ret = ppd->dd->f_portcntr(ppd, QIBPORTCNTR_PSXMITPKTS); + break; + case IB_PMA_PORT_RCV_PKTS: + ret = ppd->dd->f_portcntr(ppd, QIBPORTCNTR_PSRCVPKTS); + break; + case IB_PMA_PORT_XMIT_WAIT: + ret = ppd->dd->f_portcntr(ppd, QIBPORTCNTR_PSXMITWAIT); + break; + default: + ret = 0; + } + + return ret; +} + +/* This function assumes that the xmit_wait lock is already held */ +static u64 xmit_wait_get_value_delta(struct qib_pportdata *ppd) +{ + u32 delta; + + delta = get_counter(&ppd->ibport_data, ppd, + IB_PMA_PORT_XMIT_WAIT); + return ppd->cong_stats.counter + delta; +} + +static void cache_hw_sample_counters(struct qib_pportdata *ppd) +{ + struct qib_ibport *ibp = &ppd->ibport_data; + + ppd->cong_stats.counter_cache.psxmitdata = + get_counter(ibp, ppd, IB_PMA_PORT_XMIT_DATA); + ppd->cong_stats.counter_cache.psrcvdata = + get_counter(ibp, ppd, IB_PMA_PORT_RCV_DATA); + ppd->cong_stats.counter_cache.psxmitpkts = + get_counter(ibp, ppd, IB_PMA_PORT_XMIT_PKTS); + ppd->cong_stats.counter_cache.psrcvpkts = + get_counter(ibp, ppd, IB_PMA_PORT_RCV_PKTS); + ppd->cong_stats.counter_cache.psxmitwait = + get_counter(ibp, ppd, IB_PMA_PORT_XMIT_WAIT); +} + +static u64 get_cache_hw_sample_counters(struct qib_pportdata *ppd, + __be16 sel) +{ + u64 ret; + + switch (sel) { + case IB_PMA_PORT_XMIT_DATA: + ret = ppd->cong_stats.counter_cache.psxmitdata; + break; + case IB_PMA_PORT_RCV_DATA: + ret = ppd->cong_stats.counter_cache.psrcvdata; + break; + case IB_PMA_PORT_XMIT_PKTS: + ret = ppd->cong_stats.counter_cache.psxmitpkts; + break; + case IB_PMA_PORT_RCV_PKTS: + ret = ppd->cong_stats.counter_cache.psrcvpkts; + break; + case IB_PMA_PORT_XMIT_WAIT: + ret = ppd->cong_stats.counter_cache.psxmitwait; + break; + default: + ret = 0; + } + + return ret; +} + +static int pma_get_portsamplesresult(struct ib_perf *pmp, + struct ib_device *ibdev, u8 port) +{ + struct ib_pma_portsamplesresult *p = + (struct ib_pma_portsamplesresult *)pmp->data; + struct qib_ibdev *dev = to_idev(ibdev); + struct qib_devdata *dd = dd_from_dev(dev); + struct qib_ibport *ibp = to_iport(ibdev, port); + struct qib_pportdata *ppd = ppd_from_ibp(ibp); + unsigned long flags; + u8 status; + int i; + + memset(pmp->data, 0, sizeof(pmp->data)); + spin_lock_irqsave(&ibp->lock, flags); + p->tag = cpu_to_be16(ibp->pma_tag); + if (ppd->cong_stats.flags == IB_PMA_CONG_HW_CONTROL_TIMER) + p->sample_status = IB_PMA_SAMPLE_STATUS_DONE; + else { + status = dd->f_portcntr(ppd, QIBPORTCNTR_PSSTAT); + p->sample_status = cpu_to_be16(status); + if (status == IB_PMA_SAMPLE_STATUS_DONE) { + cache_hw_sample_counters(ppd); + ppd->cong_stats.counter = + xmit_wait_get_value_delta(ppd); + dd->f_set_cntr_sample(ppd, + QIB_CONG_TIMER_PSINTERVAL, 0); + ppd->cong_stats.flags = IB_PMA_CONG_HW_CONTROL_TIMER; + } + } + for (i = 0; i < ARRAY_SIZE(ibp->pma_counter_select); i++) + p->counter[i] = cpu_to_be32( + get_cache_hw_sample_counters( + ppd, ibp->pma_counter_select[i])); + spin_unlock_irqrestore(&ibp->lock, flags); + + return reply((struct ib_smp *) pmp); +} + +static int pma_get_portsamplesresult_ext(struct ib_perf *pmp, + struct ib_device *ibdev, u8 port) +{ + struct ib_pma_portsamplesresult_ext *p = + (struct ib_pma_portsamplesresult_ext *)pmp->data; + struct qib_ibdev *dev = to_idev(ibdev); + struct qib_devdata *dd = dd_from_dev(dev); + struct qib_ibport *ibp = to_iport(ibdev, port); + struct qib_pportdata *ppd = ppd_from_ibp(ibp); + unsigned long flags; + u8 status; + int i; + + /* Port Sampling code owns the PS* HW counters */ + memset(pmp->data, 0, sizeof(pmp->data)); + spin_lock_irqsave(&ibp->lock, flags); + p->tag = cpu_to_be16(ibp->pma_tag); + if (ppd->cong_stats.flags == IB_PMA_CONG_HW_CONTROL_TIMER) + p->sample_status = IB_PMA_SAMPLE_STATUS_DONE; + else { + status = dd->f_portcntr(ppd, QIBPORTCNTR_PSSTAT); + p->sample_status = cpu_to_be16(status); + /* 64 bits */ + p->extended_width = cpu_to_be32(0x80000000); + if (status == IB_PMA_SAMPLE_STATUS_DONE) { + cache_hw_sample_counters(ppd); + ppd->cong_stats.counter = + xmit_wait_get_value_delta(ppd); + dd->f_set_cntr_sample(ppd, + QIB_CONG_TIMER_PSINTERVAL, 0); + ppd->cong_stats.flags = IB_PMA_CONG_HW_CONTROL_TIMER; + } + } + for (i = 0; i < ARRAY_SIZE(ibp->pma_counter_select); i++) + p->counter[i] = cpu_to_be64( + get_cache_hw_sample_counters( + ppd, ibp->pma_counter_select[i])); + spin_unlock_irqrestore(&ibp->lock, flags); + + return reply((struct ib_smp *) pmp); +} + +static int pma_get_portcounters(struct ib_perf *pmp, + struct ib_device *ibdev, u8 port) +{ + struct ib_pma_portcounters *p = (struct ib_pma_portcounters *) + pmp->data; + struct qib_ibport *ibp = to_iport(ibdev, port); + struct qib_pportdata *ppd = ppd_from_ibp(ibp); + struct qib_verbs_counters cntrs; + u8 port_select = p->port_select; + + qib_get_counters(ppd, &cntrs); + + /* Adjust counters for any resets done. */ + cntrs.symbol_error_counter -= ibp->z_symbol_error_counter; + cntrs.link_error_recovery_counter -= + ibp->z_link_error_recovery_counter; + cntrs.link_downed_counter -= ibp->z_link_downed_counter; + cntrs.port_rcv_errors -= ibp->z_port_rcv_errors; + cntrs.port_rcv_remphys_errors -= ibp->z_port_rcv_remphys_errors; + cntrs.port_xmit_discards -= ibp->z_port_xmit_discards; + cntrs.port_xmit_data -= ibp->z_port_xmit_data; + cntrs.port_rcv_data -= ibp->z_port_rcv_data; + cntrs.port_xmit_packets -= ibp->z_port_xmit_packets; + cntrs.port_rcv_packets -= ibp->z_port_rcv_packets; + cntrs.local_link_integrity_errors -= + ibp->z_local_link_integrity_errors; + cntrs.excessive_buffer_overrun_errors -= + ibp->z_excessive_buffer_overrun_errors; + cntrs.vl15_dropped -= ibp->z_vl15_dropped; + cntrs.vl15_dropped += ibp->n_vl15_dropped; + + memset(pmp->data, 0, sizeof(pmp->data)); + + p->port_select = port_select; + if (pmp->attr_mod != 0 || port_select != port) + pmp->status |= IB_SMP_INVALID_FIELD; + + if (cntrs.symbol_error_counter > 0xFFFFUL) + p->symbol_error_counter = cpu_to_be16(0xFFFF); + else + p->symbol_error_counter = + cpu_to_be16((u16)cntrs.symbol_error_counter); + if (cntrs.link_error_recovery_counter > 0xFFUL) + p->link_error_recovery_counter = 0xFF; + else + p->link_error_recovery_counter = + (u8)cntrs.link_error_recovery_counter; + if (cntrs.link_downed_counter > 0xFFUL) + p->link_downed_counter = 0xFF; + else + p->link_downed_counter = (u8)cntrs.link_downed_counter; + if (cntrs.port_rcv_errors > 0xFFFFUL) + p->port_rcv_errors = cpu_to_be16(0xFFFF); + else + p->port_rcv_errors = + cpu_to_be16((u16) cntrs.port_rcv_errors); + if (cntrs.port_rcv_remphys_errors > 0xFFFFUL) + p->port_rcv_remphys_errors = cpu_to_be16(0xFFFF); + else + p->port_rcv_remphys_errors = + cpu_to_be16((u16)cntrs.port_rcv_remphys_errors); + if (cntrs.port_xmit_discards > 0xFFFFUL) + p->port_xmit_discards = cpu_to_be16(0xFFFF); + else + p->port_xmit_discards = + cpu_to_be16((u16)cntrs.port_xmit_discards); + if (cntrs.local_link_integrity_errors > 0xFUL) + cntrs.local_link_integrity_errors = 0xFUL; + if (cntrs.excessive_buffer_overrun_errors > 0xFUL) + cntrs.excessive_buffer_overrun_errors = 0xFUL; + p->lli_ebor_errors = (cntrs.local_link_integrity_errors << 4) | + cntrs.excessive_buffer_overrun_errors; + if (cntrs.vl15_dropped > 0xFFFFUL) + p->vl15_dropped = cpu_to_be16(0xFFFF); + else + p->vl15_dropped = cpu_to_be16((u16)cntrs.vl15_dropped); + if (cntrs.port_xmit_data > 0xFFFFFFFFUL) + p->port_xmit_data = cpu_to_be32(0xFFFFFFFF); + else + p->port_xmit_data = cpu_to_be32((u32)cntrs.port_xmit_data); + if (cntrs.port_rcv_data > 0xFFFFFFFFUL) + p->port_rcv_data = cpu_to_be32(0xFFFFFFFF); + else + p->port_rcv_data = cpu_to_be32((u32)cntrs.port_rcv_data); + if (cntrs.port_xmit_packets > 0xFFFFFFFFUL) + p->port_xmit_packets = cpu_to_be32(0xFFFFFFFF); + else + p->port_xmit_packets = + cpu_to_be32((u32)cntrs.port_xmit_packets); + if (cntrs.port_rcv_packets > 0xFFFFFFFFUL) + p->port_rcv_packets = cpu_to_be32(0xFFFFFFFF); + else + p->port_rcv_packets = + cpu_to_be32((u32) cntrs.port_rcv_packets); + + return reply((struct ib_smp *) pmp); +} + +static int pma_get_portcounters_cong(struct ib_perf *pmp, + struct ib_device *ibdev, u8 port) +{ + /* Congestion PMA packets start at offset 24 not 64 */ + struct ib_pma_portcounters_cong *p = + (struct ib_pma_portcounters_cong *)pmp->reserved; + struct qib_verbs_counters cntrs; + struct qib_ibport *ibp = to_iport(ibdev, port); + struct qib_pportdata *ppd = ppd_from_ibp(ibp); + struct qib_devdata *dd = dd_from_ppd(ppd); + u32 port_select = be32_to_cpu(pmp->attr_mod) & 0xFF; + u64 xmit_wait_counter; + unsigned long flags; + + /* + * This check is performed only in the GET method because the + * SET method ends up calling this anyway. + */ + if (!dd->psxmitwait_supported) + pmp->status |= IB_SMP_UNSUP_METH_ATTR; + if (port_select != port) + pmp->status |= IB_SMP_INVALID_FIELD; + + qib_get_counters(ppd, &cntrs); + spin_lock_irqsave(&ppd->ibport_data.lock, flags); + xmit_wait_counter = xmit_wait_get_value_delta(ppd); + spin_unlock_irqrestore(&ppd->ibport_data.lock, flags); + + /* Adjust counters for any resets done. */ + cntrs.symbol_error_counter -= ibp->z_symbol_error_counter; + cntrs.link_error_recovery_counter -= + ibp->z_link_error_recovery_counter; + cntrs.link_downed_counter -= ibp->z_link_downed_counter; + cntrs.port_rcv_errors -= ibp->z_port_rcv_errors; + cntrs.port_rcv_remphys_errors -= + ibp->z_port_rcv_remphys_errors; + cntrs.port_xmit_discards -= ibp->z_port_xmit_discards; + cntrs.local_link_integrity_errors -= + ibp->z_local_link_integrity_errors; + cntrs.excessive_buffer_overrun_errors -= + ibp->z_excessive_buffer_overrun_errors; + cntrs.vl15_dropped -= ibp->z_vl15_dropped; + cntrs.vl15_dropped += ibp->n_vl15_dropped; + cntrs.port_xmit_data -= ibp->z_port_xmit_data; + cntrs.port_rcv_data -= ibp->z_port_rcv_data; + cntrs.port_xmit_packets -= ibp->z_port_xmit_packets; + cntrs.port_rcv_packets -= ibp->z_port_rcv_packets; + + memset(pmp->reserved, 0, sizeof(pmp->reserved) + + sizeof(pmp->data)); + + /* + * Set top 3 bits to indicate interval in picoseconds in + * remaining bits. + */ + p->port_check_rate = + cpu_to_be16((QIB_XMIT_RATE_PICO << 13) | + (dd->psxmitwait_check_rate & + ~(QIB_XMIT_RATE_PICO << 13))); + p->port_adr_events = cpu_to_be64(0); + p->port_xmit_wait = cpu_to_be64(xmit_wait_counter); + p->port_xmit_data = cpu_to_be64(cntrs.port_xmit_data); + p->port_rcv_data = cpu_to_be64(cntrs.port_rcv_data); + p->port_xmit_packets = + cpu_to_be64(cntrs.port_xmit_packets); + p->port_rcv_packets = + cpu_to_be64(cntrs.port_rcv_packets); + if (cntrs.symbol_error_counter > 0xFFFFUL) + p->symbol_error_counter = cpu_to_be16(0xFFFF); + else + p->symbol_error_counter = + cpu_to_be16( + (u16)cntrs.symbol_error_counter); + if (cntrs.link_error_recovery_counter > 0xFFUL) + p->link_error_recovery_counter = 0xFF; + else + p->link_error_recovery_counter = + (u8)cntrs.link_error_recovery_counter; + if (cntrs.link_downed_counter > 0xFFUL) + p->link_downed_counter = 0xFF; + else + p->link_downed_counter = + (u8)cntrs.link_downed_counter; + if (cntrs.port_rcv_errors > 0xFFFFUL) + p->port_rcv_errors = cpu_to_be16(0xFFFF); + else + p->port_rcv_errors = + cpu_to_be16((u16) cntrs.port_rcv_errors); + if (cntrs.port_rcv_remphys_errors > 0xFFFFUL) + p->port_rcv_remphys_errors = cpu_to_be16(0xFFFF); + else + p->port_rcv_remphys_errors = + cpu_to_be16( + (u16)cntrs.port_rcv_remphys_errors); + if (cntrs.port_xmit_discards > 0xFFFFUL) + p->port_xmit_discards = cpu_to_be16(0xFFFF); + else + p->port_xmit_discards = + cpu_to_be16((u16)cntrs.port_xmit_discards); + if (cntrs.local_link_integrity_errors > 0xFUL) + cntrs.local_link_integrity_errors = 0xFUL; + if (cntrs.excessive_buffer_overrun_errors > 0xFUL) + cntrs.excessive_buffer_overrun_errors = 0xFUL; + p->lli_ebor_errors = (cntrs.local_link_integrity_errors << 4) | + cntrs.excessive_buffer_overrun_errors; + if (cntrs.vl15_dropped > 0xFFFFUL) + p->vl15_dropped = cpu_to_be16(0xFFFF); + else + p->vl15_dropped = cpu_to_be16((u16)cntrs.vl15_dropped); + + return reply((struct ib_smp *)pmp); +} + +static int pma_get_portcounters_ext(struct ib_perf *pmp, + struct ib_device *ibdev, u8 port) +{ + struct ib_pma_portcounters_ext *p = + (struct ib_pma_portcounters_ext *)pmp->data; + struct qib_ibport *ibp = to_iport(ibdev, port); + struct qib_pportdata *ppd = ppd_from_ibp(ibp); + u64 swords, rwords, spkts, rpkts, xwait; + u8 port_select = p->port_select; + + memset(pmp->data, 0, sizeof(pmp->data)); + + p->port_select = port_select; + if (pmp->attr_mod != 0 || port_select != port) { + pmp->status |= IB_SMP_INVALID_FIELD; + goto bail; + } + + qib_snapshot_counters(ppd, &swords, &rwords, &spkts, &rpkts, &xwait); + + /* Adjust counters for any resets done. */ + swords -= ibp->z_port_xmit_data; + rwords -= ibp->z_port_rcv_data; + spkts -= ibp->z_port_xmit_packets; + rpkts -= ibp->z_port_rcv_packets; + + p->port_xmit_data = cpu_to_be64(swords); + p->port_rcv_data = cpu_to_be64(rwords); + p->port_xmit_packets = cpu_to_be64(spkts); + p->port_rcv_packets = cpu_to_be64(rpkts); + p->port_unicast_xmit_packets = cpu_to_be64(ibp->n_unicast_xmit); + p->port_unicast_rcv_packets = cpu_to_be64(ibp->n_unicast_rcv); + p->port_multicast_xmit_packets = cpu_to_be64(ibp->n_multicast_xmit); + p->port_multicast_rcv_packets = cpu_to_be64(ibp->n_multicast_rcv); + +bail: + return reply((struct ib_smp *) pmp); +} + +static int pma_set_portcounters(struct ib_perf *pmp, + struct ib_device *ibdev, u8 port) +{ + struct ib_pma_portcounters *p = (struct ib_pma_portcounters *) + pmp->data; + struct qib_ibport *ibp = to_iport(ibdev, port); + struct qib_pportdata *ppd = ppd_from_ibp(ibp); + struct qib_verbs_counters cntrs; + + /* + * Since the HW doesn't support clearing counters, we save the + * current count and subtract it from future responses. + */ + qib_get_counters(ppd, &cntrs); + + if (p->counter_select & IB_PMA_SEL_SYMBOL_ERROR) + ibp->z_symbol_error_counter = cntrs.symbol_error_counter; + + if (p->counter_select & IB_PMA_SEL_LINK_ERROR_RECOVERY) + ibp->z_link_error_recovery_counter = + cntrs.link_error_recovery_counter; + + if (p->counter_select & IB_PMA_SEL_LINK_DOWNED) + ibp->z_link_downed_counter = cntrs.link_downed_counter; + + if (p->counter_select & IB_PMA_SEL_PORT_RCV_ERRORS) + ibp->z_port_rcv_errors = cntrs.port_rcv_errors; + + if (p->counter_select & IB_PMA_SEL_PORT_RCV_REMPHYS_ERRORS) + ibp->z_port_rcv_remphys_errors = + cntrs.port_rcv_remphys_errors; + + if (p->counter_select & IB_PMA_SEL_PORT_XMIT_DISCARDS) + ibp->z_port_xmit_discards = cntrs.port_xmit_discards; + + if (p->counter_select & IB_PMA_SEL_LOCAL_LINK_INTEGRITY_ERRORS) + ibp->z_local_link_integrity_errors = + cntrs.local_link_integrity_errors; + + if (p->counter_select & IB_PMA_SEL_EXCESSIVE_BUFFER_OVERRUNS) + ibp->z_excessive_buffer_overrun_errors = + cntrs.excessive_buffer_overrun_errors; + + if (p->counter_select & IB_PMA_SEL_PORT_VL15_DROPPED) { + ibp->n_vl15_dropped = 0; + ibp->z_vl15_dropped = cntrs.vl15_dropped; + } + + if (p->counter_select & IB_PMA_SEL_PORT_XMIT_DATA) + ibp->z_port_xmit_data = cntrs.port_xmit_data; + + if (p->counter_select & IB_PMA_SEL_PORT_RCV_DATA) + ibp->z_port_rcv_data = cntrs.port_rcv_data; + + if (p->counter_select & IB_PMA_SEL_PORT_XMIT_PACKETS) + ibp->z_port_xmit_packets = cntrs.port_xmit_packets; + + if (p->counter_select & IB_PMA_SEL_PORT_RCV_PACKETS) + ibp->z_port_rcv_packets = cntrs.port_rcv_packets; + + return pma_get_portcounters(pmp, ibdev, port); +} + +static int pma_set_portcounters_cong(struct ib_perf *pmp, + struct ib_device *ibdev, u8 port) +{ + struct qib_ibport *ibp = to_iport(ibdev, port); + struct qib_pportdata *ppd = ppd_from_ibp(ibp); + struct qib_devdata *dd = dd_from_ppd(ppd); + struct qib_verbs_counters cntrs; + u32 counter_select = (be32_to_cpu(pmp->attr_mod) >> 24) & 0xFF; + int ret = 0; + unsigned long flags; + + qib_get_counters(ppd, &cntrs); + /* Get counter values before we save them */ + ret = pma_get_portcounters_cong(pmp, ibdev, port); + + if (counter_select & IB_PMA_SEL_CONG_XMIT) { + spin_lock_irqsave(&ppd->ibport_data.lock, flags); + ppd->cong_stats.counter = 0; + dd->f_set_cntr_sample(ppd, QIB_CONG_TIMER_PSINTERVAL, + 0x0); + spin_unlock_irqrestore(&ppd->ibport_data.lock, flags); + } + if (counter_select & IB_PMA_SEL_CONG_PORT_DATA) { + ibp->z_port_xmit_data = cntrs.port_xmit_data; + ibp->z_port_rcv_data = cntrs.port_rcv_data; + ibp->z_port_xmit_packets = cntrs.port_xmit_packets; + ibp->z_port_rcv_packets = cntrs.port_rcv_packets; + } + if (counter_select & IB_PMA_SEL_CONG_ALL) { + ibp->z_symbol_error_counter = + cntrs.symbol_error_counter; + ibp->z_link_error_recovery_counter = + cntrs.link_error_recovery_counter; + ibp->z_link_downed_counter = + cntrs.link_downed_counter; + ibp->z_port_rcv_errors = cntrs.port_rcv_errors; + ibp->z_port_rcv_remphys_errors = + cntrs.port_rcv_remphys_errors; + ibp->z_port_xmit_discards = + cntrs.port_xmit_discards; + ibp->z_local_link_integrity_errors = + cntrs.local_link_integrity_errors; + ibp->z_excessive_buffer_overrun_errors = + cntrs.excessive_buffer_overrun_errors; + ibp->n_vl15_dropped = 0; + ibp->z_vl15_dropped = cntrs.vl15_dropped; + } + + return ret; +} + +static int pma_set_portcounters_ext(struct ib_perf *pmp, + struct ib_device *ibdev, u8 port) +{ + struct ib_pma_portcounters *p = (struct ib_pma_portcounters *) + pmp->data; + struct qib_ibport *ibp = to_iport(ibdev, port); + struct qib_pportdata *ppd = ppd_from_ibp(ibp); + u64 swords, rwords, spkts, rpkts, xwait; + + qib_snapshot_counters(ppd, &swords, &rwords, &spkts, &rpkts, &xwait); + + if (p->counter_select & IB_PMA_SELX_PORT_XMIT_DATA) + ibp->z_port_xmit_data = swords; + + if (p->counter_select & IB_PMA_SELX_PORT_RCV_DATA) + ibp->z_port_rcv_data = rwords; + + if (p->counter_select & IB_PMA_SELX_PORT_XMIT_PACKETS) + ibp->z_port_xmit_packets = spkts; + + if (p->counter_select & IB_PMA_SELX_PORT_RCV_PACKETS) + ibp->z_port_rcv_packets = rpkts; + + if (p->counter_select & IB_PMA_SELX_PORT_UNI_XMIT_PACKETS) + ibp->n_unicast_xmit = 0; + + if (p->counter_select & IB_PMA_SELX_PORT_UNI_RCV_PACKETS) + ibp->n_unicast_rcv = 0; + + if (p->counter_select & IB_PMA_SELX_PORT_MULTI_XMIT_PACKETS) + ibp->n_multicast_xmit = 0; + + if (p->counter_select & IB_PMA_SELX_PORT_MULTI_RCV_PACKETS) + ibp->n_multicast_rcv = 0; + + return pma_get_portcounters_ext(pmp, ibdev, port); +} + +static int process_subn(struct ib_device *ibdev, int mad_flags, + u8 port, struct ib_mad *in_mad, + struct ib_mad *out_mad) +{ + struct ib_smp *smp = (struct ib_smp *)out_mad; + struct qib_ibport *ibp = to_iport(ibdev, port); + struct qib_pportdata *ppd = ppd_from_ibp(ibp); + int ret; + + *out_mad = *in_mad; + if (smp->class_version != 1) { + smp->status |= IB_SMP_UNSUP_VERSION; + ret = reply(smp); + goto bail; + } + + ret = check_mkey(ibp, smp, mad_flags); + if (ret) { + u32 port_num = be32_to_cpu(smp->attr_mod); + + /* + * If this is a get/set portinfo, we already check the + * M_Key if the MAD is for another port and the M_Key + * is OK on the receiving port. This check is needed + * to increment the error counters when the M_Key + * fails to match on *both* ports. + */ + if (in_mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO && + (smp->method == IB_MGMT_METHOD_GET || + smp->method == IB_MGMT_METHOD_SET) && + port_num && port_num <= ibdev->phys_port_cnt && + port != port_num) + (void) check_mkey(to_iport(ibdev, port_num), smp, 0); + goto bail; + } + + switch (smp->method) { + case IB_MGMT_METHOD_GET: + switch (smp->attr_id) { + case IB_SMP_ATTR_NODE_DESC: + ret = subn_get_nodedescription(smp, ibdev); + goto bail; + case IB_SMP_ATTR_NODE_INFO: + ret = subn_get_nodeinfo(smp, ibdev, port); + goto bail; + case IB_SMP_ATTR_GUID_INFO: + ret = subn_get_guidinfo(smp, ibdev, port); + goto bail; + case IB_SMP_ATTR_PORT_INFO: + ret = subn_get_portinfo(smp, ibdev, port); + goto bail; + case IB_SMP_ATTR_PKEY_TABLE: + ret = subn_get_pkeytable(smp, ibdev, port); + goto bail; + case IB_SMP_ATTR_SL_TO_VL_TABLE: + ret = subn_get_sl_to_vl(smp, ibdev, port); + goto bail; + case IB_SMP_ATTR_VL_ARB_TABLE: + ret = subn_get_vl_arb(smp, ibdev, port); + goto bail; + case IB_SMP_ATTR_SM_INFO: + if (ibp->port_cap_flags & IB_PORT_SM_DISABLED) { + ret = IB_MAD_RESULT_SUCCESS | + IB_MAD_RESULT_CONSUMED; + goto bail; + } + if (ibp->port_cap_flags & IB_PORT_SM) { + ret = IB_MAD_RESULT_SUCCESS; + goto bail; + } + /* FALLTHROUGH */ + default: + smp->status |= IB_SMP_UNSUP_METH_ATTR; + ret = reply(smp); + goto bail; + } + + case IB_MGMT_METHOD_SET: + switch (smp->attr_id) { + case IB_SMP_ATTR_GUID_INFO: + ret = subn_set_guidinfo(smp, ibdev, port); + goto bail; + case IB_SMP_ATTR_PORT_INFO: + ret = subn_set_portinfo(smp, ibdev, port); + goto bail; + case IB_SMP_ATTR_PKEY_TABLE: + ret = subn_set_pkeytable(smp, ibdev, port); + goto bail; + case IB_SMP_ATTR_SL_TO_VL_TABLE: + ret = subn_set_sl_to_vl(smp, ibdev, port); + goto bail; + case IB_SMP_ATTR_VL_ARB_TABLE: + ret = subn_set_vl_arb(smp, ibdev, port); + goto bail; + case IB_SMP_ATTR_SM_INFO: + if (ibp->port_cap_flags & IB_PORT_SM_DISABLED) { + ret = IB_MAD_RESULT_SUCCESS | + IB_MAD_RESULT_CONSUMED; + goto bail; + } + if (ibp->port_cap_flags & IB_PORT_SM) { + ret = IB_MAD_RESULT_SUCCESS; + goto bail; + } + /* FALLTHROUGH */ + default: + smp->status |= IB_SMP_UNSUP_METH_ATTR; + ret = reply(smp); + goto bail; + } + + case IB_MGMT_METHOD_TRAP_REPRESS: + if (smp->attr_id == IB_SMP_ATTR_NOTICE) + ret = subn_trap_repress(smp, ibdev, port); + else { + smp->status |= IB_SMP_UNSUP_METH_ATTR; + ret = reply(smp); + } + goto bail; + + case IB_MGMT_METHOD_TRAP: + case IB_MGMT_METHOD_REPORT: + case IB_MGMT_METHOD_REPORT_RESP: + case IB_MGMT_METHOD_GET_RESP: + /* + * The ib_mad module will call us to process responses + * before checking for other consumers. + * Just tell the caller to process it normally. + */ + ret = IB_MAD_RESULT_SUCCESS; + goto bail; + + case IB_MGMT_METHOD_SEND: + if (ib_get_smp_direction(smp) && + smp->attr_id == QIB_VENDOR_IPG) { + ppd->dd->f_set_ib_cfg(ppd, QIB_IB_CFG_PORT, + smp->data[0]); + ret = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED; + } else + ret = IB_MAD_RESULT_SUCCESS; + goto bail; + + default: + smp->status |= IB_SMP_UNSUP_METHOD; + ret = reply(smp); + } + +bail: + return ret; +} + +static int process_perf(struct ib_device *ibdev, u8 port, + struct ib_mad *in_mad, + struct ib_mad *out_mad) +{ + struct ib_perf *pmp = (struct ib_perf *)out_mad; + int ret; + + *out_mad = *in_mad; + if (pmp->class_version != 1) { + pmp->status |= IB_SMP_UNSUP_VERSION; + ret = reply((struct ib_smp *) pmp); + goto bail; + } + + switch (pmp->method) { + case IB_MGMT_METHOD_GET: + switch (pmp->attr_id) { + case IB_PMA_CLASS_PORT_INFO: + ret = pma_get_classportinfo(pmp, ibdev); + goto bail; + case IB_PMA_PORT_SAMPLES_CONTROL: + ret = pma_get_portsamplescontrol(pmp, ibdev, port); + goto bail; + case IB_PMA_PORT_SAMPLES_RESULT: + ret = pma_get_portsamplesresult(pmp, ibdev, port); + goto bail; + case IB_PMA_PORT_SAMPLES_RESULT_EXT: + ret = pma_get_portsamplesresult_ext(pmp, ibdev, port); + goto bail; + case IB_PMA_PORT_COUNTERS: + ret = pma_get_portcounters(pmp, ibdev, port); + goto bail; + case IB_PMA_PORT_COUNTERS_EXT: + ret = pma_get_portcounters_ext(pmp, ibdev, port); + goto bail; + case IB_PMA_PORT_COUNTERS_CONG: + ret = pma_get_portcounters_cong(pmp, ibdev, port); + goto bail; + default: + pmp->status |= IB_SMP_UNSUP_METH_ATTR; + ret = reply((struct ib_smp *) pmp); + goto bail; + } + + case IB_MGMT_METHOD_SET: + switch (pmp->attr_id) { + case IB_PMA_PORT_SAMPLES_CONTROL: + ret = pma_set_portsamplescontrol(pmp, ibdev, port); + goto bail; + case IB_PMA_PORT_COUNTERS: + ret = pma_set_portcounters(pmp, ibdev, port); + goto bail; + case IB_PMA_PORT_COUNTERS_EXT: + ret = pma_set_portcounters_ext(pmp, ibdev, port); + goto bail; + case IB_PMA_PORT_COUNTERS_CONG: + ret = pma_set_portcounters_cong(pmp, ibdev, port); + goto bail; + default: + pmp->status |= IB_SMP_UNSUP_METH_ATTR; + ret = reply((struct ib_smp *) pmp); + goto bail; + } + + case IB_MGMT_METHOD_TRAP: + case IB_MGMT_METHOD_GET_RESP: + /* + * The ib_mad module will call us to process responses + * before checking for other consumers. + * Just tell the caller to process it normally. + */ + ret = IB_MAD_RESULT_SUCCESS; + goto bail; + + default: + pmp->status |= IB_SMP_UNSUP_METHOD; + ret = reply((struct ib_smp *) pmp); + } + +bail: + return ret; +} + +/** + * qib_process_mad - process an incoming MAD packet + * @ibdev: the infiniband device this packet came in on + * @mad_flags: MAD flags + * @port: the port number this packet came in on + * @in_wc: the work completion entry for this packet + * @in_grh: the global route header for this packet + * @in_mad: the incoming MAD + * @out_mad: any outgoing MAD reply + * + * Returns IB_MAD_RESULT_SUCCESS if this is a MAD that we are not + * interested in processing. + * + * Note that the verbs framework has already done the MAD sanity checks, + * and hop count/pointer updating for IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE + * MADs. + * + * This is called by the ib_mad module. + */ +int qib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port, + struct ib_wc *in_wc, struct ib_grh *in_grh, + struct ib_mad *in_mad, struct ib_mad *out_mad) +{ + int ret; + + switch (in_mad->mad_hdr.mgmt_class) { + case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE: + case IB_MGMT_CLASS_SUBN_LID_ROUTED: + ret = process_subn(ibdev, mad_flags, port, in_mad, out_mad); + goto bail; + + case IB_MGMT_CLASS_PERF_MGMT: + ret = process_perf(ibdev, port, in_mad, out_mad); + goto bail; + + default: + ret = IB_MAD_RESULT_SUCCESS; + } + +bail: + return ret; +} + +static void send_handler(struct ib_mad_agent *agent, + struct ib_mad_send_wc *mad_send_wc) +{ + ib_free_send_mad(mad_send_wc->send_buf); +} + +static void xmit_wait_timer_func(unsigned long opaque) +{ + struct qib_pportdata *ppd = (struct qib_pportdata *)opaque; + struct qib_devdata *dd = dd_from_ppd(ppd); + unsigned long flags; + u8 status; + + spin_lock_irqsave(&ppd->ibport_data.lock, flags); + if (ppd->cong_stats.flags == IB_PMA_CONG_HW_CONTROL_SAMPLE) { + status = dd->f_portcntr(ppd, QIBPORTCNTR_PSSTAT); + if (status == IB_PMA_SAMPLE_STATUS_DONE) { + /* save counter cache */ + cache_hw_sample_counters(ppd); + ppd->cong_stats.flags = IB_PMA_CONG_HW_CONTROL_TIMER; + } else + goto done; + } + ppd->cong_stats.counter = xmit_wait_get_value_delta(ppd); + dd->f_set_cntr_sample(ppd, QIB_CONG_TIMER_PSINTERVAL, 0x0); +done: + spin_unlock_irqrestore(&ppd->ibport_data.lock, flags); + mod_timer(&ppd->cong_stats.timer, jiffies + HZ); +} + +int qib_create_agents(struct qib_ibdev *dev) +{ + struct qib_devdata *dd = dd_from_dev(dev); + struct ib_mad_agent *agent; + struct qib_ibport *ibp; + int p; + int ret; + + for (p = 0; p < dd->num_pports; p++) { + ibp = &dd->pport[p].ibport_data; + agent = ib_register_mad_agent(&dev->ibdev, p + 1, IB_QPT_SMI, + NULL, 0, send_handler, + NULL, NULL); + if (IS_ERR(agent)) { + ret = PTR_ERR(agent); + goto err; + } + + /* Initialize xmit_wait structure */ + dd->pport[p].cong_stats.counter = 0; + init_timer(&dd->pport[p].cong_stats.timer); + dd->pport[p].cong_stats.timer.function = xmit_wait_timer_func; + dd->pport[p].cong_stats.timer.data = + (unsigned long)(&dd->pport[p]); + dd->pport[p].cong_stats.timer.expires = 0; + add_timer(&dd->pport[p].cong_stats.timer); + + ibp->send_agent = agent; + } + + return 0; + +err: + for (p = 0; p < dd->num_pports; p++) { + ibp = &dd->pport[p].ibport_data; + if (ibp->send_agent) { + agent = ibp->send_agent; + ibp->send_agent = NULL; + ib_unregister_mad_agent(agent); + } + } + + return ret; +} + +void qib_free_agents(struct qib_ibdev *dev) +{ + struct qib_devdata *dd = dd_from_dev(dev); + struct ib_mad_agent *agent; + struct qib_ibport *ibp; + int p; + + for (p = 0; p < dd->num_pports; p++) { + ibp = &dd->pport[p].ibport_data; + if (ibp->send_agent) { + agent = ibp->send_agent; + ibp->send_agent = NULL; + ib_unregister_mad_agent(agent); + } + if (ibp->sm_ah) { + ib_destroy_ah(&ibp->sm_ah->ibah); + ibp->sm_ah = NULL; + } + if (dd->pport[p].cong_stats.timer.data) + del_timer_sync(&dd->pport[p].cong_stats.timer); + } +} diff --git a/drivers/infiniband/hw/qib/qib_mad.h b/drivers/infiniband/hw/qib/qib_mad.h new file mode 100644 index 000000000000..147aff9117d7 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_mad.h @@ -0,0 +1,373 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation. + * All rights reserved. + * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define IB_SMP_UNSUP_VERSION cpu_to_be16(0x0004) +#define IB_SMP_UNSUP_METHOD cpu_to_be16(0x0008) +#define IB_SMP_UNSUP_METH_ATTR cpu_to_be16(0x000C) +#define IB_SMP_INVALID_FIELD cpu_to_be16(0x001C) + +struct ib_node_info { + u8 base_version; + u8 class_version; + u8 node_type; + u8 num_ports; + __be64 sys_guid; + __be64 node_guid; + __be64 port_guid; + __be16 partition_cap; + __be16 device_id; + __be32 revision; + u8 local_port_num; + u8 vendor_id[3]; +} __attribute__ ((packed)); + +struct ib_mad_notice_attr { + u8 generic_type; + u8 prod_type_msb; + __be16 prod_type_lsb; + __be16 trap_num; + __be16 issuer_lid; + __be16 toggle_count; + + union { + struct { + u8 details[54]; + } raw_data; + + struct { + __be16 reserved; + __be16 lid; /* where violation happened */ + u8 port_num; /* where violation happened */ + } __attribute__ ((packed)) ntc_129_131; + + struct { + __be16 reserved; + __be16 lid; /* LID where change occured */ + u8 reserved2; + u8 local_changes; /* low bit - local changes */ + __be32 new_cap_mask; /* new capability mask */ + u8 reserved3; + u8 change_flags; /* low 3 bits only */ + } __attribute__ ((packed)) ntc_144; + + struct { + __be16 reserved; + __be16 lid; /* lid where sys guid changed */ + __be16 reserved2; + __be64 new_sys_guid; + } __attribute__ ((packed)) ntc_145; + + struct { + __be16 reserved; + __be16 lid; + __be16 dr_slid; + u8 method; + u8 reserved2; + __be16 attr_id; + __be32 attr_mod; + __be64 mkey; + u8 reserved3; + u8 dr_trunc_hop; + u8 dr_rtn_path[30]; + } __attribute__ ((packed)) ntc_256; + + struct { + __be16 reserved; + __be16 lid1; + __be16 lid2; + __be32 key; + __be32 sl_qp1; /* SL: high 4 bits */ + __be32 qp2; /* high 8 bits reserved */ + union ib_gid gid1; + union ib_gid gid2; + } __attribute__ ((packed)) ntc_257_258; + + } details; +}; + +/* + * Generic trap/notice types + */ +#define IB_NOTICE_TYPE_FATAL 0x80 +#define IB_NOTICE_TYPE_URGENT 0x81 +#define IB_NOTICE_TYPE_SECURITY 0x82 +#define IB_NOTICE_TYPE_SM 0x83 +#define IB_NOTICE_TYPE_INFO 0x84 + +/* + * Generic trap/notice producers + */ +#define IB_NOTICE_PROD_CA cpu_to_be16(1) +#define IB_NOTICE_PROD_SWITCH cpu_to_be16(2) +#define IB_NOTICE_PROD_ROUTER cpu_to_be16(3) +#define IB_NOTICE_PROD_CLASS_MGR cpu_to_be16(4) + +/* + * Generic trap/notice numbers + */ +#define IB_NOTICE_TRAP_LLI_THRESH cpu_to_be16(129) +#define IB_NOTICE_TRAP_EBO_THRESH cpu_to_be16(130) +#define IB_NOTICE_TRAP_FLOW_UPDATE cpu_to_be16(131) +#define IB_NOTICE_TRAP_CAP_MASK_CHG cpu_to_be16(144) +#define IB_NOTICE_TRAP_SYS_GUID_CHG cpu_to_be16(145) +#define IB_NOTICE_TRAP_BAD_MKEY cpu_to_be16(256) +#define IB_NOTICE_TRAP_BAD_PKEY cpu_to_be16(257) +#define IB_NOTICE_TRAP_BAD_QKEY cpu_to_be16(258) + +/* + * Repress trap/notice flags + */ +#define IB_NOTICE_REPRESS_LLI_THRESH (1 << 0) +#define IB_NOTICE_REPRESS_EBO_THRESH (1 << 1) +#define IB_NOTICE_REPRESS_FLOW_UPDATE (1 << 2) +#define IB_NOTICE_REPRESS_CAP_MASK_CHG (1 << 3) +#define IB_NOTICE_REPRESS_SYS_GUID_CHG (1 << 4) +#define IB_NOTICE_REPRESS_BAD_MKEY (1 << 5) +#define IB_NOTICE_REPRESS_BAD_PKEY (1 << 6) +#define IB_NOTICE_REPRESS_BAD_QKEY (1 << 7) + +/* + * Generic trap/notice other local changes flags (trap 144). + */ +#define IB_NOTICE_TRAP_LSE_CHG 0x04 /* Link Speed Enable changed */ +#define IB_NOTICE_TRAP_LWE_CHG 0x02 /* Link Width Enable changed */ +#define IB_NOTICE_TRAP_NODE_DESC_CHG 0x01 + +/* + * Generic trap/notice M_Key volation flags in dr_trunc_hop (trap 256). + */ +#define IB_NOTICE_TRAP_DR_NOTICE 0x80 +#define IB_NOTICE_TRAP_DR_TRUNC 0x40 + +struct ib_vl_weight_elem { + u8 vl; /* Only low 4 bits, upper 4 bits reserved */ + u8 weight; +}; + +#define IB_VLARB_LOWPRI_0_31 1 +#define IB_VLARB_LOWPRI_32_63 2 +#define IB_VLARB_HIGHPRI_0_31 3 +#define IB_VLARB_HIGHPRI_32_63 4 + +/* + * PMA class portinfo capability mask bits + */ +#define IB_PMA_CLASS_CAP_ALLPORTSELECT cpu_to_be16(1 << 8) +#define IB_PMA_CLASS_CAP_EXT_WIDTH cpu_to_be16(1 << 9) +#define IB_PMA_CLASS_CAP_XMIT_WAIT cpu_to_be16(1 << 12) + +#define IB_PMA_CLASS_PORT_INFO cpu_to_be16(0x0001) +#define IB_PMA_PORT_SAMPLES_CONTROL cpu_to_be16(0x0010) +#define IB_PMA_PORT_SAMPLES_RESULT cpu_to_be16(0x0011) +#define IB_PMA_PORT_COUNTERS cpu_to_be16(0x0012) +#define IB_PMA_PORT_COUNTERS_EXT cpu_to_be16(0x001D) +#define IB_PMA_PORT_SAMPLES_RESULT_EXT cpu_to_be16(0x001E) +#define IB_PMA_PORT_COUNTERS_CONG cpu_to_be16(0xFF00) + +struct ib_perf { + u8 base_version; + u8 mgmt_class; + u8 class_version; + u8 method; + __be16 status; + __be16 unused; + __be64 tid; + __be16 attr_id; + __be16 resv; + __be32 attr_mod; + u8 reserved[40]; + u8 data[192]; +} __attribute__ ((packed)); + +struct ib_pma_classportinfo { + u8 base_version; + u8 class_version; + __be16 cap_mask; + u8 reserved[3]; + u8 resp_time_value; /* only lower 5 bits */ + union ib_gid redirect_gid; + __be32 redirect_tc_sl_fl; /* 8, 4, 20 bits respectively */ + __be16 redirect_lid; + __be16 redirect_pkey; + __be32 redirect_qp; /* only lower 24 bits */ + __be32 redirect_qkey; + union ib_gid trap_gid; + __be32 trap_tc_sl_fl; /* 8, 4, 20 bits respectively */ + __be16 trap_lid; + __be16 trap_pkey; + __be32 trap_hl_qp; /* 8, 24 bits respectively */ + __be32 trap_qkey; +} __attribute__ ((packed)); + +struct ib_pma_portsamplescontrol { + u8 opcode; + u8 port_select; + u8 tick; + u8 counter_width; /* only lower 3 bits */ + __be32 counter_mask0_9; /* 2, 10 * 3, bits */ + __be16 counter_mask10_14; /* 1, 5 * 3, bits */ + u8 sample_mechanisms; + u8 sample_status; /* only lower 2 bits */ + __be64 option_mask; + __be64 vendor_mask; + __be32 sample_start; + __be32 sample_interval; + __be16 tag; + __be16 counter_select[15]; +} __attribute__ ((packed)); + +struct ib_pma_portsamplesresult { + __be16 tag; + __be16 sample_status; /* only lower 2 bits */ + __be32 counter[15]; +} __attribute__ ((packed)); + +struct ib_pma_portsamplesresult_ext { + __be16 tag; + __be16 sample_status; /* only lower 2 bits */ + __be32 extended_width; /* only upper 2 bits */ + __be64 counter[15]; +} __attribute__ ((packed)); + +struct ib_pma_portcounters { + u8 reserved; + u8 port_select; + __be16 counter_select; + __be16 symbol_error_counter; + u8 link_error_recovery_counter; + u8 link_downed_counter; + __be16 port_rcv_errors; + __be16 port_rcv_remphys_errors; + __be16 port_rcv_switch_relay_errors; + __be16 port_xmit_discards; + u8 port_xmit_constraint_errors; + u8 port_rcv_constraint_errors; + u8 reserved1; + u8 lli_ebor_errors; /* 4, 4, bits */ + __be16 reserved2; + __be16 vl15_dropped; + __be32 port_xmit_data; + __be32 port_rcv_data; + __be32 port_xmit_packets; + __be32 port_rcv_packets; +} __attribute__ ((packed)); + +struct ib_pma_portcounters_cong { + u8 reserved; + u8 reserved1; + __be16 port_check_rate; + __be16 symbol_error_counter; + u8 link_error_recovery_counter; + u8 link_downed_counter; + __be16 port_rcv_errors; + __be16 port_rcv_remphys_errors; + __be16 port_rcv_switch_relay_errors; + __be16 port_xmit_discards; + u8 port_xmit_constraint_errors; + u8 port_rcv_constraint_errors; + u8 reserved2; + u8 lli_ebor_errors; /* 4, 4, bits */ + __be16 reserved3; + __be16 vl15_dropped; + __be64 port_xmit_data; + __be64 port_rcv_data; + __be64 port_xmit_packets; + __be64 port_rcv_packets; + __be64 port_xmit_wait; + __be64 port_adr_events; +} __attribute__ ((packed)); + +#define IB_PMA_CONG_HW_CONTROL_TIMER 0x00 +#define IB_PMA_CONG_HW_CONTROL_SAMPLE 0x01 + +#define QIB_XMIT_RATE_UNSUPPORTED 0x0 +#define QIB_XMIT_RATE_PICO 0x7 +/* number of 4nsec cycles equaling 2secs */ +#define QIB_CONG_TIMER_PSINTERVAL 0x1DCD64EC + +#define IB_PMA_SEL_SYMBOL_ERROR cpu_to_be16(0x0001) +#define IB_PMA_SEL_LINK_ERROR_RECOVERY cpu_to_be16(0x0002) +#define IB_PMA_SEL_LINK_DOWNED cpu_to_be16(0x0004) +#define IB_PMA_SEL_PORT_RCV_ERRORS cpu_to_be16(0x0008) +#define IB_PMA_SEL_PORT_RCV_REMPHYS_ERRORS cpu_to_be16(0x0010) +#define IB_PMA_SEL_PORT_XMIT_DISCARDS cpu_to_be16(0x0040) +#define IB_PMA_SEL_LOCAL_LINK_INTEGRITY_ERRORS cpu_to_be16(0x0200) +#define IB_PMA_SEL_EXCESSIVE_BUFFER_OVERRUNS cpu_to_be16(0x0400) +#define IB_PMA_SEL_PORT_VL15_DROPPED cpu_to_be16(0x0800) +#define IB_PMA_SEL_PORT_XMIT_DATA cpu_to_be16(0x1000) +#define IB_PMA_SEL_PORT_RCV_DATA cpu_to_be16(0x2000) +#define IB_PMA_SEL_PORT_XMIT_PACKETS cpu_to_be16(0x4000) +#define IB_PMA_SEL_PORT_RCV_PACKETS cpu_to_be16(0x8000) + +#define IB_PMA_SEL_CONG_ALL 0x01 +#define IB_PMA_SEL_CONG_PORT_DATA 0x02 +#define IB_PMA_SEL_CONG_XMIT 0x04 +#define IB_PMA_SEL_CONG_ROUTING 0x08 + +struct ib_pma_portcounters_ext { + u8 reserved; + u8 port_select; + __be16 counter_select; + __be32 reserved1; + __be64 port_xmit_data; + __be64 port_rcv_data; + __be64 port_xmit_packets; + __be64 port_rcv_packets; + __be64 port_unicast_xmit_packets; + __be64 port_unicast_rcv_packets; + __be64 port_multicast_xmit_packets; + __be64 port_multicast_rcv_packets; +} __attribute__ ((packed)); + +#define IB_PMA_SELX_PORT_XMIT_DATA cpu_to_be16(0x0001) +#define IB_PMA_SELX_PORT_RCV_DATA cpu_to_be16(0x0002) +#define IB_PMA_SELX_PORT_XMIT_PACKETS cpu_to_be16(0x0004) +#define IB_PMA_SELX_PORT_RCV_PACKETS cpu_to_be16(0x0008) +#define IB_PMA_SELX_PORT_UNI_XMIT_PACKETS cpu_to_be16(0x0010) +#define IB_PMA_SELX_PORT_UNI_RCV_PACKETS cpu_to_be16(0x0020) +#define IB_PMA_SELX_PORT_MULTI_XMIT_PACKETS cpu_to_be16(0x0040) +#define IB_PMA_SELX_PORT_MULTI_RCV_PACKETS cpu_to_be16(0x0080) + +/* + * The PortSamplesControl.CounterMasks field is an array of 3 bit fields + * which specify the N'th counter's capabilities. See ch. 16.1.3.2. + * We support 5 counters which only count the mandatory quantities. + */ +#define COUNTER_MASK(q, n) (q << ((9 - n) * 3)) +#define COUNTER_MASK0_9 \ + cpu_to_be32(COUNTER_MASK(1, 0) | \ + COUNTER_MASK(1, 1) | \ + COUNTER_MASK(1, 2) | \ + COUNTER_MASK(1, 3) | \ + COUNTER_MASK(1, 4)) diff --git a/drivers/infiniband/hw/qib/qib_mmap.c b/drivers/infiniband/hw/qib/qib_mmap.c new file mode 100644 index 000000000000..8b73a11d571c --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_mmap.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include "qib_verbs.h" + +/** + * qib_release_mmap_info - free mmap info structure + * @ref: a pointer to the kref within struct qib_mmap_info + */ +void qib_release_mmap_info(struct kref *ref) +{ + struct qib_mmap_info *ip = + container_of(ref, struct qib_mmap_info, ref); + struct qib_ibdev *dev = to_idev(ip->context->device); + + spin_lock_irq(&dev->pending_lock); + list_del(&ip->pending_mmaps); + spin_unlock_irq(&dev->pending_lock); + + vfree(ip->obj); + kfree(ip); +} + +/* + * open and close keep track of how many times the CQ is mapped, + * to avoid releasing it. + */ +static void qib_vma_open(struct vm_area_struct *vma) +{ + struct qib_mmap_info *ip = vma->vm_private_data; + + kref_get(&ip->ref); +} + +static void qib_vma_close(struct vm_area_struct *vma) +{ + struct qib_mmap_info *ip = vma->vm_private_data; + + kref_put(&ip->ref, qib_release_mmap_info); +} + +static struct vm_operations_struct qib_vm_ops = { + .open = qib_vma_open, + .close = qib_vma_close, +}; + +/** + * qib_mmap - create a new mmap region + * @context: the IB user context of the process making the mmap() call + * @vma: the VMA to be initialized + * Return zero if the mmap is OK. Otherwise, return an errno. + */ +int qib_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) +{ + struct qib_ibdev *dev = to_idev(context->device); + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + unsigned long size = vma->vm_end - vma->vm_start; + struct qib_mmap_info *ip, *pp; + int ret = -EINVAL; + + /* + * Search the device's list of objects waiting for a mmap call. + * Normally, this list is very short since a call to create a + * CQ, QP, or SRQ is soon followed by a call to mmap(). + */ + spin_lock_irq(&dev->pending_lock); + list_for_each_entry_safe(ip, pp, &dev->pending_mmaps, + pending_mmaps) { + /* Only the creator is allowed to mmap the object */ + if (context != ip->context || (__u64) offset != ip->offset) + continue; + /* Don't allow a mmap larger than the object. */ + if (size > ip->size) + break; + + list_del_init(&ip->pending_mmaps); + spin_unlock_irq(&dev->pending_lock); + + ret = remap_vmalloc_range(vma, ip->obj, 0); + if (ret) + goto done; + vma->vm_ops = &qib_vm_ops; + vma->vm_private_data = ip; + qib_vma_open(vma); + goto done; + } + spin_unlock_irq(&dev->pending_lock); +done: + return ret; +} + +/* + * Allocate information for qib_mmap + */ +struct qib_mmap_info *qib_create_mmap_info(struct qib_ibdev *dev, + u32 size, + struct ib_ucontext *context, + void *obj) { + struct qib_mmap_info *ip; + + ip = kmalloc(sizeof *ip, GFP_KERNEL); + if (!ip) + goto bail; + + size = PAGE_ALIGN(size); + + spin_lock_irq(&dev->mmap_offset_lock); + if (dev->mmap_offset == 0) + dev->mmap_offset = PAGE_SIZE; + ip->offset = dev->mmap_offset; + dev->mmap_offset += size; + spin_unlock_irq(&dev->mmap_offset_lock); + + INIT_LIST_HEAD(&ip->pending_mmaps); + ip->size = size; + ip->context = context; + ip->obj = obj; + kref_init(&ip->ref); + +bail: + return ip; +} + +void qib_update_mmap_info(struct qib_ibdev *dev, struct qib_mmap_info *ip, + u32 size, void *obj) +{ + size = PAGE_ALIGN(size); + + spin_lock_irq(&dev->mmap_offset_lock); + if (dev->mmap_offset == 0) + dev->mmap_offset = PAGE_SIZE; + ip->offset = dev->mmap_offset; + dev->mmap_offset += size; + spin_unlock_irq(&dev->mmap_offset_lock); + + ip->size = size; + ip->obj = obj; +} diff --git a/drivers/infiniband/hw/qib/qib_mr.c b/drivers/infiniband/hw/qib/qib_mr.c new file mode 100644 index 000000000000..5f95f0f6385d --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_mr.c @@ -0,0 +1,503 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. + * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include + +#include "qib.h" + +/* Fast memory region */ +struct qib_fmr { + struct ib_fmr ibfmr; + u8 page_shift; + struct qib_mregion mr; /* must be last */ +}; + +static inline struct qib_fmr *to_ifmr(struct ib_fmr *ibfmr) +{ + return container_of(ibfmr, struct qib_fmr, ibfmr); +} + +/** + * qib_get_dma_mr - get a DMA memory region + * @pd: protection domain for this memory region + * @acc: access flags + * + * Returns the memory region on success, otherwise returns an errno. + * Note that all DMA addresses should be created via the + * struct ib_dma_mapping_ops functions (see qib_dma.c). + */ +struct ib_mr *qib_get_dma_mr(struct ib_pd *pd, int acc) +{ + struct qib_ibdev *dev = to_idev(pd->device); + struct qib_mr *mr; + struct ib_mr *ret; + unsigned long flags; + + if (to_ipd(pd)->user) { + ret = ERR_PTR(-EPERM); + goto bail; + } + + mr = kzalloc(sizeof *mr, GFP_KERNEL); + if (!mr) { + ret = ERR_PTR(-ENOMEM); + goto bail; + } + + mr->mr.access_flags = acc; + atomic_set(&mr->mr.refcount, 0); + + spin_lock_irqsave(&dev->lk_table.lock, flags); + if (!dev->dma_mr) + dev->dma_mr = &mr->mr; + spin_unlock_irqrestore(&dev->lk_table.lock, flags); + + ret = &mr->ibmr; + +bail: + return ret; +} + +static struct qib_mr *alloc_mr(int count, struct qib_lkey_table *lk_table) +{ + struct qib_mr *mr; + int m, i = 0; + + /* Allocate struct plus pointers to first level page tables. */ + m = (count + QIB_SEGSZ - 1) / QIB_SEGSZ; + mr = kmalloc(sizeof *mr + m * sizeof mr->mr.map[0], GFP_KERNEL); + if (!mr) + goto done; + + /* Allocate first level page tables. */ + for (; i < m; i++) { + mr->mr.map[i] = kmalloc(sizeof *mr->mr.map[0], GFP_KERNEL); + if (!mr->mr.map[i]) + goto bail; + } + mr->mr.mapsz = m; + mr->mr.max_segs = count; + + /* + * ib_reg_phys_mr() will initialize mr->ibmr except for + * lkey and rkey. + */ + if (!qib_alloc_lkey(lk_table, &mr->mr)) + goto bail; + mr->ibmr.lkey = mr->mr.lkey; + mr->ibmr.rkey = mr->mr.lkey; + + atomic_set(&mr->mr.refcount, 0); + goto done; + +bail: + while (i) + kfree(mr->mr.map[--i]); + kfree(mr); + mr = NULL; + +done: + return mr; +} + +/** + * qib_reg_phys_mr - register a physical memory region + * @pd: protection domain for this memory region + * @buffer_list: pointer to the list of physical buffers to register + * @num_phys_buf: the number of physical buffers to register + * @iova_start: the starting address passed over IB which maps to this MR + * + * Returns the memory region on success, otherwise returns an errno. + */ +struct ib_mr *qib_reg_phys_mr(struct ib_pd *pd, + struct ib_phys_buf *buffer_list, + int num_phys_buf, int acc, u64 *iova_start) +{ + struct qib_mr *mr; + int n, m, i; + struct ib_mr *ret; + + mr = alloc_mr(num_phys_buf, &to_idev(pd->device)->lk_table); + if (mr == NULL) { + ret = ERR_PTR(-ENOMEM); + goto bail; + } + + mr->mr.pd = pd; + mr->mr.user_base = *iova_start; + mr->mr.iova = *iova_start; + mr->mr.length = 0; + mr->mr.offset = 0; + mr->mr.access_flags = acc; + mr->umem = NULL; + + m = 0; + n = 0; + for (i = 0; i < num_phys_buf; i++) { + mr->mr.map[m]->segs[n].vaddr = (void *) buffer_list[i].addr; + mr->mr.map[m]->segs[n].length = buffer_list[i].size; + mr->mr.length += buffer_list[i].size; + n++; + if (n == QIB_SEGSZ) { + m++; + n = 0; + } + } + + ret = &mr->ibmr; + +bail: + return ret; +} + +/** + * qib_reg_user_mr - register a userspace memory region + * @pd: protection domain for this memory region + * @start: starting userspace address + * @length: length of region to register + * @virt_addr: virtual address to use (from HCA's point of view) + * @mr_access_flags: access flags for this memory region + * @udata: unused by the QLogic_IB driver + * + * Returns the memory region on success, otherwise returns an errno. + */ +struct ib_mr *qib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, + u64 virt_addr, int mr_access_flags, + struct ib_udata *udata) +{ + struct qib_mr *mr; + struct ib_umem *umem; + struct ib_umem_chunk *chunk; + int n, m, i; + struct ib_mr *ret; + + if (length == 0) { + ret = ERR_PTR(-EINVAL); + goto bail; + } + + umem = ib_umem_get(pd->uobject->context, start, length, + mr_access_flags, 0); + if (IS_ERR(umem)) + return (void *) umem; + + n = 0; + list_for_each_entry(chunk, &umem->chunk_list, list) + n += chunk->nents; + + mr = alloc_mr(n, &to_idev(pd->device)->lk_table); + if (!mr) { + ret = ERR_PTR(-ENOMEM); + ib_umem_release(umem); + goto bail; + } + + mr->mr.pd = pd; + mr->mr.user_base = start; + mr->mr.iova = virt_addr; + mr->mr.length = length; + mr->mr.offset = umem->offset; + mr->mr.access_flags = mr_access_flags; + mr->umem = umem; + + m = 0; + n = 0; + list_for_each_entry(chunk, &umem->chunk_list, list) { + for (i = 0; i < chunk->nents; i++) { + void *vaddr; + + vaddr = page_address(sg_page(&chunk->page_list[i])); + if (!vaddr) { + ret = ERR_PTR(-EINVAL); + goto bail; + } + mr->mr.map[m]->segs[n].vaddr = vaddr; + mr->mr.map[m]->segs[n].length = umem->page_size; + n++; + if (n == QIB_SEGSZ) { + m++; + n = 0; + } + } + } + ret = &mr->ibmr; + +bail: + return ret; +} + +/** + * qib_dereg_mr - unregister and free a memory region + * @ibmr: the memory region to free + * + * Returns 0 on success. + * + * Note that this is called to free MRs created by qib_get_dma_mr() + * or qib_reg_user_mr(). + */ +int qib_dereg_mr(struct ib_mr *ibmr) +{ + struct qib_mr *mr = to_imr(ibmr); + struct qib_ibdev *dev = to_idev(ibmr->device); + int ret; + int i; + + ret = qib_free_lkey(dev, &mr->mr); + if (ret) + return ret; + + i = mr->mr.mapsz; + while (i) + kfree(mr->mr.map[--i]); + if (mr->umem) + ib_umem_release(mr->umem); + kfree(mr); + return 0; +} + +/* + * Allocate a memory region usable with the + * IB_WR_FAST_REG_MR send work request. + * + * Return the memory region on success, otherwise return an errno. + */ +struct ib_mr *qib_alloc_fast_reg_mr(struct ib_pd *pd, int max_page_list_len) +{ + struct qib_mr *mr; + + mr = alloc_mr(max_page_list_len, &to_idev(pd->device)->lk_table); + if (mr == NULL) + return ERR_PTR(-ENOMEM); + + mr->mr.pd = pd; + mr->mr.user_base = 0; + mr->mr.iova = 0; + mr->mr.length = 0; + mr->mr.offset = 0; + mr->mr.access_flags = 0; + mr->umem = NULL; + + return &mr->ibmr; +} + +struct ib_fast_reg_page_list * +qib_alloc_fast_reg_page_list(struct ib_device *ibdev, int page_list_len) +{ + unsigned size = page_list_len * sizeof(u64); + struct ib_fast_reg_page_list *pl; + + if (size > PAGE_SIZE) + return ERR_PTR(-EINVAL); + + pl = kmalloc(sizeof *pl, GFP_KERNEL); + if (!pl) + return ERR_PTR(-ENOMEM); + + pl->page_list = kmalloc(size, GFP_KERNEL); + if (!pl->page_list) + goto err_free; + + return pl; + +err_free: + kfree(pl); + return ERR_PTR(-ENOMEM); +} + +void qib_free_fast_reg_page_list(struct ib_fast_reg_page_list *pl) +{ + kfree(pl->page_list); + kfree(pl); +} + +/** + * qib_alloc_fmr - allocate a fast memory region + * @pd: the protection domain for this memory region + * @mr_access_flags: access flags for this memory region + * @fmr_attr: fast memory region attributes + * + * Returns the memory region on success, otherwise returns an errno. + */ +struct ib_fmr *qib_alloc_fmr(struct ib_pd *pd, int mr_access_flags, + struct ib_fmr_attr *fmr_attr) +{ + struct qib_fmr *fmr; + int m, i = 0; + struct ib_fmr *ret; + + /* Allocate struct plus pointers to first level page tables. */ + m = (fmr_attr->max_pages + QIB_SEGSZ - 1) / QIB_SEGSZ; + fmr = kmalloc(sizeof *fmr + m * sizeof fmr->mr.map[0], GFP_KERNEL); + if (!fmr) + goto bail; + + /* Allocate first level page tables. */ + for (; i < m; i++) { + fmr->mr.map[i] = kmalloc(sizeof *fmr->mr.map[0], + GFP_KERNEL); + if (!fmr->mr.map[i]) + goto bail; + } + fmr->mr.mapsz = m; + + /* + * ib_alloc_fmr() will initialize fmr->ibfmr except for lkey & + * rkey. + */ + if (!qib_alloc_lkey(&to_idev(pd->device)->lk_table, &fmr->mr)) + goto bail; + fmr->ibfmr.rkey = fmr->mr.lkey; + fmr->ibfmr.lkey = fmr->mr.lkey; + /* + * Resources are allocated but no valid mapping (RKEY can't be + * used). + */ + fmr->mr.pd = pd; + fmr->mr.user_base = 0; + fmr->mr.iova = 0; + fmr->mr.length = 0; + fmr->mr.offset = 0; + fmr->mr.access_flags = mr_access_flags; + fmr->mr.max_segs = fmr_attr->max_pages; + fmr->page_shift = fmr_attr->page_shift; + + atomic_set(&fmr->mr.refcount, 0); + ret = &fmr->ibfmr; + goto done; + +bail: + while (i) + kfree(fmr->mr.map[--i]); + kfree(fmr); + ret = ERR_PTR(-ENOMEM); + +done: + return ret; +} + +/** + * qib_map_phys_fmr - set up a fast memory region + * @ibmfr: the fast memory region to set up + * @page_list: the list of pages to associate with the fast memory region + * @list_len: the number of pages to associate with the fast memory region + * @iova: the virtual address of the start of the fast memory region + * + * This may be called from interrupt context. + */ + +int qib_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list, + int list_len, u64 iova) +{ + struct qib_fmr *fmr = to_ifmr(ibfmr); + struct qib_lkey_table *rkt; + unsigned long flags; + int m, n, i; + u32 ps; + int ret; + + if (atomic_read(&fmr->mr.refcount)) + return -EBUSY; + + if (list_len > fmr->mr.max_segs) { + ret = -EINVAL; + goto bail; + } + rkt = &to_idev(ibfmr->device)->lk_table; + spin_lock_irqsave(&rkt->lock, flags); + fmr->mr.user_base = iova; + fmr->mr.iova = iova; + ps = 1 << fmr->page_shift; + fmr->mr.length = list_len * ps; + m = 0; + n = 0; + for (i = 0; i < list_len; i++) { + fmr->mr.map[m]->segs[n].vaddr = (void *) page_list[i]; + fmr->mr.map[m]->segs[n].length = ps; + if (++n == QIB_SEGSZ) { + m++; + n = 0; + } + } + spin_unlock_irqrestore(&rkt->lock, flags); + ret = 0; + +bail: + return ret; +} + +/** + * qib_unmap_fmr - unmap fast memory regions + * @fmr_list: the list of fast memory regions to unmap + * + * Returns 0 on success. + */ +int qib_unmap_fmr(struct list_head *fmr_list) +{ + struct qib_fmr *fmr; + struct qib_lkey_table *rkt; + unsigned long flags; + + list_for_each_entry(fmr, fmr_list, ibfmr.list) { + rkt = &to_idev(fmr->ibfmr.device)->lk_table; + spin_lock_irqsave(&rkt->lock, flags); + fmr->mr.user_base = 0; + fmr->mr.iova = 0; + fmr->mr.length = 0; + spin_unlock_irqrestore(&rkt->lock, flags); + } + return 0; +} + +/** + * qib_dealloc_fmr - deallocate a fast memory region + * @ibfmr: the fast memory region to deallocate + * + * Returns 0 on success. + */ +int qib_dealloc_fmr(struct ib_fmr *ibfmr) +{ + struct qib_fmr *fmr = to_ifmr(ibfmr); + int ret; + int i; + + ret = qib_free_lkey(to_idev(ibfmr->device), &fmr->mr); + if (ret) + return ret; + + i = fmr->mr.mapsz; + while (i) + kfree(fmr->mr.map[--i]); + kfree(fmr); + return 0; +} diff --git a/drivers/infiniband/hw/qib/qib_pcie.c b/drivers/infiniband/hw/qib/qib_pcie.c new file mode 100644 index 000000000000..c926bf4541df --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_pcie.c @@ -0,0 +1,738 @@ +/* + * Copyright (c) 2008, 2009 QLogic Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include "qib.h" + +/* + * This file contains PCIe utility routines that are common to the + * various QLogic InfiniPath adapters + */ + +/* + * Code to adjust PCIe capabilities. + * To minimize the change footprint, we call it + * from qib_pcie_params, which every chip-specific + * file calls, even though this violates some + * expectations of harmlessness. + */ +static int qib_tune_pcie_caps(struct qib_devdata *); +static int qib_tune_pcie_coalesce(struct qib_devdata *); + +/* + * Do all the common PCIe setup and initialization. + * devdata is not yet allocated, and is not allocated until after this + * routine returns success. Therefore qib_dev_err() can't be used for error + * printing. + */ +int qib_pcie_init(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + int ret; + + ret = pci_enable_device(pdev); + if (ret) { + /* + * This can happen (in theory) iff: + * We did a chip reset, and then failed to reprogram the + * BAR, or the chip reset due to an internal error. We then + * unloaded the driver and reloaded it. + * + * Both reset cases set the BAR back to initial state. For + * the latter case, the AER sticky error bit at offset 0x718 + * should be set, but the Linux kernel doesn't yet know + * about that, it appears. If the original BAR was retained + * in the kernel data structures, this may be OK. + */ + qib_early_err(&pdev->dev, "pci enable failed: error %d\n", + -ret); + goto done; + } + + ret = pci_request_regions(pdev, QIB_DRV_NAME); + if (ret) { + qib_devinfo(pdev, "pci_request_regions fails: err %d\n", -ret); + goto bail; + } + + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); + if (ret) { + /* + * If the 64 bit setup fails, try 32 bit. Some systems + * do not setup 64 bit maps on systems with 2GB or less + * memory installed. + */ + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret) { + qib_devinfo(pdev, "Unable to set DMA mask: %d\n", ret); + goto bail; + } + ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); + } else + ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); + if (ret) + qib_early_err(&pdev->dev, + "Unable to set DMA consistent mask: %d\n", ret); + + pci_set_master(pdev); + ret = pci_enable_pcie_error_reporting(pdev); + if (ret) + qib_early_err(&pdev->dev, + "Unable to enable pcie error reporting: %d\n", + ret); + goto done; + +bail: + pci_disable_device(pdev); + pci_release_regions(pdev); +done: + return ret; +} + +/* + * Do remaining PCIe setup, once dd is allocated, and save away + * fields required to re-initialize after a chip reset, or for + * various other purposes + */ +int qib_pcie_ddinit(struct qib_devdata *dd, struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + unsigned long len; + resource_size_t addr; + + dd->pcidev = pdev; + pci_set_drvdata(pdev, dd); + + addr = pci_resource_start(pdev, 0); + len = pci_resource_len(pdev, 0); + +#if defined(__powerpc__) + /* There isn't a generic way to specify writethrough mappings */ + dd->kregbase = __ioremap(addr, len, _PAGE_NO_CACHE | _PAGE_WRITETHRU); +#else + dd->kregbase = ioremap_nocache(addr, len); +#endif + + if (!dd->kregbase) + return -ENOMEM; + + dd->kregend = (u64 __iomem *)((void __iomem *) dd->kregbase + len); + dd->physaddr = addr; /* used for io_remap, etc. */ + + /* + * Save BARs to rewrite after device reset. Save all 64 bits of + * BAR, just in case. + */ + dd->pcibar0 = addr; + dd->pcibar1 = addr >> 32; + dd->deviceid = ent->device; /* save for later use */ + dd->vendorid = ent->vendor; + + return 0; +} + +/* + * Do PCIe cleanup, after chip-specific cleanup, etc. Just prior + * to releasing the dd memory. + * void because none of the core pcie cleanup returns are void + */ +void qib_pcie_ddcleanup(struct qib_devdata *dd) +{ + u64 __iomem *base = (void __iomem *) dd->kregbase; + + dd->kregbase = NULL; + iounmap(base); + if (dd->piobase) + iounmap(dd->piobase); + if (dd->userbase) + iounmap(dd->userbase); + + pci_disable_device(dd->pcidev); + pci_release_regions(dd->pcidev); + + pci_set_drvdata(dd->pcidev, NULL); +} + +static void qib_msix_setup(struct qib_devdata *dd, int pos, u32 *msixcnt, + struct msix_entry *msix_entry) +{ + int ret; + u32 tabsize = 0; + u16 msix_flags; + + pci_read_config_word(dd->pcidev, pos + PCI_MSIX_FLAGS, &msix_flags); + tabsize = 1 + (msix_flags & PCI_MSIX_FLAGS_QSIZE); + if (tabsize > *msixcnt) + tabsize = *msixcnt; + ret = pci_enable_msix(dd->pcidev, msix_entry, tabsize); + if (ret > 0) { + tabsize = ret; + ret = pci_enable_msix(dd->pcidev, msix_entry, tabsize); + } + if (ret) { + qib_dev_err(dd, "pci_enable_msix %d vectors failed: %d, " + "falling back to INTx\n", tabsize, ret); + tabsize = 0; + } + *msixcnt = tabsize; + + if (ret) + qib_enable_intx(dd->pcidev); + +} + +/** + * We save the msi lo and hi values, so we can restore them after + * chip reset (the kernel PCI infrastructure doesn't yet handle that + * correctly. + */ +static int qib_msi_setup(struct qib_devdata *dd, int pos) +{ + struct pci_dev *pdev = dd->pcidev; + u16 control; + int ret; + + ret = pci_enable_msi(pdev); + if (ret) + qib_dev_err(dd, "pci_enable_msi failed: %d, " + "interrupts may not work\n", ret); + /* continue even if it fails, we may still be OK... */ + + pci_read_config_dword(pdev, pos + PCI_MSI_ADDRESS_LO, + &dd->msi_lo); + pci_read_config_dword(pdev, pos + PCI_MSI_ADDRESS_HI, + &dd->msi_hi); + pci_read_config_word(pdev, pos + PCI_MSI_FLAGS, &control); + /* now save the data (vector) info */ + pci_read_config_word(pdev, pos + ((control & PCI_MSI_FLAGS_64BIT) + ? 12 : 8), + &dd->msi_data); + return ret; +} + +int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent, + struct msix_entry *entry) +{ + u16 linkstat, speed; + int pos = 0, pose, ret = 1; + + pose = pci_find_capability(dd->pcidev, PCI_CAP_ID_EXP); + if (!pose) { + qib_dev_err(dd, "Can't find PCI Express capability!\n"); + /* set up something... */ + dd->lbus_width = 1; + dd->lbus_speed = 2500; /* Gen1, 2.5GHz */ + goto bail; + } + + pos = pci_find_capability(dd->pcidev, PCI_CAP_ID_MSIX); + if (nent && *nent && pos) { + qib_msix_setup(dd, pos, nent, entry); + ret = 0; /* did it, either MSIx or INTx */ + } else { + pos = pci_find_capability(dd->pcidev, PCI_CAP_ID_MSI); + if (pos) + ret = qib_msi_setup(dd, pos); + else + qib_dev_err(dd, "No PCI MSI or MSIx capability!\n"); + } + if (!pos) + qib_enable_intx(dd->pcidev); + + pci_read_config_word(dd->pcidev, pose + PCI_EXP_LNKSTA, &linkstat); + /* + * speed is bits 0-3, linkwidth is bits 4-8 + * no defines for them in headers + */ + speed = linkstat & 0xf; + linkstat >>= 4; + linkstat &= 0x1f; + dd->lbus_width = linkstat; + + switch (speed) { + case 1: + dd->lbus_speed = 2500; /* Gen1, 2.5GHz */ + break; + case 2: + dd->lbus_speed = 5000; /* Gen1, 5GHz */ + break; + default: /* not defined, assume gen1 */ + dd->lbus_speed = 2500; + break; + } + + /* + * Check against expected pcie width and complain if "wrong" + * on first initialization, not afterwards (i.e., reset). + */ + if (minw && linkstat < minw) + qib_dev_err(dd, + "PCIe width %u (x%u HCA), performance reduced\n", + linkstat, minw); + + qib_tune_pcie_caps(dd); + + qib_tune_pcie_coalesce(dd); + +bail: + /* fill in string, even on errors */ + snprintf(dd->lbus_info, sizeof(dd->lbus_info), + "PCIe,%uMHz,x%u\n", dd->lbus_speed, dd->lbus_width); + return ret; +} + +/* + * Setup pcie interrupt stuff again after a reset. I'd like to just call + * pci_enable_msi() again for msi, but when I do that, + * the MSI enable bit doesn't get set in the command word, and + * we switch to to a different interrupt vector, which is confusing, + * so I instead just do it all inline. Perhaps somehow can tie this + * into the PCIe hotplug support at some point + */ +int qib_reinit_intr(struct qib_devdata *dd) +{ + int pos; + u16 control; + int ret = 0; + + /* If we aren't using MSI, don't restore it */ + if (!dd->msi_lo) + goto bail; + + pos = pci_find_capability(dd->pcidev, PCI_CAP_ID_MSI); + if (!pos) { + qib_dev_err(dd, "Can't find MSI capability, " + "can't restore MSI settings\n"); + ret = 0; + /* nothing special for MSIx, just MSI */ + goto bail; + } + pci_write_config_dword(dd->pcidev, pos + PCI_MSI_ADDRESS_LO, + dd->msi_lo); + pci_write_config_dword(dd->pcidev, pos + PCI_MSI_ADDRESS_HI, + dd->msi_hi); + pci_read_config_word(dd->pcidev, pos + PCI_MSI_FLAGS, &control); + if (!(control & PCI_MSI_FLAGS_ENABLE)) { + control |= PCI_MSI_FLAGS_ENABLE; + pci_write_config_word(dd->pcidev, pos + PCI_MSI_FLAGS, + control); + } + /* now rewrite the data (vector) info */ + pci_write_config_word(dd->pcidev, pos + + ((control & PCI_MSI_FLAGS_64BIT) ? 12 : 8), + dd->msi_data); + ret = 1; +bail: + if (!ret && (dd->flags & QIB_HAS_INTX)) { + qib_enable_intx(dd->pcidev); + ret = 1; + } + + /* and now set the pci master bit again */ + pci_set_master(dd->pcidev); + + return ret; +} + +/* + * Disable msi interrupt if enabled, and clear msi_lo. + * This is used primarily for the fallback to INTx, but + * is also used in reinit after reset, and during cleanup. + */ +void qib_nomsi(struct qib_devdata *dd) +{ + dd->msi_lo = 0; + pci_disable_msi(dd->pcidev); +} + +/* + * Same as qib_nosmi, but for MSIx. + */ +void qib_nomsix(struct qib_devdata *dd) +{ + pci_disable_msix(dd->pcidev); +} + +/* + * Similar to pci_intx(pdev, 1), except that we make sure + * msi(x) is off. + */ +void qib_enable_intx(struct pci_dev *pdev) +{ + u16 cw, new; + int pos; + + /* first, turn on INTx */ + pci_read_config_word(pdev, PCI_COMMAND, &cw); + new = cw & ~PCI_COMMAND_INTX_DISABLE; + if (new != cw) + pci_write_config_word(pdev, PCI_COMMAND, new); + + pos = pci_find_capability(pdev, PCI_CAP_ID_MSI); + if (pos) { + /* then turn off MSI */ + pci_read_config_word(pdev, pos + PCI_MSI_FLAGS, &cw); + new = cw & ~PCI_MSI_FLAGS_ENABLE; + if (new != cw) + pci_write_config_word(pdev, pos + PCI_MSI_FLAGS, new); + } + pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); + if (pos) { + /* then turn off MSIx */ + pci_read_config_word(pdev, pos + PCI_MSIX_FLAGS, &cw); + new = cw & ~PCI_MSIX_FLAGS_ENABLE; + if (new != cw) + pci_write_config_word(pdev, pos + PCI_MSIX_FLAGS, new); + } +} + +/* + * These two routines are helper routines for the device reset code + * to move all the pcie code out of the chip-specific driver code. + */ +void qib_pcie_getcmd(struct qib_devdata *dd, u16 *cmd, u8 *iline, u8 *cline) +{ + pci_read_config_word(dd->pcidev, PCI_COMMAND, cmd); + pci_read_config_byte(dd->pcidev, PCI_INTERRUPT_LINE, iline); + pci_read_config_byte(dd->pcidev, PCI_CACHE_LINE_SIZE, cline); +} + +void qib_pcie_reenable(struct qib_devdata *dd, u16 cmd, u8 iline, u8 cline) +{ + int r; + r = pci_write_config_dword(dd->pcidev, PCI_BASE_ADDRESS_0, + dd->pcibar0); + if (r) + qib_dev_err(dd, "rewrite of BAR0 failed: %d\n", r); + r = pci_write_config_dword(dd->pcidev, PCI_BASE_ADDRESS_1, + dd->pcibar1); + if (r) + qib_dev_err(dd, "rewrite of BAR1 failed: %d\n", r); + /* now re-enable memory access, and restore cosmetic settings */ + pci_write_config_word(dd->pcidev, PCI_COMMAND, cmd); + pci_write_config_byte(dd->pcidev, PCI_INTERRUPT_LINE, iline); + pci_write_config_byte(dd->pcidev, PCI_CACHE_LINE_SIZE, cline); + r = pci_enable_device(dd->pcidev); + if (r) + qib_dev_err(dd, "pci_enable_device failed after " + "reset: %d\n", r); +} + +/* code to adjust PCIe capabilities. */ + +static int fld2val(int wd, int mask) +{ + int lsbmask; + + if (!mask) + return 0; + wd &= mask; + lsbmask = mask ^ (mask & (mask - 1)); + wd /= lsbmask; + return wd; +} + +static int val2fld(int wd, int mask) +{ + int lsbmask; + + if (!mask) + return 0; + lsbmask = mask ^ (mask & (mask - 1)); + wd *= lsbmask; + return wd; +} + +static int qib_pcie_coalesce; +module_param_named(pcie_coalesce, qib_pcie_coalesce, int, S_IRUGO); +MODULE_PARM_DESC(pcie_coalesce, "tune PCIe colescing on some Intel chipsets"); + +/* + * Enable PCIe completion and data coalescing, on Intel 5x00 and 7300 + * chipsets. This is known to be unsafe for some revisions of some + * of these chipsets, with some BIOS settings, and enabling it on those + * systems may result in the system crashing, and/or data corruption. + */ +static int qib_tune_pcie_coalesce(struct qib_devdata *dd) +{ + int r; + struct pci_dev *parent; + int ppos; + u16 devid; + u32 mask, bits, val; + + if (!qib_pcie_coalesce) + return 0; + + /* Find out supported and configured values for parent (root) */ + parent = dd->pcidev->bus->self; + if (parent->bus->parent) { + qib_devinfo(dd->pcidev, "Parent not root\n"); + return 1; + } + ppos = pci_find_capability(parent, PCI_CAP_ID_EXP); + if (!ppos) + return 1; + if (parent->vendor != 0x8086) + return 1; + + /* + * - bit 12: Max_rdcmp_Imt_EN: need to set to 1 + * - bit 11: COALESCE_FORCE: need to set to 0 + * - bit 10: COALESCE_EN: need to set to 1 + * (but limitations on some on some chipsets) + * + * On the Intel 5000, 5100, and 7300 chipsets, there is + * also: - bit 25:24: COALESCE_MODE, need to set to 0 + */ + devid = parent->device; + if (devid >= 0x25e2 && devid <= 0x25fa) { + u8 rev; + + /* 5000 P/V/X/Z */ + pci_read_config_byte(parent, PCI_REVISION_ID, &rev); + if (rev <= 0xb2) + bits = 1U << 10; + else + bits = 7U << 10; + mask = (3U << 24) | (7U << 10); + } else if (devid >= 0x65e2 && devid <= 0x65fa) { + /* 5100 */ + bits = 1U << 10; + mask = (3U << 24) | (7U << 10); + } else if (devid >= 0x4021 && devid <= 0x402e) { + /* 5400 */ + bits = 7U << 10; + mask = 7U << 10; + } else if (devid >= 0x3604 && devid <= 0x360a) { + /* 7300 */ + bits = 7U << 10; + mask = (3U << 24) | (7U << 10); + } else { + /* not one of the chipsets that we know about */ + return 1; + } + pci_read_config_dword(parent, 0x48, &val); + val &= ~mask; + val |= bits; + r = pci_write_config_dword(parent, 0x48, val); + return 0; +} + +/* + * BIOS may not set PCIe bus-utilization parameters for best performance. + * Check and optionally adjust them to maximize our throughput. + */ +static int qib_pcie_caps; +module_param_named(pcie_caps, qib_pcie_caps, int, S_IRUGO); +MODULE_PARM_DESC(pcie_caps, "Max PCIe tuning: Payload (4lsb), ReadReq (D4..7)"); + +static int qib_tune_pcie_caps(struct qib_devdata *dd) +{ + int ret = 1; /* Assume the worst */ + struct pci_dev *parent; + int ppos, epos; + u16 pcaps, pctl, ecaps, ectl; + int rc_sup, ep_sup; + int rc_cur, ep_cur; + + /* Find out supported and configured values for parent (root) */ + parent = dd->pcidev->bus->self; + if (parent->bus->parent) { + qib_devinfo(dd->pcidev, "Parent not root\n"); + goto bail; + } + ppos = pci_find_capability(parent, PCI_CAP_ID_EXP); + if (ppos) { + pci_read_config_word(parent, ppos + PCI_EXP_DEVCAP, &pcaps); + pci_read_config_word(parent, ppos + PCI_EXP_DEVCTL, &pctl); + } else + goto bail; + /* Find out supported and configured values for endpoint (us) */ + epos = pci_find_capability(dd->pcidev, PCI_CAP_ID_EXP); + if (epos) { + pci_read_config_word(dd->pcidev, epos + PCI_EXP_DEVCAP, &ecaps); + pci_read_config_word(dd->pcidev, epos + PCI_EXP_DEVCTL, &ectl); + } else + goto bail; + ret = 0; + /* Find max payload supported by root, endpoint */ + rc_sup = fld2val(pcaps, PCI_EXP_DEVCAP_PAYLOAD); + ep_sup = fld2val(ecaps, PCI_EXP_DEVCAP_PAYLOAD); + if (rc_sup > ep_sup) + rc_sup = ep_sup; + + rc_cur = fld2val(pctl, PCI_EXP_DEVCTL_PAYLOAD); + ep_cur = fld2val(ectl, PCI_EXP_DEVCTL_PAYLOAD); + + /* If Supported greater than limit in module param, limit it */ + if (rc_sup > (qib_pcie_caps & 7)) + rc_sup = qib_pcie_caps & 7; + /* If less than (allowed, supported), bump root payload */ + if (rc_sup > rc_cur) { + rc_cur = rc_sup; + pctl = (pctl & ~PCI_EXP_DEVCTL_PAYLOAD) | + val2fld(rc_cur, PCI_EXP_DEVCTL_PAYLOAD); + pci_write_config_word(parent, ppos + PCI_EXP_DEVCTL, pctl); + } + /* If less than (allowed, supported), bump endpoint payload */ + if (rc_sup > ep_cur) { + ep_cur = rc_sup; + ectl = (ectl & ~PCI_EXP_DEVCTL_PAYLOAD) | + val2fld(ep_cur, PCI_EXP_DEVCTL_PAYLOAD); + pci_write_config_word(dd->pcidev, epos + PCI_EXP_DEVCTL, ectl); + } + + /* + * Now the Read Request size. + * No field for max supported, but PCIe spec limits it to 4096, + * which is code '5' (log2(4096) - 7) + */ + rc_sup = 5; + if (rc_sup > ((qib_pcie_caps >> 4) & 7)) + rc_sup = (qib_pcie_caps >> 4) & 7; + rc_cur = fld2val(pctl, PCI_EXP_DEVCTL_READRQ); + ep_cur = fld2val(ectl, PCI_EXP_DEVCTL_READRQ); + + if (rc_sup > rc_cur) { + rc_cur = rc_sup; + pctl = (pctl & ~PCI_EXP_DEVCTL_READRQ) | + val2fld(rc_cur, PCI_EXP_DEVCTL_READRQ); + pci_write_config_word(parent, ppos + PCI_EXP_DEVCTL, pctl); + } + if (rc_sup > ep_cur) { + ep_cur = rc_sup; + ectl = (ectl & ~PCI_EXP_DEVCTL_READRQ) | + val2fld(ep_cur, PCI_EXP_DEVCTL_READRQ); + pci_write_config_word(dd->pcidev, epos + PCI_EXP_DEVCTL, ectl); + } +bail: + return ret; +} +/* End of PCIe capability tuning */ + +/* + * From here through qib_pci_err_handler definition is invoked via + * PCI error infrastructure, registered via pci + */ +static pci_ers_result_t +qib_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) +{ + struct qib_devdata *dd = pci_get_drvdata(pdev); + pci_ers_result_t ret = PCI_ERS_RESULT_RECOVERED; + + switch (state) { + case pci_channel_io_normal: + qib_devinfo(pdev, "State Normal, ignoring\n"); + break; + + case pci_channel_io_frozen: + qib_devinfo(pdev, "State Frozen, requesting reset\n"); + pci_disable_device(pdev); + ret = PCI_ERS_RESULT_NEED_RESET; + break; + + case pci_channel_io_perm_failure: + qib_devinfo(pdev, "State Permanent Failure, disabling\n"); + if (dd) { + /* no more register accesses! */ + dd->flags &= ~QIB_PRESENT; + qib_disable_after_error(dd); + } + /* else early, or other problem */ + ret = PCI_ERS_RESULT_DISCONNECT; + break; + + default: /* shouldn't happen */ + qib_devinfo(pdev, "QIB PCI errors detected (state %d)\n", + state); + break; + } + return ret; +} + +static pci_ers_result_t +qib_pci_mmio_enabled(struct pci_dev *pdev) +{ + u64 words = 0U; + struct qib_devdata *dd = pci_get_drvdata(pdev); + pci_ers_result_t ret = PCI_ERS_RESULT_RECOVERED; + + if (dd && dd->pport) { + words = dd->f_portcntr(dd->pport, QIBPORTCNTR_WORDRCV); + if (words == ~0ULL) + ret = PCI_ERS_RESULT_NEED_RESET; + } + qib_devinfo(pdev, "QIB mmio_enabled function called, " + "read wordscntr %Lx, returning %d\n", words, ret); + return ret; +} + +static pci_ers_result_t +qib_pci_slot_reset(struct pci_dev *pdev) +{ + qib_devinfo(pdev, "QIB link_reset function called, ignored\n"); + return PCI_ERS_RESULT_CAN_RECOVER; +} + +static pci_ers_result_t +qib_pci_link_reset(struct pci_dev *pdev) +{ + qib_devinfo(pdev, "QIB link_reset function called, ignored\n"); + return PCI_ERS_RESULT_CAN_RECOVER; +} + +static void +qib_pci_resume(struct pci_dev *pdev) +{ + struct qib_devdata *dd = pci_get_drvdata(pdev); + qib_devinfo(pdev, "QIB resume function called\n"); + pci_cleanup_aer_uncorrect_error_status(pdev); + /* + * Running jobs will fail, since it's asynchronous + * unlike sysfs-requested reset. Better than + * doing nothing. + */ + qib_init(dd, 1); /* same as re-init after reset */ +} + +struct pci_error_handlers qib_pci_err_handler = { + .error_detected = qib_pci_error_detected, + .mmio_enabled = qib_pci_mmio_enabled, + .link_reset = qib_pci_link_reset, + .slot_reset = qib_pci_slot_reset, + .resume = qib_pci_resume, +}; diff --git a/drivers/infiniband/hw/qib/qib_pio_copy.c b/drivers/infiniband/hw/qib/qib_pio_copy.c new file mode 100644 index 000000000000..10b8c444dd31 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_pio_copy.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2009 QLogic Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "qib.h" + +/** + * qib_pio_copy - copy data to MMIO space, in multiples of 32-bits + * @to: destination, in MMIO space (must be 64-bit aligned) + * @from: source (must be 64-bit aligned) + * @count: number of 32-bit quantities to copy + * + * Copy data from kernel space to MMIO space, in multiples of 32 bits at a + * time. Order of access is not guaranteed, nor is a memory barrier + * performed afterwards. + */ +void qib_pio_copy(void __iomem *to, const void *from, size_t count) +{ +#ifdef CONFIG_64BIT + u64 __iomem *dst = to; + const u64 *src = from; + const u64 *end = src + (count >> 1); + + while (src < end) + __raw_writeq(*src++, dst++); + if (count & 1) + __raw_writel(*(const u32 *)src, dst); +#else + u32 __iomem *dst = to; + const u32 *src = from; + const u32 *end = src + count; + + while (src < end) + __raw_writel(*src++, dst++); +#endif +} diff --git a/drivers/infiniband/hw/qib/qib_qp.c b/drivers/infiniband/hw/qib/qib_qp.c new file mode 100644 index 000000000000..e0f65e39076b --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_qp.c @@ -0,0 +1,1255 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation. + * All rights reserved. + * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include + +#include "qib.h" + +#define BITS_PER_PAGE (PAGE_SIZE*BITS_PER_BYTE) +#define BITS_PER_PAGE_MASK (BITS_PER_PAGE-1) + +static inline unsigned mk_qpn(struct qib_qpn_table *qpt, + struct qpn_map *map, unsigned off) +{ + return (map - qpt->map) * BITS_PER_PAGE + off; +} + +static inline unsigned find_next_offset(struct qib_qpn_table *qpt, + struct qpn_map *map, unsigned off, + unsigned r) +{ + if (qpt->mask) { + off++; + if ((off & qpt->mask) >> 1 != r) + off = ((off & qpt->mask) ? + (off | qpt->mask) + 1 : off) | (r << 1); + } else + off = find_next_zero_bit(map->page, BITS_PER_PAGE, off); + return off; +} + +/* + * Convert the AETH credit code into the number of credits. + */ +static u32 credit_table[31] = { + 0, /* 0 */ + 1, /* 1 */ + 2, /* 2 */ + 3, /* 3 */ + 4, /* 4 */ + 6, /* 5 */ + 8, /* 6 */ + 12, /* 7 */ + 16, /* 8 */ + 24, /* 9 */ + 32, /* A */ + 48, /* B */ + 64, /* C */ + 96, /* D */ + 128, /* E */ + 192, /* F */ + 256, /* 10 */ + 384, /* 11 */ + 512, /* 12 */ + 768, /* 13 */ + 1024, /* 14 */ + 1536, /* 15 */ + 2048, /* 16 */ + 3072, /* 17 */ + 4096, /* 18 */ + 6144, /* 19 */ + 8192, /* 1A */ + 12288, /* 1B */ + 16384, /* 1C */ + 24576, /* 1D */ + 32768 /* 1E */ +}; + +static void get_map_page(struct qib_qpn_table *qpt, struct qpn_map *map) +{ + unsigned long page = get_zeroed_page(GFP_KERNEL); + + /* + * Free the page if someone raced with us installing it. + */ + + spin_lock(&qpt->lock); + if (map->page) + free_page(page); + else + map->page = (void *)page; + spin_unlock(&qpt->lock); +} + +/* + * Allocate the next available QPN or + * zero/one for QP type IB_QPT_SMI/IB_QPT_GSI. + */ +static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt, + enum ib_qp_type type, u8 port) +{ + u32 i, offset, max_scan, qpn; + struct qpn_map *map; + u32 ret; + int r; + + if (type == IB_QPT_SMI || type == IB_QPT_GSI) { + unsigned n; + + ret = type == IB_QPT_GSI; + n = 1 << (ret + 2 * (port - 1)); + spin_lock(&qpt->lock); + if (qpt->flags & n) + ret = -EINVAL; + else + qpt->flags |= n; + spin_unlock(&qpt->lock); + goto bail; + } + + r = smp_processor_id(); + if (r >= dd->n_krcv_queues) + r %= dd->n_krcv_queues; + qpn = qpt->last + 1; + if (qpn >= QPN_MAX) + qpn = 2; + if (qpt->mask && ((qpn & qpt->mask) >> 1) != r) + qpn = ((qpn & qpt->mask) ? (qpn | qpt->mask) + 1 : qpn) | + (r << 1); + offset = qpn & BITS_PER_PAGE_MASK; + map = &qpt->map[qpn / BITS_PER_PAGE]; + max_scan = qpt->nmaps - !offset; + for (i = 0;;) { + if (unlikely(!map->page)) { + get_map_page(qpt, map); + if (unlikely(!map->page)) + break; + } + do { + if (!test_and_set_bit(offset, map->page)) { + qpt->last = qpn; + ret = qpn; + goto bail; + } + offset = find_next_offset(qpt, map, offset, r); + qpn = mk_qpn(qpt, map, offset); + /* + * This test differs from alloc_pidmap(). + * If find_next_offset() does find a zero + * bit, we don't need to check for QPN + * wrapping around past our starting QPN. + * We just need to be sure we don't loop + * forever. + */ + } while (offset < BITS_PER_PAGE && qpn < QPN_MAX); + /* + * In order to keep the number of pages allocated to a + * minimum, we scan the all existing pages before increasing + * the size of the bitmap table. + */ + if (++i > max_scan) { + if (qpt->nmaps == QPNMAP_ENTRIES) + break; + map = &qpt->map[qpt->nmaps++]; + offset = qpt->mask ? (r << 1) : 0; + } else if (map < &qpt->map[qpt->nmaps]) { + ++map; + offset = qpt->mask ? (r << 1) : 0; + } else { + map = &qpt->map[0]; + offset = qpt->mask ? (r << 1) : 2; + } + qpn = mk_qpn(qpt, map, offset); + } + + ret = -ENOMEM; + +bail: + return ret; +} + +static void free_qpn(struct qib_qpn_table *qpt, u32 qpn) +{ + struct qpn_map *map; + + map = qpt->map + qpn / BITS_PER_PAGE; + if (map->page) + clear_bit(qpn & BITS_PER_PAGE_MASK, map->page); +} + +/* + * Put the QP into the hash table. + * The hash table holds a reference to the QP. + */ +static void insert_qp(struct qib_ibdev *dev, struct qib_qp *qp) +{ + struct qib_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); + unsigned n = qp->ibqp.qp_num % dev->qp_table_size; + unsigned long flags; + + spin_lock_irqsave(&dev->qpt_lock, flags); + + if (qp->ibqp.qp_num == 0) + ibp->qp0 = qp; + else if (qp->ibqp.qp_num == 1) + ibp->qp1 = qp; + else { + qp->next = dev->qp_table[n]; + dev->qp_table[n] = qp; + } + atomic_inc(&qp->refcount); + + spin_unlock_irqrestore(&dev->qpt_lock, flags); +} + +/* + * Remove the QP from the table so it can't be found asynchronously by + * the receive interrupt routine. + */ +static void remove_qp(struct qib_ibdev *dev, struct qib_qp *qp) +{ + struct qib_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); + struct qib_qp *q, **qpp; + unsigned long flags; + + qpp = &dev->qp_table[qp->ibqp.qp_num % dev->qp_table_size]; + + spin_lock_irqsave(&dev->qpt_lock, flags); + + if (ibp->qp0 == qp) { + ibp->qp0 = NULL; + atomic_dec(&qp->refcount); + } else if (ibp->qp1 == qp) { + ibp->qp1 = NULL; + atomic_dec(&qp->refcount); + } else + for (; (q = *qpp) != NULL; qpp = &q->next) + if (q == qp) { + *qpp = qp->next; + qp->next = NULL; + atomic_dec(&qp->refcount); + break; + } + + spin_unlock_irqrestore(&dev->qpt_lock, flags); +} + +/** + * qib_free_all_qps - check for QPs still in use + * @qpt: the QP table to empty + * + * There should not be any QPs still in use. + * Free memory for table. + */ +unsigned qib_free_all_qps(struct qib_devdata *dd) +{ + struct qib_ibdev *dev = &dd->verbs_dev; + unsigned long flags; + struct qib_qp *qp; + unsigned n, qp_inuse = 0; + + for (n = 0; n < dd->num_pports; n++) { + struct qib_ibport *ibp = &dd->pport[n].ibport_data; + + if (!qib_mcast_tree_empty(ibp)) + qp_inuse++; + if (ibp->qp0) + qp_inuse++; + if (ibp->qp1) + qp_inuse++; + } + + spin_lock_irqsave(&dev->qpt_lock, flags); + for (n = 0; n < dev->qp_table_size; n++) { + qp = dev->qp_table[n]; + dev->qp_table[n] = NULL; + + for (; qp; qp = qp->next) + qp_inuse++; + } + spin_unlock_irqrestore(&dev->qpt_lock, flags); + + return qp_inuse; +} + +/** + * qib_lookup_qpn - return the QP with the given QPN + * @qpt: the QP table + * @qpn: the QP number to look up + * + * The caller is responsible for decrementing the QP reference count + * when done. + */ +struct qib_qp *qib_lookup_qpn(struct qib_ibport *ibp, u32 qpn) +{ + struct qib_ibdev *dev = &ppd_from_ibp(ibp)->dd->verbs_dev; + unsigned long flags; + struct qib_qp *qp; + + spin_lock_irqsave(&dev->qpt_lock, flags); + + if (qpn == 0) + qp = ibp->qp0; + else if (qpn == 1) + qp = ibp->qp1; + else + for (qp = dev->qp_table[qpn % dev->qp_table_size]; qp; + qp = qp->next) + if (qp->ibqp.qp_num == qpn) + break; + if (qp) + atomic_inc(&qp->refcount); + + spin_unlock_irqrestore(&dev->qpt_lock, flags); + return qp; +} + +/** + * qib_reset_qp - initialize the QP state to the reset state + * @qp: the QP to reset + * @type: the QP type + */ +static void qib_reset_qp(struct qib_qp *qp, enum ib_qp_type type) +{ + qp->remote_qpn = 0; + qp->qkey = 0; + qp->qp_access_flags = 0; + atomic_set(&qp->s_dma_busy, 0); + qp->s_flags &= QIB_S_SIGNAL_REQ_WR; + qp->s_hdrwords = 0; + qp->s_wqe = NULL; + qp->s_draining = 0; + qp->s_next_psn = 0; + qp->s_last_psn = 0; + qp->s_sending_psn = 0; + qp->s_sending_hpsn = 0; + qp->s_psn = 0; + qp->r_psn = 0; + qp->r_msn = 0; + if (type == IB_QPT_RC) { + qp->s_state = IB_OPCODE_RC_SEND_LAST; + qp->r_state = IB_OPCODE_RC_SEND_LAST; + } else { + qp->s_state = IB_OPCODE_UC_SEND_LAST; + qp->r_state = IB_OPCODE_UC_SEND_LAST; + } + qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE; + qp->r_nak_state = 0; + qp->r_aflags = 0; + qp->r_flags = 0; + qp->s_head = 0; + qp->s_tail = 0; + qp->s_cur = 0; + qp->s_acked = 0; + qp->s_last = 0; + qp->s_ssn = 1; + qp->s_lsn = 0; + qp->s_mig_state = IB_MIG_MIGRATED; + memset(qp->s_ack_queue, 0, sizeof(qp->s_ack_queue)); + qp->r_head_ack_queue = 0; + qp->s_tail_ack_queue = 0; + qp->s_num_rd_atomic = 0; + if (qp->r_rq.wq) { + qp->r_rq.wq->head = 0; + qp->r_rq.wq->tail = 0; + } + qp->r_sge.num_sge = 0; +} + +static void clear_mr_refs(struct qib_qp *qp, int clr_sends) +{ + unsigned n; + + if (test_and_clear_bit(QIB_R_REWIND_SGE, &qp->r_aflags)) + while (qp->s_rdma_read_sge.num_sge) { + atomic_dec(&qp->s_rdma_read_sge.sge.mr->refcount); + if (--qp->s_rdma_read_sge.num_sge) + qp->s_rdma_read_sge.sge = + *qp->s_rdma_read_sge.sg_list++; + } + + while (qp->r_sge.num_sge) { + atomic_dec(&qp->r_sge.sge.mr->refcount); + if (--qp->r_sge.num_sge) + qp->r_sge.sge = *qp->r_sge.sg_list++; + } + + if (clr_sends) { + while (qp->s_last != qp->s_head) { + struct qib_swqe *wqe = get_swqe_ptr(qp, qp->s_last); + unsigned i; + + for (i = 0; i < wqe->wr.num_sge; i++) { + struct qib_sge *sge = &wqe->sg_list[i]; + + atomic_dec(&sge->mr->refcount); + } + if (qp->ibqp.qp_type == IB_QPT_UD || + qp->ibqp.qp_type == IB_QPT_SMI || + qp->ibqp.qp_type == IB_QPT_GSI) + atomic_dec(&to_iah(wqe->wr.wr.ud.ah)->refcount); + if (++qp->s_last >= qp->s_size) + qp->s_last = 0; + } + if (qp->s_rdma_mr) { + atomic_dec(&qp->s_rdma_mr->refcount); + qp->s_rdma_mr = NULL; + } + } + + if (qp->ibqp.qp_type != IB_QPT_RC) + return; + + for (n = 0; n < ARRAY_SIZE(qp->s_ack_queue); n++) { + struct qib_ack_entry *e = &qp->s_ack_queue[n]; + + if (e->opcode == IB_OPCODE_RC_RDMA_READ_REQUEST && + e->rdma_sge.mr) { + atomic_dec(&e->rdma_sge.mr->refcount); + e->rdma_sge.mr = NULL; + } + } +} + +/** + * qib_error_qp - put a QP into the error state + * @qp: the QP to put into the error state + * @err: the receive completion error to signal if a RWQE is active + * + * Flushes both send and receive work queues. + * Returns true if last WQE event should be generated. + * The QP s_lock should be held and interrupts disabled. + * If we are already in error state, just return. + */ +int qib_error_qp(struct qib_qp *qp, enum ib_wc_status err) +{ + struct qib_ibdev *dev = to_idev(qp->ibqp.device); + struct ib_wc wc; + int ret = 0; + + if (qp->state == IB_QPS_ERR || qp->state == IB_QPS_RESET) + goto bail; + + qp->state = IB_QPS_ERR; + + if (qp->s_flags & (QIB_S_TIMER | QIB_S_WAIT_RNR)) { + qp->s_flags &= ~(QIB_S_TIMER | QIB_S_WAIT_RNR); + del_timer(&qp->s_timer); + } + spin_lock(&dev->pending_lock); + if (!list_empty(&qp->iowait) && !(qp->s_flags & QIB_S_BUSY)) { + qp->s_flags &= ~QIB_S_ANY_WAIT_IO; + list_del_init(&qp->iowait); + } + spin_unlock(&dev->pending_lock); + + if (!(qp->s_flags & QIB_S_BUSY)) { + qp->s_hdrwords = 0; + if (qp->s_rdma_mr) { + atomic_dec(&qp->s_rdma_mr->refcount); + qp->s_rdma_mr = NULL; + } + if (qp->s_tx) { + qib_put_txreq(qp->s_tx); + qp->s_tx = NULL; + } + } + + /* Schedule the sending tasklet to drain the send work queue. */ + if (qp->s_last != qp->s_head) + qib_schedule_send(qp); + + clear_mr_refs(qp, 0); + + memset(&wc, 0, sizeof(wc)); + wc.qp = &qp->ibqp; + wc.opcode = IB_WC_RECV; + + if (test_and_clear_bit(QIB_R_WRID_VALID, &qp->r_aflags)) { + wc.wr_id = qp->r_wr_id; + wc.status = err; + qib_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1); + } + wc.status = IB_WC_WR_FLUSH_ERR; + + if (qp->r_rq.wq) { + struct qib_rwq *wq; + u32 head; + u32 tail; + + spin_lock(&qp->r_rq.lock); + + /* sanity check pointers before trusting them */ + wq = qp->r_rq.wq; + head = wq->head; + if (head >= qp->r_rq.size) + head = 0; + tail = wq->tail; + if (tail >= qp->r_rq.size) + tail = 0; + while (tail != head) { + wc.wr_id = get_rwqe_ptr(&qp->r_rq, tail)->wr_id; + if (++tail >= qp->r_rq.size) + tail = 0; + qib_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1); + } + wq->tail = tail; + + spin_unlock(&qp->r_rq.lock); + } else if (qp->ibqp.event_handler) + ret = 1; + +bail: + return ret; +} + +/** + * qib_modify_qp - modify the attributes of a queue pair + * @ibqp: the queue pair who's attributes we're modifying + * @attr: the new attributes + * @attr_mask: the mask of attributes to modify + * @udata: user data for libibverbs.so + * + * Returns 0 on success, otherwise returns an errno. + */ +int qib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, + int attr_mask, struct ib_udata *udata) +{ + struct qib_ibdev *dev = to_idev(ibqp->device); + struct qib_qp *qp = to_iqp(ibqp); + enum ib_qp_state cur_state, new_state; + struct ib_event ev; + int lastwqe = 0; + int mig = 0; + int ret; + u32 pmtu = 0; /* for gcc warning only */ + + spin_lock_irq(&qp->r_lock); + spin_lock(&qp->s_lock); + + cur_state = attr_mask & IB_QP_CUR_STATE ? + attr->cur_qp_state : qp->state; + new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state; + + if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, + attr_mask)) + goto inval; + + if (attr_mask & IB_QP_AV) { + if (attr->ah_attr.dlid >= QIB_MULTICAST_LID_BASE) + goto inval; + if (qib_check_ah(qp->ibqp.device, &attr->ah_attr)) + goto inval; + } + + if (attr_mask & IB_QP_ALT_PATH) { + if (attr->alt_ah_attr.dlid >= QIB_MULTICAST_LID_BASE) + goto inval; + if (qib_check_ah(qp->ibqp.device, &attr->alt_ah_attr)) + goto inval; + if (attr->alt_pkey_index >= qib_get_npkeys(dd_from_dev(dev))) + goto inval; + } + + if (attr_mask & IB_QP_PKEY_INDEX) + if (attr->pkey_index >= qib_get_npkeys(dd_from_dev(dev))) + goto inval; + + if (attr_mask & IB_QP_MIN_RNR_TIMER) + if (attr->min_rnr_timer > 31) + goto inval; + + if (attr_mask & IB_QP_PORT) + if (qp->ibqp.qp_type == IB_QPT_SMI || + qp->ibqp.qp_type == IB_QPT_GSI || + attr->port_num == 0 || + attr->port_num > ibqp->device->phys_port_cnt) + goto inval; + + if (attr_mask & IB_QP_DEST_QPN) + if (attr->dest_qp_num > QIB_QPN_MASK) + goto inval; + + if (attr_mask & IB_QP_RETRY_CNT) + if (attr->retry_cnt > 7) + goto inval; + + if (attr_mask & IB_QP_RNR_RETRY) + if (attr->rnr_retry > 7) + goto inval; + + /* + * Don't allow invalid path_mtu values. OK to set greater + * than the active mtu (or even the max_cap, if we have tuned + * that to a small mtu. We'll set qp->path_mtu + * to the lesser of requested attribute mtu and active, + * for packetizing messages. + * Note that the QP port has to be set in INIT and MTU in RTR. + */ + if (attr_mask & IB_QP_PATH_MTU) { + struct qib_devdata *dd = dd_from_dev(dev); + int mtu, pidx = qp->port_num - 1; + + mtu = ib_mtu_enum_to_int(attr->path_mtu); + if (mtu == -1) + goto inval; + if (mtu > dd->pport[pidx].ibmtu) { + switch (dd->pport[pidx].ibmtu) { + case 4096: + pmtu = IB_MTU_4096; + break; + case 2048: + pmtu = IB_MTU_2048; + break; + case 1024: + pmtu = IB_MTU_1024; + break; + case 512: + pmtu = IB_MTU_512; + break; + case 256: + pmtu = IB_MTU_256; + break; + default: + pmtu = IB_MTU_2048; + } + } else + pmtu = attr->path_mtu; + } + + if (attr_mask & IB_QP_PATH_MIG_STATE) { + if (attr->path_mig_state == IB_MIG_REARM) { + if (qp->s_mig_state == IB_MIG_ARMED) + goto inval; + if (new_state != IB_QPS_RTS) + goto inval; + } else if (attr->path_mig_state == IB_MIG_MIGRATED) { + if (qp->s_mig_state == IB_MIG_REARM) + goto inval; + if (new_state != IB_QPS_RTS && new_state != IB_QPS_SQD) + goto inval; + if (qp->s_mig_state == IB_MIG_ARMED) + mig = 1; + } else + goto inval; + } + + if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) + if (attr->max_dest_rd_atomic > QIB_MAX_RDMA_ATOMIC) + goto inval; + + switch (new_state) { + case IB_QPS_RESET: + if (qp->state != IB_QPS_RESET) { + qp->state = IB_QPS_RESET; + spin_lock(&dev->pending_lock); + if (!list_empty(&qp->iowait)) + list_del_init(&qp->iowait); + spin_unlock(&dev->pending_lock); + qp->s_flags &= ~(QIB_S_TIMER | QIB_S_ANY_WAIT); + spin_unlock(&qp->s_lock); + spin_unlock_irq(&qp->r_lock); + /* Stop the sending work queue and retry timer */ + cancel_work_sync(&qp->s_work); + del_timer_sync(&qp->s_timer); + wait_event(qp->wait_dma, !atomic_read(&qp->s_dma_busy)); + if (qp->s_tx) { + qib_put_txreq(qp->s_tx); + qp->s_tx = NULL; + } + remove_qp(dev, qp); + wait_event(qp->wait, !atomic_read(&qp->refcount)); + spin_lock_irq(&qp->r_lock); + spin_lock(&qp->s_lock); + clear_mr_refs(qp, 1); + qib_reset_qp(qp, ibqp->qp_type); + } + break; + + case IB_QPS_RTR: + /* Allow event to retrigger if QP set to RTR more than once */ + qp->r_flags &= ~QIB_R_COMM_EST; + qp->state = new_state; + break; + + case IB_QPS_SQD: + qp->s_draining = qp->s_last != qp->s_cur; + qp->state = new_state; + break; + + case IB_QPS_SQE: + if (qp->ibqp.qp_type == IB_QPT_RC) + goto inval; + qp->state = new_state; + break; + + case IB_QPS_ERR: + lastwqe = qib_error_qp(qp, IB_WC_WR_FLUSH_ERR); + break; + + default: + qp->state = new_state; + break; + } + + if (attr_mask & IB_QP_PKEY_INDEX) + qp->s_pkey_index = attr->pkey_index; + + if (attr_mask & IB_QP_PORT) + qp->port_num = attr->port_num; + + if (attr_mask & IB_QP_DEST_QPN) + qp->remote_qpn = attr->dest_qp_num; + + if (attr_mask & IB_QP_SQ_PSN) { + qp->s_next_psn = attr->sq_psn & QIB_PSN_MASK; + qp->s_psn = qp->s_next_psn; + qp->s_sending_psn = qp->s_next_psn; + qp->s_last_psn = qp->s_next_psn - 1; + qp->s_sending_hpsn = qp->s_last_psn; + } + + if (attr_mask & IB_QP_RQ_PSN) + qp->r_psn = attr->rq_psn & QIB_PSN_MASK; + + if (attr_mask & IB_QP_ACCESS_FLAGS) + qp->qp_access_flags = attr->qp_access_flags; + + if (attr_mask & IB_QP_AV) { + qp->remote_ah_attr = attr->ah_attr; + qp->s_srate = attr->ah_attr.static_rate; + } + + if (attr_mask & IB_QP_ALT_PATH) { + qp->alt_ah_attr = attr->alt_ah_attr; + qp->s_alt_pkey_index = attr->alt_pkey_index; + } + + if (attr_mask & IB_QP_PATH_MIG_STATE) { + qp->s_mig_state = attr->path_mig_state; + if (mig) { + qp->remote_ah_attr = qp->alt_ah_attr; + qp->port_num = qp->alt_ah_attr.port_num; + qp->s_pkey_index = qp->s_alt_pkey_index; + } + } + + if (attr_mask & IB_QP_PATH_MTU) + qp->path_mtu = pmtu; + + if (attr_mask & IB_QP_RETRY_CNT) { + qp->s_retry_cnt = attr->retry_cnt; + qp->s_retry = attr->retry_cnt; + } + + if (attr_mask & IB_QP_RNR_RETRY) { + qp->s_rnr_retry_cnt = attr->rnr_retry; + qp->s_rnr_retry = attr->rnr_retry; + } + + if (attr_mask & IB_QP_MIN_RNR_TIMER) + qp->r_min_rnr_timer = attr->min_rnr_timer; + + if (attr_mask & IB_QP_TIMEOUT) + qp->timeout = attr->timeout; + + if (attr_mask & IB_QP_QKEY) + qp->qkey = attr->qkey; + + if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) + qp->r_max_rd_atomic = attr->max_dest_rd_atomic; + + if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) + qp->s_max_rd_atomic = attr->max_rd_atomic; + + spin_unlock(&qp->s_lock); + spin_unlock_irq(&qp->r_lock); + + if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) + insert_qp(dev, qp); + + if (lastwqe) { + ev.device = qp->ibqp.device; + ev.element.qp = &qp->ibqp; + ev.event = IB_EVENT_QP_LAST_WQE_REACHED; + qp->ibqp.event_handler(&ev, qp->ibqp.qp_context); + } + if (mig) { + ev.device = qp->ibqp.device; + ev.element.qp = &qp->ibqp; + ev.event = IB_EVENT_PATH_MIG; + qp->ibqp.event_handler(&ev, qp->ibqp.qp_context); + } + ret = 0; + goto bail; + +inval: + spin_unlock(&qp->s_lock); + spin_unlock_irq(&qp->r_lock); + ret = -EINVAL; + +bail: + return ret; +} + +int qib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, + int attr_mask, struct ib_qp_init_attr *init_attr) +{ + struct qib_qp *qp = to_iqp(ibqp); + + attr->qp_state = qp->state; + attr->cur_qp_state = attr->qp_state; + attr->path_mtu = qp->path_mtu; + attr->path_mig_state = qp->s_mig_state; + attr->qkey = qp->qkey; + attr->rq_psn = qp->r_psn & QIB_PSN_MASK; + attr->sq_psn = qp->s_next_psn & QIB_PSN_MASK; + attr->dest_qp_num = qp->remote_qpn; + attr->qp_access_flags = qp->qp_access_flags; + attr->cap.max_send_wr = qp->s_size - 1; + attr->cap.max_recv_wr = qp->ibqp.srq ? 0 : qp->r_rq.size - 1; + attr->cap.max_send_sge = qp->s_max_sge; + attr->cap.max_recv_sge = qp->r_rq.max_sge; + attr->cap.max_inline_data = 0; + attr->ah_attr = qp->remote_ah_attr; + attr->alt_ah_attr = qp->alt_ah_attr; + attr->pkey_index = qp->s_pkey_index; + attr->alt_pkey_index = qp->s_alt_pkey_index; + attr->en_sqd_async_notify = 0; + attr->sq_draining = qp->s_draining; + attr->max_rd_atomic = qp->s_max_rd_atomic; + attr->max_dest_rd_atomic = qp->r_max_rd_atomic; + attr->min_rnr_timer = qp->r_min_rnr_timer; + attr->port_num = qp->port_num; + attr->timeout = qp->timeout; + attr->retry_cnt = qp->s_retry_cnt; + attr->rnr_retry = qp->s_rnr_retry_cnt; + attr->alt_port_num = qp->alt_ah_attr.port_num; + attr->alt_timeout = qp->alt_timeout; + + init_attr->event_handler = qp->ibqp.event_handler; + init_attr->qp_context = qp->ibqp.qp_context; + init_attr->send_cq = qp->ibqp.send_cq; + init_attr->recv_cq = qp->ibqp.recv_cq; + init_attr->srq = qp->ibqp.srq; + init_attr->cap = attr->cap; + if (qp->s_flags & QIB_S_SIGNAL_REQ_WR) + init_attr->sq_sig_type = IB_SIGNAL_REQ_WR; + else + init_attr->sq_sig_type = IB_SIGNAL_ALL_WR; + init_attr->qp_type = qp->ibqp.qp_type; + init_attr->port_num = qp->port_num; + return 0; +} + +/** + * qib_compute_aeth - compute the AETH (syndrome + MSN) + * @qp: the queue pair to compute the AETH for + * + * Returns the AETH. + */ +__be32 qib_compute_aeth(struct qib_qp *qp) +{ + u32 aeth = qp->r_msn & QIB_MSN_MASK; + + if (qp->ibqp.srq) { + /* + * Shared receive queues don't generate credits. + * Set the credit field to the invalid value. + */ + aeth |= QIB_AETH_CREDIT_INVAL << QIB_AETH_CREDIT_SHIFT; + } else { + u32 min, max, x; + u32 credits; + struct qib_rwq *wq = qp->r_rq.wq; + u32 head; + u32 tail; + + /* sanity check pointers before trusting them */ + head = wq->head; + if (head >= qp->r_rq.size) + head = 0; + tail = wq->tail; + if (tail >= qp->r_rq.size) + tail = 0; + /* + * Compute the number of credits available (RWQEs). + * XXX Not holding the r_rq.lock here so there is a small + * chance that the pair of reads are not atomic. + */ + credits = head - tail; + if ((int)credits < 0) + credits += qp->r_rq.size; + /* + * Binary search the credit table to find the code to + * use. + */ + min = 0; + max = 31; + for (;;) { + x = (min + max) / 2; + if (credit_table[x] == credits) + break; + if (credit_table[x] > credits) + max = x; + else if (min == x) + break; + else + min = x; + } + aeth |= x << QIB_AETH_CREDIT_SHIFT; + } + return cpu_to_be32(aeth); +} + +/** + * qib_create_qp - create a queue pair for a device + * @ibpd: the protection domain who's device we create the queue pair for + * @init_attr: the attributes of the queue pair + * @udata: user data for libibverbs.so + * + * Returns the queue pair on success, otherwise returns an errno. + * + * Called by the ib_create_qp() core verbs function. + */ +struct ib_qp *qib_create_qp(struct ib_pd *ibpd, + struct ib_qp_init_attr *init_attr, + struct ib_udata *udata) +{ + struct qib_qp *qp; + int err; + struct qib_swqe *swq = NULL; + struct qib_ibdev *dev; + struct qib_devdata *dd; + size_t sz; + size_t sg_list_sz; + struct ib_qp *ret; + + if (init_attr->cap.max_send_sge > ib_qib_max_sges || + init_attr->cap.max_send_wr > ib_qib_max_qp_wrs) { + ret = ERR_PTR(-EINVAL); + goto bail; + } + + /* Check receive queue parameters if no SRQ is specified. */ + if (!init_attr->srq) { + if (init_attr->cap.max_recv_sge > ib_qib_max_sges || + init_attr->cap.max_recv_wr > ib_qib_max_qp_wrs) { + ret = ERR_PTR(-EINVAL); + goto bail; + } + if (init_attr->cap.max_send_sge + + init_attr->cap.max_send_wr + + init_attr->cap.max_recv_sge + + init_attr->cap.max_recv_wr == 0) { + ret = ERR_PTR(-EINVAL); + goto bail; + } + } + + switch (init_attr->qp_type) { + case IB_QPT_SMI: + case IB_QPT_GSI: + if (init_attr->port_num == 0 || + init_attr->port_num > ibpd->device->phys_port_cnt) { + ret = ERR_PTR(-EINVAL); + goto bail; + } + case IB_QPT_UC: + case IB_QPT_RC: + case IB_QPT_UD: + sz = sizeof(struct qib_sge) * + init_attr->cap.max_send_sge + + sizeof(struct qib_swqe); + swq = vmalloc((init_attr->cap.max_send_wr + 1) * sz); + if (swq == NULL) { + ret = ERR_PTR(-ENOMEM); + goto bail; + } + sz = sizeof(*qp); + sg_list_sz = 0; + if (init_attr->srq) { + struct qib_srq *srq = to_isrq(init_attr->srq); + + if (srq->rq.max_sge > 1) + sg_list_sz = sizeof(*qp->r_sg_list) * + (srq->rq.max_sge - 1); + } else if (init_attr->cap.max_recv_sge > 1) + sg_list_sz = sizeof(*qp->r_sg_list) * + (init_attr->cap.max_recv_sge - 1); + qp = kzalloc(sz + sg_list_sz, GFP_KERNEL); + if (!qp) { + ret = ERR_PTR(-ENOMEM); + goto bail_swq; + } + if (init_attr->srq) + sz = 0; + else { + qp->r_rq.size = init_attr->cap.max_recv_wr + 1; + qp->r_rq.max_sge = init_attr->cap.max_recv_sge; + sz = (sizeof(struct ib_sge) * qp->r_rq.max_sge) + + sizeof(struct qib_rwqe); + qp->r_rq.wq = vmalloc_user(sizeof(struct qib_rwq) + + qp->r_rq.size * sz); + if (!qp->r_rq.wq) { + ret = ERR_PTR(-ENOMEM); + goto bail_qp; + } + } + + /* + * ib_create_qp() will initialize qp->ibqp + * except for qp->ibqp.qp_num. + */ + spin_lock_init(&qp->r_lock); + spin_lock_init(&qp->s_lock); + spin_lock_init(&qp->r_rq.lock); + atomic_set(&qp->refcount, 0); + init_waitqueue_head(&qp->wait); + init_waitqueue_head(&qp->wait_dma); + init_timer(&qp->s_timer); + qp->s_timer.data = (unsigned long)qp; + INIT_WORK(&qp->s_work, qib_do_send); + INIT_LIST_HEAD(&qp->iowait); + INIT_LIST_HEAD(&qp->rspwait); + qp->state = IB_QPS_RESET; + qp->s_wq = swq; + qp->s_size = init_attr->cap.max_send_wr + 1; + qp->s_max_sge = init_attr->cap.max_send_sge; + if (init_attr->sq_sig_type == IB_SIGNAL_REQ_WR) + qp->s_flags = QIB_S_SIGNAL_REQ_WR; + dev = to_idev(ibpd->device); + dd = dd_from_dev(dev); + err = alloc_qpn(dd, &dev->qpn_table, init_attr->qp_type, + init_attr->port_num); + if (err < 0) { + ret = ERR_PTR(err); + vfree(qp->r_rq.wq); + goto bail_qp; + } + qp->ibqp.qp_num = err; + qp->port_num = init_attr->port_num; + qp->processor_id = smp_processor_id(); + qib_reset_qp(qp, init_attr->qp_type); + break; + + default: + /* Don't support raw QPs */ + ret = ERR_PTR(-ENOSYS); + goto bail; + } + + init_attr->cap.max_inline_data = 0; + + /* + * Return the address of the RWQ as the offset to mmap. + * See qib_mmap() for details. + */ + if (udata && udata->outlen >= sizeof(__u64)) { + if (!qp->r_rq.wq) { + __u64 offset = 0; + + err = ib_copy_to_udata(udata, &offset, + sizeof(offset)); + if (err) { + ret = ERR_PTR(err); + goto bail_ip; + } + } else { + u32 s = sizeof(struct qib_rwq) + qp->r_rq.size * sz; + + qp->ip = qib_create_mmap_info(dev, s, + ibpd->uobject->context, + qp->r_rq.wq); + if (!qp->ip) { + ret = ERR_PTR(-ENOMEM); + goto bail_ip; + } + + err = ib_copy_to_udata(udata, &(qp->ip->offset), + sizeof(qp->ip->offset)); + if (err) { + ret = ERR_PTR(err); + goto bail_ip; + } + } + } + + spin_lock(&dev->n_qps_lock); + if (dev->n_qps_allocated == ib_qib_max_qps) { + spin_unlock(&dev->n_qps_lock); + ret = ERR_PTR(-ENOMEM); + goto bail_ip; + } + + dev->n_qps_allocated++; + spin_unlock(&dev->n_qps_lock); + + if (qp->ip) { + spin_lock_irq(&dev->pending_lock); + list_add(&qp->ip->pending_mmaps, &dev->pending_mmaps); + spin_unlock_irq(&dev->pending_lock); + } + + ret = &qp->ibqp; + goto bail; + +bail_ip: + if (qp->ip) + kref_put(&qp->ip->ref, qib_release_mmap_info); + else + vfree(qp->r_rq.wq); + free_qpn(&dev->qpn_table, qp->ibqp.qp_num); +bail_qp: + kfree(qp); +bail_swq: + vfree(swq); +bail: + return ret; +} + +/** + * qib_destroy_qp - destroy a queue pair + * @ibqp: the queue pair to destroy + * + * Returns 0 on success. + * + * Note that this can be called while the QP is actively sending or + * receiving! + */ +int qib_destroy_qp(struct ib_qp *ibqp) +{ + struct qib_qp *qp = to_iqp(ibqp); + struct qib_ibdev *dev = to_idev(ibqp->device); + + /* Make sure HW and driver activity is stopped. */ + spin_lock_irq(&qp->s_lock); + if (qp->state != IB_QPS_RESET) { + qp->state = IB_QPS_RESET; + spin_lock(&dev->pending_lock); + if (!list_empty(&qp->iowait)) + list_del_init(&qp->iowait); + spin_unlock(&dev->pending_lock); + qp->s_flags &= ~(QIB_S_TIMER | QIB_S_ANY_WAIT); + spin_unlock_irq(&qp->s_lock); + cancel_work_sync(&qp->s_work); + del_timer_sync(&qp->s_timer); + wait_event(qp->wait_dma, !atomic_read(&qp->s_dma_busy)); + if (qp->s_tx) { + qib_put_txreq(qp->s_tx); + qp->s_tx = NULL; + } + remove_qp(dev, qp); + wait_event(qp->wait, !atomic_read(&qp->refcount)); + clear_mr_refs(qp, 1); + } else + spin_unlock_irq(&qp->s_lock); + + /* all user's cleaned up, mark it available */ + free_qpn(&dev->qpn_table, qp->ibqp.qp_num); + spin_lock(&dev->n_qps_lock); + dev->n_qps_allocated--; + spin_unlock(&dev->n_qps_lock); + + if (qp->ip) + kref_put(&qp->ip->ref, qib_release_mmap_info); + else + vfree(qp->r_rq.wq); + vfree(qp->s_wq); + kfree(qp); + return 0; +} + +/** + * qib_init_qpn_table - initialize the QP number table for a device + * @qpt: the QPN table + */ +void qib_init_qpn_table(struct qib_devdata *dd, struct qib_qpn_table *qpt) +{ + spin_lock_init(&qpt->lock); + qpt->last = 1; /* start with QPN 2 */ + qpt->nmaps = 1; + qpt->mask = dd->qpn_mask; +} + +/** + * qib_free_qpn_table - free the QP number table for a device + * @qpt: the QPN table + */ +void qib_free_qpn_table(struct qib_qpn_table *qpt) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(qpt->map); i++) + if (qpt->map[i].page) + free_page((unsigned long) qpt->map[i].page); +} + +/** + * qib_get_credit - flush the send work queue of a QP + * @qp: the qp who's send work queue to flush + * @aeth: the Acknowledge Extended Transport Header + * + * The QP s_lock should be held. + */ +void qib_get_credit(struct qib_qp *qp, u32 aeth) +{ + u32 credit = (aeth >> QIB_AETH_CREDIT_SHIFT) & QIB_AETH_CREDIT_MASK; + + /* + * If the credit is invalid, we can send + * as many packets as we like. Otherwise, we have to + * honor the credit field. + */ + if (credit == QIB_AETH_CREDIT_INVAL) { + if (!(qp->s_flags & QIB_S_UNLIMITED_CREDIT)) { + qp->s_flags |= QIB_S_UNLIMITED_CREDIT; + if (qp->s_flags & QIB_S_WAIT_SSN_CREDIT) { + qp->s_flags &= ~QIB_S_WAIT_SSN_CREDIT; + qib_schedule_send(qp); + } + } + } else if (!(qp->s_flags & QIB_S_UNLIMITED_CREDIT)) { + /* Compute new LSN (i.e., MSN + credit) */ + credit = (aeth + credit_table[credit]) & QIB_MSN_MASK; + if (qib_cmp24(credit, qp->s_lsn) > 0) { + qp->s_lsn = credit; + if (qp->s_flags & QIB_S_WAIT_SSN_CREDIT) { + qp->s_flags &= ~QIB_S_WAIT_SSN_CREDIT; + qib_schedule_send(qp); + } + } + } +} diff --git a/drivers/infiniband/hw/qib/qib_qsfp.c b/drivers/infiniband/hw/qib/qib_qsfp.c new file mode 100644 index 000000000000..35b3604b691d --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_qsfp.c @@ -0,0 +1,564 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. + * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include + +#include "qib.h" +#include "qib_qsfp.h" + +/* + * QSFP support for ib_qib driver, using "Two Wire Serial Interface" driver + * in qib_twsi.c + */ +#define QSFP_MAX_RETRY 4 + +static int qsfp_read(struct qib_pportdata *ppd, int addr, void *bp, int len) +{ + struct qib_devdata *dd = ppd->dd; + u32 out, mask; + int ret, cnt, pass = 0; + int stuck = 0; + u8 *buff = bp; + + ret = mutex_lock_interruptible(&dd->eep_lock); + if (ret) + goto no_unlock; + + if (dd->twsi_eeprom_dev == QIB_TWSI_NO_DEV) { + ret = -ENXIO; + goto bail; + } + + /* + * We presume, if we are called at all, that this board has + * QSFP. This is on the same i2c chain as the legacy parts, + * but only responds if the module is selected via GPIO pins. + * Further, there are very long setup and hold requirements + * on MODSEL. + */ + mask = QSFP_GPIO_MOD_SEL_N | QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE; + out = QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE; + if (ppd->hw_pidx) { + mask <<= QSFP_GPIO_PORT2_SHIFT; + out <<= QSFP_GPIO_PORT2_SHIFT; + } + + dd->f_gpio_mod(dd, out, mask, mask); + + /* + * Module could take up to 2 Msec to respond to MOD_SEL, and there + * is no way to tell if it is ready, so we must wait. + */ + msleep(2); + + /* Make sure TWSI bus is in sane state. */ + ret = qib_twsi_reset(dd); + if (ret) { + qib_dev_porterr(dd, ppd->port, + "QSFP interface Reset for read failed\n"); + ret = -EIO; + stuck = 1; + goto deselect; + } + + /* All QSFP modules are at A0 */ + + cnt = 0; + while (cnt < len) { + unsigned in_page; + int wlen = len - cnt; + in_page = addr % QSFP_PAGESIZE; + if ((in_page + wlen) > QSFP_PAGESIZE) + wlen = QSFP_PAGESIZE - in_page; + ret = qib_twsi_blk_rd(dd, QSFP_DEV, addr, buff + cnt, wlen); + /* Some QSFP's fail first try. Retry as experiment */ + if (ret && cnt == 0 && ++pass < QSFP_MAX_RETRY) + continue; + if (ret) { + /* qib_twsi_blk_rd() 1 for error, else 0 */ + ret = -EIO; + goto deselect; + } + addr += wlen; + cnt += wlen; + } + ret = cnt; + +deselect: + /* + * Module could take up to 10 uSec after transfer before + * ready to respond to MOD_SEL negation, and there is no way + * to tell if it is ready, so we must wait. + */ + udelay(10); + /* set QSFP MODSEL, RST. LP all high */ + dd->f_gpio_mod(dd, mask, mask, mask); + + /* + * Module could take up to 2 Msec to respond to MOD_SEL + * going away, and there is no way to tell if it is ready. + * so we must wait. + */ + if (stuck) + qib_dev_err(dd, "QSFP interface bus stuck non-idle\n"); + + if (pass >= QSFP_MAX_RETRY && ret) + qib_dev_porterr(dd, ppd->port, "QSFP failed even retrying\n"); + else if (pass) + qib_dev_porterr(dd, ppd->port, "QSFP retries: %d\n", pass); + + msleep(2); + +bail: + mutex_unlock(&dd->eep_lock); + +no_unlock: + return ret; +} + +/* + * qsfp_write + * We do not ordinarily write the QSFP, but this is needed to select + * the page on non-flat QSFPs, and possibly later unusual cases + */ +static int qib_qsfp_write(struct qib_pportdata *ppd, int addr, void *bp, + int len) +{ + struct qib_devdata *dd = ppd->dd; + u32 out, mask; + int ret, cnt; + u8 *buff = bp; + + ret = mutex_lock_interruptible(&dd->eep_lock); + if (ret) + goto no_unlock; + + if (dd->twsi_eeprom_dev == QIB_TWSI_NO_DEV) { + ret = -ENXIO; + goto bail; + } + + /* + * We presume, if we are called at all, that this board has + * QSFP. This is on the same i2c chain as the legacy parts, + * but only responds if the module is selected via GPIO pins. + * Further, there are very long setup and hold requirements + * on MODSEL. + */ + mask = QSFP_GPIO_MOD_SEL_N | QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE; + out = QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE; + if (ppd->hw_pidx) { + mask <<= QSFP_GPIO_PORT2_SHIFT; + out <<= QSFP_GPIO_PORT2_SHIFT; + } + dd->f_gpio_mod(dd, out, mask, mask); + + /* + * Module could take up to 2 Msec to respond to MOD_SEL, + * and there is no way to tell if it is ready, so we must wait. + */ + msleep(2); + + /* Make sure TWSI bus is in sane state. */ + ret = qib_twsi_reset(dd); + if (ret) { + qib_dev_porterr(dd, ppd->port, + "QSFP interface Reset for write failed\n"); + ret = -EIO; + goto deselect; + } + + /* All QSFP modules are at A0 */ + + cnt = 0; + while (cnt < len) { + unsigned in_page; + int wlen = len - cnt; + in_page = addr % QSFP_PAGESIZE; + if ((in_page + wlen) > QSFP_PAGESIZE) + wlen = QSFP_PAGESIZE - in_page; + ret = qib_twsi_blk_wr(dd, QSFP_DEV, addr, buff + cnt, wlen); + if (ret) { + /* qib_twsi_blk_wr() 1 for error, else 0 */ + ret = -EIO; + goto deselect; + } + addr += wlen; + cnt += wlen; + } + ret = cnt; + +deselect: + /* + * Module could take up to 10 uSec after transfer before + * ready to respond to MOD_SEL negation, and there is no way + * to tell if it is ready, so we must wait. + */ + udelay(10); + /* set QSFP MODSEL, RST, LP high */ + dd->f_gpio_mod(dd, mask, mask, mask); + /* + * Module could take up to 2 Msec to respond to MOD_SEL + * going away, and there is no way to tell if it is ready. + * so we must wait. + */ + msleep(2); + +bail: + mutex_unlock(&dd->eep_lock); + +no_unlock: + return ret; +} + +/* + * For validation, we want to check the checksums, even of the + * fields we do not otherwise use. This function reads the bytes from + * to and returns the 8lsbs of the sum, or <0 for errors + */ +static int qsfp_cks(struct qib_pportdata *ppd, int first, int next) +{ + int ret; + u16 cks; + u8 bval; + + cks = 0; + while (first < next) { + ret = qsfp_read(ppd, first, &bval, 1); + if (ret < 0) + goto bail; + cks += bval; + ++first; + } + ret = cks & 0xFF; +bail: + return ret; + +} + +int qib_refresh_qsfp_cache(struct qib_pportdata *ppd, struct qib_qsfp_cache *cp) +{ + int ret; + int idx; + u16 cks; + u32 mask; + u8 peek[4]; + + /* ensure sane contents on invalid reads, for cable swaps */ + memset(cp, 0, sizeof(*cp)); + + mask = QSFP_GPIO_MOD_PRS_N; + if (ppd->hw_pidx) + mask <<= QSFP_GPIO_PORT2_SHIFT; + + ret = ppd->dd->f_gpio_mod(ppd->dd, 0, 0, 0); + if (ret & mask) { + ret = -ENODEV; + goto bail; + } + + ret = qsfp_read(ppd, 0, peek, 3); + if (ret < 0) + goto bail; + if ((peek[0] & 0xFE) != 0x0C) + qib_dev_porterr(ppd->dd, ppd->port, + "QSFP byte0 is 0x%02X, S/B 0x0C/D\n", peek[0]); + + if ((peek[2] & 2) == 0) { + /* + * If cable is paged, rather than "flat memory", we need to + * set the page to zero, Even if it already appears to be zero. + */ + u8 poke = 0; + ret = qib_qsfp_write(ppd, 127, &poke, 1); + udelay(50); + if (ret != 1) { + qib_dev_porterr(ppd->dd, ppd->port, + "Failed QSFP Page set\n"); + goto bail; + } + } + + ret = qsfp_read(ppd, QSFP_MOD_ID_OFFS, &cp->id, 1); + if (ret < 0) + goto bail; + if ((cp->id & 0xFE) != 0x0C) + qib_dev_porterr(ppd->dd, ppd->port, + "QSFP ID byte is 0x%02X, S/B 0x0C/D\n", cp->id); + cks = cp->id; + + ret = qsfp_read(ppd, QSFP_MOD_PWR_OFFS, &cp->pwr, 1); + if (ret < 0) + goto bail; + cks += cp->pwr; + + ret = qsfp_cks(ppd, QSFP_MOD_PWR_OFFS + 1, QSFP_MOD_LEN_OFFS); + if (ret < 0) + goto bail; + cks += ret; + + ret = qsfp_read(ppd, QSFP_MOD_LEN_OFFS, &cp->len, 1); + if (ret < 0) + goto bail; + cks += cp->len; + + ret = qsfp_read(ppd, QSFP_MOD_TECH_OFFS, &cp->tech, 1); + if (ret < 0) + goto bail; + cks += cp->tech; + + ret = qsfp_read(ppd, QSFP_VEND_OFFS, &cp->vendor, QSFP_VEND_LEN); + if (ret < 0) + goto bail; + for (idx = 0; idx < QSFP_VEND_LEN; ++idx) + cks += cp->vendor[idx]; + + ret = qsfp_read(ppd, QSFP_IBXCV_OFFS, &cp->xt_xcv, 1); + if (ret < 0) + goto bail; + cks += cp->xt_xcv; + + ret = qsfp_read(ppd, QSFP_VOUI_OFFS, &cp->oui, QSFP_VOUI_LEN); + if (ret < 0) + goto bail; + for (idx = 0; idx < QSFP_VOUI_LEN; ++idx) + cks += cp->oui[idx]; + + ret = qsfp_read(ppd, QSFP_PN_OFFS, &cp->partnum, QSFP_PN_LEN); + if (ret < 0) + goto bail; + for (idx = 0; idx < QSFP_PN_LEN; ++idx) + cks += cp->partnum[idx]; + + ret = qsfp_read(ppd, QSFP_REV_OFFS, &cp->rev, QSFP_REV_LEN); + if (ret < 0) + goto bail; + for (idx = 0; idx < QSFP_REV_LEN; ++idx) + cks += cp->rev[idx]; + + ret = qsfp_read(ppd, QSFP_ATTEN_OFFS, &cp->atten, QSFP_ATTEN_LEN); + if (ret < 0) + goto bail; + for (idx = 0; idx < QSFP_ATTEN_LEN; ++idx) + cks += cp->atten[idx]; + + ret = qsfp_cks(ppd, QSFP_ATTEN_OFFS + QSFP_ATTEN_LEN, QSFP_CC_OFFS); + if (ret < 0) + goto bail; + cks += ret; + + cks &= 0xFF; + ret = qsfp_read(ppd, QSFP_CC_OFFS, &cp->cks1, 1); + if (ret < 0) + goto bail; + if (cks != cp->cks1) + qib_dev_porterr(ppd->dd, ppd->port, + "QSFP cks1 is %02X, computed %02X\n", cp->cks1, + cks); + + /* Second checksum covers 192 to (serial, date, lot) */ + ret = qsfp_cks(ppd, QSFP_CC_OFFS + 1, QSFP_SN_OFFS); + if (ret < 0) + goto bail; + cks = ret; + + ret = qsfp_read(ppd, QSFP_SN_OFFS, &cp->serial, QSFP_SN_LEN); + if (ret < 0) + goto bail; + for (idx = 0; idx < QSFP_SN_LEN; ++idx) + cks += cp->serial[idx]; + + ret = qsfp_read(ppd, QSFP_DATE_OFFS, &cp->date, QSFP_DATE_LEN); + if (ret < 0) + goto bail; + for (idx = 0; idx < QSFP_DATE_LEN; ++idx) + cks += cp->date[idx]; + + ret = qsfp_read(ppd, QSFP_LOT_OFFS, &cp->lot, QSFP_LOT_LEN); + if (ret < 0) + goto bail; + for (idx = 0; idx < QSFP_LOT_LEN; ++idx) + cks += cp->lot[idx]; + + ret = qsfp_cks(ppd, QSFP_LOT_OFFS + QSFP_LOT_LEN, QSFP_CC_EXT_OFFS); + if (ret < 0) + goto bail; + cks += ret; + + ret = qsfp_read(ppd, QSFP_CC_EXT_OFFS, &cp->cks2, 1); + if (ret < 0) + goto bail; + cks &= 0xFF; + if (cks != cp->cks2) + qib_dev_porterr(ppd->dd, ppd->port, + "QSFP cks2 is %02X, computed %02X\n", cp->cks2, + cks); + return 0; + +bail: + cp->id = 0; + return ret; +} + +const char * const qib_qsfp_devtech[16] = { + "850nm VCSEL", "1310nm VCSEL", "1550nm VCSEL", "1310nm FP", + "1310nm DFB", "1550nm DFB", "1310nm EML", "1550nm EML", + "Cu Misc", "1490nm DFB", "Cu NoEq", "Cu Eq", + "Undef", "Cu Active BothEq", "Cu FarEq", "Cu NearEq" +}; + +#define QSFP_DUMP_CHUNK 16 /* Holds longest string */ +#define QSFP_DEFAULT_HDR_CNT 224 + +static const char *pwr_codes = "1.5W2.0W2.5W3.5W"; + +/* + * Initialize structures that control access to QSFP. Called once per port + * on cards that support QSFP. + */ +void qib_qsfp_init(struct qib_qsfp_data *qd, + void (*fevent)(struct work_struct *)) +{ + u32 mask, highs; + int pins; + + struct qib_devdata *dd = qd->ppd->dd; + + /* Initialize work struct for later QSFP events */ + INIT_WORK(&qd->work, fevent); + + /* + * Later, we may want more validation. For now, just set up pins and + * blip reset. If module is present, call qib_refresh_qsfp_cache(), + * to do further init. + */ + mask = QSFP_GPIO_MOD_SEL_N | QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE; + highs = mask - QSFP_GPIO_MOD_RST_N; + if (qd->ppd->hw_pidx) { + mask <<= QSFP_GPIO_PORT2_SHIFT; + highs <<= QSFP_GPIO_PORT2_SHIFT; + } + dd->f_gpio_mod(dd, highs, mask, mask); + udelay(20); /* Generous RST dwell */ + + dd->f_gpio_mod(dd, mask, mask, mask); + /* Spec says module can take up to two seconds! */ + mask = QSFP_GPIO_MOD_PRS_N; + if (qd->ppd->hw_pidx) + mask <<= QSFP_GPIO_PORT2_SHIFT; + + /* Do not try to wait here. Better to let event handle it */ + pins = dd->f_gpio_mod(dd, 0, 0, 0); + if (pins & mask) + goto bail; + /* We see a module, but it may be unwise to look yet. Just schedule */ + qd->t_insert = get_jiffies_64(); + schedule_work(&qd->work); +bail: + return; +} + +void qib_qsfp_deinit(struct qib_qsfp_data *qd) +{ + /* + * There is nothing to do here for now. our + * work is scheduled with schedule_work(), and + * flush_scheduled_work() from remove_one will + * block until all work ssetup with schedule_work() + * completes. + */ +} + +int qib_qsfp_dump(struct qib_pportdata *ppd, char *buf, int len) +{ + struct qib_qsfp_cache cd; + u8 bin_buff[QSFP_DUMP_CHUNK]; + char lenstr[6]; + int sofar, ret; + int bidx = 0; + + sofar = 0; + ret = qib_refresh_qsfp_cache(ppd, &cd); + if (ret < 0) + goto bail; + + lenstr[0] = ' '; + lenstr[1] = '\0'; + if (QSFP_IS_CU(cd.tech)) + sprintf(lenstr, "%dM ", cd.len); + + sofar += scnprintf(buf + sofar, len - sofar, "PWR:%.3sW\n", pwr_codes + + (QSFP_PWR(cd.pwr) * 4)); + + sofar += scnprintf(buf + sofar, len - sofar, "TECH:%s%s\n", lenstr, + qib_qsfp_devtech[cd.tech >> 4]); + + sofar += scnprintf(buf + sofar, len - sofar, "Vendor:%.*s\n", + QSFP_VEND_LEN, cd.vendor); + + sofar += scnprintf(buf + sofar, len - sofar, "OUI:%06X\n", + QSFP_OUI(cd.oui)); + + sofar += scnprintf(buf + sofar, len - sofar, "Part#:%.*s\n", + QSFP_PN_LEN, cd.partnum); + sofar += scnprintf(buf + sofar, len - sofar, "Rev:%.*s\n", + QSFP_REV_LEN, cd.rev); + if (QSFP_IS_CU(cd.tech)) + sofar += scnprintf(buf + sofar, len - sofar, "Atten:%d, %d\n", + QSFP_ATTEN_SDR(cd.atten), + QSFP_ATTEN_DDR(cd.atten)); + sofar += scnprintf(buf + sofar, len - sofar, "Serial:%.*s\n", + QSFP_SN_LEN, cd.serial); + sofar += scnprintf(buf + sofar, len - sofar, "Date:%.*s\n", + QSFP_DATE_LEN, cd.date); + sofar += scnprintf(buf + sofar, len - sofar, "Lot:%.*s\n", + QSFP_LOT_LEN, cd.date); + + while (bidx < QSFP_DEFAULT_HDR_CNT) { + int iidx; + ret = qsfp_read(ppd, bidx, bin_buff, QSFP_DUMP_CHUNK); + if (ret < 0) + goto bail; + for (iidx = 0; iidx < ret; ++iidx) { + sofar += scnprintf(buf + sofar, len-sofar, " %02X", + bin_buff[iidx]); + } + sofar += scnprintf(buf + sofar, len - sofar, "\n"); + bidx += QSFP_DUMP_CHUNK; + } + ret = sofar; +bail: + return ret; +} diff --git a/drivers/infiniband/hw/qib/qib_qsfp.h b/drivers/infiniband/hw/qib/qib_qsfp.h new file mode 100644 index 000000000000..19b527bafd57 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_qsfp.h @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. + * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +/* QSFP support common definitions, for ib_qib driver */ + +#define QSFP_DEV 0xA0 +#define QSFP_PWR_LAG_MSEC 2000 + +/* + * Below are masks for various QSFP signals, for Port 1. + * Port2 equivalents are shifted by QSFP_GPIO_PORT2_SHIFT. + * _N means asserted low + */ +#define QSFP_GPIO_MOD_SEL_N (4) +#define QSFP_GPIO_MOD_PRS_N (8) +#define QSFP_GPIO_INT_N (0x10) +#define QSFP_GPIO_MOD_RST_N (0x20) +#define QSFP_GPIO_LP_MODE (0x40) +#define QSFP_GPIO_PORT2_SHIFT 5 + +#define QSFP_PAGESIZE 128 +/* Defined fields that QLogic requires of qualified cables */ +/* Byte 0 is Identifier, not checked */ +/* Byte 1 is reserved "status MSB" */ +/* Byte 2 is "status LSB" We only care that D2 "Flat Mem" is set. */ +/* + * Rest of first 128 not used, although 127 is reserved for page select + * if module is not "Flat memory". + */ +/* Byte 128 is Identifier: must be 0x0c for QSFP, or 0x0d for QSFP+ */ +#define QSFP_MOD_ID_OFFS 128 +/* + * Byte 129 is "Extended Identifier". We only care about D7,D6: Power class + * 0:1.5W, 1:2.0W, 2:2.5W, 3:3.5W + */ +#define QSFP_MOD_PWR_OFFS 129 +/* Byte 130 is Connector type. Not QLogic req'd */ +/* Bytes 131..138 are Transceiver types, bit maps for various tech, none IB */ +/* Byte 139 is encoding. code 0x01 is 8b10b. Not QLogic req'd */ +/* byte 140 is nominal bit-rate, in units of 100Mbits/sec Not QLogic req'd */ +/* Byte 141 is Extended Rate Select. Not QLogic req'd */ +/* Bytes 142..145 are lengths for various fiber types. Not QLogic req'd */ +/* Byte 146 is length for Copper. Units of 1 meter */ +#define QSFP_MOD_LEN_OFFS 146 +/* + * Byte 147 is Device technology. D0..3 not Qlogc req'd + * D4..7 select from 15 choices, translated by table: + */ +#define QSFP_MOD_TECH_OFFS 147 +extern const char *const qib_qsfp_devtech[16]; +/* Active Equalization includes fiber, copper full EQ, and copper near Eq */ +#define QSFP_IS_ACTIVE(tech) ((0xA2FF >> ((tech) >> 4)) & 1) +/* Attenuation should be valid for copper other than full/near Eq */ +#define QSFP_HAS_ATTEN(tech) ((0x4D00 >> ((tech) >> 4)) & 1) +/* Length is only valid if technology is "copper" */ +#define QSFP_IS_CU(tech) ((0xED00 >> ((tech) >> 4)) & 1) +#define QSFP_TECH_1490 9 + +#define QSFP_OUI(oui) (((unsigned)oui[0] << 16) | ((unsigned)oui[1] << 8) | \ + oui[2]) +#define QSFP_OUI_AMPHENOL 0x415048 +#define QSFP_OUI_FINISAR 0x009065 +#define QSFP_OUI_GORE 0x002177 + +/* Bytes 148..163 are Vendor Name, Left-justified Blank-filled */ +#define QSFP_VEND_OFFS 148 +#define QSFP_VEND_LEN 16 +/* Byte 164 is IB Extended tranceiver codes Bits D0..3 are SDR,DDR,QDR,EDR */ +#define QSFP_IBXCV_OFFS 164 +/* Bytes 165..167 are Vendor OUI number */ +#define QSFP_VOUI_OFFS 165 +#define QSFP_VOUI_LEN 3 +/* Bytes 168..183 are Vendor Part Number, string */ +#define QSFP_PN_OFFS 168 +#define QSFP_PN_LEN 16 +/* Bytes 184,185 are Vendor Rev. Left Justified, Blank-filled */ +#define QSFP_REV_OFFS 184 +#define QSFP_REV_LEN 2 +/* + * Bytes 186,187 are Wavelength, if Optical. Not Qlogic req'd + * If copper, they are attenuation in dB: + * Byte 186 is at 2.5Gb/sec (SDR), Byte 187 at 5.0Gb/sec (DDR) + */ +#define QSFP_ATTEN_OFFS 186 +#define QSFP_ATTEN_LEN 2 +/* Bytes 188,189 are Wavelength tolerance, not QLogic req'd */ +/* Byte 190 is Max Case Temp. Not QLogic req'd */ +/* Byte 191 is LSB of sum of bytes 128..190. Not QLogic req'd */ +#define QSFP_CC_OFFS 191 +/* Bytes 192..195 are Options implemented in qsfp. Not Qlogic req'd */ +/* Bytes 196..211 are Serial Number, String */ +#define QSFP_SN_OFFS 196 +#define QSFP_SN_LEN 16 +/* Bytes 212..219 are date-code YYMMDD (MM==1 for Jan) */ +#define QSFP_DATE_OFFS 212 +#define QSFP_DATE_LEN 6 +/* Bytes 218,219 are optional lot-code, string */ +#define QSFP_LOT_OFFS 218 +#define QSFP_LOT_LEN 2 +/* Bytes 220, 221 indicate monitoring options, Not QLogic req'd */ +/* Byte 223 is LSB of sum of bytes 192..222 */ +#define QSFP_CC_EXT_OFFS 223 + +/* + * struct qib_qsfp_data encapsulates state of QSFP device for one port. + * it will be part of port-chip-specific data if a board supports QSFP. + * + * Since multiple board-types use QSFP, and their pport_data structs + * differ (in the chip-specific section), we need a pointer to its head. + * + * Avoiding premature optimization, we will have one work_struct per port, + * and let the (increasingly inaccurately named) eep_lock arbitrate + * access to common resources. + * + */ + +/* + * Hold the parts of the onboard EEPROM that we care about, so we aren't + * coonstantly bit-boffing + */ +struct qib_qsfp_cache { + u8 id; /* must be 0x0C or 0x0D; 0 indicates invalid EEPROM read */ + u8 pwr; /* in D6,7 */ + u8 len; /* in meters, Cu only */ + u8 tech; + char vendor[QSFP_VEND_LEN]; + u8 xt_xcv; /* Ext. tranceiver codes, 4 lsbs are IB speed supported */ + u8 oui[QSFP_VOUI_LEN]; + u8 partnum[QSFP_PN_LEN]; + u8 rev[QSFP_REV_LEN]; + u8 atten[QSFP_ATTEN_LEN]; + u8 cks1; /* Checksum of bytes 128..190 */ + u8 serial[QSFP_SN_LEN]; + u8 date[QSFP_DATE_LEN]; + u8 lot[QSFP_LOT_LEN]; + u8 cks2; /* Checsum of bytes 192..222 */ +}; + +#define QSFP_PWR(pbyte) (((pbyte) >> 6) & 3) +#define QSFP_ATTEN_SDR(attenarray) (attenarray[0]) +#define QSFP_ATTEN_DDR(attenarray) (attenarray[1]) + +struct qib_qsfp_data { + /* Helps to find our way */ + struct qib_pportdata *ppd; + struct work_struct work; + struct qib_qsfp_cache cache; + u64 t_insert; +}; + +extern int qib_refresh_qsfp_cache(struct qib_pportdata *ppd, + struct qib_qsfp_cache *cp); +extern void qib_qsfp_init(struct qib_qsfp_data *qd, + void (*fevent)(struct work_struct *)); +extern void qib_qsfp_deinit(struct qib_qsfp_data *qd); diff --git a/drivers/infiniband/hw/qib/qib_rc.c b/drivers/infiniband/hw/qib/qib_rc.c new file mode 100644 index 000000000000..40c0a373719c --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_rc.c @@ -0,0 +1,2288 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. + * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include + +#include "qib.h" + +/* cut down ridiculously long IB macro names */ +#define OP(x) IB_OPCODE_RC_##x + +static void rc_timeout(unsigned long arg); + +static u32 restart_sge(struct qib_sge_state *ss, struct qib_swqe *wqe, + u32 psn, u32 pmtu) +{ + u32 len; + + len = ((psn - wqe->psn) & QIB_PSN_MASK) * pmtu; + ss->sge = wqe->sg_list[0]; + ss->sg_list = wqe->sg_list + 1; + ss->num_sge = wqe->wr.num_sge; + ss->total_len = wqe->length; + qib_skip_sge(ss, len, 0); + return wqe->length - len; +} + +static void start_timer(struct qib_qp *qp) +{ + qp->s_flags |= QIB_S_TIMER; + qp->s_timer.function = rc_timeout; + /* 4.096 usec. * (1 << qp->timeout) */ + qp->s_timer.expires = jiffies + + usecs_to_jiffies((4096UL * (1UL << qp->timeout)) / 1000UL); + add_timer(&qp->s_timer); +} + +/** + * qib_make_rc_ack - construct a response packet (ACK, NAK, or RDMA read) + * @dev: the device for this QP + * @qp: a pointer to the QP + * @ohdr: a pointer to the IB header being constructed + * @pmtu: the path MTU + * + * Return 1 if constructed; otherwise, return 0. + * Note that we are in the responder's side of the QP context. + * Note the QP s_lock must be held. + */ +static int qib_make_rc_ack(struct qib_ibdev *dev, struct qib_qp *qp, + struct qib_other_headers *ohdr, u32 pmtu) +{ + struct qib_ack_entry *e; + u32 hwords; + u32 len; + u32 bth0; + u32 bth2; + + /* Don't send an ACK if we aren't supposed to. */ + if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) + goto bail; + + /* header size in 32-bit words LRH+BTH = (8+12)/4. */ + hwords = 5; + + switch (qp->s_ack_state) { + case OP(RDMA_READ_RESPONSE_LAST): + case OP(RDMA_READ_RESPONSE_ONLY): + e = &qp->s_ack_queue[qp->s_tail_ack_queue]; + if (e->rdma_sge.mr) { + atomic_dec(&e->rdma_sge.mr->refcount); + e->rdma_sge.mr = NULL; + } + /* FALLTHROUGH */ + case OP(ATOMIC_ACKNOWLEDGE): + /* + * We can increment the tail pointer now that the last + * response has been sent instead of only being + * constructed. + */ + if (++qp->s_tail_ack_queue > QIB_MAX_RDMA_ATOMIC) + qp->s_tail_ack_queue = 0; + /* FALLTHROUGH */ + case OP(SEND_ONLY): + case OP(ACKNOWLEDGE): + /* Check for no next entry in the queue. */ + if (qp->r_head_ack_queue == qp->s_tail_ack_queue) { + if (qp->s_flags & QIB_S_ACK_PENDING) + goto normal; + goto bail; + } + + e = &qp->s_ack_queue[qp->s_tail_ack_queue]; + if (e->opcode == OP(RDMA_READ_REQUEST)) { + /* + * If a RDMA read response is being resent and + * we haven't seen the duplicate request yet, + * then stop sending the remaining responses the + * responder has seen until the requester resends it. + */ + len = e->rdma_sge.sge_length; + if (len && !e->rdma_sge.mr) { + qp->s_tail_ack_queue = qp->r_head_ack_queue; + goto bail; + } + /* Copy SGE state in case we need to resend */ + qp->s_rdma_mr = e->rdma_sge.mr; + if (qp->s_rdma_mr) + atomic_inc(&qp->s_rdma_mr->refcount); + qp->s_ack_rdma_sge.sge = e->rdma_sge; + qp->s_ack_rdma_sge.num_sge = 1; + qp->s_cur_sge = &qp->s_ack_rdma_sge; + if (len > pmtu) { + len = pmtu; + qp->s_ack_state = OP(RDMA_READ_RESPONSE_FIRST); + } else { + qp->s_ack_state = OP(RDMA_READ_RESPONSE_ONLY); + e->sent = 1; + } + ohdr->u.aeth = qib_compute_aeth(qp); + hwords++; + qp->s_ack_rdma_psn = e->psn; + bth2 = qp->s_ack_rdma_psn++ & QIB_PSN_MASK; + } else { + /* COMPARE_SWAP or FETCH_ADD */ + qp->s_cur_sge = NULL; + len = 0; + qp->s_ack_state = OP(ATOMIC_ACKNOWLEDGE); + ohdr->u.at.aeth = qib_compute_aeth(qp); + ohdr->u.at.atomic_ack_eth[0] = + cpu_to_be32(e->atomic_data >> 32); + ohdr->u.at.atomic_ack_eth[1] = + cpu_to_be32(e->atomic_data); + hwords += sizeof(ohdr->u.at) / sizeof(u32); + bth2 = e->psn & QIB_PSN_MASK; + e->sent = 1; + } + bth0 = qp->s_ack_state << 24; + break; + + case OP(RDMA_READ_RESPONSE_FIRST): + qp->s_ack_state = OP(RDMA_READ_RESPONSE_MIDDLE); + /* FALLTHROUGH */ + case OP(RDMA_READ_RESPONSE_MIDDLE): + qp->s_cur_sge = &qp->s_ack_rdma_sge; + qp->s_rdma_mr = qp->s_ack_rdma_sge.sge.mr; + if (qp->s_rdma_mr) + atomic_inc(&qp->s_rdma_mr->refcount); + len = qp->s_ack_rdma_sge.sge.sge_length; + if (len > pmtu) + len = pmtu; + else { + ohdr->u.aeth = qib_compute_aeth(qp); + hwords++; + qp->s_ack_state = OP(RDMA_READ_RESPONSE_LAST); + e = &qp->s_ack_queue[qp->s_tail_ack_queue]; + e->sent = 1; + } + bth0 = qp->s_ack_state << 24; + bth2 = qp->s_ack_rdma_psn++ & QIB_PSN_MASK; + break; + + default: +normal: + /* + * Send a regular ACK. + * Set the s_ack_state so we wait until after sending + * the ACK before setting s_ack_state to ACKNOWLEDGE + * (see above). + */ + qp->s_ack_state = OP(SEND_ONLY); + qp->s_flags &= ~QIB_S_ACK_PENDING; + qp->s_cur_sge = NULL; + if (qp->s_nak_state) + ohdr->u.aeth = + cpu_to_be32((qp->r_msn & QIB_MSN_MASK) | + (qp->s_nak_state << + QIB_AETH_CREDIT_SHIFT)); + else + ohdr->u.aeth = qib_compute_aeth(qp); + hwords++; + len = 0; + bth0 = OP(ACKNOWLEDGE) << 24; + bth2 = qp->s_ack_psn & QIB_PSN_MASK; + } + qp->s_rdma_ack_cnt++; + qp->s_hdrwords = hwords; + qp->s_cur_size = len; + qib_make_ruc_header(qp, ohdr, bth0, bth2); + return 1; + +bail: + qp->s_ack_state = OP(ACKNOWLEDGE); + qp->s_flags &= ~(QIB_S_RESP_PENDING | QIB_S_ACK_PENDING); + return 0; +} + +/** + * qib_make_rc_req - construct a request packet (SEND, RDMA r/w, ATOMIC) + * @qp: a pointer to the QP + * + * Return 1 if constructed; otherwise, return 0. + */ +int qib_make_rc_req(struct qib_qp *qp) +{ + struct qib_ibdev *dev = to_idev(qp->ibqp.device); + struct qib_other_headers *ohdr; + struct qib_sge_state *ss; + struct qib_swqe *wqe; + u32 hwords; + u32 len; + u32 bth0; + u32 bth2; + u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu); + char newreq; + unsigned long flags; + int ret = 0; + int delta; + + ohdr = &qp->s_hdr.u.oth; + if (qp->remote_ah_attr.ah_flags & IB_AH_GRH) + ohdr = &qp->s_hdr.u.l.oth; + + /* + * The lock is needed to synchronize between the sending tasklet, + * the receive interrupt handler, and timeout resends. + */ + spin_lock_irqsave(&qp->s_lock, flags); + + /* Sending responses has higher priority over sending requests. */ + if ((qp->s_flags & QIB_S_RESP_PENDING) && + qib_make_rc_ack(dev, qp, ohdr, pmtu)) + goto done; + + if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_SEND_OK)) { + if (!(ib_qib_state_ops[qp->state] & QIB_FLUSH_SEND)) + goto bail; + /* We are in the error state, flush the work request. */ + if (qp->s_last == qp->s_head) + goto bail; + /* If DMAs are in progress, we can't flush immediately. */ + if (atomic_read(&qp->s_dma_busy)) { + qp->s_flags |= QIB_S_WAIT_DMA; + goto bail; + } + wqe = get_swqe_ptr(qp, qp->s_last); + while (qp->s_last != qp->s_acked) { + qib_send_complete(qp, wqe, IB_WC_SUCCESS); + if (++qp->s_last >= qp->s_size) + qp->s_last = 0; + wqe = get_swqe_ptr(qp, qp->s_last); + } + qib_send_complete(qp, wqe, IB_WC_WR_FLUSH_ERR); + goto done; + } + + if (qp->s_flags & (QIB_S_WAIT_RNR | QIB_S_WAIT_ACK)) + goto bail; + + if (qib_cmp24(qp->s_psn, qp->s_sending_hpsn) <= 0) { + if (qib_cmp24(qp->s_sending_psn, qp->s_sending_hpsn) <= 0) { + qp->s_flags |= QIB_S_WAIT_PSN; + goto bail; + } + qp->s_sending_psn = qp->s_psn; + qp->s_sending_hpsn = qp->s_psn - 1; + } + + /* header size in 32-bit words LRH+BTH = (8+12)/4. */ + hwords = 5; + bth0 = 0; + + /* Send a request. */ + wqe = get_swqe_ptr(qp, qp->s_cur); + switch (qp->s_state) { + default: + if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_NEXT_SEND_OK)) + goto bail; + /* + * Resend an old request or start a new one. + * + * We keep track of the current SWQE so that + * we don't reset the "furthest progress" state + * if we need to back up. + */ + newreq = 0; + if (qp->s_cur == qp->s_tail) { + /* Check if send work queue is empty. */ + if (qp->s_tail == qp->s_head) + goto bail; + /* + * If a fence is requested, wait for previous + * RDMA read and atomic operations to finish. + */ + if ((wqe->wr.send_flags & IB_SEND_FENCE) && + qp->s_num_rd_atomic) { + qp->s_flags |= QIB_S_WAIT_FENCE; + goto bail; + } + wqe->psn = qp->s_next_psn; + newreq = 1; + } + /* + * Note that we have to be careful not to modify the + * original work request since we may need to resend + * it. + */ + len = wqe->length; + ss = &qp->s_sge; + bth2 = qp->s_psn & QIB_PSN_MASK; + switch (wqe->wr.opcode) { + case IB_WR_SEND: + case IB_WR_SEND_WITH_IMM: + /* If no credit, return. */ + if (!(qp->s_flags & QIB_S_UNLIMITED_CREDIT) && + qib_cmp24(wqe->ssn, qp->s_lsn + 1) > 0) { + qp->s_flags |= QIB_S_WAIT_SSN_CREDIT; + goto bail; + } + wqe->lpsn = wqe->psn; + if (len > pmtu) { + wqe->lpsn += (len - 1) / pmtu; + qp->s_state = OP(SEND_FIRST); + len = pmtu; + break; + } + if (wqe->wr.opcode == IB_WR_SEND) + qp->s_state = OP(SEND_ONLY); + else { + qp->s_state = OP(SEND_ONLY_WITH_IMMEDIATE); + /* Immediate data comes after the BTH */ + ohdr->u.imm_data = wqe->wr.ex.imm_data; + hwords += 1; + } + if (wqe->wr.send_flags & IB_SEND_SOLICITED) + bth0 |= IB_BTH_SOLICITED; + bth2 |= IB_BTH_REQ_ACK; + if (++qp->s_cur == qp->s_size) + qp->s_cur = 0; + break; + + case IB_WR_RDMA_WRITE: + if (newreq && !(qp->s_flags & QIB_S_UNLIMITED_CREDIT)) + qp->s_lsn++; + /* FALLTHROUGH */ + case IB_WR_RDMA_WRITE_WITH_IMM: + /* If no credit, return. */ + if (!(qp->s_flags & QIB_S_UNLIMITED_CREDIT) && + qib_cmp24(wqe->ssn, qp->s_lsn + 1) > 0) { + qp->s_flags |= QIB_S_WAIT_SSN_CREDIT; + goto bail; + } + ohdr->u.rc.reth.vaddr = + cpu_to_be64(wqe->wr.wr.rdma.remote_addr); + ohdr->u.rc.reth.rkey = + cpu_to_be32(wqe->wr.wr.rdma.rkey); + ohdr->u.rc.reth.length = cpu_to_be32(len); + hwords += sizeof(struct ib_reth) / sizeof(u32); + wqe->lpsn = wqe->psn; + if (len > pmtu) { + wqe->lpsn += (len - 1) / pmtu; + qp->s_state = OP(RDMA_WRITE_FIRST); + len = pmtu; + break; + } + if (wqe->wr.opcode == IB_WR_RDMA_WRITE) + qp->s_state = OP(RDMA_WRITE_ONLY); + else { + qp->s_state = + OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE); + /* Immediate data comes after RETH */ + ohdr->u.rc.imm_data = wqe->wr.ex.imm_data; + hwords += 1; + if (wqe->wr.send_flags & IB_SEND_SOLICITED) + bth0 |= IB_BTH_SOLICITED; + } + bth2 |= IB_BTH_REQ_ACK; + if (++qp->s_cur == qp->s_size) + qp->s_cur = 0; + break; + + case IB_WR_RDMA_READ: + /* + * Don't allow more operations to be started + * than the QP limits allow. + */ + if (newreq) { + if (qp->s_num_rd_atomic >= + qp->s_max_rd_atomic) { + qp->s_flags |= QIB_S_WAIT_RDMAR; + goto bail; + } + qp->s_num_rd_atomic++; + if (!(qp->s_flags & QIB_S_UNLIMITED_CREDIT)) + qp->s_lsn++; + /* + * Adjust s_next_psn to count the + * expected number of responses. + */ + if (len > pmtu) + qp->s_next_psn += (len - 1) / pmtu; + wqe->lpsn = qp->s_next_psn++; + } + ohdr->u.rc.reth.vaddr = + cpu_to_be64(wqe->wr.wr.rdma.remote_addr); + ohdr->u.rc.reth.rkey = + cpu_to_be32(wqe->wr.wr.rdma.rkey); + ohdr->u.rc.reth.length = cpu_to_be32(len); + qp->s_state = OP(RDMA_READ_REQUEST); + hwords += sizeof(ohdr->u.rc.reth) / sizeof(u32); + ss = NULL; + len = 0; + bth2 |= IB_BTH_REQ_ACK; + if (++qp->s_cur == qp->s_size) + qp->s_cur = 0; + break; + + case IB_WR_ATOMIC_CMP_AND_SWP: + case IB_WR_ATOMIC_FETCH_AND_ADD: + /* + * Don't allow more operations to be started + * than the QP limits allow. + */ + if (newreq) { + if (qp->s_num_rd_atomic >= + qp->s_max_rd_atomic) { + qp->s_flags |= QIB_S_WAIT_RDMAR; + goto bail; + } + qp->s_num_rd_atomic++; + if (!(qp->s_flags & QIB_S_UNLIMITED_CREDIT)) + qp->s_lsn++; + wqe->lpsn = wqe->psn; + } + if (wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP) { + qp->s_state = OP(COMPARE_SWAP); + ohdr->u.atomic_eth.swap_data = cpu_to_be64( + wqe->wr.wr.atomic.swap); + ohdr->u.atomic_eth.compare_data = cpu_to_be64( + wqe->wr.wr.atomic.compare_add); + } else { + qp->s_state = OP(FETCH_ADD); + ohdr->u.atomic_eth.swap_data = cpu_to_be64( + wqe->wr.wr.atomic.compare_add); + ohdr->u.atomic_eth.compare_data = 0; + } + ohdr->u.atomic_eth.vaddr[0] = cpu_to_be32( + wqe->wr.wr.atomic.remote_addr >> 32); + ohdr->u.atomic_eth.vaddr[1] = cpu_to_be32( + wqe->wr.wr.atomic.remote_addr); + ohdr->u.atomic_eth.rkey = cpu_to_be32( + wqe->wr.wr.atomic.rkey); + hwords += sizeof(struct ib_atomic_eth) / sizeof(u32); + ss = NULL; + len = 0; + bth2 |= IB_BTH_REQ_ACK; + if (++qp->s_cur == qp->s_size) + qp->s_cur = 0; + break; + + default: + goto bail; + } + qp->s_sge.sge = wqe->sg_list[0]; + qp->s_sge.sg_list = wqe->sg_list + 1; + qp->s_sge.num_sge = wqe->wr.num_sge; + qp->s_sge.total_len = wqe->length; + qp->s_len = wqe->length; + if (newreq) { + qp->s_tail++; + if (qp->s_tail >= qp->s_size) + qp->s_tail = 0; + } + if (wqe->wr.opcode == IB_WR_RDMA_READ) + qp->s_psn = wqe->lpsn + 1; + else { + qp->s_psn++; + if (qib_cmp24(qp->s_psn, qp->s_next_psn) > 0) + qp->s_next_psn = qp->s_psn; + } + break; + + case OP(RDMA_READ_RESPONSE_FIRST): + /* + * qp->s_state is normally set to the opcode of the + * last packet constructed for new requests and therefore + * is never set to RDMA read response. + * RDMA_READ_RESPONSE_FIRST is used by the ACK processing + * thread to indicate a SEND needs to be restarted from an + * earlier PSN without interferring with the sending thread. + * See qib_restart_rc(). + */ + qp->s_len = restart_sge(&qp->s_sge, wqe, qp->s_psn, pmtu); + /* FALLTHROUGH */ + case OP(SEND_FIRST): + qp->s_state = OP(SEND_MIDDLE); + /* FALLTHROUGH */ + case OP(SEND_MIDDLE): + bth2 = qp->s_psn++ & QIB_PSN_MASK; + if (qib_cmp24(qp->s_psn, qp->s_next_psn) > 0) + qp->s_next_psn = qp->s_psn; + ss = &qp->s_sge; + len = qp->s_len; + if (len > pmtu) { + len = pmtu; + break; + } + if (wqe->wr.opcode == IB_WR_SEND) + qp->s_state = OP(SEND_LAST); + else { + qp->s_state = OP(SEND_LAST_WITH_IMMEDIATE); + /* Immediate data comes after the BTH */ + ohdr->u.imm_data = wqe->wr.ex.imm_data; + hwords += 1; + } + if (wqe->wr.send_flags & IB_SEND_SOLICITED) + bth0 |= IB_BTH_SOLICITED; + bth2 |= IB_BTH_REQ_ACK; + qp->s_cur++; + if (qp->s_cur >= qp->s_size) + qp->s_cur = 0; + break; + + case OP(RDMA_READ_RESPONSE_LAST): + /* + * qp->s_state is normally set to the opcode of the + * last packet constructed for new requests and therefore + * is never set to RDMA read response. + * RDMA_READ_RESPONSE_LAST is used by the ACK processing + * thread to indicate a RDMA write needs to be restarted from + * an earlier PSN without interferring with the sending thread. + * See qib_restart_rc(). + */ + qp->s_len = restart_sge(&qp->s_sge, wqe, qp->s_psn, pmtu); + /* FALLTHROUGH */ + case OP(RDMA_WRITE_FIRST): + qp->s_state = OP(RDMA_WRITE_MIDDLE); + /* FALLTHROUGH */ + case OP(RDMA_WRITE_MIDDLE): + bth2 = qp->s_psn++ & QIB_PSN_MASK; + if (qib_cmp24(qp->s_psn, qp->s_next_psn) > 0) + qp->s_next_psn = qp->s_psn; + ss = &qp->s_sge; + len = qp->s_len; + if (len > pmtu) { + len = pmtu; + break; + } + if (wqe->wr.opcode == IB_WR_RDMA_WRITE) + qp->s_state = OP(RDMA_WRITE_LAST); + else { + qp->s_state = OP(RDMA_WRITE_LAST_WITH_IMMEDIATE); + /* Immediate data comes after the BTH */ + ohdr->u.imm_data = wqe->wr.ex.imm_data; + hwords += 1; + if (wqe->wr.send_flags & IB_SEND_SOLICITED) + bth0 |= IB_BTH_SOLICITED; + } + bth2 |= IB_BTH_REQ_ACK; + qp->s_cur++; + if (qp->s_cur >= qp->s_size) + qp->s_cur = 0; + break; + + case OP(RDMA_READ_RESPONSE_MIDDLE): + /* + * qp->s_state is normally set to the opcode of the + * last packet constructed for new requests and therefore + * is never set to RDMA read response. + * RDMA_READ_RESPONSE_MIDDLE is used by the ACK processing + * thread to indicate a RDMA read needs to be restarted from + * an earlier PSN without interferring with the sending thread. + * See qib_restart_rc(). + */ + len = ((qp->s_psn - wqe->psn) & QIB_PSN_MASK) * pmtu; + ohdr->u.rc.reth.vaddr = + cpu_to_be64(wqe->wr.wr.rdma.remote_addr + len); + ohdr->u.rc.reth.rkey = + cpu_to_be32(wqe->wr.wr.rdma.rkey); + ohdr->u.rc.reth.length = cpu_to_be32(wqe->length - len); + qp->s_state = OP(RDMA_READ_REQUEST); + hwords += sizeof(ohdr->u.rc.reth) / sizeof(u32); + bth2 = (qp->s_psn & QIB_PSN_MASK) | IB_BTH_REQ_ACK; + qp->s_psn = wqe->lpsn + 1; + ss = NULL; + len = 0; + qp->s_cur++; + if (qp->s_cur == qp->s_size) + qp->s_cur = 0; + break; + } + qp->s_sending_hpsn = bth2; + delta = (((int) bth2 - (int) wqe->psn) << 8) >> 8; + if (delta && delta % QIB_PSN_CREDIT == 0) + bth2 |= IB_BTH_REQ_ACK; + if (qp->s_flags & QIB_S_SEND_ONE) { + qp->s_flags &= ~QIB_S_SEND_ONE; + qp->s_flags |= QIB_S_WAIT_ACK; + bth2 |= IB_BTH_REQ_ACK; + } + qp->s_len -= len; + qp->s_hdrwords = hwords; + qp->s_cur_sge = ss; + qp->s_cur_size = len; + qib_make_ruc_header(qp, ohdr, bth0 | (qp->s_state << 24), bth2); +done: + ret = 1; + goto unlock; + +bail: + qp->s_flags &= ~QIB_S_BUSY; +unlock: + spin_unlock_irqrestore(&qp->s_lock, flags); + return ret; +} + +/** + * qib_send_rc_ack - Construct an ACK packet and send it + * @qp: a pointer to the QP + * + * This is called from qib_rc_rcv() and qib_kreceive(). + * Note that RDMA reads and atomics are handled in the + * send side QP state and tasklet. + */ +void qib_send_rc_ack(struct qib_qp *qp) +{ + struct qib_devdata *dd = dd_from_ibdev(qp->ibqp.device); + struct qib_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); + struct qib_pportdata *ppd = ppd_from_ibp(ibp); + u64 pbc; + u16 lrh0; + u32 bth0; + u32 hwords; + u32 pbufn; + u32 __iomem *piobuf; + struct qib_ib_header hdr; + struct qib_other_headers *ohdr; + u32 control; + unsigned long flags; + + spin_lock_irqsave(&qp->s_lock, flags); + + if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) + goto unlock; + + /* Don't send ACK or NAK if a RDMA read or atomic is pending. */ + if ((qp->s_flags & QIB_S_RESP_PENDING) || qp->s_rdma_ack_cnt) + goto queue_ack; + + /* Construct the header with s_lock held so APM doesn't change it. */ + ohdr = &hdr.u.oth; + lrh0 = QIB_LRH_BTH; + /* header size in 32-bit words LRH+BTH+AETH = (8+12+4)/4. */ + hwords = 6; + if (unlikely(qp->remote_ah_attr.ah_flags & IB_AH_GRH)) { + hwords += qib_make_grh(ibp, &hdr.u.l.grh, + &qp->remote_ah_attr.grh, hwords, 0); + ohdr = &hdr.u.l.oth; + lrh0 = QIB_LRH_GRH; + } + /* read pkey_index w/o lock (its atomic) */ + bth0 = qib_get_pkey(ibp, qp->s_pkey_index) | (OP(ACKNOWLEDGE) << 24); + if (qp->s_mig_state == IB_MIG_MIGRATED) + bth0 |= IB_BTH_MIG_REQ; + if (qp->r_nak_state) + ohdr->u.aeth = cpu_to_be32((qp->r_msn & QIB_MSN_MASK) | + (qp->r_nak_state << + QIB_AETH_CREDIT_SHIFT)); + else + ohdr->u.aeth = qib_compute_aeth(qp); + lrh0 |= ibp->sl_to_vl[qp->remote_ah_attr.sl] << 12 | + qp->remote_ah_attr.sl << 4; + hdr.lrh[0] = cpu_to_be16(lrh0); + hdr.lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid); + hdr.lrh[2] = cpu_to_be16(hwords + SIZE_OF_CRC); + hdr.lrh[3] = cpu_to_be16(ppd->lid | qp->remote_ah_attr.src_path_bits); + ohdr->bth[0] = cpu_to_be32(bth0); + ohdr->bth[1] = cpu_to_be32(qp->remote_qpn); + ohdr->bth[2] = cpu_to_be32(qp->r_ack_psn & QIB_PSN_MASK); + + spin_unlock_irqrestore(&qp->s_lock, flags); + + /* Don't try to send ACKs if the link isn't ACTIVE */ + if (!(ppd->lflags & QIBL_LINKACTIVE)) + goto done; + + control = dd->f_setpbc_control(ppd, hwords + SIZE_OF_CRC, + qp->s_srate, lrh0 >> 12); + /* length is + 1 for the control dword */ + pbc = ((u64) control << 32) | (hwords + 1); + + piobuf = dd->f_getsendbuf(ppd, pbc, &pbufn); + if (!piobuf) { + /* + * We are out of PIO buffers at the moment. + * Pass responsibility for sending the ACK to the + * send tasklet so that when a PIO buffer becomes + * available, the ACK is sent ahead of other outgoing + * packets. + */ + spin_lock_irqsave(&qp->s_lock, flags); + goto queue_ack; + } + + /* + * Write the pbc. + * We have to flush after the PBC for correctness + * on some cpus or WC buffer can be written out of order. + */ + writeq(pbc, piobuf); + + if (dd->flags & QIB_PIO_FLUSH_WC) { + u32 *hdrp = (u32 *) &hdr; + + qib_flush_wc(); + qib_pio_copy(piobuf + 2, hdrp, hwords - 1); + qib_flush_wc(); + __raw_writel(hdrp[hwords - 1], piobuf + hwords + 1); + } else + qib_pio_copy(piobuf + 2, (u32 *) &hdr, hwords); + + if (dd->flags & QIB_USE_SPCL_TRIG) { + u32 spcl_off = (pbufn >= dd->piobcnt2k) ? 2047 : 1023; + + qib_flush_wc(); + __raw_writel(0xaebecede, piobuf + spcl_off); + } + + qib_flush_wc(); + qib_sendbuf_done(dd, pbufn); + + ibp->n_unicast_xmit++; + goto done; + +queue_ack: + if (ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK) { + ibp->n_rc_qacks++; + qp->s_flags |= QIB_S_ACK_PENDING | QIB_S_RESP_PENDING; + qp->s_nak_state = qp->r_nak_state; + qp->s_ack_psn = qp->r_ack_psn; + + /* Schedule the send tasklet. */ + qib_schedule_send(qp); + } +unlock: + spin_unlock_irqrestore(&qp->s_lock, flags); +done: + return; +} + +/** + * reset_psn - reset the QP state to send starting from PSN + * @qp: the QP + * @psn: the packet sequence number to restart at + * + * This is called from qib_rc_rcv() to process an incoming RC ACK + * for the given QP. + * Called at interrupt level with the QP s_lock held. + */ +static void reset_psn(struct qib_qp *qp, u32 psn) +{ + u32 n = qp->s_acked; + struct qib_swqe *wqe = get_swqe_ptr(qp, n); + u32 opcode; + + qp->s_cur = n; + + /* + * If we are starting the request from the beginning, + * let the normal send code handle initialization. + */ + if (qib_cmp24(psn, wqe->psn) <= 0) { + qp->s_state = OP(SEND_LAST); + goto done; + } + + /* Find the work request opcode corresponding to the given PSN. */ + opcode = wqe->wr.opcode; + for (;;) { + int diff; + + if (++n == qp->s_size) + n = 0; + if (n == qp->s_tail) + break; + wqe = get_swqe_ptr(qp, n); + diff = qib_cmp24(psn, wqe->psn); + if (diff < 0) + break; + qp->s_cur = n; + /* + * If we are starting the request from the beginning, + * let the normal send code handle initialization. + */ + if (diff == 0) { + qp->s_state = OP(SEND_LAST); + goto done; + } + opcode = wqe->wr.opcode; + } + + /* + * Set the state to restart in the middle of a request. + * Don't change the s_sge, s_cur_sge, or s_cur_size. + * See qib_make_rc_req(). + */ + switch (opcode) { + case IB_WR_SEND: + case IB_WR_SEND_WITH_IMM: + qp->s_state = OP(RDMA_READ_RESPONSE_FIRST); + break; + + case IB_WR_RDMA_WRITE: + case IB_WR_RDMA_WRITE_WITH_IMM: + qp->s_state = OP(RDMA_READ_RESPONSE_LAST); + break; + + case IB_WR_RDMA_READ: + qp->s_state = OP(RDMA_READ_RESPONSE_MIDDLE); + break; + + default: + /* + * This case shouldn't happen since its only + * one PSN per req. + */ + qp->s_state = OP(SEND_LAST); + } +done: + qp->s_psn = psn; + /* + * Set QIB_S_WAIT_PSN as qib_rc_complete() may start the timer + * asynchronously before the send tasklet can get scheduled. + * Doing it in qib_make_rc_req() is too late. + */ + if ((qib_cmp24(qp->s_psn, qp->s_sending_hpsn) <= 0) && + (qib_cmp24(qp->s_sending_psn, qp->s_sending_hpsn) <= 0)) + qp->s_flags |= QIB_S_WAIT_PSN; +} + +/* + * Back up requester to resend the last un-ACKed request. + * The QP s_lock should be held and interrupts disabled. + */ +static void qib_restart_rc(struct qib_qp *qp, u32 psn, int wait) +{ + struct qib_swqe *wqe = get_swqe_ptr(qp, qp->s_acked); + struct qib_ibport *ibp; + + if (qp->s_retry == 0) { + if (qp->s_mig_state == IB_MIG_ARMED) { + qib_migrate_qp(qp); + qp->s_retry = qp->s_retry_cnt; + } else if (qp->s_last == qp->s_acked) { + qib_send_complete(qp, wqe, IB_WC_RETRY_EXC_ERR); + qib_error_qp(qp, IB_WC_WR_FLUSH_ERR); + return; + } else /* XXX need to handle delayed completion */ + return; + } else + qp->s_retry--; + + ibp = to_iport(qp->ibqp.device, qp->port_num); + if (wqe->wr.opcode == IB_WR_RDMA_READ) + ibp->n_rc_resends++; + else + ibp->n_rc_resends += (qp->s_psn - psn) & QIB_PSN_MASK; + + qp->s_flags &= ~(QIB_S_WAIT_FENCE | QIB_S_WAIT_RDMAR | + QIB_S_WAIT_SSN_CREDIT | QIB_S_WAIT_PSN | + QIB_S_WAIT_ACK); + if (wait) + qp->s_flags |= QIB_S_SEND_ONE; + reset_psn(qp, psn); +} + +/* + * This is called from s_timer for missing responses. + */ +static void rc_timeout(unsigned long arg) +{ + struct qib_qp *qp = (struct qib_qp *)arg; + struct qib_ibport *ibp; + unsigned long flags; + + spin_lock_irqsave(&qp->s_lock, flags); + if (qp->s_flags & QIB_S_TIMER) { + ibp = to_iport(qp->ibqp.device, qp->port_num); + ibp->n_rc_timeouts++; + qp->s_flags &= ~QIB_S_TIMER; + del_timer(&qp->s_timer); + qib_restart_rc(qp, qp->s_last_psn + 1, 1); + qib_schedule_send(qp); + } + spin_unlock_irqrestore(&qp->s_lock, flags); +} + +/* + * This is called from s_timer for RNR timeouts. + */ +void qib_rc_rnr_retry(unsigned long arg) +{ + struct qib_qp *qp = (struct qib_qp *)arg; + unsigned long flags; + + spin_lock_irqsave(&qp->s_lock, flags); + if (qp->s_flags & QIB_S_WAIT_RNR) { + qp->s_flags &= ~QIB_S_WAIT_RNR; + del_timer(&qp->s_timer); + qib_schedule_send(qp); + } + spin_unlock_irqrestore(&qp->s_lock, flags); +} + +/* + * Set qp->s_sending_psn to the next PSN after the given one. + * This would be psn+1 except when RDMA reads are present. + */ +static void reset_sending_psn(struct qib_qp *qp, u32 psn) +{ + struct qib_swqe *wqe; + u32 n = qp->s_last; + + /* Find the work request corresponding to the given PSN. */ + for (;;) { + wqe = get_swqe_ptr(qp, n); + if (qib_cmp24(psn, wqe->lpsn) <= 0) { + if (wqe->wr.opcode == IB_WR_RDMA_READ) + qp->s_sending_psn = wqe->lpsn + 1; + else + qp->s_sending_psn = psn + 1; + break; + } + if (++n == qp->s_size) + n = 0; + if (n == qp->s_tail) + break; + } +} + +/* + * This should be called with the QP s_lock held and interrupts disabled. + */ +void qib_rc_send_complete(struct qib_qp *qp, struct qib_ib_header *hdr) +{ + struct qib_other_headers *ohdr; + struct qib_swqe *wqe; + struct ib_wc wc; + unsigned i; + u32 opcode; + u32 psn; + + if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_OR_FLUSH_SEND)) + return; + + /* Find out where the BTH is */ + if ((be16_to_cpu(hdr->lrh[0]) & 3) == QIB_LRH_BTH) + ohdr = &hdr->u.oth; + else + ohdr = &hdr->u.l.oth; + + opcode = be32_to_cpu(ohdr->bth[0]) >> 24; + if (opcode >= OP(RDMA_READ_RESPONSE_FIRST) && + opcode <= OP(ATOMIC_ACKNOWLEDGE)) { + WARN_ON(!qp->s_rdma_ack_cnt); + qp->s_rdma_ack_cnt--; + return; + } + + psn = be32_to_cpu(ohdr->bth[2]); + reset_sending_psn(qp, psn); + + /* + * Start timer after a packet requesting an ACK has been sent and + * there are still requests that haven't been acked. + */ + if ((psn & IB_BTH_REQ_ACK) && qp->s_acked != qp->s_tail && + !(qp->s_flags & (QIB_S_TIMER | QIB_S_WAIT_RNR | QIB_S_WAIT_PSN))) + start_timer(qp); + + while (qp->s_last != qp->s_acked) { + wqe = get_swqe_ptr(qp, qp->s_last); + if (qib_cmp24(wqe->lpsn, qp->s_sending_psn) >= 0 && + qib_cmp24(qp->s_sending_psn, qp->s_sending_hpsn) <= 0) + break; + for (i = 0; i < wqe->wr.num_sge; i++) { + struct qib_sge *sge = &wqe->sg_list[i]; + + atomic_dec(&sge->mr->refcount); + } + /* Post a send completion queue entry if requested. */ + if (!(qp->s_flags & QIB_S_SIGNAL_REQ_WR) || + (wqe->wr.send_flags & IB_SEND_SIGNALED)) { + memset(&wc, 0, sizeof wc); + wc.wr_id = wqe->wr.wr_id; + wc.status = IB_WC_SUCCESS; + wc.opcode = ib_qib_wc_opcode[wqe->wr.opcode]; + wc.byte_len = wqe->length; + wc.qp = &qp->ibqp; + qib_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 0); + } + if (++qp->s_last >= qp->s_size) + qp->s_last = 0; + } + /* + * If we were waiting for sends to complete before resending, + * and they are now complete, restart sending. + */ + if (qp->s_flags & QIB_S_WAIT_PSN && + qib_cmp24(qp->s_sending_psn, qp->s_sending_hpsn) > 0) { + qp->s_flags &= ~QIB_S_WAIT_PSN; + qp->s_sending_psn = qp->s_psn; + qp->s_sending_hpsn = qp->s_psn - 1; + qib_schedule_send(qp); + } +} + +static inline void update_last_psn(struct qib_qp *qp, u32 psn) +{ + qp->s_last_psn = psn; +} + +/* + * Generate a SWQE completion. + * This is similar to qib_send_complete but has to check to be sure + * that the SGEs are not being referenced if the SWQE is being resent. + */ +static struct qib_swqe *do_rc_completion(struct qib_qp *qp, + struct qib_swqe *wqe, + struct qib_ibport *ibp) +{ + struct ib_wc wc; + unsigned i; + + /* + * Don't decrement refcount and don't generate a + * completion if the SWQE is being resent until the send + * is finished. + */ + if (qib_cmp24(wqe->lpsn, qp->s_sending_psn) < 0 || + qib_cmp24(qp->s_sending_psn, qp->s_sending_hpsn) > 0) { + for (i = 0; i < wqe->wr.num_sge; i++) { + struct qib_sge *sge = &wqe->sg_list[i]; + + atomic_dec(&sge->mr->refcount); + } + /* Post a send completion queue entry if requested. */ + if (!(qp->s_flags & QIB_S_SIGNAL_REQ_WR) || + (wqe->wr.send_flags & IB_SEND_SIGNALED)) { + memset(&wc, 0, sizeof wc); + wc.wr_id = wqe->wr.wr_id; + wc.status = IB_WC_SUCCESS; + wc.opcode = ib_qib_wc_opcode[wqe->wr.opcode]; + wc.byte_len = wqe->length; + wc.qp = &qp->ibqp; + qib_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 0); + } + if (++qp->s_last >= qp->s_size) + qp->s_last = 0; + } else + ibp->n_rc_delayed_comp++; + + qp->s_retry = qp->s_retry_cnt; + update_last_psn(qp, wqe->lpsn); + + /* + * If we are completing a request which is in the process of + * being resent, we can stop resending it since we know the + * responder has already seen it. + */ + if (qp->s_acked == qp->s_cur) { + if (++qp->s_cur >= qp->s_size) + qp->s_cur = 0; + qp->s_acked = qp->s_cur; + wqe = get_swqe_ptr(qp, qp->s_cur); + if (qp->s_acked != qp->s_tail) { + qp->s_state = OP(SEND_LAST); + qp->s_psn = wqe->psn; + } + } else { + if (++qp->s_acked >= qp->s_size) + qp->s_acked = 0; + if (qp->state == IB_QPS_SQD && qp->s_acked == qp->s_cur) + qp->s_draining = 0; + wqe = get_swqe_ptr(qp, qp->s_acked); + } + return wqe; +} + +/** + * do_rc_ack - process an incoming RC ACK + * @qp: the QP the ACK came in on + * @psn: the packet sequence number of the ACK + * @opcode: the opcode of the request that resulted in the ACK + * + * This is called from qib_rc_rcv_resp() to process an incoming RC ACK + * for the given QP. + * Called at interrupt level with the QP s_lock held. + * Returns 1 if OK, 0 if current operation should be aborted (NAK). + */ +static int do_rc_ack(struct qib_qp *qp, u32 aeth, u32 psn, int opcode, + u64 val, struct qib_ctxtdata *rcd) +{ + struct qib_ibport *ibp; + enum ib_wc_status status; + struct qib_swqe *wqe; + int ret = 0; + u32 ack_psn; + int diff; + + /* Remove QP from retry timer */ + if (qp->s_flags & (QIB_S_TIMER | QIB_S_WAIT_RNR)) { + qp->s_flags &= ~(QIB_S_TIMER | QIB_S_WAIT_RNR); + del_timer(&qp->s_timer); + } + + /* + * Note that NAKs implicitly ACK outstanding SEND and RDMA write + * requests and implicitly NAK RDMA read and atomic requests issued + * before the NAK'ed request. The MSN won't include the NAK'ed + * request but will include an ACK'ed request(s). + */ + ack_psn = psn; + if (aeth >> 29) + ack_psn--; + wqe = get_swqe_ptr(qp, qp->s_acked); + ibp = to_iport(qp->ibqp.device, qp->port_num); + + /* + * The MSN might be for a later WQE than the PSN indicates so + * only complete WQEs that the PSN finishes. + */ + while ((diff = qib_cmp24(ack_psn, wqe->lpsn)) >= 0) { + /* + * RDMA_READ_RESPONSE_ONLY is a special case since + * we want to generate completion events for everything + * before the RDMA read, copy the data, then generate + * the completion for the read. + */ + if (wqe->wr.opcode == IB_WR_RDMA_READ && + opcode == OP(RDMA_READ_RESPONSE_ONLY) && + diff == 0) { + ret = 1; + goto bail; + } + /* + * If this request is a RDMA read or atomic, and the ACK is + * for a later operation, this ACK NAKs the RDMA read or + * atomic. In other words, only a RDMA_READ_LAST or ONLY + * can ACK a RDMA read and likewise for atomic ops. Note + * that the NAK case can only happen if relaxed ordering is + * used and requests are sent after an RDMA read or atomic + * is sent but before the response is received. + */ + if ((wqe->wr.opcode == IB_WR_RDMA_READ && + (opcode != OP(RDMA_READ_RESPONSE_LAST) || diff != 0)) || + ((wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP || + wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD) && + (opcode != OP(ATOMIC_ACKNOWLEDGE) || diff != 0))) { + /* Retry this request. */ + if (!(qp->r_flags & QIB_R_RDMAR_SEQ)) { + qp->r_flags |= QIB_R_RDMAR_SEQ; + qib_restart_rc(qp, qp->s_last_psn + 1, 0); + if (list_empty(&qp->rspwait)) { + qp->r_flags |= QIB_R_RSP_SEND; + atomic_inc(&qp->refcount); + list_add_tail(&qp->rspwait, + &rcd->qp_wait_list); + } + } + /* + * No need to process the ACK/NAK since we are + * restarting an earlier request. + */ + goto bail; + } + if (wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP || + wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD) { + u64 *vaddr = wqe->sg_list[0].vaddr; + *vaddr = val; + } + if (qp->s_num_rd_atomic && + (wqe->wr.opcode == IB_WR_RDMA_READ || + wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP || + wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD)) { + qp->s_num_rd_atomic--; + /* Restart sending task if fence is complete */ + if ((qp->s_flags & QIB_S_WAIT_FENCE) && + !qp->s_num_rd_atomic) { + qp->s_flags &= ~(QIB_S_WAIT_FENCE | + QIB_S_WAIT_ACK); + qib_schedule_send(qp); + } else if (qp->s_flags & QIB_S_WAIT_RDMAR) { + qp->s_flags &= ~(QIB_S_WAIT_RDMAR | + QIB_S_WAIT_ACK); + qib_schedule_send(qp); + } + } + wqe = do_rc_completion(qp, wqe, ibp); + if (qp->s_acked == qp->s_tail) + break; + } + + switch (aeth >> 29) { + case 0: /* ACK */ + ibp->n_rc_acks++; + if (qp->s_acked != qp->s_tail) { + /* + * We are expecting more ACKs so + * reset the retransmit timer. + */ + start_timer(qp); + /* + * We can stop resending the earlier packets and + * continue with the next packet the receiver wants. + */ + if (qib_cmp24(qp->s_psn, psn) <= 0) + reset_psn(qp, psn + 1); + } else if (qib_cmp24(qp->s_psn, psn) <= 0) { + qp->s_state = OP(SEND_LAST); + qp->s_psn = psn + 1; + } + if (qp->s_flags & QIB_S_WAIT_ACK) { + qp->s_flags &= ~QIB_S_WAIT_ACK; + qib_schedule_send(qp); + } + qib_get_credit(qp, aeth); + qp->s_rnr_retry = qp->s_rnr_retry_cnt; + qp->s_retry = qp->s_retry_cnt; + update_last_psn(qp, psn); + ret = 1; + goto bail; + + case 1: /* RNR NAK */ + ibp->n_rnr_naks++; + if (qp->s_acked == qp->s_tail) + goto bail; + if (qp->s_flags & QIB_S_WAIT_RNR) + goto bail; + if (qp->s_rnr_retry == 0) { + status = IB_WC_RNR_RETRY_EXC_ERR; + goto class_b; + } + if (qp->s_rnr_retry_cnt < 7) + qp->s_rnr_retry--; + + /* The last valid PSN is the previous PSN. */ + update_last_psn(qp, psn - 1); + + ibp->n_rc_resends += (qp->s_psn - psn) & QIB_PSN_MASK; + + reset_psn(qp, psn); + + qp->s_flags &= ~(QIB_S_WAIT_SSN_CREDIT | QIB_S_WAIT_ACK); + qp->s_flags |= QIB_S_WAIT_RNR; + qp->s_timer.function = qib_rc_rnr_retry; + qp->s_timer.expires = jiffies + usecs_to_jiffies( + ib_qib_rnr_table[(aeth >> QIB_AETH_CREDIT_SHIFT) & + QIB_AETH_CREDIT_MASK]); + add_timer(&qp->s_timer); + goto bail; + + case 3: /* NAK */ + if (qp->s_acked == qp->s_tail) + goto bail; + /* The last valid PSN is the previous PSN. */ + update_last_psn(qp, psn - 1); + switch ((aeth >> QIB_AETH_CREDIT_SHIFT) & + QIB_AETH_CREDIT_MASK) { + case 0: /* PSN sequence error */ + ibp->n_seq_naks++; + /* + * Back up to the responder's expected PSN. + * Note that we might get a NAK in the middle of an + * RDMA READ response which terminates the RDMA + * READ. + */ + qib_restart_rc(qp, psn, 0); + qib_schedule_send(qp); + break; + + case 1: /* Invalid Request */ + status = IB_WC_REM_INV_REQ_ERR; + ibp->n_other_naks++; + goto class_b; + + case 2: /* Remote Access Error */ + status = IB_WC_REM_ACCESS_ERR; + ibp->n_other_naks++; + goto class_b; + + case 3: /* Remote Operation Error */ + status = IB_WC_REM_OP_ERR; + ibp->n_other_naks++; +class_b: + if (qp->s_last == qp->s_acked) { + qib_send_complete(qp, wqe, status); + qib_error_qp(qp, IB_WC_WR_FLUSH_ERR); + } + break; + + default: + /* Ignore other reserved NAK error codes */ + goto reserved; + } + qp->s_retry = qp->s_retry_cnt; + qp->s_rnr_retry = qp->s_rnr_retry_cnt; + goto bail; + + default: /* 2: reserved */ +reserved: + /* Ignore reserved NAK codes. */ + goto bail; + } + +bail: + return ret; +} + +/* + * We have seen an out of sequence RDMA read middle or last packet. + * This ACKs SENDs and RDMA writes up to the first RDMA read or atomic SWQE. + */ +static void rdma_seq_err(struct qib_qp *qp, struct qib_ibport *ibp, u32 psn, + struct qib_ctxtdata *rcd) +{ + struct qib_swqe *wqe; + + /* Remove QP from retry timer */ + if (qp->s_flags & (QIB_S_TIMER | QIB_S_WAIT_RNR)) { + qp->s_flags &= ~(QIB_S_TIMER | QIB_S_WAIT_RNR); + del_timer(&qp->s_timer); + } + + wqe = get_swqe_ptr(qp, qp->s_acked); + + while (qib_cmp24(psn, wqe->lpsn) > 0) { + if (wqe->wr.opcode == IB_WR_RDMA_READ || + wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP || + wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD) + break; + wqe = do_rc_completion(qp, wqe, ibp); + } + + ibp->n_rdma_seq++; + qp->r_flags |= QIB_R_RDMAR_SEQ; + qib_restart_rc(qp, qp->s_last_psn + 1, 0); + if (list_empty(&qp->rspwait)) { + qp->r_flags |= QIB_R_RSP_SEND; + atomic_inc(&qp->refcount); + list_add_tail(&qp->rspwait, &rcd->qp_wait_list); + } +} + +/** + * qib_rc_rcv_resp - process an incoming RC response packet + * @ibp: the port this packet came in on + * @ohdr: the other headers for this packet + * @data: the packet data + * @tlen: the packet length + * @qp: the QP for this packet + * @opcode: the opcode for this packet + * @psn: the packet sequence number for this packet + * @hdrsize: the header length + * @pmtu: the path MTU + * + * This is called from qib_rc_rcv() to process an incoming RC response + * packet for the given QP. + * Called at interrupt level. + */ +static void qib_rc_rcv_resp(struct qib_ibport *ibp, + struct qib_other_headers *ohdr, + void *data, u32 tlen, + struct qib_qp *qp, + u32 opcode, + u32 psn, u32 hdrsize, u32 pmtu, + struct qib_ctxtdata *rcd) +{ + struct qib_swqe *wqe; + enum ib_wc_status status; + unsigned long flags; + int diff; + u32 pad; + u32 aeth; + u64 val; + + spin_lock_irqsave(&qp->s_lock, flags); + + /* Double check we can process this now that we hold the s_lock. */ + if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) + goto ack_done; + + /* Ignore invalid responses. */ + if (qib_cmp24(psn, qp->s_next_psn) >= 0) + goto ack_done; + + /* Ignore duplicate responses. */ + diff = qib_cmp24(psn, qp->s_last_psn); + if (unlikely(diff <= 0)) { + /* Update credits for "ghost" ACKs */ + if (diff == 0 && opcode == OP(ACKNOWLEDGE)) { + aeth = be32_to_cpu(ohdr->u.aeth); + if ((aeth >> 29) == 0) + qib_get_credit(qp, aeth); + } + goto ack_done; + } + + /* + * Skip everything other than the PSN we expect, if we are waiting + * for a reply to a restarted RDMA read or atomic op. + */ + if (qp->r_flags & QIB_R_RDMAR_SEQ) { + if (qib_cmp24(psn, qp->s_last_psn + 1) != 0) + goto ack_done; + qp->r_flags &= ~QIB_R_RDMAR_SEQ; + } + + if (unlikely(qp->s_acked == qp->s_tail)) + goto ack_done; + wqe = get_swqe_ptr(qp, qp->s_acked); + status = IB_WC_SUCCESS; + + switch (opcode) { + case OP(ACKNOWLEDGE): + case OP(ATOMIC_ACKNOWLEDGE): + case OP(RDMA_READ_RESPONSE_FIRST): + aeth = be32_to_cpu(ohdr->u.aeth); + if (opcode == OP(ATOMIC_ACKNOWLEDGE)) { + __be32 *p = ohdr->u.at.atomic_ack_eth; + + val = ((u64) be32_to_cpu(p[0]) << 32) | + be32_to_cpu(p[1]); + } else + val = 0; + if (!do_rc_ack(qp, aeth, psn, opcode, val, rcd) || + opcode != OP(RDMA_READ_RESPONSE_FIRST)) + goto ack_done; + hdrsize += 4; + wqe = get_swqe_ptr(qp, qp->s_acked); + if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ)) + goto ack_op_err; + /* + * If this is a response to a resent RDMA read, we + * have to be careful to copy the data to the right + * location. + */ + qp->s_rdma_read_len = restart_sge(&qp->s_rdma_read_sge, + wqe, psn, pmtu); + goto read_middle; + + case OP(RDMA_READ_RESPONSE_MIDDLE): + /* no AETH, no ACK */ + if (unlikely(qib_cmp24(psn, qp->s_last_psn + 1))) + goto ack_seq_err; + if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ)) + goto ack_op_err; +read_middle: + if (unlikely(tlen != (hdrsize + pmtu + 4))) + goto ack_len_err; + if (unlikely(pmtu >= qp->s_rdma_read_len)) + goto ack_len_err; + + /* + * We got a response so update the timeout. + * 4.096 usec. * (1 << qp->timeout) + */ + qp->s_flags |= QIB_S_TIMER; + mod_timer(&qp->s_timer, jiffies + + usecs_to_jiffies((4096UL * (1UL << qp->timeout)) / + 1000UL)); + if (qp->s_flags & QIB_S_WAIT_ACK) { + qp->s_flags &= ~QIB_S_WAIT_ACK; + qib_schedule_send(qp); + } + + if (opcode == OP(RDMA_READ_RESPONSE_MIDDLE)) + qp->s_retry = qp->s_retry_cnt; + + /* + * Update the RDMA receive state but do the copy w/o + * holding the locks and blocking interrupts. + */ + qp->s_rdma_read_len -= pmtu; + update_last_psn(qp, psn); + spin_unlock_irqrestore(&qp->s_lock, flags); + qib_copy_sge(&qp->s_rdma_read_sge, data, pmtu, 0); + goto bail; + + case OP(RDMA_READ_RESPONSE_ONLY): + aeth = be32_to_cpu(ohdr->u.aeth); + if (!do_rc_ack(qp, aeth, psn, opcode, 0, rcd)) + goto ack_done; + /* Get the number of bytes the message was padded by. */ + pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3; + /* + * Check that the data size is >= 0 && <= pmtu. + * Remember to account for the AETH header (4) and + * ICRC (4). + */ + if (unlikely(tlen < (hdrsize + pad + 8))) + goto ack_len_err; + /* + * If this is a response to a resent RDMA read, we + * have to be careful to copy the data to the right + * location. + */ + wqe = get_swqe_ptr(qp, qp->s_acked); + qp->s_rdma_read_len = restart_sge(&qp->s_rdma_read_sge, + wqe, psn, pmtu); + goto read_last; + + case OP(RDMA_READ_RESPONSE_LAST): + /* ACKs READ req. */ + if (unlikely(qib_cmp24(psn, qp->s_last_psn + 1))) + goto ack_seq_err; + if (unlikely(wqe->wr.opcode != IB_WR_RDMA_READ)) + goto ack_op_err; + /* Get the number of bytes the message was padded by. */ + pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3; + /* + * Check that the data size is >= 1 && <= pmtu. + * Remember to account for the AETH header (4) and + * ICRC (4). + */ + if (unlikely(tlen <= (hdrsize + pad + 8))) + goto ack_len_err; +read_last: + tlen -= hdrsize + pad + 8; + if (unlikely(tlen != qp->s_rdma_read_len)) + goto ack_len_err; + aeth = be32_to_cpu(ohdr->u.aeth); + qib_copy_sge(&qp->s_rdma_read_sge, data, tlen, 0); + WARN_ON(qp->s_rdma_read_sge.num_sge); + (void) do_rc_ack(qp, aeth, psn, + OP(RDMA_READ_RESPONSE_LAST), 0, rcd); + goto ack_done; + } + +ack_op_err: + status = IB_WC_LOC_QP_OP_ERR; + goto ack_err; + +ack_seq_err: + rdma_seq_err(qp, ibp, psn, rcd); + goto ack_done; + +ack_len_err: + status = IB_WC_LOC_LEN_ERR; +ack_err: + if (qp->s_last == qp->s_acked) { + qib_send_complete(qp, wqe, status); + qib_error_qp(qp, IB_WC_WR_FLUSH_ERR); + } +ack_done: + spin_unlock_irqrestore(&qp->s_lock, flags); +bail: + return; +} + +/** + * qib_rc_rcv_error - process an incoming duplicate or error RC packet + * @ohdr: the other headers for this packet + * @data: the packet data + * @qp: the QP for this packet + * @opcode: the opcode for this packet + * @psn: the packet sequence number for this packet + * @diff: the difference between the PSN and the expected PSN + * + * This is called from qib_rc_rcv() to process an unexpected + * incoming RC packet for the given QP. + * Called at interrupt level. + * Return 1 if no more processing is needed; otherwise return 0 to + * schedule a response to be sent. + */ +static int qib_rc_rcv_error(struct qib_other_headers *ohdr, + void *data, + struct qib_qp *qp, + u32 opcode, + u32 psn, + int diff, + struct qib_ctxtdata *rcd) +{ + struct qib_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); + struct qib_ack_entry *e; + unsigned long flags; + u8 i, prev; + int old_req; + + if (diff > 0) { + /* + * Packet sequence error. + * A NAK will ACK earlier sends and RDMA writes. + * Don't queue the NAK if we already sent one. + */ + if (!qp->r_nak_state) { + ibp->n_rc_seqnak++; + qp->r_nak_state = IB_NAK_PSN_ERROR; + /* Use the expected PSN. */ + qp->r_ack_psn = qp->r_psn; + /* + * Wait to send the sequence NAK until all packets + * in the receive queue have been processed. + * Otherwise, we end up propagating congestion. + */ + if (list_empty(&qp->rspwait)) { + qp->r_flags |= QIB_R_RSP_NAK; + atomic_inc(&qp->refcount); + list_add_tail(&qp->rspwait, &rcd->qp_wait_list); + } + } + goto done; + } + + /* + * Handle a duplicate request. Don't re-execute SEND, RDMA + * write or atomic op. Don't NAK errors, just silently drop + * the duplicate request. Note that r_sge, r_len, and + * r_rcv_len may be in use so don't modify them. + * + * We are supposed to ACK the earliest duplicate PSN but we + * can coalesce an outstanding duplicate ACK. We have to + * send the earliest so that RDMA reads can be restarted at + * the requester's expected PSN. + * + * First, find where this duplicate PSN falls within the + * ACKs previously sent. + * old_req is true if there is an older response that is scheduled + * to be sent before sending this one. + */ + e = NULL; + old_req = 1; + ibp->n_rc_dupreq++; + + spin_lock_irqsave(&qp->s_lock, flags); + /* Double check we can process this now that we hold the s_lock. */ + if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) + goto unlock_done; + + for (i = qp->r_head_ack_queue; ; i = prev) { + if (i == qp->s_tail_ack_queue) + old_req = 0; + if (i) + prev = i - 1; + else + prev = QIB_MAX_RDMA_ATOMIC; + if (prev == qp->r_head_ack_queue) { + e = NULL; + break; + } + e = &qp->s_ack_queue[prev]; + if (!e->opcode) { + e = NULL; + break; + } + if (qib_cmp24(psn, e->psn) >= 0) { + if (prev == qp->s_tail_ack_queue && + qib_cmp24(psn, e->lpsn) <= 0) + old_req = 0; + break; + } + } + switch (opcode) { + case OP(RDMA_READ_REQUEST): { + struct ib_reth *reth; + u32 offset; + u32 len; + + /* + * If we didn't find the RDMA read request in the ack queue, + * we can ignore this request. + */ + if (!e || e->opcode != OP(RDMA_READ_REQUEST)) + goto unlock_done; + /* RETH comes after BTH */ + reth = &ohdr->u.rc.reth; + /* + * Address range must be a subset of the original + * request and start on pmtu boundaries. + * We reuse the old ack_queue slot since the requester + * should not back up and request an earlier PSN for the + * same request. + */ + offset = ((psn - e->psn) & QIB_PSN_MASK) * + ib_mtu_enum_to_int(qp->path_mtu); + len = be32_to_cpu(reth->length); + if (unlikely(offset + len != e->rdma_sge.sge_length)) + goto unlock_done; + if (e->rdma_sge.mr) { + atomic_dec(&e->rdma_sge.mr->refcount); + e->rdma_sge.mr = NULL; + } + if (len != 0) { + u32 rkey = be32_to_cpu(reth->rkey); + u64 vaddr = be64_to_cpu(reth->vaddr); + int ok; + + ok = qib_rkey_ok(qp, &e->rdma_sge, len, vaddr, rkey, + IB_ACCESS_REMOTE_READ); + if (unlikely(!ok)) + goto unlock_done; + } else { + e->rdma_sge.vaddr = NULL; + e->rdma_sge.length = 0; + e->rdma_sge.sge_length = 0; + } + e->psn = psn; + if (old_req) + goto unlock_done; + qp->s_tail_ack_queue = prev; + break; + } + + case OP(COMPARE_SWAP): + case OP(FETCH_ADD): { + /* + * If we didn't find the atomic request in the ack queue + * or the send tasklet is already backed up to send an + * earlier entry, we can ignore this request. + */ + if (!e || e->opcode != (u8) opcode || old_req) + goto unlock_done; + qp->s_tail_ack_queue = prev; + break; + } + + default: + /* + * Ignore this operation if it doesn't request an ACK + * or an earlier RDMA read or atomic is going to be resent. + */ + if (!(psn & IB_BTH_REQ_ACK) || old_req) + goto unlock_done; + /* + * Resend the most recent ACK if this request is + * after all the previous RDMA reads and atomics. + */ + if (i == qp->r_head_ack_queue) { + spin_unlock_irqrestore(&qp->s_lock, flags); + qp->r_nak_state = 0; + qp->r_ack_psn = qp->r_psn - 1; + goto send_ack; + } + /* + * Try to send a simple ACK to work around a Mellanox bug + * which doesn't accept a RDMA read response or atomic + * response as an ACK for earlier SENDs or RDMA writes. + */ + if (!(qp->s_flags & QIB_S_RESP_PENDING)) { + spin_unlock_irqrestore(&qp->s_lock, flags); + qp->r_nak_state = 0; + qp->r_ack_psn = qp->s_ack_queue[i].psn - 1; + goto send_ack; + } + /* + * Resend the RDMA read or atomic op which + * ACKs this duplicate request. + */ + qp->s_tail_ack_queue = i; + break; + } + qp->s_ack_state = OP(ACKNOWLEDGE); + qp->s_flags |= QIB_S_RESP_PENDING; + qp->r_nak_state = 0; + qib_schedule_send(qp); + +unlock_done: + spin_unlock_irqrestore(&qp->s_lock, flags); +done: + return 1; + +send_ack: + return 0; +} + +void qib_rc_error(struct qib_qp *qp, enum ib_wc_status err) +{ + unsigned long flags; + int lastwqe; + + spin_lock_irqsave(&qp->s_lock, flags); + lastwqe = qib_error_qp(qp, err); + spin_unlock_irqrestore(&qp->s_lock, flags); + + if (lastwqe) { + struct ib_event ev; + + ev.device = qp->ibqp.device; + ev.element.qp = &qp->ibqp; + ev.event = IB_EVENT_QP_LAST_WQE_REACHED; + qp->ibqp.event_handler(&ev, qp->ibqp.qp_context); + } +} + +static inline void qib_update_ack_queue(struct qib_qp *qp, unsigned n) +{ + unsigned next; + + next = n + 1; + if (next > QIB_MAX_RDMA_ATOMIC) + next = 0; + qp->s_tail_ack_queue = next; + qp->s_ack_state = OP(ACKNOWLEDGE); +} + +/** + * qib_rc_rcv - process an incoming RC packet + * @rcd: the context pointer + * @hdr: the header of this packet + * @has_grh: true if the header has a GRH + * @data: the packet data + * @tlen: the packet length + * @qp: the QP for this packet + * + * This is called from qib_qp_rcv() to process an incoming RC packet + * for the given QP. + * Called at interrupt level. + */ +void qib_rc_rcv(struct qib_ctxtdata *rcd, struct qib_ib_header *hdr, + int has_grh, void *data, u32 tlen, struct qib_qp *qp) +{ + struct qib_ibport *ibp = &rcd->ppd->ibport_data; + struct qib_other_headers *ohdr; + u32 opcode; + u32 hdrsize; + u32 psn; + u32 pad; + struct ib_wc wc; + u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu); + int diff; + struct ib_reth *reth; + unsigned long flags; + int ret; + + /* Check for GRH */ + if (!has_grh) { + ohdr = &hdr->u.oth; + hdrsize = 8 + 12; /* LRH + BTH */ + } else { + ohdr = &hdr->u.l.oth; + hdrsize = 8 + 40 + 12; /* LRH + GRH + BTH */ + } + + opcode = be32_to_cpu(ohdr->bth[0]); + spin_lock_irqsave(&qp->s_lock, flags); + if (qib_ruc_check_hdr(ibp, hdr, has_grh, qp, opcode)) + goto sunlock; + spin_unlock_irqrestore(&qp->s_lock, flags); + + psn = be32_to_cpu(ohdr->bth[2]); + opcode >>= 24; + + /* Prevent simultaneous processing after APM on different CPUs */ + spin_lock(&qp->r_lock); + + /* + * Process responses (ACKs) before anything else. Note that the + * packet sequence number will be for something in the send work + * queue rather than the expected receive packet sequence number. + * In other words, this QP is the requester. + */ + if (opcode >= OP(RDMA_READ_RESPONSE_FIRST) && + opcode <= OP(ATOMIC_ACKNOWLEDGE)) { + qib_rc_rcv_resp(ibp, ohdr, data, tlen, qp, opcode, psn, + hdrsize, pmtu, rcd); + goto runlock; + } + + /* Compute 24 bits worth of difference. */ + diff = qib_cmp24(psn, qp->r_psn); + if (unlikely(diff)) { + if (qib_rc_rcv_error(ohdr, data, qp, opcode, psn, diff, rcd)) + goto runlock; + goto send_ack; + } + + /* Check for opcode sequence errors. */ + switch (qp->r_state) { + case OP(SEND_FIRST): + case OP(SEND_MIDDLE): + if (opcode == OP(SEND_MIDDLE) || + opcode == OP(SEND_LAST) || + opcode == OP(SEND_LAST_WITH_IMMEDIATE)) + break; + goto nack_inv; + + case OP(RDMA_WRITE_FIRST): + case OP(RDMA_WRITE_MIDDLE): + if (opcode == OP(RDMA_WRITE_MIDDLE) || + opcode == OP(RDMA_WRITE_LAST) || + opcode == OP(RDMA_WRITE_LAST_WITH_IMMEDIATE)) + break; + goto nack_inv; + + default: + if (opcode == OP(SEND_MIDDLE) || + opcode == OP(SEND_LAST) || + opcode == OP(SEND_LAST_WITH_IMMEDIATE) || + opcode == OP(RDMA_WRITE_MIDDLE) || + opcode == OP(RDMA_WRITE_LAST) || + opcode == OP(RDMA_WRITE_LAST_WITH_IMMEDIATE)) + goto nack_inv; + /* + * Note that it is up to the requester to not send a new + * RDMA read or atomic operation before receiving an ACK + * for the previous operation. + */ + break; + } + + memset(&wc, 0, sizeof wc); + + if (qp->state == IB_QPS_RTR && !(qp->r_flags & QIB_R_COMM_EST)) { + qp->r_flags |= QIB_R_COMM_EST; + if (qp->ibqp.event_handler) { + struct ib_event ev; + + ev.device = qp->ibqp.device; + ev.element.qp = &qp->ibqp; + ev.event = IB_EVENT_COMM_EST; + qp->ibqp.event_handler(&ev, qp->ibqp.qp_context); + } + } + + /* OK, process the packet. */ + switch (opcode) { + case OP(SEND_FIRST): + ret = qib_get_rwqe(qp, 0); + if (ret < 0) + goto nack_op_err; + if (!ret) + goto rnr_nak; + qp->r_rcv_len = 0; + /* FALLTHROUGH */ + case OP(SEND_MIDDLE): + case OP(RDMA_WRITE_MIDDLE): +send_middle: + /* Check for invalid length PMTU or posted rwqe len. */ + if (unlikely(tlen != (hdrsize + pmtu + 4))) + goto nack_inv; + qp->r_rcv_len += pmtu; + if (unlikely(qp->r_rcv_len > qp->r_len)) + goto nack_inv; + qib_copy_sge(&qp->r_sge, data, pmtu, 1); + break; + + case OP(RDMA_WRITE_LAST_WITH_IMMEDIATE): + /* consume RWQE */ + ret = qib_get_rwqe(qp, 1); + if (ret < 0) + goto nack_op_err; + if (!ret) + goto rnr_nak; + goto send_last_imm; + + case OP(SEND_ONLY): + case OP(SEND_ONLY_WITH_IMMEDIATE): + ret = qib_get_rwqe(qp, 0); + if (ret < 0) + goto nack_op_err; + if (!ret) + goto rnr_nak; + qp->r_rcv_len = 0; + if (opcode == OP(SEND_ONLY)) + goto send_last; + /* FALLTHROUGH */ + case OP(SEND_LAST_WITH_IMMEDIATE): +send_last_imm: + wc.ex.imm_data = ohdr->u.imm_data; + hdrsize += 4; + wc.wc_flags = IB_WC_WITH_IMM; + /* FALLTHROUGH */ + case OP(SEND_LAST): + case OP(RDMA_WRITE_LAST): +send_last: + /* Get the number of bytes the message was padded by. */ + pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3; + /* Check for invalid length. */ + /* XXX LAST len should be >= 1 */ + if (unlikely(tlen < (hdrsize + pad + 4))) + goto nack_inv; + /* Don't count the CRC. */ + tlen -= (hdrsize + pad + 4); + wc.byte_len = tlen + qp->r_rcv_len; + if (unlikely(wc.byte_len > qp->r_len)) + goto nack_inv; + qib_copy_sge(&qp->r_sge, data, tlen, 1); + while (qp->r_sge.num_sge) { + atomic_dec(&qp->r_sge.sge.mr->refcount); + if (--qp->r_sge.num_sge) + qp->r_sge.sge = *qp->r_sge.sg_list++; + } + qp->r_msn++; + if (!test_and_clear_bit(QIB_R_WRID_VALID, &qp->r_aflags)) + break; + wc.wr_id = qp->r_wr_id; + wc.status = IB_WC_SUCCESS; + if (opcode == OP(RDMA_WRITE_LAST_WITH_IMMEDIATE) || + opcode == OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE)) + wc.opcode = IB_WC_RECV_RDMA_WITH_IMM; + else + wc.opcode = IB_WC_RECV; + wc.qp = &qp->ibqp; + wc.src_qp = qp->remote_qpn; + wc.slid = qp->remote_ah_attr.dlid; + wc.sl = qp->remote_ah_attr.sl; + /* Signal completion event if the solicited bit is set. */ + qib_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, + (ohdr->bth[0] & + cpu_to_be32(IB_BTH_SOLICITED)) != 0); + break; + + case OP(RDMA_WRITE_FIRST): + case OP(RDMA_WRITE_ONLY): + case OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE): + if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_WRITE))) + goto nack_inv; + /* consume RWQE */ + reth = &ohdr->u.rc.reth; + hdrsize += sizeof(*reth); + qp->r_len = be32_to_cpu(reth->length); + qp->r_rcv_len = 0; + qp->r_sge.sg_list = NULL; + if (qp->r_len != 0) { + u32 rkey = be32_to_cpu(reth->rkey); + u64 vaddr = be64_to_cpu(reth->vaddr); + int ok; + + /* Check rkey & NAK */ + ok = qib_rkey_ok(qp, &qp->r_sge.sge, qp->r_len, vaddr, + rkey, IB_ACCESS_REMOTE_WRITE); + if (unlikely(!ok)) + goto nack_acc; + qp->r_sge.num_sge = 1; + } else { + qp->r_sge.num_sge = 0; + qp->r_sge.sge.mr = NULL; + qp->r_sge.sge.vaddr = NULL; + qp->r_sge.sge.length = 0; + qp->r_sge.sge.sge_length = 0; + } + if (opcode == OP(RDMA_WRITE_FIRST)) + goto send_middle; + else if (opcode == OP(RDMA_WRITE_ONLY)) + goto send_last; + ret = qib_get_rwqe(qp, 1); + if (ret < 0) + goto nack_op_err; + if (!ret) + goto rnr_nak; + goto send_last_imm; + + case OP(RDMA_READ_REQUEST): { + struct qib_ack_entry *e; + u32 len; + u8 next; + + if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_READ))) + goto nack_inv; + next = qp->r_head_ack_queue + 1; + /* s_ack_queue is size QIB_MAX_RDMA_ATOMIC+1 so use > not >= */ + if (next > QIB_MAX_RDMA_ATOMIC) + next = 0; + spin_lock_irqsave(&qp->s_lock, flags); + /* Double check we can process this while holding the s_lock. */ + if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) + goto srunlock; + if (unlikely(next == qp->s_tail_ack_queue)) { + if (!qp->s_ack_queue[next].sent) + goto nack_inv_unlck; + qib_update_ack_queue(qp, next); + } + e = &qp->s_ack_queue[qp->r_head_ack_queue]; + if (e->opcode == OP(RDMA_READ_REQUEST) && e->rdma_sge.mr) { + atomic_dec(&e->rdma_sge.mr->refcount); + e->rdma_sge.mr = NULL; + } + reth = &ohdr->u.rc.reth; + len = be32_to_cpu(reth->length); + if (len) { + u32 rkey = be32_to_cpu(reth->rkey); + u64 vaddr = be64_to_cpu(reth->vaddr); + int ok; + + /* Check rkey & NAK */ + ok = qib_rkey_ok(qp, &e->rdma_sge, len, vaddr, + rkey, IB_ACCESS_REMOTE_READ); + if (unlikely(!ok)) + goto nack_acc_unlck; + /* + * Update the next expected PSN. We add 1 later + * below, so only add the remainder here. + */ + if (len > pmtu) + qp->r_psn += (len - 1) / pmtu; + } else { + e->rdma_sge.mr = NULL; + e->rdma_sge.vaddr = NULL; + e->rdma_sge.length = 0; + e->rdma_sge.sge_length = 0; + } + e->opcode = opcode; + e->sent = 0; + e->psn = psn; + e->lpsn = qp->r_psn; + /* + * We need to increment the MSN here instead of when we + * finish sending the result since a duplicate request would + * increment it more than once. + */ + qp->r_msn++; + qp->r_psn++; + qp->r_state = opcode; + qp->r_nak_state = 0; + qp->r_head_ack_queue = next; + + /* Schedule the send tasklet. */ + qp->s_flags |= QIB_S_RESP_PENDING; + qib_schedule_send(qp); + + goto srunlock; + } + + case OP(COMPARE_SWAP): + case OP(FETCH_ADD): { + struct ib_atomic_eth *ateth; + struct qib_ack_entry *e; + u64 vaddr; + atomic64_t *maddr; + u64 sdata; + u32 rkey; + u8 next; + + if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_ATOMIC))) + goto nack_inv; + next = qp->r_head_ack_queue + 1; + if (next > QIB_MAX_RDMA_ATOMIC) + next = 0; + spin_lock_irqsave(&qp->s_lock, flags); + /* Double check we can process this while holding the s_lock. */ + if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) + goto srunlock; + if (unlikely(next == qp->s_tail_ack_queue)) { + if (!qp->s_ack_queue[next].sent) + goto nack_inv_unlck; + qib_update_ack_queue(qp, next); + } + e = &qp->s_ack_queue[qp->r_head_ack_queue]; + if (e->opcode == OP(RDMA_READ_REQUEST) && e->rdma_sge.mr) { + atomic_dec(&e->rdma_sge.mr->refcount); + e->rdma_sge.mr = NULL; + } + ateth = &ohdr->u.atomic_eth; + vaddr = ((u64) be32_to_cpu(ateth->vaddr[0]) << 32) | + be32_to_cpu(ateth->vaddr[1]); + if (unlikely(vaddr & (sizeof(u64) - 1))) + goto nack_inv_unlck; + rkey = be32_to_cpu(ateth->rkey); + /* Check rkey & NAK */ + if (unlikely(!qib_rkey_ok(qp, &qp->r_sge.sge, sizeof(u64), + vaddr, rkey, + IB_ACCESS_REMOTE_ATOMIC))) + goto nack_acc_unlck; + /* Perform atomic OP and save result. */ + maddr = (atomic64_t *) qp->r_sge.sge.vaddr; + sdata = be64_to_cpu(ateth->swap_data); + e->atomic_data = (opcode == OP(FETCH_ADD)) ? + (u64) atomic64_add_return(sdata, maddr) - sdata : + (u64) cmpxchg((u64 *) qp->r_sge.sge.vaddr, + be64_to_cpu(ateth->compare_data), + sdata); + atomic_dec(&qp->r_sge.sge.mr->refcount); + qp->r_sge.num_sge = 0; + e->opcode = opcode; + e->sent = 0; + e->psn = psn; + e->lpsn = psn; + qp->r_msn++; + qp->r_psn++; + qp->r_state = opcode; + qp->r_nak_state = 0; + qp->r_head_ack_queue = next; + + /* Schedule the send tasklet. */ + qp->s_flags |= QIB_S_RESP_PENDING; + qib_schedule_send(qp); + + goto srunlock; + } + + default: + /* NAK unknown opcodes. */ + goto nack_inv; + } + qp->r_psn++; + qp->r_state = opcode; + qp->r_ack_psn = psn; + qp->r_nak_state = 0; + /* Send an ACK if requested or required. */ + if (psn & (1 << 31)) + goto send_ack; + goto runlock; + +rnr_nak: + qp->r_nak_state = IB_RNR_NAK | qp->r_min_rnr_timer; + qp->r_ack_psn = qp->r_psn; + /* Queue RNR NAK for later */ + if (list_empty(&qp->rspwait)) { + qp->r_flags |= QIB_R_RSP_NAK; + atomic_inc(&qp->refcount); + list_add_tail(&qp->rspwait, &rcd->qp_wait_list); + } + goto runlock; + +nack_op_err: + qib_rc_error(qp, IB_WC_LOC_QP_OP_ERR); + qp->r_nak_state = IB_NAK_REMOTE_OPERATIONAL_ERROR; + qp->r_ack_psn = qp->r_psn; + /* Queue NAK for later */ + if (list_empty(&qp->rspwait)) { + qp->r_flags |= QIB_R_RSP_NAK; + atomic_inc(&qp->refcount); + list_add_tail(&qp->rspwait, &rcd->qp_wait_list); + } + goto runlock; + +nack_inv_unlck: + spin_unlock_irqrestore(&qp->s_lock, flags); +nack_inv: + qib_rc_error(qp, IB_WC_LOC_QP_OP_ERR); + qp->r_nak_state = IB_NAK_INVALID_REQUEST; + qp->r_ack_psn = qp->r_psn; + /* Queue NAK for later */ + if (list_empty(&qp->rspwait)) { + qp->r_flags |= QIB_R_RSP_NAK; + atomic_inc(&qp->refcount); + list_add_tail(&qp->rspwait, &rcd->qp_wait_list); + } + goto runlock; + +nack_acc_unlck: + spin_unlock_irqrestore(&qp->s_lock, flags); +nack_acc: + qib_rc_error(qp, IB_WC_LOC_PROT_ERR); + qp->r_nak_state = IB_NAK_REMOTE_ACCESS_ERROR; + qp->r_ack_psn = qp->r_psn; +send_ack: + qib_send_rc_ack(qp); +runlock: + spin_unlock(&qp->r_lock); + return; + +srunlock: + spin_unlock_irqrestore(&qp->s_lock, flags); + spin_unlock(&qp->r_lock); + return; + +sunlock: + spin_unlock_irqrestore(&qp->s_lock, flags); +} diff --git a/drivers/infiniband/hw/qib/qib_ruc.c b/drivers/infiniband/hw/qib/qib_ruc.c new file mode 100644 index 000000000000..eb78d9367f06 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_ruc.c @@ -0,0 +1,817 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. + * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include + +#include "qib.h" +#include "qib_mad.h" + +/* + * Convert the AETH RNR timeout code into the number of microseconds. + */ +const u32 ib_qib_rnr_table[32] = { + 655360, /* 00: 655.36 */ + 10, /* 01: .01 */ + 20, /* 02 .02 */ + 30, /* 03: .03 */ + 40, /* 04: .04 */ + 60, /* 05: .06 */ + 80, /* 06: .08 */ + 120, /* 07: .12 */ + 160, /* 08: .16 */ + 240, /* 09: .24 */ + 320, /* 0A: .32 */ + 480, /* 0B: .48 */ + 640, /* 0C: .64 */ + 960, /* 0D: .96 */ + 1280, /* 0E: 1.28 */ + 1920, /* 0F: 1.92 */ + 2560, /* 10: 2.56 */ + 3840, /* 11: 3.84 */ + 5120, /* 12: 5.12 */ + 7680, /* 13: 7.68 */ + 10240, /* 14: 10.24 */ + 15360, /* 15: 15.36 */ + 20480, /* 16: 20.48 */ + 30720, /* 17: 30.72 */ + 40960, /* 18: 40.96 */ + 61440, /* 19: 61.44 */ + 81920, /* 1A: 81.92 */ + 122880, /* 1B: 122.88 */ + 163840, /* 1C: 163.84 */ + 245760, /* 1D: 245.76 */ + 327680, /* 1E: 327.68 */ + 491520 /* 1F: 491.52 */ +}; + +/* + * Validate a RWQE and fill in the SGE state. + * Return 1 if OK. + */ +static int qib_init_sge(struct qib_qp *qp, struct qib_rwqe *wqe) +{ + int i, j, ret; + struct ib_wc wc; + struct qib_lkey_table *rkt; + struct qib_pd *pd; + struct qib_sge_state *ss; + + rkt = &to_idev(qp->ibqp.device)->lk_table; + pd = to_ipd(qp->ibqp.srq ? qp->ibqp.srq->pd : qp->ibqp.pd); + ss = &qp->r_sge; + ss->sg_list = qp->r_sg_list; + qp->r_len = 0; + for (i = j = 0; i < wqe->num_sge; i++) { + if (wqe->sg_list[i].length == 0) + continue; + /* Check LKEY */ + if (!qib_lkey_ok(rkt, pd, j ? &ss->sg_list[j - 1] : &ss->sge, + &wqe->sg_list[i], IB_ACCESS_LOCAL_WRITE)) + goto bad_lkey; + qp->r_len += wqe->sg_list[i].length; + j++; + } + ss->num_sge = j; + ss->total_len = qp->r_len; + ret = 1; + goto bail; + +bad_lkey: + while (j) { + struct qib_sge *sge = --j ? &ss->sg_list[j - 1] : &ss->sge; + + atomic_dec(&sge->mr->refcount); + } + ss->num_sge = 0; + memset(&wc, 0, sizeof(wc)); + wc.wr_id = wqe->wr_id; + wc.status = IB_WC_LOC_PROT_ERR; + wc.opcode = IB_WC_RECV; + wc.qp = &qp->ibqp; + /* Signal solicited completion event. */ + qib_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1); + ret = 0; +bail: + return ret; +} + +/** + * qib_get_rwqe - copy the next RWQE into the QP's RWQE + * @qp: the QP + * @wr_id_only: update qp->r_wr_id only, not qp->r_sge + * + * Return -1 if there is a local error, 0 if no RWQE is available, + * otherwise return 1. + * + * Can be called from interrupt level. + */ +int qib_get_rwqe(struct qib_qp *qp, int wr_id_only) +{ + unsigned long flags; + struct qib_rq *rq; + struct qib_rwq *wq; + struct qib_srq *srq; + struct qib_rwqe *wqe; + void (*handler)(struct ib_event *, void *); + u32 tail; + int ret; + + if (qp->ibqp.srq) { + srq = to_isrq(qp->ibqp.srq); + handler = srq->ibsrq.event_handler; + rq = &srq->rq; + } else { + srq = NULL; + handler = NULL; + rq = &qp->r_rq; + } + + spin_lock_irqsave(&rq->lock, flags); + if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) { + ret = 0; + goto unlock; + } + + wq = rq->wq; + tail = wq->tail; + /* Validate tail before using it since it is user writable. */ + if (tail >= rq->size) + tail = 0; + if (unlikely(tail == wq->head)) { + ret = 0; + goto unlock; + } + /* Make sure entry is read after head index is read. */ + smp_rmb(); + wqe = get_rwqe_ptr(rq, tail); + /* + * Even though we update the tail index in memory, the verbs + * consumer is not supposed to post more entries until a + * completion is generated. + */ + if (++tail >= rq->size) + tail = 0; + wq->tail = tail; + if (!wr_id_only && !qib_init_sge(qp, wqe)) { + ret = -1; + goto unlock; + } + qp->r_wr_id = wqe->wr_id; + + ret = 1; + set_bit(QIB_R_WRID_VALID, &qp->r_aflags); + if (handler) { + u32 n; + + /* + * Validate head pointer value and compute + * the number of remaining WQEs. + */ + n = wq->head; + if (n >= rq->size) + n = 0; + if (n < tail) + n += rq->size - tail; + else + n -= tail; + if (n < srq->limit) { + struct ib_event ev; + + srq->limit = 0; + spin_unlock_irqrestore(&rq->lock, flags); + ev.device = qp->ibqp.device; + ev.element.srq = qp->ibqp.srq; + ev.event = IB_EVENT_SRQ_LIMIT_REACHED; + handler(&ev, srq->ibsrq.srq_context); + goto bail; + } + } +unlock: + spin_unlock_irqrestore(&rq->lock, flags); +bail: + return ret; +} + +/* + * Switch to alternate path. + * The QP s_lock should be held and interrupts disabled. + */ +void qib_migrate_qp(struct qib_qp *qp) +{ + struct ib_event ev; + + qp->s_mig_state = IB_MIG_MIGRATED; + qp->remote_ah_attr = qp->alt_ah_attr; + qp->port_num = qp->alt_ah_attr.port_num; + qp->s_pkey_index = qp->s_alt_pkey_index; + + ev.device = qp->ibqp.device; + ev.element.qp = &qp->ibqp; + ev.event = IB_EVENT_PATH_MIG; + qp->ibqp.event_handler(&ev, qp->ibqp.qp_context); +} + +static __be64 get_sguid(struct qib_ibport *ibp, unsigned index) +{ + if (!index) { + struct qib_pportdata *ppd = ppd_from_ibp(ibp); + + return ppd->guid; + } else + return ibp->guids[index - 1]; +} + +static int gid_ok(union ib_gid *gid, __be64 gid_prefix, __be64 id) +{ + return (gid->global.interface_id == id && + (gid->global.subnet_prefix == gid_prefix || + gid->global.subnet_prefix == IB_DEFAULT_GID_PREFIX)); +} + +/* + * + * This should be called with the QP s_lock held. + */ +int qib_ruc_check_hdr(struct qib_ibport *ibp, struct qib_ib_header *hdr, + int has_grh, struct qib_qp *qp, u32 bth0) +{ + __be64 guid; + + if (qp->s_mig_state == IB_MIG_ARMED && (bth0 & IB_BTH_MIG_REQ)) { + if (!has_grh) { + if (qp->alt_ah_attr.ah_flags & IB_AH_GRH) + goto err; + } else { + if (!(qp->alt_ah_attr.ah_flags & IB_AH_GRH)) + goto err; + guid = get_sguid(ibp, qp->alt_ah_attr.grh.sgid_index); + if (!gid_ok(&hdr->u.l.grh.dgid, ibp->gid_prefix, guid)) + goto err; + if (!gid_ok(&hdr->u.l.grh.sgid, + qp->alt_ah_attr.grh.dgid.global.subnet_prefix, + qp->alt_ah_attr.grh.dgid.global.interface_id)) + goto err; + } + if (!qib_pkey_ok((u16)bth0, + qib_get_pkey(ibp, qp->s_alt_pkey_index))) { + qib_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_PKEY, + (u16)bth0, + (be16_to_cpu(hdr->lrh[0]) >> 4) & 0xF, + 0, qp->ibqp.qp_num, + hdr->lrh[3], hdr->lrh[1]); + goto err; + } + /* Validate the SLID. See Ch. 9.6.1.5 and 17.2.8 */ + if (be16_to_cpu(hdr->lrh[3]) != qp->alt_ah_attr.dlid || + ppd_from_ibp(ibp)->port != qp->alt_ah_attr.port_num) + goto err; + qib_migrate_qp(qp); + } else { + if (!has_grh) { + if (qp->remote_ah_attr.ah_flags & IB_AH_GRH) + goto err; + } else { + if (!(qp->remote_ah_attr.ah_flags & IB_AH_GRH)) + goto err; + guid = get_sguid(ibp, + qp->remote_ah_attr.grh.sgid_index); + if (!gid_ok(&hdr->u.l.grh.dgid, ibp->gid_prefix, guid)) + goto err; + if (!gid_ok(&hdr->u.l.grh.sgid, + qp->remote_ah_attr.grh.dgid.global.subnet_prefix, + qp->remote_ah_attr.grh.dgid.global.interface_id)) + goto err; + } + if (!qib_pkey_ok((u16)bth0, + qib_get_pkey(ibp, qp->s_pkey_index))) { + qib_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_PKEY, + (u16)bth0, + (be16_to_cpu(hdr->lrh[0]) >> 4) & 0xF, + 0, qp->ibqp.qp_num, + hdr->lrh[3], hdr->lrh[1]); + goto err; + } + /* Validate the SLID. See Ch. 9.6.1.5 */ + if (be16_to_cpu(hdr->lrh[3]) != qp->remote_ah_attr.dlid || + ppd_from_ibp(ibp)->port != qp->port_num) + goto err; + if (qp->s_mig_state == IB_MIG_REARM && + !(bth0 & IB_BTH_MIG_REQ)) + qp->s_mig_state = IB_MIG_ARMED; + } + + return 0; + +err: + return 1; +} + +/** + * qib_ruc_loopback - handle UC and RC lookback requests + * @sqp: the sending QP + * + * This is called from qib_do_send() to + * forward a WQE addressed to the same HCA. + * Note that although we are single threaded due to the tasklet, we still + * have to protect against post_send(). We don't have to worry about + * receive interrupts since this is a connected protocol and all packets + * will pass through here. + */ +static void qib_ruc_loopback(struct qib_qp *sqp) +{ + struct qib_ibport *ibp = to_iport(sqp->ibqp.device, sqp->port_num); + struct qib_qp *qp; + struct qib_swqe *wqe; + struct qib_sge *sge; + unsigned long flags; + struct ib_wc wc; + u64 sdata; + atomic64_t *maddr; + enum ib_wc_status send_status; + int release; + int ret; + + /* + * Note that we check the responder QP state after + * checking the requester's state. + */ + qp = qib_lookup_qpn(ibp, sqp->remote_qpn); + + spin_lock_irqsave(&sqp->s_lock, flags); + + /* Return if we are already busy processing a work request. */ + if ((sqp->s_flags & (QIB_S_BUSY | QIB_S_ANY_WAIT)) || + !(ib_qib_state_ops[sqp->state] & QIB_PROCESS_OR_FLUSH_SEND)) + goto unlock; + + sqp->s_flags |= QIB_S_BUSY; + +again: + if (sqp->s_last == sqp->s_head) + goto clr_busy; + wqe = get_swqe_ptr(sqp, sqp->s_last); + + /* Return if it is not OK to start a new work reqeust. */ + if (!(ib_qib_state_ops[sqp->state] & QIB_PROCESS_NEXT_SEND_OK)) { + if (!(ib_qib_state_ops[sqp->state] & QIB_FLUSH_SEND)) + goto clr_busy; + /* We are in the error state, flush the work request. */ + send_status = IB_WC_WR_FLUSH_ERR; + goto flush_send; + } + + /* + * We can rely on the entry not changing without the s_lock + * being held until we update s_last. + * We increment s_cur to indicate s_last is in progress. + */ + if (sqp->s_last == sqp->s_cur) { + if (++sqp->s_cur >= sqp->s_size) + sqp->s_cur = 0; + } + spin_unlock_irqrestore(&sqp->s_lock, flags); + + if (!qp || !(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK) || + qp->ibqp.qp_type != sqp->ibqp.qp_type) { + ibp->n_pkt_drops++; + /* + * For RC, the requester would timeout and retry so + * shortcut the timeouts and just signal too many retries. + */ + if (sqp->ibqp.qp_type == IB_QPT_RC) + send_status = IB_WC_RETRY_EXC_ERR; + else + send_status = IB_WC_SUCCESS; + goto serr; + } + + memset(&wc, 0, sizeof wc); + send_status = IB_WC_SUCCESS; + + release = 1; + sqp->s_sge.sge = wqe->sg_list[0]; + sqp->s_sge.sg_list = wqe->sg_list + 1; + sqp->s_sge.num_sge = wqe->wr.num_sge; + sqp->s_len = wqe->length; + switch (wqe->wr.opcode) { + case IB_WR_SEND_WITH_IMM: + wc.wc_flags = IB_WC_WITH_IMM; + wc.ex.imm_data = wqe->wr.ex.imm_data; + /* FALLTHROUGH */ + case IB_WR_SEND: + ret = qib_get_rwqe(qp, 0); + if (ret < 0) + goto op_err; + if (!ret) + goto rnr_nak; + break; + + case IB_WR_RDMA_WRITE_WITH_IMM: + if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_WRITE))) + goto inv_err; + wc.wc_flags = IB_WC_WITH_IMM; + wc.ex.imm_data = wqe->wr.ex.imm_data; + ret = qib_get_rwqe(qp, 1); + if (ret < 0) + goto op_err; + if (!ret) + goto rnr_nak; + /* FALLTHROUGH */ + case IB_WR_RDMA_WRITE: + if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_WRITE))) + goto inv_err; + if (wqe->length == 0) + break; + if (unlikely(!qib_rkey_ok(qp, &qp->r_sge.sge, wqe->length, + wqe->wr.wr.rdma.remote_addr, + wqe->wr.wr.rdma.rkey, + IB_ACCESS_REMOTE_WRITE))) + goto acc_err; + qp->r_sge.sg_list = NULL; + qp->r_sge.num_sge = 1; + qp->r_sge.total_len = wqe->length; + break; + + case IB_WR_RDMA_READ: + if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_READ))) + goto inv_err; + if (unlikely(!qib_rkey_ok(qp, &sqp->s_sge.sge, wqe->length, + wqe->wr.wr.rdma.remote_addr, + wqe->wr.wr.rdma.rkey, + IB_ACCESS_REMOTE_READ))) + goto acc_err; + release = 0; + sqp->s_sge.sg_list = NULL; + sqp->s_sge.num_sge = 1; + qp->r_sge.sge = wqe->sg_list[0]; + qp->r_sge.sg_list = wqe->sg_list + 1; + qp->r_sge.num_sge = wqe->wr.num_sge; + qp->r_sge.total_len = wqe->length; + break; + + case IB_WR_ATOMIC_CMP_AND_SWP: + case IB_WR_ATOMIC_FETCH_AND_ADD: + if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_ATOMIC))) + goto inv_err; + if (unlikely(!qib_rkey_ok(qp, &qp->r_sge.sge, sizeof(u64), + wqe->wr.wr.atomic.remote_addr, + wqe->wr.wr.atomic.rkey, + IB_ACCESS_REMOTE_ATOMIC))) + goto acc_err; + /* Perform atomic OP and save result. */ + maddr = (atomic64_t *) qp->r_sge.sge.vaddr; + sdata = wqe->wr.wr.atomic.compare_add; + *(u64 *) sqp->s_sge.sge.vaddr = + (wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD) ? + (u64) atomic64_add_return(sdata, maddr) - sdata : + (u64) cmpxchg((u64 *) qp->r_sge.sge.vaddr, + sdata, wqe->wr.wr.atomic.swap); + atomic_dec(&qp->r_sge.sge.mr->refcount); + qp->r_sge.num_sge = 0; + goto send_comp; + + default: + send_status = IB_WC_LOC_QP_OP_ERR; + goto serr; + } + + sge = &sqp->s_sge.sge; + while (sqp->s_len) { + u32 len = sqp->s_len; + + if (len > sge->length) + len = sge->length; + if (len > sge->sge_length) + len = sge->sge_length; + BUG_ON(len == 0); + qib_copy_sge(&qp->r_sge, sge->vaddr, len, release); + sge->vaddr += len; + sge->length -= len; + sge->sge_length -= len; + if (sge->sge_length == 0) { + if (!release) + atomic_dec(&sge->mr->refcount); + if (--sqp->s_sge.num_sge) + *sge = *sqp->s_sge.sg_list++; + } else if (sge->length == 0 && sge->mr->lkey) { + if (++sge->n >= QIB_SEGSZ) { + if (++sge->m >= sge->mr->mapsz) + break; + sge->n = 0; + } + sge->vaddr = + sge->mr->map[sge->m]->segs[sge->n].vaddr; + sge->length = + sge->mr->map[sge->m]->segs[sge->n].length; + } + sqp->s_len -= len; + } + if (release) + while (qp->r_sge.num_sge) { + atomic_dec(&qp->r_sge.sge.mr->refcount); + if (--qp->r_sge.num_sge) + qp->r_sge.sge = *qp->r_sge.sg_list++; + } + + if (!test_and_clear_bit(QIB_R_WRID_VALID, &qp->r_aflags)) + goto send_comp; + + if (wqe->wr.opcode == IB_WR_RDMA_WRITE_WITH_IMM) + wc.opcode = IB_WC_RECV_RDMA_WITH_IMM; + else + wc.opcode = IB_WC_RECV; + wc.wr_id = qp->r_wr_id; + wc.status = IB_WC_SUCCESS; + wc.byte_len = wqe->length; + wc.qp = &qp->ibqp; + wc.src_qp = qp->remote_qpn; + wc.slid = qp->remote_ah_attr.dlid; + wc.sl = qp->remote_ah_attr.sl; + wc.port_num = 1; + /* Signal completion event if the solicited bit is set. */ + qib_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, + wqe->wr.send_flags & IB_SEND_SOLICITED); + +send_comp: + spin_lock_irqsave(&sqp->s_lock, flags); + ibp->n_loop_pkts++; +flush_send: + sqp->s_rnr_retry = sqp->s_rnr_retry_cnt; + qib_send_complete(sqp, wqe, send_status); + goto again; + +rnr_nak: + /* Handle RNR NAK */ + if (qp->ibqp.qp_type == IB_QPT_UC) + goto send_comp; + ibp->n_rnr_naks++; + /* + * Note: we don't need the s_lock held since the BUSY flag + * makes this single threaded. + */ + if (sqp->s_rnr_retry == 0) { + send_status = IB_WC_RNR_RETRY_EXC_ERR; + goto serr; + } + if (sqp->s_rnr_retry_cnt < 7) + sqp->s_rnr_retry--; + spin_lock_irqsave(&sqp->s_lock, flags); + if (!(ib_qib_state_ops[sqp->state] & QIB_PROCESS_RECV_OK)) + goto clr_busy; + sqp->s_flags |= QIB_S_WAIT_RNR; + sqp->s_timer.function = qib_rc_rnr_retry; + sqp->s_timer.expires = jiffies + + usecs_to_jiffies(ib_qib_rnr_table[qp->r_min_rnr_timer]); + add_timer(&sqp->s_timer); + goto clr_busy; + +op_err: + send_status = IB_WC_REM_OP_ERR; + wc.status = IB_WC_LOC_QP_OP_ERR; + goto err; + +inv_err: + send_status = IB_WC_REM_INV_REQ_ERR; + wc.status = IB_WC_LOC_QP_OP_ERR; + goto err; + +acc_err: + send_status = IB_WC_REM_ACCESS_ERR; + wc.status = IB_WC_LOC_PROT_ERR; +err: + /* responder goes to error state */ + qib_rc_error(qp, wc.status); + +serr: + spin_lock_irqsave(&sqp->s_lock, flags); + qib_send_complete(sqp, wqe, send_status); + if (sqp->ibqp.qp_type == IB_QPT_RC) { + int lastwqe = qib_error_qp(sqp, IB_WC_WR_FLUSH_ERR); + + sqp->s_flags &= ~QIB_S_BUSY; + spin_unlock_irqrestore(&sqp->s_lock, flags); + if (lastwqe) { + struct ib_event ev; + + ev.device = sqp->ibqp.device; + ev.element.qp = &sqp->ibqp; + ev.event = IB_EVENT_QP_LAST_WQE_REACHED; + sqp->ibqp.event_handler(&ev, sqp->ibqp.qp_context); + } + goto done; + } +clr_busy: + sqp->s_flags &= ~QIB_S_BUSY; +unlock: + spin_unlock_irqrestore(&sqp->s_lock, flags); +done: + if (qp && atomic_dec_and_test(&qp->refcount)) + wake_up(&qp->wait); +} + +/** + * qib_make_grh - construct a GRH header + * @ibp: a pointer to the IB port + * @hdr: a pointer to the GRH header being constructed + * @grh: the global route address to send to + * @hwords: the number of 32 bit words of header being sent + * @nwords: the number of 32 bit words of data being sent + * + * Return the size of the header in 32 bit words. + */ +u32 qib_make_grh(struct qib_ibport *ibp, struct ib_grh *hdr, + struct ib_global_route *grh, u32 hwords, u32 nwords) +{ + hdr->version_tclass_flow = + cpu_to_be32((IB_GRH_VERSION << IB_GRH_VERSION_SHIFT) | + (grh->traffic_class << IB_GRH_TCLASS_SHIFT) | + (grh->flow_label << IB_GRH_FLOW_SHIFT)); + hdr->paylen = cpu_to_be16((hwords - 2 + nwords + SIZE_OF_CRC) << 2); + /* next_hdr is defined by C8-7 in ch. 8.4.1 */ + hdr->next_hdr = IB_GRH_NEXT_HDR; + hdr->hop_limit = grh->hop_limit; + /* The SGID is 32-bit aligned. */ + hdr->sgid.global.subnet_prefix = ibp->gid_prefix; + hdr->sgid.global.interface_id = grh->sgid_index ? + ibp->guids[grh->sgid_index - 1] : ppd_from_ibp(ibp)->guid; + hdr->dgid = grh->dgid; + + /* GRH header size in 32-bit words. */ + return sizeof(struct ib_grh) / sizeof(u32); +} + +void qib_make_ruc_header(struct qib_qp *qp, struct qib_other_headers *ohdr, + u32 bth0, u32 bth2) +{ + struct qib_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); + u16 lrh0; + u32 nwords; + u32 extra_bytes; + + /* Construct the header. */ + extra_bytes = -qp->s_cur_size & 3; + nwords = (qp->s_cur_size + extra_bytes) >> 2; + lrh0 = QIB_LRH_BTH; + if (unlikely(qp->remote_ah_attr.ah_flags & IB_AH_GRH)) { + qp->s_hdrwords += qib_make_grh(ibp, &qp->s_hdr.u.l.grh, + &qp->remote_ah_attr.grh, + qp->s_hdrwords, nwords); + lrh0 = QIB_LRH_GRH; + } + lrh0 |= ibp->sl_to_vl[qp->remote_ah_attr.sl] << 12 | + qp->remote_ah_attr.sl << 4; + qp->s_hdr.lrh[0] = cpu_to_be16(lrh0); + qp->s_hdr.lrh[1] = cpu_to_be16(qp->remote_ah_attr.dlid); + qp->s_hdr.lrh[2] = cpu_to_be16(qp->s_hdrwords + nwords + SIZE_OF_CRC); + qp->s_hdr.lrh[3] = cpu_to_be16(ppd_from_ibp(ibp)->lid | + qp->remote_ah_attr.src_path_bits); + bth0 |= qib_get_pkey(ibp, qp->s_pkey_index); + bth0 |= extra_bytes << 20; + if (qp->s_mig_state == IB_MIG_MIGRATED) + bth0 |= IB_BTH_MIG_REQ; + ohdr->bth[0] = cpu_to_be32(bth0); + ohdr->bth[1] = cpu_to_be32(qp->remote_qpn); + ohdr->bth[2] = cpu_to_be32(bth2); +} + +/** + * qib_do_send - perform a send on a QP + * @work: contains a pointer to the QP + * + * Process entries in the send work queue until credit or queue is + * exhausted. Only allow one CPU to send a packet per QP (tasklet). + * Otherwise, two threads could send packets out of order. + */ +void qib_do_send(struct work_struct *work) +{ + struct qib_qp *qp = container_of(work, struct qib_qp, s_work); + struct qib_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); + struct qib_pportdata *ppd = ppd_from_ibp(ibp); + int (*make_req)(struct qib_qp *qp); + unsigned long flags; + + if ((qp->ibqp.qp_type == IB_QPT_RC || + qp->ibqp.qp_type == IB_QPT_UC) && + (qp->remote_ah_attr.dlid & ~((1 << ppd->lmc) - 1)) == ppd->lid) { + qib_ruc_loopback(qp); + return; + } + + if (qp->ibqp.qp_type == IB_QPT_RC) + make_req = qib_make_rc_req; + else if (qp->ibqp.qp_type == IB_QPT_UC) + make_req = qib_make_uc_req; + else + make_req = qib_make_ud_req; + + spin_lock_irqsave(&qp->s_lock, flags); + + /* Return if we are already busy processing a work request. */ + if (!qib_send_ok(qp)) { + spin_unlock_irqrestore(&qp->s_lock, flags); + return; + } + + qp->s_flags |= QIB_S_BUSY; + + spin_unlock_irqrestore(&qp->s_lock, flags); + + do { + /* Check for a constructed packet to be sent. */ + if (qp->s_hdrwords != 0) { + /* + * If the packet cannot be sent now, return and + * the send tasklet will be woken up later. + */ + if (qib_verbs_send(qp, &qp->s_hdr, qp->s_hdrwords, + qp->s_cur_sge, qp->s_cur_size)) + break; + /* Record that s_hdr is empty. */ + qp->s_hdrwords = 0; + } + } while (make_req(qp)); +} + +/* + * This should be called with s_lock held. + */ +void qib_send_complete(struct qib_qp *qp, struct qib_swqe *wqe, + enum ib_wc_status status) +{ + u32 old_last, last; + unsigned i; + + if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_OR_FLUSH_SEND)) + return; + + for (i = 0; i < wqe->wr.num_sge; i++) { + struct qib_sge *sge = &wqe->sg_list[i]; + + atomic_dec(&sge->mr->refcount); + } + if (qp->ibqp.qp_type == IB_QPT_UD || + qp->ibqp.qp_type == IB_QPT_SMI || + qp->ibqp.qp_type == IB_QPT_GSI) + atomic_dec(&to_iah(wqe->wr.wr.ud.ah)->refcount); + + /* See ch. 11.2.4.1 and 10.7.3.1 */ + if (!(qp->s_flags & QIB_S_SIGNAL_REQ_WR) || + (wqe->wr.send_flags & IB_SEND_SIGNALED) || + status != IB_WC_SUCCESS) { + struct ib_wc wc; + + memset(&wc, 0, sizeof wc); + wc.wr_id = wqe->wr.wr_id; + wc.status = status; + wc.opcode = ib_qib_wc_opcode[wqe->wr.opcode]; + wc.qp = &qp->ibqp; + if (status == IB_WC_SUCCESS) + wc.byte_len = wqe->length; + qib_cq_enter(to_icq(qp->ibqp.send_cq), &wc, + status != IB_WC_SUCCESS); + } + + last = qp->s_last; + old_last = last; + if (++last >= qp->s_size) + last = 0; + qp->s_last = last; + if (qp->s_acked == old_last) + qp->s_acked = last; + if (qp->s_cur == old_last) + qp->s_cur = last; + if (qp->s_tail == old_last) + qp->s_tail = last; + if (qp->state == IB_QPS_SQD && last == qp->s_cur) + qp->s_draining = 0; +} diff --git a/drivers/infiniband/hw/qib/qib_sd7220.c b/drivers/infiniband/hw/qib/qib_sd7220.c new file mode 100644 index 000000000000..0aeed0e74cb6 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_sd7220.c @@ -0,0 +1,1413 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. + * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +/* + * This file contains all of the code that is specific to the SerDes + * on the QLogic_IB 7220 chip. + */ + +#include +#include + +#include "qib.h" +#include "qib_7220.h" + +/* + * Same as in qib_iba7220.c, but just the registers needed here. + * Could move whole set to qib_7220.h, but decided better to keep + * local. + */ +#define KREG_IDX(regname) (QIB_7220_##regname##_OFFS / sizeof(u64)) +#define kr_hwerrclear KREG_IDX(HwErrClear) +#define kr_hwerrmask KREG_IDX(HwErrMask) +#define kr_hwerrstatus KREG_IDX(HwErrStatus) +#define kr_ibcstatus KREG_IDX(IBCStatus) +#define kr_ibserdesctrl KREG_IDX(IBSerDesCtrl) +#define kr_scratch KREG_IDX(Scratch) +#define kr_xgxs_cfg KREG_IDX(XGXSCfg) +/* these are used only here, not in qib_iba7220.c */ +#define kr_ibsd_epb_access_ctrl KREG_IDX(ibsd_epb_access_ctrl) +#define kr_ibsd_epb_transaction_reg KREG_IDX(ibsd_epb_transaction_reg) +#define kr_pciesd_epb_transaction_reg KREG_IDX(pciesd_epb_transaction_reg) +#define kr_pciesd_epb_access_ctrl KREG_IDX(pciesd_epb_access_ctrl) +#define kr_serdes_ddsrxeq0 KREG_IDX(SerDes_DDSRXEQ0) + +/* + * The IBSerDesMappTable is a memory that holds values to be stored in + * various SerDes registers by IBC. + */ +#define kr_serdes_maptable KREG_IDX(IBSerDesMappTable) + +/* + * Below used for sdnum parameter, selecting one of the two sections + * used for PCIe, or the single SerDes used for IB. + */ +#define PCIE_SERDES0 0 +#define PCIE_SERDES1 1 + +/* + * The EPB requires addressing in a particular form. EPB_LOC() is intended + * to make #definitions a little more readable. + */ +#define EPB_ADDR_SHF 8 +#define EPB_LOC(chn, elt, reg) \ + (((elt & 0xf) | ((chn & 7) << 4) | ((reg & 0x3f) << 9)) << \ + EPB_ADDR_SHF) +#define EPB_IB_QUAD0_CS_SHF (25) +#define EPB_IB_QUAD0_CS (1U << EPB_IB_QUAD0_CS_SHF) +#define EPB_IB_UC_CS_SHF (26) +#define EPB_PCIE_UC_CS_SHF (27) +#define EPB_GLOBAL_WR (1U << (EPB_ADDR_SHF + 8)) + +/* Forward declarations. */ +static int qib_sd7220_reg_mod(struct qib_devdata *dd, int sdnum, u32 loc, + u32 data, u32 mask); +static int ibsd_mod_allchnls(struct qib_devdata *dd, int loc, int val, + int mask); +static int qib_sd_trimdone_poll(struct qib_devdata *dd); +static void qib_sd_trimdone_monitor(struct qib_devdata *dd, const char *where); +static int qib_sd_setvals(struct qib_devdata *dd); +static int qib_sd_early(struct qib_devdata *dd); +static int qib_sd_dactrim(struct qib_devdata *dd); +static int qib_internal_presets(struct qib_devdata *dd); +/* Tweak the register (CMUCTRL5) that contains the TRIMSELF controls */ +static int qib_sd_trimself(struct qib_devdata *dd, int val); +static int epb_access(struct qib_devdata *dd, int sdnum, int claim); + +/* + * Below keeps track of whether the "once per power-on" initialization has + * been done, because uC code Version 1.32.17 or higher allows the uC to + * be reset at will, and Automatic Equalization may require it. So the + * state of the reset "pin", is no longer valid. Instead, we check for the + * actual uC code having been loaded. + */ +static int qib_ibsd_ucode_loaded(struct qib_pportdata *ppd) +{ + struct qib_devdata *dd = ppd->dd; + if (!dd->cspec->serdes_first_init_done && (qib_sd7220_ib_vfy(dd) > 0)) + dd->cspec->serdes_first_init_done = 1; + return dd->cspec->serdes_first_init_done; +} + +/* repeat #define for local use. "Real" #define is in qib_iba7220.c */ +#define QLOGIC_IB_HWE_IB_UC_MEMORYPARITYERR 0x0000004000000000ULL +#define IB_MPREG5 (EPB_LOC(6, 0, 0xE) | (1L << EPB_IB_UC_CS_SHF)) +#define IB_MPREG6 (EPB_LOC(6, 0, 0xF) | (1U << EPB_IB_UC_CS_SHF)) +#define UC_PAR_CLR_D 8 +#define UC_PAR_CLR_M 0xC +#define IB_CTRL2(chn) (EPB_LOC(chn, 7, 3) | EPB_IB_QUAD0_CS) +#define START_EQ1(chan) EPB_LOC(chan, 7, 0x27) + +void qib_sd7220_clr_ibpar(struct qib_devdata *dd) +{ + int ret; + + /* clear, then re-enable parity errs */ + ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, IB_MPREG6, + UC_PAR_CLR_D, UC_PAR_CLR_M); + if (ret < 0) { + qib_dev_err(dd, "Failed clearing IBSerDes Parity err\n"); + goto bail; + } + ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, IB_MPREG6, 0, + UC_PAR_CLR_M); + + qib_read_kreg32(dd, kr_scratch); + udelay(4); + qib_write_kreg(dd, kr_hwerrclear, + QLOGIC_IB_HWE_IB_UC_MEMORYPARITYERR); + qib_read_kreg32(dd, kr_scratch); +bail: + return; +} + +/* + * After a reset or other unusual event, the epb interface may need + * to be re-synchronized, between the host and the uC. + * returns <0 for failure to resync within IBSD_RESYNC_TRIES (not expected) + */ +#define IBSD_RESYNC_TRIES 3 +#define IB_PGUDP(chn) (EPB_LOC((chn), 2, 1) | EPB_IB_QUAD0_CS) +#define IB_CMUDONE(chn) (EPB_LOC((chn), 7, 0xF) | EPB_IB_QUAD0_CS) + +static int qib_resync_ibepb(struct qib_devdata *dd) +{ + int ret, pat, tries, chn; + u32 loc; + + ret = -1; + chn = 0; + for (tries = 0; tries < (4 * IBSD_RESYNC_TRIES); ++tries) { + loc = IB_PGUDP(chn); + ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, loc, 0, 0); + if (ret < 0) { + qib_dev_err(dd, "Failed read in resync\n"); + continue; + } + if (ret != 0xF0 && ret != 0x55 && tries == 0) + qib_dev_err(dd, "unexpected pattern in resync\n"); + pat = ret ^ 0xA5; /* alternate F0 and 55 */ + ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, loc, pat, 0xFF); + if (ret < 0) { + qib_dev_err(dd, "Failed write in resync\n"); + continue; + } + ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, loc, 0, 0); + if (ret < 0) { + qib_dev_err(dd, "Failed re-read in resync\n"); + continue; + } + if (ret != pat) { + qib_dev_err(dd, "Failed compare1 in resync\n"); + continue; + } + loc = IB_CMUDONE(chn); + ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, loc, 0, 0); + if (ret < 0) { + qib_dev_err(dd, "Failed CMUDONE rd in resync\n"); + continue; + } + if ((ret & 0x70) != ((chn << 4) | 0x40)) { + qib_dev_err(dd, "Bad CMUDONE value %02X, chn %d\n", + ret, chn); + continue; + } + if (++chn == 4) + break; /* Success */ + } + return (ret > 0) ? 0 : ret; +} + +/* + * Localize the stuff that should be done to change IB uC reset + * returns <0 for errors. + */ +static int qib_ibsd_reset(struct qib_devdata *dd, int assert_rst) +{ + u64 rst_val; + int ret = 0; + unsigned long flags; + + rst_val = qib_read_kreg64(dd, kr_ibserdesctrl); + if (assert_rst) { + /* + * Vendor recommends "interrupting" uC before reset, to + * minimize possible glitches. + */ + spin_lock_irqsave(&dd->cspec->sdepb_lock, flags); + epb_access(dd, IB_7220_SERDES, 1); + rst_val |= 1ULL; + /* Squelch possible parity error from _asserting_ reset */ + qib_write_kreg(dd, kr_hwerrmask, + dd->cspec->hwerrmask & + ~QLOGIC_IB_HWE_IB_UC_MEMORYPARITYERR); + qib_write_kreg(dd, kr_ibserdesctrl, rst_val); + /* flush write, delay to ensure it took effect */ + qib_read_kreg32(dd, kr_scratch); + udelay(2); + /* once it's reset, can remove interrupt */ + epb_access(dd, IB_7220_SERDES, -1); + spin_unlock_irqrestore(&dd->cspec->sdepb_lock, flags); + } else { + /* + * Before we de-assert reset, we need to deal with + * possible glitch on the Parity-error line. + * Suppress it around the reset, both in chip-level + * hwerrmask and in IB uC control reg. uC will allow + * it again during startup. + */ + u64 val; + rst_val &= ~(1ULL); + qib_write_kreg(dd, kr_hwerrmask, + dd->cspec->hwerrmask & + ~QLOGIC_IB_HWE_IB_UC_MEMORYPARITYERR); + + ret = qib_resync_ibepb(dd); + if (ret < 0) + qib_dev_err(dd, "unable to re-sync IB EPB\n"); + + /* set uC control regs to suppress parity errs */ + ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, IB_MPREG5, 1, 1); + if (ret < 0) + goto bail; + /* IB uC code past Version 1.32.17 allow suppression of wdog */ + ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, IB_MPREG6, 0x80, + 0x80); + if (ret < 0) { + qib_dev_err(dd, "Failed to set WDOG disable\n"); + goto bail; + } + qib_write_kreg(dd, kr_ibserdesctrl, rst_val); + /* flush write, delay for startup */ + qib_read_kreg32(dd, kr_scratch); + udelay(1); + /* clear, then re-enable parity errs */ + qib_sd7220_clr_ibpar(dd); + val = qib_read_kreg64(dd, kr_hwerrstatus); + if (val & QLOGIC_IB_HWE_IB_UC_MEMORYPARITYERR) { + qib_dev_err(dd, "IBUC Parity still set after RST\n"); + dd->cspec->hwerrmask &= + ~QLOGIC_IB_HWE_IB_UC_MEMORYPARITYERR; + } + qib_write_kreg(dd, kr_hwerrmask, + dd->cspec->hwerrmask); + } + +bail: + return ret; +} + +static void qib_sd_trimdone_monitor(struct qib_devdata *dd, + const char *where) +{ + int ret, chn, baduns; + u64 val; + + if (!where) + where = "?"; + + /* give time for reset to settle out in EPB */ + udelay(2); + + ret = qib_resync_ibepb(dd); + if (ret < 0) + qib_dev_err(dd, "not able to re-sync IB EPB (%s)\n", where); + + /* Do "sacrificial read" to get EPB in sane state after reset */ + ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, IB_CTRL2(0), 0, 0); + if (ret < 0) + qib_dev_err(dd, "Failed TRIMDONE 1st read, (%s)\n", where); + + /* Check/show "summary" Trim-done bit in IBCStatus */ + val = qib_read_kreg64(dd, kr_ibcstatus); + if (!(val & (1ULL << 11))) + qib_dev_err(dd, "IBCS TRIMDONE clear (%s)\n", where); + /* + * Do "dummy read/mod/wr" to get EPB in sane state after reset + * The default value for MPREG6 is 0. + */ + udelay(2); + + ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, IB_MPREG6, 0x80, 0x80); + if (ret < 0) + qib_dev_err(dd, "Failed Dummy RMW, (%s)\n", where); + udelay(10); + + baduns = 0; + + for (chn = 3; chn >= 0; --chn) { + /* Read CTRL reg for each channel to check TRIMDONE */ + ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, + IB_CTRL2(chn), 0, 0); + if (ret < 0) + qib_dev_err(dd, "Failed checking TRIMDONE, chn %d" + " (%s)\n", chn, where); + + if (!(ret & 0x10)) { + int probe; + + baduns |= (1 << chn); + qib_dev_err(dd, "TRIMDONE cleared on chn %d (%02X)." + " (%s)\n", chn, ret, where); + probe = qib_sd7220_reg_mod(dd, IB_7220_SERDES, + IB_PGUDP(0), 0, 0); + qib_dev_err(dd, "probe is %d (%02X)\n", + probe, probe); + probe = qib_sd7220_reg_mod(dd, IB_7220_SERDES, + IB_CTRL2(chn), 0, 0); + qib_dev_err(dd, "re-read: %d (%02X)\n", + probe, probe); + ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, + IB_CTRL2(chn), 0x10, 0x10); + if (ret < 0) + qib_dev_err(dd, + "Err on TRIMDONE rewrite1\n"); + } + } + for (chn = 3; chn >= 0; --chn) { + /* Read CTRL reg for each channel to check TRIMDONE */ + if (baduns & (1 << chn)) { + qib_dev_err(dd, + "Reseting TRIMDONE on chn %d (%s)\n", + chn, where); + ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, + IB_CTRL2(chn), 0x10, 0x10); + if (ret < 0) + qib_dev_err(dd, "Failed re-setting " + "TRIMDONE, chn %d (%s)\n", + chn, where); + } + } +} + +/* + * Below is portion of IBA7220-specific bringup_serdes() that actually + * deals with registers and memory within the SerDes itself. + * Post IB uC code version 1.32.17, was_reset being 1 is not really + * informative, so we double-check. + */ +int qib_sd7220_init(struct qib_devdata *dd) +{ + int ret = 1; /* default to failure */ + int first_reset, was_reset; + + /* SERDES MPU reset recorded in D0 */ + was_reset = (qib_read_kreg64(dd, kr_ibserdesctrl) & 1); + if (!was_reset) { + /* entered with reset not asserted, we need to do it */ + qib_ibsd_reset(dd, 1); + qib_sd_trimdone_monitor(dd, "Driver-reload"); + } + /* Substitute our deduced value for was_reset */ + ret = qib_ibsd_ucode_loaded(dd->pport); + if (ret < 0) + goto bail; + + first_reset = !ret; /* First reset if IBSD uCode not yet loaded */ + /* + * Alter some regs per vendor latest doc, reset-defaults + * are not right for IB. + */ + ret = qib_sd_early(dd); + if (ret < 0) { + qib_dev_err(dd, "Failed to set IB SERDES early defaults\n"); + goto bail; + } + /* + * Set DAC manual trim IB. + * We only do this once after chip has been reset (usually + * same as once per system boot). + */ + if (first_reset) { + ret = qib_sd_dactrim(dd); + if (ret < 0) { + qib_dev_err(dd, "Failed IB SERDES DAC trim\n"); + goto bail; + } + } + /* + * Set various registers (DDS and RXEQ) that will be + * controlled by IBC (in 1.2 mode) to reasonable preset values + * Calling the "internal" version avoids the "check for needed" + * and "trimdone monitor" that might be counter-productive. + */ + ret = qib_internal_presets(dd); + if (ret < 0) { + qib_dev_err(dd, "Failed to set IB SERDES presets\n"); + goto bail; + } + ret = qib_sd_trimself(dd, 0x80); + if (ret < 0) { + qib_dev_err(dd, "Failed to set IB SERDES TRIMSELF\n"); + goto bail; + } + + /* Load image, then try to verify */ + ret = 0; /* Assume success */ + if (first_reset) { + int vfy; + int trim_done; + + ret = qib_sd7220_ib_load(dd); + if (ret < 0) { + qib_dev_err(dd, "Failed to load IB SERDES image\n"); + goto bail; + } else { + /* Loaded image, try to verify */ + vfy = qib_sd7220_ib_vfy(dd); + if (vfy != ret) { + qib_dev_err(dd, "SERDES PRAM VFY failed\n"); + goto bail; + } /* end if verified */ + } /* end if loaded */ + + /* + * Loaded and verified. Almost good... + * hold "success" in ret + */ + ret = 0; + /* + * Prev steps all worked, continue bringup + * De-assert RESET to uC, only in first reset, to allow + * trimming. + * + * Since our default setup sets START_EQ1 to + * PRESET, we need to clear that for this very first run. + */ + ret = ibsd_mod_allchnls(dd, START_EQ1(0), 0, 0x38); + if (ret < 0) { + qib_dev_err(dd, "Failed clearing START_EQ1\n"); + goto bail; + } + + qib_ibsd_reset(dd, 0); + /* + * If this is not the first reset, trimdone should be set + * already. We may need to check about this. + */ + trim_done = qib_sd_trimdone_poll(dd); + /* + * Whether or not trimdone succeeded, we need to put the + * uC back into reset to avoid a possible fight with the + * IBC state-machine. + */ + qib_ibsd_reset(dd, 1); + + if (!trim_done) { + qib_dev_err(dd, "No TRIMDONE seen\n"); + goto bail; + } + /* + * DEBUG: check each time we reset if trimdone bits have + * gotten cleared, and re-set them. + */ + qib_sd_trimdone_monitor(dd, "First-reset"); + /* Remember so we do not re-do the load, dactrim, etc. */ + dd->cspec->serdes_first_init_done = 1; + } + /* + * setup for channel training and load values for + * RxEq and DDS in tables used by IBC in IB1.2 mode + */ + ret = 0; + if (qib_sd_setvals(dd) >= 0) + goto done; +bail: + ret = 1; +done: + /* start relock timer regardless, but start at 1 second */ + set_7220_relock_poll(dd, -1); + return ret; +} + +#define EPB_ACC_REQ 1 +#define EPB_ACC_GNT 0x100 +#define EPB_DATA_MASK 0xFF +#define EPB_RD (1ULL << 24) +#define EPB_TRANS_RDY (1ULL << 31) +#define EPB_TRANS_ERR (1ULL << 30) +#define EPB_TRANS_TRIES 5 + +/* + * query, claim, release ownership of the EPB (External Parallel Bus) + * for a specified SERDES. + * the "claim" parameter is >0 to claim, <0 to release, 0 to query. + * Returns <0 for errors, >0 if we had ownership, else 0. + */ +static int epb_access(struct qib_devdata *dd, int sdnum, int claim) +{ + u16 acc; + u64 accval; + int owned = 0; + u64 oct_sel = 0; + + switch (sdnum) { + case IB_7220_SERDES: + /* + * The IB SERDES "ownership" is fairly simple. A single each + * request/grant. + */ + acc = kr_ibsd_epb_access_ctrl; + break; + + case PCIE_SERDES0: + case PCIE_SERDES1: + /* PCIe SERDES has two "octants", need to select which */ + acc = kr_pciesd_epb_access_ctrl; + oct_sel = (2 << (sdnum - PCIE_SERDES0)); + break; + + default: + return 0; + } + + /* Make sure any outstanding transaction was seen */ + qib_read_kreg32(dd, kr_scratch); + udelay(15); + + accval = qib_read_kreg32(dd, acc); + + owned = !!(accval & EPB_ACC_GNT); + if (claim < 0) { + /* Need to release */ + u64 pollval; + /* + * The only writeable bits are the request and CS. + * Both should be clear + */ + u64 newval = 0; + qib_write_kreg(dd, acc, newval); + /* First read after write is not trustworthy */ + pollval = qib_read_kreg32(dd, acc); + udelay(5); + pollval = qib_read_kreg32(dd, acc); + if (pollval & EPB_ACC_GNT) + owned = -1; + } else if (claim > 0) { + /* Need to claim */ + u64 pollval; + u64 newval = EPB_ACC_REQ | oct_sel; + qib_write_kreg(dd, acc, newval); + /* First read after write is not trustworthy */ + pollval = qib_read_kreg32(dd, acc); + udelay(5); + pollval = qib_read_kreg32(dd, acc); + if (!(pollval & EPB_ACC_GNT)) + owned = -1; + } + return owned; +} + +/* + * Lemma to deal with race condition of write..read to epb regs + */ +static int epb_trans(struct qib_devdata *dd, u16 reg, u64 i_val, u64 *o_vp) +{ + int tries; + u64 transval; + + qib_write_kreg(dd, reg, i_val); + /* Throw away first read, as RDY bit may be stale */ + transval = qib_read_kreg64(dd, reg); + + for (tries = EPB_TRANS_TRIES; tries; --tries) { + transval = qib_read_kreg32(dd, reg); + if (transval & EPB_TRANS_RDY) + break; + udelay(5); + } + if (transval & EPB_TRANS_ERR) + return -1; + if (tries > 0 && o_vp) + *o_vp = transval; + return tries; +} + +/** + * qib_sd7220_reg_mod - modify SERDES register + * @dd: the qlogic_ib device + * @sdnum: which SERDES to access + * @loc: location - channel, element, register, as packed by EPB_LOC() macro. + * @wd: Write Data - value to set in register + * @mask: ones where data should be spliced into reg. + * + * Basic register read/modify/write, with un-needed acesses elided. That is, + * a mask of zero will prevent write, while a mask of 0xFF will prevent read. + * returns current (presumed, if a write was done) contents of selected + * register, or <0 if errors. + */ +static int qib_sd7220_reg_mod(struct qib_devdata *dd, int sdnum, u32 loc, + u32 wd, u32 mask) +{ + u16 trans; + u64 transval; + int owned; + int tries, ret; + unsigned long flags; + + switch (sdnum) { + case IB_7220_SERDES: + trans = kr_ibsd_epb_transaction_reg; + break; + + case PCIE_SERDES0: + case PCIE_SERDES1: + trans = kr_pciesd_epb_transaction_reg; + break; + + default: + return -1; + } + + /* + * All access is locked in software (vs other host threads) and + * hardware (vs uC access). + */ + spin_lock_irqsave(&dd->cspec->sdepb_lock, flags); + + owned = epb_access(dd, sdnum, 1); + if (owned < 0) { + spin_unlock_irqrestore(&dd->cspec->sdepb_lock, flags); + return -1; + } + ret = 0; + for (tries = EPB_TRANS_TRIES; tries; --tries) { + transval = qib_read_kreg32(dd, trans); + if (transval & EPB_TRANS_RDY) + break; + udelay(5); + } + + if (tries > 0) { + tries = 1; /* to make read-skip work */ + if (mask != 0xFF) { + /* + * Not a pure write, so need to read. + * loc encodes chip-select as well as address + */ + transval = loc | EPB_RD; + tries = epb_trans(dd, trans, transval, &transval); + } + if (tries > 0 && mask != 0) { + /* + * Not a pure read, so need to write. + */ + wd = (wd & mask) | (transval & ~mask); + transval = loc | (wd & EPB_DATA_MASK); + tries = epb_trans(dd, trans, transval, &transval); + } + } + /* else, failed to see ready, what error-handling? */ + + /* + * Release bus. Failure is an error. + */ + if (epb_access(dd, sdnum, -1) < 0) + ret = -1; + else + ret = transval & EPB_DATA_MASK; + + spin_unlock_irqrestore(&dd->cspec->sdepb_lock, flags); + if (tries <= 0) + ret = -1; + return ret; +} + +#define EPB_ROM_R (2) +#define EPB_ROM_W (1) +/* + * Below, all uC-related, use appropriate UC_CS, depending + * on which SerDes is used. + */ +#define EPB_UC_CTL EPB_LOC(6, 0, 0) +#define EPB_MADDRL EPB_LOC(6, 0, 2) +#define EPB_MADDRH EPB_LOC(6, 0, 3) +#define EPB_ROMDATA EPB_LOC(6, 0, 4) +#define EPB_RAMDATA EPB_LOC(6, 0, 5) + +/* Transfer date to/from uC Program RAM of IB or PCIe SerDes */ +static int qib_sd7220_ram_xfer(struct qib_devdata *dd, int sdnum, u32 loc, + u8 *buf, int cnt, int rd_notwr) +{ + u16 trans; + u64 transval; + u64 csbit; + int owned; + int tries; + int sofar; + int addr; + int ret; + unsigned long flags; + const char *op; + + /* Pick appropriate transaction reg and "Chip select" for this serdes */ + switch (sdnum) { + case IB_7220_SERDES: + csbit = 1ULL << EPB_IB_UC_CS_SHF; + trans = kr_ibsd_epb_transaction_reg; + break; + + case PCIE_SERDES0: + case PCIE_SERDES1: + /* PCIe SERDES has uC "chip select" in different bit, too */ + csbit = 1ULL << EPB_PCIE_UC_CS_SHF; + trans = kr_pciesd_epb_transaction_reg; + break; + + default: + return -1; + } + + op = rd_notwr ? "Rd" : "Wr"; + spin_lock_irqsave(&dd->cspec->sdepb_lock, flags); + + owned = epb_access(dd, sdnum, 1); + if (owned < 0) { + spin_unlock_irqrestore(&dd->cspec->sdepb_lock, flags); + return -1; + } + + /* + * In future code, we may need to distinguish several address ranges, + * and select various memories based on this. For now, just trim + * "loc" (location including address and memory select) to + * "addr" (address within memory). we will only support PRAM + * The memory is 8KB. + */ + addr = loc & 0x1FFF; + for (tries = EPB_TRANS_TRIES; tries; --tries) { + transval = qib_read_kreg32(dd, trans); + if (transval & EPB_TRANS_RDY) + break; + udelay(5); + } + + sofar = 0; + if (tries > 0) { + /* + * Every "memory" access is doubly-indirect. + * We set two bytes of address, then read/write + * one or mores bytes of data. + */ + + /* First, we set control to "Read" or "Write" */ + transval = csbit | EPB_UC_CTL | + (rd_notwr ? EPB_ROM_R : EPB_ROM_W); + tries = epb_trans(dd, trans, transval, &transval); + while (tries > 0 && sofar < cnt) { + if (!sofar) { + /* Only set address at start of chunk */ + int addrbyte = (addr + sofar) >> 8; + transval = csbit | EPB_MADDRH | addrbyte; + tries = epb_trans(dd, trans, transval, + &transval); + if (tries <= 0) + break; + addrbyte = (addr + sofar) & 0xFF; + transval = csbit | EPB_MADDRL | addrbyte; + tries = epb_trans(dd, trans, transval, + &transval); + if (tries <= 0) + break; + } + + if (rd_notwr) + transval = csbit | EPB_ROMDATA | EPB_RD; + else + transval = csbit | EPB_ROMDATA | buf[sofar]; + tries = epb_trans(dd, trans, transval, &transval); + if (tries <= 0) + break; + if (rd_notwr) + buf[sofar] = transval & EPB_DATA_MASK; + ++sofar; + } + /* Finally, clear control-bit for Read or Write */ + transval = csbit | EPB_UC_CTL; + tries = epb_trans(dd, trans, transval, &transval); + } + + ret = sofar; + /* Release bus. Failure is an error */ + if (epb_access(dd, sdnum, -1) < 0) + ret = -1; + + spin_unlock_irqrestore(&dd->cspec->sdepb_lock, flags); + if (tries <= 0) + ret = -1; + return ret; +} + +#define PROG_CHUNK 64 + +int qib_sd7220_prog_ld(struct qib_devdata *dd, int sdnum, + u8 *img, int len, int offset) +{ + int cnt, sofar, req; + + sofar = 0; + while (sofar < len) { + req = len - sofar; + if (req > PROG_CHUNK) + req = PROG_CHUNK; + cnt = qib_sd7220_ram_xfer(dd, sdnum, offset + sofar, + img + sofar, req, 0); + if (cnt < req) { + sofar = -1; + break; + } + sofar += req; + } + return sofar; +} + +#define VFY_CHUNK 64 +#define SD_PRAM_ERROR_LIMIT 42 + +int qib_sd7220_prog_vfy(struct qib_devdata *dd, int sdnum, + const u8 *img, int len, int offset) +{ + int cnt, sofar, req, idx, errors; + unsigned char readback[VFY_CHUNK]; + + errors = 0; + sofar = 0; + while (sofar < len) { + req = len - sofar; + if (req > VFY_CHUNK) + req = VFY_CHUNK; + cnt = qib_sd7220_ram_xfer(dd, sdnum, sofar + offset, + readback, req, 1); + if (cnt < req) { + /* failed in read itself */ + sofar = -1; + break; + } + for (idx = 0; idx < cnt; ++idx) { + if (readback[idx] != img[idx+sofar]) + ++errors; + } + sofar += cnt; + } + return errors ? -errors : sofar; +} + +/* + * IRQ not set up at this point in init, so we poll. + */ +#define IB_SERDES_TRIM_DONE (1ULL << 11) +#define TRIM_TMO (30) + +static int qib_sd_trimdone_poll(struct qib_devdata *dd) +{ + int trim_tmo, ret; + uint64_t val; + + /* + * Default to failure, so IBC will not start + * without IB_SERDES_TRIM_DONE. + */ + ret = 0; + for (trim_tmo = 0; trim_tmo < TRIM_TMO; ++trim_tmo) { + val = qib_read_kreg64(dd, kr_ibcstatus); + if (val & IB_SERDES_TRIM_DONE) { + ret = 1; + break; + } + msleep(10); + } + if (trim_tmo >= TRIM_TMO) { + qib_dev_err(dd, "No TRIMDONE in %d tries\n", trim_tmo); + ret = 0; + } + return ret; +} + +#define TX_FAST_ELT (9) + +/* + * Set the "negotiation" values for SERDES. These are used by the IB1.2 + * link negotiation. Macros below are attempt to keep the values a + * little more human-editable. + * First, values related to Drive De-emphasis Settings. + */ + +#define NUM_DDS_REGS 6 +#define DDS_REG_MAP 0x76A910 /* LSB-first list of regs (in elt 9) to mod */ + +#define DDS_VAL(amp_d, main_d, ipst_d, ipre_d, amp_s, main_s, ipst_s, ipre_s) \ + { { ((amp_d & 0x1F) << 1) | 1, ((amp_s & 0x1F) << 1) | 1, \ + (main_d << 3) | 4 | (ipre_d >> 2), \ + (main_s << 3) | 4 | (ipre_s >> 2), \ + ((ipst_d & 0xF) << 1) | ((ipre_d & 3) << 6) | 0x21, \ + ((ipst_s & 0xF) << 1) | ((ipre_s & 3) << 6) | 0x21 } } + +static struct dds_init { + uint8_t reg_vals[NUM_DDS_REGS]; +} dds_init_vals[] = { + /* DDR(FDR) SDR(HDR) */ + /* Vendor recommends below for 3m cable */ +#define DDS_3M 0 + DDS_VAL(31, 19, 12, 0, 29, 22, 9, 0), + DDS_VAL(31, 12, 15, 4, 31, 15, 15, 1), + DDS_VAL(31, 13, 15, 3, 31, 16, 15, 0), + DDS_VAL(31, 14, 15, 2, 31, 17, 14, 0), + DDS_VAL(31, 15, 15, 1, 31, 18, 13, 0), + DDS_VAL(31, 16, 15, 0, 31, 19, 12, 0), + DDS_VAL(31, 17, 14, 0, 31, 20, 11, 0), + DDS_VAL(31, 18, 13, 0, 30, 21, 10, 0), + DDS_VAL(31, 20, 11, 0, 28, 23, 8, 0), + DDS_VAL(31, 21, 10, 0, 27, 24, 7, 0), + DDS_VAL(31, 22, 9, 0, 26, 25, 6, 0), + DDS_VAL(30, 23, 8, 0, 25, 26, 5, 0), + DDS_VAL(29, 24, 7, 0, 23, 27, 4, 0), + /* Vendor recommends below for 1m cable */ +#define DDS_1M 13 + DDS_VAL(28, 25, 6, 0, 21, 28, 3, 0), + DDS_VAL(27, 26, 5, 0, 19, 29, 2, 0), + DDS_VAL(25, 27, 4, 0, 17, 30, 1, 0) +}; + +/* + * Now the RXEQ section of the table. + */ +/* Hardware packs an element number and register address thus: */ +#define RXEQ_INIT_RDESC(elt, addr) (((elt) & 0xF) | ((addr) << 4)) +#define RXEQ_VAL(elt, adr, val0, val1, val2, val3) \ + {RXEQ_INIT_RDESC((elt), (adr)), {(val0), (val1), (val2), (val3)} } + +#define RXEQ_VAL_ALL(elt, adr, val) \ + {RXEQ_INIT_RDESC((elt), (adr)), {(val), (val), (val), (val)} } + +#define RXEQ_SDR_DFELTH 0 +#define RXEQ_SDR_TLTH 0 +#define RXEQ_SDR_G1CNT_Z1CNT 0x11 +#define RXEQ_SDR_ZCNT 23 + +static struct rxeq_init { + u16 rdesc; /* in form used in SerDesDDSRXEQ */ + u8 rdata[4]; +} rxeq_init_vals[] = { + /* Set Rcv Eq. to Preset node */ + RXEQ_VAL_ALL(7, 0x27, 0x10), + /* Set DFELTHFDR/HDR thresholds */ + RXEQ_VAL(7, 8, 0, 0, 0, 0), /* FDR, was 0, 1, 2, 3 */ + RXEQ_VAL(7, 0x21, 0, 0, 0, 0), /* HDR */ + /* Set TLTHFDR/HDR theshold */ + RXEQ_VAL(7, 9, 2, 2, 2, 2), /* FDR, was 0, 2, 4, 6 */ + RXEQ_VAL(7, 0x23, 2, 2, 2, 2), /* HDR, was 0, 1, 2, 3 */ + /* Set Preamp setting 2 (ZFR/ZCNT) */ + RXEQ_VAL(7, 0x1B, 12, 12, 12, 12), /* FDR, was 12, 16, 20, 24 */ + RXEQ_VAL(7, 0x1C, 12, 12, 12, 12), /* HDR, was 12, 16, 20, 24 */ + /* Set Preamp DC gain and Setting 1 (GFR/GHR) */ + RXEQ_VAL(7, 0x1E, 16, 16, 16, 16), /* FDR, was 16, 17, 18, 20 */ + RXEQ_VAL(7, 0x1F, 16, 16, 16, 16), /* HDR, was 16, 17, 18, 20 */ + /* Toggle RELOCK (in VCDL_CTRL0) to lock to data */ + RXEQ_VAL_ALL(6, 6, 0x20), /* Set D5 High */ + RXEQ_VAL_ALL(6, 6, 0), /* Set D5 Low */ +}; + +/* There are 17 values from vendor, but IBC only accesses the first 16 */ +#define DDS_ROWS (16) +#define RXEQ_ROWS ARRAY_SIZE(rxeq_init_vals) + +static int qib_sd_setvals(struct qib_devdata *dd) +{ + int idx, midx; + int min_idx; /* Minimum index for this portion of table */ + uint32_t dds_reg_map; + u64 __iomem *taddr, *iaddr; + uint64_t data; + uint64_t sdctl; + + taddr = dd->kregbase + kr_serdes_maptable; + iaddr = dd->kregbase + kr_serdes_ddsrxeq0; + + /* + * Init the DDS section of the table. + * Each "row" of the table provokes NUM_DDS_REG writes, to the + * registers indicated in DDS_REG_MAP. + */ + sdctl = qib_read_kreg64(dd, kr_ibserdesctrl); + sdctl = (sdctl & ~(0x1f << 8)) | (NUM_DDS_REGS << 8); + sdctl = (sdctl & ~(0x1f << 13)) | (RXEQ_ROWS << 13); + qib_write_kreg(dd, kr_ibserdesctrl, sdctl); + + /* + * Iterate down table within loop for each register to store. + */ + dds_reg_map = DDS_REG_MAP; + for (idx = 0; idx < NUM_DDS_REGS; ++idx) { + data = ((dds_reg_map & 0xF) << 4) | TX_FAST_ELT; + writeq(data, iaddr + idx); + mmiowb(); + qib_read_kreg32(dd, kr_scratch); + dds_reg_map >>= 4; + for (midx = 0; midx < DDS_ROWS; ++midx) { + u64 __iomem *daddr = taddr + ((midx << 4) + idx); + data = dds_init_vals[midx].reg_vals[idx]; + writeq(data, daddr); + mmiowb(); + qib_read_kreg32(dd, kr_scratch); + } /* End inner for (vals for this reg, each row) */ + } /* end outer for (regs to be stored) */ + + /* + * Init the RXEQ section of the table. + * This runs in a different order, as the pattern of + * register references is more complex, but there are only + * four "data" values per register. + */ + min_idx = idx; /* RXEQ indices pick up where DDS left off */ + taddr += 0x100; /* RXEQ data is in second half of table */ + /* Iterate through RXEQ register addresses */ + for (idx = 0; idx < RXEQ_ROWS; ++idx) { + int didx; /* "destination" */ + int vidx; + + /* didx is offset by min_idx to address RXEQ range of regs */ + didx = idx + min_idx; + /* Store the next RXEQ register address */ + writeq(rxeq_init_vals[idx].rdesc, iaddr + didx); + mmiowb(); + qib_read_kreg32(dd, kr_scratch); + /* Iterate through RXEQ values */ + for (vidx = 0; vidx < 4; vidx++) { + data = rxeq_init_vals[idx].rdata[vidx]; + writeq(data, taddr + (vidx << 6) + idx); + mmiowb(); + qib_read_kreg32(dd, kr_scratch); + } + } /* end outer for (Reg-writes for RXEQ) */ + return 0; +} + +#define CMUCTRL5 EPB_LOC(7, 0, 0x15) +#define RXHSCTRL0(chan) EPB_LOC(chan, 6, 0) +#define VCDL_DAC2(chan) EPB_LOC(chan, 6, 5) +#define VCDL_CTRL0(chan) EPB_LOC(chan, 6, 6) +#define VCDL_CTRL2(chan) EPB_LOC(chan, 6, 8) +#define START_EQ2(chan) EPB_LOC(chan, 7, 0x28) + +/* + * Repeat a "store" across all channels of the IB SerDes. + * Although nominally it inherits the "read value" of the last + * channel it modified, the only really useful return is <0 for + * failure, >= 0 for success. The parameter 'loc' is assumed to + * be the location in some channel of the register to be modified + * The caller can specify use of the "gang write" option of EPB, + * in which case we use the specified channel data for any fields + * not explicitely written. + */ +static int ibsd_mod_allchnls(struct qib_devdata *dd, int loc, int val, + int mask) +{ + int ret = -1; + int chnl; + + if (loc & EPB_GLOBAL_WR) { + /* + * Our caller has assured us that we can set all four + * channels at once. Trust that. If mask is not 0xFF, + * we will read the _specified_ channel for our starting + * value. + */ + loc |= (1U << EPB_IB_QUAD0_CS_SHF); + chnl = (loc >> (4 + EPB_ADDR_SHF)) & 7; + if (mask != 0xFF) { + ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, + loc & ~EPB_GLOBAL_WR, 0, 0); + if (ret < 0) { + int sloc = loc >> EPB_ADDR_SHF; + + qib_dev_err(dd, "pre-read failed: elt %d," + " addr 0x%X, chnl %d\n", + (sloc & 0xF), + (sloc >> 9) & 0x3f, chnl); + return ret; + } + val = (ret & ~mask) | (val & mask); + } + loc &= ~(7 << (4+EPB_ADDR_SHF)); + ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, loc, val, 0xFF); + if (ret < 0) { + int sloc = loc >> EPB_ADDR_SHF; + + qib_dev_err(dd, "Global WR failed: elt %d," + " addr 0x%X, val %02X\n", + (sloc & 0xF), (sloc >> 9) & 0x3f, val); + } + return ret; + } + /* Clear "channel" and set CS so we can simply iterate */ + loc &= ~(7 << (4+EPB_ADDR_SHF)); + loc |= (1U << EPB_IB_QUAD0_CS_SHF); + for (chnl = 0; chnl < 4; ++chnl) { + int cloc = loc | (chnl << (4+EPB_ADDR_SHF)); + + ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, cloc, val, mask); + if (ret < 0) { + int sloc = loc >> EPB_ADDR_SHF; + + qib_dev_err(dd, "Write failed: elt %d," + " addr 0x%X, chnl %d, val 0x%02X," + " mask 0x%02X\n", + (sloc & 0xF), (sloc >> 9) & 0x3f, chnl, + val & 0xFF, mask & 0xFF); + break; + } + } + return ret; +} + +/* + * Set the Tx values normally modified by IBC in IB1.2 mode to default + * values, as gotten from first row of init table. + */ +static int set_dds_vals(struct qib_devdata *dd, struct dds_init *ddi) +{ + int ret; + int idx, reg, data; + uint32_t regmap; + + regmap = DDS_REG_MAP; + for (idx = 0; idx < NUM_DDS_REGS; ++idx) { + reg = (regmap & 0xF); + regmap >>= 4; + data = ddi->reg_vals[idx]; + /* Vendor says RMW not needed for these regs, use 0xFF mask */ + ret = ibsd_mod_allchnls(dd, EPB_LOC(0, 9, reg), data, 0xFF); + if (ret < 0) + break; + } + return ret; +} + +/* + * Set the Rx values normally modified by IBC in IB1.2 mode to default + * values, as gotten from selected column of init table. + */ +static int set_rxeq_vals(struct qib_devdata *dd, int vsel) +{ + int ret; + int ridx; + int cnt = ARRAY_SIZE(rxeq_init_vals); + + for (ridx = 0; ridx < cnt; ++ridx) { + int elt, reg, val, loc; + + elt = rxeq_init_vals[ridx].rdesc & 0xF; + reg = rxeq_init_vals[ridx].rdesc >> 4; + loc = EPB_LOC(0, elt, reg); + val = rxeq_init_vals[ridx].rdata[vsel]; + /* mask of 0xFF, because hardware does full-byte store. */ + ret = ibsd_mod_allchnls(dd, loc, val, 0xFF); + if (ret < 0) + break; + } + return ret; +} + +/* + * Set the default values (row 0) for DDR Driver Demphasis. + * we do this initially and whenever we turn off IB-1.2 + * + * The "default" values for Rx equalization are also stored to + * SerDes registers. Formerly (and still default), we used set 2. + * For experimenting with cables and link-partners, we allow changing + * that via a module parameter. + */ +static unsigned qib_rxeq_set = 2; +module_param_named(rxeq_default_set, qib_rxeq_set, uint, + S_IWUSR | S_IRUGO); +MODULE_PARM_DESC(rxeq_default_set, + "Which set [0..3] of Rx Equalization values is default"); + +static int qib_internal_presets(struct qib_devdata *dd) +{ + int ret = 0; + + ret = set_dds_vals(dd, dds_init_vals + DDS_3M); + + if (ret < 0) + qib_dev_err(dd, "Failed to set default DDS values\n"); + ret = set_rxeq_vals(dd, qib_rxeq_set & 3); + if (ret < 0) + qib_dev_err(dd, "Failed to set default RXEQ values\n"); + return ret; +} + +int qib_sd7220_presets(struct qib_devdata *dd) +{ + int ret = 0; + + if (!dd->cspec->presets_needed) + return ret; + dd->cspec->presets_needed = 0; + /* Assert uC reset, so we don't clash with it. */ + qib_ibsd_reset(dd, 1); + udelay(2); + qib_sd_trimdone_monitor(dd, "link-down"); + + ret = qib_internal_presets(dd); + return ret; +} + +static int qib_sd_trimself(struct qib_devdata *dd, int val) +{ + int loc = CMUCTRL5 | (1U << EPB_IB_QUAD0_CS_SHF); + + return qib_sd7220_reg_mod(dd, IB_7220_SERDES, loc, val, 0xFF); +} + +static int qib_sd_early(struct qib_devdata *dd) +{ + int ret; + + ret = ibsd_mod_allchnls(dd, RXHSCTRL0(0) | EPB_GLOBAL_WR, 0xD4, 0xFF); + if (ret < 0) + goto bail; + ret = ibsd_mod_allchnls(dd, START_EQ1(0) | EPB_GLOBAL_WR, 0x10, 0xFF); + if (ret < 0) + goto bail; + ret = ibsd_mod_allchnls(dd, START_EQ2(0) | EPB_GLOBAL_WR, 0x30, 0xFF); +bail: + return ret; +} + +#define BACTRL(chnl) EPB_LOC(chnl, 6, 0x0E) +#define LDOUTCTRL1(chnl) EPB_LOC(chnl, 7, 6) +#define RXHSSTATUS(chnl) EPB_LOC(chnl, 6, 0xF) + +static int qib_sd_dactrim(struct qib_devdata *dd) +{ + int ret; + + ret = ibsd_mod_allchnls(dd, VCDL_DAC2(0) | EPB_GLOBAL_WR, 0x2D, 0xFF); + if (ret < 0) + goto bail; + + /* more fine-tuning of what will be default */ + ret = ibsd_mod_allchnls(dd, VCDL_CTRL2(0), 3, 0xF); + if (ret < 0) + goto bail; + + ret = ibsd_mod_allchnls(dd, BACTRL(0) | EPB_GLOBAL_WR, 0x40, 0xFF); + if (ret < 0) + goto bail; + + ret = ibsd_mod_allchnls(dd, LDOUTCTRL1(0) | EPB_GLOBAL_WR, 0x04, 0xFF); + if (ret < 0) + goto bail; + + ret = ibsd_mod_allchnls(dd, RXHSSTATUS(0) | EPB_GLOBAL_WR, 0x04, 0xFF); + if (ret < 0) + goto bail; + + /* + * Delay for max possible number of steps, with slop. + * Each step is about 4usec. + */ + udelay(415); + + ret = ibsd_mod_allchnls(dd, LDOUTCTRL1(0) | EPB_GLOBAL_WR, 0x00, 0xFF); + +bail: + return ret; +} + +#define RELOCK_FIRST_MS 3 +#define RXLSPPM(chan) EPB_LOC(chan, 0, 2) +void toggle_7220_rclkrls(struct qib_devdata *dd) +{ + int loc = RXLSPPM(0) | EPB_GLOBAL_WR; + int ret; + + ret = ibsd_mod_allchnls(dd, loc, 0, 0x80); + if (ret < 0) + qib_dev_err(dd, "RCLKRLS failed to clear D7\n"); + else { + udelay(1); + ibsd_mod_allchnls(dd, loc, 0x80, 0x80); + } + /* And again for good measure */ + udelay(1); + ret = ibsd_mod_allchnls(dd, loc, 0, 0x80); + if (ret < 0) + qib_dev_err(dd, "RCLKRLS failed to clear D7\n"); + else { + udelay(1); + ibsd_mod_allchnls(dd, loc, 0x80, 0x80); + } + /* Now reset xgxs and IBC to complete the recovery */ + dd->f_xgxs_reset(dd->pport); +} + +/* + * Shut down the timer that polls for relock occasions, if needed + * this is "hooked" from qib_7220_quiet_serdes(), which is called + * just before qib_shutdown_device() in qib_driver.c shuts down all + * the other timers + */ +void shutdown_7220_relock_poll(struct qib_devdata *dd) +{ + if (dd->cspec->relock_timer_active) + del_timer_sync(&dd->cspec->relock_timer); +} + +static unsigned qib_relock_by_timer = 1; +module_param_named(relock_by_timer, qib_relock_by_timer, uint, + S_IWUSR | S_IRUGO); +MODULE_PARM_DESC(relock_by_timer, "Allow relock attempt if link not up"); + +static void qib_run_relock(unsigned long opaque) +{ + struct qib_devdata *dd = (struct qib_devdata *)opaque; + struct qib_pportdata *ppd = dd->pport; + struct qib_chip_specific *cs = dd->cspec; + int timeoff; + + /* + * Check link-training state for "stuck" state, when down. + * if found, try relock and schedule another try at + * exponentially growing delay, maxed at one second. + * if not stuck, our work is done. + */ + if ((dd->flags & QIB_INITTED) && !(ppd->lflags & + (QIBL_IB_AUTONEG_INPROG | QIBL_LINKINIT | QIBL_LINKARMED | + QIBL_LINKACTIVE))) { + if (qib_relock_by_timer) { + if (!(ppd->lflags & QIBL_IB_LINK_DISABLED)) + toggle_7220_rclkrls(dd); + } + /* re-set timer for next check */ + timeoff = cs->relock_interval << 1; + if (timeoff > HZ) + timeoff = HZ; + cs->relock_interval = timeoff; + } else + timeoff = HZ; + mod_timer(&cs->relock_timer, jiffies + timeoff); +} + +void set_7220_relock_poll(struct qib_devdata *dd, int ibup) +{ + struct qib_chip_specific *cs = dd->cspec; + + if (ibup) { + /* We are now up, relax timer to 1 second interval */ + if (cs->relock_timer_active) { + cs->relock_interval = HZ; + mod_timer(&cs->relock_timer, jiffies + HZ); + } + } else { + /* Transition to down, (re-)set timer to short interval. */ + unsigned int timeout; + + timeout = msecs_to_jiffies(RELOCK_FIRST_MS); + if (timeout == 0) + timeout = 1; + /* If timer has not yet been started, do so. */ + if (!cs->relock_timer_active) { + cs->relock_timer_active = 1; + init_timer(&cs->relock_timer); + cs->relock_timer.function = qib_run_relock; + cs->relock_timer.data = (unsigned long) dd; + cs->relock_interval = timeout; + cs->relock_timer.expires = jiffies + timeout; + add_timer(&cs->relock_timer); + } else { + cs->relock_interval = timeout; + mod_timer(&cs->relock_timer, jiffies + timeout); + } + } +} diff --git a/drivers/infiniband/hw/qib/qib_sd7220_img.c b/drivers/infiniband/hw/qib/qib_sd7220_img.c new file mode 100644 index 000000000000..a1118fbd2370 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_sd7220_img.c @@ -0,0 +1,1081 @@ +/* + * Copyright (c) 2007, 2008 QLogic Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * This file contains the memory image from the vendor, to be copied into + * the IB SERDES of the IBA7220 during initialization. + * The file also includes the two functions which use this image. + */ +#include +#include + +#include "qib.h" +#include "qib_7220.h" + +static unsigned char qib_sd7220_ib_img[] = { +/*0000*/0x02, 0x0A, 0x29, 0x02, 0x0A, 0x87, 0xE5, 0xE6, + 0x30, 0xE6, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, +/*0010*/0x00, 0xE5, 0xE2, 0x30, 0xE4, 0x04, 0x7E, 0x01, + 0x80, 0x02, 0x7E, 0x00, 0xEE, 0x5F, 0x60, 0x08, +/*0020*/0x53, 0xF9, 0xF7, 0xE4, 0xF5, 0xFE, 0x80, 0x08, + 0x7F, 0x0A, 0x12, 0x17, 0x31, 0x12, 0x0E, 0xA2, +/*0030*/0x75, 0xFC, 0x08, 0xE4, 0xF5, 0xFD, 0xE5, 0xE7, + 0x20, 0xE7, 0x03, 0x43, 0xF9, 0x08, 0x22, 0x00, +/*0040*/0x01, 0x20, 0x11, 0x00, 0x04, 0x20, 0x00, 0x75, + 0x51, 0x01, 0xE4, 0xF5, 0x52, 0xF5, 0x53, 0xF5, +/*0050*/0x52, 0xF5, 0x7E, 0x7F, 0x04, 0x02, 0x04, 0x38, + 0xC2, 0x36, 0x05, 0x52, 0xE5, 0x52, 0xD3, 0x94, +/*0060*/0x0C, 0x40, 0x05, 0x75, 0x52, 0x01, 0xD2, 0x36, + 0x90, 0x07, 0x0C, 0x74, 0x07, 0xF0, 0xA3, 0x74, +/*0070*/0xFF, 0xF0, 0xE4, 0xF5, 0x0C, 0xA3, 0xF0, 0x90, + 0x07, 0x14, 0xF0, 0xA3, 0xF0, 0x75, 0x0B, 0x20, +/*0080*/0xF5, 0x09, 0xE4, 0xF5, 0x08, 0xE5, 0x08, 0xD3, + 0x94, 0x30, 0x40, 0x03, 0x02, 0x04, 0x04, 0x12, +/*0090*/0x00, 0x06, 0x15, 0x0B, 0xE5, 0x08, 0x70, 0x04, + 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xE5, 0x09, +/*00A0*/0x70, 0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, + 0xEE, 0x5F, 0x60, 0x05, 0x12, 0x18, 0x71, 0xD2, +/*00B0*/0x35, 0x53, 0xE1, 0xF7, 0xE5, 0x08, 0x45, 0x09, + 0xFF, 0xE5, 0x0B, 0x25, 0xE0, 0x25, 0xE0, 0x24, +/*00C0*/0x83, 0xF5, 0x82, 0xE4, 0x34, 0x07, 0xF5, 0x83, + 0xEF, 0xF0, 0x85, 0xE2, 0x20, 0xE5, 0x52, 0xD3, +/*00D0*/0x94, 0x01, 0x40, 0x0D, 0x12, 0x19, 0xF3, 0xE0, + 0x54, 0xA0, 0x64, 0x40, 0x70, 0x03, 0x02, 0x03, +/*00E0*/0xFB, 0x53, 0xF9, 0xF8, 0x90, 0x94, 0x70, 0xE4, + 0xF0, 0xE0, 0xF5, 0x10, 0xAF, 0x09, 0x12, 0x1E, +/*00F0*/0xB3, 0xAF, 0x08, 0xEF, 0x44, 0x08, 0xF5, 0x82, + 0x75, 0x83, 0x80, 0xE0, 0xF5, 0x29, 0xEF, 0x44, +/*0100*/0x07, 0x12, 0x1A, 0x3C, 0xF5, 0x22, 0x54, 0x40, + 0xD3, 0x94, 0x00, 0x40, 0x1E, 0xE5, 0x29, 0x54, +/*0110*/0xF0, 0x70, 0x21, 0x12, 0x19, 0xF3, 0xE0, 0x44, + 0x80, 0xF0, 0xE5, 0x22, 0x54, 0x30, 0x65, 0x08, +/*0120*/0x70, 0x09, 0x12, 0x19, 0xF3, 0xE0, 0x54, 0xBF, + 0xF0, 0x80, 0x09, 0x12, 0x19, 0xF3, 0x74, 0x40, +/*0130*/0xF0, 0x02, 0x03, 0xFB, 0x12, 0x1A, 0x12, 0x75, + 0x83, 0xAE, 0x74, 0xFF, 0xF0, 0xAF, 0x08, 0x7E, +/*0140*/0x00, 0xEF, 0x44, 0x07, 0xF5, 0x82, 0xE0, 0xFD, + 0xE5, 0x0B, 0x25, 0xE0, 0x25, 0xE0, 0x24, 0x81, +/*0150*/0xF5, 0x82, 0xE4, 0x34, 0x07, 0xF5, 0x83, 0xED, + 0xF0, 0x90, 0x07, 0x0E, 0xE0, 0x04, 0xF0, 0xEF, +/*0160*/0x44, 0x07, 0xF5, 0x82, 0x75, 0x83, 0x98, 0xE0, + 0xF5, 0x28, 0x12, 0x1A, 0x23, 0x40, 0x0C, 0x12, +/*0170*/0x19, 0xF3, 0xE0, 0x44, 0x01, 0x12, 0x1A, 0x32, + 0x02, 0x03, 0xF6, 0xAF, 0x08, 0x7E, 0x00, 0x74, +/*0180*/0x80, 0xCD, 0xEF, 0xCD, 0x8D, 0x82, 0xF5, 0x83, + 0xE0, 0x30, 0xE0, 0x0A, 0x12, 0x19, 0xF3, 0xE0, +/*0190*/0x44, 0x20, 0xF0, 0x02, 0x03, 0xFB, 0x12, 0x19, + 0xF3, 0xE0, 0x54, 0xDF, 0xF0, 0xEE, 0x44, 0xAE, +/*01A0*/0x12, 0x1A, 0x43, 0x30, 0xE4, 0x03, 0x02, 0x03, + 0xFB, 0x74, 0x9E, 0x12, 0x1A, 0x05, 0x20, 0xE0, +/*01B0*/0x03, 0x02, 0x03, 0xFB, 0x8F, 0x82, 0x8E, 0x83, + 0xE0, 0x20, 0xE0, 0x03, 0x02, 0x03, 0xFB, 0x12, +/*01C0*/0x19, 0xF3, 0xE0, 0x44, 0x10, 0xF0, 0xE5, 0xE3, + 0x20, 0xE7, 0x08, 0xE5, 0x08, 0x12, 0x1A, 0x3A, +/*01D0*/0x44, 0x04, 0xF0, 0xAF, 0x08, 0x7E, 0x00, 0xEF, + 0x12, 0x1A, 0x3A, 0x20, 0xE2, 0x34, 0x12, 0x19, +/*01E0*/0xF3, 0xE0, 0x44, 0x08, 0xF0, 0xE5, 0xE4, 0x30, + 0xE6, 0x04, 0x7D, 0x01, 0x80, 0x02, 0x7D, 0x00, +/*01F0*/0xE5, 0x7E, 0xC3, 0x94, 0x04, 0x50, 0x04, 0x7C, + 0x01, 0x80, 0x02, 0x7C, 0x00, 0xEC, 0x4D, 0x60, +/*0200*/0x05, 0xC2, 0x35, 0x02, 0x03, 0xFB, 0xEE, 0x44, + 0xD2, 0x12, 0x1A, 0x43, 0x44, 0x40, 0xF0, 0x02, +/*0210*/0x03, 0xFB, 0x12, 0x19, 0xF3, 0xE0, 0x54, 0xF7, + 0xF0, 0x12, 0x1A, 0x12, 0x75, 0x83, 0xD2, 0xE0, +/*0220*/0x54, 0xBF, 0xF0, 0x90, 0x07, 0x14, 0xE0, 0x04, + 0xF0, 0xE5, 0x7E, 0x70, 0x03, 0x75, 0x7E, 0x01, +/*0230*/0xAF, 0x08, 0x7E, 0x00, 0x12, 0x1A, 0x23, 0x40, + 0x12, 0x12, 0x19, 0xF3, 0xE0, 0x44, 0x01, 0x12, +/*0240*/0x19, 0xF2, 0xE0, 0x54, 0x02, 0x12, 0x1A, 0x32, + 0x02, 0x03, 0xFB, 0x12, 0x19, 0xF3, 0xE0, 0x44, +/*0250*/0x02, 0x12, 0x19, 0xF2, 0xE0, 0x54, 0xFE, 0xF0, + 0xC2, 0x35, 0xEE, 0x44, 0x8A, 0x8F, 0x82, 0xF5, +/*0260*/0x83, 0xE0, 0xF5, 0x17, 0x54, 0x8F, 0x44, 0x40, + 0xF0, 0x74, 0x90, 0xFC, 0xE5, 0x08, 0x44, 0x07, +/*0270*/0xFD, 0xF5, 0x82, 0x8C, 0x83, 0xE0, 0x54, 0x3F, + 0x90, 0x07, 0x02, 0xF0, 0xE0, 0x54, 0xC0, 0x8D, +/*0280*/0x82, 0x8C, 0x83, 0xF0, 0x74, 0x92, 0x12, 0x1A, + 0x05, 0x90, 0x07, 0x03, 0x12, 0x1A, 0x19, 0x74, +/*0290*/0x82, 0x12, 0x1A, 0x05, 0x90, 0x07, 0x04, 0x12, + 0x1A, 0x19, 0x74, 0xB4, 0x12, 0x1A, 0x05, 0x90, +/*02A0*/0x07, 0x05, 0x12, 0x1A, 0x19, 0x74, 0x94, 0xFE, + 0xE5, 0x08, 0x44, 0x06, 0x12, 0x1A, 0x0A, 0xF5, +/*02B0*/0x10, 0x30, 0xE0, 0x04, 0xD2, 0x37, 0x80, 0x02, + 0xC2, 0x37, 0xE5, 0x10, 0x54, 0x7F, 0x8F, 0x82, +/*02C0*/0x8E, 0x83, 0xF0, 0x30, 0x44, 0x30, 0x12, 0x1A, + 0x03, 0x54, 0x80, 0xD3, 0x94, 0x00, 0x40, 0x04, +/*02D0*/0xD2, 0x39, 0x80, 0x02, 0xC2, 0x39, 0x8F, 0x82, + 0x8E, 0x83, 0xE0, 0x44, 0x80, 0xF0, 0x12, 0x1A, +/*02E0*/0x03, 0x54, 0x40, 0xD3, 0x94, 0x00, 0x40, 0x04, + 0xD2, 0x3A, 0x80, 0x02, 0xC2, 0x3A, 0x8F, 0x82, +/*02F0*/0x8E, 0x83, 0xE0, 0x44, 0x40, 0xF0, 0x74, 0x92, + 0xFE, 0xE5, 0x08, 0x44, 0x06, 0x12, 0x1A, 0x0A, +/*0300*/0x30, 0xE7, 0x04, 0xD2, 0x38, 0x80, 0x02, 0xC2, + 0x38, 0x8F, 0x82, 0x8E, 0x83, 0xE0, 0x54, 0x7F, +/*0310*/0xF0, 0x12, 0x1E, 0x46, 0xE4, 0xF5, 0x0A, 0x20, + 0x03, 0x02, 0x80, 0x03, 0x30, 0x43, 0x03, 0x12, +/*0320*/0x19, 0x95, 0x20, 0x02, 0x02, 0x80, 0x03, 0x30, + 0x42, 0x03, 0x12, 0x0C, 0x8F, 0x30, 0x30, 0x06, +/*0330*/0x12, 0x19, 0x95, 0x12, 0x0C, 0x8F, 0x12, 0x0D, + 0x47, 0x12, 0x19, 0xF3, 0xE0, 0x54, 0xFB, 0xF0, +/*0340*/0xE5, 0x0A, 0xC3, 0x94, 0x01, 0x40, 0x46, 0x43, + 0xE1, 0x08, 0x12, 0x19, 0xF3, 0xE0, 0x44, 0x04, +/*0350*/0xF0, 0xE5, 0xE4, 0x20, 0xE7, 0x2A, 0x12, 0x1A, + 0x12, 0x75, 0x83, 0xD2, 0xE0, 0x54, 0x08, 0xD3, +/*0360*/0x94, 0x00, 0x40, 0x04, 0x7F, 0x01, 0x80, 0x02, + 0x7F, 0x00, 0xE5, 0x0A, 0xC3, 0x94, 0x01, 0x40, +/*0370*/0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEF, + 0x5E, 0x60, 0x05, 0x12, 0x1D, 0xD7, 0x80, 0x17, +/*0380*/0x12, 0x1A, 0x12, 0x75, 0x83, 0xD2, 0xE0, 0x44, + 0x08, 0xF0, 0x02, 0x03, 0xFB, 0x12, 0x1A, 0x12, +/*0390*/0x75, 0x83, 0xD2, 0xE0, 0x54, 0xF7, 0xF0, 0x12, + 0x1E, 0x46, 0x7F, 0x08, 0x12, 0x17, 0x31, 0x74, +/*03A0*/0x8E, 0xFE, 0x12, 0x1A, 0x12, 0x8E, 0x83, 0xE0, + 0xF5, 0x10, 0x54, 0xFE, 0xF0, 0xE5, 0x10, 0x44, +/*03B0*/0x01, 0xFF, 0xE5, 0x08, 0xFD, 0xED, 0x44, 0x07, + 0xF5, 0x82, 0xEF, 0xF0, 0xE5, 0x10, 0x54, 0xFE, +/*03C0*/0xFF, 0xED, 0x44, 0x07, 0xF5, 0x82, 0xEF, 0x12, + 0x1A, 0x11, 0x75, 0x83, 0x86, 0xE0, 0x44, 0x10, +/*03D0*/0x12, 0x1A, 0x11, 0xE0, 0x44, 0x10, 0xF0, 0x12, + 0x19, 0xF3, 0xE0, 0x54, 0xFD, 0x44, 0x01, 0xFF, +/*03E0*/0x12, 0x19, 0xF3, 0xEF, 0x12, 0x1A, 0x32, 0x30, + 0x32, 0x0C, 0xE5, 0x08, 0x44, 0x08, 0xF5, 0x82, +/*03F0*/0x75, 0x83, 0x82, 0x74, 0x05, 0xF0, 0xAF, 0x0B, + 0x12, 0x18, 0xD7, 0x74, 0x10, 0x25, 0x08, 0xF5, +/*0400*/0x08, 0x02, 0x00, 0x85, 0x05, 0x09, 0xE5, 0x09, + 0xD3, 0x94, 0x07, 0x50, 0x03, 0x02, 0x00, 0x82, +/*0410*/0xE5, 0x7E, 0xD3, 0x94, 0x00, 0x40, 0x04, 0x7F, + 0x01, 0x80, 0x02, 0x7F, 0x00, 0xE5, 0x7E, 0xC3, +/*0420*/0x94, 0xFA, 0x50, 0x04, 0x7E, 0x01, 0x80, 0x02, + 0x7E, 0x00, 0xEE, 0x5F, 0x60, 0x02, 0x05, 0x7E, +/*0430*/0x30, 0x35, 0x0B, 0x43, 0xE1, 0x01, 0x7F, 0x09, + 0x12, 0x17, 0x31, 0x02, 0x00, 0x58, 0x53, 0xE1, +/*0440*/0xFE, 0x02, 0x00, 0x58, 0x8E, 0x6A, 0x8F, 0x6B, + 0x8C, 0x6C, 0x8D, 0x6D, 0x75, 0x6E, 0x01, 0x75, +/*0450*/0x6F, 0x01, 0x75, 0x70, 0x01, 0xE4, 0xF5, 0x73, + 0xF5, 0x74, 0xF5, 0x75, 0x90, 0x07, 0x2F, 0xF0, +/*0460*/0xF5, 0x3C, 0xF5, 0x3E, 0xF5, 0x46, 0xF5, 0x47, + 0xF5, 0x3D, 0xF5, 0x3F, 0xF5, 0x6F, 0xE5, 0x6F, +/*0470*/0x70, 0x0F, 0xE5, 0x6B, 0x45, 0x6A, 0x12, 0x07, + 0x2A, 0x75, 0x83, 0x80, 0x74, 0x3A, 0xF0, 0x80, +/*0480*/0x09, 0x12, 0x07, 0x2A, 0x75, 0x83, 0x80, 0x74, + 0x1A, 0xF0, 0xE4, 0xF5, 0x6E, 0xC3, 0x74, 0x3F, +/*0490*/0x95, 0x6E, 0xFF, 0x12, 0x08, 0x65, 0x75, 0x83, + 0x82, 0xEF, 0xF0, 0x12, 0x1A, 0x4D, 0x12, 0x08, +/*04A0*/0xC6, 0xE5, 0x33, 0xF0, 0x12, 0x08, 0xFA, 0x12, + 0x08, 0xB1, 0x40, 0xE1, 0xE5, 0x6F, 0x70, 0x0B, +/*04B0*/0x12, 0x07, 0x2A, 0x75, 0x83, 0x80, 0x74, 0x36, + 0xF0, 0x80, 0x09, 0x12, 0x07, 0x2A, 0x75, 0x83, +/*04C0*/0x80, 0x74, 0x16, 0xF0, 0x75, 0x6E, 0x01, 0x12, + 0x07, 0x2A, 0x75, 0x83, 0xB4, 0xE5, 0x6E, 0xF0, +/*04D0*/0x12, 0x1A, 0x4D, 0x74, 0x3F, 0x25, 0x6E, 0xF5, + 0x82, 0xE4, 0x34, 0x00, 0xF5, 0x83, 0xE5, 0x33, +/*04E0*/0xF0, 0x74, 0xBF, 0x25, 0x6E, 0xF5, 0x82, 0xE4, + 0x34, 0x00, 0x12, 0x08, 0xB1, 0x40, 0xD8, 0xE4, +/*04F0*/0xF5, 0x70, 0xF5, 0x46, 0xF5, 0x47, 0xF5, 0x6E, + 0x12, 0x08, 0xFA, 0xF5, 0x83, 0xE0, 0xFE, 0x12, +/*0500*/0x08, 0xC6, 0xE0, 0x7C, 0x00, 0x24, 0x00, 0xFF, + 0xEC, 0x3E, 0xFE, 0xAD, 0x3B, 0xD3, 0xEF, 0x9D, +/*0510*/0xEE, 0x9C, 0x50, 0x04, 0x7B, 0x01, 0x80, 0x02, + 0x7B, 0x00, 0xE5, 0x70, 0x70, 0x04, 0x7A, 0x01, +/*0520*/0x80, 0x02, 0x7A, 0x00, 0xEB, 0x5A, 0x60, 0x06, + 0x85, 0x6E, 0x46, 0x75, 0x70, 0x01, 0xD3, 0xEF, +/*0530*/0x9D, 0xEE, 0x9C, 0x50, 0x04, 0x7F, 0x01, 0x80, + 0x02, 0x7F, 0x00, 0xE5, 0x70, 0xB4, 0x01, 0x04, +/*0540*/0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEF, 0x5E, + 0x60, 0x03, 0x85, 0x6E, 0x47, 0x05, 0x6E, 0xE5, +/*0550*/0x6E, 0x64, 0x7F, 0x70, 0xA3, 0xE5, 0x46, 0x60, + 0x05, 0xE5, 0x47, 0xB4, 0x7E, 0x03, 0x85, 0x46, +/*0560*/0x47, 0xE5, 0x6F, 0x70, 0x08, 0x85, 0x46, 0x76, + 0x85, 0x47, 0x77, 0x80, 0x0E, 0xC3, 0x74, 0x7F, +/*0570*/0x95, 0x46, 0xF5, 0x78, 0xC3, 0x74, 0x7F, 0x95, + 0x47, 0xF5, 0x79, 0xE5, 0x6F, 0x70, 0x37, 0xE5, +/*0580*/0x46, 0x65, 0x47, 0x70, 0x0C, 0x75, 0x73, 0x01, + 0x75, 0x74, 0x01, 0xF5, 0x3C, 0xF5, 0x3D, 0x80, +/*0590*/0x35, 0xE4, 0xF5, 0x4E, 0xC3, 0xE5, 0x47, 0x95, + 0x46, 0xF5, 0x3C, 0xC3, 0x13, 0xF5, 0x71, 0x25, +/*05A0*/0x46, 0xF5, 0x72, 0xC3, 0x94, 0x3F, 0x40, 0x05, + 0xE4, 0xF5, 0x3D, 0x80, 0x40, 0xC3, 0x74, 0x3F, +/*05B0*/0x95, 0x72, 0xF5, 0x3D, 0x80, 0x37, 0xE5, 0x46, + 0x65, 0x47, 0x70, 0x0F, 0x75, 0x73, 0x01, 0x75, +/*05C0*/0x75, 0x01, 0xF5, 0x3E, 0xF5, 0x3F, 0x75, 0x4E, + 0x01, 0x80, 0x22, 0xE4, 0xF5, 0x4E, 0xC3, 0xE5, +/*05D0*/0x47, 0x95, 0x46, 0xF5, 0x3E, 0xC3, 0x13, 0xF5, + 0x71, 0x25, 0x46, 0xF5, 0x72, 0xD3, 0x94, 0x3F, +/*05E0*/0x50, 0x05, 0xE4, 0xF5, 0x3F, 0x80, 0x06, 0xE5, + 0x72, 0x24, 0xC1, 0xF5, 0x3F, 0x05, 0x6F, 0xE5, +/*05F0*/0x6F, 0xC3, 0x94, 0x02, 0x50, 0x03, 0x02, 0x04, + 0x6E, 0xE5, 0x6D, 0x45, 0x6C, 0x70, 0x02, 0x80, +/*0600*/0x04, 0xE5, 0x74, 0x45, 0x75, 0x90, 0x07, 0x2F, + 0xF0, 0x7F, 0x01, 0xE5, 0x3E, 0x60, 0x04, 0xE5, +/*0610*/0x3C, 0x70, 0x14, 0xE4, 0xF5, 0x3C, 0xF5, 0x3D, + 0xF5, 0x3E, 0xF5, 0x3F, 0x12, 0x08, 0xD2, 0x70, +/*0620*/0x04, 0xF0, 0x02, 0x06, 0xA4, 0x80, 0x7A, 0xE5, + 0x3C, 0xC3, 0x95, 0x3E, 0x40, 0x07, 0xE5, 0x3C, +/*0630*/0x95, 0x3E, 0xFF, 0x80, 0x06, 0xC3, 0xE5, 0x3E, + 0x95, 0x3C, 0xFF, 0xE5, 0x76, 0xD3, 0x95, 0x79, +/*0640*/0x40, 0x05, 0x85, 0x76, 0x7A, 0x80, 0x03, 0x85, + 0x79, 0x7A, 0xE5, 0x77, 0xC3, 0x95, 0x78, 0x50, +/*0650*/0x05, 0x85, 0x77, 0x7B, 0x80, 0x03, 0x85, 0x78, + 0x7B, 0xE5, 0x7B, 0xD3, 0x95, 0x7A, 0x40, 0x30, +/*0660*/0xE5, 0x7B, 0x95, 0x7A, 0xF5, 0x3C, 0xF5, 0x3E, + 0xC3, 0xE5, 0x7B, 0x95, 0x7A, 0x90, 0x07, 0x19, +/*0670*/0xF0, 0xE5, 0x3C, 0xC3, 0x13, 0xF5, 0x71, 0x25, + 0x7A, 0xF5, 0x72, 0xC3, 0x94, 0x3F, 0x40, 0x05, +/*0680*/0xE4, 0xF5, 0x3D, 0x80, 0x1F, 0xC3, 0x74, 0x3F, + 0x95, 0x72, 0xF5, 0x3D, 0xF5, 0x3F, 0x80, 0x14, +/*0690*/0xE4, 0xF5, 0x3C, 0xF5, 0x3E, 0x90, 0x07, 0x19, + 0xF0, 0x12, 0x08, 0xD2, 0x70, 0x03, 0xF0, 0x80, +/*06A0*/0x03, 0x74, 0x01, 0xF0, 0x12, 0x08, 0x65, 0x75, + 0x83, 0xD0, 0xE0, 0x54, 0x0F, 0xFE, 0xAD, 0x3C, +/*06B0*/0x70, 0x02, 0x7E, 0x07, 0xBE, 0x0F, 0x02, 0x7E, + 0x80, 0xEE, 0xFB, 0xEF, 0xD3, 0x9B, 0x74, 0x80, +/*06C0*/0xF8, 0x98, 0x40, 0x1F, 0xE4, 0xF5, 0x3C, 0xF5, + 0x3E, 0x12, 0x08, 0xD2, 0x70, 0x03, 0xF0, 0x80, +/*06D0*/0x12, 0x74, 0x01, 0xF0, 0xE5, 0x08, 0xFB, 0xEB, + 0x44, 0x07, 0xF5, 0x82, 0x75, 0x83, 0xD2, 0xE0, +/*06E0*/0x44, 0x10, 0xF0, 0xE5, 0x08, 0xFB, 0xEB, 0x44, + 0x09, 0xF5, 0x82, 0x75, 0x83, 0x9E, 0xED, 0xF0, +/*06F0*/0xEB, 0x44, 0x07, 0xF5, 0x82, 0x75, 0x83, 0xCA, + 0xED, 0xF0, 0x12, 0x08, 0x65, 0x75, 0x83, 0xCC, +/*0700*/0xEF, 0xF0, 0x22, 0xE5, 0x08, 0x44, 0x07, 0xF5, + 0x82, 0x75, 0x83, 0xBC, 0xE0, 0x54, 0xF0, 0xF0, +/*0710*/0xE5, 0x08, 0x44, 0x07, 0xF5, 0x82, 0x75, 0x83, + 0xBE, 0xE0, 0x54, 0xF0, 0xF0, 0xE5, 0x08, 0x44, +/*0720*/0x07, 0xF5, 0x82, 0x75, 0x83, 0xC0, 0xE0, 0x54, + 0xF0, 0xF0, 0xE5, 0x08, 0x44, 0x07, 0xF5, 0x82, +/*0730*/0x22, 0xF0, 0x90, 0x07, 0x28, 0xE0, 0xFE, 0xA3, + 0xE0, 0xF5, 0x82, 0x8E, 0x83, 0x22, 0x85, 0x42, +/*0740*/0x42, 0x85, 0x41, 0x41, 0x85, 0x40, 0x40, 0x74, + 0xC0, 0x2F, 0xF5, 0x82, 0x74, 0x02, 0x3E, 0xF5, +/*0750*/0x83, 0xE5, 0x42, 0xF0, 0x74, 0xE0, 0x2F, 0xF5, + 0x82, 0x74, 0x02, 0x3E, 0xF5, 0x83, 0x22, 0xE5, +/*0760*/0x42, 0x29, 0xFD, 0xE4, 0x33, 0xFC, 0xE5, 0x3C, + 0xC3, 0x9D, 0xEC, 0x64, 0x80, 0xF8, 0x74, 0x80, +/*0770*/0x98, 0x22, 0xF5, 0x83, 0xE0, 0x90, 0x07, 0x22, + 0x54, 0x1F, 0xFD, 0xE0, 0xFA, 0xA3, 0xE0, 0xF5, +/*0780*/0x82, 0x8A, 0x83, 0xED, 0xF0, 0x22, 0x90, 0x07, + 0x22, 0xE0, 0xFC, 0xA3, 0xE0, 0xF5, 0x82, 0x8C, +/*0790*/0x83, 0x22, 0x90, 0x07, 0x24, 0xFF, 0xED, 0x44, + 0x07, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0x85, +/*07A0*/0x38, 0x38, 0x85, 0x39, 0x39, 0x85, 0x3A, 0x3A, + 0x74, 0xC0, 0x2F, 0xF5, 0x82, 0x74, 0x02, 0x3E, +/*07B0*/0xF5, 0x83, 0x22, 0x90, 0x07, 0x26, 0xFF, 0xED, + 0x44, 0x07, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, +/*07C0*/0xF0, 0x74, 0xA0, 0x2F, 0xF5, 0x82, 0x74, 0x02, + 0x3E, 0xF5, 0x83, 0x22, 0x74, 0xC0, 0x25, 0x11, +/*07D0*/0xF5, 0x82, 0xE4, 0x34, 0x01, 0xF5, 0x83, 0x22, + 0x74, 0x00, 0x25, 0x11, 0xF5, 0x82, 0xE4, 0x34, +/*07E0*/0x02, 0xF5, 0x83, 0x22, 0x74, 0x60, 0x25, 0x11, + 0xF5, 0x82, 0xE4, 0x34, 0x03, 0xF5, 0x83, 0x22, +/*07F0*/0x74, 0x80, 0x25, 0x11, 0xF5, 0x82, 0xE4, 0x34, + 0x03, 0xF5, 0x83, 0x22, 0x74, 0xE0, 0x25, 0x11, +/*0800*/0xF5, 0x82, 0xE4, 0x34, 0x03, 0xF5, 0x83, 0x22, + 0x74, 0x40, 0x25, 0x11, 0xF5, 0x82, 0xE4, 0x34, +/*0810*/0x06, 0xF5, 0x83, 0x22, 0x74, 0x80, 0x2F, 0xF5, + 0x82, 0x74, 0x02, 0x3E, 0xF5, 0x83, 0x22, 0xAF, +/*0820*/0x08, 0x7E, 0x00, 0xEF, 0x44, 0x07, 0xF5, 0x82, + 0x22, 0xF5, 0x83, 0xE5, 0x82, 0x44, 0x07, 0xF5, +/*0830*/0x82, 0xE5, 0x40, 0xF0, 0x22, 0x74, 0x40, 0x25, + 0x11, 0xF5, 0x82, 0xE4, 0x34, 0x02, 0xF5, 0x83, +/*0840*/0x22, 0x74, 0xC0, 0x25, 0x11, 0xF5, 0x82, 0xE4, + 0x34, 0x03, 0xF5, 0x83, 0x22, 0x74, 0x00, 0x25, +/*0850*/0x11, 0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, + 0x22, 0x74, 0x20, 0x25, 0x11, 0xF5, 0x82, 0xE4, +/*0860*/0x34, 0x06, 0xF5, 0x83, 0x22, 0xE5, 0x08, 0xFD, + 0xED, 0x44, 0x07, 0xF5, 0x82, 0x22, 0xE5, 0x41, +/*0870*/0xF0, 0xE5, 0x65, 0x64, 0x01, 0x45, 0x64, 0x22, + 0x7E, 0x00, 0xFB, 0x7A, 0x00, 0xFD, 0x7C, 0x00, +/*0880*/0x22, 0x74, 0x20, 0x25, 0x11, 0xF5, 0x82, 0xE4, + 0x34, 0x02, 0x22, 0x74, 0xA0, 0x25, 0x11, 0xF5, +/*0890*/0x82, 0xE4, 0x34, 0x03, 0x22, 0x85, 0x3E, 0x42, + 0x85, 0x3F, 0x41, 0x8F, 0x40, 0x22, 0x85, 0x3C, +/*08A0*/0x42, 0x85, 0x3D, 0x41, 0x8F, 0x40, 0x22, 0x75, + 0x45, 0x3F, 0x90, 0x07, 0x20, 0xE4, 0xF0, 0xA3, +/*08B0*/0x22, 0xF5, 0x83, 0xE5, 0x32, 0xF0, 0x05, 0x6E, + 0xE5, 0x6E, 0xC3, 0x94, 0x40, 0x22, 0xF0, 0xE5, +/*08C0*/0x08, 0x44, 0x06, 0xF5, 0x82, 0x22, 0x74, 0x00, + 0x25, 0x6E, 0xF5, 0x82, 0xE4, 0x34, 0x00, 0xF5, +/*08D0*/0x83, 0x22, 0xE5, 0x6D, 0x45, 0x6C, 0x90, 0x07, + 0x2F, 0x22, 0xE4, 0xF9, 0xE5, 0x3C, 0xD3, 0x95, +/*08E0*/0x3E, 0x22, 0x74, 0x80, 0x2E, 0xF5, 0x82, 0xE4, + 0x34, 0x02, 0xF5, 0x83, 0xE0, 0x22, 0x74, 0xA0, +/*08F0*/0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x02, 0xF5, 0x83, + 0xE0, 0x22, 0x74, 0x80, 0x25, 0x6E, 0xF5, 0x82, +/*0900*/0xE4, 0x34, 0x00, 0x22, 0x25, 0x42, 0xFD, 0xE4, + 0x33, 0xFC, 0x22, 0x85, 0x42, 0x42, 0x85, 0x41, +/*0910*/0x41, 0x85, 0x40, 0x40, 0x22, 0xED, 0x4C, 0x60, + 0x03, 0x02, 0x09, 0xE5, 0xEF, 0x4E, 0x70, 0x37, +/*0920*/0x90, 0x07, 0x26, 0x12, 0x07, 0x89, 0xE0, 0xFD, + 0x12, 0x07, 0xCC, 0xED, 0xF0, 0x90, 0x07, 0x28, +/*0930*/0x12, 0x07, 0x89, 0xE0, 0xFD, 0x12, 0x07, 0xD8, + 0xED, 0xF0, 0x12, 0x07, 0x86, 0xE0, 0x54, 0x1F, +/*0940*/0xFD, 0x12, 0x08, 0x81, 0xF5, 0x83, 0xED, 0xF0, + 0x90, 0x07, 0x24, 0x12, 0x07, 0x89, 0xE0, 0x54, +/*0950*/0x1F, 0xFD, 0x12, 0x08, 0x35, 0xED, 0xF0, 0xEF, + 0x64, 0x04, 0x4E, 0x70, 0x37, 0x90, 0x07, 0x26, +/*0960*/0x12, 0x07, 0x89, 0xE0, 0xFD, 0x12, 0x07, 0xE4, + 0xED, 0xF0, 0x90, 0x07, 0x28, 0x12, 0x07, 0x89, +/*0970*/0xE0, 0xFD, 0x12, 0x07, 0xF0, 0xED, 0xF0, 0x12, + 0x07, 0x86, 0xE0, 0x54, 0x1F, 0xFD, 0x12, 0x08, +/*0980*/0x8B, 0xF5, 0x83, 0xED, 0xF0, 0x90, 0x07, 0x24, + 0x12, 0x07, 0x89, 0xE0, 0x54, 0x1F, 0xFD, 0x12, +/*0990*/0x08, 0x41, 0xED, 0xF0, 0xEF, 0x64, 0x01, 0x4E, + 0x70, 0x04, 0x7D, 0x01, 0x80, 0x02, 0x7D, 0x00, +/*09A0*/0xEF, 0x64, 0x02, 0x4E, 0x70, 0x04, 0x7F, 0x01, + 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x4D, 0x60, 0x78, +/*09B0*/0x90, 0x07, 0x26, 0x12, 0x07, 0x35, 0xE0, 0xFF, + 0x12, 0x07, 0xFC, 0xEF, 0x12, 0x07, 0x31, 0xE0, +/*09C0*/0xFF, 0x12, 0x08, 0x08, 0xEF, 0xF0, 0x90, 0x07, + 0x22, 0x12, 0x07, 0x35, 0xE0, 0x54, 0x1F, 0xFF, +/*09D0*/0x12, 0x08, 0x4D, 0xEF, 0xF0, 0x90, 0x07, 0x24, + 0x12, 0x07, 0x35, 0xE0, 0x54, 0x1F, 0xFF, 0x12, +/*09E0*/0x08, 0x59, 0xEF, 0xF0, 0x22, 0x12, 0x07, 0xCC, + 0xE4, 0xF0, 0x12, 0x07, 0xD8, 0xE4, 0xF0, 0x12, +/*09F0*/0x08, 0x81, 0xF5, 0x83, 0xE4, 0xF0, 0x12, 0x08, + 0x35, 0x74, 0x14, 0xF0, 0x12, 0x07, 0xE4, 0xE4, +/*0A00*/0xF0, 0x12, 0x07, 0xF0, 0xE4, 0xF0, 0x12, 0x08, + 0x8B, 0xF5, 0x83, 0xE4, 0xF0, 0x12, 0x08, 0x41, +/*0A10*/0x74, 0x14, 0xF0, 0x12, 0x07, 0xFC, 0xE4, 0xF0, + 0x12, 0x08, 0x08, 0xE4, 0xF0, 0x12, 0x08, 0x4D, +/*0A20*/0xE4, 0xF0, 0x12, 0x08, 0x59, 0x74, 0x14, 0xF0, + 0x22, 0x53, 0xF9, 0xF7, 0x75, 0xFC, 0x10, 0xE4, +/*0A30*/0xF5, 0xFD, 0x75, 0xFE, 0x30, 0xF5, 0xFF, 0xE5, + 0xE7, 0x20, 0xE7, 0x03, 0x43, 0xF9, 0x08, 0xE5, +/*0A40*/0xE6, 0x20, 0xE7, 0x0B, 0x78, 0xFF, 0xE4, 0xF6, + 0xD8, 0xFD, 0x53, 0xE6, 0xFE, 0x80, 0x09, 0x78, +/*0A50*/0x08, 0xE4, 0xF6, 0xD8, 0xFD, 0x53, 0xE6, 0xFE, + 0x75, 0x81, 0x80, 0xE4, 0xF5, 0xA8, 0xD2, 0xA8, +/*0A60*/0xC2, 0xA9, 0xD2, 0xAF, 0xE5, 0xE2, 0x20, 0xE5, + 0x05, 0x20, 0xE6, 0x02, 0x80, 0x03, 0x43, 0xE1, +/*0A70*/0x02, 0xE5, 0xE2, 0x20, 0xE0, 0x0E, 0x90, 0x00, + 0x00, 0x7F, 0x00, 0x7E, 0x08, 0xE4, 0xF0, 0xA3, +/*0A80*/0xDF, 0xFC, 0xDE, 0xFA, 0x02, 0x0A, 0xDB, 0x43, + 0xFA, 0x01, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0x83, +/*0A90*/0xC0, 0x82, 0xC0, 0xD0, 0x12, 0x1C, 0xE7, 0xD0, + 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0, +/*0AA0*/0xE0, 0x53, 0xFA, 0xFE, 0x32, 0x02, 0x1B, 0x55, + 0xE4, 0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0xF6, +/*0AB0*/0x08, 0xDF, 0xF9, 0x80, 0x29, 0xE4, 0x93, 0xA3, + 0xF8, 0x54, 0x07, 0x24, 0x0C, 0xC8, 0xC3, 0x33, +/*0AC0*/0xC4, 0x54, 0x0F, 0x44, 0x20, 0xC8, 0x83, 0x40, + 0x04, 0xF4, 0x56, 0x80, 0x01, 0x46, 0xF6, 0xDF, +/*0AD0*/0xE4, 0x80, 0x0B, 0x01, 0x02, 0x04, 0x08, 0x10, + 0x20, 0x40, 0x80, 0x90, 0x00, 0x3F, 0xE4, 0x7E, +/*0AE0*/0x01, 0x93, 0x60, 0xC1, 0xA3, 0xFF, 0x54, 0x3F, + 0x30, 0xE5, 0x09, 0x54, 0x1F, 0xFE, 0xE4, 0x93, +/*0AF0*/0xA3, 0x60, 0x01, 0x0E, 0xCF, 0x54, 0xC0, 0x25, + 0xE0, 0x60, 0xAD, 0x40, 0xB8, 0x80, 0xFE, 0x8C, +/*0B00*/0x64, 0x8D, 0x65, 0x8A, 0x66, 0x8B, 0x67, 0xE4, + 0xF5, 0x69, 0xEF, 0x4E, 0x70, 0x03, 0x02, 0x1D, +/*0B10*/0x55, 0xE4, 0xF5, 0x68, 0xE5, 0x67, 0x45, 0x66, + 0x70, 0x32, 0x12, 0x07, 0x2A, 0x75, 0x83, 0x90, +/*0B20*/0xE4, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC2, 0xE4, + 0x12, 0x07, 0x29, 0x75, 0x83, 0xC4, 0xE4, 0x12, +/*0B30*/0x08, 0x70, 0x70, 0x29, 0x12, 0x07, 0x2A, 0x75, + 0x83, 0x92, 0xE4, 0x12, 0x07, 0x29, 0x75, 0x83, +/*0B40*/0xC6, 0xE4, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC8, + 0xE4, 0xF0, 0x80, 0x11, 0x90, 0x07, 0x26, 0x12, +/*0B50*/0x07, 0x35, 0xE4, 0x12, 0x08, 0x70, 0x70, 0x05, + 0x12, 0x07, 0x32, 0xE4, 0xF0, 0x12, 0x1D, 0x55, +/*0B60*/0x12, 0x1E, 0xBF, 0xE5, 0x67, 0x45, 0x66, 0x70, + 0x33, 0x12, 0x07, 0x2A, 0x75, 0x83, 0x90, 0xE5, +/*0B70*/0x41, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC2, 0xE5, + 0x41, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC4, 0x12, +/*0B80*/0x08, 0x6E, 0x70, 0x29, 0x12, 0x07, 0x2A, 0x75, + 0x83, 0x92, 0xE5, 0x40, 0x12, 0x07, 0x29, 0x75, +/*0B90*/0x83, 0xC6, 0xE5, 0x40, 0x12, 0x07, 0x29, 0x75, + 0x83, 0xC8, 0x80, 0x0E, 0x90, 0x07, 0x26, 0x12, +/*0BA0*/0x07, 0x35, 0x12, 0x08, 0x6E, 0x70, 0x06, 0x12, + 0x07, 0x32, 0xE5, 0x40, 0xF0, 0xAF, 0x69, 0x7E, +/*0BB0*/0x00, 0xAD, 0x67, 0xAC, 0x66, 0x12, 0x04, 0x44, + 0x12, 0x07, 0x2A, 0x75, 0x83, 0xCA, 0xE0, 0xD3, +/*0BC0*/0x94, 0x00, 0x50, 0x0C, 0x05, 0x68, 0xE5, 0x68, + 0xC3, 0x94, 0x05, 0x50, 0x03, 0x02, 0x0B, 0x14, +/*0BD0*/0x22, 0x8C, 0x60, 0x8D, 0x61, 0x12, 0x08, 0xDA, + 0x74, 0x20, 0x40, 0x0D, 0x2F, 0xF5, 0x82, 0x74, +/*0BE0*/0x03, 0x3E, 0xF5, 0x83, 0xE5, 0x3E, 0xF0, 0x80, + 0x0B, 0x2F, 0xF5, 0x82, 0x74, 0x03, 0x3E, 0xF5, +/*0BF0*/0x83, 0xE5, 0x3C, 0xF0, 0xE5, 0x3C, 0xD3, 0x95, + 0x3E, 0x40, 0x3C, 0xE5, 0x61, 0x45, 0x60, 0x70, +/*0C00*/0x10, 0xE9, 0x12, 0x09, 0x04, 0xE5, 0x3E, 0x12, + 0x07, 0x68, 0x40, 0x3B, 0x12, 0x08, 0x95, 0x80, +/*0C10*/0x18, 0xE5, 0x3E, 0xC3, 0x95, 0x38, 0x40, 0x1D, + 0x85, 0x3E, 0x38, 0xE5, 0x3E, 0x60, 0x05, 0x85, +/*0C20*/0x3F, 0x39, 0x80, 0x03, 0x85, 0x39, 0x39, 0x8F, + 0x3A, 0x12, 0x08, 0x14, 0xE5, 0x3E, 0x12, 0x07, +/*0C30*/0xC0, 0xE5, 0x3F, 0xF0, 0x22, 0x80, 0x43, 0xE5, + 0x61, 0x45, 0x60, 0x70, 0x19, 0x12, 0x07, 0x5F, +/*0C40*/0x40, 0x05, 0x12, 0x08, 0x9E, 0x80, 0x27, 0x12, + 0x09, 0x0B, 0x12, 0x08, 0x14, 0xE5, 0x42, 0x12, +/*0C50*/0x07, 0xC0, 0xE5, 0x41, 0xF0, 0x22, 0xE5, 0x3C, + 0xC3, 0x95, 0x38, 0x40, 0x1D, 0x85, 0x3C, 0x38, +/*0C60*/0xE5, 0x3C, 0x60, 0x05, 0x85, 0x3D, 0x39, 0x80, + 0x03, 0x85, 0x39, 0x39, 0x8F, 0x3A, 0x12, 0x08, +/*0C70*/0x14, 0xE5, 0x3C, 0x12, 0x07, 0xC0, 0xE5, 0x3D, + 0xF0, 0x22, 0x85, 0x38, 0x38, 0x85, 0x39, 0x39, +/*0C80*/0x85, 0x3A, 0x3A, 0x12, 0x08, 0x14, 0xE5, 0x38, + 0x12, 0x07, 0xC0, 0xE5, 0x39, 0xF0, 0x22, 0x7F, +/*0C90*/0x06, 0x12, 0x17, 0x31, 0x12, 0x1D, 0x23, 0x12, + 0x0E, 0x04, 0x12, 0x0E, 0x33, 0xE0, 0x44, 0x0A, +/*0CA0*/0xF0, 0x74, 0x8E, 0xFE, 0x12, 0x0E, 0x04, 0x12, + 0x0E, 0x0B, 0xEF, 0xF0, 0xE5, 0x28, 0x30, 0xE5, +/*0CB0*/0x03, 0xD3, 0x80, 0x01, 0xC3, 0x40, 0x05, 0x75, + 0x14, 0x20, 0x80, 0x03, 0x75, 0x14, 0x08, 0x12, +/*0CC0*/0x0E, 0x04, 0x75, 0x83, 0x8A, 0xE5, 0x14, 0xF0, + 0xB4, 0xFF, 0x05, 0x75, 0x12, 0x80, 0x80, 0x06, +/*0CD0*/0xE5, 0x14, 0xC3, 0x13, 0xF5, 0x12, 0xE4, 0xF5, + 0x16, 0xF5, 0x7F, 0x12, 0x19, 0x36, 0x12, 0x13, +/*0CE0*/0xA3, 0xE5, 0x0A, 0xC3, 0x94, 0x01, 0x50, 0x09, + 0x05, 0x16, 0xE5, 0x16, 0xC3, 0x94, 0x14, 0x40, +/*0CF0*/0xEA, 0xE5, 0xE4, 0x20, 0xE7, 0x28, 0x12, 0x0E, + 0x04, 0x75, 0x83, 0xD2, 0xE0, 0x54, 0x08, 0xD3, +/*0D00*/0x94, 0x00, 0x40, 0x04, 0x7F, 0x01, 0x80, 0x02, + 0x7F, 0x00, 0xE5, 0x0A, 0xC3, 0x94, 0x01, 0x40, +/*0D10*/0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEF, + 0x5E, 0x60, 0x03, 0x12, 0x1D, 0xD7, 0xE5, 0x7F, +/*0D20*/0xC3, 0x94, 0x11, 0x40, 0x14, 0x12, 0x0E, 0x04, + 0x75, 0x83, 0xD2, 0xE0, 0x44, 0x80, 0xF0, 0xE5, +/*0D30*/0xE4, 0x20, 0xE7, 0x0F, 0x12, 0x1D, 0xD7, 0x80, + 0x0A, 0x12, 0x0E, 0x04, 0x75, 0x83, 0xD2, 0xE0, +/*0D40*/0x54, 0x7F, 0xF0, 0x12, 0x1D, 0x23, 0x22, 0x74, + 0x8A, 0x85, 0x08, 0x82, 0xF5, 0x83, 0xE5, 0x17, +/*0D50*/0xF0, 0x12, 0x0E, 0x3A, 0xE4, 0xF0, 0x90, 0x07, + 0x02, 0xE0, 0x12, 0x0E, 0x17, 0x75, 0x83, 0x90, +/*0D60*/0xEF, 0xF0, 0x74, 0x92, 0xFE, 0xE5, 0x08, 0x44, + 0x07, 0xFF, 0xF5, 0x82, 0x8E, 0x83, 0xE0, 0x54, +/*0D70*/0xC0, 0xFD, 0x90, 0x07, 0x03, 0xE0, 0x54, 0x3F, + 0x4D, 0x8F, 0x82, 0x8E, 0x83, 0xF0, 0x90, 0x07, +/*0D80*/0x04, 0xE0, 0x12, 0x0E, 0x17, 0x75, 0x83, 0x82, + 0xEF, 0xF0, 0x90, 0x07, 0x05, 0xE0, 0xFF, 0xED, +/*0D90*/0x44, 0x07, 0xF5, 0x82, 0x75, 0x83, 0xB4, 0xEF, + 0x12, 0x0E, 0x03, 0x75, 0x83, 0x80, 0xE0, 0x54, +/*0DA0*/0xBF, 0xF0, 0x30, 0x37, 0x0A, 0x12, 0x0E, 0x91, + 0x75, 0x83, 0x94, 0xE0, 0x44, 0x80, 0xF0, 0x30, +/*0DB0*/0x38, 0x0A, 0x12, 0x0E, 0x91, 0x75, 0x83, 0x92, + 0xE0, 0x44, 0x80, 0xF0, 0xE5, 0x28, 0x30, 0xE4, +/*0DC0*/0x1A, 0x20, 0x39, 0x0A, 0x12, 0x0E, 0x04, 0x75, + 0x83, 0x88, 0xE0, 0x54, 0x7F, 0xF0, 0x20, 0x3A, +/*0DD0*/0x0A, 0x12, 0x0E, 0x04, 0x75, 0x83, 0x88, 0xE0, + 0x54, 0xBF, 0xF0, 0x74, 0x8C, 0xFE, 0x12, 0x0E, +/*0DE0*/0x04, 0x8E, 0x83, 0xE0, 0x54, 0x0F, 0x12, 0x0E, + 0x03, 0x75, 0x83, 0x86, 0xE0, 0x54, 0xBF, 0xF0, +/*0DF0*/0xE5, 0x08, 0x44, 0x06, 0x12, 0x0D, 0xFD, 0x75, + 0x83, 0x8A, 0xE4, 0xF0, 0x22, 0xF5, 0x82, 0x75, +/*0E00*/0x83, 0x82, 0xE4, 0xF0, 0xE5, 0x08, 0x44, 0x07, + 0xF5, 0x82, 0x22, 0x8E, 0x83, 0xE0, 0xF5, 0x10, +/*0E10*/0x54, 0xFE, 0xF0, 0xE5, 0x10, 0x44, 0x01, 0xFF, + 0xE5, 0x08, 0xFD, 0xED, 0x44, 0x07, 0xF5, 0x82, +/*0E20*/0x22, 0xE5, 0x15, 0xC4, 0x54, 0x07, 0xFF, 0xE5, + 0x08, 0xFD, 0xED, 0x44, 0x08, 0xF5, 0x82, 0x75, +/*0E30*/0x83, 0x82, 0x22, 0x75, 0x83, 0x80, 0xE0, 0x44, + 0x40, 0xF0, 0xE5, 0x08, 0x44, 0x08, 0xF5, 0x82, +/*0E40*/0x75, 0x83, 0x8A, 0x22, 0xE5, 0x16, 0x25, 0xE0, + 0x25, 0xE0, 0x24, 0xAF, 0xF5, 0x82, 0xE4, 0x34, +/*0E50*/0x1A, 0xF5, 0x83, 0xE4, 0x93, 0xF5, 0x0D, 0x22, + 0x43, 0xE1, 0x10, 0x43, 0xE1, 0x80, 0x53, 0xE1, +/*0E60*/0xFD, 0x85, 0xE1, 0x10, 0x22, 0xE5, 0x16, 0x25, + 0xE0, 0x25, 0xE0, 0x24, 0xB2, 0xF5, 0x82, 0xE4, +/*0E70*/0x34, 0x1A, 0xF5, 0x83, 0xE4, 0x93, 0x22, 0x85, + 0x55, 0x82, 0x85, 0x54, 0x83, 0xE5, 0x15, 0xF0, +/*0E80*/0x22, 0xE5, 0xE2, 0x54, 0x20, 0xD3, 0x94, 0x00, + 0x22, 0xE5, 0xE2, 0x54, 0x40, 0xD3, 0x94, 0x00, +/*0E90*/0x22, 0xE5, 0x08, 0x44, 0x06, 0xF5, 0x82, 0x22, + 0xFD, 0xE5, 0x08, 0xFB, 0xEB, 0x44, 0x07, 0xF5, +/*0EA0*/0x82, 0x22, 0x53, 0xF9, 0xF7, 0x75, 0xFE, 0x30, + 0x22, 0xEF, 0x4E, 0x70, 0x26, 0x12, 0x07, 0xCC, +/*0EB0*/0xE0, 0xFD, 0x90, 0x07, 0x26, 0x12, 0x07, 0x7B, + 0x12, 0x07, 0xD8, 0xE0, 0xFD, 0x90, 0x07, 0x28, +/*0EC0*/0x12, 0x07, 0x7B, 0x12, 0x08, 0x81, 0x12, 0x07, + 0x72, 0x12, 0x08, 0x35, 0xE0, 0x90, 0x07, 0x24, +/*0ED0*/0x12, 0x07, 0x78, 0xEF, 0x64, 0x04, 0x4E, 0x70, + 0x29, 0x12, 0x07, 0xE4, 0xE0, 0xFD, 0x90, 0x07, +/*0EE0*/0x26, 0x12, 0x07, 0x7B, 0x12, 0x07, 0xF0, 0xE0, + 0xFD, 0x90, 0x07, 0x28, 0x12, 0x07, 0x7B, 0x12, +/*0EF0*/0x08, 0x8B, 0x12, 0x07, 0x72, 0x12, 0x08, 0x41, + 0xE0, 0x54, 0x1F, 0xFD, 0x90, 0x07, 0x24, 0x12, +/*0F00*/0x07, 0x7B, 0xEF, 0x64, 0x01, 0x4E, 0x70, 0x04, + 0x7D, 0x01, 0x80, 0x02, 0x7D, 0x00, 0xEF, 0x64, +/*0F10*/0x02, 0x4E, 0x70, 0x04, 0x7F, 0x01, 0x80, 0x02, + 0x7F, 0x00, 0xEF, 0x4D, 0x60, 0x35, 0x12, 0x07, +/*0F20*/0xFC, 0xE0, 0xFF, 0x90, 0x07, 0x26, 0x12, 0x07, + 0x89, 0xEF, 0xF0, 0x12, 0x08, 0x08, 0xE0, 0xFF, +/*0F30*/0x90, 0x07, 0x28, 0x12, 0x07, 0x89, 0xEF, 0xF0, + 0x12, 0x08, 0x4D, 0xE0, 0x54, 0x1F, 0xFF, 0x12, +/*0F40*/0x07, 0x86, 0xEF, 0xF0, 0x12, 0x08, 0x59, 0xE0, + 0x54, 0x1F, 0xFF, 0x90, 0x07, 0x24, 0x12, 0x07, +/*0F50*/0x89, 0xEF, 0xF0, 0x22, 0xE4, 0xF5, 0x53, 0x12, + 0x0E, 0x81, 0x40, 0x04, 0x7F, 0x01, 0x80, 0x02, +/*0F60*/0x7F, 0x00, 0x12, 0x0E, 0x89, 0x40, 0x04, 0x7E, + 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE, 0x4F, 0x70, +/*0F70*/0x03, 0x02, 0x0F, 0xF6, 0x85, 0xE1, 0x10, 0x43, + 0xE1, 0x02, 0x53, 0xE1, 0x0F, 0x85, 0xE1, 0x10, +/*0F80*/0xE4, 0xF5, 0x51, 0xE5, 0xE3, 0x54, 0x3F, 0xF5, + 0x52, 0x12, 0x0E, 0x89, 0x40, 0x1D, 0xAD, 0x52, +/*0F90*/0xAF, 0x51, 0x12, 0x11, 0x18, 0xEF, 0x60, 0x08, + 0x85, 0xE1, 0x10, 0x43, 0xE1, 0x40, 0x80, 0x0B, +/*0FA0*/0x53, 0xE1, 0xBF, 0x12, 0x0E, 0x58, 0x12, 0x00, + 0x06, 0x80, 0xFB, 0xE5, 0xE3, 0x54, 0x3F, 0xF5, +/*0FB0*/0x51, 0xE5, 0xE4, 0x54, 0x3F, 0xF5, 0x52, 0x12, + 0x0E, 0x81, 0x40, 0x1D, 0xAD, 0x52, 0xAF, 0x51, +/*0FC0*/0x12, 0x11, 0x18, 0xEF, 0x60, 0x08, 0x85, 0xE1, + 0x10, 0x43, 0xE1, 0x20, 0x80, 0x0B, 0x53, 0xE1, +/*0FD0*/0xDF, 0x12, 0x0E, 0x58, 0x12, 0x00, 0x06, 0x80, + 0xFB, 0x12, 0x0E, 0x81, 0x40, 0x04, 0x7F, 0x01, +/*0FE0*/0x80, 0x02, 0x7F, 0x00, 0x12, 0x0E, 0x89, 0x40, + 0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE, +/*0FF0*/0x4F, 0x60, 0x03, 0x12, 0x0E, 0x5B, 0x22, 0x12, + 0x0E, 0x21, 0xEF, 0xF0, 0x12, 0x10, 0x91, 0x22, +/*1000*/0x02, 0x11, 0x00, 0x02, 0x10, 0x40, 0x02, 0x10, + 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/*1010*/0x01, 0x20, 0x01, 0x20, 0xE4, 0xF5, 0x57, 0x12, + 0x16, 0xBD, 0x12, 0x16, 0x44, 0xE4, 0x12, 0x10, +/*1020*/0x56, 0x12, 0x14, 0xB7, 0x90, 0x07, 0x26, 0x12, + 0x07, 0x35, 0xE4, 0x12, 0x07, 0x31, 0xE4, 0xF0, +/*1030*/0x12, 0x10, 0x56, 0x12, 0x14, 0xB7, 0x90, 0x07, + 0x26, 0x12, 0x07, 0x35, 0xE5, 0x41, 0x12, 0x07, +/*1040*/0x31, 0xE5, 0x40, 0xF0, 0xAF, 0x57, 0x7E, 0x00, + 0xAD, 0x56, 0x7C, 0x00, 0x12, 0x04, 0x44, 0xAF, +/*1050*/0x56, 0x7E, 0x00, 0x02, 0x11, 0xEE, 0xFF, 0x90, + 0x07, 0x20, 0xA3, 0xE0, 0xFD, 0xE4, 0xF5, 0x56, +/*1060*/0xF5, 0x40, 0xFE, 0xFC, 0xAB, 0x56, 0xFA, 0x12, + 0x11, 0x51, 0x7F, 0x0F, 0x7D, 0x18, 0xE4, 0xF5, +/*1070*/0x56, 0xF5, 0x40, 0xFE, 0xFC, 0xAB, 0x56, 0xFA, + 0x12, 0x15, 0x41, 0xAF, 0x56, 0x7E, 0x00, 0x12, +/*1080*/0x1A, 0xFF, 0xE4, 0xFF, 0xF5, 0x56, 0x7D, 0x1F, + 0xF5, 0x40, 0xFE, 0xFC, 0xAB, 0x56, 0xFA, 0x22, +/*1090*/0x22, 0xE4, 0xF5, 0x55, 0xE5, 0x08, 0xFD, 0x74, + 0xA0, 0xF5, 0x56, 0xED, 0x44, 0x07, 0xF5, 0x57, +/*10A0*/0xE5, 0x28, 0x30, 0xE5, 0x03, 0xD3, 0x80, 0x01, + 0xC3, 0x40, 0x05, 0x7F, 0x28, 0xEF, 0x80, 0x04, +/*10B0*/0x7F, 0x14, 0xEF, 0xC3, 0x13, 0xF5, 0x54, 0xE4, + 0xF9, 0x12, 0x0E, 0x18, 0x75, 0x83, 0x8E, 0xE0, +/*10C0*/0xF5, 0x10, 0xCE, 0xEF, 0xCE, 0xEE, 0xD3, 0x94, + 0x00, 0x40, 0x26, 0xE5, 0x10, 0x54, 0xFE, 0x12, +/*10D0*/0x0E, 0x98, 0x75, 0x83, 0x8E, 0xED, 0xF0, 0xE5, + 0x10, 0x44, 0x01, 0xFD, 0xEB, 0x44, 0x07, 0xF5, +/*10E0*/0x82, 0xED, 0xF0, 0x85, 0x57, 0x82, 0x85, 0x56, + 0x83, 0xE0, 0x30, 0xE3, 0x01, 0x09, 0x1E, 0x80, +/*10F0*/0xD4, 0xC2, 0x34, 0xE9, 0xC3, 0x95, 0x54, 0x40, + 0x02, 0xD2, 0x34, 0x22, 0x02, 0x00, 0x06, 0x22, +/*1100*/0x30, 0x30, 0x11, 0x90, 0x10, 0x00, 0xE4, 0x93, + 0xF5, 0x10, 0x90, 0x10, 0x10, 0xE4, 0x93, 0xF5, +/*1110*/0x10, 0x12, 0x10, 0x90, 0x12, 0x11, 0x50, 0x22, + 0xE4, 0xFC, 0xC3, 0xED, 0x9F, 0xFA, 0xEF, 0xF5, +/*1120*/0x83, 0x75, 0x82, 0x00, 0x79, 0xFF, 0xE4, 0x93, + 0xCC, 0x6C, 0xCC, 0xA3, 0xD9, 0xF8, 0xDA, 0xF6, +/*1130*/0xE5, 0xE2, 0x30, 0xE4, 0x02, 0x8C, 0xE5, 0xED, + 0x24, 0xFF, 0xFF, 0xEF, 0x75, 0x82, 0xFF, 0xF5, +/*1140*/0x83, 0xE4, 0x93, 0x6C, 0x70, 0x03, 0x7F, 0x01, + 0x22, 0x7F, 0x00, 0x22, 0x22, 0x11, 0x00, 0x00, +/*1150*/0x22, 0x8E, 0x58, 0x8F, 0x59, 0x8C, 0x5A, 0x8D, + 0x5B, 0x8A, 0x5C, 0x8B, 0x5D, 0x75, 0x5E, 0x01, +/*1160*/0xE4, 0xF5, 0x5F, 0xF5, 0x60, 0xF5, 0x62, 0x12, + 0x07, 0x2A, 0x75, 0x83, 0xD0, 0xE0, 0xFF, 0xC4, +/*1170*/0x54, 0x0F, 0xF5, 0x61, 0x12, 0x1E, 0xA5, 0x85, + 0x59, 0x5E, 0xD3, 0xE5, 0x5E, 0x95, 0x5B, 0xE5, +/*1180*/0x5A, 0x12, 0x07, 0x6B, 0x50, 0x4B, 0x12, 0x07, + 0x03, 0x75, 0x83, 0xBC, 0xE0, 0x45, 0x5E, 0x12, +/*1190*/0x07, 0x29, 0x75, 0x83, 0xBE, 0xE0, 0x45, 0x5E, + 0x12, 0x07, 0x29, 0x75, 0x83, 0xC0, 0xE0, 0x45, +/*11A0*/0x5E, 0xF0, 0xAF, 0x5F, 0xE5, 0x60, 0x12, 0x08, + 0x78, 0x12, 0x0A, 0xFF, 0xAF, 0x62, 0x7E, 0x00, +/*11B0*/0xAD, 0x5D, 0xAC, 0x5C, 0x12, 0x04, 0x44, 0xE5, + 0x61, 0xAF, 0x5E, 0x7E, 0x00, 0xB4, 0x03, 0x05, +/*11C0*/0x12, 0x1E, 0x21, 0x80, 0x07, 0xAD, 0x5D, 0xAC, + 0x5C, 0x12, 0x13, 0x17, 0x05, 0x5E, 0x02, 0x11, +/*11D0*/0x7A, 0x12, 0x07, 0x03, 0x75, 0x83, 0xBC, 0xE0, + 0x45, 0x40, 0x12, 0x07, 0x29, 0x75, 0x83, 0xBE, +/*11E0*/0xE0, 0x45, 0x40, 0x12, 0x07, 0x29, 0x75, 0x83, + 0xC0, 0xE0, 0x45, 0x40, 0xF0, 0x22, 0x8E, 0x58, +/*11F0*/0x8F, 0x59, 0x75, 0x5A, 0x01, 0x79, 0x01, 0x75, + 0x5B, 0x01, 0xE4, 0xFB, 0x12, 0x07, 0x2A, 0x75, +/*1200*/0x83, 0xAE, 0xE0, 0x54, 0x1A, 0xFF, 0x12, 0x08, + 0x65, 0xE0, 0xC4, 0x13, 0x54, 0x07, 0xFE, 0xEF, +/*1210*/0x70, 0x0C, 0xEE, 0x65, 0x35, 0x70, 0x07, 0x90, + 0x07, 0x2F, 0xE0, 0xB4, 0x01, 0x0D, 0xAF, 0x35, +/*1220*/0x7E, 0x00, 0x12, 0x0E, 0xA9, 0xCF, 0xEB, 0xCF, + 0x02, 0x1E, 0x60, 0xE5, 0x59, 0x64, 0x02, 0x45, +/*1230*/0x58, 0x70, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, + 0x00, 0xE5, 0x59, 0x45, 0x58, 0x70, 0x04, 0x7E, +/*1240*/0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE, 0x4F, 0x60, + 0x23, 0x85, 0x41, 0x49, 0x85, 0x40, 0x4B, 0xE5, +/*1250*/0x59, 0x45, 0x58, 0x70, 0x2C, 0xAF, 0x5A, 0xFE, + 0xCD, 0xE9, 0xCD, 0xFC, 0xAB, 0x59, 0xAA, 0x58, +/*1260*/0x12, 0x0A, 0xFF, 0xAF, 0x5B, 0x7E, 0x00, 0x12, + 0x1E, 0x60, 0x80, 0x15, 0xAF, 0x5B, 0x7E, 0x00, +/*1270*/0x12, 0x1E, 0x60, 0x90, 0x07, 0x26, 0x12, 0x07, + 0x35, 0xE5, 0x49, 0x12, 0x07, 0x31, 0xE5, 0x4B, +/*1280*/0xF0, 0xE4, 0xFD, 0xAF, 0x35, 0xFE, 0xFC, 0x12, + 0x09, 0x15, 0x22, 0x8C, 0x64, 0x8D, 0x65, 0x12, +/*1290*/0x08, 0xDA, 0x40, 0x3C, 0xE5, 0x65, 0x45, 0x64, + 0x70, 0x10, 0x12, 0x09, 0x04, 0xC3, 0xE5, 0x3E, +/*12A0*/0x12, 0x07, 0x69, 0x40, 0x3B, 0x12, 0x08, 0x95, + 0x80, 0x18, 0xE5, 0x3E, 0xC3, 0x95, 0x38, 0x40, +/*12B0*/0x1D, 0x85, 0x3E, 0x38, 0xE5, 0x3E, 0x60, 0x05, + 0x85, 0x3F, 0x39, 0x80, 0x03, 0x85, 0x39, 0x39, +/*12C0*/0x8F, 0x3A, 0x12, 0x07, 0xA8, 0xE5, 0x3E, 0x12, + 0x07, 0x53, 0xE5, 0x3F, 0xF0, 0x22, 0x80, 0x3B, +/*12D0*/0xE5, 0x65, 0x45, 0x64, 0x70, 0x11, 0x12, 0x07, + 0x5F, 0x40, 0x05, 0x12, 0x08, 0x9E, 0x80, 0x1F, +/*12E0*/0x12, 0x07, 0x3E, 0xE5, 0x41, 0xF0, 0x22, 0xE5, + 0x3C, 0xC3, 0x95, 0x38, 0x40, 0x1D, 0x85, 0x3C, +/*12F0*/0x38, 0xE5, 0x3C, 0x60, 0x05, 0x85, 0x3D, 0x39, + 0x80, 0x03, 0x85, 0x39, 0x39, 0x8F, 0x3A, 0x12, +/*1300*/0x07, 0xA8, 0xE5, 0x3C, 0x12, 0x07, 0x53, 0xE5, + 0x3D, 0xF0, 0x22, 0x12, 0x07, 0x9F, 0xE5, 0x38, +/*1310*/0x12, 0x07, 0x53, 0xE5, 0x39, 0xF0, 0x22, 0x8C, + 0x63, 0x8D, 0x64, 0x12, 0x08, 0xDA, 0x40, 0x3C, +/*1320*/0xE5, 0x64, 0x45, 0x63, 0x70, 0x10, 0x12, 0x09, + 0x04, 0xC3, 0xE5, 0x3E, 0x12, 0x07, 0x69, 0x40, +/*1330*/0x3B, 0x12, 0x08, 0x95, 0x80, 0x18, 0xE5, 0x3E, + 0xC3, 0x95, 0x38, 0x40, 0x1D, 0x85, 0x3E, 0x38, +/*1340*/0xE5, 0x3E, 0x60, 0x05, 0x85, 0x3F, 0x39, 0x80, + 0x03, 0x85, 0x39, 0x39, 0x8F, 0x3A, 0x12, 0x07, +/*1350*/0xA8, 0xE5, 0x3E, 0x12, 0x07, 0x53, 0xE5, 0x3F, + 0xF0, 0x22, 0x80, 0x3B, 0xE5, 0x64, 0x45, 0x63, +/*1360*/0x70, 0x11, 0x12, 0x07, 0x5F, 0x40, 0x05, 0x12, + 0x08, 0x9E, 0x80, 0x1F, 0x12, 0x07, 0x3E, 0xE5, +/*1370*/0x41, 0xF0, 0x22, 0xE5, 0x3C, 0xC3, 0x95, 0x38, + 0x40, 0x1D, 0x85, 0x3C, 0x38, 0xE5, 0x3C, 0x60, +/*1380*/0x05, 0x85, 0x3D, 0x39, 0x80, 0x03, 0x85, 0x39, + 0x39, 0x8F, 0x3A, 0x12, 0x07, 0xA8, 0xE5, 0x3C, +/*1390*/0x12, 0x07, 0x53, 0xE5, 0x3D, 0xF0, 0x22, 0x12, + 0x07, 0x9F, 0xE5, 0x38, 0x12, 0x07, 0x53, 0xE5, +/*13A0*/0x39, 0xF0, 0x22, 0xE5, 0x0D, 0xFE, 0xE5, 0x08, + 0x8E, 0x54, 0x44, 0x05, 0xF5, 0x55, 0x75, 0x15, +/*13B0*/0x0F, 0xF5, 0x82, 0x12, 0x0E, 0x7A, 0x12, 0x17, + 0xA3, 0x20, 0x31, 0x05, 0x75, 0x15, 0x03, 0x80, +/*13C0*/0x03, 0x75, 0x15, 0x0B, 0xE5, 0x0A, 0xC3, 0x94, + 0x01, 0x50, 0x38, 0x12, 0x14, 0x20, 0x20, 0x31, +/*13D0*/0x06, 0x05, 0x15, 0x05, 0x15, 0x80, 0x04, 0x15, + 0x15, 0x15, 0x15, 0xE5, 0x0A, 0xC3, 0x94, 0x01, +/*13E0*/0x50, 0x21, 0x12, 0x14, 0x20, 0x20, 0x31, 0x04, + 0x05, 0x15, 0x80, 0x02, 0x15, 0x15, 0xE5, 0x0A, +/*13F0*/0xC3, 0x94, 0x01, 0x50, 0x0E, 0x12, 0x0E, 0x77, + 0x12, 0x17, 0xA3, 0x20, 0x31, 0x05, 0x05, 0x15, +/*1400*/0x12, 0x0E, 0x77, 0xE5, 0x15, 0xB4, 0x08, 0x04, + 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xE5, 0x15, +/*1410*/0xB4, 0x07, 0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, + 0x00, 0xEE, 0x4F, 0x60, 0x02, 0x05, 0x7F, 0x22, +/*1420*/0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xE5, 0x15, + 0xF0, 0x12, 0x17, 0xA3, 0x22, 0x12, 0x07, 0x2A, +/*1430*/0x75, 0x83, 0xAE, 0x74, 0xFF, 0x12, 0x07, 0x29, + 0xE0, 0x54, 0x1A, 0xF5, 0x34, 0xE0, 0xC4, 0x13, +/*1440*/0x54, 0x07, 0xF5, 0x35, 0x24, 0xFE, 0x60, 0x24, + 0x24, 0xFE, 0x60, 0x3C, 0x24, 0x04, 0x70, 0x63, +/*1450*/0x75, 0x31, 0x2D, 0xE5, 0x08, 0xFD, 0x74, 0xB6, + 0x12, 0x07, 0x92, 0x74, 0xBC, 0x90, 0x07, 0x22, +/*1460*/0x12, 0x07, 0x95, 0x74, 0x90, 0x12, 0x07, 0xB3, + 0x74, 0x92, 0x80, 0x3C, 0x75, 0x31, 0x3A, 0xE5, +/*1470*/0x08, 0xFD, 0x74, 0xBA, 0x12, 0x07, 0x92, 0x74, + 0xC0, 0x90, 0x07, 0x22, 0x12, 0x07, 0xB6, 0x74, +/*1480*/0xC4, 0x12, 0x07, 0xB3, 0x74, 0xC8, 0x80, 0x20, + 0x75, 0x31, 0x35, 0xE5, 0x08, 0xFD, 0x74, 0xB8, +/*1490*/0x12, 0x07, 0x92, 0x74, 0xBE, 0xFF, 0xED, 0x44, + 0x07, 0x90, 0x07, 0x22, 0xCF, 0xF0, 0xA3, 0xEF, +/*14A0*/0xF0, 0x74, 0xC2, 0x12, 0x07, 0xB3, 0x74, 0xC6, + 0xFF, 0xED, 0x44, 0x07, 0xA3, 0xCF, 0xF0, 0xA3, +/*14B0*/0xEF, 0xF0, 0x22, 0x75, 0x34, 0x01, 0x22, 0x8E, + 0x58, 0x8F, 0x59, 0x8C, 0x5A, 0x8D, 0x5B, 0x8A, +/*14C0*/0x5C, 0x8B, 0x5D, 0x75, 0x5E, 0x01, 0xE4, 0xF5, + 0x5F, 0x12, 0x1E, 0xA5, 0x85, 0x59, 0x5E, 0xD3, +/*14D0*/0xE5, 0x5E, 0x95, 0x5B, 0xE5, 0x5A, 0x12, 0x07, + 0x6B, 0x50, 0x57, 0xE5, 0x5D, 0x45, 0x5C, 0x70, +/*14E0*/0x30, 0x12, 0x07, 0x2A, 0x75, 0x83, 0x92, 0xE5, + 0x5E, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC6, 0xE5, +/*14F0*/0x5E, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC8, 0xE5, + 0x5E, 0x12, 0x07, 0x29, 0x75, 0x83, 0x90, 0xE5, +/*1500*/0x5E, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC2, 0xE5, + 0x5E, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC4, 0x80, +/*1510*/0x03, 0x12, 0x07, 0x32, 0xE5, 0x5E, 0xF0, 0xAF, + 0x5F, 0x7E, 0x00, 0xAD, 0x5D, 0xAC, 0x5C, 0x12, +/*1520*/0x04, 0x44, 0xAF, 0x5E, 0x7E, 0x00, 0xAD, 0x5D, + 0xAC, 0x5C, 0x12, 0x0B, 0xD1, 0x05, 0x5E, 0x02, +/*1530*/0x14, 0xCF, 0xAB, 0x5D, 0xAA, 0x5C, 0xAD, 0x5B, + 0xAC, 0x5A, 0xAF, 0x59, 0xAE, 0x58, 0x02, 0x1B, +/*1540*/0xFB, 0x8C, 0x5C, 0x8D, 0x5D, 0x8A, 0x5E, 0x8B, + 0x5F, 0x75, 0x60, 0x01, 0xE4, 0xF5, 0x61, 0xF5, +/*1550*/0x62, 0xF5, 0x63, 0x12, 0x1E, 0xA5, 0x8F, 0x60, + 0xD3, 0xE5, 0x60, 0x95, 0x5D, 0xE5, 0x5C, 0x12, +/*1560*/0x07, 0x6B, 0x50, 0x61, 0xE5, 0x5F, 0x45, 0x5E, + 0x70, 0x27, 0x12, 0x07, 0x2A, 0x75, 0x83, 0xB6, +/*1570*/0xE5, 0x60, 0x12, 0x07, 0x29, 0x75, 0x83, 0xB8, + 0xE5, 0x60, 0x12, 0x07, 0x29, 0x75, 0x83, 0xBA, +/*1580*/0xE5, 0x60, 0xF0, 0xAF, 0x61, 0x7E, 0x00, 0xE5, + 0x62, 0x12, 0x08, 0x7A, 0x12, 0x0A, 0xFF, 0x80, +/*1590*/0x19, 0x90, 0x07, 0x24, 0x12, 0x07, 0x35, 0xE5, + 0x60, 0x12, 0x07, 0x29, 0x75, 0x83, 0x8E, 0xE4, +/*15A0*/0x12, 0x07, 0x29, 0x74, 0x01, 0x12, 0x07, 0x29, + 0xE4, 0xF0, 0xAF, 0x63, 0x7E, 0x00, 0xAD, 0x5F, +/*15B0*/0xAC, 0x5E, 0x12, 0x04, 0x44, 0xAF, 0x60, 0x7E, + 0x00, 0xAD, 0x5F, 0xAC, 0x5E, 0x12, 0x12, 0x8B, +/*15C0*/0x05, 0x60, 0x02, 0x15, 0x58, 0x22, 0x90, 0x11, + 0x4D, 0xE4, 0x93, 0x90, 0x07, 0x2E, 0xF0, 0x12, +/*15D0*/0x08, 0x1F, 0x75, 0x83, 0xAE, 0xE0, 0x54, 0x1A, + 0xF5, 0x34, 0x70, 0x67, 0xEF, 0x44, 0x07, 0xF5, +/*15E0*/0x82, 0x75, 0x83, 0xCE, 0xE0, 0xFF, 0x13, 0x13, + 0x13, 0x54, 0x07, 0xF5, 0x36, 0x54, 0x0F, 0xD3, +/*15F0*/0x94, 0x00, 0x40, 0x06, 0x12, 0x14, 0x2D, 0x12, + 0x1B, 0xA9, 0xE5, 0x36, 0x54, 0x0F, 0x24, 0xFE, +/*1600*/0x60, 0x0C, 0x14, 0x60, 0x0C, 0x14, 0x60, 0x19, + 0x24, 0x03, 0x70, 0x37, 0x80, 0x10, 0x02, 0x1E, +/*1610*/0x91, 0x12, 0x1E, 0x91, 0x12, 0x07, 0x2A, 0x75, + 0x83, 0xCE, 0xE0, 0x54, 0xEF, 0xF0, 0x02, 0x1D, +/*1620*/0xAE, 0x12, 0x10, 0x14, 0xE4, 0xF5, 0x55, 0x12, + 0x1D, 0x85, 0x05, 0x55, 0xE5, 0x55, 0xC3, 0x94, +/*1630*/0x05, 0x40, 0xF4, 0x12, 0x07, 0x2A, 0x75, 0x83, + 0xCE, 0xE0, 0x54, 0xC7, 0x12, 0x07, 0x29, 0xE0, +/*1640*/0x44, 0x08, 0xF0, 0x22, 0xE4, 0xF5, 0x58, 0xF5, + 0x59, 0xAF, 0x08, 0xEF, 0x44, 0x07, 0xF5, 0x82, +/*1650*/0x75, 0x83, 0xD0, 0xE0, 0xFD, 0xC4, 0x54, 0x0F, + 0xF5, 0x5A, 0xEF, 0x44, 0x07, 0xF5, 0x82, 0x75, +/*1660*/0x83, 0x80, 0x74, 0x01, 0xF0, 0x12, 0x08, 0x21, + 0x75, 0x83, 0x82, 0xE5, 0x45, 0xF0, 0xEF, 0x44, +/*1670*/0x07, 0xF5, 0x82, 0x75, 0x83, 0x8A, 0x74, 0xFF, + 0xF0, 0x12, 0x1A, 0x4D, 0x12, 0x07, 0x2A, 0x75, +/*1680*/0x83, 0xBC, 0xE0, 0x54, 0xEF, 0x12, 0x07, 0x29, + 0x75, 0x83, 0xBE, 0xE0, 0x54, 0xEF, 0x12, 0x07, +/*1690*/0x29, 0x75, 0x83, 0xC0, 0xE0, 0x54, 0xEF, 0x12, + 0x07, 0x29, 0x75, 0x83, 0xBC, 0xE0, 0x44, 0x10, +/*16A0*/0x12, 0x07, 0x29, 0x75, 0x83, 0xBE, 0xE0, 0x44, + 0x10, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC0, 0xE0, +/*16B0*/0x44, 0x10, 0xF0, 0xAF, 0x58, 0xE5, 0x59, 0x12, + 0x08, 0x78, 0x02, 0x0A, 0xFF, 0xE4, 0xF5, 0x58, +/*16C0*/0x7D, 0x01, 0xF5, 0x59, 0xAF, 0x35, 0xFE, 0xFC, + 0x12, 0x09, 0x15, 0x12, 0x07, 0x2A, 0x75, 0x83, +/*16D0*/0xB6, 0x74, 0x10, 0x12, 0x07, 0x29, 0x75, 0x83, + 0xB8, 0x74, 0x10, 0x12, 0x07, 0x29, 0x75, 0x83, +/*16E0*/0xBA, 0x74, 0x10, 0x12, 0x07, 0x29, 0x75, 0x83, + 0xBC, 0x74, 0x10, 0x12, 0x07, 0x29, 0x75, 0x83, +/*16F0*/0xBE, 0x74, 0x10, 0x12, 0x07, 0x29, 0x75, 0x83, + 0xC0, 0x74, 0x10, 0x12, 0x07, 0x29, 0x75, 0x83, +/*1700*/0x90, 0xE4, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC2, + 0xE4, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC4, 0xE4, +/*1710*/0x12, 0x07, 0x29, 0x75, 0x83, 0x92, 0xE4, 0x12, + 0x07, 0x29, 0x75, 0x83, 0xC6, 0xE4, 0x12, 0x07, +/*1720*/0x29, 0x75, 0x83, 0xC8, 0xE4, 0xF0, 0xAF, 0x58, + 0xFE, 0xE5, 0x59, 0x12, 0x08, 0x7A, 0x02, 0x0A, +/*1730*/0xFF, 0xE5, 0xE2, 0x30, 0xE4, 0x6C, 0xE5, 0xE7, + 0x54, 0xC0, 0x64, 0x40, 0x70, 0x64, 0xE5, 0x09, +/*1740*/0xC4, 0x54, 0x30, 0xFE, 0xE5, 0x08, 0x25, 0xE0, + 0x25, 0xE0, 0x54, 0xC0, 0x4E, 0xFE, 0xEF, 0x54, +/*1750*/0x3F, 0x4E, 0xFD, 0xE5, 0x2B, 0xAE, 0x2A, 0x78, + 0x02, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, +/*1760*/0xF5, 0x82, 0x8E, 0x83, 0xED, 0xF0, 0xE5, 0x2B, + 0xAE, 0x2A, 0x78, 0x02, 0xC3, 0x33, 0xCE, 0x33, +/*1770*/0xCE, 0xD8, 0xF9, 0xFF, 0xF5, 0x82, 0x8E, 0x83, + 0xA3, 0xE5, 0xFE, 0xF0, 0x8F, 0x82, 0x8E, 0x83, +/*1780*/0xA3, 0xA3, 0xE5, 0xFD, 0xF0, 0x8F, 0x82, 0x8E, + 0x83, 0xA3, 0xA3, 0xA3, 0xE5, 0xFC, 0xF0, 0xC3, +/*1790*/0xE5, 0x2B, 0x94, 0xFA, 0xE5, 0x2A, 0x94, 0x00, + 0x50, 0x08, 0x05, 0x2B, 0xE5, 0x2B, 0x70, 0x02, +/*17A0*/0x05, 0x2A, 0x22, 0xE4, 0xFF, 0xE4, 0xF5, 0x58, + 0xF5, 0x56, 0xF5, 0x57, 0x74, 0x82, 0xFC, 0x12, +/*17B0*/0x0E, 0x04, 0x8C, 0x83, 0xE0, 0xF5, 0x10, 0x54, + 0x7F, 0xF0, 0xE5, 0x10, 0x44, 0x80, 0x12, 0x0E, +/*17C0*/0x98, 0xED, 0xF0, 0x7E, 0x0A, 0x12, 0x0E, 0x04, + 0x75, 0x83, 0xA0, 0xE0, 0x20, 0xE0, 0x26, 0xDE, +/*17D0*/0xF4, 0x05, 0x57, 0xE5, 0x57, 0x70, 0x02, 0x05, + 0x56, 0xE5, 0x14, 0x24, 0x01, 0xFD, 0xE4, 0x33, +/*17E0*/0xFC, 0xD3, 0xE5, 0x57, 0x9D, 0xE5, 0x56, 0x9C, + 0x40, 0xD9, 0xE5, 0x0A, 0x94, 0x20, 0x50, 0x02, +/*17F0*/0x05, 0x0A, 0x43, 0xE1, 0x08, 0xC2, 0x31, 0x12, + 0x0E, 0x04, 0x75, 0x83, 0xA6, 0xE0, 0x55, 0x12, +/*1800*/0x65, 0x12, 0x70, 0x03, 0xD2, 0x31, 0x22, 0xC2, + 0x31, 0x22, 0x90, 0x07, 0x26, 0xE0, 0xFA, 0xA3, +/*1810*/0xE0, 0xF5, 0x82, 0x8A, 0x83, 0xE0, 0xF5, 0x41, + 0xE5, 0x39, 0xC3, 0x95, 0x41, 0x40, 0x26, 0xE5, +/*1820*/0x39, 0x95, 0x41, 0xC3, 0x9F, 0xEE, 0x12, 0x07, + 0x6B, 0x40, 0x04, 0x7C, 0x01, 0x80, 0x02, 0x7C, +/*1830*/0x00, 0xE5, 0x41, 0x64, 0x3F, 0x60, 0x04, 0x7B, + 0x01, 0x80, 0x02, 0x7B, 0x00, 0xEC, 0x5B, 0x60, +/*1840*/0x29, 0x05, 0x41, 0x80, 0x28, 0xC3, 0xE5, 0x41, + 0x95, 0x39, 0xC3, 0x9F, 0xEE, 0x12, 0x07, 0x6B, +/*1850*/0x40, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, + 0xE5, 0x41, 0x60, 0x04, 0x7E, 0x01, 0x80, 0x02, +/*1860*/0x7E, 0x00, 0xEF, 0x5E, 0x60, 0x04, 0x15, 0x41, + 0x80, 0x03, 0x85, 0x39, 0x41, 0x85, 0x3A, 0x40, +/*1870*/0x22, 0xE5, 0xE2, 0x30, 0xE4, 0x60, 0xE5, 0xE1, + 0x30, 0xE2, 0x5B, 0xE5, 0x09, 0x70, 0x04, 0x7F, +/*1880*/0x01, 0x80, 0x02, 0x7F, 0x00, 0xE5, 0x08, 0x70, + 0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE, +/*1890*/0x5F, 0x60, 0x43, 0x53, 0xF9, 0xF8, 0xE5, 0xE2, + 0x30, 0xE4, 0x3B, 0xE5, 0xE1, 0x30, 0xE2, 0x2E, +/*18A0*/0x43, 0xFA, 0x02, 0x53, 0xFA, 0xFB, 0xE4, 0xF5, + 0x10, 0x90, 0x94, 0x70, 0xE5, 0x10, 0xF0, 0xE5, +/*18B0*/0xE1, 0x30, 0xE2, 0xE7, 0x90, 0x94, 0x70, 0xE0, + 0x65, 0x10, 0x60, 0x03, 0x43, 0xFA, 0x04, 0x05, +/*18C0*/0x10, 0x90, 0x94, 0x70, 0xE5, 0x10, 0xF0, 0x70, + 0xE6, 0x12, 0x00, 0x06, 0x80, 0xE1, 0x53, 0xFA, +/*18D0*/0xFD, 0x53, 0xFA, 0xFB, 0x80, 0xC0, 0x22, 0x8F, + 0x54, 0x12, 0x00, 0x06, 0xE5, 0xE1, 0x30, 0xE0, +/*18E0*/0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xE5, + 0x7E, 0xD3, 0x94, 0x05, 0x40, 0x04, 0x7E, 0x01, +/*18F0*/0x80, 0x02, 0x7E, 0x00, 0xEE, 0x4F, 0x60, 0x3D, + 0x85, 0x54, 0x11, 0xE5, 0xE2, 0x20, 0xE1, 0x32, +/*1900*/0x74, 0xCE, 0x12, 0x1A, 0x05, 0x30, 0xE7, 0x04, + 0x7D, 0x01, 0x80, 0x02, 0x7D, 0x00, 0x8F, 0x82, +/*1910*/0x8E, 0x83, 0xE0, 0x30, 0xE6, 0x04, 0x7F, 0x01, + 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x5D, 0x70, 0x15, +/*1920*/0x12, 0x15, 0xC6, 0x74, 0xCE, 0x12, 0x1A, 0x05, + 0x30, 0xE6, 0x07, 0xE0, 0x44, 0x80, 0xF0, 0x43, +/*1930*/0xF9, 0x80, 0x12, 0x18, 0x71, 0x22, 0x12, 0x0E, + 0x44, 0xE5, 0x16, 0x25, 0xE0, 0x25, 0xE0, 0x24, +/*1940*/0xB0, 0xF5, 0x82, 0xE4, 0x34, 0x1A, 0xF5, 0x83, + 0xE4, 0x93, 0xF5, 0x0F, 0xE5, 0x16, 0x25, 0xE0, +/*1950*/0x25, 0xE0, 0x24, 0xB1, 0xF5, 0x82, 0xE4, 0x34, + 0x1A, 0xF5, 0x83, 0xE4, 0x93, 0xF5, 0x0E, 0x12, +/*1960*/0x0E, 0x65, 0xF5, 0x10, 0xE5, 0x0F, 0x54, 0xF0, + 0x12, 0x0E, 0x17, 0x75, 0x83, 0x8C, 0xEF, 0xF0, +/*1970*/0xE5, 0x0F, 0x30, 0xE0, 0x0C, 0x12, 0x0E, 0x04, + 0x75, 0x83, 0x86, 0xE0, 0x44, 0x40, 0xF0, 0x80, +/*1980*/0x0A, 0x12, 0x0E, 0x04, 0x75, 0x83, 0x86, 0xE0, + 0x54, 0xBF, 0xF0, 0x12, 0x0E, 0x91, 0x75, 0x83, +/*1990*/0x82, 0xE5, 0x0E, 0xF0, 0x22, 0x7F, 0x05, 0x12, + 0x17, 0x31, 0x12, 0x0E, 0x04, 0x12, 0x0E, 0x33, +/*19A0*/0x74, 0x02, 0xF0, 0x74, 0x8E, 0xFE, 0x12, 0x0E, + 0x04, 0x12, 0x0E, 0x0B, 0xEF, 0xF0, 0x75, 0x15, +/*19B0*/0x70, 0x12, 0x0F, 0xF7, 0x20, 0x34, 0x05, 0x75, + 0x15, 0x10, 0x80, 0x03, 0x75, 0x15, 0x50, 0x12, +/*19C0*/0x0F, 0xF7, 0x20, 0x34, 0x04, 0x74, 0x10, 0x80, + 0x02, 0x74, 0xF0, 0x25, 0x15, 0xF5, 0x15, 0x12, +/*19D0*/0x0E, 0x21, 0xEF, 0xF0, 0x12, 0x10, 0x91, 0x20, + 0x34, 0x17, 0xE5, 0x15, 0x64, 0x30, 0x60, 0x0C, +/*19E0*/0x74, 0x10, 0x25, 0x15, 0xF5, 0x15, 0xB4, 0x80, + 0x03, 0xE4, 0xF5, 0x15, 0x12, 0x0E, 0x21, 0xEF, +/*19F0*/0xF0, 0x22, 0xF0, 0xE5, 0x0B, 0x25, 0xE0, 0x25, + 0xE0, 0x24, 0x82, 0xF5, 0x82, 0xE4, 0x34, 0x07, +/*1A00*/0xF5, 0x83, 0x22, 0x74, 0x88, 0xFE, 0xE5, 0x08, + 0x44, 0x07, 0xFF, 0xF5, 0x82, 0x8E, 0x83, 0xE0, +/*1A10*/0x22, 0xF0, 0xE5, 0x08, 0x44, 0x07, 0xF5, 0x82, + 0x22, 0xF0, 0xE0, 0x54, 0xC0, 0x8F, 0x82, 0x8E, +/*1A20*/0x83, 0xF0, 0x22, 0xEF, 0x44, 0x07, 0xF5, 0x82, + 0x75, 0x83, 0x86, 0xE0, 0x54, 0x10, 0xD3, 0x94, +/*1A30*/0x00, 0x22, 0xF0, 0x90, 0x07, 0x15, 0xE0, 0x04, + 0xF0, 0x22, 0x44, 0x06, 0xF5, 0x82, 0x75, 0x83, +/*1A40*/0x9E, 0xE0, 0x22, 0xFE, 0xEF, 0x44, 0x07, 0xF5, + 0x82, 0x8E, 0x83, 0xE0, 0x22, 0xE4, 0x90, 0x07, +/*1A50*/0x2A, 0xF0, 0xA3, 0xF0, 0x12, 0x07, 0x2A, 0x75, + 0x83, 0x82, 0xE0, 0x54, 0x7F, 0x12, 0x07, 0x29, +/*1A60*/0xE0, 0x44, 0x80, 0xF0, 0x12, 0x10, 0xFC, 0x12, + 0x08, 0x1F, 0x75, 0x83, 0xA0, 0xE0, 0x20, 0xE0, +/*1A70*/0x1A, 0x90, 0x07, 0x2B, 0xE0, 0x04, 0xF0, 0x70, + 0x06, 0x90, 0x07, 0x2A, 0xE0, 0x04, 0xF0, 0x90, +/*1A80*/0x07, 0x2A, 0xE0, 0xB4, 0x10, 0xE1, 0xA3, 0xE0, + 0xB4, 0x00, 0xDC, 0xEE, 0x44, 0xA6, 0xFC, 0xEF, +/*1A90*/0x44, 0x07, 0xF5, 0x82, 0x8C, 0x83, 0xE0, 0xF5, + 0x32, 0xEE, 0x44, 0xA8, 0xFE, 0xEF, 0x44, 0x07, +/*1AA0*/0xF5, 0x82, 0x8E, 0x83, 0xE0, 0xF5, 0x33, 0x22, + 0x01, 0x20, 0x11, 0x00, 0x04, 0x20, 0x00, 0x90, +/*1AB0*/0x00, 0x20, 0x0F, 0x92, 0x00, 0x21, 0x0F, 0x94, + 0x00, 0x22, 0x0F, 0x96, 0x00, 0x23, 0x0F, 0x98, +/*1AC0*/0x00, 0x24, 0x0F, 0x9A, 0x00, 0x25, 0x0F, 0x9C, + 0x00, 0x26, 0x0F, 0x9E, 0x00, 0x27, 0x0F, 0xA0, +/*1AD0*/0x01, 0x20, 0x01, 0xA2, 0x01, 0x21, 0x01, 0xA4, + 0x01, 0x22, 0x01, 0xA6, 0x01, 0x23, 0x01, 0xA8, +/*1AE0*/0x01, 0x24, 0x01, 0xAA, 0x01, 0x25, 0x01, 0xAC, + 0x01, 0x26, 0x01, 0xAE, 0x01, 0x27, 0x01, 0xB0, +/*1AF0*/0x01, 0x28, 0x01, 0xB4, 0x00, 0x28, 0x0F, 0xB6, + 0x40, 0x28, 0x0F, 0xB8, 0x61, 0x28, 0x01, 0xCB, +/*1B00*/0xEF, 0xCB, 0xCA, 0xEE, 0xCA, 0x7F, 0x01, 0xE4, + 0xFD, 0xEB, 0x4A, 0x70, 0x24, 0xE5, 0x08, 0xF5, +/*1B10*/0x82, 0x74, 0xB6, 0x12, 0x08, 0x29, 0xE5, 0x08, + 0xF5, 0x82, 0x74, 0xB8, 0x12, 0x08, 0x29, 0xE5, +/*1B20*/0x08, 0xF5, 0x82, 0x74, 0xBA, 0x12, 0x08, 0x29, + 0x7E, 0x00, 0x7C, 0x00, 0x12, 0x0A, 0xFF, 0x80, +/*1B30*/0x12, 0x90, 0x07, 0x26, 0x12, 0x07, 0x35, 0xE5, + 0x41, 0xF0, 0x90, 0x07, 0x24, 0x12, 0x07, 0x35, +/*1B40*/0xE5, 0x40, 0xF0, 0x12, 0x07, 0x2A, 0x75, 0x83, + 0x8E, 0xE4, 0x12, 0x07, 0x29, 0x74, 0x01, 0x12, +/*1B50*/0x07, 0x29, 0xE4, 0xF0, 0x22, 0xE4, 0xF5, 0x26, + 0xF5, 0x27, 0x53, 0xE1, 0xFE, 0xF5, 0x2A, 0x75, +/*1B60*/0x2B, 0x01, 0xF5, 0x08, 0x7F, 0x01, 0x12, 0x17, + 0x31, 0x30, 0x30, 0x1C, 0x90, 0x1A, 0xA9, 0xE4, +/*1B70*/0x93, 0xF5, 0x10, 0x90, 0x1F, 0xF9, 0xE4, 0x93, + 0xF5, 0x10, 0x90, 0x00, 0x41, 0xE4, 0x93, 0xF5, +/*1B80*/0x10, 0x90, 0x1E, 0xCA, 0xE4, 0x93, 0xF5, 0x10, + 0x7F, 0x02, 0x12, 0x17, 0x31, 0x12, 0x0F, 0x54, +/*1B90*/0x7F, 0x03, 0x12, 0x17, 0x31, 0x12, 0x00, 0x06, + 0xE5, 0xE2, 0x30, 0xE7, 0x09, 0x12, 0x10, 0x00, +/*1BA0*/0x30, 0x30, 0x03, 0x12, 0x11, 0x00, 0x02, 0x00, + 0x47, 0x12, 0x08, 0x1F, 0x75, 0x83, 0xD0, 0xE0, +/*1BB0*/0xC4, 0x54, 0x0F, 0xFD, 0x75, 0x43, 0x01, 0x75, + 0x44, 0xFF, 0x12, 0x08, 0xAA, 0x74, 0x04, 0xF0, +/*1BC0*/0x75, 0x3B, 0x01, 0xED, 0x14, 0x60, 0x0C, 0x14, + 0x60, 0x0B, 0x14, 0x60, 0x0F, 0x24, 0x03, 0x70, +/*1BD0*/0x0B, 0x80, 0x09, 0x80, 0x00, 0x12, 0x08, 0xA7, + 0x04, 0xF0, 0x80, 0x06, 0x12, 0x08, 0xA7, 0x74, +/*1BE0*/0x04, 0xF0, 0xEE, 0x44, 0x82, 0xFE, 0xEF, 0x44, + 0x07, 0xF5, 0x82, 0x8E, 0x83, 0xE5, 0x45, 0x12, +/*1BF0*/0x08, 0xBE, 0x75, 0x83, 0x82, 0xE5, 0x31, 0xF0, + 0x02, 0x11, 0x4C, 0x8E, 0x60, 0x8F, 0x61, 0x12, +/*1C00*/0x1E, 0xA5, 0xE4, 0xFF, 0xCE, 0xED, 0xCE, 0xEE, + 0xD3, 0x95, 0x61, 0xE5, 0x60, 0x12, 0x07, 0x6B, +/*1C10*/0x40, 0x39, 0x74, 0x20, 0x2E, 0xF5, 0x82, 0xE4, + 0x34, 0x03, 0xF5, 0x83, 0xE0, 0x70, 0x03, 0xFF, +/*1C20*/0x80, 0x26, 0x12, 0x08, 0xE2, 0xFD, 0xC3, 0x9F, + 0x40, 0x1E, 0xCF, 0xED, 0xCF, 0xEB, 0x4A, 0x70, +/*1C30*/0x0B, 0x8D, 0x42, 0x12, 0x08, 0xEE, 0xF5, 0x41, + 0x8E, 0x40, 0x80, 0x0C, 0x12, 0x08, 0xE2, 0xF5, +/*1C40*/0x38, 0x12, 0x08, 0xEE, 0xF5, 0x39, 0x8E, 0x3A, + 0x1E, 0x80, 0xBC, 0x22, 0x75, 0x58, 0x01, 0xE5, +/*1C50*/0x35, 0x70, 0x0C, 0x12, 0x07, 0xCC, 0xE0, 0xF5, + 0x4A, 0x12, 0x07, 0xD8, 0xE0, 0xF5, 0x4C, 0xE5, +/*1C60*/0x35, 0xB4, 0x04, 0x0C, 0x12, 0x07, 0xE4, 0xE0, + 0xF5, 0x4A, 0x12, 0x07, 0xF0, 0xE0, 0xF5, 0x4C, +/*1C70*/0xE5, 0x35, 0xB4, 0x01, 0x04, 0x7F, 0x01, 0x80, + 0x02, 0x7F, 0x00, 0xE5, 0x35, 0xB4, 0x02, 0x04, +/*1C80*/0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE, 0x4F, + 0x60, 0x0C, 0x12, 0x07, 0xFC, 0xE0, 0xF5, 0x4A, +/*1C90*/0x12, 0x08, 0x08, 0xE0, 0xF5, 0x4C, 0x85, 0x41, + 0x49, 0x85, 0x40, 0x4B, 0x22, 0x75, 0x5B, 0x01, +/*1CA0*/0x90, 0x07, 0x24, 0x12, 0x07, 0x35, 0xE0, 0x54, + 0x1F, 0xFF, 0xD3, 0x94, 0x02, 0x50, 0x04, 0x8F, +/*1CB0*/0x58, 0x80, 0x05, 0xEF, 0x24, 0xFE, 0xF5, 0x58, + 0xEF, 0xC3, 0x94, 0x18, 0x40, 0x05, 0x75, 0x59, +/*1CC0*/0x18, 0x80, 0x04, 0xEF, 0x04, 0xF5, 0x59, 0x85, + 0x43, 0x5A, 0xAF, 0x58, 0x7E, 0x00, 0xAD, 0x59, +/*1CD0*/0x7C, 0x00, 0xAB, 0x5B, 0x7A, 0x00, 0x12, 0x15, + 0x41, 0xAF, 0x5A, 0x7E, 0x00, 0x12, 0x18, 0x0A, +/*1CE0*/0xAF, 0x5B, 0x7E, 0x00, 0x02, 0x1A, 0xFF, 0xE5, + 0xE2, 0x30, 0xE7, 0x0E, 0x12, 0x10, 0x03, 0xC2, +/*1CF0*/0x30, 0x30, 0x30, 0x03, 0x12, 0x10, 0xFF, 0x20, + 0x33, 0x28, 0xE5, 0xE7, 0x30, 0xE7, 0x05, 0x12, +/*1D00*/0x0E, 0xA2, 0x80, 0x0D, 0xE5, 0xFE, 0xC3, 0x94, + 0x20, 0x50, 0x06, 0x12, 0x0E, 0xA2, 0x43, 0xF9, +/*1D10*/0x08, 0xE5, 0xF2, 0x30, 0xE7, 0x03, 0x53, 0xF9, + 0x7F, 0xE5, 0xF1, 0x54, 0x70, 0xD3, 0x94, 0x00, +/*1D20*/0x50, 0xD8, 0x22, 0x12, 0x0E, 0x04, 0x75, 0x83, + 0x80, 0xE4, 0xF0, 0xE5, 0x08, 0x44, 0x07, 0x12, +/*1D30*/0x0D, 0xFD, 0x75, 0x83, 0x84, 0x12, 0x0E, 0x02, + 0x75, 0x83, 0x86, 0x12, 0x0E, 0x02, 0x75, 0x83, +/*1D40*/0x8C, 0xE0, 0x54, 0xF3, 0x12, 0x0E, 0x03, 0x75, + 0x83, 0x8E, 0x12, 0x0E, 0x02, 0x75, 0x83, 0x94, +/*1D50*/0xE0, 0x54, 0xFB, 0xF0, 0x22, 0x12, 0x07, 0x2A, + 0x75, 0x83, 0x8E, 0xE4, 0x12, 0x07, 0x29, 0x74, +/*1D60*/0x01, 0x12, 0x07, 0x29, 0xE4, 0x12, 0x08, 0xBE, + 0x75, 0x83, 0x8C, 0xE0, 0x44, 0x20, 0x12, 0x08, +/*1D70*/0xBE, 0xE0, 0x54, 0xDF, 0xF0, 0x74, 0x84, 0x85, + 0x08, 0x82, 0xF5, 0x83, 0xE0, 0x54, 0x7F, 0xF0, +/*1D80*/0xE0, 0x44, 0x80, 0xF0, 0x22, 0x75, 0x56, 0x01, + 0xE4, 0xFD, 0xF5, 0x57, 0xAF, 0x35, 0xFE, 0xFC, +/*1D90*/0x12, 0x09, 0x15, 0x12, 0x1C, 0x9D, 0x12, 0x1E, + 0x7A, 0x12, 0x1C, 0x4C, 0xAF, 0x57, 0x7E, 0x00, +/*1DA0*/0xAD, 0x56, 0x7C, 0x00, 0x12, 0x04, 0x44, 0xAF, + 0x56, 0x7E, 0x00, 0x02, 0x11, 0xEE, 0x75, 0x56, +/*1DB0*/0x01, 0xE4, 0xFD, 0xF5, 0x57, 0xAF, 0x35, 0xFE, + 0xFC, 0x12, 0x09, 0x15, 0x12, 0x1C, 0x9D, 0x12, +/*1DC0*/0x1E, 0x7A, 0x12, 0x1C, 0x4C, 0xAF, 0x57, 0x7E, + 0x00, 0xAD, 0x56, 0x7C, 0x00, 0x12, 0x04, 0x44, +/*1DD0*/0xAF, 0x56, 0x7E, 0x00, 0x02, 0x11, 0xEE, 0xE4, + 0xF5, 0x16, 0x12, 0x0E, 0x44, 0xFE, 0xE5, 0x08, +/*1DE0*/0x44, 0x05, 0xFF, 0x12, 0x0E, 0x65, 0x8F, 0x82, + 0x8E, 0x83, 0xF0, 0x05, 0x16, 0xE5, 0x16, 0xC3, +/*1DF0*/0x94, 0x14, 0x40, 0xE6, 0xE5, 0x08, 0x12, 0x0E, + 0x2B, 0xE4, 0xF0, 0x22, 0xE4, 0xF5, 0x58, 0xF5, +/*1E00*/0x59, 0xF5, 0x5A, 0xFF, 0xFE, 0xAD, 0x58, 0xFC, + 0x12, 0x09, 0x15, 0x7F, 0x04, 0x7E, 0x00, 0xAD, +/*1E10*/0x58, 0x7C, 0x00, 0x12, 0x09, 0x15, 0x7F, 0x02, + 0x7E, 0x00, 0xAD, 0x58, 0x7C, 0x00, 0x02, 0x09, +/*1E20*/0x15, 0xE5, 0x3C, 0x25, 0x3E, 0xFC, 0xE5, 0x42, + 0x24, 0x00, 0xFB, 0xE4, 0x33, 0xFA, 0xEC, 0xC3, +/*1E30*/0x9B, 0xEA, 0x12, 0x07, 0x6B, 0x40, 0x0B, 0x8C, + 0x42, 0xE5, 0x3D, 0x25, 0x3F, 0xF5, 0x41, 0x8F, +/*1E40*/0x40, 0x22, 0x12, 0x09, 0x0B, 0x22, 0x74, 0x84, + 0xF5, 0x18, 0x85, 0x08, 0x19, 0x85, 0x19, 0x82, +/*1E50*/0x85, 0x18, 0x83, 0xE0, 0x54, 0x7F, 0xF0, 0xE0, + 0x44, 0x80, 0xF0, 0xE0, 0x44, 0x80, 0xF0, 0x22, +/*1E60*/0xEF, 0x4E, 0x70, 0x0B, 0x12, 0x07, 0x2A, 0x75, + 0x83, 0xD2, 0xE0, 0x54, 0xDF, 0xF0, 0x22, 0x12, +/*1E70*/0x07, 0x2A, 0x75, 0x83, 0xD2, 0xE0, 0x44, 0x20, + 0xF0, 0x22, 0x75, 0x58, 0x01, 0x90, 0x07, 0x26, +/*1E80*/0x12, 0x07, 0x35, 0xE0, 0x54, 0x3F, 0xF5, 0x41, + 0x12, 0x07, 0x32, 0xE0, 0x54, 0x3F, 0xF5, 0x40, +/*1E90*/0x22, 0x75, 0x56, 0x02, 0xE4, 0xF5, 0x57, 0x12, + 0x1D, 0xFC, 0xAF, 0x57, 0x7E, 0x00, 0xAD, 0x56, +/*1EA0*/0x7C, 0x00, 0x02, 0x04, 0x44, 0xE4, 0xF5, 0x42, + 0xF5, 0x41, 0xF5, 0x40, 0xF5, 0x38, 0xF5, 0x39, +/*1EB0*/0xF5, 0x3A, 0x22, 0xEF, 0x54, 0x07, 0xFF, 0xE5, + 0xF9, 0x54, 0xF8, 0x4F, 0xF5, 0xF9, 0x22, 0x7F, +/*1EC0*/0x01, 0xE4, 0xFE, 0x0F, 0x0E, 0xBE, 0xFF, 0xFB, + 0x22, 0x01, 0x20, 0x00, 0x01, 0x04, 0x20, 0x00, +/*1ED0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/*1EE0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/*1EF0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/*1F00*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/*1F10*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/*1F20*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/*1F30*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/*1F40*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/*1F50*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/*1F60*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/*1F70*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/*1F80*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/*1F90*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/*1FA0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/*1FB0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/*1FC0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/*1FD0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/*1FE0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/*1FF0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x20, 0x11, 0x00, 0x04, 0x20, 0x00, 0x81 +}; + +int qib_sd7220_ib_load(struct qib_devdata *dd) +{ + return qib_sd7220_prog_ld(dd, IB_7220_SERDES, qib_sd7220_ib_img, + sizeof(qib_sd7220_ib_img), 0); +} + +int qib_sd7220_ib_vfy(struct qib_devdata *dd) +{ + return qib_sd7220_prog_vfy(dd, IB_7220_SERDES, qib_sd7220_ib_img, + sizeof(qib_sd7220_ib_img), 0); +} diff --git a/drivers/infiniband/hw/qib/qib_sdma.c b/drivers/infiniband/hw/qib/qib_sdma.c new file mode 100644 index 000000000000..b8456881f7f6 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_sdma.c @@ -0,0 +1,973 @@ +/* + * Copyright (c) 2007, 2008, 2009, 2010 QLogic Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include + +#include "qib.h" +#include "qib_common.h" + +/* default pio off, sdma on */ +static ushort sdma_descq_cnt = 256; +module_param_named(sdma_descq_cnt, sdma_descq_cnt, ushort, S_IRUGO); +MODULE_PARM_DESC(sdma_descq_cnt, "Number of SDMA descq entries"); + +/* + * Bits defined in the send DMA descriptor. + */ +#define SDMA_DESC_LAST (1ULL << 11) +#define SDMA_DESC_FIRST (1ULL << 12) +#define SDMA_DESC_DMA_HEAD (1ULL << 13) +#define SDMA_DESC_USE_LARGE_BUF (1ULL << 14) +#define SDMA_DESC_INTR (1ULL << 15) +#define SDMA_DESC_COUNT_LSB 16 +#define SDMA_DESC_GEN_LSB 30 + +char *qib_sdma_state_names[] = { + [qib_sdma_state_s00_hw_down] = "s00_HwDown", + [qib_sdma_state_s10_hw_start_up_wait] = "s10_HwStartUpWait", + [qib_sdma_state_s20_idle] = "s20_Idle", + [qib_sdma_state_s30_sw_clean_up_wait] = "s30_SwCleanUpWait", + [qib_sdma_state_s40_hw_clean_up_wait] = "s40_HwCleanUpWait", + [qib_sdma_state_s50_hw_halt_wait] = "s50_HwHaltWait", + [qib_sdma_state_s99_running] = "s99_Running", +}; + +char *qib_sdma_event_names[] = { + [qib_sdma_event_e00_go_hw_down] = "e00_GoHwDown", + [qib_sdma_event_e10_go_hw_start] = "e10_GoHwStart", + [qib_sdma_event_e20_hw_started] = "e20_HwStarted", + [qib_sdma_event_e30_go_running] = "e30_GoRunning", + [qib_sdma_event_e40_sw_cleaned] = "e40_SwCleaned", + [qib_sdma_event_e50_hw_cleaned] = "e50_HwCleaned", + [qib_sdma_event_e60_hw_halted] = "e60_HwHalted", + [qib_sdma_event_e70_go_idle] = "e70_GoIdle", + [qib_sdma_event_e7220_err_halted] = "e7220_ErrHalted", + [qib_sdma_event_e7322_err_halted] = "e7322_ErrHalted", + [qib_sdma_event_e90_timer_tick] = "e90_TimerTick", +}; + +/* declare all statics here rather than keep sorting */ +static int alloc_sdma(struct qib_pportdata *); +static void sdma_complete(struct kref *); +static void sdma_finalput(struct qib_sdma_state *); +static void sdma_get(struct qib_sdma_state *); +static void sdma_put(struct qib_sdma_state *); +static void sdma_set_state(struct qib_pportdata *, enum qib_sdma_states); +static void sdma_start_sw_clean_up(struct qib_pportdata *); +static void sdma_sw_clean_up_task(unsigned long); +static void unmap_desc(struct qib_pportdata *, unsigned); + +static void sdma_get(struct qib_sdma_state *ss) +{ + kref_get(&ss->kref); +} + +static void sdma_complete(struct kref *kref) +{ + struct qib_sdma_state *ss = + container_of(kref, struct qib_sdma_state, kref); + + complete(&ss->comp); +} + +static void sdma_put(struct qib_sdma_state *ss) +{ + kref_put(&ss->kref, sdma_complete); +} + +static void sdma_finalput(struct qib_sdma_state *ss) +{ + sdma_put(ss); + wait_for_completion(&ss->comp); +} + +/* + * Complete all the sdma requests on the active list, in the correct + * order, and with appropriate processing. Called when cleaning up + * after sdma shutdown, and when new sdma requests are submitted for + * a link that is down. This matches what is done for requests + * that complete normally, it's just the full list. + * + * Must be called with sdma_lock held + */ +static void clear_sdma_activelist(struct qib_pportdata *ppd) +{ + struct qib_sdma_txreq *txp, *txp_next; + + list_for_each_entry_safe(txp, txp_next, &ppd->sdma_activelist, list) { + list_del_init(&txp->list); + if (txp->flags & QIB_SDMA_TXREQ_F_FREEDESC) { + unsigned idx; + + idx = txp->start_idx; + while (idx != txp->next_descq_idx) { + unmap_desc(ppd, idx); + if (++idx == ppd->sdma_descq_cnt) + idx = 0; + } + } + if (txp->callback) + (*txp->callback)(txp, QIB_SDMA_TXREQ_S_ABORTED); + } +} + +static void sdma_sw_clean_up_task(unsigned long opaque) +{ + struct qib_pportdata *ppd = (struct qib_pportdata *) opaque; + unsigned long flags; + + spin_lock_irqsave(&ppd->sdma_lock, flags); + + /* + * At this point, the following should always be true: + * - We are halted, so no more descriptors are getting retired. + * - We are not running, so no one is submitting new work. + * - Only we can send the e40_sw_cleaned, so we can't start + * running again until we say so. So, the active list and + * descq are ours to play with. + */ + + /* Process all retired requests. */ + qib_sdma_make_progress(ppd); + + clear_sdma_activelist(ppd); + + /* + * Resync count of added and removed. It is VERY important that + * sdma_descq_removed NEVER decrement - user_sdma depends on it. + */ + ppd->sdma_descq_removed = ppd->sdma_descq_added; + + /* + * Reset our notion of head and tail. + * Note that the HW registers will be reset when switching states + * due to calling __qib_sdma_process_event() below. + */ + ppd->sdma_descq_tail = 0; + ppd->sdma_descq_head = 0; + ppd->sdma_head_dma[0] = 0; + ppd->sdma_generation = 0; + + __qib_sdma_process_event(ppd, qib_sdma_event_e40_sw_cleaned); + + spin_unlock_irqrestore(&ppd->sdma_lock, flags); +} + +/* + * This is called when changing to state qib_sdma_state_s10_hw_start_up_wait + * as a result of send buffer errors or send DMA descriptor errors. + * We want to disarm the buffers in these cases. + */ +static void sdma_hw_start_up(struct qib_pportdata *ppd) +{ + struct qib_sdma_state *ss = &ppd->sdma_state; + unsigned bufno; + + for (bufno = ss->first_sendbuf; bufno < ss->last_sendbuf; ++bufno) + ppd->dd->f_sendctrl(ppd, QIB_SENDCTRL_DISARM_BUF(bufno)); + + ppd->dd->f_sdma_hw_start_up(ppd); +} + +static void sdma_sw_tear_down(struct qib_pportdata *ppd) +{ + struct qib_sdma_state *ss = &ppd->sdma_state; + + /* Releasing this reference means the state machine has stopped. */ + sdma_put(ss); +} + +static void sdma_start_sw_clean_up(struct qib_pportdata *ppd) +{ + tasklet_hi_schedule(&ppd->sdma_sw_clean_up_task); +} + +static void sdma_set_state(struct qib_pportdata *ppd, + enum qib_sdma_states next_state) +{ + struct qib_sdma_state *ss = &ppd->sdma_state; + struct sdma_set_state_action *action = ss->set_state_action; + unsigned op = 0; + + /* debugging bookkeeping */ + ss->previous_state = ss->current_state; + ss->previous_op = ss->current_op; + + ss->current_state = next_state; + + if (action[next_state].op_enable) + op |= QIB_SDMA_SENDCTRL_OP_ENABLE; + + if (action[next_state].op_intenable) + op |= QIB_SDMA_SENDCTRL_OP_INTENABLE; + + if (action[next_state].op_halt) + op |= QIB_SDMA_SENDCTRL_OP_HALT; + + if (action[next_state].op_drain) + op |= QIB_SDMA_SENDCTRL_OP_DRAIN; + + if (action[next_state].go_s99_running_tofalse) + ss->go_s99_running = 0; + + if (action[next_state].go_s99_running_totrue) + ss->go_s99_running = 1; + + ss->current_op = op; + + ppd->dd->f_sdma_sendctrl(ppd, ss->current_op); +} + +static void unmap_desc(struct qib_pportdata *ppd, unsigned head) +{ + __le64 *descqp = &ppd->sdma_descq[head].qw[0]; + u64 desc[2]; + dma_addr_t addr; + size_t len; + + desc[0] = le64_to_cpu(descqp[0]); + desc[1] = le64_to_cpu(descqp[1]); + + addr = (desc[1] << 32) | (desc[0] >> 32); + len = (desc[0] >> 14) & (0x7ffULL << 2); + dma_unmap_single(&ppd->dd->pcidev->dev, addr, len, DMA_TO_DEVICE); +} + +static int alloc_sdma(struct qib_pportdata *ppd) +{ + ppd->sdma_descq_cnt = sdma_descq_cnt; + if (!ppd->sdma_descq_cnt) + ppd->sdma_descq_cnt = 256; + + /* Allocate memory for SendDMA descriptor FIFO */ + ppd->sdma_descq = dma_alloc_coherent(&ppd->dd->pcidev->dev, + ppd->sdma_descq_cnt * sizeof(u64[2]), &ppd->sdma_descq_phys, + GFP_KERNEL); + + if (!ppd->sdma_descq) { + qib_dev_err(ppd->dd, "failed to allocate SendDMA descriptor " + "FIFO memory\n"); + goto bail; + } + + /* Allocate memory for DMA of head register to memory */ + ppd->sdma_head_dma = dma_alloc_coherent(&ppd->dd->pcidev->dev, + PAGE_SIZE, &ppd->sdma_head_phys, GFP_KERNEL); + if (!ppd->sdma_head_dma) { + qib_dev_err(ppd->dd, "failed to allocate SendDMA " + "head memory\n"); + goto cleanup_descq; + } + ppd->sdma_head_dma[0] = 0; + return 0; + +cleanup_descq: + dma_free_coherent(&ppd->dd->pcidev->dev, + ppd->sdma_descq_cnt * sizeof(u64[2]), (void *)ppd->sdma_descq, + ppd->sdma_descq_phys); + ppd->sdma_descq = NULL; + ppd->sdma_descq_phys = 0; +bail: + ppd->sdma_descq_cnt = 0; + return -ENOMEM; +} + +static void free_sdma(struct qib_pportdata *ppd) +{ + struct qib_devdata *dd = ppd->dd; + + if (ppd->sdma_head_dma) { + dma_free_coherent(&dd->pcidev->dev, PAGE_SIZE, + (void *)ppd->sdma_head_dma, + ppd->sdma_head_phys); + ppd->sdma_head_dma = NULL; + ppd->sdma_head_phys = 0; + } + + if (ppd->sdma_descq) { + dma_free_coherent(&dd->pcidev->dev, + ppd->sdma_descq_cnt * sizeof(u64[2]), + ppd->sdma_descq, ppd->sdma_descq_phys); + ppd->sdma_descq = NULL; + ppd->sdma_descq_phys = 0; + } +} + +static inline void make_sdma_desc(struct qib_pportdata *ppd, + u64 *sdmadesc, u64 addr, u64 dwlen, + u64 dwoffset) +{ + + WARN_ON(addr & 3); + /* SDmaPhyAddr[47:32] */ + sdmadesc[1] = addr >> 32; + /* SDmaPhyAddr[31:0] */ + sdmadesc[0] = (addr & 0xfffffffcULL) << 32; + /* SDmaGeneration[1:0] */ + sdmadesc[0] |= (ppd->sdma_generation & 3ULL) << + SDMA_DESC_GEN_LSB; + /* SDmaDwordCount[10:0] */ + sdmadesc[0] |= (dwlen & 0x7ffULL) << SDMA_DESC_COUNT_LSB; + /* SDmaBufOffset[12:2] */ + sdmadesc[0] |= dwoffset & 0x7ffULL; +} + +/* sdma_lock must be held */ +int qib_sdma_make_progress(struct qib_pportdata *ppd) +{ + struct list_head *lp = NULL; + struct qib_sdma_txreq *txp = NULL; + struct qib_devdata *dd = ppd->dd; + int progress = 0; + u16 hwhead; + u16 idx = 0; + + hwhead = dd->f_sdma_gethead(ppd); + + /* The reason for some of the complexity of this code is that + * not all descriptors have corresponding txps. So, we have to + * be able to skip over descs until we wander into the range of + * the next txp on the list. + */ + + if (!list_empty(&ppd->sdma_activelist)) { + lp = ppd->sdma_activelist.next; + txp = list_entry(lp, struct qib_sdma_txreq, list); + idx = txp->start_idx; + } + + while (ppd->sdma_descq_head != hwhead) { + /* if desc is part of this txp, unmap if needed */ + if (txp && (txp->flags & QIB_SDMA_TXREQ_F_FREEDESC) && + (idx == ppd->sdma_descq_head)) { + unmap_desc(ppd, ppd->sdma_descq_head); + if (++idx == ppd->sdma_descq_cnt) + idx = 0; + } + + /* increment dequed desc count */ + ppd->sdma_descq_removed++; + + /* advance head, wrap if needed */ + if (++ppd->sdma_descq_head == ppd->sdma_descq_cnt) + ppd->sdma_descq_head = 0; + + /* if now past this txp's descs, do the callback */ + if (txp && txp->next_descq_idx == ppd->sdma_descq_head) { + /* remove from active list */ + list_del_init(&txp->list); + if (txp->callback) + (*txp->callback)(txp, QIB_SDMA_TXREQ_S_OK); + /* see if there is another txp */ + if (list_empty(&ppd->sdma_activelist)) + txp = NULL; + else { + lp = ppd->sdma_activelist.next; + txp = list_entry(lp, struct qib_sdma_txreq, + list); + idx = txp->start_idx; + } + } + progress = 1; + } + if (progress) + qib_verbs_sdma_desc_avail(ppd, qib_sdma_descq_freecnt(ppd)); + return progress; +} + +/* + * This is called from interrupt context. + */ +void qib_sdma_intr(struct qib_pportdata *ppd) +{ + unsigned long flags; + + spin_lock_irqsave(&ppd->sdma_lock, flags); + + __qib_sdma_intr(ppd); + + spin_unlock_irqrestore(&ppd->sdma_lock, flags); +} + +void __qib_sdma_intr(struct qib_pportdata *ppd) +{ + if (__qib_sdma_running(ppd)) + qib_sdma_make_progress(ppd); +} + +int qib_setup_sdma(struct qib_pportdata *ppd) +{ + struct qib_devdata *dd = ppd->dd; + unsigned long flags; + int ret = 0; + + ret = alloc_sdma(ppd); + if (ret) + goto bail; + + /* set consistent sdma state */ + ppd->dd->f_sdma_init_early(ppd); + spin_lock_irqsave(&ppd->sdma_lock, flags); + sdma_set_state(ppd, qib_sdma_state_s00_hw_down); + spin_unlock_irqrestore(&ppd->sdma_lock, flags); + + /* set up reference counting */ + kref_init(&ppd->sdma_state.kref); + init_completion(&ppd->sdma_state.comp); + + ppd->sdma_generation = 0; + ppd->sdma_descq_head = 0; + ppd->sdma_descq_removed = 0; + ppd->sdma_descq_added = 0; + + INIT_LIST_HEAD(&ppd->sdma_activelist); + + tasklet_init(&ppd->sdma_sw_clean_up_task, sdma_sw_clean_up_task, + (unsigned long)ppd); + + ret = dd->f_init_sdma_regs(ppd); + if (ret) + goto bail_alloc; + + qib_sdma_process_event(ppd, qib_sdma_event_e10_go_hw_start); + + return 0; + +bail_alloc: + qib_teardown_sdma(ppd); +bail: + return ret; +} + +void qib_teardown_sdma(struct qib_pportdata *ppd) +{ + qib_sdma_process_event(ppd, qib_sdma_event_e00_go_hw_down); + + /* + * This waits for the state machine to exit so it is not + * necessary to kill the sdma_sw_clean_up_task to make sure + * it is not running. + */ + sdma_finalput(&ppd->sdma_state); + + free_sdma(ppd); +} + +int qib_sdma_running(struct qib_pportdata *ppd) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&ppd->sdma_lock, flags); + ret = __qib_sdma_running(ppd); + spin_unlock_irqrestore(&ppd->sdma_lock, flags); + + return ret; +} + +/* + * Complete a request when sdma not running; likely only request + * but to simplify the code, always queue it, then process the full + * activelist. We process the entire list to ensure that this particular + * request does get it's callback, but in the correct order. + * Must be called with sdma_lock held + */ +static void complete_sdma_err_req(struct qib_pportdata *ppd, + struct qib_verbs_txreq *tx) +{ + atomic_inc(&tx->qp->s_dma_busy); + /* no sdma descriptors, so no unmap_desc */ + tx->txreq.start_idx = 0; + tx->txreq.next_descq_idx = 0; + list_add_tail(&tx->txreq.list, &ppd->sdma_activelist); + clear_sdma_activelist(ppd); +} + +/* + * This function queues one IB packet onto the send DMA queue per call. + * The caller is responsible for checking: + * 1) The number of send DMA descriptor entries is less than the size of + * the descriptor queue. + * 2) The IB SGE addresses and lengths are 32-bit aligned + * (except possibly the last SGE's length) + * 3) The SGE addresses are suitable for passing to dma_map_single(). + */ +int qib_sdma_verbs_send(struct qib_pportdata *ppd, + struct qib_sge_state *ss, u32 dwords, + struct qib_verbs_txreq *tx) +{ + unsigned long flags; + struct qib_sge *sge; + struct qib_qp *qp; + int ret = 0; + u16 tail; + __le64 *descqp; + u64 sdmadesc[2]; + u32 dwoffset; + dma_addr_t addr; + + spin_lock_irqsave(&ppd->sdma_lock, flags); + +retry: + if (unlikely(!__qib_sdma_running(ppd))) { + complete_sdma_err_req(ppd, tx); + goto unlock; + } + + if (tx->txreq.sg_count > qib_sdma_descq_freecnt(ppd)) { + if (qib_sdma_make_progress(ppd)) + goto retry; + if (ppd->dd->flags & QIB_HAS_SDMA_TIMEOUT) + ppd->dd->f_sdma_set_desc_cnt(ppd, + ppd->sdma_descq_cnt / 2); + goto busy; + } + + dwoffset = tx->hdr_dwords; + make_sdma_desc(ppd, sdmadesc, (u64) tx->txreq.addr, dwoffset, 0); + + sdmadesc[0] |= SDMA_DESC_FIRST; + if (tx->txreq.flags & QIB_SDMA_TXREQ_F_USELARGEBUF) + sdmadesc[0] |= SDMA_DESC_USE_LARGE_BUF; + + /* write to the descq */ + tail = ppd->sdma_descq_tail; + descqp = &ppd->sdma_descq[tail].qw[0]; + *descqp++ = cpu_to_le64(sdmadesc[0]); + *descqp++ = cpu_to_le64(sdmadesc[1]); + + /* increment the tail */ + if (++tail == ppd->sdma_descq_cnt) { + tail = 0; + descqp = &ppd->sdma_descq[0].qw[0]; + ++ppd->sdma_generation; + } + + tx->txreq.start_idx = tail; + + sge = &ss->sge; + while (dwords) { + u32 dw; + u32 len; + + len = dwords << 2; + if (len > sge->length) + len = sge->length; + if (len > sge->sge_length) + len = sge->sge_length; + BUG_ON(len == 0); + dw = (len + 3) >> 2; + addr = dma_map_single(&ppd->dd->pcidev->dev, sge->vaddr, + dw << 2, DMA_TO_DEVICE); + if (dma_mapping_error(&ppd->dd->pcidev->dev, addr)) + goto unmap; + sdmadesc[0] = 0; + make_sdma_desc(ppd, sdmadesc, (u64) addr, dw, dwoffset); + /* SDmaUseLargeBuf has to be set in every descriptor */ + if (tx->txreq.flags & QIB_SDMA_TXREQ_F_USELARGEBUF) + sdmadesc[0] |= SDMA_DESC_USE_LARGE_BUF; + /* write to the descq */ + *descqp++ = cpu_to_le64(sdmadesc[0]); + *descqp++ = cpu_to_le64(sdmadesc[1]); + + /* increment the tail */ + if (++tail == ppd->sdma_descq_cnt) { + tail = 0; + descqp = &ppd->sdma_descq[0].qw[0]; + ++ppd->sdma_generation; + } + sge->vaddr += len; + sge->length -= len; + sge->sge_length -= len; + if (sge->sge_length == 0) { + if (--ss->num_sge) + *sge = *ss->sg_list++; + } else if (sge->length == 0 && sge->mr->lkey) { + if (++sge->n >= QIB_SEGSZ) { + if (++sge->m >= sge->mr->mapsz) + break; + sge->n = 0; + } + sge->vaddr = + sge->mr->map[sge->m]->segs[sge->n].vaddr; + sge->length = + sge->mr->map[sge->m]->segs[sge->n].length; + } + + dwoffset += dw; + dwords -= dw; + } + + if (!tail) + descqp = &ppd->sdma_descq[ppd->sdma_descq_cnt].qw[0]; + descqp -= 2; + descqp[0] |= cpu_to_le64(SDMA_DESC_LAST); + if (tx->txreq.flags & QIB_SDMA_TXREQ_F_HEADTOHOST) + descqp[0] |= cpu_to_le64(SDMA_DESC_DMA_HEAD); + if (tx->txreq.flags & QIB_SDMA_TXREQ_F_INTREQ) + descqp[0] |= cpu_to_le64(SDMA_DESC_INTR); + + atomic_inc(&tx->qp->s_dma_busy); + tx->txreq.next_descq_idx = tail; + ppd->dd->f_sdma_update_tail(ppd, tail); + ppd->sdma_descq_added += tx->txreq.sg_count; + list_add_tail(&tx->txreq.list, &ppd->sdma_activelist); + goto unlock; + +unmap: + for (;;) { + if (!tail) + tail = ppd->sdma_descq_cnt - 1; + else + tail--; + if (tail == ppd->sdma_descq_tail) + break; + unmap_desc(ppd, tail); + } + qp = tx->qp; + qib_put_txreq(tx); + spin_lock(&qp->s_lock); + if (qp->ibqp.qp_type == IB_QPT_RC) { + /* XXX what about error sending RDMA read responses? */ + if (ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK) + qib_error_qp(qp, IB_WC_GENERAL_ERR); + } else if (qp->s_wqe) + qib_send_complete(qp, qp->s_wqe, IB_WC_GENERAL_ERR); + spin_unlock(&qp->s_lock); + /* return zero to process the next send work request */ + goto unlock; + +busy: + qp = tx->qp; + spin_lock(&qp->s_lock); + if (ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK) { + struct qib_ibdev *dev; + + /* + * If we couldn't queue the DMA request, save the info + * and try again later rather than destroying the + * buffer and undoing the side effects of the copy. + */ + tx->ss = ss; + tx->dwords = dwords; + qp->s_tx = tx; + dev = &ppd->dd->verbs_dev; + spin_lock(&dev->pending_lock); + if (list_empty(&qp->iowait)) { + struct qib_ibport *ibp; + + ibp = &ppd->ibport_data; + ibp->n_dmawait++; + qp->s_flags |= QIB_S_WAIT_DMA_DESC; + list_add_tail(&qp->iowait, &dev->dmawait); + } + spin_unlock(&dev->pending_lock); + qp->s_flags &= ~QIB_S_BUSY; + spin_unlock(&qp->s_lock); + ret = -EBUSY; + } else { + spin_unlock(&qp->s_lock); + qib_put_txreq(tx); + } +unlock: + spin_unlock_irqrestore(&ppd->sdma_lock, flags); + return ret; +} + +void qib_sdma_process_event(struct qib_pportdata *ppd, + enum qib_sdma_events event) +{ + unsigned long flags; + + spin_lock_irqsave(&ppd->sdma_lock, flags); + + __qib_sdma_process_event(ppd, event); + + if (ppd->sdma_state.current_state == qib_sdma_state_s99_running) + qib_verbs_sdma_desc_avail(ppd, qib_sdma_descq_freecnt(ppd)); + + spin_unlock_irqrestore(&ppd->sdma_lock, flags); +} + +void __qib_sdma_process_event(struct qib_pportdata *ppd, + enum qib_sdma_events event) +{ + struct qib_sdma_state *ss = &ppd->sdma_state; + + switch (ss->current_state) { + case qib_sdma_state_s00_hw_down: + switch (event) { + case qib_sdma_event_e00_go_hw_down: + break; + case qib_sdma_event_e30_go_running: + /* + * If down, but running requested (usually result + * of link up, then we need to start up. + * This can happen when hw down is requested while + * bringing the link up with traffic active on + * 7220, e.g. */ + ss->go_s99_running = 1; + /* fall through and start dma engine */ + case qib_sdma_event_e10_go_hw_start: + /* This reference means the state machine is started */ + sdma_get(&ppd->sdma_state); + sdma_set_state(ppd, + qib_sdma_state_s10_hw_start_up_wait); + break; + case qib_sdma_event_e20_hw_started: + break; + case qib_sdma_event_e40_sw_cleaned: + sdma_sw_tear_down(ppd); + break; + case qib_sdma_event_e50_hw_cleaned: + break; + case qib_sdma_event_e60_hw_halted: + break; + case qib_sdma_event_e70_go_idle: + break; + case qib_sdma_event_e7220_err_halted: + break; + case qib_sdma_event_e7322_err_halted: + break; + case qib_sdma_event_e90_timer_tick: + break; + } + break; + + case qib_sdma_state_s10_hw_start_up_wait: + switch (event) { + case qib_sdma_event_e00_go_hw_down: + sdma_set_state(ppd, qib_sdma_state_s00_hw_down); + sdma_sw_tear_down(ppd); + break; + case qib_sdma_event_e10_go_hw_start: + break; + case qib_sdma_event_e20_hw_started: + sdma_set_state(ppd, ss->go_s99_running ? + qib_sdma_state_s99_running : + qib_sdma_state_s20_idle); + break; + case qib_sdma_event_e30_go_running: + ss->go_s99_running = 1; + break; + case qib_sdma_event_e40_sw_cleaned: + break; + case qib_sdma_event_e50_hw_cleaned: + break; + case qib_sdma_event_e60_hw_halted: + break; + case qib_sdma_event_e70_go_idle: + ss->go_s99_running = 0; + break; + case qib_sdma_event_e7220_err_halted: + break; + case qib_sdma_event_e7322_err_halted: + break; + case qib_sdma_event_e90_timer_tick: + break; + } + break; + + case qib_sdma_state_s20_idle: + switch (event) { + case qib_sdma_event_e00_go_hw_down: + sdma_set_state(ppd, qib_sdma_state_s00_hw_down); + sdma_sw_tear_down(ppd); + break; + case qib_sdma_event_e10_go_hw_start: + break; + case qib_sdma_event_e20_hw_started: + break; + case qib_sdma_event_e30_go_running: + sdma_set_state(ppd, qib_sdma_state_s99_running); + ss->go_s99_running = 1; + break; + case qib_sdma_event_e40_sw_cleaned: + break; + case qib_sdma_event_e50_hw_cleaned: + break; + case qib_sdma_event_e60_hw_halted: + break; + case qib_sdma_event_e70_go_idle: + break; + case qib_sdma_event_e7220_err_halted: + break; + case qib_sdma_event_e7322_err_halted: + break; + case qib_sdma_event_e90_timer_tick: + break; + } + break; + + case qib_sdma_state_s30_sw_clean_up_wait: + switch (event) { + case qib_sdma_event_e00_go_hw_down: + sdma_set_state(ppd, qib_sdma_state_s00_hw_down); + break; + case qib_sdma_event_e10_go_hw_start: + break; + case qib_sdma_event_e20_hw_started: + break; + case qib_sdma_event_e30_go_running: + ss->go_s99_running = 1; + break; + case qib_sdma_event_e40_sw_cleaned: + sdma_set_state(ppd, + qib_sdma_state_s10_hw_start_up_wait); + sdma_hw_start_up(ppd); + break; + case qib_sdma_event_e50_hw_cleaned: + break; + case qib_sdma_event_e60_hw_halted: + break; + case qib_sdma_event_e70_go_idle: + ss->go_s99_running = 0; + break; + case qib_sdma_event_e7220_err_halted: + break; + case qib_sdma_event_e7322_err_halted: + break; + case qib_sdma_event_e90_timer_tick: + break; + } + break; + + case qib_sdma_state_s40_hw_clean_up_wait: + switch (event) { + case qib_sdma_event_e00_go_hw_down: + sdma_set_state(ppd, qib_sdma_state_s00_hw_down); + sdma_start_sw_clean_up(ppd); + break; + case qib_sdma_event_e10_go_hw_start: + break; + case qib_sdma_event_e20_hw_started: + break; + case qib_sdma_event_e30_go_running: + ss->go_s99_running = 1; + break; + case qib_sdma_event_e40_sw_cleaned: + break; + case qib_sdma_event_e50_hw_cleaned: + sdma_set_state(ppd, + qib_sdma_state_s30_sw_clean_up_wait); + sdma_start_sw_clean_up(ppd); + break; + case qib_sdma_event_e60_hw_halted: + break; + case qib_sdma_event_e70_go_idle: + ss->go_s99_running = 0; + break; + case qib_sdma_event_e7220_err_halted: + break; + case qib_sdma_event_e7322_err_halted: + break; + case qib_sdma_event_e90_timer_tick: + break; + } + break; + + case qib_sdma_state_s50_hw_halt_wait: + switch (event) { + case qib_sdma_event_e00_go_hw_down: + sdma_set_state(ppd, qib_sdma_state_s00_hw_down); + sdma_start_sw_clean_up(ppd); + break; + case qib_sdma_event_e10_go_hw_start: + break; + case qib_sdma_event_e20_hw_started: + break; + case qib_sdma_event_e30_go_running: + ss->go_s99_running = 1; + break; + case qib_sdma_event_e40_sw_cleaned: + break; + case qib_sdma_event_e50_hw_cleaned: + break; + case qib_sdma_event_e60_hw_halted: + sdma_set_state(ppd, + qib_sdma_state_s40_hw_clean_up_wait); + ppd->dd->f_sdma_hw_clean_up(ppd); + break; + case qib_sdma_event_e70_go_idle: + ss->go_s99_running = 0; + break; + case qib_sdma_event_e7220_err_halted: + break; + case qib_sdma_event_e7322_err_halted: + break; + case qib_sdma_event_e90_timer_tick: + break; + } + break; + + case qib_sdma_state_s99_running: + switch (event) { + case qib_sdma_event_e00_go_hw_down: + sdma_set_state(ppd, qib_sdma_state_s00_hw_down); + sdma_start_sw_clean_up(ppd); + break; + case qib_sdma_event_e10_go_hw_start: + break; + case qib_sdma_event_e20_hw_started: + break; + case qib_sdma_event_e30_go_running: + break; + case qib_sdma_event_e40_sw_cleaned: + break; + case qib_sdma_event_e50_hw_cleaned: + break; + case qib_sdma_event_e60_hw_halted: + sdma_set_state(ppd, + qib_sdma_state_s30_sw_clean_up_wait); + sdma_start_sw_clean_up(ppd); + break; + case qib_sdma_event_e70_go_idle: + sdma_set_state(ppd, qib_sdma_state_s50_hw_halt_wait); + ss->go_s99_running = 0; + break; + case qib_sdma_event_e7220_err_halted: + sdma_set_state(ppd, + qib_sdma_state_s30_sw_clean_up_wait); + sdma_start_sw_clean_up(ppd); + break; + case qib_sdma_event_e7322_err_halted: + sdma_set_state(ppd, qib_sdma_state_s50_hw_halt_wait); + break; + case qib_sdma_event_e90_timer_tick: + break; + } + break; + } + + ss->last_event = event; +} diff --git a/drivers/infiniband/hw/qib/qib_srq.c b/drivers/infiniband/hw/qib/qib_srq.c new file mode 100644 index 000000000000..c3ec8efc2ed8 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_srq.c @@ -0,0 +1,375 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. + * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include + +#include "qib_verbs.h" + +/** + * qib_post_srq_receive - post a receive on a shared receive queue + * @ibsrq: the SRQ to post the receive on + * @wr: the list of work requests to post + * @bad_wr: A pointer to the first WR to cause a problem is put here + * + * This may be called from interrupt context. + */ +int qib_post_srq_receive(struct ib_srq *ibsrq, struct ib_recv_wr *wr, + struct ib_recv_wr **bad_wr) +{ + struct qib_srq *srq = to_isrq(ibsrq); + struct qib_rwq *wq; + unsigned long flags; + int ret; + + for (; wr; wr = wr->next) { + struct qib_rwqe *wqe; + u32 next; + int i; + + if ((unsigned) wr->num_sge > srq->rq.max_sge) { + *bad_wr = wr; + ret = -EINVAL; + goto bail; + } + + spin_lock_irqsave(&srq->rq.lock, flags); + wq = srq->rq.wq; + next = wq->head + 1; + if (next >= srq->rq.size) + next = 0; + if (next == wq->tail) { + spin_unlock_irqrestore(&srq->rq.lock, flags); + *bad_wr = wr; + ret = -ENOMEM; + goto bail; + } + + wqe = get_rwqe_ptr(&srq->rq, wq->head); + wqe->wr_id = wr->wr_id; + wqe->num_sge = wr->num_sge; + for (i = 0; i < wr->num_sge; i++) + wqe->sg_list[i] = wr->sg_list[i]; + /* Make sure queue entry is written before the head index. */ + smp_wmb(); + wq->head = next; + spin_unlock_irqrestore(&srq->rq.lock, flags); + } + ret = 0; + +bail: + return ret; +} + +/** + * qib_create_srq - create a shared receive queue + * @ibpd: the protection domain of the SRQ to create + * @srq_init_attr: the attributes of the SRQ + * @udata: data from libibverbs when creating a user SRQ + */ +struct ib_srq *qib_create_srq(struct ib_pd *ibpd, + struct ib_srq_init_attr *srq_init_attr, + struct ib_udata *udata) +{ + struct qib_ibdev *dev = to_idev(ibpd->device); + struct qib_srq *srq; + u32 sz; + struct ib_srq *ret; + + if (srq_init_attr->attr.max_sge == 0 || + srq_init_attr->attr.max_sge > ib_qib_max_srq_sges || + srq_init_attr->attr.max_wr == 0 || + srq_init_attr->attr.max_wr > ib_qib_max_srq_wrs) { + ret = ERR_PTR(-EINVAL); + goto done; + } + + srq = kmalloc(sizeof(*srq), GFP_KERNEL); + if (!srq) { + ret = ERR_PTR(-ENOMEM); + goto done; + } + + /* + * Need to use vmalloc() if we want to support large #s of entries. + */ + srq->rq.size = srq_init_attr->attr.max_wr + 1; + srq->rq.max_sge = srq_init_attr->attr.max_sge; + sz = sizeof(struct ib_sge) * srq->rq.max_sge + + sizeof(struct qib_rwqe); + srq->rq.wq = vmalloc_user(sizeof(struct qib_rwq) + srq->rq.size * sz); + if (!srq->rq.wq) { + ret = ERR_PTR(-ENOMEM); + goto bail_srq; + } + + /* + * Return the address of the RWQ as the offset to mmap. + * See qib_mmap() for details. + */ + if (udata && udata->outlen >= sizeof(__u64)) { + int err; + u32 s = sizeof(struct qib_rwq) + srq->rq.size * sz; + + srq->ip = + qib_create_mmap_info(dev, s, ibpd->uobject->context, + srq->rq.wq); + if (!srq->ip) { + ret = ERR_PTR(-ENOMEM); + goto bail_wq; + } + + err = ib_copy_to_udata(udata, &srq->ip->offset, + sizeof(srq->ip->offset)); + if (err) { + ret = ERR_PTR(err); + goto bail_ip; + } + } else + srq->ip = NULL; + + /* + * ib_create_srq() will initialize srq->ibsrq. + */ + spin_lock_init(&srq->rq.lock); + srq->rq.wq->head = 0; + srq->rq.wq->tail = 0; + srq->limit = srq_init_attr->attr.srq_limit; + + spin_lock(&dev->n_srqs_lock); + if (dev->n_srqs_allocated == ib_qib_max_srqs) { + spin_unlock(&dev->n_srqs_lock); + ret = ERR_PTR(-ENOMEM); + goto bail_ip; + } + + dev->n_srqs_allocated++; + spin_unlock(&dev->n_srqs_lock); + + if (srq->ip) { + spin_lock_irq(&dev->pending_lock); + list_add(&srq->ip->pending_mmaps, &dev->pending_mmaps); + spin_unlock_irq(&dev->pending_lock); + } + + ret = &srq->ibsrq; + goto done; + +bail_ip: + kfree(srq->ip); +bail_wq: + vfree(srq->rq.wq); +bail_srq: + kfree(srq); +done: + return ret; +} + +/** + * qib_modify_srq - modify a shared receive queue + * @ibsrq: the SRQ to modify + * @attr: the new attributes of the SRQ + * @attr_mask: indicates which attributes to modify + * @udata: user data for libibverbs.so + */ +int qib_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, + enum ib_srq_attr_mask attr_mask, + struct ib_udata *udata) +{ + struct qib_srq *srq = to_isrq(ibsrq); + struct qib_rwq *wq; + int ret = 0; + + if (attr_mask & IB_SRQ_MAX_WR) { + struct qib_rwq *owq; + struct qib_rwqe *p; + u32 sz, size, n, head, tail; + + /* Check that the requested sizes are below the limits. */ + if ((attr->max_wr > ib_qib_max_srq_wrs) || + ((attr_mask & IB_SRQ_LIMIT) ? + attr->srq_limit : srq->limit) > attr->max_wr) { + ret = -EINVAL; + goto bail; + } + + sz = sizeof(struct qib_rwqe) + + srq->rq.max_sge * sizeof(struct ib_sge); + size = attr->max_wr + 1; + wq = vmalloc_user(sizeof(struct qib_rwq) + size * sz); + if (!wq) { + ret = -ENOMEM; + goto bail; + } + + /* Check that we can write the offset to mmap. */ + if (udata && udata->inlen >= sizeof(__u64)) { + __u64 offset_addr; + __u64 offset = 0; + + ret = ib_copy_from_udata(&offset_addr, udata, + sizeof(offset_addr)); + if (ret) + goto bail_free; + udata->outbuf = + (void __user *) (unsigned long) offset_addr; + ret = ib_copy_to_udata(udata, &offset, + sizeof(offset)); + if (ret) + goto bail_free; + } + + spin_lock_irq(&srq->rq.lock); + /* + * validate head and tail pointer values and compute + * the number of remaining WQEs. + */ + owq = srq->rq.wq; + head = owq->head; + tail = owq->tail; + if (head >= srq->rq.size || tail >= srq->rq.size) { + ret = -EINVAL; + goto bail_unlock; + } + n = head; + if (n < tail) + n += srq->rq.size - tail; + else + n -= tail; + if (size <= n) { + ret = -EINVAL; + goto bail_unlock; + } + n = 0; + p = wq->wq; + while (tail != head) { + struct qib_rwqe *wqe; + int i; + + wqe = get_rwqe_ptr(&srq->rq, tail); + p->wr_id = wqe->wr_id; + p->num_sge = wqe->num_sge; + for (i = 0; i < wqe->num_sge; i++) + p->sg_list[i] = wqe->sg_list[i]; + n++; + p = (struct qib_rwqe *)((char *) p + sz); + if (++tail >= srq->rq.size) + tail = 0; + } + srq->rq.wq = wq; + srq->rq.size = size; + wq->head = n; + wq->tail = 0; + if (attr_mask & IB_SRQ_LIMIT) + srq->limit = attr->srq_limit; + spin_unlock_irq(&srq->rq.lock); + + vfree(owq); + + if (srq->ip) { + struct qib_mmap_info *ip = srq->ip; + struct qib_ibdev *dev = to_idev(srq->ibsrq.device); + u32 s = sizeof(struct qib_rwq) + size * sz; + + qib_update_mmap_info(dev, ip, s, wq); + + /* + * Return the offset to mmap. + * See qib_mmap() for details. + */ + if (udata && udata->inlen >= sizeof(__u64)) { + ret = ib_copy_to_udata(udata, &ip->offset, + sizeof(ip->offset)); + if (ret) + goto bail; + } + + /* + * Put user mapping info onto the pending list + * unless it already is on the list. + */ + spin_lock_irq(&dev->pending_lock); + if (list_empty(&ip->pending_mmaps)) + list_add(&ip->pending_mmaps, + &dev->pending_mmaps); + spin_unlock_irq(&dev->pending_lock); + } + } else if (attr_mask & IB_SRQ_LIMIT) { + spin_lock_irq(&srq->rq.lock); + if (attr->srq_limit >= srq->rq.size) + ret = -EINVAL; + else + srq->limit = attr->srq_limit; + spin_unlock_irq(&srq->rq.lock); + } + goto bail; + +bail_unlock: + spin_unlock_irq(&srq->rq.lock); +bail_free: + vfree(wq); +bail: + return ret; +} + +int qib_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr) +{ + struct qib_srq *srq = to_isrq(ibsrq); + + attr->max_wr = srq->rq.size - 1; + attr->max_sge = srq->rq.max_sge; + attr->srq_limit = srq->limit; + return 0; +} + +/** + * qib_destroy_srq - destroy a shared receive queue + * @ibsrq: the SRQ to destroy + */ +int qib_destroy_srq(struct ib_srq *ibsrq) +{ + struct qib_srq *srq = to_isrq(ibsrq); + struct qib_ibdev *dev = to_idev(ibsrq->device); + + spin_lock(&dev->n_srqs_lock); + dev->n_srqs_allocated--; + spin_unlock(&dev->n_srqs_lock); + if (srq->ip) + kref_put(&srq->ip->ref, qib_release_mmap_info); + else + vfree(srq->rq.wq); + kfree(srq); + + return 0; +} diff --git a/drivers/infiniband/hw/qib/qib_sysfs.c b/drivers/infiniband/hw/qib/qib_sysfs.c new file mode 100644 index 000000000000..dab4d9f4a2cc --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_sysfs.c @@ -0,0 +1,691 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. + * Copyright (c) 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include + +#include "qib.h" + +/** + * qib_parse_ushort - parse an unsigned short value in an arbitrary base + * @str: the string containing the number + * @valp: where to put the result + * + * Returns the number of bytes consumed, or negative value on error. + */ +static int qib_parse_ushort(const char *str, unsigned short *valp) +{ + unsigned long val; + char *end; + int ret; + + if (!isdigit(str[0])) { + ret = -EINVAL; + goto bail; + } + + val = simple_strtoul(str, &end, 0); + + if (val > 0xffff) { + ret = -EINVAL; + goto bail; + } + + *valp = val; + + ret = end + 1 - str; + if (ret == 0) + ret = -EINVAL; + +bail: + return ret; +} + +/* start of per-port functions */ +/* + * Get/Set heartbeat enable. OR of 1=enabled, 2=auto + */ +static ssize_t show_hrtbt_enb(struct qib_pportdata *ppd, char *buf) +{ + struct qib_devdata *dd = ppd->dd; + int ret; + + ret = dd->f_get_ib_cfg(ppd, QIB_IB_CFG_HRTBT); + ret = scnprintf(buf, PAGE_SIZE, "%d\n", ret); + return ret; +} + +static ssize_t store_hrtbt_enb(struct qib_pportdata *ppd, const char *buf, + size_t count) +{ + struct qib_devdata *dd = ppd->dd; + int ret; + u16 val; + + ret = qib_parse_ushort(buf, &val); + + /* + * Set the "intentional" heartbeat enable per either of + * "Enable" and "Auto", as these are normally set together. + * This bit is consulted when leaving loopback mode, + * because entering loopback mode overrides it and automatically + * disables heartbeat. + */ + if (ret >= 0) + ret = dd->f_set_ib_cfg(ppd, QIB_IB_CFG_HRTBT, val); + if (ret < 0) + qib_dev_err(dd, "attempt to set invalid Heartbeat enable\n"); + return ret < 0 ? ret : count; +} + +static ssize_t store_loopback(struct qib_pportdata *ppd, const char *buf, + size_t count) +{ + struct qib_devdata *dd = ppd->dd; + int ret = count, r; + + r = dd->f_set_ib_loopback(ppd, buf); + if (r < 0) + ret = r; + + return ret; +} + +static ssize_t store_led_override(struct qib_pportdata *ppd, const char *buf, + size_t count) +{ + struct qib_devdata *dd = ppd->dd; + int ret; + u16 val; + + ret = qib_parse_ushort(buf, &val); + if (ret > 0) + qib_set_led_override(ppd, val); + else + qib_dev_err(dd, "attempt to set invalid LED override\n"); + return ret < 0 ? ret : count; +} + +static ssize_t show_status(struct qib_pportdata *ppd, char *buf) +{ + ssize_t ret; + + if (!ppd->statusp) + ret = -EINVAL; + else + ret = scnprintf(buf, PAGE_SIZE, "0x%llx\n", + (unsigned long long) *(ppd->statusp)); + return ret; +} + +/* + * For userland compatibility, these offsets must remain fixed. + * They are strings for QIB_STATUS_* + */ +static const char *qib_status_str[] = { + "Initted", + "", + "", + "", + "", + "Present", + "IB_link_up", + "IB_configured", + "", + "Fatal_Hardware_Error", + NULL, +}; + +static ssize_t show_status_str(struct qib_pportdata *ppd, char *buf) +{ + int i, any; + u64 s; + ssize_t ret; + + if (!ppd->statusp) { + ret = -EINVAL; + goto bail; + } + + s = *(ppd->statusp); + *buf = '\0'; + for (any = i = 0; s && qib_status_str[i]; i++) { + if (s & 1) { + /* if overflow */ + if (any && strlcat(buf, " ", PAGE_SIZE) >= PAGE_SIZE) + break; + if (strlcat(buf, qib_status_str[i], PAGE_SIZE) >= + PAGE_SIZE) + break; + any = 1; + } + s >>= 1; + } + if (any) + strlcat(buf, "\n", PAGE_SIZE); + + ret = strlen(buf); + +bail: + return ret; +} + +/* end of per-port functions */ + +/* + * Start of per-port file structures and support code + * Because we are fitting into other infrastructure, we have to supply the + * full set of kobject/sysfs_ops structures and routines. + */ +#define QIB_PORT_ATTR(name, mode, show, store) \ + static struct qib_port_attr qib_port_attr_##name = \ + __ATTR(name, mode, show, store) + +struct qib_port_attr { + struct attribute attr; + ssize_t (*show)(struct qib_pportdata *, char *); + ssize_t (*store)(struct qib_pportdata *, const char *, size_t); +}; + +QIB_PORT_ATTR(loopback, S_IWUSR, NULL, store_loopback); +QIB_PORT_ATTR(led_override, S_IWUSR, NULL, store_led_override); +QIB_PORT_ATTR(hrtbt_enable, S_IWUSR | S_IRUGO, show_hrtbt_enb, + store_hrtbt_enb); +QIB_PORT_ATTR(status, S_IRUGO, show_status, NULL); +QIB_PORT_ATTR(status_str, S_IRUGO, show_status_str, NULL); + +static struct attribute *port_default_attributes[] = { + &qib_port_attr_loopback.attr, + &qib_port_attr_led_override.attr, + &qib_port_attr_hrtbt_enable.attr, + &qib_port_attr_status.attr, + &qib_port_attr_status_str.attr, + NULL +}; + +static ssize_t qib_portattr_show(struct kobject *kobj, + struct attribute *attr, char *buf) +{ + struct qib_port_attr *pattr = + container_of(attr, struct qib_port_attr, attr); + struct qib_pportdata *ppd = + container_of(kobj, struct qib_pportdata, pport_kobj); + + return pattr->show(ppd, buf); +} + +static ssize_t qib_portattr_store(struct kobject *kobj, + struct attribute *attr, const char *buf, size_t len) +{ + struct qib_port_attr *pattr = + container_of(attr, struct qib_port_attr, attr); + struct qib_pportdata *ppd = + container_of(kobj, struct qib_pportdata, pport_kobj); + + return pattr->store(ppd, buf, len); +} + +static void qib_port_release(struct kobject *kobj) +{ + /* nothing to do since memory is freed by qib_free_devdata() */ +} + +static const struct sysfs_ops qib_port_ops = { + .show = qib_portattr_show, + .store = qib_portattr_store, +}; + +static struct kobj_type qib_port_ktype = { + .release = qib_port_release, + .sysfs_ops = &qib_port_ops, + .default_attrs = port_default_attributes +}; + +/* Start sl2vl */ + +#define QIB_SL2VL_ATTR(N) \ + static struct qib_sl2vl_attr qib_sl2vl_attr_##N = { \ + .attr = { .name = __stringify(N), .mode = 0444 }, \ + .sl = N \ + } + +struct qib_sl2vl_attr { + struct attribute attr; + int sl; +}; + +QIB_SL2VL_ATTR(0); +QIB_SL2VL_ATTR(1); +QIB_SL2VL_ATTR(2); +QIB_SL2VL_ATTR(3); +QIB_SL2VL_ATTR(4); +QIB_SL2VL_ATTR(5); +QIB_SL2VL_ATTR(6); +QIB_SL2VL_ATTR(7); +QIB_SL2VL_ATTR(8); +QIB_SL2VL_ATTR(9); +QIB_SL2VL_ATTR(10); +QIB_SL2VL_ATTR(11); +QIB_SL2VL_ATTR(12); +QIB_SL2VL_ATTR(13); +QIB_SL2VL_ATTR(14); +QIB_SL2VL_ATTR(15); + +static struct attribute *sl2vl_default_attributes[] = { + &qib_sl2vl_attr_0.attr, + &qib_sl2vl_attr_1.attr, + &qib_sl2vl_attr_2.attr, + &qib_sl2vl_attr_3.attr, + &qib_sl2vl_attr_4.attr, + &qib_sl2vl_attr_5.attr, + &qib_sl2vl_attr_6.attr, + &qib_sl2vl_attr_7.attr, + &qib_sl2vl_attr_8.attr, + &qib_sl2vl_attr_9.attr, + &qib_sl2vl_attr_10.attr, + &qib_sl2vl_attr_11.attr, + &qib_sl2vl_attr_12.attr, + &qib_sl2vl_attr_13.attr, + &qib_sl2vl_attr_14.attr, + &qib_sl2vl_attr_15.attr, + NULL +}; + +static ssize_t sl2vl_attr_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct qib_sl2vl_attr *sattr = + container_of(attr, struct qib_sl2vl_attr, attr); + struct qib_pportdata *ppd = + container_of(kobj, struct qib_pportdata, sl2vl_kobj); + struct qib_ibport *qibp = &ppd->ibport_data; + + return sprintf(buf, "%u\n", qibp->sl_to_vl[sattr->sl]); +} + +static const struct sysfs_ops qib_sl2vl_ops = { + .show = sl2vl_attr_show, +}; + +static struct kobj_type qib_sl2vl_ktype = { + .release = qib_port_release, + .sysfs_ops = &qib_sl2vl_ops, + .default_attrs = sl2vl_default_attributes +}; + +/* End sl2vl */ + +/* Start diag_counters */ + +#define QIB_DIAGC_ATTR(N) \ + static struct qib_diagc_attr qib_diagc_attr_##N = { \ + .attr = { .name = __stringify(N), .mode = 0444 }, \ + .counter = offsetof(struct qib_ibport, n_##N) \ + } + +struct qib_diagc_attr { + struct attribute attr; + size_t counter; +}; + +QIB_DIAGC_ATTR(rc_resends); +QIB_DIAGC_ATTR(rc_acks); +QIB_DIAGC_ATTR(rc_qacks); +QIB_DIAGC_ATTR(rc_delayed_comp); +QIB_DIAGC_ATTR(seq_naks); +QIB_DIAGC_ATTR(rdma_seq); +QIB_DIAGC_ATTR(rnr_naks); +QIB_DIAGC_ATTR(other_naks); +QIB_DIAGC_ATTR(rc_timeouts); +QIB_DIAGC_ATTR(loop_pkts); +QIB_DIAGC_ATTR(pkt_drops); +QIB_DIAGC_ATTR(dmawait); +QIB_DIAGC_ATTR(unaligned); +QIB_DIAGC_ATTR(rc_dupreq); +QIB_DIAGC_ATTR(rc_seqnak); + +static struct attribute *diagc_default_attributes[] = { + &qib_diagc_attr_rc_resends.attr, + &qib_diagc_attr_rc_acks.attr, + &qib_diagc_attr_rc_qacks.attr, + &qib_diagc_attr_rc_delayed_comp.attr, + &qib_diagc_attr_seq_naks.attr, + &qib_diagc_attr_rdma_seq.attr, + &qib_diagc_attr_rnr_naks.attr, + &qib_diagc_attr_other_naks.attr, + &qib_diagc_attr_rc_timeouts.attr, + &qib_diagc_attr_loop_pkts.attr, + &qib_diagc_attr_pkt_drops.attr, + &qib_diagc_attr_dmawait.attr, + &qib_diagc_attr_unaligned.attr, + &qib_diagc_attr_rc_dupreq.attr, + &qib_diagc_attr_rc_seqnak.attr, + NULL +}; + +static ssize_t diagc_attr_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct qib_diagc_attr *dattr = + container_of(attr, struct qib_diagc_attr, attr); + struct qib_pportdata *ppd = + container_of(kobj, struct qib_pportdata, diagc_kobj); + struct qib_ibport *qibp = &ppd->ibport_data; + + return sprintf(buf, "%u\n", *(u32 *)((char *)qibp + dattr->counter)); +} + +static const struct sysfs_ops qib_diagc_ops = { + .show = diagc_attr_show, +}; + +static struct kobj_type qib_diagc_ktype = { + .release = qib_port_release, + .sysfs_ops = &qib_diagc_ops, + .default_attrs = diagc_default_attributes +}; + +/* End diag_counters */ + +/* end of per-port file structures and support code */ + +/* + * Start of per-unit (or driver, in some cases, but replicated + * per unit) functions (these get a device *) + */ +static ssize_t show_rev(struct device *device, struct device_attribute *attr, + char *buf) +{ + struct qib_ibdev *dev = + container_of(device, struct qib_ibdev, ibdev.dev); + + return sprintf(buf, "%x\n", dd_from_dev(dev)->minrev); +} + +static ssize_t show_hca(struct device *device, struct device_attribute *attr, + char *buf) +{ + struct qib_ibdev *dev = + container_of(device, struct qib_ibdev, ibdev.dev); + struct qib_devdata *dd = dd_from_dev(dev); + int ret; + + if (!dd->boardname) + ret = -EINVAL; + else + ret = scnprintf(buf, PAGE_SIZE, "%s\n", dd->boardname); + return ret; +} + +static ssize_t show_version(struct device *device, + struct device_attribute *attr, char *buf) +{ + /* The string printed here is already newline-terminated. */ + return scnprintf(buf, PAGE_SIZE, "%s", (char *)ib_qib_version); +} + +static ssize_t show_boardversion(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct qib_ibdev *dev = + container_of(device, struct qib_ibdev, ibdev.dev); + struct qib_devdata *dd = dd_from_dev(dev); + + /* The string printed here is already newline-terminated. */ + return scnprintf(buf, PAGE_SIZE, "%s", dd->boardversion); +} + + +static ssize_t show_localbus_info(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct qib_ibdev *dev = + container_of(device, struct qib_ibdev, ibdev.dev); + struct qib_devdata *dd = dd_from_dev(dev); + + /* The string printed here is already newline-terminated. */ + return scnprintf(buf, PAGE_SIZE, "%s", dd->lbus_info); +} + + +static ssize_t show_nctxts(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct qib_ibdev *dev = + container_of(device, struct qib_ibdev, ibdev.dev); + struct qib_devdata *dd = dd_from_dev(dev); + + /* Return the number of user ports (contexts) available. */ + return scnprintf(buf, PAGE_SIZE, "%u\n", dd->cfgctxts - + dd->first_user_ctxt); +} + +static ssize_t show_serial(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct qib_ibdev *dev = + container_of(device, struct qib_ibdev, ibdev.dev); + struct qib_devdata *dd = dd_from_dev(dev); + + buf[sizeof dd->serial] = '\0'; + memcpy(buf, dd->serial, sizeof dd->serial); + strcat(buf, "\n"); + return strlen(buf); +} + +static ssize_t store_chip_reset(struct device *device, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct qib_ibdev *dev = + container_of(device, struct qib_ibdev, ibdev.dev); + struct qib_devdata *dd = dd_from_dev(dev); + int ret; + + if (count < 5 || memcmp(buf, "reset", 5) || !dd->diag_client) { + ret = -EINVAL; + goto bail; + } + + ret = qib_reset_device(dd->unit); +bail: + return ret < 0 ? ret : count; +} + +static ssize_t show_logged_errs(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct qib_ibdev *dev = + container_of(device, struct qib_ibdev, ibdev.dev); + struct qib_devdata *dd = dd_from_dev(dev); + int idx, count; + + /* force consistency with actual EEPROM */ + if (qib_update_eeprom_log(dd) != 0) + return -ENXIO; + + count = 0; + for (idx = 0; idx < QIB_EEP_LOG_CNT; ++idx) { + count += scnprintf(buf + count, PAGE_SIZE - count, "%d%c", + dd->eep_st_errs[idx], + idx == (QIB_EEP_LOG_CNT - 1) ? '\n' : ' '); + } + + return count; +} + +/* + * Dump tempsense regs. in decimal, to ease shell-scripts. + */ +static ssize_t show_tempsense(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct qib_ibdev *dev = + container_of(device, struct qib_ibdev, ibdev.dev); + struct qib_devdata *dd = dd_from_dev(dev); + int ret; + int idx; + u8 regvals[8]; + + ret = -ENXIO; + for (idx = 0; idx < 8; ++idx) { + if (idx == 6) + continue; + ret = dd->f_tempsense_rd(dd, idx); + if (ret < 0) + break; + regvals[idx] = ret; + } + if (idx == 8) + ret = scnprintf(buf, PAGE_SIZE, "%d %d %02X %02X %d %d\n", + *(signed char *)(regvals), + *(signed char *)(regvals + 1), + regvals[2], regvals[3], + *(signed char *)(regvals + 5), + *(signed char *)(regvals + 7)); + return ret; +} + +/* + * end of per-unit (or driver, in some cases, but replicated + * per unit) functions + */ + +/* start of per-unit file structures and support code */ +static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); +static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL); +static DEVICE_ATTR(board_id, S_IRUGO, show_hca, NULL); +static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); +static DEVICE_ATTR(nctxts, S_IRUGO, show_nctxts, NULL); +static DEVICE_ATTR(serial, S_IRUGO, show_serial, NULL); +static DEVICE_ATTR(boardversion, S_IRUGO, show_boardversion, NULL); +static DEVICE_ATTR(logged_errors, S_IRUGO, show_logged_errs, NULL); +static DEVICE_ATTR(tempsense, S_IRUGO, show_tempsense, NULL); +static DEVICE_ATTR(localbus_info, S_IRUGO, show_localbus_info, NULL); +static DEVICE_ATTR(chip_reset, S_IWUSR, NULL, store_chip_reset); + +static struct device_attribute *qib_attributes[] = { + &dev_attr_hw_rev, + &dev_attr_hca_type, + &dev_attr_board_id, + &dev_attr_version, + &dev_attr_nctxts, + &dev_attr_serial, + &dev_attr_boardversion, + &dev_attr_logged_errors, + &dev_attr_tempsense, + &dev_attr_localbus_info, + &dev_attr_chip_reset, +}; + +int qib_create_port_files(struct ib_device *ibdev, u8 port_num, + struct kobject *kobj) +{ + struct qib_pportdata *ppd; + struct qib_devdata *dd = dd_from_ibdev(ibdev); + int ret; + + if (!port_num || port_num > dd->num_pports) { + qib_dev_err(dd, "Skipping infiniband class with " + "invalid port %u\n", port_num); + ret = -ENODEV; + goto bail; + } + ppd = &dd->pport[port_num - 1]; + + ret = kobject_init_and_add(&ppd->pport_kobj, &qib_port_ktype, kobj, + "linkcontrol"); + if (ret) { + qib_dev_err(dd, "Skipping linkcontrol sysfs info, " + "(err %d) port %u\n", ret, port_num); + goto bail; + } + kobject_uevent(&ppd->pport_kobj, KOBJ_ADD); + + ret = kobject_init_and_add(&ppd->sl2vl_kobj, &qib_sl2vl_ktype, kobj, + "sl2vl"); + if (ret) { + qib_dev_err(dd, "Skipping sl2vl sysfs info, " + "(err %d) port %u\n", ret, port_num); + goto bail_sl; + } + kobject_uevent(&ppd->sl2vl_kobj, KOBJ_ADD); + + ret = kobject_init_and_add(&ppd->diagc_kobj, &qib_diagc_ktype, kobj, + "diag_counters"); + if (ret) { + qib_dev_err(dd, "Skipping diag_counters sysfs info, " + "(err %d) port %u\n", ret, port_num); + goto bail_diagc; + } + kobject_uevent(&ppd->diagc_kobj, KOBJ_ADD); + + return 0; + +bail_diagc: + kobject_put(&ppd->sl2vl_kobj); +bail_sl: + kobject_put(&ppd->pport_kobj); +bail: + return ret; +} + +/* + * Register and create our files in /sys/class/infiniband. + */ +int qib_verbs_register_sysfs(struct qib_devdata *dd) +{ + struct ib_device *dev = &dd->verbs_dev.ibdev; + int i, ret; + + for (i = 0; i < ARRAY_SIZE(qib_attributes); ++i) { + ret = device_create_file(&dev->dev, qib_attributes[i]); + if (ret) + return ret; + } + + return 0; +} + +/* + * Unregister and remove our files in /sys/class/infiniband. + */ +void qib_verbs_unregister_sysfs(struct qib_devdata *dd) +{ + struct qib_pportdata *ppd; + int i; + + for (i = 0; i < dd->num_pports; i++) { + ppd = &dd->pport[i]; + kobject_put(&ppd->pport_kobj); + kobject_put(&ppd->sl2vl_kobj); + } +} diff --git a/drivers/infiniband/hw/qib/qib_twsi.c b/drivers/infiniband/hw/qib/qib_twsi.c new file mode 100644 index 000000000000..6f31ca5039db --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_twsi.c @@ -0,0 +1,498 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. + * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include + +#include "qib.h" + +/* + * QLogic_IB "Two Wire Serial Interface" driver. + * Originally written for a not-quite-i2c serial eeprom, which is + * still used on some supported boards. Later boards have added a + * variety of other uses, most board-specific, so teh bit-boffing + * part has been split off to this file, while the other parts + * have been moved to chip-specific files. + * + * We have also dropped all pretense of fully generic (e.g. pretend + * we don't know whether '1' is the higher voltage) interface, as + * the restrictions of the generic i2c interface (e.g. no access from + * driver itself) make it unsuitable for this use. + */ + +#define READ_CMD 1 +#define WRITE_CMD 0 + +/** + * i2c_wait_for_writes - wait for a write + * @dd: the qlogic_ib device + * + * We use this instead of udelay directly, so we can make sure + * that previous register writes have been flushed all the way + * to the chip. Since we are delaying anyway, the cost doesn't + * hurt, and makes the bit twiddling more regular + */ +static void i2c_wait_for_writes(struct qib_devdata *dd) +{ + /* + * implicit read of EXTStatus is as good as explicit + * read of scratch, if all we want to do is flush + * writes. + */ + dd->f_gpio_mod(dd, 0, 0, 0); + rmb(); /* inlined, so prevent compiler reordering */ +} + +/* + * QSFP modules are allowed to hold SCL low for 500uSec. Allow twice that + * for "almost compliant" modules + */ +#define SCL_WAIT_USEC 1000 + +/* BUF_WAIT is time bus must be free between STOP or ACK and to next START. + * Should be 20, but some chips need more. + */ +#define TWSI_BUF_WAIT_USEC 60 + +static void scl_out(struct qib_devdata *dd, u8 bit) +{ + u32 mask; + + udelay(1); + + mask = 1UL << dd->gpio_scl_num; + + /* SCL is meant to be bare-drain, so never set "OUT", just DIR */ + dd->f_gpio_mod(dd, 0, bit ? 0 : mask, mask); + + /* + * Allow for slow slaves by simple + * delay for falling edge, sampling on rise. + */ + if (!bit) + udelay(2); + else { + int rise_usec; + for (rise_usec = SCL_WAIT_USEC; rise_usec > 0; rise_usec -= 2) { + if (mask & dd->f_gpio_mod(dd, 0, 0, 0)) + break; + udelay(2); + } + if (rise_usec <= 0) + qib_dev_err(dd, "SCL interface stuck low > %d uSec\n", + SCL_WAIT_USEC); + } + i2c_wait_for_writes(dd); +} + +static void sda_out(struct qib_devdata *dd, u8 bit) +{ + u32 mask; + + mask = 1UL << dd->gpio_sda_num; + + /* SDA is meant to be bare-drain, so never set "OUT", just DIR */ + dd->f_gpio_mod(dd, 0, bit ? 0 : mask, mask); + + i2c_wait_for_writes(dd); + udelay(2); +} + +static u8 sda_in(struct qib_devdata *dd, int wait) +{ + int bnum; + u32 read_val, mask; + + bnum = dd->gpio_sda_num; + mask = (1UL << bnum); + /* SDA is meant to be bare-drain, so never set "OUT", just DIR */ + dd->f_gpio_mod(dd, 0, 0, mask); + read_val = dd->f_gpio_mod(dd, 0, 0, 0); + if (wait) + i2c_wait_for_writes(dd); + return (read_val & mask) >> bnum; +} + +/** + * i2c_ackrcv - see if ack following write is true + * @dd: the qlogic_ib device + */ +static int i2c_ackrcv(struct qib_devdata *dd) +{ + u8 ack_received; + + /* AT ENTRY SCL = LOW */ + /* change direction, ignore data */ + ack_received = sda_in(dd, 1); + scl_out(dd, 1); + ack_received = sda_in(dd, 1) == 0; + scl_out(dd, 0); + return ack_received; +} + +static void stop_cmd(struct qib_devdata *dd); + +/** + * rd_byte - read a byte, sending STOP on last, else ACK + * @dd: the qlogic_ib device + * + * Returns byte shifted out of device + */ +static int rd_byte(struct qib_devdata *dd, int last) +{ + int bit_cntr, data; + + data = 0; + + for (bit_cntr = 7; bit_cntr >= 0; --bit_cntr) { + data <<= 1; + scl_out(dd, 1); + data |= sda_in(dd, 0); + scl_out(dd, 0); + } + if (last) { + scl_out(dd, 1); + stop_cmd(dd); + } else { + sda_out(dd, 0); + scl_out(dd, 1); + scl_out(dd, 0); + sda_out(dd, 1); + } + return data; +} + +/** + * wr_byte - write a byte, one bit at a time + * @dd: the qlogic_ib device + * @data: the byte to write + * + * Returns 0 if we got the following ack, otherwise 1 + */ +static int wr_byte(struct qib_devdata *dd, u8 data) +{ + int bit_cntr; + u8 bit; + + for (bit_cntr = 7; bit_cntr >= 0; bit_cntr--) { + bit = (data >> bit_cntr) & 1; + sda_out(dd, bit); + scl_out(dd, 1); + scl_out(dd, 0); + } + return (!i2c_ackrcv(dd)) ? 1 : 0; +} + +/* + * issue TWSI start sequence: + * (both clock/data high, clock high, data low while clock is high) + */ +static void start_seq(struct qib_devdata *dd) +{ + sda_out(dd, 1); + scl_out(dd, 1); + sda_out(dd, 0); + udelay(1); + scl_out(dd, 0); +} + +/** + * stop_seq - transmit the stop sequence + * @dd: the qlogic_ib device + * + * (both clock/data low, clock high, data high while clock is high) + */ +static void stop_seq(struct qib_devdata *dd) +{ + scl_out(dd, 0); + sda_out(dd, 0); + scl_out(dd, 1); + sda_out(dd, 1); +} + +/** + * stop_cmd - transmit the stop condition + * @dd: the qlogic_ib device + * + * (both clock/data low, clock high, data high while clock is high) + */ +static void stop_cmd(struct qib_devdata *dd) +{ + stop_seq(dd); + udelay(TWSI_BUF_WAIT_USEC); +} + +/** + * qib_twsi_reset - reset I2C communication + * @dd: the qlogic_ib device + */ + +int qib_twsi_reset(struct qib_devdata *dd) +{ + int clock_cycles_left = 9; + int was_high = 0; + u32 pins, mask; + + /* Both SCL and SDA should be high. If not, there + * is something wrong. + */ + mask = (1UL << dd->gpio_scl_num) | (1UL << dd->gpio_sda_num); + + /* + * Force pins to desired innocuous state. + * This is the default power-on state with out=0 and dir=0, + * So tri-stated and should be floating high (barring HW problems) + */ + dd->f_gpio_mod(dd, 0, 0, mask); + + /* + * Clock nine times to get all listeners into a sane state. + * If SDA does not go high at any point, we are wedged. + * One vendor recommends then issuing START followed by STOP. + * we cannot use our "normal" functions to do that, because + * if SCL drops between them, another vendor's part will + * wedge, dropping SDA and keeping it low forever, at the end of + * the next transaction (even if it was not the device addressed). + * So our START and STOP take place with SCL held high. + */ + while (clock_cycles_left--) { + scl_out(dd, 0); + scl_out(dd, 1); + /* Note if SDA is high, but keep clocking to sync slave */ + was_high |= sda_in(dd, 0); + } + + if (was_high) { + /* + * We saw a high, which we hope means the slave is sync'd. + * Issue START, STOP, pause for T_BUF. + */ + + pins = dd->f_gpio_mod(dd, 0, 0, 0); + if ((pins & mask) != mask) + qib_dev_err(dd, "GPIO pins not at rest: %d\n", + pins & mask); + /* Drop SDA to issue START */ + udelay(1); /* Guarantee .6 uSec setup */ + sda_out(dd, 0); + udelay(1); /* Guarantee .6 uSec hold */ + /* At this point, SCL is high, SDA low. Raise SDA for STOP */ + sda_out(dd, 1); + udelay(TWSI_BUF_WAIT_USEC); + } + + return !was_high; +} + +#define QIB_TWSI_START 0x100 +#define QIB_TWSI_STOP 0x200 + +/* Write byte to TWSI, optionally prefixed with START or suffixed with + * STOP. + * returns 0 if OK (ACK received), else != 0 + */ +static int qib_twsi_wr(struct qib_devdata *dd, int data, int flags) +{ + int ret = 1; + if (flags & QIB_TWSI_START) + start_seq(dd); + + ret = wr_byte(dd, data); /* Leaves SCL low (from i2c_ackrcv()) */ + + if (flags & QIB_TWSI_STOP) + stop_cmd(dd); + return ret; +} + +/* Added functionality for IBA7220-based cards */ +#define QIB_TEMP_DEV 0x98 + +/* + * qib_twsi_blk_rd + * Formerly called qib_eeprom_internal_read, and only used for eeprom, + * but now the general interface for data transfer from twsi devices. + * One vestige of its former role is that it recognizes a device + * QIB_TWSI_NO_DEV and does the correct operation for the legacy part, + * which responded to all TWSI device codes, interpreting them as + * address within device. On all other devices found on board handled by + * this driver, the device is followed by a one-byte "address" which selects + * the "register" or "offset" within the device from which data should + * be read. + */ +int qib_twsi_blk_rd(struct qib_devdata *dd, int dev, int addr, + void *buffer, int len) +{ + int ret; + u8 *bp = buffer; + + ret = 1; + + if (dev == QIB_TWSI_NO_DEV) { + /* legacy not-really-I2C */ + addr = (addr << 1) | READ_CMD; + ret = qib_twsi_wr(dd, addr, QIB_TWSI_START); + } else { + /* Actual I2C */ + ret = qib_twsi_wr(dd, dev | WRITE_CMD, QIB_TWSI_START); + if (ret) { + stop_cmd(dd); + ret = 1; + goto bail; + } + /* + * SFF spec claims we do _not_ stop after the addr + * but simply issue a start with the "read" dev-addr. + * Since we are implicitely waiting for ACK here, + * we need t_buf (nominally 20uSec) before that start, + * and cannot rely on the delay built in to the STOP + */ + ret = qib_twsi_wr(dd, addr, 0); + udelay(TWSI_BUF_WAIT_USEC); + + if (ret) { + qib_dev_err(dd, + "Failed to write interface read addr %02X\n", + addr); + ret = 1; + goto bail; + } + ret = qib_twsi_wr(dd, dev | READ_CMD, QIB_TWSI_START); + } + if (ret) { + stop_cmd(dd); + ret = 1; + goto bail; + } + + /* + * block devices keeps clocking data out as long as we ack, + * automatically incrementing the address. Some have "pages" + * whose boundaries will not be crossed, but the handling + * of these is left to the caller, who is in a better + * position to know. + */ + while (len-- > 0) { + /* + * Get and store data, sending ACK if length remaining, + * else STOP + */ + *bp++ = rd_byte(dd, !len); + } + + ret = 0; + +bail: + return ret; +} + +/* + * qib_twsi_blk_wr + * Formerly called qib_eeprom_internal_write, and only used for eeprom, + * but now the general interface for data transfer to twsi devices. + * One vestige of its former role is that it recognizes a device + * QIB_TWSI_NO_DEV and does the correct operation for the legacy part, + * which responded to all TWSI device codes, interpreting them as + * address within device. On all other devices found on board handled by + * this driver, the device is followed by a one-byte "address" which selects + * the "register" or "offset" within the device to which data should + * be written. + */ +int qib_twsi_blk_wr(struct qib_devdata *dd, int dev, int addr, + const void *buffer, int len) +{ + int sub_len; + const u8 *bp = buffer; + int max_wait_time, i; + int ret; + ret = 1; + + while (len > 0) { + if (dev == QIB_TWSI_NO_DEV) { + if (qib_twsi_wr(dd, (addr << 1) | WRITE_CMD, + QIB_TWSI_START)) { + goto failed_write; + } + } else { + /* Real I2C */ + if (qib_twsi_wr(dd, dev | WRITE_CMD, QIB_TWSI_START)) + goto failed_write; + ret = qib_twsi_wr(dd, addr, 0); + if (ret) { + qib_dev_err(dd, "Failed to write interface" + " write addr %02X\n", addr); + goto failed_write; + } + } + + sub_len = min(len, 4); + addr += sub_len; + len -= sub_len; + + for (i = 0; i < sub_len; i++) + if (qib_twsi_wr(dd, *bp++, 0)) + goto failed_write; + + stop_cmd(dd); + + /* + * Wait for write complete by waiting for a successful + * read (the chip replies with a zero after the write + * cmd completes, and before it writes to the eeprom. + * The startcmd for the read will fail the ack until + * the writes have completed. We do this inline to avoid + * the debug prints that are in the real read routine + * if the startcmd fails. + * We also use the proper device address, so it doesn't matter + * whether we have real eeprom_dev. Legacy likes any address. + */ + max_wait_time = 100; + while (qib_twsi_wr(dd, dev | READ_CMD, QIB_TWSI_START)) { + stop_cmd(dd); + if (!--max_wait_time) + goto failed_write; + } + /* now read (and ignore) the resulting byte */ + rd_byte(dd, 1); + } + + ret = 0; + goto bail; + +failed_write: + stop_cmd(dd); + ret = 1; + +bail: + return ret; +} diff --git a/drivers/infiniband/hw/qib/qib_tx.c b/drivers/infiniband/hw/qib/qib_tx.c new file mode 100644 index 000000000000..f7eb1ddff5f3 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_tx.c @@ -0,0 +1,557 @@ +/* + * Copyright (c) 2008, 2009, 2010 QLogic Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include "qib.h" + +static unsigned qib_hol_timeout_ms = 3000; +module_param_named(hol_timeout_ms, qib_hol_timeout_ms, uint, S_IRUGO); +MODULE_PARM_DESC(hol_timeout_ms, + "duration of user app suspension after link failure"); + +unsigned qib_sdma_fetch_arb = 1; +module_param_named(fetch_arb, qib_sdma_fetch_arb, uint, S_IRUGO); +MODULE_PARM_DESC(fetch_arb, "IBA7220: change SDMA descriptor arbitration"); + +/** + * qib_disarm_piobufs - cancel a range of PIO buffers + * @dd: the qlogic_ib device + * @first: the first PIO buffer to cancel + * @cnt: the number of PIO buffers to cancel + * + * Cancel a range of PIO buffers. Used at user process close, + * in case it died while writing to a PIO buffer. + */ +void qib_disarm_piobufs(struct qib_devdata *dd, unsigned first, unsigned cnt) +{ + unsigned long flags; + unsigned i; + unsigned last; + + last = first + cnt; + spin_lock_irqsave(&dd->pioavail_lock, flags); + for (i = first; i < last; i++) { + __clear_bit(i, dd->pio_need_disarm); + dd->f_sendctrl(dd->pport, QIB_SENDCTRL_DISARM_BUF(i)); + } + spin_unlock_irqrestore(&dd->pioavail_lock, flags); +} + +/* + * This is called by a user process when it sees the DISARM_BUFS event + * bit is set. + */ +int qib_disarm_piobufs_ifneeded(struct qib_ctxtdata *rcd) +{ + struct qib_devdata *dd = rcd->dd; + unsigned i; + unsigned last; + unsigned n = 0; + + last = rcd->pio_base + rcd->piocnt; + /* + * Don't need uctxt_lock here, since user has called in to us. + * Clear at start in case more interrupts set bits while we + * are disarming + */ + if (rcd->user_event_mask) { + /* + * subctxt_cnt is 0 if not shared, so do base + * separately, first, then remaining subctxt, if any + */ + clear_bit(_QIB_EVENT_DISARM_BUFS_BIT, &rcd->user_event_mask[0]); + for (i = 1; i < rcd->subctxt_cnt; i++) + clear_bit(_QIB_EVENT_DISARM_BUFS_BIT, + &rcd->user_event_mask[i]); + } + spin_lock_irq(&dd->pioavail_lock); + for (i = rcd->pio_base; i < last; i++) { + if (__test_and_clear_bit(i, dd->pio_need_disarm)) { + n++; + dd->f_sendctrl(rcd->ppd, QIB_SENDCTRL_DISARM_BUF(i)); + } + } + spin_unlock_irq(&dd->pioavail_lock); + return 0; +} + +static struct qib_pportdata *is_sdma_buf(struct qib_devdata *dd, unsigned i) +{ + struct qib_pportdata *ppd; + unsigned pidx; + + for (pidx = 0; pidx < dd->num_pports; pidx++) { + ppd = dd->pport + pidx; + if (i >= ppd->sdma_state.first_sendbuf && + i < ppd->sdma_state.last_sendbuf) + return ppd; + } + return NULL; +} + +/* + * Return true if send buffer is being used by a user context. + * Sets _QIB_EVENT_DISARM_BUFS_BIT in user_event_mask as a side effect + */ +static int find_ctxt(struct qib_devdata *dd, unsigned bufn) +{ + struct qib_ctxtdata *rcd; + unsigned ctxt; + int ret = 0; + + spin_lock(&dd->uctxt_lock); + for (ctxt = dd->first_user_ctxt; ctxt < dd->cfgctxts; ctxt++) { + rcd = dd->rcd[ctxt]; + if (!rcd || bufn < rcd->pio_base || + bufn >= rcd->pio_base + rcd->piocnt) + continue; + if (rcd->user_event_mask) { + int i; + /* + * subctxt_cnt is 0 if not shared, so do base + * separately, first, then remaining subctxt, if any + */ + set_bit(_QIB_EVENT_DISARM_BUFS_BIT, + &rcd->user_event_mask[0]); + for (i = 1; i < rcd->subctxt_cnt; i++) + set_bit(_QIB_EVENT_DISARM_BUFS_BIT, + &rcd->user_event_mask[i]); + } + ret = 1; + break; + } + spin_unlock(&dd->uctxt_lock); + + return ret; +} + +/* + * Disarm a set of send buffers. If the buffer might be actively being + * written to, mark the buffer to be disarmed later when it is not being + * written to. + * + * This should only be called from the IRQ error handler. + */ +void qib_disarm_piobufs_set(struct qib_devdata *dd, unsigned long *mask, + unsigned cnt) +{ + struct qib_pportdata *ppd, *pppd[dd->num_pports]; + unsigned i; + unsigned long flags; + + for (i = 0; i < dd->num_pports; i++) + pppd[i] = NULL; + + for (i = 0; i < cnt; i++) { + int which; + if (!test_bit(i, mask)) + continue; + /* + * If the buffer is owned by the DMA hardware, + * reset the DMA engine. + */ + ppd = is_sdma_buf(dd, i); + if (ppd) { + pppd[ppd->port] = ppd; + continue; + } + /* + * If the kernel is writing the buffer or the buffer is + * owned by a user process, we can't clear it yet. + */ + spin_lock_irqsave(&dd->pioavail_lock, flags); + if (test_bit(i, dd->pio_writing) || + (!test_bit(i << 1, dd->pioavailkernel) && + find_ctxt(dd, i))) { + __set_bit(i, dd->pio_need_disarm); + which = 0; + } else { + which = 1; + dd->f_sendctrl(dd->pport, QIB_SENDCTRL_DISARM_BUF(i)); + } + spin_unlock_irqrestore(&dd->pioavail_lock, flags); + } + + /* do cancel_sends once per port that had sdma piobufs in error */ + for (i = 0; i < dd->num_pports; i++) + if (pppd[i]) + qib_cancel_sends(pppd[i]); +} + +/** + * update_send_bufs - update shadow copy of the PIO availability map + * @dd: the qlogic_ib device + * + * called whenever our local copy indicates we have run out of send buffers + */ +static void update_send_bufs(struct qib_devdata *dd) +{ + unsigned long flags; + unsigned i; + const unsigned piobregs = dd->pioavregs; + + /* + * If the generation (check) bits have changed, then we update the + * busy bit for the corresponding PIO buffer. This algorithm will + * modify positions to the value they already have in some cases + * (i.e., no change), but it's faster than changing only the bits + * that have changed. + * + * We would like to do this atomicly, to avoid spinlocks in the + * critical send path, but that's not really possible, given the + * type of changes, and that this routine could be called on + * multiple cpu's simultaneously, so we lock in this routine only, + * to avoid conflicting updates; all we change is the shadow, and + * it's a single 64 bit memory location, so by definition the update + * is atomic in terms of what other cpu's can see in testing the + * bits. The spin_lock overhead isn't too bad, since it only + * happens when all buffers are in use, so only cpu overhead, not + * latency or bandwidth is affected. + */ + if (!dd->pioavailregs_dma) + return; + spin_lock_irqsave(&dd->pioavail_lock, flags); + for (i = 0; i < piobregs; i++) { + u64 pchbusy, pchg, piov, pnew; + + piov = le64_to_cpu(dd->pioavailregs_dma[i]); + pchg = dd->pioavailkernel[i] & + ~(dd->pioavailshadow[i] ^ piov); + pchbusy = pchg << QLOGIC_IB_SENDPIOAVAIL_BUSY_SHIFT; + if (pchg && (pchbusy & dd->pioavailshadow[i])) { + pnew = dd->pioavailshadow[i] & ~pchbusy; + pnew |= piov & pchbusy; + dd->pioavailshadow[i] = pnew; + } + } + spin_unlock_irqrestore(&dd->pioavail_lock, flags); +} + +/* + * Debugging code and stats updates if no pio buffers available. + */ +static noinline void no_send_bufs(struct qib_devdata *dd) +{ + dd->upd_pio_shadow = 1; + + /* not atomic, but if we lose a stat count in a while, that's OK */ + qib_stats.sps_nopiobufs++; +} + +/* + * Common code for normal driver send buffer allocation, and reserved + * allocation. + * + * Do appropriate marking as busy, etc. + * Returns buffer pointer if one is found, otherwise NULL. + */ +u32 __iomem *qib_getsendbuf_range(struct qib_devdata *dd, u32 *pbufnum, + u32 first, u32 last) +{ + unsigned i, j, updated = 0; + unsigned nbufs; + unsigned long flags; + unsigned long *shadow = dd->pioavailshadow; + u32 __iomem *buf; + + if (!(dd->flags & QIB_PRESENT)) + return NULL; + + nbufs = last - first + 1; /* number in range to check */ + if (dd->upd_pio_shadow) { + /* + * Minor optimization. If we had no buffers on last call, + * start out by doing the update; continue and do scan even + * if no buffers were updated, to be paranoid. + */ + update_send_bufs(dd); + updated++; + } + i = first; +rescan: + /* + * While test_and_set_bit() is atomic, we do that and then the + * change_bit(), and the pair is not. See if this is the cause + * of the remaining armlaunch errors. + */ + spin_lock_irqsave(&dd->pioavail_lock, flags); + for (j = 0; j < nbufs; j++, i++) { + if (i > last) + i = first; + if (__test_and_set_bit((2 * i) + 1, shadow)) + continue; + /* flip generation bit */ + __change_bit(2 * i, shadow); + /* remember that the buffer can be written to now */ + __set_bit(i, dd->pio_writing); + break; + } + spin_unlock_irqrestore(&dd->pioavail_lock, flags); + + if (j == nbufs) { + if (!updated) { + /* + * First time through; shadow exhausted, but may be + * buffers available, try an update and then rescan. + */ + update_send_bufs(dd); + updated++; + i = first; + goto rescan; + } + no_send_bufs(dd); + buf = NULL; + } else { + if (i < dd->piobcnt2k) + buf = (u32 __iomem *)(dd->pio2kbase + + i * dd->palign); + else + buf = (u32 __iomem *)(dd->pio4kbase + + (i - dd->piobcnt2k) * dd->align4k); + if (pbufnum) + *pbufnum = i; + dd->upd_pio_shadow = 0; + } + + return buf; +} + +/* + * Record that the caller is finished writing to the buffer so we don't + * disarm it while it is being written and disarm it now if needed. + */ +void qib_sendbuf_done(struct qib_devdata *dd, unsigned n) +{ + unsigned long flags; + + spin_lock_irqsave(&dd->pioavail_lock, flags); + __clear_bit(n, dd->pio_writing); + if (__test_and_clear_bit(n, dd->pio_need_disarm)) + dd->f_sendctrl(dd->pport, QIB_SENDCTRL_DISARM_BUF(n)); + spin_unlock_irqrestore(&dd->pioavail_lock, flags); +} + +/** + * qib_chg_pioavailkernel - change which send buffers are available for kernel + * @dd: the qlogic_ib device + * @start: the starting send buffer number + * @len: the number of send buffers + * @avail: true if the buffers are available for kernel use, false otherwise + */ +void qib_chg_pioavailkernel(struct qib_devdata *dd, unsigned start, + unsigned len, u32 avail, struct qib_ctxtdata *rcd) +{ + unsigned long flags; + unsigned end; + unsigned ostart = start; + + /* There are two bits per send buffer (busy and generation) */ + start *= 2; + end = start + len * 2; + + spin_lock_irqsave(&dd->pioavail_lock, flags); + /* Set or clear the busy bit in the shadow. */ + while (start < end) { + if (avail) { + unsigned long dma; + int i; + + /* + * The BUSY bit will never be set, because we disarm + * the user buffers before we hand them back to the + * kernel. We do have to make sure the generation + * bit is set correctly in shadow, since it could + * have changed many times while allocated to user. + * We can't use the bitmap functions on the full + * dma array because it is always little-endian, so + * we have to flip to host-order first. + * BITS_PER_LONG is slightly wrong, since it's + * always 64 bits per register in chip... + * We only work on 64 bit kernels, so that's OK. + */ + i = start / BITS_PER_LONG; + __clear_bit(QLOGIC_IB_SENDPIOAVAIL_BUSY_SHIFT + start, + dd->pioavailshadow); + dma = (unsigned long) + le64_to_cpu(dd->pioavailregs_dma[i]); + if (test_bit((QLOGIC_IB_SENDPIOAVAIL_CHECK_SHIFT + + start) % BITS_PER_LONG, &dma)) + __set_bit(QLOGIC_IB_SENDPIOAVAIL_CHECK_SHIFT + + start, dd->pioavailshadow); + else + __clear_bit(QLOGIC_IB_SENDPIOAVAIL_CHECK_SHIFT + + start, dd->pioavailshadow); + __set_bit(start, dd->pioavailkernel); + } else { + __set_bit(start + QLOGIC_IB_SENDPIOAVAIL_BUSY_SHIFT, + dd->pioavailshadow); + __clear_bit(start, dd->pioavailkernel); + } + start += 2; + } + + spin_unlock_irqrestore(&dd->pioavail_lock, flags); + + dd->f_txchk_change(dd, ostart, len, avail, rcd); +} + +/* + * Flush all sends that might be in the ready to send state, as well as any + * that are in the process of being sent. Used whenever we need to be + * sure the send side is idle. Cleans up all buffer state by canceling + * all pio buffers, and issuing an abort, which cleans up anything in the + * launch fifo. The cancel is superfluous on some chip versions, but + * it's safer to always do it. + * PIOAvail bits are updated by the chip as if a normal send had happened. + */ +void qib_cancel_sends(struct qib_pportdata *ppd) +{ + struct qib_devdata *dd = ppd->dd; + struct qib_ctxtdata *rcd; + unsigned long flags; + unsigned ctxt; + unsigned i; + unsigned last; + + /* + * Tell PSM to disarm buffers again before trying to reuse them. + * We need to be sure the rcd doesn't change out from under us + * while we do so. We hold the two locks sequentially. We might + * needlessly set some need_disarm bits as a result, if the + * context is closed after we release the uctxt_lock, but that's + * fairly benign, and safer than nesting the locks. + */ + for (ctxt = dd->first_user_ctxt; ctxt < dd->cfgctxts; ctxt++) { + spin_lock_irqsave(&dd->uctxt_lock, flags); + rcd = dd->rcd[ctxt]; + if (rcd && rcd->ppd == ppd) { + last = rcd->pio_base + rcd->piocnt; + if (rcd->user_event_mask) { + /* + * subctxt_cnt is 0 if not shared, so do base + * separately, first, then remaining subctxt, + * if any + */ + set_bit(_QIB_EVENT_DISARM_BUFS_BIT, + &rcd->user_event_mask[0]); + for (i = 1; i < rcd->subctxt_cnt; i++) + set_bit(_QIB_EVENT_DISARM_BUFS_BIT, + &rcd->user_event_mask[i]); + } + i = rcd->pio_base; + spin_unlock_irqrestore(&dd->uctxt_lock, flags); + spin_lock_irqsave(&dd->pioavail_lock, flags); + for (; i < last; i++) + __set_bit(i, dd->pio_need_disarm); + spin_unlock_irqrestore(&dd->pioavail_lock, flags); + } else + spin_unlock_irqrestore(&dd->uctxt_lock, flags); + } + + if (!(dd->flags & QIB_HAS_SEND_DMA)) + dd->f_sendctrl(ppd, QIB_SENDCTRL_DISARM_ALL | + QIB_SENDCTRL_FLUSH); +} + +/* + * Force an update of in-memory copy of the pioavail registers, when + * needed for any of a variety of reasons. + * If already off, this routine is a nop, on the assumption that the + * caller (or set of callers) will "do the right thing". + * This is a per-device operation, so just the first port. + */ +void qib_force_pio_avail_update(struct qib_devdata *dd) +{ + dd->f_sendctrl(dd->pport, QIB_SENDCTRL_AVAIL_BLIP); +} + +void qib_hol_down(struct qib_pportdata *ppd) +{ + /* + * Cancel sends when the link goes DOWN so that we aren't doing it + * at INIT when we might be trying to send SMI packets. + */ + if (!(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) + qib_cancel_sends(ppd); +} + +/* + * Link is at INIT. + * We start the HoL timer so we can detect stuck packets blocking SMP replies. + * Timer may already be running, so use mod_timer, not add_timer. + */ +void qib_hol_init(struct qib_pportdata *ppd) +{ + if (ppd->hol_state != QIB_HOL_INIT) { + ppd->hol_state = QIB_HOL_INIT; + mod_timer(&ppd->hol_timer, + jiffies + msecs_to_jiffies(qib_hol_timeout_ms)); + } +} + +/* + * Link is up, continue any user processes, and ensure timer + * is a nop, if running. Let timer keep running, if set; it + * will nop when it sees the link is up. + */ +void qib_hol_up(struct qib_pportdata *ppd) +{ + ppd->hol_state = QIB_HOL_UP; +} + +/* + * This is only called via the timer. + */ +void qib_hol_event(unsigned long opaque) +{ + struct qib_pportdata *ppd = (struct qib_pportdata *)opaque; + + /* If hardware error, etc, skip. */ + if (!(ppd->dd->flags & QIB_INITTED)) + return; + + if (ppd->hol_state != QIB_HOL_UP) { + /* + * Try to flush sends in case a stuck packet is blocking + * SMP replies. + */ + qib_hol_down(ppd); + mod_timer(&ppd->hol_timer, + jiffies + msecs_to_jiffies(qib_hol_timeout_ms)); + } +} diff --git a/drivers/infiniband/hw/qib/qib_uc.c b/drivers/infiniband/hw/qib/qib_uc.c new file mode 100644 index 000000000000..6c7fe78cca64 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_uc.c @@ -0,0 +1,555 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation. + * All rights reserved. + * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "qib.h" + +/* cut down ridiculously long IB macro names */ +#define OP(x) IB_OPCODE_UC_##x + +/** + * qib_make_uc_req - construct a request packet (SEND, RDMA write) + * @qp: a pointer to the QP + * + * Return 1 if constructed; otherwise, return 0. + */ +int qib_make_uc_req(struct qib_qp *qp) +{ + struct qib_other_headers *ohdr; + struct qib_swqe *wqe; + unsigned long flags; + u32 hwords; + u32 bth0; + u32 len; + u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu); + int ret = 0; + + spin_lock_irqsave(&qp->s_lock, flags); + + if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_SEND_OK)) { + if (!(ib_qib_state_ops[qp->state] & QIB_FLUSH_SEND)) + goto bail; + /* We are in the error state, flush the work request. */ + if (qp->s_last == qp->s_head) + goto bail; + /* If DMAs are in progress, we can't flush immediately. */ + if (atomic_read(&qp->s_dma_busy)) { + qp->s_flags |= QIB_S_WAIT_DMA; + goto bail; + } + wqe = get_swqe_ptr(qp, qp->s_last); + qib_send_complete(qp, wqe, IB_WC_WR_FLUSH_ERR); + goto done; + } + + ohdr = &qp->s_hdr.u.oth; + if (qp->remote_ah_attr.ah_flags & IB_AH_GRH) + ohdr = &qp->s_hdr.u.l.oth; + + /* header size in 32-bit words LRH+BTH = (8+12)/4. */ + hwords = 5; + bth0 = 0; + + /* Get the next send request. */ + wqe = get_swqe_ptr(qp, qp->s_cur); + qp->s_wqe = NULL; + switch (qp->s_state) { + default: + if (!(ib_qib_state_ops[qp->state] & + QIB_PROCESS_NEXT_SEND_OK)) + goto bail; + /* Check if send work queue is empty. */ + if (qp->s_cur == qp->s_head) + goto bail; + /* + * Start a new request. + */ + wqe->psn = qp->s_next_psn; + qp->s_psn = qp->s_next_psn; + qp->s_sge.sge = wqe->sg_list[0]; + qp->s_sge.sg_list = wqe->sg_list + 1; + qp->s_sge.num_sge = wqe->wr.num_sge; + qp->s_sge.total_len = wqe->length; + len = wqe->length; + qp->s_len = len; + switch (wqe->wr.opcode) { + case IB_WR_SEND: + case IB_WR_SEND_WITH_IMM: + if (len > pmtu) { + qp->s_state = OP(SEND_FIRST); + len = pmtu; + break; + } + if (wqe->wr.opcode == IB_WR_SEND) + qp->s_state = OP(SEND_ONLY); + else { + qp->s_state = + OP(SEND_ONLY_WITH_IMMEDIATE); + /* Immediate data comes after the BTH */ + ohdr->u.imm_data = wqe->wr.ex.imm_data; + hwords += 1; + } + if (wqe->wr.send_flags & IB_SEND_SOLICITED) + bth0 |= IB_BTH_SOLICITED; + qp->s_wqe = wqe; + if (++qp->s_cur >= qp->s_size) + qp->s_cur = 0; + break; + + case IB_WR_RDMA_WRITE: + case IB_WR_RDMA_WRITE_WITH_IMM: + ohdr->u.rc.reth.vaddr = + cpu_to_be64(wqe->wr.wr.rdma.remote_addr); + ohdr->u.rc.reth.rkey = + cpu_to_be32(wqe->wr.wr.rdma.rkey); + ohdr->u.rc.reth.length = cpu_to_be32(len); + hwords += sizeof(struct ib_reth) / 4; + if (len > pmtu) { + qp->s_state = OP(RDMA_WRITE_FIRST); + len = pmtu; + break; + } + if (wqe->wr.opcode == IB_WR_RDMA_WRITE) + qp->s_state = OP(RDMA_WRITE_ONLY); + else { + qp->s_state = + OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE); + /* Immediate data comes after the RETH */ + ohdr->u.rc.imm_data = wqe->wr.ex.imm_data; + hwords += 1; + if (wqe->wr.send_flags & IB_SEND_SOLICITED) + bth0 |= IB_BTH_SOLICITED; + } + qp->s_wqe = wqe; + if (++qp->s_cur >= qp->s_size) + qp->s_cur = 0; + break; + + default: + goto bail; + } + break; + + case OP(SEND_FIRST): + qp->s_state = OP(SEND_MIDDLE); + /* FALLTHROUGH */ + case OP(SEND_MIDDLE): + len = qp->s_len; + if (len > pmtu) { + len = pmtu; + break; + } + if (wqe->wr.opcode == IB_WR_SEND) + qp->s_state = OP(SEND_LAST); + else { + qp->s_state = OP(SEND_LAST_WITH_IMMEDIATE); + /* Immediate data comes after the BTH */ + ohdr->u.imm_data = wqe->wr.ex.imm_data; + hwords += 1; + } + if (wqe->wr.send_flags & IB_SEND_SOLICITED) + bth0 |= IB_BTH_SOLICITED; + qp->s_wqe = wqe; + if (++qp->s_cur >= qp->s_size) + qp->s_cur = 0; + break; + + case OP(RDMA_WRITE_FIRST): + qp->s_state = OP(RDMA_WRITE_MIDDLE); + /* FALLTHROUGH */ + case OP(RDMA_WRITE_MIDDLE): + len = qp->s_len; + if (len > pmtu) { + len = pmtu; + break; + } + if (wqe->wr.opcode == IB_WR_RDMA_WRITE) + qp->s_state = OP(RDMA_WRITE_LAST); + else { + qp->s_state = + OP(RDMA_WRITE_LAST_WITH_IMMEDIATE); + /* Immediate data comes after the BTH */ + ohdr->u.imm_data = wqe->wr.ex.imm_data; + hwords += 1; + if (wqe->wr.send_flags & IB_SEND_SOLICITED) + bth0 |= IB_BTH_SOLICITED; + } + qp->s_wqe = wqe; + if (++qp->s_cur >= qp->s_size) + qp->s_cur = 0; + break; + } + qp->s_len -= len; + qp->s_hdrwords = hwords; + qp->s_cur_sge = &qp->s_sge; + qp->s_cur_size = len; + qib_make_ruc_header(qp, ohdr, bth0 | (qp->s_state << 24), + qp->s_next_psn++ & QIB_PSN_MASK); +done: + ret = 1; + goto unlock; + +bail: + qp->s_flags &= ~QIB_S_BUSY; +unlock: + spin_unlock_irqrestore(&qp->s_lock, flags); + return ret; +} + +/** + * qib_uc_rcv - handle an incoming UC packet + * @ibp: the port the packet came in on + * @hdr: the header of the packet + * @has_grh: true if the packet has a GRH + * @data: the packet data + * @tlen: the length of the packet + * @qp: the QP for this packet. + * + * This is called from qib_qp_rcv() to process an incoming UC packet + * for the given QP. + * Called at interrupt level. + */ +void qib_uc_rcv(struct qib_ibport *ibp, struct qib_ib_header *hdr, + int has_grh, void *data, u32 tlen, struct qib_qp *qp) +{ + struct qib_other_headers *ohdr; + unsigned long flags; + u32 opcode; + u32 hdrsize; + u32 psn; + u32 pad; + struct ib_wc wc; + u32 pmtu = ib_mtu_enum_to_int(qp->path_mtu); + struct ib_reth *reth; + int ret; + + /* Check for GRH */ + if (!has_grh) { + ohdr = &hdr->u.oth; + hdrsize = 8 + 12; /* LRH + BTH */ + } else { + ohdr = &hdr->u.l.oth; + hdrsize = 8 + 40 + 12; /* LRH + GRH + BTH */ + } + + opcode = be32_to_cpu(ohdr->bth[0]); + spin_lock_irqsave(&qp->s_lock, flags); + if (qib_ruc_check_hdr(ibp, hdr, has_grh, qp, opcode)) + goto sunlock; + spin_unlock_irqrestore(&qp->s_lock, flags); + + psn = be32_to_cpu(ohdr->bth[2]); + opcode >>= 24; + memset(&wc, 0, sizeof wc); + + /* Prevent simultaneous processing after APM on different CPUs */ + spin_lock(&qp->r_lock); + + /* Compare the PSN verses the expected PSN. */ + if (unlikely(qib_cmp24(psn, qp->r_psn) != 0)) { + /* + * Handle a sequence error. + * Silently drop any current message. + */ + qp->r_psn = psn; +inv: + if (qp->r_state == OP(SEND_FIRST) || + qp->r_state == OP(SEND_MIDDLE)) { + set_bit(QIB_R_REWIND_SGE, &qp->r_aflags); + qp->r_sge.num_sge = 0; + } else + while (qp->r_sge.num_sge) { + atomic_dec(&qp->r_sge.sge.mr->refcount); + if (--qp->r_sge.num_sge) + qp->r_sge.sge = *qp->r_sge.sg_list++; + } + qp->r_state = OP(SEND_LAST); + switch (opcode) { + case OP(SEND_FIRST): + case OP(SEND_ONLY): + case OP(SEND_ONLY_WITH_IMMEDIATE): + goto send_first; + + case OP(RDMA_WRITE_FIRST): + case OP(RDMA_WRITE_ONLY): + case OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE): + goto rdma_first; + + default: + goto drop; + } + } + + /* Check for opcode sequence errors. */ + switch (qp->r_state) { + case OP(SEND_FIRST): + case OP(SEND_MIDDLE): + if (opcode == OP(SEND_MIDDLE) || + opcode == OP(SEND_LAST) || + opcode == OP(SEND_LAST_WITH_IMMEDIATE)) + break; + goto inv; + + case OP(RDMA_WRITE_FIRST): + case OP(RDMA_WRITE_MIDDLE): + if (opcode == OP(RDMA_WRITE_MIDDLE) || + opcode == OP(RDMA_WRITE_LAST) || + opcode == OP(RDMA_WRITE_LAST_WITH_IMMEDIATE)) + break; + goto inv; + + default: + if (opcode == OP(SEND_FIRST) || + opcode == OP(SEND_ONLY) || + opcode == OP(SEND_ONLY_WITH_IMMEDIATE) || + opcode == OP(RDMA_WRITE_FIRST) || + opcode == OP(RDMA_WRITE_ONLY) || + opcode == OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE)) + break; + goto inv; + } + + if (qp->state == IB_QPS_RTR && !(qp->r_flags & QIB_R_COMM_EST)) { + qp->r_flags |= QIB_R_COMM_EST; + if (qp->ibqp.event_handler) { + struct ib_event ev; + + ev.device = qp->ibqp.device; + ev.element.qp = &qp->ibqp; + ev.event = IB_EVENT_COMM_EST; + qp->ibqp.event_handler(&ev, qp->ibqp.qp_context); + } + } + + /* OK, process the packet. */ + switch (opcode) { + case OP(SEND_FIRST): + case OP(SEND_ONLY): + case OP(SEND_ONLY_WITH_IMMEDIATE): +send_first: + if (test_and_clear_bit(QIB_R_REWIND_SGE, &qp->r_aflags)) + qp->r_sge = qp->s_rdma_read_sge; + else { + ret = qib_get_rwqe(qp, 0); + if (ret < 0) + goto op_err; + if (!ret) + goto drop; + /* + * qp->s_rdma_read_sge will be the owner + * of the mr references. + */ + qp->s_rdma_read_sge = qp->r_sge; + } + qp->r_rcv_len = 0; + if (opcode == OP(SEND_ONLY)) + goto send_last; + else if (opcode == OP(SEND_ONLY_WITH_IMMEDIATE)) + goto send_last_imm; + /* FALLTHROUGH */ + case OP(SEND_MIDDLE): + /* Check for invalid length PMTU or posted rwqe len. */ + if (unlikely(tlen != (hdrsize + pmtu + 4))) + goto rewind; + qp->r_rcv_len += pmtu; + if (unlikely(qp->r_rcv_len > qp->r_len)) + goto rewind; + qib_copy_sge(&qp->r_sge, data, pmtu, 0); + break; + + case OP(SEND_LAST_WITH_IMMEDIATE): +send_last_imm: + wc.ex.imm_data = ohdr->u.imm_data; + hdrsize += 4; + wc.wc_flags = IB_WC_WITH_IMM; + /* FALLTHROUGH */ + case OP(SEND_LAST): +send_last: + /* Get the number of bytes the message was padded by. */ + pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3; + /* Check for invalid length. */ + /* XXX LAST len should be >= 1 */ + if (unlikely(tlen < (hdrsize + pad + 4))) + goto rewind; + /* Don't count the CRC. */ + tlen -= (hdrsize + pad + 4); + wc.byte_len = tlen + qp->r_rcv_len; + if (unlikely(wc.byte_len > qp->r_len)) + goto rewind; + wc.opcode = IB_WC_RECV; +last_imm: + qib_copy_sge(&qp->r_sge, data, tlen, 0); + while (qp->s_rdma_read_sge.num_sge) { + atomic_dec(&qp->s_rdma_read_sge.sge.mr->refcount); + if (--qp->s_rdma_read_sge.num_sge) + qp->s_rdma_read_sge.sge = + *qp->s_rdma_read_sge.sg_list++; + } + wc.wr_id = qp->r_wr_id; + wc.status = IB_WC_SUCCESS; + wc.qp = &qp->ibqp; + wc.src_qp = qp->remote_qpn; + wc.slid = qp->remote_ah_attr.dlid; + wc.sl = qp->remote_ah_attr.sl; + /* Signal completion event if the solicited bit is set. */ + qib_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, + (ohdr->bth[0] & + cpu_to_be32(IB_BTH_SOLICITED)) != 0); + break; + + case OP(RDMA_WRITE_FIRST): + case OP(RDMA_WRITE_ONLY): + case OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE): /* consume RWQE */ +rdma_first: + if (unlikely(!(qp->qp_access_flags & + IB_ACCESS_REMOTE_WRITE))) { + goto drop; + } + reth = &ohdr->u.rc.reth; + hdrsize += sizeof(*reth); + qp->r_len = be32_to_cpu(reth->length); + qp->r_rcv_len = 0; + qp->r_sge.sg_list = NULL; + if (qp->r_len != 0) { + u32 rkey = be32_to_cpu(reth->rkey); + u64 vaddr = be64_to_cpu(reth->vaddr); + int ok; + + /* Check rkey */ + ok = qib_rkey_ok(qp, &qp->r_sge.sge, qp->r_len, + vaddr, rkey, IB_ACCESS_REMOTE_WRITE); + if (unlikely(!ok)) + goto drop; + qp->r_sge.num_sge = 1; + } else { + qp->r_sge.num_sge = 0; + qp->r_sge.sge.mr = NULL; + qp->r_sge.sge.vaddr = NULL; + qp->r_sge.sge.length = 0; + qp->r_sge.sge.sge_length = 0; + } + if (opcode == OP(RDMA_WRITE_ONLY)) + goto rdma_last; + else if (opcode == OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE)) + goto rdma_last_imm; + /* FALLTHROUGH */ + case OP(RDMA_WRITE_MIDDLE): + /* Check for invalid length PMTU or posted rwqe len. */ + if (unlikely(tlen != (hdrsize + pmtu + 4))) + goto drop; + qp->r_rcv_len += pmtu; + if (unlikely(qp->r_rcv_len > qp->r_len)) + goto drop; + qib_copy_sge(&qp->r_sge, data, pmtu, 1); + break; + + case OP(RDMA_WRITE_LAST_WITH_IMMEDIATE): +rdma_last_imm: + wc.ex.imm_data = ohdr->u.imm_data; + hdrsize += 4; + wc.wc_flags = IB_WC_WITH_IMM; + + /* Get the number of bytes the message was padded by. */ + pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3; + /* Check for invalid length. */ + /* XXX LAST len should be >= 1 */ + if (unlikely(tlen < (hdrsize + pad + 4))) + goto drop; + /* Don't count the CRC. */ + tlen -= (hdrsize + pad + 4); + if (unlikely(tlen + qp->r_rcv_len != qp->r_len)) + goto drop; + if (test_and_clear_bit(QIB_R_REWIND_SGE, &qp->r_aflags)) + while (qp->s_rdma_read_sge.num_sge) { + atomic_dec(&qp->s_rdma_read_sge.sge.mr-> + refcount); + if (--qp->s_rdma_read_sge.num_sge) + qp->s_rdma_read_sge.sge = + *qp->s_rdma_read_sge.sg_list++; + } + else { + ret = qib_get_rwqe(qp, 1); + if (ret < 0) + goto op_err; + if (!ret) + goto drop; + } + wc.byte_len = qp->r_len; + wc.opcode = IB_WC_RECV_RDMA_WITH_IMM; + goto last_imm; + + case OP(RDMA_WRITE_LAST): +rdma_last: + /* Get the number of bytes the message was padded by. */ + pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3; + /* Check for invalid length. */ + /* XXX LAST len should be >= 1 */ + if (unlikely(tlen < (hdrsize + pad + 4))) + goto drop; + /* Don't count the CRC. */ + tlen -= (hdrsize + pad + 4); + if (unlikely(tlen + qp->r_rcv_len != qp->r_len)) + goto drop; + qib_copy_sge(&qp->r_sge, data, tlen, 1); + while (qp->r_sge.num_sge) { + atomic_dec(&qp->r_sge.sge.mr->refcount); + if (--qp->r_sge.num_sge) + qp->r_sge.sge = *qp->r_sge.sg_list++; + } + break; + + default: + /* Drop packet for unknown opcodes. */ + goto drop; + } + qp->r_psn++; + qp->r_state = opcode; + spin_unlock(&qp->r_lock); + return; + +rewind: + set_bit(QIB_R_REWIND_SGE, &qp->r_aflags); + qp->r_sge.num_sge = 0; +drop: + ibp->n_pkt_drops++; + spin_unlock(&qp->r_lock); + return; + +op_err: + qib_rc_error(qp, IB_WC_LOC_QP_OP_ERR); + spin_unlock(&qp->r_lock); + return; + +sunlock: + spin_unlock_irqrestore(&qp->s_lock, flags); +} diff --git a/drivers/infiniband/hw/qib/qib_ud.c b/drivers/infiniband/hw/qib/qib_ud.c new file mode 100644 index 000000000000..c838cda73347 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_ud.c @@ -0,0 +1,607 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. + * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include + +#include "qib.h" +#include "qib_mad.h" + +/** + * qib_ud_loopback - handle send on loopback QPs + * @sqp: the sending QP + * @swqe: the send work request + * + * This is called from qib_make_ud_req() to forward a WQE addressed + * to the same HCA. + * Note that the receive interrupt handler may be calling qib_ud_rcv() + * while this is being called. + */ +static void qib_ud_loopback(struct qib_qp *sqp, struct qib_swqe *swqe) +{ + struct qib_ibport *ibp = to_iport(sqp->ibqp.device, sqp->port_num); + struct qib_pportdata *ppd; + struct qib_qp *qp; + struct ib_ah_attr *ah_attr; + unsigned long flags; + struct qib_sge_state ssge; + struct qib_sge *sge; + struct ib_wc wc; + u32 length; + + qp = qib_lookup_qpn(ibp, swqe->wr.wr.ud.remote_qpn); + if (!qp) { + ibp->n_pkt_drops++; + return; + } + if (qp->ibqp.qp_type != sqp->ibqp.qp_type || + !(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) { + ibp->n_pkt_drops++; + goto drop; + } + + ah_attr = &to_iah(swqe->wr.wr.ud.ah)->attr; + ppd = ppd_from_ibp(ibp); + + if (qp->ibqp.qp_num > 1) { + u16 pkey1; + u16 pkey2; + u16 lid; + + pkey1 = qib_get_pkey(ibp, sqp->s_pkey_index); + pkey2 = qib_get_pkey(ibp, qp->s_pkey_index); + if (unlikely(!qib_pkey_ok(pkey1, pkey2))) { + lid = ppd->lid | (ah_attr->src_path_bits & + ((1 << ppd->lmc) - 1)); + qib_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_PKEY, pkey1, + ah_attr->sl, + sqp->ibqp.qp_num, qp->ibqp.qp_num, + cpu_to_be16(lid), + cpu_to_be16(ah_attr->dlid)); + goto drop; + } + } + + /* + * Check that the qkey matches (except for QP0, see 9.6.1.4.1). + * Qkeys with the high order bit set mean use the + * qkey from the QP context instead of the WR (see 10.2.5). + */ + if (qp->ibqp.qp_num) { + u32 qkey; + + qkey = (int)swqe->wr.wr.ud.remote_qkey < 0 ? + sqp->qkey : swqe->wr.wr.ud.remote_qkey; + if (unlikely(qkey != qp->qkey)) { + u16 lid; + + lid = ppd->lid | (ah_attr->src_path_bits & + ((1 << ppd->lmc) - 1)); + qib_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_QKEY, qkey, + ah_attr->sl, + sqp->ibqp.qp_num, qp->ibqp.qp_num, + cpu_to_be16(lid), + cpu_to_be16(ah_attr->dlid)); + goto drop; + } + } + + /* + * A GRH is expected to preceed the data even if not + * present on the wire. + */ + length = swqe->length; + memset(&wc, 0, sizeof wc); + wc.byte_len = length + sizeof(struct ib_grh); + + if (swqe->wr.opcode == IB_WR_SEND_WITH_IMM) { + wc.wc_flags = IB_WC_WITH_IMM; + wc.ex.imm_data = swqe->wr.ex.imm_data; + } + + spin_lock_irqsave(&qp->r_lock, flags); + + /* + * Get the next work request entry to find where to put the data. + */ + if (qp->r_flags & QIB_R_REUSE_SGE) + qp->r_flags &= ~QIB_R_REUSE_SGE; + else { + int ret; + + ret = qib_get_rwqe(qp, 0); + if (ret < 0) { + qib_rc_error(qp, IB_WC_LOC_QP_OP_ERR); + goto bail_unlock; + } + if (!ret) { + if (qp->ibqp.qp_num == 0) + ibp->n_vl15_dropped++; + goto bail_unlock; + } + } + /* Silently drop packets which are too big. */ + if (unlikely(wc.byte_len > qp->r_len)) { + qp->r_flags |= QIB_R_REUSE_SGE; + ibp->n_pkt_drops++; + goto bail_unlock; + } + + if (ah_attr->ah_flags & IB_AH_GRH) { + qib_copy_sge(&qp->r_sge, &ah_attr->grh, + sizeof(struct ib_grh), 1); + wc.wc_flags |= IB_WC_GRH; + } else + qib_skip_sge(&qp->r_sge, sizeof(struct ib_grh), 1); + ssge.sg_list = swqe->sg_list + 1; + ssge.sge = *swqe->sg_list; + ssge.num_sge = swqe->wr.num_sge; + sge = &ssge.sge; + while (length) { + u32 len = sge->length; + + if (len > length) + len = length; + if (len > sge->sge_length) + len = sge->sge_length; + BUG_ON(len == 0); + qib_copy_sge(&qp->r_sge, sge->vaddr, len, 1); + sge->vaddr += len; + sge->length -= len; + sge->sge_length -= len; + if (sge->sge_length == 0) { + if (--ssge.num_sge) + *sge = *ssge.sg_list++; + } else if (sge->length == 0 && sge->mr->lkey) { + if (++sge->n >= QIB_SEGSZ) { + if (++sge->m >= sge->mr->mapsz) + break; + sge->n = 0; + } + sge->vaddr = + sge->mr->map[sge->m]->segs[sge->n].vaddr; + sge->length = + sge->mr->map[sge->m]->segs[sge->n].length; + } + length -= len; + } + while (qp->r_sge.num_sge) { + atomic_dec(&qp->r_sge.sge.mr->refcount); + if (--qp->r_sge.num_sge) + qp->r_sge.sge = *qp->r_sge.sg_list++; + } + if (!test_and_clear_bit(QIB_R_WRID_VALID, &qp->r_aflags)) + goto bail_unlock; + wc.wr_id = qp->r_wr_id; + wc.status = IB_WC_SUCCESS; + wc.opcode = IB_WC_RECV; + wc.qp = &qp->ibqp; + wc.src_qp = sqp->ibqp.qp_num; + wc.pkey_index = qp->ibqp.qp_type == IB_QPT_GSI ? + swqe->wr.wr.ud.pkey_index : 0; + wc.slid = ppd->lid | (ah_attr->src_path_bits & ((1 << ppd->lmc) - 1)); + wc.sl = ah_attr->sl; + wc.dlid_path_bits = ah_attr->dlid & ((1 << ppd->lmc) - 1); + wc.port_num = qp->port_num; + /* Signal completion event if the solicited bit is set. */ + qib_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, + swqe->wr.send_flags & IB_SEND_SOLICITED); + ibp->n_loop_pkts++; +bail_unlock: + spin_unlock_irqrestore(&qp->r_lock, flags); +drop: + if (atomic_dec_and_test(&qp->refcount)) + wake_up(&qp->wait); +} + +/** + * qib_make_ud_req - construct a UD request packet + * @qp: the QP + * + * Return 1 if constructed; otherwise, return 0. + */ +int qib_make_ud_req(struct qib_qp *qp) +{ + struct qib_other_headers *ohdr; + struct ib_ah_attr *ah_attr; + struct qib_pportdata *ppd; + struct qib_ibport *ibp; + struct qib_swqe *wqe; + unsigned long flags; + u32 nwords; + u32 extra_bytes; + u32 bth0; + u16 lrh0; + u16 lid; + int ret = 0; + int next_cur; + + spin_lock_irqsave(&qp->s_lock, flags); + + if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_NEXT_SEND_OK)) { + if (!(ib_qib_state_ops[qp->state] & QIB_FLUSH_SEND)) + goto bail; + /* We are in the error state, flush the work request. */ + if (qp->s_last == qp->s_head) + goto bail; + /* If DMAs are in progress, we can't flush immediately. */ + if (atomic_read(&qp->s_dma_busy)) { + qp->s_flags |= QIB_S_WAIT_DMA; + goto bail; + } + wqe = get_swqe_ptr(qp, qp->s_last); + qib_send_complete(qp, wqe, IB_WC_WR_FLUSH_ERR); + goto done; + } + + if (qp->s_cur == qp->s_head) + goto bail; + + wqe = get_swqe_ptr(qp, qp->s_cur); + next_cur = qp->s_cur + 1; + if (next_cur >= qp->s_size) + next_cur = 0; + + /* Construct the header. */ + ibp = to_iport(qp->ibqp.device, qp->port_num); + ppd = ppd_from_ibp(ibp); + ah_attr = &to_iah(wqe->wr.wr.ud.ah)->attr; + if (ah_attr->dlid >= QIB_MULTICAST_LID_BASE) { + if (ah_attr->dlid != QIB_PERMISSIVE_LID) + ibp->n_multicast_xmit++; + else + ibp->n_unicast_xmit++; + } else { + ibp->n_unicast_xmit++; + lid = ah_attr->dlid & ~((1 << ppd->lmc) - 1); + if (unlikely(lid == ppd->lid)) { + /* + * If DMAs are in progress, we can't generate + * a completion for the loopback packet since + * it would be out of order. + * XXX Instead of waiting, we could queue a + * zero length descriptor so we get a callback. + */ + if (atomic_read(&qp->s_dma_busy)) { + qp->s_flags |= QIB_S_WAIT_DMA; + goto bail; + } + qp->s_cur = next_cur; + spin_unlock_irqrestore(&qp->s_lock, flags); + qib_ud_loopback(qp, wqe); + spin_lock_irqsave(&qp->s_lock, flags); + qib_send_complete(qp, wqe, IB_WC_SUCCESS); + goto done; + } + } + + qp->s_cur = next_cur; + extra_bytes = -wqe->length & 3; + nwords = (wqe->length + extra_bytes) >> 2; + + /* header size in 32-bit words LRH+BTH+DETH = (8+12+8)/4. */ + qp->s_hdrwords = 7; + qp->s_cur_size = wqe->length; + qp->s_cur_sge = &qp->s_sge; + qp->s_srate = ah_attr->static_rate; + qp->s_wqe = wqe; + qp->s_sge.sge = wqe->sg_list[0]; + qp->s_sge.sg_list = wqe->sg_list + 1; + qp->s_sge.num_sge = wqe->wr.num_sge; + qp->s_sge.total_len = wqe->length; + + if (ah_attr->ah_flags & IB_AH_GRH) { + /* Header size in 32-bit words. */ + qp->s_hdrwords += qib_make_grh(ibp, &qp->s_hdr.u.l.grh, + &ah_attr->grh, + qp->s_hdrwords, nwords); + lrh0 = QIB_LRH_GRH; + ohdr = &qp->s_hdr.u.l.oth; + /* + * Don't worry about sending to locally attached multicast + * QPs. It is unspecified by the spec. what happens. + */ + } else { + /* Header size in 32-bit words. */ + lrh0 = QIB_LRH_BTH; + ohdr = &qp->s_hdr.u.oth; + } + if (wqe->wr.opcode == IB_WR_SEND_WITH_IMM) { + qp->s_hdrwords++; + ohdr->u.ud.imm_data = wqe->wr.ex.imm_data; + bth0 = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE << 24; + } else + bth0 = IB_OPCODE_UD_SEND_ONLY << 24; + lrh0 |= ah_attr->sl << 4; + if (qp->ibqp.qp_type == IB_QPT_SMI) + lrh0 |= 0xF000; /* Set VL (see ch. 13.5.3.1) */ + else + lrh0 |= ibp->sl_to_vl[ah_attr->sl] << 12; + qp->s_hdr.lrh[0] = cpu_to_be16(lrh0); + qp->s_hdr.lrh[1] = cpu_to_be16(ah_attr->dlid); /* DEST LID */ + qp->s_hdr.lrh[2] = cpu_to_be16(qp->s_hdrwords + nwords + SIZE_OF_CRC); + lid = ppd->lid; + if (lid) { + lid |= ah_attr->src_path_bits & ((1 << ppd->lmc) - 1); + qp->s_hdr.lrh[3] = cpu_to_be16(lid); + } else + qp->s_hdr.lrh[3] = IB_LID_PERMISSIVE; + if (wqe->wr.send_flags & IB_SEND_SOLICITED) + bth0 |= IB_BTH_SOLICITED; + bth0 |= extra_bytes << 20; + bth0 |= qp->ibqp.qp_type == IB_QPT_SMI ? QIB_DEFAULT_P_KEY : + qib_get_pkey(ibp, qp->ibqp.qp_type == IB_QPT_GSI ? + wqe->wr.wr.ud.pkey_index : qp->s_pkey_index); + ohdr->bth[0] = cpu_to_be32(bth0); + /* + * Use the multicast QP if the destination LID is a multicast LID. + */ + ohdr->bth[1] = ah_attr->dlid >= QIB_MULTICAST_LID_BASE && + ah_attr->dlid != QIB_PERMISSIVE_LID ? + cpu_to_be32(QIB_MULTICAST_QPN) : + cpu_to_be32(wqe->wr.wr.ud.remote_qpn); + ohdr->bth[2] = cpu_to_be32(qp->s_next_psn++ & QIB_PSN_MASK); + /* + * Qkeys with the high order bit set mean use the + * qkey from the QP context instead of the WR (see 10.2.5). + */ + ohdr->u.ud.deth[0] = cpu_to_be32((int)wqe->wr.wr.ud.remote_qkey < 0 ? + qp->qkey : wqe->wr.wr.ud.remote_qkey); + ohdr->u.ud.deth[1] = cpu_to_be32(qp->ibqp.qp_num); + +done: + ret = 1; + goto unlock; + +bail: + qp->s_flags &= ~QIB_S_BUSY; +unlock: + spin_unlock_irqrestore(&qp->s_lock, flags); + return ret; +} + +static unsigned qib_lookup_pkey(struct qib_ibport *ibp, u16 pkey) +{ + struct qib_pportdata *ppd = ppd_from_ibp(ibp); + struct qib_devdata *dd = ppd->dd; + unsigned ctxt = ppd->hw_pidx; + unsigned i; + + pkey &= 0x7fff; /* remove limited/full membership bit */ + + for (i = 0; i < ARRAY_SIZE(dd->rcd[ctxt]->pkeys); ++i) + if ((dd->rcd[ctxt]->pkeys[i] & 0x7fff) == pkey) + return i; + + /* + * Should not get here, this means hardware failed to validate pkeys. + * Punt and return index 0. + */ + return 0; +} + +/** + * qib_ud_rcv - receive an incoming UD packet + * @ibp: the port the packet came in on + * @hdr: the packet header + * @has_grh: true if the packet has a GRH + * @data: the packet data + * @tlen: the packet length + * @qp: the QP the packet came on + * + * This is called from qib_qp_rcv() to process an incoming UD packet + * for the given QP. + * Called at interrupt level. + */ +void qib_ud_rcv(struct qib_ibport *ibp, struct qib_ib_header *hdr, + int has_grh, void *data, u32 tlen, struct qib_qp *qp) +{ + struct qib_other_headers *ohdr; + int opcode; + u32 hdrsize; + u32 pad; + struct ib_wc wc; + u32 qkey; + u32 src_qp; + u16 dlid; + + /* Check for GRH */ + if (!has_grh) { + ohdr = &hdr->u.oth; + hdrsize = 8 + 12 + 8; /* LRH + BTH + DETH */ + } else { + ohdr = &hdr->u.l.oth; + hdrsize = 8 + 40 + 12 + 8; /* LRH + GRH + BTH + DETH */ + } + qkey = be32_to_cpu(ohdr->u.ud.deth[0]); + src_qp = be32_to_cpu(ohdr->u.ud.deth[1]) & QIB_QPN_MASK; + + /* Get the number of bytes the message was padded by. */ + pad = (be32_to_cpu(ohdr->bth[0]) >> 20) & 3; + if (unlikely(tlen < (hdrsize + pad + 4))) { + /* Drop incomplete packets. */ + ibp->n_pkt_drops++; + goto bail; + } + tlen -= hdrsize + pad + 4; + + /* + * Check that the permissive LID is only used on QP0 + * and the QKEY matches (see 9.6.1.4.1 and 9.6.1.5.1). + */ + if (qp->ibqp.qp_num) { + if (unlikely(hdr->lrh[1] == IB_LID_PERMISSIVE || + hdr->lrh[3] == IB_LID_PERMISSIVE)) { + ibp->n_pkt_drops++; + goto bail; + } + if (qp->ibqp.qp_num > 1) { + u16 pkey1, pkey2; + + pkey1 = be32_to_cpu(ohdr->bth[0]); + pkey2 = qib_get_pkey(ibp, qp->s_pkey_index); + if (unlikely(!qib_pkey_ok(pkey1, pkey2))) { + qib_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_PKEY, + pkey1, + (be16_to_cpu(hdr->lrh[0]) >> 4) & + 0xF, + src_qp, qp->ibqp.qp_num, + hdr->lrh[3], hdr->lrh[1]); + goto bail; + } + } + if (unlikely(qkey != qp->qkey)) { + qib_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_QKEY, qkey, + (be16_to_cpu(hdr->lrh[0]) >> 4) & 0xF, + src_qp, qp->ibqp.qp_num, + hdr->lrh[3], hdr->lrh[1]); + goto bail; + } + /* Drop invalid MAD packets (see 13.5.3.1). */ + if (unlikely(qp->ibqp.qp_num == 1 && + (tlen != 256 || + (be16_to_cpu(hdr->lrh[0]) >> 12) == 15))) { + ibp->n_pkt_drops++; + goto bail; + } + } else { + struct ib_smp *smp; + + /* Drop invalid MAD packets (see 13.5.3.1). */ + if (tlen != 256 || (be16_to_cpu(hdr->lrh[0]) >> 12) != 15) { + ibp->n_pkt_drops++; + goto bail; + } + smp = (struct ib_smp *) data; + if ((hdr->lrh[1] == IB_LID_PERMISSIVE || + hdr->lrh[3] == IB_LID_PERMISSIVE) && + smp->mgmt_class != IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) { + ibp->n_pkt_drops++; + goto bail; + } + } + + /* + * The opcode is in the low byte when its in network order + * (top byte when in host order). + */ + opcode = be32_to_cpu(ohdr->bth[0]) >> 24; + if (qp->ibqp.qp_num > 1 && + opcode == IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE) { + wc.ex.imm_data = ohdr->u.ud.imm_data; + wc.wc_flags = IB_WC_WITH_IMM; + hdrsize += sizeof(u32); + } else if (opcode == IB_OPCODE_UD_SEND_ONLY) { + wc.ex.imm_data = 0; + wc.wc_flags = 0; + } else { + ibp->n_pkt_drops++; + goto bail; + } + + /* + * A GRH is expected to preceed the data even if not + * present on the wire. + */ + wc.byte_len = tlen + sizeof(struct ib_grh); + + /* + * We need to serialize getting a receive work queue entry and + * generating a completion for it against QPs sending to this QP + * locally. + */ + spin_lock(&qp->r_lock); + + /* + * Get the next work request entry to find where to put the data. + */ + if (qp->r_flags & QIB_R_REUSE_SGE) + qp->r_flags &= ~QIB_R_REUSE_SGE; + else { + int ret; + + ret = qib_get_rwqe(qp, 0); + if (ret < 0) { + qib_rc_error(qp, IB_WC_LOC_QP_OP_ERR); + goto bail_unlock; + } + if (!ret) { + if (qp->ibqp.qp_num == 0) + ibp->n_vl15_dropped++; + goto bail_unlock; + } + } + /* Silently drop packets which are too big. */ + if (unlikely(wc.byte_len > qp->r_len)) { + qp->r_flags |= QIB_R_REUSE_SGE; + ibp->n_pkt_drops++; + goto bail_unlock; + } + if (has_grh) { + qib_copy_sge(&qp->r_sge, &hdr->u.l.grh, + sizeof(struct ib_grh), 1); + wc.wc_flags |= IB_WC_GRH; + } else + qib_skip_sge(&qp->r_sge, sizeof(struct ib_grh), 1); + qib_copy_sge(&qp->r_sge, data, wc.byte_len - sizeof(struct ib_grh), 1); + while (qp->r_sge.num_sge) { + atomic_dec(&qp->r_sge.sge.mr->refcount); + if (--qp->r_sge.num_sge) + qp->r_sge.sge = *qp->r_sge.sg_list++; + } + if (!test_and_clear_bit(QIB_R_WRID_VALID, &qp->r_aflags)) + goto bail_unlock; + wc.wr_id = qp->r_wr_id; + wc.status = IB_WC_SUCCESS; + wc.opcode = IB_WC_RECV; + wc.vendor_err = 0; + wc.qp = &qp->ibqp; + wc.src_qp = src_qp; + wc.pkey_index = qp->ibqp.qp_type == IB_QPT_GSI ? + qib_lookup_pkey(ibp, be32_to_cpu(ohdr->bth[0])) : 0; + wc.slid = be16_to_cpu(hdr->lrh[3]); + wc.sl = (be16_to_cpu(hdr->lrh[0]) >> 4) & 0xF; + dlid = be16_to_cpu(hdr->lrh[1]); + /* + * Save the LMC lower bits if the destination LID is a unicast LID. + */ + wc.dlid_path_bits = dlid >= QIB_MULTICAST_LID_BASE ? 0 : + dlid & ((1 << ppd_from_ibp(ibp)->lmc) - 1); + wc.port_num = qp->port_num; + /* Signal completion event if the solicited bit is set. */ + qib_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, + (ohdr->bth[0] & + cpu_to_be32(IB_BTH_SOLICITED)) != 0); +bail_unlock: + spin_unlock(&qp->r_lock); +bail:; +} diff --git a/drivers/infiniband/hw/qib/qib_user_pages.c b/drivers/infiniband/hw/qib/qib_user_pages.c new file mode 100644 index 000000000000..d7a26c1d4f37 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_user_pages.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. + * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include + +#include "qib.h" + +static void __qib_release_user_pages(struct page **p, size_t num_pages, + int dirty) +{ + size_t i; + + for (i = 0; i < num_pages; i++) { + if (dirty) + set_page_dirty_lock(p[i]); + put_page(p[i]); + } +} + +/* + * Call with current->mm->mmap_sem held. + */ +static int __get_user_pages(unsigned long start_page, size_t num_pages, + struct page **p, struct vm_area_struct **vma) +{ + unsigned long lock_limit; + size_t got; + int ret; + + lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; + + if (num_pages > lock_limit && !capable(CAP_IPC_LOCK)) { + ret = -ENOMEM; + goto bail; + } + + for (got = 0; got < num_pages; got += ret) { + ret = get_user_pages(current, current->mm, + start_page + got * PAGE_SIZE, + num_pages - got, 1, 1, + p + got, vma); + if (ret < 0) + goto bail_release; + } + + current->mm->locked_vm += num_pages; + + ret = 0; + goto bail; + +bail_release: + __qib_release_user_pages(p, got, 0); +bail: + return ret; +} + +/** + * qib_map_page - a safety wrapper around pci_map_page() + * + * A dma_addr of all 0's is interpreted by the chip as "disabled". + * Unfortunately, it can also be a valid dma_addr returned on some + * architectures. + * + * The powerpc iommu assigns dma_addrs in ascending order, so we don't + * have to bother with retries or mapping a dummy page to insure we + * don't just get the same mapping again. + * + * I'm sure we won't be so lucky with other iommu's, so FIXME. + */ +dma_addr_t qib_map_page(struct pci_dev *hwdev, struct page *page, + unsigned long offset, size_t size, int direction) +{ + dma_addr_t phys; + + phys = pci_map_page(hwdev, page, offset, size, direction); + + if (phys == 0) { + pci_unmap_page(hwdev, phys, size, direction); + phys = pci_map_page(hwdev, page, offset, size, direction); + /* + * FIXME: If we get 0 again, we should keep this page, + * map another, then free the 0 page. + */ + } + + return phys; +} + +/** + * qib_get_user_pages - lock user pages into memory + * @start_page: the start page + * @num_pages: the number of pages + * @p: the output page structures + * + * This function takes a given start page (page aligned user virtual + * address) and pins it and the following specified number of pages. For + * now, num_pages is always 1, but that will probably change at some point + * (because caller is doing expected sends on a single virtually contiguous + * buffer, so we can do all pages at once). + */ +int qib_get_user_pages(unsigned long start_page, size_t num_pages, + struct page **p) +{ + int ret; + + down_write(¤t->mm->mmap_sem); + + ret = __get_user_pages(start_page, num_pages, p, NULL); + + up_write(¤t->mm->mmap_sem); + + return ret; +} + +void qib_release_user_pages(struct page **p, size_t num_pages) +{ + if (current->mm) /* during close after signal, mm can be NULL */ + down_write(¤t->mm->mmap_sem); + + __qib_release_user_pages(p, num_pages, 1); + + if (current->mm) { + current->mm->locked_vm -= num_pages; + up_write(¤t->mm->mmap_sem); + } +} diff --git a/drivers/infiniband/hw/qib/qib_user_sdma.c b/drivers/infiniband/hw/qib/qib_user_sdma.c new file mode 100644 index 000000000000..4c19e06b5e85 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_user_sdma.c @@ -0,0 +1,897 @@ +/* + * Copyright (c) 2007, 2008, 2009 QLogic Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qib.h" +#include "qib_user_sdma.h" + +/* minimum size of header */ +#define QIB_USER_SDMA_MIN_HEADER_LENGTH 64 +/* expected size of headers (for dma_pool) */ +#define QIB_USER_SDMA_EXP_HEADER_LENGTH 64 +/* attempt to drain the queue for 5secs */ +#define QIB_USER_SDMA_DRAIN_TIMEOUT 500 + +struct qib_user_sdma_pkt { + u8 naddr; /* dimension of addr (1..3) ... */ + u32 counter; /* sdma pkts queued counter for this entry */ + u64 added; /* global descq number of entries */ + + struct { + u32 offset; /* offset for kvaddr, addr */ + u32 length; /* length in page */ + u8 put_page; /* should we put_page? */ + u8 dma_mapped; /* is page dma_mapped? */ + struct page *page; /* may be NULL (coherent mem) */ + void *kvaddr; /* FIXME: only for pio hack */ + dma_addr_t addr; + } addr[4]; /* max pages, any more and we coalesce */ + struct list_head list; /* list element */ +}; + +struct qib_user_sdma_queue { + /* + * pkts sent to dma engine are queued on this + * list head. the type of the elements of this + * list are struct qib_user_sdma_pkt... + */ + struct list_head sent; + + /* headers with expected length are allocated from here... */ + char header_cache_name[64]; + struct dma_pool *header_cache; + + /* packets are allocated from the slab cache... */ + char pkt_slab_name[64]; + struct kmem_cache *pkt_slab; + + /* as packets go on the queued queue, they are counted... */ + u32 counter; + u32 sent_counter; + + /* dma page table */ + struct rb_root dma_pages_root; + + /* protect everything above... */ + struct mutex lock; +}; + +struct qib_user_sdma_queue * +qib_user_sdma_queue_create(struct device *dev, int unit, int ctxt, int sctxt) +{ + struct qib_user_sdma_queue *pq = + kmalloc(sizeof(struct qib_user_sdma_queue), GFP_KERNEL); + + if (!pq) + goto done; + + pq->counter = 0; + pq->sent_counter = 0; + INIT_LIST_HEAD(&pq->sent); + + mutex_init(&pq->lock); + + snprintf(pq->pkt_slab_name, sizeof(pq->pkt_slab_name), + "qib-user-sdma-pkts-%u-%02u.%02u", unit, ctxt, sctxt); + pq->pkt_slab = kmem_cache_create(pq->pkt_slab_name, + sizeof(struct qib_user_sdma_pkt), + 0, 0, NULL); + + if (!pq->pkt_slab) + goto err_kfree; + + snprintf(pq->header_cache_name, sizeof(pq->header_cache_name), + "qib-user-sdma-headers-%u-%02u.%02u", unit, ctxt, sctxt); + pq->header_cache = dma_pool_create(pq->header_cache_name, + dev, + QIB_USER_SDMA_EXP_HEADER_LENGTH, + 4, 0); + if (!pq->header_cache) + goto err_slab; + + pq->dma_pages_root = RB_ROOT; + + goto done; + +err_slab: + kmem_cache_destroy(pq->pkt_slab); +err_kfree: + kfree(pq); + pq = NULL; + +done: + return pq; +} + +static void qib_user_sdma_init_frag(struct qib_user_sdma_pkt *pkt, + int i, size_t offset, size_t len, + int put_page, int dma_mapped, + struct page *page, + void *kvaddr, dma_addr_t dma_addr) +{ + pkt->addr[i].offset = offset; + pkt->addr[i].length = len; + pkt->addr[i].put_page = put_page; + pkt->addr[i].dma_mapped = dma_mapped; + pkt->addr[i].page = page; + pkt->addr[i].kvaddr = kvaddr; + pkt->addr[i].addr = dma_addr; +} + +static void qib_user_sdma_init_header(struct qib_user_sdma_pkt *pkt, + u32 counter, size_t offset, + size_t len, int dma_mapped, + struct page *page, + void *kvaddr, dma_addr_t dma_addr) +{ + pkt->naddr = 1; + pkt->counter = counter; + qib_user_sdma_init_frag(pkt, 0, offset, len, 0, dma_mapped, page, + kvaddr, dma_addr); +} + +/* we've too many pages in the iovec, coalesce to a single page */ +static int qib_user_sdma_coalesce(const struct qib_devdata *dd, + struct qib_user_sdma_pkt *pkt, + const struct iovec *iov, + unsigned long niov) +{ + int ret = 0; + struct page *page = alloc_page(GFP_KERNEL); + void *mpage_save; + char *mpage; + int i; + int len = 0; + dma_addr_t dma_addr; + + if (!page) { + ret = -ENOMEM; + goto done; + } + + mpage = kmap(page); + mpage_save = mpage; + for (i = 0; i < niov; i++) { + int cfur; + + cfur = copy_from_user(mpage, + iov[i].iov_base, iov[i].iov_len); + if (cfur) { + ret = -EFAULT; + goto free_unmap; + } + + mpage += iov[i].iov_len; + len += iov[i].iov_len; + } + + dma_addr = dma_map_page(&dd->pcidev->dev, page, 0, len, + DMA_TO_DEVICE); + if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) { + ret = -ENOMEM; + goto free_unmap; + } + + qib_user_sdma_init_frag(pkt, 1, 0, len, 0, 1, page, mpage_save, + dma_addr); + pkt->naddr = 2; + + goto done; + +free_unmap: + kunmap(page); + __free_page(page); +done: + return ret; +} + +/* + * How many pages in this iovec element? + */ +static int qib_user_sdma_num_pages(const struct iovec *iov) +{ + const unsigned long addr = (unsigned long) iov->iov_base; + const unsigned long len = iov->iov_len; + const unsigned long spage = addr & PAGE_MASK; + const unsigned long epage = (addr + len - 1) & PAGE_MASK; + + return 1 + ((epage - spage) >> PAGE_SHIFT); +} + +/* + * Truncate length to page boundry. + */ +static int qib_user_sdma_page_length(unsigned long addr, unsigned long len) +{ + const unsigned long offset = addr & ~PAGE_MASK; + + return ((offset + len) > PAGE_SIZE) ? (PAGE_SIZE - offset) : len; +} + +static void qib_user_sdma_free_pkt_frag(struct device *dev, + struct qib_user_sdma_queue *pq, + struct qib_user_sdma_pkt *pkt, + int frag) +{ + const int i = frag; + + if (pkt->addr[i].page) { + if (pkt->addr[i].dma_mapped) + dma_unmap_page(dev, + pkt->addr[i].addr, + pkt->addr[i].length, + DMA_TO_DEVICE); + + if (pkt->addr[i].kvaddr) + kunmap(pkt->addr[i].page); + + if (pkt->addr[i].put_page) + put_page(pkt->addr[i].page); + else + __free_page(pkt->addr[i].page); + } else if (pkt->addr[i].kvaddr) + /* free coherent mem from cache... */ + dma_pool_free(pq->header_cache, + pkt->addr[i].kvaddr, pkt->addr[i].addr); +} + +/* return number of pages pinned... */ +static int qib_user_sdma_pin_pages(const struct qib_devdata *dd, + struct qib_user_sdma_pkt *pkt, + unsigned long addr, int tlen, int npages) +{ + struct page *pages[2]; + int j; + int ret; + + ret = get_user_pages(current, current->mm, addr, + npages, 0, 1, pages, NULL); + + if (ret != npages) { + int i; + + for (i = 0; i < ret; i++) + put_page(pages[i]); + + ret = -ENOMEM; + goto done; + } + + for (j = 0; j < npages; j++) { + /* map the pages... */ + const int flen = qib_user_sdma_page_length(addr, tlen); + dma_addr_t dma_addr = + dma_map_page(&dd->pcidev->dev, + pages[j], 0, flen, DMA_TO_DEVICE); + unsigned long fofs = addr & ~PAGE_MASK; + + if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) { + ret = -ENOMEM; + goto done; + } + + qib_user_sdma_init_frag(pkt, pkt->naddr, fofs, flen, 1, 1, + pages[j], kmap(pages[j]), dma_addr); + + pkt->naddr++; + addr += flen; + tlen -= flen; + } + +done: + return ret; +} + +static int qib_user_sdma_pin_pkt(const struct qib_devdata *dd, + struct qib_user_sdma_queue *pq, + struct qib_user_sdma_pkt *pkt, + const struct iovec *iov, + unsigned long niov) +{ + int ret = 0; + unsigned long idx; + + for (idx = 0; idx < niov; idx++) { + const int npages = qib_user_sdma_num_pages(iov + idx); + const unsigned long addr = (unsigned long) iov[idx].iov_base; + + ret = qib_user_sdma_pin_pages(dd, pkt, addr, + iov[idx].iov_len, npages); + if (ret < 0) + goto free_pkt; + } + + goto done; + +free_pkt: + for (idx = 0; idx < pkt->naddr; idx++) + qib_user_sdma_free_pkt_frag(&dd->pcidev->dev, pq, pkt, idx); + +done: + return ret; +} + +static int qib_user_sdma_init_payload(const struct qib_devdata *dd, + struct qib_user_sdma_queue *pq, + struct qib_user_sdma_pkt *pkt, + const struct iovec *iov, + unsigned long niov, int npages) +{ + int ret = 0; + + if (npages >= ARRAY_SIZE(pkt->addr)) + ret = qib_user_sdma_coalesce(dd, pkt, iov, niov); + else + ret = qib_user_sdma_pin_pkt(dd, pq, pkt, iov, niov); + + return ret; +} + +/* free a packet list -- return counter value of last packet */ +static void qib_user_sdma_free_pkt_list(struct device *dev, + struct qib_user_sdma_queue *pq, + struct list_head *list) +{ + struct qib_user_sdma_pkt *pkt, *pkt_next; + + list_for_each_entry_safe(pkt, pkt_next, list, list) { + int i; + + for (i = 0; i < pkt->naddr; i++) + qib_user_sdma_free_pkt_frag(dev, pq, pkt, i); + + kmem_cache_free(pq->pkt_slab, pkt); + } +} + +/* + * copy headers, coalesce etc -- pq->lock must be held + * + * we queue all the packets to list, returning the + * number of bytes total. list must be empty initially, + * as, if there is an error we clean it... + */ +static int qib_user_sdma_queue_pkts(const struct qib_devdata *dd, + struct qib_user_sdma_queue *pq, + struct list_head *list, + const struct iovec *iov, + unsigned long niov, + int maxpkts) +{ + unsigned long idx = 0; + int ret = 0; + int npkts = 0; + struct page *page = NULL; + __le32 *pbc; + dma_addr_t dma_addr; + struct qib_user_sdma_pkt *pkt = NULL; + size_t len; + size_t nw; + u32 counter = pq->counter; + int dma_mapped = 0; + + while (idx < niov && npkts < maxpkts) { + const unsigned long addr = (unsigned long) iov[idx].iov_base; + const unsigned long idx_save = idx; + unsigned pktnw; + unsigned pktnwc; + int nfrags = 0; + int npages = 0; + int cfur; + + dma_mapped = 0; + len = iov[idx].iov_len; + nw = len >> 2; + page = NULL; + + pkt = kmem_cache_alloc(pq->pkt_slab, GFP_KERNEL); + if (!pkt) { + ret = -ENOMEM; + goto free_list; + } + + if (len < QIB_USER_SDMA_MIN_HEADER_LENGTH || + len > PAGE_SIZE || len & 3 || addr & 3) { + ret = -EINVAL; + goto free_pkt; + } + + if (len == QIB_USER_SDMA_EXP_HEADER_LENGTH) + pbc = dma_pool_alloc(pq->header_cache, GFP_KERNEL, + &dma_addr); + else + pbc = NULL; + + if (!pbc) { + page = alloc_page(GFP_KERNEL); + if (!page) { + ret = -ENOMEM; + goto free_pkt; + } + pbc = kmap(page); + } + + cfur = copy_from_user(pbc, iov[idx].iov_base, len); + if (cfur) { + ret = -EFAULT; + goto free_pbc; + } + + /* + * This assignment is a bit strange. it's because the + * the pbc counts the number of 32 bit words in the full + * packet _except_ the first word of the pbc itself... + */ + pktnwc = nw - 1; + + /* + * pktnw computation yields the number of 32 bit words + * that the caller has indicated in the PBC. note that + * this is one less than the total number of words that + * goes to the send DMA engine as the first 32 bit word + * of the PBC itself is not counted. Armed with this count, + * we can verify that the packet is consistent with the + * iovec lengths. + */ + pktnw = le32_to_cpu(*pbc) & QIB_PBC_LENGTH_MASK; + if (pktnw < pktnwc || pktnw > pktnwc + (PAGE_SIZE >> 2)) { + ret = -EINVAL; + goto free_pbc; + } + + idx++; + while (pktnwc < pktnw && idx < niov) { + const size_t slen = iov[idx].iov_len; + const unsigned long faddr = + (unsigned long) iov[idx].iov_base; + + if (slen & 3 || faddr & 3 || !slen || + slen > PAGE_SIZE) { + ret = -EINVAL; + goto free_pbc; + } + + npages++; + if ((faddr & PAGE_MASK) != + ((faddr + slen - 1) & PAGE_MASK)) + npages++; + + pktnwc += slen >> 2; + idx++; + nfrags++; + } + + if (pktnwc != pktnw) { + ret = -EINVAL; + goto free_pbc; + } + + if (page) { + dma_addr = dma_map_page(&dd->pcidev->dev, + page, 0, len, DMA_TO_DEVICE); + if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) { + ret = -ENOMEM; + goto free_pbc; + } + + dma_mapped = 1; + } + + qib_user_sdma_init_header(pkt, counter, 0, len, dma_mapped, + page, pbc, dma_addr); + + if (nfrags) { + ret = qib_user_sdma_init_payload(dd, pq, pkt, + iov + idx_save + 1, + nfrags, npages); + if (ret < 0) + goto free_pbc_dma; + } + + counter++; + npkts++; + + list_add_tail(&pkt->list, list); + } + + ret = idx; + goto done; + +free_pbc_dma: + if (dma_mapped) + dma_unmap_page(&dd->pcidev->dev, dma_addr, len, DMA_TO_DEVICE); +free_pbc: + if (page) { + kunmap(page); + __free_page(page); + } else + dma_pool_free(pq->header_cache, pbc, dma_addr); +free_pkt: + kmem_cache_free(pq->pkt_slab, pkt); +free_list: + qib_user_sdma_free_pkt_list(&dd->pcidev->dev, pq, list); +done: + return ret; +} + +static void qib_user_sdma_set_complete_counter(struct qib_user_sdma_queue *pq, + u32 c) +{ + pq->sent_counter = c; +} + +/* try to clean out queue -- needs pq->lock */ +static int qib_user_sdma_queue_clean(struct qib_pportdata *ppd, + struct qib_user_sdma_queue *pq) +{ + struct qib_devdata *dd = ppd->dd; + struct list_head free_list; + struct qib_user_sdma_pkt *pkt; + struct qib_user_sdma_pkt *pkt_prev; + int ret = 0; + + INIT_LIST_HEAD(&free_list); + + list_for_each_entry_safe(pkt, pkt_prev, &pq->sent, list) { + s64 descd = ppd->sdma_descq_removed - pkt->added; + + if (descd < 0) + break; + + list_move_tail(&pkt->list, &free_list); + + /* one more packet cleaned */ + ret++; + } + + if (!list_empty(&free_list)) { + u32 counter; + + pkt = list_entry(free_list.prev, + struct qib_user_sdma_pkt, list); + counter = pkt->counter; + + qib_user_sdma_free_pkt_list(&dd->pcidev->dev, pq, &free_list); + qib_user_sdma_set_complete_counter(pq, counter); + } + + return ret; +} + +void qib_user_sdma_queue_destroy(struct qib_user_sdma_queue *pq) +{ + if (!pq) + return; + + kmem_cache_destroy(pq->pkt_slab); + dma_pool_destroy(pq->header_cache); + kfree(pq); +} + +/* clean descriptor queue, returns > 0 if some elements cleaned */ +static int qib_user_sdma_hwqueue_clean(struct qib_pportdata *ppd) +{ + int ret; + unsigned long flags; + + spin_lock_irqsave(&ppd->sdma_lock, flags); + ret = qib_sdma_make_progress(ppd); + spin_unlock_irqrestore(&ppd->sdma_lock, flags); + + return ret; +} + +/* we're in close, drain packets so that we can cleanup successfully... */ +void qib_user_sdma_queue_drain(struct qib_pportdata *ppd, + struct qib_user_sdma_queue *pq) +{ + struct qib_devdata *dd = ppd->dd; + int i; + + if (!pq) + return; + + for (i = 0; i < QIB_USER_SDMA_DRAIN_TIMEOUT; i++) { + mutex_lock(&pq->lock); + if (list_empty(&pq->sent)) { + mutex_unlock(&pq->lock); + break; + } + qib_user_sdma_hwqueue_clean(ppd); + qib_user_sdma_queue_clean(ppd, pq); + mutex_unlock(&pq->lock); + msleep(10); + } + + if (!list_empty(&pq->sent)) { + struct list_head free_list; + + qib_dev_err(dd, "user sdma lists not empty: forcing!\n"); + INIT_LIST_HEAD(&free_list); + mutex_lock(&pq->lock); + list_splice_init(&pq->sent, &free_list); + qib_user_sdma_free_pkt_list(&dd->pcidev->dev, pq, &free_list); + mutex_unlock(&pq->lock); + } +} + +static inline __le64 qib_sdma_make_desc0(struct qib_pportdata *ppd, + u64 addr, u64 dwlen, u64 dwoffset) +{ + u8 tmpgen; + + tmpgen = ppd->sdma_generation; + + return cpu_to_le64(/* SDmaPhyAddr[31:0] */ + ((addr & 0xfffffffcULL) << 32) | + /* SDmaGeneration[1:0] */ + ((tmpgen & 3ULL) << 30) | + /* SDmaDwordCount[10:0] */ + ((dwlen & 0x7ffULL) << 16) | + /* SDmaBufOffset[12:2] */ + (dwoffset & 0x7ffULL)); +} + +static inline __le64 qib_sdma_make_first_desc0(__le64 descq) +{ + return descq | cpu_to_le64(1ULL << 12); +} + +static inline __le64 qib_sdma_make_last_desc0(__le64 descq) +{ + /* last */ /* dma head */ + return descq | cpu_to_le64(1ULL << 11 | 1ULL << 13); +} + +static inline __le64 qib_sdma_make_desc1(u64 addr) +{ + /* SDmaPhyAddr[47:32] */ + return cpu_to_le64(addr >> 32); +} + +static void qib_user_sdma_send_frag(struct qib_pportdata *ppd, + struct qib_user_sdma_pkt *pkt, int idx, + unsigned ofs, u16 tail) +{ + const u64 addr = (u64) pkt->addr[idx].addr + + (u64) pkt->addr[idx].offset; + const u64 dwlen = (u64) pkt->addr[idx].length / 4; + __le64 *descqp; + __le64 descq0; + + descqp = &ppd->sdma_descq[tail].qw[0]; + + descq0 = qib_sdma_make_desc0(ppd, addr, dwlen, ofs); + if (idx == 0) + descq0 = qib_sdma_make_first_desc0(descq0); + if (idx == pkt->naddr - 1) + descq0 = qib_sdma_make_last_desc0(descq0); + + descqp[0] = descq0; + descqp[1] = qib_sdma_make_desc1(addr); +} + +/* pq->lock must be held, get packets on the wire... */ +static int qib_user_sdma_push_pkts(struct qib_pportdata *ppd, + struct qib_user_sdma_queue *pq, + struct list_head *pktlist) +{ + struct qib_devdata *dd = ppd->dd; + int ret = 0; + unsigned long flags; + u16 tail; + u8 generation; + u64 descq_added; + + if (list_empty(pktlist)) + return 0; + + if (unlikely(!(ppd->lflags & QIBL_LINKACTIVE))) + return -ECOMM; + + spin_lock_irqsave(&ppd->sdma_lock, flags); + + /* keep a copy for restoring purposes in case of problems */ + generation = ppd->sdma_generation; + descq_added = ppd->sdma_descq_added; + + if (unlikely(!__qib_sdma_running(ppd))) { + ret = -ECOMM; + goto unlock; + } + + tail = ppd->sdma_descq_tail; + while (!list_empty(pktlist)) { + struct qib_user_sdma_pkt *pkt = + list_entry(pktlist->next, struct qib_user_sdma_pkt, + list); + int i; + unsigned ofs = 0; + u16 dtail = tail; + + if (pkt->naddr > qib_sdma_descq_freecnt(ppd)) + goto unlock_check_tail; + + for (i = 0; i < pkt->naddr; i++) { + qib_user_sdma_send_frag(ppd, pkt, i, ofs, tail); + ofs += pkt->addr[i].length >> 2; + + if (++tail == ppd->sdma_descq_cnt) { + tail = 0; + ++ppd->sdma_generation; + } + } + + if ((ofs << 2) > ppd->ibmaxlen) { + ret = -EMSGSIZE; + goto unlock; + } + + /* + * If the packet is >= 2KB mtu equivalent, we have to use + * the large buffers, and have to mark each descriptor as + * part of a large buffer packet. + */ + if (ofs > dd->piosize2kmax_dwords) { + for (i = 0; i < pkt->naddr; i++) { + ppd->sdma_descq[dtail].qw[0] |= + cpu_to_le64(1ULL << 14); + if (++dtail == ppd->sdma_descq_cnt) + dtail = 0; + } + } + + ppd->sdma_descq_added += pkt->naddr; + pkt->added = ppd->sdma_descq_added; + list_move_tail(&pkt->list, &pq->sent); + ret++; + } + +unlock_check_tail: + /* advance the tail on the chip if necessary */ + if (ppd->sdma_descq_tail != tail) + dd->f_sdma_update_tail(ppd, tail); + +unlock: + if (unlikely(ret < 0)) { + ppd->sdma_generation = generation; + ppd->sdma_descq_added = descq_added; + } + spin_unlock_irqrestore(&ppd->sdma_lock, flags); + + return ret; +} + +int qib_user_sdma_writev(struct qib_ctxtdata *rcd, + struct qib_user_sdma_queue *pq, + const struct iovec *iov, + unsigned long dim) +{ + struct qib_devdata *dd = rcd->dd; + struct qib_pportdata *ppd = rcd->ppd; + int ret = 0; + struct list_head list; + int npkts = 0; + + INIT_LIST_HEAD(&list); + + mutex_lock(&pq->lock); + + /* why not -ECOMM like qib_user_sdma_push_pkts() below? */ + if (!qib_sdma_running(ppd)) + goto done_unlock; + + if (ppd->sdma_descq_added != ppd->sdma_descq_removed) { + qib_user_sdma_hwqueue_clean(ppd); + qib_user_sdma_queue_clean(ppd, pq); + } + + while (dim) { + const int mxp = 8; + + down_write(¤t->mm->mmap_sem); + ret = qib_user_sdma_queue_pkts(dd, pq, &list, iov, dim, mxp); + up_write(¤t->mm->mmap_sem); + + if (ret <= 0) + goto done_unlock; + else { + dim -= ret; + iov += ret; + } + + /* force packets onto the sdma hw queue... */ + if (!list_empty(&list)) { + /* + * Lazily clean hw queue. the 4 is a guess of about + * how many sdma descriptors a packet will take (it + * doesn't have to be perfect). + */ + if (qib_sdma_descq_freecnt(ppd) < ret * 4) { + qib_user_sdma_hwqueue_clean(ppd); + qib_user_sdma_queue_clean(ppd, pq); + } + + ret = qib_user_sdma_push_pkts(ppd, pq, &list); + if (ret < 0) + goto done_unlock; + else { + npkts += ret; + pq->counter += ret; + + if (!list_empty(&list)) + goto done_unlock; + } + } + } + +done_unlock: + if (!list_empty(&list)) + qib_user_sdma_free_pkt_list(&dd->pcidev->dev, pq, &list); + mutex_unlock(&pq->lock); + + return (ret < 0) ? ret : npkts; +} + +int qib_user_sdma_make_progress(struct qib_pportdata *ppd, + struct qib_user_sdma_queue *pq) +{ + int ret = 0; + + mutex_lock(&pq->lock); + qib_user_sdma_hwqueue_clean(ppd); + ret = qib_user_sdma_queue_clean(ppd, pq); + mutex_unlock(&pq->lock); + + return ret; +} + +u32 qib_user_sdma_complete_counter(const struct qib_user_sdma_queue *pq) +{ + return pq ? pq->sent_counter : 0; +} + +u32 qib_user_sdma_inflight_counter(struct qib_user_sdma_queue *pq) +{ + return pq ? pq->counter : 0; +} diff --git a/drivers/infiniband/hw/qib/qib_user_sdma.h b/drivers/infiniband/hw/qib/qib_user_sdma.h new file mode 100644 index 000000000000..ce8cbaf6a5c2 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_user_sdma.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2007, 2008 QLogic Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include + +struct qib_user_sdma_queue; + +struct qib_user_sdma_queue * +qib_user_sdma_queue_create(struct device *dev, int unit, int port, int sport); +void qib_user_sdma_queue_destroy(struct qib_user_sdma_queue *pq); + +int qib_user_sdma_writev(struct qib_ctxtdata *pd, + struct qib_user_sdma_queue *pq, + const struct iovec *iov, + unsigned long dim); + +int qib_user_sdma_make_progress(struct qib_pportdata *ppd, + struct qib_user_sdma_queue *pq); + +void qib_user_sdma_queue_drain(struct qib_pportdata *ppd, + struct qib_user_sdma_queue *pq); + +u32 qib_user_sdma_complete_counter(const struct qib_user_sdma_queue *pq); +u32 qib_user_sdma_inflight_counter(struct qib_user_sdma_queue *pq); diff --git a/drivers/infiniband/hw/qib/qib_verbs.c b/drivers/infiniband/hw/qib/qib_verbs.c new file mode 100644 index 000000000000..cda8f4173d23 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_verbs.c @@ -0,0 +1,2248 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation. + * All rights reserved. + * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include "qib.h" +#include "qib_common.h" + +static unsigned int ib_qib_qp_table_size = 251; +module_param_named(qp_table_size, ib_qib_qp_table_size, uint, S_IRUGO); +MODULE_PARM_DESC(qp_table_size, "QP table size"); + +unsigned int ib_qib_lkey_table_size = 16; +module_param_named(lkey_table_size, ib_qib_lkey_table_size, uint, + S_IRUGO); +MODULE_PARM_DESC(lkey_table_size, + "LKEY table size in bits (2^n, 1 <= n <= 23)"); + +static unsigned int ib_qib_max_pds = 0xFFFF; +module_param_named(max_pds, ib_qib_max_pds, uint, S_IRUGO); +MODULE_PARM_DESC(max_pds, + "Maximum number of protection domains to support"); + +static unsigned int ib_qib_max_ahs = 0xFFFF; +module_param_named(max_ahs, ib_qib_max_ahs, uint, S_IRUGO); +MODULE_PARM_DESC(max_ahs, "Maximum number of address handles to support"); + +unsigned int ib_qib_max_cqes = 0x2FFFF; +module_param_named(max_cqes, ib_qib_max_cqes, uint, S_IRUGO); +MODULE_PARM_DESC(max_cqes, + "Maximum number of completion queue entries to support"); + +unsigned int ib_qib_max_cqs = 0x1FFFF; +module_param_named(max_cqs, ib_qib_max_cqs, uint, S_IRUGO); +MODULE_PARM_DESC(max_cqs, "Maximum number of completion queues to support"); + +unsigned int ib_qib_max_qp_wrs = 0x3FFF; +module_param_named(max_qp_wrs, ib_qib_max_qp_wrs, uint, S_IRUGO); +MODULE_PARM_DESC(max_qp_wrs, "Maximum number of QP WRs to support"); + +unsigned int ib_qib_max_qps = 16384; +module_param_named(max_qps, ib_qib_max_qps, uint, S_IRUGO); +MODULE_PARM_DESC(max_qps, "Maximum number of QPs to support"); + +unsigned int ib_qib_max_sges = 0x60; +module_param_named(max_sges, ib_qib_max_sges, uint, S_IRUGO); +MODULE_PARM_DESC(max_sges, "Maximum number of SGEs to support"); + +unsigned int ib_qib_max_mcast_grps = 16384; +module_param_named(max_mcast_grps, ib_qib_max_mcast_grps, uint, S_IRUGO); +MODULE_PARM_DESC(max_mcast_grps, + "Maximum number of multicast groups to support"); + +unsigned int ib_qib_max_mcast_qp_attached = 16; +module_param_named(max_mcast_qp_attached, ib_qib_max_mcast_qp_attached, + uint, S_IRUGO); +MODULE_PARM_DESC(max_mcast_qp_attached, + "Maximum number of attached QPs to support"); + +unsigned int ib_qib_max_srqs = 1024; +module_param_named(max_srqs, ib_qib_max_srqs, uint, S_IRUGO); +MODULE_PARM_DESC(max_srqs, "Maximum number of SRQs to support"); + +unsigned int ib_qib_max_srq_sges = 128; +module_param_named(max_srq_sges, ib_qib_max_srq_sges, uint, S_IRUGO); +MODULE_PARM_DESC(max_srq_sges, "Maximum number of SRQ SGEs to support"); + +unsigned int ib_qib_max_srq_wrs = 0x1FFFF; +module_param_named(max_srq_wrs, ib_qib_max_srq_wrs, uint, S_IRUGO); +MODULE_PARM_DESC(max_srq_wrs, "Maximum number of SRQ WRs support"); + +static unsigned int ib_qib_disable_sma; +module_param_named(disable_sma, ib_qib_disable_sma, uint, S_IWUSR | S_IRUGO); +MODULE_PARM_DESC(disable_sma, "Disable the SMA"); + +/* + * Note that it is OK to post send work requests in the SQE and ERR + * states; qib_do_send() will process them and generate error + * completions as per IB 1.2 C10-96. + */ +const int ib_qib_state_ops[IB_QPS_ERR + 1] = { + [IB_QPS_RESET] = 0, + [IB_QPS_INIT] = QIB_POST_RECV_OK, + [IB_QPS_RTR] = QIB_POST_RECV_OK | QIB_PROCESS_RECV_OK, + [IB_QPS_RTS] = QIB_POST_RECV_OK | QIB_PROCESS_RECV_OK | + QIB_POST_SEND_OK | QIB_PROCESS_SEND_OK | + QIB_PROCESS_NEXT_SEND_OK, + [IB_QPS_SQD] = QIB_POST_RECV_OK | QIB_PROCESS_RECV_OK | + QIB_POST_SEND_OK | QIB_PROCESS_SEND_OK, + [IB_QPS_SQE] = QIB_POST_RECV_OK | QIB_PROCESS_RECV_OK | + QIB_POST_SEND_OK | QIB_FLUSH_SEND, + [IB_QPS_ERR] = QIB_POST_RECV_OK | QIB_FLUSH_RECV | + QIB_POST_SEND_OK | QIB_FLUSH_SEND, +}; + +struct qib_ucontext { + struct ib_ucontext ibucontext; +}; + +static inline struct qib_ucontext *to_iucontext(struct ib_ucontext + *ibucontext) +{ + return container_of(ibucontext, struct qib_ucontext, ibucontext); +} + +/* + * Translate ib_wr_opcode into ib_wc_opcode. + */ +const enum ib_wc_opcode ib_qib_wc_opcode[] = { + [IB_WR_RDMA_WRITE] = IB_WC_RDMA_WRITE, + [IB_WR_RDMA_WRITE_WITH_IMM] = IB_WC_RDMA_WRITE, + [IB_WR_SEND] = IB_WC_SEND, + [IB_WR_SEND_WITH_IMM] = IB_WC_SEND, + [IB_WR_RDMA_READ] = IB_WC_RDMA_READ, + [IB_WR_ATOMIC_CMP_AND_SWP] = IB_WC_COMP_SWAP, + [IB_WR_ATOMIC_FETCH_AND_ADD] = IB_WC_FETCH_ADD +}; + +/* + * System image GUID. + */ +__be64 ib_qib_sys_image_guid; + +/** + * qib_copy_sge - copy data to SGE memory + * @ss: the SGE state + * @data: the data to copy + * @length: the length of the data + */ +void qib_copy_sge(struct qib_sge_state *ss, void *data, u32 length, int release) +{ + struct qib_sge *sge = &ss->sge; + + while (length) { + u32 len = sge->length; + + if (len > length) + len = length; + if (len > sge->sge_length) + len = sge->sge_length; + BUG_ON(len == 0); + memcpy(sge->vaddr, data, len); + sge->vaddr += len; + sge->length -= len; + sge->sge_length -= len; + if (sge->sge_length == 0) { + if (release) + atomic_dec(&sge->mr->refcount); + if (--ss->num_sge) + *sge = *ss->sg_list++; + } else if (sge->length == 0 && sge->mr->lkey) { + if (++sge->n >= QIB_SEGSZ) { + if (++sge->m >= sge->mr->mapsz) + break; + sge->n = 0; + } + sge->vaddr = + sge->mr->map[sge->m]->segs[sge->n].vaddr; + sge->length = + sge->mr->map[sge->m]->segs[sge->n].length; + } + data += len; + length -= len; + } +} + +/** + * qib_skip_sge - skip over SGE memory - XXX almost dup of prev func + * @ss: the SGE state + * @length: the number of bytes to skip + */ +void qib_skip_sge(struct qib_sge_state *ss, u32 length, int release) +{ + struct qib_sge *sge = &ss->sge; + + while (length) { + u32 len = sge->length; + + if (len > length) + len = length; + if (len > sge->sge_length) + len = sge->sge_length; + BUG_ON(len == 0); + sge->vaddr += len; + sge->length -= len; + sge->sge_length -= len; + if (sge->sge_length == 0) { + if (release) + atomic_dec(&sge->mr->refcount); + if (--ss->num_sge) + *sge = *ss->sg_list++; + } else if (sge->length == 0 && sge->mr->lkey) { + if (++sge->n >= QIB_SEGSZ) { + if (++sge->m >= sge->mr->mapsz) + break; + sge->n = 0; + } + sge->vaddr = + sge->mr->map[sge->m]->segs[sge->n].vaddr; + sge->length = + sge->mr->map[sge->m]->segs[sge->n].length; + } + length -= len; + } +} + +/* + * Count the number of DMA descriptors needed to send length bytes of data. + * Don't modify the qib_sge_state to get the count. + * Return zero if any of the segments is not aligned. + */ +static u32 qib_count_sge(struct qib_sge_state *ss, u32 length) +{ + struct qib_sge *sg_list = ss->sg_list; + struct qib_sge sge = ss->sge; + u8 num_sge = ss->num_sge; + u32 ndesc = 1; /* count the header */ + + while (length) { + u32 len = sge.length; + + if (len > length) + len = length; + if (len > sge.sge_length) + len = sge.sge_length; + BUG_ON(len == 0); + if (((long) sge.vaddr & (sizeof(u32) - 1)) || + (len != length && (len & (sizeof(u32) - 1)))) { + ndesc = 0; + break; + } + ndesc++; + sge.vaddr += len; + sge.length -= len; + sge.sge_length -= len; + if (sge.sge_length == 0) { + if (--num_sge) + sge = *sg_list++; + } else if (sge.length == 0 && sge.mr->lkey) { + if (++sge.n >= QIB_SEGSZ) { + if (++sge.m >= sge.mr->mapsz) + break; + sge.n = 0; + } + sge.vaddr = + sge.mr->map[sge.m]->segs[sge.n].vaddr; + sge.length = + sge.mr->map[sge.m]->segs[sge.n].length; + } + length -= len; + } + return ndesc; +} + +/* + * Copy from the SGEs to the data buffer. + */ +static void qib_copy_from_sge(void *data, struct qib_sge_state *ss, u32 length) +{ + struct qib_sge *sge = &ss->sge; + + while (length) { + u32 len = sge->length; + + if (len > length) + len = length; + if (len > sge->sge_length) + len = sge->sge_length; + BUG_ON(len == 0); + memcpy(data, sge->vaddr, len); + sge->vaddr += len; + sge->length -= len; + sge->sge_length -= len; + if (sge->sge_length == 0) { + if (--ss->num_sge) + *sge = *ss->sg_list++; + } else if (sge->length == 0 && sge->mr->lkey) { + if (++sge->n >= QIB_SEGSZ) { + if (++sge->m >= sge->mr->mapsz) + break; + sge->n = 0; + } + sge->vaddr = + sge->mr->map[sge->m]->segs[sge->n].vaddr; + sge->length = + sge->mr->map[sge->m]->segs[sge->n].length; + } + data += len; + length -= len; + } +} + +/** + * qib_post_one_send - post one RC, UC, or UD send work request + * @qp: the QP to post on + * @wr: the work request to send + */ +static int qib_post_one_send(struct qib_qp *qp, struct ib_send_wr *wr) +{ + struct qib_swqe *wqe; + u32 next; + int i; + int j; + int acc; + int ret; + unsigned long flags; + struct qib_lkey_table *rkt; + struct qib_pd *pd; + + spin_lock_irqsave(&qp->s_lock, flags); + + /* Check that state is OK to post send. */ + if (unlikely(!(ib_qib_state_ops[qp->state] & QIB_POST_SEND_OK))) + goto bail_inval; + + /* IB spec says that num_sge == 0 is OK. */ + if (wr->num_sge > qp->s_max_sge) + goto bail_inval; + + /* + * Don't allow RDMA reads or atomic operations on UC or + * undefined operations. + * Make sure buffer is large enough to hold the result for atomics. + */ + if (wr->opcode == IB_WR_FAST_REG_MR) { + if (qib_fast_reg_mr(qp, wr)) + goto bail_inval; + } else if (qp->ibqp.qp_type == IB_QPT_UC) { + if ((unsigned) wr->opcode >= IB_WR_RDMA_READ) + goto bail_inval; + } else if (qp->ibqp.qp_type != IB_QPT_RC) { + /* Check IB_QPT_SMI, IB_QPT_GSI, IB_QPT_UD opcode */ + if (wr->opcode != IB_WR_SEND && + wr->opcode != IB_WR_SEND_WITH_IMM) + goto bail_inval; + /* Check UD destination address PD */ + if (qp->ibqp.pd != wr->wr.ud.ah->pd) + goto bail_inval; + } else if ((unsigned) wr->opcode > IB_WR_ATOMIC_FETCH_AND_ADD) + goto bail_inval; + else if (wr->opcode >= IB_WR_ATOMIC_CMP_AND_SWP && + (wr->num_sge == 0 || + wr->sg_list[0].length < sizeof(u64) || + wr->sg_list[0].addr & (sizeof(u64) - 1))) + goto bail_inval; + else if (wr->opcode >= IB_WR_RDMA_READ && !qp->s_max_rd_atomic) + goto bail_inval; + + next = qp->s_head + 1; + if (next >= qp->s_size) + next = 0; + if (next == qp->s_last) { + ret = -ENOMEM; + goto bail; + } + + rkt = &to_idev(qp->ibqp.device)->lk_table; + pd = to_ipd(qp->ibqp.pd); + wqe = get_swqe_ptr(qp, qp->s_head); + wqe->wr = *wr; + wqe->length = 0; + j = 0; + if (wr->num_sge) { + acc = wr->opcode >= IB_WR_RDMA_READ ? + IB_ACCESS_LOCAL_WRITE : 0; + for (i = 0; i < wr->num_sge; i++) { + u32 length = wr->sg_list[i].length; + int ok; + + if (length == 0) + continue; + ok = qib_lkey_ok(rkt, pd, &wqe->sg_list[j], + &wr->sg_list[i], acc); + if (!ok) + goto bail_inval_free; + wqe->length += length; + j++; + } + wqe->wr.num_sge = j; + } + if (qp->ibqp.qp_type == IB_QPT_UC || + qp->ibqp.qp_type == IB_QPT_RC) { + if (wqe->length > 0x80000000U) + goto bail_inval_free; + } else if (wqe->length > (dd_from_ibdev(qp->ibqp.device)->pport + + qp->port_num - 1)->ibmtu) + goto bail_inval_free; + else + atomic_inc(&to_iah(wr->wr.ud.ah)->refcount); + wqe->ssn = qp->s_ssn++; + qp->s_head = next; + + ret = 0; + goto bail; + +bail_inval_free: + while (j) { + struct qib_sge *sge = &wqe->sg_list[--j]; + + atomic_dec(&sge->mr->refcount); + } +bail_inval: + ret = -EINVAL; +bail: + spin_unlock_irqrestore(&qp->s_lock, flags); + return ret; +} + +/** + * qib_post_send - post a send on a QP + * @ibqp: the QP to post the send on + * @wr: the list of work requests to post + * @bad_wr: the first bad WR is put here + * + * This may be called from interrupt context. + */ +static int qib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, + struct ib_send_wr **bad_wr) +{ + struct qib_qp *qp = to_iqp(ibqp); + int err = 0; + + for (; wr; wr = wr->next) { + err = qib_post_one_send(qp, wr); + if (err) { + *bad_wr = wr; + goto bail; + } + } + + /* Try to do the send work in the caller's context. */ + qib_do_send(&qp->s_work); + +bail: + return err; +} + +/** + * qib_post_receive - post a receive on a QP + * @ibqp: the QP to post the receive on + * @wr: the WR to post + * @bad_wr: the first bad WR is put here + * + * This may be called from interrupt context. + */ +static int qib_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, + struct ib_recv_wr **bad_wr) +{ + struct qib_qp *qp = to_iqp(ibqp); + struct qib_rwq *wq = qp->r_rq.wq; + unsigned long flags; + int ret; + + /* Check that state is OK to post receive. */ + if (!(ib_qib_state_ops[qp->state] & QIB_POST_RECV_OK) || !wq) { + *bad_wr = wr; + ret = -EINVAL; + goto bail; + } + + for (; wr; wr = wr->next) { + struct qib_rwqe *wqe; + u32 next; + int i; + + if ((unsigned) wr->num_sge > qp->r_rq.max_sge) { + *bad_wr = wr; + ret = -EINVAL; + goto bail; + } + + spin_lock_irqsave(&qp->r_rq.lock, flags); + next = wq->head + 1; + if (next >= qp->r_rq.size) + next = 0; + if (next == wq->tail) { + spin_unlock_irqrestore(&qp->r_rq.lock, flags); + *bad_wr = wr; + ret = -ENOMEM; + goto bail; + } + + wqe = get_rwqe_ptr(&qp->r_rq, wq->head); + wqe->wr_id = wr->wr_id; + wqe->num_sge = wr->num_sge; + for (i = 0; i < wr->num_sge; i++) + wqe->sg_list[i] = wr->sg_list[i]; + /* Make sure queue entry is written before the head index. */ + smp_wmb(); + wq->head = next; + spin_unlock_irqrestore(&qp->r_rq.lock, flags); + } + ret = 0; + +bail: + return ret; +} + +/** + * qib_qp_rcv - processing an incoming packet on a QP + * @rcd: the context pointer + * @hdr: the packet header + * @has_grh: true if the packet has a GRH + * @data: the packet data + * @tlen: the packet length + * @qp: the QP the packet came on + * + * This is called from qib_ib_rcv() to process an incoming packet + * for the given QP. + * Called at interrupt level. + */ +static void qib_qp_rcv(struct qib_ctxtdata *rcd, struct qib_ib_header *hdr, + int has_grh, void *data, u32 tlen, struct qib_qp *qp) +{ + struct qib_ibport *ibp = &rcd->ppd->ibport_data; + + /* Check for valid receive state. */ + if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) { + ibp->n_pkt_drops++; + return; + } + + switch (qp->ibqp.qp_type) { + case IB_QPT_SMI: + case IB_QPT_GSI: + if (ib_qib_disable_sma) + break; + /* FALLTHROUGH */ + case IB_QPT_UD: + qib_ud_rcv(ibp, hdr, has_grh, data, tlen, qp); + break; + + case IB_QPT_RC: + qib_rc_rcv(rcd, hdr, has_grh, data, tlen, qp); + break; + + case IB_QPT_UC: + qib_uc_rcv(ibp, hdr, has_grh, data, tlen, qp); + break; + + default: + break; + } +} + +/** + * qib_ib_rcv - process an incoming packet + * @rcd: the context pointer + * @rhdr: the header of the packet + * @data: the packet payload + * @tlen: the packet length + * + * This is called from qib_kreceive() to process an incoming packet at + * interrupt level. Tlen is the length of the header + data + CRC in bytes. + */ +void qib_ib_rcv(struct qib_ctxtdata *rcd, void *rhdr, void *data, u32 tlen) +{ + struct qib_pportdata *ppd = rcd->ppd; + struct qib_ibport *ibp = &ppd->ibport_data; + struct qib_ib_header *hdr = rhdr; + struct qib_other_headers *ohdr; + struct qib_qp *qp; + u32 qp_num; + int lnh; + u8 opcode; + u16 lid; + + /* 24 == LRH+BTH+CRC */ + if (unlikely(tlen < 24)) + goto drop; + + /* Check for a valid destination LID (see ch. 7.11.1). */ + lid = be16_to_cpu(hdr->lrh[1]); + if (lid < QIB_MULTICAST_LID_BASE) { + lid &= ~((1 << ppd->lmc) - 1); + if (unlikely(lid != ppd->lid)) + goto drop; + } + + /* Check for GRH */ + lnh = be16_to_cpu(hdr->lrh[0]) & 3; + if (lnh == QIB_LRH_BTH) + ohdr = &hdr->u.oth; + else if (lnh == QIB_LRH_GRH) { + u32 vtf; + + ohdr = &hdr->u.l.oth; + if (hdr->u.l.grh.next_hdr != IB_GRH_NEXT_HDR) + goto drop; + vtf = be32_to_cpu(hdr->u.l.grh.version_tclass_flow); + if ((vtf >> IB_GRH_VERSION_SHIFT) != IB_GRH_VERSION) + goto drop; + } else + goto drop; + + opcode = be32_to_cpu(ohdr->bth[0]) >> 24; + ibp->opstats[opcode & 0x7f].n_bytes += tlen; + ibp->opstats[opcode & 0x7f].n_packets++; + + /* Get the destination QP number. */ + qp_num = be32_to_cpu(ohdr->bth[1]) & QIB_QPN_MASK; + if (qp_num == QIB_MULTICAST_QPN) { + struct qib_mcast *mcast; + struct qib_mcast_qp *p; + + if (lnh != QIB_LRH_GRH) + goto drop; + mcast = qib_mcast_find(ibp, &hdr->u.l.grh.dgid); + if (mcast == NULL) + goto drop; + ibp->n_multicast_rcv++; + list_for_each_entry_rcu(p, &mcast->qp_list, list) + qib_qp_rcv(rcd, hdr, 1, data, tlen, p->qp); + /* + * Notify qib_multicast_detach() if it is waiting for us + * to finish. + */ + if (atomic_dec_return(&mcast->refcount) <= 1) + wake_up(&mcast->wait); + } else { + qp = qib_lookup_qpn(ibp, qp_num); + if (!qp) + goto drop; + ibp->n_unicast_rcv++; + qib_qp_rcv(rcd, hdr, lnh == QIB_LRH_GRH, data, tlen, qp); + /* + * Notify qib_destroy_qp() if it is waiting + * for us to finish. + */ + if (atomic_dec_and_test(&qp->refcount)) + wake_up(&qp->wait); + } + return; + +drop: + ibp->n_pkt_drops++; +} + +/* + * This is called from a timer to check for QPs + * which need kernel memory in order to send a packet. + */ +static void mem_timer(unsigned long data) +{ + struct qib_ibdev *dev = (struct qib_ibdev *) data; + struct list_head *list = &dev->memwait; + struct qib_qp *qp = NULL; + unsigned long flags; + + spin_lock_irqsave(&dev->pending_lock, flags); + if (!list_empty(list)) { + qp = list_entry(list->next, struct qib_qp, iowait); + list_del_init(&qp->iowait); + atomic_inc(&qp->refcount); + if (!list_empty(list)) + mod_timer(&dev->mem_timer, jiffies + 1); + } + spin_unlock_irqrestore(&dev->pending_lock, flags); + + if (qp) { + spin_lock_irqsave(&qp->s_lock, flags); + if (qp->s_flags & QIB_S_WAIT_KMEM) { + qp->s_flags &= ~QIB_S_WAIT_KMEM; + qib_schedule_send(qp); + } + spin_unlock_irqrestore(&qp->s_lock, flags); + if (atomic_dec_and_test(&qp->refcount)) + wake_up(&qp->wait); + } +} + +static void update_sge(struct qib_sge_state *ss, u32 length) +{ + struct qib_sge *sge = &ss->sge; + + sge->vaddr += length; + sge->length -= length; + sge->sge_length -= length; + if (sge->sge_length == 0) { + if (--ss->num_sge) + *sge = *ss->sg_list++; + } else if (sge->length == 0 && sge->mr->lkey) { + if (++sge->n >= QIB_SEGSZ) { + if (++sge->m >= sge->mr->mapsz) + return; + sge->n = 0; + } + sge->vaddr = sge->mr->map[sge->m]->segs[sge->n].vaddr; + sge->length = sge->mr->map[sge->m]->segs[sge->n].length; + } +} + +#ifdef __LITTLE_ENDIAN +static inline u32 get_upper_bits(u32 data, u32 shift) +{ + return data >> shift; +} + +static inline u32 set_upper_bits(u32 data, u32 shift) +{ + return data << shift; +} + +static inline u32 clear_upper_bytes(u32 data, u32 n, u32 off) +{ + data <<= ((sizeof(u32) - n) * BITS_PER_BYTE); + data >>= ((sizeof(u32) - n - off) * BITS_PER_BYTE); + return data; +} +#else +static inline u32 get_upper_bits(u32 data, u32 shift) +{ + return data << shift; +} + +static inline u32 set_upper_bits(u32 data, u32 shift) +{ + return data >> shift; +} + +static inline u32 clear_upper_bytes(u32 data, u32 n, u32 off) +{ + data >>= ((sizeof(u32) - n) * BITS_PER_BYTE); + data <<= ((sizeof(u32) - n - off) * BITS_PER_BYTE); + return data; +} +#endif + +static void copy_io(u32 __iomem *piobuf, struct qib_sge_state *ss, + u32 length, unsigned flush_wc) +{ + u32 extra = 0; + u32 data = 0; + u32 last; + + while (1) { + u32 len = ss->sge.length; + u32 off; + + if (len > length) + len = length; + if (len > ss->sge.sge_length) + len = ss->sge.sge_length; + BUG_ON(len == 0); + /* If the source address is not aligned, try to align it. */ + off = (unsigned long)ss->sge.vaddr & (sizeof(u32) - 1); + if (off) { + u32 *addr = (u32 *)((unsigned long)ss->sge.vaddr & + ~(sizeof(u32) - 1)); + u32 v = get_upper_bits(*addr, off * BITS_PER_BYTE); + u32 y; + + y = sizeof(u32) - off; + if (len > y) + len = y; + if (len + extra >= sizeof(u32)) { + data |= set_upper_bits(v, extra * + BITS_PER_BYTE); + len = sizeof(u32) - extra; + if (len == length) { + last = data; + break; + } + __raw_writel(data, piobuf); + piobuf++; + extra = 0; + data = 0; + } else { + /* Clear unused upper bytes */ + data |= clear_upper_bytes(v, len, extra); + if (len == length) { + last = data; + break; + } + extra += len; + } + } else if (extra) { + /* Source address is aligned. */ + u32 *addr = (u32 *) ss->sge.vaddr; + int shift = extra * BITS_PER_BYTE; + int ushift = 32 - shift; + u32 l = len; + + while (l >= sizeof(u32)) { + u32 v = *addr; + + data |= set_upper_bits(v, shift); + __raw_writel(data, piobuf); + data = get_upper_bits(v, ushift); + piobuf++; + addr++; + l -= sizeof(u32); + } + /* + * We still have 'extra' number of bytes leftover. + */ + if (l) { + u32 v = *addr; + + if (l + extra >= sizeof(u32)) { + data |= set_upper_bits(v, shift); + len -= l + extra - sizeof(u32); + if (len == length) { + last = data; + break; + } + __raw_writel(data, piobuf); + piobuf++; + extra = 0; + data = 0; + } else { + /* Clear unused upper bytes */ + data |= clear_upper_bytes(v, l, extra); + if (len == length) { + last = data; + break; + } + extra += l; + } + } else if (len == length) { + last = data; + break; + } + } else if (len == length) { + u32 w; + + /* + * Need to round up for the last dword in the + * packet. + */ + w = (len + 3) >> 2; + qib_pio_copy(piobuf, ss->sge.vaddr, w - 1); + piobuf += w - 1; + last = ((u32 *) ss->sge.vaddr)[w - 1]; + break; + } else { + u32 w = len >> 2; + + qib_pio_copy(piobuf, ss->sge.vaddr, w); + piobuf += w; + + extra = len & (sizeof(u32) - 1); + if (extra) { + u32 v = ((u32 *) ss->sge.vaddr)[w]; + + /* Clear unused upper bytes */ + data = clear_upper_bytes(v, extra, 0); + } + } + update_sge(ss, len); + length -= len; + } + /* Update address before sending packet. */ + update_sge(ss, length); + if (flush_wc) { + /* must flush early everything before trigger word */ + qib_flush_wc(); + __raw_writel(last, piobuf); + /* be sure trigger word is written */ + qib_flush_wc(); + } else + __raw_writel(last, piobuf); +} + +static struct qib_verbs_txreq *get_txreq(struct qib_ibdev *dev, + struct qib_qp *qp, int *retp) +{ + struct qib_verbs_txreq *tx; + unsigned long flags; + + spin_lock_irqsave(&qp->s_lock, flags); + spin_lock(&dev->pending_lock); + + if (!list_empty(&dev->txreq_free)) { + struct list_head *l = dev->txreq_free.next; + + list_del(l); + tx = list_entry(l, struct qib_verbs_txreq, txreq.list); + *retp = 0; + } else { + if (ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK && + list_empty(&qp->iowait)) { + dev->n_txwait++; + qp->s_flags |= QIB_S_WAIT_TX; + list_add_tail(&qp->iowait, &dev->txwait); + } + tx = NULL; + qp->s_flags &= ~QIB_S_BUSY; + *retp = -EBUSY; + } + + spin_unlock(&dev->pending_lock); + spin_unlock_irqrestore(&qp->s_lock, flags); + + return tx; +} + +void qib_put_txreq(struct qib_verbs_txreq *tx) +{ + struct qib_ibdev *dev; + struct qib_qp *qp; + unsigned long flags; + + qp = tx->qp; + dev = to_idev(qp->ibqp.device); + + if (atomic_dec_and_test(&qp->refcount)) + wake_up(&qp->wait); + if (tx->mr) { + atomic_dec(&tx->mr->refcount); + tx->mr = NULL; + } + if (tx->txreq.flags & QIB_SDMA_TXREQ_F_FREEBUF) { + tx->txreq.flags &= ~QIB_SDMA_TXREQ_F_FREEBUF; + dma_unmap_single(&dd_from_dev(dev)->pcidev->dev, + tx->txreq.addr, tx->hdr_dwords << 2, + DMA_TO_DEVICE); + kfree(tx->align_buf); + } + + spin_lock_irqsave(&dev->pending_lock, flags); + + /* Put struct back on free list */ + list_add(&tx->txreq.list, &dev->txreq_free); + + if (!list_empty(&dev->txwait)) { + /* Wake up first QP wanting a free struct */ + qp = list_entry(dev->txwait.next, struct qib_qp, iowait); + list_del_init(&qp->iowait); + atomic_inc(&qp->refcount); + spin_unlock_irqrestore(&dev->pending_lock, flags); + + spin_lock_irqsave(&qp->s_lock, flags); + if (qp->s_flags & QIB_S_WAIT_TX) { + qp->s_flags &= ~QIB_S_WAIT_TX; + qib_schedule_send(qp); + } + spin_unlock_irqrestore(&qp->s_lock, flags); + + if (atomic_dec_and_test(&qp->refcount)) + wake_up(&qp->wait); + } else + spin_unlock_irqrestore(&dev->pending_lock, flags); +} + +/* + * This is called when there are send DMA descriptors that might be + * available. + * + * This is called with ppd->sdma_lock held. + */ +void qib_verbs_sdma_desc_avail(struct qib_pportdata *ppd, unsigned avail) +{ + struct qib_qp *qp, *nqp; + struct qib_qp *qps[20]; + struct qib_ibdev *dev; + unsigned i, n; + + n = 0; + dev = &ppd->dd->verbs_dev; + spin_lock(&dev->pending_lock); + + /* Search wait list for first QP wanting DMA descriptors. */ + list_for_each_entry_safe(qp, nqp, &dev->dmawait, iowait) { + if (qp->port_num != ppd->port) + continue; + if (n == ARRAY_SIZE(qps)) + break; + if (qp->s_tx->txreq.sg_count > avail) + break; + avail -= qp->s_tx->txreq.sg_count; + list_del_init(&qp->iowait); + atomic_inc(&qp->refcount); + qps[n++] = qp; + } + + spin_unlock(&dev->pending_lock); + + for (i = 0; i < n; i++) { + qp = qps[i]; + spin_lock(&qp->s_lock); + if (qp->s_flags & QIB_S_WAIT_DMA_DESC) { + qp->s_flags &= ~QIB_S_WAIT_DMA_DESC; + qib_schedule_send(qp); + } + spin_unlock(&qp->s_lock); + if (atomic_dec_and_test(&qp->refcount)) + wake_up(&qp->wait); + } +} + +/* + * This is called with ppd->sdma_lock held. + */ +static void sdma_complete(struct qib_sdma_txreq *cookie, int status) +{ + struct qib_verbs_txreq *tx = + container_of(cookie, struct qib_verbs_txreq, txreq); + struct qib_qp *qp = tx->qp; + + spin_lock(&qp->s_lock); + if (tx->wqe) + qib_send_complete(qp, tx->wqe, IB_WC_SUCCESS); + else if (qp->ibqp.qp_type == IB_QPT_RC) { + struct qib_ib_header *hdr; + + if (tx->txreq.flags & QIB_SDMA_TXREQ_F_FREEBUF) + hdr = &tx->align_buf->hdr; + else { + struct qib_ibdev *dev = to_idev(qp->ibqp.device); + + hdr = &dev->pio_hdrs[tx->hdr_inx].hdr; + } + qib_rc_send_complete(qp, hdr); + } + if (atomic_dec_and_test(&qp->s_dma_busy)) { + if (qp->state == IB_QPS_RESET) + wake_up(&qp->wait_dma); + else if (qp->s_flags & QIB_S_WAIT_DMA) { + qp->s_flags &= ~QIB_S_WAIT_DMA; + qib_schedule_send(qp); + } + } + spin_unlock(&qp->s_lock); + + qib_put_txreq(tx); +} + +static int wait_kmem(struct qib_ibdev *dev, struct qib_qp *qp) +{ + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&qp->s_lock, flags); + if (ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK) { + spin_lock(&dev->pending_lock); + if (list_empty(&qp->iowait)) { + if (list_empty(&dev->memwait)) + mod_timer(&dev->mem_timer, jiffies + 1); + qp->s_flags |= QIB_S_WAIT_KMEM; + list_add_tail(&qp->iowait, &dev->memwait); + } + spin_unlock(&dev->pending_lock); + qp->s_flags &= ~QIB_S_BUSY; + ret = -EBUSY; + } + spin_unlock_irqrestore(&qp->s_lock, flags); + + return ret; +} + +static int qib_verbs_send_dma(struct qib_qp *qp, struct qib_ib_header *hdr, + u32 hdrwords, struct qib_sge_state *ss, u32 len, + u32 plen, u32 dwords) +{ + struct qib_ibdev *dev = to_idev(qp->ibqp.device); + struct qib_devdata *dd = dd_from_dev(dev); + struct qib_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); + struct qib_pportdata *ppd = ppd_from_ibp(ibp); + struct qib_verbs_txreq *tx; + struct qib_pio_header *phdr; + u32 control; + u32 ndesc; + int ret; + + tx = qp->s_tx; + if (tx) { + qp->s_tx = NULL; + /* resend previously constructed packet */ + ret = qib_sdma_verbs_send(ppd, tx->ss, tx->dwords, tx); + goto bail; + } + + tx = get_txreq(dev, qp, &ret); + if (!tx) + goto bail; + + control = dd->f_setpbc_control(ppd, plen, qp->s_srate, + be16_to_cpu(hdr->lrh[0]) >> 12); + tx->qp = qp; + atomic_inc(&qp->refcount); + tx->wqe = qp->s_wqe; + tx->mr = qp->s_rdma_mr; + if (qp->s_rdma_mr) + qp->s_rdma_mr = NULL; + tx->txreq.callback = sdma_complete; + if (dd->flags & QIB_HAS_SDMA_TIMEOUT) + tx->txreq.flags = QIB_SDMA_TXREQ_F_HEADTOHOST; + else + tx->txreq.flags = QIB_SDMA_TXREQ_F_INTREQ; + if (plen + 1 > dd->piosize2kmax_dwords) + tx->txreq.flags |= QIB_SDMA_TXREQ_F_USELARGEBUF; + + if (len) { + /* + * Don't try to DMA if it takes more descriptors than + * the queue holds. + */ + ndesc = qib_count_sge(ss, len); + if (ndesc >= ppd->sdma_descq_cnt) + ndesc = 0; + } else + ndesc = 1; + if (ndesc) { + phdr = &dev->pio_hdrs[tx->hdr_inx]; + phdr->pbc[0] = cpu_to_le32(plen); + phdr->pbc[1] = cpu_to_le32(control); + memcpy(&phdr->hdr, hdr, hdrwords << 2); + tx->txreq.flags |= QIB_SDMA_TXREQ_F_FREEDESC; + tx->txreq.sg_count = ndesc; + tx->txreq.addr = dev->pio_hdrs_phys + + tx->hdr_inx * sizeof(struct qib_pio_header); + tx->hdr_dwords = hdrwords + 2; /* add PBC length */ + ret = qib_sdma_verbs_send(ppd, ss, dwords, tx); + goto bail; + } + + /* Allocate a buffer and copy the header and payload to it. */ + tx->hdr_dwords = plen + 1; + phdr = kmalloc(tx->hdr_dwords << 2, GFP_ATOMIC); + if (!phdr) + goto err_tx; + phdr->pbc[0] = cpu_to_le32(plen); + phdr->pbc[1] = cpu_to_le32(control); + memcpy(&phdr->hdr, hdr, hdrwords << 2); + qib_copy_from_sge((u32 *) &phdr->hdr + hdrwords, ss, len); + + tx->txreq.addr = dma_map_single(&dd->pcidev->dev, phdr, + tx->hdr_dwords << 2, DMA_TO_DEVICE); + if (dma_mapping_error(&dd->pcidev->dev, tx->txreq.addr)) + goto map_err; + tx->align_buf = phdr; + tx->txreq.flags |= QIB_SDMA_TXREQ_F_FREEBUF; + tx->txreq.sg_count = 1; + ret = qib_sdma_verbs_send(ppd, NULL, 0, tx); + goto unaligned; + +map_err: + kfree(phdr); +err_tx: + qib_put_txreq(tx); + ret = wait_kmem(dev, qp); +unaligned: + ibp->n_unaligned++; +bail: + return ret; +} + +/* + * If we are now in the error state, return zero to flush the + * send work request. + */ +static int no_bufs_available(struct qib_qp *qp) +{ + struct qib_ibdev *dev = to_idev(qp->ibqp.device); + struct qib_devdata *dd; + unsigned long flags; + int ret = 0; + + /* + * Note that as soon as want_buffer() is called and + * possibly before it returns, qib_ib_piobufavail() + * could be called. Therefore, put QP on the I/O wait list before + * enabling the PIO avail interrupt. + */ + spin_lock_irqsave(&qp->s_lock, flags); + if (ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK) { + spin_lock(&dev->pending_lock); + if (list_empty(&qp->iowait)) { + dev->n_piowait++; + qp->s_flags |= QIB_S_WAIT_PIO; + list_add_tail(&qp->iowait, &dev->piowait); + dd = dd_from_dev(dev); + dd->f_wantpiobuf_intr(dd, 1); + } + spin_unlock(&dev->pending_lock); + qp->s_flags &= ~QIB_S_BUSY; + ret = -EBUSY; + } + spin_unlock_irqrestore(&qp->s_lock, flags); + return ret; +} + +static int qib_verbs_send_pio(struct qib_qp *qp, struct qib_ib_header *ibhdr, + u32 hdrwords, struct qib_sge_state *ss, u32 len, + u32 plen, u32 dwords) +{ + struct qib_devdata *dd = dd_from_ibdev(qp->ibqp.device); + struct qib_pportdata *ppd = dd->pport + qp->port_num - 1; + u32 *hdr = (u32 *) ibhdr; + u32 __iomem *piobuf_orig; + u32 __iomem *piobuf; + u64 pbc; + unsigned long flags; + unsigned flush_wc; + u32 control; + u32 pbufn; + + control = dd->f_setpbc_control(ppd, plen, qp->s_srate, + be16_to_cpu(ibhdr->lrh[0]) >> 12); + pbc = ((u64) control << 32) | plen; + piobuf = dd->f_getsendbuf(ppd, pbc, &pbufn); + if (unlikely(piobuf == NULL)) + return no_bufs_available(qp); + + /* + * Write the pbc. + * We have to flush after the PBC for correctness on some cpus + * or WC buffer can be written out of order. + */ + writeq(pbc, piobuf); + piobuf_orig = piobuf; + piobuf += 2; + + flush_wc = dd->flags & QIB_PIO_FLUSH_WC; + if (len == 0) { + /* + * If there is just the header portion, must flush before + * writing last word of header for correctness, and after + * the last header word (trigger word). + */ + if (flush_wc) { + qib_flush_wc(); + qib_pio_copy(piobuf, hdr, hdrwords - 1); + qib_flush_wc(); + __raw_writel(hdr[hdrwords - 1], piobuf + hdrwords - 1); + qib_flush_wc(); + } else + qib_pio_copy(piobuf, hdr, hdrwords); + goto done; + } + + if (flush_wc) + qib_flush_wc(); + qib_pio_copy(piobuf, hdr, hdrwords); + piobuf += hdrwords; + + /* The common case is aligned and contained in one segment. */ + if (likely(ss->num_sge == 1 && len <= ss->sge.length && + !((unsigned long)ss->sge.vaddr & (sizeof(u32) - 1)))) { + u32 *addr = (u32 *) ss->sge.vaddr; + + /* Update address before sending packet. */ + update_sge(ss, len); + if (flush_wc) { + qib_pio_copy(piobuf, addr, dwords - 1); + /* must flush early everything before trigger word */ + qib_flush_wc(); + __raw_writel(addr[dwords - 1], piobuf + dwords - 1); + /* be sure trigger word is written */ + qib_flush_wc(); + } else + qib_pio_copy(piobuf, addr, dwords); + goto done; + } + copy_io(piobuf, ss, len, flush_wc); +done: + if (dd->flags & QIB_USE_SPCL_TRIG) { + u32 spcl_off = (pbufn >= dd->piobcnt2k) ? 2047 : 1023; + qib_flush_wc(); + __raw_writel(0xaebecede, piobuf_orig + spcl_off); + } + qib_sendbuf_done(dd, pbufn); + if (qp->s_rdma_mr) { + atomic_dec(&qp->s_rdma_mr->refcount); + qp->s_rdma_mr = NULL; + } + if (qp->s_wqe) { + spin_lock_irqsave(&qp->s_lock, flags); + qib_send_complete(qp, qp->s_wqe, IB_WC_SUCCESS); + spin_unlock_irqrestore(&qp->s_lock, flags); + } else if (qp->ibqp.qp_type == IB_QPT_RC) { + spin_lock_irqsave(&qp->s_lock, flags); + qib_rc_send_complete(qp, ibhdr); + spin_unlock_irqrestore(&qp->s_lock, flags); + } + return 0; +} + +/** + * qib_verbs_send - send a packet + * @qp: the QP to send on + * @hdr: the packet header + * @hdrwords: the number of 32-bit words in the header + * @ss: the SGE to send + * @len: the length of the packet in bytes + * + * Return zero if packet is sent or queued OK. + * Return non-zero and clear qp->s_flags QIB_S_BUSY otherwise. + */ +int qib_verbs_send(struct qib_qp *qp, struct qib_ib_header *hdr, + u32 hdrwords, struct qib_sge_state *ss, u32 len) +{ + struct qib_devdata *dd = dd_from_ibdev(qp->ibqp.device); + u32 plen; + int ret; + u32 dwords = (len + 3) >> 2; + + /* + * Calculate the send buffer trigger address. + * The +1 counts for the pbc control dword following the pbc length. + */ + plen = hdrwords + dwords + 1; + + /* + * VL15 packets (IB_QPT_SMI) will always use PIO, so we + * can defer SDMA restart until link goes ACTIVE without + * worrying about just how we got there. + */ + if (qp->ibqp.qp_type == IB_QPT_SMI || + !(dd->flags & QIB_HAS_SEND_DMA)) + ret = qib_verbs_send_pio(qp, hdr, hdrwords, ss, len, + plen, dwords); + else + ret = qib_verbs_send_dma(qp, hdr, hdrwords, ss, len, + plen, dwords); + + return ret; +} + +int qib_snapshot_counters(struct qib_pportdata *ppd, u64 *swords, + u64 *rwords, u64 *spkts, u64 *rpkts, + u64 *xmit_wait) +{ + int ret; + struct qib_devdata *dd = ppd->dd; + + if (!(dd->flags & QIB_PRESENT)) { + /* no hardware, freeze, etc. */ + ret = -EINVAL; + goto bail; + } + *swords = dd->f_portcntr(ppd, QIBPORTCNTR_WORDSEND); + *rwords = dd->f_portcntr(ppd, QIBPORTCNTR_WORDRCV); + *spkts = dd->f_portcntr(ppd, QIBPORTCNTR_PKTSEND); + *rpkts = dd->f_portcntr(ppd, QIBPORTCNTR_PKTRCV); + *xmit_wait = dd->f_portcntr(ppd, QIBPORTCNTR_SENDSTALL); + + ret = 0; + +bail: + return ret; +} + +/** + * qib_get_counters - get various chip counters + * @dd: the qlogic_ib device + * @cntrs: counters are placed here + * + * Return the counters needed by recv_pma_get_portcounters(). + */ +int qib_get_counters(struct qib_pportdata *ppd, + struct qib_verbs_counters *cntrs) +{ + int ret; + + if (!(ppd->dd->flags & QIB_PRESENT)) { + /* no hardware, freeze, etc. */ + ret = -EINVAL; + goto bail; + } + cntrs->symbol_error_counter = + ppd->dd->f_portcntr(ppd, QIBPORTCNTR_IBSYMBOLERR); + cntrs->link_error_recovery_counter = + ppd->dd->f_portcntr(ppd, QIBPORTCNTR_IBLINKERRRECOV); + /* + * The link downed counter counts when the other side downs the + * connection. We add in the number of times we downed the link + * due to local link integrity errors to compensate. + */ + cntrs->link_downed_counter = + ppd->dd->f_portcntr(ppd, QIBPORTCNTR_IBLINKDOWN); + cntrs->port_rcv_errors = + ppd->dd->f_portcntr(ppd, QIBPORTCNTR_RXDROPPKT) + + ppd->dd->f_portcntr(ppd, QIBPORTCNTR_RCVOVFL) + + ppd->dd->f_portcntr(ppd, QIBPORTCNTR_ERR_RLEN) + + ppd->dd->f_portcntr(ppd, QIBPORTCNTR_INVALIDRLEN) + + ppd->dd->f_portcntr(ppd, QIBPORTCNTR_ERRLINK) + + ppd->dd->f_portcntr(ppd, QIBPORTCNTR_ERRICRC) + + ppd->dd->f_portcntr(ppd, QIBPORTCNTR_ERRVCRC) + + ppd->dd->f_portcntr(ppd, QIBPORTCNTR_ERRLPCRC) + + ppd->dd->f_portcntr(ppd, QIBPORTCNTR_BADFORMAT); + cntrs->port_rcv_errors += + ppd->dd->f_portcntr(ppd, QIBPORTCNTR_RXLOCALPHYERR); + cntrs->port_rcv_errors += + ppd->dd->f_portcntr(ppd, QIBPORTCNTR_RXVLERR); + cntrs->port_rcv_remphys_errors = + ppd->dd->f_portcntr(ppd, QIBPORTCNTR_RCVEBP); + cntrs->port_xmit_discards = + ppd->dd->f_portcntr(ppd, QIBPORTCNTR_UNSUPVL); + cntrs->port_xmit_data = ppd->dd->f_portcntr(ppd, + QIBPORTCNTR_WORDSEND); + cntrs->port_rcv_data = ppd->dd->f_portcntr(ppd, + QIBPORTCNTR_WORDRCV); + cntrs->port_xmit_packets = ppd->dd->f_portcntr(ppd, + QIBPORTCNTR_PKTSEND); + cntrs->port_rcv_packets = ppd->dd->f_portcntr(ppd, + QIBPORTCNTR_PKTRCV); + cntrs->local_link_integrity_errors = + ppd->dd->f_portcntr(ppd, QIBPORTCNTR_LLI); + cntrs->excessive_buffer_overrun_errors = + ppd->dd->f_portcntr(ppd, QIBPORTCNTR_EXCESSBUFOVFL); + cntrs->vl15_dropped = + ppd->dd->f_portcntr(ppd, QIBPORTCNTR_VL15PKTDROP); + + ret = 0; + +bail: + return ret; +} + +/** + * qib_ib_piobufavail - callback when a PIO buffer is available + * @dd: the device pointer + * + * This is called from qib_intr() at interrupt level when a PIO buffer is + * available after qib_verbs_send() returned an error that no buffers were + * available. Disable the interrupt if there are no more QPs waiting. + */ +void qib_ib_piobufavail(struct qib_devdata *dd) +{ + struct qib_ibdev *dev = &dd->verbs_dev; + struct list_head *list; + struct qib_qp *qps[5]; + struct qib_qp *qp; + unsigned long flags; + unsigned i, n; + + list = &dev->piowait; + n = 0; + + /* + * Note: checking that the piowait list is empty and clearing + * the buffer available interrupt needs to be atomic or we + * could end up with QPs on the wait list with the interrupt + * disabled. + */ + spin_lock_irqsave(&dev->pending_lock, flags); + while (!list_empty(list)) { + if (n == ARRAY_SIZE(qps)) + goto full; + qp = list_entry(list->next, struct qib_qp, iowait); + list_del_init(&qp->iowait); + atomic_inc(&qp->refcount); + qps[n++] = qp; + } + dd->f_wantpiobuf_intr(dd, 0); +full: + spin_unlock_irqrestore(&dev->pending_lock, flags); + + for (i = 0; i < n; i++) { + qp = qps[i]; + + spin_lock_irqsave(&qp->s_lock, flags); + if (qp->s_flags & QIB_S_WAIT_PIO) { + qp->s_flags &= ~QIB_S_WAIT_PIO; + qib_schedule_send(qp); + } + spin_unlock_irqrestore(&qp->s_lock, flags); + + /* Notify qib_destroy_qp() if it is waiting. */ + if (atomic_dec_and_test(&qp->refcount)) + wake_up(&qp->wait); + } +} + +static int qib_query_device(struct ib_device *ibdev, + struct ib_device_attr *props) +{ + struct qib_devdata *dd = dd_from_ibdev(ibdev); + struct qib_ibdev *dev = to_idev(ibdev); + + memset(props, 0, sizeof(*props)); + + props->device_cap_flags = IB_DEVICE_BAD_PKEY_CNTR | + IB_DEVICE_BAD_QKEY_CNTR | IB_DEVICE_SHUTDOWN_PORT | + IB_DEVICE_SYS_IMAGE_GUID | IB_DEVICE_RC_RNR_NAK_GEN | + IB_DEVICE_PORT_ACTIVE_EVENT | IB_DEVICE_SRQ_RESIZE; + props->page_size_cap = PAGE_SIZE; + props->vendor_id = + QIB_SRC_OUI_1 << 16 | QIB_SRC_OUI_2 << 8 | QIB_SRC_OUI_3; + props->vendor_part_id = dd->deviceid; + props->hw_ver = dd->minrev; + props->sys_image_guid = ib_qib_sys_image_guid; + props->max_mr_size = ~0ULL; + props->max_qp = ib_qib_max_qps; + props->max_qp_wr = ib_qib_max_qp_wrs; + props->max_sge = ib_qib_max_sges; + props->max_cq = ib_qib_max_cqs; + props->max_ah = ib_qib_max_ahs; + props->max_cqe = ib_qib_max_cqes; + props->max_mr = dev->lk_table.max; + props->max_fmr = dev->lk_table.max; + props->max_map_per_fmr = 32767; + props->max_pd = ib_qib_max_pds; + props->max_qp_rd_atom = QIB_MAX_RDMA_ATOMIC; + props->max_qp_init_rd_atom = 255; + /* props->max_res_rd_atom */ + props->max_srq = ib_qib_max_srqs; + props->max_srq_wr = ib_qib_max_srq_wrs; + props->max_srq_sge = ib_qib_max_srq_sges; + /* props->local_ca_ack_delay */ + props->atomic_cap = IB_ATOMIC_GLOB; + props->max_pkeys = qib_get_npkeys(dd); + props->max_mcast_grp = ib_qib_max_mcast_grps; + props->max_mcast_qp_attach = ib_qib_max_mcast_qp_attached; + props->max_total_mcast_qp_attach = props->max_mcast_qp_attach * + props->max_mcast_grp; + + return 0; +} + +static int qib_query_port(struct ib_device *ibdev, u8 port, + struct ib_port_attr *props) +{ + struct qib_devdata *dd = dd_from_ibdev(ibdev); + struct qib_ibport *ibp = to_iport(ibdev, port); + struct qib_pportdata *ppd = ppd_from_ibp(ibp); + enum ib_mtu mtu; + u16 lid = ppd->lid; + + memset(props, 0, sizeof(*props)); + props->lid = lid ? lid : be16_to_cpu(IB_LID_PERMISSIVE); + props->lmc = ppd->lmc; + props->sm_lid = ibp->sm_lid; + props->sm_sl = ibp->sm_sl; + props->state = dd->f_iblink_state(ppd->lastibcstat); + props->phys_state = dd->f_ibphys_portstate(ppd->lastibcstat); + props->port_cap_flags = ibp->port_cap_flags; + props->gid_tbl_len = QIB_GUIDS_PER_PORT; + props->max_msg_sz = 0x80000000; + props->pkey_tbl_len = qib_get_npkeys(dd); + props->bad_pkey_cntr = ibp->pkey_violations; + props->qkey_viol_cntr = ibp->qkey_violations; + props->active_width = ppd->link_width_active; + /* See rate_show() */ + props->active_speed = ppd->link_speed_active; + props->max_vl_num = qib_num_vls(ppd->vls_supported); + props->init_type_reply = 0; + + props->max_mtu = qib_ibmtu ? qib_ibmtu : IB_MTU_4096; + switch (ppd->ibmtu) { + case 4096: + mtu = IB_MTU_4096; + break; + case 2048: + mtu = IB_MTU_2048; + break; + case 1024: + mtu = IB_MTU_1024; + break; + case 512: + mtu = IB_MTU_512; + break; + case 256: + mtu = IB_MTU_256; + break; + default: + mtu = IB_MTU_2048; + } + props->active_mtu = mtu; + props->subnet_timeout = ibp->subnet_timeout; + + return 0; +} + +static int qib_modify_device(struct ib_device *device, + int device_modify_mask, + struct ib_device_modify *device_modify) +{ + struct qib_devdata *dd = dd_from_ibdev(device); + unsigned i; + int ret; + + if (device_modify_mask & ~(IB_DEVICE_MODIFY_SYS_IMAGE_GUID | + IB_DEVICE_MODIFY_NODE_DESC)) { + ret = -EOPNOTSUPP; + goto bail; + } + + if (device_modify_mask & IB_DEVICE_MODIFY_NODE_DESC) { + memcpy(device->node_desc, device_modify->node_desc, 64); + for (i = 0; i < dd->num_pports; i++) { + struct qib_ibport *ibp = &dd->pport[i].ibport_data; + + qib_node_desc_chg(ibp); + } + } + + if (device_modify_mask & IB_DEVICE_MODIFY_SYS_IMAGE_GUID) { + ib_qib_sys_image_guid = + cpu_to_be64(device_modify->sys_image_guid); + for (i = 0; i < dd->num_pports; i++) { + struct qib_ibport *ibp = &dd->pport[i].ibport_data; + + qib_sys_guid_chg(ibp); + } + } + + ret = 0; + +bail: + return ret; +} + +static int qib_modify_port(struct ib_device *ibdev, u8 port, + int port_modify_mask, struct ib_port_modify *props) +{ + struct qib_ibport *ibp = to_iport(ibdev, port); + struct qib_pportdata *ppd = ppd_from_ibp(ibp); + + ibp->port_cap_flags |= props->set_port_cap_mask; + ibp->port_cap_flags &= ~props->clr_port_cap_mask; + if (props->set_port_cap_mask || props->clr_port_cap_mask) + qib_cap_mask_chg(ibp); + if (port_modify_mask & IB_PORT_SHUTDOWN) + qib_set_linkstate(ppd, QIB_IB_LINKDOWN); + if (port_modify_mask & IB_PORT_RESET_QKEY_CNTR) + ibp->qkey_violations = 0; + return 0; +} + +static int qib_query_gid(struct ib_device *ibdev, u8 port, + int index, union ib_gid *gid) +{ + struct qib_devdata *dd = dd_from_ibdev(ibdev); + int ret = 0; + + if (!port || port > dd->num_pports) + ret = -EINVAL; + else { + struct qib_ibport *ibp = to_iport(ibdev, port); + struct qib_pportdata *ppd = ppd_from_ibp(ibp); + + gid->global.subnet_prefix = ibp->gid_prefix; + if (index == 0) + gid->global.interface_id = ppd->guid; + else if (index < QIB_GUIDS_PER_PORT) + gid->global.interface_id = ibp->guids[index - 1]; + else + ret = -EINVAL; + } + + return ret; +} + +static struct ib_pd *qib_alloc_pd(struct ib_device *ibdev, + struct ib_ucontext *context, + struct ib_udata *udata) +{ + struct qib_ibdev *dev = to_idev(ibdev); + struct qib_pd *pd; + struct ib_pd *ret; + + /* + * This is actually totally arbitrary. Some correctness tests + * assume there's a maximum number of PDs that can be allocated. + * We don't actually have this limit, but we fail the test if + * we allow allocations of more than we report for this value. + */ + + pd = kmalloc(sizeof *pd, GFP_KERNEL); + if (!pd) { + ret = ERR_PTR(-ENOMEM); + goto bail; + } + + spin_lock(&dev->n_pds_lock); + if (dev->n_pds_allocated == ib_qib_max_pds) { + spin_unlock(&dev->n_pds_lock); + kfree(pd); + ret = ERR_PTR(-ENOMEM); + goto bail; + } + + dev->n_pds_allocated++; + spin_unlock(&dev->n_pds_lock); + + /* ib_alloc_pd() will initialize pd->ibpd. */ + pd->user = udata != NULL; + + ret = &pd->ibpd; + +bail: + return ret; +} + +static int qib_dealloc_pd(struct ib_pd *ibpd) +{ + struct qib_pd *pd = to_ipd(ibpd); + struct qib_ibdev *dev = to_idev(ibpd->device); + + spin_lock(&dev->n_pds_lock); + dev->n_pds_allocated--; + spin_unlock(&dev->n_pds_lock); + + kfree(pd); + + return 0; +} + +int qib_check_ah(struct ib_device *ibdev, struct ib_ah_attr *ah_attr) +{ + /* A multicast address requires a GRH (see ch. 8.4.1). */ + if (ah_attr->dlid >= QIB_MULTICAST_LID_BASE && + ah_attr->dlid != QIB_PERMISSIVE_LID && + !(ah_attr->ah_flags & IB_AH_GRH)) + goto bail; + if ((ah_attr->ah_flags & IB_AH_GRH) && + ah_attr->grh.sgid_index >= QIB_GUIDS_PER_PORT) + goto bail; + if (ah_attr->dlid == 0) + goto bail; + if (ah_attr->port_num < 1 || + ah_attr->port_num > ibdev->phys_port_cnt) + goto bail; + if (ah_attr->static_rate != IB_RATE_PORT_CURRENT && + ib_rate_to_mult(ah_attr->static_rate) < 0) + goto bail; + if (ah_attr->sl > 15) + goto bail; + return 0; +bail: + return -EINVAL; +} + +/** + * qib_create_ah - create an address handle + * @pd: the protection domain + * @ah_attr: the attributes of the AH + * + * This may be called from interrupt context. + */ +static struct ib_ah *qib_create_ah(struct ib_pd *pd, + struct ib_ah_attr *ah_attr) +{ + struct qib_ah *ah; + struct ib_ah *ret; + struct qib_ibdev *dev = to_idev(pd->device); + unsigned long flags; + + if (qib_check_ah(pd->device, ah_attr)) { + ret = ERR_PTR(-EINVAL); + goto bail; + } + + ah = kmalloc(sizeof *ah, GFP_ATOMIC); + if (!ah) { + ret = ERR_PTR(-ENOMEM); + goto bail; + } + + spin_lock_irqsave(&dev->n_ahs_lock, flags); + if (dev->n_ahs_allocated == ib_qib_max_ahs) { + spin_unlock_irqrestore(&dev->n_ahs_lock, flags); + kfree(ah); + ret = ERR_PTR(-ENOMEM); + goto bail; + } + + dev->n_ahs_allocated++; + spin_unlock_irqrestore(&dev->n_ahs_lock, flags); + + /* ib_create_ah() will initialize ah->ibah. */ + ah->attr = *ah_attr; + atomic_set(&ah->refcount, 0); + + ret = &ah->ibah; + +bail: + return ret; +} + +/** + * qib_destroy_ah - destroy an address handle + * @ibah: the AH to destroy + * + * This may be called from interrupt context. + */ +static int qib_destroy_ah(struct ib_ah *ibah) +{ + struct qib_ibdev *dev = to_idev(ibah->device); + struct qib_ah *ah = to_iah(ibah); + unsigned long flags; + + if (atomic_read(&ah->refcount) != 0) + return -EBUSY; + + spin_lock_irqsave(&dev->n_ahs_lock, flags); + dev->n_ahs_allocated--; + spin_unlock_irqrestore(&dev->n_ahs_lock, flags); + + kfree(ah); + + return 0; +} + +static int qib_modify_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr) +{ + struct qib_ah *ah = to_iah(ibah); + + if (qib_check_ah(ibah->device, ah_attr)) + return -EINVAL; + + ah->attr = *ah_attr; + + return 0; +} + +static int qib_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr) +{ + struct qib_ah *ah = to_iah(ibah); + + *ah_attr = ah->attr; + + return 0; +} + +/** + * qib_get_npkeys - return the size of the PKEY table for context 0 + * @dd: the qlogic_ib device + */ +unsigned qib_get_npkeys(struct qib_devdata *dd) +{ + return ARRAY_SIZE(dd->rcd[0]->pkeys); +} + +/* + * Return the indexed PKEY from the port PKEY table. + * No need to validate rcd[ctxt]; the port is setup if we are here. + */ +unsigned qib_get_pkey(struct qib_ibport *ibp, unsigned index) +{ + struct qib_pportdata *ppd = ppd_from_ibp(ibp); + struct qib_devdata *dd = ppd->dd; + unsigned ctxt = ppd->hw_pidx; + unsigned ret; + + /* dd->rcd null if mini_init or some init failures */ + if (!dd->rcd || index >= ARRAY_SIZE(dd->rcd[ctxt]->pkeys)) + ret = 0; + else + ret = dd->rcd[ctxt]->pkeys[index]; + + return ret; +} + +static int qib_query_pkey(struct ib_device *ibdev, u8 port, u16 index, + u16 *pkey) +{ + struct qib_devdata *dd = dd_from_ibdev(ibdev); + int ret; + + if (index >= qib_get_npkeys(dd)) { + ret = -EINVAL; + goto bail; + } + + *pkey = qib_get_pkey(to_iport(ibdev, port), index); + ret = 0; + +bail: + return ret; +} + +/** + * qib_alloc_ucontext - allocate a ucontest + * @ibdev: the infiniband device + * @udata: not used by the QLogic_IB driver + */ + +static struct ib_ucontext *qib_alloc_ucontext(struct ib_device *ibdev, + struct ib_udata *udata) +{ + struct qib_ucontext *context; + struct ib_ucontext *ret; + + context = kmalloc(sizeof *context, GFP_KERNEL); + if (!context) { + ret = ERR_PTR(-ENOMEM); + goto bail; + } + + ret = &context->ibucontext; + +bail: + return ret; +} + +static int qib_dealloc_ucontext(struct ib_ucontext *context) +{ + kfree(to_iucontext(context)); + return 0; +} + +static void init_ibport(struct qib_pportdata *ppd) +{ + struct qib_verbs_counters cntrs; + struct qib_ibport *ibp = &ppd->ibport_data; + + spin_lock_init(&ibp->lock); + /* Set the prefix to the default value (see ch. 4.1.1) */ + ibp->gid_prefix = IB_DEFAULT_GID_PREFIX; + ibp->sm_lid = be16_to_cpu(IB_LID_PERMISSIVE); + ibp->port_cap_flags = IB_PORT_SYS_IMAGE_GUID_SUP | + IB_PORT_CLIENT_REG_SUP | IB_PORT_SL_MAP_SUP | + IB_PORT_TRAP_SUP | IB_PORT_AUTO_MIGR_SUP | + IB_PORT_DR_NOTICE_SUP | IB_PORT_CAP_MASK_NOTICE_SUP | + IB_PORT_OTHER_LOCAL_CHANGES_SUP; + if (ppd->dd->flags & QIB_HAS_LINK_LATENCY) + ibp->port_cap_flags |= IB_PORT_LINK_LATENCY_SUP; + ibp->pma_counter_select[0] = IB_PMA_PORT_XMIT_DATA; + ibp->pma_counter_select[1] = IB_PMA_PORT_RCV_DATA; + ibp->pma_counter_select[2] = IB_PMA_PORT_XMIT_PKTS; + ibp->pma_counter_select[3] = IB_PMA_PORT_RCV_PKTS; + ibp->pma_counter_select[4] = IB_PMA_PORT_XMIT_WAIT; + + /* Snapshot current HW counters to "clear" them. */ + qib_get_counters(ppd, &cntrs); + ibp->z_symbol_error_counter = cntrs.symbol_error_counter; + ibp->z_link_error_recovery_counter = + cntrs.link_error_recovery_counter; + ibp->z_link_downed_counter = cntrs.link_downed_counter; + ibp->z_port_rcv_errors = cntrs.port_rcv_errors; + ibp->z_port_rcv_remphys_errors = cntrs.port_rcv_remphys_errors; + ibp->z_port_xmit_discards = cntrs.port_xmit_discards; + ibp->z_port_xmit_data = cntrs.port_xmit_data; + ibp->z_port_rcv_data = cntrs.port_rcv_data; + ibp->z_port_xmit_packets = cntrs.port_xmit_packets; + ibp->z_port_rcv_packets = cntrs.port_rcv_packets; + ibp->z_local_link_integrity_errors = + cntrs.local_link_integrity_errors; + ibp->z_excessive_buffer_overrun_errors = + cntrs.excessive_buffer_overrun_errors; + ibp->z_vl15_dropped = cntrs.vl15_dropped; +} + +/** + * qib_register_ib_device - register our device with the infiniband core + * @dd: the device data structure + * Return the allocated qib_ibdev pointer or NULL on error. + */ +int qib_register_ib_device(struct qib_devdata *dd) +{ + struct qib_ibdev *dev = &dd->verbs_dev; + struct ib_device *ibdev = &dev->ibdev; + struct qib_pportdata *ppd = dd->pport; + unsigned i, lk_tab_size; + int ret; + + dev->qp_table_size = ib_qib_qp_table_size; + dev->qp_table = kzalloc(dev->qp_table_size * sizeof *dev->qp_table, + GFP_KERNEL); + if (!dev->qp_table) { + ret = -ENOMEM; + goto err_qpt; + } + + for (i = 0; i < dd->num_pports; i++) + init_ibport(ppd + i); + + /* Only need to initialize non-zero fields. */ + spin_lock_init(&dev->qpt_lock); + spin_lock_init(&dev->n_pds_lock); + spin_lock_init(&dev->n_ahs_lock); + spin_lock_init(&dev->n_cqs_lock); + spin_lock_init(&dev->n_qps_lock); + spin_lock_init(&dev->n_srqs_lock); + spin_lock_init(&dev->n_mcast_grps_lock); + init_timer(&dev->mem_timer); + dev->mem_timer.function = mem_timer; + dev->mem_timer.data = (unsigned long) dev; + + qib_init_qpn_table(dd, &dev->qpn_table); + + /* + * The top ib_qib_lkey_table_size bits are used to index the + * table. The lower 8 bits can be owned by the user (copied from + * the LKEY). The remaining bits act as a generation number or tag. + */ + spin_lock_init(&dev->lk_table.lock); + dev->lk_table.max = 1 << ib_qib_lkey_table_size; + lk_tab_size = dev->lk_table.max * sizeof(*dev->lk_table.table); + dev->lk_table.table = (struct qib_mregion **) + __get_free_pages(GFP_KERNEL, get_order(lk_tab_size)); + if (dev->lk_table.table == NULL) { + ret = -ENOMEM; + goto err_lk; + } + memset(dev->lk_table.table, 0, lk_tab_size); + INIT_LIST_HEAD(&dev->pending_mmaps); + spin_lock_init(&dev->pending_lock); + dev->mmap_offset = PAGE_SIZE; + spin_lock_init(&dev->mmap_offset_lock); + INIT_LIST_HEAD(&dev->piowait); + INIT_LIST_HEAD(&dev->dmawait); + INIT_LIST_HEAD(&dev->txwait); + INIT_LIST_HEAD(&dev->memwait); + INIT_LIST_HEAD(&dev->txreq_free); + + if (ppd->sdma_descq_cnt) { + dev->pio_hdrs = dma_alloc_coherent(&dd->pcidev->dev, + ppd->sdma_descq_cnt * + sizeof(struct qib_pio_header), + &dev->pio_hdrs_phys, + GFP_KERNEL); + if (!dev->pio_hdrs) { + ret = -ENOMEM; + goto err_hdrs; + } + } + + for (i = 0; i < ppd->sdma_descq_cnt; i++) { + struct qib_verbs_txreq *tx; + + tx = kzalloc(sizeof *tx, GFP_KERNEL); + if (!tx) { + ret = -ENOMEM; + goto err_tx; + } + tx->hdr_inx = i; + list_add(&tx->txreq.list, &dev->txreq_free); + } + + /* + * The system image GUID is supposed to be the same for all + * IB HCAs in a single system but since there can be other + * device types in the system, we can't be sure this is unique. + */ + if (!ib_qib_sys_image_guid) + ib_qib_sys_image_guid = ppd->guid; + + strlcpy(ibdev->name, "qib%d", IB_DEVICE_NAME_MAX); + ibdev->owner = THIS_MODULE; + ibdev->node_guid = ppd->guid; + ibdev->uverbs_abi_ver = QIB_UVERBS_ABI_VERSION; + ibdev->uverbs_cmd_mask = + (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) | + (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) | + (1ull << IB_USER_VERBS_CMD_QUERY_PORT) | + (1ull << IB_USER_VERBS_CMD_ALLOC_PD) | + (1ull << IB_USER_VERBS_CMD_DEALLOC_PD) | + (1ull << IB_USER_VERBS_CMD_CREATE_AH) | + (1ull << IB_USER_VERBS_CMD_MODIFY_AH) | + (1ull << IB_USER_VERBS_CMD_QUERY_AH) | + (1ull << IB_USER_VERBS_CMD_DESTROY_AH) | + (1ull << IB_USER_VERBS_CMD_REG_MR) | + (1ull << IB_USER_VERBS_CMD_DEREG_MR) | + (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) | + (1ull << IB_USER_VERBS_CMD_CREATE_CQ) | + (1ull << IB_USER_VERBS_CMD_RESIZE_CQ) | + (1ull << IB_USER_VERBS_CMD_DESTROY_CQ) | + (1ull << IB_USER_VERBS_CMD_POLL_CQ) | + (1ull << IB_USER_VERBS_CMD_REQ_NOTIFY_CQ) | + (1ull << IB_USER_VERBS_CMD_CREATE_QP) | + (1ull << IB_USER_VERBS_CMD_QUERY_QP) | + (1ull << IB_USER_VERBS_CMD_MODIFY_QP) | + (1ull << IB_USER_VERBS_CMD_DESTROY_QP) | + (1ull << IB_USER_VERBS_CMD_POST_SEND) | + (1ull << IB_USER_VERBS_CMD_POST_RECV) | + (1ull << IB_USER_VERBS_CMD_ATTACH_MCAST) | + (1ull << IB_USER_VERBS_CMD_DETACH_MCAST) | + (1ull << IB_USER_VERBS_CMD_CREATE_SRQ) | + (1ull << IB_USER_VERBS_CMD_MODIFY_SRQ) | + (1ull << IB_USER_VERBS_CMD_QUERY_SRQ) | + (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ) | + (1ull << IB_USER_VERBS_CMD_POST_SRQ_RECV); + ibdev->node_type = RDMA_NODE_IB_CA; + ibdev->phys_port_cnt = dd->num_pports; + ibdev->num_comp_vectors = 1; + ibdev->dma_device = &dd->pcidev->dev; + ibdev->query_device = qib_query_device; + ibdev->modify_device = qib_modify_device; + ibdev->query_port = qib_query_port; + ibdev->modify_port = qib_modify_port; + ibdev->query_pkey = qib_query_pkey; + ibdev->query_gid = qib_query_gid; + ibdev->alloc_ucontext = qib_alloc_ucontext; + ibdev->dealloc_ucontext = qib_dealloc_ucontext; + ibdev->alloc_pd = qib_alloc_pd; + ibdev->dealloc_pd = qib_dealloc_pd; + ibdev->create_ah = qib_create_ah; + ibdev->destroy_ah = qib_destroy_ah; + ibdev->modify_ah = qib_modify_ah; + ibdev->query_ah = qib_query_ah; + ibdev->create_srq = qib_create_srq; + ibdev->modify_srq = qib_modify_srq; + ibdev->query_srq = qib_query_srq; + ibdev->destroy_srq = qib_destroy_srq; + ibdev->create_qp = qib_create_qp; + ibdev->modify_qp = qib_modify_qp; + ibdev->query_qp = qib_query_qp; + ibdev->destroy_qp = qib_destroy_qp; + ibdev->post_send = qib_post_send; + ibdev->post_recv = qib_post_receive; + ibdev->post_srq_recv = qib_post_srq_receive; + ibdev->create_cq = qib_create_cq; + ibdev->destroy_cq = qib_destroy_cq; + ibdev->resize_cq = qib_resize_cq; + ibdev->poll_cq = qib_poll_cq; + ibdev->req_notify_cq = qib_req_notify_cq; + ibdev->get_dma_mr = qib_get_dma_mr; + ibdev->reg_phys_mr = qib_reg_phys_mr; + ibdev->reg_user_mr = qib_reg_user_mr; + ibdev->dereg_mr = qib_dereg_mr; + ibdev->alloc_fast_reg_mr = qib_alloc_fast_reg_mr; + ibdev->alloc_fast_reg_page_list = qib_alloc_fast_reg_page_list; + ibdev->free_fast_reg_page_list = qib_free_fast_reg_page_list; + ibdev->alloc_fmr = qib_alloc_fmr; + ibdev->map_phys_fmr = qib_map_phys_fmr; + ibdev->unmap_fmr = qib_unmap_fmr; + ibdev->dealloc_fmr = qib_dealloc_fmr; + ibdev->attach_mcast = qib_multicast_attach; + ibdev->detach_mcast = qib_multicast_detach; + ibdev->process_mad = qib_process_mad; + ibdev->mmap = qib_mmap; + ibdev->dma_ops = &qib_dma_mapping_ops; + + snprintf(ibdev->node_desc, sizeof(ibdev->node_desc), + QIB_IDSTR " %s", init_utsname()->nodename); + + ret = ib_register_device(ibdev, qib_create_port_files); + if (ret) + goto err_reg; + + ret = qib_create_agents(dev); + if (ret) + goto err_agents; + + if (qib_verbs_register_sysfs(dd)) + goto err_class; + + goto bail; + +err_class: + qib_free_agents(dev); +err_agents: + ib_unregister_device(ibdev); +err_reg: +err_tx: + while (!list_empty(&dev->txreq_free)) { + struct list_head *l = dev->txreq_free.next; + struct qib_verbs_txreq *tx; + + list_del(l); + tx = list_entry(l, struct qib_verbs_txreq, txreq.list); + kfree(tx); + } + if (ppd->sdma_descq_cnt) + dma_free_coherent(&dd->pcidev->dev, + ppd->sdma_descq_cnt * + sizeof(struct qib_pio_header), + dev->pio_hdrs, dev->pio_hdrs_phys); +err_hdrs: + free_pages((unsigned long) dev->lk_table.table, get_order(lk_tab_size)); +err_lk: + kfree(dev->qp_table); +err_qpt: + qib_dev_err(dd, "cannot register verbs: %d!\n", -ret); +bail: + return ret; +} + +void qib_unregister_ib_device(struct qib_devdata *dd) +{ + struct qib_ibdev *dev = &dd->verbs_dev; + struct ib_device *ibdev = &dev->ibdev; + u32 qps_inuse; + unsigned lk_tab_size; + + qib_verbs_unregister_sysfs(dd); + + qib_free_agents(dev); + + ib_unregister_device(ibdev); + + if (!list_empty(&dev->piowait)) + qib_dev_err(dd, "piowait list not empty!\n"); + if (!list_empty(&dev->dmawait)) + qib_dev_err(dd, "dmawait list not empty!\n"); + if (!list_empty(&dev->txwait)) + qib_dev_err(dd, "txwait list not empty!\n"); + if (!list_empty(&dev->memwait)) + qib_dev_err(dd, "memwait list not empty!\n"); + if (dev->dma_mr) + qib_dev_err(dd, "DMA MR not NULL!\n"); + + qps_inuse = qib_free_all_qps(dd); + if (qps_inuse) + qib_dev_err(dd, "QP memory leak! %u still in use\n", + qps_inuse); + + del_timer_sync(&dev->mem_timer); + qib_free_qpn_table(&dev->qpn_table); + while (!list_empty(&dev->txreq_free)) { + struct list_head *l = dev->txreq_free.next; + struct qib_verbs_txreq *tx; + + list_del(l); + tx = list_entry(l, struct qib_verbs_txreq, txreq.list); + kfree(tx); + } + if (dd->pport->sdma_descq_cnt) + dma_free_coherent(&dd->pcidev->dev, + dd->pport->sdma_descq_cnt * + sizeof(struct qib_pio_header), + dev->pio_hdrs, dev->pio_hdrs_phys); + lk_tab_size = dev->lk_table.max * sizeof(*dev->lk_table.table); + free_pages((unsigned long) dev->lk_table.table, + get_order(lk_tab_size)); + kfree(dev->qp_table); +} diff --git a/drivers/infiniband/hw/qib/qib_verbs.h b/drivers/infiniband/hw/qib/qib_verbs.h new file mode 100644 index 000000000000..bd57c1273225 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_verbs.h @@ -0,0 +1,1100 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation. + * All rights reserved. + * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef QIB_VERBS_H +#define QIB_VERBS_H + +#include +#include +#include +#include +#include +#include +#include +#include + +struct qib_ctxtdata; +struct qib_pportdata; +struct qib_devdata; +struct qib_verbs_txreq; + +#define QIB_MAX_RDMA_ATOMIC 16 +#define QIB_GUIDS_PER_PORT 5 + +#define QPN_MAX (1 << 24) +#define QPNMAP_ENTRIES (QPN_MAX / PAGE_SIZE / BITS_PER_BYTE) + +/* + * Increment this value if any changes that break userspace ABI + * compatibility are made. + */ +#define QIB_UVERBS_ABI_VERSION 2 + +/* + * Define an ib_cq_notify value that is not valid so we know when CQ + * notifications are armed. + */ +#define IB_CQ_NONE (IB_CQ_NEXT_COMP + 1) + +#define IB_SEQ_NAK (3 << 29) + +/* AETH NAK opcode values */ +#define IB_RNR_NAK 0x20 +#define IB_NAK_PSN_ERROR 0x60 +#define IB_NAK_INVALID_REQUEST 0x61 +#define IB_NAK_REMOTE_ACCESS_ERROR 0x62 +#define IB_NAK_REMOTE_OPERATIONAL_ERROR 0x63 +#define IB_NAK_INVALID_RD_REQUEST 0x64 + +/* Flags for checking QP state (see ib_qib_state_ops[]) */ +#define QIB_POST_SEND_OK 0x01 +#define QIB_POST_RECV_OK 0x02 +#define QIB_PROCESS_RECV_OK 0x04 +#define QIB_PROCESS_SEND_OK 0x08 +#define QIB_PROCESS_NEXT_SEND_OK 0x10 +#define QIB_FLUSH_SEND 0x20 +#define QIB_FLUSH_RECV 0x40 +#define QIB_PROCESS_OR_FLUSH_SEND \ + (QIB_PROCESS_SEND_OK | QIB_FLUSH_SEND) + +/* IB Performance Manager status values */ +#define IB_PMA_SAMPLE_STATUS_DONE 0x00 +#define IB_PMA_SAMPLE_STATUS_STARTED 0x01 +#define IB_PMA_SAMPLE_STATUS_RUNNING 0x02 + +/* Mandatory IB performance counter select values. */ +#define IB_PMA_PORT_XMIT_DATA cpu_to_be16(0x0001) +#define IB_PMA_PORT_RCV_DATA cpu_to_be16(0x0002) +#define IB_PMA_PORT_XMIT_PKTS cpu_to_be16(0x0003) +#define IB_PMA_PORT_RCV_PKTS cpu_to_be16(0x0004) +#define IB_PMA_PORT_XMIT_WAIT cpu_to_be16(0x0005) + +#define QIB_VENDOR_IPG cpu_to_be16(0xFFA0) + +#define IB_BTH_REQ_ACK (1 << 31) +#define IB_BTH_SOLICITED (1 << 23) +#define IB_BTH_MIG_REQ (1 << 22) + +/* XXX Should be defined in ib_verbs.h enum ib_port_cap_flags */ +#define IB_PORT_OTHER_LOCAL_CHANGES_SUP (1 << 26) + +#define IB_GRH_VERSION 6 +#define IB_GRH_VERSION_MASK 0xF +#define IB_GRH_VERSION_SHIFT 28 +#define IB_GRH_TCLASS_MASK 0xFF +#define IB_GRH_TCLASS_SHIFT 20 +#define IB_GRH_FLOW_MASK 0xFFFFF +#define IB_GRH_FLOW_SHIFT 0 +#define IB_GRH_NEXT_HDR 0x1B + +#define IB_DEFAULT_GID_PREFIX cpu_to_be64(0xfe80000000000000ULL) + +/* Values for set/get portinfo VLCap OperationalVLs */ +#define IB_VL_VL0 1 +#define IB_VL_VL0_1 2 +#define IB_VL_VL0_3 3 +#define IB_VL_VL0_7 4 +#define IB_VL_VL0_14 5 + +static inline int qib_num_vls(int vls) +{ + switch (vls) { + default: + case IB_VL_VL0: + return 1; + case IB_VL_VL0_1: + return 2; + case IB_VL_VL0_3: + return 4; + case IB_VL_VL0_7: + return 8; + case IB_VL_VL0_14: + return 15; + } +} + +struct ib_reth { + __be64 vaddr; + __be32 rkey; + __be32 length; +} __attribute__ ((packed)); + +struct ib_atomic_eth { + __be32 vaddr[2]; /* unaligned so access as 2 32-bit words */ + __be32 rkey; + __be64 swap_data; + __be64 compare_data; +} __attribute__ ((packed)); + +struct qib_other_headers { + __be32 bth[3]; + union { + struct { + __be32 deth[2]; + __be32 imm_data; + } ud; + struct { + struct ib_reth reth; + __be32 imm_data; + } rc; + struct { + __be32 aeth; + __be32 atomic_ack_eth[2]; + } at; + __be32 imm_data; + __be32 aeth; + struct ib_atomic_eth atomic_eth; + } u; +} __attribute__ ((packed)); + +/* + * Note that UD packets with a GRH header are 8+40+12+8 = 68 bytes + * long (72 w/ imm_data). Only the first 56 bytes of the IB header + * will be in the eager header buffer. The remaining 12 or 16 bytes + * are in the data buffer. + */ +struct qib_ib_header { + __be16 lrh[4]; + union { + struct { + struct ib_grh grh; + struct qib_other_headers oth; + } l; + struct qib_other_headers oth; + } u; +} __attribute__ ((packed)); + +struct qib_pio_header { + __le32 pbc[2]; + struct qib_ib_header hdr; +} __attribute__ ((packed)); + +/* + * There is one struct qib_mcast for each multicast GID. + * All attached QPs are then stored as a list of + * struct qib_mcast_qp. + */ +struct qib_mcast_qp { + struct list_head list; + struct qib_qp *qp; +}; + +struct qib_mcast { + struct rb_node rb_node; + union ib_gid mgid; + struct list_head qp_list; + wait_queue_head_t wait; + atomic_t refcount; + int n_attached; +}; + +/* Protection domain */ +struct qib_pd { + struct ib_pd ibpd; + int user; /* non-zero if created from user space */ +}; + +/* Address Handle */ +struct qib_ah { + struct ib_ah ibah; + struct ib_ah_attr attr; + atomic_t refcount; +}; + +/* + * This structure is used by qib_mmap() to validate an offset + * when an mmap() request is made. The vm_area_struct then uses + * this as its vm_private_data. + */ +struct qib_mmap_info { + struct list_head pending_mmaps; + struct ib_ucontext *context; + void *obj; + __u64 offset; + struct kref ref; + unsigned size; +}; + +/* + * This structure is used to contain the head pointer, tail pointer, + * and completion queue entries as a single memory allocation so + * it can be mmap'ed into user space. + */ +struct qib_cq_wc { + u32 head; /* index of next entry to fill */ + u32 tail; /* index of next ib_poll_cq() entry */ + union { + /* these are actually size ibcq.cqe + 1 */ + struct ib_uverbs_wc uqueue[0]; + struct ib_wc kqueue[0]; + }; +}; + +/* + * The completion queue structure. + */ +struct qib_cq { + struct ib_cq ibcq; + struct work_struct comptask; + spinlock_t lock; /* protect changes in this struct */ + u8 notify; + u8 triggered; + struct qib_cq_wc *queue; + struct qib_mmap_info *ip; +}; + +/* + * A segment is a linear region of low physical memory. + * XXX Maybe we should use phys addr here and kmap()/kunmap(). + * Used by the verbs layer. + */ +struct qib_seg { + void *vaddr; + size_t length; +}; + +/* The number of qib_segs that fit in a page. */ +#define QIB_SEGSZ (PAGE_SIZE / sizeof(struct qib_seg)) + +struct qib_segarray { + struct qib_seg segs[QIB_SEGSZ]; +}; + +struct qib_mregion { + struct ib_pd *pd; /* shares refcnt of ibmr.pd */ + u64 user_base; /* User's address for this region */ + u64 iova; /* IB start address of this region */ + size_t length; + u32 lkey; + u32 offset; /* offset (bytes) to start of region */ + int access_flags; + u32 max_segs; /* number of qib_segs in all the arrays */ + u32 mapsz; /* size of the map array */ + atomic_t refcount; + struct qib_segarray *map[0]; /* the segments */ +}; + +/* + * These keep track of the copy progress within a memory region. + * Used by the verbs layer. + */ +struct qib_sge { + struct qib_mregion *mr; + void *vaddr; /* kernel virtual address of segment */ + u32 sge_length; /* length of the SGE */ + u32 length; /* remaining length of the segment */ + u16 m; /* current index: mr->map[m] */ + u16 n; /* current index: mr->map[m]->segs[n] */ +}; + +/* Memory region */ +struct qib_mr { + struct ib_mr ibmr; + struct ib_umem *umem; + struct qib_mregion mr; /* must be last */ +}; + +/* + * Send work request queue entry. + * The size of the sg_list is determined when the QP is created and stored + * in qp->s_max_sge. + */ +struct qib_swqe { + struct ib_send_wr wr; /* don't use wr.sg_list */ + u32 psn; /* first packet sequence number */ + u32 lpsn; /* last packet sequence number */ + u32 ssn; /* send sequence number */ + u32 length; /* total length of data in sg_list */ + struct qib_sge sg_list[0]; +}; + +/* + * Receive work request queue entry. + * The size of the sg_list is determined when the QP (or SRQ) is created + * and stored in qp->r_rq.max_sge (or srq->rq.max_sge). + */ +struct qib_rwqe { + u64 wr_id; + u8 num_sge; + struct ib_sge sg_list[0]; +}; + +/* + * This structure is used to contain the head pointer, tail pointer, + * and receive work queue entries as a single memory allocation so + * it can be mmap'ed into user space. + * Note that the wq array elements are variable size so you can't + * just index into the array to get the N'th element; + * use get_rwqe_ptr() instead. + */ +struct qib_rwq { + u32 head; /* new work requests posted to the head */ + u32 tail; /* receives pull requests from here. */ + struct qib_rwqe wq[0]; +}; + +struct qib_rq { + struct qib_rwq *wq; + spinlock_t lock; /* protect changes in this struct */ + u32 size; /* size of RWQE array */ + u8 max_sge; +}; + +struct qib_srq { + struct ib_srq ibsrq; + struct qib_rq rq; + struct qib_mmap_info *ip; + /* send signal when number of RWQEs < limit */ + u32 limit; +}; + +struct qib_sge_state { + struct qib_sge *sg_list; /* next SGE to be used if any */ + struct qib_sge sge; /* progress state for the current SGE */ + u32 total_len; + u8 num_sge; +}; + +/* + * This structure holds the information that the send tasklet needs + * to send a RDMA read response or atomic operation. + */ +struct qib_ack_entry { + u8 opcode; + u8 sent; + u32 psn; + u32 lpsn; + union { + struct qib_sge rdma_sge; + u64 atomic_data; + }; +}; + +/* + * Variables prefixed with s_ are for the requester (sender). + * Variables prefixed with r_ are for the responder (receiver). + * Variables prefixed with ack_ are for responder replies. + * + * Common variables are protected by both r_rq.lock and s_lock in that order + * which only happens in modify_qp() or changing the QP 'state'. + */ +struct qib_qp { + struct ib_qp ibqp; + struct qib_qp *next; /* link list for QPN hash table */ + struct qib_qp *timer_next; /* link list for qib_ib_timer() */ + struct list_head iowait; /* link for wait PIO buf */ + struct list_head rspwait; /* link for waititing to respond */ + struct ib_ah_attr remote_ah_attr; + struct ib_ah_attr alt_ah_attr; + struct qib_ib_header s_hdr; /* next packet header to send */ + atomic_t refcount; + wait_queue_head_t wait; + wait_queue_head_t wait_dma; + struct timer_list s_timer; + struct work_struct s_work; + struct qib_mmap_info *ip; + struct qib_sge_state *s_cur_sge; + struct qib_verbs_txreq *s_tx; + struct qib_mregion *s_rdma_mr; + struct qib_sge_state s_sge; /* current send request data */ + struct qib_ack_entry s_ack_queue[QIB_MAX_RDMA_ATOMIC + 1]; + struct qib_sge_state s_ack_rdma_sge; + struct qib_sge_state s_rdma_read_sge; + struct qib_sge_state r_sge; /* current receive data */ + spinlock_t r_lock; /* used for APM */ + spinlock_t s_lock; + atomic_t s_dma_busy; + unsigned processor_id; /* Processor ID QP is bound to */ + u32 s_flags; + u32 s_cur_size; /* size of send packet in bytes */ + u32 s_len; /* total length of s_sge */ + u32 s_rdma_read_len; /* total length of s_rdma_read_sge */ + u32 s_next_psn; /* PSN for next request */ + u32 s_last_psn; /* last response PSN processed */ + u32 s_sending_psn; /* lowest PSN that is being sent */ + u32 s_sending_hpsn; /* highest PSN that is being sent */ + u32 s_psn; /* current packet sequence number */ + u32 s_ack_rdma_psn; /* PSN for sending RDMA read responses */ + u32 s_ack_psn; /* PSN for acking sends and RDMA writes */ + u32 s_rnr_timeout; /* number of milliseconds for RNR timeout */ + u32 r_ack_psn; /* PSN for next ACK or atomic ACK */ + u64 r_wr_id; /* ID for current receive WQE */ + unsigned long r_aflags; + u32 r_len; /* total length of r_sge */ + u32 r_rcv_len; /* receive data len processed */ + u32 r_psn; /* expected rcv packet sequence number */ + u32 r_msn; /* message sequence number */ + u16 s_hdrwords; /* size of s_hdr in 32 bit words */ + u16 s_rdma_ack_cnt; + u8 state; /* QP state */ + u8 s_state; /* opcode of last packet sent */ + u8 s_ack_state; /* opcode of packet to ACK */ + u8 s_nak_state; /* non-zero if NAK is pending */ + u8 r_state; /* opcode of last packet received */ + u8 r_nak_state; /* non-zero if NAK is pending */ + u8 r_min_rnr_timer; /* retry timeout value for RNR NAKs */ + u8 r_flags; + u8 r_max_rd_atomic; /* max number of RDMA read/atomic to receive */ + u8 r_head_ack_queue; /* index into s_ack_queue[] */ + u8 qp_access_flags; + u8 s_max_sge; /* size of s_wq->sg_list */ + u8 s_retry_cnt; /* number of times to retry */ + u8 s_rnr_retry_cnt; + u8 s_retry; /* requester retry counter */ + u8 s_rnr_retry; /* requester RNR retry counter */ + u8 s_pkey_index; /* PKEY index to use */ + u8 s_alt_pkey_index; /* Alternate path PKEY index to use */ + u8 s_max_rd_atomic; /* max number of RDMA read/atomic to send */ + u8 s_num_rd_atomic; /* number of RDMA read/atomic pending */ + u8 s_tail_ack_queue; /* index into s_ack_queue[] */ + u8 s_srate; + u8 s_draining; + u8 s_mig_state; + u8 timeout; /* Timeout for this QP */ + u8 alt_timeout; /* Alternate path timeout for this QP */ + u8 port_num; + enum ib_mtu path_mtu; + u32 remote_qpn; + u32 qkey; /* QKEY for this QP (for UD or RD) */ + u32 s_size; /* send work queue size */ + u32 s_head; /* new entries added here */ + u32 s_tail; /* next entry to process */ + u32 s_cur; /* current work queue entry */ + u32 s_acked; /* last un-ACK'ed entry */ + u32 s_last; /* last completed entry */ + u32 s_ssn; /* SSN of tail entry */ + u32 s_lsn; /* limit sequence number (credit) */ + struct qib_swqe *s_wq; /* send work queue */ + struct qib_swqe *s_wqe; + struct qib_rq r_rq; /* receive work queue */ + struct qib_sge r_sg_list[0]; /* verified SGEs */ +}; + +/* + * Atomic bit definitions for r_aflags. + */ +#define QIB_R_WRID_VALID 0 +#define QIB_R_REWIND_SGE 1 + +/* + * Bit definitions for r_flags. + */ +#define QIB_R_REUSE_SGE 0x01 +#define QIB_R_RDMAR_SEQ 0x02 +#define QIB_R_RSP_NAK 0x04 +#define QIB_R_RSP_SEND 0x08 +#define QIB_R_COMM_EST 0x10 + +/* + * Bit definitions for s_flags. + * + * QIB_S_SIGNAL_REQ_WR - set if QP send WRs contain completion signaled + * QIB_S_BUSY - send tasklet is processing the QP + * QIB_S_TIMER - the RC retry timer is active + * QIB_S_ACK_PENDING - an ACK is waiting to be sent after RDMA read/atomics + * QIB_S_WAIT_FENCE - waiting for all prior RDMA read or atomic SWQEs + * before processing the next SWQE + * QIB_S_WAIT_RDMAR - waiting for a RDMA read or atomic SWQE to complete + * before processing the next SWQE + * QIB_S_WAIT_RNR - waiting for RNR timeout + * QIB_S_WAIT_SSN_CREDIT - waiting for RC credits to process next SWQE + * QIB_S_WAIT_DMA - waiting for send DMA queue to drain before generating + * next send completion entry not via send DMA + * QIB_S_WAIT_PIO - waiting for a send buffer to be available + * QIB_S_WAIT_TX - waiting for a struct qib_verbs_txreq to be available + * QIB_S_WAIT_DMA_DESC - waiting for DMA descriptors to be available + * QIB_S_WAIT_KMEM - waiting for kernel memory to be available + * QIB_S_WAIT_PSN - waiting for a packet to exit the send DMA queue + * QIB_S_WAIT_ACK - waiting for an ACK packet before sending more requests + * QIB_S_SEND_ONE - send one packet, request ACK, then wait for ACK + */ +#define QIB_S_SIGNAL_REQ_WR 0x0001 +#define QIB_S_BUSY 0x0002 +#define QIB_S_TIMER 0x0004 +#define QIB_S_RESP_PENDING 0x0008 +#define QIB_S_ACK_PENDING 0x0010 +#define QIB_S_WAIT_FENCE 0x0020 +#define QIB_S_WAIT_RDMAR 0x0040 +#define QIB_S_WAIT_RNR 0x0080 +#define QIB_S_WAIT_SSN_CREDIT 0x0100 +#define QIB_S_WAIT_DMA 0x0200 +#define QIB_S_WAIT_PIO 0x0400 +#define QIB_S_WAIT_TX 0x0800 +#define QIB_S_WAIT_DMA_DESC 0x1000 +#define QIB_S_WAIT_KMEM 0x2000 +#define QIB_S_WAIT_PSN 0x4000 +#define QIB_S_WAIT_ACK 0x8000 +#define QIB_S_SEND_ONE 0x10000 +#define QIB_S_UNLIMITED_CREDIT 0x20000 + +/* + * Wait flags that would prevent any packet type from being sent. + */ +#define QIB_S_ANY_WAIT_IO (QIB_S_WAIT_PIO | QIB_S_WAIT_TX | \ + QIB_S_WAIT_DMA_DESC | QIB_S_WAIT_KMEM) + +/* + * Wait flags that would prevent send work requests from making progress. + */ +#define QIB_S_ANY_WAIT_SEND (QIB_S_WAIT_FENCE | QIB_S_WAIT_RDMAR | \ + QIB_S_WAIT_RNR | QIB_S_WAIT_SSN_CREDIT | QIB_S_WAIT_DMA | \ + QIB_S_WAIT_PSN | QIB_S_WAIT_ACK) + +#define QIB_S_ANY_WAIT (QIB_S_ANY_WAIT_IO | QIB_S_ANY_WAIT_SEND) + +#define QIB_PSN_CREDIT 16 + +/* + * Since struct qib_swqe is not a fixed size, we can't simply index into + * struct qib_qp.s_wq. This function does the array index computation. + */ +static inline struct qib_swqe *get_swqe_ptr(struct qib_qp *qp, + unsigned n) +{ + return (struct qib_swqe *)((char *)qp->s_wq + + (sizeof(struct qib_swqe) + + qp->s_max_sge * + sizeof(struct qib_sge)) * n); +} + +/* + * Since struct qib_rwqe is not a fixed size, we can't simply index into + * struct qib_rwq.wq. This function does the array index computation. + */ +static inline struct qib_rwqe *get_rwqe_ptr(struct qib_rq *rq, unsigned n) +{ + return (struct qib_rwqe *) + ((char *) rq->wq->wq + + (sizeof(struct qib_rwqe) + + rq->max_sge * sizeof(struct ib_sge)) * n); +} + +/* + * QPN-map pages start out as NULL, they get allocated upon + * first use and are never deallocated. This way, + * large bitmaps are not allocated unless large numbers of QPs are used. + */ +struct qpn_map { + void *page; +}; + +struct qib_qpn_table { + spinlock_t lock; /* protect changes in this struct */ + unsigned flags; /* flags for QP0/1 allocated for each port */ + u32 last; /* last QP number allocated */ + u32 nmaps; /* size of the map table */ + u16 limit; + u16 mask; + /* bit map of free QP numbers other than 0/1 */ + struct qpn_map map[QPNMAP_ENTRIES]; +}; + +struct qib_lkey_table { + spinlock_t lock; /* protect changes in this struct */ + u32 next; /* next unused index (speeds search) */ + u32 gen; /* generation count */ + u32 max; /* size of the table */ + struct qib_mregion **table; +}; + +struct qib_opcode_stats { + u64 n_packets; /* number of packets */ + u64 n_bytes; /* total number of bytes */ +}; + +struct qib_ibport { + struct qib_qp *qp0; + struct qib_qp *qp1; + struct ib_mad_agent *send_agent; /* agent for SMI (traps) */ + struct qib_ah *sm_ah; + struct qib_ah *smi_ah; + struct rb_root mcast_tree; + spinlock_t lock; /* protect changes in this struct */ + + /* non-zero when timer is set */ + unsigned long mkey_lease_timeout; + unsigned long trap_timeout; + __be64 gid_prefix; /* in network order */ + __be64 mkey; + __be64 guids[QIB_GUIDS_PER_PORT - 1]; /* writable GUIDs */ + u64 tid; /* TID for traps */ + u64 n_unicast_xmit; /* total unicast packets sent */ + u64 n_unicast_rcv; /* total unicast packets received */ + u64 n_multicast_xmit; /* total multicast packets sent */ + u64 n_multicast_rcv; /* total multicast packets received */ + u64 z_symbol_error_counter; /* starting count for PMA */ + u64 z_link_error_recovery_counter; /* starting count for PMA */ + u64 z_link_downed_counter; /* starting count for PMA */ + u64 z_port_rcv_errors; /* starting count for PMA */ + u64 z_port_rcv_remphys_errors; /* starting count for PMA */ + u64 z_port_xmit_discards; /* starting count for PMA */ + u64 z_port_xmit_data; /* starting count for PMA */ + u64 z_port_rcv_data; /* starting count for PMA */ + u64 z_port_xmit_packets; /* starting count for PMA */ + u64 z_port_rcv_packets; /* starting count for PMA */ + u32 z_local_link_integrity_errors; /* starting count for PMA */ + u32 z_excessive_buffer_overrun_errors; /* starting count for PMA */ + u32 z_vl15_dropped; /* starting count for PMA */ + u32 n_rc_resends; + u32 n_rc_acks; + u32 n_rc_qacks; + u32 n_rc_delayed_comp; + u32 n_seq_naks; + u32 n_rdma_seq; + u32 n_rnr_naks; + u32 n_other_naks; + u32 n_loop_pkts; + u32 n_pkt_drops; + u32 n_vl15_dropped; + u32 n_rc_timeouts; + u32 n_dmawait; + u32 n_unaligned; + u32 n_rc_dupreq; + u32 n_rc_seqnak; + u32 port_cap_flags; + u32 pma_sample_start; + u32 pma_sample_interval; + __be16 pma_counter_select[5]; + u16 pma_tag; + u16 pkey_violations; + u16 qkey_violations; + u16 mkey_violations; + u16 mkey_lease_period; + u16 sm_lid; + u16 repress_traps; + u8 sm_sl; + u8 mkeyprot; + u8 subnet_timeout; + u8 vl_high_limit; + u8 sl_to_vl[16]; + + struct qib_opcode_stats opstats[128]; +}; + +struct qib_ibdev { + struct ib_device ibdev; + struct list_head pending_mmaps; + spinlock_t mmap_offset_lock; /* protect mmap_offset */ + u32 mmap_offset; + struct qib_mregion *dma_mr; + + /* QP numbers are shared by all IB ports */ + struct qib_qpn_table qpn_table; + struct qib_lkey_table lk_table; + struct list_head piowait; /* list for wait PIO buf */ + struct list_head dmawait; /* list for wait DMA */ + struct list_head txwait; /* list for wait qib_verbs_txreq */ + struct list_head memwait; /* list for wait kernel memory */ + struct list_head txreq_free; + struct timer_list mem_timer; + struct qib_qp **qp_table; + struct qib_pio_header *pio_hdrs; + dma_addr_t pio_hdrs_phys; + /* list of QPs waiting for RNR timer */ + spinlock_t pending_lock; /* protect wait lists, PMA counters, etc. */ + unsigned qp_table_size; /* size of the hash table */ + spinlock_t qpt_lock; + + u32 n_piowait; + u32 n_txwait; + + u32 n_pds_allocated; /* number of PDs allocated for device */ + spinlock_t n_pds_lock; + u32 n_ahs_allocated; /* number of AHs allocated for device */ + spinlock_t n_ahs_lock; + u32 n_cqs_allocated; /* number of CQs allocated for device */ + spinlock_t n_cqs_lock; + u32 n_qps_allocated; /* number of QPs allocated for device */ + spinlock_t n_qps_lock; + u32 n_srqs_allocated; /* number of SRQs allocated for device */ + spinlock_t n_srqs_lock; + u32 n_mcast_grps_allocated; /* number of mcast groups allocated */ + spinlock_t n_mcast_grps_lock; +}; + +struct qib_verbs_counters { + u64 symbol_error_counter; + u64 link_error_recovery_counter; + u64 link_downed_counter; + u64 port_rcv_errors; + u64 port_rcv_remphys_errors; + u64 port_xmit_discards; + u64 port_xmit_data; + u64 port_rcv_data; + u64 port_xmit_packets; + u64 port_rcv_packets; + u32 local_link_integrity_errors; + u32 excessive_buffer_overrun_errors; + u32 vl15_dropped; +}; + +static inline struct qib_mr *to_imr(struct ib_mr *ibmr) +{ + return container_of(ibmr, struct qib_mr, ibmr); +} + +static inline struct qib_pd *to_ipd(struct ib_pd *ibpd) +{ + return container_of(ibpd, struct qib_pd, ibpd); +} + +static inline struct qib_ah *to_iah(struct ib_ah *ibah) +{ + return container_of(ibah, struct qib_ah, ibah); +} + +static inline struct qib_cq *to_icq(struct ib_cq *ibcq) +{ + return container_of(ibcq, struct qib_cq, ibcq); +} + +static inline struct qib_srq *to_isrq(struct ib_srq *ibsrq) +{ + return container_of(ibsrq, struct qib_srq, ibsrq); +} + +static inline struct qib_qp *to_iqp(struct ib_qp *ibqp) +{ + return container_of(ibqp, struct qib_qp, ibqp); +} + +static inline struct qib_ibdev *to_idev(struct ib_device *ibdev) +{ + return container_of(ibdev, struct qib_ibdev, ibdev); +} + +/* + * Send if not busy or waiting for I/O and either + * a RC response is pending or we can process send work requests. + */ +static inline int qib_send_ok(struct qib_qp *qp) +{ + return !(qp->s_flags & (QIB_S_BUSY | QIB_S_ANY_WAIT_IO)) && + (qp->s_hdrwords || (qp->s_flags & QIB_S_RESP_PENDING) || + !(qp->s_flags & QIB_S_ANY_WAIT_SEND)); +} + +extern struct workqueue_struct *qib_wq; +extern struct workqueue_struct *qib_cq_wq; + +/* + * This must be called with s_lock held. + */ +static inline void qib_schedule_send(struct qib_qp *qp) +{ + if (qib_send_ok(qp)) { + if (qp->processor_id == smp_processor_id()) + queue_work(qib_wq, &qp->s_work); + else + queue_work_on(qp->processor_id, + qib_wq, &qp->s_work); + } +} + +static inline int qib_pkey_ok(u16 pkey1, u16 pkey2) +{ + u16 p1 = pkey1 & 0x7FFF; + u16 p2 = pkey2 & 0x7FFF; + + /* + * Low 15 bits must be non-zero and match, and + * one of the two must be a full member. + */ + return p1 && p1 == p2 && ((__s16)pkey1 < 0 || (__s16)pkey2 < 0); +} + +void qib_bad_pqkey(struct qib_ibport *ibp, __be16 trap_num, u32 key, u32 sl, + u32 qp1, u32 qp2, __be16 lid1, __be16 lid2); +void qib_cap_mask_chg(struct qib_ibport *ibp); +void qib_sys_guid_chg(struct qib_ibport *ibp); +void qib_node_desc_chg(struct qib_ibport *ibp); +int qib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, + struct ib_wc *in_wc, struct ib_grh *in_grh, + struct ib_mad *in_mad, struct ib_mad *out_mad); +int qib_create_agents(struct qib_ibdev *dev); +void qib_free_agents(struct qib_ibdev *dev); + +/* + * Compare the lower 24 bits of the two values. + * Returns an integer <, ==, or > than zero. + */ +static inline int qib_cmp24(u32 a, u32 b) +{ + return (((int) a) - ((int) b)) << 8; +} + +struct qib_mcast *qib_mcast_find(struct qib_ibport *ibp, union ib_gid *mgid); + +int qib_snapshot_counters(struct qib_pportdata *ppd, u64 *swords, + u64 *rwords, u64 *spkts, u64 *rpkts, + u64 *xmit_wait); + +int qib_get_counters(struct qib_pportdata *ppd, + struct qib_verbs_counters *cntrs); + +int qib_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid); + +int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid); + +int qib_mcast_tree_empty(struct qib_ibport *ibp); + +__be32 qib_compute_aeth(struct qib_qp *qp); + +struct qib_qp *qib_lookup_qpn(struct qib_ibport *ibp, u32 qpn); + +struct ib_qp *qib_create_qp(struct ib_pd *ibpd, + struct ib_qp_init_attr *init_attr, + struct ib_udata *udata); + +int qib_destroy_qp(struct ib_qp *ibqp); + +int qib_error_qp(struct qib_qp *qp, enum ib_wc_status err); + +int qib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, + int attr_mask, struct ib_udata *udata); + +int qib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, + int attr_mask, struct ib_qp_init_attr *init_attr); + +unsigned qib_free_all_qps(struct qib_devdata *dd); + +void qib_init_qpn_table(struct qib_devdata *dd, struct qib_qpn_table *qpt); + +void qib_free_qpn_table(struct qib_qpn_table *qpt); + +void qib_get_credit(struct qib_qp *qp, u32 aeth); + +unsigned qib_pkt_delay(u32 plen, u8 snd_mult, u8 rcv_mult); + +void qib_verbs_sdma_desc_avail(struct qib_pportdata *ppd, unsigned avail); + +void qib_put_txreq(struct qib_verbs_txreq *tx); + +int qib_verbs_send(struct qib_qp *qp, struct qib_ib_header *hdr, + u32 hdrwords, struct qib_sge_state *ss, u32 len); + +void qib_copy_sge(struct qib_sge_state *ss, void *data, u32 length, + int release); + +void qib_skip_sge(struct qib_sge_state *ss, u32 length, int release); + +void qib_uc_rcv(struct qib_ibport *ibp, struct qib_ib_header *hdr, + int has_grh, void *data, u32 tlen, struct qib_qp *qp); + +void qib_rc_rcv(struct qib_ctxtdata *rcd, struct qib_ib_header *hdr, + int has_grh, void *data, u32 tlen, struct qib_qp *qp); + +int qib_check_ah(struct ib_device *ibdev, struct ib_ah_attr *ah_attr); + +void qib_rc_rnr_retry(unsigned long arg); + +void qib_rc_send_complete(struct qib_qp *qp, struct qib_ib_header *hdr); + +void qib_rc_error(struct qib_qp *qp, enum ib_wc_status err); + +int qib_post_ud_send(struct qib_qp *qp, struct ib_send_wr *wr); + +void qib_ud_rcv(struct qib_ibport *ibp, struct qib_ib_header *hdr, + int has_grh, void *data, u32 tlen, struct qib_qp *qp); + +int qib_alloc_lkey(struct qib_lkey_table *rkt, struct qib_mregion *mr); + +int qib_free_lkey(struct qib_ibdev *dev, struct qib_mregion *mr); + +int qib_lkey_ok(struct qib_lkey_table *rkt, struct qib_pd *pd, + struct qib_sge *isge, struct ib_sge *sge, int acc); + +int qib_rkey_ok(struct qib_qp *qp, struct qib_sge *sge, + u32 len, u64 vaddr, u32 rkey, int acc); + +int qib_post_srq_receive(struct ib_srq *ibsrq, struct ib_recv_wr *wr, + struct ib_recv_wr **bad_wr); + +struct ib_srq *qib_create_srq(struct ib_pd *ibpd, + struct ib_srq_init_attr *srq_init_attr, + struct ib_udata *udata); + +int qib_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, + enum ib_srq_attr_mask attr_mask, + struct ib_udata *udata); + +int qib_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr); + +int qib_destroy_srq(struct ib_srq *ibsrq); + +void qib_cq_enter(struct qib_cq *cq, struct ib_wc *entry, int sig); + +int qib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry); + +struct ib_cq *qib_create_cq(struct ib_device *ibdev, int entries, + int comp_vector, struct ib_ucontext *context, + struct ib_udata *udata); + +int qib_destroy_cq(struct ib_cq *ibcq); + +int qib_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags notify_flags); + +int qib_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata); + +struct ib_mr *qib_get_dma_mr(struct ib_pd *pd, int acc); + +struct ib_mr *qib_reg_phys_mr(struct ib_pd *pd, + struct ib_phys_buf *buffer_list, + int num_phys_buf, int acc, u64 *iova_start); + +struct ib_mr *qib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, + u64 virt_addr, int mr_access_flags, + struct ib_udata *udata); + +int qib_dereg_mr(struct ib_mr *ibmr); + +struct ib_mr *qib_alloc_fast_reg_mr(struct ib_pd *pd, int max_page_list_len); + +struct ib_fast_reg_page_list *qib_alloc_fast_reg_page_list( + struct ib_device *ibdev, int page_list_len); + +void qib_free_fast_reg_page_list(struct ib_fast_reg_page_list *pl); + +int qib_fast_reg_mr(struct qib_qp *qp, struct ib_send_wr *wr); + +struct ib_fmr *qib_alloc_fmr(struct ib_pd *pd, int mr_access_flags, + struct ib_fmr_attr *fmr_attr); + +int qib_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list, + int list_len, u64 iova); + +int qib_unmap_fmr(struct list_head *fmr_list); + +int qib_dealloc_fmr(struct ib_fmr *ibfmr); + +void qib_release_mmap_info(struct kref *ref); + +struct qib_mmap_info *qib_create_mmap_info(struct qib_ibdev *dev, u32 size, + struct ib_ucontext *context, + void *obj); + +void qib_update_mmap_info(struct qib_ibdev *dev, struct qib_mmap_info *ip, + u32 size, void *obj); + +int qib_mmap(struct ib_ucontext *context, struct vm_area_struct *vma); + +int qib_get_rwqe(struct qib_qp *qp, int wr_id_only); + +void qib_migrate_qp(struct qib_qp *qp); + +int qib_ruc_check_hdr(struct qib_ibport *ibp, struct qib_ib_header *hdr, + int has_grh, struct qib_qp *qp, u32 bth0); + +u32 qib_make_grh(struct qib_ibport *ibp, struct ib_grh *hdr, + struct ib_global_route *grh, u32 hwords, u32 nwords); + +void qib_make_ruc_header(struct qib_qp *qp, struct qib_other_headers *ohdr, + u32 bth0, u32 bth2); + +void qib_do_send(struct work_struct *work); + +void qib_send_complete(struct qib_qp *qp, struct qib_swqe *wqe, + enum ib_wc_status status); + +void qib_send_rc_ack(struct qib_qp *qp); + +int qib_make_rc_req(struct qib_qp *qp); + +int qib_make_uc_req(struct qib_qp *qp); + +int qib_make_ud_req(struct qib_qp *qp); + +int qib_register_ib_device(struct qib_devdata *); + +void qib_unregister_ib_device(struct qib_devdata *); + +void qib_ib_rcv(struct qib_ctxtdata *, void *, void *, u32); + +void qib_ib_piobufavail(struct qib_devdata *); + +unsigned qib_get_npkeys(struct qib_devdata *); + +unsigned qib_get_pkey(struct qib_ibport *, unsigned); + +extern const enum ib_wc_opcode ib_qib_wc_opcode[]; + +/* + * Below HCA-independent IB PhysPortState values, returned + * by the f_ibphys_portstate() routine. + */ +#define IB_PHYSPORTSTATE_SLEEP 1 +#define IB_PHYSPORTSTATE_POLL 2 +#define IB_PHYSPORTSTATE_DISABLED 3 +#define IB_PHYSPORTSTATE_CFG_TRAIN 4 +#define IB_PHYSPORTSTATE_LINKUP 5 +#define IB_PHYSPORTSTATE_LINK_ERR_RECOVER 6 +#define IB_PHYSPORTSTATE_CFG_DEBOUNCE 8 +#define IB_PHYSPORTSTATE_CFG_IDLE 0xB +#define IB_PHYSPORTSTATE_RECOVERY_RETRAIN 0xC +#define IB_PHYSPORTSTATE_RECOVERY_WAITRMT 0xE +#define IB_PHYSPORTSTATE_RECOVERY_IDLE 0xF +#define IB_PHYSPORTSTATE_CFG_ENH 0x10 +#define IB_PHYSPORTSTATE_CFG_WAIT_ENH 0x13 + +extern const int ib_qib_state_ops[]; + +extern __be64 ib_qib_sys_image_guid; /* in network order */ + +extern unsigned int ib_qib_lkey_table_size; + +extern unsigned int ib_qib_max_cqes; + +extern unsigned int ib_qib_max_cqs; + +extern unsigned int ib_qib_max_qp_wrs; + +extern unsigned int ib_qib_max_qps; + +extern unsigned int ib_qib_max_sges; + +extern unsigned int ib_qib_max_mcast_grps; + +extern unsigned int ib_qib_max_mcast_qp_attached; + +extern unsigned int ib_qib_max_srqs; + +extern unsigned int ib_qib_max_srq_sges; + +extern unsigned int ib_qib_max_srq_wrs; + +extern const u32 ib_qib_rnr_table[]; + +extern struct ib_dma_mapping_ops qib_dma_mapping_ops; + +#endif /* QIB_VERBS_H */ diff --git a/drivers/infiniband/hw/qib/qib_verbs_mcast.c b/drivers/infiniband/hw/qib/qib_verbs_mcast.c new file mode 100644 index 000000000000..dabb697b1c2a --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_verbs_mcast.c @@ -0,0 +1,368 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. + * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include + +#include "qib.h" + +/** + * qib_mcast_qp_alloc - alloc a struct to link a QP to mcast GID struct + * @qp: the QP to link + */ +static struct qib_mcast_qp *qib_mcast_qp_alloc(struct qib_qp *qp) +{ + struct qib_mcast_qp *mqp; + + mqp = kmalloc(sizeof *mqp, GFP_KERNEL); + if (!mqp) + goto bail; + + mqp->qp = qp; + atomic_inc(&qp->refcount); + +bail: + return mqp; +} + +static void qib_mcast_qp_free(struct qib_mcast_qp *mqp) +{ + struct qib_qp *qp = mqp->qp; + + /* Notify qib_destroy_qp() if it is waiting. */ + if (atomic_dec_and_test(&qp->refcount)) + wake_up(&qp->wait); + + kfree(mqp); +} + +/** + * qib_mcast_alloc - allocate the multicast GID structure + * @mgid: the multicast GID + * + * A list of QPs will be attached to this structure. + */ +static struct qib_mcast *qib_mcast_alloc(union ib_gid *mgid) +{ + struct qib_mcast *mcast; + + mcast = kmalloc(sizeof *mcast, GFP_KERNEL); + if (!mcast) + goto bail; + + mcast->mgid = *mgid; + INIT_LIST_HEAD(&mcast->qp_list); + init_waitqueue_head(&mcast->wait); + atomic_set(&mcast->refcount, 0); + mcast->n_attached = 0; + +bail: + return mcast; +} + +static void qib_mcast_free(struct qib_mcast *mcast) +{ + struct qib_mcast_qp *p, *tmp; + + list_for_each_entry_safe(p, tmp, &mcast->qp_list, list) + qib_mcast_qp_free(p); + + kfree(mcast); +} + +/** + * qib_mcast_find - search the global table for the given multicast GID + * @ibp: the IB port structure + * @mgid: the multicast GID to search for + * + * Returns NULL if not found. + * + * The caller is responsible for decrementing the reference count if found. + */ +struct qib_mcast *qib_mcast_find(struct qib_ibport *ibp, union ib_gid *mgid) +{ + struct rb_node *n; + unsigned long flags; + struct qib_mcast *mcast; + + spin_lock_irqsave(&ibp->lock, flags); + n = ibp->mcast_tree.rb_node; + while (n) { + int ret; + + mcast = rb_entry(n, struct qib_mcast, rb_node); + + ret = memcmp(mgid->raw, mcast->mgid.raw, + sizeof(union ib_gid)); + if (ret < 0) + n = n->rb_left; + else if (ret > 0) + n = n->rb_right; + else { + atomic_inc(&mcast->refcount); + spin_unlock_irqrestore(&ibp->lock, flags); + goto bail; + } + } + spin_unlock_irqrestore(&ibp->lock, flags); + + mcast = NULL; + +bail: + return mcast; +} + +/** + * qib_mcast_add - insert mcast GID into table and attach QP struct + * @mcast: the mcast GID table + * @mqp: the QP to attach + * + * Return zero if both were added. Return EEXIST if the GID was already in + * the table but the QP was added. Return ESRCH if the QP was already + * attached and neither structure was added. + */ +static int qib_mcast_add(struct qib_ibdev *dev, struct qib_ibport *ibp, + struct qib_mcast *mcast, struct qib_mcast_qp *mqp) +{ + struct rb_node **n = &ibp->mcast_tree.rb_node; + struct rb_node *pn = NULL; + int ret; + + spin_lock_irq(&ibp->lock); + + while (*n) { + struct qib_mcast *tmcast; + struct qib_mcast_qp *p; + + pn = *n; + tmcast = rb_entry(pn, struct qib_mcast, rb_node); + + ret = memcmp(mcast->mgid.raw, tmcast->mgid.raw, + sizeof(union ib_gid)); + if (ret < 0) { + n = &pn->rb_left; + continue; + } + if (ret > 0) { + n = &pn->rb_right; + continue; + } + + /* Search the QP list to see if this is already there. */ + list_for_each_entry_rcu(p, &tmcast->qp_list, list) { + if (p->qp == mqp->qp) { + ret = ESRCH; + goto bail; + } + } + if (tmcast->n_attached == ib_qib_max_mcast_qp_attached) { + ret = ENOMEM; + goto bail; + } + + tmcast->n_attached++; + + list_add_tail_rcu(&mqp->list, &tmcast->qp_list); + ret = EEXIST; + goto bail; + } + + spin_lock(&dev->n_mcast_grps_lock); + if (dev->n_mcast_grps_allocated == ib_qib_max_mcast_grps) { + spin_unlock(&dev->n_mcast_grps_lock); + ret = ENOMEM; + goto bail; + } + + dev->n_mcast_grps_allocated++; + spin_unlock(&dev->n_mcast_grps_lock); + + mcast->n_attached++; + + list_add_tail_rcu(&mqp->list, &mcast->qp_list); + + atomic_inc(&mcast->refcount); + rb_link_node(&mcast->rb_node, pn, n); + rb_insert_color(&mcast->rb_node, &ibp->mcast_tree); + + ret = 0; + +bail: + spin_unlock_irq(&ibp->lock); + + return ret; +} + +int qib_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) +{ + struct qib_qp *qp = to_iqp(ibqp); + struct qib_ibdev *dev = to_idev(ibqp->device); + struct qib_ibport *ibp; + struct qib_mcast *mcast; + struct qib_mcast_qp *mqp; + int ret; + + if (ibqp->qp_num <= 1 || qp->state == IB_QPS_RESET) { + ret = -EINVAL; + goto bail; + } + + /* + * Allocate data structures since its better to do this outside of + * spin locks and it will most likely be needed. + */ + mcast = qib_mcast_alloc(gid); + if (mcast == NULL) { + ret = -ENOMEM; + goto bail; + } + mqp = qib_mcast_qp_alloc(qp); + if (mqp == NULL) { + qib_mcast_free(mcast); + ret = -ENOMEM; + goto bail; + } + ibp = to_iport(ibqp->device, qp->port_num); + switch (qib_mcast_add(dev, ibp, mcast, mqp)) { + case ESRCH: + /* Neither was used: OK to attach the same QP twice. */ + qib_mcast_qp_free(mqp); + qib_mcast_free(mcast); + break; + + case EEXIST: /* The mcast wasn't used */ + qib_mcast_free(mcast); + break; + + case ENOMEM: + /* Exceeded the maximum number of mcast groups. */ + qib_mcast_qp_free(mqp); + qib_mcast_free(mcast); + ret = -ENOMEM; + goto bail; + + default: + break; + } + + ret = 0; + +bail: + return ret; +} + +int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) +{ + struct qib_qp *qp = to_iqp(ibqp); + struct qib_ibdev *dev = to_idev(ibqp->device); + struct qib_ibport *ibp = to_iport(ibqp->device, qp->port_num); + struct qib_mcast *mcast = NULL; + struct qib_mcast_qp *p, *tmp; + struct rb_node *n; + int last = 0; + int ret; + + if (ibqp->qp_num <= 1 || qp->state == IB_QPS_RESET) { + ret = -EINVAL; + goto bail; + } + + spin_lock_irq(&ibp->lock); + + /* Find the GID in the mcast table. */ + n = ibp->mcast_tree.rb_node; + while (1) { + if (n == NULL) { + spin_unlock_irq(&ibp->lock); + ret = -EINVAL; + goto bail; + } + + mcast = rb_entry(n, struct qib_mcast, rb_node); + ret = memcmp(gid->raw, mcast->mgid.raw, + sizeof(union ib_gid)); + if (ret < 0) + n = n->rb_left; + else if (ret > 0) + n = n->rb_right; + else + break; + } + + /* Search the QP list. */ + list_for_each_entry_safe(p, tmp, &mcast->qp_list, list) { + if (p->qp != qp) + continue; + /* + * We found it, so remove it, but don't poison the forward + * link until we are sure there are no list walkers. + */ + list_del_rcu(&p->list); + mcast->n_attached--; + + /* If this was the last attached QP, remove the GID too. */ + if (list_empty(&mcast->qp_list)) { + rb_erase(&mcast->rb_node, &ibp->mcast_tree); + last = 1; + } + break; + } + + spin_unlock_irq(&ibp->lock); + + if (p) { + /* + * Wait for any list walkers to finish before freeing the + * list element. + */ + wait_event(mcast->wait, atomic_read(&mcast->refcount) <= 1); + qib_mcast_qp_free(p); + } + if (last) { + atomic_dec(&mcast->refcount); + wait_event(mcast->wait, !atomic_read(&mcast->refcount)); + qib_mcast_free(mcast); + spin_lock_irq(&dev->n_mcast_grps_lock); + dev->n_mcast_grps_allocated--; + spin_unlock_irq(&dev->n_mcast_grps_lock); + } + + ret = 0; + +bail: + return ret; +} + +int qib_mcast_tree_empty(struct qib_ibport *ibp) +{ + return ibp->mcast_tree.rb_node == NULL; +} diff --git a/drivers/infiniband/hw/qib/qib_wc_ppc64.c b/drivers/infiniband/hw/qib/qib_wc_ppc64.c new file mode 100644 index 000000000000..673cf4c22ebd --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_wc_ppc64.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * This file is conditionally built on PowerPC only. Otherwise weak symbol + * versions of the functions exported from here are used. + */ + +#include "qib.h" + +/** + * qib_enable_wc - enable write combining for MMIO writes to the device + * @dd: qlogic_ib device + * + * Nothing to do on PowerPC, so just return without error. + */ +int qib_enable_wc(struct qib_devdata *dd) +{ + return 0; +} + +/** + * qib_unordered_wc - indicate whether write combining is unordered + * + * Because our performance depends on our ability to do write + * combining mmio writes in the most efficient way, we need to + * know if we are on a processor that may reorder stores when + * write combining. + */ +int qib_unordered_wc(void) +{ + return 1; +} diff --git a/drivers/infiniband/hw/qib/qib_wc_x86_64.c b/drivers/infiniband/hw/qib/qib_wc_x86_64.c new file mode 100644 index 000000000000..561b8bca4060 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_wc_x86_64.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved. + * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * This file is conditionally built on x86_64 only. Otherwise weak symbol + * versions of the functions exported from here are used. + */ + +#include +#include +#include + +#include "qib.h" + +/** + * qib_enable_wc - enable write combining for MMIO writes to the device + * @dd: qlogic_ib device + * + * This routine is x86_64-specific; it twiddles the CPU's MTRRs to enable + * write combining. + */ +int qib_enable_wc(struct qib_devdata *dd) +{ + int ret = 0; + u64 pioaddr, piolen; + unsigned bits; + const unsigned long addr = pci_resource_start(dd->pcidev, 0); + const size_t len = pci_resource_len(dd->pcidev, 0); + + /* + * Set the PIO buffers to be WCCOMB, so we get HT bursts to the + * chip. Linux (possibly the hardware) requires it to be on a power + * of 2 address matching the length (which has to be a power of 2). + * For rev1, that means the base address, for rev2, it will be just + * the PIO buffers themselves. + * For chips with two sets of buffers, the calculations are + * somewhat more complicated; we need to sum, and the piobufbase + * register has both offsets, 2K in low 32 bits, 4K in high 32 bits. + * The buffers are still packed, so a single range covers both. + */ + if (dd->piobcnt2k && dd->piobcnt4k) { + /* 2 sizes for chip */ + unsigned long pio2kbase, pio4kbase; + pio2kbase = dd->piobufbase & 0xffffffffUL; + pio4kbase = (dd->piobufbase >> 32) & 0xffffffffUL; + if (pio2kbase < pio4kbase) { + /* all current chips */ + pioaddr = addr + pio2kbase; + piolen = pio4kbase - pio2kbase + + dd->piobcnt4k * dd->align4k; + } else { + pioaddr = addr + pio4kbase; + piolen = pio2kbase - pio4kbase + + dd->piobcnt2k * dd->palign; + } + } else { /* single buffer size (2K, currently) */ + pioaddr = addr + dd->piobufbase; + piolen = dd->piobcnt2k * dd->palign + + dd->piobcnt4k * dd->align4k; + } + + for (bits = 0; !(piolen & (1ULL << bits)); bits++) + /* do nothing */ ; + + if (piolen != (1ULL << bits)) { + piolen >>= bits; + while (piolen >>= 1) + bits++; + piolen = 1ULL << (bits + 1); + } + if (pioaddr & (piolen - 1)) { + u64 atmp; + atmp = pioaddr & ~(piolen - 1); + if (atmp < addr || (atmp + piolen) > (addr + len)) { + qib_dev_err(dd, "No way to align address/size " + "(%llx/%llx), no WC mtrr\n", + (unsigned long long) atmp, + (unsigned long long) piolen << 1); + ret = -ENODEV; + } else { + pioaddr = atmp; + piolen <<= 1; + } + } + + if (!ret) { + int cookie; + + cookie = mtrr_add(pioaddr, piolen, MTRR_TYPE_WRCOMB, 0); + if (cookie < 0) { + { + qib_devinfo(dd->pcidev, + "mtrr_add() WC for PIO bufs " + "failed (%d)\n", + cookie); + ret = -EINVAL; + } + } else { + dd->wc_cookie = cookie; + dd->wc_base = (unsigned long) pioaddr; + dd->wc_len = (unsigned long) piolen; + } + } + + return ret; +} + +/** + * qib_disable_wc - disable write combining for MMIO writes to the device + * @dd: qlogic_ib device + */ +void qib_disable_wc(struct qib_devdata *dd) +{ + if (dd->wc_cookie) { + int r; + + r = mtrr_del(dd->wc_cookie, dd->wc_base, + dd->wc_len); + if (r < 0) + qib_devinfo(dd->pcidev, + "mtrr_del(%lx, %lx, %lx) failed: %d\n", + dd->wc_cookie, dd->wc_base, + dd->wc_len, r); + dd->wc_cookie = 0; /* even on failure */ + } +} + +/** + * qib_unordered_wc - indicate whether write combining is ordered + * + * Because our performance depends on our ability to do write combining mmio + * writes in the most efficient way, we need to know if we are on an Intel + * or AMD x86_64 processor. AMD x86_64 processors flush WC buffers out in + * the order completed, and so no special flushing is required to get + * correct ordering. Intel processors, however, will flush write buffers + * out in "random" orders, and so explicit ordering is needed at times. + */ +int qib_unordered_wc(void) +{ + return boot_cpu_data.x86_vendor != X86_VENDOR_AMD; +} -- cgit v1.2.3 From f6d60848baf9f4015c76c665791875ed623cd5b7 Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Thu, 6 May 2010 17:03:19 -0700 Subject: IB/ipath: Remove support for QLogic PCIe QLE devices The ib_qib driver is taking over support for QLogic PCIe QLE devices, so remove support for them from ib_ipath. The ib_ipath driver now supports only the obsolete QLogic Hyper-Transport IB host channel adapter (model QHT7140). Signed-off-by: Ralph Campbell Signed-off-by: Roland Dreier --- drivers/infiniband/hw/ipath/Kconfig | 8 +- drivers/infiniband/hw/ipath/Makefile | 6 +- drivers/infiniband/hw/ipath/ipath_7220.h | 57 - drivers/infiniband/hw/ipath/ipath_driver.c | 28 +- drivers/infiniband/hw/ipath/ipath_iba6120.c | 1862 ----------------- drivers/infiniband/hw/ipath/ipath_iba7220.c | 2631 ------------------------ drivers/infiniband/hw/ipath/ipath_kernel.h | 2 - drivers/infiniband/hw/ipath/ipath_sd7220.c | 1462 ------------- drivers/infiniband/hw/ipath/ipath_sd7220_img.c | 1082 ---------- 9 files changed, 7 insertions(+), 7131 deletions(-) delete mode 100644 drivers/infiniband/hw/ipath/ipath_7220.h delete mode 100644 drivers/infiniband/hw/ipath/ipath_iba6120.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_iba7220.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_sd7220.c delete mode 100644 drivers/infiniband/hw/ipath/ipath_sd7220_img.c (limited to 'drivers') diff --git a/drivers/infiniband/hw/ipath/Kconfig b/drivers/infiniband/hw/ipath/Kconfig index 3c7968f25ec2..1d9bb115cbf6 100644 --- a/drivers/infiniband/hw/ipath/Kconfig +++ b/drivers/infiniband/hw/ipath/Kconfig @@ -1,9 +1,11 @@ config INFINIBAND_IPATH - tristate "QLogic InfiniPath Driver" - depends on 64BIT && NET + tristate "QLogic HTX HCA support" + depends on 64BIT && NET && HT_IRQ ---help--- - This is a driver for QLogic InfiniPath host channel adapters, + This is a driver for the obsolete QLogic Hyper-Transport + IB host channel adapter (model QHT7140), including InfiniBand verbs support. This driver allows these devices to be used with both kernel upper level protocols such as IP-over-InfiniBand as well as with userspace applications (in conjunction with InfiniBand userspace access). + For QLogic PCIe QLE based cards, use the QIB driver instead. diff --git a/drivers/infiniband/hw/ipath/Makefile b/drivers/infiniband/hw/ipath/Makefile index bf9450061986..fa3df82681df 100644 --- a/drivers/infiniband/hw/ipath/Makefile +++ b/drivers/infiniband/hw/ipath/Makefile @@ -29,13 +29,9 @@ ib_ipath-y := \ ipath_user_pages.o \ ipath_user_sdma.o \ ipath_verbs_mcast.o \ - ipath_verbs.o \ - ipath_iba7220.o \ - ipath_sd7220.o \ - ipath_sd7220_img.o + ipath_verbs.o ib_ipath-$(CONFIG_HT_IRQ) += ipath_iba6110.o -ib_ipath-$(CONFIG_PCI_MSI) += ipath_iba6120.o ib_ipath-$(CONFIG_X86_64) += ipath_wc_x86_64.o ib_ipath-$(CONFIG_PPC64) += ipath_wc_ppc64.o diff --git a/drivers/infiniband/hw/ipath/ipath_7220.h b/drivers/infiniband/hw/ipath/ipath_7220.h deleted file mode 100644 index 74fa5cc5131d..000000000000 --- a/drivers/infiniband/hw/ipath/ipath_7220.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef _IPATH_7220_H -#define _IPATH_7220_H -/* - * Copyright (c) 2007 QLogic Corporation. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* - * This header file provides the declarations and common definitions - * for (mostly) manipulation of the SerDes blocks within the IBA7220. - * the functions declared should only be called from within other - * 7220-related files such as ipath_iba7220.c or ipath_sd7220.c. - */ -int ipath_sd7220_presets(struct ipath_devdata *dd); -int ipath_sd7220_init(struct ipath_devdata *dd, int was_reset); -int ipath_sd7220_prog_ld(struct ipath_devdata *dd, int sdnum, u8 *img, - int len, int offset); -int ipath_sd7220_prog_vfy(struct ipath_devdata *dd, int sdnum, const u8 *img, - int len, int offset); -/* - * Below used for sdnum parameter, selecting one of the two sections - * used for PCIe, or the single SerDes used for IB, which is the - * only one currently used - */ -#define IB_7220_SERDES 2 - -int ipath_sd7220_ib_load(struct ipath_devdata *dd); -int ipath_sd7220_ib_vfy(struct ipath_devdata *dd); - -#endif /* _IPATH_7220_H */ diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index 6302626d17f0..21337468c652 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c @@ -132,18 +132,13 @@ static int __devinit ipath_init_one(struct pci_dev *, /* Only needed for registration, nothing else needs this info */ #define PCI_VENDOR_ID_PATHSCALE 0x1fc1 -#define PCI_VENDOR_ID_QLOGIC 0x1077 #define PCI_DEVICE_ID_INFINIPATH_HT 0xd -#define PCI_DEVICE_ID_INFINIPATH_PE800 0x10 -#define PCI_DEVICE_ID_INFINIPATH_7220 0x7220 /* Number of seconds before our card status check... */ #define STATUS_TIMEOUT 60 static const struct pci_device_id ipath_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_HT) }, - { PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_PE800) }, - { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_INFINIPATH_7220) }, { 0, } }; @@ -521,30 +516,9 @@ static int __devinit ipath_init_one(struct pci_dev *pdev, /* setup the chip-specific functions, as early as possible. */ switch (ent->device) { case PCI_DEVICE_ID_INFINIPATH_HT: -#ifdef CONFIG_HT_IRQ ipath_init_iba6110_funcs(dd); break; -#else - ipath_dev_err(dd, "QLogic HT device 0x%x cannot work if " - "CONFIG_HT_IRQ is not enabled\n", ent->device); - return -ENODEV; -#endif - case PCI_DEVICE_ID_INFINIPATH_PE800: -#ifdef CONFIG_PCI_MSI - ipath_init_iba6120_funcs(dd); - break; -#else - ipath_dev_err(dd, "QLogic PCIE device 0x%x cannot work if " - "CONFIG_PCI_MSI is not enabled\n", ent->device); - return -ENODEV; -#endif - case PCI_DEVICE_ID_INFINIPATH_7220: -#ifndef CONFIG_PCI_MSI - ipath_dbg("CONFIG_PCI_MSI is not enabled, " - "using INTx for unit %u\n", dd->ipath_unit); -#endif - ipath_init_iba7220_funcs(dd); - break; + default: ipath_dev_err(dd, "Found unknown QLogic deviceid 0x%x, " "failing\n", ent->device); diff --git a/drivers/infiniband/hw/ipath/ipath_iba6120.c b/drivers/infiniband/hw/ipath/ipath_iba6120.c deleted file mode 100644 index 4b4a30b0dabd..000000000000 --- a/drivers/infiniband/hw/ipath/ipath_iba6120.c +++ /dev/null @@ -1,1862 +0,0 @@ -/* - * Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved. - * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -/* - * This file contains all of the code that is specific to the - * InfiniPath PCIe chip. - */ - -#include -#include -#include -#include - -#include "ipath_kernel.h" -#include "ipath_registers.h" - -static void ipath_setup_pe_setextled(struct ipath_devdata *, u64, u64); - -/* - * This file contains all the chip-specific register information and - * access functions for the QLogic InfiniPath PCI-Express chip. - * - * This lists the InfiniPath registers, in the actual chip layout. - * This structure should never be directly accessed. - */ -struct _infinipath_do_not_use_kernel_regs { - unsigned long long Revision; - unsigned long long Control; - unsigned long long PageAlign; - unsigned long long PortCnt; - unsigned long long DebugPortSelect; - unsigned long long Reserved0; - unsigned long long SendRegBase; - unsigned long long UserRegBase; - unsigned long long CounterRegBase; - unsigned long long Scratch; - unsigned long long Reserved1; - unsigned long long Reserved2; - unsigned long long IntBlocked; - unsigned long long IntMask; - unsigned long long IntStatus; - unsigned long long IntClear; - unsigned long long ErrorMask; - unsigned long long ErrorStatus; - unsigned long long ErrorClear; - unsigned long long HwErrMask; - unsigned long long HwErrStatus; - unsigned long long HwErrClear; - unsigned long long HwDiagCtrl; - unsigned long long MDIO; - unsigned long long IBCStatus; - unsigned long long IBCCtrl; - unsigned long long ExtStatus; - unsigned long long ExtCtrl; - unsigned long long GPIOOut; - unsigned long long GPIOMask; - unsigned long long GPIOStatus; - unsigned long long GPIOClear; - unsigned long long RcvCtrl; - unsigned long long RcvBTHQP; - unsigned long long RcvHdrSize; - unsigned long long RcvHdrCnt; - unsigned long long RcvHdrEntSize; - unsigned long long RcvTIDBase; - unsigned long long RcvTIDCnt; - unsigned long long RcvEgrBase; - unsigned long long RcvEgrCnt; - unsigned long long RcvBufBase; - unsigned long long RcvBufSize; - unsigned long long RxIntMemBase; - unsigned long long RxIntMemSize; - unsigned long long RcvPartitionKey; - unsigned long long Reserved3; - unsigned long long RcvPktLEDCnt; - unsigned long long Reserved4[8]; - unsigned long long SendCtrl; - unsigned long long SendPIOBufBase; - unsigned long long SendPIOSize; - unsigned long long SendPIOBufCnt; - unsigned long long SendPIOAvailAddr; - unsigned long long TxIntMemBase; - unsigned long long TxIntMemSize; - unsigned long long Reserved5; - unsigned long long PCIeRBufTestReg0; - unsigned long long PCIeRBufTestReg1; - unsigned long long Reserved51[6]; - unsigned long long SendBufferError; - unsigned long long SendBufferErrorCONT1; - unsigned long long Reserved6SBE[6]; - unsigned long long RcvHdrAddr0; - unsigned long long RcvHdrAddr1; - unsigned long long RcvHdrAddr2; - unsigned long long RcvHdrAddr3; - unsigned long long RcvHdrAddr4; - unsigned long long Reserved7RHA[11]; - unsigned long long RcvHdrTailAddr0; - unsigned long long RcvHdrTailAddr1; - unsigned long long RcvHdrTailAddr2; - unsigned long long RcvHdrTailAddr3; - unsigned long long RcvHdrTailAddr4; - unsigned long long Reserved8RHTA[11]; - unsigned long long Reserved9SW[8]; - unsigned long long SerdesConfig0; - unsigned long long SerdesConfig1; - unsigned long long SerdesStatus; - unsigned long long XGXSConfig; - unsigned long long IBPLLCfg; - unsigned long long Reserved10SW2[3]; - unsigned long long PCIEQ0SerdesConfig0; - unsigned long long PCIEQ0SerdesConfig1; - unsigned long long PCIEQ0SerdesStatus; - unsigned long long Reserved11; - unsigned long long PCIEQ1SerdesConfig0; - unsigned long long PCIEQ1SerdesConfig1; - unsigned long long PCIEQ1SerdesStatus; - unsigned long long Reserved12; -}; - -struct _infinipath_do_not_use_counters { - __u64 LBIntCnt; - __u64 LBFlowStallCnt; - __u64 Reserved1; - __u64 TxUnsupVLErrCnt; - __u64 TxDataPktCnt; - __u64 TxFlowPktCnt; - __u64 TxDwordCnt; - __u64 TxLenErrCnt; - __u64 TxMaxMinLenErrCnt; - __u64 TxUnderrunCnt; - __u64 TxFlowStallCnt; - __u64 TxDroppedPktCnt; - __u64 RxDroppedPktCnt; - __u64 RxDataPktCnt; - __u64 RxFlowPktCnt; - __u64 RxDwordCnt; - __u64 RxLenErrCnt; - __u64 RxMaxMinLenErrCnt; - __u64 RxICRCErrCnt; - __u64 RxVCRCErrCnt; - __u64 RxFlowCtrlErrCnt; - __u64 RxBadFormatCnt; - __u64 RxLinkProblemCnt; - __u64 RxEBPCnt; - __u64 RxLPCRCErrCnt; - __u64 RxBufOvflCnt; - __u64 RxTIDFullErrCnt; - __u64 RxTIDValidErrCnt; - __u64 RxPKeyMismatchCnt; - __u64 RxP0HdrEgrOvflCnt; - __u64 RxP1HdrEgrOvflCnt; - __u64 RxP2HdrEgrOvflCnt; - __u64 RxP3HdrEgrOvflCnt; - __u64 RxP4HdrEgrOvflCnt; - __u64 RxP5HdrEgrOvflCnt; - __u64 RxP6HdrEgrOvflCnt; - __u64 RxP7HdrEgrOvflCnt; - __u64 RxP8HdrEgrOvflCnt; - __u64 Reserved6; - __u64 Reserved7; - __u64 IBStatusChangeCnt; - __u64 IBLinkErrRecoveryCnt; - __u64 IBLinkDownedCnt; - __u64 IBSymbolErrCnt; -}; - -#define IPATH_KREG_OFFSET(field) (offsetof( \ - struct _infinipath_do_not_use_kernel_regs, field) / sizeof(u64)) -#define IPATH_CREG_OFFSET(field) (offsetof( \ - struct _infinipath_do_not_use_counters, field) / sizeof(u64)) - -static const struct ipath_kregs ipath_pe_kregs = { - .kr_control = IPATH_KREG_OFFSET(Control), - .kr_counterregbase = IPATH_KREG_OFFSET(CounterRegBase), - .kr_debugportselect = IPATH_KREG_OFFSET(DebugPortSelect), - .kr_errorclear = IPATH_KREG_OFFSET(ErrorClear), - .kr_errormask = IPATH_KREG_OFFSET(ErrorMask), - .kr_errorstatus = IPATH_KREG_OFFSET(ErrorStatus), - .kr_extctrl = IPATH_KREG_OFFSET(ExtCtrl), - .kr_extstatus = IPATH_KREG_OFFSET(ExtStatus), - .kr_gpio_clear = IPATH_KREG_OFFSET(GPIOClear), - .kr_gpio_mask = IPATH_KREG_OFFSET(GPIOMask), - .kr_gpio_out = IPATH_KREG_OFFSET(GPIOOut), - .kr_gpio_status = IPATH_KREG_OFFSET(GPIOStatus), - .kr_hwdiagctrl = IPATH_KREG_OFFSET(HwDiagCtrl), - .kr_hwerrclear = IPATH_KREG_OFFSET(HwErrClear), - .kr_hwerrmask = IPATH_KREG_OFFSET(HwErrMask), - .kr_hwerrstatus = IPATH_KREG_OFFSET(HwErrStatus), - .kr_ibcctrl = IPATH_KREG_OFFSET(IBCCtrl), - .kr_ibcstatus = IPATH_KREG_OFFSET(IBCStatus), - .kr_intblocked = IPATH_KREG_OFFSET(IntBlocked), - .kr_intclear = IPATH_KREG_OFFSET(IntClear), - .kr_intmask = IPATH_KREG_OFFSET(IntMask), - .kr_intstatus = IPATH_KREG_OFFSET(IntStatus), - .kr_mdio = IPATH_KREG_OFFSET(MDIO), - .kr_pagealign = IPATH_KREG_OFFSET(PageAlign), - .kr_partitionkey = IPATH_KREG_OFFSET(RcvPartitionKey), - .kr_portcnt = IPATH_KREG_OFFSET(PortCnt), - .kr_rcvbthqp = IPATH_KREG_OFFSET(RcvBTHQP), - .kr_rcvbufbase = IPATH_KREG_OFFSET(RcvBufBase), - .kr_rcvbufsize = IPATH_KREG_OFFSET(RcvBufSize), - .kr_rcvctrl = IPATH_KREG_OFFSET(RcvCtrl), - .kr_rcvegrbase = IPATH_KREG_OFFSET(RcvEgrBase), - .kr_rcvegrcnt = IPATH_KREG_OFFSET(RcvEgrCnt), - .kr_rcvhdrcnt = IPATH_KREG_OFFSET(RcvHdrCnt), - .kr_rcvhdrentsize = IPATH_KREG_OFFSET(RcvHdrEntSize), - .kr_rcvhdrsize = IPATH_KREG_OFFSET(RcvHdrSize), - .kr_rcvintmembase = IPATH_KREG_OFFSET(RxIntMemBase), - .kr_rcvintmemsize = IPATH_KREG_OFFSET(RxIntMemSize), - .kr_rcvtidbase = IPATH_KREG_OFFSET(RcvTIDBase), - .kr_rcvtidcnt = IPATH_KREG_OFFSET(RcvTIDCnt), - .kr_revision = IPATH_KREG_OFFSET(Revision), - .kr_scratch = IPATH_KREG_OFFSET(Scratch), - .kr_sendbuffererror = IPATH_KREG_OFFSET(SendBufferError), - .kr_sendctrl = IPATH_KREG_OFFSET(SendCtrl), - .kr_sendpioavailaddr = IPATH_KREG_OFFSET(SendPIOAvailAddr), - .kr_sendpiobufbase = IPATH_KREG_OFFSET(SendPIOBufBase), - .kr_sendpiobufcnt = IPATH_KREG_OFFSET(SendPIOBufCnt), - .kr_sendpiosize = IPATH_KREG_OFFSET(SendPIOSize), - .kr_sendregbase = IPATH_KREG_OFFSET(SendRegBase), - .kr_txintmembase = IPATH_KREG_OFFSET(TxIntMemBase), - .kr_txintmemsize = IPATH_KREG_OFFSET(TxIntMemSize), - .kr_userregbase = IPATH_KREG_OFFSET(UserRegBase), - .kr_serdesconfig0 = IPATH_KREG_OFFSET(SerdesConfig0), - .kr_serdesconfig1 = IPATH_KREG_OFFSET(SerdesConfig1), - .kr_serdesstatus = IPATH_KREG_OFFSET(SerdesStatus), - .kr_xgxsconfig = IPATH_KREG_OFFSET(XGXSConfig), - .kr_ibpllcfg = IPATH_KREG_OFFSET(IBPLLCfg), - - /* - * These should not be used directly via ipath_write_kreg64(), - * use them with ipath_write_kreg64_port(), - */ - .kr_rcvhdraddr = IPATH_KREG_OFFSET(RcvHdrAddr0), - .kr_rcvhdrtailaddr = IPATH_KREG_OFFSET(RcvHdrTailAddr0), - - /* The rcvpktled register controls one of the debug port signals, so - * a packet activity LED can be connected to it. */ - .kr_rcvpktledcnt = IPATH_KREG_OFFSET(RcvPktLEDCnt), - .kr_pcierbuftestreg0 = IPATH_KREG_OFFSET(PCIeRBufTestReg0), - .kr_pcierbuftestreg1 = IPATH_KREG_OFFSET(PCIeRBufTestReg1), - .kr_pcieq0serdesconfig0 = IPATH_KREG_OFFSET(PCIEQ0SerdesConfig0), - .kr_pcieq0serdesconfig1 = IPATH_KREG_OFFSET(PCIEQ0SerdesConfig1), - .kr_pcieq0serdesstatus = IPATH_KREG_OFFSET(PCIEQ0SerdesStatus), - .kr_pcieq1serdesconfig0 = IPATH_KREG_OFFSET(PCIEQ1SerdesConfig0), - .kr_pcieq1serdesconfig1 = IPATH_KREG_OFFSET(PCIEQ1SerdesConfig1), - .kr_pcieq1serdesstatus = IPATH_KREG_OFFSET(PCIEQ1SerdesStatus) -}; - -static const struct ipath_cregs ipath_pe_cregs = { - .cr_badformatcnt = IPATH_CREG_OFFSET(RxBadFormatCnt), - .cr_erricrccnt = IPATH_CREG_OFFSET(RxICRCErrCnt), - .cr_errlinkcnt = IPATH_CREG_OFFSET(RxLinkProblemCnt), - .cr_errlpcrccnt = IPATH_CREG_OFFSET(RxLPCRCErrCnt), - .cr_errpkey = IPATH_CREG_OFFSET(RxPKeyMismatchCnt), - .cr_errrcvflowctrlcnt = IPATH_CREG_OFFSET(RxFlowCtrlErrCnt), - .cr_err_rlencnt = IPATH_CREG_OFFSET(RxLenErrCnt), - .cr_errslencnt = IPATH_CREG_OFFSET(TxLenErrCnt), - .cr_errtidfull = IPATH_CREG_OFFSET(RxTIDFullErrCnt), - .cr_errtidvalid = IPATH_CREG_OFFSET(RxTIDValidErrCnt), - .cr_errvcrccnt = IPATH_CREG_OFFSET(RxVCRCErrCnt), - .cr_ibstatuschange = IPATH_CREG_OFFSET(IBStatusChangeCnt), - .cr_intcnt = IPATH_CREG_OFFSET(LBIntCnt), - .cr_invalidrlencnt = IPATH_CREG_OFFSET(RxMaxMinLenErrCnt), - .cr_invalidslencnt = IPATH_CREG_OFFSET(TxMaxMinLenErrCnt), - .cr_lbflowstallcnt = IPATH_CREG_OFFSET(LBFlowStallCnt), - .cr_pktrcvcnt = IPATH_CREG_OFFSET(RxDataPktCnt), - .cr_pktrcvflowctrlcnt = IPATH_CREG_OFFSET(RxFlowPktCnt), - .cr_pktsendcnt = IPATH_CREG_OFFSET(TxDataPktCnt), - .cr_pktsendflowcnt = IPATH_CREG_OFFSET(TxFlowPktCnt), - .cr_portovflcnt = IPATH_CREG_OFFSET(RxP0HdrEgrOvflCnt), - .cr_rcvebpcnt = IPATH_CREG_OFFSET(RxEBPCnt), - .cr_rcvovflcnt = IPATH_CREG_OFFSET(RxBufOvflCnt), - .cr_senddropped = IPATH_CREG_OFFSET(TxDroppedPktCnt), - .cr_sendstallcnt = IPATH_CREG_OFFSET(TxFlowStallCnt), - .cr_sendunderruncnt = IPATH_CREG_OFFSET(TxUnderrunCnt), - .cr_wordrcvcnt = IPATH_CREG_OFFSET(RxDwordCnt), - .cr_wordsendcnt = IPATH_CREG_OFFSET(TxDwordCnt), - .cr_unsupvlcnt = IPATH_CREG_OFFSET(TxUnsupVLErrCnt), - .cr_rxdroppktcnt = IPATH_CREG_OFFSET(RxDroppedPktCnt), - .cr_iblinkerrrecovcnt = IPATH_CREG_OFFSET(IBLinkErrRecoveryCnt), - .cr_iblinkdowncnt = IPATH_CREG_OFFSET(IBLinkDownedCnt), - .cr_ibsymbolerrcnt = IPATH_CREG_OFFSET(IBSymbolErrCnt) -}; - -/* kr_control bits */ -#define INFINIPATH_C_RESET 1U - -/* kr_intstatus, kr_intclear, kr_intmask bits */ -#define INFINIPATH_I_RCVURG_MASK ((1U<<5)-1) -#define INFINIPATH_I_RCVURG_SHIFT 0 -#define INFINIPATH_I_RCVAVAIL_MASK ((1U<<5)-1) -#define INFINIPATH_I_RCVAVAIL_SHIFT 12 - -/* kr_hwerrclear, kr_hwerrmask, kr_hwerrstatus, bits */ -#define INFINIPATH_HWE_PCIEMEMPARITYERR_MASK 0x000000000000003fULL -#define INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT 0 -#define INFINIPATH_HWE_PCIEPOISONEDTLP 0x0000000010000000ULL -#define INFINIPATH_HWE_PCIECPLTIMEOUT 0x0000000020000000ULL -#define INFINIPATH_HWE_PCIEBUSPARITYXTLH 0x0000000040000000ULL -#define INFINIPATH_HWE_PCIEBUSPARITYXADM 0x0000000080000000ULL -#define INFINIPATH_HWE_PCIEBUSPARITYRADM 0x0000000100000000ULL -#define INFINIPATH_HWE_COREPLL_FBSLIP 0x0080000000000000ULL -#define INFINIPATH_HWE_COREPLL_RFSLIP 0x0100000000000000ULL -#define INFINIPATH_HWE_PCIE1PLLFAILED 0x0400000000000000ULL -#define INFINIPATH_HWE_PCIE0PLLFAILED 0x0800000000000000ULL -#define INFINIPATH_HWE_SERDESPLLFAILED 0x1000000000000000ULL - -#define IBA6120_IBCS_LINKTRAININGSTATE_MASK 0xf -#define IBA6120_IBCS_LINKSTATE_SHIFT 4 - -/* kr_extstatus bits */ -#define INFINIPATH_EXTS_FREQSEL 0x2 -#define INFINIPATH_EXTS_SERDESSEL 0x4 -#define INFINIPATH_EXTS_MEMBIST_ENDTEST 0x0000000000004000 -#define INFINIPATH_EXTS_MEMBIST_FOUND 0x0000000000008000 - -/* kr_xgxsconfig bits */ -#define INFINIPATH_XGXS_RESET 0x5ULL - -#define _IPATH_GPIO_SDA_NUM 1 -#define _IPATH_GPIO_SCL_NUM 0 - -#define IPATH_GPIO_SDA (1ULL << \ - (_IPATH_GPIO_SDA_NUM+INFINIPATH_EXTC_GPIOOE_SHIFT)) -#define IPATH_GPIO_SCL (1ULL << \ - (_IPATH_GPIO_SCL_NUM+INFINIPATH_EXTC_GPIOOE_SHIFT)) - -#define INFINIPATH_RT_BUFSIZE_MASK 0xe0000000ULL -#define INFINIPATH_RT_BUFSIZE_SHIFTVAL(tid) \ - ((((tid) & INFINIPATH_RT_BUFSIZE_MASK) >> 29) + 11 - 1) -#define INFINIPATH_RT_BUFSIZE(tid) (1 << INFINIPATH_RT_BUFSIZE_SHIFTVAL(tid)) -#define INFINIPATH_RT_IS_VALID(tid) \ - (((tid) & INFINIPATH_RT_BUFSIZE_MASK) && \ - ((((tid) & INFINIPATH_RT_BUFSIZE_MASK) != INFINIPATH_RT_BUFSIZE_MASK))) -#define INFINIPATH_RT_ADDR_MASK 0x1FFFFFFFULL /* 29 bits valid */ -#define INFINIPATH_RT_ADDR_SHIFT 10 - -#define INFINIPATH_R_INTRAVAIL_SHIFT 16 -#define INFINIPATH_R_TAILUPD_SHIFT 31 - -/* 6120 specific hardware errors... */ -static const struct ipath_hwerror_msgs ipath_6120_hwerror_msgs[] = { - INFINIPATH_HWE_MSG(PCIEPOISONEDTLP, "PCIe Poisoned TLP"), - INFINIPATH_HWE_MSG(PCIECPLTIMEOUT, "PCIe completion timeout"), - /* - * In practice, it's unlikely wthat we'll see PCIe PLL, or bus - * parity or memory parity error failures, because most likely we - * won't be able to talk to the core of the chip. Nonetheless, we - * might see them, if they are in parts of the PCIe core that aren't - * essential. - */ - INFINIPATH_HWE_MSG(PCIE1PLLFAILED, "PCIePLL1"), - INFINIPATH_HWE_MSG(PCIE0PLLFAILED, "PCIePLL0"), - INFINIPATH_HWE_MSG(PCIEBUSPARITYXTLH, "PCIe XTLH core parity"), - INFINIPATH_HWE_MSG(PCIEBUSPARITYXADM, "PCIe ADM TX core parity"), - INFINIPATH_HWE_MSG(PCIEBUSPARITYRADM, "PCIe ADM RX core parity"), - INFINIPATH_HWE_MSG(RXDSYNCMEMPARITYERR, "Rx Dsync"), - INFINIPATH_HWE_MSG(SERDESPLLFAILED, "SerDes PLL"), -}; - -#define TXE_PIO_PARITY ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF | \ - INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC) \ - << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) -#define RXE_EAGER_PARITY (INFINIPATH_HWE_RXEMEMPARITYERR_EAGERTID \ - << INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT) - -static void ipath_pe_put_tid_2(struct ipath_devdata *, u64 __iomem *, - u32, unsigned long); - -/* - * On platforms using this chip, and not having ordered WC stores, we - * can get TXE parity errors due to speculative reads to the PIO buffers, - * and this, due to a chip bug can result in (many) false parity error - * reports. So it's a debug print on those, and an info print on systems - * where the speculative reads don't occur. - */ -static void ipath_pe_txe_recover(struct ipath_devdata *dd) -{ - if (ipath_unordered_wc()) - ipath_dbg("Recovering from TXE PIO parity error\n"); - else { - ++ipath_stats.sps_txeparity; - dev_info(&dd->pcidev->dev, - "Recovering from TXE PIO parity error\n"); - } -} - - -/** - * ipath_pe_handle_hwerrors - display hardware errors. - * @dd: the infinipath device - * @msg: the output buffer - * @msgl: the size of the output buffer - * - * Use same msg buffer as regular errors to avoid excessive stack - * use. Most hardware errors are catastrophic, but for right now, - * we'll print them and continue. We reuse the same message buffer as - * ipath_handle_errors() to avoid excessive stack usage. - */ -static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg, - size_t msgl) -{ - ipath_err_t hwerrs; - u32 bits, ctrl; - int isfatal = 0; - char bitsmsg[64]; - int log_idx; - - hwerrs = ipath_read_kreg64(dd, dd->ipath_kregs->kr_hwerrstatus); - if (!hwerrs) { - /* - * better than printing cofusing messages - * This seems to be related to clearing the crc error, or - * the pll error during init. - */ - ipath_cdbg(VERBOSE, "Called but no hardware errors set\n"); - return; - } else if (hwerrs == ~0ULL) { - ipath_dev_err(dd, "Read of hardware error status failed " - "(all bits set); ignoring\n"); - return; - } - ipath_stats.sps_hwerrs++; - - /* Always clear the error status register, except MEMBISTFAIL, - * regardless of whether we continue or stop using the chip. - * We want that set so we know it failed, even across driver reload. - * We'll still ignore it in the hwerrmask. We do this partly for - * diagnostics, but also for support */ - ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, - hwerrs&~INFINIPATH_HWE_MEMBISTFAILED); - - hwerrs &= dd->ipath_hwerrmask; - - /* We log some errors to EEPROM, check if we have any of those. */ - for (log_idx = 0; log_idx < IPATH_EEP_LOG_CNT; ++log_idx) - if (hwerrs & dd->ipath_eep_st_masks[log_idx].hwerrs_to_log) - ipath_inc_eeprom_err(dd, log_idx, 1); - - /* - * make sure we get this much out, unless told to be quiet, - * or it's occurred within the last 5 seconds - */ - if ((hwerrs & ~(dd->ipath_lasthwerror | TXE_PIO_PARITY | - RXE_EAGER_PARITY)) || - (ipath_debug & __IPATH_VERBDBG)) - dev_info(&dd->pcidev->dev, "Hardware error: hwerr=0x%llx " - "(cleared)\n", (unsigned long long) hwerrs); - dd->ipath_lasthwerror |= hwerrs; - - if (hwerrs & ~dd->ipath_hwe_bitsextant) - ipath_dev_err(dd, "hwerror interrupt with unknown errors " - "%llx set\n", (unsigned long long) - (hwerrs & ~dd->ipath_hwe_bitsextant)); - - ctrl = ipath_read_kreg32(dd, dd->ipath_kregs->kr_control); - if ((ctrl & INFINIPATH_C_FREEZEMODE) && !ipath_diag_inuse) { - /* - * parity errors in send memory are recoverable, - * just cancel the send (if indicated in * sendbuffererror), - * count the occurrence, unfreeze (if no other handled - * hardware error bits are set), and continue. They can - * occur if a processor speculative read is done to the PIO - * buffer while we are sending a packet, for example. - */ - if (hwerrs & TXE_PIO_PARITY) { - ipath_pe_txe_recover(dd); - hwerrs &= ~TXE_PIO_PARITY; - } - if (!hwerrs) { - static u32 freeze_cnt; - - freeze_cnt++; - ipath_dbg("Clearing freezemode on ignored or recovered " - "hardware error (%u)\n", freeze_cnt); - ipath_clear_freeze(dd); - } - } - - *msg = '\0'; - - if (hwerrs & INFINIPATH_HWE_MEMBISTFAILED) { - strlcat(msg, "[Memory BIST test failed, InfiniPath hardware unusable]", - msgl); - /* ignore from now on, so disable until driver reloaded */ - *dd->ipath_statusp |= IPATH_STATUS_HWERROR; - dd->ipath_hwerrmask &= ~INFINIPATH_HWE_MEMBISTFAILED; - ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, - dd->ipath_hwerrmask); - } - - ipath_format_hwerrors(hwerrs, - ipath_6120_hwerror_msgs, - sizeof(ipath_6120_hwerror_msgs)/ - sizeof(ipath_6120_hwerror_msgs[0]), - msg, msgl); - - if (hwerrs & (INFINIPATH_HWE_PCIEMEMPARITYERR_MASK - << INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT)) { - bits = (u32) ((hwerrs >> - INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT) & - INFINIPATH_HWE_PCIEMEMPARITYERR_MASK); - snprintf(bitsmsg, sizeof bitsmsg, - "[PCIe Mem Parity Errs %x] ", bits); - strlcat(msg, bitsmsg, msgl); - } - -#define _IPATH_PLL_FAIL (INFINIPATH_HWE_COREPLL_FBSLIP | \ - INFINIPATH_HWE_COREPLL_RFSLIP ) - - if (hwerrs & _IPATH_PLL_FAIL) { - snprintf(bitsmsg, sizeof bitsmsg, - "[PLL failed (%llx), InfiniPath hardware unusable]", - (unsigned long long) hwerrs & _IPATH_PLL_FAIL); - strlcat(msg, bitsmsg, msgl); - /* ignore from now on, so disable until driver reloaded */ - dd->ipath_hwerrmask &= ~(hwerrs & _IPATH_PLL_FAIL); - ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, - dd->ipath_hwerrmask); - } - - if (hwerrs & INFINIPATH_HWE_SERDESPLLFAILED) { - /* - * If it occurs, it is left masked since the external - * interface is unused - */ - dd->ipath_hwerrmask &= ~INFINIPATH_HWE_SERDESPLLFAILED; - ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, - dd->ipath_hwerrmask); - } - - if (hwerrs) { - /* - * if any set that we aren't ignoring; only - * make the complaint once, in case it's stuck - * or recurring, and we get here multiple - * times. - */ - ipath_dev_err(dd, "%s hardware error\n", msg); - if (dd->ipath_flags & IPATH_INITTED) { - ipath_set_linkstate(dd, IPATH_IB_LINKDOWN); - ipath_setup_pe_setextled(dd, - INFINIPATH_IBCS_L_STATE_DOWN, - INFINIPATH_IBCS_LT_STATE_DISABLED); - ipath_dev_err(dd, "Fatal Hardware Error (freeze " - "mode), no longer usable, SN %.16s\n", - dd->ipath_serial); - isfatal = 1; - } - *dd->ipath_statusp &= ~IPATH_STATUS_IB_READY; - /* mark as having had error */ - *dd->ipath_statusp |= IPATH_STATUS_HWERROR; - /* - * mark as not usable, at a minimum until driver - * is reloaded, probably until reboot, since no - * other reset is possible. - */ - dd->ipath_flags &= ~IPATH_INITTED; - } else - *msg = 0; /* recovered from all of them */ - - if (isfatal && !ipath_diag_inuse && dd->ipath_freezemsg && msg) { - /* - * for /sys status file ; if no trailing brace is copied, - * we'll know it was truncated. - */ - snprintf(dd->ipath_freezemsg, dd->ipath_freezelen, - "{%s}", msg); - } -} - -/** - * ipath_pe_boardname - fill in the board name - * @dd: the infinipath device - * @name: the output buffer - * @namelen: the size of the output buffer - * - * info is based on the board revision register - */ -static int ipath_pe_boardname(struct ipath_devdata *dd, char *name, - size_t namelen) -{ - char *n = NULL; - u8 boardrev = dd->ipath_boardrev; - int ret; - - switch (boardrev) { - case 0: - n = "InfiniPath_Emulation"; - break; - case 1: - n = "InfiniPath_QLE7140-Bringup"; - break; - case 2: - n = "InfiniPath_QLE7140"; - break; - case 3: - n = "InfiniPath_QMI7140"; - break; - case 4: - n = "InfiniPath_QEM7140"; - break; - case 5: - n = "InfiniPath_QMH7140"; - break; - case 6: - n = "InfiniPath_QLE7142"; - break; - default: - ipath_dev_err(dd, - "Don't yet know about board with ID %u\n", - boardrev); - snprintf(name, namelen, "Unknown_InfiniPath_PCIe_%u", - boardrev); - break; - } - if (n) - snprintf(name, namelen, "%s", n); - - if (dd->ipath_majrev != 4 || !dd->ipath_minrev || dd->ipath_minrev>2) { - ipath_dev_err(dd, "Unsupported InfiniPath hardware revision %u.%u!\n", - dd->ipath_majrev, dd->ipath_minrev); - ret = 1; - } else { - ret = 0; - if (dd->ipath_minrev >= 2) - dd->ipath_f_put_tid = ipath_pe_put_tid_2; - } - - /* - * set here, not in ipath_init_*_funcs because we have to do - * it after we can read chip registers. - */ - dd->ipath_ureg_align = - ipath_read_kreg32(dd, dd->ipath_kregs->kr_pagealign); - - return ret; -} - -/** - * ipath_pe_init_hwerrors - enable hardware errors - * @dd: the infinipath device - * - * now that we have finished initializing everything that might reasonably - * cause a hardware error, and cleared those errors bits as they occur, - * we can enable hardware errors in the mask (potentially enabling - * freeze mode), and enable hardware errors as errors (along with - * everything else) in errormask - */ -static void ipath_pe_init_hwerrors(struct ipath_devdata *dd) -{ - ipath_err_t val; - u64 extsval; - - extsval = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extstatus); - - if (!(extsval & INFINIPATH_EXTS_MEMBIST_ENDTEST)) - ipath_dev_err(dd, "MemBIST did not complete!\n"); - if (extsval & INFINIPATH_EXTS_MEMBIST_FOUND) - ipath_dbg("MemBIST corrected\n"); - - val = ~0ULL; /* barring bugs, all hwerrors become interrupts, */ - - if (!dd->ipath_boardrev) // no PLL for Emulator - val &= ~INFINIPATH_HWE_SERDESPLLFAILED; - - if (dd->ipath_minrev < 2) { - /* workaround bug 9460 in internal interface bus parity - * checking. Fixed (HW bug 9490) in Rev2. - */ - val &= ~INFINIPATH_HWE_PCIEBUSPARITYRADM; - } - dd->ipath_hwerrmask = val; -} - -/** - * ipath_pe_bringup_serdes - bring up the serdes - * @dd: the infinipath device - */ -static int ipath_pe_bringup_serdes(struct ipath_devdata *dd) -{ - u64 val, config1, prev_val; - int ret = 0; - - ipath_dbg("Trying to bringup serdes\n"); - - if (ipath_read_kreg64(dd, dd->ipath_kregs->kr_hwerrstatus) & - INFINIPATH_HWE_SERDESPLLFAILED) { - ipath_dbg("At start, serdes PLL failed bit set " - "in hwerrstatus, clearing and continuing\n"); - ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, - INFINIPATH_HWE_SERDESPLLFAILED); - } - - dd->ibdeltainprog = 1; - dd->ibsymsnap = - ipath_read_creg32(dd, dd->ipath_cregs->cr_ibsymbolerrcnt); - dd->iblnkerrsnap = - ipath_read_creg32(dd, dd->ipath_cregs->cr_iblinkerrrecovcnt); - - val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0); - config1 = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig1); - - ipath_cdbg(VERBOSE, "SerDes status config0=%llx config1=%llx, " - "xgxsconfig %llx\n", (unsigned long long) val, - (unsigned long long) config1, (unsigned long long) - ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig)); - - /* - * Force reset on, also set rxdetect enable. Must do before reading - * serdesstatus at least for simulation, or some of the bits in - * serdes status will come back as undefined and cause simulation - * failures - */ - val |= INFINIPATH_SERDC0_RESET_PLL | INFINIPATH_SERDC0_RXDETECT_EN - | INFINIPATH_SERDC0_L1PWR_DN; - ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val); - /* be sure chip saw it */ - ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); - udelay(5); /* need pll reset set at least for a bit */ - /* - * after PLL is reset, set the per-lane Resets and TxIdle and - * clear the PLL reset and rxdetect (to get falling edge). - * Leave L1PWR bits set (permanently) - */ - val &= ~(INFINIPATH_SERDC0_RXDETECT_EN | INFINIPATH_SERDC0_RESET_PLL - | INFINIPATH_SERDC0_L1PWR_DN); - val |= INFINIPATH_SERDC0_RESET_MASK | INFINIPATH_SERDC0_TXIDLE; - ipath_cdbg(VERBOSE, "Clearing pll reset and setting lane resets " - "and txidle (%llx)\n", (unsigned long long) val); - ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val); - /* be sure chip saw it */ - ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); - /* need PLL reset clear for at least 11 usec before lane - * resets cleared; give it a few more to be sure */ - udelay(15); - val &= ~(INFINIPATH_SERDC0_RESET_MASK | INFINIPATH_SERDC0_TXIDLE); - - ipath_cdbg(VERBOSE, "Clearing lane resets and txidle " - "(writing %llx)\n", (unsigned long long) val); - ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val); - /* be sure chip saw it */ - val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); - - val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig); - prev_val = val; - if (val & INFINIPATH_XGXS_RESET) - val &= ~INFINIPATH_XGXS_RESET; - if (((val >> INFINIPATH_XGXS_RX_POL_SHIFT) & - INFINIPATH_XGXS_RX_POL_MASK) != dd->ipath_rx_pol_inv ) { - /* need to compensate for Tx inversion in partner */ - val &= ~(INFINIPATH_XGXS_RX_POL_MASK << - INFINIPATH_XGXS_RX_POL_SHIFT); - val |= dd->ipath_rx_pol_inv << - INFINIPATH_XGXS_RX_POL_SHIFT; - } - if (val != prev_val) - ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val); - - val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0); - - /* clear current and de-emphasis bits */ - config1 &= ~0x0ffffffff00ULL; - /* set current to 20ma */ - config1 |= 0x00000000000ULL; - /* set de-emphasis to -5.68dB */ - config1 |= 0x0cccc000000ULL; - ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig1, config1); - - ipath_cdbg(VERBOSE, "done: SerDes status config0=%llx " - "config1=%llx, sstatus=%llx xgxs=%llx\n", - (unsigned long long) val, (unsigned long long) config1, - (unsigned long long) - ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesstatus), - (unsigned long long) - ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig)); - - return ret; -} - -/** - * ipath_pe_quiet_serdes - set serdes to txidle - * @dd: the infinipath device - * Called when driver is being unloaded - */ -static void ipath_pe_quiet_serdes(struct ipath_devdata *dd) -{ - u64 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0); - - if (dd->ibsymdelta || dd->iblnkerrdelta || - dd->ibdeltainprog) { - u64 diagc; - /* enable counter writes */ - diagc = ipath_read_kreg64(dd, dd->ipath_kregs->kr_hwdiagctrl); - ipath_write_kreg(dd, dd->ipath_kregs->kr_hwdiagctrl, - diagc | INFINIPATH_DC_COUNTERWREN); - - if (dd->ibsymdelta || dd->ibdeltainprog) { - val = ipath_read_creg32(dd, - dd->ipath_cregs->cr_ibsymbolerrcnt); - if (dd->ibdeltainprog) - val -= val - dd->ibsymsnap; - val -= dd->ibsymdelta; - ipath_write_creg(dd, - dd->ipath_cregs->cr_ibsymbolerrcnt, val); - } - if (dd->iblnkerrdelta || dd->ibdeltainprog) { - val = ipath_read_creg32(dd, - dd->ipath_cregs->cr_iblinkerrrecovcnt); - if (dd->ibdeltainprog) - val -= val - dd->iblnkerrsnap; - val -= dd->iblnkerrdelta; - ipath_write_creg(dd, - dd->ipath_cregs->cr_iblinkerrrecovcnt, val); - } - - /* and disable counter writes */ - ipath_write_kreg(dd, dd->ipath_kregs->kr_hwdiagctrl, diagc); - } - val |= INFINIPATH_SERDC0_TXIDLE; - ipath_dbg("Setting TxIdleEn on serdes (config0 = %llx)\n", - (unsigned long long) val); - ipath_write_kreg(dd, dd->ipath_kregs->kr_serdesconfig0, val); -} - -static int ipath_pe_intconfig(struct ipath_devdata *dd) -{ - u32 chiprev; - - /* - * If the chip supports added error indication via GPIO pins, - * enable interrupts on those bits so the interrupt routine - * can count the events. Also set flag so interrupt routine - * can know they are expected. - */ - chiprev = dd->ipath_revision >> INFINIPATH_R_CHIPREVMINOR_SHIFT; - if ((chiprev & INFINIPATH_R_CHIPREVMINOR_MASK) > 1) { - /* Rev2+ reports extra errors via internal GPIO pins */ - dd->ipath_flags |= IPATH_GPIO_ERRINTRS; - dd->ipath_gpio_mask |= IPATH_GPIO_ERRINTR_MASK; - ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_mask, - dd->ipath_gpio_mask); - } - return 0; -} - -/** - * ipath_setup_pe_setextled - set the state of the two external LEDs - * @dd: the infinipath device - * @lst: the L state - * @ltst: the LT state - - * These LEDs indicate the physical and logical state of IB link. - * For this chip (at least with recommended board pinouts), LED1 - * is Yellow (logical state) and LED2 is Green (physical state), - * - * Note: We try to match the Mellanox HCA LED behavior as best - * we can. Green indicates physical link state is OK (something is - * plugged in, and we can train). - * Amber indicates the link is logically up (ACTIVE). - * Mellanox further blinks the amber LED to indicate data packet - * activity, but we have no hardware support for that, so it would - * require waking up every 10-20 msecs and checking the counters - * on the chip, and then turning the LED off if appropriate. That's - * visible overhead, so not something we will do. - * - */ -static void ipath_setup_pe_setextled(struct ipath_devdata *dd, u64 lst, - u64 ltst) -{ - u64 extctl; - unsigned long flags = 0; - - /* the diags use the LED to indicate diag info, so we leave - * the external LED alone when the diags are running */ - if (ipath_diag_inuse) - return; - - /* Allow override of LED display for, e.g. Locating system in rack */ - if (dd->ipath_led_override) { - ltst = (dd->ipath_led_override & IPATH_LED_PHYS) - ? INFINIPATH_IBCS_LT_STATE_LINKUP - : INFINIPATH_IBCS_LT_STATE_DISABLED; - lst = (dd->ipath_led_override & IPATH_LED_LOG) - ? INFINIPATH_IBCS_L_STATE_ACTIVE - : INFINIPATH_IBCS_L_STATE_DOWN; - } - - spin_lock_irqsave(&dd->ipath_gpio_lock, flags); - extctl = dd->ipath_extctrl & ~(INFINIPATH_EXTC_LED1PRIPORT_ON | - INFINIPATH_EXTC_LED2PRIPORT_ON); - - if (ltst == INFINIPATH_IBCS_LT_STATE_LINKUP) - extctl |= INFINIPATH_EXTC_LED2PRIPORT_ON; - if (lst == INFINIPATH_IBCS_L_STATE_ACTIVE) - extctl |= INFINIPATH_EXTC_LED1PRIPORT_ON; - dd->ipath_extctrl = extctl; - ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, extctl); - spin_unlock_irqrestore(&dd->ipath_gpio_lock, flags); -} - -/** - * ipath_setup_pe_cleanup - clean up any per-chip chip-specific stuff - * @dd: the infinipath device - * - * This is called during driver unload. - * We do the pci_disable_msi here, not in generic code, because it - * isn't used for the HT chips. If we do end up needing pci_enable_msi - * at some point in the future for HT, we'll move the call back - * into the main init_one code. - */ -static void ipath_setup_pe_cleanup(struct ipath_devdata *dd) -{ - dd->ipath_msi_lo = 0; /* just in case unload fails */ - pci_disable_msi(dd->pcidev); -} - -static void ipath_6120_pcie_params(struct ipath_devdata *dd) -{ - u16 linkstat, speed; - int pos; - - pos = pci_find_capability(dd->pcidev, PCI_CAP_ID_EXP); - if (!pos) { - ipath_dev_err(dd, "Can't find PCI Express capability!\n"); - goto bail; - } - - pci_read_config_word(dd->pcidev, pos + PCI_EXP_LNKSTA, - &linkstat); - /* - * speed is bits 0-4, linkwidth is bits 4-8 - * no defines for them in headers - */ - speed = linkstat & 0xf; - linkstat >>= 4; - linkstat &= 0x1f; - dd->ipath_lbus_width = linkstat; - - switch (speed) { - case 1: - dd->ipath_lbus_speed = 2500; /* Gen1, 2.5GHz */ - break; - case 2: - dd->ipath_lbus_speed = 5000; /* Gen1, 5GHz */ - break; - default: /* not defined, assume gen1 */ - dd->ipath_lbus_speed = 2500; - break; - } - - if (linkstat < 8) - ipath_dev_err(dd, - "PCIe width %u (x8 HCA), performance reduced\n", - linkstat); - else - ipath_cdbg(VERBOSE, "PCIe speed %u width %u (x8 HCA)\n", - dd->ipath_lbus_speed, linkstat); - - if (speed != 1) - ipath_dev_err(dd, - "PCIe linkspeed %u is incorrect; " - "should be 1 (2500)!\n", speed); -bail: - /* fill in string, even on errors */ - snprintf(dd->ipath_lbus_info, sizeof(dd->ipath_lbus_info), - "PCIe,%uMHz,x%u\n", - dd->ipath_lbus_speed, - dd->ipath_lbus_width); - - return; -} - -/** - * ipath_setup_pe_config - setup PCIe config related stuff - * @dd: the infinipath device - * @pdev: the PCI device - * - * The pci_enable_msi() call will fail on systems with MSI quirks - * such as those with AMD8131, even if the device of interest is not - * attached to that device, (in the 2.6.13 - 2.6.15 kernels, at least, fixed - * late in 2.6.16). - * All that can be done is to edit the kernel source to remove the quirk - * check until that is fixed. - * We do not need to call enable_msi() for our HyperTransport chip, - * even though it uses MSI, and we want to avoid the quirk warning, so - * So we call enable_msi only for PCIe. If we do end up needing - * pci_enable_msi at some point in the future for HT, we'll move the - * call back into the main init_one code. - * We save the msi lo and hi values, so we can restore them after - * chip reset (the kernel PCI infrastructure doesn't yet handle that - * correctly). - */ -static int ipath_setup_pe_config(struct ipath_devdata *dd, - struct pci_dev *pdev) -{ - int pos, ret; - - dd->ipath_msi_lo = 0; /* used as a flag during reset processing */ - ret = pci_enable_msi(dd->pcidev); - if (ret) - ipath_dev_err(dd, "pci_enable_msi failed: %d, " - "interrupts may not work\n", ret); - /* continue even if it fails, we may still be OK... */ - dd->ipath_irq = pdev->irq; - - if ((pos = pci_find_capability(dd->pcidev, PCI_CAP_ID_MSI))) { - u16 control; - pci_read_config_dword(dd->pcidev, pos + PCI_MSI_ADDRESS_LO, - &dd->ipath_msi_lo); - pci_read_config_dword(dd->pcidev, pos + PCI_MSI_ADDRESS_HI, - &dd->ipath_msi_hi); - pci_read_config_word(dd->pcidev, pos + PCI_MSI_FLAGS, - &control); - /* now save the data (vector) info */ - pci_read_config_word(dd->pcidev, - pos + ((control & PCI_MSI_FLAGS_64BIT) - ? 12 : 8), - &dd->ipath_msi_data); - ipath_cdbg(VERBOSE, "Read msi data 0x%x from config offset " - "0x%x, control=0x%x\n", dd->ipath_msi_data, - pos + ((control & PCI_MSI_FLAGS_64BIT) ? 12 : 8), - control); - /* we save the cachelinesize also, although it doesn't - * really matter */ - pci_read_config_byte(dd->pcidev, PCI_CACHE_LINE_SIZE, - &dd->ipath_pci_cacheline); - } else - ipath_dev_err(dd, "Can't find MSI capability, " - "can't save MSI settings for reset\n"); - - ipath_6120_pcie_params(dd); - - dd->ipath_link_width_supported = IB_WIDTH_1X | IB_WIDTH_4X; - dd->ipath_link_speed_supported = IPATH_IB_SDR; - dd->ipath_link_width_enabled = IB_WIDTH_4X; - dd->ipath_link_speed_enabled = dd->ipath_link_speed_supported; - /* these can't change for this chip, so set once */ - dd->ipath_link_width_active = dd->ipath_link_width_enabled; - dd->ipath_link_speed_active = dd->ipath_link_speed_enabled; - return 0; -} - -static void ipath_init_pe_variables(struct ipath_devdata *dd) -{ - /* - * setup the register offsets, since they are different for each - * chip - */ - dd->ipath_kregs = &ipath_pe_kregs; - dd->ipath_cregs = &ipath_pe_cregs; - - /* - * bits for selecting i2c direction and values, - * used for I2C serial flash - */ - dd->ipath_gpio_sda_num = _IPATH_GPIO_SDA_NUM; - dd->ipath_gpio_scl_num = _IPATH_GPIO_SCL_NUM; - dd->ipath_gpio_sda = IPATH_GPIO_SDA; - dd->ipath_gpio_scl = IPATH_GPIO_SCL; - - /* - * Fill in data for field-values that change in newer chips. - * We dynamically specify only the mask for LINKTRAININGSTATE - * and only the shift for LINKSTATE, as they are the only ones - * that change. Also precalculate the 3 link states of interest - * and the combined mask. - */ - dd->ibcs_ls_shift = IBA6120_IBCS_LINKSTATE_SHIFT; - dd->ibcs_lts_mask = IBA6120_IBCS_LINKTRAININGSTATE_MASK; - dd->ibcs_mask = (INFINIPATH_IBCS_LINKSTATE_MASK << - dd->ibcs_ls_shift) | dd->ibcs_lts_mask; - dd->ib_init = (INFINIPATH_IBCS_LT_STATE_LINKUP << - INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | - (INFINIPATH_IBCS_L_STATE_INIT << dd->ibcs_ls_shift); - dd->ib_arm = (INFINIPATH_IBCS_LT_STATE_LINKUP << - INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | - (INFINIPATH_IBCS_L_STATE_ARM << dd->ibcs_ls_shift); - dd->ib_active = (INFINIPATH_IBCS_LT_STATE_LINKUP << - INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | - (INFINIPATH_IBCS_L_STATE_ACTIVE << dd->ibcs_ls_shift); - - /* - * Fill in data for ibcc field-values that change in newer chips. - * We dynamically specify only the mask for LINKINITCMD - * and only the shift for LINKCMD and MAXPKTLEN, as they are - * the only ones that change. - */ - dd->ibcc_lic_mask = INFINIPATH_IBCC_LINKINITCMD_MASK; - dd->ibcc_lc_shift = INFINIPATH_IBCC_LINKCMD_SHIFT; - dd->ibcc_mpl_shift = INFINIPATH_IBCC_MAXPKTLEN_SHIFT; - - /* Fill in shifts for RcvCtrl. */ - dd->ipath_r_portenable_shift = INFINIPATH_R_PORTENABLE_SHIFT; - dd->ipath_r_intravail_shift = INFINIPATH_R_INTRAVAIL_SHIFT; - dd->ipath_r_tailupd_shift = INFINIPATH_R_TAILUPD_SHIFT; - dd->ipath_r_portcfg_shift = 0; /* Not on IBA6120 */ - - /* variables for sanity checking interrupt and errors */ - dd->ipath_hwe_bitsextant = - (INFINIPATH_HWE_RXEMEMPARITYERR_MASK << - INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT) | - (INFINIPATH_HWE_TXEMEMPARITYERR_MASK << - INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) | - (INFINIPATH_HWE_PCIEMEMPARITYERR_MASK << - INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT) | - INFINIPATH_HWE_PCIE1PLLFAILED | - INFINIPATH_HWE_PCIE0PLLFAILED | - INFINIPATH_HWE_PCIEPOISONEDTLP | - INFINIPATH_HWE_PCIECPLTIMEOUT | - INFINIPATH_HWE_PCIEBUSPARITYXTLH | - INFINIPATH_HWE_PCIEBUSPARITYXADM | - INFINIPATH_HWE_PCIEBUSPARITYRADM | - INFINIPATH_HWE_MEMBISTFAILED | - INFINIPATH_HWE_COREPLL_FBSLIP | - INFINIPATH_HWE_COREPLL_RFSLIP | - INFINIPATH_HWE_SERDESPLLFAILED | - INFINIPATH_HWE_IBCBUSTOSPCPARITYERR | - INFINIPATH_HWE_IBCBUSFRSPCPARITYERR; - dd->ipath_i_bitsextant = - (INFINIPATH_I_RCVURG_MASK << INFINIPATH_I_RCVURG_SHIFT) | - (INFINIPATH_I_RCVAVAIL_MASK << - INFINIPATH_I_RCVAVAIL_SHIFT) | - INFINIPATH_I_ERROR | INFINIPATH_I_SPIOSENT | - INFINIPATH_I_SPIOBUFAVAIL | INFINIPATH_I_GPIO; - dd->ipath_e_bitsextant = - INFINIPATH_E_RFORMATERR | INFINIPATH_E_RVCRC | - INFINIPATH_E_RICRC | INFINIPATH_E_RMINPKTLEN | - INFINIPATH_E_RMAXPKTLEN | INFINIPATH_E_RLONGPKTLEN | - INFINIPATH_E_RSHORTPKTLEN | INFINIPATH_E_RUNEXPCHAR | - INFINIPATH_E_RUNSUPVL | INFINIPATH_E_REBP | - INFINIPATH_E_RIBFLOW | INFINIPATH_E_RBADVERSION | - INFINIPATH_E_RRCVEGRFULL | INFINIPATH_E_RRCVHDRFULL | - INFINIPATH_E_RBADTID | INFINIPATH_E_RHDRLEN | - INFINIPATH_E_RHDR | INFINIPATH_E_RIBLOSTLINK | - INFINIPATH_E_SMINPKTLEN | INFINIPATH_E_SMAXPKTLEN | - INFINIPATH_E_SUNDERRUN | INFINIPATH_E_SPKTLEN | - INFINIPATH_E_SDROPPEDSMPPKT | INFINIPATH_E_SDROPPEDDATAPKT | - INFINIPATH_E_SPIOARMLAUNCH | INFINIPATH_E_SUNEXPERRPKTNUM | - INFINIPATH_E_SUNSUPVL | INFINIPATH_E_IBSTATUSCHANGED | - INFINIPATH_E_INVALIDADDR | INFINIPATH_E_RESET | - INFINIPATH_E_HARDWARE; - - dd->ipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK; - dd->ipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK; - dd->ipath_i_rcvavail_shift = INFINIPATH_I_RCVAVAIL_SHIFT; - dd->ipath_i_rcvurg_shift = INFINIPATH_I_RCVURG_SHIFT; - - /* - * EEPROM error log 0 is TXE Parity errors. 1 is RXE Parity. - * 2 is Some Misc, 3 is reserved for future. - */ - dd->ipath_eep_st_masks[0].hwerrs_to_log = - INFINIPATH_HWE_TXEMEMPARITYERR_MASK << - INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT; - - /* Ignore errors in PIO/PBC on systems with unordered write-combining */ - if (ipath_unordered_wc()) - dd->ipath_eep_st_masks[0].hwerrs_to_log &= ~TXE_PIO_PARITY; - - dd->ipath_eep_st_masks[1].hwerrs_to_log = - INFINIPATH_HWE_RXEMEMPARITYERR_MASK << - INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT; - - dd->ipath_eep_st_masks[2].errs_to_log = INFINIPATH_E_RESET; - dd->delay_mult = 2; /* SDR, 4X, can't change */ -} - -/* setup the MSI stuff again after a reset. I'd like to just call - * pci_enable_msi() and request_irq() again, but when I do that, - * the MSI enable bit doesn't get set in the command word, and - * we switch to to a different interrupt vector, which is confusing, - * so I instead just do it all inline. Perhaps somehow can tie this - * into the PCIe hotplug support at some point - * Note, because I'm doing it all here, I don't call pci_disable_msi() - * or free_irq() at the start of ipath_setup_pe_reset(). - */ -static int ipath_reinit_msi(struct ipath_devdata *dd) -{ - int pos; - u16 control; - int ret; - - if (!dd->ipath_msi_lo) { - dev_info(&dd->pcidev->dev, "Can't restore MSI config, " - "initial setup failed?\n"); - ret = 0; - goto bail; - } - - if (!(pos = pci_find_capability(dd->pcidev, PCI_CAP_ID_MSI))) { - ipath_dev_err(dd, "Can't find MSI capability, " - "can't restore MSI settings\n"); - ret = 0; - goto bail; - } - ipath_cdbg(VERBOSE, "Writing msi_lo 0x%x to config offset 0x%x\n", - dd->ipath_msi_lo, pos + PCI_MSI_ADDRESS_LO); - pci_write_config_dword(dd->pcidev, pos + PCI_MSI_ADDRESS_LO, - dd->ipath_msi_lo); - ipath_cdbg(VERBOSE, "Writing msi_lo 0x%x to config offset 0x%x\n", - dd->ipath_msi_hi, pos + PCI_MSI_ADDRESS_HI); - pci_write_config_dword(dd->pcidev, pos + PCI_MSI_ADDRESS_HI, - dd->ipath_msi_hi); - pci_read_config_word(dd->pcidev, pos + PCI_MSI_FLAGS, &control); - if (!(control & PCI_MSI_FLAGS_ENABLE)) { - ipath_cdbg(VERBOSE, "MSI control at off %x was %x, " - "setting MSI enable (%x)\n", pos + PCI_MSI_FLAGS, - control, control | PCI_MSI_FLAGS_ENABLE); - control |= PCI_MSI_FLAGS_ENABLE; - pci_write_config_word(dd->pcidev, pos + PCI_MSI_FLAGS, - control); - } - /* now rewrite the data (vector) info */ - pci_write_config_word(dd->pcidev, pos + - ((control & PCI_MSI_FLAGS_64BIT) ? 12 : 8), - dd->ipath_msi_data); - /* we restore the cachelinesize also, although it doesn't really - * matter */ - pci_write_config_byte(dd->pcidev, PCI_CACHE_LINE_SIZE, - dd->ipath_pci_cacheline); - /* and now set the pci master bit again */ - pci_set_master(dd->pcidev); - ret = 1; - -bail: - return ret; -} - -/* This routine sleeps, so it can only be called from user context, not - * from interrupt context. If we need interrupt context, we can split - * it into two routines. -*/ -static int ipath_setup_pe_reset(struct ipath_devdata *dd) -{ - u64 val; - int i; - int ret; - u16 cmdval; - - pci_read_config_word(dd->pcidev, PCI_COMMAND, &cmdval); - - /* Use ERROR so it shows up in logs, etc. */ - ipath_dev_err(dd, "Resetting InfiniPath unit %u\n", dd->ipath_unit); - /* keep chip from being accessed in a few places */ - dd->ipath_flags &= ~(IPATH_INITTED|IPATH_PRESENT); - val = dd->ipath_control | INFINIPATH_C_RESET; - ipath_write_kreg(dd, dd->ipath_kregs->kr_control, val); - mb(); - - for (i = 1; i <= 5; i++) { - int r; - /* allow MBIST, etc. to complete; longer on each retry. - * We sometimes get machine checks from bus timeout if no - * response, so for now, make it *really* long. - */ - msleep(1000 + (1 + i) * 2000); - if ((r = - pci_write_config_dword(dd->pcidev, PCI_BASE_ADDRESS_0, - dd->ipath_pcibar0))) - ipath_dev_err(dd, "rewrite of BAR0 failed: %d\n", - r); - if ((r = - pci_write_config_dword(dd->pcidev, PCI_BASE_ADDRESS_1, - dd->ipath_pcibar1))) - ipath_dev_err(dd, "rewrite of BAR1 failed: %d\n", - r); - /* now re-enable memory access */ - pci_write_config_word(dd->pcidev, PCI_COMMAND, cmdval); - if ((r = pci_enable_device(dd->pcidev))) - ipath_dev_err(dd, "pci_enable_device failed after " - "reset: %d\n", r); - /* - * whether it fully enabled or not, mark as present, - * again (but not INITTED) - */ - dd->ipath_flags |= IPATH_PRESENT; - val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_revision); - if (val == dd->ipath_revision) { - ipath_cdbg(VERBOSE, "Got matching revision " - "register %llx on try %d\n", - (unsigned long long) val, i); - ret = ipath_reinit_msi(dd); - goto bail; - } - /* Probably getting -1 back */ - ipath_dbg("Didn't get expected revision register, " - "got %llx, try %d\n", (unsigned long long) val, - i + 1); - } - ret = 0; /* failed */ - -bail: - if (ret) - ipath_6120_pcie_params(dd); - return ret; -} - -/** - * ipath_pe_put_tid - write a TID in chip - * @dd: the infinipath device - * @tidptr: pointer to the expected TID (in chip) to update - * @tidtype: RCVHQ_RCV_TYPE_EAGER (1) for eager, RCVHQ_RCV_TYPE_EXPECTED (0) for expected - * @pa: physical address of in memory buffer; ipath_tidinvalid if freeing - * - * This exists as a separate routine to allow for special locking etc. - * It's used for both the full cleanup on exit, as well as the normal - * setup and teardown. - */ -static void ipath_pe_put_tid(struct ipath_devdata *dd, u64 __iomem *tidptr, - u32 type, unsigned long pa) -{ - u32 __iomem *tidp32 = (u32 __iomem *)tidptr; - unsigned long flags = 0; /* keep gcc quiet */ - int tidx; - spinlock_t *tidlockp; - - if (!dd->ipath_kregbase) - return; - - if (pa != dd->ipath_tidinvalid) { - if (pa & ((1U << 11) - 1)) { - dev_info(&dd->pcidev->dev, "BUG: physaddr %lx " - "not 2KB aligned!\n", pa); - return; - } - pa >>= 11; - /* paranoia check */ - if (pa & ~INFINIPATH_RT_ADDR_MASK) - ipath_dev_err(dd, - "BUG: Physical page address 0x%lx " - "has bits set in 31-29\n", pa); - - if (type == RCVHQ_RCV_TYPE_EAGER) - pa |= dd->ipath_tidtemplate; - else /* for now, always full 4KB page */ - pa |= 2 << 29; - } - - /* - * Workaround chip bug 9437 by writing the scratch register - * before and after the TID, and with an io write barrier. - * We use a spinlock around the writes, so they can't intermix - * with other TID (eager or expected) writes (the chip bug - * is triggered by back to back TID writes). Unfortunately, this - * call can be done from interrupt level for the port 0 eager TIDs, - * so we have to use irqsave locks. - */ - /* - * Assumes tidptr always > ipath_egrtidbase - * if type == RCVHQ_RCV_TYPE_EAGER. - */ - tidx = tidptr - dd->ipath_egrtidbase; - - tidlockp = (type == RCVHQ_RCV_TYPE_EAGER && tidx < dd->ipath_rcvegrcnt) - ? &dd->ipath_kernel_tid_lock : &dd->ipath_user_tid_lock; - spin_lock_irqsave(tidlockp, flags); - ipath_write_kreg(dd, dd->ipath_kregs->kr_scratch, 0xfeeddeaf); - writel(pa, tidp32); - ipath_write_kreg(dd, dd->ipath_kregs->kr_scratch, 0xdeadbeef); - mmiowb(); - spin_unlock_irqrestore(tidlockp, flags); -} - -/** - * ipath_pe_put_tid_2 - write a TID in chip, Revision 2 or higher - * @dd: the infinipath device - * @tidptr: pointer to the expected TID (in chip) to update - * @tidtype: RCVHQ_RCV_TYPE_EAGER (1) for eager, RCVHQ_RCV_TYPE_EXPECTED (0) for expected - * @pa: physical address of in memory buffer; ipath_tidinvalid if freeing - * - * This exists as a separate routine to allow for selection of the - * appropriate "flavor". The static calls in cleanup just use the - * revision-agnostic form, as they are not performance critical. - */ -static void ipath_pe_put_tid_2(struct ipath_devdata *dd, u64 __iomem *tidptr, - u32 type, unsigned long pa) -{ - u32 __iomem *tidp32 = (u32 __iomem *)tidptr; - u32 tidx; - - if (!dd->ipath_kregbase) - return; - - if (pa != dd->ipath_tidinvalid) { - if (pa & ((1U << 11) - 1)) { - dev_info(&dd->pcidev->dev, "BUG: physaddr %lx " - "not 2KB aligned!\n", pa); - return; - } - pa >>= 11; - /* paranoia check */ - if (pa & ~INFINIPATH_RT_ADDR_MASK) - ipath_dev_err(dd, - "BUG: Physical page address 0x%lx " - "has bits set in 31-29\n", pa); - - if (type == RCVHQ_RCV_TYPE_EAGER) - pa |= dd->ipath_tidtemplate; - else /* for now, always full 4KB page */ - pa |= 2 << 29; - } - tidx = tidptr - dd->ipath_egrtidbase; - writel(pa, tidp32); - mmiowb(); -} - - -/** - * ipath_pe_clear_tid - clear all TID entries for a port, expected and eager - * @dd: the infinipath device - * @port: the port - * - * clear all TID entries for a port, expected and eager. - * Used from ipath_close(). On this chip, TIDs are only 32 bits, - * not 64, but they are still on 64 bit boundaries, so tidbase - * is declared as u64 * for the pointer math, even though we write 32 bits - */ -static void ipath_pe_clear_tids(struct ipath_devdata *dd, unsigned port) -{ - u64 __iomem *tidbase; - unsigned long tidinv; - int i; - - if (!dd->ipath_kregbase) - return; - - ipath_cdbg(VERBOSE, "Invalidate TIDs for port %u\n", port); - - tidinv = dd->ipath_tidinvalid; - tidbase = (u64 __iomem *) - ((char __iomem *)(dd->ipath_kregbase) + - dd->ipath_rcvtidbase + - port * dd->ipath_rcvtidcnt * sizeof(*tidbase)); - - for (i = 0; i < dd->ipath_rcvtidcnt; i++) - dd->ipath_f_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EXPECTED, - tidinv); - - tidbase = (u64 __iomem *) - ((char __iomem *)(dd->ipath_kregbase) + - dd->ipath_rcvegrbase + - port * dd->ipath_rcvegrcnt * sizeof(*tidbase)); - - for (i = 0; i < dd->ipath_rcvegrcnt; i++) - dd->ipath_f_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EAGER, - tidinv); -} - -/** - * ipath_pe_tidtemplate - setup constants for TID updates - * @dd: the infinipath device - * - * We setup stuff that we use a lot, to avoid calculating each time - */ -static void ipath_pe_tidtemplate(struct ipath_devdata *dd) -{ - u32 egrsize = dd->ipath_rcvegrbufsize; - - /* For now, we always allocate 4KB buffers (at init) so we can - * receive max size packets. We may want a module parameter to - * specify 2KB or 4KB and/or make be per port instead of per device - * for those who want to reduce memory footprint. Note that the - * ipath_rcvhdrentsize size must be large enough to hold the largest - * IB header (currently 96 bytes) that we expect to handle (plus of - * course the 2 dwords of RHF). - */ - if (egrsize == 2048) - dd->ipath_tidtemplate = 1U << 29; - else if (egrsize == 4096) - dd->ipath_tidtemplate = 2U << 29; - else { - egrsize = 4096; - dev_info(&dd->pcidev->dev, "BUG: unsupported egrbufsize " - "%u, using %u\n", dd->ipath_rcvegrbufsize, - egrsize); - dd->ipath_tidtemplate = 2U << 29; - } - dd->ipath_tidinvalid = 0; -} - -static int ipath_pe_early_init(struct ipath_devdata *dd) -{ - dd->ipath_flags |= IPATH_4BYTE_TID; - if (ipath_unordered_wc()) - dd->ipath_flags |= IPATH_PIO_FLUSH_WC; - - /* - * For openfabrics, we need to be able to handle an IB header of - * 24 dwords. HT chip has arbitrary sized receive buffers, so we - * made them the same size as the PIO buffers. This chip does not - * handle arbitrary size buffers, so we need the header large enough - * to handle largest IB header, but still have room for a 2KB MTU - * standard IB packet. - */ - dd->ipath_rcvhdrentsize = 24; - dd->ipath_rcvhdrsize = IPATH_DFLT_RCVHDRSIZE; - dd->ipath_rhf_offset = 0; - dd->ipath_egrtidbase = (u64 __iomem *) - ((char __iomem *) dd->ipath_kregbase + dd->ipath_rcvegrbase); - - dd->ipath_rcvegrbufsize = ipath_mtu4096 ? 4096 : 2048; - /* - * the min() check here is currently a nop, but it may not always - * be, depending on just how we do ipath_rcvegrbufsize - */ - dd->ipath_ibmaxlen = min(ipath_mtu4096 ? dd->ipath_piosize4k : - dd->ipath_piosize2k, - dd->ipath_rcvegrbufsize + - (dd->ipath_rcvhdrentsize << 2)); - dd->ipath_init_ibmaxlen = dd->ipath_ibmaxlen; - - /* - * We can request a receive interrupt for 1 or - * more packets from current offset. For now, we set this - * up for a single packet. - */ - dd->ipath_rhdrhead_intr_off = 1ULL<<32; - - ipath_get_eeprom_info(dd); - - return 0; -} - -int __attribute__((weak)) ipath_unordered_wc(void) -{ - return 0; -} - -/** - * ipath_init_pe_get_base_info - set chip-specific flags for user code - * @pd: the infinipath port - * @kbase: ipath_base_info pointer - * - * We set the PCIE flag because the lower bandwidth on PCIe vs - * HyperTransport can affect some user packet algorithms. - */ -static int ipath_pe_get_base_info(struct ipath_portdata *pd, void *kbase) -{ - struct ipath_base_info *kinfo = kbase; - struct ipath_devdata *dd; - - if (ipath_unordered_wc()) { - kinfo->spi_runtime_flags |= IPATH_RUNTIME_FORCE_WC_ORDER; - ipath_cdbg(PROC, "Intel processor, forcing WC order\n"); - } - else - ipath_cdbg(PROC, "Not Intel processor, WC ordered\n"); - - if (pd == NULL) - goto done; - - dd = pd->port_dd; - -done: - kinfo->spi_runtime_flags |= IPATH_RUNTIME_PCIE | - IPATH_RUNTIME_FORCE_PIOAVAIL | IPATH_RUNTIME_PIO_REGSWAPPED; - return 0; -} - -static void ipath_pe_free_irq(struct ipath_devdata *dd) -{ - free_irq(dd->ipath_irq, dd); - dd->ipath_irq = 0; -} - - -static struct ipath_message_header * -ipath_pe_get_msgheader(struct ipath_devdata *dd, __le32 *rhf_addr) -{ - return (struct ipath_message_header *) - &rhf_addr[sizeof(u64) / sizeof(u32)]; -} - -static void ipath_pe_config_ports(struct ipath_devdata *dd, ushort cfgports) -{ - dd->ipath_portcnt = - ipath_read_kreg32(dd, dd->ipath_kregs->kr_portcnt); - dd->ipath_p0_rcvegrcnt = - ipath_read_kreg32(dd, dd->ipath_kregs->kr_rcvegrcnt); -} - -static void ipath_pe_read_counters(struct ipath_devdata *dd, - struct infinipath_counters *cntrs) -{ - cntrs->LBIntCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(LBIntCnt)); - cntrs->LBFlowStallCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(LBFlowStallCnt)); - cntrs->TxSDmaDescCnt = 0; - cntrs->TxUnsupVLErrCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxUnsupVLErrCnt)); - cntrs->TxDataPktCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxDataPktCnt)); - cntrs->TxFlowPktCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxFlowPktCnt)); - cntrs->TxDwordCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxDwordCnt)); - cntrs->TxLenErrCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxLenErrCnt)); - cntrs->TxMaxMinLenErrCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxMaxMinLenErrCnt)); - cntrs->TxUnderrunCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxUnderrunCnt)); - cntrs->TxFlowStallCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxFlowStallCnt)); - cntrs->TxDroppedPktCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(TxDroppedPktCnt)); - cntrs->RxDroppedPktCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxDroppedPktCnt)); - cntrs->RxDataPktCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxDataPktCnt)); - cntrs->RxFlowPktCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxFlowPktCnt)); - cntrs->RxDwordCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxDwordCnt)); - cntrs->RxLenErrCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxLenErrCnt)); - cntrs->RxMaxMinLenErrCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxMaxMinLenErrCnt)); - cntrs->RxICRCErrCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxICRCErrCnt)); - cntrs->RxVCRCErrCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxVCRCErrCnt)); - cntrs->RxFlowCtrlErrCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxFlowCtrlErrCnt)); - cntrs->RxBadFormatCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxBadFormatCnt)); - cntrs->RxLinkProblemCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxLinkProblemCnt)); - cntrs->RxEBPCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxEBPCnt)); - cntrs->RxLPCRCErrCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxLPCRCErrCnt)); - cntrs->RxBufOvflCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxBufOvflCnt)); - cntrs->RxTIDFullErrCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxTIDFullErrCnt)); - cntrs->RxTIDValidErrCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxTIDValidErrCnt)); - cntrs->RxPKeyMismatchCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxPKeyMismatchCnt)); - cntrs->RxP0HdrEgrOvflCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP0HdrEgrOvflCnt)); - cntrs->RxP1HdrEgrOvflCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP1HdrEgrOvflCnt)); - cntrs->RxP2HdrEgrOvflCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP2HdrEgrOvflCnt)); - cntrs->RxP3HdrEgrOvflCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP3HdrEgrOvflCnt)); - cntrs->RxP4HdrEgrOvflCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(RxP4HdrEgrOvflCnt)); - cntrs->RxP5HdrEgrOvflCnt = 0; - cntrs->RxP6HdrEgrOvflCnt = 0; - cntrs->RxP7HdrEgrOvflCnt = 0; - cntrs->RxP8HdrEgrOvflCnt = 0; - cntrs->RxP9HdrEgrOvflCnt = 0; - cntrs->RxP10HdrEgrOvflCnt = 0; - cntrs->RxP11HdrEgrOvflCnt = 0; - cntrs->RxP12HdrEgrOvflCnt = 0; - cntrs->RxP13HdrEgrOvflCnt = 0; - cntrs->RxP14HdrEgrOvflCnt = 0; - cntrs->RxP15HdrEgrOvflCnt = 0; - cntrs->RxP16HdrEgrOvflCnt = 0; - cntrs->IBStatusChangeCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(IBStatusChangeCnt)); - cntrs->IBLinkErrRecoveryCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(IBLinkErrRecoveryCnt)); - cntrs->IBLinkDownedCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(IBLinkDownedCnt)); - cntrs->IBSymbolErrCnt = - ipath_snap_cntr(dd, IPATH_CREG_OFFSET(IBSymbolErrCnt)); - cntrs->RxVL15DroppedPktCnt = 0; - cntrs->RxOtherLocalPhyErrCnt = 0; - cntrs->PcieRetryBufDiagQwordCnt = 0; - cntrs->ExcessBufferOvflCnt = dd->ipath_overrun_thresh_errs; - cntrs->LocalLinkIntegrityErrCnt = dd->ipath_lli_errs; - cntrs->RxVlErrCnt = 0; - cntrs->RxDlidFltrCnt = 0; -} - - -/* no interrupt fallback for these chips */ -static int ipath_pe_nointr_fallback(struct ipath_devdata *dd) -{ - return 0; -} - - -/* - * reset the XGXS (between serdes and IBC). Slightly less intrusive - * than resetting the IBC or external link state, and useful in some - * cases to cause some retraining. To do this right, we reset IBC - * as well. - */ -static void ipath_pe_xgxs_reset(struct ipath_devdata *dd) -{ - u64 val, prev_val; - - prev_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig); - val = prev_val | INFINIPATH_XGXS_RESET; - prev_val &= ~INFINIPATH_XGXS_RESET; /* be sure */ - ipath_write_kreg(dd, dd->ipath_kregs->kr_control, - dd->ipath_control & ~INFINIPATH_C_LINKENABLE); - ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val); - ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); - ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, prev_val); - ipath_write_kreg(dd, dd->ipath_kregs->kr_control, - dd->ipath_control); -} - - -static int ipath_pe_get_ib_cfg(struct ipath_devdata *dd, int which) -{ - int ret; - - switch (which) { - case IPATH_IB_CFG_LWID: - ret = dd->ipath_link_width_active; - break; - case IPATH_IB_CFG_SPD: - ret = dd->ipath_link_speed_active; - break; - case IPATH_IB_CFG_LWID_ENB: - ret = dd->ipath_link_width_enabled; - break; - case IPATH_IB_CFG_SPD_ENB: - ret = dd->ipath_link_speed_enabled; - break; - default: - ret = -ENOTSUPP; - break; - } - return ret; -} - - -/* we assume range checking is already done, if needed */ -static int ipath_pe_set_ib_cfg(struct ipath_devdata *dd, int which, u32 val) -{ - int ret = 0; - - if (which == IPATH_IB_CFG_LWID_ENB) - dd->ipath_link_width_enabled = val; - else if (which == IPATH_IB_CFG_SPD_ENB) - dd->ipath_link_speed_enabled = val; - else - ret = -ENOTSUPP; - return ret; -} - -static void ipath_pe_config_jint(struct ipath_devdata *dd, u16 a, u16 b) -{ -} - - -static int ipath_pe_ib_updown(struct ipath_devdata *dd, int ibup, u64 ibcs) -{ - if (ibup) { - if (dd->ibdeltainprog) { - dd->ibdeltainprog = 0; - dd->ibsymdelta += - ipath_read_creg32(dd, - dd->ipath_cregs->cr_ibsymbolerrcnt) - - dd->ibsymsnap; - dd->iblnkerrdelta += - ipath_read_creg32(dd, - dd->ipath_cregs->cr_iblinkerrrecovcnt) - - dd->iblnkerrsnap; - } - } else { - dd->ipath_lli_counter = 0; - if (!dd->ibdeltainprog) { - dd->ibdeltainprog = 1; - dd->ibsymsnap = - ipath_read_creg32(dd, - dd->ipath_cregs->cr_ibsymbolerrcnt); - dd->iblnkerrsnap = - ipath_read_creg32(dd, - dd->ipath_cregs->cr_iblinkerrrecovcnt); - } - } - - ipath_setup_pe_setextled(dd, ipath_ib_linkstate(dd, ibcs), - ipath_ib_linktrstate(dd, ibcs)); - return 0; -} - - -/** - * ipath_init_iba6120_funcs - set up the chip-specific function pointers - * @dd: the infinipath device - * - * This is global, and is called directly at init to set up the - * chip-specific function pointers for later use. - */ -void ipath_init_iba6120_funcs(struct ipath_devdata *dd) -{ - dd->ipath_f_intrsetup = ipath_pe_intconfig; - dd->ipath_f_bus = ipath_setup_pe_config; - dd->ipath_f_reset = ipath_setup_pe_reset; - dd->ipath_f_get_boardname = ipath_pe_boardname; - dd->ipath_f_init_hwerrors = ipath_pe_init_hwerrors; - dd->ipath_f_early_init = ipath_pe_early_init; - dd->ipath_f_handle_hwerrors = ipath_pe_handle_hwerrors; - dd->ipath_f_quiet_serdes = ipath_pe_quiet_serdes; - dd->ipath_f_bringup_serdes = ipath_pe_bringup_serdes; - dd->ipath_f_clear_tids = ipath_pe_clear_tids; - /* - * _f_put_tid may get changed after we read the chip revision, - * but we start with the safe version for all revs - */ - dd->ipath_f_put_tid = ipath_pe_put_tid; - dd->ipath_f_cleanup = ipath_setup_pe_cleanup; - dd->ipath_f_setextled = ipath_setup_pe_setextled; - dd->ipath_f_get_base_info = ipath_pe_get_base_info; - dd->ipath_f_free_irq = ipath_pe_free_irq; - dd->ipath_f_tidtemplate = ipath_pe_tidtemplate; - dd->ipath_f_intr_fallback = ipath_pe_nointr_fallback; - dd->ipath_f_xgxs_reset = ipath_pe_xgxs_reset; - dd->ipath_f_get_msgheader = ipath_pe_get_msgheader; - dd->ipath_f_config_ports = ipath_pe_config_ports; - dd->ipath_f_read_counters = ipath_pe_read_counters; - dd->ipath_f_get_ib_cfg = ipath_pe_get_ib_cfg; - dd->ipath_f_set_ib_cfg = ipath_pe_set_ib_cfg; - dd->ipath_f_config_jint = ipath_pe_config_jint; - dd->ipath_f_ib_updown = ipath_pe_ib_updown; - - - /* initialize chip-specific variables */ - ipath_init_pe_variables(dd); -} - diff --git a/drivers/infiniband/hw/ipath/ipath_iba7220.c b/drivers/infiniband/hw/ipath/ipath_iba7220.c deleted file mode 100644 index 34b778ed97fc..000000000000 --- a/drivers/infiniband/hw/ipath/ipath_iba7220.c +++ /dev/null @@ -1,2631 +0,0 @@ -/* - * Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved. - * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -/* - * This file contains all of the code that is specific to the - * InfiniPath 7220 chip (except that specific to the SerDes) - */ - -#include -#include -#include -#include -#include -#include - -#include "ipath_kernel.h" -#include "ipath_registers.h" -#include "ipath_7220.h" - -static void ipath_setup_7220_setextled(struct ipath_devdata *, u64, u64); - -static unsigned ipath_compat_ddr_negotiate = 1; - -module_param_named(compat_ddr_negotiate, ipath_compat_ddr_negotiate, uint, - S_IWUSR | S_IRUGO); -MODULE_PARM_DESC(compat_ddr_negotiate, - "Attempt pre-IBTA 1.2 DDR speed negotiation"); - -static unsigned ipath_sdma_fetch_arb = 1; -module_param_named(fetch_arb, ipath_sdma_fetch_arb, uint, S_IRUGO); -MODULE_PARM_DESC(fetch_arb, "IBA7220: change SDMA descriptor arbitration"); - -/* - * This file contains almost all the chip-specific register information and - * access functions for the QLogic InfiniPath 7220 PCI-Express chip, with the - * exception of SerDes support, which in in ipath_sd7220.c. - * - * This lists the InfiniPath registers, in the actual chip layout. - * This structure should never be directly accessed. - */ -struct _infinipath_do_not_use_kernel_regs { - unsigned long long Revision; - unsigned long long Control; - unsigned long long PageAlign; - unsigned long long PortCnt; - unsigned long long DebugPortSelect; - unsigned long long DebugSigsIntSel; /* was Reserved0;*/ - unsigned long long SendRegBase; - unsigned long long UserRegBase; - unsigned long long CounterRegBase; - unsigned long long Scratch; - unsigned long long EEPROMAddrCmd; /* was Reserved1; */ - unsigned long long EEPROMData; /* was Reserved2; */ - unsigned long long IntBlocked; - unsigned long long IntMask; - unsigned long long IntStatus; - unsigned long long IntClear; - unsigned long long ErrorMask; - unsigned long long ErrorStatus; - unsigned long long ErrorClear; - unsigned long long HwErrMask; - unsigned long long HwErrStatus; - unsigned long long HwErrClear; - unsigned long long HwDiagCtrl; - unsigned long long MDIO; - unsigned long long IBCStatus; - unsigned long long IBCCtrl; - unsigned long long ExtStatus; - unsigned long long ExtCtrl; - unsigned long long GPIOOut; - unsigned long long GPIOMask; - unsigned long long GPIOStatus; - unsigned long long GPIOClear; - unsigned long long RcvCtrl; - unsigned long long RcvBTHQP; - unsigned long long RcvHdrSize; - unsigned long long RcvHdrCnt; - unsigned long long RcvHdrEntSize; - unsigned long long RcvTIDBase; - unsigned long long RcvTIDCnt; - unsigned long long RcvEgrBase; - unsigned long long RcvEgrCnt; - unsigned long long RcvBufBase; - unsigned long long RcvBufSize; - unsigned long long RxIntMemBase; - unsigned long long RxIntMemSize; - unsigned long long RcvPartitionKey; - unsigned long long RcvQPMulticastPort; - unsigned long long RcvPktLEDCnt; - unsigned long long IBCDDRCtrl; - unsigned long long HRTBT_GUID; - unsigned long long IB_SDTEST_IF_TX; - unsigned long long IB_SDTEST_IF_RX; - unsigned long long IBCDDRCtrl2; - unsigned long long IBCDDRStatus; - unsigned long long JIntReload; - unsigned long long IBNCModeCtrl; - unsigned long long SendCtrl; - unsigned long long SendBufBase; - unsigned long long SendBufSize; - unsigned long long SendBufCnt; - unsigned long long SendAvailAddr; - unsigned long long TxIntMemBase; - unsigned long long TxIntMemSize; - unsigned long long SendDmaBase; - unsigned long long SendDmaLenGen; - unsigned long long SendDmaTail; - unsigned long long SendDmaHead; - unsigned long long SendDmaHeadAddr; - unsigned long long SendDmaBufMask0; - unsigned long long SendDmaBufMask1; - unsigned long long SendDmaBufMask2; - unsigned long long SendDmaStatus; - unsigned long long SendBufferError; - unsigned long long SendBufferErrorCONT1; - unsigned long long SendBufErr2; /* was Reserved6SBE[0/6] */ - unsigned long long Reserved6L[2]; - unsigned long long AvailUpdCount; - unsigned long long RcvHdrAddr0; - unsigned long long RcvHdrAddrs[16]; /* Why enumerate? */ - unsigned long long Reserved7hdtl; /* Align next to 300 */ - unsigned long long RcvHdrTailAddr0; /* 300, like others */ - unsigned long long RcvHdrTailAddrs[16]; - unsigned long long Reserved9SW[7]; /* was [8]; we have 17 ports */ - unsigned long long IbsdEpbAccCtl; /* IB Serdes EPB access control */ - unsigned long long IbsdEpbTransReg; /* IB Serdes EPB Transaction */ - unsigned long long Reserved10sds; /* was SerdesStatus on */ - unsigned long long XGXSConfig; - unsigned long long IBSerDesCtrl; /* Was IBPLLCfg on Monty */ - unsigned long long EEPCtlStat; /* for "boot" EEPROM/FLASH */ - unsigned long long EEPAddrCmd; - unsigned long long EEPData; - unsigned long long PcieEpbAccCtl; - unsigned long long PcieEpbTransCtl; - unsigned long long EfuseCtl; /* E-Fuse control */ - unsigned long long EfuseData[4]; - unsigned long long ProcMon; - /* this chip moves following two from previous 200, 208 */ - unsigned long long PCIeRBufTestReg0; - unsigned long long PCIeRBufTestReg1; - /* added for this chip */ - unsigned long long PCIeRBufTestReg2; - unsigned long long PCIeRBufTestReg3; - /* added for this chip, debug only */ - unsigned long long SPC_JTAG_ACCESS_REG; - unsigned long long LAControlReg; - unsigned long long GPIODebugSelReg; - unsigned long long DebugPortValueReg; - /* added for this chip, DMA */ - unsigned long long SendDmaBufUsed[3]; - unsigned long long SendDmaReqTagUsed; - /* - * added for this chip, EFUSE: note that these program 64-bit - * words 2 and 3 */ - unsigned long long efuse_pgm_data[2]; - unsigned long long Reserved11LAalign[10]; /* Skip 4B0..4F8 */ - /* we have 30 regs for DDS and RXEQ in IB SERDES */ - unsigned long long SerDesDDSRXEQ[30]; - unsigned long long Reserved12LAalign[2]; /* Skip 5F0, 5F8 */ - /* added for LA debug support */ - unsigned long long LAMemory[32]; -}; - -struct _infinipath_do_not_use_counters { - __u64 LBIntCnt; - __u64 LBFlowStallCnt; - __u64 TxSDmaDescCnt; /* was Reserved1 */ - __u64 TxUnsupVLErrCnt; - __u64 TxDataPktCnt; - __u64 TxFlowPktCnt; - __u64 TxDwordCnt; - __u64 TxLenErrCnt; - __u64 TxMaxMinLenErrCnt; - __u64 TxUnderrunCnt; - __u64 TxFlowStallCnt; - __u64 TxDroppedPktCnt; - __u64 RxDroppedPktCnt; - __u64 RxDataPktCnt; - __u64 RxFlowPktCnt; - __u64 RxDwordCnt; - __u64 RxLenErrCnt; - __u64 RxMaxMinLenErrCnt; - __u64 RxICRCErrCnt; - __u64 RxVCRCErrCnt; - __u64 RxFlowCtrlErrCnt; - __u64 RxBadFormatCnt; - __u64 RxLinkProblemCnt; - __u64 RxEBPCnt; - __u64 RxLPCRCErrCnt; - __u64 RxBufOvflCnt; - __u64 RxTIDFullErrCnt; - __u64 RxTIDValidErrCnt; - __u64 RxPKeyMismatchCnt; - __u64 RxP0HdrEgrOvflCnt; - __u64 RxP1HdrEgrOvflCnt; - __u64 RxP2HdrEgrOvflCnt; - __u64 RxP3HdrEgrOvflCnt; - __u64 RxP4HdrEgrOvflCnt; - __u64 RxP5HdrEgrOvflCnt; - __u64 RxP6HdrEgrOvflCnt; - __u64 RxP7HdrEgrOvflCnt; - __u64 RxP8HdrEgrOvflCnt; - __u64 RxP9HdrEgrOvflCnt; /* was Reserved6 */ - __u64 RxP10HdrEgrOvflCnt; /* was Reserved7 */ - __u64 RxP11HdrEgrOvflCnt; /* new for IBA7220 */ - __u64 RxP12HdrEgrOvflCnt; /* new for IBA7220 */ - __u64 RxP13HdrEgrOvflCnt; /* new for IBA7220 */ - __u64 RxP14HdrEgrOvflCnt; /* new for IBA7220 */ - __u64 RxP15HdrEgrOvflCnt; /* new for IBA7220 */ - __u64 RxP16HdrEgrOvflCnt; /* new for IBA7220 */ - __u64 IBStatusChangeCnt; - __u64 IBLinkErrRecoveryCnt; - __u64 IBLinkDownedCnt; - __u64 IBSymbolErrCnt; - /* The following are new for IBA7220 */ - __u64 RxVL15DroppedPktCnt; - __u64 RxOtherLocalPhyErrCnt; - __u64 PcieRetryBufDiagQwordCnt; - __u64 ExcessBufferOvflCnt; - __u64 LocalLinkIntegrityErrCnt; - __u64 RxVlErrCnt; - __u64 RxDlidFltrCnt; - __u64 Reserved8[7]; - __u64 PSStat; - __u64 PSStart; - __u64 PSInterval; - __u64 PSRcvDataCount; - __u64 PSRcvPktsCount; - __u64 PSXmitDataCount; - __u64 PSXmitPktsCount; - __u64 PSXmitWaitCount; -}; - -#define IPATH_KREG_OFFSET(field) (offsetof( \ - struct _infinipath_do_not_use_kernel_regs, field) / sizeof(u64)) -#define IPATH_CREG_OFFSET(field) (offsetof( \ - struct _infinipath_do_not_use_counters, field) / sizeof(u64)) - -static const struct ipath_kregs ipath_7220_kregs = { - .kr_control = IPATH_KREG_OFFSET(Control), - .kr_counterregbase = IPATH_KREG_OFFSET(CounterRegBase), - .kr_debugportselect = IPATH_KREG_OFFSET(DebugPortSelect), - .kr_errorclear = IPATH_KREG_OFFSET(ErrorClear), - .kr_errormask = IPATH_KREG_OFFSET(ErrorMask), - .kr_errorstatus = IPATH_KREG_OFFSET(ErrorStatus), - .kr_extctrl = IPATH_KREG_OFFSET(ExtCtrl), - .kr_extstatus = IPATH_KREG_OFFSET(ExtStatus), - .kr_gpio_clear = IPATH_KREG_OFFSET(GPIOClear), - .kr_gpio_mask = IPATH_KREG_OFFSET(GPIOMask), - .kr_gpio_out = IPATH_KREG_OFFSET(GPIOOut), - .kr_gpio_status = IPATH_KREG_OFFSET(GPIOStatus), - .kr_hwdiagctrl = IPATH_KREG_OFFSET(HwDiagCtrl), - .kr_hwerrclear = IPATH_KREG_OFFSET(HwErrClear), - .kr_hwerrmask = IPATH_KREG_OFFSET(HwErrMask), - .kr_hwerrstatus = IPATH_KREG_OFFSET(HwErrStatus), - .kr_ibcctrl = IPATH_KREG_OFFSET(IBCCtrl), - .kr_ibcstatus = IPATH_KREG_OFFSET(IBCStatus), - .kr_intblocked = IPATH_KREG_OFFSET(IntBlocked), - .kr_intclear = IPATH_KREG_OFFSET(IntClear), - .kr_intmask = IPATH_KREG_OFFSET(IntMask), - .kr_intstatus = IPATH_KREG_OFFSET(IntStatus), - .kr_mdio = IPATH_KREG_OFFSET(MDIO), - .kr_pagealign = IPATH_KREG_OFFSET(PageAlign), - .kr_partitionkey = IPATH_KREG_OFFSET(RcvPartitionKey), - .kr_portcnt = IPATH_KREG_OFFSET(PortCnt), - .kr_rcvbthqp = IPATH_KREG_OFFSET(RcvBTHQP), - .kr_rcvbufbase = IPATH_KREG_OFFSET(RcvBufBase), - .kr_rcvbufsize = IPATH_KREG_OFFSET(RcvBufSize), - .kr_rcvctrl = IPATH_KREG_OFFSET(RcvCtrl), - .kr_rcvegrbase = IPATH_KREG_OFFSET(RcvEgrBase), - .kr_rcvegrcnt = IPATH_KREG_OFFSET(RcvEgrCnt), - .kr_rcvhdrcnt = IPATH_KREG_OFFSET(RcvHdrCnt), - .kr_rcvhdrentsize = IPATH_KREG_OFFSET(RcvHdrEntSize), - .kr_rcvhdrsize = IPATH_KREG_OFFSET(RcvHdrSize), - .kr_rcvintmembase = IPATH_KREG_OFFSET(RxIntMemBase), - .kr_rcvintmemsize = IPATH_KREG_OFFSET(RxIntMemSize), - .kr_rcvtidbase = IPATH_KREG_OFFSET(RcvTIDBase), - .kr_rcvtidcnt = IPATH_KREG_OFFSET(RcvTIDCnt), - .kr_revision = IPATH_KREG_OFFSET(Revision), - .kr_scratch = IPATH_KREG_OFFSET(Scratch), - .kr_sendbuffererror = IPATH_KREG_OFFSET(SendBufferError), - .kr_sendctrl = IPATH_KREG_OFFSET(SendCtrl), - .kr_sendpioavailaddr = IPATH_KREG_OFFSET(SendAvailAddr), - .kr_sendpiobufbase = IPATH_KREG_OFFSET(SendBufBase), - .kr_sendpiobufcnt = IPATH_KREG_OFFSET(SendBufCnt), - .kr_sendpiosize = IPATH_KREG_OFFSET(SendBufSize), - .kr_sendregbase = IPATH_KREG_OFFSET(SendRegBase), - .kr_txintmembase = IPATH_KREG_OFFSET(TxIntMemBase), - .kr_txintmemsize = IPATH_KREG_OFFSET(TxIntMemSize), - .kr_userregbase = IPATH_KREG_OFFSET(UserRegBase), - - .kr_xgxsconfig = IPATH_KREG_OFFSET(XGXSConfig), - - /* send dma related regs */ - .kr_senddmabase = IPATH_KREG_OFFSET(SendDmaBase), - .kr_senddmalengen = IPATH_KREG_OFFSET(SendDmaLenGen), - .kr_senddmatail = IPATH_KREG_OFFSET(SendDmaTail), - .kr_senddmahead = IPATH_KREG_OFFSET(SendDmaHead), - .kr_senddmaheadaddr = IPATH_KREG_OFFSET(SendDmaHeadAddr), - .kr_senddmabufmask0 = IPATH_KREG_OFFSET(SendDmaBufMask0), - .kr_senddmabufmask1 = IPATH_KREG_OFFSET(SendDmaBufMask1), - .kr_senddmabufmask2 = IPATH_KREG_OFFSET(SendDmaBufMask2), - .kr_senddmastatus = IPATH_KREG_OFFSET(SendDmaStatus), - - /* SerDes related regs */ - .kr_ibserdesctrl = IPATH_KREG_OFFSET(IBSerDesCtrl), - .kr_ib_epbacc = IPATH_KREG_OFFSET(IbsdEpbAccCtl), - .kr_ib_epbtrans = IPATH_KREG_OFFSET(IbsdEpbTransReg), - .kr_pcie_epbacc = IPATH_KREG_OFFSET(PcieEpbAccCtl), - .kr_pcie_epbtrans = IPATH_KREG_OFFSET(PcieEpbTransCtl), - .kr_ib_ddsrxeq = IPATH_KREG_OFFSET(SerDesDDSRXEQ), - - /* - * These should not be used directly via ipath_read_kreg64(), - * use them with ipath_read_kreg64_port() - */ - .kr_rcvhdraddr = IPATH_KREG_OFFSET(RcvHdrAddr0), - .kr_rcvhdrtailaddr = IPATH_KREG_OFFSET(RcvHdrTailAddr0), - - /* - * The rcvpktled register controls one of the debug port signals, so - * a packet activity LED can be connected to it. - */ - .kr_rcvpktledcnt = IPATH_KREG_OFFSET(RcvPktLEDCnt), - .kr_pcierbuftestreg0 = IPATH_KREG_OFFSET(PCIeRBufTestReg0), - .kr_pcierbuftestreg1 = IPATH_KREG_OFFSET(PCIeRBufTestReg1), - - .kr_hrtbt_guid = IPATH_KREG_OFFSET(HRTBT_GUID), - .kr_ibcddrctrl = IPATH_KREG_OFFSET(IBCDDRCtrl), - .kr_ibcddrstatus = IPATH_KREG_OFFSET(IBCDDRStatus), - .kr_jintreload = IPATH_KREG_OFFSET(JIntReload) -}; - -static const struct ipath_cregs ipath_7220_cregs = { - .cr_badformatcnt = IPATH_CREG_OFFSET(RxBadFormatCnt), - .cr_erricrccnt = IPATH_CREG_OFFSET(RxICRCErrCnt), - .cr_errlinkcnt = IPATH_CREG_OFFSET(RxLinkProblemCnt), - .cr_errlpcrccnt = IPATH_CREG_OFFSET(RxLPCRCErrCnt), - .cr_errpkey = IPATH_CREG_OFFSET(RxPKeyMismatchCnt), - .cr_errrcvflowctrlcnt = IPATH_CREG_OFFSET(RxFlowCtrlErrCnt), - .cr_err_rlencnt = IPATH_CREG_OFFSET(RxLenErrCnt), - .cr_errslencnt = IPATH_CREG_OFFSET(TxLenErrCnt), - .cr_errtidfull = IPATH_CREG_OFFSET(RxTIDFullErrCnt), - .cr_errtidvalid = IPATH_CREG_OFFSET(RxTIDValidErrCnt), - .cr_errvcrccnt = IPATH_CREG_OFFSET(RxVCRCErrCnt), - .cr_ibstatuschange = IPATH_CREG_OFFSET(IBStatusChangeCnt), - .cr_intcnt = IPATH_CREG_OFFSET(LBIntCnt), - .cr_invalidrlencnt = IPATH_CREG_OFFSET(RxMaxMinLenErrCnt), - .cr_invalidslencnt = IPATH_CREG_OFFSET(TxMaxMinLenErrCnt), - .cr_lbflowstallcnt = IPATH_CREG_OFFSET(LBFlowStallCnt), - .cr_pktrcvcnt = IPATH_CREG_OFFSET(RxDataPktCnt), - .cr_pktrcvflowctrlcnt = IPATH_CREG_OFFSET(RxFlowPktCnt), - .cr_pktsendcnt = IPATH_CREG_OFFSET(TxDataPktCnt), - .cr_pktsendflowcnt = IPATH_CREG_OFFSET(TxFlowPktCnt), - .cr_portovflcnt = IPATH_CREG_OFFSET(RxP0HdrEgrOvflCnt), - .cr_rcvebpcnt = IPATH_CREG_OFFSET(RxEBPCnt), - .cr_rcvovflcnt = IPATH_CREG_OFFSET(RxBufOvflCnt), - .cr_senddropped = IPATH_CREG_OFFSET(TxDroppedPktCnt), - .cr_sendstallcnt = IPATH_CREG_OFFSET(TxFlowStallCnt), - .cr_sendunderruncnt = IPATH_CREG_OFFSET(TxUnderrunCnt), - .cr_wordrcvcnt = IPATH_CREG_OFFSET(RxDwordCnt), - .cr_wordsendcnt = IPATH_CREG_OFFSET(TxDwordCnt), - .cr_unsupvlcnt = IPATH_CREG_OFFSET(TxUnsupVLErrCnt), - .cr_rxdroppktcnt = IPATH_CREG_OFFSET(RxDroppedPktCnt), - .cr_iblinkerrrecovcnt = IPATH_CREG_OFFSET(IBLinkErrRecoveryCnt), - .cr_iblinkdowncnt = IPATH_CREG_OFFSET(IBLinkDownedCnt), - .cr_ibsymbolerrcnt = IPATH_CREG_OFFSET(IBSymbolErrCnt), - .cr_vl15droppedpktcnt = IPATH_CREG_OFFSET(RxVL15DroppedPktCnt), - .cr_rxotherlocalphyerrcnt = - IPATH_CREG_OFFSET(RxOtherLocalPhyErrCnt), - .cr_excessbufferovflcnt = IPATH_CREG_OFFSET(ExcessBufferOvflCnt), - .cr_locallinkintegrityerrcnt = - IPATH_CREG_OFFSET(LocalLinkIntegrityErrCnt), - .cr_rxvlerrcnt = IPATH_CREG_OFFSET(RxVlErrCnt), - .cr_rxdlidfltrcnt = IPATH_CREG_OFFSET(RxDlidFltrCnt), - .cr_psstat = IPATH_CREG_OFFSET(PSStat), - .cr_psstart = IPATH_CREG_OFFSET(PSStart), - .cr_psinterval = IPATH_CREG_OFFSET(PSInterval), - .cr_psrcvdatacount = IPATH_CREG_OFFSET(PSRcvDataCount), - .cr_psrcvpktscount = IPATH_CREG_OFFSET(PSRcvPktsCount), - .cr_psxmitdatacount = IPATH_CREG_OFFSET(PSXmitDataCount), - .cr_psxmitpktscount = IPATH_CREG_OFFSET(PSXmitPktsCount), - .cr_psxmitwaitcount = IPATH_CREG_OFFSET(PSXmitWaitCount), -}; - -/* kr_control bits */ -#define INFINIPATH_C_RESET (1U<<7) - -/* kr_intstatus, kr_intclear, kr_intmask bits */ -#define INFINIPATH_I_RCVURG_MASK ((1ULL<<17)-1) -#define INFINIPATH_I_RCVURG_SHIFT 32 -#define INFINIPATH_I_RCVAVAIL_MASK ((1ULL<<17)-1) -#define INFINIPATH_I_RCVAVAIL_SHIFT 0 -#define INFINIPATH_I_SERDESTRIMDONE (1ULL<<27) - -/* kr_hwerrclear, kr_hwerrmask, kr_hwerrstatus, bits */ -#define INFINIPATH_HWE_PCIEMEMPARITYERR_MASK 0x00000000000000ffULL -#define INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT 0 -#define INFINIPATH_HWE_PCIEPOISONEDTLP 0x0000000010000000ULL -#define INFINIPATH_HWE_PCIECPLTIMEOUT 0x0000000020000000ULL -#define INFINIPATH_HWE_PCIEBUSPARITYXTLH 0x0000000040000000ULL -#define INFINIPATH_HWE_PCIEBUSPARITYXADM 0x0000000080000000ULL -#define INFINIPATH_HWE_PCIEBUSPARITYRADM 0x0000000100000000ULL -#define INFINIPATH_HWE_COREPLL_FBSLIP 0x0080000000000000ULL -#define INFINIPATH_HWE_COREPLL_RFSLIP 0x0100000000000000ULL -#define INFINIPATH_HWE_PCIE1PLLFAILED 0x0400000000000000ULL -#define INFINIPATH_HWE_PCIE0PLLFAILED 0x0800000000000000ULL -#define INFINIPATH_HWE_SERDESPLLFAILED 0x1000000000000000ULL -/* specific to this chip */ -#define INFINIPATH_HWE_PCIECPLDATAQUEUEERR 0x0000000000000040ULL -#define INFINIPATH_HWE_PCIECPLHDRQUEUEERR 0x0000000000000080ULL -#define INFINIPATH_HWE_SDMAMEMREADERR 0x0000000010000000ULL -#define INFINIPATH_HWE_CLK_UC_PLLNOTLOCKED 0x2000000000000000ULL -#define INFINIPATH_HWE_PCIESERDESQ0PCLKNOTDETECT 0x0100000000000000ULL -#define INFINIPATH_HWE_PCIESERDESQ1PCLKNOTDETECT 0x0200000000000000ULL -#define INFINIPATH_HWE_PCIESERDESQ2PCLKNOTDETECT 0x0400000000000000ULL -#define INFINIPATH_HWE_PCIESERDESQ3PCLKNOTDETECT 0x0800000000000000ULL -#define INFINIPATH_HWE_DDSRXEQMEMORYPARITYERR 0x0000008000000000ULL -#define INFINIPATH_HWE_IB_UC_MEMORYPARITYERR 0x0000004000000000ULL -#define INFINIPATH_HWE_PCIE_UC_OCT0MEMORYPARITYERR 0x0000001000000000ULL -#define INFINIPATH_HWE_PCIE_UC_OCT1MEMORYPARITYERR 0x0000002000000000ULL - -#define IBA7220_IBCS_LINKTRAININGSTATE_MASK 0x1F -#define IBA7220_IBCS_LINKSTATE_SHIFT 5 -#define IBA7220_IBCS_LINKSPEED_SHIFT 8 -#define IBA7220_IBCS_LINKWIDTH_SHIFT 9 - -#define IBA7220_IBCC_LINKINITCMD_MASK 0x7ULL -#define IBA7220_IBCC_LINKCMD_SHIFT 19 -#define IBA7220_IBCC_MAXPKTLEN_SHIFT 21 - -/* kr_ibcddrctrl bits */ -#define IBA7220_IBC_DLIDLMC_MASK 0xFFFFFFFFUL -#define IBA7220_IBC_DLIDLMC_SHIFT 32 -#define IBA7220_IBC_HRTBT_MASK 3 -#define IBA7220_IBC_HRTBT_SHIFT 16 -#define IBA7220_IBC_HRTBT_ENB 0x10000UL -#define IBA7220_IBC_LANE_REV_SUPPORTED (1<<8) -#define IBA7220_IBC_LREV_MASK 1 -#define IBA7220_IBC_LREV_SHIFT 8 -#define IBA7220_IBC_RXPOL_MASK 1 -#define IBA7220_IBC_RXPOL_SHIFT 7 -#define IBA7220_IBC_WIDTH_SHIFT 5 -#define IBA7220_IBC_WIDTH_MASK 0x3 -#define IBA7220_IBC_WIDTH_1X_ONLY (0<ipath_p0_rcvegrcnt + - (port-1) * dd->ipath_rcvegrcnt : 0; -} - -static void ipath_7220_txe_recover(struct ipath_devdata *dd) -{ - ++ipath_stats.sps_txeparity; - - dev_info(&dd->pcidev->dev, - "Recovering from TXE PIO parity error\n"); - ipath_disarm_senderrbufs(dd); -} - - -/** - * ipath_7220_handle_hwerrors - display hardware errors. - * @dd: the infinipath device - * @msg: the output buffer - * @msgl: the size of the output buffer - * - * Use same msg buffer as regular errors to avoid excessive stack - * use. Most hardware errors are catastrophic, but for right now, - * we'll print them and continue. We reuse the same message buffer as - * ipath_handle_errors() to avoid excessive stack usage. - */ -static void ipath_7220_handle_hwerrors(struct ipath_devdata *dd, char *msg, - size_t msgl) -{ - ipath_err_t hwerrs; - u32 bits, ctrl; - int isfatal = 0; - char bitsmsg[64]; - int log_idx; - - hwerrs = ipath_read_kreg64(dd, dd->ipath_kregs->kr_hwerrstatus); - if (!hwerrs) { - /* - * better than printing cofusing messages - * This seems to be related to clearing the crc error, or - * the pll error during init. - */ - ipath_cdbg(VERBOSE, "Called but no hardware errors set\n"); - goto bail; - } else if (hwerrs == ~0ULL) { - ipath_dev_err(dd, "Read of hardware error status failed " - "(all bits set); ignoring\n"); - goto bail; - } - ipath_stats.sps_hwerrs++; - - /* - * Always clear the error status register, except MEMBISTFAIL, - * regardless of whether we continue or stop using the chip. - * We want that set so we know it failed, even across driver reload. - * We'll still ignore it in the hwerrmask. We do this partly for - * diagnostics, but also for support. - */ - ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, - hwerrs&~INFINIPATH_HWE_MEMBISTFAILED); - - hwerrs &= dd->ipath_hwerrmask; - - /* We log some errors to EEPROM, check if we have any of those. */ - for (log_idx = 0; log_idx < IPATH_EEP_LOG_CNT; ++log_idx) - if (hwerrs & dd->ipath_eep_st_masks[log_idx].hwerrs_to_log) - ipath_inc_eeprom_err(dd, log_idx, 1); - /* - * Make sure we get this much out, unless told to be quiet, - * or it's occurred within the last 5 seconds. - */ - if ((hwerrs & ~(dd->ipath_lasthwerror | - ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF | - INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC) - << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT))) || - (ipath_debug & __IPATH_VERBDBG)) - dev_info(&dd->pcidev->dev, "Hardware error: hwerr=0x%llx " - "(cleared)\n", (unsigned long long) hwerrs); - dd->ipath_lasthwerror |= hwerrs; - - if (hwerrs & ~dd->ipath_hwe_bitsextant) - ipath_dev_err(dd, "hwerror interrupt with unknown errors " - "%llx set\n", (unsigned long long) - (hwerrs & ~dd->ipath_hwe_bitsextant)); - - if (hwerrs & INFINIPATH_HWE_IB_UC_MEMORYPARITYERR) - ipath_sd7220_clr_ibpar(dd); - - ctrl = ipath_read_kreg32(dd, dd->ipath_kregs->kr_control); - if ((ctrl & INFINIPATH_C_FREEZEMODE) && !ipath_diag_inuse) { - /* - * Parity errors in send memory are recoverable by h/w - * just do housekeeping, exit freeze mode and continue. - */ - if (hwerrs & ((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF | - INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC) - << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT)) { - ipath_7220_txe_recover(dd); - hwerrs &= ~((INFINIPATH_HWE_TXEMEMPARITYERR_PIOBUF | - INFINIPATH_HWE_TXEMEMPARITYERR_PIOPBC) - << INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT); - } - if (hwerrs) { - /* - * If any set that we aren't ignoring only make the - * complaint once, in case it's stuck or recurring, - * and we get here multiple times - * Force link down, so switch knows, and - * LEDs are turned off. - */ - if (dd->ipath_flags & IPATH_INITTED) { - ipath_set_linkstate(dd, IPATH_IB_LINKDOWN); - ipath_setup_7220_setextled(dd, - INFINIPATH_IBCS_L_STATE_DOWN, - INFINIPATH_IBCS_LT_STATE_DISABLED); - ipath_dev_err(dd, "Fatal Hardware Error " - "(freeze mode), no longer" - " usable, SN %.16s\n", - dd->ipath_serial); - isfatal = 1; - } - /* - * Mark as having had an error for driver, and also - * for /sys and status word mapped to user programs. - * This marks unit as not usable, until reset. - */ - *dd->ipath_statusp &= ~IPATH_STATUS_IB_READY; - *dd->ipath_statusp |= IPATH_STATUS_HWERROR; - dd->ipath_flags &= ~IPATH_INITTED; - } else { - ipath_dbg("Clearing freezemode on ignored or " - "recovered hardware error\n"); - ipath_clear_freeze(dd); - } - } - - *msg = '\0'; - - if (hwerrs & INFINIPATH_HWE_MEMBISTFAILED) { - strlcat(msg, "[Memory BIST test failed, " - "InfiniPath hardware unusable]", msgl); - /* ignore from now on, so disable until driver reloaded */ - *dd->ipath_statusp |= IPATH_STATUS_HWERROR; - dd->ipath_hwerrmask &= ~INFINIPATH_HWE_MEMBISTFAILED; - ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, - dd->ipath_hwerrmask); - } - - ipath_format_hwerrors(hwerrs, - ipath_7220_hwerror_msgs, - ARRAY_SIZE(ipath_7220_hwerror_msgs), - msg, msgl); - - if (hwerrs & (INFINIPATH_HWE_PCIEMEMPARITYERR_MASK - << INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT)) { - bits = (u32) ((hwerrs >> - INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT) & - INFINIPATH_HWE_PCIEMEMPARITYERR_MASK); - snprintf(bitsmsg, sizeof bitsmsg, - "[PCIe Mem Parity Errs %x] ", bits); - strlcat(msg, bitsmsg, msgl); - } - -#define _IPATH_PLL_FAIL (INFINIPATH_HWE_COREPLL_FBSLIP | \ - INFINIPATH_HWE_COREPLL_RFSLIP) - - if (hwerrs & _IPATH_PLL_FAIL) { - snprintf(bitsmsg, sizeof bitsmsg, - "[PLL failed (%llx), InfiniPath hardware unusable]", - (unsigned long long) hwerrs & _IPATH_PLL_FAIL); - strlcat(msg, bitsmsg, msgl); - /* ignore from now on, so disable until driver reloaded */ - dd->ipath_hwerrmask &= ~(hwerrs & _IPATH_PLL_FAIL); - ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, - dd->ipath_hwerrmask); - } - - if (hwerrs & INFINIPATH_HWE_SERDESPLLFAILED) { - /* - * If it occurs, it is left masked since the eternal - * interface is unused. - */ - dd->ipath_hwerrmask &= ~INFINIPATH_HWE_SERDESPLLFAILED; - ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, - dd->ipath_hwerrmask); - } - - ipath_dev_err(dd, "%s hardware error\n", msg); - /* - * For /sys status file. if no trailing } is copied, we'll - * know it was truncated. - */ - if (isfatal && !ipath_diag_inuse && dd->ipath_freezemsg) - snprintf(dd->ipath_freezemsg, dd->ipath_freezelen, - "{%s}", msg); -bail:; -} - -/** - * ipath_7220_boardname - fill in the board name - * @dd: the infinipath device - * @name: the output buffer - * @namelen: the size of the output buffer - * - * info is based on the board revision register - */ -static int ipath_7220_boardname(struct ipath_devdata *dd, char *name, - size_t namelen) -{ - char *n = NULL; - u8 boardrev = dd->ipath_boardrev; - int ret; - - if (boardrev == 15) { - /* - * Emulator sometimes comes up all-ones, rather than zero. - */ - boardrev = 0; - dd->ipath_boardrev = boardrev; - } - switch (boardrev) { - case 0: - n = "InfiniPath_7220_Emulation"; - break; - case 1: - n = "InfiniPath_QLE7240"; - break; - case 2: - n = "InfiniPath_QLE7280"; - break; - case 3: - n = "InfiniPath_QLE7242"; - break; - case 4: - n = "InfiniPath_QEM7240"; - break; - case 5: - n = "InfiniPath_QMI7240"; - break; - case 6: - n = "InfiniPath_QMI7264"; - break; - case 7: - n = "InfiniPath_QMH7240"; - break; - case 8: - n = "InfiniPath_QME7240"; - break; - case 9: - n = "InfiniPath_QLE7250"; - break; - case 10: - n = "InfiniPath_QLE7290"; - break; - case 11: - n = "InfiniPath_QEM7250"; - break; - case 12: - n = "InfiniPath_QLE-Bringup"; - break; - default: - ipath_dev_err(dd, - "Don't yet know about board with ID %u\n", - boardrev); - snprintf(name, namelen, "Unknown_InfiniPath_PCIe_%u", - boardrev); - break; - } - if (n) - snprintf(name, namelen, "%s", n); - - if (dd->ipath_majrev != 5 || !dd->ipath_minrev || - dd->ipath_minrev > 2) { - ipath_dev_err(dd, "Unsupported InfiniPath hardware " - "revision %u.%u!\n", - dd->ipath_majrev, dd->ipath_minrev); - ret = 1; - } else if (dd->ipath_minrev == 1 && - !(dd->ipath_flags & IPATH_INITTED)) { - /* Rev1 chips are prototype. Complain at init, but allow use */ - ipath_dev_err(dd, "Unsupported hardware " - "revision %u.%u, Contact support@qlogic.com\n", - dd->ipath_majrev, dd->ipath_minrev); - ret = 0; - } else - ret = 0; - - /* - * Set here not in ipath_init_*_funcs because we have to do - * it after we can read chip registers. - */ - dd->ipath_ureg_align = 0x10000; /* 64KB alignment */ - - return ret; -} - -/** - * ipath_7220_init_hwerrors - enable hardware errors - * @dd: the infinipath device - * - * now that we have finished initializing everything that might reasonably - * cause a hardware error, and cleared those errors bits as they occur, - * we can enable hardware errors in the mask (potentially enabling - * freeze mode), and enable hardware errors as errors (along with - * everything else) in errormask - */ -static void ipath_7220_init_hwerrors(struct ipath_devdata *dd) -{ - ipath_err_t val; - u64 extsval; - - extsval = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extstatus); - - if (!(extsval & (INFINIPATH_EXTS_MEMBIST_ENDTEST | - INFINIPATH_EXTS_MEMBIST_DISABLED))) - ipath_dev_err(dd, "MemBIST did not complete!\n"); - if (extsval & INFINIPATH_EXTS_MEMBIST_DISABLED) - dev_info(&dd->pcidev->dev, "MemBIST is disabled.\n"); - - val = ~0ULL; /* barring bugs, all hwerrors become interrupts, */ - - if (!dd->ipath_boardrev) /* no PLL for Emulator */ - val &= ~INFINIPATH_HWE_SERDESPLLFAILED; - - if (dd->ipath_minrev == 1) - val &= ~(1ULL << 42); /* TXE LaunchFIFO Parity rev1 issue */ - - val &= ~INFINIPATH_HWE_IB_UC_MEMORYPARITYERR; - dd->ipath_hwerrmask = val; - - /* - * special trigger "error" is for debugging purposes. It - * works around a processor/chipset problem. The error - * interrupt allows us to count occurrences, but we don't - * want to pay the overhead for normal use. Emulation only - */ - if (!dd->ipath_boardrev) - dd->ipath_maskederrs = INFINIPATH_E_SENDSPECIALTRIGGER; -} - -/* - * All detailed interaction with the SerDes has been moved to ipath_sd7220.c - * - * The portion of IBA7220-specific bringup_serdes() that actually deals with - * registers and memory within the SerDes itself is ipath_sd7220_init(). - */ - -/** - * ipath_7220_bringup_serdes - bring up the serdes - * @dd: the infinipath device - */ -static int ipath_7220_bringup_serdes(struct ipath_devdata *dd) -{ - int ret = 0; - u64 val, prev_val, guid; - int was_reset; /* Note whether uC was reset */ - - ipath_dbg("Trying to bringup serdes\n"); - - if (ipath_read_kreg64(dd, dd->ipath_kregs->kr_hwerrstatus) & - INFINIPATH_HWE_SERDESPLLFAILED) { - ipath_dbg("At start, serdes PLL failed bit set " - "in hwerrstatus, clearing and continuing\n"); - ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, - INFINIPATH_HWE_SERDESPLLFAILED); - } - - dd->ibdeltainprog = 1; - dd->ibsymsnap = - ipath_read_creg32(dd, dd->ipath_cregs->cr_ibsymbolerrcnt); - dd->iblnkerrsnap = - ipath_read_creg32(dd, dd->ipath_cregs->cr_iblinkerrrecovcnt); - - if (!dd->ipath_ibcddrctrl) { - /* not on re-init after reset */ - dd->ipath_ibcddrctrl = - ipath_read_kreg64(dd, dd->ipath_kregs->kr_ibcddrctrl); - - if (dd->ipath_link_speed_enabled == - (IPATH_IB_SDR | IPATH_IB_DDR)) - dd->ipath_ibcddrctrl |= - IBA7220_IBC_SPEED_AUTONEG_MASK | - IBA7220_IBC_IBTA_1_2_MASK; - else - dd->ipath_ibcddrctrl |= - dd->ipath_link_speed_enabled == IPATH_IB_DDR - ? IBA7220_IBC_SPEED_DDR : - IBA7220_IBC_SPEED_SDR; - if ((dd->ipath_link_width_enabled & (IB_WIDTH_1X | - IB_WIDTH_4X)) == (IB_WIDTH_1X | IB_WIDTH_4X)) - dd->ipath_ibcddrctrl |= IBA7220_IBC_WIDTH_AUTONEG; - else - dd->ipath_ibcddrctrl |= - dd->ipath_link_width_enabled == IB_WIDTH_4X - ? IBA7220_IBC_WIDTH_4X_ONLY : - IBA7220_IBC_WIDTH_1X_ONLY; - - /* always enable these on driver reload, not sticky */ - dd->ipath_ibcddrctrl |= - IBA7220_IBC_RXPOL_MASK << IBA7220_IBC_RXPOL_SHIFT; - dd->ipath_ibcddrctrl |= - IBA7220_IBC_HRTBT_MASK << IBA7220_IBC_HRTBT_SHIFT; - /* - * automatic lane reversal detection for receive - * doesn't work correctly in rev 1, so disable it - * on that rev, otherwise enable (disabling not - * sticky across reload for >rev1) - */ - if (dd->ipath_minrev == 1) - dd->ipath_ibcddrctrl &= - ~IBA7220_IBC_LANE_REV_SUPPORTED; - else - dd->ipath_ibcddrctrl |= - IBA7220_IBC_LANE_REV_SUPPORTED; - } - - ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcddrctrl, - dd->ipath_ibcddrctrl); - - ipath_write_kreg(dd, IPATH_KREG_OFFSET(IBNCModeCtrl), 0Ull); - - /* IBA7220 has SERDES MPU reset in D0 of what _was_ IBPLLCfg */ - val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_ibserdesctrl); - /* remember if uC was in Reset or not, for dactrim */ - was_reset = (val & 1); - ipath_cdbg(VERBOSE, "IBReset %s xgxsconfig %llx\n", - was_reset ? "Asserted" : "Negated", (unsigned long long) - ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig)); - - if (dd->ipath_boardrev) { - /* - * Hardware is not emulator, and may have been reset. Init it. - * Below will release reset, but needs to know if chip was - * originally in reset, to only trim DACs on first time - * after chip reset or powercycle (not driver reload) - */ - ret = ipath_sd7220_init(dd, was_reset); - } - - val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig); - prev_val = val; - val |= INFINIPATH_XGXS_FC_SAFE; - if (val != prev_val) { - ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val); - ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); - } - if (val & INFINIPATH_XGXS_RESET) - val &= ~INFINIPATH_XGXS_RESET; - if (val != prev_val) - ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val); - - ipath_cdbg(VERBOSE, "done: xgxs=%llx from %llx\n", - (unsigned long long) - ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig), - (unsigned long long) prev_val); - - guid = be64_to_cpu(dd->ipath_guid); - - if (!guid) { - /* have to have something, so use likely unique tsc */ - guid = get_cycles(); - ipath_dbg("No GUID for heartbeat, faking %llx\n", - (unsigned long long)guid); - } else - ipath_cdbg(VERBOSE, "Wrote %llX to HRTBT_GUID\n", - (unsigned long long) guid); - ipath_write_kreg(dd, dd->ipath_kregs->kr_hrtbt_guid, guid); - return ret; -} - -static void ipath_7220_config_jint(struct ipath_devdata *dd, - u16 idle_ticks, u16 max_packets) -{ - - /* - * We can request a receive interrupt for 1 or more packets - * from current offset. - */ - if (idle_ticks == 0 || max_packets == 0) - /* interrupt after one packet if no mitigation */ - dd->ipath_rhdrhead_intr_off = - 1ULL << IBA7220_HDRHEAD_PKTINT_SHIFT; - else - /* Turn off RcvHdrHead interrupts if using mitigation */ - dd->ipath_rhdrhead_intr_off = 0ULL; - - /* refresh kernel RcvHdrHead registers... */ - ipath_write_ureg(dd, ur_rcvhdrhead, - dd->ipath_rhdrhead_intr_off | - dd->ipath_pd[0]->port_head, 0); - - dd->ipath_jint_max_packets = max_packets; - dd->ipath_jint_idle_ticks = idle_ticks; - ipath_write_kreg(dd, dd->ipath_kregs->kr_jintreload, - ((u64) max_packets << INFINIPATH_JINT_PACKETSHIFT) | - idle_ticks); -} - -/** - * ipath_7220_quiet_serdes - set serdes to txidle - * @dd: the infinipath device - * Called when driver is being unloaded - */ -static void ipath_7220_quiet_serdes(struct ipath_devdata *dd) -{ - u64 val; - if (dd->ibsymdelta || dd->iblnkerrdelta || - dd->ibdeltainprog) { - u64 diagc; - /* enable counter writes */ - diagc = ipath_read_kreg64(dd, dd->ipath_kregs->kr_hwdiagctrl); - ipath_write_kreg(dd, dd->ipath_kregs->kr_hwdiagctrl, - diagc | INFINIPATH_DC_COUNTERWREN); - - if (dd->ibsymdelta || dd->ibdeltainprog) { - val = ipath_read_creg32(dd, - dd->ipath_cregs->cr_ibsymbolerrcnt); - if (dd->ibdeltainprog) - val -= val - dd->ibsymsnap; - val -= dd->ibsymdelta; - ipath_write_creg(dd, - dd->ipath_cregs->cr_ibsymbolerrcnt, val); - } - if (dd->iblnkerrdelta || dd->ibdeltainprog) { - val = ipath_read_creg32(dd, - dd->ipath_cregs->cr_iblinkerrrecovcnt); - if (dd->ibdeltainprog) - val -= val - dd->iblnkerrsnap; - val -= dd->iblnkerrdelta; - ipath_write_creg(dd, - dd->ipath_cregs->cr_iblinkerrrecovcnt, val); - } - - /* and disable counter writes */ - ipath_write_kreg(dd, dd->ipath_kregs->kr_hwdiagctrl, diagc); - } - - dd->ipath_flags &= ~IPATH_IB_AUTONEG_INPROG; - wake_up(&dd->ipath_autoneg_wait); - cancel_delayed_work(&dd->ipath_autoneg_work); - flush_scheduled_work(); - ipath_shutdown_relock_poll(dd); - val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig); - val |= INFINIPATH_XGXS_RESET; - ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val); -} - -static int ipath_7220_intconfig(struct ipath_devdata *dd) -{ - ipath_7220_config_jint(dd, dd->ipath_jint_idle_ticks, - dd->ipath_jint_max_packets); - return 0; -} - -/** - * ipath_setup_7220_setextled - set the state of the two external LEDs - * @dd: the infinipath device - * @lst: the L state - * @ltst: the LT state - * - * These LEDs indicate the physical and logical state of IB link. - * For this chip (at least with recommended board pinouts), LED1 - * is Yellow (logical state) and LED2 is Green (physical state), - * - * Note: We try to match the Mellanox HCA LED behavior as best - * we can. Green indicates physical link state is OK (something is - * plugged in, and we can train). - * Amber indicates the link is logically up (ACTIVE). - * Mellanox further blinks the amber LED to indicate data packet - * activity, but we have no hardware support for that, so it would - * require waking up every 10-20 msecs and checking the counters - * on the chip, and then turning the LED off if appropriate. That's - * visible overhead, so not something we will do. - * - */ -static void ipath_setup_7220_setextled(struct ipath_devdata *dd, u64 lst, - u64 ltst) -{ - u64 extctl, ledblink = 0; - unsigned long flags = 0; - - /* the diags use the LED to indicate diag info, so we leave - * the external LED alone when the diags are running */ - if (ipath_diag_inuse) - return; - - /* Allow override of LED display for, e.g. Locating system in rack */ - if (dd->ipath_led_override) { - ltst = (dd->ipath_led_override & IPATH_LED_PHYS) - ? INFINIPATH_IBCS_LT_STATE_LINKUP - : INFINIPATH_IBCS_LT_STATE_DISABLED; - lst = (dd->ipath_led_override & IPATH_LED_LOG) - ? INFINIPATH_IBCS_L_STATE_ACTIVE - : INFINIPATH_IBCS_L_STATE_DOWN; - } - - spin_lock_irqsave(&dd->ipath_gpio_lock, flags); - extctl = dd->ipath_extctrl & ~(INFINIPATH_EXTC_LED1PRIPORT_ON | - INFINIPATH_EXTC_LED2PRIPORT_ON); - if (ltst == INFINIPATH_IBCS_LT_STATE_LINKUP) { - extctl |= INFINIPATH_EXTC_LED1PRIPORT_ON; - /* - * counts are in chip clock (4ns) periods. - * This is 1/16 sec (66.6ms) on, - * 3/16 sec (187.5 ms) off, with packets rcvd - */ - ledblink = ((66600*1000UL/4) << IBA7220_LEDBLINK_ON_SHIFT) - | ((187500*1000UL/4) << IBA7220_LEDBLINK_OFF_SHIFT); - } - if (lst == INFINIPATH_IBCS_L_STATE_ACTIVE) - extctl |= INFINIPATH_EXTC_LED2PRIPORT_ON; - dd->ipath_extctrl = extctl; - ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, extctl); - spin_unlock_irqrestore(&dd->ipath_gpio_lock, flags); - - if (ledblink) /* blink the LED on packet receive */ - ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvpktledcnt, - ledblink); -} - -/* - * Similar to pci_intx(pdev, 1), except that we make sure - * msi is off... - */ -static void ipath_enable_intx(struct pci_dev *pdev) -{ - u16 cw, new; - int pos; - - /* first, turn on INTx */ - pci_read_config_word(pdev, PCI_COMMAND, &cw); - new = cw & ~PCI_COMMAND_INTX_DISABLE; - if (new != cw) - pci_write_config_word(pdev, PCI_COMMAND, new); - - /* then turn off MSI */ - pos = pci_find_capability(pdev, PCI_CAP_ID_MSI); - if (pos) { - pci_read_config_word(pdev, pos + PCI_MSI_FLAGS, &cw); - new = cw & ~PCI_MSI_FLAGS_ENABLE; - if (new != cw) - pci_write_config_word(pdev, pos + PCI_MSI_FLAGS, new); - } -} - -static int ipath_msi_enabled(struct pci_dev *pdev) -{ - int pos, ret = 0; - - pos = pci_find_capability(pdev, PCI_CAP_ID_MSI); - if (pos) { - u16 cw; - - pci_read_config_word(pdev, pos + PCI_MSI_FLAGS, &cw); - ret = !!(cw & PCI_MSI_FLAGS_ENABLE); - } - return ret; -} - -/* - * disable msi interrupt if enabled, and clear the flag. - * flag is used primarily for the fallback to INTx, but - * is also used in reinit after reset as a flag. - */ -static void ipath_7220_nomsi(struct ipath_devdata *dd) -{ - dd->ipath_msi_lo = 0; - - if (ipath_msi_enabled(dd->pcidev)) { - /* - * free, but don't zero; later kernels require - * it be freed before disable_msi, so the intx - * setup has to request it again. - */ - if (dd->ipath_irq) - free_irq(dd->ipath_irq, dd); - pci_disable_msi(dd->pcidev); - } -} - -/* - * ipath_setup_7220_cleanup - clean up any per-chip chip-specific stuff - * @dd: the infinipath device - * - * Nothing but msi interrupt cleanup for now. - * - * This is called during driver unload. - */ -static void ipath_setup_7220_cleanup(struct ipath_devdata *dd) -{ - ipath_7220_nomsi(dd); -} - - -static void ipath_7220_pcie_params(struct ipath_devdata *dd, u32 boardrev) -{ - u16 linkstat, minwidth, speed; - int pos; - - pos = pci_find_capability(dd->pcidev, PCI_CAP_ID_EXP); - if (!pos) { - ipath_dev_err(dd, "Can't find PCI Express capability!\n"); - goto bail; - } - - pci_read_config_word(dd->pcidev, pos + PCI_EXP_LNKSTA, - &linkstat); - /* - * speed is bits 0-4, linkwidth is bits 4-8 - * no defines for them in headers - */ - speed = linkstat & 0xf; - linkstat >>= 4; - linkstat &= 0x1f; - dd->ipath_lbus_width = linkstat; - switch (boardrev) { - case 0: - case 2: - case 10: - case 12: - minwidth = 16; /* x16 capable boards */ - break; - default: - minwidth = 8; /* x8 capable boards */ - break; - } - - switch (speed) { - case 1: - dd->ipath_lbus_speed = 2500; /* Gen1, 2.5GHz */ - break; - case 2: - dd->ipath_lbus_speed = 5000; /* Gen1, 5GHz */ - break; - default: /* not defined, assume gen1 */ - dd->ipath_lbus_speed = 2500; - break; - } - - if (linkstat < minwidth) - ipath_dev_err(dd, - "PCIe width %u (x%u HCA), performance " - "reduced\n", linkstat, minwidth); - else - ipath_cdbg(VERBOSE, "PCIe speed %u width %u (x%u HCA)\n", - dd->ipath_lbus_speed, linkstat, minwidth); - - if (speed != 1) - ipath_dev_err(dd, - "PCIe linkspeed %u is incorrect; " - "should be 1 (2500)!\n", speed); - -bail: - /* fill in string, even on errors */ - snprintf(dd->ipath_lbus_info, sizeof(dd->ipath_lbus_info), - "PCIe,%uMHz,x%u\n", - dd->ipath_lbus_speed, - dd->ipath_lbus_width); - return; -} - - -/** - * ipath_setup_7220_config - setup PCIe config related stuff - * @dd: the infinipath device - * @pdev: the PCI device - * - * The pci_enable_msi() call will fail on systems with MSI quirks - * such as those with AMD8131, even if the device of interest is not - * attached to that device, (in the 2.6.13 - 2.6.15 kernels, at least, fixed - * late in 2.6.16). - * All that can be done is to edit the kernel source to remove the quirk - * check until that is fixed. - * We do not need to call enable_msi() for our HyperTransport chip, - * even though it uses MSI, and we want to avoid the quirk warning, so - * So we call enable_msi only for PCIe. If we do end up needing - * pci_enable_msi at some point in the future for HT, we'll move the - * call back into the main init_one code. - * We save the msi lo and hi values, so we can restore them after - * chip reset (the kernel PCI infrastructure doesn't yet handle that - * correctly). - */ -static int ipath_setup_7220_config(struct ipath_devdata *dd, - struct pci_dev *pdev) -{ - int pos, ret = -1; - u32 boardrev; - - dd->ipath_msi_lo = 0; /* used as a flag during reset processing */ - - pos = pci_find_capability(pdev, PCI_CAP_ID_MSI); - if (!strcmp(int_type, "force_msi") || !strcmp(int_type, "auto")) - ret = pci_enable_msi(pdev); - if (ret) { - if (!strcmp(int_type, "force_msi")) { - ipath_dev_err(dd, "pci_enable_msi failed: %d, " - "force_msi is on, so not continuing.\n", - ret); - return ret; - } - - ipath_enable_intx(pdev); - if (!strcmp(int_type, "auto")) - ipath_dev_err(dd, "pci_enable_msi failed: %d, " - "falling back to INTx\n", ret); - } else if (pos) { - u16 control; - pci_read_config_dword(pdev, pos + PCI_MSI_ADDRESS_LO, - &dd->ipath_msi_lo); - pci_read_config_dword(pdev, pos + PCI_MSI_ADDRESS_HI, - &dd->ipath_msi_hi); - pci_read_config_word(pdev, pos + PCI_MSI_FLAGS, - &control); - /* now save the data (vector) info */ - pci_read_config_word(pdev, - pos + ((control & PCI_MSI_FLAGS_64BIT) - ? PCI_MSI_DATA_64 : - PCI_MSI_DATA_32), - &dd->ipath_msi_data); - } else - ipath_dev_err(dd, "Can't find MSI capability, " - "can't save MSI settings for reset\n"); - - dd->ipath_irq = pdev->irq; - - /* - * We save the cachelinesize also, although it doesn't - * really matter. - */ - pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, - &dd->ipath_pci_cacheline); - - /* - * this function called early, ipath_boardrev not set yet. Can't - * use ipath_read_kreg64() yet, too early in init, so use readq() - */ - boardrev = (readq(&dd->ipath_kregbase[dd->ipath_kregs->kr_revision]) - >> INFINIPATH_R_BOARDID_SHIFT) & INFINIPATH_R_BOARDID_MASK; - - ipath_7220_pcie_params(dd, boardrev); - - dd->ipath_flags |= IPATH_NODMA_RTAIL | IPATH_HAS_SEND_DMA | - IPATH_HAS_PBC_CNT | IPATH_HAS_THRESH_UPDATE; - dd->ipath_pioupd_thresh = 4U; /* set default update threshold */ - return 0; -} - -static void ipath_init_7220_variables(struct ipath_devdata *dd) -{ - /* - * setup the register offsets, since they are different for each - * chip - */ - dd->ipath_kregs = &ipath_7220_kregs; - dd->ipath_cregs = &ipath_7220_cregs; - - /* - * bits for selecting i2c direction and values, - * used for I2C serial flash - */ - dd->ipath_gpio_sda_num = _IPATH_GPIO_SDA_NUM; - dd->ipath_gpio_scl_num = _IPATH_GPIO_SCL_NUM; - dd->ipath_gpio_sda = IPATH_GPIO_SDA; - dd->ipath_gpio_scl = IPATH_GPIO_SCL; - - /* - * Fill in data for field-values that change in IBA7220. - * We dynamically specify only the mask for LINKTRAININGSTATE - * and only the shift for LINKSTATE, as they are the only ones - * that change. Also precalculate the 3 link states of interest - * and the combined mask. - */ - dd->ibcs_ls_shift = IBA7220_IBCS_LINKSTATE_SHIFT; - dd->ibcs_lts_mask = IBA7220_IBCS_LINKTRAININGSTATE_MASK; - dd->ibcs_mask = (INFINIPATH_IBCS_LINKSTATE_MASK << - dd->ibcs_ls_shift) | dd->ibcs_lts_mask; - dd->ib_init = (INFINIPATH_IBCS_LT_STATE_LINKUP << - INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | - (INFINIPATH_IBCS_L_STATE_INIT << dd->ibcs_ls_shift); - dd->ib_arm = (INFINIPATH_IBCS_LT_STATE_LINKUP << - INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | - (INFINIPATH_IBCS_L_STATE_ARM << dd->ibcs_ls_shift); - dd->ib_active = (INFINIPATH_IBCS_LT_STATE_LINKUP << - INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) | - (INFINIPATH_IBCS_L_STATE_ACTIVE << dd->ibcs_ls_shift); - - /* - * Fill in data for ibcc field-values that change in IBA7220. - * We dynamically specify only the mask for LINKINITCMD - * and only the shift for LINKCMD and MAXPKTLEN, as they are - * the only ones that change. - */ - dd->ibcc_lic_mask = IBA7220_IBCC_LINKINITCMD_MASK; - dd->ibcc_lc_shift = IBA7220_IBCC_LINKCMD_SHIFT; - dd->ibcc_mpl_shift = IBA7220_IBCC_MAXPKTLEN_SHIFT; - - /* Fill in shifts for RcvCtrl. */ - dd->ipath_r_portenable_shift = INFINIPATH_R_PORTENABLE_SHIFT; - dd->ipath_r_intravail_shift = IBA7220_R_INTRAVAIL_SHIFT; - dd->ipath_r_tailupd_shift = IBA7220_R_TAILUPD_SHIFT; - dd->ipath_r_portcfg_shift = IBA7220_R_PORTCFG_SHIFT; - - /* variables for sanity checking interrupt and errors */ - dd->ipath_hwe_bitsextant = - (INFINIPATH_HWE_RXEMEMPARITYERR_MASK << - INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT) | - (INFINIPATH_HWE_TXEMEMPARITYERR_MASK << - INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT) | - (INFINIPATH_HWE_PCIEMEMPARITYERR_MASK << - INFINIPATH_HWE_PCIEMEMPARITYERR_SHIFT) | - INFINIPATH_HWE_PCIE1PLLFAILED | - INFINIPATH_HWE_PCIE0PLLFAILED | - INFINIPATH_HWE_PCIEPOISONEDTLP | - INFINIPATH_HWE_PCIECPLTIMEOUT | - INFINIPATH_HWE_PCIEBUSPARITYXTLH | - INFINIPATH_HWE_PCIEBUSPARITYXADM | - INFINIPATH_HWE_PCIEBUSPARITYRADM | - INFINIPATH_HWE_MEMBISTFAILED | - INFINIPATH_HWE_COREPLL_FBSLIP | - INFINIPATH_HWE_COREPLL_RFSLIP | - INFINIPATH_HWE_SERDESPLLFAILED | - INFINIPATH_HWE_IBCBUSTOSPCPARITYERR | - INFINIPATH_HWE_IBCBUSFRSPCPARITYERR | - INFINIPATH_HWE_PCIECPLDATAQUEUEERR | - INFINIPATH_HWE_PCIECPLHDRQUEUEERR | - INFINIPATH_HWE_SDMAMEMREADERR | - INFINIPATH_HWE_CLK_UC_PLLNOTLOCKED | - INFINIPATH_HWE_PCIESERDESQ0PCLKNOTDETECT | - INFINIPATH_HWE_PCIESERDESQ1PCLKNOTDETECT | - INFINIPATH_HWE_PCIESERDESQ2PCLKNOTDETECT | - INFINIPATH_HWE_PCIESERDESQ3PCLKNOTDETECT | - INFINIPATH_HWE_DDSRXEQMEMORYPARITYERR | - INFINIPATH_HWE_IB_UC_MEMORYPARITYERR | - INFINIPATH_HWE_PCIE_UC_OCT0MEMORYPARITYERR | - INFINIPATH_HWE_PCIE_UC_OCT1MEMORYPARITYERR; - dd->ipath_i_bitsextant = - INFINIPATH_I_SDMAINT | INFINIPATH_I_SDMADISABLED | - (INFINIPATH_I_RCVURG_MASK << INFINIPATH_I_RCVURG_SHIFT) | - (INFINIPATH_I_RCVAVAIL_MASK << - INFINIPATH_I_RCVAVAIL_SHIFT) | - INFINIPATH_I_ERROR | INFINIPATH_I_SPIOSENT | - INFINIPATH_I_SPIOBUFAVAIL | INFINIPATH_I_GPIO | - INFINIPATH_I_JINT | INFINIPATH_I_SERDESTRIMDONE; - dd->ipath_e_bitsextant = - INFINIPATH_E_RFORMATERR | INFINIPATH_E_RVCRC | - INFINIPATH_E_RICRC | INFINIPATH_E_RMINPKTLEN | - INFINIPATH_E_RMAXPKTLEN | INFINIPATH_E_RLONGPKTLEN | - INFINIPATH_E_RSHORTPKTLEN | INFINIPATH_E_RUNEXPCHAR | - INFINIPATH_E_RUNSUPVL | INFINIPATH_E_REBP | - INFINIPATH_E_RIBFLOW | INFINIPATH_E_RBADVERSION | - INFINIPATH_E_RRCVEGRFULL | INFINIPATH_E_RRCVHDRFULL | - INFINIPATH_E_RBADTID | INFINIPATH_E_RHDRLEN | - INFINIPATH_E_RHDR | INFINIPATH_E_RIBLOSTLINK | - INFINIPATH_E_SENDSPECIALTRIGGER | - INFINIPATH_E_SDMADISABLED | INFINIPATH_E_SMINPKTLEN | - INFINIPATH_E_SMAXPKTLEN | INFINIPATH_E_SUNDERRUN | - INFINIPATH_E_SPKTLEN | INFINIPATH_E_SDROPPEDSMPPKT | - INFINIPATH_E_SDROPPEDDATAPKT | - INFINIPATH_E_SPIOARMLAUNCH | INFINIPATH_E_SUNEXPERRPKTNUM | - INFINIPATH_E_SUNSUPVL | INFINIPATH_E_SENDBUFMISUSE | - INFINIPATH_E_SDMAGENMISMATCH | INFINIPATH_E_SDMAOUTOFBOUND | - INFINIPATH_E_SDMATAILOUTOFBOUND | INFINIPATH_E_SDMABASE | - INFINIPATH_E_SDMA1STDESC | INFINIPATH_E_SDMARPYTAG | - INFINIPATH_E_SDMADWEN | INFINIPATH_E_SDMAMISSINGDW | - INFINIPATH_E_SDMAUNEXPDATA | - INFINIPATH_E_IBSTATUSCHANGED | INFINIPATH_E_INVALIDADDR | - INFINIPATH_E_RESET | INFINIPATH_E_HARDWARE | - INFINIPATH_E_SDMADESCADDRMISALIGN | - INFINIPATH_E_INVALIDEEPCMD; - - dd->ipath_i_rcvavail_mask = INFINIPATH_I_RCVAVAIL_MASK; - dd->ipath_i_rcvurg_mask = INFINIPATH_I_RCVURG_MASK; - dd->ipath_i_rcvavail_shift = INFINIPATH_I_RCVAVAIL_SHIFT; - dd->ipath_i_rcvurg_shift = INFINIPATH_I_RCVURG_SHIFT; - dd->ipath_flags |= IPATH_INTREG_64 | IPATH_HAS_MULT_IB_SPEED - | IPATH_HAS_LINK_LATENCY; - - /* - * EEPROM error log 0 is TXE Parity errors. 1 is RXE Parity. - * 2 is Some Misc, 3 is reserved for future. - */ - dd->ipath_eep_st_masks[0].hwerrs_to_log = - INFINIPATH_HWE_TXEMEMPARITYERR_MASK << - INFINIPATH_HWE_TXEMEMPARITYERR_SHIFT; - - dd->ipath_eep_st_masks[1].hwerrs_to_log = - INFINIPATH_HWE_RXEMEMPARITYERR_MASK << - INFINIPATH_HWE_RXEMEMPARITYERR_SHIFT; - - dd->ipath_eep_st_masks[2].errs_to_log = INFINIPATH_E_RESET; - - ipath_linkrecovery = 0; - - init_waitqueue_head(&dd->ipath_autoneg_wait); - INIT_DELAYED_WORK(&dd->ipath_autoneg_work, autoneg_work); - - dd->ipath_link_width_supported = IB_WIDTH_1X | IB_WIDTH_4X; - dd->ipath_link_speed_supported = IPATH_IB_SDR | IPATH_IB_DDR; - - dd->ipath_link_width_enabled = dd->ipath_link_width_supported; - dd->ipath_link_speed_enabled = dd->ipath_link_speed_supported; - /* - * set the initial values to reasonable default, will be set - * for real when link is up. - */ - dd->ipath_link_width_active = IB_WIDTH_4X; - dd->ipath_link_speed_active = IPATH_IB_SDR; - dd->delay_mult = rate_to_delay[0][1]; -} - - -/* - * Setup the MSI stuff again after a reset. I'd like to just call - * pci_enable_msi() and request_irq() again, but when I do that, - * the MSI enable bit doesn't get set in the command word, and - * we switch to to a different interrupt vector, which is confusing, - * so I instead just do it all inline. Perhaps somehow can tie this - * into the PCIe hotplug support at some point - * Note, because I'm doing it all here, I don't call pci_disable_msi() - * or free_irq() at the start of ipath_setup_7220_reset(). - */ -static int ipath_reinit_msi(struct ipath_devdata *dd) -{ - int ret = 0; - - int pos; - u16 control; - if (!dd->ipath_msi_lo) /* Using intX, or init problem */ - goto bail; - - pos = pci_find_capability(dd->pcidev, PCI_CAP_ID_MSI); - if (!pos) { - ipath_dev_err(dd, "Can't find MSI capability, " - "can't restore MSI settings\n"); - goto bail; - } - ipath_cdbg(VERBOSE, "Writing msi_lo 0x%x to config offset 0x%x\n", - dd->ipath_msi_lo, pos + PCI_MSI_ADDRESS_LO); - pci_write_config_dword(dd->pcidev, pos + PCI_MSI_ADDRESS_LO, - dd->ipath_msi_lo); - ipath_cdbg(VERBOSE, "Writing msi_lo 0x%x to config offset 0x%x\n", - dd->ipath_msi_hi, pos + PCI_MSI_ADDRESS_HI); - pci_write_config_dword(dd->pcidev, pos + PCI_MSI_ADDRESS_HI, - dd->ipath_msi_hi); - pci_read_config_word(dd->pcidev, pos + PCI_MSI_FLAGS, &control); - if (!(control & PCI_MSI_FLAGS_ENABLE)) { - ipath_cdbg(VERBOSE, "MSI control at off %x was %x, " - "setting MSI enable (%x)\n", pos + PCI_MSI_FLAGS, - control, control | PCI_MSI_FLAGS_ENABLE); - control |= PCI_MSI_FLAGS_ENABLE; - pci_write_config_word(dd->pcidev, pos + PCI_MSI_FLAGS, - control); - } - /* now rewrite the data (vector) info */ - pci_write_config_word(dd->pcidev, pos + - ((control & PCI_MSI_FLAGS_64BIT) ? 12 : 8), - dd->ipath_msi_data); - ret = 1; - -bail: - if (!ret) { - ipath_dbg("Using INTx, MSI disabled or not configured\n"); - ipath_enable_intx(dd->pcidev); - ret = 1; - } - /* - * We restore the cachelinesize also, although it doesn't really - * matter. - */ - pci_write_config_byte(dd->pcidev, PCI_CACHE_LINE_SIZE, - dd->ipath_pci_cacheline); - /* and now set the pci master bit again */ - pci_set_master(dd->pcidev); - - return ret; -} - -/* - * This routine sleeps, so it can only be called from user context, not - * from interrupt context. If we need interrupt context, we can split - * it into two routines. - */ -static int ipath_setup_7220_reset(struct ipath_devdata *dd) -{ - u64 val; - int i; - int ret; - u16 cmdval; - - pci_read_config_word(dd->pcidev, PCI_COMMAND, &cmdval); - - /* Use dev_err so it shows up in logs, etc. */ - ipath_dev_err(dd, "Resetting InfiniPath unit %u\n", dd->ipath_unit); - - /* keep chip from being accessed in a few places */ - dd->ipath_flags &= ~(IPATH_INITTED | IPATH_PRESENT); - val = dd->ipath_control | INFINIPATH_C_RESET; - ipath_write_kreg(dd, dd->ipath_kregs->kr_control, val); - mb(); - - for (i = 1; i <= 5; i++) { - int r; - - /* - * Allow MBIST, etc. to complete; longer on each retry. - * We sometimes get machine checks from bus timeout if no - * response, so for now, make it *really* long. - */ - msleep(1000 + (1 + i) * 2000); - r = pci_write_config_dword(dd->pcidev, PCI_BASE_ADDRESS_0, - dd->ipath_pcibar0); - if (r) - ipath_dev_err(dd, "rewrite of BAR0 failed: %d\n", r); - r = pci_write_config_dword(dd->pcidev, PCI_BASE_ADDRESS_1, - dd->ipath_pcibar1); - if (r) - ipath_dev_err(dd, "rewrite of BAR1 failed: %d\n", r); - /* now re-enable memory access */ - pci_write_config_word(dd->pcidev, PCI_COMMAND, cmdval); - r = pci_enable_device(dd->pcidev); - if (r) - ipath_dev_err(dd, "pci_enable_device failed after " - "reset: %d\n", r); - /* - * whether it fully enabled or not, mark as present, - * again (but not INITTED) - */ - dd->ipath_flags |= IPATH_PRESENT; - val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_revision); - if (val == dd->ipath_revision) { - ipath_cdbg(VERBOSE, "Got matching revision " - "register %llx on try %d\n", - (unsigned long long) val, i); - ret = ipath_reinit_msi(dd); - goto bail; - } - /* Probably getting -1 back */ - ipath_dbg("Didn't get expected revision register, " - "got %llx, try %d\n", (unsigned long long) val, - i + 1); - } - ret = 0; /* failed */ - -bail: - if (ret) - ipath_7220_pcie_params(dd, dd->ipath_boardrev); - - return ret; -} - -/** - * ipath_7220_put_tid - write a TID to the chip - * @dd: the infinipath device - * @tidptr: pointer to the expected TID (in chip) to update - * @tidtype: 0 for eager, 1 for expected - * @pa: physical address of in memory buffer; ipath_tidinvalid if freeing - * - * This exists as a separate routine to allow for selection of the - * appropriate "flavor". The static calls in cleanup just use the - * revision-agnostic form, as they are not performance critical. - */ -static void ipath_7220_put_tid(struct ipath_devdata *dd, u64 __iomem *tidptr, - u32 type, unsigned long pa) -{ - if (pa != dd->ipath_tidinvalid) { - u64 chippa = pa >> IBA7220_TID_PA_SHIFT; - - /* paranoia checks */ - if (pa != (chippa << IBA7220_TID_PA_SHIFT)) { - dev_info(&dd->pcidev->dev, "BUG: physaddr %lx " - "not 2KB aligned!\n", pa); - return; - } - if (chippa >= (1UL << IBA7220_TID_SZ_SHIFT)) { - ipath_dev_err(dd, - "BUG: Physical page address 0x%lx " - "larger than supported\n", pa); - return; - } - - if (type == RCVHQ_RCV_TYPE_EAGER) - chippa |= dd->ipath_tidtemplate; - else /* for now, always full 4KB page */ - chippa |= IBA7220_TID_SZ_4K; - writeq(chippa, tidptr); - } else - writeq(pa, tidptr); - mmiowb(); -} - -/** - * ipath_7220_clear_tid - clear all TID entries for a port, expected and eager - * @dd: the infinipath device - * @port: the port - * - * clear all TID entries for a port, expected and eager. - * Used from ipath_close(). On this chip, TIDs are only 32 bits, - * not 64, but they are still on 64 bit boundaries, so tidbase - * is declared as u64 * for the pointer math, even though we write 32 bits - */ -static void ipath_7220_clear_tids(struct ipath_devdata *dd, unsigned port) -{ - u64 __iomem *tidbase; - unsigned long tidinv; - int i; - - if (!dd->ipath_kregbase) - return; - - ipath_cdbg(VERBOSE, "Invalidate TIDs for port %u\n", port); - - tidinv = dd->ipath_tidinvalid; - tidbase = (u64 __iomem *) - ((char __iomem *)(dd->ipath_kregbase) + - dd->ipath_rcvtidbase + - port * dd->ipath_rcvtidcnt * sizeof(*tidbase)); - - for (i = 0; i < dd->ipath_rcvtidcnt; i++) - ipath_7220_put_tid(dd, &tidbase[i], RCVHQ_RCV_TYPE_EXPECTED, - tidinv); - - tidbase = (u64 __iomem *) - ((char __iomem *)(dd->ipath_kregbase) + - dd->ipath_rcvegrbase + port_egrtid_idx(dd, port) - * sizeof(*tidbase)); - - for (i = port ? dd->ipath_rcvegrcnt : dd->ipath_p0_rcvegrcnt; i; i--) - ipath_7220_put_tid(dd, &tidbase[i-1], RCVHQ_RCV_TYPE_EAGER, - tidinv); -} - -/** - * ipath_7220_tidtemplate - setup constants for TID updates - * @dd: the infinipath device - * - * We setup stuff that we use a lot, to avoid calculating each time - */ -static void ipath_7220_tidtemplate(struct ipath_devdata *dd) -{ - /* For now, we always allocate 4KB buffers (at init) so we can - * receive max size packets. We may want a module parameter to - * specify 2KB or 4KB and/or make be per port instead of per device - * for those who want to reduce memory footprint. Note that the - * ipath_rcvhdrentsize size must be large enough to hold the largest - * IB header (currently 96 bytes) that we expect to handle (plus of - * course the 2 dwords of RHF). - */ - if (dd->ipath_rcvegrbufsize == 2048) - dd->ipath_tidtemplate = IBA7220_TID_SZ_2K; - else if (dd->ipath_rcvegrbufsize == 4096) - dd->ipath_tidtemplate = IBA7220_TID_SZ_4K; - else { - dev_info(&dd->pcidev->dev, "BUG: unsupported egrbufsize " - "%u, using %u\n", dd->ipath_rcvegrbufsize, - 4096); - dd->ipath_tidtemplate = IBA7220_TID_SZ_4K; - } - dd->ipath_tidinvalid = 0; -} - -static int ipath_7220_early_init(struct ipath_devdata *dd) -{ - u32 i, s; - - if (strcmp(int_type, "auto") && - strcmp(int_type, "force_msi") && - strcmp(int_type, "force_intx")) { - ipath_dev_err(dd, "Invalid interrupt_type: '%s', expecting " - "auto, force_msi or force_intx\n", int_type); - return -EINVAL; - } - - /* - * Control[4] has been added to change the arbitration within - * the SDMA engine between favoring data fetches over descriptor - * fetches. ipath_sdma_fetch_arb==0 gives data fetches priority. - */ - if (ipath_sdma_fetch_arb && (dd->ipath_minrev > 1)) - dd->ipath_control |= 1<<4; - - dd->ipath_flags |= IPATH_4BYTE_TID; - - /* - * For openfabrics, we need to be able to handle an IB header of - * 24 dwords. HT chip has arbitrary sized receive buffers, so we - * made them the same size as the PIO buffers. This chip does not - * handle arbitrary size buffers, so we need the header large enough - * to handle largest IB header, but still have room for a 2KB MTU - * standard IB packet. - */ - dd->ipath_rcvhdrentsize = 24; - dd->ipath_rcvhdrsize = IPATH_DFLT_RCVHDRSIZE; - dd->ipath_rhf_offset = - dd->ipath_rcvhdrentsize - sizeof(u64) / sizeof(u32); - - dd->ipath_rcvegrbufsize = ipath_mtu4096 ? 4096 : 2048; - /* - * the min() check here is currently a nop, but it may not always - * be, depending on just how we do ipath_rcvegrbufsize - */ - dd->ipath_ibmaxlen = min(ipath_mtu4096 ? dd->ipath_piosize4k : - dd->ipath_piosize2k, - dd->ipath_rcvegrbufsize + - (dd->ipath_rcvhdrentsize << 2)); - dd->ipath_init_ibmaxlen = dd->ipath_ibmaxlen; - - ipath_7220_config_jint(dd, INFINIPATH_JINT_DEFAULT_IDLE_TICKS, - INFINIPATH_JINT_DEFAULT_MAX_PACKETS); - - if (dd->ipath_boardrev) /* no eeprom on emulator */ - ipath_get_eeprom_info(dd); - - /* start of code to check and print procmon */ - s = ipath_read_kreg32(dd, IPATH_KREG_OFFSET(ProcMon)); - s &= ~(1U<<31); /* clear done bit */ - s |= 1U<<14; /* clear counter (write 1 to clear) */ - ipath_write_kreg(dd, IPATH_KREG_OFFSET(ProcMon), s); - /* make sure clear_counter low long enough before start */ - ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); - ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); - - s &= ~(1U<<14); /* allow counter to count (before starting) */ - ipath_write_kreg(dd, IPATH_KREG_OFFSET(ProcMon), s); - ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); - ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); - s = ipath_read_kreg32(dd, IPATH_KREG_OFFSET(ProcMon)); - - s |= 1U<<15; /* start the counter */ - s &= ~(1U<<31); /* clear done bit */ - s &= ~0x7ffU; /* clear frequency bits */ - s |= 0xe29; /* set frequency bits, in case cleared */ - ipath_write_kreg(dd, IPATH_KREG_OFFSET(ProcMon), s); - - s = 0; - for (i = 500; i > 0 && !(s&(1ULL<<31)); i--) { - ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); - s = ipath_read_kreg32(dd, IPATH_KREG_OFFSET(ProcMon)); - } - if (!(s&(1U<<31))) - ipath_dev_err(dd, "ProcMon register not valid: 0x%x\n", s); - else - ipath_dbg("ProcMon=0x%x, count=0x%x\n", s, (s>>16)&0x1ff); - - return 0; -} - -/** - * ipath_init_7220_get_base_info - set chip-specific flags for user code - * @pd: the infinipath port - * @kbase: ipath_base_info pointer - * - * We set the PCIE flag because the lower bandwidth on PCIe vs - * HyperTransport can affect some user packet algorithims. - */ -static int ipath_7220_get_base_info(struct ipath_portdata *pd, void *kbase) -{ - struct ipath_base_info *kinfo = kbase; - - kinfo->spi_runtime_flags |= - IPATH_RUNTIME_PCIE | IPATH_RUNTIME_NODMA_RTAIL | - IPATH_RUNTIME_SDMA; - - return 0; -} - -static void ipath_7220_free_irq(struct ipath_devdata *dd) -{ - free_irq(dd->ipath_irq, dd); - dd->ipath_irq = 0; -} - -static struct ipath_message_header * -ipath_7220_get_msgheader(struct ipath_devdata *dd, __le32 *rhf_addr) -{ - u32 offset = ipath_hdrget_offset(rhf_addr); - - return (struct ipath_message_header *) - (rhf_addr - dd->ipath_rhf_offset + offset); -} - -static void ipath_7220_config_ports(struct ipath_devdata *dd, ushort cfgports) -{ - u32 nchipports; - - nchipports = ipath_read_kreg32(dd, dd->ipath_kregs->kr_portcnt); - if (!cfgports) { - int ncpus = num_online_cpus(); - - if (ncpus <= 4) - dd->ipath_portcnt = 5; - else if (ncpus <= 8) - dd->ipath_portcnt = 9; - if (dd->ipath_portcnt) - ipath_dbg("Auto-configured for %u ports, %d cpus " - "online\n", dd->ipath_portcnt, ncpus); - } else if (cfgports <= nchipports) - dd->ipath_portcnt = cfgports; - if (!dd->ipath_portcnt) /* none of the above, set to max */ - dd->ipath_portcnt = nchipports; - /* - * chip can be configured for 5, 9, or 17 ports, and choice - * affects number of eager TIDs per port (1K, 2K, 4K). - */ - if (dd->ipath_portcnt > 9) - dd->ipath_rcvctrl |= 2ULL << IBA7220_R_PORTCFG_SHIFT; - else if (dd->ipath_portcnt > 5) - dd->ipath_rcvctrl |= 1ULL << IBA7220_R_PORTCFG_SHIFT; - /* else configure for default 5 receive ports */ - ipath_write_kreg(dd, dd->ipath_kregs->kr_rcvctrl, - dd->ipath_rcvctrl); - dd->ipath_p0_rcvegrcnt = 2048; /* always */ - if (dd->ipath_flags & IPATH_HAS_SEND_DMA) - dd->ipath_pioreserved = 3; /* kpiobufs used for PIO */ -} - - -static int ipath_7220_get_ib_cfg(struct ipath_devdata *dd, int which) -{ - int lsb, ret = 0; - u64 maskr; /* right-justified mask */ - - switch (which) { - case IPATH_IB_CFG_HRTBT: /* Get Heartbeat off/enable/auto */ - lsb = IBA7220_IBC_HRTBT_SHIFT; - maskr = IBA7220_IBC_HRTBT_MASK; - break; - - case IPATH_IB_CFG_LWID_ENB: /* Get allowed Link-width */ - ret = dd->ipath_link_width_enabled; - goto done; - - case IPATH_IB_CFG_LWID: /* Get currently active Link-width */ - ret = dd->ipath_link_width_active; - goto done; - - case IPATH_IB_CFG_SPD_ENB: /* Get allowed Link speeds */ - ret = dd->ipath_link_speed_enabled; - goto done; - - case IPATH_IB_CFG_SPD: /* Get current Link spd */ - ret = dd->ipath_link_speed_active; - goto done; - - case IPATH_IB_CFG_RXPOL_ENB: /* Get Auto-RX-polarity enable */ - lsb = IBA7220_IBC_RXPOL_SHIFT; - maskr = IBA7220_IBC_RXPOL_MASK; - break; - - case IPATH_IB_CFG_LREV_ENB: /* Get Auto-Lane-reversal enable */ - lsb = IBA7220_IBC_LREV_SHIFT; - maskr = IBA7220_IBC_LREV_MASK; - break; - - case IPATH_IB_CFG_LINKLATENCY: - ret = ipath_read_kreg64(dd, dd->ipath_kregs->kr_ibcddrstatus) - & IBA7220_DDRSTAT_LINKLAT_MASK; - goto done; - - default: - ret = -ENOTSUPP; - goto done; - } - ret = (int)((dd->ipath_ibcddrctrl >> lsb) & maskr); -done: - return ret; -} - -static int ipath_7220_set_ib_cfg(struct ipath_devdata *dd, int which, u32 val) -{ - int lsb, ret = 0, setforce = 0; - u64 maskr; /* right-justified mask */ - - switch (which) { - case IPATH_IB_CFG_LIDLMC: - /* - * Set LID and LMC. Combined to avoid possible hazard - * caller puts LMC in 16MSbits, DLID in 16LSbits of val - */ - lsb = IBA7220_IBC_DLIDLMC_SHIFT; - maskr = IBA7220_IBC_DLIDLMC_MASK; - break; - - case IPATH_IB_CFG_HRTBT: /* set Heartbeat off/enable/auto */ - if (val & IPATH_IB_HRTBT_ON && - (dd->ipath_flags & IPATH_NO_HRTBT)) - goto bail; - lsb = IBA7220_IBC_HRTBT_SHIFT; - maskr = IBA7220_IBC_HRTBT_MASK; - break; - - case IPATH_IB_CFG_LWID_ENB: /* set allowed Link-width */ - /* - * As with speed, only write the actual register if - * the link is currently down, otherwise takes effect - * on next link change. - */ - dd->ipath_link_width_enabled = val; - if ((dd->ipath_flags & (IPATH_LINKDOWN|IPATH_LINKINIT)) != - IPATH_LINKDOWN) - goto bail; - /* - * We set the IPATH_IB_FORCE_NOTIFY bit so updown - * will get called because we want update - * link_width_active, and the change may not take - * effect for some time (if we are in POLL), so this - * flag will force the updown routine to be called - * on the next ibstatuschange down interrupt, even - * if it's not an down->up transition. - */ - val--; /* convert from IB to chip */ - maskr = IBA7220_IBC_WIDTH_MASK; - lsb = IBA7220_IBC_WIDTH_SHIFT; - setforce = 1; - dd->ipath_flags |= IPATH_IB_FORCE_NOTIFY; - break; - - case IPATH_IB_CFG_SPD_ENB: /* set allowed Link speeds */ - /* - * If we turn off IB1.2, need to preset SerDes defaults, - * but not right now. Set a flag for the next time - * we command the link down. As with width, only write the - * actual register if the link is currently down, otherwise - * takes effect on next link change. Since setting is being - * explictly requested (via MAD or sysfs), clear autoneg - * failure status if speed autoneg is enabled. - */ - dd->ipath_link_speed_enabled = val; - if (dd->ipath_ibcddrctrl & IBA7220_IBC_IBTA_1_2_MASK && - !(val & (val - 1))) - dd->ipath_presets_needed = 1; - if ((dd->ipath_flags & (IPATH_LINKDOWN|IPATH_LINKINIT)) != - IPATH_LINKDOWN) - goto bail; - /* - * We set the IPATH_IB_FORCE_NOTIFY bit so updown - * will get called because we want update - * link_speed_active, and the change may not take - * effect for some time (if we are in POLL), so this - * flag will force the updown routine to be called - * on the next ibstatuschange down interrupt, even - * if it's not an down->up transition. When setting - * speed autoneg, clear AUTONEG_FAILED. - */ - if (val == (IPATH_IB_SDR | IPATH_IB_DDR)) { - val = IBA7220_IBC_SPEED_AUTONEG_MASK | - IBA7220_IBC_IBTA_1_2_MASK; - dd->ipath_flags &= ~IPATH_IB_AUTONEG_FAILED; - } else - val = val == IPATH_IB_DDR ? IBA7220_IBC_SPEED_DDR - : IBA7220_IBC_SPEED_SDR; - maskr = IBA7220_IBC_SPEED_AUTONEG_MASK | - IBA7220_IBC_IBTA_1_2_MASK; - lsb = 0; /* speed bits are low bits */ - setforce = 1; - break; - - case IPATH_IB_CFG_RXPOL_ENB: /* set Auto-RX-polarity enable */ - lsb = IBA7220_IBC_RXPOL_SHIFT; - maskr = IBA7220_IBC_RXPOL_MASK; - break; - - case IPATH_IB_CFG_LREV_ENB: /* set Auto-Lane-reversal enable */ - lsb = IBA7220_IBC_LREV_SHIFT; - maskr = IBA7220_IBC_LREV_MASK; - break; - - default: - ret = -ENOTSUPP; - goto bail; - } - dd->ipath_ibcddrctrl &= ~(maskr << lsb); - dd->ipath_ibcddrctrl |= (((u64) val & maskr) << lsb); - ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcddrctrl, - dd->ipath_ibcddrctrl); - if (setforce) - dd->ipath_flags |= IPATH_IB_FORCE_NOTIFY; -bail: - return ret; -} - -static void ipath_7220_read_counters(struct ipath_devdata *dd, - struct infinipath_counters *cntrs) -{ - u64 *counters = (u64 *) cntrs; - int i; - - for (i = 0; i < sizeof(*cntrs) / sizeof(u64); i++) - counters[i] = ipath_snap_cntr(dd, i); -} - -/* if we are using MSI, try to fallback to INTx */ -static int ipath_7220_intr_fallback(struct ipath_devdata *dd) -{ - if (dd->ipath_msi_lo) { - dev_info(&dd->pcidev->dev, "MSI interrupt not detected," - " trying INTx interrupts\n"); - ipath_7220_nomsi(dd); - ipath_enable_intx(dd->pcidev); - /* - * some newer kernels require free_irq before disable_msi, - * and irq can be changed during disable and intx enable - * and we need to therefore use the pcidev->irq value, - * not our saved MSI value. - */ - dd->ipath_irq = dd->pcidev->irq; - if (request_irq(dd->ipath_irq, ipath_intr, IRQF_SHARED, - IPATH_DRV_NAME, dd)) - ipath_dev_err(dd, - "Could not re-request_irq for INTx\n"); - return 1; - } - return 0; -} - -/* - * reset the XGXS (between serdes and IBC). Slightly less intrusive - * than resetting the IBC or external link state, and useful in some - * cases to cause some retraining. To do this right, we reset IBC - * as well. - */ -static void ipath_7220_xgxs_reset(struct ipath_devdata *dd) -{ - u64 val, prev_val; - - prev_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig); - val = prev_val | INFINIPATH_XGXS_RESET; - prev_val &= ~INFINIPATH_XGXS_RESET; /* be sure */ - ipath_write_kreg(dd, dd->ipath_kregs->kr_control, - dd->ipath_control & ~INFINIPATH_C_LINKENABLE); - ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, val); - ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); - ipath_write_kreg(dd, dd->ipath_kregs->kr_xgxsconfig, prev_val); - ipath_write_kreg(dd, dd->ipath_kregs->kr_control, - dd->ipath_control); -} - - -/* Still needs cleanup, too much hardwired stuff */ -static void autoneg_send(struct ipath_devdata *dd, - u32 *hdr, u32 dcnt, u32 *data) -{ - int i; - u64 cnt; - u32 __iomem *piobuf; - u32 pnum; - - i = 0; - cnt = 7 + dcnt + 1; /* 7 dword header, dword data, icrc */ - while (!(piobuf = ipath_getpiobuf(dd, cnt, &pnum))) { - if (i++ > 15) { - ipath_dbg("Couldn't get pio buffer for send\n"); - return; - } - udelay(2); - } - if (dd->ipath_flags&IPATH_HAS_PBC_CNT) - cnt |= 0x80000000UL<<32; /* mark as VL15 */ - writeq(cnt, piobuf); - ipath_flush_wc(); - __iowrite32_copy(piobuf + 2, hdr, 7); - __iowrite32_copy(piobuf + 9, data, dcnt); - ipath_flush_wc(); -} - -/* - * _start packet gets sent twice at start, _done gets sent twice at end - */ -static void ipath_autoneg_send(struct ipath_devdata *dd, int which) -{ - static u32 swapped; - u32 dw, i, hcnt, dcnt, *data; - static u32 hdr[7] = { 0xf002ffff, 0x48ffff, 0x6400abba }; - static u32 madpayload_start[0x40] = { - 0x1810103, 0x1, 0x0, 0x0, 0x2c90000, 0x2c9, 0x0, 0x0, - 0xffffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x1388, 0x15e, 0x1, /* rest 0's */ - }; - static u32 madpayload_done[0x40] = { - 0x1810103, 0x1, 0x0, 0x0, 0x2c90000, 0x2c9, 0x0, 0x0, - 0xffffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x40000001, 0x1388, 0x15e, /* rest 0's */ - }; - dcnt = ARRAY_SIZE(madpayload_start); - hcnt = ARRAY_SIZE(hdr); - if (!swapped) { - /* for maintainability, do it at runtime */ - for (i = 0; i < hcnt; i++) { - dw = (__force u32) cpu_to_be32(hdr[i]); - hdr[i] = dw; - } - for (i = 0; i < dcnt; i++) { - dw = (__force u32) cpu_to_be32(madpayload_start[i]); - madpayload_start[i] = dw; - dw = (__force u32) cpu_to_be32(madpayload_done[i]); - madpayload_done[i] = dw; - } - swapped = 1; - } - - data = which ? madpayload_done : madpayload_start; - ipath_cdbg(PKT, "Sending %s special MADs\n", which?"done":"start"); - - autoneg_send(dd, hdr, dcnt, data); - ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); - udelay(2); - autoneg_send(dd, hdr, dcnt, data); - ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); - udelay(2); -} - - - -/* - * Do the absolute minimum to cause an IB speed change, and make it - * ready, but don't actually trigger the change. The caller will - * do that when ready (if link is in Polling training state, it will - * happen immediately, otherwise when link next goes down) - * - * This routine should only be used as part of the DDR autonegotation - * code for devices that are not compliant with IB 1.2 (or code that - * fixes things up for same). - * - * When link has gone down, and autoneg enabled, or autoneg has - * failed and we give up until next time we set both speeds, and - * then we want IBTA enabled as well as "use max enabled speed. - */ -static void set_speed_fast(struct ipath_devdata *dd, u32 speed) -{ - dd->ipath_ibcddrctrl &= ~(IBA7220_IBC_SPEED_AUTONEG_MASK | - IBA7220_IBC_IBTA_1_2_MASK | - (IBA7220_IBC_WIDTH_MASK << IBA7220_IBC_WIDTH_SHIFT)); - - if (speed == (IPATH_IB_SDR | IPATH_IB_DDR)) - dd->ipath_ibcddrctrl |= IBA7220_IBC_SPEED_AUTONEG_MASK | - IBA7220_IBC_IBTA_1_2_MASK; - else - dd->ipath_ibcddrctrl |= speed == IPATH_IB_DDR ? - IBA7220_IBC_SPEED_DDR : IBA7220_IBC_SPEED_SDR; - - /* - * Convert from IB-style 1 = 1x, 2 = 4x, 3 = auto - * to chip-centric 0 = 1x, 1 = 4x, 2 = auto - */ - dd->ipath_ibcddrctrl |= (u64)(dd->ipath_link_width_enabled - 1) << - IBA7220_IBC_WIDTH_SHIFT; - ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcddrctrl, - dd->ipath_ibcddrctrl); - ipath_cdbg(VERBOSE, "setup for IB speed (%x) done\n", speed); -} - - -/* - * this routine is only used when we are not talking to another - * IB 1.2-compliant device that we think can do DDR. - * (This includes all existing switch chips as of Oct 2007.) - * 1.2-compliant devices go directly to DDR prior to reaching INIT - */ -static void try_auto_neg(struct ipath_devdata *dd) -{ - /* - * required for older non-IB1.2 DDR switches. Newer - * non-IB-compliant switches don't need it, but so far, - * aren't bothered by it either. "Magic constant" - */ - ipath_write_kreg(dd, IPATH_KREG_OFFSET(IBNCModeCtrl), - 0x3b9dc07); - dd->ipath_flags |= IPATH_IB_AUTONEG_INPROG; - ipath_autoneg_send(dd, 0); - set_speed_fast(dd, IPATH_IB_DDR); - ipath_toggle_rclkrls(dd); - /* 2 msec is minimum length of a poll cycle */ - schedule_delayed_work(&dd->ipath_autoneg_work, - msecs_to_jiffies(2)); -} - - -static int ipath_7220_ib_updown(struct ipath_devdata *dd, int ibup, u64 ibcs) -{ - int ret = 0, symadj = 0; - u32 ltstate = ipath_ib_linkstate(dd, ibcs); - - dd->ipath_link_width_active = - ((ibcs >> IBA7220_IBCS_LINKWIDTH_SHIFT) & 1) ? - IB_WIDTH_4X : IB_WIDTH_1X; - dd->ipath_link_speed_active = - ((ibcs >> IBA7220_IBCS_LINKSPEED_SHIFT) & 1) ? - IPATH_IB_DDR : IPATH_IB_SDR; - - if (!ibup) { - /* - * when link goes down we don't want aeq running, so it - * won't't interfere with IBC training, etc., and we need - * to go back to the static SerDes preset values - */ - if (dd->ipath_x1_fix_tries && - ltstate <= INFINIPATH_IBCS_LT_STATE_SLEEPQUIET && - ltstate != INFINIPATH_IBCS_LT_STATE_LINKUP) - dd->ipath_x1_fix_tries = 0; - if (!(dd->ipath_flags & (IPATH_IB_AUTONEG_FAILED | - IPATH_IB_AUTONEG_INPROG))) - set_speed_fast(dd, dd->ipath_link_speed_enabled); - if (!(dd->ipath_flags & IPATH_IB_AUTONEG_INPROG)) { - ipath_cdbg(VERBOSE, "Setting RXEQ defaults\n"); - ipath_sd7220_presets(dd); - } - /* this might better in ipath_sd7220_presets() */ - ipath_set_relock_poll(dd, ibup); - } else { - if (ipath_compat_ddr_negotiate && - !(dd->ipath_flags & (IPATH_IB_AUTONEG_FAILED | - IPATH_IB_AUTONEG_INPROG)) && - dd->ipath_link_speed_active == IPATH_IB_SDR && - (dd->ipath_link_speed_enabled & - (IPATH_IB_DDR | IPATH_IB_SDR)) == - (IPATH_IB_DDR | IPATH_IB_SDR) && - dd->ipath_autoneg_tries < IPATH_AUTONEG_TRIES) { - /* we are SDR, and DDR auto-negotiation enabled */ - ++dd->ipath_autoneg_tries; - ipath_dbg("DDR negotiation try, %u/%u\n", - dd->ipath_autoneg_tries, - IPATH_AUTONEG_TRIES); - if (!dd->ibdeltainprog) { - dd->ibdeltainprog = 1; - dd->ibsymsnap = ipath_read_creg32(dd, - dd->ipath_cregs->cr_ibsymbolerrcnt); - dd->iblnkerrsnap = ipath_read_creg32(dd, - dd->ipath_cregs->cr_iblinkerrrecovcnt); - } - try_auto_neg(dd); - ret = 1; /* no other IB status change processing */ - } else if ((dd->ipath_flags & IPATH_IB_AUTONEG_INPROG) - && dd->ipath_link_speed_active == IPATH_IB_SDR) { - ipath_autoneg_send(dd, 1); - set_speed_fast(dd, IPATH_IB_DDR); - udelay(2); - ipath_toggle_rclkrls(dd); - ret = 1; /* no other IB status change processing */ - } else { - if ((dd->ipath_flags & IPATH_IB_AUTONEG_INPROG) && - (dd->ipath_link_speed_active & IPATH_IB_DDR)) { - ipath_dbg("Got to INIT with DDR autoneg\n"); - dd->ipath_flags &= ~(IPATH_IB_AUTONEG_INPROG - | IPATH_IB_AUTONEG_FAILED); - dd->ipath_autoneg_tries = 0; - /* re-enable SDR, for next link down */ - set_speed_fast(dd, - dd->ipath_link_speed_enabled); - wake_up(&dd->ipath_autoneg_wait); - symadj = 1; - } else if (dd->ipath_flags & IPATH_IB_AUTONEG_FAILED) { - /* - * clear autoneg failure flag, and do setup - * so we'll try next time link goes down and - * back to INIT (possibly connected to different - * device). - */ - ipath_dbg("INIT %sDR after autoneg failure\n", - (dd->ipath_link_speed_active & - IPATH_IB_DDR) ? "D" : "S"); - dd->ipath_flags &= ~IPATH_IB_AUTONEG_FAILED; - dd->ipath_ibcddrctrl |= - IBA7220_IBC_IBTA_1_2_MASK; - ipath_write_kreg(dd, - IPATH_KREG_OFFSET(IBNCModeCtrl), 0); - symadj = 1; - } - } - /* - * if we are in 1X on rev1 only, and are in autoneg width, - * it could be due to an xgxs problem, so if we haven't - * already tried, try twice to get to 4X; if we - * tried, and couldn't, report it, since it will - * probably not be what is desired. - */ - if (dd->ipath_minrev == 1 && - (dd->ipath_link_width_enabled & (IB_WIDTH_1X | - IB_WIDTH_4X)) == (IB_WIDTH_1X | IB_WIDTH_4X) - && dd->ipath_link_width_active == IB_WIDTH_1X - && dd->ipath_x1_fix_tries < 3) { - if (++dd->ipath_x1_fix_tries == 3) { - dev_info(&dd->pcidev->dev, - "IB link is in 1X mode\n"); - if (!(dd->ipath_flags & - IPATH_IB_AUTONEG_INPROG)) - symadj = 1; - } - else { - ipath_cdbg(VERBOSE, "IB 1X in " - "auto-width, try %u to be " - "sure it's really 1X; " - "ltstate %u\n", - dd->ipath_x1_fix_tries, - ltstate); - dd->ipath_f_xgxs_reset(dd); - ret = 1; /* skip other processing */ - } - } else if (!(dd->ipath_flags & IPATH_IB_AUTONEG_INPROG)) - symadj = 1; - - if (!ret) { - dd->delay_mult = rate_to_delay - [(ibcs >> IBA7220_IBCS_LINKSPEED_SHIFT) & 1] - [(ibcs >> IBA7220_IBCS_LINKWIDTH_SHIFT) & 1]; - - ipath_set_relock_poll(dd, ibup); - } - } - - if (symadj) { - if (dd->ibdeltainprog) { - dd->ibdeltainprog = 0; - dd->ibsymdelta += ipath_read_creg32(dd, - dd->ipath_cregs->cr_ibsymbolerrcnt) - - dd->ibsymsnap; - dd->iblnkerrdelta += ipath_read_creg32(dd, - dd->ipath_cregs->cr_iblinkerrrecovcnt) - - dd->iblnkerrsnap; - } - } else if (!ibup && !dd->ibdeltainprog - && !(dd->ipath_flags & IPATH_IB_AUTONEG_INPROG)) { - dd->ibdeltainprog = 1; - dd->ibsymsnap = ipath_read_creg32(dd, - dd->ipath_cregs->cr_ibsymbolerrcnt); - dd->iblnkerrsnap = ipath_read_creg32(dd, - dd->ipath_cregs->cr_iblinkerrrecovcnt); - } - - if (!ret) - ipath_setup_7220_setextled(dd, ipath_ib_linkstate(dd, ibcs), - ltstate); - return ret; -} - - -/* - * Handle the empirically determined mechanism for auto-negotiation - * of DDR speed with switches. - */ -static void autoneg_work(struct work_struct *work) -{ - struct ipath_devdata *dd; - u64 startms; - u32 lastlts, i; - - dd = container_of(work, struct ipath_devdata, - ipath_autoneg_work.work); - - startms = jiffies_to_msecs(jiffies); - - /* - * busy wait for this first part, it should be at most a - * few hundred usec, since we scheduled ourselves for 2msec. - */ - for (i = 0; i < 25; i++) { - lastlts = ipath_ib_linktrstate(dd, dd->ipath_lastibcstat); - if (lastlts == INFINIPATH_IBCS_LT_STATE_POLLQUIET) { - ipath_set_linkstate(dd, IPATH_IB_LINKDOWN_DISABLE); - break; - } - udelay(100); - } - - if (!(dd->ipath_flags & IPATH_IB_AUTONEG_INPROG)) - goto done; /* we got there early or told to stop */ - - /* we expect this to timeout */ - if (wait_event_timeout(dd->ipath_autoneg_wait, - !(dd->ipath_flags & IPATH_IB_AUTONEG_INPROG), - msecs_to_jiffies(90))) - goto done; - - ipath_toggle_rclkrls(dd); - - /* we expect this to timeout */ - if (wait_event_timeout(dd->ipath_autoneg_wait, - !(dd->ipath_flags & IPATH_IB_AUTONEG_INPROG), - msecs_to_jiffies(1700))) - goto done; - - set_speed_fast(dd, IPATH_IB_SDR); - ipath_toggle_rclkrls(dd); - - /* - * wait up to 250 msec for link to train and get to INIT at DDR; - * this should terminate early - */ - wait_event_timeout(dd->ipath_autoneg_wait, - !(dd->ipath_flags & IPATH_IB_AUTONEG_INPROG), - msecs_to_jiffies(250)); -done: - if (dd->ipath_flags & IPATH_IB_AUTONEG_INPROG) { - ipath_dbg("Did not get to DDR INIT (%x) after %Lu msecs\n", - ipath_ib_state(dd, dd->ipath_lastibcstat), - (unsigned long long) jiffies_to_msecs(jiffies)-startms); - dd->ipath_flags &= ~IPATH_IB_AUTONEG_INPROG; - if (dd->ipath_autoneg_tries == IPATH_AUTONEG_TRIES) { - dd->ipath_flags |= IPATH_IB_AUTONEG_FAILED; - ipath_dbg("Giving up on DDR until next IB " - "link Down\n"); - dd->ipath_autoneg_tries = 0; - } - set_speed_fast(dd, dd->ipath_link_speed_enabled); - } -} - - -/** - * ipath_init_iba7220_funcs - set up the chip-specific function pointers - * @dd: the infinipath device - * - * This is global, and is called directly at init to set up the - * chip-specific function pointers for later use. - */ -void ipath_init_iba7220_funcs(struct ipath_devdata *dd) -{ - dd->ipath_f_intrsetup = ipath_7220_intconfig; - dd->ipath_f_bus = ipath_setup_7220_config; - dd->ipath_f_reset = ipath_setup_7220_reset; - dd->ipath_f_get_boardname = ipath_7220_boardname; - dd->ipath_f_init_hwerrors = ipath_7220_init_hwerrors; - dd->ipath_f_early_init = ipath_7220_early_init; - dd->ipath_f_handle_hwerrors = ipath_7220_handle_hwerrors; - dd->ipath_f_quiet_serdes = ipath_7220_quiet_serdes; - dd->ipath_f_bringup_serdes = ipath_7220_bringup_serdes; - dd->ipath_f_clear_tids = ipath_7220_clear_tids; - dd->ipath_f_put_tid = ipath_7220_put_tid; - dd->ipath_f_cleanup = ipath_setup_7220_cleanup; - dd->ipath_f_setextled = ipath_setup_7220_setextled; - dd->ipath_f_get_base_info = ipath_7220_get_base_info; - dd->ipath_f_free_irq = ipath_7220_free_irq; - dd->ipath_f_tidtemplate = ipath_7220_tidtemplate; - dd->ipath_f_intr_fallback = ipath_7220_intr_fallback; - dd->ipath_f_xgxs_reset = ipath_7220_xgxs_reset; - dd->ipath_f_get_ib_cfg = ipath_7220_get_ib_cfg; - dd->ipath_f_set_ib_cfg = ipath_7220_set_ib_cfg; - dd->ipath_f_config_jint = ipath_7220_config_jint; - dd->ipath_f_config_ports = ipath_7220_config_ports; - dd->ipath_f_read_counters = ipath_7220_read_counters; - dd->ipath_f_get_msgheader = ipath_7220_get_msgheader; - dd->ipath_f_ib_updown = ipath_7220_ib_updown; - - /* initialize chip-specific variables */ - ipath_init_7220_variables(dd); -} diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h index b3d7efcdf021..6559af60bffd 100644 --- a/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/drivers/infiniband/hw/ipath/ipath_kernel.h @@ -1030,8 +1030,6 @@ void ipath_free_data(struct ipath_portdata *dd); u32 __iomem *ipath_getpiobuf(struct ipath_devdata *, u32, u32 *); void ipath_chg_pioavailkernel(struct ipath_devdata *dd, unsigned start, unsigned len, int avail); -void ipath_init_iba7220_funcs(struct ipath_devdata *); -void ipath_init_iba6120_funcs(struct ipath_devdata *); void ipath_init_iba6110_funcs(struct ipath_devdata *); void ipath_get_eeprom_info(struct ipath_devdata *); int ipath_update_eeprom_log(struct ipath_devdata *dd); diff --git a/drivers/infiniband/hw/ipath/ipath_sd7220.c b/drivers/infiniband/hw/ipath/ipath_sd7220.c deleted file mode 100644 index 2a68d9f624dd..000000000000 --- a/drivers/infiniband/hw/ipath/ipath_sd7220.c +++ /dev/null @@ -1,1462 +0,0 @@ -/* - * Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved. - * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -/* - * This file contains all of the code that is specific to the SerDes - * on the InfiniPath 7220 chip. - */ - -#include -#include - -#include "ipath_kernel.h" -#include "ipath_registers.h" -#include "ipath_7220.h" - -/* - * The IBSerDesMappTable is a memory that holds values to be stored in - * various SerDes registers by IBC. It is not part of the normal kregs - * map and is used in exactly one place, hence the #define below. - */ -#define KR_IBSerDesMappTable (0x94000 / (sizeof(uint64_t))) - -/* - * Below used for sdnum parameter, selecting one of the two sections - * used for PCIe, or the single SerDes used for IB. - */ -#define PCIE_SERDES0 0 -#define PCIE_SERDES1 1 - -/* - * The EPB requires addressing in a particular form. EPB_LOC() is intended - * to make #definitions a little more readable. - */ -#define EPB_ADDR_SHF 8 -#define EPB_LOC(chn, elt, reg) \ - (((elt & 0xf) | ((chn & 7) << 4) | ((reg & 0x3f) << 9)) << \ - EPB_ADDR_SHF) -#define EPB_IB_QUAD0_CS_SHF (25) -#define EPB_IB_QUAD0_CS (1U << EPB_IB_QUAD0_CS_SHF) -#define EPB_IB_UC_CS_SHF (26) -#define EPB_PCIE_UC_CS_SHF (27) -#define EPB_GLOBAL_WR (1U << (EPB_ADDR_SHF + 8)) - -/* Forward declarations. */ -static int ipath_sd7220_reg_mod(struct ipath_devdata *dd, int sdnum, u32 loc, - u32 data, u32 mask); -static int ibsd_mod_allchnls(struct ipath_devdata *dd, int loc, int val, - int mask); -static int ipath_sd_trimdone_poll(struct ipath_devdata *dd); -static void ipath_sd_trimdone_monitor(struct ipath_devdata *dd, - const char *where); -static int ipath_sd_setvals(struct ipath_devdata *dd); -static int ipath_sd_early(struct ipath_devdata *dd); -static int ipath_sd_dactrim(struct ipath_devdata *dd); -/* Set the registers that IBC may muck with to their default "preset" values */ -int ipath_sd7220_presets(struct ipath_devdata *dd); -static int ipath_internal_presets(struct ipath_devdata *dd); -/* Tweak the register (CMUCTRL5) that contains the TRIMSELF controls */ -static int ipath_sd_trimself(struct ipath_devdata *dd, int val); -static int epb_access(struct ipath_devdata *dd, int sdnum, int claim); - -void ipath_set_relock_poll(struct ipath_devdata *dd, int ibup); - -/* - * Below keeps track of whether the "once per power-on" initialization has - * been done, because uC code Version 1.32.17 or higher allows the uC to - * be reset at will, and Automatic Equalization may require it. So the - * state of the reset "pin", as reflected in was_reset parameter to - * ipath_sd7220_init() is no longer valid. Instead, we check for the - * actual uC code having been loaded. - */ -static int ipath_ibsd_ucode_loaded(struct ipath_devdata *dd) -{ - if (!dd->serdes_first_init_done && (ipath_sd7220_ib_vfy(dd) > 0)) - dd->serdes_first_init_done = 1; - return dd->serdes_first_init_done; -} - -/* repeat #define for local use. "Real" #define is in ipath_iba7220.c */ -#define INFINIPATH_HWE_IB_UC_MEMORYPARITYERR 0x0000004000000000ULL -#define IB_MPREG5 (EPB_LOC(6, 0, 0xE) | (1L << EPB_IB_UC_CS_SHF)) -#define IB_MPREG6 (EPB_LOC(6, 0, 0xF) | (1U << EPB_IB_UC_CS_SHF)) -#define UC_PAR_CLR_D 8 -#define UC_PAR_CLR_M 0xC -#define IB_CTRL2(chn) (EPB_LOC(chn, 7, 3) | EPB_IB_QUAD0_CS) -#define START_EQ1(chan) EPB_LOC(chan, 7, 0x27) - -void ipath_sd7220_clr_ibpar(struct ipath_devdata *dd) -{ - int ret; - - /* clear, then re-enable parity errs */ - ret = ipath_sd7220_reg_mod(dd, IB_7220_SERDES, IB_MPREG6, - UC_PAR_CLR_D, UC_PAR_CLR_M); - if (ret < 0) { - ipath_dev_err(dd, "Failed clearing IBSerDes Parity err\n"); - goto bail; - } - ret = ipath_sd7220_reg_mod(dd, IB_7220_SERDES, IB_MPREG6, 0, - UC_PAR_CLR_M); - - ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); - udelay(4); - ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrclear, - INFINIPATH_HWE_IB_UC_MEMORYPARITYERR); - ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); -bail: - return; -} - -/* - * After a reset or other unusual event, the epb interface may need - * to be re-synchronized, between the host and the uC. - * returns <0 for failure to resync within IBSD_RESYNC_TRIES (not expected) - */ -#define IBSD_RESYNC_TRIES 3 -#define IB_PGUDP(chn) (EPB_LOC((chn), 2, 1) | EPB_IB_QUAD0_CS) -#define IB_CMUDONE(chn) (EPB_LOC((chn), 7, 0xF) | EPB_IB_QUAD0_CS) - -static int ipath_resync_ibepb(struct ipath_devdata *dd) -{ - int ret, pat, tries, chn; - u32 loc; - - ret = -1; - chn = 0; - for (tries = 0; tries < (4 * IBSD_RESYNC_TRIES); ++tries) { - loc = IB_PGUDP(chn); - ret = ipath_sd7220_reg_mod(dd, IB_7220_SERDES, loc, 0, 0); - if (ret < 0) { - ipath_dev_err(dd, "Failed read in resync\n"); - continue; - } - if (ret != 0xF0 && ret != 0x55 && tries == 0) - ipath_dev_err(dd, "unexpected pattern in resync\n"); - pat = ret ^ 0xA5; /* alternate F0 and 55 */ - ret = ipath_sd7220_reg_mod(dd, IB_7220_SERDES, loc, pat, 0xFF); - if (ret < 0) { - ipath_dev_err(dd, "Failed write in resync\n"); - continue; - } - ret = ipath_sd7220_reg_mod(dd, IB_7220_SERDES, loc, 0, 0); - if (ret < 0) { - ipath_dev_err(dd, "Failed re-read in resync\n"); - continue; - } - if (ret != pat) { - ipath_dev_err(dd, "Failed compare1 in resync\n"); - continue; - } - loc = IB_CMUDONE(chn); - ret = ipath_sd7220_reg_mod(dd, IB_7220_SERDES, loc, 0, 0); - if (ret < 0) { - ipath_dev_err(dd, "Failed CMUDONE rd in resync\n"); - continue; - } - if ((ret & 0x70) != ((chn << 4) | 0x40)) { - ipath_dev_err(dd, "Bad CMUDONE value %02X, chn %d\n", - ret, chn); - continue; - } - if (++chn == 4) - break; /* Success */ - } - ipath_cdbg(VERBOSE, "Resync in %d tries\n", tries); - return (ret > 0) ? 0 : ret; -} - -/* - * Localize the stuff that should be done to change IB uC reset - * returns <0 for errors. - */ -static int ipath_ibsd_reset(struct ipath_devdata *dd, int assert_rst) -{ - u64 rst_val; - int ret = 0; - unsigned long flags; - - rst_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_ibserdesctrl); - if (assert_rst) { - /* - * Vendor recommends "interrupting" uC before reset, to - * minimize possible glitches. - */ - spin_lock_irqsave(&dd->ipath_sdepb_lock, flags); - epb_access(dd, IB_7220_SERDES, 1); - rst_val |= 1ULL; - /* Squelch possible parity error from _asserting_ reset */ - ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, - dd->ipath_hwerrmask & - ~INFINIPATH_HWE_IB_UC_MEMORYPARITYERR); - ipath_write_kreg(dd, dd->ipath_kregs->kr_ibserdesctrl, rst_val); - /* flush write, delay to ensure it took effect */ - ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); - udelay(2); - /* once it's reset, can remove interrupt */ - epb_access(dd, IB_7220_SERDES, -1); - spin_unlock_irqrestore(&dd->ipath_sdepb_lock, flags); - } else { - /* - * Before we de-assert reset, we need to deal with - * possible glitch on the Parity-error line. - * Suppress it around the reset, both in chip-level - * hwerrmask and in IB uC control reg. uC will allow - * it again during startup. - */ - u64 val; - rst_val &= ~(1ULL); - ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, - dd->ipath_hwerrmask & - ~INFINIPATH_HWE_IB_UC_MEMORYPARITYERR); - - ret = ipath_resync_ibepb(dd); - if (ret < 0) - ipath_dev_err(dd, "unable to re-sync IB EPB\n"); - - /* set uC control regs to suppress parity errs */ - ret = ipath_sd7220_reg_mod(dd, IB_7220_SERDES, IB_MPREG5, 1, 1); - if (ret < 0) - goto bail; - /* IB uC code past Version 1.32.17 allow suppression of wdog */ - ret = ipath_sd7220_reg_mod(dd, IB_7220_SERDES, IB_MPREG6, 0x80, - 0x80); - if (ret < 0) { - ipath_dev_err(dd, "Failed to set WDOG disable\n"); - goto bail; - } - ipath_write_kreg(dd, dd->ipath_kregs->kr_ibserdesctrl, rst_val); - /* flush write, delay for startup */ - ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); - udelay(1); - /* clear, then re-enable parity errs */ - ipath_sd7220_clr_ibpar(dd); - val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_hwerrstatus); - if (val & INFINIPATH_HWE_IB_UC_MEMORYPARITYERR) { - ipath_dev_err(dd, "IBUC Parity still set after RST\n"); - dd->ipath_hwerrmask &= - ~INFINIPATH_HWE_IB_UC_MEMORYPARITYERR; - } - ipath_write_kreg(dd, dd->ipath_kregs->kr_hwerrmask, - dd->ipath_hwerrmask); - } - -bail: - return ret; -} - -static void ipath_sd_trimdone_monitor(struct ipath_devdata *dd, - const char *where) -{ - int ret, chn, baduns; - u64 val; - - if (!where) - where = "?"; - - /* give time for reset to settle out in EPB */ - udelay(2); - - ret = ipath_resync_ibepb(dd); - if (ret < 0) - ipath_dev_err(dd, "not able to re-sync IB EPB (%s)\n", where); - - /* Do "sacrificial read" to get EPB in sane state after reset */ - ret = ipath_sd7220_reg_mod(dd, IB_7220_SERDES, IB_CTRL2(0), 0, 0); - if (ret < 0) - ipath_dev_err(dd, "Failed TRIMDONE 1st read, (%s)\n", where); - - /* Check/show "summary" Trim-done bit in IBCStatus */ - val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_ibcstatus); - if (val & (1ULL << 11)) - ipath_cdbg(VERBOSE, "IBCS TRIMDONE set (%s)\n", where); - else - ipath_dev_err(dd, "IBCS TRIMDONE clear (%s)\n", where); - - udelay(2); - - ret = ipath_sd7220_reg_mod(dd, IB_7220_SERDES, IB_MPREG6, 0x80, 0x80); - if (ret < 0) - ipath_dev_err(dd, "Failed Dummy RMW, (%s)\n", where); - udelay(10); - - baduns = 0; - - for (chn = 3; chn >= 0; --chn) { - /* Read CTRL reg for each channel to check TRIMDONE */ - ret = ipath_sd7220_reg_mod(dd, IB_7220_SERDES, - IB_CTRL2(chn), 0, 0); - if (ret < 0) - ipath_dev_err(dd, "Failed checking TRIMDONE, chn %d" - " (%s)\n", chn, where); - - if (!(ret & 0x10)) { - int probe; - baduns |= (1 << chn); - ipath_dev_err(dd, "TRIMDONE cleared on chn %d (%02X)." - " (%s)\n", chn, ret, where); - probe = ipath_sd7220_reg_mod(dd, IB_7220_SERDES, - IB_PGUDP(0), 0, 0); - ipath_dev_err(dd, "probe is %d (%02X)\n", - probe, probe); - probe = ipath_sd7220_reg_mod(dd, IB_7220_SERDES, - IB_CTRL2(chn), 0, 0); - ipath_dev_err(dd, "re-read: %d (%02X)\n", - probe, probe); - ret = ipath_sd7220_reg_mod(dd, IB_7220_SERDES, - IB_CTRL2(chn), 0x10, 0x10); - if (ret < 0) - ipath_dev_err(dd, - "Err on TRIMDONE rewrite1\n"); - } - } - for (chn = 3; chn >= 0; --chn) { - /* Read CTRL reg for each channel to check TRIMDONE */ - if (baduns & (1 << chn)) { - ipath_dev_err(dd, - "Reseting TRIMDONE on chn %d (%s)\n", - chn, where); - ret = ipath_sd7220_reg_mod(dd, IB_7220_SERDES, - IB_CTRL2(chn), 0x10, 0x10); - if (ret < 0) - ipath_dev_err(dd, "Failed re-setting " - "TRIMDONE, chn %d (%s)\n", - chn, where); - } - } -} - -/* - * Below is portion of IBA7220-specific bringup_serdes() that actually - * deals with registers and memory within the SerDes itself. - * Post IB uC code version 1.32.17, was_reset being 1 is not really - * informative, so we double-check. - */ -int ipath_sd7220_init(struct ipath_devdata *dd, int was_reset) -{ - int ret = 1; /* default to failure */ - int first_reset; - int val_stat; - - if (!was_reset) { - /* entered with reset not asserted, we need to do it */ - ipath_ibsd_reset(dd, 1); - ipath_sd_trimdone_monitor(dd, "Driver-reload"); - } - - /* Substitute our deduced value for was_reset */ - ret = ipath_ibsd_ucode_loaded(dd); - if (ret < 0) { - ret = 1; - goto done; - } - first_reset = !ret; /* First reset if IBSD uCode not yet loaded */ - - /* - * Alter some regs per vendor latest doc, reset-defaults - * are not right for IB. - */ - ret = ipath_sd_early(dd); - if (ret < 0) { - ipath_dev_err(dd, "Failed to set IB SERDES early defaults\n"); - ret = 1; - goto done; - } - - /* - * Set DAC manual trim IB. - * We only do this once after chip has been reset (usually - * same as once per system boot). - */ - if (first_reset) { - ret = ipath_sd_dactrim(dd); - if (ret < 0) { - ipath_dev_err(dd, "Failed IB SERDES DAC trim\n"); - ret = 1; - goto done; - } - } - - /* - * Set various registers (DDS and RXEQ) that will be - * controlled by IBC (in 1.2 mode) to reasonable preset values - * Calling the "internal" version avoids the "check for needed" - * and "trimdone monitor" that might be counter-productive. - */ - ret = ipath_internal_presets(dd); - if (ret < 0) { - ipath_dev_err(dd, "Failed to set IB SERDES presets\n"); - ret = 1; - goto done; - } - ret = ipath_sd_trimself(dd, 0x80); - if (ret < 0) { - ipath_dev_err(dd, "Failed to set IB SERDES TRIMSELF\n"); - ret = 1; - goto done; - } - - /* Load image, then try to verify */ - ret = 0; /* Assume success */ - if (first_reset) { - int vfy; - int trim_done; - ipath_dbg("SerDes uC was reset, reloading PRAM\n"); - ret = ipath_sd7220_ib_load(dd); - if (ret < 0) { - ipath_dev_err(dd, "Failed to load IB SERDES image\n"); - ret = 1; - goto done; - } - - /* Loaded image, try to verify */ - vfy = ipath_sd7220_ib_vfy(dd); - if (vfy != ret) { - ipath_dev_err(dd, "SERDES PRAM VFY failed\n"); - ret = 1; - goto done; - } - /* - * Loaded and verified. Almost good... - * hold "success" in ret - */ - ret = 0; - - /* - * Prev steps all worked, continue bringup - * De-assert RESET to uC, only in first reset, to allow - * trimming. - * - * Since our default setup sets START_EQ1 to - * PRESET, we need to clear that for this very first run. - */ - ret = ibsd_mod_allchnls(dd, START_EQ1(0), 0, 0x38); - if (ret < 0) { - ipath_dev_err(dd, "Failed clearing START_EQ1\n"); - ret = 1; - goto done; - } - - ipath_ibsd_reset(dd, 0); - /* - * If this is not the first reset, trimdone should be set - * already. - */ - trim_done = ipath_sd_trimdone_poll(dd); - /* - * Whether or not trimdone succeeded, we need to put the - * uC back into reset to avoid a possible fight with the - * IBC state-machine. - */ - ipath_ibsd_reset(dd, 1); - - if (!trim_done) { - ipath_dev_err(dd, "No TRIMDONE seen\n"); - ret = 1; - goto done; - } - - ipath_sd_trimdone_monitor(dd, "First-reset"); - /* Remember so we do not re-do the load, dactrim, etc. */ - dd->serdes_first_init_done = 1; - } - /* - * Setup for channel training and load values for - * RxEq and DDS in tables used by IBC in IB1.2 mode - */ - - val_stat = ipath_sd_setvals(dd); - if (val_stat < 0) - ret = 1; -done: - /* start relock timer regardless, but start at 1 second */ - ipath_set_relock_poll(dd, -1); - return ret; -} - -#define EPB_ACC_REQ 1 -#define EPB_ACC_GNT 0x100 -#define EPB_DATA_MASK 0xFF -#define EPB_RD (1ULL << 24) -#define EPB_TRANS_RDY (1ULL << 31) -#define EPB_TRANS_ERR (1ULL << 30) -#define EPB_TRANS_TRIES 5 - -/* - * query, claim, release ownership of the EPB (External Parallel Bus) - * for a specified SERDES. - * the "claim" parameter is >0 to claim, <0 to release, 0 to query. - * Returns <0 for errors, >0 if we had ownership, else 0. - */ -static int epb_access(struct ipath_devdata *dd, int sdnum, int claim) -{ - u16 acc; - u64 accval; - int owned = 0; - u64 oct_sel = 0; - - switch (sdnum) { - case IB_7220_SERDES : - /* - * The IB SERDES "ownership" is fairly simple. A single each - * request/grant. - */ - acc = dd->ipath_kregs->kr_ib_epbacc; - break; - case PCIE_SERDES0 : - case PCIE_SERDES1 : - /* PCIe SERDES has two "octants", need to select which */ - acc = dd->ipath_kregs->kr_pcie_epbacc; - oct_sel = (2 << (sdnum - PCIE_SERDES0)); - break; - default : - return 0; - } - - /* Make sure any outstanding transaction was seen */ - ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); - udelay(15); - - accval = ipath_read_kreg32(dd, acc); - - owned = !!(accval & EPB_ACC_GNT); - if (claim < 0) { - /* Need to release */ - u64 pollval; - /* - * The only writeable bits are the request and CS. - * Both should be clear - */ - u64 newval = 0; - ipath_write_kreg(dd, acc, newval); - /* First read after write is not trustworthy */ - pollval = ipath_read_kreg32(dd, acc); - udelay(5); - pollval = ipath_read_kreg32(dd, acc); - if (pollval & EPB_ACC_GNT) - owned = -1; - } else if (claim > 0) { - /* Need to claim */ - u64 pollval; - u64 newval = EPB_ACC_REQ | oct_sel; - ipath_write_kreg(dd, acc, newval); - /* First read after write is not trustworthy */ - pollval = ipath_read_kreg32(dd, acc); - udelay(5); - pollval = ipath_read_kreg32(dd, acc); - if (!(pollval & EPB_ACC_GNT)) - owned = -1; - } - return owned; -} - -/* - * Lemma to deal with race condition of write..read to epb regs - */ -static int epb_trans(struct ipath_devdata *dd, u16 reg, u64 i_val, u64 *o_vp) -{ - int tries; - u64 transval; - - - ipath_write_kreg(dd, reg, i_val); - /* Throw away first read, as RDY bit may be stale */ - transval = ipath_read_kreg64(dd, reg); - - for (tries = EPB_TRANS_TRIES; tries; --tries) { - transval = ipath_read_kreg32(dd, reg); - if (transval & EPB_TRANS_RDY) - break; - udelay(5); - } - if (transval & EPB_TRANS_ERR) - return -1; - if (tries > 0 && o_vp) - *o_vp = transval; - return tries; -} - -/** - * - * ipath_sd7220_reg_mod - modify SERDES register - * @dd: the infinipath device - * @sdnum: which SERDES to access - * @loc: location - channel, element, register, as packed by EPB_LOC() macro. - * @wd: Write Data - value to set in register - * @mask: ones where data should be spliced into reg. - * - * Basic register read/modify/write, with un-needed accesses elided. That is, - * a mask of zero will prevent write, while a mask of 0xFF will prevent read. - * returns current (presumed, if a write was done) contents of selected - * register, or <0 if errors. - */ -static int ipath_sd7220_reg_mod(struct ipath_devdata *dd, int sdnum, u32 loc, - u32 wd, u32 mask) -{ - u16 trans; - u64 transval; - int owned; - int tries, ret; - unsigned long flags; - - switch (sdnum) { - case IB_7220_SERDES : - trans = dd->ipath_kregs->kr_ib_epbtrans; - break; - case PCIE_SERDES0 : - case PCIE_SERDES1 : - trans = dd->ipath_kregs->kr_pcie_epbtrans; - break; - default : - return -1; - } - - /* - * All access is locked in software (vs other host threads) and - * hardware (vs uC access). - */ - spin_lock_irqsave(&dd->ipath_sdepb_lock, flags); - - owned = epb_access(dd, sdnum, 1); - if (owned < 0) { - spin_unlock_irqrestore(&dd->ipath_sdepb_lock, flags); - return -1; - } - ret = 0; - for (tries = EPB_TRANS_TRIES; tries; --tries) { - transval = ipath_read_kreg32(dd, trans); - if (transval & EPB_TRANS_RDY) - break; - udelay(5); - } - - if (tries > 0) { - tries = 1; /* to make read-skip work */ - if (mask != 0xFF) { - /* - * Not a pure write, so need to read. - * loc encodes chip-select as well as address - */ - transval = loc | EPB_RD; - tries = epb_trans(dd, trans, transval, &transval); - } - if (tries > 0 && mask != 0) { - /* - * Not a pure read, so need to write. - */ - wd = (wd & mask) | (transval & ~mask); - transval = loc | (wd & EPB_DATA_MASK); - tries = epb_trans(dd, trans, transval, &transval); - } - } - /* else, failed to see ready, what error-handling? */ - - /* - * Release bus. Failure is an error. - */ - if (epb_access(dd, sdnum, -1) < 0) - ret = -1; - else - ret = transval & EPB_DATA_MASK; - - spin_unlock_irqrestore(&dd->ipath_sdepb_lock, flags); - if (tries <= 0) - ret = -1; - return ret; -} - -#define EPB_ROM_R (2) -#define EPB_ROM_W (1) -/* - * Below, all uC-related, use appropriate UC_CS, depending - * on which SerDes is used. - */ -#define EPB_UC_CTL EPB_LOC(6, 0, 0) -#define EPB_MADDRL EPB_LOC(6, 0, 2) -#define EPB_MADDRH EPB_LOC(6, 0, 3) -#define EPB_ROMDATA EPB_LOC(6, 0, 4) -#define EPB_RAMDATA EPB_LOC(6, 0, 5) - -/* Transfer date to/from uC Program RAM of IB or PCIe SerDes */ -static int ipath_sd7220_ram_xfer(struct ipath_devdata *dd, int sdnum, u32 loc, - u8 *buf, int cnt, int rd_notwr) -{ - u16 trans; - u64 transval; - u64 csbit; - int owned; - int tries; - int sofar; - int addr; - int ret; - unsigned long flags; - const char *op; - - /* Pick appropriate transaction reg and "Chip select" for this serdes */ - switch (sdnum) { - case IB_7220_SERDES : - csbit = 1ULL << EPB_IB_UC_CS_SHF; - trans = dd->ipath_kregs->kr_ib_epbtrans; - break; - case PCIE_SERDES0 : - case PCIE_SERDES1 : - /* PCIe SERDES has uC "chip select" in different bit, too */ - csbit = 1ULL << EPB_PCIE_UC_CS_SHF; - trans = dd->ipath_kregs->kr_pcie_epbtrans; - break; - default : - return -1; - } - - op = rd_notwr ? "Rd" : "Wr"; - spin_lock_irqsave(&dd->ipath_sdepb_lock, flags); - - owned = epb_access(dd, sdnum, 1); - if (owned < 0) { - spin_unlock_irqrestore(&dd->ipath_sdepb_lock, flags); - ipath_dbg("Could not get %s access to %s EPB: %X, loc %X\n", - op, (sdnum == IB_7220_SERDES) ? "IB" : "PCIe", - owned, loc); - return -1; - } - - /* - * In future code, we may need to distinguish several address ranges, - * and select various memories based on this. For now, just trim - * "loc" (location including address and memory select) to - * "addr" (address within memory). we will only support PRAM - * The memory is 8KB. - */ - addr = loc & 0x1FFF; - for (tries = EPB_TRANS_TRIES; tries; --tries) { - transval = ipath_read_kreg32(dd, trans); - if (transval & EPB_TRANS_RDY) - break; - udelay(5); - } - - sofar = 0; - if (tries <= 0) - ipath_dbg("No initial RDY on EPB access request\n"); - else { - /* - * Every "memory" access is doubly-indirect. - * We set two bytes of address, then read/write - * one or mores bytes of data. - */ - - /* First, we set control to "Read" or "Write" */ - transval = csbit | EPB_UC_CTL | - (rd_notwr ? EPB_ROM_R : EPB_ROM_W); - tries = epb_trans(dd, trans, transval, &transval); - if (tries <= 0) - ipath_dbg("No EPB response to uC %s cmd\n", op); - while (tries > 0 && sofar < cnt) { - if (!sofar) { - /* Only set address at start of chunk */ - int addrbyte = (addr + sofar) >> 8; - transval = csbit | EPB_MADDRH | addrbyte; - tries = epb_trans(dd, trans, transval, - &transval); - if (tries <= 0) { - ipath_dbg("No EPB response ADDRH\n"); - break; - } - addrbyte = (addr + sofar) & 0xFF; - transval = csbit | EPB_MADDRL | addrbyte; - tries = epb_trans(dd, trans, transval, - &transval); - if (tries <= 0) { - ipath_dbg("No EPB response ADDRL\n"); - break; - } - } - - if (rd_notwr) - transval = csbit | EPB_ROMDATA | EPB_RD; - else - transval = csbit | EPB_ROMDATA | buf[sofar]; - tries = epb_trans(dd, trans, transval, &transval); - if (tries <= 0) { - ipath_dbg("No EPB response DATA\n"); - break; - } - if (rd_notwr) - buf[sofar] = transval & EPB_DATA_MASK; - ++sofar; - } - /* Finally, clear control-bit for Read or Write */ - transval = csbit | EPB_UC_CTL; - tries = epb_trans(dd, trans, transval, &transval); - if (tries <= 0) - ipath_dbg("No EPB response to drop of uC %s cmd\n", op); - } - - ret = sofar; - /* Release bus. Failure is an error */ - if (epb_access(dd, sdnum, -1) < 0) - ret = -1; - - spin_unlock_irqrestore(&dd->ipath_sdepb_lock, flags); - if (tries <= 0) { - ipath_dbg("SERDES PRAM %s failed after %d bytes\n", op, sofar); - ret = -1; - } - return ret; -} - -#define PROG_CHUNK 64 - -int ipath_sd7220_prog_ld(struct ipath_devdata *dd, int sdnum, - u8 *img, int len, int offset) -{ - int cnt, sofar, req; - - sofar = 0; - while (sofar < len) { - req = len - sofar; - if (req > PROG_CHUNK) - req = PROG_CHUNK; - cnt = ipath_sd7220_ram_xfer(dd, sdnum, offset + sofar, - img + sofar, req, 0); - if (cnt < req) { - sofar = -1; - break; - } - sofar += req; - } - return sofar; -} - -#define VFY_CHUNK 64 -#define SD_PRAM_ERROR_LIMIT 42 - -int ipath_sd7220_prog_vfy(struct ipath_devdata *dd, int sdnum, - const u8 *img, int len, int offset) -{ - int cnt, sofar, req, idx, errors; - unsigned char readback[VFY_CHUNK]; - - errors = 0; - sofar = 0; - while (sofar < len) { - req = len - sofar; - if (req > VFY_CHUNK) - req = VFY_CHUNK; - cnt = ipath_sd7220_ram_xfer(dd, sdnum, sofar + offset, - readback, req, 1); - if (cnt < req) { - /* failed in read itself */ - sofar = -1; - break; - } - for (idx = 0; idx < cnt; ++idx) { - if (readback[idx] != img[idx+sofar]) - ++errors; - } - sofar += cnt; - } - return errors ? -errors : sofar; -} - -/* IRQ not set up at this point in init, so we poll. */ -#define IB_SERDES_TRIM_DONE (1ULL << 11) -#define TRIM_TMO (30) - -static int ipath_sd_trimdone_poll(struct ipath_devdata *dd) -{ - int trim_tmo, ret; - uint64_t val; - - /* - * Default to failure, so IBC will not start - * without IB_SERDES_TRIM_DONE. - */ - ret = 0; - for (trim_tmo = 0; trim_tmo < TRIM_TMO; ++trim_tmo) { - val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_ibcstatus); - if (val & IB_SERDES_TRIM_DONE) { - ipath_cdbg(VERBOSE, "TRIMDONE after %d\n", trim_tmo); - ret = 1; - break; - } - msleep(10); - } - if (trim_tmo >= TRIM_TMO) { - ipath_dev_err(dd, "No TRIMDONE in %d tries\n", trim_tmo); - ret = 0; - } - return ret; -} - -#define TX_FAST_ELT (9) - -/* - * Set the "negotiation" values for SERDES. These are used by the IB1.2 - * link negotiation. Macros below are attempt to keep the values a - * little more human-editable. - * First, values related to Drive De-emphasis Settings. - */ - -#define NUM_DDS_REGS 6 -#define DDS_REG_MAP 0x76A910 /* LSB-first list of regs (in elt 9) to mod */ - -#define DDS_VAL(amp_d, main_d, ipst_d, ipre_d, amp_s, main_s, ipst_s, ipre_s) \ - { { ((amp_d & 0x1F) << 1) | 1, ((amp_s & 0x1F) << 1) | 1, \ - (main_d << 3) | 4 | (ipre_d >> 2), \ - (main_s << 3) | 4 | (ipre_s >> 2), \ - ((ipst_d & 0xF) << 1) | ((ipre_d & 3) << 6) | 0x21, \ - ((ipst_s & 0xF) << 1) | ((ipre_s & 3) << 6) | 0x21 } } - -static struct dds_init { - uint8_t reg_vals[NUM_DDS_REGS]; -} dds_init_vals[] = { - /* DDR(FDR) SDR(HDR) */ - /* Vendor recommends below for 3m cable */ -#define DDS_3M 0 - DDS_VAL(31, 19, 12, 0, 29, 22, 9, 0), - DDS_VAL(31, 12, 15, 4, 31, 15, 15, 1), - DDS_VAL(31, 13, 15, 3, 31, 16, 15, 0), - DDS_VAL(31, 14, 15, 2, 31, 17, 14, 0), - DDS_VAL(31, 15, 15, 1, 31, 18, 13, 0), - DDS_VAL(31, 16, 15, 0, 31, 19, 12, 0), - DDS_VAL(31, 17, 14, 0, 31, 20, 11, 0), - DDS_VAL(31, 18, 13, 0, 30, 21, 10, 0), - DDS_VAL(31, 20, 11, 0, 28, 23, 8, 0), - DDS_VAL(31, 21, 10, 0, 27, 24, 7, 0), - DDS_VAL(31, 22, 9, 0, 26, 25, 6, 0), - DDS_VAL(30, 23, 8, 0, 25, 26, 5, 0), - DDS_VAL(29, 24, 7, 0, 23, 27, 4, 0), - /* Vendor recommends below for 1m cable */ -#define DDS_1M 13 - DDS_VAL(28, 25, 6, 0, 21, 28, 3, 0), - DDS_VAL(27, 26, 5, 0, 19, 29, 2, 0), - DDS_VAL(25, 27, 4, 0, 17, 30, 1, 0) -}; - -/* - * Next, values related to Receive Equalization. - * In comments, FDR (Full) is IB DDR, HDR (Half) is IB SDR - */ -/* Hardware packs an element number and register address thus: */ -#define RXEQ_INIT_RDESC(elt, addr) (((elt) & 0xF) | ((addr) << 4)) -#define RXEQ_VAL(elt, adr, val0, val1, val2, val3) \ - {RXEQ_INIT_RDESC((elt), (adr)), {(val0), (val1), (val2), (val3)} } - -#define RXEQ_VAL_ALL(elt, adr, val) \ - {RXEQ_INIT_RDESC((elt), (adr)), {(val), (val), (val), (val)} } - -#define RXEQ_SDR_DFELTH 0 -#define RXEQ_SDR_TLTH 0 -#define RXEQ_SDR_G1CNT_Z1CNT 0x11 -#define RXEQ_SDR_ZCNT 23 - -static struct rxeq_init { - u16 rdesc; /* in form used in SerDesDDSRXEQ */ - u8 rdata[4]; -} rxeq_init_vals[] = { - /* Set Rcv Eq. to Preset node */ - RXEQ_VAL_ALL(7, 0x27, 0x10), - /* Set DFELTHFDR/HDR thresholds */ - RXEQ_VAL(7, 8, 0, 0, 0, 0), /* FDR */ - RXEQ_VAL(7, 0x21, 0, 0, 0, 0), /* HDR */ - /* Set TLTHFDR/HDR threshold */ - RXEQ_VAL(7, 9, 2, 2, 2, 2), /* FDR */ - RXEQ_VAL(7, 0x23, 2, 2, 2, 2), /* HDR */ - /* Set Preamp setting 2 (ZFR/ZCNT) */ - RXEQ_VAL(7, 0x1B, 12, 12, 12, 12), /* FDR */ - RXEQ_VAL(7, 0x1C, 12, 12, 12, 12), /* HDR */ - /* Set Preamp DC gain and Setting 1 (GFR/GHR) */ - RXEQ_VAL(7, 0x1E, 0x10, 0x10, 0x10, 0x10), /* FDR */ - RXEQ_VAL(7, 0x1F, 0x10, 0x10, 0x10, 0x10), /* HDR */ - /* Toggle RELOCK (in VCDL_CTRL0) to lock to data */ - RXEQ_VAL_ALL(6, 6, 0x20), /* Set D5 High */ - RXEQ_VAL_ALL(6, 6, 0), /* Set D5 Low */ -}; - -/* There are 17 values from vendor, but IBC only accesses the first 16 */ -#define DDS_ROWS (16) -#define RXEQ_ROWS ARRAY_SIZE(rxeq_init_vals) - -static int ipath_sd_setvals(struct ipath_devdata *dd) -{ - int idx, midx; - int min_idx; /* Minimum index for this portion of table */ - uint32_t dds_reg_map; - u64 __iomem *taddr, *iaddr; - uint64_t data; - uint64_t sdctl; - - taddr = dd->ipath_kregbase + KR_IBSerDesMappTable; - iaddr = dd->ipath_kregbase + dd->ipath_kregs->kr_ib_ddsrxeq; - - /* - * Init the DDS section of the table. - * Each "row" of the table provokes NUM_DDS_REG writes, to the - * registers indicated in DDS_REG_MAP. - */ - sdctl = ipath_read_kreg64(dd, dd->ipath_kregs->kr_ibserdesctrl); - sdctl = (sdctl & ~(0x1f << 8)) | (NUM_DDS_REGS << 8); - sdctl = (sdctl & ~(0x1f << 13)) | (RXEQ_ROWS << 13); - ipath_write_kreg(dd, dd->ipath_kregs->kr_ibserdesctrl, sdctl); - - /* - * Iterate down table within loop for each register to store. - */ - dds_reg_map = DDS_REG_MAP; - for (idx = 0; idx < NUM_DDS_REGS; ++idx) { - data = ((dds_reg_map & 0xF) << 4) | TX_FAST_ELT; - writeq(data, iaddr + idx); - mmiowb(); - ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); - dds_reg_map >>= 4; - for (midx = 0; midx < DDS_ROWS; ++midx) { - u64 __iomem *daddr = taddr + ((midx << 4) + idx); - data = dds_init_vals[midx].reg_vals[idx]; - writeq(data, daddr); - mmiowb(); - ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); - } /* End inner for (vals for this reg, each row) */ - } /* end outer for (regs to be stored) */ - - /* - * Init the RXEQ section of the table. As explained above the table - * rxeq_init_vals[], this runs in a different order, as the pattern - * of register references is more complex, but there are only - * four "data" values per register. - */ - min_idx = idx; /* RXEQ indices pick up where DDS left off */ - taddr += 0x100; /* RXEQ data is in second half of table */ - /* Iterate through RXEQ register addresses */ - for (idx = 0; idx < RXEQ_ROWS; ++idx) { - int didx; /* "destination" */ - int vidx; - - /* didx is offset by min_idx to address RXEQ range of regs */ - didx = idx + min_idx; - /* Store the next RXEQ register address */ - writeq(rxeq_init_vals[idx].rdesc, iaddr + didx); - mmiowb(); - ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); - /* Iterate through RXEQ values */ - for (vidx = 0; vidx < 4; vidx++) { - data = rxeq_init_vals[idx].rdata[vidx]; - writeq(data, taddr + (vidx << 6) + idx); - mmiowb(); - ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch); - } - } /* end outer for (Reg-writes for RXEQ) */ - return 0; -} - -#define CMUCTRL5 EPB_LOC(7, 0, 0x15) -#define RXHSCTRL0(chan) EPB_LOC(chan, 6, 0) -#define VCDL_DAC2(chan) EPB_LOC(chan, 6, 5) -#define VCDL_CTRL0(chan) EPB_LOC(chan, 6, 6) -#define VCDL_CTRL2(chan) EPB_LOC(chan, 6, 8) -#define START_EQ2(chan) EPB_LOC(chan, 7, 0x28) - -static int ibsd_sto_noisy(struct ipath_devdata *dd, int loc, int val, int mask) -{ - int ret = -1; - int sloc; /* shifted loc, for messages */ - - loc |= (1U << EPB_IB_QUAD0_CS_SHF); - sloc = loc >> EPB_ADDR_SHF; - - ret = ipath_sd7220_reg_mod(dd, IB_7220_SERDES, loc, val, mask); - if (ret < 0) - ipath_dev_err(dd, "Write failed: elt %d," - " addr 0x%X, chnl %d, val 0x%02X, mask 0x%02X\n", - (sloc & 0xF), (sloc >> 9) & 0x3f, (sloc >> 4) & 7, - val & 0xFF, mask & 0xFF); - return ret; -} - -/* - * Repeat a "store" across all channels of the IB SerDes. - * Although nominally it inherits the "read value" of the last - * channel it modified, the only really useful return is <0 for - * failure, >= 0 for success. The parameter 'loc' is assumed to - * be the location for the channel-0 copy of the register to - * be modified. - */ -static int ibsd_mod_allchnls(struct ipath_devdata *dd, int loc, int val, - int mask) -{ - int ret = -1; - int chnl; - - if (loc & EPB_GLOBAL_WR) { - /* - * Our caller has assured us that we can set all four - * channels at once. Trust that. If mask is not 0xFF, - * we will read the _specified_ channel for our starting - * value. - */ - loc |= (1U << EPB_IB_QUAD0_CS_SHF); - chnl = (loc >> (4 + EPB_ADDR_SHF)) & 7; - if (mask != 0xFF) { - ret = ipath_sd7220_reg_mod(dd, IB_7220_SERDES, - loc & ~EPB_GLOBAL_WR, 0, 0); - if (ret < 0) { - int sloc = loc >> EPB_ADDR_SHF; - ipath_dev_err(dd, "pre-read failed: elt %d," - " addr 0x%X, chnl %d\n", (sloc & 0xF), - (sloc >> 9) & 0x3f, chnl); - return ret; - } - val = (ret & ~mask) | (val & mask); - } - loc &= ~(7 << (4+EPB_ADDR_SHF)); - ret = ipath_sd7220_reg_mod(dd, IB_7220_SERDES, loc, val, 0xFF); - if (ret < 0) { - int sloc = loc >> EPB_ADDR_SHF; - ipath_dev_err(dd, "Global WR failed: elt %d," - " addr 0x%X, val %02X\n", - (sloc & 0xF), (sloc >> 9) & 0x3f, val); - } - return ret; - } - /* Clear "channel" and set CS so we can simply iterate */ - loc &= ~(7 << (4+EPB_ADDR_SHF)); - loc |= (1U << EPB_IB_QUAD0_CS_SHF); - for (chnl = 0; chnl < 4; ++chnl) { - int cloc; - cloc = loc | (chnl << (4+EPB_ADDR_SHF)); - ret = ipath_sd7220_reg_mod(dd, IB_7220_SERDES, cloc, val, mask); - if (ret < 0) { - int sloc = loc >> EPB_ADDR_SHF; - ipath_dev_err(dd, "Write failed: elt %d," - " addr 0x%X, chnl %d, val 0x%02X," - " mask 0x%02X\n", - (sloc & 0xF), (sloc >> 9) & 0x3f, chnl, - val & 0xFF, mask & 0xFF); - break; - } - } - return ret; -} - -/* - * Set the Tx values normally modified by IBC in IB1.2 mode to default - * values, as gotten from first row of init table. - */ -static int set_dds_vals(struct ipath_devdata *dd, struct dds_init *ddi) -{ - int ret; - int idx, reg, data; - uint32_t regmap; - - regmap = DDS_REG_MAP; - for (idx = 0; idx < NUM_DDS_REGS; ++idx) { - reg = (regmap & 0xF); - regmap >>= 4; - data = ddi->reg_vals[idx]; - /* Vendor says RMW not needed for these regs, use 0xFF mask */ - ret = ibsd_mod_allchnls(dd, EPB_LOC(0, 9, reg), data, 0xFF); - if (ret < 0) - break; - } - return ret; -} - -/* - * Set the Rx values normally modified by IBC in IB1.2 mode to default - * values, as gotten from selected column of init table. - */ -static int set_rxeq_vals(struct ipath_devdata *dd, int vsel) -{ - int ret; - int ridx; - int cnt = ARRAY_SIZE(rxeq_init_vals); - - for (ridx = 0; ridx < cnt; ++ridx) { - int elt, reg, val, loc; - elt = rxeq_init_vals[ridx].rdesc & 0xF; - reg = rxeq_init_vals[ridx].rdesc >> 4; - loc = EPB_LOC(0, elt, reg); - val = rxeq_init_vals[ridx].rdata[vsel]; - /* mask of 0xFF, because hardware does full-byte store. */ - ret = ibsd_mod_allchnls(dd, loc, val, 0xFF); - if (ret < 0) - break; - } - return ret; -} - -/* - * Set the default values (row 0) for DDR Driver Demphasis. - * we do this initially and whenever we turn off IB-1.2 - * The "default" values for Rx equalization are also stored to - * SerDes registers. Formerly (and still default), we used set 2. - * For experimenting with cables and link-partners, we allow changing - * that via a module parameter. - */ -static unsigned ipath_rxeq_set = 2; -module_param_named(rxeq_default_set, ipath_rxeq_set, uint, - S_IWUSR | S_IRUGO); -MODULE_PARM_DESC(rxeq_default_set, - "Which set [0..3] of Rx Equalization values is default"); - -static int ipath_internal_presets(struct ipath_devdata *dd) -{ - int ret = 0; - - ret = set_dds_vals(dd, dds_init_vals + DDS_3M); - - if (ret < 0) - ipath_dev_err(dd, "Failed to set default DDS values\n"); - ret = set_rxeq_vals(dd, ipath_rxeq_set & 3); - if (ret < 0) - ipath_dev_err(dd, "Failed to set default RXEQ values\n"); - return ret; -} - -int ipath_sd7220_presets(struct ipath_devdata *dd) -{ - int ret = 0; - - if (!dd->ipath_presets_needed) - return ret; - dd->ipath_presets_needed = 0; - /* Assert uC reset, so we don't clash with it. */ - ipath_ibsd_reset(dd, 1); - udelay(2); - ipath_sd_trimdone_monitor(dd, "link-down"); - - ret = ipath_internal_presets(dd); -return ret; -} - -static int ipath_sd_trimself(struct ipath_devdata *dd, int val) -{ - return ibsd_sto_noisy(dd, CMUCTRL5, val, 0xFF); -} - -static int ipath_sd_early(struct ipath_devdata *dd) -{ - int ret = -1; /* Default failed */ - int chnl; - - for (chnl = 0; chnl < 4; ++chnl) { - ret = ibsd_sto_noisy(dd, RXHSCTRL0(chnl), 0xD4, 0xFF); - if (ret < 0) - goto bail; - } - for (chnl = 0; chnl < 4; ++chnl) { - ret = ibsd_sto_noisy(dd, VCDL_DAC2(chnl), 0x2D, 0xFF); - if (ret < 0) - goto bail; - } - /* more fine-tuning of what will be default */ - for (chnl = 0; chnl < 4; ++chnl) { - ret = ibsd_sto_noisy(dd, VCDL_CTRL2(chnl), 3, 0xF); - if (ret < 0) - goto bail; - } - for (chnl = 0; chnl < 4; ++chnl) { - ret = ibsd_sto_noisy(dd, START_EQ1(chnl), 0x10, 0xFF); - if (ret < 0) - goto bail; - } - for (chnl = 0; chnl < 4; ++chnl) { - ret = ibsd_sto_noisy(dd, START_EQ2(chnl), 0x30, 0xFF); - if (ret < 0) - goto bail; - } -bail: - return ret; -} - -#define BACTRL(chnl) EPB_LOC(chnl, 6, 0x0E) -#define LDOUTCTRL1(chnl) EPB_LOC(chnl, 7, 6) -#define RXHSSTATUS(chnl) EPB_LOC(chnl, 6, 0xF) - -static int ipath_sd_dactrim(struct ipath_devdata *dd) -{ - int ret = -1; /* Default failed */ - int chnl; - - for (chnl = 0; chnl < 4; ++chnl) { - ret = ibsd_sto_noisy(dd, BACTRL(chnl), 0x40, 0xFF); - if (ret < 0) - goto bail; - } - for (chnl = 0; chnl < 4; ++chnl) { - ret = ibsd_sto_noisy(dd, LDOUTCTRL1(chnl), 0x04, 0xFF); - if (ret < 0) - goto bail; - } - for (chnl = 0; chnl < 4; ++chnl) { - ret = ibsd_sto_noisy(dd, RXHSSTATUS(chnl), 0x04, 0xFF); - if (ret < 0) - goto bail; - } - /* - * delay for max possible number of steps, with slop. - * Each step is about 4usec. - */ - udelay(415); - for (chnl = 0; chnl < 4; ++chnl) { - ret = ibsd_sto_noisy(dd, LDOUTCTRL1(chnl), 0x00, 0xFF); - if (ret < 0) - goto bail; - } -bail: - return ret; -} - -#define RELOCK_FIRST_MS 3 -#define RXLSPPM(chan) EPB_LOC(chan, 0, 2) -void ipath_toggle_rclkrls(struct ipath_devdata *dd) -{ - int loc = RXLSPPM(0) | EPB_GLOBAL_WR; - int ret; - - ret = ibsd_mod_allchnls(dd, loc, 0, 0x80); - if (ret < 0) - ipath_dev_err(dd, "RCLKRLS failed to clear D7\n"); - else { - udelay(1); - ibsd_mod_allchnls(dd, loc, 0x80, 0x80); - } - /* And again for good measure */ - udelay(1); - ret = ibsd_mod_allchnls(dd, loc, 0, 0x80); - if (ret < 0) - ipath_dev_err(dd, "RCLKRLS failed to clear D7\n"); - else { - udelay(1); - ibsd_mod_allchnls(dd, loc, 0x80, 0x80); - } - /* Now reset xgxs and IBC to complete the recovery */ - dd->ipath_f_xgxs_reset(dd); -} - -/* - * Shut down the timer that polls for relock occasions, if needed - * this is "hooked" from ipath_7220_quiet_serdes(), which is called - * just before ipath_shutdown_device() in ipath_driver.c shuts down all - * the other timers - */ -void ipath_shutdown_relock_poll(struct ipath_devdata *dd) -{ - struct ipath_relock *irp = &dd->ipath_relock_singleton; - if (atomic_read(&irp->ipath_relock_timer_active)) { - del_timer_sync(&irp->ipath_relock_timer); - atomic_set(&irp->ipath_relock_timer_active, 0); - } -} - -static unsigned ipath_relock_by_timer = 1; -module_param_named(relock_by_timer, ipath_relock_by_timer, uint, - S_IWUSR | S_IRUGO); -MODULE_PARM_DESC(relock_by_timer, "Allow relock attempt if link not up"); - -static void ipath_run_relock(unsigned long opaque) -{ - struct ipath_devdata *dd = (struct ipath_devdata *)opaque; - struct ipath_relock *irp = &dd->ipath_relock_singleton; - u64 val, ltstate; - - if (!(dd->ipath_flags & IPATH_INITTED)) { - /* Not yet up, just reenable the timer for later */ - irp->ipath_relock_interval = HZ; - mod_timer(&irp->ipath_relock_timer, jiffies + HZ); - return; - } - - /* - * Check link-training state for "stuck" state. - * if found, try relock and schedule another try at - * exponentially growing delay, maxed at one second. - * if not stuck, our work is done. - */ - val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_ibcstatus); - ltstate = ipath_ib_linktrstate(dd, val); - - if (ltstate <= INFINIPATH_IBCS_LT_STATE_CFGWAITRMT - && ltstate != INFINIPATH_IBCS_LT_STATE_LINKUP) { - int timeoff; - /* Not up yet. Try again, if allowed by module-param */ - if (ipath_relock_by_timer) { - if (dd->ipath_flags & IPATH_IB_AUTONEG_INPROG) - ipath_cdbg(VERBOSE, "Skip RELOCK in AUTONEG\n"); - else if (!(dd->ipath_flags & IPATH_IB_LINK_DISABLED)) { - ipath_cdbg(VERBOSE, "RELOCK\n"); - ipath_toggle_rclkrls(dd); - } - } - /* re-set timer for next check */ - timeoff = irp->ipath_relock_interval << 1; - if (timeoff > HZ) - timeoff = HZ; - irp->ipath_relock_interval = timeoff; - - mod_timer(&irp->ipath_relock_timer, jiffies + timeoff); - } else { - /* Up, so no more need to check so often */ - mod_timer(&irp->ipath_relock_timer, jiffies + HZ); - } -} - -void ipath_set_relock_poll(struct ipath_devdata *dd, int ibup) -{ - struct ipath_relock *irp = &dd->ipath_relock_singleton; - - if (ibup > 0) { - /* we are now up, so relax timer to 1 second interval */ - if (atomic_read(&irp->ipath_relock_timer_active)) - mod_timer(&irp->ipath_relock_timer, jiffies + HZ); - } else { - /* Transition to down, (re-)set timer to short interval. */ - int timeout; - timeout = (HZ * ((ibup == -1) ? 1000 : RELOCK_FIRST_MS))/1000; - if (timeout == 0) - timeout = 1; - /* If timer has not yet been started, do so. */ - if (atomic_inc_return(&irp->ipath_relock_timer_active) == 1) { - init_timer(&irp->ipath_relock_timer); - irp->ipath_relock_timer.function = ipath_run_relock; - irp->ipath_relock_timer.data = (unsigned long) dd; - irp->ipath_relock_interval = timeout; - irp->ipath_relock_timer.expires = jiffies + timeout; - add_timer(&irp->ipath_relock_timer); - } else { - irp->ipath_relock_interval = timeout; - mod_timer(&irp->ipath_relock_timer, jiffies + timeout); - atomic_dec(&irp->ipath_relock_timer_active); - } - } -} - diff --git a/drivers/infiniband/hw/ipath/ipath_sd7220_img.c b/drivers/infiniband/hw/ipath/ipath_sd7220_img.c deleted file mode 100644 index 5ef59da9270a..000000000000 --- a/drivers/infiniband/hw/ipath/ipath_sd7220_img.c +++ /dev/null @@ -1,1082 +0,0 @@ -/* - * Copyright (c) 2007, 2008 QLogic Corporation. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* - * This file contains the memory image from the vendor, to be copied into - * the IB SERDES of the IBA7220 during initialization. - * The file also includes the two functions which use this image. - */ -#include -#include - -#include "ipath_kernel.h" -#include "ipath_registers.h" -#include "ipath_7220.h" - -static unsigned char ipath_sd7220_ib_img[] = { -/*0000*/0x02, 0x0A, 0x29, 0x02, 0x0A, 0x87, 0xE5, 0xE6, - 0x30, 0xE6, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, -/*0010*/0x00, 0xE5, 0xE2, 0x30, 0xE4, 0x04, 0x7E, 0x01, - 0x80, 0x02, 0x7E, 0x00, 0xEE, 0x5F, 0x60, 0x08, -/*0020*/0x53, 0xF9, 0xF7, 0xE4, 0xF5, 0xFE, 0x80, 0x08, - 0x7F, 0x0A, 0x12, 0x17, 0x31, 0x12, 0x0E, 0xA2, -/*0030*/0x75, 0xFC, 0x08, 0xE4, 0xF5, 0xFD, 0xE5, 0xE7, - 0x20, 0xE7, 0x03, 0x43, 0xF9, 0x08, 0x22, 0x00, -/*0040*/0x01, 0x20, 0x11, 0x00, 0x04, 0x20, 0x00, 0x75, - 0x51, 0x01, 0xE4, 0xF5, 0x52, 0xF5, 0x53, 0xF5, -/*0050*/0x52, 0xF5, 0x7E, 0x7F, 0x04, 0x02, 0x04, 0x38, - 0xC2, 0x36, 0x05, 0x52, 0xE5, 0x52, 0xD3, 0x94, -/*0060*/0x0C, 0x40, 0x05, 0x75, 0x52, 0x01, 0xD2, 0x36, - 0x90, 0x07, 0x0C, 0x74, 0x07, 0xF0, 0xA3, 0x74, -/*0070*/0xFF, 0xF0, 0xE4, 0xF5, 0x0C, 0xA3, 0xF0, 0x90, - 0x07, 0x14, 0xF0, 0xA3, 0xF0, 0x75, 0x0B, 0x20, -/*0080*/0xF5, 0x09, 0xE4, 0xF5, 0x08, 0xE5, 0x08, 0xD3, - 0x94, 0x30, 0x40, 0x03, 0x02, 0x04, 0x04, 0x12, -/*0090*/0x00, 0x06, 0x15, 0x0B, 0xE5, 0x08, 0x70, 0x04, - 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xE5, 0x09, -/*00A0*/0x70, 0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, - 0xEE, 0x5F, 0x60, 0x05, 0x12, 0x18, 0x71, 0xD2, -/*00B0*/0x35, 0x53, 0xE1, 0xF7, 0xE5, 0x08, 0x45, 0x09, - 0xFF, 0xE5, 0x0B, 0x25, 0xE0, 0x25, 0xE0, 0x24, -/*00C0*/0x83, 0xF5, 0x82, 0xE4, 0x34, 0x07, 0xF5, 0x83, - 0xEF, 0xF0, 0x85, 0xE2, 0x20, 0xE5, 0x52, 0xD3, -/*00D0*/0x94, 0x01, 0x40, 0x0D, 0x12, 0x19, 0xF3, 0xE0, - 0x54, 0xA0, 0x64, 0x40, 0x70, 0x03, 0x02, 0x03, -/*00E0*/0xFB, 0x53, 0xF9, 0xF8, 0x90, 0x94, 0x70, 0xE4, - 0xF0, 0xE0, 0xF5, 0x10, 0xAF, 0x09, 0x12, 0x1E, -/*00F0*/0xB3, 0xAF, 0x08, 0xEF, 0x44, 0x08, 0xF5, 0x82, - 0x75, 0x83, 0x80, 0xE0, 0xF5, 0x29, 0xEF, 0x44, -/*0100*/0x07, 0x12, 0x1A, 0x3C, 0xF5, 0x22, 0x54, 0x40, - 0xD3, 0x94, 0x00, 0x40, 0x1E, 0xE5, 0x29, 0x54, -/*0110*/0xF0, 0x70, 0x21, 0x12, 0x19, 0xF3, 0xE0, 0x44, - 0x80, 0xF0, 0xE5, 0x22, 0x54, 0x30, 0x65, 0x08, -/*0120*/0x70, 0x09, 0x12, 0x19, 0xF3, 0xE0, 0x54, 0xBF, - 0xF0, 0x80, 0x09, 0x12, 0x19, 0xF3, 0x74, 0x40, -/*0130*/0xF0, 0x02, 0x03, 0xFB, 0x12, 0x1A, 0x12, 0x75, - 0x83, 0xAE, 0x74, 0xFF, 0xF0, 0xAF, 0x08, 0x7E, -/*0140*/0x00, 0xEF, 0x44, 0x07, 0xF5, 0x82, 0xE0, 0xFD, - 0xE5, 0x0B, 0x25, 0xE0, 0x25, 0xE0, 0x24, 0x81, -/*0150*/0xF5, 0x82, 0xE4, 0x34, 0x07, 0xF5, 0x83, 0xED, - 0xF0, 0x90, 0x07, 0x0E, 0xE0, 0x04, 0xF0, 0xEF, -/*0160*/0x44, 0x07, 0xF5, 0x82, 0x75, 0x83, 0x98, 0xE0, - 0xF5, 0x28, 0x12, 0x1A, 0x23, 0x40, 0x0C, 0x12, -/*0170*/0x19, 0xF3, 0xE0, 0x44, 0x01, 0x12, 0x1A, 0x32, - 0x02, 0x03, 0xF6, 0xAF, 0x08, 0x7E, 0x00, 0x74, -/*0180*/0x80, 0xCD, 0xEF, 0xCD, 0x8D, 0x82, 0xF5, 0x83, - 0xE0, 0x30, 0xE0, 0x0A, 0x12, 0x19, 0xF3, 0xE0, -/*0190*/0x44, 0x20, 0xF0, 0x02, 0x03, 0xFB, 0x12, 0x19, - 0xF3, 0xE0, 0x54, 0xDF, 0xF0, 0xEE, 0x44, 0xAE, -/*01A0*/0x12, 0x1A, 0x43, 0x30, 0xE4, 0x03, 0x02, 0x03, - 0xFB, 0x74, 0x9E, 0x12, 0x1A, 0x05, 0x20, 0xE0, -/*01B0*/0x03, 0x02, 0x03, 0xFB, 0x8F, 0x82, 0x8E, 0x83, - 0xE0, 0x20, 0xE0, 0x03, 0x02, 0x03, 0xFB, 0x12, -/*01C0*/0x19, 0xF3, 0xE0, 0x44, 0x10, 0xF0, 0xE5, 0xE3, - 0x20, 0xE7, 0x08, 0xE5, 0x08, 0x12, 0x1A, 0x3A, -/*01D0*/0x44, 0x04, 0xF0, 0xAF, 0x08, 0x7E, 0x00, 0xEF, - 0x12, 0x1A, 0x3A, 0x20, 0xE2, 0x34, 0x12, 0x19, -/*01E0*/0xF3, 0xE0, 0x44, 0x08, 0xF0, 0xE5, 0xE4, 0x30, - 0xE6, 0x04, 0x7D, 0x01, 0x80, 0x02, 0x7D, 0x00, -/*01F0*/0xE5, 0x7E, 0xC3, 0x94, 0x04, 0x50, 0x04, 0x7C, - 0x01, 0x80, 0x02, 0x7C, 0x00, 0xEC, 0x4D, 0x60, -/*0200*/0x05, 0xC2, 0x35, 0x02, 0x03, 0xFB, 0xEE, 0x44, - 0xD2, 0x12, 0x1A, 0x43, 0x44, 0x40, 0xF0, 0x02, -/*0210*/0x03, 0xFB, 0x12, 0x19, 0xF3, 0xE0, 0x54, 0xF7, - 0xF0, 0x12, 0x1A, 0x12, 0x75, 0x83, 0xD2, 0xE0, -/*0220*/0x54, 0xBF, 0xF0, 0x90, 0x07, 0x14, 0xE0, 0x04, - 0xF0, 0xE5, 0x7E, 0x70, 0x03, 0x75, 0x7E, 0x01, -/*0230*/0xAF, 0x08, 0x7E, 0x00, 0x12, 0x1A, 0x23, 0x40, - 0x12, 0x12, 0x19, 0xF3, 0xE0, 0x44, 0x01, 0x12, -/*0240*/0x19, 0xF2, 0xE0, 0x54, 0x02, 0x12, 0x1A, 0x32, - 0x02, 0x03, 0xFB, 0x12, 0x19, 0xF3, 0xE0, 0x44, -/*0250*/0x02, 0x12, 0x19, 0xF2, 0xE0, 0x54, 0xFE, 0xF0, - 0xC2, 0x35, 0xEE, 0x44, 0x8A, 0x8F, 0x82, 0xF5, -/*0260*/0x83, 0xE0, 0xF5, 0x17, 0x54, 0x8F, 0x44, 0x40, - 0xF0, 0x74, 0x90, 0xFC, 0xE5, 0x08, 0x44, 0x07, -/*0270*/0xFD, 0xF5, 0x82, 0x8C, 0x83, 0xE0, 0x54, 0x3F, - 0x90, 0x07, 0x02, 0xF0, 0xE0, 0x54, 0xC0, 0x8D, -/*0280*/0x82, 0x8C, 0x83, 0xF0, 0x74, 0x92, 0x12, 0x1A, - 0x05, 0x90, 0x07, 0x03, 0x12, 0x1A, 0x19, 0x74, -/*0290*/0x82, 0x12, 0x1A, 0x05, 0x90, 0x07, 0x04, 0x12, - 0x1A, 0x19, 0x74, 0xB4, 0x12, 0x1A, 0x05, 0x90, -/*02A0*/0x07, 0x05, 0x12, 0x1A, 0x19, 0x74, 0x94, 0xFE, - 0xE5, 0x08, 0x44, 0x06, 0x12, 0x1A, 0x0A, 0xF5, -/*02B0*/0x10, 0x30, 0xE0, 0x04, 0xD2, 0x37, 0x80, 0x02, - 0xC2, 0x37, 0xE5, 0x10, 0x54, 0x7F, 0x8F, 0x82, -/*02C0*/0x8E, 0x83, 0xF0, 0x30, 0x44, 0x30, 0x12, 0x1A, - 0x03, 0x54, 0x80, 0xD3, 0x94, 0x00, 0x40, 0x04, -/*02D0*/0xD2, 0x39, 0x80, 0x02, 0xC2, 0x39, 0x8F, 0x82, - 0x8E, 0x83, 0xE0, 0x44, 0x80, 0xF0, 0x12, 0x1A, -/*02E0*/0x03, 0x54, 0x40, 0xD3, 0x94, 0x00, 0x40, 0x04, - 0xD2, 0x3A, 0x80, 0x02, 0xC2, 0x3A, 0x8F, 0x82, -/*02F0*/0x8E, 0x83, 0xE0, 0x44, 0x40, 0xF0, 0x74, 0x92, - 0xFE, 0xE5, 0x08, 0x44, 0x06, 0x12, 0x1A, 0x0A, -/*0300*/0x30, 0xE7, 0x04, 0xD2, 0x38, 0x80, 0x02, 0xC2, - 0x38, 0x8F, 0x82, 0x8E, 0x83, 0xE0, 0x54, 0x7F, -/*0310*/0xF0, 0x12, 0x1E, 0x46, 0xE4, 0xF5, 0x0A, 0x20, - 0x03, 0x02, 0x80, 0x03, 0x30, 0x43, 0x03, 0x12, -/*0320*/0x19, 0x95, 0x20, 0x02, 0x02, 0x80, 0x03, 0x30, - 0x42, 0x03, 0x12, 0x0C, 0x8F, 0x30, 0x30, 0x06, -/*0330*/0x12, 0x19, 0x95, 0x12, 0x0C, 0x8F, 0x12, 0x0D, - 0x47, 0x12, 0x19, 0xF3, 0xE0, 0x54, 0xFB, 0xF0, -/*0340*/0xE5, 0x0A, 0xC3, 0x94, 0x01, 0x40, 0x46, 0x43, - 0xE1, 0x08, 0x12, 0x19, 0xF3, 0xE0, 0x44, 0x04, -/*0350*/0xF0, 0xE5, 0xE4, 0x20, 0xE7, 0x2A, 0x12, 0x1A, - 0x12, 0x75, 0x83, 0xD2, 0xE0, 0x54, 0x08, 0xD3, -/*0360*/0x94, 0x00, 0x40, 0x04, 0x7F, 0x01, 0x80, 0x02, - 0x7F, 0x00, 0xE5, 0x0A, 0xC3, 0x94, 0x01, 0x40, -/*0370*/0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEF, - 0x5E, 0x60, 0x05, 0x12, 0x1D, 0xD7, 0x80, 0x17, -/*0380*/0x12, 0x1A, 0x12, 0x75, 0x83, 0xD2, 0xE0, 0x44, - 0x08, 0xF0, 0x02, 0x03, 0xFB, 0x12, 0x1A, 0x12, -/*0390*/0x75, 0x83, 0xD2, 0xE0, 0x54, 0xF7, 0xF0, 0x12, - 0x1E, 0x46, 0x7F, 0x08, 0x12, 0x17, 0x31, 0x74, -/*03A0*/0x8E, 0xFE, 0x12, 0x1A, 0x12, 0x8E, 0x83, 0xE0, - 0xF5, 0x10, 0x54, 0xFE, 0xF0, 0xE5, 0x10, 0x44, -/*03B0*/0x01, 0xFF, 0xE5, 0x08, 0xFD, 0xED, 0x44, 0x07, - 0xF5, 0x82, 0xEF, 0xF0, 0xE5, 0x10, 0x54, 0xFE, -/*03C0*/0xFF, 0xED, 0x44, 0x07, 0xF5, 0x82, 0xEF, 0x12, - 0x1A, 0x11, 0x75, 0x83, 0x86, 0xE0, 0x44, 0x10, -/*03D0*/0x12, 0x1A, 0x11, 0xE0, 0x44, 0x10, 0xF0, 0x12, - 0x19, 0xF3, 0xE0, 0x54, 0xFD, 0x44, 0x01, 0xFF, -/*03E0*/0x12, 0x19, 0xF3, 0xEF, 0x12, 0x1A, 0x32, 0x30, - 0x32, 0x0C, 0xE5, 0x08, 0x44, 0x08, 0xF5, 0x82, -/*03F0*/0x75, 0x83, 0x82, 0x74, 0x05, 0xF0, 0xAF, 0x0B, - 0x12, 0x18, 0xD7, 0x74, 0x10, 0x25, 0x08, 0xF5, -/*0400*/0x08, 0x02, 0x00, 0x85, 0x05, 0x09, 0xE5, 0x09, - 0xD3, 0x94, 0x07, 0x50, 0x03, 0x02, 0x00, 0x82, -/*0410*/0xE5, 0x7E, 0xD3, 0x94, 0x00, 0x40, 0x04, 0x7F, - 0x01, 0x80, 0x02, 0x7F, 0x00, 0xE5, 0x7E, 0xC3, -/*0420*/0x94, 0xFA, 0x50, 0x04, 0x7E, 0x01, 0x80, 0x02, - 0x7E, 0x00, 0xEE, 0x5F, 0x60, 0x02, 0x05, 0x7E, -/*0430*/0x30, 0x35, 0x0B, 0x43, 0xE1, 0x01, 0x7F, 0x09, - 0x12, 0x17, 0x31, 0x02, 0x00, 0x58, 0x53, 0xE1, -/*0440*/0xFE, 0x02, 0x00, 0x58, 0x8E, 0x6A, 0x8F, 0x6B, - 0x8C, 0x6C, 0x8D, 0x6D, 0x75, 0x6E, 0x01, 0x75, -/*0450*/0x6F, 0x01, 0x75, 0x70, 0x01, 0xE4, 0xF5, 0x73, - 0xF5, 0x74, 0xF5, 0x75, 0x90, 0x07, 0x2F, 0xF0, -/*0460*/0xF5, 0x3C, 0xF5, 0x3E, 0xF5, 0x46, 0xF5, 0x47, - 0xF5, 0x3D, 0xF5, 0x3F, 0xF5, 0x6F, 0xE5, 0x6F, -/*0470*/0x70, 0x0F, 0xE5, 0x6B, 0x45, 0x6A, 0x12, 0x07, - 0x2A, 0x75, 0x83, 0x80, 0x74, 0x3A, 0xF0, 0x80, -/*0480*/0x09, 0x12, 0x07, 0x2A, 0x75, 0x83, 0x80, 0x74, - 0x1A, 0xF0, 0xE4, 0xF5, 0x6E, 0xC3, 0x74, 0x3F, -/*0490*/0x95, 0x6E, 0xFF, 0x12, 0x08, 0x65, 0x75, 0x83, - 0x82, 0xEF, 0xF0, 0x12, 0x1A, 0x4D, 0x12, 0x08, -/*04A0*/0xC6, 0xE5, 0x33, 0xF0, 0x12, 0x08, 0xFA, 0x12, - 0x08, 0xB1, 0x40, 0xE1, 0xE5, 0x6F, 0x70, 0x0B, -/*04B0*/0x12, 0x07, 0x2A, 0x75, 0x83, 0x80, 0x74, 0x36, - 0xF0, 0x80, 0x09, 0x12, 0x07, 0x2A, 0x75, 0x83, -/*04C0*/0x80, 0x74, 0x16, 0xF0, 0x75, 0x6E, 0x01, 0x12, - 0x07, 0x2A, 0x75, 0x83, 0xB4, 0xE5, 0x6E, 0xF0, -/*04D0*/0x12, 0x1A, 0x4D, 0x74, 0x3F, 0x25, 0x6E, 0xF5, - 0x82, 0xE4, 0x34, 0x00, 0xF5, 0x83, 0xE5, 0x33, -/*04E0*/0xF0, 0x74, 0xBF, 0x25, 0x6E, 0xF5, 0x82, 0xE4, - 0x34, 0x00, 0x12, 0x08, 0xB1, 0x40, 0xD8, 0xE4, -/*04F0*/0xF5, 0x70, 0xF5, 0x46, 0xF5, 0x47, 0xF5, 0x6E, - 0x12, 0x08, 0xFA, 0xF5, 0x83, 0xE0, 0xFE, 0x12, -/*0500*/0x08, 0xC6, 0xE0, 0x7C, 0x00, 0x24, 0x00, 0xFF, - 0xEC, 0x3E, 0xFE, 0xAD, 0x3B, 0xD3, 0xEF, 0x9D, -/*0510*/0xEE, 0x9C, 0x50, 0x04, 0x7B, 0x01, 0x80, 0x02, - 0x7B, 0x00, 0xE5, 0x70, 0x70, 0x04, 0x7A, 0x01, -/*0520*/0x80, 0x02, 0x7A, 0x00, 0xEB, 0x5A, 0x60, 0x06, - 0x85, 0x6E, 0x46, 0x75, 0x70, 0x01, 0xD3, 0xEF, -/*0530*/0x9D, 0xEE, 0x9C, 0x50, 0x04, 0x7F, 0x01, 0x80, - 0x02, 0x7F, 0x00, 0xE5, 0x70, 0xB4, 0x01, 0x04, -/*0540*/0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEF, 0x5E, - 0x60, 0x03, 0x85, 0x6E, 0x47, 0x05, 0x6E, 0xE5, -/*0550*/0x6E, 0x64, 0x7F, 0x70, 0xA3, 0xE5, 0x46, 0x60, - 0x05, 0xE5, 0x47, 0xB4, 0x7E, 0x03, 0x85, 0x46, -/*0560*/0x47, 0xE5, 0x6F, 0x70, 0x08, 0x85, 0x46, 0x76, - 0x85, 0x47, 0x77, 0x80, 0x0E, 0xC3, 0x74, 0x7F, -/*0570*/0x95, 0x46, 0xF5, 0x78, 0xC3, 0x74, 0x7F, 0x95, - 0x47, 0xF5, 0x79, 0xE5, 0x6F, 0x70, 0x37, 0xE5, -/*0580*/0x46, 0x65, 0x47, 0x70, 0x0C, 0x75, 0x73, 0x01, - 0x75, 0x74, 0x01, 0xF5, 0x3C, 0xF5, 0x3D, 0x80, -/*0590*/0x35, 0xE4, 0xF5, 0x4E, 0xC3, 0xE5, 0x47, 0x95, - 0x46, 0xF5, 0x3C, 0xC3, 0x13, 0xF5, 0x71, 0x25, -/*05A0*/0x46, 0xF5, 0x72, 0xC3, 0x94, 0x3F, 0x40, 0x05, - 0xE4, 0xF5, 0x3D, 0x80, 0x40, 0xC3, 0x74, 0x3F, -/*05B0*/0x95, 0x72, 0xF5, 0x3D, 0x80, 0x37, 0xE5, 0x46, - 0x65, 0x47, 0x70, 0x0F, 0x75, 0x73, 0x01, 0x75, -/*05C0*/0x75, 0x01, 0xF5, 0x3E, 0xF5, 0x3F, 0x75, 0x4E, - 0x01, 0x80, 0x22, 0xE4, 0xF5, 0x4E, 0xC3, 0xE5, -/*05D0*/0x47, 0x95, 0x46, 0xF5, 0x3E, 0xC3, 0x13, 0xF5, - 0x71, 0x25, 0x46, 0xF5, 0x72, 0xD3, 0x94, 0x3F, -/*05E0*/0x50, 0x05, 0xE4, 0xF5, 0x3F, 0x80, 0x06, 0xE5, - 0x72, 0x24, 0xC1, 0xF5, 0x3F, 0x05, 0x6F, 0xE5, -/*05F0*/0x6F, 0xC3, 0x94, 0x02, 0x50, 0x03, 0x02, 0x04, - 0x6E, 0xE5, 0x6D, 0x45, 0x6C, 0x70, 0x02, 0x80, -/*0600*/0x04, 0xE5, 0x74, 0x45, 0x75, 0x90, 0x07, 0x2F, - 0xF0, 0x7F, 0x01, 0xE5, 0x3E, 0x60, 0x04, 0xE5, -/*0610*/0x3C, 0x70, 0x14, 0xE4, 0xF5, 0x3C, 0xF5, 0x3D, - 0xF5, 0x3E, 0xF5, 0x3F, 0x12, 0x08, 0xD2, 0x70, -/*0620*/0x04, 0xF0, 0x02, 0x06, 0xA4, 0x80, 0x7A, 0xE5, - 0x3C, 0xC3, 0x95, 0x3E, 0x40, 0x07, 0xE5, 0x3C, -/*0630*/0x95, 0x3E, 0xFF, 0x80, 0x06, 0xC3, 0xE5, 0x3E, - 0x95, 0x3C, 0xFF, 0xE5, 0x76, 0xD3, 0x95, 0x79, -/*0640*/0x40, 0x05, 0x85, 0x76, 0x7A, 0x80, 0x03, 0x85, - 0x79, 0x7A, 0xE5, 0x77, 0xC3, 0x95, 0x78, 0x50, -/*0650*/0x05, 0x85, 0x77, 0x7B, 0x80, 0x03, 0x85, 0x78, - 0x7B, 0xE5, 0x7B, 0xD3, 0x95, 0x7A, 0x40, 0x30, -/*0660*/0xE5, 0x7B, 0x95, 0x7A, 0xF5, 0x3C, 0xF5, 0x3E, - 0xC3, 0xE5, 0x7B, 0x95, 0x7A, 0x90, 0x07, 0x19, -/*0670*/0xF0, 0xE5, 0x3C, 0xC3, 0x13, 0xF5, 0x71, 0x25, - 0x7A, 0xF5, 0x72, 0xC3, 0x94, 0x3F, 0x40, 0x05, -/*0680*/0xE4, 0xF5, 0x3D, 0x80, 0x1F, 0xC3, 0x74, 0x3F, - 0x95, 0x72, 0xF5, 0x3D, 0xF5, 0x3F, 0x80, 0x14, -/*0690*/0xE4, 0xF5, 0x3C, 0xF5, 0x3E, 0x90, 0x07, 0x19, - 0xF0, 0x12, 0x08, 0xD2, 0x70, 0x03, 0xF0, 0x80, -/*06A0*/0x03, 0x74, 0x01, 0xF0, 0x12, 0x08, 0x65, 0x75, - 0x83, 0xD0, 0xE0, 0x54, 0x0F, 0xFE, 0xAD, 0x3C, -/*06B0*/0x70, 0x02, 0x7E, 0x07, 0xBE, 0x0F, 0x02, 0x7E, - 0x80, 0xEE, 0xFB, 0xEF, 0xD3, 0x9B, 0x74, 0x80, -/*06C0*/0xF8, 0x98, 0x40, 0x1F, 0xE4, 0xF5, 0x3C, 0xF5, - 0x3E, 0x12, 0x08, 0xD2, 0x70, 0x03, 0xF0, 0x80, -/*06D0*/0x12, 0x74, 0x01, 0xF0, 0xE5, 0x08, 0xFB, 0xEB, - 0x44, 0x07, 0xF5, 0x82, 0x75, 0x83, 0xD2, 0xE0, -/*06E0*/0x44, 0x10, 0xF0, 0xE5, 0x08, 0xFB, 0xEB, 0x44, - 0x09, 0xF5, 0x82, 0x75, 0x83, 0x9E, 0xED, 0xF0, -/*06F0*/0xEB, 0x44, 0x07, 0xF5, 0x82, 0x75, 0x83, 0xCA, - 0xED, 0xF0, 0x12, 0x08, 0x65, 0x75, 0x83, 0xCC, -/*0700*/0xEF, 0xF0, 0x22, 0xE5, 0x08, 0x44, 0x07, 0xF5, - 0x82, 0x75, 0x83, 0xBC, 0xE0, 0x54, 0xF0, 0xF0, -/*0710*/0xE5, 0x08, 0x44, 0x07, 0xF5, 0x82, 0x75, 0x83, - 0xBE, 0xE0, 0x54, 0xF0, 0xF0, 0xE5, 0x08, 0x44, -/*0720*/0x07, 0xF5, 0x82, 0x75, 0x83, 0xC0, 0xE0, 0x54, - 0xF0, 0xF0, 0xE5, 0x08, 0x44, 0x07, 0xF5, 0x82, -/*0730*/0x22, 0xF0, 0x90, 0x07, 0x28, 0xE0, 0xFE, 0xA3, - 0xE0, 0xF5, 0x82, 0x8E, 0x83, 0x22, 0x85, 0x42, -/*0740*/0x42, 0x85, 0x41, 0x41, 0x85, 0x40, 0x40, 0x74, - 0xC0, 0x2F, 0xF5, 0x82, 0x74, 0x02, 0x3E, 0xF5, -/*0750*/0x83, 0xE5, 0x42, 0xF0, 0x74, 0xE0, 0x2F, 0xF5, - 0x82, 0x74, 0x02, 0x3E, 0xF5, 0x83, 0x22, 0xE5, -/*0760*/0x42, 0x29, 0xFD, 0xE4, 0x33, 0xFC, 0xE5, 0x3C, - 0xC3, 0x9D, 0xEC, 0x64, 0x80, 0xF8, 0x74, 0x80, -/*0770*/0x98, 0x22, 0xF5, 0x83, 0xE0, 0x90, 0x07, 0x22, - 0x54, 0x1F, 0xFD, 0xE0, 0xFA, 0xA3, 0xE0, 0xF5, -/*0780*/0x82, 0x8A, 0x83, 0xED, 0xF0, 0x22, 0x90, 0x07, - 0x22, 0xE0, 0xFC, 0xA3, 0xE0, 0xF5, 0x82, 0x8C, -/*0790*/0x83, 0x22, 0x90, 0x07, 0x24, 0xFF, 0xED, 0x44, - 0x07, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0x85, -/*07A0*/0x38, 0x38, 0x85, 0x39, 0x39, 0x85, 0x3A, 0x3A, - 0x74, 0xC0, 0x2F, 0xF5, 0x82, 0x74, 0x02, 0x3E, -/*07B0*/0xF5, 0x83, 0x22, 0x90, 0x07, 0x26, 0xFF, 0xED, - 0x44, 0x07, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, -/*07C0*/0xF0, 0x74, 0xA0, 0x2F, 0xF5, 0x82, 0x74, 0x02, - 0x3E, 0xF5, 0x83, 0x22, 0x74, 0xC0, 0x25, 0x11, -/*07D0*/0xF5, 0x82, 0xE4, 0x34, 0x01, 0xF5, 0x83, 0x22, - 0x74, 0x00, 0x25, 0x11, 0xF5, 0x82, 0xE4, 0x34, -/*07E0*/0x02, 0xF5, 0x83, 0x22, 0x74, 0x60, 0x25, 0x11, - 0xF5, 0x82, 0xE4, 0x34, 0x03, 0xF5, 0x83, 0x22, -/*07F0*/0x74, 0x80, 0x25, 0x11, 0xF5, 0x82, 0xE4, 0x34, - 0x03, 0xF5, 0x83, 0x22, 0x74, 0xE0, 0x25, 0x11, -/*0800*/0xF5, 0x82, 0xE4, 0x34, 0x03, 0xF5, 0x83, 0x22, - 0x74, 0x40, 0x25, 0x11, 0xF5, 0x82, 0xE4, 0x34, -/*0810*/0x06, 0xF5, 0x83, 0x22, 0x74, 0x80, 0x2F, 0xF5, - 0x82, 0x74, 0x02, 0x3E, 0xF5, 0x83, 0x22, 0xAF, -/*0820*/0x08, 0x7E, 0x00, 0xEF, 0x44, 0x07, 0xF5, 0x82, - 0x22, 0xF5, 0x83, 0xE5, 0x82, 0x44, 0x07, 0xF5, -/*0830*/0x82, 0xE5, 0x40, 0xF0, 0x22, 0x74, 0x40, 0x25, - 0x11, 0xF5, 0x82, 0xE4, 0x34, 0x02, 0xF5, 0x83, -/*0840*/0x22, 0x74, 0xC0, 0x25, 0x11, 0xF5, 0x82, 0xE4, - 0x34, 0x03, 0xF5, 0x83, 0x22, 0x74, 0x00, 0x25, -/*0850*/0x11, 0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, - 0x22, 0x74, 0x20, 0x25, 0x11, 0xF5, 0x82, 0xE4, -/*0860*/0x34, 0x06, 0xF5, 0x83, 0x22, 0xE5, 0x08, 0xFD, - 0xED, 0x44, 0x07, 0xF5, 0x82, 0x22, 0xE5, 0x41, -/*0870*/0xF0, 0xE5, 0x65, 0x64, 0x01, 0x45, 0x64, 0x22, - 0x7E, 0x00, 0xFB, 0x7A, 0x00, 0xFD, 0x7C, 0x00, -/*0880*/0x22, 0x74, 0x20, 0x25, 0x11, 0xF5, 0x82, 0xE4, - 0x34, 0x02, 0x22, 0x74, 0xA0, 0x25, 0x11, 0xF5, -/*0890*/0x82, 0xE4, 0x34, 0x03, 0x22, 0x85, 0x3E, 0x42, - 0x85, 0x3F, 0x41, 0x8F, 0x40, 0x22, 0x85, 0x3C, -/*08A0*/0x42, 0x85, 0x3D, 0x41, 0x8F, 0x40, 0x22, 0x75, - 0x45, 0x3F, 0x90, 0x07, 0x20, 0xE4, 0xF0, 0xA3, -/*08B0*/0x22, 0xF5, 0x83, 0xE5, 0x32, 0xF0, 0x05, 0x6E, - 0xE5, 0x6E, 0xC3, 0x94, 0x40, 0x22, 0xF0, 0xE5, -/*08C0*/0x08, 0x44, 0x06, 0xF5, 0x82, 0x22, 0x74, 0x00, - 0x25, 0x6E, 0xF5, 0x82, 0xE4, 0x34, 0x00, 0xF5, -/*08D0*/0x83, 0x22, 0xE5, 0x6D, 0x45, 0x6C, 0x90, 0x07, - 0x2F, 0x22, 0xE4, 0xF9, 0xE5, 0x3C, 0xD3, 0x95, -/*08E0*/0x3E, 0x22, 0x74, 0x80, 0x2E, 0xF5, 0x82, 0xE4, - 0x34, 0x02, 0xF5, 0x83, 0xE0, 0x22, 0x74, 0xA0, -/*08F0*/0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x02, 0xF5, 0x83, - 0xE0, 0x22, 0x74, 0x80, 0x25, 0x6E, 0xF5, 0x82, -/*0900*/0xE4, 0x34, 0x00, 0x22, 0x25, 0x42, 0xFD, 0xE4, - 0x33, 0xFC, 0x22, 0x85, 0x42, 0x42, 0x85, 0x41, -/*0910*/0x41, 0x85, 0x40, 0x40, 0x22, 0xED, 0x4C, 0x60, - 0x03, 0x02, 0x09, 0xE5, 0xEF, 0x4E, 0x70, 0x37, -/*0920*/0x90, 0x07, 0x26, 0x12, 0x07, 0x89, 0xE0, 0xFD, - 0x12, 0x07, 0xCC, 0xED, 0xF0, 0x90, 0x07, 0x28, -/*0930*/0x12, 0x07, 0x89, 0xE0, 0xFD, 0x12, 0x07, 0xD8, - 0xED, 0xF0, 0x12, 0x07, 0x86, 0xE0, 0x54, 0x1F, -/*0940*/0xFD, 0x12, 0x08, 0x81, 0xF5, 0x83, 0xED, 0xF0, - 0x90, 0x07, 0x24, 0x12, 0x07, 0x89, 0xE0, 0x54, -/*0950*/0x1F, 0xFD, 0x12, 0x08, 0x35, 0xED, 0xF0, 0xEF, - 0x64, 0x04, 0x4E, 0x70, 0x37, 0x90, 0x07, 0x26, -/*0960*/0x12, 0x07, 0x89, 0xE0, 0xFD, 0x12, 0x07, 0xE4, - 0xED, 0xF0, 0x90, 0x07, 0x28, 0x12, 0x07, 0x89, -/*0970*/0xE0, 0xFD, 0x12, 0x07, 0xF0, 0xED, 0xF0, 0x12, - 0x07, 0x86, 0xE0, 0x54, 0x1F, 0xFD, 0x12, 0x08, -/*0980*/0x8B, 0xF5, 0x83, 0xED, 0xF0, 0x90, 0x07, 0x24, - 0x12, 0x07, 0x89, 0xE0, 0x54, 0x1F, 0xFD, 0x12, -/*0990*/0x08, 0x41, 0xED, 0xF0, 0xEF, 0x64, 0x01, 0x4E, - 0x70, 0x04, 0x7D, 0x01, 0x80, 0x02, 0x7D, 0x00, -/*09A0*/0xEF, 0x64, 0x02, 0x4E, 0x70, 0x04, 0x7F, 0x01, - 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x4D, 0x60, 0x78, -/*09B0*/0x90, 0x07, 0x26, 0x12, 0x07, 0x35, 0xE0, 0xFF, - 0x12, 0x07, 0xFC, 0xEF, 0x12, 0x07, 0x31, 0xE0, -/*09C0*/0xFF, 0x12, 0x08, 0x08, 0xEF, 0xF0, 0x90, 0x07, - 0x22, 0x12, 0x07, 0x35, 0xE0, 0x54, 0x1F, 0xFF, -/*09D0*/0x12, 0x08, 0x4D, 0xEF, 0xF0, 0x90, 0x07, 0x24, - 0x12, 0x07, 0x35, 0xE0, 0x54, 0x1F, 0xFF, 0x12, -/*09E0*/0x08, 0x59, 0xEF, 0xF0, 0x22, 0x12, 0x07, 0xCC, - 0xE4, 0xF0, 0x12, 0x07, 0xD8, 0xE4, 0xF0, 0x12, -/*09F0*/0x08, 0x81, 0xF5, 0x83, 0xE4, 0xF0, 0x12, 0x08, - 0x35, 0x74, 0x14, 0xF0, 0x12, 0x07, 0xE4, 0xE4, -/*0A00*/0xF0, 0x12, 0x07, 0xF0, 0xE4, 0xF0, 0x12, 0x08, - 0x8B, 0xF5, 0x83, 0xE4, 0xF0, 0x12, 0x08, 0x41, -/*0A10*/0x74, 0x14, 0xF0, 0x12, 0x07, 0xFC, 0xE4, 0xF0, - 0x12, 0x08, 0x08, 0xE4, 0xF0, 0x12, 0x08, 0x4D, -/*0A20*/0xE4, 0xF0, 0x12, 0x08, 0x59, 0x74, 0x14, 0xF0, - 0x22, 0x53, 0xF9, 0xF7, 0x75, 0xFC, 0x10, 0xE4, -/*0A30*/0xF5, 0xFD, 0x75, 0xFE, 0x30, 0xF5, 0xFF, 0xE5, - 0xE7, 0x20, 0xE7, 0x03, 0x43, 0xF9, 0x08, 0xE5, -/*0A40*/0xE6, 0x20, 0xE7, 0x0B, 0x78, 0xFF, 0xE4, 0xF6, - 0xD8, 0xFD, 0x53, 0xE6, 0xFE, 0x80, 0x09, 0x78, -/*0A50*/0x08, 0xE4, 0xF6, 0xD8, 0xFD, 0x53, 0xE6, 0xFE, - 0x75, 0x81, 0x80, 0xE4, 0xF5, 0xA8, 0xD2, 0xA8, -/*0A60*/0xC2, 0xA9, 0xD2, 0xAF, 0xE5, 0xE2, 0x20, 0xE5, - 0x05, 0x20, 0xE6, 0x02, 0x80, 0x03, 0x43, 0xE1, -/*0A70*/0x02, 0xE5, 0xE2, 0x20, 0xE0, 0x0E, 0x90, 0x00, - 0x00, 0x7F, 0x00, 0x7E, 0x08, 0xE4, 0xF0, 0xA3, -/*0A80*/0xDF, 0xFC, 0xDE, 0xFA, 0x02, 0x0A, 0xDB, 0x43, - 0xFA, 0x01, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0x83, -/*0A90*/0xC0, 0x82, 0xC0, 0xD0, 0x12, 0x1C, 0xE7, 0xD0, - 0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0, -/*0AA0*/0xE0, 0x53, 0xFA, 0xFE, 0x32, 0x02, 0x1B, 0x55, - 0xE4, 0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0xF6, -/*0AB0*/0x08, 0xDF, 0xF9, 0x80, 0x29, 0xE4, 0x93, 0xA3, - 0xF8, 0x54, 0x07, 0x24, 0x0C, 0xC8, 0xC3, 0x33, -/*0AC0*/0xC4, 0x54, 0x0F, 0x44, 0x20, 0xC8, 0x83, 0x40, - 0x04, 0xF4, 0x56, 0x80, 0x01, 0x46, 0xF6, 0xDF, -/*0AD0*/0xE4, 0x80, 0x0B, 0x01, 0x02, 0x04, 0x08, 0x10, - 0x20, 0x40, 0x80, 0x90, 0x00, 0x3F, 0xE4, 0x7E, -/*0AE0*/0x01, 0x93, 0x60, 0xC1, 0xA3, 0xFF, 0x54, 0x3F, - 0x30, 0xE5, 0x09, 0x54, 0x1F, 0xFE, 0xE4, 0x93, -/*0AF0*/0xA3, 0x60, 0x01, 0x0E, 0xCF, 0x54, 0xC0, 0x25, - 0xE0, 0x60, 0xAD, 0x40, 0xB8, 0x80, 0xFE, 0x8C, -/*0B00*/0x64, 0x8D, 0x65, 0x8A, 0x66, 0x8B, 0x67, 0xE4, - 0xF5, 0x69, 0xEF, 0x4E, 0x70, 0x03, 0x02, 0x1D, -/*0B10*/0x55, 0xE4, 0xF5, 0x68, 0xE5, 0x67, 0x45, 0x66, - 0x70, 0x32, 0x12, 0x07, 0x2A, 0x75, 0x83, 0x90, -/*0B20*/0xE4, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC2, 0xE4, - 0x12, 0x07, 0x29, 0x75, 0x83, 0xC4, 0xE4, 0x12, -/*0B30*/0x08, 0x70, 0x70, 0x29, 0x12, 0x07, 0x2A, 0x75, - 0x83, 0x92, 0xE4, 0x12, 0x07, 0x29, 0x75, 0x83, -/*0B40*/0xC6, 0xE4, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC8, - 0xE4, 0xF0, 0x80, 0x11, 0x90, 0x07, 0x26, 0x12, -/*0B50*/0x07, 0x35, 0xE4, 0x12, 0x08, 0x70, 0x70, 0x05, - 0x12, 0x07, 0x32, 0xE4, 0xF0, 0x12, 0x1D, 0x55, -/*0B60*/0x12, 0x1E, 0xBF, 0xE5, 0x67, 0x45, 0x66, 0x70, - 0x33, 0x12, 0x07, 0x2A, 0x75, 0x83, 0x90, 0xE5, -/*0B70*/0x41, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC2, 0xE5, - 0x41, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC4, 0x12, -/*0B80*/0x08, 0x6E, 0x70, 0x29, 0x12, 0x07, 0x2A, 0x75, - 0x83, 0x92, 0xE5, 0x40, 0x12, 0x07, 0x29, 0x75, -/*0B90*/0x83, 0xC6, 0xE5, 0x40, 0x12, 0x07, 0x29, 0x75, - 0x83, 0xC8, 0x80, 0x0E, 0x90, 0x07, 0x26, 0x12, -/*0BA0*/0x07, 0x35, 0x12, 0x08, 0x6E, 0x70, 0x06, 0x12, - 0x07, 0x32, 0xE5, 0x40, 0xF0, 0xAF, 0x69, 0x7E, -/*0BB0*/0x00, 0xAD, 0x67, 0xAC, 0x66, 0x12, 0x04, 0x44, - 0x12, 0x07, 0x2A, 0x75, 0x83, 0xCA, 0xE0, 0xD3, -/*0BC0*/0x94, 0x00, 0x50, 0x0C, 0x05, 0x68, 0xE5, 0x68, - 0xC3, 0x94, 0x05, 0x50, 0x03, 0x02, 0x0B, 0x14, -/*0BD0*/0x22, 0x8C, 0x60, 0x8D, 0x61, 0x12, 0x08, 0xDA, - 0x74, 0x20, 0x40, 0x0D, 0x2F, 0xF5, 0x82, 0x74, -/*0BE0*/0x03, 0x3E, 0xF5, 0x83, 0xE5, 0x3E, 0xF0, 0x80, - 0x0B, 0x2F, 0xF5, 0x82, 0x74, 0x03, 0x3E, 0xF5, -/*0BF0*/0x83, 0xE5, 0x3C, 0xF0, 0xE5, 0x3C, 0xD3, 0x95, - 0x3E, 0x40, 0x3C, 0xE5, 0x61, 0x45, 0x60, 0x70, -/*0C00*/0x10, 0xE9, 0x12, 0x09, 0x04, 0xE5, 0x3E, 0x12, - 0x07, 0x68, 0x40, 0x3B, 0x12, 0x08, 0x95, 0x80, -/*0C10*/0x18, 0xE5, 0x3E, 0xC3, 0x95, 0x38, 0x40, 0x1D, - 0x85, 0x3E, 0x38, 0xE5, 0x3E, 0x60, 0x05, 0x85, -/*0C20*/0x3F, 0x39, 0x80, 0x03, 0x85, 0x39, 0x39, 0x8F, - 0x3A, 0x12, 0x08, 0x14, 0xE5, 0x3E, 0x12, 0x07, -/*0C30*/0xC0, 0xE5, 0x3F, 0xF0, 0x22, 0x80, 0x43, 0xE5, - 0x61, 0x45, 0x60, 0x70, 0x19, 0x12, 0x07, 0x5F, -/*0C40*/0x40, 0x05, 0x12, 0x08, 0x9E, 0x80, 0x27, 0x12, - 0x09, 0x0B, 0x12, 0x08, 0x14, 0xE5, 0x42, 0x12, -/*0C50*/0x07, 0xC0, 0xE5, 0x41, 0xF0, 0x22, 0xE5, 0x3C, - 0xC3, 0x95, 0x38, 0x40, 0x1D, 0x85, 0x3C, 0x38, -/*0C60*/0xE5, 0x3C, 0x60, 0x05, 0x85, 0x3D, 0x39, 0x80, - 0x03, 0x85, 0x39, 0x39, 0x8F, 0x3A, 0x12, 0x08, -/*0C70*/0x14, 0xE5, 0x3C, 0x12, 0x07, 0xC0, 0xE5, 0x3D, - 0xF0, 0x22, 0x85, 0x38, 0x38, 0x85, 0x39, 0x39, -/*0C80*/0x85, 0x3A, 0x3A, 0x12, 0x08, 0x14, 0xE5, 0x38, - 0x12, 0x07, 0xC0, 0xE5, 0x39, 0xF0, 0x22, 0x7F, -/*0C90*/0x06, 0x12, 0x17, 0x31, 0x12, 0x1D, 0x23, 0x12, - 0x0E, 0x04, 0x12, 0x0E, 0x33, 0xE0, 0x44, 0x0A, -/*0CA0*/0xF0, 0x74, 0x8E, 0xFE, 0x12, 0x0E, 0x04, 0x12, - 0x0E, 0x0B, 0xEF, 0xF0, 0xE5, 0x28, 0x30, 0xE5, -/*0CB0*/0x03, 0xD3, 0x80, 0x01, 0xC3, 0x40, 0x05, 0x75, - 0x14, 0x20, 0x80, 0x03, 0x75, 0x14, 0x08, 0x12, -/*0CC0*/0x0E, 0x04, 0x75, 0x83, 0x8A, 0xE5, 0x14, 0xF0, - 0xB4, 0xFF, 0x05, 0x75, 0x12, 0x80, 0x80, 0x06, -/*0CD0*/0xE5, 0x14, 0xC3, 0x13, 0xF5, 0x12, 0xE4, 0xF5, - 0x16, 0xF5, 0x7F, 0x12, 0x19, 0x36, 0x12, 0x13, -/*0CE0*/0xA3, 0xE5, 0x0A, 0xC3, 0x94, 0x01, 0x50, 0x09, - 0x05, 0x16, 0xE5, 0x16, 0xC3, 0x94, 0x14, 0x40, -/*0CF0*/0xEA, 0xE5, 0xE4, 0x20, 0xE7, 0x28, 0x12, 0x0E, - 0x04, 0x75, 0x83, 0xD2, 0xE0, 0x54, 0x08, 0xD3, -/*0D00*/0x94, 0x00, 0x40, 0x04, 0x7F, 0x01, 0x80, 0x02, - 0x7F, 0x00, 0xE5, 0x0A, 0xC3, 0x94, 0x01, 0x40, -/*0D10*/0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEF, - 0x5E, 0x60, 0x03, 0x12, 0x1D, 0xD7, 0xE5, 0x7F, -/*0D20*/0xC3, 0x94, 0x11, 0x40, 0x14, 0x12, 0x0E, 0x04, - 0x75, 0x83, 0xD2, 0xE0, 0x44, 0x80, 0xF0, 0xE5, -/*0D30*/0xE4, 0x20, 0xE7, 0x0F, 0x12, 0x1D, 0xD7, 0x80, - 0x0A, 0x12, 0x0E, 0x04, 0x75, 0x83, 0xD2, 0xE0, -/*0D40*/0x54, 0x7F, 0xF0, 0x12, 0x1D, 0x23, 0x22, 0x74, - 0x8A, 0x85, 0x08, 0x82, 0xF5, 0x83, 0xE5, 0x17, -/*0D50*/0xF0, 0x12, 0x0E, 0x3A, 0xE4, 0xF0, 0x90, 0x07, - 0x02, 0xE0, 0x12, 0x0E, 0x17, 0x75, 0x83, 0x90, -/*0D60*/0xEF, 0xF0, 0x74, 0x92, 0xFE, 0xE5, 0x08, 0x44, - 0x07, 0xFF, 0xF5, 0x82, 0x8E, 0x83, 0xE0, 0x54, -/*0D70*/0xC0, 0xFD, 0x90, 0x07, 0x03, 0xE0, 0x54, 0x3F, - 0x4D, 0x8F, 0x82, 0x8E, 0x83, 0xF0, 0x90, 0x07, -/*0D80*/0x04, 0xE0, 0x12, 0x0E, 0x17, 0x75, 0x83, 0x82, - 0xEF, 0xF0, 0x90, 0x07, 0x05, 0xE0, 0xFF, 0xED, -/*0D90*/0x44, 0x07, 0xF5, 0x82, 0x75, 0x83, 0xB4, 0xEF, - 0x12, 0x0E, 0x03, 0x75, 0x83, 0x80, 0xE0, 0x54, -/*0DA0*/0xBF, 0xF0, 0x30, 0x37, 0x0A, 0x12, 0x0E, 0x91, - 0x75, 0x83, 0x94, 0xE0, 0x44, 0x80, 0xF0, 0x30, -/*0DB0*/0x38, 0x0A, 0x12, 0x0E, 0x91, 0x75, 0x83, 0x92, - 0xE0, 0x44, 0x80, 0xF0, 0xE5, 0x28, 0x30, 0xE4, -/*0DC0*/0x1A, 0x20, 0x39, 0x0A, 0x12, 0x0E, 0x04, 0x75, - 0x83, 0x88, 0xE0, 0x54, 0x7F, 0xF0, 0x20, 0x3A, -/*0DD0*/0x0A, 0x12, 0x0E, 0x04, 0x75, 0x83, 0x88, 0xE0, - 0x54, 0xBF, 0xF0, 0x74, 0x8C, 0xFE, 0x12, 0x0E, -/*0DE0*/0x04, 0x8E, 0x83, 0xE0, 0x54, 0x0F, 0x12, 0x0E, - 0x03, 0x75, 0x83, 0x86, 0xE0, 0x54, 0xBF, 0xF0, -/*0DF0*/0xE5, 0x08, 0x44, 0x06, 0x12, 0x0D, 0xFD, 0x75, - 0x83, 0x8A, 0xE4, 0xF0, 0x22, 0xF5, 0x82, 0x75, -/*0E00*/0x83, 0x82, 0xE4, 0xF0, 0xE5, 0x08, 0x44, 0x07, - 0xF5, 0x82, 0x22, 0x8E, 0x83, 0xE0, 0xF5, 0x10, -/*0E10*/0x54, 0xFE, 0xF0, 0xE5, 0x10, 0x44, 0x01, 0xFF, - 0xE5, 0x08, 0xFD, 0xED, 0x44, 0x07, 0xF5, 0x82, -/*0E20*/0x22, 0xE5, 0x15, 0xC4, 0x54, 0x07, 0xFF, 0xE5, - 0x08, 0xFD, 0xED, 0x44, 0x08, 0xF5, 0x82, 0x75, -/*0E30*/0x83, 0x82, 0x22, 0x75, 0x83, 0x80, 0xE0, 0x44, - 0x40, 0xF0, 0xE5, 0x08, 0x44, 0x08, 0xF5, 0x82, -/*0E40*/0x75, 0x83, 0x8A, 0x22, 0xE5, 0x16, 0x25, 0xE0, - 0x25, 0xE0, 0x24, 0xAF, 0xF5, 0x82, 0xE4, 0x34, -/*0E50*/0x1A, 0xF5, 0x83, 0xE4, 0x93, 0xF5, 0x0D, 0x22, - 0x43, 0xE1, 0x10, 0x43, 0xE1, 0x80, 0x53, 0xE1, -/*0E60*/0xFD, 0x85, 0xE1, 0x10, 0x22, 0xE5, 0x16, 0x25, - 0xE0, 0x25, 0xE0, 0x24, 0xB2, 0xF5, 0x82, 0xE4, -/*0E70*/0x34, 0x1A, 0xF5, 0x83, 0xE4, 0x93, 0x22, 0x85, - 0x55, 0x82, 0x85, 0x54, 0x83, 0xE5, 0x15, 0xF0, -/*0E80*/0x22, 0xE5, 0xE2, 0x54, 0x20, 0xD3, 0x94, 0x00, - 0x22, 0xE5, 0xE2, 0x54, 0x40, 0xD3, 0x94, 0x00, -/*0E90*/0x22, 0xE5, 0x08, 0x44, 0x06, 0xF5, 0x82, 0x22, - 0xFD, 0xE5, 0x08, 0xFB, 0xEB, 0x44, 0x07, 0xF5, -/*0EA0*/0x82, 0x22, 0x53, 0xF9, 0xF7, 0x75, 0xFE, 0x30, - 0x22, 0xEF, 0x4E, 0x70, 0x26, 0x12, 0x07, 0xCC, -/*0EB0*/0xE0, 0xFD, 0x90, 0x07, 0x26, 0x12, 0x07, 0x7B, - 0x12, 0x07, 0xD8, 0xE0, 0xFD, 0x90, 0x07, 0x28, -/*0EC0*/0x12, 0x07, 0x7B, 0x12, 0x08, 0x81, 0x12, 0x07, - 0x72, 0x12, 0x08, 0x35, 0xE0, 0x90, 0x07, 0x24, -/*0ED0*/0x12, 0x07, 0x78, 0xEF, 0x64, 0x04, 0x4E, 0x70, - 0x29, 0x12, 0x07, 0xE4, 0xE0, 0xFD, 0x90, 0x07, -/*0EE0*/0x26, 0x12, 0x07, 0x7B, 0x12, 0x07, 0xF0, 0xE0, - 0xFD, 0x90, 0x07, 0x28, 0x12, 0x07, 0x7B, 0x12, -/*0EF0*/0x08, 0x8B, 0x12, 0x07, 0x72, 0x12, 0x08, 0x41, - 0xE0, 0x54, 0x1F, 0xFD, 0x90, 0x07, 0x24, 0x12, -/*0F00*/0x07, 0x7B, 0xEF, 0x64, 0x01, 0x4E, 0x70, 0x04, - 0x7D, 0x01, 0x80, 0x02, 0x7D, 0x00, 0xEF, 0x64, -/*0F10*/0x02, 0x4E, 0x70, 0x04, 0x7F, 0x01, 0x80, 0x02, - 0x7F, 0x00, 0xEF, 0x4D, 0x60, 0x35, 0x12, 0x07, -/*0F20*/0xFC, 0xE0, 0xFF, 0x90, 0x07, 0x26, 0x12, 0x07, - 0x89, 0xEF, 0xF0, 0x12, 0x08, 0x08, 0xE0, 0xFF, -/*0F30*/0x90, 0x07, 0x28, 0x12, 0x07, 0x89, 0xEF, 0xF0, - 0x12, 0x08, 0x4D, 0xE0, 0x54, 0x1F, 0xFF, 0x12, -/*0F40*/0x07, 0x86, 0xEF, 0xF0, 0x12, 0x08, 0x59, 0xE0, - 0x54, 0x1F, 0xFF, 0x90, 0x07, 0x24, 0x12, 0x07, -/*0F50*/0x89, 0xEF, 0xF0, 0x22, 0xE4, 0xF5, 0x53, 0x12, - 0x0E, 0x81, 0x40, 0x04, 0x7F, 0x01, 0x80, 0x02, -/*0F60*/0x7F, 0x00, 0x12, 0x0E, 0x89, 0x40, 0x04, 0x7E, - 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE, 0x4F, 0x70, -/*0F70*/0x03, 0x02, 0x0F, 0xF6, 0x85, 0xE1, 0x10, 0x43, - 0xE1, 0x02, 0x53, 0xE1, 0x0F, 0x85, 0xE1, 0x10, -/*0F80*/0xE4, 0xF5, 0x51, 0xE5, 0xE3, 0x54, 0x3F, 0xF5, - 0x52, 0x12, 0x0E, 0x89, 0x40, 0x1D, 0xAD, 0x52, -/*0F90*/0xAF, 0x51, 0x12, 0x11, 0x18, 0xEF, 0x60, 0x08, - 0x85, 0xE1, 0x10, 0x43, 0xE1, 0x40, 0x80, 0x0B, -/*0FA0*/0x53, 0xE1, 0xBF, 0x12, 0x0E, 0x58, 0x12, 0x00, - 0x06, 0x80, 0xFB, 0xE5, 0xE3, 0x54, 0x3F, 0xF5, -/*0FB0*/0x51, 0xE5, 0xE4, 0x54, 0x3F, 0xF5, 0x52, 0x12, - 0x0E, 0x81, 0x40, 0x1D, 0xAD, 0x52, 0xAF, 0x51, -/*0FC0*/0x12, 0x11, 0x18, 0xEF, 0x60, 0x08, 0x85, 0xE1, - 0x10, 0x43, 0xE1, 0x20, 0x80, 0x0B, 0x53, 0xE1, -/*0FD0*/0xDF, 0x12, 0x0E, 0x58, 0x12, 0x00, 0x06, 0x80, - 0xFB, 0x12, 0x0E, 0x81, 0x40, 0x04, 0x7F, 0x01, -/*0FE0*/0x80, 0x02, 0x7F, 0x00, 0x12, 0x0E, 0x89, 0x40, - 0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE, -/*0FF0*/0x4F, 0x60, 0x03, 0x12, 0x0E, 0x5B, 0x22, 0x12, - 0x0E, 0x21, 0xEF, 0xF0, 0x12, 0x10, 0x91, 0x22, -/*1000*/0x02, 0x11, 0x00, 0x02, 0x10, 0x40, 0x02, 0x10, - 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/*1010*/0x01, 0x20, 0x01, 0x20, 0xE4, 0xF5, 0x57, 0x12, - 0x16, 0xBD, 0x12, 0x16, 0x44, 0xE4, 0x12, 0x10, -/*1020*/0x56, 0x12, 0x14, 0xB7, 0x90, 0x07, 0x26, 0x12, - 0x07, 0x35, 0xE4, 0x12, 0x07, 0x31, 0xE4, 0xF0, -/*1030*/0x12, 0x10, 0x56, 0x12, 0x14, 0xB7, 0x90, 0x07, - 0x26, 0x12, 0x07, 0x35, 0xE5, 0x41, 0x12, 0x07, -/*1040*/0x31, 0xE5, 0x40, 0xF0, 0xAF, 0x57, 0x7E, 0x00, - 0xAD, 0x56, 0x7C, 0x00, 0x12, 0x04, 0x44, 0xAF, -/*1050*/0x56, 0x7E, 0x00, 0x02, 0x11, 0xEE, 0xFF, 0x90, - 0x07, 0x20, 0xA3, 0xE0, 0xFD, 0xE4, 0xF5, 0x56, -/*1060*/0xF5, 0x40, 0xFE, 0xFC, 0xAB, 0x56, 0xFA, 0x12, - 0x11, 0x51, 0x7F, 0x0F, 0x7D, 0x18, 0xE4, 0xF5, -/*1070*/0x56, 0xF5, 0x40, 0xFE, 0xFC, 0xAB, 0x56, 0xFA, - 0x12, 0x15, 0x41, 0xAF, 0x56, 0x7E, 0x00, 0x12, -/*1080*/0x1A, 0xFF, 0xE4, 0xFF, 0xF5, 0x56, 0x7D, 0x1F, - 0xF5, 0x40, 0xFE, 0xFC, 0xAB, 0x56, 0xFA, 0x22, -/*1090*/0x22, 0xE4, 0xF5, 0x55, 0xE5, 0x08, 0xFD, 0x74, - 0xA0, 0xF5, 0x56, 0xED, 0x44, 0x07, 0xF5, 0x57, -/*10A0*/0xE5, 0x28, 0x30, 0xE5, 0x03, 0xD3, 0x80, 0x01, - 0xC3, 0x40, 0x05, 0x7F, 0x28, 0xEF, 0x80, 0x04, -/*10B0*/0x7F, 0x14, 0xEF, 0xC3, 0x13, 0xF5, 0x54, 0xE4, - 0xF9, 0x12, 0x0E, 0x18, 0x75, 0x83, 0x8E, 0xE0, -/*10C0*/0xF5, 0x10, 0xCE, 0xEF, 0xCE, 0xEE, 0xD3, 0x94, - 0x00, 0x40, 0x26, 0xE5, 0x10, 0x54, 0xFE, 0x12, -/*10D0*/0x0E, 0x98, 0x75, 0x83, 0x8E, 0xED, 0xF0, 0xE5, - 0x10, 0x44, 0x01, 0xFD, 0xEB, 0x44, 0x07, 0xF5, -/*10E0*/0x82, 0xED, 0xF0, 0x85, 0x57, 0x82, 0x85, 0x56, - 0x83, 0xE0, 0x30, 0xE3, 0x01, 0x09, 0x1E, 0x80, -/*10F0*/0xD4, 0xC2, 0x34, 0xE9, 0xC3, 0x95, 0x54, 0x40, - 0x02, 0xD2, 0x34, 0x22, 0x02, 0x00, 0x06, 0x22, -/*1100*/0x30, 0x30, 0x11, 0x90, 0x10, 0x00, 0xE4, 0x93, - 0xF5, 0x10, 0x90, 0x10, 0x10, 0xE4, 0x93, 0xF5, -/*1110*/0x10, 0x12, 0x10, 0x90, 0x12, 0x11, 0x50, 0x22, - 0xE4, 0xFC, 0xC3, 0xED, 0x9F, 0xFA, 0xEF, 0xF5, -/*1120*/0x83, 0x75, 0x82, 0x00, 0x79, 0xFF, 0xE4, 0x93, - 0xCC, 0x6C, 0xCC, 0xA3, 0xD9, 0xF8, 0xDA, 0xF6, -/*1130*/0xE5, 0xE2, 0x30, 0xE4, 0x02, 0x8C, 0xE5, 0xED, - 0x24, 0xFF, 0xFF, 0xEF, 0x75, 0x82, 0xFF, 0xF5, -/*1140*/0x83, 0xE4, 0x93, 0x6C, 0x70, 0x03, 0x7F, 0x01, - 0x22, 0x7F, 0x00, 0x22, 0x22, 0x11, 0x00, 0x00, -/*1150*/0x22, 0x8E, 0x58, 0x8F, 0x59, 0x8C, 0x5A, 0x8D, - 0x5B, 0x8A, 0x5C, 0x8B, 0x5D, 0x75, 0x5E, 0x01, -/*1160*/0xE4, 0xF5, 0x5F, 0xF5, 0x60, 0xF5, 0x62, 0x12, - 0x07, 0x2A, 0x75, 0x83, 0xD0, 0xE0, 0xFF, 0xC4, -/*1170*/0x54, 0x0F, 0xF5, 0x61, 0x12, 0x1E, 0xA5, 0x85, - 0x59, 0x5E, 0xD3, 0xE5, 0x5E, 0x95, 0x5B, 0xE5, -/*1180*/0x5A, 0x12, 0x07, 0x6B, 0x50, 0x4B, 0x12, 0x07, - 0x03, 0x75, 0x83, 0xBC, 0xE0, 0x45, 0x5E, 0x12, -/*1190*/0x07, 0x29, 0x75, 0x83, 0xBE, 0xE0, 0x45, 0x5E, - 0x12, 0x07, 0x29, 0x75, 0x83, 0xC0, 0xE0, 0x45, -/*11A0*/0x5E, 0xF0, 0xAF, 0x5F, 0xE5, 0x60, 0x12, 0x08, - 0x78, 0x12, 0x0A, 0xFF, 0xAF, 0x62, 0x7E, 0x00, -/*11B0*/0xAD, 0x5D, 0xAC, 0x5C, 0x12, 0x04, 0x44, 0xE5, - 0x61, 0xAF, 0x5E, 0x7E, 0x00, 0xB4, 0x03, 0x05, -/*11C0*/0x12, 0x1E, 0x21, 0x80, 0x07, 0xAD, 0x5D, 0xAC, - 0x5C, 0x12, 0x13, 0x17, 0x05, 0x5E, 0x02, 0x11, -/*11D0*/0x7A, 0x12, 0x07, 0x03, 0x75, 0x83, 0xBC, 0xE0, - 0x45, 0x40, 0x12, 0x07, 0x29, 0x75, 0x83, 0xBE, -/*11E0*/0xE0, 0x45, 0x40, 0x12, 0x07, 0x29, 0x75, 0x83, - 0xC0, 0xE0, 0x45, 0x40, 0xF0, 0x22, 0x8E, 0x58, -/*11F0*/0x8F, 0x59, 0x75, 0x5A, 0x01, 0x79, 0x01, 0x75, - 0x5B, 0x01, 0xE4, 0xFB, 0x12, 0x07, 0x2A, 0x75, -/*1200*/0x83, 0xAE, 0xE0, 0x54, 0x1A, 0xFF, 0x12, 0x08, - 0x65, 0xE0, 0xC4, 0x13, 0x54, 0x07, 0xFE, 0xEF, -/*1210*/0x70, 0x0C, 0xEE, 0x65, 0x35, 0x70, 0x07, 0x90, - 0x07, 0x2F, 0xE0, 0xB4, 0x01, 0x0D, 0xAF, 0x35, -/*1220*/0x7E, 0x00, 0x12, 0x0E, 0xA9, 0xCF, 0xEB, 0xCF, - 0x02, 0x1E, 0x60, 0xE5, 0x59, 0x64, 0x02, 0x45, -/*1230*/0x58, 0x70, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, - 0x00, 0xE5, 0x59, 0x45, 0x58, 0x70, 0x04, 0x7E, -/*1240*/0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE, 0x4F, 0x60, - 0x23, 0x85, 0x41, 0x49, 0x85, 0x40, 0x4B, 0xE5, -/*1250*/0x59, 0x45, 0x58, 0x70, 0x2C, 0xAF, 0x5A, 0xFE, - 0xCD, 0xE9, 0xCD, 0xFC, 0xAB, 0x59, 0xAA, 0x58, -/*1260*/0x12, 0x0A, 0xFF, 0xAF, 0x5B, 0x7E, 0x00, 0x12, - 0x1E, 0x60, 0x80, 0x15, 0xAF, 0x5B, 0x7E, 0x00, -/*1270*/0x12, 0x1E, 0x60, 0x90, 0x07, 0x26, 0x12, 0x07, - 0x35, 0xE5, 0x49, 0x12, 0x07, 0x31, 0xE5, 0x4B, -/*1280*/0xF0, 0xE4, 0xFD, 0xAF, 0x35, 0xFE, 0xFC, 0x12, - 0x09, 0x15, 0x22, 0x8C, 0x64, 0x8D, 0x65, 0x12, -/*1290*/0x08, 0xDA, 0x40, 0x3C, 0xE5, 0x65, 0x45, 0x64, - 0x70, 0x10, 0x12, 0x09, 0x04, 0xC3, 0xE5, 0x3E, -/*12A0*/0x12, 0x07, 0x69, 0x40, 0x3B, 0x12, 0x08, 0x95, - 0x80, 0x18, 0xE5, 0x3E, 0xC3, 0x95, 0x38, 0x40, -/*12B0*/0x1D, 0x85, 0x3E, 0x38, 0xE5, 0x3E, 0x60, 0x05, - 0x85, 0x3F, 0x39, 0x80, 0x03, 0x85, 0x39, 0x39, -/*12C0*/0x8F, 0x3A, 0x12, 0x07, 0xA8, 0xE5, 0x3E, 0x12, - 0x07, 0x53, 0xE5, 0x3F, 0xF0, 0x22, 0x80, 0x3B, -/*12D0*/0xE5, 0x65, 0x45, 0x64, 0x70, 0x11, 0x12, 0x07, - 0x5F, 0x40, 0x05, 0x12, 0x08, 0x9E, 0x80, 0x1F, -/*12E0*/0x12, 0x07, 0x3E, 0xE5, 0x41, 0xF0, 0x22, 0xE5, - 0x3C, 0xC3, 0x95, 0x38, 0x40, 0x1D, 0x85, 0x3C, -/*12F0*/0x38, 0xE5, 0x3C, 0x60, 0x05, 0x85, 0x3D, 0x39, - 0x80, 0x03, 0x85, 0x39, 0x39, 0x8F, 0x3A, 0x12, -/*1300*/0x07, 0xA8, 0xE5, 0x3C, 0x12, 0x07, 0x53, 0xE5, - 0x3D, 0xF0, 0x22, 0x12, 0x07, 0x9F, 0xE5, 0x38, -/*1310*/0x12, 0x07, 0x53, 0xE5, 0x39, 0xF0, 0x22, 0x8C, - 0x63, 0x8D, 0x64, 0x12, 0x08, 0xDA, 0x40, 0x3C, -/*1320*/0xE5, 0x64, 0x45, 0x63, 0x70, 0x10, 0x12, 0x09, - 0x04, 0xC3, 0xE5, 0x3E, 0x12, 0x07, 0x69, 0x40, -/*1330*/0x3B, 0x12, 0x08, 0x95, 0x80, 0x18, 0xE5, 0x3E, - 0xC3, 0x95, 0x38, 0x40, 0x1D, 0x85, 0x3E, 0x38, -/*1340*/0xE5, 0x3E, 0x60, 0x05, 0x85, 0x3F, 0x39, 0x80, - 0x03, 0x85, 0x39, 0x39, 0x8F, 0x3A, 0x12, 0x07, -/*1350*/0xA8, 0xE5, 0x3E, 0x12, 0x07, 0x53, 0xE5, 0x3F, - 0xF0, 0x22, 0x80, 0x3B, 0xE5, 0x64, 0x45, 0x63, -/*1360*/0x70, 0x11, 0x12, 0x07, 0x5F, 0x40, 0x05, 0x12, - 0x08, 0x9E, 0x80, 0x1F, 0x12, 0x07, 0x3E, 0xE5, -/*1370*/0x41, 0xF0, 0x22, 0xE5, 0x3C, 0xC3, 0x95, 0x38, - 0x40, 0x1D, 0x85, 0x3C, 0x38, 0xE5, 0x3C, 0x60, -/*1380*/0x05, 0x85, 0x3D, 0x39, 0x80, 0x03, 0x85, 0x39, - 0x39, 0x8F, 0x3A, 0x12, 0x07, 0xA8, 0xE5, 0x3C, -/*1390*/0x12, 0x07, 0x53, 0xE5, 0x3D, 0xF0, 0x22, 0x12, - 0x07, 0x9F, 0xE5, 0x38, 0x12, 0x07, 0x53, 0xE5, -/*13A0*/0x39, 0xF0, 0x22, 0xE5, 0x0D, 0xFE, 0xE5, 0x08, - 0x8E, 0x54, 0x44, 0x05, 0xF5, 0x55, 0x75, 0x15, -/*13B0*/0x0F, 0xF5, 0x82, 0x12, 0x0E, 0x7A, 0x12, 0x17, - 0xA3, 0x20, 0x31, 0x05, 0x75, 0x15, 0x03, 0x80, -/*13C0*/0x03, 0x75, 0x15, 0x0B, 0xE5, 0x0A, 0xC3, 0x94, - 0x01, 0x50, 0x38, 0x12, 0x14, 0x20, 0x20, 0x31, -/*13D0*/0x06, 0x05, 0x15, 0x05, 0x15, 0x80, 0x04, 0x15, - 0x15, 0x15, 0x15, 0xE5, 0x0A, 0xC3, 0x94, 0x01, -/*13E0*/0x50, 0x21, 0x12, 0x14, 0x20, 0x20, 0x31, 0x04, - 0x05, 0x15, 0x80, 0x02, 0x15, 0x15, 0xE5, 0x0A, -/*13F0*/0xC3, 0x94, 0x01, 0x50, 0x0E, 0x12, 0x0E, 0x77, - 0x12, 0x17, 0xA3, 0x20, 0x31, 0x05, 0x05, 0x15, -/*1400*/0x12, 0x0E, 0x77, 0xE5, 0x15, 0xB4, 0x08, 0x04, - 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xE5, 0x15, -/*1410*/0xB4, 0x07, 0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, - 0x00, 0xEE, 0x4F, 0x60, 0x02, 0x05, 0x7F, 0x22, -/*1420*/0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xE5, 0x15, - 0xF0, 0x12, 0x17, 0xA3, 0x22, 0x12, 0x07, 0x2A, -/*1430*/0x75, 0x83, 0xAE, 0x74, 0xFF, 0x12, 0x07, 0x29, - 0xE0, 0x54, 0x1A, 0xF5, 0x34, 0xE0, 0xC4, 0x13, -/*1440*/0x54, 0x07, 0xF5, 0x35, 0x24, 0xFE, 0x60, 0x24, - 0x24, 0xFE, 0x60, 0x3C, 0x24, 0x04, 0x70, 0x63, -/*1450*/0x75, 0x31, 0x2D, 0xE5, 0x08, 0xFD, 0x74, 0xB6, - 0x12, 0x07, 0x92, 0x74, 0xBC, 0x90, 0x07, 0x22, -/*1460*/0x12, 0x07, 0x95, 0x74, 0x90, 0x12, 0x07, 0xB3, - 0x74, 0x92, 0x80, 0x3C, 0x75, 0x31, 0x3A, 0xE5, -/*1470*/0x08, 0xFD, 0x74, 0xBA, 0x12, 0x07, 0x92, 0x74, - 0xC0, 0x90, 0x07, 0x22, 0x12, 0x07, 0xB6, 0x74, -/*1480*/0xC4, 0x12, 0x07, 0xB3, 0x74, 0xC8, 0x80, 0x20, - 0x75, 0x31, 0x35, 0xE5, 0x08, 0xFD, 0x74, 0xB8, -/*1490*/0x12, 0x07, 0x92, 0x74, 0xBE, 0xFF, 0xED, 0x44, - 0x07, 0x90, 0x07, 0x22, 0xCF, 0xF0, 0xA3, 0xEF, -/*14A0*/0xF0, 0x74, 0xC2, 0x12, 0x07, 0xB3, 0x74, 0xC6, - 0xFF, 0xED, 0x44, 0x07, 0xA3, 0xCF, 0xF0, 0xA3, -/*14B0*/0xEF, 0xF0, 0x22, 0x75, 0x34, 0x01, 0x22, 0x8E, - 0x58, 0x8F, 0x59, 0x8C, 0x5A, 0x8D, 0x5B, 0x8A, -/*14C0*/0x5C, 0x8B, 0x5D, 0x75, 0x5E, 0x01, 0xE4, 0xF5, - 0x5F, 0x12, 0x1E, 0xA5, 0x85, 0x59, 0x5E, 0xD3, -/*14D0*/0xE5, 0x5E, 0x95, 0x5B, 0xE5, 0x5A, 0x12, 0x07, - 0x6B, 0x50, 0x57, 0xE5, 0x5D, 0x45, 0x5C, 0x70, -/*14E0*/0x30, 0x12, 0x07, 0x2A, 0x75, 0x83, 0x92, 0xE5, - 0x5E, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC6, 0xE5, -/*14F0*/0x5E, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC8, 0xE5, - 0x5E, 0x12, 0x07, 0x29, 0x75, 0x83, 0x90, 0xE5, -/*1500*/0x5E, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC2, 0xE5, - 0x5E, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC4, 0x80, -/*1510*/0x03, 0x12, 0x07, 0x32, 0xE5, 0x5E, 0xF0, 0xAF, - 0x5F, 0x7E, 0x00, 0xAD, 0x5D, 0xAC, 0x5C, 0x12, -/*1520*/0x04, 0x44, 0xAF, 0x5E, 0x7E, 0x00, 0xAD, 0x5D, - 0xAC, 0x5C, 0x12, 0x0B, 0xD1, 0x05, 0x5E, 0x02, -/*1530*/0x14, 0xCF, 0xAB, 0x5D, 0xAA, 0x5C, 0xAD, 0x5B, - 0xAC, 0x5A, 0xAF, 0x59, 0xAE, 0x58, 0x02, 0x1B, -/*1540*/0xFB, 0x8C, 0x5C, 0x8D, 0x5D, 0x8A, 0x5E, 0x8B, - 0x5F, 0x75, 0x60, 0x01, 0xE4, 0xF5, 0x61, 0xF5, -/*1550*/0x62, 0xF5, 0x63, 0x12, 0x1E, 0xA5, 0x8F, 0x60, - 0xD3, 0xE5, 0x60, 0x95, 0x5D, 0xE5, 0x5C, 0x12, -/*1560*/0x07, 0x6B, 0x50, 0x61, 0xE5, 0x5F, 0x45, 0x5E, - 0x70, 0x27, 0x12, 0x07, 0x2A, 0x75, 0x83, 0xB6, -/*1570*/0xE5, 0x60, 0x12, 0x07, 0x29, 0x75, 0x83, 0xB8, - 0xE5, 0x60, 0x12, 0x07, 0x29, 0x75, 0x83, 0xBA, -/*1580*/0xE5, 0x60, 0xF0, 0xAF, 0x61, 0x7E, 0x00, 0xE5, - 0x62, 0x12, 0x08, 0x7A, 0x12, 0x0A, 0xFF, 0x80, -/*1590*/0x19, 0x90, 0x07, 0x24, 0x12, 0x07, 0x35, 0xE5, - 0x60, 0x12, 0x07, 0x29, 0x75, 0x83, 0x8E, 0xE4, -/*15A0*/0x12, 0x07, 0x29, 0x74, 0x01, 0x12, 0x07, 0x29, - 0xE4, 0xF0, 0xAF, 0x63, 0x7E, 0x00, 0xAD, 0x5F, -/*15B0*/0xAC, 0x5E, 0x12, 0x04, 0x44, 0xAF, 0x60, 0x7E, - 0x00, 0xAD, 0x5F, 0xAC, 0x5E, 0x12, 0x12, 0x8B, -/*15C0*/0x05, 0x60, 0x02, 0x15, 0x58, 0x22, 0x90, 0x11, - 0x4D, 0xE4, 0x93, 0x90, 0x07, 0x2E, 0xF0, 0x12, -/*15D0*/0x08, 0x1F, 0x75, 0x83, 0xAE, 0xE0, 0x54, 0x1A, - 0xF5, 0x34, 0x70, 0x67, 0xEF, 0x44, 0x07, 0xF5, -/*15E0*/0x82, 0x75, 0x83, 0xCE, 0xE0, 0xFF, 0x13, 0x13, - 0x13, 0x54, 0x07, 0xF5, 0x36, 0x54, 0x0F, 0xD3, -/*15F0*/0x94, 0x00, 0x40, 0x06, 0x12, 0x14, 0x2D, 0x12, - 0x1B, 0xA9, 0xE5, 0x36, 0x54, 0x0F, 0x24, 0xFE, -/*1600*/0x60, 0x0C, 0x14, 0x60, 0x0C, 0x14, 0x60, 0x19, - 0x24, 0x03, 0x70, 0x37, 0x80, 0x10, 0x02, 0x1E, -/*1610*/0x91, 0x12, 0x1E, 0x91, 0x12, 0x07, 0x2A, 0x75, - 0x83, 0xCE, 0xE0, 0x54, 0xEF, 0xF0, 0x02, 0x1D, -/*1620*/0xAE, 0x12, 0x10, 0x14, 0xE4, 0xF5, 0x55, 0x12, - 0x1D, 0x85, 0x05, 0x55, 0xE5, 0x55, 0xC3, 0x94, -/*1630*/0x05, 0x40, 0xF4, 0x12, 0x07, 0x2A, 0x75, 0x83, - 0xCE, 0xE0, 0x54, 0xC7, 0x12, 0x07, 0x29, 0xE0, -/*1640*/0x44, 0x08, 0xF0, 0x22, 0xE4, 0xF5, 0x58, 0xF5, - 0x59, 0xAF, 0x08, 0xEF, 0x44, 0x07, 0xF5, 0x82, -/*1650*/0x75, 0x83, 0xD0, 0xE0, 0xFD, 0xC4, 0x54, 0x0F, - 0xF5, 0x5A, 0xEF, 0x44, 0x07, 0xF5, 0x82, 0x75, -/*1660*/0x83, 0x80, 0x74, 0x01, 0xF0, 0x12, 0x08, 0x21, - 0x75, 0x83, 0x82, 0xE5, 0x45, 0xF0, 0xEF, 0x44, -/*1670*/0x07, 0xF5, 0x82, 0x75, 0x83, 0x8A, 0x74, 0xFF, - 0xF0, 0x12, 0x1A, 0x4D, 0x12, 0x07, 0x2A, 0x75, -/*1680*/0x83, 0xBC, 0xE0, 0x54, 0xEF, 0x12, 0x07, 0x29, - 0x75, 0x83, 0xBE, 0xE0, 0x54, 0xEF, 0x12, 0x07, -/*1690*/0x29, 0x75, 0x83, 0xC0, 0xE0, 0x54, 0xEF, 0x12, - 0x07, 0x29, 0x75, 0x83, 0xBC, 0xE0, 0x44, 0x10, -/*16A0*/0x12, 0x07, 0x29, 0x75, 0x83, 0xBE, 0xE0, 0x44, - 0x10, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC0, 0xE0, -/*16B0*/0x44, 0x10, 0xF0, 0xAF, 0x58, 0xE5, 0x59, 0x12, - 0x08, 0x78, 0x02, 0x0A, 0xFF, 0xE4, 0xF5, 0x58, -/*16C0*/0x7D, 0x01, 0xF5, 0x59, 0xAF, 0x35, 0xFE, 0xFC, - 0x12, 0x09, 0x15, 0x12, 0x07, 0x2A, 0x75, 0x83, -/*16D0*/0xB6, 0x74, 0x10, 0x12, 0x07, 0x29, 0x75, 0x83, - 0xB8, 0x74, 0x10, 0x12, 0x07, 0x29, 0x75, 0x83, -/*16E0*/0xBA, 0x74, 0x10, 0x12, 0x07, 0x29, 0x75, 0x83, - 0xBC, 0x74, 0x10, 0x12, 0x07, 0x29, 0x75, 0x83, -/*16F0*/0xBE, 0x74, 0x10, 0x12, 0x07, 0x29, 0x75, 0x83, - 0xC0, 0x74, 0x10, 0x12, 0x07, 0x29, 0x75, 0x83, -/*1700*/0x90, 0xE4, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC2, - 0xE4, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC4, 0xE4, -/*1710*/0x12, 0x07, 0x29, 0x75, 0x83, 0x92, 0xE4, 0x12, - 0x07, 0x29, 0x75, 0x83, 0xC6, 0xE4, 0x12, 0x07, -/*1720*/0x29, 0x75, 0x83, 0xC8, 0xE4, 0xF0, 0xAF, 0x58, - 0xFE, 0xE5, 0x59, 0x12, 0x08, 0x7A, 0x02, 0x0A, -/*1730*/0xFF, 0xE5, 0xE2, 0x30, 0xE4, 0x6C, 0xE5, 0xE7, - 0x54, 0xC0, 0x64, 0x40, 0x70, 0x64, 0xE5, 0x09, -/*1740*/0xC4, 0x54, 0x30, 0xFE, 0xE5, 0x08, 0x25, 0xE0, - 0x25, 0xE0, 0x54, 0xC0, 0x4E, 0xFE, 0xEF, 0x54, -/*1750*/0x3F, 0x4E, 0xFD, 0xE5, 0x2B, 0xAE, 0x2A, 0x78, - 0x02, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, -/*1760*/0xF5, 0x82, 0x8E, 0x83, 0xED, 0xF0, 0xE5, 0x2B, - 0xAE, 0x2A, 0x78, 0x02, 0xC3, 0x33, 0xCE, 0x33, -/*1770*/0xCE, 0xD8, 0xF9, 0xFF, 0xF5, 0x82, 0x8E, 0x83, - 0xA3, 0xE5, 0xFE, 0xF0, 0x8F, 0x82, 0x8E, 0x83, -/*1780*/0xA3, 0xA3, 0xE5, 0xFD, 0xF0, 0x8F, 0x82, 0x8E, - 0x83, 0xA3, 0xA3, 0xA3, 0xE5, 0xFC, 0xF0, 0xC3, -/*1790*/0xE5, 0x2B, 0x94, 0xFA, 0xE5, 0x2A, 0x94, 0x00, - 0x50, 0x08, 0x05, 0x2B, 0xE5, 0x2B, 0x70, 0x02, -/*17A0*/0x05, 0x2A, 0x22, 0xE4, 0xFF, 0xE4, 0xF5, 0x58, - 0xF5, 0x56, 0xF5, 0x57, 0x74, 0x82, 0xFC, 0x12, -/*17B0*/0x0E, 0x04, 0x8C, 0x83, 0xE0, 0xF5, 0x10, 0x54, - 0x7F, 0xF0, 0xE5, 0x10, 0x44, 0x80, 0x12, 0x0E, -/*17C0*/0x98, 0xED, 0xF0, 0x7E, 0x0A, 0x12, 0x0E, 0x04, - 0x75, 0x83, 0xA0, 0xE0, 0x20, 0xE0, 0x26, 0xDE, -/*17D0*/0xF4, 0x05, 0x57, 0xE5, 0x57, 0x70, 0x02, 0x05, - 0x56, 0xE5, 0x14, 0x24, 0x01, 0xFD, 0xE4, 0x33, -/*17E0*/0xFC, 0xD3, 0xE5, 0x57, 0x9D, 0xE5, 0x56, 0x9C, - 0x40, 0xD9, 0xE5, 0x0A, 0x94, 0x20, 0x50, 0x02, -/*17F0*/0x05, 0x0A, 0x43, 0xE1, 0x08, 0xC2, 0x31, 0x12, - 0x0E, 0x04, 0x75, 0x83, 0xA6, 0xE0, 0x55, 0x12, -/*1800*/0x65, 0x12, 0x70, 0x03, 0xD2, 0x31, 0x22, 0xC2, - 0x31, 0x22, 0x90, 0x07, 0x26, 0xE0, 0xFA, 0xA3, -/*1810*/0xE0, 0xF5, 0x82, 0x8A, 0x83, 0xE0, 0xF5, 0x41, - 0xE5, 0x39, 0xC3, 0x95, 0x41, 0x40, 0x26, 0xE5, -/*1820*/0x39, 0x95, 0x41, 0xC3, 0x9F, 0xEE, 0x12, 0x07, - 0x6B, 0x40, 0x04, 0x7C, 0x01, 0x80, 0x02, 0x7C, -/*1830*/0x00, 0xE5, 0x41, 0x64, 0x3F, 0x60, 0x04, 0x7B, - 0x01, 0x80, 0x02, 0x7B, 0x00, 0xEC, 0x5B, 0x60, -/*1840*/0x29, 0x05, 0x41, 0x80, 0x28, 0xC3, 0xE5, 0x41, - 0x95, 0x39, 0xC3, 0x9F, 0xEE, 0x12, 0x07, 0x6B, -/*1850*/0x40, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, - 0xE5, 0x41, 0x60, 0x04, 0x7E, 0x01, 0x80, 0x02, -/*1860*/0x7E, 0x00, 0xEF, 0x5E, 0x60, 0x04, 0x15, 0x41, - 0x80, 0x03, 0x85, 0x39, 0x41, 0x85, 0x3A, 0x40, -/*1870*/0x22, 0xE5, 0xE2, 0x30, 0xE4, 0x60, 0xE5, 0xE1, - 0x30, 0xE2, 0x5B, 0xE5, 0x09, 0x70, 0x04, 0x7F, -/*1880*/0x01, 0x80, 0x02, 0x7F, 0x00, 0xE5, 0x08, 0x70, - 0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE, -/*1890*/0x5F, 0x60, 0x43, 0x53, 0xF9, 0xF8, 0xE5, 0xE2, - 0x30, 0xE4, 0x3B, 0xE5, 0xE1, 0x30, 0xE2, 0x2E, -/*18A0*/0x43, 0xFA, 0x02, 0x53, 0xFA, 0xFB, 0xE4, 0xF5, - 0x10, 0x90, 0x94, 0x70, 0xE5, 0x10, 0xF0, 0xE5, -/*18B0*/0xE1, 0x30, 0xE2, 0xE7, 0x90, 0x94, 0x70, 0xE0, - 0x65, 0x10, 0x60, 0x03, 0x43, 0xFA, 0x04, 0x05, -/*18C0*/0x10, 0x90, 0x94, 0x70, 0xE5, 0x10, 0xF0, 0x70, - 0xE6, 0x12, 0x00, 0x06, 0x80, 0xE1, 0x53, 0xFA, -/*18D0*/0xFD, 0x53, 0xFA, 0xFB, 0x80, 0xC0, 0x22, 0x8F, - 0x54, 0x12, 0x00, 0x06, 0xE5, 0xE1, 0x30, 0xE0, -/*18E0*/0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xE5, - 0x7E, 0xD3, 0x94, 0x05, 0x40, 0x04, 0x7E, 0x01, -/*18F0*/0x80, 0x02, 0x7E, 0x00, 0xEE, 0x4F, 0x60, 0x3D, - 0x85, 0x54, 0x11, 0xE5, 0xE2, 0x20, 0xE1, 0x32, -/*1900*/0x74, 0xCE, 0x12, 0x1A, 0x05, 0x30, 0xE7, 0x04, - 0x7D, 0x01, 0x80, 0x02, 0x7D, 0x00, 0x8F, 0x82, -/*1910*/0x8E, 0x83, 0xE0, 0x30, 0xE6, 0x04, 0x7F, 0x01, - 0x80, 0x02, 0x7F, 0x00, 0xEF, 0x5D, 0x70, 0x15, -/*1920*/0x12, 0x15, 0xC6, 0x74, 0xCE, 0x12, 0x1A, 0x05, - 0x30, 0xE6, 0x07, 0xE0, 0x44, 0x80, 0xF0, 0x43, -/*1930*/0xF9, 0x80, 0x12, 0x18, 0x71, 0x22, 0x12, 0x0E, - 0x44, 0xE5, 0x16, 0x25, 0xE0, 0x25, 0xE0, 0x24, -/*1940*/0xB0, 0xF5, 0x82, 0xE4, 0x34, 0x1A, 0xF5, 0x83, - 0xE4, 0x93, 0xF5, 0x0F, 0xE5, 0x16, 0x25, 0xE0, -/*1950*/0x25, 0xE0, 0x24, 0xB1, 0xF5, 0x82, 0xE4, 0x34, - 0x1A, 0xF5, 0x83, 0xE4, 0x93, 0xF5, 0x0E, 0x12, -/*1960*/0x0E, 0x65, 0xF5, 0x10, 0xE5, 0x0F, 0x54, 0xF0, - 0x12, 0x0E, 0x17, 0x75, 0x83, 0x8C, 0xEF, 0xF0, -/*1970*/0xE5, 0x0F, 0x30, 0xE0, 0x0C, 0x12, 0x0E, 0x04, - 0x75, 0x83, 0x86, 0xE0, 0x44, 0x40, 0xF0, 0x80, -/*1980*/0x0A, 0x12, 0x0E, 0x04, 0x75, 0x83, 0x86, 0xE0, - 0x54, 0xBF, 0xF0, 0x12, 0x0E, 0x91, 0x75, 0x83, -/*1990*/0x82, 0xE5, 0x0E, 0xF0, 0x22, 0x7F, 0x05, 0x12, - 0x17, 0x31, 0x12, 0x0E, 0x04, 0x12, 0x0E, 0x33, -/*19A0*/0x74, 0x02, 0xF0, 0x74, 0x8E, 0xFE, 0x12, 0x0E, - 0x04, 0x12, 0x0E, 0x0B, 0xEF, 0xF0, 0x75, 0x15, -/*19B0*/0x70, 0x12, 0x0F, 0xF7, 0x20, 0x34, 0x05, 0x75, - 0x15, 0x10, 0x80, 0x03, 0x75, 0x15, 0x50, 0x12, -/*19C0*/0x0F, 0xF7, 0x20, 0x34, 0x04, 0x74, 0x10, 0x80, - 0x02, 0x74, 0xF0, 0x25, 0x15, 0xF5, 0x15, 0x12, -/*19D0*/0x0E, 0x21, 0xEF, 0xF0, 0x12, 0x10, 0x91, 0x20, - 0x34, 0x17, 0xE5, 0x15, 0x64, 0x30, 0x60, 0x0C, -/*19E0*/0x74, 0x10, 0x25, 0x15, 0xF5, 0x15, 0xB4, 0x80, - 0x03, 0xE4, 0xF5, 0x15, 0x12, 0x0E, 0x21, 0xEF, -/*19F0*/0xF0, 0x22, 0xF0, 0xE5, 0x0B, 0x25, 0xE0, 0x25, - 0xE0, 0x24, 0x82, 0xF5, 0x82, 0xE4, 0x34, 0x07, -/*1A00*/0xF5, 0x83, 0x22, 0x74, 0x88, 0xFE, 0xE5, 0x08, - 0x44, 0x07, 0xFF, 0xF5, 0x82, 0x8E, 0x83, 0xE0, -/*1A10*/0x22, 0xF0, 0xE5, 0x08, 0x44, 0x07, 0xF5, 0x82, - 0x22, 0xF0, 0xE0, 0x54, 0xC0, 0x8F, 0x82, 0x8E, -/*1A20*/0x83, 0xF0, 0x22, 0xEF, 0x44, 0x07, 0xF5, 0x82, - 0x75, 0x83, 0x86, 0xE0, 0x54, 0x10, 0xD3, 0x94, -/*1A30*/0x00, 0x22, 0xF0, 0x90, 0x07, 0x15, 0xE0, 0x04, - 0xF0, 0x22, 0x44, 0x06, 0xF5, 0x82, 0x75, 0x83, -/*1A40*/0x9E, 0xE0, 0x22, 0xFE, 0xEF, 0x44, 0x07, 0xF5, - 0x82, 0x8E, 0x83, 0xE0, 0x22, 0xE4, 0x90, 0x07, -/*1A50*/0x2A, 0xF0, 0xA3, 0xF0, 0x12, 0x07, 0x2A, 0x75, - 0x83, 0x82, 0xE0, 0x54, 0x7F, 0x12, 0x07, 0x29, -/*1A60*/0xE0, 0x44, 0x80, 0xF0, 0x12, 0x10, 0xFC, 0x12, - 0x08, 0x1F, 0x75, 0x83, 0xA0, 0xE0, 0x20, 0xE0, -/*1A70*/0x1A, 0x90, 0x07, 0x2B, 0xE0, 0x04, 0xF0, 0x70, - 0x06, 0x90, 0x07, 0x2A, 0xE0, 0x04, 0xF0, 0x90, -/*1A80*/0x07, 0x2A, 0xE0, 0xB4, 0x10, 0xE1, 0xA3, 0xE0, - 0xB4, 0x00, 0xDC, 0xEE, 0x44, 0xA6, 0xFC, 0xEF, -/*1A90*/0x44, 0x07, 0xF5, 0x82, 0x8C, 0x83, 0xE0, 0xF5, - 0x32, 0xEE, 0x44, 0xA8, 0xFE, 0xEF, 0x44, 0x07, -/*1AA0*/0xF5, 0x82, 0x8E, 0x83, 0xE0, 0xF5, 0x33, 0x22, - 0x01, 0x20, 0x11, 0x00, 0x04, 0x20, 0x00, 0x90, -/*1AB0*/0x00, 0x20, 0x0F, 0x92, 0x00, 0x21, 0x0F, 0x94, - 0x00, 0x22, 0x0F, 0x96, 0x00, 0x23, 0x0F, 0x98, -/*1AC0*/0x00, 0x24, 0x0F, 0x9A, 0x00, 0x25, 0x0F, 0x9C, - 0x00, 0x26, 0x0F, 0x9E, 0x00, 0x27, 0x0F, 0xA0, -/*1AD0*/0x01, 0x20, 0x01, 0xA2, 0x01, 0x21, 0x01, 0xA4, - 0x01, 0x22, 0x01, 0xA6, 0x01, 0x23, 0x01, 0xA8, -/*1AE0*/0x01, 0x24, 0x01, 0xAA, 0x01, 0x25, 0x01, 0xAC, - 0x01, 0x26, 0x01, 0xAE, 0x01, 0x27, 0x01, 0xB0, -/*1AF0*/0x01, 0x28, 0x01, 0xB4, 0x00, 0x28, 0x0F, 0xB6, - 0x40, 0x28, 0x0F, 0xB8, 0x61, 0x28, 0x01, 0xCB, -/*1B00*/0xEF, 0xCB, 0xCA, 0xEE, 0xCA, 0x7F, 0x01, 0xE4, - 0xFD, 0xEB, 0x4A, 0x70, 0x24, 0xE5, 0x08, 0xF5, -/*1B10*/0x82, 0x74, 0xB6, 0x12, 0x08, 0x29, 0xE5, 0x08, - 0xF5, 0x82, 0x74, 0xB8, 0x12, 0x08, 0x29, 0xE5, -/*1B20*/0x08, 0xF5, 0x82, 0x74, 0xBA, 0x12, 0x08, 0x29, - 0x7E, 0x00, 0x7C, 0x00, 0x12, 0x0A, 0xFF, 0x80, -/*1B30*/0x12, 0x90, 0x07, 0x26, 0x12, 0x07, 0x35, 0xE5, - 0x41, 0xF0, 0x90, 0x07, 0x24, 0x12, 0x07, 0x35, -/*1B40*/0xE5, 0x40, 0xF0, 0x12, 0x07, 0x2A, 0x75, 0x83, - 0x8E, 0xE4, 0x12, 0x07, 0x29, 0x74, 0x01, 0x12, -/*1B50*/0x07, 0x29, 0xE4, 0xF0, 0x22, 0xE4, 0xF5, 0x26, - 0xF5, 0x27, 0x53, 0xE1, 0xFE, 0xF5, 0x2A, 0x75, -/*1B60*/0x2B, 0x01, 0xF5, 0x08, 0x7F, 0x01, 0x12, 0x17, - 0x31, 0x30, 0x30, 0x1C, 0x90, 0x1A, 0xA9, 0xE4, -/*1B70*/0x93, 0xF5, 0x10, 0x90, 0x1F, 0xF9, 0xE4, 0x93, - 0xF5, 0x10, 0x90, 0x00, 0x41, 0xE4, 0x93, 0xF5, -/*1B80*/0x10, 0x90, 0x1E, 0xCA, 0xE4, 0x93, 0xF5, 0x10, - 0x7F, 0x02, 0x12, 0x17, 0x31, 0x12, 0x0F, 0x54, -/*1B90*/0x7F, 0x03, 0x12, 0x17, 0x31, 0x12, 0x00, 0x06, - 0xE5, 0xE2, 0x30, 0xE7, 0x09, 0x12, 0x10, 0x00, -/*1BA0*/0x30, 0x30, 0x03, 0x12, 0x11, 0x00, 0x02, 0x00, - 0x47, 0x12, 0x08, 0x1F, 0x75, 0x83, 0xD0, 0xE0, -/*1BB0*/0xC4, 0x54, 0x0F, 0xFD, 0x75, 0x43, 0x01, 0x75, - 0x44, 0xFF, 0x12, 0x08, 0xAA, 0x74, 0x04, 0xF0, -/*1BC0*/0x75, 0x3B, 0x01, 0xED, 0x14, 0x60, 0x0C, 0x14, - 0x60, 0x0B, 0x14, 0x60, 0x0F, 0x24, 0x03, 0x70, -/*1BD0*/0x0B, 0x80, 0x09, 0x80, 0x00, 0x12, 0x08, 0xA7, - 0x04, 0xF0, 0x80, 0x06, 0x12, 0x08, 0xA7, 0x74, -/*1BE0*/0x04, 0xF0, 0xEE, 0x44, 0x82, 0xFE, 0xEF, 0x44, - 0x07, 0xF5, 0x82, 0x8E, 0x83, 0xE5, 0x45, 0x12, -/*1BF0*/0x08, 0xBE, 0x75, 0x83, 0x82, 0xE5, 0x31, 0xF0, - 0x02, 0x11, 0x4C, 0x8E, 0x60, 0x8F, 0x61, 0x12, -/*1C00*/0x1E, 0xA5, 0xE4, 0xFF, 0xCE, 0xED, 0xCE, 0xEE, - 0xD3, 0x95, 0x61, 0xE5, 0x60, 0x12, 0x07, 0x6B, -/*1C10*/0x40, 0x39, 0x74, 0x20, 0x2E, 0xF5, 0x82, 0xE4, - 0x34, 0x03, 0xF5, 0x83, 0xE0, 0x70, 0x03, 0xFF, -/*1C20*/0x80, 0x26, 0x12, 0x08, 0xE2, 0xFD, 0xC3, 0x9F, - 0x40, 0x1E, 0xCF, 0xED, 0xCF, 0xEB, 0x4A, 0x70, -/*1C30*/0x0B, 0x8D, 0x42, 0x12, 0x08, 0xEE, 0xF5, 0x41, - 0x8E, 0x40, 0x80, 0x0C, 0x12, 0x08, 0xE2, 0xF5, -/*1C40*/0x38, 0x12, 0x08, 0xEE, 0xF5, 0x39, 0x8E, 0x3A, - 0x1E, 0x80, 0xBC, 0x22, 0x75, 0x58, 0x01, 0xE5, -/*1C50*/0x35, 0x70, 0x0C, 0x12, 0x07, 0xCC, 0xE0, 0xF5, - 0x4A, 0x12, 0x07, 0xD8, 0xE0, 0xF5, 0x4C, 0xE5, -/*1C60*/0x35, 0xB4, 0x04, 0x0C, 0x12, 0x07, 0xE4, 0xE0, - 0xF5, 0x4A, 0x12, 0x07, 0xF0, 0xE0, 0xF5, 0x4C, -/*1C70*/0xE5, 0x35, 0xB4, 0x01, 0x04, 0x7F, 0x01, 0x80, - 0x02, 0x7F, 0x00, 0xE5, 0x35, 0xB4, 0x02, 0x04, -/*1C80*/0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE, 0x4F, - 0x60, 0x0C, 0x12, 0x07, 0xFC, 0xE0, 0xF5, 0x4A, -/*1C90*/0x12, 0x08, 0x08, 0xE0, 0xF5, 0x4C, 0x85, 0x41, - 0x49, 0x85, 0x40, 0x4B, 0x22, 0x75, 0x5B, 0x01, -/*1CA0*/0x90, 0x07, 0x24, 0x12, 0x07, 0x35, 0xE0, 0x54, - 0x1F, 0xFF, 0xD3, 0x94, 0x02, 0x50, 0x04, 0x8F, -/*1CB0*/0x58, 0x80, 0x05, 0xEF, 0x24, 0xFE, 0xF5, 0x58, - 0xEF, 0xC3, 0x94, 0x18, 0x40, 0x05, 0x75, 0x59, -/*1CC0*/0x18, 0x80, 0x04, 0xEF, 0x04, 0xF5, 0x59, 0x85, - 0x43, 0x5A, 0xAF, 0x58, 0x7E, 0x00, 0xAD, 0x59, -/*1CD0*/0x7C, 0x00, 0xAB, 0x5B, 0x7A, 0x00, 0x12, 0x15, - 0x41, 0xAF, 0x5A, 0x7E, 0x00, 0x12, 0x18, 0x0A, -/*1CE0*/0xAF, 0x5B, 0x7E, 0x00, 0x02, 0x1A, 0xFF, 0xE5, - 0xE2, 0x30, 0xE7, 0x0E, 0x12, 0x10, 0x03, 0xC2, -/*1CF0*/0x30, 0x30, 0x30, 0x03, 0x12, 0x10, 0xFF, 0x20, - 0x33, 0x28, 0xE5, 0xE7, 0x30, 0xE7, 0x05, 0x12, -/*1D00*/0x0E, 0xA2, 0x80, 0x0D, 0xE5, 0xFE, 0xC3, 0x94, - 0x20, 0x50, 0x06, 0x12, 0x0E, 0xA2, 0x43, 0xF9, -/*1D10*/0x08, 0xE5, 0xF2, 0x30, 0xE7, 0x03, 0x53, 0xF9, - 0x7F, 0xE5, 0xF1, 0x54, 0x70, 0xD3, 0x94, 0x00, -/*1D20*/0x50, 0xD8, 0x22, 0x12, 0x0E, 0x04, 0x75, 0x83, - 0x80, 0xE4, 0xF0, 0xE5, 0x08, 0x44, 0x07, 0x12, -/*1D30*/0x0D, 0xFD, 0x75, 0x83, 0x84, 0x12, 0x0E, 0x02, - 0x75, 0x83, 0x86, 0x12, 0x0E, 0x02, 0x75, 0x83, -/*1D40*/0x8C, 0xE0, 0x54, 0xF3, 0x12, 0x0E, 0x03, 0x75, - 0x83, 0x8E, 0x12, 0x0E, 0x02, 0x75, 0x83, 0x94, -/*1D50*/0xE0, 0x54, 0xFB, 0xF0, 0x22, 0x12, 0x07, 0x2A, - 0x75, 0x83, 0x8E, 0xE4, 0x12, 0x07, 0x29, 0x74, -/*1D60*/0x01, 0x12, 0x07, 0x29, 0xE4, 0x12, 0x08, 0xBE, - 0x75, 0x83, 0x8C, 0xE0, 0x44, 0x20, 0x12, 0x08, -/*1D70*/0xBE, 0xE0, 0x54, 0xDF, 0xF0, 0x74, 0x84, 0x85, - 0x08, 0x82, 0xF5, 0x83, 0xE0, 0x54, 0x7F, 0xF0, -/*1D80*/0xE0, 0x44, 0x80, 0xF0, 0x22, 0x75, 0x56, 0x01, - 0xE4, 0xFD, 0xF5, 0x57, 0xAF, 0x35, 0xFE, 0xFC, -/*1D90*/0x12, 0x09, 0x15, 0x12, 0x1C, 0x9D, 0x12, 0x1E, - 0x7A, 0x12, 0x1C, 0x4C, 0xAF, 0x57, 0x7E, 0x00, -/*1DA0*/0xAD, 0x56, 0x7C, 0x00, 0x12, 0x04, 0x44, 0xAF, - 0x56, 0x7E, 0x00, 0x02, 0x11, 0xEE, 0x75, 0x56, -/*1DB0*/0x01, 0xE4, 0xFD, 0xF5, 0x57, 0xAF, 0x35, 0xFE, - 0xFC, 0x12, 0x09, 0x15, 0x12, 0x1C, 0x9D, 0x12, -/*1DC0*/0x1E, 0x7A, 0x12, 0x1C, 0x4C, 0xAF, 0x57, 0x7E, - 0x00, 0xAD, 0x56, 0x7C, 0x00, 0x12, 0x04, 0x44, -/*1DD0*/0xAF, 0x56, 0x7E, 0x00, 0x02, 0x11, 0xEE, 0xE4, - 0xF5, 0x16, 0x12, 0x0E, 0x44, 0xFE, 0xE5, 0x08, -/*1DE0*/0x44, 0x05, 0xFF, 0x12, 0x0E, 0x65, 0x8F, 0x82, - 0x8E, 0x83, 0xF0, 0x05, 0x16, 0xE5, 0x16, 0xC3, -/*1DF0*/0x94, 0x14, 0x40, 0xE6, 0xE5, 0x08, 0x12, 0x0E, - 0x2B, 0xE4, 0xF0, 0x22, 0xE4, 0xF5, 0x58, 0xF5, -/*1E00*/0x59, 0xF5, 0x5A, 0xFF, 0xFE, 0xAD, 0x58, 0xFC, - 0x12, 0x09, 0x15, 0x7F, 0x04, 0x7E, 0x00, 0xAD, -/*1E10*/0x58, 0x7C, 0x00, 0x12, 0x09, 0x15, 0x7F, 0x02, - 0x7E, 0x00, 0xAD, 0x58, 0x7C, 0x00, 0x02, 0x09, -/*1E20*/0x15, 0xE5, 0x3C, 0x25, 0x3E, 0xFC, 0xE5, 0x42, - 0x24, 0x00, 0xFB, 0xE4, 0x33, 0xFA, 0xEC, 0xC3, -/*1E30*/0x9B, 0xEA, 0x12, 0x07, 0x6B, 0x40, 0x0B, 0x8C, - 0x42, 0xE5, 0x3D, 0x25, 0x3F, 0xF5, 0x41, 0x8F, -/*1E40*/0x40, 0x22, 0x12, 0x09, 0x0B, 0x22, 0x74, 0x84, - 0xF5, 0x18, 0x85, 0x08, 0x19, 0x85, 0x19, 0x82, -/*1E50*/0x85, 0x18, 0x83, 0xE0, 0x54, 0x7F, 0xF0, 0xE0, - 0x44, 0x80, 0xF0, 0xE0, 0x44, 0x80, 0xF0, 0x22, -/*1E60*/0xEF, 0x4E, 0x70, 0x0B, 0x12, 0x07, 0x2A, 0x75, - 0x83, 0xD2, 0xE0, 0x54, 0xDF, 0xF0, 0x22, 0x12, -/*1E70*/0x07, 0x2A, 0x75, 0x83, 0xD2, 0xE0, 0x44, 0x20, - 0xF0, 0x22, 0x75, 0x58, 0x01, 0x90, 0x07, 0x26, -/*1E80*/0x12, 0x07, 0x35, 0xE0, 0x54, 0x3F, 0xF5, 0x41, - 0x12, 0x07, 0x32, 0xE0, 0x54, 0x3F, 0xF5, 0x40, -/*1E90*/0x22, 0x75, 0x56, 0x02, 0xE4, 0xF5, 0x57, 0x12, - 0x1D, 0xFC, 0xAF, 0x57, 0x7E, 0x00, 0xAD, 0x56, -/*1EA0*/0x7C, 0x00, 0x02, 0x04, 0x44, 0xE4, 0xF5, 0x42, - 0xF5, 0x41, 0xF5, 0x40, 0xF5, 0x38, 0xF5, 0x39, -/*1EB0*/0xF5, 0x3A, 0x22, 0xEF, 0x54, 0x07, 0xFF, 0xE5, - 0xF9, 0x54, 0xF8, 0x4F, 0xF5, 0xF9, 0x22, 0x7F, -/*1EC0*/0x01, 0xE4, 0xFE, 0x0F, 0x0E, 0xBE, 0xFF, 0xFB, - 0x22, 0x01, 0x20, 0x00, 0x01, 0x04, 0x20, 0x00, -/*1ED0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/*1EE0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/*1EF0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/*1F00*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/*1F10*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/*1F20*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/*1F30*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/*1F40*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/*1F50*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/*1F60*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/*1F70*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/*1F80*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/*1F90*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/*1FA0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/*1FB0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/*1FC0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/*1FD0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/*1FE0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -/*1FF0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x20, 0x11, 0x00, 0x04, 0x20, 0x00, 0x81 -}; - -int ipath_sd7220_ib_load(struct ipath_devdata *dd) -{ - return ipath_sd7220_prog_ld(dd, IB_7220_SERDES, ipath_sd7220_ib_img, - sizeof(ipath_sd7220_ib_img), 0); -} - -int ipath_sd7220_ib_vfy(struct ipath_devdata *dd) -{ - return ipath_sd7220_prog_vfy(dd, IB_7220_SERDES, ipath_sd7220_ib_img, - sizeof(ipath_sd7220_ib_img), 0); -} -- cgit v1.2.3 From 6fc7f5730b71916bc44389015d404f668674c64c Mon Sep 17 00:00:00 2001 From: Scott Feldman Date: Sat, 22 May 2010 17:29:52 +0000 Subject: enic: bug fix: sprintf UUID to string as u8[] rather than u16[] array Signed-off-by: Scott Feldman Signed-off-by: David S. Miller --- drivers/net/enic/enic_main.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index e125113759a5..7e973237bf98 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1034,9 +1034,10 @@ static int enic_set_port_profile(struct enic *enic, u8 request, u8 *mac, { struct vic_provinfo *vp; u8 oui[3] = VIC_PROVINFO_CISCO_OUI; - unsigned short *uuid; + u8 *uuid; char uuid_str[38]; - static char *uuid_fmt = "%04X%04X-%04X-%04X-%04X-%04X%04X%04X"; + static char *uuid_fmt = "%02X%02X%02X%02X-%02X%02X-%02X%02X-" + "%02X%02X-%02X%02X%02X%02X%0X%02X"; int err; if (!name) @@ -1058,20 +1059,24 @@ static int enic_set_port_profile(struct enic *enic, u8 request, u8 *mac, ETH_ALEN, mac); if (instance_uuid) { - uuid = (unsigned short *)instance_uuid; + uuid = instance_uuid; sprintf(uuid_str, uuid_fmt, - uuid[0], uuid[1], uuid[2], uuid[3], - uuid[4], uuid[5], uuid[6], uuid[7]); + uuid[0], uuid[1], uuid[2], uuid[3], + uuid[4], uuid[5], uuid[6], uuid[7], + uuid[8], uuid[9], uuid[10], uuid[11], + uuid[12], uuid[13], uuid[14], uuid[15]); vic_provinfo_add_tlv(vp, VIC_LINUX_PROV_TLV_CLIENT_UUID_STR, sizeof(uuid_str), uuid_str); } if (host_uuid) { - uuid = (unsigned short *)host_uuid; + uuid = host_uuid; sprintf(uuid_str, uuid_fmt, - uuid[0], uuid[1], uuid[2], uuid[3], - uuid[4], uuid[5], uuid[6], uuid[7]); + uuid[0], uuid[1], uuid[2], uuid[3], + uuid[4], uuid[5], uuid[6], uuid[7], + uuid[8], uuid[9], uuid[10], uuid[11], + uuid[12], uuid[13], uuid[14], uuid[15]); vic_provinfo_add_tlv(vp, VIC_LINUX_PROV_TLV_HOST_UUID_STR, sizeof(uuid_str), uuid_str); -- cgit v1.2.3 From 418c437d8b4b87815f3afed89da2aa0078d5379d Mon Sep 17 00:00:00 2001 From: Scott Feldman Date: Sat, 22 May 2010 17:29:58 +0000 Subject: enic: Use random mac addr when associating port-profile Use random mac addr for interface when associating port-profile to dynamic enic device, in the case no mac addr was previous assigned. Signed-off-by: Scott Feldman Signed-off-by: David S. Miller --- drivers/net/enic/enic_main.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 7e973237bf98..6586b5c7e4b6 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1132,6 +1132,14 @@ static int enic_set_vf_port(struct net_device *netdev, int vf, switch (request) { case PORT_REQUEST_ASSOCIATE: + /* If the interface mac addr hasn't been assigned, + * assign a random mac addr before setting port- + * profile. + */ + + if (is_zero_ether_addr(netdev->dev_addr)) + random_ether_addr(netdev->dev_addr); + if (port[IFLA_PORT_PROFILE]) name = nla_data(port[IFLA_PORT_PROFILE]); -- cgit v1.2.3 From ee02a4ef40f2e049c80f9cc04e21a9b48288b6ff Mon Sep 17 00:00:00 2001 From: Thomas Chou Date: Sun, 23 May 2010 16:44:02 +0000 Subject: ethoc: fix null dereference in ethoc_probe Dan reported the patch 0baa080c75c: "ethoc: use system memory as buffer" introduced a potential null dereference. 1060 free: 1061 if (priv->dma_alloc) ^^^^^^^^^^^^^^^ priv can be null here. He also suggested that the error handling is not complete. This patch fixes the null priv issue and improves resources releasing in ethoc_probe() and ethoc_remove(). Reported-by: Dan Carpenter Signed-off-by: Thomas Chou Signed-off-by: David S. Miller --- drivers/net/ethoc.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index 14cbde5cf68e..6ed2df14ec84 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -174,6 +174,7 @@ MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size"); * @iobase: pointer to I/O memory region * @membase: pointer to buffer memory region * @dma_alloc: dma allocated buffer size + * @io_region_size: I/O memory region size * @num_tx: number of send buffers * @cur_tx: last send buffer written * @dty_tx: last buffer actually sent @@ -193,6 +194,7 @@ struct ethoc { void __iomem *iobase; void __iomem *membase; int dma_alloc; + resource_size_t io_region_size; unsigned int num_tx; unsigned int cur_tx; @@ -943,6 +945,7 @@ static int ethoc_probe(struct platform_device *pdev) priv = netdev_priv(netdev); priv->netdev = netdev; priv->dma_alloc = 0; + priv->io_region_size = mmio->end - mmio->start + 1; priv->iobase = devm_ioremap_nocache(&pdev->dev, netdev->base_addr, resource_size(mmio)); @@ -1047,20 +1050,34 @@ static int ethoc_probe(struct platform_device *pdev) ret = register_netdev(netdev); if (ret < 0) { dev_err(&netdev->dev, "failed to register interface\n"); - goto error; + goto error2; } goto out; +error2: + netif_napi_del(&priv->napi); error: mdiobus_unregister(priv->mdio); free_mdio: kfree(priv->mdio->irq); mdiobus_free(priv->mdio); free: - if (priv->dma_alloc) - dma_free_coherent(NULL, priv->dma_alloc, priv->membase, - netdev->mem_start); + if (priv) { + if (priv->dma_alloc) + dma_free_coherent(NULL, priv->dma_alloc, priv->membase, + netdev->mem_start); + else if (priv->membase) + devm_iounmap(&pdev->dev, priv->membase); + if (priv->iobase) + devm_iounmap(&pdev->dev, priv->iobase); + } + if (mem) + devm_release_mem_region(&pdev->dev, mem->start, + mem->end - mem->start + 1); + if (mmio) + devm_release_mem_region(&pdev->dev, mmio->start, + mmio->end - mmio->start + 1); free_netdev(netdev); out: return ret; @@ -1078,6 +1095,7 @@ static int ethoc_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); if (netdev) { + netif_napi_del(&priv->napi); phy_disconnect(priv->phy); priv->phy = NULL; @@ -1089,6 +1107,14 @@ static int ethoc_remove(struct platform_device *pdev) if (priv->dma_alloc) dma_free_coherent(NULL, priv->dma_alloc, priv->membase, netdev->mem_start); + else { + devm_iounmap(&pdev->dev, priv->membase); + devm_release_mem_region(&pdev->dev, netdev->mem_start, + netdev->mem_end - netdev->mem_start + 1); + } + devm_iounmap(&pdev->dev, priv->iobase); + devm_release_mem_region(&pdev->dev, netdev->base_addr, + priv->io_region_size); unregister_netdev(netdev); free_netdev(netdev); } -- cgit v1.2.3 From 7f267de41fde594500cbbccb1b29acb4475f2da2 Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Tue, 18 May 2010 01:34:46 +0000 Subject: bfin_mac: fix memleak in mii_bus{probe|remove} Fix memory leak with miibus->irq Signed-off-by: Denis Kirjanov Signed-off-by: David S. Miller --- drivers/net/bfin_mac.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index 39a54bad397f..368f33313fb6 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c @@ -1626,6 +1626,7 @@ static int __devinit bfin_mii_bus_probe(struct platform_device *pdev) return 0; out_err_mdiobus_register: + kfree(miibus->irq); mdiobus_free(miibus); out_err_alloc: peripheral_free_list(pin_req); @@ -1638,6 +1639,7 @@ static int __devexit bfin_mii_bus_remove(struct platform_device *pdev) struct mii_bus *miibus = platform_get_drvdata(pdev); platform_set_drvdata(pdev, NULL); mdiobus_unregister(miibus); + kfree(miibus->irq); mdiobus_free(miibus); peripheral_free_list(pin_req); return 0; -- cgit v1.2.3 From a5e93151e4390e4d27bee27ddb73f78f58260594 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 22 May 2010 10:27:48 +0000 Subject: pppoe: uninitialized variable in pppoe_flush_dev() This assignment got deleted along with the checks by mistake. This comes from: 8753d29fd "pppoe: remove unnecessary checks in pppoe_flush_dev" Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/pppoe.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index b1b93ff2351f..805b64d1e893 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -289,6 +289,7 @@ static void pppoe_flush_dev(struct net_device *dev) struct pppoe_net *pn; int i; + pn = pppoe_pernet(dev_net(dev)); write_lock_bh(&pn->hash_lock); for (i = 0; i < PPPOE_HASH_SIZE; i++) { struct pppox_sock *po = pn->hash_table[i]; -- cgit v1.2.3 From 85a83560afa69862639fb2d6f670b4440a003335 Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Sun, 23 May 2010 01:02:08 +0000 Subject: isdn/capi: make reset_ctr op truly optional The CAPI controller operation reset_ctr is marked as optional, and not all drivers do implement it. Add a check to the kernel CAPI whether it exists before trying to call it. Signed-off-by: Tilman Schmidt Acked-by: Karsten Keil Signed-off-by: David S. Miller --- drivers/isdn/capi/kcapi.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c index bd00dceacaf0..bde3c88b8b27 100644 --- a/drivers/isdn/capi/kcapi.c +++ b/drivers/isdn/capi/kcapi.c @@ -1147,6 +1147,12 @@ load_unlock_out: if (ctr->state == CAPI_CTR_DETECTED) goto reset_unlock_out; + if (ctr->reset_ctr == NULL) { + printk(KERN_DEBUG "kcapi: reset: no reset function\n"); + retval = -ESRCH; + goto reset_unlock_out; + } + ctr->reset_ctr(ctr); retval = wait_on_ctr_state(ctr, CAPI_CTR_DETECTED); -- cgit v1.2.3 From e487639dc8ca6bd6c19a4140f45ebc88da56ddd5 Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Sun, 23 May 2010 01:02:38 +0000 Subject: isdn/gigaset: remove dummy CAPI method implementations Dummy implementations for the optional CAPI controller operations load_firmware and reset_ctr can cause userspace callers to hang indefinitely. It's better not to implement them at all. Signed-off-by: Tilman Schmidt Acked-by: Karsten Keil Signed-off-by: David S. Miller --- drivers/isdn/gigaset/capi.c | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c index 964a55fb1486..e72f86bccaa5 100644 --- a/drivers/isdn/gigaset/capi.c +++ b/drivers/isdn/gigaset/capi.c @@ -932,30 +932,6 @@ void gigaset_isdn_stop(struct cardstate *cs) * ============================ */ -/* - * load firmware - */ -static int gigaset_load_firmware(struct capi_ctr *ctr, capiloaddata *data) -{ - struct cardstate *cs = ctr->driverdata; - - /* AVM specific operation, not needed for Gigaset -- ignore */ - dev_notice(cs->dev, "load_firmware ignored\n"); - - return 0; -} - -/* - * reset (deactivate) controller - */ -static void gigaset_reset_ctr(struct capi_ctr *ctr) -{ - struct cardstate *cs = ctr->driverdata; - - /* AVM specific operation, not needed for Gigaset -- ignore */ - dev_notice(cs->dev, "reset_ctr ignored\n"); -} - /* * register CAPI application */ @@ -2213,8 +2189,8 @@ int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid) iif->ctr.driverdata = cs; strncpy(iif->ctr.name, isdnid, sizeof(iif->ctr.name)); iif->ctr.driver_name = "gigaset"; - iif->ctr.load_firmware = gigaset_load_firmware; - iif->ctr.reset_ctr = gigaset_reset_ctr; + iif->ctr.load_firmware = NULL; + iif->ctr.reset_ctr = NULL; iif->ctr.register_appl = gigaset_register_appl; iif->ctr.release_appl = gigaset_release_appl; iif->ctr.send_message = gigaset_send_message; -- cgit v1.2.3 From eda6e6f86b5f95b982ac7ebf7cf5be2a29a291e9 Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Sat, 22 May 2010 22:00:10 +0000 Subject: net/irda: bfin_sir: IRDA is not affected by anomaly 05000230 Anomaly 05000230 (over sampling of the UART STOP bit) applies only when the peripheral is operating in UART mode. So drop the anomaly handling in the IRDA code. Signed-off-by: Graf Yang Signed-off-by: Mike Frysinger Signed-off-by: David S. Miller --- drivers/net/irda/bfin_sir.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/irda/bfin_sir.c b/drivers/net/irda/bfin_sir.c index 911c082cee5a..f940dfa1f7f8 100644 --- a/drivers/net/irda/bfin_sir.c +++ b/drivers/net/irda/bfin_sir.c @@ -107,8 +107,12 @@ static int bfin_sir_set_speed(struct bfin_sir_port *port, int speed) case 57600: case 115200: - quot = (port->clk + (8 * speed)) / (16 * speed)\ - - ANOMALY_05000230; + /* + * IRDA is not affected by anomaly 05000230, so there is no + * need to tweak the divisor like he UART driver (which will + * slightly speed up the baud rate on us). + */ + quot = (port->clk + (8 * speed)) / (16 * speed); do { udelay(utime); -- cgit v1.2.3 From 8286274284e15b11b0f531b6ceeef21fbe00a8dd Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 24 May 2010 00:14:10 -0700 Subject: tun: Update classid on packet injection This patch makes tun update its socket classid every time we inject a packet into the network stack. This is so that any updates made by the admin to the process writing packets to tun is effected. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- drivers/net/tun.c | 2 ++ net/core/sock.c | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 97b25533e5fb..8793c2bf7f15 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -526,6 +526,8 @@ static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun, struct sk_buff *skb; int err; + sock_update_classid(sk); + /* Under a page? Don't bother with paged skb. */ if (prepad + len < PAGE_SIZE || !linear) linear = len; diff --git a/net/core/sock.c b/net/core/sock.c index a05ae7f9771e..37fe9b6adade 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1064,6 +1064,7 @@ void sock_update_classid(struct sock *sk) if (classid && classid != sk->sk_classid) sk->sk_classid = classid; } +EXPORT_SYMBOL(sock_update_classid); #endif /** -- cgit v1.2.3 From 5eb32bd059379530fc3809a7fcf183feca75f601 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Mon, 24 May 2010 00:36:13 -0700 Subject: fec: add support for PHY interface platform data The i.MX25 PDK uses RMII to communicate with its PHY. This patch adds the ability to configure RMII, based on platform data. Signed-off-by: Baruch Siach Acked-by: Greg Ungerer Signed-off-by: David S. Miller --- drivers/net/fec.c | 22 ++++++++++++++++++++++ drivers/net/fec.h | 2 ++ include/linux/fec.h | 21 +++++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 include/linux/fec.h (limited to 'drivers') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 42d9ac9ba395..326465ffbb23 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -41,6 +41,7 @@ #include #include #include +#include #include @@ -182,6 +183,7 @@ struct fec_enet_private { struct phy_device *phy_dev; int mii_timeout; uint phy_speed; + phy_interface_t phy_interface; int index; int link; int full_duplex; @@ -1191,6 +1193,21 @@ fec_restart(struct net_device *dev, int duplex) /* Set MII speed */ writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); +#ifdef FEC_MIIGSK_ENR + if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) { + /* disable the gasket and wait */ + writel(0, fep->hwp + FEC_MIIGSK_ENR); + while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4) + udelay(1); + + /* configure the gasket: RMII, 50 MHz, no loopback, no echo */ + writel(1, fep->hwp + FEC_MIIGSK_CFGR); + + /* re-enable the gasket */ + writel(2, fep->hwp + FEC_MIIGSK_ENR); + } +#endif + /* And last, enable the transmit and receive processing */ writel(2, fep->hwp + FEC_ECNTRL); writel(0, fep->hwp + FEC_R_DES_ACTIVE); @@ -1226,6 +1243,7 @@ static int __devinit fec_probe(struct platform_device *pdev) { struct fec_enet_private *fep; + struct fec_platform_data *pdata; struct net_device *ndev; int i, irq, ret = 0; struct resource *r; @@ -1259,6 +1277,10 @@ fec_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ndev); + pdata = pdev->dev.platform_data; + if (pdata) + fep->phy_interface = pdata->phy; + /* This device has up to three irqs on some platforms */ for (i = 0; i < 3; i++) { irq = platform_get_irq(pdev, i); diff --git a/drivers/net/fec.h b/drivers/net/fec.h index cc47f3f057c7..2c48b25668d5 100644 --- a/drivers/net/fec.h +++ b/drivers/net/fec.h @@ -43,6 +43,8 @@ #define FEC_R_DES_START 0x180 /* Receive descriptor ring */ #define FEC_X_DES_START 0x184 /* Transmit descriptor ring */ #define FEC_R_BUFF_SIZE 0x188 /* Maximum receive buff size */ +#define FEC_MIIGSK_CFGR 0x300 /* MIIGSK Configuration reg */ +#define FEC_MIIGSK_ENR 0x308 /* MIIGSK Enable reg */ #else diff --git a/include/linux/fec.h b/include/linux/fec.h new file mode 100644 index 000000000000..5d3523d8dd0c --- /dev/null +++ b/include/linux/fec.h @@ -0,0 +1,21 @@ +/* include/linux/fec.h + * + * Copyright (c) 2009 Orex Computed Radiography + * Baruch Siach + * + * Header file for the FEC platform data + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __LINUX_FEC_H__ +#define __LINUX_FEC_H__ + +#include + +struct fec_platform_data { + phy_interface_t phy; +}; + +#endif -- cgit v1.2.3 From 5f2776293f7a4390f587642b1b7e1e6288e11a01 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 21 May 2010 16:15:32 +1000 Subject: HID: fix hid-roccat-kone for bin_attr API change After merging the driver-core tree, today's linux-next build (x86_64 allmodconfig) produced these warnings: drivers/hid/hid-roccat-kone.c:694: warning: initialization from incompatible pointer type drivers/hid/hid-roccat-kone.c:696: warning: initialization from incompatible pointer type drivers/hid/hid-roccat-kone.c:701: warning: initialization from incompatible pointer type drivers/hid/hid-roccat-kone.c:703: warning: initialization from incompatible pointer type drivers/hid/hid-roccat-kone.c:708: warning: initialization from incompatible pointer type drivers/hid/hid-roccat-kone.c:710: warning: initialization from incompatible pointer type drivers/hid/hid-roccat-kone.c:715: warning: initialization from incompatible pointer type drivers/hid/hid-roccat-kone.c:717: warning: initialization from incompatible pointer type drivers/hid/hid-roccat-kone.c:722: warning: initialization from incompatible pointer type drivers/hid/hid-roccat-kone.c:724: warning: initialization from incompatible pointer type drivers/hid/hid-roccat-kone.c:729: warning: initialization from incompatible pointer type drivers/hid/hid-roccat-kone.c:731: warning: initialization from incompatible pointer type Introduced by commit 867040163f10f2b52b45bc573f330d6eb28f5914 ("sysfs: add struct file* to bin_attr callbacks") from the driver-core tree interacting with commit 14bf62cde79423a02a590e02664ed29a36facec1 ("HID: add driver for Roccat Kone gaming mouse") from the hid tree. Signed-off-by: Stephen Rothwell Signed-off-by: Jiri Kosina --- drivers/hid/hid-roccat-kone.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c index 66e694054ba2..b6371d3fe0f9 100644 --- a/drivers/hid/hid-roccat-kone.c +++ b/drivers/hid/hid-roccat-kone.c @@ -263,7 +263,7 @@ static int kone_get_firmware_version(struct usb_device *usb_dev, int *result) return 0; } -static ssize_t kone_sysfs_read_settings(struct kobject *kobj, +static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); @@ -287,7 +287,7 @@ static ssize_t kone_sysfs_read_settings(struct kobject *kobj, * This function keeps values in kone_device up to date and assumes that in * case of error the old data is still valid */ -static ssize_t kone_sysfs_write_settings(struct kobject *kobj, +static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); @@ -342,31 +342,31 @@ static ssize_t kone_sysfs_read_profilex(struct kobject *kobj, return count; } -static ssize_t kone_sysfs_read_profile1(struct kobject *kobj, +static ssize_t kone_sysfs_read_profile1(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { return kone_sysfs_read_profilex(kobj, attr, buf, off, count, 1); } -static ssize_t kone_sysfs_read_profile2(struct kobject *kobj, +static ssize_t kone_sysfs_read_profile2(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { return kone_sysfs_read_profilex(kobj, attr, buf, off, count, 2); } -static ssize_t kone_sysfs_read_profile3(struct kobject *kobj, +static ssize_t kone_sysfs_read_profile3(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { return kone_sysfs_read_profilex(kobj, attr, buf, off, count, 3); } -static ssize_t kone_sysfs_read_profile4(struct kobject *kobj, +static ssize_t kone_sysfs_read_profile4(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { return kone_sysfs_read_profilex(kobj, attr, buf, off, count, 4); } -static ssize_t kone_sysfs_read_profile5(struct kobject *kobj, +static ssize_t kone_sysfs_read_profile5(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { return kone_sysfs_read_profilex(kobj, attr, buf, off, count, 5); @@ -404,31 +404,31 @@ static ssize_t kone_sysfs_write_profilex(struct kobject *kobj, return sizeof(struct kone_profile); } -static ssize_t kone_sysfs_write_profile1(struct kobject *kobj, +static ssize_t kone_sysfs_write_profile1(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { return kone_sysfs_write_profilex(kobj, attr, buf, off, count, 1); } -static ssize_t kone_sysfs_write_profile2(struct kobject *kobj, +static ssize_t kone_sysfs_write_profile2(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { return kone_sysfs_write_profilex(kobj, attr, buf, off, count, 2); } -static ssize_t kone_sysfs_write_profile3(struct kobject *kobj, +static ssize_t kone_sysfs_write_profile3(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { return kone_sysfs_write_profilex(kobj, attr, buf, off, count, 3); } -static ssize_t kone_sysfs_write_profile4(struct kobject *kobj, +static ssize_t kone_sysfs_write_profile4(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { return kone_sysfs_write_profilex(kobj, attr, buf, off, count, 4); } -static ssize_t kone_sysfs_write_profile5(struct kobject *kobj, +static ssize_t kone_sysfs_write_profile5(struct file *fp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { return kone_sysfs_write_profilex(kobj, attr, buf, off, count, 5); -- cgit v1.2.3 From 9f6aa5750de30b1ba35f6cb8de50c17b4fb59cab Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 23 May 2010 17:02:30 -0700 Subject: scsi_scan.c: fix/convert functions to use kernel-doc scsi_scan.c: fix incorrectly formatted kernel-doc notation & convert documentation of 2 functions into kernel-doc. Signed-off-by: Randy Dunlap Signed-off-by: Linus Torvalds --- drivers/scsi/scsi_scan.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index c992ecf4e372..9798c2c06b93 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1220,7 +1220,7 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget, } /** - * scsilun_to_int: convert a scsi_lun to an int + * scsilun_to_int - convert a scsi_lun to an int * @scsilun: struct scsi_lun to be converted. * * Description: @@ -1252,7 +1252,7 @@ int scsilun_to_int(struct scsi_lun *scsilun) EXPORT_SYMBOL(scsilun_to_int); /** - * int_to_scsilun: reverts an int into a scsi_lun + * int_to_scsilun - reverts an int into a scsi_lun * @lun: integer to be reverted * @scsilun: struct scsi_lun to be set. * @@ -1876,12 +1876,9 @@ void scsi_forget_host(struct Scsi_Host *shost) spin_unlock_irqrestore(shost->host_lock, flags); } -/* - * Function: scsi_get_host_dev() - * - * Purpose: Create a scsi_device that points to the host adapter itself. - * - * Arguments: SHpnt - Host that needs a scsi_device +/** + * scsi_get_host_dev - Create a scsi_device that points to the host adapter itself + * @shost: Host that needs a scsi_device * * Lock status: None assumed. * @@ -1894,7 +1891,7 @@ void scsi_forget_host(struct Scsi_Host *shost) * * Note - this device is not accessible from any high-level * drivers (including generics), which is probably not - * optimal. We can add hooks later to attach + * optimal. We can add hooks later to attach. */ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost) { @@ -1920,18 +1917,13 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost) } EXPORT_SYMBOL(scsi_get_host_dev); -/* - * Function: scsi_free_host_dev() - * - * Purpose: Free a scsi_device that points to the host adapter itself. - * - * Arguments: SHpnt - Host that needs a scsi_device +/** + * scsi_free_host_dev - Free a scsi_device that points to the host adapter itself + * @sdev: Host device to be freed * * Lock status: None assumed. * * Returns: Nothing - * - * Notes: */ void scsi_free_host_dev(struct scsi_device *sdev) { -- cgit v1.2.3 From 9b8f77a184fcc44349c547be944ba921fd4247b3 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 23 May 2010 17:02:30 -0700 Subject: fusion: fix kernel-doc notation The function name must be followed by a space, hypen, space, and a short description. Signed-off-by: Ben Hutchings Signed-off-by: Randy Dunlap Cc: Eric Moore Signed-off-by: Linus Torvalds --- drivers/message/fusion/mptscsih.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 7bd4c0fc23cc..5c53624e0e87 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -2570,9 +2570,7 @@ mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i) } /** - * mptscsih_set_scsi_lookup - * - * writes a scmd entry into the ScsiLookup[] array list + * mptscsih_set_scsi_lookup - write a scmd entry into the ScsiLookup[] array list * * @ioc: Pointer to MPT_ADAPTER structure * @i: index into the array @@ -2735,7 +2733,7 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, /** - * mptscsih_get_completion_code - + * mptscsih_get_completion_code - get completion code from MPT request * @ioc: Pointer to MPT_ADAPTER structure * @req: Pointer to original MPT request frame * @reply: Pointer to MPT reply frame (NULL if TurboReply) -- cgit v1.2.3 From a69eee4988752c7196677958b4ed8f4c2b28499a Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 24 May 2010 07:45:43 -0700 Subject: Revert "ath9k: Group Key fix for VAPs" This reverts commit 03ceedea972a82d343fa5c2528b3952fa9e615d5, since it breaks resume from suspend-to-ram on Rafael's Acer Ferrari One. NetworkManager thinks everything is ok, but it can't connect to the AP to get an IP address after the resume. In fact, it even breaks resume for non-ath9k chipsets: reverting it also fixes Rafael's Toshiba Protege R500 with the iwlagn driver. As Johannes says: "Indeed, this patch needs to be reverted. That mac80211 change is wrong and completely unnecessary." Reported-and-requested-by: Rafael J. Wysocki Acked-by: Johannes Berg Cc: Daniel Yingqiang Ma Cc: John W. Linville Cc: David Miller Signed-off-by: Linus Torvalds --- drivers/net/wireless/ath/ath9k/main.c | 28 +++------------------------- include/net/mac80211.h | 1 - net/mac80211/key.c | 1 - 3 files changed, 3 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 893b552981a0..abfa0493236f 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -752,7 +752,6 @@ static int ath_key_config(struct ath_common *common, struct ath_hw *ah = common->ah; struct ath9k_keyval hk; const u8 *mac = NULL; - u8 gmac[ETH_ALEN]; int ret = 0; int idx; @@ -776,30 +775,9 @@ static int ath_key_config(struct ath_common *common, memcpy(hk.kv_val, key->key, key->keylen); if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { - - if (key->ap_addr) { - /* - * Group keys on hardware that supports multicast frame - * key search use a mac that is the sender's address with - * the high bit set instead of the app-specified address. - */ - memcpy(gmac, key->ap_addr, ETH_ALEN); - gmac[0] |= 0x80; - mac = gmac; - - if (key->alg == ALG_TKIP) - idx = ath_reserve_key_cache_slot_tkip(common); - else - idx = ath_reserve_key_cache_slot(common); - if (idx < 0) - mac = NULL; /* no free key cache entries */ - } - - if (!mac) { - /* For now, use the default keys for broadcast keys. This may - * need to change with virtual interfaces. */ - idx = key->keyidx; - } + /* For now, use the default keys for broadcast keys. This may + * need to change with virtual interfaces. */ + idx = key->keyidx; } else if (key->keyidx) { if (WARN_ON(!sta)) return -EOPNOTSUPP; diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 5be900d19660..e24b0363e6cb 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -831,7 +831,6 @@ struct ieee80211_key_conf { u8 iv_len; u8 hw_key_idx; u8 flags; - u8 *ap_addr; s8 keyidx; u8 keylen; u8 key[0]; diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 8d4b41787dcf..e8f6e3b252d8 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -140,7 +140,6 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) struct ieee80211_sub_if_data, u.ap); - key->conf.ap_addr = sdata->dev->dev_addr; ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf); if (!ret) { -- cgit v1.2.3 From e6b50c30fa8d46c9401c2d48eee2351bdbb4c51c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 7 May 2010 10:53:45 +0200 Subject: [SCSI] be2iscsi: correct return value in mgmt_invalidate_icds() This function should return 0 on error. Returning -1 would cause a crash. Also there is an extra space before the newline character and a missing space between the "for" and the "mgmt_invalidate_icds". I put the string on one line. The current version of checkpatch.pl complains that the line is too long, but it makes grepping easier. Signed-off-by: Dan Carpenter Reviewed-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/be2iscsi/be_mgmt.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index e641922f20bc..350cbeaae160 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c @@ -167,10 +167,9 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, &nonemb_cmd.dma); if (nonemb_cmd.va == NULL) { SE_DEBUG(DBG_LVL_1, - "Failed to allocate memory for" - "mgmt_invalidate_icds \n"); + "Failed to allocate memory for mgmt_invalidate_icds\n"); spin_unlock(&ctrl->mbox_lock); - return -1; + return 0; } nonemb_cmd.size = sizeof(struct invalidate_commands_params_in); req = nonemb_cmd.va; -- cgit v1.2.3 From 438b03311108b05a7b794bcf3941700853c62d1e Mon Sep 17 00:00:00 2001 From: Wayne Boyer Date: Mon, 10 May 2010 09:13:00 -0700 Subject: [SCSI] ipr: implement fixes for 64 bit adapter support Implement some small fixes for 64 bit support that were preventing the adapter from becoming operational. Signed-off-by: Wayne Boyer Acked-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/ipr.c | 13 +++++++++---- drivers/scsi/ipr.h | 3 ++- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 6a6661c35b2f..735402f61aba 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -1040,7 +1040,7 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res, proto = cfgtew->u.cfgte64->proto; res->res_flags = cfgtew->u.cfgte64->res_flags; res->qmodel = IPR_QUEUEING_MODEL64(res); - res->type = cfgtew->u.cfgte64->res_type & 0x0f; + res->type = cfgtew->u.cfgte64->res_type; memcpy(res->res_path, &cfgtew->u.cfgte64->res_path, sizeof(res->res_path)); @@ -5014,6 +5014,8 @@ static int ipr_build_ioadl64(struct ipr_ioa_cfg *ioa_cfg, ipr_cmd->dma_use_sg = nseg; + ioarcb->data_transfer_length = cpu_to_be32(length); + if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) { ioadl_flags = IPR_IOADL_FLAGS_WRITE; ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; @@ -6706,7 +6708,7 @@ static int ipr_init_res_table(struct ipr_cmnd *ipr_cmd) list_move_tail(&res->queue, &old_res); if (ioa_cfg->sis64) - entries = ioa_cfg->u.cfg_table64->hdr64.num_entries; + entries = be16_to_cpu(ioa_cfg->u.cfg_table64->hdr64.num_entries); else entries = ioa_cfg->u.cfg_table->hdr.num_entries; @@ -6792,6 +6794,7 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd) ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); ioarcb->cmd_pkt.cdb[0] = IPR_QUERY_IOA_CONFIG; + ioarcb->cmd_pkt.cdb[6] = (ioa_cfg->cfg_table_size >> 16) & 0xff; ioarcb->cmd_pkt.cdb[7] = (ioa_cfg->cfg_table_size >> 8) & 0xff; ioarcb->cmd_pkt.cdb[8] = ioa_cfg->cfg_table_size & 0xff; @@ -7122,7 +7125,9 @@ static int ipr_reset_next_stage(struct ipr_cmnd *ipr_cmd) ipr_dbg("IPL stage = 0x%lx, IPL stage time = %ld\n", stage, stage_time); /* sanity check the stage_time value */ - if (stage_time < IPR_IPL_INIT_MIN_STAGE_TIME) + if (stage_time == 0) + stage_time = IPR_IPL_INIT_DEFAULT_STAGE_TIME; + else if (stage_time < IPR_IPL_INIT_MIN_STAGE_TIME) stage_time = IPR_IPL_INIT_MIN_STAGE_TIME; else if (stage_time > IPR_LONG_OPERATIONAL_TIMEOUT) stage_time = IPR_LONG_OPERATIONAL_TIMEOUT; @@ -7364,7 +7369,7 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd) } } - ENTER; + LEAVE; return IPR_RC_JOB_CONTINUE; } diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index 4c267b5e0b96..4e7f81494ea4 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -244,6 +244,7 @@ #define IPR_RUNTIME_RESET 0x40000000 #define IPR_IPL_INIT_MIN_STAGE_TIME 5 +#define IPR_IPL_INIT_DEFAULT_STAGE_TIME 15 #define IPR_IPL_INIT_STAGE_UNKNOWN 0x0 #define IPR_IPL_INIT_STAGE_TRANSOP 0xB0000000 #define IPR_IPL_INIT_STAGE_MASK 0xff000000 @@ -804,7 +805,7 @@ struct ipr_hostrcb_array_data_entry_enhanced { }__attribute__((packed, aligned (4))); struct ipr_hostrcb_type_ff_error { - __be32 ioa_data[502]; + __be32 ioa_data[758]; }__attribute__((packed, aligned (4))); struct ipr_hostrcb_type_01_error { -- cgit v1.2.3 From 96d21f00ab59c9f27fad191d12a2ccfeff3c9108 Mon Sep 17 00:00:00 2001 From: Wayne Boyer Date: Mon, 10 May 2010 09:13:27 -0700 Subject: [SCSI] ipr: include the resource path in the IOA status area structure The IOA status area now includes the new resource path field for 64 bit adapters. This patch changes the driver to fix the ioasa structure and to use the correct structure definition based on the type of adatper. Signed-off-by: Wayne Boyer Acked-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/ipr.c | 131 ++++++++++++++++++++++++++++++----------------------- drivers/scsi/ipr.h | 26 ++++++++++- 2 files changed, 98 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 735402f61aba..8c2f4c4041c1 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -567,7 +567,8 @@ static void ipr_trc_hook(struct ipr_cmnd *ipr_cmd, static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd) { struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; - struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; + struct ipr_ioasa *ioasa = &ipr_cmd->s.ioasa; + struct ipr_ioasa64 *ioasa64 = &ipr_cmd->s.ioasa64; dma_addr_t dma_addr = ipr_cmd->dma_addr; memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); @@ -576,19 +577,19 @@ static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd) ioarcb->ioadl_len = 0; ioarcb->read_ioadl_len = 0; - if (ipr_cmd->ioa_cfg->sis64) + if (ipr_cmd->ioa_cfg->sis64) { ioarcb->u.sis64_addr_data.data_ioadl_addr = cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64)); - else { + ioasa64->u.gata.status = 0; + } else { ioarcb->write_ioadl_addr = cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl)); ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; + ioasa->u.gata.status = 0; } - ioasa->ioasc = 0; - ioasa->residual_data_len = 0; - ioasa->u.gata.status = 0; - + ioasa->hdr.ioasc = 0; + ioasa->hdr.residual_data_len = 0; ipr_cmd->scsi_cmd = NULL; ipr_cmd->qc = NULL; ipr_cmd->sense_buffer[0] = 0; @@ -768,8 +769,8 @@ static void ipr_fail_all_ops(struct ipr_ioa_cfg *ioa_cfg) list_for_each_entry_safe(ipr_cmd, temp, &ioa_cfg->pending_q, queue) { list_del(&ipr_cmd->queue); - ipr_cmd->ioasa.ioasc = cpu_to_be32(IPR_IOASC_IOA_WAS_RESET); - ipr_cmd->ioasa.ilid = cpu_to_be32(IPR_DRIVER_ILID); + ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_IOA_WAS_RESET); + ipr_cmd->s.ioasa.hdr.ilid = cpu_to_be32(IPR_DRIVER_ILID); if (ipr_cmd->scsi_cmd) ipr_cmd->done = ipr_scsi_eh_done; @@ -1319,7 +1320,7 @@ static void ipr_process_ccn(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb; - u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); + u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); list_del(&hostrcb->queue); list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); @@ -2354,7 +2355,7 @@ static void ipr_process_error(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb; - u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); + u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); u32 fd_ioasc; if (ioa_cfg->sis64) @@ -4509,11 +4510,16 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg, } ipr_send_blocking_cmd(ipr_cmd, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT); - ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); + ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); - if (ipr_is_gata(res) && res->sata_port && ioasc != IPR_IOASC_IOA_WAS_RESET) - memcpy(&res->sata_port->ioasa, &ipr_cmd->ioasa.u.gata, - sizeof(struct ipr_ioasa_gata)); + if (ipr_is_gata(res) && res->sata_port && ioasc != IPR_IOASC_IOA_WAS_RESET) { + if (ipr_cmd->ioa_cfg->sis64) + memcpy(&res->sata_port->ioasa, &ipr_cmd->s.ioasa64.u.gata, + sizeof(struct ipr_ioasa_gata)); + else + memcpy(&res->sata_port->ioasa, &ipr_cmd->s.ioasa.u.gata, + sizeof(struct ipr_ioasa_gata)); + } LEAVE; return (IPR_IOASC_SENSE_KEY(ioasc) ? -EIO : 0); @@ -4768,7 +4774,7 @@ static int ipr_cancel_op(struct scsi_cmnd * scsi_cmd) scmd_printk(KERN_ERR, scsi_cmd, "Aborting command: %02X\n", scsi_cmd->cmnd[0]); ipr_send_blocking_cmd(ipr_cmd, ipr_abort_timeout, IPR_CANCEL_ALL_TIMEOUT); - ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); + ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); /* * If the abort task timed out and we sent a bus reset, we will get @@ -4940,7 +4946,7 @@ static irqreturn_t ipr_isr(int irq, void *devp) ipr_cmd = ioa_cfg->ipr_cmnd_list[cmd_index]; - ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); + ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); ipr_trc_hook(ipr_cmd, IPR_TRACE_FINISH, ioasc); @@ -5137,7 +5143,7 @@ static void ipr_erp_done(struct ipr_cmnd *ipr_cmd) struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; struct ipr_resource_entry *res = scsi_cmd->device->hostdata; struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; - u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); + u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); if (IPR_IOASC_SENSE_KEY(ioasc) > 0) { scsi_cmd->result |= (DID_ERROR << 16); @@ -5168,7 +5174,7 @@ static void ipr_erp_done(struct ipr_cmnd *ipr_cmd) static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd) { struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; - struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; + struct ipr_ioasa *ioasa = &ipr_cmd->s.ioasa; dma_addr_t dma_addr = ipr_cmd->dma_addr; memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); @@ -5176,8 +5182,8 @@ static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd) ioarcb->read_data_transfer_length = 0; ioarcb->ioadl_len = 0; ioarcb->read_ioadl_len = 0; - ioasa->ioasc = 0; - ioasa->residual_data_len = 0; + ioasa->hdr.ioasc = 0; + ioasa->hdr.residual_data_len = 0; if (ipr_cmd->ioa_cfg->sis64) ioarcb->u.sis64_addr_data.data_ioadl_addr = @@ -5202,7 +5208,7 @@ static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd) static void ipr_erp_request_sense(struct ipr_cmnd *ipr_cmd) { struct ipr_cmd_pkt *cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt; - u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); + u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); if (IPR_IOASC_SENSE_KEY(ioasc) > 0) { ipr_erp_done(ipr_cmd); @@ -5279,12 +5285,12 @@ static void ipr_dump_ioasa(struct ipr_ioa_cfg *ioa_cfg, int i; u16 data_len; u32 ioasc, fd_ioasc; - struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; + struct ipr_ioasa *ioasa = &ipr_cmd->s.ioasa; __be32 *ioasa_data = (__be32 *)ioasa; int error_index; - ioasc = be32_to_cpu(ioasa->ioasc) & IPR_IOASC_IOASC_MASK; - fd_ioasc = be32_to_cpu(ioasa->fd_ioasc) & IPR_IOASC_IOASC_MASK; + ioasc = be32_to_cpu(ioasa->hdr.ioasc) & IPR_IOASC_IOASC_MASK; + fd_ioasc = be32_to_cpu(ioasa->hdr.fd_ioasc) & IPR_IOASC_IOASC_MASK; if (0 == ioasc) return; @@ -5299,7 +5305,7 @@ static void ipr_dump_ioasa(struct ipr_ioa_cfg *ioa_cfg, if (ioa_cfg->log_level < IPR_MAX_LOG_LEVEL) { /* Don't log an error if the IOA already logged one */ - if (ioasa->ilid != 0) + if (ioasa->hdr.ilid != 0) return; if (!ipr_is_gscsi(res)) @@ -5311,10 +5317,11 @@ static void ipr_dump_ioasa(struct ipr_ioa_cfg *ioa_cfg, ipr_res_err(ioa_cfg, res, "%s\n", ipr_error_table[error_index].error); - if (sizeof(struct ipr_ioasa) < be16_to_cpu(ioasa->ret_stat_len)) + data_len = be16_to_cpu(ioasa->hdr.ret_stat_len); + if (ioa_cfg->sis64 && sizeof(struct ipr_ioasa64) < data_len) + data_len = sizeof(struct ipr_ioasa64); + else if (!ioa_cfg->sis64 && sizeof(struct ipr_ioasa) < data_len) data_len = sizeof(struct ipr_ioasa); - else - data_len = be16_to_cpu(ioasa->ret_stat_len); ipr_err("IOASA Dump:\n"); @@ -5340,8 +5347,8 @@ static void ipr_gen_sense(struct ipr_cmnd *ipr_cmd) u32 failing_lba; u8 *sense_buf = ipr_cmd->scsi_cmd->sense_buffer; struct ipr_resource_entry *res = ipr_cmd->scsi_cmd->device->hostdata; - struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; - u32 ioasc = be32_to_cpu(ioasa->ioasc); + struct ipr_ioasa *ioasa = &ipr_cmd->s.ioasa; + u32 ioasc = be32_to_cpu(ioasa->hdr.ioasc); memset(sense_buf, 0, SCSI_SENSE_BUFFERSIZE); @@ -5384,7 +5391,7 @@ static void ipr_gen_sense(struct ipr_cmnd *ipr_cmd) /* Illegal request */ if ((IPR_IOASC_SENSE_KEY(ioasc) == 0x05) && - (be32_to_cpu(ioasa->ioasc_specific) & IPR_FIELD_POINTER_VALID)) { + (be32_to_cpu(ioasa->hdr.ioasc_specific) & IPR_FIELD_POINTER_VALID)) { sense_buf[7] = 10; /* additional length */ /* IOARCB was in error */ @@ -5395,10 +5402,10 @@ static void ipr_gen_sense(struct ipr_cmnd *ipr_cmd) sense_buf[16] = ((IPR_FIELD_POINTER_MASK & - be32_to_cpu(ioasa->ioasc_specific)) >> 8) & 0xff; + be32_to_cpu(ioasa->hdr.ioasc_specific)) >> 8) & 0xff; sense_buf[17] = (IPR_FIELD_POINTER_MASK & - be32_to_cpu(ioasa->ioasc_specific)) & 0xff; + be32_to_cpu(ioasa->hdr.ioasc_specific)) & 0xff; } else { if (ioasc == IPR_IOASC_MED_DO_NOT_REALLOC) { if (ipr_is_vset_device(res)) @@ -5430,14 +5437,20 @@ static void ipr_gen_sense(struct ipr_cmnd *ipr_cmd) **/ static int ipr_get_autosense(struct ipr_cmnd *ipr_cmd) { - struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; + struct ipr_ioasa *ioasa = &ipr_cmd->s.ioasa; + struct ipr_ioasa64 *ioasa64 = &ipr_cmd->s.ioasa64; - if ((be32_to_cpu(ioasa->ioasc_specific) & IPR_AUTOSENSE_VALID) == 0) + if ((be32_to_cpu(ioasa->hdr.ioasc_specific) & IPR_AUTOSENSE_VALID) == 0) return 0; - memcpy(ipr_cmd->scsi_cmd->sense_buffer, ioasa->auto_sense.data, - min_t(u16, be16_to_cpu(ioasa->auto_sense.auto_sense_len), - SCSI_SENSE_BUFFERSIZE)); + if (ipr_cmd->ioa_cfg->sis64) + memcpy(ipr_cmd->scsi_cmd->sense_buffer, ioasa64->auto_sense.data, + min_t(u16, be16_to_cpu(ioasa64->auto_sense.auto_sense_len), + SCSI_SENSE_BUFFERSIZE)); + else + memcpy(ipr_cmd->scsi_cmd->sense_buffer, ioasa->auto_sense.data, + min_t(u16, be16_to_cpu(ioasa->auto_sense.auto_sense_len), + SCSI_SENSE_BUFFERSIZE)); return 1; } @@ -5457,7 +5470,7 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg, { struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; struct ipr_resource_entry *res = scsi_cmd->device->hostdata; - u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); + u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); u32 masked_ioasc = ioasc & IPR_IOASC_IOASC_MASK; if (!res) { @@ -5549,9 +5562,9 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; - u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); + u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); - scsi_set_resid(scsi_cmd, be32_to_cpu(ipr_cmd->ioasa.residual_data_len)); + scsi_set_resid(scsi_cmd, be32_to_cpu(ipr_cmd->s.ioasa.hdr.residual_data_len)); if (likely(IPR_IOASC_SENSE_KEY(ioasc) == 0)) { scsi_dma_unmap(ipr_cmd->scsi_cmd); @@ -5841,19 +5854,23 @@ static void ipr_sata_done(struct ipr_cmnd *ipr_cmd) struct ata_queued_cmd *qc = ipr_cmd->qc; struct ipr_sata_port *sata_port = qc->ap->private_data; struct ipr_resource_entry *res = sata_port->res; - u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); + u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); - memcpy(&sata_port->ioasa, &ipr_cmd->ioasa.u.gata, - sizeof(struct ipr_ioasa_gata)); + if (ipr_cmd->ioa_cfg->sis64) + memcpy(&sata_port->ioasa, &ipr_cmd->s.ioasa64.u.gata, + sizeof(struct ipr_ioasa_gata)); + else + memcpy(&sata_port->ioasa, &ipr_cmd->s.ioasa.u.gata, + sizeof(struct ipr_ioasa_gata)); ipr_dump_ioasa(ioa_cfg, ipr_cmd, res); - if (be32_to_cpu(ipr_cmd->ioasa.ioasc_specific) & IPR_ATA_DEVICE_WAS_RESET) + if (be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc_specific) & IPR_ATA_DEVICE_WAS_RESET) scsi_report_device_reset(ioa_cfg->host, res->bus, res->target); if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR) - qc->err_mask |= __ac_err_mask(ipr_cmd->ioasa.u.gata.status); + qc->err_mask |= __ac_err_mask(sata_port->ioasa.status); else - qc->err_mask |= ac_err_mask(ipr_cmd->ioasa.u.gata.status); + qc->err_mask |= ac_err_mask(sata_port->ioasa.status); list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); ata_qc_complete(qc); } @@ -6522,7 +6539,7 @@ static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd, static int ipr_reset_cmd_failed(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; - u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); + u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); dev_err(&ioa_cfg->pdev->dev, "0x%02X failed with IOASC: 0x%08X\n", @@ -6546,7 +6563,7 @@ static int ipr_reset_cmd_failed(struct ipr_cmnd *ipr_cmd) static int ipr_reset_mode_sense_failed(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; - u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); + u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) { ipr_cmd->job_step = ipr_set_supported_devs; @@ -6636,7 +6653,7 @@ static int ipr_ioafp_mode_select_page24(struct ipr_cmnd *ipr_cmd) **/ static int ipr_reset_mode_sense_page24_failed(struct ipr_cmnd *ipr_cmd) { - u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); + u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) { ipr_cmd->job_step = ipr_ioafp_mode_sense_page28; @@ -7337,12 +7354,12 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd) rc = pci_restore_state(ioa_cfg->pdev); if (rc != PCIBIOS_SUCCESSFUL) { - ipr_cmd->ioasa.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); + ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); return IPR_RC_JOB_CONTINUE; } if (ipr_set_pcix_cmd_reg(ioa_cfg)) { - ipr_cmd->ioasa.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); + ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); return IPR_RC_JOB_CONTINUE; } @@ -7411,7 +7428,7 @@ static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd) if (rc != PCIBIOS_SUCCESSFUL) { pci_unblock_user_cfg_access(ipr_cmd->ioa_cfg->pdev); - ipr_cmd->ioasa.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); + ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); rc = IPR_RC_JOB_CONTINUE; } else { ipr_cmd->job_step = ipr_reset_bist_done; @@ -7670,7 +7687,7 @@ static void ipr_reset_ioa_job(struct ipr_cmnd *ipr_cmd) struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; do { - ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); + ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); if (ioa_cfg->reset_cmd != ipr_cmd) { /* @@ -8053,13 +8070,13 @@ static int __devinit ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg) ioarcb->u.sis64_addr_data.data_ioadl_addr = cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64)); ioarcb->u.sis64_addr_data.ioasa_host_pci_addr = - cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, ioasa)); + cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, s.ioasa64)); } else { ioarcb->write_ioadl_addr = cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl)); ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; ioarcb->ioasa_host_pci_addr = - cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioasa)); + cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, s.ioasa)); } ioarcb->ioasa_len = cpu_to_be16(sizeof(struct ipr_ioasa)); ipr_cmd->cmd_index = i; diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index 4e7f81494ea4..f8a17d88db84 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -614,7 +614,7 @@ struct ipr_auto_sense { __be32 data[SCSI_SENSE_BUFFERSIZE/sizeof(__be32)]; }; -struct ipr_ioasa { +struct ipr_ioasa_hdr { __be32 ioasc; #define IPR_IOASC_SENSE_KEY(ioasc) ((ioasc) >> 24) #define IPR_IOASC_SENSE_CODE(ioasc) (((ioasc) & 0x00ff0000) >> 16) @@ -646,6 +646,25 @@ struct ipr_ioasa { #define IPR_FIELD_POINTER_VALID (0x80000000 >> 8) #define IPR_FIELD_POINTER_MASK 0x0000ffff +}__attribute__((packed, aligned (4))); + +struct ipr_ioasa { + struct ipr_ioasa_hdr hdr; + + union { + struct ipr_ioasa_vset vset; + struct ipr_ioasa_af_dasd dasd; + struct ipr_ioasa_gpdd gpdd; + struct ipr_ioasa_gata gata; + } u; + + struct ipr_auto_sense auto_sense; +}__attribute__((packed, aligned (4))); + +struct ipr_ioasa64 { + struct ipr_ioasa_hdr hdr; + u8 fd_res_path[8]; + union { struct ipr_ioasa_vset vset; struct ipr_ioasa_af_dasd dasd; @@ -1465,7 +1484,10 @@ struct ipr_cmnd { struct ipr_ioadl64_desc ioadl64[IPR_NUM_IOADL_ENTRIES]; struct ipr_ata64_ioadl ata_ioadl; } i; - struct ipr_ioasa ioasa; + union { + struct ipr_ioasa ioasa; + struct ipr_ioasa64 ioasa64; + } s; struct list_head queue; struct scsi_cmnd *scsi_cmd; struct ata_queued_cmd *qc; -- cgit v1.2.3 From 7be96900a2a662c67403559acd250f011b1d70db Mon Sep 17 00:00:00 2001 From: Wayne Boyer Date: Mon, 10 May 2010 09:14:07 -0700 Subject: [SCSI] ipr: fix a register read to use the correct address for 64 bit adapters Fix ipr_reset_enable_ioa() to read the correct IOA to host interrupt register address for 64 bit adapters. We need to read the lower 32 bits, not the upper 32 bits. Also change the write of the 64 bit mask value to a single writeq instead of two writel calls. Finally, use the correct u8 type for the type field in the ipr_resource_entry structure. Signed-off-by: Wayne Boyer Acked-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/ipr.c | 12 ++++++++---- drivers/scsi/ipr.h | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 8c2f4c4041c1..2f280d08fcc6 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -7187,13 +7187,14 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; volatile u32 int_reg; + volatile u64 maskval; ENTER; ipr_cmd->job_step = ipr_ioafp_identify_hrrq; ipr_init_ioa_mem(ioa_cfg); ioa_cfg->allow_interrupts = 1; - int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); + int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32); if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) { writel((IPR_PCII_ERROR_INTERRUPTS | IPR_PCII_HRRQ_UPDATED), @@ -7205,9 +7206,12 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd) /* Enable destructive diagnostics on IOA */ writel(ioa_cfg->doorbell, ioa_cfg->regs.set_uproc_interrupt_reg32); - writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg32); - if (ioa_cfg->sis64) - writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_mask_reg); + if (ioa_cfg->sis64) { + maskval = IPR_PCII_IPL_STAGE_CHANGE; + maskval = (maskval << 32) | IPR_PCII_OPER_INTERRUPTS; + writeq(maskval, ioa_cfg->regs.clr_interrupt_mask_reg); + } else + writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg32); int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index f8a17d88db84..9ecd2259eb39 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -1201,7 +1201,7 @@ struct ipr_resource_entry { u8 flags; __be16 res_flags; - __be32 type; + u8 type; u8 qmodel; struct ipr_std_inq_data std_inq_data; -- cgit v1.2.3 From b8803b1cef28af785c4e903b9b1449898d68c758 Mon Sep 17 00:00:00 2001 From: Wayne Boyer Date: Fri, 14 May 2010 08:55:13 -0700 Subject: [SCSI] ipr: set the data list length in the request control block In bring up testing for the new 64 bit adapters, the first read command failed after loading the driver. The cause was that the command requires more than one scatter gather element and the corresponding code to set the data list length in the request control block was missing. This patch adds the correct assignment. Signed-off-by: Wayne Boyer Acked-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/ipr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 2f280d08fcc6..5244282cd97f 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -5021,6 +5021,8 @@ static int ipr_build_ioadl64(struct ipr_ioa_cfg *ioa_cfg, ipr_cmd->dma_use_sg = nseg; ioarcb->data_transfer_length = cpu_to_be32(length); + ioarcb->ioadl_len = + cpu_to_be32(sizeof(struct ipr_ioadl64_desc) * ipr_cmd->dma_use_sg); if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) { ioadl_flags = IPR_IOADL_FLAGS_WRITE; -- cgit v1.2.3 From 64ffdb762241c0a9c0c8fac7ea92aa0ba1529334 Mon Sep 17 00:00:00 2001 From: Wayne Boyer Date: Wed, 19 May 2010 11:56:13 -0700 Subject: [SCSI] ipr: improve interrupt service routine performance During performance testing on P7 machines it was observed that the interrupt service routine was doing unnecessary MMIO operations. This patch rearranges the logic of the routine and moves some of the code out of the main routine. The result is that there are now fewer MMIO operations in the performance path of the code. Signed-off-by: Wayne Boyer Acked-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/ipr.c | 63 ++++++++++++++++++++++++++---------------------------- 1 file changed, 30 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 5244282cd97f..82ea4a8226b0 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -4818,15 +4818,39 @@ static int ipr_eh_abort(struct scsi_cmnd * scsi_cmd) /** * ipr_handle_other_interrupt - Handle "other" interrupts * @ioa_cfg: ioa config struct - * @int_reg: interrupt register * * Return value: * IRQ_NONE / IRQ_HANDLED **/ -static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg, - volatile u32 int_reg) +static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg) { irqreturn_t rc = IRQ_HANDLED; + volatile u32 int_reg, int_mask_reg; + + int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg32); + int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg; + + /* If an interrupt on the adapter did not occur, ignore it. + * Or in the case of SIS 64, check for a stage change interrupt. + */ + if ((int_reg & IPR_PCII_OPER_INTERRUPTS) == 0) { + if (ioa_cfg->sis64) { + int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); + int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; + if (int_reg & IPR_PCII_IPL_STAGE_CHANGE) { + + /* clear stage change */ + writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_reg); + int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; + list_del(&ioa_cfg->reset_cmd->queue); + del_timer(&ioa_cfg->reset_cmd->timer); + ipr_reset_ioa_job(ioa_cfg->reset_cmd); + return IRQ_HANDLED; + } + } + + return IRQ_NONE; + } if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) { /* Mask the interrupt */ @@ -4887,7 +4911,7 @@ static irqreturn_t ipr_isr(int irq, void *devp) { struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)devp; unsigned long lock_flags = 0; - volatile u32 int_reg, int_mask_reg; + volatile u32 int_reg; u32 ioasc; u16 cmd_index; int num_hrrq = 0; @@ -4902,33 +4926,6 @@ static irqreturn_t ipr_isr(int irq, void *devp) return IRQ_NONE; } - int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg32); - int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg; - - /* If an interrupt on the adapter did not occur, ignore it. - * Or in the case of SIS 64, check for a stage change interrupt. - */ - if (unlikely((int_reg & IPR_PCII_OPER_INTERRUPTS) == 0)) { - if (ioa_cfg->sis64) { - int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); - int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; - if (int_reg & IPR_PCII_IPL_STAGE_CHANGE) { - - /* clear stage change */ - writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_reg); - int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; - list_del(&ioa_cfg->reset_cmd->queue); - del_timer(&ioa_cfg->reset_cmd->timer); - ipr_reset_ioa_job(ioa_cfg->reset_cmd); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - return IRQ_HANDLED; - } - } - - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - return IRQ_NONE; - } - while (1) { ipr_cmd = NULL; @@ -4968,7 +4965,7 @@ static irqreturn_t ipr_isr(int irq, void *devp) /* Clear the PCI interrupt */ do { writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32); - int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg; + int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32); } while (int_reg & IPR_PCII_HRRQ_UPDATED && num_hrrq++ < IPR_MAX_HRRQ_RETRIES); @@ -4983,7 +4980,7 @@ static irqreturn_t ipr_isr(int irq, void *devp) } if (unlikely(rc == IRQ_NONE)) - rc = ipr_handle_other_interrupt(ioa_cfg, int_reg); + rc = ipr_handle_other_interrupt(ioa_cfg); spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); return rc; -- cgit v1.2.3 From c2fd1a4ebf9127c280d227acb635eb1df213439c Mon Sep 17 00:00:00 2001 From: Cory Maccarrone Date: Sat, 22 May 2010 13:00:28 -0700 Subject: HID: Add the GYR4101US USB ID to hid-gyration This change adds in the USB product ID for the Gyration GYR4101US USB media center remote control. This remote is similar enough to the other two devices that this driver can be used without any other changes to get full support for the remote. Signed-off-by: Cory Maccarrone Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-gyration.c | 1 + drivers/hid/hid-ids.h | 1 + 3 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index e10e314d38cc..aa0f7dcabcd7 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1301,6 +1301,7 @@ static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) }, { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, diff --git a/drivers/hid/hid-gyration.c b/drivers/hid/hid-gyration.c index 62416e6baeca..3975e039c3dd 100644 --- a/drivers/hid/hid-gyration.c +++ b/drivers/hid/hid-gyration.c @@ -73,6 +73,7 @@ static int gyration_event(struct hid_device *hdev, struct hid_field *field, static const struct hid_device_id gyration_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, { } }; MODULE_DEVICE_TABLE(hid, gyration_devices); diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 9776896cc4fc..6af77ed0b555 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -282,6 +282,7 @@ #define USB_VENDOR_ID_GYRATION 0x0c16 #define USB_DEVICE_ID_GYRATION_REMOTE 0x0002 #define USB_DEVICE_ID_GYRATION_REMOTE_2 0x0003 +#define USB_DEVICE_ID_GYRATION_REMOTE_3 0x0008 #define USB_VENDOR_ID_HAPP 0x078b #define USB_DEVICE_ID_UGCI_DRIVING 0x0010 -- cgit v1.2.3 From b5eae9ff5ba6d76de19286dd6429acd7cde3f79d Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 19 May 2010 10:18:16 +0900 Subject: ath5k: consistently use rx_bufsize for RX DMA We should use the same buffer size we set up for DMA also in the hardware descriptor. Previously we used common->rx_bufsize for setting up the DMA mapping, but used skb_tailroom(skb) for the size we tell to the hardware in the descriptor itself. The problem is that skb_tailroom(skb) can give us a larger value than the size we set up for DMA before. This allows the hardware to write into memory locations not set up for DMA. In practice this should rarely happen because all packets should be smaller than the maximum 802.11 packet size. On the tested platform rx_bufsize is 2528, and we allocated an skb of 2559 bytes length (including padding for cache alignment) but sbk_tailroom() was 2592. Just consistently use rx_bufsize for all RX DMA memory sizes. Also use the return value of the descriptor setup function. Cc: stable@kernel.org Signed-off-by: Bruno Randolf Reviewed-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 5f04cf38a5bc..cc6d41dec332 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1214,6 +1214,7 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) struct ath5k_hw *ah = sc->ah; struct sk_buff *skb = bf->skb; struct ath5k_desc *ds; + int ret; if (!skb) { skb = ath5k_rx_skb_alloc(sc, &bf->skbaddr); @@ -1240,9 +1241,9 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) ds = bf->desc; ds->ds_link = bf->daddr; /* link to self */ ds->ds_data = bf->skbaddr; - ah->ah_setup_rx_desc(ah, ds, - skb_tailroom(skb), /* buffer size */ - 0); + ret = ah->ah_setup_rx_desc(ah, ds, ah->common.rx_bufsize, 0); + if (ret) + return ret; if (sc->rxlink != NULL) *sc->rxlink = bf->daddr; -- cgit v1.2.3 From 52a9bd2a8fac5193435bb575313c89656709aea8 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Wed, 19 May 2010 08:47:59 +0200 Subject: rt2x00: don't use to_pci_dev in rt2x00pci_uninitialize Don't use to_pci_dev in rt2x00pci_uninitialize to get the allocated irq as it won't work for platform devices (SoC). Instead, use the irq field that's already used everywhere else. Signed-off-by: Helmut Schaa Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index a016f7ccde29..f71eee67f977 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -206,7 +206,7 @@ void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) /* * Free irq line. */ - free_irq(to_pci_dev(rt2x00dev->dev)->irq, rt2x00dev); + free_irq(rt2x00dev->irq, rt2x00dev); /* * Free DMA -- cgit v1.2.3 From 617f3d0d71e2eae4d8d475cefe9363b140e52083 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 30 Mar 2010 02:52:38 +0900 Subject: wireless: update gfp/slab.h includes Implicit slab.h inclusion via percpu.h is about to go away. Make sure gfp.h or slab.h is included as necessary. Signed-off-by: Tejun Heo Cc: Stephen Rothwell Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 1 + drivers/net/wireless/iwlwifi/iwl-agn-ict.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index ad556aa8da39..c251603ab032 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "common.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c index a273e373b7b0..c92b2c0cbd91 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "iwl-dev.h" -- cgit v1.2.3 From 3dc3fc52ea1537f5f37ab301d2b1468a0e79988f Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 24 May 2010 13:36:37 -0400 Subject: Revert "ath9k: Group Key fix for VAPs" This reverts commit 03ceedea972a82d343fa5c2528b3952fa9e615d5. This patch was reported to cause a regression in which connectivity is lost and cannot be reestablished after a suspend/resume cycle. Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 28 +++------------------------- include/net/mac80211.h | 1 - net/mac80211/key.c | 1 - 3 files changed, 3 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 893b552981a0..abfa0493236f 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -752,7 +752,6 @@ static int ath_key_config(struct ath_common *common, struct ath_hw *ah = common->ah; struct ath9k_keyval hk; const u8 *mac = NULL; - u8 gmac[ETH_ALEN]; int ret = 0; int idx; @@ -776,30 +775,9 @@ static int ath_key_config(struct ath_common *common, memcpy(hk.kv_val, key->key, key->keylen); if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { - - if (key->ap_addr) { - /* - * Group keys on hardware that supports multicast frame - * key search use a mac that is the sender's address with - * the high bit set instead of the app-specified address. - */ - memcpy(gmac, key->ap_addr, ETH_ALEN); - gmac[0] |= 0x80; - mac = gmac; - - if (key->alg == ALG_TKIP) - idx = ath_reserve_key_cache_slot_tkip(common); - else - idx = ath_reserve_key_cache_slot(common); - if (idx < 0) - mac = NULL; /* no free key cache entries */ - } - - if (!mac) { - /* For now, use the default keys for broadcast keys. This may - * need to change with virtual interfaces. */ - idx = key->keyidx; - } + /* For now, use the default keys for broadcast keys. This may + * need to change with virtual interfaces. */ + idx = key->keyidx; } else if (key->keyidx) { if (WARN_ON(!sta)) return -EOPNOTSUPP; diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 5be900d19660..e24b0363e6cb 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -831,7 +831,6 @@ struct ieee80211_key_conf { u8 iv_len; u8 hw_key_idx; u8 flags; - u8 *ap_addr; s8 keyidx; u8 keylen; u8 key[0]; diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 8d4b41787dcf..e8f6e3b252d8 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -140,7 +140,6 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) struct ieee80211_sub_if_data, u.ap); - key->conf.ap_addr = sdata->dev->dev_addr; ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf); if (!ret) { -- cgit v1.2.3 From 9655a6ec19ca656af246fb80817aa337892aefbf Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Thu, 13 May 2010 21:16:03 +0200 Subject: rt2x00: Fix failed SLEEP->AWAKE and AWAKE->SLEEP transitions. (Based on a patch created by Ondrej Zary) In some circumstances the Ralink devices do not properly go to sleep or wake up, with timeouts occurring. Fix this by retrying telling the device that it has to wake up or sleep. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 9 +++++---- drivers/net/wireless/rt2x00/rt2500pci.c | 9 +++++---- drivers/net/wireless/rt2x00/rt61pci.c | 7 ++++--- drivers/net/wireless/rt2x00/rt73usb.c | 7 ++++--- 4 files changed, 18 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 4ba7b038928f..ad2c98af7e9d 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -926,7 +926,7 @@ static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev) static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) { - u32 reg; + u32 reg, reg2; unsigned int i; char put_to_sleep; char bbp_state; @@ -947,11 +947,12 @@ static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev, * device has entered the correct state. */ for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®); - bbp_state = rt2x00_get_field32(reg, PWRCSR1_BBP_CURR_STATE); - rf_state = rt2x00_get_field32(reg, PWRCSR1_RF_CURR_STATE); + rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®2); + bbp_state = rt2x00_get_field32(reg2, PWRCSR1_BBP_CURR_STATE); + rf_state = rt2x00_get_field32(reg2, PWRCSR1_RF_CURR_STATE); if (bbp_state == state && rf_state == state) return 0; + rt2x00pci_register_write(rt2x00dev, PWRCSR1, reg); msleep(10); } diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 89d132d4af12..41da3d218c65 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1084,7 +1084,7 @@ static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev) static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) { - u32 reg; + u32 reg, reg2; unsigned int i; char put_to_sleep; char bbp_state; @@ -1105,11 +1105,12 @@ static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev, * device has entered the correct state. */ for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®); - bbp_state = rt2x00_get_field32(reg, PWRCSR1_BBP_CURR_STATE); - rf_state = rt2x00_get_field32(reg, PWRCSR1_RF_CURR_STATE); + rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®2); + bbp_state = rt2x00_get_field32(reg2, PWRCSR1_BBP_CURR_STATE); + rf_state = rt2x00_get_field32(reg2, PWRCSR1_RF_CURR_STATE); if (bbp_state == state && rf_state == state) return 0; + rt2x00pci_register_write(rt2x00dev, PWRCSR1, reg); msleep(10); } diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 2e3076f67535..6a74baf4e934 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -1689,7 +1689,7 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev) static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) { - u32 reg; + u32 reg, reg2; unsigned int i; char put_to_sleep; @@ -1706,10 +1706,11 @@ static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) * device has entered the correct state. */ for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®); - state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE); + rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®2); + state = rt2x00_get_field32(reg2, MAC_CSR12_BBP_CURRENT_STATE); if (state == !put_to_sleep) return 0; + rt2x00pci_register_write(rt2x00dev, MAC_CSR12, reg); msleep(10); } diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index e35bd19c3c5a..6e0d82efe924 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1366,7 +1366,7 @@ static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev) static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) { - u32 reg; + u32 reg, reg2; unsigned int i; char put_to_sleep; @@ -1383,10 +1383,11 @@ static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) * device has entered the correct state. */ for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2x00usb_register_read(rt2x00dev, MAC_CSR12, ®); - state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE); + rt2x00usb_register_read(rt2x00dev, MAC_CSR12, ®2); + state = rt2x00_get_field32(reg2, MAC_CSR12_BBP_CURRENT_STATE); if (state == !put_to_sleep) return 0; + rt2x00usb_register_write(rt2x00dev, MAC_CSR12, reg); msleep(10); } -- cgit v1.2.3 From 663cb47cc2c5acd32850f67d051e47d62ed199c9 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Thu, 13 May 2010 21:16:04 +0200 Subject: rt2x00: Fix rt2800usb TX descriptor writing. The recent changes to skb handling introduced a bug in the rt2800usb TX descriptor writing whereby the length of the USB packet wasn't calculated correctly. Found via code inspection, as the devices themselves didn't seem to mind. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 0f8b84b7224c..699161327d65 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -413,7 +413,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, */ rt2x00_desc_read(txi, 0, &word); rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, - skb->len + TXWI_DESC_SIZE); + skb->len - TXINFO_DESC_SIZE); rt2x00_set_field32(&word, TXINFO_W0_WIV, !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); -- cgit v1.2.3 From 690e781c5a3241d2366a3120ca410162da9c365e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 14 May 2010 16:50:56 +0200 Subject: ath9k_htc: dereferencing before check in hif_usb_tx_cb() After c11d8f89d3b7: "ath9k_htc: Simplify TX URB management" we no longer assume that tx_buf is a non-null pointer. Signed-off-by: Dan Carpenter Acked-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 46dc41a16faa..ac82911ee609 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -107,12 +107,14 @@ static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, static void hif_usb_tx_cb(struct urb *urb) { struct tx_buf *tx_buf = (struct tx_buf *) urb->context; - struct hif_device_usb *hif_dev = tx_buf->hif_dev; + struct hif_device_usb *hif_dev; struct sk_buff *skb; - if (!hif_dev || !tx_buf) + if (!tx_buf || !tx_buf->hif_dev) return; + hif_dev = tx_buf->hif_dev; + switch (urb->status) { case 0: break; -- cgit v1.2.3 From 7606688afc767c0b94bb2d79512affe3ba1264ce Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 14 May 2010 16:52:37 +0200 Subject: ath9k_htc: rare leak in ath9k_hif_usb_alloc_tx_urbs() This is obviously a small picky thing. The original error handling code doesn't free the most recent allocations which haven't been added to the hif_dev->tx.tx_buf list yet. Signed-off-by: Dan Carpenter Acked-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index ac82911ee609..77b359162d6c 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -609,6 +609,10 @@ static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) return 0; err: + if (tx_buf) { + kfree(tx_buf->buf); + kfree(tx_buf); + } ath9k_hif_usb_dealloc_tx_urbs(hif_dev); return -ENOMEM; } -- cgit v1.2.3 From 96900c751dd16fc9455e7184cbe8758ac7aa7e79 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 14 May 2010 16:53:46 +0200 Subject: iwlwifi: testing the wrong variable in iwl_add_bssid_station() The intent here is to test that "sta_id_r" is a valid pointer. We do this same test later on in the function. Btw iwl_add_bssid_station() is called from two places and "sta_id_r" is a valid pointer from both callers. Signed-off-by: Dan Carpenter Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-sta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 85ed235ac901..83a26361a9b5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -431,7 +431,7 @@ int iwl_add_bssid_station(struct iwl_priv *priv, const u8 *addr, bool init_rs, struct iwl_link_quality_cmd *link_cmd; unsigned long flags; - if (*sta_id_r) + if (sta_id_r) *sta_id_r = IWL_INVALID_STATION; ret = iwl_add_station_common(priv, addr, 0, NULL, &sta_id); -- cgit v1.2.3 From ededf1f82ac8f06a0311097a68ccb582d32e70d5 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Sat, 22 May 2010 23:58:13 -0700 Subject: ath9k: Fix rx of mcast/bcast frames in PS mode with auto sleep The functionality to keep the device awake until it is done with the rx of any mcast/bcast frames which are pending on AP should also be added to the hardwares which support auto sleep feature. This patch fixes frequent failures in ARP resolution when it is initiated by the other end. Currently auto sleep is enabled only for ar9003 in ath9k. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/recv.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index ba139132c85f..ca6065b71b46 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -19,6 +19,12 @@ #define SKB_CB_ATHBUF(__skb) (*((struct ath_buf **)__skb->cb)) +static inline bool ath9k_check_auto_sleep(struct ath_softc *sc) +{ + return sc->ps_enabled && + (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP); +} + static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc, struct ieee80211_hdr *hdr) { @@ -616,8 +622,8 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb) hdr = (struct ieee80211_hdr *)skb->data; /* Process Beacon and CAB receive in PS state */ - if ((sc->ps_flags & PS_WAIT_FOR_BEACON) && - ieee80211_is_beacon(hdr->frame_control)) + if (((sc->ps_flags & PS_WAIT_FOR_BEACON) || ath9k_check_auto_sleep(sc)) + && ieee80211_is_beacon(hdr->frame_control)) ath_rx_ps_beacon(sc, skb); else if ((sc->ps_flags & PS_WAIT_FOR_CAB) && (ieee80211_is_data(hdr->frame_control) || @@ -932,9 +938,10 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) sc->rx.rxotherant = 0; } - if (unlikely(sc->ps_flags & (PS_WAIT_FOR_BEACON | - PS_WAIT_FOR_CAB | - PS_WAIT_FOR_PSPOLL_DATA))) + if (unlikely(ath9k_check_auto_sleep(sc) || + (sc->ps_flags & (PS_WAIT_FOR_BEACON | + PS_WAIT_FOR_CAB | + PS_WAIT_FOR_PSPOLL_DATA)))) ath_rx_ps(sc, skb); ath_rx_send_to_mac80211(hw, sc, skb, rxs); -- cgit v1.2.3 From 556ae19110f2de5ace4733e0c19e5fa01fad08b3 Mon Sep 17 00:00:00 2001 From: Sarveshwar Bandi Date: Mon, 24 May 2010 18:38:25 -0700 Subject: be2net: Bug fix in init code in probe PCI function reset needs to invoked after fw init ioctl is issued. Signed-off-by: Sarveshwar Bandi Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 058d7f95f5ae..1c79c2009e40 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2487,10 +2487,6 @@ static int __devinit be_probe(struct pci_dev *pdev, status = be_cmd_POST(adapter); if (status) goto ctrl_clean; - - status = be_cmd_reset_function(adapter); - if (status) - goto ctrl_clean; } /* tell fw we're ready to fire cmds */ @@ -2498,6 +2494,12 @@ static int __devinit be_probe(struct pci_dev *pdev, if (status) goto ctrl_clean; + if (be_physfn(adapter)) { + status = be_cmd_reset_function(adapter); + if (status) + goto ctrl_clean; + } + status = be_stats_init(adapter); if (status) goto ctrl_clean; -- cgit v1.2.3 From f16d3d57486cd079b29ae7a6c3b31c90e69c9c44 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Mon, 24 May 2010 07:02:25 +0000 Subject: macvlan: do proper cleanup in macvlan_common_newlink() V2 Fixes possible memory leak. Signed-off-by: Jiri Pirko Acked-by: Patrick McHardy Signed-off-by: David S. Miller --- drivers/net/macvlan.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 4e238afab4a3..87e8d4cb4057 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -634,11 +634,18 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, err = register_netdevice(dev); if (err < 0) - return err; + goto destroy_port; list_add_tail(&vlan->list, &port->vlans); netif_stacked_transfer_operstate(lowerdev, dev); + return 0; + +destroy_port: + if (list_empty(&port->vlans)) + macvlan_port_destroy(lowerdev); + + return err; } EXPORT_SYMBOL_GPL(macvlan_common_newlink); -- cgit v1.2.3 From e1f42ff4f06e5feaa57a22556ad977ef62164e14 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 24 May 2010 07:53:24 +0000 Subject: fbdev: fix erroneous index in drivers/video/sh_mobile_lcdcfb.c Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- drivers/video/sh_mobile_lcdcfb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index e8c769944812..12c451a711e9 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -991,13 +991,13 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) priv->ch[j].lcdc = priv; memcpy(&priv->ch[j].cfg, &pdata->ch[i], sizeof(pdata->ch[i])); - error = sh_mobile_lcdc_check_interface(&priv->ch[i]); + error = sh_mobile_lcdc_check_interface(&priv->ch[j]); if (error) { dev_err(&pdev->dev, "unsupported interface type\n"); goto err1; } - init_waitqueue_head(&priv->ch[i].frame_end_wait); - init_completion(&priv->ch[i].vsync_completion); + init_waitqueue_head(&priv->ch[j].frame_end_wait); + init_completion(&priv->ch[j].vsync_completion); priv->ch[j].pan_offset = 0; switch (pdata->ch[i].chan) { -- cgit v1.2.3 From fd388ce677e7de9180a7d46d12c5162f76af64ac Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Thu, 20 May 2010 16:57:27 -0500 Subject: RDMA/cxgb4: Detach from the LLD after unregistering RDMA device In the RDMA core unregister path, kernel users will be calling down into the T4 provider to release resources. So we cannot detach from the LLD until this process completes. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/device.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index be23b5eab13b..c7e2484e7219 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c @@ -504,14 +504,12 @@ static void __exit c4iw_exit_module(void) { struct c4iw_dev *dev, *tmp; - cxgb4_unregister_uld(CXGB4_ULD_RDMA); - mutex_lock(&dev_mutex); list_for_each_entry_safe(dev, tmp, &dev_list, entry) { c4iw_remove(dev); } mutex_unlock(&dev_mutex); - + cxgb4_unregister_uld(CXGB4_ULD_RDMA); c4iw_cm_term(); debugfs_remove_recursive(c4iw_debugfs_root); } -- cgit v1.2.3 From 1c01c5388306a4c2245b71da0cba22d521e897ae Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Thu, 20 May 2010 16:57:32 -0500 Subject: RDMA/cxgb4: Register RDMA provider based on LLD state_change events The LLD now supports proper UP state change events, so move the RDMA provider registration to UP path. This fixes a crash when loading iw_cxgb4 _after_ the NFS/RDMA transport is up and running. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/device.c | 46 ++++++++++++++++++++++++++-------- drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 1 + drivers/infiniband/hw/cxgb4/provider.c | 2 ++ 3 files changed, 39 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index c7e2484e7219..d870f9c17c1e 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c @@ -306,7 +306,8 @@ static void c4iw_remove(struct c4iw_dev *dev) PDBG("%s c4iw_dev %p\n", __func__, dev); cancel_delayed_work_sync(&dev->db_drop_task); list_del(&dev->entry); - c4iw_unregister_device(dev); + if (dev->registered) + c4iw_unregister_device(dev); c4iw_rdev_close(&dev->rdev); idr_destroy(&dev->cqidr); idr_destroy(&dev->qpidr); @@ -343,12 +344,6 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) list_add_tail(&devp->entry, &dev_list); mutex_unlock(&dev_mutex); - if (c4iw_register_device(devp)) { - printk(KERN_ERR MOD "Unable to register device\n"); - mutex_lock(&dev_mutex); - c4iw_remove(devp); - mutex_unlock(&dev_mutex); - } if (c4iw_debugfs_root) { devp->debugfs_root = debugfs_create_dir( pci_name(devp->rdev.lldi.pdev), @@ -379,9 +374,6 @@ static void *c4iw_uld_add(const struct cxgb4_lld_info *infop) for (i = 0; i < dev->rdev.lldi.nrxq; i++) PDBG("rxqid[%u] %u\n", i, dev->rdev.lldi.rxq_ids[i]); - - printk(KERN_INFO MOD "Initialized device %s\n", - pci_name(dev->rdev.lldi.pdev)); out: return dev; } @@ -471,7 +463,41 @@ nomem: static int c4iw_uld_state_change(void *handle, enum cxgb4_state new_state) { + struct c4iw_dev *dev = handle; + PDBG("%s new_state %u\n", __func__, new_state); + switch (new_state) { + case CXGB4_STATE_UP: + printk(KERN_INFO MOD "%s: Up\n", pci_name(dev->rdev.lldi.pdev)); + if (!dev->registered) { + int ret; + ret = c4iw_register_device(dev); + if (ret) + printk(KERN_ERR MOD + "%s: RDMA registration failed: %d\n", + pci_name(dev->rdev.lldi.pdev), ret); + } + break; + case CXGB4_STATE_DOWN: + printk(KERN_INFO MOD "%s: Down\n", + pci_name(dev->rdev.lldi.pdev)); + if (dev->registered) + c4iw_unregister_device(dev); + break; + case CXGB4_STATE_START_RECOVERY: + printk(KERN_INFO MOD "%s: Fatal Error\n", + pci_name(dev->rdev.lldi.pdev)); + if (dev->registered) + c4iw_unregister_device(dev); + break; + case CXGB4_STATE_DETACH: + printk(KERN_INFO MOD "%s: Detach\n", + pci_name(dev->rdev.lldi.pdev)); + mutex_lock(&dev_mutex); + c4iw_remove(dev); + mutex_unlock(&dev_mutex); + break; + } return 0; } diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index a6269981e815..277ab589b44d 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h @@ -152,6 +152,7 @@ struct c4iw_dev { struct list_head entry; struct delayed_work db_drop_task; struct dentry *debugfs_root; + u8 registered; }; static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev) diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c index dfc49020bb9c..322134bb8b73 100644 --- a/drivers/infiniband/hw/cxgb4/provider.c +++ b/drivers/infiniband/hw/cxgb4/provider.c @@ -496,6 +496,7 @@ int c4iw_register_device(struct c4iw_dev *dev) if (ret) goto bail2; } + dev->registered = 1; return 0; bail2: ib_unregister_device(&dev->ibdev); @@ -514,5 +515,6 @@ void c4iw_unregister_device(struct c4iw_dev *dev) c4iw_class_attributes[i]); ib_unregister_device(&dev->ibdev); kfree(dev->ibdev.iwcm); + dev->registered = 0; return; } -- cgit v1.2.3 From 895cf5f3d6cb72825919a39ae48a41476a821e65 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Thu, 20 May 2010 16:57:38 -0500 Subject: RDMA/cxgb4: CQ size must be IQ size - 2 We need 1 extra entry for the status page and 1 to always have 1 free entry to detect when the queue is full. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/cq.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c index fb1aafcc294f..46ac00f728f3 100644 --- a/drivers/infiniband/hw/cxgb4/cq.c +++ b/drivers/infiniband/hw/cxgb4/cq.c @@ -780,6 +780,9 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev, int entries, /* account for the status page. */ entries++; + /* IQ needs one extra entry to differentiate full vs empty. */ + entries++; + /* * entries must be multiple of 16 for HW. */ @@ -801,7 +804,7 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev, int entries, chp->rhp = rhp; chp->cq.size--; /* status page */ - chp->ibcq.cqe = chp->cq.size; + chp->ibcq.cqe = chp->cq.size - 1; spin_lock_init(&chp->lock); atomic_set(&chp->refcnt, 1); init_waitqueue_head(&chp->wait); -- cgit v1.2.3 From 84172dee05cbce6ae791eac481ef4d8590cda791 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Thu, 20 May 2010 16:57:43 -0500 Subject: RDMA/cxgb4: Optimize CQ overflow detection 1) save the timestamp flit in the cq when we consume a CQE. 2) always compare the saved flit with the previous entry flit when reading the next CQE entry. If the flits don't compare, then we have overflowed. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/cq.c | 1 + drivers/infiniband/hw/cxgb4/t4.h | 28 ++++++++++++++++------------ 2 files changed, 17 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c index 46ac00f728f3..2447f5295482 100644 --- a/drivers/infiniband/hw/cxgb4/cq.c +++ b/drivers/infiniband/hw/cxgb4/cq.c @@ -373,6 +373,7 @@ static void create_read_req_cqe(struct t4_wq *wq, struct t4_cqe *hw_cqe, V_CQE_SWCQE(SW_CQE(hw_cqe)) | V_CQE_OPCODE(FW_RI_READ_REQ) | V_CQE_TYPE(1)); + read_cqe->bits_type_ts = hw_cqe->bits_type_ts; } /* diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h index d0e8af352408..712bc5620d3e 100644 --- a/drivers/infiniband/hw/cxgb4/t4.h +++ b/drivers/infiniband/hw/cxgb4/t4.h @@ -434,7 +434,7 @@ struct t4_cq { struct c4iw_rdev *rdev; u64 ugts; size_t memsize; - u64 timestamp; + __be64 bits_type_ts; u32 cqid; u16 size; /* including status page */ u16 cidx; @@ -487,6 +487,7 @@ static inline void t4_swcq_consume(struct t4_cq *cq) static inline void t4_hwcq_consume(struct t4_cq *cq) { + cq->bits_type_ts = cq->queue[cq->cidx].bits_type_ts; cq->cidx_inc++; if (++cq->cidx == cq->size) { cq->cidx = 0; @@ -501,20 +502,23 @@ static inline int t4_valid_cqe(struct t4_cq *cq, struct t4_cqe *cqe) static inline int t4_next_hw_cqe(struct t4_cq *cq, struct t4_cqe **cqe) { - int ret = 0; - u64 bits_type_ts = be64_to_cpu(cq->queue[cq->cidx].bits_type_ts); + int ret; + u16 prev_cidx; - if (G_CQE_GENBIT(bits_type_ts) == cq->gen) { - *cqe = &cq->queue[cq->cidx]; - cq->timestamp = G_CQE_TS(bits_type_ts); - } else if (G_CQE_TS(bits_type_ts) > cq->timestamp) - ret = -EOVERFLOW; + if (cq->cidx == 0) + prev_cidx = cq->size - 1; else - ret = -ENODATA; - if (ret == -EOVERFLOW) { - printk(KERN_ERR MOD "cq overflow cqid %u\n", cq->cqid); + prev_cidx = cq->cidx - 1; + + if (cq->queue[prev_cidx].bits_type_ts != cq->bits_type_ts) { + ret = -EOVERFLOW; cq->error = 1; - } + printk(KERN_ERR MOD "cq overflow cqid %u\n", cq->cqid); + } else if (t4_valid_cqe(cq, &cq->queue[cq->cidx])) { + *cqe = &cq->queue[cq->cidx]; + ret = 0; + } else + ret = -ENODATA; return ret; } -- cgit v1.2.3 From 7ec45b923446d484eb39434e18d354666426e606 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Thu, 20 May 2010 16:57:49 -0500 Subject: RDMA/cxgb4: Fix overflow bug in CQ arm - wrap cq->cqidx_inc based on cq size. - optimize t4_arm_cq logic. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/t4.h | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h index 712bc5620d3e..333abd3c7264 100644 --- a/drivers/infiniband/hw/cxgb4/t4.h +++ b/drivers/infiniband/hw/cxgb4/t4.h @@ -449,25 +449,17 @@ struct t4_cq { static inline int t4_arm_cq(struct t4_cq *cq, int se) { u32 val; - u16 inc; - - do { - /* - * inc must be less the both the max update value -and- - * the size of the CQ. - */ - inc = cq->cidx_inc <= CIDXINC_MASK ? cq->cidx_inc : - CIDXINC_MASK; - inc = inc <= (cq->size - 1) ? inc : (cq->size - 1); - if (inc == cq->cidx_inc) - val = SEINTARM(se) | CIDXINC(inc) | TIMERREG(6) | - INGRESSQID(cq->cqid); - else - val = SEINTARM(0) | CIDXINC(inc) | TIMERREG(7) | - INGRESSQID(cq->cqid); - cq->cidx_inc -= inc; + + while (cq->cidx_inc > CIDXINC_MASK) { + val = SEINTARM(0) | CIDXINC(CIDXINC_MASK) | TIMERREG(7) | + INGRESSQID(cq->cqid); writel(val, cq->gts); - } while (cq->cidx_inc); + cq->cidx_inc -= CIDXINC_MASK; + } + val = SEINTARM(se) | CIDXINC(cq->cidx_inc) | TIMERREG(6) | + INGRESSQID(cq->cqid); + writel(val, cq->gts); + cq->cidx_inc = 0; return 0; } @@ -488,7 +480,8 @@ static inline void t4_swcq_consume(struct t4_cq *cq) static inline void t4_hwcq_consume(struct t4_cq *cq) { cq->bits_type_ts = cq->queue[cq->cidx].bits_type_ts; - cq->cidx_inc++; + if (++cq->cidx_inc == cq->size) + cq->cidx_inc = 0; if (++cq->cidx == cq->size) { cq->cidx = 0; cq->gen ^= 1; -- cgit v1.2.3 From 841dba9a5a0dbced4b4bc240f444d47f30ba6724 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Thu, 20 May 2010 16:57:54 -0500 Subject: RDMA/cxgb4: Return proper errors in fastreg mr/pbl allocation Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/mem.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c index e54ff6d25691..993ed1fe7bf6 100644 --- a/drivers/infiniband/hw/cxgb4/mem.c +++ b/drivers/infiniband/hw/cxgb4/mem.c @@ -712,8 +712,10 @@ struct ib_mr *c4iw_alloc_fast_reg_mr(struct ib_pd *pd, int pbl_depth) php = to_c4iw_pd(pd); rhp = php->rhp; mhp = kzalloc(sizeof(*mhp), GFP_KERNEL); - if (!mhp) + if (!mhp) { + ret = -ENOMEM; goto err; + } mhp->rhp = rhp; ret = alloc_pbl(mhp, pbl_depth); @@ -730,8 +732,10 @@ struct ib_mr *c4iw_alloc_fast_reg_mr(struct ib_pd *pd, int pbl_depth) mhp->attr.state = 1; mmid = (stag) >> 8; mhp->ibmr.rkey = mhp->ibmr.lkey = stag; - if (insert_handle(rhp, &rhp->mmidr, mhp, mmid)) + if (insert_handle(rhp, &rhp->mmidr, mhp, mmid)) { + ret = -ENOMEM; goto err3; + } PDBG("%s mmid 0x%x mhp %p stag 0x%x\n", __func__, mmid, mhp, stag); return &(mhp->ibmr); -- cgit v1.2.3 From 25737bd4ca1b58e86efa9211c1717140e0d4910e Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Thu, 20 May 2010 16:57:59 -0500 Subject: RDMA/cxgb4: Don't limit fastreg page list depth Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/mem.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c index 993ed1fe7bf6..7f94da1a2437 100644 --- a/drivers/infiniband/hw/cxgb4/mem.c +++ b/drivers/infiniband/hw/cxgb4/mem.c @@ -759,9 +759,6 @@ struct ib_fast_reg_page_list *c4iw_alloc_fastreg_pbl(struct ib_device *device, dma_addr_t dma_addr; int size = sizeof *c4pl + page_list_len * sizeof(u64); - if (page_list_len > T4_MAX_FR_DEPTH) - return ERR_PTR(-EINVAL); - c4pl = dma_alloc_coherent(&dev->rdev.lldi.pdev->dev, size, &dma_addr, GFP_KERNEL); if (!c4pl) -- cgit v1.2.3 From f64b88433c27815f931d4d5ff7db7ac701fdc8c9 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Thu, 20 May 2010 16:58:05 -0500 Subject: RDMA/cxgb4: Update some HW limits Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/t4.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h index 333abd3c7264..1057cb96302e 100644 --- a/drivers/infiniband/hw/cxgb4/t4.h +++ b/drivers/infiniband/hw/cxgb4/t4.h @@ -41,11 +41,13 @@ #define T4_MAX_NUM_QP (1<<16) #define T4_MAX_NUM_CQ (1<<15) #define T4_MAX_NUM_PD (1<<15) -#define T4_MAX_PBL_SIZE 256 -#define T4_MAX_RQ_SIZE 1024 -#define T4_MAX_SQ_SIZE 1024 -#define T4_MAX_QP_DEPTH (T4_MAX_RQ_SIZE-1) -#define T4_MAX_CQ_DEPTH 8192 +#define T4_EQ_STATUS_ENTRIES (L1_CACHE_BYTES > 64 ? 2 : 1) +#define T4_MAX_EQ_SIZE (65520 - T4_EQ_STATUS_ENTRIES) +#define T4_MAX_IQ_SIZE (65520 - 1) +#define T4_MAX_RQ_SIZE (8192 - T4_EQ_STATUS_ENTRIES) +#define T4_MAX_SQ_SIZE (T4_MAX_EQ_SIZE - 1) +#define T4_MAX_QP_DEPTH (T4_MAX_RQ_SIZE - 1) +#define T4_MAX_CQ_DEPTH (T4_MAX_IQ_SIZE - 1) #define T4_MAX_NUM_STAG (1<<15) #define T4_MAX_MR_SIZE (~0ULL - 1) #define T4_PAGESIZE_MASK 0xffff000 /* 4KB-128MB */ @@ -79,12 +81,11 @@ struct t4_status_page { sizeof(struct fw_ri_isgl)) / sizeof(struct fw_ri_sge)) #define T4_MAX_FR_IMMD ((T4_SQ_NUM_BYTES - sizeof(struct fw_ri_fr_nsmr_wr) - \ sizeof(struct fw_ri_immd))) -#define T4_MAX_FR_DEPTH 255 +#define T4_MAX_FR_DEPTH (T4_MAX_FR_IMMD / sizeof(u64)) #define T4_RQ_NUM_SLOTS 2 #define T4_RQ_NUM_BYTES (T4_EQ_SIZE * T4_RQ_NUM_SLOTS) -#define T4_MAX_RECV_SGE ((T4_RQ_NUM_BYTES - sizeof(struct fw_ri_recv_wr) - \ - sizeof(struct fw_ri_isgl)) / sizeof(struct fw_ri_sge)) +#define T4_MAX_RECV_SGE 4 union t4_wr { struct fw_ri_res_wr res; -- cgit v1.2.3 From 4ab1eb9c8df620d5ed64fa1d1be683862b311685 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Thu, 20 May 2010 16:58:10 -0500 Subject: RDMA/cxgb4: Set fence flag for inv-local-stag work requests Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/qp.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 83a01dc0c4c1..9fb52fa75e2a 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -588,6 +588,8 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, err = build_fastreg(wqe, wr, &len16); break; case IB_WR_LOCAL_INV: + if (wr->send_flags & IB_SEND_FENCE) + fw_flags |= FW_RI_LOCAL_FENCE_FLAG; fw_opcode = FW_RI_INV_LSTAG_WR; swsqe->opcode = FW_RI_LOCAL_INV; err = build_inv_stag(wqe, wr, &len16); -- cgit v1.2.3 From 2f1fb507eec22ee64b541ea8586a7365ede8be2e Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Thu, 20 May 2010 16:58:16 -0500 Subject: RDMA/cxgb4: Support IB_WR_READ_WITH_INV opcode Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/qp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 9fb52fa75e2a..a41881b15e6d 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -572,9 +572,13 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, err = build_rdma_write(wqe, wr, &len16); break; case IB_WR_RDMA_READ: + case IB_WR_RDMA_READ_WITH_INV: fw_opcode = FW_RI_RDMA_READ_WR; swsqe->opcode = FW_RI_READ_REQ; - fw_flags = 0; + if (wr->opcode == IB_WR_RDMA_READ_WITH_INV) + fw_flags |= FW_RI_RDMA_READ_INVALIDATE; + else + fw_flags = 0; err = build_rdma_read(wqe, wr, &len16); if (err) break; -- cgit v1.2.3 From 30a6a62fc35208924ffa8a472b0af4552441cbff Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Thu, 20 May 2010 16:58:21 -0500 Subject: RDMA/cxgb4: Only insert sq qid in lookup table Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/qp.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index a41881b15e6d..0c28ed1eafa6 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -1345,7 +1345,6 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp) wait_event(qhp->wait, !qhp->ep); remove_handle(rhp, &rhp->qpidr, qhp->wq.sq.qid); - remove_handle(rhp, &rhp->qpidr, qhp->wq.rq.qid); atomic_dec(&qhp->refcnt); wait_event(qhp->wait, !atomic_read(&qhp->refcnt)); @@ -1448,30 +1447,26 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, if (ret) goto err2; - ret = insert_handle(rhp, &rhp->qpidr, qhp, qhp->wq.rq.qid); - if (ret) - goto err3; - if (udata) { mm1 = kmalloc(sizeof *mm1, GFP_KERNEL); if (!mm1) { ret = -ENOMEM; - goto err4; + goto err3; } mm2 = kmalloc(sizeof *mm2, GFP_KERNEL); if (!mm2) { ret = -ENOMEM; - goto err5; + goto err4; } mm3 = kmalloc(sizeof *mm3, GFP_KERNEL); if (!mm3) { ret = -ENOMEM; - goto err6; + goto err5; } mm4 = kmalloc(sizeof *mm4, GFP_KERNEL); if (!mm4) { ret = -ENOMEM; - goto err7; + goto err6; } uresp.qid_mask = rhp->rdev.qpmask; @@ -1493,7 +1488,7 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, spin_unlock(&ucontext->mmap_lock); ret = ib_copy_to_udata(udata, &uresp, sizeof uresp); if (ret) - goto err8; + goto err7; mm1->key = uresp.sq_key; mm1->addr = virt_to_phys(qhp->wq.sq.queue); mm1->len = PAGE_ALIGN(qhp->wq.sq.memsize); @@ -1517,16 +1512,14 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, __func__, qhp, qhp->attr.sq_num_entries, qhp->attr.rq_num_entries, qhp->wq.sq.qid); return &qhp->ibqp; -err8: - kfree(mm4); err7: - kfree(mm3); + kfree(mm4); err6: - kfree(mm2); + kfree(mm3); err5: - kfree(mm1); + kfree(mm2); err4: - remove_handle(rhp, &rhp->qpidr, qhp->wq.rq.qid); + kfree(mm1); err3: remove_handle(rhp, &rhp->qpidr, qhp->wq.sq.qid); err2: -- cgit v1.2.3 From 39942a028c559e39495ae7b29a8dd9b0c3c03003 Mon Sep 17 00:00:00 2001 From: Faisal Latif Date: Fri, 21 May 2010 16:54:57 -0500 Subject: RDMA/nes: Have ethtool read hardware registers for rx/tx stats Enhance ethtool to read hardware registers for rcv/tx error stats. Also add support for free pbl resources. Remove cq depth stats, which are not used. Signed-off-by: Faisal Latif Signed-off-by: Roland Dreier --- drivers/infiniband/hw/nes/nes_nic.c | 72 ++++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index 9f4cadf9f851..242f42d8c1c6 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c @@ -1002,6 +1002,7 @@ static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu) return ret; } + static const char nes_ethtool_stringset[][ETH_GSTRING_LEN] = { "Link Change Interrupts", "Linearized SKBs", @@ -1016,11 +1017,15 @@ static const char nes_ethtool_stringset[][ETH_GSTRING_LEN] = { "Rx Jabber Errors", "Rx Oversized Frames", "Rx Short Frames", + "Rx Length Errors", + "Rx CRC Errors", + "Rx Port Discard", "Endnode Rx Discards", "Endnode Rx Octets", "Endnode Rx Frames", "Endnode Tx Octets", "Endnode Tx Frames", + "Tx Errors", "mh detected", "mh pauses", "Retransmission Count", @@ -1049,19 +1054,13 @@ static const char nes_ethtool_stringset[][ETH_GSTRING_LEN] = { "CM Nodes Destroyed", "CM Accel Drops", "CM Resets Received", + "Free 4Kpbls", + "Free 256pbls", "Timer Inits", - "CQ Depth 1", - "CQ Depth 4", - "CQ Depth 16", - "CQ Depth 24", - "CQ Depth 32", - "CQ Depth 128", - "CQ Depth 256", "LRO aggregated", "LRO flushed", "LRO no_desc", }; - #define NES_ETHTOOL_STAT_COUNT ARRAY_SIZE(nes_ethtool_stringset) /** @@ -1121,12 +1120,14 @@ static void nes_netdev_get_strings(struct net_device *netdev, u32 stringset, /** * nes_netdev_get_ethtool_stats */ + static void nes_netdev_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *target_ethtool_stats, u64 *target_stat_values) { u64 u64temp; struct nes_vnic *nesvnic = netdev_priv(netdev); struct nes_device *nesdev = nesvnic->nesdev; + struct nes_adapter *nesadapter = nesdev->nesadapter; u32 nic_count; u32 u32temp; u32 index = 0; @@ -1155,6 +1156,46 @@ static void nes_netdev_get_ethtool_stats(struct net_device *netdev, nesvnic->nesdev->port_tx_discards += u32temp; nesvnic->netstats.tx_dropped += u32temp; + u32temp = nes_read_indexed(nesdev, + NES_IDX_MAC_RX_SHORT_FRAMES + (nesvnic->nesdev->mac_index*0x200)); + nesvnic->netstats.rx_dropped += u32temp; + nesvnic->nesdev->mac_rx_errors += u32temp; + nesvnic->nesdev->mac_rx_short_frames += u32temp; + + u32temp = nes_read_indexed(nesdev, + NES_IDX_MAC_RX_OVERSIZED_FRAMES + (nesvnic->nesdev->mac_index*0x200)); + nesvnic->netstats.rx_dropped += u32temp; + nesvnic->nesdev->mac_rx_errors += u32temp; + nesvnic->nesdev->mac_rx_oversized_frames += u32temp; + + u32temp = nes_read_indexed(nesdev, + NES_IDX_MAC_RX_JABBER_FRAMES + (nesvnic->nesdev->mac_index*0x200)); + nesvnic->netstats.rx_dropped += u32temp; + nesvnic->nesdev->mac_rx_errors += u32temp; + nesvnic->nesdev->mac_rx_jabber_frames += u32temp; + + u32temp = nes_read_indexed(nesdev, + NES_IDX_MAC_RX_SYMBOL_ERR_FRAMES + (nesvnic->nesdev->mac_index*0x200)); + nesvnic->netstats.rx_dropped += u32temp; + nesvnic->nesdev->mac_rx_errors += u32temp; + nesvnic->nesdev->mac_rx_symbol_err_frames += u32temp; + + u32temp = nes_read_indexed(nesdev, + NES_IDX_MAC_RX_LENGTH_ERR_FRAMES + (nesvnic->nesdev->mac_index*0x200)); + nesvnic->netstats.rx_length_errors += u32temp; + nesvnic->nesdev->mac_rx_errors += u32temp; + + u32temp = nes_read_indexed(nesdev, + NES_IDX_MAC_RX_CRC_ERR_FRAMES + (nesvnic->nesdev->mac_index*0x200)); + nesvnic->nesdev->mac_rx_errors += u32temp; + nesvnic->nesdev->mac_rx_crc_errors += u32temp; + nesvnic->netstats.rx_crc_errors += u32temp; + + u32temp = nes_read_indexed(nesdev, + NES_IDX_MAC_TX_ERRORS + (nesvnic->nesdev->mac_index*0x200)); + nesvnic->nesdev->mac_tx_errors += u32temp; + nesvnic->netstats.tx_errors += u32temp; + for (nic_count = 0; nic_count < NES_MAX_PORT_COUNT; nic_count++) { if (nesvnic->qp_nic_index[nic_count] == 0xf) break; @@ -1219,11 +1260,15 @@ static void nes_netdev_get_ethtool_stats(struct net_device *netdev, target_stat_values[++index] = nesvnic->nesdev->mac_rx_jabber_frames; target_stat_values[++index] = nesvnic->nesdev->mac_rx_oversized_frames; target_stat_values[++index] = nesvnic->nesdev->mac_rx_short_frames; + target_stat_values[++index] = nesvnic->netstats.rx_length_errors; + target_stat_values[++index] = nesvnic->nesdev->mac_rx_crc_errors; + target_stat_values[++index] = nesvnic->nesdev->port_rx_discards; target_stat_values[++index] = nesvnic->endnode_nstat_rx_discard; target_stat_values[++index] = nesvnic->endnode_nstat_rx_octets; target_stat_values[++index] = nesvnic->endnode_nstat_rx_frames; target_stat_values[++index] = nesvnic->endnode_nstat_tx_octets; target_stat_values[++index] = nesvnic->endnode_nstat_tx_frames; + target_stat_values[++index] = nesvnic->nesdev->mac_tx_errors; target_stat_values[++index] = mh_detected; target_stat_values[++index] = mh_pauses_sent; target_stat_values[++index] = nesvnic->endnode_ipv4_tcp_retransmits; @@ -1252,21 +1297,14 @@ static void nes_netdev_get_ethtool_stats(struct net_device *netdev, target_stat_values[++index] = atomic_read(&cm_nodes_destroyed); target_stat_values[++index] = atomic_read(&cm_accel_dropped_pkts); target_stat_values[++index] = atomic_read(&cm_resets_recvd); + target_stat_values[++index] = nesadapter->free_4kpbl; + target_stat_values[++index] = nesadapter->free_256pbl; target_stat_values[++index] = int_mod_timer_init; - target_stat_values[++index] = int_mod_cq_depth_1; - target_stat_values[++index] = int_mod_cq_depth_4; - target_stat_values[++index] = int_mod_cq_depth_16; - target_stat_values[++index] = int_mod_cq_depth_24; - target_stat_values[++index] = int_mod_cq_depth_32; - target_stat_values[++index] = int_mod_cq_depth_128; - target_stat_values[++index] = int_mod_cq_depth_256; target_stat_values[++index] = nesvnic->lro_mgr.stats.aggregated; target_stat_values[++index] = nesvnic->lro_mgr.stats.flushed; target_stat_values[++index] = nesvnic->lro_mgr.stats.no_desc; - } - /** * nes_netdev_get_drvinfo */ -- cgit v1.2.3 From df02902313feb1472bc6ec16e486f72b39e9d4b2 Mon Sep 17 00:00:00 2001 From: Faisal Latif Date: Fri, 21 May 2010 16:55:03 -0500 Subject: RDMA/nes: Async event for closed QP causes crash Under abnormal termination, modify_qp() closes the QP, and async event (AE) handling also attempts to close the same QP, causing a crash. Fix this by checking the state of the QP before processing the AE. Signed-off-by: Faisal Latif Signed-off-by: Roland Dreier --- drivers/infiniband/hw/nes/nes_hw.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 86acb7d57064..bb9c77504fe2 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c @@ -3422,6 +3422,7 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, struct nes_adapter *nesadapter = nesdev->nesadapter; u32 aeq_info; u32 next_iwarp_state = 0; + u32 aeqe_cq_id; u16 async_event_id; u8 tcp_state; u8 iwarp_state; @@ -3449,6 +3450,14 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]), aeqe, nes_tcp_state_str[tcp_state], nes_iwarp_state_str[iwarp_state]); + aeqe_cq_id = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]); + if (aeq_info & NES_AEQE_QP) { + if ((!nes_is_resource_allocated(nesadapter, nesadapter->allocated_qps, + aeqe_cq_id)) || + (atomic_read(&nesqp->close_timer_started))) + return; + } + switch (async_event_id) { case NES_AEQE_AEID_LLP_FIN_RECEIVED: if (nesqp->term_flags) -- cgit v1.2.3 From 0398fb70940e1f10939d6126eafb760bd48d1566 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Fri, 14 May 2010 09:14:26 +0000 Subject: spi/spi_mpc8xxx: Fix QE mode Litte Endian QE mode uses Little Endian so words > 8 bits are byte swapped. Workaround this by always enforcing wordsize 8 for words > 8 bits. Unfortunately this will not work for LSB transfers where wordsize is > 8 bits so disable these for now. Also move the different quirks into its own function to keep mpc8xxx_spi_setup_transfer() sane. Signed-off-by: Joakim Tjernlund Acked-by: Anton Vorontsov Signed-off-by: Grant Likely --- drivers/spi/spi_mpc8xxx.c | 101 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 70 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c index 0dfc482bbff5..66517ce750f3 100644 --- a/drivers/spi/spi_mpc8xxx.c +++ b/drivers/spi/spi_mpc8xxx.c @@ -286,36 +286,12 @@ static void mpc8xxx_spi_chipselect(struct spi_device *spi, int value) } } -static -int mpc8xxx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) +static int +mspi_apply_cpu_mode_quirks(struct spi_mpc8xxx_cs *cs, + struct spi_device *spi, + struct mpc8xxx_spi *mpc8xxx_spi, + int bits_per_word) { - struct mpc8xxx_spi *mpc8xxx_spi; - u8 bits_per_word, pm; - u32 hz; - struct spi_mpc8xxx_cs *cs = spi->controller_state; - - mpc8xxx_spi = spi_master_get_devdata(spi->master); - - if (t) { - bits_per_word = t->bits_per_word; - hz = t->speed_hz; - } else { - bits_per_word = 0; - hz = 0; - } - - /* spi_transfer level calls that work per-word */ - if (!bits_per_word) - bits_per_word = spi->bits_per_word; - - /* Make sure its a bit width we support [4..16, 32] */ - if ((bits_per_word < 4) - || ((bits_per_word > 16) && (bits_per_word != 32))) - return -EINVAL; - - if (!hz) - hz = spi->max_speed_hz; - cs->rx_shift = 0; cs->tx_shift = 0; if (bits_per_word <= 8) { @@ -339,19 +315,82 @@ int mpc8xxx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) return -EINVAL; if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE && - spi->mode & SPI_LSB_FIRST) { + spi->mode & SPI_LSB_FIRST) { cs->tx_shift = 0; if (bits_per_word <= 8) cs->rx_shift = 8; else cs->rx_shift = 0; } - mpc8xxx_spi->rx_shift = cs->rx_shift; mpc8xxx_spi->tx_shift = cs->tx_shift; mpc8xxx_spi->get_rx = cs->get_rx; mpc8xxx_spi->get_tx = cs->get_tx; + return bits_per_word; +} + +static int +mspi_apply_qe_mode_quirks(struct spi_mpc8xxx_cs *cs, + struct spi_device *spi, + int bits_per_word) +{ + /* QE uses Little Endian for words > 8 + * so transform all words > 8 into 8 bits + * Unfortnatly that doesn't work for LSB so + * reject these for now */ + /* Note: 32 bits word, LSB works iff + * tfcr/rfcr is set to CPMFCR_GBL */ + if (spi->mode & SPI_LSB_FIRST && + bits_per_word > 8) + return -EINVAL; + if (bits_per_word > 8) + return 8; /* pretend its 8 bits */ + return bits_per_word; +} + +static +int mpc8xxx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) +{ + struct mpc8xxx_spi *mpc8xxx_spi; + int bits_per_word; + u8 pm; + u32 hz; + struct spi_mpc8xxx_cs *cs = spi->controller_state; + + mpc8xxx_spi = spi_master_get_devdata(spi->master); + + if (t) { + bits_per_word = t->bits_per_word; + hz = t->speed_hz; + } else { + bits_per_word = 0; + hz = 0; + } + + /* spi_transfer level calls that work per-word */ + if (!bits_per_word) + bits_per_word = spi->bits_per_word; + + /* Make sure its a bit width we support [4..16, 32] */ + if ((bits_per_word < 4) + || ((bits_per_word > 16) && (bits_per_word != 32))) + return -EINVAL; + + if (!hz) + hz = spi->max_speed_hz; + + if (!(mpc8xxx_spi->flags & SPI_CPM_MODE)) + bits_per_word = mspi_apply_cpu_mode_quirks(cs, spi, + mpc8xxx_spi, + bits_per_word); + else if (mpc8xxx_spi->flags & SPI_QE) + bits_per_word = mspi_apply_qe_mode_quirks(cs, spi, + bits_per_word); + + if (bits_per_word < 0) + return bits_per_word; + if (bits_per_word == 32) bits_per_word = 0; else -- cgit v1.2.3 From 338ff2982d969a8e09ca356552cb5022ad380766 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Mon, 17 May 2010 13:17:10 +0000 Subject: spi/spi_mpc8xxx: Do not use map_tx_dma to unmap rx_dma This fixes a typo were map_tx_dma is used instead of map_rx_dma, casing the driver to unmap rx_dma when it shouldn't. Signed-off-by: Joakim Tjernlund Acked-by: Anton Vorontsov Signed-off-by: Grant Likely --- drivers/spi/spi_mpc8xxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c index 66517ce750f3..6e7aabe8db18 100644 --- a/drivers/spi/spi_mpc8xxx.c +++ b/drivers/spi/spi_mpc8xxx.c @@ -515,7 +515,7 @@ static void mpc8xxx_spi_cpm_bufs_complete(struct mpc8xxx_spi *mspi) if (mspi->map_tx_dma) dma_unmap_single(dev, mspi->tx_dma, t->len, DMA_TO_DEVICE); - if (mspi->map_tx_dma) + if (mspi->map_rx_dma) dma_unmap_single(dev, mspi->rx_dma, t->len, DMA_FROM_DEVICE); mspi->xfer_in_progress = NULL; } -- cgit v1.2.3 From 556f4aeb7d9dfac8573d0281dd555bd3210d8366 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 5 May 2010 09:28:15 +0000 Subject: spi/pl022: fix up differences between ARM and ST versions The PL022 SPI driver did not cleanly separate between the original unmodified ARM version and the ST Microelectronics versions. Split this more cleanly and fix some whitespace moaning from checkpatch at the same time. Signed-off-by: Linus Walleij Signed-off-by: Grant Likely --- drivers/spi/amba-pl022.c | 178 +++++++++++++++++++++++++++++++-------------- include/linux/amba/pl022.h | 4 +- 2 files changed, 125 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c index e9aeee16d922..65092171cec3 100644 --- a/drivers/spi/amba-pl022.c +++ b/drivers/spi/amba-pl022.c @@ -102,13 +102,21 @@ /* * SSP Control Register 0 - SSP_CR0 */ -#define SSP_CR0_MASK_DSS (0x1FUL << 0) -#define SSP_CR0_MASK_HALFDUP (0x1UL << 5) +#define SSP_CR0_MASK_DSS (0x0FUL << 0) +#define SSP_CR0_MASK_FRF (0x3UL << 4) #define SSP_CR0_MASK_SPO (0x1UL << 6) #define SSP_CR0_MASK_SPH (0x1UL << 7) #define SSP_CR0_MASK_SCR (0xFFUL << 8) -#define SSP_CR0_MASK_CSS (0x1FUL << 16) -#define SSP_CR0_MASK_FRF (0x3UL << 21) + +/* + * The ST version of this block moves som bits + * in SSP_CR0 and extends it to 32 bits + */ +#define SSP_CR0_MASK_DSS_ST (0x1FUL << 0) +#define SSP_CR0_MASK_HALFDUP_ST (0x1UL << 5) +#define SSP_CR0_MASK_CSS_ST (0x1FUL << 16) +#define SSP_CR0_MASK_FRF_ST (0x3UL << 21) + /* * SSP Control Register 0 - SSP_CR1 @@ -117,16 +125,16 @@ #define SSP_CR1_MASK_SSE (0x1UL << 1) #define SSP_CR1_MASK_MS (0x1UL << 2) #define SSP_CR1_MASK_SOD (0x1UL << 3) -#define SSP_CR1_MASK_RENDN (0x1UL << 4) -#define SSP_CR1_MASK_TENDN (0x1UL << 5) -#define SSP_CR1_MASK_MWAIT (0x1UL << 6) -#define SSP_CR1_MASK_RXIFLSEL (0x7UL << 7) -#define SSP_CR1_MASK_TXIFLSEL (0x7UL << 10) /* - * SSP Data Register - SSP_DR + * The ST version of this block adds some bits + * in SSP_CR1 */ -#define SSP_DR_MASK_DATA 0xFFFFFFFF +#define SSP_CR1_MASK_RENDN_ST (0x1UL << 4) +#define SSP_CR1_MASK_TENDN_ST (0x1UL << 5) +#define SSP_CR1_MASK_MWAIT_ST (0x1UL << 6) +#define SSP_CR1_MASK_RXIFLSEL_ST (0x7UL << 7) +#define SSP_CR1_MASK_TXIFLSEL_ST (0x7UL << 10) /* * SSP Status Register - SSP_SR @@ -134,7 +142,7 @@ #define SSP_SR_MASK_TFE (0x1UL << 0) /* Transmit FIFO empty */ #define SSP_SR_MASK_TNF (0x1UL << 1) /* Transmit FIFO not full */ #define SSP_SR_MASK_RNE (0x1UL << 2) /* Receive FIFO not empty */ -#define SSP_SR_MASK_RFF (0x1UL << 3) /* Receive FIFO full */ +#define SSP_SR_MASK_RFF (0x1UL << 3) /* Receive FIFO full */ #define SSP_SR_MASK_BSY (0x1UL << 4) /* Busy Flag */ /* @@ -227,7 +235,7 @@ /* * SSP Test Data Register - SSP_TDR */ -#define TDR_MASK_TESTDATA (0xFFFFFFFF) +#define TDR_MASK_TESTDATA (0xFFFFFFFF) /* * Message State @@ -235,33 +243,33 @@ * hold a single state value, that's why all this * (void *) casting is done here. */ -#define STATE_START ((void *) 0) -#define STATE_RUNNING ((void *) 1) -#define STATE_DONE ((void *) 2) -#define STATE_ERROR ((void *) -1) +#define STATE_START ((void *) 0) +#define STATE_RUNNING ((void *) 1) +#define STATE_DONE ((void *) 2) +#define STATE_ERROR ((void *) -1) /* * Queue State */ -#define QUEUE_RUNNING (0) -#define QUEUE_STOPPED (1) +#define QUEUE_RUNNING (0) +#define QUEUE_STOPPED (1) /* * SSP State - Whether Enabled or Disabled */ -#define SSP_DISABLED (0) -#define SSP_ENABLED (1) +#define SSP_DISABLED (0) +#define SSP_ENABLED (1) /* * SSP DMA State - Whether DMA Enabled or Disabled */ -#define SSP_DMA_DISABLED (0) -#define SSP_DMA_ENABLED (1) +#define SSP_DMA_DISABLED (0) +#define SSP_DMA_ENABLED (1) /* * SSP Clock Defaults */ -#define NMDK_SSP_DEFAULT_CLKRATE 0x2 -#define NMDK_SSP_DEFAULT_PRESCALE 0x40 +#define SSP_DEFAULT_CLKRATE 0x2 +#define SSP_DEFAULT_PRESCALE 0x40 /* * SSP Clock Parameter ranges @@ -307,16 +315,20 @@ enum ssp_writing { * @fifodepth: depth of FIFOs (both) * @max_bpw: maximum number of bits per word * @unidir: supports unidirection transfers + * @extended_cr: 32 bit wide control register 0 with extra + * features and extra features in CR1 as found in the ST variants */ struct vendor_data { int fifodepth; int max_bpw; bool unidir; + bool extended_cr; }; /** * struct pl022 - This is the private SSP driver data structure * @adev: AMBA device model hookup + * @vendor: Vendor data for the IP block * @phybase: The physical memory where the SSP device resides * @virtbase: The virtual memory where the SSP is mapped * @master: SPI framework hookup @@ -369,7 +381,8 @@ struct pl022 { /** * struct chip_data - To maintain runtime state of SSP for each client chip - * @cr0: Value of control register CR0 of SSP + * @cr0: Value of control register CR0 of SSP - on later ST variants this + * register is 32 bits wide rather than just 16 * @cr1: Value of control register CR1 of SSP * @dmacr: Value of DMA control Register of SSP * @cpsr: Value of Clock prescale register @@ -384,7 +397,7 @@ struct pl022 { * This would be set according to the current message that would be served */ struct chip_data { - u16 cr0; + u32 cr0; u16 cr1; u16 dmacr; u16 cpsr; @@ -517,7 +530,10 @@ static void restore_state(struct pl022 *pl022) { struct chip_data *chip = pl022->cur_chip; - writew(chip->cr0, SSP_CR0(pl022->virtbase)); + if (pl022->vendor->extended_cr) + writel(chip->cr0, SSP_CR0(pl022->virtbase)); + else + writew(chip->cr0, SSP_CR0(pl022->virtbase)); writew(chip->cr1, SSP_CR1(pl022->virtbase)); writew(chip->dmacr, SSP_DMACR(pl022->virtbase)); writew(chip->cpsr, SSP_CPSR(pl022->virtbase)); @@ -535,28 +551,43 @@ static void restore_state(struct pl022 *pl022) */ #define DEFAULT_SSP_REG_CR0 ( \ GEN_MASK_BITS(SSP_DATA_BITS_12, SSP_CR0_MASK_DSS, 0) | \ - GEN_MASK_BITS(SSP_MICROWIRE_CHANNEL_FULL_DUPLEX, SSP_CR0_MASK_HALFDUP, 5) | \ + GEN_MASK_BITS(SSP_INTERFACE_MOTOROLA_SPI, SSP_CR0_MASK_FRF, 4) | \ + GEN_MASK_BITS(SSP_CLK_POL_IDLE_LOW, SSP_CR0_MASK_SPO, 6) | \ + GEN_MASK_BITS(SSP_CLK_SECOND_EDGE, SSP_CR0_MASK_SPH, 7) | \ + GEN_MASK_BITS(SSP_DEFAULT_CLKRATE, SSP_CR0_MASK_SCR, 8) \ +) + +/* ST versions have slightly different bit layout */ +#define DEFAULT_SSP_REG_CR0_ST ( \ + GEN_MASK_BITS(SSP_DATA_BITS_12, SSP_CR0_MASK_DSS_ST, 0) | \ + GEN_MASK_BITS(SSP_MICROWIRE_CHANNEL_FULL_DUPLEX, SSP_CR0_MASK_HALFDUP_ST, 5) | \ GEN_MASK_BITS(SSP_CLK_POL_IDLE_LOW, SSP_CR0_MASK_SPO, 6) | \ GEN_MASK_BITS(SSP_CLK_SECOND_EDGE, SSP_CR0_MASK_SPH, 7) | \ - GEN_MASK_BITS(NMDK_SSP_DEFAULT_CLKRATE, SSP_CR0_MASK_SCR, 8) | \ - GEN_MASK_BITS(SSP_BITS_8, SSP_CR0_MASK_CSS, 16) | \ - GEN_MASK_BITS(SSP_INTERFACE_MOTOROLA_SPI, SSP_CR0_MASK_FRF, 21) \ + GEN_MASK_BITS(SSP_DEFAULT_CLKRATE, SSP_CR0_MASK_SCR, 8) | \ + GEN_MASK_BITS(SSP_BITS_8, SSP_CR0_MASK_CSS_ST, 16) | \ + GEN_MASK_BITS(SSP_INTERFACE_MOTOROLA_SPI, SSP_CR0_MASK_FRF_ST, 21) \ ) #define DEFAULT_SSP_REG_CR1 ( \ GEN_MASK_BITS(LOOPBACK_DISABLED, SSP_CR1_MASK_LBM, 0) | \ GEN_MASK_BITS(SSP_DISABLED, SSP_CR1_MASK_SSE, 1) | \ GEN_MASK_BITS(SSP_MASTER, SSP_CR1_MASK_MS, 2) | \ - GEN_MASK_BITS(DO_NOT_DRIVE_TX, SSP_CR1_MASK_SOD, 3) | \ - GEN_MASK_BITS(SSP_RX_MSB, SSP_CR1_MASK_RENDN, 4) | \ - GEN_MASK_BITS(SSP_TX_MSB, SSP_CR1_MASK_TENDN, 5) | \ - GEN_MASK_BITS(SSP_MWIRE_WAIT_ZERO, SSP_CR1_MASK_MWAIT, 6) |\ - GEN_MASK_BITS(SSP_RX_1_OR_MORE_ELEM, SSP_CR1_MASK_RXIFLSEL, 7) | \ - GEN_MASK_BITS(SSP_TX_1_OR_MORE_EMPTY_LOC, SSP_CR1_MASK_TXIFLSEL, 10) \ + GEN_MASK_BITS(DO_NOT_DRIVE_TX, SSP_CR1_MASK_SOD, 3) \ ) +/* ST versions extend this register to use all 16 bits */ +#define DEFAULT_SSP_REG_CR1_ST ( \ + DEFAULT_SSP_REG_CR1 | \ + GEN_MASK_BITS(SSP_RX_MSB, SSP_CR1_MASK_RENDN_ST, 4) | \ + GEN_MASK_BITS(SSP_TX_MSB, SSP_CR1_MASK_TENDN_ST, 5) | \ + GEN_MASK_BITS(SSP_MWIRE_WAIT_ZERO, SSP_CR1_MASK_MWAIT_ST, 6) |\ + GEN_MASK_BITS(SSP_RX_1_OR_MORE_ELEM, SSP_CR1_MASK_RXIFLSEL_ST, 7) | \ + GEN_MASK_BITS(SSP_TX_1_OR_MORE_EMPTY_LOC, SSP_CR1_MASK_TXIFLSEL_ST, 10) \ +) + + #define DEFAULT_SSP_REG_CPSR ( \ - GEN_MASK_BITS(NMDK_SSP_DEFAULT_PRESCALE, SSP_CPSR_MASK_CPSDVSR, 0) \ + GEN_MASK_BITS(SSP_DEFAULT_PRESCALE, SSP_CPSR_MASK_CPSDVSR, 0) \ ) #define DEFAULT_SSP_REG_DMACR (\ @@ -567,8 +598,13 @@ static void restore_state(struct pl022 *pl022) static void load_ssp_default_config(struct pl022 *pl022) { - writew(DEFAULT_SSP_REG_CR0, SSP_CR0(pl022->virtbase)); - writew(DEFAULT_SSP_REG_CR1, SSP_CR1(pl022->virtbase)); + if (pl022->vendor->extended_cr) { + writel(DEFAULT_SSP_REG_CR0_ST, SSP_CR0(pl022->virtbase)); + writew(DEFAULT_SSP_REG_CR1_ST, SSP_CR1(pl022->virtbase)); + } else { + writew(DEFAULT_SSP_REG_CR0, SSP_CR0(pl022->virtbase)); + writew(DEFAULT_SSP_REG_CR1, SSP_CR1(pl022->virtbase)); + } writew(DEFAULT_SSP_REG_DMACR, SSP_DMACR(pl022->virtbase)); writew(DEFAULT_SSP_REG_CPSR, SSP_CPSR(pl022->virtbase)); writew(DISABLE_ALL_INTERRUPTS, SSP_IMSC(pl022->virtbase)); @@ -1008,7 +1044,7 @@ static void do_polling_transfer(void *data) writew((readw(SSP_CR1(pl022->virtbase)) | SSP_CR1_MASK_SSE), SSP_CR1(pl022->virtbase)); - dev_dbg(&pl022->adev->dev, "POLLING TRANSFER ONGOING ... \n"); + dev_dbg(&pl022->adev->dev, "polling transfer ongoing ...\n"); /* FIXME: insert a timeout so we don't hang here indefinately */ while (pl022->tx < pl022->tx_end || pl022->rx < pl022->rx_end) readwriter(pl022); @@ -1280,11 +1316,21 @@ static int verify_controller_parameters(struct pl022 *pl022, "Wait State is configured incorrectly\n"); return -EINVAL; } - if ((chip_info->duplex != SSP_MICROWIRE_CHANNEL_FULL_DUPLEX) - && (chip_info->duplex != - SSP_MICROWIRE_CHANNEL_HALF_DUPLEX)) { - dev_err(chip_info->dev, - "DUPLEX is configured incorrectly\n"); + /* Half duplex is only available in the ST Micro version */ + if (pl022->vendor->extended_cr) { + if ((chip_info->duplex != + SSP_MICROWIRE_CHANNEL_FULL_DUPLEX) + && (chip_info->duplex != + SSP_MICROWIRE_CHANNEL_HALF_DUPLEX)) + dev_err(chip_info->dev, + "Microwire duplex mode is configured incorrectly\n"); + return -EINVAL; + } else { + if (chip_info->duplex != SSP_MICROWIRE_CHANNEL_FULL_DUPLEX) + dev_err(chip_info->dev, + "Microwire half duplex mode requested," + " but this is only available in the" + " ST version of PL022\n"); return -EINVAL; } } @@ -1581,22 +1627,40 @@ static int pl022_setup(struct spi_device *spi) chip->cpsr = chip_info->clk_freq.cpsdvsr; - SSP_WRITE_BITS(chip->cr0, chip_info->data_size, SSP_CR0_MASK_DSS, 0); - SSP_WRITE_BITS(chip->cr0, chip_info->duplex, SSP_CR0_MASK_HALFDUP, 5); + /* Special setup for the ST micro extended control registers */ + if (pl022->vendor->extended_cr) { + SSP_WRITE_BITS(chip->cr0, chip_info->data_size, + SSP_CR0_MASK_DSS_ST, 0); + SSP_WRITE_BITS(chip->cr0, chip_info->duplex, + SSP_CR0_MASK_HALFDUP_ST, 5); + SSP_WRITE_BITS(chip->cr0, chip_info->ctrl_len, + SSP_CR0_MASK_CSS_ST, 16); + SSP_WRITE_BITS(chip->cr0, chip_info->iface, + SSP_CR0_MASK_FRF_ST, 21); + SSP_WRITE_BITS(chip->cr1, chip_info->endian_rx, + SSP_CR1_MASK_RENDN_ST, 4); + SSP_WRITE_BITS(chip->cr1, chip_info->endian_tx, + SSP_CR1_MASK_TENDN_ST, 5); + SSP_WRITE_BITS(chip->cr1, chip_info->wait_state, + SSP_CR1_MASK_MWAIT_ST, 6); + SSP_WRITE_BITS(chip->cr1, chip_info->rx_lev_trig, + SSP_CR1_MASK_RXIFLSEL_ST, 7); + SSP_WRITE_BITS(chip->cr1, chip_info->tx_lev_trig, + SSP_CR1_MASK_TXIFLSEL_ST, 10); + } else { + SSP_WRITE_BITS(chip->cr0, chip_info->data_size, + SSP_CR0_MASK_DSS, 0); + SSP_WRITE_BITS(chip->cr0, chip_info->iface, + SSP_CR0_MASK_FRF, 4); + } + /* Stuff that is common for all versions */ SSP_WRITE_BITS(chip->cr0, chip_info->clk_pol, SSP_CR0_MASK_SPO, 6); SSP_WRITE_BITS(chip->cr0, chip_info->clk_phase, SSP_CR0_MASK_SPH, 7); SSP_WRITE_BITS(chip->cr0, chip_info->clk_freq.scr, SSP_CR0_MASK_SCR, 8); - SSP_WRITE_BITS(chip->cr0, chip_info->ctrl_len, SSP_CR0_MASK_CSS, 16); - SSP_WRITE_BITS(chip->cr0, chip_info->iface, SSP_CR0_MASK_FRF, 21); SSP_WRITE_BITS(chip->cr1, chip_info->lbm, SSP_CR1_MASK_LBM, 0); SSP_WRITE_BITS(chip->cr1, SSP_DISABLED, SSP_CR1_MASK_SSE, 1); SSP_WRITE_BITS(chip->cr1, chip_info->hierarchy, SSP_CR1_MASK_MS, 2); SSP_WRITE_BITS(chip->cr1, chip_info->slave_tx_disable, SSP_CR1_MASK_SOD, 3); - SSP_WRITE_BITS(chip->cr1, chip_info->endian_rx, SSP_CR1_MASK_RENDN, 4); - SSP_WRITE_BITS(chip->cr1, chip_info->endian_tx, SSP_CR1_MASK_TENDN, 5); - SSP_WRITE_BITS(chip->cr1, chip_info->wait_state, SSP_CR1_MASK_MWAIT, 6); - SSP_WRITE_BITS(chip->cr1, chip_info->rx_lev_trig, SSP_CR1_MASK_RXIFLSEL, 7); - SSP_WRITE_BITS(chip->cr1, chip_info->tx_lev_trig, SSP_CR1_MASK_TXIFLSEL, 10); /* Save controller_state */ spi_set_ctldata(spi, chip); @@ -1809,6 +1873,7 @@ static struct vendor_data vendor_arm = { .fifodepth = 8, .max_bpw = 16, .unidir = false, + .extended_cr = false, }; @@ -1816,6 +1881,7 @@ static struct vendor_data vendor_st = { .fifodepth = 32, .max_bpw = 32, .unidir = false, + .extended_cr = true, }; static struct amba_id pl022_ids[] = { diff --git a/include/linux/amba/pl022.h b/include/linux/amba/pl022.h index e4836c6b3dd7..612f39913340 100644 --- a/include/linux/amba/pl022.h +++ b/include/linux/amba/pl022.h @@ -71,6 +71,7 @@ struct ssp_clock_params { /** * enum ssp_rx_endian - endianess of Rx FIFO Data + * this feature is only available in ST versionf of PL022 */ enum ssp_rx_endian { SSP_RX_MSB, @@ -181,7 +182,8 @@ enum ssp_microwire_wait_state { }; /** - * enum Microwire - whether Full/Half Duplex + * enum Microwire - whether Full/Half Duplex, only available + * in the ST Micro variant. * @SSP_MICROWIRE_CHANNEL_FULL_DUPLEX: SSPTXD becomes bi-directional, * SSPRXD not used * @SSP_MICROWIRE_CHANNEL_HALF_DUPLEX: SSPTXD is an output, SSPRXD is -- cgit v1.2.3 From 781c7b129b1beb876905f7212927aa0ee1b022e5 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 7 May 2010 08:40:53 +0000 Subject: spi/pl022: add support for the PL023 derivate This adds support for a further ST variant of the PL022 called PL023. Some differences in the control registers due to being stripped down to SPI mode only, and a new clock feedback sample delay config setting is available. Signed-off-by: Linus Walleij Signed-off-by: Grant Likely --- drivers/spi/amba-pl022.c | 90 +++++++++++++++++++++++++++++++++++++--------- include/linux/amba/pl022.h | 32 +++++++++++++++-- 2 files changed, 104 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c index 65092171cec3..c75831c1deda 100644 --- a/drivers/spi/amba-pl022.c +++ b/drivers/spi/amba-pl022.c @@ -135,6 +135,8 @@ #define SSP_CR1_MASK_MWAIT_ST (0x1UL << 6) #define SSP_CR1_MASK_RXIFLSEL_ST (0x7UL << 7) #define SSP_CR1_MASK_TXIFLSEL_ST (0x7UL << 10) +/* This one is only in the PL023 variant */ +#define SSP_CR1_MASK_FBCLKDEL_ST (0x7UL << 13) /* * SSP Status Register - SSP_SR @@ -317,12 +319,14 @@ enum ssp_writing { * @unidir: supports unidirection transfers * @extended_cr: 32 bit wide control register 0 with extra * features and extra features in CR1 as found in the ST variants + * @pl023: supports a subset of the ST extensions called "PL023" */ struct vendor_data { int fifodepth; int max_bpw; bool unidir; bool extended_cr; + bool pl023; }; /** @@ -541,11 +545,6 @@ static void restore_state(struct pl022 *pl022) writew(CLEAR_ALL_INTERRUPTS, SSP_ICR(pl022->virtbase)); } -/** - * load_ssp_default_config - Load default configuration for SSP - * @pl022: SSP driver private data structure - */ - /* * Default SSP Register Values */ @@ -568,6 +567,14 @@ static void restore_state(struct pl022 *pl022) GEN_MASK_BITS(SSP_INTERFACE_MOTOROLA_SPI, SSP_CR0_MASK_FRF_ST, 21) \ ) +/* The PL023 version is slightly different again */ +#define DEFAULT_SSP_REG_CR0_ST_PL023 ( \ + GEN_MASK_BITS(SSP_DATA_BITS_12, SSP_CR0_MASK_DSS_ST, 0) | \ + GEN_MASK_BITS(SSP_CLK_POL_IDLE_LOW, SSP_CR0_MASK_SPO, 6) | \ + GEN_MASK_BITS(SSP_CLK_SECOND_EDGE, SSP_CR0_MASK_SPH, 7) | \ + GEN_MASK_BITS(SSP_DEFAULT_CLKRATE, SSP_CR0_MASK_SCR, 8) \ +) + #define DEFAULT_SSP_REG_CR1 ( \ GEN_MASK_BITS(LOOPBACK_DISABLED, SSP_CR1_MASK_LBM, 0) | \ GEN_MASK_BITS(SSP_DISABLED, SSP_CR1_MASK_SSE, 1) | \ @@ -585,6 +592,20 @@ static void restore_state(struct pl022 *pl022) GEN_MASK_BITS(SSP_TX_1_OR_MORE_EMPTY_LOC, SSP_CR1_MASK_TXIFLSEL_ST, 10) \ ) +/* + * The PL023 variant has further differences: no loopback mode, no microwire + * support, and a new clock feedback delay setting. + */ +#define DEFAULT_SSP_REG_CR1_ST_PL023 ( \ + GEN_MASK_BITS(SSP_DISABLED, SSP_CR1_MASK_SSE, 1) | \ + GEN_MASK_BITS(SSP_MASTER, SSP_CR1_MASK_MS, 2) | \ + GEN_MASK_BITS(DO_NOT_DRIVE_TX, SSP_CR1_MASK_SOD, 3) | \ + GEN_MASK_BITS(SSP_RX_MSB, SSP_CR1_MASK_RENDN_ST, 4) | \ + GEN_MASK_BITS(SSP_TX_MSB, SSP_CR1_MASK_TENDN_ST, 5) | \ + GEN_MASK_BITS(SSP_RX_1_OR_MORE_ELEM, SSP_CR1_MASK_RXIFLSEL_ST, 7) | \ + GEN_MASK_BITS(SSP_TX_1_OR_MORE_EMPTY_LOC, SSP_CR1_MASK_TXIFLSEL_ST, 10) | \ + GEN_MASK_BITS(SSP_FEEDBACK_CLK_DELAY_NONE, SSP_CR1_MASK_FBCLKDEL_ST, 13) \ +) #define DEFAULT_SSP_REG_CPSR ( \ GEN_MASK_BITS(SSP_DEFAULT_PRESCALE, SSP_CPSR_MASK_CPSDVSR, 0) \ @@ -595,10 +616,16 @@ static void restore_state(struct pl022 *pl022) GEN_MASK_BITS(SSP_DMA_DISABLED, SSP_DMACR_MASK_TXDMAE, 1) \ ) - +/** + * load_ssp_default_config - Load default configuration for SSP + * @pl022: SSP driver private data structure + */ static void load_ssp_default_config(struct pl022 *pl022) { - if (pl022->vendor->extended_cr) { + if (pl022->vendor->pl023) { + writel(DEFAULT_SSP_REG_CR0_ST_PL023, SSP_CR0(pl022->virtbase)); + writew(DEFAULT_SSP_REG_CR1_ST_PL023, SSP_CR1(pl022->virtbase)); + } else if (pl022->vendor->extended_cr) { writel(DEFAULT_SSP_REG_CR0_ST, SSP_CR0(pl022->virtbase)); writew(DEFAULT_SSP_REG_CR1_ST, SSP_CR1(pl022->virtbase)); } else { @@ -1629,20 +1656,27 @@ static int pl022_setup(struct spi_device *spi) /* Special setup for the ST micro extended control registers */ if (pl022->vendor->extended_cr) { + if (pl022->vendor->pl023) { + /* These bits are only in the PL023 */ + SSP_WRITE_BITS(chip->cr1, chip_info->clkdelay, + SSP_CR1_MASK_FBCLKDEL_ST, 13); + } else { + /* These bits are in the PL022 but not PL023 */ + SSP_WRITE_BITS(chip->cr0, chip_info->duplex, + SSP_CR0_MASK_HALFDUP_ST, 5); + SSP_WRITE_BITS(chip->cr0, chip_info->ctrl_len, + SSP_CR0_MASK_CSS_ST, 16); + SSP_WRITE_BITS(chip->cr0, chip_info->iface, + SSP_CR0_MASK_FRF_ST, 21); + SSP_WRITE_BITS(chip->cr1, chip_info->wait_state, + SSP_CR1_MASK_MWAIT_ST, 6); + } SSP_WRITE_BITS(chip->cr0, chip_info->data_size, SSP_CR0_MASK_DSS_ST, 0); - SSP_WRITE_BITS(chip->cr0, chip_info->duplex, - SSP_CR0_MASK_HALFDUP_ST, 5); - SSP_WRITE_BITS(chip->cr0, chip_info->ctrl_len, - SSP_CR0_MASK_CSS_ST, 16); - SSP_WRITE_BITS(chip->cr0, chip_info->iface, - SSP_CR0_MASK_FRF_ST, 21); SSP_WRITE_BITS(chip->cr1, chip_info->endian_rx, SSP_CR1_MASK_RENDN_ST, 4); SSP_WRITE_BITS(chip->cr1, chip_info->endian_tx, SSP_CR1_MASK_TENDN_ST, 5); - SSP_WRITE_BITS(chip->cr1, chip_info->wait_state, - SSP_CR1_MASK_MWAIT_ST, 6); SSP_WRITE_BITS(chip->cr1, chip_info->rx_lev_trig, SSP_CR1_MASK_RXIFLSEL_ST, 7); SSP_WRITE_BITS(chip->cr1, chip_info->tx_lev_trig, @@ -1657,7 +1691,9 @@ static int pl022_setup(struct spi_device *spi) SSP_WRITE_BITS(chip->cr0, chip_info->clk_pol, SSP_CR0_MASK_SPO, 6); SSP_WRITE_BITS(chip->cr0, chip_info->clk_phase, SSP_CR0_MASK_SPH, 7); SSP_WRITE_BITS(chip->cr0, chip_info->clk_freq.scr, SSP_CR0_MASK_SCR, 8); - SSP_WRITE_BITS(chip->cr1, chip_info->lbm, SSP_CR1_MASK_LBM, 0); + /* Loopback is available on all versions except PL023 */ + if (!pl022->vendor->pl023) + SSP_WRITE_BITS(chip->cr1, chip_info->lbm, SSP_CR1_MASK_LBM, 0); SSP_WRITE_BITS(chip->cr1, SSP_DISABLED, SSP_CR1_MASK_SSE, 1); SSP_WRITE_BITS(chip->cr1, chip_info->hierarchy, SSP_CR1_MASK_MS, 2); SSP_WRITE_BITS(chip->cr1, chip_info->slave_tx_disable, SSP_CR1_MASK_SOD, 3); @@ -1874,6 +1910,7 @@ static struct vendor_data vendor_arm = { .max_bpw = 16, .unidir = false, .extended_cr = false, + .pl023 = false, }; @@ -1882,6 +1919,15 @@ static struct vendor_data vendor_st = { .max_bpw = 32, .unidir = false, .extended_cr = true, + .pl023 = false, +}; + +static struct vendor_data vendor_st_pl023 = { + .fifodepth = 32, + .max_bpw = 32, + .unidir = false, + .extended_cr = true, + .pl023 = true, }; static struct amba_id pl022_ids[] = { @@ -1903,6 +1949,18 @@ static struct amba_id pl022_ids[] = { .mask = 0xffffffff, .data = &vendor_st, }, + { + /* + * ST-Ericsson derivative "PL023" (this is not + * an official ARM number), this is a PL022 SSP block + * stripped to SPI mode only, it has 32bit wide + * and 32 locations deep TX/RX FIFO but no extended + * CR0/CR1 register + */ + .id = 0x00080023, + .mask = 0xffffffff, + .data = &vendor_st_pl023, + }, { 0, 0 }, }; diff --git a/include/linux/amba/pl022.h b/include/linux/amba/pl022.h index 612f39913340..abf26cc47a2b 100644 --- a/include/linux/amba/pl022.h +++ b/include/linux/amba/pl022.h @@ -182,8 +182,8 @@ enum ssp_microwire_wait_state { }; /** - * enum Microwire - whether Full/Half Duplex, only available - * in the ST Micro variant. + * enum ssp_duplex - whether Full/Half Duplex on microwire, only + * available in the ST Micro variant. * @SSP_MICROWIRE_CHANNEL_FULL_DUPLEX: SSPTXD becomes bi-directional, * SSPRXD not used * @SSP_MICROWIRE_CHANNEL_HALF_DUPLEX: SSPTXD is an output, SSPRXD is @@ -194,6 +194,31 @@ enum ssp_duplex { SSP_MICROWIRE_CHANNEL_HALF_DUPLEX }; +/** + * enum ssp_clkdelay - an optional clock delay on the feedback clock + * only available in the ST Micro PL023 variant. + * @SSP_FEEDBACK_CLK_DELAY_NONE: no delay, the data coming in from the + * slave is sampled directly + * @SSP_FEEDBACK_CLK_DELAY_1T: the incoming slave data is sampled with + * a delay of T-dt + * @SSP_FEEDBACK_CLK_DELAY_2T: dito with a delay if 2T-dt + * @SSP_FEEDBACK_CLK_DELAY_3T: dito with a delay if 3T-dt + * @SSP_FEEDBACK_CLK_DELAY_4T: dito with a delay if 4T-dt + * @SSP_FEEDBACK_CLK_DELAY_5T: dito with a delay if 5T-dt + * @SSP_FEEDBACK_CLK_DELAY_6T: dito with a delay if 6T-dt + * @SSP_FEEDBACK_CLK_DELAY_7T: dito with a delay if 7T-dt + */ +enum ssp_clkdelay { + SSP_FEEDBACK_CLK_DELAY_NONE, + SSP_FEEDBACK_CLK_DELAY_1T, + SSP_FEEDBACK_CLK_DELAY_2T, + SSP_FEEDBACK_CLK_DELAY_3T, + SSP_FEEDBACK_CLK_DELAY_4T, + SSP_FEEDBACK_CLK_DELAY_5T, + SSP_FEEDBACK_CLK_DELAY_6T, + SSP_FEEDBACK_CLK_DELAY_7T +}; + /** * CHIP select/deselect commands */ @@ -237,6 +262,8 @@ struct pl022_ssp_controller { * @ctrl_len: Microwire interface: Control length * @wait_state: Microwire interface: Wait state * @duplex: Microwire interface: Full/Half duplex + * @clkdelay: on the PL023 variant, the delay in feeback clock cycles + * before sampling the incoming line * @cs_control: function pointer to board-specific function to * assert/deassert I/O port to control HW generation of devices chip-select. * @dma_xfer_type: Type of DMA xfer (Mem-to-periph or Periph-to-Periph) @@ -260,6 +287,7 @@ struct pl022_config_chip { enum ssp_microwire_ctrl_len ctrl_len; enum ssp_microwire_wait_state wait_state; enum ssp_duplex duplex; + enum ssp_clkdelay clkdelay; void (*cs_control) (u32 control); }; -- cgit v1.2.3 From 4a12404ddaa06e8ec5e2c0d8ece4d821281e6024 Mon Sep 17 00:00:00 2001 From: Grzegorz Sygieda Date: Thu, 20 May 2010 22:28:30 +0000 Subject: spi/pl022: fix stop queue procedure This fix prevents queue being marked as "stopped", if data exists in the queue list. Signed-off-by: Grzegorz Sygieda Signed-off-by: Lukasz Baj Signed-off-by: Linus Walleij Signed-off-by: Grant Likely --- drivers/spi/amba-pl022.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c index c75831c1deda..f0a1418ce660 100644 --- a/drivers/spi/amba-pl022.c +++ b/drivers/spi/amba-pl022.c @@ -1211,7 +1211,6 @@ static int stop_queue(struct pl022 *pl022) * A wait_queue on the pl022->busy could be used, but then the common * execution path (pump_messages) would be required to call wake_up or * friends on every SPI message. Do this instead */ - pl022->run = QUEUE_STOPPED; while (!list_empty(&pl022->queue) && pl022->busy && limit--) { spin_unlock_irqrestore(&pl022->queue_lock, flags); msleep(10); @@ -1220,6 +1219,7 @@ static int stop_queue(struct pl022 *pl022) if (!list_empty(&pl022->queue) || pl022->busy) status = -EBUSY; + else pl022->run = QUEUE_STOPPED; spin_unlock_irqrestore(&pl022->queue_lock, flags); -- cgit v1.2.3 From 8b66c13474e1683d53255f3b2948231b61cdaefd Mon Sep 17 00:00:00 2001 From: Roman Tereshonkov Date: Mon, 12 Apr 2010 09:07:54 +0000 Subject: spi/omap2_mcspi: change default DMA_MIN_BYTES value to 160 The value 160 has been obtained as optimal in testing it for wl1271 which use spi for communication. In some sense this change might also influence on other spi devices connected to omap2_mcspi controller. Signed-off-by: Roman Tereshonkov Signed-off-by: Grant Likely --- drivers/spi/omap2_mcspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index e0de0d0eedea..e6d08b844156 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c @@ -113,7 +113,7 @@ struct omap2_mcspi_dma { /* use PIO for small transfers, avoiding DMA setup/teardown overhead and * cache operations; better heuristics consider wordsize and bitrate. */ -#define DMA_MIN_BYTES 8 +#define DMA_MIN_BYTES 160 struct omap2_mcspi { -- cgit v1.2.3 From 4743a0f88c4000dfa3c422ecc4d750d3a3410550 Mon Sep 17 00:00:00 2001 From: Roman Tereshonkov Date: Tue, 13 Apr 2010 10:41:51 +0000 Subject: spi/omap2_mcspi: add turbo mode support Turbo mode allows to read data to shift register when rx-buffer is full thus improving the perfomance. This feature is available for RX-only mode. In PIO turbo mode when the penultimate word is available in RX-buffer the controller should be disabled before reading data to prevent the next transaction triggering. The controller itself handles the last word to be correctly loaded to shift-register and then transferred to RX-buffer. The turbo mode is enabled by setting turbo_mode parameter to 1. This parameter is a part of omap2_mcspi_device_config structure which is passed through the spi_device controller_data pointer. Signed-off-by: Roman Tereshonkov Signed-off-by: Grant Likely --- drivers/spi/omap2_mcspi.c | 132 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 111 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index e6d08b844156..6df85537bd19 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c @@ -38,7 +38,7 @@ #include #include - +#include #define OMAP2_MCSPI_MAX_FREQ 48000000 @@ -229,6 +229,8 @@ static void omap2_mcspi_set_enable(const struct spi_device *spi, int enable) l = enable ? OMAP2_MCSPI_CHCTRL_EN : 0; mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCTRL0, l); + /* Flash post-writes */ + mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCTRL0); } static void omap2_mcspi_force_cs(struct spi_device *spi, int cs_active) @@ -303,11 +305,14 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) unsigned int count, c; unsigned long base, tx_reg, rx_reg; int word_len, data_type, element_count; + int elements; + u32 l; u8 * rx; const u8 * tx; mcspi = spi_master_get_devdata(spi->master); mcspi_dma = &mcspi->dma_channels[spi->chip_select]; + l = mcspi_cached_chconf0(spi); count = xfer->len; c = count; @@ -346,8 +351,12 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) } if (rx != NULL) { + elements = element_count - 1; + if (l & OMAP2_MCSPI_CHCONF_TURBO) + elements--; + omap_set_dma_transfer_params(mcspi_dma->dma_rx_channel, - data_type, element_count - 1, 1, + data_type, elements, 1, OMAP_DMA_SYNC_ELEMENT, mcspi_dma->dma_rx_sync_dev, 1); @@ -379,17 +388,42 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) wait_for_completion(&mcspi_dma->dma_rx_completion); dma_unmap_single(NULL, xfer->rx_dma, count, DMA_FROM_DEVICE); omap2_mcspi_set_enable(spi, 0); + + if (l & OMAP2_MCSPI_CHCONF_TURBO) { + + if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0) + & OMAP2_MCSPI_CHSTAT_RXS)) { + u32 w; + + w = mcspi_read_cs_reg(spi, OMAP2_MCSPI_RX0); + if (word_len <= 8) + ((u8 *)xfer->rx_buf)[elements++] = w; + else if (word_len <= 16) + ((u16 *)xfer->rx_buf)[elements++] = w; + else /* word_len <= 32 */ + ((u32 *)xfer->rx_buf)[elements++] = w; + } else { + dev_err(&spi->dev, + "DMA RX penultimate word empty"); + count -= (word_len <= 8) ? 2 : + (word_len <= 16) ? 4 : + /* word_len <= 32 */ 8; + omap2_mcspi_set_enable(spi, 1); + return count; + } + } + if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0) & OMAP2_MCSPI_CHSTAT_RXS)) { u32 w; w = mcspi_read_cs_reg(spi, OMAP2_MCSPI_RX0); if (word_len <= 8) - ((u8 *)xfer->rx_buf)[element_count - 1] = w; + ((u8 *)xfer->rx_buf)[elements] = w; else if (word_len <= 16) - ((u16 *)xfer->rx_buf)[element_count - 1] = w; + ((u16 *)xfer->rx_buf)[elements] = w; else /* word_len <= 32 */ - ((u32 *)xfer->rx_buf)[element_count - 1] = w; + ((u32 *)xfer->rx_buf)[elements] = w; } else { dev_err(&spi->dev, "DMA RX last word empty"); count -= (word_len <= 8) ? 1 : @@ -433,7 +467,6 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) word_len = cs->word_len; l = mcspi_cached_chconf0(spi); - l &= ~OMAP2_MCSPI_CHCONF_TRM_MASK; /* We store the pre-calculated register addresses on stack to speed * up the transfer loop. */ @@ -468,11 +501,26 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) dev_err(&spi->dev, "RXS timed out\n"); goto out; } - /* prevent last RX_ONLY read from triggering - * more word i/o: switch to rx+tx - */ - if (c == 0 && tx == NULL) - mcspi_write_chconf0(spi, l); + + if (c == 1 && tx == NULL && + (l & OMAP2_MCSPI_CHCONF_TURBO)) { + omap2_mcspi_set_enable(spi, 0); + *rx++ = __raw_readl(rx_reg); +#ifdef VERBOSE + dev_dbg(&spi->dev, "read-%d %02x\n", + word_len, *(rx - 1)); +#endif + if (mcspi_wait_for_reg_bit(chstat_reg, + OMAP2_MCSPI_CHSTAT_RXS) < 0) { + dev_err(&spi->dev, + "RXS timed out\n"); + goto out; + } + c = 0; + } else if (c == 0 && tx == NULL) { + omap2_mcspi_set_enable(spi, 0); + } + *rx++ = __raw_readl(rx_reg); #ifdef VERBOSE dev_dbg(&spi->dev, "read-%d %02x\n", @@ -506,11 +554,26 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) dev_err(&spi->dev, "RXS timed out\n"); goto out; } - /* prevent last RX_ONLY read from triggering - * more word i/o: switch to rx+tx - */ - if (c == 0 && tx == NULL) - mcspi_write_chconf0(spi, l); + + if (c == 2 && tx == NULL && + (l & OMAP2_MCSPI_CHCONF_TURBO)) { + omap2_mcspi_set_enable(spi, 0); + *rx++ = __raw_readl(rx_reg); +#ifdef VERBOSE + dev_dbg(&spi->dev, "read-%d %04x\n", + word_len, *(rx - 1)); +#endif + if (mcspi_wait_for_reg_bit(chstat_reg, + OMAP2_MCSPI_CHSTAT_RXS) < 0) { + dev_err(&spi->dev, + "RXS timed out\n"); + goto out; + } + c = 0; + } else if (c == 0 && tx == NULL) { + omap2_mcspi_set_enable(spi, 0); + } + *rx++ = __raw_readl(rx_reg); #ifdef VERBOSE dev_dbg(&spi->dev, "read-%d %04x\n", @@ -544,11 +607,26 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) dev_err(&spi->dev, "RXS timed out\n"); goto out; } - /* prevent last RX_ONLY read from triggering - * more word i/o: switch to rx+tx - */ - if (c == 0 && tx == NULL) - mcspi_write_chconf0(spi, l); + + if (c == 4 && tx == NULL && + (l & OMAP2_MCSPI_CHCONF_TURBO)) { + omap2_mcspi_set_enable(spi, 0); + *rx++ = __raw_readl(rx_reg); +#ifdef VERBOSE + dev_dbg(&spi->dev, "read-%d %08x\n", + word_len, *(rx - 1)); +#endif + if (mcspi_wait_for_reg_bit(chstat_reg, + OMAP2_MCSPI_CHSTAT_RXS) < 0) { + dev_err(&spi->dev, + "RXS timed out\n"); + goto out; + } + c = 0; + } else if (c == 0 && tx == NULL) { + omap2_mcspi_set_enable(spi, 0); + } + *rx++ = __raw_readl(rx_reg); #ifdef VERBOSE dev_dbg(&spi->dev, "read-%d %08x\n", @@ -568,6 +646,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) dev_err(&spi->dev, "EOT timed out\n"); } out: + omap2_mcspi_set_enable(spi, 1); return count - c; } @@ -797,6 +876,7 @@ static void omap2_mcspi_work(struct work_struct *work) struct spi_transfer *t = NULL; int cs_active = 0; struct omap2_mcspi_cs *cs; + struct omap2_mcspi_device_config *cd; int par_override = 0; int status = 0; u32 chconf; @@ -809,6 +889,7 @@ static void omap2_mcspi_work(struct work_struct *work) spi = m->spi; cs = spi->controller_state; + cd = spi->controller_data; omap2_mcspi_set_enable(spi, 1); list_for_each_entry(t, &m->transfers, transfer_list) { @@ -832,10 +913,19 @@ static void omap2_mcspi_work(struct work_struct *work) chconf = mcspi_cached_chconf0(spi); chconf &= ~OMAP2_MCSPI_CHCONF_TRM_MASK; + chconf &= ~OMAP2_MCSPI_CHCONF_TURBO; + if (t->tx_buf == NULL) chconf |= OMAP2_MCSPI_CHCONF_TRM_RX_ONLY; else if (t->rx_buf == NULL) chconf |= OMAP2_MCSPI_CHCONF_TRM_TX_ONLY; + + if (cd && cd->turbo_mode && t->tx_buf == NULL) { + /* Turbo mode is for more than one word */ + if (t->len > ((cs->word_len + 7) >> 3)) + chconf |= OMAP2_MCSPI_CHCONF_TURBO; + } + mcspi_write_chconf0(spi, chconf); if (t->len) { -- cgit v1.2.3 From 99f1a43f436a6a92d15bddfeb65f3a920c8b88d3 Mon Sep 17 00:00:00 2001 From: Scott Ellis Date: Mon, 24 May 2010 14:20:27 +0000 Subject: spi/omap2_mcspi: Check params before dereference or use Check spi->chip_select for range before use. Signed-off-by: Scott Ellis Signed-off-by: Grant Likely --- drivers/spi/omap2_mcspi.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index 6df85537bd19..b3a94ca0a75a 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c @@ -834,7 +834,6 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) struct omap2_mcspi_cs *cs; mcspi = spi_master_get_devdata(spi->master); - mcspi_dma = &mcspi->dma_channels[spi->chip_select]; if (spi->controller_state) { /* Unlink controller state from context save list */ @@ -844,13 +843,17 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) kfree(spi->controller_state); } - if (mcspi_dma->dma_rx_channel != -1) { - omap_free_dma(mcspi_dma->dma_rx_channel); - mcspi_dma->dma_rx_channel = -1; - } - if (mcspi_dma->dma_tx_channel != -1) { - omap_free_dma(mcspi_dma->dma_tx_channel); - mcspi_dma->dma_tx_channel = -1; + if (spi->chip_select < spi->master->num_chipselect) { + mcspi_dma = &mcspi->dma_channels[spi->chip_select]; + + if (mcspi_dma->dma_rx_channel != -1) { + omap_free_dma(mcspi_dma->dma_rx_channel); + mcspi_dma->dma_rx_channel = -1; + } + if (mcspi_dma->dma_tx_channel != -1) { + omap_free_dma(mcspi_dma->dma_tx_channel); + mcspi_dma->dma_tx_channel = -1; + } } } -- cgit v1.2.3 From 011f23a3c2f20ae15b7664d3942493af107fe39b Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 6 May 2010 04:47:04 +0000 Subject: spi/ep93xx: implemented driver for Cirrus EP93xx SPI controller This patch adds an SPI master driver for the Cirrus EP93xx SPI controller found in EP93xx chips. Signed-off-by: Mika Westerberg Signed-off-by: H Hartley Sweeten Acked-by: H Hartley Sweeten Signed-off-by: Grant Likely --- Documentation/spi/ep93xx_spi | 95 +++ arch/arm/mach-ep93xx/include/mach/ep93xx_spi.h | 27 + drivers/spi/Kconfig | 10 + drivers/spi/Makefile | 1 + drivers/spi/ep93xx_spi.c | 938 +++++++++++++++++++++++++ 5 files changed, 1071 insertions(+) create mode 100644 Documentation/spi/ep93xx_spi create mode 100644 arch/arm/mach-ep93xx/include/mach/ep93xx_spi.h create mode 100644 drivers/spi/ep93xx_spi.c (limited to 'drivers') diff --git a/Documentation/spi/ep93xx_spi b/Documentation/spi/ep93xx_spi new file mode 100644 index 000000000000..6325f5b48635 --- /dev/null +++ b/Documentation/spi/ep93xx_spi @@ -0,0 +1,95 @@ +Cirrus EP93xx SPI controller driver HOWTO +========================================= + +ep93xx_spi driver brings SPI master support for EP93xx SPI controller. Chip +selects are implemented with GPIO lines. + +NOTE: If possible, don't use SFRMOUT (SFRM1) signal as a chip select. It will +not work correctly (it cannot be controlled by software). Use GPIO lines +instead. + +Sample configuration +==================== + +Typically driver configuration is done in platform board files (the files under +arch/arm/mach-ep93xx/*.c). In this example we configure MMC over SPI through +this driver on TS-7260 board. You can adapt the code to suit your needs. + +This example uses EGPIO9 as SD/MMC card chip select (this is wired in DIO1 +header on the board). + +You need to select CONFIG_MMC_SPI to use mmc_spi driver. + +arch/arm/mach-ep93xx/ts72xx.c: + +... +#include +#include + +#include + +/* this is our GPIO line used for chip select */ +#define MMC_CHIP_SELECT_GPIO EP93XX_GPIO_LINE_EGPIO9 + +static int ts72xx_mmc_spi_setup(struct spi_device *spi) +{ + int err; + + err = gpio_request(MMC_CHIP_SELECT_GPIO, spi->modalias); + if (err) + return err; + + gpio_direction_output(MMC_CHIP_SELECT_GPIO, 1); + + return 0; +} + +static void ts72xx_mmc_spi_cleanup(struct spi_device *spi) +{ + gpio_set_value(MMC_CHIP_SELECT_GPIO, 1); + gpio_direction_input(MMC_CHIP_SELECT_GPIO); + gpio_free(MMC_CHIP_SELECT_GPIO); +} + +static void ts72xx_mmc_spi_cs_control(struct spi_device *spi, int value) +{ + gpio_set_value(MMC_CHIP_SELECT_GPIO, value); +} + +static struct ep93xx_spi_chip_ops ts72xx_mmc_spi_ops = { + .setup = ts72xx_mmc_spi_setup, + .cleanup = ts72xx_mmc_spi_cleanup, + .cs_control = ts72xx_mmc_spi_cs_control, +}; + +static struct spi_board_info ts72xx_spi_devices[] __initdata = { + { + .modalias = "mmc_spi", + .controller_data = &ts72xx_mmc_spi_ops, + /* + * We use 10 MHz even though the maximum is 7.4 MHz. The driver + * will limit it automatically to max. frequency. + */ + .max_speed_hz = 10 * 1000 * 1000, + .bus_num = 0, + .chip_select = 0, + .mode = SPI_MODE_0, + }, +}; + +static struct ep93xx_spi_info ts72xx_spi_info = { + .num_chipselect = ARRAY_SIZE(ts72xx_spi_devices), +}; + +static void __init ts72xx_init_machine(void) +{ + ... + ep93xx_register_spi(&ts72xx_spi_info, ts72xx_spi_devices, + ARRAY_SIZE(ts72xx_spi_devices)); +} + +Thanks to +========= +Martin Guy, H. Hartley Sweeten and others who helped me during development of +the driver. Simplemachines.it donated me a Sim.One board which I used testing +the driver on EP9307. diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx_spi.h b/arch/arm/mach-ep93xx/include/mach/ep93xx_spi.h new file mode 100644 index 000000000000..0a37961b3453 --- /dev/null +++ b/arch/arm/mach-ep93xx/include/mach/ep93xx_spi.h @@ -0,0 +1,27 @@ +#ifndef __ASM_MACH_EP93XX_SPI_H +#define __ASM_MACH_EP93XX_SPI_H + +struct spi_device; + +/** + * struct ep93xx_spi_info - EP93xx specific SPI descriptor + * @num_chipselect: number of chip selects on this board, must be + * at least one + */ +struct ep93xx_spi_info { + int num_chipselect; +}; + +/** + * struct ep93xx_spi_chip_ops - operation callbacks for SPI slave device + * @setup: setup the chip select mechanism + * @cleanup: cleanup the chip select mechanism + * @cs_control: control the device chip select + */ +struct ep93xx_spi_chip_ops { + int (*setup)(struct spi_device *spi); + void (*cleanup)(struct spi_device *spi); + void (*cs_control)(struct spi_device *spi, int value); +}; + +#endif /* __ASM_MACH_EP93XX_SPI_H */ diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index a191fa2be7c5..2b2f4c3b6b62 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -117,6 +117,16 @@ config SPI_DAVINCI help SPI master controller for DaVinci and DA8xx SPI modules. +config SPI_EP93XX + tristate "Cirrus Logic EP93xx SPI controller" + depends on ARCH_EP93XX + help + This enables using the Cirrus EP93xx SPI controller in master + mode. + + To compile this driver as a module, choose M here. The module will be + called ep93xx_spi. + config SPI_GPIO tristate "GPIO-based bitbanging SPI Master" depends on GENERIC_GPIO diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index d7d0f89b797b..377f8455208d 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_SPI_DAVINCI) += davinci_spi.o obj-$(CONFIG_SPI_DESIGNWARE) += dw_spi.o obj-$(CONFIG_SPI_DW_PCI) += dw_spi_pci.o obj-$(CONFIG_SPI_DW_MMIO) += dw_spi_mmio.o +obj-$(CONFIG_SPI_EP93XX) += ep93xx_spi.o obj-$(CONFIG_SPI_GPIO) += spi_gpio.o obj-$(CONFIG_SPI_IMX) += spi_imx.o obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o diff --git a/drivers/spi/ep93xx_spi.c b/drivers/spi/ep93xx_spi.c new file mode 100644 index 000000000000..0ba35df9a6df --- /dev/null +++ b/drivers/spi/ep93xx_spi.c @@ -0,0 +1,938 @@ +/* + * Driver for Cirrus Logic EP93xx SPI controller. + * + * Copyright (c) 2010 Mika Westerberg + * + * Explicit FIFO handling code was inspired by amba-pl022 driver. + * + * Chip select support using other than built-in GPIOs by H. Hartley Sweeten. + * + * For more information about the SPI controller see documentation on Cirrus + * Logic web site: + * http://www.cirrus.com/en/pubs/manual/EP93xx_Users_Guide_UM1.pdf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define SSPCR0 0x0000 +#define SSPCR0_MODE_SHIFT 6 +#define SSPCR0_SCR_SHIFT 8 + +#define SSPCR1 0x0004 +#define SSPCR1_RIE BIT(0) +#define SSPCR1_TIE BIT(1) +#define SSPCR1_RORIE BIT(2) +#define SSPCR1_LBM BIT(3) +#define SSPCR1_SSE BIT(4) +#define SSPCR1_MS BIT(5) +#define SSPCR1_SOD BIT(6) + +#define SSPDR 0x0008 + +#define SSPSR 0x000c +#define SSPSR_TFE BIT(0) +#define SSPSR_TNF BIT(1) +#define SSPSR_RNE BIT(2) +#define SSPSR_RFF BIT(3) +#define SSPSR_BSY BIT(4) +#define SSPCPSR 0x0010 + +#define SSPIIR 0x0014 +#define SSPIIR_RIS BIT(0) +#define SSPIIR_TIS BIT(1) +#define SSPIIR_RORIS BIT(2) +#define SSPICR SSPIIR + +/* timeout in milliseconds */ +#define SPI_TIMEOUT 5 +/* maximum depth of RX/TX FIFO */ +#define SPI_FIFO_SIZE 8 + +/** + * struct ep93xx_spi - EP93xx SPI controller structure + * @lock: spinlock that protects concurrent accesses to fields @running, + * @current_msg and @msg_queue + * @pdev: pointer to platform device + * @clk: clock for the controller + * @regs_base: pointer to ioremap()'d registers + * @irq: IRQ number used by the driver + * @min_rate: minimum clock rate (in Hz) supported by the controller + * @max_rate: maximum clock rate (in Hz) supported by the controller + * @running: is the queue running + * @wq: workqueue used by the driver + * @msg_work: work that is queued for the driver + * @wait: wait here until given transfer is completed + * @msg_queue: queue for the messages + * @current_msg: message that is currently processed (or %NULL if none) + * @tx: current byte in transfer to transmit + * @rx: current byte in transfer to receive + * @fifo_level: how full is FIFO (%0..%SPI_FIFO_SIZE - %1). Receiving one + * frame decreases this level and sending one frame increases it. + * + * This structure holds EP93xx SPI controller specific information. When + * @running is %true, driver accepts transfer requests from protocol drivers. + * @current_msg is used to hold pointer to the message that is currently + * processed. If @current_msg is %NULL, it means that no processing is going + * on. + * + * Most of the fields are only written once and they can be accessed without + * taking the @lock. Fields that are accessed concurrently are: @current_msg, + * @running, and @msg_queue. + */ +struct ep93xx_spi { + spinlock_t lock; + const struct platform_device *pdev; + struct clk *clk; + void __iomem *regs_base; + int irq; + unsigned long min_rate; + unsigned long max_rate; + bool running; + struct workqueue_struct *wq; + struct work_struct msg_work; + struct completion wait; + struct list_head msg_queue; + struct spi_message *current_msg; + size_t tx; + size_t rx; + size_t fifo_level; +}; + +/** + * struct ep93xx_spi_chip - SPI device hardware settings + * @spi: back pointer to the SPI device + * @rate: max rate in hz this chip supports + * @div_cpsr: cpsr (pre-scaler) divider + * @div_scr: scr divider + * @dss: bits per word (4 - 16 bits) + * @ops: private chip operations + * + * This structure is used to store hardware register specific settings for each + * SPI device. Settings are written to hardware by function + * ep93xx_spi_chip_setup(). + */ +struct ep93xx_spi_chip { + const struct spi_device *spi; + unsigned long rate; + u8 div_cpsr; + u8 div_scr; + u8 dss; + struct ep93xx_spi_chip_ops *ops; +}; + +/* converts bits per word to CR0.DSS value */ +#define bits_per_word_to_dss(bpw) ((bpw) - 1) + +static inline void +ep93xx_spi_write_u8(const struct ep93xx_spi *espi, u16 reg, u8 value) +{ + __raw_writeb(value, espi->regs_base + reg); +} + +static inline u8 +ep93xx_spi_read_u8(const struct ep93xx_spi *spi, u16 reg) +{ + return __raw_readb(spi->regs_base + reg); +} + +static inline void +ep93xx_spi_write_u16(const struct ep93xx_spi *espi, u16 reg, u16 value) +{ + __raw_writew(value, espi->regs_base + reg); +} + +static inline u16 +ep93xx_spi_read_u16(const struct ep93xx_spi *spi, u16 reg) +{ + return __raw_readw(spi->regs_base + reg); +} + +static int ep93xx_spi_enable(const struct ep93xx_spi *espi) +{ + u8 regval; + int err; + + err = clk_enable(espi->clk); + if (err) + return err; + + regval = ep93xx_spi_read_u8(espi, SSPCR1); + regval |= SSPCR1_SSE; + ep93xx_spi_write_u8(espi, SSPCR1, regval); + + return 0; +} + +static void ep93xx_spi_disable(const struct ep93xx_spi *espi) +{ + u8 regval; + + regval = ep93xx_spi_read_u8(espi, SSPCR1); + regval &= ~SSPCR1_SSE; + ep93xx_spi_write_u8(espi, SSPCR1, regval); + + clk_disable(espi->clk); +} + +static void ep93xx_spi_enable_interrupts(const struct ep93xx_spi *espi) +{ + u8 regval; + + regval = ep93xx_spi_read_u8(espi, SSPCR1); + regval |= (SSPCR1_RORIE | SSPCR1_TIE | SSPCR1_RIE); + ep93xx_spi_write_u8(espi, SSPCR1, regval); +} + +static void ep93xx_spi_disable_interrupts(const struct ep93xx_spi *espi) +{ + u8 regval; + + regval = ep93xx_spi_read_u8(espi, SSPCR1); + regval &= ~(SSPCR1_RORIE | SSPCR1_TIE | SSPCR1_RIE); + ep93xx_spi_write_u8(espi, SSPCR1, regval); +} + +/** + * ep93xx_spi_calc_divisors() - calculates SPI clock divisors + * @espi: ep93xx SPI controller struct + * @chip: divisors are calculated for this chip + * @rate: desired SPI output clock rate + * + * Function calculates cpsr (clock pre-scaler) and scr divisors based on + * given @rate and places them to @chip->div_cpsr and @chip->div_scr. If, + * for some reason, divisors cannot be calculated nothing is stored and + * %-EINVAL is returned. + */ +static int ep93xx_spi_calc_divisors(const struct ep93xx_spi *espi, + struct ep93xx_spi_chip *chip, + unsigned long rate) +{ + unsigned long spi_clk_rate = clk_get_rate(espi->clk); + int cpsr, scr; + + /* + * Make sure that max value is between values supported by the + * controller. Note that minimum value is already checked in + * ep93xx_spi_transfer(). + */ + rate = clamp(rate, espi->min_rate, espi->max_rate); + + /* + * Calculate divisors so that we can get speed according the + * following formula: + * rate = spi_clock_rate / (cpsr * (1 + scr)) + * + * cpsr must be even number and starts from 2, scr can be any number + * between 0 and 255. + */ + for (cpsr = 2; cpsr <= 254; cpsr += 2) { + for (scr = 0; scr <= 255; scr++) { + if ((spi_clk_rate / (cpsr * (scr + 1))) <= rate) { + chip->div_scr = (u8)scr; + chip->div_cpsr = (u8)cpsr; + return 0; + } + } + } + + return -EINVAL; +} + +static void ep93xx_spi_cs_control(struct spi_device *spi, bool control) +{ + struct ep93xx_spi_chip *chip = spi_get_ctldata(spi); + int value = (spi->mode & SPI_CS_HIGH) ? control : !control; + + if (chip->ops && chip->ops->cs_control) + chip->ops->cs_control(spi, value); +} + +/** + * ep93xx_spi_setup() - setup an SPI device + * @spi: SPI device to setup + * + * This function sets up SPI device mode, speed etc. Can be called multiple + * times for a single device. Returns %0 in case of success, negative error in + * case of failure. When this function returns success, the device is + * deselected. + */ +static int ep93xx_spi_setup(struct spi_device *spi) +{ + struct ep93xx_spi *espi = spi_master_get_devdata(spi->master); + struct ep93xx_spi_chip *chip; + + if (spi->bits_per_word < 4 || spi->bits_per_word > 16) { + dev_err(&espi->pdev->dev, "invalid bits per word %d\n", + spi->bits_per_word); + return -EINVAL; + } + + chip = spi_get_ctldata(spi); + if (!chip) { + dev_dbg(&espi->pdev->dev, "initial setup for %s\n", + spi->modalias); + + chip = kzalloc(sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + chip->spi = spi; + chip->ops = spi->controller_data; + + if (chip->ops && chip->ops->setup) { + int ret = chip->ops->setup(spi); + if (ret) { + kfree(chip); + return ret; + } + } + + spi_set_ctldata(spi, chip); + } + + if (spi->max_speed_hz != chip->rate) { + int err; + + err = ep93xx_spi_calc_divisors(espi, chip, spi->max_speed_hz); + if (err != 0) { + spi_set_ctldata(spi, NULL); + kfree(chip); + return err; + } + chip->rate = spi->max_speed_hz; + } + + chip->dss = bits_per_word_to_dss(spi->bits_per_word); + + ep93xx_spi_cs_control(spi, false); + return 0; +} + +/** + * ep93xx_spi_transfer() - queue message to be transferred + * @spi: target SPI device + * @msg: message to be transferred + * + * This function is called by SPI device drivers when they are going to transfer + * a new message. It simply puts the message in the queue and schedules + * workqueue to perform the actual transfer later on. + * + * Returns %0 on success and negative error in case of failure. + */ +static int ep93xx_spi_transfer(struct spi_device *spi, struct spi_message *msg) +{ + struct ep93xx_spi *espi = spi_master_get_devdata(spi->master); + struct spi_transfer *t; + unsigned long flags; + + if (!msg || !msg->complete) + return -EINVAL; + + /* first validate each transfer */ + list_for_each_entry(t, &msg->transfers, transfer_list) { + if (t->bits_per_word) { + if (t->bits_per_word < 4 || t->bits_per_word > 16) + return -EINVAL; + } + if (t->speed_hz && t->speed_hz < espi->min_rate) + return -EINVAL; + } + + /* + * Now that we own the message, let's initialize it so that it is + * suitable for us. We use @msg->status to signal whether there was + * error in transfer and @msg->state is used to hold pointer to the + * current transfer (or %NULL if no active current transfer). + */ + msg->state = NULL; + msg->status = 0; + msg->actual_length = 0; + + spin_lock_irqsave(&espi->lock, flags); + if (!espi->running) { + spin_unlock_irqrestore(&espi->lock, flags); + return -ESHUTDOWN; + } + list_add_tail(&msg->queue, &espi->msg_queue); + queue_work(espi->wq, &espi->msg_work); + spin_unlock_irqrestore(&espi->lock, flags); + + return 0; +} + +/** + * ep93xx_spi_cleanup() - cleans up master controller specific state + * @spi: SPI device to cleanup + * + * This function releases master controller specific state for given @spi + * device. + */ +static void ep93xx_spi_cleanup(struct spi_device *spi) +{ + struct ep93xx_spi_chip *chip; + + chip = spi_get_ctldata(spi); + if (chip) { + if (chip->ops && chip->ops->cleanup) + chip->ops->cleanup(spi); + spi_set_ctldata(spi, NULL); + kfree(chip); + } +} + +/** + * ep93xx_spi_chip_setup() - configures hardware according to given @chip + * @espi: ep93xx SPI controller struct + * @chip: chip specific settings + * + * This function sets up the actual hardware registers with settings given in + * @chip. Note that no validation is done so make sure that callers validate + * settings before calling this. + */ +static void ep93xx_spi_chip_setup(const struct ep93xx_spi *espi, + const struct ep93xx_spi_chip *chip) +{ + u16 cr0; + + cr0 = chip->div_scr << SSPCR0_SCR_SHIFT; + cr0 |= (chip->spi->mode & (SPI_CPHA|SPI_CPOL)) << SSPCR0_MODE_SHIFT; + cr0 |= chip->dss; + + dev_dbg(&espi->pdev->dev, "setup: mode %d, cpsr %d, scr %d, dss %d\n", + chip->spi->mode, chip->div_cpsr, chip->div_scr, chip->dss); + dev_dbg(&espi->pdev->dev, "setup: cr0 %#x", cr0); + + ep93xx_spi_write_u8(espi, SSPCPSR, chip->div_cpsr); + ep93xx_spi_write_u16(espi, SSPCR0, cr0); +} + +static inline int bits_per_word(const struct ep93xx_spi *espi) +{ + struct spi_message *msg = espi->current_msg; + struct spi_transfer *t = msg->state; + + return t->bits_per_word ? t->bits_per_word : msg->spi->bits_per_word; +} + +static void ep93xx_do_write(struct ep93xx_spi *espi, struct spi_transfer *t) +{ + if (bits_per_word(espi) > 8) { + u16 tx_val = 0; + + if (t->tx_buf) + tx_val = ((u16 *)t->tx_buf)[espi->tx]; + ep93xx_spi_write_u16(espi, SSPDR, tx_val); + espi->tx += sizeof(tx_val); + } else { + u8 tx_val = 0; + + if (t->tx_buf) + tx_val = ((u8 *)t->tx_buf)[espi->tx]; + ep93xx_spi_write_u8(espi, SSPDR, tx_val); + espi->tx += sizeof(tx_val); + } +} + +static void ep93xx_do_read(struct ep93xx_spi *espi, struct spi_transfer *t) +{ + if (bits_per_word(espi) > 8) { + u16 rx_val; + + rx_val = ep93xx_spi_read_u16(espi, SSPDR); + if (t->rx_buf) + ((u16 *)t->rx_buf)[espi->rx] = rx_val; + espi->rx += sizeof(rx_val); + } else { + u8 rx_val; + + rx_val = ep93xx_spi_read_u8(espi, SSPDR); + if (t->rx_buf) + ((u8 *)t->rx_buf)[espi->rx] = rx_val; + espi->rx += sizeof(rx_val); + } +} + +/** + * ep93xx_spi_read_write() - perform next RX/TX transfer + * @espi: ep93xx SPI controller struct + * + * This function transfers next bytes (or half-words) to/from RX/TX FIFOs. If + * called several times, the whole transfer will be completed. Returns + * %-EINPROGRESS when current transfer was not yet completed otherwise %0. + * + * When this function is finished, RX FIFO should be empty and TX FIFO should be + * full. + */ +static int ep93xx_spi_read_write(struct ep93xx_spi *espi) +{ + struct spi_message *msg = espi->current_msg; + struct spi_transfer *t = msg->state; + + /* read as long as RX FIFO has frames in it */ + while ((ep93xx_spi_read_u8(espi, SSPSR) & SSPSR_RNE)) { + ep93xx_do_read(espi, t); + espi->fifo_level--; + } + + /* write as long as TX FIFO has room */ + while (espi->fifo_level < SPI_FIFO_SIZE && espi->tx < t->len) { + ep93xx_do_write(espi, t); + espi->fifo_level++; + } + + if (espi->rx == t->len) { + msg->actual_length += t->len; + return 0; + } + + return -EINPROGRESS; +} + +/** + * ep93xx_spi_process_transfer() - processes one SPI transfer + * @espi: ep93xx SPI controller struct + * @msg: current message + * @t: transfer to process + * + * This function processes one SPI transfer given in @t. Function waits until + * transfer is complete (may sleep) and updates @msg->status based on whether + * transfer was succesfully processed or not. + */ +static void ep93xx_spi_process_transfer(struct ep93xx_spi *espi, + struct spi_message *msg, + struct spi_transfer *t) +{ + struct ep93xx_spi_chip *chip = spi_get_ctldata(msg->spi); + + msg->state = t; + + /* + * Handle any transfer specific settings if needed. We use + * temporary chip settings here and restore original later when + * the transfer is finished. + */ + if (t->speed_hz || t->bits_per_word) { + struct ep93xx_spi_chip tmp_chip = *chip; + + if (t->speed_hz) { + int err; + + err = ep93xx_spi_calc_divisors(espi, &tmp_chip, + t->speed_hz); + if (err) { + dev_err(&espi->pdev->dev, + "failed to adjust speed\n"); + msg->status = err; + return; + } + } + + if (t->bits_per_word) + tmp_chip.dss = bits_per_word_to_dss(t->bits_per_word); + + /* + * Set up temporary new hw settings for this transfer. + */ + ep93xx_spi_chip_setup(espi, &tmp_chip); + } + + espi->rx = 0; + espi->tx = 0; + + /* + * Now everything is set up for the current transfer. We prime the TX + * FIFO, enable interrupts, and wait for the transfer to complete. + */ + if (ep93xx_spi_read_write(espi)) { + ep93xx_spi_enable_interrupts(espi); + wait_for_completion(&espi->wait); + } + + /* + * In case of error during transmit, we bail out from processing + * the message. + */ + if (msg->status) + return; + + /* + * After this transfer is finished, perform any possible + * post-transfer actions requested by the protocol driver. + */ + if (t->delay_usecs) { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(usecs_to_jiffies(t->delay_usecs)); + } + if (t->cs_change) { + if (!list_is_last(&t->transfer_list, &msg->transfers)) { + /* + * In case protocol driver is asking us to drop the + * chipselect briefly, we let the scheduler to handle + * any "delay" here. + */ + ep93xx_spi_cs_control(msg->spi, false); + cond_resched(); + ep93xx_spi_cs_control(msg->spi, true); + } + } + + if (t->speed_hz || t->bits_per_word) + ep93xx_spi_chip_setup(espi, chip); +} + +/* + * ep93xx_spi_process_message() - process one SPI message + * @espi: ep93xx SPI controller struct + * @msg: message to process + * + * This function processes a single SPI message. We go through all transfers in + * the message and pass them to ep93xx_spi_process_transfer(). Chipselect is + * asserted during the whole message (unless per transfer cs_change is set). + * + * @msg->status contains %0 in case of success or negative error code in case of + * failure. + */ +static void ep93xx_spi_process_message(struct ep93xx_spi *espi, + struct spi_message *msg) +{ + unsigned long timeout; + struct spi_transfer *t; + int err; + + /* + * Enable the SPI controller and its clock. + */ + err = ep93xx_spi_enable(espi); + if (err) { + dev_err(&espi->pdev->dev, "failed to enable SPI controller\n"); + msg->status = err; + return; + } + + /* + * Just to be sure: flush any data from RX FIFO. + */ + timeout = jiffies + msecs_to_jiffies(SPI_TIMEOUT); + while (ep93xx_spi_read_u16(espi, SSPSR) & SSPSR_RNE) { + if (time_after(jiffies, timeout)) { + dev_warn(&espi->pdev->dev, + "timeout while flushing RX FIFO\n"); + msg->status = -ETIMEDOUT; + return; + } + ep93xx_spi_read_u16(espi, SSPDR); + } + + /* + * We explicitly handle FIFO level. This way we don't have to check TX + * FIFO status using %SSPSR_TNF bit which may cause RX FIFO overruns. + */ + espi->fifo_level = 0; + + /* + * Update SPI controller registers according to spi device and assert + * the chipselect. + */ + ep93xx_spi_chip_setup(espi, spi_get_ctldata(msg->spi)); + ep93xx_spi_cs_control(msg->spi, true); + + list_for_each_entry(t, &msg->transfers, transfer_list) { + ep93xx_spi_process_transfer(espi, msg, t); + if (msg->status) + break; + } + + /* + * Now the whole message is transferred (or failed for some reason). We + * deselect the device and disable the SPI controller. + */ + ep93xx_spi_cs_control(msg->spi, false); + ep93xx_spi_disable(espi); +} + +#define work_to_espi(work) (container_of((work), struct ep93xx_spi, msg_work)) + +/** + * ep93xx_spi_work() - EP93xx SPI workqueue worker function + * @work: work struct + * + * Workqueue worker function. This function is called when there are new + * SPI messages to be processed. Message is taken out from the queue and then + * passed to ep93xx_spi_process_message(). + * + * After message is transferred, protocol driver is notified by calling + * @msg->complete(). In case of error, @msg->status is set to negative error + * number, otherwise it contains zero (and @msg->actual_length is updated). + */ +static void ep93xx_spi_work(struct work_struct *work) +{ + struct ep93xx_spi *espi = work_to_espi(work); + struct spi_message *msg; + + spin_lock_irq(&espi->lock); + if (!espi->running || espi->current_msg || + list_empty(&espi->msg_queue)) { + spin_unlock_irq(&espi->lock); + return; + } + msg = list_first_entry(&espi->msg_queue, struct spi_message, queue); + list_del_init(&msg->queue); + espi->current_msg = msg; + spin_unlock_irq(&espi->lock); + + ep93xx_spi_process_message(espi, msg); + + /* + * Update the current message and re-schedule ourselves if there are + * more messages in the queue. + */ + spin_lock_irq(&espi->lock); + espi->current_msg = NULL; + if (espi->running && !list_empty(&espi->msg_queue)) + queue_work(espi->wq, &espi->msg_work); + spin_unlock_irq(&espi->lock); + + /* notify the protocol driver that we are done with this message */ + msg->complete(msg->context); +} + +static irqreturn_t ep93xx_spi_interrupt(int irq, void *dev_id) +{ + struct ep93xx_spi *espi = dev_id; + u8 irq_status = ep93xx_spi_read_u8(espi, SSPIIR); + + /* + * If we got ROR (receive overrun) interrupt we know that something is + * wrong. Just abort the message. + */ + if (unlikely(irq_status & SSPIIR_RORIS)) { + /* clear the overrun interrupt */ + ep93xx_spi_write_u8(espi, SSPICR, 0); + dev_warn(&espi->pdev->dev, + "receive overrun, aborting the message\n"); + espi->current_msg->status = -EIO; + } else { + /* + * Interrupt is either RX (RIS) or TX (TIS). For both cases we + * simply execute next data transfer. + */ + if (ep93xx_spi_read_write(espi)) { + /* + * In normal case, there still is some processing left + * for current transfer. Let's wait for the next + * interrupt then. + */ + return IRQ_HANDLED; + } + } + + /* + * Current transfer is finished, either with error or with success. In + * any case we disable interrupts and notify the worker to handle + * any post-processing of the message. + */ + ep93xx_spi_disable_interrupts(espi); + complete(&espi->wait); + return IRQ_HANDLED; +} + +static int __init ep93xx_spi_probe(struct platform_device *pdev) +{ + struct spi_master *master; + struct ep93xx_spi_info *info; + struct ep93xx_spi *espi; + struct resource *res; + int error; + + info = pdev->dev.platform_data; + + master = spi_alloc_master(&pdev->dev, sizeof(*espi)); + if (!master) { + dev_err(&pdev->dev, "failed to allocate spi master\n"); + return -ENOMEM; + } + + master->setup = ep93xx_spi_setup; + master->transfer = ep93xx_spi_transfer; + master->cleanup = ep93xx_spi_cleanup; + master->bus_num = pdev->id; + master->num_chipselect = info->num_chipselect; + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; + + platform_set_drvdata(pdev, master); + + espi = spi_master_get_devdata(master); + + espi->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(espi->clk)) { + dev_err(&pdev->dev, "unable to get spi clock\n"); + error = PTR_ERR(espi->clk); + goto fail_release_master; + } + + spin_lock_init(&espi->lock); + init_completion(&espi->wait); + + /* + * Calculate maximum and minimum supported clock rates + * for the controller. + */ + espi->max_rate = clk_get_rate(espi->clk) / 2; + espi->min_rate = clk_get_rate(espi->clk) / (254 * 256); + espi->pdev = pdev; + + espi->irq = platform_get_irq(pdev, 0); + if (espi->irq < 0) { + error = -EBUSY; + dev_err(&pdev->dev, "failed to get irq resources\n"); + goto fail_put_clock; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "unable to get iomem resource\n"); + error = -ENODEV; + goto fail_put_clock; + } + + res = request_mem_region(res->start, resource_size(res), pdev->name); + if (!res) { + dev_err(&pdev->dev, "unable to request iomem resources\n"); + error = -EBUSY; + goto fail_put_clock; + } + + espi->regs_base = ioremap(res->start, resource_size(res)); + if (!espi->regs_base) { + dev_err(&pdev->dev, "failed to map resources\n"); + error = -ENODEV; + goto fail_free_mem; + } + + error = request_irq(espi->irq, ep93xx_spi_interrupt, 0, + "ep93xx-spi", espi); + if (error) { + dev_err(&pdev->dev, "failed to request irq\n"); + goto fail_unmap_regs; + } + + espi->wq = create_singlethread_workqueue("ep93xx_spid"); + if (!espi->wq) { + dev_err(&pdev->dev, "unable to create workqueue\n"); + goto fail_free_irq; + } + INIT_WORK(&espi->msg_work, ep93xx_spi_work); + INIT_LIST_HEAD(&espi->msg_queue); + espi->running = true; + + /* make sure that the hardware is disabled */ + ep93xx_spi_write_u8(espi, SSPCR1, 0); + + error = spi_register_master(master); + if (error) { + dev_err(&pdev->dev, "failed to register SPI master\n"); + goto fail_free_queue; + } + + dev_info(&pdev->dev, "EP93xx SPI Controller at 0x%08lx irq %d\n", + (unsigned long)res->start, espi->irq); + + return 0; + +fail_free_queue: + destroy_workqueue(espi->wq); +fail_free_irq: + free_irq(espi->irq, espi); +fail_unmap_regs: + iounmap(espi->regs_base); +fail_free_mem: + release_mem_region(res->start, resource_size(res)); +fail_put_clock: + clk_put(espi->clk); +fail_release_master: + spi_master_put(master); + platform_set_drvdata(pdev, NULL); + + return error; +} + +static int __exit ep93xx_spi_remove(struct platform_device *pdev) +{ + struct spi_master *master = platform_get_drvdata(pdev); + struct ep93xx_spi *espi = spi_master_get_devdata(master); + struct resource *res; + + spin_lock_irq(&espi->lock); + espi->running = false; + spin_unlock_irq(&espi->lock); + + destroy_workqueue(espi->wq); + + /* + * Complete remaining messages with %-ESHUTDOWN status. + */ + spin_lock_irq(&espi->lock); + while (!list_empty(&espi->msg_queue)) { + struct spi_message *msg; + + msg = list_first_entry(&espi->msg_queue, + struct spi_message, queue); + list_del_init(&msg->queue); + msg->status = -ESHUTDOWN; + spin_unlock_irq(&espi->lock); + msg->complete(msg->context); + spin_lock_irq(&espi->lock); + } + spin_unlock_irq(&espi->lock); + + free_irq(espi->irq, espi); + iounmap(espi->regs_base); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(res->start, resource_size(res)); + clk_put(espi->clk); + platform_set_drvdata(pdev, NULL); + + spi_unregister_master(master); + return 0; +} + +static struct platform_driver ep93xx_spi_driver = { + .driver = { + .name = "ep93xx-spi", + .owner = THIS_MODULE, + }, + .remove = __exit_p(ep93xx_spi_remove), +}; + +static int __init ep93xx_spi_init(void) +{ + return platform_driver_probe(&ep93xx_spi_driver, ep93xx_spi_probe); +} +module_init(ep93xx_spi_init); + +static void __exit ep93xx_spi_exit(void) +{ + platform_driver_unregister(&ep93xx_spi_driver); +} +module_exit(ep93xx_spi_exit); + +MODULE_DESCRIPTION("EP93xx SPI Controller driver"); +MODULE_AUTHOR("Mika Westerberg "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ep93xx-spi"); -- cgit v1.2.3 From 2da8cb6af5fe0d9e16b8a49399c8b7c6cfa94d5a Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Fri, 30 Apr 2010 13:21:26 +0000 Subject: powerpc/mpc5121: move PSC FIFO memory init to platform code Since PSC could also be used in other modes than UART mode we move PSC FIFO memory initialization from serial driver to common platform code. The initialized FIFO memory slices may not overlap, so the most easy way would be to configure them all at once at init time for all PSC devices. This is now done by this patch. Signed-off-by: Anatolij Gustschin Signed-off-by: Grant Likely --- arch/powerpc/platforms/512x/mpc512x_shared.c | 78 ++++++++++++++++++++++++++++ drivers/serial/mpc52xx_uart.c | 69 ------------------------ 2 files changed, 78 insertions(+), 69 deletions(-) (limited to 'drivers') diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c index b7f518a60f03..707e572b7c40 100644 --- a/arch/powerpc/platforms/512x/mpc512x_shared.c +++ b/arch/powerpc/platforms/512x/mpc512x_shared.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "mpc512x.h" @@ -95,9 +96,86 @@ void __init mpc512x_declare_of_platform_devices(void) } } +#define DEFAULT_FIFO_SIZE 16 + +static unsigned int __init get_fifo_size(struct device_node *np, + char *prop_name) +{ + const unsigned int *fp; + + fp = of_get_property(np, prop_name, NULL); + if (fp) + return *fp; + + pr_warning("no %s property in %s node, defaulting to %d\n", + prop_name, np->full_name, DEFAULT_FIFO_SIZE); + + return DEFAULT_FIFO_SIZE; +} + +#define FIFOC(_base) ((struct mpc512x_psc_fifo __iomem *) \ + ((u32)(_base) + sizeof(struct mpc52xx_psc))) + +/* Init PSC FIFO space for TX and RX slices */ +void __init mpc512x_psc_fifo_init(void) +{ + struct device_node *np; + void __iomem *psc; + unsigned int tx_fifo_size; + unsigned int rx_fifo_size; + int fifobase = 0; /* current fifo address in 32 bit words */ + + for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") { + tx_fifo_size = get_fifo_size(np, "fsl,tx-fifo-size"); + rx_fifo_size = get_fifo_size(np, "fsl,rx-fifo-size"); + + /* size in register is in 4 byte units */ + tx_fifo_size /= 4; + rx_fifo_size /= 4; + if (!tx_fifo_size) + tx_fifo_size = 1; + if (!rx_fifo_size) + rx_fifo_size = 1; + + psc = of_iomap(np, 0); + if (!psc) { + pr_err("%s: Can't map %s device\n", + __func__, np->full_name); + continue; + } + + /* FIFO space is 4KiB, check if requested size is available */ + if ((fifobase + tx_fifo_size + rx_fifo_size) > 0x1000) { + pr_err("%s: no fifo space available for %s\n", + __func__, np->full_name); + iounmap(psc); + /* + * chances are that another device requests less + * fifo space, so we continue. + */ + continue; + } + + /* set tx and rx fifo size registers */ + out_be32(&FIFOC(psc)->txsz, (fifobase << 16) | tx_fifo_size); + fifobase += tx_fifo_size; + out_be32(&FIFOC(psc)->rxsz, (fifobase << 16) | rx_fifo_size); + fifobase += rx_fifo_size; + + /* reset and enable the slices */ + out_be32(&FIFOC(psc)->txcmd, 0x80); + out_be32(&FIFOC(psc)->txcmd, 0x01); + out_be32(&FIFOC(psc)->rxcmd, 0x80); + out_be32(&FIFOC(psc)->rxcmd, 0x01); + + iounmap(psc); + } +} + void __init mpc512x_init(void) { mpc512x_declare_of_platform_devices(); mpc5121_clk_init(); mpc512x_restart_init(); + mpc512x_psc_fifo_init(); } diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 02469c31bf0b..f0ca448a1ebf 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c @@ -397,34 +397,10 @@ static unsigned long mpc512x_getuartclk(void *p) return mpc5xxx_get_bus_frequency(p); } -#define DEFAULT_FIFO_SIZE 16 - -static unsigned int __init get_fifo_size(struct device_node *np, - char *fifo_name) -{ - const unsigned int *fp; - - fp = of_get_property(np, fifo_name, NULL); - if (fp) - return *fp; - - pr_warning("no %s property in %s node, defaulting to %d\n", - fifo_name, np->full_name, DEFAULT_FIFO_SIZE); - - return DEFAULT_FIFO_SIZE; -} - -#define FIFOC(_base) ((struct mpc512x_psc_fifo __iomem *) \ - ((u32)(_base) + sizeof(struct mpc52xx_psc))) - /* Init PSC FIFO Controller */ static int __init mpc512x_psc_fifoc_init(void) { struct device_node *np; - void __iomem *psc; - unsigned int tx_fifo_size; - unsigned int rx_fifo_size; - int fifobase = 0; /* current fifo address in 32 bit words */ np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-psc-fifo"); @@ -447,51 +423,6 @@ static int __init mpc512x_psc_fifoc_init(void) return -ENODEV; } - for_each_compatible_node(np, NULL, "fsl,mpc5121-psc-uart") { - tx_fifo_size = get_fifo_size(np, "fsl,tx-fifo-size"); - rx_fifo_size = get_fifo_size(np, "fsl,rx-fifo-size"); - - /* size in register is in 4 byte units */ - tx_fifo_size /= 4; - rx_fifo_size /= 4; - if (!tx_fifo_size) - tx_fifo_size = 1; - if (!rx_fifo_size) - rx_fifo_size = 1; - - psc = of_iomap(np, 0); - if (!psc) { - pr_err("%s: Can't map %s device\n", - __func__, np->full_name); - continue; - } - - /* FIFO space is 4KiB, check if requested size is available */ - if ((fifobase + tx_fifo_size + rx_fifo_size) > 0x1000) { - pr_err("%s: no fifo space available for %s\n", - __func__, np->full_name); - iounmap(psc); - /* - * chances are that another device requests less - * fifo space, so we continue. - */ - continue; - } - /* set tx and rx fifo size registers */ - out_be32(&FIFOC(psc)->txsz, (fifobase << 16) | tx_fifo_size); - fifobase += tx_fifo_size; - out_be32(&FIFOC(psc)->rxsz, (fifobase << 16) | rx_fifo_size); - fifobase += rx_fifo_size; - - /* reset and enable the slices */ - out_be32(&FIFOC(psc)->txcmd, 0x80); - out_be32(&FIFOC(psc)->txcmd, 0x01); - out_be32(&FIFOC(psc)->rxcmd, 0x80); - out_be32(&FIFOC(psc)->rxcmd, 0x01); - - iounmap(psc); - } - return 0; } -- cgit v1.2.3 From 6e27388f1bd60b55e0b1a83d14233e6c7ad33700 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Fri, 30 Apr 2010 13:21:27 +0000 Subject: spi/mpc5121: Add SPI master driver for MPC5121 PSC Signed-off-by: John Rigby Signed-off-by: Anatolij Gustschin Signed-off-by: Grant Likely --- arch/powerpc/include/asm/mpc52xx_psc.h | 1 + drivers/spi/Kconfig | 7 + drivers/spi/Makefile | 1 + drivers/spi/mpc512x_psc_spi.c | 576 +++++++++++++++++++++++++++++++++ 4 files changed, 585 insertions(+) create mode 100644 drivers/spi/mpc512x_psc_spi.c (limited to 'drivers') diff --git a/arch/powerpc/include/asm/mpc52xx_psc.h b/arch/powerpc/include/asm/mpc52xx_psc.h index 42561f4f032d..ecc4fc69ac13 100644 --- a/arch/powerpc/include/asm/mpc52xx_psc.h +++ b/arch/powerpc/include/asm/mpc52xx_psc.h @@ -248,6 +248,7 @@ struct mpc52xx_psc_fifo { u16 tflwfptr; /* PSC + 0x9e */ }; +#define MPC512x_PSC_FIFO_EOF 0x100 #define MPC512x_PSC_FIFO_RESET_SLICE 0x80 #define MPC512x_PSC_FIFO_ENABLE_SLICE 0x01 #define MPC512x_PSC_FIFO_ENABLE_DMA 0x04 diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 2b2f4c3b6b62..aacc0ed25ba4 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -175,6 +175,13 @@ config SPI_MPC52xx_PSC This enables using the Freescale MPC52xx Programmable Serial Controller in master SPI mode. +config SPI_MPC512x_PSC + tristate "Freescale MPC512x PSC SPI controller" + depends on SPI_MASTER && PPC_MPC512x + help + This enables using the Freescale MPC5121 Programmable Serial + Controller in SPI master mode. + config SPI_MPC8xxx tristate "Freescale MPC8xxx SPI controller" depends on FSL_SOC diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 377f8455208d..e9cbd18217a0 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_SPI_OMAP24XX) += omap2_mcspi.o obj-$(CONFIG_SPI_OMAP_100K) += omap_spi_100k.o obj-$(CONFIG_SPI_ORION) += orion_spi.o obj-$(CONFIG_SPI_PL022) += amba-pl022.o +obj-$(CONFIG_SPI_MPC512x_PSC) += mpc512x_psc_spi.o obj-$(CONFIG_SPI_MPC52xx_PSC) += mpc52xx_psc_spi.o obj-$(CONFIG_SPI_MPC52xx) += mpc52xx_spi.o obj-$(CONFIG_SPI_MPC8xxx) += spi_mpc8xxx.o diff --git a/drivers/spi/mpc512x_psc_spi.c b/drivers/spi/mpc512x_psc_spi.c new file mode 100644 index 000000000000..28a126d2742b --- /dev/null +++ b/drivers/spi/mpc512x_psc_spi.c @@ -0,0 +1,576 @@ +/* + * MPC512x PSC in SPI mode driver. + * + * Copyright (C) 2007,2008 Freescale Semiconductor Inc. + * Original port from 52xx driver: + * Hongjun Chen + * + * Fork of mpc52xx_psc_spi.c: + * Copyright (C) 2006 TOPTICA Photonics AG., Dragos Carp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct mpc512x_psc_spi { + void (*cs_control)(struct spi_device *spi, bool on); + u32 sysclk; + + /* driver internal data */ + struct mpc52xx_psc __iomem *psc; + struct mpc512x_psc_fifo __iomem *fifo; + unsigned int irq; + u8 bits_per_word; + u8 busy; + u32 mclk; + u8 eofbyte; + + struct workqueue_struct *workqueue; + struct work_struct work; + + struct list_head queue; + spinlock_t lock; /* Message queue lock */ + + struct completion done; +}; + +/* controller state */ +struct mpc512x_psc_spi_cs { + int bits_per_word; + int speed_hz; +}; + +/* set clock freq, clock ramp, bits per work + * if t is NULL then reset the values to the default values + */ +static int mpc512x_psc_spi_transfer_setup(struct spi_device *spi, + struct spi_transfer *t) +{ + struct mpc512x_psc_spi_cs *cs = spi->controller_state; + + cs->speed_hz = (t && t->speed_hz) + ? t->speed_hz : spi->max_speed_hz; + cs->bits_per_word = (t && t->bits_per_word) + ? t->bits_per_word : spi->bits_per_word; + cs->bits_per_word = ((cs->bits_per_word + 7) / 8) * 8; + return 0; +} + +static void mpc512x_psc_spi_activate_cs(struct spi_device *spi) +{ + struct mpc512x_psc_spi_cs *cs = spi->controller_state; + struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master); + struct mpc52xx_psc __iomem *psc = mps->psc; + u32 sicr; + u32 ccr; + u16 bclkdiv; + + sicr = in_be32(&psc->sicr); + + /* Set clock phase and polarity */ + if (spi->mode & SPI_CPHA) + sicr |= 0x00001000; + else + sicr &= ~0x00001000; + + if (spi->mode & SPI_CPOL) + sicr |= 0x00002000; + else + sicr &= ~0x00002000; + + if (spi->mode & SPI_LSB_FIRST) + sicr |= 0x10000000; + else + sicr &= ~0x10000000; + out_be32(&psc->sicr, sicr); + + ccr = in_be32(&psc->ccr); + ccr &= 0xFF000000; + if (cs->speed_hz) + bclkdiv = (mps->mclk / cs->speed_hz) - 1; + else + bclkdiv = (mps->mclk / 1000000) - 1; /* default 1MHz */ + + ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8)); + out_be32(&psc->ccr, ccr); + mps->bits_per_word = cs->bits_per_word; + + if (mps->cs_control) + mps->cs_control(spi, (spi->mode & SPI_CS_HIGH) ? 1 : 0); +} + +static void mpc512x_psc_spi_deactivate_cs(struct spi_device *spi) +{ + struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master); + + if (mps->cs_control) + mps->cs_control(spi, (spi->mode & SPI_CS_HIGH) ? 0 : 1); + +} + +/* extract and scale size field in txsz or rxsz */ +#define MPC512x_PSC_FIFO_SZ(sz) ((sz & 0x7ff) << 2); + +#define EOFBYTE 1 + +static int mpc512x_psc_spi_transfer_rxtx(struct spi_device *spi, + struct spi_transfer *t) +{ + struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master); + struct mpc52xx_psc __iomem *psc = mps->psc; + struct mpc512x_psc_fifo __iomem *fifo = mps->fifo; + size_t len = t->len; + u8 *tx_buf = (u8 *)t->tx_buf; + u8 *rx_buf = (u8 *)t->rx_buf; + + if (!tx_buf && !rx_buf && t->len) + return -EINVAL; + + /* Zero MR2 */ + in_8(&psc->mode); + out_8(&psc->mode, 0x0); + + while (len) { + int count; + int i; + u8 data; + size_t fifosz; + int rxcount; + + /* + * The number of bytes that can be sent at a time + * depends on the fifo size. + */ + fifosz = MPC512x_PSC_FIFO_SZ(in_be32(&fifo->txsz)); + count = min(fifosz, len); + + for (i = count; i > 0; i--) { + data = tx_buf ? *tx_buf++ : 0; + if (len == EOFBYTE) + setbits32(&fifo->txcmd, MPC512x_PSC_FIFO_EOF); + out_8(&fifo->txdata_8, data); + len--; + } + + INIT_COMPLETION(mps->done); + + /* interrupt on tx fifo empty */ + out_be32(&fifo->txisr, MPC512x_PSC_FIFO_EMPTY); + out_be32(&fifo->tximr, MPC512x_PSC_FIFO_EMPTY); + + /* enable transmiter/receiver */ + out_8(&psc->command, + MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE); + + wait_for_completion(&mps->done); + + mdelay(1); + + /* rx fifo should have count bytes in it */ + rxcount = in_be32(&fifo->rxcnt); + if (rxcount != count) + mdelay(1); + + rxcount = in_be32(&fifo->rxcnt); + if (rxcount != count) { + dev_warn(&spi->dev, "expected %d bytes in rx fifo " + "but got %d\n", count, rxcount); + } + + rxcount = min(rxcount, count); + for (i = rxcount; i > 0; i--) { + data = in_8(&fifo->rxdata_8); + if (rx_buf) + *rx_buf++ = data; + } + while (in_be32(&fifo->rxcnt)) { + in_8(&fifo->rxdata_8); + } + + out_8(&psc->command, + MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE); + } + /* disable transmiter/receiver and fifo interrupt */ + out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE); + out_be32(&fifo->tximr, 0); + return 0; +} + +static void mpc512x_psc_spi_work(struct work_struct *work) +{ + struct mpc512x_psc_spi *mps = container_of(work, + struct mpc512x_psc_spi, + work); + + spin_lock_irq(&mps->lock); + mps->busy = 1; + while (!list_empty(&mps->queue)) { + struct spi_message *m; + struct spi_device *spi; + struct spi_transfer *t = NULL; + unsigned cs_change; + int status; + + m = container_of(mps->queue.next, struct spi_message, queue); + list_del_init(&m->queue); + spin_unlock_irq(&mps->lock); + + spi = m->spi; + cs_change = 1; + status = 0; + list_for_each_entry(t, &m->transfers, transfer_list) { + if (t->bits_per_word || t->speed_hz) { + status = mpc512x_psc_spi_transfer_setup(spi, t); + if (status < 0) + break; + } + + if (cs_change) + mpc512x_psc_spi_activate_cs(spi); + cs_change = t->cs_change; + + status = mpc512x_psc_spi_transfer_rxtx(spi, t); + if (status) + break; + m->actual_length += t->len; + + if (t->delay_usecs) + udelay(t->delay_usecs); + + if (cs_change) + mpc512x_psc_spi_deactivate_cs(spi); + } + + m->status = status; + m->complete(m->context); + + if (status || !cs_change) + mpc512x_psc_spi_deactivate_cs(spi); + + mpc512x_psc_spi_transfer_setup(spi, NULL); + + spin_lock_irq(&mps->lock); + } + mps->busy = 0; + spin_unlock_irq(&mps->lock); +} + +static int mpc512x_psc_spi_setup(struct spi_device *spi) +{ + struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master); + struct mpc512x_psc_spi_cs *cs = spi->controller_state; + unsigned long flags; + + if (spi->bits_per_word % 8) + return -EINVAL; + + if (!cs) { + cs = kzalloc(sizeof *cs, GFP_KERNEL); + if (!cs) + return -ENOMEM; + spi->controller_state = cs; + } + + cs->bits_per_word = spi->bits_per_word; + cs->speed_hz = spi->max_speed_hz; + + spin_lock_irqsave(&mps->lock, flags); + if (!mps->busy) + mpc512x_psc_spi_deactivate_cs(spi); + spin_unlock_irqrestore(&mps->lock, flags); + + return 0; +} + +static int mpc512x_psc_spi_transfer(struct spi_device *spi, + struct spi_message *m) +{ + struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master); + unsigned long flags; + + m->actual_length = 0; + m->status = -EINPROGRESS; + + spin_lock_irqsave(&mps->lock, flags); + list_add_tail(&m->queue, &mps->queue); + queue_work(mps->workqueue, &mps->work); + spin_unlock_irqrestore(&mps->lock, flags); + + return 0; +} + +static void mpc512x_psc_spi_cleanup(struct spi_device *spi) +{ + kfree(spi->controller_state); +} + +static int mpc512x_psc_spi_port_config(struct spi_master *master, + struct mpc512x_psc_spi *mps) +{ + struct mpc52xx_psc __iomem *psc = mps->psc; + struct mpc512x_psc_fifo __iomem *fifo = mps->fifo; + struct clk *spiclk; + int ret = 0; + char name[32]; + u32 sicr; + u32 ccr; + u16 bclkdiv; + + sprintf(name, "psc%d_mclk", master->bus_num); + spiclk = clk_get(&master->dev, name); + clk_enable(spiclk); + mps->mclk = clk_get_rate(spiclk); + clk_put(spiclk); + + /* Reset the PSC into a known state */ + out_8(&psc->command, MPC52xx_PSC_RST_RX); + out_8(&psc->command, MPC52xx_PSC_RST_TX); + out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE); + + /* Disable psc interrupts all useful interrupts are in fifo */ + out_be16(&psc->isr_imr.imr, 0); + + /* Disable fifo interrupts, will be enabled later */ + out_be32(&fifo->tximr, 0); + out_be32(&fifo->rximr, 0); + + /* Setup fifo slice address and size */ + /*out_be32(&fifo->txsz, 0x0fe00004);*/ + /*out_be32(&fifo->rxsz, 0x0ff00004);*/ + + sicr = 0x01000000 | /* SIM = 0001 -- 8 bit */ + 0x00800000 | /* GenClk = 1 -- internal clk */ + 0x00008000 | /* SPI = 1 */ + 0x00004000 | /* MSTR = 1 -- SPI master */ + 0x00000800; /* UseEOF = 1 -- SS low until EOF */ + + out_be32(&psc->sicr, sicr); + + ccr = in_be32(&psc->ccr); + ccr &= 0xFF000000; + bclkdiv = (mps->mclk / 1000000) - 1; /* default 1MHz */ + ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8)); + out_be32(&psc->ccr, ccr); + + /* Set 2ms DTL delay */ + out_8(&psc->ctur, 0x00); + out_8(&psc->ctlr, 0x82); + + /* we don't use the alarms */ + out_be32(&fifo->rxalarm, 0xfff); + out_be32(&fifo->txalarm, 0); + + /* Enable FIFO slices for Rx/Tx */ + out_be32(&fifo->rxcmd, + MPC512x_PSC_FIFO_ENABLE_SLICE | MPC512x_PSC_FIFO_ENABLE_DMA); + out_be32(&fifo->txcmd, + MPC512x_PSC_FIFO_ENABLE_SLICE | MPC512x_PSC_FIFO_ENABLE_DMA); + + mps->bits_per_word = 8; + + return ret; +} + +static irqreturn_t mpc512x_psc_spi_isr(int irq, void *dev_id) +{ + struct mpc512x_psc_spi *mps = (struct mpc512x_psc_spi *)dev_id; + struct mpc512x_psc_fifo __iomem *fifo = mps->fifo; + + /* clear interrupt and wake up the work queue */ + if (in_be32(&fifo->txisr) & + in_be32(&fifo->tximr) & MPC512x_PSC_FIFO_EMPTY) { + out_be32(&fifo->txisr, MPC512x_PSC_FIFO_EMPTY); + out_be32(&fifo->tximr, 0); + complete(&mps->done); + return IRQ_HANDLED; + } + return IRQ_NONE; +} + +/* bus_num is used only for the case dev->platform_data == NULL */ +static int __init mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, + u32 size, unsigned int irq, + s16 bus_num) +{ + struct fsl_spi_platform_data *pdata = dev->platform_data; + struct mpc512x_psc_spi *mps; + struct spi_master *master; + int ret; + void *tempp; + + master = spi_alloc_master(dev, sizeof *mps); + if (master == NULL) + return -ENOMEM; + + dev_set_drvdata(dev, master); + mps = spi_master_get_devdata(master); + mps->irq = irq; + + if (pdata == NULL) { + dev_err(dev, "probe called without platform data, no " + "cs_control function will be called\n"); + mps->cs_control = NULL; + mps->sysclk = 0; + master->bus_num = bus_num; + master->num_chipselect = 255; + } else { + mps->cs_control = pdata->cs_control; + mps->sysclk = pdata->sysclk; + master->bus_num = pdata->bus_num; + master->num_chipselect = pdata->max_chipselect; + } + + master->setup = mpc512x_psc_spi_setup; + master->transfer = mpc512x_psc_spi_transfer; + master->cleanup = mpc512x_psc_spi_cleanup; + + tempp = ioremap(regaddr, size); + if (!tempp) { + dev_err(dev, "could not ioremap I/O port range\n"); + ret = -EFAULT; + goto free_master; + } + mps->psc = tempp; + mps->fifo = + (struct mpc512x_psc_fifo *)(tempp + sizeof(struct mpc52xx_psc)); + + ret = request_irq(mps->irq, mpc512x_psc_spi_isr, IRQF_SHARED, + "mpc512x-psc-spi", mps); + if (ret) + goto free_master; + + ret = mpc512x_psc_spi_port_config(master, mps); + if (ret < 0) + goto free_irq; + + spin_lock_init(&mps->lock); + init_completion(&mps->done); + INIT_WORK(&mps->work, mpc512x_psc_spi_work); + INIT_LIST_HEAD(&mps->queue); + + mps->workqueue = + create_singlethread_workqueue(dev_name(master->dev.parent)); + if (mps->workqueue == NULL) { + ret = -EBUSY; + goto free_irq; + } + + ret = spi_register_master(master); + if (ret < 0) + goto unreg_master; + + return ret; + +unreg_master: + destroy_workqueue(mps->workqueue); +free_irq: + free_irq(mps->irq, mps); +free_master: + if (mps->psc) + iounmap(mps->psc); + spi_master_put(master); + + return ret; +} + +static int __exit mpc512x_psc_spi_do_remove(struct device *dev) +{ + struct spi_master *master = dev_get_drvdata(dev); + struct mpc512x_psc_spi *mps = spi_master_get_devdata(master); + + flush_workqueue(mps->workqueue); + destroy_workqueue(mps->workqueue); + spi_unregister_master(master); + free_irq(mps->irq, mps); + if (mps->psc) + iounmap(mps->psc); + + return 0; +} + +static int __init mpc512x_psc_spi_of_probe(struct of_device *op, + const struct of_device_id *match) +{ + const u32 *regaddr_p; + u64 regaddr64, size64; + s16 id = -1; + + regaddr_p = of_get_address(op->node, 0, &size64, NULL); + if (!regaddr_p) { + dev_err(&op->dev, "Invalid PSC address\n"); + return -EINVAL; + } + regaddr64 = of_translate_address(op->node, regaddr_p); + + /* get PSC id (0..11, used by port_config) */ + if (op->dev.platform_data == NULL) { + const u32 *psc_nump; + + psc_nump = of_get_property(op->node, "cell-index", NULL); + if (!psc_nump || *psc_nump > 11) { + dev_err(&op->dev, "mpc512x_psc_spi: Device node %s " + "has invalid cell-index property\n", + op->node->full_name); + return -EINVAL; + } + id = *psc_nump; + } + + return mpc512x_psc_spi_do_probe(&op->dev, (u32) regaddr64, (u32) size64, + irq_of_parse_and_map(op->node, 0), id); +} + +static int __exit mpc512x_psc_spi_of_remove(struct of_device *op) +{ + return mpc512x_psc_spi_do_remove(&op->dev); +} + +static struct of_device_id mpc512x_psc_spi_of_match[] = { + { .compatible = "fsl,mpc5121-psc-spi", }, + {}, +}; + +MODULE_DEVICE_TABLE(of, mpc512x_psc_spi_of_match); + +static struct of_platform_driver mpc512x_psc_spi_of_driver = { + .match_table = mpc512x_psc_spi_of_match, + .probe = mpc512x_psc_spi_of_probe, + .remove = __exit_p(mpc512x_psc_spi_of_remove), + .driver = { + .name = "mpc512x-psc-spi", + .owner = THIS_MODULE, + }, +}; + +static int __init mpc512x_psc_spi_init(void) +{ + return of_register_platform_driver(&mpc512x_psc_spi_of_driver); +} +module_init(mpc512x_psc_spi_init); + +static void __exit mpc512x_psc_spi_exit(void) +{ + of_unregister_platform_driver(&mpc512x_psc_spi_of_driver); +} +module_exit(mpc512x_psc_spi_exit); + +MODULE_AUTHOR("John Rigby"); +MODULE_DESCRIPTION("MPC512x PSC SPI Driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 41c4221ca6b9db8ea63d2c2323c0e7a8865eba6e Mon Sep 17 00:00:00 2001 From: hartleys Date: Thu, 6 May 2010 20:51:04 +0000 Subject: spi: move bitbang txrx utility functions to private header A number of files in drivers/spi fail checkincludes.pl due to the double include of . The first include is needed to get the struct spi_bitbang definition and the spi_bitbang_* function prototypes. The second include happens after defining EXPAND_BITBANG_TXRX to get the inlined bitbang_txrx_* utility functions. The header is also included by a number of other spi drivers, as well as some arch/ code, in order to use struct spi_bitbang and the associated functions. To fix the double include, and remove any potential confusion about it, move the inlined bitbang_txrx_* functions to a new private header in drivers/spi and also remove the need to define EXPAND_BITBANG_TXRX. Signed-off-by: H Hartley Sweeten Signed-off-by: Grant Likely --- drivers/spi/spi_bitbang_txrx.h | 93 ++++++++++++++++++++++++++++++++++++ drivers/spi/spi_butterfly.c | 3 +- drivers/spi/spi_gpio.c | 3 +- drivers/spi/spi_lm70llp.c | 3 +- drivers/spi/spi_s3c24xx_gpio.c | 3 +- drivers/spi/spi_sh_sci.c | 3 +- include/linux/spi/spi_bitbang.h | 101 ---------------------------------------- 7 files changed, 98 insertions(+), 111 deletions(-) create mode 100644 drivers/spi/spi_bitbang_txrx.h (limited to 'drivers') diff --git a/drivers/spi/spi_bitbang_txrx.h b/drivers/spi/spi_bitbang_txrx.h new file mode 100644 index 000000000000..fc033bbf9180 --- /dev/null +++ b/drivers/spi/spi_bitbang_txrx.h @@ -0,0 +1,93 @@ +/* + * Mix this utility code with some glue code to get one of several types of + * simple SPI master driver. Two do polled word-at-a-time I/O: + * + * - GPIO/parport bitbangers. Provide chipselect() and txrx_word[](), + * expanding the per-word routines from the inline templates below. + * + * - Drivers for controllers resembling bare shift registers. Provide + * chipselect() and txrx_word[](), with custom setup()/cleanup() methods + * that use your controller's clock and chipselect registers. + * + * Some hardware works well with requests at spi_transfer scope: + * + * - Drivers leveraging smarter hardware, with fifos or DMA; or for half + * duplex (MicroWire) controllers. Provide chipselect() and txrx_bufs(), + * and custom setup()/cleanup() methods. + */ + +/* + * The code that knows what GPIO pins do what should have declared four + * functions, ideally as inlines, before including this header: + * + * void setsck(struct spi_device *, int is_on); + * void setmosi(struct spi_device *, int is_on); + * int getmiso(struct spi_device *); + * void spidelay(unsigned); + * + * setsck()'s is_on parameter is a zero/nonzero boolean. + * + * setmosi()'s is_on parameter is a zero/nonzero boolean. + * + * getmiso() is required to return 0 or 1 only. Any other value is invalid + * and will result in improper operation. + * + * A non-inlined routine would call bitbang_txrx_*() routines. The + * main loop could easily compile down to a handful of instructions, + * especially if the delay is a NOP (to run at peak speed). + * + * Since this is software, the timings may not be exactly what your board's + * chips need ... there may be several reasons you'd need to tweak timings + * in these routines, not just make to make it faster or slower to match a + * particular CPU clock rate. + */ + +static inline u32 +bitbang_txrx_be_cpha0(struct spi_device *spi, + unsigned nsecs, unsigned cpol, + u32 word, u8 bits) +{ + /* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */ + + /* clock starts at inactive polarity */ + for (word <<= (32 - bits); likely(bits); bits--) { + + /* setup MSB (to slave) on trailing edge */ + setmosi(spi, word & (1 << 31)); + spidelay(nsecs); /* T(setup) */ + + setsck(spi, !cpol); + spidelay(nsecs); + + /* sample MSB (from slave) on leading edge */ + word <<= 1; + word |= getmiso(spi); + setsck(spi, cpol); + } + return word; +} + +static inline u32 +bitbang_txrx_be_cpha1(struct spi_device *spi, + unsigned nsecs, unsigned cpol, + u32 word, u8 bits) +{ + /* if (cpol == 0) this is SPI_MODE_1; else this is SPI_MODE_3 */ + + /* clock starts at inactive polarity */ + for (word <<= (32 - bits); likely(bits); bits--) { + + /* setup MSB (to slave) on leading edge */ + setsck(spi, !cpol); + setmosi(spi, word & (1 << 31)); + spidelay(nsecs); /* T(setup) */ + + setsck(spi, cpol); + spidelay(nsecs); + + /* sample MSB (from slave) on trailing edge */ + word <<= 1; + word |= getmiso(spi); + } + return word; +} diff --git a/drivers/spi/spi_butterfly.c b/drivers/spi/spi_butterfly.c index c2184866fa9c..8b5281281111 100644 --- a/drivers/spi/spi_butterfly.c +++ b/drivers/spi/spi_butterfly.c @@ -149,8 +149,7 @@ static void butterfly_chipselect(struct spi_device *spi, int value) #define spidelay(X) do{}while(0) //#define spidelay ndelay -#define EXPAND_BITBANG_TXRX -#include +#include "spi_bitbang_txrx.h" static u32 butterfly_txrx_word_mode0(struct spi_device *spi, diff --git a/drivers/spi/spi_gpio.c b/drivers/spi/spi_gpio.c index 26bd03e61855..7edbd5807e0e 100644 --- a/drivers/spi/spi_gpio.c +++ b/drivers/spi/spi_gpio.c @@ -127,8 +127,7 @@ static inline int getmiso(const struct spi_device *spi) */ #define spidelay(nsecs) do {} while (0) -#define EXPAND_BITBANG_TXRX -#include +#include "spi_bitbang_txrx.h" /* * These functions can leverage inline expansion of GPIO calls to shrink diff --git a/drivers/spi/spi_lm70llp.c b/drivers/spi/spi_lm70llp.c index 568c781ad91c..86fb7b5993db 100644 --- a/drivers/spi/spi_lm70llp.c +++ b/drivers/spi/spi_lm70llp.c @@ -174,8 +174,7 @@ static inline int getmiso(struct spi_device *s) } /*--------------------------------------------------------------------*/ -#define EXPAND_BITBANG_TXRX 1 -#include +#include "spi_bitbang_txrx.h" static void lm70_chipselect(struct spi_device *spi, int value) { diff --git a/drivers/spi/spi_s3c24xx_gpio.c b/drivers/spi/spi_s3c24xx_gpio.c index bbf9371cd284..8979a75dbd7b 100644 --- a/drivers/spi/spi_s3c24xx_gpio.c +++ b/drivers/spi/spi_s3c24xx_gpio.c @@ -58,8 +58,7 @@ static inline u32 getmiso(struct spi_device *dev) #define spidelay(x) ndelay(x) -#define EXPAND_BITBANG_TXRX -#include +#include "spi_bitbang_txrx.h" static u32 s3c2410_spigpio_txrx_mode0(struct spi_device *spi, diff --git a/drivers/spi/spi_sh_sci.c b/drivers/spi/spi_sh_sci.c index a65c12ffa733..a511be7961a0 100644 --- a/drivers/spi/spi_sh_sci.c +++ b/drivers/spi/spi_sh_sci.c @@ -78,8 +78,7 @@ static inline u32 getmiso(struct spi_device *dev) #define spidelay(x) ndelay(x) -#define EXPAND_BITBANG_TXRX -#include +#include "spi_bitbang_txrx.h" static u32 sh_sci_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits) diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h index 3274c507b8a9..f987a2bee16a 100644 --- a/include/linux/spi/spi_bitbang.h +++ b/include/linux/spi/spi_bitbang.h @@ -1,24 +1,6 @@ #ifndef __SPI_BITBANG_H #define __SPI_BITBANG_H -/* - * Mix this utility code with some glue code to get one of several types of - * simple SPI master driver. Two do polled word-at-a-time I/O: - * - * - GPIO/parport bitbangers. Provide chipselect() and txrx_word[](), - * expanding the per-word routines from the inline templates below. - * - * - Drivers for controllers resembling bare shift registers. Provide - * chipselect() and txrx_word[](), with custom setup()/cleanup() methods - * that use your controller's clock and chipselect registers. - * - * Some hardware works well with requests at spi_transfer scope: - * - * - Drivers leveraging smarter hardware, with fifos or DMA; or for half - * duplex (MicroWire) controllers. Provide chipselect() and txrx_bufs(), - * and custom setup()/cleanup() methods. - */ - #include struct spi_bitbang { @@ -68,86 +50,3 @@ extern int spi_bitbang_start(struct spi_bitbang *spi); extern int spi_bitbang_stop(struct spi_bitbang *spi); #endif /* __SPI_BITBANG_H */ - -/*-------------------------------------------------------------------------*/ - -#ifdef EXPAND_BITBANG_TXRX - -/* - * The code that knows what GPIO pins do what should have declared four - * functions, ideally as inlines, before #defining EXPAND_BITBANG_TXRX - * and including this header: - * - * void setsck(struct spi_device *, int is_on); - * void setmosi(struct spi_device *, int is_on); - * int getmiso(struct spi_device *); - * void spidelay(unsigned); - * - * setsck()'s is_on parameter is a zero/nonzero boolean. - * - * setmosi()'s is_on parameter is a zero/nonzero boolean. - * - * getmiso() is required to return 0 or 1 only. Any other value is invalid - * and will result in improper operation. - * - * A non-inlined routine would call bitbang_txrx_*() routines. The - * main loop could easily compile down to a handful of instructions, - * especially if the delay is a NOP (to run at peak speed). - * - * Since this is software, the timings may not be exactly what your board's - * chips need ... there may be several reasons you'd need to tweak timings - * in these routines, not just make to make it faster or slower to match a - * particular CPU clock rate. - */ - -static inline u32 -bitbang_txrx_be_cpha0(struct spi_device *spi, - unsigned nsecs, unsigned cpol, - u32 word, u8 bits) -{ - /* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */ - - /* clock starts at inactive polarity */ - for (word <<= (32 - bits); likely(bits); bits--) { - - /* setup MSB (to slave) on trailing edge */ - setmosi(spi, word & (1 << 31)); - spidelay(nsecs); /* T(setup) */ - - setsck(spi, !cpol); - spidelay(nsecs); - - /* sample MSB (from slave) on leading edge */ - word <<= 1; - word |= getmiso(spi); - setsck(spi, cpol); - } - return word; -} - -static inline u32 -bitbang_txrx_be_cpha1(struct spi_device *spi, - unsigned nsecs, unsigned cpol, - u32 word, u8 bits) -{ - /* if (cpol == 0) this is SPI_MODE_1; else this is SPI_MODE_3 */ - - /* clock starts at inactive polarity */ - for (word <<= (32 - bits); likely(bits); bits--) { - - /* setup MSB (to slave) on leading edge */ - setsck(spi, !cpol); - setmosi(spi, word & (1 << 31)); - spidelay(nsecs); /* T(setup) */ - - setsck(spi, cpol); - spidelay(nsecs); - - /* sample MSB (from slave) on trailing edge */ - word <<= 1; - word |= getmiso(spi); - } - return word; -} - -#endif /* EXPAND_BITBANG_TXRX */ -- cgit v1.2.3 From 0c2a2ae32793e3500a15a449612485f5d17dd431 Mon Sep 17 00:00:00 2001 From: Thomas Koeller Date: Mon, 26 Apr 2010 09:01:45 +0000 Subject: spi/davinci: Fix clock prescale factor computation Computation of the clock prescaler value returned bogus results if the requested SPI clock was impossible to set. It now sets either the maximum or minimum clock frequency, as appropriate. Signed-off-by: Thomas Koeller Signed-off-by: Grant Likely --- drivers/spi/davinci_spi.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c index 95afb6b77395..b85090caf7cf 100644 --- a/drivers/spi/davinci_spi.c +++ b/drivers/spi/davinci_spi.c @@ -301,7 +301,7 @@ static int davinci_spi_setup_transfer(struct spi_device *spi, struct davinci_spi *davinci_spi; struct davinci_spi_platform_data *pdata; u8 bits_per_word = 0; - u32 hz = 0, prescale; + u32 hz = 0, prescale = 0, clkspeed; davinci_spi = spi_master_get_devdata(spi->master); pdata = davinci_spi->pdata; @@ -338,10 +338,16 @@ static int davinci_spi_setup_transfer(struct spi_device *spi, set_fmt_bits(davinci_spi->base, bits_per_word & 0x1f, spi->chip_select); - prescale = ((clk_get_rate(davinci_spi->clk) / hz) - 1) & 0xff; + clkspeed = clk_get_rate(davinci_spi->clk); + if (hz > clkspeed / 2) + prescale = 1 << 8; + if (hz < clkspeed / 256) + prescale = 255 << 8; + if (!prescale) + prescale = ((clkspeed / hz - 1) << 8) & 0x0000ff00; clear_fmt_bits(davinci_spi->base, 0x0000ff00, spi->chip_select); - set_fmt_bits(davinci_spi->base, prescale << 8, spi->chip_select); + set_fmt_bits(davinci_spi->base, prescale, spi->chip_select); return 0; } -- cgit v1.2.3 From bf6a67ee3427ab142136e03e90d0b67ecbca5ff2 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 25 May 2010 00:48:24 -0600 Subject: spi/xilinx: Fix compile error Commit 58f9b0b02414062eaff46716bc04b47d7e79add5, "of: eliminate of_device->node and dev_archdata->{of,prom}_node" changed the location of the device_node pointer. Most drivers were converted to the new location, but the xilinx_spi_of driver was missed and now fails to compile. This patch fixes up the xilinx_spi_of driver to use the new location. Signed-off-by: Grant Likely --- drivers/spi/xilinx_spi_of.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/xilinx_spi_of.c b/drivers/spi/xilinx_spi_of.c index 55c58012a028..4654805b08d8 100644 --- a/drivers/spi/xilinx_spi_of.c +++ b/drivers/spi/xilinx_spi_of.c @@ -48,13 +48,13 @@ static int __devinit xilinx_spi_of_probe(struct of_device *ofdev, const u32 *prop; int len; - rc = of_address_to_resource(ofdev->node, 0, &r_mem); + rc = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem); if (rc) { dev_warn(&ofdev->dev, "invalid address\n"); return rc; } - rc = of_irq_to_resource(ofdev->node, 0, &r_irq); + rc = of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq); if (rc == NO_IRQ) { dev_warn(&ofdev->dev, "no IRQ found\n"); return -ENODEV; @@ -67,7 +67,7 @@ static int __devinit xilinx_spi_of_probe(struct of_device *ofdev, return -ENOMEM; /* number of slave select bits is required */ - prop = of_get_property(ofdev->node, "xlnx,num-ss-bits", &len); + prop = of_get_property(ofdev->dev.of_node, "xlnx,num-ss-bits", &len); if (!prop || len < sizeof(*prop)) { dev_warn(&ofdev->dev, "no 'xlnx,num-ss-bits' property\n"); return -EINVAL; @@ -81,7 +81,7 @@ static int __devinit xilinx_spi_of_probe(struct of_device *ofdev, dev_set_drvdata(&ofdev->dev, master); /* Add any subnodes on the SPI bus */ - of_register_spi_devices(master, ofdev->node); + of_register_spi_devices(master, ofdev->dev.of_node); return 0; } -- cgit v1.2.3 From 206f5f2fcb5ff5bb0c60f9e9189937f3ca03e378 Mon Sep 17 00:00:00 2001 From: Stefan Achatz Date: Wed, 19 May 2010 18:55:16 +0200 Subject: HID: roccat: propagate special events of roccat hardware to userspace Module roccat is a char device used to report special events of roccat hardware to userland. These events include requests for on-screen-display of profile or dpi settings or requests for execution of macro sequences that are not stored in device. The information in these events depends on hid device implementation and contains data that is not available in a single hid event or else hidraw could have been used. It is inspired by hidraw, but uses only one circular buffer for all readers. The device is as generic as possible so that the functionality is usable by all (kone and upcomming) roccat device drivers. Signed-off-by: Stefan Achatz Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 8 + drivers/hid/Makefile | 1 + drivers/hid/hid-roccat-kone.c | 49 +++++ drivers/hid/hid-roccat-kone.h | 9 + drivers/hid/hid-roccat.c | 428 ++++++++++++++++++++++++++++++++++++++++++ drivers/hid/hid-roccat.h | 31 +++ 6 files changed, 526 insertions(+) create mode 100644 drivers/hid/hid-roccat.c create mode 100644 drivers/hid/hid-roccat.h (limited to 'drivers') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 76ba59b9fea1..132278fa6240 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -347,6 +347,14 @@ config HID_QUANTA ---help--- Support for Quanta Optical Touch dual-touch panels. +config HID_ROCCAT + tristate "Roccat special event support" + depends on USB_HID + ---help--- + Support for Roccat special events. + Say Y here if you have a Roccat mouse or keyboard and want OSD or + macro execution support. + config HID_ROCCAT_KONE tristate "Roccat Kone Mouse support" depends on USB_HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 22e47eaeea32..987fa0627367 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_HID_QUANTA) += hid-quanta.o obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o +obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c index b6371d3fe0f9..17f2dc04f883 100644 --- a/drivers/hid/hid-roccat-kone.c +++ b/drivers/hid/hid-roccat-kone.c @@ -37,6 +37,7 @@ #include #include #include "hid-ids.h" +#include "hid-roccat.h" #include "hid-roccat-kone.h" static void kone_set_settings_checksum(struct kone_settings *settings) @@ -849,6 +850,16 @@ static int kone_init_specials(struct hid_device *hdev) "couldn't init struct kone_device\n"); goto exit_free; } + + retval = roccat_connect(hdev); + if (retval < 0) { + dev_err(&hdev->dev, "couldn't init char dev\n"); + /* be tolerant about not getting chrdev */ + } else { + kone->roccat_claimed = 1; + kone->chrdev_minor = retval; + } + retval = kone_create_sysfs_attributes(intf); if (retval) { dev_err(&hdev->dev, "cannot create sysfs files\n"); @@ -868,10 +879,14 @@ exit_free: static void kone_remove_specials(struct hid_device *hdev) { struct usb_interface *intf = to_usb_interface(hdev->dev.parent); + struct kone_device *kone; if (intf->cur_altsetting->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE) { kone_remove_sysfs_attributes(intf); + kone = hid_get_drvdata(hdev); + if (kone->roccat_claimed) + roccat_disconnect(kone->chrdev_minor); kfree(hid_get_drvdata(hdev)); } } @@ -930,6 +945,37 @@ static void kone_keep_values_up_to_date(struct kone_device *kone, } } +static void kone_report_to_chrdev(struct kone_device const *kone, + struct kone_mouse_event const *event) +{ + struct kone_roccat_report roccat_report; + + switch (event->event) { + case kone_mouse_event_switch_profile: + case kone_mouse_event_switch_dpi: + case kone_mouse_event_osd_profile: + case kone_mouse_event_osd_dpi: + roccat_report.event = event->event; + roccat_report.value = event->value; + roccat_report.key = 0; + roccat_report_event(kone->chrdev_minor, + (uint8_t *)&roccat_report, + sizeof(struct kone_roccat_report)); + break; + case kone_mouse_event_call_overlong_macro: + if (event->value == kone_keystroke_action_press) { + roccat_report.event = kone_mouse_event_call_overlong_macro; + roccat_report.value = kone->actual_profile; + roccat_report.key = event->macro_key; + roccat_report_event(kone->chrdev_minor, + (uint8_t *)&roccat_report, + sizeof(struct kone_roccat_report)); + } + break; + } + +} + /* * Is called for keyboard- and mousepart. * Only mousepart gets informations about special events in its extended event @@ -958,6 +1004,9 @@ static int kone_raw_event(struct hid_device *hdev, struct hid_report *report, kone_keep_values_up_to_date(kone, event); + if (kone->roccat_claimed) + kone_report_to_chrdev(kone, event); + return 0; /* always do further processing */ } diff --git a/drivers/hid/hid-roccat-kone.h b/drivers/hid/hid-roccat-kone.h index b413b10a7f8a..003e6f81c195 100644 --- a/drivers/hid/hid-roccat-kone.h +++ b/drivers/hid/hid-roccat-kone.h @@ -189,6 +189,12 @@ enum kone_commands { kone_command_firmware = 0xe5a }; +struct kone_roccat_report { + uint8_t event; + uint8_t value; /* holds dpi or profile value */ + uint8_t key; /* macro key on overlong macro execution */ +}; + #pragma pack(pop) struct kone_device { @@ -219,6 +225,9 @@ struct kone_device { * so it's read only once */ int firmware_version; + + int roccat_claimed; + int chrdev_minor; }; #endif diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c new file mode 100644 index 000000000000..e05d48edb66f --- /dev/null +++ b/drivers/hid/hid-roccat.c @@ -0,0 +1,428 @@ +/* + * Roccat driver for Linux + * + * Copyright (c) 2010 Stefan Achatz + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +/* + * Module roccat is a char device used to report special events of roccat + * hardware to userland. These events include requests for on-screen-display of + * profile or dpi settings or requests for execution of macro sequences that are + * not stored in device. The information in these events depends on hid device + * implementation and contains data that is not available in a single hid event + * or else hidraw could have been used. + * It is inspired by hidraw, but uses only one circular buffer for all readers. + */ + +#include +#include +#include + +#include "hid-roccat.h" + +#define ROCCAT_FIRST_MINOR 0 +#define ROCCAT_MAX_DEVICES 8 + +/* should be a power of 2 for performance reason */ +#define ROCCAT_CBUF_SIZE 16 + +struct roccat_report { + uint8_t *value; + int len; +}; + +struct roccat_device { + unsigned int minor; + int open; + int exist; + wait_queue_head_t wait; + struct device *dev; + struct hid_device *hid; + struct list_head readers; + /* protects modifications of readers list */ + struct mutex readers_lock; + + /* + * circular_buffer has one writer and multiple readers with their own + * read pointers + */ + struct roccat_report cbuf[ROCCAT_CBUF_SIZE]; + int cbuf_end; + struct mutex cbuf_lock; +}; + +struct roccat_reader { + struct list_head node; + struct roccat_device *device; + int cbuf_start; +}; + +static int roccat_major; +static struct class *roccat_class; +static struct cdev roccat_cdev; + +static struct roccat_device *devices[ROCCAT_MAX_DEVICES]; +/* protects modifications of devices array */ +static DEFINE_MUTEX(devices_lock); + +static ssize_t roccat_read(struct file *file, char __user *buffer, + size_t count, loff_t *ppos) +{ + struct roccat_reader *reader = file->private_data; + struct roccat_device *device = reader->device; + struct roccat_report *report; + ssize_t retval = 0, len; + DECLARE_WAITQUEUE(wait, current); + + mutex_lock(&device->cbuf_lock); + + /* no data? */ + if (reader->cbuf_start == device->cbuf_end) { + add_wait_queue(&device->wait, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + /* wait for data */ + while (reader->cbuf_start == device->cbuf_end) { + if (file->f_flags & O_NONBLOCK) { + retval = -EAGAIN; + break; + } + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } + if (!device->exist) { + retval = -EIO; + break; + } + + mutex_unlock(&device->cbuf_lock); + schedule(); + mutex_lock(&device->cbuf_lock); + set_current_state(TASK_INTERRUPTIBLE); + } + + set_current_state(TASK_RUNNING); + remove_wait_queue(&device->wait, &wait); + } + + /* here we either have data or a reason to return if retval is set */ + if (retval) + goto exit_unlock; + + report = &device->cbuf[reader->cbuf_start]; + /* + * If report is larger than requested amount of data, rest of report + * is lost! + */ + len = report->len > count ? count : report->len; + + if (copy_to_user(buffer, report->value, len)) { + retval = -EFAULT; + goto exit_unlock; + } + retval += len; + reader->cbuf_start = (reader->cbuf_start + 1) % ROCCAT_CBUF_SIZE; + +exit_unlock: + mutex_unlock(&device->cbuf_lock); + return retval; +} + +static unsigned int roccat_poll(struct file *file, poll_table *wait) +{ + struct roccat_reader *reader = file->private_data; + poll_wait(file, &reader->device->wait, wait); + if (reader->cbuf_start != reader->device->cbuf_end) + return POLLIN | POLLRDNORM; + if (!reader->device->exist) + return POLLERR | POLLHUP; + return 0; +} + +static int roccat_open(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + struct roccat_reader *reader; + struct roccat_device *device; + int error = 0; + + reader = kzalloc(sizeof(struct roccat_reader), GFP_KERNEL); + if (!reader) + return -ENOMEM; + + mutex_lock(&devices_lock); + + device = devices[minor]; + + mutex_lock(&device->readers_lock); + + if (!device) { + printk(KERN_EMERG "roccat device with minor %d doesn't exist\n", + minor); + error = -ENODEV; + goto exit_unlock; + } + + if (!device->open++) { + /* power on device on adding first reader */ + if (device->hid->ll_driver->power) { + error = device->hid->ll_driver->power(device->hid, + PM_HINT_FULLON); + if (error < 0) { + --device->open; + goto exit_unlock; + } + } + error = device->hid->ll_driver->open(device->hid); + if (error < 0) { + if (device->hid->ll_driver->power) + device->hid->ll_driver->power(device->hid, + PM_HINT_NORMAL); + --device->open; + goto exit_unlock; + } + } + + reader->device = device; + /* new reader doesn't get old events */ + reader->cbuf_start = device->cbuf_end; + + list_add_tail(&reader->node, &device->readers); + file->private_data = reader; + +exit_unlock: + mutex_unlock(&device->readers_lock); + mutex_unlock(&devices_lock); + return error; +} + +static int roccat_release(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + struct roccat_reader *reader = file->private_data; + struct roccat_device *device; + + mutex_lock(&devices_lock); + + device = devices[minor]; + if (!device) { + mutex_unlock(&devices_lock); + printk(KERN_EMERG "roccat device with minor %d doesn't exist\n", + minor); + return -ENODEV; + } + + mutex_lock(&device->readers_lock); + list_del(&reader->node); + mutex_unlock(&device->readers_lock); + kfree(reader); + + if (!--device->open) { + /* removing last reader */ + if (device->exist) { + if (device->hid->ll_driver->power) + device->hid->ll_driver->power(device->hid, + PM_HINT_NORMAL); + device->hid->ll_driver->close(device->hid); + } else { + kfree(device); + } + } + + mutex_unlock(&devices_lock); + + return 0; +} + +/* + * roccat_report_event() - output data to readers + * @minor: minor device number returned by roccat_connect() + * @data: pointer to data + * @len: size of data + * + * Return value is zero on success, a negative error code on failure. + * + * This is called from interrupt handler. + */ +int roccat_report_event(int minor, u8 const *data, int len) +{ + struct roccat_device *device; + struct roccat_reader *reader; + struct roccat_report *report; + uint8_t *new_value; + + new_value = kmemdup(data, len, GFP_ATOMIC); + if (!new_value) + return -ENOMEM; + + device = devices[minor]; + + report = &device->cbuf[device->cbuf_end]; + + /* passing NULL is safe */ + kfree(report->value); + + report->value = new_value; + report->len = len; + device->cbuf_end = (device->cbuf_end + 1) % ROCCAT_CBUF_SIZE; + + list_for_each_entry(reader, &device->readers, node) { + /* + * As we already inserted one element, the buffer can't be + * empty. If start and end are equal, buffer is full and we + * increase start, so that slow reader misses one event, but + * gets the newer ones in the right order. + */ + if (reader->cbuf_start == device->cbuf_end) + reader->cbuf_start = (reader->cbuf_start + 1) % ROCCAT_CBUF_SIZE; + } + + wake_up_interruptible(&device->wait); + return 0; +} +EXPORT_SYMBOL_GPL(roccat_report_event); + +/* + * roccat_connect() - create a char device for special event output + * @hid: the hid device the char device should be connected to. + * + * Return value is minor device number in Range [0, ROCCAT_MAX_DEVICES] on + * success, a negative error code on failure. + */ +int roccat_connect(struct hid_device *hid) +{ + unsigned int minor; + struct roccat_device *device; + int temp; + + device = kzalloc(sizeof(struct roccat_device), GFP_KERNEL); + if (!device) + return -ENOMEM; + + mutex_lock(&devices_lock); + + for (minor = 0; minor < ROCCAT_MAX_DEVICES; ++minor) { + if (devices[minor]) + continue; + break; + } + + if (minor < ROCCAT_MAX_DEVICES) { + devices[minor] = device; + } else { + mutex_unlock(&devices_lock); + kfree(device); + return -EINVAL; + } + + device->dev = device_create(roccat_class, &hid->dev, + MKDEV(roccat_major, minor), NULL, + "%s%s%d", "roccat", hid->driver->name, minor); + + if (IS_ERR(device->dev)) { + devices[minor] = NULL; + mutex_unlock(&devices_lock); + temp = PTR_ERR(device->dev); + kfree(device); + return temp; + } + + mutex_unlock(&devices_lock); + + init_waitqueue_head(&device->wait); + INIT_LIST_HEAD(&device->readers); + mutex_init(&device->readers_lock); + mutex_init(&device->cbuf_lock); + device->minor = minor; + device->hid = hid; + device->exist = 1; + device->cbuf_end = 0; + + return minor; +} +EXPORT_SYMBOL_GPL(roccat_connect); + +/* roccat_disconnect() - remove char device from hid device + * @minor: the minor device number returned by roccat_connect() + */ +void roccat_disconnect(int minor) +{ + struct roccat_device *device; + + mutex_lock(&devices_lock); + device = devices[minor]; + devices[minor] = NULL; + mutex_unlock(&devices_lock); + + device->exist = 0; /* TODO exist maybe not needed */ + + device_destroy(roccat_class, MKDEV(roccat_major, minor)); + + if (device->open) { + device->hid->ll_driver->close(device->hid); + wake_up_interruptible(&device->wait); + } else { + kfree(device); + } +} +EXPORT_SYMBOL_GPL(roccat_disconnect); + +static const struct file_operations roccat_ops = { + .owner = THIS_MODULE, + .read = roccat_read, + .poll = roccat_poll, + .open = roccat_open, + .release = roccat_release, +}; + +static int __init roccat_init(void) +{ + int retval; + dev_t dev_id; + + retval = alloc_chrdev_region(&dev_id, ROCCAT_FIRST_MINOR, + ROCCAT_MAX_DEVICES, "roccat"); + + roccat_major = MAJOR(dev_id); + + if (retval < 0) { + printk(KERN_WARNING "roccat: can't get major number\n"); + return retval; + } + + roccat_class = class_create(THIS_MODULE, "roccat"); + if (IS_ERR(roccat_class)) { + retval = PTR_ERR(roccat_class); + unregister_chrdev_region(dev_id, ROCCAT_MAX_DEVICES); + return retval; + } + + cdev_init(&roccat_cdev, &roccat_ops); + cdev_add(&roccat_cdev, dev_id, ROCCAT_MAX_DEVICES); + + return 0; +} + +static void __exit roccat_exit(void) +{ + dev_t dev_id = MKDEV(roccat_major, 0); + + cdev_del(&roccat_cdev); + class_destroy(roccat_class); + unregister_chrdev_region(dev_id, ROCCAT_MAX_DEVICES); +} + +module_init(roccat_init); +module_exit(roccat_exit); + +MODULE_AUTHOR("Stefan Achatz"); +MODULE_DESCRIPTION("USB Roccat char device"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/hid/hid-roccat.h b/drivers/hid/hid-roccat.h new file mode 100644 index 000000000000..40cca5b918dc --- /dev/null +++ b/drivers/hid/hid-roccat.h @@ -0,0 +1,31 @@ +#ifndef __HID_ROCCAT_H +#define __HID_ROCCAT_H + +/* + * Copyright (c) 2010 Stefan Achatz + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include +#include + +#ifdef CONFIG_HID_ROCCAT +int roccat_connect(struct hid_device *hid); +void roccat_disconnect(int minor); +int roccat_report_event(int minor, u8 const *data, int len); +#else +static inline int roccat_connect(struct hid_device *hid) { return -1; } +static inline void roccat_disconnect(int minor) {} +static inline int roccat_report_event(int minor, u8 const *data, int len) +{ + return 0; +} +#endif + +#endif -- cgit v1.2.3 From 0e927bfc87037c1f44d6b61be12c36f6215ee5b2 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Tue, 25 May 2010 09:58:05 +0200 Subject: HID: roccat: fix build failure if built as module Fix build failure when roccat and roccat-kone are built as modules. Signed-off-by: Jiri Kosina --- drivers/hid/hid-roccat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/hid-roccat.h b/drivers/hid/hid-roccat.h index 40cca5b918dc..d8aae0c1fa7e 100644 --- a/drivers/hid/hid-roccat.h +++ b/drivers/hid/hid-roccat.h @@ -15,7 +15,7 @@ #include #include -#ifdef CONFIG_HID_ROCCAT +#if defined(CONFIG_HID_ROCCAT) || defined (CONFIG_HID_ROCCAT_MODULE) int roccat_connect(struct hid_device *hid); void roccat_disconnect(int minor); int roccat_report_event(int minor, u8 const *data, int len); -- cgit v1.2.3 From 42bd5d499455fe4235bb82cffe937a4089a8bba9 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 9 Mar 2010 11:07:40 -0500 Subject: watchdog: bfin: use new common Blackfin watchdog header use new common Blackfin watchdog header Signed-off-by: Mike Frysinger Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/bfin_wdt.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c index 9c7ccd1e9088..9042a95fc98c 100644 --- a/drivers/watchdog/bfin_wdt.c +++ b/drivers/watchdog/bfin_wdt.c @@ -23,6 +23,7 @@ #include #include #include +#include #define stamp(fmt, args...) \ pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args) @@ -49,24 +50,6 @@ # define bfin_write_WDOG_STAT(x) bfin_write_WDOGA_STAT(x) #endif -/* Bit in SWRST that indicates boot caused by watchdog */ -#define SWRST_RESET_WDOG 0x4000 - -/* Bit in WDOG_CTL that indicates watchdog has expired (WDR0) */ -#define WDOG_EXPIRED 0x8000 - -/* Masks for WDEV field in WDOG_CTL register */ -#define ICTL_RESET 0x0 -#define ICTL_NMI 0x2 -#define ICTL_GPI 0x4 -#define ICTL_NONE 0x6 -#define ICTL_MASK 0x6 - -/* Masks for WDEN field in WDOG_CTL register */ -#define WDEN_MASK 0x0FF0 -#define WDEN_ENABLE 0x0000 -#define WDEN_DISABLE 0x0AD0 - /* some defaults */ #define WATCHDOG_TIMEOUT 20 -- cgit v1.2.3 From 76550d3292ba1b0dd1ff0a13d78a2718eba599c7 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 1 May 2010 09:46:15 -0700 Subject: watchdog: fix several MODULE_PARM_DESC strings Fix MODULE_PARM_DESC() strings in several watchdog drivers. Some are simple as add a parenthesis. Others are problems from __stringify() being used on a variable name instead of a macro name, so the variable name is produced in the string instead of its build-time value. In these cases, create a macro for the value so that the module param description string is useful. Only pc87413_wdt has been built (due to toolchains). Signed-off-by: Randy Dunlap Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/mpc8xxx_wdt.c | 2 +- drivers/watchdog/pc87413_wdt.c | 9 ++++++--- drivers/watchdog/pnx833x_wdt.c | 11 +++++++---- drivers/watchdog/s3c2410_wdt.c | 6 +++--- drivers/watchdog/shwdt.c | 2 +- drivers/watchdog/wdt977.c | 2 +- 6 files changed, 19 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c index 7b55974191dd..6622335773bb 100644 --- a/drivers/watchdog/mpc8xxx_wdt.c +++ b/drivers/watchdog/mpc8xxx_wdt.c @@ -53,7 +53,7 @@ static int mpc8xxx_wdt_init_late(void); static u16 timeout = 0xffff; module_param(timeout, ushort, 0); MODULE_PARM_DESC(timeout, - "Watchdog timeout in ticks. (01 for debug, (default 0)"); + "0 to reboot (default 0)"); +MODULE_PARM_DESC(debug, "Watchdog debug, set to >1 for debug (default 0)"); static unsigned long open_lock; static struct device *wdt_dev; /* platform device attached to */ diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index a03f84e5ee1f..6fc74065abee 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c @@ -496,7 +496,7 @@ MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); module_param(clock_division_ratio, int, 0); MODULE_PARM_DESC(clock_division_ratio, "Clock division ratio. Valid ranges are from 0x5 (1.31ms) " - "to 0x7 (5.25ms). (default=" __MODULE_STRING(clock_division_ratio) ")"); + "to 0x7 (5.25ms). (default=" __MODULE_STRING(WTCSR_CKS_4096) ")"); module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, diff --git a/drivers/watchdog/wdt977.c b/drivers/watchdog/wdt977.c index 90ef70eb47d7..5c2521fc836c 100644 --- a/drivers/watchdog/wdt977.c +++ b/drivers/watchdog/wdt977.c @@ -63,7 +63,7 @@ static char expect_close; static DEFINE_SPINLOCK(spinlock); module_param(timeout, int, 0); -MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (60..15300), default=" +MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (60..15300, default=" __MODULE_STRING(DEFAULT_TIMEOUT) ")"); module_param(testmode, int, 0); MODULE_PARM_DESC(testmode, "Watchdog testmode (1 = no reboot), default=0"); -- cgit v1.2.3 From 8b18085a92c72fe1754481890e9dfc600e736b1f Mon Sep 17 00:00:00 2001 From: Wim Van Sebroeck Date: Tue, 27 Apr 2010 08:24:11 +0000 Subject: watchdog: booke_wdt: fix ioctl status flags The WDIOC_GETSTATUS & WDIOC_GETBOOTSTATUS ioctl calls return the WDIOF_* flags and nothing else. Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/booke_wdt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c index 801ead191499..3d49671cdf5a 100644 --- a/drivers/watchdog/booke_wdt.c +++ b/drivers/watchdog/booke_wdt.c @@ -137,12 +137,12 @@ static long booke_wdt_ioctl(struct file *file, if (copy_to_user((void *)arg, &ident, sizeof(ident))) return -EFAULT; case WDIOC_GETSTATUS: - return put_user(ident.options, p); + return put_user(0, p); case WDIOC_GETBOOTSTATUS: /* XXX: something is clearing TSR */ tmp = mfspr(SPRN_TSR) & TSR_WRS(3); - /* returns 1 if last reset was caused by the WDT */ - return (tmp ? 1 : 0); + /* returns CARDRESET if last reset was caused by the WDT */ + return (tmp ? WDIOF_CARDRESET : 0); case WDIOC_SETOPTIONS: if (get_user(tmp, p)) return -EINVAL; -- cgit v1.2.3 From 4724ba575ea73431aba8a48be6f5a382c470418d Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 3 May 2010 11:42:52 -0700 Subject: watchdog: update/improve/consolidate watchdog driver Move the limited watchdog driver help from kernel-parameters.txt to Documentation/watchdog/watchdog-parameters.txt and add info to it for all watchdog drivers except the ones that have driver-specific files already. Correct minor comments and MODULE_PARM_DESC() text in 2 places. Signed-off-by: Randy Dunlap Signed-off-by: Wim Van Sebroeck --- Documentation/kernel-parameters.txt | 15 +- Documentation/watchdog/00-INDEX | 5 + Documentation/watchdog/watchdog-parameters.txt | 390 +++++++++++++++++++++++++ Documentation/watchdog/wdt.txt | 15 +- drivers/watchdog/eurotechwdt.c | 1 - drivers/watchdog/wdt.c | 2 +- 6 files changed, 411 insertions(+), 17 deletions(-) create mode 100644 Documentation/watchdog/watchdog-parameters.txt (limited to 'drivers') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index f5fce483930c..b56ea860da21 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -290,9 +290,6 @@ and is between 256 and 4096 characters. It is defined in the file advansys= [HW,SCSI] See header of drivers/scsi/advansys.c. - advwdt= [HW,WDT] Advantech WDT - Format: , - aedsp16= [HW,OSS] Audio Excel DSP 16 Format: ,,,,, See also header of sound/oss/aedsp16.c. @@ -765,9 +762,6 @@ and is between 256 and 4096 characters. It is defined in the file This option is obsoleted by the "netdev=" option, which has equivalent usage. See its documentation for details. - eurwdt= [HW,WDT] Eurotech CPU-1220/1410 onboard watchdog. - Format: [,] - failslab= fail_page_alloc= fail_make_request=[KNL] @@ -2267,9 +2261,6 @@ and is between 256 and 4096 characters. It is defined in the file sched_debug [KNL] Enables verbose scheduler debug messages. - sc1200wdt= [HW,WDT] SC1200 WDT (watchdog) driver - Format: [,[,]] - scsi_debug_*= [SCSI] See drivers/scsi/scsi_debug.c. @@ -2858,8 +2849,10 @@ and is between 256 and 4096 characters. It is defined in the file wd7000= [HW,SCSI] See header of drivers/scsi/wd7000.c. - wdt= [WDT] Watchdog - See Documentation/watchdog/wdt.txt. + watchdog timers [HW,WDT] For information on watchdog timers, + see Documentation/watchdog/watchdog-parameters.txt + or other driver-specific files in the + Documentation/watchdog/ directory. x2apic_phys [X86-64,APIC] Use x2apic physical mode instead of default x2apic cluster mode on platforms diff --git a/Documentation/watchdog/00-INDEX b/Documentation/watchdog/00-INDEX index c3ea47e507fe..ee994513a9b1 100644 --- a/Documentation/watchdog/00-INDEX +++ b/Documentation/watchdog/00-INDEX @@ -1,10 +1,15 @@ 00-INDEX - this file. +hpwdt.txt + - information on the HP iLO2 NMI watchdog pcwd-watchdog.txt - documentation for Berkshire Products PC Watchdog ISA cards. src/ - directory holding watchdog related example programs. watchdog-api.txt - description of the Linux Watchdog driver API. +watchdog-parameters.txt + - information on driver parameters (for drivers other than + the ones that have driver-specific files here) wdt.txt - description of the Watchdog Timer Interfaces for Linux. diff --git a/Documentation/watchdog/watchdog-parameters.txt b/Documentation/watchdog/watchdog-parameters.txt new file mode 100644 index 000000000000..41c95cc1dc1f --- /dev/null +++ b/Documentation/watchdog/watchdog-parameters.txt @@ -0,0 +1,390 @@ +This file provides information on the module parameters of many of +the Linux watchdog drivers. Watchdog driver parameter specs should +be listed here unless the driver has its own driver-specific information +file. + + +See Documentation/kernel-parameters.txt for information on +providing kernel parameters for builtin drivers versus loadable +modules. + + +------------------------------------------------- +acquirewdt: +wdt_stop: Acquire WDT 'stop' io port (default 0x43) +wdt_start: Acquire WDT 'start' io port (default 0x443) +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- +advantechwdt: +wdt_stop: Advantech WDT 'stop' io port (default 0x443) +wdt_start: Advantech WDT 'start' io port (default 0x443) +timeout: Watchdog timeout in seconds. 1<= timeout <=63, default=60. +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- +alim1535_wdt: +timeout: Watchdog timeout in seconds. (0 < timeout < 18000, default=60 +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- +alim7101_wdt: +timeout: Watchdog timeout in seconds. (1<=timeout<=3600, default=30 +use_gpio: Use the gpio watchdog (required by old cobalt boards). + default=0/off/no +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- +ar7_wdt: +margin: Watchdog margin in seconds (default=60) +nowayout: Disable watchdog shutdown on close + (default=kernel config parameter) +------------------------------------------------- +at32ap700x_wdt: +timeout: Timeout value. Limited to be 1 or 2 seconds. (default=2) +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- +at91rm9200_wdt: +wdt_time: Watchdog time in seconds. (default=5) +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- +at91sam9_wdt: +heartbeat: Watchdog heartbeats in seconds. (default = 15) +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- +bcm47xx_wdt: +wdt_time: Watchdog time in seconds. (default=30) +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- +bfin_wdt: +timeout: Watchdog timeout in seconds. (1<=timeout<=((2^32)/SCLK), default=20) +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- +coh901327_wdt: +margin: Watchdog margin in seconds (default 60s) +------------------------------------------------- +cpu5wdt: +port: base address of watchdog card, default is 0x91 +verbose: be verbose, default is 0 (no) +ticks: count down ticks, default is 10000 +------------------------------------------------- +cpwd: +wd0_timeout: Default watchdog0 timeout in 1/10secs +wd1_timeout: Default watchdog1 timeout in 1/10secs +wd2_timeout: Default watchdog2 timeout in 1/10secs +------------------------------------------------- +davinci_wdt: +heartbeat: Watchdog heartbeat period in seconds from 1 to 600, default 60 +------------------------------------------------- +ep93xx_wdt: +nowayout: Watchdog cannot be stopped once started +timeout: Watchdog timeout in seconds. (1<=timeout<=3600, default=TBD) +------------------------------------------------- +eurotechwdt: +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +io: Eurotech WDT io port (default=0x3f0) +irq: Eurotech WDT irq (default=10) +ev: Eurotech WDT event type (default is `int') +------------------------------------------------- +gef_wdt: +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- +geodewdt: +timeout: Watchdog timeout in seconds. 1<= timeout <=131, default=60. +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- +i6300esb: +heartbeat: Watchdog heartbeat in seconds. (11 for debug, (default 0) +------------------------------------------------- +sa1100_wdt: +margin: Watchdog margin in seconds (default 60s) +------------------------------------------------- +sb_wdog: +timeout: Watchdog timeout in microseconds (max/default 8388607 or 8.3ish secs) +------------------------------------------------- +sbc60xxwdt: +wdt_stop: SBC60xx WDT 'stop' io port (default 0x45) +wdt_start: SBC60xx WDT 'start' io port (default 0x443) +timeout: Watchdog timeout in seconds. (1<=timeout<=3600, default=30) +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- +sbc7240_wdt: +timeout: Watchdog timeout in seconds. (1<=timeout<=255, default=30) +nowayout: Disable watchdog when closing device file +------------------------------------------------- +sbc8360: +timeout: Index into timeout table (0-63) (default=27 (60s)) +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- +sbc_epx_c3: +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- +sbc_fitpc2_wdt: +margin: Watchdog margin in seconds (default 60s) +nowayout: Watchdog cannot be stopped once started +------------------------------------------------- +sc1200wdt: +isapnp: When set to 0 driver ISA PnP support will be disabled (default=1) +io: io port +timeout: range is 0-255 minutes, default is 1 +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- +sc520_wdt: +timeout: Watchdog timeout in seconds. (1 <= timeout <= 3600, default=30) +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- +sch311x_wdt: +force_id: Override the detected device ID +therm_trip: Should a ThermTrip trigger the reset generator +timeout: Watchdog timeout in seconds. 1<= timeout <=15300, default=60 +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- +scx200_wdt: +margin: Watchdog margin in seconds +nowayout: Disable watchdog shutdown on close +------------------------------------------------- +shwdt: +clock_division_ratio: Clock division ratio. Valid ranges are from 0x5 (1.31ms) + to 0x7 (5.25ms). (default=7) +heartbeat: Watchdog heartbeat in seconds. (1 <= heartbeat <= 3600, default=30 +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- +smsc37b787_wdt: +timeout: range is 1-255 units, default is 60 +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- +softdog: +soft_margin: Watchdog soft_margin in seconds. + (0 < soft_margin < 65536, default=60) +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +soft_noboot: Softdog action, set to 1 to ignore reboots, 0 to reboot + (default=0) +------------------------------------------------- +stmp3xxx_wdt: +heartbeat: Watchdog heartbeat period in seconds from 1 to 4194304, default 19 +------------------------------------------------- +ts72xx_wdt: +timeout: Watchdog timeout in seconds. (1 <= timeout <= 8, default=8) +nowayout: Disable watchdog shutdown on close +------------------------------------------------- +twl4030_wdt: +nowayout: Watchdog cannot be stopped once started + (default=kernel config parameter) +------------------------------------------------- +txx9wdt: +timeout: Watchdog timeout in seconds. (0 Date: Mon, 17 May 2010 14:12:15 +0300 Subject: watchdog: twl4030_wdt: Disable watchdog during probing If we are not able to register then it is better to have watchdog in disabled state than noticing a system reboot. Signed-off-by: Ameya Palande Acked-By: Timo Kokkonen Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/twl4030_wdt.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c index dcabe77ad141..b5045ca7e61c 100644 --- a/drivers/watchdog/twl4030_wdt.c +++ b/drivers/watchdog/twl4030_wdt.c @@ -190,6 +190,8 @@ static int __devinit twl4030_wdt_probe(struct platform_device *pdev) twl4030_wdt_dev = pdev; + twl4030_wdt_disable(wdt); + ret = misc_register(&wdt->miscdev); if (ret) { dev_err(wdt->miscdev.parent, -- cgit v1.2.3 From 7e6811daa662fc4eb87ddfb3ea0ea9d782044157 Mon Sep 17 00:00:00 2001 From: Pádraig Brady Date: Mon, 19 Apr 2010 13:38:25 +0100 Subject: iTCO_wdt: fix TCO V1 timeout values and limits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For TCO V1 devices the programmed timeout was twice too long because the fact that the TCO V1 timer needs to count down twice before triggering the watchdog, wasn't accounted for. Also the timeout values in the module description and error message were clarified. And the _STS registers are 16 bit instead of 8 bit. Signed-off-by: Pádraig Brady Tested-by: Simon Kagstrom Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/iTCO_vendor_support.c | 11 +---------- drivers/watchdog/iTCO_wdt.c | 29 ++++++++++++++++++++--------- 2 files changed, 21 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c index 5133bca5ccbe..481d1ad43464 100644 --- a/drivers/watchdog/iTCO_vendor_support.c +++ b/drivers/watchdog/iTCO_vendor_support.c @@ -101,13 +101,6 @@ static void supermicro_old_pre_stop(unsigned long acpibase) outl(val32, SMI_EN); /* Needed to deactivate watchdog */ } -static void supermicro_old_pre_keepalive(unsigned long acpibase) -{ - /* Reload TCO Timer (done in iTCO_wdt_keepalive) + */ - /* Clear "Expire Flag" (Bit 3 of TC01_STS register) */ - outb(0x08, TCO1_STS); -} - /* * Vendor Support: 2 * Board: Super Micro Computer Inc. P4SBx, P4DPx @@ -337,9 +330,7 @@ EXPORT_SYMBOL(iTCO_vendor_pre_stop); void iTCO_vendor_pre_keepalive(unsigned long acpibase, unsigned int heartbeat) { - if (vendorsupport == SUPERMICRO_OLD_BOARD) - supermicro_old_pre_keepalive(acpibase); - else if (vendorsupport == SUPERMICRO_NEW_BOARD) + if (vendorsupport == SUPERMICRO_NEW_BOARD) supermicro_new_pre_set_heartbeat(heartbeat); } EXPORT_SYMBOL(iTCO_vendor_pre_keepalive); diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 8da886035374..69de8713b8e4 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c @@ -40,7 +40,7 @@ /* Module and version information */ #define DRV_NAME "iTCO_wdt" -#define DRV_VERSION "1.05" +#define DRV_VERSION "1.06" #define PFX DRV_NAME ": " /* Includes */ @@ -391,8 +391,8 @@ static struct platform_device *iTCO_wdt_platform_device; #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ module_param(heartbeat, int, 0); -MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. " - "(2 Date: Thu, 20 May 2010 11:58:24 +0100 Subject: watchdog: s3c2410_wdt - Add extra option to include watchdog for Samsung SoCs This patch adds HAVE_S3C2410_WATCHDOG to control inclusion of watchdog driver for Samsung SoCs. This option will help to include the driver only for the necessary machines and not for all for any given arch. Signed-off-by: Banajit Goswami Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/Kconfig | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index b87ba23442d2..c57ecffe0085 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -145,13 +145,19 @@ config KS8695_WATCHDOG Watchdog timer embedded into KS8695 processor. This will reboot your system when the timeout is reached. +config HAVE_S3C2410_WATCHDOG + bool + help + This will include watchdog timer support for Samsung SoCs. If + you want to include watchdog support for any machine, kindly + select this in the respective mach-XXXX/Kconfig file. + config S3C2410_WATCHDOG tristate "S3C2410 Watchdog" - depends on ARCH_S3C2410 + depends on ARCH_S3C2410 || HAVE_S3C2410_WATCHDOG help - Watchdog timer block in the Samsung S3C2410 chips. This will - reboot the system when the timer expires with the watchdog - enabled. + Watchdog timer block in the Samsung SoCs. This will reboot + the system when the timer expires with the watchdog enabled. The driver is limited by the speed of the system's PCLK signal, so with reasonably fast systems (PCLK around 50-66MHz) -- cgit v1.2.3 From 100fb76f0acfebcb7c72875890b9ef33ff04dc2b Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Thu, 20 May 2010 11:58:25 +0100 Subject: watchdog: s3c2410_wdt - Fix on handling of the request_mem_region fail If the request for wdt_mem region fails, this patch modifies the driver such that, it does not try to release the wdt_mem region on exit. Signed-off-by: Banajit Goswami Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/s3c2410_wdt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 095cbf38eb5d..300932580ded 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c @@ -426,8 +426,7 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) wdt_mem = request_mem_region(res->start, size, pdev->name); if (wdt_mem == NULL) { dev_err(dev, "failed to get memory region\n"); - ret = -ENOENT; - goto err_req; + return -EBUSY; } wdt_base = ioremap(res->start, size); -- cgit v1.2.3 From 0178f3e28e2166664916265c5d4922b1376b9fa1 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 26 Apr 2010 15:18:14 +0100 Subject: regulator: Allow regulator-regulator supplies to be specified by name When one regulator supplies another allow the relationship to be specified using names rather than struct regulators, in a similar manner to that allowed for consumer supplies. This allows static configuration at compile time, reducing the need for dynamic init code. Also change the references to LINE supply to be system supply since line is sometimes used for actual supplies and therefore potentially confusing. Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/core.c | 30 ++++++++++++++++++++++++++++++ include/linux/regulator/machine.h | 9 +++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 51cf2bb37438..eb112d961515 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2328,7 +2328,37 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, goto scrub; /* set supply regulator if it exists */ + if (init_data->supply_regulator && init_data->supply_regulator_dev) { + dev_err(dev, + "Supply regulator specified by both name and dev\n"); + goto scrub; + } + + if (init_data->supply_regulator) { + struct regulator_dev *r; + int found = 0; + + list_for_each_entry(r, ®ulator_list, list) { + if (strcmp(rdev_get_name(r), + init_data->supply_regulator) == 0) { + found = 1; + break; + } + } + + if (!found) { + dev_err(dev, "Failed to find supply %s\n", + init_data->supply_regulator); + goto scrub; + } + + ret = set_supply(rdev, r); + if (ret < 0) + goto scrub; + } + if (init_data->supply_regulator_dev) { + dev_warn(dev, "Uses supply_regulator_dev instead of regulator_supply\n"); ret = set_supply(rdev, dev_get_drvdata(init_data->supply_regulator_dev)); if (ret < 0) diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 234a8476cba8..e2980287245e 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -157,7 +157,11 @@ struct regulator_consumer_supply { * * Initialisation constraints, our supply and consumers supplies. * - * @supply_regulator_dev: Parent regulator (if any). + * @supply_regulator: Parent regulator. Specified using the regulator name + * as it appears in the name field in sysfs, which can + * be explicitly set using the constraints field 'name'. + * @supply_regulator_dev: Parent regulator (if any) - DEPRECATED in favour + * of supply_regulator. * * @constraints: Constraints. These must be specified for the regulator to * be usable. @@ -168,7 +172,8 @@ struct regulator_consumer_supply { * @driver_data: Data passed to regulator_init. */ struct regulator_init_data { - struct device *supply_regulator_dev; /* or NULL for LINE */ + const char *supply_regulator; /* or NULL for system supply */ + struct device *supply_regulator_dev; /* or NULL for system supply */ struct regulation_constraints constraints; -- cgit v1.2.3 From 23b5cc2ab6783256cf06779e1d522482b819b808 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 29 Apr 2010 10:55:09 +0300 Subject: regulator: prevent registration of matching regulator consumer supplies Acked-by: Mark Brown Pointer comparison is not sufficient for non-NULL device name matching, so use strcmp(). Otherwise the semantics remain the same. Signed-off-by: Jani Nikula Signed-off-by: Liam Girdwood --- drivers/regulator/core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index eb112d961515..2a3494f72465 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -944,8 +944,13 @@ static int set_consumer_device_supply(struct regulator_dev *rdev, has_dev = 0; list_for_each_entry(node, ®ulator_map_list, list) { - if (consumer_dev_name != node->dev_name) + if (node->dev_name && consumer_dev_name) { + if (strcmp(node->dev_name, consumer_dev_name) != 0) + continue; + } else if (node->dev_name || consumer_dev_name) { continue; + } + if (strcmp(node->supply, supply) != 0) continue; -- cgit v1.2.3 From 47bd53f0e8008294ff58c5b37d713f25a8dc56aa Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 29 Apr 2010 10:55:10 +0300 Subject: regulator: fix unset_regulator_supplies() to remove all matches Remove all matching consumer supplies, not just the first, to not leave dangling pointers. Signed-off-by: Jani Nikula Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/core.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 2a3494f72465..a50672f33afa 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1013,7 +1013,6 @@ static void unset_regulator_supplies(struct regulator_dev *rdev) list_del(&node->list); kfree(node->dev_name); kfree(node); - return; } } } -- cgit v1.2.3 From d4033b54fc91221b13e2850bf298683c0f2ff37d Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 29 Apr 2010 10:55:11 +0300 Subject: regulator: simplify regulator_register() error handling Simply remove all consumer supplies for the regulator on errors. Remove unset_consumer_device_supply() which is no longer used. Signed-off-by: Jani Nikula Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/core.c | 35 +++++------------------------------ 1 file changed, 5 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index a50672f33afa..98e5d14f94f3 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -981,29 +981,6 @@ static int set_consumer_device_supply(struct regulator_dev *rdev, return 0; } -static void unset_consumer_device_supply(struct regulator_dev *rdev, - const char *consumer_dev_name, struct device *consumer_dev) -{ - struct regulator_map *node, *n; - - if (consumer_dev && !consumer_dev_name) - consumer_dev_name = dev_name(consumer_dev); - - list_for_each_entry_safe(node, n, ®ulator_map_list, list) { - if (rdev != node->regulator) - continue; - - if (consumer_dev_name && node->dev_name && - strcmp(consumer_dev_name, node->dev_name)) - continue; - - list_del(&node->list); - kfree(node->dev_name); - kfree(node); - return; - } -} - static void unset_regulator_supplies(struct regulator_dev *rdev) { struct regulator_map *node, *n; @@ -2375,13 +2352,8 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, init_data->consumer_supplies[i].dev, init_data->consumer_supplies[i].dev_name, init_data->consumer_supplies[i].supply); - if (ret < 0) { - for (--i; i >= 0; i--) - unset_consumer_device_supply(rdev, - init_data->consumer_supplies[i].dev_name, - init_data->consumer_supplies[i].dev); - goto scrub; - } + if (ret < 0) + goto unset_supplies; } list_add(&rdev->list, ®ulator_list); @@ -2389,6 +2361,9 @@ out: mutex_unlock(®ulator_list_mutex); return rdev; +unset_supplies: + unset_regulator_supplies(rdev); + scrub: device_unregister(&rdev->dev); /* device core frees rdev */ -- cgit v1.2.3 From 192bbb95ca16f2b4d4383e76b3262672e6116daa Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Thu, 29 Apr 2010 13:33:50 -0400 Subject: regulator: make 88pm860x sharing one driver structure Remove a lot of driver structures in 88pm860x driver. Make regulators share one driver structure. Signed-off-by: Haojian Zhuang Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/mfd/88pm860x-core.c | 34 ++++++++++++++--------------- drivers/regulator/88pm8607.c | 51 +++++++++----------------------------------- 2 files changed, 27 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index 6a14d2b1ccf0..21de38daf948 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c @@ -176,30 +176,30 @@ static struct resource regulator_resources[] = { PM8607_REG_RESOURCE(LDO14, LDO14), }; -#define PM8607_REG_DEVS(_name, _id) \ +#define PM8607_REG_DEVS(_id) \ { \ - .name = "88pm8607-" #_name, \ + .name = "88pm860x-regulator", \ .num_resources = 1, \ .resources = ®ulator_resources[PM8607_ID_##_id], \ .id = PM8607_ID_##_id, \ } static struct mfd_cell regulator_devs[] = { - PM8607_REG_DEVS(buck1, BUCK1), - PM8607_REG_DEVS(buck2, BUCK2), - PM8607_REG_DEVS(buck3, BUCK3), - PM8607_REG_DEVS(ldo1, LDO1), - PM8607_REG_DEVS(ldo2, LDO2), - PM8607_REG_DEVS(ldo3, LDO3), - PM8607_REG_DEVS(ldo4, LDO4), - PM8607_REG_DEVS(ldo5, LDO5), - PM8607_REG_DEVS(ldo6, LDO6), - PM8607_REG_DEVS(ldo7, LDO7), - PM8607_REG_DEVS(ldo8, LDO8), - PM8607_REG_DEVS(ldo9, LDO9), - PM8607_REG_DEVS(ldo10, LDO10), - PM8607_REG_DEVS(ldo12, LDO12), - PM8607_REG_DEVS(ldo14, LDO14), + PM8607_REG_DEVS(BUCK1), + PM8607_REG_DEVS(BUCK2), + PM8607_REG_DEVS(BUCK3), + PM8607_REG_DEVS(LDO1), + PM8607_REG_DEVS(LDO2), + PM8607_REG_DEVS(LDO3), + PM8607_REG_DEVS(LDO4), + PM8607_REG_DEVS(LDO5), + PM8607_REG_DEVS(LDO6), + PM8607_REG_DEVS(LDO7), + PM8607_REG_DEVS(LDO8), + PM8607_REG_DEVS(LDO9), + PM8607_REG_DEVS(LDO10), + PM8607_REG_DEVS(LDO12), + PM8607_REG_DEVS(LDO14), }; struct pm860x_irq_data { diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index 5fb83e2ced25..121bab4c0dc0 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -484,60 +484,29 @@ static int __devexit pm8607_regulator_remove(struct platform_device *pdev) { struct pm8607_regulator_info *info = platform_get_drvdata(pdev); + platform_set_drvdata(pdev, NULL); regulator_unregister(info->regulator); return 0; } -#define PM8607_REGULATOR_DRIVER(_name) \ -{ \ - .driver = { \ - .name = "88pm8607-" #_name, \ - .owner = THIS_MODULE, \ - }, \ - .probe = pm8607_regulator_probe, \ - .remove = __devexit_p(pm8607_regulator_remove), \ -} - -static struct platform_driver pm8607_regulator_driver[] = { - PM8607_REGULATOR_DRIVER(buck1), - PM8607_REGULATOR_DRIVER(buck2), - PM8607_REGULATOR_DRIVER(buck3), - PM8607_REGULATOR_DRIVER(ldo1), - PM8607_REGULATOR_DRIVER(ldo2), - PM8607_REGULATOR_DRIVER(ldo3), - PM8607_REGULATOR_DRIVER(ldo4), - PM8607_REGULATOR_DRIVER(ldo5), - PM8607_REGULATOR_DRIVER(ldo6), - PM8607_REGULATOR_DRIVER(ldo7), - PM8607_REGULATOR_DRIVER(ldo8), - PM8607_REGULATOR_DRIVER(ldo9), - PM8607_REGULATOR_DRIVER(ldo10), - PM8607_REGULATOR_DRIVER(ldo12), - PM8607_REGULATOR_DRIVER(ldo14), +static struct platform_driver pm8607_regulator_driver = { + .driver = { + .name = "88pm860x-regulator", + .owner = THIS_MODULE, + }, + .probe = pm8607_regulator_probe, + .remove = __devexit_p(pm8607_regulator_remove), }; static int __init pm8607_regulator_init(void) { - int i, count, ret; - - count = ARRAY_SIZE(pm8607_regulator_driver); - for (i = 0; i < count; i++) { - ret = platform_driver_register(&pm8607_regulator_driver[i]); - if (ret != 0) - pr_err("Failed to register regulator driver: %d\n", - ret); - } - return 0; + return platform_driver_register(&pm8607_regulator_driver); } subsys_initcall(pm8607_regulator_init); static void __exit pm8607_regulator_exit(void) { - int i, count; - - count = ARRAY_SIZE(pm8607_regulator_driver); - for (i = 0; i < count; i++) - platform_driver_unregister(&pm8607_regulator_driver[i]); + platform_driver_unregister(&pm8607_regulator_driver); } module_exit(pm8607_regulator_exit); -- cgit v1.2.3 From 9f79e9db2e282857912bcfe7f741bcdd5c46e860 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Tue, 4 May 2010 09:54:51 -0400 Subject: regulator: use voltage number array in 88pm860x A lot of condition comparision statements are used in original driver. These statements are used to check the boundary of voltage numbers since voltage number isn't linear. Now use array of voltage numbers instead. Clean code with simpler way. Signed-off-by: Haojian Zhuang Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/mfd/88pm860x-core.c | 2 + drivers/regulator/88pm8607.c | 482 ++++++++++++++++++++----------------------- include/linux/mfd/88pm860x.h | 3 +- 3 files changed, 224 insertions(+), 263 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index 21de38daf948..405d2d5183cf 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c @@ -173,6 +173,7 @@ static struct resource regulator_resources[] = { PM8607_REG_RESOURCE(LDO9, LDO9), PM8607_REG_RESOURCE(LDO10, LDO10), PM8607_REG_RESOURCE(LDO12, LDO12), + PM8607_REG_RESOURCE(VIBRATOR_SET, VIBRATOR_SET), PM8607_REG_RESOURCE(LDO14, LDO14), }; @@ -199,6 +200,7 @@ static struct mfd_cell regulator_devs[] = { PM8607_REG_DEVS(LDO9), PM8607_REG_DEVS(LDO10), PM8607_REG_DEVS(LDO12), + PM8607_REG_DEVS(LDO13), PM8607_REG_DEVS(LDO14), }; diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index 121bab4c0dc0..7d149a8d8d9b 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -23,9 +23,9 @@ struct pm8607_regulator_info { struct regulator_dev *regulator; struct i2c_client *i2c; - int min_uV; - int max_uV; - int step_uV; + unsigned int *vol_table; + unsigned int *vol_suspend; + int vol_reg; int vol_shift; int vol_nbits; @@ -36,83 +36,189 @@ struct pm8607_regulator_info { int slope_double; }; -static inline int check_range(struct pm8607_regulator_info *info, - int min_uV, int max_uV) -{ - if (max_uV < info->min_uV || min_uV > info->max_uV || min_uV > max_uV) - return -EINVAL; +static const unsigned int BUCK1_table[] = { + 725000, 750000, 775000, 800000, 825000, 850000, 875000, 900000, + 925000, 950000, 975000, 1000000, 1025000, 1050000, 1075000, 1100000, + 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, + 1325000, 1350000, 1375000, 1400000, 1425000, 1450000, 1475000, 1500000, + 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000, + 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000, + 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000, + 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000, +}; - return 0; -} +static const unsigned int BUCK1_suspend_table[] = { + 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000, + 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000, + 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000, + 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000, + 800000, 825000, 850000, 875000, 900000, 925000, 950000, 975000, + 1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, + 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000, + 1400000, 1425000, 1450000, 1475000, 1500000, 1500000, 1500000, 1500000, +}; + +static const unsigned int BUCK2_table[] = { + 0, 50000, 100000, 150000, 200000, 250000, 300000, 350000, + 400000, 450000, 500000, 550000, 600000, 650000, 700000, 750000, + 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, 1150000, + 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, 1550000, + 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, 1950000, + 2000000, 2050000, 2100000, 2150000, 2200000, 2250000, 2300000, 2350000, + 2400000, 2450000, 2500000, 2550000, 2600000, 2650000, 2700000, 2750000, + 2800000, 2850000, 2900000, 2950000, 3000000, 3000000, 3000000, 3000000, +}; + +static const unsigned int BUCK2_suspend_table[] = { + 0, 50000, 100000, 150000, 200000, 250000, 300000, 350000, + 400000, 450000, 500000, 550000, 600000, 650000, 700000, 750000, + 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, 1150000, + 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, 1550000, + 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, 1950000, + 2000000, 2050000, 2100000, 2150000, 2200000, 2250000, 2300000, 2350000, + 2400000, 2450000, 2500000, 2550000, 2600000, 2650000, 2700000, 2750000, + 2800000, 2850000, 2900000, 2950000, 3000000, 3000000, 3000000, 3000000, +}; + +static const unsigned int BUCK3_table[] = { + 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000, + 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000, + 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000, + 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000, + 800000, 825000, 850000, 875000, 900000, 925000, 950000, 975000, + 1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, + 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000, + 1400000, 1425000, 1450000, 1475000, 1500000, 1500000, 1500000, 1500000, +}; + +static const unsigned int BUCK3_suspend_table[] = { + 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000, + 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000, + 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000, + 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000, + 800000, 825000, 850000, 875000, 900000, 925000, 950000, 975000, + 1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, + 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000, + 1400000, 1425000, 1450000, 1475000, 1500000, 1500000, 1500000, 1500000, +}; + +static const unsigned int LDO1_table[] = { + 1800000, 1200000, 2800000, 0, +}; + +static const unsigned int LDO1_suspend_table[] = { + 1800000, 1200000, 0, 0, +}; + +static const unsigned int LDO2_table[] = { + 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 3300000, +}; + +static const unsigned int LDO2_suspend_table[] = { + 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000, +}; + +static const unsigned int LDO3_table[] = { + 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 3300000, +}; + +static const unsigned int LDO3_suspend_table[] = { + 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000, +}; + +static const unsigned int LDO4_table[] = { + 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2900000, 3300000, +}; + +static const unsigned int LDO4_suspend_table[] = { + 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2900000, 2900000, +}; + +static const unsigned int LDO5_table[] = { + 2900000, 3000000, 3100000, 3300000, +}; + +static const unsigned int LDO5_suspend_table[] = { + 2900000, 0, 0, 0, +}; + +static const unsigned int LDO6_table[] = { + 1800000, 1850000, 2600000, 2650000, 2700000, 2750000, 2800000, 3300000, +}; + +static const unsigned int LDO6_suspend_table[] = { + 1800000, 1850000, 2600000, 2650000, 2700000, 2750000, 2800000, 2900000, +}; + +static const unsigned int LDO7_table[] = { + 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000, +}; + +static const unsigned int LDO7_suspend_table[] = { + 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000, +}; + +static const unsigned int LDO8_table[] = { + 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000, +}; + +static const unsigned int LDO8_suspend_table[] = { + 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000, +}; + +static const unsigned int LDO9_table[] = { + 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 3300000, +}; + +static const unsigned int LDO9_suspend_table[] = { + 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000, +}; + +static const unsigned int LDO10_table[] = { + 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 3300000, + 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, +}; + +static const unsigned int LDO10_suspend_table[] = { + 1800000, 1850000, 1900000, 2700000, 2750000, 2800000, 2850000, 2900000, + 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, +}; + +static const unsigned int LDO12_table[] = { + 1800000, 1900000, 2700000, 2800000, 2900000, 3000000, 3100000, 3300000, + 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, +}; + +static const unsigned int LDO12_suspend_table[] = { + 1800000, 1900000, 2700000, 2800000, 2900000, 2900000, 2900000, 2900000, + 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, 1200000, +}; + +static const unsigned int LDO13_table[] = { + 1300000, 1800000, 2000000, 2500000, 2800000, 3000000, 0, 0, +}; + +static const unsigned int LDO13_suspend_table[] = { + 0, +}; + +static const unsigned int LDO14_table[] = { + 1800000, 1850000, 2700000, 2750000, 2800000, 2850000, 2900000, 3300000, +}; + +static const unsigned int LDO14_suspend_table[] = { + 1800000, 1850000, 2700000, 2750000, 2800000, 2850000, 2900000, 2900000, +}; static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) { struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); int ret = -EINVAL; - switch (info->desc.id) { - case PM8607_ID_BUCK1: - ret = (index < 0x1d) ? (index * 25000 + 800000) : - ((index < 0x20) ? 1500000 : - ((index < 0x40) ? ((index - 0x20) * 25000) : - -EINVAL)); - break; - case PM8607_ID_BUCK3: - ret = (index < 0x3d) ? (index * 25000) : - ((index < 0x40) ? 1500000 : -EINVAL); - if (ret < 0) - break; + if (info->vol_table && (index < (2 << info->vol_nbits))) { + ret = info->vol_table[index]; if (info->slope_double) ret <<= 1; - break; - case PM8607_ID_LDO1: - ret = (index == 0) ? 1800000 : - ((index == 1) ? 1200000 : - ((index == 2) ? 2800000 : -EINVAL)); - break; - case PM8607_ID_LDO5: - ret = (index == 0) ? 2900000 : - ((index == 1) ? 3000000 : - ((index == 2) ? 3100000 : 3300000)); - break; - case PM8607_ID_LDO7: - case PM8607_ID_LDO8: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 8) ? (index * 50000 + 2550000) : - -EINVAL); - break; - case PM8607_ID_LDO12: - ret = (index < 2) ? (index * 100000 + 1800000) : - ((index < 7) ? (index * 100000 + 2500000) : - ((index == 7) ? 3300000 : 1200000)); - break; - case PM8607_ID_LDO2: - case PM8607_ID_LDO3: - case PM8607_ID_LDO9: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 7) ? (index * 50000 + 2550000) : - 3300000); - break; - case PM8607_ID_LDO4: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 6) ? (index * 50000 + 2550000) : - ((index == 6) ? 2900000 : 3300000)); - break; - case PM8607_ID_LDO6: - ret = (index < 2) ? (index * 50000 + 1800000) : - ((index < 7) ? (index * 50000 + 2500000) : - 3300000); - break; - case PM8607_ID_LDO10: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 7) ? (index * 50000 + 2550000) : - ((index == 7) ? 3300000 : 1200000)); - break; - case PM8607_ID_LDO14: - ret = (index < 2) ? (index * 50000 + 1800000) : - ((index < 7) ? (index * 50000 + 2600000) : - 3300000); - break; } return ret; } @@ -120,174 +226,26 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) { struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); - int val = -ENOENT; - int ret; + int i, ret = -ENOENT; - switch (info->desc.id) { - case PM8607_ID_BUCK1: - if (min_uV >= 800000) /* 800mV ~ 1500mV / 25mV */ - val = (min_uV - 775001) / 25000; - else { /* 25mV ~ 775mV / 25mV */ - val = (min_uV + 249999) / 25000; - val += 32; - } - break; - case PM8607_ID_BUCK3: - if (info->slope_double) - min_uV = min_uV >> 1; - val = (min_uV + 249999) / 25000; /* 0mV ~ 1500mV / 25mV */ - - break; - case PM8607_ID_LDO1: - if (min_uV > 1800000) - val = 2; - else if (min_uV > 1200000) - val = 0; - else - val = 1; - break; - case PM8607_ID_LDO5: - if (min_uV > 3100000) - val = 3; - else /* 2900mV ~ 3100mV / 100mV */ - val = (min_uV - 2800001) / 100000; - break; - case PM8607_ID_LDO7: - case PM8607_ID_LDO8: - if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ - if (min_uV <= 1800000) - val = 0; /* 1800mv */ - else if (min_uV <= 1900000) - val = (min_uV - 1750001) / 50000; - else - val = 3; /* 2700mV */ - } else { /* 2700mV ~ 2900mV / 50mV */ - if (min_uV <= 2900000) { - val = (min_uV - 2650001) / 50000; - val += 3; - } else - val = -EINVAL; - } - break; - case PM8607_ID_LDO10: - if (min_uV > 2850000) - val = 7; - else if (min_uV <= 1200000) - val = 8; - else if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */ - val = (min_uV - 1750001) / 50000; - else { /* 2700mV ~ 2850mV / 50mV */ - val = (min_uV - 2650001) / 50000; - val += 3; - } - break; - case PM8607_ID_LDO12: - if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 100mV */ - if (min_uV <= 1200000) - val = 8; /* 1200mV */ - else if (min_uV <= 1800000) - val = 0; /* 1800mV */ - else if (min_uV <= 1900000) - val = (min_uV - 1700001) / 100000; - else - val = 2; /* 2700mV */ - } else { /* 2700mV ~ 3100mV / 100mV */ - if (min_uV <= 3100000) { - val = (min_uV - 2600001) / 100000; - val += 2; - } else if (min_uV <= 3300000) - val = 7; - else - val = -EINVAL; - } - break; - case PM8607_ID_LDO2: - case PM8607_ID_LDO3: - case PM8607_ID_LDO9: - if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ - if (min_uV <= 1800000) - val = 0; - else if (min_uV <= 1900000) - val = (min_uV - 1750001) / 50000; - else - val = 3; /* 2700mV */ - } else { /* 2700mV ~ 2850mV / 50mV */ - if (min_uV <= 2850000) { - val = (min_uV - 2650001) / 50000; - val += 3; - } else if (min_uV <= 3300000) - val = 7; - else - val = -EINVAL; - } - break; - case PM8607_ID_LDO4: - if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ - if (min_uV <= 1800000) - val = 0; - else if (min_uV <= 1900000) - val = (min_uV - 1750001) / 50000; - else - val = 3; /* 2700mV */ - } else { /* 2700mV ~ 2800mV / 50mV */ - if (min_uV <= 2850000) { - val = (min_uV - 2650001) / 50000; - val += 3; - } else if (min_uV <= 2900000) - val = 6; - else if (min_uV <= 3300000) - val = 7; - else - val = -EINVAL; - } - break; - case PM8607_ID_LDO6: - if (min_uV < 2600000) { /* 1800mV ~ 1850mV / 50mV */ - if (min_uV <= 1800000) - val = 0; - else if (min_uV <= 1850000) - val = (min_uV - 1750001) / 50000; - else - val = 2; /* 2600mV */ - } else { /* 2600mV ~ 2800mV / 50mV */ - if (min_uV <= 2800000) { - val = (min_uV - 2550001) / 50000; - val += 2; - } else if (min_uV <= 3300000) - val = 7; - else - val = -EINVAL; - } - break; - case PM8607_ID_LDO14: - if (min_uV < 2700000) { /* 1800mV ~ 1850mV / 50mV */ - if (min_uV <= 1800000) - val = 0; - else if (min_uV <= 1850000) - val = (min_uV - 1750001) / 50000; - else - val = 2; /* 2700mV */ - } else { /* 2700mV ~ 2900mV / 50mV */ - if (min_uV <= 2900000) { - val = (min_uV - 2650001) / 50000; - val += 2; - } else if (min_uV <= 3300000) - val = 7; - else - val = -EINVAL; - } - break; + if (info->slope_double) { + min_uV = min_uV >> 1; + max_uV = max_uV >> 1; } - if (val >= 0) { - ret = pm8607_list_voltage(rdev, val); - if (ret > max_uV) { - pr_err("exceed voltage range (%d %d) uV", - min_uV, max_uV); - return -EINVAL; + if (info->vol_table) { + for (i = 0; i < (2 << info->vol_nbits); i++) { + if (!info->vol_table[i]) + break; + if ((min_uV <= info->vol_table[i]) + && (max_uV >= info->vol_table[i])) { + ret = i; + break; + } } - } else - pr_err("invalid voltage range (%d %d) uV", min_uV, max_uV); - return val; + } + if (ret < 0) + pr_err("invalid voltage range (%d %d) uV\n", min_uV, max_uV); + return ret; } static int pm8607_set_voltage(struct regulator_dev *rdev, @@ -297,7 +255,7 @@ static int pm8607_set_voltage(struct regulator_dev *rdev, uint8_t val, mask; int ret; - if (check_range(info, min_uV, max_uV)) { + if (min_uV > max_uV) { pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV); return -EINVAL; } @@ -375,18 +333,15 @@ static struct regulator_ops pm8607_regulator_ops = { .is_enabled = pm8607_is_enabled, }; -#define PM8607_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \ +#define PM8607_DVC(vreg, nbits, ureg, ubit, ereg, ebit) \ { \ .desc = { \ - .name = "BUCK" #_id, \ + .name = #vreg, \ .ops = &pm8607_regulator_ops, \ .type = REGULATOR_VOLTAGE, \ - .id = PM8607_ID_BUCK##_id, \ + .id = PM8607_ID_##vreg, \ .owner = THIS_MODULE, \ }, \ - .min_uV = (min) * 1000, \ - .max_uV = (max) * 1000, \ - .step_uV = (step) * 1000, \ .vol_reg = PM8607_##vreg, \ .vol_shift = (0), \ .vol_nbits = (nbits), \ @@ -395,9 +350,11 @@ static struct regulator_ops pm8607_regulator_ops = { .enable_reg = PM8607_##ereg, \ .enable_bit = (ebit), \ .slope_double = (0), \ + .vol_table = (unsigned int *)&vreg##_table, \ + .vol_suspend = (unsigned int *)&vreg##_suspend_table, \ } -#define PM8607_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit) \ +#define PM8607_LDO(_id, vreg, shift, nbits, ereg, ebit) \ { \ .desc = { \ .name = "LDO" #_id, \ @@ -406,33 +363,34 @@ static struct regulator_ops pm8607_regulator_ops = { .id = PM8607_ID_LDO##_id, \ .owner = THIS_MODULE, \ }, \ - .min_uV = (min) * 1000, \ - .max_uV = (max) * 1000, \ - .step_uV = (step) * 1000, \ .vol_reg = PM8607_##vreg, \ .vol_shift = (shift), \ .vol_nbits = (nbits), \ .enable_reg = PM8607_##ereg, \ .enable_bit = (ebit), \ .slope_double = (0), \ + .vol_table = (unsigned int *)&LDO##_id##_table, \ + .vol_suspend = (unsigned int *)&LDO##_id##_suspend_table, \ } static struct pm8607_regulator_info pm8607_regulator_info[] = { - PM8607_DVC(1, 0, 1500, 25, BUCK1, 6, GO, 0, SUPPLIES_EN11, 0), - PM8607_DVC(3, 0, 1500, 25, BUCK3, 6, GO, 2, SUPPLIES_EN11, 2), - - PM8607_LDO(1 , 1200, 2800, 0, LDO1 , 0, 2, SUPPLIES_EN11, 3), - PM8607_LDO(2 , 1800, 3300, 0, LDO2 , 0, 3, SUPPLIES_EN11, 4), - PM8607_LDO(3 , 1800, 3300, 0, LDO3 , 0, 3, SUPPLIES_EN11, 5), - PM8607_LDO(4 , 1800, 3300, 0, LDO4 , 0, 3, SUPPLIES_EN11, 6), - PM8607_LDO(5 , 2900, 3300, 0, LDO5 , 0, 2, SUPPLIES_EN11, 7), - PM8607_LDO(6 , 1800, 3300, 0, LDO6 , 0, 3, SUPPLIES_EN12, 0), - PM8607_LDO(7 , 1800, 2900, 0, LDO7 , 0, 3, SUPPLIES_EN12, 1), - PM8607_LDO(8 , 1800, 2900, 0, LDO8 , 0, 3, SUPPLIES_EN12, 2), - PM8607_LDO(9 , 1800, 3300, 0, LDO9 , 0, 3, SUPPLIES_EN12, 3), - PM8607_LDO(10, 1200, 3300, 0, LDO10, 0, 4, SUPPLIES_EN11, 4), - PM8607_LDO(12, 1200, 3300, 0, LDO12, 0, 4, SUPPLIES_EN11, 5), - PM8607_LDO(14, 1800, 3300, 0, LDO14, 0, 3, SUPPLIES_EN11, 6), + PM8607_DVC(BUCK1, 6, GO, 0, SUPPLIES_EN11, 0), + PM8607_DVC(BUCK2, 6, GO, 1, SUPPLIES_EN11, 1), + PM8607_DVC(BUCK3, 6, GO, 2, SUPPLIES_EN11, 2), + + PM8607_LDO( 1, LDO1, 0, 2, SUPPLIES_EN11, 3), + PM8607_LDO( 2, LDO2, 0, 3, SUPPLIES_EN11, 4), + PM8607_LDO( 3, LDO3, 0, 3, SUPPLIES_EN11, 5), + PM8607_LDO( 4, LDO4, 0, 3, SUPPLIES_EN11, 6), + PM8607_LDO( 5, LDO5, 0, 2, SUPPLIES_EN11, 7), + PM8607_LDO( 6, LDO6, 0, 3, SUPPLIES_EN12, 0), + PM8607_LDO( 7, LDO7, 0, 3, SUPPLIES_EN12, 1), + PM8607_LDO( 8, LDO8, 0, 3, SUPPLIES_EN12, 2), + PM8607_LDO( 9, LDO9, 0, 3, SUPPLIES_EN12, 3), + PM8607_LDO(10, LDO10, 0, 3, SUPPLIES_EN12, 4), + PM8607_LDO(12, LDO12, 0, 4, SUPPLIES_EN12, 5), + PM8607_LDO(13, VIBRATOR_SET, 1, 3, VIBRATOR_SET, 0), + PM8607_LDO(14, LDO14, 0, 4, SUPPLIES_EN12, 6), }; static inline struct pm8607_regulator_info *find_regulator_info(int id) diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h index 73f92c5feea2..e3c4ff8c3e38 100644 --- a/include/linux/mfd/88pm860x.h +++ b/include/linux/mfd/88pm860x.h @@ -132,6 +132,7 @@ enum { PM8607_ID_LDO9, PM8607_ID_LDO10, PM8607_ID_LDO12, + PM8607_ID_LDO13, PM8607_ID_LDO14, PM8607_ID_RG_MAX, @@ -309,7 +310,7 @@ struct pm860x_chip { }; -#define PM8607_MAX_REGULATOR 15 /* 3 Bucks, 12 LDOs */ +#define PM8607_MAX_REGULATOR PM8607_ID_RG_MAX /* 3 Bucks, 13 LDOs */ enum { GI2C_PORT = 0, -- cgit v1.2.3 From 1dcc434b52ff25416b225f6ac229fc775867303a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 6 May 2010 11:33:36 +0800 Subject: mc13783-regulator: fix vaild voltage range checking for mc13783_fixed_regulator_set_voltage In the case of "min_uV == max_uV == mc13783_regulators[id].voltages[0]", mc13783_fixed_regulator_set_voltage should return 0 instead of -EINVAL. This patch also adds a missing ">" character for MODULE_AUTHOR, a trivial fix. Signed-off-by: Axel Lin Cc: Mark Brown Cc: Liam Girdwood Acked-by: Sascha Hauer Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/mc13783-regulator.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c index ad036dd8da13..4597d508a229 100644 --- a/drivers/regulator/mc13783-regulator.c +++ b/drivers/regulator/mc13783-regulator.c @@ -440,8 +440,8 @@ static int mc13783_fixed_regulator_set_voltage(struct regulator_dev *rdev, dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", __func__, id, min_uV, max_uV); - if (min_uV > mc13783_regulators[id].voltages[0] && - max_uV < mc13783_regulators[id].voltages[0]) + if (min_uV >= mc13783_regulators[id].voltages[0] && + max_uV <= mc13783_regulators[id].voltages[0]) return 0; else return -EINVAL; @@ -649,6 +649,6 @@ static void __exit mc13783_regulator_exit(void) module_exit(mc13783_regulator_exit); MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Sascha Hauer "); MODULE_DESCRIPTION("Regulator Driver for Freescale MC13783 PMIC"); MODULE_ALIAS("platform:mc13783-regulator"); -- cgit v1.2.3 From 3e3d3be79c75a214cd81454bb891980532d8ca89 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Thu, 22 Apr 2010 14:18:32 +0530 Subject: twl6030: regulator: Remove vsel tables and use formula for calculation All twl6030 regulators can be programmed from 1.0v to 3.3v with 100mV steps. The below formula can be used to calculate the vsel values to be programmed in the VREG_VOLTAGE registers. Voltage(in mV) = 1000mv + 100mv * (vsel - 1) Ex: if vsel = 0x9, mV = 1000 + 100 * (9 -1) = 1800mV. This patch removes all existing VSEL tables for twl6030 adjustable regulators and just uses the formula directly for vsel calculations after verifing they fall in the allowed range. Signed-off-by: Rajendra Nayak Cc: Liam Girdwood Cc: Samuel Ortiz Cc: Mark Brown Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/twl-regulator.c | 138 +++++++++++++++++++++++++------------- 1 file changed, 91 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 9729d760fb4d..7e5892efc437 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -49,6 +49,7 @@ struct twlreg_info { /* chip constraints on regulator behavior */ u16 min_mV; + u16 max_mV; /* used by regulator core */ struct regulator_desc desc; @@ -318,31 +319,8 @@ static const u16 VIO_VSEL_table[] = { static const u16 VINTANA2_VSEL_table[] = { 2500, 2750, }; -static const u16 VAUX1_6030_VSEL_table[] = { - 1000, 1300, 1800, 2500, - 2800, 2900, 3000, 3000, -}; -static const u16 VAUX2_6030_VSEL_table[] = { - 1200, 1800, 2500, 2750, - 2800, 2800, 2800, 2800, -}; -static const u16 VAUX3_6030_VSEL_table[] = { - 1000, 1200, 1300, 1800, - 2500, 2800, 3000, 3000, -}; -static const u16 VMMC_VSEL_table[] = { - 1200, 1800, 2800, 2900, - 3000, 3000, 3000, 3000, -}; -static const u16 VPP_VSEL_table[] = { - 1800, 1900, 2000, 2100, - 2200, 2300, 2400, 2500, -}; -static const u16 VUSIM_VSEL_table[] = { - 1200, 1800, 2500, 2900, -}; -static int twlldo_list_voltage(struct regulator_dev *rdev, unsigned index) +static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) { struct twlreg_info *info = rdev_get_drvdata(rdev); int mV = info->table[index]; @@ -351,7 +329,7 @@ static int twlldo_list_voltage(struct regulator_dev *rdev, unsigned index) } static int -twlldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) +twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) { struct twlreg_info *info = rdev_get_drvdata(rdev); int vsel; @@ -375,7 +353,7 @@ twlldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) return -EDOM; } -static int twlldo_get_voltage(struct regulator_dev *rdev) +static int twl4030ldo_get_voltage(struct regulator_dev *rdev) { struct twlreg_info *info = rdev_get_drvdata(rdev); int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, @@ -388,11 +366,67 @@ static int twlldo_get_voltage(struct regulator_dev *rdev) return LDO_MV(info->table[vsel]) * 1000; } -static struct regulator_ops twlldo_ops = { - .list_voltage = twlldo_list_voltage, +static struct regulator_ops twl4030ldo_ops = { + .list_voltage = twl4030ldo_list_voltage, - .set_voltage = twlldo_set_voltage, - .get_voltage = twlldo_get_voltage, + .set_voltage = twl4030ldo_set_voltage, + .get_voltage = twl4030ldo_get_voltage, + + .enable = twlreg_enable, + .disable = twlreg_disable, + .is_enabled = twlreg_is_enabled, + + .set_mode = twlreg_set_mode, + + .get_status = twlreg_get_status, +}; + +static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) +{ + struct twlreg_info *info = rdev_get_drvdata(rdev); + + return ((info->min_mV + (index * 100)) * 1000); +} + +static int +twl6030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) +{ + struct twlreg_info *info = rdev_get_drvdata(rdev); + int vsel; + + if ((min_uV/1000 < info->min_mV) || (max_uV/1000 > info->max_mV)) + return -EDOM; + + /* + * Use the below formula to calculate vsel + * mV = 1000mv + 100mv * (vsel - 1) + */ + vsel = (min_uV/1000 - 1000)/100 + 1; + return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE, vsel); + +} + +static int twl6030ldo_get_voltage(struct regulator_dev *rdev) +{ + struct twlreg_info *info = rdev_get_drvdata(rdev); + int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, + VREG_VOLTAGE); + + if (vsel < 0) + return vsel; + + /* + * Use the below formula to calculate vsel + * mV = 1000mv + 100mv * (vsel - 1) + */ + return (1000 + (100 * (vsel - 1))) * 1000; +} + +static struct regulator_ops twl6030ldo_ops = { + .list_voltage = twl6030ldo_list_voltage, + + .set_voltage = twl6030ldo_set_voltage, + .get_voltage = twl6030ldo_get_voltage, .enable = twlreg_enable, .disable = twlreg_disable, @@ -438,24 +472,16 @@ static struct regulator_ops twlfixed_ops = { /*----------------------------------------------------------------------*/ -#define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) \ - TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \ - remap_conf, TWL4030) #define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ remap_conf) \ TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ remap_conf, TWL4030) -#define TWL6030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \ - remap_conf) \ - TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \ - remap_conf, TWL6030) #define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ remap_conf) \ TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ remap_conf, TWL6030) -#define TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf, \ - family) { \ +#define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) { \ .base = offset, \ .id = num, \ .table_len = ARRAY_SIZE(label##_VSEL_table), \ @@ -464,14 +490,32 @@ static struct regulator_ops twlfixed_ops = { .remap = remap_conf, \ .desc = { \ .name = #label, \ - .id = family##_REG_##label, \ + .id = TWL4030_REG_##label, \ .n_voltages = ARRAY_SIZE(label##_VSEL_table), \ - .ops = &twlldo_ops, \ + .ops = &twl4030ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ }, \ } +#define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num, \ + remap_conf) { \ + .base = offset, \ + .id = num, \ + .min_mV = min_mVolts, \ + .max_mV = max_mVolts, \ + .remap = remap_conf, \ + .desc = { \ + .name = #label, \ + .id = TWL6030_REG_##label, \ + .n_voltages = (max_mVolts - min_mVolts)/100, \ + .ops = &twl6030ldo_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + }, \ + } + + #define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \ family) { \ .base = offset, \ @@ -519,12 +563,12 @@ static struct twlreg_info twl_regs[] = { /* 6030 REG with base as PMC Slave Misc : 0x0030 */ /* Turnon-delay and remap configuration values for 6030 are not verified since the specification is not public */ - TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1, 0, 0x21), - TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 2, 0, 0x21), - TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 3, 0, 0x21), - TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 4, 0, 0x21), - TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 5, 0, 0x21), - TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 7, 0, 0x21), + TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300, 1, 0x21), + TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300, 2, 0x21), + TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300, 3, 0x21), + TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300, 4, 0x21), + TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300, 5, 0x21), + TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300, 7, 0x21), TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0, 0x21), TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0, 0x21), TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0, 0x21), -- cgit v1.2.3 From 64714354a45a58a072cfc926db0a078611a63d43 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 13 May 2010 17:33:01 +0800 Subject: Regulators: ab3100/bq24022: add a missing .owner field in regulator_desc This patch adds a missing .owner field in regulator_desc, which is used for refcounting. Signed-off-by: Axel Lin Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/ab3100.c | 10 ++++++++++ drivers/regulator/bq24022.c | 1 + 2 files changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index 7de950959ed2..1afd008ca957 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c @@ -492,18 +492,21 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .id = AB3100_LDO_A, .ops = ®ulator_ops_fixed, .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, }, { .name = "LDO_C", .id = AB3100_LDO_C, .ops = ®ulator_ops_fixed, .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, }, { .name = "LDO_D", .id = AB3100_LDO_D, .ops = ®ulator_ops_fixed, .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, }, { .name = "LDO_E", @@ -511,6 +514,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .ops = ®ulator_ops_variable_sleepable, .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages), .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, }, { .name = "LDO_F", @@ -518,6 +522,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .ops = ®ulator_ops_variable, .n_voltages = ARRAY_SIZE(ldo_f_typ_voltages), .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, }, { .name = "LDO_G", @@ -525,6 +530,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .ops = ®ulator_ops_variable, .n_voltages = ARRAY_SIZE(ldo_g_typ_voltages), .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, }, { .name = "LDO_H", @@ -532,6 +538,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .ops = ®ulator_ops_variable, .n_voltages = ARRAY_SIZE(ldo_h_typ_voltages), .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, }, { .name = "LDO_K", @@ -539,12 +546,14 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .ops = ®ulator_ops_variable, .n_voltages = ARRAY_SIZE(ldo_k_typ_voltages), .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, }, { .name = "LDO_EXT", .id = AB3100_LDO_EXT, .ops = ®ulator_ops_external, .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, }, { .name = "BUCK", @@ -552,6 +561,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .ops = ®ulator_ops_variable_sleepable, .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages), .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, }, }; diff --git a/drivers/regulator/bq24022.c b/drivers/regulator/bq24022.c index d08cd9b66c6d..068d488a4f71 100644 --- a/drivers/regulator/bq24022.c +++ b/drivers/regulator/bq24022.c @@ -78,6 +78,7 @@ static struct regulator_desc bq24022_desc = { .name = "bq24022", .ops = &bq24022_ops, .type = REGULATOR_CURRENT, + .owner = THIS_MODULE, }; static int __init bq24022_probe(struct platform_device *pdev) -- cgit v1.2.3 From 500b4ac90d1103a7c302d5bb16c53f4ffc45d057 Mon Sep 17 00:00:00 2001 From: Sundar R Iyer Date: Mon, 17 May 2010 21:24:48 +0530 Subject: regulator: return set_mode is same mode is requested On Mon, 2010-05-17 at 17:34 +0200, Mark Brown wrote: > This doesn't seem like the right error handling - if the driver has a > set_mode() you'd *expect* it to have a get_mode() but there's no need > for it to be a strict requirement. True. In such a case, even a valid request would be lost! So now in the updated patch: - check if get_mode is present to avoid oops; - if get_mode is not present, proceed anyways for the request. Here is the updated patch: >From bad0d5eb51ef84be5b100e3dd0f5a590ea0529b6 Mon Sep 17 00:00:00 2001 From: Sundar R Iyer Date: Fri, 14 May 2010 15:14:17 +0530 Subject: [PATCH 1/1] regulator: return set_mode when same mode is requested save I/O costs by returning when the same mode is requested for the regulator Cc: Liam Girdwood Cc: Mark Brown Acked-by: Linus Walleij Signed-off-by: Sundar R Iyer Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/core.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 98e5d14f94f3..2248087b9be2 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1745,6 +1745,7 @@ int regulator_set_mode(struct regulator *regulator, unsigned int mode) { struct regulator_dev *rdev = regulator->rdev; int ret; + int regulator_curr_mode; mutex_lock(&rdev->mutex); @@ -1754,6 +1755,15 @@ int regulator_set_mode(struct regulator *regulator, unsigned int mode) goto out; } + /* return if the same mode is requested */ + if (rdev->desc->ops->get_mode) { + regulator_curr_mode = rdev->desc->ops->get_mode(rdev); + if (regulator_curr_mode == mode) { + ret = 0; + goto out; + } + } + /* constraints check */ ret = regulator_check_mode(rdev, mode); if (ret < 0) -- cgit v1.2.3 From bbabb158f0e9d41174ae5c2183a8e4f981daf6ce Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 25 May 2010 02:39:45 +0200 Subject: power_supply: Fix regression for 'type' property Commit 5f487cd34f4337f9bc27ca19da72a39d1b0a0ab4 (power_supply: Use attribute groups) causes a regression the power supply core does not export the 'type' attribute anymore. POWER_SUPPLY_PROP_TYPE is handled by the power supply core without the low-level driver, so power_supply_attr_is_visible() must always return the entry as readable. Reported-by: Rafael J. Wysocki Signed-off-by: Daniel Mack Tested-by: Rafael J. Wysocki Signed-off-by: Anton Vorontsov --- drivers/power/power_supply_sysfs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index 6a86cdfd79fa..9d30eeb8c810 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c @@ -179,14 +179,16 @@ static mode_t power_supply_attr_is_visible(struct kobject *kobj, { struct device *dev = container_of(kobj, struct device, kobj); struct power_supply *psy = dev_get_drvdata(dev); + mode_t mode = S_IRUSR | S_IRGRP | S_IROTH; int i; + if (attrno == POWER_SUPPLY_PROP_TYPE) + return mode; + for (i = 0; i < psy->num_properties; i++) { int property = psy->properties[i]; if (property == attrno) { - mode_t mode = S_IRUSR | S_IRGRP | S_IROTH; - if (psy->property_is_writeable && psy->property_is_writeable(psy, property) > 0) mode |= S_IWUSR; -- cgit v1.2.3 From 4b3fb4e79cc3e40ec033a77f1b3d81e7851a6cf5 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 25 May 2010 19:47:12 +0900 Subject: input: serio: disable i8042 for non-cayman sh platforms. The sh64 cayman platform is the only sh board that ships with an i8042, so we just hide it for all of the others. Signed-off-by: Paul Mundt --- drivers/input/serio/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index f34f1dbeb577..3bfe8fafc6ad 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig @@ -21,7 +21,8 @@ if SERIO config SERIO_I8042 tristate "i8042 PC Keyboard controller" if EMBEDDED || !X86 default y - depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && !M68K && !BLACKFIN + depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && \ + (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN help i8042 is the chip over which the standard AT keyboard and PS/2 mouse are connected to the computer. If you use these devices, -- cgit v1.2.3 From bb2fd8a844d3a9209599b5fb694b30ac46a56ef0 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 29 Apr 2010 10:03:17 +0200 Subject: watchdog: Driver for the watchdog timer on Freescale IMX2 (and later) processors. This is the driver for the hardware watchdog on the Freescale IMX2 and later processors. Signed-off-by: Wolfram Sang Cc: Vladimir Zapolskiy Cc: Sascha Hauer Tested-by: Juergen Beisert Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/Kconfig | 12 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/imx2_wdt.c | 358 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 371 insertions(+) create mode 100644 drivers/watchdog/imx2_wdt.c (limited to 'drivers') diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index c57ecffe0085..afcfacc9bbe2 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -312,6 +312,18 @@ config MAX63XX_WATCHDOG help Support for memory mapped max63{69,70,71,72,73,74} watchdog timer. +config IMX2_WDT + tristate "IMX2+ Watchdog" + depends on ARCH_MX2 || ARCH_MX25 || ARCH_MX3 || ARCH_MX5 + help + This is the driver for the hardware watchdog + on the Freescale IMX2 and later processors. + If you have one of these processors and wish to have + watchdog support enabled, say Y, otherwise say N. + + To compile this driver as a module, choose M here: the + module will be called imx2_wdt. + # AVR32 Architecture config AT32AP700X_WDT diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 5e3cb95bb0e9..72f3e2073f8e 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -47,6 +47,7 @@ obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o obj-$(CONFIG_ADX_WATCHDOG) += adx_wdt.o obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o +obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o # AVR32 Architecture obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c new file mode 100644 index 000000000000..ea25885781bb --- /dev/null +++ b/drivers/watchdog/imx2_wdt.c @@ -0,0 +1,358 @@ +/* + * Watchdog driver for IMX2 and later processors + * + * Copyright (C) 2010 Wolfram Sang, Pengutronix e.K. + * + * some parts adapted by similar drivers from Darius Augulis and Vladimir + * Zapolskiy, additional improvements by Wim Van Sebroeck. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * NOTE: MX1 has a slightly different Watchdog than MX2 and later: + * + * MX1: MX2+: + * ---- ----- + * Registers: 32-bit 16-bit + * Stopable timer: Yes No + * Need to enable clk: No Yes + * Halt on suspend: Manual Can be automatic + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "imx2-wdt" + +#define IMX2_WDT_WCR 0x00 /* Control Register */ +#define IMX2_WDT_WCR_WT (0xFF << 8) /* -> Watchdog Timeout Field */ +#define IMX2_WDT_WCR_WRE (1 << 3) /* -> WDOG Reset Enable */ +#define IMX2_WDT_WCR_WDE (1 << 2) /* -> Watchdog Enable */ + +#define IMX2_WDT_WSR 0x02 /* Service Register */ +#define IMX2_WDT_SEQ1 0x5555 /* -> service sequence 1 */ +#define IMX2_WDT_SEQ2 0xAAAA /* -> service sequence 2 */ + +#define IMX2_WDT_MAX_TIME 128 +#define IMX2_WDT_DEFAULT_TIME 60 /* in seconds */ + +#define WDOG_SEC_TO_COUNT(s) ((s * 2 - 1) << 8) + +#define IMX2_WDT_STATUS_OPEN 0 +#define IMX2_WDT_STATUS_STARTED 1 +#define IMX2_WDT_EXPECT_CLOSE 2 + +static struct { + struct clk *clk; + void __iomem *base; + unsigned timeout; + unsigned long status; + struct timer_list timer; /* Pings the watchdog when closed */ +} imx2_wdt; + +static struct miscdevice imx2_wdt_miscdev; + +static int nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, int, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + + +static unsigned timeout = IMX2_WDT_DEFAULT_TIME; +module_param(timeout, uint, 0); +MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=" + __MODULE_STRING(IMX2_WDT_DEFAULT_TIME) ")"); + +static const struct watchdog_info imx2_wdt_info = { + .identity = "imx2+ watchdog", + .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, +}; + +static inline void imx2_wdt_setup(void) +{ + u16 val = __raw_readw(imx2_wdt.base + IMX2_WDT_WCR); + + /* Strip the old watchdog Time-Out value */ + val &= ~IMX2_WDT_WCR_WT; + /* Generate reset if WDOG times out */ + val &= ~IMX2_WDT_WCR_WRE; + /* Keep Watchdog Disabled */ + val &= ~IMX2_WDT_WCR_WDE; + /* Set the watchdog's Time-Out value */ + val |= WDOG_SEC_TO_COUNT(imx2_wdt.timeout); + + __raw_writew(val, imx2_wdt.base + IMX2_WDT_WCR); + + /* enable the watchdog */ + val |= IMX2_WDT_WCR_WDE; + __raw_writew(val, imx2_wdt.base + IMX2_WDT_WCR); +} + +static inline void imx2_wdt_ping(void) +{ + __raw_writew(IMX2_WDT_SEQ1, imx2_wdt.base + IMX2_WDT_WSR); + __raw_writew(IMX2_WDT_SEQ2, imx2_wdt.base + IMX2_WDT_WSR); +} + +static void imx2_wdt_timer_ping(unsigned long arg) +{ + /* ping it every imx2_wdt.timeout / 2 seconds to prevent reboot */ + imx2_wdt_ping(); + mod_timer(&imx2_wdt.timer, jiffies + imx2_wdt.timeout * HZ / 2); +} + +static void imx2_wdt_start(void) +{ + if (!test_and_set_bit(IMX2_WDT_STATUS_STARTED, &imx2_wdt.status)) { + /* at our first start we enable clock and do initialisations */ + clk_enable(imx2_wdt.clk); + + imx2_wdt_setup(); + } else /* delete the timer that pings the watchdog after close */ + del_timer_sync(&imx2_wdt.timer); + + /* Watchdog is enabled - time to reload the timeout value */ + imx2_wdt_ping(); +} + +static void imx2_wdt_stop(void) +{ + /* we don't need a clk_disable, it cannot be disabled once started. + * We use a timer to ping the watchdog while /dev/watchdog is closed */ + imx2_wdt_timer_ping(0); +} + +static void imx2_wdt_set_timeout(int new_timeout) +{ + u16 val = __raw_readw(imx2_wdt.base + IMX2_WDT_WCR); + + /* set the new timeout value in the WSR */ + val &= ~IMX2_WDT_WCR_WT; + val |= WDOG_SEC_TO_COUNT(new_timeout); + __raw_writew(val, imx2_wdt.base + IMX2_WDT_WCR); +} + +static int imx2_wdt_open(struct inode *inode, struct file *file) +{ + if (test_and_set_bit(IMX2_WDT_STATUS_OPEN, &imx2_wdt.status)) + return -EBUSY; + + imx2_wdt_start(); + return nonseekable_open(inode, file); +} + +static int imx2_wdt_close(struct inode *inode, struct file *file) +{ + if (test_bit(IMX2_WDT_EXPECT_CLOSE, &imx2_wdt.status) && !nowayout) + imx2_wdt_stop(); + else { + dev_crit(imx2_wdt_miscdev.parent, + "Unexpected close: Expect reboot!\n"); + imx2_wdt_ping(); + } + + clear_bit(IMX2_WDT_EXPECT_CLOSE, &imx2_wdt.status); + clear_bit(IMX2_WDT_STATUS_OPEN, &imx2_wdt.status); + return 0; +} + +static long imx2_wdt_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + void __user *argp = (void __user *)arg; + int __user *p = argp; + int new_value; + + switch (cmd) { + case WDIOC_GETSUPPORT: + return copy_to_user(argp, &imx2_wdt_info, + sizeof(struct watchdog_info)) ? -EFAULT : 0; + + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + return put_user(0, p); + + case WDIOC_KEEPALIVE: + imx2_wdt_ping(); + return 0; + + case WDIOC_SETTIMEOUT: + if (get_user(new_value, p)) + return -EFAULT; + if ((new_value < 1) || (new_value > IMX2_WDT_MAX_TIME)) + return -EINVAL; + imx2_wdt_set_timeout(new_value); + imx2_wdt.timeout = new_value; + imx2_wdt_ping(); + + /* Fallthrough to return current value */ + case WDIOC_GETTIMEOUT: + return put_user(imx2_wdt.timeout, p); + + default: + return -ENOTTY; + } +} + +static ssize_t imx2_wdt_write(struct file *file, const char __user *data, + size_t len, loff_t *ppos) +{ + size_t i; + char c; + + if (len == 0) /* Can we see this even ? */ + return 0; + + clear_bit(IMX2_WDT_EXPECT_CLOSE, &imx2_wdt.status); + /* scan to see whether or not we got the magic character */ + for (i = 0; i != len; i++) { + if (get_user(c, data + i)) + return -EFAULT; + if (c == 'V') + set_bit(IMX2_WDT_EXPECT_CLOSE, &imx2_wdt.status); + } + + imx2_wdt_ping(); + return len; +} + +static const struct file_operations imx2_wdt_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .unlocked_ioctl = imx2_wdt_ioctl, + .open = imx2_wdt_open, + .release = imx2_wdt_close, + .write = imx2_wdt_write, +}; + +static struct miscdevice imx2_wdt_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &imx2_wdt_fops, +}; + +static int __init imx2_wdt_probe(struct platform_device *pdev) +{ + int ret; + int res_size; + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "can't get device resources\n"); + return -ENODEV; + } + + res_size = resource_size(res); + if (!devm_request_mem_region(&pdev->dev, res->start, res_size, + res->name)) { + dev_err(&pdev->dev, "can't allocate %d bytes at %d address\n", + res_size, res->start); + return -ENOMEM; + } + + imx2_wdt.base = devm_ioremap_nocache(&pdev->dev, res->start, res_size); + if (!imx2_wdt.base) { + dev_err(&pdev->dev, "ioremap failed\n"); + return -ENOMEM; + } + + imx2_wdt.clk = clk_get_sys("imx-wdt.0", NULL); + if (IS_ERR(imx2_wdt.clk)) { + dev_err(&pdev->dev, "can't get Watchdog clock\n"); + return PTR_ERR(imx2_wdt.clk); + } + + imx2_wdt.timeout = clamp_t(unsigned, timeout, 1, IMX2_WDT_MAX_TIME); + if (imx2_wdt.timeout != timeout) + dev_warn(&pdev->dev, "Initial timeout out of range! " + "Clamped from %u to %u\n", timeout, imx2_wdt.timeout); + + setup_timer(&imx2_wdt.timer, imx2_wdt_timer_ping, 0); + + imx2_wdt_miscdev.parent = &pdev->dev; + ret = misc_register(&imx2_wdt_miscdev); + if (ret) + goto fail; + + dev_info(&pdev->dev, + "IMX2+ Watchdog Timer enabled. timeout=%ds (nowayout=%d)\n", + imx2_wdt.timeout, nowayout); + return 0; + +fail: + imx2_wdt_miscdev.parent = NULL; + clk_put(imx2_wdt.clk); + return ret; +} + +static int __exit imx2_wdt_remove(struct platform_device *pdev) +{ + misc_deregister(&imx2_wdt_miscdev); + + if (test_bit(IMX2_WDT_STATUS_STARTED, &imx2_wdt.status)) { + del_timer_sync(&imx2_wdt.timer); + + dev_crit(imx2_wdt_miscdev.parent, + "Device removed: Expect reboot!\n"); + } else + clk_put(imx2_wdt.clk); + + imx2_wdt_miscdev.parent = NULL; + return 0; +} + +static void imx2_wdt_shutdown(struct platform_device *pdev) +{ + if (test_bit(IMX2_WDT_STATUS_STARTED, &imx2_wdt.status)) { + /* we are running, we need to delete the timer but will give + * max timeout before reboot will take place */ + del_timer_sync(&imx2_wdt.timer); + imx2_wdt_set_timeout(IMX2_WDT_MAX_TIME); + imx2_wdt_ping(); + + dev_crit(imx2_wdt_miscdev.parent, + "Device shutdown: Expect reboot!\n"); + } +} + +static struct platform_driver imx2_wdt_driver = { + .probe = imx2_wdt_probe, + .remove = __exit_p(imx2_wdt_remove), + .shutdown = imx2_wdt_shutdown, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init imx2_wdt_init(void) +{ + return platform_driver_probe(&imx2_wdt_driver, imx2_wdt_probe); +} +module_init(imx2_wdt_init); + +static void __exit imx2_wdt_exit(void) +{ + platform_driver_unregister(&imx2_wdt_driver); +} +module_exit(imx2_wdt_exit); + +MODULE_AUTHOR("Wolfram Sang"); +MODULE_DESCRIPTION("Watchdog driver for IMX2 and later"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); +MODULE_ALIAS("platform:" DRIVER_NAME); -- cgit v1.2.3 From 8c38a2951026e6b428d3ce6e518d123c35becd18 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Fri, 21 May 2010 18:24:16 -0500 Subject: [SCSI] iscsi_tcp: remove sk_sleep check There is no need to call sk_sleep before calling wake_up_interruptible, because the wait_queue_head is now with the socket. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/iscsi_tcp.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index bf55d3057413..fec47de72535 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -601,10 +601,8 @@ static void iscsi_sw_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); write_unlock_bh(&tcp_sw_conn->sock->sk->sk_callback_lock); - if (sk_sleep(sock->sk)) { - sock->sk->sk_err = EIO; - wake_up_interruptible(sk_sleep(sock->sk)); - } + sock->sk->sk_err = EIO; + wake_up_interruptible(sk_sleep(sock->sk)); iscsi_conn_stop(cls_conn, flag); iscsi_sw_tcp_release_conn(conn); -- cgit v1.2.3 From 7873ca4e4401f0ecd8868bf1543113467e6bae61 Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 21 May 2010 14:39:45 -0700 Subject: [SCSI] bfa: fix system crash when reading sysfs fc_host statistics The port data structure related to fc_host statistics collection is not initialized. This causes system crash when reading the fc_host statistics. The fix is to initialize port structure during driver attach. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfa_core.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c index 0c08e185a766..3a7b3f88932f 100644 --- a/drivers/scsi/bfa/bfa_core.c +++ b/drivers/scsi/bfa/bfa_core.c @@ -84,11 +84,32 @@ bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo) for (i = 0; hal_mods[i]; i++) hal_mods[i]->meminfo(cfg, &km_len, &dm_len); + dm_len += bfa_port_meminfo(); meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_len = km_len; meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_len = dm_len; } +static void +bfa_com_port_attach(struct bfa_s *bfa, struct bfa_meminfo_s *mi) +{ + struct bfa_port_s *port = &bfa->modules.port; + uint32_t dm_len; + uint8_t *dm_kva; + uint64_t dm_pa; + + dm_len = bfa_port_meminfo(); + dm_kva = bfa_meminfo_dma_virt(mi); + dm_pa = bfa_meminfo_dma_phys(mi); + + memset(port, 0, sizeof(struct bfa_port_s)); + bfa_port_attach(port, &bfa->ioc, bfa, bfa->trcmod, bfa->logm); + bfa_port_mem_claim(port, dm_kva, dm_pa); + + bfa_meminfo_dma_virt(mi) = dm_kva + dm_len; + bfa_meminfo_dma_phys(mi) = dm_pa + dm_len; +} + /** * Use this function to do attach the driver instance with the BFA * library. This function will not trigger any HW initialization @@ -140,6 +161,7 @@ bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, for (i = 0; hal_mods[i]; i++) hal_mods[i]->attach(bfa, bfad, cfg, meminfo, pcidev); + bfa_com_port_attach(bfa, meminfo); } /** -- cgit v1.2.3 From ed4a6d7f0676db50b5023cc01f6cda82a2f2a307 Mon Sep 17 00:00:00 2001 From: Mel Gorman Date: Mon, 24 May 2010 14:32:29 -0700 Subject: mm: compaction: add /sys trigger for per-node memory compaction Add a per-node sysfs file called compact. When the file is written to, each zone in that node is compacted. The intention that this would be used by something like a job scheduler in a batch system before a job starts so that the job can allocate the maximum number of hugepages without significant start-up cost. Signed-off-by: Mel Gorman Acked-by: Rik van Riel Reviewed-by: KOSAKI Motohiro Reviewed-by: Christoph Lameter Reviewed-by: Minchan Kim Reviewed-by: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/ABI/testing/sysfs-devices-node | 7 +++++++ drivers/base/node.c | 3 +++ include/linux/compaction.h | 16 ++++++++++++++++ mm/compaction.c | 23 +++++++++++++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-devices-node (limited to 'drivers') diff --git a/Documentation/ABI/testing/sysfs-devices-node b/Documentation/ABI/testing/sysfs-devices-node new file mode 100644 index 000000000000..453a210c3ceb --- /dev/null +++ b/Documentation/ABI/testing/sysfs-devices-node @@ -0,0 +1,7 @@ +What: /sys/devices/system/node/nodeX/compact +Date: February 2010 +Contact: Mel Gorman +Description: + When this file is written to, all memory within that node + will be compacted. When it completes, memory will be freed + into blocks which have as many contiguous pages as possible diff --git a/drivers/base/node.c b/drivers/base/node.c index 057979a19eea..2bdd8a94ec94 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -246,6 +247,8 @@ int register_node(struct node *node, int num, struct node *parent) scan_unevictable_register_node(node); hugetlb_register_node(node); + + compaction_register_node(node); } return error; } diff --git a/include/linux/compaction.h b/include/linux/compaction.h index 572388880ba8..ba98cfe0ae15 100644 --- a/include/linux/compaction.h +++ b/include/linux/compaction.h @@ -12,4 +12,20 @@ extern int sysctl_compaction_handler(struct ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos); #endif /* CONFIG_COMPACTION */ +#if defined(CONFIG_COMPACTION) && defined(CONFIG_SYSFS) && defined(CONFIG_NUMA) +extern int compaction_register_node(struct node *node); +extern void compaction_unregister_node(struct node *node); + +#else + +static inline int compaction_register_node(struct node *node) +{ + return 0; +} + +static inline void compaction_unregister_node(struct node *node) +{ +} +#endif /* CONFIG_COMPACTION && CONFIG_SYSFS && CONFIG_NUMA */ + #endif /* _LINUX_COMPACTION_H */ diff --git a/mm/compaction.c b/mm/compaction.c index 77854fbc0f56..f61f77983ff4 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "internal.h" /* @@ -453,3 +454,25 @@ int sysctl_compaction_handler(struct ctl_table *table, int write, return 0; } + +#if defined(CONFIG_SYSFS) && defined(CONFIG_NUMA) +ssize_t sysfs_compact_node(struct sys_device *dev, + struct sysdev_attribute *attr, + const char *buf, size_t count) +{ + compact_node(dev->id); + + return count; +} +static SYSDEV_ATTR(compact, S_IWUSR, NULL, sysfs_compact_node); + +int compaction_register_node(struct node *node) +{ + return sysdev_create_file(&node->sysdev, &attr_compact); +} + +void compaction_unregister_node(struct node *node) +{ + return sysdev_remove_file(&node->sysdev, &attr_compact); +} +#endif /* CONFIG_SYSFS && CONFIG_NUMA */ -- cgit v1.2.3 From e9a137cb00d8b0f71c08a9e67d993f53e7713d21 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 24 May 2010 14:32:55 -0700 Subject: m68knommu: fix broken use of BUAD_TABLE_SIZE in 68328serial driver Commit 8b505ca8e2600eb9e7dd2d6b2682a81717671374 ("serial: 68328serial.c: remove BAUD_TABLE_SIZE macro") misses one use of BAUD_TABLE_SIZE. So the resulting 68328serial.c does not compile: drivers/serial/68328serial.c: In function `m68328_console_setup': drivers/serial/68328serial.c:1439: error: `BAUD_TABLE_SIZE' undeclared (first use in this function) drivers/serial/68328serial.c:1439: error: (Each undeclared identifier is reported only once drivers/serial/68328serial.c:1439: error: for each function it appears in.) Fix that last use of it. Signed-off-by: Greg Ungerer Cc: Thiago Farina Cc: Alan Cox Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/68328serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index 78ed24bb6a35..30463862603b 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c @@ -1437,7 +1437,7 @@ int m68328_console_setup(struct console *cp, char *arg) for (i = 0; i < ARRAY_SIZE(baud_table); i++) if (baud_table[i] == n) break; - if (i < BAUD_TABLE_SIZE) { + if (i < ARRAY_SIZE(baud_table)) { m68328_console_baud = n; m68328_console_cbaud = 0; if (i > 15) { -- cgit v1.2.3 From 1f85f87d4f81d1e5a2d502d48316a1bdc5acac0b Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Mon, 24 May 2010 14:32:59 -0700 Subject: cpuidle: add a repeating pattern detector to the menu governor Currently, the menu governor uses the (corrected) next timer as key item for predicting the idle duration. It turns out that there are specific cases where this breaks down: There are cases where we have a very repetitive pattern of idle durations, where the idle period is pretty much the same, for reasons completely unrelated to the next timer event. Examples of such repeating patterns are network loads with irq mitigation, the mouse moving but in theory also the wifi beacons. This patch adds a relatively simple detector for such repeating patterns, where the standard deviation of the last 8 idle periods is compared to a threshold. With this extra predictor in place, measurements show that the DECAY factor can now be increased (the decaying average will now decay slower) to get an even more stable result. [arjan@infradead.org: fix bug identified by Frank] Signed-off-by: Arjan van de Ven Cc: Corrado Zoccolo Cc: Frank Rowand Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/cpuidle/governors/menu.c | 60 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index b81ad9c731ae..52ff8aa63f84 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -21,9 +21,12 @@ #include #define BUCKETS 12 +#define INTERVALS 8 #define RESOLUTION 1024 -#define DECAY 4 +#define DECAY 8 #define MAX_INTERESTING 50000 +#define STDDEV_THRESH 400 + /* * Concepts and ideas behind the menu governor @@ -64,6 +67,16 @@ * indexed based on the magnitude of the expected duration as well as the * "is IO outstanding" property. * + * Repeatable-interval-detector + * ---------------------------- + * There are some cases where "next timer" is a completely unusable predictor: + * Those cases where the interval is fixed, for example due to hardware + * interrupt mitigation, but also due to fixed transfer rate devices such as + * mice. + * For this, we use a different predictor: We track the duration of the last 8 + * intervals and if the stand deviation of these 8 intervals is below a + * threshold value, we use the average of these intervals as prediction. + * * Limiting Performance Impact * --------------------------- * C states, especially those with large exit latencies, can have a real @@ -104,6 +117,8 @@ struct menu_device { unsigned int exit_us; unsigned int bucket; u64 correction_factor[BUCKETS]; + u32 intervals[INTERVALS]; + int interval_ptr; }; @@ -175,6 +190,42 @@ static u64 div_round64(u64 dividend, u32 divisor) return div_u64(dividend + (divisor / 2), divisor); } +/* + * Try detecting repeating patterns by keeping track of the last 8 + * intervals, and checking if the standard deviation of that set + * of points is below a threshold. If it is... then use the + * average of these 8 points as the estimated value. + */ +static void detect_repeating_patterns(struct menu_device *data) +{ + int i; + uint64_t avg = 0; + uint64_t stddev = 0; /* contains the square of the std deviation */ + + /* first calculate average and standard deviation of the past */ + for (i = 0; i < INTERVALS; i++) + avg += data->intervals[i]; + avg = avg / INTERVALS; + + /* if the avg is beyond the known next tick, it's worthless */ + if (avg > data->expected_us) + return; + + for (i = 0; i < INTERVALS; i++) + stddev += (data->intervals[i] - avg) * + (data->intervals[i] - avg); + + stddev = stddev / INTERVALS; + + /* + * now.. if stddev is small.. then assume we have a + * repeating pattern and predict we keep doing this. + */ + + if (avg && stddev < STDDEV_THRESH) + data->predicted_us = avg; +} + /** * menu_select - selects the next idle state to enter * @dev: the CPU @@ -218,6 +269,8 @@ static int menu_select(struct cpuidle_device *dev) data->predicted_us = div_round64(data->expected_us * data->correction_factor[data->bucket], RESOLUTION * DECAY); + detect_repeating_patterns(data); + /* * We want to default to C1 (hlt), not to busy polling * unless the timer is happening really really soon. @@ -310,6 +363,11 @@ static void menu_update(struct cpuidle_device *dev) new_factor = 1; data->correction_factor[data->bucket] = new_factor; + + /* update the repeating-pattern data */ + data->intervals[data->interval_ptr++] = last_idle_us; + if (data->interval_ptr >= INTERVALS) + data->interval_ptr = 0; } /** -- cgit v1.2.3 From 940370fc86b920b51a34217a1facc3e9e97c2456 Mon Sep 17 00:00:00 2001 From: Yury Polyanskiy Date: Mon, 24 May 2010 14:33:02 -0700 Subject: hangcheck-timer: fix x86_32 bugs drivers/char/hangcheck-timer.c is doubly broken. When the overflown value of TIMER_FREQ is abnormally low, it spams the syslog with KERN_CRIT messages "Hangcheck: hangcheck value past margin!" But whether it happens or not depends on HZ and lpj in a complex way. People have hit it occasionally as far as google search can tell. First, the following line overflows unsigned long: # define TIMER_FREQ (HZ*loops_per_jiffy) Second, and more importantly, loops_per_jiffy has little to do with the con= version from the the time scale of get_cycles() (aka rdtsc) to the time scale of jiffies. The attached patch resolves both of the problems. Acked-by: Joel Becker Cc: john stultz Cc: Jan Glauber Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/hangcheck-timer.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c index 712d9f271aa6..e0249722d25f 100644 --- a/drivers/char/hangcheck-timer.c +++ b/drivers/char/hangcheck-timer.c @@ -49,8 +49,9 @@ #include #include #include +#include -#define VERSION_STR "0.9.0" +#define VERSION_STR "0.9.1" #define DEFAULT_IOFENCE_MARGIN 60 /* Default fudge factor, in seconds */ #define DEFAULT_IOFENCE_TICK 180 /* Default timer timeout, in seconds */ @@ -119,10 +120,8 @@ __setup("hcheck_dump_tasks", hangcheck_parse_dump_tasks); #if defined(CONFIG_S390) # define HAVE_MONOTONIC # define TIMER_FREQ 1000000000ULL -#elif defined(CONFIG_IA64) -# define TIMER_FREQ ((unsigned long long)local_cpu_data->itc_freq) #else -# define TIMER_FREQ (HZ*loops_per_jiffy) +# define TIMER_FREQ 1000000000ULL #endif #ifdef HAVE_MONOTONIC @@ -130,7 +129,9 @@ extern unsigned long long monotonic_clock(void); #else static inline unsigned long long monotonic_clock(void) { - return get_cycles(); + struct timespec ts; + getrawmonotonic(&ts); + return timespec_to_ns(&ts); } #endif /* HAVE_MONOTONIC */ @@ -168,6 +169,13 @@ static void hangcheck_fire(unsigned long data) printk(KERN_CRIT "Hangcheck: hangcheck value past margin!\n"); } } +#if 0 + /* + * Enable to investigate delays in detail + */ + printk("Hangcheck: called %Ld ns since last time (%Ld ns overshoot)\n", + tsc_diff, tsc_diff - hangcheck_tick*TIMER_FREQ); +#endif mod_timer(&hangcheck_ticktock, jiffies + (hangcheck_tick*HZ)); hangcheck_tsc = monotonic_clock(); } @@ -180,7 +188,7 @@ static int __init hangcheck_init(void) #if defined (HAVE_MONOTONIC) printk("Hangcheck: Using monotonic_clock().\n"); #else - printk("Hangcheck: Using get_cycles().\n"); + printk("Hangcheck: Using getrawmonotonic().\n"); #endif /* HAVE_MONOTONIC */ hangcheck_tsc_margin = (unsigned long long)(hangcheck_margin + hangcheck_tick); -- cgit v1.2.3 From 4be929be34f9bdeffa40d815d32d7d60d2c7f03b Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 24 May 2010 14:33:03 -0700 Subject: kernel-wide: replace USHORT_MAX, SHORT_MAX and SHORT_MIN with USHRT_MAX, SHRT_MAX and SHRT_MIN - C99 knows about USHRT_MAX/SHRT_MAX/SHRT_MIN, not USHORT_MAX/SHORT_MAX/SHORT_MIN. - Make SHRT_MIN of type s16, not int, for consistency. [akpm@linux-foundation.org: fix drivers/dma/timb_dma.c] [akpm@linux-foundation.org: fix security/keys/keyring.c] Signed-off-by: Alexey Dobriyan Acked-by: WANG Cong Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/dma/timb_dma.c | 2 +- drivers/scsi/fcoe/fcoe.c | 2 +- drivers/scsi/mpt2sas/mpt2sas_base.c | 2 +- drivers/scsi/mpt2sas/mpt2sas_config.c | 2 +- drivers/vhost/vhost.c | 2 +- fs/nfs/super.c | 4 ++-- fs/nfsd/nfsctl.c | 4 ++-- fs/ocfs2/blockcheck.c | 4 ++-- include/linux/kernel.h | 6 +++--- include/linux/sched.h | 2 +- include/net/ip.h | 6 +++--- include/net/ipv6.h | 6 +++--- ipc/msg.c | 12 ++++++------ ipc/util.c | 4 ++-- lib/vsprintf.c | 2 +- net/9p/protocol.c | 2 +- net/dccp/options.c | 2 +- net/ipv4/udp.c | 8 ++++---- net/mac80211/sta_info.c | 2 +- net/sunrpc/rpcb_clnt.c | 2 +- security/keys/keyring.c | 6 +++--- 21 files changed, 41 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index 0172fa3c7a2b..a1bf77c1993f 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -188,7 +188,7 @@ static void __td_unmap_descs(struct timb_dma_desc *td_desc, bool single) static int td_fill_desc(struct timb_dma_chan *td_chan, u8 *dma_desc, struct scatterlist *sg, bool last) { - if (sg_dma_len(sg) > USHORT_MAX) { + if (sg_dma_len(sg) > USHRT_MAX) { dev_err(chan2dev(&td_chan->chan), "Too big sg element\n"); return -EINVAL; } diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 9276121db1ef..44a07593de56 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -688,7 +688,7 @@ static int fcoe_shost_config(struct fc_lport *lport, struct device *dev) } if (!lport->vport) - fc_host_max_npiv_vports(lport->host) = USHORT_MAX; + fc_host_max_npiv_vports(lport->host) = USHRT_MAX; snprintf(fc_host_symbolic_name(lport->host), FC_SYMBOLIC_NAME_SIZE, "%s v%s over %s", FCOE_NAME, FCOE_VERSION, diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index b830d61684dd..0ec1ed389c20 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -3757,7 +3757,7 @@ _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) if (ioc->config_cmds.status & MPT2_CMD_PENDING) { ioc->config_cmds.status |= MPT2_CMD_RESET; mpt2sas_base_free_smid(ioc, ioc->config_cmds.smid); - ioc->config_cmds.smid = USHORT_MAX; + ioc->config_cmds.smid = USHRT_MAX; complete(&ioc->config_cmds.done); } break; diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c index e762dd3e2fcb..c65442982d7b 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_config.c +++ b/drivers/scsi/mpt2sas/mpt2sas_config.c @@ -258,7 +258,7 @@ mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, #ifdef CONFIG_SCSI_MPT2SAS_LOGGING _config_display_some_debug(ioc, smid, "config_done", mpi_reply); #endif - ioc->config_cmds.smid = USHORT_MAX; + ioc->config_cmds.smid = USHRT_MAX; complete(&ioc->config_cmds.done); return 1; } diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 750effe0f98b..c6fb8e968f21 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -806,7 +806,7 @@ static unsigned get_indirect(struct vhost_dev *dev, struct vhost_virtqueue *vq, count = indirect->len / sizeof desc; /* Buffers are chained via a 16 bit next field, so * we can have at most 2^16 of these. */ - if (count > USHORT_MAX + 1) { + if (count > USHRT_MAX + 1) { vq_err(vq, "Indirect buffer length too big: %d\n", indirect->len); return -E2BIG; diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 2f8b1157daa2..04214fc5c304 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1060,7 +1060,7 @@ static int nfs_parse_mount_options(char *raw, goto out_nomem; rc = strict_strtoul(string, 10, &option); kfree(string); - if (rc != 0 || option > USHORT_MAX) + if (rc != 0 || option > USHRT_MAX) goto out_invalid_value; mnt->nfs_server.port = option; break; @@ -1181,7 +1181,7 @@ static int nfs_parse_mount_options(char *raw, goto out_nomem; rc = strict_strtoul(string, 10, &option); kfree(string); - if (rc != 0 || option > USHORT_MAX) + if (rc != 0 || option > USHRT_MAX) goto out_invalid_value; mnt->mount_server.port = option; break; diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index bc3194ea01f5..508941c23af7 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -998,7 +998,7 @@ static ssize_t __write_ports_addxprt(char *buf) if (sscanf(buf, "%15s %4u", transport, &port) != 2) return -EINVAL; - if (port < 1 || port > USHORT_MAX) + if (port < 1 || port > USHRT_MAX) return -EINVAL; err = nfsd_create_serv(); @@ -1040,7 +1040,7 @@ static ssize_t __write_ports_delxprt(char *buf) if (sscanf(&buf[1], "%15s %4u", transport, &port) != 2) return -EINVAL; - if (port < 1 || port > USHORT_MAX || nfsd_serv == NULL) + if (port < 1 || port > USHRT_MAX || nfsd_serv == NULL) return -EINVAL; xprt = svc_find_xprt(nfsd_serv, transport, AF_UNSPEC, port); diff --git a/fs/ocfs2/blockcheck.c b/fs/ocfs2/blockcheck.c index b7428c5d0d3b..ec6d12339593 100644 --- a/fs/ocfs2/blockcheck.c +++ b/fs/ocfs2/blockcheck.c @@ -403,7 +403,7 @@ void ocfs2_block_check_compute(void *data, size_t blocksize, * No ecc'd ocfs2 structure is larger than 4K, so ecc will be no * larger than 16 bits. */ - BUG_ON(ecc > USHORT_MAX); + BUG_ON(ecc > USHRT_MAX); bc->bc_crc32e = cpu_to_le32(crc); bc->bc_ecc = cpu_to_le16((u16)ecc); @@ -508,7 +508,7 @@ void ocfs2_block_check_compute_bhs(struct buffer_head **bhs, int nr, * No ecc'd ocfs2 structure is larger than 4K, so ecc will be no * larger than 16 bits. */ - BUG_ON(ecc > USHORT_MAX); + BUG_ON(ecc > USHRT_MAX); bc->bc_crc32e = cpu_to_le32(crc); bc->bc_ecc = cpu_to_le16((u16)ecc); diff --git a/include/linux/kernel.h b/include/linux/kernel.h index cc5e3ffe9fce..a2e7c32e17e7 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -24,9 +24,9 @@ extern const char linux_banner[]; extern const char linux_proc_banner[]; -#define USHORT_MAX ((u16)(~0U)) -#define SHORT_MAX ((s16)(USHORT_MAX>>1)) -#define SHORT_MIN (-SHORT_MAX - 1) +#define USHRT_MAX ((u16)(~0U)) +#define SHRT_MAX ((s16)(USHRT_MAX>>1)) +#define SHRT_MIN ((s16)(-SHRT_MAX - 1)) #define INT_MAX ((int)(~0U>>1)) #define INT_MIN (-INT_MAX - 1) #define UINT_MAX (~0U) diff --git a/include/linux/sched.h b/include/linux/sched.h index 415b8f8a3f45..c0151ffd3541 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -384,7 +384,7 @@ struct user_namespace; * 1-3 now and depends on arch. We use "5" as safe margin, here. */ #define MAPCOUNT_ELF_CORE_MARGIN (5) -#define DEFAULT_MAX_MAP_COUNT (USHORT_MAX - MAPCOUNT_ELF_CORE_MARGIN) +#define DEFAULT_MAX_MAP_COUNT (USHRT_MAX - MAPCOUNT_ELF_CORE_MARGIN) extern int sysctl_max_map_count; diff --git a/include/net/ip.h b/include/net/ip.h index 63548f0a44b1..452f229c380a 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -358,11 +358,11 @@ enum ip_defrag_users { IP_DEFRAG_LOCAL_DELIVER, IP_DEFRAG_CALL_RA_CHAIN, IP_DEFRAG_CONNTRACK_IN, - __IP_DEFRAG_CONNTRACK_IN_END = IP_DEFRAG_CONNTRACK_IN + USHORT_MAX, + __IP_DEFRAG_CONNTRACK_IN_END = IP_DEFRAG_CONNTRACK_IN + USHRT_MAX, IP_DEFRAG_CONNTRACK_OUT, - __IP_DEFRAG_CONNTRACK_OUT_END = IP_DEFRAG_CONNTRACK_OUT + USHORT_MAX, + __IP_DEFRAG_CONNTRACK_OUT_END = IP_DEFRAG_CONNTRACK_OUT + USHRT_MAX, IP_DEFRAG_CONNTRACK_BRIDGE_IN, - __IP_DEFRAG_CONNTRACK_BRIDGE_IN = IP_DEFRAG_CONNTRACK_BRIDGE_IN + USHORT_MAX, + __IP_DEFRAG_CONNTRACK_BRIDGE_IN = IP_DEFRAG_CONNTRACK_BRIDGE_IN + USHRT_MAX, IP_DEFRAG_VS_IN, IP_DEFRAG_VS_OUT, IP_DEFRAG_VS_FWD diff --git a/include/net/ipv6.h b/include/net/ipv6.h index eba5cc00325a..2600b69757b8 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -354,11 +354,11 @@ struct inet_frag_queue; enum ip6_defrag_users { IP6_DEFRAG_LOCAL_DELIVER, IP6_DEFRAG_CONNTRACK_IN, - __IP6_DEFRAG_CONNTRACK_IN = IP6_DEFRAG_CONNTRACK_IN + USHORT_MAX, + __IP6_DEFRAG_CONNTRACK_IN = IP6_DEFRAG_CONNTRACK_IN + USHRT_MAX, IP6_DEFRAG_CONNTRACK_OUT, - __IP6_DEFRAG_CONNTRACK_OUT = IP6_DEFRAG_CONNTRACK_OUT + USHORT_MAX, + __IP6_DEFRAG_CONNTRACK_OUT = IP6_DEFRAG_CONNTRACK_OUT + USHRT_MAX, IP6_DEFRAG_CONNTRACK_BRIDGE_IN, - __IP6_DEFRAG_CONNTRACK_BRIDGE_IN = IP6_DEFRAG_CONNTRACK_BRIDGE_IN + USHORT_MAX, + __IP6_DEFRAG_CONNTRACK_BRIDGE_IN = IP6_DEFRAG_CONNTRACK_BRIDGE_IN + USHRT_MAX, }; struct ip6_create_arg { diff --git a/ipc/msg.c b/ipc/msg.c index 9547cb7ac313..747b65507a91 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -345,19 +345,19 @@ copy_msqid_to_user(void __user *buf, struct msqid64_ds *in, int version) out.msg_rtime = in->msg_rtime; out.msg_ctime = in->msg_ctime; - if (in->msg_cbytes > USHORT_MAX) - out.msg_cbytes = USHORT_MAX; + if (in->msg_cbytes > USHRT_MAX) + out.msg_cbytes = USHRT_MAX; else out.msg_cbytes = in->msg_cbytes; out.msg_lcbytes = in->msg_cbytes; - if (in->msg_qnum > USHORT_MAX) - out.msg_qnum = USHORT_MAX; + if (in->msg_qnum > USHRT_MAX) + out.msg_qnum = USHRT_MAX; else out.msg_qnum = in->msg_qnum; - if (in->msg_qbytes > USHORT_MAX) - out.msg_qbytes = USHORT_MAX; + if (in->msg_qbytes > USHRT_MAX) + out.msg_qbytes = USHRT_MAX; else out.msg_qbytes = in->msg_qbytes; out.msg_lqbytes = in->msg_qbytes; diff --git a/ipc/util.c b/ipc/util.c index 79ce84e890f7..69a0cc13d966 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -124,8 +124,8 @@ void ipc_init_ids(struct ipc_ids *ids) ids->seq = 0; { int seq_limit = INT_MAX/SEQ_MULTIPLIER; - if (seq_limit > USHORT_MAX) - ids->seq_max = USHORT_MAX; + if (seq_limit > USHRT_MAX) + ids->seq_max = USHRT_MAX; else ids->seq_max = seq_limit; } diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 46d34b0b74a8..20c95121d8a1 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1980,7 +1980,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args) { char *s = (char *)va_arg(args, char *); if (field_width == -1) - field_width = SHORT_MAX; + field_width = SHRT_MAX; /* first, skip leading white space in buffer */ str = skip_spaces(str); diff --git a/net/9p/protocol.c b/net/9p/protocol.c index 77d3aab4036b..149f82160130 100644 --- a/net/9p/protocol.c +++ b/net/9p/protocol.c @@ -394,7 +394,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, const char *sptr = va_arg(ap, const char *); int16_t len = 0; if (sptr) - len = MIN(strlen(sptr), USHORT_MAX); + len = MIN(strlen(sptr), USHRT_MAX); errcode = p9pdu_writef(pdu, proto_version, "w", len); diff --git a/net/dccp/options.c b/net/dccp/options.c index 1b08cae9c65b..07395f861d35 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -296,7 +296,7 @@ static inline u8 dccp_ndp_len(const u64 ndp) { if (likely(ndp <= 0xFF)) return 1; - return likely(ndp <= USHORT_MAX) ? 2 : (ndp <= UINT_MAX ? 4 : 6); + return likely(ndp <= USHRT_MAX) ? 2 : (ndp <= UINT_MAX ? 4 : 6); } int dccp_insert_option(struct sock *sk, struct sk_buff *skb, diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 9de6a698f91d..baeec29fe0f1 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1686,8 +1686,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, return -ENOPROTOOPT; if (val != 0 && val < 8) /* Illegal coverage: use default (8) */ val = 8; - else if (val > USHORT_MAX) - val = USHORT_MAX; + else if (val > USHRT_MAX) + val = USHRT_MAX; up->pcslen = val; up->pcflag |= UDPLITE_SEND_CC; break; @@ -1700,8 +1700,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, return -ENOPROTOOPT; if (val != 0 && val < 8) /* Avoid silly minimal values. */ val = 8; - else if (val > USHORT_MAX) - val = USHORT_MAX; + else if (val > USHRT_MAX) + val = USHRT_MAX; up->pcrlen = val; up->pcflag |= UDPLITE_RECV_CC; break; diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 730197591ab5..ba9360a475b0 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -259,7 +259,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, skb_queue_head_init(&sta->tx_filtered); for (i = 0; i < NUM_RX_DATA_QUEUES; i++) - sta->last_seq_ctrl[i] = cpu_to_le16(USHORT_MAX); + sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); #ifdef CONFIG_MAC80211_VERBOSE_DEBUG printk(KERN_DEBUG "%s: Allocated STA %pM\n", diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 121105355f60..dac219a56ae1 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -783,7 +783,7 @@ static int rpcb_dec_getport(struct rpc_rqst *req, __be32 *p, port = ntohl(*p); dprintk("RPC: %5u PMAP_%s result: %lu\n", task->tk_pid, task->tk_msg.rpc_proc->p_name, port); - if (unlikely(port > USHORT_MAX)) + if (unlikely(port > USHRT_MAX)) return -EIO; rpcb->r_port = port; diff --git a/security/keys/keyring.c b/security/keys/keyring.c index ef03a82a0135..d37f713e73ce 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c @@ -669,7 +669,7 @@ static void keyring_unlink_rcu_disposal(struct rcu_head *rcu) struct keyring_list *klist = container_of(rcu, struct keyring_list, rcu); - if (klist->delkey != USHORT_MAX) + if (klist->delkey != USHRT_MAX) key_put(klist->keys[klist->delkey]); kfree(klist); } @@ -746,7 +746,7 @@ int __key_link_begin(struct key *keyring, const struct key_type *type, max += klist->maxkeys; ret = -ENFILE; - if (max > USHORT_MAX - 1) + if (max > USHRT_MAX - 1) goto error_quota; size = sizeof(*klist) + sizeof(struct key *) * max; if (size > PAGE_SIZE) @@ -763,7 +763,7 @@ int __key_link_begin(struct key *keyring, const struct key_type *type, sizeof(struct key *) * klist->nkeys); nklist->delkey = klist->nkeys; nklist->nkeys = klist->nkeys + 1; - klist->delkey = USHORT_MAX; + klist->delkey = USHRT_MAX; } else { nklist->nkeys = 1; nklist->delkey = 0; -- cgit v1.2.3 From 08a82c6872ac1d37cb993a52f1b35f97f48295bd Mon Sep 17 00:00:00 2001 From: Phil Carmody Date: Mon, 24 May 2010 14:33:04 -0700 Subject: hvsi: fix messed up error checking getting state name Handle out-of-range indices before reading what they refer to. And don't access the one-past-the-end element of the array either. Signed-off-by: Phil Carmody Cc: Benjamin Herrenschmidt Cc: Roel Kluin Cc: Grant Likely Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/hvsi.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c index 793b236c9266..d4b14ff1c4c1 100644 --- a/drivers/char/hvsi.c +++ b/drivers/char/hvsi.c @@ -194,10 +194,8 @@ static inline void print_state(struct hvsi_struct *hp) "HVSI_WAIT_FOR_MCTRL_RESPONSE", "HVSI_FSP_DIED", }; - const char *name = state_names[hp->state]; - - if (hp->state > ARRAY_SIZE(state_names)) - name = "UNKNOWN"; + const char *name = (hp->state < ARRAY_SIZE(state_names)) + ? state_names[hp->state] : "UNKNOWN"; pr_debug("hvsi%i: state = %s\n", hp->index, name); #endif /* DEBUG */ -- cgit v1.2.3 From fa1f68db6ca7ebb6fc4487ac215bffba06c01c28 Mon Sep 17 00:00:00 2001 From: Samu Onkalo Date: Mon, 24 May 2010 14:33:10 -0700 Subject: drivers: misc: pass miscdevice pointer via file private data For misc devices, inode->i_cdev doesn't point to the device drivers own data. Link between file operations and device driver internal data is lost. Pass pointer to misc device struct via file private data for driver open function use. Signed-off-by: Samu Onkalo Cc: Al Viro Cc: Christoph Hellwig Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/misc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 92ab03d28294..cd650ca8c679 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -144,6 +144,7 @@ static int misc_open(struct inode * inode, struct file * file) old_fops = file->f_op; file->f_op = new_fops; if (file->f_op->open) { + file->private_data = c; err=file->f_op->open(inode,file); if (err) { fops_put(file->f_op); -- cgit v1.2.3 From 0993dbedf2cc2f5fd0701fa3b27afdd303536b87 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 24 May 2010 14:33:13 -0700 Subject: ad525x_dpot: simplify duplicated sysfs defines Macro away the duplication to make maintenance easier. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/ad525x_dpot.c | 238 ++++++++------------------------------------- 1 file changed, 43 insertions(+), 195 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/ad525x_dpot.c b/drivers/misc/ad525x_dpot.c index 30a59f2bacd2..e6b274b5dbd6 100644 --- a/drivers/misc/ad525x_dpot.c +++ b/drivers/misc/ad525x_dpot.c @@ -158,175 +158,45 @@ static ssize_t sysfs_do_cmd(struct device *dev, /* ------------------------------------------------------------------------- */ -static ssize_t show_rdac0(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sysfs_show_reg(dev, attr, buf, AD525X_I2C_RDAC | AD525X_RDAC0); -} - -static ssize_t set_rdac0(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return sysfs_set_reg(dev, attr, buf, count, - AD525X_I2C_RDAC | AD525X_RDAC0); -} - -static DEVICE_ATTR(rdac0, S_IWUSR | S_IRUGO, show_rdac0, set_rdac0); - -static ssize_t show_eeprom0(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sysfs_show_reg(dev, attr, buf, AD525X_I2C_EEPROM | AD525X_RDAC0); -} - -static ssize_t set_eeprom0(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return sysfs_set_reg(dev, attr, buf, count, - AD525X_I2C_EEPROM | AD525X_RDAC0); -} - -static DEVICE_ATTR(eeprom0, S_IWUSR | S_IRUGO, show_eeprom0, set_eeprom0); - -static ssize_t show_tolerance0(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sysfs_show_reg(dev, attr, buf, - AD525X_I2C_EEPROM | AD525X_TOL_RDAC0); -} - -static DEVICE_ATTR(tolerance0, S_IRUGO, show_tolerance0, NULL); - -/* ------------------------------------------------------------------------- */ - -static ssize_t show_rdac1(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sysfs_show_reg(dev, attr, buf, AD525X_I2C_RDAC | AD525X_RDAC1); +#define DPOT_DEVICE_SHOW(_name, _reg) static ssize_t \ +show_##_name(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + return sysfs_show_reg(dev, attr, buf, _reg); \ } -static ssize_t set_rdac1(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return sysfs_set_reg(dev, attr, buf, count, - AD525X_I2C_RDAC | AD525X_RDAC1); +#define DPOT_DEVICE_SET(_name, _reg) static ssize_t \ +set_##_name(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + return sysfs_set_reg(dev, attr, buf, count, _reg); \ } -static DEVICE_ATTR(rdac1, S_IWUSR | S_IRUGO, show_rdac1, set_rdac1); +#define DPOT_DEVICE_SHOW_SET(name, reg) \ +DPOT_DEVICE_SHOW(name, reg) \ +DPOT_DEVICE_SET(name, reg) \ +static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, set_##name); -static ssize_t show_eeprom1(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sysfs_show_reg(dev, attr, buf, AD525X_I2C_EEPROM | AD525X_RDAC1); -} +#define DPOT_DEVICE_SHOW_ONLY(name, reg) \ +DPOT_DEVICE_SHOW(name, reg) \ +static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, NULL); -static ssize_t set_eeprom1(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return sysfs_set_reg(dev, attr, buf, count, - AD525X_I2C_EEPROM | AD525X_RDAC1); -} +DPOT_DEVICE_SHOW_SET(rdac0, AD525X_I2C_RDAC | AD525X_RDAC0); +DPOT_DEVICE_SHOW_SET(eeprom0, AD525X_I2C_EEPROM | AD525X_RDAC0); +DPOT_DEVICE_SHOW_ONLY(tolerance0, AD525X_I2C_EEPROM | AD525X_TOL_RDAC0); -static DEVICE_ATTR(eeprom1, S_IWUSR | S_IRUGO, show_eeprom1, set_eeprom1); +DPOT_DEVICE_SHOW_SET(rdac1, AD525X_I2C_RDAC | AD525X_RDAC1); +DPOT_DEVICE_SHOW_SET(eeprom1, AD525X_I2C_EEPROM | AD525X_RDAC1); +DPOT_DEVICE_SHOW_ONLY(tolerance1, AD525X_I2C_EEPROM | AD525X_TOL_RDAC1); -static ssize_t show_tolerance1(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sysfs_show_reg(dev, attr, buf, - AD525X_I2C_EEPROM | AD525X_TOL_RDAC1); -} - -static DEVICE_ATTR(tolerance1, S_IRUGO, show_tolerance1, NULL); +DPOT_DEVICE_SHOW_SET(rdac2, AD525X_I2C_RDAC | AD525X_RDAC2); +DPOT_DEVICE_SHOW_SET(eeprom2, AD525X_I2C_EEPROM | AD525X_RDAC2); +DPOT_DEVICE_SHOW_ONLY(tolerance2, AD525X_I2C_EEPROM | AD525X_TOL_RDAC2); -/* ------------------------------------------------------------------------- */ - -static ssize_t show_rdac2(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sysfs_show_reg(dev, attr, buf, AD525X_I2C_RDAC | AD525X_RDAC2); -} - -static ssize_t set_rdac2(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return sysfs_set_reg(dev, attr, buf, count, - AD525X_I2C_RDAC | AD525X_RDAC2); -} - -static DEVICE_ATTR(rdac2, S_IWUSR | S_IRUGO, show_rdac2, set_rdac2); - -static ssize_t show_eeprom2(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sysfs_show_reg(dev, attr, buf, AD525X_I2C_EEPROM | AD525X_RDAC2); -} - -static ssize_t set_eeprom2(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return sysfs_set_reg(dev, attr, buf, count, - AD525X_I2C_EEPROM | AD525X_RDAC2); -} - -static DEVICE_ATTR(eeprom2, S_IWUSR | S_IRUGO, show_eeprom2, set_eeprom2); - -static ssize_t show_tolerance2(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sysfs_show_reg(dev, attr, buf, - AD525X_I2C_EEPROM | AD525X_TOL_RDAC2); -} - -static DEVICE_ATTR(tolerance2, S_IRUGO, show_tolerance2, NULL); - -/* ------------------------------------------------------------------------- */ - -static ssize_t show_rdac3(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sysfs_show_reg(dev, attr, buf, AD525X_I2C_RDAC | AD525X_RDAC3); -} - -static ssize_t set_rdac3(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return sysfs_set_reg(dev, attr, buf, count, - AD525X_I2C_RDAC | AD525X_RDAC3); -} - -static DEVICE_ATTR(rdac3, S_IWUSR | S_IRUGO, show_rdac3, set_rdac3); - -static ssize_t show_eeprom3(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sysfs_show_reg(dev, attr, buf, AD525X_I2C_EEPROM | AD525X_RDAC3); -} - -static ssize_t set_eeprom3(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return sysfs_set_reg(dev, attr, buf, count, - AD525X_I2C_EEPROM | AD525X_RDAC3); -} - -static DEVICE_ATTR(eeprom3, S_IWUSR | S_IRUGO, show_eeprom3, set_eeprom3); - -static ssize_t show_tolerance3(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sysfs_show_reg(dev, attr, buf, - AD525X_I2C_EEPROM | AD525X_TOL_RDAC3); -} - -static DEVICE_ATTR(tolerance3, S_IRUGO, show_tolerance3, NULL); +DPOT_DEVICE_SHOW_SET(rdac3, AD525X_I2C_RDAC | AD525X_RDAC3); +DPOT_DEVICE_SHOW_SET(eeprom3, AD525X_I2C_EEPROM | AD525X_RDAC3); +DPOT_DEVICE_SHOW_ONLY(tolerance3, AD525X_I2C_EEPROM | AD525X_TOL_RDAC3); static struct attribute *ad525x_attributes_wipers[4][4] = { { @@ -361,41 +231,19 @@ static const struct attribute_group ad525x_group_wipers[] = { /* ------------------------------------------------------------------------- */ -static ssize_t set_inc_all(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return sysfs_do_cmd(dev, attr, buf, count, AD525X_INC_ALL); -} - -static DEVICE_ATTR(inc_all, S_IWUSR, NULL, set_inc_all); - -static ssize_t set_dec_all(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return sysfs_do_cmd(dev, attr, buf, count, AD525X_DEC_ALL); -} - -static DEVICE_ATTR(dec_all, S_IWUSR, NULL, set_dec_all); - -static ssize_t set_inc_all_6db(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return sysfs_do_cmd(dev, attr, buf, count, AD525X_INC_ALL_6DB); -} - -static DEVICE_ATTR(inc_all_6db, S_IWUSR, NULL, set_inc_all_6db); - -static ssize_t set_dec_all_6db(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return sysfs_do_cmd(dev, attr, buf, count, AD525X_DEC_ALL_6DB); -} - -static DEVICE_ATTR(dec_all_6db, S_IWUSR, NULL, set_dec_all_6db); +#define DPOT_DEVICE_DO_CMD(_name, _cmd) static ssize_t \ +set_##_name(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + return sysfs_do_cmd(dev, attr, buf, count, _cmd); \ +} \ +static DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, NULL, set_##_name); + +DPOT_DEVICE_DO_CMD(inc_all, AD525X_INC_ALL); +DPOT_DEVICE_DO_CMD(dec_all, AD525X_DEC_ALL); +DPOT_DEVICE_DO_CMD(inc_all_6db, AD525X_INC_ALL_6DB); +DPOT_DEVICE_DO_CMD(dec_all_6db, AD525X_DEC_ALL_6DB); static struct attribute *ad525x_attributes_commands[] = { &dev_attr_inc_all.attr, -- cgit v1.2.3 From 0c53b9fbcca8870e4f4b248f4ed5fdadd43a01b6 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 24 May 2010 14:33:13 -0700 Subject: ad525x_dpot: extend write argument to 16bits The possible output data is 16bits, not 8bits, so don't truncate it. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/ad525x_dpot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/ad525x_dpot.c b/drivers/misc/ad525x_dpot.c index e6b274b5dbd6..ce92088bf0b8 100644 --- a/drivers/misc/ad525x_dpot.c +++ b/drivers/misc/ad525x_dpot.c @@ -75,7 +75,7 @@ enum dpot_devid { #define AD525X_INC_ALL (AD525X_I2C_CMD | (0xB << 3)) static s32 ad525x_read(struct i2c_client *client, u8 reg); -static s32 ad525x_write(struct i2c_client *client, u8 reg, u8 value); +static s32 ad525x_write(struct i2c_client *client, u8 reg, u16 value); /* * Client data (each client gets its own) @@ -296,7 +296,7 @@ static s32 ad525x_read(struct i2c_client *client, u8 reg) * A negative return value indicates an error occurred while reading * the register. */ -static s32 ad525x_write(struct i2c_client *client, u8 reg, u8 value) +static s32 ad525x_write(struct i2c_client *client, u8 reg, u16 value) { struct dpot_data *data = i2c_get_clientdata(client); -- cgit v1.2.3 From 6c536e4ce8edd61fdc4ab68e19ae164a54fc958f Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 24 May 2010 14:33:14 -0700 Subject: ad525x_dpot: add support for SPI parts Split the bus logic out into separate files so that we can handle I2C and SPI busses independently. The new SPI bus logic brings in support for a lot more parts: AD5160, AD5161, AD5162, AD5165, AD5200, AD5201, AD5203, AD5204, AD5206, AD5207, AD5231, AD5232, AD5233, AD5235, AD5260, AD5262, AD5263, AD5290, AD5291, AD5292, AD5293, AD7376, AD8400, AD8402, AD8403, ADN2850 [randy.dunlap@oracle.com: fix ad525X_dpot build] Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/Kconfig | 30 +- drivers/misc/Makefile | 2 + drivers/misc/ad525x_dpot-i2c.c | 119 ++++++++ drivers/misc/ad525x_dpot-spi.c | 172 +++++++++++ drivers/misc/ad525x_dpot.c | 629 ++++++++++++++++++++--------------------- drivers/misc/ad525x_dpot.h | 173 ++++++++++++ 6 files changed, 806 insertions(+), 319 deletions(-) create mode 100644 drivers/misc/ad525x_dpot-i2c.c create mode 100644 drivers/misc/ad525x_dpot-spi.c create mode 100644 drivers/misc/ad525x_dpot.h (limited to 'drivers') diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 0d0d625fece2..69e019e7d69c 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -14,11 +14,15 @@ menuconfig MISC_DEVICES if MISC_DEVICES config AD525X_DPOT - tristate "Analog Devices AD525x Digital Potentiometers" - depends on I2C && SYSFS + tristate "Analog Devices Digital Potentiometers" + depends on (I2C || SPI) && SYSFS help If you say yes here, you get support for the Analog Devices - AD5258, AD5259, AD5251, AD5252, AD5253, AD5254 and AD5255 + AD5258, AD5259, AD5251, AD5252, AD5253, AD5254, AD5255 + AD5160, AD5161, AD5162, AD5165, AD5200, AD5201, AD5203, + AD5204, AD5206, AD5207, AD5231, AD5232, AD5233, AD5235, + AD5260, AD5262, AD5263, AD5290, AD5291, AD5292, AD5293, + AD7376, AD8400, AD8402, AD8403, ADN2850 digital potentiometer chips. See Documentation/misc-devices/ad525x_dpot.txt for the @@ -27,6 +31,26 @@ config AD525X_DPOT This driver can also be built as a module. If so, the module will be called ad525x_dpot. +config AD525X_DPOT_I2C + tristate "support I2C bus connection" + depends on AD525X_DPOT && I2C + help + Say Y here if you have a digital potentiometers hooked to an I2C bus. + + To compile this driver as a module, choose M here: the + module will be called ad525x_dpot-i2c. + +config AD525X_DPOT_SPI + tristate "support SPI bus connection" + depends on AD525X_DPOT && SPI_MASTER + help + Say Y here if you have a digital potentiometers hooked to an SPI bus. + + If unsure, say N (but it's safe to say "Y"). + + To compile this driver as a module, choose M here: the + module will be called ad525x_dpot-spi. + config ATMEL_PWM tristate "Atmel AT32/AT91 PWM support" depends on AVR32 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index f12dc3e54402..6ed06a19474a 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -4,6 +4,8 @@ obj-$(CONFIG_IBM_ASM) += ibmasm/ obj-$(CONFIG_AD525X_DPOT) += ad525x_dpot.o +obj-$(CONFIG_AD525X_DPOT_I2C) += ad525x_dpot-i2c.o +obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o diff --git a/drivers/misc/ad525x_dpot-i2c.c b/drivers/misc/ad525x_dpot-i2c.c new file mode 100644 index 000000000000..971e61d7f881 --- /dev/null +++ b/drivers/misc/ad525x_dpot-i2c.c @@ -0,0 +1,119 @@ +/* + * Driver for the Analog Devices digital potentiometers (I2C bus) + * + * Copyright (C) 2010 Michael Hennerich, Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include + +#include "ad525x_dpot.h" + +/* ------------------------------------------------------------------------- */ +/* I2C bus functions */ +static int write_d8(void *client, u8 val) +{ + return i2c_smbus_write_byte(client, val); +} + +static int write_r8d8(void *client, u8 reg, u8 val) +{ + return i2c_smbus_write_byte_data(client, reg, val); +} + +static int write_r8d16(void *client, u8 reg, u16 val) +{ + return i2c_smbus_write_word_data(client, reg, val); +} + +static int read_d8(void *client) +{ + return i2c_smbus_read_byte(client); +} + +static int read_r8d8(void *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int read_r8d16(void *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static const struct ad_dpot_bus_ops bops = { + .read_d8 = read_d8, + .read_r8d8 = read_r8d8, + .read_r8d16 = read_r8d16, + .write_d8 = write_d8, + .write_r8d8 = write_r8d8, + .write_r8d16 = write_r8d16, +}; + +static int __devinit ad_dpot_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct ad_dpot_bus_data bdata = { + .client = client, + .bops = &bops, + }; + + struct ad_dpot_id dpot_id = { + .name = (char *) &id->name, + .devid = id->driver_data, + }; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WORD_DATA)) { + dev_err(&client->dev, "SMBUS Word Data not Supported\n"); + return -EIO; + } + + return ad_dpot_probe(&client->dev, &bdata, &dpot_id); +} + +static int __devexit ad_dpot_i2c_remove(struct i2c_client *client) +{ + return ad_dpot_remove(&client->dev); +} + +static const struct i2c_device_id ad_dpot_id[] = { + {"ad5258", AD5258_ID}, + {"ad5259", AD5259_ID}, + {"ad5251", AD5251_ID}, + {"ad5252", AD5252_ID}, + {"ad5253", AD5253_ID}, + {"ad5254", AD5254_ID}, + {"ad5255", AD5255_ID}, + {} +}; +MODULE_DEVICE_TABLE(i2c, ad_dpot_id); + +static struct i2c_driver ad_dpot_i2c_driver = { + .driver = { + .name = "ad_dpot", + .owner = THIS_MODULE, + }, + .probe = ad_dpot_i2c_probe, + .remove = __devexit_p(ad_dpot_i2c_remove), + .id_table = ad_dpot_id, +}; + +static int __init ad_dpot_i2c_init(void) +{ + return i2c_add_driver(&ad_dpot_i2c_driver); +} +module_init(ad_dpot_i2c_init); + +static void __exit ad_dpot_i2c_exit(void) +{ + i2c_del_driver(&ad_dpot_i2c_driver); +} +module_exit(ad_dpot_i2c_exit); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("digital potentiometer I2C bus driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("i2c:ad_dpot"); diff --git a/drivers/misc/ad525x_dpot-spi.c b/drivers/misc/ad525x_dpot-spi.c new file mode 100644 index 000000000000..b8c6df9c8437 --- /dev/null +++ b/drivers/misc/ad525x_dpot-spi.c @@ -0,0 +1,172 @@ +/* + * Driver for the Analog Devices digital potentiometers (SPI bus) + * + * Copyright (C) 2010 Michael Hennerich, Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include + +#include "ad525x_dpot.h" + +static const struct ad_dpot_id ad_dpot_spi_devlist[] = { + {.name = "ad5160", .devid = AD5160_ID}, + {.name = "ad5161", .devid = AD5161_ID}, + {.name = "ad5162", .devid = AD5162_ID}, + {.name = "ad5165", .devid = AD5165_ID}, + {.name = "ad5200", .devid = AD5200_ID}, + {.name = "ad5201", .devid = AD5201_ID}, + {.name = "ad5203", .devid = AD5203_ID}, + {.name = "ad5204", .devid = AD5204_ID}, + {.name = "ad5206", .devid = AD5206_ID}, + {.name = "ad5207", .devid = AD5207_ID}, + {.name = "ad5231", .devid = AD5231_ID}, + {.name = "ad5232", .devid = AD5232_ID}, + {.name = "ad5233", .devid = AD5233_ID}, + {.name = "ad5235", .devid = AD5235_ID}, + {.name = "ad5260", .devid = AD5260_ID}, + {.name = "ad5262", .devid = AD5262_ID}, + {.name = "ad5263", .devid = AD5263_ID}, + {.name = "ad5290", .devid = AD5290_ID}, + {.name = "ad5291", .devid = AD5291_ID}, + {.name = "ad5292", .devid = AD5292_ID}, + {.name = "ad5293", .devid = AD5293_ID}, + {.name = "ad7376", .devid = AD7376_ID}, + {.name = "ad8400", .devid = AD8400_ID}, + {.name = "ad8402", .devid = AD8402_ID}, + {.name = "ad8403", .devid = AD8403_ID}, + {.name = "adn2850", .devid = ADN2850_ID}, + {} +}; + +/* ------------------------------------------------------------------------- */ + +/* SPI bus functions */ +static int write8(void *client, u8 val) +{ + u8 data = val; + return spi_write(client, &data, 1); +} + +static int write16(void *client, u8 reg, u8 val) +{ + u8 data[2] = {reg, val}; + return spi_write(client, data, 1); +} + +static int write24(void *client, u8 reg, u16 val) +{ + u8 data[3] = {reg, val >> 8, val}; + return spi_write(client, data, 1); +} + +static int read8(void *client) +{ + int ret; + u8 data; + ret = spi_read(client, &data, 1); + if (ret < 0) + return ret; + + return data; +} + +static int read16(void *client, u8 reg) +{ + int ret; + u8 buf_rx[2]; + + write16(client, reg, 0); + ret = spi_read(client, buf_rx, 2); + if (ret < 0) + return ret; + + return (buf_rx[0] << 8) | buf_rx[1]; +} + +static int read24(void *client, u8 reg) +{ + int ret; + u8 buf_rx[3]; + + write24(client, reg, 0); + ret = spi_read(client, buf_rx, 3); + if (ret < 0) + return ret; + + return (buf_rx[1] << 8) | buf_rx[2]; +} + +static const struct ad_dpot_bus_ops bops = { + .read_d8 = read8, + .read_r8d8 = read16, + .read_r8d16 = read24, + .write_d8 = write8, + .write_r8d8 = write16, + .write_r8d16 = write24, +}; + +static const struct ad_dpot_id *dpot_match_id(const struct ad_dpot_id *id, + char *name) +{ + while (id->name && id->name[0]) { + if (strcmp(name, id->name) == 0) + return id; + id++; + } + return NULL; +} + +static int __devinit ad_dpot_spi_probe(struct spi_device *spi) +{ + char *name = spi->dev.platform_data; + const struct ad_dpot_id *dpot_id; + + struct ad_dpot_bus_data bdata = { + .client = spi, + .bops = &bops, + }; + + dpot_id = dpot_match_id(ad_dpot_spi_devlist, name); + + if (dpot_id == NULL) { + dev_err(&spi->dev, "%s not in supported device list", name); + return -ENODEV; + } + + return ad_dpot_probe(&spi->dev, &bdata, dpot_id); +} + +static int __devexit ad_dpot_spi_remove(struct spi_device *spi) +{ + return ad_dpot_remove(&spi->dev); +} + +static struct spi_driver ad_dpot_spi_driver = { + .driver = { + .name = "ad_dpot", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = ad_dpot_spi_probe, + .remove = __devexit_p(ad_dpot_spi_remove), +}; + +static int __init ad_dpot_spi_init(void) +{ + return spi_register_driver(&ad_dpot_spi_driver); +} +module_init(ad_dpot_spi_init); + +static void __exit ad_dpot_spi_exit(void) +{ + spi_unregister_driver(&ad_dpot_spi_driver); +} +module_exit(ad_dpot_spi_exit); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("digital potentiometer SPI bus driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("spi:ad_dpot"); diff --git a/drivers/misc/ad525x_dpot.c b/drivers/misc/ad525x_dpot.c index ce92088bf0b8..a41c2de0eae8 100644 --- a/drivers/misc/ad525x_dpot.c +++ b/drivers/misc/ad525x_dpot.c @@ -1,6 +1,6 @@ /* - * ad525x_dpot: Driver for the Analog Devices AD525x digital potentiometers - * Copyright (c) 2009 Analog Devices, Inc. + * ad525x_dpot: Driver for the Analog Devices digital potentiometers + * Copyright (c) 2009-2010 Analog Devices, Inc. * Author: Michael Hennerich * * DEVID #Wipers #Positions Resistor Options (kOhm) @@ -11,6 +11,32 @@ * AD5255 3 512 25, 250 * AD5253 4 64 1, 10, 50, 100 * AD5254 4 256 1, 10, 50, 100 + * AD5160 1 256 5, 10, 50, 100 + * AD5161 1 256 5, 10, 50, 100 + * AD5162 2 256 2.5, 10, 50, 100 + * AD5165 1 256 100 + * AD5200 1 256 10, 50 + * AD5201 1 33 10, 50 + * AD5203 4 64 10, 100 + * AD5204 4 256 10, 50, 100 + * AD5206 6 256 10, 50, 100 + * AD5207 2 256 10, 50, 100 + * AD5231 1 1024 10, 50, 100 + * AD5232 2 256 10, 50, 100 + * AD5233 4 64 10, 50, 100 + * AD5235 2 1024 25, 250 + * AD5260 1 256 20, 50, 200 + * AD5262 2 256 20, 50, 200 + * AD5263 4 256 20, 50, 200 + * AD5290 1 256 10, 50, 100 + * AD5291 1 256 20 + * AD5292 1 1024 20 + * AD5293 1 1024 20 + * AD7376 1 128 10, 50, 100, 1M + * AD8400 1 256 1, 10, 50, 100 + * AD8402 2 256 1, 10, 50, 100 + * AD8403 4 256 1, 10, 50, 100 + * ADN2850 3 512 25, 250 * * See Documentation/misc-devices/ad525x_dpot.txt for more info. * @@ -28,77 +54,182 @@ #include #include #include -#include -#include #include +#include -#define DRIVER_NAME "ad525x_dpot" -#define DRIVER_VERSION "0.1" - -enum dpot_devid { - AD5258_ID, - AD5259_ID, - AD5251_ID, - AD5252_ID, - AD5253_ID, - AD5254_ID, - AD5255_ID, -}; +#define DRIVER_VERSION "0.2" -#define AD5258_MAX_POSITION 64 -#define AD5259_MAX_POSITION 256 -#define AD5251_MAX_POSITION 64 -#define AD5252_MAX_POSITION 256 -#define AD5253_MAX_POSITION 64 -#define AD5254_MAX_POSITION 256 -#define AD5255_MAX_POSITION 512 - -#define AD525X_RDAC0 0 -#define AD525X_RDAC1 1 -#define AD525X_RDAC2 2 -#define AD525X_RDAC3 3 - -#define AD525X_REG_TOL 0x18 -#define AD525X_TOL_RDAC0 (AD525X_REG_TOL | AD525X_RDAC0) -#define AD525X_TOL_RDAC1 (AD525X_REG_TOL | AD525X_RDAC1) -#define AD525X_TOL_RDAC2 (AD525X_REG_TOL | AD525X_RDAC2) -#define AD525X_TOL_RDAC3 (AD525X_REG_TOL | AD525X_RDAC3) - -/* RDAC-to-EEPROM Interface Commands */ -#define AD525X_I2C_RDAC (0x00 << 5) -#define AD525X_I2C_EEPROM (0x01 << 5) -#define AD525X_I2C_CMD (0x80) - -#define AD525X_DEC_ALL_6DB (AD525X_I2C_CMD | (0x4 << 3)) -#define AD525X_INC_ALL_6DB (AD525X_I2C_CMD | (0x9 << 3)) -#define AD525X_DEC_ALL (AD525X_I2C_CMD | (0x6 << 3)) -#define AD525X_INC_ALL (AD525X_I2C_CMD | (0xB << 3)) - -static s32 ad525x_read(struct i2c_client *client, u8 reg); -static s32 ad525x_write(struct i2c_client *client, u8 reg, u16 value); +#include "ad525x_dpot.h" /* * Client data (each client gets its own) */ struct dpot_data { + struct ad_dpot_bus_data bdata; struct mutex update_lock; unsigned rdac_mask; unsigned max_pos; - unsigned devid; + unsigned long devid; + unsigned uid; + unsigned feat; + unsigned wipers; + u16 rdac_cache[8]; }; +static inline int dpot_read_d8(struct dpot_data *dpot) +{ + return dpot->bdata.bops->read_d8(dpot->bdata.client); +} + +static inline int dpot_read_r8d8(struct dpot_data *dpot, u8 reg) +{ + return dpot->bdata.bops->read_r8d8(dpot->bdata.client, reg); +} + +static inline int dpot_read_r8d16(struct dpot_data *dpot, u8 reg) +{ + return dpot->bdata.bops->read_r8d16(dpot->bdata.client, reg); +} + +static inline int dpot_write_d8(struct dpot_data *dpot, u8 val) +{ + return dpot->bdata.bops->write_d8(dpot->bdata.client, val); +} + +static inline int dpot_write_r8d8(struct dpot_data *dpot, u8 reg, u16 val) +{ + return dpot->bdata.bops->write_r8d8(dpot->bdata.client, reg, val); +} + +static inline int dpot_write_r8d16(struct dpot_data *dpot, u8 reg, u16 val) +{ + return dpot->bdata.bops->write_r8d16(dpot->bdata.client, reg, val); +} + +static s32 dpot_read(struct dpot_data *dpot, u8 reg) +{ + unsigned val = 0; + + if (dpot->feat & F_SPI) { + if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD))) { + + if (dpot->feat & F_RDACS_WONLY) + return dpot->rdac_cache[reg & DPOT_RDAC_MASK]; + + if (dpot->uid == DPOT_UID(AD5291_ID) || + dpot->uid == DPOT_UID(AD5292_ID) || + dpot->uid == DPOT_UID(AD5293_ID)) + return dpot_read_r8d8(dpot, + DPOT_AD5291_READ_RDAC << 2); + + val = DPOT_SPI_READ_RDAC; + } else if (reg & DPOT_ADDR_EEPROM) { + val = DPOT_SPI_READ_EEPROM; + } + + if (dpot->feat & F_SPI_16BIT) + return dpot_read_r8d8(dpot, val); + else if (dpot->feat & F_SPI_24BIT) + return dpot_read_r8d16(dpot, val); + + } else { /* I2C */ + + if ((reg & DPOT_REG_TOL) || (dpot->max_pos > 256)) + return dpot_read_r8d16(dpot, (reg & 0xF8) | + ((reg & 0x7) << 1)); + else + return dpot_read_r8d8(dpot, reg); + + } + return -EFAULT; +} + +static s32 dpot_write(struct dpot_data *dpot, u8 reg, u16 value) +{ + unsigned val = 0; + + if (dpot->feat & F_SPI) { + if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD))) { + if (dpot->feat & F_RDACS_WONLY) + dpot->rdac_cache[reg & DPOT_RDAC_MASK] = value; + + if (dpot->feat & F_AD_APPDATA) { + if (dpot->feat & F_SPI_8BIT) { + val = ((reg & DPOT_RDAC_MASK) << + DPOT_MAX_POS(dpot->devid)) | + value; + return dpot_write_d8(dpot, val); + } else if (dpot->feat & F_SPI_16BIT) { + val = ((reg & DPOT_RDAC_MASK) << + DPOT_MAX_POS(dpot->devid)) | + value; + return dpot_write_r8d8(dpot, val >> 8, + val & 0xFF); + } else + BUG(); + } else { + if (dpot->uid == DPOT_UID(AD5291_ID) || + dpot->uid == DPOT_UID(AD5292_ID) || + dpot->uid == DPOT_UID(AD5293_ID)) + return dpot_write_r8d8(dpot, + (DPOT_AD5291_RDAC << 2) | + (value >> 8), value & 0xFF); + + val = DPOT_SPI_RDAC | (reg & DPOT_RDAC_MASK); + } + } else if (reg & DPOT_ADDR_EEPROM) { + val = DPOT_SPI_EEPROM | (reg & DPOT_RDAC_MASK); + } else if (reg & DPOT_ADDR_CMD) { + switch (reg) { + case DPOT_DEC_ALL_6DB: + val = DPOT_SPI_DEC_ALL_6DB; + break; + case DPOT_INC_ALL_6DB: + val = DPOT_SPI_INC_ALL_6DB; + break; + case DPOT_DEC_ALL: + val = DPOT_SPI_DEC_ALL; + break; + case DPOT_INC_ALL: + val = DPOT_SPI_INC_ALL; + break; + } + } else + BUG(); + + if (dpot->feat & F_SPI_16BIT) + return dpot_write_r8d8(dpot, val, value); + else if (dpot->feat & F_SPI_24BIT) + return dpot_write_r8d16(dpot, val, value); + } else { + /* Only write the instruction byte for certain commands */ + if (reg & DPOT_ADDR_CMD) + return dpot_write_d8(dpot, reg); + + if (dpot->max_pos > 256) + return dpot_write_r8d16(dpot, (reg & 0xF8) | + ((reg & 0x7) << 1), value); + else + /* All other registers require instruction + data bytes */ + return dpot_write_r8d8(dpot, reg, value); + + } + + return -EFAULT; +} + /* sysfs functions */ static ssize_t sysfs_show_reg(struct device *dev, - struct device_attribute *attr, char *buf, u32 reg) + struct device_attribute *attr, + char *buf, u32 reg) { - struct i2c_client *client = to_i2c_client(dev); - struct dpot_data *data = i2c_get_clientdata(client); + struct dpot_data *data = dev_get_drvdata(dev); s32 value; mutex_lock(&data->update_lock); - value = ad525x_read(client, reg); + value = dpot_read(data, reg); mutex_unlock(&data->update_lock); if (value < 0) @@ -111,7 +242,7 @@ static ssize_t sysfs_show_reg(struct device *dev, * datasheet (Rev. A) for more details. */ - if (reg & AD525X_REG_TOL) + if (reg & DPOT_REG_TOL) return sprintf(buf, "0x%04x\n", value & 0xFFFF); else return sprintf(buf, "%u\n", value & data->rdac_mask); @@ -121,8 +252,7 @@ static ssize_t sysfs_set_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count, u32 reg) { - struct i2c_client *client = to_i2c_client(dev); - struct dpot_data *data = i2c_get_clientdata(client); + struct dpot_data *data = dev_get_drvdata(dev); unsigned long value; int err; @@ -134,8 +264,8 @@ static ssize_t sysfs_set_reg(struct device *dev, value = data->rdac_mask; mutex_lock(&data->update_lock); - ad525x_write(client, reg, value); - if (reg & AD525X_I2C_EEPROM) + dpot_write(data, reg, value); + if (reg & DPOT_ADDR_EEPROM) msleep(26); /* Sleep while the EEPROM updates */ mutex_unlock(&data->update_lock); @@ -146,11 +276,10 @@ static ssize_t sysfs_do_cmd(struct device *dev, struct device_attribute *attr, const char *buf, size_t count, u32 reg) { - struct i2c_client *client = to_i2c_client(dev); - struct dpot_data *data = i2c_get_clientdata(client); + struct dpot_data *data = dev_get_drvdata(dev); mutex_lock(&data->update_lock); - ad525x_write(client, reg, 0); + dpot_write(data, reg, 0); mutex_unlock(&data->update_lock); return count; @@ -182,51 +311,58 @@ static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, set_##name); DPOT_DEVICE_SHOW(name, reg) \ static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, NULL); -DPOT_DEVICE_SHOW_SET(rdac0, AD525X_I2C_RDAC | AD525X_RDAC0); -DPOT_DEVICE_SHOW_SET(eeprom0, AD525X_I2C_EEPROM | AD525X_RDAC0); -DPOT_DEVICE_SHOW_ONLY(tolerance0, AD525X_I2C_EEPROM | AD525X_TOL_RDAC0); - -DPOT_DEVICE_SHOW_SET(rdac1, AD525X_I2C_RDAC | AD525X_RDAC1); -DPOT_DEVICE_SHOW_SET(eeprom1, AD525X_I2C_EEPROM | AD525X_RDAC1); -DPOT_DEVICE_SHOW_ONLY(tolerance1, AD525X_I2C_EEPROM | AD525X_TOL_RDAC1); - -DPOT_DEVICE_SHOW_SET(rdac2, AD525X_I2C_RDAC | AD525X_RDAC2); -DPOT_DEVICE_SHOW_SET(eeprom2, AD525X_I2C_EEPROM | AD525X_RDAC2); -DPOT_DEVICE_SHOW_ONLY(tolerance2, AD525X_I2C_EEPROM | AD525X_TOL_RDAC2); - -DPOT_DEVICE_SHOW_SET(rdac3, AD525X_I2C_RDAC | AD525X_RDAC3); -DPOT_DEVICE_SHOW_SET(eeprom3, AD525X_I2C_EEPROM | AD525X_RDAC3); -DPOT_DEVICE_SHOW_ONLY(tolerance3, AD525X_I2C_EEPROM | AD525X_TOL_RDAC3); - -static struct attribute *ad525x_attributes_wipers[4][4] = { - { - &dev_attr_rdac0.attr, - &dev_attr_eeprom0.attr, - &dev_attr_tolerance0.attr, - NULL - }, { - &dev_attr_rdac1.attr, - &dev_attr_eeprom1.attr, - &dev_attr_tolerance1.attr, - NULL - }, { - &dev_attr_rdac2.attr, - &dev_attr_eeprom2.attr, - &dev_attr_tolerance2.attr, - NULL - }, { - &dev_attr_rdac3.attr, - &dev_attr_eeprom3.attr, - &dev_attr_tolerance3.attr, - NULL - } +DPOT_DEVICE_SHOW_SET(rdac0, DPOT_ADDR_RDAC | DPOT_RDAC0); +DPOT_DEVICE_SHOW_SET(eeprom0, DPOT_ADDR_EEPROM | DPOT_RDAC0); +DPOT_DEVICE_SHOW_ONLY(tolerance0, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC0); + +DPOT_DEVICE_SHOW_SET(rdac1, DPOT_ADDR_RDAC | DPOT_RDAC1); +DPOT_DEVICE_SHOW_SET(eeprom1, DPOT_ADDR_EEPROM | DPOT_RDAC1); +DPOT_DEVICE_SHOW_ONLY(tolerance1, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC1); + +DPOT_DEVICE_SHOW_SET(rdac2, DPOT_ADDR_RDAC | DPOT_RDAC2); +DPOT_DEVICE_SHOW_SET(eeprom2, DPOT_ADDR_EEPROM | DPOT_RDAC2); +DPOT_DEVICE_SHOW_ONLY(tolerance2, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC2); + +DPOT_DEVICE_SHOW_SET(rdac3, DPOT_ADDR_RDAC | DPOT_RDAC3); +DPOT_DEVICE_SHOW_SET(eeprom3, DPOT_ADDR_EEPROM | DPOT_RDAC3); +DPOT_DEVICE_SHOW_ONLY(tolerance3, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC3); + +DPOT_DEVICE_SHOW_SET(rdac4, DPOT_ADDR_RDAC | DPOT_RDAC4); +DPOT_DEVICE_SHOW_SET(eeprom4, DPOT_ADDR_EEPROM | DPOT_RDAC4); +DPOT_DEVICE_SHOW_ONLY(tolerance4, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC4); + +DPOT_DEVICE_SHOW_SET(rdac5, DPOT_ADDR_RDAC | DPOT_RDAC5); +DPOT_DEVICE_SHOW_SET(eeprom5, DPOT_ADDR_EEPROM | DPOT_RDAC5); +DPOT_DEVICE_SHOW_ONLY(tolerance5, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC5); + +static const struct attribute *dpot_attrib_wipers[] = { + &dev_attr_rdac0.attr, + &dev_attr_rdac1.attr, + &dev_attr_rdac2.attr, + &dev_attr_rdac3.attr, + &dev_attr_rdac4.attr, + &dev_attr_rdac5.attr, + NULL +}; + +static const struct attribute *dpot_attrib_eeprom[] = { + &dev_attr_eeprom0.attr, + &dev_attr_eeprom1.attr, + &dev_attr_eeprom2.attr, + &dev_attr_eeprom3.attr, + &dev_attr_eeprom4.attr, + &dev_attr_eeprom5.attr, + NULL }; -static const struct attribute_group ad525x_group_wipers[] = { - {.attrs = ad525x_attributes_wipers[AD525X_RDAC0]}, - {.attrs = ad525x_attributes_wipers[AD525X_RDAC1]}, - {.attrs = ad525x_attributes_wipers[AD525X_RDAC2]}, - {.attrs = ad525x_attributes_wipers[AD525X_RDAC3]}, +static const struct attribute *dpot_attrib_tolerance[] = { + &dev_attr_tolerance0.attr, + &dev_attr_tolerance1.attr, + &dev_attr_tolerance2.attr, + &dev_attr_tolerance3.attr, + &dev_attr_tolerance4.attr, + &dev_attr_tolerance5.attr, + NULL }; /* ------------------------------------------------------------------------- */ @@ -240,10 +376,10 @@ set_##_name(struct device *dev, \ } \ static DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, NULL, set_##_name); -DPOT_DEVICE_DO_CMD(inc_all, AD525X_INC_ALL); -DPOT_DEVICE_DO_CMD(dec_all, AD525X_DEC_ALL); -DPOT_DEVICE_DO_CMD(inc_all_6db, AD525X_INC_ALL_6DB); -DPOT_DEVICE_DO_CMD(dec_all_6db, AD525X_DEC_ALL_6DB); +DPOT_DEVICE_DO_CMD(inc_all, DPOT_INC_ALL); +DPOT_DEVICE_DO_CMD(dec_all, DPOT_DEC_ALL); +DPOT_DEVICE_DO_CMD(inc_all_6db, DPOT_INC_ALL_6DB); +DPOT_DEVICE_DO_CMD(dec_all_6db, DPOT_DEC_ALL_6DB); static struct attribute *ad525x_attributes_commands[] = { &dev_attr_inc_all.attr, @@ -257,74 +393,44 @@ static const struct attribute_group ad525x_group_commands = { .attrs = ad525x_attributes_commands, }; -/* ------------------------------------------------------------------------- */ - -/* i2c device functions */ - -/** - * ad525x_read - return the value contained in the specified register - * on the AD5258 device. - * @client: value returned from i2c_new_device() - * @reg: the register to read - * - * If the tolerance register is specified, 2 bytes are returned. - * Otherwise, 1 byte is returned. A negative value indicates an error - * occurred while reading the register. - */ -static s32 ad525x_read(struct i2c_client *client, u8 reg) +__devinit int ad_dpot_add_files(struct device *dev, + unsigned features, unsigned rdac) { - struct dpot_data *data = i2c_get_clientdata(client); + int err = sysfs_create_file(&dev->kobj, + dpot_attrib_wipers[rdac]); + if (features & F_CMD_EEP) + err |= sysfs_create_file(&dev->kobj, + dpot_attrib_eeprom[rdac]); + if (features & F_CMD_TOL) + err |= sysfs_create_file(&dev->kobj, + dpot_attrib_tolerance[rdac]); - if ((reg & AD525X_REG_TOL) || (data->max_pos > 256)) - return i2c_smbus_read_word_data(client, (reg & 0xF8) | - ((reg & 0x7) << 1)); - else - return i2c_smbus_read_byte_data(client, reg); + if (err) + dev_err(dev, "failed to register sysfs hooks for RDAC%d\n", + rdac); + + return err; } -/** - * ad525x_write - store the given value in the specified register on - * the AD5258 device. - * @client: value returned from i2c_new_device() - * @reg: the register to write - * @value: the byte to store in the register - * - * For certain instructions that do not require a data byte, "NULL" - * should be specified for the "value" parameter. These instructions - * include NOP, RESTORE_FROM_EEPROM, and STORE_TO_EEPROM. - * - * A negative return value indicates an error occurred while reading - * the register. - */ -static s32 ad525x_write(struct i2c_client *client, u8 reg, u16 value) +inline void ad_dpot_remove_files(struct device *dev, + unsigned features, unsigned rdac) { - struct dpot_data *data = i2c_get_clientdata(client); - - /* Only write the instruction byte for certain commands */ - if (reg & AD525X_I2C_CMD) - return i2c_smbus_write_byte(client, reg); - - if (data->max_pos > 256) - return i2c_smbus_write_word_data(client, (reg & 0xF8) | - ((reg & 0x7) << 1), value); - else - /* All other registers require instruction + data bytes */ - return i2c_smbus_write_byte_data(client, reg, value); + sysfs_remove_file(&dev->kobj, + dpot_attrib_wipers[rdac]); + if (features & F_CMD_EEP) + sysfs_remove_file(&dev->kobj, + dpot_attrib_eeprom[rdac]); + if (features & F_CMD_TOL) + sysfs_remove_file(&dev->kobj, + dpot_attrib_tolerance[rdac]); } -static int ad525x_probe(struct i2c_client *client, - const struct i2c_device_id *id) +__devinit int ad_dpot_probe(struct device *dev, + struct ad_dpot_bus_data *bdata, const struct ad_dpot_id *id) { - struct device *dev = &client->dev; - struct dpot_data *data; - int err = 0; - - dev_dbg(dev, "%s\n", __func__); - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) { - dev_err(dev, "missing I2C functionality for this driver\n"); - goto exit; - } + struct dpot_data *data; + int i, err = 0; data = kzalloc(sizeof(struct dpot_data), GFP_KERNEL); if (!data) { @@ -332,183 +438,74 @@ static int ad525x_probe(struct i2c_client *client, goto exit; } - i2c_set_clientdata(client, data); + dev_set_drvdata(dev, data); mutex_init(&data->update_lock); - switch (id->driver_data) { - case AD5258_ID: - data->max_pos = AD5258_MAX_POSITION; - err = sysfs_create_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC0]); - break; - case AD5259_ID: - data->max_pos = AD5259_MAX_POSITION; - err = sysfs_create_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC0]); - break; - case AD5251_ID: - data->max_pos = AD5251_MAX_POSITION; - err = sysfs_create_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC1]); - err |= sysfs_create_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC3]); - err |= sysfs_create_group(&dev->kobj, &ad525x_group_commands); - break; - case AD5252_ID: - data->max_pos = AD5252_MAX_POSITION; - err = sysfs_create_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC1]); - err |= sysfs_create_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC3]); - err |= sysfs_create_group(&dev->kobj, &ad525x_group_commands); - break; - case AD5253_ID: - data->max_pos = AD5253_MAX_POSITION; - err = sysfs_create_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC0]); - err |= sysfs_create_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC1]); - err |= sysfs_create_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC2]); - err |= sysfs_create_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC3]); - err |= sysfs_create_group(&dev->kobj, &ad525x_group_commands); - break; - case AD5254_ID: - data->max_pos = AD5254_MAX_POSITION; - err = sysfs_create_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC0]); - err |= sysfs_create_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC1]); - err |= sysfs_create_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC2]); - err |= sysfs_create_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC3]); - err |= sysfs_create_group(&dev->kobj, &ad525x_group_commands); - break; - case AD5255_ID: - data->max_pos = AD5255_MAX_POSITION; - err = sysfs_create_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC0]); - err |= sysfs_create_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC1]); - err |= sysfs_create_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC2]); - err |= sysfs_create_group(&dev->kobj, &ad525x_group_commands); - break; - default: - err = -ENODEV; - goto exit_free; - } + data->bdata = *bdata; + data->devid = id->devid; + + data->max_pos = 1 << DPOT_MAX_POS(data->devid); + data->rdac_mask = data->max_pos - 1; + data->feat = DPOT_FEAT(data->devid); + data->uid = DPOT_UID(data->devid); + data->wipers = DPOT_WIPERS(data->devid); + + for (i = DPOT_RDAC0; i <= DPOT_RDAC5; i++) + if (data->wipers & (1 << i)) { + err = ad_dpot_add_files(dev, data->feat, i); + if (err) + goto exit_remove_files; + /* power-up midscale */ + if (data->feat & F_RDACS_WONLY) + data->rdac_cache[i] = data->max_pos / 2; + } + + if (data->feat & F_CMD_INC) + err = sysfs_create_group(&dev->kobj, &ad525x_group_commands); if (err) { dev_err(dev, "failed to register sysfs hooks\n"); goto exit_free; } - data->devid = id->driver_data; - data->rdac_mask = data->max_pos - 1; - dev_info(dev, "%s %d-Position Digital Potentiometer registered\n", id->name, data->max_pos); return 0; +exit_remove_files: + for (i = DPOT_RDAC0; i <= DPOT_RDAC5; i++) + if (data->wipers & (1 << i)) + ad_dpot_remove_files(dev, data->feat, i); + exit_free: kfree(data); - i2c_set_clientdata(client, NULL); + dev_set_drvdata(dev, NULL); exit: - dev_err(dev, "failed to create client\n"); + dev_err(dev, "failed to create client for %s ID 0x%lX\n", + id->name, id->devid); return err; } +EXPORT_SYMBOL(ad_dpot_probe); -static int __devexit ad525x_remove(struct i2c_client *client) +__devexit int ad_dpot_remove(struct device *dev) { - struct dpot_data *data = i2c_get_clientdata(client); - struct device *dev = &client->dev; - - switch (data->devid) { - case AD5258_ID: - case AD5259_ID: - sysfs_remove_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC0]); - break; - case AD5251_ID: - case AD5252_ID: - sysfs_remove_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC1]); - sysfs_remove_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC3]); - sysfs_remove_group(&dev->kobj, &ad525x_group_commands); - break; - case AD5253_ID: - case AD5254_ID: - sysfs_remove_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC0]); - sysfs_remove_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC1]); - sysfs_remove_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC2]); - sysfs_remove_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC3]); - sysfs_remove_group(&dev->kobj, &ad525x_group_commands); - break; - case AD5255_ID: - sysfs_remove_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC0]); - sysfs_remove_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC1]); - sysfs_remove_group(&dev->kobj, - &ad525x_group_wipers[AD525X_RDAC2]); - sysfs_remove_group(&dev->kobj, &ad525x_group_commands); - break; - } + struct dpot_data *data = dev_get_drvdata(dev); + int i; + + for (i = DPOT_RDAC0; i <= DPOT_RDAC5; i++) + if (data->wipers & (1 << i)) + ad_dpot_remove_files(dev, data->feat, i); - i2c_set_clientdata(client, NULL); kfree(data); return 0; } +EXPORT_SYMBOL(ad_dpot_remove); -static const struct i2c_device_id ad525x_idtable[] = { - {"ad5258", AD5258_ID}, - {"ad5259", AD5259_ID}, - {"ad5251", AD5251_ID}, - {"ad5252", AD5252_ID}, - {"ad5253", AD5253_ID}, - {"ad5254", AD5254_ID}, - {"ad5255", AD5255_ID}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, ad525x_idtable); - -static struct i2c_driver ad525x_driver = { - .driver = { - .owner = THIS_MODULE, - .name = DRIVER_NAME, - }, - .id_table = ad525x_idtable, - .probe = ad525x_probe, - .remove = __devexit_p(ad525x_remove), -}; - -static int __init ad525x_init(void) -{ - return i2c_add_driver(&ad525x_driver); -} - -module_init(ad525x_init); - -static void __exit ad525x_exit(void) -{ - i2c_del_driver(&ad525x_driver); -} - -module_exit(ad525x_exit); MODULE_AUTHOR("Chris Verges , " - "Michael Hennerich , "); -MODULE_DESCRIPTION("AD5258/9 digital potentiometer driver"); + "Michael Hennerich "); +MODULE_DESCRIPTION("Digital potentiometer driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRIVER_VERSION); diff --git a/drivers/misc/ad525x_dpot.h b/drivers/misc/ad525x_dpot.h new file mode 100644 index 000000000000..99b388e12f5f --- /dev/null +++ b/drivers/misc/ad525x_dpot.h @@ -0,0 +1,173 @@ +/* + * Driver for the Analog Devices digital potentiometers + * + * Copyright (C) 2010 Michael Hennerich, Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef _AD_DPOT_H_ +#define _AD_DPOT_H_ + +#include + +#define DPOT_CONF(features, wipers, max_pos, uid) \ + (((features) << 18) | (((wipers) & 0xFF) << 10) | \ + ((max_pos & 0xF) << 6) | (uid & 0x3F)) + +#define DPOT_UID(conf) (conf & 0x3F) +#define DPOT_MAX_POS(conf) ((conf >> 6) & 0xF) +#define DPOT_WIPERS(conf) ((conf >> 10) & 0xFF) +#define DPOT_FEAT(conf) (conf >> 18) + +#define BRDAC0 (1 << 0) +#define BRDAC1 (1 << 1) +#define BRDAC2 (1 << 2) +#define BRDAC3 (1 << 3) +#define BRDAC4 (1 << 4) +#define BRDAC5 (1 << 5) + +#define F_CMD_INC (1 << 0) /* Features INC/DEC ALL, 6dB */ +#define F_CMD_EEP (1 << 1) /* Features EEPROM */ +#define F_CMD_TOL (1 << 2) /* RDACS are Read/Write + Tolerance REG */ +#define F_RDACS_RW (1 << 3) /* RDACS are Read/Write + Tolerance REG */ +#define F_RDACS_WONLY (1 << 4) /* RDACS are Write only */ +#define F_AD_APPDATA (1 << 5) /* RDAC Address append to data */ +#define F_SPI_8BIT (1 << 6) /* All SPI XFERS are 8-bit */ +#define F_SPI_16BIT (1 << 7) /* All SPI XFERS are 16-bit */ +#define F_SPI_24BIT (1 << 8) /* All SPI XFERS are 24-bit */ + +#define F_RDACS_RW_TOL (F_RDACS_RW | F_CMD_EEP | F_CMD_TOL) +#define F_RDACS_RW_EEP (F_RDACS_RW | F_CMD_EEP) +#define F_SPI (F_SPI_8BIT | F_SPI_16BIT | F_SPI_24BIT) + +enum dpot_devid { + AD5258_ID = DPOT_CONF(F_RDACS_RW_TOL, BRDAC0, 6, 0), /* I2C */ + AD5259_ID = DPOT_CONF(F_RDACS_RW_TOL, BRDAC0, 8, 1), + AD5251_ID = DPOT_CONF(F_RDACS_RW_TOL | F_CMD_INC, + BRDAC0 | BRDAC3, 6, 2), + AD5252_ID = DPOT_CONF(F_RDACS_RW_TOL | F_CMD_INC, + BRDAC0 | BRDAC3, 8, 3), + AD5253_ID = DPOT_CONF(F_RDACS_RW_TOL | F_CMD_INC, + BRDAC0 | BRDAC1 | BRDAC2 | BRDAC3, 6, 4), + AD5254_ID = DPOT_CONF(F_RDACS_RW_TOL | F_CMD_INC, + BRDAC0 | BRDAC1 | BRDAC2 | BRDAC3, 8, 5), + AD5255_ID = DPOT_CONF(F_RDACS_RW_TOL | F_CMD_INC, + BRDAC0 | BRDAC1 | BRDAC2, 9, 6), + AD5160_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT, + BRDAC0, 8, 7), /* SPI */ + AD5161_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT, + BRDAC0, 8, 8), + AD5162_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT, + BRDAC0 | BRDAC1, 8, 9), + AD5165_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT, + BRDAC0, 8, 10), + AD5200_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT, + BRDAC0, 8, 11), + AD5201_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT, + BRDAC0, 5, 12), + AD5203_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT, + BRDAC0 | BRDAC1 | BRDAC2 | BRDAC3, 6, 13), + AD5204_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT, + BRDAC0 | BRDAC1 | BRDAC2 | BRDAC3, 8, 14), + AD5206_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT, + BRDAC0 | BRDAC1 | BRDAC2 | BRDAC3 | BRDAC4 | BRDAC5, + 8, 15), + AD5207_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT, + BRDAC0 | BRDAC1, 8, 16), + AD5231_ID = DPOT_CONF(F_RDACS_RW_EEP | F_CMD_INC | F_SPI_24BIT, + BRDAC0, 10, 17), + AD5232_ID = DPOT_CONF(F_RDACS_RW_EEP | F_CMD_INC | F_SPI_16BIT, + BRDAC0 | BRDAC1, 8, 18), + AD5233_ID = DPOT_CONF(F_RDACS_RW_EEP | F_CMD_INC | F_SPI_16BIT, + BRDAC0 | BRDAC1 | BRDAC2 | BRDAC3, 6, 19), + AD5235_ID = DPOT_CONF(F_RDACS_RW_EEP | F_CMD_INC | F_SPI_24BIT, + BRDAC0 | BRDAC1, 10, 20), + AD5260_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT, + BRDAC0, 8, 21), + AD5262_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT, + BRDAC0 | BRDAC1, 8, 22), + AD5263_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT, + BRDAC0 | BRDAC1 | BRDAC2 | BRDAC3, 8, 23), + AD5290_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT, + BRDAC0, 8, 24), + AD5291_ID = DPOT_CONF(F_RDACS_RW | F_SPI_16BIT, BRDAC0, 8, 25), + AD5292_ID = DPOT_CONF(F_RDACS_RW | F_SPI_16BIT, BRDAC0, 10, 26), + AD5293_ID = DPOT_CONF(F_RDACS_RW | F_SPI_16BIT, BRDAC0, 10, 27), + AD7376_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT, + BRDAC0, 7, 28), + AD8400_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT, + BRDAC0, 8, 29), + AD8402_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT, + BRDAC0 | BRDAC1, 8, 30), + AD8403_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT, + BRDAC0 | BRDAC1 | BRDAC2, 8, 31), + ADN2850_ID = DPOT_CONF(F_RDACS_RW_EEP | F_CMD_INC | F_SPI_24BIT, + BRDAC0 | BRDAC1, 10, 32), +}; + +#define DPOT_RDAC0 0 +#define DPOT_RDAC1 1 +#define DPOT_RDAC2 2 +#define DPOT_RDAC3 3 +#define DPOT_RDAC4 4 +#define DPOT_RDAC5 5 + +#define DPOT_RDAC_MASK 0x1F + +#define DPOT_REG_TOL 0x18 +#define DPOT_TOL_RDAC0 (DPOT_REG_TOL | DPOT_RDAC0) +#define DPOT_TOL_RDAC1 (DPOT_REG_TOL | DPOT_RDAC1) +#define DPOT_TOL_RDAC2 (DPOT_REG_TOL | DPOT_RDAC2) +#define DPOT_TOL_RDAC3 (DPOT_REG_TOL | DPOT_RDAC3) +#define DPOT_TOL_RDAC4 (DPOT_REG_TOL | DPOT_RDAC4) +#define DPOT_TOL_RDAC5 (DPOT_REG_TOL | DPOT_RDAC5) + +/* RDAC-to-EEPROM Interface Commands */ +#define DPOT_ADDR_RDAC (0x00 << 5) +#define DPOT_ADDR_EEPROM (0x01 << 5) +#define DPOT_ADDR_CMD (0x80) + +#define DPOT_DEC_ALL_6DB (DPOT_ADDR_CMD | (0x4 << 3)) +#define DPOT_INC_ALL_6DB (DPOT_ADDR_CMD | (0x9 << 3)) +#define DPOT_DEC_ALL (DPOT_ADDR_CMD | (0x6 << 3)) +#define DPOT_INC_ALL (DPOT_ADDR_CMD | (0xB << 3)) + +#define DPOT_SPI_RDAC 0xB0 +#define DPOT_SPI_EEPROM 0x30 +#define DPOT_SPI_READ_RDAC 0xA0 +#define DPOT_SPI_READ_EEPROM 0x90 +#define DPOT_SPI_DEC_ALL_6DB 0x50 +#define DPOT_SPI_INC_ALL_6DB 0xD0 +#define DPOT_SPI_DEC_ALL 0x70 +#define DPOT_SPI_INC_ALL 0xF0 + +/* AD5291/2/3 use special commands */ +#define DPOT_AD5291_RDAC 0x01 +#define DPOT_AD5291_READ_RDAC 0x02 + +struct dpot_data; + +struct ad_dpot_bus_ops { + int (*read_d8) (void *client); + int (*read_r8d8) (void *client, u8 reg); + int (*read_r8d16) (void *client, u8 reg); + int (*write_d8) (void *client, u8 val); + int (*write_r8d8) (void *client, u8 reg, u8 val); + int (*write_r8d16) (void *client, u8 reg, u16 val); +}; + +struct ad_dpot_bus_data { + void *client; + const struct ad_dpot_bus_ops *bops; +}; + +struct ad_dpot_id { + char *name; + unsigned long devid; +}; + +int ad_dpot_probe(struct device *dev, struct ad_dpot_bus_data *bdata, const struct ad_dpot_id *id); +int ad_dpot_remove(struct device *dev); + +#endif -- cgit v1.2.3 From e3ae68476ce0636554b5d95a33777f80ba407dc0 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 24 May 2010 14:33:15 -0700 Subject: ad525x_dpot: add support for AD524x pots New parts supported: AD5241, AD5242, AD5243, AD5245, AD5246, AD5247, AD5248 Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/Kconfig | 3 +- drivers/misc/ad525x_dpot-i2c.c | 7 ++ drivers/misc/ad525x_dpot.c | 234 +++++++++++++++++++++++++---------------- drivers/misc/ad525x_dpot.h | 27 +++-- 4 files changed, 175 insertions(+), 96 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 69e019e7d69c..90c3415dc90a 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -22,7 +22,8 @@ config AD525X_DPOT AD5160, AD5161, AD5162, AD5165, AD5200, AD5201, AD5203, AD5204, AD5206, AD5207, AD5231, AD5232, AD5233, AD5235, AD5260, AD5262, AD5263, AD5290, AD5291, AD5292, AD5293, - AD7376, AD8400, AD8402, AD8403, ADN2850 + AD7376, AD8400, AD8402, AD8403, ADN2850, AD5241, AD5242, + AD5243, AD5245, AD5246, AD5247, AD5248 digital potentiometer chips. See Documentation/misc-devices/ad525x_dpot.txt for the diff --git a/drivers/misc/ad525x_dpot-i2c.c b/drivers/misc/ad525x_dpot-i2c.c index 971e61d7f881..0dfad4e70f74 100644 --- a/drivers/misc/ad525x_dpot-i2c.c +++ b/drivers/misc/ad525x_dpot-i2c.c @@ -87,6 +87,13 @@ static const struct i2c_device_id ad_dpot_id[] = { {"ad5253", AD5253_ID}, {"ad5254", AD5254_ID}, {"ad5255", AD5255_ID}, + {"ad5241", AD5241_ID}, + {"ad5242", AD5242_ID}, + {"ad5243", AD5243_ID}, + {"ad5245", AD5245_ID}, + {"ad5246", AD5246_ID}, + {"ad5247", AD5247_ID}, + {"ad5248", AD5248_ID}, {} }; MODULE_DEVICE_TABLE(i2c, ad_dpot_id); diff --git a/drivers/misc/ad525x_dpot.c b/drivers/misc/ad525x_dpot.c index a41c2de0eae8..35a4c4b343d4 100644 --- a/drivers/misc/ad525x_dpot.c +++ b/drivers/misc/ad525x_dpot.c @@ -37,6 +37,13 @@ * AD8402 2 256 1, 10, 50, 100 * AD8403 4 256 1, 10, 50, 100 * ADN2850 3 512 25, 250 + * AD5241 1 256 10, 100, 1M + * AD5246 1 128 5, 10, 50, 100 + * AD5247 1 128 5, 10, 50, 100 + * AD5245 1 256 5, 10, 50, 100 + * AD5243 2 256 2.5, 10, 50, 100 + * AD5248 2 256 2.5, 10, 50, 100 + * AD5242 2 256 20, 50, 200 * * See Documentation/misc-devices/ad525x_dpot.txt for more info. * @@ -107,118 +114,169 @@ static inline int dpot_write_r8d16(struct dpot_data *dpot, u8 reg, u16 val) return dpot->bdata.bops->write_r8d16(dpot->bdata.client, reg, val); } -static s32 dpot_read(struct dpot_data *dpot, u8 reg) +static s32 dpot_read_spi(struct dpot_data *dpot, u8 reg) { - unsigned val = 0; + unsigned ctrl = 0; - if (dpot->feat & F_SPI) { - if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD))) { + if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD))) { - if (dpot->feat & F_RDACS_WONLY) - return dpot->rdac_cache[reg & DPOT_RDAC_MASK]; + if (dpot->feat & F_RDACS_WONLY) + return dpot->rdac_cache[reg & DPOT_RDAC_MASK]; - if (dpot->uid == DPOT_UID(AD5291_ID) || - dpot->uid == DPOT_UID(AD5292_ID) || - dpot->uid == DPOT_UID(AD5293_ID)) - return dpot_read_r8d8(dpot, - DPOT_AD5291_READ_RDAC << 2); + if (dpot->uid == DPOT_UID(AD5291_ID) || + dpot->uid == DPOT_UID(AD5292_ID) || + dpot->uid == DPOT_UID(AD5293_ID)) + return dpot_read_r8d8(dpot, + DPOT_AD5291_READ_RDAC << 2); - val = DPOT_SPI_READ_RDAC; - } else if (reg & DPOT_ADDR_EEPROM) { - val = DPOT_SPI_READ_EEPROM; - } + ctrl = DPOT_SPI_READ_RDAC; + } else if (reg & DPOT_ADDR_EEPROM) { + ctrl = DPOT_SPI_READ_EEPROM; + } - if (dpot->feat & F_SPI_16BIT) - return dpot_read_r8d8(dpot, val); - else if (dpot->feat & F_SPI_24BIT) - return dpot_read_r8d16(dpot, val); + if (dpot->feat & F_SPI_16BIT) + return dpot_read_r8d8(dpot, ctrl); + else if (dpot->feat & F_SPI_24BIT) + return dpot_read_r8d16(dpot, ctrl); - } else { /* I2C */ + return -EFAULT; +} +static s32 dpot_read_i2c(struct dpot_data *dpot, u8 reg) +{ + unsigned ctrl = 0; + switch (dpot->uid) { + case DPOT_UID(AD5246_ID): + case DPOT_UID(AD5247_ID): + return dpot_read_d8(dpot); + case DPOT_UID(AD5245_ID): + case DPOT_UID(AD5241_ID): + case DPOT_UID(AD5242_ID): + case DPOT_UID(AD5243_ID): + case DPOT_UID(AD5248_ID): + ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ? + 0 : DPOT_AD5291_RDAC_AB; + return dpot_read_r8d8(dpot, ctrl); + default: if ((reg & DPOT_REG_TOL) || (dpot->max_pos > 256)) return dpot_read_r8d16(dpot, (reg & 0xF8) | ((reg & 0x7) << 1)); else return dpot_read_r8d8(dpot, reg); - } - return -EFAULT; } -static s32 dpot_write(struct dpot_data *dpot, u8 reg, u16 value) +static s32 dpot_read(struct dpot_data *dpot, u8 reg) +{ + if (dpot->feat & F_SPI) + return dpot_read_spi(dpot, reg); + else + return dpot_read_i2c(dpot, reg); +} + +static s32 dpot_write_spi(struct dpot_data *dpot, u8 reg, u16 value) { unsigned val = 0; - if (dpot->feat & F_SPI) { - if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD))) { - if (dpot->feat & F_RDACS_WONLY) - dpot->rdac_cache[reg & DPOT_RDAC_MASK] = value; - - if (dpot->feat & F_AD_APPDATA) { - if (dpot->feat & F_SPI_8BIT) { - val = ((reg & DPOT_RDAC_MASK) << - DPOT_MAX_POS(dpot->devid)) | - value; - return dpot_write_d8(dpot, val); - } else if (dpot->feat & F_SPI_16BIT) { - val = ((reg & DPOT_RDAC_MASK) << - DPOT_MAX_POS(dpot->devid)) | - value; - return dpot_write_r8d8(dpot, val >> 8, - val & 0xFF); - } else - BUG(); - } else { - if (dpot->uid == DPOT_UID(AD5291_ID) || - dpot->uid == DPOT_UID(AD5292_ID) || - dpot->uid == DPOT_UID(AD5293_ID)) - return dpot_write_r8d8(dpot, - (DPOT_AD5291_RDAC << 2) | - (value >> 8), value & 0xFF); - - val = DPOT_SPI_RDAC | (reg & DPOT_RDAC_MASK); - } - } else if (reg & DPOT_ADDR_EEPROM) { - val = DPOT_SPI_EEPROM | (reg & DPOT_RDAC_MASK); - } else if (reg & DPOT_ADDR_CMD) { - switch (reg) { - case DPOT_DEC_ALL_6DB: - val = DPOT_SPI_DEC_ALL_6DB; - break; - case DPOT_INC_ALL_6DB: - val = DPOT_SPI_INC_ALL_6DB; - break; - case DPOT_DEC_ALL: - val = DPOT_SPI_DEC_ALL; - break; - case DPOT_INC_ALL: - val = DPOT_SPI_INC_ALL; - break; - } - } else - BUG(); - - if (dpot->feat & F_SPI_16BIT) - return dpot_write_r8d8(dpot, val, value); - else if (dpot->feat & F_SPI_24BIT) - return dpot_write_r8d16(dpot, val, value); - } else { - /* Only write the instruction byte for certain commands */ - if (reg & DPOT_ADDR_CMD) - return dpot_write_d8(dpot, reg); - - if (dpot->max_pos > 256) - return dpot_write_r8d16(dpot, (reg & 0xF8) | - ((reg & 0x7) << 1), value); - else - /* All other registers require instruction + data bytes */ - return dpot_write_r8d8(dpot, reg, value); + if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD))) { + if (dpot->feat & F_RDACS_WONLY) + dpot->rdac_cache[reg & DPOT_RDAC_MASK] = value; + + if (dpot->feat & F_AD_APPDATA) { + if (dpot->feat & F_SPI_8BIT) { + val = ((reg & DPOT_RDAC_MASK) << + DPOT_MAX_POS(dpot->devid)) | + value; + return dpot_write_d8(dpot, val); + } else if (dpot->feat & F_SPI_16BIT) { + val = ((reg & DPOT_RDAC_MASK) << + DPOT_MAX_POS(dpot->devid)) | + value; + return dpot_write_r8d8(dpot, val >> 8, + val & 0xFF); + } else + BUG(); + } else { + if (dpot->uid == DPOT_UID(AD5291_ID) || + dpot->uid == DPOT_UID(AD5292_ID) || + dpot->uid == DPOT_UID(AD5293_ID)) + return dpot_write_r8d8(dpot, + (DPOT_AD5291_RDAC << 2) | + (value >> 8), value & 0xFF); - } + val = DPOT_SPI_RDAC | (reg & DPOT_RDAC_MASK); + } + } else if (reg & DPOT_ADDR_EEPROM) { + val = DPOT_SPI_EEPROM | (reg & DPOT_RDAC_MASK); + } else if (reg & DPOT_ADDR_CMD) { + switch (reg) { + case DPOT_DEC_ALL_6DB: + val = DPOT_SPI_DEC_ALL_6DB; + break; + case DPOT_INC_ALL_6DB: + val = DPOT_SPI_INC_ALL_6DB; + break; + case DPOT_DEC_ALL: + val = DPOT_SPI_DEC_ALL; + break; + case DPOT_INC_ALL: + val = DPOT_SPI_INC_ALL; + break; + } + } else + BUG(); + + if (dpot->feat & F_SPI_16BIT) + return dpot_write_r8d8(dpot, val, value); + else if (dpot->feat & F_SPI_24BIT) + return dpot_write_r8d16(dpot, val, value); return -EFAULT; } +static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value) +{ + /* Only write the instruction byte for certain commands */ + unsigned ctrl = 0; + + switch (dpot->uid) { + case DPOT_UID(AD5246_ID): + case DPOT_UID(AD5247_ID): + return dpot_write_d8(dpot, value); + break; + + case DPOT_UID(AD5245_ID): + case DPOT_UID(AD5241_ID): + case DPOT_UID(AD5242_ID): + case DPOT_UID(AD5243_ID): + case DPOT_UID(AD5248_ID): + ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ? 0 : DPOT_AD5291_RDAC_AB; + return dpot_write_r8d8(dpot, ctrl, value); + break; + + + default: + if (reg & DPOT_ADDR_CMD) + return dpot_write_d8(dpot, reg); + + if (dpot->max_pos > 256) + return dpot_write_r8d16(dpot, (reg & 0xF8) | + ((reg & 0x7) << 1), value); + else + /* All other registers require instruction + data bytes */ + return dpot_write_r8d8(dpot, reg, value); + } +} + + +static s32 dpot_write(struct dpot_data *dpot, u8 reg, u16 value) +{ + if (dpot->feat & F_SPI) + return dpot_write_spi(dpot, reg, value); + else + return dpot_write_i2c(dpot, reg, value); +} + /* sysfs functions */ static ssize_t sysfs_show_reg(struct device *dev, diff --git a/drivers/misc/ad525x_dpot.h b/drivers/misc/ad525x_dpot.h index 99b388e12f5f..849c5d0782b2 100644 --- a/drivers/misc/ad525x_dpot.h +++ b/drivers/misc/ad525x_dpot.h @@ -29,13 +29,14 @@ #define F_CMD_INC (1 << 0) /* Features INC/DEC ALL, 6dB */ #define F_CMD_EEP (1 << 1) /* Features EEPROM */ -#define F_CMD_TOL (1 << 2) /* RDACS are Read/Write + Tolerance REG */ -#define F_RDACS_RW (1 << 3) /* RDACS are Read/Write + Tolerance REG */ -#define F_RDACS_WONLY (1 << 4) /* RDACS are Write only */ -#define F_AD_APPDATA (1 << 5) /* RDAC Address append to data */ -#define F_SPI_8BIT (1 << 6) /* All SPI XFERS are 8-bit */ -#define F_SPI_16BIT (1 << 7) /* All SPI XFERS are 16-bit */ -#define F_SPI_24BIT (1 << 8) /* All SPI XFERS are 24-bit */ +#define F_CMD_OTP (1 << 2) /* Features OTP */ +#define F_CMD_TOL (1 << 3) /* RDACS feature Tolerance REG */ +#define F_RDACS_RW (1 << 4) /* RDACS are Read/Write */ +#define F_RDACS_WONLY (1 << 5) /* RDACS are Write only */ +#define F_AD_APPDATA (1 << 6) /* RDAC Address append to data */ +#define F_SPI_8BIT (1 << 7) /* All SPI XFERS are 8-bit */ +#define F_SPI_16BIT (1 << 8) /* All SPI XFERS are 16-bit */ +#define F_SPI_24BIT (1 << 9) /* All SPI XFERS are 24-bit */ #define F_RDACS_RW_TOL (F_RDACS_RW | F_CMD_EEP | F_CMD_TOL) #define F_RDACS_RW_EEP (F_RDACS_RW | F_CMD_EEP) @@ -104,6 +105,15 @@ enum dpot_devid { BRDAC0 | BRDAC1 | BRDAC2, 8, 31), ADN2850_ID = DPOT_CONF(F_RDACS_RW_EEP | F_CMD_INC | F_SPI_24BIT, BRDAC0 | BRDAC1, 10, 32), + AD5241_ID = DPOT_CONF(F_RDACS_RW, BRDAC0, 8, 33), + AD5242_ID = DPOT_CONF(F_RDACS_RW, BRDAC0 | BRDAC1, 8, 34), + AD5243_ID = DPOT_CONF(F_RDACS_RW, BRDAC0 | BRDAC1, 8, 35), + AD5245_ID = DPOT_CONF(F_RDACS_RW, BRDAC0, 8, 36), + AD5246_ID = DPOT_CONF(F_RDACS_RW, BRDAC0, 7, 37), + AD5247_ID = DPOT_CONF(F_RDACS_RW, BRDAC0, 7, 38), + AD5248_ID = DPOT_CONF(F_RDACS_RW, BRDAC0 | BRDAC1, 8, 39), + + }; #define DPOT_RDAC0 0 @@ -146,6 +156,9 @@ enum dpot_devid { #define DPOT_AD5291_RDAC 0x01 #define DPOT_AD5291_READ_RDAC 0x02 +/* AD524x use special commands */ +#define DPOT_AD5291_RDAC_AB 0x80 + struct dpot_data; struct ad_dpot_bus_ops { -- cgit v1.2.3 From c74cba610c9559e72377fd9725a3d329581aa256 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 24 May 2010 14:33:15 -0700 Subject: ad525x_dpot: add support for ADN2860 and AD528x pots New parts supported: AD5280, AD5282, ADN2860 Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/Kconfig | 3 ++- drivers/misc/ad525x_dpot-i2c.c | 3 +++ drivers/misc/ad525x_dpot.c | 28 +++++++++++++++++----------- drivers/misc/ad525x_dpot.h | 6 ++++-- 4 files changed, 26 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 90c3415dc90a..233886d00861 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -23,7 +23,8 @@ config AD525X_DPOT AD5204, AD5206, AD5207, AD5231, AD5232, AD5233, AD5235, AD5260, AD5262, AD5263, AD5290, AD5291, AD5292, AD5293, AD7376, AD8400, AD8402, AD8403, ADN2850, AD5241, AD5242, - AD5243, AD5245, AD5246, AD5247, AD5248 + AD5243, AD5245, AD5246, AD5247, AD5248, AD5280, AD5282, + ADN2860 digital potentiometer chips. See Documentation/misc-devices/ad525x_dpot.txt for the diff --git a/drivers/misc/ad525x_dpot-i2c.c b/drivers/misc/ad525x_dpot-i2c.c index 0dfad4e70f74..abba18efdde3 100644 --- a/drivers/misc/ad525x_dpot-i2c.c +++ b/drivers/misc/ad525x_dpot-i2c.c @@ -94,6 +94,9 @@ static const struct i2c_device_id ad_dpot_id[] = { {"ad5246", AD5246_ID}, {"ad5247", AD5247_ID}, {"ad5248", AD5248_ID}, + {"ad5280", AD5280_ID}, + {"ad5282", AD5282_ID}, + {"adn2860", ADN2860_ID}, {} }; MODULE_DEVICE_TABLE(i2c, ad_dpot_id); diff --git a/drivers/misc/ad525x_dpot.c b/drivers/misc/ad525x_dpot.c index 35a4c4b343d4..255ba4b5e355 100644 --- a/drivers/misc/ad525x_dpot.c +++ b/drivers/misc/ad525x_dpot.c @@ -44,6 +44,9 @@ * AD5243 2 256 2.5, 10, 50, 100 * AD5248 2 256 2.5, 10, 50, 100 * AD5242 2 256 20, 50, 200 + * AD5280 1 256 20, 50, 200 + * AD5282 2 256 20, 50, 200 + * ADN2860 3 512 25, 250 * * See Documentation/misc-devices/ad525x_dpot.txt for more info. * @@ -154,6 +157,8 @@ static s32 dpot_read_i2c(struct dpot_data *dpot, u8 reg) case DPOT_UID(AD5242_ID): case DPOT_UID(AD5243_ID): case DPOT_UID(AD5248_ID): + case DPOT_UID(AD5280_ID): + case DPOT_UID(AD5282_ID): ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ? 0 : DPOT_AD5291_RDAC_AB; return dpot_read_r8d8(dpot, ctrl); @@ -250,21 +255,22 @@ static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value) case DPOT_UID(AD5242_ID): case DPOT_UID(AD5243_ID): case DPOT_UID(AD5248_ID): - ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ? 0 : DPOT_AD5291_RDAC_AB; + case DPOT_UID(AD5280_ID): + case DPOT_UID(AD5282_ID): + ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ? + 0 : DPOT_AD5291_RDAC_AB; return dpot_write_r8d8(dpot, ctrl, value); break; - - default: - if (reg & DPOT_ADDR_CMD) - return dpot_write_d8(dpot, reg); + if (reg & DPOT_ADDR_CMD) + return dpot_write_d8(dpot, reg); - if (dpot->max_pos > 256) - return dpot_write_r8d16(dpot, (reg & 0xF8) | - ((reg & 0x7) << 1), value); - else - /* All other registers require instruction + data bytes */ - return dpot_write_r8d8(dpot, reg, value); + if (dpot->max_pos > 256) + return dpot_write_r8d16(dpot, (reg & 0xF8) | + ((reg & 0x7) << 1), value); + else + /* All other registers require instruction + data bytes */ + return dpot_write_r8d8(dpot, reg, value); } } diff --git a/drivers/misc/ad525x_dpot.h b/drivers/misc/ad525x_dpot.h index 849c5d0782b2..d789a95cbe09 100644 --- a/drivers/misc/ad525x_dpot.h +++ b/drivers/misc/ad525x_dpot.h @@ -112,8 +112,10 @@ enum dpot_devid { AD5246_ID = DPOT_CONF(F_RDACS_RW, BRDAC0, 7, 37), AD5247_ID = DPOT_CONF(F_RDACS_RW, BRDAC0, 7, 38), AD5248_ID = DPOT_CONF(F_RDACS_RW, BRDAC0 | BRDAC1, 8, 39), - - + AD5280_ID = DPOT_CONF(F_RDACS_RW, BRDAC0, 8, 40), + AD5282_ID = DPOT_CONF(F_RDACS_RW, BRDAC0 | BRDAC1, 8, 41), + ADN2860_ID = DPOT_CONF(F_RDACS_RW_TOL | F_CMD_INC, + BRDAC0 | BRDAC1 | BRDAC2, 9, 42), }; #define DPOT_RDAC0 0 -- cgit v1.2.3 From 59592d0ccc0000d74ea5fc2a59e3ec0c9ef1fb13 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 24 May 2010 14:33:16 -0700 Subject: ad525x_dpot: add support for one time programmable pots New parts supported: AD5170, AD5171, AD5172, AD5173, AD5273 Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/Kconfig | 2 +- drivers/misc/ad525x_dpot-i2c.c | 5 ++ drivers/misc/ad525x_dpot.c | 121 +++++++++++++++++++++++++++++++++++++++-- drivers/misc/ad525x_dpot.h | 42 +++++++++----- 4 files changed, 150 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 233886d00861..26386a92f5aa 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -24,7 +24,7 @@ config AD525X_DPOT AD5260, AD5262, AD5263, AD5290, AD5291, AD5292, AD5293, AD7376, AD8400, AD8402, AD8403, ADN2850, AD5241, AD5242, AD5243, AD5245, AD5246, AD5247, AD5248, AD5280, AD5282, - ADN2860 + ADN2860, AD5273, AD5171, AD5170, AD5172, AD5173 digital potentiometer chips. See Documentation/misc-devices/ad525x_dpot.txt for the diff --git a/drivers/misc/ad525x_dpot-i2c.c b/drivers/misc/ad525x_dpot-i2c.c index abba18efdde3..374352af7979 100644 --- a/drivers/misc/ad525x_dpot-i2c.c +++ b/drivers/misc/ad525x_dpot-i2c.c @@ -97,6 +97,11 @@ static const struct i2c_device_id ad_dpot_id[] = { {"ad5280", AD5280_ID}, {"ad5282", AD5282_ID}, {"adn2860", ADN2860_ID}, + {"ad5273", AD5273_ID}, + {"ad5171", AD5171_ID}, + {"ad5170", AD5170_ID}, + {"ad5172", AD5172_ID}, + {"ad5173", AD5173_ID}, {} }; MODULE_DEVICE_TABLE(i2c, ad_dpot_id); diff --git a/drivers/misc/ad525x_dpot.c b/drivers/misc/ad525x_dpot.c index 255ba4b5e355..5e6fa8449e8b 100644 --- a/drivers/misc/ad525x_dpot.c +++ b/drivers/misc/ad525x_dpot.c @@ -47,6 +47,11 @@ * AD5280 1 256 20, 50, 200 * AD5282 2 256 20, 50, 200 * ADN2860 3 512 25, 250 + * AD5273 1 64 1, 10, 50, 100 (OTP) + * AD5171 1 64 5, 10, 50, 100 (OTP) + * AD5170 1 256 2.5, 10, 50, 100 (OTP) + * AD5172 2 256 2.5, 10, 50, 100 (OTP) + * AD5173 2 256 2.5, 10, 50, 100 (OTP) * * See Documentation/misc-devices/ad525x_dpot.txt for more info. * @@ -84,7 +89,8 @@ struct dpot_data { unsigned uid; unsigned feat; unsigned wipers; - u16 rdac_cache[8]; + u16 rdac_cache[MAX_RDACS]; + DECLARE_BITMAP(otp_en_mask, MAX_RDACS); }; static inline int dpot_read_d8(struct dpot_data *dpot) @@ -162,6 +168,15 @@ static s32 dpot_read_i2c(struct dpot_data *dpot, u8 reg) ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ? 0 : DPOT_AD5291_RDAC_AB; return dpot_read_r8d8(dpot, ctrl); + case DPOT_UID(AD5170_ID): + case DPOT_UID(AD5171_ID): + case DPOT_UID(AD5273_ID): + return dpot_read_d8(dpot); + case DPOT_UID(AD5172_ID): + case DPOT_UID(AD5173_ID): + ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ? + 0 : DPOT_AD5272_3_A0; + return dpot_read_r8d8(dpot, ctrl); default: if ((reg & DPOT_REG_TOL) || (dpot->max_pos > 256)) return dpot_read_r8d16(dpot, (reg & 0xF8) | @@ -242,7 +257,7 @@ static s32 dpot_write_spi(struct dpot_data *dpot, u8 reg, u16 value) static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value) { /* Only write the instruction byte for certain commands */ - unsigned ctrl = 0; + unsigned tmp = 0, ctrl = 0; switch (dpot->uid) { case DPOT_UID(AD5246_ID): @@ -261,6 +276,37 @@ static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value) 0 : DPOT_AD5291_RDAC_AB; return dpot_write_r8d8(dpot, ctrl, value); break; + case DPOT_UID(AD5171_ID): + case DPOT_UID(AD5273_ID): + if (reg & DPOT_ADDR_OTP) { + tmp = dpot_read_d8(dpot); + if (tmp >> 6) /* Ready to Program? */ + return -EFAULT; + ctrl = DPOT_AD5273_FUSE; + } + return dpot_write_r8d8(dpot, ctrl, value); + break; + case DPOT_UID(AD5172_ID): + case DPOT_UID(AD5173_ID): + ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ? + 0 : DPOT_AD5272_3_A0; + if (reg & DPOT_ADDR_OTP) { + tmp = dpot_read_r8d16(dpot, ctrl); + if (tmp >> 14) /* Ready to Program? */ + return -EFAULT; + ctrl |= DPOT_AD5270_2_3_FUSE; + } + return dpot_write_r8d8(dpot, ctrl, value); + break; + case DPOT_UID(AD5170_ID): + if (reg & DPOT_ADDR_OTP) { + tmp = dpot_read_r8d16(dpot, tmp); + if (tmp >> 14) /* Ready to Program? */ + return -EFAULT; + ctrl = DPOT_AD5270_2_3_FUSE; + } + return dpot_write_r8d8(dpot, ctrl, value); + break; default: if (reg & DPOT_ADDR_CMD) return dpot_write_d8(dpot, reg); @@ -292,6 +338,12 @@ static ssize_t sysfs_show_reg(struct device *dev, struct dpot_data *data = dev_get_drvdata(dev); s32 value; + if (reg & DPOT_ADDR_OTP_EN) + return sprintf(buf, "%s\n", + test_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask) ? + "enabled" : "disabled"); + + mutex_lock(&data->update_lock); value = dpot_read(data, reg); mutex_unlock(&data->update_lock); @@ -320,6 +372,19 @@ static ssize_t sysfs_set_reg(struct device *dev, unsigned long value; int err; + if (reg & DPOT_ADDR_OTP_EN) { + if (!strncmp(buf, "enabled", sizeof("enabled"))) + set_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask); + else + clear_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask); + + return count; + } + + if ((reg & DPOT_ADDR_OTP) && + !test_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask)) + return -EPERM; + err = strict_strtoul(buf, 10, &value); if (err) return err; @@ -331,6 +396,8 @@ static ssize_t sysfs_set_reg(struct device *dev, dpot_write(data, reg, value); if (reg & DPOT_ADDR_EEPROM) msleep(26); /* Sleep while the EEPROM updates */ + else if (reg & DPOT_ADDR_OTP) + msleep(400); /* Sleep while the OTP updates */ mutex_unlock(&data->update_lock); return count; @@ -378,26 +445,38 @@ static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, NULL); DPOT_DEVICE_SHOW_SET(rdac0, DPOT_ADDR_RDAC | DPOT_RDAC0); DPOT_DEVICE_SHOW_SET(eeprom0, DPOT_ADDR_EEPROM | DPOT_RDAC0); DPOT_DEVICE_SHOW_ONLY(tolerance0, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC0); +DPOT_DEVICE_SHOW_SET(otp0, DPOT_ADDR_OTP | DPOT_RDAC0); +DPOT_DEVICE_SHOW_SET(otp0en, DPOT_ADDR_OTP_EN | DPOT_RDAC0); DPOT_DEVICE_SHOW_SET(rdac1, DPOT_ADDR_RDAC | DPOT_RDAC1); DPOT_DEVICE_SHOW_SET(eeprom1, DPOT_ADDR_EEPROM | DPOT_RDAC1); DPOT_DEVICE_SHOW_ONLY(tolerance1, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC1); +DPOT_DEVICE_SHOW_SET(otp1, DPOT_ADDR_OTP | DPOT_RDAC1); +DPOT_DEVICE_SHOW_SET(otp1en, DPOT_ADDR_OTP_EN | DPOT_RDAC1); DPOT_DEVICE_SHOW_SET(rdac2, DPOT_ADDR_RDAC | DPOT_RDAC2); DPOT_DEVICE_SHOW_SET(eeprom2, DPOT_ADDR_EEPROM | DPOT_RDAC2); DPOT_DEVICE_SHOW_ONLY(tolerance2, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC2); +DPOT_DEVICE_SHOW_SET(otp2, DPOT_ADDR_OTP | DPOT_RDAC2); +DPOT_DEVICE_SHOW_SET(otp2en, DPOT_ADDR_OTP_EN | DPOT_RDAC2); DPOT_DEVICE_SHOW_SET(rdac3, DPOT_ADDR_RDAC | DPOT_RDAC3); DPOT_DEVICE_SHOW_SET(eeprom3, DPOT_ADDR_EEPROM | DPOT_RDAC3); DPOT_DEVICE_SHOW_ONLY(tolerance3, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC3); +DPOT_DEVICE_SHOW_SET(otp3, DPOT_ADDR_OTP | DPOT_RDAC3); +DPOT_DEVICE_SHOW_SET(otp3en, DPOT_ADDR_OTP_EN | DPOT_RDAC3); DPOT_DEVICE_SHOW_SET(rdac4, DPOT_ADDR_RDAC | DPOT_RDAC4); DPOT_DEVICE_SHOW_SET(eeprom4, DPOT_ADDR_EEPROM | DPOT_RDAC4); DPOT_DEVICE_SHOW_ONLY(tolerance4, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC4); +DPOT_DEVICE_SHOW_SET(otp4, DPOT_ADDR_OTP | DPOT_RDAC4); +DPOT_DEVICE_SHOW_SET(otp4en, DPOT_ADDR_OTP_EN | DPOT_RDAC4); DPOT_DEVICE_SHOW_SET(rdac5, DPOT_ADDR_RDAC | DPOT_RDAC5); DPOT_DEVICE_SHOW_SET(eeprom5, DPOT_ADDR_EEPROM | DPOT_RDAC5); DPOT_DEVICE_SHOW_ONLY(tolerance5, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC5); +DPOT_DEVICE_SHOW_SET(otp5, DPOT_ADDR_OTP | DPOT_RDAC5); +DPOT_DEVICE_SHOW_SET(otp5en, DPOT_ADDR_OTP_EN | DPOT_RDAC5); static const struct attribute *dpot_attrib_wipers[] = { &dev_attr_rdac0.attr, @@ -419,6 +498,26 @@ static const struct attribute *dpot_attrib_eeprom[] = { NULL }; +static const struct attribute *dpot_attrib_otp[] = { + &dev_attr_otp0.attr, + &dev_attr_otp1.attr, + &dev_attr_otp2.attr, + &dev_attr_otp3.attr, + &dev_attr_otp4.attr, + &dev_attr_otp5.attr, + NULL +}; + +static const struct attribute *dpot_attrib_otp_en[] = { + &dev_attr_otp0en.attr, + &dev_attr_otp1en.attr, + &dev_attr_otp2en.attr, + &dev_attr_otp3en.attr, + &dev_attr_otp4en.attr, + &dev_attr_otp5en.attr, + NULL +}; + static const struct attribute *dpot_attrib_tolerance[] = { &dev_attr_tolerance0.attr, &dev_attr_tolerance1.attr, @@ -468,6 +567,12 @@ __devinit int ad_dpot_add_files(struct device *dev, if (features & F_CMD_TOL) err |= sysfs_create_file(&dev->kobj, dpot_attrib_tolerance[rdac]); + if (features & F_CMD_OTP) { + err |= sysfs_create_file(&dev->kobj, + dpot_attrib_otp_en[rdac]); + err |= sysfs_create_file(&dev->kobj, + dpot_attrib_otp[rdac]); + } if (err) dev_err(dev, "failed to register sysfs hooks for RDAC%d\n", @@ -487,6 +592,12 @@ inline void ad_dpot_remove_files(struct device *dev, if (features & F_CMD_TOL) sysfs_remove_file(&dev->kobj, dpot_attrib_tolerance[rdac]); + if (features & F_CMD_OTP) { + sysfs_remove_file(&dev->kobj, + dpot_attrib_otp_en[rdac]); + sysfs_remove_file(&dev->kobj, + dpot_attrib_otp[rdac]); + } } __devinit int ad_dpot_probe(struct device *dev, @@ -514,7 +625,7 @@ __devinit int ad_dpot_probe(struct device *dev, data->uid = DPOT_UID(data->devid); data->wipers = DPOT_WIPERS(data->devid); - for (i = DPOT_RDAC0; i <= DPOT_RDAC5; i++) + for (i = DPOT_RDAC0; i < MAX_RDACS; i++) if (data->wipers & (1 << i)) { err = ad_dpot_add_files(dev, data->feat, i); if (err) @@ -538,7 +649,7 @@ __devinit int ad_dpot_probe(struct device *dev, return 0; exit_remove_files: - for (i = DPOT_RDAC0; i <= DPOT_RDAC5; i++) + for (i = DPOT_RDAC0; i < MAX_RDACS; i++) if (data->wipers & (1 << i)) ad_dpot_remove_files(dev, data->feat, i); @@ -557,7 +668,7 @@ __devexit int ad_dpot_remove(struct device *dev) struct dpot_data *data = dev_get_drvdata(dev); int i; - for (i = DPOT_RDAC0; i <= DPOT_RDAC5; i++) + for (i = DPOT_RDAC0; i < MAX_RDACS; i++) if (data->wipers & (1 << i)) ad_dpot_remove_files(dev, data->feat, i); diff --git a/drivers/misc/ad525x_dpot.h b/drivers/misc/ad525x_dpot.h index d789a95cbe09..78b89fd2e2fd 100644 --- a/drivers/misc/ad525x_dpot.h +++ b/drivers/misc/ad525x_dpot.h @@ -15,17 +15,18 @@ (((features) << 18) | (((wipers) & 0xFF) << 10) | \ ((max_pos & 0xF) << 6) | (uid & 0x3F)) -#define DPOT_UID(conf) (conf & 0x3F) -#define DPOT_MAX_POS(conf) ((conf >> 6) & 0xF) -#define DPOT_WIPERS(conf) ((conf >> 10) & 0xFF) -#define DPOT_FEAT(conf) (conf >> 18) - -#define BRDAC0 (1 << 0) -#define BRDAC1 (1 << 1) -#define BRDAC2 (1 << 2) -#define BRDAC3 (1 << 3) -#define BRDAC4 (1 << 4) -#define BRDAC5 (1 << 5) +#define DPOT_UID(conf) (conf & 0x3F) +#define DPOT_MAX_POS(conf) ((conf >> 6) & 0xF) +#define DPOT_WIPERS(conf) ((conf >> 10) & 0xFF) +#define DPOT_FEAT(conf) (conf >> 18) + +#define BRDAC0 (1 << 0) +#define BRDAC1 (1 << 1) +#define BRDAC2 (1 << 2) +#define BRDAC3 (1 << 3) +#define BRDAC4 (1 << 4) +#define BRDAC5 (1 << 5) +#define MAX_RDACS 6 #define F_CMD_INC (1 << 0) /* Features INC/DEC ALL, 6dB */ #define F_CMD_EEP (1 << 1) /* Features EEPROM */ @@ -116,6 +117,11 @@ enum dpot_devid { AD5282_ID = DPOT_CONF(F_RDACS_RW, BRDAC0 | BRDAC1, 8, 41), ADN2860_ID = DPOT_CONF(F_RDACS_RW_TOL | F_CMD_INC, BRDAC0 | BRDAC1 | BRDAC2, 9, 42), + AD5273_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0, 6, 43), + AD5171_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0, 6, 44), + AD5170_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0, 8, 45), + AD5172_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0 | BRDAC1, 8, 46), + AD5173_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0 | BRDAC1, 8, 47), }; #define DPOT_RDAC0 0 @@ -136,9 +142,11 @@ enum dpot_devid { #define DPOT_TOL_RDAC5 (DPOT_REG_TOL | DPOT_RDAC5) /* RDAC-to-EEPROM Interface Commands */ -#define DPOT_ADDR_RDAC (0x00 << 5) -#define DPOT_ADDR_EEPROM (0x01 << 5) -#define DPOT_ADDR_CMD (0x80) +#define DPOT_ADDR_RDAC (0x0 << 5) +#define DPOT_ADDR_EEPROM (0x1 << 5) +#define DPOT_ADDR_OTP (0x1 << 6) +#define DPOT_ADDR_CMD (0x1 << 7) +#define DPOT_ADDR_OTP_EN (0x1 << 9) #define DPOT_DEC_ALL_6DB (DPOT_ADDR_CMD | (0x4 << 3)) #define DPOT_INC_ALL_6DB (DPOT_ADDR_CMD | (0x9 << 3)) @@ -161,6 +169,12 @@ enum dpot_devid { /* AD524x use special commands */ #define DPOT_AD5291_RDAC_AB 0x80 +#define DPOT_AD5273_FUSE 0x80 +#define DPOT_AD5270_2_3_FUSE 0x20 +#define DPOT_AD5270_2_3_OW 0x08 +#define DPOT_AD5272_3_A0 0x08 +#define DPOT_AD5270_2FUSE 0x80 + struct dpot_data; struct ad_dpot_bus_ops { -- cgit v1.2.3 From 0496b55c56d0be80e27f417f66690d97e5370f86 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 24 May 2010 14:33:25 -0700 Subject: drivers: isdn: use new hex_to_bin() method Remove own implementation of hex_to_bin(). Signed-off-by: Andy Shevchenko Acked-by: Tilman Schmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/isdn/gigaset/capi.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c index 964a55fb1486..ac4cfeed3946 100644 --- a/drivers/isdn/gigaset/capi.c +++ b/drivers/isdn/gigaset/capi.c @@ -169,17 +169,6 @@ static inline void ignore_cstruct_param(struct cardstate *cs, _cstruct param, msgname, paramname); } -/* - * convert hex to binary - */ -static inline u8 hex2bin(char c) -{ - int result = c & 0x0f; - if (c & 0x40) - result += 9; - return result; -} - /* * convert an IE from Gigaset hex string to ETSI binary representation * including length byte @@ -191,7 +180,7 @@ static int encode_ie(char *in, u8 *out, int maxlen) while (*in) { if (!isxdigit(in[0]) || !isxdigit(in[1]) || l >= maxlen) return -1; - out[++l] = (hex2bin(in[0]) << 4) + hex2bin(in[1]); + out[++l] = (hex_to_bin(in[0]) << 4) + hex_to_bin(in[1]); in += 2; } out[0] = l; -- cgit v1.2.3 From 96b89f323d6af996a7f6bd84d2119cbf7145f9a4 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 24 May 2010 14:33:25 -0700 Subject: usb: atm: speedtch: use new hex_to_bin() method Instead of using own implementation which potentialy has bugs involve hex_to_bin() function. It requires to have hex_to_bin() implementation introduced by starter patch in series. Signed-off-by: Andy Shevchenko Cc: Duncan Sands Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/usb/atm/speedtch.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 1e9ba4bdffef..1335456b4f93 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c @@ -127,8 +127,6 @@ MODULE_PARM_DESC(ModemOption, "default: 0x10,0x00,0x00,0x00,0x20"); #define ENDPOINT_ISOC_DATA 0x07 #define ENDPOINT_FIRMWARE 0x05 -#define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) ) - struct speedtch_params { unsigned int altsetting; unsigned int BMaxDSL; @@ -669,7 +667,8 @@ static int speedtch_atm_start(struct usbatm_data *usbatm, struct atm_dev *atm_de memset(atm_dev->esi, 0, sizeof(atm_dev->esi)); if (usb_string(usb_dev, usb_dev->descriptor.iSerialNumber, mac_str, sizeof(mac_str)) == 12) { for (i = 0; i < 6; i++) - atm_dev->esi[i] = (hex2int(mac_str[i * 2]) * 16) + (hex2int(mac_str[i * 2 + 1])); + atm_dev->esi[i] = (hex_to_bin(mac_str[i * 2]) << 4) + + hex_to_bin(mac_str[i * 2 + 1]); } /* Start modem synchronisation */ -- cgit v1.2.3 From 1356de06cea80ffc84cde6a4f8779414f20f211e Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 24 May 2010 14:33:27 -0700 Subject: staging: rt2860: use new hex_to_bin() method Instead of using own implementation involve hex_to_bin() function. Signed-off-by: Andy Shevchenko Cc: Greg Kroah-Hartman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/staging/rt2860/common/rtmp_init.c | 15 ++------------- drivers/staging/rt2860/rtmp.h | 2 -- 2 files changed, 2 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rt2860/common/rtmp_init.c b/drivers/staging/rt2860/common/rtmp_init.c index 21a95ffdfb86..a09038542f26 100644 --- a/drivers/staging/rt2860/common/rtmp_init.c +++ b/drivers/staging/rt2860/common/rtmp_init.c @@ -2810,17 +2810,6 @@ void UserCfgInit(struct rt_rtmp_adapter *pAd) } /* IRQL = PASSIVE_LEVEL */ -u8 BtoH(char ch) -{ - if (ch >= '0' && ch <= '9') - return (ch - '0'); /* Handle numerals */ - if (ch >= 'A' && ch <= 'F') - return (ch - 'A' + 0xA); /* Handle capitol hex digits */ - if (ch >= 'a' && ch <= 'f') - return (ch - 'a' + 0xA); /* Handle small hex digits */ - return (255); -} - /* */ /* FUNCTION: AtoH(char *, u8 *, int) */ /* */ @@ -2847,8 +2836,8 @@ void AtoH(char *src, u8 *dest, int destlen) destTemp = (u8 *)dest; while (destlen--) { - *destTemp = BtoH(*srcptr++) << 4; /* Put 1st ascii byte in upper nibble. */ - *destTemp += BtoH(*srcptr++); /* Add 2nd ascii byte to above. */ + *destTemp = hex_to_bin(*srcptr++) << 4; /* Put 1st ascii byte in upper nibble. */ + *destTemp += hex_to_bin(*srcptr++); /* Add 2nd ascii byte to above. */ destTemp++; } } diff --git a/drivers/staging/rt2860/rtmp.h b/drivers/staging/rt2860/rtmp.h index ab525ee15042..82b6e783b33f 100644 --- a/drivers/staging/rt2860/rtmp.h +++ b/drivers/staging/rt2860/rtmp.h @@ -2356,8 +2356,6 @@ void RTMPMoveMemory(void *pDest, void *pSrc, unsigned long Length); void AtoH(char *src, u8 *dest, int destlen); -u8 BtoH(char ch); - void RTMPPatchMacBbpBug(struct rt_rtmp_adapter *pAd); void RTMPInitTimer(struct rt_rtmp_adapter *pAd, -- cgit v1.2.3 From 26355387c21accb0919d34ee59478c23b2030ee5 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 24 May 2010 14:33:28 -0700 Subject: drivers: wireless: use new hex_to_bin() method Instead of using own implementation involve hex_to_bin() function. Signed-off-by: Andy Shevchenko Acked-by: John W. Linville Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/net/wireless/airo.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index a441aad922c2..3b7ab20a5c54 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -5162,13 +5162,6 @@ static void proc_SSID_on_close(struct inode *inode, struct file *file) enable_MAC(ai, 1); } -static inline u8 hexVal(char c) { - if (c>='0' && c<='9') return c -= '0'; - if (c>='a' && c<='f') return c -= 'a'-10; - if (c>='A' && c<='F') return c -= 'A'-10; - return 0; -} - static void proc_APList_on_close( struct inode *inode, struct file *file ) { struct proc_data *data = (struct proc_data *)file->private_data; struct proc_dir_entry *dp = PDE(inode); @@ -5188,11 +5181,11 @@ static void proc_APList_on_close( struct inode *inode, struct file *file ) { switch(j%3) { case 0: APList_rid.ap[i][j/3]= - hexVal(data->wbuffer[j+i*6*3])<<4; + hex_to_bin(data->wbuffer[j+i*6*3])<<4; break; case 1: APList_rid.ap[i][j/3]|= - hexVal(data->wbuffer[j+i*6*3]); + hex_to_bin(data->wbuffer[j+i*6*3]); break; } } @@ -5340,10 +5333,10 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) { for( i = 0; i < 16*3 && data->wbuffer[i+j]; i++ ) { switch(i%3) { case 0: - key[i/3] = hexVal(data->wbuffer[i+j])<<4; + key[i/3] = hex_to_bin(data->wbuffer[i+j])<<4; break; case 1: - key[i/3] |= hexVal(data->wbuffer[i+j]); + key[i/3] |= hex_to_bin(data->wbuffer[i+j]); break; } } -- cgit v1.2.3 From 965fd9e9a2d6d0a2704815e4579008a9f65282a0 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 24 May 2010 14:33:28 -0700 Subject: drivers: acpi: don't use own implementation of hex_to_bin() Remove own implementation of hex_to_bin(). Signed-off-by: Andy Shevchenko Cc: Len Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/acpi/bus.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 9042a8579668..c1d23cd71652 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -401,11 +401,6 @@ static void acpi_print_osc_error(acpi_handle handle, printk("\n"); } -static u8 hex_val(unsigned char c) -{ - return isdigit(c) ? c - '0' : toupper(c) - 'A' + 10; -} - static acpi_status acpi_str_to_uuid(char *str, u8 *uuid) { int i; @@ -422,8 +417,8 @@ static acpi_status acpi_str_to_uuid(char *str, u8 *uuid) return AE_BAD_PARAMETER; } for (i = 0; i < 16; i++) { - uuid[i] = hex_val(str[opc_map_to_uuid[i]]) << 4; - uuid[i] |= hex_val(str[opc_map_to_uuid[i] + 1]); + uuid[i] = hex_to_bin(str[opc_map_to_uuid[i]]) << 4; + uuid[i] |= hex_to_bin(str[opc_map_to_uuid[i] + 1]); } return AE_OK; } -- cgit v1.2.3 From 58e814227de9e8b5a4a50fb8018a770de9e974a0 Mon Sep 17 00:00:00 2001 From: Samu Onkalo Date: Mon, 24 May 2010 14:33:32 -0700 Subject: lis3: add missing constants for 8bit device Definitions for click were missing. Signed-off-by: Samu Onkalo Acked-by: Eric Piel Tested-by: Daniel Mack Cc: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/hwmon/lis3lv02d.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h index e6a01f44709b..692e2442ce08 100644 --- a/drivers/hwmon/lis3lv02d.h +++ b/drivers/hwmon/lis3lv02d.h @@ -196,6 +196,16 @@ enum lis3lv02d_dd_src { DD_SRC_IA = 0x40, }; +enum lis3lv02d_click_src_8b { + CLICK_SINGLE_X = 0x01, + CLICK_DOUBLE_X = 0x02, + CLICK_SINGLE_Y = 0x04, + CLICK_DOUBLE_Y = 0x08, + CLICK_SINGLE_Z = 0x10, + CLICK_DOUBLE_Z = 0x20, + CLICK_IA = 0x40, +}; + struct axis_conversion { s8 x; s8 y; -- cgit v1.2.3 From ecc437aeee65afeea2e1bed963ccf6c384c555ea Mon Sep 17 00:00:00 2001 From: Samu Onkalo Date: Mon, 24 May 2010 14:33:34 -0700 Subject: lis3: separate configuration function for 8 bit device Separate configuration function for 8 bit version of the chip. This way generic part of the init function stays little bit more readable. Signed-off-by: Samu Onkalo Acked-by: Eric Piel Tested-by: Daniel Mack Cc: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/hwmon/lis3lv02d.c | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index b2f2277cad3c..99fd45deda41 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c @@ -521,6 +521,30 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3) } EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); +static void lis3lv02d_8b_configure(struct lis3lv02d *dev, + struct lis3lv02d_platform_data *p) +{ + if (p->click_flags) { + dev->write(dev, CLICK_CFG, p->click_flags); + dev->write(dev, CLICK_TIMELIMIT, p->click_time_limit); + dev->write(dev, CLICK_LATENCY, p->click_latency); + dev->write(dev, CLICK_WINDOW, p->click_window); + dev->write(dev, CLICK_THSZ, p->click_thresh_z & 0xf); + dev->write(dev, CLICK_THSY_X, + (p->click_thresh_x & 0xf) | + (p->click_thresh_y << 4)); + } + + if (p->wakeup_flags) { + dev->write(dev, FF_WU_CFG_1, p->wakeup_flags); + dev->write(dev, FF_WU_THS_1, p->wakeup_thresh & 0x7f); + /* default to 2.5ms for now */ + dev->write(dev, FF_WU_DURATION_1, 1); + /* enable high pass filter for both free-fall units */ + dev->write(dev, CTRL_REG2, HP_FF_WU1 | HP_FF_WU2); + } +} + /* * Initialise the accelerometer and the various subsystems. * Should be rather independent of the bus system. @@ -567,25 +591,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) if (dev->pdata) { struct lis3lv02d_platform_data *p = dev->pdata; - if (p->click_flags && (dev->whoami == WAI_8B)) { - dev->write(dev, CLICK_CFG, p->click_flags); - dev->write(dev, CLICK_TIMELIMIT, p->click_time_limit); - dev->write(dev, CLICK_LATENCY, p->click_latency); - dev->write(dev, CLICK_WINDOW, p->click_window); - dev->write(dev, CLICK_THSZ, p->click_thresh_z & 0xf); - dev->write(dev, CLICK_THSY_X, - (p->click_thresh_x & 0xf) | - (p->click_thresh_y << 4)); - } - - if (p->wakeup_flags && (dev->whoami == WAI_8B)) { - dev->write(dev, FF_WU_CFG_1, p->wakeup_flags); - dev->write(dev, FF_WU_THS_1, p->wakeup_thresh & 0x7f); - /* default to 2.5ms for now */ - dev->write(dev, FF_WU_DURATION_1, 1); - /* enable high pass filter for both free-fall units */ - dev->write(dev, CTRL_REG2, HP_FF_WU1 | HP_FF_WU2); - } + if (dev->whoami == WAI_8B) + lis3lv02d_8b_configure(dev, p); if (p->irq_cfg) dev->write(dev, CTRL_REG3, p->irq_cfg); -- cgit v1.2.3 From 342c5f128140d54961c435d1702eadcaba97a37a Mon Sep 17 00:00:00 2001 From: Samu Onkalo Date: Mon, 24 May 2010 14:33:35 -0700 Subject: lis3: introduce platform data for second ff / wu unit 8 bit device has two wakeup / free fall units. It was not possible to configure the second unit. This patch introduces configuration entry to the platform data and also corresponding changes to the 8 bit setup function. High pass filters were enabled by default. Patch introduces configuration option for high pass filter cut off frequency and also possibility to disable or enable the filter via platform data. Since the control is a new one and default state was filter enabled, new option is used to disable the filter. This way old platform data is still compatible with the change. Signed-off-by: Samu Onkalo Acked-by: Eric Piel Tested-by: Daniel Mack Cc: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/hwmon/lis3lv02d.c | 15 +++++++++++++-- include/linux/lis3lv02d.h | 9 +++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index 99fd45deda41..50f312339608 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c @@ -524,6 +524,8 @@ EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); static void lis3lv02d_8b_configure(struct lis3lv02d *dev, struct lis3lv02d_platform_data *p) { + int ctrl2 = p->hipass_ctrl; + if (p->click_flags) { dev->write(dev, CLICK_CFG, p->click_flags); dev->write(dev, CLICK_TIMELIMIT, p->click_time_limit); @@ -540,9 +542,18 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev, dev->write(dev, FF_WU_THS_1, p->wakeup_thresh & 0x7f); /* default to 2.5ms for now */ dev->write(dev, FF_WU_DURATION_1, 1); - /* enable high pass filter for both free-fall units */ - dev->write(dev, CTRL_REG2, HP_FF_WU1 | HP_FF_WU2); + ctrl2 ^= HP_FF_WU1; /* Xor to keep compatible with old pdata*/ + } + + if (p->wakeup_flags2) { + dev->write(dev, FF_WU_CFG_2, p->wakeup_flags2); + dev->write(dev, FF_WU_THS_2, p->wakeup_thresh2 & 0x7f); + /* default to 2.5ms for now */ + dev->write(dev, FF_WU_DURATION_2, 1); + ctrl2 ^= HP_FF_WU2; /* Xor to keep compatible with old pdata*/ } + /* Configure hipass filters */ + dev->write(dev, CTRL_REG2, ctrl2); } /* diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h index f1ca0dcc1628..d6251995c042 100644 --- a/include/linux/lis3lv02d.h +++ b/include/linux/lis3lv02d.h @@ -43,6 +43,15 @@ struct lis3lv02d_platform_data { #define LIS3_WAKEUP_Z_HI (1 << 5) unsigned char wakeup_flags; unsigned char wakeup_thresh; + unsigned char wakeup_flags2; + unsigned char wakeup_thresh2; +#define LIS3_HIPASS_CUTFF_8HZ 0 +#define LIS3_HIPASS_CUTFF_4HZ 1 +#define LIS3_HIPASS_CUTFF_2HZ 2 +#define LIS3_HIPASS_CUTFF_1HZ 3 +#define LIS3_HIPASS1_DISABLE (1 << 2) +#define LIS3_HIPASS2_DISABLE (1 << 3) + unsigned char hipass_ctrl; #define LIS3_NO_MAP 0 #define LIS3_DEV_X 1 #define LIS3_DEV_Y 2 -- cgit v1.2.3 From 92ba4fe4b53b4fa5ac71ec4d80572348fca85796 Mon Sep 17 00:00:00 2001 From: Samu Onkalo Date: Mon, 24 May 2010 14:33:36 -0700 Subject: lis3: add skeletons for interrupt handlers Original lis3 driver didn't provide interrupt handler(s) for click or threshold event handling. This patch adds threaded handlers for one or two interrupt lines for 8 bit device. Actual content for interrupt handling is provided in the separate patch. Signed-off-by: Samu Onkalo Tested-by: Daniel Mack Acked-by: Eric Piel Cc: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/hwmon/lis3lv02d.c | 87 ++++++++++++++++++++++++++++++++++------------- include/linux/lis3lv02d.h | 1 + 2 files changed, 65 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index 50f312339608..3c06350bae3a 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c @@ -251,6 +251,9 @@ EXPORT_SYMBOL_GPL(lis3lv02d_poweron); static irqreturn_t lis302dl_interrupt(int irq, void *dummy) { + if (!test_bit(0, &lis3_dev.misc_opened)) + goto out; + /* * Be careful: on some HP laptops the bios force DD when on battery and * the lid is closed. This leads to interrupts as soon as a little move @@ -260,44 +263,35 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy) wake_up_interruptible(&lis3_dev.misc_wait); kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN); +out: + if (lis3_dev.whoami == WAI_8B && lis3_dev.idev && + lis3_dev.idev->input->users) + return IRQ_WAKE_THREAD; return IRQ_HANDLED; } -static int lis3lv02d_misc_open(struct inode *inode, struct file *file) +static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data) { - int ret; + return IRQ_HANDLED; +} +static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data) +{ + return IRQ_HANDLED; +} + +static int lis3lv02d_misc_open(struct inode *inode, struct file *file) +{ if (test_and_set_bit(0, &lis3_dev.misc_opened)) return -EBUSY; /* already open */ atomic_set(&lis3_dev.count, 0); - - /* - * The sensor can generate interrupts for free-fall and direction - * detection (distinguishable with FF_WU_SRC and DD_SRC) but to keep - * the things simple and _fast_ we activate it only for free-fall, so - * no need to read register (very slow with ACPI). For the same reason, - * we forbid shared interrupts. - * - * IRQF_TRIGGER_RISING seems pointless on HP laptops because the - * io-apic is not configurable (and generates a warning) but I keep it - * in case of support for other hardware. - */ - ret = request_irq(lis3_dev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING, - DRIVER_NAME, &lis3_dev); - - if (ret) { - clear_bit(0, &lis3_dev.misc_opened); - printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", lis3_dev.irq); - return -EBUSY; - } return 0; } static int lis3lv02d_misc_release(struct inode *inode, struct file *file) { fasync_helper(-1, file, 0, &lis3_dev.async_queue); - free_irq(lis3_dev.irq, &lis3_dev); clear_bit(0, &lis3_dev.misc_opened); /* release the device */ return 0; } @@ -434,6 +428,11 @@ EXPORT_SYMBOL_GPL(lis3lv02d_joystick_enable); void lis3lv02d_joystick_disable(void) { + if (lis3_dev.irq) + free_irq(lis3_dev.irq, &lis3_dev); + if (lis3_dev.pdata && lis3_dev.pdata->irq2) + free_irq(lis3_dev.pdata->irq2, &lis3_dev); + if (!lis3_dev.idev) return; @@ -524,6 +523,7 @@ EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); static void lis3lv02d_8b_configure(struct lis3lv02d *dev, struct lis3lv02d_platform_data *p) { + int err; int ctrl2 = p->hipass_ctrl; if (p->click_flags) { @@ -554,6 +554,18 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev, } /* Configure hipass filters */ dev->write(dev, CTRL_REG2, ctrl2); + + if (p->irq2) { + err = request_threaded_irq(p->irq2, + NULL, + lis302dl_interrupt_thread2_8b, + IRQF_TRIGGER_RISING | + IRQF_ONESHOT, + DRIVER_NAME, &lis3_dev); + if (err < 0) + printk(KERN_ERR DRIVER_NAME + "No second IRQ. Limited functionality\n"); + } } /* @@ -562,6 +574,9 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev, */ int lis3lv02d_init_device(struct lis3lv02d *dev) { + int err; + irq_handler_t thread_fn; + dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I); switch (dev->whoami) { @@ -616,6 +631,32 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) goto out; } + /* + * The sensor can generate interrupts for free-fall and direction + * detection (distinguishable with FF_WU_SRC and DD_SRC) but to keep + * the things simple and _fast_ we activate it only for free-fall, so + * no need to read register (very slow with ACPI). For the same reason, + * we forbid shared interrupts. + * + * IRQF_TRIGGER_RISING seems pointless on HP laptops because the + * io-apic is not configurable (and generates a warning) but I keep it + * in case of support for other hardware. + */ + if (dev->whoami == WAI_8B) + thread_fn = lis302dl_interrupt_thread1_8b; + else + thread_fn = NULL; + + err = request_threaded_irq(dev->irq, lis302dl_interrupt, + thread_fn, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + DRIVER_NAME, &lis3_dev); + + if (err < 0) { + printk(KERN_ERR DRIVER_NAME "Cannot get IRQ\n"); + goto out; + } + if (misc_register(&lis3lv02d_misc_device)) printk(KERN_ERR DRIVER_NAME ": misc_register failed\n"); out: diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h index d6251995c042..fd289b1e1ec1 100644 --- a/include/linux/lis3lv02d.h +++ b/include/linux/lis3lv02d.h @@ -67,6 +67,7 @@ struct lis3lv02d_platform_data { /* Limits for selftest are specified in chip data sheet */ s16 st_min_limits[3]; /* min pass limit x, y, z */ s16 st_max_limits[3]; /* max pass limit x, y, z */ + int irq2; }; #endif /* __LIS3LV02D_H_ */ -- cgit v1.2.3 From 6d94d4081048756df78444a07201156f4930fe48 Mon Sep 17 00:00:00 2001 From: Samu Onkalo Date: Mon, 24 May 2010 14:33:37 -0700 Subject: lis3: interrupt handlers for 8bit wakeup and click events Content for the 8bit device threaded interrupt handlers. Depending on the interrupt line and chip configuration, either click or wakeup / freefall handler is called. In case of click, BTN_ event is sent via input device. In case of wakeup or freefall, input device ABS_ events are updated immediatelly. It is still possible to configure interrupt line 1 for fast freefall detection and use the second line either for click or threshold based interrupts. Or both lines can be used for click / threshold interrupts. Polled input device can be set to stopped state and still get coordinate updates via input device using interrupt based method. Polled mode and interrupt mode can also be used parallel. BTN_ events are remapped based on existing axis remapping information. Signed-off-by: Samu Onkalo Acked-by: Eric Piel Cc: Daniel Mack Cc: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/hwmon/lis3lv02d.c | 98 ++++++++++++++++++++++++++++++++++++++++------- drivers/hwmon/lis3lv02d.h | 1 + include/linux/lis3lv02d.h | 2 + 3 files changed, 88 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index 3c06350bae3a..56a1d34d3670 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c @@ -121,11 +121,9 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z) int position[3]; int i; - mutex_lock(&lis3->mutex); position[0] = lis3->read_data(lis3, OUTX); position[1] = lis3->read_data(lis3, OUTY); position[2] = lis3->read_data(lis3, OUTZ); - mutex_unlock(&lis3->mutex); for (i = 0; i < 3; i++) position[i] = (position[i] * lis3->scale) / LIS3_ACCURACY; @@ -249,6 +247,19 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3) EXPORT_SYMBOL_GPL(lis3lv02d_poweron); +static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev) +{ + int x, y, z; + + mutex_lock(&lis3_dev.mutex); + lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); + input_report_abs(pidev->input, ABS_X, x); + input_report_abs(pidev->input, ABS_Y, y); + input_report_abs(pidev->input, ABS_Z, z); + input_sync(pidev->input); + mutex_unlock(&lis3_dev.mutex); +} + static irqreturn_t lis302dl_interrupt(int irq, void *dummy) { if (!test_bit(0, &lis3_dev.misc_opened)) @@ -270,13 +281,71 @@ out: return IRQ_HANDLED; } +static void lis302dl_interrupt_handle_click(struct lis3lv02d *lis3) +{ + struct input_dev *dev = lis3->idev->input; + u8 click_src; + + mutex_lock(&lis3->mutex); + lis3->read(lis3, CLICK_SRC, &click_src); + + if (click_src & CLICK_SINGLE_X) { + input_report_key(dev, lis3->mapped_btns[0], 1); + input_report_key(dev, lis3->mapped_btns[0], 0); + } + + if (click_src & CLICK_SINGLE_Y) { + input_report_key(dev, lis3->mapped_btns[1], 1); + input_report_key(dev, lis3->mapped_btns[1], 0); + } + + if (click_src & CLICK_SINGLE_Z) { + input_report_key(dev, lis3->mapped_btns[2], 1); + input_report_key(dev, lis3->mapped_btns[2], 0); + } + input_sync(dev); + mutex_unlock(&lis3->mutex); +} + +static void lis302dl_interrupt_handle_ff_wu(struct lis3lv02d *lis3) +{ + u8 wu1_src; + u8 wu2_src; + + lis3->read(lis3, FF_WU_SRC_1, &wu1_src); + lis3->read(lis3, FF_WU_SRC_2, &wu2_src); + + wu1_src = wu1_src & FF_WU_SRC_IA ? wu1_src : 0; + wu2_src = wu2_src & FF_WU_SRC_IA ? wu2_src : 0; + + /* joystick poll is internally protected by the lis3->mutex. */ + if (wu1_src || wu2_src) + lis3lv02d_joystick_poll(lis3_dev.idev); +} + static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data) { + + struct lis3lv02d *lis3 = data; + + if ((lis3->pdata->irq_cfg & LIS3_IRQ1_MASK) == LIS3_IRQ1_CLICK) + lis302dl_interrupt_handle_click(lis3); + else + lis302dl_interrupt_handle_ff_wu(lis3); + return IRQ_HANDLED; } static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data) { + + struct lis3lv02d *lis3 = data; + + if ((lis3->pdata->irq_cfg & LIS3_IRQ2_MASK) == LIS3_IRQ2_CLICK) + lis302dl_interrupt_handle_click(lis3); + else + lis302dl_interrupt_handle_ff_wu(lis3); + return IRQ_HANDLED; } @@ -374,22 +443,12 @@ static struct miscdevice lis3lv02d_misc_device = { .fops = &lis3lv02d_misc_fops, }; -static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev) -{ - int x, y, z; - - lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); - input_report_abs(pidev->input, ABS_X, x); - input_report_abs(pidev->input, ABS_Y, y); - input_report_abs(pidev->input, ABS_Z, z); - input_sync(pidev->input); -} - int lis3lv02d_joystick_enable(void) { struct input_dev *input_dev; int err; int max_val, fuzz, flat; + int btns[] = {BTN_X, BTN_Y, BTN_Z}; if (lis3_dev.idev) return -EINVAL; @@ -416,6 +475,10 @@ int lis3lv02d_joystick_enable(void) input_set_abs_params(input_dev, ABS_Y, -max_val, max_val, fuzz, flat); input_set_abs_params(input_dev, ABS_Z, -max_val, max_val, fuzz, flat); + lis3_dev.mapped_btns[0] = lis3lv02d_get_axis(abs(lis3_dev.ac.x), btns); + lis3_dev.mapped_btns[1] = lis3lv02d_get_axis(abs(lis3_dev.ac.y), btns); + lis3_dev.mapped_btns[2] = lis3lv02d_get_axis(abs(lis3_dev.ac.z), btns); + err = input_register_polled_device(lis3_dev.idev); if (err) { input_free_polled_device(lis3_dev.idev); @@ -461,7 +524,9 @@ static ssize_t lis3lv02d_position_show(struct device *dev, { int x, y, z; + mutex_lock(&lis3_dev.mutex); lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); + mutex_unlock(&lis3_dev.mutex); return sprintf(buf, "(%d,%d,%d)\n", x, y, z); } @@ -535,6 +600,13 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev, dev->write(dev, CLICK_THSY_X, (p->click_thresh_x & 0xf) | (p->click_thresh_y << 4)); + + if (dev->idev) { + struct input_dev *input_dev = lis3_dev.idev->input; + input_set_capability(input_dev, EV_KEY, BTN_X); + input_set_capability(input_dev, EV_KEY, BTN_Y); + input_set_capability(input_dev, EV_KEY, BTN_Z); + } } if (p->wakeup_flags) { diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h index 692e2442ce08..854091380e33 100644 --- a/drivers/hwmon/lis3lv02d.h +++ b/drivers/hwmon/lis3lv02d.h @@ -233,6 +233,7 @@ struct lis3lv02d { struct platform_device *pdev; /* platform device */ atomic_t count; /* interrupt count after last read */ struct axis_conversion ac; /* hw -> logical axis */ + int mapped_btns[3]; u32 irq; /* IRQ number */ struct fasync_struct *async_queue; /* queue for the misc device */ diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h index fd289b1e1ec1..0e8a346424bb 100644 --- a/include/linux/lis3lv02d.h +++ b/include/linux/lis3lv02d.h @@ -25,12 +25,14 @@ struct lis3lv02d_platform_data { #define LIS3_IRQ1_FF_WU_12 (3 << 0) #define LIS3_IRQ1_DATA_READY (4 << 0) #define LIS3_IRQ1_CLICK (7 << 0) +#define LIS3_IRQ1_MASK (7 << 0) #define LIS3_IRQ2_DISABLE (0 << 3) #define LIS3_IRQ2_FF_WU_1 (1 << 3) #define LIS3_IRQ2_FF_WU_2 (2 << 3) #define LIS3_IRQ2_FF_WU_12 (3 << 3) #define LIS3_IRQ2_DATA_READY (4 << 3) #define LIS3_IRQ2_CLICK (7 << 3) +#define LIS3_IRQ2_MASK (7 << 3) #define LIS3_IRQ_OPEN_DRAIN (1 << 6) #define LIS3_IRQ_ACTIVE_LOW (1 << 7) unsigned char irq_cfg; -- cgit v1.2.3 From 4a70a413ccfd1c14ef29a290a4d2dada04ccbefb Mon Sep 17 00:00:00 2001 From: Samu Onkalo Date: Mon, 24 May 2010 14:33:37 -0700 Subject: lis3: setup poll interval limits Set valid adjustment window (0 - 2000ms). Signed-off-by: Samu Onkalo Acked-by: Eric Piel Cc: Daniel Mack Cc: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/hwmon/lis3lv02d.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index 56a1d34d3670..6138f036b159 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c @@ -41,6 +41,8 @@ /* joystick device poll interval in milliseconds */ #define MDPS_POLL_INTERVAL 50 +#define MDPS_POLL_MIN 0 +#define MDPS_POLL_MAX 2000 /* * The sensor can also generate interrupts (DRDY) but it's pretty pointless * because they are generated even if the data do not change. So it's better @@ -459,6 +461,8 @@ int lis3lv02d_joystick_enable(void) lis3_dev.idev->poll = lis3lv02d_joystick_poll; lis3_dev.idev->poll_interval = MDPS_POLL_INTERVAL; + lis3_dev.idev->poll_interval_min = MDPS_POLL_MIN; + lis3_dev.idev->poll_interval_max = MDPS_POLL_MAX; input_dev = lis3_dev.idev->input; input_dev->name = "ST LIS3LV02DL Accelerometer"; -- cgit v1.2.3 From e0c70b80786296d4f3c35ebe0d52591cebf8f916 Mon Sep 17 00:00:00 2001 From: Paul Thomas Date: Mon, 24 May 2010 14:33:38 -0700 Subject: hwmon: add TI ads7871 a/d converter driver [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Paul Thomas Cc: Jonathan Cameron Cc: Jean Delvare Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/hwmon/Kconfig | 9 ++ drivers/hwmon/Makefile | 1 + drivers/hwmon/ads7871.c | 253 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 263 insertions(+) create mode 100644 drivers/hwmon/ads7871.c (limited to 'drivers') diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 9be8e1754a0b..6a9ac754ca5d 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -802,6 +802,15 @@ config SENSORS_ADS7828 This driver can also be built as a module. If so, the module will be called ads7828. +config SENSORS_ADS7871 + tristate "Texas Instruments ADS7871 A/D converter" + depends on SPI + help + If you say yes here you get support for TI ADS7871 & ADS7870 + + This driver can also be built as a module. If so, the module + will be called ads7871. + config SENSORS_AMC6821 tristate "Texas Instruments AMC6821" depends on I2C && EXPERIMENTAL diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 4aa1a3d112ad..86920fb34118 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o +obj-$(CONFIG_SENSORS_ADS7871) += ads7871.o obj-$(CONFIG_SENSORS_ADT7411) += adt7411.o obj-$(CONFIG_SENSORS_ADT7462) += adt7462.o obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o diff --git a/drivers/hwmon/ads7871.c b/drivers/hwmon/ads7871.c new file mode 100644 index 000000000000..b300a2048af1 --- /dev/null +++ b/drivers/hwmon/ads7871.c @@ -0,0 +1,253 @@ +/* + * ads7871 - driver for TI ADS7871 A/D converter + * + * Copyright (c) 2010 Paul Thomas + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * later as publishhed by the Free Software Foundation. + * + * You need to have something like this in struct spi_board_info + * { + * .modalias = "ads7871", + * .max_speed_hz = 2*1000*1000, + * .chip_select = 0, + * .bus_num = 1, + * }, + */ + +/*From figure 18 in the datasheet*/ +/*Register addresses*/ +#define REG_LS_BYTE 0 /*A/D Output Data, LS Byte*/ +#define REG_MS_BYTE 1 /*A/D Output Data, MS Byte*/ +#define REG_PGA_VALID 2 /*PGA Valid Register*/ +#define REG_AD_CONTROL 3 /*A/D Control Register*/ +#define REG_GAIN_MUX 4 /*Gain/Mux Register*/ +#define REG_IO_STATE 5 /*Digital I/O State Register*/ +#define REG_IO_CONTROL 6 /*Digital I/O Control Register*/ +#define REG_OSC_CONTROL 7 /*Rev/Oscillator Control Register*/ +#define REG_SER_CONTROL 24 /*Serial Interface Control Register*/ +#define REG_ID 31 /*ID Register*/ + +/*From figure 17 in the datasheet +* These bits get ORed with the address to form +* the instruction byte */ +/*Instruction Bit masks*/ +#define INST_MODE_bm (1<<7) +#define INST_READ_bm (1<<6) +#define INST_16BIT_bm (1<<5) + +/*From figure 18 in the datasheet*/ +/*bit masks for Rev/Oscillator Control Register*/ +#define MUX_CNV_bv 7 +#define MUX_CNV_bm (1< +#include +#include +#include +#include +#include +#include +#include + +#define DEVICE_NAME "ads7871" + +struct ads7871_data { + struct device *hwmon_dev; + struct mutex update_lock; +}; + +static int ads7871_read_reg8(struct spi_device *spi, int reg) +{ + int ret; + reg = reg | INST_READ_bm; + ret = spi_w8r8(spi, reg); + return ret; +} + +static int ads7871_read_reg16(struct spi_device *spi, int reg) +{ + int ret; + reg = reg | INST_READ_bm | INST_16BIT_bm; + ret = spi_w8r16(spi, reg); + return ret; +} + +static int ads7871_write_reg8(struct spi_device *spi, int reg, u8 val) +{ + u8 tmp[2] = {reg, val}; + return spi_write(spi, tmp, sizeof(tmp)); +} + +static ssize_t show_voltage(struct device *dev, + struct device_attribute *da, char *buf) +{ + struct spi_device *spi = to_spi_device(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + int ret, val, i = 0; + uint8_t channel, mux_cnv; + + channel = attr->index; + /*TODO: add support for conversions + *other than single ended with a gain of 1*/ + /*MUX_M3_bm forces single ended*/ + /*This is also where the gain of the PGA would be set*/ + ads7871_write_reg8(spi, REG_GAIN_MUX, + (MUX_CNV_bm | MUX_M3_bm | channel)); + + ret = ads7871_read_reg8(spi, REG_GAIN_MUX); + mux_cnv = ((ret & MUX_CNV_bm)>>MUX_CNV_bv); + /*on 400MHz arm9 platform the conversion + *is already done when we do this test*/ + while ((i < 2) && mux_cnv) { + i++; + ret = ads7871_read_reg8(spi, REG_GAIN_MUX); + mux_cnv = ((ret & MUX_CNV_bm)>>MUX_CNV_bv); + msleep_interruptible(1); + } + + if (mux_cnv == 0) { + val = ads7871_read_reg16(spi, REG_LS_BYTE); + /*result in volts*10000 = (val/8192)*2.5*10000*/ + val = ((val>>2) * 25000) / 8192; + return sprintf(buf, "%d\n", val); + } else { + return -1; + } +} + +static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_voltage, NULL, 0); +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_voltage, NULL, 1); +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_voltage, NULL, 2); +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_voltage, NULL, 3); +static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_voltage, NULL, 4); +static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_voltage, NULL, 5); +static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_voltage, NULL, 6); +static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_voltage, NULL, 7); + +static struct attribute *ads7871_attributes[] = { + &sensor_dev_attr_in0_input.dev_attr.attr, + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_in4_input.dev_attr.attr, + &sensor_dev_attr_in5_input.dev_attr.attr, + &sensor_dev_attr_in6_input.dev_attr.attr, + &sensor_dev_attr_in7_input.dev_attr.attr, + NULL +}; + +static const struct attribute_group ads7871_group = { + .attrs = ads7871_attributes, +}; + +static int __devinit ads7871_probe(struct spi_device *spi) +{ + int status, ret, err = 0; + uint8_t val; + struct ads7871_data *pdata; + + dev_dbg(&spi->dev, "probe\n"); + + pdata = kzalloc(sizeof(struct ads7871_data), GFP_KERNEL); + if (!pdata) { + err = -ENOMEM; + goto exit; + } + + status = sysfs_create_group(&spi->dev.kobj, &ads7871_group); + if (status < 0) + goto error_free; + + pdata->hwmon_dev = hwmon_device_register(&spi->dev); + if (IS_ERR(pdata->hwmon_dev)) { + err = PTR_ERR(pdata->hwmon_dev); + goto error_remove; + } + + spi_set_drvdata(spi, pdata); + + /* Configure the SPI bus */ + spi->mode = (SPI_MODE_0); + spi->bits_per_word = 8; + spi_setup(spi); + + ads7871_write_reg8(spi, REG_SER_CONTROL, 0); + ads7871_write_reg8(spi, REG_AD_CONTROL, 0); + + val = (OSC_OSCR_bm | OSC_OSCE_bm | OSC_REFE_bm | OSC_BUFE_bm); + ads7871_write_reg8(spi, REG_OSC_CONTROL, val); + ret = ads7871_read_reg8(spi, REG_OSC_CONTROL); + + dev_dbg(&spi->dev, "REG_OSC_CONTROL write:%x, read:%x\n", val, ret); + /*because there is no other error checking on an SPI bus + we need to make sure we really have a chip*/ + if (val != ret) { + err = -ENODEV; + goto error_remove; + } + + return 0; + +error_remove: + sysfs_remove_group(&spi->dev.kobj, &ads7871_group); +error_free: + kfree(pdata); +exit: + return err; +} + +static int __devexit ads7871_remove(struct spi_device *spi) +{ + struct ads7871_data *pdata = spi_get_drvdata(spi); + + hwmon_device_unregister(pdata->hwmon_dev); + sysfs_remove_group(&spi->dev.kobj, &ads7871_group); + kfree(pdata); + return 0; +} + +static struct spi_driver ads7871_driver = { + .driver = { + .name = DEVICE_NAME, + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + + .probe = ads7871_probe, + .remove = __devexit_p(ads7871_remove), +}; + +static int __init ads7871_init(void) +{ + return spi_register_driver(&ads7871_driver); +} + +static void __exit ads7871_exit(void) +{ + spi_unregister_driver(&ads7871_driver); +} + +module_init(ads7871_init); +module_exit(ads7871_exit); + +MODULE_AUTHOR("Paul Thomas "); +MODULE_DESCRIPTION("TI ADS7871 A/D driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 5db47b009d17d69a2f8d84357e7b24c3e3c2edec Mon Sep 17 00:00:00 2001 From: Carsten Emde Date: Mon, 24 May 2010 14:33:39 -0700 Subject: drivers/hwmon/coretemp.c: detect the thermal sensors by CPUID The thermal sensors of Intel(R) CPUs can be detected by CPUID instruction, indicated by CPUID.06H.EAX[0]. Signed-off-by: Huaxu Wan Signed-off-by: Carsten Emde Reviewed-by: Valdis Kletnieks Cc: Jean Delvare Cc: Henrique de Moraes Holschuh Cc: Yong Wang Cc: Rudolf Marek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/hwmon/coretemp.c | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index e9b7fbc5a447..9fae7cbc5d76 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -451,28 +451,20 @@ static int __init coretemp_init(void) for_each_online_cpu(i) { struct cpuinfo_x86 *c = &cpu_data(i); + /* + * CPUID.06H.EAX[0] indicates whether the CPU has thermal + * sensors. We check this bit only, all the early CPUs + * without thermal sensors will be filtered out. + */ + if (c->cpuid_level >= 6 && (cpuid_eax(0x06) & 0x01)) { + err = coretemp_device_add(i); + if (err) + goto exit_devices_unreg; - /* check if family 6, models 0xe (Pentium M DC), - 0xf (Core 2 DC 65nm), 0x16 (Core 2 SC 65nm), - 0x17 (Penryn 45nm), 0x1a (Nehalem), 0x1c (Atom), - 0x1e (Lynnfield) */ - if ((c->cpuid_level < 0) || (c->x86 != 0x6) || - !((c->x86_model == 0xe) || (c->x86_model == 0xf) || - (c->x86_model == 0x16) || (c->x86_model == 0x17) || - (c->x86_model == 0x1a) || (c->x86_model == 0x1c) || - (c->x86_model == 0x1e))) { - - /* supported CPU not found, but report the unknown - family 6 CPU */ - if ((c->x86 == 0x6) && (c->x86_model > 0xf)) - printk(KERN_WARNING DRVNAME ": Unknown CPU " - "model 0x%x\n", c->x86_model); - continue; + } else { + printk(KERN_INFO DRVNAME ": CPU (model=0x%x)" + " has no thermal sensor.\n", c->x86_model); } - - err = coretemp_device_add(i); - if (err) - goto exit_devices_unreg; } if (list_empty(&pdev_list)) { err = -ENODEV; -- cgit v1.2.3 From a321cedb12904114e2ba5041a3673ca24deb09c9 Mon Sep 17 00:00:00 2001 From: Carsten Emde Date: Mon, 24 May 2010 14:33:41 -0700 Subject: drivers/hwmon/coretemp.c: get TjMax value from MSR The MSR IA32_TEMPERATURE_TARGET contains the TjMax value in the newer Intel processors. Signed-off-by: Huaxu Wan Signed-off-by: Carsten Emde Cc: Jean Delvare Cc: Valdis Kletnieks Cc: Henrique de Moraes Holschuh Cc: Yong Wang Cc: Rudolf Marek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86/include/asm/msr-index.h | 2 ++ drivers/hwmon/coretemp.c | 61 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 59 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index f9324851eba0..b49d8ca228f6 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -236,6 +236,8 @@ #define MSR_IA32_MISC_ENABLE 0x000001a0 +#define MSR_IA32_TEMPERATURE_TARGET 0x000001a2 + /* MISC_ENABLE bits: architectural */ #define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << 0) #define MSR_IA32_MISC_ENABLE_TCC (1ULL << 1) diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 9fae7cbc5d76..2988da150ed6 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -241,6 +241,55 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device * return tjmax; } +static int __devinit get_tjmax(struct cpuinfo_x86 *c, u32 id, + struct device *dev) +{ + /* The 100C is default for both mobile and non mobile CPUs */ + int err; + u32 eax, edx; + u32 val; + + /* A new feature of current Intel(R) processors, the + IA32_TEMPERATURE_TARGET contains the TjMax value */ + err = rdmsr_safe_on_cpu(id, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx); + if (err) { + dev_warn(dev, "Unable to read TjMax from CPU.\n"); + } else { + val = (eax >> 16) & 0xff; + /* + * If the TjMax is not plausible, an assumption + * will be used + */ + if ((val > 80) && (val < 120)) { + dev_info(dev, "TjMax is %d C.\n", val); + return val * 1000; + } + } + + /* + * An assumption is made for early CPUs and unreadable MSR. + * NOTE: the given value may not be correct. + */ + + switch (c->x86_model) { + case 0xe: + case 0xf: + case 0x16: + case 0x1a: + dev_warn(dev, "TjMax is assumed as 100 C!\n"); + return 100000; + break; + case 0x17: + case 0x1c: /* Atom CPUs */ + return adjust_tjmax(c, id, dev); + break; + default: + dev_warn(dev, "CPU (model=0x%x) is not supported yet," + " using default TjMax of 100C.\n", c->x86_model); + return 100000; + } +} + static int __devinit coretemp_probe(struct platform_device *pdev) { struct coretemp_data *data; @@ -283,14 +332,18 @@ static int __devinit coretemp_probe(struct platform_device *pdev) } } - data->tjmax = adjust_tjmax(c, data->id, &pdev->dev); + data->tjmax = get_tjmax(c, data->id, &pdev->dev); platform_set_drvdata(pdev, data); - /* read the still undocumented IA32_TEMPERATURE_TARGET it exists - on older CPUs but not in this register, Atoms don't have it either */ + /* + * read the still undocumented IA32_TEMPERATURE_TARGET. It exists + * on older CPUs but not in this register, + * Atoms don't have it either. + */ if ((c->x86_model > 0xe) && (c->x86_model != 0x1c)) { - err = rdmsr_safe_on_cpu(data->id, 0x1a2, &eax, &edx); + err = rdmsr_safe_on_cpu(data->id, MSR_IA32_TEMPERATURE_TARGET, + &eax, &edx); if (err) { dev_warn(&pdev->dev, "Unable to read" " IA32_TEMPERATURE_TARGET MSR\n"); -- cgit v1.2.3 From f3bc3189a001ec85c7b1119ad4aa5e39eea0f05e Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 24 May 2010 14:33:41 -0700 Subject: xen: fix build when SYSRQ is disabled Fix build error when CONFIG_MAGIC_SYSRQ is not enabled: drivers/xen/manage.c:223: error: implicit declaration of function 'handle_sysrq' Signed-off-by: Randy Dunlap Acked-by: Jeremy Fitzhardinge Cc: Chris Wright Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/xen/manage.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 8943b8ccee1a..07e857b0de13 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -185,6 +185,7 @@ static void shutdown_handler(struct xenbus_watch *watch, kfree(str); } +#ifdef CONFIG_MAGIC_SYSRQ static void sysrq_handler(struct xenbus_watch *watch, const char **vec, unsigned int len) { @@ -214,15 +215,16 @@ static void sysrq_handler(struct xenbus_watch *watch, const char **vec, handle_sysrq(sysrq_key, NULL); } -static struct xenbus_watch shutdown_watch = { - .node = "control/shutdown", - .callback = shutdown_handler -}; - static struct xenbus_watch sysrq_watch = { .node = "control/sysrq", .callback = sysrq_handler }; +#endif + +static struct xenbus_watch shutdown_watch = { + .node = "control/shutdown", + .callback = shutdown_handler +}; static int setup_shutdown_watcher(void) { @@ -234,11 +236,13 @@ static int setup_shutdown_watcher(void) return err; } +#ifdef CONFIG_MAGIC_SYSRQ err = register_xenbus_watch(&sysrq_watch); if (err) { printk(KERN_ERR "Failed to set sysrq watcher\n"); return err; } +#endif return 0; } -- cgit v1.2.3 From 9f4123b78d02ba48e7e6e3cd9de789c9b85b557a Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Mon, 24 May 2010 14:33:43 -0700 Subject: s3c rtc driver: add support for S3C64xx Add support for the S3C64xx SoC to the generic S3C RTC driver. Signed-off-by: Maurus Cuelenaere Acked-by: Ben Dooks Cc: Frans Pop Cc: Paul Gortmaker Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/plat-samsung/include/plat/regs-rtc.h | 4 + drivers/rtc/Kconfig | 2 +- drivers/rtc/rtc-s3c.c | 107 +++++++++++++++++++++----- 3 files changed, 92 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/arch/arm/plat-samsung/include/plat/regs-rtc.h b/arch/arm/plat-samsung/include/plat/regs-rtc.h index d5837cf8e402..65c190d142dd 100644 --- a/arch/arm/plat-samsung/include/plat/regs-rtc.h +++ b/arch/arm/plat-samsung/include/plat/regs-rtc.h @@ -20,6 +20,10 @@ #define S3C2410_RTCCON_CLKSEL (1<<1) #define S3C2410_RTCCON_CNTSEL (1<<2) #define S3C2410_RTCCON_CLKRST (1<<3) +#define S3C64XX_RTCCON_TICEN (1<<8) + +#define S3C64XX_RTCCON_TICMSK (0xF<<7) +#define S3C64XX_RTCCON_TICSHT (7) #define S3C2410_TICNT S3C2410_RTCREG(0x44) #define S3C2410_TICNT_ENABLE (1<<7) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 50ac047cd136..f1598324344c 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -640,7 +640,7 @@ config RTC_DRV_OMAP config RTC_DRV_S3C tristate "Samsung S3C series SoC RTC" - depends on ARCH_S3C2410 + depends on ARCH_S3C2410 || ARCH_S3C64XX help RTC (Realtime Clock) driver for the clock inbuilt into the Samsung S3C24XX series of SoCs. This can provide periodic diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 4969b6059c89..e5972b2c17b7 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -29,6 +29,11 @@ #include #include +enum s3c_cpu_type { + TYPE_S3C2410, + TYPE_S3C64XX, +}; + /* I have yet to find an S3C implementation with more than one * of these rtc blocks in */ @@ -37,6 +42,7 @@ static struct resource *s3c_rtc_mem; static void __iomem *s3c_rtc_base; static int s3c_rtc_alarmno = NO_IRQ; static int s3c_rtc_tickno = NO_IRQ; +static enum s3c_cpu_type s3c_rtc_cpu_type; static DEFINE_SPINLOCK(s3c_rtc_pie_lock); @@ -80,12 +86,25 @@ static int s3c_rtc_setpie(struct device *dev, int enabled) pr_debug("%s: pie=%d\n", __func__, enabled); spin_lock_irq(&s3c_rtc_pie_lock); - tmp = readb(s3c_rtc_base + S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE; - if (enabled) - tmp |= S3C2410_TICNT_ENABLE; + if (s3c_rtc_cpu_type == TYPE_S3C64XX) { + tmp = readb(s3c_rtc_base + S3C2410_RTCCON); + tmp &= ~S3C64XX_RTCCON_TICEN; + + if (enabled) + tmp |= S3C64XX_RTCCON_TICEN; + + writeb(tmp, s3c_rtc_base + S3C2410_RTCCON); + } else { + tmp = readb(s3c_rtc_base + S3C2410_TICNT); + tmp &= ~S3C2410_TICNT_ENABLE; + + if (enabled) + tmp |= S3C2410_TICNT_ENABLE; + + writeb(tmp, s3c_rtc_base + S3C2410_TICNT); + } - writeb(tmp, s3c_rtc_base + S3C2410_TICNT); spin_unlock_irq(&s3c_rtc_pie_lock); return 0; @@ -93,15 +112,21 @@ static int s3c_rtc_setpie(struct device *dev, int enabled) static int s3c_rtc_setfreq(struct device *dev, int freq) { - unsigned int tmp; + struct platform_device *pdev = to_platform_device(dev); + struct rtc_device *rtc_dev = platform_get_drvdata(pdev); + unsigned int tmp = 0; if (!is_power_of_2(freq)) return -EINVAL; spin_lock_irq(&s3c_rtc_pie_lock); - tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE; - tmp |= (128 / freq)-1; + if (s3c_rtc_cpu_type == TYPE_S3C2410) { + tmp = readb(s3c_rtc_base + S3C2410_TICNT); + tmp &= S3C2410_TICNT_ENABLE; + } + + tmp |= (rtc_dev->max_user_freq / freq)-1; writeb(tmp, s3c_rtc_base + S3C2410_TICNT); spin_unlock_irq(&s3c_rtc_pie_lock); @@ -283,10 +308,17 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) { - unsigned int ticnt = readb(s3c_rtc_base + S3C2410_TICNT); + unsigned int ticnt; - seq_printf(seq, "periodic_IRQ\t: %s\n", - (ticnt & S3C2410_TICNT_ENABLE) ? "yes" : "no" ); + if (s3c_rtc_cpu_type == TYPE_S3C64XX) { + ticnt = readb(s3c_rtc_base + S3C2410_RTCCON); + ticnt &= S3C64XX_RTCCON_TICEN; + } else { + ticnt = readb(s3c_rtc_base + S3C2410_TICNT); + ticnt &= S3C2410_TICNT_ENABLE; + } + + seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no"); return 0; } @@ -353,10 +385,16 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en) if (!en) { tmp = readb(base + S3C2410_RTCCON); - writeb(tmp & ~S3C2410_RTCCON_RTCEN, base + S3C2410_RTCCON); - - tmp = readb(base + S3C2410_TICNT); - writeb(tmp & ~S3C2410_TICNT_ENABLE, base + S3C2410_TICNT); + if (s3c_rtc_cpu_type == TYPE_S3C64XX) + tmp &= ~S3C64XX_RTCCON_TICEN; + tmp &= ~S3C2410_RTCCON_RTCEN; + writeb(tmp, base + S3C2410_RTCCON); + + if (s3c_rtc_cpu_type == TYPE_S3C2410) { + tmp = readb(base + S3C2410_TICNT); + tmp &= ~S3C2410_TICNT_ENABLE; + writeb(tmp, base + S3C2410_TICNT); + } } else { /* re-enable the device, and check it is ok */ @@ -472,7 +510,12 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) goto err_nortc; } - rtc->max_user_freq = 128; + if (s3c_rtc_cpu_type == TYPE_S3C64XX) + rtc->max_user_freq = 32768; + else + rtc->max_user_freq = 128; + + s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data; platform_set_drvdata(pdev, rtc); return 0; @@ -492,20 +535,30 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) /* RTC Power management control */ -static int ticnt_save; +static int ticnt_save, ticnt_en_save; static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) { /* save TICNT for anyone using periodic interrupts */ ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); + if (s3c_rtc_cpu_type == TYPE_S3C64XX) { + ticnt_en_save = readb(s3c_rtc_base + S3C2410_RTCCON); + ticnt_en_save &= S3C64XX_RTCCON_TICEN; + } s3c_rtc_enable(pdev, 0); return 0; } static int s3c_rtc_resume(struct platform_device *pdev) { + unsigned int tmp; + s3c_rtc_enable(pdev, 1); writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); + if (s3c_rtc_cpu_type == TYPE_S3C64XX && ticnt_en_save) { + tmp = readb(s3c_rtc_base + S3C2410_RTCCON); + writeb(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON); + } return 0; } #else @@ -513,13 +566,27 @@ static int s3c_rtc_resume(struct platform_device *pdev) #define s3c_rtc_resume NULL #endif -static struct platform_driver s3c2410_rtc_driver = { +static struct platform_device_id s3c_rtc_driver_ids[] = { + { + .name = "s3c2410-rtc", + .driver_data = TYPE_S3C2410, + }, { + .name = "s3c64xx-rtc", + .driver_data = TYPE_S3C64XX, + }, + { } +}; + +MODULE_DEVICE_TABLE(platform, s3c_rtc_driver_ids); + +static struct platform_driver s3c_rtc_driver = { .probe = s3c_rtc_probe, .remove = __devexit_p(s3c_rtc_remove), .suspend = s3c_rtc_suspend, .resume = s3c_rtc_resume, + .id_table = s3c_rtc_driver_ids, .driver = { - .name = "s3c2410-rtc", + .name = "s3c-rtc", .owner = THIS_MODULE, }, }; @@ -529,12 +596,12 @@ static char __initdata banner[] = "S3C24XX RTC, (c) 2004,2006 Simtec Electronics static int __init s3c_rtc_init(void) { printk(banner); - return platform_driver_register(&s3c2410_rtc_driver); + return platform_driver_register(&s3c_rtc_driver); } static void __exit s3c_rtc_exit(void) { - platform_driver_unregister(&s3c2410_rtc_driver); + platform_driver_unregister(&s3c_rtc_driver); } module_init(s3c_rtc_init); -- cgit v1.2.3 From 5cf8f57d44d16652336fabdd65e727a6e6f98cd5 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Mon, 24 May 2010 14:33:46 -0700 Subject: rtc-mxc: remove unnecessary clock source for rtc subsystem On imx SoCs rtc clock parent is CKIL, but clock rate shall be determined using rtc clock itself, that eliminates CKIL clock usage in the driver. Signed-off-by: Vladimir Zapolskiy Cc: Alessandro Zummo Cc: Daniel Mack Cc: Andrew Morton Cc: Paul Gortmaker Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-mxc.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index d71fe61db1d6..25ec921db07c 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -379,7 +379,6 @@ static struct rtc_class_ops mxc_rtc_ops = { static int __init mxc_rtc_probe(struct platform_device *pdev) { - struct clk *clk; struct resource *res; struct rtc_device *rtc; struct rtc_plat_data *pdata = NULL; @@ -402,14 +401,15 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) pdata->ioaddr = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - clk = clk_get(&pdev->dev, "ckil"); - if (IS_ERR(clk)) { - ret = PTR_ERR(clk); + pdata->clk = clk_get(&pdev->dev, "rtc"); + if (IS_ERR(pdata->clk)) { + dev_err(&pdev->dev, "unable to get clock!\n"); + ret = PTR_ERR(pdata->clk); goto exit_free_pdata; } - rate = clk_get_rate(clk); - clk_put(clk); + clk_enable(pdata->clk); + rate = clk_get_rate(pdata->clk); if (rate == 32768) reg = RTC_INPUT_CLK_32768HZ; @@ -420,7 +420,7 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) else { dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n", rate); ret = -EINVAL; - goto exit_free_pdata; + goto exit_put_clk; } reg |= RTC_ENABLE_BIT; @@ -428,18 +428,9 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) if (((readw(pdata->ioaddr + RTC_RTCCTL)) & RTC_ENABLE_BIT) == 0) { dev_err(&pdev->dev, "hardware module can't be enabled!\n"); ret = -EIO; - goto exit_free_pdata; - } - - pdata->clk = clk_get(&pdev->dev, "rtc"); - if (IS_ERR(pdata->clk)) { - dev_err(&pdev->dev, "unable to get clock!\n"); - ret = PTR_ERR(pdata->clk); - goto exit_free_pdata; + goto exit_put_clk; } - clk_enable(pdata->clk); - rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { -- cgit v1.2.3 From e17ab5cbed795d3823da830f5e8d3ffe25a38446 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 24 May 2010 14:33:46 -0700 Subject: rtc-isl1208: use sysfs_{create/remove}_group Instead of individually creating and removing the sysfs device attribute files, wrap them in an attribute_group and use sysfs_{create/remove}_group. Signed-off-by: H Hartley Sweeten Cc: Alessandro Zummo Cc: Paul Gortmaker Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-isl1208.c | 45 +++++++++++---------------------------------- 1 file changed, 11 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index 054e05294af8..468200c38ecb 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -462,39 +462,16 @@ isl1208_sysfs_store_usr(struct device *dev, static DEVICE_ATTR(usr, S_IRUGO | S_IWUSR, isl1208_sysfs_show_usr, isl1208_sysfs_store_usr); -static int -isl1208_sysfs_register(struct device *dev) -{ - int err; - - err = device_create_file(dev, &dev_attr_atrim); - if (err) - return err; - - err = device_create_file(dev, &dev_attr_dtrim); - if (err) { - device_remove_file(dev, &dev_attr_atrim); - return err; - } - - err = device_create_file(dev, &dev_attr_usr); - if (err) { - device_remove_file(dev, &dev_attr_atrim); - device_remove_file(dev, &dev_attr_dtrim); - } - - return 0; -} - -static int -isl1208_sysfs_unregister(struct device *dev) -{ - device_remove_file(dev, &dev_attr_dtrim); - device_remove_file(dev, &dev_attr_atrim); - device_remove_file(dev, &dev_attr_usr); +static struct attribute *isl1208_rtc_attrs[] = { + &dev_attr_atrim.attr, + &dev_attr_dtrim.attr, + &dev_attr_usr.attr, + NULL +}; - return 0; -} +static const struct attribute_group isl1208_rtc_sysfs_files = { + .attrs = isl1208_rtc_attrs, +}; static int isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) @@ -529,7 +506,7 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) dev_warn(&client->dev, "rtc power failure detected, " "please set clock.\n"); - rc = isl1208_sysfs_register(&client->dev); + rc = sysfs_create_group(&client->dev.kobj, &isl1208_rtc_sysfs_files); if (rc) goto exit_unregister; @@ -546,7 +523,7 @@ isl1208_remove(struct i2c_client *client) { struct rtc_device *rtc = i2c_get_clientdata(client); - isl1208_sysfs_unregister(&client->dev); + sysfs_remove_group(&client->dev.kobj, &isl1208_rtc_sysfs_files); rtc_device_unregister(rtc); return 0; -- cgit v1.2.3 From 72cc8e51cfdde9007adab7d841ac4113b05b2c56 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 24 May 2010 14:33:47 -0700 Subject: rtc-ds1302: add some abstraction for new platform support The current ds1302 driver (or at least the one that lives in /drivers/rtc) seems to be designed for memory mapped devices only. This make it quite hard to add support for GPIO-based implementations (as this is the case for the upcoming Arcom Vulcan). This patch moves the direct register access to inline functions with explicit names. Still not as good as a proper platform driver, but at least neater. Signed-off-by: Marc Zyngier Cc: Paul Gortmaker Cc: Alessandro Zummo Cc: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1302.c | 85 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index 532acf9b05d8..359d1e04626c 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c @@ -16,7 +16,6 @@ #include #include #include -#include #define DRV_NAME "rtc-ds1302" #define DRV_VERSION "0.1.1" @@ -34,14 +33,55 @@ #define RTC_ADDR_MIN 0x01 /* Address of minute register */ #define RTC_ADDR_SEC 0x00 /* Address of second register */ +#ifdef CONFIG_SH_SECUREEDGE5410 +#include +#include + #define RTC_RESET 0x1000 #define RTC_IODATA 0x0800 #define RTC_SCLK 0x0400 -#ifdef CONFIG_SH_SECUREEDGE5410 -#include #define set_dp(x) SECUREEDGE_WRITE_IOPORT(x, 0x1c00) #define get_dp() SECUREEDGE_READ_IOPORT() +#define ds1302_set_tx() +#define ds1302_set_rx() + +static inline int ds1302_hw_init(void) +{ + return 0; +} + +static inline void ds1302_reset(void) +{ + set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); +} + +static inline void ds1302_clock(void) +{ + set_dp(get_dp() | RTC_SCLK); /* clock high */ + set_dp(get_dp() & ~RTC_SCLK); /* clock low */ +} + +static inline void ds1302_start(void) +{ + set_dp(get_dp() | RTC_RESET); +} + +static inline void ds1302_stop(void) +{ + set_dp(get_dp() & ~RTC_RESET); +} + +static inline void ds1302_txbit(int bit) +{ + set_dp((get_dp() & ~RTC_IODATA) | (bit ? RTC_IODATA : 0)); +} + +static inline int ds1302_rxbit(void) +{ + return !!(get_dp() & RTC_IODATA); +} + #else #error "Add support for your platform" #endif @@ -50,11 +90,11 @@ static void ds1302_sendbits(unsigned int val) { int i; + ds1302_set_tx(); + for (i = 8; (i); i--, val >>= 1) { - set_dp((get_dp() & ~RTC_IODATA) | ((val & 0x1) ? - RTC_IODATA : 0)); - set_dp(get_dp() | RTC_SCLK); /* clock high */ - set_dp(get_dp() & ~RTC_SCLK); /* clock low */ + ds1302_txbit(val & 0x1); + ds1302_clock(); } } @@ -63,10 +103,11 @@ static unsigned int ds1302_recvbits(void) unsigned int val; int i; + ds1302_set_rx(); + for (i = 0, val = 0; (i < 8); i++) { - val |= (((get_dp() & RTC_IODATA) ? 1 : 0) << i); - set_dp(get_dp() | RTC_SCLK); /* clock high */ - set_dp(get_dp() & ~RTC_SCLK); /* clock low */ + val |= (ds1302_rxbit() << i); + ds1302_clock(); } return val; @@ -76,23 +117,24 @@ static unsigned int ds1302_readbyte(unsigned int addr) { unsigned int val; - set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); + ds1302_reset(); - set_dp(get_dp() | RTC_RESET); + ds1302_start(); ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ); val = ds1302_recvbits(); - set_dp(get_dp() & ~RTC_RESET); + ds1302_stop(); return val; } static void ds1302_writebyte(unsigned int addr, unsigned int val) { - set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); - set_dp(get_dp() | RTC_RESET); + ds1302_reset(); + + ds1302_start(); ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE); ds1302_sendbits(val); - set_dp(get_dp() & ~RTC_RESET); + ds1302_stop(); } static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm) @@ -167,13 +209,20 @@ static int __init ds1302_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; + if (ds1302_hw_init()) { + dev_err(&pdev->dev, "Failed to init communication channel"); + return -EINVAL; + } + /* Reset */ - set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); + ds1302_reset(); /* Write a magic value to the DS1302 RAM, and see if it sticks. */ ds1302_writebyte(RTC_ADDR_RAM0, 0x42); - if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42) + if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42) { + dev_err(&pdev->dev, "Failed to probe"); return -ENODEV; + } rtc = rtc_device_register("ds1302", &pdev->dev, &ds1302_rtc_ops, THIS_MODULE); -- cgit v1.2.3 From 6ba8bcd457d9fc793ac9435aa2e4138f571d4ec5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 24 May 2010 14:33:49 -0700 Subject: rtc-cmos: do dev_set_drvdata() earlier in the initialization The bug is an oops when dev_get_drvdata() returned null in cmos_update_irq_enable(). The call tree looks like this: rtc_dev_ioctl() => rtc_update_irq_enable() => cmos_update_irq_enable() It's caused by a race condition in the module initialization. It is rtc_device_register() which makes the ioctl operations live so I moved the call to dev_set_drvdata() before the call to rtc_device_register(). Addresses https://bugzilla.kernel.org/show_bug.cgi?id=15963 Reported-by: Randy Dunlap Signed-off-by: Dan Carpenter Tested-by: Randy Dunlap Cc: Alessandro Zummo Cc: Paul Gortmaker Cc: Malte Schroder Cc: Ralf Baechle Cc: Herton Ronaldo Krzesinski Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-cmos.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 96e8e70fbf1e..11b8ea29d2b7 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -719,6 +719,9 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) } } + cmos_rtc.dev = dev; + dev_set_drvdata(dev, &cmos_rtc); + cmos_rtc.rtc = rtc_device_register(driver_name, dev, &cmos_rtc_ops, THIS_MODULE); if (IS_ERR(cmos_rtc.rtc)) { @@ -726,8 +729,6 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) goto cleanup0; } - cmos_rtc.dev = dev; - dev_set_drvdata(dev, &cmos_rtc); rename_region(ports, dev_name(&cmos_rtc.rtc->dev)); spin_lock_irq(&rtc_lock); -- cgit v1.2.3 From 5815e5d36eff44b3dd38943f3a98a4d9ce985118 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 24 May 2010 14:33:51 -0700 Subject: rtc: use genirq directly in rtc-wm831x Now that the WM831x core uses genirq for the IRQ controller there is no need to use the WM831x-specific wrappers to request interrupts so convert to use genirq directly. Also use more meaningful strings to make /proc/interrupts more readily legible. Signed-off-by: Mark Brown Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-wm831x.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c index b16cfe57a484..82931dc65c0b 100644 --- a/drivers/rtc/rtc-wm831x.c +++ b/drivers/rtc/rtc-wm831x.c @@ -449,17 +449,17 @@ static int wm831x_rtc_probe(struct platform_device *pdev) goto err; } - ret = wm831x_request_irq(wm831x, per_irq, wm831x_per_irq, - IRQF_TRIGGER_RISING, "wm831x_rtc_per", - wm831x_rtc); + ret = request_threaded_irq(per_irq, NULL, wm831x_per_irq, + IRQF_TRIGGER_RISING, "RTC period", + wm831x_rtc); if (ret != 0) { dev_err(&pdev->dev, "Failed to request periodic IRQ %d: %d\n", per_irq, ret); } - ret = wm831x_request_irq(wm831x, alm_irq, wm831x_alm_irq, - IRQF_TRIGGER_RISING, "wm831x_rtc_alm", - wm831x_rtc); + ret = request_threaded_irq(alm_irq, NULL, wm831x_alm_irq, + IRQF_TRIGGER_RISING, "RTC alarm", + wm831x_rtc); if (ret != 0) { dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n", alm_irq, ret); @@ -478,8 +478,8 @@ static int __devexit wm831x_rtc_remove(struct platform_device *pdev) int per_irq = platform_get_irq_byname(pdev, "PER"); int alm_irq = platform_get_irq_byname(pdev, "ALM"); - wm831x_free_irq(wm831x_rtc->wm831x, alm_irq, wm831x_rtc); - wm831x_free_irq(wm831x_rtc->wm831x, per_irq, wm831x_rtc); + free_irq(alm_irq, wm831x_rtc); + free_irq(per_irq, wm831x_rtc); rtc_device_unregister(wm831x_rtc->rtc); kfree(wm831x_rtc); -- cgit v1.2.3 From fbd65e0ecdeffe5e50ad850fb7240888b1af6b22 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 24 May 2010 14:33:52 -0700 Subject: fbdev: bfin-lq035q1-fb: respect new PPI mode platform field This lets us support the new BF527-EZKIT V2.1 via platform resources tweaks only. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger Cc: Bryan Wu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/bfin-lq035q1-fb.c | 252 +++++++++++++++++++++++----------------- 1 file changed, 146 insertions(+), 106 deletions(-) (limited to 'drivers') diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/bfin-lq035q1-fb.c index 2baac7cc1425..c8e1f04941bd 100644 --- a/drivers/video/bfin-lq035q1-fb.c +++ b/drivers/video/bfin-lq035q1-fb.c @@ -61,47 +61,13 @@ #define LCD_X_RES 320 /* Horizontal Resolution */ #define LCD_Y_RES 240 /* Vertical Resolution */ #define DMA_BUS_SIZE 16 +#define U_LINE 4 /* Blanking Lines */ -#define USE_RGB565_16_BIT_PPI - -#ifdef USE_RGB565_16_BIT_PPI -#define LCD_BPP 16 /* Bit Per Pixel */ -#define CLOCKS_PER_PIX 1 -#define CPLD_PIPELINE_DELAY_COR 0 /* NO CPLB */ -#endif /* Interface 16/18-bit TFT over an 8-bit wide PPI using a small Programmable Logic Device (CPLD) * http://blackfin.uclinux.org/gf/project/stamp/frs/?action=FrsReleaseBrowse&frs_package_id=165 */ -#ifdef USE_RGB565_8_BIT_PPI -#define LCD_BPP 16 /* Bit Per Pixel */ -#define CLOCKS_PER_PIX 2 -#define CPLD_PIPELINE_DELAY_COR 3 /* RGB565 */ -#endif - -#ifdef USE_RGB888_8_BIT_PPI -#define LCD_BPP 24 /* Bit Per Pixel */ -#define CLOCKS_PER_PIX 3 -#define CPLD_PIPELINE_DELAY_COR 5 /* RGB888 */ -#endif - - /* - * HS and VS timing parameters (all in number of PPI clk ticks) - */ - -#define U_LINE 4 /* Blanking Lines */ - -#define H_ACTPIX (LCD_X_RES * CLOCKS_PER_PIX) /* active horizontal pixel */ -#define H_PERIOD (336 * CLOCKS_PER_PIX) /* HS period */ -#define H_PULSE (2 * CLOCKS_PER_PIX) /* HS pulse width */ -#define H_START (7 * CLOCKS_PER_PIX + CPLD_PIPELINE_DELAY_COR) /* first valid pixel */ - -#define V_LINES (LCD_Y_RES + U_LINE) /* total vertical lines */ -#define V_PULSE (2 * CLOCKS_PER_PIX) /* VS pulse width (1-5 H_PERIODs) */ -#define V_PERIOD (H_PERIOD * V_LINES) /* VS period */ - -#define ACTIVE_VIDEO_MEM_OFFSET ((U_LINE / 2) * LCD_X_RES * (LCD_BPP / 8)) #define BFIN_LCD_NBR_PALETTE_ENTRIES 256 @@ -110,12 +76,6 @@ #define PPI_PORT_CFG_01 0x10 #define PPI_POLS_1 0x8000 -#if (CLOCKS_PER_PIX > 1) -#define PPI_PMODE (DLEN_8 | PACK_EN) -#else -#define PPI_PMODE (DLEN_16) -#endif - #define LQ035_INDEX 0x74 #define LQ035_DATA 0x76 @@ -139,6 +99,15 @@ struct bfin_lq035q1fb_info { int irq; spinlock_t lock; /* lock */ u32 pseudo_pal[16]; + + u32 lcd_bpp; + u32 h_actpix; + u32 h_period; + u32 h_pulse; + u32 h_start; + u32 v_lines; + u32 v_pulse; + u32 v_period; }; static int nocursor; @@ -234,16 +203,69 @@ static int lq035q1_backlight(struct bfin_lq035q1fb_info *info, unsigned arg) return 0; } +static int bfin_lq035q1_calc_timing(struct bfin_lq035q1fb_info *fbi) +{ + unsigned long clocks_per_pix, cpld_pipeline_delay_cor; + + /* + * Interface 16/18-bit TFT over an 8-bit wide PPI using a small + * Programmable Logic Device (CPLD) + * http://blackfin.uclinux.org/gf/project/stamp/frs/?action=FrsReleaseBrowse&frs_package_id=165 + */ + + switch (fbi->disp_info->ppi_mode) { + case USE_RGB565_16_BIT_PPI: + fbi->lcd_bpp = 16; + clocks_per_pix = 1; + cpld_pipeline_delay_cor = 0; + break; + case USE_RGB565_8_BIT_PPI: + fbi->lcd_bpp = 16; + clocks_per_pix = 2; + cpld_pipeline_delay_cor = 3; + break; + case USE_RGB888_8_BIT_PPI: + fbi->lcd_bpp = 24; + clocks_per_pix = 3; + cpld_pipeline_delay_cor = 5; + break; + default: + return -EINVAL; + } + + /* + * HS and VS timing parameters (all in number of PPI clk ticks) + */ + + fbi->h_actpix = (LCD_X_RES * clocks_per_pix); /* active horizontal pixel */ + fbi->h_period = (336 * clocks_per_pix); /* HS period */ + fbi->h_pulse = (2 * clocks_per_pix); /* HS pulse width */ + fbi->h_start = (7 * clocks_per_pix + cpld_pipeline_delay_cor); /* first valid pixel */ + + fbi->v_lines = (LCD_Y_RES + U_LINE); /* total vertical lines */ + fbi->v_pulse = (2 * clocks_per_pix); /* VS pulse width (1-5 H_PERIODs) */ + fbi->v_period = (fbi->h_period * fbi->v_lines); /* VS period */ + + return 0; +} + static void bfin_lq035q1_config_ppi(struct bfin_lq035q1fb_info *fbi) { - bfin_write_PPI_DELAY(H_START); - bfin_write_PPI_COUNT(H_ACTPIX - 1); - bfin_write_PPI_FRAME(V_LINES); + unsigned ppi_pmode; + + if (fbi->disp_info->ppi_mode == USE_RGB565_16_BIT_PPI) + ppi_pmode = DLEN_16; + else + ppi_pmode = (DLEN_8 | PACK_EN); + + bfin_write_PPI_DELAY(fbi->h_start); + bfin_write_PPI_COUNT(fbi->h_actpix - 1); + bfin_write_PPI_FRAME(fbi->v_lines); bfin_write_PPI_CONTROL(PPI_TX_MODE | /* output mode , PORT_DIR */ PPI_XFER_TYPE_11 | /* sync mode XFR_TYPE */ PPI_PORT_CFG_01 | /* two frame sync PORT_CFG */ - PPI_PMODE | /* 8/16 bit data length / PACK_EN? */ + ppi_pmode | /* 8/16 bit data length / PACK_EN? */ PPI_POLS_1); /* faling edge syncs POLS */ } @@ -272,19 +294,19 @@ static void bfin_lq035q1_stop_timers(void) } -static void bfin_lq035q1_init_timers(void) +static void bfin_lq035q1_init_timers(struct bfin_lq035q1fb_info *fbi) { bfin_lq035q1_stop_timers(); - set_gptimer_period(TIMER_HSYNC_id, H_PERIOD); - set_gptimer_pwidth(TIMER_HSYNC_id, H_PULSE); + set_gptimer_period(TIMER_HSYNC_id, fbi->h_period); + set_gptimer_pwidth(TIMER_HSYNC_id, fbi->h_pulse); set_gptimer_config(TIMER_HSYNC_id, TIMER_MODE_PWM | TIMER_PERIOD_CNT | TIMER_TIN_SEL | TIMER_CLK_SEL| TIMER_EMU_RUN); - set_gptimer_period(TIMER_VSYNC_id, V_PERIOD); - set_gptimer_pwidth(TIMER_VSYNC_id, V_PULSE); + set_gptimer_period(TIMER_VSYNC_id, fbi->v_period); + set_gptimer_pwidth(TIMER_VSYNC_id, fbi->v_pulse); set_gptimer_config(TIMER_VSYNC_id, TIMER_MODE_PWM | TIMER_PERIOD_CNT | TIMER_TIN_SEL | TIMER_CLK_SEL | TIMER_EMU_RUN); @@ -294,21 +316,21 @@ static void bfin_lq035q1_init_timers(void) static void bfin_lq035q1_config_dma(struct bfin_lq035q1fb_info *fbi) { + set_dma_config(CH_PPI, set_bfin_dma_config(DIR_READ, DMA_FLOW_AUTO, INTR_DISABLE, DIMENSION_2D, DATA_SIZE_16, DMA_NOSYNC_KEEP_DMA_BUF)); - set_dma_x_count(CH_PPI, (LCD_X_RES * LCD_BPP) / DMA_BUS_SIZE); + set_dma_x_count(CH_PPI, (LCD_X_RES * fbi->lcd_bpp) / DMA_BUS_SIZE); set_dma_x_modify(CH_PPI, DMA_BUS_SIZE / 8); - set_dma_y_count(CH_PPI, V_LINES); + set_dma_y_count(CH_PPI, fbi->v_lines); set_dma_y_modify(CH_PPI, DMA_BUS_SIZE / 8); set_dma_start_addr(CH_PPI, (unsigned long)fbi->fb_buffer); } -#if (CLOCKS_PER_PIX == 1) static const u16 ppi0_req_16[] = {P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3, P_PPI0_D4, P_PPI0_D5, @@ -316,22 +338,27 @@ static const u16 ppi0_req_16[] = {P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, P_PPI0_D9, P_PPI0_D10, P_PPI0_D11, P_PPI0_D12, P_PPI0_D13, P_PPI0_D14, P_PPI0_D15, 0}; -#else -static const u16 ppi0_req_16[] = {P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, + +static const u16 ppi0_req_8[] = {P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3, P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7, 0}; -#endif -static inline void bfin_lq035q1_free_ports(void) +static inline void bfin_lq035q1_free_ports(unsigned ppi16) { - peripheral_free_list(ppi0_req_16); + if (ppi16) + peripheral_free_list(ppi0_req_16); + else + peripheral_free_list(ppi0_req_8); + if (ANOMALY_05000400) gpio_free(P_IDENT(P_PPI0_FS3)); } -static int __devinit bfin_lq035q1_request_ports(struct platform_device *pdev) +static int __devinit bfin_lq035q1_request_ports(struct platform_device *pdev, + unsigned ppi16) { + int ret; /* ANOMALY_05000400 - PPI Does Not Start Properly In Specific Mode: * Drive PPI_FS3 Low */ @@ -342,7 +369,12 @@ static int __devinit bfin_lq035q1_request_ports(struct platform_device *pdev) gpio_direction_output(P_IDENT(P_PPI0_FS3), 0); } - if (peripheral_request_list(ppi0_req_16, DRIVER_NAME)) { + if (ppi16) + ret = peripheral_request_list(ppi0_req_16, DRIVER_NAME); + else + ret = peripheral_request_list(ppi0_req_8, DRIVER_NAME); + + if (ret) { dev_err(&pdev->dev, "requesting peripherals failed\n"); return -EFAULT; } @@ -364,7 +396,7 @@ static int bfin_lq035q1_fb_open(struct fb_info *info, int user) bfin_lq035q1_config_dma(fbi); bfin_lq035q1_config_ppi(fbi); - bfin_lq035q1_init_timers(); + bfin_lq035q1_init_timers(fbi); /* start dma */ enable_dma(CH_PPI); @@ -402,12 +434,9 @@ static int bfin_lq035q1_fb_release(struct fb_info *info, int user) static int bfin_lq035q1_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { - switch (var->bits_per_pixel) { -#if (LCD_BPP == 24) - case 24:/* TRUECOLOUR, 16m */ -#else - case 16:/* DIRECTCOLOUR, 64k */ -#endif + struct bfin_lq035q1fb_info *fbi = info->par; + + if (var->bits_per_pixel == fbi->lcd_bpp) { var->red.offset = info->var.red.offset; var->green.offset = info->var.green.offset; var->blue.offset = info->var.blue.offset; @@ -420,8 +449,7 @@ static int bfin_lq035q1_fb_check_var(struct fb_var_screeninfo *var, var->red.msb_right = 0; var->green.msb_right = 0; var->blue.msb_right = 0; - break; - default: + } else { pr_debug("%s: depth not supported: %u BPP\n", __func__, var->bits_per_pixel); return -EINVAL; @@ -528,6 +556,7 @@ static int __devinit bfin_lq035q1_probe(struct platform_device *pdev) { struct bfin_lq035q1fb_info *info; struct fb_info *fbinfo; + u32 active_video_mem_offset; int ret; ret = request_dma(CH_PPI, DRIVER_NAME"_CH_PPI"); @@ -550,6 +579,12 @@ static int __devinit bfin_lq035q1_probe(struct platform_device *pdev) platform_set_drvdata(pdev, fbinfo); + ret = bfin_lq035q1_calc_timing(info); + if (ret < 0) { + dev_err(&pdev->dev, "Failed PPI Mode\n"); + goto out3; + } + strcpy(fbinfo->fix.id, DRIVER_NAME); fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; @@ -571,46 +606,48 @@ static int __devinit bfin_lq035q1_probe(struct platform_device *pdev) fbinfo->var.xres_virtual = LCD_X_RES; fbinfo->var.yres = LCD_Y_RES; fbinfo->var.yres_virtual = LCD_Y_RES; - fbinfo->var.bits_per_pixel = LCD_BPP; + fbinfo->var.bits_per_pixel = info->lcd_bpp; if (info->disp_info->mode & LQ035_BGR) { -#if (LCD_BPP == 24) - fbinfo->var.red.offset = 0; - fbinfo->var.green.offset = 8; - fbinfo->var.blue.offset = 16; -#else - fbinfo->var.red.offset = 0; - fbinfo->var.green.offset = 5; - fbinfo->var.blue.offset = 11; -#endif + if (info->lcd_bpp == 24) { + fbinfo->var.red.offset = 0; + fbinfo->var.green.offset = 8; + fbinfo->var.blue.offset = 16; + } else { + fbinfo->var.red.offset = 0; + fbinfo->var.green.offset = 5; + fbinfo->var.blue.offset = 11; + } } else { -#if (LCD_BPP == 24) - fbinfo->var.red.offset = 16; - fbinfo->var.green.offset = 8; - fbinfo->var.blue.offset = 0; -#else - fbinfo->var.red.offset = 11; - fbinfo->var.green.offset = 5; - fbinfo->var.blue.offset = 0; -#endif + if (info->lcd_bpp == 24) { + fbinfo->var.red.offset = 16; + fbinfo->var.green.offset = 8; + fbinfo->var.blue.offset = 0; + } else { + fbinfo->var.red.offset = 11; + fbinfo->var.green.offset = 5; + fbinfo->var.blue.offset = 0; + } } fbinfo->var.transp.offset = 0; -#if (LCD_BPP == 24) - fbinfo->var.red.length = 8; - fbinfo->var.green.length = 8; - fbinfo->var.blue.length = 8; -#else - fbinfo->var.red.length = 5; - fbinfo->var.green.length = 6; - fbinfo->var.blue.length = 5; -#endif + if (info->lcd_bpp == 24) { + fbinfo->var.red.length = 8; + fbinfo->var.green.length = 8; + fbinfo->var.blue.length = 8; + } else { + fbinfo->var.red.length = 5; + fbinfo->var.green.length = 6; + fbinfo->var.blue.length = 5; + } fbinfo->var.transp.length = 0; - fbinfo->fix.smem_len = LCD_X_RES * LCD_Y_RES * LCD_BPP / 8 - + ACTIVE_VIDEO_MEM_OFFSET; + active_video_mem_offset = ((U_LINE / 2) * LCD_X_RES * (info->lcd_bpp / 8)); + + fbinfo->fix.smem_len = LCD_X_RES * LCD_Y_RES * info->lcd_bpp / 8 + + active_video_mem_offset; fbinfo->fix.line_length = fbinfo->var.xres_virtual * fbinfo->var.bits_per_pixel / 8; @@ -629,8 +666,8 @@ static int __devinit bfin_lq035q1_probe(struct platform_device *pdev) goto out3; } - fbinfo->screen_base = (void *)info->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET; - fbinfo->fix.smem_start = (int)info->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET; + fbinfo->screen_base = (void *)info->fb_buffer + active_video_mem_offset; + fbinfo->fix.smem_start = (int)info->fb_buffer + active_video_mem_offset; fbinfo->fbops = &bfin_lq035q1_fb_ops; @@ -643,7 +680,8 @@ static int __devinit bfin_lq035q1_probe(struct platform_device *pdev) goto out4; } - ret = bfin_lq035q1_request_ports(pdev); + ret = bfin_lq035q1_request_ports(pdev, + info->disp_info->ppi_mode == USE_RGB565_16_BIT_PPI); if (ret) { dev_err(&pdev->dev, "couldn't request gpio port\n"); goto out6; @@ -693,7 +731,7 @@ static int __devinit bfin_lq035q1_probe(struct platform_device *pdev) } dev_info(&pdev->dev, "%dx%d %d-bit RGB FrameBuffer initialized\n", - LCD_X_RES, LCD_Y_RES, LCD_BPP); + LCD_X_RES, LCD_Y_RES, info->lcd_bpp); return 0; @@ -705,7 +743,8 @@ static int __devinit bfin_lq035q1_probe(struct platform_device *pdev) out8: free_irq(info->irq, info); out7: - bfin_lq035q1_free_ports(); + bfin_lq035q1_free_ports(info->disp_info->ppi_mode == + USE_RGB565_16_BIT_PPI); out6: fb_dealloc_cmap(&fbinfo->cmap); out4: @@ -742,7 +781,8 @@ static int __devexit bfin_lq035q1_remove(struct platform_device *pdev) fb_dealloc_cmap(&fbinfo->cmap); - bfin_lq035q1_free_ports(); + bfin_lq035q1_free_ports(info->disp_info->ppi_mode == + USE_RGB565_16_BIT_PPI); platform_set_drvdata(pdev, NULL); framebuffer_release(fbinfo); @@ -781,7 +821,7 @@ static int bfin_lq035q1_resume(struct device *dev) bfin_lq035q1_config_dma(info); bfin_lq035q1_config_ppi(info); - bfin_lq035q1_init_timers(); + bfin_lq035q1_init_timers(info); /* start dma */ enable_dma(CH_PPI); -- cgit v1.2.3 From dbd536bf2f1b494240b56035ee16eba2e3d89b6a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 24 May 2010 14:33:53 -0700 Subject: sis: strcpy() => strlcpy() These are different size buffers (40 chars vs 16), we may as well be cautious. Signed-off-by: Dan Carpenter Cc: Thomas Winischhofer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/sis/sis_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index a531a0f7cdf2..559bf1727a2b 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c @@ -1845,7 +1845,7 @@ sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info) memset(fix, 0, sizeof(struct fb_fix_screeninfo)); - strcpy(fix->id, ivideo->myid); + strlcpy(fix->id, ivideo->myid, sizeof(fix->id)); mutex_lock(&info->mm_lock); fix->smem_start = ivideo->video_base + ivideo->video_offset; -- cgit v1.2.3 From bd9b5caf8616501d2ab6f17210b11f81ea7546eb Mon Sep 17 00:00:00 2001 From: Henrik Kretzschmar Date: Mon, 24 May 2010 14:33:54 -0700 Subject: fbdev: section cleanup in arcfb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the sections in the arcfb driver, by moving: * the variables arcfb_fix and arcfb_var from .init.data to .devinit.data * arcfb_remove() from .text to .devexit.text This fixes the following warnings issued by modpost: WARNING: drivers/video/built-in.o(.devinit.text+0x543): Section mismatch in reference from the function arcfb_probe() to the variable .init.data:arcfb_var The function __devinit arcfb_probe() references a variable __initdata arcfb_var. If arcfb_var is only used by arcfb_probe then annotate arcfb_var with a matching annotation. WARNING: drivers/video/built-in.o(.devinit.text+0x558): Section mismatch in reference from the function arcfb_probe() to the variable .init.data:arcfb_fix The function __devinit arcfb_probe() references a variable __initdata arcfb_fix. If arcfb_fix is only used by arcfb_probe then annotate arcfb_fix with a matching annotation. Signed-off-by: Henrik Kretzschmar Acked-by: Uwe Kleine-König Cc: [if "platform-drivers: move probe to .devinit.text in drivers/video" was merged] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/arcfb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c index 8d406fb689c1..f3d7440f0072 100644 --- a/drivers/video/arcfb.c +++ b/drivers/video/arcfb.c @@ -80,7 +80,7 @@ struct arcfb_par { spinlock_t lock; }; -static struct fb_fix_screeninfo arcfb_fix __initdata = { +static struct fb_fix_screeninfo arcfb_fix __devinitdata = { .id = "arcfb", .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_MONO01, @@ -90,7 +90,7 @@ static struct fb_fix_screeninfo arcfb_fix __initdata = { .accel = FB_ACCEL_NONE, }; -static struct fb_var_screeninfo arcfb_var __initdata = { +static struct fb_var_screeninfo arcfb_var __devinitdata = { .xres = 128, .yres = 64, .xres_virtual = 128, @@ -588,7 +588,7 @@ err: return retval; } -static int arcfb_remove(struct platform_device *dev) +static int __devexit arcfb_remove(struct platform_device *dev) { struct fb_info *info = platform_get_drvdata(dev); @@ -602,7 +602,7 @@ static int arcfb_remove(struct platform_device *dev) static struct platform_driver arcfb_driver = { .probe = arcfb_probe, - .remove = arcfb_remove, + .remove = __devexit_p(arcfb_remove), .driver = { .name = "arcfb", }, -- cgit v1.2.3 From e217e6e39f62e47f7e659b715235dbd57df480f8 Mon Sep 17 00:00:00 2001 From: Henrik Kretzschmar Date: Mon, 24 May 2010 14:33:56 -0700 Subject: fbdev: section cleanup in hgafb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix up the sections in the hgafb driver, by * moving hga_default_var and hga_fix from .init.data to .devinit.data * moving hga_detect() from .init.text to .devinit.text * moving hga_fb_remove() from .text to .devexit.text This fixes the following warnings issued by modpost: WARNING: drivers/video/hgafb.o(.devinit.text+0x18): Section mismatch in referenc e from the function hgafb_probe() to the function .init.text:hga_card_detect() The function __devinit hgafb_probe() references a function __init hga_card_detect(). If hga_card_detect is only used by hgafb_probe then annotate hga_card_detect with a matching annotation. WARNING: drivers/video/hgafb.o(.devinit.text+0xfe): Section mismatch in referenc e from the function hgafb_probe() to the variable .init.data:hga_fix The function __devinit hgafb_probe() references a variable __initdata hga_fix. If hga_fix is only used by hgafb_probe then annotate hga_fix with a matching annotation. WARNING: drivers/video/hgafb.o(.devinit.text+0x105): Section mismatch in reference from the function hgafb_probe() to the variable .init.data:hga_default_var The function __devinit hgafb_probe() references a variable __initdata hga_default_var. If hga_default_var is only used by hgafb_probe then annotate hga_default_var with a matching annotation. Signed-off-by: Henrik Kretzschmar Acked-by: Uwe Kleine-König Cc: [if "platform-drivers: move probe to .devinit.text in drivers/video" was merged] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/hgafb.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/video/hgafb.c b/drivers/video/hgafb.c index 8bbf251f83d9..af8f0f2cc782 100644 --- a/drivers/video/hgafb.c +++ b/drivers/video/hgafb.c @@ -106,7 +106,7 @@ static DEFINE_SPINLOCK(hga_reg_lock); /* Framebuffer driver structures */ -static struct fb_var_screeninfo __initdata hga_default_var = { +static struct fb_var_screeninfo hga_default_var __devinitdata = { .xres = 720, .yres = 348, .xres_virtual = 720, @@ -120,7 +120,7 @@ static struct fb_var_screeninfo __initdata hga_default_var = { .width = -1, }; -static struct fb_fix_screeninfo __initdata hga_fix = { +static struct fb_fix_screeninfo hga_fix __devinitdata = { .id = "HGA", .type = FB_TYPE_PACKED_PIXELS, /* (not sure) */ .visual = FB_VISUAL_MONO10, @@ -276,7 +276,7 @@ static void hga_blank(int blank_mode) spin_unlock_irqrestore(&hga_reg_lock, flags); } -static int __init hga_card_detect(void) +static int __devinit hga_card_detect(void) { int count = 0; void __iomem *p, *q; @@ -596,7 +596,7 @@ static int __devinit hgafb_probe(struct platform_device *pdev) return 0; } -static int hgafb_remove(struct platform_device *pdev) +static int __devexit hgafb_remove(struct platform_device *pdev) { struct fb_info *info = platform_get_drvdata(pdev); @@ -621,7 +621,7 @@ static int hgafb_remove(struct platform_device *pdev) static struct platform_driver hgafb_driver = { .probe = hgafb_probe, - .remove = hgafb_remove, + .remove = __devexit_p(hgafb_remove), .driver = { .name = "hgafb", }, -- cgit v1.2.3 From 3cc04971661e37e7de6fbf9808ede554b5e1cb4e Mon Sep 17 00:00:00 2001 From: Henrik Kretzschmar Date: Mon, 24 May 2010 14:33:57 -0700 Subject: fbdev: section cleanup in vfb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix up the section in the vfb driver, by moving the variables vfb_default and vfb_fix from .init.data to .devinit.data This fixes the following warnings issued by modpost: WARNING: drivers/video/vfb.o(.devinit.text+0xf8): Section mismatch in reference from the function vfb_probe() to the variable .init.data:vfb_default The function __devinit vfb_probe() references a variable __initdata vfb_default. If vfb_default is only used by vfb_probe then annotate vfb_default with a matching annotation. WARNING: drivers/video/vfb.o(.devinit.text+0x114): Section mismatch in reference from the function vfb_probe() to the variable .init.data:vfb_fix The function __devinit vfb_probe() references a variable __initdata vfb_fix. If vfb_fix is only used by vfb_probe then annotate vfb_fix with a matching annotation. Signed-off-by: Henrik Kretzschmar Acked-by: Uwe Kleine-König Cc: [if "platform-drivers: move probe to .devinit.text in drivers/video" was merged] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/vfb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c index 9b5532b4de35..bc67251f1a2f 100644 --- a/drivers/video/vfb.c +++ b/drivers/video/vfb.c @@ -78,7 +78,7 @@ static void rvfree(void *mem, unsigned long size) vfree(mem); } -static struct fb_var_screeninfo vfb_default __initdata = { +static struct fb_var_screeninfo vfb_default __devinitdata = { .xres = 640, .yres = 480, .xres_virtual = 640, @@ -100,7 +100,7 @@ static struct fb_var_screeninfo vfb_default __initdata = { .vmode = FB_VMODE_NONINTERLACED, }; -static struct fb_fix_screeninfo vfb_fix __initdata = { +static struct fb_fix_screeninfo vfb_fix __devinitdata = { .id = "Virtual FB", .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_PSEUDOCOLOR, -- cgit v1.2.3 From ad1458464cbbe6935be6e20d70920301733158af Mon Sep 17 00:00:00 2001 From: Henrik Kretzschmar Date: Mon, 24 May 2010 14:33:59 -0700 Subject: fbdev: section cleanup in vga16fb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix up the sections in the vga16fb driver, by moving: * the variables vga16_defined and vga16fb from .init.data to .devinit.data * vga16fb_setup() from .text to .init.text * vga16fb_remove() from .text. to .devexit.text This fixes the following warnings issued by modpost: WARNING: drivers/video/built-in.o(.devinit.text+0x1a420): Section mismatch in re ference from the function vga16fb_probe() to the (unknown reference) .init.data: (unknown) The function __devinit vga16fb_probe() references a (unknown reference) __initdata (unknown). If (unknown) is only used by vga16fb_probe then annotate (unknown) with a matching annotation. WARNING: drivers/video/built-in.o(.devinit.text+0x1a437): Section mismatch in reference from the function vga16fb_probe() to the variable .init.data:vga16fb_defined The function __devinit vga16fb_probe() references a variable __initdata vga16fb_defined. If vga16fb_defined is only used by vga16fb_probe then annotate vga16fb_defined with a matching annotation. WARNING: drivers/video/built-in.o(.devinit.text+0x1a457): Section mismatch in reference from the function vga16fb_probe() to the variable .init.data:vga16fb_fix The function __devinit vga16fb_probe() references a variable __initdata vga16fb_fix. If vga16fb_fix is only used by vga16fb_probe then annotate vga16fb_fix with a matching annotation. Signed-off-by: Henrik Kretzschmar Acked-by: Uwe Kleine-König Cc: [if "platform-drivers: move probe to .devinit.text in drivers/video" was merged] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/vga16fb.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c index 149c47ac7e93..28ccab44a391 100644 --- a/drivers/video/vga16fb.c +++ b/drivers/video/vga16fb.c @@ -65,7 +65,7 @@ struct vga16fb_par { /* --------------------------------------------------------------------- */ -static struct fb_var_screeninfo vga16fb_defined __initdata = { +static struct fb_var_screeninfo vga16fb_defined __devinitdata = { .xres = 640, .yres = 480, .xres_virtual = 640, @@ -85,7 +85,7 @@ static struct fb_var_screeninfo vga16fb_defined __initdata = { }; /* name should not depend on EGA/VGA */ -static struct fb_fix_screeninfo vga16fb_fix __initdata = { +static struct fb_fix_screeninfo vga16fb_fix __devinitdata = { .id = "VGA16 VGA", .smem_start = VGA_FB_PHYS, .smem_len = VGA_FB_PHYS_LEN, @@ -1287,7 +1287,7 @@ static struct fb_ops vga16fb_ops = { }; #ifndef MODULE -static int vga16fb_setup(char *options) +static int __init vga16fb_setup(char *options) { char *this_opt; @@ -1393,7 +1393,7 @@ static int __devinit vga16fb_probe(struct platform_device *dev) return ret; } -static int vga16fb_remove(struct platform_device *dev) +static int __devexit vga16fb_remove(struct platform_device *dev) { struct fb_info *info = platform_get_drvdata(dev); @@ -1405,7 +1405,7 @@ static int vga16fb_remove(struct platform_device *dev) static struct platform_driver vga16fb_driver = { .probe = vga16fb_probe, - .remove = vga16fb_remove, + .remove = __devexit_p(vga16fb_remove), .driver = { .name = "vga16fb", }, -- cgit v1.2.3 From fb6cb3270af8f2ad3dd556906a9c52aa85754849 Mon Sep 17 00:00:00 2001 From: Henrik Kretzschmar Date: Mon, 24 May 2010 14:34:00 -0700 Subject: fbdev: section cleanup in w100fb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix up the section in the w100fb driver, by moving: * w100fb_remove() from .text to .devexit.text * w100_get_xtal_table() from .text to .devinit.text * w100fb_init() from .devinit.text to .init.text Signed-off-by: Henrik Kretzschmar Acked-by: Uwe Kleine-König Cc: [if "platform-drivers: move probe to .devinit.text in drivers/video" was merged] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/w100fb.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c index 31b0e17ed090..e66b8b19ce5d 100644 --- a/drivers/video/w100fb.c +++ b/drivers/video/w100fb.c @@ -53,7 +53,7 @@ static void w100_update_enable(void); static void w100_update_disable(void); static void calc_hsync(struct w100fb_par *par); static void w100_init_graphic_engine(struct w100fb_par *par); -struct w100_pll_info *w100_get_xtal_table(unsigned int freq); +struct w100_pll_info *w100_get_xtal_table(unsigned int freq) __devinit; /* Pseudo palette size */ #define MAX_PALETTES 16 @@ -782,7 +782,7 @@ out: } -static int w100fb_remove(struct platform_device *pdev) +static int __devexit w100fb_remove(struct platform_device *pdev) { struct fb_info *info = platform_get_drvdata(pdev); struct w100fb_par *par=info->par; @@ -1020,7 +1020,7 @@ static struct pll_entries { { 0 }, }; -struct w100_pll_info *w100_get_xtal_table(unsigned int freq) +struct w100_pll_info __devinit *w100_get_xtal_table(unsigned int freq) { struct pll_entries *pll_entry = w100_pll_tables; @@ -1611,7 +1611,7 @@ static void w100_vsync(void) static struct platform_driver w100fb_driver = { .probe = w100fb_probe, - .remove = w100fb_remove, + .remove = __devexit_p(w100fb_remove), .suspend = w100fb_suspend, .resume = w100fb_resume, .driver = { @@ -1619,7 +1619,7 @@ static struct platform_driver w100fb_driver = { }, }; -int __devinit w100fb_init(void) +int __init w100fb_init(void) { return platform_driver_register(&w100fb_driver); } -- cgit v1.2.3 From 1f9c3e1f07e39c8af3bf42236fc553b5bb0f83f1 Mon Sep 17 00:00:00 2001 From: Martin Ambrose Date: Mon, 24 May 2010 14:34:01 -0700 Subject: fbdev: da8xx/omap-l1xx: implement double buffering This work includes the following: - Implement handler for FBIO_WAITFORVSYNC ioctl. - Allocate the data and palette buffers separately. A consequence of this is that the palette and data loading is now done in different phases. And that the LCD must be disabled temporarily after the palette is loaded but this will only happen once after init and each time the palette is changed. I think this is OK. - Allocate two (ping and pong) framebuffers from memory. - Add pan_display handler which toggles the LCDC DMA registers between the ping and pong buffers. Signed-off-by: Martin Ambrose Cc: Chaithrika U S Cc: Sudhakar Rajashekhara Cc: Krzysztof Helt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/da8xx-fb.c | 301 ++++++++++++++++++++++++++++++++++++----------- include/video/da8xx-fb.h | 1 + 2 files changed, 235 insertions(+), 67 deletions(-) (limited to 'drivers') diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 8d244ba0f601..cad7d45c8bac 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -36,7 +36,9 @@ #define DRIVER_NAME "da8xx_lcdc" /* LCD Status Register */ +#define LCD_END_OF_FRAME1 BIT(9) #define LCD_END_OF_FRAME0 BIT(8) +#define LCD_PL_LOAD_DONE BIT(6) #define LCD_FIFO_UNDERFLOW BIT(5) #define LCD_SYNC_LOST BIT(2) @@ -58,11 +60,13 @@ #define LCD_PALETTE_LOAD_MODE(x) ((x) << 20) #define PALETTE_AND_DATA 0x00 #define PALETTE_ONLY 0x01 +#define DATA_ONLY 0x02 #define LCD_MONO_8BIT_MODE BIT(9) #define LCD_RASTER_ORDER BIT(8) #define LCD_TFT_MODE BIT(7) #define LCD_UNDERFLOW_INT_ENA BIT(6) +#define LCD_PL_ENABLE BIT(4) #define LCD_MONOCHROME_MODE BIT(1) #define LCD_RASTER_ENABLE BIT(0) #define LCD_TFT_ALT_ENABLE BIT(23) @@ -87,6 +91,10 @@ #define LCD_DMA_CTRL_REG 0x40 #define LCD_DMA_FRM_BUF_BASE_ADDR_0_REG 0x44 #define LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG 0x48 +#define LCD_DMA_FRM_BUF_BASE_ADDR_1_REG 0x4C +#define LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG 0x50 + +#define LCD_NUM_BUFFERS 2 #define WSI_TIMEOUT 50 #define PALETTE_SIZE 256 @@ -111,13 +119,20 @@ static inline void lcdc_write(unsigned int val, unsigned int addr) struct da8xx_fb_par { resource_size_t p_palette_base; unsigned char *v_palette_base; + dma_addr_t vram_phys; + unsigned long vram_size; + void *vram_virt; + unsigned int dma_start; + unsigned int dma_end; struct clk *lcdc_clk; int irq; unsigned short pseudo_palette[16]; - unsigned int databuf_sz; unsigned int palette_sz; unsigned int pxl_clk; int blank; + wait_queue_head_t vsync_wait; + int vsync_flag; + int vsync_timeout; #ifdef CONFIG_CPU_FREQ struct notifier_block freq_transition; #endif @@ -148,9 +163,9 @@ static struct fb_fix_screeninfo da8xx_fb_fix __devinitdata = { .type = FB_TYPE_PACKED_PIXELS, .type_aux = 0, .visual = FB_VISUAL_PSEUDOCOLOR, - .xpanstep = 1, + .xpanstep = 0, .ypanstep = 1, - .ywrapstep = 1, + .ywrapstep = 0, .accel = FB_ACCEL_NONE }; @@ -221,22 +236,48 @@ static inline void lcd_disable_raster(void) static void lcd_blit(int load_mode, struct da8xx_fb_par *par) { - u32 tmp = par->p_palette_base + par->databuf_sz - 4; - u32 reg; + u32 start; + u32 end; + u32 reg_ras; + u32 reg_dma; + + /* init reg to clear PLM (loading mode) fields */ + reg_ras = lcdc_read(LCD_RASTER_CTRL_REG); + reg_ras &= ~(3 << 20); + + reg_dma = lcdc_read(LCD_DMA_CTRL_REG); + + if (load_mode == LOAD_DATA) { + start = par->dma_start; + end = par->dma_end; + + reg_ras |= LCD_PALETTE_LOAD_MODE(DATA_ONLY); + reg_dma |= LCD_END_OF_FRAME_INT_ENA; + reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE; + + lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG); + lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG); + lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_1_REG); + lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG); + } else if (load_mode == LOAD_PALETTE) { + start = par->p_palette_base; + end = start + par->palette_sz - 1; + + reg_ras |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY); + reg_ras |= LCD_PL_ENABLE; + + lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG); + lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG); + } - /* Update the databuf in the hw. */ - lcdc_write(par->p_palette_base, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG); - lcdc_write(tmp, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG); + lcdc_write(reg_dma, LCD_DMA_CTRL_REG); + lcdc_write(reg_ras, LCD_RASTER_CTRL_REG); - /* Start the DMA. */ - reg = lcdc_read(LCD_RASTER_CTRL_REG); - reg &= ~(3 << 20); - if (load_mode == LOAD_DATA) - reg |= LCD_PALETTE_LOAD_MODE(PALETTE_AND_DATA); - else if (load_mode == LOAD_PALETTE) - reg |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY); - - lcdc_write(reg, LCD_RASTER_CTRL_REG); + /* + * The Raster enable bit must be set after all other control fields are + * set. + */ + lcd_enable_raster(); } /* Configure the Burst Size of DMA */ @@ -368,12 +409,8 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg) static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height, u32 bpp, u32 raster_order) { - u32 bpl, reg; + u32 reg; - /* Disable Dual Frame Buffer. */ - reg = lcdc_read(LCD_DMA_CTRL_REG); - lcdc_write(reg & ~LCD_DUAL_FRAME_BUFFER_ENABLE, - LCD_DMA_CTRL_REG); /* Set the Panel Width */ /* Pixels per line = (PPL + 1)*16 */ /*0x3F in bits 4..9 gives max horisontal resolution = 1024 pixels*/ @@ -410,9 +447,6 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height, return -EINVAL; } - bpl = width * bpp / 8; - par->databuf_sz = height * bpl + par->palette_sz; - return 0; } @@ -421,8 +455,9 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, struct fb_info *info) { struct da8xx_fb_par *par = info->par; - unsigned short *palette = (unsigned short *)par->v_palette_base; + unsigned short *palette = (unsigned short *) par->v_palette_base; u_short pal; + int update_hw = 0; if (regno > 255) return 1; @@ -439,8 +474,10 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, pal |= (green & 0x00f0); pal |= (blue & 0x000f); - palette[regno] = pal; - + if (palette[regno] != pal) { + update_hw = 1; + palette[regno] = pal; + } } else if ((info->var.bits_per_pixel == 16) && regno < 16) { red >>= (16 - info->var.red.length); red <<= info->var.red.offset; @@ -453,9 +490,16 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, par->pseudo_palette[regno] = red | green | blue; - palette[0] = 0x4000; + if (palette[0] != 0x4000) { + update_hw = 1; + palette[0] = 0x4000; + } } + /* Update the palette in the h/w as needed. */ + if (update_hw) + lcd_blit(LOAD_PALETTE, par); + return 0; } @@ -541,15 +585,54 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, static irqreturn_t lcdc_irq_handler(int irq, void *arg) { + struct da8xx_fb_par *par = arg; u32 stat = lcdc_read(LCD_STAT_REG); + u32 reg_ras; if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { lcd_disable_raster(); lcdc_write(stat, LCD_STAT_REG); lcd_enable_raster(); - } else + } else if (stat & LCD_PL_LOAD_DONE) { + /* + * Must disable raster before changing state of any control bit. + * And also must be disabled before clearing the PL loading + * interrupt via the following write to the status register. If + * this is done after then one gets multiple PL done interrupts. + */ + lcd_disable_raster(); + lcdc_write(stat, LCD_STAT_REG); + /* Disable PL completion inerrupt */ + reg_ras = lcdc_read(LCD_RASTER_CTRL_REG); + reg_ras &= ~LCD_PL_ENABLE; + lcdc_write(reg_ras, LCD_RASTER_CTRL_REG); + + /* Setup and start data loading mode */ + lcd_blit(LOAD_DATA, par); + } else { + lcdc_write(stat, LCD_STAT_REG); + + if (stat & LCD_END_OF_FRAME0) { + lcdc_write(par->dma_start, + LCD_DMA_FRM_BUF_BASE_ADDR_0_REG); + lcdc_write(par->dma_end, + LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG); + par->vsync_flag = 1; + wake_up_interruptible(&par->vsync_wait); + } + + if (stat & LCD_END_OF_FRAME1) { + lcdc_write(par->dma_start, + LCD_DMA_FRM_BUF_BASE_ADDR_1_REG); + lcdc_write(par->dma_end, + LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG); + par->vsync_flag = 1; + wake_up_interruptible(&par->vsync_wait); + } + } + return IRQ_HANDLED; } @@ -654,9 +737,10 @@ static int __devexit fb_remove(struct platform_device *dev) unregister_framebuffer(info); fb_dealloc_cmap(&info->cmap); - dma_free_coherent(NULL, par->databuf_sz + PAGE_SIZE, - info->screen_base - PAGE_SIZE, - info->fix.smem_start); + dma_free_coherent(NULL, PALETTE_SIZE, par->v_palette_base, + par->p_palette_base); + dma_free_coherent(NULL, par->vram_size, par->vram_virt, + par->vram_phys); free_irq(par->irq, par); clk_disable(par->lcdc_clk); clk_put(par->lcdc_clk); @@ -668,6 +752,39 @@ static int __devexit fb_remove(struct platform_device *dev) return 0; } +/* + * Function to wait for vertical sync which for this LCD peripheral + * translates into waiting for the current raster frame to complete. + */ +static int fb_wait_for_vsync(struct fb_info *info) +{ + struct da8xx_fb_par *par = info->par; + int ret; + + /* + * Set flag to 0 and wait for isr to set to 1. It would seem there is a + * race condition here where the ISR could have occured just before or + * just after this set. But since we are just coarsely waiting for + * a frame to complete then that's OK. i.e. if the frame completed + * just before this code executed then we have to wait another full + * frame time but there is no way to avoid such a situation. On the + * other hand if the frame completed just after then we don't need + * to wait long at all. Either way we are guaranteed to return to the + * user immediately after a frame completion which is all that is + * required. + */ + par->vsync_flag = 0; + ret = wait_event_interruptible_timeout(par->vsync_wait, + par->vsync_flag != 0, + par->vsync_timeout); + if (ret < 0) + return ret; + if (ret == 0) + return -ETIMEDOUT; + + return 0; +} + static int fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) { @@ -697,6 +814,8 @@ static int fb_ioctl(struct fb_info *info, unsigned int cmd, sync_arg.pulse_width, sync_arg.front_porch); break; + case FBIO_WAITFORVSYNC: + return fb_wait_for_vsync(info); default: return -EINVAL; } @@ -732,10 +851,47 @@ static int cfb_blank(int blank, struct fb_info *info) return ret; } +/* + * Set new x,y offsets in the virtual display for the visible area and switch + * to the new mode. + */ +static int da8xx_pan_display(struct fb_var_screeninfo *var, + struct fb_info *fbi) +{ + int ret = 0; + struct fb_var_screeninfo new_var; + struct da8xx_fb_par *par = fbi->par; + struct fb_fix_screeninfo *fix = &fbi->fix; + unsigned int end; + unsigned int start; + + if (var->xoffset != fbi->var.xoffset || + var->yoffset != fbi->var.yoffset) { + memcpy(&new_var, &fbi->var, sizeof(new_var)); + new_var.xoffset = var->xoffset; + new_var.yoffset = var->yoffset; + if (fb_check_var(&new_var, fbi)) + ret = -EINVAL; + else { + memcpy(&fbi->var, &new_var, sizeof(new_var)); + + start = fix->smem_start + + new_var.yoffset * fix->line_length + + new_var.xoffset * var->bits_per_pixel / 8; + end = start + var->yres * fix->line_length - 1; + par->dma_start = start; + par->dma_end = end; + } + } + + return ret; +} + static struct fb_ops da8xx_fb_ops = { .owner = THIS_MODULE, .fb_check_var = fb_check_var, .fb_setcolreg = fb_setcolreg, + .fb_pan_display = da8xx_pan_display, .fb_ioctl = fb_ioctl, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, @@ -829,40 +985,53 @@ static int __init fb_probe(struct platform_device *device) } /* allocate frame buffer */ - da8xx_fb_info->screen_base = dma_alloc_coherent(NULL, - par->databuf_sz + PAGE_SIZE, - (resource_size_t *) - &da8xx_fb_info->fix.smem_start, - GFP_KERNEL | GFP_DMA); - - if (!da8xx_fb_info->screen_base) { + par->vram_size = lcdc_info->width * lcdc_info->height * lcd_cfg->bpp; + par->vram_size = PAGE_ALIGN(par->vram_size/8); + par->vram_size = par->vram_size * LCD_NUM_BUFFERS; + + par->vram_virt = dma_alloc_coherent(NULL, + par->vram_size, + (resource_size_t *) &par->vram_phys, + GFP_KERNEL | GFP_DMA); + if (!par->vram_virt) { dev_err(&device->dev, "GLCD: kmalloc for frame buffer failed\n"); ret = -EINVAL; goto err_release_fb; } - /* move palette base pointer by (PAGE_SIZE - palette_sz) bytes */ - par->v_palette_base = da8xx_fb_info->screen_base + - (PAGE_SIZE - par->palette_sz); - par->p_palette_base = da8xx_fb_info->fix.smem_start + - (PAGE_SIZE - par->palette_sz); - - /* the rest of the frame buffer is pixel data */ - da8xx_fb_info->screen_base = par->v_palette_base + par->palette_sz; - da8xx_fb_fix.smem_start = par->p_palette_base + par->palette_sz; - da8xx_fb_fix.smem_len = par->databuf_sz - par->palette_sz; - da8xx_fb_fix.line_length = (lcdc_info->width * lcd_cfg->bpp) / 8; + da8xx_fb_info->screen_base = (char __iomem *) par->vram_virt; + da8xx_fb_fix.smem_start = par->vram_phys; + da8xx_fb_fix.smem_len = par->vram_size; + da8xx_fb_fix.line_length = (lcdc_info->width * lcd_cfg->bpp) / 8; + + par->dma_start = par->vram_phys; + par->dma_end = par->dma_start + lcdc_info->height * + da8xx_fb_fix.line_length - 1; + + /* allocate palette buffer */ + par->v_palette_base = dma_alloc_coherent(NULL, + PALETTE_SIZE, + (resource_size_t *) + &par->p_palette_base, + GFP_KERNEL | GFP_DMA); + if (!par->v_palette_base) { + dev_err(&device->dev, + "GLCD: kmalloc for palette buffer failed\n"); + ret = -EINVAL; + goto err_release_fb_mem; + } + memset(par->v_palette_base, 0, PALETTE_SIZE); par->irq = platform_get_irq(device, 0); if (par->irq < 0) { ret = -ENOENT; - goto err_release_fb_mem; + goto err_release_pl_mem; } ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par); if (ret) - goto err_release_fb_mem; + goto err_release_pl_mem; /* Initialize par */ da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp; @@ -870,8 +1039,8 @@ static int __init fb_probe(struct platform_device *device) da8xx_fb_var.xres = lcdc_info->width; da8xx_fb_var.xres_virtual = lcdc_info->width; - da8xx_fb_var.yres = lcdc_info->height; - da8xx_fb_var.yres_virtual = lcdc_info->height; + da8xx_fb_var.yres = lcdc_info->height; + da8xx_fb_var.yres_virtual = lcdc_info->height * LCD_NUM_BUFFERS; da8xx_fb_var.grayscale = lcd_cfg->p_disp_panel->panel_shade == MONOCHROME ? 1 : 0; @@ -892,18 +1061,18 @@ static int __init fb_probe(struct platform_device *device) ret = fb_alloc_cmap(&da8xx_fb_info->cmap, PALETTE_SIZE, 0); if (ret) goto err_free_irq; - - /* First palette_sz byte of the frame buffer is the palette */ da8xx_fb_info->cmap.len = par->palette_sz; - /* Flush the buffer to the screen. */ - lcd_blit(LOAD_DATA, par); - /* initialize var_screeninfo */ da8xx_fb_var.activate = FB_ACTIVATE_FORCE; fb_set_var(da8xx_fb_info, &da8xx_fb_var); dev_set_drvdata(&device->dev, da8xx_fb_info); + + /* initialize the vsync wait queue */ + init_waitqueue_head(&par->vsync_wait); + par->vsync_timeout = HZ / 5; + /* Register the Frame Buffer */ if (register_framebuffer(da8xx_fb_info) < 0) { dev_err(&device->dev, @@ -919,10 +1088,6 @@ static int __init fb_probe(struct platform_device *device) goto err_cpu_freq; } #endif - - /* enable raster engine */ - lcd_enable_raster(); - return 0; #ifdef CONFIG_CPU_FREQ @@ -936,10 +1101,12 @@ err_dealloc_cmap: err_free_irq: free_irq(par->irq, par); +err_release_pl_mem: + dma_free_coherent(NULL, PALETTE_SIZE, par->v_palette_base, + par->p_palette_base); + err_release_fb_mem: - dma_free_coherent(NULL, par->databuf_sz + PAGE_SIZE, - da8xx_fb_info->screen_base - PAGE_SIZE, - da8xx_fb_info->fix.smem_start); + dma_free_coherent(NULL, par->vram_size, par->vram_virt, par->vram_phys); err_release_fb: framebuffer_release(da8xx_fb_info); diff --git a/include/video/da8xx-fb.h b/include/video/da8xx-fb.h index 89d43b3d4cb9..6316cdabf73f 100644 --- a/include/video/da8xx-fb.h +++ b/include/video/da8xx-fb.h @@ -99,6 +99,7 @@ struct lcd_sync_arg { #define FBIPUT_COLOR _IOW('F', 6, int) #define FBIPUT_HSYNC _IOW('F', 9, int) #define FBIPUT_VSYNC _IOW('F', 10, int) +#define FBIO_WAITFORVSYNC _IOW('F', 0x20, u_int32_t) #endif /* ifndef DA8XX_FB_H */ -- cgit v1.2.3 From 49c39b4953e545ce3b5957cce22e1ade01c6e642 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Mon, 24 May 2010 14:34:02 -0700 Subject: fbdev: move FBIO_WAITFORVSYNC to linux/fb.h FBIO_WAITFORVSYNC is currently implemented by matroxfb, atyfb, intelfb and more. All of them keep redefining the same FBIO_WAITFORVSYNC macro over and over again, so move it to linux/fb.h and clean up those duplicate defines. Signed-off-by: Grazvydas Ignotas Cc: Ville Syrjala Cc: Grant Likely Cc: Maik Broemme Cc: Petr Vandrovec Cc: Benjamin Herrenschmidt Cc: Krzysztof Helt Cc: "Hiremath, Vaibhav" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/aty/atyfb_base.c | 4 ---- drivers/video/intelfb/intelfb.h | 4 ---- include/linux/fb.h | 2 +- include/linux/ivtvfb.h | 1 - include/linux/matroxfb.h | 3 +-- include/video/sh_mobile_lcdc.h | 2 -- 6 files changed, 2 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 29d72851f85b..f8d69ad36830 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -1820,10 +1820,6 @@ struct atyclk { #define ATYIO_FEATW 0x41545903 /* ATY\03 */ #endif -#ifndef FBIO_WAITFORVSYNC -#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) -#endif - static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg) { struct atyfb_par *par = (struct atyfb_par *) info->par; diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h index 40984551c927..6b51175629c7 100644 --- a/drivers/video/intelfb/intelfb.h +++ b/drivers/video/intelfb/intelfb.h @@ -371,10 +371,6 @@ struct intelfb_info { ((dinfo)->chipset == INTEL_965G) || \ ((dinfo)->chipset == INTEL_965GM)) -#ifndef FBIO_WAITFORVSYNC -#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) -#endif - /*** function prototypes ***/ extern int intelfb_var_to_depth(const struct fb_var_screeninfo *var); diff --git a/include/linux/fb.h b/include/linux/fb.h index 1296af45169d..f3793ebc241c 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -37,7 +37,7 @@ struct dentry; #define FBIOGET_HWCINFO 0x4616 #define FBIOPUT_MODEINFO 0x4617 #define FBIOGET_DISPINFO 0x4618 - +#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ #define FB_TYPE_PLANES 1 /* Non interleaved planes */ diff --git a/include/linux/ivtvfb.h b/include/linux/ivtvfb.h index 9d88b29ddf55..e8b92f67f10d 100644 --- a/include/linux/ivtvfb.h +++ b/include/linux/ivtvfb.h @@ -33,6 +33,5 @@ struct ivtvfb_dma_frame { }; #define IVTVFB_IOC_DMA_FRAME _IOW('V', BASE_VIDIOC_PRIVATE+0, struct ivtvfb_dma_frame) -#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) #endif diff --git a/include/linux/matroxfb.h b/include/linux/matroxfb.h index 2203121a43e9..8c22a8938642 100644 --- a/include/linux/matroxfb.h +++ b/include/linux/matroxfb.h @@ -4,6 +4,7 @@ #include #include #include +#include struct matroxioc_output_mode { __u32 output; /* which output */ @@ -37,7 +38,5 @@ enum matroxfb_ctrl_id { MATROXFB_CID_LAST }; -#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) - #endif diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h index 2cc893fc1f85..288205457713 100644 --- a/include/video/sh_mobile_lcdc.h +++ b/include/video/sh_mobile_lcdc.h @@ -34,8 +34,6 @@ enum { LCDC_CLK_BUS, LCDC_CLK_PERIPHERAL, LCDC_CLK_EXTERNAL }; #define LCDC_FLAGS_HSCNT (1 << 3) /* Disable HSYNC during VBLANK */ #define LCDC_FLAGS_DWCNT (1 << 4) /* Disable dotclock during blanking */ -#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) - struct sh_mobile_lcdc_sys_bus_cfg { unsigned long ldmt2r; unsigned long ldmt3r; -- cgit v1.2.3 From e88a0f461aeadfe309d36a2a4fac9ffb1b0ed651 Mon Sep 17 00:00:00 2001 From: Henrik Kretzschmar Date: Mon, 24 May 2010 14:34:04 -0700 Subject: hitfb: fix sections Since the drivers probe call was changed from .init.text to .devinit.text in commit c2e13037e6794bd0d9de3f9ecabf5615f15c160b ("platform-drivers: move probe to .devinit.text in drivers/video") the fb_fix_screeninfo and fb_var_screeninfo structures must be changed from .init.data to .devinit.data, too. Also the drivers remove routine should be moved from .exit.text to .devexit.text Signed-off-by: Henrik Kretzschmar Cc: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/hitfb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c index 393f3f3d3dfe..cfb8d6451014 100644 --- a/drivers/video/hitfb.c +++ b/drivers/video/hitfb.c @@ -30,14 +30,14 @@ #define WIDTH 640 -static struct fb_var_screeninfo hitfb_var __initdata = { +static struct fb_var_screeninfo hitfb_var __devinitdata = { .activate = FB_ACTIVATE_NOW, .height = -1, .width = -1, .vmode = FB_VMODE_NONINTERLACED, }; -static struct fb_fix_screeninfo hitfb_fix __initdata = { +static struct fb_fix_screeninfo hitfb_fix __devinitdata = { .id = "Hitachi HD64461", .type = FB_TYPE_PACKED_PIXELS, .accel = FB_ACCEL_NONE, @@ -417,7 +417,7 @@ err_fb: return ret; } -static int __exit hitfb_remove(struct platform_device *dev) +static int __devexit hitfb_remove(struct platform_device *dev) { struct fb_info *info = platform_get_drvdata(dev); @@ -462,7 +462,7 @@ static const struct dev_pm_ops hitfb_dev_pm_ops = { static struct platform_driver hitfb_driver = { .probe = hitfb_probe, - .remove = __exit_p(hitfb_remove), + .remove = __devexit_p(hitfb_remove), .driver = { .name = "hitfb", .owner = THIS_MODULE, -- cgit v1.2.3 From a8ce4be7d5b99a6338e695b26358abca329735c1 Mon Sep 17 00:00:00 2001 From: Henrik Kretzschmar Date: Mon, 24 May 2010 14:34:05 -0700 Subject: s3c2410fb: fix sections Since the drivers probe calls were changed from .init.text to .devinit.text in commit c2e13037e6794bd0d9de3f9ecabf5615f15c160b ("platform-drivers: move probe to .devinit.text in drivers/video") all the function from .init.text should be moved to .devinit.text, too. The drivers remove calls can also be move from .text to .devexit.text. Signed-off-by: Henrik Kretzschmar Cc: Vincent Sanders Acked-by: Arnaud Patard Tested-by: Arnaud Patard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/s3c2410fb.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index 2b094dec4a56..46b430978bcc 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c @@ -631,7 +631,7 @@ static struct fb_ops s3c2410fb_ops = { * cache. Once this area is remapped, all virtual memory * access to the video memory should occur at the new region. */ -static int __init s3c2410fb_map_video_memory(struct fb_info *info) +static int __devinit s3c2410fb_map_video_memory(struct fb_info *info) { struct s3c2410fb_info *fbi = info->par; dma_addr_t map_dma; @@ -814,7 +814,7 @@ static inline void s3c2410fb_cpufreq_deregister(struct s3c2410fb_info *info) static char driver_name[] = "s3c2410fb"; -static int __init s3c24xxfb_probe(struct platform_device *pdev, +static int __devinit s3c24xxfb_probe(struct platform_device *pdev, enum s3c_drv_type drv_type) { struct s3c2410fb_info *info; @@ -1018,7 +1018,7 @@ static int __devinit s3c2412fb_probe(struct platform_device *pdev) /* * Cleanup */ -static int s3c2410fb_remove(struct platform_device *pdev) +static int __devexit s3c2410fb_remove(struct platform_device *pdev) { struct fb_info *fbinfo = platform_get_drvdata(pdev); struct s3c2410fb_info *info = fbinfo->par; @@ -1096,7 +1096,7 @@ static int s3c2410fb_resume(struct platform_device *dev) static struct platform_driver s3c2410fb_driver = { .probe = s3c2410fb_probe, - .remove = s3c2410fb_remove, + .remove = __devexit_p(s3c2410fb_remove), .suspend = s3c2410fb_suspend, .resume = s3c2410fb_resume, .driver = { @@ -1107,7 +1107,7 @@ static struct platform_driver s3c2410fb_driver = { static struct platform_driver s3c2412fb_driver = { .probe = s3c2412fb_probe, - .remove = s3c2410fb_remove, + .remove = __devexit_p(s3c2410fb_remove), .suspend = s3c2410fb_suspend, .resume = s3c2410fb_resume, .driver = { -- cgit v1.2.3 From 0d5b02641faade3dfd376abdcffbd8ccb03c7a91 Mon Sep 17 00:00:00 2001 From: Henrik Kretzschmar Date: Mon, 24 May 2010 14:34:07 -0700 Subject: sgivwfb: fix sections Since the drivers probe call was changed from .init.text to .devinit.text in commit c2e13037e6794bd0d9de3f9ecabf5615f15c160b ("platform-drivers: move probe to .devinit.text in drivers/video") the fb_fix_screeninfo and fb_var_screeninfo structures must be changed from .init.data to .devinit.data, too. Also the drivers remove routine should be moved from .text to .devexit.text It removes these 7 section mismatch warnings from modpost: WARNING: vmlinux.o(.devinit.text+0x1e28): Section mismatch in reference from the function sgivwfb_probe() to the variable .init.data:sgivwfb_fix The function __devinit sgivwfb_probe() references a variable __initdata sgivwfb_fix. If sgivwfb_fix is only used by sgivwfb_probe then annotate sgivwfb_fix with a matching annotation. WARNING: vmlinux.o(.devinit.text+0x1e50): Section mismatch in reference from the function sgivwfb_probe() to the (unknown reference) .init.data:(unknown) The function __devinit sgivwfb_probe() references a (unknown reference) __initdata (unknown). If (unknown) is only used by sgivwfb_probe then annotate (unknown) with a matching annotation. WARNING: vmlinux.o(.devinit.text+0x1e59): Section mismatch in reference from the function sgivwfb_probe() to the (unknown reference) .init.data:(unknown) The function __devinit sgivwfb_probe() references a (unknown reference) __initdata (unknown). If (unknown) is only used by sgivwfb_probe then annotate (unknown) with a matching annotation. WARNING: vmlinux.o(.devinit.text+0x1e60): Section mismatch in reference from the function sgivwfb_probe() to the variable .init.data:sgivwfb_fix The function __devinit sgivwfb_probe() references a variable __initdata sgivwfb_fix. If sgivwfb_fix is only used by sgivwfb_probe then annotate sgivwfb_fix with a matching annotation. WARNING: vmlinux.o(.devinit.text+0x1e6a): Section mismatch in reference from the function sgivwfb_probe() to the (unknown reference) .init.data:(unknown) The function __devinit sgivwfb_probe() references a (unknown reference) __initdata (unknown). If (unknown) is only used by sgivwfb_probe then annotate (unknown) with a matching annotation. WARNING: vmlinux.o(.devinit.text+0x1e7f): Section mismatch in reference from the function sgivwfb_probe() to the variable .init.data:sgivwfb_var1600sw The function __devinit sgivwfb_probe() references a variable __initdata sgivwfb_var1600sw. If sgivwfb_var1600sw is only used by sgivwfb_probe then annotate sgivwfb_var1600sw with a matching annotation. WARNING: vmlinux.o(.devinit.text+0x1e91): Section mismatch in reference from the function sgivwfb_probe() to the variable .init.data:sgivwfb_var The function __devinit sgivwfb_probe() references a variable __initdata sgivwfb_var. If sgivwfb_var is only used by sgivwfb_probe then annotate sgivwfb_var with a matching annotation. Signed-off-by: Henrik Kretzschmar Cc: Arnaud Patard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/sgivwfb.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c index 7a3a5e28eca1..53455f295510 100644 --- a/drivers/video/sgivwfb.c +++ b/drivers/video/sgivwfb.c @@ -47,7 +47,7 @@ static int ywrap = 0; static int flatpanel_id = -1; -static struct fb_fix_screeninfo sgivwfb_fix __initdata = { +static struct fb_fix_screeninfo sgivwfb_fix __devinitdata = { .id = "SGI Vis WS FB", .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_PSEUDOCOLOR, @@ -57,7 +57,7 @@ static struct fb_fix_screeninfo sgivwfb_fix __initdata = { .line_length = 640, }; -static struct fb_var_screeninfo sgivwfb_var __initdata = { +static struct fb_var_screeninfo sgivwfb_var __devinitdata = { /* 640x480, 8 bpp */ .xres = 640, .yres = 480, @@ -79,7 +79,7 @@ static struct fb_var_screeninfo sgivwfb_var __initdata = { .vmode = FB_VMODE_NONINTERLACED }; -static struct fb_var_screeninfo sgivwfb_var1600sw __initdata = { +static struct fb_var_screeninfo sgivwfb_var1600sw __devinitdata = { /* 1600x1024, 8 bpp */ .xres = 1600, .yres = 1024, @@ -825,7 +825,7 @@ fail_ioremap_regs: return -ENXIO; } -static int sgivwfb_remove(struct platform_device *dev) +static int __devexit sgivwfb_remove(struct platform_device *dev) { struct fb_info *info = platform_get_drvdata(dev); @@ -845,7 +845,7 @@ static int sgivwfb_remove(struct platform_device *dev) static struct platform_driver sgivwfb_driver = { .probe = sgivwfb_probe, - .remove = sgivwfb_remove, + .remove = __devexit_p(sgivwfb_remove), .driver = { .name = "sgivwfb", }, -- cgit v1.2.3 From 49bbd815fd8ba26d0354900b783b767c7f47c816 Mon Sep 17 00:00:00 2001 From: Albert Herranz Date: Mon, 24 May 2010 14:34:08 -0700 Subject: fb_defio: fix for non-dirty ptes Fix a problem observed while using fb_defio with a short delay on a PowerPC platform. It is possible that page_mkclean() is invoked in the deferred io work function _before_ a PTE has been marked dirty. In this case, the page is removed from the defio pagelist but page_mkclean() does not write-protect the page again. The end result is that defio ignores all subsequent writes to the page and the corresponding portions of the framebuffer never get updated. The fix consists in keeping track of the pages with non-dirty PTEs, re-checking them again on the next deferred io work iteration. Note that those pages are not passed to the defio callback as they are not written by userspace yet. Signed-off-by: Albert Herranz Acked-by: Jaya Kumar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/fb_defio.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c index 6113c47e095a..1105a591dcc1 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fb_defio.c @@ -155,25 +155,41 @@ static void fb_deferred_io_work(struct work_struct *work) { struct fb_info *info = container_of(work, struct fb_info, deferred_work.work); - struct list_head *node, *next; - struct page *cur; struct fb_deferred_io *fbdefio = info->fbdefio; + struct page *page, *tmp_page; + struct list_head *node, *tmp_node; + struct list_head non_dirty; + + INIT_LIST_HEAD(&non_dirty); /* here we mkclean the pages, then do all deferred IO */ mutex_lock(&fbdefio->lock); - list_for_each_entry(cur, &fbdefio->pagelist, lru) { - lock_page(cur); - page_mkclean(cur); - unlock_page(cur); + list_for_each_entry_safe(page, tmp_page, &fbdefio->pagelist, lru) { + lock_page(page); + /* + * The workqueue callback can be triggered after a + * ->page_mkwrite() call but before the PTE has been marked + * dirty. In this case page_mkclean() won't "rearm" the page. + * + * To avoid this, remove those "non-dirty" pages from the + * pagelist before calling the driver's callback, then add + * them back to get processed on the next work iteration. + * At that time, their PTEs will hopefully be dirty for real. + */ + if (!page_mkclean(page)) + list_move_tail(&page->lru, &non_dirty); + unlock_page(page); } /* driver's callback with pagelist */ fbdefio->deferred_io(info, &fbdefio->pagelist); - /* clear the list */ - list_for_each_safe(node, next, &fbdefio->pagelist) { + /* clear the list... */ + list_for_each_safe(node, tmp_node, &fbdefio->pagelist) { list_del(node); } + /* ... and add back the "non-dirty" pages to the list */ + list_splice_tail(&non_dirty, &fbdefio->pagelist); mutex_unlock(&fbdefio->lock); } @@ -202,6 +218,7 @@ EXPORT_SYMBOL_GPL(fb_deferred_io_open); void fb_deferred_io_cleanup(struct fb_info *info) { struct fb_deferred_io *fbdefio = info->fbdefio; + struct list_head *node, *tmp_node; struct page *page; int i; @@ -209,6 +226,13 @@ void fb_deferred_io_cleanup(struct fb_info *info) cancel_delayed_work(&info->deferred_work); flush_scheduled_work(); + /* the list may have still some non-dirty pages at this point */ + mutex_lock(&fbdefio->lock); + list_for_each_safe(node, tmp_node, &fbdefio->pagelist) { + list_del(node); + } + mutex_unlock(&fbdefio->lock); + /* clear out the mapping that we setup */ for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) { page = fb_deferred_io_page(info, i); -- cgit v1.2.3 From a42dcb883d948a5f26c005f0e401e8297aa05f76 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 24 May 2010 14:34:09 -0700 Subject: nuc900fb: release correct mem region We should be releasing "res->start" here. Signed-off-by: Dan Carpenter Acked-by: Wan ZongShun Cc: Wang Qiang Cc: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/nuc900fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/nuc900fb.c b/drivers/video/nuc900fb.c index 6bf0d460a738..d4cde79ea15e 100644 --- a/drivers/video/nuc900fb.c +++ b/drivers/video/nuc900fb.c @@ -667,7 +667,7 @@ release_irq: release_regs: iounmap(fbi->io); release_mem_region: - release_mem_region((unsigned long)fbi->mem, size); + release_mem_region(res->start, size); free_fb: framebuffer_release(fbinfo); return ret; -- cgit v1.2.3 From bf87eae94880f1b79c2828d8705f0d97e961f168 Mon Sep 17 00:00:00 2001 From: Henrik Kretzschmar Date: Mon, 24 May 2010 14:34:09 -0700 Subject: auxdisplay: section cleanup in cfag12864bfb driver This fixes a two section mismatches and makes remove() __devexit. Signed-off-by: Henrik Kretzschmar Cc: Miguel Ojeda Sandonis Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/auxdisplay/cfag12864bfb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/auxdisplay/cfag12864bfb.c b/drivers/auxdisplay/cfag12864bfb.c index 3fecfb446d90..5ad3bad2b0a5 100644 --- a/drivers/auxdisplay/cfag12864bfb.c +++ b/drivers/auxdisplay/cfag12864bfb.c @@ -37,7 +37,7 @@ #define CFAG12864BFB_NAME "cfag12864bfb" -static struct fb_fix_screeninfo cfag12864bfb_fix __initdata = { +static struct fb_fix_screeninfo cfag12864bfb_fix __devinitdata = { .id = "cfag12864b", .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_MONO10, @@ -48,7 +48,7 @@ static struct fb_fix_screeninfo cfag12864bfb_fix __initdata = { .accel = FB_ACCEL_NONE, }; -static struct fb_var_screeninfo cfag12864bfb_var __initdata = { +static struct fb_var_screeninfo cfag12864bfb_var __devinitdata = { .xres = CFAG12864B_WIDTH, .yres = CFAG12864B_HEIGHT, .xres_virtual = CFAG12864B_WIDTH, @@ -114,7 +114,7 @@ none: return ret; } -static int cfag12864bfb_remove(struct platform_device *device) +static int __devexit cfag12864bfb_remove(struct platform_device *device) { struct fb_info *info = platform_get_drvdata(device); @@ -128,7 +128,7 @@ static int cfag12864bfb_remove(struct platform_device *device) static struct platform_driver cfag12864bfb_driver = { .probe = cfag12864bfb_probe, - .remove = cfag12864bfb_remove, + .remove = __devexit_p(cfag12864bfb_remove), .driver = { .name = CFAG12864BFB_NAME, }, -- cgit v1.2.3 From 774610e4f26cb3d9da14a8b5974324c9e51017bd Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 13 May 2010 20:37:24 +0200 Subject: ath9k: change beacon allocation to prefer the first beacon slot This fixes IBSS beacon transmissions without VEOL enabled Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index c8a4558f79ba..77face76e05f 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -274,17 +274,11 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) avp->av_bslot = 0; for (slot = 0; slot < ATH_BCBUF; slot++) if (sc->beacon.bslot[slot] == NULL) { - /* - * XXX hack, space out slots to better - * deal with misses - */ - if (slot+1 < ATH_BCBUF && - sc->beacon.bslot[slot+1] == NULL) { - avp->av_bslot = slot+1; - break; - } avp->av_bslot = slot; + /* NB: keep looking for a double slot */ + if (slot == 0 || !sc->beacon.bslot[slot-1]) + break; } BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL); sc->beacon.bslot[avp->av_bslot] = vif; -- cgit v1.2.3 From a65e4cb402b5f3e120570ba1faca4354d47e8f2f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 13 May 2010 20:37:25 +0200 Subject: ath9k: remove VEOL support for ad-hoc With VEOL, Beacon transmission in ad-hoc does not currently work. I believe for larger ad-hoc networks, VEOL is too unreliable, as it can get beacon transmissions stuck during synchronization. Use SWBA based beacon trasmission similar to AP mode instead. Signed-off-by: Felix Fietkau Acked-by: Benoit Papillault Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 63 ++++++--------------------------- 1 file changed, 10 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 77face76e05f..f43d85a302c4 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -76,22 +76,13 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, ds = bf->bf_desc; flags = ATH9K_TXDESC_NOACK; - if (((sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || - (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) && - (ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) { - ds->ds_link = bf->bf_daddr; /* self-linked */ - flags |= ATH9K_TXDESC_VEOL; - /* Let hardware handle antenna switching. */ - antenna = 0; - } else { - ds->ds_link = 0; - /* - * Switch antenna every beacon. - * Should only switch every beacon period, not for every SWBA - * XXX assumes two antennae - */ - antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1); - } + ds->ds_link = 0; + /* + * Switch antenna every beacon. + * Should only switch every beacon period, not for every SWBA + * XXX assumes two antennae + */ + antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1); sband = &sc->sbands[common->hw->conf.channel->band]; rate = sband->bitrates[rateidx].hw_value; @@ -215,36 +206,6 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, return bf; } -/* - * Startup beacon transmission for adhoc mode when they are sent entirely - * by the hardware using the self-linked descriptor + veol trick. -*/ -static void ath_beacon_start_adhoc(struct ath_softc *sc, - struct ieee80211_vif *vif) -{ - struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); - struct ath_buf *bf; - struct ath_vif *avp; - struct sk_buff *skb; - - avp = (void *)vif->drv_priv; - - if (avp->av_bcbuf == NULL) - return; - - bf = avp->av_bcbuf; - skb = bf->bf_mpdu; - - ath_beacon_setup(sc, avp, bf, 0); - - /* NB: caller is known to have already stopped tx dma */ - ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr); - ath9k_hw_txstart(ah, sc->beacon.beaconq); - ath_print(common, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n", - sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc); -} - int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) { struct ath_softc *sc = aphy->sc; @@ -265,7 +226,8 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) list_del(&avp->av_bcbuf->list); if (sc->sc_ah->opmode == NL80211_IFTYPE_AP || - !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) { + sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC || + sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) { int slot; /* * Assign the vif to a beacon xmit slot. As @@ -715,8 +677,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, * self-linked tx descriptor and let the hardware deal with things. */ intval |= ATH9K_BEACON_ENA; - if (!(ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) - ah->imask |= ATH9K_INT_SWBA; + ah->imask |= ATH9K_INT_SWBA; ath_beaconq_config(sc); @@ -726,10 +687,6 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, ath9k_beacon_init(sc, nexttbtt, intval); sc->beacon.bmisscnt = 0; ath9k_hw_set_interrupts(ah, ah->imask); - - /* FIXME: Handle properly when vif is NULL */ - if (vif && ah->caps.hw_caps & ATH9K_HW_CAP_VEOL) - ath_beacon_start_adhoc(sc, vif); } void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) -- cgit v1.2.3 From 36b83ded062a7416bb9184f4d6c537ad99571f4d Mon Sep 17 00:00:00 2001 From: Nick Cheng Date: Mon, 17 May 2010 11:22:42 +0800 Subject: [SCSI] arcmsr: Support HW reset for EH and polling scheme for scsi device 1. To support instantaneous report for SCSI device existing by periodic polling 2. In arcmsr_iop_xfer(), inform AP of F/W's deadlock state to prevent endless waiting 3. To block the coming SCSI command while the driver is handling bus reset 4. To support HW reset in bus reset error handler Signed-off-by: Nick Cheng Signed-off-by: James Bottomley --- drivers/scsi/arcmsr/arcmsr.h | 29 +- drivers/scsi/arcmsr/arcmsr_attr.c | 3 + drivers/scsi/arcmsr/arcmsr_hba.c | 684 ++++++++++++++++++++++++++++---------- 3 files changed, 525 insertions(+), 191 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index ab646e580d64..ce5371b3cdd5 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -48,7 +48,7 @@ struct device_attribute; /*The limit of outstanding scsi command that firmware can handle*/ #define ARCMSR_MAX_OUTSTANDING_CMD 256 #define ARCMSR_MAX_FREECCB_NUM 320 -#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.15 2008/02/27" +#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.15 2008/11/03" #define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_MAX_XFER_SECTORS 512 #define ARCMSR_MAX_XFER_SECTORS_B 4096 @@ -110,6 +110,8 @@ struct CMD_MESSAGE_FIELD #define FUNCTION_SAY_HELLO 0x0807 #define FUNCTION_SAY_GOODBYE 0x0808 #define FUNCTION_FLUSH_ADAPTER_CACHE 0x0809 +#define FUNCTION_GET_FIRMWARE_STATUS 0x080A +#define FUNCTION_HARDWARE_RESET 0x080B /* ARECA IO CONTROL CODE*/ #define ARCMSR_MESSAGE_READ_RQBUFFER \ ARECA_SATA_RAID | FUNCTION_READ_RQBUFFER @@ -133,6 +135,7 @@ struct CMD_MESSAGE_FIELD #define ARCMSR_MESSAGE_RETURNCODE_OK 0x00000001 #define ARCMSR_MESSAGE_RETURNCODE_ERROR 0x00000006 #define ARCMSR_MESSAGE_RETURNCODE_3F 0x0000003F +#define ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON 0x00000088 /* ************************************************************* ** structure for holding DMA address data @@ -341,13 +344,13 @@ struct MessageUnit_B uint32_t done_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; uint32_t postq_index; uint32_t doneq_index; - void __iomem *drv2iop_doorbell_reg; - void __iomem *drv2iop_doorbell_mask_reg; - void __iomem *iop2drv_doorbell_reg; - void __iomem *iop2drv_doorbell_mask_reg; - void __iomem *msgcode_rwbuffer_reg; - void __iomem *ioctl_wbuffer_reg; - void __iomem *ioctl_rbuffer_reg; + uint32_t __iomem *drv2iop_doorbell_reg; + uint32_t __iomem *drv2iop_doorbell_mask_reg; + uint32_t __iomem *iop2drv_doorbell_reg; + uint32_t __iomem *iop2drv_doorbell_mask_reg; + uint32_t __iomem *msgcode_rwbuffer_reg; + uint32_t __iomem *ioctl_wbuffer_reg; + uint32_t __iomem *ioctl_rbuffer_reg; }; /* @@ -375,6 +378,7 @@ struct AdapterControlBlock /* message unit ATU inbound base address0 */ uint32_t acb_flags; + uint8_t adapter_index; #define ACB_F_SCSISTOPADAPTER 0x0001 #define ACB_F_MSG_STOP_BGRB 0x0002 /* stop RAID background rebuild */ @@ -390,7 +394,7 @@ struct AdapterControlBlock #define ACB_F_BUS_RESET 0x0080 #define ACB_F_IOP_INITED 0x0100 /* iop init */ - + #define ACB_F_FIRMWARE_TRAP 0x0400 struct CommandControlBlock * pccb_pool[ARCMSR_MAX_FREECCB_NUM]; /* used for memory free */ struct list_head ccb_free_list; @@ -423,12 +427,19 @@ struct AdapterControlBlock #define ARECA_RAID_GOOD 0xaa uint32_t num_resets; uint32_t num_aborts; + uint32_t signature; uint32_t firm_request_len; uint32_t firm_numbers_queue; uint32_t firm_sdram_size; uint32_t firm_hd_channels; char firm_model[12]; char firm_version[20]; + char device_map[20]; /*21,84-99*/ + struct work_struct arcmsr_do_message_isr_bh; + struct timer_list eternal_timer; + unsigned short fw_state; + atomic_t rq_map_token; + int ante_token_value; };/* HW_DEVICE_EXTENSION */ /* ******************************************************************************* diff --git a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c index a4e04c50c436..07fdfe57e38e 100644 --- a/drivers/scsi/arcmsr/arcmsr_attr.c +++ b/drivers/scsi/arcmsr/arcmsr_attr.c @@ -192,6 +192,7 @@ static struct bin_attribute arcmsr_sysfs_message_read_attr = { .attr = { .name = "mu_read", .mode = S_IRUSR , + .owner = THIS_MODULE, }, .size = 1032, .read = arcmsr_sysfs_iop_message_read, @@ -201,6 +202,7 @@ static struct bin_attribute arcmsr_sysfs_message_write_attr = { .attr = { .name = "mu_write", .mode = S_IWUSR, + .owner = THIS_MODULE, }, .size = 1032, .write = arcmsr_sysfs_iop_message_write, @@ -210,6 +212,7 @@ static struct bin_attribute arcmsr_sysfs_message_clear_attr = { .attr = { .name = "mu_clear", .mode = S_IWUSR, + .owner = THIS_MODULE, }, .size = 1, .write = arcmsr_sysfs_iop_message_clear, diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index ffbe2192da3c..ffa54792bb33 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -72,8 +72,16 @@ #include #include "arcmsr.h" +#ifdef CONFIG_SCSI_ARCMSR_RESET + static int sleeptime = 20; + static int retrycount = 12; + module_param(sleeptime, int, S_IRUGO|S_IWUSR); + MODULE_PARM_DESC(sleeptime, "The waiting period for FW ready while bus reset"); + module_param(retrycount, int, S_IRUGO|S_IWUSR); + MODULE_PARM_DESC(retrycount, "The retry count for FW ready while bus reset"); +#endif MODULE_AUTHOR("Erich Chen "); -MODULE_DESCRIPTION("ARECA (ARC11xx/12xx/13xx/16xx) SATA/SAS RAID HOST Adapter"); +MODULE_DESCRIPTION("ARECA (ARC11xx/12xx/13xx/16xx) SATA/SAS RAID Host Bus Adapter"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(ARCMSR_DRIVER_VERSION); @@ -96,6 +104,13 @@ static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb); static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb); static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb); static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb); +static void arcmsr_request_device_map(unsigned long pacb); +static void arcmsr_request_hba_device_map(struct AdapterControlBlock *acb); +static void arcmsr_request_hbb_device_map(struct AdapterControlBlock *acb); +static void arcmsr_message_isr_bh_fn(struct work_struct *work); +static void *arcmsr_get_firmware_spec(struct AdapterControlBlock *acb, int mode); +static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb); + static const char *arcmsr_info(struct Scsi_Host *); static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb); static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, @@ -112,7 +127,7 @@ static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, static struct scsi_host_template arcmsr_scsi_host_template = { .module = THIS_MODULE, - .name = "ARCMSR ARECA SATA/SAS RAID HOST Adapter" + .name = "ARCMSR ARECA SATA/SAS RAID Host Bus Adapter" ARCMSR_DRIVER_VERSION, .info = arcmsr_info, .queuecommand = arcmsr_queue_command, @@ -128,16 +143,6 @@ static struct scsi_host_template arcmsr_scsi_host_template = { .use_clustering = ENABLE_CLUSTERING, .shost_attrs = arcmsr_host_attrs, }; -#ifdef CONFIG_SCSI_ARCMSR_AER -static pci_ers_result_t arcmsr_pci_slot_reset(struct pci_dev *pdev); -static pci_ers_result_t arcmsr_pci_error_detected(struct pci_dev *pdev, - pci_channel_state_t state); - -static struct pci_error_handlers arcmsr_pci_error_handlers = { - .error_detected = arcmsr_pci_error_detected, - .slot_reset = arcmsr_pci_slot_reset, -}; -#endif static struct pci_device_id arcmsr_device_id_table[] = { {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1110)}, {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1120)}, @@ -166,9 +171,6 @@ static struct pci_driver arcmsr_pci_driver = { .probe = arcmsr_probe, .remove = arcmsr_remove, .shutdown = arcmsr_shutdown, - #ifdef CONFIG_SCSI_ARCMSR_AER - .err_handler = &arcmsr_pci_error_handlers, - #endif }; static irqreturn_t arcmsr_do_interrupt(int irq, void *dev_id) @@ -236,10 +238,9 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) void *dma_coherent; dma_addr_t dma_coherent_handle, dma_addr; struct CommandControlBlock *ccb_tmp; - uint32_t intmask_org; int i, j; - acb->pmuA = pci_ioremap_bar(pdev, 0); + acb->pmuA = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); if (!acb->pmuA) { printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n", acb->host->host_no); @@ -281,12 +282,6 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) for (i = 0; i < ARCMSR_MAX_TARGETID; i++) for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++) acb->devstate[i][j] = ARECA_RAID_GONE; - - /* - ** here we need to tell iop 331 our ccb_tmp.HighPart - ** if ccb_tmp.HighPart is not zero - */ - intmask_org = arcmsr_disable_outbound_ints(acb); } break; @@ -297,7 +292,6 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) void __iomem *mem_base0, *mem_base1; void *dma_coherent; dma_addr_t dma_coherent_handle, dma_addr; - uint32_t intmask_org; struct CommandControlBlock *ccb_tmp; int i, j; @@ -333,11 +327,13 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) reg = (struct MessageUnit_B *)(dma_coherent + ARCMSR_MAX_FREECCB_NUM * sizeof(struct CommandControlBlock)); acb->pmuB = reg; - mem_base0 = pci_ioremap_bar(pdev, 0); + mem_base0 = ioremap(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); if (!mem_base0) goto out; - mem_base1 = pci_ioremap_bar(pdev, 2); + mem_base1 = ioremap(pci_resource_start(pdev, 2), + pci_resource_len(pdev, 2)); if (!mem_base1) { iounmap(mem_base0); goto out; @@ -357,12 +353,6 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) for (i = 0; i < ARCMSR_MAX_TARGETID; i++) for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++) acb->devstate[i][j] = ARECA_RAID_GOOD; - - /* - ** here we need to tell iop 331 our ccb_tmp.HighPart - ** if ccb_tmp.HighPart is not zero - */ - intmask_org = arcmsr_disable_outbound_ints(acb); } break; } @@ -374,6 +364,88 @@ out: sizeof(struct MessageUnit_B)), acb->dma_coherent, acb->dma_coherent_handle); return -ENOMEM; } +static void arcmsr_message_isr_bh_fn(struct work_struct *work) +{ + struct AdapterControlBlock *acb = container_of(work, struct AdapterControlBlock, arcmsr_do_message_isr_bh); + + switch (acb->adapter_type) { + case ACB_ADAPTER_TYPE_A: { + + struct MessageUnit_A __iomem *reg = acb->pmuA; + char *acb_dev_map = (char *)acb->device_map; + uint32_t __iomem *signature = (uint32_t __iomem *) (®->message_rwbuffer[0]); + char __iomem *devicemap = (char __iomem *) (®->message_rwbuffer[21]); + int target, lun; + struct scsi_device *psdev; + char diff; + + atomic_inc(&acb->rq_map_token); + if (readl(signature) == ARCMSR_SIGNATURE_GET_CONFIG) { + for (target = 0; target < ARCMSR_MAX_TARGETID - 1; target++) { + diff = (*acb_dev_map)^readb(devicemap); + if (diff != 0) { + char temp; + *acb_dev_map = readb(devicemap); + temp = *acb_dev_map; + for (lun = 0; lun < ARCMSR_MAX_TARGETLUN; lun++) { + if ((temp & 0x01) == 1 && (diff & 0x01) == 1) { + scsi_add_device(acb->host, 0, target, lun); + } else if ((temp & 0x01) == 0 && (diff & 0x01) == 1) { + psdev = scsi_device_lookup(acb->host, 0, target, lun); + if (psdev != NULL) { + scsi_remove_device(psdev); + scsi_device_put(psdev); + } + } + temp >>= 1; + diff >>= 1; + } + } + devicemap++; + acb_dev_map++; + } + } + break; + } + + case ACB_ADAPTER_TYPE_B: { + struct MessageUnit_B *reg = acb->pmuB; + char *acb_dev_map = (char *)acb->device_map; + uint32_t __iomem *signature = (uint32_t __iomem *)(®->msgcode_rwbuffer_reg[0]); + char __iomem *devicemap = (char __iomem *)(®->msgcode_rwbuffer_reg[21]); + int target, lun; + struct scsi_device *psdev; + char diff; + + atomic_inc(&acb->rq_map_token); + if (readl(signature) == ARCMSR_SIGNATURE_GET_CONFIG) { + for (target = 0; target < ARCMSR_MAX_TARGETID - 1; target++) { + diff = (*acb_dev_map)^readb(devicemap); + if (diff != 0) { + char temp; + *acb_dev_map = readb(devicemap); + temp = *acb_dev_map; + for (lun = 0; lun < ARCMSR_MAX_TARGETLUN; lun++) { + if ((temp & 0x01) == 1 && (diff & 0x01) == 1) { + scsi_add_device(acb->host, 0, target, lun); + } else if ((temp & 0x01) == 0 && (diff & 0x01) == 1) { + psdev = scsi_device_lookup(acb->host, 0, target, lun); + if (psdev != NULL) { + scsi_remove_device(psdev); + scsi_device_put(psdev); + } + } + temp >>= 1; + diff >>= 1; + } + } + devicemap++; + acb_dev_map++; + } + } + } + } +} static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id) @@ -432,17 +504,17 @@ static int arcmsr_probe(struct pci_dev *pdev, ACB_F_MESSAGE_WQBUFFER_READED); acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER; INIT_LIST_HEAD(&acb->ccb_free_list); - + INIT_WORK(&acb->arcmsr_do_message_isr_bh, arcmsr_message_isr_bh_fn); error = arcmsr_alloc_ccb_pool(acb); if (error) goto out_release_regions; + arcmsr_iop_init(acb); error = request_irq(pdev->irq, arcmsr_do_interrupt, IRQF_SHARED, "arcmsr", acb); if (error) goto out_free_ccb_pool; - arcmsr_iop_init(acb); pci_set_drvdata(pdev, host); if (strncmp(acb->firm_version, "V1.42", 5) >= 0) host->max_sectors= ARCMSR_MAX_XFER_SECTORS_B; @@ -459,6 +531,14 @@ static int arcmsr_probe(struct pci_dev *pdev, #ifdef CONFIG_SCSI_ARCMSR_AER pci_enable_pcie_error_reporting(pdev); #endif + atomic_set(&acb->rq_map_token, 16); + acb->fw_state = true; + init_timer(&acb->eternal_timer); + acb->eternal_timer.expires = jiffies + msecs_to_jiffies(10*HZ); + acb->eternal_timer.data = (unsigned long) acb; + acb->eternal_timer.function = &arcmsr_request_device_map; + add_timer(&acb->eternal_timer); + return 0; out_free_sysfs: out_free_irq: @@ -518,40 +598,48 @@ static uint8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb) return 0xff; } -static void arcmsr_abort_hba_allcmd(struct AdapterControlBlock *acb) +static uint8_t arcmsr_abort_hba_allcmd(struct AdapterControlBlock *acb) { struct MessageUnit_A __iomem *reg = acb->pmuA; writel(ARCMSR_INBOUND_MESG0_ABORT_CMD, ®->inbound_msgaddr0); - if (arcmsr_hba_wait_msgint_ready(acb)) + if (arcmsr_hba_wait_msgint_ready(acb)) { printk(KERN_NOTICE "arcmsr%d: wait 'abort all outstanding command' timeout \n" , acb->host->host_no); + return 0xff; + } + return 0x00; } -static void arcmsr_abort_hbb_allcmd(struct AdapterControlBlock *acb) +static uint8_t arcmsr_abort_hbb_allcmd(struct AdapterControlBlock *acb) { struct MessageUnit_B *reg = acb->pmuB; writel(ARCMSR_MESSAGE_ABORT_CMD, reg->drv2iop_doorbell_reg); - if (arcmsr_hbb_wait_msgint_ready(acb)) + if (arcmsr_hbb_wait_msgint_ready(acb)) { printk(KERN_NOTICE "arcmsr%d: wait 'abort all outstanding command' timeout \n" , acb->host->host_no); + return 0xff; + } + return 0x00; } -static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb) +static uint8_t arcmsr_abort_allcmd(struct AdapterControlBlock *acb) { + uint8_t rtnval = 0; switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_A: { - arcmsr_abort_hba_allcmd(acb); + rtnval = arcmsr_abort_hba_allcmd(acb); } break; case ACB_ADAPTER_TYPE_B: { - arcmsr_abort_hbb_allcmd(acb); + rtnval = arcmsr_abort_hbb_allcmd(acb); } } + return rtnval; } static void arcmsr_pci_unmap_dma(struct CommandControlBlock *ccb) @@ -649,8 +737,7 @@ static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb) case ACB_ADAPTER_TYPE_A : { struct MessageUnit_A __iomem *reg = acb->pmuA; - orig_mask = readl(®->outbound_intmask)|\ - ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE; + orig_mask = readl(®->outbound_intmask); writel(orig_mask|ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, \ ®->outbound_intmask); } @@ -658,8 +745,7 @@ static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb) case ACB_ADAPTER_TYPE_B : { struct MessageUnit_B *reg = acb->pmuB; - orig_mask = readl(reg->iop2drv_doorbell_mask_reg) & \ - (~ARCMSR_IOP2DRV_MESSAGE_CMD_DONE); + orig_mask = readl(reg->iop2drv_doorbell_mask_reg); writel(0, reg->iop2drv_doorbell_mask_reg); } break; @@ -795,12 +881,13 @@ static void arcmsr_remove(struct pci_dev *pdev) struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; int poll_count = 0; - arcmsr_free_sysfs_attr(acb); scsi_remove_host(host); + flush_scheduled_work(); + del_timer_sync(&acb->eternal_timer); + arcmsr_disable_outbound_ints(acb); arcmsr_stop_adapter_bgrb(acb); arcmsr_flush_adapter_cache(acb); - arcmsr_disable_outbound_ints(acb); acb->acb_flags |= ACB_F_SCSISTOPADAPTER; acb->acb_flags &= ~ACB_F_IOP_INITED; @@ -841,7 +928,9 @@ static void arcmsr_shutdown(struct pci_dev *pdev) struct Scsi_Host *host = pci_get_drvdata(pdev); struct AdapterControlBlock *acb = (struct AdapterControlBlock *)host->hostdata; - + del_timer_sync(&acb->eternal_timer); + arcmsr_disable_outbound_ints(acb); + flush_scheduled_work(); arcmsr_stop_adapter_bgrb(acb); arcmsr_flush_adapter_cache(acb); } @@ -861,7 +950,7 @@ static void arcmsr_module_exit(void) module_init(arcmsr_module_init); module_exit(arcmsr_module_exit); -static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb, \ +static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb, u32 intmask_org) { u32 mask; @@ -871,7 +960,8 @@ static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb, \ case ACB_ADAPTER_TYPE_A : { struct MessageUnit_A __iomem *reg = acb->pmuA; mask = intmask_org & ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE | - ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE); + ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE| + ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE); writel(mask, ®->outbound_intmask); acb->outbound_int_enable = ~(intmask_org & mask) & 0x000000ff; } @@ -879,8 +969,10 @@ static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb, \ case ACB_ADAPTER_TYPE_B : { struct MessageUnit_B *reg = acb->pmuB; - mask = intmask_org | (ARCMSR_IOP2DRV_DATA_WRITE_OK | \ - ARCMSR_IOP2DRV_DATA_READ_OK | ARCMSR_IOP2DRV_CDB_DONE); + mask = intmask_org | (ARCMSR_IOP2DRV_DATA_WRITE_OK | + ARCMSR_IOP2DRV_DATA_READ_OK | + ARCMSR_IOP2DRV_CDB_DONE | + ARCMSR_IOP2DRV_MESSAGE_CMD_DONE); writel(mask, reg->iop2drv_doorbell_mask_reg); acb->outbound_int_enable = (intmask_org | mask) & 0x0000000f; } @@ -1048,8 +1140,8 @@ static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb) } case ACB_ADAPTER_TYPE_B: { struct MessageUnit_B *reg = acb->pmuB; - iounmap(reg->drv2iop_doorbell_reg - ARCMSR_DRV2IOP_DOORBELL); - iounmap(reg->ioctl_wbuffer_reg - ARCMSR_IOCTL_WBUFFER); + iounmap((u8 *)reg->drv2iop_doorbell_reg - ARCMSR_DRV2IOP_DOORBELL); + iounmap((u8 *)reg->ioctl_wbuffer_reg - ARCMSR_IOCTL_WBUFFER); dma_free_coherent(&acb->pdev->dev, (ARCMSR_MAX_FREECCB_NUM * sizeof(struct CommandControlBlock) + 0x20 + sizeof(struct MessageUnit_B)), acb->dma_coherent, acb->dma_coherent_handle); @@ -1249,13 +1341,36 @@ static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb) reg->doneq_index = index; } } +/* +********************************************************************************** +** Handle a message interrupt +** +** The only message interrupt we expect is in response to a query for the current adapter config. +** We want this in order to compare the drivemap so that we can detect newly-attached drives. +********************************************************************************** +*/ +static void arcmsr_hba_message_isr(struct AdapterControlBlock *acb) +{ + struct MessageUnit_A *reg = acb->pmuA; + + /*clear interrupt and message state*/ + writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT, ®->outbound_intstatus); + schedule_work(&acb->arcmsr_do_message_isr_bh); +} +static void arcmsr_hbb_message_isr(struct AdapterControlBlock *acb) +{ + struct MessageUnit_B *reg = acb->pmuB; + /*clear interrupt and message state*/ + writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN, reg->iop2drv_doorbell_reg); + schedule_work(&acb->arcmsr_do_message_isr_bh); +} static int arcmsr_handle_hba_isr(struct AdapterControlBlock *acb) { uint32_t outbound_intstatus; struct MessageUnit_A __iomem *reg = acb->pmuA; - outbound_intstatus = readl(®->outbound_intstatus) & \ + outbound_intstatus = readl(®->outbound_intstatus) & acb->outbound_int_enable; if (!(outbound_intstatus & ARCMSR_MU_OUTBOUND_HANDLE_INT)) { return 1; @@ -1267,6 +1382,10 @@ static int arcmsr_handle_hba_isr(struct AdapterControlBlock *acb) if (outbound_intstatus & ARCMSR_MU_OUTBOUND_POSTQUEUE_INT) { arcmsr_hba_postqueue_isr(acb); } + if (outbound_intstatus & ARCMSR_MU_OUTBOUND_MESSAGE0_INT) { + /* messenger of "driver to iop commands" */ + arcmsr_hba_message_isr(acb); + } return 0; } @@ -1275,13 +1394,14 @@ static int arcmsr_handle_hbb_isr(struct AdapterControlBlock *acb) uint32_t outbound_doorbell; struct MessageUnit_B *reg = acb->pmuB; - outbound_doorbell = readl(reg->iop2drv_doorbell_reg) & \ + outbound_doorbell = readl(reg->iop2drv_doorbell_reg) & acb->outbound_int_enable; if (!outbound_doorbell) return 1; writel(~outbound_doorbell, reg->iop2drv_doorbell_reg); - /*in case the last action of doorbell interrupt clearance is cached, this action can push HW to write down the clear bit*/ + /*in case the last action of doorbell interrupt clearance is cached, + this action can push HW to write down the clear bit*/ readl(reg->iop2drv_doorbell_reg); writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell_reg); if (outbound_doorbell & ARCMSR_IOP2DRV_DATA_WRITE_OK) { @@ -1293,6 +1413,10 @@ static int arcmsr_handle_hbb_isr(struct AdapterControlBlock *acb) if (outbound_doorbell & ARCMSR_IOP2DRV_CDB_DONE) { arcmsr_hbb_postqueue_isr(acb); } + if (outbound_doorbell & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) { + /* messenger of "driver to iop commands" */ + arcmsr_hbb_message_isr(acb); + } return 0; } @@ -1360,7 +1484,7 @@ void arcmsr_post_ioctldata2iop(struct AdapterControlBlock *acb) } } -static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \ +static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, struct scsi_cmnd *cmd) { struct CMD_MESSAGE_FIELD *pcmdmessagefld; @@ -1398,6 +1522,13 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \ retvalue = ARCMSR_MESSAGE_FAIL; goto message_out; } + + if (!acb->fw_state) { + pcmdmessagefld->cmdmessage.ReturnCode = + ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; + goto message_out; + } + ptmpQbuffer = ver_addr; while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex) && (allxfer_len < 1031)) { @@ -1444,6 +1575,12 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \ retvalue = ARCMSR_MESSAGE_FAIL; goto message_out; } + if (!acb->fw_state) { + pcmdmessagefld->cmdmessage.ReturnCode = + ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; + goto message_out; + } + ptmpuserbuffer = ver_addr; user_len = pcmdmessagefld->cmdmessage.Length; memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len); @@ -1496,6 +1633,11 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \ case ARCMSR_MESSAGE_CLEAR_RQBUFFER: { uint8_t *pQbuffer = acb->rqbuffer; + if (!acb->fw_state) { + pcmdmessagefld->cmdmessage.ReturnCode = + ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; + goto message_out; + } if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; @@ -1511,6 +1653,11 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \ case ARCMSR_MESSAGE_CLEAR_WQBUFFER: { uint8_t *pQbuffer = acb->wqbuffer; + if (!acb->fw_state) { + pcmdmessagefld->cmdmessage.ReturnCode = + ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; + goto message_out; + } if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; @@ -1529,6 +1676,11 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \ case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: { uint8_t *pQbuffer; + if (!acb->fw_state) { + pcmdmessagefld->cmdmessage.ReturnCode = + ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; + goto message_out; + } if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; @@ -1551,13 +1703,22 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \ break; case ARCMSR_MESSAGE_RETURN_CODE_3F: { + if (!acb->fw_state) { + pcmdmessagefld->cmdmessage.ReturnCode = + ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; + goto message_out; + } pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_3F; } break; case ARCMSR_MESSAGE_SAY_HELLO: { int8_t *hello_string = "Hello! I am ARCMSR"; - + if (!acb->fw_state) { + pcmdmessagefld->cmdmessage.ReturnCode = + ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; + goto message_out; + } memcpy(pcmdmessagefld->messagedatabuffer, hello_string , (int16_t)strlen(hello_string)); pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; @@ -1565,10 +1726,20 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \ break; case ARCMSR_MESSAGE_SAY_GOODBYE: + if (!acb->fw_state) { + pcmdmessagefld->cmdmessage.ReturnCode = + ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; + goto message_out; + } arcmsr_iop_parking(acb); break; case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE: + if (!acb->fw_state) { + pcmdmessagefld->cmdmessage.ReturnCode = + ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON; + goto message_out; + } arcmsr_flush_adapter_cache(acb); break; @@ -1651,16 +1822,57 @@ static int arcmsr_queue_command(struct scsi_cmnd *cmd, struct CommandControlBlock *ccb; int target = cmd->device->id; int lun = cmd->device->lun; - + uint8_t scsicmd = cmd->cmnd[0]; cmd->scsi_done = done; cmd->host_scribble = NULL; cmd->result = 0; + + if ((scsicmd == SYNCHRONIZE_CACHE) || (scsicmd == SEND_DIAGNOSTIC)) { + if (acb->devstate[target][lun] == ARECA_RAID_GONE) { + cmd->result = (DID_NO_CONNECT << 16); + } + cmd->scsi_done(cmd); + return 0; + } + if (acb->acb_flags & ACB_F_BUS_RESET) { - printk(KERN_NOTICE "arcmsr%d: bus reset" - " and return busy \n" - , acb->host->host_no); + switch (acb->adapter_type) { + case ACB_ADAPTER_TYPE_A: { + struct MessageUnit_A __iomem *reg = acb->pmuA; + uint32_t intmask_org, outbound_doorbell; + + if ((readl(®->outbound_msgaddr1) & + ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0) { + printk(KERN_NOTICE "arcmsr%d: bus reset and return busy\n", + acb->host->host_no); return SCSI_MLQUEUE_HOST_BUSY; } + + acb->acb_flags &= ~ACB_F_FIRMWARE_TRAP; + printk(KERN_NOTICE "arcmsr%d: hardware bus reset and reset ok\n", + acb->host->host_no); + /* disable all outbound interrupt */ + intmask_org = arcmsr_disable_outbound_ints(acb); + arcmsr_get_firmware_spec(acb, 1); + /*start background rebuild*/ + arcmsr_start_adapter_bgrb(acb); + /* clear Qbuffer if door bell ringed */ + outbound_doorbell = readl(®->outbound_doorbell); + /*clear interrupt */ + writel(outbound_doorbell, ®->outbound_doorbell); + writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, + ®->inbound_doorbell); + /* enable outbound Post Queue,outbound doorbell Interrupt */ + arcmsr_enable_outbound_ints(acb, intmask_org); + acb->acb_flags |= ACB_F_IOP_INITED; + acb->acb_flags &= ~ACB_F_BUS_RESET; + } + break; + case ACB_ADAPTER_TYPE_B: { + } + } + } + if (target == 16) { /* virtual device for iop message transfer */ arcmsr_handle_virtual_command(acb, cmd); @@ -1699,21 +1911,25 @@ static int arcmsr_queue_command(struct scsi_cmnd *cmd, return 0; } -static void arcmsr_get_hba_config(struct AdapterControlBlock *acb) +static void *arcmsr_get_hba_config(struct AdapterControlBlock *acb, int mode) { struct MessageUnit_A __iomem *reg = acb->pmuA; char *acb_firm_model = acb->firm_model; char *acb_firm_version = acb->firm_version; + char *acb_device_map = acb->device_map; char __iomem *iop_firm_model = (char __iomem *)(®->message_rwbuffer[15]); char __iomem *iop_firm_version = (char __iomem *)(®->message_rwbuffer[17]); + char __iomem *iop_device_map = (char __iomem *) (®->message_rwbuffer[21]); int count; writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); if (arcmsr_hba_wait_msgint_ready(acb)) { printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ miscellaneous data' timeout \n", acb->host->host_no); + return NULL; } + if (mode == 1) { count = 8; while (count) { *acb_firm_model = readb(iop_firm_model); @@ -1730,34 +1946,48 @@ static void arcmsr_get_hba_config(struct AdapterControlBlock *acb) count--; } + count = 16; + while (count) { + *acb_device_map = readb(iop_device_map); + acb_device_map++; + iop_device_map++; + count--; + } + printk(KERN_INFO "ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n" , acb->host->host_no , acb->firm_version); - + acb->signature = readl(®->message_rwbuffer[0]); acb->firm_request_len = readl(®->message_rwbuffer[1]); acb->firm_numbers_queue = readl(®->message_rwbuffer[2]); acb->firm_sdram_size = readl(®->message_rwbuffer[3]); acb->firm_hd_channels = readl(®->message_rwbuffer[4]); } - -static void arcmsr_get_hbb_config(struct AdapterControlBlock *acb) + return reg->message_rwbuffer; +} +static void __iomem *arcmsr_get_hbb_config(struct AdapterControlBlock *acb, int mode) { struct MessageUnit_B *reg = acb->pmuB; uint32_t __iomem *lrwbuffer = reg->msgcode_rwbuffer_reg; char *acb_firm_model = acb->firm_model; char *acb_firm_version = acb->firm_version; + char *acb_device_map = acb->device_map; char __iomem *iop_firm_model = (char __iomem *)(&lrwbuffer[15]); /*firm_model,15,60-67*/ char __iomem *iop_firm_version = (char __iomem *)(&lrwbuffer[17]); /*firm_version,17,68-83*/ + char __iomem *iop_device_map = (char __iomem *) (&lrwbuffer[21]); + /*firm_version,21,84-99*/ int count; writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell_reg); if (arcmsr_hbb_wait_msgint_ready(acb)) { printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ miscellaneous data' timeout \n", acb->host->host_no); + return NULL; } + if (mode == 1) { count = 8; while (count) { @@ -1776,11 +2006,20 @@ static void arcmsr_get_hbb_config(struct AdapterControlBlock *acb) count--; } + count = 16; + while (count) { + *acb_device_map = readb(iop_device_map); + acb_device_map++; + iop_device_map++; + count--; + } + printk(KERN_INFO "ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n", acb->host->host_no, acb->firm_version); - lrwbuffer++; + acb->signature = readl(lrwbuffer++); + /*firm_signature,1,00-03*/ acb->firm_request_len = readl(lrwbuffer++); /*firm_request_len,1,04-07*/ acb->firm_numbers_queue = readl(lrwbuffer++); @@ -1790,20 +2029,23 @@ static void arcmsr_get_hbb_config(struct AdapterControlBlock *acb) acb->firm_hd_channels = readl(lrwbuffer); /*firm_ide_channels,4,16-19*/ } - -static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb) + return reg->msgcode_rwbuffer_reg; +} +static void *arcmsr_get_firmware_spec(struct AdapterControlBlock *acb, int mode) { + void *rtnval = 0; switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_A: { - arcmsr_get_hba_config(acb); + rtnval = arcmsr_get_hba_config(acb, mode); } break; case ACB_ADAPTER_TYPE_B: { - arcmsr_get_hbb_config(acb); + rtnval = arcmsr_get_hbb_config(acb, mode); } break; } + return rtnval; } static void arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb, @@ -2043,6 +2285,66 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb) } } +static void arcmsr_request_hba_device_map(struct AdapterControlBlock *acb) +{ + struct MessageUnit_A __iomem *reg = acb->pmuA; + + if (unlikely(atomic_read(&acb->rq_map_token) == 0)) { + acb->fw_state = false; + } else { + /*to prevent rq_map_token from changing by other interrupt, then + avoid the dead-lock*/ + acb->fw_state = true; + atomic_dec(&acb->rq_map_token); + if (!(acb->fw_state) || + (acb->ante_token_value == atomic_read(&acb->rq_map_token))) { + atomic_set(&acb->rq_map_token, 16); + } + acb->ante_token_value = atomic_read(&acb->rq_map_token); + writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); + } + mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6000)); + return; +} + +static void arcmsr_request_hbb_device_map(struct AdapterControlBlock *acb) +{ + struct MessageUnit_B __iomem *reg = acb->pmuB; + + if (unlikely(atomic_read(&acb->rq_map_token) == 0)) { + acb->fw_state = false; + } else { + /*to prevent rq_map_token from changing by other interrupt, then + avoid the dead-lock*/ + acb->fw_state = true; + atomic_dec(&acb->rq_map_token); + if (!(acb->fw_state) || + (acb->ante_token_value == atomic_read(&acb->rq_map_token))) { + atomic_set(&acb->rq_map_token, 16); + } + acb->ante_token_value = atomic_read(&acb->rq_map_token); + writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell_reg); + } + mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6000)); + return; +} + +static void arcmsr_request_device_map(unsigned long pacb) +{ + struct AdapterControlBlock *acb = (struct AdapterControlBlock *)pacb; + + switch (acb->adapter_type) { + case ACB_ADAPTER_TYPE_A: { + arcmsr_request_hba_device_map(acb); + } + break; + case ACB_ADAPTER_TYPE_B: { + arcmsr_request_hbb_device_map(acb); + } + break; + } +} + static void arcmsr_start_hba_bgrb(struct AdapterControlBlock *acb) { struct MessageUnit_A __iomem *reg = acb->pmuA; @@ -2121,6 +2423,60 @@ static void arcmsr_enable_eoi_mode(struct AdapterControlBlock *acb) return; } +static void arcmsr_hardware_reset(struct AdapterControlBlock *acb) +{ + uint8_t value[64]; + int i; + + /* backup pci config data */ + for (i = 0; i < 64; i++) { + pci_read_config_byte(acb->pdev, i, &value[i]); + } + /* hardware reset signal */ + pci_write_config_byte(acb->pdev, 0x84, 0x20); + msleep(1000); + /* write back pci config data */ + for (i = 0; i < 64; i++) { + pci_write_config_byte(acb->pdev, i, value[i]); + } + msleep(1000); + return; +} +/* +**************************************************************************** +**************************************************************************** +*/ +#ifdef CONFIG_SCSI_ARCMSR_RESET + int arcmsr_sleep_for_bus_reset(struct scsi_cmnd *cmd) + { + struct Scsi_Host *shost = NULL; + spinlock_t *host_lock = NULL; + int i, isleep; + + shost = cmd->device->host; + host_lock = shost->host_lock; + + printk(KERN_NOTICE "Host %d bus reset over, sleep %d seconds (busy %d, can queue %d) ...........\n", + shost->host_no, sleeptime, shost->host_busy, shost->can_queue); + isleep = sleeptime / 10; + spin_unlock_irq(host_lock); + if (isleep > 0) { + for (i = 0; i < isleep; i++) { + msleep(10000); + printk(KERN_NOTICE "^%d^\n", i); + } + } + + isleep = sleeptime % 10; + if (isleep > 0) { + msleep(isleep * 1000); + printk(KERN_NOTICE "^v^\n"); + } + spin_lock_irq(host_lock); + printk(KERN_NOTICE "***** wake up *****\n"); + return 0; + } +#endif static void arcmsr_iop_init(struct AdapterControlBlock *acb) { uint32_t intmask_org; @@ -2129,7 +2485,7 @@ static void arcmsr_iop_init(struct AdapterControlBlock *acb) intmask_org = arcmsr_disable_outbound_ints(acb); arcmsr_wait_firmware_ready(acb); arcmsr_iop_confirm(acb); - arcmsr_get_firmware_spec(acb); + arcmsr_get_firmware_spec(acb, 1); /*start background rebuild*/ arcmsr_start_adapter_bgrb(acb); /* empty doorbell Qbuffer if door bell ringed */ @@ -2140,51 +2496,110 @@ static void arcmsr_iop_init(struct AdapterControlBlock *acb) acb->acb_flags |= ACB_F_IOP_INITED; } -static void arcmsr_iop_reset(struct AdapterControlBlock *acb) +static uint8_t arcmsr_iop_reset(struct AdapterControlBlock *acb) { struct CommandControlBlock *ccb; uint32_t intmask_org; + uint8_t rtnval = 0x00; int i = 0; if (atomic_read(&acb->ccboutstandingcount) != 0) { + /* disable all outbound interrupt */ + intmask_org = arcmsr_disable_outbound_ints(acb); /* talk to iop 331 outstanding command aborted */ - arcmsr_abort_allcmd(acb); - + rtnval = arcmsr_abort_allcmd(acb); /* wait for 3 sec for all command aborted*/ ssleep(3); - - /* disable all outbound interrupt */ - intmask_org = arcmsr_disable_outbound_ints(acb); /* clear all outbound posted Q */ arcmsr_done4abort_postqueue(acb); for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { ccb = acb->pccb_pool[i]; if (ccb->startdone == ARCMSR_CCB_START) { - ccb->startdone = ARCMSR_CCB_ABORTED; arcmsr_ccb_complete(ccb, 1); } } + atomic_set(&acb->ccboutstandingcount, 0); /* enable all outbound interrupt */ arcmsr_enable_outbound_ints(acb, intmask_org); + return rtnval; } + return rtnval; } static int arcmsr_bus_reset(struct scsi_cmnd *cmd) { struct AdapterControlBlock *acb = (struct AdapterControlBlock *)cmd->device->host->hostdata; - int i; + int retry = 0; - acb->num_resets++; + if (acb->acb_flags & ACB_F_BUS_RESET) + return SUCCESS; + + printk(KERN_NOTICE "arcmsr%d: bus reset ..... \n", acb->adapter_index); acb->acb_flags |= ACB_F_BUS_RESET; - for (i = 0; i < 400; i++) { - if (!atomic_read(&acb->ccboutstandingcount)) + acb->num_resets++; + while (atomic_read(&acb->ccboutstandingcount) != 0 && retry < 4) { + arcmsr_interrupt(acb); + retry++; + } + + if (arcmsr_iop_reset(acb)) { + switch (acb->adapter_type) { + case ACB_ADAPTER_TYPE_A: { + printk(KERN_NOTICE "arcmsr%d: do hardware bus reset, num_resets = %d num_aborts = %d \n", + acb->adapter_index, acb->num_resets, acb->num_aborts); + arcmsr_hardware_reset(acb); + acb->acb_flags |= ACB_F_FIRMWARE_TRAP; + acb->acb_flags &= ~ACB_F_IOP_INITED; + #ifdef CONFIG_SCSI_ARCMSR_RESET + struct MessageUnit_A __iomem *reg = acb->pmuA; + uint32_t intmask_org, outbound_doorbell; + int retry_count = 0; +sleep_again: + arcmsr_sleep_for_bus_reset(cmd); + if ((readl(®->outbound_msgaddr1) & + ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0) { + printk(KERN_NOTICE "arcmsr%d: hardware bus reset and return busy, retry=%d \n", + acb->host->host_no, retry_count); + if (retry_count > retrycount) { + printk(KERN_NOTICE "arcmsr%d: hardware bus reset and return busy, retry aborted \n", + acb->host->host_no); + return SUCCESS; + } + retry_count++; + goto sleep_again; + } + acb->acb_flags &= ~ACB_F_FIRMWARE_TRAP; + acb->acb_flags |= ACB_F_IOP_INITED; + acb->acb_flags &= ~ACB_F_BUS_RESET; + printk(KERN_NOTICE "arcmsr%d: hardware bus reset and reset ok \n", + acb->host->host_no); + /* disable all outbound interrupt */ + intmask_org = arcmsr_disable_outbound_ints(acb); + arcmsr_get_firmware_spec(acb, 1); + /*start background rebuild*/ + arcmsr_start_adapter_bgrb(acb); + /* clear Qbuffer if door bell ringed */ + outbound_doorbell = readl(®->outbound_doorbell); + writel(outbound_doorbell, ®->outbound_doorbell); /*clear interrupt */ + writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, ®->inbound_doorbell); + /* enable outbound Post Queue,outbound doorbell Interrupt */ + arcmsr_enable_outbound_ints(acb, intmask_org); + atomic_set(&acb->rq_map_token, 16); + init_timer(&acb->eternal_timer); + acb->eternal_timer.expires = jiffies + msecs_to_jiffies(20*HZ); + acb->eternal_timer.data = (unsigned long) acb; + acb->eternal_timer.function = &arcmsr_request_device_map; + add_timer(&acb->eternal_timer); + #endif + } break; - arcmsr_interrupt(acb);/* FIXME: need spinlock */ - msleep(25); + case ACB_ADAPTER_TYPE_B: { } - arcmsr_iop_reset(acb); + } + } else { acb->acb_flags &= ~ACB_F_BUS_RESET; + } return SUCCESS; } @@ -2277,98 +2692,3 @@ static const char *arcmsr_info(struct Scsi_Host *host) ARCMSR_DRIVER_VERSION); return buf; } -#ifdef CONFIG_SCSI_ARCMSR_AER -static pci_ers_result_t arcmsr_pci_slot_reset(struct pci_dev *pdev) -{ - struct Scsi_Host *host = pci_get_drvdata(pdev); - struct AdapterControlBlock *acb = - (struct AdapterControlBlock *) host->hostdata; - uint32_t intmask_org; - int i, j; - - if (pci_enable_device(pdev)) { - return PCI_ERS_RESULT_DISCONNECT; - } - pci_set_master(pdev); - intmask_org = arcmsr_disable_outbound_ints(acb); - acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED | - ACB_F_MESSAGE_RQBUFFER_CLEARED | - ACB_F_MESSAGE_WQBUFFER_READED); - acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER; - for (i = 0; i < ARCMSR_MAX_TARGETID; i++) - for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++) - acb->devstate[i][j] = ARECA_RAID_GONE; - - arcmsr_wait_firmware_ready(acb); - arcmsr_iop_confirm(acb); - /* disable all outbound interrupt */ - arcmsr_get_firmware_spec(acb); - /*start background rebuild*/ - arcmsr_start_adapter_bgrb(acb); - /* empty doorbell Qbuffer if door bell ringed */ - arcmsr_clear_doorbell_queue_buffer(acb); - arcmsr_enable_eoi_mode(acb); - /* enable outbound Post Queue,outbound doorbell Interrupt */ - arcmsr_enable_outbound_ints(acb, intmask_org); - acb->acb_flags |= ACB_F_IOP_INITED; - - pci_enable_pcie_error_reporting(pdev); - return PCI_ERS_RESULT_RECOVERED; -} - -static void arcmsr_pci_ers_need_reset_forepart(struct pci_dev *pdev) -{ - struct Scsi_Host *host = pci_get_drvdata(pdev); - struct AdapterControlBlock *acb = (struct AdapterControlBlock *)host->hostdata; - struct CommandControlBlock *ccb; - uint32_t intmask_org; - int i = 0; - - if (atomic_read(&acb->ccboutstandingcount) != 0) { - /* talk to iop 331 outstanding command aborted */ - arcmsr_abort_allcmd(acb); - /* wait for 3 sec for all command aborted*/ - ssleep(3); - /* disable all outbound interrupt */ - intmask_org = arcmsr_disable_outbound_ints(acb); - /* clear all outbound posted Q */ - arcmsr_done4abort_postqueue(acb); - for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { - ccb = acb->pccb_pool[i]; - if (ccb->startdone == ARCMSR_CCB_START) { - ccb->startdone = ARCMSR_CCB_ABORTED; - arcmsr_ccb_complete(ccb, 1); - } - } - /* enable all outbound interrupt */ - arcmsr_enable_outbound_ints(acb, intmask_org); - } - pci_disable_device(pdev); -} - -static void arcmsr_pci_ers_disconnect_forepart(struct pci_dev *pdev) -{ - struct Scsi_Host *host = pci_get_drvdata(pdev); - struct AdapterControlBlock *acb = \ - (struct AdapterControlBlock *)host->hostdata; - - arcmsr_stop_adapter_bgrb(acb); - arcmsr_flush_adapter_cache(acb); -} - -static pci_ers_result_t arcmsr_pci_error_detected(struct pci_dev *pdev, - pci_channel_state_t state) -{ - switch (state) { - case pci_channel_io_frozen: - arcmsr_pci_ers_need_reset_forepart(pdev); - return PCI_ERS_RESULT_NEED_RESET; - case pci_channel_io_perm_failure: - arcmsr_pci_ers_disconnect_forepart(pdev); - return PCI_ERS_RESULT_DISCONNECT; - break; - default: - return PCI_ERS_RESULT_NEED_RESET; - } -} -#endif -- cgit v1.2.3 From 5487ab4a5a71e955fef7094a0624df0542da91ef Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Tue, 25 May 2010 16:40:47 +0800 Subject: SFI: add support for v0.81 spec There are 2 major changes from v0.81 to v0.7: 1. Consolidating the SPIB/I2CB tables into a new DEVS table, which is more expandable and can support other bus types than spi/i2c. 2. Creating a new GPIO table, which list all the GPIO pins used in the platform. However, to avoid breaking current platforms who use SFI v0.7 version firmware, the definitions for SPIB/I2CB will still be kept for a while Signed-off-by: Feng Tang Signed-off-by: Len Brown --- drivers/sfi/sfi_core.c | 2 +- include/linux/sfi.h | 24 +++++++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/sfi/sfi_core.c b/drivers/sfi/sfi_core.c index b204a0929139..aba6a461365b 100644 --- a/drivers/sfi/sfi_core.c +++ b/drivers/sfi/sfi_core.c @@ -390,7 +390,7 @@ void __init sfi_init(void) if (sfi_disabled) return; - pr_info("Simple Firmware Interface v0.7 http://simplefirmware.org\n"); + pr_info("Simple Firmware Interface v0.81 http://simplefirmware.org\n"); if (sfi_find_syst() || sfi_parse_syst() || sfi_platform_init()) disable_sfi(); diff --git a/include/linux/sfi.h b/include/linux/sfi.h index 9a6f7607174e..0299b4ce63db 100644 --- a/include/linux/sfi.h +++ b/include/linux/sfi.h @@ -73,6 +73,8 @@ #define SFI_SIG_SPIB "SPIB" #define SFI_SIG_I2CB "I2CB" #define SFI_SIG_GPEM "GPEM" +#define SFI_SIG_DEVS "DEVS" +#define SFI_SIG_GPIO "GPIO" #define SFI_SIGNATURE_SIZE 4 #define SFI_OEM_ID_SIZE 6 @@ -145,6 +147,27 @@ struct sfi_rtc_table_entry { u32 irq; } __packed; +struct sfi_device_table_entry { + u8 type; /* bus type, I2C, SPI or ...*/ +#define SFI_DEV_TYPE_SPI 0 +#define SFI_DEV_TYPE_I2C 1 +#define SFI_DEV_TYPE_UART 2 +#define SFI_DEV_TYPE_HSI 3 +#define SFI_DEV_TYPE_IPC 4 + + u8 host_num; /* attached to host 0, 1...*/ + u16 addr; + u8 irq; + u32 max_freq; + char name[16]; +} __packed; + +struct sfi_gpio_table_entry { + char controller_name[16]; + u16 pin_no; + char pin_name[16]; +} __packed; + struct sfi_spi_table_entry { u16 host_num; /* attached to host 0, 1...*/ u16 cs; /* chip select */ @@ -166,7 +189,6 @@ struct sfi_gpe_table_entry { u16 phys_id; /* physical GPE id */ } __packed; - typedef int (*sfi_table_handler) (struct sfi_table_header *table); #ifdef CONFIG_SFI -- cgit v1.2.3 From 8a52da632ceb9d8b776494563df579e87b7b586b Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 15 May 2010 11:46:12 +0200 Subject: [SCSI] aacraid: Eliminate use after free The debugging code using the freed structure is moved before the kfree. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @free@ expression E; position p; @@ kfree@p(E) @@ expression free.E, subE<=free.E, E1; position free.p; @@ kfree@p(E) ... ( subE = E1 | * E ) // Signed-off-by: Julia Lawall Signed-off-by: James Bottomley --- drivers/scsi/aacraid/commctrl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 9c0c91178538..1a5bf5724750 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c @@ -655,9 +655,9 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) /* Does this really need to be GFP_DMA? */ p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); if(!p) { - kfree (usg); - dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", + dprintk((KERN_DEBUG "aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", usg->sg[i].count,i,usg->count)); + kfree(usg); rcode = -ENOMEM; goto cleanup; } -- cgit v1.2.3 From f9e8894ae5157796dd69249c56062042d02a431d Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 18 Mar 2010 15:39:30 -0400 Subject: [SCSI] fix race in scsi_target_reap This patch (as1357) fixes a race in SCSI target allocation and release. Putting a target in the STARGET_DEL state isn't protected by the host lock, so an old target structure could be reused by a new device even though it's about to be deleted. The cure is to change the state while still holding the host lock. Signed-off-by: Alan Stern Signed-off-by: James Bottomley --- drivers/scsi/scsi_scan.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index c992ecf4e372..a77468cd5a33 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -492,19 +492,20 @@ void scsi_target_reap(struct scsi_target *starget) struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); unsigned long flags; enum scsi_target_state state; - int empty; + int empty = 0; spin_lock_irqsave(shost->host_lock, flags); state = starget->state; - empty = --starget->reap_ref == 0 && - list_empty(&starget->devices) ? 1 : 0; + if (--starget->reap_ref == 0 && list_empty(&starget->devices)) { + empty = 1; + starget->state = STARGET_DEL; + } spin_unlock_irqrestore(shost->host_lock, flags); if (!empty) return; BUG_ON(state == STARGET_DEL); - starget->state = STARGET_DEL; if (state == STARGET_CREATED) scsi_target_destroy(starget); else -- cgit v1.2.3 From b17e0969dc184c66ed8934e130344621829484a3 Mon Sep 17 00:00:00 2001 From: Chien Tung Date: Tue, 25 May 2010 10:13:09 -0500 Subject: RDMA/nes: Fix incorrect unlock in nes_process_mac_intr() Commit ce6e74f2 ("RDMA/nes: Make nesadapter->phy_lock usage consistent") introduced a problem where phy_lock was only unlocked within an if statement and so nes_process_mac_intr() could return with phy_lock still held. Fix this. This was discovered because of the sparse warning: drivers/infiniband/hw/nes/nes_hw.c:2643:9: warning: context imbalance in 'nes_process_mac_intr' - different lock contexts for basic block Reported-by: Roland Dreier Signed-off-by: Chien Tung Signed-off-by: Roland Dreier --- drivers/infiniband/hw/nes/nes_hw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index bb9c77504fe2..57874a165083 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c @@ -2584,7 +2584,6 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) break; } } - spin_unlock_irqrestore(&nesadapter->phy_lock, flags); if (phy_data & 0x0004) { if (wide_ppm_offset && @@ -2639,6 +2638,8 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) } } + spin_unlock_irqrestore(&nesadapter->phy_lock, flags); + nesadapter->mac_sw_state[mac_number] = NES_MAC_SW_IDLE; } -- cgit v1.2.3 From 578454ff7eab61d13a26b568f99a89a2c9edc881 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 20 May 2010 18:07:20 +0200 Subject: driver core: add devname module aliases to allow module on-demand auto-loading This adds: alias: devname: to some common kernel modules, which will allow the on-demand loading of the kernel module when the device node is accessed. Ideally all these modules would be compiled-in, but distros seems too much in love with their modularization that we need to cover the common cases with this new facility. It will allow us to remove a bunch of pretty useless init scripts and modprobes from init scripts. The static device node aliases will be carried in the module itself. The program depmod will extract this information to a file in the module directory: $ cat /lib/modules/2.6.34-00650-g537b60d-dirty/modules.devname # Device nodes to trigger on-demand module loading. microcode cpu/microcode c10:184 fuse fuse c10:229 ppp_generic ppp c108:0 tun net/tun c10:200 dm_mod mapper/control c10:235 Udev will pick up the depmod created file on startup and create all the static device nodes which the kernel modules specify, so that these modules get automatically loaded when the device node is accessed: $ /sbin/udevd --debug ... static_dev_create_from_modules: mknod '/dev/cpu/microcode' c10:184 static_dev_create_from_modules: mknod '/dev/fuse' c10:229 static_dev_create_from_modules: mknod '/dev/ppp' c108:0 static_dev_create_from_modules: mknod '/dev/net/tun' c10:200 static_dev_create_from_modules: mknod '/dev/mapper/control' c10:235 udev_rules_apply_static_dev_perms: chmod '/dev/net/tun' 0666 udev_rules_apply_static_dev_perms: chmod '/dev/fuse' 0666 A few device nodes are switched to statically allocated numbers, to allow the static nodes to work. This might also useful for systems which still run a plain static /dev, which is completely unsafe to use with any dynamic minor numbers. Note: The devname aliases must be limited to the *common* and *single*instance* device nodes, like the misc devices, and never be used for conceptually limited systems like the loop devices, which should rather get fixed properly and get a control node for losetup to talk to, instead of creating a random number of device nodes in advance, regardless if they are ever used. This facility is to hide the mess distros are creating with too modualized kernels, and just to hide that these modules are not compiled-in, and not to paper-over broken concepts. Thanks! :) Cc: Greg Kroah-Hartman Cc: David S. Miller Cc: Miklos Szeredi Cc: Chris Mason Cc: Alasdair G Kergon Cc: Tigran Aivazian Cc: Ian Kent Signed-Off-By: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- Documentation/devices.txt | 2 ++ arch/x86/kernel/microcode_core.c | 1 + drivers/net/ppp_generic.c | 4 ++-- drivers/net/tun.c | 1 + fs/autofs4/dev-ioctl.c | 5 ++++- fs/btrfs/super.c | 5 ++++- fs/fuse/dev.c | 1 + include/linux/miscdevice.h | 2 ++ 8 files changed, 17 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/Documentation/devices.txt b/Documentation/devices.txt index 53d64d382343..1d83d124056c 100644 --- a/Documentation/devices.txt +++ b/Documentation/devices.txt @@ -443,6 +443,8 @@ Your cooperation is appreciated. 231 = /dev/snapshot System memory snapshot device 232 = /dev/kvm Kernel-based virtual machine (hardware virtualization extensions) 233 = /dev/kmview View-OS A process with a view + 234 = /dev/btrfs-control Btrfs control device + 235 = /dev/autofs Autofs control device 240-254 Reserved for local use 255 Reserved for MISC_DYNAMIC_MINOR diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index 2cd8c544e41a..fa6551d36c10 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c @@ -260,6 +260,7 @@ static void microcode_dev_exit(void) } MODULE_ALIAS_MISCDEV(MICROCODE_MINOR); +MODULE_ALIAS("devname:cpu/microcode"); #else #define microcode_dev_init() 0 #define microcode_dev_exit() do { } while (0) diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 5441688daba7..c5f8eb102bf7 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -2926,5 +2926,5 @@ EXPORT_SYMBOL(ppp_output_wakeup); EXPORT_SYMBOL(ppp_register_compressor); EXPORT_SYMBOL(ppp_unregister_compressor); MODULE_LICENSE("GPL"); -MODULE_ALIAS_CHARDEV_MAJOR(PPP_MAJOR); -MODULE_ALIAS("/dev/ppp"); +MODULE_ALIAS_CHARDEV(PPP_MAJOR, 0); +MODULE_ALIAS("devname:ppp"); diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 97b25533e5fb..005cad689578 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1649,3 +1649,4 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_AUTHOR(DRV_COPYRIGHT); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(TUN_MINOR); +MODULE_ALIAS("devname:net/tun"); diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c index d29b7f6df862..d832062869f6 100644 --- a/fs/autofs4/dev-ioctl.c +++ b/fs/autofs4/dev-ioctl.c @@ -736,11 +736,14 @@ static const struct file_operations _dev_ioctl_fops = { }; static struct miscdevice _autofs_dev_ioctl_misc = { - .minor = MISC_DYNAMIC_MINOR, + .minor = AUTOFS_MINOR, .name = AUTOFS_DEVICE_NAME, .fops = &_dev_ioctl_fops }; +MODULE_ALIAS_MISCDEV(AUTOFS_MINOR); +MODULE_ALIAS("devname:autofs"); + /* Register/deregister misc character device */ int autofs_dev_ioctl_init(void) { diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 1866dff0538e..2909a03e5230 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -832,11 +832,14 @@ static const struct file_operations btrfs_ctl_fops = { }; static struct miscdevice btrfs_misc = { - .minor = MISC_DYNAMIC_MINOR, + .minor = BTRFS_MINOR, .name = "btrfs-control", .fops = &btrfs_ctl_fops }; +MODULE_ALIAS_MISCDEV(BTRFS_MINOR); +MODULE_ALIAS("devname:btrfs-control"); + static int btrfs_interface_init(void) { return misc_register(&btrfs_misc); diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index eb7e9423691f..e53df5ebb2b8 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -18,6 +18,7 @@ #include MODULE_ALIAS_MISCDEV(FUSE_MINOR); +MODULE_ALIAS("devname:fuse"); static struct kmem_cache *fuse_req_cachep; diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h index 8b5f7cc0fba6..b631c46cffd9 100644 --- a/include/linux/miscdevice.h +++ b/include/linux/miscdevice.h @@ -31,6 +31,8 @@ #define FUSE_MINOR 229 #define KVM_MINOR 232 #define VHOST_NET_MINOR 233 +#define BTRFS_MINOR 234 +#define AUTOFS_MINOR 235 #define MISC_DYNAMIC_MINOR 255 struct device; -- cgit v1.2.3 From dd7496f217462a23a9a8a15b9925866eaad76e22 Mon Sep 17 00:00:00 2001 From: Filip Aben Date: Tue, 25 May 2010 16:09:23 -0700 Subject: hso: add support for new products This patch adds a few new product id's for the hso driver. Signed-off-by: Filip Aben Signed-off-by: David S. Miller --- drivers/net/usb/hso.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 9964df199511..0a3c41faea9c 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -475,6 +475,9 @@ static const struct usb_device_id hso_ids[] = { {USB_DEVICE(0x0af0, 0x8302)}, {USB_DEVICE(0x0af0, 0x8304)}, {USB_DEVICE(0x0af0, 0x8400)}, + {USB_DEVICE(0x0af0, 0x8600)}, + {USB_DEVICE(0x0af0, 0x8800)}, + {USB_DEVICE(0x0af0, 0x8900)}, {USB_DEVICE(0x0af0, 0xd035)}, {USB_DEVICE(0x0af0, 0xd055)}, {USB_DEVICE(0x0af0, 0xd155)}, -- cgit v1.2.3 From dd131e76e562fa0c6f9dd53130e8d08d39a0b62c Mon Sep 17 00:00:00 2001 From: Sarveshwar Bandi Date: Tue, 25 May 2010 16:16:32 -0700 Subject: be2net: Bug fix to avoid disabling bottom half during firmware upgrade. Certain firmware commands/operations to upgrade firmware could take several seconds to complete. The code presently disables bottom half during these operations which could lead to unpredictable behaviour in certain cases. This patch now does all firmware upgrade operations asynchronously using a completion variable. Signed-off-by: Sarveshwar Bandi Signed-off-by: David S. Miller --- drivers/net/benet/be.h | 2 ++ drivers/net/benet/be_cmds.c | 19 +++++++++++++++++-- drivers/net/benet/be_main.c | 1 + 3 files changed, 20 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 373c1a563474..b46be490cd2a 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -283,6 +283,8 @@ struct be_adapter { u8 port_type; u8 transceiver; u8 generation; /* BladeEngine ASIC generation */ + u32 flash_status; + struct completion flash_compl; bool sriov_enabled; u32 vf_if_handle[BE_MAX_VF]; diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index e79bf8b9af3b..c911bfb55b19 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -59,6 +59,13 @@ static int be_mcc_compl_process(struct be_adapter *adapter, compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) & CQE_STATUS_COMPL_MASK; + + if ((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) && + (compl->tag1 == CMD_SUBSYSTEM_COMMON)) { + adapter->flash_status = compl_status; + complete(&adapter->flash_compl); + } + if (compl_status == MCC_STATUS_SUCCESS) { if (compl->tag0 == OPCODE_ETH_GET_STATISTICS) { struct be_cmd_resp_get_stats *resp = @@ -1417,6 +1424,7 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, int status; spin_lock_bh(&adapter->mcc_lock); + adapter->flash_status = 0; wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -1428,6 +1436,7 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, be_wrb_hdr_prepare(wrb, cmd->size, false, 1, OPCODE_COMMON_WRITE_FLASHROM); + wrb->tag1 = CMD_SUBSYSTEM_COMMON; be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, OPCODE_COMMON_WRITE_FLASHROM, cmd->size); @@ -1439,10 +1448,16 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, req->params.op_code = cpu_to_le32(flash_opcode); req->params.data_buf_size = cpu_to_le32(buf_size); - status = be_mcc_notify_wait(adapter); + be_mcc_notify(adapter); + spin_unlock_bh(&adapter->mcc_lock); + + if (!wait_for_completion_timeout(&adapter->flash_compl, + msecs_to_jiffies(12000))) + status = -1; + else + status = adapter->flash_status; err: - spin_unlock_bh(&adapter->mcc_lock); return status; } diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 1c79c2009e40..aa065c71ddd8 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2319,6 +2319,7 @@ static int be_ctrl_init(struct be_adapter *adapter) spin_lock_init(&adapter->mcc_lock); spin_lock_init(&adapter->mcc_cq_lock); + init_completion(&adapter->flash_compl); pci_save_state(adapter->pdev); return 0; -- cgit v1.2.3 From f925b1303e0672effc78547353bd2ddfe11f5b5f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 25 May 2010 16:24:03 -0700 Subject: drivers/net/usb/asix.c: Fix pointer cast. Stephen Rothwell reports the following new warning: drivers/net/usb/asix.c: In function 'asix_rx_fixup': drivers/net/usb/asix.c:325: warning: cast from pointer to integer of different size drivers/net/usb/asix.c:354: warning: cast from pointer to integer of different size The code just cares about the low alignment bits, so use an "unsigned long" cast instead of one to "u32". Signed-off-by: David S. Miller --- drivers/net/usb/asix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 31b73310ec77..1f802e90474c 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -322,7 +322,7 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) size = (u16) (header & 0x0000ffff); if ((skb->len) - ((size + 1) & 0xfffe) == 0) { - u8 alignment = (u32)skb->data & 0x3; + u8 alignment = (unsigned long)skb->data & 0x3; if (alignment != 0x2) { /* * not 16bit aligned so use the room provided by @@ -351,7 +351,7 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) } ax_skb = skb_clone(skb, GFP_ATOMIC); if (ax_skb) { - u8 alignment = (u32)packet & 0x3; + u8 alignment = (unsigned long)packet & 0x3; ax_skb->len = size; if (alignment != 0x2) { -- cgit v1.2.3 From 2f20ccf8190b064468cb2c7ba92e757ae37e61b1 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 19 May 2010 22:10:19 +0200 Subject: sata_mv: drop unncessary EH callback resetting Now that BMDMA EH ops are separated out from SFF ops, mv5_ops doesn't have to explicitly reset ->error_handler() and ->post_internal_cmd(). Drop them. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index f3471bc949d3..16bacd389265 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -675,8 +675,6 @@ static struct ata_port_operations mv5_ops = { .freeze = mv_eh_freeze, .thaw = mv_eh_thaw, .hardreset = mv_hardreset, - .error_handler = ata_std_error_handler, /* avoid SFF EH */ - .post_internal_cmd = ATA_OP_NULL, .scr_read = mv5_scr_read, .scr_write = mv5_scr_write, -- cgit v1.2.3 From 37f65b8bc262a5ae4c8e58be92fe3032f0aaaf04 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 19 May 2010 22:10:20 +0200 Subject: libata-sff: ata_sff_irq_clear() is BMDMA specific ata_sff_irq_clear() is BMDMA specific. Rename it to ata_bmdma_irq_clear(), move it to ata_bmdma_port_ops and make ->sff_irq_clear() optional. Note: ata_bmdma_irq_clear() is actually only needed by ata_piix and possibly by sata_sil. This should be moved to respective low level drivers later. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-sff.c | 67 ++++++++++++++++++++++++++---------------------- drivers/ata/pata_bf54x.c | 2 +- drivers/ata/pata_scc.c | 2 +- drivers/ata/sata_nv.c | 2 +- drivers/ata/sata_sil.c | 4 +-- drivers/ata/sata_via.c | 2 +- include/linux/libata.h | 1 + 7 files changed, 44 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 19ddf924944f..55bc4880cbf3 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -63,7 +63,6 @@ const struct ata_port_operations ata_sff_port_ops = { .sff_tf_read = ata_sff_tf_read, .sff_exec_command = ata_sff_exec_command, .sff_data_xfer = ata_sff_data_xfer, - .sff_irq_clear = ata_sff_irq_clear, .sff_drain_fifo = ata_sff_drain_fifo, .lost_interrupt = ata_sff_lost_interrupt, @@ -395,32 +394,11 @@ void ata_sff_irq_on(struct ata_port *ap) ata_sff_set_devctl(ap, ap->ctl); ata_wait_idle(ap); - ap->ops->sff_irq_clear(ap); + if (ap->ops->sff_irq_clear) + ap->ops->sff_irq_clear(ap); } EXPORT_SYMBOL_GPL(ata_sff_irq_on); -/** - * ata_sff_irq_clear - Clear PCI IDE BMDMA interrupt. - * @ap: Port associated with this ATA transaction. - * - * Clear interrupt and error flags in DMA status register. - * - * May be used as the irq_clear() entry in ata_port_operations. - * - * LOCKING: - * spin_lock_irqsave(host lock) - */ -void ata_sff_irq_clear(struct ata_port *ap) -{ - void __iomem *mmio = ap->ioaddr.bmdma_addr; - - if (!mmio) - return; - - iowrite8(ioread8(mmio + ATA_DMA_STATUS), mmio + ATA_DMA_STATUS); -} -EXPORT_SYMBOL_GPL(ata_sff_irq_clear); - /** * ata_sff_tf_load - send taskfile registers to host controller * @ap: Port to which output is sent @@ -1572,7 +1550,8 @@ unsigned int ata_sff_host_intr(struct ata_port *ap, } /* clear irq events */ - ap->ops->sff_irq_clear(ap); + if (ap->ops->sff_irq_clear) + ap->ops->sff_irq_clear(ap); ata_sff_hsm_move(ap, qc, status, 0); @@ -1588,7 +1567,8 @@ idle_irq: #ifdef ATA_IRQ_TRAP if ((ap->stats.idle_irq % 1000) == 0) { ap->ops->sff_check_status(ap); - ap->ops->sff_irq_clear(ap); + if (ap->ops->sff_irq_clear) + ap->ops->sff_irq_clear(ap); ata_port_printk(ap, KERN_WARNING, "irq trap\n"); return 1; } @@ -1658,7 +1638,8 @@ retry: if (idle & (1 << i)) { ap->ops->sff_check_status(ap); - ap->ops->sff_irq_clear(ap); + if (ap->ops->sff_irq_clear) + ap->ops->sff_irq_clear(ap); } else { /* clear INTRQ and check if BUSY cleared */ if (!(ap->ops->sff_check_status(ap) & ATA_BUSY)) @@ -1744,7 +1725,8 @@ void ata_sff_freeze(struct ata_port *ap) */ ap->ops->sff_check_status(ap); - ap->ops->sff_irq_clear(ap); + if (ap->ops->sff_irq_clear) + ap->ops->sff_irq_clear(ap); } EXPORT_SYMBOL_GPL(ata_sff_freeze); @@ -1761,7 +1743,8 @@ void ata_sff_thaw(struct ata_port *ap) { /* clear & re-enable interrupts */ ap->ops->sff_check_status(ap); - ap->ops->sff_irq_clear(ap); + if (ap->ops->sff_irq_clear) + ap->ops->sff_irq_clear(ap); ata_sff_irq_on(ap); } EXPORT_SYMBOL_GPL(ata_sff_thaw); @@ -2580,6 +2563,7 @@ const struct ata_port_operations ata_bmdma_port_ops = { .qc_prep = ata_bmdma_qc_prep, .qc_issue = ata_bmdma_qc_issue, + .sff_irq_clear = ata_bmdma_irq_clear, .bmdma_setup = ata_bmdma_setup, .bmdma_start = ata_bmdma_start, .bmdma_stop = ata_bmdma_stop, @@ -2848,7 +2832,8 @@ void ata_bmdma_error_handler(struct ata_port *ap) /* if we're gonna thaw, make sure IRQ is clear */ if (thaw) { ap->ops->sff_check_status(ap); - ap->ops->sff_irq_clear(ap); + if (ap->ops->sff_irq_clear) + ap->ops->sff_irq_clear(ap); } } @@ -2881,6 +2866,28 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc) } EXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd); +/** + * ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt. + * @ap: Port associated with this ATA transaction. + * + * Clear interrupt and error flags in DMA status register. + * + * May be used as the irq_clear() entry in ata_port_operations. + * + * LOCKING: + * spin_lock_irqsave(host lock) + */ +void ata_bmdma_irq_clear(struct ata_port *ap) +{ + void __iomem *mmio = ap->ioaddr.bmdma_addr; + + if (!mmio) + return; + + iowrite8(ioread8(mmio + ATA_DMA_STATUS), mmio + ATA_DMA_STATUS); +} +EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear); + /** * ata_bmdma_setup - Set up PCI IDE BMDMA transaction * @qc: Info associated with this ATA transaction. diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index 6422cfd13d0d..9cae65de750e 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c @@ -1214,7 +1214,7 @@ static unsigned int bfin_data_xfer(struct ata_device *dev, unsigned char *buf, * bfin_irq_clear - Clear ATAPI interrupt. * @ap: Port associated with this ATA transaction. * - * Note: Original code is ata_sff_irq_clear(). + * Note: Original code is ata_bmdma_irq_clear(). */ static void bfin_irq_clear(struct ata_port *ap) diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index 6f6193b707cb..fb318cdaffb7 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -875,7 +875,7 @@ static void scc_postreset(struct ata_link *link, unsigned int *classes) * scc_irq_clear - Clear PCI IDE BMDMA interrupt. * @ap: Port associated with this ATA transaction. * - * Note: Original code is ata_sff_irq_clear(). + * Note: Original code is ata_bmdma_irq_clear(). */ static void scc_irq_clear (struct ata_port *ap) diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index baa8f0d2c86f..358dde0178d4 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -1100,7 +1100,7 @@ static void nv_adma_irq_clear(struct ata_port *ap) u32 notifier_clears[2]; if (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) { - ata_sff_irq_clear(ap); + ata_bmdma_irq_clear(ap); return; } diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index 2dda312b6b9a..3a4f84219719 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c @@ -503,7 +503,7 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2) goto err_hsm; /* ack bmdma irq events */ - ata_sff_irq_clear(ap); + ata_bmdma_irq_clear(ap); /* kick HSM in the ass */ ata_sff_hsm_move(ap, qc, status, 0); @@ -584,7 +584,7 @@ static void sil_thaw(struct ata_port *ap) /* clear IRQ */ ap->ops->sff_check_status(ap); - ata_sff_irq_clear(ap); + ata_bmdma_irq_clear(ap); /* turn on SATA IRQ if supported */ if (!(ap->flags & SIL_FLAG_NO_SATA_IRQ)) diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 08f65492cc81..7737dd5a434e 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -308,7 +308,7 @@ static void svia_noop_freeze(struct ata_port *ap) * certain way. Leave it alone and just clear pending IRQ. */ ap->ops->sff_check_status(ap); - ata_sff_irq_clear(ap); + ata_bmdma_irq_clear(ap); } /** diff --git a/include/linux/libata.h b/include/linux/libata.h index ee84e7e12039..8fd1ca8c7ef3 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1630,6 +1630,7 @@ extern unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc); extern void ata_bmdma_dumb_qc_prep(struct ata_queued_cmd *qc); extern void ata_bmdma_error_handler(struct ata_port *ap); extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc); +extern void ata_bmdma_irq_clear(struct ata_port *ap); 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_queued_cmd *qc); -- cgit v1.2.3 From c3b2889424c26f3b42962b6f39aabb4f1fd1b576 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 19 May 2010 22:10:21 +0200 Subject: libata-sff: separate out BMDMA irq handler Separate out BMDMA irq handler from SFF irq handler. The misnamed host_intr() functions are renamed to ata_sff_port_intr() and ata_bmdma_port_intr(). Common parts are factored into __ata_sff_port_intr() and __ata_sff_interrupt() and used by sff and bmdma interrupt routines. All BMDMA drivers now use ata_bmdma_interrupt() or ata_bmdma_port_intr() while all non-BMDMA SFF ones use ata_sff_interrupt() or ata_sff_port_intr(). For now, ata_pci_sff_init_one() uses ata_bmdma_interrupt() as it's used by both SFF and BMDMA drivers. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 2 +- drivers/ata/libata-sff.c | 208 +++++++++++++++++++++++++++----------------- drivers/ata/pata_atp867x.c | 2 +- drivers/ata/pata_cs5520.c | 2 +- drivers/ata/pata_hpt3x3.c | 2 +- drivers/ata/pata_icside.c | 2 +- drivers/ata/pata_macio.c | 2 +- drivers/ata/pata_mpc52xx.c | 2 +- drivers/ata/pata_ninja32.c | 2 +- drivers/ata/pata_pdc2027x.c | 2 +- drivers/ata/pata_rdc.c | 2 +- drivers/ata/pata_scc.c | 2 +- drivers/ata/pata_sil680.c | 2 +- drivers/ata/sata_mv.c | 2 +- drivers/ata/sata_nv.c | 4 +- drivers/ata/sata_qstor.c | 2 +- drivers/ata/sata_sis.c | 2 +- drivers/ata/sata_svw.c | 2 +- drivers/ata/sata_uli.c | 2 +- drivers/ata/sata_via.c | 2 +- drivers/ata/sata_vsc.c | 2 +- include/linux/libata.h | 5 +- 22 files changed, 155 insertions(+), 100 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index ec52fc618763..73685df98db9 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -1626,7 +1626,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev, host->flags |= ATA_HOST_PARALLEL_SCAN; pci_set_master(pdev); - return ata_pci_sff_activate_host(host, ata_sff_interrupt, &piix_sht); + return ata_pci_sff_activate_host(host, ata_bmdma_interrupt, &piix_sht); } static void piix_remove_one(struct pci_dev *pdev) diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 55bc4880cbf3..bef7571a1d42 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -1469,27 +1469,27 @@ bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc) } EXPORT_SYMBOL_GPL(ata_sff_qc_fill_rtf); -/** - * ata_sff_host_intr - Handle host interrupt for given (port, task) - * @ap: Port on which interrupt arrived (possibly...) - * @qc: Taskfile currently active in engine - * - * Handle host interrupt for given queued command. Currently, - * only DMA interrupts are handled. All other commands are - * handled via polling with interrupts disabled (nIEN bit). - * - * LOCKING: - * spin_lock_irqsave(host lock) - * - * RETURNS: - * One if interrupt was handled, zero if not (shared irq). - */ -unsigned int ata_sff_host_intr(struct ata_port *ap, - struct ata_queued_cmd *qc) +static unsigned int ata_sff_idle_irq(struct ata_port *ap) { - struct ata_eh_info *ehi = &ap->link.eh_info; - u8 status, host_stat = 0; - bool bmdma_stopped = false; + ap->stats.idle_irq++; + +#ifdef ATA_IRQ_TRAP + if ((ap->stats.idle_irq % 1000) == 0) { + ap->ops->sff_check_status(ap); + if (ap->ops->sff_irq_clear) + ap->ops->sff_irq_clear(ap); + ata_port_printk(ap, KERN_WARNING, "irq trap\n"); + return 1; + } +#endif + return 0; /* irq not handled */ +} + +static unsigned int __ata_sff_port_intr(struct ata_port *ap, + struct ata_queued_cmd *qc, + bool hsmv_on_idle) +{ + u8 status; VPRINTK("ata%u: protocol %d task_state %d\n", ap->print_id, qc->tf.protocol, ap->hsm_task_state); @@ -1506,47 +1506,24 @@ unsigned int ata_sff_host_intr(struct ata_port *ap, * need to check ata_is_atapi(qc->tf.protocol) again. */ if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) - goto idle_irq; - break; - case HSM_ST_LAST: - if (qc->tf.protocol == ATA_PROT_DMA || - qc->tf.protocol == ATAPI_PROT_DMA) { - /* check status of DMA engine */ - host_stat = ap->ops->bmdma_status(ap); - VPRINTK("ata%u: host_stat 0x%X\n", - ap->print_id, host_stat); - - /* if it's not our irq... */ - if (!(host_stat & ATA_DMA_INTR)) - goto idle_irq; - - /* before we do anything else, clear DMA-Start bit */ - ap->ops->bmdma_stop(qc); - bmdma_stopped = true; - - if (unlikely(host_stat & ATA_DMA_ERR)) { - /* error when transfering data to/from memory */ - qc->err_mask |= AC_ERR_HOST_BUS; - ap->hsm_task_state = HSM_ST_ERR; - } - } + return ata_sff_idle_irq(ap); break; case HSM_ST: + case HSM_ST_LAST: break; default: - goto idle_irq; + return ata_sff_idle_irq(ap); } - /* check main status, clearing INTRQ if needed */ status = ata_sff_irq_status(ap); if (status & ATA_BUSY) { - if (bmdma_stopped) { + if (hsmv_on_idle) { /* BMDMA engine is already stopped, we're screwed */ qc->err_mask |= AC_ERR_HSM; ap->hsm_task_state = HSM_ST_ERR; } else - goto idle_irq; + return ata_sff_idle_irq(ap); } /* clear irq events */ @@ -1555,43 +1532,30 @@ unsigned int ata_sff_host_intr(struct ata_port *ap, ata_sff_hsm_move(ap, qc, status, 0); - if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA || - qc->tf.protocol == ATAPI_PROT_DMA)) - ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat); - return 1; /* irq handled */ - -idle_irq: - ap->stats.idle_irq++; - -#ifdef ATA_IRQ_TRAP - if ((ap->stats.idle_irq % 1000) == 0) { - ap->ops->sff_check_status(ap); - if (ap->ops->sff_irq_clear) - ap->ops->sff_irq_clear(ap); - ata_port_printk(ap, KERN_WARNING, "irq trap\n"); - return 1; - } -#endif - return 0; /* irq not handled */ } -EXPORT_SYMBOL_GPL(ata_sff_host_intr); /** - * ata_sff_interrupt - Default ATA host interrupt handler - * @irq: irq line (unused) - * @dev_instance: pointer to our ata_host information structure + * ata_sff_port_intr - Handle SFF port interrupt + * @ap: Port on which interrupt arrived (possibly...) + * @qc: Taskfile currently active in engine * - * Default interrupt handler for PCI IDE devices. Calls - * ata_sff_host_intr() for each port that is not disabled. + * Handle port interrupt for given queued command. * * LOCKING: - * Obtains host lock during operation. + * spin_lock_irqsave(host lock) * * RETURNS: - * IRQ_NONE or IRQ_HANDLED. + * One if interrupt was handled, zero if not (shared irq). */ -irqreturn_t ata_sff_interrupt(int irq, void *dev_instance) +unsigned int ata_sff_port_intr(struct ata_port *ap, struct ata_queued_cmd *qc) +{ + return __ata_sff_port_intr(ap, qc, false); +} +EXPORT_SYMBOL_GPL(ata_sff_port_intr); + +static inline irqreturn_t __ata_sff_interrupt(int irq, void *dev_instance, + unsigned int (*port_intr)(struct ata_port *, struct ata_queued_cmd *)) { struct ata_host *host = dev_instance; bool retried = false; @@ -1611,7 +1575,7 @@ retry: qc = ata_qc_from_tag(ap, ap->link.active_tag); if (qc) { if (!(qc->tf.flags & ATA_TFLAG_POLLING)) - handled |= ata_sff_host_intr(ap, qc); + handled |= port_intr(ap, qc); else polling |= 1 << i; } else @@ -1661,6 +1625,25 @@ retry: return IRQ_RETVAL(handled); } + +/** + * ata_sff_interrupt - Default SFF ATA host interrupt handler + * @irq: irq line (unused) + * @dev_instance: pointer to our ata_host information structure + * + * Default interrupt handler for PCI IDE devices. Calls + * ata_sff_port_intr() for each port that is not disabled. + * + * LOCKING: + * Obtains host lock during operation. + * + * RETURNS: + * IRQ_NONE or IRQ_HANDLED. + */ +irqreturn_t ata_sff_interrupt(int irq, void *dev_instance) +{ + return __ata_sff_interrupt(irq, dev_instance, ata_sff_port_intr); +} EXPORT_SYMBOL_GPL(ata_sff_interrupt); /** @@ -1698,7 +1681,7 @@ void ata_sff_lost_interrupt(struct ata_port *ap) status); /* Run the host interrupt logic as if the interrupt had not been lost */ - ata_sff_host_intr(ap, qc); + ata_sff_port_intr(ap, qc); } EXPORT_SYMBOL_GPL(ata_sff_lost_interrupt); @@ -2541,7 +2524,7 @@ int ata_pci_sff_init_one(struct pci_dev *pdev, host->flags |= hflag; pci_set_master(pdev); - rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht); + rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht); out: if (rc == 0) devres_remove_group(&pdev->dev, NULL); @@ -2787,6 +2770,75 @@ unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc) } EXPORT_SYMBOL_GPL(ata_bmdma_qc_issue); +/** + * ata_bmdma_port_intr - Handle BMDMA port interrupt + * @ap: Port on which interrupt arrived (possibly...) + * @qc: Taskfile currently active in engine + * + * Handle port interrupt for given queued command. + * + * LOCKING: + * spin_lock_irqsave(host lock) + * + * RETURNS: + * One if interrupt was handled, zero if not (shared irq). + */ +unsigned int ata_bmdma_port_intr(struct ata_port *ap, struct ata_queued_cmd *qc) +{ + struct ata_eh_info *ehi = &ap->link.eh_info; + u8 host_stat = 0; + bool bmdma_stopped = false; + unsigned int handled; + + if (ap->hsm_task_state == HSM_ST_LAST && ata_is_dma(qc->tf.protocol)) { + /* check status of DMA engine */ + host_stat = ap->ops->bmdma_status(ap); + VPRINTK("ata%u: host_stat 0x%X\n", ap->print_id, host_stat); + + /* if it's not our irq... */ + if (!(host_stat & ATA_DMA_INTR)) + return ata_sff_idle_irq(ap); + + /* before we do anything else, clear DMA-Start bit */ + ap->ops->bmdma_stop(qc); + bmdma_stopped = true; + + if (unlikely(host_stat & ATA_DMA_ERR)) { + /* error when transfering data to/from memory */ + qc->err_mask |= AC_ERR_HOST_BUS; + ap->hsm_task_state = HSM_ST_ERR; + } + } + + handled = __ata_sff_port_intr(ap, qc, bmdma_stopped); + + if (unlikely(qc->err_mask) && ata_is_dma(qc->tf.protocol)) + ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat); + + return handled; +} +EXPORT_SYMBOL_GPL(ata_bmdma_port_intr); + +/** + * ata_bmdma_interrupt - Default BMDMA ATA host interrupt handler + * @irq: irq line (unused) + * @dev_instance: pointer to our ata_host information structure + * + * Default interrupt handler for PCI IDE devices. Calls + * ata_bmdma_port_intr() for each port that is not disabled. + * + * LOCKING: + * Obtains host lock during operation. + * + * RETURNS: + * IRQ_NONE or IRQ_HANDLED. + */ +irqreturn_t ata_bmdma_interrupt(int irq, void *dev_instance) +{ + return __ata_sff_interrupt(irq, dev_instance, ata_bmdma_port_intr); +} +EXPORT_SYMBOL_GPL(ata_bmdma_interrupt); + /** * ata_bmdma_error_handler - Stock error handler for BMDMA controller * @ap: port to handle error for diff --git a/drivers/ata/pata_atp867x.c b/drivers/ata/pata_atp867x.c index bb6e0746e07d..95295935dd95 100644 --- a/drivers/ata/pata_atp867x.c +++ b/drivers/ata/pata_atp867x.c @@ -525,7 +525,7 @@ static int atp867x_init_one(struct pci_dev *pdev, pci_set_master(pdev); - rc = ata_host_activate(host, pdev->irq, ata_sff_interrupt, + rc = ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, IRQF_SHARED, &atp867x_sht); if (rc) dev_printk(KERN_ERR, &pdev->dev, "failed to activate host\n"); diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index 17c5f346ff01..030952f1f97c 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c @@ -221,7 +221,7 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi continue; rc = devm_request_irq(&pdev->dev, irq[ap->port_no], - ata_sff_interrupt, 0, DRV_NAME, host); + ata_bmdma_interrupt, 0, DRV_NAME, host); if (rc) return rc; diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c index 727a81ce4c9f..b63d5e2d4628 100644 --- a/drivers/ata/pata_hpt3x3.c +++ b/drivers/ata/pata_hpt3x3.c @@ -248,7 +248,7 @@ static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ata_port_pbar_desc(ap, 4, offset_cmd[i], "cmd"); } pci_set_master(pdev); - return ata_host_activate(host, pdev->irq, ata_sff_interrupt, + return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, IRQF_SHARED, &hpt3x3_sht); } diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c index b56e8f722d20..9f2889fe43b2 100644 --- a/drivers/ata/pata_icside.c +++ b/drivers/ata/pata_icside.c @@ -470,7 +470,7 @@ static int __devinit pata_icside_add_ports(struct pata_icside_info *info) pata_icside_setup_ioaddr(ap, info->base, info, info->port[i]); } - return ata_host_activate(host, ec->irq, ata_sff_interrupt, 0, + return ata_host_activate(host, ec->irq, ata_bmdma_interrupt, 0, &pata_icside_sht); } diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c index b5b48e703cb7..76640ac76888 100644 --- a/drivers/ata/pata_macio.c +++ b/drivers/ata/pata_macio.c @@ -1110,7 +1110,7 @@ static int __devinit pata_macio_common_init(struct pata_macio_priv *priv, /* Start it up */ priv->irq = irq; - return ata_host_activate(priv->host, irq, ata_sff_interrupt, 0, + return ata_host_activate(priv->host, irq, ata_bmdma_interrupt, 0, &pata_macio_sht); } diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index 36afe2c1c747..f087ab55b1df 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -659,7 +659,7 @@ mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv, ata_port_desc(ap, "ata_regs 0x%lx", raw_ata_regs); /* activate host */ - return ata_host_activate(host, priv->ata_irq, ata_sff_interrupt, 0, + return ata_host_activate(host, priv->ata_irq, ata_bmdma_interrupt, 0, &mpc52xx_ata_sht); } diff --git a/drivers/ata/pata_ninja32.c b/drivers/ata/pata_ninja32.c index dd53a66b19e3..cc50bd09aa26 100644 --- a/drivers/ata/pata_ninja32.c +++ b/drivers/ata/pata_ninja32.c @@ -149,7 +149,7 @@ static int ninja32_init_one(struct pci_dev *dev, const struct pci_device_id *id) ninja32_program(base); /* FIXME: Should we disable them at remove ? */ - return ata_host_activate(host, dev->irq, ata_sff_interrupt, + return ata_host_activate(host, dev->irq, ata_bmdma_interrupt, IRQF_SHARED, &ninja32_sht); } diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index 09f1f22c0307..b18351122525 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c @@ -754,7 +754,7 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de return -EIO; pci_set_master(pdev); - return ata_host_activate(host, pdev->irq, ata_sff_interrupt, + return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, IRQF_SHARED, &pdc2027x_sht); } diff --git a/drivers/ata/pata_rdc.c b/drivers/ata/pata_rdc.c index 37092cfd7bc6..2dd7748c9040 100644 --- a/drivers/ata/pata_rdc.c +++ b/drivers/ata/pata_rdc.c @@ -354,7 +354,7 @@ static int __devinit rdc_init_one(struct pci_dev *pdev, host->flags |= ATA_HOST_PARALLEL_SCAN; pci_set_master(pdev); - return ata_pci_sff_activate_host(host, ata_sff_interrupt, &rdc_sht); + return ata_pci_sff_activate_host(host, ata_bmdma_interrupt, &rdc_sht); } static void rdc_remove_one(struct pci_dev *pdev) diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index fb318cdaffb7..d9db3f8d60ef 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -1105,7 +1105,7 @@ static int scc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) return rc; - return ata_host_activate(host, pdev->irq, ata_sff_interrupt, + return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, IRQF_SHARED, &scc_sht); } diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index 43faf106f647..ac5593786540 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c @@ -374,7 +374,7 @@ static int __devinit sil680_init_one(struct pci_dev *pdev, ata_sff_std_ports(&host->ports[1]->ioaddr); /* Register & activate */ - return ata_host_activate(host, pdev->irq, ata_sff_interrupt, + return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, IRQF_SHARED, &sil680_sht); use_ioports: diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 16bacd389265..a476cd99b95d 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -2811,7 +2811,7 @@ static void mv_port_intr(struct ata_port *ap, u32 port_cause) } else if (!edma_was_enabled) { struct ata_queued_cmd *qc = mv_get_active_qc(ap); if (qc) - ata_sff_host_intr(ap, qc); + ata_bmdma_port_intr(ap, qc); else mv_unexpected_intr(ap, edma_was_enabled); } diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 358dde0178d4..4269b9915e43 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -920,7 +920,7 @@ static int nv_host_intr(struct ata_port *ap, u8 irq_stat) } /* handle interrupt */ - return ata_sff_host_intr(ap, qc); + return ata_bmdma_port_intr(ap, qc); } static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) @@ -1505,7 +1505,7 @@ static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance) qc = ata_qc_from_tag(ap, ap->link.active_tag); if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) { - handled += ata_sff_host_intr(ap, qc); + handled += ata_bmdma_port_intr(ap, qc); } else { /* * No request pending? Clear interrupt status diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index d533b3d20ca1..0074351d7edf 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c @@ -454,7 +454,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host *host) if (!pp || pp->state != qs_state_mmio) continue; if (!(qc->tf.flags & ATA_TFLAG_POLLING)) - handled |= ata_sff_host_intr(ap, qc); + handled |= ata_sff_port_intr(ap, qc); } return handled; } diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index f8a91bfd66a8..fff10458a1aa 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c @@ -308,7 +308,7 @@ static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_master(pdev); pci_intx(pdev, 1); - return ata_host_activate(host, pdev->irq, ata_sff_interrupt, + return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, IRQF_SHARED, &sis_sht); } diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 101fd6a19829..7d9db4aaf07e 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c @@ -502,7 +502,7 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en writel(0x0, mmio_base + K2_SATA_SIM_OFFSET); pci_set_master(pdev); - return ata_host_activate(host, pdev->irq, ata_sff_interrupt, + return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, IRQF_SHARED, &k2_sata_sht); } diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c index d8dac17dc2c8..b8578c32d344 100644 --- a/drivers/ata/sata_uli.c +++ b/drivers/ata/sata_uli.c @@ -242,7 +242,7 @@ static int uli_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_master(pdev); pci_intx(pdev, 1); - return ata_host_activate(host, pdev->irq, ata_sff_interrupt, + return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, IRQF_SHARED, &uli_sht); } diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 7737dd5a434e..7da5d019873b 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -628,7 +628,7 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) svia_configure(pdev); pci_set_master(pdev); - return ata_host_activate(host, pdev->irq, ata_sff_interrupt, + return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, IRQF_SHARED, &svia_sht); } diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c index 2107952ebff1..b777176ff494 100644 --- a/drivers/ata/sata_vsc.c +++ b/drivers/ata/sata_vsc.c @@ -245,7 +245,7 @@ static void vsc_port_intr(u8 port_status, struct ata_port *ap) qc = ata_qc_from_tag(ap, ap->link.active_tag); if (qc && likely(!(qc->tf.flags & ATA_TFLAG_POLLING))) - handled = ata_sff_host_intr(ap, qc); + handled = ata_bmdma_port_intr(ap, qc); /* We received an interrupt during a polled command, * or some other spurious condition. Interrupt reporting diff --git a/include/linux/libata.h b/include/linux/libata.h index 8fd1ca8c7ef3..b76d767e0240 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1593,7 +1593,7 @@ extern int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, extern void ata_sff_queue_pio_task(struct ata_port *ap, unsigned long delay); extern unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc); extern bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc); -extern unsigned int ata_sff_host_intr(struct ata_port *ap, +extern unsigned int ata_sff_port_intr(struct ata_port *ap, struct ata_queued_cmd *qc); extern irqreturn_t ata_sff_interrupt(int irq, void *dev_instance); extern void ata_sff_lost_interrupt(struct ata_port *ap); @@ -1628,6 +1628,9 @@ extern int ata_pci_sff_init_one(struct pci_dev *pdev, extern void ata_bmdma_qc_prep(struct ata_queued_cmd *qc); extern unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc); extern void ata_bmdma_dumb_qc_prep(struct ata_queued_cmd *qc); +extern unsigned int ata_bmdma_port_intr(struct ata_port *ap, + struct ata_queued_cmd *qc); +extern irqreturn_t ata_bmdma_interrupt(int irq, void *dev_instance); extern void ata_bmdma_error_handler(struct ata_port *ap); extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc); extern void ata_bmdma_irq_clear(struct ata_port *ap); -- cgit v1.2.3 From 1c5afdf7a629d2e77de8dd043b97a33dcd7e6dfa Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 19 May 2010 22:10:22 +0200 Subject: libata-sff: separate out BMDMA init Separate out ata_pci_bmdma_prepare_host() and ata_pci_bmdma_init_one() from their SFF counterparts. SFF ones no longer try to initialize BMDMA or set PCI master. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/ata_generic.c | 2 +- drivers/ata/ata_piix.c | 2 +- drivers/ata/libata-sff.c | 138 +++++++++++++++++++++++++++++++++------- drivers/ata/pata_acpi.c | 2 +- drivers/ata/pata_ali.c | 5 +- drivers/ata/pata_amd.c | 2 +- drivers/ata/pata_artop.c | 2 +- drivers/ata/pata_atiixp.c | 4 +- drivers/ata/pata_cmd64x.c | 2 +- drivers/ata/pata_cs5530.c | 2 +- drivers/ata/pata_cs5535.c | 2 +- drivers/ata/pata_cs5536.c | 2 +- drivers/ata/pata_cypress.c | 2 +- drivers/ata/pata_efar.c | 4 +- drivers/ata/pata_hpt366.c | 2 +- drivers/ata/pata_hpt37x.c | 2 +- drivers/ata/pata_hpt3x2n.c | 2 +- drivers/ata/pata_it8213.c | 2 +- drivers/ata/pata_it821x.c | 2 +- drivers/ata/pata_jmicron.c | 2 +- drivers/ata/pata_marvell.c | 2 +- drivers/ata/pata_netcell.c | 2 +- drivers/ata/pata_ns87415.c | 2 +- drivers/ata/pata_oldpiix.c | 2 +- drivers/ata/pata_optidma.c | 2 +- drivers/ata/pata_pdc202xx_old.c | 2 +- drivers/ata/pata_piccolo.c | 2 +- drivers/ata/pata_radisys.c | 2 +- drivers/ata/pata_rdc.c | 2 +- drivers/ata/pata_sc1200.c | 2 +- drivers/ata/pata_sch.c | 2 +- drivers/ata/pata_serverworks.c | 2 +- drivers/ata/pata_sil680.c | 2 +- drivers/ata/pata_sis.c | 2 +- drivers/ata/pata_sl82c105.c | 2 +- drivers/ata/pata_triflex.c | 2 +- drivers/ata/pata_via.c | 2 +- drivers/ata/sata_nv.c | 2 +- drivers/ata/sata_sis.c | 2 +- drivers/ata/sata_via.c | 4 +- include/linux/libata.h | 7 ++ 41 files changed, 166 insertions(+), 66 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index 33fb614f9784..573158a9668d 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c @@ -155,7 +155,7 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id return rc; pcim_pin_device(dev); } - return ata_pci_sff_init_one(dev, ppi, &generic_sht, NULL, 0); + return ata_pci_bmdma_init_one(dev, ppi, &generic_sht, NULL, 0); } static struct pci_device_id ata_generic[] = { diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 73685df98db9..7409f98d2ae6 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -1589,7 +1589,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev, hpriv->map = piix_init_sata_map(pdev, port_info, piix_map_db_table[ent->driver_data]); - rc = ata_pci_sff_prepare_host(pdev, ppi, &host); + rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); if (rc) return rc; host->private_data = hpriv; diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index bef7571a1d42..c29f1468e164 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -2315,13 +2315,13 @@ int ata_pci_sff_init_host(struct ata_host *host) EXPORT_SYMBOL_GPL(ata_pci_sff_init_host); /** - * ata_pci_sff_prepare_host - helper to prepare native PCI ATA host + * ata_pci_sff_prepare_host - helper to prepare PCI PIO-only SFF ATA host * @pdev: target PCI device * @ppi: array of port_info, must be enough for two ports * @r_host: out argument for the initialized ATA host * - * Helper to allocate ATA host for @pdev, acquire all native PCI - * resources and initialize it accordingly in one go. + * Helper to allocate PIO-only SFF ATA host for @pdev, acquire + * all PCI resources and initialize it accordingly in one go. * * LOCKING: * Inherited from calling layer (may sleep). @@ -2351,9 +2351,6 @@ int ata_pci_sff_prepare_host(struct pci_dev *pdev, if (rc) goto err_out; - /* init DMA related stuff */ - ata_pci_bmdma_init(host); - devres_remove_group(&pdev->dev, NULL); *r_host = host; return 0; @@ -2458,8 +2455,21 @@ out: } EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host); +static const struct ata_port_info *ata_sff_find_valid_pi( + const struct ata_port_info * const *ppi) +{ + int i; + + /* look up the first valid port_info */ + for (i = 0; i < 2 && ppi[i]; i++) + if (ppi[i]->port_ops != &ata_dummy_port_ops) + return ppi[i]; + + return NULL; +} + /** - * ata_pci_sff_init_one - Initialize/register PCI IDE host controller + * ata_pci_sff_init_one - Initialize/register PIO-only PCI IDE controller * @pdev: Controller to be initialized * @ppi: array of port_info, must be enough for two ports * @sht: scsi_host_template to use when registering the host @@ -2468,11 +2478,7 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host); * * This is a helper function which can be called from a driver's * xxx_init_one() probe function if the hardware uses traditional - * IDE taskfile registers. - * - * This function calls pci_enable_device(), reserves its register - * regions, sets the dma mask, enables bus master mode, and calls - * ata_device_add() + * IDE taskfile registers and is PIO only. * * ASSUMPTION: * Nobody makes a single channel controller that appears solely as @@ -2489,20 +2495,13 @@ int ata_pci_sff_init_one(struct pci_dev *pdev, struct scsi_host_template *sht, void *host_priv, int hflag) { struct device *dev = &pdev->dev; - const struct ata_port_info *pi = NULL; + const struct ata_port_info *pi; struct ata_host *host = NULL; - int i, rc; + int rc; DPRINTK("ENTER\n"); - /* look up the first valid port_info */ - for (i = 0; i < 2 && ppi[i]; i++) { - if (ppi[i]->port_ops != &ata_dummy_port_ops) { - pi = ppi[i]; - break; - } - } - + pi = ata_sff_find_valid_pi(ppi); if (!pi) { dev_printk(KERN_ERR, &pdev->dev, "no valid port_info specified\n"); @@ -2523,8 +2522,7 @@ int ata_pci_sff_init_one(struct pci_dev *pdev, host->private_data = host_priv; host->flags |= hflag; - pci_set_master(pdev); - rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht); + rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht); out: if (rc == 0) devres_remove_group(&pdev->dev, NULL); @@ -3196,6 +3194,98 @@ void ata_pci_bmdma_init(struct ata_host *host) } EXPORT_SYMBOL_GPL(ata_pci_bmdma_init); +/** + * ata_pci_bmdma_prepare_host - helper to prepare PCI BMDMA ATA host + * @pdev: target PCI device + * @ppi: array of port_info, must be enough for two ports + * @r_host: out argument for the initialized ATA host + * + * Helper to allocate BMDMA ATA host for @pdev, acquire all PCI + * resources and initialize it accordingly in one go. + * + * LOCKING: + * Inherited from calling layer (may sleep). + * + * RETURNS: + * 0 on success, -errno otherwise. + */ +int ata_pci_bmdma_prepare_host(struct pci_dev *pdev, + const struct ata_port_info * const * ppi, + struct ata_host **r_host) +{ + int rc; + + rc = ata_pci_sff_prepare_host(pdev, ppi, r_host); + if (rc) + return rc; + + ata_pci_bmdma_init(*r_host); + return 0; +} +EXPORT_SYMBOL_GPL(ata_pci_bmdma_prepare_host); + +/** + * ata_pci_bmdma_init_one - Initialize/register BMDMA PCI IDE controller + * @pdev: Controller to be initialized + * @ppi: array of port_info, must be enough for two ports + * @sht: scsi_host_template to use when registering the host + * @host_priv: host private_data + * @hflags: host flags + * + * This function is similar to ata_pci_sff_init_one() but also + * takes care of BMDMA initialization. + * + * LOCKING: + * Inherited from PCI layer (may sleep). + * + * RETURNS: + * Zero on success, negative on errno-based value on error. + */ +int ata_pci_bmdma_init_one(struct pci_dev *pdev, + const struct ata_port_info * const * ppi, + struct scsi_host_template *sht, void *host_priv, + int hflags) +{ + struct device *dev = &pdev->dev; + const struct ata_port_info *pi; + struct ata_host *host = NULL; + int rc; + + DPRINTK("ENTER\n"); + + pi = ata_sff_find_valid_pi(ppi); + if (!pi) { + dev_printk(KERN_ERR, &pdev->dev, + "no valid port_info specified\n"); + return -EINVAL; + } + + if (!devres_open_group(dev, NULL, GFP_KERNEL)) + return -ENOMEM; + + rc = pcim_enable_device(pdev); + if (rc) + goto out; + + /* prepare and activate BMDMA host */ + rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); + if (rc) + goto out; + host->private_data = host_priv; + host->flags |= hflags; + + pci_set_master(pdev); + rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht); + out: + if (rc == 0) + devres_remove_group(&pdev->dev, NULL); + else + devres_release_group(&pdev->dev, NULL); + + return rc; +} +EXPORT_SYMBOL_GPL(ata_pci_bmdma_init_one); + #endif /* CONFIG_PCI */ /** diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c index 066b9f301ed5..c8d47034d5e9 100644 --- a/drivers/ata/pata_acpi.c +++ b/drivers/ata/pata_acpi.c @@ -260,7 +260,7 @@ static int pacpi_init_one (struct pci_dev *pdev, const struct pci_device_id *id) return rc; pcim_pin_device(pdev); } - return ata_pci_sff_init_one(pdev, ppi, &pacpi_sht, NULL, 0); + return ata_pci_bmdma_init_one(pdev, ppi, &pacpi_sht, NULL, 0); } static const struct pci_device_id pacpi_pci_tbl[] = { diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index f306e10c748d..794ec6e3275d 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c @@ -583,7 +583,10 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ppi[0] = &info_20_udma; } - return ata_pci_sff_init_one(pdev, ppi, &ali_sht, NULL, 0); + if (!ppi[0]->mwdma_mask && !ppi[0]->udma_mask) + return ata_pci_sff_init_one(pdev, ppi, &ali_sht, NULL, 0); + else + return ata_pci_bmdma_init_one(pdev, ppi, &ali_sht, NULL, 0); } #ifdef CONFIG_PM diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index d95eca9c547e..620a07cabe31 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c @@ -574,7 +574,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) } /* And fire it up */ - return ata_pci_sff_init_one(pdev, ppi, &amd_sht, hpriv, 0); + return ata_pci_bmdma_init_one(pdev, ppi, &amd_sht, hpriv, 0); } #ifdef CONFIG_PM diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c index 4d066d6c30fa..ba43f0f8c880 100644 --- a/drivers/ata/pata_artop.c +++ b/drivers/ata/pata_artop.c @@ -421,7 +421,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) BUG_ON(ppi[0] == NULL); - return ata_pci_sff_init_one(pdev, ppi, &artop_sht, NULL, 0); + return ata_pci_bmdma_init_one(pdev, ppi, &artop_sht, NULL, 0); } static const struct pci_device_id artop_pci_tbl[] = { diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index 44d88b380ddd..43755616dc5a 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c @@ -246,8 +246,8 @@ static int atiixp_init_one(struct pci_dev *pdev, const struct pci_device_id *id) if (!pci_test_config_bits(pdev, &atiixp_enable_bits[i])) ppi[i] = &ata_dummy_port_info; - return ata_pci_sff_init_one(pdev, ppi, &atiixp_sht, NULL, - ATA_HOST_PARALLEL_SCAN); + return ata_pci_bmdma_init_one(pdev, ppi, &atiixp_sht, NULL, + ATA_HOST_PARALLEL_SCAN); } static const struct pci_device_id atiixp[] = { diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 4c81a71b8877..9f5da1c7454b 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c @@ -367,7 +367,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) pci_write_config_byte(pdev, UDIDETCR0, 0xF0); #endif - return ata_pci_sff_init_one(pdev, ppi, &cmd64x_sht, NULL, 0); + return ata_pci_bmdma_init_one(pdev, ppi, &cmd64x_sht, NULL, 0); } #ifdef CONFIG_PM diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c index e809a4233a81..f792330f0d8e 100644 --- a/drivers/ata/pata_cs5530.c +++ b/drivers/ata/pata_cs5530.c @@ -324,7 +324,7 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id) ppi[1] = &info_palmax_secondary; /* Now kick off ATA set up */ - return ata_pci_sff_init_one(pdev, ppi, &cs5530_sht, NULL, 0); + return ata_pci_bmdma_init_one(pdev, ppi, &cs5530_sht, NULL, 0); } #ifdef CONFIG_PM diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c index a02e6459fdcc..03a93186aa19 100644 --- a/drivers/ata/pata_cs5535.c +++ b/drivers/ata/pata_cs5535.c @@ -198,7 +198,7 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id) rdmsr(ATAC_CH0D1_PIO, timings, dummy); if (CS5535_BAD_PIO(timings)) wrmsr(ATAC_CH0D1_PIO, 0xF7F4F7F4UL, 0); - return ata_pci_sff_init_one(dev, ppi, &cs5535_sht, NULL, 0); + return ata_pci_bmdma_init_one(dev, ppi, &cs5535_sht, NULL, 0); } static const struct pci_device_id cs5535[] = { diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c index 914ae3506ff5..21ee23f89e88 100644 --- a/drivers/ata/pata_cs5536.c +++ b/drivers/ata/pata_cs5536.c @@ -260,7 +260,7 @@ static int cs5536_init_one(struct pci_dev *dev, const struct pci_device_id *id) return -ENODEV; } - return ata_pci_sff_init_one(dev, ppi, &cs5536_sht, NULL, 0); + return ata_pci_bmdma_init_one(dev, ppi, &cs5536_sht, NULL, 0); } static const struct pci_device_id cs5536[] = { diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c index 0fcc096b8dac..6d915b063d93 100644 --- a/drivers/ata/pata_cypress.c +++ b/drivers/ata/pata_cypress.c @@ -138,7 +138,7 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *i if (PCI_FUNC(pdev->devfn) != 1) return -ENODEV; - return ata_pci_sff_init_one(pdev, ppi, &cy82c693_sht, NULL, 0); + return ata_pci_bmdma_init_one(pdev, ppi, &cy82c693_sht, NULL, 0); } static const struct pci_device_id cy82c693[] = { diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c index 3bac0e079691..a08834758ea2 100644 --- a/drivers/ata/pata_efar.c +++ b/drivers/ata/pata_efar.c @@ -277,8 +277,8 @@ static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); - return ata_pci_sff_init_one(pdev, ppi, &efar_sht, NULL, - ATA_HOST_PARALLEL_SCAN); + return ata_pci_bmdma_init_one(pdev, ppi, &efar_sht, NULL, + ATA_HOST_PARALLEL_SCAN); } static const struct pci_device_id efar_pci_tbl[] = { diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index 8580eb3cd54d..7688868557b9 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c @@ -361,7 +361,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) break; } /* Now kick off ATA set up */ - return ata_pci_sff_init_one(dev, ppi, &hpt36x_sht, hpriv, 0); + return ata_pci_bmdma_init_one(dev, ppi, &hpt36x_sht, hpriv, 0); } #ifdef CONFIG_PM diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 98b498b6907c..9ae4c0830577 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -987,7 +987,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) } /* Now kick off ATA set up */ - return ata_pci_sff_init_one(dev, ppi, &hpt37x_sht, private_data, 0); + return ata_pci_bmdma_init_one(dev, ppi, &hpt37x_sht, private_data, 0); } static const struct pci_device_id hpt37x[] = { diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index 8b95aeba0e74..32f3463216b8 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -548,7 +548,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c); /* Now kick off ATA set up */ - return ata_pci_sff_init_one(dev, ppi, &hpt3x2n_sht, hpriv, 0); + return ata_pci_bmdma_init_one(dev, ppi, &hpt3x2n_sht, hpriv, 0); } static const struct pci_device_id hpt3x2n[] = { diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c index f971f0de88e6..4d142a2ab8fd 100644 --- a/drivers/ata/pata_it8213.c +++ b/drivers/ata/pata_it8213.c @@ -273,7 +273,7 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *en dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); - return ata_pci_sff_init_one(pdev, ppi, &it8213_sht, NULL, 0); + return ata_pci_bmdma_init_one(pdev, ppi, &it8213_sht, NULL, 0); } static const struct pci_device_id it8213_pci_tbl[] = { diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 2bd2b002d14a..bf88f71a21f4 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -933,7 +933,7 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) else ppi[0] = &info_smart; } - return ata_pci_sff_init_one(pdev, ppi, &it821x_sht, NULL, 0); + return ata_pci_bmdma_init_one(pdev, ppi, &it821x_sht, NULL, 0); } #ifdef CONFIG_PM diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c index 565e01e6ac7c..cb3babbb7035 100644 --- a/drivers/ata/pata_jmicron.c +++ b/drivers/ata/pata_jmicron.c @@ -144,7 +144,7 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i }; const struct ata_port_info *ppi[] = { &info, NULL }; - return ata_pci_sff_init_one(pdev, ppi, &jmicron_sht, NULL, 0); + return ata_pci_bmdma_init_one(pdev, ppi, &jmicron_sht, NULL, 0); } static const struct pci_device_id jmicron_pci_tbl[] = { diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c index e8ca02e5a71d..dd38083dcbeb 100644 --- a/drivers/ata/pata_marvell.c +++ b/drivers/ata/pata_marvell.c @@ -153,7 +153,7 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i return -ENODEV; } #endif - return ata_pci_sff_init_one(pdev, ppi, &marvell_sht, NULL, 0); + return ata_pci_bmdma_init_one(pdev, ppi, &marvell_sht, NULL, 0); } static const struct pci_device_id marvell_pci_tbl[] = { diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c index 94f979a7f4f7..3eb921c746a1 100644 --- a/drivers/ata/pata_netcell.c +++ b/drivers/ata/pata_netcell.c @@ -82,7 +82,7 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e ata_pci_bmdma_clear_simplex(pdev); /* And let the library code do the work */ - return ata_pci_sff_init_one(pdev, port_info, &netcell_sht, NULL, 0); + return ata_pci_bmdma_init_one(pdev, port_info, &netcell_sht, NULL, 0); } static const struct pci_device_id netcell_pci_tbl[] = { diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c index fdbba2d76d3e..605f198f958c 100644 --- a/drivers/ata/pata_ns87415.c +++ b/drivers/ata/pata_ns87415.c @@ -380,7 +380,7 @@ static int ns87415_init_one (struct pci_dev *pdev, const struct pci_device_id *e ns87415_fixup(pdev); - return ata_pci_sff_init_one(pdev, ppi, &ns87415_sht, NULL, 0); + return ata_pci_bmdma_init_one(pdev, ppi, &ns87415_sht, NULL, 0); } static const struct pci_device_id ns87415_pci_tbl[] = { diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c index 988ef2627be3..b811c1636204 100644 --- a/drivers/ata/pata_oldpiix.c +++ b/drivers/ata/pata_oldpiix.c @@ -248,7 +248,7 @@ static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *e dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); - return ata_pci_sff_init_one(pdev, ppi, &oldpiix_sht, NULL, 0); + return ata_pci_bmdma_init_one(pdev, ppi, &oldpiix_sht, NULL, 0); } static const struct pci_device_id oldpiix_pci_tbl[] = { diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c index 76b7d12b1e8d..0852cd07de08 100644 --- a/drivers/ata/pata_optidma.c +++ b/drivers/ata/pata_optidma.c @@ -429,7 +429,7 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id) if (optiplus_with_udma(dev)) ppi[0] = &info_82c700_udma; - return ata_pci_sff_init_one(dev, ppi, &optidma_sht, NULL, 0); + return ata_pci_bmdma_init_one(dev, ppi, &optidma_sht, NULL, 0); } static const struct pci_device_id optidma[] = { diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index fa1e2f3bc0fd..c39f213e1bbc 100644 --- a/drivers/ata/pata_pdc202xx_old.c +++ b/drivers/ata/pata_pdc202xx_old.c @@ -337,7 +337,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id return -ENODEV; } } - return ata_pci_sff_init_one(dev, ppi, &pdc202xx_sht, NULL, 0); + return ata_pci_bmdma_init_one(dev, ppi, &pdc202xx_sht, NULL, 0); } static const struct pci_device_id pdc202xx[] = { diff --git a/drivers/ata/pata_piccolo.c b/drivers/ata/pata_piccolo.c index 981615414849..cb01bf9496fe 100644 --- a/drivers/ata/pata_piccolo.c +++ b/drivers/ata/pata_piccolo.c @@ -95,7 +95,7 @@ static int ata_tosh_init_one(struct pci_dev *dev, const struct pci_device_id *id }; const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info }; /* Just one port for the moment */ - return ata_pci_sff_init_one(dev, ppi, &tosh_sht, NULL, 0); + return ata_pci_bmdma_init_one(dev, ppi, &tosh_sht, NULL, 0); } static struct pci_device_id ata_tosh[] = { diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c index a5fa388e5398..8574b31f1773 100644 --- a/drivers/ata/pata_radisys.c +++ b/drivers/ata/pata_radisys.c @@ -227,7 +227,7 @@ static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *e dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); - return ata_pci_sff_init_one(pdev, ppi, &radisys_sht, NULL, 0); + return ata_pci_bmdma_init_one(pdev, ppi, &radisys_sht, NULL, 0); } static const struct pci_device_id radisys_pci_tbl[] = { diff --git a/drivers/ata/pata_rdc.c b/drivers/ata/pata_rdc.c index 2dd7748c9040..5fbe9b166c69 100644 --- a/drivers/ata/pata_rdc.c +++ b/drivers/ata/pata_rdc.c @@ -344,7 +344,7 @@ static int __devinit rdc_init_one(struct pci_dev *pdev, */ pci_read_config_dword(pdev, 0x54, &hpriv->saved_iocfg); - rc = ata_pci_sff_prepare_host(pdev, ppi, &host); + rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); if (rc) return rc; host->private_data = hpriv; diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c index 6b5b63a2fd8e..e2c18257adff 100644 --- a/drivers/ata/pata_sc1200.c +++ b/drivers/ata/pata_sc1200.c @@ -237,7 +237,7 @@ static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id) }; const struct ata_port_info *ppi[] = { &info, NULL }; - return ata_pci_sff_init_one(dev, ppi, &sc1200_sht, NULL, 0); + return ata_pci_bmdma_init_one(dev, ppi, &sc1200_sht, NULL, 0); } static const struct pci_device_id sc1200[] = { diff --git a/drivers/ata/pata_sch.c b/drivers/ata/pata_sch.c index 86b3d0133c7c..e97b32f03a6e 100644 --- a/drivers/ata/pata_sch.c +++ b/drivers/ata/pata_sch.c @@ -179,7 +179,7 @@ static int __devinit sch_init_one(struct pci_dev *pdev, dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); - return ata_pci_sff_init_one(pdev, ppi, &sch_sht, NULL, 0); + return ata_pci_bmdma_init_one(pdev, ppi, &sch_sht, NULL, 0); } static int __init sch_init(void) diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c index 43ea389df2b3..86dd714e3e1d 100644 --- a/drivers/ata/pata_serverworks.c +++ b/drivers/ata/pata_serverworks.c @@ -460,7 +460,7 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) ata_pci_bmdma_clear_simplex(pdev); - return ata_pci_sff_init_one(pdev, ppi, &serverworks_sht, NULL, 0); + return ata_pci_bmdma_init_one(pdev, ppi, &serverworks_sht, NULL, 0); } #ifdef CONFIG_PM diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index ac5593786540..d3190d7ec304 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c @@ -378,7 +378,7 @@ static int __devinit sil680_init_one(struct pci_dev *pdev, IRQF_SHARED, &sil680_sht); use_ioports: - return ata_pci_sff_init_one(pdev, ppi, &sil680_sht, NULL, 0); + return ata_pci_bmdma_init_one(pdev, ppi, &sil680_sht, NULL, 0); } #ifdef CONFIG_PM diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index b6708032f321..60cea13cccce 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c @@ -826,7 +826,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) sis_fixup(pdev, chipset); - return ata_pci_sff_init_one(pdev, ppi, &sis_sht, chipset, 0); + return ata_pci_bmdma_init_one(pdev, ppi, &sis_sht, chipset, 0); } #ifdef CONFIG_PM diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c index 733b042a7469..98548f640c8e 100644 --- a/drivers/ata/pata_sl82c105.c +++ b/drivers/ata/pata_sl82c105.c @@ -316,7 +316,7 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; pci_write_config_dword(dev, 0x40, val); - return ata_pci_sff_init_one(dev, ppi, &sl82c105_sht, NULL, 0); + return ata_pci_bmdma_init_one(dev, ppi, &sl82c105_sht, NULL, 0); } static const struct pci_device_id sl82c105[] = { diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c index 48f50600ed2a..0d1f89e571dd 100644 --- a/drivers/ata/pata_triflex.c +++ b/drivers/ata/pata_triflex.c @@ -201,7 +201,7 @@ static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id) if (!printed_version++) dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n"); - return ata_pci_sff_init_one(dev, ppi, &triflex_sht, NULL, 0); + return ata_pci_bmdma_init_one(dev, ppi, &triflex_sht, NULL, 0); } static const struct pci_device_id triflex[] = { diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 7e3e0a5598b7..5e659885de16 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -627,7 +627,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) } /* We have established the device type, now fire it up */ - return ata_pci_sff_init_one(pdev, ppi, &via_sht, (void *)config, 0); + return ata_pci_bmdma_init_one(pdev, ppi, &via_sht, (void *)config, 0); } #ifdef CONFIG_PM diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 4269b9915e43..6fd114784116 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -2430,7 +2430,7 @@ static int nv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ppi[0] = &nv_port_info[type]; ipriv = ppi[0]->private_data; - rc = ata_pci_sff_prepare_host(pdev, ppi, &host); + rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); if (rc) return rc; diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index fff10458a1aa..2bfe3ae03976 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c @@ -279,7 +279,7 @@ static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) break; } - rc = ata_pci_sff_prepare_host(pdev, ppi, &host); + rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); if (rc) return rc; diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 7da5d019873b..101d8c219caf 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -463,7 +463,7 @@ static int vt6420_prepare_host(struct pci_dev *pdev, struct ata_host **r_host) struct ata_host *host; int rc; - rc = ata_pci_sff_prepare_host(pdev, ppi, &host); + rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); if (rc) return rc; *r_host = host; @@ -520,7 +520,7 @@ static int vt8251_prepare_host(struct pci_dev *pdev, struct ata_host **r_host) struct ata_host *host; int i, rc; - rc = ata_pci_sff_prepare_host(pdev, ppi, &host); + rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); if (rc) return rc; *r_host = host; diff --git a/include/linux/libata.h b/include/linux/libata.h index b76d767e0240..fe2be88bc266 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1644,6 +1644,13 @@ extern int ata_bmdma_port_start32(struct ata_port *ap); #ifdef CONFIG_PCI extern int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev); extern void ata_pci_bmdma_init(struct ata_host *host); +extern int ata_pci_bmdma_prepare_host(struct pci_dev *pdev, + const struct ata_port_info * const * ppi, + struct ata_host **r_host); +extern int ata_pci_bmdma_init_one(struct pci_dev *pdev, + const struct ata_port_info * const * ppi, + struct scsi_host_template *sht, + void *host_priv, int hflags); #endif /* CONFIG_PCI */ /** -- cgit v1.2.3 From d6b0de8c28ef32d081cfee938e443ce2a2429cfe Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 19 May 2010 22:10:23 +0200 Subject: libata-sff: kill dummy BMDMA ops from sata_qstor and pata_octeon_cf Now that SFF and BMDMA are completely separate, sata_qstor and pata_octeon_cf which inherit from ata_sff_port_ops don't need to worry about BMDMA ops being called. Kill the dummy BMDMA ops. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/pata_octeon_cf.c | 18 ------------------ drivers/ata/sata_qstor.c | 14 -------------- 2 files changed, 32 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index 3001109352ea..06ddd91ffeda 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -749,20 +749,6 @@ static void octeon_cf_dev_config(struct ata_device *dev) dev->max_sectors = min(dev->max_sectors, 4095U); } -/* - * Trap if driver tries to do standard bmdma commands. They are not - * supported. - */ -static void unreachable_qc(struct ata_queued_cmd *qc) -{ - BUG(); -} - -static u8 unreachable_port(struct ata_port *ap) -{ - BUG(); -} - /* * We don't do ATAPI DMA so return 0. */ @@ -804,10 +790,6 @@ static struct ata_port_operations octeon_cf_ops = { .sff_dev_select = octeon_cf_dev_select, .sff_irq_on = octeon_cf_irq_on, .sff_irq_clear = octeon_cf_irq_clear, - .bmdma_setup = unreachable_qc, - .bmdma_start = unreachable_qc, - .bmdma_stop = unreachable_qc, - .bmdma_status = unreachable_port, .cable_detect = ata_cable_40wire, .set_piomode = octeon_cf_set_piomode, .set_dmamode = octeon_cf_set_dmamode, diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index 0074351d7edf..daeebf19a6a9 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c @@ -120,8 +120,6 @@ static void qs_host_stop(struct ata_host *host); static void qs_qc_prep(struct ata_queued_cmd *qc); static unsigned int qs_qc_issue(struct ata_queued_cmd *qc); static int qs_check_atapi_dma(struct ata_queued_cmd *qc); -static void qs_bmdma_stop(struct ata_queued_cmd *qc); -static u8 qs_bmdma_status(struct ata_port *ap); static void qs_freeze(struct ata_port *ap); static void qs_thaw(struct ata_port *ap); static int qs_prereset(struct ata_link *link, unsigned long deadline); @@ -137,8 +135,6 @@ static struct ata_port_operations qs_ata_ops = { .inherits = &ata_sff_port_ops, .check_atapi_dma = qs_check_atapi_dma, - .bmdma_stop = qs_bmdma_stop, - .bmdma_status = qs_bmdma_status, .qc_prep = qs_qc_prep, .qc_issue = qs_qc_issue, @@ -190,16 +186,6 @@ static int qs_check_atapi_dma(struct ata_queued_cmd *qc) return 1; /* ATAPI DMA not supported */ } -static void qs_bmdma_stop(struct ata_queued_cmd *qc) -{ - /* nothing */ -} - -static u8 qs_bmdma_status(struct ata_port *ap) -{ - return 0; -} - static inline void qs_enter_reg_mode(struct ata_port *ap) { u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000); -- cgit v1.2.3 From 9a7780c9acb821fe1c2b6fc53f74cc2556ff5364 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 19 May 2010 22:10:24 +0200 Subject: libata-sff: make BMDMA optional Make BMDMA optional depending on new config variable CONFIG_ATA_BMDMA. In Kconfig, drivers are grouped into five groups - non-SFF native, SFF w/ custom DMA interface, SFF w/ BMDMA, PIO-only SFF, and generic fallback / legacy ones. Kconfig and Makefile are reorganized according to the groups and ordered alphabetically inside each group. ata_ioports.bmdma_addr and ata_port.bmdma_prd[_dma] are put into CONFIG_ATA_BMDMA, as are all bmdma related ops, variables and functions. This increase the binary size slightly when BMDMA is enabled but on both native-only and PIO-only configurations the size is slightly reduced. Either way, the size difference is insignificant. This change is more meaningful to signify the separation between SFF and BMDMA and as a tool to verify the separation. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/Kconfig | 511 +++++++++++++++++++++++++---------------------- drivers/ata/Makefile | 83 ++++---- drivers/ata/libata-sff.c | 11 + include/linux/libata.h | 22 +- 4 files changed, 341 insertions(+), 286 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index e68541f662b9..73f883333a0d 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -57,6 +57,8 @@ config SATA_PMP This option adds support for SATA Port Multipliers (the SATA version of an ethernet hub, or SAS expander). +comment "Controllers with non-SFF native interface" + config SATA_AHCI tristate "AHCI SATA support" depends on PCI @@ -73,11 +75,12 @@ config SATA_AHCI_PLATFORM If unsure, say N. -config SATA_SIL24 - tristate "Silicon Image 3124/3132 SATA support" - depends on PCI +config SATA_FSL + tristate "Freescale 3.0Gbps SATA support" + depends on FSL_SOC help - This option enables support for Silicon Image 3124/3132 Serial ATA. + This option enables support for Freescale 3.0Gbps SATA controller. + It can be found on MPC837x and MPC8315. If unsure, say N. @@ -87,12 +90,11 @@ config SATA_INIC162X help This option enables support for Initio 162x Serial ATA. -config SATA_FSL - tristate "Freescale 3.0Gbps SATA support" - depends on FSL_SOC +config SATA_SIL24 + tristate "Silicon Image 3124/3132 SATA support" + depends on PCI help - This option enables support for Freescale 3.0Gbps SATA controller. - It can be found on MPC837x and MPC8315. + This option enables support for Silicon Image 3124/3132 Serial ATA. If unsure, say N. @@ -116,15 +118,65 @@ config ATA_SFF if ATA_SFF -config SATA_SVW - tristate "ServerWorks Frodo / Apple K2 SATA support" +comment "SFF controllers with custom DMA interface" + +config PDC_ADMA + tristate "Pacific Digital ADMA support" depends on PCI help - This option enables support for Broadcom/Serverworks/Apple K2 - SATA support. + This option enables support for Pacific Digital ADMA controllers + + If unsure, say N. + +config PATA_MPC52xx + tristate "Freescale MPC52xx SoC internal IDE" + depends on PPC_MPC52xx && PPC_BESTCOMM + select PPC_BESTCOMM_ATA + help + This option enables support for integrated IDE controller + of the Freescale MPC52xx SoC. + + If unsure, say N. + +config PATA_OCTEON_CF + tristate "OCTEON Boot Bus Compact Flash support" + depends on CPU_CAVIUM_OCTEON + help + This option enables a polled compact flash driver for use with + compact flash cards attached to the OCTEON boot bus. + + If unsure, say N. + +config SATA_QSTOR + tristate "Pacific Digital SATA QStor support" + depends on PCI + help + This option enables support for Pacific Digital Serial ATA QStor. + + If unsure, say N. + +config SATA_SX4 + tristate "Promise SATA SX4 support (Experimental)" + depends on PCI && EXPERIMENTAL + help + This option enables support for Promise Serial ATA SX4. If unsure, say N. +config ATA_BMDMA + bool "ATA BMDMA support" + default y + help + This option adds support for SFF ATA controllers with BMDMA + capability. BMDMA stands for bus-master DMA and the + de-facto DMA interface for SFF controllers. + + If unuser, say Y. + +if ATA_BMDMA + +comment "SATA SFF controllers with BMDMA" + config ATA_PIIX tristate "Intel ESB, ICH, PIIX3, PIIX4 PATA/SATA support" depends on PCI @@ -152,22 +204,6 @@ config SATA_NV If unsure, say N. -config PDC_ADMA - tristate "Pacific Digital ADMA support" - depends on PCI - help - This option enables support for Pacific Digital ADMA controllers - - If unsure, say N. - -config SATA_QSTOR - tristate "Pacific Digital SATA QStor support" - depends on PCI - help - This option enables support for Pacific Digital Serial ATA QStor. - - If unsure, say N. - config SATA_PROMISE tristate "Promise SATA TX2/TX4 support" depends on PCI @@ -176,14 +212,6 @@ config SATA_PROMISE If unsure, say N. -config SATA_SX4 - tristate "Promise SATA SX4 support (Experimental)" - depends on PCI && EXPERIMENTAL - help - This option enables support for Promise Serial ATA SX4. - - If unsure, say N. - config SATA_SIL tristate "Silicon Image SATA support" depends on PCI @@ -203,6 +231,15 @@ config SATA_SIS enable the PATA_SIS driver in the config. If unsure, say N. +config SATA_SVW + tristate "ServerWorks Frodo / Apple K2 SATA support" + depends on PCI + help + This option enables support for Broadcom/Serverworks/Apple K2 + SATA support. + + If unsure, say N. + config SATA_ULI tristate "ULi Electronics SATA support" depends on PCI @@ -227,14 +264,7 @@ config SATA_VITESSE If unsure, say N. -config PATA_ACPI - tristate "ACPI firmware driver for PATA" - depends on ATA_ACPI - help - This option enables an ACPI method driver which drives - motherboard PATA controller interfaces through the ACPI - firmware in the BIOS. This driver can sometimes handle - otherwise unsupported hardware. +comment "PATA SFF controllers with BMDMA" config PATA_ALI tristate "ALi PATA support" @@ -262,40 +292,30 @@ config PATA_ARTOP If unsure, say N. -config PATA_ATP867X - tristate "ARTOP/Acard ATP867X PATA support" +config PATA_ATIIXP + tristate "ATI PATA support" depends on PCI help - This option enables support for ARTOP/Acard ATP867X PATA - controllers. - - If unsure, say N. - -config PATA_AT32 - tristate "Atmel AVR32 PATA support (Experimental)" - depends on AVR32 && PLATFORM_AT32AP && EXPERIMENTAL - help - This option enables support for the IDE devices on the - Atmel AT32AP platform. + This option enables support for the ATI ATA interfaces + found on the many ATI chipsets. If unsure, say N. -config PATA_ATIIXP - tristate "ATI PATA support" +config PATA_ATP867X + tristate "ARTOP/Acard ATP867X PATA support" depends on PCI help - This option enables support for the ATI ATA interfaces - found on the many ATI chipsets. + This option enables support for ARTOP/Acard ATP867X PATA + controllers. If unsure, say N. -config PATA_CMD640_PCI - tristate "CMD640 PCI PATA support (Experimental)" - depends on PCI && EXPERIMENTAL +config PATA_BF54X + tristate "Blackfin 54x ATAPI support" + depends on BF542 || BF548 || BF549 help - This option enables support for the CMD640 PCI IDE - interface chip. Only the primary channel is currently - supported. + This option enables support for the built-in ATAPI controller on + Blackfin 54x family chips. If unsure, say N. @@ -362,15 +382,6 @@ config PATA_EFAR If unsure, say N. -config ATA_GENERIC - tristate "Generic ATA support" - depends on PCI - help - This option enables support for generic BIOS configured - ATA controllers via the new ATA layer - - If unsure, say N. - config PATA_HPT366 tristate "HPT 366/368 PATA support" depends on PCI @@ -415,12 +426,20 @@ config PATA_HPT3X3_DMA controllers. Enable with care as there are still some problems with DMA on this chipset. -config PATA_ISAPNP - tristate "ISA Plug and Play PATA support" - depends on ISAPNP +config PATA_ICSIDE + tristate "Acorn ICS PATA support" + depends on ARM && ARCH_ACORN help - This option enables support for ISA plug & play ATA - controllers such as those found on old soundcards. + On Acorn systems, say Y here if you wish to use the ICS PATA + interface card. This is not required for ICS partition support. + If you are unsure, say N to this. + +config PATA_IT8213 + tristate "IT8213 PATA support (Experimental)" + depends on PCI && EXPERIMENTAL + help + This option enables support for the ITE 821 PATA + controllers via the new ATA layer. If unsure, say N. @@ -434,15 +453,6 @@ config PATA_IT821X If unsure, say N. -config PATA_IT8213 - tristate "IT8213 PATA support (Experimental)" - depends on PCI && EXPERIMENTAL - help - This option enables support for the ITE 821 PATA - controllers via the new ATA layer. - - If unsure, say N. - config PATA_JMICRON tristate "JMicron PATA support" depends on PCI @@ -452,23 +462,14 @@ config PATA_JMICRON If unsure, say N. -config PATA_LEGACY - tristate "Legacy ISA PATA support (Experimental)" - depends on (ISA || PCI) && EXPERIMENTAL - help - This option enables support for ISA/VLB/PCI bus legacy PATA - ports and allows them to be accessed via the new ATA layer. - - If unsure, say N. - -config PATA_TRIFLEX - tristate "Compaq Triflex PATA support" - depends on PCI +config PATA_MACIO + tristate "Apple PowerMac/PowerBook internal 'MacIO' IDE" + depends on PPC_PMAC help - Enable support for the Compaq 'Triflex' IDE controller as found - on many Compaq Pentium-Pro systems, via the new ATA layer. - - If unsure, say N. + Most IDE capable PowerMacs have IDE busses driven by a variant + of this controller which is part of the Apple chipset used on + most PowerMac models. Some models have multiple busses using + different chipsets, though generally, MacIO is one of them. config PATA_MARVELL tristate "Marvell PATA support via legacy mode" @@ -481,32 +482,6 @@ config PATA_MARVELL If unsure, say N. -config PATA_MPC52xx - tristate "Freescale MPC52xx SoC internal IDE" - depends on PPC_MPC52xx && PPC_BESTCOMM - select PPC_BESTCOMM_ATA - help - This option enables support for integrated IDE controller - of the Freescale MPC52xx SoC. - - If unsure, say N. - -config PATA_MPIIX - tristate "Intel PATA MPIIX support" - depends on PCI - help - This option enables support for MPIIX PATA support. - - If unsure, say N. - -config PATA_OLDPIIX - tristate "Intel PATA old PIIX support" - depends on PCI - help - This option enables support for early PIIX PATA support. - - If unsure, say N. - config PATA_NETCELL tristate "NETCELL Revolution RAID support" depends on PCI @@ -525,15 +500,6 @@ config PATA_NINJA32 If unsure, say N. -config PATA_NS87410 - tristate "Nat Semi NS87410 PATA support" - depends on PCI - help - This option enables support for the National Semiconductor - NS87410 PCI-IDE controller. - - If unsure, say N. - config PATA_NS87415 tristate "Nat Semi NS87415 PATA support" depends on PCI @@ -543,12 +509,11 @@ config PATA_NS87415 If unsure, say N. -config PATA_OPTI - tristate "OPTI621/6215 PATA support (Very Experimental)" - depends on PCI && EXPERIMENTAL +config PATA_OLDPIIX + tristate "Intel PATA old PIIX support" + depends on PCI help - This option enables full PIO support for the early Opti ATA - controllers found on some old motherboards. + This option enables support for early PIIX PATA support. If unsure, say N. @@ -562,24 +527,6 @@ config PATA_OPTIDMA If unsure, say N. -config PATA_PALMLD - tristate "Palm LifeDrive PATA support" - depends on MACH_PALMLD - help - This option enables support for Palm LifeDrive's internal ATA - port via the new ATA layer. - - If unsure, say N. - -config PATA_PCMCIA - tristate "PCMCIA PATA support" - depends on PCMCIA - help - This option enables support for PCMCIA ATA interfaces, including - compact flash card adapters via the new ATA layer. - - If unsure, say N. - config PATA_PDC2027X tristate "Promise PATA 2027x support" depends on PCI @@ -597,12 +544,6 @@ config PATA_PDC_OLD If unsure, say N. -config PATA_QDI - tristate "QDI VLB PATA support" - depends on ISA - help - Support for QDI 6500 and 6580 PATA controllers on VESA local bus. - config PATA_RADISYS tristate "RADISYS 82600 PATA support (Experimental)" depends on PCI && EXPERIMENTAL @@ -612,15 +553,6 @@ config PATA_RADISYS If unsure, say N. -config PATA_RB532 - tristate "RouterBoard 532 PATA CompactFlash support" - depends on MIKROTIK_RB532 - help - This option enables support for the RouterBoard 532 - PATA CompactFlash controller. - - If unsure, say N. - config PATA_RDC tristate "RDC PATA support" depends on PCI @@ -631,21 +563,30 @@ config PATA_RDC If unsure, say N. -config PATA_RZ1000 - tristate "PC Tech RZ1000 PATA support" +config PATA_SC1200 + tristate "SC1200 PATA support" depends on PCI help - This option enables basic support for the PC Tech RZ1000/1 - PATA controllers via the new ATA layer + This option enables support for the NatSemi/AMD SC1200 SoC + companion chip used with the Geode processor family. If unsure, say N. -config PATA_SC1200 - tristate "SC1200 PATA support" +config PATA_SCC + tristate "Toshiba's Cell Reference Set IDE support" + depends on PCI && PPC_CELLEB + help + This option enables support for the built-in IDE controller on + Toshiba Cell Reference Board. + + If unsure, say N. + +config PATA_SCH + tristate "Intel SCH PATA support" depends on PCI help - This option enables support for the NatSemi/AMD SC1200 SoC - companion chip used with the Geode processor family. + This option enables support for Intel SCH PATA on the Intel + SCH (US15W, US15L, UL11L) series host controllers. If unsure, say N. @@ -683,6 +624,15 @@ config PATA_TOSHIBA If unsure, say N. +config PATA_TRIFLEX + tristate "Compaq Triflex PATA support" + depends on PCI + help + Enable support for the Compaq 'Triflex' IDE controller as found + on many Compaq Pentium-Pro systems, via the new ATA layer. + + If unsure, say N. + config PATA_VIA tristate "VIA PATA support" depends on PCI @@ -701,12 +651,99 @@ config PATA_WINBOND If unsure, say N. -config PATA_WINBOND_VLB - tristate "Winbond W83759A VLB PATA support (Experimental)" - depends on ISA && EXPERIMENTAL +endif # ATA_BMDMA + +comment "PIO-only SFF controllers" + +config PATA_AT32 + tristate "Atmel AVR32 PATA support (Experimental)" + depends on AVR32 && PLATFORM_AT32AP && EXPERIMENTAL help - Support for the Winbond W83759A controller on Vesa Local Bus - systems. + This option enables support for the IDE devices on the + Atmel AT32AP platform. + + If unsure, say N. + +config PATA_AT91 + tristate "PATA support for AT91SAM9260" + depends on ARM && ARCH_AT91 + help + This option enables support for IDE devices on the Atmel AT91SAM9260 SoC. + + If unsure, say N. + +config PATA_CMD640_PCI + tristate "CMD640 PCI PATA support (Experimental)" + depends on PCI && EXPERIMENTAL + help + This option enables support for the CMD640 PCI IDE + interface chip. Only the primary channel is currently + supported. + + If unsure, say N. + +config PATA_ISAPNP + tristate "ISA Plug and Play PATA support" + depends on ISAPNP + help + This option enables support for ISA plug & play ATA + controllers such as those found on old soundcards. + + If unsure, say N. + +config PATA_IXP4XX_CF + tristate "IXP4XX Compact Flash support" + depends on ARCH_IXP4XX + help + This option enables support for a Compact Flash connected on + the ixp4xx expansion bus. This driver had been written for + Loft/Avila boards in mind but can work with others. + + If unsure, say N. + +config PATA_MPIIX + tristate "Intel PATA MPIIX support" + depends on PCI + help + This option enables support for MPIIX PATA support. + + If unsure, say N. + +config PATA_NS87410 + tristate "Nat Semi NS87410 PATA support" + depends on PCI + help + This option enables support for the National Semiconductor + NS87410 PCI-IDE controller. + + If unsure, say N. + +config PATA_OPTI + tristate "OPTI621/6215 PATA support (Very Experimental)" + depends on PCI && EXPERIMENTAL + help + This option enables full PIO support for the early Opti ATA + controllers found on some old motherboards. + + If unsure, say N. + +config PATA_PALMLD + tristate "Palm LifeDrive PATA support" + depends on MACH_PALMLD + help + This option enables support for Palm LifeDrive's internal ATA + port via the new ATA layer. + + If unsure, say N. + +config PATA_PCMCIA + tristate "PCMCIA PATA support" + depends on PCMCIA + help + This option enables support for PCMCIA ATA interfaces, including + compact flash card adapters via the new ATA layer. + + If unsure, say N. config HAVE_PATA_PLATFORM bool @@ -725,14 +762,6 @@ config PATA_PLATFORM If unsure, say N. -config PATA_AT91 - tristate "PATA support for AT91SAM9260" - depends on ARM && ARCH_AT91 - help - This option enables support for IDE devices on the Atmel AT91SAM9260 SoC. - - If unsure, say N. - config PATA_OF_PLATFORM tristate "OpenFirmware platform device PATA support" depends on PATA_PLATFORM && PPC_OF @@ -743,69 +772,65 @@ config PATA_OF_PLATFORM If unsure, say N. -config PATA_ICSIDE - tristate "Acorn ICS PATA support" - depends on ARM && ARCH_ACORN +config PATA_QDI + tristate "QDI VLB PATA support" + depends on ISA help - On Acorn systems, say Y here if you wish to use the ICS PATA - interface card. This is not required for ICS partition support. - If you are unsure, say N to this. + Support for QDI 6500 and 6580 PATA controllers on VESA local bus. -config PATA_IXP4XX_CF - tristate "IXP4XX Compact Flash support" - depends on ARCH_IXP4XX +config PATA_RB532 + tristate "RouterBoard 532 PATA CompactFlash support" + depends on MIKROTIK_RB532 help - This option enables support for a Compact Flash connected on - the ixp4xx expansion bus. This driver had been written for - Loft/Avila boards in mind but can work with others. + This option enables support for the RouterBoard 532 + PATA CompactFlash controller. If unsure, say N. -config PATA_OCTEON_CF - tristate "OCTEON Boot Bus Compact Flash support" - depends on CPU_CAVIUM_OCTEON +config PATA_RZ1000 + tristate "PC Tech RZ1000 PATA support" + depends on PCI help - This option enables a polled compact flash driver for use with - compact flash cards attached to the OCTEON boot bus. + This option enables basic support for the PC Tech RZ1000/1 + PATA controllers via the new ATA layer If unsure, say N. -config PATA_SCC - tristate "Toshiba's Cell Reference Set IDE support" - depends on PCI && PPC_CELLEB +config PATA_WINBOND_VLB + tristate "Winbond W83759A VLB PATA support (Experimental)" + depends on ISA && EXPERIMENTAL help - This option enables support for the built-in IDE controller on - Toshiba Cell Reference Board. + Support for the Winbond W83759A controller on Vesa Local Bus + systems. - If unsure, say N. +comment "Generic fallback / legacy drivers" -config PATA_SCH - tristate "Intel SCH PATA support" - depends on PCI +config PATA_ACPI + tristate "ACPI firmware driver for PATA" + depends on ATA_ACPI && ATA_BMDMA help - This option enables support for Intel SCH PATA on the Intel - SCH (US15W, US15L, UL11L) series host controllers. - - If unsure, say N. + This option enables an ACPI method driver which drives + motherboard PATA controller interfaces through the ACPI + firmware in the BIOS. This driver can sometimes handle + otherwise unsupported hardware. -config PATA_BF54X - tristate "Blackfin 54x ATAPI support" - depends on BF542 || BF548 || BF549 +config ATA_GENERIC + tristate "Generic ATA support" + depends on PCI && ATA_BMDMA help - This option enables support for the built-in ATAPI controller on - Blackfin 54x family chips. + This option enables support for generic BIOS configured + ATA controllers via the new ATA layer If unsure, say N. -config PATA_MACIO - tristate "Apple PowerMac/PowerBook internal 'MacIO' IDE" - depends on PPC_PMAC +config PATA_LEGACY + tristate "Legacy ISA PATA support (Experimental)" + depends on (ISA || PCI) && EXPERIMENTAL help - Most IDE capable PowerMacs have IDE busses driven by a variant - of this controller which is part of the Apple chipset used on - most PowerMac models. Some models have multiple busses using - different chipsets, though generally, MacIO is one of them. + This option enables support for ISA/VLB/PCI bus legacy PATA + ports and allows them to be accessed via the new ATA layer. + If unsure, say N. endif # ATA_SFF endif # ATA diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index d0a93c4ad3ec..7ef89d73df63 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -1,33 +1,39 @@ obj-$(CONFIG_ATA) += libata.o +# non-SFF interface obj-$(CONFIG_SATA_AHCI) += ahci.o libahci.o obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o -obj-$(CONFIG_SATA_SVW) += sata_svw.o +obj-$(CONFIG_SATA_FSL) += sata_fsl.o +obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o +obj-$(CONFIG_SATA_SIL24) += sata_sil24.o + +# SFF w/ custom DMA +obj-$(CONFIG_PDC_ADMA) += pdc_adma.o +obj-$(CONFIG_PATA_MPC52xx) += pata_mpc52xx.o +obj-$(CONFIG_PATA_OCTEON_CF) += pata_octeon_cf.o +obj-$(CONFIG_SATA_QSTOR) += sata_qstor.o +obj-$(CONFIG_SATA_SX4) += sata_sx4.o + +# SFF SATA w/ BMDMA obj-$(CONFIG_ATA_PIIX) += ata_piix.o +obj-$(CONFIG_SATA_MV) += sata_mv.o +obj-$(CONFIG_SATA_NV) += sata_nv.o obj-$(CONFIG_SATA_PROMISE) += sata_promise.o -obj-$(CONFIG_SATA_QSTOR) += sata_qstor.o obj-$(CONFIG_SATA_SIL) += sata_sil.o -obj-$(CONFIG_SATA_SIL24) += sata_sil24.o -obj-$(CONFIG_SATA_VIA) += sata_via.o -obj-$(CONFIG_SATA_VITESSE) += sata_vsc.o obj-$(CONFIG_SATA_SIS) += sata_sis.o -obj-$(CONFIG_SATA_SX4) += sata_sx4.o -obj-$(CONFIG_SATA_NV) += sata_nv.o +obj-$(CONFIG_SATA_SVW) += sata_svw.o obj-$(CONFIG_SATA_ULI) += sata_uli.o -obj-$(CONFIG_SATA_MV) += sata_mv.o -obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o -obj-$(CONFIG_PDC_ADMA) += pdc_adma.o -obj-$(CONFIG_SATA_FSL) += sata_fsl.o -obj-$(CONFIG_PATA_MACIO) += pata_macio.o +obj-$(CONFIG_SATA_VIA) += sata_via.o +obj-$(CONFIG_SATA_VITESSE) += sata_vsc.o +# SFF PATA w/ BMDMA obj-$(CONFIG_PATA_ALI) += pata_ali.o obj-$(CONFIG_PATA_AMD) += pata_amd.o obj-$(CONFIG_PATA_ARTOP) += pata_artop.o -obj-$(CONFIG_PATA_ATP867X) += pata_atp867x.o -obj-$(CONFIG_PATA_AT32) += pata_at32.o obj-$(CONFIG_PATA_ATIIXP) += pata_atiixp.o -obj-$(CONFIG_PATA_CMD640_PCI) += pata_cmd640.o +obj-$(CONFIG_PATA_ATP867X) += pata_atp867x.o +obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o obj-$(CONFIG_PATA_CMD64X) += pata_cmd64x.o obj-$(CONFIG_PATA_CS5520) += pata_cs5520.o obj-$(CONFIG_PATA_CS5530) += pata_cs5530.o @@ -39,47 +45,50 @@ obj-$(CONFIG_PATA_HPT366) += pata_hpt366.o obj-$(CONFIG_PATA_HPT37X) += pata_hpt37x.o obj-$(CONFIG_PATA_HPT3X2N) += pata_hpt3x2n.o obj-$(CONFIG_PATA_HPT3X3) += pata_hpt3x3.o -obj-$(CONFIG_PATA_ISAPNP) += pata_isapnp.o -obj-$(CONFIG_PATA_IT821X) += pata_it821x.o +obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o obj-$(CONFIG_PATA_IT8213) += pata_it8213.o +obj-$(CONFIG_PATA_IT821X) += pata_it821x.o obj-$(CONFIG_PATA_JMICRON) += pata_jmicron.o +obj-$(CONFIG_PATA_MACIO) += pata_macio.o +obj-$(CONFIG_PATA_MARVELL) += pata_marvell.o obj-$(CONFIG_PATA_NETCELL) += pata_netcell.o obj-$(CONFIG_PATA_NINJA32) += pata_ninja32.o -obj-$(CONFIG_PATA_NS87410) += pata_ns87410.o obj-$(CONFIG_PATA_NS87415) += pata_ns87415.o -obj-$(CONFIG_PATA_OPTI) += pata_opti.o -obj-$(CONFIG_PATA_OPTIDMA) += pata_optidma.o -obj-$(CONFIG_PATA_MPC52xx) += pata_mpc52xx.o -obj-$(CONFIG_PATA_MARVELL) += pata_marvell.o -obj-$(CONFIG_PATA_MPIIX) += pata_mpiix.o obj-$(CONFIG_PATA_OLDPIIX) += pata_oldpiix.o -obj-$(CONFIG_PATA_PALMLD) += pata_palmld.o -obj-$(CONFIG_PATA_PCMCIA) += pata_pcmcia.o +obj-$(CONFIG_PATA_OPTIDMA) += pata_optidma.o obj-$(CONFIG_PATA_PDC2027X) += pata_pdc2027x.o obj-$(CONFIG_PATA_PDC_OLD) += pata_pdc202xx_old.o -obj-$(CONFIG_PATA_QDI) += pata_qdi.o obj-$(CONFIG_PATA_RADISYS) += pata_radisys.o -obj-$(CONFIG_PATA_RB532) += pata_rb532_cf.o obj-$(CONFIG_PATA_RDC) += pata_rdc.o -obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o obj-$(CONFIG_PATA_SC1200) += pata_sc1200.o +obj-$(CONFIG_PATA_SCC) += pata_scc.o +obj-$(CONFIG_PATA_SCH) += pata_sch.o obj-$(CONFIG_PATA_SERVERWORKS) += pata_serverworks.o obj-$(CONFIG_PATA_SIL680) += pata_sil680.o +obj-$(CONFIG_PATA_SIS) += pata_sis.o obj-$(CONFIG_PATA_TOSHIBA) += pata_piccolo.o +obj-$(CONFIG_PATA_TRIFLEX) += pata_triflex.o obj-$(CONFIG_PATA_VIA) += pata_via.o obj-$(CONFIG_PATA_WINBOND) += pata_sl82c105.o -obj-$(CONFIG_PATA_WINBOND_VLB) += pata_winbond.o -obj-$(CONFIG_PATA_SIS) += pata_sis.o -obj-$(CONFIG_PATA_TRIFLEX) += pata_triflex.o + +# SFF PIO only +obj-$(CONFIG_PATA_AT32) += pata_at32.o +obj-$(CONFIG_PATA_AT91) += pata_at91.o +obj-$(CONFIG_PATA_CMD640_PCI) += pata_cmd640.o +obj-$(CONFIG_PATA_ISAPNP) += pata_isapnp.o obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o -obj-$(CONFIG_PATA_SCC) += pata_scc.o -obj-$(CONFIG_PATA_SCH) += pata_sch.o -obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o -obj-$(CONFIG_PATA_OCTEON_CF) += pata_octeon_cf.o +obj-$(CONFIG_PATA_MPIIX) += pata_mpiix.o +obj-$(CONFIG_PATA_NS87410) += pata_ns87410.o +obj-$(CONFIG_PATA_OPTI) += pata_opti.o +obj-$(CONFIG_PATA_PCMCIA) += pata_pcmcia.o +obj-$(CONFIG_PATA_PALMLD) += pata_palmld.o obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o -obj-$(CONFIG_PATA_AT91) += pata_at91.o obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o -obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o +obj-$(CONFIG_PATA_QDI) += pata_qdi.o +obj-$(CONFIG_PATA_RB532) += pata_rb532_cf.o +obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o +obj-$(CONFIG_PATA_WINBOND_VLB) += pata_winbond.o + # Should be last but two libata driver obj-$(CONFIG_PATA_ACPI) += pata_acpi.o # Should be last but one libata driver diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index c29f1468e164..efa4a18cfb9d 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -798,11 +798,15 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc) case ATAPI_PROT_NODATA: ap->hsm_task_state = HSM_ST_LAST; break; +#ifdef CONFIG_ATA_BMDMA case ATAPI_PROT_DMA: ap->hsm_task_state = HSM_ST_LAST; /* initiate bmdma */ ap->ops->bmdma_start(qc); break; +#endif /* CONFIG_ATA_BMDMA */ + default: + BUG(); } } @@ -2535,6 +2539,12 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_init_one); #endif /* CONFIG_PCI */ +/* + * BMDMA support + */ + +#ifdef CONFIG_ATA_BMDMA + const struct ata_port_operations ata_bmdma_port_ops = { .inherits = &ata_sff_port_ops, @@ -3287,6 +3297,7 @@ int ata_pci_bmdma_init_one(struct pci_dev *pdev, EXPORT_SYMBOL_GPL(ata_pci_bmdma_init_one); #endif /* CONFIG_PCI */ +#endif /* CONFIG_ATA_BMDMA */ /** * ata_sff_port_init - Initialize SFF/BMDMA ATA port diff --git a/include/linux/libata.h b/include/linux/libata.h index fe2be88bc266..4c5eca4e663b 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -513,7 +513,9 @@ struct ata_ioports { void __iomem *command_addr; void __iomem *altstatus_addr; void __iomem *ctl_addr; +#ifdef CONFIG_ATA_BMDMA void __iomem *bmdma_addr; +#endif /* CONFIG_ATA_BMDMA */ void __iomem *scr_addr; }; #endif /* CONFIG_ATA_SFF */ @@ -721,8 +723,10 @@ struct ata_port { u8 ctl; /* cache of ATA control register */ u8 last_ctl; /* Cache last written value */ struct delayed_work sff_pio_task; +#ifdef CONFIG_ATA_BMDMA struct ata_bmdma_prd *bmdma_prd; /* BMDMA SG list */ dma_addr_t bmdma_prd_dma; /* and its DMA mapping */ +#endif /* CONFIG_ATA_BMDMA */ #endif /* CONFIG_ATA_SFF */ unsigned int pio_mask; @@ -856,10 +860,12 @@ struct ata_port_operations { void (*sff_irq_clear)(struct ata_port *); void (*sff_drain_fifo)(struct ata_queued_cmd *qc); +#ifdef CONFIG_ATA_BMDMA void (*bmdma_setup)(struct ata_queued_cmd *qc); void (*bmdma_start)(struct ata_queued_cmd *qc); void (*bmdma_stop)(struct ata_queued_cmd *qc); u8 (*bmdma_status)(struct ata_port *ap); +#endif /* CONFIG_ATA_BMDMA */ #endif /* CONFIG_ATA_SFF */ ssize_t (*em_show)(struct ata_port *ap, char *buf); @@ -1555,7 +1561,6 @@ extern void sata_pmp_error_handler(struct ata_port *ap); #ifdef CONFIG_ATA_SFF extern const struct ata_port_operations ata_sff_port_ops; -extern const struct ata_port_operations ata_bmdma_port_ops; extern const struct ata_port_operations ata_bmdma32_port_ops; /* PIO only, sg_tablesize and dma_boundary limits can be removed */ @@ -1564,11 +1569,6 @@ extern const struct ata_port_operations ata_bmdma32_port_ops; .sg_tablesize = LIBATA_MAX_PRD, \ .dma_boundary = ATA_DMA_BOUNDARY -#define ATA_BMDMA_SHT(drv_name) \ - ATA_BASE_SHT(drv_name), \ - .sg_tablesize = LIBATA_MAX_PRD, \ - .dma_boundary = ATA_DMA_BOUNDARY - extern void ata_sff_dev_select(struct ata_port *ap, unsigned int device); extern u8 ata_sff_check_status(struct ata_port *ap); extern void ata_sff_pause(struct ata_port *ap); @@ -1625,6 +1625,15 @@ extern int ata_pci_sff_init_one(struct pci_dev *pdev, struct scsi_host_template *sht, void *host_priv, int hflags); #endif /* CONFIG_PCI */ +#ifdef CONFIG_ATA_BMDMA + +extern const struct ata_port_operations ata_bmdma_port_ops; + +#define ATA_BMDMA_SHT(drv_name) \ + ATA_BASE_SHT(drv_name), \ + .sg_tablesize = LIBATA_MAX_PRD, \ + .dma_boundary = ATA_DMA_BOUNDARY + extern void ata_bmdma_qc_prep(struct ata_queued_cmd *qc); extern unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc); extern void ata_bmdma_dumb_qc_prep(struct ata_queued_cmd *qc); @@ -1652,6 +1661,7 @@ extern int ata_pci_bmdma_init_one(struct pci_dev *pdev, struct scsi_host_template *sht, void *host_priv, int hflags); #endif /* CONFIG_PCI */ +#endif /* CONFIG_ATA_BMDMA */ /** * ata_sff_busy_wait - Wait for a port status register -- cgit v1.2.3 From e7ecd435692ca9bde9d124be30b3a26e672ea6c2 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 19 May 2010 15:38:58 +0200 Subject: libata: disable ATAPI AN by default There are ATAPI devices which raise AN when hit by commands issued by open(). This leads to infinite loop of AN -> MEDIA_CHANGE uevent -> udev open() to check media -> AN. Both ACS and SerialATA standards don't define in which case ATAPI devices are supposed to raise or not raise AN. They both list media insertion event as a possible use case for ATAPI ANs but there is no clear description of what constitutes such events. As such, it seems a bit too naive to export ANs directly to userland as MEDIA_CHANGE events without further verification (which should behave similarly to windows as it apparently is the only thing that some hardware vendors are testing against). This patch adds libata.atapi_an module parameter and disables ATAPI AN by default for now. Signed-off-by: Tejun Heo Cc: Kay Sievers Cc: Nick Bowler Cc: David Zeuthen Cc: stable@kernel.org Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index c47373f01f89..8959f42c5b3b 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -160,6 +160,10 @@ int libata_allow_tpm = 0; module_param_named(allow_tpm, libata_allow_tpm, int, 0444); MODULE_PARM_DESC(allow_tpm, "Permit the use of TPM commands (0=off [default], 1=on)"); +static int atapi_an; +module_param(atapi_an, int, 0444); +MODULE_PARM_DESC(atapi_an, "Enable ATAPI AN media presence notification (0=0ff [default], 1=on)"); + MODULE_AUTHOR("Jeff Garzik"); MODULE_DESCRIPTION("Library module for ATA devices"); MODULE_LICENSE("GPL"); @@ -2510,7 +2514,8 @@ int ata_dev_configure(struct ata_device *dev) * to enable ATAPI AN to discern between PHY status * changed notifications and ATAPI ANs. */ - if ((ap->flags & ATA_FLAG_AN) && ata_id_has_atapi_AN(id) && + if (atapi_an && + (ap->flags & ATA_FLAG_AN) && ata_id_has_atapi_AN(id) && (!sata_pmp_attached(ap) || sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf) == 0)) { unsigned int err_mask; -- cgit v1.2.3 From 43c9c59185eec7caaff6e9dd8d4c93a4d9836a86 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 23 May 2010 12:59:11 +0200 Subject: libata: implement dump_id force param Add dump_id libata.force parameter. If specified, libata dumps full IDENTIFY data during device configuration. This is to aid debugging. Signed-off-by: Tejun Heo Cc: Larry Baker Signed-off-by: Jeff Garzik --- Documentation/kernel-parameters.txt | 2 ++ drivers/ata/libata-core.c | 9 +++++++++ include/linux/libata.h | 1 + 3 files changed, 12 insertions(+) (limited to 'drivers') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index b56ea860da21..a5c055066764 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1252,6 +1252,8 @@ and is between 256 and 4096 characters. It is defined in the file * nohrst, nosrst, norst: suppress hard, soft and both resets. + * dump_id: dump IDENTIFY data. + If there are multiple matching configurations changing the same attribute, the last one is used. diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 8959f42c5b3b..06b7e49e039c 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2126,6 +2126,14 @@ retry: goto err_out; } + if (dev->horkage & ATA_HORKAGE_DUMP_ID) { + ata_dev_printk(dev, KERN_DEBUG, "dumping IDENTIFY data, " + "class=%d may_fallback=%d tried_spinup=%d\n", + class, may_fallback, tried_spinup); + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, + 16, 2, id, ATA_ID_WORDS * sizeof(*id), true); + } + /* Falling back doesn't make sense if ID data was read * successfully at least once. */ @@ -6377,6 +6385,7 @@ static int __init ata_parse_force_one(char **cur, { "3.0Gbps", .spd_limit = 2 }, { "noncq", .horkage_on = ATA_HORKAGE_NONCQ }, { "ncq", .horkage_off = ATA_HORKAGE_NONCQ }, + { "dump_id", .horkage_on = ATA_HORKAGE_DUMP_ID }, { "pio0", .xfer_mask = 1 << (ATA_SHIFT_PIO + 0) }, { "pio1", .xfer_mask = 1 << (ATA_SHIFT_PIO + 1) }, { "pio2", .xfer_mask = 1 << (ATA_SHIFT_PIO + 2) }, diff --git a/include/linux/libata.h b/include/linux/libata.h index 4c5eca4e663b..3bad2701bfa6 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -386,6 +386,7 @@ enum { ATA_HORKAGE_1_5_GBPS = (1 << 13), /* force 1.5 Gbps */ ATA_HORKAGE_NOSETXFER = (1 << 14), /* skip SETXFER, SATA only */ ATA_HORKAGE_BROKEN_FPDMA_AA = (1 << 15), /* skip AA */ + ATA_HORKAGE_DUMP_ID = (1 << 16), /* dump IDENTIFY data */ /* DMA mask for user DMA control: User visible values; DO NOT renumber */ -- cgit v1.2.3 From 921d98b58285805d792257e311da9e920eb5d73e Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Wed, 26 May 2010 10:27:44 +1000 Subject: drm/radeon/kms: suppress a build warning (unused variable) At least 'make CONFIG_DEBUG_SECTION_MISMATCH=y' causes drivers/gpu/drm/radeon/atombios_crtc.c: In function 'atombios_crtc_set_pll': drivers/gpu/drm/radeon/atombios_crtc.c:684: warning: 'pll' may be used uninitialized in this function which has the looks of a falso positive. Add a default: case so that gcc rests assured that all possible pll_id's are covered. Keep the present cases that fall through to the default one for self-documentation. Signed-off-by: Stefan Richter Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atombios_crtc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 03dd6c41dc19..f3f2827017ef 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -707,6 +707,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode break; case ATOM_DCPLL: case ATOM_PPLL_INVALID: + default: pll = &rdev->clock.dcpll; break; } -- cgit v1.2.3 From 4a638b4e38234233f5c7e6705662fbc0b58d80c2 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 25 May 2010 16:33:09 -0400 Subject: drm/edid: Allow non-fatal checksum errors in CEA blocks Switches will try to update the topology address and not correctly fix up the checksum, so just let it slide. https://bugs.freedesktop.org/28229 Signed-off-by: Adam Jackson Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_edid.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index f569ae88ab38..c1981861bbbd 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -147,7 +147,10 @@ drm_edid_block_valid(u8 *raw_edid) csum += raw_edid[i]; if (csum) { DRM_ERROR("EDID checksum is invalid, remainder is %d\n", csum); - goto bad; + + /* allow CEA to slide through, switches mangle this */ + if (raw_edid[0] != 0x02) + goto bad; } /* per-block-type checks */ -- cgit v1.2.3 From ff6c7341e0bc486c3e1b369ab7f3b325b98600d3 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 25 May 2010 17:37:08 -0700 Subject: n2_crypto: Fix build after of_device/of_platform_driver changes. Signed-off-by: David S. Miller --- drivers/crypto/n2_core.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/n2_core.c b/drivers/crypto/n2_core.c index 8566be832f51..1a5b1e709d67 100644 --- a/drivers/crypto/n2_core.c +++ b/drivers/crypto/n2_core.c @@ -1398,7 +1398,7 @@ static int find_devino_index(struct of_device *dev, struct spu_mdesc_info *ip, intr = ip->ino_table[i].intr; - dev_intrs = of_get_property(dev->node, "interrupts", NULL); + dev_intrs = of_get_property(dev->dev.of_node, "interrupts", NULL); if (!dev_intrs) return -ENODEV; @@ -1574,7 +1574,7 @@ static int spu_mdesc_walk_arcs(struct mdesc_handle *mdesc, id = mdesc_get_property(mdesc, tgt, "id", NULL); if (table[*id] != NULL) { dev_err(&dev->dev, "%s: SPU cpu slot already set.\n", - dev->node->full_name); + dev->dev.of_node->full_name); return -EINVAL; } cpu_set(*id, p->sharing); @@ -1595,7 +1595,7 @@ static int handle_exec_unit(struct spu_mdesc_info *ip, struct list_head *list, p = kzalloc(sizeof(struct spu_queue), GFP_KERNEL); if (!p) { dev_err(&dev->dev, "%s: Could not allocate SPU queue.\n", - dev->node->full_name); + dev->dev.of_node->full_name); return -ENOMEM; } @@ -1684,7 +1684,7 @@ static int __devinit grab_mdesc_irq_props(struct mdesc_handle *mdesc, const unsigned int *reg; u64 node; - reg = of_get_property(dev->node, "reg", NULL); + reg = of_get_property(dev->dev.of_node, "reg", NULL); if (!reg) return -ENODEV; @@ -1836,7 +1836,7 @@ static int __devinit n2_crypto_probe(struct of_device *dev, n2_spu_driver_version(); - full_name = dev->node->full_name; + full_name = dev->dev.of_node->full_name; pr_info("Found N2CP at %s\n", full_name); np = alloc_n2cp(); @@ -1948,7 +1948,7 @@ static int __devinit n2_mau_probe(struct of_device *dev, n2_spu_driver_version(); - full_name = dev->node->full_name; + full_name = dev->dev.of_node->full_name; pr_info("Found NCP at %s\n", full_name); mp = alloc_ncp(); @@ -2034,8 +2034,11 @@ static struct of_device_id n2_crypto_match[] = { MODULE_DEVICE_TABLE(of, n2_crypto_match); static struct of_platform_driver n2_crypto_driver = { - .name = "n2cp", - .match_table = n2_crypto_match, + .driver = { + .name = "n2cp", + .owner = THIS_MODULE, + .of_match_table = n2_crypto_match, + }, .probe = n2_crypto_probe, .remove = __devexit_p(n2_crypto_remove), }; @@ -2055,8 +2058,11 @@ static struct of_device_id n2_mau_match[] = { MODULE_DEVICE_TABLE(of, n2_mau_match); static struct of_platform_driver n2_mau_driver = { - .name = "ncp", - .match_table = n2_mau_match, + .driver = { + .name = "ncp", + .owner = THIS_MODULE, + .of_match_table = n2_mau_match, + }, .probe = n2_mau_probe, .remove = __devexit_p(n2_mau_remove), }; -- cgit v1.2.3 From 527b9525256f97ad8d092bbfc8fdc3c5409f4a4d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 22 May 2010 00:50:12 -0700 Subject: n2_crypto: Fix MAU kmem_cache name. Both the CWQ and MAU caches unintentionally had that same name. Signed-off-by: David S. Miller --- drivers/crypto/n2_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/crypto/n2_core.c b/drivers/crypto/n2_core.c index 1a5b1e709d67..5613b8affe11 100644 --- a/drivers/crypto/n2_core.c +++ b/drivers/crypto/n2_core.c @@ -1449,7 +1449,7 @@ static int queue_cache_init(void) { if (!queue_cache[HV_NCS_QTYPE_MAU - 1]) queue_cache[HV_NCS_QTYPE_MAU - 1] = - kmem_cache_create("cwq_queue", + kmem_cache_create("mau_queue", (MAU_NUM_ENTRIES * MAU_ENTRY_SIZE), MAU_ENTRY_SIZE, 0, NULL); -- cgit v1.2.3 From c9aa55e5271a53d28e93fa58759d318b403c15ba Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 22 May 2010 01:09:04 -0700 Subject: n2_crypto: Plumb fallback ahash requests properly. Do this by putting the async fallback request at the end of an n2 specific ahash request context, then properly adjusting the request private size in our ahash ->cra_init(). We also need to put the writable state bits into the n2 request private instead of the n2 cra_ctx. With help from Herbert Xu. Signed-off-by: David S. Miller --- drivers/crypto/n2_core.c | 95 ++++++++++++++++++++++++------------------------ 1 file changed, 48 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/n2_core.c b/drivers/crypto/n2_core.c index 5613b8affe11..23163fda5035 100644 --- a/drivers/crypto/n2_core.c +++ b/drivers/crypto/n2_core.c @@ -251,16 +251,10 @@ static void n2_base_ctx_init(struct n2_base_ctx *ctx) struct n2_hash_ctx { struct n2_base_ctx base; - struct crypto_ahash *fallback; + struct crypto_ahash *fallback_tfm; +}; - /* These next three members must match the layout created by - * crypto_init_shash_ops_async. This allows us to properly - * plumb requests we can't do in hardware down to the fallback - * operation, providing all of the data structures and layouts - * expected by those paths. - */ - struct ahash_request fallback_req; - struct shash_desc fallback_desc; +struct n2_hash_req_ctx { union { struct md5_state md5; struct sha1_state sha1; @@ -269,56 +263,62 @@ struct n2_hash_ctx { unsigned char hash_key[64]; unsigned char keyed_zero_hash[32]; + + struct ahash_request fallback_req; }; static int n2_hash_async_init(struct ahash_request *req) { + struct n2_hash_req_ctx *rctx = ahash_request_ctx(req); struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); - ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback); - ctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; + ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm); + rctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; - return crypto_ahash_init(&ctx->fallback_req); + return crypto_ahash_init(&rctx->fallback_req); } static int n2_hash_async_update(struct ahash_request *req) { + struct n2_hash_req_ctx *rctx = ahash_request_ctx(req); struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); - ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback); - ctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; - ctx->fallback_req.nbytes = req->nbytes; - ctx->fallback_req.src = req->src; + ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm); + rctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; + rctx->fallback_req.nbytes = req->nbytes; + rctx->fallback_req.src = req->src; - return crypto_ahash_update(&ctx->fallback_req); + return crypto_ahash_update(&rctx->fallback_req); } static int n2_hash_async_final(struct ahash_request *req) { + struct n2_hash_req_ctx *rctx = ahash_request_ctx(req); struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); - ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback); - ctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; - ctx->fallback_req.result = req->result; + ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm); + rctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; + rctx->fallback_req.result = req->result; - return crypto_ahash_final(&ctx->fallback_req); + return crypto_ahash_final(&rctx->fallback_req); } static int n2_hash_async_finup(struct ahash_request *req) { + struct n2_hash_req_ctx *rctx = ahash_request_ctx(req); struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); - ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback); - ctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; - ctx->fallback_req.nbytes = req->nbytes; - ctx->fallback_req.src = req->src; - ctx->fallback_req.result = req->result; + ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm); + rctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; + rctx->fallback_req.nbytes = req->nbytes; + rctx->fallback_req.src = req->src; + rctx->fallback_req.result = req->result; - return crypto_ahash_finup(&ctx->fallback_req); + return crypto_ahash_finup(&rctx->fallback_req); } static int n2_hash_cra_init(struct crypto_tfm *tfm) @@ -338,7 +338,10 @@ static int n2_hash_cra_init(struct crypto_tfm *tfm) goto out; } - ctx->fallback = fallback_tfm; + crypto_ahash_set_reqsize(ahash, (sizeof(struct n2_hash_req_ctx) + + crypto_ahash_reqsize(fallback_tfm))); + + ctx->fallback_tfm = fallback_tfm; return 0; out: @@ -350,7 +353,7 @@ static void n2_hash_cra_exit(struct crypto_tfm *tfm) struct crypto_ahash *ahash = __crypto_ahash_cast(tfm); struct n2_hash_ctx *ctx = crypto_ahash_ctx(ahash); - crypto_free_ahash(ctx->fallback); + crypto_free_ahash(ctx->fallback_tfm); } static unsigned long wait_for_tail(struct spu_queue *qp) @@ -399,14 +402,16 @@ static int n2_hash_async_digest(struct ahash_request *req, * exceed 2^16. */ if (unlikely(req->nbytes > (1 << 16))) { - ctx->fallback_req.base.tfm = crypto_ahash_tfm(ctx->fallback); - ctx->fallback_req.base.flags = + struct n2_hash_req_ctx *rctx = ahash_request_ctx(req); + + ahash_request_set_tfm(&rctx->fallback_req, ctx->fallback_tfm); + rctx->fallback_req.base.flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP; - ctx->fallback_req.nbytes = req->nbytes; - ctx->fallback_req.src = req->src; - ctx->fallback_req.result = req->result; + rctx->fallback_req.nbytes = req->nbytes; + rctx->fallback_req.src = req->src; + rctx->fallback_req.result = req->result; - return crypto_ahash_digest(&ctx->fallback_req); + return crypto_ahash_digest(&rctx->fallback_req); } n2_base_ctx_init(&ctx->base); @@ -472,9 +477,8 @@ out: static int n2_md5_async_digest(struct ahash_request *req) { - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); - struct md5_state *m = &ctx->u.md5; + struct n2_hash_req_ctx *rctx = ahash_request_ctx(req); + struct md5_state *m = &rctx->u.md5; if (unlikely(req->nbytes == 0)) { static const char md5_zero[MD5_DIGEST_SIZE] = { @@ -497,9 +501,8 @@ static int n2_md5_async_digest(struct ahash_request *req) static int n2_sha1_async_digest(struct ahash_request *req) { - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); - struct sha1_state *s = &ctx->u.sha1; + struct n2_hash_req_ctx *rctx = ahash_request_ctx(req); + struct sha1_state *s = &rctx->u.sha1; if (unlikely(req->nbytes == 0)) { static const char sha1_zero[SHA1_DIGEST_SIZE] = { @@ -524,9 +527,8 @@ static int n2_sha1_async_digest(struct ahash_request *req) static int n2_sha256_async_digest(struct ahash_request *req) { - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); - struct sha256_state *s = &ctx->u.sha256; + struct n2_hash_req_ctx *rctx = ahash_request_ctx(req); + struct sha256_state *s = &rctx->u.sha256; if (req->nbytes == 0) { static const char sha256_zero[SHA256_DIGEST_SIZE] = { @@ -555,9 +557,8 @@ static int n2_sha256_async_digest(struct ahash_request *req) static int n2_sha224_async_digest(struct ahash_request *req) { - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct n2_hash_ctx *ctx = crypto_ahash_ctx(tfm); - struct sha256_state *s = &ctx->u.sha256; + struct n2_hash_req_ctx *rctx = ahash_request_ctx(req); + struct sha256_state *s = &rctx->u.sha256; if (req->nbytes == 0) { static const char sha224_zero[SHA224_DIGEST_SIZE] = { -- cgit v1.2.3 From 2101d6f7ac791e87a274371a07a408f74e40ec49 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 24 May 2010 12:14:15 -0700 Subject: agp: amd64, fix pci reference leaks Stanse found pci reference leaks in uli_agp_init and nforce3_agp_init initialization functions. The PCI devices are bridges, so it's not critical, but still worth fixing. Signed-off-by: Jiri Slaby Cc: Jesse Barnes Signed-off-by: Andrew Morton Signed-off-by: Dave Airlie --- drivers/char/agp/amd64-agp.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 67ea3a60de74..70312da4c968 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c @@ -384,7 +384,7 @@ static int __devinit uli_agp_init(struct pci_dev *pdev) { u32 httfea,baseaddr,enuscr; struct pci_dev *dev1; - int i; + int i, ret; unsigned size = amd64_fetch_size(); dev_info(&pdev->dev, "setting up ULi AGP\n"); @@ -400,15 +400,18 @@ static int __devinit uli_agp_init(struct pci_dev *pdev) if (i == ARRAY_SIZE(uli_sizes)) { dev_info(&pdev->dev, "no ULi size found for %d\n", size); - return -ENODEV; + ret = -ENODEV; + goto put; } /* shadow x86-64 registers into ULi registers */ pci_read_config_dword (k8_northbridges[0], AMD64_GARTAPERTUREBASE, &httfea); /* if x86-64 aperture base is beyond 4G, exit here */ - if ((httfea & 0x7fff) >> (32 - 25)) - return -ENODEV; + if ((httfea & 0x7fff) >> (32 - 25)) { + ret = -ENODEV; + goto put; + } httfea = (httfea& 0x7fff) << 25; @@ -420,9 +423,10 @@ static int __devinit uli_agp_init(struct pci_dev *pdev) enuscr= httfea+ (size * 1024 * 1024) - 1; pci_write_config_dword(dev1, ULI_X86_64_HTT_FEA_REG, httfea); pci_write_config_dword(dev1, ULI_X86_64_ENU_SCR_REG, enuscr); - + ret = 0; +put: pci_dev_put(dev1); - return 0; + return ret; } @@ -441,7 +445,7 @@ static int nforce3_agp_init(struct pci_dev *pdev) { u32 tmp, apbase, apbar, aplimit; struct pci_dev *dev1; - int i; + int i, ret; unsigned size = amd64_fetch_size(); dev_info(&pdev->dev, "setting up Nforce3 AGP\n"); @@ -458,7 +462,8 @@ static int nforce3_agp_init(struct pci_dev *pdev) if (i == ARRAY_SIZE(nforce3_sizes)) { dev_info(&pdev->dev, "no NForce3 size found for %d\n", size); - return -ENODEV; + ret = -ENODEV; + goto put; } pci_read_config_dword(dev1, NVIDIA_X86_64_1_APSIZE, &tmp); @@ -472,7 +477,8 @@ static int nforce3_agp_init(struct pci_dev *pdev) /* if x86-64 aperture base is beyond 4G, exit here */ if ( (apbase & 0x7fff) >> (32 - 25) ) { dev_info(&pdev->dev, "aperture base > 4G\n"); - return -ENODEV; + ret = -ENODEV; + goto put; } apbase = (apbase & 0x7fff) << 25; @@ -488,9 +494,11 @@ static int nforce3_agp_init(struct pci_dev *pdev) pci_write_config_dword(dev1, NVIDIA_X86_64_1_APBASE2, apbase); pci_write_config_dword(dev1, NVIDIA_X86_64_1_APLIMIT2, aplimit); + ret = 0; +put: pci_dev_put(dev1); - return 0; + return ret; } static int __devinit agp_amd64_probe(struct pci_dev *pdev, -- cgit v1.2.3 From 7e3a1f4ab1a550dd6cf62a23aabedbad0d23e2d7 Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Tue, 25 May 2010 12:22:33 -0700 Subject: IB/qib: Fix undefined symbol error when CONFIG_PCI_MSI=n This patch fixes a compile error saying qib_init_iba6120_funcs() is undefined when CONFIG_PCI_MSI is not defined. Thanks to Randy Dunlap for finding this and suggesting the fix. Signed-off-by: Ralph Campbell Signed-off-by: Roland Dreier --- drivers/infiniband/hw/qib/qib_iba6120.c | 12 ------------ drivers/infiniband/hw/qib/qib_init.c | 6 ++++++ 2 files changed, 6 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/qib/qib_iba6120.c b/drivers/infiniband/hw/qib/qib_iba6120.c index 7b6549fd429b..1eadadc13da8 100644 --- a/drivers/infiniband/hw/qib/qib_iba6120.c +++ b/drivers/infiniband/hw/qib/qib_iba6120.c @@ -3475,14 +3475,6 @@ struct qib_devdata *qib_init_iba6120_funcs(struct pci_dev *pdev, struct qib_devdata *dd; int ret; -#ifndef CONFIG_PCI_MSI - qib_early_err(&pdev->dev, "QLogic PCIE device 0x%x cannot " - "work if CONFIG_PCI_MSI is not enabled\n", - ent->device); - dd = ERR_PTR(-ENODEV); - goto bail; -#endif - dd = qib_alloc_devdata(pdev, sizeof(struct qib_pportdata) + sizeof(struct qib_chip_specific)); if (IS_ERR(dd)) @@ -3554,10 +3546,6 @@ struct qib_devdata *qib_init_iba6120_funcs(struct pci_dev *pdev, if (qib_mini_init) goto bail; -#ifndef CONFIG_PCI_MSI - qib_dev_err(dd, "PCI_MSI not configured, NO interrupts\n"); -#endif - if (qib_pcie_params(dd, 8, NULL, NULL)) qib_dev_err(dd, "Failed to setup PCIe or interrupts; " "continuing anyway\n"); diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c index c0139c07e97e..9b40f345ac3f 100644 --- a/drivers/infiniband/hw/qib/qib_init.c +++ b/drivers/infiniband/hw/qib/qib_init.c @@ -1237,7 +1237,13 @@ static int __devinit qib_init_one(struct pci_dev *pdev, */ switch (ent->device) { case PCI_DEVICE_ID_QLOGIC_IB_6120: +#ifdef CONFIG_PCI_MSI dd = qib_init_iba6120_funcs(pdev, ent); +#else + qib_early_err(&pdev->dev, "QLogic PCIE device 0x%x cannot " + "work if CONFIG_PCI_MSI is not enabled\n", + ent->device); +#endif break; case PCI_DEVICE_ID_QLOGIC_IB_7220: -- cgit v1.2.3 From e642df6a0be93316c0a886766057c4cc510c123d Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 22 May 2010 10:21:27 +0200 Subject: IB/ucm: Use memdup_user() Use memdup_user when user data is immediately copied into the allocated region. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression from,to,size,flag; position p; identifier l1,l2; @@ - to = \(kmalloc@p\|kzalloc@p\)(size,flag); + to = memdup_user(from,size); if ( - to==NULL + IS_ERR(to) || ...) { <+... when != goto l1; - -ENOMEM + PTR_ERR(to) ...+> } - if (copy_from_user(to, from, size) != 0) { - <+... when != goto l2; - -EFAULT - ...+> - } // Signed-off-by: Julia Lawall --- drivers/infiniband/core/ucm.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index 46474842cfe9..08f948df8fa9 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c @@ -706,14 +706,9 @@ static int ib_ucm_alloc_data(const void **dest, u64 src, u32 len) if (!len) return 0; - data = kmalloc(len, GFP_KERNEL); - if (!data) - return -ENOMEM; - - if (copy_from_user(data, (void __user *)(unsigned long)src, len)) { - kfree(data); - return -EFAULT; - } + data = memdup_user((void __user *)(unsigned long)src, len); + if (IS_ERR(data)) + return PTR_ERR(data); *dest = data; return 0; -- cgit v1.2.3 From d938a702e5ce8909ea68be97566150507bfea4df Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Wed, 26 May 2010 00:33:43 -0700 Subject: be2net: increase POST timeout for EEH recovery Sometimes BE requires longer time for POST completion after an EEH reset. Increasing the timeout value accordingly. Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be_cmds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index c911bfb55b19..9d11dbf5e4da 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -294,7 +294,7 @@ int be_cmd_POST(struct be_adapter *adapter) } else { return 0; } - } while (timeout < 20); + } while (timeout < 40); dev_err(&adapter->pdev->dev, "POST timeout; stage=0x%x\n", stage); return -1; -- cgit v1.2.3 From 98652efceab8f0b1a3a1b2750544a395ec056115 Mon Sep 17 00:00:00 2001 From: Christoph Fritz Date: Sat, 17 Apr 2010 13:57:17 +0200 Subject: leds: 88pm860x - fix checking in probe function Improve device and platform data checks in probe function. Signed-off-by: Haojian Zhuang Signed-off-by: Christoph Fritz Signed-off-by: Richard Purdie --- drivers/leds/leds-88pm860x.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c index 16a60c06c96c..b7677106cff8 100644 --- a/drivers/leds/leds-88pm860x.c +++ b/drivers/leds/leds-88pm860x.c @@ -256,8 +256,10 @@ static int pm860x_led_probe(struct platform_device *pdev) if (pdev->dev.parent->platform_data) { pm860x_pdata = pdev->dev.parent->platform_data; pdata = pm860x_pdata->led; - } else - pdata = NULL; + } else { + dev_err(&pdev->dev, "missing platform data\n"); + return -EINVAL; + } data = kzalloc(sizeof(struct pm860x_led), GFP_KERNEL); if (data == NULL) @@ -268,8 +270,11 @@ static int pm860x_led_probe(struct platform_device *pdev) data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion; data->iset = pdata->iset; data->port = __check_device(pdata, data->name); - if (data->port < 0) + if (data->port < 0) { + dev_err(&pdev->dev, "check device failed\n"); + kfree(data); return -EINVAL; + } data->current_brightness = 0; data->cdev.name = data->name; -- cgit v1.2.3 From 14e40f644b020d473415342461b7c62e3bb5e312 Mon Sep 17 00:00:00 2001 From: Bjarke Istrup Pedersen Date: Mon, 24 May 2010 12:15:56 -0700 Subject: leds: Add LED driver for the Soekris net5501 board It is based on the previously submitted code by Alessandro Zummo, but is changed to use the new GPIO driver with 2.6.33, and the driver has been moved to drivers/leds where it belongs. [akpm@linux-foundation.org: coding-style fixes] [randy.dunlap@oracle.com: fix net5501 kconfig] Signed-off-by: Bjarke Istrup Pedersen Signed-off-by: Randy Dunlap Signed-off-by: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Richard Purdie --- drivers/leds/Kconfig | 10 +++++ drivers/leds/Makefile | 1 + drivers/leds/leds-net5501.c | 94 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 drivers/leds/leds-net5501.c (limited to 'drivers') diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 505eb64c329c..ecb6932c3636 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -67,6 +67,16 @@ config LEDS_NET48XX This option enables support for the Soekris net4801 and net4826 error LED. +config LEDS_NET5501 + tristate "LED Support for Soekris net5501 series Error LED" + depends on LEDS_CLASS && LEDS_TRIGGERS + depends on LEDS_GPIO_PLATFORM && GPIO_CS5535 + select LEDS_TRIGGER_DEFAULT_ON + default n + help + Add support for the Soekris net5501 board (detection, error led + and GPIO). + config LEDS_FSG tristate "LED Support for the Freecom FSG-3" depends on MACH_FSG diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 0cd8b9957380..77119f2e26b3 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_LEDS_MIKROTIK_RB532) += leds-rb532.o obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o +obj-$(CONFIG_LEDS_NET5501) += leds-net5501.o obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o obj-$(CONFIG_LEDS_ALIX2) += leds-alix2.o obj-$(CONFIG_LEDS_H1940) += leds-h1940.o diff --git a/drivers/leds/leds-net5501.c b/drivers/leds/leds-net5501.c new file mode 100644 index 000000000000..3063f591f0dc --- /dev/null +++ b/drivers/leds/leds-net5501.c @@ -0,0 +1,94 @@ +/* + * Soekris board support code + * + * Copyright (C) 2008-2009 Tower Technologies + * Written by Alessandro Zummo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +static struct gpio_led net5501_leds[] = { + { + .name = "error", + .gpio = 6, + .default_trigger = "default-on", + }, +}; + +static struct gpio_led_platform_data net5501_leds_data = { + .num_leds = ARRAY_SIZE(net5501_leds), + .leds = net5501_leds, +}; + +static struct platform_device net5501_leds_dev = { + .name = "leds-gpio", + .id = -1, + .dev.platform_data = &net5501_leds_data, +}; + +static void __init init_net5501(void) +{ + platform_device_register(&net5501_leds_dev); +} + +struct soekris_board { + u16 offset; + char *sig; + u8 len; + void (*init)(void); +}; + +static struct soekris_board __initdata boards[] = { + { 0xb7b, "net5501", 7, init_net5501 }, /* net5501 v1.33/1.33c */ + { 0xb1f, "net5501", 7, init_net5501 }, /* net5501 v1.32i */ +}; + +static int __init soekris_init(void) +{ + int i; + unsigned char *rombase, *bios; + + if (!is_geode()) + return 0; + + rombase = ioremap(0xffff0000, 0xffff); + if (!rombase) { + printk(KERN_INFO "Soekris net5501 LED driver failed to get rombase"); + return 0; + } + + bios = rombase + 0x20; /* null terminated */ + + if (strncmp(bios, "comBIOS", 7)) + goto unmap; + + for (i = 0; i < ARRAY_SIZE(boards); i++) { + unsigned char *model = rombase + boards[i].offset; + + if (strncmp(model, boards[i].sig, boards[i].len) == 0) { + printk(KERN_INFO "Soekris %s: %s\n", model, bios); + + if (boards[i].init) + boards[i].init(); + break; + } + } + +unmap: + iounmap(rombase); + return 0; +} + +arch_initcall(soekris_init); -- cgit v1.2.3 From 2146325df2c2640059a9e064890c30c6e259b458 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 22 May 2010 20:54:55 +1000 Subject: leds: leds-gpio: Change blink_set callback to be able to turn off blinking The leds-gpio blink_set() callback follows the same prototype as the main leds subsystem blink_set() one. The problem is that to stop blink, normally, a leds driver does it in the brightness_set() callback when asked to set a new fixed value. However, with leds-gpio, the platform has no hook to do so, as this later callback results in a standard GPIO manipulation. This changes the leds-gpio specific callback to take a new argument that indicates whether the LED should be blinking or not and in what state it should be set if not. We also update the dns323 platform which seems to be the only user of this so far. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Richard Purdie --- arch/arm/mach-orion5x/dns323-setup.c | 22 ++++++++++++---------- drivers/leds/leds-gpio.c | 31 ++++++++++++++++++++++++------- include/linux/leds.h | 12 ++++++++---- 3 files changed, 44 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c index 685f34a9634b..fe0de1698edc 100644 --- a/arch/arm/mach-orion5x/dns323-setup.c +++ b/arch/arm/mach-orion5x/dns323-setup.c @@ -240,22 +240,23 @@ error_fail: #define ORION_BLINK_HALF_PERIOD 100 /* ms */ -static int dns323_gpio_blink_set(unsigned gpio, +static int dns323_gpio_blink_set(unsigned gpio, int state, unsigned long *delay_on, unsigned long *delay_off) { - static int value = 0; - if (!*delay_on && !*delay_off) + if (delay_on && delay_off && !*delay_on && !*delay_off) *delay_on = *delay_off = ORION_BLINK_HALF_PERIOD; - if (ORION_BLINK_HALF_PERIOD == *delay_on - && ORION_BLINK_HALF_PERIOD == *delay_off) { - value = !value; - orion_gpio_set_blink(gpio, value); - return 0; + switch(state) { + case GPIO_LED_NO_BLINK_LOW: + case GPIO_LED_NO_BLINK_HIGH: + orion_gpio_set_blink(gpio, 0); + gpio_set_value(gpio, state); + break; + case GPIO_LED_BLINK: + orion_gpio_set_blink(gpio, 1); } - - return -EINVAL; + return 0; } static struct gpio_led dns323_leds[] = { @@ -263,6 +264,7 @@ static struct gpio_led dns323_leds[] = { .name = "power:blue", .gpio = DNS323_GPIO_LED_POWER2, .default_trigger = "timer", + .active_low = 1, }, { .name = "right:amber", .gpio = DNS323_GPIO_LED_RIGHT_AMBER, diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 6d94b0b9979c..26843dd6b859 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -26,7 +26,8 @@ struct gpio_led_data { u8 new_level; u8 can_sleep; u8 active_low; - int (*platform_gpio_blink_set)(unsigned gpio, + u8 blinking; + int (*platform_gpio_blink_set)(unsigned gpio, int state, unsigned long *delay_on, unsigned long *delay_off); }; @@ -35,7 +36,13 @@ static void gpio_led_work(struct work_struct *work) struct gpio_led_data *led_dat = container_of(work, struct gpio_led_data, work); - gpio_set_value_cansleep(led_dat->gpio, led_dat->new_level); + if (led_dat->blinking) { + led_dat->platform_gpio_blink_set(led_dat->gpio, + led_dat->new_level, + NULL, NULL); + led_dat->blinking = 0; + } else + gpio_set_value_cansleep(led_dat->gpio, led_dat->new_level); } static void gpio_led_set(struct led_classdev *led_cdev, @@ -60,8 +67,14 @@ static void gpio_led_set(struct led_classdev *led_cdev, if (led_dat->can_sleep) { led_dat->new_level = level; schedule_work(&led_dat->work); - } else - gpio_set_value(led_dat->gpio, level); + } else { + if (led_dat->blinking) { + led_dat->platform_gpio_blink_set(led_dat->gpio, level, + NULL, NULL); + led_dat->blinking = 0; + } else + gpio_set_value(led_dat->gpio, level); + } } static int gpio_blink_set(struct led_classdev *led_cdev, @@ -70,12 +83,14 @@ static int gpio_blink_set(struct led_classdev *led_cdev, struct gpio_led_data *led_dat = container_of(led_cdev, struct gpio_led_data, cdev); - return led_dat->platform_gpio_blink_set(led_dat->gpio, delay_on, delay_off); + led_dat->blinking = 1; + return led_dat->platform_gpio_blink_set(led_dat->gpio, GPIO_LED_BLINK, + delay_on, delay_off); } static int __devinit create_gpio_led(const struct gpio_led *template, struct gpio_led_data *led_dat, struct device *parent, - int (*blink_set)(unsigned, unsigned long *, unsigned long *)) + int (*blink_set)(unsigned, int, unsigned long *, unsigned long *)) { int ret, state; @@ -97,6 +112,7 @@ static int __devinit create_gpio_led(const struct gpio_led *template, led_dat->gpio = template->gpio; led_dat->can_sleep = gpio_cansleep(template->gpio); led_dat->active_low = template->active_low; + led_dat->blinking = 0; if (blink_set) { led_dat->platform_gpio_blink_set = blink_set; led_dat->cdev.blink_set = gpio_blink_set; @@ -113,7 +129,7 @@ static int __devinit create_gpio_led(const struct gpio_led *template, ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state); if (ret < 0) goto err; - + INIT_WORK(&led_dat->work, gpio_led_work); ret = led_classdev_register(parent, &led_dat->cdev); @@ -234,6 +250,7 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev, led.gpio = of_get_gpio_flags(child, 0, &flags); led.active_low = flags & OF_GPIO_ACTIVE_LOW; led.name = of_get_property(child, "label", NULL) ? : child->name; + led.blinking = 0; led.default_trigger = of_get_property(child, "linux,default-trigger", NULL); state = of_get_property(child, "default-state", NULL); diff --git a/include/linux/leds.h b/include/linux/leds.h index d8bf9665e70c..ba6986a11663 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -149,14 +149,18 @@ struct gpio_led { unsigned default_state : 2; /* default_state should be one of LEDS_GPIO_DEFSTATE_(ON|OFF|KEEP) */ }; -#define LEDS_GPIO_DEFSTATE_OFF 0 -#define LEDS_GPIO_DEFSTATE_ON 1 -#define LEDS_GPIO_DEFSTATE_KEEP 2 +#define LEDS_GPIO_DEFSTATE_OFF 0 +#define LEDS_GPIO_DEFSTATE_ON 1 +#define LEDS_GPIO_DEFSTATE_KEEP 2 struct gpio_led_platform_data { int num_leds; struct gpio_led *leds; - int (*gpio_blink_set)(unsigned gpio, + +#define GPIO_LED_NO_BLINK_LOW 0 /* No blink GPIO state low */ +#define GPIO_LED_NO_BLINK_HIGH 1 /* No blink GPIO state high */ +#define GPIO_LED_BLINK 2 /* Plase, blink */ + int (*gpio_blink_set)(unsigned gpio, int state, unsigned long *delay_on, unsigned long *delay_off); }; -- cgit v1.2.3 From 569762ef3dcf8fc5aecdb059d8c0741b90fe1d17 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 17 May 2010 08:48:28 +0800 Subject: leds: led-class: set permissions on max_brightness file to 0444 max_brightness is not writable, thus set permissions to 0444. Signed-off-by: Axel Lin Signed-off-by: Richard Purdie --- drivers/leds/led-class.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 69e7d86a5143..260660076507 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -74,7 +74,7 @@ static ssize_t led_max_brightness_show(struct device *dev, static struct device_attribute led_class_attrs[] = { __ATTR(brightness, 0644, led_brightness_show, led_brightness_store), - __ATTR(max_brightness, 0644, led_max_brightness_show, NULL), + __ATTR(max_brightness, 0444, led_max_brightness_show, NULL), #ifdef CONFIG_LEDS_TRIGGERS __ATTR(trigger, 0644, led_trigger_show, led_trigger_store), #endif -- cgit v1.2.3 From 7e1ce34f25c984a93dc0a2d8c217f7f78516b376 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 17 May 2010 17:47:48 +0800 Subject: leds: leds-lp3944: properly handle lp3944_configure fail in lp3944_probe In current implementation, lp3944_probe return 0 even if lp3944_configure fail. Therefore, led_classdev_unregister will be executed twice ( in error handling of lp3944_configure and lp3944_remove ). This patch properly handles lp3944_configure fail in lp3944_probe. Signed-off-by: Axel Lin Acked-by: Wolfram Sang Acked-by: Antonio Ospite Signed-off-by: Richard Purdie --- drivers/leds/leds-lp3944.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/leds/leds-lp3944.c b/drivers/leds/leds-lp3944.c index 8d5ecceba181..932a58da76c4 100644 --- a/drivers/leds/leds-lp3944.c +++ b/drivers/leds/leds-lp3944.c @@ -379,6 +379,7 @@ static int __devinit lp3944_probe(struct i2c_client *client, { struct lp3944_platform_data *lp3944_pdata = client->dev.platform_data; struct lp3944_data *data; + int err; if (lp3944_pdata == NULL) { dev_err(&client->dev, "no platform data\n"); @@ -401,9 +402,13 @@ static int __devinit lp3944_probe(struct i2c_client *client, mutex_init(&data->lock); - dev_info(&client->dev, "lp3944 enabled\n"); + err = lp3944_configure(client, data, lp3944_pdata); + if (err < 0) { + kfree(data); + return err; + } - lp3944_configure(client, data, lp3944_pdata); + dev_info(&client->dev, "lp3944 enabled\n"); return 0; } -- cgit v1.2.3 From 1e653accf7d2b02e75af550963b261b3243ac20e Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 17 May 2010 13:42:43 +0800 Subject: leds: leds-ss4200: fix led_classdev_unregister twice in error handling In current implementation, if device_create_file failed in register_nasgpio_led, led_classdev_unregister will be executed twice. ( in register_nasgpio_led it calls led_classdev_unregister before return and in nas_gpio_init out_err ) This patch fixes it by only unregistering those that were successfully registered in out_err. ( not including last failed register_nasgpio_led call ) Signed-off-by: Axel Lin Acked-by: Dave Hansen Signed-off-by: Richard Purdie --- drivers/leds/leds-ss4200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c index 51477ec71391..a688293abd0b 100644 --- a/drivers/leds/leds-ss4200.c +++ b/drivers/leds/leds-ss4200.c @@ -534,7 +534,7 @@ static int __init nas_gpio_init(void) set_power_light_amber_noblink(); return 0; out_err: - for (; i >= 0; i--) + for (i--; i >= 0; i--) unregister_nasgpio_led(i); pci_unregister_driver(&nas_gpio_pci_driver); return ret; -- cgit v1.2.3 From 7fdcef8a414eaeb367b3696005b25283d62d195d Mon Sep 17 00:00:00 2001 From: Philippe Rétornaz Date: Wed, 19 May 2010 09:24:31 +0200 Subject: leds: Add mc13783 LED support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This add basic led support for Freescale MC13783 PMIC. Signed-off-by: Philippe Rétornaz Signed-off-by: Richard Purdie --- drivers/leds/Kconfig | 7 + drivers/leds/Makefile | 1 + drivers/leds/leds-mc13783.c | 403 ++++++++++++++++++++++++++++++++++++++++++++ drivers/mfd/mc13783-core.c | 4 + include/linux/mfd/mc13783.h | 66 ++++++++ 5 files changed, 481 insertions(+) create mode 100644 drivers/leds/leds-mc13783.c (limited to 'drivers') diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index ecb6932c3636..f98d17a7108b 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -295,6 +295,13 @@ config LEDS_DELL_NETBOOKS This adds support for the Latitude 2100 and similar notebooks that have an external LED. +config LEDS_MC13783 + tristate "LED Support for MC13783 PMIC" + depends on MFD_MC13783 + help + This option enable support for on-chip LED drivers found + on Freescale Semiconductor MC13783 PMIC. + config LEDS_TRIGGERS bool "LED Trigger support" help diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 77119f2e26b3..2493de499374 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o obj-$(CONFIG_LEDS_DELL_NETBOOKS) += dell-led.o +obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o # LED SPI Drivers obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o diff --git a/drivers/leds/leds-mc13783.c b/drivers/leds/leds-mc13783.c new file mode 100644 index 000000000000..f05bb08d0f09 --- /dev/null +++ b/drivers/leds/leds-mc13783.c @@ -0,0 +1,403 @@ +/* + * LEDs driver for Freescale MC13783 + * + * Copyright (C) 2010 Philippe Rétornaz + * + * Based on leds-da903x: + * Copyright (C) 2008 Compulab, Ltd. + * Mike Rapoport + * + * Copyright (C) 2006-2008 Marvell International Ltd. + * Eric Miao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct mc13783_led { + struct led_classdev cdev; + struct work_struct work; + struct mc13783 *master; + enum led_brightness new_brightness; + int id; +}; + +#define MC13783_REG_LED_CONTROL_0 51 +#define MC13783_LED_C0_ENABLE_BIT (1 << 0) +#define MC13783_LED_C0_TRIODE_MD_BIT (1 << 7) +#define MC13783_LED_C0_TRIODE_AD_BIT (1 << 8) +#define MC13783_LED_C0_TRIODE_KP_BIT (1 << 9) +#define MC13783_LED_C0_BOOST_BIT (1 << 10) +#define MC13783_LED_C0_ABMODE_MASK 0x7 +#define MC13783_LED_C0_ABMODE 11 +#define MC13783_LED_C0_ABREF_MASK 0x3 +#define MC13783_LED_C0_ABREF 14 + +#define MC13783_REG_LED_CONTROL_1 52 +#define MC13783_LED_C1_TC1HALF_BIT (1 << 18) + +#define MC13783_REG_LED_CONTROL_2 53 +#define MC13783_LED_C2_BL_P_MASK 0xf +#define MC13783_LED_C2_MD_P 9 +#define MC13783_LED_C2_AD_P 13 +#define MC13783_LED_C2_KP_P 17 +#define MC13783_LED_C2_BL_C_MASK 0x7 +#define MC13783_LED_C2_MD_C 0 +#define MC13783_LED_C2_AD_C 3 +#define MC13783_LED_C2_KP_C 6 + +#define MC13783_REG_LED_CONTROL_3 54 +#define MC13783_LED_C3_TC_P 6 +#define MC13783_LED_C3_TC_P_MASK 0x1f + +#define MC13783_REG_LED_CONTROL_4 55 +#define MC13783_REG_LED_CONTROL_5 56 + +#define MC13783_LED_Cx_PERIOD 21 +#define MC13783_LED_Cx_PERIOD_MASK 0x3 +#define MC13783_LED_Cx_SLEWLIM_BIT (1 << 23) +#define MC13783_LED_Cx_TRIODE_TC_BIT (1 << 23) +#define MC13783_LED_Cx_TC_C_MASK 0x3 + +static void mc13783_led_work(struct work_struct *work) +{ + struct mc13783_led *led = container_of(work, struct mc13783_led, work); + int reg = 0; + int mask = 0; + int value = 0; + int bank, off, shift; + + switch (led->id) { + case MC13783_LED_MD: + reg = MC13783_REG_LED_CONTROL_2; + mask = MC13783_LED_C2_BL_P_MASK << MC13783_LED_C2_MD_P; + value = (led->new_brightness >> 4) << MC13783_LED_C2_MD_P; + break; + case MC13783_LED_AD: + reg = MC13783_REG_LED_CONTROL_2; + mask = MC13783_LED_C2_BL_P_MASK << MC13783_LED_C2_AD_P; + value = (led->new_brightness >> 4) << MC13783_LED_C2_AD_P; + break; + case MC13783_LED_KP: + reg = MC13783_REG_LED_CONTROL_2; + mask = MC13783_LED_C2_BL_P_MASK << MC13783_LED_C2_KP_P; + value = (led->new_brightness >> 4) << MC13783_LED_C2_KP_P; + break; + case MC13783_LED_R1: + case MC13783_LED_G1: + case MC13783_LED_B1: + case MC13783_LED_R2: + case MC13783_LED_G2: + case MC13783_LED_B2: + case MC13783_LED_R3: + case MC13783_LED_G3: + case MC13783_LED_B3: + off = led->id - MC13783_LED_R1; + bank = off/3; + reg = MC13783_REG_LED_CONTROL_3 + off/3; + shift = (off - bank * 3) * 5 + MC13783_LED_C3_TC_P; + value = (led->new_brightness >> 3) << shift; + mask = MC13783_LED_C3_TC_P_MASK << shift; + break; + } + + mc13783_lock(led->master); + + mc13783_reg_rmw(led->master, reg, mask, value); + + mc13783_unlock(led->master); +} + +static void mc13783_led_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct mc13783_led *led; + + led = container_of(led_cdev, struct mc13783_led, cdev); + led->new_brightness = value; + schedule_work(&led->work); +} + +static int __devinit mc13783_led_setup(struct mc13783_led *led, int max_current) +{ + int shift = 0; + int mask = 0; + int value = 0; + int reg = 0; + int ret, bank; + + switch (led->id) { + case MC13783_LED_MD: + shift = MC13783_LED_C2_MD_C; + mask = MC13783_LED_C2_BL_C_MASK; + value = max_current & MC13783_LED_C2_BL_C_MASK; + reg = MC13783_REG_LED_CONTROL_2; + break; + case MC13783_LED_AD: + shift = MC13783_LED_C2_AD_C; + mask = MC13783_LED_C2_BL_C_MASK; + value = max_current & MC13783_LED_C2_BL_C_MASK; + reg = MC13783_REG_LED_CONTROL_2; + break; + case MC13783_LED_KP: + shift = MC13783_LED_C2_KP_C; + mask = MC13783_LED_C2_BL_C_MASK; + value = max_current & MC13783_LED_C2_BL_C_MASK; + reg = MC13783_REG_LED_CONTROL_2; + break; + case MC13783_LED_R1: + case MC13783_LED_G1: + case MC13783_LED_B1: + case MC13783_LED_R2: + case MC13783_LED_G2: + case MC13783_LED_B2: + case MC13783_LED_R3: + case MC13783_LED_G3: + case MC13783_LED_B3: + bank = (led->id - MC13783_LED_R1)/3; + reg = MC13783_REG_LED_CONTROL_3 + bank; + shift = ((led->id - MC13783_LED_R1) - bank * 3) * 2; + mask = MC13783_LED_Cx_TC_C_MASK; + value = max_current & MC13783_LED_Cx_TC_C_MASK; + break; + } + + mc13783_lock(led->master); + + ret = mc13783_reg_rmw(led->master, reg, mask << shift, + value << shift); + + mc13783_unlock(led->master); + return ret; +} + +static int __devinit mc13783_leds_prepare(struct platform_device *pdev) +{ + struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); + struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent); + int ret = 0; + int reg = 0; + + mc13783_lock(dev); + + if (pdata->flags & MC13783_LED_TC1HALF) + reg |= MC13783_LED_C1_TC1HALF_BIT; + + if (pdata->flags & MC13783_LED_SLEWLIMTC) + reg |= MC13783_LED_Cx_SLEWLIM_BIT; + + ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_1, reg); + if (ret) + goto out; + + reg = (pdata->bl_period & MC13783_LED_Cx_PERIOD_MASK) << + MC13783_LED_Cx_PERIOD; + + if (pdata->flags & MC13783_LED_SLEWLIMBL) + reg |= MC13783_LED_Cx_SLEWLIM_BIT; + + ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_2, reg); + if (ret) + goto out; + + reg = (pdata->tc1_period & MC13783_LED_Cx_PERIOD_MASK) << + MC13783_LED_Cx_PERIOD; + + if (pdata->flags & MC13783_LED_TRIODE_TC1) + reg |= MC13783_LED_Cx_TRIODE_TC_BIT; + + ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_3, reg); + if (ret) + goto out; + + reg = (pdata->tc2_period & MC13783_LED_Cx_PERIOD_MASK) << + MC13783_LED_Cx_PERIOD; + + if (pdata->flags & MC13783_LED_TRIODE_TC2) + reg |= MC13783_LED_Cx_TRIODE_TC_BIT; + + ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_4, reg); + if (ret) + goto out; + + reg = (pdata->tc3_period & MC13783_LED_Cx_PERIOD_MASK) << + MC13783_LED_Cx_PERIOD; + + if (pdata->flags & MC13783_LED_TRIODE_TC3) + reg |= MC13783_LED_Cx_TRIODE_TC_BIT;; + + ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_5, reg); + if (ret) + goto out; + + reg = MC13783_LED_C0_ENABLE_BIT; + if (pdata->flags & MC13783_LED_TRIODE_MD) + reg |= MC13783_LED_C0_TRIODE_MD_BIT; + if (pdata->flags & MC13783_LED_TRIODE_AD) + reg |= MC13783_LED_C0_TRIODE_AD_BIT; + if (pdata->flags & MC13783_LED_TRIODE_KP) + reg |= MC13783_LED_C0_TRIODE_KP_BIT; + if (pdata->flags & MC13783_LED_BOOST_EN) + reg |= MC13783_LED_C0_BOOST_BIT; + + reg |= (pdata->abmode & MC13783_LED_C0_ABMODE_MASK) << + MC13783_LED_C0_ABMODE; + reg |= (pdata->abref & MC13783_LED_C0_ABREF_MASK) << + MC13783_LED_C0_ABREF; + + ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_0, reg); + +out: + mc13783_unlock(dev); + return ret; +} + +static int __devinit mc13783_led_probe(struct platform_device *pdev) +{ + struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); + struct mc13783_led_platform_data *led_cur; + struct mc13783_led *led, *led_dat; + int ret, i; + int init_led = 0; + + if (pdata == NULL) { + dev_err(&pdev->dev, "missing platform data\n"); + return -ENODEV; + } + + if (pdata->num_leds < 1 || pdata->num_leds > MC13783_LED_MAX) { + dev_err(&pdev->dev, "Invalid led count %d\n", pdata->num_leds); + return -EINVAL; + } + + led = kzalloc(sizeof(*led) * pdata->num_leds, GFP_KERNEL); + if (led == NULL) { + dev_err(&pdev->dev, "failed to alloc memory\n"); + return -ENOMEM; + } + + ret = mc13783_leds_prepare(pdev); + if (ret) { + dev_err(&pdev->dev, "unable to init led driver\n"); + goto err_free; + } + + for (i = 0; i < pdata->num_leds; i++) { + led_dat = &led[i]; + led_cur = &pdata->led[i]; + + if (led_cur->id > MC13783_LED_MAX || led_cur->id < 0) { + dev_err(&pdev->dev, "invalid id %d\n", led_cur->id); + ret = -EINVAL; + goto err_register; + } + + if (init_led & (1 << led_cur->id)) { + dev_err(&pdev->dev, "led %d already initialized\n", + led_cur->id); + ret = -EINVAL; + goto err_register; + } + + init_led |= 1 << led_cur->id; + led_dat->cdev.name = led_cur->name; + led_dat->cdev.default_trigger = led_cur->default_trigger; + led_dat->cdev.brightness_set = mc13783_led_set; + led_dat->cdev.brightness = LED_OFF; + led_dat->id = led_cur->id; + led_dat->master = dev_get_drvdata(pdev->dev.parent); + + INIT_WORK(&led_dat->work, mc13783_led_work); + + ret = led_classdev_register(pdev->dev.parent, &led_dat->cdev); + if (ret) { + dev_err(&pdev->dev, "failed to register led %d\n", + led_dat->id); + goto err_register; + } + + ret = mc13783_led_setup(led_dat, led_cur->max_current); + if (ret) { + dev_err(&pdev->dev, "unable to init led %d\n", + led_dat->id); + i++; + goto err_register; + } + } + + platform_set_drvdata(pdev, led); + return 0; + +err_register: + for (i = i - 1; i >= 0; i--) { + led_classdev_unregister(&led[i].cdev); + cancel_work_sync(&led[i].work); + } + +err_free: + kfree(led); + return ret; +} + +static int __devexit mc13783_led_remove(struct platform_device *pdev) +{ + struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); + struct mc13783_led *led = platform_get_drvdata(pdev); + struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent); + int i; + + for (i = 0; i < pdata->num_leds; i++) { + led_classdev_unregister(&led[i].cdev); + cancel_work_sync(&led[i].work); + } + + mc13783_lock(dev); + + mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_0, 0); + mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_1, 0); + mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_2, 0); + mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_3, 0); + mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_4, 0); + mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_5, 0); + + mc13783_unlock(dev); + + kfree(led); + return 0; +} + +static struct platform_driver mc13783_led_driver = { + .driver = { + .name = "mc13783-led", + .owner = THIS_MODULE, + }, + .probe = mc13783_led_probe, + .remove = __devexit_p(mc13783_led_remove), +}; + +static int __init mc13783_led_init(void) +{ + return platform_driver_register(&mc13783_led_driver); +} +module_init(mc13783_led_init); + +static void __exit mc13783_led_exit(void) +{ + platform_driver_unregister(&mc13783_led_driver); +} +module_exit(mc13783_led_exit); + +MODULE_DESCRIPTION("LEDs driver for Freescale MC13783 PMIC"); +MODULE_AUTHOR("Philippe Retornaz "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:mc13783-led"); diff --git a/drivers/mfd/mc13783-core.c b/drivers/mfd/mc13783-core.c index 1f68ecadddc2..fecf38a4f025 100644 --- a/drivers/mfd/mc13783-core.c +++ b/drivers/mfd/mc13783-core.c @@ -679,6 +679,10 @@ err_revision: if (pdata->flags & MC13783_USE_TOUCHSCREEN) mc13783_add_subdevice(mc13783, "mc13783-ts"); + if (pdata->flags & MC13783_USE_LED) + mc13783_add_subdevice_pdata(mc13783, "mc13783-led", + pdata->leds, sizeof(*pdata->leds)); + return 0; } diff --git a/include/linux/mfd/mc13783.h b/include/linux/mfd/mc13783.h index 8895d9d8879c..4a894f688549 100644 --- a/include/linux/mfd/mc13783.h +++ b/include/linux/mfd/mc13783.h @@ -64,6 +64,70 @@ static inline int mc13783_ackirq(struct mc13783 *mc13783, int irq) MC13783_ADC0_TSMOD1 | \ MC13783_ADC0_TSMOD2) +struct mc13783_led_platform_data { +#define MC13783_LED_MD 0 +#define MC13783_LED_AD 1 +#define MC13783_LED_KP 2 +#define MC13783_LED_R1 3 +#define MC13783_LED_G1 4 +#define MC13783_LED_B1 5 +#define MC13783_LED_R2 6 +#define MC13783_LED_G2 7 +#define MC13783_LED_B2 8 +#define MC13783_LED_R3 9 +#define MC13783_LED_G3 10 +#define MC13783_LED_B3 11 +#define MC13783_LED_MAX MC13783_LED_B3 + int id; + const char *name; + const char *default_trigger; + +/* Three or two bits current selection depending on the led */ + char max_current; +}; + +struct mc13783_leds_platform_data { + int num_leds; + struct mc13783_led_platform_data *led; + +#define MC13783_LED_TRIODE_MD (1 << 0) +#define MC13783_LED_TRIODE_AD (1 << 1) +#define MC13783_LED_TRIODE_KP (1 << 2) +#define MC13783_LED_BOOST_EN (1 << 3) +#define MC13783_LED_TC1HALF (1 << 4) +#define MC13783_LED_SLEWLIMTC (1 << 5) +#define MC13783_LED_SLEWLIMBL (1 << 6) +#define MC13783_LED_TRIODE_TC1 (1 << 7) +#define MC13783_LED_TRIODE_TC2 (1 << 8) +#define MC13783_LED_TRIODE_TC3 (1 << 9) + int flags; + +#define MC13783_LED_AB_DISABLED 0 +#define MC13783_LED_AB_MD1 1 +#define MC13783_LED_AB_MD12 2 +#define MC13783_LED_AB_MD123 3 +#define MC13783_LED_AB_MD1234 4 +#define MC13783_LED_AB_MD1234_AD1 5 +#define MC13783_LED_AB_MD1234_AD12 6 +#define MC13783_LED_AB_MD1_AD 7 + char abmode; + +#define MC13783_LED_ABREF_200MV 0 +#define MC13783_LED_ABREF_400MV 1 +#define MC13783_LED_ABREF_600MV 2 +#define MC13783_LED_ABREF_800MV 3 + char abref; + +#define MC13783_LED_PERIOD_10MS 0 +#define MC13783_LED_PERIOD_100MS 1 +#define MC13783_LED_PERIOD_500MS 2 +#define MC13783_LED_PERIOD_2S 3 + char bl_period; + char tc1_period; + char tc2_period; + char tc3_period; +}; + /* to be cleaned up */ struct regulator_init_data; @@ -80,12 +144,14 @@ struct mc13783_regulator_platform_data { struct mc13783_platform_data { int num_regulators; struct mc13783_regulator_init_data *regulators; + struct mc13783_leds_platform_data *leds; #define MC13783_USE_TOUCHSCREEN (1 << 0) #define MC13783_USE_CODEC (1 << 1) #define MC13783_USE_ADC (1 << 2) #define MC13783_USE_RTC (1 << 3) #define MC13783_USE_REGULATOR (1 << 4) +#define MC13783_USE_LED (1 << 5) unsigned int flags; }; -- cgit v1.2.3 From 3e4a326df654d748d73600068fbdbdfed0b0db43 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 22 Mar 2010 20:51:36 -0400 Subject: backlight: backlight_device_register() return ERR_PTR() backlight_device_register() returns a valid pointer or ERR_PTR() never NULL. Signed-off-by: Dan Carpenter Signed-off-by: Andrew Morton Signed-off-by: Richard Purdie --- drivers/video/backlight/adx_bl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/adx_bl.c b/drivers/video/backlight/adx_bl.c index 7f4a7c30a98b..fe9af129c5dd 100644 --- a/drivers/video/backlight/adx_bl.c +++ b/drivers/video/backlight/adx_bl.c @@ -107,8 +107,8 @@ static int __devinit adx_backlight_probe(struct platform_device *pdev) props.max_brightness = 0xff; bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, bl, &adx_backlight_ops, &props); - if (!bldev) { - ret = -ENOMEM; + if (IS_ERR(bldev)) { + ret = PTR_ERR(bldev); goto out; } -- cgit v1.2.3 From 8fdd5767ebe5806f02e1c8d9ac67ac4da8836f53 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Mar 2010 13:17:35 -0500 Subject: backlight: Kconfig cleanup Cleanup the "depends on" logic by wrapping the affected config options in appropriate if/endif blocks. Remove all the "default n" since that is the default default. Signed-off-by: H Hartley Sweeten Signed-off-by: Richard Purdie --- drivers/video/backlight/Kconfig | 79 ++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index c025c84601b0..4dfb5f44dffd 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -8,12 +8,13 @@ menuconfig BACKLIGHT_LCD_SUPPORT Enable this to be able to choose the drivers for controlling the backlight and the LCD panel on some platforms, for example on PDAs. +if BACKLIGHT_LCD_SUPPORT + # # LCD # config LCD_CLASS_DEVICE tristate "Lowlevel LCD controls" - depends on BACKLIGHT_LCD_SUPPORT default m help This framework adds support for low-level control of LCD. @@ -24,31 +25,32 @@ config LCD_CLASS_DEVICE To have support for your specific LCD panel you will have to select the proper drivers which depend on this option. +if LCD_CLASS_DEVICE + config LCD_CORGI tristate "LCD Panel support for SHARP corgi/spitz model" - depends on LCD_CLASS_DEVICE && SPI_MASTER && PXA_SHARPSL + depends on SPI_MASTER && PXA_SHARPSL help Say y here to support the LCD panels usually found on SHARP corgi (C7x0) and spitz (Cxx00) models. config LCD_L4F00242T03 tristate "Epson L4F00242T03 LCD" - depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO + depends on SPI_MASTER && GENERIC_GPIO help SPI driver for Epson L4F00242T03. This provides basic support for init and powering the LCD up/down through a sysfs interface. config LCD_LMS283GF05 tristate "Samsung LMS283GF05 LCD" - depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO + depends on SPI_MASTER && GENERIC_GPIO help SPI driver for Samsung LMS283GF05. This provides basic support for powering the LCD up/down through a sysfs interface. config LCD_LTV350QV tristate "Samsung LTV350QV LCD Panel" - depends on LCD_CLASS_DEVICE && SPI_MASTER - default n + depends on SPI_MASTER help If you have a Samsung LTV350QV LCD panel, say y to include a power control driver for it. The panel starts up in power @@ -59,60 +61,53 @@ config LCD_LTV350QV config LCD_ILI9320 tristate - depends on LCD_CLASS_DEVICE && BACKLIGHT_LCD_SUPPORT - default n help If you have a panel based on the ILI9320 controller chip then say y to include a power driver for it. config LCD_TDO24M tristate "Toppoly TDO24M and TDO35S LCD Panels support" - depends on LCD_CLASS_DEVICE && SPI_MASTER - default n + depends on SPI_MASTER help If you have a Toppoly TDO24M/TDO35S series LCD panel, say y here to include the support for it. config LCD_VGG2432A4 tristate "VGG2432A4 LCM device support" - depends on BACKLIGHT_LCD_SUPPORT && LCD_CLASS_DEVICE && SPI_MASTER + depends on SPI_MASTER select LCD_ILI9320 - default n help If you have a VGG2432A4 panel based on the ILI9320 controller chip then say y to include a power driver for it. config LCD_PLATFORM tristate "Platform LCD controls" - depends on LCD_CLASS_DEVICE help This driver provides a platform-device registered LCD power control interface. config LCD_TOSA tristate "Sharp SL-6000 LCD Driver" - depends on LCD_CLASS_DEVICE && SPI - depends on MACH_TOSA - default n + depends on SPI && MACH_TOSA help If you have an Sharp SL-6000 Zaurus say Y to enable a driver for its LCD. config LCD_HP700 tristate "HP Jornada 700 series LCD Driver" - depends on LCD_CLASS_DEVICE depends on SA1100_JORNADA720_SSP && !PREEMPT default y help If you have an HP Jornada 700 series handheld (710/720/728) say Y to enable LCD control driver. +endif # LCD_CLASS_DEVICE + # # Backlight # config BACKLIGHT_CLASS_DEVICE tristate "Lowlevel Backlight controls" - depends on BACKLIGHT_LCD_SUPPORT default m help This framework adds support for low-level control of the LCD @@ -121,9 +116,11 @@ config BACKLIGHT_CLASS_DEVICE To have support for your specific LCD panel you will have to select the proper drivers which depend on this option. +if BACKLIGHT_CLASS_DEVICE + config BACKLIGHT_ATMEL_LCDC bool "Atmel LCDC Contrast-as-Backlight control" - depends on BACKLIGHT_CLASS_DEVICE && FB_ATMEL + depends on FB_ATMEL default y if MACH_SAM9261EK || MACH_SAM9G10EK || MACH_SAM9263EK help This provides a backlight control internal to the Atmel LCDC @@ -136,8 +133,7 @@ config BACKLIGHT_ATMEL_LCDC config BACKLIGHT_ATMEL_PWM tristate "Atmel PWM backlight control" - depends on BACKLIGHT_CLASS_DEVICE && ATMEL_PWM - default n + depends on ATMEL_PWM help Say Y here if you want to use the PWM peripheral in Atmel AT91 and AVR32 devices. This driver will need additional platform data to know @@ -148,7 +144,6 @@ config BACKLIGHT_ATMEL_PWM config BACKLIGHT_GENERIC tristate "Generic (aka Sharp Corgi) Backlight Driver" - depends on BACKLIGHT_CLASS_DEVICE default y help Say y to enable the generic platform backlight driver previously @@ -157,7 +152,7 @@ config BACKLIGHT_GENERIC config BACKLIGHT_LOCOMO tristate "Sharp LOCOMO LCD/Backlight Driver" - depends on BACKLIGHT_CLASS_DEVICE && SHARP_LOCOMO + depends on SHARP_LOCOMO default y help If you have a Sharp Zaurus SL-5500 (Collie) or SL-5600 (Poodle) say y to @@ -165,7 +160,7 @@ config BACKLIGHT_LOCOMO config BACKLIGHT_OMAP1 tristate "OMAP1 PWL-based LCD Backlight" - depends on BACKLIGHT_CLASS_DEVICE && ARCH_OMAP1 + depends on ARCH_OMAP1 default y help This driver controls the LCD backlight level and power for @@ -174,7 +169,7 @@ config BACKLIGHT_OMAP1 config BACKLIGHT_HP680 tristate "HP Jornada 680 Backlight Driver" - depends on BACKLIGHT_CLASS_DEVICE && SH_HP6XX + depends on SH_HP6XX default y help If you have a HP Jornada 680, say y to enable the @@ -182,7 +177,6 @@ config BACKLIGHT_HP680 config BACKLIGHT_HP700 tristate "HP Jornada 700 series Backlight Driver" - depends on BACKLIGHT_CLASS_DEVICE depends on SA1100_JORNADA720_SSP && !PREEMPT default y help @@ -191,76 +185,70 @@ config BACKLIGHT_HP700 config BACKLIGHT_PROGEAR tristate "Frontpath ProGear Backlight Driver" - depends on BACKLIGHT_CLASS_DEVICE && PCI && X86 - default n + depends on PCI && X86 help If you have a Frontpath ProGear say Y to enable the backlight driver. config BACKLIGHT_CARILLO_RANCH tristate "Intel Carillo Ranch Backlight Driver" - depends on BACKLIGHT_CLASS_DEVICE && LCD_CLASS_DEVICE && PCI && X86 && FB_LE80578 - default n + depends on LCD_CLASS_DEVICE && PCI && X86 && FB_LE80578 help If you have a Intel LE80578 (Carillo Ranch) say Y to enable the backlight driver. config BACKLIGHT_PWM tristate "Generic PWM based Backlight Driver" - depends on BACKLIGHT_CLASS_DEVICE && HAVE_PWM + depends on HAVE_PWM help If you have a LCD backlight adjustable by PWM, say Y to enable this driver. config BACKLIGHT_DA903X tristate "Backlight Driver for DA9030/DA9034 using WLED" - depends on BACKLIGHT_CLASS_DEVICE && PMIC_DA903X + depends on PMIC_DA903X help If you have a LCD backlight connected to the WLED output of DA9030 or DA9034 WLED output, say Y here to enable this driver. config BACKLIGHT_MAX8925 tristate "Backlight driver for MAX8925" - depends on BACKLIGHT_CLASS_DEVICE && MFD_MAX8925 + depends on MFD_MAX8925 help If you have a LCD backlight connected to the WLED output of MAX8925 WLED output, say Y here to enable this driver. config BACKLIGHT_MBP_NVIDIA tristate "MacBook Pro Nvidia Backlight Driver" - depends on BACKLIGHT_CLASS_DEVICE && X86 - default n + depends on X86 help If you have an Apple Macbook Pro with Nvidia graphics hardware say Y to enable a driver for its backlight config BACKLIGHT_TOSA tristate "Sharp SL-6000 Backlight Driver" - depends on BACKLIGHT_CLASS_DEVICE && I2C - depends on MACH_TOSA && LCD_TOSA - default n + depends on I2C && MACH_TOSA && LCD_TOSA help If you have an Sharp SL-6000 Zaurus say Y to enable a driver for its backlight config BACKLIGHT_SAHARA tristate "Tabletkiosk Sahara Touch-iT Backlight Driver" - depends on BACKLIGHT_CLASS_DEVICE && X86 - default n + depends on X86 help If you have a Tabletkiosk Sahara Touch-iT, say y to enable the backlight driver. config BACKLIGHT_WM831X tristate "WM831x PMIC Backlight Driver" - depends on BACKLIGHT_CLASS_DEVICE && MFD_WM831X + depends on MFD_WM831X help If you have a backlight driven by the ISINK and DCDC of a WM831x PMIC say y to enable the backlight driver for it. config BACKLIGHT_ADX tristate "Avionic Design Xanthos Backlight Driver" - depends on BACKLIGHT_CLASS_DEVICE && ARCH_PXA_ADX + depends on ARCH_PXA_ADX default y help Say Y to enable the backlight driver on Avionic Design Xanthos-based @@ -268,7 +256,7 @@ config BACKLIGHT_ADX config BACKLIGHT_ADP5520 tristate "Backlight Driver for ADP5520/ADP5501 using WLED" - depends on BACKLIGHT_CLASS_DEVICE && PMIC_ADP5520 + depends on PMIC_ADP5520 help If you have a LCD backlight connected to the BST/BL_SNK output of ADP5520 or ADP5501, say Y here to enable this driver. @@ -278,7 +266,10 @@ config BACKLIGHT_ADP5520 config BACKLIGHT_88PM860X tristate "Backlight Driver for 88PM8606 using WLED" - depends on BACKLIGHT_CLASS_DEVICE && MFD_88PM860X + depends on MFD_88PM860X help Say Y to enable the backlight driver for Marvell 88PM8606. +endif # BACKLIGHT_CLASS_DEVICE + +endif # BACKLIGHT_LCD_SUPPORT -- cgit v1.2.3 From 8193db229101fa5e7e7070422a7471775140e7bd Mon Sep 17 00:00:00 2001 From: Mario Schwalbe Date: Mon, 19 Apr 2010 17:59:26 +0100 Subject: backlight: mbp_nvidia_bl - add support for older MacBookPro and MacBook 6,1. Add support for all remaining models not yet present in Linus'/Richard Purdie's tree nor Evan McClain's patch to finally complete the list. Signed-off-by: Mario Schwalbe Signed-off-by: Andrew Morton Signed-off-by: Richard Purdie --- drivers/video/backlight/mbp_nvidia_bl.c | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'drivers') diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c index 1b5d3fe6bbbc..52c780f5db1b 100644 --- a/drivers/video/backlight/mbp_nvidia_bl.c +++ b/drivers/video/backlight/mbp_nvidia_bl.c @@ -182,6 +182,42 @@ static const struct dmi_system_id __initdata mbp_device_table[] = { }, .driver_data = (void *)&intel_chipset_data, }, + { + .callback = mbp_dmi_match, + .ident = "MacBookPro 1,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro1,1"), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident = "MacBookPro 1,2", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro1,2"), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident = "MacBookPro 2,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,1"), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident = "MacBookPro 2,2", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2"), + }, + .driver_data = (void *)&intel_chipset_data, + }, { .callback = mbp_dmi_match, .ident = "MacBookPro 3,1", @@ -236,6 +272,15 @@ static const struct dmi_system_id __initdata mbp_device_table[] = { }, .driver_data = (void *)&nvidia_chipset_data, }, + { + .callback = mbp_dmi_match, + .ident = "MacBook 6,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook6,1"), + }, + .driver_data = (void *)&nvidia_chipset_data, + }, { .callback = mbp_dmi_match, .ident = "MacBookAir 2,1", -- cgit v1.2.3 From 9844ce0501b03843c44156d6e36afb80e847c974 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 7 May 2010 11:06:21 +0200 Subject: backlight: 88pm860x_bl - potential memory leak I added a kfree() on the error path. I don't really expect it to affect anyone, but it's easy and makes the static checkers happy. Signed-off-by: Dan Carpenter Signed-off-by: Richard Purdie --- drivers/video/backlight/88pm860x_bl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c index 68d2518fadaa..78d8fde9fe8f 100644 --- a/drivers/video/backlight/88pm860x_bl.c +++ b/drivers/video/backlight/88pm860x_bl.c @@ -222,6 +222,7 @@ static int pm860x_backlight_probe(struct platform_device *pdev) data->port = __check_device(pdata, name); if (data->port < 0) { dev_err(&pdev->dev, "wrong platform data is assigned"); + kfree(data); return -EINVAL; } -- cgit v1.2.3 From 82fd53b7f70af9855eda613450a7e4701ffdae20 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 30 Apr 2010 14:09:51 -0700 Subject: backlight: new driver for the ADP8860 backlight parts The ADP8860 combines a programmable backlight LED charge pump driver with automatic phototransistor control. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger Signed-off-by: Andrew Morton Signed-off-by: Richard Purdie --- drivers/video/backlight/Kconfig | 12 + drivers/video/backlight/Makefile | 1 + drivers/video/backlight/adp8860_bl.c | 809 +++++++++++++++++++++++++++++++++++ include/linux/i2c/adp8860.h | 137 ++++++ 4 files changed, 959 insertions(+) create mode 100644 drivers/video/backlight/adp8860_bl.c create mode 100644 include/linux/i2c/adp8860.h (limited to 'drivers') diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 4dfb5f44dffd..0f7e795f27f8 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -264,6 +264,18 @@ config BACKLIGHT_ADP5520 To compile this driver as a module, choose M here: the module will be called adp5520_bl. +config BACKLIGHT_ADP8860 + tristate "Backlight Driver for ADP8860 using WLED" + depends on BACKLIGHT_CLASS_DEVICE && I2C + select NEW_LEDS + select LEDS_CLASS + help + If you have a LCD backlight connected to the ADP8860, + say Y here to enable this driver. + + To compile this driver as a module, choose M here: the module will + be called adp8860_bl. + config BACKLIGHT_88PM860X tristate "Backlight Driver for 88PM8606 using WLED" depends on MFD_88PM860X diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 09d1f14d6257..3cbaacae8f9c 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -30,5 +30,6 @@ obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o obj-$(CONFIG_BACKLIGHT_ADX) += adx_bl.o obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o +obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c new file mode 100644 index 000000000000..3c449d2f68b9 --- /dev/null +++ b/drivers/video/backlight/adp8860_bl.c @@ -0,0 +1,809 @@ +/* + * Backlight driver for Analog Devices ADP8860 Backlight Devices + * + * Copyright 2009-2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#define ADP8860_EXT_FEATURES +#define ADP8860_USE_LEDS + +#define ADP8860_MFDVID 0x00 /* Manufacturer and device ID */ +#define ADP8860_MDCR 0x01 /* Device mode and status */ +#define ADP8860_MDCR2 0x02 /* Device mode and Status Register 2 */ +#define ADP8860_INTR_EN 0x03 /* Interrupts enable */ +#define ADP8860_CFGR 0x04 /* Configuration register */ +#define ADP8860_BLSEN 0x05 /* Sink enable backlight or independent */ +#define ADP8860_BLOFF 0x06 /* Backlight off timeout */ +#define ADP8860_BLDIM 0x07 /* Backlight dim timeout */ +#define ADP8860_BLFR 0x08 /* Backlight fade in and out rates */ +#define ADP8860_BLMX1 0x09 /* Backlight (Brightness Level 1-daylight) maximum current */ +#define ADP8860_BLDM1 0x0A /* Backlight (Brightness Level 1-daylight) dim current */ +#define ADP8860_BLMX2 0x0B /* Backlight (Brightness Level 2-office) maximum current */ +#define ADP8860_BLDM2 0x0C /* Backlight (Brightness Level 2-office) dim current */ +#define ADP8860_BLMX3 0x0D /* Backlight (Brightness Level 3-dark) maximum current */ +#define ADP8860_BLDM3 0x0E /* Backlight (Brightness Level 3-dark) dim current */ +#define ADP8860_ISCFR 0x0F /* Independent sink current fade control register */ +#define ADP8860_ISCC 0x10 /* Independent sink current control register */ +#define ADP8860_ISCT1 0x11 /* Independent Sink Current Timer Register LED[7:5] */ +#define ADP8860_ISCT2 0x12 /* Independent Sink Current Timer Register LED[4:1] */ +#define ADP8860_ISCF 0x13 /* Independent sink current fade register */ +#define ADP8860_ISC7 0x14 /* Independent Sink Current LED7 */ +#define ADP8860_ISC6 0x15 /* Independent Sink Current LED6 */ +#define ADP8860_ISC5 0x16 /* Independent Sink Current LED5 */ +#define ADP8860_ISC4 0x17 /* Independent Sink Current LED4 */ +#define ADP8860_ISC3 0x18 /* Independent Sink Current LED3 */ +#define ADP8860_ISC2 0x19 /* Independent Sink Current LED2 */ +#define ADP8860_ISC1 0x1A /* Independent Sink Current LED1 */ +#define ADP8860_CCFG 0x1B /* Comparator configuration */ +#define ADP8860_CCFG2 0x1C /* Second comparator configuration */ +#define ADP8860_L2_TRP 0x1D /* L2 comparator reference */ +#define ADP8860_L2_HYS 0x1E /* L2 hysteresis */ +#define ADP8860_L3_TRP 0x1F /* L3 comparator reference */ +#define ADP8860_L3_HYS 0x20 /* L3 hysteresis */ +#define ADP8860_PH1LEVL 0x21 /* First phototransistor ambient light level-low byte register */ +#define ADP8860_PH1LEVH 0x22 /* First phototransistor ambient light level-high byte register */ +#define ADP8860_PH2LEVL 0x23 /* Second phototransistor ambient light level-low byte register */ +#define ADP8860_PH2LEVH 0x24 /* Second phototransistor ambient light level-high byte register */ + +#define ADP8860_MANUFID 0x0 /* Analog Devices ADP8860 Manufacturer ID */ +#define ADP8860_DEVICEID 0x7 /* Analog Devices ADP8860 Device ID */ +#define ADP8860_DEVID(x) ((x) & 0xF) +#define ADP8860_MANID(x) ((x) >> 4) + +/* MDCR Device mode and status */ +#define INT_CFG (1 << 6) +#define NSTBY (1 << 5) +#define DIM_EN (1 << 4) +#define SIS_EN (1 << 2) +#define CMP_AUTOEN (1 << 1) +#define BLEN (1 << 0) + +/* ADP8860_CCFG Main ALS comparator level enable */ +#define L3_EN (1 << 1) +#define L2_EN (1 << 0) + +#define CFGR_BLV_SHIFT 3 +#define CFGR_BLV_MASK 0x3 +#define ADP8860_FLAG_LED_MASK 0xFF + +#define FADE_VAL(in, out) ((0xF & (in)) | ((0xF & (out)) << 4)) +#define BL_CFGR_VAL(law, blv) ((((blv) & CFGR_BLV_MASK) << CFGR_BLV_SHIFT) | ((0x3 & (law)) << 1)) +#define ALS_CCFG_VAL(filt) ((0x7 & filt) << 5) + +struct adp8860_led { + struct led_classdev cdev; + struct work_struct work; + struct i2c_client *client; + enum led_brightness new_brightness; + int id; + int flags; +}; + +struct adp8860_bl { + struct i2c_client *client; + struct backlight_device *bl; + struct adp8860_led *led; + struct adp8860_backlight_platform_data *pdata; + struct mutex lock; + unsigned long cached_daylight_max; + int id; + int revid; + int current_brightness; +}; + +static int adp8860_read(struct i2c_client *client, int reg, uint8_t *val) +{ + int ret; + + ret = i2c_smbus_read_byte_data(client, reg); + if (ret < 0) { + dev_err(&client->dev, "failed reading at 0x%02x\n", reg); + return ret; + } + + *val = (uint8_t)ret; + return 0; +} + + +static int adp8860_write(struct i2c_client *client, u8 reg, u8 val) +{ + return i2c_smbus_write_byte_data(client, reg, val); +} + +static int adp8860_set_bits(struct i2c_client *client, int reg, uint8_t bit_mask) +{ + struct adp8860_bl *data = i2c_get_clientdata(client); + uint8_t reg_val; + int ret; + + mutex_lock(&data->lock); + + ret = adp8860_read(client, reg, ®_val); + + if (!ret && ((reg_val & bit_mask) == 0)) { + reg_val |= bit_mask; + ret = adp8860_write(client, reg, reg_val); + } + + mutex_unlock(&data->lock); + return ret; +} + +static int adp8860_clr_bits(struct i2c_client *client, int reg, uint8_t bit_mask) +{ + struct adp8860_bl *data = i2c_get_clientdata(client); + uint8_t reg_val; + int ret; + + mutex_lock(&data->lock); + + ret = adp8860_read(client, reg, ®_val); + + if (!ret && (reg_val & bit_mask)) { + reg_val &= ~bit_mask; + ret = adp8860_write(client, reg, reg_val); + } + + mutex_unlock(&data->lock); + return ret; +} + +/* + * Independent sink / LED + */ +#if defined(ADP8860_USE_LEDS) +static void adp8860_led_work(struct work_struct *work) +{ + struct adp8860_led *led = container_of(work, struct adp8860_led, work); + adp8860_write(led->client, ADP8860_ISC1 - led->id + 1, + led->new_brightness >> 1); +} + +static void adp8860_led_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct adp8860_led *led; + + led = container_of(led_cdev, struct adp8860_led, cdev); + led->new_brightness = value; + schedule_work(&led->work); +} + +static int adp8860_led_setup(struct adp8860_led *led) +{ + struct i2c_client *client = led->client; + int ret = 0; + + ret = adp8860_write(client, ADP8860_ISC1 - led->id + 1, 0); + ret |= adp8860_set_bits(client, ADP8860_ISCC, 1 << (led->id - 1)); + + if (led->id > 4) + ret |= adp8860_set_bits(client, ADP8860_ISCT1, + (led->flags & 0x3) << ((led->id - 5) * 2)); + else + ret |= adp8860_set_bits(client, ADP8860_ISCT2, + (led->flags & 0x3) << ((led->id - 1) * 2)); + + return ret; +} + +static int __devinit adp8860_led_probe(struct i2c_client *client) +{ + struct adp8860_backlight_platform_data *pdata = + client->dev.platform_data; + struct adp8860_bl *data = i2c_get_clientdata(client); + struct adp8860_led *led, *led_dat; + struct led_info *cur_led; + int ret, i; + + led = kzalloc(sizeof(*led) * pdata->num_leds, GFP_KERNEL); + if (led == NULL) { + dev_err(&client->dev, "failed to alloc memory\n"); + return -ENOMEM; + } + + ret = adp8860_write(client, ADP8860_ISCFR, pdata->led_fade_law); + ret = adp8860_write(client, ADP8860_ISCT1, + (pdata->led_on_time & 0x3) << 6); + ret |= adp8860_write(client, ADP8860_ISCF, + FADE_VAL(pdata->led_fade_in, pdata->led_fade_out)); + + if (ret) { + dev_err(&client->dev, "failed to write\n"); + goto err_free; + } + + for (i = 0; i < pdata->num_leds; ++i) { + cur_led = &pdata->leds[i]; + led_dat = &led[i]; + + led_dat->id = cur_led->flags & ADP8860_FLAG_LED_MASK; + + if (led_dat->id > 7 || led_dat->id < 1) { + dev_err(&client->dev, "Invalid LED ID %d\n", + led_dat->id); + goto err; + } + + if (pdata->bl_led_assign & (1 << (led_dat->id - 1))) { + dev_err(&client->dev, "LED %d used by Backlight\n", + led_dat->id); + goto err; + } + + led_dat->cdev.name = cur_led->name; + led_dat->cdev.default_trigger = cur_led->default_trigger; + led_dat->cdev.brightness_set = adp8860_led_set; + led_dat->cdev.brightness = LED_OFF; + led_dat->flags = cur_led->flags >> FLAG_OFFT_SHIFT; + led_dat->client = client; + led_dat->new_brightness = LED_OFF; + INIT_WORK(&led_dat->work, adp8860_led_work); + + ret = led_classdev_register(&client->dev, &led_dat->cdev); + if (ret) { + dev_err(&client->dev, "failed to register LED %d\n", + led_dat->id); + goto err; + } + + ret = adp8860_led_setup(led_dat); + if (ret) { + dev_err(&client->dev, "failed to write\n"); + i++; + goto err; + } + } + + data->led = led; + + return 0; + + err: + for (i = i - 1; i >= 0; --i) { + led_classdev_unregister(&led[i].cdev); + cancel_work_sync(&led[i].work); + } + + err_free: + kfree(led); + + return ret; +} + +static int __devexit adp8860_led_remove(struct i2c_client *client) +{ + struct adp8860_backlight_platform_data *pdata = + client->dev.platform_data; + struct adp8860_bl *data = i2c_get_clientdata(client); + int i; + + for (i = 0; i < pdata->num_leds; i++) { + led_classdev_unregister(&data->led[i].cdev); + cancel_work_sync(&data->led[i].work); + } + + kfree(data->led); + return 0; +} +#else +static int __devinit adp8860_led_probe(struct i2c_client *client) +{ + return 0; +} + +static int __devexit adp8860_led_remove(struct i2c_client *client) +{ + return 0; +} +#endif + +static int adp8860_bl_set(struct backlight_device *bl, int brightness) +{ + struct adp8860_bl *data = bl_get_data(bl); + struct i2c_client *client = data->client; + int ret = 0; + + if (data->pdata->en_ambl_sens) { + if ((brightness > 0) && (brightness < ADP8860_MAX_BRIGHTNESS)) { + /* Disable Ambient Light auto adjust */ + ret |= adp8860_clr_bits(client, ADP8860_MDCR, + CMP_AUTOEN); + ret |= adp8860_write(client, ADP8860_BLMX1, brightness); + } else { + /* + * MAX_BRIGHTNESS -> Enable Ambient Light auto adjust + * restore daylight l1 sysfs brightness + */ + ret |= adp8860_write(client, ADP8860_BLMX1, + data->cached_daylight_max); + ret |= adp8860_set_bits(client, ADP8860_MDCR, + CMP_AUTOEN); + } + } else + ret |= adp8860_write(client, ADP8860_BLMX1, brightness); + + if (data->current_brightness && brightness == 0) + ret |= adp8860_set_bits(client, + ADP8860_MDCR, DIM_EN); + else if (data->current_brightness == 0 && brightness) + ret |= adp8860_clr_bits(client, + ADP8860_MDCR, DIM_EN); + + if (!ret) + data->current_brightness = brightness; + + return ret; +} + +static int adp8860_bl_update_status(struct backlight_device *bl) +{ + int brightness = bl->props.brightness; + if (bl->props.power != FB_BLANK_UNBLANK) + brightness = 0; + + if (bl->props.fb_blank != FB_BLANK_UNBLANK) + brightness = 0; + + return adp8860_bl_set(bl, brightness); +} + +static int adp8860_bl_get_brightness(struct backlight_device *bl) +{ + struct adp8860_bl *data = bl_get_data(bl); + + return data->current_brightness; +} + +static const struct backlight_ops adp8860_bl_ops = { + .update_status = adp8860_bl_update_status, + .get_brightness = adp8860_bl_get_brightness, +}; + +static int adp8860_bl_setup(struct backlight_device *bl) +{ + struct adp8860_bl *data = bl_get_data(bl); + struct i2c_client *client = data->client; + struct adp8860_backlight_platform_data *pdata = data->pdata; + int ret = 0; + + ret |= adp8860_write(client, ADP8860_BLSEN, ~pdata->bl_led_assign); + ret |= adp8860_write(client, ADP8860_BLMX1, pdata->l1_daylight_max); + ret |= adp8860_write(client, ADP8860_BLDM1, pdata->l1_daylight_dim); + + if (pdata->en_ambl_sens) { + data->cached_daylight_max = pdata->l1_daylight_max; + ret |= adp8860_write(client, ADP8860_BLMX2, + pdata->l2_office_max); + ret |= adp8860_write(client, ADP8860_BLDM2, + pdata->l2_office_dim); + ret |= adp8860_write(client, ADP8860_BLMX3, + pdata->l3_dark_max); + ret |= adp8860_write(client, ADP8860_BLDM3, + pdata->l3_dark_dim); + + ret |= adp8860_write(client, ADP8860_L2_TRP, pdata->l2_trip); + ret |= adp8860_write(client, ADP8860_L2_HYS, pdata->l2_hyst); + ret |= adp8860_write(client, ADP8860_L3_TRP, pdata->l3_trip); + ret |= adp8860_write(client, ADP8860_L3_HYS, pdata->l3_hyst); + ret |= adp8860_write(client, ADP8860_CCFG, L2_EN | L3_EN | + ALS_CCFG_VAL(pdata->abml_filt)); + } + + ret |= adp8860_write(client, ADP8860_CFGR, + BL_CFGR_VAL(pdata->bl_fade_law, 0)); + + ret |= adp8860_write(client, ADP8860_BLFR, FADE_VAL(pdata->bl_fade_in, + pdata->bl_fade_out)); + + ret |= adp8860_set_bits(client, ADP8860_MDCR, BLEN | DIM_EN | NSTBY); + + return ret; +} + +static ssize_t adp8860_show(struct device *dev, char *buf, int reg) +{ + struct adp8860_bl *data = dev_get_drvdata(dev); + int error; + uint8_t reg_val; + + mutex_lock(&data->lock); + error = adp8860_read(data->client, reg, ®_val); + mutex_unlock(&data->lock); + + if (error < 0) + return error; + + return sprintf(buf, "%u\n", reg_val); +} + +static ssize_t adp8860_store(struct device *dev, const char *buf, + size_t count, int reg) +{ + struct adp8860_bl *data = dev_get_drvdata(dev); + unsigned long val; + int ret; + + ret = strict_strtoul(buf, 10, &val); + if (ret) + return ret; + + mutex_lock(&data->lock); + adp8860_write(data->client, reg, val); + mutex_unlock(&data->lock); + + return count; +} + +static ssize_t adp8860_bl_l3_dark_max_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return adp8860_show(dev, buf, ADP8860_BLMX3); +} + +static ssize_t adp8860_bl_l3_dark_max_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + return adp8860_store(dev, buf, count, ADP8860_BLMX3); +} + +static DEVICE_ATTR(l3_dark_max, 0664, adp8860_bl_l3_dark_max_show, + adp8860_bl_l3_dark_max_store); + +static ssize_t adp8860_bl_l2_office_max_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return adp8860_show(dev, buf, ADP8860_BLMX2); +} + +static ssize_t adp8860_bl_l2_office_max_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + return adp8860_store(dev, buf, count, ADP8860_BLMX2); +} +static DEVICE_ATTR(l2_office_max, 0664, adp8860_bl_l2_office_max_show, + adp8860_bl_l2_office_max_store); + +static ssize_t adp8860_bl_l1_daylight_max_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return adp8860_show(dev, buf, ADP8860_BLMX1); +} + +static ssize_t adp8860_bl_l1_daylight_max_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct adp8860_bl *data = dev_get_drvdata(dev); + + strict_strtoul(buf, 10, &data->cached_daylight_max); + return adp8860_store(dev, buf, count, ADP8860_BLMX1); +} +static DEVICE_ATTR(l1_daylight_max, 0664, adp8860_bl_l1_daylight_max_show, + adp8860_bl_l1_daylight_max_store); + +static ssize_t adp8860_bl_l3_dark_dim_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return adp8860_show(dev, buf, ADP8860_BLDM3); +} + +static ssize_t adp8860_bl_l3_dark_dim_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return adp8860_store(dev, buf, count, ADP8860_BLDM3); +} +static DEVICE_ATTR(l3_dark_dim, 0664, adp8860_bl_l3_dark_dim_show, + adp8860_bl_l3_dark_dim_store); + +static ssize_t adp8860_bl_l2_office_dim_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return adp8860_show(dev, buf, ADP8860_BLDM2); +} + +static ssize_t adp8860_bl_l2_office_dim_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return adp8860_store(dev, buf, count, ADP8860_BLDM2); +} +static DEVICE_ATTR(l2_office_dim, 0664, adp8860_bl_l2_office_dim_show, + adp8860_bl_l2_office_dim_store); + +static ssize_t adp8860_bl_l1_daylight_dim_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return adp8860_show(dev, buf, ADP8860_BLDM1); +} + +static ssize_t adp8860_bl_l1_daylight_dim_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return adp8860_store(dev, buf, count, ADP8860_BLDM1); +} +static DEVICE_ATTR(l1_daylight_dim, 0664, adp8860_bl_l1_daylight_dim_show, + adp8860_bl_l1_daylight_dim_store); + +#ifdef ADP8860_EXT_FEATURES +static ssize_t adp8860_bl_ambient_light_level_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct adp8860_bl *data = dev_get_drvdata(dev); + int error; + uint8_t reg_val; + uint16_t ret_val; + + mutex_lock(&data->lock); + error = adp8860_read(data->client, ADP8860_PH1LEVL, ®_val); + ret_val = reg_val; + error |= adp8860_read(data->client, ADP8860_PH1LEVH, ®_val); + mutex_unlock(&data->lock); + + if (error < 0) + return error; + + /* Return 13-bit conversion value for the first light sensor */ + ret_val += (reg_val & 0x1F) << 8; + + return sprintf(buf, "%u\n", ret_val); +} +static DEVICE_ATTR(ambient_light_level, 0444, + adp8860_bl_ambient_light_level_show, NULL); + +static ssize_t adp8860_bl_ambient_light_zone_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct adp8860_bl *data = dev_get_drvdata(dev); + int error; + uint8_t reg_val; + + mutex_lock(&data->lock); + error = adp8860_read(data->client, ADP8860_CFGR, ®_val); + mutex_unlock(&data->lock); + + if (error < 0) + return error; + + return sprintf(buf, "%u\n", + ((reg_val >> CFGR_BLV_SHIFT) & CFGR_BLV_MASK) + 1); +} + +static ssize_t adp8860_bl_ambient_light_zone_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct adp8860_bl *data = dev_get_drvdata(dev); + unsigned long val; + uint8_t reg_val; + int ret; + + ret = strict_strtoul(buf, 10, &val); + if (ret) + return ret; + + if (val == 0) { + /* Enable automatic ambient light sensing */ + adp8860_set_bits(data->client, ADP8860_MDCR, CMP_AUTOEN); + } else if ((val > 0) && (val < 6)) { + /* Disable automatic ambient light sensing */ + adp8860_clr_bits(data->client, ADP8860_MDCR, CMP_AUTOEN); + + /* Set user supplied ambient light zone */ + mutex_lock(&data->lock); + adp8860_read(data->client, ADP8860_CFGR, ®_val); + reg_val &= ~(CFGR_BLV_MASK << CFGR_BLV_SHIFT); + reg_val |= val << CFGR_BLV_SHIFT; + adp8860_write(data->client, ADP8860_CFGR, reg_val); + mutex_unlock(&data->lock); + } + + return count; +} +static DEVICE_ATTR(ambient_light_zone, 0664, + adp8860_bl_ambient_light_zone_show, + adp8860_bl_ambient_light_zone_store); +#endif + +static struct attribute *adp8860_bl_attributes[] = { + &dev_attr_l3_dark_max.attr, + &dev_attr_l3_dark_dim.attr, + &dev_attr_l2_office_max.attr, + &dev_attr_l2_office_dim.attr, + &dev_attr_l1_daylight_max.attr, + &dev_attr_l1_daylight_dim.attr, +#ifdef ADP8860_EXT_FEATURES + &dev_attr_ambient_light_level.attr, + &dev_attr_ambient_light_zone.attr, +#endif + NULL +}; + +static const struct attribute_group adp8860_bl_attr_group = { + .attrs = adp8860_bl_attributes, +}; + +static int __devinit adp8860_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct backlight_device *bl; + struct adp8860_bl *data; + struct adp8860_backlight_platform_data *pdata = + client->dev.platform_data; + uint8_t reg_val; + int ret; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_err(&client->dev, "SMBUS Byte Data not Supported\n"); + return -EIO; + } + + if (!pdata) { + dev_err(&client->dev, "no platform data?\n"); + return -EINVAL; + } + + ret = adp8860_read(client, ADP8860_MFDVID, ®_val); + if (ret < 0) + return -EIO; + + if (ADP8860_MANID(reg_val) != ADP8860_MANUFID) { + dev_err(&client->dev, "failed to probe\n"); + return -ENODEV; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + + /* It's confirmed that the DEVID field is actually a REVID */ + + data->revid = ADP8860_DEVID(reg_val); + data->client = client; + data->pdata = pdata; + data->id = id->driver_data; + data->current_brightness = 0; + i2c_set_clientdata(client, data); + + mutex_init(&data->lock); + + bl = backlight_device_register(dev_driver_string(&client->dev), + &client->dev, data, &adp8860_bl_ops); + if (IS_ERR(bl)) { + dev_err(&client->dev, "failed to register backlight\n"); + ret = PTR_ERR(bl); + goto out2; + } + + bl->props.max_brightness = + bl->props.brightness = ADP8860_MAX_BRIGHTNESS; + + data->bl = bl; + + if (pdata->en_ambl_sens) + ret = sysfs_create_group(&bl->dev.kobj, + &adp8860_bl_attr_group); + + if (ret) { + dev_err(&client->dev, "failed to register sysfs\n"); + goto out1; + } + + ret = adp8860_bl_setup(bl); + if (ret) { + ret = -EIO; + goto out; + } + + backlight_update_status(bl); + + dev_info(&client->dev, "Rev.%d Backlight\n", data->revid); + + if (pdata->num_leds) + adp8860_led_probe(client); + + return 0; + +out: + if (data->pdata->en_ambl_sens) + sysfs_remove_group(&data->bl->dev.kobj, + &adp8860_bl_attr_group); +out1: + backlight_device_unregister(bl); +out2: + i2c_set_clientdata(client, NULL); + kfree(data); + + return ret; +} + +static int __devexit adp8860_remove(struct i2c_client *client) +{ + struct adp8860_bl *data = i2c_get_clientdata(client); + + adp8860_clr_bits(client, ADP8860_MDCR, NSTBY); + + if (data->led) + adp8860_led_remove(client); + + if (data->pdata->en_ambl_sens) + sysfs_remove_group(&data->bl->dev.kobj, + &adp8860_bl_attr_group); + + backlight_device_unregister(data->bl); + i2c_set_clientdata(client, NULL); + kfree(data); + + return 0; +} + +#ifdef CONFIG_PM +static int adp8860_i2c_suspend(struct i2c_client *client, pm_message_t message) +{ + adp8860_clr_bits(client, ADP8860_MDCR, NSTBY); + + return 0; +} + +static int adp8860_i2c_resume(struct i2c_client *client) +{ + adp8860_set_bits(client, ADP8860_MDCR, NSTBY); + + return 0; +} +#else +#define adp8860_i2c_suspend NULL +#define adp8860_i2c_resume NULL +#endif + +static const struct i2c_device_id adp8860_id[] = { + { "adp8860", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, adp8860_id); + +static struct i2c_driver adp8860_driver = { + .driver = { + .name = KBUILD_MODNAME, + }, + .probe = adp8860_probe, + .remove = __devexit_p(adp8860_remove), + .suspend = adp8860_i2c_suspend, + .resume = adp8860_i2c_resume, + .id_table = adp8860_id, +}; + +static int __init adp8860_init(void) +{ + return i2c_add_driver(&adp8860_driver); +} +module_init(adp8860_init); + +static void __exit adp8860_exit(void) +{ + i2c_del_driver(&adp8860_driver); +} +module_exit(adp8860_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("ADP8860 Backlight driver"); +MODULE_ALIAS("i2c:adp8860-backlight"); diff --git a/include/linux/i2c/adp8860.h b/include/linux/i2c/adp8860.h new file mode 100644 index 000000000000..115514b7176e --- /dev/null +++ b/include/linux/i2c/adp8860.h @@ -0,0 +1,137 @@ +/* + * Definitions and platform data for Analog Devices + * Backlight drivers ADP8860 + * + * Copyright 2009-2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __LINUX_I2C_ADP8860_H +#define __LINUX_I2C_ADP8860_H + +#include +#include + +#define ID_ADP8860 8860 + +#define ADP8860_MAX_BRIGHTNESS 0x7F +#define FLAG_OFFT_SHIFT 8 + +/* + * LEDs subdevice platform data + */ + +#define ADP8860_LED_DIS_BLINK (0 << FLAG_OFFT_SHIFT) +#define ADP8860_LED_OFFT_600ms (1 << FLAG_OFFT_SHIFT) +#define ADP8860_LED_OFFT_1200ms (2 << FLAG_OFFT_SHIFT) +#define ADP8860_LED_OFFT_1800ms (3 << FLAG_OFFT_SHIFT) + +#define ADP8860_LED_ONT_200ms 0 +#define ADP8860_LED_ONT_600ms 1 +#define ADP8860_LED_ONT_800ms 2 +#define ADP8860_LED_ONT_1200ms 3 + +#define ADP8860_LED_D7 (7) +#define ADP8860_LED_D6 (6) +#define ADP8860_LED_D5 (5) +#define ADP8860_LED_D4 (4) +#define ADP8860_LED_D3 (3) +#define ADP8860_LED_D2 (2) +#define ADP8860_LED_D1 (1) + +/* + * Backlight subdevice platform data + */ + +#define ADP8860_BL_D7 (1 << 6) +#define ADP8860_BL_D6 (1 << 5) +#define ADP8860_BL_D5 (1 << 4) +#define ADP8860_BL_D4 (1 << 3) +#define ADP8860_BL_D3 (1 << 2) +#define ADP8860_BL_D2 (1 << 1) +#define ADP8860_BL_D1 (1 << 0) + +#define ADP8860_FADE_T_DIS 0 /* Fade Timer Disabled */ +#define ADP8860_FADE_T_300ms 1 /* 0.3 Sec */ +#define ADP8860_FADE_T_600ms 2 +#define ADP8860_FADE_T_900ms 3 +#define ADP8860_FADE_T_1200ms 4 +#define ADP8860_FADE_T_1500ms 5 +#define ADP8860_FADE_T_1800ms 6 +#define ADP8860_FADE_T_2100ms 7 +#define ADP8860_FADE_T_2400ms 8 +#define ADP8860_FADE_T_2700ms 9 +#define ADP8860_FADE_T_3000ms 10 +#define ADP8860_FADE_T_3500ms 11 +#define ADP8860_FADE_T_4000ms 12 +#define ADP8860_FADE_T_4500ms 13 +#define ADP8860_FADE_T_5000ms 14 +#define ADP8860_FADE_T_5500ms 15 /* 5.5 Sec */ + +#define ADP8860_FADE_LAW_LINEAR 0 +#define ADP8860_FADE_LAW_SQUARE 1 +#define ADP8860_FADE_LAW_CUBIC1 2 +#define ADP8860_FADE_LAW_CUBIC2 3 + +#define ADP8860_BL_AMBL_FILT_80ms 0 /* Light sensor filter time */ +#define ADP8860_BL_AMBL_FILT_160ms 1 +#define ADP8860_BL_AMBL_FILT_320ms 2 +#define ADP8860_BL_AMBL_FILT_640ms 3 +#define ADP8860_BL_AMBL_FILT_1280ms 4 +#define ADP8860_BL_AMBL_FILT_2560ms 5 +#define ADP8860_BL_AMBL_FILT_5120ms 6 +#define ADP8860_BL_AMBL_FILT_10240ms 7 /* 10.24 sec */ + +/* + * Blacklight current 0..30mA + */ +#define ADP8860_BL_CUR_mA(I) ((I * 127) / 30) + +/* + * L2 comparator current 0..1106uA + */ +#define ADP8860_L2_COMP_CURR_uA(I) ((I * 255) / 1106) + +/* + * L3 comparator current 0..138uA + */ +#define ADP8860_L3_COMP_CURR_uA(I) ((I * 255) / 138) + +struct adp8860_backlight_platform_data { + u8 bl_led_assign; /* 1 = Backlight 0 = Individual LED */ + + u8 bl_fade_in; /* Backlight Fade-In Timer */ + u8 bl_fade_out; /* Backlight Fade-Out Timer */ + u8 bl_fade_law; /* fade-on/fade-off transfer characteristic */ + + u8 en_ambl_sens; /* 1 = enable ambient light sensor */ + u8 abml_filt; /* Light sensor filter time */ + + u8 l1_daylight_max; /* use BL_CUR_mA(I) 0 <= I <= 30 mA */ + u8 l1_daylight_dim; /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */ + u8 l2_office_max; /* use BL_CUR_mA(I) 0 <= I <= 30 mA */ + u8 l2_office_dim; /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */ + u8 l3_dark_max; /* use BL_CUR_mA(I) 0 <= I <= 30 mA */ + u8 l3_dark_dim; /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */ + + u8 l2_trip; /* use L2_COMP_CURR_uA(I) 0 <= I <= 1106 uA */ + u8 l2_hyst; /* use L2_COMP_CURR_uA(I) 0 <= I <= 1106 uA */ + u8 l3_trip; /* use L3_COMP_CURR_uA(I) 0 <= I <= 551 uA */ + u8 l3_hyst; /* use L3_COMP_CURR_uA(I) 0 <= I <= 551 uA */ + + /** + * Independent Current Sinks / LEDS + * Sinks not assigned to the Backlight can be exposed to + * user space using the LEDS CLASS interface + */ + + int num_leds; + struct led_info *leds; + u8 led_fade_in; /* LED Fade-In Timer */ + u8 led_fade_out; /* LED Fade-Out Timer */ + u8 led_fade_law; /* fade-on/fade-off transfer characteristic */ + u8 led_on_time; +}; + +#endif /* __LINUX_I2C_ADP8860_H */ -- cgit v1.2.3 From 3f43f8b2ad9035c5440d65681079f4d80542d21f Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 12 May 2010 13:49:12 -0700 Subject: backlight: fix adp8860_bl build errors Add slab.h to fix part of build. Add a parameter in backlight_device_register() call to fix part of build. drivers/video/backlight/adp8860_bl.c:215: error: implicit declaration of function 'kzalloc' drivers/video/backlight/adp8860_bl.c:215: warning: assignment makes pointer from integer without a cast drivers/video/backlight/adp8860_bl.c:285: error: implicit declaration of function 'kfree' drivers/video/backlight/adp8860_bl.c:673: warning: assignment makes pointer from integer without a cast drivers/video/backlight/adp8860_bl.c:689: error: too few arguments to function 'backlight_device_register' Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Richard Purdie --- drivers/video/backlight/adp8860_bl.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c index 3c449d2f68b9..99d14ed88571 100644 --- a/drivers/video/backlight/adp8860_bl.c +++ b/drivers/video/backlight/adp8860_bl.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -647,6 +648,7 @@ static int __devinit adp8860_probe(struct i2c_client *client, struct adp8860_bl *data; struct adp8860_backlight_platform_data *pdata = client->dev.platform_data; + struct backlight_properties props; uint8_t reg_val; int ret; @@ -683,10 +685,13 @@ static int __devinit adp8860_probe(struct i2c_client *client, data->current_brightness = 0; i2c_set_clientdata(client, data); + memset(&props, 0, sizeof(props)); + props.max_brightness = ADP8860_MAX_BRIGHTNESS; + mutex_init(&data->lock); bl = backlight_device_register(dev_driver_string(&client->dev), - &client->dev, data, &adp8860_bl_ops); + &client->dev, data, &adp8860_bl_ops, &props); if (IS_ERR(bl)) { dev_err(&client->dev, "failed to register backlight\n"); ret = PTR_ERR(bl); -- cgit v1.2.3 From 47306fc35ec39a5d0715e0a79344d02dffeaeeb2 Mon Sep 17 00:00:00 2001 From: Alberto Panizzo Date: Mon, 26 Apr 2010 22:51:08 +0200 Subject: backlight: l4f00242t03: Fix regulators handling code in remove function Simple swap of regulator free Signed-off-by: Alberto Panizzo Signed-off-by: Richard Purdie --- drivers/video/backlight/l4f00242t03.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c index bcdb12c93efd..1dafec85ddc0 100644 --- a/drivers/video/backlight/l4f00242t03.c +++ b/drivers/video/backlight/l4f00242t03.c @@ -222,9 +222,9 @@ static int __devexit l4f00242t03_remove(struct spi_device *spi) gpio_free(pdata->reset_gpio); if (priv->io_reg) - regulator_put(priv->core_reg); - if (priv->core_reg) regulator_put(priv->io_reg); + if (priv->core_reg) + regulator_put(priv->core_reg); kfree(priv); -- cgit v1.2.3 From 08b3924b24cdb1942393dc3009335a2153bd2eac Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 5 May 2010 12:13:23 -0500 Subject: backlight: Add Cirrus EP93xx backlight driver The EP9307, EP9312, and EP9315 processors include a framebuffer peripheral. This peripheral has a dedicated pwm output called BRIGHT that can be used to control the backlight on an LCD. Signed-off-by: H Hartley Sweeten Signed-off-by: Richard Purdie --- drivers/video/backlight/Kconfig | 10 +++ drivers/video/backlight/Makefile | 1 + drivers/video/backlight/ep93xx_bl.c | 160 ++++++++++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 drivers/video/backlight/ep93xx_bl.c (limited to 'drivers') diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 0f7e795f27f8..2d8052182960 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -142,6 +142,16 @@ config BACKLIGHT_ATMEL_PWM To compile this driver as a module, choose M here: the module will be called atmel-pwm-bl. +config BACKLIGHT_EP93XX + tristate "Cirrus EP93xx Backlight Driver" + depends on FB_EP93XX + help + If you have a LCD backlight connected to the BRIGHT output of + the EP93xx, say Y here to enable this driver. + + To compile this driver as a module, choose M here: the module will + be called ep93xx_bl. + config BACKLIGHT_GENERIC tristate "Generic (aka Sharp Corgi) Backlight Driver" default y diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 3cbaacae8f9c..ef610b15fdc6 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o +obj-$(CONFIG_BACKLIGHT_EP93XX) += ep93xx_bl.o obj-$(CONFIG_BACKLIGHT_GENERIC) += generic_bl.o obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o diff --git a/drivers/video/backlight/ep93xx_bl.c b/drivers/video/backlight/ep93xx_bl.c new file mode 100644 index 000000000000..b0cc49184803 --- /dev/null +++ b/drivers/video/backlight/ep93xx_bl.c @@ -0,0 +1,160 @@ +/* + * Driver for the Cirrus EP93xx lcd backlight + * + * Copyright (c) 2010 H Hartley Sweeten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This driver controls the pulse width modulated brightness control output, + * BRIGHT, on the Cirrus EP9307, EP9312, and EP9315 processors. + */ + + +#include +#include +#include +#include + +#include + +#define EP93XX_RASTER_REG(x) (EP93XX_RASTER_BASE + (x)) +#define EP93XX_RASTER_BRIGHTNESS EP93XX_RASTER_REG(0x20) + +#define EP93XX_MAX_COUNT 255 +#define EP93XX_MAX_BRIGHT 255 +#define EP93XX_DEF_BRIGHT 128 + +struct ep93xxbl { + void __iomem *mmio; + int brightness; +}; + +static int ep93xxbl_set(struct backlight_device *bl, int brightness) +{ + struct ep93xxbl *ep93xxbl = bl_get_data(bl); + + __raw_writel((brightness << 8) | EP93XX_MAX_COUNT, ep93xxbl->mmio); + + ep93xxbl->brightness = brightness; + + return 0; +} + +static int ep93xxbl_update_status(struct backlight_device *bl) +{ + int brightness = bl->props.brightness; + + if (bl->props.power != FB_BLANK_UNBLANK || + bl->props.fb_blank != FB_BLANK_UNBLANK) + brightness = 0; + + return ep93xxbl_set(bl, brightness); +} + +static int ep93xxbl_get_brightness(struct backlight_device *bl) +{ + struct ep93xxbl *ep93xxbl = bl_get_data(bl); + + return ep93xxbl->brightness; +} + +static const struct backlight_ops ep93xxbl_ops = { + .update_status = ep93xxbl_update_status, + .get_brightness = ep93xxbl_get_brightness, +}; + +static int __init ep93xxbl_probe(struct platform_device *dev) +{ + struct ep93xxbl *ep93xxbl; + struct backlight_device *bl; + struct backlight_properties props; + + ep93xxbl = devm_kzalloc(&dev->dev, sizeof(*ep93xxbl), GFP_KERNEL); + if (!ep93xxbl) + return -ENOMEM; + + /* + * This register is located in the range already ioremap'ed by + * the framebuffer driver. A MFD driver seems a bit of overkill + * to handle this so use the static I/O mapping; this address + * is already virtual. + * + * NOTE: No locking is required; the framebuffer does not touch + * this register. + */ + ep93xxbl->mmio = EP93XX_RASTER_BRIGHTNESS; + + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = EP93XX_MAX_BRIGHT; + bl = backlight_device_register(dev->name, &dev->dev, ep93xxbl, + &ep93xxbl_ops, &props); + if (IS_ERR(bl)) + return PTR_ERR(bl); + + bl->props.brightness = EP93XX_DEF_BRIGHT; + + platform_set_drvdata(dev, bl); + + ep93xxbl_update_status(bl); + + return 0; +} + +static int ep93xxbl_remove(struct platform_device *dev) +{ + struct backlight_device *bl = platform_get_drvdata(dev); + + backlight_device_unregister(bl); + platform_set_drvdata(dev, NULL); + return 0; +} + +#ifdef CONFIG_PM +static int ep93xxbl_suspend(struct platform_device *dev, pm_message_t state) +{ + struct backlight_device *bl = platform_get_drvdata(dev); + + return ep93xxbl_set(bl, 0); +} + +static int ep93xxbl_resume(struct platform_device *dev) +{ + struct backlight_device *bl = platform_get_drvdata(dev); + + backlight_update_status(bl); + return 0; +} +#else +#define ep93xxbl_suspend NULL +#define ep93xxbl_resume NULL +#endif + +static struct platform_driver ep93xxbl_driver = { + .driver = { + .name = "ep93xx-bl", + .owner = THIS_MODULE, + }, + .probe = ep93xxbl_probe, + .remove = __devexit_p(ep93xxbl_remove), + .suspend = ep93xxbl_suspend, + .resume = ep93xxbl_resume, +}; + +static int __init ep93xxbl_init(void) +{ + return platform_driver_register(&ep93xxbl_driver); +} +module_init(ep93xxbl_init); + +static void __exit ep93xxbl_exit(void) +{ + platform_driver_unregister(&ep93xxbl_driver); +} +module_exit(ep93xxbl_exit); + +MODULE_DESCRIPTION("EP93xx Backlight Driver"); +MODULE_AUTHOR("H Hartley Sweeten "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ep93xx-bl"); -- cgit v1.2.3 From ed601fa46777cb529bda0dbec80c4aec704dd063 Mon Sep 17 00:00:00 2001 From: Steffen Röcker Date: Tue, 23 Mar 2010 23:12:33 +0100 Subject: backlight: mbp_nvidia_bl - Fix DMI_SYS_VENDOR for MacBook1,1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix DMI_SYS_VENDOR for MacBook1,1. When the MacBook1,1 came out Apple was still named Apple Computer, I am not sure if this applies to older MacBook2,1 versions aswell. Signed-off-by: Steffen Röcker Signed-off-by: Richard Purdie --- drivers/video/backlight/mbp_nvidia_bl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c index 52c780f5db1b..9fb533f6373e 100644 --- a/drivers/video/backlight/mbp_nvidia_bl.c +++ b/drivers/video/backlight/mbp_nvidia_bl.c @@ -141,7 +141,7 @@ static const struct dmi_system_id __initdata mbp_device_table[] = { .callback = mbp_dmi_match, .ident = "MacBook 1,1", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"), }, .driver_data = (void *)&intel_chipset_data, -- cgit v1.2.3 From c7c06d8a95fd6b83d9f71a0cfecd3f91945d17e5 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Wed, 26 May 2010 03:00:59 -0400 Subject: backlight: adp8860: add support for ADP8861 & ADP8863 Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger Signed-off-by: Richard Purdie --- drivers/video/backlight/Kconfig | 6 ++-- drivers/video/backlight/adp8860_bl.c | 58 +++++++++++++++++++++++++----------- include/linux/i2c/adp8860.h | 17 +++++++++++ 3 files changed, 61 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 2d8052182960..39ecaf71c1f9 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -275,13 +275,13 @@ config BACKLIGHT_ADP5520 be called adp5520_bl. config BACKLIGHT_ADP8860 - tristate "Backlight Driver for ADP8860 using WLED" + tristate "Backlight Driver for ADP8860/ADP8861/ADP8863 using WLED" depends on BACKLIGHT_CLASS_DEVICE && I2C select NEW_LEDS select LEDS_CLASS help - If you have a LCD backlight connected to the ADP8860, - say Y here to enable this driver. + If you have a LCD backlight connected to the ADP8860, ADP8861 or + ADP8863 say Y here to enable this driver. To compile this driver as a module, choose M here: the module will be called adp8860_bl. diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c index 99d14ed88571..921ca37398f3 100644 --- a/drivers/video/backlight/adp8860_bl.c +++ b/drivers/video/backlight/adp8860_bl.c @@ -62,7 +62,9 @@ #define ADP8860_PH2LEVH 0x24 /* Second phototransistor ambient light level-high byte register */ #define ADP8860_MANUFID 0x0 /* Analog Devices ADP8860 Manufacturer ID */ -#define ADP8860_DEVICEID 0x7 /* Analog Devices ADP8860 Device ID */ +#define ADP8861_MANUFID 0x4 /* Analog Devices ADP8861 Manufacturer ID */ +#define ADP8863_MANUFID 0x2 /* Analog Devices ADP8863 Manufacturer ID */ + #define ADP8860_DEVID(x) ((x) & 0xF) #define ADP8860_MANID(x) ((x) >> 4) @@ -70,6 +72,7 @@ #define INT_CFG (1 << 6) #define NSTBY (1 << 5) #define DIM_EN (1 << 4) +#define GDWN_DIS (1 << 3) #define SIS_EN (1 << 2) #define CMP_AUTOEN (1 << 1) #define BLEN (1 << 0) @@ -86,6 +89,12 @@ #define BL_CFGR_VAL(law, blv) ((((blv) & CFGR_BLV_MASK) << CFGR_BLV_SHIFT) | ((0x3 & (law)) << 1)) #define ALS_CCFG_VAL(filt) ((0x7 & filt) << 5) +enum { + adp8860, + adp8861, + adp8863 +}; + struct adp8860_led { struct led_classdev cdev; struct work_struct work; @@ -105,6 +114,8 @@ struct adp8860_bl { int id; int revid; int current_brightness; + unsigned en_ambl_sens:1; + unsigned gdwn_dis:1; }; static int adp8860_read(struct i2c_client *client, int reg, uint8_t *val) @@ -121,7 +132,6 @@ static int adp8860_read(struct i2c_client *client, int reg, uint8_t *val) return 0; } - static int adp8860_write(struct i2c_client *client, u8 reg, u8 val) { return i2c_smbus_write_byte_data(client, reg, val); @@ -321,7 +331,7 @@ static int adp8860_bl_set(struct backlight_device *bl, int brightness) struct i2c_client *client = data->client; int ret = 0; - if (data->pdata->en_ambl_sens) { + if (data->en_ambl_sens) { if ((brightness > 0) && (brightness < ADP8860_MAX_BRIGHTNESS)) { /* Disable Ambient Light auto adjust */ ret |= adp8860_clr_bits(client, ADP8860_MDCR, @@ -388,7 +398,7 @@ static int adp8860_bl_setup(struct backlight_device *bl) ret |= adp8860_write(client, ADP8860_BLMX1, pdata->l1_daylight_max); ret |= adp8860_write(client, ADP8860_BLDM1, pdata->l1_daylight_dim); - if (pdata->en_ambl_sens) { + if (data->en_ambl_sens) { data->cached_daylight_max = pdata->l1_daylight_max; ret |= adp8860_write(client, ADP8860_BLMX2, pdata->l2_office_max); @@ -413,7 +423,8 @@ static int adp8860_bl_setup(struct backlight_device *bl) ret |= adp8860_write(client, ADP8860_BLFR, FADE_VAL(pdata->bl_fade_in, pdata->bl_fade_out)); - ret |= adp8860_set_bits(client, ADP8860_MDCR, BLEN | DIM_EN | NSTBY); + ret |= adp8860_set_bits(client, ADP8860_MDCR, BLEN | DIM_EN | NSTBY | + (data->gdwn_dis ? GDWN_DIS : 0)); return ret; } @@ -663,19 +674,29 @@ static int __devinit adp8860_probe(struct i2c_client *client, return -EINVAL; } + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + ret = adp8860_read(client, ADP8860_MFDVID, ®_val); if (ret < 0) - return -EIO; + goto out2; - if (ADP8860_MANID(reg_val) != ADP8860_MANUFID) { + switch (ADP8860_MANID(reg_val)) { + case ADP8863_MANUFID: + data->gdwn_dis = !!pdata->gdwn_dis; + case ADP8860_MANUFID: + data->en_ambl_sens = !!pdata->en_ambl_sens; + break; + case ADP8861_MANUFID: + data->gdwn_dis = !!pdata->gdwn_dis; + break; + default: dev_err(&client->dev, "failed to probe\n"); - return -ENODEV; + ret = -ENODEV; + goto out2; } - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (data == NULL) - return -ENOMEM; - /* It's confirmed that the DEVID field is actually a REVID */ data->revid = ADP8860_DEVID(reg_val); @@ -703,7 +724,7 @@ static int __devinit adp8860_probe(struct i2c_client *client, data->bl = bl; - if (pdata->en_ambl_sens) + if (data->en_ambl_sens) ret = sysfs_create_group(&bl->dev.kobj, &adp8860_bl_attr_group); @@ -720,7 +741,8 @@ static int __devinit adp8860_probe(struct i2c_client *client, backlight_update_status(bl); - dev_info(&client->dev, "Rev.%d Backlight\n", data->revid); + dev_info(&client->dev, "%s Rev.%d Backlight\n", + client->name, data->revid); if (pdata->num_leds) adp8860_led_probe(client); @@ -728,7 +750,7 @@ static int __devinit adp8860_probe(struct i2c_client *client, return 0; out: - if (data->pdata->en_ambl_sens) + if (data->en_ambl_sens) sysfs_remove_group(&data->bl->dev.kobj, &adp8860_bl_attr_group); out1: @@ -749,7 +771,7 @@ static int __devexit adp8860_remove(struct i2c_client *client) if (data->led) adp8860_led_remove(client); - if (data->pdata->en_ambl_sens) + if (data->en_ambl_sens) sysfs_remove_group(&data->bl->dev.kobj, &adp8860_bl_attr_group); @@ -780,7 +802,9 @@ static int adp8860_i2c_resume(struct i2c_client *client) #endif static const struct i2c_device_id adp8860_id[] = { - { "adp8860", 0 }, + { "adp8860", adp8860 }, + { "adp8861", adp8861 }, + { "adp8863", adp8863 }, { } }; MODULE_DEVICE_TABLE(i2c, adp8860_id); diff --git a/include/linux/i2c/adp8860.h b/include/linux/i2c/adp8860.h index 115514b7176e..0b4d39855c91 100644 --- a/include/linux/i2c/adp8860.h +++ b/include/linux/i2c/adp8860.h @@ -132,6 +132,23 @@ struct adp8860_backlight_platform_data { u8 led_fade_out; /* LED Fade-Out Timer */ u8 led_fade_law; /* fade-on/fade-off transfer characteristic */ u8 led_on_time; + + /** + * Gain down disable. Setting this option does not allow the + * charge pump to switch to lower gains. NOT AVAILABLE on ADP8860 + * 1 = the charge pump doesn't switch down in gain until all LEDs are 0. + * The charge pump switches up in gain as needed. This feature is + * useful if the ADP8863 charge pump is used to drive an external load. + * This feature must be used when utilizing small fly capacitors + * (0402 or smaller). + * 0 = the charge pump automatically switches up and down in gain. + * This provides optimal efficiency, but is not suitable for driving + * loads that are not connected through the ADP8863 diode drivers. + * Additionally, the charge pump fly capacitors should be low ESR + * and sized 0603 or greater. + */ + + u8 gdwn_dis; }; #endif /* __LINUX_I2C_ADP8860_H */ -- cgit v1.2.3 From ee378a5c6550dcbfe6fa9c71b84ca2eb19cb288e Mon Sep 17 00:00:00 2001 From: InKi Dae Date: Mon, 24 May 2010 12:21:36 -0700 Subject: backlight: add S6E63M0 AMOLED LCD Panel driver This is S6E63M0 AMOLED LCD Panel(480x800) driver using 3-wired SPI interface also almost features for lcd panel driver has been implemented in here. and I added new structure common for all the lcd panel drivers to include/linux/lcd.h file. LCD Panel driver needs interfaces for controlling device power such as power on/off and reset. these interfaces are device specific so it should be implemented to machine code at this time, we should create new structure for registering these functions as callbacks and also a header file for that structure and finally registered callback functions would be called by lcd panel driver. such header file(including new structure for lcd panel) would be added for all the lcd panel drivers. If anyone provides common structure for registering such callback functions then we could reduce unnecessary header files for lcd panel. I thought that suitable anyone could be include/linux/lcd.h so a new lcd_platform_data structure was added there. [akpm@linux-foundation.org: coding-style fixes] [randy.dunlap@oracle.com: fix s6e63m0 kconfig] [randy.dunlap@oracle.com: fix device attribute functions return types] Signed-off-by: InKi Dae Reviewed-by: KyungMin Park Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Richard Purdie --- drivers/video/backlight/Kconfig | 8 + drivers/video/backlight/Makefile | 1 + drivers/video/backlight/s6e63m0.c | 920 ++++++++++++++++++++++++++++++++ drivers/video/backlight/s6e63m0_gamma.h | 266 +++++++++ include/linux/lcd.h | 23 + 5 files changed, 1218 insertions(+) create mode 100644 drivers/video/backlight/s6e63m0.c create mode 100644 drivers/video/backlight/s6e63m0_gamma.h (limited to 'drivers') diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 39ecaf71c1f9..cbd80978460e 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -101,6 +101,14 @@ config LCD_HP700 If you have an HP Jornada 700 series handheld (710/720/728) say Y to enable LCD control driver. +config LCD_S6E63M0 + tristate "S6E63M0 AMOLED LCD Driver" + depends on SPI && BACKLIGHT_CLASS_DEVICE + default n + help + If you have an S6E63M0 LCD Panel, say Y to enable its + LCD control driver. + endif # LCD_CLASS_DEVICE # diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index ef610b15fdc6..f8978c0a2319 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o obj-$(CONFIG_LCD_TDO24M) += tdo24m.o obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o +obj-$(CONFIG_LCD_S6E63M0) += s6e63m0.o obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o diff --git a/drivers/video/backlight/s6e63m0.c b/drivers/video/backlight/s6e63m0.c new file mode 100644 index 000000000000..a3128c9cb7ad --- /dev/null +++ b/drivers/video/backlight/s6e63m0.c @@ -0,0 +1,920 @@ +/* + * S6E63M0 AMOLED LCD panel driver. + * + * Author: InKi Dae + * + * Derived from drivers/video/omap/lcd-apollon.c + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "s6e63m0_gamma.h" + +#define SLEEPMSEC 0x1000 +#define ENDDEF 0x2000 +#define DEFMASK 0xFF00 +#define COMMAND_ONLY 0xFE +#define DATA_ONLY 0xFF + +#define MIN_BRIGHTNESS 0 +#define MAX_BRIGHTNESS 10 + +#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL) + +struct s6e63m0 { + struct device *dev; + struct spi_device *spi; + unsigned int power; + unsigned int current_brightness; + unsigned int gamma_mode; + unsigned int gamma_table_count; + struct lcd_device *ld; + struct backlight_device *bd; + struct lcd_platform_data *lcd_pd; +}; + +static const unsigned short SEQ_PANEL_CONDITION_SET[] = { + 0xF8, 0x01, + DATA_ONLY, 0x27, + DATA_ONLY, 0x27, + DATA_ONLY, 0x07, + DATA_ONLY, 0x07, + DATA_ONLY, 0x54, + DATA_ONLY, 0x9f, + DATA_ONLY, 0x63, + DATA_ONLY, 0x86, + DATA_ONLY, 0x1a, + DATA_ONLY, 0x33, + DATA_ONLY, 0x0d, + DATA_ONLY, 0x00, + DATA_ONLY, 0x00, + + ENDDEF, 0x0000 +}; + +static const unsigned short SEQ_DISPLAY_CONDITION_SET[] = { + 0xf2, 0x02, + DATA_ONLY, 0x03, + DATA_ONLY, 0x1c, + DATA_ONLY, 0x10, + DATA_ONLY, 0x10, + + 0xf7, 0x03, + DATA_ONLY, 0x00, + DATA_ONLY, 0x00, + + ENDDEF, 0x0000 +}; + +static const unsigned short SEQ_GAMMA_SETTING[] = { + 0xfa, 0x00, + DATA_ONLY, 0x18, + DATA_ONLY, 0x08, + DATA_ONLY, 0x24, + DATA_ONLY, 0x64, + DATA_ONLY, 0x56, + DATA_ONLY, 0x33, + DATA_ONLY, 0xb6, + DATA_ONLY, 0xba, + DATA_ONLY, 0xa8, + DATA_ONLY, 0xac, + DATA_ONLY, 0xb1, + DATA_ONLY, 0x9d, + DATA_ONLY, 0xc1, + DATA_ONLY, 0xc1, + DATA_ONLY, 0xb7, + DATA_ONLY, 0x00, + DATA_ONLY, 0x9c, + DATA_ONLY, 0x00, + DATA_ONLY, 0x9f, + DATA_ONLY, 0x00, + DATA_ONLY, 0xd6, + + 0xfa, 0x01, + + ENDDEF, 0x0000 +}; + +static const unsigned short SEQ_ETC_CONDITION_SET[] = { + 0xf6, 0x00, + DATA_ONLY, 0x8c, + DATA_ONLY, 0x07, + + 0xb3, 0xc, + + 0xb5, 0x2c, + DATA_ONLY, 0x12, + DATA_ONLY, 0x0c, + DATA_ONLY, 0x0a, + DATA_ONLY, 0x10, + DATA_ONLY, 0x0e, + DATA_ONLY, 0x17, + DATA_ONLY, 0x13, + DATA_ONLY, 0x1f, + DATA_ONLY, 0x1a, + DATA_ONLY, 0x2a, + DATA_ONLY, 0x24, + DATA_ONLY, 0x1f, + DATA_ONLY, 0x1b, + DATA_ONLY, 0x1a, + DATA_ONLY, 0x17, + + DATA_ONLY, 0x2b, + DATA_ONLY, 0x26, + DATA_ONLY, 0x22, + DATA_ONLY, 0x20, + DATA_ONLY, 0x3a, + DATA_ONLY, 0x34, + DATA_ONLY, 0x30, + DATA_ONLY, 0x2c, + DATA_ONLY, 0x29, + DATA_ONLY, 0x26, + DATA_ONLY, 0x25, + DATA_ONLY, 0x23, + DATA_ONLY, 0x21, + DATA_ONLY, 0x20, + DATA_ONLY, 0x1e, + DATA_ONLY, 0x1e, + + 0xb6, 0x00, + DATA_ONLY, 0x00, + DATA_ONLY, 0x11, + DATA_ONLY, 0x22, + DATA_ONLY, 0x33, + DATA_ONLY, 0x44, + DATA_ONLY, 0x44, + DATA_ONLY, 0x44, + + DATA_ONLY, 0x55, + DATA_ONLY, 0x55, + DATA_ONLY, 0x66, + DATA_ONLY, 0x66, + DATA_ONLY, 0x66, + DATA_ONLY, 0x66, + DATA_ONLY, 0x66, + DATA_ONLY, 0x66, + + 0xb7, 0x2c, + DATA_ONLY, 0x12, + DATA_ONLY, 0x0c, + DATA_ONLY, 0x0a, + DATA_ONLY, 0x10, + DATA_ONLY, 0x0e, + DATA_ONLY, 0x17, + DATA_ONLY, 0x13, + DATA_ONLY, 0x1f, + DATA_ONLY, 0x1a, + DATA_ONLY, 0x2a, + DATA_ONLY, 0x24, + DATA_ONLY, 0x1f, + DATA_ONLY, 0x1b, + DATA_ONLY, 0x1a, + DATA_ONLY, 0x17, + + DATA_ONLY, 0x2b, + DATA_ONLY, 0x26, + DATA_ONLY, 0x22, + DATA_ONLY, 0x20, + DATA_ONLY, 0x3a, + DATA_ONLY, 0x34, + DATA_ONLY, 0x30, + DATA_ONLY, 0x2c, + DATA_ONLY, 0x29, + DATA_ONLY, 0x26, + DATA_ONLY, 0x25, + DATA_ONLY, 0x23, + DATA_ONLY, 0x21, + DATA_ONLY, 0x20, + DATA_ONLY, 0x1e, + DATA_ONLY, 0x1e, + + 0xb8, 0x00, + DATA_ONLY, 0x00, + DATA_ONLY, 0x11, + DATA_ONLY, 0x22, + DATA_ONLY, 0x33, + DATA_ONLY, 0x44, + DATA_ONLY, 0x44, + DATA_ONLY, 0x44, + + DATA_ONLY, 0x55, + DATA_ONLY, 0x55, + DATA_ONLY, 0x66, + DATA_ONLY, 0x66, + DATA_ONLY, 0x66, + DATA_ONLY, 0x66, + DATA_ONLY, 0x66, + DATA_ONLY, 0x66, + + 0xb9, 0x2c, + DATA_ONLY, 0x12, + DATA_ONLY, 0x0c, + DATA_ONLY, 0x0a, + DATA_ONLY, 0x10, + DATA_ONLY, 0x0e, + DATA_ONLY, 0x17, + DATA_ONLY, 0x13, + DATA_ONLY, 0x1f, + DATA_ONLY, 0x1a, + DATA_ONLY, 0x2a, + DATA_ONLY, 0x24, + DATA_ONLY, 0x1f, + DATA_ONLY, 0x1b, + DATA_ONLY, 0x1a, + DATA_ONLY, 0x17, + + DATA_ONLY, 0x2b, + DATA_ONLY, 0x26, + DATA_ONLY, 0x22, + DATA_ONLY, 0x20, + DATA_ONLY, 0x3a, + DATA_ONLY, 0x34, + DATA_ONLY, 0x30, + DATA_ONLY, 0x2c, + DATA_ONLY, 0x29, + DATA_ONLY, 0x26, + DATA_ONLY, 0x25, + DATA_ONLY, 0x23, + DATA_ONLY, 0x21, + DATA_ONLY, 0x20, + DATA_ONLY, 0x1e, + DATA_ONLY, 0x1e, + + 0xba, 0x00, + DATA_ONLY, 0x00, + DATA_ONLY, 0x11, + DATA_ONLY, 0x22, + DATA_ONLY, 0x33, + DATA_ONLY, 0x44, + DATA_ONLY, 0x44, + DATA_ONLY, 0x44, + + DATA_ONLY, 0x55, + DATA_ONLY, 0x55, + DATA_ONLY, 0x66, + DATA_ONLY, 0x66, + DATA_ONLY, 0x66, + DATA_ONLY, 0x66, + DATA_ONLY, 0x66, + DATA_ONLY, 0x66, + + 0xc1, 0x4d, + DATA_ONLY, 0x96, + DATA_ONLY, 0x1d, + DATA_ONLY, 0x00, + DATA_ONLY, 0x00, + DATA_ONLY, 0x01, + DATA_ONLY, 0xdf, + DATA_ONLY, 0x00, + DATA_ONLY, 0x00, + DATA_ONLY, 0x03, + DATA_ONLY, 0x1f, + DATA_ONLY, 0x00, + DATA_ONLY, 0x00, + DATA_ONLY, 0x00, + DATA_ONLY, 0x00, + DATA_ONLY, 0x00, + DATA_ONLY, 0x00, + DATA_ONLY, 0x00, + DATA_ONLY, 0x00, + DATA_ONLY, 0x03, + DATA_ONLY, 0x06, + DATA_ONLY, 0x09, + DATA_ONLY, 0x0d, + DATA_ONLY, 0x0f, + DATA_ONLY, 0x12, + DATA_ONLY, 0x15, + DATA_ONLY, 0x18, + + 0xb2, 0x10, + DATA_ONLY, 0x10, + DATA_ONLY, 0x0b, + DATA_ONLY, 0x05, + + ENDDEF, 0x0000 +}; + +static const unsigned short SEQ_ACL_ON[] = { + /* ACL on */ + 0xc0, 0x01, + + ENDDEF, 0x0000 +}; + +static const unsigned short SEQ_ACL_OFF[] = { + /* ACL off */ + 0xc0, 0x00, + + ENDDEF, 0x0000 +}; + +static const unsigned short SEQ_ELVSS_ON[] = { + /* ELVSS on */ + 0xb1, 0x0b, + + ENDDEF, 0x0000 +}; + +static const unsigned short SEQ_ELVSS_OFF[] = { + /* ELVSS off */ + 0xb1, 0x0a, + + ENDDEF, 0x0000 +}; + +static const unsigned short SEQ_STAND_BY_OFF[] = { + 0x11, COMMAND_ONLY, + + ENDDEF, 0x0000 +}; + +static const unsigned short SEQ_STAND_BY_ON[] = { + 0x10, COMMAND_ONLY, + + ENDDEF, 0x0000 +}; + +static const unsigned short SEQ_DISPLAY_ON[] = { + 0x29, COMMAND_ONLY, + + ENDDEF, 0x0000 +}; + + +static int s6e63m0_spi_write_byte(struct s6e63m0 *lcd, int addr, int data) +{ + u16 buf[1]; + struct spi_message msg; + + struct spi_transfer xfer = { + .len = 2, + .tx_buf = buf, + }; + + buf[0] = (addr << 8) | data; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + + return spi_sync(lcd->spi, &msg); +} + +static int s6e63m0_spi_write(struct s6e63m0 *lcd, unsigned char address, + unsigned char command) +{ + int ret = 0; + + if (address != DATA_ONLY) + ret = s6e63m0_spi_write_byte(lcd, 0x0, address); + if (command != COMMAND_ONLY) + ret = s6e63m0_spi_write_byte(lcd, 0x1, command); + + return ret; +} + +static int s6e63m0_panel_send_sequence(struct s6e63m0 *lcd, + const unsigned short *wbuf) +{ + int ret = 0, i = 0; + + while ((wbuf[i] & DEFMASK) != ENDDEF) { + if ((wbuf[i] & DEFMASK) != SLEEPMSEC) { + ret = s6e63m0_spi_write(lcd, wbuf[i], wbuf[i+1]); + if (ret) + break; + } else + udelay(wbuf[i+1]*1000); + i += 2; + } + + return ret; +} + +static int _s6e63m0_gamma_ctl(struct s6e63m0 *lcd, const unsigned int *gamma) +{ + unsigned int i = 0; + int ret = 0; + + /* disable gamma table updating. */ + ret = s6e63m0_spi_write(lcd, 0xfa, 0x00); + if (ret) { + dev_err(lcd->dev, "failed to disable gamma table updating.\n"); + goto gamma_err; + } + + for (i = 0 ; i < GAMMA_TABLE_COUNT; i++) { + ret = s6e63m0_spi_write(lcd, DATA_ONLY, gamma[i]); + if (ret) { + dev_err(lcd->dev, "failed to set gamma table.\n"); + goto gamma_err; + } + } + + /* update gamma table. */ + ret = s6e63m0_spi_write(lcd, 0xfa, 0x01); + if (ret) + dev_err(lcd->dev, "failed to update gamma table.\n"); + +gamma_err: + return ret; +} + +static int s6e63m0_gamma_ctl(struct s6e63m0 *lcd, int gamma) +{ + int ret = 0; + + ret = _s6e63m0_gamma_ctl(lcd, gamma_table.gamma_22_table[gamma]); + + return ret; +} + + +static int s6e63m0_ldi_init(struct s6e63m0 *lcd) +{ + int ret, i; + const unsigned short *init_seq[] = { + SEQ_PANEL_CONDITION_SET, + SEQ_DISPLAY_CONDITION_SET, + SEQ_GAMMA_SETTING, + SEQ_ETC_CONDITION_SET, + SEQ_ACL_ON, + SEQ_ELVSS_ON, + }; + + for (i = 0; i < ARRAY_SIZE(init_seq); i++) { + ret = s6e63m0_panel_send_sequence(lcd, init_seq[i]); + if (ret) + break; + } + + return ret; +} + +static int s6e63m0_ldi_enable(struct s6e63m0 *lcd) +{ + int ret = 0, i; + const unsigned short *enable_seq[] = { + SEQ_STAND_BY_OFF, + SEQ_DISPLAY_ON, + }; + + for (i = 0; i < ARRAY_SIZE(enable_seq); i++) { + ret = s6e63m0_panel_send_sequence(lcd, enable_seq[i]); + if (ret) + break; + } + + return ret; +} + +static int s6e63m0_ldi_disable(struct s6e63m0 *lcd) +{ + int ret; + + ret = s6e63m0_panel_send_sequence(lcd, SEQ_STAND_BY_ON); + + return ret; +} + +static int s6e63m0_power_on(struct s6e63m0 *lcd) +{ + int ret = 0; + struct lcd_platform_data *pd = NULL; + struct backlight_device *bd = NULL; + + pd = lcd->lcd_pd; + if (!pd) { + dev_err(lcd->dev, "platform data is NULL.\n"); + return -EFAULT; + } + + bd = lcd->bd; + if (!bd) { + dev_err(lcd->dev, "backlight device is NULL.\n"); + return -EFAULT; + } + + if (!pd->power_on) { + dev_err(lcd->dev, "power_on is NULL.\n"); + return -EFAULT; + } else { + pd->power_on(lcd->ld, 1); + mdelay(pd->power_on_delay); + } + + if (!pd->reset) { + dev_err(lcd->dev, "reset is NULL.\n"); + return -EFAULT; + } else { + pd->reset(lcd->ld); + mdelay(pd->reset_delay); + } + + ret = s6e63m0_ldi_init(lcd); + if (ret) { + dev_err(lcd->dev, "failed to initialize ldi.\n"); + return ret; + } + + ret = s6e63m0_ldi_enable(lcd); + if (ret) { + dev_err(lcd->dev, "failed to enable ldi.\n"); + return ret; + } + + /* set brightness to current value after power on or resume. */ + ret = s6e63m0_gamma_ctl(lcd, bd->props.brightness); + if (ret) { + dev_err(lcd->dev, "lcd gamma setting failed.\n"); + return ret; + } + + return 0; +} + +static int s6e63m0_power_off(struct s6e63m0 *lcd) +{ + int ret = 0; + struct lcd_platform_data *pd = NULL; + + pd = lcd->lcd_pd; + if (!pd) { + dev_err(lcd->dev, "platform data is NULL.\n"); + return -EFAULT; + } + + ret = s6e63m0_ldi_disable(lcd); + if (ret) { + dev_err(lcd->dev, "lcd setting failed.\n"); + return -EIO; + } + + mdelay(pd->power_off_delay); + + if (!pd->power_on) { + dev_err(lcd->dev, "power_on is NULL.\n"); + return -EFAULT; + } else + pd->power_on(lcd->ld, 0); + + return 0; +} + +static int s6e63m0_power(struct s6e63m0 *lcd, int power) +{ + int ret = 0; + + if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power)) + ret = s6e63m0_power_on(lcd); + else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power)) + ret = s6e63m0_power_off(lcd); + + if (!ret) + lcd->power = power; + + return ret; +} + +static int s6e63m0_set_power(struct lcd_device *ld, int power) +{ + struct s6e63m0 *lcd = lcd_get_data(ld); + + if (power != FB_BLANK_UNBLANK && power != FB_BLANK_POWERDOWN && + power != FB_BLANK_NORMAL) { + dev_err(lcd->dev, "power value should be 0, 1 or 4.\n"); + return -EINVAL; + } + + return s6e63m0_power(lcd, power); +} + +static int s6e63m0_get_power(struct lcd_device *ld) +{ + struct s6e63m0 *lcd = lcd_get_data(ld); + + return lcd->power; +} + +static int s6e63m0_get_brightness(struct backlight_device *bd) +{ + return bd->props.brightness; +} + +static int s6e63m0_set_brightness(struct backlight_device *bd) +{ + int ret = 0, brightness = bd->props.brightness; + struct s6e63m0 *lcd = bl_get_data(bd); + + if (brightness < MIN_BRIGHTNESS || + brightness > bd->props.max_brightness) { + dev_err(&bd->dev, "lcd brightness should be %d to %d.\n", + MIN_BRIGHTNESS, MAX_BRIGHTNESS); + return -EINVAL; + } + + ret = s6e63m0_gamma_ctl(lcd, bd->props.brightness); + if (ret) { + dev_err(&bd->dev, "lcd brightness setting failed.\n"); + return -EIO; + } + + return ret; +} + +static struct lcd_ops s6e63m0_lcd_ops = { + .set_power = s6e63m0_set_power, + .get_power = s6e63m0_get_power, +}; + +static const struct backlight_ops s6e63m0_backlight_ops = { + .get_brightness = s6e63m0_get_brightness, + .update_status = s6e63m0_set_brightness, +}; + +static ssize_t s6e63m0_sysfs_show_gamma_mode(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct s6e63m0 *lcd = dev_get_drvdata(dev); + char temp[10]; + + switch (lcd->gamma_mode) { + case 0: + sprintf(temp, "2.2 mode\n"); + strcat(buf, temp); + break; + case 1: + sprintf(temp, "1.9 mode\n"); + strcat(buf, temp); + break; + case 2: + sprintf(temp, "1.7 mode\n"); + strcat(buf, temp); + break; + default: + dev_info(dev, "gamma mode could be 0:2.2, 1:1.9 or 2:1.7)n"); + break; + } + + return strlen(buf); +} + +static ssize_t s6e63m0_sysfs_store_gamma_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct s6e63m0 *lcd = dev_get_drvdata(dev); + struct backlight_device *bd = NULL; + int brightness, rc; + + rc = strict_strtoul(buf, 0, (unsigned long *)&lcd->gamma_mode); + if (rc < 0) + return rc; + + bd = lcd->bd; + + brightness = bd->props.brightness; + + switch (lcd->gamma_mode) { + case 0: + _s6e63m0_gamma_ctl(lcd, gamma_table.gamma_22_table[brightness]); + break; + case 1: + _s6e63m0_gamma_ctl(lcd, gamma_table.gamma_19_table[brightness]); + break; + case 2: + _s6e63m0_gamma_ctl(lcd, gamma_table.gamma_17_table[brightness]); + break; + default: + dev_info(dev, "gamma mode could be 0:2.2, 1:1.9 or 2:1.7\n"); + _s6e63m0_gamma_ctl(lcd, gamma_table.gamma_22_table[brightness]); + break; + } + return len; +} + +static DEVICE_ATTR(gamma_mode, 0644, + s6e63m0_sysfs_show_gamma_mode, s6e63m0_sysfs_store_gamma_mode); + +static ssize_t s6e63m0_sysfs_show_gamma_table(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct s6e63m0 *lcd = dev_get_drvdata(dev); + char temp[3]; + + sprintf(temp, "%d\n", lcd->gamma_table_count); + strcpy(buf, temp); + + return strlen(buf); +} +static DEVICE_ATTR(gamma_table, 0644, + s6e63m0_sysfs_show_gamma_table, NULL); + +static int __init s6e63m0_probe(struct spi_device *spi) +{ + int ret = 0; + struct s6e63m0 *lcd = NULL; + struct lcd_device *ld = NULL; + struct backlight_device *bd = NULL; + + lcd = kzalloc(sizeof(struct s6e63m0), GFP_KERNEL); + if (!lcd) + return -ENOMEM; + + /* s6e63m0 lcd panel uses 3-wire 9bits SPI Mode. */ + spi->bits_per_word = 9; + + ret = spi_setup(spi); + if (ret < 0) { + dev_err(&spi->dev, "spi setup failed.\n"); + goto out_free_lcd; + } + + lcd->spi = spi; + lcd->dev = &spi->dev; + + lcd->lcd_pd = (struct lcd_platform_data *)spi->dev.platform_data; + if (!lcd->lcd_pd) { + dev_err(&spi->dev, "platform data is NULL.\n"); + goto out_free_lcd; + } + + ld = lcd_device_register("s6e63m0", &spi->dev, lcd, &s6e63m0_lcd_ops); + if (IS_ERR(ld)) { + ret = PTR_ERR(ld); + goto out_free_lcd; + } + + lcd->ld = ld; + + bd = backlight_device_register("s6e63m0bl-bl", &spi->dev, lcd, + &s6e63m0_backlight_ops, NULL); + if (IS_ERR(bd)) { + ret = PTR_ERR(bd); + goto out_lcd_unregister; + } + + bd->props.max_brightness = MAX_BRIGHTNESS; + bd->props.brightness = MAX_BRIGHTNESS; + lcd->bd = bd; + + /* + * it gets gamma table count available so it gets user + * know that. + */ + lcd->gamma_table_count = + sizeof(gamma_table) / (MAX_GAMMA_LEVEL * sizeof(int)); + + ret = device_create_file(&(spi->dev), &dev_attr_gamma_mode); + if (ret < 0) + dev_err(&(spi->dev), "failed to add sysfs entries\n"); + + ret = device_create_file(&(spi->dev), &dev_attr_gamma_table); + if (ret < 0) + dev_err(&(spi->dev), "failed to add sysfs entries\n"); + + /* + * if lcd panel was on from bootloader like u-boot then + * do not lcd on. + */ + if (!lcd->lcd_pd->lcd_enabled) { + /* + * if lcd panel was off from bootloader then + * current lcd status is powerdown and then + * it enables lcd panel. + */ + lcd->power = FB_BLANK_POWERDOWN; + + s6e63m0_power(lcd, FB_BLANK_UNBLANK); + } else + lcd->power = FB_BLANK_UNBLANK; + + dev_set_drvdata(&spi->dev, lcd); + + dev_info(&spi->dev, "s6e63m0 panel driver has been probed.\n"); + + return 0; + +out_lcd_unregister: + lcd_device_unregister(ld); +out_free_lcd: + kfree(lcd); + return ret; +} + +static int __devexit s6e63m0_remove(struct spi_device *spi) +{ + struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev); + + s6e63m0_power(lcd, FB_BLANK_POWERDOWN); + lcd_device_unregister(lcd->ld); + kfree(lcd); + + return 0; +} + +#if defined(CONFIG_PM) +unsigned int before_power; + +static int s6e63m0_suspend(struct spi_device *spi, pm_message_t mesg) +{ + int ret = 0; + struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev); + + dev_dbg(&spi->dev, "lcd->power = %d\n", lcd->power); + + before_power = lcd->power; + + /* + * when lcd panel is suspend, lcd panel becomes off + * regardless of status. + */ + ret = s6e63m0_power(lcd, FB_BLANK_POWERDOWN); + + return ret; +} + +static int s6e63m0_resume(struct spi_device *spi) +{ + int ret = 0; + struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev); + + /* + * after suspended, if lcd panel status is FB_BLANK_UNBLANK + * (at that time, before_power is FB_BLANK_UNBLANK) then + * it changes that status to FB_BLANK_POWERDOWN to get lcd on. + */ + if (before_power == FB_BLANK_UNBLANK) + lcd->power = FB_BLANK_POWERDOWN; + + dev_dbg(&spi->dev, "before_power = %d\n", before_power); + + ret = s6e63m0_power(lcd, before_power); + + return ret; +} +#else +#define s6e63m0_suspend NULL +#define s6e63m0_resume NULL +#endif + +/* Power down all displays on reboot, poweroff or halt. */ +static void s6e63m0_shutdown(struct spi_device *spi) +{ + struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev); + + s6e63m0_power(lcd, FB_BLANK_POWERDOWN); +} + +static struct spi_driver s6e63m0_driver = { + .driver = { + .name = "s6e63m0", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = s6e63m0_probe, + .remove = __devexit_p(s6e63m0_remove), + .shutdown = s6e63m0_shutdown, + .suspend = s6e63m0_suspend, + .resume = s6e63m0_resume, +}; + +static int __init s6e63m0_init(void) +{ + return spi_register_driver(&s6e63m0_driver); +} + +static void __exit s6e63m0_exit(void) +{ + spi_unregister_driver(&s6e63m0_driver); +} + +module_init(s6e63m0_init); +module_exit(s6e63m0_exit); + +MODULE_AUTHOR("InKi Dae "); +MODULE_DESCRIPTION("S6E63M0 LCD Driver"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/video/backlight/s6e63m0_gamma.h b/drivers/video/backlight/s6e63m0_gamma.h new file mode 100644 index 000000000000..2c44bdb0696b --- /dev/null +++ b/drivers/video/backlight/s6e63m0_gamma.h @@ -0,0 +1,266 @@ +/* linux/drivers/video/samsung/s6e63m0_brightness.h + * + * Gamma level definitions. + * + * Copyright (c) 2009 Samsung Electronics + * InKi Dae + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef _S6E63M0_BRIGHTNESS_H +#define _S6E63M0_BRIGHTNESS_H + +#define MAX_GAMMA_LEVEL 11 +#define GAMMA_TABLE_COUNT 21 + +/* gamma value: 2.2 */ +static const unsigned int s6e63m0_22_300[] = { + 0x18, 0x08, 0x24, 0x5f, 0x50, 0x2d, 0xB6, + 0xB9, 0xA7, 0xAd, 0xB1, 0x9f, 0xbe, 0xC0, + 0xB5, 0x00, 0xa0, 0x00, 0xa4, 0x00, 0xdb +}; + +static const unsigned int s6e63m0_22_280[] = { + 0x18, 0x08, 0x24, 0x64, 0x56, 0x33, 0xB6, + 0xBA, 0xA8, 0xAC, 0xB1, 0x9D, 0xC1, 0xC1, + 0xB7, 0x00, 0x9C, 0x00, 0x9F, 0x00, 0xD6 +}; + +static const unsigned int s6e63m0_22_260[] = { + 0x18, 0x08, 0x24, 0x66, 0x58, 0x34, 0xB6, + 0xBA, 0xA7, 0xAF, 0xB3, 0xA0, 0xC1, 0xC2, + 0xB7, 0x00, 0x97, 0x00, 0x9A, 0x00, 0xD1 + +}; + +static const unsigned int s6e63m0_22_240[] = { + 0x18, 0x08, 0x24, 0x62, 0x54, 0x30, 0xB9, + 0xBB, 0xA9, 0xB0, 0xB3, 0xA1, 0xC1, 0xC3, + 0xB7, 0x00, 0x91, 0x00, 0x95, 0x00, 0xDA + +}; +static const unsigned int s6e63m0_22_220[] = { + 0x18, 0x08, 0x24, 0x63, 0x53, 0x31, 0xB8, + 0xBC, 0xA9, 0xB0, 0xB5, 0xA2, 0xC4, 0xC4, + 0xB8, 0x00, 0x8B, 0x00, 0x8E, 0x00, 0xC2 +}; + +static const unsigned int s6e63m0_22_200[] = { + 0x18, 0x08, 0x24, 0x66, 0x55, 0x34, 0xBA, + 0xBD, 0xAB, 0xB1, 0xB5, 0xA3, 0xC5, 0xC6, + 0xB9, 0x00, 0x85, 0x00, 0x88, 0x00, 0xBA +}; + +static const unsigned int s6e63m0_22_170[] = { + 0x18, 0x08, 0x24, 0x69, 0x54, 0x37, 0xBB, + 0xBE, 0xAC, 0xB4, 0xB7, 0xA6, 0xC7, 0xC8, + 0xBC, 0x00, 0x7B, 0x00, 0x7E, 0x00, 0xAB +}; + +static const unsigned int s6e63m0_22_140[] = { + 0x18, 0x08, 0x24, 0x6C, 0x54, 0x3A, 0xBC, + 0xBF, 0xAC, 0xB7, 0xBB, 0xA9, 0xC9, 0xC9, + 0xBE, 0x00, 0x71, 0x00, 0x73, 0x00, 0x9E +}; + +static const unsigned int s6e63m0_22_110[] = { + 0x18, 0x08, 0x24, 0x70, 0x51, 0x3E, 0xBF, + 0xC1, 0xAF, 0xB9, 0xBC, 0xAB, 0xCC, 0xCC, + 0xC2, 0x00, 0x65, 0x00, 0x67, 0x00, 0x8D +}; + +static const unsigned int s6e63m0_22_90[] = { + 0x18, 0x08, 0x24, 0x73, 0x4A, 0x3D, 0xC0, + 0xC2, 0xB1, 0xBB, 0xBE, 0xAC, 0xCE, 0xCF, + 0xC5, 0x00, 0x5D, 0x00, 0x5E, 0x00, 0x82 +}; + +static const unsigned int s6e63m0_22_30[] = { + 0x18, 0x08, 0x24, 0x78, 0xEC, 0x3D, 0xC8, + 0xC2, 0xB6, 0xC4, 0xC7, 0xB6, 0xD5, 0xD7, + 0xCC, 0x00, 0x39, 0x00, 0x36, 0x00, 0x51 +}; + +/* gamma value: 1.9 */ +static const unsigned int s6e63m0_19_300[] = { + 0x18, 0x08, 0x24, 0x61, 0x5F, 0x39, 0xBA, + 0xBD, 0xAD, 0xB1, 0xB6, 0xA5, 0xC4, 0xC5, + 0xBC, 0x00, 0xA0, 0x00, 0xA4, 0x00, 0xDB +}; + +static const unsigned int s6e63m0_19_280[] = { + 0x18, 0x08, 0x24, 0x61, 0x60, 0x39, 0xBB, + 0xBE, 0xAD, 0xB2, 0xB6, 0xA6, 0xC5, 0xC7, + 0xBD, 0x00, 0x9B, 0x00, 0x9E, 0x00, 0xD5 +}; + +static const unsigned int s6e63m0_19_260[] = { + 0x18, 0x08, 0x24, 0x63, 0x61, 0x3B, 0xBA, + 0xBE, 0xAC, 0xB3, 0xB8, 0xA7, 0xC6, 0xC8, + 0xBD, 0x00, 0x96, 0x00, 0x98, 0x00, 0xCF +}; + +static const unsigned int s6e63m0_19_240[] = { + 0x18, 0x08, 0x24, 0x67, 0x64, 0x3F, 0xBB, + 0xBE, 0xAD, 0xB3, 0xB9, 0xA7, 0xC8, 0xC9, + 0xBE, 0x00, 0x90, 0x00, 0x92, 0x00, 0xC8 +}; + +static const unsigned int s6e63m0_19_220[] = { + 0x18, 0x08, 0x24, 0x68, 0x64, 0x40, 0xBC, + 0xBF, 0xAF, 0xB4, 0xBA, 0xA9, 0xC8, 0xCA, + 0xBE, 0x00, 0x8B, 0x00, 0x8C, 0x00, 0xC0 +}; + +static const unsigned int s6e63m0_19_200[] = { + 0x18, 0x08, 0x24, 0x68, 0x64, 0x3F, 0xBE, + 0xC0, 0xB0, 0xB6, 0xBB, 0xAB, 0xC8, 0xCB, + 0xBF, 0x00, 0x85, 0x00, 0x86, 0x00, 0xB8 +}; + +static const unsigned int s6e63m0_19_170[] = { + 0x18, 0x08, 0x24, 0x69, 0x64, 0x40, 0xBF, + 0xC1, 0xB0, 0xB9, 0xBE, 0xAD, 0xCB, 0xCD, + 0xC2, 0x00, 0x7A, 0x00, 0x7B, 0x00, 0xAA +}; + +static const unsigned int s6e63m0_19_140[] = { + 0x18, 0x08, 0x24, 0x6E, 0x65, 0x45, 0xC0, + 0xC3, 0xB2, 0xBA, 0xBE, 0xAE, 0xCD, 0xD0, + 0xC4, 0x00, 0x70, 0x00, 0x70, 0x00, 0x9C +}; + +static const unsigned int s6e63m0_19_110[] = { + 0x18, 0x08, 0x24, 0x6F, 0x65, 0x46, 0xC2, + 0xC4, 0xB3, 0xBF, 0xC2, 0xB2, 0xCF, 0xD1, + 0xC6, 0x00, 0x64, 0x00, 0x64, 0x00, 0x8D +}; + +static const unsigned int s6e63m0_19_90[] = { + 0x18, 0x08, 0x24, 0x74, 0x60, 0x4A, 0xC3, + 0xC6, 0xB5, 0xBF, 0xC3, 0xB2, 0xD2, 0xD3, + 0xC8, 0x00, 0x5B, 0x00, 0x5B, 0x00, 0x81 +}; + +static const unsigned int s6e63m0_19_30[] = { + 0x18, 0x08, 0x24, 0x84, 0x45, 0x4F, 0xCA, + 0xCB, 0xBC, 0xC9, 0xCB, 0xBC, 0xDA, 0xDA, + 0xD0, 0x00, 0x35, 0x00, 0x34, 0x00, 0x4E +}; + +/* gamma value: 1.7 */ +static const unsigned int s6e63m0_17_300[] = { + 0x18, 0x08, 0x24, 0x70, 0x70, 0x4F, 0xBF, + 0xC2, 0xB2, 0xB8, 0xBC, 0xAC, 0xCB, 0xCD, + 0xC3, 0x00, 0xA0, 0x00, 0xA4, 0x00, 0xDB +}; + +static const unsigned int s6e63m0_17_280[] = { + 0x18, 0x08, 0x24, 0x71, 0x71, 0x50, 0xBF, + 0xC2, 0xB2, 0xBA, 0xBE, 0xAE, 0xCB, 0xCD, + 0xC3, 0x00, 0x9C, 0x00, 0x9F, 0x00, 0xD6 +}; + +static const unsigned int s6e63m0_17_260[] = { + 0x18, 0x08, 0x24, 0x72, 0x72, 0x50, 0xC0, + 0xC3, 0xB4, 0xB9, 0xBE, 0xAE, 0xCC, 0xCF, + 0xC4, 0x00, 0x97, 0x00, 0x9A, 0x00, 0xD1 +}; + +static const unsigned int s6e63m0_17_240[] = { + 0x18, 0x08, 0x24, 0x71, 0x72, 0x4F, 0xC2, + 0xC4, 0xB5, 0xBB, 0xBF, 0xB0, 0xCC, 0xCF, + 0xC3, 0x00, 0x91, 0x00, 0x95, 0x00, 0xCA +}; + +static const unsigned int s6e63m0_17_220[] = { + 0x18, 0x08, 0x24, 0x71, 0x73, 0x4F, 0xC2, + 0xC5, 0xB5, 0xBD, 0xC0, 0xB2, 0xCD, 0xD1, + 0xC5, 0x00, 0x8B, 0x00, 0x8E, 0x00, 0xC2 +}; + +static const unsigned int s6e63m0_17_200[] = { + 0x18, 0x08, 0x24, 0x72, 0x75, 0x51, 0xC2, + 0xC6, 0xB5, 0xBF, 0xC1, 0xB3, 0xCE, 0xD1, + 0xC6, 0x00, 0x85, 0x00, 0x88, 0x00, 0xBA +}; + +static const unsigned int s6e63m0_17_170[] = { + 0x18, 0x08, 0x24, 0x75, 0x77, 0x54, 0xC3, + 0xC7, 0xB7, 0xC0, 0xC3, 0xB4, 0xD1, 0xD3, + 0xC9, 0x00, 0x7B, 0x00, 0x7E, 0x00, 0xAB +}; + +static const unsigned int s6e63m0_17_140[] = { + 0x18, 0x08, 0x24, 0x7B, 0x77, 0x58, 0xC3, + 0xC8, 0xB8, 0xC2, 0xC6, 0xB6, 0xD3, 0xD4, + 0xCA, 0x00, 0x71, 0x00, 0x73, 0x00, 0x9E +}; + +static const unsigned int s6e63m0_17_110[] = { + 0x18, 0x08, 0x24, 0x81, 0x7B, 0x5D, 0xC6, + 0xCA, 0xBB, 0xC3, 0xC7, 0xB8, 0xD6, 0xD8, + 0xCD, 0x00, 0x65, 0x00, 0x67, 0x00, 0x8D +}; + +static const unsigned int s6e63m0_17_90[] = { + 0x18, 0x08, 0x24, 0x82, 0x7A, 0x5B, 0xC8, + 0xCB, 0xBD, 0xC5, 0xCA, 0xBA, 0xD6, 0xD8, + 0xCE, 0x00, 0x5D, 0x00, 0x5E, 0x00, 0x82 +}; + +static const unsigned int s6e63m0_17_30[] = { + 0x18, 0x08, 0x24, 0x8F, 0x73, 0x63, 0xD1, + 0xD0, 0xC5, 0xCC, 0xD1, 0xC2, 0xDE, 0xE0, + 0xD6, 0x00, 0x39, 0x00, 0x36, 0x00, 0x51 +}; + +struct s6e63m0_gamma { + unsigned int *gamma_22_table[MAX_GAMMA_LEVEL]; + unsigned int *gamma_19_table[MAX_GAMMA_LEVEL]; + unsigned int *gamma_17_table[MAX_GAMMA_LEVEL]; +}; + +static struct s6e63m0_gamma gamma_table = { + .gamma_22_table[0] = (unsigned int *)&s6e63m0_22_30, + .gamma_22_table[1] = (unsigned int *)&s6e63m0_22_90, + .gamma_22_table[2] = (unsigned int *)&s6e63m0_22_110, + .gamma_22_table[3] = (unsigned int *)&s6e63m0_22_140, + .gamma_22_table[4] = (unsigned int *)&s6e63m0_22_170, + .gamma_22_table[5] = (unsigned int *)&s6e63m0_22_200, + .gamma_22_table[6] = (unsigned int *)&s6e63m0_22_220, + .gamma_22_table[7] = (unsigned int *)&s6e63m0_22_240, + .gamma_22_table[8] = (unsigned int *)&s6e63m0_22_260, + .gamma_22_table[9] = (unsigned int *)&s6e63m0_22_280, + .gamma_22_table[10] = (unsigned int *)&s6e63m0_22_300, + + .gamma_19_table[0] = (unsigned int *)&s6e63m0_19_30, + .gamma_19_table[1] = (unsigned int *)&s6e63m0_19_90, + .gamma_19_table[2] = (unsigned int *)&s6e63m0_19_110, + .gamma_19_table[3] = (unsigned int *)&s6e63m0_19_140, + .gamma_19_table[4] = (unsigned int *)&s6e63m0_19_170, + .gamma_19_table[5] = (unsigned int *)&s6e63m0_19_200, + .gamma_19_table[6] = (unsigned int *)&s6e63m0_19_220, + .gamma_19_table[7] = (unsigned int *)&s6e63m0_19_240, + .gamma_19_table[8] = (unsigned int *)&s6e63m0_19_260, + .gamma_19_table[9] = (unsigned int *)&s6e63m0_19_280, + .gamma_19_table[10] = (unsigned int *)&s6e63m0_19_300, + + .gamma_17_table[0] = (unsigned int *)&s6e63m0_17_30, + .gamma_17_table[1] = (unsigned int *)&s6e63m0_17_90, + .gamma_17_table[2] = (unsigned int *)&s6e63m0_17_110, + .gamma_17_table[3] = (unsigned int *)&s6e63m0_17_140, + .gamma_17_table[4] = (unsigned int *)&s6e63m0_17_170, + .gamma_17_table[5] = (unsigned int *)&s6e63m0_17_200, + .gamma_17_table[6] = (unsigned int *)&s6e63m0_17_220, + .gamma_17_table[7] = (unsigned int *)&s6e63m0_17_240, + .gamma_17_table[8] = (unsigned int *)&s6e63m0_17_260, + .gamma_17_table[9] = (unsigned int *)&s6e63m0_17_280, + .gamma_17_table[10] = (unsigned int *)&s6e63m0_17_300, +}; + +#endif + diff --git a/include/linux/lcd.h b/include/linux/lcd.h index c67fecafff90..8877123f2d6e 100644 --- a/include/linux/lcd.h +++ b/include/linux/lcd.h @@ -69,6 +69,29 @@ struct lcd_device { struct device dev; }; +struct lcd_platform_data { + /* reset lcd panel device. */ + int (*reset)(struct lcd_device *ld); + /* on or off to lcd panel. if 'enable' is 0 then + lcd power off and 1, lcd power on. */ + int (*power_on)(struct lcd_device *ld, int enable); + + /* it indicates whether lcd panel was enabled + from bootloader or not. */ + int lcd_enabled; + /* it means delay for stable time when it becomes low to high + or high to low that is dependent on whether reset gpio is + low active or high active. */ + unsigned int reset_delay; + /* stable time needing to become lcd power on. */ + unsigned int power_on_delay; + /* stable time needing to become lcd power off. */ + unsigned int power_off_delay; + + /* it could be used for any purpose. */ + void *pdata; +}; + static inline void lcd_set_power(struct lcd_device *ld, int power) { mutex_lock(&ld->update_lock); -- cgit v1.2.3 From beb0a43f398efac87a3b9c2c6a5c5a163df50413 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 3 May 2010 14:42:44 +0800 Subject: backlight: l4f00242t03: fix error handling in l4f00242t03_probe Error handling fixes: 1. In the case of kzalloc failure, simple return -ENOMEM instead of goto err. ( priv is NULL in this case ) 2. In the case of gpio_request fail for reset_gpio and data_enable_gpio, properly release resources by goto err and err2 respectively. Signed-off-by: Axel Lin Acked-by: Alberto Panizzo Signed-off-by: Richard Purdie --- drivers/video/backlight/l4f00242t03.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c index 1dafec85ddc0..9093ef0fa869 100644 --- a/drivers/video/backlight/l4f00242t03.c +++ b/drivers/video/backlight/l4f00242t03.c @@ -125,8 +125,7 @@ static int __devinit l4f00242t03_probe(struct spi_device *spi) if (priv == NULL) { dev_err(&spi->dev, "No memory for this device.\n"); - ret = -ENOMEM; - goto err; + return -ENOMEM; } dev_set_drvdata(&spi->dev, priv); @@ -139,7 +138,7 @@ static int __devinit l4f00242t03_probe(struct spi_device *spi) if (ret) { dev_err(&spi->dev, "Unable to get the lcd l4f00242t03 reset gpio.\n"); - return ret; + goto err; } ret = gpio_direction_output(pdata->reset_gpio, 1); @@ -151,7 +150,7 @@ static int __devinit l4f00242t03_probe(struct spi_device *spi) if (ret) { dev_err(&spi->dev, "Unable to get the lcd l4f00242t03 data en gpio.\n"); - return ret; + goto err2; } ret = gpio_direction_output(pdata->data_enable_gpio, 0); -- cgit v1.2.3 From 146e10a8c457236e017355ed9ba0ef78fbb3d12b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 10 May 2010 09:27:34 +0800 Subject: backlight: max8925_bl: Fix error handling path Properly unregister a previously registered backlight device object in error handling of max8925_backlight_probe. Signed-off-by: Axel Lin Signed-off-by: Richard Purdie --- drivers/video/backlight/max8925_bl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c index b5accc957ad3..b2b2c7ba1f63 100644 --- a/drivers/video/backlight/max8925_bl.c +++ b/drivers/video/backlight/max8925_bl.c @@ -162,6 +162,7 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev) backlight_update_status(bl); return 0; out: + backlight_device_unregister(bl); kfree(data); return ret; } -- cgit v1.2.3 From 1f976996c7413b5b48d35b195cc2d7adcd3f68d7 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 10 May 2010 09:29:58 +0800 Subject: backlight: 88pm860x_bl: fix error handling in pm860x_backlight_probe This patch properly unregisters a previously registered backlight device object in error handling Signed-off-by: Axel Lin Signed-off-by: Richard Purdie --- drivers/video/backlight/88pm860x_bl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c index 78d8fde9fe8f..38ffc3fbcbe4 100644 --- a/drivers/video/backlight/88pm860x_bl.c +++ b/drivers/video/backlight/88pm860x_bl.c @@ -267,6 +267,7 @@ static int pm860x_backlight_probe(struct platform_device *pdev) backlight_update_status(bl); return 0; out: + backlight_device_unregister(bl); kfree(data); return ret; } -- cgit v1.2.3 From 2ddfd12f3584840f5190897214423061d8a0602f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 12 May 2010 02:44:32 +0200 Subject: backlight: Add pcf50633 backlight driver This patch adds a backlight driver for controlling the pcf50633 LED module. Signed-off-by: Lars-Peter Clausen Acked-by: Samuel Ortiz Signed-off-by: Richard Purdie --- drivers/video/backlight/Kconfig | 7 + drivers/video/backlight/Makefile | 1 + drivers/video/backlight/pcf50633-backlight.c | 190 +++++++++++++++++++++++++++ include/linux/mfd/pcf50633/backlight.h | 51 +++++++ 4 files changed, 249 insertions(+) create mode 100644 drivers/video/backlight/pcf50633-backlight.c create mode 100644 include/linux/mfd/pcf50633/backlight.h (limited to 'drivers') diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index cbd80978460e..e54a337227ea 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -300,6 +300,13 @@ config BACKLIGHT_88PM860X help Say Y to enable the backlight driver for Marvell 88PM8606. +config BACKLIGHT_PCF50633 + tristate "Backlight driver for NXP PCF50633 MFD" + depends on BACKLIGHT_CLASS_DEVICE && MFD_PCF50633 + help + If you have a backlight driven by a NXP PCF50633 MFD, say Y here to + enable its driver. + endif # BACKLIGHT_CLASS_DEVICE endif # BACKLIGHT_LCD_SUPPORT diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index f8978c0a2319..44c0f81ad85d 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -34,4 +34,5 @@ obj-$(CONFIG_BACKLIGHT_ADX) += adx_bl.o obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o +obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o diff --git a/drivers/video/backlight/pcf50633-backlight.c b/drivers/video/backlight/pcf50633-backlight.c new file mode 100644 index 000000000000..3c424f7efdcc --- /dev/null +++ b/drivers/video/backlight/pcf50633-backlight.c @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2009-2010, Lars-Peter Clausen + * PCF50633 backlight device driver + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include + +struct pcf50633_bl { + struct pcf50633 *pcf; + struct backlight_device *bl; + + unsigned int brightness; + unsigned int brightness_limit; +}; + +/* + * pcf50633_bl_set_brightness_limit + * + * Update the brightness limit for the pc50633 backlight. The actual brightness + * will not go above the limit. This is useful to limit power drain for example + * on low battery. + * + * @dev: Pointer to a pcf50633 device + * @limit: The brightness limit. Valid values are 0-63 + */ +int pcf50633_bl_set_brightness_limit(struct pcf50633 *pcf, unsigned int limit) +{ + struct pcf50633_bl *pcf_bl = platform_get_drvdata(pcf->bl_pdev); + + if (!pcf_bl) + return -ENODEV; + + pcf_bl->brightness_limit = limit & 0x3f; + backlight_update_status(pcf_bl->bl); + + return 0; +} + +static int pcf50633_bl_update_status(struct backlight_device *bl) +{ + struct pcf50633_bl *pcf_bl = bl_get_data(bl); + unsigned int new_brightness; + + + if (bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK) || + bl->props.power != FB_BLANK_UNBLANK) + new_brightness = 0; + else if (bl->props.brightness < pcf_bl->brightness_limit) + new_brightness = bl->props.brightness; + else + new_brightness = pcf_bl->brightness_limit; + + + if (pcf_bl->brightness == new_brightness) + return 0; + + if (new_brightness) { + pcf50633_reg_write(pcf_bl->pcf, PCF50633_REG_LEDOUT, + new_brightness); + if (!pcf_bl->brightness) + pcf50633_reg_write(pcf_bl->pcf, PCF50633_REG_LEDENA, 1); + } else { + pcf50633_reg_write(pcf_bl->pcf, PCF50633_REG_LEDENA, 0); + } + + pcf_bl->brightness = new_brightness; + + return 0; +} + +static int pcf50633_bl_get_brightness(struct backlight_device *bl) +{ + struct pcf50633_bl *pcf_bl = bl_get_data(bl); + return pcf_bl->brightness; +} + +static const struct backlight_ops pcf50633_bl_ops = { + .get_brightness = pcf50633_bl_get_brightness, + .update_status = pcf50633_bl_update_status, + .options = BL_CORE_SUSPENDRESUME, +}; + +static int __devinit pcf50633_bl_probe(struct platform_device *pdev) +{ + int ret; + struct pcf50633_bl *pcf_bl; + struct device *parent = pdev->dev.parent; + struct pcf50633_platform_data *pcf50633_data = parent->platform_data; + struct pcf50633_bl_platform_data *pdata = pcf50633_data->backlight_data; + struct backlight_properties bl_props; + + pcf_bl = kzalloc(sizeof(*pcf_bl), GFP_KERNEL); + if (!pcf_bl) + return -ENOMEM; + + bl_props.max_brightness = 0x3f; + bl_props.power = FB_BLANK_UNBLANK; + + if (pdata) { + bl_props.brightness = pdata->default_brightness; + pcf_bl->brightness_limit = pdata->default_brightness_limit; + } else { + bl_props.brightness = 0x3f; + pcf_bl->brightness_limit = 0x3f; + } + + pcf_bl->pcf = dev_to_pcf50633(pdev->dev.parent); + + pcf_bl->bl = backlight_device_register(pdev->name, &pdev->dev, pcf_bl, + &pcf50633_bl_ops, &bl_props); + + if (IS_ERR(pcf_bl->bl)) { + ret = PTR_ERR(pcf_bl->bl); + goto err_free; + } + + platform_set_drvdata(pdev, pcf_bl); + + pcf50633_reg_write(pcf_bl->pcf, PCF50633_REG_LEDDIM, pdata->ramp_time); + + /* Should be different from bl_props.brightness, so we do not exit + * update_status early the first time it's called */ + pcf_bl->brightness = pcf_bl->bl->props.brightness + 1; + + backlight_update_status(pcf_bl->bl); + + return 0; + +err_free: + kfree(pcf_bl); + + return ret; +} + +static int __devexit pcf50633_bl_remove(struct platform_device *pdev) +{ + struct pcf50633_bl *pcf_bl = platform_get_drvdata(pdev); + + backlight_device_unregister(pcf_bl->bl); + + platform_set_drvdata(pdev, NULL); + + kfree(pcf_bl); + + return 0; +} + +static struct platform_driver pcf50633_bl_driver = { + .probe = pcf50633_bl_probe, + .remove = __devexit_p(pcf50633_bl_remove), + .driver = { + .name = "pcf50633-backlight", + }, +}; + +static int __init pcf50633_bl_init(void) +{ + return platform_driver_register(&pcf50633_bl_driver); +} +module_init(pcf50633_bl_init); + +static void __exit pcf50633_bl_exit(void) +{ + platform_driver_unregister(&pcf50633_bl_driver); +} +module_exit(pcf50633_bl_exit); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("PCF50633 backlight driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:pcf50633-backlight"); diff --git a/include/linux/mfd/pcf50633/backlight.h b/include/linux/mfd/pcf50633/backlight.h new file mode 100644 index 000000000000..83747e217b27 --- /dev/null +++ b/include/linux/mfd/pcf50633/backlight.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2009-2010, Lars-Peter Clausen + * PCF50633 backlight device driver + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef __LINUX_MFD_PCF50633_BACKLIGHT +#define __LINUX_MFD_PCF50633_BACKLIGHT + +/* +* @default_brightness: Backlight brightness is initialized to this value +* +* Brightness to be used after the driver has been probed. +* Valid range 0-63. +* +* @default_brightness_limit: The actual brightness is limited by this value +* +* Brightness limit to be used after the driver has been probed. This is useful +* when it is not known how much power is available for the backlight during +* probe. +* Valid range 0-63. Can be changed later with pcf50633_bl_set_brightness_limit. +* +* @ramp_time: Display ramp time when changing brightness +* +* When changing the backlights brightness the change is not instant, instead +* it fades smooth from one state to another. This value specifies how long +* the fade should take. The lower the value the higher the fade time. +* Valid range 0-255 +*/ +struct pcf50633_bl_platform_data { + unsigned int default_brightness; + unsigned int default_brightness_limit; + uint8_t ramp_time; +}; + + +struct pcf50633; + +int pcf50633_bl_set_brightness_limit(struct pcf50633 *pcf, unsigned int limit); + +#endif + -- cgit v1.2.3 From f5bf403a9dc944bf560f49dd029195e54fcbc41c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 12 May 2010 02:44:33 +0200 Subject: backlight: pcf50633: Register a pcf50633-backlight device in pcf50633 core driver. Register a device newly added pcf50633-backlight driver as a child device in the pcf50633 core driver. Signed-off-by: Lars-Peter Clausen Acked-by: Samuel Ortiz Signed-off-by: Richard Purdie --- drivers/mfd/pcf50633-core.c | 3 +++ include/linux/mfd/pcf50633/core.h | 4 ++++ 2 files changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 63a614d696c1..dc95ddb708f1 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -620,6 +620,9 @@ static int __devinit pcf50633_probe(struct i2c_client *client, &pcf->mbc_pdev); pcf50633_client_dev_register(pcf, "pcf50633-adc", &pcf->adc_pdev); + pcf50633_client_dev_register(pcf, "pcf50633-backlight", + &pcf->bl_pdev); + for (i = 0; i < PCF50633_NUM_REGULATORS; i++) { struct platform_device *pdev; diff --git a/include/linux/mfd/pcf50633/core.h b/include/linux/mfd/pcf50633/core.h index 3398bd9aab11..ad411a78870c 100644 --- a/include/linux/mfd/pcf50633/core.h +++ b/include/linux/mfd/pcf50633/core.h @@ -18,6 +18,7 @@ #include #include #include +#include struct pcf50633; @@ -43,6 +44,8 @@ struct pcf50633_platform_data { void (*force_shutdown)(struct pcf50633 *); u8 resumers[5]; + + struct pcf50633_bl_platform_data *backlight_data; }; struct pcf50633_irq { @@ -152,6 +155,7 @@ struct pcf50633 { struct platform_device *mbc_pdev; struct platform_device *adc_pdev; struct platform_device *input_pdev; + struct platform_device *bl_pdev; struct platform_device *regulator_pdev[PCF50633_NUM_REGULATORS]; }; -- cgit v1.2.3 From 6869b15efccce954a28d14c84b25350d125e2f93 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 17 May 2009 12:17:28 +0200 Subject: m68k/scsi: gvp11 - Kill ugly DMA() macro Acked-by: James Bottomley Signed-off-by: Geert Uytterhoeven --- drivers/scsi/gvp11.c | 52 ++++++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c index 18b7102bb80e..777972e6bbf3 100644 --- a/drivers/scsi/gvp11.c +++ b/drivers/scsi/gvp11.c @@ -22,15 +22,13 @@ #include -#define DMA(ptr) ((gvp11_scsiregs *)((ptr)->base)) - -static irqreturn_t gvp11_intr(int irq, void *_instance) +static irqreturn_t gvp11_intr(int irq, void *data) { + struct Scsi_Host *instance = data; + gvp11_scsiregs *regs = (gvp11_scsiregs *)(instance->base); + unsigned int status = regs->CNTR; unsigned long flags; - unsigned int status; - struct Scsi_Host *instance = (struct Scsi_Host *)_instance; - status = DMA(instance)->CNTR; if (!(status & GVP11_DMAC_INT_PENDING)) return IRQ_NONE; @@ -51,6 +49,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) { struct Scsi_Host *instance = cmd->device->host; struct WD33C93_hostdata *hdata = shost_priv(instance); + gvp11_scsiregs *regs = (gvp11_scsiregs *)(instance->base); unsigned short cntr = GVP11_DMAC_INT_ENABLE; unsigned long addr = virt_to_bus(cmd->SCp.ptr); int bank_mask; @@ -117,10 +116,10 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) cntr |= GVP11_DMAC_DIR_WRITE; hdata->dma_dir = dir_in; - DMA(cmd->device->host)->CNTR = cntr; + regs->CNTR = cntr; /* setup DMA *physical* address */ - DMA(cmd->device->host)->ACR = addr; + regs->ACR = addr; if (dir_in) { /* invalidate any cache */ @@ -132,10 +131,10 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) bank_mask = (~hdata->dma_xfer_mask >> 18) & 0x01c0; if (bank_mask) - DMA(cmd->device->host)->BANK = bank_mask & (addr >> 18); + regs->BANK = bank_mask & (addr >> 18); /* start DMA */ - DMA(cmd->device->host)->ST_DMA = 1; + regs->ST_DMA = 1; /* return success */ return 0; @@ -144,12 +143,13 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, int status) { + gvp11_scsiregs *regs = (gvp11_scsiregs *)(instance->base); struct WD33C93_hostdata *hdata = shost_priv(instance); /* stop DMA */ - DMA(instance)->SP_DMA = 1; + regs->SP_DMA = 1; /* remove write bit from CONTROL bits */ - DMA(instance)->CNTR = GVP11_DMAC_INT_ENABLE; + regs->CNTR = GVP11_DMAC_INT_ENABLE; /* copy from a bounce buffer, if necessary */ if (status && hdata->dma_bounce_buffer) { @@ -178,7 +178,8 @@ int __init gvp11_detect(struct scsi_host_template *tpnt) struct zorro_dev *z = NULL; unsigned int default_dma_xfer_mask; struct WD33C93_hostdata *hdata; - wd33c93_regs regs; + gvp11_scsiregs *regs; + wd33c93_regs wdregs; int num_gvp11 = 0; #ifdef CHECK_WD33C93 volatile unsigned char *sasr_3393, *scmd_3393; @@ -310,33 +311,34 @@ int __init gvp11_detect(struct scsi_host_template *tpnt) else hdata->dma_xfer_mask = default_dma_xfer_mask; - DMA(instance)->secret2 = 1; - DMA(instance)->secret1 = 0; - DMA(instance)->secret3 = 15; - while (DMA(instance)->CNTR & GVP11_DMAC_BUSY) + regs = (gvp11_scsiregs *)(instance->base); + regs->secret2 = 1; + regs->secret1 = 0; + regs->secret3 = 15; + while (regs->CNTR & GVP11_DMAC_BUSY) ; - DMA(instance)->CNTR = 0; + regs->CNTR = 0; - DMA(instance)->BANK = 0; + regs->BANK = 0; epc = *(unsigned short *)(ZTWO_VADDR(address) + 0x8000); /* * Check for 14MHz SCSI clock */ - regs.SASR = &(DMA(instance)->SASR); - regs.SCMD = &(DMA(instance)->SCMD); + wdregs.SASR = ®s->SASR; + wdregs.SCMD = ®s->SCMD; hdata->no_sync = 0xff; hdata->fast = 0; hdata->dma_mode = CTRL_DMA; - wd33c93_init(instance, regs, dma_setup, dma_stop, + wd33c93_init(instance, wdregs, dma_setup, dma_stop, (epc & GVP_SCSICLKMASK) ? WD33C93_FS_8_10 : WD33C93_FS_12_15); if (request_irq(IRQ_AMIGA_PORTS, gvp11_intr, IRQF_SHARED, "GVP11 SCSI", instance)) goto unregister; - DMA(instance)->CNTR = GVP11_DMAC_INT_ENABLE; + regs->CNTR = GVP11_DMAC_INT_ENABLE; num_gvp11++; continue; @@ -391,7 +393,9 @@ static struct scsi_host_template driver_template = { int gvp11_release(struct Scsi_Host *instance) { #ifdef MODULE - DMA(instance)->CNTR = 0; + gvp11_scsiregs *regs = (gvp11_scsiregs *)(instance->base); + + regs->CNTR = 0; release_mem_region(ZTWO_PADDR(instance->base), 256); free_irq(IRQ_AMIGA_PORTS, instance); #endif -- cgit v1.2.3 From d753722ee0223f80e6d0a553c68583c6ae57c1b2 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 17 May 2009 12:17:23 +0200 Subject: m68k/scsi: a3000 - Kill ugly DMA() macro Acked-by: James Bottomley Signed-off-by: Geert Uytterhoeven --- drivers/scsi/a3000.c | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c index bc6eb69f5fd0..ae9b25a3e3e7 100644 --- a/drivers/scsi/a3000.c +++ b/drivers/scsi/a3000.c @@ -22,16 +22,15 @@ #include -#define DMA(ptr) ((a3000_scsiregs *)((ptr)->base)) - static struct Scsi_Host *a3000_host = NULL; static int a3000_release(struct Scsi_Host *instance); static irqreturn_t a3000_intr(int irq, void *dummy) { + a3000_scsiregs *regs = (a3000_scsiregs *)(a3000_host->base); + unsigned int status = regs->ISTR; unsigned long flags; - unsigned int status = DMA(a3000_host)->ISTR; if (!(status & ISTR_INT_P)) return IRQ_NONE; @@ -48,6 +47,7 @@ static irqreturn_t a3000_intr(int irq, void *dummy) static int dma_setup(struct scsi_cmnd *cmd, int dir_in) { struct WD33C93_hostdata *hdata = shost_priv(a3000_host); + a3000_scsiregs *regs = (a3000_scsiregs *)(a3000_host->base); unsigned short cntr = CNTR_PDMD | CNTR_INTEN; unsigned long addr = virt_to_bus(cmd->SCp.ptr); @@ -84,10 +84,10 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) /* remember direction */ hdata->dma_dir = dir_in; - DMA(a3000_host)->CNTR = cntr; + regs->CNTR = cntr; /* setup DMA *physical* address */ - DMA(a3000_host)->ACR = addr; + regs->ACR = addr; if (dir_in) { /* invalidate any cache */ @@ -99,7 +99,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) /* start DMA */ mb(); /* make sure setup is completed */ - DMA(a3000_host)->ST_DMA = 1; + regs->ST_DMA = 1; mb(); /* make sure DMA has started before next IO */ /* return success */ @@ -110,6 +110,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, int status) { struct WD33C93_hostdata *hdata = shost_priv(instance); + a3000_scsiregs *regs = (a3000_scsiregs *)(instance->base); /* disable SCSI interrupts */ unsigned short cntr = CNTR_PDMD; @@ -117,14 +118,14 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, if (!hdata->dma_dir) cntr |= CNTR_DDIR; - DMA(instance)->CNTR = cntr; + regs->CNTR = cntr; mb(); /* make sure CNTR is updated before next IO */ /* flush if we were reading */ if (hdata->dma_dir) { - DMA(instance)->FLUSH = 1; + regs->FLUSH = 1; mb(); /* don't allow prefetch */ - while (!(DMA(instance)->ISTR & ISTR_FE_FLG)) + while (!(regs->ISTR & ISTR_FE_FLG)) barrier(); mb(); /* no IO until FLUSH is done */ } @@ -133,14 +134,14 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, /* I think that this CINT is only necessary if you are * using the terminal count features. HM 7 Mar 1994 */ - DMA(instance)->CINT = 1; + regs->CINT = 1; /* stop DMA */ - DMA(instance)->SP_DMA = 1; + regs->SP_DMA = 1; mb(); /* make sure DMA is stopped before next IO */ /* restore the CONTROL bits (minus the direction flag) */ - DMA(instance)->CNTR = CNTR_PDMD | CNTR_INTEN; + regs->CNTR = CNTR_PDMD | CNTR_INTEN; mb(); /* make sure CNTR is updated before next IO */ /* copy from a bounce buffer, if necessary */ @@ -163,7 +164,8 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, static int __init a3000_detect(struct scsi_host_template *tpnt) { - wd33c93_regs regs; + wd33c93_regs wdregs; + a3000_scsiregs *regs; struct WD33C93_hostdata *hdata; if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(A3000_SCSI)) @@ -180,18 +182,20 @@ static int __init a3000_detect(struct scsi_host_template *tpnt) a3000_host->base = ZTWO_VADDR(0xDD0000); a3000_host->irq = IRQ_AMIGA_PORTS; - DMA(a3000_host)->DAWR = DAWR_A3000; - regs.SASR = &(DMA(a3000_host)->SASR); - regs.SCMD = &(DMA(a3000_host)->SCMD); + regs = (a3000_scsiregs *)(a3000_host->base); + regs->DAWR = DAWR_A3000; + wdregs.SASR = ®s->SASR; + wdregs.SCMD = ®s->SCMD; hdata = shost_priv(a3000_host); hdata->no_sync = 0xff; hdata->fast = 0; hdata->dma_mode = CTRL_DMA; - wd33c93_init(a3000_host, regs, dma_setup, dma_stop, WD33C93_FS_12_15); + wd33c93_init(a3000_host, wdregs, dma_setup, dma_stop, + WD33C93_FS_12_15); if (request_irq(IRQ_AMIGA_PORTS, a3000_intr, IRQF_SHARED, "A3000 SCSI", a3000_intr)) goto fail_irq; - DMA(a3000_host)->CNTR = CNTR_PDMD | CNTR_INTEN; + regs->CNTR = CNTR_PDMD | CNTR_INTEN; return 1; @@ -239,7 +243,9 @@ static struct scsi_host_template driver_template = { static int a3000_release(struct Scsi_Host *instance) { - DMA(instance)->CNTR = 0; + a3000_scsiregs *regs = (a3000_scsiregs *)(instance->base); + + regs->CNTR = 0; release_mem_region(0xDD0000, 256); free_irq(IRQ_AMIGA_PORTS, a3000_intr); return 1; -- cgit v1.2.3 From 4616ac7e84c58660a11b991460cf2611552faa76 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 17 May 2009 13:35:13 +0200 Subject: m68k/scsi: mvme147 - Kill static global mvme147_host Acked-by: James Bottomley Signed-off-by: Geert Uytterhoeven --- drivers/scsi/mvme147.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c index 716d1785cda7..1b6195b4717d 100644 --- a/drivers/scsi/mvme147.c +++ b/drivers/scsi/mvme147.c @@ -16,12 +16,12 @@ #include -static struct Scsi_Host *mvme147_host = NULL; - -static irqreturn_t mvme147_intr(int irq, void *dummy) +static irqreturn_t mvme147_intr(int irq, void *data) { + struct Scsi_Host *instance = data; + if (irq == MVME147_IRQ_SCSI_PORT) - wd33c93_intr(mvme147_host); + wd33c93_intr(instance); else m147_pcc->dma_intr = 0x89; /* Ack and enable ints */ return IRQ_HANDLED; @@ -29,7 +29,8 @@ static irqreturn_t mvme147_intr(int irq, void *dummy) static int dma_setup(struct scsi_cmnd *cmd, int dir_in) { - struct WD33C93_hostdata *hdata = shost_priv(mvme147_host); + struct Scsi_Host *instance = cmd->device->host; + struct WD33C93_hostdata *hdata = shost_priv(instance); unsigned char flags = 0x01; unsigned long addr = virt_to_bus(cmd->SCp.ptr); @@ -66,6 +67,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, int mvme147_detect(struct scsi_host_template *tpnt) { static unsigned char called = 0; + struct Scsi_Host *instance; wd33c93_regs regs; struct WD33C93_hostdata *hdata; @@ -76,25 +78,25 @@ int mvme147_detect(struct scsi_host_template *tpnt) tpnt->proc_name = "MVME147"; tpnt->proc_info = &wd33c93_proc_info; - mvme147_host = scsi_register(tpnt, sizeof(struct WD33C93_hostdata)); - if (!mvme147_host) + instance = scsi_register(tpnt, sizeof(struct WD33C93_hostdata)); + if (!instance) goto err_out; - mvme147_host->base = 0xfffe4000; - mvme147_host->irq = MVME147_IRQ_SCSI_PORT; + instance->base = 0xfffe4000; + instance->irq = MVME147_IRQ_SCSI_PORT; regs.SASR = (volatile unsigned char *)0xfffe4000; regs.SCMD = (volatile unsigned char *)0xfffe4001; - hdata = shost_priv(mvme147_host); + hdata = shost_priv(instance); hdata->no_sync = 0xff; hdata->fast = 0; hdata->dma_mode = CTRL_DMA; - wd33c93_init(mvme147_host, regs, dma_setup, dma_stop, WD33C93_FS_8_10); + wd33c93_init(instance, regs, dma_setup, dma_stop, WD33C93_FS_8_10); if (request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0, - "MVME147 SCSI PORT", mvme147_intr)) + "MVME147 SCSI PORT", instance)) goto err_unregister; if (request_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr, 0, - "MVME147 SCSI DMA", mvme147_intr)) + "MVME147 SCSI DMA", instance)) goto err_free_irq; #if 0 /* Disabled; causes problems booting */ m147_pcc->scsi_interrupt = 0x10; /* Assert SCSI bus reset */ @@ -113,7 +115,7 @@ int mvme147_detect(struct scsi_host_template *tpnt) err_free_irq: free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr); err_unregister: - scsi_unregister(mvme147_host); + scsi_unregister(instance); err_out: return 0; } -- cgit v1.2.3 From a8169e6057e9b7dd41c9e3b7a41efebc4bd859c9 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 17 May 2009 13:35:07 +0200 Subject: m68k/scsi: a3000 - Kill static global a3000_host Acked-by: James Bottomley Signed-off-by: Geert Uytterhoeven --- drivers/scsi/a3000.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c index ae9b25a3e3e7..eabc41b65dad 100644 --- a/drivers/scsi/a3000.c +++ b/drivers/scsi/a3000.c @@ -22,22 +22,21 @@ #include -static struct Scsi_Host *a3000_host = NULL; - static int a3000_release(struct Scsi_Host *instance); -static irqreturn_t a3000_intr(int irq, void *dummy) +static irqreturn_t a3000_intr(int irq, void *data) { - a3000_scsiregs *regs = (a3000_scsiregs *)(a3000_host->base); + struct Scsi_Host *instance = data; + a3000_scsiregs *regs = (a3000_scsiregs *)(instance->base); unsigned int status = regs->ISTR; unsigned long flags; if (!(status & ISTR_INT_P)) return IRQ_NONE; if (status & ISTR_INTS) { - spin_lock_irqsave(a3000_host->host_lock, flags); - wd33c93_intr(a3000_host); - spin_unlock_irqrestore(a3000_host->host_lock, flags); + spin_lock_irqsave(instance->host_lock, flags); + wd33c93_intr(instance); + spin_unlock_irqrestore(instance->host_lock, flags); return IRQ_HANDLED; } printk("Non-serviced A3000 SCSI-interrupt? ISTR = %02x\n", status); @@ -46,8 +45,9 @@ static irqreturn_t a3000_intr(int irq, void *dummy) static int dma_setup(struct scsi_cmnd *cmd, int dir_in) { - struct WD33C93_hostdata *hdata = shost_priv(a3000_host); - a3000_scsiregs *regs = (a3000_scsiregs *)(a3000_host->base); + struct Scsi_Host *instance = cmd->device->host; + struct WD33C93_hostdata *hdata = shost_priv(instance); + a3000_scsiregs *regs = (a3000_scsiregs *)(instance->base); unsigned short cntr = CNTR_PDMD | CNTR_INTEN; unsigned long addr = virt_to_bus(cmd->SCp.ptr); @@ -164,6 +164,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, static int __init a3000_detect(struct scsi_host_template *tpnt) { + struct Scsi_Host *instance; wd33c93_regs wdregs; a3000_scsiregs *regs; struct WD33C93_hostdata *hdata; @@ -176,31 +177,30 @@ static int __init a3000_detect(struct scsi_host_template *tpnt) tpnt->proc_name = "A3000"; tpnt->proc_info = &wd33c93_proc_info; - a3000_host = scsi_register(tpnt, sizeof(struct WD33C93_hostdata)); - if (a3000_host == NULL) + instance = scsi_register(tpnt, sizeof(struct WD33C93_hostdata)); + if (instance == NULL) goto fail_register; - a3000_host->base = ZTWO_VADDR(0xDD0000); - a3000_host->irq = IRQ_AMIGA_PORTS; - regs = (a3000_scsiregs *)(a3000_host->base); + instance->base = ZTWO_VADDR(0xDD0000); + instance->irq = IRQ_AMIGA_PORTS; + regs = (a3000_scsiregs *)(instance->base); regs->DAWR = DAWR_A3000; wdregs.SASR = ®s->SASR; wdregs.SCMD = ®s->SCMD; - hdata = shost_priv(a3000_host); + hdata = shost_priv(instance); hdata->no_sync = 0xff; hdata->fast = 0; hdata->dma_mode = CTRL_DMA; - wd33c93_init(a3000_host, wdregs, dma_setup, dma_stop, - WD33C93_FS_12_15); + wd33c93_init(instance, wdregs, dma_setup, dma_stop, WD33C93_FS_12_15); if (request_irq(IRQ_AMIGA_PORTS, a3000_intr, IRQF_SHARED, "A3000 SCSI", - a3000_intr)) + instance)) goto fail_irq; regs->CNTR = CNTR_PDMD | CNTR_INTEN; return 1; fail_irq: - scsi_unregister(a3000_host); + scsi_unregister(instance); fail_register: release_mem_region(0xDD0000, 256); return 0; -- cgit v1.2.3 From 11ca46eaf207e2fde20f6207b6a3ae7b6295da07 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 17 May 2009 20:44:16 +0200 Subject: m68k/scsi: gvp11 - Extract check_wd33c93() Acked-by: James Bottomley Signed-off-by: Geert Uytterhoeven --- drivers/scsi/gvp11.c | 160 ++++++++++++++++++++++++++------------------------- 1 file changed, 83 insertions(+), 77 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c index 777972e6bbf3..59a7bff53e13 100644 --- a/drivers/scsi/gvp11.c +++ b/drivers/scsi/gvp11.c @@ -22,6 +22,8 @@ #include +#define CHECK_WD33C93 + static irqreturn_t gvp11_intr(int irq, void *data) { struct Scsi_Host *instance = data; @@ -167,7 +169,85 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, } } -#define CHECK_WD33C93 +static int __init check_wd33c93(gvp11_scsiregs *regs) +{ +#ifdef CHECK_WD33C93 + volatile unsigned char *sasr_3393, *scmd_3393; + unsigned char save_sasr; + unsigned char q, qq; + + /* + * These darn GVP boards are a problem - it can be tough to tell + * whether or not they include a SCSI controller. This is the + * ultimate Yet-Another-GVP-Detection-Hack in that it actually + * probes for a WD33c93 chip: If we find one, it's extremely + * likely that this card supports SCSI, regardless of Product_ + * Code, Board_Size, etc. + */ + + /* Get pointers to the presumed register locations and save contents */ + + sasr_3393 = ®s->SASR; + scmd_3393 = ®s->SCMD; + save_sasr = *sasr_3393; + + /* First test the AuxStatus Reg */ + + q = *sasr_3393; /* read it */ + if (q & 0x08) /* bit 3 should always be clear */ + return -ENODEV; + *sasr_3393 = WD_AUXILIARY_STATUS; /* setup indirect address */ + if (*sasr_3393 == WD_AUXILIARY_STATUS) { /* shouldn't retain the write */ + *sasr_3393 = save_sasr; /* Oops - restore this byte */ + return -ENODEV; + } + if (*sasr_3393 != q) { /* should still read the same */ + *sasr_3393 = save_sasr; /* Oops - restore this byte */ + return -ENODEV; + } + if (*scmd_3393 != q) /* and so should the image at 0x1f */ + return -ENODEV; + + /* + * Ok, we probably have a wd33c93, but let's check a few other places + * for good measure. Make sure that this works for both 'A and 'B + * chip versions. + */ + + *sasr_3393 = WD_SCSI_STATUS; + q = *scmd_3393; + *sasr_3393 = WD_SCSI_STATUS; + *scmd_3393 = ~q; + *sasr_3393 = WD_SCSI_STATUS; + qq = *scmd_3393; + *sasr_3393 = WD_SCSI_STATUS; + *scmd_3393 = q; + if (qq != q) /* should be read only */ + return -ENODEV; + *sasr_3393 = 0x1e; /* this register is unimplemented */ + q = *scmd_3393; + *sasr_3393 = 0x1e; + *scmd_3393 = ~q; + *sasr_3393 = 0x1e; + qq = *scmd_3393; + *sasr_3393 = 0x1e; + *scmd_3393 = q; + if (qq != q || qq != 0xff) /* should be read only, all 1's */ + return -ENODEV; + *sasr_3393 = WD_TIMEOUT_PERIOD; + q = *scmd_3393; + *sasr_3393 = WD_TIMEOUT_PERIOD; + *scmd_3393 = ~q; + *sasr_3393 = WD_TIMEOUT_PERIOD; + qq = *scmd_3393; + *sasr_3393 = WD_TIMEOUT_PERIOD; + *scmd_3393 = q; + if (qq != (~q & 0xff)) /* should be read/write */ + return -ENODEV; +#endif /* CHECK_WD33C93 */ + + return 0; +} int __init gvp11_detect(struct scsi_host_template *tpnt) { @@ -181,11 +261,6 @@ int __init gvp11_detect(struct scsi_host_template *tpnt) gvp11_scsiregs *regs; wd33c93_regs wdregs; int num_gvp11 = 0; -#ifdef CHECK_WD33C93 - volatile unsigned char *sasr_3393, *scmd_3393; - unsigned char save_sasr; - unsigned char q, qq; -#endif if (!MACH_IS_AMIGA || called) return 0; @@ -226,77 +301,9 @@ int __init gvp11_detect(struct scsi_host_template *tpnt) if (!request_mem_region(address, 256, "wd33c93")) continue; -#ifdef CHECK_WD33C93 - - /* - * These darn GVP boards are a problem - it can be tough to tell - * whether or not they include a SCSI controller. This is the - * ultimate Yet-Another-GVP-Detection-Hack in that it actually - * probes for a WD33c93 chip: If we find one, it's extremely - * likely that this card supports SCSI, regardless of Product_ - * Code, Board_Size, etc. - */ - - /* Get pointers to the presumed register locations and save contents */ - - sasr_3393 = &(((gvp11_scsiregs *)(ZTWO_VADDR(address)))->SASR); - scmd_3393 = &(((gvp11_scsiregs *)(ZTWO_VADDR(address)))->SCMD); - save_sasr = *sasr_3393; - - /* First test the AuxStatus Reg */ - - q = *sasr_3393; /* read it */ - if (q & 0x08) /* bit 3 should always be clear */ - goto release; - *sasr_3393 = WD_AUXILIARY_STATUS; /* setup indirect address */ - if (*sasr_3393 == WD_AUXILIARY_STATUS) { /* shouldn't retain the write */ - *sasr_3393 = save_sasr; /* Oops - restore this byte */ - goto release; - } - if (*sasr_3393 != q) { /* should still read the same */ - *sasr_3393 = save_sasr; /* Oops - restore this byte */ - goto release; - } - if (*scmd_3393 != q) /* and so should the image at 0x1f */ - goto release; - - /* - * Ok, we probably have a wd33c93, but let's check a few other places - * for good measure. Make sure that this works for both 'A and 'B - * chip versions. - */ - - *sasr_3393 = WD_SCSI_STATUS; - q = *scmd_3393; - *sasr_3393 = WD_SCSI_STATUS; - *scmd_3393 = ~q; - *sasr_3393 = WD_SCSI_STATUS; - qq = *scmd_3393; - *sasr_3393 = WD_SCSI_STATUS; - *scmd_3393 = q; - if (qq != q) /* should be read only */ - goto release; - *sasr_3393 = 0x1e; /* this register is unimplemented */ - q = *scmd_3393; - *sasr_3393 = 0x1e; - *scmd_3393 = ~q; - *sasr_3393 = 0x1e; - qq = *scmd_3393; - *sasr_3393 = 0x1e; - *scmd_3393 = q; - if (qq != q || qq != 0xff) /* should be read only, all 1's */ + regs = (gvp11_scsiregs *)(ZTWO_VADDR(address)); + if (check_wd33c93(regs)) goto release; - *sasr_3393 = WD_TIMEOUT_PERIOD; - q = *scmd_3393; - *sasr_3393 = WD_TIMEOUT_PERIOD; - *scmd_3393 = ~q; - *sasr_3393 = WD_TIMEOUT_PERIOD; - qq = *scmd_3393; - *sasr_3393 = WD_TIMEOUT_PERIOD; - *scmd_3393 = q; - if (qq != (~q & 0xff)) /* should be read/write */ - goto release; -#endif instance = scsi_register(tpnt, sizeof(struct WD33C93_hostdata)); if (instance == NULL) @@ -311,7 +318,6 @@ int __init gvp11_detect(struct scsi_host_template *tpnt) else hdata->dma_xfer_mask = default_dma_xfer_mask; - regs = (gvp11_scsiregs *)(instance->base); regs->secret2 = 1; regs->secret1 = 0; regs->secret3 = 15; -- cgit v1.2.3 From 56522e39ab75ea7f1f4f5fe4cb760f00815f3d81 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 17 May 2009 21:05:54 +0200 Subject: m68k/scsi: a2091 - Kill a2091_scsiregs typedef Acked-by: James Bottomley Signed-off-by: Geert Uytterhoeven --- drivers/scsi/a2091.c | 12 ++++++------ drivers/scsi/a2091.h | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c index 308541ff85cf..09b3d77db03f 100644 --- a/drivers/scsi/a2091.c +++ b/drivers/scsi/a2091.c @@ -27,7 +27,7 @@ static int a2091_release(struct Scsi_Host *instance); static irqreturn_t a2091_intr(int irq, void *data) { struct Scsi_Host *instance = data; - a2091_scsiregs *regs = (a2091_scsiregs *)(instance->base); + struct a2091_scsiregs *regs = (struct a2091_scsiregs *)(instance->base); unsigned int status = regs->ISTR; unsigned long flags; @@ -44,7 +44,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) { struct Scsi_Host *instance = cmd->device->host; struct WD33C93_hostdata *hdata = shost_priv(instance); - a2091_scsiregs *regs = (a2091_scsiregs *)(instance->base); + struct a2091_scsiregs *regs = (struct a2091_scsiregs *)(instance->base); unsigned short cntr = CNTR_PDMD | CNTR_INTEN; unsigned long addr = virt_to_bus(cmd->SCp.ptr); @@ -109,7 +109,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, int status) { struct WD33C93_hostdata *hdata = shost_priv(instance); - a2091_scsiregs *regs = (a2091_scsiregs *)(instance->base); + struct a2091_scsiregs *regs = (struct a2091_scsiregs *)(instance->base); /* disable SCSI interrupts */ unsigned short cntr = CNTR_PDMD; @@ -154,7 +154,7 @@ static int __init a2091_detect(struct scsi_host_template *tpnt) unsigned long address; struct zorro_dev *z = NULL; wd33c93_regs wdregs; - a2091_scsiregs *regs; + struct a2091_scsiregs *regs; struct WD33C93_hostdata *hdata; int num_a2091 = 0; @@ -179,7 +179,7 @@ static int __init a2091_detect(struct scsi_host_template *tpnt) instance->base = ZTWO_VADDR(address); instance->irq = IRQ_AMIGA_PORTS; instance->unique_id = z->slotaddr; - regs = (a2091_scsiregs *)(instance->base); + regs = (struct a2091_scsiregs *)(instance->base); regs->DAWR = DAWR_A2091; wdregs.SASR = ®s->SASR; wdregs.SCMD = ®s->SCMD; @@ -243,7 +243,7 @@ static struct scsi_host_template driver_template = { static int a2091_release(struct Scsi_Host *instance) { #ifdef MODULE - a2091_scsiregs *regs = (a2091_scsiregs *)(instance->base); + struct a2091_scsiregs *regs = (struct a2091_scsiregs *)(instance->base); regs->CNTR = 0; release_mem_region(ZTWO_PADDR(instance->base), 256); diff --git a/drivers/scsi/a2091.h b/drivers/scsi/a2091.h index 1c3daa1fd754..794b8e65c711 100644 --- a/drivers/scsi/a2091.h +++ b/drivers/scsi/a2091.h @@ -25,7 +25,7 @@ */ #define A2091_XFER_MASK (0xff000001) -typedef struct { +struct a2091_scsiregs { unsigned char pad1[64]; volatile unsigned short ISTR; volatile unsigned short CNTR; @@ -44,7 +44,7 @@ typedef struct { volatile unsigned short CINT; unsigned char pad7[2]; volatile unsigned short FLUSH; -} a2091_scsiregs; +}; #define DAWR_A2091 (3) -- cgit v1.2.3 From 349d65fdc8e5bb3335fa5e6984ca2c12154a8269 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 17 May 2009 21:05:55 +0200 Subject: m68k/scsi: gvp11 - Kill gvp11_scsiregs typedef Acked-by: James Bottomley Signed-off-by: Geert Uytterhoeven --- drivers/scsi/gvp11.c | 14 +++++++------- drivers/scsi/gvp11.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c index 59a7bff53e13..874cbee1be23 100644 --- a/drivers/scsi/gvp11.c +++ b/drivers/scsi/gvp11.c @@ -27,7 +27,7 @@ static irqreturn_t gvp11_intr(int irq, void *data) { struct Scsi_Host *instance = data; - gvp11_scsiregs *regs = (gvp11_scsiregs *)(instance->base); + struct gvp11_scsiregs *regs = (struct gvp11_scsiregs *)(instance->base); unsigned int status = regs->CNTR; unsigned long flags; @@ -51,7 +51,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) { struct Scsi_Host *instance = cmd->device->host; struct WD33C93_hostdata *hdata = shost_priv(instance); - gvp11_scsiregs *regs = (gvp11_scsiregs *)(instance->base); + struct gvp11_scsiregs *regs = (struct gvp11_scsiregs *)(instance->base); unsigned short cntr = GVP11_DMAC_INT_ENABLE; unsigned long addr = virt_to_bus(cmd->SCp.ptr); int bank_mask; @@ -145,7 +145,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, int status) { - gvp11_scsiregs *regs = (gvp11_scsiregs *)(instance->base); + struct gvp11_scsiregs *regs = (struct gvp11_scsiregs *)(instance->base); struct WD33C93_hostdata *hdata = shost_priv(instance); /* stop DMA */ @@ -169,7 +169,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, } } -static int __init check_wd33c93(gvp11_scsiregs *regs) +static int __init check_wd33c93(struct gvp11_scsiregs *regs) { #ifdef CHECK_WD33C93 volatile unsigned char *sasr_3393, *scmd_3393; @@ -258,7 +258,7 @@ int __init gvp11_detect(struct scsi_host_template *tpnt) struct zorro_dev *z = NULL; unsigned int default_dma_xfer_mask; struct WD33C93_hostdata *hdata; - gvp11_scsiregs *regs; + struct gvp11_scsiregs *regs; wd33c93_regs wdregs; int num_gvp11 = 0; @@ -301,7 +301,7 @@ int __init gvp11_detect(struct scsi_host_template *tpnt) if (!request_mem_region(address, 256, "wd33c93")) continue; - regs = (gvp11_scsiregs *)(ZTWO_VADDR(address)); + regs = (struct gvp11_scsiregs *)(ZTWO_VADDR(address)); if (check_wd33c93(regs)) goto release; @@ -399,7 +399,7 @@ static struct scsi_host_template driver_template = { int gvp11_release(struct Scsi_Host *instance) { #ifdef MODULE - gvp11_scsiregs *regs = (gvp11_scsiregs *)(instance->base); + struct gvp11_scsiregs *regs = (struct gvp11_scsiregs *)(instance->base); regs->CNTR = 0; release_mem_region(ZTWO_PADDR(instance->base), 256); diff --git a/drivers/scsi/gvp11.h b/drivers/scsi/gvp11.h index e2efdf9601ef..b27a3ee3313e 100644 --- a/drivers/scsi/gvp11.h +++ b/drivers/scsi/gvp11.h @@ -30,7 +30,7 @@ int gvp11_release(struct Scsi_Host *); */ #define GVP11_XFER_MASK (0xff000001) -typedef struct { +struct gvp11_scsiregs { unsigned char pad1[64]; volatile unsigned short CNTR; unsigned char pad2[31]; @@ -46,7 +46,7 @@ typedef struct { volatile unsigned short SP_DMA; volatile unsigned short secret2; /* store 1 here */ volatile unsigned short secret3; /* store 15 here */ -} gvp11_scsiregs; +}; /* bits in CNTR */ #define GVP11_DMAC_BUSY (1<<0) -- cgit v1.2.3 From c57c1cab789e4d54fd767fb844e3a309c754e6ed Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 17 May 2009 21:05:53 +0200 Subject: m68k/scsi: a3000 - Kill a3000_scsiregs typedef Acked-by: James Bottomley Signed-off-by: Geert Uytterhoeven --- drivers/scsi/a3000.c | 12 ++++++------ drivers/scsi/a3000.h | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c index eabc41b65dad..79a4a3c97474 100644 --- a/drivers/scsi/a3000.c +++ b/drivers/scsi/a3000.c @@ -27,7 +27,7 @@ static int a3000_release(struct Scsi_Host *instance); static irqreturn_t a3000_intr(int irq, void *data) { struct Scsi_Host *instance = data; - a3000_scsiregs *regs = (a3000_scsiregs *)(instance->base); + struct a3000_scsiregs *regs = (struct a3000_scsiregs *)(instance->base); unsigned int status = regs->ISTR; unsigned long flags; @@ -47,7 +47,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) { struct Scsi_Host *instance = cmd->device->host; struct WD33C93_hostdata *hdata = shost_priv(instance); - a3000_scsiregs *regs = (a3000_scsiregs *)(instance->base); + struct a3000_scsiregs *regs = (struct a3000_scsiregs *)(instance->base); unsigned short cntr = CNTR_PDMD | CNTR_INTEN; unsigned long addr = virt_to_bus(cmd->SCp.ptr); @@ -110,7 +110,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, int status) { struct WD33C93_hostdata *hdata = shost_priv(instance); - a3000_scsiregs *regs = (a3000_scsiregs *)(instance->base); + struct a3000_scsiregs *regs = (struct a3000_scsiregs *)(instance->base); /* disable SCSI interrupts */ unsigned short cntr = CNTR_PDMD; @@ -166,7 +166,7 @@ static int __init a3000_detect(struct scsi_host_template *tpnt) { struct Scsi_Host *instance; wd33c93_regs wdregs; - a3000_scsiregs *regs; + struct a3000_scsiregs *regs; struct WD33C93_hostdata *hdata; if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(A3000_SCSI)) @@ -183,7 +183,7 @@ static int __init a3000_detect(struct scsi_host_template *tpnt) instance->base = ZTWO_VADDR(0xDD0000); instance->irq = IRQ_AMIGA_PORTS; - regs = (a3000_scsiregs *)(instance->base); + regs = (struct a3000_scsiregs *)(instance->base); regs->DAWR = DAWR_A3000; wdregs.SASR = ®s->SASR; wdregs.SCMD = ®s->SCMD; @@ -243,7 +243,7 @@ static struct scsi_host_template driver_template = { static int a3000_release(struct Scsi_Host *instance) { - a3000_scsiregs *regs = (a3000_scsiregs *)(instance->base); + struct a3000_scsiregs *regs = (struct a3000_scsiregs *)(instance->base); regs->CNTR = 0; release_mem_region(0xDD0000, 256); diff --git a/drivers/scsi/a3000.h b/drivers/scsi/a3000.h index 684813ee378c..49db4a335aab 100644 --- a/drivers/scsi/a3000.h +++ b/drivers/scsi/a3000.h @@ -25,7 +25,7 @@ */ #define A3000_XFER_MASK (0x00000003) -typedef struct { +struct a3000_scsiregs { unsigned char pad1[2]; volatile unsigned short DAWR; volatile unsigned int WTC; @@ -46,7 +46,7 @@ typedef struct { volatile unsigned char SASR; unsigned char pad9; volatile unsigned char SCMD; -} a3000_scsiregs; +}; #define DAWR_A3000 (3) -- cgit v1.2.3 From 5d3f2c38603289fdaa60644ceb93307f0abc77de Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 18 Nov 2008 21:25:15 +0100 Subject: m68k/scsi: mvme147 - Kill obsolete HOSTS_C logic Kill the obsolete HOSTS_C define and the related double inclusion of mvme147.h Acked-by: James Bottomley Signed-off-by: Geert Uytterhoeven --- drivers/scsi/mvme147.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c index 1b6195b4717d..c29d0dbb9660 100644 --- a/drivers/scsi/mvme147.c +++ b/drivers/scsi/mvme147.c @@ -134,9 +134,6 @@ static int mvme147_bus_reset(struct scsi_cmnd *cmd) return SUCCESS; } -#define HOSTS_C - -#include "mvme147.h" static struct scsi_host_template driver_template = { .proc_name = "MVME147", -- cgit v1.2.3 From c737e22cde37e4e2ad126316e4aab7349a491ab3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 16 Aug 2009 11:17:35 +0200 Subject: m68k: amiga - A2091/A590 SCSI zorro_driver conversion Acked-by: James Bottomley Signed-off-by: Geert Uytterhoeven --- drivers/scsi/a2091.c | 186 ++++++++++++++++++++++++++++----------------------- 1 file changed, 102 insertions(+), 84 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c index 09b3d77db03f..fc4fce99528e 100644 --- a/drivers/scsi/a2091.c +++ b/drivers/scsi/a2091.c @@ -1,28 +1,20 @@ #include -#include -#include -#include #include #include +#include +#include +#include +#include -#include #include #include #include #include -#include -#include -#include #include "scsi.h" -#include #include "wd33c93.h" #include "a2091.h" -#include - - -static int a2091_release(struct Scsi_Host *instance); static irqreturn_t a2091_intr(int irq, void *data) { @@ -147,85 +139,27 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, } } -static int __init a2091_detect(struct scsi_host_template *tpnt) -{ - static unsigned char called = 0; - struct Scsi_Host *instance; - unsigned long address; - struct zorro_dev *z = NULL; - wd33c93_regs wdregs; - struct a2091_scsiregs *regs; - struct WD33C93_hostdata *hdata; - int num_a2091 = 0; - - if (!MACH_IS_AMIGA || called) - return 0; - called = 1; - - tpnt->proc_name = "A2091"; - tpnt->proc_info = &wd33c93_proc_info; - - while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { - if (z->id != ZORRO_PROD_CBM_A590_A2091_1 && - z->id != ZORRO_PROD_CBM_A590_A2091_2) - continue; - address = z->resource.start; - if (!request_mem_region(address, 256, "wd33c93")) - continue; - - instance = scsi_register(tpnt, sizeof(struct WD33C93_hostdata)); - if (instance == NULL) - goto release; - instance->base = ZTWO_VADDR(address); - instance->irq = IRQ_AMIGA_PORTS; - instance->unique_id = z->slotaddr; - regs = (struct a2091_scsiregs *)(instance->base); - regs->DAWR = DAWR_A2091; - wdregs.SASR = ®s->SASR; - wdregs.SCMD = ®s->SCMD; - hdata = shost_priv(instance); - hdata->no_sync = 0xff; - hdata->fast = 0; - hdata->dma_mode = CTRL_DMA; - wd33c93_init(instance, wdregs, dma_setup, dma_stop, - WD33C93_FS_8_10); - if (request_irq(IRQ_AMIGA_PORTS, a2091_intr, IRQF_SHARED, - "A2091 SCSI", instance)) - goto unregister; - regs->CNTR = CNTR_PDMD | CNTR_INTEN; - num_a2091++; - continue; - -unregister: - scsi_unregister(instance); -release: - release_mem_region(address, 256); - } - - return num_a2091; -} - static int a2091_bus_reset(struct scsi_cmnd *cmd) { + struct Scsi_Host *instance = cmd->device->host; + /* FIXME perform bus-specific reset */ /* FIXME 2: kill this function, and let midlayer fall back to the same action, calling wd33c93_host_reset() */ - spin_lock_irq(cmd->device->host->host_lock); + spin_lock_irq(instance->host_lock); wd33c93_host_reset(cmd); - spin_unlock_irq(cmd->device->host->host_lock); + spin_unlock_irq(instance->host_lock); return SUCCESS; } -#define HOSTS_C - -static struct scsi_host_template driver_template = { - .proc_name = "A2901", +static struct scsi_host_template a2091_scsi_template = { + .module = THIS_MODULE, .name = "Commodore A2091/A590 SCSI", - .detect = a2091_detect, - .release = a2091_release, + .proc_info = wd33c93_proc_info, + .proc_name = "A2901", .queuecommand = wd33c93_queuecommand, .eh_abort_handler = wd33c93_abort, .eh_bus_reset_handler = a2091_bus_reset, @@ -237,19 +171,103 @@ static struct scsi_host_template driver_template = { .use_clustering = DISABLE_CLUSTERING }; +static int __devinit a2091_probe(struct zorro_dev *z, + const struct zorro_device_id *ent) +{ + struct Scsi_Host *instance; + int error; + struct a2091_scsiregs *regs; + wd33c93_regs wdregs; + struct WD33C93_hostdata *hdata; + + if (!request_mem_region(z->resource.start, 256, "wd33c93")) + return -EBUSY; + + instance = scsi_host_alloc(&a2091_scsi_template, + sizeof(struct WD33C93_hostdata)); + if (!instance) { + error = -ENOMEM; + goto fail_alloc; + } + + instance->base = ZTWO_VADDR(z->resource.start); + instance->irq = IRQ_AMIGA_PORTS; + instance->unique_id = z->slotaddr; + + regs = (struct a2091_scsiregs *)(instance->base); + regs->DAWR = DAWR_A2091; + + wdregs.SASR = ®s->SASR; + wdregs.SCMD = ®s->SCMD; -#include "scsi_module.c" + hdata = shost_priv(instance); + hdata->no_sync = 0xff; + hdata->fast = 0; + hdata->dma_mode = CTRL_DMA; + + wd33c93_init(instance, wdregs, dma_setup, dma_stop, WD33C93_FS_8_10); + error = request_irq(IRQ_AMIGA_PORTS, a2091_intr, IRQF_SHARED, + "A2091 SCSI", instance); + if (error) + goto fail_irq; + + regs->CNTR = CNTR_PDMD | CNTR_INTEN; + + error = scsi_add_host(instance, NULL); + if (error) + goto fail_host; + + zorro_set_drvdata(z, instance); + + scsi_scan_host(instance); + return 0; -static int a2091_release(struct Scsi_Host *instance) +fail_host: + free_irq(IRQ_AMIGA_PORTS, instance); +fail_irq: + scsi_host_put(instance); +fail_alloc: + release_mem_region(z->resource.start, 256); + return error; +} + +static void __devexit a2091_remove(struct zorro_dev *z) { -#ifdef MODULE + struct Scsi_Host *instance = zorro_get_drvdata(z); struct a2091_scsiregs *regs = (struct a2091_scsiregs *)(instance->base); regs->CNTR = 0; - release_mem_region(ZTWO_PADDR(instance->base), 256); + scsi_remove_host(instance); free_irq(IRQ_AMIGA_PORTS, instance); -#endif - return 1; + scsi_host_put(instance); + release_mem_region(z->resource.start, 256); +} + +static struct zorro_device_id a2091_zorro_tbl[] __devinitdata = { + { ZORRO_PROD_CBM_A590_A2091_1 }, + { ZORRO_PROD_CBM_A590_A2091_2 }, + { 0 } +}; +MODULE_DEVICE_TABLE(zorro, a2091_zorro_tbl); + +static struct zorro_driver a2091_driver = { + .name = "a2091", + .id_table = a2091_zorro_tbl, + .probe = a2091_probe, + .remove = __devexit_p(a2091_remove), +}; + +static int __init a2091_init(void) +{ + return zorro_register_driver(&a2091_driver); +} +module_init(a2091_init); + +static void __exit a2091_exit(void) +{ + zorro_unregister_driver(&a2091_driver); } +module_exit(a2091_exit); +MODULE_DESCRIPTION("Commodore A2091/A590 SCSI"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 65c2784a24d8d0a67ba3a50029846e0b82bdc223 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 12 Apr 2010 21:55:03 +0200 Subject: m68k/scsi: a2091 - Do not use legacy Scsi_Host.base Acked-by: James Bottomley Signed-off-by: Geert Uytterhoeven --- drivers/scsi/a2091.c | 75 ++++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c index fc4fce99528e..1bb5d3f0e260 100644 --- a/drivers/scsi/a2091.c +++ b/drivers/scsi/a2091.c @@ -16,11 +16,16 @@ #include "a2091.h" +struct a2091_hostdata { + struct WD33C93_hostdata wh; + struct a2091_scsiregs *regs; +}; + static irqreturn_t a2091_intr(int irq, void *data) { struct Scsi_Host *instance = data; - struct a2091_scsiregs *regs = (struct a2091_scsiregs *)(instance->base); - unsigned int status = regs->ISTR; + struct a2091_hostdata *hdata = shost_priv(instance); + unsigned int status = hdata->regs->ISTR; unsigned long flags; if (!(status & (ISTR_INT_F | ISTR_INT_P)) || !(status & ISTR_INTS)) @@ -35,38 +40,39 @@ static irqreturn_t a2091_intr(int irq, void *data) static int dma_setup(struct scsi_cmnd *cmd, int dir_in) { struct Scsi_Host *instance = cmd->device->host; - struct WD33C93_hostdata *hdata = shost_priv(instance); - struct a2091_scsiregs *regs = (struct a2091_scsiregs *)(instance->base); + struct a2091_hostdata *hdata = shost_priv(instance); + struct WD33C93_hostdata *wh = &hdata->wh; + struct a2091_scsiregs *regs = hdata->regs; unsigned short cntr = CNTR_PDMD | CNTR_INTEN; unsigned long addr = virt_to_bus(cmd->SCp.ptr); /* don't allow DMA if the physical address is bad */ if (addr & A2091_XFER_MASK) { - hdata->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff; - hdata->dma_bounce_buffer = kmalloc(hdata->dma_bounce_len, - GFP_KERNEL); + wh->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff; + wh->dma_bounce_buffer = kmalloc(wh->dma_bounce_len, + GFP_KERNEL); /* can't allocate memory; use PIO */ - if (!hdata->dma_bounce_buffer) { - hdata->dma_bounce_len = 0; + if (!wh->dma_bounce_buffer) { + wh->dma_bounce_len = 0; return 1; } /* get the physical address of the bounce buffer */ - addr = virt_to_bus(hdata->dma_bounce_buffer); + addr = virt_to_bus(wh->dma_bounce_buffer); /* the bounce buffer may not be in the first 16M of physmem */ if (addr & A2091_XFER_MASK) { /* we could use chipmem... maybe later */ - kfree(hdata->dma_bounce_buffer); - hdata->dma_bounce_buffer = NULL; - hdata->dma_bounce_len = 0; + kfree(wh->dma_bounce_buffer); + wh->dma_bounce_buffer = NULL; + wh->dma_bounce_len = 0; return 1; } if (!dir_in) { /* copy to bounce buffer for a write */ - memcpy(hdata->dma_bounce_buffer, cmd->SCp.ptr, + memcpy(wh->dma_bounce_buffer, cmd->SCp.ptr, cmd->SCp.this_residual); } } @@ -76,7 +82,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) cntr |= CNTR_DDIR; /* remember direction */ - hdata->dma_dir = dir_in; + wh->dma_dir = dir_in; regs->CNTR = cntr; @@ -100,20 +106,21 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, int status) { - struct WD33C93_hostdata *hdata = shost_priv(instance); - struct a2091_scsiregs *regs = (struct a2091_scsiregs *)(instance->base); + struct a2091_hostdata *hdata = shost_priv(instance); + struct WD33C93_hostdata *wh = &hdata->wh; + struct a2091_scsiregs *regs = hdata->regs; /* disable SCSI interrupts */ unsigned short cntr = CNTR_PDMD; - if (!hdata->dma_dir) + if (!wh->dma_dir) cntr |= CNTR_DDIR; /* disable SCSI interrupts */ regs->CNTR = cntr; /* flush if we were reading */ - if (hdata->dma_dir) { + if (wh->dma_dir) { regs->FLUSH = 1; while (!(regs->ISTR & ISTR_FE_FLG)) ; @@ -129,13 +136,13 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, regs->CNTR = CNTR_PDMD | CNTR_INTEN; /* copy from a bounce buffer, if necessary */ - if (status && hdata->dma_bounce_buffer) { - if (hdata->dma_dir) - memcpy(SCpnt->SCp.ptr, hdata->dma_bounce_buffer, + if (status && wh->dma_bounce_buffer) { + if (wh->dma_dir) + memcpy(SCpnt->SCp.ptr, wh->dma_bounce_buffer, SCpnt->SCp.this_residual); - kfree(hdata->dma_bounce_buffer); - hdata->dma_bounce_buffer = NULL; - hdata->dma_bounce_len = 0; + kfree(wh->dma_bounce_buffer); + wh->dma_bounce_buffer = NULL; + wh->dma_bounce_len = 0; } } @@ -178,32 +185,32 @@ static int __devinit a2091_probe(struct zorro_dev *z, int error; struct a2091_scsiregs *regs; wd33c93_regs wdregs; - struct WD33C93_hostdata *hdata; + struct a2091_hostdata *hdata; if (!request_mem_region(z->resource.start, 256, "wd33c93")) return -EBUSY; instance = scsi_host_alloc(&a2091_scsi_template, - sizeof(struct WD33C93_hostdata)); + sizeof(struct a2091_hostdata)); if (!instance) { error = -ENOMEM; goto fail_alloc; } - instance->base = ZTWO_VADDR(z->resource.start); instance->irq = IRQ_AMIGA_PORTS; instance->unique_id = z->slotaddr; - regs = (struct a2091_scsiregs *)(instance->base); + regs = (struct a2091_scsiregs *)ZTWO_VADDR(z->resource.start); regs->DAWR = DAWR_A2091; wdregs.SASR = ®s->SASR; wdregs.SCMD = ®s->SCMD; hdata = shost_priv(instance); - hdata->no_sync = 0xff; - hdata->fast = 0; - hdata->dma_mode = CTRL_DMA; + hdata->wh.no_sync = 0xff; + hdata->wh.fast = 0; + hdata->wh.dma_mode = CTRL_DMA; + hdata->regs = regs; wd33c93_init(instance, wdregs, dma_setup, dma_stop, WD33C93_FS_8_10); error = request_irq(IRQ_AMIGA_PORTS, a2091_intr, IRQF_SHARED, @@ -234,9 +241,9 @@ fail_alloc: static void __devexit a2091_remove(struct zorro_dev *z) { struct Scsi_Host *instance = zorro_get_drvdata(z); - struct a2091_scsiregs *regs = (struct a2091_scsiregs *)(instance->base); + struct a2091_hostdata *hdata = shost_priv(instance); - regs->CNTR = 0; + hdata->regs->CNTR = 0; scsi_remove_host(instance); free_irq(IRQ_AMIGA_PORTS, instance); scsi_host_put(instance); -- cgit v1.2.3 From c1d288a58936cd0654844d807e53a203f4838fb4 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 16 Aug 2009 11:17:35 +0200 Subject: m68k: amiga - GVP Series II SCSI zorro_driver conversion Acked-by: James Bottomley Signed-off-by: Geert Uytterhoeven --- drivers/scsi/gvp11.c | 298 +++++++++++++++++++++++++++------------------------ drivers/scsi/gvp11.h | 7 -- 2 files changed, 156 insertions(+), 149 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c index 874cbee1be23..4507a16ee1c6 100644 --- a/drivers/scsi/gvp11.c +++ b/drivers/scsi/gvp11.c @@ -1,26 +1,20 @@ #include -#include -#include -#include #include #include +#include +#include +#include +#include -#include #include #include #include #include -#include -#include -#include #include "scsi.h" -#include #include "wd33c93.h" #include "gvp11.h" -#include - #define CHECK_WD33C93 @@ -169,7 +163,40 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, } } -static int __init check_wd33c93(struct gvp11_scsiregs *regs) +static int gvp11_bus_reset(struct scsi_cmnd *cmd) +{ + struct Scsi_Host *instance = cmd->device->host; + + /* FIXME perform bus-specific reset */ + + /* FIXME 2: shouldn't we no-op this function (return + FAILED), and fall back to host reset function, + wd33c93_host_reset ? */ + + spin_lock_irq(instance->host_lock); + wd33c93_host_reset(cmd); + spin_unlock_irq(instance->host_lock); + + return SUCCESS; +} + +static struct scsi_host_template gvp11_scsi_template = { + .module = THIS_MODULE, + .name = "GVP Series II SCSI", + .proc_info = wd33c93_proc_info, + .proc_name = "GVP11", + .queuecommand = wd33c93_queuecommand, + .eh_abort_handler = wd33c93_abort, + .eh_bus_reset_handler = gvp11_bus_reset, + .eh_host_reset_handler = wd33c93_host_reset, + .can_queue = CAN_QUEUE, + .this_id = 7, + .sg_tablesize = SG_ALL, + .cmd_per_lun = CMD_PER_LUN, + .use_clustering = DISABLE_CLUSTERING +}; + +static int __devinit check_wd33c93(struct gvp11_scsiregs *regs) { #ifdef CHECK_WD33C93 volatile unsigned char *sasr_3393, *scmd_3393; @@ -249,163 +276,150 @@ static int __init check_wd33c93(struct gvp11_scsiregs *regs) return 0; } -int __init gvp11_detect(struct scsi_host_template *tpnt) +static int __devinit gvp11_probe(struct zorro_dev *z, + const struct zorro_device_id *ent) { - static unsigned char called = 0; struct Scsi_Host *instance; unsigned long address; + int error; unsigned int epc; - struct zorro_dev *z = NULL; unsigned int default_dma_xfer_mask; struct WD33C93_hostdata *hdata; struct gvp11_scsiregs *regs; wd33c93_regs wdregs; - int num_gvp11 = 0; - - if (!MACH_IS_AMIGA || called) - return 0; - called = 1; - - tpnt->proc_name = "GVP11"; - tpnt->proc_info = &wd33c93_proc_info; - - while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { - /* - * This should (hopefully) be the correct way to identify - * all the different GVP SCSI controllers (except for the - * SERIES I though). - */ - - if (z->id == ZORRO_PROD_GVP_COMBO_030_R3_SCSI || - z->id == ZORRO_PROD_GVP_SERIES_II) - default_dma_xfer_mask = ~0x00ffffff; - else if (z->id == ZORRO_PROD_GVP_GFORCE_030_SCSI || - z->id == ZORRO_PROD_GVP_A530_SCSI || - z->id == ZORRO_PROD_GVP_COMBO_030_R4_SCSI) - default_dma_xfer_mask = ~0x01ffffff; - else if (z->id == ZORRO_PROD_GVP_A1291 || - z->id == ZORRO_PROD_GVP_GFORCE_040_SCSI_1) - default_dma_xfer_mask = ~0x07ffffff; - else - continue; - - /* - * Rumors state that some GVP ram boards use the same product - * code as the SCSI controllers. Therefore if the board-size - * is not 64KB we asume it is a ram board and bail out. - */ - if (z->resource.end - z->resource.start != 0xffff) - continue; - - address = z->resource.start; - if (!request_mem_region(address, 256, "wd33c93")) - continue; - - regs = (struct gvp11_scsiregs *)(ZTWO_VADDR(address)); - if (check_wd33c93(regs)) - goto release; - - instance = scsi_register(tpnt, sizeof(struct WD33C93_hostdata)); - if (instance == NULL) - goto release; - instance->base = ZTWO_VADDR(address); - instance->irq = IRQ_AMIGA_PORTS; - instance->unique_id = z->slotaddr; - - hdata = shost_priv(instance); - if (gvp11_xfer_mask) - hdata->dma_xfer_mask = gvp11_xfer_mask; - else - hdata->dma_xfer_mask = default_dma_xfer_mask; - - regs->secret2 = 1; - regs->secret1 = 0; - regs->secret3 = 15; - while (regs->CNTR & GVP11_DMAC_BUSY) - ; - regs->CNTR = 0; - - regs->BANK = 0; - - epc = *(unsigned short *)(ZTWO_VADDR(address) + 0x8000); - - /* - * Check for 14MHz SCSI clock - */ - wdregs.SASR = ®s->SASR; - wdregs.SCMD = ®s->SCMD; - hdata->no_sync = 0xff; - hdata->fast = 0; - hdata->dma_mode = CTRL_DMA; - wd33c93_init(instance, wdregs, dma_setup, dma_stop, - (epc & GVP_SCSICLKMASK) ? WD33C93_FS_8_10 - : WD33C93_FS_12_15); - - if (request_irq(IRQ_AMIGA_PORTS, gvp11_intr, IRQF_SHARED, - "GVP11 SCSI", instance)) - goto unregister; - regs->CNTR = GVP11_DMAC_INT_ENABLE; - num_gvp11++; - continue; - -unregister: - scsi_unregister(instance); -release: - release_mem_region(address, 256); + + default_dma_xfer_mask = ent->driver_data; + + /* + * Rumors state that some GVP ram boards use the same product + * code as the SCSI controllers. Therefore if the board-size + * is not 64KB we asume it is a ram board and bail out. + */ + if (zorro_resource_len(z) != 0x10000) + return -ENODEV; + + address = z->resource.start; + if (!request_mem_region(address, 256, "wd33c93")) + return -EBUSY; + + regs = (struct gvp11_scsiregs *)(ZTWO_VADDR(address)); + + error = check_wd33c93(regs); + if (error) + goto fail_check_or_alloc; + + instance = scsi_host_alloc(&gvp11_scsi_template, + sizeof(struct WD33C93_hostdata)); + if (!instance) { + error = -ENOMEM; + goto fail_check_or_alloc; } - return num_gvp11; -} + instance->base = (unsigned long)regs; + instance->irq = IRQ_AMIGA_PORTS; + instance->unique_id = z->slotaddr; -static int gvp11_bus_reset(struct scsi_cmnd *cmd) -{ - /* FIXME perform bus-specific reset */ + regs->secret2 = 1; + regs->secret1 = 0; + regs->secret3 = 15; + while (regs->CNTR & GVP11_DMAC_BUSY) + ; + regs->CNTR = 0; + regs->BANK = 0; - /* FIXME 2: shouldn't we no-op this function (return - FAILED), and fall back to host reset function, - wd33c93_host_reset ? */ + wdregs.SASR = ®s->SASR; + wdregs.SCMD = ®s->SCMD; - spin_lock_irq(cmd->device->host->host_lock); - wd33c93_host_reset(cmd); - spin_unlock_irq(cmd->device->host->host_lock); + hdata = shost_priv(instance); + if (gvp11_xfer_mask) + hdata->dma_xfer_mask = gvp11_xfer_mask; + else + hdata->dma_xfer_mask = default_dma_xfer_mask; - return SUCCESS; -} + hdata->no_sync = 0xff; + hdata->fast = 0; + hdata->dma_mode = CTRL_DMA; + /* + * Check for 14MHz SCSI clock + */ + epc = *(unsigned short *)(ZTWO_VADDR(address) + 0x8000); + wd33c93_init(instance, wdregs, dma_setup, dma_stop, + (epc & GVP_SCSICLKMASK) ? WD33C93_FS_8_10 + : WD33C93_FS_12_15); -#define HOSTS_C + error = request_irq(IRQ_AMIGA_PORTS, gvp11_intr, IRQF_SHARED, + "GVP11 SCSI", instance); + if (error) + goto fail_irq; -#include "gvp11.h" + regs->CNTR = GVP11_DMAC_INT_ENABLE; -static struct scsi_host_template driver_template = { - .proc_name = "GVP11", - .name = "GVP Series II SCSI", - .detect = gvp11_detect, - .release = gvp11_release, - .queuecommand = wd33c93_queuecommand, - .eh_abort_handler = wd33c93_abort, - .eh_bus_reset_handler = gvp11_bus_reset, - .eh_host_reset_handler = wd33c93_host_reset, - .can_queue = CAN_QUEUE, - .this_id = 7, - .sg_tablesize = SG_ALL, - .cmd_per_lun = CMD_PER_LUN, - .use_clustering = DISABLE_CLUSTERING -}; + error = scsi_add_host(instance, NULL); + if (error) + goto fail_host; + zorro_set_drvdata(z, instance); + scsi_scan_host(instance); + return 0; -#include "scsi_module.c" +fail_host: + free_irq(IRQ_AMIGA_PORTS, instance); +fail_irq: + scsi_host_put(instance); +fail_check_or_alloc: + release_mem_region(address, 256); + return error; +} -int gvp11_release(struct Scsi_Host *instance) +static void __devexit gvp11_remove(struct zorro_dev *z) { -#ifdef MODULE + struct Scsi_Host *instance = zorro_get_drvdata(z); struct gvp11_scsiregs *regs = (struct gvp11_scsiregs *)(instance->base); regs->CNTR = 0; - release_mem_region(ZTWO_PADDR(instance->base), 256); + scsi_remove_host(instance); free_irq(IRQ_AMIGA_PORTS, instance); -#endif - return 1; + scsi_host_put(instance); + release_mem_region(z->resource.start, 256); +} + + /* + * This should (hopefully) be the correct way to identify + * all the different GVP SCSI controllers (except for the + * SERIES I though). + */ + +static struct zorro_device_id gvp11_zorro_tbl[] __devinitdata = { + { ZORRO_PROD_GVP_COMBO_030_R3_SCSI, ~0x00ffffff }, + { ZORRO_PROD_GVP_SERIES_II, ~0x00ffffff }, + { ZORRO_PROD_GVP_GFORCE_030_SCSI, ~0x01ffffff }, + { ZORRO_PROD_GVP_A530_SCSI, ~0x01ffffff }, + { ZORRO_PROD_GVP_COMBO_030_R4_SCSI, ~0x01ffffff }, + { ZORRO_PROD_GVP_A1291, ~0x07ffffff }, + { ZORRO_PROD_GVP_GFORCE_040_SCSI_1, ~0x07ffffff }, + { 0 } +}; +MODULE_DEVICE_TABLE(zorro, gvp11_zorro_tbl); + +static struct zorro_driver gvp11_driver = { + .name = "gvp11", + .id_table = gvp11_zorro_tbl, + .probe = gvp11_probe, + .remove = __devexit_p(gvp11_remove), +}; + +static int __init gvp11_init(void) +{ + return zorro_register_driver(&gvp11_driver); +} +module_init(gvp11_init); + +static void __exit gvp11_exit(void) +{ + zorro_unregister_driver(&gvp11_driver); } +module_exit(gvp11_exit); +MODULE_DESCRIPTION("GVP Series II SCSI"); MODULE_LICENSE("GPL"); diff --git a/drivers/scsi/gvp11.h b/drivers/scsi/gvp11.h index b27a3ee3313e..852913cde5dd 100644 --- a/drivers/scsi/gvp11.h +++ b/drivers/scsi/gvp11.h @@ -11,9 +11,6 @@ #include -int gvp11_detect(struct scsi_host_template *); -int gvp11_release(struct Scsi_Host *); - #ifndef CMD_PER_LUN #define CMD_PER_LUN 2 #endif @@ -22,8 +19,6 @@ int gvp11_release(struct Scsi_Host *); #define CAN_QUEUE 16 #endif -#ifndef HOSTS_C - /* * if the transfer address ANDed with this results in a non-zero * result, then we can't use DMA. @@ -54,6 +49,4 @@ struct gvp11_scsiregs { #define GVP11_DMAC_INT_ENABLE (1<<3) #define GVP11_DMAC_DIR_WRITE (1<<4) -#endif /* else def HOSTS_C */ - #endif /* GVP11_H */ -- cgit v1.2.3 From cf2ed279f915f36c84ce21a5933ad4bba9f81de8 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 12 Apr 2010 21:55:25 +0200 Subject: m68k/scsi: gvp11 - Do not use legacy Scsi_Host.base Acked-by: James Bottomley Signed-off-by: Geert Uytterhoeven --- drivers/scsi/gvp11.c | 105 +++++++++++++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c index 4507a16ee1c6..2ce26eb7a1ec 100644 --- a/drivers/scsi/gvp11.c +++ b/drivers/scsi/gvp11.c @@ -18,11 +18,16 @@ #define CHECK_WD33C93 +struct gvp11_hostdata { + struct WD33C93_hostdata wh; + struct gvp11_scsiregs *regs; +}; + static irqreturn_t gvp11_intr(int irq, void *data) { struct Scsi_Host *instance = data; - struct gvp11_scsiregs *regs = (struct gvp11_scsiregs *)(instance->base); - unsigned int status = regs->CNTR; + struct gvp11_hostdata *hdata = shost_priv(instance); + unsigned int status = hdata->regs->CNTR; unsigned long flags; if (!(status & GVP11_DMAC_INT_PENDING)) @@ -44,65 +49,66 @@ void gvp11_setup(char *str, int *ints) static int dma_setup(struct scsi_cmnd *cmd, int dir_in) { struct Scsi_Host *instance = cmd->device->host; - struct WD33C93_hostdata *hdata = shost_priv(instance); - struct gvp11_scsiregs *regs = (struct gvp11_scsiregs *)(instance->base); + struct gvp11_hostdata *hdata = shost_priv(instance); + struct WD33C93_hostdata *wh = &hdata->wh; + struct gvp11_scsiregs *regs = hdata->regs; unsigned short cntr = GVP11_DMAC_INT_ENABLE; unsigned long addr = virt_to_bus(cmd->SCp.ptr); int bank_mask; static int scsi_alloc_out_of_range = 0; /* use bounce buffer if the physical address is bad */ - if (addr & hdata->dma_xfer_mask) { - hdata->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff; + if (addr & wh->dma_xfer_mask) { + wh->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff; if (!scsi_alloc_out_of_range) { - hdata->dma_bounce_buffer = - kmalloc(hdata->dma_bounce_len, GFP_KERNEL); - hdata->dma_buffer_pool = BUF_SCSI_ALLOCED; + wh->dma_bounce_buffer = + kmalloc(wh->dma_bounce_len, GFP_KERNEL); + wh->dma_buffer_pool = BUF_SCSI_ALLOCED; } if (scsi_alloc_out_of_range || - !hdata->dma_bounce_buffer) { - hdata->dma_bounce_buffer = - amiga_chip_alloc(hdata->dma_bounce_len, + !wh->dma_bounce_buffer) { + wh->dma_bounce_buffer = + amiga_chip_alloc(wh->dma_bounce_len, "GVP II SCSI Bounce Buffer"); - if (!hdata->dma_bounce_buffer) { - hdata->dma_bounce_len = 0; + if (!wh->dma_bounce_buffer) { + wh->dma_bounce_len = 0; return 1; } - hdata->dma_buffer_pool = BUF_CHIP_ALLOCED; + wh->dma_buffer_pool = BUF_CHIP_ALLOCED; } /* check if the address of the bounce buffer is OK */ - addr = virt_to_bus(hdata->dma_bounce_buffer); + addr = virt_to_bus(wh->dma_bounce_buffer); - if (addr & hdata->dma_xfer_mask) { + if (addr & wh->dma_xfer_mask) { /* fall back to Chip RAM if address out of range */ - if (hdata->dma_buffer_pool == BUF_SCSI_ALLOCED) { - kfree(hdata->dma_bounce_buffer); + if (wh->dma_buffer_pool == BUF_SCSI_ALLOCED) { + kfree(wh->dma_bounce_buffer); scsi_alloc_out_of_range = 1; } else { - amiga_chip_free(hdata->dma_bounce_buffer); + amiga_chip_free(wh->dma_bounce_buffer); } - hdata->dma_bounce_buffer = - amiga_chip_alloc(hdata->dma_bounce_len, + wh->dma_bounce_buffer = + amiga_chip_alloc(wh->dma_bounce_len, "GVP II SCSI Bounce Buffer"); - if (!hdata->dma_bounce_buffer) { - hdata->dma_bounce_len = 0; + if (!wh->dma_bounce_buffer) { + wh->dma_bounce_len = 0; return 1; } - addr = virt_to_bus(hdata->dma_bounce_buffer); - hdata->dma_buffer_pool = BUF_CHIP_ALLOCED; + addr = virt_to_bus(wh->dma_bounce_buffer); + wh->dma_buffer_pool = BUF_CHIP_ALLOCED; } if (!dir_in) { /* copy to bounce buffer for a write */ - memcpy(hdata->dma_bounce_buffer, cmd->SCp.ptr, + memcpy(wh->dma_bounce_buffer, cmd->SCp.ptr, cmd->SCp.this_residual); } } @@ -111,7 +117,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) if (!dir_in) cntr |= GVP11_DMAC_DIR_WRITE; - hdata->dma_dir = dir_in; + wh->dma_dir = dir_in; regs->CNTR = cntr; /* setup DMA *physical* address */ @@ -125,7 +131,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) cache_push(addr, cmd->SCp.this_residual); } - bank_mask = (~hdata->dma_xfer_mask >> 18) & 0x01c0; + bank_mask = (~wh->dma_xfer_mask >> 18) & 0x01c0; if (bank_mask) regs->BANK = bank_mask & (addr >> 18); @@ -139,8 +145,9 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, int status) { - struct gvp11_scsiregs *regs = (struct gvp11_scsiregs *)(instance->base); - struct WD33C93_hostdata *hdata = shost_priv(instance); + struct gvp11_hostdata *hdata = shost_priv(instance); + struct WD33C93_hostdata *wh = &hdata->wh; + struct gvp11_scsiregs *regs = hdata->regs; /* stop DMA */ regs->SP_DMA = 1; @@ -148,18 +155,18 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, regs->CNTR = GVP11_DMAC_INT_ENABLE; /* copy from a bounce buffer, if necessary */ - if (status && hdata->dma_bounce_buffer) { - if (hdata->dma_dir && SCpnt) - memcpy(SCpnt->SCp.ptr, hdata->dma_bounce_buffer, + if (status && wh->dma_bounce_buffer) { + if (wh->dma_dir && SCpnt) + memcpy(SCpnt->SCp.ptr, wh->dma_bounce_buffer, SCpnt->SCp.this_residual); - if (hdata->dma_buffer_pool == BUF_SCSI_ALLOCED) - kfree(hdata->dma_bounce_buffer); + if (wh->dma_buffer_pool == BUF_SCSI_ALLOCED) + kfree(wh->dma_bounce_buffer); else - amiga_chip_free(hdata->dma_bounce_buffer); + amiga_chip_free(wh->dma_bounce_buffer); - hdata->dma_bounce_buffer = NULL; - hdata->dma_bounce_len = 0; + wh->dma_bounce_buffer = NULL; + wh->dma_bounce_len = 0; } } @@ -284,7 +291,7 @@ static int __devinit gvp11_probe(struct zorro_dev *z, int error; unsigned int epc; unsigned int default_dma_xfer_mask; - struct WD33C93_hostdata *hdata; + struct gvp11_hostdata *hdata; struct gvp11_scsiregs *regs; wd33c93_regs wdregs; @@ -309,13 +316,12 @@ static int __devinit gvp11_probe(struct zorro_dev *z, goto fail_check_or_alloc; instance = scsi_host_alloc(&gvp11_scsi_template, - sizeof(struct WD33C93_hostdata)); + sizeof(struct gvp11_hostdata)); if (!instance) { error = -ENOMEM; goto fail_check_or_alloc; } - instance->base = (unsigned long)regs; instance->irq = IRQ_AMIGA_PORTS; instance->unique_id = z->slotaddr; @@ -332,13 +338,14 @@ static int __devinit gvp11_probe(struct zorro_dev *z, hdata = shost_priv(instance); if (gvp11_xfer_mask) - hdata->dma_xfer_mask = gvp11_xfer_mask; + hdata->wh.dma_xfer_mask = gvp11_xfer_mask; else - hdata->dma_xfer_mask = default_dma_xfer_mask; + hdata->wh.dma_xfer_mask = default_dma_xfer_mask; - hdata->no_sync = 0xff; - hdata->fast = 0; - hdata->dma_mode = CTRL_DMA; + hdata->wh.no_sync = 0xff; + hdata->wh.fast = 0; + hdata->wh.dma_mode = CTRL_DMA; + hdata->regs = regs; /* * Check for 14MHz SCSI clock @@ -375,9 +382,9 @@ fail_check_or_alloc: static void __devexit gvp11_remove(struct zorro_dev *z) { struct Scsi_Host *instance = zorro_get_drvdata(z); - struct gvp11_scsiregs *regs = (struct gvp11_scsiregs *)(instance->base); + struct gvp11_hostdata *hdata = shost_priv(instance); - regs->CNTR = 0; + hdata->regs->CNTR = 0; scsi_remove_host(instance); free_irq(IRQ_AMIGA_PORTS, instance); scsi_host_put(instance); -- cgit v1.2.3 From c2a24a4ca1137473971842461612e56a654e7edb Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 5 Apr 2009 13:02:45 +0200 Subject: m68k: amiga - A3000 SCSI platform device conversion Acked-by: James Bottomley Signed-off-by: Geert Uytterhoeven --- arch/m68k/amiga/platform.c | 11 +++ drivers/scsi/a3000.c | 164 +++++++++++++++++++++++++++------------------ 2 files changed, 111 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/arch/m68k/amiga/platform.c b/arch/m68k/amiga/platform.c index 38f18bf14737..df1fae3c3729 100644 --- a/arch/m68k/amiga/platform.c +++ b/arch/m68k/amiga/platform.c @@ -58,6 +58,13 @@ subsys_initcall(amiga_init_bus); #endif /* CONFIG_ZORRO */ +static const struct resource a3000_scsi_resource __initconst = { + .start = 0xdd0000, + .end = 0xdd00ff, + .flags = IORESOURCE_MEM, +}; + + static int __init amiga_init_devices(void) { if (!MACH_IS_AMIGA) @@ -77,6 +84,10 @@ static int __init amiga_init_devices(void) if (AMIGAHW_PRESENT(AMI_FLOPPY)) platform_device_register_simple("amiga-floppy", -1, NULL, 0); + if (AMIGAHW_PRESENT(A3000_SCSI)) + platform_device_register_simple("amiga-a3000-scsi", -1, + &a3000_scsi_resource, 1); + return 0; } diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c index 79a4a3c97474..7f09d89100a1 100644 --- a/drivers/scsi/a3000.c +++ b/drivers/scsi/a3000.c @@ -1,28 +1,21 @@ #include #include -#include -#include #include #include +#include #include #include +#include -#include #include #include #include #include -#include #include "scsi.h" -#include #include "wd33c93.h" #include "a3000.h" -#include - - -static int a3000_release(struct Scsi_Host *instance); static irqreturn_t a3000_intr(int irq, void *data) { @@ -39,7 +32,7 @@ static irqreturn_t a3000_intr(int irq, void *data) spin_unlock_irqrestore(instance->host_lock, flags); return IRQ_HANDLED; } - printk("Non-serviced A3000 SCSI-interrupt? ISTR = %02x\n", status); + pr_warning("Non-serviced A3000 SCSI-interrupt? ISTR = %02x\n", status); return IRQ_NONE; } @@ -162,93 +155,136 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, } } -static int __init a3000_detect(struct scsi_host_template *tpnt) +static int a3000_bus_reset(struct scsi_cmnd *cmd) +{ + struct Scsi_Host *instance = cmd->device->host; + + /* FIXME perform bus-specific reset */ + + /* FIXME 2: kill this entire function, which should + cause mid-layer to call wd33c93_host_reset anyway? */ + + spin_lock_irq(instance->host_lock); + wd33c93_host_reset(cmd); + spin_unlock_irq(instance->host_lock); + + return SUCCESS; +} + +static struct scsi_host_template amiga_a3000_scsi_template = { + .module = THIS_MODULE, + .name = "Amiga 3000 built-in SCSI", + .proc_info = wd33c93_proc_info, + .proc_name = "A3000", + .queuecommand = wd33c93_queuecommand, + .eh_abort_handler = wd33c93_abort, + .eh_bus_reset_handler = a3000_bus_reset, + .eh_host_reset_handler = wd33c93_host_reset, + .can_queue = CAN_QUEUE, + .this_id = 7, + .sg_tablesize = SG_ALL, + .cmd_per_lun = CMD_PER_LUN, + .use_clustering = ENABLE_CLUSTERING +}; + +static int __init amiga_a3000_scsi_probe(struct platform_device *pdev) { + struct resource *res; struct Scsi_Host *instance; - wd33c93_regs wdregs; + int error; struct a3000_scsiregs *regs; + wd33c93_regs wdregs; struct WD33C93_hostdata *hdata; - if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(A3000_SCSI)) - return 0; - if (!request_mem_region(0xDD0000, 256, "wd33c93")) - return 0; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; - tpnt->proc_name = "A3000"; - tpnt->proc_info = &wd33c93_proc_info; + if (!request_mem_region(res->start, resource_size(res), "wd33c93")) + return -EBUSY; - instance = scsi_register(tpnt, sizeof(struct WD33C93_hostdata)); - if (instance == NULL) - goto fail_register; + instance = scsi_host_alloc(&amiga_a3000_scsi_template, + sizeof(struct WD33C93_hostdata)); + if (!instance) { + error = -ENOMEM; + goto fail_alloc; + } - instance->base = ZTWO_VADDR(0xDD0000); + instance->base = ZTWO_VADDR(res->start); instance->irq = IRQ_AMIGA_PORTS; + regs = (struct a3000_scsiregs *)(instance->base); regs->DAWR = DAWR_A3000; + wdregs.SASR = ®s->SASR; wdregs.SCMD = ®s->SCMD; + hdata = shost_priv(instance); hdata->no_sync = 0xff; hdata->fast = 0; hdata->dma_mode = CTRL_DMA; + wd33c93_init(instance, wdregs, dma_setup, dma_stop, WD33C93_FS_12_15); - if (request_irq(IRQ_AMIGA_PORTS, a3000_intr, IRQF_SHARED, "A3000 SCSI", - instance)) + error = request_irq(IRQ_AMIGA_PORTS, a3000_intr, IRQF_SHARED, + "A3000 SCSI", instance); + if (error) goto fail_irq; + regs->CNTR = CNTR_PDMD | CNTR_INTEN; - return 1; + error = scsi_add_host(instance, NULL); + if (error) + goto fail_host; -fail_irq: - scsi_unregister(instance); -fail_register: - release_mem_region(0xDD0000, 256); + platform_set_drvdata(pdev, instance); + + scsi_scan_host(instance); return 0; + +fail_host: + free_irq(IRQ_AMIGA_PORTS, instance); +fail_irq: + scsi_host_put(instance); +fail_alloc: + release_mem_region(res->start, resource_size(res)); + return error; } -static int a3000_bus_reset(struct scsi_cmnd *cmd) +static int __exit amiga_a3000_scsi_remove(struct platform_device *pdev) { - /* FIXME perform bus-specific reset */ - - /* FIXME 2: kill this entire function, which should - cause mid-layer to call wd33c93_host_reset anyway? */ - - spin_lock_irq(cmd->device->host->host_lock); - wd33c93_host_reset(cmd); - spin_unlock_irq(cmd->device->host->host_lock); + struct Scsi_Host *instance = platform_get_drvdata(pdev); + struct a3000_scsiregs *regs = (struct a3000_scsiregs *)(instance->base); + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - return SUCCESS; + regs->CNTR = 0; + scsi_remove_host(instance); + free_irq(IRQ_AMIGA_PORTS, instance); + scsi_host_put(instance); + release_mem_region(res->start, resource_size(res)); + return 0; } -#define HOSTS_C - -static struct scsi_host_template driver_template = { - .proc_name = "A3000", - .name = "Amiga 3000 built-in SCSI", - .detect = a3000_detect, - .release = a3000_release, - .queuecommand = wd33c93_queuecommand, - .eh_abort_handler = wd33c93_abort, - .eh_bus_reset_handler = a3000_bus_reset, - .eh_host_reset_handler = wd33c93_host_reset, - .can_queue = CAN_QUEUE, - .this_id = 7, - .sg_tablesize = SG_ALL, - .cmd_per_lun = CMD_PER_LUN, - .use_clustering = ENABLE_CLUSTERING +static struct platform_driver amiga_a3000_scsi_driver = { + .remove = __exit_p(amiga_a3000_scsi_remove), + .driver = { + .name = "amiga-a3000-scsi", + .owner = THIS_MODULE, + }, }; - -#include "scsi_module.c" - -static int a3000_release(struct Scsi_Host *instance) +static int __init amiga_a3000_scsi_init(void) { - struct a3000_scsiregs *regs = (struct a3000_scsiregs *)(instance->base); + return platform_driver_probe(&amiga_a3000_scsi_driver, + amiga_a3000_scsi_probe); +} +module_init(amiga_a3000_scsi_init); - regs->CNTR = 0; - release_mem_region(0xDD0000, 256); - free_irq(IRQ_AMIGA_PORTS, a3000_intr); - return 1; +static void __exit amiga_a3000_scsi_exit(void) +{ + platform_driver_unregister(&amiga_a3000_scsi_driver); } +module_exit(amiga_a3000_scsi_exit); +MODULE_DESCRIPTION("Amiga 3000 built-in SCSI"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:amiga-a3000-scsi"); -- cgit v1.2.3 From 2b21d5e47bb9b07f90cf213c885867cf11f99976 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 12 Apr 2010 21:55:15 +0200 Subject: m68k/scsi: a3000 - Do not use legacy Scsi_Host.base Acked-by: James Bottomley Signed-off-by: Geert Uytterhoeven --- drivers/scsi/a3000.c | 76 ++++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c index 7f09d89100a1..d9468027fb61 100644 --- a/drivers/scsi/a3000.c +++ b/drivers/scsi/a3000.c @@ -17,11 +17,16 @@ #include "a3000.h" +struct a3000_hostdata { + struct WD33C93_hostdata wh; + struct a3000_scsiregs *regs; +}; + static irqreturn_t a3000_intr(int irq, void *data) { struct Scsi_Host *instance = data; - struct a3000_scsiregs *regs = (struct a3000_scsiregs *)(instance->base); - unsigned int status = regs->ISTR; + struct a3000_hostdata *hdata = shost_priv(instance); + unsigned int status = hdata->regs->ISTR; unsigned long flags; if (!(status & ISTR_INT_P)) @@ -39,8 +44,9 @@ static irqreturn_t a3000_intr(int irq, void *data) static int dma_setup(struct scsi_cmnd *cmd, int dir_in) { struct Scsi_Host *instance = cmd->device->host; - struct WD33C93_hostdata *hdata = shost_priv(instance); - struct a3000_scsiregs *regs = (struct a3000_scsiregs *)(instance->base); + struct a3000_hostdata *hdata = shost_priv(instance); + struct WD33C93_hostdata *wh = &hdata->wh; + struct a3000_scsiregs *regs = hdata->regs; unsigned short cntr = CNTR_PDMD | CNTR_INTEN; unsigned long addr = virt_to_bus(cmd->SCp.ptr); @@ -51,23 +57,23 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) * buffer */ if (addr & A3000_XFER_MASK) { - hdata->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff; - hdata->dma_bounce_buffer = kmalloc(hdata->dma_bounce_len, - GFP_KERNEL); + wh->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff; + wh->dma_bounce_buffer = kmalloc(wh->dma_bounce_len, + GFP_KERNEL); /* can't allocate memory; use PIO */ - if (!hdata->dma_bounce_buffer) { - hdata->dma_bounce_len = 0; + if (!wh->dma_bounce_buffer) { + wh->dma_bounce_len = 0; return 1; } if (!dir_in) { /* copy to bounce buffer for a write */ - memcpy(hdata->dma_bounce_buffer, cmd->SCp.ptr, + memcpy(wh->dma_bounce_buffer, cmd->SCp.ptr, cmd->SCp.this_residual); } - addr = virt_to_bus(hdata->dma_bounce_buffer); + addr = virt_to_bus(wh->dma_bounce_buffer); } /* setup dma direction */ @@ -75,7 +81,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) cntr |= CNTR_DDIR; /* remember direction */ - hdata->dma_dir = dir_in; + wh->dma_dir = dir_in; regs->CNTR = cntr; @@ -102,20 +108,21 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, int status) { - struct WD33C93_hostdata *hdata = shost_priv(instance); - struct a3000_scsiregs *regs = (struct a3000_scsiregs *)(instance->base); + struct a3000_hostdata *hdata = shost_priv(instance); + struct WD33C93_hostdata *wh = &hdata->wh; + struct a3000_scsiregs *regs = hdata->regs; /* disable SCSI interrupts */ unsigned short cntr = CNTR_PDMD; - if (!hdata->dma_dir) + if (!wh->dma_dir) cntr |= CNTR_DDIR; regs->CNTR = cntr; mb(); /* make sure CNTR is updated before next IO */ /* flush if we were reading */ - if (hdata->dma_dir) { + if (wh->dma_dir) { regs->FLUSH = 1; mb(); /* don't allow prefetch */ while (!(regs->ISTR & ISTR_FE_FLG)) @@ -138,19 +145,18 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, mb(); /* make sure CNTR is updated before next IO */ /* copy from a bounce buffer, if necessary */ - if (status && hdata->dma_bounce_buffer) { + if (status && wh->dma_bounce_buffer) { if (SCpnt) { - if (hdata->dma_dir && SCpnt) - memcpy(SCpnt->SCp.ptr, - hdata->dma_bounce_buffer, + if (wh->dma_dir && SCpnt) + memcpy(SCpnt->SCp.ptr, wh->dma_bounce_buffer, SCpnt->SCp.this_residual); - kfree(hdata->dma_bounce_buffer); - hdata->dma_bounce_buffer = NULL; - hdata->dma_bounce_len = 0; + kfree(wh->dma_bounce_buffer); + wh->dma_bounce_buffer = NULL; + wh->dma_bounce_len = 0; } else { - kfree(hdata->dma_bounce_buffer); - hdata->dma_bounce_buffer = NULL; - hdata->dma_bounce_len = 0; + kfree(wh->dma_bounce_buffer); + wh->dma_bounce_buffer = NULL; + wh->dma_bounce_len = 0; } } } @@ -194,7 +200,7 @@ static int __init amiga_a3000_scsi_probe(struct platform_device *pdev) int error; struct a3000_scsiregs *regs; wd33c93_regs wdregs; - struct WD33C93_hostdata *hdata; + struct a3000_hostdata *hdata; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) @@ -204,25 +210,25 @@ static int __init amiga_a3000_scsi_probe(struct platform_device *pdev) return -EBUSY; instance = scsi_host_alloc(&amiga_a3000_scsi_template, - sizeof(struct WD33C93_hostdata)); + sizeof(struct a3000_hostdata)); if (!instance) { error = -ENOMEM; goto fail_alloc; } - instance->base = ZTWO_VADDR(res->start); instance->irq = IRQ_AMIGA_PORTS; - regs = (struct a3000_scsiregs *)(instance->base); + regs = (struct a3000_scsiregs *)ZTWO_VADDR(res->start); regs->DAWR = DAWR_A3000; wdregs.SASR = ®s->SASR; wdregs.SCMD = ®s->SCMD; hdata = shost_priv(instance); - hdata->no_sync = 0xff; - hdata->fast = 0; - hdata->dma_mode = CTRL_DMA; + hdata->wh.no_sync = 0xff; + hdata->wh.fast = 0; + hdata->wh.dma_mode = CTRL_DMA; + hdata->regs = regs; wd33c93_init(instance, wdregs, dma_setup, dma_stop, WD33C93_FS_12_15); error = request_irq(IRQ_AMIGA_PORTS, a3000_intr, IRQF_SHARED, @@ -253,10 +259,10 @@ fail_alloc: static int __exit amiga_a3000_scsi_remove(struct platform_device *pdev) { struct Scsi_Host *instance = platform_get_drvdata(pdev); - struct a3000_scsiregs *regs = (struct a3000_scsiregs *)(instance->base); + struct a3000_hostdata *hdata = shost_priv(instance); struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - regs->CNTR = 0; + hdata->regs->CNTR = 0; scsi_remove_host(instance); free_irq(IRQ_AMIGA_PORTS, instance); scsi_host_put(instance); -- cgit v1.2.3 From a24a6b22254bca8d54be6c8b7d8730d09f1058cc Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 5 Apr 2009 13:05:50 +0200 Subject: m68k: amiga - A4000T SCSI platform device conversion Acked-by: James Bottomley Signed-off-by: Geert Uytterhoeven --- arch/m68k/amiga/platform.c | 11 +++++ drivers/scsi/a4000t.c | 101 +++++++++++++++++++++------------------------ 2 files changed, 57 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/arch/m68k/amiga/platform.c b/arch/m68k/amiga/platform.c index df1fae3c3729..027e4cae88ff 100644 --- a/arch/m68k/amiga/platform.c +++ b/arch/m68k/amiga/platform.c @@ -65,6 +65,13 @@ static const struct resource a3000_scsi_resource __initconst = { }; +static const struct resource a4000t_scsi_resource __initconst = { + .start = 0xdd0000, + .end = 0xdd0fff, + .flags = IORESOURCE_MEM, +}; + + static int __init amiga_init_devices(void) { if (!MACH_IS_AMIGA) @@ -88,6 +95,10 @@ static int __init amiga_init_devices(void) platform_device_register_simple("amiga-a3000-scsi", -1, &a3000_scsi_resource, 1); + if (AMIGAHW_PRESENT(A4000_SCSI)) + platform_device_register_simple("amiga-a4000t-scsi", -1, + &a4000t_scsi_resource, 1); + return 0; } diff --git a/drivers/scsi/a4000t.c b/drivers/scsi/a4000t.c index 11ae6be8aeaf..23c76f41883c 100644 --- a/drivers/scsi/a4000t.c +++ b/drivers/scsi/a4000t.c @@ -20,10 +20,6 @@ #include "53c700.h" -MODULE_AUTHOR("Alan Hourihane / Kars de Jong "); -MODULE_DESCRIPTION("Amiga A4000T NCR53C710 driver"); -MODULE_LICENSE("GPL"); - static struct scsi_host_template a4000t_scsi_driver_template = { .name = "A4000T builtin SCSI", @@ -32,30 +28,35 @@ static struct scsi_host_template a4000t_scsi_driver_template = { .module = THIS_MODULE, }; -static struct platform_device *a4000t_scsi_device; -#define A4000T_SCSI_ADDR 0xdd0040 +#define A4000T_SCSI_OFFSET 0x40 -static int __devinit a4000t_probe(struct platform_device *dev) +static int __init amiga_a4000t_scsi_probe(struct platform_device *pdev) { - struct Scsi_Host *host; + struct resource *res; + phys_addr_t scsi_addr; struct NCR_700_Host_Parameters *hostdata; + struct Scsi_Host *host; - if (!(MACH_IS_AMIGA && AMIGAHW_PRESENT(A4000_SCSI))) - goto out; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; - if (!request_mem_region(A4000T_SCSI_ADDR, 0x1000, + if (!request_mem_region(res->start, resource_size(res), "A4000T builtin SCSI")) - goto out; + return -EBUSY; - hostdata = kzalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); + hostdata = kzalloc(sizeof(struct NCR_700_Host_Parameters), + GFP_KERNEL); if (!hostdata) { - printk(KERN_ERR "a4000t-scsi: Failed to allocate host data\n"); + dev_err(&pdev->dev, "Failed to allocate host data\n"); goto out_release; } + scsi_addr = res->start + A4000T_SCSI_OFFSET; + /* Fill in the required pieces of hostdata */ - hostdata->base = (void __iomem *)ZTWO_VADDR(A4000T_SCSI_ADDR); + hostdata->base = (void __iomem *)ZTWO_VADDR(scsi_addr); hostdata->clock = 50; hostdata->chip710 = 1; hostdata->dmode_extra = DMODE_FC2; @@ -63,26 +64,25 @@ static int __devinit a4000t_probe(struct platform_device *dev) /* and register the chip */ host = NCR_700_detect(&a4000t_scsi_driver_template, hostdata, - &dev->dev); + &pdev->dev); if (!host) { - printk(KERN_ERR "a4000t-scsi: No host detected; " - "board configuration problem?\n"); + dev_err(&pdev->dev, + "No host detected; board configuration problem?\n"); goto out_free; } host->this_id = 7; - host->base = A4000T_SCSI_ADDR; + host->base = scsi_addr; host->irq = IRQ_AMIGA_PORTS; if (request_irq(host->irq, NCR_700_intr, IRQF_SHARED, "a4000t-scsi", host)) { - printk(KERN_ERR "a4000t-scsi: request_irq failed\n"); + dev_err(&pdev->dev, "request_irq failed\n"); goto out_put_host; } - platform_set_drvdata(dev, host); + platform_set_drvdata(pdev, host); scsi_scan_host(host); - return 0; out_put_host: @@ -90,58 +90,49 @@ static int __devinit a4000t_probe(struct platform_device *dev) out_free: kfree(hostdata); out_release: - release_mem_region(A4000T_SCSI_ADDR, 0x1000); - out: + release_mem_region(res->start, resource_size(res)); return -ENODEV; } -static __devexit int a4000t_device_remove(struct platform_device *dev) +static int __exit amiga_a4000t_scsi_remove(struct platform_device *pdev) { - struct Scsi_Host *host = platform_get_drvdata(dev); + struct Scsi_Host *host = platform_get_drvdata(pdev); struct NCR_700_Host_Parameters *hostdata = shost_priv(host); + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); scsi_remove_host(host); - NCR_700_release(host); kfree(hostdata); free_irq(host->irq, host); - release_mem_region(A4000T_SCSI_ADDR, 0x1000); - + release_mem_region(res->start, resource_size(res)); return 0; } -static struct platform_driver a4000t_scsi_driver = { - .driver = { - .name = "a4000t-scsi", - .owner = THIS_MODULE, +static struct platform_driver amiga_a4000t_scsi_driver = { + .remove = __exit_p(amiga_a4000t_scsi_remove), + .driver = { + .name = "amiga-a4000t-scsi", + .owner = THIS_MODULE, }, - .probe = a4000t_probe, - .remove = __devexit_p(a4000t_device_remove), }; -static int __init a4000t_scsi_init(void) +static int __init amiga_a4000t_scsi_init(void) { - int err; - - err = platform_driver_register(&a4000t_scsi_driver); - if (err) - return err; - - a4000t_scsi_device = platform_device_register_simple("a4000t-scsi", - -1, NULL, 0); - if (IS_ERR(a4000t_scsi_device)) { - platform_driver_unregister(&a4000t_scsi_driver); - return PTR_ERR(a4000t_scsi_device); - } - - return err; + return platform_driver_probe(&amiga_a4000t_scsi_driver, + amiga_a4000t_scsi_probe); } -static void __exit a4000t_scsi_exit(void) +module_init(amiga_a4000t_scsi_init); + +static void __exit amiga_a4000t_scsi_exit(void) { - platform_device_unregister(a4000t_scsi_device); - platform_driver_unregister(&a4000t_scsi_driver); + platform_driver_unregister(&amiga_a4000t_scsi_driver); } -module_init(a4000t_scsi_init); -module_exit(a4000t_scsi_exit); +module_exit(amiga_a4000t_scsi_exit); + +MODULE_AUTHOR("Alan Hourihane / " + "Kars de Jong "); +MODULE_DESCRIPTION("Amiga A4000T NCR53C710 driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:amiga-a4000t-scsi"); -- cgit v1.2.3 From 9aed2302655854586069d90e0d59ce3a0e12809d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 8 Dec 2009 20:12:20 +0100 Subject: m68k: amiga - Amiga Gayle IDE platform device conversion Signed-off-by: Geert Uytterhoeven --- arch/m68k/amiga/platform.c | 63 ++++++++++++++++- arch/m68k/include/asm/amigayle.h | 6 ++ drivers/ide/gayle.c | 147 ++++++++++++++++++++++----------------- 3 files changed, 150 insertions(+), 66 deletions(-) (limited to 'drivers') diff --git a/arch/m68k/amiga/platform.c b/arch/m68k/amiga/platform.c index 027e4cae88ff..907f6f5f2cac 100644 --- a/arch/m68k/amiga/platform.c +++ b/arch/m68k/amiga/platform.c @@ -11,6 +11,7 @@ #include #include +#include #ifdef CONFIG_ZORRO @@ -55,7 +56,24 @@ static int __init amiga_init_bus(void) subsys_initcall(amiga_init_bus); -#endif /* CONFIG_ZORRO */ + +static int z_dev_present(zorro_id id) +{ + unsigned int i; + + for (i = 0; i < zorro_num_autocon; i++) + if (zorro_autocon[i].rom.er_Manufacturer == ZORRO_MANUF(id) && + zorro_autocon[i].rom.er_Product == ZORRO_PROD(id)) + return 1; + + return 0; +} + +#else /* !CONFIG_ZORRO */ + +static inline int z_dev_present(zorro_id id) { return 0; } + +#endif /* !CONFIG_ZORRO */ static const struct resource a3000_scsi_resource __initconst = { @@ -72,8 +90,36 @@ static const struct resource a4000t_scsi_resource __initconst = { }; +static const struct resource a1200_ide_resource __initconst = { + .start = 0xda0000, + .end = 0xda1fff, + .flags = IORESOURCE_MEM, +}; + +static const struct gayle_ide_platform_data a1200_ide_pdata __initconst = { + .base = 0xda0000, + .irqport = 0xda9000, + .explicit_ack = 1, +}; + + +static const struct resource a4000_ide_resource __initconst = { + .start = 0xdd2000, + .end = 0xdd3fff, + .flags = IORESOURCE_MEM, +}; + +static const struct gayle_ide_platform_data a4000_ide_pdata __initconst = { + .base = 0xdd2020, + .irqport = 0xdd3020, + .explicit_ack = 0, +}; + + static int __init amiga_init_devices(void) { + struct platform_device *pdev; + if (!MACH_IS_AMIGA) return -ENODEV; @@ -99,6 +145,21 @@ static int __init amiga_init_devices(void) platform_device_register_simple("amiga-a4000t-scsi", -1, &a4000t_scsi_resource, 1); + if (AMIGAHW_PRESENT(A1200_IDE) || + z_dev_present(ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530_SCSI_IDE)) { + pdev = platform_device_register_simple("amiga-gayle-ide", -1, + &a1200_ide_resource, 1); + platform_device_add_data(pdev, &a1200_ide_pdata, + sizeof(a1200_ide_pdata)); + } + + if (AMIGAHW_PRESENT(A4000_IDE)) { + pdev = platform_device_register_simple("amiga-gayle-ide", -1, + &a4000_ide_resource, 1); + platform_device_add_data(pdev, &a4000_ide_pdata, + sizeof(a4000_ide_pdata)); + } + return 0; } diff --git a/arch/m68k/include/asm/amigayle.h b/arch/m68k/include/asm/amigayle.h index bb5a6aa329f3..a01453d9c231 100644 --- a/arch/m68k/include/asm/amigayle.h +++ b/arch/m68k/include/asm/amigayle.h @@ -104,4 +104,10 @@ struct GAYLE { #define GAYLE_CFG_250NS 0x00 #define GAYLE_CFG_720NS 0x0c +struct gayle_ide_platform_data { + unsigned long base; + unsigned long irqport; + int explicit_ack; /* A1200 IDE needs explicit ack */ +}; + #endif /* asm-m68k/amigayle.h */ diff --git a/drivers/ide/gayle.c b/drivers/ide/gayle.c index b9e517de6a82..3feaa26410be 100644 --- a/drivers/ide/gayle.c +++ b/drivers/ide/gayle.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -23,15 +24,6 @@ #include - /* - * Bases of the IDE interfaces - */ - -#define GAYLE_BASE_4000 0xdd2020 /* A4000/A4000T */ -#define GAYLE_BASE_1200 0xda0000 /* A1200/A600 and E-Matrix 530 */ - -#define GAYLE_IDEREG_SIZE 0x2000 - /* * Offsets from one of the above bases */ @@ -68,20 +60,20 @@ MODULE_PARM_DESC(doubler, "enable support for IDE doublers"); static int gayle_test_irq(ide_hwif_t *hwif) { - unsigned char ch; + unsigned char ch; - ch = z_readb(hwif->io_ports.irq_addr); - if (!(ch & GAYLE_IRQ_IDE)) - return 0; - return 1; + ch = z_readb(hwif->io_ports.irq_addr); + if (!(ch & GAYLE_IRQ_IDE)) + return 0; + return 1; } static void gayle_a1200_clear_irq(ide_drive_t *drive) { - ide_hwif_t *hwif = drive->hwif; + ide_hwif_t *hwif = drive->hwif; - (void)z_readb(hwif->io_ports.status_addr); - z_writeb(0x7c, hwif->io_ports.irq_addr); + (void)z_readb(hwif->io_ports.status_addr); + z_writeb(0x7c, hwif->io_ports.irq_addr); } static void __init gayle_setup_ports(struct ide_hw *hw, unsigned long base, @@ -122,64 +114,89 @@ static const struct ide_port_info gayle_port_info = { * Probe for a Gayle IDE interface (and optionally for an IDE doubler) */ -static int __init gayle_init(void) +static int __init amiga_gayle_ide_probe(struct platform_device *pdev) { - unsigned long phys_base, res_start, res_n; - unsigned long base, ctrlport, irqport; - int a4000, i, rc; - struct ide_hw hw[GAYLE_NUM_HWIFS], *hws[GAYLE_NUM_HWIFS]; - struct ide_port_info d = gayle_port_info; - - if (!MACH_IS_AMIGA) - return -ENODEV; - - if ((a4000 = AMIGAHW_PRESENT(A4000_IDE)) || AMIGAHW_PRESENT(A1200_IDE)) - goto found; - -#ifdef CONFIG_ZORRO - if (zorro_find_device(ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530_SCSI_IDE, - NULL)) - goto found; -#endif - return -ENODEV; - -found: - printk(KERN_INFO "ide: Gayle IDE controller (A%d style%s)\n", - a4000 ? 4000 : 1200, - ide_doubler ? ", IDE doubler" : ""); - - if (a4000) { - phys_base = GAYLE_BASE_4000; - irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_4000); - d.port_ops = &gayle_a4000_port_ops; - } else { - phys_base = GAYLE_BASE_1200; - irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_1200); - d.port_ops = &gayle_a1200_port_ops; + struct resource *res; + struct gayle_ide_platform_data *pdata; + unsigned long base, ctrlport, irqport; + unsigned int i; + int error; + struct ide_hw hw[GAYLE_NUM_HWIFS], *hws[GAYLE_NUM_HWIFS]; + struct ide_port_info d = gayle_port_info; + struct ide_host *host; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + if (!request_mem_region(res->start, resource_size(res), "IDE")) + return -EBUSY; + + pdata = pdev->dev.platform_data; + pr_info("ide: Gayle IDE controller (A%u style%s)\n", + pdata->explicit_ack ? 1200 : 4000, + ide_doubler ? ", IDE doubler" : ""); + + base = (unsigned long)ZTWO_VADDR(pdata->base); + ctrlport = 0; + irqport = (unsigned long)ZTWO_VADDR(pdata->irqport); + if (pdata->explicit_ack) + d.port_ops = &gayle_a1200_port_ops; + else + d.port_ops = &gayle_a4000_port_ops; + + for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++, base += GAYLE_NEXT_PORT) { + if (GAYLE_HAS_CONTROL_REG) + ctrlport = base + GAYLE_CONTROL; + + gayle_setup_ports(&hw[i], base, ctrlport, irqport); + hws[i] = &hw[i]; } - res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1); - res_n = GAYLE_IDEREG_SIZE; + error = ide_host_add(&d, hws, i, &host); + if (error) + goto out; - if (!request_mem_region(res_start, res_n, "IDE")) - return -EBUSY; + platform_set_drvdata(pdev, host); + return 0; - for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) { - base = (unsigned long)ZTWO_VADDR(phys_base + i * GAYLE_NEXT_PORT); - ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0; +out: + release_mem_region(res->start, resource_size(res)); + return error; +} + +static int __exit amiga_gayle_ide_remove(struct platform_device *pdev) +{ + struct ide_host *host = platform_get_drvdata(pdev); + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + ide_host_remove(host); + release_mem_region(res->start, resource_size(res)); + return 0; +} - gayle_setup_ports(&hw[i], base, ctrlport, irqport); +static struct platform_driver amiga_gayle_ide_driver = { + .remove = __exit_p(amiga_gayle_ide_remove), + .driver = { + .name = "amiga-gayle-ide", + .owner = THIS_MODULE, + }, +}; - hws[i] = &hw[i]; - } +static int __init amiga_gayle_ide_init(void) +{ + return platform_driver_probe(&amiga_gayle_ide_driver, + amiga_gayle_ide_probe); +} - rc = ide_host_add(&d, hws, i, NULL); - if (rc) - release_mem_region(res_start, res_n); +module_init(amiga_gayle_ide_init); - return rc; +static void __exit amiga_gayle_ide_exit(void) +{ + platform_driver_unregister(&amiga_gayle_ide_driver); } -module_init(gayle_init); +module_exit(amiga_gayle_ide_exit); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:amiga-gayle-ide"); -- cgit v1.2.3 From 5121c7172d7d9bec33535e098c9487cf4e8186f2 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 5 Apr 2009 13:10:56 +0200 Subject: m68k: amiga - Keyboard platform device conversion Signed-off-by: Geert Uytterhoeven --- arch/m68k/amiga/platform.c | 5 +++ drivers/input/keyboard/amikbd.c | 97 ++++++++++++++++++++++++----------------- 2 files changed, 63 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/arch/m68k/amiga/platform.c b/arch/m68k/amiga/platform.c index 907f6f5f2cac..d427de23c02e 100644 --- a/arch/m68k/amiga/platform.c +++ b/arch/m68k/amiga/platform.c @@ -160,6 +160,11 @@ static int __init amiga_init_devices(void) sizeof(a4000_ide_pdata)); } + + /* other I/O hardware */ + if (AMIGAHW_PRESENT(AMI_KEYBOARD)) + platform_device_register_simple("amiga-keyboard", -1, NULL, 0); + return 0; } diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c index 35149ec455a9..79172af164f2 100644 --- a/drivers/input/keyboard/amikbd.c +++ b/drivers/input/keyboard/amikbd.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -154,10 +155,9 @@ static const char *amikbd_messages[8] = { [7] = KERN_WARNING "amikbd: keyboard interrupt\n" }; -static struct input_dev *amikbd_dev; - -static irqreturn_t amikbd_interrupt(int irq, void *dummy) +static irqreturn_t amikbd_interrupt(int irq, void *data) { + struct input_dev *dev = data; unsigned char scancode, down; scancode = ~ciaa.sdr; /* get and invert scancode (keyboard is active low) */ @@ -170,47 +170,42 @@ static irqreturn_t amikbd_interrupt(int irq, void *dummy) if (scancode < 0x78) { /* scancodes < 0x78 are keys */ if (scancode == 98) { /* CapsLock is a toggle switch key on Amiga */ - input_report_key(amikbd_dev, scancode, 1); - input_report_key(amikbd_dev, scancode, 0); + input_report_key(dev, scancode, 1); + input_report_key(dev, scancode, 0); } else { - input_report_key(amikbd_dev, scancode, down); + input_report_key(dev, scancode, down); } - input_sync(amikbd_dev); + input_sync(dev); } else /* scancodes >= 0x78 are error codes */ printk(amikbd_messages[scancode - 0x78]); return IRQ_HANDLED; } -static int __init amikbd_init(void) +static int __init amikbd_probe(struct platform_device *pdev) { + struct input_dev *dev; int i, j, err; - if (!AMIGAHW_PRESENT(AMI_KEYBOARD)) - return -ENODEV; - - if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb")) - return -EBUSY; - - amikbd_dev = input_allocate_device(); - if (!amikbd_dev) { - printk(KERN_ERR "amikbd: not enough memory for input device\n"); - err = -ENOMEM; - goto fail1; + dev = input_allocate_device(); + if (!dev) { + dev_err(&pdev->dev, "Not enough memory for input device\n"); + return -ENOMEM; } - amikbd_dev->name = "Amiga Keyboard"; - amikbd_dev->phys = "amikbd/input0"; - amikbd_dev->id.bustype = BUS_AMIGA; - amikbd_dev->id.vendor = 0x0001; - amikbd_dev->id.product = 0x0001; - amikbd_dev->id.version = 0x0100; + dev->name = pdev->name; + dev->phys = "amikbd/input0"; + dev->id.bustype = BUS_AMIGA; + dev->id.vendor = 0x0001; + dev->id.product = 0x0001; + dev->id.version = 0x0100; + dev->dev.parent = &pdev->dev; - amikbd_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); for (i = 0; i < 0x78; i++) - set_bit(i, amikbd_dev->keybit); + set_bit(i, dev->keybit); for (i = 0; i < MAX_NR_KEYMAPS; i++) { static u_short temp_map[NR_KEYS] __initdata; @@ -229,30 +224,54 @@ static int __init amikbd_init(void) memcpy(key_maps[i], temp_map, sizeof(temp_map)); } ciaa.cra &= ~0x41; /* serial data in, turn off TA */ - if (request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", - amikbd_interrupt)) { - err = -EBUSY; + err = request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", + dev); + if (err) goto fail2; - } - err = input_register_device(amikbd_dev); + err = input_register_device(dev); if (err) goto fail3; + platform_set_drvdata(pdev, dev); + return 0; - fail3: free_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt); - fail2: input_free_device(amikbd_dev); - fail1: release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100); + fail3: free_irq(IRQ_AMIGA_CIAA_SP, dev); + fail2: input_free_device(dev); return err; } -static void __exit amikbd_exit(void) +static int __exit amikbd_remove(struct platform_device *pdev) +{ + struct input_dev *dev = platform_get_drvdata(pdev); + + platform_set_drvdata(pdev, NULL); + free_irq(IRQ_AMIGA_CIAA_SP, dev); + input_unregister_device(dev); + return 0; +} + +static struct platform_driver amikbd_driver = { + .remove = __exit_p(amikbd_remove), + .driver = { + .name = "amiga-keyboard", + .owner = THIS_MODULE, + }, +}; + +static int __init amikbd_init(void) { - free_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt); - input_unregister_device(amikbd_dev); - release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100); + return platform_driver_probe(&amikbd_driver, amikbd_probe); } module_init(amikbd_init); + +static void __exit amikbd_exit(void) +{ + platform_driver_unregister(&amikbd_driver); +} + module_exit(amikbd_exit); + +MODULE_ALIAS("platform:amiga-keyboard"); -- cgit v1.2.3 From 314c926f64b345f153b9180a2c79333657dbec48 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 5 Apr 2009 13:11:28 +0200 Subject: m68k: amiga - Mouse platform device conversion Signed-off-by: Geert Uytterhoeven --- arch/m68k/amiga/platform.c | 3 ++ drivers/input/mouse/amimouse.c | 98 +++++++++++++++++++++++++++--------------- 2 files changed, 66 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/arch/m68k/amiga/platform.c b/arch/m68k/amiga/platform.c index d427de23c02e..269bafc8da17 100644 --- a/arch/m68k/amiga/platform.c +++ b/arch/m68k/amiga/platform.c @@ -165,6 +165,9 @@ static int __init amiga_init_devices(void) if (AMIGAHW_PRESENT(AMI_KEYBOARD)) platform_device_register_simple("amiga-keyboard", -1, NULL, 0); + if (AMIGAHW_PRESENT(AMI_MOUSE)) + platform_device_register_simple("amiga-mouse", -1, NULL, 0); + return 0; } diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c index a185ac78a42c..ff5f61a0fd3a 100644 --- a/drivers/input/mouse/amimouse.c +++ b/drivers/input/mouse/amimouse.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -34,10 +35,10 @@ MODULE_DESCRIPTION("Amiga mouse driver"); MODULE_LICENSE("GPL"); static int amimouse_lastx, amimouse_lasty; -static struct input_dev *amimouse_dev; -static irqreturn_t amimouse_interrupt(int irq, void *dummy) +static irqreturn_t amimouse_interrupt(int irq, void *data) { + struct input_dev *dev = data; unsigned short joy0dat, potgor; int nx, ny, dx, dy; @@ -59,14 +60,14 @@ static irqreturn_t amimouse_interrupt(int irq, void *dummy) potgor = amiga_custom.potgor; - input_report_rel(amimouse_dev, REL_X, dx); - input_report_rel(amimouse_dev, REL_Y, dy); + input_report_rel(dev, REL_X, dx); + input_report_rel(dev, REL_Y, dy); - input_report_key(amimouse_dev, BTN_LEFT, ciaa.pra & 0x40); - input_report_key(amimouse_dev, BTN_MIDDLE, potgor & 0x0100); - input_report_key(amimouse_dev, BTN_RIGHT, potgor & 0x0400); + input_report_key(dev, BTN_LEFT, ciaa.pra & 0x40); + input_report_key(dev, BTN_MIDDLE, potgor & 0x0100); + input_report_key(dev, BTN_RIGHT, potgor & 0x0400); - input_sync(amimouse_dev); + input_sync(dev); return IRQ_HANDLED; } @@ -74,63 +75,90 @@ static irqreturn_t amimouse_interrupt(int irq, void *dummy) static int amimouse_open(struct input_dev *dev) { unsigned short joy0dat; + int error; joy0dat = amiga_custom.joy0dat; amimouse_lastx = joy0dat & 0xff; amimouse_lasty = joy0dat >> 8; - if (request_irq(IRQ_AMIGA_VERTB, amimouse_interrupt, 0, "amimouse", amimouse_interrupt)) { - printk(KERN_ERR "amimouse.c: Can't allocate irq %d\n", IRQ_AMIGA_VERTB); - return -EBUSY; - } + error = request_irq(IRQ_AMIGA_VERTB, amimouse_interrupt, 0, "amimouse", + dev); + if (error) + dev_err(&dev->dev, "Can't allocate irq %d\n", IRQ_AMIGA_VERTB); - return 0; + return error; } static void amimouse_close(struct input_dev *dev) { - free_irq(IRQ_AMIGA_VERTB, amimouse_interrupt); + free_irq(IRQ_AMIGA_VERTB, dev); } -static int __init amimouse_init(void) +static int __init amimouse_probe(struct platform_device *pdev) { int err; + struct input_dev *dev; - if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE)) - return -ENODEV; - - amimouse_dev = input_allocate_device(); - if (!amimouse_dev) + dev = input_allocate_device(); + if (!dev) return -ENOMEM; - amimouse_dev->name = "Amiga mouse"; - amimouse_dev->phys = "amimouse/input0"; - amimouse_dev->id.bustype = BUS_AMIGA; - amimouse_dev->id.vendor = 0x0001; - amimouse_dev->id.product = 0x0002; - amimouse_dev->id.version = 0x0100; + dev->name = pdev->name; + dev->phys = "amimouse/input0"; + dev->id.bustype = BUS_AMIGA; + dev->id.vendor = 0x0001; + dev->id.product = 0x0002; + dev->id.version = 0x0100; - amimouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - amimouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); - amimouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | + dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); + dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); + dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); - amimouse_dev->open = amimouse_open; - amimouse_dev->close = amimouse_close; + dev->open = amimouse_open; + dev->close = amimouse_close; + dev->dev.parent = &pdev->dev; - err = input_register_device(amimouse_dev); + err = input_register_device(dev); if (err) { - input_free_device(amimouse_dev); + input_free_device(dev); return err; } + platform_set_drvdata(pdev, dev); + return 0; } -static void __exit amimouse_exit(void) +static int __exit amimouse_remove(struct platform_device *pdev) { - input_unregister_device(amimouse_dev); + struct input_dev *dev = platform_get_drvdata(pdev); + + platform_set_drvdata(pdev, NULL); + input_unregister_device(dev); + return 0; +} + +static struct platform_driver amimouse_driver = { + .remove = __exit_p(amimouse_remove), + .driver = { + .name = "amiga-mouse", + .owner = THIS_MODULE, + }, +}; + +static int __init amimouse_init(void) +{ + return platform_driver_probe(&amimouse_driver, amimouse_probe); } module_init(amimouse_init); + +static void __exit amimouse_exit(void) +{ + platform_driver_unregister(&amimouse_driver); +} + module_exit(amimouse_exit); + +MODULE_ALIAS("platform:amiga-mouse"); -- cgit v1.2.3 From 826e8c8c804e5a38586c6b48ef38d1e755789f0c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 5 Apr 2009 13:12:30 +0200 Subject: m68k: amiga - Serial port platform device conversion Signed-off-by: Geert Uytterhoeven --- arch/m68k/amiga/platform.c | 3 +++ drivers/char/amiserial.c | 61 ++++++++++++++++++++++++++-------------------- 2 files changed, 38 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/arch/m68k/amiga/platform.c b/arch/m68k/amiga/platform.c index 269bafc8da17..52aa62da8528 100644 --- a/arch/m68k/amiga/platform.c +++ b/arch/m68k/amiga/platform.c @@ -168,6 +168,9 @@ static int __init amiga_init_devices(void) if (AMIGAHW_PRESENT(AMI_MOUSE)) platform_device_register_simple("amiga-mouse", -1, NULL, 0); + if (AMIGAHW_PRESENT(AMI_SERIAL)) + platform_device_register_simple("amiga-serial", -1, NULL, 0); + return 0; } diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 56b27671adc4..4f8d60c25a98 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c @@ -84,6 +84,7 @@ static char *serial_version = "4.30"; #include #include #include +#include #include @@ -1954,29 +1955,16 @@ static const struct tty_operations serial_ops = { /* * The serial driver boot-time initialization code! */ -static int __init rs_init(void) +static int __init amiga_serial_probe(struct platform_device *pdev) { unsigned long flags; struct serial_state * state; int error; - if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_SERIAL)) - return -ENODEV; - serial_driver = alloc_tty_driver(1); if (!serial_driver) return -ENOMEM; - /* - * We request SERDAT and SERPER only, because the serial registers are - * too spreaded over the custom register space - */ - if (!request_mem_region(CUSTOM_PHYSADDR+0x30, 4, - "amiserial [Paula]")) { - error = -EBUSY; - goto fail_put_tty_driver; - } - IRQ_ports = NULL; show_serial_version(); @@ -1998,7 +1986,7 @@ static int __init rs_init(void) error = tty_register_driver(serial_driver); if (error) - goto fail_release_mem_region; + goto fail_put_tty_driver; state = rs_table; state->magic = SSTATE_MAGIC; @@ -2050,23 +2038,24 @@ static int __init rs_init(void) ciab.ddra |= (SER_DTR | SER_RTS); /* outputs */ ciab.ddra &= ~(SER_DCD | SER_CTS | SER_DSR); /* inputs */ + platform_set_drvdata(pdev, state); + return 0; fail_free_irq: free_irq(IRQ_AMIGA_TBE, state); fail_unregister: tty_unregister_driver(serial_driver); -fail_release_mem_region: - release_mem_region(CUSTOM_PHYSADDR+0x30, 4); fail_put_tty_driver: put_tty_driver(serial_driver); return error; } -static __exit void rs_exit(void) +static int __exit amiga_serial_remove(struct platform_device *pdev) { int error; - struct async_struct *info = rs_table[0].info; + struct serial_state *state = platform_get_drvdata(pdev); + struct async_struct *info = state->info; /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ tasklet_kill(&info->tlet); @@ -2075,19 +2064,38 @@ static __exit void rs_exit(void) error); put_tty_driver(serial_driver); - if (info) { - rs_table[0].info = NULL; - kfree(info); - } + rs_table[0].info = NULL; + kfree(info); free_irq(IRQ_AMIGA_TBE, rs_table); free_irq(IRQ_AMIGA_RBF, rs_table); - release_mem_region(CUSTOM_PHYSADDR+0x30, 4); + platform_set_drvdata(pdev, NULL); + + return error; +} + +static struct platform_driver amiga_serial_driver = { + .remove = __exit_p(amiga_serial_remove), + .driver = { + .name = "amiga-serial", + .owner = THIS_MODULE, + }, +}; + +static int __init amiga_serial_init(void) +{ + return platform_driver_probe(&amiga_serial_driver, amiga_serial_probe); +} + +module_init(amiga_serial_init); + +static void __exit amiga_serial_exit(void) +{ + platform_driver_unregister(&amiga_serial_driver); } -module_init(rs_init) -module_exit(rs_exit) +module_exit(amiga_serial_exit); #if defined(CONFIG_SERIAL_CONSOLE) && !defined(MODULE) @@ -2154,3 +2162,4 @@ console_initcall(amiserial_console_init); #endif /* CONFIG_SERIAL_CONSOLE && !MODULE */ MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:amiga-serial"); -- cgit v1.2.3 From 6f8221c26be5d80f749b1b6c2e7c8456fefb5250 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 5 Apr 2009 13:13:20 +0200 Subject: m68k: amiga - Parallel port platform device conversion Signed-off-by: Geert Uytterhoeven --- arch/m68k/amiga/platform.c | 3 ++ drivers/parport/parport_amiga.c | 64 +++++++++++++++++++++++++---------------- 2 files changed, 43 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/arch/m68k/amiga/platform.c b/arch/m68k/amiga/platform.c index 52aa62da8528..c985db029503 100644 --- a/arch/m68k/amiga/platform.c +++ b/arch/m68k/amiga/platform.c @@ -171,6 +171,9 @@ static int __init amiga_init_devices(void) if (AMIGAHW_PRESENT(AMI_SERIAL)) platform_device_register_simple("amiga-serial", -1, NULL, 0); + if (AMIGAHW_PRESENT(AMI_PARALLEL)) + platform_device_register_simple("amiga-parallel", -1, NULL, 0); + return 0; } diff --git a/drivers/parport/parport_amiga.c b/drivers/parport/parport_amiga.c index 1586e1caa2f5..8bef6d60f88b 100644 --- a/drivers/parport/parport_amiga.c +++ b/drivers/parport/parport_amiga.c @@ -18,6 +18,8 @@ #include #include #include +#include + #include #include #include @@ -31,7 +33,6 @@ #define DPRINTK(x...) do { } while (0) #endif -static struct parport *this_port = NULL; static void amiga_write_data(struct parport *p, unsigned char data) { @@ -227,18 +228,11 @@ static struct parport_operations pp_amiga_ops = { /* ----------- Initialisation code --------------------------------- */ -static int __init parport_amiga_init(void) +static int __init amiga_parallel_probe(struct platform_device *pdev) { struct parport *p; int err; - if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_PARALLEL)) - return -ENODEV; - - err = -EBUSY; - if (!request_mem_region(CIAA_PHYSADDR-1+0x100, 0x100, "parallel")) - goto out_mem; - ciaa.ddrb = 0xff; ciab.ddra &= 0xf8; mb(); @@ -246,41 +240,63 @@ static int __init parport_amiga_init(void) p = parport_register_port((unsigned long)&ciaa.prb, IRQ_AMIGA_CIAA_FLG, PARPORT_DMA_NONE, &pp_amiga_ops); if (!p) - goto out_port; + return -EBUSY; - err = request_irq(IRQ_AMIGA_CIAA_FLG, parport_irq_handler, 0, p->name, p); + err = request_irq(IRQ_AMIGA_CIAA_FLG, parport_irq_handler, 0, p->name, + p); if (err) goto out_irq; - this_port = p; printk(KERN_INFO "%s: Amiga built-in port using irq\n", p->name); /* XXX: set operating mode */ parport_announce_port(p); + platform_set_drvdata(pdev, p); + return 0; out_irq: parport_put_port(p); -out_port: - release_mem_region(CIAA_PHYSADDR-1+0x100, 0x100); -out_mem: return err; } -static void __exit parport_amiga_exit(void) +static int __exit amiga_parallel_remove(struct platform_device *pdev) +{ + struct parport *port = platform_get_drvdata(pdev); + + parport_remove_port(port); + if (port->irq != PARPORT_IRQ_NONE) + free_irq(IRQ_AMIGA_CIAA_FLG, port); + parport_put_port(port); + platform_set_drvdata(pdev, NULL); + return 0; +} + +static struct platform_driver amiga_parallel_driver = { + .remove = __exit_p(amiga_parallel_remove), + .driver = { + .name = "amiga-parallel", + .owner = THIS_MODULE, + }, +}; + +static int __init amiga_parallel_init(void) +{ + return platform_driver_probe(&amiga_parallel_driver, + amiga_parallel_probe); +} + +module_init(amiga_parallel_init); + +static void __exit amiga_parallel_exit(void) { - parport_remove_port(this_port); - if (this_port->irq != PARPORT_IRQ_NONE) - free_irq(IRQ_AMIGA_CIAA_FLG, this_port); - parport_put_port(this_port); - release_mem_region(CIAA_PHYSADDR-1+0x100, 0x100); + platform_driver_unregister(&amiga_parallel_driver); } +module_exit(amiga_parallel_exit); MODULE_AUTHOR("Joerg Dorchain "); MODULE_DESCRIPTION("Parport Driver for Amiga builtin Port"); MODULE_SUPPORTED_DEVICE("Amiga builtin Parallel Port"); MODULE_LICENSE("GPL"); - -module_init(parport_amiga_init) -module_exit(parport_amiga_exit) +MODULE_ALIAS("platform:amiga-parallel"); -- cgit v1.2.3 From b578bb490fb605c23c20b63995f26d3ab2cfb6e0 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 26 May 2010 14:40:32 -0400 Subject: Revert "rt2x00: Fix rt2800usb TX descriptor writing." This reverts commit 663cb47cc2c5acd32850f67d051e47d62ed199c9. This patch was merged out of the proper order, so instead of fixing a problem with a prior (unmerged) patch, it creates one. Ooops! Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 699161327d65..0f8b84b7224c 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -413,7 +413,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, */ rt2x00_desc_read(txi, 0, &word); rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, - skb->len - TXINFO_DESC_SIZE); + skb->len + TXWI_DESC_SIZE); rt2x00_set_field32(&word, TXINFO_W0_WIV, !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); -- cgit v1.2.3 From 5001960016bb53a1075bd9d62d7c067cd38c5a68 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Tue, 25 May 2010 23:58:47 +0200 Subject: ar9170usb: fix read from freed driver context Commit "ar9170: wait for asynchronous firmware loading" introduced a bug, which is triggered by fatal errors while the driver is initializing the device. BUG: unable to handle kernel paging request at 6b6b6bf7 IP: [] kobject_put+0x7/0x70 *pde = 00000000 Oops: 0000 [#1] PREEMPT last sysfs file: /sys/devices/platform/hdaps/position Modules linked in: ar9170usb [...] Pid: 6246, comm: firmware/ar9170 Not tainted 2.6.34-wl #54 EIP: 0060:[] EFLAGS: 00010206 CPU: 0 EIP is at kobject_put+0x7/0x70 EAX: 6b6b6bd7 EBX: f4d3d0e0 ECX: f5ba9124 EDX: f6af2a7c ESI: 00000000 EDI: f4d3d0e0 EBP: 00000000 ESP: f5e98f9c DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068 Process firmware/ar9170 (pid: 6246) Stack: c12532ed 00000246 f5bfaa70 f8487353 f4d3d0e0 Call Trace: [] ? device_release_driver+0x1d/0x30 [] ? ar9170_usb_firmware_failed+0x43/0x70 [ar9170usb] [] ? request_firmware_work_func+0x2c/0x70 [] ? request_firmware_work_func+0x0/0x70 [] ? kthread+0x74/0x80 [] ? kthread+0x0/0x80 [] ? kernel_thread_helper+0x6/0x10 Code: 40 d3 f2 ff 85 c0 89 c3 74 0a ba 44 86 4c c1 e8 [...] EIP: [] kobject_put+0x7/0x70 SS:ESP 0068:f5e98f9c CR2: 000000006b6b6bf7 ---[ end trace e81abb992434b410 ]--- Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ar9170/usb.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index 82ab532a4923..a93dc18a45c3 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c @@ -739,17 +739,27 @@ err_out: static void ar9170_usb_firmware_failed(struct ar9170_usb *aru) { struct device *parent = aru->udev->dev.parent; + struct usb_device *udev; + + /* + * Store a copy of the usb_device pointer locally. + * This is because device_release_driver initiates + * ar9170_usb_disconnect, which in turn frees our + * driver context (aru). + */ + udev = aru->udev; complete(&aru->firmware_loading_complete); /* unbind anything failed */ if (parent) device_lock(parent); - device_release_driver(&aru->udev->dev); + + device_release_driver(&udev->dev); if (parent) device_unlock(parent); - usb_put_dev(aru->udev); + usb_put_dev(udev); } static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context) -- cgit v1.2.3 From 79a78dd6266a4f3e31c800e941ec62e250770a7d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 17 May 2010 09:23:54 +0100 Subject: drm/i915: Fail to load driver if KMS request without GEM The i915's implementation of KMS requires GEM in order to manage the memory and execution domains of the framebuffer and associated resources. By the point at which we detect broken a BIOS and need to disable GEM, we have already registered ourselves as a KMS driver with several subsystems. Rather than introducing a fragile unwind and attempt to continue with UMS, spit out an error and unload the driver. References: [Bug 15754] IP: [] drm_mm_search_free+0x49/0x90 [drm] BUG: unable to handle kernel NULL pointer dereference at (null) https://bugzilla.kernel.org/show_bug.cgi?id=15754 [drm:i915_driver_load] *ERROR* Detected broken video BIOS with 262140/262144kB of video memory stolen. [drm:i915_driver_load] *ERROR* Disabling GEM. (try reducing stolen memory or updating the BIOS to fix). i915 0000:00:02.0: irq 30 for MSI/MSI-X [drm] set up 255M of stolen space BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] drm_mm_search_free+0x49/0x90 [drm] PGD 69719067 PUD 69dda067 PMD 0 Oops: 0000 [#1] PREEMPT SMP last sysfs file: /sys/module/snd_seq_oss/initstate CPU 1 Pid: 867, comm: modprobe Not tainted 2.6.33-ARCH #1 G43Twins-FullHD/To Be Filled By O.E.M. RIP: 0010:[] [] drm_mm_search_free+0x49/0x90 [drm] RSP: 0018:ffff8800699f3af8 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffffffffffffffff RCX: 0000000000000000 RDX: 0000000000001000 RSI: 0000000000001000 RDI: ffff8800693d0f78 RBP: ffff8800699f3b18 R08: 0000000000001000 R09: 0000000000000000 R10: 2222222222222222 R11: 0000000000000000 R12: ffff880068de70c0 R13: 0000000000001000 R14: 0000000000000000 R15: ffff8800689cb000 FS: 00007fa93f4e5700(0000) GS:ffff880001880000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 00000000695a0000 CR4: 00000000000406e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process modprobe (pid: 867, threadinfo ffff8800699f2000, task ffff8800694f4740) Stack: ffff880068de73c0 ffff880068de70c0 ffff8800689cb000 0000000000001000 <0> ffff8800699f3b68 ffffffffa0299f63 ffff8800693d0f78 0000120068de70c0 <0> ffff8800689cb000 ffff880068de73c0 ffff880068de70c0 ffff8800689cb000 Call Trace: [] i915_gem_object_bind_to_gtt+0x83/0x360 [i915] [] i915_gem_object_pin+0xa5/0xb0 [i915] [] i915_gem_init_ringbuffer+0xd5/0x510 [i915] [] i915_driver_load+0x4ce/0xd00 [i915] [] ? drm_sysfs_device_add+0x87/0xb0 [drm] [] ? drm_get_minor+0x1d3/0x330 [drm] [] drm_get_dev+0x326/0x580 [drm] [] i915_pci_probe+0x10/0xd0 [i915] [] local_pci_probe+0x12/0x20 [] pci_device_probe+0x80/0xb0 [] ? driver_sysfs_add+0x5a/0x90 [] driver_probe_device+0x93/0x1a0 [] __driver_attach+0x93/0xa0 [] ? __driver_attach+0x0/0xa0 [] bus_for_each_dev+0x68/0x90 [] driver_attach+0x19/0x20 [] bus_add_driver+0xcd/0x2d0 [] driver_register+0x78/0x140 [] __pci_register_driver+0x51/0xd0 [] ? i915_init+0x0/0x52 [i915] [] drm_init+0x111/0x120 [drm] [] ? register_shrinker+0x4d/0x60 [] ? i915_init+0x0/0x52 [i915] [] i915_init+0x50/0x52 [i915] [] do_one_initcall+0x37/0x1a0 [] sys_init_module+0xd7/0x250 [] system_call_fastpath+0x16/0x1b Code: eb 29 49 8b 41 28 31 d2 49 f7 f5 85 d2 74 39 44 89 c0 29 d0 48 89 c2 48 01 f2 49 39 d2 73 29 0f 1f 00 49 89 da 4c 89 d3 4d 89 d9 <4d> 8b 19 49 39 f9 41 0f 18 0b 74 2b 4d 8b 51 30 4d 89 cc 49 39 RIP [] drm_mm_search_free+0x49/0x90 [drm] RSP CR2: 0000000000000000 Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_dma.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 2a6b5de5ae5d..22d7497e6fa6 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1672,6 +1672,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev_priv->has_gem = 0; } + if (dev_priv->has_gem == 0 && + drm_core_check_feature(dev, DRIVER_MODESET)) { + DRM_ERROR("kernel modesetting requires GEM, disabling driver.\n"); + ret = -ENODEV; + goto out_iomapfree; + } + dev->driver->get_vblank_counter = i915_get_vblank_counter; dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ if (IS_G4X(dev) || IS_IRONLAKE(dev) || IS_GEN6(dev)) { -- cgit v1.2.3 From 62fdfeaf8b1f487060b6e160e7b5cd90287607c9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 21 May 2010 13:26:39 -0700 Subject: drm/i915: Move ringbuffer-related code to intel_ringbuffer.c. This is preparation for supporting multiple ringbuffers on Ironlake. The non-copy-and-paste changes are: - de-staticing functions - I915_GEM_GPU_DOMAINS moving to i915_drv.h to be used by both files. - i915_gem_add_request had only half its implementation copy-and-pasted out of the middle of it. --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/i915_dma.c | 77 ----- drivers/gpu/drm/i915/i915_drv.h | 18 + drivers/gpu/drm/i915/i915_gem.c | 427 +----------------------- drivers/gpu/drm/i915/i915_irq.c | 35 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 568 ++++++++++++++++++++++++++++++++ 6 files changed, 592 insertions(+), 534 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_ringbuffer.c (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 95639017bdbe..da78f2c0d909 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -22,6 +22,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ intel_fb.o \ intel_tv.o \ intel_dvo.o \ + intel_ringbuffer.o \ intel_overlay.o \ dvo_ch7xxx.o \ dvo_ch7017.o \ diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 22d7497e6fa6..a657e3315950 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -40,83 +40,6 @@ #include #include -/* Really want an OS-independent resettable timer. Would like to have - * this loop run for (eg) 3 sec, but have the timer reset every time - * the head pointer changes, so that EBUSY only happens if the ring - * actually stalls for (eg) 3 seconds. - */ -int i915_wait_ring(struct drm_device * dev, int n, const char *caller) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_ring_buffer_t *ring = &(dev_priv->ring); - u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD; - u32 last_acthd = I915_READ(acthd_reg); - u32 acthd; - u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR; - int i; - - trace_i915_ring_wait_begin (dev); - - for (i = 0; i < 100000; i++) { - ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; - acthd = I915_READ(acthd_reg); - ring->space = ring->head - (ring->tail + 8); - if (ring->space < 0) - ring->space += ring->Size; - if (ring->space >= n) { - trace_i915_ring_wait_end (dev); - return 0; - } - - if (dev->primary->master) { - struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - if (master_priv->sarea_priv) - master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; - } - - - if (ring->head != last_head) - i = 0; - if (acthd != last_acthd) - i = 0; - - last_head = ring->head; - last_acthd = acthd; - msleep_interruptible(10); - - } - - trace_i915_ring_wait_end (dev); - return -EBUSY; -} - -/* As a ringbuffer is only allowed to wrap between instructions, fill - * the tail with NOOPs. - */ -int i915_wrap_ring(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - volatile unsigned int *virt; - int rem; - - rem = dev_priv->ring.Size - dev_priv->ring.tail; - if (dev_priv->ring.space < rem) { - int ret = i915_wait_ring(dev, rem, __func__); - if (ret) - return ret; - } - dev_priv->ring.space -= rem; - - virt = (unsigned int *) - (dev_priv->ring.virtual_start + dev_priv->ring.tail); - rem /= 4; - while (rem--) - *virt++ = MI_NOOP; - - dev_priv->ring.tail = 0; - - return 0; -} /** * Sets up the hardware status page for devices that need a physical address diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7f797ef1ab39..114653aa9ae2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -31,6 +31,7 @@ #define _I915_DRV_H_ #include "i915_reg.h" +#include "i915_drm.h" #include "intel_bios.h" #include @@ -55,6 +56,8 @@ enum plane { #define I915_NUM_PIPE 2 +#define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) + /* Interface history: * * 1.1: Original. @@ -849,6 +852,9 @@ extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc); extern int i915_vblank_swap(struct drm_device *dev, void *data, struct drm_file *file_priv); extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask); +extern void i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask); +void ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask); +void ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask); void i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); @@ -956,6 +962,8 @@ void i915_gem_object_flush_write_domain(struct drm_gem_object *obj); void i915_gem_shrinker_init(void); void i915_gem_shrinker_exit(void); +int i915_gem_init_pipe_control(struct drm_device *dev); +void i915_gem_cleanup_pipe_control(struct drm_device *dev); /* i915_gem_tiling.c */ void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); @@ -1006,6 +1014,16 @@ static inline void ironlake_opregion_gse_intr(struct drm_device *dev) { return; static inline void opregion_enable_asle(struct drm_device *dev) { return; } #endif +/* intel_ringbuffer.c */ +extern void i915_gem_flush(struct drm_device *dev, + uint32_t invalidate_domains, + uint32_t flush_domains); +extern int i915_dispatch_gem_execbuffer(struct drm_device *dev, + struct drm_i915_gem_execbuffer2 *exec, + struct drm_clip_rect *cliprects, + uint64_t exec_offset); +extern uint32_t i915_ring_add_request(struct drm_device *dev); + /* modesetting */ extern void intel_modeset_init(struct drm_device *dev); extern void intel_modeset_cleanup(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 112699f71fa4..4f2f5f8cdca2 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -35,8 +35,6 @@ #include #include -#define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) - static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); @@ -1592,22 +1590,6 @@ i915_gem_process_flushing_list(struct drm_device *dev, } } } - -#define PIPE_CONTROL_FLUSH(addr) \ - OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ - PIPE_CONTROL_DEPTH_STALL); \ - OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT); \ - OUT_RING(0); \ - OUT_RING(0); \ - -/** - * Creates a new sequence number, emitting a write of it to the status page - * plus an interrupt, which will trigger i915_user_interrupt_handler. - * - * Must be called with struct_lock held. - * - * Returned sequence numbers are nonzero on success. - */ uint32_t i915_add_request(struct drm_device *dev, struct drm_file *file_priv, uint32_t flush_domains) @@ -1617,7 +1599,6 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, struct drm_i915_gem_request *request; uint32_t seqno; int was_empty; - RING_LOCALS; if (file_priv != NULL) i915_file_priv = file_priv->driver_priv; @@ -1626,55 +1607,7 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, if (request == NULL) return 0; - /* Grab the seqno we're going to make this request be, and bump the - * next (skipping 0 so it can be the reserved no-seqno value). - */ - seqno = dev_priv->mm.next_gem_seqno; - dev_priv->mm.next_gem_seqno++; - if (dev_priv->mm.next_gem_seqno == 0) - dev_priv->mm.next_gem_seqno++; - - if (HAS_PIPE_CONTROL(dev)) { - u32 scratch_addr = dev_priv->seqno_gfx_addr + 128; - - /* - * Workaround qword write incoherence by flushing the - * PIPE_NOTIFY buffers out to memory before requesting - * an interrupt. - */ - BEGIN_LP_RING(32); - OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | - PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); - OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); - OUT_RING(seqno); - OUT_RING(0); - PIPE_CONTROL_FLUSH(scratch_addr); - scratch_addr += 128; /* write to separate cachelines */ - PIPE_CONTROL_FLUSH(scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(scratch_addr); - OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | - PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | - PIPE_CONTROL_NOTIFY); - OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); - OUT_RING(seqno); - OUT_RING(0); - ADVANCE_LP_RING(); - } else { - BEGIN_LP_RING(4); - OUT_RING(MI_STORE_DWORD_INDEX); - OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - OUT_RING(seqno); - - OUT_RING(MI_USER_INTERRUPT); - ADVANCE_LP_RING(); - } + seqno = i915_ring_add_request(dev); DRM_DEBUG_DRIVER("%d\n", seqno); @@ -1933,78 +1866,6 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno) return i915_do_wait_request(dev, seqno, 1); } -static void -i915_gem_flush(struct drm_device *dev, - uint32_t invalidate_domains, - uint32_t flush_domains) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - uint32_t cmd; - RING_LOCALS; - -#if WATCH_EXEC - DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, - invalidate_domains, flush_domains); -#endif - trace_i915_gem_request_flush(dev, dev_priv->mm.next_gem_seqno, - invalidate_domains, flush_domains); - - if (flush_domains & I915_GEM_DOMAIN_CPU) - drm_agp_chipset_flush(dev); - - if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) { - /* - * read/write caches: - * - * I915_GEM_DOMAIN_RENDER is always invalidated, but is - * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is - * also flushed at 2d versus 3d pipeline switches. - * - * read-only caches: - * - * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if - * MI_READ_FLUSH is set, and is always flushed on 965. - * - * I915_GEM_DOMAIN_COMMAND may not exist? - * - * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is - * invalidated when MI_EXE_FLUSH is set. - * - * I915_GEM_DOMAIN_VERTEX, which exists on 965, is - * invalidated with every MI_FLUSH. - * - * TLBs: - * - * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND - * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and - * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER - * are flushed at any MI_FLUSH. - */ - - cmd = MI_FLUSH | MI_NO_WRITE_FLUSH; - if ((invalidate_domains|flush_domains) & - I915_GEM_DOMAIN_RENDER) - cmd &= ~MI_NO_WRITE_FLUSH; - if (!IS_I965G(dev)) { - /* - * On the 965, the sampler cache always gets flushed - * and this bit is reserved. - */ - if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER) - cmd |= MI_READ_FLUSH; - } - if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION) - cmd |= MI_EXE_FLUSH; - -#if WATCH_EXEC - DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd); -#endif - BEGIN_LP_RING(2); - OUT_RING(cmd); - OUT_RING(MI_NOOP); - ADVANCE_LP_RING(); - } -} /** * Ensures that all rendering to the object has completed and the object is @@ -3545,62 +3406,6 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, return 0; } -/** Dispatch a batchbuffer to the ring - */ -static int -i915_dispatch_gem_execbuffer(struct drm_device *dev, - struct drm_i915_gem_execbuffer2 *exec, - struct drm_clip_rect *cliprects, - uint64_t exec_offset) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - int nbox = exec->num_cliprects; - int i = 0, count; - uint32_t exec_start, exec_len; - RING_LOCALS; - - exec_start = (uint32_t) exec_offset + exec->batch_start_offset; - exec_len = (uint32_t) exec->batch_len; - - trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1); - - count = nbox ? nbox : 1; - - for (i = 0; i < count; i++) { - if (i < nbox) { - int ret = i915_emit_box(dev, cliprects, i, - exec->DR1, exec->DR4); - if (ret) - return ret; - } - - if (IS_I830(dev) || IS_845G(dev)) { - BEGIN_LP_RING(4); - OUT_RING(MI_BATCH_BUFFER); - OUT_RING(exec_start | MI_BATCH_NON_SECURE); - OUT_RING(exec_start + exec_len - 4); - OUT_RING(0); - ADVANCE_LP_RING(); - } else { - BEGIN_LP_RING(2); - if (IS_I965G(dev)) { - OUT_RING(MI_BATCH_BUFFER_START | - (2 << 6) | - MI_BATCH_NON_SECURE_I965); - OUT_RING(exec_start); - } else { - OUT_RING(MI_BATCH_BUFFER_START | - (2 << 6)); - OUT_RING(exec_start | MI_BATCH_NON_SECURE); - } - ADVANCE_LP_RING(); - } - } - - /* XXX breadcrumb */ - return 0; -} - /* Throttle our rendering by waiting until the ring has completed our requests * emitted over 20 msec ago. * @@ -4615,7 +4420,7 @@ i915_gem_idle(struct drm_device *dev) * 965+ support PIPE_CONTROL commands, which provide finer grained control * over cache flushing. */ -static int +int i915_gem_init_pipe_control(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -4654,73 +4459,7 @@ err: return ret; } -static int -i915_gem_init_hws(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - int ret; - - /* If we need a physical address for the status page, it's already - * initialized at driver load time. - */ - if (!I915_NEED_GFX_HWS(dev)) - return 0; - - obj = i915_gem_alloc_object(dev, 4096); - if (obj == NULL) { - DRM_ERROR("Failed to allocate status page\n"); - ret = -ENOMEM; - goto err; - } - obj_priv = to_intel_bo(obj); - obj_priv->agp_type = AGP_USER_CACHED_MEMORY; - - ret = i915_gem_object_pin(obj, 4096); - if (ret != 0) { - drm_gem_object_unreference(obj); - goto err_unref; - } - - dev_priv->status_gfx_addr = obj_priv->gtt_offset; - - dev_priv->hw_status_page = kmap(obj_priv->pages[0]); - if (dev_priv->hw_status_page == NULL) { - DRM_ERROR("Failed to map status page.\n"); - memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); - ret = -EINVAL; - goto err_unpin; - } - - if (HAS_PIPE_CONTROL(dev)) { - ret = i915_gem_init_pipe_control(dev); - if (ret) - goto err_unpin; - } - - dev_priv->hws_obj = obj; - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - if (IS_GEN6(dev)) { - I915_WRITE(HWS_PGA_GEN6, dev_priv->status_gfx_addr); - I915_READ(HWS_PGA_GEN6); /* posting read */ - } else { - I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); - I915_READ(HWS_PGA); /* posting read */ - } - DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr); - - return 0; - -err_unpin: - i915_gem_object_unpin(obj); -err_unref: - drm_gem_object_unreference(obj); -err: - return 0; -} - -static void +void i915_gem_cleanup_pipe_control(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -4737,166 +4476,6 @@ i915_gem_cleanup_pipe_control(struct drm_device *dev) dev_priv->seqno_page = NULL; } -static void -i915_gem_cleanup_hws(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - - if (dev_priv->hws_obj == NULL) - return; - - obj = dev_priv->hws_obj; - obj_priv = to_intel_bo(obj); - - kunmap(obj_priv->pages[0]); - i915_gem_object_unpin(obj); - drm_gem_object_unreference(obj); - dev_priv->hws_obj = NULL; - - memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); - dev_priv->hw_status_page = NULL; - - if (HAS_PIPE_CONTROL(dev)) - i915_gem_cleanup_pipe_control(dev); - - /* Write high address into HWS_PGA when disabling. */ - I915_WRITE(HWS_PGA, 0x1ffff000); -} - -int -i915_gem_init_ringbuffer(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - drm_i915_ring_buffer_t *ring = &dev_priv->ring; - int ret; - u32 head; - - ret = i915_gem_init_hws(dev); - if (ret != 0) - return ret; - - obj = i915_gem_alloc_object(dev, 128 * 1024); - if (obj == NULL) { - DRM_ERROR("Failed to allocate ringbuffer\n"); - i915_gem_cleanup_hws(dev); - return -ENOMEM; - } - obj_priv = to_intel_bo(obj); - - ret = i915_gem_object_pin(obj, 4096); - if (ret != 0) { - drm_gem_object_unreference(obj); - i915_gem_cleanup_hws(dev); - return ret; - } - - /* Set up the kernel mapping for the ring. */ - ring->Size = obj->size; - - ring->map.offset = dev->agp->base + obj_priv->gtt_offset; - ring->map.size = obj->size; - ring->map.type = 0; - ring->map.flags = 0; - ring->map.mtrr = 0; - - drm_core_ioremap_wc(&ring->map, dev); - if (ring->map.handle == NULL) { - DRM_ERROR("Failed to map ringbuffer.\n"); - memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); - i915_gem_object_unpin(obj); - drm_gem_object_unreference(obj); - i915_gem_cleanup_hws(dev); - return -EINVAL; - } - ring->ring_obj = obj; - ring->virtual_start = ring->map.handle; - - /* Stop the ring if it's running. */ - I915_WRITE(PRB0_CTL, 0); - I915_WRITE(PRB0_TAIL, 0); - I915_WRITE(PRB0_HEAD, 0); - - /* Initialize the ring. */ - I915_WRITE(PRB0_START, obj_priv->gtt_offset); - head = I915_READ(PRB0_HEAD) & HEAD_ADDR; - - /* G45 ring initialization fails to reset head to zero */ - if (head != 0) { - DRM_ERROR("Ring head not reset to zero " - "ctl %08x head %08x tail %08x start %08x\n", - I915_READ(PRB0_CTL), - I915_READ(PRB0_HEAD), - I915_READ(PRB0_TAIL), - I915_READ(PRB0_START)); - I915_WRITE(PRB0_HEAD, 0); - - DRM_ERROR("Ring head forced to zero " - "ctl %08x head %08x tail %08x start %08x\n", - I915_READ(PRB0_CTL), - I915_READ(PRB0_HEAD), - I915_READ(PRB0_TAIL), - I915_READ(PRB0_START)); - } - - I915_WRITE(PRB0_CTL, - ((obj->size - 4096) & RING_NR_PAGES) | - RING_NO_REPORT | - RING_VALID); - - head = I915_READ(PRB0_HEAD) & HEAD_ADDR; - - /* If the head is still not zero, the ring is dead */ - if (head != 0) { - DRM_ERROR("Ring initialization failed " - "ctl %08x head %08x tail %08x start %08x\n", - I915_READ(PRB0_CTL), - I915_READ(PRB0_HEAD), - I915_READ(PRB0_TAIL), - I915_READ(PRB0_START)); - return -EIO; - } - - /* Update our cache of the ring state */ - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - i915_kernel_lost_context(dev); - else { - ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; - ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; - ring->space = ring->head - (ring->tail + 8); - if (ring->space < 0) - ring->space += ring->Size; - } - - if (IS_I9XX(dev) && !IS_GEN3(dev)) { - I915_WRITE(MI_MODE, - (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH); - } - - return 0; -} - -void -i915_gem_cleanup_ringbuffer(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - - if (dev_priv->ring.ring_obj == NULL) - return; - - drm_core_ioremapfree(&dev_priv->ring.map, dev); - - i915_gem_object_unpin(dev_priv->ring.ring_obj); - drm_gem_object_unreference(dev_priv->ring.ring_obj); - dev_priv->ring.ring_obj = NULL; - memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); - - i915_gem_cleanup_hws(dev); -} - int i915_gem_entervt_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 8c3f0802686d..896184bfeb12 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -74,7 +74,7 @@ ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) } } -static inline void +void ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) { if ((dev_priv->gt_irq_mask_reg & mask) != mask) { @@ -115,7 +115,7 @@ i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask) } } -static inline void +void i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask) { if ((dev_priv->irq_mask_reg & mask) != mask) { @@ -1006,37 +1006,6 @@ static int i915_emit_irq(struct drm_device * dev) return dev_priv->counter; } -void i915_user_irq_get(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); - if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) { - if (HAS_PCH_SPLIT(dev)) - ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); - else - i915_enable_irq(dev_priv, I915_USER_INTERRUPT); - } - spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); -} - -void i915_user_irq_put(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); - BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0); - if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { - if (HAS_PCH_SPLIT(dev)) - ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); - else - i915_disable_irq(dev_priv, I915_USER_INTERRUPT); - } - spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); -} - void i915_trace_irq_get(struct drm_device *dev, u32 seqno) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c new file mode 100644 index 000000000000..13a796fafaee --- /dev/null +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -0,0 +1,568 @@ +/* + * Copyright © 2008-2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + * Zou Nan hai + * Xiang Hai hao + * + */ + +#include "drmP.h" +#include "drm.h" +#include "i915_drm.h" +#include "i915_drv.h" +#include "i915_trace.h" +#include "intel_drv.h" + +void +i915_gem_flush(struct drm_device *dev, + uint32_t invalidate_domains, + uint32_t flush_domains) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + uint32_t cmd; + RING_LOCALS; + +#if WATCH_EXEC + DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, + invalidate_domains, flush_domains); +#endif + trace_i915_gem_request_flush(dev, dev_priv->mm.next_gem_seqno, + invalidate_domains, flush_domains); + + if (flush_domains & I915_GEM_DOMAIN_CPU) + drm_agp_chipset_flush(dev); + + if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) { + /* + * read/write caches: + * + * I915_GEM_DOMAIN_RENDER is always invalidated, but is + * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is + * also flushed at 2d versus 3d pipeline switches. + * + * read-only caches: + * + * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if + * MI_READ_FLUSH is set, and is always flushed on 965. + * + * I915_GEM_DOMAIN_COMMAND may not exist? + * + * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is + * invalidated when MI_EXE_FLUSH is set. + * + * I915_GEM_DOMAIN_VERTEX, which exists on 965, is + * invalidated with every MI_FLUSH. + * + * TLBs: + * + * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND + * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and + * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER + * are flushed at any MI_FLUSH. + */ + + cmd = MI_FLUSH | MI_NO_WRITE_FLUSH; + if ((invalidate_domains|flush_domains) & + I915_GEM_DOMAIN_RENDER) + cmd &= ~MI_NO_WRITE_FLUSH; + if (!IS_I965G(dev)) { + /* + * On the 965, the sampler cache always gets flushed + * and this bit is reserved. + */ + if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER) + cmd |= MI_READ_FLUSH; + } + if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION) + cmd |= MI_EXE_FLUSH; + +#if WATCH_EXEC + DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd); +#endif + BEGIN_LP_RING(2); + OUT_RING(cmd); + OUT_RING(MI_NOOP); + ADVANCE_LP_RING(); + } + +} +#define PIPE_CONTROL_FLUSH(addr) \ + OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ + PIPE_CONTROL_DEPTH_STALL); \ + OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT); \ + OUT_RING(0); \ + OUT_RING(0); \ + +/** + * Creates a new sequence number, emitting a write of it to the status page + * plus an interrupt, which will trigger i915_user_interrupt_handler. + * + * Must be called with struct_lock held. + * + * Returned sequence numbers are nonzero on success. + */ +uint32_t +i915_ring_add_request(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + uint32_t seqno; + RING_LOCALS; + + /* Grab the seqno we're going to make this request be, and bump the + * next (skipping 0 so it can be the reserved no-seqno value). + */ + seqno = dev_priv->mm.next_gem_seqno; + dev_priv->mm.next_gem_seqno++; + if (dev_priv->mm.next_gem_seqno == 0) + dev_priv->mm.next_gem_seqno++; + + if (HAS_PIPE_CONTROL(dev)) { + u32 scratch_addr = dev_priv->seqno_gfx_addr + 128; + + /* + * Workaround qword write incoherence by flushing the + * PIPE_NOTIFY buffers out to memory before requesting + * an interrupt. + */ + BEGIN_LP_RING(32); + OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | + PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); + OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); + OUT_RING(seqno); + OUT_RING(0); + PIPE_CONTROL_FLUSH(scratch_addr); + scratch_addr += 128; /* write to separate cachelines */ + PIPE_CONTROL_FLUSH(scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(scratch_addr); + OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | + PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | + PIPE_CONTROL_NOTIFY); + OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); + OUT_RING(seqno); + OUT_RING(0); + ADVANCE_LP_RING(); + } else { + BEGIN_LP_RING(4); + OUT_RING(MI_STORE_DWORD_INDEX); + OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + OUT_RING(seqno); + + OUT_RING(MI_USER_INTERRUPT); + ADVANCE_LP_RING(); + } + return seqno; +} + +void i915_user_irq_get(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + unsigned long irqflags; + + spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); + if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) { + if (HAS_PCH_SPLIT(dev)) + ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); + else + i915_enable_irq(dev_priv, I915_USER_INTERRUPT); + } + spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); +} + +void i915_user_irq_put(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + unsigned long irqflags; + + spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); + BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0); + if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { + if (HAS_PCH_SPLIT(dev)) + ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); + else + i915_disable_irq(dev_priv, I915_USER_INTERRUPT); + } + spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); +} + +/** Dispatch a batchbuffer to the ring + */ +int +i915_dispatch_gem_execbuffer(struct drm_device *dev, + struct drm_i915_gem_execbuffer2 *exec, + struct drm_clip_rect *cliprects, + uint64_t exec_offset) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + int nbox = exec->num_cliprects; + int i = 0, count; + uint32_t exec_start, exec_len; + RING_LOCALS; + + exec_start = (uint32_t) exec_offset + exec->batch_start_offset; + exec_len = (uint32_t) exec->batch_len; + + trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1); + + count = nbox ? nbox : 1; + + for (i = 0; i < count; i++) { + if (i < nbox) { + int ret = i915_emit_box(dev, cliprects, i, + exec->DR1, exec->DR4); + if (ret) + return ret; + } + + if (IS_I830(dev) || IS_845G(dev)) { + BEGIN_LP_RING(4); + OUT_RING(MI_BATCH_BUFFER); + OUT_RING(exec_start | MI_BATCH_NON_SECURE); + OUT_RING(exec_start + exec_len - 4); + OUT_RING(0); + ADVANCE_LP_RING(); + } else { + BEGIN_LP_RING(2); + if (IS_I965G(dev)) { + OUT_RING(MI_BATCH_BUFFER_START | + (2 << 6) | + MI_BATCH_NON_SECURE_I965); + OUT_RING(exec_start); + } else { + OUT_RING(MI_BATCH_BUFFER_START | + (2 << 6)); + OUT_RING(exec_start | MI_BATCH_NON_SECURE); + } + ADVANCE_LP_RING(); + } + } + + /* XXX breadcrumb */ + return 0; +} + +static void +i915_gem_cleanup_hws(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_gem_object *obj; + struct drm_i915_gem_object *obj_priv; + + if (dev_priv->hws_obj == NULL) + return; + + obj = dev_priv->hws_obj; + obj_priv = to_intel_bo(obj); + + kunmap(obj_priv->pages[0]); + i915_gem_object_unpin(obj); + drm_gem_object_unreference(obj); + dev_priv->hws_obj = NULL; + + memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); + dev_priv->hw_status_page = NULL; + + if (HAS_PIPE_CONTROL(dev)) + i915_gem_cleanup_pipe_control(dev); + + /* Write high address into HWS_PGA when disabling. */ + I915_WRITE(HWS_PGA, 0x1ffff000); +} + +static int +i915_gem_init_hws(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_gem_object *obj; + struct drm_i915_gem_object *obj_priv; + int ret; + + /* If we need a physical address for the status page, it's already + * initialized at driver load time. + */ + if (!I915_NEED_GFX_HWS(dev)) + return 0; + + obj = i915_gem_alloc_object(dev, 4096); + if (obj == NULL) { + DRM_ERROR("Failed to allocate status page\n"); + ret = -ENOMEM; + goto err; + } + obj_priv = to_intel_bo(obj); + obj_priv->agp_type = AGP_USER_CACHED_MEMORY; + + ret = i915_gem_object_pin(obj, 4096); + if (ret != 0) { + drm_gem_object_unreference(obj); + goto err_unref; + } + + dev_priv->status_gfx_addr = obj_priv->gtt_offset; + + dev_priv->hw_status_page = kmap(obj_priv->pages[0]); + if (dev_priv->hw_status_page == NULL) { + DRM_ERROR("Failed to map status page.\n"); + memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); + ret = -EINVAL; + goto err_unpin; + } + + if (HAS_PIPE_CONTROL(dev)) { + ret = i915_gem_init_pipe_control(dev); + if (ret) + goto err_unpin; + } + + dev_priv->hws_obj = obj; + memset(dev_priv->hw_status_page, 0, PAGE_SIZE); + if (IS_GEN6(dev)) { + I915_WRITE(HWS_PGA_GEN6, dev_priv->status_gfx_addr); + I915_READ(HWS_PGA_GEN6); /* posting read */ + } else { + I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); + I915_READ(HWS_PGA); /* posting read */ + } + DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr); + + return 0; + +err_unpin: + i915_gem_object_unpin(obj); +err_unref: + drm_gem_object_unreference(obj); +err: + return 0; +} + +int +i915_gem_init_ringbuffer(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_gem_object *obj; + struct drm_i915_gem_object *obj_priv; + drm_i915_ring_buffer_t *ring = &dev_priv->ring; + int ret; + u32 head; + + ret = i915_gem_init_hws(dev); + if (ret != 0) + return ret; + + obj = i915_gem_alloc_object(dev, 128 * 1024); + if (obj == NULL) { + DRM_ERROR("Failed to allocate ringbuffer\n"); + i915_gem_cleanup_hws(dev); + return -ENOMEM; + } + obj_priv = to_intel_bo(obj); + + ret = i915_gem_object_pin(obj, 4096); + if (ret != 0) { + drm_gem_object_unreference(obj); + i915_gem_cleanup_hws(dev); + return ret; + } + + /* Set up the kernel mapping for the ring. */ + ring->Size = obj->size; + + ring->map.offset = dev->agp->base + obj_priv->gtt_offset; + ring->map.size = obj->size; + ring->map.type = 0; + ring->map.flags = 0; + ring->map.mtrr = 0; + + drm_core_ioremap_wc(&ring->map, dev); + if (ring->map.handle == NULL) { + DRM_ERROR("Failed to map ringbuffer.\n"); + memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); + i915_gem_object_unpin(obj); + drm_gem_object_unreference(obj); + i915_gem_cleanup_hws(dev); + return -EINVAL; + } + ring->ring_obj = obj; + ring->virtual_start = ring->map.handle; + + /* Stop the ring if it's running. */ + I915_WRITE(PRB0_CTL, 0); + I915_WRITE(PRB0_TAIL, 0); + I915_WRITE(PRB0_HEAD, 0); + + /* Initialize the ring. */ + I915_WRITE(PRB0_START, obj_priv->gtt_offset); + head = I915_READ(PRB0_HEAD) & HEAD_ADDR; + + /* G45 ring initialization fails to reset head to zero */ + if (head != 0) { + DRM_ERROR("Ring head not reset to zero " + "ctl %08x head %08x tail %08x start %08x\n", + I915_READ(PRB0_CTL), + I915_READ(PRB0_HEAD), + I915_READ(PRB0_TAIL), + I915_READ(PRB0_START)); + I915_WRITE(PRB0_HEAD, 0); + + DRM_ERROR("Ring head forced to zero " + "ctl %08x head %08x tail %08x start %08x\n", + I915_READ(PRB0_CTL), + I915_READ(PRB0_HEAD), + I915_READ(PRB0_TAIL), + I915_READ(PRB0_START)); + } + + I915_WRITE(PRB0_CTL, + ((obj->size - 4096) & RING_NR_PAGES) | + RING_NO_REPORT | + RING_VALID); + + head = I915_READ(PRB0_HEAD) & HEAD_ADDR; + + /* If the head is still not zero, the ring is dead */ + if (head != 0) { + DRM_ERROR("Ring initialization failed " + "ctl %08x head %08x tail %08x start %08x\n", + I915_READ(PRB0_CTL), + I915_READ(PRB0_HEAD), + I915_READ(PRB0_TAIL), + I915_READ(PRB0_START)); + return -EIO; + } + + /* Update our cache of the ring state */ + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + i915_kernel_lost_context(dev); + else { + ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; + ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; + ring->space = ring->head - (ring->tail + 8); + if (ring->space < 0) + ring->space += ring->Size; + } + + if (IS_I9XX(dev) && !IS_GEN3(dev)) { + I915_WRITE(MI_MODE, + (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH); + } + + return 0; +} + +void +i915_gem_cleanup_ringbuffer(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + + if (dev_priv->ring.ring_obj == NULL) + return; + + drm_core_ioremapfree(&dev_priv->ring.map, dev); + + i915_gem_object_unpin(dev_priv->ring.ring_obj); + drm_gem_object_unreference(dev_priv->ring.ring_obj); + dev_priv->ring.ring_obj = NULL; + memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); + + i915_gem_cleanup_hws(dev); +} + +/* As a ringbuffer is only allowed to wrap between instructions, fill + * the tail with NOOPs. + */ +int i915_wrap_ring(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + volatile unsigned int *virt; + int rem; + + rem = dev_priv->ring.Size - dev_priv->ring.tail; + if (dev_priv->ring.space < rem) { + int ret = i915_wait_ring(dev, rem, __func__); + if (ret) + return ret; + } + dev_priv->ring.space -= rem; + + virt = (unsigned int *) + (dev_priv->ring.virtual_start + dev_priv->ring.tail); + rem /= 4; + while (rem--) + *virt++ = MI_NOOP; + + dev_priv->ring.tail = 0; + + return 0; +} + +int i915_wait_ring(struct drm_device * dev, int n, const char *caller) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + drm_i915_ring_buffer_t *ring = &(dev_priv->ring); + u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD; + u32 last_acthd = I915_READ(acthd_reg); + u32 acthd; + u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR; + int i; + + trace_i915_ring_wait_begin (dev); + + for (i = 0; i < 100000; i++) { + ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; + acthd = I915_READ(acthd_reg); + ring->space = ring->head - (ring->tail + 8); + if (ring->space < 0) + ring->space += ring->Size; + if (ring->space >= n) { + trace_i915_ring_wait_end (dev); + return 0; + } + + if (dev->primary->master) { + struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; + if (master_priv->sarea_priv) + master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; + } + + + if (ring->head != last_head) + i = 0; + if (acthd != last_acthd) + i = 0; + + last_head = ring->head; + last_acthd = acthd; + msleep_interruptible(10); + + } + + trace_i915_ring_wait_end (dev); + return -EBUSY; +} -- cgit v1.2.3 From d3301d86b4bf2bcf649982ae464211d8bcf9575a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 21 May 2010 13:55:54 -0700 Subject: drm/i915: Rename dev_priv->ring to dev_priv->render_ring. With the advent of the BSD ring, be clear about which ring this is. The docs are pretty consistent with calling this the Render engine at this point. --- drivers/gpu/drm/i915/i915_debugfs.c | 8 +++---- drivers/gpu/drm/i915/i915_dma.c | 38 ++++++++++++++++----------------- drivers/gpu/drm/i915/i915_drv.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 20 ++++++++--------- drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/i915/i915_irq.c | 12 +++++------ drivers/gpu/drm/i915/intel_ringbuffer.c | 28 ++++++++++++------------ 7 files changed, 55 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 322070c0c631..488175c70c7d 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -317,14 +317,14 @@ static int i915_ringbuffer_data(struct seq_file *m, void *data) u8 *virt; uint32_t *ptr, off; - if (!dev_priv->ring.ring_obj) { + if (!dev_priv->render_ring.ring_obj) { seq_printf(m, "No ringbuffer setup\n"); return 0; } - virt = dev_priv->ring.virtual_start; + virt = dev_priv->render_ring.virtual_start; - for (off = 0; off < dev_priv->ring.Size; off += 4) { + for (off = 0; off < dev_priv->render_ring.Size; off += 4) { ptr = (uint32_t *)(virt + off); seq_printf(m, "%08x : %08x\n", off, *ptr); } @@ -344,7 +344,7 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) seq_printf(m, "RingHead : %08x\n", head); seq_printf(m, "RingTail : %08x\n", tail); - seq_printf(m, "RingSize : %08lx\n", dev_priv->ring.Size); + seq_printf(m, "RingSize : %08lx\n", dev_priv->render_ring.Size); seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD)); return 0; diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a657e3315950..6de7eace4319 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -95,7 +95,7 @@ void i915_kernel_lost_context(struct drm_device * dev) { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_master_private *master_priv; - drm_i915_ring_buffer_t *ring = &(dev_priv->ring); + drm_i915_ring_buffer_t *ring = &(dev_priv->render_ring); /* * We should never lose context on the ring with modesetting @@ -128,11 +128,11 @@ static int i915_dma_cleanup(struct drm_device * dev) if (dev->irq_enabled) drm_irq_uninstall(dev); - if (dev_priv->ring.virtual_start) { - drm_core_ioremapfree(&dev_priv->ring.map, dev); - dev_priv->ring.virtual_start = NULL; - dev_priv->ring.map.handle = NULL; - dev_priv->ring.map.size = 0; + if (dev_priv->render_ring.virtual_start) { + drm_core_ioremapfree(&dev_priv->render_ring.map, dev); + dev_priv->render_ring.virtual_start = NULL; + dev_priv->render_ring.map.handle = NULL; + dev_priv->render_ring.map.size = 0; } /* Clear the HWS virtual address at teardown */ @@ -156,24 +156,24 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) } if (init->ring_size != 0) { - if (dev_priv->ring.ring_obj != NULL) { + if (dev_priv->render_ring.ring_obj != NULL) { i915_dma_cleanup(dev); DRM_ERROR("Client tried to initialize ringbuffer in " "GEM mode\n"); return -EINVAL; } - dev_priv->ring.Size = init->ring_size; + dev_priv->render_ring.Size = init->ring_size; - dev_priv->ring.map.offset = init->ring_start; - dev_priv->ring.map.size = init->ring_size; - dev_priv->ring.map.type = 0; - dev_priv->ring.map.flags = 0; - dev_priv->ring.map.mtrr = 0; + dev_priv->render_ring.map.offset = init->ring_start; + dev_priv->render_ring.map.size = init->ring_size; + dev_priv->render_ring.map.type = 0; + dev_priv->render_ring.map.flags = 0; + dev_priv->render_ring.map.mtrr = 0; - drm_core_ioremap_wc(&dev_priv->ring.map, dev); + drm_core_ioremap_wc(&dev_priv->render_ring.map, dev); - if (dev_priv->ring.map.handle == NULL) { + if (dev_priv->render_ring.map.handle == NULL) { i915_dma_cleanup(dev); DRM_ERROR("can not ioremap virtual address for" " ring buffer\n"); @@ -181,7 +181,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) } } - dev_priv->ring.virtual_start = dev_priv->ring.map.handle; + dev_priv->render_ring.virtual_start = dev_priv->render_ring.map.handle; dev_priv->cpp = init->cpp; dev_priv->back_offset = init->back_offset; @@ -203,7 +203,7 @@ static int i915_dma_resume(struct drm_device * dev) DRM_DEBUG_DRIVER("%s\n", __func__); - if (dev_priv->ring.map.handle == NULL) { + if (dev_priv->render_ring.map.handle == NULL) { DRM_ERROR("can not ioremap virtual address for" " ring buffer\n"); return -ENOMEM; @@ -332,7 +332,7 @@ static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords) int i; RING_LOCALS; - if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8) + if ((dwords+1) * sizeof(int) >= dev_priv->render_ring.Size - 8) return -EINVAL; BEGIN_LP_RING((dwords+1)&~1); @@ -563,7 +563,7 @@ static int i915_quiescent(struct drm_device * dev) drm_i915_private_t *dev_priv = dev->dev_private; i915_kernel_lost_context(dev); - return i915_wait_ring(dev, dev_priv->ring.Size - 8, __func__); + return i915_wait_ring(dev, dev_priv->render_ring.Size - 8, __func__); } static int i915_flush_ioctl(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 5c51e45ab68d..a1814f65fdb4 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -389,7 +389,7 @@ int i965_reset(struct drm_device *dev, u8 flags) */ if (drm_core_check_feature(dev, DRIVER_MODESET) || !dev_priv->mm.suspended) { - drm_i915_ring_buffer_t *ring = &dev_priv->ring; + drm_i915_ring_buffer_t *ring = &dev_priv->render_ring; struct drm_gem_object *obj = ring->ring_obj; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); dev_priv->mm.suspended = 0; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 114653aa9ae2..a39440cf1dee 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -244,7 +244,7 @@ typedef struct drm_i915_private { void __iomem *regs; struct pci_dev *bridge_dev; - drm_i915_ring_buffer_t ring; + drm_i915_ring_buffer_t render_ring; drm_dma_handle_t *status_page_dmah; void *hw_status_page; @@ -1044,7 +1044,7 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); * has access to the ring. */ #define RING_LOCK_TEST_WITH_RETURN(dev, file_priv) do { \ - if (((drm_i915_private_t *)dev->dev_private)->ring.ring_obj == NULL) \ + if (((drm_i915_private_t *)dev->dev_private)->render_ring.ring_obj == NULL) \ LOCK_TEST_WITH_RETURN(dev, file_priv); \ } while (0) @@ -1066,15 +1066,15 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); int bytes__ = 4*(n); \ if (I915_VERBOSE) DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \ /* a wrap must occur between instructions so pad beforehand */ \ - if (unlikely (dev_priv->ring.tail + bytes__ > dev_priv->ring.Size)) \ + if (unlikely (dev_priv->render_ring.tail + bytes__ > dev_priv->render_ring.Size)) \ i915_wrap_ring(dev); \ - if (unlikely (dev_priv->ring.space < bytes__)) \ + if (unlikely (dev_priv->render_ring.space < bytes__)) \ i915_wait_ring(dev, bytes__, __func__); \ ring_virt__ = (unsigned int *) \ - (dev_priv->ring.virtual_start + dev_priv->ring.tail); \ - dev_priv->ring.tail += bytes__; \ - dev_priv->ring.tail &= dev_priv->ring.Size - 1; \ - dev_priv->ring.space -= bytes__; \ + (dev_priv->render_ring.virtual_start + dev_priv->render_ring.tail); \ + dev_priv->render_ring.tail += bytes__; \ + dev_priv->render_ring.tail &= dev_priv->render_ring.Size - 1; \ + dev_priv->render_ring.space -= bytes__; \ } while (0) #define OUT_RING(n) do { \ @@ -1084,8 +1084,8 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); #define ADVANCE_LP_RING() do { \ if (I915_VERBOSE) \ - DRM_DEBUG("ADVANCE_LP_RING %x\n", dev_priv->ring.tail); \ - I915_WRITE(PRB0_TAIL, dev_priv->ring.tail); \ + DRM_DEBUG("ADVANCE_LP_RING %x\n", dev_priv->render_ring.tail); \ + I915_WRITE(PRB0_TAIL, dev_priv->render_ring.tail); \ } while(0) /** diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4f2f5f8cdca2..95dbe5628a25 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4378,7 +4378,7 @@ i915_gem_idle(struct drm_device *dev) mutex_lock(&dev->struct_mutex); - if (dev_priv->mm.suspended || dev_priv->ring.ring_obj == NULL) { + if (dev_priv->mm.suspended || dev_priv->render_ring.ring_obj == NULL) { mutex_unlock(&dev->struct_mutex); return 0; } diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 896184bfeb12..dd91c97de968 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -536,17 +536,17 @@ i915_ringbuffer_last_batch(struct drm_device *dev) */ bbaddr = 0; head = I915_READ(PRB0_HEAD) & HEAD_ADDR; - ring = (u32 *)(dev_priv->ring.virtual_start + head); + ring = (u32 *)(dev_priv->render_ring.virtual_start + head); - while (--ring >= (u32 *)dev_priv->ring.virtual_start) { + while (--ring >= (u32 *)dev_priv->render_ring.virtual_start) { bbaddr = i915_get_bbaddr(dev, ring); if (bbaddr) break; } if (bbaddr == 0) { - ring = (u32 *)(dev_priv->ring.virtual_start + dev_priv->ring.Size); - while (--ring >= (u32 *)dev_priv->ring.virtual_start) { + ring = (u32 *)(dev_priv->render_ring.virtual_start + dev_priv->render_ring.Size); + while (--ring >= (u32 *)dev_priv->render_ring.virtual_start) { bbaddr = i915_get_bbaddr(dev, ring); if (bbaddr) break; @@ -639,7 +639,7 @@ static void i915_capture_error_state(struct drm_device *dev) error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); /* Record the ringbuffer */ - error->ringbuffer = i915_error_object_create(dev, dev_priv->ring.ring_obj); + error->ringbuffer = i915_error_object_create(dev, dev_priv->render_ring.ring_obj); /* Record buffers on the active list. */ error->active_bo = NULL; @@ -1056,7 +1056,7 @@ int i915_irq_emit(struct drm_device *dev, void *data, drm_i915_irq_emit_t *emit = data; int result; - if (!dev_priv || !dev_priv->ring.virtual_start) { + if (!dev_priv || !dev_priv->render_ring.virtual_start) { DRM_ERROR("called with no initialization\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 13a796fafaee..06058ddb4eed 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -368,7 +368,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; struct drm_gem_object *obj; struct drm_i915_gem_object *obj_priv; - drm_i915_ring_buffer_t *ring = &dev_priv->ring; + drm_i915_ring_buffer_t *ring = &dev_priv->render_ring; int ret; u32 head; @@ -403,7 +403,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev) drm_core_ioremap_wc(&ring->map, dev); if (ring->map.handle == NULL) { DRM_ERROR("Failed to map ringbuffer.\n"); - memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); + memset(&dev_priv->render_ring, 0, sizeof(dev_priv->render_ring)); i915_gem_object_unpin(obj); drm_gem_object_unreference(obj); i915_gem_cleanup_hws(dev); @@ -481,15 +481,15 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; - if (dev_priv->ring.ring_obj == NULL) + if (dev_priv->render_ring.ring_obj == NULL) return; - drm_core_ioremapfree(&dev_priv->ring.map, dev); + drm_core_ioremapfree(&dev_priv->render_ring.map, dev); - i915_gem_object_unpin(dev_priv->ring.ring_obj); - drm_gem_object_unreference(dev_priv->ring.ring_obj); - dev_priv->ring.ring_obj = NULL; - memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); + i915_gem_object_unpin(dev_priv->render_ring.ring_obj); + drm_gem_object_unreference(dev_priv->render_ring.ring_obj); + dev_priv->render_ring.ring_obj = NULL; + memset(&dev_priv->render_ring, 0, sizeof(dev_priv->render_ring)); i915_gem_cleanup_hws(dev); } @@ -503,21 +503,21 @@ int i915_wrap_ring(struct drm_device *dev) volatile unsigned int *virt; int rem; - rem = dev_priv->ring.Size - dev_priv->ring.tail; - if (dev_priv->ring.space < rem) { + rem = dev_priv->render_ring.Size - dev_priv->render_ring.tail; + if (dev_priv->render_ring.space < rem) { int ret = i915_wait_ring(dev, rem, __func__); if (ret) return ret; } - dev_priv->ring.space -= rem; + dev_priv->render_ring.space -= rem; virt = (unsigned int *) - (dev_priv->ring.virtual_start + dev_priv->ring.tail); + (dev_priv->render_ring.virtual_start + dev_priv->render_ring.tail); rem /= 4; while (rem--) *virt++ = MI_NOOP; - dev_priv->ring.tail = 0; + dev_priv->render_ring.tail = 0; return 0; } @@ -525,7 +525,7 @@ int i915_wrap_ring(struct drm_device *dev) int i915_wait_ring(struct drm_device * dev, int n, const char *caller) { drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_ring_buffer_t *ring = &(dev_priv->ring); + drm_i915_ring_buffer_t *ring = &(dev_priv->render_ring); u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD; u32 last_acthd = I915_READ(acthd_reg); u32 acthd; -- cgit v1.2.3 From f27ec1d6db4aa3348ca7be896f1466599aecea3e Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Wed, 26 May 2010 13:15:06 -0700 Subject: IB/qib: Don't rely on (undefined) order of function parameter evaluation Some of the qib sysfs code passes a buffer pointer into simple_read_from_buffer() but relies on a function call in another parameter of the same call to initialize that pointer. Since the order of evaluation of function parameters is undefined, this will break if gcc chooses the wrong order. Fix this by splitting the code into two separate function calls. This was noticed because of warnings like the following on ppc: drivers/infiniband/hw/qib/qib_fs.c: In function 'portcntrs_2_read': drivers/infiniband/hw/qib/qib_fs.c:203: warning: 'counters' is used uninitialized in this function Reported-by: Stephen Rothwell Signed-off-by: Roland Dreier --- drivers/infiniband/hw/qib/qib_fs.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c index 755470440ef1..edef8527eb34 100644 --- a/drivers/infiniband/hw/qib/qib_fs.c +++ b/drivers/infiniband/hw/qib/qib_fs.c @@ -144,10 +144,11 @@ static ssize_t dev_counters_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { u64 *counters; + size_t avail; struct qib_devdata *dd = private2dd(file); - return simple_read_from_buffer(buf, count, ppos, counters, - dd->f_read_cntrs(dd, *ppos, NULL, &counters)); + avail = dd->f_read_cntrs(dd, *ppos, NULL, &counters); + return simple_read_from_buffer(buf, count, ppos, counters, avail); } /* read the per-device counters */ @@ -155,10 +156,11 @@ static ssize_t dev_names_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { char *names; + size_t avail; struct qib_devdata *dd = private2dd(file); - return simple_read_from_buffer(buf, count, ppos, names, - dd->f_read_cntrs(dd, *ppos, &names, NULL)); + avail = dd->f_read_cntrs(dd, *ppos, &names, NULL); + return simple_read_from_buffer(buf, count, ppos, names, avail); } static const struct file_operations cntr_ops[] = { @@ -176,10 +178,11 @@ static ssize_t portnames_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { char *names; + size_t avail; struct qib_devdata *dd = private2dd(file); - return simple_read_from_buffer(buf, count, ppos, names, - dd->f_read_portcntrs(dd, *ppos, 0, &names, NULL)); + avail = dd->f_read_portcntrs(dd, *ppos, 0, &names, NULL); + return simple_read_from_buffer(buf, count, ppos, names, avail); } /* read the per-port counters for port 1 (pidx 0) */ @@ -187,10 +190,11 @@ static ssize_t portcntrs_1_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { u64 *counters; + size_t avail; struct qib_devdata *dd = private2dd(file); - return simple_read_from_buffer(buf, count, ppos, counters, - dd->f_read_portcntrs(dd, *ppos, 0, NULL, &counters)); + avail = dd->f_read_portcntrs(dd, *ppos, 0, NULL, &counters); + return simple_read_from_buffer(buf, count, ppos, counters, avail); } /* read the per-port counters for port 2 (pidx 1) */ @@ -198,10 +202,11 @@ static ssize_t portcntrs_2_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { u64 *counters; + size_t avail; struct qib_devdata *dd = private2dd(file); - return simple_read_from_buffer(buf, count, ppos, counters, - dd->f_read_portcntrs(dd, *ppos, 1, NULL, &counters)); + avail = dd->f_read_portcntrs(dd, *ppos, 1, NULL, &counters); + return simple_read_from_buffer(buf, count, ppos, counters, avail); } static const struct file_operations portcntr_ops[] = { -- cgit v1.2.3 From 8187a2b70e34c727a06617441f74f202b6fefaf9 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Fri, 21 May 2010 09:08:55 +0800 Subject: drm/i915: introduce intel_ring_buffer structure (V2) Introduces a more complete intel_ring_buffer structure with callbacks for setup and management of a particular ringbuffer, and converts the render ring buffer consumers to use it. Signed-off-by: Zou Nan hai Signed-off-by: Xiang Hai hao [anholt: Fixed up whitespace fail and rebased against prep patches] Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_debugfs.c | 6 +- drivers/gpu/drm/i915/i915_dma.c | 58 ++-- drivers/gpu/drm/i915/i915_drv.c | 29 +- drivers/gpu/drm/i915/i915_drv.h | 80 ++--- drivers/gpu/drm/i915/i915_gem.c | 76 ++++- drivers/gpu/drm/i915/i915_irq.c | 15 +- drivers/gpu/drm/i915/intel_display.c | 1 - drivers/gpu/drm/i915/intel_overlay.c | 8 - drivers/gpu/drm/i915/intel_ringbuffer.c | 582 +++++++++++++++++++------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 124 +++++++ include/drm/i915_drm.h | 4 +- 11 files changed, 606 insertions(+), 377 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_ringbuffer.h (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 488175c70c7d..4fddf094deb2 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -317,14 +317,14 @@ static int i915_ringbuffer_data(struct seq_file *m, void *data) u8 *virt; uint32_t *ptr, off; - if (!dev_priv->render_ring.ring_obj) { + if (!dev_priv->render_ring.gem_object) { seq_printf(m, "No ringbuffer setup\n"); return 0; } virt = dev_priv->render_ring.virtual_start; - for (off = 0; off < dev_priv->render_ring.Size; off += 4) { + for (off = 0; off < dev_priv->render_ring.size; off += 4) { ptr = (uint32_t *)(virt + off); seq_printf(m, "%08x : %08x\n", off, *ptr); } @@ -344,7 +344,7 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) seq_printf(m, "RingHead : %08x\n", head); seq_printf(m, "RingTail : %08x\n", tail); - seq_printf(m, "RingSize : %08lx\n", dev_priv->render_ring.Size); + seq_printf(m, "RingSize : %08lx\n", dev_priv->render_ring.size); seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD)); return 0; diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 6de7eace4319..2541428b2fe5 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -40,7 +40,6 @@ #include #include - /** * Sets up the hardware status page for devices that need a physical address * in the register. @@ -56,10 +55,11 @@ static int i915_init_phys_hws(struct drm_device *dev) DRM_ERROR("Can not allocate hardware status page\n"); return -ENOMEM; } - dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; + dev_priv->render_ring.status_page.page_addr + = dev_priv->status_page_dmah->vaddr; dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); + memset(dev_priv->render_ring.status_page.page_addr, 0, PAGE_SIZE); if (IS_I965G(dev)) dev_priv->dma_status_page |= (dev_priv->dma_status_page >> 28) & @@ -95,7 +95,7 @@ void i915_kernel_lost_context(struct drm_device * dev) { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_master_private *master_priv; - drm_i915_ring_buffer_t *ring = &(dev_priv->render_ring); + struct intel_ring_buffer *ring = &dev_priv->render_ring; /* * We should never lose context on the ring with modesetting @@ -108,7 +108,7 @@ void i915_kernel_lost_context(struct drm_device * dev) ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) - ring->space += ring->Size; + ring->space += ring->size; if (!dev->primary->master) return; @@ -128,12 +128,7 @@ static int i915_dma_cleanup(struct drm_device * dev) if (dev->irq_enabled) drm_irq_uninstall(dev); - if (dev_priv->render_ring.virtual_start) { - drm_core_ioremapfree(&dev_priv->render_ring.map, dev); - dev_priv->render_ring.virtual_start = NULL; - dev_priv->render_ring.map.handle = NULL; - dev_priv->render_ring.map.size = 0; - } + intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); /* Clear the HWS virtual address at teardown */ if (I915_NEED_GFX_HWS(dev)) @@ -156,14 +151,14 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) } if (init->ring_size != 0) { - if (dev_priv->render_ring.ring_obj != NULL) { + if (dev_priv->render_ring.gem_object != NULL) { i915_dma_cleanup(dev); DRM_ERROR("Client tried to initialize ringbuffer in " "GEM mode\n"); return -EINVAL; } - dev_priv->render_ring.Size = init->ring_size; + dev_priv->render_ring.size = init->ring_size; dev_priv->render_ring.map.offset = init->ring_start; dev_priv->render_ring.map.size = init->ring_size; @@ -201,26 +196,29 @@ static int i915_dma_resume(struct drm_device * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + struct intel_ring_buffer *ring; DRM_DEBUG_DRIVER("%s\n", __func__); - if (dev_priv->render_ring.map.handle == NULL) { + ring = &dev_priv->render_ring; + + if (ring->map.handle == NULL) { DRM_ERROR("can not ioremap virtual address for" " ring buffer\n"); return -ENOMEM; } /* Program Hardware Status Page */ - if (!dev_priv->hw_status_page) { + if (!ring->status_page.page_addr) { DRM_ERROR("Can not find hardware status page\n"); return -EINVAL; } DRM_DEBUG_DRIVER("hw status page @ %p\n", - dev_priv->hw_status_page); - - if (dev_priv->status_gfx_addr != 0) - I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); + ring->status_page.page_addr); + if (ring->status_page.gfx_addr != 0) + ring->setup_status_page(dev, ring); else I915_WRITE(HWS_PGA, dev_priv->dma_status_page); + DRM_DEBUG_DRIVER("Enabled hardware status page\n"); return 0; @@ -330,9 +328,8 @@ static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords) { drm_i915_private_t *dev_priv = dev->dev_private; int i; - RING_LOCALS; - if ((dwords+1) * sizeof(int) >= dev_priv->render_ring.Size - 8) + if ((dwords+1) * sizeof(int) >= dev_priv->render_ring.size - 8) return -EINVAL; BEGIN_LP_RING((dwords+1)&~1); @@ -365,9 +362,7 @@ i915_emit_box(struct drm_device *dev, struct drm_clip_rect *boxes, int i, int DR1, int DR4) { - drm_i915_private_t *dev_priv = dev->dev_private; struct drm_clip_rect box = boxes[i]; - RING_LOCALS; if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { DRM_ERROR("Bad box %d,%d..%d,%d\n", @@ -404,7 +399,6 @@ static void i915_emit_breadcrumb(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - RING_LOCALS; dev_priv->counter++; if (dev_priv->counter > 0x7FFFFFFFUL) @@ -458,10 +452,8 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, drm_i915_batchbuffer_t * batch, struct drm_clip_rect *cliprects) { - drm_i915_private_t *dev_priv = dev->dev_private; int nbox = batch->num_cliprects; int i = 0, count; - RING_LOCALS; if ((batch->start | batch->used) & 0x7) { DRM_ERROR("alignment"); @@ -510,7 +502,6 @@ static int i915_dispatch_flip(struct drm_device * dev) drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - RING_LOCALS; if (!master_priv->sarea_priv) return -EINVAL; @@ -563,7 +554,8 @@ static int i915_quiescent(struct drm_device * dev) drm_i915_private_t *dev_priv = dev->dev_private; i915_kernel_lost_context(dev); - return i915_wait_ring(dev, dev_priv->render_ring.Size - 8, __func__); + return intel_wait_ring_buffer(dev, &dev_priv->render_ring, + dev_priv->render_ring.size - 8); } static int i915_flush_ioctl(struct drm_device *dev, void *data, @@ -805,6 +797,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, { drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_hws_addr_t *hws = data; + struct intel_ring_buffer *ring = &dev_priv->render_ring; if (!I915_NEED_GFX_HWS(dev)) return -EINVAL; @@ -821,7 +814,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, DRM_DEBUG_DRIVER("set status page addr 0x%08x\n", (u32)hws->addr); - dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); + ring->status_page.gfx_addr = hws->addr & (0x1ffff<<12); dev_priv->hws_map.offset = dev->agp->base + hws->addr; dev_priv->hws_map.size = 4*1024; @@ -837,10 +830,10 @@ static int i915_set_status_page(struct drm_device *dev, void *data, " G33 hw status page\n"); return -ENOMEM; } - dev_priv->hw_status_page = dev_priv->hws_map.handle; + ring->status_page.page_addr = dev_priv->hws_map.handle; + memset(ring->status_page.page_addr, 0, PAGE_SIZE); + I915_WRITE(HWS_PGA, ring->status_page.gfx_addr); - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); DRM_DEBUG_DRIVER("load hws HWS_PGA with gfx mem 0x%x\n", dev_priv->status_gfx_addr); DRM_DEBUG_DRIVER("load hws at %p\n", @@ -1639,7 +1632,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) spin_lock_init(&dev_priv->user_irq_lock); spin_lock_init(&dev_priv->error_lock); - dev_priv->user_irq_refcount = 0; dev_priv->trace_irq_seqno = 0; ret = drm_vblank_init(dev, I915_NUM_PIPE); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index a1814f65fdb4..c57c54f403da 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -388,33 +388,10 @@ int i965_reset(struct drm_device *dev, u8 flags) * switched away). */ if (drm_core_check_feature(dev, DRIVER_MODESET) || - !dev_priv->mm.suspended) { - drm_i915_ring_buffer_t *ring = &dev_priv->render_ring; - struct drm_gem_object *obj = ring->ring_obj; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + !dev_priv->mm.suspended) { + struct intel_ring_buffer *ring = &dev_priv->render_ring; dev_priv->mm.suspended = 0; - - /* Stop the ring if it's running. */ - I915_WRITE(PRB0_CTL, 0); - I915_WRITE(PRB0_TAIL, 0); - I915_WRITE(PRB0_HEAD, 0); - - /* Initialize the ring. */ - I915_WRITE(PRB0_START, obj_priv->gtt_offset); - I915_WRITE(PRB0_CTL, - ((obj->size - 4096) & RING_NR_PAGES) | - RING_NO_REPORT | - RING_VALID); - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - i915_kernel_lost_context(dev); - else { - ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; - ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; - ring->space = ring->head - (ring->tail + 8); - if (ring->space < 0) - ring->space += ring->Size; - } - + ring->init(dev, ring); mutex_unlock(&dev->struct_mutex); drm_irq_uninstall(dev); drm_irq_install(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a39440cf1dee..6bb7933d49dc 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -31,8 +31,8 @@ #define _I915_DRV_H_ #include "i915_reg.h" -#include "i915_drm.h" #include "intel_bios.h" +#include "intel_ringbuffer.h" #include /* General customization: @@ -92,16 +92,6 @@ struct drm_i915_gem_phys_object { struct drm_gem_object *cur_obj; }; -typedef struct _drm_i915_ring_buffer { - unsigned long Size; - u8 *virtual_start; - int head; - int tail; - int space; - drm_local_map_t map; - struct drm_gem_object *ring_obj; -} drm_i915_ring_buffer_t; - struct mem_block { struct mem_block *next; struct mem_block *prev; @@ -244,7 +234,7 @@ typedef struct drm_i915_private { void __iomem *regs; struct pci_dev *bridge_dev; - drm_i915_ring_buffer_t render_ring; + struct intel_ring_buffer render_ring; drm_dma_handle_t *status_page_dmah; void *hw_status_page; @@ -270,8 +260,6 @@ typedef struct drm_i915_private { atomic_t irq_received; /** Protects user_irq_refcount and irq_mask_reg */ spinlock_t user_irq_lock; - /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */ - int user_irq_refcount; u32 trace_irq_seqno; /** Cached value of IMR to avoid reads in updating the bitfield */ u32 irq_mask_reg; @@ -832,9 +820,7 @@ extern int i915_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int i915_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv); -void i915_user_irq_get(struct drm_device *dev); void i915_trace_irq_get(struct drm_device *dev, u32 seqno); -void i915_user_irq_put(struct drm_device *dev); extern void i915_enable_interrupt (struct drm_device *dev); extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); @@ -853,8 +839,10 @@ extern int i915_vblank_swap(struct drm_device *dev, void *data, struct drm_file *file_priv); extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask); extern void i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask); -void ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask); -void ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask); +extern void ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, + u32 mask); +extern void ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, + u32 mask); void i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); @@ -962,8 +950,6 @@ void i915_gem_object_flush_write_domain(struct drm_gem_object *obj); void i915_gem_shrinker_init(void); void i915_gem_shrinker_exit(void); -int i915_gem_init_pipe_control(struct drm_device *dev); -void i915_gem_cleanup_pipe_control(struct drm_device *dev); /* i915_gem_tiling.c */ void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); @@ -1014,16 +1000,6 @@ static inline void ironlake_opregion_gse_intr(struct drm_device *dev) { return; static inline void opregion_enable_asle(struct drm_device *dev) { return; } #endif -/* intel_ringbuffer.c */ -extern void i915_gem_flush(struct drm_device *dev, - uint32_t invalidate_domains, - uint32_t flush_domains); -extern int i915_dispatch_gem_execbuffer(struct drm_device *dev, - struct drm_i915_gem_execbuffer2 *exec, - struct drm_clip_rect *cliprects, - uint64_t exec_offset); -extern uint32_t i915_ring_add_request(struct drm_device *dev); - /* modesetting */ extern void intel_modeset_init(struct drm_device *dev); extern void intel_modeset_cleanup(struct drm_device *dev); @@ -1044,7 +1020,8 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); * has access to the ring. */ #define RING_LOCK_TEST_WITH_RETURN(dev, file_priv) do { \ - if (((drm_i915_private_t *)dev->dev_private)->render_ring.ring_obj == NULL) \ + if (((drm_i915_private_t *)dev->dev_private)->render_ring.gem_object \ + == NULL) \ LOCK_TEST_WITH_RETURN(dev, file_priv); \ } while (0) @@ -1060,32 +1037,27 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); #define I915_VERBOSE 0 -#define RING_LOCALS volatile unsigned int *ring_virt__; - -#define BEGIN_LP_RING(n) do { \ - int bytes__ = 4*(n); \ - if (I915_VERBOSE) DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \ - /* a wrap must occur between instructions so pad beforehand */ \ - if (unlikely (dev_priv->render_ring.tail + bytes__ > dev_priv->render_ring.Size)) \ - i915_wrap_ring(dev); \ - if (unlikely (dev_priv->render_ring.space < bytes__)) \ - i915_wait_ring(dev, bytes__, __func__); \ - ring_virt__ = (unsigned int *) \ - (dev_priv->render_ring.virtual_start + dev_priv->render_ring.tail); \ - dev_priv->render_ring.tail += bytes__; \ - dev_priv->render_ring.tail &= dev_priv->render_ring.Size - 1; \ - dev_priv->render_ring.space -= bytes__; \ +#define BEGIN_LP_RING(n) do { \ + drm_i915_private_t *dev_priv = dev->dev_private; \ + if (I915_VERBOSE) \ + DRM_DEBUG(" BEGIN_LP_RING %x\n", (int)(n)); \ + intel_ring_begin(dev, &dev_priv->render_ring, 4*(n)); \ } while (0) -#define OUT_RING(n) do { \ - if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ - *ring_virt__++ = (n); \ + +#define OUT_RING(x) do { \ + drm_i915_private_t *dev_priv = dev->dev_private; \ + if (I915_VERBOSE) \ + DRM_DEBUG(" OUT_RING %x\n", (int)(x)); \ + intel_ring_emit(dev, &dev_priv->render_ring, x); \ } while (0) #define ADVANCE_LP_RING() do { \ + drm_i915_private_t *dev_priv = dev->dev_private; \ if (I915_VERBOSE) \ - DRM_DEBUG("ADVANCE_LP_RING %x\n", dev_priv->render_ring.tail); \ - I915_WRITE(PRB0_TAIL, dev_priv->render_ring.tail); \ + DRM_DEBUG("ADVANCE_LP_RING %x\n", \ + dev_priv->render_ring.tail); \ + intel_ring_advance(dev, &dev_priv->render_ring); \ } while(0) /** @@ -1103,14 +1075,12 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); * * The area from dword 0x20 to 0x3ff is available for driver usage. */ -#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) +#define READ_HWSP(dev_priv, reg) (((volatile u32 *)\ + (dev_priv->render_ring.status_page.page_addr))[reg]) #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX) #define I915_GEM_HWS_INDEX 0x20 #define I915_BREADCRUMB_INDEX 0x21 -extern int i915_wrap_ring(struct drm_device * dev); -extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); - #define INTEL_INFO(dev) (((struct drm_i915_private *) (dev)->dev_private)->info) #define IS_I830(dev) ((dev)->pci_device == 0x3577) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 95dbe5628a25..58b6e814fae1 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1590,6 +1590,7 @@ i915_gem_process_flushing_list(struct drm_device *dev, } } } + uint32_t i915_add_request(struct drm_device *dev, struct drm_file *file_priv, uint32_t flush_domains) @@ -1607,7 +1608,8 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, if (request == NULL) return 0; - seqno = i915_ring_add_request(dev); + seqno = dev_priv->render_ring.add_request(dev, &dev_priv->render_ring, + file_priv, flush_domains); DRM_DEBUG_DRIVER("%d\n", seqno); @@ -1645,10 +1647,8 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, static uint32_t i915_retire_commands(struct drm_device *dev) { - drm_i915_private_t *dev_priv = dev->dev_private; uint32_t cmd = MI_FLUSH | MI_NO_WRITE_FLUSH; uint32_t flush_domains = 0; - RING_LOCALS; /* The sampler always gets flushed on i965 (sigh) */ if (IS_I965G(dev)) @@ -1746,7 +1746,9 @@ i915_gem_retire_requests(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; uint32_t seqno; - if (!dev_priv->hw_status_page || list_empty(&dev_priv->mm.request_list)) + struct intel_ring_buffer *ring = &(dev_priv->render_ring); + if (!ring->status_page.page_addr + || list_empty(&dev_priv->mm.request_list)) return; seqno = i915_get_gem_seqno(dev); @@ -1773,7 +1775,8 @@ i915_gem_retire_requests(struct drm_device *dev) if (unlikely (dev_priv->trace_irq_seqno && i915_seqno_passed(dev_priv->trace_irq_seqno, seqno))) { - i915_user_irq_put(dev); + + ring->user_irq_put(dev, ring); dev_priv->trace_irq_seqno = 0; } } @@ -1803,6 +1806,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) u32 ier; int ret = 0; + struct intel_ring_buffer *ring = &dev_priv->render_ring; BUG_ON(seqno == 0); if (atomic_read(&dev_priv->mm.wedged)) @@ -1823,7 +1827,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) trace_i915_gem_request_wait_begin(dev, seqno); dev_priv->mm.waiting_gem_seqno = seqno; - i915_user_irq_get(dev); + ring->user_irq_get(dev, ring); if (interruptible) ret = wait_event_interruptible(dev_priv->irq_queue, i915_seqno_passed(i915_get_gem_seqno(dev), seqno) || @@ -1833,7 +1837,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) i915_seqno_passed(i915_get_gem_seqno(dev), seqno) || atomic_read(&dev_priv->mm.wedged)); - i915_user_irq_put(dev); + ring->user_irq_put(dev, ring); dev_priv->mm.waiting_gem_seqno = 0; trace_i915_gem_request_wait_end(dev, seqno); @@ -1867,6 +1871,19 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno) } +static void +i915_gem_flush(struct drm_device *dev, + uint32_t invalidate_domains, + uint32_t flush_domains) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + if (flush_domains & I915_GEM_DOMAIN_CPU) + drm_agp_chipset_flush(dev); + dev_priv->render_ring.flush(dev, &dev_priv->render_ring, + invalidate_domains, + flush_domains); +} + /** * Ensures that all rendering to the object has completed and the object is * safe to unbind from the GTT or access from the CPU. @@ -3820,7 +3837,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, #endif /* Exec the batchbuffer */ - ret = i915_dispatch_gem_execbuffer(dev, args, cliprects, exec_offset); + ret = dev_priv->render_ring.dispatch_gem_execbuffer(dev, + &dev_priv->render_ring, + args, + cliprects, + exec_offset); if (ret) { DRM_ERROR("dispatch failed %d\n", ret); goto err; @@ -4378,7 +4399,8 @@ i915_gem_idle(struct drm_device *dev) mutex_lock(&dev->struct_mutex); - if (dev_priv->mm.suspended || dev_priv->render_ring.ring_obj == NULL) { + if (dev_priv->mm.suspended || + dev_priv->render_ring.gem_object == NULL) { mutex_unlock(&dev->struct_mutex); return 0; } @@ -4420,7 +4442,7 @@ i915_gem_idle(struct drm_device *dev) * 965+ support PIPE_CONTROL commands, which provide finer grained control * over cache flushing. */ -int +static int i915_gem_init_pipe_control(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -4459,7 +4481,8 @@ err: return ret; } -void + +static void i915_gem_cleanup_pipe_control(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -4476,6 +4499,37 @@ i915_gem_cleanup_pipe_control(struct drm_device *dev) dev_priv->seqno_page = NULL; } +int +i915_gem_init_ringbuffer(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + int ret; + dev_priv->render_ring = render_ring; + if (!I915_NEED_GFX_HWS(dev)) { + dev_priv->render_ring.status_page.page_addr + = dev_priv->status_page_dmah->vaddr; + memset(dev_priv->render_ring.status_page.page_addr, + 0, PAGE_SIZE); + } + if (HAS_PIPE_CONTROL(dev)) { + ret = i915_gem_init_pipe_control(dev); + if (ret) + return ret; + } + ret = intel_init_ring_buffer(dev, &dev_priv->render_ring); + return ret; +} + +void +i915_gem_cleanup_ringbuffer(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + + intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); + if (HAS_PIPE_CONTROL(dev)) + i915_gem_cleanup_pipe_control(dev); +} + int i915_gem_entervt_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index dd91c97de968..e07c643c8365 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -545,7 +545,8 @@ i915_ringbuffer_last_batch(struct drm_device *dev) } if (bbaddr == 0) { - ring = (u32 *)(dev_priv->render_ring.virtual_start + dev_priv->render_ring.Size); + ring = (u32 *)(dev_priv->render_ring.virtual_start + + dev_priv->render_ring.size); while (--ring >= (u32 *)dev_priv->render_ring.virtual_start) { bbaddr = i915_get_bbaddr(dev, ring); if (bbaddr) @@ -639,7 +640,8 @@ static void i915_capture_error_state(struct drm_device *dev) error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); /* Record the ringbuffer */ - error->ringbuffer = i915_error_object_create(dev, dev_priv->render_ring.ring_obj); + error->ringbuffer = i915_error_object_create(dev, + dev_priv->render_ring.gem_object); /* Record buffers on the active list. */ error->active_bo = NULL; @@ -984,7 +986,6 @@ static int i915_emit_irq(struct drm_device * dev) { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - RING_LOCALS; i915_kernel_lost_context(dev); @@ -1009,9 +1010,10 @@ static int i915_emit_irq(struct drm_device * dev) void i915_trace_irq_get(struct drm_device *dev, u32 seqno) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + struct intel_ring_buffer *render_ring = &dev_priv->render_ring; if (dev_priv->trace_irq_seqno == 0) - i915_user_irq_get(dev); + render_ring->user_irq_get(dev, render_ring); dev_priv->trace_irq_seqno = seqno; } @@ -1021,6 +1023,7 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; int ret = 0; + struct intel_ring_buffer *render_ring = &dev_priv->render_ring; DRM_DEBUG_DRIVER("irq_nr=%d breadcrumb=%d\n", irq_nr, READ_BREADCRUMB(dev_priv)); @@ -1034,10 +1037,10 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) if (master_priv->sarea_priv) master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; - i915_user_irq_get(dev); + render_ring->user_irq_get(dev, render_ring); DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ, READ_BREADCRUMB(dev_priv) >= irq_nr); - i915_user_irq_put(dev); + render_ring->user_irq_put(dev, render_ring); if (ret == -EBUSY) { DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f469a84cacfd..b867f3c78408 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4629,7 +4629,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, unsigned long flags; int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC; int ret, pipesrc; - RING_LOCALS; work = kzalloc(sizeof *work, GFP_KERNEL); if (work == NULL) diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index b0e17b06eb6e..93da83782e5e 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -211,9 +211,7 @@ static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay) static int intel_overlay_on(struct intel_overlay *overlay) { struct drm_device *dev = overlay->dev; - drm_i915_private_t *dev_priv = dev->dev_private; int ret; - RING_LOCALS; BUG_ON(overlay->active); @@ -248,7 +246,6 @@ static void intel_overlay_continue(struct intel_overlay *overlay, drm_i915_private_t *dev_priv = dev->dev_private; u32 flip_addr = overlay->flip_addr; u32 tmp; - RING_LOCALS; BUG_ON(!overlay->active); @@ -274,7 +271,6 @@ static int intel_overlay_wait_flip(struct intel_overlay *overlay) drm_i915_private_t *dev_priv = dev->dev_private; int ret; u32 tmp; - RING_LOCALS; if (overlay->last_flip_req != 0) { ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); @@ -314,9 +310,7 @@ static int intel_overlay_off(struct intel_overlay *overlay) { u32 flip_addr = overlay->flip_addr; struct drm_device *dev = overlay->dev; - drm_i915_private_t *dev_priv = dev->dev_private; int ret; - RING_LOCALS; BUG_ON(!overlay->active); @@ -390,11 +384,9 @@ int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, int interruptible) { struct drm_device *dev = overlay->dev; - drm_i915_private_t *dev_priv = dev->dev_private; struct drm_gem_object *obj; u32 flip_addr; int ret; - RING_LOCALS; if (overlay->hw_wedged == HW_WEDGED) return -EIO; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 06058ddb4eed..5715c4d8cce9 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -29,30 +29,24 @@ #include "drmP.h" #include "drm.h" -#include "i915_drm.h" #include "i915_drv.h" +#include "i915_drm.h" #include "i915_trace.h" -#include "intel_drv.h" -void -i915_gem_flush(struct drm_device *dev, - uint32_t invalidate_domains, - uint32_t flush_domains) +static void +render_ring_flush(struct drm_device *dev, + struct intel_ring_buffer *ring, + u32 invalidate_domains, + u32 flush_domains) { - drm_i915_private_t *dev_priv = dev->dev_private; - uint32_t cmd; - RING_LOCALS; - #if WATCH_EXEC DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, invalidate_domains, flush_domains); #endif - trace_i915_gem_request_flush(dev, dev_priv->mm.next_gem_seqno, + u32 cmd; + trace_i915_gem_request_flush(dev, ring->next_seqno, invalidate_domains, flush_domains); - if (flush_domains & I915_GEM_DOMAIN_CPU) - drm_agp_chipset_flush(dev); - if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) { /* * read/write caches: @@ -100,19 +94,130 @@ i915_gem_flush(struct drm_device *dev, #if WATCH_EXEC DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd); #endif - BEGIN_LP_RING(2); - OUT_RING(cmd); - OUT_RING(MI_NOOP); - ADVANCE_LP_RING(); + intel_ring_begin(dev, ring, 8); + intel_ring_emit(dev, ring, cmd); + intel_ring_emit(dev, ring, MI_NOOP); + intel_ring_advance(dev, ring); } +} + +static unsigned int render_ring_get_head(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + return I915_READ(PRB0_HEAD) & HEAD_ADDR; +} +static unsigned int render_ring_get_tail(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + return I915_READ(PRB0_TAIL) & TAIL_ADDR; } + +static unsigned int render_ring_get_active_head(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD; + + return I915_READ(acthd_reg); +} + +static void render_ring_advance_ring(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + I915_WRITE(PRB0_TAIL, ring->tail); +} + +static int init_ring_common(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + u32 head; + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_i915_gem_object *obj_priv; + obj_priv = to_intel_bo(ring->gem_object); + + /* Stop the ring if it's running. */ + I915_WRITE(ring->regs.ctl, 0); + I915_WRITE(ring->regs.head, 0); + I915_WRITE(ring->regs.tail, 0); + + /* Initialize the ring. */ + I915_WRITE(ring->regs.start, obj_priv->gtt_offset); + head = ring->get_head(dev, ring); + + /* G45 ring initialization fails to reset head to zero */ + if (head != 0) { + DRM_ERROR("%s head not reset to zero " + "ctl %08x head %08x tail %08x start %08x\n", + ring->name, + I915_READ(ring->regs.ctl), + I915_READ(ring->regs.head), + I915_READ(ring->regs.tail), + I915_READ(ring->regs.start)); + + I915_WRITE(ring->regs.head, 0); + + DRM_ERROR("%s head forced to zero " + "ctl %08x head %08x tail %08x start %08x\n", + ring->name, + I915_READ(ring->regs.ctl), + I915_READ(ring->regs.head), + I915_READ(ring->regs.tail), + I915_READ(ring->regs.start)); + } + + I915_WRITE(ring->regs.ctl, + ((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES) + | RING_NO_REPORT | RING_VALID); + + head = I915_READ(ring->regs.head) & HEAD_ADDR; + /* If the head is still not zero, the ring is dead */ + if (head != 0) { + DRM_ERROR("%s initialization failed " + "ctl %08x head %08x tail %08x start %08x\n", + ring->name, + I915_READ(ring->regs.ctl), + I915_READ(ring->regs.head), + I915_READ(ring->regs.tail), + I915_READ(ring->regs.start)); + return -EIO; + } + + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + i915_kernel_lost_context(dev); + else { + ring->head = ring->get_head(dev, ring); + ring->tail = ring->get_tail(dev, ring); + ring->space = ring->head - (ring->tail + 8); + if (ring->space < 0) + ring->space += ring->size; + } + return 0; +} + +static int init_render_ring(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + int ret = init_ring_common(dev, ring); + if (IS_I9XX(dev) && !IS_GEN3(dev)) { + I915_WRITE(MI_MODE, + (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH); + } + return ret; +} + #define PIPE_CONTROL_FLUSH(addr) \ +do { \ OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ PIPE_CONTROL_DEPTH_STALL); \ OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT); \ OUT_RING(0); \ OUT_RING(0); \ +} while (0) /** * Creates a new sequence number, emitting a write of it to the status page @@ -122,21 +227,15 @@ i915_gem_flush(struct drm_device *dev, * * Returned sequence numbers are nonzero on success. */ -uint32_t -i915_ring_add_request(struct drm_device *dev) +static u32 +render_ring_add_request(struct drm_device *dev, + struct intel_ring_buffer *ring, + struct drm_file *file_priv, + u32 flush_domains) { + u32 seqno; drm_i915_private_t *dev_priv = dev->dev_private; - uint32_t seqno; - RING_LOCALS; - - /* Grab the seqno we're going to make this request be, and bump the - * next (skipping 0 so it can be the reserved no-seqno value). - */ - seqno = dev_priv->mm.next_gem_seqno; - dev_priv->mm.next_gem_seqno++; - if (dev_priv->mm.next_gem_seqno == 0) - dev_priv->mm.next_gem_seqno++; - + seqno = intel_ring_get_seqno(dev, ring); if (HAS_PIPE_CONTROL(dev)) { u32 scratch_addr = dev_priv->seqno_gfx_addr + 128; @@ -181,13 +280,26 @@ i915_ring_add_request(struct drm_device *dev) return seqno; } -void i915_user_irq_get(struct drm_device *dev) +static u32 +render_ring_get_gem_seqno(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + if (HAS_PIPE_CONTROL(dev)) + return ((volatile u32 *)(dev_priv->seqno_page))[0]; + else + return intel_read_status_page(ring, I915_GEM_HWS_INDEX); +} + +static void +render_ring_get_user_irq(struct drm_device *dev, + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; unsigned long irqflags; spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); - if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) { + if (dev->irq_enabled && (++ring->user_irq_refcount == 1)) { if (HAS_PCH_SPLIT(dev)) ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); else @@ -196,14 +308,16 @@ void i915_user_irq_get(struct drm_device *dev) spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); } -void i915_user_irq_put(struct drm_device *dev) +static void +render_ring_put_user_irq(struct drm_device *dev, + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; unsigned long irqflags; spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); - BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0); - if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { + BUG_ON(dev->irq_enabled && ring->user_irq_refcount <= 0); + if (dev->irq_enabled && (--ring->user_irq_refcount == 0)) { if (HAS_PCH_SPLIT(dev)) ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); else @@ -212,20 +326,31 @@ void i915_user_irq_put(struct drm_device *dev) spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); } -/** Dispatch a batchbuffer to the ring - */ -int -i915_dispatch_gem_execbuffer(struct drm_device *dev, - struct drm_i915_gem_execbuffer2 *exec, - struct drm_clip_rect *cliprects, - uint64_t exec_offset) +static void render_setup_status_page(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + if (IS_GEN6(dev)) { + I915_WRITE(HWS_PGA_GEN6, ring->status_page.gfx_addr); + I915_READ(HWS_PGA_GEN6); /* posting read */ + } else { + I915_WRITE(HWS_PGA, ring->status_page.gfx_addr); + I915_READ(HWS_PGA); /* posting read */ + } + +} + +static int +render_ring_dispatch_gem_execbuffer(struct drm_device *dev, + struct intel_ring_buffer *ring, + struct drm_i915_gem_execbuffer2 *exec, + struct drm_clip_rect *cliprects, + uint64_t exec_offset) { drm_i915_private_t *dev_priv = dev->dev_private; int nbox = exec->num_cliprects; int i = 0, count; uint32_t exec_start, exec_len; - RING_LOCALS; - exec_start = (uint32_t) exec_offset + exec->batch_start_offset; exec_len = (uint32_t) exec->batch_len; @@ -242,74 +367,61 @@ i915_dispatch_gem_execbuffer(struct drm_device *dev, } if (IS_I830(dev) || IS_845G(dev)) { - BEGIN_LP_RING(4); - OUT_RING(MI_BATCH_BUFFER); - OUT_RING(exec_start | MI_BATCH_NON_SECURE); - OUT_RING(exec_start + exec_len - 4); - OUT_RING(0); - ADVANCE_LP_RING(); + intel_ring_begin(dev, ring, 4); + intel_ring_emit(dev, ring, MI_BATCH_BUFFER); + intel_ring_emit(dev, ring, + exec_start | MI_BATCH_NON_SECURE); + intel_ring_emit(dev, ring, exec_start + exec_len - 4); + intel_ring_emit(dev, ring, 0); } else { - BEGIN_LP_RING(2); + intel_ring_begin(dev, ring, 4); if (IS_I965G(dev)) { - OUT_RING(MI_BATCH_BUFFER_START | - (2 << 6) | - MI_BATCH_NON_SECURE_I965); - OUT_RING(exec_start); + intel_ring_emit(dev, ring, + MI_BATCH_BUFFER_START | (2 << 6) + | MI_BATCH_NON_SECURE_I965); + intel_ring_emit(dev, ring, exec_start); } else { - OUT_RING(MI_BATCH_BUFFER_START | - (2 << 6)); - OUT_RING(exec_start | MI_BATCH_NON_SECURE); + intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START + | (2 << 6)); + intel_ring_emit(dev, ring, exec_start | + MI_BATCH_NON_SECURE); } - ADVANCE_LP_RING(); } + intel_ring_advance(dev, ring); } /* XXX breadcrumb */ return 0; } -static void -i915_gem_cleanup_hws(struct drm_device *dev) +static void cleanup_status_page(struct drm_device *dev, + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_gem_object *obj; struct drm_i915_gem_object *obj_priv; - if (dev_priv->hws_obj == NULL) + obj = ring->status_page.obj; + if (obj == NULL) return; - - obj = dev_priv->hws_obj; obj_priv = to_intel_bo(obj); kunmap(obj_priv->pages[0]); i915_gem_object_unpin(obj); drm_gem_object_unreference(obj); - dev_priv->hws_obj = NULL; + ring->status_page.obj = NULL; memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); - dev_priv->hw_status_page = NULL; - - if (HAS_PIPE_CONTROL(dev)) - i915_gem_cleanup_pipe_control(dev); - - /* Write high address into HWS_PGA when disabling. */ - I915_WRITE(HWS_PGA, 0x1ffff000); } -static int -i915_gem_init_hws(struct drm_device *dev) +static int init_status_page(struct drm_device *dev, + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_gem_object *obj; struct drm_i915_gem_object *obj_priv; int ret; - /* If we need a physical address for the status page, it's already - * initialized at driver load time. - */ - if (!I915_NEED_GFX_HWS(dev)) - return 0; - obj = i915_gem_alloc_object(dev, 4096); if (obj == NULL) { DRM_ERROR("Failed to allocate status page\n"); @@ -321,36 +433,21 @@ i915_gem_init_hws(struct drm_device *dev) ret = i915_gem_object_pin(obj, 4096); if (ret != 0) { - drm_gem_object_unreference(obj); goto err_unref; } - dev_priv->status_gfx_addr = obj_priv->gtt_offset; - - dev_priv->hw_status_page = kmap(obj_priv->pages[0]); - if (dev_priv->hw_status_page == NULL) { - DRM_ERROR("Failed to map status page.\n"); + ring->status_page.gfx_addr = obj_priv->gtt_offset; + ring->status_page.page_addr = kmap(obj_priv->pages[0]); + if (ring->status_page.page_addr == NULL) { memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); - ret = -EINVAL; goto err_unpin; } + ring->status_page.obj = obj; + memset(ring->status_page.page_addr, 0, PAGE_SIZE); - if (HAS_PIPE_CONTROL(dev)) { - ret = i915_gem_init_pipe_control(dev); - if (ret) - goto err_unpin; - } - - dev_priv->hws_obj = obj; - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - if (IS_GEN6(dev)) { - I915_WRITE(HWS_PGA_GEN6, dev_priv->status_gfx_addr); - I915_READ(HWS_PGA_GEN6); /* posting read */ - } else { - I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); - I915_READ(HWS_PGA); /* posting read */ - } - DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr); + ring->setup_status_page(dev, ring); + DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n", + ring->name, ring->status_page.gfx_addr); return 0; @@ -359,43 +456,42 @@ err_unpin: err_unref: drm_gem_object_unreference(obj); err: - return 0; + return ret; } -int -i915_gem_init_ringbuffer(struct drm_device *dev) + +int intel_init_ring_buffer(struct drm_device *dev, + struct intel_ring_buffer *ring) { - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; - drm_i915_ring_buffer_t *ring = &dev_priv->render_ring; int ret; - u32 head; + struct drm_i915_gem_object *obj_priv; + struct drm_gem_object *obj; + ring->dev = dev; - ret = i915_gem_init_hws(dev); - if (ret != 0) - return ret; + if (I915_NEED_GFX_HWS(dev)) { + ret = init_status_page(dev, ring); + if (ret) + return ret; + } - obj = i915_gem_alloc_object(dev, 128 * 1024); + obj = i915_gem_alloc_object(dev, ring->size); if (obj == NULL) { DRM_ERROR("Failed to allocate ringbuffer\n"); - i915_gem_cleanup_hws(dev); - return -ENOMEM; + ret = -ENOMEM; + goto cleanup; } - obj_priv = to_intel_bo(obj); - ret = i915_gem_object_pin(obj, 4096); + ring->gem_object = obj; + + ret = i915_gem_object_pin(obj, ring->alignment); if (ret != 0) { drm_gem_object_unreference(obj); - i915_gem_cleanup_hws(dev); - return ret; + goto cleanup; } - /* Set up the kernel mapping for the ring. */ - ring->Size = obj->size; - + obj_priv = to_intel_bo(obj); + ring->map.size = ring->size; ring->map.offset = dev->agp->base + obj_priv->gtt_offset; - ring->map.size = obj->size; ring->map.type = 0; ring->map.flags = 0; ring->map.mtrr = 0; @@ -403,143 +499,85 @@ i915_gem_init_ringbuffer(struct drm_device *dev) drm_core_ioremap_wc(&ring->map, dev); if (ring->map.handle == NULL) { DRM_ERROR("Failed to map ringbuffer.\n"); - memset(&dev_priv->render_ring, 0, sizeof(dev_priv->render_ring)); i915_gem_object_unpin(obj); drm_gem_object_unreference(obj); - i915_gem_cleanup_hws(dev); - return -EINVAL; - } - ring->ring_obj = obj; - ring->virtual_start = ring->map.handle; - - /* Stop the ring if it's running. */ - I915_WRITE(PRB0_CTL, 0); - I915_WRITE(PRB0_TAIL, 0); - I915_WRITE(PRB0_HEAD, 0); - - /* Initialize the ring. */ - I915_WRITE(PRB0_START, obj_priv->gtt_offset); - head = I915_READ(PRB0_HEAD) & HEAD_ADDR; - - /* G45 ring initialization fails to reset head to zero */ - if (head != 0) { - DRM_ERROR("Ring head not reset to zero " - "ctl %08x head %08x tail %08x start %08x\n", - I915_READ(PRB0_CTL), - I915_READ(PRB0_HEAD), - I915_READ(PRB0_TAIL), - I915_READ(PRB0_START)); - I915_WRITE(PRB0_HEAD, 0); - - DRM_ERROR("Ring head forced to zero " - "ctl %08x head %08x tail %08x start %08x\n", - I915_READ(PRB0_CTL), - I915_READ(PRB0_HEAD), - I915_READ(PRB0_TAIL), - I915_READ(PRB0_START)); + ret = -EINVAL; + goto cleanup; } - I915_WRITE(PRB0_CTL, - ((obj->size - 4096) & RING_NR_PAGES) | - RING_NO_REPORT | - RING_VALID); - - head = I915_READ(PRB0_HEAD) & HEAD_ADDR; - - /* If the head is still not zero, the ring is dead */ - if (head != 0) { - DRM_ERROR("Ring initialization failed " - "ctl %08x head %08x tail %08x start %08x\n", - I915_READ(PRB0_CTL), - I915_READ(PRB0_HEAD), - I915_READ(PRB0_TAIL), - I915_READ(PRB0_START)); - return -EIO; + ring->virtual_start = ring->map.handle; + ret = ring->init(dev, ring); + if (ret != 0) { + intel_cleanup_ring_buffer(dev, ring); + return ret; } - /* Update our cache of the ring state */ if (!drm_core_check_feature(dev, DRIVER_MODESET)) i915_kernel_lost_context(dev); else { - ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; - ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; + ring->head = ring->get_head(dev, ring); + ring->tail = ring->get_tail(dev, ring); ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) - ring->space += ring->Size; + ring->space += ring->size; } - - if (IS_I9XX(dev) && !IS_GEN3(dev)) { - I915_WRITE(MI_MODE, - (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH); - } - - return 0; + INIT_LIST_HEAD(&ring->active_list); + INIT_LIST_HEAD(&ring->request_list); + return ret; +cleanup: + cleanup_status_page(dev, ring); + return ret; } -void -i915_gem_cleanup_ringbuffer(struct drm_device *dev) +void intel_cleanup_ring_buffer(struct drm_device *dev, + struct intel_ring_buffer *ring) { - drm_i915_private_t *dev_priv = dev->dev_private; - - if (dev_priv->render_ring.ring_obj == NULL) + if (ring->gem_object == NULL) return; - drm_core_ioremapfree(&dev_priv->render_ring.map, dev); - - i915_gem_object_unpin(dev_priv->render_ring.ring_obj); - drm_gem_object_unreference(dev_priv->render_ring.ring_obj); - dev_priv->render_ring.ring_obj = NULL; - memset(&dev_priv->render_ring, 0, sizeof(dev_priv->render_ring)); + drm_core_ioremapfree(&ring->map, dev); - i915_gem_cleanup_hws(dev); + i915_gem_object_unpin(ring->gem_object); + drm_gem_object_unreference(ring->gem_object); + ring->gem_object = NULL; + cleanup_status_page(dev, ring); } -/* As a ringbuffer is only allowed to wrap between instructions, fill - * the tail with NOOPs. - */ -int i915_wrap_ring(struct drm_device *dev) +int intel_wrap_ring_buffer(struct drm_device *dev, + struct intel_ring_buffer *ring) { - drm_i915_private_t *dev_priv = dev->dev_private; - volatile unsigned int *virt; + unsigned int *virt; int rem; + rem = ring->size - ring->tail; - rem = dev_priv->render_ring.Size - dev_priv->render_ring.tail; - if (dev_priv->render_ring.space < rem) { - int ret = i915_wait_ring(dev, rem, __func__); + if (ring->space < rem) { + int ret = intel_wait_ring_buffer(dev, ring, rem); if (ret) return ret; } - dev_priv->render_ring.space -= rem; - virt = (unsigned int *) - (dev_priv->render_ring.virtual_start + dev_priv->render_ring.tail); + virt = (unsigned int *)(ring->virtual_start + ring->tail); rem /= 4; while (rem--) *virt++ = MI_NOOP; - dev_priv->render_ring.tail = 0; + ring->tail = 0; return 0; } -int i915_wait_ring(struct drm_device * dev, int n, const char *caller) +int intel_wait_ring_buffer(struct drm_device *dev, + struct intel_ring_buffer *ring, int n) { - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_ring_buffer_t *ring = &(dev_priv->render_ring); - u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD; - u32 last_acthd = I915_READ(acthd_reg); - u32 acthd; - u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR; - int i; + unsigned long end; trace_i915_ring_wait_begin (dev); - - for (i = 0; i < 100000; i++) { - ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; - acthd = I915_READ(acthd_reg); + end = jiffies + 3 * HZ; + do { + ring->head = ring->get_head(dev, ring); ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) - ring->space += ring->Size; + ring->space += ring->size; if (ring->space >= n) { trace_i915_ring_wait_end (dev); return 0; @@ -550,19 +588,97 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller) if (master_priv->sarea_priv) master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; } + yield(); + } while (!time_after(jiffies, end)); + trace_i915_ring_wait_end (dev); + return -EBUSY; +} +void intel_ring_begin(struct drm_device *dev, + struct intel_ring_buffer *ring, int n) +{ + if (unlikely(ring->tail + n > ring->size)) + intel_wrap_ring_buffer(dev, ring); + if (unlikely(ring->space < n)) + intel_wait_ring_buffer(dev, ring, n); +} - if (ring->head != last_head) - i = 0; - if (acthd != last_acthd) - i = 0; +void intel_ring_emit(struct drm_device *dev, + struct intel_ring_buffer *ring, unsigned int data) +{ + unsigned int *virt = ring->virtual_start + ring->tail; + *virt = data; + ring->tail += 4; + ring->tail &= ring->size - 1; + ring->space -= 4; +} - last_head = ring->head; - last_acthd = acthd; - msleep_interruptible(10); +void intel_ring_advance(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + ring->advance_ring(dev, ring); +} - } +void intel_fill_struct(struct drm_device *dev, + struct intel_ring_buffer *ring, + void *data, + unsigned int len) +{ + unsigned int *virt = ring->virtual_start + ring->tail; + BUG_ON((len&~(4-1)) != 0); + intel_ring_begin(dev, ring, len); + memcpy(virt, data, len); + ring->tail += len; + ring->tail &= ring->size - 1; + ring->space -= len; + intel_ring_advance(dev, ring); +} - trace_i915_ring_wait_end (dev); - return -EBUSY; +u32 intel_ring_get_seqno(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + u32 seqno; + seqno = ring->next_seqno; + + /* reserve 0 for non-seqno */ + if (++ring->next_seqno == 0) + ring->next_seqno = 1; + return seqno; } + +struct intel_ring_buffer render_ring = { + .name = "render ring", + .regs = { + .ctl = PRB0_CTL, + .head = PRB0_HEAD, + .tail = PRB0_TAIL, + .start = PRB0_START + }, + .ring_flag = I915_EXEC_RENDER, + .size = 32 * PAGE_SIZE, + .alignment = PAGE_SIZE, + .virtual_start = NULL, + .dev = NULL, + .gem_object = NULL, + .head = 0, + .tail = 0, + .space = 0, + .next_seqno = 1, + .user_irq_refcount = 0, + .irq_gem_seqno = 0, + .waiting_gem_seqno = 0, + .setup_status_page = render_setup_status_page, + .init = init_render_ring, + .get_head = render_ring_get_head, + .get_tail = render_ring_get_tail, + .get_active_head = render_ring_get_active_head, + .advance_ring = render_ring_advance_ring, + .flush = render_ring_flush, + .add_request = render_ring_add_request, + .get_gem_seqno = render_ring_get_gem_seqno, + .user_irq_get = render_ring_get_user_irq, + .user_irq_put = render_ring_put_user_irq, + .dispatch_gem_execbuffer = render_ring_dispatch_gem_execbuffer, + .status_page = {NULL, 0, NULL}, + .map = {0,} +}; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h new file mode 100644 index 000000000000..d5568d3766de --- /dev/null +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -0,0 +1,124 @@ +#ifndef _INTEL_RINGBUFFER_H_ +#define _INTEL_RINGBUFFER_H_ + +struct intel_hw_status_page { + void *page_addr; + unsigned int gfx_addr; + struct drm_gem_object *obj; +}; + +struct drm_i915_gem_execbuffer2; +struct intel_ring_buffer { + const char *name; + struct ring_regs { + u32 ctl; + u32 head; + u32 tail; + u32 start; + } regs; + unsigned int ring_flag; + unsigned long size; + unsigned int alignment; + void *virtual_start; + struct drm_device *dev; + struct drm_gem_object *gem_object; + + unsigned int head; + unsigned int tail; + unsigned int space; + u32 next_seqno; + struct intel_hw_status_page status_page; + + u32 irq_gem_seqno; /* last seq seem at irq time */ + u32 waiting_gem_seqno; + int user_irq_refcount; + void (*user_irq_get)(struct drm_device *dev, + struct intel_ring_buffer *ring); + void (*user_irq_put)(struct drm_device *dev, + struct intel_ring_buffer *ring); + void (*setup_status_page)(struct drm_device *dev, + struct intel_ring_buffer *ring); + + int (*init)(struct drm_device *dev, + struct intel_ring_buffer *ring); + + unsigned int (*get_head)(struct drm_device *dev, + struct intel_ring_buffer *ring); + unsigned int (*get_tail)(struct drm_device *dev, + struct intel_ring_buffer *ring); + unsigned int (*get_active_head)(struct drm_device *dev, + struct intel_ring_buffer *ring); + void (*advance_ring)(struct drm_device *dev, + struct intel_ring_buffer *ring); + void (*flush)(struct drm_device *dev, + struct intel_ring_buffer *ring, + u32 invalidate_domains, + u32 flush_domains); + u32 (*add_request)(struct drm_device *dev, + struct intel_ring_buffer *ring, + struct drm_file *file_priv, + u32 flush_domains); + u32 (*get_gem_seqno)(struct drm_device *dev, + struct intel_ring_buffer *ring); + int (*dispatch_gem_execbuffer)(struct drm_device *dev, + struct intel_ring_buffer *ring, + struct drm_i915_gem_execbuffer2 *exec, + struct drm_clip_rect *cliprects, + uint64_t exec_offset); + + /** + * List of objects currently involved in rendering from the + * ringbuffer. + * + * Includes buffers having the contents of their GPU caches + * flushed, not necessarily primitives. last_rendering_seqno + * represents when the rendering involved will be completed. + * + * A reference is held on the buffer while on this list. + */ + struct list_head active_list; + + /** + * List of breadcrumbs associated with GPU requests currently + * outstanding. + */ + struct list_head request_list; + + wait_queue_head_t irq_queue; + drm_local_map_t map; +}; + +static inline u32 +intel_read_status_page(struct intel_ring_buffer *ring, + int reg) +{ + u32 *regs = ring->status_page.page_addr; + return regs[reg]; +} + +int intel_init_ring_buffer(struct drm_device *dev, + struct intel_ring_buffer *ring); +void intel_cleanup_ring_buffer(struct drm_device *dev, + struct intel_ring_buffer *ring); +int intel_wait_ring_buffer(struct drm_device *dev, + struct intel_ring_buffer *ring, int n); +int intel_wrap_ring_buffer(struct drm_device *dev, + struct intel_ring_buffer *ring); +void intel_ring_begin(struct drm_device *dev, + struct intel_ring_buffer *ring, int n); +void intel_ring_emit(struct drm_device *dev, + struct intel_ring_buffer *ring, u32 data); +void intel_fill_struct(struct drm_device *dev, + struct intel_ring_buffer *ring, + void *data, + unsigned int len); +void intel_ring_advance(struct drm_device *dev, + struct intel_ring_buffer *ring); + +u32 intel_ring_get_seqno(struct drm_device *dev, + struct intel_ring_buffer *ring); + +extern struct intel_ring_buffer render_ring; +extern struct intel_ring_buffer bsd_ring; + +#endif /* _INTEL_RINGBUFFER_H_ */ diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index b64a8d7cdf6d..e9168704cabe 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -616,7 +616,9 @@ struct drm_i915_gem_execbuffer2 { __u32 num_cliprects; /** This is a struct drm_clip_rect *cliprects */ __u64 cliprects_ptr; - __u64 flags; /* currently unused */ +#define I915_EXEC_RENDER (1<<0) +#define I915_EXEC_BSD (1<<1) + __u64 flags; __u64 rsvd1; __u64 rsvd2; }; -- cgit v1.2.3 From 852835f343146a82a528c3b712b373661d4fa17a Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Fri, 21 May 2010 09:08:56 +0800 Subject: drm/i915: convert some gem structures to per-ring V2 The active list and request list move into the ringbuffer structure, so each can track its active objects in the order they are in that ring. The flushing list does not, as it doesn't matter which ring caused data to end up in the render cache. Objects gain a pointer to the ring they are active on (if any). Signed-off-by: Zou Nan hai Signed-off-by: Xiang Hai hao Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_debugfs.c | 12 +- drivers/gpu/drm/i915/i915_dma.c | 8 +- drivers/gpu/drm/i915/i915_drv.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 39 +++---- drivers/gpu/drm/i915/i915_gem.c | 210 ++++++++++++++++++++--------------- drivers/gpu/drm/i915/i915_irq.c | 45 +++++--- drivers/gpu/drm/i915/intel_overlay.c | 44 +++++--- 7 files changed, 207 insertions(+), 153 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 4fddf094deb2..c864858d5064 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -77,7 +77,7 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) case ACTIVE_LIST: seq_printf(m, "Active:\n"); lock = &dev_priv->mm.active_list_lock; - head = &dev_priv->mm.active_list; + head = &dev_priv->render_ring.active_list; break; case INACTIVE_LIST: seq_printf(m, "Inactive:\n"); @@ -129,7 +129,8 @@ static int i915_gem_request_info(struct seq_file *m, void *data) struct drm_i915_gem_request *gem_request; seq_printf(m, "Request:\n"); - list_for_each_entry(gem_request, &dev_priv->mm.request_list, list) { + list_for_each_entry(gem_request, &dev_priv->render_ring.request_list, + list) { seq_printf(m, " %d @ %d\n", gem_request->seqno, (int) (jiffies - gem_request->emitted_jiffies)); @@ -145,7 +146,7 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data) if (dev_priv->hw_status_page != NULL) { seq_printf(m, "Current sequence: %d\n", - i915_get_gem_seqno(dev)); + i915_get_gem_seqno(dev, &dev_priv->render_ring)); } else { seq_printf(m, "Current sequence: hws uninitialized\n"); } @@ -197,7 +198,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) atomic_read(&dev_priv->irq_received)); if (dev_priv->hw_status_page != NULL) { seq_printf(m, "Current sequence: %d\n", - i915_get_gem_seqno(dev)); + i915_get_gem_seqno(dev, &dev_priv->render_ring)); } else { seq_printf(m, "Current sequence: hws uninitialized\n"); } @@ -287,7 +288,8 @@ static int i915_batchbuffer_info(struct seq_file *m, void *data) spin_lock(&dev_priv->mm.active_list_lock); - list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { + list_for_each_entry(obj_priv, &dev_priv->render_ring.active_list, + list) { obj = &obj_priv->base; if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) { ret = i915_gem_object_get_pages(obj, 0); diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 2541428b2fe5..f485880300ce 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -82,7 +82,8 @@ static void i915_free_hws(struct drm_device *dev) dev_priv->status_page_dmah = NULL; } - if (dev_priv->status_gfx_addr) { + if (dev_priv->render_ring.status_page.gfx_addr) { + dev_priv->render_ring.status_page.gfx_addr = 0; dev_priv->status_gfx_addr = 0; drm_core_ioremapfree(&dev_priv->hws_map, dev); } @@ -835,9 +836,9 @@ static int i915_set_status_page(struct drm_device *dev, void *data, I915_WRITE(HWS_PGA, ring->status_page.gfx_addr); DRM_DEBUG_DRIVER("load hws HWS_PGA with gfx mem 0x%x\n", - dev_priv->status_gfx_addr); + dev_priv->status_gfx_addr); DRM_DEBUG_DRIVER("load hws at %p\n", - dev_priv->hw_status_page); + dev_priv->hw_status_page); return 0; } @@ -1510,7 +1511,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) resource_size_t base, size; int ret = 0, mmio_bar; uint32_t agp_size, prealloc_size, prealloc_start; - /* i915 has 4 more counters */ dev->counters += 4; dev->types[6] = _DRM_STAT_IRQ; diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index c57c54f403da..d40f62d36453 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -340,7 +340,7 @@ int i965_reset(struct drm_device *dev, u8 flags) /* * Clear request list */ - i915_gem_retire_requests(dev); + i915_gem_retire_requests(dev, &dev_priv->render_ring); if (need_display) i915_save_display(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6bb7933d49dc..3f35989ba74c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -505,18 +505,7 @@ typedef struct drm_i915_private { */ struct list_head shrink_list; - /** - * List of objects currently involved in rendering from the - * ringbuffer. - * - * Includes buffers having the contents of their GPU caches - * flushed, not necessarily primitives. last_rendering_seqno - * represents when the rendering involved will be completed. - * - * A reference is held on the buffer while on this list. - */ spinlock_t active_list_lock; - struct list_head active_list; /** * List of objects which are not in the ringbuffer but which @@ -553,12 +542,6 @@ typedef struct drm_i915_private { /** LRU list of objects with fence regs on them. */ struct list_head fence_list; - /** - * List of breadcrumbs associated with GPU requests currently - * outstanding. - */ - struct list_head request_list; - /** * We leave the user IRQ off as much as possible, * but this means that requests will finish and never @@ -683,6 +666,9 @@ struct drm_i915_gem_object { */ uint32_t gtt_offset; + /* Which ring is refering to is this object */ + struct intel_ring_buffer *ring; + /** * Fake offset for use by mmap(2) */ @@ -756,6 +742,9 @@ struct drm_i915_gem_object { * an emission time with seqnos for tracking how far ahead of the GPU we are. */ struct drm_i915_gem_request { + /** On Which ring this request was generated */ + struct intel_ring_buffer *ring; + /** GEM sequence number associated with this request. */ uint32_t seqno; @@ -916,11 +905,13 @@ void i915_gem_object_unpin(struct drm_gem_object *obj); int i915_gem_object_unbind(struct drm_gem_object *obj); void i915_gem_release_mmap(struct drm_gem_object *obj); void i915_gem_lastclose(struct drm_device *dev); -uint32_t i915_get_gem_seqno(struct drm_device *dev); +uint32_t i915_get_gem_seqno(struct drm_device *dev, + struct intel_ring_buffer *ring); bool i915_seqno_passed(uint32_t seq1, uint32_t seq2); int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); int i915_gem_object_put_fence_reg(struct drm_gem_object *obj); -void i915_gem_retire_requests(struct drm_device *dev); +void i915_gem_retire_requests(struct drm_device *dev, + struct intel_ring_buffer *ring); void i915_gem_retire_work_handler(struct work_struct *work); void i915_gem_clflush_object(struct drm_gem_object *obj); int i915_gem_object_set_domain(struct drm_gem_object *obj, @@ -931,9 +922,13 @@ void i915_gem_cleanup_ringbuffer(struct drm_device *dev); int i915_gem_do_init(struct drm_device *dev, unsigned long start, unsigned long end); int i915_gem_idle(struct drm_device *dev); -uint32_t i915_add_request(struct drm_device *dev, struct drm_file *file_priv, - uint32_t flush_domains); -int i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible); +uint32_t i915_add_request(struct drm_device *dev, + struct drm_file *file_priv, + uint32_t flush_domains, + struct intel_ring_buffer *ring); +int i915_do_wait_request(struct drm_device *dev, + uint32_t seqno, int interruptible, + struct intel_ring_buffer *ring); int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 58b6e814fae1..af664ba923c5 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1482,11 +1482,14 @@ i915_gem_object_put_pages(struct drm_gem_object *obj) } static void -i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno) +i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno, + struct intel_ring_buffer *ring) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + BUG_ON(ring == NULL); + obj_priv->ring = ring; /* Add a reference if we're newly entering the active list. */ if (!obj_priv->active) { @@ -1495,8 +1498,7 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno) } /* Move from whatever list we were on to the tail of execution. */ spin_lock(&dev_priv->mm.active_list_lock); - list_move_tail(&obj_priv->list, - &dev_priv->mm.active_list); + list_move_tail(&obj_priv->list, &ring->active_list); spin_unlock(&dev_priv->mm.active_list_lock); obj_priv->last_rendering_seqno = seqno; } @@ -1549,6 +1551,7 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj) BUG_ON(!list_empty(&obj_priv->gpu_write_list)); obj_priv->last_rendering_seqno = 0; + obj_priv->ring = NULL; if (obj_priv->active) { obj_priv->active = 0; drm_gem_object_unreference(obj); @@ -1558,7 +1561,8 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj) static void i915_gem_process_flushing_list(struct drm_device *dev, - uint32_t flush_domains, uint32_t seqno) + uint32_t flush_domains, uint32_t seqno, + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv, *next; @@ -1569,12 +1573,13 @@ i915_gem_process_flushing_list(struct drm_device *dev, struct drm_gem_object *obj = &obj_priv->base; if ((obj->write_domain & flush_domains) == - obj->write_domain) { + obj->write_domain && + obj_priv->ring->ring_flag == ring->ring_flag) { uint32_t old_write_domain = obj->write_domain; obj->write_domain = 0; list_del_init(&obj_priv->gpu_write_list); - i915_gem_object_move_to_active(obj, seqno); + i915_gem_object_move_to_active(obj, seqno, ring); /* update the fence lru list */ if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { @@ -1593,7 +1598,7 @@ i915_gem_process_flushing_list(struct drm_device *dev, uint32_t i915_add_request(struct drm_device *dev, struct drm_file *file_priv, - uint32_t flush_domains) + uint32_t flush_domains, struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_file_private *i915_file_priv = NULL; @@ -1608,15 +1613,14 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, if (request == NULL) return 0; - seqno = dev_priv->render_ring.add_request(dev, &dev_priv->render_ring, - file_priv, flush_domains); - - DRM_DEBUG_DRIVER("%d\n", seqno); + seqno = ring->add_request(dev, ring, file_priv, flush_domains); request->seqno = seqno; + request->ring = ring; request->emitted_jiffies = jiffies; - was_empty = list_empty(&dev_priv->mm.request_list); - list_add_tail(&request->list, &dev_priv->mm.request_list); + was_empty = list_empty(&ring->request_list); + list_add_tail(&request->list, &ring->request_list); + if (i915_file_priv) { list_add_tail(&request->client_list, &i915_file_priv->mm.request_list); @@ -1628,7 +1632,7 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, * domain we're flushing with our flush. */ if (flush_domains != 0) - i915_gem_process_flushing_list(dev, flush_domains, seqno); + i915_gem_process_flushing_list(dev, flush_domains, seqno, ring); if (!dev_priv->mm.suspended) { mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); @@ -1645,18 +1649,16 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, * before signalling the CPU */ static uint32_t -i915_retire_commands(struct drm_device *dev) +i915_retire_commands(struct drm_device *dev, struct intel_ring_buffer *ring) { - uint32_t cmd = MI_FLUSH | MI_NO_WRITE_FLUSH; uint32_t flush_domains = 0; /* The sampler always gets flushed on i965 (sigh) */ if (IS_I965G(dev)) flush_domains |= I915_GEM_DOMAIN_SAMPLER; - BEGIN_LP_RING(2); - OUT_RING(cmd); - OUT_RING(0); /* noop */ - ADVANCE_LP_RING(); + + ring->flush(dev, ring, + I915_GEM_DOMAIN_COMMAND, flush_domains); return flush_domains; } @@ -1676,11 +1678,11 @@ i915_gem_retire_request(struct drm_device *dev, * by the ringbuffer to the flushing/inactive lists as appropriate. */ spin_lock(&dev_priv->mm.active_list_lock); - while (!list_empty(&dev_priv->mm.active_list)) { + while (!list_empty(&request->ring->active_list)) { struct drm_gem_object *obj; struct drm_i915_gem_object *obj_priv; - obj_priv = list_first_entry(&dev_priv->mm.active_list, + obj_priv = list_first_entry(&request->ring->active_list, struct drm_i915_gem_object, list); obj = &obj_priv->base; @@ -1727,37 +1729,33 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2) } uint32_t -i915_get_gem_seqno(struct drm_device *dev) +i915_get_gem_seqno(struct drm_device *dev, + struct intel_ring_buffer *ring) { - drm_i915_private_t *dev_priv = dev->dev_private; - - if (HAS_PIPE_CONTROL(dev)) - return ((volatile u32 *)(dev_priv->seqno_page))[0]; - else - return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX); + return ring->get_gem_seqno(dev, ring); } /** * This function clears the request list as sequence numbers are passed. */ void -i915_gem_retire_requests(struct drm_device *dev) +i915_gem_retire_requests(struct drm_device *dev, + struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; uint32_t seqno; - struct intel_ring_buffer *ring = &(dev_priv->render_ring); if (!ring->status_page.page_addr - || list_empty(&dev_priv->mm.request_list)) + || list_empty(&ring->request_list)) return; - seqno = i915_get_gem_seqno(dev); + seqno = i915_get_gem_seqno(dev, ring); - while (!list_empty(&dev_priv->mm.request_list)) { + while (!list_empty(&ring->request_list)) { struct drm_i915_gem_request *request; uint32_t retiring_seqno; - request = list_first_entry(&dev_priv->mm.request_list, + request = list_first_entry(&ring->request_list, struct drm_i915_gem_request, list); retiring_seqno = request->seqno; @@ -1792,27 +1790,28 @@ i915_gem_retire_work_handler(struct work_struct *work) dev = dev_priv->dev; mutex_lock(&dev->struct_mutex); - i915_gem_retire_requests(dev); + i915_gem_retire_requests(dev, &dev_priv->render_ring); + if (!dev_priv->mm.suspended && - !list_empty(&dev_priv->mm.request_list)) + (!list_empty(&dev_priv->render_ring.request_list))) queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); mutex_unlock(&dev->struct_mutex); } int -i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) +i915_do_wait_request(struct drm_device *dev, uint32_t seqno, + int interruptible, struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; u32 ier; int ret = 0; - struct intel_ring_buffer *ring = &dev_priv->render_ring; BUG_ON(seqno == 0); if (atomic_read(&dev_priv->mm.wedged)) return -EIO; - if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) { + if (!i915_seqno_passed(ring->get_gem_seqno(dev, ring), seqno)) { if (HAS_PCH_SPLIT(dev)) ier = I915_READ(DEIER) | I915_READ(GTIER); else @@ -1826,19 +1825,21 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) trace_i915_gem_request_wait_begin(dev, seqno); - dev_priv->mm.waiting_gem_seqno = seqno; + ring->waiting_gem_seqno = seqno; ring->user_irq_get(dev, ring); if (interruptible) - ret = wait_event_interruptible(dev_priv->irq_queue, - i915_seqno_passed(i915_get_gem_seqno(dev), seqno) || - atomic_read(&dev_priv->mm.wedged)); + ret = wait_event_interruptible(ring->irq_queue, + i915_seqno_passed( + ring->get_gem_seqno(dev, ring), seqno) + || atomic_read(&dev_priv->mm.wedged)); else - wait_event(dev_priv->irq_queue, - i915_seqno_passed(i915_get_gem_seqno(dev), seqno) || - atomic_read(&dev_priv->mm.wedged)); + wait_event(ring->irq_queue, + i915_seqno_passed( + ring->get_gem_seqno(dev, ring), seqno) + || atomic_read(&dev_priv->mm.wedged)); ring->user_irq_put(dev, ring); - dev_priv->mm.waiting_gem_seqno = 0; + ring->waiting_gem_seqno = 0; trace_i915_gem_request_wait_end(dev, seqno); } @@ -1847,7 +1848,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) if (ret && ret != -ERESTARTSYS) DRM_ERROR("%s returns %d (awaiting %d at %d)\n", - __func__, ret, seqno, i915_get_gem_seqno(dev)); + __func__, ret, seqno, ring->get_gem_seqno(dev, ring)); /* Directly dispatch request retiring. While we have the work queue * to handle this, the waiter on a request often wants an associated @@ -1855,7 +1856,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) * a separate wait queue to handle that. */ if (ret == 0) - i915_gem_retire_requests(dev); + i915_gem_retire_requests(dev, ring); return ret; } @@ -1865,12 +1866,12 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) * request and object lists appropriately for that event. */ static int -i915_wait_request(struct drm_device *dev, uint32_t seqno) +i915_wait_request(struct drm_device *dev, uint32_t seqno, + struct intel_ring_buffer *ring) { - return i915_do_wait_request(dev, seqno, 1); + return i915_do_wait_request(dev, seqno, 1, ring); } - static void i915_gem_flush(struct drm_device *dev, uint32_t invalidate_domains, @@ -1884,6 +1885,19 @@ i915_gem_flush(struct drm_device *dev, flush_domains); } +static void +i915_gem_flush_ring(struct drm_device *dev, + uint32_t invalidate_domains, + uint32_t flush_domains, + struct intel_ring_buffer *ring) +{ + if (flush_domains & I915_GEM_DOMAIN_CPU) + drm_agp_chipset_flush(dev); + ring->flush(dev, ring, + invalidate_domains, + flush_domains); +} + /** * Ensures that all rendering to the object has completed and the object is * safe to unbind from the GTT or access from the CPU. @@ -1908,7 +1922,8 @@ i915_gem_object_wait_rendering(struct drm_gem_object *obj) DRM_INFO("%s: object %p wait for seqno %08x\n", __func__, obj, obj_priv->last_rendering_seqno); #endif - ret = i915_wait_request(dev, obj_priv->last_rendering_seqno); + ret = i915_wait_request(dev, + obj_priv->last_rendering_seqno, obj_priv->ring); if (ret != 0) return ret; } @@ -2025,10 +2040,11 @@ i915_gpu_idle(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; bool lists_empty; uint32_t seqno; + int ret; spin_lock(&dev_priv->mm.active_list_lock); lists_empty = list_empty(&dev_priv->mm.flushing_list) && - list_empty(&dev_priv->mm.active_list); + list_empty(&dev_priv->render_ring.active_list); spin_unlock(&dev_priv->mm.active_list_lock); if (lists_empty) @@ -2036,11 +2052,13 @@ i915_gpu_idle(struct drm_device *dev) /* Flush everything onto the inactive list. */ i915_gem_flush(dev, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); - seqno = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS); + seqno = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS, + &dev_priv->render_ring); if (seqno == 0) return -ENOMEM; + ret = i915_wait_request(dev, seqno, &dev_priv->render_ring); - return i915_wait_request(dev, seqno); + return ret; } static int @@ -2053,7 +2071,7 @@ i915_gem_evict_everything(struct drm_device *dev) spin_lock(&dev_priv->mm.active_list_lock); lists_empty = (list_empty(&dev_priv->mm.inactive_list) && list_empty(&dev_priv->mm.flushing_list) && - list_empty(&dev_priv->mm.active_list)); + list_empty(&dev_priv->render_ring.active_list)); spin_unlock(&dev_priv->mm.active_list_lock); if (lists_empty) @@ -2073,7 +2091,7 @@ i915_gem_evict_everything(struct drm_device *dev) spin_lock(&dev_priv->mm.active_list_lock); lists_empty = (list_empty(&dev_priv->mm.inactive_list) && list_empty(&dev_priv->mm.flushing_list) && - list_empty(&dev_priv->mm.active_list)); + list_empty(&dev_priv->render_ring.active_list)); spin_unlock(&dev_priv->mm.active_list_lock); BUG_ON(!lists_empty); @@ -2087,8 +2105,9 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) struct drm_gem_object *obj; int ret; + struct intel_ring_buffer *render_ring = &dev_priv->render_ring; for (;;) { - i915_gem_retire_requests(dev); + i915_gem_retire_requests(dev, render_ring); /* If there's an inactive buffer available now, grab it * and be done. @@ -2112,14 +2131,15 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) * things, wait for the next to finish and hopefully leave us * a buffer to evict. */ - if (!list_empty(&dev_priv->mm.request_list)) { + if (!list_empty(&render_ring->request_list)) { struct drm_i915_gem_request *request; - request = list_first_entry(&dev_priv->mm.request_list, + request = list_first_entry(&render_ring->request_list, struct drm_i915_gem_request, list); - ret = i915_wait_request(dev, request->seqno); + ret = i915_wait_request(dev, + request->seqno, request->ring); if (ret) return ret; @@ -2146,10 +2166,13 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) if (obj != NULL) { uint32_t seqno; - i915_gem_flush(dev, + i915_gem_flush_ring(dev, + obj->write_domain, obj->write_domain, - obj->write_domain); - seqno = i915_add_request(dev, NULL, obj->write_domain); + obj_priv->ring); + seqno = i915_add_request(dev, NULL, + obj->write_domain, + obj_priv->ring); if (seqno == 0) return -ENOMEM; continue; @@ -2685,6 +2708,7 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; uint32_t old_write_domain; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0) return; @@ -2692,7 +2716,7 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj) /* Queue the GPU write cache flushing we need. */ old_write_domain = obj->write_domain; i915_gem_flush(dev, 0, obj->write_domain); - (void) i915_add_request(dev, NULL, obj->write_domain); + (void) i915_add_request(dev, NULL, obj->write_domain, obj_priv->ring); BUG_ON(obj->write_domain); trace_i915_gem_object_change_domain(obj, @@ -2832,7 +2856,10 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj) DRM_INFO("%s: object %p wait for seqno %08x\n", __func__, obj, obj_priv->last_rendering_seqno); #endif - ret = i915_do_wait_request(dev, obj_priv->last_rendering_seqno, 0); + ret = i915_do_wait_request(dev, + obj_priv->last_rendering_seqno, + 0, + obj_priv->ring); if (ret != 0) return ret; } @@ -3451,7 +3478,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file_priv) if (time_after_eq(request->emitted_jiffies, recent_enough)) break; - ret = i915_wait_request(dev, request->seqno); + ret = i915_wait_request(dev, request->seqno, request->ring); if (ret != 0) break; } @@ -3608,6 +3635,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, uint32_t seqno, flush_domains, reloc_index; int pin_tries, flips; + struct intel_ring_buffer *ring = NULL; + #if WATCH_EXEC DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", (int) args->buffers_ptr, args->buffer_count, args->batch_len); @@ -3665,6 +3694,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, goto pre_mutex_err; } + ring = &dev_priv->render_ring; + /* Look up object handles */ flips = 0; for (i = 0; i < args->buffer_count; i++) { @@ -3798,9 +3829,12 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, i915_gem_flush(dev, dev->invalidate_domains, dev->flush_domains); - if (dev->flush_domains & I915_GEM_GPU_DOMAINS) + if (dev->flush_domains & I915_GEM_GPU_DOMAINS) { (void)i915_add_request(dev, file_priv, - dev->flush_domains); + dev->flush_domains, + &dev_priv->render_ring); + + } } for (i = 0; i < args->buffer_count; i++) { @@ -3837,11 +3871,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, #endif /* Exec the batchbuffer */ - ret = dev_priv->render_ring.dispatch_gem_execbuffer(dev, - &dev_priv->render_ring, - args, - cliprects, - exec_offset); + ret = ring->dispatch_gem_execbuffer(dev, ring, args, + cliprects, exec_offset); if (ret) { DRM_ERROR("dispatch failed %d\n", ret); goto err; @@ -3851,7 +3882,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, * Ensure that the commands in the batch buffer are * finished before the interrupt fires */ - flush_domains = i915_retire_commands(dev); + flush_domains = i915_retire_commands(dev, ring); i915_verify_inactive(dev, __FILE__, __LINE__); @@ -3862,12 +3893,13 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, * *some* interrupts representing completion of buffers that we can * wait on when trying to clear up gtt space). */ - seqno = i915_add_request(dev, file_priv, flush_domains); + seqno = i915_add_request(dev, file_priv, flush_domains, ring); BUG_ON(seqno == 0); for (i = 0; i < args->buffer_count; i++) { struct drm_gem_object *obj = object_list[i]; + obj_priv = to_intel_bo(obj); - i915_gem_object_move_to_active(obj, seqno); + i915_gem_object_move_to_active(obj, seqno, ring); #if WATCH_LRU DRM_INFO("%s: move to exec list %p\n", __func__, obj); #endif @@ -3979,7 +4011,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, exec2.DR4 = args->DR4; exec2.num_cliprects = args->num_cliprects; exec2.cliprects_ptr = args->cliprects_ptr; - exec2.flags = 0; + exec2.flags = I915_EXEC_RENDER; ret = i915_gem_do_execbuffer(dev, data, file_priv, &exec2, exec2_list); if (!ret) { @@ -4218,6 +4250,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, struct drm_i915_gem_busy *args = data; struct drm_gem_object *obj; struct drm_i915_gem_object *obj_priv; + drm_i915_private_t *dev_priv = dev->dev_private; obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) { @@ -4232,7 +4265,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, * actually unmasked, and our working set ends up being larger than * required. */ - i915_gem_retire_requests(dev); + i915_gem_retire_requests(dev, &dev_priv->render_ring); obj_priv = to_intel_bo(obj); /* Don't count being on the flushing list against the object being @@ -4555,12 +4588,12 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, } spin_lock(&dev_priv->mm.active_list_lock); - BUG_ON(!list_empty(&dev_priv->mm.active_list)); + BUG_ON(!list_empty(&dev_priv->render_ring.active_list)); spin_unlock(&dev_priv->mm.active_list_lock); BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); - BUG_ON(!list_empty(&dev_priv->mm.request_list)); + BUG_ON(!list_empty(&dev_priv->render_ring.request_list)); mutex_unlock(&dev->struct_mutex); drm_irq_install(dev); @@ -4599,18 +4632,16 @@ i915_gem_load(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; spin_lock_init(&dev_priv->mm.active_list_lock); - INIT_LIST_HEAD(&dev_priv->mm.active_list); INIT_LIST_HEAD(&dev_priv->mm.flushing_list); INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list); INIT_LIST_HEAD(&dev_priv->mm.inactive_list); - INIT_LIST_HEAD(&dev_priv->mm.request_list); INIT_LIST_HEAD(&dev_priv->mm.fence_list); + INIT_LIST_HEAD(&dev_priv->render_ring.active_list); + INIT_LIST_HEAD(&dev_priv->render_ring.request_list); for (i = 0; i < 16; i++) INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); INIT_DELAYED_WORK(&dev_priv->mm.retire_work, i915_gem_retire_work_handler); - dev_priv->mm.next_gem_seqno = 1; - spin_lock(&shrink_list_lock); list_add(&dev_priv->mm.shrink_list, &shrink_list); spin_unlock(&shrink_list_lock); @@ -4842,7 +4873,7 @@ i915_gpu_is_active(struct drm_device *dev) spin_lock(&dev_priv->mm.active_list_lock); lists_empty = list_empty(&dev_priv->mm.flushing_list) && - list_empty(&dev_priv->mm.active_list); + list_empty(&dev_priv->render_ring.active_list); spin_unlock(&dev_priv->mm.active_list_lock); return !lists_empty; @@ -4887,8 +4918,7 @@ rescan: continue; spin_unlock(&shrink_list_lock); - - i915_gem_retire_requests(dev); + i915_gem_retire_requests(dev, &dev_priv->render_ring); list_for_each_entry_safe(obj_priv, next_obj, &dev_priv->mm.inactive_list, diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index e07c643c8365..8a667f1db75a 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -331,6 +331,7 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) int ret = IRQ_NONE; u32 de_iir, gt_iir, de_ier, pch_iir; struct drm_i915_master_private *master_priv; + struct intel_ring_buffer *render_ring = &dev_priv->render_ring; /* disable master interrupt before clearing iir */ de_ier = I915_READ(DEIER); @@ -354,10 +355,10 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) } if (gt_iir & GT_PIPE_NOTIFY) { - u32 seqno = i915_get_gem_seqno(dev); - dev_priv->mm.irq_gem_seqno = seqno; + u32 seqno = render_ring->get_gem_seqno(dev, render_ring); + render_ring->irq_gem_seqno = seqno; trace_i915_gem_request_complete(dev, seqno); - DRM_WAKEUP(&dev_priv->irq_queue); + DRM_WAKEUP(&dev_priv->render_ring.irq_queue); dev_priv->hangcheck_count = 0; mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); } @@ -588,7 +589,7 @@ static void i915_capture_error_state(struct drm_device *dev) return; } - error->seqno = i915_get_gem_seqno(dev); + error->seqno = i915_get_gem_seqno(dev, &dev_priv->render_ring); error->eir = I915_READ(EIR); error->pgtbl_er = I915_READ(PGTBL_ER); error->pipeastat = I915_READ(PIPEASTAT); @@ -616,7 +617,9 @@ static void i915_capture_error_state(struct drm_device *dev) batchbuffer[0] = NULL; batchbuffer[1] = NULL; count = 0; - list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { + list_for_each_entry(obj_priv, + &dev_priv->render_ring.active_list, list) { + struct drm_gem_object *obj = &obj_priv->base; if (batchbuffer[0] == NULL && @@ -653,7 +656,8 @@ static void i915_capture_error_state(struct drm_device *dev) if (error->active_bo) { int i = 0; - list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { + list_for_each_entry(obj_priv, + &dev_priv->render_ring.active_list, list) { struct drm_gem_object *obj = &obj_priv->base; error->active_bo[i].size = obj->size; @@ -831,7 +835,7 @@ static void i915_handle_error(struct drm_device *dev, bool wedged) /* * Wakeup waiting processes so they don't hang */ - DRM_WAKEUP(&dev_priv->irq_queue); + DRM_WAKEUP(&dev_priv->render_ring.irq_queue); } queue_work(dev_priv->wq, &dev_priv->error_work); @@ -850,6 +854,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) unsigned long irqflags; int irq_received; int ret = IRQ_NONE; + struct intel_ring_buffer *render_ring = &dev_priv->render_ring; atomic_inc(&dev_priv->irq_received); @@ -930,10 +935,11 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) } if (iir & I915_USER_INTERRUPT) { - u32 seqno = i915_get_gem_seqno(dev); - dev_priv->mm.irq_gem_seqno = seqno; + u32 seqno = + render_ring->get_gem_seqno(dev, render_ring); + render_ring->irq_gem_seqno = seqno; trace_i915_gem_request_complete(dev, seqno); - DRM_WAKEUP(&dev_priv->irq_queue); + DRM_WAKEUP(&dev_priv->render_ring.irq_queue); dev_priv->hangcheck_count = 0; mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); } @@ -1038,7 +1044,7 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; render_ring->user_irq_get(dev, render_ring); - DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ, + DRM_WAIT_ON(ret, dev_priv->render_ring.irq_queue, 3 * DRM_HZ, READ_BREADCRUMB(dev_priv) >= irq_nr); render_ring->user_irq_put(dev, render_ring); @@ -1205,9 +1211,12 @@ int i915_vblank_swap(struct drm_device *dev, void *data, return -EINVAL; } -struct drm_i915_gem_request *i915_get_tail_request(struct drm_device *dev) { +struct drm_i915_gem_request * +i915_get_tail_request(struct drm_device *dev) +{ drm_i915_private_t *dev_priv = dev->dev_private; - return list_entry(dev_priv->mm.request_list.prev, struct drm_i915_gem_request, list); + return list_entry(dev_priv->render_ring.request_list.prev, + struct drm_i915_gem_request, list); } /** @@ -1232,8 +1241,10 @@ void i915_hangcheck_elapsed(unsigned long data) acthd = I915_READ(ACTHD_I965); /* If all work is done then ACTHD clearly hasn't advanced. */ - if (list_empty(&dev_priv->mm.request_list) || - i915_seqno_passed(i915_get_gem_seqno(dev), i915_get_tail_request(dev)->seqno)) { + if (list_empty(&dev_priv->render_ring.request_list) || + i915_seqno_passed(i915_get_gem_seqno(dev, + &dev_priv->render_ring), + i915_get_tail_request(dev)->seqno)) { dev_priv->hangcheck_count = 0; return; } @@ -1300,7 +1311,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) (void) I915_READ(DEIER); /* user interrupt should be enabled, but masked initial */ - dev_priv->gt_irq_mask_reg = 0xffffffff; + dev_priv->gt_irq_mask_reg = ~render_mask; dev_priv->gt_irq_enable_reg = render_mask; I915_WRITE(GTIIR, I915_READ(GTIIR)); @@ -1363,7 +1374,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev) u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; u32 error_mask; - DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); + DRM_INIT_WAITQUEUE(&dev_priv->render_ring.irq_queue); dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 93da83782e5e..d7ad5139d17c 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -212,6 +212,7 @@ static int intel_overlay_on(struct intel_overlay *overlay) { struct drm_device *dev = overlay->dev; int ret; + drm_i915_private_t *dev_priv = dev->dev_private; BUG_ON(overlay->active); @@ -225,11 +226,13 @@ static int intel_overlay_on(struct intel_overlay *overlay) OUT_RING(MI_NOOP); ADVANCE_LP_RING(); - overlay->last_flip_req = i915_add_request(dev, NULL, 0); + overlay->last_flip_req = + i915_add_request(dev, NULL, 0, &dev_priv->render_ring); if (overlay->last_flip_req == 0) return -ENOMEM; - ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); + ret = i915_do_wait_request(dev, + overlay->last_flip_req, 1, &dev_priv->render_ring); if (ret != 0) return ret; @@ -262,7 +265,8 @@ static void intel_overlay_continue(struct intel_overlay *overlay, OUT_RING(flip_addr); ADVANCE_LP_RING(); - overlay->last_flip_req = i915_add_request(dev, NULL, 0); + overlay->last_flip_req = + i915_add_request(dev, NULL, 0, &dev_priv->render_ring); } static int intel_overlay_wait_flip(struct intel_overlay *overlay) @@ -273,7 +277,8 @@ static int intel_overlay_wait_flip(struct intel_overlay *overlay) u32 tmp; if (overlay->last_flip_req != 0) { - ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); + ret = i915_do_wait_request(dev, overlay->last_flip_req, + 1, &dev_priv->render_ring); if (ret == 0) { overlay->last_flip_req = 0; @@ -292,11 +297,13 @@ static int intel_overlay_wait_flip(struct intel_overlay *overlay) OUT_RING(MI_NOOP); ADVANCE_LP_RING(); - overlay->last_flip_req = i915_add_request(dev, NULL, 0); + overlay->last_flip_req = + i915_add_request(dev, NULL, 0, &dev_priv->render_ring); if (overlay->last_flip_req == 0) return -ENOMEM; - ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); + ret = i915_do_wait_request(dev, overlay->last_flip_req, + 1, &dev_priv->render_ring); if (ret != 0) return ret; @@ -310,6 +317,7 @@ static int intel_overlay_off(struct intel_overlay *overlay) { u32 flip_addr = overlay->flip_addr; struct drm_device *dev = overlay->dev; + drm_i915_private_t *dev_priv = dev->dev_private; int ret; BUG_ON(!overlay->active); @@ -330,11 +338,13 @@ static int intel_overlay_off(struct intel_overlay *overlay) OUT_RING(MI_NOOP); ADVANCE_LP_RING(); - overlay->last_flip_req = i915_add_request(dev, NULL, 0); + overlay->last_flip_req = + i915_add_request(dev, NULL, 0, &dev_priv->render_ring); if (overlay->last_flip_req == 0) return -ENOMEM; - ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); + ret = i915_do_wait_request(dev, overlay->last_flip_req, + 1, &dev_priv->render_ring); if (ret != 0) return ret; @@ -348,11 +358,13 @@ static int intel_overlay_off(struct intel_overlay *overlay) OUT_RING(MI_NOOP); ADVANCE_LP_RING(); - overlay->last_flip_req = i915_add_request(dev, NULL, 0); + overlay->last_flip_req = + i915_add_request(dev, NULL, 0, &dev_priv->render_ring); if (overlay->last_flip_req == 0) return -ENOMEM; - ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); + ret = i915_do_wait_request(dev, overlay->last_flip_req, + 1, &dev_priv->render_ring); if (ret != 0) return ret; @@ -385,6 +397,7 @@ int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, { struct drm_device *dev = overlay->dev; struct drm_gem_object *obj; + drm_i915_private_t *dev_priv = dev->dev_private; u32 flip_addr; int ret; @@ -392,12 +405,14 @@ int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, return -EIO; if (overlay->last_flip_req == 0) { - overlay->last_flip_req = i915_add_request(dev, NULL, 0); + overlay->last_flip_req = + i915_add_request(dev, NULL, 0, &dev_priv->render_ring); if (overlay->last_flip_req == 0) return -ENOMEM; } - ret = i915_do_wait_request(dev, overlay->last_flip_req, interruptible); + ret = i915_do_wait_request(dev, overlay->last_flip_req, + interruptible, &dev_priv->render_ring); if (ret != 0) return ret; @@ -421,12 +436,13 @@ int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, OUT_RING(MI_NOOP); ADVANCE_LP_RING(); - overlay->last_flip_req = i915_add_request(dev, NULL, 0); + overlay->last_flip_req = i915_add_request(dev, NULL, + 0, &dev_priv->render_ring); if (overlay->last_flip_req == 0) return -ENOMEM; ret = i915_do_wait_request(dev, overlay->last_flip_req, - interruptible); + interruptible, &dev_priv->render_ring); if (ret != 0) return ret; -- cgit v1.2.3 From d1b851fc0d105caa6b6e3e7c92d2987dfb52cbe0 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Fri, 21 May 2010 09:08:57 +0800 Subject: drm/i915: implement BSD ring buffer V2 The BSD (bit stream decoder) ring is used for accessing the BSD engine which decodes video bitstream for H.264 and VC1 on G45+. It is asynchronous with the render ring and has access to separate parts of the GPU from it, though the render cache is coherent between the two. Signed-off-by: Zou Nan hai Signed-off-by: Xiang Hai hao Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_dma.c | 2 + drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_gem.c | 107 +++++++++++++++++++--- drivers/gpu/drm/i915/i915_irq.c | 13 ++- drivers/gpu/drm/i915/i915_reg.h | 14 +++ drivers/gpu/drm/i915/intel_ringbuffer.c | 153 ++++++++++++++++++++++++++++++++ 6 files changed, 276 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index f485880300ce..1dbed700800e 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -130,6 +130,8 @@ static int i915_dma_cleanup(struct drm_device * dev) drm_irq_uninstall(dev); intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); + if (HAS_BSD(dev)) + intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring); /* Clear the HWS virtual address at teardown */ if (I915_NEED_GFX_HWS(dev)) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3f35989ba74c..6bc0fc080f2b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -235,6 +235,7 @@ typedef struct drm_i915_private { struct pci_dev *bridge_dev; struct intel_ring_buffer render_ring; + struct intel_ring_buffer bsd_ring; drm_dma_handle_t *status_page_dmah; void *hw_status_page; @@ -1121,6 +1122,7 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); (dev)->pci_device == 0x2A42 || \ (dev)->pci_device == 0x2E42) +#define HAS_BSD(dev) (IS_IRONLAKE(dev) || IS_G4X(dev)) #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index af664ba923c5..c51495f15718 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1730,7 +1730,7 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2) uint32_t i915_get_gem_seqno(struct drm_device *dev, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring) { return ring->get_gem_seqno(dev, ring); } @@ -1792,8 +1792,13 @@ i915_gem_retire_work_handler(struct work_struct *work) mutex_lock(&dev->struct_mutex); i915_gem_retire_requests(dev, &dev_priv->render_ring); + if (HAS_BSD(dev)) + i915_gem_retire_requests(dev, &dev_priv->bsd_ring); + if (!dev_priv->mm.suspended && - (!list_empty(&dev_priv->render_ring.request_list))) + (!list_empty(&dev_priv->render_ring.request_list) || + (HAS_BSD(dev) && + !list_empty(&dev_priv->bsd_ring.request_list)))) queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); mutex_unlock(&dev->struct_mutex); } @@ -1883,6 +1888,11 @@ i915_gem_flush(struct drm_device *dev, dev_priv->render_ring.flush(dev, &dev_priv->render_ring, invalidate_domains, flush_domains); + + if (HAS_BSD(dev)) + dev_priv->bsd_ring.flush(dev, &dev_priv->bsd_ring, + invalidate_domains, + flush_domains); } static void @@ -2039,12 +2049,14 @@ i915_gpu_idle(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; bool lists_empty; - uint32_t seqno; + uint32_t seqno1, seqno2; int ret; spin_lock(&dev_priv->mm.active_list_lock); - lists_empty = list_empty(&dev_priv->mm.flushing_list) && - list_empty(&dev_priv->render_ring.active_list); + lists_empty = (list_empty(&dev_priv->mm.flushing_list) && + list_empty(&dev_priv->render_ring.active_list) && + (!HAS_BSD(dev) || + list_empty(&dev_priv->bsd_ring.active_list))); spin_unlock(&dev_priv->mm.active_list_lock); if (lists_empty) @@ -2052,11 +2064,23 @@ i915_gpu_idle(struct drm_device *dev) /* Flush everything onto the inactive list. */ i915_gem_flush(dev, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); - seqno = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS, + seqno1 = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS, &dev_priv->render_ring); - if (seqno == 0) + if (seqno1 == 0) return -ENOMEM; - ret = i915_wait_request(dev, seqno, &dev_priv->render_ring); + ret = i915_wait_request(dev, seqno1, &dev_priv->render_ring); + + if (HAS_BSD(dev)) { + seqno2 = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS, + &dev_priv->bsd_ring); + if (seqno2 == 0) + return -ENOMEM; + + ret = i915_wait_request(dev, seqno2, &dev_priv->bsd_ring); + if (ret) + return ret; + } + return ret; } @@ -2071,7 +2095,9 @@ i915_gem_evict_everything(struct drm_device *dev) spin_lock(&dev_priv->mm.active_list_lock); lists_empty = (list_empty(&dev_priv->mm.inactive_list) && list_empty(&dev_priv->mm.flushing_list) && - list_empty(&dev_priv->render_ring.active_list)); + list_empty(&dev_priv->render_ring.active_list) && + (!HAS_BSD(dev) + || list_empty(&dev_priv->bsd_ring.active_list))); spin_unlock(&dev_priv->mm.active_list_lock); if (lists_empty) @@ -2091,7 +2117,9 @@ i915_gem_evict_everything(struct drm_device *dev) spin_lock(&dev_priv->mm.active_list_lock); lists_empty = (list_empty(&dev_priv->mm.inactive_list) && list_empty(&dev_priv->mm.flushing_list) && - list_empty(&dev_priv->render_ring.active_list)); + list_empty(&dev_priv->render_ring.active_list) && + (!HAS_BSD(dev) + || list_empty(&dev_priv->bsd_ring.active_list))); spin_unlock(&dev_priv->mm.active_list_lock); BUG_ON(!lists_empty); @@ -2106,9 +2134,13 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) int ret; struct intel_ring_buffer *render_ring = &dev_priv->render_ring; + struct intel_ring_buffer *bsd_ring = &dev_priv->bsd_ring; for (;;) { i915_gem_retire_requests(dev, render_ring); + if (HAS_BSD(dev)) + i915_gem_retire_requests(dev, bsd_ring); + /* If there's an inactive buffer available now, grab it * and be done. */ @@ -2146,6 +2178,21 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) continue; } + if (HAS_BSD(dev) && !list_empty(&bsd_ring->request_list)) { + struct drm_i915_gem_request *request; + + request = list_first_entry(&bsd_ring->request_list, + struct drm_i915_gem_request, + list); + + ret = i915_wait_request(dev, + request->seqno, request->ring); + if (ret) + return ret; + + continue; + } + /* If we didn't have anything on the request list but there * are buffers awaiting a flush, emit one and try again. * When we wait on it, those buffers waiting for that flush @@ -3641,6 +3688,16 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", (int) args->buffers_ptr, args->buffer_count, args->batch_len); #endif + if (args->flags & I915_EXEC_BSD) { + if (!HAS_BSD(dev)) { + DRM_ERROR("execbuf with wrong flag\n"); + return -EINVAL; + } + ring = &dev_priv->bsd_ring; + } else { + ring = &dev_priv->render_ring; + } + if (args->buffer_count < 1) { DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); @@ -3694,8 +3751,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, goto pre_mutex_err; } - ring = &dev_priv->render_ring; - /* Look up object handles */ flips = 0; for (i = 0; i < args->buffer_count; i++) { @@ -3834,6 +3889,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, dev->flush_domains, &dev_priv->render_ring); + if (HAS_BSD(dev)) + (void)i915_add_request(dev, file_priv, + dev->flush_domains, + &dev_priv->bsd_ring); } } @@ -4267,6 +4326,9 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, */ i915_gem_retire_requests(dev, &dev_priv->render_ring); + if (HAS_BSD(dev)) + i915_gem_retire_requests(dev, &dev_priv->bsd_ring); + obj_priv = to_intel_bo(obj); /* Don't count being on the flushing list against the object being * done. Otherwise, a buffer left on the flushing list but not getting @@ -4433,7 +4495,9 @@ i915_gem_idle(struct drm_device *dev) mutex_lock(&dev->struct_mutex); if (dev_priv->mm.suspended || - dev_priv->render_ring.gem_object == NULL) { + (dev_priv->render_ring.gem_object == NULL) || + (HAS_BSD(dev) && + dev_priv->bsd_ring.gem_object == NULL)) { mutex_unlock(&dev->struct_mutex); return 0; } @@ -4550,6 +4614,10 @@ i915_gem_init_ringbuffer(struct drm_device *dev) return ret; } ret = intel_init_ring_buffer(dev, &dev_priv->render_ring); + if (!ret && HAS_BSD(dev)) { + dev_priv->bsd_ring = bsd_ring; + ret = intel_init_ring_buffer(dev, &dev_priv->bsd_ring); + } return ret; } @@ -4559,6 +4627,8 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); + if (HAS_BSD(dev)) + intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring); if (HAS_PIPE_CONTROL(dev)) i915_gem_cleanup_pipe_control(dev); } @@ -4589,11 +4659,13 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, spin_lock(&dev_priv->mm.active_list_lock); BUG_ON(!list_empty(&dev_priv->render_ring.active_list)); + BUG_ON(HAS_BSD(dev) && !list_empty(&dev_priv->bsd_ring.active_list)); spin_unlock(&dev_priv->mm.active_list_lock); BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); BUG_ON(!list_empty(&dev_priv->render_ring.request_list)); + BUG_ON(HAS_BSD(dev) && !list_empty(&dev_priv->bsd_ring.request_list)); mutex_unlock(&dev->struct_mutex); drm_irq_install(dev); @@ -4638,6 +4710,10 @@ i915_gem_load(struct drm_device *dev) INIT_LIST_HEAD(&dev_priv->mm.fence_list); INIT_LIST_HEAD(&dev_priv->render_ring.active_list); INIT_LIST_HEAD(&dev_priv->render_ring.request_list); + if (HAS_BSD(dev)) { + INIT_LIST_HEAD(&dev_priv->bsd_ring.active_list); + INIT_LIST_HEAD(&dev_priv->bsd_ring.request_list); + } for (i = 0; i < 16; i++) INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); INIT_DELAYED_WORK(&dev_priv->mm.retire_work, @@ -4874,6 +4950,8 @@ i915_gpu_is_active(struct drm_device *dev) spin_lock(&dev_priv->mm.active_list_lock); lists_empty = list_empty(&dev_priv->mm.flushing_list) && list_empty(&dev_priv->render_ring.active_list); + if (HAS_BSD(dev)) + lists_empty &= list_empty(&dev_priv->bsd_ring.active_list); spin_unlock(&dev_priv->mm.active_list_lock); return !lists_empty; @@ -4920,6 +4998,9 @@ rescan: spin_unlock(&shrink_list_lock); i915_gem_retire_requests(dev, &dev_priv->render_ring); + if (HAS_BSD(dev)) + i915_gem_retire_requests(dev, &dev_priv->bsd_ring); + list_for_each_entry_safe(obj_priv, next_obj, &dev_priv->mm.inactive_list, list) { diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 8a667f1db75a..0a3a5806a12e 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -53,7 +53,7 @@ I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) /** Interrupts that we mask and unmask at runtime. */ -#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT) +#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT | I915_BSD_USER_INTERRUPT) #define I915_PIPE_VBLANK_STATUS (PIPE_START_VBLANK_INTERRUPT_STATUS |\ PIPE_VBLANK_INTERRUPT_STATUS) @@ -362,6 +362,9 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) dev_priv->hangcheck_count = 0; mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); } + if (gt_iir & GT_BSD_USER_INTERRUPT) + DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); + if (de_iir & DE_GSE) ironlake_opregion_gse_intr(dev); @@ -944,6 +947,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); } + if (HAS_BSD(dev) && (iir & I915_BSD_USER_INTERRUPT)) + DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); + if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) intel_prepare_page_flip(dev, 0); @@ -1297,7 +1303,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) /* enable kind of interrupts always enabled */ u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; - u32 render_mask = GT_PIPE_NOTIFY; + u32 render_mask = GT_PIPE_NOTIFY | GT_BSD_USER_INTERRUPT; u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; @@ -1376,6 +1382,9 @@ int i915_driver_irq_postinstall(struct drm_device *dev) DRM_INIT_WAITQUEUE(&dev_priv->render_ring.irq_queue); + if (HAS_BSD(dev)) + DRM_INIT_WAITQUEUE(&dev_priv->bsd_ring.irq_queue); + dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; if (HAS_PCH_SPLIT(dev)) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f3e39cc46f0d..784cf3c914e9 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -334,6 +334,7 @@ #define I915_DEBUG_INTERRUPT (1<<2) #define I915_USER_INTERRUPT (1<<1) #define I915_ASLE_INTERRUPT (1<<0) +#define I915_BSD_USER_INTERRUPT (1<<25) #define EIR 0x020b0 #define EMR 0x020b4 #define ESR 0x020b8 @@ -368,6 +369,17 @@ #define BB_ADDR 0x02140 /* 8 bytes */ #define GFX_FLSH_CNTL 0x02170 /* 915+ only */ +/* + * BSD (bit stream decoder instruction and interrupt control register defines + * (G4X and Ironlake only) + */ + +#define BSD_RING_TAIL 0x04030 +#define BSD_RING_HEAD 0x04034 +#define BSD_RING_START 0x04038 +#define BSD_RING_CTL 0x0403c +#define BSD_RING_ACTHD 0x04074 +#define BSD_HWS_PGA 0x04080 /* * Framebuffer compression (915+ only) @@ -2355,6 +2367,8 @@ #define GT_PIPE_NOTIFY (1 << 4) #define GT_SYNC_STATUS (1 << 2) #define GT_USER_INTERRUPT (1 << 0) +#define GT_BSD_USER_INTERRUPT (1 << 5) + #define GTISR 0x44010 #define GTIMR 0x44014 diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 5715c4d8cce9..f6b84fe8099a 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -340,6 +340,119 @@ static void render_setup_status_page(struct drm_device *dev, } +void +bsd_ring_flush(struct drm_device *dev, + struct intel_ring_buffer *ring, + u32 invalidate_domains, + u32 flush_domains) +{ + intel_ring_begin(dev, ring, 8); + intel_ring_emit(dev, ring, MI_FLUSH); + intel_ring_emit(dev, ring, MI_NOOP); + intel_ring_advance(dev, ring); +} + +static inline unsigned int bsd_ring_get_head(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + return I915_READ(BSD_RING_HEAD) & HEAD_ADDR; +} + +static inline unsigned int bsd_ring_get_tail(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + return I915_READ(BSD_RING_TAIL) & TAIL_ADDR; +} + +static inline unsigned int bsd_ring_get_active_head(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + return I915_READ(BSD_RING_ACTHD); +} + +static inline void bsd_ring_advance_ring(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + I915_WRITE(BSD_RING_TAIL, ring->tail); +} + +static int init_bsd_ring(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + return init_ring_common(dev, ring); +} + +static u32 +bsd_ring_add_request(struct drm_device *dev, + struct intel_ring_buffer *ring, + struct drm_file *file_priv, + u32 flush_domains) +{ + u32 seqno; + seqno = intel_ring_get_seqno(dev, ring); + intel_ring_begin(dev, ring, 4); + intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX); + intel_ring_emit(dev, ring, + I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + intel_ring_emit(dev, ring, seqno); + intel_ring_emit(dev, ring, MI_USER_INTERRUPT); + intel_ring_advance(dev, ring); + + DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno); + + return seqno; +} + +static void bsd_setup_status_page(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + I915_WRITE(BSD_HWS_PGA, ring->status_page.gfx_addr); + I915_READ(BSD_HWS_PGA); +} + +static void +bsd_ring_get_user_irq(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + /* do nothing */ +} +static void +bsd_ring_put_user_irq(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + /* do nothing */ +} + +static u32 +bsd_ring_get_gem_seqno(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + return intel_read_status_page(ring, I915_GEM_HWS_INDEX); +} + +static int +bsd_ring_dispatch_gem_execbuffer(struct drm_device *dev, + struct intel_ring_buffer *ring, + struct drm_i915_gem_execbuffer2 *exec, + struct drm_clip_rect *cliprects, + uint64_t exec_offset) +{ + uint32_t exec_start; + exec_start = (uint32_t) exec_offset + exec->batch_start_offset; + intel_ring_begin(dev, ring, 2); + intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START | + (2 << 6) | MI_BATCH_NON_SECURE_I965); + intel_ring_emit(dev, ring, exec_start); + intel_ring_advance(dev, ring); + return 0; +} + + static int render_ring_dispatch_gem_execbuffer(struct drm_device *dev, struct intel_ring_buffer *ring, @@ -588,6 +701,7 @@ int intel_wait_ring_buffer(struct drm_device *dev, if (master_priv->sarea_priv) master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; } + yield(); } while (!time_after(jiffies, end)); trace_i915_ring_wait_end (dev); @@ -682,3 +796,42 @@ struct intel_ring_buffer render_ring = { .status_page = {NULL, 0, NULL}, .map = {0,} }; + +/* ring buffer for bit-stream decoder */ + +struct intel_ring_buffer bsd_ring = { + .name = "bsd ring", + .regs = { + .ctl = BSD_RING_CTL, + .head = BSD_RING_HEAD, + .tail = BSD_RING_TAIL, + .start = BSD_RING_START + }, + .ring_flag = I915_EXEC_BSD, + .size = 32 * PAGE_SIZE, + .alignment = PAGE_SIZE, + .virtual_start = NULL, + .dev = NULL, + .gem_object = NULL, + .head = 0, + .tail = 0, + .space = 0, + .next_seqno = 1, + .user_irq_refcount = 0, + .irq_gem_seqno = 0, + .waiting_gem_seqno = 0, + .setup_status_page = bsd_setup_status_page, + .init = init_bsd_ring, + .get_head = bsd_ring_get_head, + .get_tail = bsd_ring_get_tail, + .get_active_head = bsd_ring_get_active_head, + .advance_ring = bsd_ring_advance_ring, + .flush = bsd_ring_flush, + .add_request = bsd_ring_add_request, + .get_gem_seqno = bsd_ring_get_gem_seqno, + .user_irq_get = bsd_ring_get_user_irq, + .user_irq_put = bsd_ring_put_user_irq, + .dispatch_gem_execbuffer = bsd_ring_dispatch_gem_execbuffer, + .status_page = {NULL, 0, NULL}, + .map = {0,} +}; -- cgit v1.2.3 From 9517a92f48b08bb02cfb616825850b82b28461cc Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 21 May 2010 09:40:45 -0700 Subject: drm/i915: add timeout to FBC disable waits FBC disable on 965 can take long enough to trigger latency checks in the kernel so be sure to timeout after a reasonable period. Fixes https://bugzilla.kernel.org/show_bug.cgi?id=15015. Tested-by: James Ettle Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_display.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b867f3c78408..36afe9409964 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1029,19 +1029,28 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) void i8xx_disable_fbc(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long timeout = jiffies + msecs_to_jiffies(1); u32 fbc_ctl; if (!I915_HAS_FBC(dev)) return; + if (!(I915_READ(FBC_CONTROL) & FBC_CTL_EN)) + return; /* Already off, just return */ + /* Disable compression */ fbc_ctl = I915_READ(FBC_CONTROL); fbc_ctl &= ~FBC_CTL_EN; I915_WRITE(FBC_CONTROL, fbc_ctl); /* Wait for compressing bit to clear */ - while (I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) - ; /* nothing */ + while (I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) { + if (time_after(jiffies, timeout)) { + DRM_DEBUG_DRIVER("FBC idle timed out\n"); + break; + } + ; /* do nothing */ + } intel_wait_for_vblank(dev); -- cgit v1.2.3 From f41275e893191eeb7a88e431d594e167adbd5234 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Mon, 24 May 2010 16:25:44 +0800 Subject: drm/i915: Convert more trace events to DEFINE_EVENT Convert i915_gem_object_clflush to DEFINE_EVENT, and save ~0.5K: text data bss dec hex filename 13204 2732 12 15948 3e4c i915_trace_points.o.orig 12668 2732 12 15412 3c34 i915_trace_points.o No change in functionality. Signed-off-by: Li Zefan Acked-by: Steven Rostedt Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_trace.h | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 9e4c45f68d6e..fab21760dd57 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -53,23 +53,6 @@ TRACE_EVENT(i915_gem_object_bind, __entry->obj, __entry->gtt_offset) ); -TRACE_EVENT(i915_gem_object_clflush, - - TP_PROTO(struct drm_gem_object *obj), - - TP_ARGS(obj), - - TP_STRUCT__entry( - __field(struct drm_gem_object *, obj) - ), - - TP_fast_assign( - __entry->obj = obj; - ), - - TP_printk("obj=%p", __entry->obj) -); - TRACE_EVENT(i915_gem_object_change_domain, TP_PROTO(struct drm_gem_object *obj, uint32_t old_read_domains, uint32_t old_write_domain), @@ -132,6 +115,13 @@ DECLARE_EVENT_CLASS(i915_gem_object, TP_printk("obj=%p", __entry->obj) ); +DEFINE_EVENT(i915_gem_object, i915_gem_object_clflush, + + TP_PROTO(struct drm_gem_object *obj), + + TP_ARGS(obj) +); + DEFINE_EVENT(i915_gem_object, i915_gem_object_unbind, TP_PROTO(struct drm_gem_object *obj), -- cgit v1.2.3 From f953c9353f5fe6e98fa7f32f51060a74d845b5f8 Mon Sep 17 00:00:00 2001 From: Daniel J Blueman Date: Mon, 17 May 2010 14:23:52 +0100 Subject: i915: fix lock imbalance on error path... While investigating Intel i5 Arrandale GPU lockups with -rc4, I noticed a lock imbalance. Signed-off-by: Daniel J Blueman Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_drv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index d40f62d36453..c072b212979c 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -370,6 +370,7 @@ int i965_reset(struct drm_device *dev, u8 flags) } } else { DRM_ERROR("Error occurred. Don't know how to reset this chip.\n"); + mutex_unlock(&dev->struct_mutex); return -ENODEV; } -- cgit v1.2.3 From 734b4157b367d66405f7dab80085d17c9c8dd3b5 Mon Sep 17 00:00:00 2001 From: Krzysztof Halasa Date: Tue, 25 May 2010 18:41:46 +0200 Subject: drm/i915: Add support for interlaced display. This doesn't change the clock limits (minimums), i.e. it won't make it output 720x576 PAL nor 720x480 NTSC, but it will work with modes like 1080i etc. (including GLX and textured Xvideo, not sure about the overlay). Tested on i915 + analog VGA, it would be worth checking if newer chips (and which ones) still support interlaced mode. Signed-off-by: Krzysztof Halasa Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_crt.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index e16ac5a28c3c..d5c130202396 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -569,7 +569,7 @@ void intel_crt_init(struct drm_device *dev) (1 << INTEL_ANALOG_CLONE_BIT) | (1 << INTEL_SDVO_LVDS_CLONE_BIT); intel_encoder->crtc_mask = (1 << 0) | (1 << 1); - connector->interlace_allowed = 0; + connector->interlace_allowed = 1; connector->doublescan_allowed = 0; drm_encoder_helper_add(&intel_encoder->enc, &intel_crt_helper_funcs); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 36afe9409964..4c7c151114f7 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2354,6 +2354,8 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, if (mode->clock * 3 > 27000 * 4) return MODE_CLOCK_HIGH; } + + drm_mode_set_crtcinfo(adjusted_mode, 0); return true; } @@ -3781,6 +3783,18 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, } } + if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { + pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; + /* the chip adds 2 halflines automatically */ + adjusted_mode->crtc_vdisplay -= 1; + adjusted_mode->crtc_vtotal -= 1; + adjusted_mode->crtc_vblank_start -= 1; + adjusted_mode->crtc_vblank_end -= 1; + adjusted_mode->crtc_vsync_end -= 1; + adjusted_mode->crtc_vsync_start -= 1; + } else + pipeconf &= ~PIPECONF_INTERLACE_W_FIELD_INDICATION; /* progressive */ + I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16)); I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | -- cgit v1.2.3 From 7a772c492fcfffae812ffca78a628e76fa57fe58 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 24 May 2010 16:46:29 -0400 Subject: drm/i915/gen4: Extra CRT hotplug paranoia Disable the CRT plug interrupt while doing the force cycle, explicitly clear any CRT interrupt we may have generated, and restore when done. Should mitigate interrupt storms from hotplug detection. Signed-off-by: Adam Jackson Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_reg.h | 1 - drivers/gpu/drm/i915/intel_crt.c | 21 ++++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 784cf3c914e9..7a726840efa7 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1067,7 +1067,6 @@ #define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2) #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) #define CRT_HOTPLUG_MASK (0x3fc) /* Bits 9-2 */ -#define CRT_FORCE_HOTPLUG_MASK 0xfffffe1f #define PORT_HOTPLUG_STAT 0x61114 #define HDMIB_HOTPLUG_INT_STATUS (1 << 29) diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index d5c130202396..22ff38455731 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -217,7 +217,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - u32 hotplug_en; + u32 hotplug_en, orig, stat; + bool ret = false; int i, tries = 0; if (HAS_PCH_SPLIT(dev)) @@ -232,8 +233,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) tries = 2; else tries = 1; - hotplug_en = I915_READ(PORT_HOTPLUG_EN); - hotplug_en &= CRT_FORCE_HOTPLUG_MASK; + hotplug_en = orig = I915_READ(PORT_HOTPLUG_EN); + hotplug_en &= CRT_HOTPLUG_MASK; hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; if (IS_G4X(dev)) @@ -255,11 +256,17 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) } while (time_after(timeout, jiffies)); } - if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) != - CRT_HOTPLUG_MONITOR_NONE) - return true; + stat = I915_READ(PORT_HOTPLUG_STAT); + if ((stat & CRT_HOTPLUG_MONITOR_MASK) != CRT_HOTPLUG_MONITOR_NONE) + ret = true; + + /* clear the interrupt we just generated, if any */ + I915_WRITE(PORT_HOTPLUG_STAT, CRT_HOTPLUG_INT_STATUS); - return false; + /* and put the bits back */ + I915_WRITE(PORT_HOTPLUG_EN, orig); + + return ret; } static bool intel_crt_detect_ddc(struct drm_encoder *encoder) -- cgit v1.2.3 From 7648fa99eb77a2e1a90b7beaa420e07d819b9c11 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 20 May 2010 14:28:11 -0700 Subject: drm/i915: add power monitoring support Add power monitoring support to the i915 driver for use by the IPS driver. Export the available power info to the IPS driver through a few new inter-driver hooks. When used together, the IPS driver and this patch can significantly increase graphics performance on Ironlake class chips. Signed-off-by: Jesse Barnes [anholt: Fixed 32-bit compile. stupid obfuscating div_u64()] Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_debugfs.c | 56 +++- drivers/gpu/drm/i915/i915_dma.c | 533 ++++++++++++++++++++++++++++++++++- drivers/gpu/drm/i915/i915_drv.h | 20 +- drivers/gpu/drm/i915/i915_irq.c | 28 +- drivers/gpu/drm/i915/i915_reg.h | 41 +++ drivers/gpu/drm/i915/intel_display.c | 147 ++++++++-- 6 files changed, 772 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index c864858d5064..eb11e1e049cb 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -491,11 +491,14 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; u16 rgvswctl = I915_READ16(MEMSWCTL); + u16 rgvstat = I915_READ16(MEMSTAT_ILK); - seq_printf(m, "Last command: 0x%01x\n", (rgvswctl >> 13) & 0x3); - seq_printf(m, "Command status: %d\n", (rgvswctl >> 12) & 1); - seq_printf(m, "P%d DELAY 0x%02x\n", (rgvswctl >> 8) & 0xf, - rgvswctl & 0x3f); + seq_printf(m, "Requested P-state: %d\n", (rgvswctl >> 8) & 0xf); + seq_printf(m, "Requested VID: %d\n", rgvswctl & 0x3f); + seq_printf(m, "Current VID: %d\n", (rgvstat & MEMSTAT_VID_MASK) >> + MEMSTAT_VID_SHIFT); + seq_printf(m, "Current P-state: %d\n", + (rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT); return 0; } @@ -510,7 +513,8 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused) for (i = 0; i < 16; i++) { delayfreq = I915_READ(PXVFREQ_BASE + i * 4); - seq_printf(m, "P%02dVIDFREQ: 0x%08x\n", i, delayfreq); + seq_printf(m, "P%02dVIDFREQ: 0x%08x (VID: %d)\n", i, delayfreq, + (delayfreq & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT); } return 0; @@ -543,6 +547,8 @@ static int i915_drpc_info(struct seq_file *m, void *unused) struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; u32 rgvmodectl = I915_READ(MEMMODECTL); + u32 rstdbyctl = I915_READ(MCHBAR_RENDER_STANDBY); + u16 crstandvid = I915_READ16(CRSTANDVID); seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ? "yes" : "no"); @@ -557,9 +563,13 @@ static int i915_drpc_info(struct seq_file *m, void *unused) rgvmodectl & MEMMODE_RCLK_GATE ? "yes" : "no"); seq_printf(m, "Starting frequency: P%d\n", (rgvmodectl & MEMMODE_FSTART_MASK) >> MEMMODE_FSTART_SHIFT); - seq_printf(m, "Max frequency: P%d\n", + seq_printf(m, "Max P-state: P%d\n", (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT); - seq_printf(m, "Min frequency: P%d\n", (rgvmodectl & MEMMODE_FMIN_MASK)); + seq_printf(m, "Min P-state: P%d\n", (rgvmodectl & MEMMODE_FMIN_MASK)); + seq_printf(m, "RS1 VID: %d\n", (crstandvid & 0x3f)); + seq_printf(m, "RS2 VID: %d\n", ((crstandvid >> 8) & 0x3f)); + seq_printf(m, "Render standby enabled: %s\n", + (rstdbyctl & RCX_SW_EXIT) ? "no" : "yes"); return 0; } @@ -623,6 +633,36 @@ static int i915_sr_status(struct seq_file *m, void *unused) return 0; } +static int i915_emon_status(struct seq_file *m, void *unused) +{ + struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_device *dev = node->minor->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + unsigned long temp, chipset, gfx; + + temp = i915_mch_val(dev_priv); + chipset = i915_chipset_val(dev_priv); + gfx = i915_gfx_val(dev_priv); + + seq_printf(m, "GMCH temp: %ld\n", temp); + seq_printf(m, "Chipset power: %ld\n", chipset); + seq_printf(m, "GFX power: %ld\n", gfx); + seq_printf(m, "Total power: %ld\n", chipset + gfx); + + return 0; +} + +static int i915_gfxec(struct seq_file *m, void *unused) +{ + struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_device *dev = node->minor->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + + seq_printf(m, "GFXEC: %ld\n", (unsigned long)I915_READ(0x112f4)); + + return 0; +} + static int i915_wedged_open(struct inode *inode, struct file *filp) @@ -745,6 +785,8 @@ static struct drm_info_list i915_debugfs_list[] = { {"i915_delayfreq_table", i915_delayfreq_table, 0}, {"i915_inttoext_table", i915_inttoext_table, 0}, {"i915_drpc_info", i915_drpc_info, 0}, + {"i915_emon_status", i915_emon_status, 0}, + {"i915_gfxec", i915_gfxec, 0}, {"i915_fbc_status", i915_fbc_status, 0}, {"i915_sr_status", i915_sr_status, 0}, }; diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1dbed700800e..12e92f2cc3a7 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1458,14 +1458,11 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master) master->driver_priv = NULL; } -static void i915_get_mem_freq(struct drm_device *dev) +static void i915_pineview_get_mem_freq(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; u32 tmp; - if (!IS_PINEVIEW(dev)) - return; - tmp = I915_READ(CLKCFG); switch (tmp & CLKCFG_FSB_MASK) { @@ -1496,6 +1493,519 @@ static void i915_get_mem_freq(struct drm_device *dev) } } +static void i915_ironlake_get_mem_freq(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + u16 ddrpll, csipll; + + ddrpll = I915_READ16(DDRMPLL1); + csipll = I915_READ16(CSIPLL0); + + switch (ddrpll & 0xff) { + case 0xc: + dev_priv->mem_freq = 800; + break; + case 0x10: + dev_priv->mem_freq = 1066; + break; + case 0x14: + dev_priv->mem_freq = 1333; + break; + case 0x18: + dev_priv->mem_freq = 1600; + break; + default: + DRM_DEBUG_DRIVER("unknown memory frequency 0x%02x\n", + ddrpll & 0xff); + dev_priv->mem_freq = 0; + break; + } + + dev_priv->r_t = dev_priv->mem_freq; + + switch (csipll & 0x3ff) { + case 0x00c: + dev_priv->fsb_freq = 3200; + break; + case 0x00e: + dev_priv->fsb_freq = 3733; + break; + case 0x010: + dev_priv->fsb_freq = 4266; + break; + case 0x012: + dev_priv->fsb_freq = 4800; + break; + case 0x014: + dev_priv->fsb_freq = 5333; + break; + case 0x016: + dev_priv->fsb_freq = 5866; + break; + case 0x018: + dev_priv->fsb_freq = 6400; + break; + default: + DRM_DEBUG_DRIVER("unknown fsb frequency 0x%04x\n", + csipll & 0x3ff); + dev_priv->fsb_freq = 0; + break; + } + + if (dev_priv->fsb_freq == 3200) { + dev_priv->c_m = 0; + } else if (dev_priv->fsb_freq > 3200 && dev_priv->fsb_freq <= 4800) { + dev_priv->c_m = 1; + } else { + dev_priv->c_m = 2; + } +} + +struct v_table { + u8 vid; + unsigned long vd; /* in .1 mil */ + unsigned long vm; /* in .1 mil */ + u8 pvid; +}; + +static struct v_table v_table[] = { + { 0, 16125, 15000, 0x7f, }, + { 1, 16000, 14875, 0x7e, }, + { 2, 15875, 14750, 0x7d, }, + { 3, 15750, 14625, 0x7c, }, + { 4, 15625, 14500, 0x7b, }, + { 5, 15500, 14375, 0x7a, }, + { 6, 15375, 14250, 0x79, }, + { 7, 15250, 14125, 0x78, }, + { 8, 15125, 14000, 0x77, }, + { 9, 15000, 13875, 0x76, }, + { 10, 14875, 13750, 0x75, }, + { 11, 14750, 13625, 0x74, }, + { 12, 14625, 13500, 0x73, }, + { 13, 14500, 13375, 0x72, }, + { 14, 14375, 13250, 0x71, }, + { 15, 14250, 13125, 0x70, }, + { 16, 14125, 13000, 0x6f, }, + { 17, 14000, 12875, 0x6e, }, + { 18, 13875, 12750, 0x6d, }, + { 19, 13750, 12625, 0x6c, }, + { 20, 13625, 12500, 0x6b, }, + { 21, 13500, 12375, 0x6a, }, + { 22, 13375, 12250, 0x69, }, + { 23, 13250, 12125, 0x68, }, + { 24, 13125, 12000, 0x67, }, + { 25, 13000, 11875, 0x66, }, + { 26, 12875, 11750, 0x65, }, + { 27, 12750, 11625, 0x64, }, + { 28, 12625, 11500, 0x63, }, + { 29, 12500, 11375, 0x62, }, + { 30, 12375, 11250, 0x61, }, + { 31, 12250, 11125, 0x60, }, + { 32, 12125, 11000, 0x5f, }, + { 33, 12000, 10875, 0x5e, }, + { 34, 11875, 10750, 0x5d, }, + { 35, 11750, 10625, 0x5c, }, + { 36, 11625, 10500, 0x5b, }, + { 37, 11500, 10375, 0x5a, }, + { 38, 11375, 10250, 0x59, }, + { 39, 11250, 10125, 0x58, }, + { 40, 11125, 10000, 0x57, }, + { 41, 11000, 9875, 0x56, }, + { 42, 10875, 9750, 0x55, }, + { 43, 10750, 9625, 0x54, }, + { 44, 10625, 9500, 0x53, }, + { 45, 10500, 9375, 0x52, }, + { 46, 10375, 9250, 0x51, }, + { 47, 10250, 9125, 0x50, }, + { 48, 10125, 9000, 0x4f, }, + { 49, 10000, 8875, 0x4e, }, + { 50, 9875, 8750, 0x4d, }, + { 51, 9750, 8625, 0x4c, }, + { 52, 9625, 8500, 0x4b, }, + { 53, 9500, 8375, 0x4a, }, + { 54, 9375, 8250, 0x49, }, + { 55, 9250, 8125, 0x48, }, + { 56, 9125, 8000, 0x47, }, + { 57, 9000, 7875, 0x46, }, + { 58, 8875, 7750, 0x45, }, + { 59, 8750, 7625, 0x44, }, + { 60, 8625, 7500, 0x43, }, + { 61, 8500, 7375, 0x42, }, + { 62, 8375, 7250, 0x41, }, + { 63, 8250, 7125, 0x40, }, + { 64, 8125, 7000, 0x3f, }, + { 65, 8000, 6875, 0x3e, }, + { 66, 7875, 6750, 0x3d, }, + { 67, 7750, 6625, 0x3c, }, + { 68, 7625, 6500, 0x3b, }, + { 69, 7500, 6375, 0x3a, }, + { 70, 7375, 6250, 0x39, }, + { 71, 7250, 6125, 0x38, }, + { 72, 7125, 6000, 0x37, }, + { 73, 7000, 5875, 0x36, }, + { 74, 6875, 5750, 0x35, }, + { 75, 6750, 5625, 0x34, }, + { 76, 6625, 5500, 0x33, }, + { 77, 6500, 5375, 0x32, }, + { 78, 6375, 5250, 0x31, }, + { 79, 6250, 5125, 0x30, }, + { 80, 6125, 5000, 0x2f, }, + { 81, 6000, 4875, 0x2e, }, + { 82, 5875, 4750, 0x2d, }, + { 83, 5750, 4625, 0x2c, }, + { 84, 5625, 4500, 0x2b, }, + { 85, 5500, 4375, 0x2a, }, + { 86, 5375, 4250, 0x29, }, + { 87, 5250, 4125, 0x28, }, + { 88, 5125, 4000, 0x27, }, + { 89, 5000, 3875, 0x26, }, + { 90, 4875, 3750, 0x25, }, + { 91, 4750, 3625, 0x24, }, + { 92, 4625, 3500, 0x23, }, + { 93, 4500, 3375, 0x22, }, + { 94, 4375, 3250, 0x21, }, + { 95, 4250, 3125, 0x20, }, + { 96, 4125, 3000, 0x1f, }, + { 97, 4125, 3000, 0x1e, }, + { 98, 4125, 3000, 0x1d, }, + { 99, 4125, 3000, 0x1c, }, + { 100, 4125, 3000, 0x1b, }, + { 101, 4125, 3000, 0x1a, }, + { 102, 4125, 3000, 0x19, }, + { 103, 4125, 3000, 0x18, }, + { 104, 4125, 3000, 0x17, }, + { 105, 4125, 3000, 0x16, }, + { 106, 4125, 3000, 0x15, }, + { 107, 4125, 3000, 0x14, }, + { 108, 4125, 3000, 0x13, }, + { 109, 4125, 3000, 0x12, }, + { 110, 4125, 3000, 0x11, }, + { 111, 4125, 3000, 0x10, }, + { 112, 4125, 3000, 0x0f, }, + { 113, 4125, 3000, 0x0e, }, + { 114, 4125, 3000, 0x0d, }, + { 115, 4125, 3000, 0x0c, }, + { 116, 4125, 3000, 0x0b, }, + { 117, 4125, 3000, 0x0a, }, + { 118, 4125, 3000, 0x09, }, + { 119, 4125, 3000, 0x08, }, + { 120, 1125, 0, 0x07, }, + { 121, 1000, 0, 0x06, }, + { 122, 875, 0, 0x05, }, + { 123, 750, 0, 0x04, }, + { 124, 625, 0, 0x03, }, + { 125, 500, 0, 0x02, }, + { 126, 375, 0, 0x01, }, + { 127, 0, 0, 0x00, }, +}; + +struct cparams { + int i; + int t; + int m; + int c; +}; + +static struct cparams cparams[] = { + { 1, 1333, 301, 28664 }, + { 1, 1066, 294, 24460 }, + { 1, 800, 294, 25192 }, + { 0, 1333, 276, 27605 }, + { 0, 1066, 276, 27605 }, + { 0, 800, 231, 23784 }, +}; + +unsigned long i915_chipset_val(struct drm_i915_private *dev_priv) +{ + u64 total_count, diff, ret; + u32 count1, count2, count3, m = 0, c = 0; + unsigned long now = jiffies_to_msecs(jiffies), diff1; + int i; + + diff1 = now - dev_priv->last_time1; + + count1 = I915_READ(DMIEC); + count2 = I915_READ(DDREC); + count3 = I915_READ(CSIEC); + + total_count = count1 + count2 + count3; + + /* FIXME: handle per-counter overflow */ + if (total_count < dev_priv->last_count1) { + diff = ~0UL - dev_priv->last_count1; + diff += total_count; + } else { + diff = total_count - dev_priv->last_count1; + } + + for (i = 0; i < ARRAY_SIZE(cparams); i++) { + if (cparams[i].i == dev_priv->c_m && + cparams[i].t == dev_priv->r_t) { + m = cparams[i].m; + c = cparams[i].c; + break; + } + } + + div_u64(diff, diff1); + ret = ((m * diff) + c); + div_u64(ret, 10); + + dev_priv->last_count1 = total_count; + dev_priv->last_time1 = now; + + return ret; +} + +unsigned long i915_mch_val(struct drm_i915_private *dev_priv) +{ + unsigned long m, x, b; + u32 tsfs; + + tsfs = I915_READ(TSFS); + + m = ((tsfs & TSFS_SLOPE_MASK) >> TSFS_SLOPE_SHIFT); + x = I915_READ8(TR1); + + b = tsfs & TSFS_INTR_MASK; + + return ((m * x) / 127) - b; +} + +static unsigned long pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid) +{ + unsigned long val = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(v_table); i++) { + if (v_table[i].pvid == pxvid) { + if (IS_MOBILE(dev_priv->dev)) + val = v_table[i].vm; + else + val = v_table[i].vd; + } + } + + return val; +} + +void i915_update_gfx_val(struct drm_i915_private *dev_priv) +{ + struct timespec now, diff1; + u64 diff; + unsigned long diffms; + u32 count; + + getrawmonotonic(&now); + diff1 = timespec_sub(now, dev_priv->last_time2); + + /* Don't divide by 0 */ + diffms = diff1.tv_sec * 1000 + diff1.tv_nsec / 1000000; + if (!diffms) + return; + + count = I915_READ(GFXEC); + + if (count < dev_priv->last_count2) { + diff = ~0UL - dev_priv->last_count2; + diff += count; + } else { + diff = count - dev_priv->last_count2; + } + + dev_priv->last_count2 = count; + dev_priv->last_time2 = now; + + /* More magic constants... */ + diff = diff * 1181; + div_u64(diff, diffms * 10); + dev_priv->gfx_power = diff; +} + +unsigned long i915_gfx_val(struct drm_i915_private *dev_priv) +{ + unsigned long t, corr, state1, corr2, state2; + u32 pxvid, ext_v; + + pxvid = I915_READ(PXVFREQ_BASE + (dev_priv->cur_delay * 4)); + pxvid = (pxvid >> 24) & 0x7f; + ext_v = pvid_to_extvid(dev_priv, pxvid); + + state1 = ext_v; + + t = i915_mch_val(dev_priv); + + /* Revel in the empirically derived constants */ + + /* Correction factor in 1/100000 units */ + if (t > 80) + corr = ((t * 2349) + 135940); + else if (t >= 50) + corr = ((t * 964) + 29317); + else /* < 50 */ + corr = ((t * 301) + 1004); + + corr = corr * ((150142 * state1) / 10000 - 78642); + corr /= 100000; + corr2 = (corr * dev_priv->corr); + + state2 = (corr2 * state1) / 10000; + state2 /= 100; /* convert to mW */ + + i915_update_gfx_val(dev_priv); + + return dev_priv->gfx_power + state2; +} + +/* Global for IPS driver to get at the current i915 device */ +static struct drm_i915_private *i915_mch_dev; +/* + * Lock protecting IPS related data structures + * - i915_mch_dev + * - dev_priv->max_delay + * - dev_priv->min_delay + * - dev_priv->fmax + * - dev_priv->gpu_busy + */ +DEFINE_SPINLOCK(mchdev_lock); + +/** + * i915_read_mch_val - return value for IPS use + * + * Calculate and return a value for the IPS driver to use when deciding whether + * we have thermal and power headroom to increase CPU or GPU power budget. + */ +unsigned long i915_read_mch_val(void) +{ + struct drm_i915_private *dev_priv; + unsigned long chipset_val, graphics_val, ret = 0; + + spin_lock(&mchdev_lock); + if (!i915_mch_dev) + goto out_unlock; + dev_priv = i915_mch_dev; + + chipset_val = i915_chipset_val(dev_priv); + graphics_val = i915_gfx_val(dev_priv); + + ret = chipset_val + graphics_val; + +out_unlock: + spin_unlock(&mchdev_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(i915_read_mch_val); + +/** + * i915_gpu_raise - raise GPU frequency limit + * + * Raise the limit; IPS indicates we have thermal headroom. + */ +bool i915_gpu_raise(void) +{ + struct drm_i915_private *dev_priv; + bool ret = true; + + spin_lock(&mchdev_lock); + if (!i915_mch_dev) { + ret = false; + goto out_unlock; + } + dev_priv = i915_mch_dev; + + if (dev_priv->max_delay > dev_priv->fmax) + dev_priv->max_delay--; + +out_unlock: + spin_unlock(&mchdev_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(i915_gpu_raise); + +/** + * i915_gpu_lower - lower GPU frequency limit + * + * IPS indicates we're close to a thermal limit, so throttle back the GPU + * frequency maximum. + */ +bool i915_gpu_lower(void) +{ + struct drm_i915_private *dev_priv; + bool ret = true; + + spin_lock(&mchdev_lock); + if (!i915_mch_dev) { + ret = false; + goto out_unlock; + } + dev_priv = i915_mch_dev; + + if (dev_priv->max_delay < dev_priv->min_delay) + dev_priv->max_delay++; + +out_unlock: + spin_unlock(&mchdev_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(i915_gpu_lower); + +/** + * i915_gpu_busy - indicate GPU business to IPS + * + * Tell the IPS driver whether or not the GPU is busy. + */ +bool i915_gpu_busy(void) +{ + struct drm_i915_private *dev_priv; + bool ret = false; + + spin_lock(&mchdev_lock); + if (!i915_mch_dev) + goto out_unlock; + dev_priv = i915_mch_dev; + + ret = dev_priv->busy; + +out_unlock: + spin_unlock(&mchdev_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(i915_gpu_busy); + +/** + * i915_gpu_turbo_disable - disable graphics turbo + * + * Disable graphics turbo by resetting the max frequency and setting the + * current frequency to the default. + */ +bool i915_gpu_turbo_disable(void) +{ + struct drm_i915_private *dev_priv; + bool ret = true; + + spin_lock(&mchdev_lock); + if (!i915_mch_dev) { + ret = false; + goto out_unlock; + } + dev_priv = i915_mch_dev; + + dev_priv->max_delay = dev_priv->fstart; + + if (!ironlake_set_drps(dev_priv->dev, dev_priv->fstart)) + ret = false; + +out_unlock: + spin_unlock(&mchdev_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable); + /** * i915_driver_load - setup chip and create an initial config * @dev: DRM device @@ -1616,7 +2126,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto out_workqueue_free; } - i915_get_mem_freq(dev); + if (IS_PINEVIEW(dev)) + i915_pineview_get_mem_freq(dev); + else if (IS_IRONLAKE(dev)) + i915_ironlake_get_mem_freq(dev); /* On the 945G/GM, the chipset reports the MSI capability on the * integrated graphics even though the support isn't actually there @@ -1662,6 +2175,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, (unsigned long) dev); + + spin_lock(&mchdev_lock); + i915_mch_dev = dev_priv; + dev_priv->mchdev_lock = &mchdev_lock; + spin_unlock(&mchdev_lock); + return 0; out_workqueue_free: @@ -1683,6 +2202,10 @@ int i915_driver_unload(struct drm_device *dev) i915_destroy_error_state(dev); + spin_lock(&mchdev_lock); + i915_mch_dev = NULL; + spin_unlock(&mchdev_lock); + destroy_workqueue(dev_priv->wq); del_timer_sync(&dev_priv->hangcheck_timer); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6bc0fc080f2b..91b3a1c20ef8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -619,6 +619,18 @@ typedef struct drm_i915_private { u8 cur_delay; u8 min_delay; u8 max_delay; + u8 fmax; + u8 fstart; + + u64 last_count1; + unsigned long last_time1; + u64 last_count2; + struct timespec last_time2; + unsigned long gfx_power; + int c_m; + int r_t; + u8 corr; + spinlock_t *mchdev_lock; enum no_fbc_reason no_fbc_reason; @@ -802,6 +814,11 @@ extern int i915_emit_box(struct drm_device *dev, struct drm_clip_rect *boxes, int i, int DR1, int DR4); extern int i965_reset(struct drm_device *dev, u8 flags); +extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv); +extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv); +extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv); +extern void i915_update_gfx_val(struct drm_i915_private *dev_priv); + /* i915_irq.c */ void i915_hangcheck_elapsed(unsigned long data); @@ -1005,7 +1022,7 @@ extern void g4x_disable_fbc(struct drm_device *dev); extern void intel_disable_fbc(struct drm_device *dev); extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval); extern bool intel_fbc_enabled(struct drm_device *dev); - +extern bool ironlake_set_drps(struct drm_device *dev, u8 val); extern void intel_detect_pch (struct drm_device *dev); extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); @@ -1030,6 +1047,7 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); #define I915_WRITE64(reg, val) writeq(val, dev_priv->regs + (reg)) #define I915_READ64(reg) readq(dev_priv->regs + (reg)) #define POSTING_READ(reg) (void)I915_READ(reg) +#define POSTING_READ16(reg) (void)I915_READ16(reg) #define I915_VERBOSE 0 diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 0a3a5806a12e..b5dba4795f6f 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -278,10 +278,9 @@ static void i915_handle_rps_change(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; u32 busy_up, busy_down, max_avg, min_avg; - u16 rgvswctl; u8 new_delay = dev_priv->cur_delay; - I915_WRITE(MEMINTRSTS, I915_READ(MEMINTRSTS) & ~MEMINT_EVAL_CHG); + I915_WRITE16(MEMINTRSTS, MEMINT_EVAL_CHG); busy_up = I915_READ(RCPREVBSYTUPAVG); busy_down = I915_READ(RCPREVBSYTDNAVG); max_avg = I915_READ(RCBMAXAVG); @@ -300,27 +299,8 @@ static void i915_handle_rps_change(struct drm_device *dev) new_delay = dev_priv->min_delay; } - DRM_DEBUG("rps change requested: %d -> %d\n", - dev_priv->cur_delay, new_delay); - - rgvswctl = I915_READ(MEMSWCTL); - if (rgvswctl & MEMCTL_CMD_STS) { - DRM_ERROR("gpu busy, RCS change rejected\n"); - return; /* still busy with another command */ - } - - /* Program the new state */ - rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | - (new_delay << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM; - I915_WRITE(MEMSWCTL, rgvswctl); - POSTING_READ(MEMSWCTL); - - rgvswctl |= MEMCTL_CMD_STS; - I915_WRITE(MEMSWCTL, rgvswctl); - - dev_priv->cur_delay = new_delay; - - DRM_DEBUG("rps changed\n"); + if (ironlake_set_drps(dev, new_delay)) + dev_priv->cur_delay = new_delay; return; } @@ -392,7 +372,7 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) } if (de_iir & DE_PCU_EVENT) { - I915_WRITE(MEMINTRSTS, I915_READ(MEMINTRSTS)); + I915_WRITE16(MEMINTRSTS, I915_READ(MEMINTRSTS)); i915_handle_rps_change(dev); } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 7a726840efa7..df7224de0aed 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -838,6 +838,12 @@ #define CLKCFG_MEM_800 (3 << 4) #define CLKCFG_MEM_MASK (7 << 4) +#define TR1 0x11006 +#define TSFS 0x11020 +#define TSFS_SLOPE_MASK 0x0000ff00 +#define TSFS_SLOPE_SHIFT 8 +#define TSFS_INTR_MASK 0x000000ff + #define CRSTANDVID 0x11100 #define PXVFREQ_BASE 0x11110 /* P[0-15]VIDFREQ (0x1114c) (Ironlake) */ #define PXVFREQ_PX_MASK 0x7f000000 @@ -976,6 +982,41 @@ #define MEMSTAT_SRC_CTL_STDBY 3 #define RCPREVBSYTUPAVG 0x113b8 #define RCPREVBSYTDNAVG 0x113bc +#define SDEW 0x1124c +#define CSIEW0 0x11250 +#define CSIEW1 0x11254 +#define CSIEW2 0x11258 +#define PEW 0x1125c +#define DEW 0x11270 +#define MCHAFE 0x112c0 +#define CSIEC 0x112e0 +#define DMIEC 0x112e4 +#define DDREC 0x112e8 +#define PEG0EC 0x112ec +#define PEG1EC 0x112f0 +#define GFXEC 0x112f4 +#define RPPREVBSYTUPAVG 0x113b8 +#define RPPREVBSYTDNAVG 0x113bc +#define ECR 0x11600 +#define ECR_GPFE (1<<31) +#define ECR_IMONE (1<<30) +#define ECR_CAP_MASK 0x0000001f /* Event range, 0-31 */ +#define OGW0 0x11608 +#define OGW1 0x1160c +#define EG0 0x11610 +#define EG1 0x11614 +#define EG2 0x11618 +#define EG3 0x1161c +#define EG4 0x11620 +#define EG5 0x11624 +#define EG6 0x11628 +#define EG7 0x1162c +#define PXW 0x11664 +#define PXWL 0x11680 +#define LCFUSE02 0x116c0 +#define LCFUSE_HIV_MASK 0x000000ff +#define CSIPLL0 0x12c10 +#define DDRMPLL1 0X12c20 #define PEG_BAND_GAP_DATA 0x14d68 /* diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4c7c151114f7..e94d1db35364 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4459,6 +4459,8 @@ static void intel_idle_update(struct work_struct *work) mutex_lock(&dev->struct_mutex); + i915_update_gfx_val(dev_priv); + if (IS_I945G(dev) || IS_I945GM(dev)) { DRM_DEBUG_DRIVER("enable memory self refresh on 945\n"); I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN); @@ -5045,10 +5047,32 @@ err_unref: return NULL; } +bool ironlake_set_drps(struct drm_device *dev, u8 val) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + u16 rgvswctl; + + rgvswctl = I915_READ16(MEMSWCTL); + if (rgvswctl & MEMCTL_CMD_STS) { + DRM_DEBUG("gpu busy, RCS change rejected\n"); + return false; /* still busy with another command */ + } + + rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | + (val << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM; + I915_WRITE16(MEMSWCTL, rgvswctl); + POSTING_READ16(MEMSWCTL); + + rgvswctl |= MEMCTL_CMD_STS; + I915_WRITE16(MEMSWCTL, rgvswctl); + + return true; +} + void ironlake_enable_drps(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - u32 rgvmodectl = I915_READ(MEMMODECTL), rgvswctl; + u32 rgvmodectl = I915_READ(MEMMODECTL); u8 fmax, fmin, fstart, vstart; int i = 0; @@ -5067,13 +5091,21 @@ void ironlake_enable_drps(struct drm_device *dev) fmin = (rgvmodectl & MEMMODE_FMIN_MASK); fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >> MEMMODE_FSTART_SHIFT; + fstart = fmax; + vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT; - dev_priv->max_delay = fstart; /* can't go to fmax w/o IPS */ + dev_priv->fmax = fstart; /* IPS callback will increase this */ + dev_priv->fstart = fstart; + + dev_priv->max_delay = fmax; dev_priv->min_delay = fmin; dev_priv->cur_delay = fstart; + DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n", fmax, fmin, + fstart); + I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN); /* @@ -5095,20 +5127,19 @@ void ironlake_enable_drps(struct drm_device *dev) } msleep(1); - rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | - (fstart << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM; - I915_WRITE(MEMSWCTL, rgvswctl); - POSTING_READ(MEMSWCTL); + ironlake_set_drps(dev, fstart); - rgvswctl |= MEMCTL_CMD_STS; - I915_WRITE(MEMSWCTL, rgvswctl); + dev_priv->last_count1 = I915_READ(0x112e4) + I915_READ(0x112e8) + + I915_READ(0x112e0); + dev_priv->last_time1 = jiffies_to_msecs(jiffies); + dev_priv->last_count2 = I915_READ(0x112f4); + getrawmonotonic(&dev_priv->last_time2); } void ironlake_disable_drps(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - u32 rgvswctl; - u8 fstart; + u16 rgvswctl = I915_READ16(MEMSWCTL); /* Ack interrupts, disable EFC interrupt */ I915_WRITE(MEMINTREN, I915_READ(MEMINTREN) & ~MEMINT_EVAL_CHG_EN); @@ -5118,11 +5149,7 @@ void ironlake_disable_drps(struct drm_device *dev) I915_WRITE(DEIMR, I915_READ(DEIMR) | DE_PCU_EVENT); /* Go back to the starting frequency */ - fstart = (I915_READ(MEMMODECTL) & MEMMODE_FSTART_MASK) >> - MEMMODE_FSTART_SHIFT; - rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | - (fstart << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM; - I915_WRITE(MEMSWCTL, rgvswctl); + ironlake_set_drps(dev, dev_priv->fstart); msleep(1); rgvswctl |= MEMCTL_CMD_STS; I915_WRITE(MEMSWCTL, rgvswctl); @@ -5130,6 +5157,92 @@ void ironlake_disable_drps(struct drm_device *dev) } +static unsigned long intel_pxfreq(u32 vidfreq) +{ + unsigned long freq; + int div = (vidfreq & 0x3f0000) >> 16; + int post = (vidfreq & 0x3000) >> 12; + int pre = (vidfreq & 0x7); + + if (!pre) + return 0; + + freq = ((div * 133333) / ((1<dev_private; + u32 lcfuse; + u8 pxw[16]; + int i; + + /* Disable to program */ + I915_WRITE(ECR, 0); + POSTING_READ(ECR); + + /* Program energy weights for various events */ + I915_WRITE(SDEW, 0x15040d00); + I915_WRITE(CSIEW0, 0x007f0000); + I915_WRITE(CSIEW1, 0x1e220004); + I915_WRITE(CSIEW2, 0x04000004); + + for (i = 0; i < 5; i++) + I915_WRITE(PEW + (i * 4), 0); + for (i = 0; i < 3; i++) + I915_WRITE(DEW + (i * 4), 0); + + /* Program P-state weights to account for frequency power adjustment */ + for (i = 0; i < 16; i++) { + u32 pxvidfreq = I915_READ(PXVFREQ_BASE + (i * 4)); + unsigned long freq = intel_pxfreq(pxvidfreq); + unsigned long vid = (pxvidfreq & PXVFREQ_PX_MASK) >> + PXVFREQ_PX_SHIFT; + unsigned long val; + + val = vid * vid; + val *= (freq / 1000); + val *= 255; + val /= (127*127*900); + if (val > 0xff) + DRM_ERROR("bad pxval: %ld\n", val); + pxw[i] = val; + } + /* Render standby states get 0 weight */ + pxw[14] = 0; + pxw[15] = 0; + + for (i = 0; i < 4; i++) { + u32 val = (pxw[i*4] << 24) | (pxw[(i*4)+1] << 16) | + (pxw[(i*4)+2] << 8) | (pxw[(i*4)+3]); + I915_WRITE(PXW + (i * 4), val); + } + + /* Adjust magic regs to magic values (more experimental results) */ + I915_WRITE(OGW0, 0); + I915_WRITE(OGW1, 0); + I915_WRITE(EG0, 0x00007f00); + I915_WRITE(EG1, 0x0000000e); + I915_WRITE(EG2, 0x000e0000); + I915_WRITE(EG3, 0x68000300); + I915_WRITE(EG4, 0x42000000); + I915_WRITE(EG5, 0x00140031); + I915_WRITE(EG6, 0); + I915_WRITE(EG7, 0); + + for (i = 0; i < 8; i++) + I915_WRITE(PXWL + (i * 4), 0); + + /* Enable PMON + select events */ + I915_WRITE(ECR, 0x80000019); + + lcfuse = I915_READ(LCFUSE02); + + dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK); +} + void intel_init_clock_gating(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -5376,8 +5489,10 @@ void intel_modeset_init(struct drm_device *dev) intel_init_clock_gating(dev); - if (IS_IRONLAKE_M(dev)) + if (IS_IRONLAKE_M(dev)) { ironlake_enable_drps(dev); + intel_init_emon(dev); + } INIT_WORK(&dev_priv->idle_work, intel_idle_update); setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, -- cgit v1.2.3 From 9a7e8492d17394a81d5534abf90b5b2ada7ea3c0 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 20 May 2010 10:33:46 +0200 Subject: drm/i915: Storage class should be before const qualifier The C99 specification states in section 6.11.5: The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature. Signed-off-by: Tobias Klauser Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_drv.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index c072b212979c..423dc90c1e20 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -60,95 +60,95 @@ extern int intel_agp_enabled; .subdevice = PCI_ANY_ID, \ .driver_data = (unsigned long) info } -const static struct intel_device_info intel_i830_info = { +static const struct intel_device_info intel_i830_info = { .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, }; -const static struct intel_device_info intel_845g_info = { +static const struct intel_device_info intel_845g_info = { .is_i8xx = 1, }; -const static struct intel_device_info intel_i85x_info = { +static const struct intel_device_info intel_i85x_info = { .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1, .cursor_needs_physical = 1, }; -const static struct intel_device_info intel_i865g_info = { +static const struct intel_device_info intel_i865g_info = { .is_i8xx = 1, }; -const static struct intel_device_info intel_i915g_info = { +static const struct intel_device_info intel_i915g_info = { .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1, }; -const static struct intel_device_info intel_i915gm_info = { +static const struct intel_device_info intel_i915gm_info = { .is_i9xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, }; -const static struct intel_device_info intel_i945g_info = { +static const struct intel_device_info intel_i945g_info = { .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1, }; -const static struct intel_device_info intel_i945gm_info = { +static const struct intel_device_info intel_i945gm_info = { .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_hotplug = 1, .cursor_needs_physical = 1, }; -const static struct intel_device_info intel_i965g_info = { +static const struct intel_device_info intel_i965g_info = { .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1, }; -const static struct intel_device_info intel_i965gm_info = { +static const struct intel_device_info intel_i965gm_info = { .is_i965g = 1, .is_mobile = 1, .is_i965gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1, }; -const static struct intel_device_info intel_g33_info = { +static const struct intel_device_info intel_g33_info = { .is_g33 = 1, .is_i9xx = 1, .need_gfx_hws = 1, .has_hotplug = 1, }; -const static struct intel_device_info intel_g45_info = { +static const struct intel_device_info intel_g45_info = { .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1, .has_pipe_cxsr = 1, .has_hotplug = 1, }; -const static struct intel_device_info intel_gm45_info = { +static const struct intel_device_info intel_gm45_info = { .is_i965g = 1, .is_mobile = 1, .is_g4x = 1, .is_i9xx = 1, .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, .has_pipe_cxsr = 1, .has_hotplug = 1, }; -const static struct intel_device_info intel_pineview_info = { +static const struct intel_device_info intel_pineview_info = { .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1, .need_gfx_hws = 1, .has_hotplug = 1, }; -const static struct intel_device_info intel_ironlake_d_info = { +static const struct intel_device_info intel_ironlake_d_info = { .is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, .has_pipe_cxsr = 1, .has_hotplug = 1, }; -const static struct intel_device_info intel_ironlake_m_info = { +static const struct intel_device_info intel_ironlake_m_info = { .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, .has_rc6 = 1, .has_hotplug = 1, }; -const static struct intel_device_info intel_sandybridge_d_info = { +static const struct intel_device_info intel_sandybridge_d_info = { .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, .has_hotplug = 1, .is_gen6 = 1, }; -const static struct intel_device_info intel_sandybridge_m_info = { +static const struct intel_device_info intel_sandybridge_m_info = { .is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, .need_gfx_hws = 1, .has_hotplug = 1, .is_gen6 = 1, }; -const static struct pci_device_id pciidlist[] = { +static const struct pci_device_id pciidlist[] = { INTEL_VGA_DEVICE(0x3577, &intel_i830_info), INTEL_VGA_DEVICE(0x2562, &intel_845g_info), INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), -- cgit v1.2.3 From f1befe71fa7a79ab733011b045639d8d809924ad Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 18 May 2010 12:24:51 +0100 Subject: agp/intel: Restrict GTT mapping to valid range on i915 and i945 References: Bug 15733 - Crash when accessing nonexistent GTT entries in i915 https://bugzilla.kernel.org/show_bug.cgi?id=15733 On G33 and above, the size of the GTT space is determined by the GMCH control register. Prior to this revision, the size is determined by the size of the aperture. So we must careful to map and fill the appropriate range depending on chipset. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt --- drivers/char/agp/intel-gtt.c | 46 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index e8ea6825822c..9344216183a4 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -1059,7 +1059,7 @@ static void intel_i9xx_setup_flush(void) } } -static int intel_i915_configure(void) +static int intel_i9xx_configure(void) { struct aper_size_info_fixed *current_size; u32 temp; @@ -1207,6 +1207,38 @@ static int intel_i9xx_fetch_size(void) return 0; } +static int intel_i915_get_gtt_size(void) +{ + int size; + + if (IS_G33) { + u16 gmch_ctrl; + + /* G33's GTT size defined in gmch_ctrl */ + pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); + switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) { + case G33_PGETBL_SIZE_1M: + size = 1024; + break; + case G33_PGETBL_SIZE_2M: + size = 2048; + break; + default: + dev_info(&agp_bridge->dev->dev, + "unknown page table size 0x%x, assuming 512KB\n", + (gmch_ctrl & G33_PGETBL_SIZE_MASK)); + size = 512; + } + } else { + /* On previous hardware, the GTT size was just what was + * required to map the aperture. + */ + size = agp_bridge->driver->fetch_size(); + } + + return KB(size); +} + /* The intel i915 automatically initializes the agp aperture during POST. * Use the memory already set aside for in the GTT. */ @@ -1216,7 +1248,7 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) struct aper_size_info_fixed *size; int num_entries; u32 temp, temp2; - int gtt_map_size = 256 * 1024; + int gtt_map_size; size = agp_bridge->current_size; page_order = size->page_order; @@ -1226,8 +1258,8 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); pci_read_config_dword(intel_private.pcidev, I915_PTEADDR, &temp2); - if (IS_G33) - gtt_map_size = 1024 * 1024; /* 1M on G33 */ + gtt_map_size = intel_i915_get_gtt_size(); + intel_private.gtt = ioremap(temp2, gtt_map_size); if (!intel_private.gtt) return -ENOMEM; @@ -1422,7 +1454,7 @@ static const struct agp_bridge_driver intel_915_driver = { .size_type = FIXED_APER_SIZE, .num_aperture_sizes = 4, .needs_scratch_page = true, - .configure = intel_i915_configure, + .configure = intel_i9xx_configure, .fetch_size = intel_i9xx_fetch_size, .cleanup = intel_i915_cleanup, .mask_memory = intel_i810_mask_memory, @@ -1455,7 +1487,7 @@ static const struct agp_bridge_driver intel_i965_driver = { .size_type = FIXED_APER_SIZE, .num_aperture_sizes = 4, .needs_scratch_page = true, - .configure = intel_i915_configure, + .configure = intel_i9xx_configure, .fetch_size = intel_i9xx_fetch_size, .cleanup = intel_i915_cleanup, .mask_memory = intel_i965_mask_memory, @@ -1488,7 +1520,7 @@ static const struct agp_bridge_driver intel_g33_driver = { .size_type = FIXED_APER_SIZE, .num_aperture_sizes = 4, .needs_scratch_page = true, - .configure = intel_i915_configure, + .configure = intel_i9xx_configure, .fetch_size = intel_i9xx_fetch_size, .cleanup = intel_i915_cleanup, .mask_memory = intel_i965_mask_memory, -- cgit v1.2.3 From 9908ff736adf261e749b4887486a32ffa209304c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 15 May 2010 09:57:03 +0100 Subject: drm/i915: Kill dangerous pending-flip debugging We can, by virtue of a vblank interrupt firing in the middle of setting up the unpin work (i.e. after we set the unpin_work field and before we write to the ringbuffer) enter intel_finish_page_flip() prior to receiving the pending flip notification. Therefore we can expect to hit intel_finish_page_flip() under normal circumstances without a pending flip and even without installing the pending_flip_obj. This is exacerbated by aperture thrashing whilst binding the framebuffer References: Bug 28079 - "glresize" causes kernel panic in intel_finish_page_flip. https://bugs.freedesktop.org/show_bug.cgi?id=28079 Reported-by: Nick Bowler Signed-off-by: Chris Wilson Cc: Jesse Barnes Cc: stable@kernel.org Reviewed-by: Jesse Barnes Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_display.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e94d1db35364..f946332612ec 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4589,12 +4589,6 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe) spin_lock_irqsave(&dev->event_lock, flags); work = intel_crtc->unpin_work; if (work == NULL || !work->pending) { - if (work && !work->pending) { - obj_priv = to_intel_bo(work->pending_flip_obj); - DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n", - obj_priv, - atomic_read(&obj_priv->pending_flip)); - } spin_unlock_irqrestore(&dev->event_lock, flags); return; } -- cgit v1.2.3 From 9962c9252e46eda7058067cbe73bdf1ed74b0d37 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Thu, 13 May 2010 14:45:42 -0400 Subject: drm/i915/dp: Only enable enhanced framing if the sink supports it DisplayPort spec v1.1a, Table 2-52. Signed-off-by: Adam Jackson Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_dp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 6b1c9a27c27a..6eed9a2006d7 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -675,10 +675,9 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, dp_priv->link_configuration[1] = dp_priv->lane_count; /* - * Check for DPCD version > 1.1, - * enable enahanced frame stuff in that case + * Check for DPCD version > 1.1 and enhanced framing support */ - if (dp_priv->dpcd[0] >= 0x11) { + if (dp_priv->dpcd[0] >= 0x11 && (dp_priv->dpcd[2] & DP_ENHANCED_FRAME_CAP)) { dp_priv->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; dp_priv->DP |= DP_ENHANCED_FRAMING; } -- cgit v1.2.3 From a7de64e540d2017a8e44dec1ca9d88a509aa7e05 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Thu, 13 May 2010 14:45:43 -0400 Subject: drm/i915/dp: Add DPCD data to debug output Signed-off-by: Adam Jackson Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_dp.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 6eed9a2006d7..0a11c657c949 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1207,6 +1207,8 @@ ironlake_dp_detect(struct drm_connector *connector) if (dp_priv->dpcd[0] != 0) status = connector_status_connected; } + DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", dp_priv->dpcd[0], + dp_priv->dpcd[1], dp_priv->dpcd[2], dp_priv->dpcd[3]); return status; } -- cgit v1.2.3 From 778c35444f7bbb8f1816d40ada650e19c5da9c02 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 13 May 2010 11:49:44 +0200 Subject: drm/i915: combine all small integers into one single bitfield This saves a whooping 7 dwords. Zero functional changes. Because some of the refcounts are rather tightly calculated, I've put BUG_ONs in the code to check for overflows. Signed-off-by: Daniel Vetter Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_drv.h | 75 +++++++++++++++++++++++++++-------------- drivers/gpu/drm/i915/i915_gem.c | 5 +++ 2 files changed, 54 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 91b3a1c20ef8..cccf8019f65a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -658,19 +658,64 @@ struct drm_i915_gem_object { * (has pending rendering), and is not set if it's on inactive (ready * to be unbound). */ - int active; + unsigned int active : 1; /** * This is set if the object has been written to since last bound * to the GTT */ - int dirty; + unsigned int dirty : 1; + + /** + * Fence register bits (if any) for this object. Will be set + * as needed when mapped into the GTT. + * Protected by dev->struct_mutex. + * + * Size: 4 bits for 16 fences + sign (for FENCE_REG_NONE) + */ + int fence_reg : 5; + + /** + * Used for checking the object doesn't appear more than once + * in an execbuffer object list. + */ + unsigned int in_execbuffer : 1; + + /** + * Advice: are the backing pages purgeable? + */ + unsigned int madv : 2; + + /** + * Refcount for the pages array. With the current locking scheme, there + * are at most two concurrent users: Binding a bo to the gtt and + * pwrite/pread using physical addresses. So two bits for a maximum + * of two users are enough. + */ + unsigned int pages_refcount : 2; +#define DRM_I915_GEM_OBJECT_MAX_PAGES_REFCOUNT 0x3 + + /** + * Current tiling mode for the object. + */ + unsigned int tiling_mode : 2; + + /** How many users have pinned this object in GTT space. The following + * users can each hold at most one reference: pwrite/pread, pin_ioctl + * (via user_pin_count), execbuffer (objects are not allowed multiple + * times for the same batchbuffer), and the framebuffer code. When + * switching/pageflipping, the framebuffer code has at most two buffers + * pinned per crtc. + * + * In the worst case this is 1 + 1 + 1 + 2*2 = 7. That would fit into 3 + * bits with absolutely no headroom. So use 4 bits. */ + int pin_count : 4; +#define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf /** AGP memory structure for our GTT binding. */ DRM_AGP_MEM *agp_mem; struct page **pages; - int pages_refcount; /** * Current offset of the object in GTT space. @@ -687,21 +732,10 @@ struct drm_i915_gem_object { */ uint64_t mmap_offset; - /** - * Fence register bits (if any) for this object. Will be set - * as needed when mapped into the GTT. - * Protected by dev->struct_mutex. - */ - int fence_reg; - - /** How many users have pinned this object in GTT space */ - int pin_count; - /** Breadcrumb of last rendering to the buffer. */ uint32_t last_rendering_seqno; - /** Current tiling mode for the object. */ - uint32_t tiling_mode; + /** Current tiling stride for the object, if it's tiled. */ uint32_t stride; /** Record of address bit 17 of each page at last unbind. */ @@ -723,17 +757,6 @@ struct drm_i915_gem_object { /** for phy allocated objects */ struct drm_i915_gem_phys_object *phys_obj; - /** - * Used for checking the object doesn't appear more than once - * in an execbuffer object list. - */ - int in_execbuffer; - - /** - * Advice: are the backing pages purgeable? - */ - int madv; - /** * Number of crtcs where this object is currently the fb, but * will be page flipped away on the next vblank. When it diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c51495f15718..bf703551343a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2247,6 +2247,9 @@ i915_gem_object_get_pages(struct drm_gem_object *obj, struct inode *inode; struct page *page; + BUG_ON(obj_priv->pages_refcount + == DRM_I915_GEM_OBJECT_MAX_PAGES_REFCOUNT); + if (obj_priv->pages_refcount++ != 0) return 0; @@ -4156,6 +4159,8 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int ret; + BUG_ON(obj_priv->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT); + i915_verify_inactive(dev, __FILE__, __LINE__); if (obj_priv->gtt_space == NULL) { ret = i915_gem_object_bind_to_gtt(obj, alignment); -- cgit v1.2.3 From 467b200da78c56036e58850a7f27902937d506f7 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Wed, 12 May 2010 11:02:14 +0800 Subject: drm/i915: Fix HDMI mode select for Cougarpoint PCH For real HDMI sink, CPT HDMI port has to set 'HDMI' mode flag in order to make HDMI audio work correctly. This is required patch for drm/i915 to enable HDMI audio on CPT PCH, ALSA patch is at http://mailman.alsa-project.org/pipermail/alsa-devel/2010-May/027601.html Tested-by: Fengguang Wu Signed-off-by: Zhenyu Wang Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_reg.h | 3 +++ drivers/gpu/drm/i915/intel_hdmi.c | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index df7224de0aed..881fbe9a17f2 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2744,6 +2744,9 @@ #define SDVO_ENCODING (0) #define TMDS_ENCODING (2 << 10) #define NULL_PACKET_VSYNC_ENABLE (1 << 9) +/* CPT */ +#define HDMI_MODE_SELECT (1 << 9) +#define DVI_MODE_SELECT (0) #define SDVOB_BORDER_ENABLE (1 << 7) #define AUDIO_ENABLE (1 << 6) #define VSYNC_ACTIVE_HIGH (1 << 4) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 65727f0a79a3..83bd764b000e 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -59,8 +59,11 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH; - if (hdmi_priv->has_hdmi_sink) + if (hdmi_priv->has_hdmi_sink) { sdvox |= SDVO_AUDIO_ENABLE; + if (HAS_PCH_CPT(dev)) + sdvox |= HDMI_MODE_SELECT; + } if (intel_crtc->pipe == 1) { if (HAS_PCH_CPT(dev)) -- cgit v1.2.3 From 90a78e8f60f679b0937011314a6cda39c7449d1d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 7 May 2010 10:40:09 +0200 Subject: i915/intel_sdvo: remove unneeded null check The "connector" variable is used as the cursor in a list_for_each_entry() and it's always non-null so we don't need to check it. Signed-off-by: Dan Carpenter Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_sdvo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index aba72c489a2f..76993ac16cc1 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1479,7 +1479,7 @@ intel_find_analog_connector(struct drm_device *dev) intel_encoder = enc_to_intel_encoder(encoder); if (intel_encoder->type == INTEL_OUTPUT_ANALOG) { list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector && encoder == intel_attached_encoder(connector)) + if (encoder == intel_attached_encoder(connector)) return connector; } } -- cgit v1.2.3 From d8201ab6514f8dc1a0ccfac52c688d80976a425a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 7 May 2010 10:39:00 +0200 Subject: i915: remove unneeded null checks The "encoder" variable can never be null because it is used as loop cursor in a list_for_each_entry() loop. Signed-off-by: Dan Carpenter Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_dp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 0a11c657c949..49b54f05d3cf 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -576,7 +576,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, struct intel_encoder *intel_encoder; struct intel_dp_priv *dp_priv; - if (!encoder || encoder->crtc != crtc) + if (encoder->crtc != crtc) continue; intel_encoder = enc_to_intel_encoder(encoder); @@ -1353,7 +1353,7 @@ intel_trans_dp_port_sel (struct drm_crtc *crtc) struct intel_encoder *intel_encoder = NULL; list_for_each_entry(encoder, &mode_config->encoder_list, head) { - if (!encoder || encoder->crtc != crtc) + if (encoder->crtc != crtc) continue; intel_encoder = enc_to_intel_encoder(encoder); -- cgit v1.2.3 From 9553426372eef71c849499fb1d232f4b0577c0f9 Mon Sep 17 00:00:00 2001 From: Li Peng Date: Tue, 18 May 2010 18:58:44 +0800 Subject: drm/i915: Add CxSR support on Pineview DDR3 Pineview with DDR3 memory has different latencies to enable CxSR. This patch updates CxSR latency table to add Pineview DDR3 latency configuration. It also adds one flag "is_ddr3" for checking DDR3 setting in MCHBAR. Cc: Shaohua Li Cc: Zhao Yakui Signed-off-by: Li Peng Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_dma.c | 4 ++ drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_reg.h | 4 ++ drivers/gpu/drm/i915/intel_display.c | 72 ++++++++++++++++++++++-------------- 4 files changed, 53 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 12e92f2cc3a7..a5f401664845 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1491,6 +1491,10 @@ static void i915_pineview_get_mem_freq(struct drm_device *dev) dev_priv->mem_freq = 800; break; } + + /* detect pineview DDR3 setting */ + tmp = I915_READ(CSHRDDR3CTL); + dev_priv->is_ddr3 = (tmp & CSHRDDR3CTL_DDR3) ? 1 : 0; } static void i915_ironlake_get_mem_freq(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index cccf8019f65a..e6b4cab6565f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -326,7 +326,7 @@ typedef struct drm_i915_private { int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ int num_fence_regs; /* 8 on pre-965, 16 otherwise */ - unsigned int fsb_freq, mem_freq; + unsigned int fsb_freq, mem_freq, is_ddr3; spinlock_t error_lock; struct drm_i915_error_state *first_error; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 881fbe9a17f2..af7b10853e33 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -817,6 +817,10 @@ #define DCC_CHANNEL_XOR_DISABLE (1 << 10) #define DCC_CHANNEL_XOR_BIT_17 (1 << 9) +/** Pineview MCH register contains DDR3 setting */ +#define CSHRDDR3CTL 0x101a8 +#define CSHRDDR3CTL_DDR3 (1 << 2) + /** 965 MCH register controlling DRAM channel configuration */ #define C0DRB3 0x10206 #define C1DRB3 0x10606 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f946332612ec..cfac4dd1d483 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2640,6 +2640,7 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz, struct cxsr_latency { int is_desktop; + int is_ddr3; unsigned long fsb_freq; unsigned long mem_freq; unsigned long display_sr; @@ -2649,33 +2650,45 @@ struct cxsr_latency { }; static struct cxsr_latency cxsr_latency_table[] = { - {1, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ - {1, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ - {1, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ - - {1, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */ - {1, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */ - {1, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */ - - {1, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */ - {1, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */ - {1, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */ - - {0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */ - {0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */ - {0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */ - - {0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */ - {0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */ - {0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */ - - {0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */ - {0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */ - {0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */ + {1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ + {1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ + {1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ + {1, 1, 800, 667, 6420, 36420, 6873, 36873}, /* DDR3-667 SC */ + {1, 1, 800, 800, 5902, 35902, 6318, 36318}, /* DDR3-800 SC */ + + {1, 0, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */ + {1, 0, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */ + {1, 0, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */ + {1, 1, 667, 667, 6438, 36438, 6911, 36911}, /* DDR3-667 SC */ + {1, 1, 667, 800, 5941, 35941, 6377, 36377}, /* DDR3-800 SC */ + + {1, 0, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */ + {1, 0, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */ + {1, 0, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */ + {1, 1, 400, 667, 6509, 36509, 7062, 37062}, /* DDR3-667 SC */ + {1, 1, 400, 800, 5985, 35985, 6501, 36501}, /* DDR3-800 SC */ + + {0, 0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */ + {0, 0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */ + {0, 0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */ + {0, 1, 800, 667, 6476, 36476, 6955, 36955}, /* DDR3-667 SC */ + {0, 1, 800, 800, 5958, 35958, 6400, 36400}, /* DDR3-800 SC */ + + {0, 0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */ + {0, 0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */ + {0, 0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */ + {0, 1, 667, 667, 6494, 36494, 6993, 36993}, /* DDR3-667 SC */ + {0, 1, 667, 800, 5998, 35998, 6460, 36460}, /* DDR3-800 SC */ + + {0, 0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */ + {0, 0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */ + {0, 0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */ + {0, 1, 400, 667, 6566, 36566, 7145, 37145}, /* DDR3-667 SC */ + {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */ }; -static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb, - int mem) +static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int is_ddr3, + int fsb, int mem) { int i; struct cxsr_latency *latency; @@ -2686,6 +2699,7 @@ static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb, for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) { latency = &cxsr_latency_table[i]; if (is_desktop == latency->is_desktop && + is_ddr3 == latency->is_ddr3 && fsb == latency->fsb_freq && mem == latency->mem_freq) return latency; } @@ -2800,8 +2814,8 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, struct cxsr_latency *latency; int sr_clock; - latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->fsb_freq, - dev_priv->mem_freq); + latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, + dev_priv->fsb_freq, dev_priv->mem_freq); if (!latency) { DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); pineview_disable_cxsr(dev); @@ -5406,11 +5420,13 @@ static void intel_init_display(struct drm_device *dev) dev_priv->display.update_wm = NULL; } else if (IS_PINEVIEW(dev)) { if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev), + dev_priv->is_ddr3, dev_priv->fsb_freq, dev_priv->mem_freq)) { DRM_INFO("failed to find known CxSR latency " - "(found fsb freq %d, mem freq %d), " + "(found ddr%s fsb freq %d, mem freq %d), " "disabling CxSR\n", + (dev_priv->is_ddr3 == 1) ? "3": "2", dev_priv->fsb_freq, dev_priv->mem_freq); /* Disable CxSR and never update its watermark again */ pineview_disable_cxsr(dev); -- cgit v1.2.3 From a65a3e82b5b5f8f70cc0d51498441585d5b381f1 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Wed, 26 May 2010 23:27:06 +0200 Subject: [S390] cio: remove stsch Since 8821d24cd261aede9b0436cd3252b17a60ccc33a we no longer use the plain stsch inline function but the one which can handle exceptions. Remove the unused function. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/ioasm.h | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/cio/ioasm.h b/drivers/s390/cio/ioasm.h index 759262792633..fac06155773f 100644 --- a/drivers/s390/cio/ioasm.h +++ b/drivers/s390/cio/ioasm.h @@ -23,21 +23,6 @@ struct tpi_info { * Some S390 specific IO instructions as inline */ -static inline int stsch(struct subchannel_id schid, struct schib *addr) -{ - register struct subchannel_id reg1 asm ("1") = schid; - int ccode; - - asm volatile( - " stsch 0(%3)\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode), "=m" (*addr) - : "d" (reg1), "a" (addr) - : "cc"); - return ccode; -} - static inline int stsch_err(struct subchannel_id schid, struct schib *addr) { register struct subchannel_id reg1 asm ("1") = schid; -- cgit v1.2.3 From c560d105a197464603247bf55962fc7f23c8cb62 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Wed, 26 May 2010 23:27:07 +0200 Subject: [S390] ccwgroup: add locking around drvdata access Several processes may concurrently try to create a group device from the same ccw_device(s). Add locking arround the drvdata access to prevent race conditions. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/ccwgroup.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 5f97ea2ee6b1..97b25d68e3e7 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -123,8 +123,10 @@ ccwgroup_release (struct device *dev) for (i = 0; i < gdev->count; i++) { if (gdev->cdev[i]) { + spin_lock_irq(gdev->cdev[i]->ccwlock); if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev) dev_set_drvdata(&gdev->cdev[i]->dev, NULL); + spin_unlock_irq(gdev->cdev[i]->ccwlock); put_device(&gdev->cdev[i]->dev); } } @@ -262,11 +264,14 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id, goto error; } /* Don't allow a device to belong to more than one group. */ + spin_lock_irq(gdev->cdev[i]->ccwlock); if (dev_get_drvdata(&gdev->cdev[i]->dev)) { + spin_unlock_irq(gdev->cdev[i]->ccwlock); rc = -EINVAL; goto error; } dev_set_drvdata(&gdev->cdev[i]->dev, gdev); + spin_unlock_irq(gdev->cdev[i]->ccwlock); } /* Check for sufficient number of bus ids. */ if (i < num_devices && !curr_buf) { @@ -303,8 +308,10 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id, error: for (i = 0; i < num_devices; i++) if (gdev->cdev[i]) { + spin_lock_irq(gdev->cdev[i]->ccwlock); if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev) dev_set_drvdata(&gdev->cdev[i]->dev, NULL); + spin_unlock_irq(gdev->cdev[i]->ccwlock); put_device(&gdev->cdev[i]->dev); gdev->cdev[i] = NULL; } -- cgit v1.2.3 From 094f2100d6bb16ef0c4f82167cc55173ca22ee93 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Wed, 26 May 2010 23:27:08 +0200 Subject: [S390] cio: unit check handling during internal I/O Send unit checks that occur during internal I/O to the device driver and react according to its return code. Signed-off-by: Michael Ernst Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/ccwdev.h | 10 ++++++++++ drivers/s390/cio/ccwreq.c | 15 +++++++++++++++ 2 files changed, 25 insertions(+) (limited to 'drivers') diff --git a/arch/s390/include/asm/ccwdev.h b/arch/s390/include/asm/ccwdev.h index f4bd346a52d3..1c0030f9b890 100644 --- a/arch/s390/include/asm/ccwdev.h +++ b/arch/s390/include/asm/ccwdev.h @@ -91,6 +91,14 @@ struct ccw_device { void (*handler) (struct ccw_device *, unsigned long, struct irb *); }; +/* + * Possible CIO actions triggered by the unit check handler. + */ +enum uc_todo { + UC_TODO_RETRY, + UC_TODO_RETRY_ON_NEW_PATH, + UC_TODO_STOP +}; /** * struct ccw driver - device driver for channel attached devices @@ -107,6 +115,7 @@ struct ccw_device { * @freeze: callback for freezing during hibernation snapshotting * @thaw: undo work done in @freeze * @restore: callback for restoring after hibernation + * @uc_handler: callback for unit check handler * @driver: embedded device driver structure * @name: device driver name */ @@ -124,6 +133,7 @@ struct ccw_driver { int (*freeze)(struct ccw_device *); int (*thaw) (struct ccw_device *); int (*restore)(struct ccw_device *); + enum uc_todo (*uc_handler) (struct ccw_device *, struct irb *); struct device_driver driver; char *name; }; diff --git a/drivers/s390/cio/ccwreq.c b/drivers/s390/cio/ccwreq.c index 37df42af05ec..7f206ed44fdf 100644 --- a/drivers/s390/cio/ccwreq.c +++ b/drivers/s390/cio/ccwreq.c @@ -159,6 +159,7 @@ static enum io_status ccwreq_status(struct ccw_device *cdev, struct irb *lcirb) { struct irb *irb = &cdev->private->irb; struct cmd_scsw *scsw = &irb->scsw.cmd; + enum uc_todo todo; /* Perform BASIC SENSE if needed. */ if (ccw_device_accumulate_and_sense(cdev, lcirb)) @@ -178,6 +179,20 @@ static enum io_status ccwreq_status(struct ccw_device *cdev, struct irb *lcirb) /* Check for command reject. */ if (irb->ecw[0] & SNS0_CMD_REJECT) return IO_REJECTED; + /* Ask the driver what to do */ + if (cdev->drv && cdev->drv->uc_handler) { + todo = cdev->drv->uc_handler(cdev, lcirb); + switch (todo) { + case UC_TODO_RETRY: + return IO_STATUS_ERROR; + case UC_TODO_RETRY_ON_NEW_PATH: + return IO_PATH_ERROR; + case UC_TODO_STOP: + return IO_REJECTED; + default: + return IO_STATUS_ERROR; + } + } /* Assume that unexpected SENSE data implies an error. */ return IO_STATUS_ERROR; } -- cgit v1.2.3 From a23ed009a726feeafdbabeaf5f0bde1a3f04d121 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Wed, 26 May 2010 23:27:09 +0200 Subject: [S390] dasd: unit check handling during internal cio I/O React on unit checks during cio internal I/O. Handle as unsolicited interrupt and advice cio to retry. Signed-off-by: Stefan Haberland Signed-off-by: Martin Schwidefsky --- drivers/s390/block/dasd.c | 23 +++++++++++++++++++++++ drivers/s390/block/dasd_eckd.c | 1 + drivers/s390/block/dasd_int.h | 1 + 3 files changed, 25 insertions(+) (limited to 'drivers') diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 0e86247d791e..33975e922d65 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -1186,6 +1186,29 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, dasd_schedule_device_bh(device); } +enum uc_todo dasd_generic_uc_handler(struct ccw_device *cdev, struct irb *irb) +{ + struct dasd_device *device; + + device = dasd_device_from_cdev_locked(cdev); + + if (IS_ERR(device)) + goto out; + if (test_bit(DASD_FLAG_OFFLINE, &device->flags) || + device->state != device->target || + !device->discipline->handle_unsolicited_interrupt){ + dasd_put_device(device); + goto out; + } + + dasd_device_clear_timer(device); + device->discipline->handle_unsolicited_interrupt(device, irb); + dasd_put_device(device); +out: + return UC_TODO_RETRY; +} +EXPORT_SYMBOL_GPL(dasd_generic_uc_handler); + /* * If we have an error on a dasd_block layer request then we cancel * and return all further requests from the same dasd_block as well. diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 5b1cd8d6e971..ab84da5592e8 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -3436,6 +3436,7 @@ static struct ccw_driver dasd_eckd_driver = { .freeze = dasd_generic_pm_freeze, .thaw = dasd_generic_restore_device, .restore = dasd_generic_restore_device, + .uc_handler = dasd_generic_uc_handler, }; /* diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 32fac186ba3f..49b431d135e0 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h @@ -617,6 +617,7 @@ int dasd_generic_notify(struct ccw_device *, int); void dasd_generic_handle_state_change(struct dasd_device *); int dasd_generic_pm_freeze(struct ccw_device *); int dasd_generic_restore_device(struct ccw_device *); +enum uc_todo dasd_generic_uc_handler(struct ccw_device *, struct irb *); int dasd_generic_read_dev_chars(struct dasd_device *, int, void *, int); char *dasd_get_sense(struct irb *); -- cgit v1.2.3 From e20f9c64c79e2282f9eb531509181965ec8f0a92 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 26 May 2010 14:51:06 -0700 Subject: drm/i915: Clean up leftover bits from hws move to ring structure. Fixes /debug/dri/0/i915_gem_interrupt output for status page. Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_debugfs.c | 6 +++--- drivers/gpu/drm/i915/i915_dma.c | 7 +++---- drivers/gpu/drm/i915/i915_drv.h | 3 --- 3 files changed, 6 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index eb11e1e049cb..52510ad8b25d 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -144,7 +144,7 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data) struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; - if (dev_priv->hw_status_page != NULL) { + if (dev_priv->render_ring.status_page.page_addr != NULL) { seq_printf(m, "Current sequence: %d\n", i915_get_gem_seqno(dev, &dev_priv->render_ring)); } else { @@ -196,7 +196,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) } seq_printf(m, "Interrupts received: %d\n", atomic_read(&dev_priv->irq_received)); - if (dev_priv->hw_status_page != NULL) { + if (dev_priv->render_ring.status_page.page_addr != NULL) { seq_printf(m, "Current sequence: %d\n", i915_get_gem_seqno(dev, &dev_priv->render_ring)); } else { @@ -252,7 +252,7 @@ static int i915_hws_info(struct seq_file *m, void *data) int i; volatile u32 *hws; - hws = (volatile u32 *)dev_priv->hw_status_page; + hws = (volatile u32 *)dev_priv->render_ring.status_page.page_addr; if (hws == NULL) return 0; diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a5f401664845..6577798d3441 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -84,7 +84,6 @@ static void i915_free_hws(struct drm_device *dev) if (dev_priv->render_ring.status_page.gfx_addr) { dev_priv->render_ring.status_page.gfx_addr = 0; - dev_priv->status_gfx_addr = 0; drm_core_ioremapfree(&dev_priv->hws_map, dev); } @@ -828,7 +827,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, drm_core_ioremap_wc(&dev_priv->hws_map, dev); if (dev_priv->hws_map.handle == NULL) { i915_dma_cleanup(dev); - dev_priv->status_gfx_addr = 0; + ring->status_page.gfx_addr = 0; DRM_ERROR("can not ioremap virtual address for" " G33 hw status page\n"); return -ENOMEM; @@ -838,9 +837,9 @@ static int i915_set_status_page(struct drm_device *dev, void *data, I915_WRITE(HWS_PGA, ring->status_page.gfx_addr); DRM_DEBUG_DRIVER("load hws HWS_PGA with gfx mem 0x%x\n", - dev_priv->status_gfx_addr); + ring->status_page.gfx_addr); DRM_DEBUG_DRIVER("load hws at %p\n", - dev_priv->hw_status_page); + ring->status_page.page_addr); return 0; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e6b4cab6565f..9ed8ecd95801 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -238,14 +238,11 @@ typedef struct drm_i915_private { struct intel_ring_buffer bsd_ring; drm_dma_handle_t *status_page_dmah; - void *hw_status_page; void *seqno_page; dma_addr_t dma_status_page; uint32_t counter; - unsigned int status_gfx_addr; unsigned int seqno_gfx_addr; drm_local_map_t hws_map; - struct drm_gem_object *hws_obj; struct drm_gem_object *seqno_obj; struct drm_gem_object *pwrctx; -- cgit v1.2.3 From a77fcf895046664927dd6eea816602b87a1a6337 Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Wed, 26 May 2010 16:08:44 -0700 Subject: IB/qib: Use a single txselect module parameter for serdes tuning As part of the earlier patches submitted and reviewed, it was agreed to change the way serdes tuning parameters were specified to the driver. The updated patch got dropped by the linux-rdma email list so the earlier version of qib_iba7322.c ended up being used. This patch updates qib_iab7322.c to the simpler, single parameter method of setting the serdes parameters. Signed-off-by: Ralph Campbell Signed-off-by: Roland Dreier --- drivers/infiniband/hw/qib/qib_iba7322.c | 582 ++++++++++---------------------- 1 file changed, 179 insertions(+), 403 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index 2c24eab35b54..23fb9efe20a4 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c @@ -114,40 +114,18 @@ static ushort qib_singleport; module_param_named(singleport, qib_singleport, ushort, S_IRUGO); MODULE_PARM_DESC(singleport, "Use only IB port 1; more per-port buffer space"); - -/* - * Setup QMH7342 receive and transmit parameters, necessary because - * each bay, Mez connector, and IB port need different tuning, beyond - * what the switch and HCA can do automatically. - * It's expected to be done by cat'ing files to the modules file, - * rather than setting up as a module parameter. - * It's a "write-only" file, returns 0 when read back. - * The unit, port, bay (if given), and values MUST be done as a single write. - * The unit, port, and bay must precede the values to be effective. - */ -static int setup_qmh_params(const char *, struct kernel_param *); -static unsigned dummy_qmh_params; -module_param_call(qmh_serdes_setup, setup_qmh_params, param_get_uint, - &dummy_qmh_params, S_IWUSR | S_IRUGO); - -/* similarly for QME7342, but it's simpler */ -static int setup_qme_params(const char *, struct kernel_param *); -static unsigned dummy_qme_params; -module_param_call(qme_serdes_setup, setup_qme_params, param_get_uint, - &dummy_qme_params, S_IWUSR | S_IRUGO); - #define MAX_ATTEN_LEN 64 /* plenty for any real system */ /* for read back, default index is ~5m copper cable */ -static char cable_atten_list[MAX_ATTEN_LEN] = "10"; -static struct kparam_string kp_cable_atten = { - .string = cable_atten_list, +static char txselect_list[MAX_ATTEN_LEN] = "10"; +static struct kparam_string kp_txselect = { + .string = txselect_list, .maxlen = MAX_ATTEN_LEN }; -static int setup_cable_atten(const char *, struct kernel_param *); -module_param_call(cable_atten, setup_cable_atten, param_get_string, - &kp_cable_atten, S_IWUSR | S_IRUGO); -MODULE_PARM_DESC(cable_atten, \ - "cable attenuation indices for cables with invalid EEPROM"); +static int setup_txselect(const char *, struct kernel_param *); +module_param_call(txselect, setup_txselect, param_get_string, + &kp_txselect, S_IWUSR | S_IRUGO); +MODULE_PARM_DESC(txselect, \ + "Tx serdes indices (for no QSFP or invalid QSFP data)"); #define BOARD_QME7342 5 #define BOARD_QMH7342 6 @@ -574,11 +552,12 @@ struct vendor_txdds_ent { static void write_tx_serdes_param(struct qib_pportdata *, struct txdds_ent *); #define TXDDS_TABLE_SZ 16 /* number of entries per speed in onchip table */ +#define TXDDS_EXTRA_SZ 11 /* number of extra tx settings entries */ #define SERDES_CHANS 4 /* yes, it's obvious, but one less magic number */ #define H1_FORCE_VAL 8 -#define H1_FORCE_QME 1 /* may be overridden via setup_qme_params() */ -#define H1_FORCE_QMH 7 /* may be overridden via setup_qmh_params() */ +#define H1_FORCE_QME 1 /* may be overridden via setup_txselect() */ +#define H1_FORCE_QMH 7 /* may be overridden via setup_txselect() */ /* The static and dynamic registers are paired, and the pairs indexed by spd */ #define krp_static_adapt_dis(spd) (KREG_IBPORT_IDX(ADAPT_DISABLE_STATIC_SDR) \ @@ -590,15 +569,6 @@ static void write_tx_serdes_param(struct qib_pportdata *, struct txdds_ent *); #define QDR_STATIC_ADAPT_INIT 0xffffffffffULL /* up, disable H0,H1-8, LE */ #define QDR_STATIC_ADAPT_INIT_R1 0xf0ffffffffULL /* r1 up, disable H0,H1-8 */ -static const struct txdds_ent qmh_sdr_txdds = { 11, 0, 5, 6 }; -static const struct txdds_ent qmh_ddr_txdds = { 7, 0, 2, 8 }; -static const struct txdds_ent qmh_qdr_txdds = { 0, 1, 3, 10 }; - -/* this is used for unknown mez cards also */ -static const struct txdds_ent qme_sdr_txdds = { 11, 0, 4, 4 }; -static const struct txdds_ent qme_ddr_txdds = { 7, 0, 2, 7 }; -static const struct txdds_ent qme_qdr_txdds = { 0, 1, 12, 11 }; - struct qib_chippport_specific { u64 __iomem *kpregbase; u64 __iomem *cpregbase; @@ -637,12 +607,8 @@ struct qib_chippport_specific { * Per-bay per-channel rcv QMH H1 values and Tx values for QDR. * entry zero is unused, to simplify indexing */ - u16 h1_val; - u8 amp[SERDES_CHANS]; - u8 pre[SERDES_CHANS]; - u8 mainv[SERDES_CHANS]; - u8 post[SERDES_CHANS]; - u8 no_eep; /* attenuation index to use if no qsfp info */ + u8 h1_val; + u8 no_eep; /* txselect table index to use if no qsfp info */ u8 ipg_tries; u8 ibmalfusesnap; struct qib_qsfp_data qsfp_data; @@ -5360,7 +5326,13 @@ static int qib_7322_ib_updown(struct qib_pportdata *ppd, int ibup, u64 ibcs) QIBL_IB_AUTONEG_INPROG))) set_7322_ibspeed_fast(ppd, ppd->link_speed_enabled); if (!(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) { + /* unlock the Tx settings, speed may change */ + qib_write_kreg_port(ppd, krp_tx_deemph_override, + SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, + reset_tx_deemphasis_override)); qib_cancel_sends(ppd); + /* on link down, ensure sane pcs state */ + qib_7322_mini_pcs_reset(ppd); spin_lock_irqsave(&ppd->sdma_lock, flags); if (__qib_sdma_running(ppd)) __qib_sdma_process_event(ppd, @@ -5766,26 +5738,28 @@ static void qib_init_7322_qsfp(struct qib_pportdata *ppd) } /* - * called at device initialization time, and also if the cable_atten + * called at device initialization time, and also if the txselect * module parameter is changed. This is used for cables that don't * have valid QSFP EEPROMs (not present, or attenuation is zero). * We initialize to the default, then if there is a specific - * unit,port match, we use that. + * unit,port match, we use that (and set it immediately, for the + * current speed, if the link is at INIT or better). * String format is "default# unit#,port#=# ... u,p=#", separators must - * be a SPACE character. A newline terminates. + * be a SPACE character. A newline terminates. The u,p=# tuples may + * optionally have "u,p=#,#", where the final # is the H1 value * The last specific match is used (actually, all are used, but last * one is the one that winds up set); if none at all, fall back on default. */ static void set_no_qsfp_atten(struct qib_devdata *dd, int change) { char *nxt, *str; - int pidx, unit, port, deflt; + u32 pidx, unit, port, deflt, h1; unsigned long val; - int any = 0; + int any = 0, seth1; - str = cable_atten_list; + str = txselect_list; - /* default number is validated in setup_cable_atten() */ + /* default number is validated in setup_txselect() */ deflt = simple_strtoul(str, &nxt, 0); for (pidx = 0; pidx < dd->num_pports; ++pidx) dd->pport[pidx].cpspec->no_eep = deflt; @@ -5812,16 +5786,28 @@ static void set_no_qsfp_atten(struct qib_devdata *dd, int change) ; continue; } - if (val >= TXDDS_TABLE_SZ) + if (val >= TXDDS_TABLE_SZ + TXDDS_EXTRA_SZ) continue; + seth1 = 0; + h1 = 0; /* gcc thinks it might be used uninitted */ + if (*nxt == ',' && nxt[1]) { + str = ++nxt; + h1 = (u32)simple_strtoul(str, &nxt, 0); + if (nxt == str) + while (*nxt && *nxt++ != ' ') /* skip */ + ; + else + seth1 = 1; + } for (pidx = 0; dd->unit == unit && pidx < dd->num_pports; ++pidx) { - if (dd->pport[pidx].port != port || - !dd->pport[pidx].link_speed_supported) + struct qib_pportdata *ppd = &dd->pport[pidx]; + + if (ppd->port != port || !ppd->link_speed_supported) continue; - dd->pport[pidx].cpspec->no_eep = val; + ppd->cpspec->no_eep = val; /* now change the IBC and serdes, overriding generic */ - init_txdds_table(&dd->pport[pidx], 1); + init_txdds_table(ppd, 1); any++; } if (*nxt == '\n') @@ -5832,35 +5818,35 @@ static void set_no_qsfp_atten(struct qib_devdata *dd, int change) * Change the IBC and serdes, but since it's * general, don't override specific settings. */ - for (pidx = 0; pidx < dd->num_pports; ++pidx) { - if (!dd->pport[pidx].link_speed_supported) - continue; - init_txdds_table(&dd->pport[pidx], 0); - } + for (pidx = 0; pidx < dd->num_pports; ++pidx) + if (dd->pport[pidx].link_speed_supported) + init_txdds_table(&dd->pport[pidx], 0); } } -/* handle the cable_atten parameter changing */ -static int setup_cable_atten(const char *str, struct kernel_param *kp) +/* handle the txselect parameter changing */ +static int setup_txselect(const char *str, struct kernel_param *kp) { struct qib_devdata *dd; unsigned long val; char *n; if (strlen(str) >= MAX_ATTEN_LEN) { - printk(KERN_INFO QIB_DRV_NAME " cable_atten_values string " + printk(KERN_INFO QIB_DRV_NAME " txselect_values string " "too long\n"); return -ENOSPC; } val = simple_strtoul(str, &n, 0); - if (n == str || val >= TXDDS_TABLE_SZ) { + if (n == str || val >= (TXDDS_TABLE_SZ + TXDDS_EXTRA_SZ)) { printk(KERN_INFO QIB_DRV_NAME - "cable_atten_values must start with a number\n"); + "txselect_values must start with a number < %d\n", + TXDDS_TABLE_SZ + TXDDS_EXTRA_SZ); return -EINVAL; } - strcpy(cable_atten_list, str); + strcpy(txselect_list, str); list_for_each_entry(dd, &qib_dev_list, list) - set_no_qsfp_atten(dd, 1); + if (dd->deviceid == PCI_DEVICE_ID_QLOGIC_IB_7322) + set_no_qsfp_atten(dd, 1); return 0; } @@ -6261,28 +6247,17 @@ static int qib_init_7322_variables(struct qib_devdata *dd) * in adapter-specific routines. */ if (!(ppd->dd->flags & QIB_HAS_QSFP)) { - int i; - const struct txdds_ent *txdds; - if (!IS_QMH(ppd->dd) && !IS_QME(ppd->dd)) qib_devinfo(ppd->dd->pcidev, "IB%u:%u: " "Unknown mezzanine card type\n", - ppd->dd->unit, ppd->port); - txdds = IS_QMH(ppd->dd) ? &qmh_qdr_txdds : - &qme_qdr_txdds; - + dd->unit, ppd->port); + cp->h1_val = IS_QMH(dd) ? H1_FORCE_QMH : H1_FORCE_QME; /* - * set values in case link comes up - * before table is written to driver. + * Choose center value as default tx serdes setting + * until changed through module parameter. */ - cp->h1_val = IS_QMH(ppd->dd) ? H1_FORCE_QMH : - H1_FORCE_QME; - for (i = 0; i < SERDES_CHANS; i++) { - cp->amp[i] = txdds->amp; - cp->pre[i] = txdds->pre; - cp->mainv[i] = txdds->main; - cp->post[i] = txdds->post; - } + ppd->cpspec->no_eep = IS_QMH(dd) ? + TXDDS_TABLE_SZ + 2 : TXDDS_TABLE_SZ + 4; } else cp->h1_val = H1_FORCE_VAL; @@ -6299,8 +6274,7 @@ static int qib_init_7322_variables(struct qib_devdata *dd) dd->rcvhdrentsize = QIB_RCVHDR_ENTSIZE; dd->rcvhdrsize = QIB_DFLT_RCVHDRSIZE; - dd->rhf_offset = - dd->rcvhdrentsize - sizeof(u64) / sizeof(u32); + dd->rhf_offset = dd->rcvhdrentsize - sizeof(u64) / sizeof(u32); /* we always allocate at least 2048 bytes for eager buffers */ dd->rcvegrbufsize = max(mtu, 2048); @@ -7111,8 +7085,8 @@ static const struct txdds_ent txdds_ddr[TXDDS_TABLE_SZ] = { static const struct txdds_ent txdds_qdr[TXDDS_TABLE_SZ] = { /* amp, pre, main, post */ { 2, 2, 15, 6 }, /* Loopback */ - { 0, 1, 0, 7 }, /* 2 dB */ - { 0, 1, 0, 9 }, /* 3 dB */ + { 0, 1, 0, 7 }, /* 2 dB (also QMH7342) */ + { 0, 1, 0, 9 }, /* 3 dB (also QMH7342) */ { 0, 1, 0, 11 }, /* 4 dB */ { 0, 1, 0, 13 }, /* 5 dB */ { 0, 1, 0, 15 }, /* 6 dB */ @@ -7128,6 +7102,57 @@ static const struct txdds_ent txdds_qdr[TXDDS_TABLE_SZ] = { { 0, 2, 9, 15 }, /* 16 dB */ }; +/* + * extra entries for use with txselect, for indices >= TXDDS_TABLE_SZ. + * These are mostly used for mez cards going through connectors + * and backplane traces, but can be used to add other "unusual" + * table values as well. + */ +static const struct txdds_ent txdds_extra_sdr[TXDDS_EXTRA_SZ] = { + /* amp, pre, main, post */ + { 0, 0, 0, 1 }, /* QMH7342 backplane settings */ + { 0, 0, 0, 1 }, /* QMH7342 backplane settings */ + { 0, 0, 0, 2 }, /* QMH7342 backplane settings */ + { 0, 0, 0, 2 }, /* QMH7342 backplane settings */ + { 0, 0, 0, 11 }, /* QME7342 backplane settings */ + { 0, 0, 0, 11 }, /* QME7342 backplane settings */ + { 0, 0, 0, 11 }, /* QME7342 backplane settings */ + { 0, 0, 0, 11 }, /* QME7342 backplane settings */ + { 0, 0, 0, 11 }, /* QME7342 backplane settings */ + { 0, 0, 0, 11 }, /* QME7342 backplane settings */ + { 0, 0, 0, 11 }, /* QME7342 backplane settings */ +}; + +static const struct txdds_ent txdds_extra_ddr[TXDDS_EXTRA_SZ] = { + /* amp, pre, main, post */ + { 0, 0, 0, 7 }, /* QMH7342 backplane settings */ + { 0, 0, 0, 7 }, /* QMH7342 backplane settings */ + { 0, 0, 0, 8 }, /* QMH7342 backplane settings */ + { 0, 0, 0, 8 }, /* QMH7342 backplane settings */ + { 0, 0, 0, 13 }, /* QME7342 backplane settings */ + { 0, 0, 0, 13 }, /* QME7342 backplane settings */ + { 0, 0, 0, 13 }, /* QME7342 backplane settings */ + { 0, 0, 0, 13 }, /* QME7342 backplane settings */ + { 0, 0, 0, 13 }, /* QME7342 backplane settings */ + { 0, 0, 0, 13 }, /* QME7342 backplane settings */ + { 0, 0, 0, 13 }, /* QME7342 backplane settings */ +}; + +static const struct txdds_ent txdds_extra_qdr[TXDDS_EXTRA_SZ] = { + /* amp, pre, main, post */ + { 0, 1, 0, 4 }, /* QMH7342 backplane settings */ + { 0, 1, 0, 5 }, /* QMH7342 backplane settings */ + { 0, 1, 0, 6 }, /* QMH7342 backplane settings */ + { 0, 1, 0, 8 }, /* QMH7342 backplane settings */ + { 0, 1, 12, 10 }, /* QME7342 backplane setting */ + { 0, 1, 12, 11 }, /* QME7342 backplane setting */ + { 0, 1, 12, 12 }, /* QME7342 backplane setting */ + { 0, 1, 12, 14 }, /* QME7342 backplane setting */ + { 0, 1, 12, 6 }, /* QME7342 backplane setting */ + { 0, 1, 12, 7 }, /* QME7342 backplane setting */ + { 0, 1, 12, 8 }, /* QME7342 backplane setting */ +}; + static const struct txdds_ent *get_atten_table(const struct txdds_ent *txdds, unsigned atten) { @@ -7145,7 +7170,7 @@ static const struct txdds_ent *get_atten_table(const struct txdds_ent *txdds, } /* - * if override is set, the module parameter cable_atten has a value + * if override is set, the module parameter txselect has a value * for this specific port, so use it, rather than our normal mechanism. */ static void find_best_ent(struct qib_pportdata *ppd, @@ -7184,15 +7209,28 @@ static void find_best_ent(struct qib_pportdata *ppd, *ddr_dds = get_atten_table(txdds_ddr, qd->atten[0]); *qdr_dds = get_atten_table(txdds_qdr, qd->atten[1]); return; - } else { + } else if (ppd->cpspec->no_eep < TXDDS_TABLE_SZ) { /* * If we have no (or incomplete) data from the cable - * EEPROM, or no QSFP, use the module parameter value - * to index into the attentuation table. + * EEPROM, or no QSFP, or override is set, use the + * module parameter value to index into the attentuation + * table. */ - *sdr_dds = &txdds_sdr[ppd->cpspec->no_eep]; - *ddr_dds = &txdds_ddr[ppd->cpspec->no_eep]; - *qdr_dds = &txdds_qdr[ppd->cpspec->no_eep]; + idx = ppd->cpspec->no_eep; + *sdr_dds = &txdds_sdr[idx]; + *ddr_dds = &txdds_ddr[idx]; + *qdr_dds = &txdds_qdr[idx]; + } else if (ppd->cpspec->no_eep < (TXDDS_TABLE_SZ + TXDDS_EXTRA_SZ)) { + /* similar to above, but index into the "extra" table. */ + idx = ppd->cpspec->no_eep - TXDDS_TABLE_SZ; + *sdr_dds = &txdds_extra_sdr[idx]; + *ddr_dds = &txdds_extra_ddr[idx]; + *qdr_dds = &txdds_extra_qdr[idx]; + } else { + /* this shouldn't happen, it's range checked */ + *sdr_dds = txdds_sdr + qib_long_atten; + *ddr_dds = txdds_ddr + qib_long_atten; + *qdr_dds = txdds_qdr + qib_long_atten; } } @@ -7203,33 +7241,24 @@ static void init_txdds_table(struct qib_pportdata *ppd, int override) int idx; int single_ent = 0; - if (IS_QMH(ppd->dd)) { - /* normally will be overridden, via setup_qmh() */ - sdr_dds = &qmh_sdr_txdds; - ddr_dds = &qmh_ddr_txdds; - qdr_dds = &qmh_qdr_txdds; - single_ent = 1; - } else if (IS_QME(ppd->dd)) { - sdr_dds = &qme_sdr_txdds; - ddr_dds = &qme_ddr_txdds; - qdr_dds = &qme_qdr_txdds; + find_best_ent(ppd, &sdr_dds, &ddr_dds, &qdr_dds, override); + + /* for mez cards or override, use the selected value for all entries */ + if (!(ppd->dd->flags & QIB_HAS_QSFP) || override) single_ent = 1; - } else - find_best_ent(ppd, &sdr_dds, &ddr_dds, &qdr_dds, override); /* Fill in the first entry with the best entry found. */ set_txdds(ppd, 0, sdr_dds); set_txdds(ppd, TXDDS_TABLE_SZ, ddr_dds); set_txdds(ppd, 2 * TXDDS_TABLE_SZ, qdr_dds); - - /* - * for our current speed, also write that value into the - * tx serdes registers. - */ - dds = (struct txdds_ent *)(ppd->link_speed_active == QIB_IB_QDR ? - qdr_dds : (ppd->link_speed_active == - QIB_IB_DDR ? ddr_dds : sdr_dds)); - write_tx_serdes_param(ppd, dds); + if (ppd->lflags & (QIBL_LINKINIT | QIBL_LINKARMED | + QIBL_LINKACTIVE)) { + dds = (struct txdds_ent *)(ppd->link_speed_active == + QIB_IB_QDR ? qdr_dds : + (ppd->link_speed_active == + QIB_IB_DDR ? ddr_dds : sdr_dds)); + write_tx_serdes_param(ppd, dds); + } /* Fill in the remaining entries with the default table values. */ for (idx = 1; idx < ARRAY_SIZE(txdds_sdr); ++idx) { @@ -7352,6 +7381,11 @@ static int serdes_7322_init(struct qib_pportdata *ppd) */ init_txdds_table(ppd, 0); + /* ensure no tx overrides from earlier driver loads */ + qib_write_kreg_port(ppd, krp_tx_deemph_override, + SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, + reset_tx_deemphasis_override)); + /* Patch some SerDes defaults to "Better for IB" */ /* Timing Loop Bandwidth: cdr_timing[11:9] = 0 */ ibsd_wr_allchans(ppd, 2, 0, BMASK(11, 9)); @@ -7421,7 +7455,7 @@ static int serdes_7322_init(struct qib_pportdata *ppd) QDR_STATIC_ADAPT_DOWN_R1 : QDR_STATIC_ADAPT_DOWN); ppd->cpspec->qdr_dfe_on = 1; - /* (FLoop LOS gate: PPM filter enabled */ + /* FLoop LOS gate: PPM filter enabled */ ibsd_wr_allchans(ppd, 38, 0 << 10, 1 << 10); /* rx offset center enabled */ @@ -7486,68 +7520,39 @@ static void write_tx_serdes_param(struct qib_pportdata *ppd, SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, txc0_ena) | SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, txcp1_ena) | SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, txcn1_ena)); - deemph |= 1ULL << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, - tx_override_deemphasis_select); - deemph |= txdds->amp << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, - txampcntl_d2a); - deemph |= txdds->main << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, - txc0_ena); - deemph |= txdds->post << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, - txcp1_ena); - deemph |= txdds->pre << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, + + deemph |= SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, + tx_override_deemphasis_select); + deemph |= (txdds->amp & SYM_RMASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, + txampcntl_d2a)) << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, + txampcntl_d2a); + deemph |= (txdds->main & SYM_RMASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, + txc0_ena)) << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, + txc0_ena); + deemph |= (txdds->post & SYM_RMASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, + txcp1_ena)) << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, + txcp1_ena); + deemph |= (txdds->pre & SYM_RMASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, + txcn1_ena)) << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, txcn1_ena); qib_write_kreg_port(ppd, krp_tx_deemph_override, deemph); } /* - * set per-bay, per channel parameters. For now, we ignore - * do_tx, and always set tx parameters, and set them with the same value - * for all channels, using the channel 0 value. We may switch to - * per-channel settings in the future, and that method only needs - * to be done once. - * Because this also writes the IBC txdds table with a single set - * of values, it should be called only for cases where we want to completely - * force a specific setting, typically only for mez cards. + * Set the parameters for mez cards on link bounce, so they are + * always exactly what was requested. Similar logic to init_txdds + * but does just the serdes. */ static void adj_tx_serdes(struct qib_pportdata *ppd) { - struct txdds_ent txdds; - int i; - u8 *amp, *pre, *mainv, *post; - - /* - * Because we use TX_DEEMPHASIS_OVERRIDE, we need to - * always do tx side, just like H1, since it is cleared - * by link down - */ - amp = ppd->cpspec->amp; - pre = ppd->cpspec->pre; - mainv = ppd->cpspec->mainv; - post = ppd->cpspec->post; - - amp[0] &= SYM_RMASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, - txampcntl_d2a); - mainv[0] &= SYM_RMASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, - txc0_ena); - post[0] &= SYM_RMASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, - txcp1_ena); - pre[0] &= SYM_RMASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, - txcn1_ena); - - /* - * Use the channel zero values, only, for now, for - * all channels - */ - txdds.amp = amp[0]; - txdds.pre = pre[0]; - txdds.main = mainv[0]; - txdds.post = post[0]; - - /* write the QDR table for IBC use, as backup for link down */ - for (i = 0; i < ARRAY_SIZE(txdds_qdr); ++i) - set_txdds(ppd, i + 32, &txdds); + const struct txdds_ent *sdr_dds, *ddr_dds, *qdr_dds; + struct txdds_ent *dds; - write_tx_serdes_param(ppd, &txdds); + find_best_ent(ppd, &sdr_dds, &ddr_dds, &qdr_dds, 1); + dds = (struct txdds_ent *)(ppd->link_speed_active == QIB_IB_QDR ? + qdr_dds : (ppd->link_speed_active == QIB_IB_DDR ? + ddr_dds : sdr_dds)); + write_tx_serdes_param(ppd, dds); } /* set QDR forced value for H1, if needed */ @@ -7567,235 +7572,6 @@ static void force_h1(struct qib_pportdata *ppd) } } -/* - * Parse the parameters for the QMH7342, to get rx and tx serdes - * settings for that Bay, for both possible mez connectors (PCIe bus) - * and IB link (one link on mez1, two possible on mez2). - * - * Data is comma or white space separated. - * - * A set of data has 7 groups, rx and tx groups have SERDES_CHANS values, - * one per IB lane (serdes channel). - * The groups are Bay, bus# H1 rcv, and amp, pre, post, main Tx values (QDR). - * The Bay # is used only for debugging currently. - * H1 values are set whenever the link goes down, or is at cfg_test or - * cfg_wait_enh. Tx values are programmed once, when this routine is called - * (and with default values at chip initialization). Values are any base, in - * strtoul style, and values are seperated by comma, or any white space - * (space, tab, newline). - * - * An example set might look like this (white space vs - * comma used for human ease of reading) - * The ordering is a set of Bay# Bus# H1, amp, pre, post, and main for mez1 IB1, - * repeat for mez2 IB1, then mez2 IB2. - * - * B B H1:0 amp:0 pre:0 post: 0 main:0 - * a u H1: 1 amp: 1 pre: 1 post: 1 main: 1 - * y s H1: 2 amp: 2 pre: 2 post: 2 main: 2 - * H1: 4 amp: 3 pre: 3 post: 3 main: 3 - * 1 3 8,6,5,6 0,0,0,0 1,1,1,1 10,10,10,10 3,3,3,3 - * 1 6 7,6,6,7 0,0,0,0 1,1,1,1 10,10,10,10 3,3,3,3 - * 1 6 9,7,7,8 0,0,0,0 1,1,1,1 10,10,10,10 3,3,3,3 - */ -#define N_QMH_FIELDS 22 -static int setup_qmh_params(const char *str, struct kernel_param *kp) -{ - char *abuf, *v, *nv, *nvp; - struct qib_devdata *dd; - struct qib_pportdata *ppd; - u32 mez, vlen, nf, port, bay; - int ret = 0, found = 0; - - vlen = strlen(str) + 1; - abuf = kmalloc(vlen, GFP_KERNEL); - if (!abuf) { - printk(KERN_INFO QIB_DRV_NAME - " Unable to allocate QMH param buffer; ignoring\n"); - return 0; - } - memcpy(abuf, str, vlen); - v = abuf; - - /* these 3 are because gcc can't know they are set before used */ - port = 1; - mez = 1; /* used only for debugging */ - bay = 0; /* used only for debugging */ - ppd = NULL; - for (nf = 0; (nv = strsep(&v, ", \t\n\r")) && - nf < (N_QMH_FIELDS * 3);) { - u32 val; - - if (!*nv) - /* allow for multiple separators */ - continue; - - val = simple_strtoul(nv, &nvp, 0); - if (nv == nvp) { - printk(KERN_INFO QIB_DRV_NAME - " Bay%u, mez%u IB%u non-numeric value (%s) " - "field #%u, ignoring rest\n", bay, mez, - port, nv, nf % (N_QMH_FIELDS * 3)); - ret = -EINVAL; - goto bail; - } - if (!(nf % N_QMH_FIELDS)) { - ppd = NULL; - bay = val; - if (!bay || bay > 16) { - printk(KERN_INFO QIB_DRV_NAME - " Invalid bay # %u, field %u, " - "ignoring rest\n", bay, nf); - ret = -EINVAL; - goto bail; - } - } else if ((nf % N_QMH_FIELDS) == 1) { - u32 bus = val; - if (nf == 1) { - mez = 1; - port = 1; - } else if (nf == (N_QMH_FIELDS + 1)) { - mez = 2; - port = 1; - } else { - mez = 2; - port = 2; - } - list_for_each_entry(dd, &qib_dev_list, list) { - if (dd->deviceid != PCI_DEVICE_ID_QLOGIC_IB_7322 - || !IS_QMH(dd)) - continue; /* only for QMH cards */ - if (dd->pcidev->bus->number == bus) { - found++; - ppd = &dd->pport[port - 1]; - } - } - } else if (ppd) { - u32 parm = (nf % N_QMH_FIELDS) - 2; - if (parm < SERDES_CHANS && !(parm % SERDES_CHANS)) - ppd->cpspec->h1_val = val; - else if (parm < (2 * SERDES_CHANS)) - ppd->cpspec->amp[parm % SERDES_CHANS] = val; - else if (parm < (3 * SERDES_CHANS)) - ppd->cpspec->pre[parm % SERDES_CHANS] = val; - else if (parm < (4 * SERDES_CHANS)) - ppd->cpspec->post[parm % SERDES_CHANS] = val; - else { - ppd->cpspec->mainv[parm % SERDES_CHANS] = val; - /* At the end of a port, set params */ - if (parm == ((5 * SERDES_CHANS) - 1)) - adj_tx_serdes(ppd); - } - } - nf++; - } - if (!found) { - printk(KERN_ERR QIB_DRV_NAME - ": No match found for qmh_serdes_setup parameter\n"); - ret = -EINVAL; - } -bail: - kfree(abuf); - return ret; -} - -/* - * Similarly for QME7342, but the format is simpler, values are the - * same for all mez card positions in a blade (2 or 4 per blade), but - * are different for some blades vs others, and we don't need to - * specify different parameters for different serdes channels or different - * IB ports. - * Format is: h1 amp,pre,post,main - * Alternate format (so ports can be different): Pport# h1 amp,pre,post,main - */ -#define N_QME_FIELDS 5 -static int setup_qme_params(const char *str, struct kernel_param *kp) -{ - char *abuf, *v, *nv, *nvp; - struct qib_devdata *dd; - u32 vlen, nf, port = 0; - u8 h1, tx[4]; /* amp, pre, post, main */ - int ret = -EINVAL; - char *seplist; - - vlen = strlen(str) + 1; - abuf = kmalloc(vlen, GFP_KERNEL); - if (!abuf) { - printk(KERN_INFO QIB_DRV_NAME - " Unable to allocate QME param buffer; ignoring\n"); - return 0; - } - strncpy(abuf, str, vlen); - - v = abuf; - seplist = " \t"; - h1 = H1_FORCE_QME; /* gcc can't figure out always set before used */ - - for (nf = 0; (nv = strsep(&v, seplist)); ) { - u32 val; - - if (!*nv) - /* allow for multiple separators */ - continue; - - if (!nf && *nv == 'P') { - /* alternate format with port */ - val = simple_strtoul(++nv, &nvp, 0); - if (nv == nvp || port >= NUM_IB_PORTS) { - printk(KERN_INFO QIB_DRV_NAME - " %s: non-numeric port value (%s) " - "ignoring rest\n", __func__, nv); - goto done; - } - port = val; - continue; /* without incrementing nf */ - } - val = simple_strtoul(nv, &nvp, 0); - if (nv == nvp) { - printk(KERN_INFO QIB_DRV_NAME - " %s: non-numeric value (%s) " - "field #%u, ignoring rest\n", __func__, - nv, nf); - goto done; - } - if (!nf) { - h1 = val; - seplist = ","; - } else - tx[nf - 1] = val; - if (++nf == N_QME_FIELDS) { - list_for_each_entry(dd, &qib_dev_list, list) { - int pidx, i; - if (dd->deviceid != PCI_DEVICE_ID_QLOGIC_IB_7322 - || !IS_QME(dd)) - continue; /* only for QME cards */ - for (pidx = 0; pidx < dd->num_pports; ++pidx) { - struct qib_pportdata *ppd; - ppd = &dd->pport[pidx]; - if ((port && ppd->port != port) || - !ppd->link_speed_supported) - continue; - ppd->cpspec->h1_val = h1; - for (i = 0; i < SERDES_CHANS; i++) { - ppd->cpspec->amp[i] = tx[0]; - ppd->cpspec->pre[i] = tx[1]; - ppd->cpspec->post[i] = tx[2]; - ppd->cpspec->mainv[i] = tx[3]; - } - adj_tx_serdes(ppd); - } - } - ret = 0; - goto done; - } - } - printk(KERN_INFO QIB_DRV_NAME - " %s: Only %u of %u fields provided, skipping\n", - __func__, nf, N_QME_FIELDS); -done: - kfree(abuf); - return ret; -} - #define SJA_EN SYM_MASK(SPC_JTAG_ACCESS_REG, SPC_JTAG_ACCESS_EN) #define BISTEN_LSB SYM_LSB(SPC_JTAG_ACCESS_REG, bist_en) -- cgit v1.2.3 From 755fae0ac41672523a3ac00d41fe9bac226b0578 Mon Sep 17 00:00:00 2001 From: Brian Hill Date: Wed, 26 May 2010 20:42:18 -0700 Subject: net: ll_temac: fix interrupt bug when interrupt 0 is used The code is not checking the interrupt for DMA correctly so that an interrupt number of 0 will cause a false error. Signed-off-by: Brian Hill Signed-off-by: John Linn Signed-off-by: David S. Miller --- drivers/net/ll_temac_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index b59b24d667f0..1bb6e605f64f 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -950,7 +950,7 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) lp->rx_irq = irq_of_parse_and_map(np, 0); lp->tx_irq = irq_of_parse_and_map(np, 1); - if (!lp->rx_irq || !lp->tx_irq) { + if ((lp->rx_irq == NO_IRQ) || (lp->tx_irq == NO_IRQ)) { dev_err(&op->dev, "could not determine irqs\n"); rc = -ENOMEM; goto nodev; -- cgit v1.2.3 From 23ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3 Mon Sep 17 00:00:00 2001 From: Brian Hill Date: Wed, 26 May 2010 20:44:30 -0700 Subject: net: ll_temac: fix checksum offload logic The current checksum offload code does not work and this corrects that functionality. It also updates the interrupt coallescing initialization so than there are fewer interrupts and performance is increased. Signed-off-by: Brian Hill Signed-off-by: John Linn Signed-off-by: David S. Miller --- drivers/net/ll_temac.h | 5 +++ drivers/net/ll_temac_main.c | 82 ++++++++++++++++++++++++++++++++------------- 2 files changed, 63 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ll_temac.h b/drivers/net/ll_temac.h index c03358434acb..522abe2ff25a 100644 --- a/drivers/net/ll_temac.h +++ b/drivers/net/ll_temac.h @@ -295,6 +295,10 @@ This option defaults to enabled (set) */ #define MULTICAST_CAM_TABLE_NUM 4 +/* TEMAC Synthesis features */ +#define TEMAC_FEATURE_RX_CSUM (1 << 0) +#define TEMAC_FEATURE_TX_CSUM (1 << 1) + /* TX/RX CURDESC_PTR points to first descriptor */ /* TX/RX TAILDESC_PTR points to last descriptor in linked list */ @@ -353,6 +357,7 @@ struct temac_local { struct mutex indirect_mutex; u32 options; /* Current options word */ int last_link; + unsigned int temac_features; /* Buffer descriptors */ struct cdmac_bd *tx_bd_v; diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index 1bb6e605f64f..fbd07de2e088 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -245,7 +245,7 @@ static int temac_dma_bd_init(struct net_device *ndev) CHNL_CTRL_IRQ_COAL_EN); /* 0x10220483 */ /* 0x00100483 */ - lp->dma_out(lp, RX_CHNL_CTRL, 0xff010000 | + lp->dma_out(lp, RX_CHNL_CTRL, 0xff070000 | CHNL_CTRL_IRQ_EN | CHNL_CTRL_IRQ_DLY_EN | CHNL_CTRL_IRQ_COAL_EN | @@ -574,6 +574,10 @@ static void temac_start_xmit_done(struct net_device *ndev) if (cur_p->app4) dev_kfree_skb_irq((struct sk_buff *)cur_p->app4); cur_p->app0 = 0; + cur_p->app1 = 0; + cur_p->app2 = 0; + cur_p->app3 = 0; + cur_p->app4 = 0; ndev->stats.tx_packets++; ndev->stats.tx_bytes += cur_p->len; @@ -589,6 +593,29 @@ static void temac_start_xmit_done(struct net_device *ndev) netif_wake_queue(ndev); } +static inline int temac_check_tx_bd_space(struct temac_local *lp, int num_frag) +{ + struct cdmac_bd *cur_p; + int tail; + + tail = lp->tx_bd_tail; + cur_p = &lp->tx_bd_v[tail]; + + do { + if (cur_p->app0) + return NETDEV_TX_BUSY; + + tail++; + if (tail >= TX_BD_NUM) + tail = 0; + + cur_p = &lp->tx_bd_v[tail]; + num_frag--; + } while (num_frag >= 0); + + return 0; +} + static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) { struct temac_local *lp = netdev_priv(ndev); @@ -603,7 +630,7 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) start_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; - if (cur_p->app0 & STS_CTRL_APP0_CMPLT) { + if (temac_check_tx_bd_space(lp, num_frag)) { if (!netif_queue_stopped(ndev)) { netif_stop_queue(ndev); return NETDEV_TX_BUSY; @@ -613,29 +640,14 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) cur_p->app0 = 0; if (skb->ip_summed == CHECKSUM_PARTIAL) { - const struct iphdr *ip = ip_hdr(skb); - int length = 0, start = 0, insert = 0; - - switch (ip->protocol) { - case IPPROTO_TCP: - start = sizeof(struct iphdr) + ETH_HLEN; - insert = sizeof(struct iphdr) + ETH_HLEN + 16; - length = ip->tot_len - sizeof(struct iphdr); - break; - case IPPROTO_UDP: - start = sizeof(struct iphdr) + ETH_HLEN; - insert = sizeof(struct iphdr) + ETH_HLEN + 6; - length = ip->tot_len - sizeof(struct iphdr); - break; - default: - break; - } - cur_p->app1 = ((start << 16) | insert); - cur_p->app2 = csum_tcpudp_magic(ip->saddr, ip->daddr, - length, ip->protocol, 0); - skb->data[insert] = 0; - skb->data[insert + 1] = 0; + unsigned int csum_start_off = skb_transport_offset(skb); + unsigned int csum_index_off = csum_start_off + skb->csum_offset; + + cur_p->app0 |= 1; /* TX Checksum Enabled */ + cur_p->app1 = (csum_start_off << 16) | csum_index_off; + cur_p->app2 = 0; /* initial checksum seed */ } + cur_p->app0 |= STS_CTRL_APP0_SOP; cur_p->len = skb_headlen(skb); cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len, @@ -699,6 +711,15 @@ static void ll_temac_recv(struct net_device *ndev) skb->protocol = eth_type_trans(skb, ndev); skb->ip_summed = CHECKSUM_NONE; + /* if we're doing rx csum offload, set it up */ + if (((lp->temac_features & TEMAC_FEATURE_RX_CSUM) != 0) && + (skb->protocol == __constant_htons(ETH_P_IP)) && + (skb->len > 64)) { + + skb->csum = cur_p->app3 & 0xFFFF; + skb->ip_summed = CHECKSUM_COMPLETE; + } + netif_rx(skb); ndev->stats.rx_packets++; @@ -883,6 +904,7 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) struct temac_local *lp; struct net_device *ndev; const void *addr; + __be32 *p; int size, rc = 0; /* Init network device structure */ @@ -926,6 +948,18 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) goto nodev; } + /* Setup checksum offload, but default to off if not specified */ + lp->temac_features = 0; + p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,txcsum", NULL); + if (p && be32_to_cpu(*p)) { + lp->temac_features |= TEMAC_FEATURE_TX_CSUM; + /* Can checksum TCP/UDP over IPv4. */ + ndev->features |= NETIF_F_IP_CSUM; + } + p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,rxcsum", NULL); + if (p && be32_to_cpu(*p)) + lp->temac_features |= TEMAC_FEATURE_RX_CSUM; + /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */ np = of_parse_phandle(op->node, "llink-connected", 0); if (!np) { -- cgit v1.2.3 From 067fb2f648543894ce775082c5636f4c32b99e4f Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 26 May 2010 23:30:55 -0700 Subject: Input: ads7846 - return error on regulator_get() failure In probe(), if regulator_get() failed, an error code was not being returned causing the driver to be successfully bound, even though probe failed. This in turn caused the suspend, resume and remove methods to be registered and accessed via the SPI core. Since these functions all access private driver data using pointers that had been freed during the failed probe, this would lead to unpredictable behavior. This patch ensures that probe() returns an error code in this failure case so the driver is not bound. Found using lockdep and noticing the lock used in the suspend/resum path pointed to a bogus lock due to the freed memory. Signed-off-by: Kevin Hilman Acked-by: Mike Frysinger Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ads7846.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 532279cda0e4..634f6f6b9b13 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -1163,8 +1163,8 @@ static int __devinit ads7846_probe(struct spi_device *spi) ts->reg = regulator_get(&spi->dev, "vcc"); if (IS_ERR(ts->reg)) { - dev_err(&spi->dev, "unable to get regulator: %ld\n", - PTR_ERR(ts->reg)); + err = PTR_ERR(ts->reg); + dev_err(&spi->dev, "unable to get regulator: %ld\n", err); goto err_free_gpio; } -- cgit v1.2.3 From 388bbcade41ee68d2d1ebb51a538380ea48ae599 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Wed, 26 May 2010 23:30:54 -0700 Subject: Input: usbtouchscreen - support bigger iNexio touchscreens Bigger Nexio touchscreens not only send more data but also the header values are modified somewhat. Fix the header (it's a guesswork but it works at least on one 46" touchscreen with 2.00SMS firmware) and also increase rept_size. Signed-off-by: Ondrej Zary Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/usbtouchscreen.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 0b0ae2e17a60..82227b00d4b9 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -857,6 +857,11 @@ static int nexio_read_data(struct usbtouch_usb *usbtouch, unsigned char *pkt) if ((pkt[0] & 0xe0) != 0xe0) return 0; + if (be16_to_cpu(packet->data_len) > 0xff) + packet->data_len = cpu_to_be16(be16_to_cpu(packet->data_len) - 0x100); + if (be16_to_cpu(packet->x_len) > 0xff) + packet->x_len = cpu_to_be16(be16_to_cpu(packet->x_len) - 0x80); + /* send ACK */ ret = usb_submit_urb(priv->ack, GFP_ATOMIC); @@ -1112,7 +1117,7 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { #ifdef CONFIG_TOUCHSCREEN_USB_NEXIO [DEVTYPE_NEXIO] = { - .rept_size = 128, + .rept_size = 1024, .irq_always = true, .read_data = nexio_read_data, .init = nexio_init, -- cgit v1.2.3 From 0f3d9a17469d71ba1bab79c07c8eecb9e26e60af Mon Sep 17 00:00:00 2001 From: Krishna Kumar Date: Tue, 25 May 2010 11:10:36 +0530 Subject: vhost: Fix host panic if ioctl called with wrong index Missed a boundary value check in vhost_set_vring. The host panics if idx == nvqs is used in ioctl commands in vhost_virtqueue_init. Signed-off-by: Krishna Kumar Signed-off-by: Michael S. Tsirkin --- drivers/vhost/vhost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 750effe0f98b..44f123abb0f4 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -374,7 +374,7 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) r = get_user(idx, idxp); if (r < 0) return r; - if (idx > d->nvqs) + if (idx >= d->nvqs) return -ENOBUFS; vq = d->vqs + idx; -- cgit v1.2.3 From 7ad9c9d27048547e96e4e3a13b5780ec6f81bb9f Mon Sep 17 00:00:00 2001 From: Takuya Yoshikawa Date: Thu, 27 May 2010 18:58:03 +0900 Subject: vhost: fix to check the return value of copy_to/from_user() correctly copy_to/from_user() returns the number of bytes that could not be copied. So we need to check if it is not zero, and in that case, we should return the error number -EFAULT rather than directly return the return value from copy_to/from_user(). Signed-off-by: Takuya Yoshikawa Signed-off-by: Michael S. Tsirkin --- drivers/vhost/vhost.c | 51 ++++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 44f123abb0f4..e36620272715 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -320,10 +320,8 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m) { struct vhost_memory mem, *newmem, *oldmem; unsigned long size = offsetof(struct vhost_memory, regions); - long r; - r = copy_from_user(&mem, m, size); - if (r) - return r; + if (copy_from_user(&mem, m, size)) + return -EFAULT; if (mem.padding) return -EOPNOTSUPP; if (mem.nregions > VHOST_MEMORY_MAX_NREGIONS) @@ -333,11 +331,10 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m) return -ENOMEM; memcpy(newmem, &mem, size); - r = copy_from_user(newmem->regions, m->regions, - mem.nregions * sizeof *m->regions); - if (r) { + if (copy_from_user(newmem->regions, m->regions, + mem.nregions * sizeof *m->regions)) { kfree(newmem); - return r; + return -EFAULT; } if (!memory_access_ok(d, newmem, vhost_has_feature(d, VHOST_F_LOG_ALL))) @@ -389,9 +386,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) r = -EBUSY; break; } - r = copy_from_user(&s, argp, sizeof s); - if (r < 0) + if (copy_from_user(&s, argp, sizeof s)) { + r = -EFAULT; break; + } if (!s.num || s.num > 0xffff || (s.num & (s.num - 1))) { r = -EINVAL; break; @@ -405,9 +403,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) r = -EBUSY; break; } - r = copy_from_user(&s, argp, sizeof s); - if (r < 0) + if (copy_from_user(&s, argp, sizeof s)) { + r = -EFAULT; break; + } if (s.num > 0xffff) { r = -EINVAL; break; @@ -419,12 +418,14 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) case VHOST_GET_VRING_BASE: s.index = idx; s.num = vq->last_avail_idx; - r = copy_to_user(argp, &s, sizeof s); + if (copy_to_user(argp, &s, sizeof s)) + r = -EFAULT; break; case VHOST_SET_VRING_ADDR: - r = copy_from_user(&a, argp, sizeof a); - if (r < 0) + if (copy_from_user(&a, argp, sizeof a)) { + r = -EFAULT; break; + } if (a.flags & ~(0x1 << VHOST_VRING_F_LOG)) { r = -EOPNOTSUPP; break; @@ -477,9 +478,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) vq->used = (void __user *)(unsigned long)a.used_user_addr; break; case VHOST_SET_VRING_KICK: - r = copy_from_user(&f, argp, sizeof f); - if (r < 0) + if (copy_from_user(&f, argp, sizeof f)) { + r = -EFAULT; break; + } eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); if (IS_ERR(eventfp)) { r = PTR_ERR(eventfp); @@ -492,9 +494,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) filep = eventfp; break; case VHOST_SET_VRING_CALL: - r = copy_from_user(&f, argp, sizeof f); - if (r < 0) + if (copy_from_user(&f, argp, sizeof f)) { + r = -EFAULT; break; + } eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); if (IS_ERR(eventfp)) { r = PTR_ERR(eventfp); @@ -510,9 +513,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) filep = eventfp; break; case VHOST_SET_VRING_ERR: - r = copy_from_user(&f, argp, sizeof f); - if (r < 0) + if (copy_from_user(&f, argp, sizeof f)) { + r = -EFAULT; break; + } eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); if (IS_ERR(eventfp)) { r = PTR_ERR(eventfp); @@ -575,9 +579,10 @@ long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, unsigned long arg) r = vhost_set_memory(d, argp); break; case VHOST_SET_LOG_BASE: - r = copy_from_user(&p, argp, sizeof p); - if (r < 0) + if (copy_from_user(&p, argp, sizeof p)) { + r = -EFAULT; break; + } if ((u64)(unsigned long)p != p) { r = -EFAULT; break; -- cgit v1.2.3 From d3553a52490dcac54f45083f8fa018e26c22e947 Mon Sep 17 00:00:00 2001 From: Takuya Yoshikawa Date: Thu, 27 May 2010 19:01:58 +0900 Subject: vhost-net: fix to check the return value of copy_to/from_user() correctly copy_to/from_user() returns the number of bytes that could not be copied. So we need to check if it is not zero, and in that case, we should return the error number -EFAULT rather than directly return the return value from copy_to/from_user(). Signed-off-by: Takuya Yoshikawa Signed-off-by: Michael S. Tsirkin --- drivers/vhost/net.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index aa88911c9504..0f41c9195e9b 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -593,17 +593,17 @@ static long vhost_net_ioctl(struct file *f, unsigned int ioctl, int r; switch (ioctl) { case VHOST_NET_SET_BACKEND: - r = copy_from_user(&backend, argp, sizeof backend); - if (r < 0) - return r; + if (copy_from_user(&backend, argp, sizeof backend)) + return -EFAULT; return vhost_net_set_backend(n, backend.index, backend.fd); case VHOST_GET_FEATURES: features = VHOST_FEATURES; - return copy_to_user(featurep, &features, sizeof features); + if (copy_to_user(featurep, &features, sizeof features)) + return -EFAULT; + return 0; case VHOST_SET_FEATURES: - r = copy_from_user(&features, featurep, sizeof features); - if (r < 0) - return r; + if (copy_from_user(&features, featurep, sizeof features)) + return -EFAULT; if (features & ~VHOST_FEATURES) return -EOPNOTSUPP; return vhost_net_set_features(n, features); -- cgit v1.2.3 From a02c37891a9b2d7ce93f9d09455b4f67c4c23b95 Mon Sep 17 00:00:00 2001 From: Takuya Yoshikawa Date: Thu, 27 May 2010 19:03:56 +0900 Subject: vhost: fix the memory leak which will happen when memory_access_ok fails We need to free newmem when vhost_set_memory() fails to complete. Signed-off-by: Takuya Yoshikawa Signed-off-by: Michael S. Tsirkin --- drivers/vhost/vhost.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index e36620272715..da21ae951826 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -337,8 +337,10 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m) return -EFAULT; } - if (!memory_access_ok(d, newmem, vhost_has_feature(d, VHOST_F_LOG_ALL))) + if (!memory_access_ok(d, newmem, vhost_has_feature(d, VHOST_F_LOG_ALL))) { + kfree(newmem); return -EFAULT; + } oldmem = d->memory; rcu_assign_pointer(d->memory, newmem); synchronize_rcu(); -- cgit v1.2.3 From 36a32ae0007c6c1e4e5d1a4363290792c2938f0a Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Fri, 21 May 2010 11:16:10 +0400 Subject: pohmelfs: Remove dead quota code Quota on pohmelfs is non-functional. IFAIU quota logic was copy-pasted from generic setattr(). Acked-by: Evgeniy Polyakov Signed-off-by: Dmitry Monakhov Signed-off-by: Jan Kara --- drivers/staging/pohmelfs/inode.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c index 9286e863b0e7..e1ccb49c75ec 100644 --- a/drivers/staging/pohmelfs/inode.c +++ b/drivers/staging/pohmelfs/inode.c @@ -29,7 +29,6 @@ #include #include #include -#include #include "netfs.h" @@ -969,13 +968,6 @@ int pohmelfs_setattr_raw(struct inode *inode, struct iattr *attr) goto err_out_exit; } - if ((attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || - (attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { - err = dquot_transfer(inode, attr); - if (err) - goto err_out_exit; - } - err = inode_setattr(inode, attr); if (err) { dprintk("%s: ino: %llu, failed to set the attributes.\n", __func__, POHMELFS_I(inode)->ino); -- cgit v1.2.3 From ca2afb6dbea74ee762ae5856af7045a57a65e9c8 Mon Sep 17 00:00:00 2001 From: Sudhakar Rajashekhara Date: Wed, 26 May 2010 14:41:49 -0700 Subject: davinci: mmc: pass number of SG segments as platform data On some platforms like DM355, the number of EDMA parameter slots available for EDMA_SLOT_ANY usage are few. In such cases, if MMC/SD uses 16 slots for each instance of MMC controller, then the number of slots available for other modules will be very few. By passing the number of EDMA slots to be used in MMC driver from platform data, EDMA slots available for other purposes can be controlled. Most of the platforms will not use this platform data variable. But on DM355, as the number of EDMA resources available is limited, the number of scatter- gather segments used inside the MMC driver can be 8 (passed as platform data) instead of 16. On DM355, when the number of scatter-gather segments was reduced to 8, I saw a performance difference of about 0.25-0.4 Mbytes/sec during write. Read performance variations were negligible. Signed-off-by: Sudhakar Rajashekhara Acked-by: Kevin Hilman Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/mach-davinci/include/mach/mmc.h | 3 +++ drivers/mmc/host/davinci_mmc.c | 24 +++++++++++++++++------- 2 files changed, 20 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-davinci/include/mach/mmc.h b/arch/arm/mach-davinci/include/mach/mmc.h index 5a85e24f3673..d4f1e9675069 100644 --- a/arch/arm/mach-davinci/include/mach/mmc.h +++ b/arch/arm/mach-davinci/include/mach/mmc.h @@ -22,6 +22,9 @@ struct davinci_mmc_config { /* Version of the MMC/SD controller */ u8 version; + + /* Number of sg segments */ + u8 nr_sg; }; void davinci_setup_mmc(int module, struct davinci_mmc_config *config); diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index 3bd0ba294e9d..547d29c31b40 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c @@ -137,15 +137,15 @@ /* * One scatterlist dma "segment" is at most MAX_CCNT rw_threshold units, - * and we handle up to NR_SG segments. MMC_BLOCK_BOUNCE kicks in only + * and we handle up to MAX_NR_SG segments. MMC_BLOCK_BOUNCE kicks in only * for drivers with max_hw_segs == 1, making the segments bigger (64KB) - * than the page or two that's otherwise typical. NR_SG == 16 gives at - * least the same throughput boost, using EDMA transfer linkage instead - * of spending CPU time copying pages. + * than the page or two that's otherwise typical. nr_sg (passed from + * platform data) == 16 gives at least the same throughput boost, using + * EDMA transfer linkage instead of spending CPU time copying pages. */ #define MAX_CCNT ((1 << 16) - 1) -#define NR_SG 16 +#define MAX_NR_SG 16 static unsigned rw_threshold = 32; module_param(rw_threshold, uint, S_IRUGO); @@ -192,7 +192,7 @@ struct mmc_davinci_host { struct edmacc_param tx_template; struct edmacc_param rx_template; unsigned n_link; - u32 links[NR_SG - 1]; + u32 links[MAX_NR_SG - 1]; /* For PIO we walk scatterlists one segment at a time. */ unsigned int sg_len; @@ -202,6 +202,8 @@ struct mmc_davinci_host { u8 version; /* for ns in one cycle calculation */ unsigned ns_in_one_cycle; + /* Number of sg segments */ + u8 nr_sg; #ifdef CONFIG_CPU_FREQ struct notifier_block freq_transition; #endif @@ -568,6 +570,7 @@ davinci_release_dma_channels(struct mmc_davinci_host *host) static int __init davinci_acquire_dma_channels(struct mmc_davinci_host *host) { + u32 link_size; int r, i; /* Acquire master DMA write channel */ @@ -593,7 +596,8 @@ static int __init davinci_acquire_dma_channels(struct mmc_davinci_host *host) /* Allocate parameter RAM slots, which will later be bound to a * channel as needed to handle a scatterlist. */ - for (i = 0; i < ARRAY_SIZE(host->links); i++) { + link_size = min_t(unsigned, host->nr_sg, ARRAY_SIZE(host->links)); + for (i = 0; i < link_size; i++) { r = edma_alloc_slot(EDMA_CTLR(host->txdma), EDMA_SLOT_ANY); if (r < 0) { dev_dbg(mmc_dev(host->mmc), "dma PaRAM alloc --> %d\n", @@ -1202,6 +1206,12 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev) init_mmcsd_host(host); + if (pdata->nr_sg) + host->nr_sg = pdata->nr_sg - 1; + + if (host->nr_sg > MAX_NR_SG || !host->nr_sg) + host->nr_sg = MAX_NR_SG; + host->use_dma = use_dma; host->irq = irq; -- cgit v1.2.3 From 0e950fa686d53a57ee6c47f477ecfc681670c6a9 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 26 May 2010 14:41:49 -0700 Subject: mmc-omap: add support for 16-bit and 32-bit registers The omap850 and omap730 use 16-bit registers instead of 32-bit, requiring a modification of the register addresses in the mmc-omap driver. To resolve this, a bit shift is performed on base register addresses, either by 1 or 2 bits depending on the CPU in use. This yields the correct registers for each CPU. Signed-off-by: Marek Belisko Signed-off-by: Cory Maccarrone Signed-off-by: Tony Lindgren Cc: Ladislav Michl Cc: Ben Dooks Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/host/omap.c | 62 ++++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 84d280406341..475490b18570 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -39,30 +39,30 @@ #include #define OMAP_MMC_REG_CMD 0x00 -#define OMAP_MMC_REG_ARGL 0x04 -#define OMAP_MMC_REG_ARGH 0x08 -#define OMAP_MMC_REG_CON 0x0c -#define OMAP_MMC_REG_STAT 0x10 -#define OMAP_MMC_REG_IE 0x14 -#define OMAP_MMC_REG_CTO 0x18 -#define OMAP_MMC_REG_DTO 0x1c -#define OMAP_MMC_REG_DATA 0x20 -#define OMAP_MMC_REG_BLEN 0x24 -#define OMAP_MMC_REG_NBLK 0x28 -#define OMAP_MMC_REG_BUF 0x2c -#define OMAP_MMC_REG_SDIO 0x34 -#define OMAP_MMC_REG_REV 0x3c -#define OMAP_MMC_REG_RSP0 0x40 -#define OMAP_MMC_REG_RSP1 0x44 -#define OMAP_MMC_REG_RSP2 0x48 -#define OMAP_MMC_REG_RSP3 0x4c -#define OMAP_MMC_REG_RSP4 0x50 -#define OMAP_MMC_REG_RSP5 0x54 -#define OMAP_MMC_REG_RSP6 0x58 -#define OMAP_MMC_REG_RSP7 0x5c -#define OMAP_MMC_REG_IOSR 0x60 -#define OMAP_MMC_REG_SYSC 0x64 -#define OMAP_MMC_REG_SYSS 0x68 +#define OMAP_MMC_REG_ARGL 0x01 +#define OMAP_MMC_REG_ARGH 0x02 +#define OMAP_MMC_REG_CON 0x03 +#define OMAP_MMC_REG_STAT 0x04 +#define OMAP_MMC_REG_IE 0x05 +#define OMAP_MMC_REG_CTO 0x06 +#define OMAP_MMC_REG_DTO 0x07 +#define OMAP_MMC_REG_DATA 0x08 +#define OMAP_MMC_REG_BLEN 0x09 +#define OMAP_MMC_REG_NBLK 0x0a +#define OMAP_MMC_REG_BUF 0x0b +#define OMAP_MMC_REG_SDIO 0x0d +#define OMAP_MMC_REG_REV 0x0f +#define OMAP_MMC_REG_RSP0 0x10 +#define OMAP_MMC_REG_RSP1 0x11 +#define OMAP_MMC_REG_RSP2 0x12 +#define OMAP_MMC_REG_RSP3 0x13 +#define OMAP_MMC_REG_RSP4 0x14 +#define OMAP_MMC_REG_RSP5 0x15 +#define OMAP_MMC_REG_RSP6 0x16 +#define OMAP_MMC_REG_RSP7 0x17 +#define OMAP_MMC_REG_IOSR 0x18 +#define OMAP_MMC_REG_SYSC 0x19 +#define OMAP_MMC_REG_SYSS 0x1a #define OMAP_MMC_STAT_CARD_ERR (1 << 14) #define OMAP_MMC_STAT_CARD_IRQ (1 << 13) @@ -78,8 +78,9 @@ #define OMAP_MMC_STAT_CARD_BUSY (1 << 2) #define OMAP_MMC_STAT_END_OF_CMD (1 << 0) -#define OMAP_MMC_READ(host, reg) __raw_readw((host)->virt_base + OMAP_MMC_REG_##reg) -#define OMAP_MMC_WRITE(host, reg, val) __raw_writew((val), (host)->virt_base + OMAP_MMC_REG_##reg) +#define OMAP_MMC_REG(host, reg) (OMAP_MMC_REG_##reg << (host)->reg_shift) +#define OMAP_MMC_READ(host, reg) __raw_readw((host)->virt_base + OMAP_MMC_REG(host, reg)) +#define OMAP_MMC_WRITE(host, reg, val) __raw_writew((val), (host)->virt_base + OMAP_MMC_REG(host, reg)) /* * Command types @@ -133,6 +134,7 @@ struct mmc_omap_host { int irq; unsigned char bus_mode; unsigned char hw_bus_mode; + unsigned int reg_shift; struct work_struct cmd_abort_work; unsigned abort:1; @@ -680,9 +682,9 @@ mmc_omap_xfer_data(struct mmc_omap_host *host, int write) host->data->bytes_xfered += n; if (write) { - __raw_writesw(host->virt_base + OMAP_MMC_REG_DATA, host->buffer, n); + __raw_writesw(host->virt_base + OMAP_MMC_REG(host, DATA), host->buffer, n); } else { - __raw_readsw(host->virt_base + OMAP_MMC_REG_DATA, host->buffer, n); + __raw_readsw(host->virt_base + OMAP_MMC_REG(host, DATA), host->buffer, n); } } @@ -900,7 +902,7 @@ mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data) int dst_port = 0; int sync_dev = 0; - data_addr = host->phys_base + OMAP_MMC_REG_DATA; + data_addr = host->phys_base + OMAP_MMC_REG(host, DATA); frame = data->blksz; count = sg_dma_len(sg); @@ -1493,6 +1495,8 @@ static int __init mmc_omap_probe(struct platform_device *pdev) } } + host->reg_shift = (cpu_is_omap7xx() ? 1 : 2); + return 0; err_plat_cleanup: -- cgit v1.2.3 From f27f47ef5b67106ff1cdeebf061387a7b30c12bc Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 26 May 2010 14:41:53 -0700 Subject: sdhci: implement CAP_CLOCK_BASE_BROKEN quirk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some hosts (e.g. as found in CNS3xxx SOCs) report wrong value in CLOCK_BASE capability field, and currently there is no way to force the SDHCI core to use the platform-provided base clock value. This patch implements CAP_CLOCK_BASE_BROKEN quirk. When enabled, the SDHCI core will always use base clock frequency provided by the platform. Signed-off-by: Anton Vorontsov Cc: Richard Röjfors Cc: David Vrabel Cc: Pierre Ossman Cc: Ben Dooks Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/host/sdhci.c | 3 ++- drivers/mmc/host/sdhci.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 9d4fdfa685e5..02b365f5a4be 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1744,7 +1744,8 @@ int sdhci_add_host(struct sdhci_host *host) host->max_clk = (caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT; host->max_clk *= 1000000; - if (host->max_clk == 0) { + if (host->max_clk == 0 || host->quirks & + SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN) { if (!host->ops->get_max_clock) { printk(KERN_ERR "%s: Hardware doesn't specify base clock " diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 842f46f94284..831bf7f137f6 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -236,6 +236,8 @@ struct sdhci_host { #define SDHCI_QUIRK_DELAY_AFTER_POWER (1<<23) /* Controller uses SDCLK instead of TMCLK for data timeouts */ #define SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK (1<<24) +/* Controller reports wrong base clock capability */ +#define SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN (1<<25) int irq; /* Device IRQ */ void __iomem * ioaddr; /* Mapped address */ -- cgit v1.2.3 From a7626b7a5de37bbd506b23633be95428ee81c2e4 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 26 May 2010 14:41:55 -0700 Subject: sdhci-pltfm: implement platform data passing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This includes platform ops, quirks and (de)initialization callbacks. Signed-off-by: Anton Vorontsov Cc: Richard Röjfors Cc: David Vrabel Cc: Pierre Ossman Cc: Ben Dooks Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/host/sdhci-pltfm.c | 24 ++++++++++++++++++++---- include/linux/sdhci-pltfm.h | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 include/linux/sdhci-pltfm.h (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c index 297f40ae6ad5..217b911a2635 100644 --- a/drivers/mmc/host/sdhci-pltfm.c +++ b/drivers/mmc/host/sdhci-pltfm.c @@ -29,6 +29,7 @@ #include #include +#include #include "sdhci.h" @@ -49,12 +50,11 @@ static struct sdhci_ops sdhci_pltfm_ops = { static int __devinit sdhci_pltfm_probe(struct platform_device *pdev) { + struct sdhci_pltfm_data *pdata = pdev->dev.platform_data; struct sdhci_host *host; struct resource *iomem; int ret; - BUG_ON(pdev == NULL); - iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!iomem) { ret = -ENOMEM; @@ -76,7 +76,12 @@ static int __devinit sdhci_pltfm_probe(struct platform_device *pdev) } host->hw_name = "platform"; - host->ops = &sdhci_pltfm_ops; + if (pdata && pdata->ops) + host->ops = pdata->ops; + else + host->ops = &sdhci_pltfm_ops; + if (pdata) + host->quirks = pdata->quirks; host->irq = platform_get_irq(pdev, 0); if (!request_mem_region(iomem->start, resource_size(iomem), @@ -93,6 +98,12 @@ static int __devinit sdhci_pltfm_probe(struct platform_device *pdev) goto err_remap; } + if (pdata && pdata->init) { + ret = pdata->init(host); + if (ret) + goto err_plat_init; + } + ret = sdhci_add_host(host); if (ret) goto err_add_host; @@ -102,6 +113,9 @@ static int __devinit sdhci_pltfm_probe(struct platform_device *pdev) return 0; err_add_host: + if (pdata && pdata->exit) + pdata->exit(host); +err_plat_init: iounmap(host->ioaddr); err_remap: release_mem_region(iomem->start, resource_size(iomem)); @@ -114,6 +128,7 @@ err: static int __devexit sdhci_pltfm_remove(struct platform_device *pdev) { + struct sdhci_pltfm_data *pdata = pdev->dev.platform_data; struct sdhci_host *host = platform_get_drvdata(pdev); struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); int dead; @@ -125,6 +140,8 @@ static int __devexit sdhci_pltfm_remove(struct platform_device *pdev) dead = 1; sdhci_remove_host(host, dead); + if (pdata && pdata->exit) + pdata->exit(host); iounmap(host->ioaddr); release_mem_region(iomem->start, resource_size(iomem)); sdhci_free_host(host); @@ -165,4 +182,3 @@ MODULE_DESCRIPTION("Secure Digital Host Controller Interface platform driver"); MODULE_AUTHOR("Mocean Laboratories "); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:sdhci"); - diff --git a/include/linux/sdhci-pltfm.h b/include/linux/sdhci-pltfm.h new file mode 100644 index 000000000000..0239bd70241e --- /dev/null +++ b/include/linux/sdhci-pltfm.h @@ -0,0 +1,35 @@ +/* + * Platform data declarations for the sdhci-pltfm driver. + * + * Copyright (c) 2010 MontaVista Software, LLC. + * + * Author: Anton Vorontsov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + */ + +#ifndef _SDHCI_PLTFM_H +#define _SDHCI_PLTFM_H + +struct sdhci_ops; +struct sdhci_host; + +/** + * struct sdhci_pltfm_data - SDHCI platform-specific information & hooks + * @ops: optional pointer to the platform-provided SDHCI ops + * @quirks: optional SDHCI quirks + * @init: optional hook that is called during device probe, before the + * driver tries to access any SDHCI registers + * @exit: optional hook that is called during device removal + */ +struct sdhci_pltfm_data { + struct sdhci_ops *ops; + unsigned int quirks; + int (*init)(struct sdhci_host *host); + void (*exit)(struct sdhci_host *host); +}; + +#endif /* _SDHCI_PLTFM_H */ -- cgit v1.2.3 From e632c45ad040a54058db577981cdc3f4b316da55 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 26 May 2010 14:41:56 -0700 Subject: sdhci-pltfm: do not print errors in case of an extended iomem size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some hosts have an extended SDHCI iomem size, so the driver should only print errors if the iomem size is less than 0x100. Signed-off-by: Anton Vorontsov Acked-by: Richard Röjfors Cc: David Vrabel Cc: Pierre Ossman Cc: Ben Dooks Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/host/sdhci-pltfm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c index 217b911a2635..b6ee0d719698 100644 --- a/drivers/mmc/host/sdhci-pltfm.c +++ b/drivers/mmc/host/sdhci-pltfm.c @@ -61,7 +61,7 @@ static int __devinit sdhci_pltfm_probe(struct platform_device *pdev) goto err; } - if (resource_size(iomem) != 0x100) + if (resource_size(iomem) < 0x100) dev_err(&pdev->dev, "Invalid iomem size. You may " "experience problems.\n"); -- cgit v1.2.3 From 06de845f72eeb169ea624f17396cd41d03384940 Mon Sep 17 00:00:00 2001 From: Chaithrika U S Date: Wed, 26 May 2010 14:41:57 -0700 Subject: davinci: mmc: add a function to control reset state of the controller Add a helper function which will aid in changing the reset status of the controller. Signed-off-by: Chaithrika U S Signed-off-by: Kevin Hilman Cc: Vipin Bhandari Cc: Sudhakar Rajashekhara Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/host/davinci_mmc.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index 547d29c31b40..56afe0a00f56 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c @@ -909,19 +909,26 @@ static void mmc_davinci_cmd_done(struct mmc_davinci_host *host, } } -static void -davinci_abort_data(struct mmc_davinci_host *host, struct mmc_data *data) +static inline void mmc_davinci_reset_ctrl(struct mmc_davinci_host *host, + int val) { u32 temp; - /* reset command and data state machines */ temp = readl(host->base + DAVINCI_MMCCTL); - writel(temp | MMCCTL_CMDRST | MMCCTL_DATRST, - host->base + DAVINCI_MMCCTL); + if (val) /* reset */ + temp |= MMCCTL_CMDRST | MMCCTL_DATRST; + else /* enable */ + temp &= ~(MMCCTL_CMDRST | MMCCTL_DATRST); - temp &= ~(MMCCTL_CMDRST | MMCCTL_DATRST); - udelay(10); writel(temp, host->base + DAVINCI_MMCCTL); + udelay(10); +} + +static void +davinci_abort_data(struct mmc_davinci_host *host, struct mmc_data *data) +{ + mmc_davinci_reset_ctrl(host, 1); + mmc_davinci_reset_ctrl(host, 0); } static irqreturn_t mmc_davinci_irq(int irq, void *dev_id) @@ -1125,15 +1132,8 @@ static inline void mmc_davinci_cpufreq_deregister(struct mmc_davinci_host *host) #endif static void __init init_mmcsd_host(struct mmc_davinci_host *host) { - /* DAT line portion is diabled and in reset state */ - writel(readl(host->base + DAVINCI_MMCCTL) | MMCCTL_DATRST, - host->base + DAVINCI_MMCCTL); - - /* CMD line portion is diabled and in reset state */ - writel(readl(host->base + DAVINCI_MMCCTL) | MMCCTL_CMDRST, - host->base + DAVINCI_MMCCTL); - udelay(10); + mmc_davinci_reset_ctrl(host, 1); writel(0, host->base + DAVINCI_MMCCLK); writel(MMCCLK_CLKEN, host->base + DAVINCI_MMCCLK); @@ -1141,12 +1141,7 @@ static void __init init_mmcsd_host(struct mmc_davinci_host *host) writel(0x1FFF, host->base + DAVINCI_MMCTOR); writel(0xFFFF, host->base + DAVINCI_MMCTOD); - writel(readl(host->base + DAVINCI_MMCCTL) & ~MMCCTL_DATRST, - host->base + DAVINCI_MMCCTL); - writel(readl(host->base + DAVINCI_MMCCTL) & ~MMCCTL_CMDRST, - host->base + DAVINCI_MMCCTL); - - udelay(10); + mmc_davinci_reset_ctrl(host, 0); } static int __init davinci_mmcsd_probe(struct platform_device *pdev) -- cgit v1.2.3 From bbce5802afc560c4a487afea3761b85fcb862fb3 Mon Sep 17 00:00:00 2001 From: Chaithrika U S Date: Wed, 26 May 2010 14:41:57 -0700 Subject: davinci: mmc: updates to suspend/resume implementation Improve the suspend and resume callbacks in DaVinci MMC host controller driver. Modify the reset status of the contorller and clock during suspend and resume. Also migrate the power management callbacks from platform driver to dev_pm_ops structure. Tested on DA850/OMAP-L138 EVM. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Chaithrika U S Acked-by: Kevin Hilman Cc: Vipin Bhandari Cc: Sudhakar Rajashekhara Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/host/davinci_mmc.c | 51 +++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index 56afe0a00f56..aae39125b8d7 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c @@ -171,6 +171,7 @@ struct mmc_davinci_host { #define DAVINCI_MMC_DATADIR_READ 1 #define DAVINCI_MMC_DATADIR_WRITE 2 unsigned char data_dir; + unsigned char suspended; /* buffer is used during PIO of one scatterlist segment, and * is updated along with buffer_bytes_left. bytes_left applies @@ -1332,32 +1333,66 @@ static int __exit davinci_mmcsd_remove(struct platform_device *pdev) } #ifdef CONFIG_PM -static int davinci_mmcsd_suspend(struct platform_device *pdev, pm_message_t msg) +static int davinci_mmcsd_suspend(struct device *dev) { + struct platform_device *pdev = to_platform_device(dev); struct mmc_davinci_host *host = platform_get_drvdata(pdev); + struct pm_message msg = { PM_EVENT_SUSPEND }; + int ret; - return mmc_suspend_host(host->mmc, msg); + mmc_host_enable(host->mmc); + ret = mmc_suspend_host(host->mmc, msg); + if (!ret) { + writel(0, host->base + DAVINCI_MMCIM); + mmc_davinci_reset_ctrl(host, 1); + mmc_host_disable(host->mmc); + clk_disable(host->clk); + host->suspended = 1; + } else { + host->suspended = 0; + mmc_host_disable(host->mmc); + } + + return ret; } -static int davinci_mmcsd_resume(struct platform_device *pdev) +static int davinci_mmcsd_resume(struct device *dev) { + struct platform_device *pdev = to_platform_device(dev); struct mmc_davinci_host *host = platform_get_drvdata(pdev); + int ret; - return mmc_resume_host(host->mmc); + if (!host->suspended) + return 0; + + clk_enable(host->clk); + mmc_host_enable(host->mmc); + + mmc_davinci_reset_ctrl(host, 0); + ret = mmc_resume_host(host->mmc); + if (!ret) + host->suspended = 0; + + return ret; } + +static const struct dev_pm_ops davinci_mmcsd_pm = { + .suspend = davinci_mmcsd_suspend, + .resume = davinci_mmcsd_resume, +}; + +#define davinci_mmcsd_pm_ops (&davinci_mmcsd_pm) #else -#define davinci_mmcsd_suspend NULL -#define davinci_mmcsd_resume NULL +#define davinci_mmcsd_pm_ops NULL #endif static struct platform_driver davinci_mmcsd_driver = { .driver = { .name = "davinci_mmc", .owner = THIS_MODULE, + .pm = davinci_mmcsd_pm_ops, }, .remove = __exit_p(davinci_mmcsd_remove), - .suspend = davinci_mmcsd_suspend, - .resume = davinci_mmcsd_resume, }; static int __init davinci_mmcsd_init(void) -- cgit v1.2.3 From 6dd6bca3fb6d4f186cdc67ba9e3949ef456dcc53 Mon Sep 17 00:00:00 2001 From: Mark Asselstine Date: Wed, 26 May 2010 14:41:58 -0700 Subject: mmc: sd: clean up redundant memset The clearing of mrq via a memset at the top of the for loop in mmc_wait_for_app_cmd() is not required as mrq is not used and there is another clearing of mrq just below. We remove the first memset since if the initial tests in the for loop fail the memset is not required. Signed-off-by: Mark Asselstine Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/core/sd_ops.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c index 0d96080d44b0..63772e7e7608 100644 --- a/drivers/mmc/core/sd_ops.c +++ b/drivers/mmc/core/sd_ops.c @@ -79,8 +79,6 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card, * we cannot use the retries field in mmc_command. */ for (i = 0;i <= retries;i++) { - memset(&mrq, 0, sizeof(struct mmc_request)); - err = mmc_app_cmd(host, card); if (err) { /* no point in retrying; no APP commands allowed */ -- cgit v1.2.3 From 99ddffd8ef84c0389e31cb4b90d9e5415ea19cb0 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Wed, 26 May 2010 14:41:59 -0700 Subject: mmc: atmel-mci: enable SD high speed support Enable high speed support for atmel-mci driver. This support is dependent of the revision of the IP and, of course, the capacity of the SD card used. Signed-off-by: Nicolas Ferre Reviewed-by: Haavard Skinnemoen Cc: Maciej Sosnowski Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/host/atmel-mci.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index df0e8a88d85f..f6013ccbc619 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -952,10 +952,21 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (mci_has_rwproof()) host->mode_reg |= (MCI_MR_WRPROOF | MCI_MR_RDPROOF); - if (list_empty(&host->queue)) + if (atmci_is_mci2()) { + /* setup High Speed mode in relation with card capacity */ + if (ios->timing == MMC_TIMING_SD_HS) + host->cfg_reg |= MCI_CFG_HSMODE; + else + host->cfg_reg &= ~MCI_CFG_HSMODE; + } + + if (list_empty(&host->queue)) { mci_writel(host, MR, host->mode_reg); - else + if (atmci_is_mci2()) + mci_writel(host, CFG, host->cfg_reg); + } else { host->need_clock_update = true; + } spin_unlock_bh(&host->lock); } else { @@ -1052,8 +1063,11 @@ static void atmci_request_end(struct atmel_mci *host, struct mmc_request *mrq) * necessary if set_ios() is called when a different slot is * busy transfering data. */ - if (host->need_clock_update) + if (host->need_clock_update) { mci_writel(host, MR, host->mode_reg); + if (atmci_is_mci2()) + mci_writel(host, CFG, host->cfg_reg); + } host->cur_slot->mrq = NULL; host->mrq = NULL; @@ -1565,6 +1579,8 @@ static int __init atmci_init_slot(struct atmel_mci *host, mmc->f_min = DIV_ROUND_UP(host->bus_hz, 512); mmc->f_max = host->bus_hz / 2; mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; + if (atmci_is_mci2()) + mmc->caps |= MMC_CAP_SD_HIGHSPEED; if (slot_data->bus_width >= 4) mmc->caps |= MMC_CAP_4_BIT_DATA; -- cgit v1.2.3 From fdc50a9444b9781f4dd5aa5f7453300d2688cc5f Mon Sep 17 00:00:00 2001 From: Yusuke Goda Date: Wed, 26 May 2010 14:41:59 -0700 Subject: mmc: add support MMCIF for SuperH MMCIF is the MMC Host Interface in SuperH. Signed-off-by: Yusuke Goda Cc: Ben Hutchings Cc: Paul Mundt Cc: Magnus Damm Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/host/Kconfig | 8 + drivers/mmc/host/Makefile | 1 + drivers/mmc/host/sh_mmcif.c | 965 +++++++++++++++++++++++++++++++++++++++++++ include/linux/mmc/sh_mmcif.h | 39 ++ 4 files changed, 1013 insertions(+) create mode 100644 drivers/mmc/host/sh_mmcif.c create mode 100644 include/linux/mmc/sh_mmcif.h (limited to 'drivers') diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 2e13b94769fd..aeecbc932fbd 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -412,3 +412,11 @@ config SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND depends on SDH_BFIN help If you say yes here SD-Cards may work on the EZkit. + +config MMC_SH_MMCIF + tristate "SuperH Internal MMCIF support" + depends on MMC_BLOCK && (SUPERH || ARCH_SHMOBILE) + help + This selects the MMC Host Interface controler (MMCIF). + + This driver supports MMCIF in sh7724/sh7757/sh7372. diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index f4803977dfce..2447b66afeb3 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_MMC_TMIO) += tmio_mmc.o obj-$(CONFIG_MMC_CB710) += cb710-mmc.o obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o +obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o sdhci-of-y := sdhci-of-core.o diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c new file mode 100644 index 000000000000..eb97830c0344 --- /dev/null +++ b/drivers/mmc/host/sh_mmcif.c @@ -0,0 +1,965 @@ +/* + * MMCIF eMMC driver. + * + * Copyright (C) 2010 Renesas Solutions Corp. + * Yusuke Goda + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. + * + * + * TODO + * 1. DMA + * 2. Power management + * 3. Handle MMC errors better + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "sh_mmcif" +#define DRIVER_VERSION "2010-04-28" + +#define MMCIF_CE_CMD_SET 0x00000000 +#define MMCIF_CE_ARG 0x00000008 +#define MMCIF_CE_ARG_CMD12 0x0000000C +#define MMCIF_CE_CMD_CTRL 0x00000010 +#define MMCIF_CE_BLOCK_SET 0x00000014 +#define MMCIF_CE_CLK_CTRL 0x00000018 +#define MMCIF_CE_BUF_ACC 0x0000001C +#define MMCIF_CE_RESP3 0x00000020 +#define MMCIF_CE_RESP2 0x00000024 +#define MMCIF_CE_RESP1 0x00000028 +#define MMCIF_CE_RESP0 0x0000002C +#define MMCIF_CE_RESP_CMD12 0x00000030 +#define MMCIF_CE_DATA 0x00000034 +#define MMCIF_CE_INT 0x00000040 +#define MMCIF_CE_INT_MASK 0x00000044 +#define MMCIF_CE_HOST_STS1 0x00000048 +#define MMCIF_CE_HOST_STS2 0x0000004C +#define MMCIF_CE_VERSION 0x0000007C + +/* CE_CMD_SET */ +#define CMD_MASK 0x3f000000 +#define CMD_SET_RTYP_NO ((0 << 23) | (0 << 22)) +#define CMD_SET_RTYP_6B ((0 << 23) | (1 << 22)) /* R1/R1b/R3/R4/R5 */ +#define CMD_SET_RTYP_17B ((1 << 23) | (0 << 22)) /* R2 */ +#define CMD_SET_RBSY (1 << 21) /* R1b */ +#define CMD_SET_CCSEN (1 << 20) +#define CMD_SET_WDAT (1 << 19) /* 1: on data, 0: no data */ +#define CMD_SET_DWEN (1 << 18) /* 1: write, 0: read */ +#define CMD_SET_CMLTE (1 << 17) /* 1: multi block trans, 0: single */ +#define CMD_SET_CMD12EN (1 << 16) /* 1: CMD12 auto issue */ +#define CMD_SET_RIDXC_INDEX ((0 << 15) | (0 << 14)) /* index check */ +#define CMD_SET_RIDXC_BITS ((0 << 15) | (1 << 14)) /* check bits check */ +#define CMD_SET_RIDXC_NO ((1 << 15) | (0 << 14)) /* no check */ +#define CMD_SET_CRC7C ((0 << 13) | (0 << 12)) /* CRC7 check*/ +#define CMD_SET_CRC7C_BITS ((0 << 13) | (1 << 12)) /* check bits check*/ +#define CMD_SET_CRC7C_INTERNAL ((1 << 13) | (0 << 12)) /* internal CRC7 check*/ +#define CMD_SET_CRC16C (1 << 10) /* 0: CRC16 check*/ +#define CMD_SET_CRCSTE (1 << 8) /* 1: not receive CRC status */ +#define CMD_SET_TBIT (1 << 7) /* 1: tran mission bit "Low" */ +#define CMD_SET_OPDM (1 << 6) /* 1: open/drain */ +#define CMD_SET_CCSH (1 << 5) +#define CMD_SET_DATW_1 ((0 << 1) | (0 << 0)) /* 1bit */ +#define CMD_SET_DATW_4 ((0 << 1) | (1 << 0)) /* 4bit */ +#define CMD_SET_DATW_8 ((1 << 1) | (0 << 0)) /* 8bit */ + +/* CE_CMD_CTRL */ +#define CMD_CTRL_BREAK (1 << 0) + +/* CE_BLOCK_SET */ +#define BLOCK_SIZE_MASK 0x0000ffff + +/* CE_CLK_CTRL */ +#define CLK_ENABLE (1 << 24) /* 1: output mmc clock */ +#define CLK_CLEAR ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16)) +#define CLK_SUP_PCLK ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16)) +#define SRSPTO_256 ((1 << 13) | (0 << 12)) /* resp timeout */ +#define SRBSYTO_29 ((1 << 11) | (1 << 10) | \ + (1 << 9) | (1 << 8)) /* resp busy timeout */ +#define SRWDTO_29 ((1 << 7) | (1 << 6) | \ + (1 << 5) | (1 << 4)) /* read/write timeout */ +#define SCCSTO_29 ((1 << 3) | (1 << 2) | \ + (1 << 1) | (1 << 0)) /* ccs timeout */ + +/* CE_BUF_ACC */ +#define BUF_ACC_DMAWEN (1 << 25) +#define BUF_ACC_DMAREN (1 << 24) +#define BUF_ACC_BUSW_32 (0 << 17) +#define BUF_ACC_BUSW_16 (1 << 17) +#define BUF_ACC_ATYP (1 << 16) + +/* CE_INT */ +#define INT_CCSDE (1 << 29) +#define INT_CMD12DRE (1 << 26) +#define INT_CMD12RBE (1 << 25) +#define INT_CMD12CRE (1 << 24) +#define INT_DTRANE (1 << 23) +#define INT_BUFRE (1 << 22) +#define INT_BUFWEN (1 << 21) +#define INT_BUFREN (1 << 20) +#define INT_CCSRCV (1 << 19) +#define INT_RBSYE (1 << 17) +#define INT_CRSPE (1 << 16) +#define INT_CMDVIO (1 << 15) +#define INT_BUFVIO (1 << 14) +#define INT_WDATERR (1 << 11) +#define INT_RDATERR (1 << 10) +#define INT_RIDXERR (1 << 9) +#define INT_RSPERR (1 << 8) +#define INT_CCSTO (1 << 5) +#define INT_CRCSTO (1 << 4) +#define INT_WDATTO (1 << 3) +#define INT_RDATTO (1 << 2) +#define INT_RBSYTO (1 << 1) +#define INT_RSPTO (1 << 0) +#define INT_ERR_STS (INT_CMDVIO | INT_BUFVIO | INT_WDATERR | \ + INT_RDATERR | INT_RIDXERR | INT_RSPERR | \ + INT_CCSTO | INT_CRCSTO | INT_WDATTO | \ + INT_RDATTO | INT_RBSYTO | INT_RSPTO) + +/* CE_INT_MASK */ +#define MASK_ALL 0x00000000 +#define MASK_MCCSDE (1 << 29) +#define MASK_MCMD12DRE (1 << 26) +#define MASK_MCMD12RBE (1 << 25) +#define MASK_MCMD12CRE (1 << 24) +#define MASK_MDTRANE (1 << 23) +#define MASK_MBUFRE (1 << 22) +#define MASK_MBUFWEN (1 << 21) +#define MASK_MBUFREN (1 << 20) +#define MASK_MCCSRCV (1 << 19) +#define MASK_MRBSYE (1 << 17) +#define MASK_MCRSPE (1 << 16) +#define MASK_MCMDVIO (1 << 15) +#define MASK_MBUFVIO (1 << 14) +#define MASK_MWDATERR (1 << 11) +#define MASK_MRDATERR (1 << 10) +#define MASK_MRIDXERR (1 << 9) +#define MASK_MRSPERR (1 << 8) +#define MASK_MCCSTO (1 << 5) +#define MASK_MCRCSTO (1 << 4) +#define MASK_MWDATTO (1 << 3) +#define MASK_MRDATTO (1 << 2) +#define MASK_MRBSYTO (1 << 1) +#define MASK_MRSPTO (1 << 0) + +/* CE_HOST_STS1 */ +#define STS1_CMDSEQ (1 << 31) + +/* CE_HOST_STS2 */ +#define STS2_CRCSTE (1 << 31) +#define STS2_CRC16E (1 << 30) +#define STS2_AC12CRCE (1 << 29) +#define STS2_RSPCRC7E (1 << 28) +#define STS2_CRCSTEBE (1 << 27) +#define STS2_RDATEBE (1 << 26) +#define STS2_AC12REBE (1 << 25) +#define STS2_RSPEBE (1 << 24) +#define STS2_AC12IDXE (1 << 23) +#define STS2_RSPIDXE (1 << 22) +#define STS2_CCSTO (1 << 15) +#define STS2_RDATTO (1 << 14) +#define STS2_DATBSYTO (1 << 13) +#define STS2_CRCSTTO (1 << 12) +#define STS2_AC12BSYTO (1 << 11) +#define STS2_RSPBSYTO (1 << 10) +#define STS2_AC12RSPTO (1 << 9) +#define STS2_RSPTO (1 << 8) +#define STS2_CRC_ERR (STS2_CRCSTE | STS2_CRC16E | \ + STS2_AC12CRCE | STS2_RSPCRC7E | STS2_CRCSTEBE) +#define STS2_TIMEOUT_ERR (STS2_CCSTO | STS2_RDATTO | \ + STS2_DATBSYTO | STS2_CRCSTTO | \ + STS2_AC12BSYTO | STS2_RSPBSYTO | \ + STS2_AC12RSPTO | STS2_RSPTO) + +/* CE_VERSION */ +#define SOFT_RST_ON (1 << 31) +#define SOFT_RST_OFF (0 << 31) + +#define CLKDEV_EMMC_DATA 52000000 /* 52MHz */ +#define CLKDEV_MMC_DATA 20000000 /* 20MHz */ +#define CLKDEV_INIT 400000 /* 400 KHz */ + +struct sh_mmcif_host { + struct mmc_host *mmc; + struct mmc_data *data; + struct mmc_command *cmd; + struct platform_device *pd; + struct clk *hclk; + unsigned int clk; + int bus_width; + u16 wait_int; + u16 sd_error; + long timeout; + void __iomem *addr; + wait_queue_head_t intr_wait; +}; + +static inline u32 sh_mmcif_readl(struct sh_mmcif_host *host, unsigned int reg) +{ + return readl(host->addr + reg); +} + +static inline void sh_mmcif_writel(struct sh_mmcif_host *host, + unsigned int reg, u32 val) +{ + writel(val, host->addr + reg); +} + +static inline void sh_mmcif_bitset(struct sh_mmcif_host *host, + unsigned int reg, u32 val) +{ + writel(val | sh_mmcif_readl(host, reg), host->addr + reg); +} + +static inline void sh_mmcif_bitclr(struct sh_mmcif_host *host, + unsigned int reg, u32 val) +{ + writel(~val & sh_mmcif_readl(host, reg), host->addr + reg); +} + + +static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk) +{ + struct sh_mmcif_plat_data *p = host->pd->dev.platform_data; + + sh_mmcif_bitclr(host, MMCIF_CE_CLK_CTRL, CLK_ENABLE); + sh_mmcif_bitclr(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR); + + if (!clk) + return; + if (p->sup_pclk && clk == host->clk) + sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_SUP_PCLK); + else + sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR & + (ilog2(__rounddown_pow_of_two(host->clk / clk)) << 16)); + + sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_ENABLE); +} + +static void sh_mmcif_sync_reset(struct sh_mmcif_host *host) +{ + u32 tmp; + + tmp = 0x010f0000 & sh_mmcif_readl(host, MMCIF_CE_CLK_CTRL); + + sh_mmcif_writel(host, MMCIF_CE_VERSION, SOFT_RST_ON); + sh_mmcif_writel(host, MMCIF_CE_VERSION, SOFT_RST_OFF); + sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, tmp | + SRSPTO_256 | SRBSYTO_29 | SRWDTO_29 | SCCSTO_29); + /* byte swap on */ + sh_mmcif_bitset(host, MMCIF_CE_BUF_ACC, BUF_ACC_ATYP); +} + +static int sh_mmcif_error_manage(struct sh_mmcif_host *host) +{ + u32 state1, state2; + int ret, timeout = 10000000; + + host->sd_error = 0; + host->wait_int = 0; + + state1 = sh_mmcif_readl(host, MMCIF_CE_HOST_STS1); + state2 = sh_mmcif_readl(host, MMCIF_CE_HOST_STS2); + pr_debug("%s: ERR HOST_STS1 = %08x\n", \ + DRIVER_NAME, sh_mmcif_readl(host, MMCIF_CE_HOST_STS1)); + pr_debug("%s: ERR HOST_STS2 = %08x\n", \ + DRIVER_NAME, sh_mmcif_readl(host, MMCIF_CE_HOST_STS2)); + + if (state1 & STS1_CMDSEQ) { + sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, CMD_CTRL_BREAK); + sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, ~CMD_CTRL_BREAK); + while (1) { + timeout--; + if (timeout < 0) { + pr_err(DRIVER_NAME": Forceed end of " \ + "command sequence timeout err\n"); + return -EIO; + } + if (!(sh_mmcif_readl(host, MMCIF_CE_HOST_STS1) + & STS1_CMDSEQ)) + break; + mdelay(1); + } + sh_mmcif_sync_reset(host); + pr_debug(DRIVER_NAME": Forced end of command sequence\n"); + return -EIO; + } + + if (state2 & STS2_CRC_ERR) { + pr_debug(DRIVER_NAME": Happened CRC error\n"); + ret = -EIO; + } else if (state2 & STS2_TIMEOUT_ERR) { + pr_debug(DRIVER_NAME": Happened Timeout error\n"); + ret = -ETIMEDOUT; + } else { + pr_debug(DRIVER_NAME": Happened End/Index error\n"); + ret = -EIO; + } + return ret; +} + +static int sh_mmcif_single_read(struct sh_mmcif_host *host, + struct mmc_request *mrq) +{ + struct mmc_data *data = mrq->data; + long time; + u32 blocksize, i, *p = sg_virt(data->sg); + + host->wait_int = 0; + + /* buf read enable */ + sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); + time = wait_event_interruptible_timeout(host->intr_wait, + host->wait_int == 1 || + host->sd_error == 1, host->timeout); + if (host->wait_int != 1 && (time == 0 || host->sd_error != 0)) + return sh_mmcif_error_manage(host); + + host->wait_int = 0; + blocksize = (BLOCK_SIZE_MASK & + sh_mmcif_readl(host, MMCIF_CE_BLOCK_SET)) + 3; + for (i = 0; i < blocksize / 4; i++) + *p++ = sh_mmcif_readl(host, MMCIF_CE_DATA); + + /* buffer read end */ + sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFRE); + time = wait_event_interruptible_timeout(host->intr_wait, + host->wait_int == 1 || + host->sd_error == 1, host->timeout); + if (host->wait_int != 1 && (time == 0 || host->sd_error != 0)) + return sh_mmcif_error_manage(host); + + host->wait_int = 0; + return 0; +} + +static int sh_mmcif_multi_read(struct sh_mmcif_host *host, + struct mmc_request *mrq) +{ + struct mmc_data *data = mrq->data; + long time; + u32 blocksize, i, j, sec, *p; + + blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host, MMCIF_CE_BLOCK_SET); + for (j = 0; j < data->sg_len; j++) { + p = sg_virt(data->sg); + host->wait_int = 0; + for (sec = 0; sec < data->sg->length / blocksize; sec++) { + sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); + /* buf read enable */ + time = wait_event_interruptible_timeout(host->intr_wait, + host->wait_int == 1 || + host->sd_error == 1, host->timeout); + + if (host->wait_int != 1 && + (time == 0 || host->sd_error != 0)) + return sh_mmcif_error_manage(host); + + host->wait_int = 0; + for (i = 0; i < blocksize / 4; i++) + *p++ = sh_mmcif_readl(host, MMCIF_CE_DATA); + } + if (j < data->sg_len - 1) + data->sg++; + } + return 0; +} + +static int sh_mmcif_single_write(struct sh_mmcif_host *host, + struct mmc_request *mrq) +{ + struct mmc_data *data = mrq->data; + long time; + u32 blocksize, i, *p = sg_virt(data->sg); + + host->wait_int = 0; + sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); + + /* buf write enable */ + time = wait_event_interruptible_timeout(host->intr_wait, + host->wait_int == 1 || + host->sd_error == 1, host->timeout); + if (host->wait_int != 1 && (time == 0 || host->sd_error != 0)) + return sh_mmcif_error_manage(host); + + host->wait_int = 0; + blocksize = (BLOCK_SIZE_MASK & + sh_mmcif_readl(host, MMCIF_CE_BLOCK_SET)) + 3; + for (i = 0; i < blocksize / 4; i++) + sh_mmcif_writel(host, MMCIF_CE_DATA, *p++); + + /* buffer write end */ + sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MDTRANE); + + time = wait_event_interruptible_timeout(host->intr_wait, + host->wait_int == 1 || + host->sd_error == 1, host->timeout); + if (host->wait_int != 1 && (time == 0 || host->sd_error != 0)) + return sh_mmcif_error_manage(host); + + host->wait_int = 0; + return 0; +} + +static int sh_mmcif_multi_write(struct sh_mmcif_host *host, + struct mmc_request *mrq) +{ + struct mmc_data *data = mrq->data; + long time; + u32 i, sec, j, blocksize, *p; + + blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host, MMCIF_CE_BLOCK_SET); + + for (j = 0; j < data->sg_len; j++) { + p = sg_virt(data->sg); + host->wait_int = 0; + for (sec = 0; sec < data->sg->length / blocksize; sec++) { + sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); + /* buf write enable*/ + time = wait_event_interruptible_timeout(host->intr_wait, + host->wait_int == 1 || + host->sd_error == 1, host->timeout); + + if (host->wait_int != 1 && + (time == 0 || host->sd_error != 0)) + return sh_mmcif_error_manage(host); + + host->wait_int = 0; + for (i = 0; i < blocksize / 4; i++) + sh_mmcif_writel(host, MMCIF_CE_DATA, *p++); + } + if (j < data->sg_len - 1) + data->sg++; + } + return 0; +} + +static void sh_mmcif_get_response(struct sh_mmcif_host *host, + struct mmc_command *cmd) +{ + if (cmd->flags & MMC_RSP_136) { + cmd->resp[0] = sh_mmcif_readl(host, MMCIF_CE_RESP3); + cmd->resp[1] = sh_mmcif_readl(host, MMCIF_CE_RESP2); + cmd->resp[2] = sh_mmcif_readl(host, MMCIF_CE_RESP1); + cmd->resp[3] = sh_mmcif_readl(host, MMCIF_CE_RESP0); + } else + cmd->resp[0] = sh_mmcif_readl(host, MMCIF_CE_RESP0); +} + +static void sh_mmcif_get_cmd12response(struct sh_mmcif_host *host, + struct mmc_command *cmd) +{ + cmd->resp[0] = sh_mmcif_readl(host, MMCIF_CE_RESP_CMD12); +} + +static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host, + struct mmc_request *mrq, struct mmc_command *cmd, u32 opc) +{ + u32 tmp = 0; + + /* Response Type check */ + switch (mmc_resp_type(cmd)) { + case MMC_RSP_NONE: + tmp |= CMD_SET_RTYP_NO; + break; + case MMC_RSP_R1: + case MMC_RSP_R1B: + case MMC_RSP_R3: + tmp |= CMD_SET_RTYP_6B; + break; + case MMC_RSP_R2: + tmp |= CMD_SET_RTYP_17B; + break; + default: + pr_err(DRIVER_NAME": Not support type response.\n"); + break; + } + switch (opc) { + /* RBSY */ + case MMC_SWITCH: + case MMC_STOP_TRANSMISSION: + case MMC_SET_WRITE_PROT: + case MMC_CLR_WRITE_PROT: + case MMC_ERASE: + case MMC_GEN_CMD: + tmp |= CMD_SET_RBSY; + break; + } + /* WDAT / DATW */ + if (host->data) { + tmp |= CMD_SET_WDAT; + switch (host->bus_width) { + case MMC_BUS_WIDTH_1: + tmp |= CMD_SET_DATW_1; + break; + case MMC_BUS_WIDTH_4: + tmp |= CMD_SET_DATW_4; + break; + case MMC_BUS_WIDTH_8: + tmp |= CMD_SET_DATW_8; + break; + default: + pr_err(DRIVER_NAME": Not support bus width.\n"); + break; + } + } + /* DWEN */ + if (opc == MMC_WRITE_BLOCK || opc == MMC_WRITE_MULTIPLE_BLOCK) + tmp |= CMD_SET_DWEN; + /* CMLTE/CMD12EN */ + if (opc == MMC_READ_MULTIPLE_BLOCK || opc == MMC_WRITE_MULTIPLE_BLOCK) { + tmp |= CMD_SET_CMLTE | CMD_SET_CMD12EN; + sh_mmcif_bitset(host, MMCIF_CE_BLOCK_SET, + mrq->data->blocks << 16); + } + /* RIDXC[1:0] check bits */ + if (opc == MMC_SEND_OP_COND || opc == MMC_ALL_SEND_CID || + opc == MMC_SEND_CSD || opc == MMC_SEND_CID) + tmp |= CMD_SET_RIDXC_BITS; + /* RCRC7C[1:0] check bits */ + if (opc == MMC_SEND_OP_COND) + tmp |= CMD_SET_CRC7C_BITS; + /* RCRC7C[1:0] internal CRC7 */ + if (opc == MMC_ALL_SEND_CID || + opc == MMC_SEND_CSD || opc == MMC_SEND_CID) + tmp |= CMD_SET_CRC7C_INTERNAL; + + return opc = ((opc << 24) | tmp); +} + +static u32 sh_mmcif_data_trans(struct sh_mmcif_host *host, + struct mmc_request *mrq, u32 opc) +{ + u32 ret; + + switch (opc) { + case MMC_READ_MULTIPLE_BLOCK: + ret = sh_mmcif_multi_read(host, mrq); + break; + case MMC_WRITE_MULTIPLE_BLOCK: + ret = sh_mmcif_multi_write(host, mrq); + break; + case MMC_WRITE_BLOCK: + ret = sh_mmcif_single_write(host, mrq); + break; + case MMC_READ_SINGLE_BLOCK: + case MMC_SEND_EXT_CSD: + ret = sh_mmcif_single_read(host, mrq); + break; + default: + pr_err(DRIVER_NAME": NOT SUPPORT CMD = d'%08d\n", opc); + ret = -EINVAL; + break; + } + return ret; +} + +static void sh_mmcif_start_cmd(struct sh_mmcif_host *host, + struct mmc_request *mrq, struct mmc_command *cmd) +{ + long time; + int ret = 0, mask = 0; + u32 opc = cmd->opcode; + + host->cmd = cmd; + + switch (opc) { + /* respons busy check */ + case MMC_SWITCH: + case MMC_STOP_TRANSMISSION: + case MMC_SET_WRITE_PROT: + case MMC_CLR_WRITE_PROT: + case MMC_ERASE: + case MMC_GEN_CMD: + mask = MASK_MRBSYE; + break; + default: + mask = MASK_MCRSPE; + break; + } + mask |= MASK_MCMDVIO | MASK_MBUFVIO | MASK_MWDATERR | + MASK_MRDATERR | MASK_MRIDXERR | MASK_MRSPERR | + MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO | + MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO; + + if (host->data) { + sh_mmcif_writel(host, MMCIF_CE_BLOCK_SET, 0); + sh_mmcif_writel(host, MMCIF_CE_BLOCK_SET, mrq->data->blksz); + } + opc = sh_mmcif_set_cmd(host, mrq, cmd, opc); + + sh_mmcif_writel(host, MMCIF_CE_INT, 0xD80430C0); + sh_mmcif_writel(host, MMCIF_CE_INT_MASK, mask); + /* set arg */ + sh_mmcif_writel(host, MMCIF_CE_ARG, cmd->arg); + host->wait_int = 0; + /* set cmd */ + sh_mmcif_writel(host, MMCIF_CE_CMD_SET, opc); + + time = wait_event_interruptible_timeout(host->intr_wait, + host->wait_int == 1 || host->sd_error == 1, host->timeout); + if (host->wait_int != 1 && time == 0) { + cmd->error = sh_mmcif_error_manage(host); + return; + } + if (host->sd_error) { + switch (cmd->opcode) { + case MMC_ALL_SEND_CID: + case MMC_SELECT_CARD: + case MMC_APP_CMD: + cmd->error = -ETIMEDOUT; + break; + default: + pr_debug("%s: Cmd(d'%d) err\n", + DRIVER_NAME, cmd->opcode); + cmd->error = sh_mmcif_error_manage(host); + break; + } + host->sd_error = 0; + host->wait_int = 0; + return; + } + if (!(cmd->flags & MMC_RSP_PRESENT)) { + cmd->error = ret; + host->wait_int = 0; + return; + } + if (host->wait_int == 1) { + sh_mmcif_get_response(host, cmd); + host->wait_int = 0; + } + if (host->data) { + ret = sh_mmcif_data_trans(host, mrq, cmd->opcode); + if (ret < 0) + mrq->data->bytes_xfered = 0; + else + mrq->data->bytes_xfered = + mrq->data->blocks * mrq->data->blksz; + } + cmd->error = ret; +} + +static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host, + struct mmc_request *mrq, struct mmc_command *cmd) +{ + long time; + + if (mrq->cmd->opcode == MMC_READ_MULTIPLE_BLOCK) + sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12DRE); + else if (mrq->cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK) + sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE); + else { + pr_err(DRIVER_NAME": not support stop cmd\n"); + cmd->error = sh_mmcif_error_manage(host); + return; + } + + time = wait_event_interruptible_timeout(host->intr_wait, + host->wait_int == 1 || + host->sd_error == 1, host->timeout); + if (host->wait_int != 1 && (time == 0 || host->sd_error != 0)) { + cmd->error = sh_mmcif_error_manage(host); + return; + } + sh_mmcif_get_cmd12response(host, cmd); + host->wait_int = 0; + cmd->error = 0; +} + +static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct sh_mmcif_host *host = mmc_priv(mmc); + + switch (mrq->cmd->opcode) { + /* MMCIF does not support SD/SDIO command */ + case SD_IO_SEND_OP_COND: + case MMC_APP_CMD: + mrq->cmd->error = -ETIMEDOUT; + mmc_request_done(mmc, mrq); + return; + case MMC_SEND_EXT_CSD: /* = SD_SEND_IF_COND (8) */ + if (!mrq->data) { + /* send_if_cond cmd (not support) */ + mrq->cmd->error = -ETIMEDOUT; + mmc_request_done(mmc, mrq); + return; + } + break; + default: + break; + } + host->data = mrq->data; + sh_mmcif_start_cmd(host, mrq, mrq->cmd); + host->data = NULL; + + if (mrq->cmd->error != 0) { + mmc_request_done(mmc, mrq); + return; + } + if (mrq->stop) + sh_mmcif_stop_cmd(host, mrq, mrq->stop); + mmc_request_done(mmc, mrq); +} + +static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct sh_mmcif_host *host = mmc_priv(mmc); + struct sh_mmcif_plat_data *p = host->pd->dev.platform_data; + + if (ios->power_mode == MMC_POWER_OFF) { + /* clock stop */ + sh_mmcif_clock_control(host, 0); + if (p->down_pwr) + p->down_pwr(host->pd); + return; + } else if (ios->power_mode == MMC_POWER_UP) { + if (p->set_pwr) + p->set_pwr(host->pd, ios->power_mode); + } + + if (ios->clock) + sh_mmcif_clock_control(host, ios->clock); + + host->bus_width = ios->bus_width; +} + +static struct mmc_host_ops sh_mmcif_ops = { + .request = sh_mmcif_request, + .set_ios = sh_mmcif_set_ios, +}; + +static void sh_mmcif_detect(struct mmc_host *mmc) +{ + mmc_detect_change(mmc, 0); +} + +static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) +{ + struct sh_mmcif_host *host = dev_id; + u32 state = 0; + int err = 0; + + state = sh_mmcif_readl(host, MMCIF_CE_INT); + + if (state & INT_RBSYE) { + sh_mmcif_writel(host, MMCIF_CE_INT, ~(INT_RBSYE | INT_CRSPE)); + sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MRBSYE); + } else if (state & INT_CRSPE) { + sh_mmcif_writel(host, MMCIF_CE_INT, ~INT_CRSPE); + sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCRSPE); + } else if (state & INT_BUFREN) { + sh_mmcif_writel(host, MMCIF_CE_INT, ~INT_BUFREN); + sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); + } else if (state & INT_BUFWEN) { + sh_mmcif_writel(host, MMCIF_CE_INT, ~INT_BUFWEN); + sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); + } else if (state & INT_CMD12DRE) { + sh_mmcif_writel(host, MMCIF_CE_INT, + ~(INT_CMD12DRE | INT_CMD12RBE | + INT_CMD12CRE | INT_BUFRE)); + sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12DRE); + } else if (state & INT_BUFRE) { + sh_mmcif_writel(host, MMCIF_CE_INT, ~INT_BUFRE); + sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFRE); + } else if (state & INT_DTRANE) { + sh_mmcif_writel(host, MMCIF_CE_INT, ~INT_DTRANE); + sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MDTRANE); + } else if (state & INT_CMD12RBE) { + sh_mmcif_writel(host, MMCIF_CE_INT, + ~(INT_CMD12RBE | INT_CMD12CRE)); + sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE); + } else if (state & INT_ERR_STS) { + /* err interrupts */ + sh_mmcif_writel(host, MMCIF_CE_INT, ~state); + sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state); + err = 1; + } else { + pr_debug("%s: Not support int\n", DRIVER_NAME); + sh_mmcif_writel(host, MMCIF_CE_INT, ~state); + sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state); + err = 1; + } + if (err) { + host->sd_error = 1; + pr_debug("%s: int err state = %08x\n", DRIVER_NAME, state); + } + host->wait_int = 1; + wake_up(&host->intr_wait); + + return IRQ_HANDLED; +} + +static int __devinit sh_mmcif_probe(struct platform_device *pdev) +{ + int ret = 0, irq[2]; + struct mmc_host *mmc; + struct sh_mmcif_host *host = NULL; + struct sh_mmcif_plat_data *pd = NULL; + struct resource *res; + void __iomem *reg; + char clk_name[8]; + + irq[0] = platform_get_irq(pdev, 0); + irq[1] = platform_get_irq(pdev, 1); + if (irq[0] < 0 || irq[1] < 0) { + pr_err(DRIVER_NAME": Get irq error\n"); + return -ENXIO; + } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "platform_get_resource error.\n"); + return -ENXIO; + } + reg = ioremap(res->start, resource_size(res)); + if (!reg) { + dev_err(&pdev->dev, "ioremap error.\n"); + return -ENOMEM; + } + pd = (struct sh_mmcif_plat_data *)(pdev->dev.platform_data); + if (!pd) { + dev_err(&pdev->dev, "sh_mmcif plat data error.\n"); + ret = -ENXIO; + goto clean_up; + } + mmc = mmc_alloc_host(sizeof(struct sh_mmcif_host), &pdev->dev); + if (!mmc) { + ret = -ENOMEM; + goto clean_up; + } + host = mmc_priv(mmc); + host->mmc = mmc; + host->addr = reg; + host->timeout = 1000; + + snprintf(clk_name, sizeof(clk_name), "mmc%d", pdev->id); + host->hclk = clk_get(&pdev->dev, clk_name); + if (IS_ERR(host->hclk)) { + dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); + ret = PTR_ERR(host->hclk); + goto clean_up1; + } + clk_enable(host->hclk); + host->clk = clk_get_rate(host->hclk); + host->pd = pdev; + + init_waitqueue_head(&host->intr_wait); + + mmc->ops = &sh_mmcif_ops; + mmc->f_max = host->clk; + /* close to 400KHz */ + if (mmc->f_max < 51200000) + mmc->f_min = mmc->f_max / 128; + else if (mmc->f_max < 102400000) + mmc->f_min = mmc->f_max / 256; + else + mmc->f_min = mmc->f_max / 512; + if (pd->ocr) + mmc->ocr_avail = pd->ocr; + mmc->caps = MMC_CAP_MMC_HIGHSPEED; + if (pd->caps) + mmc->caps |= pd->caps; + mmc->max_phys_segs = 128; + mmc->max_hw_segs = 128; + mmc->max_blk_size = 512; + mmc->max_blk_count = 65535; + mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; + mmc->max_seg_size = mmc->max_req_size; + + sh_mmcif_sync_reset(host); + platform_set_drvdata(pdev, host); + mmc_add_host(mmc); + + ret = request_irq(irq[0], sh_mmcif_intr, 0, "sh_mmc:error", host); + if (ret) { + pr_err(DRIVER_NAME": request_irq error (sh_mmc:error)\n"); + goto clean_up2; + } + ret = request_irq(irq[1], sh_mmcif_intr, 0, "sh_mmc:int", host); + if (ret) { + free_irq(irq[0], host); + pr_err(DRIVER_NAME": request_irq error (sh_mmc:int)\n"); + goto clean_up2; + } + + sh_mmcif_writel(host, MMCIF_CE_INT_MASK, MASK_ALL); + sh_mmcif_detect(host->mmc); + + pr_info("%s: driver version %s\n", DRIVER_NAME, DRIVER_VERSION); + pr_debug("%s: chip ver H'%04x\n", DRIVER_NAME, + sh_mmcif_readl(host, MMCIF_CE_VERSION) & 0x0000ffff); + return ret; + +clean_up2: + clk_disable(host->hclk); +clean_up1: + mmc_free_host(mmc); +clean_up: + if (reg) + iounmap(reg); + return ret; +} + +static int __devexit sh_mmcif_remove(struct platform_device *pdev) +{ + struct sh_mmcif_host *host = platform_get_drvdata(pdev); + int irq[2]; + + sh_mmcif_writel(host, MMCIF_CE_INT_MASK, MASK_ALL); + + irq[0] = platform_get_irq(pdev, 0); + irq[1] = platform_get_irq(pdev, 1); + + if (host->addr) + iounmap(host->addr); + + platform_set_drvdata(pdev, NULL); + mmc_remove_host(host->mmc); + + free_irq(irq[0], host); + free_irq(irq[1], host); + + clk_disable(host->hclk); + mmc_free_host(host->mmc); + + return 0; +} + +static struct platform_driver sh_mmcif_driver = { + .probe = sh_mmcif_probe, + .remove = sh_mmcif_remove, + .driver = { + .name = DRIVER_NAME, + }, +}; + +static int __init sh_mmcif_init(void) +{ + return platform_driver_register(&sh_mmcif_driver); +} + +static void __exit sh_mmcif_exit(void) +{ + platform_driver_unregister(&sh_mmcif_driver); +} + +module_init(sh_mmcif_init); +module_exit(sh_mmcif_exit); + + +MODULE_DESCRIPTION("SuperH on-chip MMC/eMMC interface driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS(DRIVER_NAME); +MODULE_AUTHOR("Yusuke Goda "); diff --git a/include/linux/mmc/sh_mmcif.h b/include/linux/mmc/sh_mmcif.h new file mode 100644 index 000000000000..aafe832f18aa --- /dev/null +++ b/include/linux/mmc/sh_mmcif.h @@ -0,0 +1,39 @@ +/* + * include/linux/mmc/sh_mmcif.h + * + * platform data for eMMC driver + * + * Copyright (C) 2010 Renesas Solutions Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. + * + */ + +#ifndef __SH_MMCIF_H__ +#define __SH_MMCIF_H__ + +/* + * MMCIF : CE_CLK_CTRL [19:16] + * 1000 : Peripheral clock / 512 + * 0111 : Peripheral clock / 256 + * 0110 : Peripheral clock / 128 + * 0101 : Peripheral clock / 64 + * 0100 : Peripheral clock / 32 + * 0011 : Peripheral clock / 16 + * 0010 : Peripheral clock / 8 + * 0001 : Peripheral clock / 4 + * 0000 : Peripheral clock / 2 + * 1111 : Peripheral clock (sup_pclk set '1') + */ + +struct sh_mmcif_plat_data { + void (*set_pwr)(struct platform_device *pdev, int state); + void (*down_pwr)(struct platform_device *pdev); + u8 sup_pclk; /* 1 :SH7757, 0: SH7724/SH7372 */ + unsigned long caps; + u32 ocr; +}; + +#endif /* __SH_MMCIF_H__ */ -- cgit v1.2.3 From 88ff82ed4ff048c5548db9313b3de327c91234f8 Mon Sep 17 00:00:00 2001 From: Anders Grahn Date: Wed, 26 May 2010 14:42:01 -0700 Subject: mmc: atmel-mci: Add support for SDIO interrupts Atmel-mci support for SDIO interrupts. This adds the enable_sdio_irq() function and the configuration of sdio irq mask per slot. With this irq mask information, we keep the idea of multiple slot per sd/mmc host (not only A and B). MMC_CAP_SDIO_IRQ is added according to slot configuration. A new little function is added to run mmc_signal_sdio_irq() during interrupt handling routine. Signed-off-by: Anders Grahn Signed-off-by: Nicolas Ferre Cc: Haavard Skinnemoen Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/host/atmel-mci.c | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index f6013ccbc619..95ef864ad8f9 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -173,6 +173,7 @@ struct atmel_mci { * @mmc: The mmc_host representing this slot. * @host: The MMC controller this slot is using. * @sdc_reg: Value of SDCR to be written before using this slot. + * @sdio_irq: SDIO irq mask for this slot. * @mrq: mmc_request currently being processed or waiting to be * processed, or NULL when the slot is idle. * @queue_node: List node for placing this node in the @queue list of @@ -191,6 +192,7 @@ struct atmel_mci_slot { struct atmel_mci *host; u32 sdc_reg; + u32 sdio_irq; struct mmc_request *mrq; struct list_head queue_node; @@ -792,7 +794,7 @@ static void atmci_start_request(struct atmel_mci *host, mci_writel(host, SDCR, slot->sdc_reg); iflags = mci_readl(host, IMR); - if (iflags) + if (iflags & ~(MCI_SDIOIRQA | MCI_SDIOIRQB)) dev_warn(&slot->mmc->class_dev, "WARNING: IMR=0x%08x\n", iflags); @@ -1041,11 +1043,23 @@ static int atmci_get_cd(struct mmc_host *mmc) return present; } +static void atmci_enable_sdio_irq(struct mmc_host *mmc, int enable) +{ + struct atmel_mci_slot *slot = mmc_priv(mmc); + struct atmel_mci *host = slot->host; + + if (enable) + mci_writel(host, IER, slot->sdio_irq); + else + mci_writel(host, IDR, slot->sdio_irq); +} + static const struct mmc_host_ops atmci_ops = { .request = atmci_request, .set_ios = atmci_set_ios, .get_ro = atmci_get_ro, .get_cd = atmci_get_cd, + .enable_sdio_irq = atmci_enable_sdio_irq, }; /* Called with host->lock held */ @@ -1497,6 +1511,19 @@ static void atmci_cmd_interrupt(struct atmel_mci *host, u32 status) tasklet_schedule(&host->tasklet); } +static void atmci_sdio_interrupt(struct atmel_mci *host, u32 status) +{ + int i; + + for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) { + struct atmel_mci_slot *slot = host->slot[i]; + if (slot && (status & slot->sdio_irq)) { + mmc_signal_sdio_irq(slot->mmc); + } + } +} + + static irqreturn_t atmci_interrupt(int irq, void *dev_id) { struct atmel_mci *host = dev_id; @@ -1536,6 +1563,10 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id) if (pending & MCI_CMDRDY) atmci_cmd_interrupt(host, status); + + if (pending & (MCI_SDIOIRQA | MCI_SDIOIRQB)) + atmci_sdio_interrupt(host, status); + } while (pass_count++ < 5); return pass_count ? IRQ_HANDLED : IRQ_NONE; @@ -1558,7 +1589,7 @@ static irqreturn_t atmci_detect_interrupt(int irq, void *dev_id) static int __init atmci_init_slot(struct atmel_mci *host, struct mci_slot_pdata *slot_data, unsigned int id, - u32 sdc_reg) + u32 sdc_reg, u32 sdio_irq) { struct mmc_host *mmc; struct atmel_mci_slot *slot; @@ -1574,11 +1605,14 @@ static int __init atmci_init_slot(struct atmel_mci *host, slot->wp_pin = slot_data->wp_pin; slot->detect_is_active_high = slot_data->detect_is_active_high; slot->sdc_reg = sdc_reg; + slot->sdio_irq = sdio_irq; mmc->ops = &atmci_ops; mmc->f_min = DIV_ROUND_UP(host->bus_hz, 512); mmc->f_max = host->bus_hz / 2; mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; + if (sdio_irq) + mmc->caps |= MMC_CAP_SDIO_IRQ; if (atmci_is_mci2()) mmc->caps |= MMC_CAP_SD_HIGHSPEED; if (slot_data->bus_width >= 4) @@ -1769,13 +1803,13 @@ static int __init atmci_probe(struct platform_device *pdev) ret = -ENODEV; if (pdata->slot[0].bus_width) { ret = atmci_init_slot(host, &pdata->slot[0], - 0, MCI_SDCSEL_SLOT_A); + 0, MCI_SDCSEL_SLOT_A, MCI_SDIOIRQA); if (!ret) nr_slots++; } if (pdata->slot[1].bus_width) { ret = atmci_init_slot(host, &pdata->slot[1], - 1, MCI_SDCSEL_SLOT_B); + 1, MCI_SDCSEL_SLOT_B, MCI_SDIOIRQB); if (!ret) nr_slots++; } -- cgit v1.2.3 From a751a7d69fe91e4640884ae02fe44ddceb7f4cd8 Mon Sep 17 00:00:00 2001 From: Zhangfei Gao Date: Wed, 26 May 2010 14:42:02 -0700 Subject: mmc: SDHCI_INT_DATA_MASK typo error Signed-off-by: Zhangfei Gao Reviewed-by: Matt Fleming Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/host/sdhci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 831bf7f137f6..47c1360cc2a3 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -127,7 +127,7 @@ #define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \ SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \ SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \ - SDHCI_INT_DATA_END_BIT | SDHCI_ADMA_ERROR) + SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR) #define SDHCI_INT_ALL_MASK ((unsigned int)-1) #define SDHCI_ACMD12_ERR 0x3C -- cgit v1.2.3 From dc297c92e6e63af5cbd7e7d2f377247f5664a378 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Wed, 26 May 2010 14:42:03 -0700 Subject: sdhci: build fix: rename SDHCI I/O accessor functions Unfortunately some architectures #define their read{b,w,l} and write{b,w,l} I/O accessors which makes the SDHCI I/O accessor functions of the same names subject to preprocessing. This leads to the following compiler error, In file included from drivers/mmc/host/sdhci.c:26: drivers/mmc/host/sdhci.h:318:35: error: macro "writel" passed 3 arguments, but takes just 2 Rename the SDHCI I/O functions so that CONFIG_MMC_SDHCI_IO_ACCESSORS can be enabled for architectures that implement their read{b,w,l} and write{b,w,l} functions with macros. Signed-off-by: Matt Fleming Cc: Zhangfei Gao Acked-by: Anton Vorontsov Acked-by: Wolfram Sang Acked-by: Ben Dooks Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/host/sdhci-of-esdhc.c | 12 ++++++------ drivers/mmc/host/sdhci-of-hlwd.c | 12 ++++++------ drivers/mmc/host/sdhci.h | 36 ++++++++++++++++++------------------ 3 files changed, 30 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index d5b11a17e648..c8623de13af3 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -129,12 +129,12 @@ struct sdhci_of_data sdhci_esdhc = { SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET | SDHCI_QUIRK_NO_CARD_NO_RESET, .ops = { - .readl = sdhci_be32bs_readl, - .readw = esdhc_readw, - .readb = sdhci_be32bs_readb, - .writel = sdhci_be32bs_writel, - .writew = esdhc_writew, - .writeb = esdhc_writeb, + .read_l = sdhci_be32bs_readl, + .read_w = esdhc_readw, + .read_b = sdhci_be32bs_readb, + .write_l = sdhci_be32bs_writel, + .write_w = esdhc_writew, + .write_b = esdhc_writeb, .set_clock = esdhc_set_clock, .enable_dma = esdhc_enable_dma, .get_max_clock = esdhc_get_max_clock, diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c index 35117f3ed757..68ddb7546ae2 100644 --- a/drivers/mmc/host/sdhci-of-hlwd.c +++ b/drivers/mmc/host/sdhci-of-hlwd.c @@ -55,11 +55,11 @@ struct sdhci_of_data sdhci_hlwd = { .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_32BIT_DMA_SIZE, .ops = { - .readl = sdhci_be32bs_readl, - .readw = sdhci_be32bs_readw, - .readb = sdhci_be32bs_readb, - .writel = sdhci_hlwd_writel, - .writew = sdhci_hlwd_writew, - .writeb = sdhci_hlwd_writeb, + .read_l = sdhci_be32bs_readl, + .read_w = sdhci_be32bs_readw, + .read_b = sdhci_be32bs_readb, + .write_l = sdhci_hlwd_writel, + .write_w = sdhci_hlwd_writew, + .write_b = sdhci_hlwd_writeb, }, }; diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 47c1360cc2a3..af08a1935b06 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -296,12 +296,12 @@ struct sdhci_host { struct sdhci_ops { #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS - u32 (*readl)(struct sdhci_host *host, int reg); - u16 (*readw)(struct sdhci_host *host, int reg); - u8 (*readb)(struct sdhci_host *host, int reg); - void (*writel)(struct sdhci_host *host, u32 val, int reg); - void (*writew)(struct sdhci_host *host, u16 val, int reg); - void (*writeb)(struct sdhci_host *host, u8 val, int reg); + u32 (*read_l)(struct sdhci_host *host, int reg); + u16 (*read_w)(struct sdhci_host *host, int reg); + u8 (*read_b)(struct sdhci_host *host, int reg); + void (*write_l)(struct sdhci_host *host, u32 val, int reg); + void (*write_w)(struct sdhci_host *host, u16 val, int reg); + void (*write_b)(struct sdhci_host *host, u8 val, int reg); #endif void (*set_clock)(struct sdhci_host *host, unsigned int clock); @@ -316,48 +316,48 @@ struct sdhci_ops { static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg) { - if (unlikely(host->ops->writel)) - host->ops->writel(host, val, reg); + if (unlikely(host->ops->write_l)) + host->ops->write_l(host, val, reg); else writel(val, host->ioaddr + reg); } static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg) { - if (unlikely(host->ops->writew)) - host->ops->writew(host, val, reg); + if (unlikely(host->ops->write_w)) + host->ops->write_w(host, val, reg); else writew(val, host->ioaddr + reg); } static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg) { - if (unlikely(host->ops->writeb)) - host->ops->writeb(host, val, reg); + if (unlikely(host->ops->write_b)) + host->ops->write_b(host, val, reg); else writeb(val, host->ioaddr + reg); } static inline u32 sdhci_readl(struct sdhci_host *host, int reg) { - if (unlikely(host->ops->readl)) - return host->ops->readl(host, reg); + if (unlikely(host->ops->read_l)) + return host->ops->read_l(host, reg); else return readl(host->ioaddr + reg); } static inline u16 sdhci_readw(struct sdhci_host *host, int reg) { - if (unlikely(host->ops->readw)) - return host->ops->readw(host, reg); + if (unlikely(host->ops->read_w)) + return host->ops->read_w(host, reg); else return readw(host->ioaddr + reg); } static inline u8 sdhci_readb(struct sdhci_host *host, int reg) { - if (unlikely(host->ops->readb)) - return host->ops->readb(host, reg); + if (unlikely(host->ops->read_b)) + return host->ops->read_b(host, reg); else return readb(host->ioaddr + reg); } -- cgit v1.2.3 From 70764a905785ebacc8d44fed7a12fba3db267ae6 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Wed, 26 May 2010 14:42:04 -0700 Subject: mmc: s3c6410: add new quirk in sdhci driver and update ADMA descriptor build The s3c6410 sdhci controller does not support the 'End' attribute and NOP attribute in the same 8-Byte ADMA descriptor. This patch adds a new quirk to identify sdhci host contollers with such behaviour. In addition to this, for controllers using the new quirk, the last entry in the ADMA descritor table is marked with the 'End' attribute (instead of using a NOP descriptor with 'End' attribute). Signed-off-by: Maurus Cuelenaere Signed-off-by: Thomas Abraham Acked-by: Ben Dooks Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/host/sdhci.c | 20 +++++++++++++++----- drivers/mmc/host/sdhci.h | 2 ++ 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 02b365f5a4be..d27cc9178041 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -496,12 +496,22 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, WARN_ON((desc - host->adma_desc) > (128 * 2 + 1) * 4); } - /* - * Add a terminating entry. - */ + if (host->quirks & SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC) { + /* + * Mark the last descriptor as the terminating descriptor + */ + if (desc != host->adma_desc) { + desc -= 8; + desc[0] |= 0x2; /* end */ + } + } else { + /* + * Add a terminating entry. + */ - /* nop, end, valid */ - sdhci_set_adma_desc(desc, 0, 0, 0x3); + /* nop, end, valid */ + sdhci_set_adma_desc(desc, 0, 0, 0x3); + } /* * Resync align buffer as we might have changed it. diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index af08a1935b06..c8468134adc9 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -238,6 +238,8 @@ struct sdhci_host { #define SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK (1<<24) /* Controller reports wrong base clock capability */ #define SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN (1<<25) +/* Controller cannot support End Attribute in NOP ADMA descriptor */ +#define SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC (1<<26) int irq; /* Device IRQ */ void __iomem * ioaddr; /* Mapped address */ -- cgit v1.2.3 From b2e75eff5e859d0c294e7405958362b26a423c6e Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Wed, 26 May 2010 14:42:05 -0700 Subject: mmc: s3c6410: enable ADMA feature in 6410 sdhci controller Enable the ADMA feature in the 6410 SDHCI controller driver. Signed-off-by: Maurus Cuelenaere Signed-off-by: Thomas Abraham Acked-by: Ben Dooks Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/host/sdhci-s3c.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 2136794c0cfa..ad3a78edeb8a 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c @@ -317,12 +317,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) host->irq = irq; /* Setup quirks for the controller */ - - /* Currently with ADMA enabled we are getting some length - * interrupts that are not being dealt with, do disable - * ADMA until this is sorted out. */ - host->quirks |= SDHCI_QUIRK_BROKEN_ADMA; - host->quirks |= SDHCI_QUIRK_32BIT_ADMA_SIZE; + host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC; #ifndef CONFIG_MMC_SDHCI_S3C_DMA -- cgit v1.2.3 From 14c5aa6d3797c6b3d09193a8423472847f738526 Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Wed, 26 May 2010 14:42:05 -0700 Subject: sdhci: enable multiblock transfers in sdhci-s3c Wifi over SDIO doesn't work correctly without multiblock, so enable this. This patch depends on the following patches: Signed-off-by: Maurus Cuelenaere Cc: Thomas Abraham Cc: Ben Dooks Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/host/sdhci-s3c.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index ad3a78edeb8a..af217924a76e 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c @@ -325,9 +325,6 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) * support as well. */ host->quirks |= SDHCI_QUIRK_BROKEN_DMA; - /* PIO currently has problems with multi-block IO */ - host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK; - #endif /* CONFIG_MMC_SDHCI_S3C_DMA */ /* It seems we do not get an DATA transfer complete on non-busy -- cgit v1.2.3 From b417577d3b9bbb06a4ddc9aa955af9bd503f7242 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Wed, 26 May 2010 14:42:06 -0700 Subject: omap_hsmmc: improve interrupt synchronisation The following changes were needed: - do not use in_interrupt() because it will not work with threaded interrupts In addition, the following improvements were made: - ensure DMA is unmapped only after the final DMA interrupt - ensure a request is completed only after the final DMA interrupt - disable controller interrupts when a request is not in progress - remove the spin-lock protecting the start of a new request from an unexpected interrupt because the locking was complicated and a 'req_in_progress' flag suffices (since the spin-lock only defers the unexpected interrupts anyway) - instead use the spin-lock to protect the MMC interrupt handler from the DMA interrupt handler - remove the semaphore preventing DMA from being started while the previous DMA is still in progress - the other changes make that impossible, so it is now a BUG_ON condition - ensure the controller interrupt status is clear before exiting the interrrupt handler In general, these changes make the code safer but do not fix any specific bugs so backporting is not necessary. Signed-off-by: Adrian Hunter Tested-by: Venkatraman S Acked-by: Madhusudhan Chikkature Acked-by: Tony Lindgren Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/host/omap_hsmmc.c | 262 +++++++++++++++++++++--------------------- 1 file changed, 134 insertions(+), 128 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index e9caf694c59e..c9401efd1137 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -157,12 +157,10 @@ struct omap_hsmmc_host { */ struct regulator *vcc; struct regulator *vcc_aux; - struct semaphore sem; struct work_struct mmc_carddetect_work; void __iomem *base; resource_size_t mapbase; spinlock_t irq_lock; /* Prevent races with irq handler */ - unsigned long flags; unsigned int id; unsigned int dma_len; unsigned int dma_sg_idx; @@ -183,6 +181,7 @@ struct omap_hsmmc_host { int protect_card; int reqs_blocked; int use_reg; + int req_in_progress; struct omap_mmc_platform_data *pdata; }; @@ -524,6 +523,27 @@ static void omap_hsmmc_stop_clock(struct omap_hsmmc_host *host) dev_dbg(mmc_dev(host->mmc), "MMC Clock is not stoped\n"); } +static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host) +{ + unsigned int irq_mask; + + if (host->use_dma) + irq_mask = INT_EN_MASK & ~(BRR_ENABLE | BWR_ENABLE); + else + irq_mask = INT_EN_MASK; + + OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); + OMAP_HSMMC_WRITE(host->base, ISE, irq_mask); + OMAP_HSMMC_WRITE(host->base, IE, irq_mask); +} + +static void omap_hsmmc_disable_irq(struct omap_hsmmc_host *host) +{ + OMAP_HSMMC_WRITE(host->base, ISE, 0); + OMAP_HSMMC_WRITE(host->base, IE, 0); + OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); +} + #ifdef CONFIG_PM /* @@ -592,9 +612,7 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host) && time_before(jiffies, timeout)) ; - OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); - OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK); - OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); + omap_hsmmc_disable_irq(host); /* Do not initialize card-specific things if the power is off */ if (host->power_mode == MMC_POWER_OFF) @@ -697,6 +715,8 @@ static void send_init_stream(struct omap_hsmmc_host *host) return; disable_irq(host->irq); + + OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); OMAP_HSMMC_WRITE(host->base, CON, OMAP_HSMMC_READ(host->base, CON) | INIT_STREAM); OMAP_HSMMC_WRITE(host->base, CMD, INIT_STREAM_CMD); @@ -762,17 +782,7 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, mmc_hostname(host->mmc), cmd->opcode, cmd->arg); host->cmd = cmd; - /* - * Clear status bits and enable interrupts - */ - OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); - OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK); - - if (host->use_dma) - OMAP_HSMMC_WRITE(host->base, IE, - INT_EN_MASK & ~(BRR_ENABLE | BWR_ENABLE)); - else - OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); + omap_hsmmc_enable_irq(host); host->response_busy = 0; if (cmd->flags & MMC_RSP_PRESENT) { @@ -806,13 +816,7 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, if (host->use_dma) cmdreg |= DMA_EN; - /* - * In an interrupt context (i.e. STOP command), the spinlock is unlocked - * by the interrupt handler, otherwise (i.e. for a new request) it is - * unlocked here. - */ - if (!in_interrupt()) - spin_unlock_irqrestore(&host->irq_lock, host->flags); + host->req_in_progress = 1; OMAP_HSMMC_WRITE(host->base, ARG, cmd->arg); OMAP_HSMMC_WRITE(host->base, CMD, cmdreg); @@ -827,6 +831,23 @@ omap_hsmmc_get_dma_dir(struct omap_hsmmc_host *host, struct mmc_data *data) return DMA_FROM_DEVICE; } +static void omap_hsmmc_request_done(struct omap_hsmmc_host *host, struct mmc_request *mrq) +{ + int dma_ch; + + spin_lock(&host->irq_lock); + host->req_in_progress = 0; + dma_ch = host->dma_ch; + spin_unlock(&host->irq_lock); + + omap_hsmmc_disable_irq(host); + /* Do not complete the request if DMA is still in progress */ + if (mrq->data && host->use_dma && dma_ch != -1) + return; + host->mrq = NULL; + mmc_request_done(host->mmc, mrq); +} + /* * Notify the transfer complete to MMC core */ @@ -843,25 +864,19 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data) return; } - host->mrq = NULL; - mmc_request_done(host->mmc, mrq); + omap_hsmmc_request_done(host, mrq); return; } host->data = NULL; - if (host->use_dma && host->dma_ch != -1) - dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len, - omap_hsmmc_get_dma_dir(host, data)); - if (!data->error) data->bytes_xfered += data->blocks * (data->blksz); else data->bytes_xfered = 0; if (!data->stop) { - host->mrq = NULL; - mmc_request_done(host->mmc, data->mrq); + omap_hsmmc_request_done(host, data->mrq); return; } omap_hsmmc_start_command(host, data->stop, NULL); @@ -887,10 +902,8 @@ omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct mmc_command *cmd) cmd->resp[0] = OMAP_HSMMC_READ(host->base, RSP10); } } - if ((host->data == NULL && !host->response_busy) || cmd->error) { - host->mrq = NULL; - mmc_request_done(host->mmc, cmd->mrq); - } + if ((host->data == NULL && !host->response_busy) || cmd->error) + omap_hsmmc_request_done(host, cmd->mrq); } /* @@ -898,14 +911,19 @@ omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct mmc_command *cmd) */ static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno) { + int dma_ch; + host->data->error = errno; - if (host->use_dma && host->dma_ch != -1) { + spin_lock(&host->irq_lock); + dma_ch = host->dma_ch; + host->dma_ch = -1; + spin_unlock(&host->irq_lock); + + if (host->use_dma && dma_ch != -1) { dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->dma_len, omap_hsmmc_get_dma_dir(host, host->data)); - omap_free_dma(host->dma_ch); - host->dma_ch = -1; - up(&host->sem); + omap_free_dma(dma_ch); } host->data = NULL; } @@ -967,28 +985,21 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host, __func__); } -/* - * MMC controller IRQ handler - */ -static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) +static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status) { - struct omap_hsmmc_host *host = dev_id; struct mmc_data *data; - int end_cmd = 0, end_trans = 0, status; - - spin_lock(&host->irq_lock); - - if (host->mrq == NULL) { - OMAP_HSMMC_WRITE(host->base, STAT, - OMAP_HSMMC_READ(host->base, STAT)); - /* Flush posted write */ - OMAP_HSMMC_READ(host->base, STAT); - spin_unlock(&host->irq_lock); - return IRQ_HANDLED; + int end_cmd = 0, end_trans = 0; + + if (!host->req_in_progress) { + do { + OMAP_HSMMC_WRITE(host->base, STAT, status); + /* Flush posted write */ + status = OMAP_HSMMC_READ(host->base, STAT); + } while (status & INT_EN_MASK); + return; } data = host->data; - status = OMAP_HSMMC_READ(host->base, STAT); dev_dbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status); if (status & ERR) { @@ -1041,15 +1052,27 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) } OMAP_HSMMC_WRITE(host->base, STAT, status); - /* Flush posted write */ - OMAP_HSMMC_READ(host->base, STAT); if (end_cmd || ((status & CC) && host->cmd)) omap_hsmmc_cmd_done(host, host->cmd); if ((end_trans || (status & TC)) && host->mrq) omap_hsmmc_xfer_done(host, data); +} - spin_unlock(&host->irq_lock); +/* + * MMC controller IRQ handler + */ +static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) +{ + struct omap_hsmmc_host *host = dev_id; + int status; + + status = OMAP_HSMMC_READ(host->base, STAT); + do { + omap_hsmmc_do_irq(host, status); + /* Flush posted write */ + status = OMAP_HSMMC_READ(host->base, STAT); + } while (status & INT_EN_MASK); return IRQ_HANDLED; } @@ -1244,31 +1267,47 @@ static void omap_hsmmc_config_dma_params(struct omap_hsmmc_host *host, /* * DMA call back function */ -static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *data) +static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data) { - struct omap_hsmmc_host *host = data; + struct omap_hsmmc_host *host = cb_data; + struct mmc_data *data = host->mrq->data; + int dma_ch, req_in_progress; if (ch_status & OMAP2_DMA_MISALIGNED_ERR_IRQ) dev_dbg(mmc_dev(host->mmc), "MISALIGNED_ADRS_ERR\n"); - if (host->dma_ch < 0) + spin_lock(&host->irq_lock); + if (host->dma_ch < 0) { + spin_unlock(&host->irq_lock); return; + } host->dma_sg_idx++; if (host->dma_sg_idx < host->dma_len) { /* Fire up the next transfer. */ - omap_hsmmc_config_dma_params(host, host->data, - host->data->sg + host->dma_sg_idx); + omap_hsmmc_config_dma_params(host, data, + data->sg + host->dma_sg_idx); + spin_unlock(&host->irq_lock); return; } - omap_free_dma(host->dma_ch); + dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len, + omap_hsmmc_get_dma_dir(host, data)); + + req_in_progress = host->req_in_progress; + dma_ch = host->dma_ch; host->dma_ch = -1; - /* - * DMA Callback: run in interrupt context. - * mutex_unlock will throw a kernel warning if used. - */ - up(&host->sem); + spin_unlock(&host->irq_lock); + + omap_free_dma(dma_ch); + + /* If DMA has finished after TC, complete the request */ + if (!req_in_progress) { + struct mmc_request *mrq = host->mrq; + + host->mrq = NULL; + mmc_request_done(host->mmc, mrq); + } } /* @@ -1277,7 +1316,7 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *data) static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host, struct mmc_request *req) { - int dma_ch = 0, ret = 0, err = 1, i; + int dma_ch = 0, ret = 0, i; struct mmc_data *data = req->data; /* Sanity check: all the SG entries must be aligned by block size. */ @@ -1294,23 +1333,7 @@ static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host, */ return -EINVAL; - /* - * If for some reason the DMA transfer is still active, - * we wait for timeout period and free the dma - */ - if (host->dma_ch != -1) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(100); - if (down_trylock(&host->sem)) { - omap_free_dma(host->dma_ch); - host->dma_ch = -1; - up(&host->sem); - return err; - } - } else { - if (down_trylock(&host->sem)) - return err; - } + BUG_ON(host->dma_ch != -1); ret = omap_request_dma(omap_hsmmc_get_dma_sync_dev(host, data), "MMC/SD", omap_hsmmc_dma_cb, host, &dma_ch); @@ -1410,37 +1433,27 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req) struct omap_hsmmc_host *host = mmc_priv(mmc); int err; - /* - * Prevent races with the interrupt handler because of unexpected - * interrupts, but not if we are already in interrupt context i.e. - * retries. - */ - if (!in_interrupt()) { - spin_lock_irqsave(&host->irq_lock, host->flags); - /* - * Protect the card from I/O if there is a possibility - * it can be removed. - */ - if (host->protect_card) { - if (host->reqs_blocked < 3) { - /* - * Ensure the controller is left in a consistent - * state by resetting the command and data state - * machines. - */ - omap_hsmmc_reset_controller_fsm(host, SRD); - omap_hsmmc_reset_controller_fsm(host, SRC); - host->reqs_blocked += 1; - } - req->cmd->error = -EBADF; - if (req->data) - req->data->error = -EBADF; - spin_unlock_irqrestore(&host->irq_lock, host->flags); - mmc_request_done(mmc, req); - return; - } else if (host->reqs_blocked) - host->reqs_blocked = 0; - } + BUG_ON(host->req_in_progress); + BUG_ON(host->dma_ch != -1); + if (host->protect_card) { + if (host->reqs_blocked < 3) { + /* + * Ensure the controller is left in a consistent + * state by resetting the command and data state + * machines. + */ + omap_hsmmc_reset_controller_fsm(host, SRD); + omap_hsmmc_reset_controller_fsm(host, SRC); + host->reqs_blocked += 1; + } + req->cmd->error = -EBADF; + if (req->data) + req->data->error = -EBADF; + req->cmd->retries = 0; + mmc_request_done(mmc, req); + return; + } else if (host->reqs_blocked) + host->reqs_blocked = 0; WARN_ON(host->mrq != NULL); host->mrq = req; err = omap_hsmmc_prepare_data(host, req); @@ -1449,8 +1462,6 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req) if (req->data) req->data->error = err; host->mrq = NULL; - if (!in_interrupt()) - spin_unlock_irqrestore(&host->irq_lock, host->flags); mmc_request_done(mmc, req); return; } @@ -2019,7 +2030,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) mmc->f_min = 400000; mmc->f_max = 52000000; - sema_init(&host->sem, 1); spin_lock_init(&host->irq_lock); host->iclk = clk_get(&pdev->dev, "ick"); @@ -2162,8 +2172,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) } } - OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK); - OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); + omap_hsmmc_disable_irq(host); mmc_host_lazy_disable(host->mmc); @@ -2283,10 +2292,7 @@ static int omap_hsmmc_suspend(struct platform_device *pdev, pm_message_t state) mmc_host_enable(host->mmc); ret = mmc_suspend_host(host->mmc, state); if (ret == 0) { - OMAP_HSMMC_WRITE(host->base, ISE, 0); - OMAP_HSMMC_WRITE(host->base, IE, 0); - - + omap_hsmmc_disable_irq(host); OMAP_HSMMC_WRITE(host->base, HCTL, OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP); mmc_host_disable(host->mmc); -- cgit v1.2.3 From a791daa15305e7e549a418ef0ae6bc4b4580066e Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 26 May 2010 14:42:07 -0700 Subject: mmc: OMAP HS-MMC: convert to dev_pm_ops Convert PM operations to use dev_pm_ops. This will facilitate the runtime PM coversion which will add to dev_pm_ops hooks. Note that dev_pm_ops version of the suspend hook no longer takes a 'state' argument. However, the MMC core function mmc_suspend_host() still takes a 'state' argument, but it is unused, so a dummy state variable was created to pass to the MMC core. In the future, the MMC core should be converted to drop this state argument and the rest of the MMC drivers could be easily converted to dev_pm_ops as well. Signed-off-by: Kevin Hilman Cc: Madhusudhan Chikkature Cc: Adrian Hunter Cc: Matt Fleming Cc: Tony Lindgren Cc: Denis Karpov Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/host/omap_hsmmc.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index c9401efd1137..d25b19b3ca29 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -2267,10 +2267,12 @@ static int omap_hsmmc_remove(struct platform_device *pdev) } #ifdef CONFIG_PM -static int omap_hsmmc_suspend(struct platform_device *pdev, pm_message_t state) +static int omap_hsmmc_suspend(struct device *dev) { int ret = 0; + struct platform_device *pdev = to_platform_device(dev); struct omap_hsmmc_host *host = platform_get_drvdata(pdev); + pm_message_t state = PMSG_SUSPEND; /* unused by MMC core */ if (host && host->suspended) return 0; @@ -2316,9 +2318,10 @@ static int omap_hsmmc_suspend(struct platform_device *pdev, pm_message_t state) } /* Routine to resume the MMC device */ -static int omap_hsmmc_resume(struct platform_device *pdev) +static int omap_hsmmc_resume(struct device *dev) { int ret = 0; + struct platform_device *pdev = to_platform_device(dev); struct omap_hsmmc_host *host = platform_get_drvdata(pdev); if (host && !host->suspended) @@ -2369,13 +2372,17 @@ clk_en_err: #define omap_hsmmc_resume NULL #endif -static struct platform_driver omap_hsmmc_driver = { - .remove = omap_hsmmc_remove, +static struct dev_pm_ops omap_hsmmc_dev_pm_ops = { .suspend = omap_hsmmc_suspend, .resume = omap_hsmmc_resume, +}; + +static struct platform_driver omap_hsmmc_driver = { + .remove = omap_hsmmc_remove, .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, + .pm = &omap_hsmmc_dev_pm_ops, }, }; -- cgit v1.2.3 From 1a13f8fa76c880be41d6b1e6a2b44404bcbfdf9e Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Wed, 26 May 2010 14:42:08 -0700 Subject: mmc: remove the "state" argument to mmc_suspend_host() Even though many mmc host drivers pass a pm_message_t argument to mmc_suspend_host() that argument isn't used the by MMC core. As host drivers are converted to dev_pm_ops they'll have to construct pm_message_t's (as they won't be passed by the PM subsystem any more) just to appease the mmc suspend interface. We might as well just delete the unused paramter. Signed-off-by: Matt Fleming Acked-by: Anton Vorontsov Acked-by: Michal Miroslaw ZZ Acked-by: Sascha Sommer Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/core/core.c | 3 +-- drivers/mmc/host/at91_mci.c | 2 +- drivers/mmc/host/au1xmmc.c | 2 +- drivers/mmc/host/bfin_sdh.c | 2 +- drivers/mmc/host/cb710-mmc.c | 2 +- drivers/mmc/host/davinci_mmc.c | 3 +-- drivers/mmc/host/imxmmc.c | 2 +- drivers/mmc/host/mmci.c | 2 +- drivers/mmc/host/msm_sdcc.c | 2 +- drivers/mmc/host/mvsdio.c | 2 +- drivers/mmc/host/mxcmmc.c | 2 +- drivers/mmc/host/omap.c | 2 +- drivers/mmc/host/omap_hsmmc.c | 2 +- drivers/mmc/host/pxamci.c | 2 +- drivers/mmc/host/s3cmci.c | 3 +-- drivers/mmc/host/sdhci-of-core.c | 2 +- drivers/mmc/host/sdhci.c | 2 +- drivers/mmc/host/sdricoh_cs.c | 2 +- drivers/mmc/host/tifm_sd.c | 2 +- drivers/mmc/host/tmio_mmc.c | 2 +- drivers/mmc/host/via-sdmmc.c | 2 +- drivers/mmc/host/wbsd.c | 2 +- include/linux/mmc/host.h | 2 +- 23 files changed, 23 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 3168ebd616b2..569e94da844c 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1252,9 +1252,8 @@ EXPORT_SYMBOL(mmc_card_can_sleep); /** * mmc_suspend_host - suspend a host * @host: mmc host - * @state: suspend mode (PM_SUSPEND_xxx) */ -int mmc_suspend_host(struct mmc_host *host, pm_message_t state) +int mmc_suspend_host(struct mmc_host *host) { int err = 0; diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 336d9f553f3e..5f3a599ead07 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -1157,7 +1157,7 @@ static int at91_mci_suspend(struct platform_device *pdev, pm_message_t state) enable_irq_wake(host->board->det_pin); if (mmc) - ret = mmc_suspend_host(mmc, state); + ret = mmc_suspend_host(mmc); return ret; } diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index f5834449400e..c8da5d30a861 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c @@ -1142,7 +1142,7 @@ static int au1xmmc_suspend(struct platform_device *pdev, pm_message_t state) struct au1xmmc_host *host = platform_get_drvdata(pdev); int ret; - ret = mmc_suspend_host(host->mmc, state); + ret = mmc_suspend_host(host->mmc); if (ret) return ret; diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c index 6919e844072c..4b0e677d7295 100644 --- a/drivers/mmc/host/bfin_sdh.c +++ b/drivers/mmc/host/bfin_sdh.c @@ -576,7 +576,7 @@ static int sdh_suspend(struct platform_device *dev, pm_message_t state) int ret = 0; if (mmc) - ret = mmc_suspend_host(mmc, state); + ret = mmc_suspend_host(mmc); bfin_write_SDH_PWR_CTL(bfin_read_SDH_PWR_CTL() & ~PWR_ON); peripheral_free_list(drv_data->pin_req); diff --git a/drivers/mmc/host/cb710-mmc.c b/drivers/mmc/host/cb710-mmc.c index 92a324f7417c..ca3bdc831900 100644 --- a/drivers/mmc/host/cb710-mmc.c +++ b/drivers/mmc/host/cb710-mmc.c @@ -675,7 +675,7 @@ static int cb710_mmc_suspend(struct platform_device *pdev, pm_message_t state) struct mmc_host *mmc = cb710_slot_to_mmc(slot); int err; - err = mmc_suspend_host(mmc, state); + err = mmc_suspend_host(mmc); if (err) return err; diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index aae39125b8d7..33d9f1b00862 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c @@ -1337,11 +1337,10 @@ static int davinci_mmcsd_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct mmc_davinci_host *host = platform_get_drvdata(pdev); - struct pm_message msg = { PM_EVENT_SUSPEND }; int ret; mmc_host_enable(host->mmc); - ret = mmc_suspend_host(host->mmc, msg); + ret = mmc_suspend_host(host->mmc); if (!ret) { writel(0, host->base + DAVINCI_MMCIM); mmc_davinci_reset_ctrl(host, 1); diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c index bf98d7cc928a..9a68ff4353a2 100644 --- a/drivers/mmc/host/imxmmc.c +++ b/drivers/mmc/host/imxmmc.c @@ -1115,7 +1115,7 @@ static int imxmci_suspend(struct platform_device *dev, pm_message_t state) int ret = 0; if (mmc) - ret = mmc_suspend_host(mmc, state); + ret = mmc_suspend_host(mmc); return ret; } diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index ff115d920888..4917af96bae1 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -824,7 +824,7 @@ static int mmci_suspend(struct amba_device *dev, pm_message_t state) if (mmc) { struct mmci_host *host = mmc_priv(mmc); - ret = mmc_suspend_host(mmc, state); + ret = mmc_suspend_host(mmc); if (ret == 0) writel(0, host->base + MMCIMASK0); } diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 61f1d27fed3f..24e09454e522 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -1327,7 +1327,7 @@ msmsdcc_suspend(struct platform_device *dev, pm_message_t state) disable_irq(host->stat_irq); if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) - rc = mmc_suspend_host(mmc, state); + rc = mmc_suspend_host(mmc); if (!rc) msmsdcc_writel(host, 0, MMCIMASK0); if (host->clks_on) diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c index 34e23489811a..366eefa77c5a 100644 --- a/drivers/mmc/host/mvsdio.c +++ b/drivers/mmc/host/mvsdio.c @@ -865,7 +865,7 @@ static int mvsd_suspend(struct platform_device *dev, pm_message_t state) int ret = 0; if (mmc) - ret = mmc_suspend_host(mmc, state); + ret = mmc_suspend_host(mmc); return ret; } diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index ec18e3b60342..d9d4a72e0ec7 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -932,7 +932,7 @@ static int mxcmci_suspend(struct platform_device *dev, pm_message_t state) int ret = 0; if (mmc) - ret = mmc_suspend_host(mmc, state); + ret = mmc_suspend_host(mmc); return ret; } diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 475490b18570..2b281680e320 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -1561,7 +1561,7 @@ static int mmc_omap_suspend(struct platform_device *pdev, pm_message_t mesg) struct mmc_omap_slot *slot; slot = host->slots[i]; - ret = mmc_suspend_host(slot->mmc, mesg); + ret = mmc_suspend_host(slot->mmc); if (ret < 0) { while (--i >= 0) { slot = host->slots[i]; diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index d25b19b3ca29..b032828c6126 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -2292,7 +2292,7 @@ static int omap_hsmmc_suspend(struct device *dev) } cancel_work_sync(&host->mmc_carddetect_work); mmc_host_enable(host->mmc); - ret = mmc_suspend_host(host->mmc, state); + ret = mmc_suspend_host(host->mmc); if (ret == 0) { omap_hsmmc_disable_irq(host); OMAP_HSMMC_WRITE(host->base, HCTL, diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index e4f00e70a749..0a4e43f37140 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -813,7 +813,7 @@ static int pxamci_suspend(struct device *dev) int ret = 0; if (mmc) - ret = mmc_suspend_host(mmc, PMSG_SUSPEND); + ret = mmc_suspend_host(mmc); return ret; } diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 2fdf7689ae6c..2e16e0a90a5e 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c @@ -1881,9 +1881,8 @@ MODULE_DEVICE_TABLE(platform, s3cmci_driver_ids); static int s3cmci_suspend(struct device *dev) { struct mmc_host *mmc = platform_get_drvdata(to_platform_device(dev)); - struct pm_message event = { PM_EVENT_SUSPEND }; - return mmc_suspend_host(mmc, event); + return mmc_suspend_host(mmc); } static int s3cmci_resume(struct device *dev) diff --git a/drivers/mmc/host/sdhci-of-core.c b/drivers/mmc/host/sdhci-of-core.c index 7802a543d8fc..a2e9820cd42f 100644 --- a/drivers/mmc/host/sdhci-of-core.c +++ b/drivers/mmc/host/sdhci-of-core.c @@ -89,7 +89,7 @@ static int sdhci_of_suspend(struct of_device *ofdev, pm_message_t state) { struct sdhci_host *host = dev_get_drvdata(&ofdev->dev); - return mmc_suspend_host(host->mmc, state); + return mmc_suspend_host(host->mmc); } static int sdhci_of_resume(struct of_device *ofdev) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index d27cc9178041..c6d1bd8d4ac4 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1597,7 +1597,7 @@ int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state) sdhci_disable_card_detection(host); - ret = mmc_suspend_host(host->mmc, state); + ret = mmc_suspend_host(host->mmc); if (ret) return ret; diff --git a/drivers/mmc/host/sdricoh_cs.c b/drivers/mmc/host/sdricoh_cs.c index cb41e9c3ac07..e7507af3856e 100644 --- a/drivers/mmc/host/sdricoh_cs.c +++ b/drivers/mmc/host/sdricoh_cs.c @@ -519,7 +519,7 @@ static int sdricoh_pcmcia_suspend(struct pcmcia_device *link) { struct mmc_host *mmc = link->priv; dev_dbg(&link->dev, "suspend\n"); - mmc_suspend_host(mmc, PMSG_SUSPEND); + mmc_suspend_host(mmc); return 0; } diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c index 82554ddec6b3..cec99958b652 100644 --- a/drivers/mmc/host/tifm_sd.c +++ b/drivers/mmc/host/tifm_sd.c @@ -1032,7 +1032,7 @@ static void tifm_sd_remove(struct tifm_dev *sock) static int tifm_sd_suspend(struct tifm_dev *sock, pm_message_t state) { - return mmc_suspend_host(tifm_get_drvdata(sock), state); + return mmc_suspend_host(tifm_get_drvdata(sock)); } static int tifm_sd_resume(struct tifm_dev *sock) diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index 883fcac21004..ee7d0a5a51c4 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c @@ -768,7 +768,7 @@ static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state) struct mmc_host *mmc = platform_get_drvdata(dev); int ret; - ret = mmc_suspend_host(mmc, state); + ret = mmc_suspend_host(mmc); /* Tell MFD core it can disable us now.*/ if (!ret && cell->disable) diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c index 632858a94376..19f2d72dbca5 100644 --- a/drivers/mmc/host/via-sdmmc.c +++ b/drivers/mmc/host/via-sdmmc.c @@ -1280,7 +1280,7 @@ static int via_sd_suspend(struct pci_dev *pcidev, pm_message_t state) via_save_pcictrlreg(host); via_save_sdcreg(host); - ret = mmc_suspend_host(host->mmc, state); + ret = mmc_suspend_host(host->mmc); pci_save_state(pcidev); pci_enable_wake(pcidev, pci_choose_state(pcidev, state), 0); diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index 69efe01eece8..0012f5d13d28 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c @@ -1819,7 +1819,7 @@ static int wbsd_suspend(struct wbsd_host *host, pm_message_t state) { BUG_ON(host == NULL); - return mmc_suspend_host(host->mmc, state); + return mmc_suspend_host(host->mmc); } static int wbsd_resume(struct wbsd_host *host) diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 3196c84cc630..f65913c9f5a4 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -230,7 +230,7 @@ static inline void *mmc_priv(struct mmc_host *host) #define mmc_classdev(x) (&(x)->class_dev) #define mmc_hostname(x) (dev_name(&(x)->class_dev)) -extern int mmc_suspend_host(struct mmc_host *, pm_message_t); +extern int mmc_suspend_host(struct mmc_host *); extern int mmc_resume_host(struct mmc_host *); extern void mmc_power_save_host(struct mmc_host *host); -- cgit v1.2.3 From 6c1f716e8154ee9315534782b9b1eedea0559a24 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Wed, 26 May 2010 14:42:09 -0700 Subject: sdio: add new function for RAW (Read after Write) operation SDIO specification allows RAW (Read after Write) operation using IO_RW_DIRECT command (CMD52) by setting the RAW bit. This operation is similar to ordinary read/write commands, except that both write and read are performed using single command/response pair. The Linux SDIO layer already supports this internaly, only external function is missing for drivers to make use, which is added by this patch. This type of command is required to implement proper power save mode support in wl1251 wifi driver. Android has similar patch for G1 in it's tree for the same reason: http://android.git.kernel.org/?p=kernel/common.git;a=commitdiff;h=74a47786f6ecbe6c1cf9fb15efe6a968451deb52 Signed-off-by: Grazvydas Ignotas Acked-by: Kalle Valo Cc: Dmitry Shmidt Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/core/sdio_io.c | 30 ++++++++++++++++++++++++++++++ include/linux/mmc/sdio_func.h | 3 +++ 2 files changed, 33 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c index ff27c8c71355..0f687cdeb064 100644 --- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c @@ -405,6 +405,36 @@ void sdio_writeb(struct sdio_func *func, u8 b, unsigned int addr, int *err_ret) } EXPORT_SYMBOL_GPL(sdio_writeb); +/** + * sdio_writeb_readb - write and read a byte from SDIO function + * @func: SDIO function to access + * @write_byte: byte to write + * @addr: address to write to + * @err_ret: optional status value from transfer + * + * Performs a RAW (Read after Write) operation as defined by SDIO spec - + * single byte is written to address space of a given SDIO function and + * response is read back from the same address, both using single request. + * If there is a problem with the operation, 0xff is returned and + * @err_ret will contain the error code. + */ +u8 sdio_writeb_readb(struct sdio_func *func, u8 write_byte, + unsigned int addr, int *err_ret) +{ + int ret; + u8 val; + + ret = mmc_io_rw_direct(func->card, 1, func->num, addr, + write_byte, &val); + if (err_ret) + *err_ret = ret; + if (ret) + val = 0xff; + + return val; +} +EXPORT_SYMBOL_GPL(sdio_writeb_readb); + /** * sdio_memcpy_fromio - read a chunk of memory from a SDIO function * @func: SDIO function to access diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h index c6c0cceba5fe..31baaf82f458 100644 --- a/include/linux/mmc/sdio_func.h +++ b/include/linux/mmc/sdio_func.h @@ -145,6 +145,9 @@ extern void sdio_writew(struct sdio_func *func, u16 b, extern void sdio_writel(struct sdio_func *func, u32 b, unsigned int addr, int *err_ret); +extern u8 sdio_writeb_readb(struct sdio_func *func, u8 write_byte, + unsigned int addr, int *err_ret); + extern int sdio_memcpy_toio(struct sdio_func *func, unsigned int addr, void *src, int count); extern int sdio_writesb(struct sdio_func *func, unsigned int addr, -- cgit v1.2.3 From c63b3cba4f47ef9f4b3f952b4f923cf341d250ac Mon Sep 17 00:00:00 2001 From: Viresh KUMAR Date: Wed, 26 May 2010 14:42:10 -0700 Subject: sdhci-spear: ST SPEAr based SDHCI controller glue Add a glue layer to support the sdhci driver on the ST SPEAr platform. Signed-off-by: Viresh Kumar Cc: Cc: Linus Walleij Cc: Russell King Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- MAINTAINERS | 6 + drivers/mmc/host/Kconfig | 12 ++ drivers/mmc/host/Makefile | 1 + drivers/mmc/host/sdhci-spear.c | 298 ++++++++++++++++++++++++++++++++++++++++ include/linux/mmc/sdhci-spear.h | 42 ++++++ 5 files changed, 359 insertions(+) create mode 100644 drivers/mmc/host/sdhci-spear.c create mode 100644 include/linux/mmc/sdhci-spear.h (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index 18355cc1ce26..8b7eba2de603 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5004,6 +5004,12 @@ L: linux-mmc@vger.kernel.org S: Maintained F: drivers/mmc/host/sdhci-s3c.c +SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) ST SPEAR DRIVER +M: Viresh Kumar +L: linux-mmc@vger.kernel.org +S: Maintained +F: drivers/mmc/host/sdhci-spear.c + SECURITY SUBSYSTEM M: James Morris L: linux-security-module@vger.kernel.org (suggested Cc:) diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index aeecbc932fbd..e171e77f6129 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -136,6 +136,18 @@ config MMC_SDHCI_S3C If unsure, say N. +config MMC_SDHCI_SPEAR + tristate "SDHCI support on ST SPEAr platform" + depends on MMC_SDHCI && PLAT_SPEAR + help + This selects the Secure Digital Host Controller Interface (SDHCI) + often referrered to as the HSMMC block in some of the ST SPEAR range + of SoC + + If you have a controller with this interface, say Y or M here. + + If unsure, say N. + config MMC_SDHCI_S3C_DMA bool "DMA support on S3C SDHCI" depends on MMC_SDHCI_S3C && EXPERIMENTAL diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 2447b66afeb3..e30c2ee48894 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_MMC_SDHCI) += sdhci.o obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o +obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o obj-$(CONFIG_MMC_OMAP) += omap.o diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c new file mode 100644 index 000000000000..d70c54c7b70a --- /dev/null +++ b/drivers/mmc/host/sdhci-spear.c @@ -0,0 +1,298 @@ +/* + * drivers/mmc/host/sdhci-spear.c + * + * Support of SDHCI platform devices for spear soc family + * + * Copyright (C) 2010 ST Microelectronics + * Viresh Kumar + * + * Inspired by sdhci-pltfm.c + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sdhci.h" + +struct spear_sdhci { + struct clk *clk; + struct sdhci_plat_data *data; +}; + +/* sdhci ops */ +static struct sdhci_ops sdhci_pltfm_ops = { + /* Nothing to do for now. */ +}; + +/* gpio card detection interrupt handler */ +static irqreturn_t sdhci_gpio_irq(int irq, void *dev_id) +{ + struct platform_device *pdev = dev_id; + struct sdhci_host *host = platform_get_drvdata(pdev); + struct spear_sdhci *sdhci = dev_get_platdata(&pdev->dev); + unsigned long gpio_irq_type; + int val; + + val = gpio_get_value(sdhci->data->card_int_gpio); + + /* val == 1 -> card removed, val == 0 -> card inserted */ + /* if card removed - set irq for low level, else vice versa */ + gpio_irq_type = val ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH; + set_irq_type(irq, gpio_irq_type); + + if (sdhci->data->card_power_gpio >= 0) { + if (!sdhci->data->power_always_enb) { + /* if card inserted, give power, otherwise remove it */ + val = sdhci->data->power_active_high ? !val : val ; + gpio_set_value(sdhci->data->card_power_gpio, val); + } + } + + /* inform sdhci driver about card insertion/removal */ + tasklet_schedule(&host->card_tasklet); + + return IRQ_HANDLED; +} + +static int __devinit sdhci_probe(struct platform_device *pdev) +{ + struct sdhci_host *host; + struct resource *iomem; + struct spear_sdhci *sdhci; + int ret; + + BUG_ON(pdev == NULL); + + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!iomem) { + ret = -ENOMEM; + dev_dbg(&pdev->dev, "memory resource not defined\n"); + goto err; + } + + if (!request_mem_region(iomem->start, resource_size(iomem), + "spear-sdhci")) { + ret = -EBUSY; + dev_dbg(&pdev->dev, "cannot request region\n"); + goto err; + } + + sdhci = kzalloc(sizeof(*sdhci), GFP_KERNEL); + if (!sdhci) { + ret = -ENOMEM; + dev_dbg(&pdev->dev, "cannot allocate memory for sdhci\n"); + goto err_kzalloc; + } + + /* clk enable */ + sdhci->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(sdhci->clk)) { + ret = PTR_ERR(sdhci->clk); + dev_dbg(&pdev->dev, "Error getting clock\n"); + goto err_clk_get; + } + + ret = clk_enable(sdhci->clk); + if (ret) { + dev_dbg(&pdev->dev, "Error enabling clock\n"); + goto err_clk_enb; + } + + /* overwrite platform_data */ + sdhci->data = dev_get_platdata(&pdev->dev); + pdev->dev.platform_data = sdhci; + + if (pdev->dev.parent) + host = sdhci_alloc_host(pdev->dev.parent, 0); + else + host = sdhci_alloc_host(&pdev->dev, 0); + + if (IS_ERR(host)) { + ret = PTR_ERR(host); + dev_dbg(&pdev->dev, "error allocating host\n"); + goto err_alloc_host; + } + + host->hw_name = "sdhci"; + host->ops = &sdhci_pltfm_ops; + host->irq = platform_get_irq(pdev, 0); + host->quirks = SDHCI_QUIRK_BROKEN_ADMA; + + host->ioaddr = ioremap(iomem->start, resource_size(iomem)); + if (!host->ioaddr) { + ret = -ENOMEM; + dev_dbg(&pdev->dev, "failed to remap registers\n"); + goto err_ioremap; + } + + ret = sdhci_add_host(host); + if (ret) { + dev_dbg(&pdev->dev, "error adding host\n"); + goto err_add_host; + } + + platform_set_drvdata(pdev, host); + + /* + * It is optional to use GPIOs for sdhci Power control & sdhci card + * interrupt detection. If sdhci->data is NULL, then use original sdhci + * lines otherwise GPIO lines. + * If GPIO is selected for power control, then power should be disabled + * after card removal and should be enabled when card insertion + * interrupt occurs + */ + if (!sdhci->data) + return 0; + + if (sdhci->data->card_power_gpio >= 0) { + int val = 0; + + ret = gpio_request(sdhci->data->card_power_gpio, "sdhci"); + if (ret < 0) { + dev_dbg(&pdev->dev, "gpio request fail: %d\n", + sdhci->data->card_power_gpio); + goto err_pgpio_request; + } + + if (sdhci->data->power_always_enb) + val = sdhci->data->power_active_high; + else + val = !sdhci->data->power_active_high; + + ret = gpio_direction_output(sdhci->data->card_power_gpio, val); + if (ret) { + dev_dbg(&pdev->dev, "gpio set direction fail: %d\n", + sdhci->data->card_power_gpio); + goto err_pgpio_direction; + } + + gpio_set_value(sdhci->data->card_power_gpio, 1); + } + + if (sdhci->data->card_int_gpio >= 0) { + ret = gpio_request(sdhci->data->card_int_gpio, "sdhci"); + if (ret < 0) { + dev_dbg(&pdev->dev, "gpio request fail: %d\n", + sdhci->data->card_int_gpio); + goto err_igpio_request; + } + + ret = gpio_direction_input(sdhci->data->card_int_gpio); + if (ret) { + dev_dbg(&pdev->dev, "gpio set direction fail: %d\n", + sdhci->data->card_int_gpio); + goto err_igpio_direction; + } + ret = request_irq(gpio_to_irq(sdhci->data->card_int_gpio), + sdhci_gpio_irq, IRQF_TRIGGER_LOW, + mmc_hostname(host->mmc), pdev); + if (ret) { + dev_dbg(&pdev->dev, "gpio request irq fail: %d\n", + sdhci->data->card_int_gpio); + goto err_igpio_request_irq; + } + + } + + return 0; + +err_igpio_request_irq: +err_igpio_direction: + if (sdhci->data->card_int_gpio >= 0) + gpio_free(sdhci->data->card_int_gpio); +err_igpio_request: +err_pgpio_direction: + if (sdhci->data->card_power_gpio >= 0) + gpio_free(sdhci->data->card_power_gpio); +err_pgpio_request: + platform_set_drvdata(pdev, NULL); + sdhci_remove_host(host, 1); +err_add_host: + iounmap(host->ioaddr); +err_ioremap: + sdhci_free_host(host); +err_alloc_host: + clk_disable(sdhci->clk); +err_clk_enb: + clk_put(sdhci->clk); +err_clk_get: + kfree(sdhci); +err_kzalloc: + release_mem_region(iomem->start, resource_size(iomem)); +err: + dev_err(&pdev->dev, "spear-sdhci probe failed: %d\n", ret); + return ret; +} + +static int __devexit sdhci_remove(struct platform_device *pdev) +{ + struct sdhci_host *host = platform_get_drvdata(pdev); + struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + struct spear_sdhci *sdhci = dev_get_platdata(&pdev->dev); + int dead; + u32 scratch; + + if (sdhci->data) { + if (sdhci->data->card_int_gpio >= 0) { + free_irq(gpio_to_irq(sdhci->data->card_int_gpio), pdev); + gpio_free(sdhci->data->card_int_gpio); + } + + if (sdhci->data->card_power_gpio >= 0) + gpio_free(sdhci->data->card_power_gpio); + } + + platform_set_drvdata(pdev, NULL); + dead = 0; + scratch = readl(host->ioaddr + SDHCI_INT_STATUS); + if (scratch == (u32)-1) + dead = 1; + + sdhci_remove_host(host, dead); + iounmap(host->ioaddr); + sdhci_free_host(host); + clk_disable(sdhci->clk); + clk_put(sdhci->clk); + kfree(sdhci); + if (iomem) + release_mem_region(iomem->start, resource_size(iomem)); + + return 0; +} + +static struct platform_driver sdhci_driver = { + .driver = { + .name = "sdhci", + .owner = THIS_MODULE, + }, + .probe = sdhci_probe, + .remove = __devexit_p(sdhci_remove), +}; + +static int __init sdhci_init(void) +{ + return platform_driver_register(&sdhci_driver); +} +module_init(sdhci_init); + +static void __exit sdhci_exit(void) +{ + platform_driver_unregister(&sdhci_driver); +} +module_exit(sdhci_exit); + +MODULE_DESCRIPTION("SPEAr Secure Digital Host Controller Interface driver"); +MODULE_AUTHOR("Viresh Kumar "); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/mmc/sdhci-spear.h b/include/linux/mmc/sdhci-spear.h new file mode 100644 index 000000000000..9188c973f3e1 --- /dev/null +++ b/include/linux/mmc/sdhci-spear.h @@ -0,0 +1,42 @@ +/* + * include/linux/mmc/sdhci-spear.h + * + * SDHCI declarations specific to ST SPEAr platform + * + * Copyright (C) 2010 ST Microelectronics + * Viresh Kumar + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef MMC_SDHCI_SPEAR_H +#define MMC_SDHCI_SPEAR_H + +#include +/* + * struct sdhci_plat_data: spear sdhci platform data structure + * + * @card_power_gpio: gpio pin for enabling/disabling power to sdhci socket + * @power_active_high: if set, enable power to sdhci socket by setting + * card_power_gpio + * @power_always_enb: If set, then enable power on probe, otherwise enable only + * on card insertion and disable on card removal. + * card_int_gpio: gpio pin used for card detection + */ +struct sdhci_plat_data { + int card_power_gpio; + int power_active_high; + int power_always_enb; + int card_int_gpio; +}; + +/* This function is used to set platform_data field of pdev->dev */ +static inline void +sdhci_set_plat_data(struct platform_device *pdev, struct sdhci_plat_data *data) +{ + pdev->dev.platform_data = data; +} + +#endif /* MMC_SDHCI_SPEAR_H */ -- cgit v1.2.3 From dc0fd7b56141999832a6bccda2f7e9765f0bc087 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 26 May 2010 14:42:11 -0700 Subject: drivers/mmc/host: use ERR_CAST Use ERR_CAST(x) rather than ERR_PTR(PTR_ERR(x)). The former makes more clear what is the purpose of the operation, which otherwise looks like a no-op. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ type T; T x; identifier f; @@ T f (...) { <+... - ERR_PTR(PTR_ERR(x)) + x ...+> } @@ expression x; @@ - ERR_PTR(PTR_ERR(x)) + ERR_CAST(x) // Signed-off-by: Julia Lawall Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mmc/host/sdhci-pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 6701af629c30..65483fdea45b 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -628,7 +628,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_pci_slot)); if (IS_ERR(host)) { dev_err(&pdev->dev, "cannot allocate host\n"); - return ERR_PTR(PTR_ERR(host)); + return ERR_CAST(host); } slot = sdhci_priv(host); -- cgit v1.2.3 From 9b71ca2005a93ad813b95d92578131ab899ccc5d Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 26 May 2010 14:42:11 -0700 Subject: drivers/char/vt.c: use memdup_user Use memdup_user when user data is immediately copied into the allocated region. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression from,to,size,flag; position p; identifier l1,l2; @@ - to = \(kmalloc@p\|kzalloc@p\)(size,flag); + to = memdup_user(from,size); if ( - to==NULL + IS_ERR(to) || ...) { <+... when != goto l1; - -ENOMEM + PTR_ERR(to) ...+> } - if (copy_from_user(to, from, size) != 0) { - <+... when != goto l2; - -EFAULT - ...+> - } // Signed-off-by: Julia Lawall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/vt.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/char/vt.c b/drivers/char/vt.c index bd1d1164fec5..7cdb6ee569cd 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -3967,13 +3967,9 @@ static int con_font_set(struct vc_data *vc, struct console_font_op *op) font.charcount = op->charcount; font.height = op->height; font.width = op->width; - font.data = kmalloc(size, GFP_KERNEL); - if (!font.data) - return -ENOMEM; - if (copy_from_user(font.data, op->data, size)) { - kfree(font.data); - return -EFAULT; - } + font.data = memdup_user(op->data, size); + if (IS_ERR(font.data)) + return PTR_ERR(font.data); acquire_console_sem(); if (vc->vc_sw->con_font_set) rc = vc->vc_sw->con_font_set(vc, &font, op->flags); -- cgit v1.2.3 From b81d67a50c0f3021d170466388bec3e7fc3abe75 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 26 May 2010 14:42:12 -0700 Subject: drivers/message/i2o/i2o_config.c: use memdup_user Use memdup_user when user data is immediately copied into the allocated region. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression from,to,size,flag; position p; identifier l1,l2; @@ - to = \(kmalloc@p\|kzalloc@p\)(size,flag); + to = memdup_user(from,size); if ( - to==NULL + IS_ERR(to) || ...) { <+... when != goto l1; - -ENOMEM + PTR_ERR(to) ...+> } - if (copy_from_user(to, from, size) != 0) { - <+... when != goto l2; - -EFAULT - ...+> - } // Signed-off-by: Julia Lawall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/message/i2o/i2o_config.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c index d33693c13368..c4b117f5fb70 100644 --- a/drivers/message/i2o/i2o_config.c +++ b/drivers/message/i2o/i2o_config.c @@ -186,14 +186,9 @@ static int i2o_cfg_parms(unsigned long arg, unsigned int type) if (!dev) return -ENXIO; - ops = kmalloc(kcmd.oplen, GFP_KERNEL); - if (!ops) - return -ENOMEM; - - if (copy_from_user(ops, kcmd.opbuf, kcmd.oplen)) { - kfree(ops); - return -EFAULT; - } + ops = memdup_user(kcmd.opbuf, kcmd.oplen); + if (IS_ERR(ops)) + return PTR_ERR(ops); /* * It's possible to have a _very_ large table -- cgit v1.2.3 From 0af62f4d1eedaacf6a85e293958699540d09fa3e Mon Sep 17 00:00:00 2001 From: Virupax Sadashivpetimath Date: Wed, 26 May 2010 14:42:14 -0700 Subject: rtc: AB8500 RTC driver Add a driver for the RTC on the AB8500 power management chip. This is a client of the AB8500 MFD driver. Signed-off-by: Virupax Sadashivpetimath Signed-off-by: Rabin Vincent Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Cc: Alessandro Zummo Cc: Samuel Ortiz Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/Kconfig | 7 + drivers/rtc/Makefile | 1 + drivers/rtc/rtc-ab8500.c | 363 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 371 insertions(+) create mode 100644 drivers/rtc/rtc-ab8500.c (limited to 'drivers') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index f1598324344c..10ba12c8c5e0 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -611,6 +611,13 @@ config RTC_DRV_AB3100 Select this to enable the ST-Ericsson AB3100 Mixed Signal IC RTC support. This chip contains a battery- and capacitor-backed RTC. +config RTC_DRV_AB8500 + tristate "ST-Ericsson AB8500 RTC" + depends on AB8500_CORE + help + Select this to enable the ST-Ericsson AB8500 power management IC RTC + support. This chip contains a battery- and capacitor-backed RTC. + config RTC_DRV_NUC900 tristate "NUC910/NUC920 RTC driver" depends on RTC_CLASS && ARCH_W90X900 diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 245311a1348f..5adbba7cf89c 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -18,6 +18,7 @@ rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o # Keep the list ordered. obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o +obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c new file mode 100644 index 000000000000..2fda03125e55 --- /dev/null +++ b/drivers/rtc/rtc-ab8500.c @@ -0,0 +1,363 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License terms: GNU General Public License (GPL) version 2 + * Author: Virupax Sadashivpetimath + * + * RTC clock driver for the RTC part of the AB8500 Power management chip. + * Based on RTC clock driver for the AB3100 Analog Baseband Chip by + * Linus Walleij + */ + +#include +#include +#include +#include +#include +#include +#include + +#define AB8500_RTC_SOFF_STAT_REG 0x0F00 +#define AB8500_RTC_CC_CONF_REG 0x0F01 +#define AB8500_RTC_READ_REQ_REG 0x0F02 +#define AB8500_RTC_WATCH_TSECMID_REG 0x0F03 +#define AB8500_RTC_WATCH_TSECHI_REG 0x0F04 +#define AB8500_RTC_WATCH_TMIN_LOW_REG 0x0F05 +#define AB8500_RTC_WATCH_TMIN_MID_REG 0x0F06 +#define AB8500_RTC_WATCH_TMIN_HI_REG 0x0F07 +#define AB8500_RTC_ALRM_MIN_LOW_REG 0x0F08 +#define AB8500_RTC_ALRM_MIN_MID_REG 0x0F09 +#define AB8500_RTC_ALRM_MIN_HI_REG 0x0F0A +#define AB8500_RTC_STAT_REG 0x0F0B +#define AB8500_RTC_BKUP_CHG_REG 0x0F0C +#define AB8500_RTC_FORCE_BKUP_REG 0x0F0D +#define AB8500_RTC_CALIB_REG 0x0F0E +#define AB8500_RTC_SWITCH_STAT_REG 0x0F0F +#define AB8500_REV_REG 0x1080 + +/* RtcReadRequest bits */ +#define RTC_READ_REQUEST 0x01 +#define RTC_WRITE_REQUEST 0x02 + +/* RtcCtrl bits */ +#define RTC_ALARM_ENA 0x04 +#define RTC_STATUS_DATA 0x01 + +#define COUNTS_PER_SEC (0xF000 / 60) +#define AB8500_RTC_EPOCH 2000 + +static const unsigned long ab8500_rtc_time_regs[] = { + AB8500_RTC_WATCH_TMIN_HI_REG, AB8500_RTC_WATCH_TMIN_MID_REG, + AB8500_RTC_WATCH_TMIN_LOW_REG, AB8500_RTC_WATCH_TSECHI_REG, + AB8500_RTC_WATCH_TSECMID_REG +}; + +static const unsigned long ab8500_rtc_alarm_regs[] = { + AB8500_RTC_ALRM_MIN_HI_REG, AB8500_RTC_ALRM_MIN_MID_REG, + AB8500_RTC_ALRM_MIN_LOW_REG +}; + +/* Calculate the seconds from 1970 to 01-01-2000 00:00:00 */ +static unsigned long get_elapsed_seconds(int year) +{ + unsigned long secs; + struct rtc_time tm = { + .tm_year = year - 1900, + .tm_mday = 1, + }; + + /* + * This function calculates secs from 1970 and not from + * 1900, even if we supply the offset from year 1900. + */ + rtc_tm_to_time(&tm, &secs); + return secs; +} + +static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); + unsigned long timeout = jiffies + HZ; + int retval, i; + unsigned long mins, secs; + unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)]; + + /* Request a data read */ + retval = ab8500_write(ab8500, AB8500_RTC_READ_REQ_REG, + RTC_READ_REQUEST); + if (retval < 0) + return retval; + + /* Early AB8500 chips will not clear the rtc read request bit */ + if (ab8500->revision == 0) { + msleep(1); + } else { + /* Wait for some cycles after enabling the rtc read in ab8500 */ + while (time_before(jiffies, timeout)) { + retval = ab8500_read(ab8500, AB8500_RTC_READ_REQ_REG); + if (retval < 0) + return retval; + + if (!(retval & RTC_READ_REQUEST)) + break; + + msleep(1); + } + } + + /* Read the Watchtime registers */ + for (i = 0; i < ARRAY_SIZE(ab8500_rtc_time_regs); i++) { + retval = ab8500_read(ab8500, ab8500_rtc_time_regs[i]); + if (retval < 0) + return retval; + buf[i] = retval; + } + + mins = (buf[0] << 16) | (buf[1] << 8) | buf[2]; + + secs = (buf[3] << 8) | buf[4]; + secs = secs / COUNTS_PER_SEC; + secs = secs + (mins * 60); + + /* Add back the initially subtracted number of seconds */ + secs += get_elapsed_seconds(AB8500_RTC_EPOCH); + + rtc_time_to_tm(secs, tm); + return rtc_valid_tm(tm); +} + +static int ab8500_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); + int retval, i; + unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)]; + unsigned long no_secs, no_mins, secs = 0; + + if (tm->tm_year < (AB8500_RTC_EPOCH - 1900)) { + dev_dbg(dev, "year should be equal to or greater than %d\n", + AB8500_RTC_EPOCH); + return -EINVAL; + } + + /* Get the number of seconds since 1970 */ + rtc_tm_to_time(tm, &secs); + + /* + * Convert it to the number of seconds since 01-01-2000 00:00:00, since + * we only have a small counter in the RTC. + */ + secs -= get_elapsed_seconds(AB8500_RTC_EPOCH); + + no_mins = secs / 60; + + no_secs = secs % 60; + /* Make the seconds count as per the RTC resolution */ + no_secs = no_secs * COUNTS_PER_SEC; + + buf[4] = no_secs & 0xFF; + buf[3] = (no_secs >> 8) & 0xFF; + + buf[2] = no_mins & 0xFF; + buf[1] = (no_mins >> 8) & 0xFF; + buf[0] = (no_mins >> 16) & 0xFF; + + for (i = 0; i < ARRAY_SIZE(ab8500_rtc_time_regs); i++) { + retval = ab8500_write(ab8500, ab8500_rtc_time_regs[i], buf[i]); + if (retval < 0) + return retval; + } + + /* Request a data write */ + return ab8500_write(ab8500, AB8500_RTC_READ_REQ_REG, RTC_WRITE_REQUEST); +} + +static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ + struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); + int retval, i; + int rtc_ctrl; + unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)]; + unsigned long secs, mins; + + /* Check if the alarm is enabled or not */ + rtc_ctrl = ab8500_read(ab8500, AB8500_RTC_STAT_REG); + if (rtc_ctrl < 0) + return rtc_ctrl; + + if (rtc_ctrl & RTC_ALARM_ENA) + alarm->enabled = 1; + else + alarm->enabled = 0; + + alarm->pending = 0; + + for (i = 0; i < ARRAY_SIZE(ab8500_rtc_alarm_regs); i++) { + retval = ab8500_read(ab8500, ab8500_rtc_alarm_regs[i]); + if (retval < 0) + return retval; + buf[i] = retval; + } + + mins = (buf[0] << 16) | (buf[1] << 8) | (buf[2]); + secs = mins * 60; + + /* Add back the initially subtracted number of seconds */ + secs += get_elapsed_seconds(AB8500_RTC_EPOCH); + + rtc_time_to_tm(secs, &alarm->time); + + return rtc_valid_tm(&alarm->time); +} + +static int ab8500_rtc_irq_enable(struct device *dev, unsigned int enabled) +{ + struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); + + return ab8500_set_bits(ab8500, AB8500_RTC_STAT_REG, RTC_ALARM_ENA, + enabled ? RTC_ALARM_ENA : 0); +} + +static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ + struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); + int retval, i; + unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)]; + unsigned long mins, secs = 0; + + if (alarm->time.tm_year < (AB8500_RTC_EPOCH - 1900)) { + dev_dbg(dev, "year should be equal to or greater than %d\n", + AB8500_RTC_EPOCH); + return -EINVAL; + } + + /* Get the number of seconds since 1970 */ + rtc_tm_to_time(&alarm->time, &secs); + + /* + * Convert it to the number of seconds since 01-01-2000 00:00:00, since + * we only have a small counter in the RTC. + */ + secs -= get_elapsed_seconds(AB8500_RTC_EPOCH); + + mins = secs / 60; + + buf[2] = mins & 0xFF; + buf[1] = (mins >> 8) & 0xFF; + buf[0] = (mins >> 16) & 0xFF; + + /* Set the alarm time */ + for (i = 0; i < ARRAY_SIZE(ab8500_rtc_alarm_regs); i++) { + retval = ab8500_write(ab8500, ab8500_rtc_alarm_regs[i], buf[i]); + if (retval < 0) + return retval; + } + + return ab8500_rtc_irq_enable(dev, alarm->enabled); +} + +static irqreturn_t rtc_alarm_handler(int irq, void *data) +{ + struct rtc_device *rtc = data; + unsigned long events = RTC_IRQF | RTC_AF; + + dev_dbg(&rtc->dev, "%s\n", __func__); + rtc_update_irq(rtc, 1, events); + + return IRQ_HANDLED; +} + +static const struct rtc_class_ops ab8500_rtc_ops = { + .read_time = ab8500_rtc_read_time, + .set_time = ab8500_rtc_set_time, + .read_alarm = ab8500_rtc_read_alarm, + .set_alarm = ab8500_rtc_set_alarm, + .alarm_irq_enable = ab8500_rtc_irq_enable, +}; + +static int __devinit ab8500_rtc_probe(struct platform_device *pdev) +{ + struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); + int err; + struct rtc_device *rtc; + int rtc_ctrl; + int irq; + + irq = platform_get_irq_byname(pdev, "ALARM"); + if (irq < 0) + return irq; + + /* For RTC supply test */ + err = ab8500_set_bits(ab8500, AB8500_RTC_STAT_REG, RTC_STATUS_DATA, + RTC_STATUS_DATA); + if (err < 0) + return err; + + /* Wait for reset by the PorRtc */ + msleep(1); + + rtc_ctrl = ab8500_read(ab8500, AB8500_RTC_STAT_REG); + if (rtc_ctrl < 0) + return rtc_ctrl; + + /* Check if the RTC Supply fails */ + if (!(rtc_ctrl & RTC_STATUS_DATA)) { + dev_err(&pdev->dev, "RTC supply failure\n"); + return -ENODEV; + } + + rtc = rtc_device_register("ab8500-rtc", &pdev->dev, &ab8500_rtc_ops, + THIS_MODULE); + if (IS_ERR(rtc)) { + dev_err(&pdev->dev, "Registration failed\n"); + err = PTR_ERR(rtc); + return err; + } + + err = request_threaded_irq(irq, NULL, rtc_alarm_handler, 0, + "ab8500-rtc", rtc); + if (err < 0) { + rtc_device_unregister(rtc); + return err; + } + + platform_set_drvdata(pdev, rtc); + + return 0; +} + +static int __devexit ab8500_rtc_remove(struct platform_device *pdev) +{ + struct rtc_device *rtc = platform_get_drvdata(pdev); + int irq = platform_get_irq_byname(pdev, "ALARM"); + + free_irq(irq, rtc); + rtc_device_unregister(rtc); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct platform_driver ab8500_rtc_driver = { + .driver = { + .name = "ab8500-rtc", + .owner = THIS_MODULE, + }, + .probe = ab8500_rtc_probe, + .remove = __devexit_p(ab8500_rtc_remove), +}; + +static int __init ab8500_rtc_init(void) +{ + return platform_driver_register(&ab8500_rtc_driver); +} + +static void __exit ab8500_rtc_exit(void) +{ + platform_driver_unregister(&ab8500_rtc_driver); +} + +module_init(ab8500_rtc_init); +module_exit(ab8500_rtc_exit); +MODULE_AUTHOR("Virupax Sadashivpetimath "); +MODULE_DESCRIPTION("AB8500 RTC Driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From a80a0bbee49872c296c9ed9d6af0f510fcd825a7 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Wed, 26 May 2010 14:42:16 -0700 Subject: gpio: add interrupt handling capability to max732x Most of the GPIO expanders supported by the max732x driver have interrupt generation capability by reporting changes on input pins through an INT# pin. This patch implements the irq_chip functionnality (edge detection only). Signed-off-by: Marc Zyngier Cc: Eric Miao Cc: Jebediah Huang Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpio/Kconfig | 7 + drivers/gpio/max732x.c | 355 +++++++++++++++++++++++++++++++++++++++++--- include/linux/i2c/max732x.h | 3 + 3 files changed, 346 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index fee678f74a19..1aa63a2e9af5 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -139,6 +139,13 @@ config GPIO_MAX732X Board setup code must specify the model to use, and the start number for these GPIOs. +config GPIO_MAX732X_IRQ + bool "Interrupt controller support for MAX732x" + depends on GPIO_MAX732X=y && GENERIC_HARDIRQS + help + Say yes here to enable the max732x to be used as an interrupt + controller. It requires the driver to be built in the kernel. + config GPIO_PCA953X tristate "PCA953x, PCA955x, TCA64xx, and MAX7310 I/O ports" depends on I2C diff --git a/drivers/gpio/max732x.c b/drivers/gpio/max732x.c index f7868243af89..2053ba9cbfae 100644 --- a/drivers/gpio/max732x.c +++ b/drivers/gpio/max732x.c @@ -17,7 +17,8 @@ #include #include #include - +#include +#include #include #include @@ -31,7 +32,8 @@ * - Open Drain I/O * * designated by 'O', 'I' and 'P' individually according to MAXIM's - * datasheets. + * datasheets. 'I' and 'P' ports are interrupt capables, some with + * a dedicated interrupt mask. * * There are two groups of I/O ports, each group usually includes * up to 8 I/O ports, and is accessed by a specific I2C address: @@ -44,7 +46,8 @@ * * Within each group of ports, there are five known combinations of * I/O ports: 4I4O, 4P4O, 8I, 8P, 8O, see the definitions below for - * the detailed organization of these ports. + * the detailed organization of these ports. Only Goup A is interrupt + * capable. * * GPIO numbers start from 'gpio_base + 0' to 'gpio_base + 8/16', * and GPIOs from GROUP_A are numbered before those from GROUP_B @@ -68,16 +71,47 @@ #define GROUP_A(x) ((x) & 0xffff) /* I2C Addr: 0b'110xxxx */ #define GROUP_B(x) ((x) << 16) /* I2C Addr: 0b'101xxxx */ +#define INT_NONE 0x0 /* No interrupt capability */ +#define INT_NO_MASK 0x1 /* Has interrupts, no mask */ +#define INT_INDEP_MASK 0x2 /* Has interrupts, independent mask */ +#define INT_MERGED_MASK 0x3 /* Has interrupts, merged mask */ + +#define INT_CAPS(x) (((uint64_t)(x)) << 32) + +enum { + MAX7319, + MAX7320, + MAX7321, + MAX7322, + MAX7323, + MAX7324, + MAX7325, + MAX7326, + MAX7327, +}; + +static uint64_t max732x_features[] = { + [MAX7319] = GROUP_A(IO_8I) | INT_CAPS(INT_MERGED_MASK), + [MAX7320] = GROUP_B(IO_8O), + [MAX7321] = GROUP_A(IO_8P) | INT_CAPS(INT_NO_MASK), + [MAX7322] = GROUP_A(IO_4I4O) | INT_CAPS(INT_MERGED_MASK), + [MAX7323] = GROUP_A(IO_4P4O) | INT_CAPS(INT_INDEP_MASK), + [MAX7324] = GROUP_A(IO_8I) | GROUP_B(IO_8O) | INT_CAPS(INT_MERGED_MASK), + [MAX7325] = GROUP_A(IO_8P) | GROUP_B(IO_8O) | INT_CAPS(INT_NO_MASK), + [MAX7326] = GROUP_A(IO_4I4O) | GROUP_B(IO_8O) | INT_CAPS(INT_MERGED_MASK), + [MAX7327] = GROUP_A(IO_4P4O) | GROUP_B(IO_8O) | INT_CAPS(INT_NO_MASK), +}; + static const struct i2c_device_id max732x_id[] = { - { "max7319", GROUP_A(IO_8I) }, - { "max7320", GROUP_B(IO_8O) }, - { "max7321", GROUP_A(IO_8P) }, - { "max7322", GROUP_A(IO_4I4O) }, - { "max7323", GROUP_A(IO_4P4O) }, - { "max7324", GROUP_A(IO_8I) | GROUP_B(IO_8O) }, - { "max7325", GROUP_A(IO_8P) | GROUP_B(IO_8O) }, - { "max7326", GROUP_A(IO_4I4O) | GROUP_B(IO_8O) }, - { "max7327", GROUP_A(IO_4P4O) | GROUP_B(IO_8O) }, + { "max7319", MAX7319 }, + { "max7320", MAX7320 }, + { "max7321", MAX7321 }, + { "max7322", MAX7322 }, + { "max7323", MAX7323 }, + { "max7324", MAX7324 }, + { "max7325", MAX7325 }, + { "max7326", MAX7326 }, + { "max7327", MAX7327 }, { }, }; MODULE_DEVICE_TABLE(i2c, max732x_id); @@ -96,9 +130,19 @@ struct max732x_chip { struct mutex lock; uint8_t reg_out[2]; + +#ifdef CONFIG_GPIO_MAX732X_IRQ + struct mutex irq_lock; + int irq_base; + uint8_t irq_mask; + uint8_t irq_mask_cur; + uint8_t irq_trig_raise; + uint8_t irq_trig_fall; + uint8_t irq_features; +#endif }; -static int max732x_write(struct max732x_chip *chip, int group_a, uint8_t val) +static int max732x_writeb(struct max732x_chip *chip, int group_a, uint8_t val) { struct i2c_client *client; int ret; @@ -113,7 +157,7 @@ static int max732x_write(struct max732x_chip *chip, int group_a, uint8_t val) return 0; } -static int max732x_read(struct max732x_chip *chip, int group_a, uint8_t *val) +static int max732x_readb(struct max732x_chip *chip, int group_a, uint8_t *val) { struct i2c_client *client; int ret; @@ -142,7 +186,7 @@ static int max732x_gpio_get_value(struct gpio_chip *gc, unsigned off) chip = container_of(gc, struct max732x_chip, gpio_chip); - ret = max732x_read(chip, is_group_a(chip, off), ®_val); + ret = max732x_readb(chip, is_group_a(chip, off), ®_val); if (ret < 0) return 0; @@ -162,7 +206,7 @@ static void max732x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) reg_out = (off > 7) ? chip->reg_out[1] : chip->reg_out[0]; reg_out = (val) ? reg_out | mask : reg_out & ~mask; - ret = max732x_write(chip, is_group_a(chip, off), reg_out); + ret = max732x_writeb(chip, is_group_a(chip, off), reg_out); if (ret < 0) goto out; @@ -209,12 +253,278 @@ static int max732x_gpio_direction_output(struct gpio_chip *gc, return 0; } +#ifdef CONFIG_GPIO_MAX732X_IRQ +static int max732x_writew(struct max732x_chip *chip, uint16_t val) +{ + int ret; + + val = cpu_to_le16(val); + + ret = i2c_master_send(chip->client_group_a, (char *)&val, 2); + if (ret < 0) { + dev_err(&chip->client_group_a->dev, "failed writing\n"); + return ret; + } + + return 0; +} + +static int max732x_readw(struct max732x_chip *chip, uint16_t *val) +{ + int ret; + + ret = i2c_master_recv(chip->client_group_a, (char *)val, 2); + if (ret < 0) { + dev_err(&chip->client_group_a->dev, "failed reading\n"); + return ret; + } + + *val = le16_to_cpu(*val); + return 0; +} + +static void max732x_irq_update_mask(struct max732x_chip *chip) +{ + uint16_t msg; + + if (chip->irq_mask == chip->irq_mask_cur) + return; + + chip->irq_mask = chip->irq_mask_cur; + + if (chip->irq_features == INT_NO_MASK) + return; + + mutex_lock(&chip->lock); + + switch (chip->irq_features) { + case INT_INDEP_MASK: + msg = (chip->irq_mask << 8) | chip->reg_out[0]; + max732x_writew(chip, msg); + break; + + case INT_MERGED_MASK: + msg = chip->irq_mask | chip->reg_out[0]; + max732x_writeb(chip, 1, (uint8_t)msg); + break; + } + + mutex_unlock(&chip->lock); +} + +static int max732x_gpio_to_irq(struct gpio_chip *gc, unsigned off) +{ + struct max732x_chip *chip; + + chip = container_of(gc, struct max732x_chip, gpio_chip); + return chip->irq_base + off; +} + +static void max732x_irq_mask(unsigned int irq) +{ + struct max732x_chip *chip = get_irq_chip_data(irq); + + chip->irq_mask_cur &= ~(1 << (irq - chip->irq_base)); +} + +static void max732x_irq_unmask(unsigned int irq) +{ + struct max732x_chip *chip = get_irq_chip_data(irq); + + chip->irq_mask_cur |= 1 << (irq - chip->irq_base); +} + +static void max732x_irq_bus_lock(unsigned int irq) +{ + struct max732x_chip *chip = get_irq_chip_data(irq); + + mutex_lock(&chip->irq_lock); + chip->irq_mask_cur = chip->irq_mask; +} + +static void max732x_irq_bus_sync_unlock(unsigned int irq) +{ + struct max732x_chip *chip = get_irq_chip_data(irq); + + max732x_irq_update_mask(chip); + mutex_unlock(&chip->irq_lock); +} + +static int max732x_irq_set_type(unsigned int irq, unsigned int type) +{ + struct max732x_chip *chip = get_irq_chip_data(irq); + uint16_t off = irq - chip->irq_base; + uint16_t mask = 1 << off; + + if (!(mask & chip->dir_input)) { + dev_dbg(&chip->client->dev, "%s port %d is output only\n", + chip->client->name, off); + return -EACCES; + } + + if (!(type & IRQ_TYPE_EDGE_BOTH)) { + dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", + irq, type); + return -EINVAL; + } + + if (type & IRQ_TYPE_EDGE_FALLING) + chip->irq_trig_fall |= mask; + else + chip->irq_trig_fall &= ~mask; + + if (type & IRQ_TYPE_EDGE_RISING) + chip->irq_trig_raise |= mask; + else + chip->irq_trig_raise &= ~mask; + + return max732x_gpio_direction_input(&chip->gpio_chip, off); +} + +static struct irq_chip max732x_irq_chip = { + .name = "max732x", + .mask = max732x_irq_mask, + .unmask = max732x_irq_unmask, + .bus_lock = max732x_irq_bus_lock, + .bus_sync_unlock = max732x_irq_bus_sync_unlock, + .set_type = max732x_irq_set_type, +}; + +static uint8_t max732x_irq_pending(struct max732x_chip *chip) +{ + uint8_t cur_stat; + uint8_t old_stat; + uint8_t trigger; + uint8_t pending; + uint16_t status; + int ret; + + ret = max732x_readw(chip, &status); + if (ret) + return 0; + + trigger = status >> 8; + trigger &= chip->irq_mask; + + if (!trigger) + return 0; + + cur_stat = status & 0xFF; + cur_stat &= chip->irq_mask; + + old_stat = cur_stat ^ trigger; + + pending = (old_stat & chip->irq_trig_fall) | + (cur_stat & chip->irq_trig_raise); + pending &= trigger; + + return pending; +} + +static irqreturn_t max732x_irq_handler(int irq, void *devid) +{ + struct max732x_chip *chip = devid; + uint8_t pending; + uint8_t level; + + pending = max732x_irq_pending(chip); + + if (!pending) + return IRQ_HANDLED; + + do { + level = __ffs(pending); + handle_nested_irq(level + chip->irq_base); + + pending &= ~(1 << level); + } while (pending); + + return IRQ_HANDLED; +} + +static int max732x_irq_setup(struct max732x_chip *chip, + const struct i2c_device_id *id) +{ + struct i2c_client *client = chip->client; + struct max732x_platform_data *pdata = client->dev.platform_data; + int has_irq = max732x_features[id->driver_data] >> 32; + int ret; + + if (pdata->irq_base && has_irq != INT_NONE) { + int lvl; + + chip->irq_base = pdata->irq_base; + chip->irq_features = has_irq; + mutex_init(&chip->irq_lock); + + for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) { + int irq = lvl + chip->irq_base; + + if (!(chip->dir_input & (1 << lvl))) + continue; + + set_irq_chip_data(irq, chip); + set_irq_chip_and_handler(irq, &max732x_irq_chip, + handle_edge_irq); + set_irq_nested_thread(irq, 1); +#ifdef CONFIG_ARM + set_irq_flags(irq, IRQF_VALID); +#else + set_irq_noprobe(irq); +#endif + } + + ret = request_threaded_irq(client->irq, + NULL, + max732x_irq_handler, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + dev_name(&client->dev), chip); + if (ret) { + dev_err(&client->dev, "failed to request irq %d\n", + client->irq); + goto out_failed; + } + + chip->gpio_chip.to_irq = max732x_gpio_to_irq; + } + + return 0; + +out_failed: + chip->irq_base = 0; + return ret; +} + +static void max732x_irq_teardown(struct max732x_chip *chip) +{ + if (chip->irq_base) + free_irq(chip->client->irq, chip); +} +#else /* CONFIG_GPIO_MAX732X_IRQ */ +static int max732x_irq_setup(struct max732x_chip *chip, + const struct i2c_device_id *id) +{ + struct i2c_client *client = chip->client; + struct max732x_platform_data *pdata = client->dev.platform_data; + int has_irq = max732x_features[id->driver_data] >> 32; + + if (pdata->irq_base && has_irq != INT_NONE) + dev_warn(&client->dev, "interrupt support not compiled in\n"); + + return 0; +} + +static void max732x_irq_teardown(struct max732x_chip *chip) +{ +} +#endif + static int __devinit max732x_setup_gpio(struct max732x_chip *chip, const struct i2c_device_id *id, unsigned gpio_start) { struct gpio_chip *gc = &chip->gpio_chip; - uint32_t id_data = id->driver_data; + uint32_t id_data = (uint32_t)max732x_features[id->driver_data]; int i, port = 0; for (i = 0; i < 16; i++, id_data >>= 2) { @@ -306,9 +616,13 @@ static int __devinit max732x_probe(struct i2c_client *client, mutex_init(&chip->lock); - max732x_read(chip, is_group_a(chip, 0), &chip->reg_out[0]); + max732x_readb(chip, is_group_a(chip, 0), &chip->reg_out[0]); if (nr_port > 7) - max732x_read(chip, is_group_a(chip, 8), &chip->reg_out[1]); + max732x_readb(chip, is_group_a(chip, 8), &chip->reg_out[1]); + + ret = max732x_irq_setup(chip, id); + if (ret) + goto out_failed; ret = gpiochip_add(&chip->gpio_chip); if (ret) @@ -325,6 +639,7 @@ static int __devinit max732x_probe(struct i2c_client *client, return 0; out_failed: + max732x_irq_teardown(chip); kfree(chip); return ret; } @@ -352,6 +667,8 @@ static int __devexit max732x_remove(struct i2c_client *client) return ret; } + max732x_irq_teardown(chip); + /* unregister any dummy i2c_client */ if (chip->client_dummy) i2c_unregister_device(chip->client_dummy); diff --git a/include/linux/i2c/max732x.h b/include/linux/i2c/max732x.h index e10336631c62..c04bac8bf2fe 100644 --- a/include/linux/i2c/max732x.h +++ b/include/linux/i2c/max732x.h @@ -7,6 +7,9 @@ struct max732x_platform_data { /* number of the first GPIO */ unsigned gpio_base; + /* interrupt base */ + int irq_base; + void *context; /* param to setup/teardown */ int (*setup)(struct i2c_client *client, -- cgit v1.2.3 From 62154991a8b2b932112d39bf4aeaab37fa7b9a31 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 26 May 2010 14:42:17 -0700 Subject: gpiolib: make names array and its values const MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gpiolib doesn't need to modify the names and I assume most initializers use string constants that shouldn't be modified anyhow. [akpm@linux-foundation.org: fix drivers/gpio/cs5535-gpio.c] Signed-off-by: Uwe Kleine-König Cc: Kevin Wells Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpio/cs5535-gpio.c | 2 +- drivers/gpio/gpiolib.c | 2 +- drivers/gpio/pca953x.c | 2 +- include/asm-generic/gpio.h | 2 +- include/linux/i2c/pca953x.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/cs5535-gpio.c b/drivers/gpio/cs5535-gpio.c index 0c3c498f2260..f73a1555e49d 100644 --- a/drivers/gpio/cs5535-gpio.c +++ b/drivers/gpio/cs5535-gpio.c @@ -197,7 +197,7 @@ static int chip_direction_output(struct gpio_chip *c, unsigned offset, int val) return 0; } -static char *cs5535_gpio_names[] = { +static const char * const cs5535_gpio_names[] = { "GPIO0", "GPIO1", "GPIO2", "GPIO3", "GPIO4", "GPIO5", "GPIO6", "GPIO7", "GPIO8", "GPIO9", "GPIO10", "GPIO11", diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index cae1b8c5b08c..ce267ee4b94e 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -722,7 +722,7 @@ int gpio_export(unsigned gpio, bool direction_may_change) unsigned long flags; struct gpio_desc *desc; int status = -EINVAL; - char *ioname = NULL; + const char *ioname = NULL; /* can't export until sysfs is available ... */ if (!gpio_class.p) { diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index f156ab3bb6ed..a2b12aa1f2b9 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c @@ -73,7 +73,7 @@ struct pca953x_chip { struct i2c_client *client; struct pca953x_platform_data *dyn_pdata; struct gpio_chip gpio_chip; - char **names; + const char *const *names; }; static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val) diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 979c6a57f2f1..bc0c14da7162 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -98,7 +98,7 @@ struct gpio_chip { struct gpio_chip *chip); int base; u16 ngpio; - char **names; + const char *const *names; unsigned can_sleep:1; unsigned exported:1; }; diff --git a/include/linux/i2c/pca953x.h b/include/linux/i2c/pca953x.h index d5c5a60c8a0b..139ba52667c8 100644 --- a/include/linux/i2c/pca953x.h +++ b/include/linux/i2c/pca953x.h @@ -24,7 +24,7 @@ struct pca953x_platform_data { int (*teardown)(struct i2c_client *client, unsigned gpio, unsigned ngpio, void *context); - char **names; + const char *const *names; }; #endif /* _LINUX_PCA953X_H */ -- cgit v1.2.3 From 7cfe1395b28c472e569db6595a27bfefb161a7bc Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 26 May 2010 14:42:18 -0700 Subject: gpiolib: a gpio is unsigned, so use %u to print it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpio/gpiolib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index ce267ee4b94e..05019c15a868 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -753,7 +753,7 @@ int gpio_export(unsigned gpio, bool direction_may_change) struct device *dev; dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), - desc, ioname ? ioname : "gpio%d", gpio); + desc, ioname ? ioname : "gpio%u", gpio); if (!IS_ERR(dev)) { status = sysfs_create_group(&dev->kobj, &gpio_attr_group); -- cgit v1.2.3 From c1cc9b9775c931a0015178daf92d41aec00580de Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 26 May 2010 14:42:19 -0700 Subject: pl061: fix offset value range checking The valid offset value is 0..PL061_GPIO_NR-1, this patch corrects the offset value range checking. Signed-off-by: Axel Lin Acked-by: Baruch Siach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpio/pl061.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpio/pl061.c b/drivers/gpio/pl061.c index 105701a1f05b..ee568c8fcbd0 100644 --- a/drivers/gpio/pl061.c +++ b/drivers/gpio/pl061.c @@ -164,7 +164,7 @@ static int pl061_irq_type(unsigned irq, unsigned trigger) unsigned long flags; u8 gpiois, gpioibe, gpioiev; - if (offset < 0 || offset > PL061_GPIO_NR) + if (offset < 0 || offset >= PL061_GPIO_NR) return -EINVAL; spin_lock_irqsave(&chip->irq_lock, flags); -- cgit v1.2.3 From 5535cb681c38bda94af02ef4b043a25b52303e65 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 26 May 2010 14:42:20 -0700 Subject: max732x: correct nr_port checking off by one error Setup both client_group_a and client_group_b if nr_port > 8 (not including nr_port==8). Signed-off-by: Axel Lin Cc: Eric Miao Cc: Ben Dooks Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpio/max732x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/max732x.c b/drivers/gpio/max732x.c index 2053ba9cbfae..26ff40110d9f 100644 --- a/drivers/gpio/max732x.c +++ b/drivers/gpio/max732x.c @@ -595,14 +595,14 @@ static int __devinit max732x_probe(struct i2c_client *client, switch (client->addr & 0x70) { case 0x60: chip->client_group_a = client; - if (nr_port > 7) { + if (nr_port > 8) { c = i2c_new_dummy(client->adapter, addr_b); chip->client_group_b = chip->client_dummy = c; } break; case 0x50: chip->client_group_b = client; - if (nr_port > 7) { + if (nr_port > 8) { c = i2c_new_dummy(client->adapter, addr_a); chip->client_group_a = chip->client_dummy = c; } @@ -617,7 +617,7 @@ static int __devinit max732x_probe(struct i2c_client *client, mutex_init(&chip->lock); max732x_readb(chip, is_group_a(chip, 0), &chip->reg_out[0]); - if (nr_port > 7) + if (nr_port > 8) max732x_readb(chip, is_group_a(chip, 8), &chip->reg_out[1]); ret = max732x_irq_setup(chip, id); -- cgit v1.2.3 From a13c1868aa60ae7a2516b8d00ee8873dea587581 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Wed, 26 May 2010 14:42:21 -0700 Subject: gpio: max732x: fix input configuration for open-drain pins Fix a bug I noticed while hacking on the max732x driver for interrupt support. According to the datasheets, open-drain pins have to be configured as output-high (which in that case is actually high impedance) to be used as input. Signed-off-by: Marc Zyngier Acked-by: Eric Miao Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpio/max732x.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/gpio/max732x.c b/drivers/gpio/max732x.c index 26ff40110d9f..9cad60f9e962 100644 --- a/drivers/gpio/max732x.c +++ b/drivers/gpio/max732x.c @@ -232,6 +232,13 @@ static int max732x_gpio_direction_input(struct gpio_chip *gc, unsigned off) return -EACCES; } + /* + * Open-drain pins must be set to high impedance (which is + * equivalent to output-high) to be turned into an input. + */ + if ((mask & chip->dir_output)) + max732x_gpio_set_value(gc, off, 1); + return 0; } -- cgit v1.2.3 From 796a8e423ac8afe9e98ad96e668f50142bdd7825 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 26 May 2010 14:42:21 -0700 Subject: gpiolib: make gpiochip_add() show a better error message The current message, 'not registered' is confusing as it implies it was not registered with something, whereas printing 'failed to register' implies it was the gpiochip_add() call that did not work correctly. Signed-off-by: Ben Dooks Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpio/gpiolib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 05019c15a868..362a613d266e 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1106,7 +1106,7 @@ unlock: fail: /* failures here can mean systems won't boot... */ if (status) - pr_err("gpiochip_add: gpios %d..%d (%s) not registered\n", + pr_err("gpiochip_add: gpios %d..%d (%s) failed to register\n", chip->base, chip->base + chip->ngpio - 1, chip->label ? : "generic"); return status; -- cgit v1.2.3 From c4b5be98fe78508e7199d6919eb712feba9a4f01 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 26 May 2010 14:42:23 -0700 Subject: gpiolib: introduce set_debounce method A few architectures, like OMAP, allow you to set a debouncing time for the gpio before generating the IRQ. Teach gpiolib about that. Mark said: : This would be generally useful for embedded systems, especially where : the interrupt concerned is a wake source. It allows drivers to avoid : spurious interrupts from noisy sources so if the hardware supports it : the driver can avoid having to explicitly wait for the signal to become : stable and software has to cope with fewer events. We've lived without : it for quite some time, though. David said: : I looked at adding debounce support to the generic GPIO calls (and thus : gpiolib) some time back, but decided against it. I forget why at this : time (check list archives) but it wasn't because of lack of utility in : certain contexts. : : One thing to watch out for is just how variable the hardware capabilities : are. Atmel GPIOs have something like a fixed number of 32K clock cycles : for debounce, twl4030 had something odd, OMAPs were more like the Atmel : chips but with a different clock. In some cases debouncing had to be : ganged, not per-GPIO. And so forth. Signed-off-by: Felipe Balbi Cc: Tony Lindgren Cc: David Brownell Reviewed-by: Mark Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpio/gpiolib.c | 43 +++++++++++++++++++++++++++++++++++++++++++ include/asm-generic/gpio.h | 5 +++++ include/linux/gpio.h | 5 +++++ 3 files changed, 53 insertions(+) (limited to 'drivers') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 362a613d266e..3ca36542e338 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1447,6 +1447,49 @@ fail: } EXPORT_SYMBOL_GPL(gpio_direction_output); +/** + * gpio_set_debounce - sets @debounce time for a @gpio + * @gpio: the gpio to set debounce time + * @debounce: debounce time is microseconds + */ +int gpio_set_debounce(unsigned gpio, unsigned debounce) +{ + unsigned long flags; + struct gpio_chip *chip; + struct gpio_desc *desc = &gpio_desc[gpio]; + int status = -EINVAL; + + spin_lock_irqsave(&gpio_lock, flags); + + if (!gpio_is_valid(gpio)) + goto fail; + chip = desc->chip; + if (!chip || !chip->set || !chip->set_debounce) + goto fail; + gpio -= chip->base; + if (gpio >= chip->ngpio) + goto fail; + status = gpio_ensure_requested(desc, gpio); + if (status < 0) + goto fail; + + /* now we know the gpio is valid and chip won't vanish */ + + spin_unlock_irqrestore(&gpio_lock, flags); + + might_sleep_if(extra_checks && chip->can_sleep); + + return chip->set_debounce(chip, gpio, debounce); + +fail: + spin_unlock_irqrestore(&gpio_lock, flags); + if (status) + pr_debug("%s: gpio-%d status %d\n", + __func__, gpio, status); + + return status; +} +EXPORT_SYMBOL_GPL(gpio_set_debounce); /* I/O calls are only valid after configuration completed; the relevant * "is this a valid GPIO" error checks should already have been done. diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index fb1ecf8baa90..4f3d75e1ad39 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -90,6 +90,9 @@ struct gpio_chip { unsigned offset); int (*direction_output)(struct gpio_chip *chip, unsigned offset, int value); + int (*set_debounce)(struct gpio_chip *chip, + unsigned offset, unsigned debounce); + void (*set)(struct gpio_chip *chip, unsigned offset, int value); @@ -123,6 +126,8 @@ extern void gpio_free(unsigned gpio); extern int gpio_direction_input(unsigned gpio); extern int gpio_direction_output(unsigned gpio, int value); +extern int gpio_set_debounce(unsigned gpio, unsigned debounce); + extern int gpio_get_value_cansleep(unsigned gpio); extern void gpio_set_value_cansleep(unsigned gpio, int value); diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 4e949a5b5b85..03f616b78cfa 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h @@ -51,6 +51,11 @@ static inline int gpio_direction_output(unsigned gpio, int value) return -ENOSYS; } +static inline int gpio_set_debounce(unsigned gpio, unsigned debounce) +{ + return -ENOSYS; +} + static inline int gpio_get_value(unsigned gpio) { /* GPIO can never have been requested or set as {in,out}put */ -- cgit v1.2.3 From 8081c84c9ce71ef73e591e19f1f7a516cb111e1c Mon Sep 17 00:00:00 2001 From: Alek Du Date: Wed, 26 May 2010 14:42:25 -0700 Subject: gpio: add Penwell gpio support Intel Penwell chip has two 96 pins GPIO blocks, which are very similiar as Intel Langwell chip GPIO block, except for pin number difference. This patch expends the original Langwell GPIO driver to support Penwell's. Signed-off-by: Alek Du Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpio/Kconfig | 4 +-- drivers/gpio/langwell_gpio.c | 83 +++++++++++++++++++++++++++----------------- 2 files changed, 53 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 1aa63a2e9af5..4fd0f276df5a 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -271,10 +271,10 @@ config GPIO_BT8XX If unsure, say N. config GPIO_LANGWELL - bool "Intel Moorestown Platform Langwell GPIO support" + bool "Intel Langwell/Penwell GPIO support" depends on PCI help - Say Y here to support Intel Moorestown platform GPIO. + Say Y here to support Intel Langwell/Penwell GPIO. config GPIO_TIMBERDALE bool "Support for timberdale GPIO IP" diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c index 00c3a14127af..8383a8d7f994 100644 --- a/drivers/gpio/langwell_gpio.c +++ b/drivers/gpio/langwell_gpio.c @@ -17,6 +17,7 @@ /* Supports: * Moorestown platform Langwell chip. + * Medfield platform Penwell chip. */ #include @@ -31,44 +32,65 @@ #include #include -struct lnw_gpio_register { - u32 GPLR[2]; - u32 GPDR[2]; - u32 GPSR[2]; - u32 GPCR[2]; - u32 GRER[2]; - u32 GFER[2]; - u32 GEDR[2]; +/* + * Langwell chip has 64 pins and thus there are 2 32bit registers to control + * each feature, while Penwell chip has 96 pins for each block, and need 3 32bit + * registers to control them, so we only define the order here instead of a + * structure, to get a bit offset for a pin (use GPDR as an example): + * + * nreg = ngpio / 32; + * reg = offset / 32; + * bit = offset % 32; + * reg_addr = reg_base + GPDR * nreg * 4 + reg * 4; + * + * so the bit of reg_addr is to control pin offset's GPDR feature +*/ + +enum GPIO_REG { + GPLR = 0, /* pin level read-only */ + GPDR, /* pin direction */ + GPSR, /* pin set */ + GPCR, /* pin clear */ + GRER, /* rising edge detect */ + GFER, /* falling edge detect */ + GEDR, /* edge detect result */ }; struct lnw_gpio { struct gpio_chip chip; - struct lnw_gpio_register *reg_base; + void *reg_base; spinlock_t lock; unsigned irq_base; }; -static int lnw_gpio_get(struct gpio_chip *chip, unsigned offset) +static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset, + enum GPIO_REG reg_type) { struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip); + unsigned nreg = chip->ngpio / 32; u8 reg = offset / 32; - void __iomem *gplr; + void __iomem *ptr; + + ptr = (void __iomem *)(lnw->reg_base + reg_type * nreg * 4 + reg * 4); + return ptr; +} + +static int lnw_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + void __iomem *gplr = gpio_reg(chip, offset, GPLR); - gplr = (void __iomem *)(&lnw->reg_base->GPLR[reg]); return readl(gplr) & BIT(offset % 32); } static void lnw_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { - struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip); - u8 reg = offset / 32; void __iomem *gpsr, *gpcr; if (value) { - gpsr = (void __iomem *)(&lnw->reg_base->GPSR[reg]); + gpsr = gpio_reg(chip, offset, GPSR); writel(BIT(offset % 32), gpsr); } else { - gpcr = (void __iomem *)(&lnw->reg_base->GPCR[reg]); + gpcr = gpio_reg(chip, offset, GPCR); writel(BIT(offset % 32), gpcr); } } @@ -76,12 +98,10 @@ static void lnw_gpio_set(struct gpio_chip *chip, unsigned offset, int value) static int lnw_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip); - u8 reg = offset / 32; + void __iomem *gpdr = gpio_reg(chip, offset, GPDR); u32 value; unsigned long flags; - void __iomem *gpdr; - gpdr = (void __iomem *)(&lnw->reg_base->GPDR[reg]); spin_lock_irqsave(&lnw->lock, flags); value = readl(gpdr); value &= ~BIT(offset % 32); @@ -94,12 +114,10 @@ static int lnw_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value) { struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip); - u8 reg = offset / 32; + void __iomem *gpdr = gpio_reg(chip, offset, GPDR); unsigned long flags; - void __iomem *gpdr; lnw_gpio_set(chip, offset, value); - gpdr = (void __iomem *)(&lnw->reg_base->GPDR[reg]); spin_lock_irqsave(&lnw->lock, flags); value = readl(gpdr); value |= BIT(offset % 32);; @@ -118,11 +136,10 @@ static int lnw_irq_type(unsigned irq, unsigned type) { struct lnw_gpio *lnw = get_irq_chip_data(irq); u32 gpio = irq - lnw->irq_base; - u8 reg = gpio / 32; unsigned long flags; u32 value; - void __iomem *grer = (void __iomem *)(&lnw->reg_base->GRER[reg]); - void __iomem *gfer = (void __iomem *)(&lnw->reg_base->GFER[reg]); + void __iomem *grer = gpio_reg(&lnw->chip, gpio, GRER); + void __iomem *gfer = gpio_reg(&lnw->chip, gpio, GFER); if (gpio >= lnw->chip.ngpio) return -EINVAL; @@ -158,8 +175,10 @@ static struct irq_chip lnw_irqchip = { .set_type = lnw_irq_type, }; -static struct pci_device_id lnw_gpio_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080f) }, +static DEFINE_PCI_DEVICE_TABLE(lnw_gpio_ids) = { /* pin number */ + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080f), .driver_data = 64 }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081f), .driver_data = 96 }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081a), .driver_data = 96 }, { 0, } }; MODULE_DEVICE_TABLE(pci, lnw_gpio_ids); @@ -167,17 +186,17 @@ MODULE_DEVICE_TABLE(pci, lnw_gpio_ids); static void lnw_irq_handler(unsigned irq, struct irq_desc *desc) { struct lnw_gpio *lnw = (struct lnw_gpio *)get_irq_data(irq); - u32 reg, gpio; + u32 base, gpio; void __iomem *gedr; u32 gedr_v; /* check GPIO controller to check which pin triggered the interrupt */ - for (reg = 0; reg < lnw->chip.ngpio / 32; reg++) { - gedr = (void __iomem *)(&lnw->reg_base->GEDR[reg]); + for (base = 0; base < lnw->chip.ngpio; base += 32) { + gedr = gpio_reg(&lnw->chip, base, GEDR); gedr_v = readl(gedr); if (!gedr_v) continue; - for (gpio = reg*32; gpio < reg*32+32; gpio++) + for (gpio = base; gpio < base + 32; gpio++) if (gedr_v & BIT(gpio % 32)) { pr_debug("pin %d triggered\n", gpio); generic_handle_irq(lnw->irq_base + gpio); @@ -245,7 +264,7 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, lnw->chip.set = lnw_gpio_set; lnw->chip.to_irq = lnw_gpio_to_irq; lnw->chip.base = gpio_base; - lnw->chip.ngpio = 64; + lnw->chip.ngpio = id->driver_data; lnw->chip.can_sleep = 0; pci_set_drvdata(pdev, lnw); retval = gpiochip_add(&lnw->chip); -- cgit v1.2.3 From 48baa18b250d5e36ed9f9bb04cdf812d74da08ca Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 26 May 2010 14:42:26 -0700 Subject: drivers/gpio/it8761e_gpio: check return value of gpiochip_remove() This eliminates the following build warning: drivers/gpio/it8761e_gpio.c: In function `it8761e_gpio_exit': drivers/gpio/it8761e_gpio.c:220: warning: ignoring return value of `gpiochip_remove', declared with attribute warn_unused_result Signed-off-by: Daniel Mack Cc: Denis Turischev Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpio/it8761e_gpio.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpio/it8761e_gpio.c b/drivers/gpio/it8761e_gpio.c index 41a9388f2fde..48fc43c4bdd1 100644 --- a/drivers/gpio/it8761e_gpio.c +++ b/drivers/gpio/it8761e_gpio.c @@ -217,7 +217,10 @@ gpiochip_add_err: static void __exit it8761e_gpio_exit(void) { if (gpio_ba) { - gpiochip_remove(&it8761e_gpio_chip); + int ret = gpiochip_remove(&it8761e_gpio_chip); + + WARN(ret, "%s(): gpiochip_remove() failed, ret=%d\n", + __func__, ret); release_region(gpio_ba, GPIO_IOSIZE); gpio_ba = 0; -- cgit v1.2.3 From 9966c4fea578bcf356c35cdf184cdacde495bc2c Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Wed, 26 May 2010 14:42:27 -0700 Subject: add support for S3 Trio3D/1X/2X Add support for S3 Trio3D/1X (86C360) and S3 Trio3D/2X (86C362 and 86C368) cards to s3fb driver. Tested with 86C362 AGP and 86C368 PCI&AGP. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Ondrej Zary Acked-by: Ondrej Zajicek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/s3fb.c | 101 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 81 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c index d4471b4c0374..dce8c97b4333 100644 --- a/drivers/video/s3fb.c +++ b/drivers/video/s3fb.c @@ -71,7 +71,8 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64", "S3 Trio64UV+", "S3 Trio64V2/DX", "S3 Trio64V2/GX", "S3 Plato/PX", "S3 Aurora64VP", "S3 Virge", "S3 Virge/VX", "S3 Virge/DX", "S3 Virge/GX", - "S3 Virge/GX2", "S3 Virge/GX2P", "S3 Virge/GX2P"}; + "S3 Virge/GX2", "S3 Virge/GX2P", "S3 Virge/GX2P", + "S3 Trio3D/1X", "S3 Trio3D/2X", "S3 Trio3D/2X"}; #define CHIP_UNKNOWN 0x00 #define CHIP_732_TRIO32 0x01 @@ -89,10 +90,14 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64", #define CHIP_356_VIRGE_GX2 0x0D #define CHIP_357_VIRGE_GX2P 0x0E #define CHIP_359_VIRGE_GX2P 0x0F +#define CHIP_360_TRIO3D_1X 0x10 +#define CHIP_362_TRIO3D_2X 0x11 +#define CHIP_368_TRIO3D_2X 0x12 #define CHIP_XXX_TRIO 0x80 #define CHIP_XXX_TRIO64V2_DXGX 0x81 #define CHIP_XXX_VIRGE_DXGX 0x82 +#define CHIP_36X_TRIO3D_1X_2X 0x83 #define CHIP_UNDECIDED_FLAG 0x80 #define CHIP_MASK 0xFF @@ -324,6 +329,7 @@ static void s3fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) static void s3_set_pixclock(struct fb_info *info, u32 pixclock) { + struct s3fb_info *par = info->par; u16 m, n, r; u8 regval; int rv; @@ -339,7 +345,13 @@ static void s3_set_pixclock(struct fb_info *info, u32 pixclock) vga_w(NULL, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD); /* Set S3 clock registers */ - vga_wseq(NULL, 0x12, ((n - 2) | (r << 5))); + if (par->chip == CHIP_360_TRIO3D_1X || + par->chip == CHIP_362_TRIO3D_2X || + par->chip == CHIP_368_TRIO3D_2X) { + vga_wseq(NULL, 0x12, (n - 2) | ((r & 3) << 6)); /* n and two bits of r */ + vga_wseq(NULL, 0x29, r >> 2); /* remaining highest bit of r */ + } else + vga_wseq(NULL, 0x12, (n - 2) | (r << 5)); vga_wseq(NULL, 0x13, m - 2); udelay(1000); @@ -456,7 +468,7 @@ static int s3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) static int s3fb_set_par(struct fb_info *info) { struct s3fb_info *par = info->par; - u32 value, mode, hmul, offset_value, screen_size, multiplex; + u32 value, mode, hmul, offset_value, screen_size, multiplex, dbytes; u32 bpp = info->var.bits_per_pixel; if (bpp != 0) { @@ -518,7 +530,7 @@ static int s3fb_set_par(struct fb_info *info) svga_wcrt_mask(0x33, 0x00, 0x08); /* no DDR ? */ svga_wcrt_mask(0x43, 0x00, 0x01); /* no DDR ? */ - svga_wcrt_mask(0x5D, 0x00, 0x28); // Clear strange HSlen bits + svga_wcrt_mask(0x5D, 0x00, 0x28); /* Clear strange HSlen bits */ /* svga_wcrt_mask(0x58, 0x03, 0x03); */ @@ -530,10 +542,14 @@ static int s3fb_set_par(struct fb_info *info) pr_debug("fb%d: offset register : %d\n", info->node, offset_value); svga_wcrt_multi(s3_offset_regs, offset_value); - vga_wcrt(NULL, 0x54, 0x18); /* M parameter */ - vga_wcrt(NULL, 0x60, 0xff); /* N parameter */ - vga_wcrt(NULL, 0x61, 0xff); /* L parameter */ - vga_wcrt(NULL, 0x62, 0xff); /* L parameter */ + if (par->chip != CHIP_360_TRIO3D_1X && + par->chip != CHIP_362_TRIO3D_2X && + par->chip != CHIP_368_TRIO3D_2X) { + vga_wcrt(NULL, 0x54, 0x18); /* M parameter */ + vga_wcrt(NULL, 0x60, 0xff); /* N parameter */ + vga_wcrt(NULL, 0x61, 0xff); /* L parameter */ + vga_wcrt(NULL, 0x62, 0xff); /* L parameter */ + } vga_wcrt(NULL, 0x3A, 0x35); svga_wattr(0x33, 0x00); @@ -570,6 +586,16 @@ static int s3fb_set_par(struct fb_info *info) vga_wcrt(NULL, 0x66, 0x90); } + if (par->chip == CHIP_360_TRIO3D_1X || + par->chip == CHIP_362_TRIO3D_2X || + par->chip == CHIP_368_TRIO3D_2X) { + dbytes = info->var.xres * ((bpp+7)/8); + vga_wcrt(NULL, 0x91, (dbytes + 7) / 8); + vga_wcrt(NULL, 0x90, (((dbytes + 7) / 8) >> 8) | 0x80); + + vga_wcrt(NULL, 0x66, 0x81); + } + svga_wcrt_mask(0x31, 0x00, 0x40); multiplex = 0; hmul = 1; @@ -615,11 +641,13 @@ static int s3fb_set_par(struct fb_info *info) break; case 3: pr_debug("fb%d: 8 bit pseudocolor\n", info->node); - if (info->var.pixclock > 20000) { - svga_wcrt_mask(0x50, 0x00, 0x30); + svga_wcrt_mask(0x50, 0x00, 0x30); + if (info->var.pixclock > 20000 || + par->chip == CHIP_360_TRIO3D_1X || + par->chip == CHIP_362_TRIO3D_2X || + par->chip == CHIP_368_TRIO3D_2X) svga_wcrt_mask(0x67, 0x00, 0xF0); - } else { - svga_wcrt_mask(0x50, 0x00, 0x30); + else { svga_wcrt_mask(0x67, 0x10, 0xF0); multiplex = 1; } @@ -634,7 +662,10 @@ static int s3fb_set_par(struct fb_info *info) } else { svga_wcrt_mask(0x50, 0x10, 0x30); svga_wcrt_mask(0x67, 0x30, 0xF0); - hmul = 2; + if (par->chip != CHIP_360_TRIO3D_1X && + par->chip != CHIP_362_TRIO3D_2X && + par->chip != CHIP_368_TRIO3D_2X) + hmul = 2; } break; case 5: @@ -647,7 +678,10 @@ static int s3fb_set_par(struct fb_info *info) } else { svga_wcrt_mask(0x50, 0x10, 0x30); svga_wcrt_mask(0x67, 0x50, 0xF0); - hmul = 2; + if (par->chip != CHIP_360_TRIO3D_1X && + par->chip != CHIP_362_TRIO3D_2X && + par->chip != CHIP_368_TRIO3D_2X) + hmul = 2; } break; case 6: @@ -866,6 +900,17 @@ static int __devinit s3_identification(int chip) return CHIP_385_VIRGE_GX; } + if (chip == CHIP_36X_TRIO3D_1X_2X) { + switch (vga_rcrt(NULL, 0x2f)) { + case 0x00: + return CHIP_360_TRIO3D_1X; + case 0x01: + return CHIP_362_TRIO3D_2X; + case 0x02: + return CHIP_368_TRIO3D_2X; + } + } + return CHIP_UNKNOWN; } @@ -930,17 +975,32 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i vga_wcrt(NULL, 0x38, 0x48); vga_wcrt(NULL, 0x39, 0xA5); - /* Find how many physical memory there is on card */ - /* 0x36 register is accessible even if other registers are locked */ - regval = vga_rcrt(NULL, 0x36); - info->screen_size = s3_memsizes[regval >> 5] << 10; - info->fix.smem_len = info->screen_size; - + /* Identify chip type */ par->chip = id->driver_data & CHIP_MASK; par->rev = vga_rcrt(NULL, 0x2f); if (par->chip & CHIP_UNDECIDED_FLAG) par->chip = s3_identification(par->chip); + /* Find how many physical memory there is on card */ + /* 0x36 register is accessible even if other registers are locked */ + regval = vga_rcrt(NULL, 0x36); + if (par->chip == CHIP_360_TRIO3D_1X || + par->chip == CHIP_362_TRIO3D_2X || + par->chip == CHIP_368_TRIO3D_2X) { + switch ((regval & 0xE0) >> 5) { + case 0: /* 8MB -- only 4MB usable for display */ + case 1: /* 4MB with 32-bit bus */ + case 2: /* 4MB */ + info->screen_size = 4 << 20; + break; + case 6: /* 2MB */ + info->screen_size = 2 << 20; + break; + } + } else + info->screen_size = s3_memsizes[regval >> 5] << 10; + info->fix.smem_len = info->screen_size; + /* Find MCLK frequency */ regval = vga_rseq(NULL, 0x10); par->mclk_freq = ((vga_rseq(NULL, 0x11) + 2) * 14318) / ((regval & 0x1F) + 2); @@ -1131,6 +1191,7 @@ static struct pci_device_id s3_devices[] __devinitdata = { {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A10), .driver_data = CHIP_356_VIRGE_GX2}, {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A11), .driver_data = CHIP_357_VIRGE_GX2P}, {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P}, + {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A13), .driver_data = CHIP_36X_TRIO3D_1X_2X}, {0, 0, 0, 0, 0, 0, 0} }; -- cgit v1.2.3 From a51faabc666c054cb2d983fcd5152aa6d0b80604 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 26 May 2010 14:42:29 -0700 Subject: drivers/video/via: use memdup_user Use memdup_user when user data is immediately copied into the allocated region. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression from,to,size,flag; position p; identifier l1,l2; @@ - to = \(kmalloc@p\|kzalloc@p\)(size,flag); + to = memdup_user(from,size); if ( - to==NULL + IS_ERR(to) || ...) { <+... when != goto l1; - -ENOMEM + PTR_ERR(to) ...+> } - if (copy_from_user(to, from, size) != 0) { - <+... when != goto l2; - -EFAULT - ...+> - } // Signed-off-by: Julia Lawall Cc: Joseph Chan Cc: Scott Fang Cc: Florian Tobias Schandinat Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/via/viafbdev.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 2bc40e682f95..1082541358f0 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -578,14 +578,9 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) break; case VIAFB_SET_GAMMA_LUT: - viafb_gamma_table = kmalloc(256 * sizeof(u32), GFP_KERNEL); - if (!viafb_gamma_table) - return -ENOMEM; - if (copy_from_user(viafb_gamma_table, argp, - 256 * sizeof(u32))) { - kfree(viafb_gamma_table); - return -EFAULT; - } + viafb_gamma_table = memdup_user(argp, 256 * sizeof(u32)); + if (IS_ERR(viafb_gamma_table)) + return PTR_ERR(viafb_gamma_table); viafb_set_gamma_table(viafb_bpp, viafb_gamma_table); kfree(viafb_gamma_table); break; -- cgit v1.2.3 From d11991cbacaa9283de2b6e362e7ec5f21bc40044 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 26 May 2010 14:42:30 -0700 Subject: fbdev: bfin-t350mcqb-fb: avoid unused warnings in backlight code The current backlight code is stubbed out, so the new props changes added some warnings about unused label/prop. Signed-off-by: Mike Frysinger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/bfin-t350mcqb-fb.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c index c2ec3dcd4e91..7a50272eaab9 100644 --- a/drivers/video/bfin-t350mcqb-fb.c +++ b/drivers/video/bfin-t350mcqb-fb.c @@ -420,7 +420,9 @@ static irqreturn_t bfin_t350mcqb_irq_error(int irq, void *dev_id) static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev) { +#ifndef NO_BL_SUPPORT struct backlight_properties props; +#endif struct bfin_t350mcqbfb_info *info; struct fb_info *fbinfo; int ret; @@ -550,7 +552,8 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev) printk(KERN_ERR DRIVER_NAME ": unable to register backlight.\n"); ret = -EINVAL; - goto out9; + unregister_framebuffer(fbinfo); + goto out8; } lcd_dev = lcd_device_register(DRIVER_NAME, NULL, &bfin_lcd_ops); @@ -559,8 +562,6 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev) return 0; -out9: - unregister_framebuffer(fbinfo); out8: free_irq(info->irq, info); out7: -- cgit v1.2.3 From 8fc809d17984f18fbad7ae23e47a62b195969c19 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 26 May 2010 14:42:31 -0700 Subject: fbdev: bf54x-lq043fb: fix unused warnings with backlight code The current backlight code is stubbed out, so the new props changes added some warnings: drivers/video/bf54x-lq043fb.c: In function 'bfin_bf54x_probe': drivers/video/bf54x-lq043fb.c:666: warning: label 'out9' defined but not used drivers/video/bf54x-lq043fb.c:504: warning: unused variable 'props' Fix em ! Signed-off-by: Mike Frysinger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/bf54x-lq043fb.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c index 23b2a8c0dbfc..b020ba7f1cf2 100644 --- a/drivers/video/bf54x-lq043fb.c +++ b/drivers/video/bf54x-lq043fb.c @@ -501,7 +501,9 @@ static irqreturn_t bfin_bf54x_irq_error(int irq, void *dev_id) static int __devinit bfin_bf54x_probe(struct platform_device *pdev) { +#ifndef NO_BL_SUPPORT struct backlight_properties props; +#endif struct bfin_bf54xfb_info *info; struct fb_info *fbinfo; int ret; @@ -654,7 +656,8 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev) printk(KERN_ERR DRIVER_NAME ": unable to register backlight.\n"); ret = -EINVAL; - goto out9; + unregister_framebuffer(fbinfo); + goto out8; } lcd_dev = lcd_device_register(DRIVER_NAME, &pdev->dev, NULL, &bfin_lcd_ops); @@ -663,8 +666,6 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev) return 0; -out9: - unregister_framebuffer(fbinfo); out8: free_irq(info->irq, info); out7: -- cgit v1.2.3 From b8d6b0d6b6882a53e4586a07e1292223d55299d1 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 26 May 2010 14:42:32 -0700 Subject: drivers/telephony/ixj.c: use memdup_user Use memdup_user when user data is immediately copied into the allocated region. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression from,to,size,flag; position p; identifier l1,l2; @@ - to = \(kmalloc@p\|kzalloc@p\)(size,flag); + to = memdup_user(from,size); if ( - to==NULL + IS_ERR(to) || ...) { <+... when != goto l1; - -ENOMEM + PTR_ERR(to) ...+> } - if (copy_from_user(to, from, size) != 0) { - <+... when != goto l2; - -EFAULT - ...+> - } // Signed-off-by: Julia Lawall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/telephony/ixj.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c index e89304c72568..b53deee25d74 100644 --- a/drivers/telephony/ixj.c +++ b/drivers/telephony/ixj.c @@ -5879,20 +5879,13 @@ out: static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp) { IXJ_FILTER_CADENCE *lcp; - lcp = kmalloc(sizeof(IXJ_FILTER_CADENCE), GFP_KERNEL); - if (lcp == NULL) { + lcp = memdup_user(cp, sizeof(IXJ_FILTER_CADENCE)); + if (IS_ERR(lcp)) { if(ixjdebug & 0x0001) { - printk(KERN_INFO "Could not allocate memory for cadence\n"); + printk(KERN_INFO "Could not allocate memory for cadence or could not copy cadence to kernel\n"); } - return -ENOMEM; + return PTR_ERR(lcp); } - if (copy_from_user(lcp, cp, sizeof(IXJ_FILTER_CADENCE))) { - if(ixjdebug & 0x0001) { - printk(KERN_INFO "Could not copy cadence to kernel\n"); - } - kfree(lcp); - return -EFAULT; - } if (lcp->filter > 5) { if(ixjdebug & 0x0001) { printk(KERN_INFO "Cadence out of range\n"); -- cgit v1.2.3 From ad84bb5b98bf81deae97e3bcd814675d6b4e6f72 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Wed, 26 May 2010 14:43:31 -0700 Subject: topology: convert cpu notifier to return encapsulate errno value By the previous modification, the cpu notifier can return encapsulate errno value. This converts the cpu notifiers for topology. Signed-off-by: Akinobu Mita Cc: Greg Kroah-Hartman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/base/topology.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/topology.c b/drivers/base/topology.c index bf6b13206d00..9fc630ce1ddb 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c @@ -162,7 +162,7 @@ static int __cpuinit topology_cpu_callback(struct notifier_block *nfb, topology_remove_dev(cpu); break; } - return rc ? NOTIFY_BAD : NOTIFY_OK; + return notifier_from_errno(rc); } static int __cpuinit topology_sysfs_init(void) -- cgit v1.2.3 From 1dee31f74fed47565ed62023fc65fcb7d6c5d648 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Wed, 26 May 2010 14:43:34 -0700 Subject: ehca: convert cpu notifier to return encapsulate errno value By the previous modification, the cpu notifier can return encapsulate errno value. This converts the cpu notifiers for ehca. Signed-off-by: Akinobu Mita Cc: Hoang-Nam Nguyen Cc: Christoph Raisch Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/infiniband/hw/ehca/ehca_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index 07cae552cafb..e571e60ecb88 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c @@ -847,7 +847,7 @@ static int __cpuinit comp_pool_callback(struct notifier_block *nfb, ehca_gen_dbg("CPU: %x (CPU_PREPARE)", cpu); if (!create_comp_task(pool, cpu)) { ehca_gen_err("Can't create comp_task for cpu: %x", cpu); - return NOTIFY_BAD; + return notifier_from_errno(-ENOMEM); } break; case CPU_UP_CANCELED: -- cgit v1.2.3 From 55af6bb509d3ef2696faddd4a734bf024794b337 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Wed, 26 May 2010 14:43:35 -0700 Subject: md: convert cpu notifier to return encapsulate errno value By the previous modification, the cpu notifier can return encapsulate errno value. This converts the cpu notifiers for raid5. Signed-off-by: Akinobu Mita Cc: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/raid5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 9ea17d6c799b..d2c0f94fa37d 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -4645,7 +4645,7 @@ static int raid456_cpu_notify(struct notifier_block *nfb, unsigned long action, kfree(percpu->scribble); pr_err("%s: failed memory allocation for cpu%ld\n", __func__, cpu); - return NOTIFY_BAD; + return notifier_from_errno(-ENOMEM); } break; case CPU_DEAD: -- cgit v1.2.3 From 5fedc4a282f0c6f5be5e4bebc8840f6022153bb3 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Wed, 26 May 2010 14:43:45 -0700 Subject: ipmi: change addr_source to an enum rather than strings Switch from a char* to an enum to identify the address source of SIs, making it easier to handle them appropriately during registration. Signed-off-by: Matthew Garrett Signed-off-by: Corey Minyard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 44 +++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 47ffe4a90a95..93ab75887fbf 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -107,6 +107,14 @@ enum si_type { }; static char *si_to_str[] = { "kcs", "smic", "bt" }; +enum ipmi_addr_src { + SI_INVALID = 0, SI_HOTMOD, SI_HARDCODED, SI_SPMI, SI_ACPI, SI_SMBIOS, + SI_PCI, SI_DEVICETREE, SI_DEFAULT +}; +static char *ipmi_addr_src_to_str[] = { NULL, "hotmod", "hardcoded", "SPMI", + "ACPI", "SMBIOS", "PCI", + "device-tree", "default" }; + #define DEVICE_NAME "ipmi_si" static struct platform_driver ipmi_driver = { @@ -188,7 +196,7 @@ struct smi_info { int (*irq_setup)(struct smi_info *info); void (*irq_cleanup)(struct smi_info *info); unsigned int io_size; - char *addr_source; /* ACPI, PCI, SMBIOS, hardcode, default. */ + enum ipmi_addr_src addr_source; /* ACPI, PCI, SMBIOS, hardcode, etc. */ void (*addr_source_cleanup)(struct smi_info *info); void *addr_source_data; @@ -1755,7 +1763,7 @@ static int hotmod_handler(const char *val, struct kernel_param *kp) goto out; } - info->addr_source = "hotmod"; + info->addr_source = SI_HOTMOD; info->si_type = si_type; info->io.addr_data = addr; info->io.addr_type = addr_space; @@ -1813,7 +1821,7 @@ static __devinit void hardcode_find_bmc(void) if (!info) return; - info->addr_source = "hardcoded"; + info->addr_source = SI_HARDCODED; if (!si_type[i] || strcmp(si_type[i], "kcs") == 0) { info->si_type = SI_KCS; @@ -2004,7 +2012,7 @@ static __devinit int try_init_spmi(struct SPMITable *spmi) return -ENOMEM; } - info->addr_source = "SPMI"; + info->addr_source = SI_SPMI; /* Figure out the interface type. */ switch (spmi->InterfaceType) { @@ -2105,7 +2113,7 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, if (!info) return -ENOMEM; - info->addr_source = "ACPI"; + info->addr_source = SI_ACPI; handle = acpi_dev->handle; @@ -2269,7 +2277,7 @@ static __devinit void try_init_dmi(struct dmi_ipmi_data *ipmi_data) return; } - info->addr_source = "SMBIOS"; + info->addr_source = SI_SMBIOS; switch (ipmi_data->type) { case 0x01: /* KCS */ @@ -2368,7 +2376,7 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, if (!info) return -ENOMEM; - info->addr_source = "PCI"; + info->addr_source = SI_PCI; switch (class_type) { case PCI_ERMC_CLASSCODE_TYPE_SMIC: @@ -2508,7 +2516,7 @@ static int __devinit ipmi_of_probe(struct of_device *dev, } info->si_type = (enum si_type) match->data; - info->addr_source = "device-tree"; + info->addr_source = SI_DEVICETREE; info->irq_setup = std_irq_setup; if (resource.flags & IORESOURCE_IO) { @@ -2951,7 +2959,7 @@ static __devinit void default_find_bmc(void) if (!info) return; - info->addr_source = NULL; + info->addr_source = SI_DEFAULT; info->si_type = ipmi_defaults[i].type; info->io_setup = port_setup; @@ -2994,16 +3002,14 @@ static int try_smi_init(struct smi_info *new_smi) int rv; int i; - if (new_smi->addr_source) { - printk(KERN_INFO "ipmi_si: Trying %s-specified %s state" - " machine at %s address 0x%lx, slave address 0x%x," - " irq %d\n", - new_smi->addr_source, - si_to_str[new_smi->si_type], - addr_space_to_str[new_smi->io.addr_type], - new_smi->io.addr_data, - new_smi->slave_addr, new_smi->irq); - } + printk(KERN_INFO "ipmi_si: Trying %s-specified %s state" + " machine at %s address 0x%lx, slave address 0x%x," + " irq %d\n", + ipmi_addr_src_to_str[new_smi->addr_source], + si_to_str[new_smi->si_type], + addr_space_to_str[new_smi->io.addr_type], + new_smi->io.addr_data, + new_smi->slave_addr, new_smi->irq); mutex_lock(&smi_infos_lock); if (!is_new_interface(new_smi)) { -- cgit v1.2.3 From 2407d77a1a013b88ee3b817f2b934e420e5376f5 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Wed, 26 May 2010 14:43:46 -0700 Subject: ipmi: split device discovery and registration The ipmi spec indicates that we should only make use of one si per bmc, so separate device discovery and registration to make that possible. [thenzl@redhat.com: fix mutex use] Signed-off-by: Matthew Garrett Signed-off-by: Corey Minyard Signed-off-by: Tomas Henzl Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 130 +++++++++++++++++++++++++-------------- 1 file changed, 84 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 93ab75887fbf..3f2a4900fe18 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -308,6 +308,7 @@ static int num_max_busy_us; static int unload_when_empty = 1; +static int add_smi(struct smi_info *smi); static int try_smi_init(struct smi_info *smi); static void cleanup_one_si(struct smi_info *to_clean); @@ -1785,7 +1786,9 @@ static int hotmod_handler(const char *val, struct kernel_param *kp) info->irq_setup = std_irq_setup; info->slave_addr = ipmb; - try_smi_init(info); + if (!add_smi(info)) + if (try_smi_init(info)) + cleanup_one_si(info); } else { /* remove */ struct smi_info *e, *tmp_e; @@ -1871,7 +1874,9 @@ static __devinit void hardcode_find_bmc(void) info->irq_setup = std_irq_setup; info->slave_addr = slave_addrs[i]; - try_smi_init(info); + if (!add_smi(info)) + if (try_smi_init(info)) + cleanup_one_si(info); } } @@ -2069,7 +2074,7 @@ static __devinit int try_init_spmi(struct SPMITable *spmi) } info->io.addr_data = spmi->addr.address; - try_smi_init(info); + add_smi(info); return 0; } @@ -2167,7 +2172,7 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, info->dev = &acpi_dev->dev; pnp_set_drvdata(dev, info); - return try_smi_init(info); + return add_smi(info); err_free: kfree(info); @@ -2326,7 +2331,7 @@ static __devinit void try_init_dmi(struct dmi_ipmi_data *ipmi_data) if (info->irq) info->irq_setup = std_irq_setup; - try_smi_init(info); + add_smi(info); } static void __devinit dmi_find_bmc(void) @@ -2429,7 +2434,7 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, info->dev = &pdev->dev; pci_set_drvdata(pdev, info); - return try_smi_init(info); + return add_smi(info); } static void __devexit ipmi_pci_remove(struct pci_dev *pdev) @@ -2542,7 +2547,7 @@ static int __devinit ipmi_of_probe(struct of_device *dev, dev_set_drvdata(&dev->dev, info); - return try_smi_init(info); + return add_smi(info); } static int __devexit ipmi_of_remove(struct of_device *dev) @@ -2971,14 +2976,16 @@ static __devinit void default_find_bmc(void) info->io.regsize = DEFAULT_REGSPACING; info->io.regshift = 0; - if (try_smi_init(info) == 0) { - /* Found one... */ - printk(KERN_INFO "ipmi_si: Found default %s state" - " machine at %s address 0x%lx\n", - si_to_str[info->si_type], - addr_space_to_str[info->io.addr_type], - info->io.addr_data); - return; + if (add_smi(info) == 0) { + if ((try_smi_init(info)) == 0) { + /* Found one... */ + printk(KERN_INFO "ipmi_si: Found default %s" + " state machine at %s address 0x%lx\n", + si_to_str[info->si_type], + addr_space_to_str[info->io.addr_type], + info->io.addr_data); + } else + cleanup_one_si(info); } } } @@ -2997,32 +3004,48 @@ static int is_new_interface(struct smi_info *info) return 1; } -static int try_smi_init(struct smi_info *new_smi) +static int add_smi(struct smi_info *new_smi) { - int rv; - int i; - - printk(KERN_INFO "ipmi_si: Trying %s-specified %s state" - " machine at %s address 0x%lx, slave address 0x%x," - " irq %d\n", - ipmi_addr_src_to_str[new_smi->addr_source], - si_to_str[new_smi->si_type], - addr_space_to_str[new_smi->io.addr_type], - new_smi->io.addr_data, - new_smi->slave_addr, new_smi->irq); + int rv = 0; + printk(KERN_INFO "ipmi_si: Adding %s-specified %s state machine", + ipmi_addr_src_to_str[new_smi->addr_source], + si_to_str[new_smi->si_type]); mutex_lock(&smi_infos_lock); if (!is_new_interface(new_smi)) { - printk(KERN_WARNING "ipmi_si: duplicate interface\n"); + printk(KERN_CONT ": duplicate interface\n"); rv = -EBUSY; goto out_err; } + printk(KERN_CONT "\n"); + /* So we know not to free it unless we have allocated one. */ new_smi->intf = NULL; new_smi->si_sm = NULL; new_smi->handlers = NULL; + list_add_tail(&new_smi->link, &smi_infos); + +out_err: + mutex_unlock(&smi_infos_lock); + return rv; +} + +static int try_smi_init(struct smi_info *new_smi) +{ + int rv = 0; + int i; + + printk(KERN_INFO "ipmi_si: Trying %s-specified %s state" + " machine at %s address 0x%lx, slave address 0x%x," + " irq %d\n", + ipmi_addr_src_to_str[new_smi->addr_source], + si_to_str[new_smi->si_type], + addr_space_to_str[new_smi->io.addr_type], + new_smi->io.addr_data, + new_smi->slave_addr, new_smi->irq); + switch (new_smi->si_type) { case SI_KCS: new_smi->handlers = &kcs_smi_handlers; @@ -3183,10 +3206,6 @@ static int try_smi_init(struct smi_info *new_smi) goto out_err_stop_timer; } - list_add_tail(&new_smi->link, &smi_infos); - - mutex_unlock(&smi_infos_lock); - printk(KERN_INFO "IPMI %s interface initialized\n", si_to_str[new_smi->si_type]); @@ -3197,11 +3216,17 @@ static int try_smi_init(struct smi_info *new_smi) wait_for_timer_and_thread(new_smi); out_err: - if (new_smi->intf) + new_smi->interrupt_disabled = 1; + + if (new_smi->intf) { ipmi_unregister_smi(new_smi->intf); + new_smi->intf = NULL; + } - if (new_smi->irq_cleanup) + if (new_smi->irq_cleanup) { new_smi->irq_cleanup(new_smi); + new_smi->irq_cleanup = NULL; + } /* * Wait until we know that we are out of any interrupt @@ -3214,18 +3239,21 @@ static int try_smi_init(struct smi_info *new_smi) if (new_smi->handlers) new_smi->handlers->cleanup(new_smi->si_sm); kfree(new_smi->si_sm); + new_smi->si_sm = NULL; } - if (new_smi->addr_source_cleanup) + if (new_smi->addr_source_cleanup) { new_smi->addr_source_cleanup(new_smi); - if (new_smi->io_cleanup) + new_smi->addr_source_cleanup = NULL; + } + if (new_smi->io_cleanup) { new_smi->io_cleanup(new_smi); + new_smi->io_cleanup = NULL; + } - if (new_smi->dev_registered) + if (new_smi->dev_registered) { platform_device_unregister(new_smi->pdev); - - kfree(new_smi); - - mutex_unlock(&smi_infos_lock); + new_smi->dev_registered = 0; + } return rv; } @@ -3235,6 +3263,7 @@ static __devinit int init_ipmi_si(void) int i; char *str; int rv; + struct smi_info *e; if (initialized) return 0; @@ -3292,15 +3321,21 @@ static __devinit int init_ipmi_si(void) of_register_platform_driver(&ipmi_of_platform_driver); #endif + mutex_lock(&smi_infos_lock); + list_for_each_entry(e, &smi_infos, link) { + if (!e->si_sm) + try_smi_init(e); + } + mutex_unlock(&smi_infos_lock); + if (si_trydefaults) { mutex_lock(&smi_infos_lock); if (list_empty(&smi_infos)) { /* No BMC was found, try defaults. */ mutex_unlock(&smi_infos_lock); default_find_bmc(); - } else { + } else mutex_unlock(&smi_infos_lock); - } } mutex_lock(&smi_infos_lock); @@ -3326,7 +3361,7 @@ module_init(init_ipmi_si); static void cleanup_one_si(struct smi_info *to_clean) { - int rv; + int rv = 0; unsigned long flags; if (!to_clean) @@ -3370,14 +3405,17 @@ static void cleanup_one_si(struct smi_info *to_clean) schedule_timeout_uninterruptible(1); } - rv = ipmi_unregister_smi(to_clean->intf); + if (to_clean->intf) + rv = ipmi_unregister_smi(to_clean->intf); + if (rv) { printk(KERN_ERR "ipmi_si: Unable to unregister device: errno=%d\n", rv); } - to_clean->handlers->cleanup(to_clean->si_sm); + if (to_clean->handlers) + to_clean->handlers->cleanup(to_clean->si_sm); kfree(to_clean->si_sm); -- cgit v1.2.3 From d8cc5267b802003e2c67ac5254788044852ccfa9 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Wed, 26 May 2010 14:43:46 -0700 Subject: ipmi: only register one si per bmc Only register one si per bmc. Use any user-provided devices first, followed by the first device with an irq, followed by the first device discovered. Signed-off-by: Matthew Garrett Signed-off-by: Corey Minyard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 3f2a4900fe18..9b9e1e915cf6 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -3298,6 +3298,14 @@ static __devinit int init_ipmi_si(void) hardcode_find_bmc(); + /* If the user gave us a device, they presumably want us to use it */ + mutex_lock(&smi_infos_lock); + if (!list_empty(&smi_infos)) { + mutex_unlock(&smi_infos_lock); + return 0; + } + mutex_unlock(&smi_infos_lock); + #ifdef CONFIG_DMI dmi_find_bmc(); #endif @@ -3321,10 +3329,27 @@ static __devinit int init_ipmi_si(void) of_register_platform_driver(&ipmi_of_platform_driver); #endif + /* Try to register something with interrupts first */ + mutex_lock(&smi_infos_lock); list_for_each_entry(e, &smi_infos, link) { - if (!e->si_sm) - try_smi_init(e); + if (e->irq) { + if (!try_smi_init(e)) { + mutex_unlock(&smi_infos_lock); + return 0; + } + } + } + + /* Fall back to the preferred device */ + + list_for_each_entry(e, &smi_infos, link) { + if (!e->irq) { + if (!try_smi_init(e)) { + mutex_unlock(&smi_infos_lock); + return 0; + } + } } mutex_unlock(&smi_infos_lock); -- cgit v1.2.3 From 754d453185275951d39792865927ec494fa1ebd8 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Wed, 26 May 2010 14:43:47 -0700 Subject: ipmi: change device discovery order The ipmi spec provides an ordering for si discovery. Change the driver to match, with the exception of preferring smbios to SPMI as HPs (at least) contain accurate information in the former but not the latter. Signed-off-by: Matthew Garrett Signed-off-by: Corey Minyard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 9b9e1e915cf6..5b7bf7d22494 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -3306,17 +3306,6 @@ static __devinit int init_ipmi_si(void) } mutex_unlock(&smi_infos_lock); -#ifdef CONFIG_DMI - dmi_find_bmc(); -#endif - -#ifdef CONFIG_ACPI - spmi_find_bmc(); -#endif -#ifdef CONFIG_ACPI - pnp_register_driver(&ipmi_pnp_driver); -#endif - #ifdef CONFIG_PCI rv = pci_register_driver(&ipmi_pci_driver); if (rv) @@ -3325,6 +3314,18 @@ static __devinit int init_ipmi_si(void) rv); #endif +#ifdef CONFIG_ACPI + pnp_register_driver(&ipmi_pnp_driver); +#endif + +#ifdef CONFIG_DMI + dmi_find_bmc(); +#endif + +#ifdef CONFIG_ACPI + spmi_find_bmc(); +#endif + #ifdef CONFIG_PPC_OF of_register_platform_driver(&ipmi_of_platform_driver); #endif -- cgit v1.2.3 From ea4078ca1a7a3a198e519c2a7a2ed6126e40b130 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Wed, 26 May 2010 14:43:48 -0700 Subject: ipmi: reduce polling when interrupts are available If we're not currently in the middle of a transaction, and if we have interrupts, there's no real reason to poll the controller more frequently than the core IPMI code does. Set the interrupt_disabled flag appropriately as the interrupt state changes, and make the timeout code reset itself only if the transaction is incomplete or we have no interrupts. Signed-off-by: Matthew Garrett Signed-off-by: Corey Minyard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 5b7bf7d22494..c8d68cf68598 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -454,6 +454,9 @@ static inline void disable_si_irq(struct smi_info *smi_info) if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { start_disable_irq(smi_info); smi_info->interrupt_disabled = 1; + if (!atomic_read(&smi_info->stop_operation)) + mod_timer(&smi_info->si_timer, + jiffies + SI_TIMEOUT_JIFFIES); } } @@ -706,6 +709,8 @@ static void handle_transaction_done(struct smi_info *smi_info) printk(KERN_WARNING "ipmi_si: Could not enable interrupts" ", failed set, using polled mode.\n"); + } else { + smi_info->interrupt_disabled = 0; } smi_info->si_state = SI_NORMAL; break; @@ -886,6 +891,8 @@ static void sender(void *send_info, printk("**Enqueue: %d.%9.9d\n", t.tv_sec, t.tv_usec); #endif + mod_timer(&smi_info->si_timer, jiffies + SI_TIMEOUT_JIFFIES); + if (smi_info->run_to_completion) { /* * If we are running to completion, then throw it in @@ -1086,7 +1093,8 @@ static void smi_timeout(unsigned long data) } do_add_timer: - add_timer(&(smi_info->si_timer)); + if ((smi_result != SI_SM_IDLE) || smi_info->interrupt_disabled) + add_timer(&(smi_info->si_timer)); } static irqreturn_t si_irq_handler(int irq, void *data) @@ -3117,7 +3125,7 @@ static int try_smi_init(struct smi_info *new_smi) for (i = 0; i < SI_NUM_STATS; i++) atomic_set(&new_smi->stats[i], 0); - new_smi->interrupt_disabled = 0; + new_smi->interrupt_disabled = 1; atomic_set(&new_smi->stop_operation, 0); new_smi->intf_num = smi_num; smi_num++; -- cgit v1.2.3 From 3326f4f2276791561af1fd5f2020be0186459813 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Wed, 26 May 2010 14:43:49 -0700 Subject: ipmi: reduce polling We can reasonably alter the poll rate depending on whether we're performing a transaction or merely waiting for an event. Signed-off-by: Matthew Garrett Signed-off-by: Corey Minyard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index c8d68cf68598..46bf2a97d6cb 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -893,6 +893,9 @@ static void sender(void *send_info, mod_timer(&smi_info->si_timer, jiffies + SI_TIMEOUT_JIFFIES); + if (smi_info->thread) + wake_up_process(smi_info->thread); + if (smi_info->run_to_completion) { /* * If we are running to completion, then throw it in @@ -1013,6 +1016,8 @@ static int ipmi_thread(void *data) ; /* do nothing */ else if (smi_result == SI_SM_CALL_WITH_DELAY && busy_wait) schedule(); + else if (smi_result == SI_SM_IDLE) + schedule_timeout_interruptible(100); else schedule_timeout_interruptible(0); } @@ -1055,6 +1060,7 @@ static void smi_timeout(unsigned long data) unsigned long flags; unsigned long jiffies_now; long time_diff; + long timeout; #ifdef DEBUG_TIMING struct timeval t; #endif @@ -1075,9 +1081,9 @@ static void smi_timeout(unsigned long data) if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { /* Running with interrupts, only do long timeouts. */ - smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; + timeout = jiffies + SI_TIMEOUT_JIFFIES; smi_inc_stat(smi_info, long_timeouts); - goto do_add_timer; + goto do_mod_timer; } /* @@ -1086,15 +1092,15 @@ static void smi_timeout(unsigned long data) */ if (smi_result == SI_SM_CALL_WITH_DELAY) { smi_inc_stat(smi_info, short_timeouts); - smi_info->si_timer.expires = jiffies + 1; + timeout = jiffies + 1; } else { smi_inc_stat(smi_info, long_timeouts); - smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; + timeout = jiffies + SI_TIMEOUT_JIFFIES; } - do_add_timer: - if ((smi_result != SI_SM_IDLE) || smi_info->interrupt_disabled) - add_timer(&(smi_info->si_timer)); + do_mod_timer: + if (smi_result != SI_SM_IDLE) + mod_timer(&(smi_info->si_timer), timeout); } static irqreturn_t si_irq_handler(int irq, void *data) -- cgit v1.2.3 From 06ee459402434aabed0c6d03c4cc10bfe4a3a65b Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Wed, 26 May 2010 14:43:49 -0700 Subject: ipmi: attempt to register multiple SIs of the same type Some odd systems may have multiple BMCs, and we want to be able to support them. Let's make the assumption that if a system legitimately has multiple BMCs then each BMC's SI will be of the same type, and also that we won't see multiple SIs of the same type unless we have multiple BMCs. If these hold true then we should register all SIs of the same type. Signed-off-by: Matthew Garrett Signed-off-by: Corey Minyard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 46bf2a97d6cb..6503d995b727 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -3278,6 +3278,7 @@ static __devinit int init_ipmi_si(void) char *str; int rv; struct smi_info *e; + enum ipmi_addr_src type = SI_INVALID; if (initialized) return 0; @@ -3344,30 +3345,43 @@ static __devinit int init_ipmi_si(void) of_register_platform_driver(&ipmi_of_platform_driver); #endif - /* Try to register something with interrupts first */ + /* We prefer devices with interrupts, but in the case of a machine + with multiple BMCs we assume that there will be several instances + of a given type so if we succeed in registering a type then also + try to register everything else of the same type */ mutex_lock(&smi_infos_lock); list_for_each_entry(e, &smi_infos, link) { - if (e->irq) { + /* Try to register a device if it has an IRQ and we either + haven't successfully registered a device yet or this + device has the same type as one we successfully registered */ + if (e->irq && (!type || e->addr_source == type)) { if (!try_smi_init(e)) { - mutex_unlock(&smi_infos_lock); - return 0; + type = e->addr_source; } } } + /* type will only have been set if we successfully registered an si */ + if (type) { + mutex_unlock(&smi_infos_lock); + return 0; + } + /* Fall back to the preferred device */ list_for_each_entry(e, &smi_infos, link) { - if (!e->irq) { + if (!e->irq && (!type || e->addr_source == type)) { if (!try_smi_init(e)) { - mutex_unlock(&smi_infos_lock); - return 0; + type = e->addr_source; } } } mutex_unlock(&smi_infos_lock); + if (type) + return 0; + if (si_trydefaults) { mutex_lock(&smi_infos_lock); if (list_empty(&smi_infos)) { -- cgit v1.2.3 From ddac44b7b21b72c0d9d6882ac8d7027afc25138c Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Wed, 26 May 2010 14:43:50 -0700 Subject: ipmi: change timeout and event poll to one second The timeouts in IPMI are in the 1-5 second range in message handling, so a 1 second timeout is a reasonable thing to do. This should help with reducing power consumption on idle systems. Signed-off-by: Corey Minyard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_msghandler.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index c6ad4234378d..5de4bb99cb97 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -4037,8 +4037,8 @@ static void ipmi_request_event(void) static struct timer_list ipmi_timer; -/* Call every ~100 ms. */ -#define IPMI_TIMEOUT_TIME 100 +/* Call every ~1000 ms. */ +#define IPMI_TIMEOUT_TIME 1000 /* How many jiffies does it take to get to the timeout time. */ #define IPMI_TIMEOUT_JIFFIES ((IPMI_TIMEOUT_TIME * HZ) / 1000) -- cgit v1.2.3 From 8c8eae2742d5ad05ef6e5b53c88e70a5231d7d9a Mon Sep 17 00:00:00 2001 From: Myron Stowe Date: Wed, 26 May 2010 14:43:51 -0700 Subject: ipmi: convert tracking of the ACPI device pointer to a PNP device Convert PNP patch (git 9e368fa011d4e0aa050db348d69514900520e40b) to maintain a pointer to a PNP device, 'pnp_dev', instead of the ACPI device, 'acpi_dev', that is currently being tracked with PNP based IPMI device discovery. Signed-off-by: Myron Stowe Acked-by: Zhao Yakui Acked-by: Corey Minyard Cc: Len Brown Cc: Bjorn Helgaas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 6503d995b727..31bbcbdd178a 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2183,7 +2183,7 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, info->irq_setup = std_irq_setup; } - info->dev = &acpi_dev->dev; + info->dev = &dev->dev; pnp_set_drvdata(dev, info); return add_smi(info); -- cgit v1.2.3 From 279fbd0c5daa60c76e59df33f436ca2300f2b603 Mon Sep 17 00:00:00 2001 From: Myron Stowe Date: Wed, 26 May 2010 14:43:52 -0700 Subject: ipmi: update driver to use dev_printk and its constructs Update core IPMI driver printk()'s with dev_printk(), and its constructs, to provide additional device topology information. An example of the additional device topology for a PNP device - ipmi_si 00:02: probing via ACPI ipmi_si 00:02: [io 0x0ca2-0x0ca3] regsize 1 spacing 1 irq 0 ipmi_si 00:02: Found new BMC (man_id: 0x00000b, prod_id: 0x0000, ... ipmi_si 00:02: IPMI kcs interface initialized and for a PCI device - ipmi_si 0000:01:04.6: probing via PCI ipmi_si 0000:01:04.6: PCI INT A -> GSI 21 (level, low) -> IRQ 21 ipmi_si 0000:01:04.6: [mem 0xf1ef0000-0xf1ef00ff] regsize 1 spaci... ipmi_si 0000:01:04.6: IPMI kcs interface initialized [minyard@acm.org: rework to fix rejects, extended it a bit] [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Myron Stowe Signed-off-by: Corey Minyard Cc: Zhao Yakui Cc: Len Brown Cc: Bjorn Helgaas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_msghandler.c | 11 +- drivers/char/ipmi/ipmi_si_intf.c | 223 +++++++++++++++++------------------- 2 files changed, 107 insertions(+), 127 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 5de4bb99cb97..4f3f8c9ec262 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -2505,12 +2505,11 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum, return rv; } - printk(KERN_INFO - "ipmi: Found new BMC (man_id: 0x%6.6x, " - " prod_id: 0x%4.4x, dev_id: 0x%2.2x)\n", - bmc->id.manufacturer_id, - bmc->id.product_id, - bmc->id.device_id); + dev_info(intf->si_dev, "Found new BMC (man_id: 0x%6.6x, " + "prod_id: 0x%4.4x, dev_id: 0x%2.2x)\n", + bmc->id.manufacturer_id, + bmc->id.product_id, + bmc->id.device_id); } /* diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 31bbcbdd178a..f052c481327a 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -588,9 +588,8 @@ static void handle_transaction_done(struct smi_info *smi_info) smi_info->handlers->get_result(smi_info->si_sm, msg, 3); if (msg[2] != 0) { /* Error clearing flags */ - printk(KERN_WARNING - "ipmi_si: Error clearing flags: %2.2x\n", - msg[2]); + dev_warn(smi_info->dev, + "Error clearing flags: %2.2x\n", msg[2]); } if (smi_info->si_state == SI_CLEARING_FLAGS_THEN_SET_IRQ) start_enable_irq(smi_info); @@ -682,9 +681,8 @@ static void handle_transaction_done(struct smi_info *smi_info) /* We got the flags from the SMI, now handle them. */ smi_info->handlers->get_result(smi_info->si_sm, msg, 4); if (msg[2] != 0) { - printk(KERN_WARNING - "ipmi_si: Could not enable interrupts" - ", failed get, using polled mode.\n"); + dev_warn(smi_info->dev, "Could not enable interrupts" + ", failed get, using polled mode.\n"); smi_info->si_state = SI_NORMAL; } else { msg[0] = (IPMI_NETFN_APP_REQUEST << 2); @@ -705,13 +703,11 @@ static void handle_transaction_done(struct smi_info *smi_info) /* We got the flags from the SMI, now handle them. */ smi_info->handlers->get_result(smi_info->si_sm, msg, 4); - if (msg[2] != 0) { - printk(KERN_WARNING - "ipmi_si: Could not enable interrupts" - ", failed set, using polled mode.\n"); - } else { + if (msg[2] != 0) + dev_warn(smi_info->dev, "Could not enable interrupts" + ", failed set, using polled mode.\n"); + else smi_info->interrupt_disabled = 0; - } smi_info->si_state = SI_NORMAL; break; } @@ -723,9 +719,8 @@ static void handle_transaction_done(struct smi_info *smi_info) /* We got the flags from the SMI, now handle them. */ smi_info->handlers->get_result(smi_info->si_sm, msg, 4); if (msg[2] != 0) { - printk(KERN_WARNING - "ipmi_si: Could not disable interrupts" - ", failed get.\n"); + dev_warn(smi_info->dev, "Could not disable interrupts" + ", failed get.\n"); smi_info->si_state = SI_NORMAL; } else { msg[0] = (IPMI_NETFN_APP_REQUEST << 2); @@ -747,9 +742,8 @@ static void handle_transaction_done(struct smi_info *smi_info) /* We got the flags from the SMI, now handle them. */ smi_info->handlers->get_result(smi_info->si_sm, msg, 4); if (msg[2] != 0) { - printk(KERN_WARNING - "ipmi_si: Could not disable interrupts" - ", failed set.\n"); + dev_warn(smi_info->dev, "Could not disable interrupts" + ", failed set.\n"); } smi_info->si_state = SI_NORMAL; break; @@ -1167,10 +1161,10 @@ static int smi_start_processing(void *send_info, new_smi->thread = kthread_run(ipmi_thread, new_smi, "kipmi%d", new_smi->intf_num); if (IS_ERR(new_smi->thread)) { - printk(KERN_NOTICE "ipmi_si_intf: Could not start" - " kernel thread due to error %ld, only using" - " timers to drive the interface\n", - PTR_ERR(new_smi->thread)); + dev_notice(new_smi->dev, "Could not start" + " kernel thread due to error %ld, only using" + " timers to drive the interface\n", + PTR_ERR(new_smi->thread)); new_smi->thread = NULL; } } @@ -1331,14 +1325,13 @@ static int std_irq_setup(struct smi_info *info) DEVICE_NAME, info); if (rv) { - printk(KERN_WARNING - "ipmi_si: %s unable to claim interrupt %d," - " running polled\n", - DEVICE_NAME, info->irq); + dev_warn(info->dev, "%s unable to claim interrupt %d," + " running polled\n", + DEVICE_NAME, info->irq); info->irq = 0; } else { info->irq_cleanup = std_irq_cleanup; - printk(" Using irq %d\n", info->irq); + dev_info(info->dev, "Using irq %d\n", info->irq); } return rv; @@ -1429,8 +1422,8 @@ static int port_setup(struct smi_info *info) info->io.outputb = port_outl; break; default: - printk(KERN_WARNING "ipmi_si: Invalid register size: %d\n", - info->io.regsize); + dev_warn(info->dev, "Invalid register size: %d\n", + info->io.regsize); return -EINVAL; } @@ -1552,8 +1545,8 @@ static int mem_setup(struct smi_info *info) break; #endif default: - printk(KERN_WARNING "ipmi_si: Invalid register size: %d\n", - info->io.regsize); + dev_warn(info->dev, "Invalid register size: %d\n", + info->io.regsize); return -EINVAL; } @@ -1839,6 +1832,7 @@ static __devinit void hardcode_find_bmc(void) return; info->addr_source = SI_HARDCODED; + printk(KERN_INFO PFX "probing via hardcoded address\n"); if (!si_type[i] || strcmp(si_type[i], "kcs") == 0) { info->si_type = SI_KCS; @@ -1847,8 +1841,7 @@ static __devinit void hardcode_find_bmc(void) } else if (strcmp(si_type[i], "bt") == 0) { info->si_type = SI_BT; } else { - printk(KERN_WARNING - "ipmi_si: Interface type specified " + printk(KERN_WARNING PFX "Interface type specified " "for interface %d, was invalid: %s\n", i, si_type[i]); kfree(info); @@ -1866,11 +1859,9 @@ static __devinit void hardcode_find_bmc(void) info->io.addr_data = addrs[i]; info->io.addr_type = IPMI_MEM_ADDR_SPACE; } else { - printk(KERN_WARNING - "ipmi_si: Interface type specified " - "for interface %d, " - "but port and address were not set or " - "set to zero.\n", i); + printk(KERN_WARNING PFX "Interface type specified " + "for interface %d, but port and address were " + "not set or set to zero.\n", i); kfree(info); continue; } @@ -1950,15 +1941,13 @@ static int acpi_gpe_irq_setup(struct smi_info *info) &ipmi_acpi_gpe, info); if (status != AE_OK) { - printk(KERN_WARNING - "ipmi_si: %s unable to claim ACPI GPE %d," - " running polled\n", - DEVICE_NAME, info->irq); + dev_warn(info->dev, "%s unable to claim ACPI GPE %d," + " running polled\n", DEVICE_NAME, info->irq); info->irq = 0; return -EINVAL; } else { info->irq_cleanup = acpi_gpe_irq_cleanup; - printk(" Using ACPI GPE %d\n", info->irq); + dev_info(info->dev, "Using ACPI GPE %d\n", info->irq); return 0; } } @@ -2016,8 +2005,8 @@ static __devinit int try_init_spmi(struct SPMITable *spmi) u8 addr_space; if (spmi->IPMIlegacy != 1) { - printk(KERN_INFO "IPMI: Bad SPMI legacy %d\n", spmi->IPMIlegacy); - return -ENODEV; + printk(KERN_INFO PFX "Bad SPMI legacy %d\n", spmi->IPMIlegacy); + return -ENODEV; } if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) @@ -2027,11 +2016,12 @@ static __devinit int try_init_spmi(struct SPMITable *spmi) info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { - printk(KERN_ERR "ipmi_si: Could not allocate SI data (3)\n"); + printk(KERN_ERR PFX "Could not allocate SI data (3)\n"); return -ENOMEM; } info->addr_source = SI_SPMI; + printk(KERN_INFO PFX "probing via SPMI\n"); /* Figure out the interface type. */ switch (spmi->InterfaceType) { @@ -2045,8 +2035,8 @@ static __devinit int try_init_spmi(struct SPMITable *spmi) info->si_type = SI_BT; break; default: - printk(KERN_INFO "ipmi_si: Unknown ACPI/SPMI SI type %d\n", - spmi->InterfaceType); + printk(KERN_INFO PFX "Unknown ACPI/SPMI SI type %d\n", + spmi->InterfaceType); kfree(info); return -EIO; } @@ -2082,8 +2072,7 @@ static __devinit int try_init_spmi(struct SPMITable *spmi) info->io.addr_type = IPMI_IO_ADDR_SPACE; } else { kfree(info); - printk(KERN_WARNING - "ipmi_si: Unknown ACPI I/O Address type\n"); + printk(KERN_WARNING PFX "Unknown ACPI I/O Address type\n"); return -EIO; } info->io.addr_data = spmi->addr.address; @@ -2120,6 +2109,7 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, { struct acpi_device *acpi_dev; struct smi_info *info; + struct resource *res; acpi_handle handle; acpi_status status; unsigned long long tmp; @@ -2133,6 +2123,7 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, return -ENOMEM; info->addr_source = SI_ACPI; + printk(KERN_INFO PFX "probing via ACPI\n"); handle = acpi_dev->handle; @@ -2152,22 +2143,26 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, info->si_type = SI_BT; break; default: - dev_info(&dev->dev, "unknown interface type %lld\n", tmp); + dev_info(&dev->dev, "unknown IPMI type %lld\n", tmp); goto err_free; } - if (pnp_port_valid(dev, 0)) { + res = pnp_get_resource(dev, IORESOURCE_IO, 0); + if (res) { info->io_setup = port_setup; info->io.addr_type = IPMI_IO_ADDR_SPACE; - info->io.addr_data = pnp_port_start(dev, 0); - } else if (pnp_mem_valid(dev, 0)) { - info->io_setup = mem_setup; - info->io.addr_type = IPMI_MEM_ADDR_SPACE; - info->io.addr_data = pnp_mem_start(dev, 0); } else { + res = pnp_get_resource(dev, IORESOURCE_MEM, 0); + if (res) { + info->io_setup = mem_setup; + info->io.addr_type = IPMI_MEM_ADDR_SPACE; + } + } + if (!res) { dev_err(&dev->dev, "no I/O or memory address\n"); goto err_free; } + info->io.addr_data = res->start; info->io.regspacing = DEFAULT_REGSPACING; info->io.regsize = DEFAULT_REGSPACING; @@ -2186,6 +2181,10 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, info->dev = &dev->dev; pnp_set_drvdata(dev, info); + dev_info(info->dev, "%pR regsize %d spacing %d irq %d\n", + res, info->io.regsize, info->io.regspacing, + info->irq); + return add_smi(info); err_free: @@ -2291,12 +2290,12 @@ static __devinit void try_init_dmi(struct dmi_ipmi_data *ipmi_data) info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) { - printk(KERN_ERR - "ipmi_si: Could not allocate SI data\n"); + printk(KERN_ERR PFX "Could not allocate SI data\n"); return; } info->addr_source = SI_SMBIOS; + printk(KERN_INFO PFX "probing via SMBIOS\n"); switch (ipmi_data->type) { case 0x01: /* KCS */ @@ -2326,8 +2325,7 @@ static __devinit void try_init_dmi(struct dmi_ipmi_data *ipmi_data) default: kfree(info); - printk(KERN_WARNING - "ipmi_si: Unknown SMBIOS I/O Address type: %d.\n", + printk(KERN_WARNING PFX "Unknown SMBIOS I/O Address type: %d\n", ipmi_data->addr_space); return; } @@ -2396,6 +2394,7 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, return -ENOMEM; info->addr_source = SI_PCI; + dev_info(&pdev->dev, "probing via PCI"); switch (class_type) { case PCI_ERMC_CLASSCODE_TYPE_SMIC: @@ -2412,15 +2411,13 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, default: kfree(info); - printk(KERN_INFO "ipmi_si: %s: Unknown IPMI type: %d\n", - pci_name(pdev), class_type); + dev_info(&pdev->dev, "Unknown IPMI type: %d\n", class_type); return -ENOMEM; } rv = pci_enable_device(pdev); if (rv) { - printk(KERN_ERR "ipmi_si: %s: couldn't enable PCI device\n", - pci_name(pdev)); + dev_err(&pdev->dev, "couldn't enable PCI device\n"); kfree(info); return rv; } @@ -2448,6 +2445,10 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, info->dev = &pdev->dev; pci_set_drvdata(pdev, info); + dev_info(&pdev->dev, "%pR regsize %d spacing %d irq %d\n", + &pdev->resource[0], info->io.regsize, info->io.regspacing, + info->irq); + return add_smi(info); } @@ -2500,7 +2501,7 @@ static int __devinit ipmi_of_probe(struct of_device *dev, int ret; int proplen; - dev_info(&dev->dev, PFX "probing via device tree\n"); + dev_info(&dev->dev, "probing via device tree\n"); ret = of_address_to_resource(np, 0, &resource); if (ret) { @@ -2530,7 +2531,7 @@ static int __devinit ipmi_of_probe(struct of_device *dev, if (!info) { dev_err(&dev->dev, - PFX "could not allocate memory for OF probe\n"); + "could not allocate memory for OF probe\n"); return -ENOMEM; } @@ -2555,7 +2556,7 @@ static int __devinit ipmi_of_probe(struct of_device *dev, info->irq = irq_of_parse_and_map(dev->dev.of_node, 0); info->dev = &dev->dev; - dev_dbg(&dev->dev, "addr 0x%lx regsize %d spacing %d irq %x\n", + dev_dbg(&dev->dev, "addr 0x%lx regsize %d spacing %d irq %d\n", info->io.addr_data, info->io.regsize, info->io.regspacing, info->irq); @@ -2670,9 +2671,8 @@ static int try_enable_event_buffer(struct smi_info *smi_info) rv = wait_for_msg_done(smi_info); if (rv) { - printk(KERN_WARNING - "ipmi_si: Error getting response from get global," - " enables command, the event buffer is not" + printk(KERN_WARNING PFX "Error getting response from get" + " global enables command, the event buffer is not" " enabled.\n"); goto out; } @@ -2684,10 +2684,8 @@ static int try_enable_event_buffer(struct smi_info *smi_info) resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 || resp[1] != IPMI_GET_BMC_GLOBAL_ENABLES_CMD || resp[2] != 0) { - printk(KERN_WARNING - "ipmi_si: Invalid return from get global" - " enables command, cannot enable the event" - " buffer.\n"); + printk(KERN_WARNING PFX "Invalid return from get global" + " enables command, cannot enable the event buffer.\n"); rv = -EINVAL; goto out; } @@ -2703,9 +2701,8 @@ static int try_enable_event_buffer(struct smi_info *smi_info) rv = wait_for_msg_done(smi_info); if (rv) { - printk(KERN_WARNING - "ipmi_si: Error getting response from set global," - " enables command, the event buffer is not" + printk(KERN_WARNING PFX "Error getting response from set" + " global, enables command, the event buffer is not" " enabled.\n"); goto out; } @@ -2716,10 +2713,8 @@ static int try_enable_event_buffer(struct smi_info *smi_info) if (resp_len < 3 || resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 || resp[1] != IPMI_SET_BMC_GLOBAL_ENABLES_CMD) { - printk(KERN_WARNING - "ipmi_si: Invalid return from get global," - "enables command, not enable the event" - " buffer.\n"); + printk(KERN_WARNING PFX "Invalid return from get global," + "enables command, not enable the event buffer.\n"); rv = -EINVAL; goto out; } @@ -2993,7 +2988,7 @@ static __devinit void default_find_bmc(void) if (add_smi(info) == 0) { if ((try_smi_init(info)) == 0) { /* Found one... */ - printk(KERN_INFO "ipmi_si: Found default %s" + printk(KERN_INFO PFX "Found default %s" " state machine at %s address 0x%lx\n", si_to_str[info->si_type], addr_space_to_str[info->io.addr_type], @@ -3022,12 +3017,12 @@ static int add_smi(struct smi_info *new_smi) { int rv = 0; - printk(KERN_INFO "ipmi_si: Adding %s-specified %s state machine", + printk(KERN_INFO PFX "Adding %s-specified %s state machine", ipmi_addr_src_to_str[new_smi->addr_source], si_to_str[new_smi->si_type]); mutex_lock(&smi_infos_lock); if (!is_new_interface(new_smi)) { - printk(KERN_CONT ": duplicate interface\n"); + printk(KERN_CONT PFX "duplicate interface\n"); rv = -EBUSY; goto out_err; } @@ -3051,7 +3046,7 @@ static int try_smi_init(struct smi_info *new_smi) int rv = 0; int i; - printk(KERN_INFO "ipmi_si: Trying %s-specified %s state" + printk(KERN_INFO PFX "Trying %s-specified %s state" " machine at %s address 0x%lx, slave address 0x%x," " irq %d\n", ipmi_addr_src_to_str[new_smi->addr_source], @@ -3082,7 +3077,8 @@ static int try_smi_init(struct smi_info *new_smi) /* Allocate the state machine's data and initialize it. */ new_smi->si_sm = kmalloc(new_smi->handlers->size(), GFP_KERNEL); if (!new_smi->si_sm) { - printk(KERN_ERR "Could not allocate state machine memory\n"); + printk(KERN_ERR PFX + "Could not allocate state machine memory\n"); rv = -ENOMEM; goto out_err; } @@ -3092,7 +3088,7 @@ static int try_smi_init(struct smi_info *new_smi) /* Now that we know the I/O size, we can set up the I/O. */ rv = new_smi->io_setup(new_smi); if (rv) { - printk(KERN_ERR "Could not set up I/O space\n"); + printk(KERN_ERR PFX "Could not set up I/O space\n"); goto out_err; } @@ -3102,8 +3098,7 @@ static int try_smi_init(struct smi_info *new_smi) /* Do low-level detection first. */ if (new_smi->handlers->detect(new_smi->si_sm)) { if (new_smi->addr_source) - printk(KERN_INFO "ipmi_si: Interface detection" - " failed\n"); + printk(KERN_INFO PFX "Interface detection failed\n"); rv = -ENODEV; goto out_err; } @@ -3115,7 +3110,7 @@ static int try_smi_init(struct smi_info *new_smi) rv = try_get_dev_id(new_smi); if (rv) { if (new_smi->addr_source) - printk(KERN_INFO "ipmi_si: There appears to be no BMC" + printk(KERN_INFO PFX "There appears to be no BMC" " at this location\n"); goto out_err; } @@ -3157,9 +3152,8 @@ static int try_smi_init(struct smi_info *new_smi) new_smi->pdev = platform_device_alloc("ipmi_si", new_smi->intf_num); if (!new_smi->pdev) { - printk(KERN_ERR - "ipmi_si_intf:" - " Unable to allocate platform device\n"); + printk(KERN_ERR PFX + "Unable to allocate platform device\n"); goto out_err; } new_smi->dev = &new_smi->pdev->dev; @@ -3167,9 +3161,8 @@ static int try_smi_init(struct smi_info *new_smi) rv = platform_device_add(new_smi->pdev); if (rv) { - printk(KERN_ERR - "ipmi_si_intf:" - " Unable to register system interface device:" + printk(KERN_ERR PFX + "Unable to register system interface device:" " %d\n", rv); goto out_err; @@ -3184,9 +3177,8 @@ static int try_smi_init(struct smi_info *new_smi) "bmc", new_smi->slave_addr); if (rv) { - printk(KERN_ERR - "ipmi_si: Unable to register device: error %d\n", - rv); + dev_err(new_smi->dev, "Unable to register device: error %d\n", + rv); goto out_err_stop_timer; } @@ -3194,9 +3186,7 @@ static int try_smi_init(struct smi_info *new_smi) type_file_read_proc, new_smi); if (rv) { - printk(KERN_ERR - "ipmi_si: Unable to create proc entry: %d\n", - rv); + dev_err(new_smi->dev, "Unable to create proc entry: %d\n", rv); goto out_err_stop_timer; } @@ -3204,9 +3194,7 @@ static int try_smi_init(struct smi_info *new_smi) stat_file_read_proc, new_smi); if (rv) { - printk(KERN_ERR - "ipmi_si: Unable to create proc entry: %d\n", - rv); + dev_err(new_smi->dev, "Unable to create proc entry: %d\n", rv); goto out_err_stop_timer; } @@ -3214,14 +3202,12 @@ static int try_smi_init(struct smi_info *new_smi) param_read_proc, new_smi); if (rv) { - printk(KERN_ERR - "ipmi_si: Unable to create proc entry: %d\n", - rv); + dev_err(new_smi->dev, "Unable to create proc entry: %d\n", rv); goto out_err_stop_timer; } - printk(KERN_INFO "IPMI %s interface initialized\n", - si_to_str[new_smi->si_type]); + dev_info(new_smi->dev, "IPMI %s interface initialized\n", + si_to_str[new_smi->si_type]); return 0; @@ -3287,9 +3273,7 @@ static __devinit int init_ipmi_si(void) /* Register the device drivers. */ rv = driver_register(&ipmi_driver.driver); if (rv) { - printk(KERN_ERR - "init_ipmi_si: Unable to register driver: %d\n", - rv); + printk(KERN_ERR PFX "Unable to register driver: %d\n", rv); return rv; } @@ -3324,9 +3308,7 @@ static __devinit int init_ipmi_si(void) #ifdef CONFIG_PCI rv = pci_register_driver(&ipmi_pci_driver); if (rv) - printk(KERN_ERR - "init_ipmi_si: Unable to register PCI driver: %d\n", - rv); + printk(KERN_ERR PFX "Unable to register PCI driver: %d\n", rv); #endif #ifdef CONFIG_ACPI @@ -3403,8 +3385,8 @@ static __devinit int init_ipmi_si(void) of_unregister_platform_driver(&ipmi_of_platform_driver); #endif driver_unregister(&ipmi_driver.driver); - printk(KERN_WARNING - "ipmi_si: Unable to find any System Interface(s)\n"); + printk(KERN_WARNING PFX + "Unable to find any System Interface(s)\n"); return -ENODEV; } else { mutex_unlock(&smi_infos_lock); @@ -3463,8 +3445,7 @@ static void cleanup_one_si(struct smi_info *to_clean) rv = ipmi_unregister_smi(to_clean->intf); if (rv) { - printk(KERN_ERR - "ipmi_si: Unable to unregister device: errno=%d\n", + printk(KERN_ERR PFX "Unable to unregister device: errno=%d\n", rv); } -- cgit v1.2.3 From a747c5abc329611220f16df0bb4cf0ca4a7fdf0c Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Wed, 26 May 2010 14:43:53 -0700 Subject: ipmi: handle run_to_completion properly in deliver_recv_msg() If run_to_completion flag is set, it means that we are running in a single-threaded mode, and thus no locks are held. This fixes a deadlock when IPMI notifier is being called during panic. Signed-off-by: Jiri Kosina Acked-by: Corey Minyard Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index f052c481327a..35603dd4e6c5 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -323,9 +323,14 @@ static void deliver_recv_msg(struct smi_info *smi_info, { /* Deliver the message to the upper layer with the lock released. */ - spin_unlock(&(smi_info->si_lock)); - ipmi_smi_msg_received(smi_info->intf, msg); - spin_lock(&(smi_info->si_lock)); + + if (smi_info->run_to_completion) { + ipmi_smi_msg_received(smi_info->intf, msg); + } else { + spin_unlock(&(smi_info->si_lock)); + ipmi_smi_msg_received(smi_info->intf, msg); + spin_lock(&(smi_info->si_lock)); + } } static void return_hosed_msg(struct smi_info *smi_info, int cCode) -- cgit v1.2.3 From 56d611a04fb2db77334e06274de4daed92e2c626 Mon Sep 17 00:00:00 2001 From: Marco Stornelli Date: Wed, 26 May 2010 14:43:54 -0700 Subject: char drivers: RAM oops/panic logger Ramoops, like mtdoops, can log oops/panic information but in RAM. It can be used with persistent RAM for systems without flash support. In addition, for this systems, with this driver, it's no more needed add to the kernel the mtd subsystem with advantage in footprint. It can be used in a very easy way with persistent RAM for systems without flash support. For these systems, with this driver, it is no longer required to cinlude mtd subsystem with an advantage in footprint. In addition, you can save flash space and store this information only in RAM. Signed-off-by: Marco Stornelli Cc: Simon Kagstrom Cc: David Woodhouse Cc; Anders Grafstrom Cc: Yuasa Yoichi Cc: Jamie Lokier Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/Kconfig | 7 +++ drivers/char/Makefile | 1 + drivers/char/ramoops.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 170 insertions(+) create mode 100644 drivers/char/ramoops.c (limited to 'drivers') diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index e21175be25d0..f09fc0e2062d 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -1121,5 +1121,12 @@ config DEVPORT source "drivers/s390/char/Kconfig" +config RAMOOPS + tristate "Log panic/oops to a RAM buffer" + default n + help + This enables panic and oops messages to be logged to a circular + buffer in RAM where it can be read back at some later point. + endmenu diff --git a/drivers/char/Makefile b/drivers/char/Makefile index d39be4cf1f5d..88d6eac69754 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -108,6 +108,7 @@ obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o obj-$(CONFIG_TCG_TPM) += tpm/ obj-$(CONFIG_PS3_FLASH) += ps3flash.o +obj-$(CONFIG_RAMOOPS) += ramoops.o obj-$(CONFIG_JS_RTC) += js-rtc.o js-rtc-y = rtc.o diff --git a/drivers/char/ramoops.c b/drivers/char/ramoops.c new file mode 100644 index 000000000000..74f00b5ffa36 --- /dev/null +++ b/drivers/char/ramoops.c @@ -0,0 +1,162 @@ +/* + * RAM Oops/Panic logger + * + * Copyright (C) 2010 Marco Stornelli + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include + +#define RAMOOPS_KERNMSG_HDR "====" +#define RAMOOPS_HEADER_SIZE (5 + sizeof(struct timeval)) + +#define RECORD_SIZE 4096 + +static ulong mem_address; +module_param(mem_address, ulong, 0400); +MODULE_PARM_DESC(mem_address, + "start of reserved RAM used to store oops/panic logs"); + +static ulong mem_size; +module_param(mem_size, ulong, 0400); +MODULE_PARM_DESC(mem_size, + "size of reserved RAM used to store oops/panic logs"); + +static int dump_oops = 1; +module_param(dump_oops, int, 0600); +MODULE_PARM_DESC(dump_oops, + "set to 1 to dump oopses, 0 to only dump panics (default 1)"); + +static struct ramoops_context { + struct kmsg_dumper dump; + void *virt_addr; + phys_addr_t phys_addr; + unsigned long size; + int count; + int max_count; +} oops_cxt; + +static void ramoops_do_dump(struct kmsg_dumper *dumper, + enum kmsg_dump_reason reason, const char *s1, unsigned long l1, + const char *s2, unsigned long l2) +{ + struct ramoops_context *cxt = container_of(dumper, + struct ramoops_context, dump); + unsigned long s1_start, s2_start; + unsigned long l1_cpy, l2_cpy; + int res; + char *buf; + struct timeval timestamp; + + /* Only dump oopses if dump_oops is set */ + if (reason == KMSG_DUMP_OOPS && !dump_oops) + return; + + buf = (char *)(cxt->virt_addr + (cxt->count * RECORD_SIZE)); + memset(buf, '\0', RECORD_SIZE); + res = sprintf(buf, "%s", RAMOOPS_KERNMSG_HDR); + buf += res; + do_gettimeofday(×tamp); + res = sprintf(buf, "%lu.%lu\n", (long)timestamp.tv_sec, (long)timestamp.tv_usec); + buf += res; + + l2_cpy = min(l2, (unsigned long)(RECORD_SIZE - RAMOOPS_HEADER_SIZE)); + l1_cpy = min(l1, (unsigned long)(RECORD_SIZE - RAMOOPS_HEADER_SIZE) - l2_cpy); + + s2_start = l2 - l2_cpy; + s1_start = l1 - l1_cpy; + + memcpy(buf, s1 + s1_start, l1_cpy); + memcpy(buf + l1_cpy, s2 + s2_start, l2_cpy); + + cxt->count = (cxt->count + 1) % cxt->max_count; +} + +static int __init ramoops_init(void) +{ + struct ramoops_context *cxt = &oops_cxt; + int err = -EINVAL; + + if (!mem_size) { + printk(KERN_ERR "ramoops: invalid size specification"); + goto fail3; + } + + rounddown_pow_of_two(mem_size); + + if (mem_size < RECORD_SIZE) { + printk(KERN_ERR "ramoops: size too small"); + goto fail3; + } + + cxt->max_count = mem_size / RECORD_SIZE; + cxt->count = 0; + cxt->size = mem_size; + cxt->phys_addr = mem_address; + + if (!request_mem_region(cxt->phys_addr, cxt->size, "ramoops")) { + printk(KERN_ERR "ramoops: request mem region failed"); + err = -EINVAL; + goto fail3; + } + + cxt->virt_addr = ioremap(cxt->phys_addr, cxt->size); + if (!cxt->virt_addr) { + printk(KERN_ERR "ramoops: ioremap failed"); + goto fail2; + } + + cxt->dump.dump = ramoops_do_dump; + err = kmsg_dump_register(&cxt->dump); + if (err) { + printk(KERN_ERR "ramoops: registering kmsg dumper failed"); + goto fail1; + } + + return 0; + +fail1: + iounmap(cxt->virt_addr); +fail2: + release_mem_region(cxt->phys_addr, cxt->size); +fail3: + return err; +} + +static void __exit ramoops_exit(void) +{ + struct ramoops_context *cxt = &oops_cxt; + + if (kmsg_dump_unregister(&cxt->dump) < 0) + printk(KERN_WARNING "ramoops: could not unregister kmsg_dumper"); + + iounmap(cxt->virt_addr); + release_mem_region(cxt->phys_addr, cxt->size); +} + + +module_init(ramoops_init); +module_exit(ramoops_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Marco Stornelli "); +MODULE_DESCRIPTION("RAM Oops/Panic logger/driver"); -- cgit v1.2.3 From 87575437d8173c7da48a4dee25399807c7bec9cb Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 26 May 2010 14:43:55 -0700 Subject: drivers/char/ppdev.c: use kasprintf kasprintf combines kmalloc and sprintf, and takes care of the size calculation itself. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression a,flag; expression list args; statement S; @@ a = - \(kmalloc\|kzalloc\)(...,flag) + kasprintf(flag,args) <... when != a if (a == NULL || ...) S ...> - sprintf(a,args); // Signed-off-by: Julia Lawall Cc: Michael Buesch Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ppdev.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index fdd37543aa79..02abfddce45a 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c @@ -287,12 +287,10 @@ static int register_device (int minor, struct pp_struct *pp) char *name; int fl; - name = kmalloc (strlen (CHRDEV) + 3, GFP_KERNEL); + name = kasprintf(GFP_KERNEL, CHRDEV "%x", minor); if (name == NULL) return -ENOMEM; - sprintf (name, CHRDEV "%x", minor); - port = parport_find_number (minor); if (!port) { printk (KERN_WARNING "%s: no associated port!\n", name); -- cgit v1.2.3 From f67231f80126f4e08c79c7b2056989c5c89ad4c6 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 26 May 2010 14:43:56 -0700 Subject: drivers/char/applicom.c: use memdup_user Use memdup_user when user data is immediately copied into the allocated region. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression from,to,size,flag; position p; identifier l1,l2; @@ - to = \(kmalloc@p\|kzalloc@p\)(size,flag); + to = memdup_user(from,size); if ( - to==NULL + IS_ERR(to) || ...) { <+... when != goto l1; - -ENOMEM + PTR_ERR(to) ...+> } - if (copy_from_user(to, from, size) != 0) { - <+... when != goto l2; - -EFAULT - ...+> - } // Signed-off-by: Julia Lawall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/applicom.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index 63313a33ba5f..f4ae0e0fb631 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c @@ -703,14 +703,9 @@ static long ac_ioctl(struct file *file, unsigned int cmd, unsigned long arg) /* In general, the device is only openable by root anyway, so we're not particularly concerned that bogus ioctls can flood the console. */ - adgl = kmalloc(sizeof(struct st_ram_io), GFP_KERNEL); - if (!adgl) - return -ENOMEM; - - if (copy_from_user(adgl, argp, sizeof(struct st_ram_io))) { - kfree(adgl); - return -EFAULT; - } + adgl = memdup_user(argp, sizeof(struct st_ram_io)); + if (IS_ERR(adgl)) + return PTR_ERR(adgl); lock_kernel(); IndexCard = adgl->num_card-1; -- cgit v1.2.3 From 07590ff03935a2efbc03bc7861f20c059576a479 Mon Sep 17 00:00:00 2001 From: Alexandre Bounine Date: Wed, 26 May 2010 14:43:57 -0700 Subject: rapidio: add IDT CPS/TSI switches Extentions to RapidIO switch support: 1. modify switch route operation declarations to allow using single switch-specific file for family of switches that share the same route table operations. 2. add standard route table operations for switches that that support route table manipulation registers as defined in the Rev.1.3 of RapidIO specification. 3. add clear-route-table operation for switches 4. add CPSxx and TSIxxx families of RapidIO switches Signed-off-by: Alexandre Bounine Tested-by: Thomas Moll Cc: Matt Porter Cc: Li Yang Cc: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rapidio/Kconfig | 2 + drivers/rapidio/rio-scan.c | 20 ++++++- drivers/rapidio/rio.c | 104 +++++++++++++++++++++++++++++++++++++ drivers/rapidio/rio.h | 20 ++++--- drivers/rapidio/switches/Kconfig | 28 ++++++++++ drivers/rapidio/switches/Makefile | 5 +- drivers/rapidio/switches/idtcps.c | 89 ++++++++++++++++++++++++++++++++ drivers/rapidio/switches/tsi500.c | 2 +- drivers/rapidio/switches/tsi568.c | 106 ++++++++++++++++++++++++++++++++++++++ drivers/rapidio/switches/tsi57x.c | 106 ++++++++++++++++++++++++++++++++++++++ include/linux/rio.h | 6 +++ include/linux/rio_ids.h | 14 +++++ include/linux/rio_regs.h | 14 ++++- 13 files changed, 505 insertions(+), 11 deletions(-) create mode 100644 drivers/rapidio/switches/Kconfig create mode 100644 drivers/rapidio/switches/idtcps.c create mode 100644 drivers/rapidio/switches/tsi568.c create mode 100644 drivers/rapidio/switches/tsi57x.c (limited to 'drivers') diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig index c32822ad84a4..606cb172c1e5 100644 --- a/drivers/rapidio/Kconfig +++ b/drivers/rapidio/Kconfig @@ -8,3 +8,5 @@ config RAPIDIO_DISC_TIMEOUT ---help--- Amount of time a discovery node waits for a host to complete enumeration before giving up. + +source "drivers/rapidio/switches/Kconfig" diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index 45415096c294..7f1a675d835d 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c @@ -55,6 +55,7 @@ static int rio_mport_phys_table[] = { static int rio_sport_phys_table[] = { RIO_EFB_PAR_EP_FREE_ID, RIO_EFB_SER_EP_FREE_ID, + RIO_EFB_SER_EP_FREC_ID, -1, }; @@ -246,10 +247,20 @@ static void rio_route_set_ops(struct rio_dev *rdev) pr_debug("RIO: adding routing ops for %s\n", rio_name(rdev)); rdev->rswitch->add_entry = cur->add_hook; rdev->rswitch->get_entry = cur->get_hook; + rdev->rswitch->clr_table = cur->clr_hook; + break; } cur++; } + if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) { + pr_debug("RIO: adding STD routing ops for %s\n", + rio_name(rdev)); + rdev->rswitch->add_entry = rio_std_route_add_entry; + rdev->rswitch->get_entry = rio_std_route_get_entry; + rdev->rswitch->clr_table = rio_std_route_clr_table; + } + if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry) printk(KERN_ERR "RIO: missing routing ops for %s\n", rio_name(rdev)); @@ -349,7 +360,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, if (rio_is_switch(rdev)) { rio_mport_read_config_32(port, destid, hopcount, RIO_SWP_INFO_CAR, &rdev->swpinfo); - rswitch = kmalloc(sizeof(struct rio_switch), GFP_KERNEL); + rswitch = kzalloc(sizeof(struct rio_switch), GFP_KERNEL); if (!rswitch) goto cleanup; rswitch->switchid = next_switchid; @@ -369,6 +380,10 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, rdev->rswitch->switchid); rio_route_set_ops(rdev); + if (do_enum && rdev->rswitch->clr_table) + rdev->rswitch->clr_table(port, destid, hopcount, + RIO_GLOBAL_TABLE); + list_add_tail(&rswitch->node, &rio_switches); } else @@ -866,6 +881,9 @@ static void rio_update_route_tables(struct rio_mport *port) continue; if (RIO_INVALID_ROUTE == rswitch->route_table[destid]) { + /* Skip if destid ends in empty switch*/ + if (rswitch->destid == destid) + continue; sport = rio_get_swpinfo_inport(port, rswitch->destid, rswitch->hopcount); diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index 6395c780008b..67a379216959 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c @@ -451,6 +451,110 @@ struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from) return rio_get_asm(vid, did, RIO_ANY_ID, RIO_ANY_ID, from); } +/** + * rio_std_route_add_entry - Add switch route table entry using standard + * registers defined in RIO specification rev.1.3 + * @mport: Master port to issue transaction + * @destid: Destination ID of the device + * @hopcount: Number of switch hops to the device + * @table: routing table ID (global or port-specific) + * @route_destid: destID entry in the RT + * @route_port: destination port for specified destID + */ +int rio_std_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, + u16 table, u16 route_destid, u8 route_port) +{ + if (table == RIO_GLOBAL_TABLE) { + rio_mport_write_config_32(mport, destid, hopcount, + RIO_STD_RTE_CONF_DESTID_SEL_CSR, + (u32)route_destid); + rio_mport_write_config_32(mport, destid, hopcount, + RIO_STD_RTE_CONF_PORT_SEL_CSR, + (u32)route_port); + } + udelay(10); + return 0; +} + +/** + * rio_std_route_get_entry - Read switch route table entry (port number) + * assosiated with specified destID using standard registers defined in RIO + * specification rev.1.3 + * @mport: Master port to issue transaction + * @destid: Destination ID of the device + * @hopcount: Number of switch hops to the device + * @table: routing table ID (global or port-specific) + * @route_destid: destID entry in the RT + * @route_port: returned destination port for specified destID + */ +int rio_std_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, + u16 table, u16 route_destid, u8 *route_port) +{ + u32 result; + + if (table == RIO_GLOBAL_TABLE) { + rio_mport_write_config_32(mport, destid, hopcount, + RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid); + rio_mport_read_config_32(mport, destid, hopcount, + RIO_STD_RTE_CONF_PORT_SEL_CSR, &result); + + *route_port = (u8)result; + } + + return 0; +} + +/** + * rio_std_route_clr_table - Clear swotch route table using standard registers + * defined in RIO specification rev.1.3. + * @mport: Master port to issue transaction + * @local: Indicate a local master port or remote device access + * @destid: Destination ID of the device + * @hopcount: Number of switch hops to the device + * @table: routing table ID (global or port-specific) + */ +int rio_std_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, + u16 table) +{ + u32 max_destid = 0xff; + u32 i, pef, id_inc = 1, ext_cfg = 0; + u32 port_sel = RIO_INVALID_ROUTE; + + if (table == RIO_GLOBAL_TABLE) { + rio_mport_read_config_32(mport, destid, hopcount, + RIO_PEF_CAR, &pef); + + if (mport->sys_size) { + rio_mport_read_config_32(mport, destid, hopcount, + RIO_SWITCH_RT_LIMIT, + &max_destid); + max_destid &= RIO_RT_MAX_DESTID; + } + + if (pef & RIO_PEF_EXT_RT) { + ext_cfg = 0x80000000; + id_inc = 4; + port_sel = (RIO_INVALID_ROUTE << 24) | + (RIO_INVALID_ROUTE << 16) | + (RIO_INVALID_ROUTE << 8) | + RIO_INVALID_ROUTE; + } + + for (i = 0; i <= max_destid;) { + rio_mport_write_config_32(mport, destid, hopcount, + RIO_STD_RTE_CONF_DESTID_SEL_CSR, + ext_cfg | i); + rio_mport_write_config_32(mport, destid, hopcount, + RIO_STD_RTE_CONF_PORT_SEL_CSR, + port_sel); + i += id_inc; + } + } + + udelay(10); + return 0; +} + static void rio_fixup_device(struct rio_dev *dev) { } diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h index 7786d02581f2..b53c5ec276a5 100644 --- a/drivers/rapidio/rio.h +++ b/drivers/rapidio/rio.h @@ -21,6 +21,14 @@ extern u32 rio_mport_get_feature(struct rio_mport *mport, int local, u16 destid, extern int rio_create_sysfs_dev_files(struct rio_dev *rdev); extern int rio_enum_mport(struct rio_mport *mport); extern int rio_disc_mport(struct rio_mport *mport); +extern int rio_std_route_add_entry(struct rio_mport *mport, u16 destid, + u8 hopcount, u16 table, u16 route_destid, + u8 route_port); +extern int rio_std_route_get_entry(struct rio_mport *mport, u16 destid, + u8 hopcount, u16 table, u16 route_destid, + u8 *route_port); +extern int rio_std_route_clr_table(struct rio_mport *mport, u16 destid, + u8 hopcount, u16 table); /* Structures internal to the RIO core code */ extern struct device_attribute rio_dev_attrs[]; @@ -30,9 +38,9 @@ extern struct rio_route_ops __start_rio_route_ops[]; extern struct rio_route_ops __end_rio_route_ops[]; /* Helpers internal to the RIO core code */ -#define DECLARE_RIO_ROUTE_SECTION(section, vid, did, add_hook, get_hook) \ - static struct rio_route_ops __rio_route_ops __used \ - __section(section)= { vid, did, add_hook, get_hook }; +#define DECLARE_RIO_ROUTE_SECTION(section, name, vid, did, add_hook, get_hook, clr_hook) \ + static const struct rio_route_ops __rio_route_##name __used \ + __section(section) = { vid, did, add_hook, get_hook, clr_hook }; /** * DECLARE_RIO_ROUTE_OPS - Registers switch routing operations @@ -47,9 +55,9 @@ extern struct rio_route_ops __end_rio_route_ops[]; * rio_route_ops is initialized with the ops and placed into a * RIO-specific kernel section. */ -#define DECLARE_RIO_ROUTE_OPS(vid, did, add_hook, get_hook) \ - DECLARE_RIO_ROUTE_SECTION(.rio_route_ops, \ - vid, did, add_hook, get_hook) +#define DECLARE_RIO_ROUTE_OPS(vid, did, add_hook, get_hook, clr_hook) \ + DECLARE_RIO_ROUTE_SECTION(.rio_route_ops, vid##did, \ + vid, did, add_hook, get_hook, clr_hook) #define RIO_GET_DID(size, x) (size ? (x & 0xffff) : ((x & 0x00ff0000) >> 16)) #define RIO_SET_DID(size, x) (size ? (x & 0xffff) : ((x & 0x000000ff) << 16)) diff --git a/drivers/rapidio/switches/Kconfig b/drivers/rapidio/switches/Kconfig new file mode 100644 index 000000000000..6969f398bc26 --- /dev/null +++ b/drivers/rapidio/switches/Kconfig @@ -0,0 +1,28 @@ +# +# RapidIO switches configuration +# +config RAPIDIO_TSI57X + bool "IDT Tsi57x SRIO switches support" + depends on RAPIDIO + ---help--- + Includes support for ITD Tsi57x family of serial RapidIO switches. + +config RAPIDIO_CPS_XX + bool "IDT CPS-xx SRIO switches support" + depends on RAPIDIO + ---help--- + Includes support for ITD CPS-16/12/10/8 serial RapidIO switches. + +config RAPIDIO_TSI568 + bool "Tsi568 SRIO switch support" + depends on RAPIDIO + default n + ---help--- + Includes support for ITD Tsi568 serial RapidIO switch. + +config RAPIDIO_TSI500 + bool "Tsi500 Parallel RapidIO switch support" + depends on RAPIDIO + default n + ---help--- + Includes support for ITD Tsi500 parallel RapidIO switch. diff --git a/drivers/rapidio/switches/Makefile b/drivers/rapidio/switches/Makefile index b924f8301761..0fece0e6aa89 100644 --- a/drivers/rapidio/switches/Makefile +++ b/drivers/rapidio/switches/Makefile @@ -2,4 +2,7 @@ # Makefile for RIO switches # -obj-$(CONFIG_RAPIDIO) += tsi500.o +obj-$(CONFIG_RAPIDIO_TSI57X) += tsi57x.o +obj-$(CONFIG_RAPIDIO_CPS_XX) += idtcps.o +obj-$(CONFIG_RAPIDIO_TSI568) += tsi568.o +obj-$(CONFIG_RAPIDIO_TSI500) += tsi500.o diff --git a/drivers/rapidio/switches/idtcps.c b/drivers/rapidio/switches/idtcps.c new file mode 100644 index 000000000000..7e3d03283dec --- /dev/null +++ b/drivers/rapidio/switches/idtcps.c @@ -0,0 +1,89 @@ +/* + * IDT CPS RapidIO switches support + * + * Copyright 2009 Integrated Device Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include "../rio.h" + +#define CPS_NO_ROUTE 0xdf + +static int +idtcps_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, + u16 table, u16 route_destid, u8 route_port) +{ + u32 result; + + if (table == RIO_GLOBAL_TABLE) { + rio_mport_write_config_32(mport, destid, hopcount, + RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid); + + rio_mport_read_config_32(mport, destid, hopcount, + RIO_STD_RTE_CONF_PORT_SEL_CSR, &result); + + result = (0xffffff00 & result) | (u32)route_port; + rio_mport_write_config_32(mport, destid, hopcount, + RIO_STD_RTE_CONF_PORT_SEL_CSR, result); + } + + return 0; +} + +static int +idtcps_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, + u16 table, u16 route_destid, u8 *route_port) +{ + u32 result; + + if (table == RIO_GLOBAL_TABLE) { + rio_mport_write_config_32(mport, destid, hopcount, + RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid); + + rio_mport_read_config_32(mport, destid, hopcount, + RIO_STD_RTE_CONF_PORT_SEL_CSR, &result); + + if (CPS_NO_ROUTE == (u8)result) + result = RIO_INVALID_ROUTE; + + *route_port = (u8)result; + } + + return 0; +} + +static int +idtcps_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, + u16 table) +{ + u32 i; + + if (table == RIO_GLOBAL_TABLE) { + for (i = 0x80000000; i <= 0x800000ff;) { + rio_mport_write_config_32(mport, destid, hopcount, + RIO_STD_RTE_CONF_DESTID_SEL_CSR, i); + rio_mport_write_config_32(mport, destid, hopcount, + RIO_STD_RTE_CONF_PORT_SEL_CSR, + (RIO_INVALID_ROUTE << 24) | + (RIO_INVALID_ROUTE << 16) | + (RIO_INVALID_ROUTE << 8) | RIO_INVALID_ROUTE); + i += 4; + } + } + + return 0; +} + +DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS6Q, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table); +DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS8, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table); +DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS10Q, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table); +DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS12, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table); +DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS16, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table); +DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDT70K200, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table); diff --git a/drivers/rapidio/switches/tsi500.c b/drivers/rapidio/switches/tsi500.c index c77c23bd9840..ae553bb41089 100644 --- a/drivers/rapidio/switches/tsi500.c +++ b/drivers/rapidio/switches/tsi500.c @@ -57,4 +57,4 @@ tsi500_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 tab return ret; } -DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI500, tsi500_route_add_entry, tsi500_route_get_entry); +DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI500, tsi500_route_add_entry, tsi500_route_get_entry, NULL); diff --git a/drivers/rapidio/switches/tsi568.c b/drivers/rapidio/switches/tsi568.c new file mode 100644 index 000000000000..bce9112ff0d9 --- /dev/null +++ b/drivers/rapidio/switches/tsi568.c @@ -0,0 +1,106 @@ +/* + * RapidIO Tsi568 switch support + * + * Copyright 2009-2010 Integrated Device Technology, Inc. + * Copyright 2005 MontaVista Software, Inc. + * Matt Porter + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include "../rio.h" + +/* Global (broadcast) route registers */ +#define SPBC_ROUTE_CFG_DESTID 0x10070 +#define SPBC_ROUTE_CFG_PORT 0x10074 + +/* Per port route registers */ +#define SPP_ROUTE_CFG_DESTID(n) (0x11070 + 0x100*n) +#define SPP_ROUTE_CFG_PORT(n) (0x11074 + 0x100*n) + +static int +tsi568_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, + u16 table, u16 route_destid, u8 route_port) +{ + if (table == RIO_GLOBAL_TABLE) { + rio_mport_write_config_32(mport, destid, hopcount, + SPBC_ROUTE_CFG_DESTID, route_destid); + rio_mport_write_config_32(mport, destid, hopcount, + SPBC_ROUTE_CFG_PORT, route_port); + } else { + rio_mport_write_config_32(mport, destid, hopcount, + SPP_ROUTE_CFG_DESTID(table), + route_destid); + rio_mport_write_config_32(mport, destid, hopcount, + SPP_ROUTE_CFG_PORT(table), route_port); + } + + udelay(10); + + return 0; +} + +static int +tsi568_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, + u16 table, u16 route_destid, u8 *route_port) +{ + int ret = 0; + u32 result; + + if (table == RIO_GLOBAL_TABLE) { + rio_mport_write_config_32(mport, destid, hopcount, + SPBC_ROUTE_CFG_DESTID, route_destid); + rio_mport_read_config_32(mport, destid, hopcount, + SPBC_ROUTE_CFG_PORT, &result); + } else { + rio_mport_write_config_32(mport, destid, hopcount, + SPP_ROUTE_CFG_DESTID(table), + route_destid); + rio_mport_read_config_32(mport, destid, hopcount, + SPP_ROUTE_CFG_PORT(table), &result); + } + + *route_port = result; + if (*route_port > 15) + ret = -1; + + return ret; +} + +static int +tsi568_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, + u16 table) +{ + u32 route_idx; + u32 lut_size; + + lut_size = (mport->sys_size) ? 0x1ff : 0xff; + + if (table == RIO_GLOBAL_TABLE) { + rio_mport_write_config_32(mport, destid, hopcount, + SPBC_ROUTE_CFG_DESTID, 0x80000000); + for (route_idx = 0; route_idx <= lut_size; route_idx++) + rio_mport_write_config_32(mport, destid, hopcount, + SPBC_ROUTE_CFG_PORT, + RIO_INVALID_ROUTE); + } else { + rio_mport_write_config_32(mport, destid, hopcount, + SPP_ROUTE_CFG_DESTID(table), + 0x80000000); + for (route_idx = 0; route_idx <= lut_size; route_idx++) + rio_mport_write_config_32(mport, destid, hopcount, + SPP_ROUTE_CFG_PORT(table), + RIO_INVALID_ROUTE); + } + + return 0; +} + +DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI568, tsi568_route_add_entry, tsi568_route_get_entry, tsi568_route_clr_table); diff --git a/drivers/rapidio/switches/tsi57x.c b/drivers/rapidio/switches/tsi57x.c new file mode 100644 index 000000000000..5ad7880787c9 --- /dev/null +++ b/drivers/rapidio/switches/tsi57x.c @@ -0,0 +1,106 @@ +/* + * RapidIO Tsi57x switch family support + * + * Copyright 2009 Integrated Device Technology, Inc. + * Copyright 2005 MontaVista Software, Inc. + * Matt Porter + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include "../rio.h" + +/* Global (broadcast) route registers */ +#define SPBC_ROUTE_CFG_DESTID 0x10070 +#define SPBC_ROUTE_CFG_PORT 0x10074 + +/* Per port route registers */ +#define SPP_ROUTE_CFG_DESTID(n) (0x11070 + 0x100*n) +#define SPP_ROUTE_CFG_PORT(n) (0x11074 + 0x100*n) + +static int +tsi57x_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, + u16 table, u16 route_destid, u8 route_port) +{ + if (table == RIO_GLOBAL_TABLE) { + rio_mport_write_config_32(mport, destid, hopcount, + SPBC_ROUTE_CFG_DESTID, route_destid); + rio_mport_write_config_32(mport, destid, hopcount, + SPBC_ROUTE_CFG_PORT, route_port); + } else { + rio_mport_write_config_32(mport, destid, hopcount, + SPP_ROUTE_CFG_DESTID(table), route_destid); + rio_mport_write_config_32(mport, destid, hopcount, + SPP_ROUTE_CFG_PORT(table), route_port); + } + + udelay(10); + + return 0; +} + +static int +tsi57x_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, + u16 table, u16 route_destid, u8 *route_port) +{ + int ret = 0; + u32 result; + + if (table == RIO_GLOBAL_TABLE) { + /* Use local RT of the ingress port to avoid possible + race condition */ + rio_mport_read_config_32(mport, destid, hopcount, + RIO_SWP_INFO_CAR, &result); + table = (result & RIO_SWP_INFO_PORT_NUM_MASK); + } + + rio_mport_write_config_32(mport, destid, hopcount, + SPP_ROUTE_CFG_DESTID(table), route_destid); + rio_mport_read_config_32(mport, destid, hopcount, + SPP_ROUTE_CFG_PORT(table), &result); + + *route_port = (u8)result; + if (*route_port > 15) + ret = -1; + + return ret; +} + +static int +tsi57x_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, + u16 table) +{ + u32 route_idx; + u32 lut_size; + + lut_size = (mport->sys_size) ? 0x1ff : 0xff; + + if (table == RIO_GLOBAL_TABLE) { + rio_mport_write_config_32(mport, destid, hopcount, + SPBC_ROUTE_CFG_DESTID, 0x80000000); + for (route_idx = 0; route_idx <= lut_size; route_idx++) + rio_mport_write_config_32(mport, destid, hopcount, + SPBC_ROUTE_CFG_PORT, + RIO_INVALID_ROUTE); + } else { + rio_mport_write_config_32(mport, destid, hopcount, + SPP_ROUTE_CFG_DESTID(table), 0x80000000); + for (route_idx = 0; route_idx <= lut_size; route_idx++) + rio_mport_write_config_32(mport, destid, hopcount, + SPP_ROUTE_CFG_PORT(table) , RIO_INVALID_ROUTE); + } + + return 0; +} + +DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI572, tsi57x_route_add_entry, tsi57x_route_get_entry, tsi57x_route_clr_table); +DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI574, tsi57x_route_add_entry, tsi57x_route_get_entry, tsi57x_route_clr_table); +DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI577, tsi57x_route_add_entry, tsi57x_route_get_entry, tsi57x_route_clr_table); +DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI578, tsi57x_route_add_entry, tsi57x_route_get_entry, tsi57x_route_clr_table); diff --git a/include/linux/rio.h b/include/linux/rio.h index dc0c75556c63..29d98997c6c8 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h @@ -213,6 +213,7 @@ struct rio_net { * @route_table: Copy of switch routing table * @add_entry: Callback for switch-specific route add function * @get_entry: Callback for switch-specific route get function + * @clr_table: Callback for switch-specific clear route table function */ struct rio_switch { struct list_head node; @@ -224,6 +225,8 @@ struct rio_switch { u16 table, u16 route_destid, u8 route_port); int (*get_entry) (struct rio_mport * mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 * route_port); + int (*clr_table) (struct rio_mport *mport, u16 destid, u8 hopcount, + u16 table); }; /* Low-level architecture-dependent routines */ @@ -307,6 +310,7 @@ struct rio_device_id { * @did: RIO device ID * @add_hook: Callback that adds a route entry * @get_hook: Callback that gets a route entry + * @clr_hook: Callback that clears a switch route table (may be NULL) * * Defines the operations that are necessary to manipulate the route * tables for a particular RIO switch device. @@ -317,6 +321,8 @@ struct rio_route_ops { u16 table, u16 route_destid, u8 route_port); int (*get_hook) (struct rio_mport * mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 * route_port); + int (*clr_hook) (struct rio_mport *mport, u16 destid, u8 hopcount, + u16 table); }; /* Architecture and hardware-specific functions */ diff --git a/include/linux/rio_ids.h b/include/linux/rio_ids.h index 919d4e07d54e..db50e1c288b7 100644 --- a/include/linux/rio_ids.h +++ b/include/linux/rio_ids.h @@ -20,5 +20,19 @@ #define RIO_VID_TUNDRA 0x000d #define RIO_DID_TSI500 0x0500 +#define RIO_DID_TSI568 0x0568 +#define RIO_DID_TSI572 0x0572 +#define RIO_DID_TSI574 0x0574 +#define RIO_DID_TSI576 0x0578 /* Same ID as Tsi578 */ +#define RIO_DID_TSI577 0x0577 +#define RIO_DID_TSI578 0x0578 + +#define RIO_VID_IDT 0x0038 +#define RIO_DID_IDT70K200 0x0310 +#define RIO_DID_IDTCPS8 0x035c +#define RIO_DID_IDTCPS12 0x035d +#define RIO_DID_IDTCPS16 0x035b +#define RIO_DID_IDTCPS6Q 0x035f +#define RIO_DID_IDTCPS10Q 0x035e #endif /* LINUX_RIO_IDS_H */ diff --git a/include/linux/rio_regs.h b/include/linux/rio_regs.h index 326540f9b54e..4bfb0dcfac7c 100644 --- a/include/linux/rio_regs.h +++ b/include/linux/rio_regs.h @@ -39,6 +39,8 @@ #define RIO_PEF_INB_MBOX2 0x00200000 /* [II] Mailbox 2 */ #define RIO_PEF_INB_MBOX3 0x00100000 /* [II] Mailbox 3 */ #define RIO_PEF_INB_DOORBELL 0x00080000 /* [II] Doorbells */ +#define RIO_PEF_EXT_RT 0x00000200 /* [III, 1.3] Extended route table support */ +#define RIO_PEF_STD_RT 0x00000100 /* [III, 1.3] Standard route table support */ #define RIO_PEF_CTLS 0x00000010 /* [III] CTLS */ #define RIO_PEF_EXT_FEATURES 0x00000008 /* [I] EFT_PTR valid */ #define RIO_PEF_ADDR_66 0x00000004 /* [I] 66 bits */ @@ -91,7 +93,10 @@ #define RIO_OPS_ATOMIC_CLR 0x00000010 /* [I] Atomic clr op */ #define RIO_OPS_PORT_WRITE 0x00000004 /* [I] Port-write op */ - /* 0x20-0x3c *//* Reserved */ + /* 0x20-0x30 *//* Reserved */ + +#define RIO_SWITCH_RT_LIMIT 0x34 /* [III, 1.3] Switch Route Table Destination ID Limit CAR */ +#define RIO_RT_MAX_DESTID 0x0000ffff #define RIO_MBOX_CSR 0x40 /* [II] Mailbox CSR */ #define RIO_MBOX0_AVAIL 0x80000000 /* [II] Mbox 0 avail */ @@ -153,7 +158,11 @@ #define RIO_HOST_DID_LOCK_CSR 0x68 /* [III] Host Base Device ID Lock CSR */ #define RIO_COMPONENT_TAG_CSR 0x6c /* [III] Component Tag CSR */ - /* 0x70-0xf8 *//* Reserved */ +#define RIO_STD_RTE_CONF_DESTID_SEL_CSR 0x70 +#define RIO_STD_RTE_CONF_PORT_SEL_CSR 0x74 +#define RIO_STD_RTE_DEFAULT_PORT 0x78 + + /* 0x7c-0xf8 *//* Reserved */ /* 0x100-0xfff8 *//* [I] Extended Features Space */ /* 0x10000-0xfffff8 *//* [I] Implementation-defined Space */ @@ -186,6 +195,7 @@ #define RIO_EFB_SER_EP_ID 0x0004 /* [VI] LP/Serial EP Devices */ #define RIO_EFB_SER_EP_REC_ID 0x0005 /* [VI] LP/Serial EP Recovery Devices */ #define RIO_EFB_SER_EP_FREE_ID 0x0006 /* [VI] LP/Serial EP Free Devices */ +#define RIO_EFB_SER_EP_FREC_ID 0x0009 /* [VI] LP/Serial EP Free Recovery Devices */ /* * Physical 8/16 LP-LVDS -- cgit v1.2.3 From 818a04a0bb93643d57dd8935815de2ff307b58a3 Mon Sep 17 00:00:00 2001 From: Alexandre Bounine Date: Wed, 26 May 2010 14:43:58 -0700 Subject: rapidio: add switch locking during discovery Add switch access locking during RapidIO discovery. Access lock is required when reading switch routing table contents due to indexed mechanism of RT addressing. Signed-off-by: Alexandre Bounine Tested-by: Thomas Moll Cc: Matt Porter Cc: Li Yang Cc: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rapidio/rio-scan.c | 164 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 144 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index 7f1a675d835d..cbf0d5f4fba8 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c @@ -456,6 +456,80 @@ rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport) return (result & PORT_N_ERR_STS_PORT_OK); } +/** + * rio_lock_device - Acquires host device lock for specified device + * @port: Master port to send transaction + * @destid: Destination ID for device/switch + * @hopcount: Hopcount to reach switch + * @wait_ms: Max wait time in msec (0 = no timeout) + * + * Attepts to acquire host device lock for specified device + * Returns 0 if device lock acquired or EINVAL if timeout expires. + */ +static int +rio_lock_device(struct rio_mport *port, u16 destid, u8 hopcount, int wait_ms) +{ + u32 result; + int tcnt = 0; + + /* Attempt to acquire device lock */ + rio_mport_write_config_32(port, destid, hopcount, + RIO_HOST_DID_LOCK_CSR, port->host_deviceid); + rio_mport_read_config_32(port, destid, hopcount, + RIO_HOST_DID_LOCK_CSR, &result); + + while (result != port->host_deviceid) { + if (wait_ms != 0 && tcnt == wait_ms) { + pr_debug("RIO: timeout when locking device %x:%x\n", + destid, hopcount); + return -EINVAL; + } + + /* Delay a bit */ + mdelay(1); + tcnt++; + /* Try to acquire device lock again */ + rio_mport_write_config_32(port, destid, + hopcount, + RIO_HOST_DID_LOCK_CSR, + port->host_deviceid); + rio_mport_read_config_32(port, destid, + hopcount, + RIO_HOST_DID_LOCK_CSR, &result); + } + + return 0; +} + +/** + * rio_unlock_device - Releases host device lock for specified device + * @port: Master port to send transaction + * @destid: Destination ID for device/switch + * @hopcount: Hopcount to reach switch + * + * Returns 0 if device lock released or EINVAL if fails. + */ +static int +rio_unlock_device(struct rio_mport *port, u16 destid, u8 hopcount) +{ + u32 result; + + /* Release device lock */ + rio_mport_write_config_32(port, destid, + hopcount, + RIO_HOST_DID_LOCK_CSR, + port->host_deviceid); + rio_mport_read_config_32(port, destid, hopcount, + RIO_HOST_DID_LOCK_CSR, &result); + if ((result & 0xffff) != 0xffff) { + pr_debug("RIO: badness when releasing device lock %x:%x\n", + destid, hopcount); + return -EINVAL; + } + + return 0; +} + /** * rio_route_add_entry- Add a route entry to a switch routing table * @mport: Master port to send transaction @@ -463,6 +537,7 @@ rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport) * @table: Routing table ID * @route_destid: Destination ID to be routed * @route_port: Port number to be routed + * @lock: lock switch device flag * * Calls the switch specific add_entry() method to add a route entry * on a switch. The route table can be specified using the @table @@ -471,12 +546,26 @@ rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport) * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL * on failure. */ -static int rio_route_add_entry(struct rio_mport *mport, struct rio_switch *rswitch, - u16 table, u16 route_destid, u8 route_port) +static int +rio_route_add_entry(struct rio_mport *mport, struct rio_switch *rswitch, + u16 table, u16 route_destid, u8 route_port, int lock) { - return rswitch->add_entry(mport, rswitch->destid, + int rc; + + if (lock) { + rc = rio_lock_device(mport, rswitch->destid, + rswitch->hopcount, 1000); + if (rc) + return rc; + } + + rc = rswitch->add_entry(mport, rswitch->destid, rswitch->hopcount, table, route_destid, route_port); + if (lock) + rio_unlock_device(mport, rswitch->destid, rswitch->hopcount); + + return rc; } /** @@ -486,6 +575,7 @@ static int rio_route_add_entry(struct rio_mport *mport, struct rio_switch *rswit * @table: Routing table ID * @route_destid: Destination ID to be routed * @route_port: Pointer to read port number into + * @lock: lock switch device flag * * Calls the switch specific get_entry() method to read a route entry * in a switch. The route table can be specified using the @table @@ -496,11 +586,24 @@ static int rio_route_add_entry(struct rio_mport *mport, struct rio_switch *rswit */ static int rio_route_get_entry(struct rio_mport *mport, struct rio_switch *rswitch, u16 table, - u16 route_destid, u8 * route_port) + u16 route_destid, u8 *route_port, int lock) { - return rswitch->get_entry(mport, rswitch->destid, + int rc; + + if (lock) { + rc = rio_lock_device(mport, rswitch->destid, + rswitch->hopcount, 1000); + if (rc) + return rc; + } + + rc = rswitch->get_entry(mport, rswitch->destid, rswitch->hopcount, table, route_destid, route_port); + if (lock) + rio_unlock_device(mport, rswitch->destid, rswitch->hopcount); + + return rc; } /** @@ -640,14 +743,14 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, sw_inport = rio_get_swpinfo_inport(port, RIO_ANY_DESTID(port->sys_size), hopcount); rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE, - port->host_deviceid, sw_inport); + port->host_deviceid, sw_inport, 0); rdev->rswitch->route_table[port->host_deviceid] = sw_inport; for (destid = 0; destid < next_destid; destid++) { if (destid == port->host_deviceid) continue; rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE, - destid, sw_inport); + destid, sw_inport, 0); rdev->rswitch->route_table[destid] = sw_inport; } @@ -673,7 +776,7 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE, RIO_ANY_DESTID(port->sys_size), - port_num); + port_num, 0); if (rio_enum_peer(net, port, hopcount + 1) < 0) return -1; @@ -687,7 +790,8 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE, destid, - port_num); + port_num, + 0); rdev->rswitch-> route_table[destid] = port_num; @@ -778,17 +882,21 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid, pr_debug( "RIO: scanning device on port %d\n", port_num); + + rio_lock_device(port, destid, hopcount, 1000); + for (ndestid = 0; ndestid < RIO_ANY_DESTID(port->sys_size); ndestid++) { rio_route_get_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE, ndestid, - &route_port); + &route_port, 0); if (route_port == port_num) break; } + rio_unlock_device(port, destid, hopcount); if (rio_disc_peer (net, port, ndestid, hopcount + 1) < 0) return -1; @@ -889,7 +997,9 @@ static void rio_update_route_tables(struct rio_mport *port) rswitch->destid, rswitch->hopcount); if (rswitch->add_entry) { - rio_route_add_entry(port, rswitch, RIO_GLOBAL_TABLE, destid, sport); + rio_route_add_entry(port, rswitch, + RIO_GLOBAL_TABLE, destid, + sport, 0); rswitch->route_table[destid] = sport; } } @@ -963,15 +1073,22 @@ static void rio_build_route_tables(void) u8 sport; list_for_each_entry(rdev, &rio_devices, global_list) - if (rio_is_switch(rdev)) - for (i = 0; - i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size); - i++) { - if (rio_route_get_entry - (rdev->net->hport, rdev->rswitch, RIO_GLOBAL_TABLE, - i, &sport) < 0) - continue; - rdev->rswitch->route_table[i] = sport; + if (rio_is_switch(rdev)) { + rio_lock_device(rdev->net->hport, rdev->rswitch->destid, + rdev->rswitch->hopcount, 1000); + for (i = 0; + i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size); + i++) { + if (rio_route_get_entry + (rdev->net->hport, rdev->rswitch, + RIO_GLOBAL_TABLE, i, &sport, 0) < 0) + continue; + rdev->rswitch->route_table[i] = sport; + } + + rio_unlock_device(rdev->net->hport, + rdev->rswitch->destid, + rdev->rswitch->hopcount); } } @@ -1030,6 +1147,13 @@ int __devinit rio_disc_mport(struct rio_mport *mport) del_timer_sync(&rio_enum_timer); pr_debug("done\n"); + + /* Read DestID assigned by enumerator */ + rio_local_read_config_32(mport, RIO_DID_CSR, + &mport->host_deviceid); + mport->host_deviceid = RIO_GET_DID(mport->sys_size, + mport->host_deviceid); + if (rio_disc_peer(net, mport, RIO_ANY_DESTID(mport->sys_size), 0) < 0) { printk(KERN_INFO -- cgit v1.2.3 From e5cabeb3d60f9cd3e3950aff071319ae0e2d08d8 Mon Sep 17 00:00:00 2001 From: Alexandre Bounine Date: Wed, 26 May 2010 14:43:59 -0700 Subject: rapidio: add Port-Write handling for EM Add RapidIO Port-Write message handling in the context of Error Management Extensions Specification Rev.1.3. Signed-off-by: Alexandre Bounine Tested-by: Thomas Moll Cc: Matt Porter Cc: Li Yang Cc: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/sysdev/fsl_rio.c | 2 +- drivers/rapidio/rio-scan.c | 166 ++++++++++++++----- drivers/rapidio/rio.c | 328 ++++++++++++++++++++++++++++++++++++++ drivers/rapidio/rio.h | 30 ++++ drivers/rapidio/switches/tsi568.c | 24 +++ drivers/rapidio/switches/tsi57x.c | 153 ++++++++++++++++++ include/asm-generic/vmlinux.lds.h | 5 +- include/linux/rio.h | 42 +++++ include/linux/rio_drv.h | 6 + include/linux/rio_regs.h | 61 ++++++- 10 files changed, 776 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 6a1fde0d22b0..cb0d74927f04 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -1057,7 +1057,7 @@ int fsl_rio_setup(struct of_device *dev) dev_info(&dev->dev, "LAW start 0x%016llx, size 0x%016llx.\n", law_start, law_size); - ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL); + ops = kzalloc(sizeof(struct rio_ops), GFP_KERNEL); if (!ops) { rc = -ENOMEM; goto err_ops; diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index cbf0d5f4fba8..74633cc6b2eb 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c @@ -4,6 +4,10 @@ * Copyright 2005 MontaVista Software, Inc. * Matt Porter * + * Copyright 2009 Integrated Device Technology, Inc. + * Alex Bounine + * - Added Port-Write/Error Management initialization and handling + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your @@ -31,15 +35,16 @@ LIST_HEAD(rio_devices); static LIST_HEAD(rio_switches); -#define RIO_ENUM_CMPL_MAGIC 0xdeadbeef - static void rio_enum_timeout(unsigned long); +static void rio_init_em(struct rio_dev *rdev); + DEFINE_SPINLOCK(rio_global_list_lock); static int next_destid = 0; static int next_switchid = 0; static int next_net = 0; +static int next_comptag; static struct timer_list rio_enum_timer = TIMER_INITIALIZER(rio_enum_timeout, 0, 0); @@ -52,13 +57,6 @@ static int rio_mport_phys_table[] = { -1, }; -static int rio_sport_phys_table[] = { - RIO_EFB_PAR_EP_FREE_ID, - RIO_EFB_SER_EP_FREE_ID, - RIO_EFB_SER_EP_FREC_ID, - -1, -}; - /** * rio_get_device_id - Get the base/extended device id for a device * @port: RIO master port @@ -119,12 +117,26 @@ static int rio_clear_locks(struct rio_mport *port) u32 result; int ret = 0; - /* Write component tag CSR magic complete value */ - rio_local_write_config_32(port, RIO_COMPONENT_TAG_CSR, - RIO_ENUM_CMPL_MAGIC); - list_for_each_entry(rdev, &rio_devices, global_list) - rio_write_config_32(rdev, RIO_COMPONENT_TAG_CSR, - RIO_ENUM_CMPL_MAGIC); + /* Assign component tag to all devices */ + next_comptag = 1; + rio_local_write_config_32(port, RIO_COMPONENT_TAG_CSR, next_comptag++); + + list_for_each_entry(rdev, &rio_devices, global_list) { + /* Mark device as discovered */ + rio_read_config_32(rdev, + rdev->phys_efptr + RIO_PORT_GEN_CTL_CSR, + &result); + rio_write_config_32(rdev, + rdev->phys_efptr + RIO_PORT_GEN_CTL_CSR, + result | RIO_PORT_GEN_DISCOVERED); + + rio_write_config_32(rdev, RIO_COMPONENT_TAG_CSR, next_comptag); + rdev->comp_tag = next_comptag++; + if (next_comptag >= 0x10000) { + pr_err("RIO: Component Tag Counter Overflow\n"); + break; + } + } /* Release host device id locks */ rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR, @@ -266,6 +278,30 @@ static void rio_route_set_ops(struct rio_dev *rdev) rio_name(rdev)); } +/** + * rio_em_set_ops- Sets Error Managment operations for a particular vendor switch + * @rdev: RIO device + * + * Searches the RIO EM ops table for known switch types. If the vid + * and did match a switch table entry, then set the em_init() and + * em_handle() ops to the table entry values. + */ +static void rio_em_set_ops(struct rio_dev *rdev) +{ + struct rio_em_ops *cur = __start_rio_em_ops; + struct rio_em_ops *end = __end_rio_em_ops; + + while (cur < end) { + if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) { + pr_debug("RIO: adding EM ops for %s\n", rio_name(rdev)); + rdev->rswitch->em_init = cur->init_hook; + rdev->rswitch->em_handle = cur->handler_hook; + break; + } + cur++; + } +} + /** * rio_add_device- Adds a RIO device to the device model * @rdev: RIO device @@ -336,8 +372,14 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, rdev->asm_rev = result >> 16; rio_mport_read_config_32(port, destid, hopcount, RIO_PEF_CAR, &rdev->pef); - if (rdev->pef & RIO_PEF_EXT_FEATURES) + if (rdev->pef & RIO_PEF_EXT_FEATURES) { rdev->efptr = result & 0xffff; + rdev->phys_efptr = rio_mport_get_physefb(port, 0, destid, + hopcount); + + rdev->em_efptr = rio_mport_get_feature(port, 0, destid, + hopcount, RIO_EFB_ERR_MGMNT); + } rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR, &rdev->src_ops); @@ -366,6 +408,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, rswitch->switchid = next_switchid; rswitch->hopcount = hopcount; rswitch->destid = destid; + rswitch->port_ok = 0; rswitch->route_table = kzalloc(sizeof(u8)* RIO_MAX_ROUTE_ENTRIES(port->sys_size), GFP_KERNEL); @@ -379,6 +422,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, dev_set_name(&rdev->dev, "%02x:s:%04x", rdev->net->id, rdev->rswitch->switchid); rio_route_set_ops(rdev); + rio_em_set_ops(rdev); if (do_enum && rdev->rswitch->clr_table) rdev->rswitch->clr_table(port, destid, hopcount, @@ -429,23 +473,29 @@ cleanup: * * Reads the port error status CSR for a particular switch port to * determine if the port has an active link. Returns - * %PORT_N_ERR_STS_PORT_OK if the port is active or %0 if it is + * %RIO_PORT_N_ERR_STS_PORT_OK if the port is active or %0 if it is * inactive. */ static int rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport) { - u32 result; + u32 result = 0; u32 ext_ftr_ptr; - int *entry = rio_sport_phys_table; - - do { - if ((ext_ftr_ptr = - rio_mport_get_feature(port, 0, destid, hopcount, *entry))) + ext_ftr_ptr = rio_mport_get_efb(port, 0, destid, hopcount, 0); + while (ext_ftr_ptr) { + rio_mport_read_config_32(port, destid, hopcount, + ext_ftr_ptr, &result); + result = RIO_GET_BLOCK_ID(result); + if ((result == RIO_EFB_SER_EP_FREE_ID) || + (result == RIO_EFB_SER_EP_FREE_ID_V13P) || + (result == RIO_EFB_SER_EP_FREC_ID)) break; - } while (*++entry >= 0); + + ext_ftr_ptr = rio_mport_get_efb(port, 0, destid, hopcount, + ext_ftr_ptr); + } if (ext_ftr_ptr) rio_mport_read_config_32(port, destid, hopcount, @@ -453,7 +503,7 @@ rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport) RIO_PORT_N_ERR_STS_CSR(sport), &result); - return (result & PORT_N_ERR_STS_PORT_OK); + return result & RIO_PORT_N_ERR_STS_PORT_OK; } /** @@ -762,8 +812,10 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, rio_name(rdev), rdev->vid, rdev->did, num_ports); sw_destid = next_destid; for (port_num = 0; port_num < num_ports; port_num++) { - if (sw_inport == port_num) + if (sw_inport == port_num) { + rdev->rswitch->port_ok |= (1 << port_num); continue; + } cur_destid = next_destid; @@ -773,6 +825,7 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, pr_debug( "RIO: scanning device on port %d\n", port_num); + rdev->rswitch->port_ok |= (1 << port_num); rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE, RIO_ANY_DESTID(port->sys_size), @@ -797,9 +850,28 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, port_num; } } + } else { + /* If switch supports Error Management, + * set PORT_LOCKOUT bit for unused port + */ + if (rdev->em_efptr) + rio_set_port_lockout(rdev, port_num, 1); + + rdev->rswitch->port_ok &= ~(1 << port_num); } } + /* Direct Port-write messages to the enumeratiing host */ + if ((rdev->src_ops & RIO_SRC_OPS_PORT_WRITE) && + (rdev->em_efptr)) { + rio_write_config_32(rdev, + rdev->em_efptr + RIO_EM_PW_TGT_DEVID, + (port->host_deviceid << 16) | + (port->sys_size << 15)); + } + + rio_init_em(rdev); + /* Check for empty switch */ if (next_destid == sw_destid) { next_destid++; @@ -819,21 +891,16 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, * rio_enum_complete- Tests if enumeration of a network is complete * @port: Master port to send transaction * - * Tests the Component Tag CSR for presence of the magic enumeration - * complete flag. Return %1 if enumeration is complete or %0 if + * Tests the Component Tag CSR for non-zero value (enumeration + * complete flag). Return %1 if enumeration is complete or %0 if * enumeration is incomplete. */ static int rio_enum_complete(struct rio_mport *port) { u32 tag_csr; - int ret = 0; rio_local_read_config_32(port, RIO_COMPONENT_TAG_CSR, &tag_csr); - - if (tag_csr == RIO_ENUM_CMPL_MAGIC) - ret = 1; - - return ret; + return (tag_csr & 0xffff) ? 1 : 0; } /** @@ -915,7 +982,7 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid, * * Reads the port error status CSR for the master port to * determine if the port has an active link. Returns - * %PORT_N_ERR_STS_PORT_OK if the master port is active + * %RIO_PORT_N_ERR_STS_PORT_OK if the master port is active * or %0 if it is inactive. */ static int rio_mport_is_active(struct rio_mport *port) @@ -936,7 +1003,7 @@ static int rio_mport_is_active(struct rio_mport *port) RIO_PORT_N_ERR_STS_CSR(port->index), &result); - return (result & PORT_N_ERR_STS_PORT_OK); + return result & RIO_PORT_N_ERR_STS_PORT_OK; } /** @@ -1007,6 +1074,32 @@ static void rio_update_route_tables(struct rio_mport *port) } } +/** + * rio_init_em - Initializes RIO Error Management (for switches) + * @port: Master port associated with the RIO network + * + * For each enumerated switch, call device-specific error management + * initialization routine (if supplied by the switch driver). + */ +static void rio_init_em(struct rio_dev *rdev) +{ + if (rio_is_switch(rdev) && (rdev->em_efptr) && + (rdev->rswitch->em_init)) { + rdev->rswitch->em_init(rdev); + } +} + +/** + * rio_pw_enable - Enables/disables port-write handling by a master port + * @port: Master port associated with port-write handling + * @enable: 1=enable, 0=disable + */ +static void rio_pw_enable(struct rio_mport *port, int enable) +{ + if (port->ops->pwenable) + port->ops->pwenable(port, enable); +} + /** * rio_enum_mport- Start enumeration through a master port * @mport: Master port to send transactions @@ -1050,6 +1143,7 @@ int __devinit rio_enum_mport(struct rio_mport *mport) } rio_update_route_tables(mport); rio_clear_locks(mport); + rio_pw_enable(mport, 1); } else { printk(KERN_INFO "RIO: master port %d link inactive\n", mport->id); diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index 67a379216959..8fa732e46bf6 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c @@ -5,6 +5,10 @@ * Copyright 2005 MontaVista Software, Inc. * Matt Porter * + * Copyright 2009 Integrated Device Technology, Inc. + * Alex Bounine + * - Added Port-Write/Error Management initialization and handling + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your @@ -332,6 +336,329 @@ int rio_release_outb_dbell(struct rio_dev *rdev, struct resource *res) return rc; } +/** + * rio_request_inb_pwrite - request inbound port-write message service + * @mport: RIO device to which register inbound port-write callback routine + * @pwcback: Callback routine to execute when port-write is received + * + * Binds a port-write callback function to the RapidIO device. + * Returns 0 if the request has been satisfied. + */ +int rio_request_inb_pwrite(struct rio_dev *rdev, + int (*pwcback)(struct rio_dev *rdev, union rio_pw_msg *msg, int step)) +{ + int rc = 0; + + spin_lock(&rio_global_list_lock); + if (rdev->pwcback != NULL) + rc = -ENOMEM; + else + rdev->pwcback = pwcback; + + spin_unlock(&rio_global_list_lock); + return rc; +} +EXPORT_SYMBOL_GPL(rio_request_inb_pwrite); + +/** + * rio_release_inb_pwrite - release inbound port-write message service + * @rdev: RIO device which registered for inbound port-write callback + * + * Removes callback from the rio_dev structure. Returns 0 if the request + * has been satisfied. + */ +int rio_release_inb_pwrite(struct rio_dev *rdev) +{ + int rc = -ENOMEM; + + spin_lock(&rio_global_list_lock); + if (rdev->pwcback) { + rdev->pwcback = NULL; + rc = 0; + } + + spin_unlock(&rio_global_list_lock); + return rc; +} +EXPORT_SYMBOL_GPL(rio_release_inb_pwrite); + +/** + * rio_mport_get_physefb - Helper function that returns register offset + * for Physical Layer Extended Features Block. + * @rdev: RIO device + */ +u32 +rio_mport_get_physefb(struct rio_mport *port, int local, + u16 destid, u8 hopcount) +{ + u32 ext_ftr_ptr; + u32 ftr_header; + + ext_ftr_ptr = rio_mport_get_efb(port, local, destid, hopcount, 0); + + while (ext_ftr_ptr) { + if (local) + rio_local_read_config_32(port, ext_ftr_ptr, + &ftr_header); + else + rio_mport_read_config_32(port, destid, hopcount, + ext_ftr_ptr, &ftr_header); + + ftr_header = RIO_GET_BLOCK_ID(ftr_header); + switch (ftr_header) { + + case RIO_EFB_SER_EP_ID_V13P: + case RIO_EFB_SER_EP_REC_ID_V13P: + case RIO_EFB_SER_EP_FREE_ID_V13P: + case RIO_EFB_SER_EP_ID: + case RIO_EFB_SER_EP_REC_ID: + case RIO_EFB_SER_EP_FREE_ID: + case RIO_EFB_SER_EP_FREC_ID: + + return ext_ftr_ptr; + + default: + break; + } + + ext_ftr_ptr = rio_mport_get_efb(port, local, destid, + hopcount, ext_ftr_ptr); + } + + return ext_ftr_ptr; +} + +/** + * rio_get_comptag - Begin or continue searching for a RIO device by component tag + * @comp_tag: RIO component tad to match + * @from: Previous RIO device found in search, or %NULL for new search + * + * Iterates through the list of known RIO devices. If a RIO device is + * found with a matching @comp_tag, a pointer to its device + * structure is returned. Otherwise, %NULL is returned. A new search + * is initiated by passing %NULL to the @from argument. Otherwise, if + * @from is not %NULL, searches continue from next device on the global + * list. + */ +static struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from) +{ + struct list_head *n; + struct rio_dev *rdev; + + WARN_ON(in_interrupt()); + spin_lock(&rio_global_list_lock); + n = from ? from->global_list.next : rio_devices.next; + + while (n && (n != &rio_devices)) { + rdev = rio_dev_g(n); + if (rdev->comp_tag == comp_tag) + goto exit; + n = n->next; + } + rdev = NULL; +exit: + spin_unlock(&rio_global_list_lock); + return rdev; +} + +/** + * rio_set_port_lockout - Sets/clears LOCKOUT bit (RIO EM 1.3) for a switch port. + * @rdev: Pointer to RIO device control structure + * @pnum: Switch port number to set LOCKOUT bit + * @lock: Operation : set (=1) or clear (=0) + */ +int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock) +{ + u8 hopcount = 0xff; + u16 destid = rdev->destid; + u32 regval; + + if (rdev->rswitch) { + destid = rdev->rswitch->destid; + hopcount = rdev->rswitch->hopcount; + } + + rio_mport_read_config_32(rdev->net->hport, destid, hopcount, + rdev->phys_efptr + RIO_PORT_N_CTL_CSR(pnum), + ®val); + if (lock) + regval |= RIO_PORT_N_CTL_LOCKOUT; + else + regval &= ~RIO_PORT_N_CTL_LOCKOUT; + + rio_mport_write_config_32(rdev->net->hport, destid, hopcount, + rdev->phys_efptr + RIO_PORT_N_CTL_CSR(pnum), + regval); + return 0; +} + +/** + * rio_inb_pwrite_handler - process inbound port-write message + * @pw_msg: pointer to inbound port-write message + * + * Processes an inbound port-write message. Returns 0 if the request + * has been satisfied. + */ +int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg) +{ + struct rio_dev *rdev; + struct rio_mport *mport; + u8 hopcount; + u16 destid; + u32 err_status; + int rc, portnum; + + rdev = rio_get_comptag(pw_msg->em.comptag, NULL); + if (rdev == NULL) { + /* Someting bad here (probably enumeration error) */ + pr_err("RIO: %s No matching device for CTag 0x%08x\n", + __func__, pw_msg->em.comptag); + return -EIO; + } + + pr_debug("RIO: Port-Write message from %s\n", rio_name(rdev)); + +#ifdef DEBUG_PW + { + u32 i; + for (i = 0; i < RIO_PW_MSG_SIZE/sizeof(u32);) { + pr_debug("0x%02x: %08x %08x %08x %08x", + i*4, pw_msg->raw[i], pw_msg->raw[i + 1], + pw_msg->raw[i + 2], pw_msg->raw[i + 3]); + i += 4; + } + pr_debug("\n"); + } +#endif + + /* Call an external service function (if such is registered + * for this device). This may be the service for endpoints that send + * device-specific port-write messages. End-point messages expected + * to be handled completely by EP specific device driver. + * For switches rc==0 signals that no standard processing required. + */ + if (rdev->pwcback != NULL) { + rc = rdev->pwcback(rdev, pw_msg, 0); + if (rc == 0) + return 0; + } + + /* For End-point devices processing stops here */ + if (!(rdev->pef & RIO_PEF_SWITCH)) + return 0; + + if (rdev->phys_efptr == 0) { + pr_err("RIO_PW: Bad switch initialization for %s\n", + rio_name(rdev)); + return 0; + } + + mport = rdev->net->hport; + destid = rdev->rswitch->destid; + hopcount = rdev->rswitch->hopcount; + + /* + * Process the port-write notification from switch + */ + + portnum = pw_msg->em.is_port & 0xFF; + + if (rdev->rswitch->em_handle) + rdev->rswitch->em_handle(rdev, portnum); + + rio_mport_read_config_32(mport, destid, hopcount, + rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum), + &err_status); + pr_debug("RIO_PW: SP%d_ERR_STS_CSR=0x%08x\n", portnum, err_status); + + if (pw_msg->em.errdetect) { + pr_debug("RIO_PW: RIO_EM_P%d_ERR_DETECT=0x%08x\n", + portnum, pw_msg->em.errdetect); + /* Clear EM Port N Error Detect CSR */ + rio_mport_write_config_32(mport, destid, hopcount, + rdev->em_efptr + RIO_EM_PN_ERR_DETECT(portnum), 0); + } + + if (pw_msg->em.ltlerrdet) { + pr_debug("RIO_PW: RIO_EM_LTL_ERR_DETECT=0x%08x\n", + pw_msg->em.ltlerrdet); + /* Clear EM L/T Layer Error Detect CSR */ + rio_mport_write_config_32(mport, destid, hopcount, + rdev->em_efptr + RIO_EM_LTL_ERR_DETECT, 0); + } + + /* Clear Port Errors */ + rio_mport_write_config_32(mport, destid, hopcount, + rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum), + err_status & RIO_PORT_N_ERR_STS_CLR_MASK); + + if (rdev->rswitch->port_ok & (1 << portnum)) { + if (err_status & RIO_PORT_N_ERR_STS_PORT_UNINIT) { + rdev->rswitch->port_ok &= ~(1 << portnum); + rio_set_port_lockout(rdev, portnum, 1); + + rio_mport_write_config_32(mport, destid, hopcount, + rdev->phys_efptr + + RIO_PORT_N_ACK_STS_CSR(portnum), + RIO_PORT_N_ACK_CLEAR); + + /* Schedule Extraction Service */ + pr_debug("RIO_PW: Device Extraction on [%s]-P%d\n", + rio_name(rdev), portnum); + } + } else { + if (err_status & RIO_PORT_N_ERR_STS_PORT_OK) { + rdev->rswitch->port_ok |= (1 << portnum); + rio_set_port_lockout(rdev, portnum, 0); + + /* Schedule Insertion Service */ + pr_debug("RIO_PW: Device Insertion on [%s]-P%d\n", + rio_name(rdev), portnum); + } + } + + /* Clear Port-Write Pending bit */ + rio_mport_write_config_32(mport, destid, hopcount, + rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum), + RIO_PORT_N_ERR_STS_PW_PEND); + + return 0; +} +EXPORT_SYMBOL_GPL(rio_inb_pwrite_handler); + +/** + * rio_mport_get_efb - get pointer to next extended features block + * @port: Master port to issue transaction + * @local: Indicate a local master port or remote device access + * @destid: Destination ID of the device + * @hopcount: Number of switch hops to the device + * @from: Offset of current Extended Feature block header (if 0 starts + * from ExtFeaturePtr) + */ +u32 +rio_mport_get_efb(struct rio_mport *port, int local, u16 destid, + u8 hopcount, u32 from) +{ + u32 reg_val; + + if (from == 0) { + if (local) + rio_local_read_config_32(port, RIO_ASM_INFO_CAR, + ®_val); + else + rio_mport_read_config_32(port, destid, hopcount, + RIO_ASM_INFO_CAR, ®_val); + return reg_val & RIO_EXT_FTR_PTR_MASK; + } else { + if (local) + rio_local_read_config_32(port, from, ®_val); + else + rio_mport_read_config_32(port, destid, hopcount, + from, ®_val); + return RIO_GET_BLOCK_ID(reg_val); + } +} + /** * rio_mport_get_feature - query for devices' extended features * @port: Master port to issue transaction @@ -472,6 +799,7 @@ int rio_std_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, RIO_STD_RTE_CONF_PORT_SEL_CSR, (u32)route_port); } + udelay(10); return 0; } diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h index b53c5ec276a5..2f628ce1a1c1 100644 --- a/drivers/rapidio/rio.h +++ b/drivers/rapidio/rio.h @@ -18,6 +18,10 @@ extern u32 rio_mport_get_feature(struct rio_mport *mport, int local, u16 destid, u8 hopcount, int ftr); +extern u32 rio_mport_get_physefb(struct rio_mport *port, int local, + u16 destid, u8 hopcount); +extern u32 rio_mport_get_efb(struct rio_mport *port, int local, u16 destid, + u8 hopcount, u32 from); extern int rio_create_sysfs_dev_files(struct rio_dev *rdev); extern int rio_enum_mport(struct rio_mport *mport); extern int rio_disc_mport(struct rio_mport *mport); @@ -29,6 +33,7 @@ extern int rio_std_route_get_entry(struct rio_mport *mport, u16 destid, u8 *route_port); extern int rio_std_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table); +extern int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock); /* Structures internal to the RIO core code */ extern struct device_attribute rio_dev_attrs[]; @@ -61,3 +66,28 @@ extern struct rio_route_ops __end_rio_route_ops[]; #define RIO_GET_DID(size, x) (size ? (x & 0xffff) : ((x & 0x00ff0000) >> 16)) #define RIO_SET_DID(size, x) (size ? (x & 0xffff) : ((x & 0x000000ff) << 16)) + +/* + * RapidIO Error Management + */ +extern struct rio_em_ops __start_rio_em_ops[]; +extern struct rio_em_ops __end_rio_em_ops[]; + +/* Helpers internal to the RIO core code */ +#define DECLARE_RIO_EM_SECTION(section, name, vid, did, init_hook, em_hook) \ + static const struct rio_em_ops __rio_em_##name __used \ + __section(section) = { vid, did, init_hook, em_hook }; + +/** + * DECLARE_RIO_EM_OPS - Registers switch EM operations + * @vid: RIO vendor ID + * @did: RIO device ID + * @init_hook: Callback that initializes device specific EM + * @em_hook: Callback that handles device specific EM + * + * A &struct rio_em_ops is initialized with the ops and placed into a + * RIO-specific kernel section. + */ +#define DECLARE_RIO_EM_OPS(vid, did, init_hook, em_hook) \ + DECLARE_RIO_EM_SECTION(.rio_em_ops, vid##did, \ + vid, did, init_hook, em_hook) diff --git a/drivers/rapidio/switches/tsi568.c b/drivers/rapidio/switches/tsi568.c index bce9112ff0d9..905cf9cb09cc 100644 --- a/drivers/rapidio/switches/tsi568.c +++ b/drivers/rapidio/switches/tsi568.c @@ -25,6 +25,9 @@ #define SPP_ROUTE_CFG_DESTID(n) (0x11070 + 0x100*n) #define SPP_ROUTE_CFG_PORT(n) (0x11074 + 0x100*n) +#define TSI568_SP_MODE_BC 0x10004 +#define TSI568_SP_MODE_PW_DIS 0x08000000 + static int tsi568_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 route_port) @@ -104,3 +107,24 @@ tsi568_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, } DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI568, tsi568_route_add_entry, tsi568_route_get_entry, tsi568_route_clr_table); + +static int +tsi568_em_init(struct rio_dev *rdev) +{ + struct rio_mport *mport = rdev->net->hport; + u16 destid = rdev->rswitch->destid; + u8 hopcount = rdev->rswitch->hopcount; + u32 regval; + + pr_debug("TSI568 %s [%d:%d]\n", __func__, destid, hopcount); + + /* Make sure that Port-Writes are disabled (for all ports) */ + rio_mport_read_config_32(mport, destid, hopcount, + TSI568_SP_MODE_BC, ®val); + rio_mport_write_config_32(mport, destid, hopcount, + TSI568_SP_MODE_BC, regval | TSI568_SP_MODE_PW_DIS); + + return 0; +} + +DECLARE_RIO_EM_OPS(RIO_VID_TUNDRA, RIO_DID_TSI568, tsi568_em_init, NULL); diff --git a/drivers/rapidio/switches/tsi57x.c b/drivers/rapidio/switches/tsi57x.c index 5ad7880787c9..23040b92ea76 100644 --- a/drivers/rapidio/switches/tsi57x.c +++ b/drivers/rapidio/switches/tsi57x.c @@ -25,6 +25,14 @@ #define SPP_ROUTE_CFG_DESTID(n) (0x11070 + 0x100*n) #define SPP_ROUTE_CFG_PORT(n) (0x11074 + 0x100*n) +#define TSI578_SP_MODE(n) (0x11004 + n*0x100) +#define TSI578_SP_MODE_PW_DIS 0x08000000 + +#define TSI578_SP_CTL_INDEP(n) (0x13004 + n*0x100) +#define TSI578_SP_LUT_PEINF(n) (0x13010 + n*0x100) +#define TSI578_SP_CS_TX(n) (0x13014 + n*0x100) +#define TSI578_SP_INT_STATUS(n) (0x13018 + n*0x100) + static int tsi57x_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 route_port) @@ -104,3 +112,148 @@ DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI572, tsi57x_route_add_entry, ts DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI574, tsi57x_route_add_entry, tsi57x_route_get_entry, tsi57x_route_clr_table); DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI577, tsi57x_route_add_entry, tsi57x_route_get_entry, tsi57x_route_clr_table); DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI578, tsi57x_route_add_entry, tsi57x_route_get_entry, tsi57x_route_clr_table); + +static int +tsi57x_em_init(struct rio_dev *rdev) +{ + struct rio_mport *mport = rdev->net->hport; + u16 destid = rdev->rswitch->destid; + u8 hopcount = rdev->rswitch->hopcount; + u32 regval; + int portnum; + + pr_debug("TSI578 %s [%d:%d]\n", __func__, destid, hopcount); + + for (portnum = 0; portnum < 16; portnum++) { + /* Make sure that Port-Writes are enabled (for all ports) */ + rio_mport_read_config_32(mport, destid, hopcount, + TSI578_SP_MODE(portnum), ®val); + rio_mport_write_config_32(mport, destid, hopcount, + TSI578_SP_MODE(portnum), + regval & ~TSI578_SP_MODE_PW_DIS); + + /* Clear all pending interrupts */ + rio_mport_read_config_32(mport, destid, hopcount, + rdev->phys_efptr + + RIO_PORT_N_ERR_STS_CSR(portnum), + ®val); + rio_mport_write_config_32(mport, destid, hopcount, + rdev->phys_efptr + + RIO_PORT_N_ERR_STS_CSR(portnum), + regval & 0x07120214); + + rio_mport_read_config_32(mport, destid, hopcount, + TSI578_SP_INT_STATUS(portnum), ®val); + rio_mport_write_config_32(mport, destid, hopcount, + TSI578_SP_INT_STATUS(portnum), + regval & 0x000700bd); + + /* Enable all interrupts to allow ports to send a port-write */ + rio_mport_read_config_32(mport, destid, hopcount, + TSI578_SP_CTL_INDEP(portnum), ®val); + rio_mport_write_config_32(mport, destid, hopcount, + TSI578_SP_CTL_INDEP(portnum), + regval | 0x000b0000); + + /* Skip next (odd) port if the current port is in x4 mode */ + rio_mport_read_config_32(mport, destid, hopcount, + rdev->phys_efptr + RIO_PORT_N_CTL_CSR(portnum), + ®val); + if ((regval & RIO_PORT_N_CTL_PWIDTH) == RIO_PORT_N_CTL_PWIDTH_4) + portnum++; + } + + return 0; +} + +static int +tsi57x_em_handler(struct rio_dev *rdev, u8 portnum) +{ + struct rio_mport *mport = rdev->net->hport; + u16 destid = rdev->rswitch->destid; + u8 hopcount = rdev->rswitch->hopcount; + u32 intstat, err_status; + int sendcount, checkcount; + u8 route_port; + u32 regval; + + rio_mport_read_config_32(mport, destid, hopcount, + rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum), + &err_status); + + if ((err_status & RIO_PORT_N_ERR_STS_PORT_OK) && + (err_status & (RIO_PORT_N_ERR_STS_PW_OUT_ES | + RIO_PORT_N_ERR_STS_PW_INP_ES))) { + /* Remove any queued packets by locking/unlocking port */ + rio_mport_read_config_32(mport, destid, hopcount, + rdev->phys_efptr + RIO_PORT_N_CTL_CSR(portnum), + ®val); + if (!(regval & RIO_PORT_N_CTL_LOCKOUT)) { + rio_mport_write_config_32(mport, destid, hopcount, + rdev->phys_efptr + RIO_PORT_N_CTL_CSR(portnum), + regval | RIO_PORT_N_CTL_LOCKOUT); + udelay(50); + rio_mport_write_config_32(mport, destid, hopcount, + rdev->phys_efptr + RIO_PORT_N_CTL_CSR(portnum), + regval); + } + + /* Read from link maintenance response register to clear + * valid bit + */ + rio_mport_read_config_32(mport, destid, hopcount, + rdev->phys_efptr + RIO_PORT_N_MNT_RSP_CSR(portnum), + ®val); + + /* Send a Packet-Not-Accepted/Link-Request-Input-Status control + * symbol to recover from IES/OES + */ + sendcount = 3; + while (sendcount) { + rio_mport_write_config_32(mport, destid, hopcount, + TSI578_SP_CS_TX(portnum), 0x40fc8000); + checkcount = 3; + while (checkcount--) { + udelay(50); + rio_mport_read_config_32( + mport, destid, hopcount, + rdev->phys_efptr + + RIO_PORT_N_MNT_RSP_CSR(portnum), + ®val); + if (regval & RIO_PORT_N_MNT_RSP_RVAL) + goto exit_es; + } + + sendcount--; + } + } + +exit_es: + /* Clear implementation specific error status bits */ + rio_mport_read_config_32(mport, destid, hopcount, + TSI578_SP_INT_STATUS(portnum), &intstat); + pr_debug("TSI578[%x:%x] SP%d_INT_STATUS=0x%08x\n", + destid, hopcount, portnum, intstat); + + if (intstat & 0x10000) { + rio_mport_read_config_32(mport, destid, hopcount, + TSI578_SP_LUT_PEINF(portnum), ®val); + regval = (mport->sys_size) ? (regval >> 16) : (regval >> 24); + route_port = rdev->rswitch->route_table[regval]; + pr_debug("RIO: TSI578[%s] P%d LUT Parity Error (destID=%d)\n", + rio_name(rdev), portnum, regval); + tsi57x_route_add_entry(mport, destid, hopcount, + RIO_GLOBAL_TABLE, regval, route_port); + } + + rio_mport_write_config_32(mport, destid, hopcount, + TSI578_SP_INT_STATUS(portnum), + intstat & 0x000700bd); + + return 0; +} + +DECLARE_RIO_EM_OPS(RIO_VID_TUNDRA, RIO_DID_TSI572, tsi57x_em_init, tsi57x_em_handler); +DECLARE_RIO_EM_OPS(RIO_VID_TUNDRA, RIO_DID_TSI574, tsi57x_em_init, tsi57x_em_handler); +DECLARE_RIO_EM_OPS(RIO_VID_TUNDRA, RIO_DID_TSI577, tsi57x_em_init, tsi57x_em_handler); +DECLARE_RIO_EM_OPS(RIO_VID_TUNDRA, RIO_DID_TSI578, tsi57x_em_init, tsi57x_em_handler); diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 67e652068e0e..8f7c89b20639 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -247,10 +247,13 @@ } \ \ /* RapidIO route ops */ \ - .rio_route : AT(ADDR(.rio_route) - LOAD_OFFSET) { \ + .rio_ops : AT(ADDR(.rio_ops) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start_rio_route_ops) = .; \ *(.rio_route_ops) \ VMLINUX_SYMBOL(__end_rio_route_ops) = .; \ + VMLINUX_SYMBOL(__start_rio_em_ops) = .; \ + *(.rio_em_ops) \ + VMLINUX_SYMBOL(__end_rio_em_ops) = .; \ } \ \ TRACEDATA \ diff --git a/include/linux/rio.h b/include/linux/rio.h index 29d98997c6c8..4ec31f44f406 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h @@ -64,10 +64,13 @@ #define RIO_INB_MBOX_RESOURCE 1 #define RIO_OUTB_MBOX_RESOURCE 2 +#define RIO_PW_MSG_SIZE 64 + extern struct bus_type rio_bus_type; extern struct list_head rio_devices; /* list of all devices */ struct rio_mport; +union rio_pw_msg; /** * struct rio_dev - RIO device info @@ -107,11 +110,15 @@ struct rio_dev { u32 swpinfo; /* Only used for switches */ u32 src_ops; u32 dst_ops; + u32 comp_tag; + u32 phys_efptr; + u32 em_efptr; u64 dma_mask; struct rio_switch *rswitch; /* RIO switch info */ struct rio_driver *driver; /* RIO driver claiming this device */ struct device dev; /* LDM device structure */ struct resource riores[RIO_MAX_DEV_RESOURCES]; + int (*pwcback) (struct rio_dev *rdev, union rio_pw_msg *msg, int step); u16 destid; }; @@ -211,9 +218,12 @@ struct rio_net { * @hopcount: Hopcount to this switch * @destid: Associated destid in the path * @route_table: Copy of switch routing table + * @port_ok: Status of each port (one bit per port) - OK=1 or UNINIT=0 * @add_entry: Callback for switch-specific route add function * @get_entry: Callback for switch-specific route get function * @clr_table: Callback for switch-specific clear route table function + * @em_init: Callback for switch-specific error management initialization function + * @em_handle: Callback for switch-specific error management handler function */ struct rio_switch { struct list_head node; @@ -221,12 +231,15 @@ struct rio_switch { u16 hopcount; u16 destid; u8 *route_table; + u32 port_ok; int (*add_entry) (struct rio_mport * mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 route_port); int (*get_entry) (struct rio_mport * mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 * route_port); int (*clr_table) (struct rio_mport *mport, u16 destid, u8 hopcount, u16 table); + int (*em_init) (struct rio_dev *dev); + int (*em_handle) (struct rio_dev *dev, u8 swport); }; /* Low-level architecture-dependent routines */ @@ -238,6 +251,7 @@ struct rio_switch { * @cread: Callback to perform network read of config space. * @cwrite: Callback to perform network write of config space. * @dsend: Callback to send a doorbell message. + * @pwenable: Callback to enable/disable port-write message handling. */ struct rio_ops { int (*lcread) (struct rio_mport *mport, int index, u32 offset, int len, @@ -249,6 +263,7 @@ struct rio_ops { int (*cwrite) (struct rio_mport *mport, int index, u16 destid, u8 hopcount, u32 offset, int len, u32 data); int (*dsend) (struct rio_mport *mport, int index, u16 destid, u16 data); + int (*pwenable) (struct rio_mport *mport, int enable); }; #define RIO_RESOURCE_MEM 0x00000100 @@ -325,6 +340,33 @@ struct rio_route_ops { u16 table); }; +/** + * struct rio_em_ops - Per-switch error management operations + * @vid: RIO vendor ID + * @did: RIO device ID + * @init_hook: Switch specific error management initialization (may be NULL) + * @handler_hook: Switch specific error management handler (may be NULL) + * + * Defines the operations that are necessary to initialize and handle + * error management events for a particular RIO switch device. + */ +struct rio_em_ops { + u16 vid, did; + int (*init_hook) (struct rio_dev *dev); + int (*handler_hook) (struct rio_dev *dev, u8 swport); +}; + +union rio_pw_msg { + struct { + u32 comptag; /* Component Tag CSR */ + u32 errdetect; /* Port N Error Detect CSR */ + u32 is_port; /* Implementation specific + PortID */ + u32 ltlerrdet; /* LTL Error Detect CSR */ + u32 padding[12]; + } em; + u32 raw[RIO_PW_MSG_SIZE/sizeof(u32)]; +}; + /* Architecture and hardware-specific functions */ extern int rio_init_mports(void); extern void rio_register_mport(struct rio_mport *); diff --git a/include/linux/rio_drv.h b/include/linux/rio_drv.h index c93a58a40033..edc55da717b3 100644 --- a/include/linux/rio_drv.h +++ b/include/linux/rio_drv.h @@ -413,6 +413,12 @@ void rio_release_regions(struct rio_dev *); int rio_request_region(struct rio_dev *, int, char *); void rio_release_region(struct rio_dev *, int); +/* Port-Write management */ +extern int rio_request_inb_pwrite(struct rio_dev *, + int (*)(struct rio_dev *, union rio_pw_msg*, int)); +extern int rio_release_inb_pwrite(struct rio_dev *); +extern int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg); + /* LDM support */ int rio_register_driver(struct rio_driver *); void rio_unregister_driver(struct rio_driver *); diff --git a/include/linux/rio_regs.h b/include/linux/rio_regs.h index 4bfb0dcfac7c..96ba2159d9fe 100644 --- a/include/linux/rio_regs.h +++ b/include/linux/rio_regs.h @@ -192,10 +192,14 @@ #define RIO_EFB_PAR_EP_ID 0x0001 /* [IV] LP/LVDS EP Devices */ #define RIO_EFB_PAR_EP_REC_ID 0x0002 /* [IV] LP/LVDS EP Recovery Devices */ #define RIO_EFB_PAR_EP_FREE_ID 0x0003 /* [IV] LP/LVDS EP Free Devices */ +#define RIO_EFB_SER_EP_ID_V13P 0x0001 /* [VI] LP/Serial EP Devices, RapidIO Spec ver 1.3 and above */ +#define RIO_EFB_SER_EP_REC_ID_V13P 0x0002 /* [VI] LP/Serial EP Recovery Devices, RapidIO Spec ver 1.3 and above */ +#define RIO_EFB_SER_EP_FREE_ID_V13P 0x0003 /* [VI] LP/Serial EP Free Devices, RapidIO Spec ver 1.3 and above */ #define RIO_EFB_SER_EP_ID 0x0004 /* [VI] LP/Serial EP Devices */ #define RIO_EFB_SER_EP_REC_ID 0x0005 /* [VI] LP/Serial EP Recovery Devices */ #define RIO_EFB_SER_EP_FREE_ID 0x0006 /* [VI] LP/Serial EP Free Devices */ #define RIO_EFB_SER_EP_FREC_ID 0x0009 /* [VI] LP/Serial EP Free Recovery Devices */ +#define RIO_EFB_ERR_MGMNT 0x0007 /* [VIII] Error Management Extensions */ /* * Physical 8/16 LP-LVDS @@ -211,15 +215,66 @@ #define RIO_PORT_MNT_HEADER 0x0000 #define RIO_PORT_REQ_CTL_CSR 0x0020 #define RIO_PORT_RSP_CTL_CSR 0x0024 /* 0x0001/0x0002 */ +#define RIO_PORT_LINKTO_CTL_CSR 0x0020 /* Serial */ +#define RIO_PORT_RSPTO_CTL_CSR 0x0024 /* Serial */ #define RIO_PORT_GEN_CTL_CSR 0x003c #define RIO_PORT_GEN_HOST 0x80000000 #define RIO_PORT_GEN_MASTER 0x40000000 #define RIO_PORT_GEN_DISCOVERED 0x20000000 #define RIO_PORT_N_MNT_REQ_CSR(x) (0x0040 + x*0x20) /* 0x0002 */ #define RIO_PORT_N_MNT_RSP_CSR(x) (0x0044 + x*0x20) /* 0x0002 */ +#define RIO_PORT_N_MNT_RSP_RVAL 0x80000000 /* Response Valid */ +#define RIO_PORT_N_MNT_RSP_ASTAT 0x000003e0 /* ackID Status */ +#define RIO_PORT_N_MNT_RSP_LSTAT 0x0000001f /* Link Status */ #define RIO_PORT_N_ACK_STS_CSR(x) (0x0048 + x*0x20) /* 0x0002 */ -#define RIO_PORT_N_ERR_STS_CSR(x) (0x58 + x*0x20) -#define PORT_N_ERR_STS_PORT_OK 0x00000002 -#define RIO_PORT_N_CTL_CSR(x) (0x5c + x*0x20) +#define RIO_PORT_N_ACK_CLEAR 0x80000000 +#define RIO_PORT_N_ACK_INBOUND 0x1f000000 +#define RIO_PORT_N_ACK_OUTSTAND 0x00001f00 +#define RIO_PORT_N_ACK_OUTBOUND 0x0000001f +#define RIO_PORT_N_ERR_STS_CSR(x) (0x0058 + x*0x20) +#define RIO_PORT_N_ERR_STS_PW_OUT_ES 0x00010000 /* Output Error-stopped */ +#define RIO_PORT_N_ERR_STS_PW_INP_ES 0x00000100 /* Input Error-stopped */ +#define RIO_PORT_N_ERR_STS_PW_PEND 0x00000010 /* Port-Write Pending */ +#define RIO_PORT_N_ERR_STS_PORT_ERR 0x00000004 +#define RIO_PORT_N_ERR_STS_PORT_OK 0x00000002 +#define RIO_PORT_N_ERR_STS_PORT_UNINIT 0x00000001 +#define RIO_PORT_N_ERR_STS_CLR_MASK 0x07120204 +#define RIO_PORT_N_CTL_CSR(x) (0x005c + x*0x20) +#define RIO_PORT_N_CTL_PWIDTH 0xc0000000 +#define RIO_PORT_N_CTL_PWIDTH_1 0x00000000 +#define RIO_PORT_N_CTL_PWIDTH_4 0x40000000 +#define RIO_PORT_N_CTL_LOCKOUT 0x00000002 + +/* + * Error Management Extensions (RapidIO 1.3+, Part 8) + * + * Extended Features Block ID=0x0007 + */ + +/* General EM Registers (Common for all Ports) */ + +#define RIO_EM_EFB_HEADER 0x000 /* Error Management Extensions Block Header */ +#define RIO_EM_LTL_ERR_DETECT 0x008 /* Logical/Transport Layer Error Detect CSR */ +#define RIO_EM_LTL_ERR_EN 0x00c /* Logical/Transport Layer Error Enable CSR */ +#define RIO_EM_LTL_HIADDR_CAP 0x010 /* Logical/Transport Layer High Address Capture CSR */ +#define RIO_EM_LTL_ADDR_CAP 0x014 /* Logical/Transport Layer Address Capture CSR */ +#define RIO_EM_LTL_DEVID_CAP 0x018 /* Logical/Transport Layer Device ID Capture CSR */ +#define RIO_EM_LTL_CTRL_CAP 0x01c /* Logical/Transport Layer Control Capture CSR */ +#define RIO_EM_PW_TGT_DEVID 0x028 /* Port-write Target deviceID CSR */ +#define RIO_EM_PKT_TTL 0x02c /* Packet Time-to-live CSR */ + +/* Per-Port EM Registers */ + +#define RIO_EM_PN_ERR_DETECT(x) (0x040 + x*0x40) /* Port N Error Detect CSR */ +#define REM_PED_IMPL_SPEC 0x80000000 +#define REM_PED_LINK_TO 0x00000001 +#define RIO_EM_PN_ERRRATE_EN(x) (0x044 + x*0x40) /* Port N Error Rate Enable CSR */ +#define RIO_EM_PN_ATTRIB_CAP(x) (0x048 + x*0x40) /* Port N Attributes Capture CSR */ +#define RIO_EM_PN_PKT_CAP_0(x) (0x04c + x*0x40) /* Port N Packet/Control Symbol Capture 0 CSR */ +#define RIO_EM_PN_PKT_CAP_1(x) (0x050 + x*0x40) /* Port N Packet Capture 1 CSR */ +#define RIO_EM_PN_PKT_CAP_2(x) (0x054 + x*0x40) /* Port N Packet Capture 2 CSR */ +#define RIO_EM_PN_PKT_CAP_3(x) (0x058 + x*0x40) /* Port N Packet Capture 3 CSR */ +#define RIO_EM_PN_ERRRATE(x) (0x068 + x*0x40) /* Port N Error Rate CSR */ +#define RIO_EM_PN_ERRRATE_TR(x) (0x06c + x*0x40) /* Port N Error Rate Threshold CSR */ #endif /* LINUX_RIO_REGS_H */ -- cgit v1.2.3 From 933af4a6c4913ab4c0691c8fb27fc305063889cd Mon Sep 17 00:00:00 2001 From: Thomas Moll Date: Wed, 26 May 2010 14:44:01 -0700 Subject: rapidio: add enabling SRIO port RX and TX Add the functionality to enable Input receiver and Output transmitter of every port, to allow non-maintenance traffic. Signed-off-by: Thomas Moll Signed-off-by: Alexandre Bounine Cc: Matt Porter Cc: Li Yang Cc: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rapidio/Kconfig | 11 +++++++ drivers/rapidio/rio-scan.c | 79 +++++++++++++++++++++++++++++++++++++++++++++- include/linux/rio_regs.h | 5 +++ 3 files changed, 94 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig index 606cb172c1e5..bcb5c2063370 100644 --- a/drivers/rapidio/Kconfig +++ b/drivers/rapidio/Kconfig @@ -9,4 +9,15 @@ config RAPIDIO_DISC_TIMEOUT Amount of time a discovery node waits for a host to complete enumeration before giving up. +config RAPIDIO_ENABLE_RX_TX_PORTS + bool "Enable RapidIO Input/Output Ports" + depends on RAPIDIO + ---help--- + The RapidIO specification describes a Output port transmit + enable and a Input port receive enable. The recommended state + for Input ports and Output ports should be disabled. When + this switch is set the RapidIO subsystem will enable all + ports for Input/Output direction to allow other traffic + than Maintenance transfers. + source "drivers/rapidio/switches/Kconfig" diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index 74633cc6b2eb..1faa1a5756e2 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c @@ -8,6 +8,10 @@ * Alex Bounine * - Added Port-Write/Error Management initialization and handling * + * Copyright 2009 Sysgo AG + * Thomas Moll + * - Added Input- Output- enable functionality, to allow full communication + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your @@ -327,6 +331,65 @@ static int __devinit rio_add_device(struct rio_dev *rdev) return 0; } +/** + * rio_enable_rx_tx_port - enable input reciever and output transmitter of + * given port + * @port: Master port associated with the RIO network + * @local: local=1 select local port otherwise a far device is reached + * @destid: Destination ID of the device to check host bit + * @hopcount: Number of hops to reach the target + * @port_num: Port (-number on switch) to enable on a far end device + * + * Returns 0 or 1 from on General Control Command and Status Register + * (EXT_PTR+0x3C) + */ +inline int rio_enable_rx_tx_port(struct rio_mport *port, + int local, u16 destid, + u8 hopcount, u8 port_num) { +#ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS + u32 regval; + u32 ext_ftr_ptr; + + /* + * enable rx input tx output port + */ + pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = " + "%d, port_num = %d)\n", local, destid, hopcount, port_num); + + ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount); + + if (local) { + rio_local_read_config_32(port, ext_ftr_ptr + + RIO_PORT_N_CTL_CSR(0), + ®val); + } else { + if (rio_mport_read_config_32(port, destid, hopcount, + ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), ®val) < 0) + return -EIO; + } + + if (regval & RIO_PORT_N_CTL_P_TYP_SER) { + /* serial */ + regval = regval | RIO_PORT_N_CTL_EN_RX_SER + | RIO_PORT_N_CTL_EN_TX_SER; + } else { + /* parallel */ + regval = regval | RIO_PORT_N_CTL_EN_RX_PAR + | RIO_PORT_N_CTL_EN_TX_PAR; + } + + if (local) { + rio_local_write_config_32(port, ext_ftr_ptr + + RIO_PORT_N_CTL_CSR(0), regval); + } else { + if (rio_mport_write_config_32(port, destid, hopcount, + ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0) + return -EIO; + } +#endif + return 0; +} + /** * rio_setup_device- Allocates and sets up a RIO device * @net: RIO network @@ -430,9 +493,14 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, list_add_tail(&rswitch->node, &rio_switches); - } else + } else { + if (do_enum) + /*Enable Input Output Port (transmitter reviever)*/ + rio_enable_rx_tx_port(port, 0, destid, hopcount, 0); + dev_set_name(&rdev->dev, "%02x:e:%04x", rdev->net->id, rdev->destid); + } rdev->dev.bus = &rio_bus_type; @@ -812,6 +880,11 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, rio_name(rdev), rdev->vid, rdev->did, num_ports); sw_destid = next_destid; for (port_num = 0; port_num < num_ports; port_num++) { + /*Enable Input Output Port (transmitter reviever)*/ + rio_enable_rx_tx_port(port, 0, + RIO_ANY_DESTID(port->sys_size), + hopcount, port_num); + if (sw_inport == port_num) { rdev->rswitch->port_ok |= (1 << port_num); continue; @@ -1132,6 +1205,10 @@ int __devinit rio_enum_mport(struct rio_mport *mport) rc = -ENOMEM; goto out; } + + /* Enable Input Output Port (transmitter reviever) */ + rio_enable_rx_tx_port(mport, 1, 0, 0, 0); + if (rio_enum_peer(net, mport, 0) < 0) { /* A higher priority host won enumeration, bail. */ printk(KERN_INFO diff --git a/include/linux/rio_regs.h b/include/linux/rio_regs.h index 96ba2159d9fe..aedee0489fb4 100644 --- a/include/linux/rio_regs.h +++ b/include/linux/rio_regs.h @@ -243,7 +243,12 @@ #define RIO_PORT_N_CTL_PWIDTH 0xc0000000 #define RIO_PORT_N_CTL_PWIDTH_1 0x00000000 #define RIO_PORT_N_CTL_PWIDTH_4 0x40000000 +#define RIO_PORT_N_CTL_P_TYP_SER 0x00000001 #define RIO_PORT_N_CTL_LOCKOUT 0x00000002 +#define RIO_PORT_N_CTL_EN_RX_SER 0x00200000 +#define RIO_PORT_N_CTL_EN_TX_SER 0x00400000 +#define RIO_PORT_N_CTL_EN_RX_PAR 0x08000000 +#define RIO_PORT_N_CTL_EN_TX_PAR 0x40000000 /* * Error Management Extensions (RapidIO 1.3+, Part 8) -- cgit v1.2.3 From 68b04cd38af42dbe4ee28e189633c3c50beb8873 Mon Sep 17 00:00:00 2001 From: Alexandre Bounine Date: Wed, 26 May 2010 14:44:02 -0700 Subject: rapidio: fix typos and minor edits Signed-off-by: Alexandre Bounine Cc: Matt Porter Cc: Li Yang Cc: Kumar Gala Cc: Thomas Moll Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rapidio/rio.c | 1 - drivers/rapidio/switches/Kconfig | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index 8fa732e46bf6..777e099a3d8f 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c @@ -445,7 +445,6 @@ static struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from) struct list_head *n; struct rio_dev *rdev; - WARN_ON(in_interrupt()); spin_lock(&rio_global_list_lock); n = from ? from->global_list.next : rio_devices.next; diff --git a/drivers/rapidio/switches/Kconfig b/drivers/rapidio/switches/Kconfig index 6969f398bc26..2b4e9b2b6631 100644 --- a/drivers/rapidio/switches/Kconfig +++ b/drivers/rapidio/switches/Kconfig @@ -5,24 +5,24 @@ config RAPIDIO_TSI57X bool "IDT Tsi57x SRIO switches support" depends on RAPIDIO ---help--- - Includes support for ITD Tsi57x family of serial RapidIO switches. + Includes support for IDT Tsi57x family of serial RapidIO switches. config RAPIDIO_CPS_XX bool "IDT CPS-xx SRIO switches support" depends on RAPIDIO ---help--- - Includes support for ITD CPS-16/12/10/8 serial RapidIO switches. + Includes support for IDT CPS-16/12/10/8 serial RapidIO switches. config RAPIDIO_TSI568 bool "Tsi568 SRIO switch support" depends on RAPIDIO default n ---help--- - Includes support for ITD Tsi568 serial RapidIO switch. + Includes support for IDT Tsi568 serial RapidIO switch. config RAPIDIO_TSI500 bool "Tsi500 Parallel RapidIO switch support" depends on RAPIDIO default n ---help--- - Includes support for ITD Tsi500 parallel RapidIO switch. + Includes support for IDT Tsi500 parallel RapidIO switch. -- cgit v1.2.3 From 011507e49a696462c30914e2eeebcdda33ed30f8 Mon Sep 17 00:00:00 2001 From: Alexandre Bounine Date: Wed, 26 May 2010 14:44:03 -0700 Subject: rapidio: add debug configuration option Add debug configuration option for RapidIO subsystem. Signed-off-by: Alexandre Bounine Cc: Matt Porter Cc: Li Yang Cc: Kumar Gala Cc: Thomas Moll Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rapidio/Kconfig | 11 +++++++++++ drivers/rapidio/Makefile | 4 ++++ drivers/rapidio/switches/Makefile | 4 ++++ 3 files changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig index bcb5c2063370..070211a5955c 100644 --- a/drivers/rapidio/Kconfig +++ b/drivers/rapidio/Kconfig @@ -21,3 +21,14 @@ config RAPIDIO_ENABLE_RX_TX_PORTS than Maintenance transfers. source "drivers/rapidio/switches/Kconfig" + +config RAPIDIO_DEBUG + bool "RapidIO subsystem debug messages" + depends on RAPIDIO + help + Say Y here if you want the RapidIO subsystem to produce a bunch of + debug messages to the system log. Select this if you are having a + problem with the RapidIO subsystem and want to see more of what is + going on. + + If you are unsure about this, say N here. diff --git a/drivers/rapidio/Makefile b/drivers/rapidio/Makefile index 7c0e1818de51..b6139fe187bf 100644 --- a/drivers/rapidio/Makefile +++ b/drivers/rapidio/Makefile @@ -4,3 +4,7 @@ obj-y += rio.o rio-access.o rio-driver.o rio-scan.o rio-sysfs.o obj-$(CONFIG_RAPIDIO) += switches/ + +ifeq ($(CONFIG_RAPIDIO_DEBUG),y) +EXTRA_CFLAGS += -DDEBUG +endif diff --git a/drivers/rapidio/switches/Makefile b/drivers/rapidio/switches/Makefile index 0fece0e6aa89..fe4adc3e8d5f 100644 --- a/drivers/rapidio/switches/Makefile +++ b/drivers/rapidio/switches/Makefile @@ -6,3 +6,7 @@ obj-$(CONFIG_RAPIDIO_TSI57X) += tsi57x.o obj-$(CONFIG_RAPIDIO_CPS_XX) += idtcps.o obj-$(CONFIG_RAPIDIO_TSI568) += tsi568.o obj-$(CONFIG_RAPIDIO_TSI500) += tsi500.o + +ifeq ($(CONFIG_RAPIDIO_DEBUG),y) +EXTRA_CFLAGS += -DDEBUG +endif -- cgit v1.2.3 From 058f88d672b3161fe511ebe2996c3faef63c1c8e Mon Sep 17 00:00:00 2001 From: Alexandre Bounine Date: Wed, 26 May 2010 14:44:03 -0700 Subject: rapidio: modify initialization of switch operations Modify the way how RapidIO switch operations are declared. Multiple assignments through the linker script replaced by single initialization call. Signed-off-by: Alexandre Bounine Cc: Matt Porter Cc: Li Yang Cc: Kumar Gala Cc: Thomas Moll Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rapidio/rio-scan.c | 49 +++++++++------------------------- drivers/rapidio/rio.h | 56 +++++++++++---------------------------- drivers/rapidio/switches/idtcps.c | 27 ++++++++++++++----- drivers/rapidio/switches/tsi500.c | 18 ++++++++++++- drivers/rapidio/switches/tsi568.c | 20 +++++++++++--- drivers/rapidio/switches/tsi57x.c | 31 +++++++++++++++------- include/asm-generic/vmlinux.lds.h | 9 +++---- include/linux/rio.h | 35 +++++------------------- 8 files changed, 111 insertions(+), 134 deletions(-) (limited to 'drivers') diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index 1faa1a5756e2..566432106cc5 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c @@ -246,24 +246,24 @@ static int rio_is_switch(struct rio_dev *rdev) } /** - * rio_route_set_ops- Sets routing operations for a particular vendor switch + * rio_switch_init - Sets switch operations for a particular vendor switch * @rdev: RIO device + * @do_enum: Enumeration/Discovery mode flag * - * Searches the RIO route ops table for known switch types. If the vid - * and did match a switch table entry, then set the add_entry() and - * get_entry() ops to the table entry values. + * Searches the RIO switch ops table for known switch types. If the vid + * and did match a switch table entry, then call switch initialization + * routine to setup switch-specific routines. */ -static void rio_route_set_ops(struct rio_dev *rdev) +static void rio_switch_init(struct rio_dev *rdev, int do_enum) { - struct rio_route_ops *cur = __start_rio_route_ops; - struct rio_route_ops *end = __end_rio_route_ops; + struct rio_switch_ops *cur = __start_rio_switch_ops; + struct rio_switch_ops *end = __end_rio_switch_ops; while (cur < end) { if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) { - pr_debug("RIO: adding routing ops for %s\n", rio_name(rdev)); - rdev->rswitch->add_entry = cur->add_hook; - rdev->rswitch->get_entry = cur->get_hook; - rdev->rswitch->clr_table = cur->clr_hook; + pr_debug("RIO: calling init routine for %s\n", + rio_name(rdev)); + cur->init_hook(rdev, do_enum); break; } cur++; @@ -282,30 +282,6 @@ static void rio_route_set_ops(struct rio_dev *rdev) rio_name(rdev)); } -/** - * rio_em_set_ops- Sets Error Managment operations for a particular vendor switch - * @rdev: RIO device - * - * Searches the RIO EM ops table for known switch types. If the vid - * and did match a switch table entry, then set the em_init() and - * em_handle() ops to the table entry values. - */ -static void rio_em_set_ops(struct rio_dev *rdev) -{ - struct rio_em_ops *cur = __start_rio_em_ops; - struct rio_em_ops *end = __end_rio_em_ops; - - while (cur < end) { - if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) { - pr_debug("RIO: adding EM ops for %s\n", rio_name(rdev)); - rdev->rswitch->em_init = cur->init_hook; - rdev->rswitch->em_handle = cur->handler_hook; - break; - } - cur++; - } -} - /** * rio_add_device- Adds a RIO device to the device model * @rdev: RIO device @@ -484,8 +460,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, rdev->rswitch = rswitch; dev_set_name(&rdev->dev, "%02x:s:%04x", rdev->net->id, rdev->rswitch->switchid); - rio_route_set_ops(rdev); - rio_em_set_ops(rdev); + rio_switch_init(rdev, do_enum); if (do_enum && rdev->rswitch->clr_table) rdev->rswitch->clr_table(port, destid, hopcount, diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h index 2f628ce1a1c1..f27b7a9c47d2 100644 --- a/drivers/rapidio/rio.h +++ b/drivers/rapidio/rio.h @@ -39,55 +39,29 @@ extern int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock); extern struct device_attribute rio_dev_attrs[]; extern spinlock_t rio_global_list_lock; -extern struct rio_route_ops __start_rio_route_ops[]; -extern struct rio_route_ops __end_rio_route_ops[]; +extern struct rio_switch_ops __start_rio_switch_ops[]; +extern struct rio_switch_ops __end_rio_switch_ops[]; /* Helpers internal to the RIO core code */ -#define DECLARE_RIO_ROUTE_SECTION(section, name, vid, did, add_hook, get_hook, clr_hook) \ - static const struct rio_route_ops __rio_route_##name __used \ - __section(section) = { vid, did, add_hook, get_hook, clr_hook }; +#define DECLARE_RIO_SWITCH_SECTION(section, name, vid, did, init_hook) \ + static const struct rio_switch_ops __rio_switch_##name __used \ + __section(section) = { vid, did, init_hook }; /** - * DECLARE_RIO_ROUTE_OPS - Registers switch routing operations + * DECLARE_RIO_SWITCH_INIT - Registers switch initialization routine * @vid: RIO vendor ID * @did: RIO device ID - * @add_hook: Callback that adds a route entry - * @get_hook: Callback that gets a route entry + * @init_hook: Callback that performs switch-specific initialization * - * Manipulating switch route tables in RIO is switch specific. This - * registers a switch by vendor and device ID with two callbacks for - * modifying and retrieving route entries in a switch. A &struct - * rio_route_ops is initialized with the ops and placed into a - * RIO-specific kernel section. + * Manipulating switch route tables and error management in RIO + * is switch specific. This registers a switch by vendor and device ID with + * initialization callback for setting up switch operations and (if required) + * hardware initialization. A &struct rio_switch_ops is initialized with + * pointer to the init routine and placed into a RIO-specific kernel section. */ -#define DECLARE_RIO_ROUTE_OPS(vid, did, add_hook, get_hook, clr_hook) \ - DECLARE_RIO_ROUTE_SECTION(.rio_route_ops, vid##did, \ - vid, did, add_hook, get_hook, clr_hook) +#define DECLARE_RIO_SWITCH_INIT(vid, did, init_hook) \ + DECLARE_RIO_SWITCH_SECTION(.rio_switch_ops, vid##did, \ + vid, did, init_hook) #define RIO_GET_DID(size, x) (size ? (x & 0xffff) : ((x & 0x00ff0000) >> 16)) #define RIO_SET_DID(size, x) (size ? (x & 0xffff) : ((x & 0x000000ff) << 16)) - -/* - * RapidIO Error Management - */ -extern struct rio_em_ops __start_rio_em_ops[]; -extern struct rio_em_ops __end_rio_em_ops[]; - -/* Helpers internal to the RIO core code */ -#define DECLARE_RIO_EM_SECTION(section, name, vid, did, init_hook, em_hook) \ - static const struct rio_em_ops __rio_em_##name __used \ - __section(section) = { vid, did, init_hook, em_hook }; - -/** - * DECLARE_RIO_EM_OPS - Registers switch EM operations - * @vid: RIO vendor ID - * @did: RIO device ID - * @init_hook: Callback that initializes device specific EM - * @em_hook: Callback that handles device specific EM - * - * A &struct rio_em_ops is initialized with the ops and placed into a - * RIO-specific kernel section. - */ -#define DECLARE_RIO_EM_OPS(vid, did, init_hook, em_hook) \ - DECLARE_RIO_EM_SECTION(.rio_em_ops, vid##did, \ - vid, did, init_hook, em_hook) diff --git a/drivers/rapidio/switches/idtcps.c b/drivers/rapidio/switches/idtcps.c index 7e3d03283dec..46e6630dacd3 100644 --- a/drivers/rapidio/switches/idtcps.c +++ b/drivers/rapidio/switches/idtcps.c @@ -1,7 +1,8 @@ /* * IDT CPS RapidIO switches support * - * Copyright 2009 Integrated Device Technology, Inc. + * Copyright 2009-2010 Integrated Device Technology, Inc. + * Alexandre Bounine * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -81,9 +82,21 @@ idtcps_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, return 0; } -DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS6Q, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table); -DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS8, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table); -DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS10Q, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table); -DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS12, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table); -DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS16, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table); -DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDT70K200, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table); +static int idtcps_switch_init(struct rio_dev *rdev, int do_enum) +{ + pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); + rdev->rswitch->add_entry = idtcps_route_add_entry; + rdev->rswitch->get_entry = idtcps_route_get_entry; + rdev->rswitch->clr_table = idtcps_route_clr_table; + rdev->rswitch->em_init = NULL; + rdev->rswitch->em_handle = NULL; + + return 0; +} + +DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS6Q, idtcps_switch_init); +DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS8, idtcps_switch_init); +DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS10Q, idtcps_switch_init); +DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS12, idtcps_switch_init); +DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS16, idtcps_switch_init); +DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDT70K200, idtcps_switch_init); diff --git a/drivers/rapidio/switches/tsi500.c b/drivers/rapidio/switches/tsi500.c index ae553bb41089..65b865d64d34 100644 --- a/drivers/rapidio/switches/tsi500.c +++ b/drivers/rapidio/switches/tsi500.c @@ -1,6 +1,10 @@ /* * RapidIO Tsi500 switch support * + * Copyright 2009-2010 Integrated Device Technology, Inc. + * Alexandre Bounine + * - Modified switch operations initialization. + * * Copyright 2005 MontaVista Software, Inc. * Matt Porter * @@ -57,4 +61,16 @@ tsi500_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 tab return ret; } -DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI500, tsi500_route_add_entry, tsi500_route_get_entry, NULL); +static int tsi500_switch_init(struct rio_dev *rdev, int do_enum) +{ + pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); + rdev->rswitch->add_entry = tsi500_route_add_entry; + rdev->rswitch->get_entry = tsi500_route_get_entry; + rdev->rswitch->clr_table = NULL; + rdev->rswitch->em_init = NULL; + rdev->rswitch->em_handle = NULL; + + return 0; +} + +DECLARE_RIO_SWITCH_INIT(RIO_VID_TUNDRA, RIO_DID_TSI500, tsi500_switch_init); diff --git a/drivers/rapidio/switches/tsi568.c b/drivers/rapidio/switches/tsi568.c index 905cf9cb09cc..322840d43832 100644 --- a/drivers/rapidio/switches/tsi568.c +++ b/drivers/rapidio/switches/tsi568.c @@ -2,6 +2,10 @@ * RapidIO Tsi568 switch support * * Copyright 2009-2010 Integrated Device Technology, Inc. + * Alexandre Bounine + * - Added EM support + * - Modified switch operations initialization. + * * Copyright 2005 MontaVista Software, Inc. * Matt Porter * @@ -106,8 +110,6 @@ tsi568_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, return 0; } -DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI568, tsi568_route_add_entry, tsi568_route_get_entry, tsi568_route_clr_table); - static int tsi568_em_init(struct rio_dev *rdev) { @@ -127,4 +129,16 @@ tsi568_em_init(struct rio_dev *rdev) return 0; } -DECLARE_RIO_EM_OPS(RIO_VID_TUNDRA, RIO_DID_TSI568, tsi568_em_init, NULL); +static int tsi568_switch_init(struct rio_dev *rdev, int do_enum) +{ + pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); + rdev->rswitch->add_entry = tsi568_route_add_entry; + rdev->rswitch->get_entry = tsi568_route_get_entry; + rdev->rswitch->clr_table = tsi568_route_clr_table; + rdev->rswitch->em_init = tsi568_em_init; + rdev->rswitch->em_handle = NULL; + + return 0; +} + +DECLARE_RIO_SWITCH_INIT(RIO_VID_TUNDRA, RIO_DID_TSI568, tsi568_switch_init); diff --git a/drivers/rapidio/switches/tsi57x.c b/drivers/rapidio/switches/tsi57x.c index 23040b92ea76..2e902d3e1abe 100644 --- a/drivers/rapidio/switches/tsi57x.c +++ b/drivers/rapidio/switches/tsi57x.c @@ -1,7 +1,11 @@ /* * RapidIO Tsi57x switch family support * - * Copyright 2009 Integrated Device Technology, Inc. + * Copyright 2009-2010 Integrated Device Technology, Inc. + * Alexandre Bounine + * - Added EM support + * - Modified switch operations initialization. + * * Copyright 2005 MontaVista Software, Inc. * Matt Porter * @@ -108,11 +112,6 @@ tsi57x_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, return 0; } -DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI572, tsi57x_route_add_entry, tsi57x_route_get_entry, tsi57x_route_clr_table); -DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI574, tsi57x_route_add_entry, tsi57x_route_get_entry, tsi57x_route_clr_table); -DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI577, tsi57x_route_add_entry, tsi57x_route_get_entry, tsi57x_route_clr_table); -DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI578, tsi57x_route_add_entry, tsi57x_route_get_entry, tsi57x_route_clr_table); - static int tsi57x_em_init(struct rio_dev *rdev) { @@ -253,7 +252,19 @@ exit_es: return 0; } -DECLARE_RIO_EM_OPS(RIO_VID_TUNDRA, RIO_DID_TSI572, tsi57x_em_init, tsi57x_em_handler); -DECLARE_RIO_EM_OPS(RIO_VID_TUNDRA, RIO_DID_TSI574, tsi57x_em_init, tsi57x_em_handler); -DECLARE_RIO_EM_OPS(RIO_VID_TUNDRA, RIO_DID_TSI577, tsi57x_em_init, tsi57x_em_handler); -DECLARE_RIO_EM_OPS(RIO_VID_TUNDRA, RIO_DID_TSI578, tsi57x_em_init, tsi57x_em_handler); +static int tsi57x_switch_init(struct rio_dev *rdev, int do_enum) +{ + pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); + rdev->rswitch->add_entry = tsi57x_route_add_entry; + rdev->rswitch->get_entry = tsi57x_route_get_entry; + rdev->rswitch->clr_table = tsi57x_route_clr_table; + rdev->rswitch->em_init = tsi57x_em_init; + rdev->rswitch->em_handle = tsi57x_em_handler; + + return 0; +} + +DECLARE_RIO_SWITCH_INIT(RIO_VID_TUNDRA, RIO_DID_TSI572, tsi57x_switch_init); +DECLARE_RIO_SWITCH_INIT(RIO_VID_TUNDRA, RIO_DID_TSI574, tsi57x_switch_init); +DECLARE_RIO_SWITCH_INIT(RIO_VID_TUNDRA, RIO_DID_TSI577, tsi57x_switch_init); +DECLARE_RIO_SWITCH_INIT(RIO_VID_TUNDRA, RIO_DID_TSI578, tsi57x_switch_init); diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 8f7c89b20639..ef779c6fc3d7 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -248,12 +248,9 @@ \ /* RapidIO route ops */ \ .rio_ops : AT(ADDR(.rio_ops) - LOAD_OFFSET) { \ - VMLINUX_SYMBOL(__start_rio_route_ops) = .; \ - *(.rio_route_ops) \ - VMLINUX_SYMBOL(__end_rio_route_ops) = .; \ - VMLINUX_SYMBOL(__start_rio_em_ops) = .; \ - *(.rio_em_ops) \ - VMLINUX_SYMBOL(__end_rio_em_ops) = .; \ + VMLINUX_SYMBOL(__start_rio_switch_ops) = .; \ + *(.rio_switch_ops) \ + VMLINUX_SYMBOL(__end_rio_switch_ops) = .; \ } \ \ TRACEDATA \ diff --git a/include/linux/rio.h b/include/linux/rio.h index 4ec31f44f406..3d0ac930cbea 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h @@ -320,40 +320,17 @@ struct rio_device_id { }; /** - * struct rio_route_ops - Per-switch route operations + * struct rio_switch_ops - Per-switch operations * @vid: RIO vendor ID * @did: RIO device ID - * @add_hook: Callback that adds a route entry - * @get_hook: Callback that gets a route entry - * @clr_hook: Callback that clears a switch route table (may be NULL) + * @init_hook: Callback that performs switch device initialization * - * Defines the operations that are necessary to manipulate the route - * tables for a particular RIO switch device. + * Defines the operations that are necessary to initialize/control + * a particular RIO switch device. */ -struct rio_route_ops { +struct rio_switch_ops { u16 vid, did; - int (*add_hook) (struct rio_mport * mport, u16 destid, u8 hopcount, - u16 table, u16 route_destid, u8 route_port); - int (*get_hook) (struct rio_mport * mport, u16 destid, u8 hopcount, - u16 table, u16 route_destid, u8 * route_port); - int (*clr_hook) (struct rio_mport *mport, u16 destid, u8 hopcount, - u16 table); -}; - -/** - * struct rio_em_ops - Per-switch error management operations - * @vid: RIO vendor ID - * @did: RIO device ID - * @init_hook: Switch specific error management initialization (may be NULL) - * @handler_hook: Switch specific error management handler (may be NULL) - * - * Defines the operations that are necessary to initialize and handle - * error management events for a particular RIO switch device. - */ -struct rio_em_ops { - u16 vid, did; - int (*init_hook) (struct rio_dev *dev); - int (*handler_hook) (struct rio_dev *dev, u8 swport); + int (*init_hook) (struct rio_dev *rdev, int do_enum); }; union rio_pw_msg { -- cgit v1.2.3 From 7a88d6286240f1e8a0cf9c07252e1576169020f5 Mon Sep 17 00:00:00 2001 From: Alexandre Bounine Date: Wed, 26 May 2010 14:44:04 -0700 Subject: rapidio: add switch domain routines Add switch specific domain routines required for 16-bit routing support in switches with hierarchical implementation of routing tables. Signed-off-by: Alexandre Bounine Cc: Matt Porter Cc: Li Yang Cc: Kumar Gala Cc: Thomas Moll Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rapidio/switches/idtcps.c | 33 ++++++++++++++++++++++++++++ drivers/rapidio/switches/tsi500.c | 2 ++ drivers/rapidio/switches/tsi568.c | 2 ++ drivers/rapidio/switches/tsi57x.c | 45 +++++++++++++++++++++++++++++++++++++++ include/linux/rio.h | 4 ++++ 5 files changed, 86 insertions(+) (limited to 'drivers') diff --git a/drivers/rapidio/switches/idtcps.c b/drivers/rapidio/switches/idtcps.c index 46e6630dacd3..73c3677e5ac6 100644 --- a/drivers/rapidio/switches/idtcps.c +++ b/drivers/rapidio/switches/idtcps.c @@ -17,6 +17,8 @@ #define CPS_NO_ROUTE 0xdf +#define IDTCPS_RIO_DOMAIN 0xf20020 + static int idtcps_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 route_port) @@ -82,12 +84,43 @@ idtcps_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, return 0; } +static int +idtcps_set_domain(struct rio_mport *mport, u16 destid, u8 hopcount, + u8 sw_domain) +{ + /* + * Switch domain configuration operates only at global level + */ + rio_mport_write_config_32(mport, destid, hopcount, + IDTCPS_RIO_DOMAIN, (u32)sw_domain); + return 0; +} + +static int +idtcps_get_domain(struct rio_mport *mport, u16 destid, u8 hopcount, + u8 *sw_domain) +{ + u32 regval; + + /* + * Switch domain configuration operates only at global level + */ + rio_mport_read_config_32(mport, destid, hopcount, + IDTCPS_RIO_DOMAIN, ®val); + + *sw_domain = (u8)(regval & 0xff); + + return 0; +} + static int idtcps_switch_init(struct rio_dev *rdev, int do_enum) { pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); rdev->rswitch->add_entry = idtcps_route_add_entry; rdev->rswitch->get_entry = idtcps_route_get_entry; rdev->rswitch->clr_table = idtcps_route_clr_table; + rdev->rswitch->set_domain = idtcps_set_domain; + rdev->rswitch->get_domain = idtcps_get_domain; rdev->rswitch->em_init = NULL; rdev->rswitch->em_handle = NULL; diff --git a/drivers/rapidio/switches/tsi500.c b/drivers/rapidio/switches/tsi500.c index 65b865d64d34..914eddd5aa42 100644 --- a/drivers/rapidio/switches/tsi500.c +++ b/drivers/rapidio/switches/tsi500.c @@ -67,6 +67,8 @@ static int tsi500_switch_init(struct rio_dev *rdev, int do_enum) rdev->rswitch->add_entry = tsi500_route_add_entry; rdev->rswitch->get_entry = tsi500_route_get_entry; rdev->rswitch->clr_table = NULL; + rdev->rswitch->set_domain = NULL; + rdev->rswitch->get_domain = NULL; rdev->rswitch->em_init = NULL; rdev->rswitch->em_handle = NULL; diff --git a/drivers/rapidio/switches/tsi568.c b/drivers/rapidio/switches/tsi568.c index 322840d43832..f7fd7898606e 100644 --- a/drivers/rapidio/switches/tsi568.c +++ b/drivers/rapidio/switches/tsi568.c @@ -135,6 +135,8 @@ static int tsi568_switch_init(struct rio_dev *rdev, int do_enum) rdev->rswitch->add_entry = tsi568_route_add_entry; rdev->rswitch->get_entry = tsi568_route_get_entry; rdev->rswitch->clr_table = tsi568_route_clr_table; + rdev->rswitch->set_domain = NULL; + rdev->rswitch->get_domain = NULL; rdev->rswitch->em_init = tsi568_em_init; rdev->rswitch->em_handle = NULL; diff --git a/drivers/rapidio/switches/tsi57x.c b/drivers/rapidio/switches/tsi57x.c index 2e902d3e1abe..d34df722d95f 100644 --- a/drivers/rapidio/switches/tsi57x.c +++ b/drivers/rapidio/switches/tsi57x.c @@ -30,13 +30,17 @@ #define SPP_ROUTE_CFG_PORT(n) (0x11074 + 0x100*n) #define TSI578_SP_MODE(n) (0x11004 + n*0x100) +#define TSI578_SP_MODE_GLBL 0x10004 #define TSI578_SP_MODE_PW_DIS 0x08000000 +#define TSI578_SP_MODE_LUT_512 0x01000000 #define TSI578_SP_CTL_INDEP(n) (0x13004 + n*0x100) #define TSI578_SP_LUT_PEINF(n) (0x13010 + n*0x100) #define TSI578_SP_CS_TX(n) (0x13014 + n*0x100) #define TSI578_SP_INT_STATUS(n) (0x13018 + n*0x100) +#define TSI578_GLBL_ROUTE_BASE 0x10078 + static int tsi57x_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 route_port) @@ -112,6 +116,45 @@ tsi57x_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, return 0; } +static int +tsi57x_set_domain(struct rio_mport *mport, u16 destid, u8 hopcount, + u8 sw_domain) +{ + u32 regval; + + /* + * Switch domain configuration operates only at global level + */ + + /* Turn off flat (LUT_512) mode */ + rio_mport_read_config_32(mport, destid, hopcount, + TSI578_SP_MODE_GLBL, ®val); + rio_mport_write_config_32(mport, destid, hopcount, TSI578_SP_MODE_GLBL, + regval & ~TSI578_SP_MODE_LUT_512); + /* Set switch domain base */ + rio_mport_write_config_32(mport, destid, hopcount, + TSI578_GLBL_ROUTE_BASE, + (u32)(sw_domain << 24)); + return 0; +} + +static int +tsi57x_get_domain(struct rio_mport *mport, u16 destid, u8 hopcount, + u8 *sw_domain) +{ + u32 regval; + + /* + * Switch domain configuration operates only at global level + */ + rio_mport_read_config_32(mport, destid, hopcount, + TSI578_GLBL_ROUTE_BASE, ®val); + + *sw_domain = (u8)(regval >> 24); + + return 0; +} + static int tsi57x_em_init(struct rio_dev *rdev) { @@ -258,6 +301,8 @@ static int tsi57x_switch_init(struct rio_dev *rdev, int do_enum) rdev->rswitch->add_entry = tsi57x_route_add_entry; rdev->rswitch->get_entry = tsi57x_route_get_entry; rdev->rswitch->clr_table = tsi57x_route_clr_table; + rdev->rswitch->set_domain = tsi57x_set_domain; + rdev->rswitch->get_domain = tsi57x_get_domain; rdev->rswitch->em_init = tsi57x_em_init; rdev->rswitch->em_handle = tsi57x_em_handler; diff --git a/include/linux/rio.h b/include/linux/rio.h index 3d0ac930cbea..19b5f227096e 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h @@ -238,6 +238,10 @@ struct rio_switch { u16 table, u16 route_destid, u8 * route_port); int (*clr_table) (struct rio_mport *mport, u16 destid, u8 hopcount, u16 table); + int (*set_domain) (struct rio_mport *mport, u16 destid, u8 hopcount, + u8 sw_domain); + int (*get_domain) (struct rio_mport *mport, u16 destid, u8 hopcount, + u8 *sw_domain); int (*em_init) (struct rio_dev *dev); int (*em_handle) (struct rio_dev *dev, u8 swport); }; -- cgit v1.2.3 From 679395fdaa68de39aaf2ddf7298b504fed9622d3 Mon Sep 17 00:00:00 2001 From: Alexandre Bounine Date: Wed, 26 May 2010 14:44:05 -0700 Subject: rapidio: use default route value for CPS switches Fix to use correct default value for routing table entries. Signed-off-by: Alexandre Bounine Cc: Matt Porter Cc: Li Yang Cc: Kumar Gala Cc: Thomas Moll Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rapidio/switches/idtcps.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/rapidio/switches/idtcps.c b/drivers/rapidio/switches/idtcps.c index 73c3677e5ac6..2c790c144f89 100644 --- a/drivers/rapidio/switches/idtcps.c +++ b/drivers/rapidio/switches/idtcps.c @@ -15,7 +15,8 @@ #include #include "../rio.h" -#define CPS_NO_ROUTE 0xdf +#define CPS_DEFAULT_ROUTE 0xde +#define CPS_NO_ROUTE 0xdf #define IDTCPS_RIO_DOMAIN 0xf20020 @@ -53,10 +54,11 @@ idtcps_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, rio_mport_read_config_32(mport, destid, hopcount, RIO_STD_RTE_CONF_PORT_SEL_CSR, &result); - if (CPS_NO_ROUTE == (u8)result) - result = RIO_INVALID_ROUTE; - - *route_port = (u8)result; + if (CPS_DEFAULT_ROUTE == (u8)result || + CPS_NO_ROUTE == (u8)result) + *route_port = RIO_INVALID_ROUTE; + else + *route_port = (u8)result; } return 0; @@ -74,9 +76,9 @@ idtcps_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, RIO_STD_RTE_CONF_DESTID_SEL_CSR, i); rio_mport_write_config_32(mport, destid, hopcount, RIO_STD_RTE_CONF_PORT_SEL_CSR, - (RIO_INVALID_ROUTE << 24) | - (RIO_INVALID_ROUTE << 16) | - (RIO_INVALID_ROUTE << 8) | RIO_INVALID_ROUTE); + (CPS_DEFAULT_ROUTE << 24) | + (CPS_DEFAULT_ROUTE << 16) | + (CPS_DEFAULT_ROUTE << 8) | CPS_DEFAULT_ROUTE); i += 4; } } -- cgit v1.2.3 From 63ae96be98fa35bc058805b664ab15433efd553b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 26 May 2010 14:44:14 -0700 Subject: drivers/edac: convert logging messages direct uses of __FILE__ to %s, __FILE Reduces text by eliminating multiple __FILE__ uses. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Joe Perches Cc: Doug Thompson Cc: Mauro Carvalho Chehab Cc: Tim Small Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/edac/i5000_edac.c | 20 ++++++++++---------- drivers/edac/i5400_edac.c | 20 ++++++++++---------- drivers/edac/i82443bxgx_edac.c | 22 +++++++++++----------- 3 files changed, 31 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/i5000_edac.c b/drivers/edac/i5000_edac.c index adc10a2ac5f6..996c1bdb5a34 100644 --- a/drivers/edac/i5000_edac.c +++ b/drivers/edac/i5000_edac.c @@ -774,7 +774,7 @@ static void i5000_clear_error(struct mem_ctl_info *mci) static void i5000_check_error(struct mem_ctl_info *mci) { struct i5000_error_info info; - debugf4("MC%d: " __FILE__ ": %s()\n", mci->mc_idx, __func__); + debugf4("MC%d: %s: %s()\n", mci->mc_idx, __FILE__, __func__); i5000_get_error_info(mci, &info); i5000_process_error_info(mci, &info, 1); } @@ -1353,8 +1353,8 @@ static int i5000_probe1(struct pci_dev *pdev, int dev_idx) int num_dimms_per_channel; int num_csrows; - debugf0("MC: " __FILE__ ": %s(), pdev bus %u dev=0x%x fn=0x%x\n", - __func__, + debugf0("MC: %s: %s(), pdev bus %u dev=0x%x fn=0x%x\n", + __FILE__, __func__, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); @@ -1389,7 +1389,7 @@ static int i5000_probe1(struct pci_dev *pdev, int dev_idx) return -ENOMEM; kobject_get(&mci->edac_mci_kobj); - debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); + debugf0("MC: %s: %s(): mci = %p\n", __FILE__, __func__, mci); mci->dev = &pdev->dev; /* record ptr to the generic device */ @@ -1432,8 +1432,8 @@ static int i5000_probe1(struct pci_dev *pdev, int dev_idx) /* add this new MC control structure to EDAC's list of MCs */ if (edac_mc_add_mc(mci)) { - debugf0("MC: " __FILE__ - ": %s(): failed edac_mc_add_mc()\n", __func__); + debugf0("MC: %s: %s(): failed edac_mc_add_mc()\n", + __FILE__, __func__); /* FIXME: perhaps some code should go here that disables error * reporting if we just enabled it */ @@ -1478,7 +1478,7 @@ static int __devinit i5000_init_one(struct pci_dev *pdev, { int rc; - debugf0("MC: " __FILE__ ": %s()\n", __func__); + debugf0("MC: %s: %s()\n", __FILE__, __func__); /* wake up device */ rc = pci_enable_device(pdev); @@ -1497,7 +1497,7 @@ static void __devexit i5000_remove_one(struct pci_dev *pdev) { struct mem_ctl_info *mci; - debugf0(__FILE__ ": %s()\n", __func__); + debugf0("%s: %s()\n", __FILE__, __func__); if (i5000_pci) edac_pci_release_generic_ctl(i5000_pci); @@ -1544,7 +1544,7 @@ static int __init i5000_init(void) { int pci_rc; - debugf2("MC: " __FILE__ ": %s()\n", __func__); + debugf2("MC: %s: %s()\n", __FILE__, __func__); /* Ensure that the OPSTATE is set correctly for POLL or NMI */ opstate_init(); @@ -1560,7 +1560,7 @@ static int __init i5000_init(void) */ static void __exit i5000_exit(void) { - debugf2("MC: " __FILE__ ": %s()\n", __func__); + debugf2("MC: %s: %s()\n", __FILE__, __func__); pci_unregister_driver(&i5000_driver); } diff --git a/drivers/edac/i5400_edac.c b/drivers/edac/i5400_edac.c index f99d10655ed4..010c1d6526f5 100644 --- a/drivers/edac/i5400_edac.c +++ b/drivers/edac/i5400_edac.c @@ -694,7 +694,7 @@ static void i5400_clear_error(struct mem_ctl_info *mci) static void i5400_check_error(struct mem_ctl_info *mci) { struct i5400_error_info info; - debugf4("MC%d: " __FILE__ ": %s()\n", mci->mc_idx, __func__); + debugf4("MC%d: %s: %s()\n", mci->mc_idx, __FILE__, __func__); i5400_get_error_info(mci, &info); i5400_process_error_info(mci, &info); } @@ -1227,8 +1227,8 @@ static int i5400_probe1(struct pci_dev *pdev, int dev_idx) if (dev_idx >= ARRAY_SIZE(i5400_devs)) return -EINVAL; - debugf0("MC: " __FILE__ ": %s(), pdev bus %u dev=0x%x fn=0x%x\n", - __func__, + debugf0("MC: %s: %s(), pdev bus %u dev=0x%x fn=0x%x\n", + __FILE__, __func__, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); @@ -1256,7 +1256,7 @@ static int i5400_probe1(struct pci_dev *pdev, int dev_idx) if (mci == NULL) return -ENOMEM; - debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); + debugf0("MC: %s: %s(): mci = %p\n", __FILE__, __func__, mci); mci->dev = &pdev->dev; /* record ptr to the generic device */ @@ -1299,8 +1299,8 @@ static int i5400_probe1(struct pci_dev *pdev, int dev_idx) /* add this new MC control structure to EDAC's list of MCs */ if (edac_mc_add_mc(mci)) { - debugf0("MC: " __FILE__ - ": %s(): failed edac_mc_add_mc()\n", __func__); + debugf0("MC: %s: %s(): failed edac_mc_add_mc()\n", + __FILE__, __func__); /* FIXME: perhaps some code should go here that disables error * reporting if we just enabled it */ @@ -1344,7 +1344,7 @@ static int __devinit i5400_init_one(struct pci_dev *pdev, { int rc; - debugf0("MC: " __FILE__ ": %s()\n", __func__); + debugf0("MC: %s: %s()\n", __FILE__, __func__); /* wake up device */ rc = pci_enable_device(pdev); @@ -1363,7 +1363,7 @@ static void __devexit i5400_remove_one(struct pci_dev *pdev) { struct mem_ctl_info *mci; - debugf0(__FILE__ ": %s()\n", __func__); + debugf0("%s: %s()\n", __FILE__, __func__); if (i5400_pci) edac_pci_release_generic_ctl(i5400_pci); @@ -1409,7 +1409,7 @@ static int __init i5400_init(void) { int pci_rc; - debugf2("MC: " __FILE__ ": %s()\n", __func__); + debugf2("MC: %s: %s()\n", __FILE__, __func__); /* Ensure that the OPSTATE is set correctly for POLL or NMI */ opstate_init(); @@ -1425,7 +1425,7 @@ static int __init i5400_init(void) */ static void __exit i5400_exit(void) { - debugf2("MC: " __FILE__ ": %s()\n", __func__); + debugf2("MC: %s: %s()\n", __FILE__, __func__); pci_unregister_driver(&i5400_driver); } diff --git a/drivers/edac/i82443bxgx_edac.c b/drivers/edac/i82443bxgx_edac.c index 2bf2c5051bfe..a2fa1feed724 100644 --- a/drivers/edac/i82443bxgx_edac.c +++ b/drivers/edac/i82443bxgx_edac.c @@ -178,7 +178,7 @@ static void i82443bxgx_edacmc_check(struct mem_ctl_info *mci) { struct i82443bxgx_edacmc_error_info info; - debugf1("MC%d: " __FILE__ ": %s()\n", mci->mc_idx, __func__); + debugf1("MC%d: %s: %s()\n", mci->mc_idx, __FILE__, __func__); i82443bxgx_edacmc_get_error_info(mci, &info); i82443bxgx_edacmc_process_error_info(mci, &info, 1); } @@ -198,13 +198,13 @@ static void i82443bxgx_init_csrows(struct mem_ctl_info *mci, for (index = 0; index < mci->nr_csrows; index++) { csrow = &mci->csrows[index]; pci_read_config_byte(pdev, I82443BXGX_DRB + index, &drbar); - debugf1("MC%d: " __FILE__ ": %s() Row=%d DRB = %#0x\n", - mci->mc_idx, __func__, index, drbar); + debugf1("MC%d: %s: %s() Row=%d DRB = %#0x\n", + mci->mc_idx, __FILE__, __func__, index, drbar); row_high_limit = ((u32) drbar << 23); /* find the DRAM Chip Select Base address and mask */ - debugf1("MC%d: " __FILE__ ": %s() Row=%d, " - "Boundry Address=%#0x, Last = %#0x \n", - mci->mc_idx, __func__, index, row_high_limit, + debugf1("MC%d: %s: %s() Row=%d, " + "Boundry Address=%#0x, Last = %#0x\n", + mci->mc_idx, __FILE__, __func__, index, row_high_limit, row_high_limit_last); /* 440GX goes to 2GB, represented with a DRB of 0. */ @@ -237,7 +237,7 @@ static int i82443bxgx_edacmc_probe1(struct pci_dev *pdev, int dev_idx) enum mem_type mtype; enum edac_type edac_mode; - debugf0("MC: " __FILE__ ": %s()\n", __func__); + debugf0("MC: %s: %s()\n", __FILE__, __func__); /* Something is really hosed if PCI config space reads from * the MC aren't working. @@ -250,7 +250,7 @@ static int i82443bxgx_edacmc_probe1(struct pci_dev *pdev, int dev_idx) if (mci == NULL) return -ENOMEM; - debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); + debugf0("MC: %s: %s(): mci = %p\n", __FILE__, __func__, mci); mci->dev = &pdev->dev; mci->mtype_cap = MEM_FLAG_EDO | MEM_FLAG_SDR | MEM_FLAG_RDR; mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED; @@ -336,7 +336,7 @@ static int i82443bxgx_edacmc_probe1(struct pci_dev *pdev, int dev_idx) __func__); } - debugf3("MC: " __FILE__ ": %s(): success\n", __func__); + debugf3("MC: %s: %s(): success\n", __FILE__, __func__); return 0; fail: @@ -352,7 +352,7 @@ static int __devinit i82443bxgx_edacmc_init_one(struct pci_dev *pdev, { int rc; - debugf0("MC: " __FILE__ ": %s()\n", __func__); + debugf0("MC: %s: %s()\n", __FILE__, __func__); /* don't need to call pci_enable_device() */ rc = i82443bxgx_edacmc_probe1(pdev, ent->driver_data); @@ -367,7 +367,7 @@ static void __devexit i82443bxgx_edacmc_remove_one(struct pci_dev *pdev) { struct mem_ctl_info *mci; - debugf0(__FILE__ ": %s()\n", __func__); + debugf0("%s: %s()\n", __FILE__, __func__); if (i82443bxgx_pci) edac_pci_release_generic_ctl(i82443bxgx_pci); -- cgit v1.2.3 From 6d256fa8868b4509310ea201c2d2c04fabea96ab Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 26 May 2010 14:44:20 -0700 Subject: Staging: saa7134-go7007: replace dma_sync_single with dma_sync_single_for_cpu dma_sync_single() is deprecated and will be removed soon. No functional change since dma_sync_single is the wrapper of dma_sync_single_for_cpu. saa7134-go7007.c is commented out but anyway let's replace it. Signed-off-by: FUJITA Tomonori Cc: Greg Kroah-Hartman Cc: Ben Hutchings Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/staging/go7007/saa7134-go7007.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/go7007/saa7134-go7007.c b/drivers/staging/go7007/saa7134-go7007.c index 49f0d31c118a..cf7c34a99459 100644 --- a/drivers/staging/go7007/saa7134-go7007.c +++ b/drivers/staging/go7007/saa7134-go7007.c @@ -242,13 +242,13 @@ static void saa7134_go7007_irq_ts_done(struct saa7134_dev *dev, printk(KERN_DEBUG "saa7134-go7007: irq: lost %ld\n", (status >> 16) & 0x0f); if (status & 0x100000) { - dma_sync_single(&dev->pci->dev, - saa->bottom_dma, PAGE_SIZE, DMA_FROM_DEVICE); + dma_sync_single_for_cpu(&dev->pci->dev, + saa->bottom_dma, PAGE_SIZE, DMA_FROM_DEVICE); go7007_parse_video_stream(go, saa->bottom, PAGE_SIZE); saa_writel(SAA7134_RS_BA2(5), cpu_to_le32(saa->bottom_dma)); } else { - dma_sync_single(&dev->pci->dev, - saa->top_dma, PAGE_SIZE, DMA_FROM_DEVICE); + dma_sync_single_for_cpu(&dev->pci->dev, + saa->top_dma, PAGE_SIZE, DMA_FROM_DEVICE); go7007_parse_video_stream(go, saa->top, PAGE_SIZE); saa_writel(SAA7134_RS_BA1(5), cpu_to_le32(saa->top_dma)); } -- cgit v1.2.3 From a48223f9449d0289fc20cd11a98758109830798e Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 26 May 2010 14:44:29 -0700 Subject: lktdm: add support for hardlockup, softlockup and hung task crashes This adds three new types of kernel "crashes" in the lkdtm driver to trigger hardlockups, softlockups and task hung states at will. The first two are useful to test the new generic lockup detector and check its further regressions. The latter one is a bonus to check the hung task detector regressions even though it's not currently in rework. Signed-off-by: Frederic Weisbecker Cc: Simon Kagstrom Cc: Ingo Molnar Cc: Don Zickus Cc: Cyrill Gorcunov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/lkdtm.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers') diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c index 31a991161f0a..5bfb2a2041b8 100644 --- a/drivers/misc/lkdtm.c +++ b/drivers/misc/lkdtm.c @@ -75,6 +75,9 @@ enum ctype { UNALIGNED_LOAD_STORE_WRITE, OVERWRITE_ALLOCATION, WRITE_AFTER_FREE, + SOFTLOCKUP, + HARDLOCKUP, + HUNG_TASK, }; static char* cp_name[] = { @@ -99,6 +102,9 @@ static char* cp_type[] = { "UNALIGNED_LOAD_STORE_WRITE", "OVERWRITE_ALLOCATION", "WRITE_AFTER_FREE", + "SOFTLOCKUP", + "HARDLOCKUP", + "HUNG_TASK", }; static struct jprobe lkdtm; @@ -320,6 +326,20 @@ static void lkdtm_do_action(enum ctype which) memset(data, 0x78, len); break; } + case SOFTLOCKUP: + preempt_disable(); + for (;;) + cpu_relax(); + break; + case HARDLOCKUP: + local_irq_disable(); + for (;;) + cpu_relax(); + break; + case HUNG_TASK: + set_current_state(TASK_UNINTERRUPTIBLE); + schedule(); + break; case NONE: default: break; -- cgit v1.2.3 From e1c54b64027b52ba43b86fe6219910a9e9a88b73 Mon Sep 17 00:00:00 2001 From: Jan Blunck Date: Wed, 26 May 2010 14:44:44 -0700 Subject: osst: update ppos instead of using file->f_pos osst_read()/osst_write() modify file->f_pos directly instead of the ppos given to them. The VFS later updates the file->f_pos and overwrites it with the value of ppos. Signed-off-by: Jan Blunck Cc: Frederic Weisbecker Cc: Willem Riede Cc: James Bottomley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/scsi/osst.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 8dbf1c3afb7b..222f7f88e24a 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -3587,7 +3587,7 @@ if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name if (i == (-ENOSPC)) { transfer = STp->buffer->writing; /* FIXME -- check this logic */ if (transfer <= do_count) { - filp->f_pos += do_count - transfer; + *ppos += do_count - transfer; count -= do_count - transfer; if (STps->drv_block >= 0) { STps->drv_block += (do_count - transfer) / STp->block_size; @@ -3625,7 +3625,7 @@ if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name goto out; } - filp->f_pos += do_count; + *ppos += do_count; b_point += do_count; count -= do_count; if (STps->drv_block >= 0) { @@ -3647,7 +3647,7 @@ if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name if (STps->drv_block >= 0) { STps->drv_block += blks; } - filp->f_pos += count; + *ppos += count; count = 0; } @@ -3823,7 +3823,7 @@ static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, lo } STp->logical_blk_num += transfer / STp->block_size; STps->drv_block += transfer / STp->block_size; - filp->f_pos += transfer; + *ppos += transfer; buf += transfer; total += transfer; } -- cgit v1.2.3 From b627dbce6b5524c7c9032738bb60538999f45d41 Mon Sep 17 00:00:00 2001 From: Jan Blunck Date: Wed, 26 May 2010 14:44:46 -0700 Subject: mISDN: remove unnecessary test on f_pos This test is not doing anything since it is always false if the mISDN_read() is called from vfs_read(). Besides that the driver uses nonseekable_open() and is not using off or file->f_pos anywhere. Signed-off-by: Jan Blunck Cc: Frederic Weisbecker Cc: Karsten Keil Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/isdn/mISDN/timerdev.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c index c3243c913ec0..81048b8ed8ad 100644 --- a/drivers/isdn/mISDN/timerdev.c +++ b/drivers/isdn/mISDN/timerdev.c @@ -98,8 +98,6 @@ mISDN_read(struct file *filep, char __user *buf, size_t count, loff_t *off) if (*debug & DEBUG_TIMER) printk(KERN_DEBUG "%s(%p, %p, %d, %p)\n", __func__, filep, buf, (int)count, off); - if (*off != filep->f_pos) - return -ESPIPE; if (list_empty(&dev->expired) && (dev->work == 0)) { if (filep->f_flags & O_NONBLOCK) -- cgit v1.2.3 From 09eeb1f5f4d9b52ab57820160dea6027bbea82a3 Mon Sep 17 00:00:00 2001 From: Jan Blunck Date: Wed, 26 May 2010 14:44:47 -0700 Subject: rtc-m41t80: use nonseekable_open() Use nonseekable_open() for this since seeking is not supported anyway. Signed-off-by: Jan Blunck Cc: Frederic Weisbecker Cc: Paul Gortmaker Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-m41t80.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 038095d99976..6dc4e6241418 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -595,10 +595,6 @@ static void wdt_disable(void) static ssize_t wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - /* Can't seek (pwrite) on this device - if (ppos != &file->f_pos) - return -ESPIPE; - */ if (count) { wdt_ping(); return 1; @@ -707,7 +703,7 @@ static int wdt_open(struct inode *inode, struct file *file) */ wdt_is_open = 1; unlock_kernel(); - return 0; + return nonseekable_open(inode, file); } return -ENODEV; } -- cgit v1.2.3 From 889e5fbbc2da4f59d5f1e9b6172c5ff2b92d02c8 Mon Sep 17 00:00:00 2001 From: Jan Blunck Date: Wed, 26 May 2010 14:44:50 -0700 Subject: osst: use noop_llseek() instead of default_llseek() __os_scsi_tape_open() suggests that llseek() doesn't work: "We really want to do nonseekable_open(inode, filp); here, but some versions of tar incorrectly call lseek on tapes and bail out if that fails. So we disallow pread() and pwrite(), but permit lseeks." Instead of using the fallback default_llseek() the driver should use noop_llseek() which leaves the file->f_pos untouched but succeeds. Signed-off-by: Jan Blunck Cc: Frederic Weisbecker Cc: Willem Riede Cc: James Bottomley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/scsi/osst.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 222f7f88e24a..d64b7178fa08 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -5626,6 +5626,7 @@ static const struct file_operations osst_fops = { .open = os_scsi_tape_open, .flush = os_scsi_tape_flush, .release = os_scsi_tape_close, + .llseek = noop_llseek, }; static int osst_supports(struct scsi_device * SDp) -- cgit v1.2.3 From b4d878e23c7f574490ee4d6fd59ebd6819781dd1 Mon Sep 17 00:00:00 2001 From: Jan Blunck Date: Wed, 26 May 2010 14:44:51 -0700 Subject: st: use noop_llseek() instead of default_llseek() st_open() suggests that llseek() doesn't work: "We really want to do nonseekable_open(inode, filp); here, but some versions of tar incorrectly call lseek on tapes and bail out if that fails. So we disallow pread() and pwrite(), but permit lseeks." Instead of using the fallback default_llseek() the driver should use noop_llseek() which leaves the file->f_pos untouched but succeeds. Signed-off-by: Jan Blunck Cc: Frederic Weisbecker Cc: Kai Makisara Cc: Willem Riede Cc: James Bottomley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/scsi/st.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 3ea1a713ef25..24211d0efa6d 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3962,6 +3962,7 @@ static const struct file_operations st_fops = .open = st_open, .flush = st_flush, .release = st_release, + .llseek = noop_llseek, }; static int st_probe(struct device *dev) -- cgit v1.2.3 From 03a3f695cb9776cfa7da5e8e6d34fd20dd56510e Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Thu, 27 May 2010 09:03:19 -0700 Subject: Input: s3c2410_ts - restore accidentially dropped s3c24xx ids Without s3c24xx ids driver doesn't attach on s3c2410 and s3c244x Signed-off-by: Vasily Khoruzhick Acked-by: Ben Dooks Signed-off-by: Dmitry Torokhov Signed-off-by: Linus Torvalds --- drivers/input/touchscreen/s3c2410_ts.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c index e0b7c834111d..ac5d0f9b0cb1 100644 --- a/drivers/input/touchscreen/s3c2410_ts.c +++ b/drivers/input/touchscreen/s3c2410_ts.c @@ -413,6 +413,8 @@ static struct dev_pm_ops s3c_ts_pmops = { #endif static struct platform_device_id s3cts_driver_ids[] = { + { "s3c2410-ts", 0 }, + { "s3c2440-ts", 0 }, { "s3c64xx-ts", FEAT_PEN_IRQ }, { } }; -- cgit v1.2.3 From dce80a56268fffd6b5ea57b3f6ba3d027a68f05e Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Wed, 26 May 2010 11:28:08 +0800 Subject: SFI: add sysfs interface for SFI tables. Analogous to ACPI's /sys/firmware/acpi/tables/... create /sys/firmware/sfi/tables/ The tables are primariy for the kernel, but sometimes it is useful for user-space to be able to read them. Signed-off-by: Feng Tang Signed-off-by: Len Brown --- Documentation/ABI/testing/sysfs-firmware-sfi | 15 ++++ drivers/sfi/sfi_acpi.c | 41 +++++++++++ drivers/sfi/sfi_core.c | 103 +++++++++++++++++++++++++++ drivers/sfi/sfi_core.h | 8 +++ 4 files changed, 167 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-firmware-sfi (limited to 'drivers') diff --git a/Documentation/ABI/testing/sysfs-firmware-sfi b/Documentation/ABI/testing/sysfs-firmware-sfi new file mode 100644 index 000000000000..4be7d44aeacf --- /dev/null +++ b/Documentation/ABI/testing/sysfs-firmware-sfi @@ -0,0 +1,15 @@ +What: /sys/firmware/sfi/tables/ +Date: May 2010 +Contact: Len Brown +Description: + SFI defines a number of small static memory tables + so the kernel can get platform information from firmware. + + The tables are defined in the latest SFI specification: + http://simplefirmware.org/documentation + + While the tables are used by the kernel, user-space + can observe them this way: + + # cd /sys/firmware/sfi/tables + # cat $TABLENAME > $TABLENAME.bin diff --git a/drivers/sfi/sfi_acpi.c b/drivers/sfi/sfi_acpi.c index 34aba30eb84b..f5b4ca581541 100644 --- a/drivers/sfi/sfi_acpi.c +++ b/drivers/sfi/sfi_acpi.c @@ -173,3 +173,44 @@ int sfi_acpi_table_parse(char *signature, char *oem_id, char *oem_table_id, sfi_acpi_put_table(table); return ret; } + +static ssize_t sfi_acpi_table_show(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t offset, size_t count) +{ + struct sfi_table_attr *tbl_attr = + container_of(bin_attr, struct sfi_table_attr, attr); + struct acpi_table_header *th = NULL; + struct sfi_table_key key; + ssize_t cnt; + + key.sig = tbl_attr->name; + key.oem_id = NULL; + key.oem_table_id = NULL; + + th = sfi_acpi_get_table(&key); + if (!th) + return 0; + + cnt = memory_read_from_buffer(buf, count, &offset, + th, th->length); + sfi_acpi_put_table(th); + + return cnt; +} + + +void __init sfi_acpi_sysfs_init(void) +{ + u32 tbl_cnt, i; + struct sfi_table_attr *tbl_attr; + + tbl_cnt = XSDT_GET_NUM_ENTRIES(xsdt_va, u64); + for (i = 0; i < tbl_cnt; i++) { + tbl_attr = + sfi_sysfs_install_table(xsdt_va->table_offset_entry[i]); + tbl_attr->attr.read = sfi_acpi_table_show; + } + + return; +} diff --git a/drivers/sfi/sfi_core.c b/drivers/sfi/sfi_core.c index aba6a461365b..005195958647 100644 --- a/drivers/sfi/sfi_core.c +++ b/drivers/sfi/sfi_core.c @@ -67,6 +67,7 @@ #include #include #include +#include #include "sfi_core.h" @@ -382,6 +383,102 @@ static __init int sfi_find_syst(void) return -1; } +static struct kobject *sfi_kobj; +static struct kobject *tables_kobj; + +static ssize_t sfi_table_show(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t offset, size_t count) +{ + struct sfi_table_attr *tbl_attr = + container_of(bin_attr, struct sfi_table_attr, attr); + struct sfi_table_header *th = NULL; + struct sfi_table_key key; + ssize_t cnt; + + key.sig = tbl_attr->name; + key.oem_id = NULL; + key.oem_table_id = NULL; + + if (strncmp(SFI_SIG_SYST, tbl_attr->name, SFI_SIGNATURE_SIZE)) { + th = sfi_get_table(&key); + if (!th) + return 0; + + cnt = memory_read_from_buffer(buf, count, &offset, + th, th->len); + sfi_put_table(th); + } else + cnt = memory_read_from_buffer(buf, count, &offset, + syst_va, syst_va->header.len); + + return cnt; +} + +struct sfi_table_attr __init *sfi_sysfs_install_table(u64 pa) +{ + struct sfi_table_attr *tbl_attr; + struct sfi_table_header *th; + int ret; + + tbl_attr = kzalloc(sizeof(struct sfi_table_attr), GFP_KERNEL); + if (!tbl_attr) + return NULL; + + th = sfi_map_table(pa); + if (!th || !th->sig[0]) { + kfree(tbl_attr); + return NULL; + } + + sysfs_attr_init(&tbl_attr->attr.attr); + memcpy(tbl_attr->name, th->sig, SFI_SIGNATURE_SIZE); + + tbl_attr->attr.size = 0; + tbl_attr->attr.read = sfi_table_show; + tbl_attr->attr.attr.name = tbl_attr->name; + tbl_attr->attr.attr.mode = 0400; + + ret = sysfs_create_bin_file(tables_kobj, + &tbl_attr->attr); + if (ret) + kfree(tbl_attr); + + sfi_unmap_table(th); + return tbl_attr; +} + +static int __init sfi_sysfs_init(void) +{ + int tbl_cnt, i; + + if (sfi_disabled) + return 0; + + sfi_kobj = kobject_create_and_add("sfi", firmware_kobj); + if (!sfi_kobj) + return 0; + + tables_kobj = kobject_create_and_add("tables", sfi_kobj); + if (!tables_kobj) { + kobject_put(sfi_kobj); + return 0; + } + + sfi_sysfs_install_table(syst_pa); + + tbl_cnt = SFI_GET_NUM_ENTRIES(syst_va, u64); + + for (i = 0; i < tbl_cnt; i++) + sfi_sysfs_install_table(syst_va->pentry[i]); + + sfi_acpi_sysfs_init(); + kobject_uevent(sfi_kobj, KOBJ_ADD); + kobject_uevent(tables_kobj, KOBJ_ADD); + pr_info("SFI sysfs interfaces init success\n"); + return 0; +} + void __init sfi_init(void) { if (!acpi_disabled) @@ -414,3 +511,9 @@ void __init sfi_init_late(void) sfi_acpi_init(); } + +/* + * The reason we put it here becasue we need wait till the /sys/firmware + * is setup, then our interface can be registered in /sys/firmware/sfi + */ +core_initcall(sfi_sysfs_init); diff --git a/drivers/sfi/sfi_core.h b/drivers/sfi/sfi_core.h index da82d39e104d..b7cf220d44ec 100644 --- a/drivers/sfi/sfi_core.h +++ b/drivers/sfi/sfi_core.h @@ -61,6 +61,12 @@ struct sfi_table_key{ char *oem_table_id; }; +/* sysfs interface */ +struct sfi_table_attr { + struct bin_attribute attr; + char name[8]; +}; + #define SFI_ANY_KEY { .sig = NULL, .oem_id = NULL, .oem_table_id = NULL } extern int __init sfi_acpi_init(void); @@ -68,3 +74,5 @@ extern struct sfi_table_header *sfi_check_table(u64 paddr, struct sfi_table_key *key); struct sfi_table_header *sfi_get_table(struct sfi_table_key *key); extern void sfi_put_table(struct sfi_table_header *table); +extern struct sfi_table_attr __init *sfi_sysfs_install_table(u64 pa); +extern void __init sfi_acpi_sysfs_init(void); -- cgit v1.2.3 From c0d64cb031c21f163a0ec15cf10844bcf0ceedcf Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 22 May 2010 16:34:10 -0400 Subject: cpuidle: add cpuidle_unregister_driver() error check Assure that cpuidle_unregister_driver() will not clobber the registered driver if unregistered by somebody else. Signed-off-by: Len Brown --- drivers/cpuidle/driver.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c index 2257004fe33d..826b5c0aa12b 100644 --- a/drivers/cpuidle/driver.c +++ b/drivers/cpuidle/driver.c @@ -45,8 +45,11 @@ EXPORT_SYMBOL_GPL(cpuidle_register_driver); */ void cpuidle_unregister_driver(struct cpuidle_driver *drv) { - if (!drv) + if (drv != cpuidle_curr_driver) { + WARN(1, "invalid cpuidle_unregister_driver(%s)\n", + drv->name); return; + } spin_lock(&cpuidle_driver_lock); cpuidle_curr_driver = NULL; -- cgit v1.2.3 From 70dd6beac02f43a5099fcf5fddf68cfee0cbf479 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 27 May 2010 19:58:37 +0200 Subject: hwmon: (asus_atk0110) Don't load if ACPI resources aren't enforced When the user passes the kernel parameter acpi_enforce_resources=lax, the ACPI resources are no longer protected, so a native driver can make use of them. In that case, we do not want the asus_atk0110 to be loaded. Unfortunately, this driver loads automatically due to its MODULE_DEVICE_TABLE, so the user ends up with two drivers loaded for the same device - this is bad. So I suggest that we prevent the asus_atk0110 driver from loading if acpi_enforce_resources=lax. Signed-off-by: Jean Delvare Acked-by: Luca Tettamanti Cc: Len Brown --- drivers/acpi/osl.c | 9 +++++++++ drivers/hwmon/asus_atk0110.c | 7 +++++++ include/linux/acpi.h | 2 ++ 3 files changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 4bc1c4178f50..78418ce4fc78 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -1206,6 +1206,15 @@ int acpi_check_mem_region(resource_size_t start, resource_size_t n, } EXPORT_SYMBOL(acpi_check_mem_region); +/* + * Let drivers know whether the resource checks are effective + */ +int acpi_resources_are_enforced(void) +{ + return acpi_enforce_resources == ENFORCE_RESOURCES_STRICT; +} +EXPORT_SYMBOL(acpi_resources_are_enforced); + /* * Acquire a spinlock. * diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 16c420240724..653db1bda934 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c @@ -1411,6 +1411,13 @@ static int __init atk0110_init(void) { int ret; + /* Make sure it's safe to access the device through ACPI */ + if (!acpi_resources_are_enforced()) { + pr_err("atk: Resources not safely usable due to " + "acpi_enforce_resources kernel parameter\n"); + return -EBUSY; + } + ret = acpi_bus_register_driver(&atk_driver); if (ret) pr_info("atk: acpi_bus_register_driver failed: %d\n", ret); diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 3da73f5f0ae9..2c60f1f70b38 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -248,6 +248,8 @@ int acpi_check_region(resource_size_t start, resource_size_t n, int acpi_check_mem_region(resource_size_t start, resource_size_t n, const char *name); +int acpi_resources_are_enforced(void); + #ifdef CONFIG_PM_SLEEP void __init acpi_no_s4_hw_signature(void); void __init acpi_old_suspend_ordering(void); -- cgit v1.2.3 From 10f2ed31aae11040dfd64cee10c47db79b4b4647 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Thu, 27 May 2010 19:58:38 +0200 Subject: hwmon: (lm63) Add basic support for LM64 The LM64 appears to be an LM63 with added GPIO lines. Add support for the hwmon functionality - GPIO can be added at some later stage if someone has a need for them. Signed-off-by: Matthew Garrett Signed-off-by: Jean Delvare --- Documentation/hwmon/lm63 | 7 +++++++ drivers/hwmon/Kconfig | 11 ++++++----- drivers/hwmon/lm63.c | 16 ++++++++++++---- 3 files changed, 25 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/Documentation/hwmon/lm63 b/Documentation/hwmon/lm63 index 31660bf97979..b9843eab1afb 100644 --- a/Documentation/hwmon/lm63 +++ b/Documentation/hwmon/lm63 @@ -7,6 +7,11 @@ Supported chips: Addresses scanned: I2C 0x4c Datasheet: Publicly available at the National Semiconductor website http://www.national.com/pf/LM/LM63.html + * National Semiconductor LM64 + Prefix: 'lm64' + Addresses scanned: I2C 0x18 and 0x4e + Datasheet: Publicly available at the National Semiconductor website + http://www.national.com/pf/LM/LM64.html Author: Jean Delvare @@ -55,3 +60,5 @@ The lm63 driver will not update its values more frequently than every second; reading them more often will do no harm, but will return 'old' values. +The LM64 is effectively an LM63 with GPIO lines. The driver does not +support these GPIO lines at present. diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 6a9ac754ca5d..fa609586c7c9 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -447,13 +447,14 @@ config SENSORS_IT87 will be called it87. config SENSORS_LM63 - tristate "National Semiconductor LM63" + tristate "National Semiconductor LM63 and LM64" depends on I2C help - If you say yes here you get support for the National Semiconductor - LM63 remote diode digital temperature sensor with integrated fan - control. Such chips are found on the Tyan S4882 (Thunder K8QS Pro) - motherboard, among others. + If you say yes here you get support for the National + Semiconductor LM63 and LM64 remote diode digital temperature + sensors with integrated fan control. Such chips are found + on the Tyan S4882 (Thunder K8QS Pro) motherboard, among + others. This driver can also be built as a module. If so, the module will be called lm63. diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index bf81aff7051d..776aeb3019d2 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c @@ -53,7 +53,7 @@ * Address is fully defined internally and cannot be changed. */ -static const unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END }; /* * The LM63 registers @@ -131,12 +131,15 @@ static struct lm63_data *lm63_update_device(struct device *dev); static int lm63_detect(struct i2c_client *client, struct i2c_board_info *info); static void lm63_init_client(struct i2c_client *client); +enum chips { lm63, lm64 }; + /* * Driver data (common to all clients) */ static const struct i2c_device_id lm63_id[] = { - { "lm63", 0 }, + { "lm63", lm63 }, + { "lm64", lm64 }, { } }; MODULE_DEVICE_TABLE(i2c, lm63_id); @@ -422,6 +425,7 @@ static int lm63_detect(struct i2c_client *new_client, struct i2c_adapter *adapter = new_client->adapter; u8 man_id, chip_id, reg_config1, reg_config2; u8 reg_alert_status, reg_alert_mask; + int address = new_client->addr; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; @@ -439,7 +443,6 @@ static int lm63_detect(struct i2c_client *new_client, LM63_REG_ALERT_MASK); if (man_id != 0x01 /* National Semiconductor */ - || chip_id != 0x41 /* LM63 */ || (reg_config1 & 0x18) != 0x00 || (reg_config2 & 0xF8) != 0x00 || (reg_alert_status & 0x20) != 0x00 @@ -450,7 +453,12 @@ static int lm63_detect(struct i2c_client *new_client, return -ENODEV; } - strlcpy(info->type, "lm63", I2C_NAME_SIZE); + if (chip_id == 0x41 && address == 0x4c) + strlcpy(info->type, "lm63", I2C_NAME_SIZE); + else if (chip_id == 0x51 && (address == 0x18 || address == 0x4e)) + strlcpy(info->type, "lm64", I2C_NAME_SIZE); + else + return -ENODEV; return 0; } -- cgit v1.2.3 From 162bb59e498a15e27717bcc0831b97d393f2290d Mon Sep 17 00:00:00 2001 From: Giel van Schijndel Date: Thu, 27 May 2010 19:58:40 +0200 Subject: hwmon: (f71882fg) Fixed braces coding style issues Fixed several coding style issues. Signed-off-by: Giel van Schijndel Acked-by: Hans de Goede Signed-off-by: Jean Delvare --- drivers/hwmon/f71882fg.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index a95fa4256caa..21bc66159b5a 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c @@ -866,11 +866,11 @@ static int superio_inw(int base, int reg) static inline void superio_enter(int base) { /* according to the datasheet the key must be send twice! */ - outb( SIO_UNLOCK_KEY, base); - outb( SIO_UNLOCK_KEY, base); + outb(SIO_UNLOCK_KEY, base); + outb(SIO_UNLOCK_KEY, base); } -static inline void superio_select( int base, int ld) +static inline void superio_select(int base, int ld) { outb(SIO_REG_LDSEL, base); outb(ld, base + 1); @@ -945,7 +945,7 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev) mutex_lock(&data->update_lock); /* Update once every 60 seconds */ - if ( time_after(jiffies, data->last_limits + 60 * HZ ) || + if (time_after(jiffies, data->last_limits + 60 * HZ) || !data->valid) { if (data->type == f71882fg || data->type == f71889fg) { data->in1_max = @@ -2151,8 +2151,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, } *address = superio_inw(sioaddr, SIO_REG_ADDR); - if (*address == 0) - { + if (*address == 0) { printk(KERN_WARNING DRVNAME ": Base address not set\n"); goto exit; } -- cgit v1.2.3 From e8a4eacaa93853f977b0420ca42c471d528f93af Mon Sep 17 00:00:00 2001 From: Giel van Schijndel Date: Thu, 27 May 2010 19:58:41 +0200 Subject: hwmon: (f71882fg) Use strict_stro(l|ul) instead of simple_strto$1 Use the strict_strol and strict_stroul functions instead of simple_strol and simple_stroul respectively in sysfs functions. Signed-off-by: Giel van Schijndel Acked-by: Hans de Goede Signed-off-by: Jean Delvare --- drivers/hwmon/f71882fg.c | 133 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 104 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 21bc66159b5a..4230729780c4 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c @@ -1127,8 +1127,12 @@ static ssize_t store_fan_full_speed(struct device *dev, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - long val = simple_strtol(buf, NULL, 10); + int err, nr = to_sensor_dev_attr_2(devattr)->index; + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; val = SENSORS_LIMIT(val, 23, 1500000); val = fan_to_reg(val); @@ -1157,8 +1161,12 @@ static ssize_t store_fan_beep(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - unsigned long val = simple_strtoul(buf, NULL, 10); + int err, nr = to_sensor_dev_attr_2(devattr)->index; + unsigned long val; + + err = strict_strtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP); @@ -1206,7 +1214,14 @@ static ssize_t store_in_max(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10) / 8; + int err; + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; + + val /= 8; val = SENSORS_LIMIT(val, 0, 255); mutex_lock(&data->update_lock); @@ -1233,8 +1248,12 @@ static ssize_t store_in_beep(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - unsigned long val = simple_strtoul(buf, NULL, 10); + int err, nr = to_sensor_dev_attr_2(devattr)->index; + unsigned long val; + + err = strict_strtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP); @@ -1299,8 +1318,14 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - long val = simple_strtol(buf, NULL, 10) / 1000; + int err, nr = to_sensor_dev_attr_2(devattr)->index; + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; + + val /= 1000; val = SENSORS_LIMIT(val, 0, 255); mutex_lock(&data->update_lock); @@ -1333,10 +1358,16 @@ static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - long val = simple_strtol(buf, NULL, 10) / 1000; + int err, nr = to_sensor_dev_attr_2(devattr)->index; ssize_t ret = count; u8 reg; + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; + + val /= 1000; mutex_lock(&data->update_lock); @@ -1372,8 +1403,14 @@ static ssize_t store_temp_crit(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - long val = simple_strtol(buf, NULL, 10) / 1000; + int err, nr = to_sensor_dev_attr_2(devattr)->index; + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; + + val /= 1000; val = SENSORS_LIMIT(val, 0, 255); mutex_lock(&data->update_lock); @@ -1427,8 +1464,12 @@ static ssize_t store_temp_beep(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - unsigned long val = simple_strtoul(buf, NULL, 10); + int err, nr = to_sensor_dev_attr_2(devattr)->index; + unsigned long val; + + err = strict_strtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP); @@ -1490,8 +1531,13 @@ static ssize_t store_pwm(struct device *dev, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - long val = simple_strtol(buf, NULL, 10); + int err, nr = to_sensor_dev_attr_2(devattr)->index; + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; + val = SENSORS_LIMIT(val, 0, 255); mutex_lock(&data->update_lock); @@ -1551,8 +1597,12 @@ static ssize_t store_pwm_enable(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - long val = simple_strtol(buf, NULL, 10); + int err, nr = to_sensor_dev_attr_2(devattr)->index; + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; /* Special case for F8000 pwm channel 3 which only does auto mode */ if (data->type == f8000 && nr == 2 && val != 2) @@ -1626,9 +1676,14 @@ static ssize_t store_pwm_auto_point_pwm(struct device *dev, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int pwm = to_sensor_dev_attr_2(devattr)->index; + int err, pwm = to_sensor_dev_attr_2(devattr)->index; int point = to_sensor_dev_attr_2(devattr)->nr; - long val = simple_strtol(buf, NULL, 10); + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; + val = SENSORS_LIMIT(val, 0, 255); mutex_lock(&data->update_lock); @@ -1674,10 +1729,16 @@ static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; + int err, nr = to_sensor_dev_attr_2(devattr)->index; int point = to_sensor_dev_attr_2(devattr)->nr; - long val = simple_strtol(buf, NULL, 10) / 1000; u8 reg; + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; + + val /= 1000; mutex_lock(&data->update_lock); data->pwm_auto_point_temp[nr][point] = @@ -1716,8 +1777,12 @@ static ssize_t store_pwm_interpolate(struct device *dev, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - unsigned long val = simple_strtoul(buf, NULL, 10); + int err, nr = to_sensor_dev_attr_2(devattr)->index; + unsigned long val; + + err = strict_strtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->pwm_auto_point_mapping[nr] = @@ -1752,8 +1817,12 @@ static ssize_t store_pwm_auto_point_channel(struct device *dev, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - long val = simple_strtol(buf, NULL, 10); + int err, nr = to_sensor_dev_attr_2(devattr)->index; + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; switch (val) { case 1: @@ -1798,9 +1867,15 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int pwm = to_sensor_dev_attr_2(devattr)->index; + int err, pwm = to_sensor_dev_attr_2(devattr)->index; int point = to_sensor_dev_attr_2(devattr)->nr; - long val = simple_strtol(buf, NULL, 10) / 1000; + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; + + val /= 1000; if (data->type == f71889fg) val = SENSORS_LIMIT(val, -128, 127); -- cgit v1.2.3 From bd328acdc6160b95f5d7127a9df3172892f35627 Mon Sep 17 00:00:00 2001 From: Giel van Schijndel Date: Thu, 27 May 2010 19:58:42 +0200 Subject: hwmon: (f71882fg) Code cleanup Some code cleanup: properly use previously defined functions, rather than duplicating their code. Signed-off-by: Giel van Schijndel Cc: Hans de Goede Signed-off-by: Jean Delvare --- drivers/hwmon/f71882fg.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 4230729780c4..ca34e5c48702 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c @@ -856,10 +856,8 @@ static inline int superio_inb(int base, int reg) static int superio_inw(int base, int reg) { int val; - outb(reg++, base); - val = inb(base + 1) << 8; - outb(reg, base); - val |= inb(base + 1); + val = superio_inb(base, reg) << 8; + val |= superio_inb(base, reg + 1); return val; } @@ -905,10 +903,8 @@ static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg) { u16 val; - outb(reg++, data->addr + ADDR_REG_OFFSET); - val = inb(data->addr + DATA_REG_OFFSET) << 8; - outb(reg, data->addr + ADDR_REG_OFFSET); - val |= inb(data->addr + DATA_REG_OFFSET); + val = f71882fg_read8(data, reg) << 8; + val |= f71882fg_read8(data, reg + 1); return val; } @@ -921,10 +917,8 @@ static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val) static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val) { - outb(reg++, data->addr + ADDR_REG_OFFSET); - outb(val >> 8, data->addr + DATA_REG_OFFSET); - outb(reg, data->addr + ADDR_REG_OFFSET); - outb(val & 255, data->addr + DATA_REG_OFFSET); + f71882fg_write8(data, reg, val >> 8); + f71882fg_write8(data, reg + 1, val & 0xff); } static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr) -- cgit v1.2.3 From 729d273aa7c86eb1406ade4eadf249cff188bf9a Mon Sep 17 00:00:00 2001 From: Giel van Schijndel Date: Thu, 27 May 2010 19:58:43 +0200 Subject: hwmon: (f71882fg) Acquire I/O regions while we're working with them Acquire the I/O region for the Super I/O chip while we're working on it. Signed-off-by: Giel van Schijndel Cc: Hans de Goede Signed-off-by: Jean Delvare --- drivers/hwmon/f71882fg.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index ca34e5c48702..537841ef44b9 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c @@ -2178,6 +2178,13 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, int err = -ENODEV; u16 devid; + /* Don't step on other drivers' I/O space by accident */ + if (!request_region(sioaddr, 2, DRVNAME)) { + printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n", + (int)sioaddr); + return -EBUSY; + } + superio_enter(sioaddr); devid = superio_inw(sioaddr, SIO_REG_MANID); @@ -2232,6 +2239,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, (int)superio_inb(sioaddr, SIO_REG_DEVREV)); exit: superio_exit(sioaddr); + release_region(sioaddr, 2); return err; } -- cgit v1.2.3 From 8c3c7a256f7ab142dfbcee2d8633dbce5a36fde7 Mon Sep 17 00:00:00 2001 From: "Ira W. Snyder" Date: Thu, 27 May 2010 19:58:44 +0200 Subject: hwmon: (lm90) Use programmed update rate The lm90 driver programs the sensor chip to update its readings at 2 Hz (500 ms between readings). However, the driver only does reads from the chip at intervals of 2 * HZ (2000 ms between readings). Change the driver update rate to the programmed update rate. Signed-off-by: Ira W. Snyder Signed-off-by: Jean Delvare --- drivers/hwmon/lm90.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 7cc2708871ab..760ef72eea56 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c @@ -982,7 +982,8 @@ static struct lm90_data *lm90_update_device(struct device *dev) mutex_lock(&data->update_lock); - if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { + if (time_after(jiffies, data->last_updated + HZ / 2 + HZ / 10) + || !data->valid) { u8 h, l; dev_dbg(&client->dev, "Updating lm90 data.\n"); -- cgit v1.2.3 From 87c33daadbfea6034830d5494ecaa7521de0cdd3 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 27 May 2010 19:58:46 +0200 Subject: hwmon: (adm1031) Allow setting update rate Based on earlier work by Ira W. Snyder. The adm1031 chip is capable of using a runtime configurable sampling rate, using the fan filter register. Add support for reading and setting the update rate via sysfs. Signed-off-by: Jean Delvare Acked-by: Ira W. Snyder --- drivers/hwmon/adm1031.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index 1644b92e7cc4..15c1a9616af3 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c @@ -36,6 +36,7 @@ #define ADM1031_REG_FAN_DIV(nr) (0x20 + (nr)) #define ADM1031_REG_PWM (0x22) #define ADM1031_REG_FAN_MIN(nr) (0x10 + (nr)) +#define ADM1031_REG_FAN_FILTER (0x23) #define ADM1031_REG_TEMP_OFFSET(nr) (0x0d + (nr)) #define ADM1031_REG_TEMP_MAX(nr) (0x14 + 4 * (nr)) @@ -61,6 +62,9 @@ #define ADM1031_CONF2_TACH2_ENABLE 0x08 #define ADM1031_CONF2_TEMP_ENABLE(chan) (0x10 << (chan)) +#define ADM1031_UPDATE_RATE_MASK 0x1c +#define ADM1031_UPDATE_RATE_SHIFT 2 + /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; @@ -75,6 +79,7 @@ struct adm1031_data { int chip_type; char valid; /* !=0 if following fields are valid */ unsigned long last_updated; /* In jiffies */ + unsigned int update_rate; /* In milliseconds */ /* The chan_select_table contains the possible configurations for * auto fan control. */ @@ -738,6 +743,57 @@ static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, 12); static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 13); static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 14); +/* Update Rate */ +static const unsigned int update_rates[] = { + 16000, 8000, 4000, 2000, 1000, 500, 250, 125, +}; + +static ssize_t show_update_rate(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct adm1031_data *data = i2c_get_clientdata(client); + + return sprintf(buf, "%u\n", data->update_rate); +} + +static ssize_t set_update_rate(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct adm1031_data *data = i2c_get_clientdata(client); + unsigned long val; + int i, err; + u8 reg; + + err = strict_strtoul(buf, 10, &val); + if (err) + return err; + + /* find the nearest update rate from the table */ + for (i = 0; i < ARRAY_SIZE(update_rates) - 1; i++) { + if (val >= update_rates[i]) + break; + } + /* if not found, we point to the last entry (lowest update rate) */ + + /* set the new update rate while preserving other settings */ + reg = adm1031_read_value(client, ADM1031_REG_FAN_FILTER); + reg &= ~ADM1031_UPDATE_RATE_MASK; + reg |= i << ADM1031_UPDATE_RATE_SHIFT; + adm1031_write_value(client, ADM1031_REG_FAN_FILTER, reg); + + mutex_lock(&data->update_lock); + data->update_rate = update_rates[i]; + mutex_unlock(&data->update_lock); + + return count; +} + +static DEVICE_ATTR(update_rate, S_IRUGO | S_IWUSR, show_update_rate, + set_update_rate); + static struct attribute *adm1031_attributes[] = { &sensor_dev_attr_fan1_input.dev_attr.attr, &sensor_dev_attr_fan1_div.dev_attr.attr, @@ -774,6 +830,7 @@ static struct attribute *adm1031_attributes[] = { &sensor_dev_attr_auto_fan1_min_pwm.dev_attr.attr, + &dev_attr_update_rate.attr, &dev_attr_alarms.attr, NULL @@ -900,6 +957,7 @@ static void adm1031_init_client(struct i2c_client *client) { unsigned int read_val; unsigned int mask; + int i; struct adm1031_data *data = i2c_get_clientdata(client); mask = (ADM1031_CONF2_PWM1_ENABLE | ADM1031_CONF2_TACH1_ENABLE); @@ -919,18 +977,24 @@ static void adm1031_init_client(struct i2c_client *client) ADM1031_CONF1_MONITOR_ENABLE); } + /* Read the chip's update rate */ + mask = ADM1031_UPDATE_RATE_MASK; + read_val = adm1031_read_value(client, ADM1031_REG_FAN_FILTER); + i = (read_val & mask) >> ADM1031_UPDATE_RATE_SHIFT; + data->update_rate = update_rates[i]; } static struct adm1031_data *adm1031_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct adm1031_data *data = i2c_get_clientdata(client); + unsigned long next_update; int chan; mutex_lock(&data->update_lock); - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) - || !data->valid) { + next_update = data->last_updated + msecs_to_jiffies(data->update_rate); + if (time_after(jiffies, next_update) || !data->valid) { dev_dbg(&client->dev, "Starting adm1031 update\n"); for (chan = 0; -- cgit v1.2.3 From 2b76d80adcc40b2d50cf78de046ccfc4bc63df59 Mon Sep 17 00:00:00 2001 From: Andre Prendel Date: Thu, 27 May 2010 19:58:48 +0200 Subject: hwmon: (tmp401) Use constants for sysfs file permissions Replace octal representation of file permissions by the corresponding constants. Signed-off-by: Andre Prendel Acked-by: Hans de Goede Signed-off-by: Jean Delvare --- drivers/hwmon/tmp401.c | 50 ++++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index d14a1af9f550..d58b40a6613d 100644 --- a/drivers/hwmon/tmp401.c +++ b/drivers/hwmon/tmp401.c @@ -420,30 +420,36 @@ static ssize_t reset_temp_history(struct device *dev, } static struct sensor_device_attribute tmp401_attr[] = { - SENSOR_ATTR(temp1_input, 0444, show_temp_value, NULL, 0), - SENSOR_ATTR(temp1_min, 0644, show_temp_min, store_temp_min, 0), - SENSOR_ATTR(temp1_max, 0644, show_temp_max, store_temp_max, 0), - SENSOR_ATTR(temp1_crit, 0644, show_temp_crit, store_temp_crit, 0), - SENSOR_ATTR(temp1_crit_hyst, 0644, show_temp_crit_hyst, + SENSOR_ATTR(temp1_input, S_IRUGO, show_temp_value, NULL, 0), + SENSOR_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min, + store_temp_min, 0), + SENSOR_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, + store_temp_max, 0), + SENSOR_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp_crit, + store_temp_crit, 0), + SENSOR_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp_crit_hyst, store_temp_crit_hyst, 0), - SENSOR_ATTR(temp1_min_alarm, 0444, show_status, NULL, + SENSOR_ATTR(temp1_min_alarm, S_IRUGO, show_status, NULL, TMP401_STATUS_LOCAL_LOW), - SENSOR_ATTR(temp1_max_alarm, 0444, show_status, NULL, + SENSOR_ATTR(temp1_max_alarm, S_IRUGO, show_status, NULL, TMP401_STATUS_LOCAL_HIGH), - SENSOR_ATTR(temp1_crit_alarm, 0444, show_status, NULL, + SENSOR_ATTR(temp1_crit_alarm, S_IRUGO, show_status, NULL, TMP401_STATUS_LOCAL_CRIT), - SENSOR_ATTR(temp2_input, 0444, show_temp_value, NULL, 1), - SENSOR_ATTR(temp2_min, 0644, show_temp_min, store_temp_min, 1), - SENSOR_ATTR(temp2_max, 0644, show_temp_max, store_temp_max, 1), - SENSOR_ATTR(temp2_crit, 0644, show_temp_crit, store_temp_crit, 1), - SENSOR_ATTR(temp2_crit_hyst, 0444, show_temp_crit_hyst, NULL, 1), - SENSOR_ATTR(temp2_fault, 0444, show_status, NULL, + SENSOR_ATTR(temp2_input, S_IRUGO, show_temp_value, NULL, 1), + SENSOR_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min, + store_temp_min, 1), + SENSOR_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, + store_temp_max, 1), + SENSOR_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp_crit, + store_temp_crit, 1), + SENSOR_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 1), + SENSOR_ATTR(temp2_fault, S_IRUGO, show_status, NULL, TMP401_STATUS_REMOTE_OPEN), - SENSOR_ATTR(temp2_min_alarm, 0444, show_status, NULL, + SENSOR_ATTR(temp2_min_alarm, S_IRUGO, show_status, NULL, TMP401_STATUS_REMOTE_LOW), - SENSOR_ATTR(temp2_max_alarm, 0444, show_status, NULL, + SENSOR_ATTR(temp2_max_alarm, S_IRUGO, show_status, NULL, TMP401_STATUS_REMOTE_HIGH), - SENSOR_ATTR(temp2_crit_alarm, 0444, show_status, NULL, + SENSOR_ATTR(temp2_crit_alarm, S_IRUGO, show_status, NULL, TMP401_STATUS_REMOTE_CRIT), }; @@ -455,11 +461,11 @@ static struct sensor_device_attribute tmp401_attr[] = { * and remote channels. */ static struct sensor_device_attribute tmp411_attr[] = { - SENSOR_ATTR(temp1_highest, 0444, show_temp_highest, NULL, 0), - SENSOR_ATTR(temp1_lowest, 0444, show_temp_lowest, NULL, 0), - SENSOR_ATTR(temp2_highest, 0444, show_temp_highest, NULL, 1), - SENSOR_ATTR(temp2_lowest, 0444, show_temp_lowest, NULL, 1), - SENSOR_ATTR(temp_reset_history, 0200, NULL, reset_temp_history, 0), + SENSOR_ATTR(temp1_highest, S_IRUGO, show_temp_highest, NULL, 0), + SENSOR_ATTR(temp1_lowest, S_IRUGO, show_temp_lowest, NULL, 0), + SENSOR_ATTR(temp2_highest, S_IRUGO, show_temp_highest, NULL, 1), + SENSOR_ATTR(temp2_lowest, S_IRUGO, show_temp_lowest, NULL, 1), + SENSOR_ATTR(temp_reset_history, S_IWUSR, NULL, reset_temp_history, 0), }; /* -- cgit v1.2.3 From ea63c2b91fd8b5c697bcae6a84ff4b4cef571216 Mon Sep 17 00:00:00 2001 From: Andre Prendel Date: Thu, 27 May 2010 19:58:49 +0200 Subject: hwmon: (tmp401) Reorganize code to get rid of static forward declarations Signed-off-by: Andre Prendel Acked-by: Hans de Goede Signed-off-by: Jean Delvare --- drivers/hwmon/tmp401.c | 205 +++++++++++++++++++++++-------------------------- 1 file changed, 97 insertions(+), 108 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c index d58b40a6613d..ad8d535235c5 100644 --- a/drivers/hwmon/tmp401.c +++ b/drivers/hwmon/tmp401.c @@ -91,17 +91,6 @@ static const u8 TMP411_TEMP_HIGHEST_LSB[2] = { 0x33, 0x37 }; #define TMP401_DEVICE_ID 0x11 #define TMP411_DEVICE_ID 0x12 -/* - * Functions declarations - */ - -static int tmp401_probe(struct i2c_client *client, - const struct i2c_device_id *id); -static int tmp401_detect(struct i2c_client *client, - struct i2c_board_info *info); -static int tmp401_remove(struct i2c_client *client); -static struct tmp401_data *tmp401_update_device(struct device *dev); - /* * Driver data (common to all clients) */ @@ -113,18 +102,6 @@ static const struct i2c_device_id tmp401_id[] = { }; MODULE_DEVICE_TABLE(i2c, tmp401_id); -static struct i2c_driver tmp401_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "tmp401", - }, - .probe = tmp401_probe, - .remove = tmp401_remove, - .id_table = tmp401_id, - .detect = tmp401_detect, - .address_list = normal_i2c, -}; - /* * Client data (each client gets its own) */ @@ -194,6 +171,71 @@ static u8 tmp401_crit_temp_to_register(long temp, u8 config) return (temp + 500) / 1000; } +static struct tmp401_data *tmp401_update_device_reg16( + struct i2c_client *client, struct tmp401_data *data) +{ + int i; + + for (i = 0; i < 2; i++) { + /* + * High byte must be read first immediately followed + * by the low byte + */ + data->temp[i] = i2c_smbus_read_byte_data(client, + TMP401_TEMP_MSB[i]) << 8; + data->temp[i] |= i2c_smbus_read_byte_data(client, + TMP401_TEMP_LSB[i]); + data->temp_low[i] = i2c_smbus_read_byte_data(client, + TMP401_TEMP_LOW_LIMIT_MSB_READ[i]) << 8; + data->temp_low[i] |= i2c_smbus_read_byte_data(client, + TMP401_TEMP_LOW_LIMIT_LSB[i]); + data->temp_high[i] = i2c_smbus_read_byte_data(client, + TMP401_TEMP_HIGH_LIMIT_MSB_READ[i]) << 8; + data->temp_high[i] |= i2c_smbus_read_byte_data(client, + TMP401_TEMP_HIGH_LIMIT_LSB[i]); + data->temp_crit[i] = i2c_smbus_read_byte_data(client, + TMP401_TEMP_CRIT_LIMIT[i]); + + if (data->kind == tmp411) { + data->temp_lowest[i] = i2c_smbus_read_byte_data(client, + TMP411_TEMP_LOWEST_MSB[i]) << 8; + data->temp_lowest[i] |= i2c_smbus_read_byte_data( + client, TMP411_TEMP_LOWEST_LSB[i]); + + data->temp_highest[i] = i2c_smbus_read_byte_data( + client, TMP411_TEMP_HIGHEST_MSB[i]) << 8; + data->temp_highest[i] |= i2c_smbus_read_byte_data( + client, TMP411_TEMP_HIGHEST_LSB[i]); + } + } + return data; +} + +static struct tmp401_data *tmp401_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct tmp401_data *data = i2c_get_clientdata(client); + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { + data->status = i2c_smbus_read_byte_data(client, TMP401_STATUS); + data->config = i2c_smbus_read_byte_data(client, + TMP401_CONFIG_READ); + tmp401_update_device_reg16(client, data); + + data->temp_crit_hyst = i2c_smbus_read_byte_data(client, + TMP401_TEMP_CRIT_HYST); + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + static ssize_t show_temp_value(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -535,6 +577,27 @@ static int tmp401_detect(struct i2c_client *client, return 0; } +static int tmp401_remove(struct i2c_client *client) +{ + struct tmp401_data *data = i2c_get_clientdata(client); + int i; + + if (data->hwmon_dev) + hwmon_device_unregister(data->hwmon_dev); + + for (i = 0; i < ARRAY_SIZE(tmp401_attr); i++) + device_remove_file(&client->dev, &tmp401_attr[i].dev_attr); + + if (data->kind == tmp411) { + for (i = 0; i < ARRAY_SIZE(tmp411_attr); i++) + device_remove_file(&client->dev, + &tmp411_attr[i].dev_attr); + } + + kfree(data); + return 0; +} + static int tmp401_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -587,91 +650,17 @@ exit_remove: return err; } -static int tmp401_remove(struct i2c_client *client) -{ - struct tmp401_data *data = i2c_get_clientdata(client); - int i; - - if (data->hwmon_dev) - hwmon_device_unregister(data->hwmon_dev); - - for (i = 0; i < ARRAY_SIZE(tmp401_attr); i++) - device_remove_file(&client->dev, &tmp401_attr[i].dev_attr); - - if (data->kind == tmp411) { - for (i = 0; i < ARRAY_SIZE(tmp411_attr); i++) - device_remove_file(&client->dev, - &tmp411_attr[i].dev_attr); - } - - kfree(data); - return 0; -} - -static struct tmp401_data *tmp401_update_device_reg16( - struct i2c_client *client, struct tmp401_data *data) -{ - int i; - - for (i = 0; i < 2; i++) { - /* - * High byte must be read first immediately followed - * by the low byte - */ - data->temp[i] = i2c_smbus_read_byte_data(client, - TMP401_TEMP_MSB[i]) << 8; - data->temp[i] |= i2c_smbus_read_byte_data(client, - TMP401_TEMP_LSB[i]); - data->temp_low[i] = i2c_smbus_read_byte_data(client, - TMP401_TEMP_LOW_LIMIT_MSB_READ[i]) << 8; - data->temp_low[i] |= i2c_smbus_read_byte_data(client, - TMP401_TEMP_LOW_LIMIT_LSB[i]); - data->temp_high[i] = i2c_smbus_read_byte_data(client, - TMP401_TEMP_HIGH_LIMIT_MSB_READ[i]) << 8; - data->temp_high[i] |= i2c_smbus_read_byte_data(client, - TMP401_TEMP_HIGH_LIMIT_LSB[i]); - data->temp_crit[i] = i2c_smbus_read_byte_data(client, - TMP401_TEMP_CRIT_LIMIT[i]); - - if (data->kind == tmp411) { - data->temp_lowest[i] = i2c_smbus_read_byte_data(client, - TMP411_TEMP_LOWEST_MSB[i]) << 8; - data->temp_lowest[i] |= i2c_smbus_read_byte_data( - client, TMP411_TEMP_LOWEST_LSB[i]); - - data->temp_highest[i] = i2c_smbus_read_byte_data( - client, TMP411_TEMP_HIGHEST_MSB[i]) << 8; - data->temp_highest[i] |= i2c_smbus_read_byte_data( - client, TMP411_TEMP_HIGHEST_LSB[i]); - } - } - return data; -} - -static struct tmp401_data *tmp401_update_device(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct tmp401_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { - data->status = i2c_smbus_read_byte_data(client, TMP401_STATUS); - data->config = i2c_smbus_read_byte_data(client, - TMP401_CONFIG_READ); - tmp401_update_device_reg16(client, data); - - data->temp_crit_hyst = i2c_smbus_read_byte_data(client, - TMP401_TEMP_CRIT_HYST); - - data->last_updated = jiffies; - data->valid = 1; - } - - mutex_unlock(&data->update_lock); - - return data; -} +static struct i2c_driver tmp401_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "tmp401", + }, + .probe = tmp401_probe, + .remove = tmp401_remove, + .id_table = tmp401_id, + .detect = tmp401_detect, + .address_list = normal_i2c, +}; static int __init tmp401_init(void) { -- cgit v1.2.3 From 4e4a99d32721800c061191027f18f780dcbd9e0b Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Thu, 27 May 2010 19:58:50 +0200 Subject: hwmon: (applesmc) Add support for MacBook Pro 5,3 and 5,4 The MacBookPro 5,3 model has two fans, whereas the 5,4 model has only one. This patch adds explicit support for the 5,3 and 5,4 models. Signed-off-by: Henrik Rydberg Signed-off-by: Jean Delvare --- drivers/hwmon/applesmc.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index f085c18d2905..be33094468db 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -148,6 +148,13 @@ static const char *temperature_sensors_sets[][41] = { /* Set 18: MacBook Pro 2,2 */ { "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "TM0P", "TTF0", "Th0H", "Th1H", "Tm0P", "Ts0P", NULL }, +/* Set 19: Macbook Pro 5,3 */ + { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TG0D", + "TG0F", "TG0H", "TG0P", "TG0T", "TN0D", "TN0P", "TTF0", "Th2H", + "Tm0P", "Ts0P", "Ts0S", NULL }, +/* Set 20: MacBook Pro 5,4 */ + { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TN0D", + "TN0P", "TTF0", "Th2H", "Ts0P", "Ts0S", NULL }, }; /* List of keys used to read/write fan speeds */ @@ -1363,6 +1370,10 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = { { .accelerometer = 0, .light = 0, .temperature_set = 17 }, /* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */ { .accelerometer = 1, .light = 1, .temperature_set = 18 }, +/* MacBook Pro 5,3: accelerometer, backlight and temperature set 19 */ + { .accelerometer = 1, .light = 1, .temperature_set = 19 }, +/* MacBook Pro 5,4: accelerometer, backlight and temperature set 20 */ + { .accelerometer = 1, .light = 1, .temperature_set = 20 }, }; /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". @@ -1376,6 +1387,14 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") }, &applesmc_dmi_data[7]}, + { applesmc_dmi_match, "Apple MacBook Pro 5,4", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,4") }, + &applesmc_dmi_data[20]}, + { applesmc_dmi_match, "Apple MacBook Pro 5,3", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,3") }, + &applesmc_dmi_data[19]}, { applesmc_dmi_match, "Apple MacBook Pro 5", { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") }, -- cgit v1.2.3 From 872bad55e2d3fcc13e1e8770a3b200f0c6ca5126 Mon Sep 17 00:00:00 2001 From: Bernhard Froemel Date: Thu, 27 May 2010 19:58:52 +0200 Subject: hwmon: (applesmc) Add generic support for MacBook Pro 6 This patch adds generic support for the MacBook Pro 6 family based on the 6,2 model. [rydberg@euromail.se: patch cleanup] Signed-off-by: Bernhard Froemel Signed-off-by: Henrik Rydberg Signed-off-by: Jean Delvare --- drivers/hwmon/applesmc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index be33094468db..ce41a437477d 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -155,6 +155,10 @@ static const char *temperature_sensors_sets[][41] = { /* Set 20: MacBook Pro 5,4 */ { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TN0D", "TN0P", "TTF0", "Th2H", "Ts0P", "Ts0S", NULL }, +/* Set 21: MacBook Pro 6,2 */ + { "TB0T", "TB1T", "TB2T", "TC0C", "TC0D", "TC0P", "TC1C", "TG0D", + "TG0P", "TG0T", "TMCD", "TP0P", "TPCD", "Th1H", "Th2H", "Tm0P", + "Ts0P", "Ts0S", NULL }, }; /* List of keys used to read/write fan speeds */ @@ -1374,6 +1378,8 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = { { .accelerometer = 1, .light = 1, .temperature_set = 19 }, /* MacBook Pro 5,4: accelerometer, backlight and temperature set 20 */ { .accelerometer = 1, .light = 1, .temperature_set = 20 }, +/* MacBook Pro 6,2: accelerometer, backlight and temperature set 21 */ + { .accelerometer = 1, .light = 1, .temperature_set = 21 }, }; /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". @@ -1395,6 +1401,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,3") }, &applesmc_dmi_data[19]}, + { applesmc_dmi_match, "Apple MacBook Pro 6", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro6") }, + &applesmc_dmi_data[21]}, { applesmc_dmi_match, "Apple MacBook Pro 5", { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") }, -- cgit v1.2.3 From 405eaa1c1d045cdd872802fc515f638573984880 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Thu, 27 May 2010 19:58:53 +0200 Subject: hwmon: (applesmc) Add generic support for MacBook Pro 7 This patch adds generic support for the MacBook Pro 7 family based on the 7,1 model. Signed-off-by: Henrik Rydberg Signed-off-by: Jean Delvare --- drivers/hwmon/applesmc.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index ce41a437477d..57c033169ac2 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -159,6 +159,9 @@ static const char *temperature_sensors_sets[][41] = { { "TB0T", "TB1T", "TB2T", "TC0C", "TC0D", "TC0P", "TC1C", "TG0D", "TG0P", "TG0T", "TMCD", "TP0P", "TPCD", "Th1H", "Th2H", "Tm0P", "Ts0P", "Ts0S", NULL }, +/* Set 22: MacBook Pro 7,1 */ + { "TB0T", "TB1T", "TB2T", "TC0D", "TC0P", "TN0D", "TN0P", "TN0S", + "TN1D", "TN1F", "TN1G", "TN1S", "Th1H", "Ts0P", "Ts0S", NULL }, }; /* List of keys used to read/write fan speeds */ @@ -1380,6 +1383,8 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = { { .accelerometer = 1, .light = 1, .temperature_set = 20 }, /* MacBook Pro 6,2: accelerometer, backlight and temperature set 21 */ { .accelerometer = 1, .light = 1, .temperature_set = 21 }, +/* MacBook Pro 7,1: accelerometer, backlight and temperature set 22 */ + { .accelerometer = 1, .light = 1, .temperature_set = 22 }, }; /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". @@ -1393,6 +1398,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") }, &applesmc_dmi_data[7]}, + { applesmc_dmi_match, "Apple MacBook Pro 7", { + DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro7") }, + &applesmc_dmi_data[22]}, { applesmc_dmi_match, "Apple MacBook Pro 5,4", { DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,4") }, -- cgit v1.2.3 From fa5575cff92eb43f467b9b00468d70d073e8b3d2 Mon Sep 17 00:00:00 2001 From: Alex Murray Date: Thu, 27 May 2010 19:58:54 +0200 Subject: hwmon: (applesmc) Add temperature sensor labels to sysfs interface The Apple SMC uses a systematic labeling scheme for the hardware temperature sensors. This scheme is currently hidden from userland. Since the sensor set, and consequently the numbering, differs between models, an extensive database of configurations is required for an application such as fan control. This patch adds the SMC labels to the hwmon sysfs interface, allowing applications to use the sensors more intelligibly. [rydberg@euromail.se: fixed error handling] Signed-off-by: Alex Murray Signed-off-by: Henrik Rydberg Signed-off-by: Jean Delvare --- drivers/hwmon/applesmc.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 147 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 57c033169ac2..b6598aa557a0 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -660,6 +660,17 @@ out: return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right); } +/* Displays sensor key as label */ +static ssize_t applesmc_show_sensor_label(struct device *dev, + struct device_attribute *devattr, char *sysfsbuf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + const char *key = + temperature_sensors_sets[applesmc_temperature_set][attr->index]; + + return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key); +} + /* Displays degree Celsius * 1000 */ static ssize_t applesmc_show_temperature(struct device *dev, struct device_attribute *devattr, char *sysfsbuf) @@ -1127,6 +1138,86 @@ static const struct attribute_group fan_attribute_groups[] = { /* * Temperature sensors sysfs entries. */ +static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 0); +static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 1); +static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 2); +static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 3); +static SENSOR_DEVICE_ATTR(temp5_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 4); +static SENSOR_DEVICE_ATTR(temp6_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 5); +static SENSOR_DEVICE_ATTR(temp7_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 6); +static SENSOR_DEVICE_ATTR(temp8_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 7); +static SENSOR_DEVICE_ATTR(temp9_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 8); +static SENSOR_DEVICE_ATTR(temp10_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 9); +static SENSOR_DEVICE_ATTR(temp11_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 10); +static SENSOR_DEVICE_ATTR(temp12_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 11); +static SENSOR_DEVICE_ATTR(temp13_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 12); +static SENSOR_DEVICE_ATTR(temp14_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 13); +static SENSOR_DEVICE_ATTR(temp15_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 14); +static SENSOR_DEVICE_ATTR(temp16_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 15); +static SENSOR_DEVICE_ATTR(temp17_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 16); +static SENSOR_DEVICE_ATTR(temp18_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 17); +static SENSOR_DEVICE_ATTR(temp19_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 18); +static SENSOR_DEVICE_ATTR(temp20_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 19); +static SENSOR_DEVICE_ATTR(temp21_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 20); +static SENSOR_DEVICE_ATTR(temp22_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 21); +static SENSOR_DEVICE_ATTR(temp23_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 22); +static SENSOR_DEVICE_ATTR(temp24_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 23); +static SENSOR_DEVICE_ATTR(temp25_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 24); +static SENSOR_DEVICE_ATTR(temp26_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 25); +static SENSOR_DEVICE_ATTR(temp27_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 26); +static SENSOR_DEVICE_ATTR(temp28_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 27); +static SENSOR_DEVICE_ATTR(temp29_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 28); +static SENSOR_DEVICE_ATTR(temp30_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 29); +static SENSOR_DEVICE_ATTR(temp31_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 30); +static SENSOR_DEVICE_ATTR(temp32_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 31); +static SENSOR_DEVICE_ATTR(temp33_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 32); +static SENSOR_DEVICE_ATTR(temp34_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 33); +static SENSOR_DEVICE_ATTR(temp35_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 34); +static SENSOR_DEVICE_ATTR(temp36_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 35); +static SENSOR_DEVICE_ATTR(temp37_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 36); +static SENSOR_DEVICE_ATTR(temp38_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 37); +static SENSOR_DEVICE_ATTR(temp39_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 38); +static SENSOR_DEVICE_ATTR(temp40_label, S_IRUGO, + applesmc_show_sensor_label, NULL, 39); static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, applesmc_show_temperature, NULL, 0); static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, @@ -1208,6 +1299,50 @@ static SENSOR_DEVICE_ATTR(temp39_input, S_IRUGO, static SENSOR_DEVICE_ATTR(temp40_input, S_IRUGO, applesmc_show_temperature, NULL, 39); +static struct attribute *label_attributes[] = { + &sensor_dev_attr_temp1_label.dev_attr.attr, + &sensor_dev_attr_temp2_label.dev_attr.attr, + &sensor_dev_attr_temp3_label.dev_attr.attr, + &sensor_dev_attr_temp4_label.dev_attr.attr, + &sensor_dev_attr_temp5_label.dev_attr.attr, + &sensor_dev_attr_temp6_label.dev_attr.attr, + &sensor_dev_attr_temp7_label.dev_attr.attr, + &sensor_dev_attr_temp8_label.dev_attr.attr, + &sensor_dev_attr_temp9_label.dev_attr.attr, + &sensor_dev_attr_temp10_label.dev_attr.attr, + &sensor_dev_attr_temp11_label.dev_attr.attr, + &sensor_dev_attr_temp12_label.dev_attr.attr, + &sensor_dev_attr_temp13_label.dev_attr.attr, + &sensor_dev_attr_temp14_label.dev_attr.attr, + &sensor_dev_attr_temp15_label.dev_attr.attr, + &sensor_dev_attr_temp16_label.dev_attr.attr, + &sensor_dev_attr_temp17_label.dev_attr.attr, + &sensor_dev_attr_temp18_label.dev_attr.attr, + &sensor_dev_attr_temp19_label.dev_attr.attr, + &sensor_dev_attr_temp20_label.dev_attr.attr, + &sensor_dev_attr_temp21_label.dev_attr.attr, + &sensor_dev_attr_temp22_label.dev_attr.attr, + &sensor_dev_attr_temp23_label.dev_attr.attr, + &sensor_dev_attr_temp24_label.dev_attr.attr, + &sensor_dev_attr_temp25_label.dev_attr.attr, + &sensor_dev_attr_temp26_label.dev_attr.attr, + &sensor_dev_attr_temp27_label.dev_attr.attr, + &sensor_dev_attr_temp28_label.dev_attr.attr, + &sensor_dev_attr_temp29_label.dev_attr.attr, + &sensor_dev_attr_temp30_label.dev_attr.attr, + &sensor_dev_attr_temp31_label.dev_attr.attr, + &sensor_dev_attr_temp32_label.dev_attr.attr, + &sensor_dev_attr_temp33_label.dev_attr.attr, + &sensor_dev_attr_temp34_label.dev_attr.attr, + &sensor_dev_attr_temp35_label.dev_attr.attr, + &sensor_dev_attr_temp36_label.dev_attr.attr, + &sensor_dev_attr_temp37_label.dev_attr.attr, + &sensor_dev_attr_temp38_label.dev_attr.attr, + &sensor_dev_attr_temp39_label.dev_attr.attr, + &sensor_dev_attr_temp40_label.dev_attr.attr, + NULL +}; + static struct attribute *temperature_attributes[] = { &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp2_input.dev_attr.attr, @@ -1255,6 +1390,10 @@ static struct attribute *temperature_attributes[] = { static const struct attribute_group temperature_attributes_group = { .attrs = temperature_attributes }; +static const struct attribute_group label_attributes_group = { + .attrs = label_attributes +}; + /* Module stuff */ /* @@ -1556,7 +1695,8 @@ static int __init applesmc_init(void) for (i = 0; temperature_sensors_sets[applesmc_temperature_set][i] != NULL; i++) { - if (temperature_attributes[i] == NULL) { + if (temperature_attributes[i] == NULL || + label_attributes[i] == NULL) { printk(KERN_ERR "applesmc: More temperature sensors " "in temperature_sensors_sets (at least %i)" "than available sysfs files in " @@ -1568,6 +1708,10 @@ static int __init applesmc_init(void) temperature_attributes[i]); if (ret) goto out_temperature; + ret = sysfs_create_file(&pdev->dev.kobj, + label_attributes[i]); + if (ret) + goto out_temperature; } if (applesmc_accelerometer) { @@ -1618,6 +1762,7 @@ out_accelerometer: if (applesmc_accelerometer) applesmc_release_accelerometer(); out_temperature: + sysfs_remove_group(&pdev->dev.kobj, &label_attributes_group); sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group); out_fans: while (fans_handled) @@ -1647,6 +1792,7 @@ static void __exit applesmc_exit(void) } if (applesmc_accelerometer) applesmc_release_accelerometer(); + sysfs_remove_group(&pdev->dev.kobj, &label_attributes_group); sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group); while (fans_handled) sysfs_remove_group(&pdev->dev.kobj, -- cgit v1.2.3 From dac6831e67e90d1cee430a66e7390e753c20d835 Mon Sep 17 00:00:00 2001 From: Kalhan Trisal Date: Thu, 27 May 2010 19:58:56 +0200 Subject: hwmon: EMC1403 thermal sensor support Provides support for the EMC1403 thermal sensor. Only reporting of values is supported. The various Moorestown specific extras to do with thermal alerts and the like are not in this version of the driver. Considerably edited and tidied up by Alan Cox, plus fixes and detection bits from Jean Delvare. Signed-off-by: Kalhan Trisal Signed-off-by: Alan Cox Signed-off-by: Jean Delvare --- drivers/hwmon/Kconfig | 10 ++ drivers/hwmon/Makefile | 1 + drivers/hwmon/emc1403.c | 344 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 355 insertions(+) create mode 100644 drivers/hwmon/emc1403.c (limited to 'drivers') diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index fa609586c7c9..6dddad81281e 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -750,6 +750,16 @@ config SENSORS_DME1737 This driver can also be built as a module. If so, the module will be called dme1737. +config SENSORS_EMC1403 + tristate "SMSC EMC1403 thermal sensor" + depends on I2C + help + If you say yes here you get support for the SMSC EMC1403 + temperature monitoring chip. + + Threshold values can be configured using sysfs. + Data from the different diodes are accessible via sysfs. + config SENSORS_SMSC47M1 tristate "SMSC LPC47M10x and compatibles" help diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 86920fb34118..9b1364a4bd85 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o obj-$(CONFIG_SENSORS_DME1737) += dme1737.o obj-$(CONFIG_SENSORS_DS1621) += ds1621.o +obj-$(CONFIG_SENSORS_EMC1403) += emc1403.o obj-$(CONFIG_SENSORS_F71805F) += f71805f.o obj-$(CONFIG_SENSORS_F71882FG) += f71882fg.o obj-$(CONFIG_SENSORS_F75375S) += f75375s.o diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c new file mode 100644 index 000000000000..0e4b5642638d --- /dev/null +++ b/drivers/hwmon/emc1403.c @@ -0,0 +1,344 @@ +/* + * emc1403.c - SMSC Thermal Driver + * + * Copyright (C) 2008 Intel Corp + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * TODO + * - cache alarm and critical limit registers + * - add emc1404 support + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define THERMAL_PID_REG 0xfd +#define THERMAL_SMSC_ID_REG 0xfe +#define THERMAL_REVISION_REG 0xff + +struct thermal_data { + struct device *hwmon_dev; + struct mutex mutex; + /* Cache the hyst value so we don't keep re-reading it. In theory + we could cache it forever as nobody else should be writing it. */ + u8 cached_hyst; + unsigned long hyst_valid; +}; + +static ssize_t show_temp(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + int retval = i2c_smbus_read_byte_data(client, sda->index); + + if (retval < 0) + return retval; + return sprintf(buf, "%d000\n", retval); +} + +static ssize_t show_bit(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sensor_device_attribute_2 *sda = to_sensor_dev_attr_2(attr); + int retval = i2c_smbus_read_byte_data(client, sda->nr); + + if (retval < 0) + return retval; + retval &= sda->index; + return sprintf(buf, "%d\n", retval ? 1 : 0); +} + +static ssize_t store_temp(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + struct i2c_client *client = to_i2c_client(dev); + unsigned long val; + int retval; + + if (strict_strtoul(buf, 10, &val)) + return -EINVAL; + retval = i2c_smbus_write_byte_data(client, sda->index, + DIV_ROUND_CLOSEST(val, 1000)); + if (retval < 0) + return retval; + return count; +} + +static ssize_t show_hyst(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct thermal_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + int retval; + int hyst; + + retval = i2c_smbus_read_byte_data(client, sda->index); + if (retval < 0) + return retval; + + if (time_after(jiffies, data->hyst_valid)) { + hyst = i2c_smbus_read_byte_data(client, 0x21); + if (hyst < 0) + return retval; + data->cached_hyst = hyst; + data->hyst_valid = jiffies + HZ; + } + return sprintf(buf, "%d000\n", retval - data->cached_hyst); +} + +static ssize_t store_hyst(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct thermal_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + int retval; + int hyst; + unsigned long val; + + if (strict_strtoul(buf, 10, &val)) + return -EINVAL; + + mutex_lock(&data->mutex); + retval = i2c_smbus_read_byte_data(client, sda->index); + if (retval < 0) + goto fail; + + hyst = val - retval * 1000; + hyst = DIV_ROUND_CLOSEST(hyst, 1000); + if (hyst < 0 || hyst > 255) { + retval = -ERANGE; + goto fail; + } + + retval = i2c_smbus_write_byte_data(client, 0x21, hyst); + if (retval == 0) { + retval = count; + data->cached_hyst = hyst; + data->hyst_valid = jiffies + HZ; + } +fail: + mutex_unlock(&data->mutex); + return retval; +} + +/* + * Sensors. We pass the actual i2c register to the methods. + */ + +static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x06); +static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x05); +static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x20); +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0x00); +static SENSOR_DEVICE_ATTR_2(temp1_min_alarm, S_IRUGO, + show_bit, NULL, 0x36, 0x01); +static SENSOR_DEVICE_ATTR_2(temp1_max_alarm, S_IRUGO, + show_bit, NULL, 0x35, 0x01); +static SENSOR_DEVICE_ATTR_2(temp1_crit_alarm, S_IRUGO, + show_bit, NULL, 0x37, 0x01); +static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO | S_IWUSR, + show_hyst, store_hyst, 0x20); + +static SENSOR_DEVICE_ATTR(temp2_min, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x08); +static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x07); +static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x19); +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0x01); +static SENSOR_DEVICE_ATTR_2(temp2_min_alarm, S_IRUGO, + show_bit, NULL, 0x36, 0x02); +static SENSOR_DEVICE_ATTR_2(temp2_max_alarm, S_IRUGO, + show_bit, NULL, 0x35, 0x02); +static SENSOR_DEVICE_ATTR_2(temp2_crit_alarm, S_IRUGO, + show_bit, NULL, 0x37, 0x02); +static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO | S_IWUSR, + show_hyst, store_hyst, 0x19); + +static SENSOR_DEVICE_ATTR(temp3_min, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x16); +static SENSOR_DEVICE_ATTR(temp3_max, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x15); +static SENSOR_DEVICE_ATTR(temp3_crit, S_IRUGO | S_IWUSR, + show_temp, store_temp, 0x1A); +static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 0x23); +static SENSOR_DEVICE_ATTR_2(temp3_min_alarm, S_IRUGO, + show_bit, NULL, 0x36, 0x04); +static SENSOR_DEVICE_ATTR_2(temp3_max_alarm, S_IRUGO, + show_bit, NULL, 0x35, 0x04); +static SENSOR_DEVICE_ATTR_2(temp3_crit_alarm, S_IRUGO, + show_bit, NULL, 0x37, 0x04); +static SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO | S_IWUSR, + show_hyst, store_hyst, 0x1A); + +static struct attribute *mid_att_thermal[] = { + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_crit.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp3_crit.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_crit_hyst.dev_attr.attr, + NULL +}; + +static const struct attribute_group m_thermal_gr = { + .attrs = mid_att_thermal +}; + +static int emc1403_detect(struct i2c_client *client, + struct i2c_board_info *info) +{ + int id; + /* Check if thermal chip is SMSC and EMC1403 */ + + id = i2c_smbus_read_byte_data(client, THERMAL_SMSC_ID_REG); + if (id != 0x5d) + return -ENODEV; + + /* Note: 0x25 is the 1404 which is very similar and this + driver could be extended */ + id = i2c_smbus_read_byte_data(client, THERMAL_PID_REG); + if (id != 0x21) + return -ENODEV; + + id = i2c_smbus_read_byte_data(client, THERMAL_REVISION_REG); + if (id != 0x01) + return -ENODEV; + + strlcpy(info->type, "emc1403", I2C_NAME_SIZE); + return 0; +} + +static int emc1403_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int res; + struct thermal_data *data; + + data = kzalloc(sizeof(struct thermal_data), GFP_KERNEL); + if (data == NULL) { + dev_warn(&client->dev, "out of memory"); + return -ENOMEM; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->mutex); + data->hyst_valid = jiffies - 1; /* Expired */ + + res = sysfs_create_group(&client->dev.kobj, &m_thermal_gr); + if (res) { + dev_warn(&client->dev, "create group failed\n"); + hwmon_device_unregister(data->hwmon_dev); + goto thermal_error1; + } + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + res = PTR_ERR(data->hwmon_dev); + dev_warn(&client->dev, "register hwmon dev failed\n"); + goto thermal_error2; + } + dev_info(&client->dev, "EMC1403 Thermal chip found\n"); + return res; + +thermal_error2: + sysfs_remove_group(&client->dev.kobj, &m_thermal_gr); +thermal_error1: + kfree(data); + return res; +} + +static int emc1403_remove(struct i2c_client *client) +{ + struct thermal_data *data = i2c_get_clientdata(client); + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &m_thermal_gr); + kfree(data); + return 0; +} + +static const unsigned short emc1403_address_list[] = { + 0x18, 0x2a, 0x4c, 0x4d, I2C_CLIENT_END +}; + +static const struct i2c_device_id emc1403_idtable[] = { + { "emc1403", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, emc1403_idtable); + +static struct i2c_driver sensor_emc1403 = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "emc1403", + }, + .detect = emc1403_detect, + .probe = emc1403_probe, + .remove = emc1403_remove, + .id_table = emc1403_idtable, + .address_list = emc1403_address_list, +}; + +static int __init sensor_emc1403_init(void) +{ + return i2c_add_driver(&sensor_emc1403); +} + +static void __exit sensor_emc1403_exit(void) +{ + i2c_del_driver(&sensor_emc1403); +} + +module_init(sensor_emc1403_init); +module_exit(sensor_emc1403_exit); + +MODULE_AUTHOR("Kalhan Trisal Date: Thu, 27 May 2010 19:58:56 +0200 Subject: hwmon: Driver for TI TMP102 temperature sensor Driver for the TI TMP102. The TI TMP102 is similar to the LM75. It differs from the LM75 by having a 16-bit conf register and the temp registers have a minimum resolution of 12 bits; the extended conf register can select 13-bit resolution (which this driver does) and also change the update rate (which this driver currently doesn't use). [JD: Fix tmp102_exit tag, must be __exit, not __init.] Signed-off-by: Steven King Signed-off-by: Jean Delvare --- Documentation/hwmon/tmp102 | 27 +++++ drivers/hwmon/Kconfig | 10 ++ drivers/hwmon/Makefile | 1 + drivers/hwmon/tmp102.c | 297 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 335 insertions(+) create mode 100644 Documentation/hwmon/tmp102 create mode 100644 drivers/hwmon/tmp102.c (limited to 'drivers') diff --git a/Documentation/hwmon/tmp102 b/Documentation/hwmon/tmp102 new file mode 100644 index 000000000000..239dded8539f --- /dev/null +++ b/Documentation/hwmon/tmp102 @@ -0,0 +1,27 @@ +Kernel driver tmp102 +==================== + +Supported chips: + * Texas Instruments TMP102 + Prefix: 'tmp102' + Addresses scanned: I2C 0x48 0x49 0x4a 0x4b + Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp102.html + +Author: + Steven King + +Description +----------- + +The Texas Instruments TMP102 implements one temperature sensor. Limits can be +set through the Overtemperature Shutdown register and Hysteresis register. The +sensor is accurate to 0.5 degrees over the range of -25 to +85 C, and to 1.0 +degrees from -40 to +125 C. Resolution of the sensor is 0.0625 degree. The +operating temperature has a minimum of -55 C and a maximum of +150 C. + +The TMP102 has a programmable update rate that can select between 8, 4, 1, and +0.5 Hz. (Currently the driver only supports the default of 4 Hz). + +The driver provides the common sysfs-interface for temperatures (see +/Documentation/hwmon/sysfs-interface under Temperatures). + diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 6dddad81281e..6d87892a6639 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -842,6 +842,16 @@ config SENSORS_THMC50 This driver can also be built as a module. If so, the module will be called thmc50. +config SENSORS_TMP102 + tristate "Texas Instruments TMP102 and compatibles" + depends on I2C && EXPERIMENTAL + help + If you say yes here you get support for Texas Instruments TMP102 + sensor chips. + + This driver can also be built as a module. If so, the module + will be called tmp102. + config SENSORS_TMP401 tristate "Texas Instruments TMP401 and compatibles" depends on I2C && EXPERIMENTAL diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 9b1364a4bd85..2138ceb1a713 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -91,6 +91,7 @@ obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o obj-$(CONFIG_SENSORS_THMC50) += thmc50.o +obj-$(CONFIG_SENSORS_TMP102) += tmp102.o obj-$(CONFIG_SENSORS_TMP401) += tmp401.o obj-$(CONFIG_SENSORS_TMP421) += tmp421.o obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c new file mode 100644 index 000000000000..e4def62c0ebf --- /dev/null +++ b/drivers/hwmon/tmp102.c @@ -0,0 +1,297 @@ +/* Texas Instruments TMP102 SMBUS temperature sensor driver + * + * Copyright 2010 Steven King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "tmp102" + +#define TMP102_TEMP_REG 0x00 +#define TMP102_CONF_REG 0x01 +/* note: these bit definitions are byte swapped */ +#define TMP102_CONF_SD 0x0100 +#define TMP102_CONF_TM 0x0200 +#define TMP102_CONF_POL 0x0400 +#define TMP102_CONF_F0 0x0800 +#define TMP102_CONF_F1 0x1000 +#define TMP102_CONF_R0 0x2000 +#define TMP102_CONF_R1 0x4000 +#define TMP102_CONF_OS 0x8000 +#define TMP102_CONF_EM 0x0010 +#define TMP102_CONF_AL 0x0020 +#define TMP102_CONF_CR0 0x0040 +#define TMP102_CONF_CR1 0x0080 +#define TMP102_TLOW_REG 0x02 +#define TMP102_THIGH_REG 0x03 + +struct tmp102 { + struct device *hwmon_dev; + struct mutex lock; + unsigned long last_update; + int temp[3]; +}; + +/* the TMP102 registers are big endian so we have to swab16 the values */ +static int tmp102_read_reg(struct i2c_client *client, u8 reg) +{ + int result = i2c_smbus_read_word_data(client, reg); + return result < 0 ? result : swab16(result); +} + +static int tmp102_write_reg(struct i2c_client *client, u8 reg, u16 val) +{ + return i2c_smbus_write_word_data(client, reg, swab16(val)); +} + +/* convert left adjusted 13bit TMP102 register value to miliCelsius */ +static int tmp102_reg_to_mC(s16 val) +{ + return (val * 1000) / 128; +} + +/* convert miliCelsius to left adjusted 13bit TMP102 register value */ +static u16 tmp102_mC_to_reg(int val) +{ + return (val * 128) / 1000; +} + +static const u8 tmp102_reg[] = { + TMP102_TEMP_REG, + TMP102_TLOW_REG, + TMP102_THIGH_REG, +}; + +static struct tmp102 *tmp102_update_device(struct i2c_client *client) +{ + struct tmp102 *tmp102 = i2c_get_clientdata(client); + + mutex_lock(&tmp102->lock); + if (time_after(jiffies, tmp102->last_update + HZ / 4)) { + int i; + for (i = 0; i < ARRAY_SIZE(tmp102->temp); ++i) { + int status = tmp102_read_reg(client, tmp102_reg[i]); + if (status > -1) + tmp102->temp[i] = tmp102_reg_to_mC(status); + } + tmp102->last_update = jiffies; + } + mutex_unlock(&tmp102->lock); + return tmp102; +} + +static ssize_t tmp102_show_temp(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + struct tmp102 *tmp102 = tmp102_update_device(to_i2c_client(dev)); + + return sprintf(buf, "%d\n", tmp102->temp[sda->index]); +} + +static ssize_t tmp102_set_temp(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); + struct i2c_client *client = to_i2c_client(dev); + struct tmp102 *tmp102 = i2c_get_clientdata(client); + long val; + int status = 0; + + if ((strict_strtol(buf, 10, &val) < 0) || (abs(val) > 150000)) + return -EINVAL; + mutex_lock(&tmp102->lock); + if (tmp102->temp[sda->index] != val) { + tmp102->temp[sda->index] = val; + status = tmp102_write_reg(client, tmp102_reg[sda->index], + tmp102_mC_to_reg(val)); + } + mutex_unlock(&tmp102->lock); + return status ? : count; +} + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, tmp102_show_temp, NULL , 0); + +static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, tmp102_show_temp, + tmp102_set_temp, 1); + +static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, tmp102_show_temp, + tmp102_set_temp, 2); + +static struct attribute *tmp102_attributes[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + NULL +}; + +static const struct attribute_group tmp102_attr_group = { + .attrs = tmp102_attributes, +}; + +#define TMP102_CONFIG (TMP102_CONF_TM | TMP102_CONF_EM | TMP102_CONF_CR1) +#define TMP102_CONFIG_RD_ONLY (TMP102_CONF_R0 | TMP102_CONF_R1 | TMP102_CONF_AL) + +static int __devinit tmp102_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct tmp102 *tmp102; + int status; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA)) { + dev_dbg(&client->dev, "adapter doesnt support SMBUS\n"); + return -ENODEV; + } + + tmp102 = kzalloc(sizeof(*tmp102), GFP_KERNEL); + if (!tmp102) { + dev_dbg(&client->dev, "kzalloc failed\n"); + return -ENOMEM; + } + i2c_set_clientdata(client, tmp102); + + tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONFIG); + status = tmp102_read_reg(client, TMP102_CONF_REG); + if (status < 0) { + dev_dbg(&client->dev, "error reading config register\n"); + goto fail0; + } + status &= ~TMP102_CONFIG_RD_ONLY; + if (status != TMP102_CONFIG) { + dev_dbg(&client->dev, "could not verify config settings\n"); + status = -EIO; + goto fail0; + } + tmp102->last_update = jiffies - HZ; + mutex_init(&tmp102->lock); + + status = sysfs_create_group(&client->dev.kobj, &tmp102_attr_group); + if (status) { + dev_dbg(&client->dev, "could not create sysfs files\n"); + goto fail0; + } + tmp102->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(tmp102->hwmon_dev)) { + dev_dbg(&client->dev, "unable to register hwmon device\n"); + status = PTR_ERR(tmp102->hwmon_dev); + goto fail1; + } + + dev_info(&client->dev, "initialized\n"); + + return 0; +fail1: + sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); +fail0: + i2c_set_clientdata(client, NULL); + kfree(tmp102); + + return 0; +} + +static int __devexit tmp102_remove(struct i2c_client *client) +{ + struct tmp102 *tmp102 = i2c_get_clientdata(client); + + /* shutdown the chip */ + tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONF_SD); + + hwmon_device_unregister(tmp102->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); + i2c_set_clientdata(client, NULL); + kfree(tmp102); + + return 0; +} + +#ifdef CONFIG_PM +static int tmp102_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + + tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONF_SD); + + return 0; +} + +static int tmp102_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + + tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONFIG); + + return 0; +} + +static const struct dev_pm_ops tmp102_dev_pm_ops = { + .suspend = tmp102_suspend, + .resume = tmp102_resume, +}; + +#define TMP102_DEV_PM_OPS (&tmp102_dev_pm_ops) +#else +#define TMP102_DEV_PM_OPS NULL +#endif /* CONFIG_PM */ + +static const unsigned short normal_i2c[] = { + 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END +}; + +static const struct i2c_device_id tmp102_id[] = { + { DRIVER_NAME, 0 }, + { } +}; + +static struct i2c_driver tmp102_driver = { + .driver.name = DRIVER_NAME, + .driver.pm = TMP102_DEV_PM_OPS, + .class = I2C_CLASS_HWMON, + .probe = tmp102_probe, + .remove = __devexit_p(tmp102_remove), + .id_table = tmp102_id, + .address_list = normal_i2c, +}; + +static int __init tmp102_init(void) +{ + return i2c_add_driver(&tmp102_driver); +} +module_init(tmp102_init); + +static void __exit tmp102_exit(void) +{ + i2c_del_driver(&tmp102_driver); +} +module_exit(tmp102_exit); + + +MODULE_AUTHOR("Steven King "); +MODULE_DESCRIPTION("Texas Instruments TMP102 temperature sensor driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From cff37c9e82e022068840b3d33167e64c6a0ecc06 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 27 May 2010 19:58:57 +0200 Subject: hwmon: (tmp102) Various fixes Fixes from my driver review: http://lists.lm-sensors.org/pipermail/lm-sensors/2010-March/028051.html Only the small changes are in there, more important changes will come later separately as time permits. * Drop the remnants of the now gone detect function * The TMP102 has no known compatible chip * Include the right header files * Clarify why byte swapping of register values is needed * Strip resolution info bit from temperature register value * Set cache lifetime to 1/3 second * Don't arbitrarily reject limit values; clamp as needed * Make limit writing unconditional * Don't check for transaction types the driver doesn't use * Properly check for error when setting configuration * Report error on failed probe * Make the driver load automatically where needed * Various other minor fixes Signed-off-by: Jean Delvare Cc: Steven King --- Documentation/hwmon/tmp102 | 9 +++--- drivers/hwmon/Kconfig | 2 +- drivers/hwmon/tmp102.c | 70 ++++++++++++++++++++++------------------------ 3 files changed, 39 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/Documentation/hwmon/tmp102 b/Documentation/hwmon/tmp102 index 239dded8539f..8454a7763122 100644 --- a/Documentation/hwmon/tmp102 +++ b/Documentation/hwmon/tmp102 @@ -4,7 +4,7 @@ Kernel driver tmp102 Supported chips: * Texas Instruments TMP102 Prefix: 'tmp102' - Addresses scanned: I2C 0x48 0x49 0x4a 0x4b + Addresses scanned: none Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp102.html Author: @@ -15,13 +15,12 @@ Description The Texas Instruments TMP102 implements one temperature sensor. Limits can be set through the Overtemperature Shutdown register and Hysteresis register. The -sensor is accurate to 0.5 degrees over the range of -25 to +85 C, and to 1.0 -degrees from -40 to +125 C. Resolution of the sensor is 0.0625 degree. The +sensor is accurate to 0.5 degree over the range of -25 to +85 C, and to 1.0 +degree from -40 to +125 C. Resolution of the sensor is 0.0625 degree. The operating temperature has a minimum of -55 C and a maximum of +150 C. The TMP102 has a programmable update rate that can select between 8, 4, 1, and 0.5 Hz. (Currently the driver only supports the default of 4 Hz). The driver provides the common sysfs-interface for temperatures (see -/Documentation/hwmon/sysfs-interface under Temperatures). - +Documentation/hwmon/sysfs-interface under Temperatures). diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 6d87892a6639..de22ae41f758 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -843,7 +843,7 @@ config SENSORS_THMC50 will be called thmc50. config SENSORS_TMP102 - tristate "Texas Instruments TMP102 and compatibles" + tristate "Texas Instruments TMP102" depends on I2C && EXPERIMENTAL help If you say yes here you get support for Texas Instruments TMP102 diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c index e4def62c0ebf..e9de28df0e4d 100644 --- a/drivers/hwmon/tmp102.c +++ b/drivers/hwmon/tmp102.c @@ -1,6 +1,6 @@ -/* Texas Instruments TMP102 SMBUS temperature sensor driver +/* Texas Instruments TMP102 SMBus temperature sensor driver * - * Copyright 2010 Steven King + * Copyright (C) 2010 Steven King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA */ - - #include #include #include @@ -27,7 +25,7 @@ #include #include #include -#include +#include #define DRIVER_NAME "tmp102" @@ -56,26 +54,27 @@ struct tmp102 { int temp[3]; }; -/* the TMP102 registers are big endian so we have to swab16 the values */ -static int tmp102_read_reg(struct i2c_client *client, u8 reg) +/* SMBus specifies low byte first, but the TMP102 returns high byte first, + * so we have to swab16 the values */ +static inline int tmp102_read_reg(struct i2c_client *client, u8 reg) { int result = i2c_smbus_read_word_data(client, reg); return result < 0 ? result : swab16(result); } -static int tmp102_write_reg(struct i2c_client *client, u8 reg, u16 val) +static inline int tmp102_write_reg(struct i2c_client *client, u8 reg, u16 val) { return i2c_smbus_write_word_data(client, reg, swab16(val)); } -/* convert left adjusted 13bit TMP102 register value to miliCelsius */ -static int tmp102_reg_to_mC(s16 val) +/* convert left adjusted 13-bit TMP102 register value to milliCelsius */ +static inline int tmp102_reg_to_mC(s16 val) { - return (val * 1000) / 128; + return ((val & ~0x01) * 1000) / 128; } -/* convert miliCelsius to left adjusted 13bit TMP102 register value */ -static u16 tmp102_mC_to_reg(int val) +/* convert milliCelsius to left adjusted 13-bit TMP102 register value */ +static inline u16 tmp102_mC_to_reg(int val) { return (val * 128) / 1000; } @@ -91,7 +90,7 @@ static struct tmp102 *tmp102_update_device(struct i2c_client *client) struct tmp102 *tmp102 = i2c_get_clientdata(client); mutex_lock(&tmp102->lock); - if (time_after(jiffies, tmp102->last_update + HZ / 4)) { + if (time_after(jiffies, tmp102->last_update + HZ / 3)) { int i; for (i = 0; i < ARRAY_SIZE(tmp102->temp); ++i) { int status = tmp102_read_reg(client, tmp102_reg[i]); @@ -122,16 +121,16 @@ static ssize_t tmp102_set_temp(struct device *dev, struct i2c_client *client = to_i2c_client(dev); struct tmp102 *tmp102 = i2c_get_clientdata(client); long val; - int status = 0; + int status; - if ((strict_strtol(buf, 10, &val) < 0) || (abs(val) > 150000)) + if (strict_strtol(buf, 10, &val) < 0) return -EINVAL; + val = SENSORS_LIMIT(val, -256000, 255000); + mutex_lock(&tmp102->lock); - if (tmp102->temp[sda->index] != val) { - tmp102->temp[sda->index] = val; - status = tmp102_write_reg(client, tmp102_reg[sda->index], - tmp102_mC_to_reg(val)); - } + tmp102->temp[sda->index] = val; + status = tmp102_write_reg(client, tmp102_reg[sda->index], + tmp102_mC_to_reg(val)); mutex_unlock(&tmp102->lock); return status ? : count; } @@ -164,9 +163,10 @@ static int __devinit tmp102_probe(struct i2c_client *client, struct tmp102 *tmp102; int status; - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) { - dev_dbg(&client->dev, "adapter doesnt support SMBUS\n"); + dev_err(&client->dev, "adapter doesnt support SMBus word " + "transactions\n"); return -ENODEV; } @@ -177,16 +177,20 @@ static int __devinit tmp102_probe(struct i2c_client *client, } i2c_set_clientdata(client, tmp102); - tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONFIG); + status = tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONFIG); + if (status < 0) { + dev_err(&client->dev, "error writing config register\n"); + goto fail0; + } status = tmp102_read_reg(client, TMP102_CONF_REG); if (status < 0) { - dev_dbg(&client->dev, "error reading config register\n"); + dev_err(&client->dev, "error reading config register\n"); goto fail0; } status &= ~TMP102_CONFIG_RD_ONLY; if (status != TMP102_CONFIG) { - dev_dbg(&client->dev, "could not verify config settings\n"); - status = -EIO; + dev_err(&client->dev, "config settings did not stick\n"); + status = -ENODEV; goto fail0; } tmp102->last_update = jiffies - HZ; @@ -213,7 +217,7 @@ fail0: i2c_set_clientdata(client, NULL); kfree(tmp102); - return 0; + return status; } static int __devexit tmp102_remove(struct i2c_client *client) @@ -260,23 +264,18 @@ static const struct dev_pm_ops tmp102_dev_pm_ops = { #define TMP102_DEV_PM_OPS NULL #endif /* CONFIG_PM */ -static const unsigned short normal_i2c[] = { - 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END -}; - static const struct i2c_device_id tmp102_id[] = { - { DRIVER_NAME, 0 }, + { "tmp102", 0 }, { } }; +MODULE_DEVICE_TABLE(i2c, tmp102_id); static struct i2c_driver tmp102_driver = { .driver.name = DRIVER_NAME, .driver.pm = TMP102_DEV_PM_OPS, - .class = I2C_CLASS_HWMON, .probe = tmp102_probe, .remove = __devexit_p(tmp102_remove), .id_table = tmp102_id, - .address_list = normal_i2c, }; static int __init tmp102_init(void) @@ -291,7 +290,6 @@ static void __exit tmp102_exit(void) } module_exit(tmp102_exit); - MODULE_AUTHOR("Steven King "); MODULE_DESCRIPTION("Texas Instruments TMP102 temperature sensor driver"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 8d4dee98b10050db9c32a449e460a2f69bb558ec Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 27 May 2010 19:58:58 +0200 Subject: hwmon: (tmp102) Fix suspend and resume functions Suspend and resume functions shouldn't overwrite the configuration register. They should only alter the one bit they have to touch. Also don't assume that register reads and writes always succeed. Handle errors properly, shall they happen. Signed-off-by: Jean Delvare Cc: Steven King --- drivers/hwmon/tmp102.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c index e9de28df0e4d..0da695d800c5 100644 --- a/drivers/hwmon/tmp102.c +++ b/drivers/hwmon/tmp102.c @@ -239,19 +239,27 @@ static int __devexit tmp102_remove(struct i2c_client *client) static int tmp102_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); + int config; - tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONF_SD); + config = tmp102_read_reg(client, TMP102_CONF_REG); + if (config < 0) + return config; - return 0; + config |= TMP102_CONF_SD; + return tmp102_write_reg(client, TMP102_CONF_REG, config); } static int tmp102_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); + int config; - tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONFIG); + config = tmp102_read_reg(client, TMP102_CONF_REG); + if (config < 0) + return config; - return 0; + config &= ~TMP102_CONF_SD; + return tmp102_write_reg(client, TMP102_CONF_REG, config); } static const struct dev_pm_ops tmp102_dev_pm_ops = { -- cgit v1.2.3 From 38806bda6b7c8473c47a967a514260c1a1c32c2e Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 27 May 2010 19:58:59 +0200 Subject: hwmon: (tmp102) Don't always stop chip at exit Only stop the chip at driver exit if it was stopped when driver was loaded. Leave it running otherwise. Also restore the device configuration if probe failed, to not leave the system in a dangling state. Signed-off-by: Jean Delvare Cc: Steven King --- drivers/hwmon/tmp102.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c index 0da695d800c5..8013895a1faf 100644 --- a/drivers/hwmon/tmp102.c +++ b/drivers/hwmon/tmp102.c @@ -50,6 +50,7 @@ struct tmp102 { struct device *hwmon_dev; struct mutex lock; + u16 config_orig; unsigned long last_update; int temp[3]; }; @@ -177,21 +178,27 @@ static int __devinit tmp102_probe(struct i2c_client *client, } i2c_set_clientdata(client, tmp102); + status = tmp102_read_reg(client, TMP102_CONF_REG); + if (status < 0) { + dev_err(&client->dev, "error reading config register\n"); + goto fail_free; + } + tmp102->config_orig = status; status = tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONFIG); if (status < 0) { dev_err(&client->dev, "error writing config register\n"); - goto fail0; + goto fail_restore_config; } status = tmp102_read_reg(client, TMP102_CONF_REG); if (status < 0) { dev_err(&client->dev, "error reading config register\n"); - goto fail0; + goto fail_restore_config; } status &= ~TMP102_CONFIG_RD_ONLY; if (status != TMP102_CONFIG) { dev_err(&client->dev, "config settings did not stick\n"); status = -ENODEV; - goto fail0; + goto fail_restore_config; } tmp102->last_update = jiffies - HZ; mutex_init(&tmp102->lock); @@ -199,21 +206,24 @@ static int __devinit tmp102_probe(struct i2c_client *client, status = sysfs_create_group(&client->dev.kobj, &tmp102_attr_group); if (status) { dev_dbg(&client->dev, "could not create sysfs files\n"); - goto fail0; + goto fail_restore_config; } tmp102->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(tmp102->hwmon_dev)) { dev_dbg(&client->dev, "unable to register hwmon device\n"); status = PTR_ERR(tmp102->hwmon_dev); - goto fail1; + goto fail_remove_sysfs; } dev_info(&client->dev, "initialized\n"); return 0; -fail1: + +fail_remove_sysfs: sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); -fail0: +fail_restore_config: + tmp102_write_reg(client, TMP102_CONF_REG, tmp102->config_orig); +fail_free: i2c_set_clientdata(client, NULL); kfree(tmp102); @@ -224,11 +234,19 @@ static int __devexit tmp102_remove(struct i2c_client *client) { struct tmp102 *tmp102 = i2c_get_clientdata(client); - /* shutdown the chip */ - tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONF_SD); - hwmon_device_unregister(tmp102->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); + + /* Stop monitoring if device was stopped originally */ + if (tmp102->config_orig & TMP102_CONF_SD) { + int config; + + config = tmp102_read_reg(client, TMP102_CONF_REG); + if (config >= 0) + tmp102_write_reg(client, TMP102_CONF_REG, + config | TMP102_CONF_SD); + } + i2c_set_clientdata(client, NULL); kfree(tmp102); -- cgit v1.2.3 From ea694431f9c862bd409c90ba1cb3bdc6fdde8635 Mon Sep 17 00:00:00 2001 From: Juerg Haefliger Date: Thu, 27 May 2010 19:59:01 +0200 Subject: hwmon: (dme1737) Add SCH5127 support Add support for the hardware monitoring capabilities of the SCH5127 chip to the dme1737 driver. Signed-off-by: Juerg Haefliger Signed-off-by: Jean Delvare Tested-by: Jeff Rickman --- Documentation/hwmon/dme1737 | 51 +++++-- drivers/hwmon/dme1737.c | 328 ++++++++++++++++++++++++++++++-------------- 2 files changed, 266 insertions(+), 113 deletions(-) (limited to 'drivers') diff --git a/Documentation/hwmon/dme1737 b/Documentation/hwmon/dme1737 index 001d2e70bc11..fc5df7654d63 100644 --- a/Documentation/hwmon/dme1737 +++ b/Documentation/hwmon/dme1737 @@ -9,11 +9,15 @@ Supported chips: * SMSC SCH3112, SCH3114, SCH3116 Prefix: 'sch311x' Addresses scanned: none, address read from Super-I/O config space - Datasheet: http://www.nuhorizons.com/FeaturedProducts/Volume1/SMSC/311x.pdf + Datasheet: Available on the Internet * SMSC SCH5027 Prefix: 'sch5027' Addresses scanned: I2C 0x2c, 0x2d, 0x2e Datasheet: Provided by SMSC upon request and under NDA + * SMSC SCH5127 + Prefix: 'sch5127' + Addresses scanned: none, address read from Super-I/O config space + Datasheet: Provided by SMSC upon request and under NDA Authors: Juerg Haefliger @@ -36,8 +40,8 @@ Description ----------- This driver implements support for the hardware monitoring capabilities of the -SMSC DME1737 and Asus A8000 (which are the same), SMSC SCH5027, and SMSC -SCH311x Super-I/O chips. These chips feature monitoring of 3 temp sensors +SMSC DME1737 and Asus A8000 (which are the same), SMSC SCH5027, SCH311x, +and SCH5127 Super-I/O chips. These chips feature monitoring of 3 temp sensors temp[1-3] (2 remote diodes and 1 internal), 7 voltages in[0-6] (6 external and 1 internal) and up to 6 fan speeds fan[1-6]. Additionally, the chips implement up to 5 PWM outputs pwm[1-3,5-6] for controlling fan speeds both manually and @@ -48,14 +52,14 @@ Fan[3-6] and pwm[3,5-6] are optional features and their availability depends on the configuration of the chip. The driver will detect which features are present during initialization and create the sysfs attributes accordingly. -For the SCH311x, fan[1-3] and pwm[1-3] are always present and fan[4-6] and -pwm[5-6] don't exist. +For the SCH311x and SCH5127, fan[1-3] and pwm[1-3] are always present and +fan[4-6] and pwm[5-6] don't exist. The hardware monitoring features of the DME1737, A8000, and SCH5027 are only -accessible via SMBus, while the SCH311x only provides access via the ISA bus. -The driver will therefore register itself as an I2C client driver if it detects -a DME1737, A8000, or SCH5027 and as a platform driver if it detects a SCH311x -chip. +accessible via SMBus, while the SCH311x and SCH5127 only provide access via +the ISA bus. The driver will therefore register itself as an I2C client driver +if it detects a DME1737, A8000, or SCH5027 and as a platform driver if it +detects a SCH311x or SCH5127 chip. Voltage Monitoring @@ -76,7 +80,7 @@ DME1737, A8000: in6: Vbat (+3.0V) 0V - 4.38V SCH311x: - in0: +2.5V 0V - 6.64V + in0: +2.5V 0V - 3.32V in1: Vccp (processor core) 0V - 2V in2: VCC (internal +3.3V) 0V - 4.38V in3: +5V 0V - 6.64V @@ -93,6 +97,15 @@ SCH5027: in5: VTR (+3.3V standby) 0V - 4.38V in6: Vbat (+3.0V) 0V - 4.38V +SCH5127: + in0: +2.5 0V - 3.32V + in1: Vccp (processor core) 0V - 3V + in2: VCC (internal +3.3V) 0V - 4.38V + in3: V2_IN 0V - 1.5V + in4: V1_IN 0V - 1.5V + in5: VTR (+3.3V standby) 0V - 4.38V + in6: Vbat (+3.0V) 0V - 4.38V + Each voltage input has associated min and max limits which trigger an alarm when crossed. @@ -293,3 +306,21 @@ pwm[1-3]_auto_point1_pwm RW Auto PWM pwm point. Auto_point1 is the pwm[1-3]_auto_point2_pwm RO Auto PWM pwm point. Auto_point2 is the full-speed duty-cycle which is hard- wired to 255 (100% duty-cycle). + +Chip Differences +---------------- + +Feature dme1737 sch311x sch5027 sch5127 +------------------------------------------------------- +temp[1-3]_offset yes yes +vid yes +zone3 yes yes yes +zone[1-3]_hyst yes yes +pwm min/off yes yes +fan3 opt yes opt yes +pwm3 opt yes opt yes +fan4 opt opt +fan5 opt opt +pwm5 opt opt +fan6 opt opt +pwm6 opt opt diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c index 823dd28a902c..980c17d5eeae 100644 --- a/drivers/hwmon/dme1737.c +++ b/drivers/hwmon/dme1737.c @@ -1,12 +1,14 @@ /* - * dme1737.c - Driver for the SMSC DME1737, Asus A8000, SMSC SCH311x and - * SCH5027 Super-I/O chips integrated hardware monitoring features. - * Copyright (c) 2007, 2008 Juerg Haefliger + * dme1737.c - Driver for the SMSC DME1737, Asus A8000, SMSC SCH311x, SCH5027, + * and SCH5127 Super-I/O chips integrated hardware monitoring + * features. + * Copyright (c) 2007, 2008, 2009, 2010 Juerg Haefliger * * This driver is an I2C/ISA hybrid, meaning that it uses the I2C bus to access * the chip registers if a DME1737, A8000, or SCH5027 is found and the ISA bus - * if a SCH311x chip is found. Both types of chips have very similar hardware - * monitoring capabilities but differ in the way they can be accessed. + * if a SCH311x or SCH5127 chip is found. Both types of chips have very + * similar hardware monitoring capabilities but differ in the way they can be + * accessed. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -57,7 +59,7 @@ MODULE_PARM_DESC(probe_all_addr, "Include probing of non-standard LPC " /* Addresses to scan */ static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; -enum chips { dme1737, sch5027, sch311x }; +enum chips { dme1737, sch5027, sch311x, sch5127 }; /* --------------------------------------------------------------------- * Registers @@ -164,10 +166,29 @@ static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23}; #define DME1737_VERSTEP_MASK 0xf8 #define SCH311X_DEVICE 0x8c #define SCH5027_VERSTEP 0x69 +#define SCH5127_DEVICE 0x8e + +/* Device ID values (global configuration register index 0x20) */ +#define DME1737_ID_1 0x77 +#define DME1737_ID_2 0x78 +#define SCH3112_ID 0x7c +#define SCH3114_ID 0x7d +#define SCH3116_ID 0x7f +#define SCH5027_ID 0x89 +#define SCH5127_ID 0x86 /* Length of ISA address segment */ #define DME1737_EXTENT 2 +/* chip-dependent features */ +#define HAS_TEMP_OFFSET (1 << 0) /* bit 0 */ +#define HAS_VID (1 << 1) /* bit 1 */ +#define HAS_ZONE3 (1 << 2) /* bit 2 */ +#define HAS_ZONE_HYST (1 << 3) /* bit 3 */ +#define HAS_PWM_MIN (1 << 4) /* bit 4 */ +#define HAS_FAN(ix) (1 << ((ix) + 5)) /* bits 5-10 */ +#define HAS_PWM(ix) (1 << ((ix) + 11)) /* bits 11-16 */ + /* --------------------------------------------------------------------- * Data structures and manipulation thereof * --------------------------------------------------------------------- */ @@ -187,8 +208,7 @@ struct dme1737_data { u8 vid; u8 pwm_rr_en; - u8 has_pwm; - u8 has_fan; + u32 has_features; /* Register values */ u16 in[7]; @@ -224,8 +244,11 @@ static const int IN_NOMINAL_SCH311x[] = {2500, 1500, 3300, 5000, 12000, 3300, 3300}; static const int IN_NOMINAL_SCH5027[] = {5000, 2250, 3300, 1125, 1125, 3300, 3300}; +static const int IN_NOMINAL_SCH5127[] = {2500, 2250, 3300, 1125, 1125, 3300, + 3300}; #define IN_NOMINAL(type) ((type) == sch311x ? IN_NOMINAL_SCH311x : \ (type) == sch5027 ? IN_NOMINAL_SCH5027 : \ + (type) == sch5127 ? IN_NOMINAL_SCH5127 : \ IN_NOMINAL_DME1737) /* Voltage input @@ -568,7 +591,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) /* Sample register contents every 1 sec */ if (time_after(jiffies, data->last_update + HZ) || !data->valid) { - if (data->type == dme1737) { + if (data->has_features & HAS_VID) { data->vid = dme1737_read(data, DME1737_REG_VID) & 0x3f; } @@ -599,7 +622,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) DME1737_REG_TEMP_MIN(ix)); data->temp_max[ix] = dme1737_read(data, DME1737_REG_TEMP_MAX(ix)); - if (data->type != sch5027) { + if (data->has_features & HAS_TEMP_OFFSET) { data->temp_offset[ix] = dme1737_read(data, DME1737_REG_TEMP_OFFSET(ix)); } @@ -626,7 +649,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) for (ix = 0; ix < ARRAY_SIZE(data->fan); ix++) { /* Skip reading registers if optional fans are not * present */ - if (!(data->has_fan & (1 << ix))) { + if (!(data->has_features & HAS_FAN(ix))) { continue; } data->fan[ix] = dme1737_read(data, @@ -650,7 +673,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) for (ix = 0; ix < ARRAY_SIZE(data->pwm); ix++) { /* Skip reading registers if optional PWMs are not * present */ - if (!(data->has_pwm & (1 << ix))) { + if (!(data->has_features & HAS_PWM(ix))) { continue; } data->pwm[ix] = dme1737_read(data, @@ -672,12 +695,24 @@ static struct dme1737_data *dme1737_update_device(struct device *dev) /* Thermal zone registers */ for (ix = 0; ix < ARRAY_SIZE(data->zone_low); ix++) { - data->zone_low[ix] = dme1737_read(data, - DME1737_REG_ZONE_LOW(ix)); - data->zone_abs[ix] = dme1737_read(data, - DME1737_REG_ZONE_ABS(ix)); + /* Skip reading registers if zone3 is not present */ + if ((ix == 2) && !(data->has_features & HAS_ZONE3)) { + continue; + } + /* sch5127 zone2 registers are special */ + if ((ix == 1) && (data->type == sch5127)) { + data->zone_low[1] = dme1737_read(data, + DME1737_REG_ZONE_LOW(2)); + data->zone_abs[1] = dme1737_read(data, + DME1737_REG_ZONE_ABS(2)); + } else { + data->zone_low[ix] = dme1737_read(data, + DME1737_REG_ZONE_LOW(ix)); + data->zone_abs[ix] = dme1737_read(data, + DME1737_REG_ZONE_ABS(ix)); + } } - if (data->type != sch5027) { + if (data->has_features & HAS_ZONE_HYST) { for (ix = 0; ix < ARRAY_SIZE(data->zone_hyst); ix++) { data->zone_hyst[ix] = dme1737_read(data, DME1737_REG_ZONE_HYST(ix)); @@ -1594,10 +1629,6 @@ static struct attribute *dme1737_attr[] ={ &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, &sensor_dev_attr_zone2_auto_channels_temp.dev_attr.attr, - &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, - &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, - &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, - &sensor_dev_attr_zone3_auto_channels_temp.dev_attr.attr, NULL }; @@ -1605,27 +1636,23 @@ static const struct attribute_group dme1737_group = { .attrs = dme1737_attr, }; -/* The following struct holds misc attributes, which are not available in all - * chips. Their creation depends on the chip type which is determined during - * module load. */ -static struct attribute *dme1737_misc_attr[] = { - /* Temperatures */ +/* The following struct holds temp offset attributes, which are not available + * in all chips. The following chips support them: + * DME1737, SCH311x */ +static struct attribute *dme1737_temp_offset_attr[] = { &sensor_dev_attr_temp1_offset.dev_attr.attr, &sensor_dev_attr_temp2_offset.dev_attr.attr, &sensor_dev_attr_temp3_offset.dev_attr.attr, - /* Zones */ - &sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr, - &sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr, - &sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr, NULL }; -static const struct attribute_group dme1737_misc_group = { - .attrs = dme1737_misc_attr, +static const struct attribute_group dme1737_temp_offset_group = { + .attrs = dme1737_temp_offset_attr, }; -/* The following struct holds VID-related attributes. Their creation - depends on the chip type which is determined during module load. */ +/* The following struct holds VID related attributes, which are not available + * in all chips. The following chips support them: + * DME1737 */ static struct attribute *dme1737_vid_attr[] = { &dev_attr_vrm.attr, &dev_attr_cpu0_vid.attr, @@ -1636,6 +1663,36 @@ static const struct attribute_group dme1737_vid_group = { .attrs = dme1737_vid_attr, }; +/* The following struct holds temp zone 3 related attributes, which are not + * available in all chips. The following chips support them: + * DME1737, SCH311x, SCH5027 */ +static struct attribute *dme1737_zone3_attr[] = { + &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, + &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, + &sensor_dev_attr_zone3_auto_channels_temp.dev_attr.attr, + NULL +}; + +static const struct attribute_group dme1737_zone3_group = { + .attrs = dme1737_zone3_attr, +}; + + +/* The following struct holds temp zone hysteresis related attributes, which + * are not available in all chips. The following chips support them: + * DME1737, SCH311x */ +static struct attribute *dme1737_zone_hyst_attr[] = { + &sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr, + &sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr, + &sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr, + NULL +}; + +static const struct attribute_group dme1737_zone_hyst_group = { + .attrs = dme1737_zone_hyst_attr, +}; + /* The following structs hold the PWM attributes, some of which are optional. * Their creation depends on the chip configuration which is determined during * module load. */ @@ -1691,10 +1748,10 @@ static const struct attribute_group dme1737_pwm_group[] = { { .attrs = dme1737_pwm6_attr }, }; -/* The following struct holds misc PWM attributes, which are not available in - * all chips. Their creation depends on the chip type which is determined +/* The following struct holds auto PWM min attributes, which are not available + * in all chips. Their creation depends on the chip type which is determined * during module load. */ -static struct attribute *dme1737_pwm_misc_attr[] = { +static struct attribute *dme1737_auto_pwm_min_attr[] = { &sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr, &sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr, &sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr, @@ -1764,14 +1821,25 @@ static struct attribute *dme1737_zone_chmod_attr[] = { &sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr, &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, + NULL +}; + +static const struct attribute_group dme1737_zone_chmod_group = { + .attrs = dme1737_zone_chmod_attr, +}; + + +/* The permissions of the following zone 3 attributes are changed to read- + * writeable if the chip is *not* locked. Otherwise they stay read-only. */ +static struct attribute *dme1737_zone3_chmod_attr[] = { &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, NULL }; -static const struct attribute_group dme1737_zone_chmod_group = { - .attrs = dme1737_zone_chmod_attr, +static const struct attribute_group dme1737_zone3_chmod_group = { + .attrs = dme1737_zone3_chmod_attr, }; /* The permissions of the following PWM attributes are changed to read- @@ -1887,30 +1955,35 @@ static void dme1737_remove_files(struct device *dev) int ix; for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { - if (data->has_fan & (1 << ix)) { + if (data->has_features & HAS_FAN(ix)) { sysfs_remove_group(&dev->kobj, &dme1737_fan_group[ix]); } } for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { - if (data->has_pwm & (1 << ix)) { + if (data->has_features & HAS_PWM(ix)) { sysfs_remove_group(&dev->kobj, &dme1737_pwm_group[ix]); - if (data->type != sch5027 && ix < 3) { + if ((data->has_features & HAS_PWM_MIN) && ix < 3) { sysfs_remove_file(&dev->kobj, - dme1737_pwm_misc_attr[ix]); + dme1737_auto_pwm_min_attr[ix]); } } } - if (data->type != sch5027) { - sysfs_remove_group(&dev->kobj, &dme1737_misc_group); + if (data->has_features & HAS_TEMP_OFFSET) { + sysfs_remove_group(&dev->kobj, &dme1737_temp_offset_group); } - if (data->type == dme1737) { + if (data->has_features & HAS_VID) { sysfs_remove_group(&dev->kobj, &dme1737_vid_group); } - + if (data->has_features & HAS_ZONE3) { + sysfs_remove_group(&dev->kobj, &dme1737_zone3_group); + } + if (data->has_features & HAS_ZONE_HYST) { + sysfs_remove_group(&dev->kobj, &dme1737_zone_hyst_group); + } sysfs_remove_group(&dev->kobj, &dme1737_group); if (!data->client) { @@ -1934,23 +2007,31 @@ static int dme1737_create_files(struct device *dev) goto exit_remove; } - /* Create misc sysfs attributes */ - if ((data->type != sch5027) && + /* Create chip-dependent sysfs attributes */ + if ((data->has_features & HAS_TEMP_OFFSET) && (err = sysfs_create_group(&dev->kobj, - &dme1737_misc_group))) { + &dme1737_temp_offset_group))) { goto exit_remove; } - - /* Create VID-related sysfs attributes */ - if ((data->type == dme1737) && + if ((data->has_features & HAS_VID) && (err = sysfs_create_group(&dev->kobj, &dme1737_vid_group))) { goto exit_remove; } + if ((data->has_features & HAS_ZONE3) && + (err = sysfs_create_group(&dev->kobj, + &dme1737_zone3_group))) { + goto exit_remove; + } + if ((data->has_features & HAS_ZONE_HYST) && + (err = sysfs_create_group(&dev->kobj, + &dme1737_zone_hyst_group))) { + goto exit_remove; + } /* Create fan sysfs attributes */ for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { - if (data->has_fan & (1 << ix)) { + if (data->has_features & HAS_FAN(ix)) { if ((err = sysfs_create_group(&dev->kobj, &dme1737_fan_group[ix]))) { goto exit_remove; @@ -1960,14 +2041,14 @@ static int dme1737_create_files(struct device *dev) /* Create PWM sysfs attributes */ for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_group); ix++) { - if (data->has_pwm & (1 << ix)) { + if (data->has_features & HAS_PWM(ix)) { if ((err = sysfs_create_group(&dev->kobj, &dme1737_pwm_group[ix]))) { goto exit_remove; } - if (data->type != sch5027 && ix < 3 && + if ((data->has_features & HAS_PWM_MIN) && ix < 3 && (err = sysfs_create_file(&dev->kobj, - dme1737_pwm_misc_attr[ix]))) { + dme1737_auto_pwm_min_attr[ix]))) { goto exit_remove; } } @@ -1983,21 +2064,30 @@ static int dme1737_create_files(struct device *dev) dme1737_chmod_group(dev, &dme1737_zone_chmod_group, S_IRUGO | S_IWUSR); - /* Change permissions of misc sysfs attributes */ - if (data->type != sch5027) { - dme1737_chmod_group(dev, &dme1737_misc_group, + /* Change permissions of chip-dependent sysfs attributes */ + if (data->has_features & HAS_TEMP_OFFSET) { + dme1737_chmod_group(dev, &dme1737_temp_offset_group, + S_IRUGO | S_IWUSR); + } + if (data->has_features & HAS_ZONE3) { + dme1737_chmod_group(dev, &dme1737_zone3_chmod_group, + S_IRUGO | S_IWUSR); + } + if (data->has_features & HAS_ZONE_HYST) { + dme1737_chmod_group(dev, &dme1737_zone_hyst_group, S_IRUGO | S_IWUSR); } /* Change permissions of PWM sysfs attributes */ for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_chmod_group); ix++) { - if (data->has_pwm & (1 << ix)) { + if (data->has_features & HAS_PWM(ix)) { dme1737_chmod_group(dev, &dme1737_pwm_chmod_group[ix], S_IRUGO | S_IWUSR); - if (data->type != sch5027 && ix < 3) { + if ((data->has_features & HAS_PWM_MIN) && + ix < 3) { dme1737_chmod_file(dev, - dme1737_pwm_misc_attr[ix], + dme1737_auto_pwm_min_attr[ix], S_IRUGO | S_IWUSR); } } @@ -2005,7 +2095,7 @@ static int dme1737_create_files(struct device *dev) /* Change permissions of pwm[1-3] if in manual mode */ for (ix = 0; ix < 3; ix++) { - if ((data->has_pwm & (1 << ix)) && + if ((data->has_features & HAS_PWM(ix)) && (PWM_EN_FROM_REG(data->pwm_config[ix]) == 1)) { dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix], @@ -2052,20 +2142,20 @@ static int dme1737_init_device(struct device *dev) return -EFAULT; } - /* Determine which optional fan and pwm features are enabled/present */ + /* Determine which optional fan and pwm features are enabled (only + * valid for I2C devices) */ if (client) { /* I2C chip */ data->config2 = dme1737_read(data, DME1737_REG_CONFIG2); /* Check if optional fan3 input is enabled */ if (data->config2 & 0x04) { - data->has_fan |= (1 << 2); + data->has_features |= HAS_FAN(2); } /* Fan4 and pwm3 are only available if the client's I2C address * is the default 0x2e. Otherwise the I/Os associated with * these functions are used for addr enable/select. */ if (client->addr == 0x2e) { - data->has_fan |= (1 << 3); - data->has_pwm |= (1 << 2); + data->has_features |= HAS_FAN(3) | HAS_PWM(2); } /* Determine which of the optional fan[5-6] and pwm[5-6] @@ -2077,26 +2167,40 @@ static int dme1737_init_device(struct device *dev) dev_warn(dev, "Failed to query Super-IO for optional " "features.\n"); } - } else { /* ISA chip */ - /* Fan3 and pwm3 are always available. Fan[4-5] and pwm[5-6] - * don't exist in the ISA chip. */ - data->has_fan |= (1 << 2); - data->has_pwm |= (1 << 2); } - /* Fan1, fan2, pwm1, and pwm2 are always present */ - data->has_fan |= 0x03; - data->has_pwm |= 0x03; + /* Fan[1-2] and pwm[1-2] are present in all chips */ + data->has_features |= HAS_FAN(0) | HAS_FAN(1) | HAS_PWM(0) | HAS_PWM(1); + + /* Chip-dependent features */ + switch (data->type) { + case dme1737: + data->has_features |= HAS_TEMP_OFFSET | HAS_VID | HAS_ZONE3 | + HAS_ZONE_HYST | HAS_PWM_MIN; + break; + case sch311x: + data->has_features |= HAS_TEMP_OFFSET | HAS_ZONE3 | + HAS_ZONE_HYST | HAS_PWM_MIN | HAS_FAN(2) | HAS_PWM(2); + break; + case sch5027: + data->has_features |= HAS_ZONE3; + break; + case sch5127: + data->has_features |= HAS_FAN(2) | HAS_PWM(2); + break; + default: + break; + } dev_info(dev, "Optional features: pwm3=%s, pwm5=%s, pwm6=%s, " "fan3=%s, fan4=%s, fan5=%s, fan6=%s.\n", - (data->has_pwm & (1 << 2)) ? "yes" : "no", - (data->has_pwm & (1 << 4)) ? "yes" : "no", - (data->has_pwm & (1 << 5)) ? "yes" : "no", - (data->has_fan & (1 << 2)) ? "yes" : "no", - (data->has_fan & (1 << 3)) ? "yes" : "no", - (data->has_fan & (1 << 4)) ? "yes" : "no", - (data->has_fan & (1 << 5)) ? "yes" : "no"); + (data->has_features & HAS_PWM(2)) ? "yes" : "no", + (data->has_features & HAS_PWM(4)) ? "yes" : "no", + (data->has_features & HAS_PWM(5)) ? "yes" : "no", + (data->has_features & HAS_FAN(2)) ? "yes" : "no", + (data->has_features & HAS_FAN(3)) ? "yes" : "no", + (data->has_features & HAS_FAN(4)) ? "yes" : "no", + (data->has_features & HAS_FAN(5)) ? "yes" : "no"); reg = dme1737_read(data, DME1737_REG_TACH_PWM); /* Inform if fan-to-pwm mapping differs from the default */ @@ -2122,7 +2226,7 @@ static int dme1737_init_device(struct device *dev) for (ix = 0; ix < 3; ix++) { data->pwm_config[ix] = dme1737_read(data, DME1737_REG_PWM_CONFIG(ix)); - if ((data->has_pwm & (1 << ix)) && + if ((data->has_features & HAS_PWM(ix)) && (PWM_EN_FROM_REG(data->pwm_config[ix]) == -1)) { dev_info(dev, "Switching pwm%d to " "manual mode.\n", ix + 1); @@ -2142,7 +2246,7 @@ static int dme1737_init_device(struct device *dev) data->pwm_acz[2] = 4; /* pwm3 -> zone3 */ /* Set VRM */ - if (data->type == dme1737) { + if (data->has_features & HAS_VID) { data->vrm = vid_which_vrm(); } @@ -2163,10 +2267,10 @@ static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data) dme1737_sio_enter(sio_cip); /* Check device ID - * The DME1737 can return either 0x78 or 0x77 as its device ID. - * The SCH5027 returns 0x89 as its device ID. */ + * We currently know about two kinds of DME1737 and SCH5027. */ reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); - if (!(reg == 0x77 || reg == 0x78 || reg == 0x89)) { + if (!(reg == DME1737_ID_1 || reg == DME1737_ID_2 || + reg == SCH5027_ID)) { err = -ENODEV; goto exit; } @@ -2185,16 +2289,16 @@ static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data) * are enabled and available. Bits [3:2] of registers 0x43-0x46 are set * to '10' if the respective feature is enabled. */ if ((inb(addr + 0x43) & 0x0c) == 0x08) { /* fan6 */ - data->has_fan |= (1 << 5); + data->has_features |= HAS_FAN(5); } if ((inb(addr + 0x44) & 0x0c) == 0x08) { /* pwm6 */ - data->has_pwm |= (1 << 5); + data->has_features |= HAS_PWM(5); } if ((inb(addr + 0x45) & 0x0c) == 0x08) { /* fan5 */ - data->has_fan |= (1 << 4); + data->has_features |= HAS_FAN(4); } if ((inb(addr + 0x46) & 0x0c) == 0x08) { /* pwm5 */ - data->has_pwm |= (1 << 4); + data->has_features |= HAS_PWM(4); } exit: @@ -2222,7 +2326,6 @@ static int dme1737_i2c_detect(struct i2c_client *client, if (company == DME1737_COMPANY_SMSC && verstep == SCH5027_VERSTEP) { name = "sch5027"; - } else if (company == DME1737_COMPANY_SMSC && (verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) { name = "dme1737"; @@ -2329,10 +2432,10 @@ static int __init dme1737_isa_detect(int sio_cip, unsigned short *addr) dme1737_sio_enter(sio_cip); /* Check device ID - * We currently know about SCH3112 (0x7c), SCH3114 (0x7d), and - * SCH3116 (0x7f). */ + * We currently know about SCH3112, SCH3114, SCH3116, and SCH5127 */ reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); - if (!(reg == 0x7c || reg == 0x7d || reg == 0x7f)) { + if (!(reg == SCH3112_ID || reg == SCH3114_ID || reg == SCH3116_ID || + reg == SCH5127_ID)) { err = -ENODEV; goto exit; } @@ -2424,23 +2527,42 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev) platform_set_drvdata(pdev, data); /* Skip chip detection if module is loaded with force_id parameter */ - if (!force_id) { + switch (force_id) { + case SCH3112_ID: + case SCH3114_ID: + case SCH3116_ID: + data->type = sch311x; + break; + case SCH5127_ID: + data->type = sch5127; + break; + default: company = dme1737_read(data, DME1737_REG_COMPANY); device = dme1737_read(data, DME1737_REG_DEVICE); - if (!((company == DME1737_COMPANY_SMSC) && - (device == SCH311X_DEVICE))) { + if ((company == DME1737_COMPANY_SMSC) && + (device == SCH311X_DEVICE)) { + data->type = sch311x; + } else if ((company == DME1737_COMPANY_SMSC) && + (device == SCH5127_DEVICE)) { + data->type = sch5127; + } else { err = -ENODEV; goto exit_kfree; } } - data->type = sch311x; - /* Fill in the remaining client fields and initialize the mutex */ - data->name = "sch311x"; + if (data->type == sch5127) { + data->name = "sch5127"; + } else { + data->name = "sch311x"; + } + + /* Initialize the mutex */ mutex_init(&data->update_lock); - dev_info(dev, "Found a SCH311x chip at 0x%04x\n", data->addr); + dev_info(dev, "Found a %s chip at 0x%04x\n", + data->type == sch5127 ? "SCH5127" : "SCH311x", data->addr); /* Initialize the chip */ if ((err = dme1737_init_device(dev))) { -- cgit v1.2.3 From df16dd53c575d0cb9dbee20a3149927c862a9ff6 Mon Sep 17 00:00:00 2001 From: "Ira W. Snyder" Date: Thu, 27 May 2010 19:59:02 +0200 Subject: hwmon: (ltc4245) Read only one GPIO pin Read only one of the GPIO pins as an analog voltage. The ADC can be switched to a different GPIO pin at runtime, but this is not supported. Previously, this driver would report the analog voltage of the currently selected GPIO pin as all three GPIO voltages: in9_input, in10_input and in11_input. Signed-off-by: Ira W. Snyder Signed-off-by: Jean Delvare Cc: stable@kernel.org --- Documentation/hwmon/ltc4245 | 4 +--- drivers/hwmon/ltc4245.c | 18 +++++------------- 2 files changed, 6 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/Documentation/hwmon/ltc4245 b/Documentation/hwmon/ltc4245 index 02838a47d862..86b5880d8502 100644 --- a/Documentation/hwmon/ltc4245 +++ b/Documentation/hwmon/ltc4245 @@ -72,9 +72,7 @@ in6_min_alarm 5v output undervoltage alarm in7_min_alarm 3v output undervoltage alarm in8_min_alarm Vee (-12v) output undervoltage alarm -in9_input GPIO #1 voltage data -in10_input GPIO #2 voltage data -in11_input GPIO #3 voltage data +in9_input GPIO voltage data power1_input 12v power usage (mW) power2_input 5v power usage (mW) diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c index 65c232a9d0c5..21d201befc2c 100644 --- a/drivers/hwmon/ltc4245.c +++ b/drivers/hwmon/ltc4245.c @@ -45,9 +45,7 @@ enum ltc4245_cmd { LTC4245_VEEIN = 0x19, LTC4245_VEESENSE = 0x1a, LTC4245_VEEOUT = 0x1b, - LTC4245_GPIOADC1 = 0x1c, - LTC4245_GPIOADC2 = 0x1d, - LTC4245_GPIOADC3 = 0x1e, + LTC4245_GPIOADC = 0x1c, }; struct ltc4245_data { @@ -61,7 +59,7 @@ struct ltc4245_data { u8 cregs[0x08]; /* Voltage registers */ - u8 vregs[0x0f]; + u8 vregs[0x0d]; }; static struct ltc4245_data *ltc4245_update_device(struct device *dev) @@ -86,7 +84,7 @@ static struct ltc4245_data *ltc4245_update_device(struct device *dev) data->cregs[i] = val; } - /* Read voltage registers -- 0x10 to 0x1f */ + /* Read voltage registers -- 0x10 to 0x1c */ for (i = 0; i < ARRAY_SIZE(data->vregs); i++) { val = i2c_smbus_read_byte_data(client, i+0x10); if (unlikely(val < 0)) @@ -128,9 +126,7 @@ static int ltc4245_get_voltage(struct device *dev, u8 reg) case LTC4245_VEEOUT: voltage = regval * -55; break; - case LTC4245_GPIOADC1: - case LTC4245_GPIOADC2: - case LTC4245_GPIOADC3: + case LTC4245_GPIOADC: voltage = regval * 10; break; default: @@ -297,9 +293,7 @@ LTC4245_ALARM(in7_min_alarm, (1 << 2), LTC4245_FAULT2); LTC4245_ALARM(in8_min_alarm, (1 << 3), LTC4245_FAULT2); /* GPIO voltages */ -LTC4245_VOLTAGE(in9_input, LTC4245_GPIOADC1); -LTC4245_VOLTAGE(in10_input, LTC4245_GPIOADC2); -LTC4245_VOLTAGE(in11_input, LTC4245_GPIOADC3); +LTC4245_VOLTAGE(in9_input, LTC4245_GPIOADC); /* Power Consumption (virtual) */ LTC4245_POWER(power1_input, LTC4245_12VSENSE); @@ -342,8 +336,6 @@ static struct attribute *ltc4245_attributes[] = { &sensor_dev_attr_in8_min_alarm.dev_attr.attr, &sensor_dev_attr_in9_input.dev_attr.attr, - &sensor_dev_attr_in10_input.dev_attr.attr, - &sensor_dev_attr_in11_input.dev_attr.attr, &sensor_dev_attr_power1_input.dev_attr.attr, &sensor_dev_attr_power2_input.dev_attr.attr, -- cgit v1.2.3 From 6d034059eef080a0cdda92b45baa18cb00a19835 Mon Sep 17 00:00:00 2001 From: Shubhrajyoti Datta Date: Thu, 27 May 2010 19:59:03 +0200 Subject: hwmon: (lm75) Add support for the Texas Instruments TMP105 Add support for the Texas Instruments TMP105 temperature sensor device. Signed-off-by: Shubhrajyoti Datta Acked-by: Jonathan Cameron Signed-off-by: Jean Delvare --- drivers/hwmon/Kconfig | 3 ++- drivers/hwmon/lm75.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index de22ae41f758..e19cf8eb6ccf 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -493,7 +493,8 @@ config SENSORS_LM75 - NXP's LM75A - ST Microelectronics STDS75 - TelCom (now Microchip) TCN75 - - Texas Instruments TMP100, TMP101, TMP75, TMP175, TMP275 + - Texas Instruments TMP100, TMP101, TMP105, TMP75, TMP175, + TMP275 This driver supports driver model based binding through board specific I2C device tables. diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index 8ae2cfe2d827..56463428a419 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -46,6 +46,7 @@ enum lm75_type { /* keep sorted in alphabetical order */ tcn75, tmp100, tmp101, + tmp105, tmp175, tmp275, tmp75, @@ -220,6 +221,7 @@ static const struct i2c_device_id lm75_ids[] = { { "tcn75", tcn75, }, { "tmp100", tmp100, }, { "tmp101", tmp101, }, + { "tmp105", tmp105, }, { "tmp175", tmp175, }, { "tmp275", tmp275, }, { "tmp75", tmp75, }, -- cgit v1.2.3 From 7145c45a06e9c918ccf2d8b27b01409a98a67be7 Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Thu, 27 May 2010 10:59:10 -0700 Subject: IB/qib: Remove DCA support until feature is finished The DCA code was left over from internal development to test the hardware feature and allow performance testing. The results were mixed and will require some additional work to make full use of the feature. Therefore, it is being removed for now. Signed-off-by: Ralph Campbell Signed-off-by: Roland Dreier --- drivers/infiniband/hw/qib/qib_iba7322.c | 189 -------------------------------- 1 file changed, 189 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index 23fb9efe20a4..503992d9c5ce 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c @@ -42,9 +42,6 @@ #include #include #include -#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) -#include -#endif #include "qib.h" #include "qib_7322_regs.h" @@ -518,12 +515,6 @@ struct qib_chip_specific { u32 lastbuf_for_pio; u32 stay_in_freeze; u32 recovery_ports_initted; -#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) - u32 dca_ctrl; - int rhdr_cpu[18]; - int sdma_cpu[2]; - u64 dca_rcvhdr_ctrl[5]; /* B, C, D, E, F */ -#endif struct msix_entry *msix_entries; void **msix_arg; unsigned long *sendchkenable; @@ -642,52 +633,6 @@ static struct { SYM_LSB(IntStatus, SDmaCleanupDone_1), 2 }, }; -#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) -static const struct dca_reg_map { - int shadow_inx; - int lsb; - u64 mask; - u16 regno; -} dca_rcvhdr_reg_map[] = { - { 0, SYM_LSB(DCACtrlB, RcvHdrq0DCAOPH), - ~SYM_MASK(DCACtrlB, RcvHdrq0DCAOPH) , KREG_IDX(DCACtrlB) }, - { 0, SYM_LSB(DCACtrlB, RcvHdrq1DCAOPH), - ~SYM_MASK(DCACtrlB, RcvHdrq1DCAOPH) , KREG_IDX(DCACtrlB) }, - { 0, SYM_LSB(DCACtrlB, RcvHdrq2DCAOPH), - ~SYM_MASK(DCACtrlB, RcvHdrq2DCAOPH) , KREG_IDX(DCACtrlB) }, - { 0, SYM_LSB(DCACtrlB, RcvHdrq3DCAOPH), - ~SYM_MASK(DCACtrlB, RcvHdrq3DCAOPH) , KREG_IDX(DCACtrlB) }, - { 1, SYM_LSB(DCACtrlC, RcvHdrq4DCAOPH), - ~SYM_MASK(DCACtrlC, RcvHdrq4DCAOPH) , KREG_IDX(DCACtrlC) }, - { 1, SYM_LSB(DCACtrlC, RcvHdrq5DCAOPH), - ~SYM_MASK(DCACtrlC, RcvHdrq5DCAOPH) , KREG_IDX(DCACtrlC) }, - { 1, SYM_LSB(DCACtrlC, RcvHdrq6DCAOPH), - ~SYM_MASK(DCACtrlC, RcvHdrq6DCAOPH) , KREG_IDX(DCACtrlC) }, - { 1, SYM_LSB(DCACtrlC, RcvHdrq7DCAOPH), - ~SYM_MASK(DCACtrlC, RcvHdrq7DCAOPH) , KREG_IDX(DCACtrlC) }, - { 2, SYM_LSB(DCACtrlD, RcvHdrq8DCAOPH), - ~SYM_MASK(DCACtrlD, RcvHdrq8DCAOPH) , KREG_IDX(DCACtrlD) }, - { 2, SYM_LSB(DCACtrlD, RcvHdrq9DCAOPH), - ~SYM_MASK(DCACtrlD, RcvHdrq9DCAOPH) , KREG_IDX(DCACtrlD) }, - { 2, SYM_LSB(DCACtrlD, RcvHdrq10DCAOPH), - ~SYM_MASK(DCACtrlD, RcvHdrq10DCAOPH) , KREG_IDX(DCACtrlD) }, - { 2, SYM_LSB(DCACtrlD, RcvHdrq11DCAOPH), - ~SYM_MASK(DCACtrlD, RcvHdrq11DCAOPH) , KREG_IDX(DCACtrlD) }, - { 3, SYM_LSB(DCACtrlE, RcvHdrq12DCAOPH), - ~SYM_MASK(DCACtrlE, RcvHdrq12DCAOPH) , KREG_IDX(DCACtrlE) }, - { 3, SYM_LSB(DCACtrlE, RcvHdrq13DCAOPH), - ~SYM_MASK(DCACtrlE, RcvHdrq13DCAOPH) , KREG_IDX(DCACtrlE) }, - { 3, SYM_LSB(DCACtrlE, RcvHdrq14DCAOPH), - ~SYM_MASK(DCACtrlE, RcvHdrq14DCAOPH) , KREG_IDX(DCACtrlE) }, - { 3, SYM_LSB(DCACtrlE, RcvHdrq15DCAOPH), - ~SYM_MASK(DCACtrlE, RcvHdrq15DCAOPH) , KREG_IDX(DCACtrlE) }, - { 4, SYM_LSB(DCACtrlF, RcvHdrq16DCAOPH), - ~SYM_MASK(DCACtrlF, RcvHdrq16DCAOPH) , KREG_IDX(DCACtrlF) }, - { 4, SYM_LSB(DCACtrlF, RcvHdrq17DCAOPH), - ~SYM_MASK(DCACtrlF, RcvHdrq17DCAOPH) , KREG_IDX(DCACtrlF) }, -}; -#endif - /* ibcctrl bits */ #define QLOGIC_IB_IBCC_LINKINITCMD_DISABLE 1 /* cycle through TS1/TS2 till OK */ @@ -2538,95 +2483,6 @@ static void qib_setup_7322_setextled(struct qib_pportdata *ppd, u32 on) qib_write_kreg_port(ppd, krp_rcvpktledcnt, ledblink); } -#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) -static void qib_update_rhdrq_dca(struct qib_ctxtdata *rcd) -{ - struct qib_devdata *dd = rcd->dd; - struct qib_chip_specific *cspec = dd->cspec; - int cpu = get_cpu(); - - if (cspec->rhdr_cpu[rcd->ctxt] != cpu) { - const struct dca_reg_map *rmp; - - cspec->rhdr_cpu[rcd->ctxt] = cpu; - rmp = &dca_rcvhdr_reg_map[rcd->ctxt]; - cspec->dca_rcvhdr_ctrl[rmp->shadow_inx] &= rmp->mask; - cspec->dca_rcvhdr_ctrl[rmp->shadow_inx] |= - (u64) dca3_get_tag(&dd->pcidev->dev, cpu) << rmp->lsb; - qib_write_kreg(dd, rmp->regno, - cspec->dca_rcvhdr_ctrl[rmp->shadow_inx]); - cspec->dca_ctrl |= SYM_MASK(DCACtrlA, RcvHdrqDCAEnable); - qib_write_kreg(dd, KREG_IDX(DCACtrlA), cspec->dca_ctrl); - } - put_cpu(); -} - -static void qib_update_sdma_dca(struct qib_pportdata *ppd) -{ - struct qib_devdata *dd = ppd->dd; - struct qib_chip_specific *cspec = dd->cspec; - int cpu = get_cpu(); - unsigned pidx = ppd->port - 1; - - if (cspec->sdma_cpu[pidx] != cpu) { - cspec->sdma_cpu[pidx] = cpu; - cspec->dca_rcvhdr_ctrl[4] &= ~(ppd->hw_pidx ? - SYM_MASK(DCACtrlF, SendDma1DCAOPH) : - SYM_MASK(DCACtrlF, SendDma0DCAOPH)); - cspec->dca_rcvhdr_ctrl[4] |= - (u64) dca3_get_tag(&dd->pcidev->dev, cpu) << - (ppd->hw_pidx ? - SYM_LSB(DCACtrlF, SendDma1DCAOPH) : - SYM_LSB(DCACtrlF, SendDma0DCAOPH)); - qib_write_kreg(dd, KREG_IDX(DCACtrlF), - cspec->dca_rcvhdr_ctrl[4]); - cspec->dca_ctrl |= ppd->hw_pidx ? - SYM_MASK(DCACtrlA, SendDMAHead1DCAEnable) : - SYM_MASK(DCACtrlA, SendDMAHead0DCAEnable); - qib_write_kreg(dd, KREG_IDX(DCACtrlA), cspec->dca_ctrl); - } - put_cpu(); -} - -static void qib_setup_dca(struct qib_devdata *dd) -{ - struct qib_chip_specific *cspec = dd->cspec; - int i; - - for (i = 0; i < ARRAY_SIZE(cspec->rhdr_cpu); i++) - cspec->rhdr_cpu[i] = -1; - for (i = 0; i < ARRAY_SIZE(cspec->sdma_cpu); i++) - cspec->sdma_cpu[i] = -1; - cspec->dca_rcvhdr_ctrl[0] = - (1ULL << SYM_LSB(DCACtrlB, RcvHdrq0DCAXfrCnt)) | - (1ULL << SYM_LSB(DCACtrlB, RcvHdrq1DCAXfrCnt)) | - (1ULL << SYM_LSB(DCACtrlB, RcvHdrq2DCAXfrCnt)) | - (1ULL << SYM_LSB(DCACtrlB, RcvHdrq3DCAXfrCnt)); - cspec->dca_rcvhdr_ctrl[1] = - (1ULL << SYM_LSB(DCACtrlC, RcvHdrq4DCAXfrCnt)) | - (1ULL << SYM_LSB(DCACtrlC, RcvHdrq5DCAXfrCnt)) | - (1ULL << SYM_LSB(DCACtrlC, RcvHdrq6DCAXfrCnt)) | - (1ULL << SYM_LSB(DCACtrlC, RcvHdrq7DCAXfrCnt)); - cspec->dca_rcvhdr_ctrl[2] = - (1ULL << SYM_LSB(DCACtrlD, RcvHdrq8DCAXfrCnt)) | - (1ULL << SYM_LSB(DCACtrlD, RcvHdrq9DCAXfrCnt)) | - (1ULL << SYM_LSB(DCACtrlD, RcvHdrq10DCAXfrCnt)) | - (1ULL << SYM_LSB(DCACtrlD, RcvHdrq11DCAXfrCnt)); - cspec->dca_rcvhdr_ctrl[3] = - (1ULL << SYM_LSB(DCACtrlE, RcvHdrq12DCAXfrCnt)) | - (1ULL << SYM_LSB(DCACtrlE, RcvHdrq13DCAXfrCnt)) | - (1ULL << SYM_LSB(DCACtrlE, RcvHdrq14DCAXfrCnt)) | - (1ULL << SYM_LSB(DCACtrlE, RcvHdrq15DCAXfrCnt)); - cspec->dca_rcvhdr_ctrl[4] = - (1ULL << SYM_LSB(DCACtrlF, RcvHdrq16DCAXfrCnt)) | - (1ULL << SYM_LSB(DCACtrlF, RcvHdrq17DCAXfrCnt)); - for (i = 0; i < ARRAY_SIZE(cspec->sdma_cpu); i++) - qib_write_kreg(dd, KREG_IDX(DCACtrlB) + i, - cspec->dca_rcvhdr_ctrl[i]); -} - -#endif - /* * Disable MSIx interrupt if enabled, call generic MSIx code * to cleanup, and clear pending MSIx interrupts. @@ -2667,15 +2523,6 @@ static void qib_setup_7322_cleanup(struct qib_devdata *dd) { int i; -#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) - if (dd->flags & QIB_DCA_ENABLED) { - dca_remove_requester(&dd->pcidev->dev); - dd->flags &= ~QIB_DCA_ENABLED; - dd->cspec->dca_ctrl = 0; - qib_write_kreg(dd, KREG_IDX(DCACtrlA), dd->cspec->dca_ctrl); - } -#endif - qib_7322_free_irq(dd); kfree(dd->cspec->cntrs); kfree(dd->cspec->sendchkenable); @@ -2983,11 +2830,6 @@ static irqreturn_t qib_7322pintr(int irq, void *data) if (dd->int_counter != (u32) -1) dd->int_counter++; -#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) - if (dd->flags & QIB_DCA_ENABLED) - qib_update_rhdrq_dca(rcd); -#endif - /* Clear the interrupt bit we expect to be set. */ qib_write_kreg(dd, kr_intclear, ((1ULL << QIB_I_RCVAVAIL_LSB) | (1ULL << QIB_I_RCVURG_LSB)) << rcd->ctxt); @@ -3051,11 +2893,6 @@ static irqreturn_t sdma_intr(int irq, void *data) if (dd->int_counter != (u32) -1) dd->int_counter++; -#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) - if (dd->flags & QIB_DCA_ENABLED) - qib_update_sdma_dca(ppd); -#endif - /* Clear the interrupt bit we expect to be set. */ qib_write_kreg(dd, kr_intclear, ppd->hw_pidx ? INT_MASK_P(SDma, 1) : INT_MASK_P(SDma, 0)); @@ -3085,11 +2922,6 @@ static irqreturn_t sdma_idle_intr(int irq, void *data) if (dd->int_counter != (u32) -1) dd->int_counter++; -#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) - if (dd->flags & QIB_DCA_ENABLED) - qib_update_sdma_dca(ppd); -#endif - /* Clear the interrupt bit we expect to be set. */ qib_write_kreg(dd, kr_intclear, ppd->hw_pidx ? INT_MASK_P(SDmaIdle, 1) : INT_MASK_P(SDmaIdle, 0)); @@ -3119,11 +2951,6 @@ static irqreturn_t sdma_progress_intr(int irq, void *data) if (dd->int_counter != (u32) -1) dd->int_counter++; -#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) - if (dd->flags & QIB_DCA_ENABLED) - qib_update_sdma_dca(ppd); -#endif - /* Clear the interrupt bit we expect to be set. */ qib_write_kreg(dd, kr_intclear, ppd->hw_pidx ? INT_MASK_P(SDmaProgress, 1) : @@ -3154,11 +2981,6 @@ static irqreturn_t sdma_cleanup_intr(int irq, void *data) if (dd->int_counter != (u32) -1) dd->int_counter++; -#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) - if (dd->flags & QIB_DCA_ENABLED) - qib_update_sdma_dca(ppd); -#endif - /* Clear the interrupt bit we expect to be set. */ qib_write_kreg(dd, kr_intclear, ppd->hw_pidx ? INT_MASK_PM(SDmaCleanupDone, 1) : @@ -4265,10 +4087,6 @@ static void rcvctrl_7322_mod(struct qib_pportdata *ppd, unsigned int op, qib_write_kreg_ctxt(dd, krc_rcvhdraddr, ctxt, rcd->rcvhdrq_phys); rcd->seq_cnt = 1; -#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) - if (dd->flags & QIB_DCA_ENABLED) - qib_update_rhdrq_dca(rcd); -#endif } if (op & QIB_RCVCTRL_CTXT_DIS) ppd->p_rcvctrl &= @@ -6893,13 +6711,6 @@ struct qib_devdata *qib_init_iba7322_funcs(struct pci_dev *pdev, /* clear diagctrl register, in case diags were running and crashed */ qib_write_kreg(dd, kr_hwdiagctrl, 0); -#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) - ret = dca_add_requester(&pdev->dev); - if (!ret) { - dd->flags |= QIB_DCA_ENABLED; - qib_setup_dca(dd); - } -#endif goto bail; bail_cleanup: -- cgit v1.2.3 From 9ad285d6db6e04c1c51c79152d2214fffefc92ab Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Fri, 19 Mar 2010 12:46:28 +0100 Subject: mfd: Check t7l66 platform_data pointer We should check for pdata being not NULL before dereferencing it. Reported-by: Dan Carpenter Signed-off-by: Samuel Ortiz --- drivers/mfd/t7l66xb.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c index da6383a934ac..5041d33adf0b 100644 --- a/drivers/mfd/t7l66xb.c +++ b/drivers/mfd/t7l66xb.c @@ -318,6 +318,9 @@ static int t7l66xb_probe(struct platform_device *dev) struct resource *iomem, *rscr; int ret; + if (pdata == NULL) + return -EINVAL; + iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!iomem) return -EINVAL; -- cgit v1.2.3 From d84027bc4d176a0c06e8f62a9f7a002bdd444012 Mon Sep 17 00:00:00 2001 From: Richard Röjfors Date: Tue, 16 Mar 2010 10:43:28 +0100 Subject: mfd: Add in XIIC to some configurations of timberdale MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds in the Xilinx I2C bus driver to some of the configurations of the timberdale MFD. It provides the I2C devices to the XIIC via platform data in a similar way as done to the ocores driver. Signed-off-by: Richard Röjfors Signed-off-by: Samuel Ortiz --- drivers/mfd/timberdale.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'drivers') diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c index 7f478ec4184b..1ac77d16dce9 100644 --- a/drivers/mfd/timberdale.c +++ b/drivers/mfd/timberdale.c @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -69,6 +70,12 @@ static struct i2c_board_info timberdale_i2c_board_info[] = { }, }; +static __devinitdata struct xiic_i2c_platform_data +timberdale_xiic_platform_data = { + .devices = timberdale_i2c_board_info, + .num_devices = ARRAY_SIZE(timberdale_i2c_board_info) +}; + static __devinitdata struct ocores_i2c_platform_data timberdale_ocores_platform_data = { .regstep = 4, @@ -77,6 +84,19 @@ timberdale_ocores_platform_data = { .num_devices = ARRAY_SIZE(timberdale_i2c_board_info) }; +const static __devinitconst struct resource timberdale_xiic_resources[] = { + { + .start = XIICOFFSET, + .end = XIICEND, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_TIMBERDALE_I2C, + .end = IRQ_TIMBERDALE_I2C, + .flags = IORESOURCE_IRQ, + }, +}; + const static __devinitconst struct resource timberdale_ocores_resources[] = { { .start = OCORESOFFSET, @@ -269,6 +289,13 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg0[] = { .num_resources = ARRAY_SIZE(timberdale_uart_resources), .resources = timberdale_uart_resources, }, + { + .name = "xiic-i2c", + .num_resources = ARRAY_SIZE(timberdale_xiic_resources), + .resources = timberdale_xiic_resources, + .platform_data = &timberdale_xiic_platform_data, + .data_size = sizeof(timberdale_xiic_platform_data), + }, { .name = "timb-gpio", .num_resources = ARRAY_SIZE(timberdale_gpio_resources), @@ -313,6 +340,13 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = { .num_resources = ARRAY_SIZE(timberdale_uartlite_resources), .resources = timberdale_uartlite_resources, }, + { + .name = "xiic-i2c", + .num_resources = ARRAY_SIZE(timberdale_xiic_resources), + .resources = timberdale_xiic_resources, + .platform_data = &timberdale_xiic_platform_data, + .data_size = sizeof(timberdale_xiic_platform_data), + }, { .name = "timb-gpio", .num_resources = ARRAY_SIZE(timberdale_gpio_resources), @@ -357,6 +391,13 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg2[] = { .num_resources = ARRAY_SIZE(timberdale_uart_resources), .resources = timberdale_uart_resources, }, + { + .name = "xiic-i2c", + .num_resources = ARRAY_SIZE(timberdale_xiic_resources), + .resources = timberdale_xiic_resources, + .platform_data = &timberdale_xiic_platform_data, + .data_size = sizeof(timberdale_xiic_platform_data), + }, { .name = "timb-gpio", .num_resources = ARRAY_SIZE(timberdale_gpio_resources), -- cgit v1.2.3 From f322d5f0097333343bfd92b47258ee997c889263 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 20 Mar 2010 15:12:54 +0100 Subject: mfd: Fix dangling pointers Fix I2C-drivers which missed setting clientdata to NULL before freeing the structure it points to. Also fix drivers which do this _after_ the structure was freed already. Signed-off-by: Wolfram Sang Acked-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/88pm860x-i2c.c | 1 + drivers/mfd/ab3100-core.c | 2 ++ drivers/mfd/da903x.c | 1 + drivers/mfd/menelaus.c | 3 ++- drivers/mfd/pcf50633-core.c | 1 + drivers/mfd/tps65010.c | 2 +- drivers/mfd/wm8350-i2c.c | 2 ++ 7 files changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c index 4a6e7186334e..b0bade1881d4 100644 --- a/drivers/mfd/88pm860x-i2c.c +++ b/drivers/mfd/88pm860x-i2c.c @@ -202,6 +202,7 @@ static int __devexit pm860x_remove(struct i2c_client *client) i2c_unregister_device(chip->companion); i2c_set_clientdata(chip->companion, NULL); i2c_set_clientdata(chip->client, NULL); + i2c_set_clientdata(client, NULL); kfree(chip); return 0; } diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index e4ca5909e424..16898211cd1a 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c @@ -920,6 +920,7 @@ static int __init ab3100_probe(struct i2c_client *client, i2c_unregister_device(ab3100->testreg_client); exit_no_testreg_client: exit_no_detect: + i2c_set_clientdata(client, NULL); kfree(ab3100); return err; } @@ -941,6 +942,7 @@ static int __exit ab3100_remove(struct i2c_client *client) * their notifiers so deactivate IRQ */ free_irq(client->irq, ab3100); + i2c_set_clientdata(client, NULL); kfree(ab3100); return 0; } diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c index 67181b147ab3..3ad915d0589c 100644 --- a/drivers/mfd/da903x.c +++ b/drivers/mfd/da903x.c @@ -544,6 +544,7 @@ static int __devexit da903x_remove(struct i2c_client *client) struct da903x_chip *chip = i2c_get_clientdata(client); da903x_remove_subdevs(chip); + i2c_set_clientdata(client, NULL); kfree(chip); return 0; } diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c index a94b131a18ef..721948be12c7 100644 --- a/drivers/mfd/menelaus.c +++ b/drivers/mfd/menelaus.c @@ -1228,6 +1228,7 @@ fail2: free_irq(client->irq, menelaus); flush_scheduled_work(); fail1: + i2c_set_clientdata(client, NULL); kfree(menelaus); return err; } @@ -1237,8 +1238,8 @@ static int __exit menelaus_remove(struct i2c_client *client) struct menelaus_chip *menelaus = i2c_get_clientdata(client); free_irq(client->irq, menelaus); - kfree(menelaus); i2c_set_clientdata(client, NULL); + kfree(menelaus); the_menelaus = NULL; return 0; } diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index dc95ddb708f1..710e417e0eec 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -679,6 +679,7 @@ static int __devexit pcf50633_remove(struct i2c_client *client) for (i = 0; i < PCF50633_NUM_REGULATORS; i++) platform_device_unregister(pcf->regulator_pdev[i]); + i2c_set_clientdata(client, NULL); kfree(pcf); return 0; diff --git a/drivers/mfd/tps65010.c b/drivers/mfd/tps65010.c index e5955306c2fa..9b22a77f70f5 100644 --- a/drivers/mfd/tps65010.c +++ b/drivers/mfd/tps65010.c @@ -530,8 +530,8 @@ static int __exit tps65010_remove(struct i2c_client *client) cancel_delayed_work(&tps->work); flush_scheduled_work(); debugfs_remove(tps->file); - kfree(tps); i2c_set_clientdata(client, NULL); + kfree(tps); the_tps = NULL; return 0; } diff --git a/drivers/mfd/wm8350-i2c.c b/drivers/mfd/wm8350-i2c.c index 65830f57c093..aa3ba0974ee5 100644 --- a/drivers/mfd/wm8350-i2c.c +++ b/drivers/mfd/wm8350-i2c.c @@ -82,6 +82,7 @@ static int wm8350_i2c_probe(struct i2c_client *i2c, return ret; err: + i2c_set_clientdata(i2c, NULL); kfree(wm8350); return ret; } @@ -91,6 +92,7 @@ static int wm8350_i2c_remove(struct i2c_client *i2c) struct wm8350 *wm8350 = i2c_get_clientdata(i2c); wm8350_device_exit(wm8350); + i2c_set_clientdata(i2c, NULL); kfree(wm8350); return 0; -- cgit v1.2.3 From e090d506c3f1b314059fb77b177cd4193bb81d6e Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 21 Mar 2010 01:06:05 +0100 Subject: mfd: Add support for the RDC321x southbridge This patch adds a new MFD driver for the RDC321x southbridge. This southbridge is always present in the RDC321x System-on-a-Chip and provides access to some GPIOs as well as a watchdog. Access to these two functions is done using the southbridge PCI device configuration space. Signed-off-by: Florian Fainelli Signed-off-by: Samuel Ortiz --- drivers/mfd/Kconfig | 9 +++ drivers/mfd/Makefile | 3 +- drivers/mfd/rdc321x-southbridge.c | 123 ++++++++++++++++++++++++++++++++++++++ include/linux/mfd/rdc321x.h | 26 ++++++++ 4 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 drivers/mfd/rdc321x-southbridge.c create mode 100644 include/linux/mfd/rdc321x.h (limited to 'drivers') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 3c6a9860dd9c..93d0e31c0438 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -409,6 +409,15 @@ config LPC_SCH LPC bridge function of the Intel SCH provides support for System Management Bus and General Purpose I/O. +config MFD_RDC321X + tristate "Support for RDC-R321x southbridge" + select MFD_CORE + depends on PCI + help + Say yes here if you want to have support for the RDC R-321x SoC + southbridge which provides access to GPIOs and Watchdog using the + southbridge PCI device configuration space. + endmenu menu "Multimedia Capabilities Port drivers" diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 87935f967aa0..f177e064b31b 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -63,4 +63,5 @@ obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o obj-$(CONFIG_AB4500_CORE) += ab4500-core.o obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o obj-$(CONFIG_PMIC_ADP5520) += adp5520.o -obj-$(CONFIG_LPC_SCH) += lpc_sch.o \ No newline at end of file +obj-$(CONFIG_LPC_SCH) += lpc_sch.o +obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o diff --git a/drivers/mfd/rdc321x-southbridge.c b/drivers/mfd/rdc321x-southbridge.c new file mode 100644 index 000000000000..256dd560bd48 --- /dev/null +++ b/drivers/mfd/rdc321x-southbridge.c @@ -0,0 +1,123 @@ +/* + * RDC321x MFD southbrige driver + * + * Copyright (C) 2007-2010 Florian Fainelli + * Copyright (C) 2010 Bernhard Loos + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include + +static struct rdc321x_wdt_pdata rdc321x_wdt_pdata; + +static struct resource rdc321x_wdt_resource[] = { + { + .name = "wdt-reg", + .start = RDC321X_WDT_CTRL, + .end = RDC321X_WDT_CTRL + 0x3, + .flags = IORESOURCE_MEM, + } +}; + +static struct rdc321x_gpio_pdata rdc321x_gpio_pdata = { + .max_gpios = RDC321X_MAX_GPIO, +}; + +static struct resource rdc321x_gpio_resources[] = { + { + .name = "gpio-reg1", + .start = RDC321X_GPIO_CTRL_REG1, + .end = RDC321X_GPIO_CTRL_REG1 + 0x7, + .flags = IORESOURCE_MEM, + }, { + .name = "gpio-reg2", + .start = RDC321X_GPIO_CTRL_REG2, + .end = RDC321X_GPIO_CTRL_REG2 + 0x7, + .flags = IORESOURCE_MEM, + } +}; + +static struct mfd_cell rdc321x_sb_cells[] = { + { + .name = "rdc321x-wdt", + .resources = rdc321x_wdt_resource, + .num_resources = ARRAY_SIZE(rdc321x_wdt_resource), + .driver_data = &rdc321x_wdt_pdata, + }, { + .name = "rdc321x-gpio", + .resources = rdc321x_gpio_resources, + .num_resources = ARRAY_SIZE(rdc321x_gpio_resources), + .driver_data = &rdc321x_gpio_pdata, + }, +}; + +static int __devinit rdc321x_sb_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int err; + + err = pci_enable_device(pdev); + if (err) { + dev_err(&pdev->dev, "failed to enable device\n"); + return err; + } + + rdc321x_gpio_pdata.sb_pdev = pdev; + rdc321x_wdt_pdata.sb_pdev = pdev; + + return mfd_add_devices(&pdev->dev, -1, + rdc321x_sb_cells, ARRAY_SIZE(rdc321x_sb_cells), NULL, 0); +} + +static void __devexit rdc321x_sb_remove(struct pci_dev *pdev) +{ + mfd_remove_devices(&pdev->dev); +} + +static DEFINE_PCI_DEVICE_TABLE(rdc321x_sb_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_RDC, PCI_DEVICE_ID_RDC_R6030) }, + {} +}; + +static struct pci_driver rdc321x_sb_driver = { + .name = "RDC321x Southbridge", + .id_table = rdc321x_sb_table, + .probe = rdc321x_sb_probe, + .remove = __devexit_p(rdc321x_sb_remove), +}; + +static int __init rdc321x_sb_init(void) +{ + return pci_register_driver(&rdc321x_sb_driver); +} + +static void __exit rdc321x_sb_exit(void) +{ + pci_unregister_driver(&rdc321x_sb_driver); +} + +module_init(rdc321x_sb_init); +module_exit(rdc321x_sb_exit); + +MODULE_AUTHOR("Florian Fainelli "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("RDC R-321x MFD southbridge driver"); diff --git a/include/linux/mfd/rdc321x.h b/include/linux/mfd/rdc321x.h new file mode 100644 index 000000000000..4bdf19c8eedf --- /dev/null +++ b/include/linux/mfd/rdc321x.h @@ -0,0 +1,26 @@ +#ifndef __RDC321X_MFD_H +#define __RDC321X_MFD_H + +#include +#include + +/* Offsets to be accessed in the southbridge PCI + * device configuration register */ +#define RDC321X_WDT_CTRL 0x44 +#define RDC321X_GPIO_CTRL_REG1 0x48 +#define RDC321X_GPIO_DATA_REG1 0x4c +#define RDC321X_GPIO_CTRL_REG2 0x84 +#define RDC321X_GPIO_DATA_REG2 0x88 + +#define RDC321X_MAX_GPIO 58 + +struct rdc321x_gpio_pdata { + struct pci_dev *sb_pdev; + unsigned max_gpios; +}; + +struct rdc321x_wdt_pdata { + struct pci_dev *sb_pdev; +}; + +#endif /* __RDC321X_MFD_H */ -- cgit v1.2.3 From 9956d02d6e60f0c50632ba5699bc6238defb496b Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 21 Mar 2010 01:06:09 +0100 Subject: gpio: Add support for RDC321x GPIO controller This patch adds a new GPIO driver for the RDC321x SoC GPIO controller. Signed-off-by: Florian Fainelli Signed-off-by: Samuel Ortiz --- drivers/gpio/Kconfig | 8 ++ drivers/gpio/Makefile | 3 +- drivers/gpio/rdc321x-gpio.c | 245 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 drivers/gpio/rdc321x-gpio.c (limited to 'drivers') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 4fd0f276df5a..56eb0c59c512 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -282,6 +282,14 @@ config GPIO_TIMBERDALE ---help--- Add support for the GPIO IP in the timberdale FPGA. +config GPIO_RDC321X + tristate "RDC R-321x GPIO support" + depends on PCI && GPIOLIB + select MFD_RDC321X + help + Support for the RDC R321x SoC GPIOs over southbridge + PCI configuration space. + comment "SPI GPIO expanders:" config GPIO_MAX7301 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 10f3f8d958b1..d3226d395a90 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -27,4 +27,5 @@ obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o obj-$(CONFIG_GPIO_WM831X) += wm831x-gpio.o obj-$(CONFIG_GPIO_WM8350) += wm8350-gpiolib.o obj-$(CONFIG_GPIO_WM8994) += wm8994-gpio.o -obj-$(CONFIG_GPIO_SCH) += sch_gpio.o \ No newline at end of file +obj-$(CONFIG_GPIO_SCH) += sch_gpio.o +obj-$(CONFIG_GPIO_RDC321X) += rdc321x-gpio.o diff --git a/drivers/gpio/rdc321x-gpio.c b/drivers/gpio/rdc321x-gpio.c new file mode 100644 index 000000000000..46c55193b9db --- /dev/null +++ b/drivers/gpio/rdc321x-gpio.c @@ -0,0 +1,245 @@ +/* + * RDC321x GPIO driver + * + * Copyright (C) 2008, Volker Weiss + * Copyright (C) 2007-2010 Florian Fainelli + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +struct rdc321x_gpio { + spinlock_t lock; + struct pci_dev *sb_pdev; + u32 data_reg[2]; + int reg1_ctrl_base; + int reg1_data_base; + int reg2_ctrl_base; + int reg2_data_base; + struct gpio_chip chip; +}; + +/* read GPIO pin */ +static int rdc_gpio_get_value(struct gpio_chip *chip, unsigned gpio) +{ + struct rdc321x_gpio *gpch; + u32 value = 0; + int reg; + + gpch = container_of(chip, struct rdc321x_gpio, chip); + reg = gpio < 32 ? gpch->reg1_data_base : gpch->reg2_data_base; + + spin_lock(&gpch->lock); + pci_write_config_dword(gpch->sb_pdev, reg, + gpch->data_reg[gpio < 32 ? 0 : 1]); + pci_read_config_dword(gpch->sb_pdev, reg, &value); + spin_unlock(&gpch->lock); + + return (1 << (gpio & 0x1f)) & value ? 1 : 0; +} + +static void rdc_gpio_set_value_impl(struct gpio_chip *chip, + unsigned gpio, int value) +{ + struct rdc321x_gpio *gpch; + int reg = (gpio < 32) ? 0 : 1; + + gpch = container_of(chip, struct rdc321x_gpio, chip); + + if (value) + gpch->data_reg[reg] |= 1 << (gpio & 0x1f); + else + gpch->data_reg[reg] &= ~(1 << (gpio & 0x1f)); + + pci_write_config_dword(gpch->sb_pdev, + reg ? gpch->reg1_data_base : gpch->reg2_data_base, + gpch->data_reg[reg]); +} + +/* set GPIO pin to value */ +static void rdc_gpio_set_value(struct gpio_chip *chip, + unsigned gpio, int value) +{ + struct rdc321x_gpio *gpch; + + gpch = container_of(chip, struct rdc321x_gpio, chip); + spin_lock(&gpch->lock); + rdc_gpio_set_value_impl(chip, gpio, value); + spin_unlock(&gpch->lock); +} + +static int rdc_gpio_config(struct gpio_chip *chip, + unsigned gpio, int value) +{ + struct rdc321x_gpio *gpch; + int err; + u32 reg; + + gpch = container_of(chip, struct rdc321x_gpio, chip); + + spin_lock(&gpch->lock); + err = pci_read_config_dword(gpch->sb_pdev, gpio < 32 ? + gpch->reg1_ctrl_base : gpch->reg2_ctrl_base, ®); + if (err) + goto unlock; + + reg |= 1 << (gpio & 0x1f); + + err = pci_write_config_dword(gpch->sb_pdev, gpio < 32 ? + gpch->reg1_ctrl_base : gpch->reg2_ctrl_base, reg); + if (err) + goto unlock; + + rdc_gpio_set_value_impl(chip, gpio, value); + +unlock: + spin_unlock(&gpch->lock); + + return err; +} + +/* configure GPIO pin as input */ +static int rdc_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) +{ + return rdc_gpio_config(chip, gpio, 1); +} + +/* + * Cache the initial value of both GPIO data registers + */ +static int __devinit rdc321x_gpio_probe(struct platform_device *pdev) +{ + int err; + struct resource *r; + struct rdc321x_gpio *rdc321x_gpio_dev; + struct rdc321x_gpio_pdata *pdata; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "no platform data supplied\n"); + return -ENODEV; + } + + rdc321x_gpio_dev = kzalloc(sizeof(struct rdc321x_gpio), GFP_KERNEL); + if (!rdc321x_gpio_dev) { + dev_err(&pdev->dev, "failed to allocate private data\n"); + return -ENOMEM; + } + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gpio-reg1"); + if (!r) { + dev_err(&pdev->dev, "failed to get gpio-reg1 resource\n"); + err = -ENODEV; + goto out_free; + } + + spin_lock_init(&rdc321x_gpio_dev->lock); + rdc321x_gpio_dev->sb_pdev = pdata->sb_pdev; + rdc321x_gpio_dev->reg1_ctrl_base = r->start; + rdc321x_gpio_dev->reg1_data_base = r->start + 0x4; + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gpio-reg2"); + if (!r) { + dev_err(&pdev->dev, "failed to get gpio-reg2 resource\n"); + err = -ENODEV; + goto out_free; + } + + rdc321x_gpio_dev->reg2_ctrl_base = r->start; + rdc321x_gpio_dev->reg2_data_base = r->start + 0x4; + + rdc321x_gpio_dev->chip.label = "rdc321x-gpio"; + rdc321x_gpio_dev->chip.direction_input = rdc_gpio_direction_input; + rdc321x_gpio_dev->chip.direction_output = rdc_gpio_config; + rdc321x_gpio_dev->chip.get = rdc_gpio_get_value; + rdc321x_gpio_dev->chip.set = rdc_gpio_set_value; + rdc321x_gpio_dev->chip.base = 0; + rdc321x_gpio_dev->chip.ngpio = pdata->max_gpios; + + platform_set_drvdata(pdev, rdc321x_gpio_dev); + + /* This might not be, what others (BIOS, bootloader, etc.) + wrote to these registers before, but it's a good guess. Still + better than just using 0xffffffff. */ + err = pci_read_config_dword(rdc321x_gpio_dev->sb_pdev, + rdc321x_gpio_dev->reg1_data_base, + &rdc321x_gpio_dev->data_reg[0]); + if (err) + goto out_drvdata; + + err = pci_read_config_dword(rdc321x_gpio_dev->sb_pdev, + rdc321x_gpio_dev->reg2_data_base, + &rdc321x_gpio_dev->data_reg[1]); + if (err) + goto out_drvdata; + + dev_info(&pdev->dev, "registering %d GPIOs\n", + rdc321x_gpio_dev->chip.ngpio); + return gpiochip_add(&rdc321x_gpio_dev->chip); + +out_drvdata: + platform_set_drvdata(pdev, NULL); +out_free: + kfree(rdc321x_gpio_dev); + return err; +} + +static int __devexit rdc321x_gpio_remove(struct platform_device *pdev) +{ + int ret; + struct rdc321x_gpio *rdc321x_gpio_dev = platform_get_drvdata(pdev); + + ret = gpiochip_remove(&rdc321x_gpio_dev->chip); + if (ret) + dev_err(&pdev->dev, "failed to unregister chip\n"); + + kfree(rdc321x_gpio_dev); + platform_set_drvdata(pdev, NULL); + + return ret; +} + +static struct platform_driver rdc321x_gpio_driver = { + .driver.name = "rdc321x-gpio", + .driver.owner = THIS_MODULE, + .probe = rdc321x_gpio_probe, + .remove = __devexit_p(rdc321x_gpio_remove), +}; + +static int __init rdc321x_gpio_init(void) +{ + return platform_driver_register(&rdc321x_gpio_driver); +} + +static void __exit rdc321x_gpio_exit(void) +{ + platform_driver_unregister(&rdc321x_gpio_driver); +} + +module_init(rdc321x_gpio_init); +module_exit(rdc321x_gpio_exit); + +MODULE_AUTHOR("Florian Fainelli "); +MODULE_DESCRIPTION("RDC321x GPIO driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:rdc321x-gpio"); -- cgit v1.2.3 From 842102f35a8da589486fac497885b7bd6053af2f Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 22 Mar 2010 22:56:24 -0400 Subject: watchdog: Convert rdc321x_wdt to use southbridge pci device The RDC321x MFD southbridge driver will pass a reference to the southbridge PCI device which should be used by the watchdog driver for its operations. This patch converts the watchdog driver to use the pci_dev pointer and make use of the base register resource which is passed along with the platform device. Signed-off-by: Florian Fainelli Acked-by: Wim Van Sebroeck Signed-off-by: Samuel Ortiz --- drivers/watchdog/rdc321x_wdt.c | 53 +++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c index 69c6adbd8205..4733a99955dd 100644 --- a/drivers/watchdog/rdc321x_wdt.c +++ b/drivers/watchdog/rdc321x_wdt.c @@ -1,7 +1,7 @@ /* * RDC321x watchdog driver * - * Copyright (C) 2007 Florian Fainelli + * Copyright (C) 2007-2010 Florian Fainelli * * This driver is highly inspired from the cpu5_wdt driver * @@ -36,8 +36,7 @@ #include #include #include - -#include +#include #define RDC_WDT_MASK 0x80000000 /* Mask */ #define RDC_WDT_EN 0x00800000 /* Enable bit */ @@ -63,6 +62,8 @@ static struct { int default_ticks; unsigned long inuse; spinlock_t lock; + struct pci_dev *sb_pdev; + int base_reg; } rdc321x_wdt_device; /* generic helper functions */ @@ -70,14 +71,18 @@ static struct { static void rdc321x_wdt_trigger(unsigned long unused) { unsigned long flags; + u32 val; if (rdc321x_wdt_device.running) ticks--; /* keep watchdog alive */ spin_lock_irqsave(&rdc321x_wdt_device.lock, flags); - outl(RDC_WDT_EN | inl(RDC3210_CFGREG_DATA), - RDC3210_CFGREG_DATA); + pci_read_config_dword(rdc321x_wdt_device.sb_pdev, + rdc321x_wdt_device.base_reg, &val); + val |= RDC_WDT_EN; + pci_write_config_dword(rdc321x_wdt_device.sb_pdev, + rdc321x_wdt_device.base_reg, val); spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags); /* requeue?? */ @@ -105,10 +110,13 @@ static void rdc321x_wdt_start(void) /* Clear the timer */ spin_lock_irqsave(&rdc321x_wdt_device.lock, flags); - outl(RDC_CLS_TMR, RDC3210_CFGREG_ADDR); + pci_write_config_dword(rdc321x_wdt_device.sb_pdev, + rdc321x_wdt_device.base_reg, RDC_CLS_TMR); /* Enable watchdog and set the timeout to 81.92 us */ - outl(RDC_WDT_EN | RDC_WDT_CNT, RDC3210_CFGREG_DATA); + pci_write_config_dword(rdc321x_wdt_device.sb_pdev, + rdc321x_wdt_device.base_reg, + RDC_WDT_EN | RDC_WDT_CNT); spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags); mod_timer(&rdc321x_wdt_device.timer, @@ -148,7 +156,7 @@ static long rdc321x_wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; - unsigned int value; + u32 value; static const struct watchdog_info ident = { .options = WDIOF_CARDRESET, .identity = "RDC321x WDT", @@ -162,9 +170,10 @@ static long rdc321x_wdt_ioctl(struct file *file, unsigned int cmd, case WDIOC_GETSTATUS: /* Read the value from the DATA register */ spin_lock_irqsave(&rdc321x_wdt_device.lock, flags); - value = inl(RDC3210_CFGREG_DATA); + pci_read_config_dword(rdc321x_wdt_device.sb_pdev, + rdc321x_wdt_device.base_reg, &value); spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags); - if (copy_to_user(argp, &value, sizeof(int))) + if (copy_to_user(argp, &value, sizeof(u32))) return -EFAULT; break; case WDIOC_GETSUPPORT: @@ -219,17 +228,35 @@ static struct miscdevice rdc321x_wdt_misc = { static int __devinit rdc321x_wdt_probe(struct platform_device *pdev) { int err; + struct resource *r; + struct rdc321x_wdt_pdata *pdata; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "no platform data supplied\n"); + return -ENODEV; + } + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wdt-reg"); + if (!r) { + dev_err(&pdev->dev, "failed to get wdt-reg resource\n"); + return -ENODEV; + } + + rdc321x_wdt_device.sb_pdev = pdata->sb_pdev; + rdc321x_wdt_device.base_reg = r->start; err = misc_register(&rdc321x_wdt_misc); if (err < 0) { - printk(KERN_ERR PFX "watchdog misc_register failed\n"); + dev_err(&pdev->dev, "misc_register failed\n"); return err; } spin_lock_init(&rdc321x_wdt_device.lock); /* Reset the watchdog */ - outl(RDC_WDT_RST, RDC3210_CFGREG_DATA); + pci_write_config_dword(rdc321x_wdt_device.sb_pdev, + rdc321x_wdt_device.base_reg, RDC_WDT_RST); init_completion(&rdc321x_wdt_device.stop); rdc321x_wdt_device.queue = 0; @@ -240,7 +267,7 @@ static int __devinit rdc321x_wdt_probe(struct platform_device *pdev) rdc321x_wdt_device.default_ticks = ticks; - printk(KERN_INFO PFX "watchdog init success\n"); + dev_info(&pdev->dev, "watchdog init success\n"); return 0; } -- cgit v1.2.3 From 5f7df57eeca93fc931b32e7723fe8f964aaa63df Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 22 Mar 2010 15:12:42 +0300 Subject: mfd: Off by one calculating size for timberdale MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I'm pretty sure that it should be + 1 here. It's an off by one, because we start counting at zero. Signed-off-by: Dan Carpenter Acked-by: Richard Röjfors Signed-off-by: Samuel Ortiz --- drivers/mfd/timberdale.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mfd/timberdale.h b/drivers/mfd/timberdale.h index 8d27ffabc25d..902c45120241 100644 --- a/drivers/mfd/timberdale.h +++ b/drivers/mfd/timberdale.h @@ -66,7 +66,7 @@ #define CHIPCTLOFFSET 0x800 #define CHIPCTLEND 0x8ff -#define CHIPCTLSIZE (CHIPCTLEND - CHIPCTLOFFSET) +#define CHIPCTLSIZE (CHIPCTLEND - CHIPCTLOFFSET + 1) #define INTCOFFSET 0xc00 #define INTCEND 0xfff -- cgit v1.2.3 From f03cfcbc843ae6854c69dbc771762b83b3bea15f Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Fri, 26 Mar 2010 01:09:04 +0100 Subject: mfd: Check for mem_base when building IORESOURCE_MEM resources If mem_base is NULL, then we fall back to the default case, just copying the original resource. Signed-off-by: Samuel Ortiz --- drivers/mfd/mfd-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 8ffbb7a85a7e..7dd76bceaae8 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -48,7 +48,7 @@ static int mfd_add_device(struct device *parent, int id, res[r].flags = cell->resources[r].flags; /* Find out base to use */ - if (cell->resources[r].flags & IORESOURCE_MEM) { + if ((cell->resources[r].flags & IORESOURCE_MEM) && mem_base) { res[r].parent = mem_base; res[r].start = mem_base->start + cell->resources[r].start; -- cgit v1.2.3 From 872c1b14e78661086ade8b501888850da2636eee Mon Sep 17 00:00:00 2001 From: Henrik Kretzschmar Date: Fri, 26 Mar 2010 02:40:13 +0100 Subject: mfd: Section cleanup of 88pm860x driver This patch fixes three section mismatches. WARNING: drivers/mfd/88pm860x.o(.text+0x12): Section mismatch in reference from the function pm860x_device_exit() to the function .devexit.text:device_irq_exit() The function pm860x_device_exit() references a function in an exit section. Often the function device_irq_exit() has valid usage outside the exit section and the fix is to remove the __devexit annotation of device_irq_exit. WARNING: drivers/mfd/88pm860x.o(.text+0xb0): Section mismatch in reference from the function pm860x_device_init() to the function .devinit.text:device_8606_init() The function pm860x_device_init() references the function __devinit device_8606_init(). This is often because pm860x_device_init lacks a __devinit annotation or the annotation of device_8606_init is wrong. WARNING: drivers/mfd/88pm860x.o(.text+0xbe): Section mismatch in reference from the function pm860x_device_init() to the function .devinit.text:device_8607_init() The function pm860x_device_init() references the function __devinit device_8607_init(). This is often because pm860x_device_init lacks a __devinit annotation or the annotation of device_8607_init is wrong. Signed-off-by: Henrik Kretzschmar Signed-off-by: Samuel Ortiz --- drivers/mfd/88pm860x-core.c | 6 +++--- include/linux/mfd/88pm860x.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index 405d2d5183cf..2c65a2c57294 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c @@ -566,7 +566,7 @@ out: return ret; } -static void __devexit device_irq_exit(struct pm860x_chip *chip) +static void device_irq_exit(struct pm860x_chip *chip) { if (chip->core_irq) free_irq(chip->core_irq, chip); @@ -703,7 +703,7 @@ out: return; } -int pm860x_device_init(struct pm860x_chip *chip, +int __devinit pm860x_device_init(struct pm860x_chip *chip, struct pm860x_platform_data *pdata) { chip->core_irq = 0; @@ -731,7 +731,7 @@ int pm860x_device_init(struct pm860x_chip *chip, return 0; } -void pm860x_device_exit(struct pm860x_chip *chip) +void __devexit pm860x_device_exit(struct pm860x_chip *chip) { device_irq_exit(chip); mfd_remove_devices(chip->dev); diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h index e3c4ff8c3e38..bfd23bef7363 100644 --- a/include/linux/mfd/88pm860x.h +++ b/include/linux/mfd/88pm860x.h @@ -370,7 +370,7 @@ extern int pm860x_set_bits(struct i2c_client *, int, unsigned char, unsigned char); extern int pm860x_device_init(struct pm860x_chip *chip, - struct pm860x_platform_data *pdata); -extern void pm860x_device_exit(struct pm860x_chip *chip); + struct pm860x_platform_data *pdata) __devinit ; +extern void pm860x_device_exit(struct pm860x_chip *chip) __devexit ; #endif /* __LINUX_MFD_88PM860X_H */ -- cgit v1.2.3 From dc64f30fa557ab1108e97e499a9acc550baa38bc Mon Sep 17 00:00:00 2001 From: Richard Röjfors Date: Thu, 25 Mar 2010 19:44:23 +0100 Subject: mfd: Add timb-dma to all configurations of timberdale MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add platform data for timb-dma, and add it in to timb-dma in all configurations of timberdale. Also incremented the version number. Signed-off-by: Richard Röjfors Signed-off-by: Samuel Ortiz --- drivers/mfd/timberdale.c | 97 +++++++++++++++++++++++++++++++++++++++++------- drivers/mfd/timberdale.h | 14 ++++++- 2 files changed, 96 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c index 1ac77d16dce9..2d4691acd033 100644 --- a/drivers/mfd/timberdale.c +++ b/drivers/mfd/timberdale.c @@ -41,6 +41,8 @@ #include +#include + #include "timberdale.h" #define DRIVER_NAME "timberdale" @@ -270,6 +272,65 @@ static __devinitdata struct timb_radio_platform_data } }; +static __devinitdata struct timb_dma_platform_data timb_dma_platform_data = { + .nr_channels = 10, + .channels = { + { + /* UART RX */ + .rx = true, + .descriptors = 2, + .descriptor_elements = 1 + }, + { + /* UART TX */ + .rx = false, + .descriptors = 2, + .descriptor_elements = 1 + }, + { + /* MLB RX */ + .rx = true, + .descriptors = 2, + .descriptor_elements = 1 + }, + { + /* MLB TX */ + .rx = false, + .descriptors = 2, + .descriptor_elements = 1 + }, + { + /* Video RX */ + .rx = true, + .bytes_per_line = 1440, + .descriptors = 2, + .descriptor_elements = 16 + }, + { + /* Video framedrop */ + }, + { + /* SDHCI RX */ + .rx = true, + }, + { + /* SDHCI TX */ + }, + { + /* ETH RX */ + .rx = true, + .descriptors = 2, + .descriptor_elements = 1 + }, + { + /* ETH TX */ + .rx = false, + .descriptors = 2, + .descriptor_elements = 1 + }, + } +}; + const static __devinitconst struct resource timberdale_dma_resources[] = { { .start = DMAOFFSET, @@ -284,6 +345,13 @@ const static __devinitconst struct resource timberdale_dma_resources[] = { }; static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg0[] = { + { + .name = "timb-dma", + .num_resources = ARRAY_SIZE(timberdale_dma_resources), + .resources = timberdale_dma_resources, + .platform_data = &timb_dma_platform_data, + .data_size = sizeof(timb_dma_platform_data), + }, { .name = "timb-uart", .num_resources = ARRAY_SIZE(timberdale_uart_resources), @@ -322,14 +390,16 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg0[] = { .num_resources = ARRAY_SIZE(timberdale_eth_resources), .resources = timberdale_eth_resources, }, +}; + +static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = { { .name = "timb-dma", .num_resources = ARRAY_SIZE(timberdale_dma_resources), .resources = timberdale_dma_resources, + .platform_data = &timb_dma_platform_data, + .data_size = sizeof(timb_dma_platform_data), }, -}; - -static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = { { .name = "timb-uart", .num_resources = ARRAY_SIZE(timberdale_uart_resources), @@ -378,14 +448,16 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = { .num_resources = ARRAY_SIZE(timberdale_eth_resources), .resources = timberdale_eth_resources, }, +}; + +static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg2[] = { { .name = "timb-dma", .num_resources = ARRAY_SIZE(timberdale_dma_resources), .resources = timberdale_dma_resources, + .platform_data = &timb_dma_platform_data, + .data_size = sizeof(timb_dma_platform_data), }, -}; - -static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg2[] = { { .name = "timb-uart", .num_resources = ARRAY_SIZE(timberdale_uart_resources), @@ -419,14 +491,16 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg2[] = { .platform_data = &timberdale_xspi_platform_data, .data_size = sizeof(timberdale_xspi_platform_data), }, +}; + +static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg3[] = { { .name = "timb-dma", .num_resources = ARRAY_SIZE(timberdale_dma_resources), .resources = timberdale_dma_resources, + .platform_data = &timb_dma_platform_data, + .data_size = sizeof(timb_dma_platform_data), }, -}; - -static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg3[] = { { .name = "timb-uart", .num_resources = ARRAY_SIZE(timberdale_uart_resources), @@ -465,11 +539,6 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg3[] = { .num_resources = ARRAY_SIZE(timberdale_eth_resources), .resources = timberdale_eth_resources, }, - { - .name = "timb-dma", - .num_resources = ARRAY_SIZE(timberdale_dma_resources), - .resources = timberdale_dma_resources, - }, }; static const __devinitconst struct resource timberdale_sdhc_resources[] = { diff --git a/drivers/mfd/timberdale.h b/drivers/mfd/timberdale.h index 902c45120241..c11bf6ebfe00 100644 --- a/drivers/mfd/timberdale.h +++ b/drivers/mfd/timberdale.h @@ -23,7 +23,7 @@ #ifndef MFD_TIMBERDALE_H #define MFD_TIMBERDALE_H -#define DRV_VERSION "0.1" +#define DRV_VERSION "0.2" /* This driver only support versions >= 3.8 and < 4.0 */ #define TIMB_SUPPORTED_MAJOR 3 @@ -127,4 +127,16 @@ #define GPIO_PIN_BT_RST 15 #define GPIO_NR_PINS 16 +/* DMA Channels */ +#define DMA_UART_RX 0 +#define DMA_UART_TX 1 +#define DMA_MLB_RX 2 +#define DMA_MLB_TX 3 +#define DMA_VIDEO_RX 4 +#define DMA_VIDEO_DROP 5 +#define DMA_SDHCI_RX 6 +#define DMA_SDHCI_TX 7 +#define DMA_ETH_RX 8 +#define DMA_ETH_TX 9 + #endif -- cgit v1.2.3 From 2a0cb351001bebf195d3c43d0f70441eb6a62652 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 26 Mar 2010 14:47:04 +0000 Subject: mfd: Remove unused wm831x IRQ handler data This was used by the old, pre-genirq IRQ implementation but is no longer required. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/wm831x-irq.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c index 4c1122ceb443..ec10004200c9 100644 --- a/drivers/mfd/wm831x-irq.c +++ b/drivers/mfd/wm831x-irq.c @@ -39,8 +39,6 @@ struct wm831x_irq_data { int primary; int reg; int mask; - irq_handler_t handler; - void *handler_data; }; static struct wm831x_irq_data wm831x_irqs[] = { -- cgit v1.2.3 From 165bce9783ab307368e56b7c1a168520a3791266 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 28 Mar 2010 14:28:08 +0300 Subject: mfd: Proper pcf50633 irq check "pcf->irq_handler" has PCF50633_NUM_IRQ elements. Signed-off-by: Dan Carpenter Signed-off-by: Samuel Ortiz --- drivers/mfd/pcf50633-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 710e417e0eec..5439282804cc 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -218,7 +218,7 @@ static struct attribute_group pcf_attr_group = { int pcf50633_register_irq(struct pcf50633 *pcf, int irq, void (*handler) (int, void *), void *data) { - if (irq < 0 || irq > PCF50633_NUM_IRQ || !handler) + if (irq < 0 || irq >= PCF50633_NUM_IRQ || !handler) return -EINVAL; if (WARN_ON(pcf->irq_handler[irq].handler)) @@ -235,7 +235,7 @@ EXPORT_SYMBOL_GPL(pcf50633_register_irq); int pcf50633_free_irq(struct pcf50633 *pcf, int irq) { - if (irq < 0 || irq > PCF50633_NUM_IRQ) + if (irq < 0 || irq >= PCF50633_NUM_IRQ) return -EINVAL; mutex_lock(&pcf->lock); -- cgit v1.2.3 From bd3581323cc02aefc79a21780a4ca8c578642892 Mon Sep 17 00:00:00 2001 From: "Ira W. Snyder" Date: Wed, 7 Apr 2010 09:43:00 +0200 Subject: mfd: Janz CMOD-IO PCI MODULbus Carrier Board support The Janz CMOD-IO PCI MODULbus carrier board is a PCI to MODULbus bridge, which may host many different types of MODULbus daughterboards, including CAN and GPIO controllers. Signed-off-by: Ira W. Snyder Reviewed-by: Wolfgang Grandegger Signed-off-by: Samuel Ortiz --- drivers/mfd/Kconfig | 10 ++ drivers/mfd/Makefile | 1 + drivers/mfd/janz-cmodio.c | 304 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/mfd/janz.h | 54 ++++++++ 4 files changed, 369 insertions(+) create mode 100644 drivers/mfd/janz-cmodio.c create mode 100644 include/linux/mfd/janz.h (limited to 'drivers') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 93d0e31c0438..05c137d16b04 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -418,6 +418,16 @@ config MFD_RDC321X southbridge which provides access to GPIOs and Watchdog using the southbridge PCI device configuration space. +config MFD_JANZ_CMODIO + tristate "Support for Janz CMOD-IO PCI MODULbus Carrier Board" + select MFD_CORE + depends on PCI + help + This is the core driver for the Janz CMOD-IO PCI MODULbus + carrier board. This device is a PCI to MODULbus bridge which may + host many different types of MODULbus daughterboards, including + CAN and GPIO controllers. + endmenu menu "Multimedia Capabilities Port drivers" diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index f177e064b31b..21eff85b288a 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -65,3 +65,4 @@ obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o obj-$(CONFIG_PMIC_ADP5520) += adp5520.o obj-$(CONFIG_LPC_SCH) += lpc_sch.o obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o +obj-$(CONFIG_MFD_JANZ_CMODIO) += janz-cmodio.o diff --git a/drivers/mfd/janz-cmodio.c b/drivers/mfd/janz-cmodio.c new file mode 100644 index 000000000000..9ed630799acc --- /dev/null +++ b/drivers/mfd/janz-cmodio.c @@ -0,0 +1,304 @@ +/* + * Janz CMOD-IO MODULbus Carrier Board PCI Driver + * + * Copyright (c) 2010 Ira W. Snyder + * + * Lots of inspiration and code was copied from drivers/mfd/sm501.c + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DRV_NAME "janz-cmodio" + +/* Size of each MODULbus module in PCI BAR4 */ +#define CMODIO_MODULBUS_SIZE 0x200 + +/* Maximum number of MODULbus modules on a CMOD-IO carrier board */ +#define CMODIO_MAX_MODULES 4 + +/* Module Parameters */ +static unsigned int num_modules = CMODIO_MAX_MODULES; +static unsigned char *modules[CMODIO_MAX_MODULES] = { + "empty", "empty", "empty", "empty", +}; + +module_param_array(modules, charp, &num_modules, S_IRUGO); +MODULE_PARM_DESC(modules, "MODULbus modules attached to the carrier board"); + +/* Unique Device Id */ +static unsigned int cmodio_id; + +struct cmodio_device { + /* Parent PCI device */ + struct pci_dev *pdev; + + /* PLX control registers */ + struct janz_cmodio_onboard_regs __iomem *ctrl; + + /* hex switch position */ + u8 hex; + + /* mfd-core API */ + struct mfd_cell cells[CMODIO_MAX_MODULES]; + struct resource resources[3 * CMODIO_MAX_MODULES]; + struct janz_platform_data pdata[CMODIO_MAX_MODULES]; +}; + +/* + * Subdevices using the mfd-core API + */ + +static int __devinit cmodio_setup_subdevice(struct cmodio_device *priv, + char *name, unsigned int devno, + unsigned int modno) +{ + struct janz_platform_data *pdata; + struct mfd_cell *cell; + struct resource *res; + struct pci_dev *pci; + + pci = priv->pdev; + cell = &priv->cells[devno]; + res = &priv->resources[devno * 3]; + pdata = &priv->pdata[devno]; + + cell->name = name; + cell->resources = res; + cell->num_resources = 3; + + /* Setup the subdevice ID -- must be unique */ + cell->id = cmodio_id++; + + /* Add platform data */ + pdata->modno = modno; + cell->platform_data = pdata; + cell->data_size = sizeof(*pdata); + + /* MODULbus registers -- PCI BAR3 is big-endian MODULbus access */ + res->flags = IORESOURCE_MEM; + res->parent = &pci->resource[3]; + res->start = pci->resource[3].start + (CMODIO_MODULBUS_SIZE * modno); + res->end = res->start + CMODIO_MODULBUS_SIZE - 1; + res++; + + /* PLX Control Registers -- PCI BAR4 is interrupt and other registers */ + res->flags = IORESOURCE_MEM; + res->parent = &pci->resource[4]; + res->start = pci->resource[4].start; + res->end = pci->resource[4].end; + res++; + + /* + * IRQ + * + * The start and end fields are used as an offset to the irq_base + * parameter passed into the mfd_add_devices() function call. All + * devices share the same IRQ. + */ + res->flags = IORESOURCE_IRQ; + res->parent = NULL; + res->start = 0; + res->end = 0; + res++; + + return 0; +} + +/* Probe each submodule using kernel parameters */ +static int __devinit cmodio_probe_submodules(struct cmodio_device *priv) +{ + struct pci_dev *pdev = priv->pdev; + unsigned int num_probed = 0; + char *name; + int i; + + for (i = 0; i < num_modules; i++) { + name = modules[i]; + if (!strcmp(name, "") || !strcmp(name, "empty")) + continue; + + dev_dbg(&priv->pdev->dev, "MODULbus %d: name %s\n", i, name); + cmodio_setup_subdevice(priv, name, num_probed, i); + num_probed++; + } + + /* print an error message if no modules were probed */ + if (num_probed == 0) { + dev_err(&priv->pdev->dev, "no MODULbus modules specified, " + "please set the ``modules'' kernel " + "parameter according to your " + "hardware configuration\n"); + return -ENODEV; + } + + return mfd_add_devices(&pdev->dev, 0, priv->cells, + num_probed, NULL, pdev->irq); +} + +/* + * SYSFS Attributes + */ + +static ssize_t mbus_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct cmodio_device *priv = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%x\n", priv->hex); +} + +static DEVICE_ATTR(modulbus_number, S_IRUGO, mbus_show, NULL); + +static struct attribute *cmodio_sysfs_attrs[] = { + &dev_attr_modulbus_number.attr, + NULL, +}; + +static const struct attribute_group cmodio_sysfs_attr_group = { + .attrs = cmodio_sysfs_attrs, +}; + +/* + * PCI Driver + */ + +static int __devinit cmodio_pci_probe(struct pci_dev *dev, + const struct pci_device_id *id) +{ + struct cmodio_device *priv; + int ret; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + dev_err(&dev->dev, "unable to allocate private data\n"); + ret = -ENOMEM; + goto out_return; + } + + pci_set_drvdata(dev, priv); + priv->pdev = dev; + + /* Hardware Initialization */ + ret = pci_enable_device(dev); + if (ret) { + dev_err(&dev->dev, "unable to enable device\n"); + goto out_free_priv; + } + + pci_set_master(dev); + ret = pci_request_regions(dev, DRV_NAME); + if (ret) { + dev_err(&dev->dev, "unable to request regions\n"); + goto out_pci_disable_device; + } + + /* Onboard configuration registers */ + priv->ctrl = pci_ioremap_bar(dev, 4); + if (!priv->ctrl) { + dev_err(&dev->dev, "unable to remap onboard regs\n"); + ret = -ENOMEM; + goto out_pci_release_regions; + } + + /* Read the hex switch on the carrier board */ + priv->hex = ioread8(&priv->ctrl->int_enable); + + /* Add the MODULbus number (hex switch value) to the device's sysfs */ + ret = sysfs_create_group(&dev->dev.kobj, &cmodio_sysfs_attr_group); + if (ret) { + dev_err(&dev->dev, "unable to create sysfs attributes\n"); + goto out_unmap_ctrl; + } + + /* + * Disable all interrupt lines, each submodule will enable its + * own interrupt line if needed + */ + iowrite8(0xf, &priv->ctrl->int_disable); + + /* Register drivers for all submodules */ + ret = cmodio_probe_submodules(priv); + if (ret) { + dev_err(&dev->dev, "unable to probe submodules\n"); + goto out_sysfs_remove_group; + } + + return 0; + +out_sysfs_remove_group: + sysfs_remove_group(&dev->dev.kobj, &cmodio_sysfs_attr_group); +out_unmap_ctrl: + iounmap(priv->ctrl); +out_pci_release_regions: + pci_release_regions(dev); +out_pci_disable_device: + pci_disable_device(dev); +out_free_priv: + kfree(priv); +out_return: + return ret; +} + +static void __devexit cmodio_pci_remove(struct pci_dev *dev) +{ + struct cmodio_device *priv = pci_get_drvdata(dev); + + mfd_remove_devices(&dev->dev); + sysfs_remove_group(&dev->dev.kobj, &cmodio_sysfs_attr_group); + iounmap(priv->ctrl); + pci_release_regions(dev); + pci_disable_device(dev); + kfree(priv); +} + +#define PCI_VENDOR_ID_JANZ 0x13c3 + +/* The list of devices that this module will support */ +static DEFINE_PCI_DEVICE_TABLE(cmodio_pci_ids) = { + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_JANZ, 0x0101 }, + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_JANZ, 0x0100 }, + { 0, } +}; +MODULE_DEVICE_TABLE(pci, cmodio_pci_ids); + +static struct pci_driver cmodio_pci_driver = { + .name = DRV_NAME, + .id_table = cmodio_pci_ids, + .probe = cmodio_pci_probe, + .remove = __devexit_p(cmodio_pci_remove), +}; + +/* + * Module Init / Exit + */ + +static int __init cmodio_init(void) +{ + return pci_register_driver(&cmodio_pci_driver); +} + +static void __exit cmodio_exit(void) +{ + pci_unregister_driver(&cmodio_pci_driver); +} + +MODULE_AUTHOR("Ira W. Snyder "); +MODULE_DESCRIPTION("Janz CMOD-IO PCI MODULbus Carrier Board Driver"); +MODULE_LICENSE("GPL"); + +module_init(cmodio_init); +module_exit(cmodio_exit); diff --git a/include/linux/mfd/janz.h b/include/linux/mfd/janz.h new file mode 100644 index 000000000000..e9994c469803 --- /dev/null +++ b/include/linux/mfd/janz.h @@ -0,0 +1,54 @@ +/* + * Common Definitions for Janz MODULbus devices + * + * Copyright (c) 2010 Ira W. Snyder + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef JANZ_H +#define JANZ_H + +struct janz_platform_data { + /* MODULbus Module Number */ + unsigned int modno; +}; + +/* PLX bridge chip onboard registers */ +struct janz_cmodio_onboard_regs { + u8 unused1; + + /* + * Read access: interrupt status + * Write access: interrupt disable + */ + u8 int_disable; + u8 unused2; + + /* + * Read access: MODULbus number (hex switch) + * Write access: interrupt enable + */ + u8 int_enable; + u8 unused3; + + /* write-only */ + u8 reset_assert; + u8 unused4; + + /* write-only */ + u8 reset_deassert; + u8 unused5; + + /* read-write access to serial EEPROM */ + u8 eep; + u8 unused6; + + /* write-only access to EEPROM chip select */ + u8 enid; +}; + +#endif /* JANZ_H */ -- cgit v1.2.3 From 631eb227849e3bfdec2d2e628ee5a3f962db82e2 Mon Sep 17 00:00:00 2001 From: "Ira W. Snyder" Date: Mon, 29 Mar 2010 09:58:51 -0700 Subject: can: Add support for Janz VMOD-ICAN3 Intelligent CAN module The Janz VMOD-ICAN3 is a MODULbus daughterboard which fits onto any MODULbus carrier board. It is an intelligent CAN controller with a microcontroller and associated firmware. Signed-off-by: Ira W. Snyder Acked-by: Wolfgang Grandegger Acked-by: David S. Miller Signed-off-by: Samuel Ortiz --- drivers/net/can/Kconfig | 10 + drivers/net/can/Makefile | 1 + drivers/net/can/janz-ican3.c | 1830 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1841 insertions(+) create mode 100644 drivers/net/can/janz-ican3.c (limited to 'drivers') diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 05b751719bd5..2c5227c02fa0 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -63,6 +63,16 @@ config CAN_BFIN To compile this driver as a module, choose M here: the module will be called bfin_can. +config CAN_JANZ_ICAN3 + tristate "Janz VMOD-ICAN3 Intelligent CAN controller" + depends on CAN_DEV && MFD_JANZ_CMODIO + ---help--- + Driver for Janz VMOD-ICAN3 Intelligent CAN controller module, which + connects to a MODULbus carrier board. + + This driver can also be built as a module. If so, the module will be + called janz-ican3.ko. + source "drivers/net/can/mscan/Kconfig" source "drivers/net/can/sja1000/Kconfig" diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile index 7a702f28d01c..9047cd066fea 100644 --- a/drivers/net/can/Makefile +++ b/drivers/net/can/Makefile @@ -15,5 +15,6 @@ obj-$(CONFIG_CAN_AT91) += at91_can.o obj-$(CONFIG_CAN_TI_HECC) += ti_hecc.o obj-$(CONFIG_CAN_MCP251X) += mcp251x.o obj-$(CONFIG_CAN_BFIN) += bfin_can.o +obj-$(CONFIG_CAN_JANZ_ICAN3) += janz-ican3.o ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c new file mode 100644 index 000000000000..6e533dcc36c0 --- /dev/null +++ b/drivers/net/can/janz-ican3.c @@ -0,0 +1,1830 @@ +/* + * Janz MODULbus VMOD-ICAN3 CAN Interface Driver + * + * Copyright (c) 2010 Ira W. Snyder + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/* the DPM has 64k of memory, organized into 256x 256 byte pages */ +#define DPM_NUM_PAGES 256 +#define DPM_PAGE_SIZE 256 +#define DPM_PAGE_ADDR(p) ((p) * DPM_PAGE_SIZE) + +/* JANZ ICAN3 "old-style" host interface queue page numbers */ +#define QUEUE_OLD_CONTROL 0 +#define QUEUE_OLD_RB0 1 +#define QUEUE_OLD_RB1 2 +#define QUEUE_OLD_WB0 3 +#define QUEUE_OLD_WB1 4 + +/* Janz ICAN3 "old-style" host interface control registers */ +#define MSYNC_PEER 0x00 /* ICAN only */ +#define MSYNC_LOCL 0x01 /* host only */ +#define TARGET_RUNNING 0x02 + +#define MSYNC_RB0 0x01 +#define MSYNC_RB1 0x02 +#define MSYNC_RBLW 0x04 +#define MSYNC_RB_MASK (MSYNC_RB0 | MSYNC_RB1) + +#define MSYNC_WB0 0x10 +#define MSYNC_WB1 0x20 +#define MSYNC_WBLW 0x40 +#define MSYNC_WB_MASK (MSYNC_WB0 | MSYNC_WB1) + +/* Janz ICAN3 "new-style" host interface queue page numbers */ +#define QUEUE_TOHOST 5 +#define QUEUE_FROMHOST_MID 6 +#define QUEUE_FROMHOST_HIGH 7 +#define QUEUE_FROMHOST_LOW 8 + +/* The first free page in the DPM is #9 */ +#define DPM_FREE_START 9 + +/* Janz ICAN3 "new-style" and "fast" host interface descriptor flags */ +#define DESC_VALID 0x80 +#define DESC_WRAP 0x40 +#define DESC_INTERRUPT 0x20 +#define DESC_IVALID 0x10 +#define DESC_LEN(len) (len) + +/* Janz ICAN3 Firmware Messages */ +#define MSG_CONNECTI 0x02 +#define MSG_DISCONNECT 0x03 +#define MSG_IDVERS 0x04 +#define MSG_MSGLOST 0x05 +#define MSG_NEWHOSTIF 0x08 +#define MSG_INQUIRY 0x0a +#define MSG_SETAFILMASK 0x10 +#define MSG_INITFDPMQUEUE 0x11 +#define MSG_HWCONF 0x12 +#define MSG_FMSGLOST 0x15 +#define MSG_CEVTIND 0x37 +#define MSG_CBTRREQ 0x41 +#define MSG_COFFREQ 0x42 +#define MSG_CONREQ 0x43 +#define MSG_CCONFREQ 0x47 + +/* + * Janz ICAN3 CAN Inquiry Message Types + * + * NOTE: there appears to be a firmware bug here. You must send + * NOTE: INQUIRY_STATUS and expect to receive an INQUIRY_EXTENDED + * NOTE: response. The controller never responds to a message with + * NOTE: the INQUIRY_EXTENDED subspec :( + */ +#define INQUIRY_STATUS 0x00 +#define INQUIRY_TERMINATION 0x01 +#define INQUIRY_EXTENDED 0x04 + +/* Janz ICAN3 CAN Set Acceptance Filter Mask Message Types */ +#define SETAFILMASK_REJECT 0x00 +#define SETAFILMASK_FASTIF 0x02 + +/* Janz ICAN3 CAN Hardware Configuration Message Types */ +#define HWCONF_TERMINATE_ON 0x01 +#define HWCONF_TERMINATE_OFF 0x00 + +/* Janz ICAN3 CAN Event Indication Message Types */ +#define CEVTIND_EI 0x01 +#define CEVTIND_DOI 0x02 +#define CEVTIND_LOST 0x04 +#define CEVTIND_FULL 0x08 +#define CEVTIND_BEI 0x10 + +#define CEVTIND_CHIP_SJA1000 0x02 + +#define ICAN3_BUSERR_QUOTA_MAX 255 + +/* Janz ICAN3 CAN Frame Conversion */ +#define ICAN3_ECHO 0x10 +#define ICAN3_EFF_RTR 0x40 +#define ICAN3_SFF_RTR 0x10 +#define ICAN3_EFF 0x80 + +#define ICAN3_CAN_TYPE_MASK 0x0f +#define ICAN3_CAN_TYPE_SFF 0x00 +#define ICAN3_CAN_TYPE_EFF 0x01 + +#define ICAN3_CAN_DLC_MASK 0x0f + +/* + * SJA1000 Status and Error Register Definitions + * + * Copied from drivers/net/can/sja1000/sja1000.h + */ + +/* status register content */ +#define SR_BS 0x80 +#define SR_ES 0x40 +#define SR_TS 0x20 +#define SR_RS 0x10 +#define SR_TCS 0x08 +#define SR_TBS 0x04 +#define SR_DOS 0x02 +#define SR_RBS 0x01 + +#define SR_CRIT (SR_BS|SR_ES) + +/* ECC register */ +#define ECC_SEG 0x1F +#define ECC_DIR 0x20 +#define ECC_ERR 6 +#define ECC_BIT 0x00 +#define ECC_FORM 0x40 +#define ECC_STUFF 0x80 +#define ECC_MASK 0xc0 + +/* Number of buffers for use in the "new-style" host interface */ +#define ICAN3_NEW_BUFFERS 16 + +/* Number of buffers for use in the "fast" host interface */ +#define ICAN3_TX_BUFFERS 512 +#define ICAN3_RX_BUFFERS 1024 + +/* SJA1000 Clock Input */ +#define ICAN3_CAN_CLOCK 8000000 + +/* Driver Name */ +#define DRV_NAME "janz-ican3" + +/* DPM Control Registers -- starts at offset 0x100 in the MODULbus registers */ +struct ican3_dpm_control { + /* window address register */ + u8 window_address; + u8 unused1; + + /* + * Read access: clear interrupt from microcontroller + * Write access: send interrupt to microcontroller + */ + u8 interrupt; + u8 unused2; + + /* write-only: reset all hardware on the module */ + u8 hwreset; + u8 unused3; + + /* write-only: generate an interrupt to the TPU */ + u8 tpuinterrupt; +}; + +struct ican3_dev { + + /* must be the first member */ + struct can_priv can; + + /* CAN network device */ + struct net_device *ndev; + struct napi_struct napi; + + /* Device for printing */ + struct device *dev; + + /* module number */ + unsigned int num; + + /* base address of registers and IRQ */ + struct janz_cmodio_onboard_regs __iomem *ctrl; + struct ican3_dpm_control __iomem *dpmctrl; + void __iomem *dpm; + int irq; + + /* CAN bus termination status */ + struct completion termination_comp; + bool termination_enabled; + + /* CAN bus error status registers */ + struct completion buserror_comp; + struct can_berr_counter bec; + + /* old and new style host interface */ + unsigned int iftype; + + /* + * Any function which changes the current DPM page must hold this + * lock while it is performing data accesses. This ensures that the + * function will not be preempted and end up reading data from a + * different DPM page than it expects. + */ + spinlock_t lock; + + /* new host interface */ + unsigned int rx_int; + unsigned int rx_num; + unsigned int tx_num; + + /* fast host interface */ + unsigned int fastrx_start; + unsigned int fastrx_int; + unsigned int fastrx_num; + unsigned int fasttx_start; + unsigned int fasttx_num; + + /* first free DPM page */ + unsigned int free_page; +}; + +struct ican3_msg { + u8 control; + u8 spec; + __le16 len; + u8 data[252]; +}; + +struct ican3_new_desc { + u8 control; + u8 pointer; +}; + +struct ican3_fast_desc { + u8 control; + u8 command; + u8 data[14]; +}; + +/* write to the window basic address register */ +static inline void ican3_set_page(struct ican3_dev *mod, unsigned int page) +{ + BUG_ON(page >= DPM_NUM_PAGES); + iowrite8(page, &mod->dpmctrl->window_address); +} + +/* + * ICAN3 "old-style" host interface + */ + +/* + * Recieve a message from the ICAN3 "old-style" firmware interface + * + * LOCKING: must hold mod->lock + * + * returns 0 on success, -ENOMEM when no message exists + */ +static int ican3_old_recv_msg(struct ican3_dev *mod, struct ican3_msg *msg) +{ + unsigned int mbox, mbox_page; + u8 locl, peer, xord; + + /* get the MSYNC registers */ + ican3_set_page(mod, QUEUE_OLD_CONTROL); + peer = ioread8(mod->dpm + MSYNC_PEER); + locl = ioread8(mod->dpm + MSYNC_LOCL); + xord = locl ^ peer; + + if ((xord & MSYNC_RB_MASK) == 0x00) { + dev_dbg(mod->dev, "no mbox for reading\n"); + return -ENOMEM; + } + + /* find the first free mbox to read */ + if ((xord & MSYNC_RB_MASK) == MSYNC_RB_MASK) + mbox = (xord & MSYNC_RBLW) ? MSYNC_RB0 : MSYNC_RB1; + else + mbox = (xord & MSYNC_RB0) ? MSYNC_RB0 : MSYNC_RB1; + + /* copy the message */ + mbox_page = (mbox == MSYNC_RB0) ? QUEUE_OLD_RB0 : QUEUE_OLD_RB1; + ican3_set_page(mod, mbox_page); + memcpy_fromio(msg, mod->dpm, sizeof(*msg)); + + /* + * notify the firmware that the read buffer is available + * for it to fill again + */ + locl ^= mbox; + + ican3_set_page(mod, QUEUE_OLD_CONTROL); + iowrite8(locl, mod->dpm + MSYNC_LOCL); + return 0; +} + +/* + * Send a message through the "old-style" firmware interface + * + * LOCKING: must hold mod->lock + * + * returns 0 on success, -ENOMEM when no free space exists + */ +static int ican3_old_send_msg(struct ican3_dev *mod, struct ican3_msg *msg) +{ + unsigned int mbox, mbox_page; + u8 locl, peer, xord; + + /* get the MSYNC registers */ + ican3_set_page(mod, QUEUE_OLD_CONTROL); + peer = ioread8(mod->dpm + MSYNC_PEER); + locl = ioread8(mod->dpm + MSYNC_LOCL); + xord = locl ^ peer; + + if ((xord & MSYNC_WB_MASK) == MSYNC_WB_MASK) { + dev_err(mod->dev, "no mbox for writing\n"); + return -ENOMEM; + } + + /* calculate a free mbox to use */ + mbox = (xord & MSYNC_WB0) ? MSYNC_WB1 : MSYNC_WB0; + + /* copy the message to the DPM */ + mbox_page = (mbox == MSYNC_WB0) ? QUEUE_OLD_WB0 : QUEUE_OLD_WB1; + ican3_set_page(mod, mbox_page); + memcpy_toio(mod->dpm, msg, sizeof(*msg)); + + locl ^= mbox; + if (mbox == MSYNC_WB1) + locl |= MSYNC_WBLW; + + ican3_set_page(mod, QUEUE_OLD_CONTROL); + iowrite8(locl, mod->dpm + MSYNC_LOCL); + return 0; +} + +/* + * ICAN3 "new-style" Host Interface Setup + */ + +static void __devinit ican3_init_new_host_interface(struct ican3_dev *mod) +{ + struct ican3_new_desc desc; + unsigned long flags; + void __iomem *dst; + int i; + + spin_lock_irqsave(&mod->lock, flags); + + /* setup the internal datastructures for RX */ + mod->rx_num = 0; + mod->rx_int = 0; + + /* tohost queue descriptors are in page 5 */ + ican3_set_page(mod, QUEUE_TOHOST); + dst = mod->dpm; + + /* initialize the tohost (rx) queue descriptors: pages 9-24 */ + for (i = 0; i < ICAN3_NEW_BUFFERS; i++) { + desc.control = DESC_INTERRUPT | DESC_LEN(1); /* I L=1 */ + desc.pointer = mod->free_page; + + /* set wrap flag on last buffer */ + if (i == ICAN3_NEW_BUFFERS - 1) + desc.control |= DESC_WRAP; + + memcpy_toio(dst, &desc, sizeof(desc)); + dst += sizeof(desc); + mod->free_page++; + } + + /* fromhost (tx) mid queue descriptors are in page 6 */ + ican3_set_page(mod, QUEUE_FROMHOST_MID); + dst = mod->dpm; + + /* setup the internal datastructures for TX */ + mod->tx_num = 0; + + /* initialize the fromhost mid queue descriptors: pages 25-40 */ + for (i = 0; i < ICAN3_NEW_BUFFERS; i++) { + desc.control = DESC_VALID | DESC_LEN(1); /* V L=1 */ + desc.pointer = mod->free_page; + + /* set wrap flag on last buffer */ + if (i == ICAN3_NEW_BUFFERS - 1) + desc.control |= DESC_WRAP; + + memcpy_toio(dst, &desc, sizeof(desc)); + dst += sizeof(desc); + mod->free_page++; + } + + /* fromhost hi queue descriptors are in page 7 */ + ican3_set_page(mod, QUEUE_FROMHOST_HIGH); + dst = mod->dpm; + + /* initialize only a single buffer in the fromhost hi queue (unused) */ + desc.control = DESC_VALID | DESC_WRAP | DESC_LEN(1); /* VW L=1 */ + desc.pointer = mod->free_page; + memcpy_toio(dst, &desc, sizeof(desc)); + mod->free_page++; + + /* fromhost low queue descriptors are in page 8 */ + ican3_set_page(mod, QUEUE_FROMHOST_LOW); + dst = mod->dpm; + + /* initialize only a single buffer in the fromhost low queue (unused) */ + desc.control = DESC_VALID | DESC_WRAP | DESC_LEN(1); /* VW L=1 */ + desc.pointer = mod->free_page; + memcpy_toio(dst, &desc, sizeof(desc)); + mod->free_page++; + + spin_unlock_irqrestore(&mod->lock, flags); +} + +/* + * ICAN3 Fast Host Interface Setup + */ + +static void __devinit ican3_init_fast_host_interface(struct ican3_dev *mod) +{ + struct ican3_fast_desc desc; + unsigned long flags; + unsigned int addr; + void __iomem *dst; + int i; + + spin_lock_irqsave(&mod->lock, flags); + + /* save the start recv page */ + mod->fastrx_start = mod->free_page; + mod->fastrx_num = 0; + mod->fastrx_int = 0; + + /* build a single fast tohost queue descriptor */ + memset(&desc, 0, sizeof(desc)); + desc.control = 0x00; + desc.command = 1; + + /* build the tohost queue descriptor ring in memory */ + addr = 0; + for (i = 0; i < ICAN3_RX_BUFFERS; i++) { + + /* set the wrap bit on the last buffer */ + if (i == ICAN3_RX_BUFFERS - 1) + desc.control |= DESC_WRAP; + + /* switch to the correct page */ + ican3_set_page(mod, mod->free_page); + + /* copy the descriptor to the DPM */ + dst = mod->dpm + addr; + memcpy_toio(dst, &desc, sizeof(desc)); + addr += sizeof(desc); + + /* move to the next page if necessary */ + if (addr >= DPM_PAGE_SIZE) { + addr = 0; + mod->free_page++; + } + } + + /* make sure we page-align the next queue */ + if (addr != 0) + mod->free_page++; + + /* save the start xmit page */ + mod->fasttx_start = mod->free_page; + mod->fasttx_num = 0; + + /* build a single fast fromhost queue descriptor */ + memset(&desc, 0, sizeof(desc)); + desc.control = DESC_VALID; + desc.command = 1; + + /* build the fromhost queue descriptor ring in memory */ + addr = 0; + for (i = 0; i < ICAN3_TX_BUFFERS; i++) { + + /* set the wrap bit on the last buffer */ + if (i == ICAN3_TX_BUFFERS - 1) + desc.control |= DESC_WRAP; + + /* switch to the correct page */ + ican3_set_page(mod, mod->free_page); + + /* copy the descriptor to the DPM */ + dst = mod->dpm + addr; + memcpy_toio(dst, &desc, sizeof(desc)); + addr += sizeof(desc); + + /* move to the next page if necessary */ + if (addr >= DPM_PAGE_SIZE) { + addr = 0; + mod->free_page++; + } + } + + spin_unlock_irqrestore(&mod->lock, flags); +} + +/* + * ICAN3 "new-style" Host Interface Message Helpers + */ + +/* + * LOCKING: must hold mod->lock + */ +static int ican3_new_send_msg(struct ican3_dev *mod, struct ican3_msg *msg) +{ + struct ican3_new_desc desc; + void __iomem *desc_addr = mod->dpm + (mod->tx_num * sizeof(desc)); + + /* switch to the fromhost mid queue, and read the buffer descriptor */ + ican3_set_page(mod, QUEUE_FROMHOST_MID); + memcpy_fromio(&desc, desc_addr, sizeof(desc)); + + if (!(desc.control & DESC_VALID)) { + dev_dbg(mod->dev, "%s: no free buffers\n", __func__); + return -ENOMEM; + } + + /* switch to the data page, copy the data */ + ican3_set_page(mod, desc.pointer); + memcpy_toio(mod->dpm, msg, sizeof(*msg)); + + /* switch back to the descriptor, set the valid bit, write it back */ + ican3_set_page(mod, QUEUE_FROMHOST_MID); + desc.control ^= DESC_VALID; + memcpy_toio(desc_addr, &desc, sizeof(desc)); + + /* update the tx number */ + mod->tx_num = (desc.control & DESC_WRAP) ? 0 : (mod->tx_num + 1); + return 0; +} + +/* + * LOCKING: must hold mod->lock + */ +static int ican3_new_recv_msg(struct ican3_dev *mod, struct ican3_msg *msg) +{ + struct ican3_new_desc desc; + void __iomem *desc_addr = mod->dpm + (mod->rx_num * sizeof(desc)); + + /* switch to the tohost queue, and read the buffer descriptor */ + ican3_set_page(mod, QUEUE_TOHOST); + memcpy_fromio(&desc, desc_addr, sizeof(desc)); + + if (!(desc.control & DESC_VALID)) { + dev_dbg(mod->dev, "%s: no buffers to recv\n", __func__); + return -ENOMEM; + } + + /* switch to the data page, copy the data */ + ican3_set_page(mod, desc.pointer); + memcpy_fromio(msg, mod->dpm, sizeof(*msg)); + + /* switch back to the descriptor, toggle the valid bit, write it back */ + ican3_set_page(mod, QUEUE_TOHOST); + desc.control ^= DESC_VALID; + memcpy_toio(desc_addr, &desc, sizeof(desc)); + + /* update the rx number */ + mod->rx_num = (desc.control & DESC_WRAP) ? 0 : (mod->rx_num + 1); + return 0; +} + +/* + * Message Send / Recv Helpers + */ + +static int ican3_send_msg(struct ican3_dev *mod, struct ican3_msg *msg) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&mod->lock, flags); + + if (mod->iftype == 0) + ret = ican3_old_send_msg(mod, msg); + else + ret = ican3_new_send_msg(mod, msg); + + spin_unlock_irqrestore(&mod->lock, flags); + return ret; +} + +static int ican3_recv_msg(struct ican3_dev *mod, struct ican3_msg *msg) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&mod->lock, flags); + + if (mod->iftype == 0) + ret = ican3_old_recv_msg(mod, msg); + else + ret = ican3_new_recv_msg(mod, msg); + + spin_unlock_irqrestore(&mod->lock, flags); + return ret; +} + +/* + * Quick Pre-constructed Messages + */ + +static int __devinit ican3_msg_connect(struct ican3_dev *mod) +{ + struct ican3_msg msg; + + memset(&msg, 0, sizeof(msg)); + msg.spec = MSG_CONNECTI; + msg.len = cpu_to_le16(0); + + return ican3_send_msg(mod, &msg); +} + +static int __devexit ican3_msg_disconnect(struct ican3_dev *mod) +{ + struct ican3_msg msg; + + memset(&msg, 0, sizeof(msg)); + msg.spec = MSG_DISCONNECT; + msg.len = cpu_to_le16(0); + + return ican3_send_msg(mod, &msg); +} + +static int __devinit ican3_msg_newhostif(struct ican3_dev *mod) +{ + struct ican3_msg msg; + int ret; + + memset(&msg, 0, sizeof(msg)); + msg.spec = MSG_NEWHOSTIF; + msg.len = cpu_to_le16(0); + + /* If we're not using the old interface, switching seems bogus */ + WARN_ON(mod->iftype != 0); + + ret = ican3_send_msg(mod, &msg); + if (ret) + return ret; + + /* mark the module as using the new host interface */ + mod->iftype = 1; + return 0; +} + +static int __devinit ican3_msg_fasthostif(struct ican3_dev *mod) +{ + struct ican3_msg msg; + unsigned int addr; + + memset(&msg, 0, sizeof(msg)); + msg.spec = MSG_INITFDPMQUEUE; + msg.len = cpu_to_le16(8); + + /* write the tohost queue start address */ + addr = DPM_PAGE_ADDR(mod->fastrx_start); + msg.data[0] = addr & 0xff; + msg.data[1] = (addr >> 8) & 0xff; + msg.data[2] = (addr >> 16) & 0xff; + msg.data[3] = (addr >> 24) & 0xff; + + /* write the fromhost queue start address */ + addr = DPM_PAGE_ADDR(mod->fasttx_start); + msg.data[4] = addr & 0xff; + msg.data[5] = (addr >> 8) & 0xff; + msg.data[6] = (addr >> 16) & 0xff; + msg.data[7] = (addr >> 24) & 0xff; + + /* If we're not using the new interface yet, we cannot do this */ + WARN_ON(mod->iftype != 1); + + return ican3_send_msg(mod, &msg); +} + +/* + * Setup the CAN filter to either accept or reject all + * messages from the CAN bus. + */ +static int __devinit ican3_set_id_filter(struct ican3_dev *mod, bool accept) +{ + struct ican3_msg msg; + int ret; + + /* Standard Frame Format */ + memset(&msg, 0, sizeof(msg)); + msg.spec = MSG_SETAFILMASK; + msg.len = cpu_to_le16(5); + msg.data[0] = 0x00; /* IDLo LSB */ + msg.data[1] = 0x00; /* IDLo MSB */ + msg.data[2] = 0xff; /* IDHi LSB */ + msg.data[3] = 0x07; /* IDHi MSB */ + + /* accept all frames for fast host if, or reject all frames */ + msg.data[4] = accept ? SETAFILMASK_FASTIF : SETAFILMASK_REJECT; + + ret = ican3_send_msg(mod, &msg); + if (ret) + return ret; + + /* Extended Frame Format */ + memset(&msg, 0, sizeof(msg)); + msg.spec = MSG_SETAFILMASK; + msg.len = cpu_to_le16(13); + msg.data[0] = 0; /* MUX = 0 */ + msg.data[1] = 0x00; /* IDLo LSB */ + msg.data[2] = 0x00; + msg.data[3] = 0x00; + msg.data[4] = 0x20; /* IDLo MSB */ + msg.data[5] = 0xff; /* IDHi LSB */ + msg.data[6] = 0xff; + msg.data[7] = 0xff; + msg.data[8] = 0x3f; /* IDHi MSB */ + + /* accept all frames for fast host if, or reject all frames */ + msg.data[9] = accept ? SETAFILMASK_FASTIF : SETAFILMASK_REJECT; + + return ican3_send_msg(mod, &msg); +} + +/* + * Bring the CAN bus online or offline + */ +static int ican3_set_bus_state(struct ican3_dev *mod, bool on) +{ + struct ican3_msg msg; + + memset(&msg, 0, sizeof(msg)); + msg.spec = on ? MSG_CONREQ : MSG_COFFREQ; + msg.len = cpu_to_le16(0); + + return ican3_send_msg(mod, &msg); +} + +static int ican3_set_termination(struct ican3_dev *mod, bool on) +{ + struct ican3_msg msg; + + memset(&msg, 0, sizeof(msg)); + msg.spec = MSG_HWCONF; + msg.len = cpu_to_le16(2); + msg.data[0] = 0x00; + msg.data[1] = on ? HWCONF_TERMINATE_ON : HWCONF_TERMINATE_OFF; + + return ican3_send_msg(mod, &msg); +} + +static int ican3_send_inquiry(struct ican3_dev *mod, u8 subspec) +{ + struct ican3_msg msg; + + memset(&msg, 0, sizeof(msg)); + msg.spec = MSG_INQUIRY; + msg.len = cpu_to_le16(2); + msg.data[0] = subspec; + msg.data[1] = 0x00; + + return ican3_send_msg(mod, &msg); +} + +static int ican3_set_buserror(struct ican3_dev *mod, u8 quota) +{ + struct ican3_msg msg; + + memset(&msg, 0, sizeof(msg)); + msg.spec = MSG_CCONFREQ; + msg.len = cpu_to_le16(2); + msg.data[0] = 0x00; + msg.data[1] = quota; + + return ican3_send_msg(mod, &msg); +} + +/* + * ICAN3 to Linux CAN Frame Conversion + */ + +static void ican3_to_can_frame(struct ican3_dev *mod, + struct ican3_fast_desc *desc, + struct can_frame *cf) +{ + if ((desc->command & ICAN3_CAN_TYPE_MASK) == ICAN3_CAN_TYPE_SFF) { + if (desc->data[1] & ICAN3_SFF_RTR) + cf->can_id |= CAN_RTR_FLAG; + + cf->can_id |= desc->data[0] << 3; + cf->can_id |= (desc->data[1] & 0xe0) >> 5; + cf->can_dlc = desc->data[1] & ICAN3_CAN_DLC_MASK; + memcpy(cf->data, &desc->data[2], sizeof(cf->data)); + } else { + cf->can_dlc = desc->data[0] & ICAN3_CAN_DLC_MASK; + if (desc->data[0] & ICAN3_EFF_RTR) + cf->can_id |= CAN_RTR_FLAG; + + if (desc->data[0] & ICAN3_EFF) { + cf->can_id |= CAN_EFF_FLAG; + cf->can_id |= desc->data[2] << 21; /* 28-21 */ + cf->can_id |= desc->data[3] << 13; /* 20-13 */ + cf->can_id |= desc->data[4] << 5; /* 12-5 */ + cf->can_id |= (desc->data[5] & 0xf8) >> 3; + } else { + cf->can_id |= desc->data[2] << 3; /* 10-3 */ + cf->can_id |= desc->data[3] >> 5; /* 2-0 */ + } + + memcpy(cf->data, &desc->data[6], sizeof(cf->data)); + } +} + +static void can_frame_to_ican3(struct ican3_dev *mod, + struct can_frame *cf, + struct ican3_fast_desc *desc) +{ + /* clear out any stale data in the descriptor */ + memset(desc->data, 0, sizeof(desc->data)); + + /* we always use the extended format, with the ECHO flag set */ + desc->command = ICAN3_CAN_TYPE_EFF; + desc->data[0] |= cf->can_dlc; + desc->data[1] |= ICAN3_ECHO; + + if (cf->can_id & CAN_RTR_FLAG) + desc->data[0] |= ICAN3_EFF_RTR; + + /* pack the id into the correct places */ + if (cf->can_id & CAN_EFF_FLAG) { + desc->data[0] |= ICAN3_EFF; + desc->data[2] = (cf->can_id & 0x1fe00000) >> 21; /* 28-21 */ + desc->data[3] = (cf->can_id & 0x001fe000) >> 13; /* 20-13 */ + desc->data[4] = (cf->can_id & 0x00001fe0) >> 5; /* 12-5 */ + desc->data[5] = (cf->can_id & 0x0000001f) << 3; /* 4-0 */ + } else { + desc->data[2] = (cf->can_id & 0x7F8) >> 3; /* bits 10-3 */ + desc->data[3] = (cf->can_id & 0x007) << 5; /* bits 2-0 */ + } + + /* copy the data bits into the descriptor */ + memcpy(&desc->data[6], cf->data, sizeof(cf->data)); +} + +/* + * Interrupt Handling + */ + +/* + * Handle an ID + Version message response from the firmware. We never generate + * this message in production code, but it is very useful when debugging to be + * able to display this message. + */ +static void ican3_handle_idvers(struct ican3_dev *mod, struct ican3_msg *msg) +{ + dev_dbg(mod->dev, "IDVERS response: %s\n", msg->data); +} + +static void ican3_handle_msglost(struct ican3_dev *mod, struct ican3_msg *msg) +{ + struct net_device *dev = mod->ndev; + struct net_device_stats *stats = &dev->stats; + struct can_frame *cf; + struct sk_buff *skb; + + /* + * Report that communication messages with the microcontroller firmware + * are being lost. These are never CAN frames, so we do not generate an + * error frame for userspace + */ + if (msg->spec == MSG_MSGLOST) { + dev_err(mod->dev, "lost %d control messages\n", msg->data[0]); + return; + } + + /* + * Oops, this indicates that we have lost messages in the fast queue, + * which are exclusively CAN messages. Our driver isn't reading CAN + * frames fast enough. + * + * We'll pretend that the SJA1000 told us that it ran out of buffer + * space, because there is not a better message for this. + */ + skb = alloc_can_err_skb(dev, &cf); + if (skb) { + cf->can_id |= CAN_ERR_CRTL; + cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; + stats->rx_errors++; + stats->rx_bytes += cf->can_dlc; + netif_rx(skb); + } +} + +/* + * Handle CAN Event Indication Messages from the firmware + * + * The ICAN3 firmware provides the values of some SJA1000 registers when it + * generates this message. The code below is largely copied from the + * drivers/net/can/sja1000/sja1000.c file, and adapted as necessary + */ +static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg) +{ + struct net_device *dev = mod->ndev; + struct net_device_stats *stats = &dev->stats; + enum can_state state = mod->can.state; + u8 status, isrc, rxerr, txerr; + struct can_frame *cf; + struct sk_buff *skb; + + /* we can only handle the SJA1000 part */ + if (msg->data[1] != CEVTIND_CHIP_SJA1000) { + dev_err(mod->dev, "unable to handle errors on non-SJA1000\n"); + return -ENODEV; + } + + /* check the message length for sanity */ + if (le16_to_cpu(msg->len) < 6) { + dev_err(mod->dev, "error message too short\n"); + return -EINVAL; + } + + skb = alloc_can_err_skb(dev, &cf); + if (skb == NULL) + return -ENOMEM; + + isrc = msg->data[0]; + status = msg->data[3]; + rxerr = msg->data[4]; + txerr = msg->data[5]; + + /* data overrun interrupt */ + if (isrc == CEVTIND_DOI || isrc == CEVTIND_LOST) { + dev_dbg(mod->dev, "data overrun interrupt\n"); + cf->can_id |= CAN_ERR_CRTL; + cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; + stats->rx_over_errors++; + stats->rx_errors++; + } + + /* error warning + passive interrupt */ + if (isrc == CEVTIND_EI) { + dev_dbg(mod->dev, "error warning + passive interrupt\n"); + if (status & SR_BS) { + state = CAN_STATE_BUS_OFF; + cf->can_id |= CAN_ERR_BUSOFF; + can_bus_off(dev); + } else if (status & SR_ES) { + if (rxerr >= 128 || txerr >= 128) + state = CAN_STATE_ERROR_PASSIVE; + else + state = CAN_STATE_ERROR_WARNING; + } else { + state = CAN_STATE_ERROR_ACTIVE; + } + } + + /* bus error interrupt */ + if (isrc == CEVTIND_BEI) { + u8 ecc = msg->data[2]; + + dev_dbg(mod->dev, "bus error interrupt\n"); + mod->can.can_stats.bus_error++; + stats->rx_errors++; + cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; + + switch (ecc & ECC_MASK) { + case ECC_BIT: + cf->data[2] |= CAN_ERR_PROT_BIT; + break; + case ECC_FORM: + cf->data[2] |= CAN_ERR_PROT_FORM; + break; + case ECC_STUFF: + cf->data[2] |= CAN_ERR_PROT_STUFF; + break; + default: + cf->data[2] |= CAN_ERR_PROT_UNSPEC; + cf->data[3] = ecc & ECC_SEG; + break; + } + + if ((ecc & ECC_DIR) == 0) + cf->data[2] |= CAN_ERR_PROT_TX; + + cf->data[6] = txerr; + cf->data[7] = rxerr; + } + + if (state != mod->can.state && (state == CAN_STATE_ERROR_WARNING || + state == CAN_STATE_ERROR_PASSIVE)) { + cf->can_id |= CAN_ERR_CRTL; + if (state == CAN_STATE_ERROR_WARNING) { + mod->can.can_stats.error_warning++; + cf->data[1] = (txerr > rxerr) ? + CAN_ERR_CRTL_TX_WARNING : + CAN_ERR_CRTL_RX_WARNING; + } else { + mod->can.can_stats.error_passive++; + cf->data[1] = (txerr > rxerr) ? + CAN_ERR_CRTL_TX_PASSIVE : + CAN_ERR_CRTL_RX_PASSIVE; + } + + cf->data[6] = txerr; + cf->data[7] = rxerr; + } + + mod->can.state = state; + stats->rx_errors++; + stats->rx_bytes += cf->can_dlc; + netif_rx(skb); + return 0; +} + +static void ican3_handle_inquiry(struct ican3_dev *mod, struct ican3_msg *msg) +{ + switch (msg->data[0]) { + case INQUIRY_STATUS: + case INQUIRY_EXTENDED: + mod->bec.rxerr = msg->data[5]; + mod->bec.txerr = msg->data[6]; + complete(&mod->buserror_comp); + break; + case INQUIRY_TERMINATION: + mod->termination_enabled = msg->data[6] & HWCONF_TERMINATE_ON; + complete(&mod->termination_comp); + break; + default: + dev_err(mod->dev, "recieved an unknown inquiry response\n"); + break; + } +} + +static void ican3_handle_unknown_message(struct ican3_dev *mod, + struct ican3_msg *msg) +{ + dev_warn(mod->dev, "recieved unknown message: spec 0x%.2x length %d\n", + msg->spec, le16_to_cpu(msg->len)); +} + +/* + * Handle a control message from the firmware + */ +static void ican3_handle_message(struct ican3_dev *mod, struct ican3_msg *msg) +{ + dev_dbg(mod->dev, "%s: modno %d spec 0x%.2x len %d bytes\n", __func__, + mod->num, msg->spec, le16_to_cpu(msg->len)); + + switch (msg->spec) { + case MSG_IDVERS: + ican3_handle_idvers(mod, msg); + break; + case MSG_MSGLOST: + case MSG_FMSGLOST: + ican3_handle_msglost(mod, msg); + break; + case MSG_CEVTIND: + ican3_handle_cevtind(mod, msg); + break; + case MSG_INQUIRY: + ican3_handle_inquiry(mod, msg); + break; + default: + ican3_handle_unknown_message(mod, msg); + break; + } +} + +/* + * Check that there is room in the TX ring to transmit another skb + * + * LOCKING: must hold mod->lock + */ +static bool ican3_txok(struct ican3_dev *mod) +{ + struct ican3_fast_desc __iomem *desc; + u8 control; + + /* copy the control bits of the descriptor */ + ican3_set_page(mod, mod->fasttx_start + (mod->fasttx_num / 16)); + desc = mod->dpm + ((mod->fasttx_num % 16) * sizeof(*desc)); + control = ioread8(&desc->control); + + /* if the control bits are not valid, then we have no more space */ + if (!(control & DESC_VALID)) + return false; + + return true; +} + +/* + * Recieve one CAN frame from the hardware + * + * This works like the core of a NAPI function, but is intended to be called + * from workqueue context instead. This driver already needs a workqueue to + * process control messages, so we use the workqueue instead of using NAPI. + * This was done to simplify locking. + * + * CONTEXT: must be called from user context + */ +static int ican3_recv_skb(struct ican3_dev *mod) +{ + struct net_device *ndev = mod->ndev; + struct net_device_stats *stats = &ndev->stats; + struct ican3_fast_desc desc; + void __iomem *desc_addr; + struct can_frame *cf; + struct sk_buff *skb; + unsigned long flags; + + spin_lock_irqsave(&mod->lock, flags); + + /* copy the whole descriptor */ + ican3_set_page(mod, mod->fastrx_start + (mod->fastrx_num / 16)); + desc_addr = mod->dpm + ((mod->fastrx_num % 16) * sizeof(desc)); + memcpy_fromio(&desc, desc_addr, sizeof(desc)); + + spin_unlock_irqrestore(&mod->lock, flags); + + /* check that we actually have a CAN frame */ + if (!(desc.control & DESC_VALID)) + return -ENOBUFS; + + /* allocate an skb */ + skb = alloc_can_skb(ndev, &cf); + if (unlikely(skb == NULL)) { + stats->rx_dropped++; + goto err_noalloc; + } + + /* convert the ICAN3 frame into Linux CAN format */ + ican3_to_can_frame(mod, &desc, cf); + + /* receive the skb, update statistics */ + netif_receive_skb(skb); + stats->rx_packets++; + stats->rx_bytes += cf->can_dlc; + +err_noalloc: + /* toggle the valid bit and return the descriptor to the ring */ + desc.control ^= DESC_VALID; + + spin_lock_irqsave(&mod->lock, flags); + + ican3_set_page(mod, mod->fastrx_start + (mod->fastrx_num / 16)); + memcpy_toio(desc_addr, &desc, 1); + + /* update the next buffer pointer */ + mod->fastrx_num = (desc.control & DESC_WRAP) ? 0 + : (mod->fastrx_num + 1); + + /* there are still more buffers to process */ + spin_unlock_irqrestore(&mod->lock, flags); + return 0; +} + +static int ican3_napi(struct napi_struct *napi, int budget) +{ + struct ican3_dev *mod = container_of(napi, struct ican3_dev, napi); + struct ican3_msg msg; + unsigned long flags; + int received = 0; + int ret; + + /* process all communication messages */ + while (true) { + ret = ican3_recv_msg(mod, &msg); + if (ret) + break; + + ican3_handle_message(mod, &msg); + } + + /* process all CAN frames from the fast interface */ + while (received < budget) { + ret = ican3_recv_skb(mod); + if (ret) + break; + + received++; + } + + /* We have processed all packets that the adapter had, but it + * was less than our budget, stop polling */ + if (received < budget) + napi_complete(napi); + + spin_lock_irqsave(&mod->lock, flags); + + /* Wake up the transmit queue if necessary */ + if (netif_queue_stopped(mod->ndev) && ican3_txok(mod)) + netif_wake_queue(mod->ndev); + + spin_unlock_irqrestore(&mod->lock, flags); + + /* re-enable interrupt generation */ + iowrite8(1 << mod->num, &mod->ctrl->int_enable); + return received; +} + +static irqreturn_t ican3_irq(int irq, void *dev_id) +{ + struct ican3_dev *mod = dev_id; + u8 stat; + + /* + * The interrupt status register on this device reports interrupts + * as zeroes instead of using ones like most other devices + */ + stat = ioread8(&mod->ctrl->int_disable) & (1 << mod->num); + if (stat == (1 << mod->num)) + return IRQ_NONE; + + /* clear the MODULbus interrupt from the microcontroller */ + ioread8(&mod->dpmctrl->interrupt); + + /* disable interrupt generation, schedule the NAPI poller */ + iowrite8(1 << mod->num, &mod->ctrl->int_disable); + napi_schedule(&mod->napi); + return IRQ_HANDLED; +} + +/* + * Firmware reset, startup, and shutdown + */ + +/* + * Reset an ICAN module to its power-on state + * + * CONTEXT: no network device registered + * LOCKING: work function disabled + */ +static int ican3_reset_module(struct ican3_dev *mod) +{ + u8 val = 1 << mod->num; + unsigned long start; + u8 runold, runnew; + + /* disable interrupts so no more work is scheduled */ + iowrite8(1 << mod->num, &mod->ctrl->int_disable); + + /* flush any pending work */ + flush_scheduled_work(); + + /* the first unallocated page in the DPM is #9 */ + mod->free_page = DPM_FREE_START; + + ican3_set_page(mod, QUEUE_OLD_CONTROL); + runold = ioread8(mod->dpm + TARGET_RUNNING); + + /* reset the module */ + iowrite8(val, &mod->ctrl->reset_assert); + iowrite8(val, &mod->ctrl->reset_deassert); + + /* wait until the module has finished resetting and is running */ + start = jiffies; + do { + ican3_set_page(mod, QUEUE_OLD_CONTROL); + runnew = ioread8(mod->dpm + TARGET_RUNNING); + if (runnew == (runold ^ 0xff)) + return 0; + + msleep(10); + } while (time_before(jiffies, start + HZ / 4)); + + dev_err(mod->dev, "failed to reset CAN module\n"); + return -ETIMEDOUT; +} + +static void __devexit ican3_shutdown_module(struct ican3_dev *mod) +{ + ican3_msg_disconnect(mod); + ican3_reset_module(mod); +} + +/* + * Startup an ICAN module, bringing it into fast mode + */ +static int __devinit ican3_startup_module(struct ican3_dev *mod) +{ + int ret; + + ret = ican3_reset_module(mod); + if (ret) { + dev_err(mod->dev, "unable to reset module\n"); + return ret; + } + + /* re-enable interrupts so we can send messages */ + iowrite8(1 << mod->num, &mod->ctrl->int_enable); + + ret = ican3_msg_connect(mod); + if (ret) { + dev_err(mod->dev, "unable to connect to module\n"); + return ret; + } + + ican3_init_new_host_interface(mod); + ret = ican3_msg_newhostif(mod); + if (ret) { + dev_err(mod->dev, "unable to switch to new-style interface\n"); + return ret; + } + + /* default to "termination on" */ + ret = ican3_set_termination(mod, true); + if (ret) { + dev_err(mod->dev, "unable to enable termination\n"); + return ret; + } + + /* default to "bus errors enabled" */ + ret = ican3_set_buserror(mod, ICAN3_BUSERR_QUOTA_MAX); + if (ret) { + dev_err(mod->dev, "unable to set bus-error\n"); + return ret; + } + + ican3_init_fast_host_interface(mod); + ret = ican3_msg_fasthostif(mod); + if (ret) { + dev_err(mod->dev, "unable to switch to fast host interface\n"); + return ret; + } + + ret = ican3_set_id_filter(mod, true); + if (ret) { + dev_err(mod->dev, "unable to set acceptance filter\n"); + return ret; + } + + return 0; +} + +/* + * CAN Network Device + */ + +static int ican3_open(struct net_device *ndev) +{ + struct ican3_dev *mod = netdev_priv(ndev); + u8 quota; + int ret; + + /* open the CAN layer */ + ret = open_candev(ndev); + if (ret) { + dev_err(mod->dev, "unable to start CAN layer\n"); + return ret; + } + + /* set the bus error generation state appropriately */ + if (mod->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) + quota = ICAN3_BUSERR_QUOTA_MAX; + else + quota = 0; + + ret = ican3_set_buserror(mod, quota); + if (ret) { + dev_err(mod->dev, "unable to set bus-error\n"); + close_candev(ndev); + return ret; + } + + /* bring the bus online */ + ret = ican3_set_bus_state(mod, true); + if (ret) { + dev_err(mod->dev, "unable to set bus-on\n"); + close_candev(ndev); + return ret; + } + + /* start up the network device */ + mod->can.state = CAN_STATE_ERROR_ACTIVE; + netif_start_queue(ndev); + + return 0; +} + +static int ican3_stop(struct net_device *ndev) +{ + struct ican3_dev *mod = netdev_priv(ndev); + int ret; + + /* stop the network device xmit routine */ + netif_stop_queue(ndev); + mod->can.state = CAN_STATE_STOPPED; + + /* bring the bus offline, stop receiving packets */ + ret = ican3_set_bus_state(mod, false); + if (ret) { + dev_err(mod->dev, "unable to set bus-off\n"); + return ret; + } + + /* close the CAN layer */ + close_candev(ndev); + return 0; +} + +static int ican3_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + struct ican3_dev *mod = netdev_priv(ndev); + struct net_device_stats *stats = &ndev->stats; + struct can_frame *cf = (struct can_frame *)skb->data; + struct ican3_fast_desc desc; + void __iomem *desc_addr; + unsigned long flags; + + spin_lock_irqsave(&mod->lock, flags); + + /* check that we can actually transmit */ + if (!ican3_txok(mod)) { + dev_err(mod->dev, "no free descriptors, stopping queue\n"); + netif_stop_queue(ndev); + spin_unlock_irqrestore(&mod->lock, flags); + return NETDEV_TX_BUSY; + } + + /* copy the control bits of the descriptor */ + ican3_set_page(mod, mod->fasttx_start + (mod->fasttx_num / 16)); + desc_addr = mod->dpm + ((mod->fasttx_num % 16) * sizeof(desc)); + memset(&desc, 0, sizeof(desc)); + memcpy_fromio(&desc, desc_addr, 1); + + /* convert the Linux CAN frame into ICAN3 format */ + can_frame_to_ican3(mod, cf, &desc); + + /* + * the programming manual says that you must set the IVALID bit, then + * interrupt, then set the valid bit. Quite weird, but it seems to be + * required for this to work + */ + desc.control |= DESC_IVALID; + memcpy_toio(desc_addr, &desc, sizeof(desc)); + + /* generate a MODULbus interrupt to the microcontroller */ + iowrite8(0x01, &mod->dpmctrl->interrupt); + + desc.control ^= DESC_VALID; + memcpy_toio(desc_addr, &desc, sizeof(desc)); + + /* update the next buffer pointer */ + mod->fasttx_num = (desc.control & DESC_WRAP) ? 0 + : (mod->fasttx_num + 1); + + /* update statistics */ + stats->tx_packets++; + stats->tx_bytes += cf->can_dlc; + kfree_skb(skb); + + /* + * This hardware doesn't have TX-done notifications, so we'll try and + * emulate it the best we can using ECHO skbs. Get the next TX + * descriptor, and see if we have room to send. If not, stop the queue. + * It will be woken when the ECHO skb for the current packet is recv'd. + */ + + /* copy the control bits of the descriptor */ + if (!ican3_txok(mod)) + netif_stop_queue(ndev); + + spin_unlock_irqrestore(&mod->lock, flags); + return NETDEV_TX_OK; +} + +static const struct net_device_ops ican3_netdev_ops = { + .ndo_open = ican3_open, + .ndo_stop = ican3_stop, + .ndo_start_xmit = ican3_xmit, +}; + +/* + * Low-level CAN Device + */ + +/* This structure was stolen from drivers/net/can/sja1000/sja1000.c */ +static struct can_bittiming_const ican3_bittiming_const = { + .name = DRV_NAME, + .tseg1_min = 1, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 64, + .brp_inc = 1, +}; + +/* + * This routine was stolen from drivers/net/can/sja1000/sja1000.c + * + * The bittiming register command for the ICAN3 just sets the bit timing + * registers on the SJA1000 chip directly + */ +static int ican3_set_bittiming(struct net_device *ndev) +{ + struct ican3_dev *mod = netdev_priv(ndev); + struct can_bittiming *bt = &mod->can.bittiming; + struct ican3_msg msg; + u8 btr0, btr1; + + btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6); + btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) | + (((bt->phase_seg2 - 1) & 0x7) << 4); + if (mod->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) + btr1 |= 0x80; + + memset(&msg, 0, sizeof(msg)); + msg.spec = MSG_CBTRREQ; + msg.len = cpu_to_le16(4); + msg.data[0] = 0x00; + msg.data[1] = 0x00; + msg.data[2] = btr0; + msg.data[3] = btr1; + + return ican3_send_msg(mod, &msg); +} + +static int ican3_set_mode(struct net_device *ndev, enum can_mode mode) +{ + struct ican3_dev *mod = netdev_priv(ndev); + int ret; + + if (mode != CAN_MODE_START) + return -ENOTSUPP; + + /* bring the bus online */ + ret = ican3_set_bus_state(mod, true); + if (ret) { + dev_err(mod->dev, "unable to set bus-on\n"); + return ret; + } + + /* start up the network device */ + mod->can.state = CAN_STATE_ERROR_ACTIVE; + + if (netif_queue_stopped(ndev)) + netif_wake_queue(ndev); + + return 0; +} + +static int ican3_get_berr_counter(const struct net_device *ndev, + struct can_berr_counter *bec) +{ + struct ican3_dev *mod = netdev_priv(ndev); + int ret; + + ret = ican3_send_inquiry(mod, INQUIRY_STATUS); + if (ret) + return ret; + + ret = wait_for_completion_timeout(&mod->buserror_comp, HZ); + if (ret <= 0) { + dev_info(mod->dev, "%s timed out\n", __func__); + return -ETIMEDOUT; + } + + bec->rxerr = mod->bec.rxerr; + bec->txerr = mod->bec.txerr; + return 0; +} + +/* + * Sysfs Attributes + */ + +static ssize_t ican3_sysfs_show_term(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ican3_dev *mod = netdev_priv(to_net_dev(dev)); + int ret; + + ret = ican3_send_inquiry(mod, INQUIRY_TERMINATION); + if (ret) + return ret; + + ret = wait_for_completion_timeout(&mod->termination_comp, HZ); + if (ret <= 0) { + dev_info(mod->dev, "%s timed out\n", __func__); + return -ETIMEDOUT; + } + + return snprintf(buf, PAGE_SIZE, "%u\n", mod->termination_enabled); +} + +static ssize_t ican3_sysfs_set_term(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ican3_dev *mod = netdev_priv(to_net_dev(dev)); + unsigned long enable; + int ret; + + if (strict_strtoul(buf, 0, &enable)) + return -EINVAL; + + ret = ican3_set_termination(mod, enable); + if (ret) + return ret; + + return count; +} + +static DEVICE_ATTR(termination, S_IWUGO | S_IRUGO, ican3_sysfs_show_term, + ican3_sysfs_set_term); + +static struct attribute *ican3_sysfs_attrs[] = { + &dev_attr_termination.attr, + NULL, +}; + +static struct attribute_group ican3_sysfs_attr_group = { + .attrs = ican3_sysfs_attrs, +}; + +/* + * PCI Subsystem + */ + +static int __devinit ican3_probe(struct platform_device *pdev) +{ + struct janz_platform_data *pdata; + struct net_device *ndev; + struct ican3_dev *mod; + struct resource *res; + struct device *dev; + int ret; + + pdata = pdev->dev.platform_data; + if (!pdata) + return -ENXIO; + + dev_dbg(&pdev->dev, "probe: module number %d\n", pdata->modno); + + /* save the struct device for printing */ + dev = &pdev->dev; + + /* allocate the CAN device and private data */ + ndev = alloc_candev(sizeof(*mod), 0); + if (!ndev) { + dev_err(dev, "unable to allocate CANdev\n"); + ret = -ENOMEM; + goto out_return; + } + + platform_set_drvdata(pdev, ndev); + mod = netdev_priv(ndev); + mod->ndev = ndev; + mod->dev = &pdev->dev; + mod->num = pdata->modno; + netif_napi_add(ndev, &mod->napi, ican3_napi, ICAN3_RX_BUFFERS); + spin_lock_init(&mod->lock); + init_completion(&mod->termination_comp); + init_completion(&mod->buserror_comp); + + /* setup device-specific sysfs attributes */ + ndev->sysfs_groups[0] = &ican3_sysfs_attr_group; + + /* the first unallocated page in the DPM is 9 */ + mod->free_page = DPM_FREE_START; + + ndev->netdev_ops = &ican3_netdev_ops; + ndev->flags |= IFF_ECHO; + SET_NETDEV_DEV(ndev, &pdev->dev); + + mod->can.clock.freq = ICAN3_CAN_CLOCK; + mod->can.bittiming_const = &ican3_bittiming_const; + mod->can.do_set_bittiming = ican3_set_bittiming; + mod->can.do_set_mode = ican3_set_mode; + mod->can.do_get_berr_counter = ican3_get_berr_counter; + mod->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES + | CAN_CTRLMODE_BERR_REPORTING; + + /* find our IRQ number */ + mod->irq = platform_get_irq(pdev, 0); + if (mod->irq < 0) { + dev_err(dev, "IRQ line not found\n"); + ret = -ENODEV; + goto out_free_ndev; + } + + ndev->irq = mod->irq; + + /* get access to the MODULbus registers for this module */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "MODULbus registers not found\n"); + ret = -ENODEV; + goto out_free_ndev; + } + + mod->dpm = ioremap(res->start, resource_size(res)); + if (!mod->dpm) { + dev_err(dev, "MODULbus registers not ioremap\n"); + ret = -ENOMEM; + goto out_free_ndev; + } + + mod->dpmctrl = mod->dpm + DPM_PAGE_SIZE; + + /* get access to the control registers for this module */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { + dev_err(dev, "CONTROL registers not found\n"); + ret = -ENODEV; + goto out_iounmap_dpm; + } + + mod->ctrl = ioremap(res->start, resource_size(res)); + if (!mod->ctrl) { + dev_err(dev, "CONTROL registers not ioremap\n"); + ret = -ENOMEM; + goto out_iounmap_dpm; + } + + /* disable our IRQ, then hookup the IRQ handler */ + iowrite8(1 << mod->num, &mod->ctrl->int_disable); + ret = request_irq(mod->irq, ican3_irq, IRQF_SHARED, DRV_NAME, mod); + if (ret) { + dev_err(dev, "unable to request IRQ\n"); + goto out_iounmap_ctrl; + } + + /* reset and initialize the CAN controller into fast mode */ + napi_enable(&mod->napi); + ret = ican3_startup_module(mod); + if (ret) { + dev_err(dev, "%s: unable to start CANdev\n", __func__); + goto out_free_irq; + } + + /* register with the Linux CAN layer */ + ret = register_candev(ndev); + if (ret) { + dev_err(dev, "%s: unable to register CANdev\n", __func__); + goto out_free_irq; + } + + dev_info(dev, "module %d: registered CAN device\n", pdata->modno); + return 0; + +out_free_irq: + napi_disable(&mod->napi); + iowrite8(1 << mod->num, &mod->ctrl->int_disable); + free_irq(mod->irq, mod); +out_iounmap_ctrl: + iounmap(mod->ctrl); +out_iounmap_dpm: + iounmap(mod->dpm); +out_free_ndev: + free_candev(ndev); +out_return: + return ret; +} + +static int __devexit ican3_remove(struct platform_device *pdev) +{ + struct net_device *ndev = platform_get_drvdata(pdev); + struct ican3_dev *mod = netdev_priv(ndev); + + /* unregister the netdevice, stop interrupts */ + unregister_netdev(ndev); + napi_disable(&mod->napi); + iowrite8(1 << mod->num, &mod->ctrl->int_disable); + free_irq(mod->irq, mod); + + /* put the module into reset */ + ican3_shutdown_module(mod); + + /* unmap all registers */ + iounmap(mod->ctrl); + iounmap(mod->dpm); + + free_candev(ndev); + + return 0; +} + +static struct platform_driver ican3_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = ican3_probe, + .remove = __devexit_p(ican3_remove), +}; + +static int __init ican3_init(void) +{ + return platform_driver_register(&ican3_driver); +} + +static void __exit ican3_exit(void) +{ + platform_driver_unregister(&ican3_driver); +} + +MODULE_AUTHOR("Ira W. Snyder "); +MODULE_DESCRIPTION("Janz MODULbus VMOD-ICAN3 Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:janz-ican3"); + +module_init(ican3_init); +module_exit(ican3_exit); -- cgit v1.2.3 From 800e69fbd2faea906cabd10ddb77e36410f2bd9c Mon Sep 17 00:00:00 2001 From: "Ira W. Snyder" Date: Wed, 7 Apr 2010 10:08:01 +0200 Subject: gpio: Add support for Janz VMOD-TTL Digital IO module The Janz VMOD-TTL is a MODULbus daughterboard which fits onto any MODULbus carrier board. It essentially consists of some various logic and a Zilog Z8536 CIO Counter/Timer and Parallel IO Unit. The board must be physically configured with jumpers to enable a user to drive output signals. I am only interested in outputs, so I have made this driver as simple as possible. It only supports a very minimal subset of the features provided by the Z8536 chip. Signed-off-by: Ira W. Snyder Signed-off-by: Samuel Ortiz --- drivers/gpio/Kconfig | 10 ++ drivers/gpio/Makefile | 1 + drivers/gpio/janz-ttl.c | 258 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 269 insertions(+) create mode 100644 drivers/gpio/janz-ttl.c (limited to 'drivers') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 56eb0c59c512..0e9c16b5bbce 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -325,4 +325,14 @@ config GPIO_UCB1400 To compile this driver as a module, choose M here: the module will be called ucb1400_gpio. +comment "MODULbus GPIO expanders:" + +config GPIO_JANZ_TTL + tristate "Janz VMOD-TTL Digital IO Module" + depends on MFD_JANZ_CMODIO + help + This enables support for the Janz VMOD-TTL Digital IO module. + This driver provides support for driving the pins in output + mode only. Input mode is not supported. + endif diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index d3226d395a90..94a96c51c741 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -29,3 +29,4 @@ obj-$(CONFIG_GPIO_WM8350) += wm8350-gpiolib.o obj-$(CONFIG_GPIO_WM8994) += wm8994-gpio.o obj-$(CONFIG_GPIO_SCH) += sch_gpio.o obj-$(CONFIG_GPIO_RDC321X) += rdc321x-gpio.o +obj-$(CONFIG_GPIO_JANZ_TTL) += janz-ttl.o diff --git a/drivers/gpio/janz-ttl.c b/drivers/gpio/janz-ttl.c new file mode 100644 index 000000000000..813ac077e5d7 --- /dev/null +++ b/drivers/gpio/janz-ttl.c @@ -0,0 +1,258 @@ +/* + * Janz MODULbus VMOD-TTL GPIO Driver + * + * Copyright (c) 2010 Ira W. Snyder + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DRV_NAME "janz-ttl" + +#define PORTA_DIRECTION 0x23 +#define PORTB_DIRECTION 0x2B +#define PORTC_DIRECTION 0x06 +#define PORTA_IOCTL 0x24 +#define PORTB_IOCTL 0x2C +#define PORTC_IOCTL 0x07 + +#define MASTER_INT_CTL 0x00 +#define MASTER_CONF_CTL 0x01 + +#define CONF_PAE (1 << 2) +#define CONF_PBE (1 << 7) +#define CONF_PCE (1 << 4) + +struct ttl_control_regs { + __be16 portc; + __be16 portb; + __be16 porta; + __be16 control; +}; + +struct ttl_module { + struct gpio_chip gpio; + + /* base address of registers */ + struct ttl_control_regs __iomem *regs; + + u8 portc_shadow; + u8 portb_shadow; + u8 porta_shadow; + + spinlock_t lock; +}; + +static int ttl_get_value(struct gpio_chip *gpio, unsigned offset) +{ + struct ttl_module *mod = dev_get_drvdata(gpio->dev); + u8 *shadow; + int ret; + + if (offset < 8) { + shadow = &mod->porta_shadow; + } else if (offset < 16) { + shadow = &mod->portb_shadow; + offset -= 8; + } else { + shadow = &mod->portc_shadow; + offset -= 16; + } + + spin_lock(&mod->lock); + ret = *shadow & (1 << offset); + spin_unlock(&mod->lock); + return ret; +} + +static void ttl_set_value(struct gpio_chip *gpio, unsigned offset, int value) +{ + struct ttl_module *mod = dev_get_drvdata(gpio->dev); + void __iomem *port; + u8 *shadow; + + if (offset < 8) { + port = &mod->regs->porta; + shadow = &mod->porta_shadow; + } else if (offset < 16) { + port = &mod->regs->portb; + shadow = &mod->portb_shadow; + offset -= 8; + } else { + port = &mod->regs->portc; + shadow = &mod->portc_shadow; + offset -= 16; + } + + spin_lock(&mod->lock); + if (value) + *shadow |= (1 << offset); + else + *shadow &= ~(1 << offset); + + iowrite16be(*shadow, port); + spin_unlock(&mod->lock); +} + +static void __devinit ttl_write_reg(struct ttl_module *mod, u8 reg, u16 val) +{ + iowrite16be(reg, &mod->regs->control); + iowrite16be(val, &mod->regs->control); +} + +static void __devinit ttl_setup_device(struct ttl_module *mod) +{ + /* reset the device to a known state */ + iowrite16be(0x0000, &mod->regs->control); + iowrite16be(0x0001, &mod->regs->control); + iowrite16be(0x0000, &mod->regs->control); + + /* put all ports in open-drain mode */ + ttl_write_reg(mod, PORTA_IOCTL, 0x00ff); + ttl_write_reg(mod, PORTB_IOCTL, 0x00ff); + ttl_write_reg(mod, PORTC_IOCTL, 0x000f); + + /* set all ports as outputs */ + ttl_write_reg(mod, PORTA_DIRECTION, 0x0000); + ttl_write_reg(mod, PORTB_DIRECTION, 0x0000); + ttl_write_reg(mod, PORTC_DIRECTION, 0x0000); + + /* set all ports to drive zeroes */ + iowrite16be(0x0000, &mod->regs->porta); + iowrite16be(0x0000, &mod->regs->portb); + iowrite16be(0x0000, &mod->regs->portc); + + /* enable all ports */ + ttl_write_reg(mod, MASTER_CONF_CTL, CONF_PAE | CONF_PBE | CONF_PCE); +} + +static int __devinit ttl_probe(struct platform_device *pdev) +{ + struct janz_platform_data *pdata; + struct device *dev = &pdev->dev; + struct ttl_module *mod; + struct gpio_chip *gpio; + struct resource *res; + int ret; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(dev, "no platform data\n"); + ret = -ENXIO; + goto out_return; + } + + mod = kzalloc(sizeof(*mod), GFP_KERNEL); + if (!mod) { + dev_err(dev, "unable to allocate private data\n"); + ret = -ENOMEM; + goto out_return; + } + + platform_set_drvdata(pdev, mod); + spin_lock_init(&mod->lock); + + /* get access to the MODULbus registers for this module */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "MODULbus registers not found\n"); + ret = -ENODEV; + goto out_free_mod; + } + + mod->regs = ioremap(res->start, resource_size(res)); + if (!mod->regs) { + dev_err(dev, "MODULbus registers not ioremap\n"); + ret = -ENOMEM; + goto out_free_mod; + } + + ttl_setup_device(mod); + + /* Initialize the GPIO data structures */ + gpio = &mod->gpio; + gpio->dev = &pdev->dev; + gpio->label = pdev->name; + gpio->get = ttl_get_value; + gpio->set = ttl_set_value; + gpio->owner = THIS_MODULE; + + /* request dynamic allocation */ + gpio->base = -1; + gpio->ngpio = 20; + + ret = gpiochip_add(gpio); + if (ret) { + dev_err(dev, "unable to add GPIO chip\n"); + goto out_iounmap_regs; + } + + dev_info(&pdev->dev, "module %d: registered GPIO device\n", + pdata->modno); + return 0; + +out_iounmap_regs: + iounmap(mod->regs); +out_free_mod: + kfree(mod); +out_return: + return ret; +} + +static int __devexit ttl_remove(struct platform_device *pdev) +{ + struct ttl_module *mod = platform_get_drvdata(pdev); + struct device *dev = &pdev->dev; + int ret; + + ret = gpiochip_remove(&mod->gpio); + if (ret) { + dev_err(dev, "unable to remove GPIO chip\n"); + return ret; + } + + iounmap(mod->regs); + kfree(mod); + return 0; +} + +static struct platform_driver ttl_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = ttl_probe, + .remove = __devexit_p(ttl_remove), +}; + +static int __init ttl_init(void) +{ + return platform_driver_register(&ttl_driver); +} + +static void __exit ttl_exit(void) +{ + platform_driver_unregister(&ttl_driver); +} + +MODULE_AUTHOR("Ira W. Snyder "); +MODULE_DESCRIPTION("Janz MODULbus VMOD-TTL Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:janz-ttl"); + +module_init(ttl_init); +module_exit(ttl_exit); -- cgit v1.2.3 From 7cc1392aabc31d2af9bd3cc5febbd91977452181 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 2 Apr 2010 16:31:03 +0100 Subject: mfd: Improve WM831x AUXADC completion handling Currently completion of WM831x AUXADC conversions is monitored by checking for convertor enable. Due to the mechanism used to ensure data corruption is avoided when reading AUXADC data there may under heavy I/O be a window where this bit has cleared but the conversion results have not been updated. Data availability is only guaranteed after the AUXADC data interrupt has been asserted. Avoid this by always using the interrupt to detect completion. If the chip IRQ is not set up then we poll the IRQ status register for up to 5ms. If it is set up then we rely on the data done interrupt with a vastly increased timeout, failing the conversion if the interrupt is not generated. This also saves a register read when using interrupts. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/wm831x-core.c | 65 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index f2ab025ad97a..da00ca9e0c71 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -322,7 +322,11 @@ EXPORT_SYMBOL_GPL(wm831x_set_bits); */ int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input) { - int ret, src; + int ret, src, irq_masked, timeout; + + /* Are we using the interrupt? */ + irq_masked = wm831x_reg_read(wm831x, WM831X_INTERRUPT_STATUS_1_MASK); + irq_masked &= WM831X_AUXADC_DATA_EINT; mutex_lock(&wm831x->auxadc_lock); @@ -342,6 +346,9 @@ int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input) goto out; } + /* Clear any notification from a very late arriving interrupt */ + try_wait_for_completion(&wm831x->auxadc_done); + ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL, WM831X_AUX_CVT_ENA, WM831X_AUX_CVT_ENA); if (ret < 0) { @@ -349,22 +356,46 @@ int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input) goto disable; } - /* If an interrupt arrived late clean up after it */ - try_wait_for_completion(&wm831x->auxadc_done); - - /* Ignore the result to allow us to soldier on without IRQ hookup */ - wait_for_completion_timeout(&wm831x->auxadc_done, msecs_to_jiffies(5)); - - ret = wm831x_reg_read(wm831x, WM831X_AUXADC_CONTROL); - if (ret < 0) { - dev_err(wm831x->dev, "AUXADC status read failed: %d\n", ret); - goto disable; - } - - if (ret & WM831X_AUX_CVT_ENA) { - dev_err(wm831x->dev, "Timed out reading AUXADC\n"); - ret = -EBUSY; - goto disable; + if (irq_masked) { + /* If we're not using interrupts then poll the + * interrupt status register */ + timeout = 5; + while (timeout) { + msleep(1); + + ret = wm831x_reg_read(wm831x, + WM831X_INTERRUPT_STATUS_1); + if (ret < 0) { + dev_err(wm831x->dev, + "ISR 1 read failed: %d\n", ret); + goto disable; + } + + /* Did it complete? */ + if (ret & WM831X_AUXADC_DATA_EINT) { + wm831x_reg_write(wm831x, + WM831X_INTERRUPT_STATUS_1, + WM831X_AUXADC_DATA_EINT); + break; + } else { + dev_err(wm831x->dev, + "AUXADC conversion timeout\n"); + ret = -EBUSY; + goto disable; + } + } + } else { + /* If we are using interrupts then wait for the + * interrupt to complete. Use an extremely long + * timeout to handle situations with heavy load where + * the notification of the interrupt may be delayed by + * threaded IRQ handling. */ + if (!wait_for_completion_timeout(&wm831x->auxadc_done, + msecs_to_jiffies(500))) { + dev_err(wm831x->dev, "Timed out waiting for AUXADC\n"); + ret = -EBUSY; + goto disable; + } } ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA); -- cgit v1.2.3 From 374b72ecacc074f8cfccea5a70bdd64d8953dffd Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 2 Apr 2010 18:24:20 +0200 Subject: gpio: Update gfp/slab.h includes for rdc321x Implicit slab.h inclusion via percpu.h is about to go away. Make sure gfp.h or slab.h is included as necessary. Signed-off-by: Samuel Ortiz Signed-off-by: Tejun Heo --- drivers/gpio/rdc321x-gpio.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpio/rdc321x-gpio.c b/drivers/gpio/rdc321x-gpio.c index 46c55193b9db..e344907da5b0 100644 --- a/drivers/gpio/rdc321x-gpio.c +++ b/drivers/gpio/rdc321x-gpio.c @@ -27,6 +27,7 @@ #include #include #include +#include struct rdc321x_gpio { spinlock_t lock; -- cgit v1.2.3 From d183fcc975cbbc9c427deb2d7948ab03673995c9 Mon Sep 17 00:00:00 2001 From: Todd Fischer Date: Mon, 5 Apr 2010 20:23:56 -0600 Subject: mfd: Move TPS6507x register definition to header file. Other sub-drivers for the TPS6507x chip will need to use register definition so move it out of the source file and into a header file. Signed-off-by: Todd Fischer Acked-by: Mark Brown Signed-off-by: Liam Girdwood Signed-off-by: Samuel Ortiz --- drivers/regulator/tps6507x-regulator.c | 60 +-------------- include/linux/mfd/tps6507x.h | 134 +++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+), 59 deletions(-) create mode 100644 include/linux/mfd/tps6507x.h (limited to 'drivers') diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index 74841abcc9cc..23c0597ab1f5 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -25,65 +25,7 @@ #include #include #include - -/* Register definitions */ -#define TPS6507X_REG_PPATH1 0X01 -#define TPS6507X_REG_INT 0X02 -#define TPS6507X_REG_CHGCONFIG0 0X03 -#define TPS6507X_REG_CHGCONFIG1 0X04 -#define TPS6507X_REG_CHGCONFIG2 0X05 -#define TPS6507X_REG_CHGCONFIG3 0X06 -#define TPS6507X_REG_REG_ADCONFIG 0X07 -#define TPS6507X_REG_TSCMODE 0X08 -#define TPS6507X_REG_ADRESULT_1 0X09 -#define TPS6507X_REG_ADRESULT_2 0X0A -#define TPS6507X_REG_PGOOD 0X0B -#define TPS6507X_REG_PGOODMASK 0X0C -#define TPS6507X_REG_CON_CTRL1 0X0D -#define TPS6507X_REG_CON_CTRL2 0X0E -#define TPS6507X_REG_CON_CTRL3 0X0F -#define TPS6507X_REG_DEFDCDC1 0X10 -#define TPS6507X_REG_DEFDCDC2_LOW 0X11 -#define TPS6507X_REG_DEFDCDC2_HIGH 0X12 -#define TPS6507X_REG_DEFDCDC3_LOW 0X13 -#define TPS6507X_REG_DEFDCDC3_HIGH 0X14 -#define TPS6507X_REG_DEFSLEW 0X15 -#define TPS6507X_REG_LDO_CTRL1 0X16 -#define TPS6507X_REG_DEFLDO2 0X17 -#define TPS6507X_REG_WLED_CTRL1 0X18 -#define TPS6507X_REG_WLED_CTRL2 0X19 - -/* CON_CTRL1 bitfields */ -#define TPS6507X_CON_CTRL1_DCDC1_ENABLE BIT(4) -#define TPS6507X_CON_CTRL1_DCDC2_ENABLE BIT(3) -#define TPS6507X_CON_CTRL1_DCDC3_ENABLE BIT(2) -#define TPS6507X_CON_CTRL1_LDO1_ENABLE BIT(1) -#define TPS6507X_CON_CTRL1_LDO2_ENABLE BIT(0) - -/* DEFDCDC1 bitfields */ -#define TPS6507X_DEFDCDC1_DCDC1_EXT_ADJ_EN BIT(7) -#define TPS6507X_DEFDCDC1_DCDC1_MASK 0X3F - -/* DEFDCDC2_LOW bitfields */ -#define TPS6507X_DEFDCDC2_LOW_DCDC2_MASK 0X3F - -/* DEFDCDC2_HIGH bitfields */ -#define TPS6507X_DEFDCDC2_HIGH_DCDC2_MASK 0X3F - -/* DEFDCDC3_LOW bitfields */ -#define TPS6507X_DEFDCDC3_LOW_DCDC3_MASK 0X3F - -/* DEFDCDC3_HIGH bitfields */ -#define TPS6507X_DEFDCDC3_HIGH_DCDC3_MASK 0X3F - -/* TPS6507X_REG_LDO_CTRL1 bitfields */ -#define TPS6507X_REG_LDO_CTRL1_LDO1_MASK 0X0F - -/* TPS6507X_REG_DEFLDO2 bitfields */ -#define TPS6507X_REG_DEFLDO2_LDO2_MASK 0X3F - -/* VDCDC MASK */ -#define TPS6507X_DEFDCDCX_DCDC_MASK 0X3F +#include /* DCDC's */ #define TPS6507X_DCDC_1 0 diff --git a/include/linux/mfd/tps6507x.h b/include/linux/mfd/tps6507x.h new file mode 100644 index 000000000000..155bee1f7823 --- /dev/null +++ b/include/linux/mfd/tps6507x.h @@ -0,0 +1,134 @@ +/* linux/mfd/tps6507x.h + * + * Functions to access TPS65070 power management chip. + * + * Copyright (c) 2009 RidgeRun (todd.fischer@ridgerun.com) + * + * + * For licencing details see kernel-base/COPYING + */ + +#ifndef __LINUX_MFD_TPS6507X_H +#define __LINUX_MFD_TPS6507X_H + +/* + * ---------------------------------------------------------------------------- + * Registers, all 8 bits + * ---------------------------------------------------------------------------- + */ + + +/* Register definitions */ +#define TPS6507X_REG_PPATH1 0X01 +#define TPS6507X_CHG_USB BIT(7) +#define TPS6507X_CHG_AC BIT(6) +#define TPS6507X_CHG_USB_PW_ENABLE BIT(5) +#define TPS6507X_CHG_AC_PW_ENABLE BIT(4) +#define TPS6507X_CHG_AC_CURRENT BIT(2) +#define TPS6507X_CHG_USB_CURRENT BIT(0) + +#define TPS6507X_REG_INT 0X02 +#define TPS6507X_REG_MASK_AC_USB BIT(7) +#define TPS6507X_REG_MASK_TSC BIT(6) +#define TPS6507X_REG_MASK_PB_IN BIT(5) +#define TPS6507X_REG_TSC_INT BIT(3) +#define TPS6507X_REG_PB_IN_INT BIT(2) +#define TPS6507X_REG_AC_USB_APPLIED BIT(1) +#define TPS6507X_REG_AC_USB_REMOVED BIT(0) + +#define TPS6507X_REG_CHGCONFIG0 0X03 + +#define TPS6507X_REG_CHGCONFIG1 0X04 +#define TPS6507X_CON_CTRL1_DCDC1_ENABLE BIT(4) +#define TPS6507X_CON_CTRL1_DCDC2_ENABLE BIT(3) +#define TPS6507X_CON_CTRL1_DCDC3_ENABLE BIT(2) +#define TPS6507X_CON_CTRL1_LDO1_ENABLE BIT(1) +#define TPS6507X_CON_CTRL1_LDO2_ENABLE BIT(0) + +#define TPS6507X_REG_CHGCONFIG2 0X05 + +#define TPS6507X_REG_CHGCONFIG3 0X06 + +#define TPS6507X_REG_ADCONFIG 0X07 +#define TPS6507X_ADCONFIG_AD_ENABLE BIT(7) +#define TPS6507X_ADCONFIG_START_CONVERSION BIT(6) +#define TPS6507X_ADCONFIG_CONVERSION_DONE BIT(5) +#define TPS6507X_ADCONFIG_VREF_ENABLE BIT(4) +#define TPS6507X_ADCONFIG_INPUT_AD_IN1 0 +#define TPS6507X_ADCONFIG_INPUT_AD_IN2 1 +#define TPS6507X_ADCONFIG_INPUT_AD_IN3 2 +#define TPS6507X_ADCONFIG_INPUT_AD_IN4 3 +#define TPS6507X_ADCONFIG_INPUT_TS_PIN 4 +#define TPS6507X_ADCONFIG_INPUT_BAT_CURRENT 5 +#define TPS6507X_ADCONFIG_INPUT_AC_VOLTAGE 6 +#define TPS6507X_ADCONFIG_INPUT_SYS_VOLTAGE 7 +#define TPS6507X_ADCONFIG_INPUT_CHARGER_VOLTAGE 8 +#define TPS6507X_ADCONFIG_INPUT_BAT_VOLTAGE 9 +#define TPS6507X_ADCONFIG_INPUT_THRESHOLD_VOLTAGE 10 +#define TPS6507X_ADCONFIG_INPUT_ISET1_VOLTAGE 11 +#define TPS6507X_ADCONFIG_INPUT_ISET2_VOLTAGE 12 +#define TPS6507X_ADCONFIG_INPUT_REAL_TSC 14 +#define TPS6507X_ADCONFIG_INPUT_TSC 15 + +#define TPS6507X_REG_TSCMODE 0X08 +#define TPS6507X_TSCMODE_X_POSITION 0 +#define TPS6507X_TSCMODE_Y_POSITION 1 +#define TPS6507X_TSCMODE_PRESSURE 2 +#define TPS6507X_TSCMODE_X_PLATE 3 +#define TPS6507X_TSCMODE_Y_PLATE 4 +#define TPS6507X_TSCMODE_STANDBY 5 +#define TPS6507X_TSCMODE_ADC_INPUT 6 +#define TPS6507X_TSCMODE_DISABLE 7 + +#define TPS6507X_REG_ADRESULT_1 0X09 + +#define TPS6507X_REG_ADRESULT_2 0X0A +#define TPS6507X_REG_ADRESULT_2_MASK (BIT(1) | BIT(0)) + +#define TPS6507X_REG_PGOOD 0X0B + +#define TPS6507X_REG_PGOODMASK 0X0C + +#define TPS6507X_REG_CON_CTRL1 0X0D +#define TPS6507X_CON_CTRL1_DCDC1_ENABLE BIT(4) +#define TPS6507X_CON_CTRL1_DCDC2_ENABLE BIT(3) +#define TPS6507X_CON_CTRL1_DCDC3_ENABLE BIT(2) +#define TPS6507X_CON_CTRL1_LDO1_ENABLE BIT(1) +#define TPS6507X_CON_CTRL1_LDO2_ENABLE BIT(0) + +#define TPS6507X_REG_CON_CTRL2 0X0E + +#define TPS6507X_REG_CON_CTRL3 0X0F + +#define TPS6507X_REG_DEFDCDC1 0X10 +#define TPS6507X_DEFDCDC1_DCDC1_EXT_ADJ_EN BIT(7) +#define TPS6507X_DEFDCDC1_DCDC1_MASK 0X3F + +#define TPS6507X_REG_DEFDCDC2_LOW 0X11 +#define TPS6507X_DEFDCDC2_LOW_DCDC2_MASK 0X3F + +#define TPS6507X_REG_DEFDCDC2_HIGH 0X12 +#define TPS6507X_DEFDCDC2_HIGH_DCDC2_MASK 0X3F + +#define TPS6507X_REG_DEFDCDC3_LOW 0X13 +#define TPS6507X_DEFDCDC3_LOW_DCDC3_MASK 0X3F + +#define TPS6507X_REG_DEFDCDC3_HIGH 0X14 +#define TPS6507X_DEFDCDC3_HIGH_DCDC3_MASK 0X3F + +#define TPS6507X_REG_DEFSLEW 0X15 + +#define TPS6507X_REG_LDO_CTRL1 0X16 +#define TPS6507X_REG_LDO_CTRL1_LDO1_MASK 0X0F + +#define TPS6507X_REG_DEFLDO2 0X17 +#define TPS6507X_REG_DEFLDO2_LDO2_MASK 0X3F + +#define TPS6507X_REG_WLED_CTRL1 0X18 + +#define TPS6507X_REG_WLED_CTRL2 0X19 + +/* VDCDC MASK */ +#define TPS6507X_DEFDCDCX_DCDC_MASK 0X3F + +#endif /* __LINUX_MFD_TPS6507X_H */ -- cgit v1.2.3 From 0bc20bba357f18a0e52f45afc452d0b69cf06f76 Mon Sep 17 00:00:00 2001 From: Todd Fischer Date: Mon, 5 Apr 2010 20:23:57 -0600 Subject: mfd: Add tps6507x board data structure Add mfd structure which refrences sub-driver initialization data. For example, for a giving hardware implementation, the voltage regulator sub-driver initialization data provides the mapping betten a voltage regulator and what the output voltage is being used for. Signed-off-by: Todd Fischer Acked-by: Mark Brown Signed-off-by: Liam Girdwood Signed-off-by: Samuel Ortiz --- arch/arm/mach-davinci/board-da850-evm.c | 7 ++++++- drivers/regulator/tps6507x-regulator.c | 14 ++++++++++++-- include/linux/mfd/tps6507x.h | 11 +++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index abd04932917b..95adfd42d0e6 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -533,10 +534,14 @@ struct regulator_init_data tps65070_regulator_data[] = { }, }; +static struct tps6507x_board tps_board = { + .tps6507x_pmic_init_data = &tps65070_regulator_data[0], +}; + static struct i2c_board_info __initdata da850evm_tps65070_info[] = { { I2C_BOARD_INFO("tps6507x", 0x48), - .platform_data = &tps65070_regulator_data[0], + .platform_data = &tps_board, }, }; diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index 23c0597ab1f5..c3f1bf822fd0 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -489,6 +489,7 @@ static int __devinit tps_6507x_probe(struct i2c_client *client, struct regulator_init_data *init_data; struct regulator_dev *rdev; struct tps_pmic *tps; + struct tps6507x_board *tps_board; int i; int error; @@ -496,13 +497,22 @@ static int __devinit tps_6507x_probe(struct i2c_client *client, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; + /** + * tps_board points to pmic related constants + * coming from the board-evm file. + */ + + tps_board = dev_get_platdata(&client->dev); + if (!tps_board) + return -EINVAL; + /** * init_data points to array of regulator_init structures * coming from the board-evm file. */ - init_data = client->dev.platform_data; + init_data = tps_board->tps6507x_pmic_init_data; if (!init_data) - return -EIO; + return -EINVAL; tps = kzalloc(sizeof(*tps), GFP_KERNEL); if (!tps) diff --git a/include/linux/mfd/tps6507x.h b/include/linux/mfd/tps6507x.h index 155bee1f7823..fd73af5fb95a 100644 --- a/include/linux/mfd/tps6507x.h +++ b/include/linux/mfd/tps6507x.h @@ -131,4 +131,15 @@ /* VDCDC MASK */ #define TPS6507X_DEFDCDCX_DCDC_MASK 0X3F +/** + * struct tps6507x_board - packages regulator and touchscreen init data + * @tps6507x_regulator_data: regulator initialization values + * + * Board data may be used to initialize regulator and touchscreen. + */ + +struct tps6507x_board { + struct regulator_init_data *tps6507x_pmic_init_data; +}; + #endif /* __LINUX_MFD_TPS6507X_H */ -- cgit v1.2.3 From 4ce5ba5ba2dfc8186bf31fe7f2d23ff6b5384124 Mon Sep 17 00:00:00 2001 From: Todd Fischer Date: Mon, 5 Apr 2010 20:23:58 -0600 Subject: regulator: tps6057x namespace cleanup Move from using tps or tsp6507x to tps6057x_pmic in a consistent manner. Signed-off-by: Todd Fischer Acked-by: Mark Brown Signed-off-by: Liam Girdwood Signed-off-by: Samuel Ortiz --- drivers/regulator/tps6507x-regulator.c | 172 +++++++++++++++++---------------- 1 file changed, 87 insertions(+), 85 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index c3f1bf822fd0..ea44741fcd47 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -104,7 +104,7 @@ struct tps_info { const u16 *table; }; -struct tps_pmic { +struct tps6507x_pmic { struct regulator_desc desc[TPS6507X_NUM_REGULATOR]; struct i2c_client *client; struct regulator_dev *rdev[TPS6507X_NUM_REGULATOR]; @@ -112,23 +112,23 @@ struct tps_pmic { struct mutex io_lock; }; -static inline int tps_6507x_read(struct tps_pmic *tps, u8 reg) +static inline int tps6507x_pmic_read(struct tps6507x_pmic *tps, u8 reg) { return i2c_smbus_read_byte_data(tps->client, reg); } -static inline int tps_6507x_write(struct tps_pmic *tps, u8 reg, u8 val) +static inline int tps6507x_pmic_write(struct tps6507x_pmic *tps, u8 reg, u8 val) { return i2c_smbus_write_byte_data(tps->client, reg, val); } -static int tps_6507x_set_bits(struct tps_pmic *tps, u8 reg, u8 mask) +static int tps6507x_pmic_set_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask) { int err, data; mutex_lock(&tps->io_lock); - data = tps_6507x_read(tps, reg); + data = tps6507x_pmic_read(tps, reg); if (data < 0) { dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); err = data; @@ -136,7 +136,7 @@ static int tps_6507x_set_bits(struct tps_pmic *tps, u8 reg, u8 mask) } data |= mask; - err = tps_6507x_write(tps, reg, data); + err = tps6507x_pmic_write(tps, reg, data); if (err) dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); @@ -145,13 +145,13 @@ out: return err; } -static int tps_6507x_clear_bits(struct tps_pmic *tps, u8 reg, u8 mask) +static int tps6507x_pmic_clear_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask) { int err, data; mutex_lock(&tps->io_lock); - data = tps_6507x_read(tps, reg); + data = tps6507x_pmic_read(tps, reg); if (data < 0) { dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); err = data; @@ -159,7 +159,7 @@ static int tps_6507x_clear_bits(struct tps_pmic *tps, u8 reg, u8 mask) } data &= ~mask; - err = tps_6507x_write(tps, reg, data); + err = tps6507x_pmic_write(tps, reg, data); if (err) dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); @@ -168,13 +168,13 @@ out: return err; } -static int tps_6507x_reg_read(struct tps_pmic *tps, u8 reg) +static int tps6507x_pmic_reg_read(struct tps6507x_pmic *tps, u8 reg) { int data; mutex_lock(&tps->io_lock); - data = tps_6507x_read(tps, reg); + data = tps6507x_pmic_read(tps, reg); if (data < 0) dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); @@ -182,13 +182,13 @@ static int tps_6507x_reg_read(struct tps_pmic *tps, u8 reg) return data; } -static int tps_6507x_reg_write(struct tps_pmic *tps, u8 reg, u8 val) +static int tps6507x_pmic_reg_write(struct tps6507x_pmic *tps, u8 reg, u8 val) { int err; mutex_lock(&tps->io_lock); - err = tps_6507x_write(tps, reg, val); + err = tps6507x_pmic_write(tps, reg, val); if (err < 0) dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); @@ -196,9 +196,9 @@ static int tps_6507x_reg_write(struct tps_pmic *tps, u8 reg, u8 val) return err; } -static int tps6507x_dcdc_is_enabled(struct regulator_dev *dev) +static int tps6507x_pmic_dcdc_is_enabled(struct regulator_dev *dev) { - struct tps_pmic *tps = rdev_get_drvdata(dev); + struct tps6507x_pmic *tps = rdev_get_drvdata(dev); int data, dcdc = rdev_get_id(dev); u8 shift; @@ -206,7 +206,7 @@ static int tps6507x_dcdc_is_enabled(struct regulator_dev *dev) return -EINVAL; shift = TPS6507X_MAX_REG_ID - dcdc; - data = tps_6507x_reg_read(tps, TPS6507X_REG_CON_CTRL1); + data = tps6507x_pmic_reg_read(tps, TPS6507X_REG_CON_CTRL1); if (data < 0) return data; @@ -214,9 +214,9 @@ static int tps6507x_dcdc_is_enabled(struct regulator_dev *dev) return (data & 1<info[dcdc]->table[data] * 1000; } -static int tps6507x_dcdc_set_voltage(struct regulator_dev *dev, +static int tps6507x_pmic_dcdc_set_voltage(struct regulator_dev *dev, int min_uV, int max_uV) { - struct tps_pmic *tps = rdev_get_drvdata(dev); + struct tps6507x_pmic *tps = rdev_get_drvdata(dev); int data, vsel, dcdc = rdev_get_id(dev); u8 reg; @@ -353,19 +355,19 @@ static int tps6507x_dcdc_set_voltage(struct regulator_dev *dev, if (vsel == tps->info[dcdc]->table_len) return -EINVAL; - data = tps_6507x_reg_read(tps, reg); + data = tps6507x_pmic_reg_read(tps, reg); if (data < 0) return data; data &= ~TPS6507X_DEFDCDCX_DCDC_MASK; data |= vsel; - return tps_6507x_reg_write(tps, reg, data); + return tps6507x_pmic_reg_write(tps, reg, data); } -static int tps6507x_ldo_get_voltage(struct regulator_dev *dev) +static int tps6507x_pmic_ldo_get_voltage(struct regulator_dev *dev) { - struct tps_pmic *tps = rdev_get_drvdata(dev); + struct tps6507x_pmic *tps = rdev_get_drvdata(dev); int data, ldo = rdev_get_id(dev); u8 reg, mask; @@ -379,7 +381,7 @@ static int tps6507x_ldo_get_voltage(struct regulator_dev *dev) TPS6507X_REG_DEFLDO2_LDO2_MASK); } - data = tps_6507x_reg_read(tps, reg); + data = tps6507x_pmic_reg_read(tps, reg); if (data < 0) return data; @@ -387,10 +389,10 @@ static int tps6507x_ldo_get_voltage(struct regulator_dev *dev) return tps->info[ldo]->table[data] * 1000; } -static int tps6507x_ldo_set_voltage(struct regulator_dev *dev, +static int tps6507x_pmic_ldo_set_voltage(struct regulator_dev *dev, int min_uV, int max_uV) { - struct tps_pmic *tps = rdev_get_drvdata(dev); + struct tps6507x_pmic *tps = rdev_get_drvdata(dev); int data, vsel, ldo = rdev_get_id(dev); u8 reg, mask; @@ -421,20 +423,20 @@ static int tps6507x_ldo_set_voltage(struct regulator_dev *dev, if (vsel == tps->info[ldo]->table_len) return -EINVAL; - data = tps_6507x_reg_read(tps, reg); + data = tps6507x_pmic_reg_read(tps, reg); if (data < 0) return data; data &= ~mask; data |= vsel; - return tps_6507x_reg_write(tps, reg, data); + return tps6507x_pmic_reg_write(tps, reg, data); } -static int tps6507x_dcdc_list_voltage(struct regulator_dev *dev, +static int tps6507x_pmic_dcdc_list_voltage(struct regulator_dev *dev, unsigned selector) { - struct tps_pmic *tps = rdev_get_drvdata(dev); + struct tps6507x_pmic *tps = rdev_get_drvdata(dev); int dcdc = rdev_get_id(dev); if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3) @@ -446,10 +448,10 @@ static int tps6507x_dcdc_list_voltage(struct regulator_dev *dev, return tps->info[dcdc]->table[selector] * 1000; } -static int tps6507x_ldo_list_voltage(struct regulator_dev *dev, +static int tps6507x_pmic_ldo_list_voltage(struct regulator_dev *dev, unsigned selector) { - struct tps_pmic *tps = rdev_get_drvdata(dev); + struct tps6507x_pmic *tps = rdev_get_drvdata(dev); int ldo = rdev_get_id(dev); if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) @@ -462,33 +464,33 @@ static int tps6507x_ldo_list_voltage(struct regulator_dev *dev, } /* Operations permitted on VDCDCx */ -static struct regulator_ops tps6507x_dcdc_ops = { - .is_enabled = tps6507x_dcdc_is_enabled, - .enable = tps6507x_dcdc_enable, - .disable = tps6507x_dcdc_disable, - .get_voltage = tps6507x_dcdc_get_voltage, - .set_voltage = tps6507x_dcdc_set_voltage, - .list_voltage = tps6507x_dcdc_list_voltage, +static struct regulator_ops tps6507x_pmic_dcdc_ops = { + .is_enabled = tps6507x_pmic_dcdc_is_enabled, + .enable = tps6507x_pmic_dcdc_enable, + .disable = tps6507x_pmic_dcdc_disable, + .get_voltage = tps6507x_pmic_dcdc_get_voltage, + .set_voltage = tps6507x_pmic_dcdc_set_voltage, + .list_voltage = tps6507x_pmic_dcdc_list_voltage, }; /* Operations permitted on LDOx */ -static struct regulator_ops tps6507x_ldo_ops = { - .is_enabled = tps6507x_ldo_is_enabled, - .enable = tps6507x_ldo_enable, - .disable = tps6507x_ldo_disable, - .get_voltage = tps6507x_ldo_get_voltage, - .set_voltage = tps6507x_ldo_set_voltage, - .list_voltage = tps6507x_ldo_list_voltage, +static struct regulator_ops tps6507x_pmic_ldo_ops = { + .is_enabled = tps6507x_pmic_ldo_is_enabled, + .enable = tps6507x_pmic_ldo_enable, + .disable = tps6507x_pmic_ldo_disable, + .get_voltage = tps6507x_pmic_ldo_get_voltage, + .set_voltage = tps6507x_pmic_ldo_set_voltage, + .list_voltage = tps6507x_pmic_ldo_list_voltage, }; -static int __devinit tps_6507x_probe(struct i2c_client *client, +static int __devinit tps6507x_pmic_probe(struct i2c_client *client, const struct i2c_device_id *id) { static int desc_id; const struct tps_info *info = (void *)id->driver_data; struct regulator_init_data *init_data; struct regulator_dev *rdev; - struct tps_pmic *tps; + struct tps6507x_pmic *tps; struct tps6507x_board *tps_board; int i; int error; @@ -530,7 +532,7 @@ static int __devinit tps_6507x_probe(struct i2c_client *client, tps->desc[i].id = desc_id++; tps->desc[i].n_voltages = num_voltages[i]; tps->desc[i].ops = (i > TPS6507X_DCDC_3 ? - &tps6507x_ldo_ops : &tps6507x_dcdc_ops); + &tps6507x_pmic_ldo_ops : &tps6507x_pmic_dcdc_ops); tps->desc[i].type = REGULATOR_VOLTAGE; tps->desc[i].owner = THIS_MODULE; @@ -560,14 +562,14 @@ fail: } /** - * tps_6507x_remove - TPS6507x driver i2c remove handler + * tps6507x_remove - TPS6507x driver i2c remove handler * @client: i2c driver client device structure * * Unregister TPS driver as an i2c client device driver */ -static int __devexit tps_6507x_remove(struct i2c_client *client) +static int __devexit tps6507x_pmic_remove(struct i2c_client *client) { - struct tps_pmic *tps = i2c_get_clientdata(client); + struct tps6507x_pmic *tps = i2c_get_clientdata(client); int i; /* clear the client data in i2c */ @@ -581,7 +583,7 @@ static int __devexit tps_6507x_remove(struct i2c_client *client) return 0; } -static const struct tps_info tps6507x_regs[] = { +static const struct tps_info tps6507x_pmic_regs[] = { { .name = "VDCDC1", .min_uV = 725000, @@ -619,44 +621,44 @@ static const struct tps_info tps6507x_regs[] = { }, }; -static const struct i2c_device_id tps_6507x_id[] = { +static const struct i2c_device_id tps6507x_pmic_id[] = { {.name = "tps6507x", - .driver_data = (unsigned long) tps6507x_regs,}, + .driver_data = (unsigned long) tps6507x_pmic_regs,}, { }, }; -MODULE_DEVICE_TABLE(i2c, tps_6507x_id); +MODULE_DEVICE_TABLE(i2c, tps6507x_pmic_id); -static struct i2c_driver tps_6507x_i2c_driver = { +static struct i2c_driver tps6507x_i2c_driver = { .driver = { .name = "tps6507x", .owner = THIS_MODULE, }, - .probe = tps_6507x_probe, - .remove = __devexit_p(tps_6507x_remove), - .id_table = tps_6507x_id, + .probe = tps6507x_pmic_probe, + .remove = __devexit_p(tps6507x_pmic_remove), + .id_table = tps6507x_pmic_id, }; /** - * tps_6507x_init + * tps6507x_pmic_init * * Module init function */ -static int __init tps_6507x_init(void) +static int __init tps6507x_pmic_init(void) { - return i2c_add_driver(&tps_6507x_i2c_driver); + return i2c_add_driver(&tps6507x_i2c_driver); } -subsys_initcall(tps_6507x_init); +subsys_initcall(tps6507x_pmic_init); /** - * tps_6507x_cleanup + * tps6507x_pmic_cleanup * * Module exit function */ -static void __exit tps_6507x_cleanup(void) +static void __exit tps6507x_pmic_cleanup(void) { - i2c_del_driver(&tps_6507x_i2c_driver); + i2c_del_driver(&tps6507x_i2c_driver); } -module_exit(tps_6507x_cleanup); +module_exit(tps6507x_pmic_cleanup); MODULE_AUTHOR("Texas Instruments"); MODULE_DESCRIPTION("TPS6507x voltage regulator driver"); -- cgit v1.2.3 From 31dd6a2672e337f5de188df3e5169ee732798236 Mon Sep 17 00:00:00 2001 From: Todd Fischer Date: Thu, 8 Apr 2010 09:04:55 +0200 Subject: mfd: Add TPS6507x support TPS6507x are multi function (PM, touchscreen) chipsets from TI. This commit also changes the corresponding regulator driver from being standalone to an MFD subdevice. Signed-off-by: Todd Fischer Acked-by: Mark Brown Signed-off-by: Liam Girdwood Signed-off-by: Samuel Ortiz --- drivers/mfd/Kconfig | 12 +++ drivers/mfd/Makefile | 1 + drivers/mfd/tps6507x.c | 156 +++++++++++++++++++++++++++++++++ drivers/regulator/tps6507x-regulator.c | 153 ++++++++++++++++---------------- include/linux/mfd/tps6507x.h | 22 +++++ 5 files changed, 265 insertions(+), 79 deletions(-) create mode 100644 drivers/mfd/tps6507x.c (limited to 'drivers') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 05c137d16b04..40e0a0a7df5b 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -116,6 +116,18 @@ config TPS65010 This driver can also be built as a module. If so, the module will be called tps65010. +config TPS6507X + tristate "TPS6507x Power Management / Touch Screen chips" + select MFD_CORE + depends on I2C + help + If you say yes here you get support for the TPS6507x series of + Power Management / Touch Screen chips. These include voltage + regulators, lithium ion/polymer battery charging, touch screen + and other features that are often used in portable devices. + This driver can also be built as a module. If so, the module + will be called tps6507x. + config MENELAUS bool "Texas Instruments TWL92330/Menelaus PM chip" depends on I2C=y && ARCH_OMAP2 diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 21eff85b288a..abf6f1766dcd 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o obj-$(CONFIG_MFD_WM8994) += wm8994-core.o wm8994-irq.o obj-$(CONFIG_TPS65010) += tps65010.o +obj-$(CONFIG_TPS6507X) += tps6507x.o obj-$(CONFIG_MENELAUS) += menelaus.o obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o diff --git a/drivers/mfd/tps6507x.c b/drivers/mfd/tps6507x.c new file mode 100644 index 000000000000..c59f74570b3b --- /dev/null +++ b/drivers/mfd/tps6507x.c @@ -0,0 +1,156 @@ +/* + * tps6507x.c -- TPS6507x chip family multi-function driver + * + * Copyright (c) 2010 RidgeRun (todd.fischer@ridgerun.com) + * + * Author: Todd Fischer + * todd.fischer@ridgerun.com + * + * Credits: + * + * Using code from wm831x-*.c, wm8400-core, Wolfson Microelectronics PLC. + * + * For licencing details see kernel-base/COPYING + * + */ + +#include +#include +#include +#include +#include +#include +#include + +static struct mfd_cell tps6507x_devs[] = { + { + .name = "tps6507x-pmic", + }, +}; + + +static int tps6507x_i2c_read_device(struct tps6507x_dev *tps6507x, char reg, + int bytes, void *dest) +{ + struct i2c_client *i2c = tps6507x->i2c_client; + struct i2c_msg xfer[2]; + int ret; + + /* Write register */ + xfer[0].addr = i2c->addr; + xfer[0].flags = 0; + xfer[0].len = 1; + xfer[0].buf = ® + + /* Read data */ + xfer[1].addr = i2c->addr; + xfer[1].flags = I2C_M_RD; + xfer[1].len = bytes; + xfer[1].buf = dest; + + ret = i2c_transfer(i2c->adapter, xfer, 2); + if (ret == 2) + ret = 0; + else if (ret >= 0) + ret = -EIO; + + return ret; +} + +static int tps6507x_i2c_write_device(struct tps6507x_dev *tps6507x, char reg, + int bytes, void *src) +{ + struct i2c_client *i2c = tps6507x->i2c_client; + /* we add 1 byte for device register */ + u8 msg[TPS6507X_MAX_REGISTER + 1]; + int ret; + + if (bytes > (TPS6507X_MAX_REGISTER + 1)) + return -EINVAL; + + msg[0] = reg; + memcpy(&msg[1], src, bytes); + + ret = i2c_master_send(i2c, msg, bytes + 1); + if (ret < 0) + return ret; + if (ret != bytes + 1) + return -EIO; + return 0; +} + +static int tps6507x_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct tps6507x_dev *tps6507x; + int ret = 0; + + tps6507x = kzalloc(sizeof(struct tps6507x_dev), GFP_KERNEL); + if (tps6507x == NULL) { + kfree(i2c); + return -ENOMEM; + } + + i2c_set_clientdata(i2c, tps6507x); + tps6507x->dev = &i2c->dev; + tps6507x->i2c_client = i2c; + tps6507x->read_dev = tps6507x_i2c_read_device; + tps6507x->write_dev = tps6507x_i2c_write_device; + + ret = mfd_add_devices(tps6507x->dev, -1, + tps6507x_devs, ARRAY_SIZE(tps6507x_devs), + NULL, 0); + + if (ret < 0) + goto err; + + return ret; + +err: + mfd_remove_devices(tps6507x->dev); + kfree(tps6507x); + return ret; +} + +static int tps6507x_i2c_remove(struct i2c_client *i2c) +{ + struct tps6507x_dev *tps6507x = i2c_get_clientdata(i2c); + + mfd_remove_devices(tps6507x->dev); + kfree(tps6507x); + + return 0; +} + +static const struct i2c_device_id tps6507x_i2c_id[] = { + { "tps6507x", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, tps6507x_i2c_id); + + +static struct i2c_driver tps6507x_i2c_driver = { + .driver = { + .name = "tps6507x", + .owner = THIS_MODULE, + }, + .probe = tps6507x_i2c_probe, + .remove = tps6507x_i2c_remove, + .id_table = tps6507x_i2c_id, +}; + +static int __init tps6507x_i2c_init(void) +{ + return i2c_add_driver(&tps6507x_i2c_driver); +} +/* init early so consumer devices can complete system boot */ +subsys_initcall(tps6507x_i2c_init); + +static void __exit tps6507x_i2c_exit(void) +{ + i2c_del_driver(&tps6507x_i2c_driver); +} +module_exit(tps6507x_i2c_exit); + +MODULE_DESCRIPTION("TPS6507x chip family multi-function driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index ea44741fcd47..14b4576281c5 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -104,22 +103,67 @@ struct tps_info { const u16 *table; }; +static const struct tps_info tps6507x_pmic_regs[] = { + { + .name = "VDCDC1", + .min_uV = 725000, + .max_uV = 3300000, + .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), + .table = VDCDCx_VSEL_table, + }, + { + .name = "VDCDC2", + .min_uV = 725000, + .max_uV = 3300000, + .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), + .table = VDCDCx_VSEL_table, + }, + { + .name = "VDCDC3", + .min_uV = 725000, + .max_uV = 3300000, + .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), + .table = VDCDCx_VSEL_table, + }, + { + .name = "LDO1", + .min_uV = 1000000, + .max_uV = 3300000, + .table_len = ARRAY_SIZE(LDO1_VSEL_table), + .table = LDO1_VSEL_table, + }, + { + .name = "LDO2", + .min_uV = 725000, + .max_uV = 3300000, + .table_len = ARRAY_SIZE(LDO2_VSEL_table), + .table = LDO2_VSEL_table, + }, +}; + struct tps6507x_pmic { struct regulator_desc desc[TPS6507X_NUM_REGULATOR]; - struct i2c_client *client; + struct tps6507x_dev *mfd; struct regulator_dev *rdev[TPS6507X_NUM_REGULATOR]; const struct tps_info *info[TPS6507X_NUM_REGULATOR]; struct mutex io_lock; }; - static inline int tps6507x_pmic_read(struct tps6507x_pmic *tps, u8 reg) { - return i2c_smbus_read_byte_data(tps->client, reg); + u8 val; + int err; + + err = tps->mfd->read_dev(tps->mfd, reg, 1, &val); + + if (err) + return err; + + return val; } static inline int tps6507x_pmic_write(struct tps6507x_pmic *tps, u8 reg, u8 val) { - return i2c_smbus_write_byte_data(tps->client, reg, val); + return tps->mfd->write_dev(tps->mfd, reg, 1, &val); } static int tps6507x_pmic_set_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask) @@ -130,7 +174,7 @@ static int tps6507x_pmic_set_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask) data = tps6507x_pmic_read(tps, reg); if (data < 0) { - dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); + dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg); err = data; goto out; } @@ -138,7 +182,7 @@ static int tps6507x_pmic_set_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask) data |= mask; err = tps6507x_pmic_write(tps, reg, data); if (err) - dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); + dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg); out: mutex_unlock(&tps->io_lock); @@ -153,7 +197,7 @@ static int tps6507x_pmic_clear_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask) data = tps6507x_pmic_read(tps, reg); if (data < 0) { - dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); + dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg); err = data; goto out; } @@ -161,7 +205,7 @@ static int tps6507x_pmic_clear_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask) data &= ~mask; err = tps6507x_pmic_write(tps, reg, data); if (err) - dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); + dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg); out: mutex_unlock(&tps->io_lock); @@ -176,7 +220,7 @@ static int tps6507x_pmic_reg_read(struct tps6507x_pmic *tps, u8 reg) data = tps6507x_pmic_read(tps, reg); if (data < 0) - dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); + dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg); mutex_unlock(&tps->io_lock); return data; @@ -190,7 +234,7 @@ static int tps6507x_pmic_reg_write(struct tps6507x_pmic *tps, u8 reg, u8 val) err = tps6507x_pmic_write(tps, reg, val); if (err < 0) - dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); + dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg); mutex_unlock(&tps->io_lock); return err; @@ -483,11 +527,12 @@ static struct regulator_ops tps6507x_pmic_ldo_ops = { .list_voltage = tps6507x_pmic_ldo_list_voltage, }; -static int __devinit tps6507x_pmic_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static __devinit +int tps6507x_pmic_probe(struct platform_device *pdev) { + struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); static int desc_id; - const struct tps_info *info = (void *)id->driver_data; + const struct tps_info *info = &tps6507x_pmic_regs[0]; struct regulator_init_data *init_data; struct regulator_dev *rdev; struct tps6507x_pmic *tps; @@ -495,16 +540,12 @@ static int __devinit tps6507x_pmic_probe(struct i2c_client *client, int i; int error; - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA)) - return -EIO; - /** * tps_board points to pmic related constants * coming from the board-evm file. */ - tps_board = dev_get_platdata(&client->dev); + tps_board = dev_get_platdata(tps6507x_dev->dev); if (!tps_board) return -EINVAL; @@ -523,7 +564,7 @@ static int __devinit tps6507x_pmic_probe(struct i2c_client *client, mutex_init(&tps->io_lock); /* common for all regulators */ - tps->client = client; + tps->mfd = tps6507x_dev; for (i = 0; i < TPS6507X_NUM_REGULATOR; i++, info++, init_data++) { /* Register the regulators */ @@ -537,10 +578,11 @@ static int __devinit tps6507x_pmic_probe(struct i2c_client *client, tps->desc[i].owner = THIS_MODULE; rdev = regulator_register(&tps->desc[i], - &client->dev, init_data, tps); + tps6507x_dev->dev, init_data, tps); if (IS_ERR(rdev)) { - dev_err(&client->dev, "failed to register %s\n", - id->name); + dev_err(tps6507x_dev->dev, + "failed to register %s regulator\n", + pdev->name); error = PTR_ERR(rdev); goto fail; } @@ -549,7 +591,7 @@ static int __devinit tps6507x_pmic_probe(struct i2c_client *client, tps->rdev[i] = rdev; } - i2c_set_clientdata(client, tps); + tps6507x_dev->pmic = tps; return 0; @@ -567,14 +609,12 @@ fail: * * Unregister TPS driver as an i2c client device driver */ -static int __devexit tps6507x_pmic_remove(struct i2c_client *client) +static int __devexit tps6507x_pmic_remove(struct platform_device *pdev) { - struct tps6507x_pmic *tps = i2c_get_clientdata(client); + struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev); + struct tps6507x_pmic *tps = tps6507x_dev->pmic; int i; - /* clear the client data in i2c */ - i2c_set_clientdata(client, NULL); - for (i = 0; i < TPS6507X_NUM_REGULATOR; i++) regulator_unregister(tps->rdev[i]); @@ -583,59 +623,13 @@ static int __devexit tps6507x_pmic_remove(struct i2c_client *client) return 0; } -static const struct tps_info tps6507x_pmic_regs[] = { - { - .name = "VDCDC1", - .min_uV = 725000, - .max_uV = 3300000, - .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), - .table = VDCDCx_VSEL_table, - }, - { - .name = "VDCDC2", - .min_uV = 725000, - .max_uV = 3300000, - .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), - .table = VDCDCx_VSEL_table, - }, - { - .name = "VDCDC3", - .min_uV = 725000, - .max_uV = 3300000, - .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), - .table = VDCDCx_VSEL_table, - }, - { - .name = "LDO1", - .min_uV = 1000000, - .max_uV = 3300000, - .table_len = ARRAY_SIZE(LDO1_VSEL_table), - .table = LDO1_VSEL_table, - }, - { - .name = "LDO2", - .min_uV = 725000, - .max_uV = 3300000, - .table_len = ARRAY_SIZE(LDO2_VSEL_table), - .table = LDO2_VSEL_table, - }, -}; - -static const struct i2c_device_id tps6507x_pmic_id[] = { - {.name = "tps6507x", - .driver_data = (unsigned long) tps6507x_pmic_regs,}, - { }, -}; -MODULE_DEVICE_TABLE(i2c, tps6507x_pmic_id); - -static struct i2c_driver tps6507x_i2c_driver = { +static struct platform_driver tps6507x_pmic_driver = { .driver = { - .name = "tps6507x", + .name = "tps6507x-pmic", .owner = THIS_MODULE, }, .probe = tps6507x_pmic_probe, .remove = __devexit_p(tps6507x_pmic_remove), - .id_table = tps6507x_pmic_id, }; /** @@ -645,7 +639,7 @@ static struct i2c_driver tps6507x_i2c_driver = { */ static int __init tps6507x_pmic_init(void) { - return i2c_add_driver(&tps6507x_i2c_driver); + return platform_driver_register(&tps6507x_pmic_driver); } subsys_initcall(tps6507x_pmic_init); @@ -656,10 +650,11 @@ subsys_initcall(tps6507x_pmic_init); */ static void __exit tps6507x_pmic_cleanup(void) { - i2c_del_driver(&tps6507x_i2c_driver); + platform_driver_unregister(&tps6507x_pmic_driver); } module_exit(tps6507x_pmic_cleanup); MODULE_AUTHOR("Texas Instruments"); MODULE_DESCRIPTION("TPS6507x voltage regulator driver"); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:tps6507x-pmic"); diff --git a/include/linux/mfd/tps6507x.h b/include/linux/mfd/tps6507x.h index fd73af5fb95a..9543cb716428 100644 --- a/include/linux/mfd/tps6507x.h +++ b/include/linux/mfd/tps6507x.h @@ -131,6 +131,8 @@ /* VDCDC MASK */ #define TPS6507X_DEFDCDCX_DCDC_MASK 0X3F +#define TPS6507X_MAX_REGISTER 0X19 + /** * struct tps6507x_board - packages regulator and touchscreen init data * @tps6507x_regulator_data: regulator initialization values @@ -142,4 +144,24 @@ struct tps6507x_board { struct regulator_init_data *tps6507x_pmic_init_data; }; +/** + * struct tps6507x_dev - tps6507x sub-driver chip access routines + * @read_dev() - I2C register read function + * @write_dev() - I2C register write function + * + * Device data may be used to access the TPS6507x chip + */ + +struct tps6507x_dev { + struct device *dev; + struct i2c_client *i2c_client; + int (*read_dev)(struct tps6507x_dev *tps6507x, char reg, int size, + void *dest); + int (*write_dev)(struct tps6507x_dev *tps6507x, char reg, int size, + void *src); + + /* Client devices */ + struct tps6507x_pmic *pmic; +}; + #endif /* __LINUX_MFD_TPS6507X_H */ -- cgit v1.2.3 From 752599667048898b6969e06e4637f906b04ec752 Mon Sep 17 00:00:00 2001 From: Todd Fischer Date: Mon, 5 Apr 2010 17:53:12 -0600 Subject: input: Touchscreen driver for TPS6507x Add touch screen input driver for TPS6507x family of multi-function chips. Uses the TPS6507x MFD driver. No interrupt support due to testing limitations of current hardware. Signed-off-by: Todd Fischer Signed-off-by: Samuel Ortiz --- drivers/input/touchscreen/Kconfig | 13 ++ drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/tps6507x-ts.c | 400 ++++++++++++++++++++++++++++++++ drivers/mfd/tps6507x.c | 3 + include/linux/input/tps6507x-ts.h | 24 ++ include/linux/mfd/tps6507x.h | 2 + 6 files changed, 443 insertions(+) create mode 100644 drivers/input/touchscreen/tps6507x-ts.c create mode 100644 include/linux/input/tps6507x-ts.h (limited to 'drivers') diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index b9f58ca82fd1..6703c6b9800a 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -590,4 +590,17 @@ config TOUCHSCREEN_PCAP To compile this driver as a module, choose M here: the module will be called pcap_ts. + +config TOUCHSCREEN_TPS6507X + tristate "TPS6507x based touchscreens" + depends on I2C + help + Say Y here if you have a TPS6507x based touchscreen + controller. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called tps6507x_ts. + endif diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 8ad36eef90a2..497964a7a214 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -46,3 +46,4 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_ATMEL) += atmel-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o +obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c new file mode 100644 index 000000000000..5de80a1a730b --- /dev/null +++ b/drivers/input/touchscreen/tps6507x-ts.c @@ -0,0 +1,400 @@ +/* + * drivers/input/touchscreen/tps6507x_ts.c + * + * Touchscreen driver for the tps6507x chip. + * + * Copyright (c) 2009 RidgeRun (todd.fischer@ridgerun.com) + * + * Credits: + * + * Using code from tsc2007, MtekVision Co., Ltd. + * + * For licencing details see kernel-base/COPYING + * + * TPS65070, TPS65073, TPS650731, and TPS650732 support + * 10 bit touch screen interface. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define TSC_DEFAULT_POLL_PERIOD 30 /* ms */ +#define TPS_DEFAULT_MIN_PRESSURE 0x30 +#define MAX_10BIT ((1 << 10) - 1) + +#define TPS6507X_ADCONFIG_CONVERT_TS (TPS6507X_ADCONFIG_AD_ENABLE | \ + TPS6507X_ADCONFIG_START_CONVERSION | \ + TPS6507X_ADCONFIG_INPUT_REAL_TSC) +#define TPS6507X_ADCONFIG_POWER_DOWN_TS (TPS6507X_ADCONFIG_INPUT_REAL_TSC) + +struct ts_event { + u16 x; + u16 y; + u16 pressure; +}; + +struct tps6507x_ts { + struct input_dev *input_dev; + struct device *dev; + char phys[32]; + struct workqueue_struct *wq; + struct delayed_work work; + unsigned polling; /* polling is active */ + struct ts_event tc; + struct tps6507x_dev *mfd; + u16 model; + unsigned pendown; + int irq; + void (*clear_penirq)(void); + unsigned long poll_period; /* ms */ + u16 min_pressure; + int vref; /* non-zero to leave vref on */ +}; + +static int tps6507x_read_u8(struct tps6507x_ts *tsc, u8 reg, u8 *data) +{ + int err; + + err = tsc->mfd->read_dev(tsc->mfd, reg, 1, data); + + if (err) + return err; + + return 0; +} + +static int tps6507x_write_u8(struct tps6507x_ts *tsc, u8 reg, u8 data) +{ + return tsc->mfd->write_dev(tsc->mfd, reg, 1, &data); +} + +static s32 tps6507x_adc_conversion(struct tps6507x_ts *tsc, + u8 tsc_mode, u16 *value) +{ + s32 ret; + u8 adc_status; + u8 result; + + /* Route input signal to A/D converter */ + + ret = tps6507x_write_u8(tsc, TPS6507X_REG_TSCMODE, tsc_mode); + if (ret) { + dev_err(tsc->dev, "TSC mode read failed\n"); + goto err; + } + + /* Start A/D conversion */ + + ret = tps6507x_write_u8(tsc, TPS6507X_REG_ADCONFIG, + TPS6507X_ADCONFIG_CONVERT_TS); + if (ret) { + dev_err(tsc->dev, "ADC config write failed\n"); + return ret; + } + + do { + ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADCONFIG, + &adc_status); + if (ret) { + dev_err(tsc->dev, "ADC config read failed\n"); + goto err; + } + } while (adc_status & TPS6507X_ADCONFIG_START_CONVERSION); + + ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADRESULT_2, &result); + if (ret) { + dev_err(tsc->dev, "ADC result 2 read failed\n"); + goto err; + } + + *value = (result & TPS6507X_REG_ADRESULT_2_MASK) << 8; + + ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADRESULT_1, &result); + if (ret) { + dev_err(tsc->dev, "ADC result 1 read failed\n"); + goto err; + } + + *value |= result; + + dev_dbg(tsc->dev, "TSC channel %d = 0x%X\n", tsc_mode, *value); + +err: + return ret; +} + +/* Need to call tps6507x_adc_standby() after using A/D converter for the + * touch screen interrupt to work properly. + */ + +static s32 tps6507x_adc_standby(struct tps6507x_ts *tsc) +{ + s32 ret; + s32 loops = 0; + u8 val; + + ret = tps6507x_write_u8(tsc, TPS6507X_REG_ADCONFIG, + TPS6507X_ADCONFIG_INPUT_TSC); + if (ret) + return ret; + + ret = tps6507x_write_u8(tsc, TPS6507X_REG_TSCMODE, + TPS6507X_TSCMODE_STANDBY); + if (ret) + return ret; + + ret = tps6507x_read_u8(tsc, TPS6507X_REG_INT, &val); + if (ret) + return ret; + + while (val & TPS6507X_REG_TSC_INT) { + mdelay(10); + ret = tps6507x_read_u8(tsc, TPS6507X_REG_INT, &val); + if (ret) + return ret; + loops++; + } + + return ret; +} + +static void tps6507x_ts_handler(struct work_struct *work) +{ + struct tps6507x_ts *tsc = container_of(work, + struct tps6507x_ts, work.work); + struct input_dev *input_dev = tsc->input_dev; + int pendown; + int schd; + int poll = 0; + s32 ret; + + ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_PRESSURE, + &tsc->tc.pressure); + if (ret) + goto done; + + pendown = tsc->tc.pressure > tsc->min_pressure; + + if (unlikely(!pendown && tsc->pendown)) { + dev_dbg(tsc->dev, "UP\n"); + input_report_key(input_dev, BTN_TOUCH, 0); + input_report_abs(input_dev, ABS_PRESSURE, 0); + input_sync(input_dev); + tsc->pendown = 0; + } + + if (pendown) { + + if (!tsc->pendown) { + dev_dbg(tsc->dev, "DOWN\n"); + input_report_key(input_dev, BTN_TOUCH, 1); + } else + dev_dbg(tsc->dev, "still down\n"); + + ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_X_POSITION, + &tsc->tc.x); + if (ret) + goto done; + + ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_Y_POSITION, + &tsc->tc.y); + if (ret) + goto done; + + input_report_abs(input_dev, ABS_X, tsc->tc.x); + input_report_abs(input_dev, ABS_Y, tsc->tc.y); + input_report_abs(input_dev, ABS_PRESSURE, tsc->tc.pressure); + input_sync(input_dev); + tsc->pendown = 1; + poll = 1; + } + +done: + /* always poll if not using interrupts */ + poll = 1; + + if (poll) { + schd = queue_delayed_work(tsc->wq, &tsc->work, + tsc->poll_period * HZ / 1000); + if (schd) + tsc->polling = 1; + else { + tsc->polling = 0; + dev_err(tsc->dev, "re-schedule failed"); + } + } else + tsc->polling = 0; + + ret = tps6507x_adc_standby(tsc); +} + +static int tps6507x_ts_probe(struct platform_device *pdev) +{ + int error; + struct tps6507x_ts *tsc; + struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); + struct touchscreen_init_data *init_data; + struct input_dev *input_dev; + struct tps6507x_board *tps_board; + int schd; + + /** + * tps_board points to pmic related constants + * coming from the board-evm file. + */ + + tps_board = (struct tps6507x_board *)tps6507x_dev->dev->platform_data; + + if (!tps_board) { + dev_err(tps6507x_dev->dev, + "Could not find tps6507x platform data\n"); + return -EIO; + } + + /** + * init_data points to array of regulator_init structures + * coming from the board-evm file. + */ + + init_data = tps_board->tps6507x_ts_init_data; + + tsc = kzalloc(sizeof(struct tps6507x_ts), GFP_KERNEL); + if (!tsc) { + dev_err(tps6507x_dev->dev, "failed to allocate driver data\n"); + error = -ENOMEM; + goto err0; + } + + tps6507x_dev->ts = tsc; + tsc->mfd = tps6507x_dev; + tsc->dev = tps6507x_dev->dev; + input_dev = input_allocate_device(); + if (!input_dev) { + dev_err(tsc->dev, "Failed to allocate input device.\n"); + error = -ENOMEM; + goto err1; + } + + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + + input_set_abs_params(input_dev, ABS_X, 0, MAX_10BIT, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 0, MAX_10BIT, 0, 0); + input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_10BIT, 0, 0); + + input_dev->name = "TPS6507x Touchscreen"; + input_dev->id.bustype = BUS_I2C; + input_dev->dev.parent = tsc->dev; + + snprintf(tsc->phys, sizeof(tsc->phys), + "%s/input0", dev_name(tsc->dev)); + input_dev->phys = tsc->phys; + + dev_dbg(tsc->dev, "device: %s\n", input_dev->phys); + + input_set_drvdata(input_dev, tsc); + + tsc->input_dev = input_dev; + + INIT_DELAYED_WORK(&tsc->work, tps6507x_ts_handler); + tsc->wq = create_workqueue("TPS6507x Touchscreen"); + + if (init_data) { + tsc->poll_period = init_data->poll_period; + tsc->vref = init_data->vref; + tsc->min_pressure = init_data->min_pressure; + input_dev->id.vendor = init_data->vendor; + input_dev->id.product = init_data->product; + input_dev->id.version = init_data->version; + } else { + tsc->poll_period = TSC_DEFAULT_POLL_PERIOD; + tsc->min_pressure = TPS_DEFAULT_MIN_PRESSURE; + } + + error = tps6507x_adc_standby(tsc); + if (error) + goto err2; + + error = input_register_device(input_dev); + if (error) + goto err2; + + schd = queue_delayed_work(tsc->wq, &tsc->work, + tsc->poll_period * HZ / 1000); + + if (schd) + tsc->polling = 1; + else { + tsc->polling = 0; + dev_err(tsc->dev, "schedule failed"); + goto err2; + } + + return 0; + +err2: + cancel_delayed_work(&tsc->work); + flush_workqueue(tsc->wq); + destroy_workqueue(tsc->wq); + tsc->wq = 0; + input_free_device(input_dev); +err1: + kfree(tsc); + tps6507x_dev->ts = NULL; +err0: + return error; +} + +static int __devexit tps6507x_ts_remove(struct platform_device *pdev) +{ + struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev); + struct tps6507x_ts *tsc = tps6507x_dev->ts; + struct input_dev *input_dev = tsc->input_dev; + + if (!tsc) + return 0; + + cancel_delayed_work(&tsc->work); + flush_workqueue(tsc->wq); + destroy_workqueue(tsc->wq); + tsc->wq = 0; + + input_free_device(input_dev); + + tps6507x_dev->ts = NULL; + kfree(tsc); + + return 0; +} + +static struct platform_driver tps6507x_ts_driver = { + .driver = { + .name = "tps6507x-ts", + .owner = THIS_MODULE, + }, + .probe = tps6507x_ts_probe, + .remove = __devexit_p(tps6507x_ts_remove), +}; + +static int __init tps6507x_ts_init(void) +{ + return platform_driver_register(&tps6507x_ts_driver); +} +module_init(tps6507x_ts_init); + +static void __exit tps6507x_ts_exit(void) +{ + platform_driver_unregister(&tps6507x_ts_driver); +} +module_exit(tps6507x_ts_exit); + +MODULE_AUTHOR("Todd Fischer "); +MODULE_DESCRIPTION("TPS6507x - TouchScreen driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:tps6507x-tsc"); diff --git a/drivers/mfd/tps6507x.c b/drivers/mfd/tps6507x.c index c59f74570b3b..d859dffed39f 100644 --- a/drivers/mfd/tps6507x.c +++ b/drivers/mfd/tps6507x.c @@ -26,6 +26,9 @@ static struct mfd_cell tps6507x_devs[] = { { .name = "tps6507x-pmic", }, + { + .name = "tps6507x-ts", + }, }; diff --git a/include/linux/input/tps6507x-ts.h b/include/linux/input/tps6507x-ts.h new file mode 100644 index 000000000000..ab1440313924 --- /dev/null +++ b/include/linux/input/tps6507x-ts.h @@ -0,0 +1,24 @@ +/* linux/i2c/tps6507x-ts.h + * + * Functions to access TPS65070 touch screen chip. + * + * Copyright (c) 2009 RidgeRun (todd.fischer@ridgerun.com) + * + * + * For licencing details see kernel-base/COPYING + */ + +#ifndef __LINUX_I2C_TPS6507X_TS_H +#define __LINUX_I2C_TPS6507X_TS_H + +/* Board specific touch screen initial values */ +struct touchscreen_init_data { + int poll_period; /* ms */ + int vref; /* non-zero to leave vref on */ + __u16 min_pressure; /* min reading to be treated as a touch */ + __u16 vendor; + __u16 product; + __u16 version; +}; + +#endif /* __LINUX_I2C_TPS6507X_TS_H */ diff --git a/include/linux/mfd/tps6507x.h b/include/linux/mfd/tps6507x.h index 9543cb716428..c923e4864f55 100644 --- a/include/linux/mfd/tps6507x.h +++ b/include/linux/mfd/tps6507x.h @@ -142,6 +142,7 @@ struct tps6507x_board { struct regulator_init_data *tps6507x_pmic_init_data; + struct touchscreen_init_data *tps6507x_ts_init_data; }; /** @@ -162,6 +163,7 @@ struct tps6507x_dev { /* Client devices */ struct tps6507x_pmic *pmic; + struct tps6507x_ts *ts; }; #endif /* __LINUX_MFD_TPS6507X_H */ -- cgit v1.2.3 From 0d7e0e399d7fcd5ddc3313a1aa2135fab3226d8f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 5 Apr 2010 16:14:17 +0100 Subject: mfd: Initialise WM831x IRQ masks on chip even if interrupts not in use Ensure that the hardware has interrupts masked if we are not using the interrupt controller on the WM831x by initialising the masks before we check for the setup data required for the IRQ line. This avoids signalling an unused IRQ line and improves the robustness of checks that the IRQ is in use. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/wm831x-irq.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c index ec10004200c9..7dabe4dbd373 100644 --- a/drivers/mfd/wm831x-irq.c +++ b/drivers/mfd/wm831x-irq.c @@ -490,6 +490,14 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq) mutex_init(&wm831x->irq_lock); + /* Mask the individual interrupt sources */ + for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) { + wm831x->irq_masks_cur[i] = 0xffff; + wm831x->irq_masks_cache[i] = 0xffff; + wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1_MASK + i, + 0xffff); + } + if (!irq) { dev_warn(wm831x->dev, "No interrupt specified - functionality limited\n"); @@ -505,14 +513,6 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq) wm831x->irq = irq; wm831x->irq_base = pdata->irq_base; - /* Mask the individual interrupt sources */ - for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) { - wm831x->irq_masks_cur[i] = 0xffff; - wm831x->irq_masks_cache[i] = 0xffff; - wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1_MASK + i, - 0xffff); - } - /* Register them with genirq */ for (cur_irq = wm831x->irq_base; cur_irq < ARRAY_SIZE(wm831x_irqs) + wm831x->irq_base; -- cgit v1.2.3 From b03b4d7cdd8f18395494478634707c6f132080d6 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 8 Apr 2010 10:02:39 +0200 Subject: mfd: Ensure WM831x charger interrupts are acknowledged when suspending The charger interrupts on the WM831x are unconditionally a wake source for the system. If the power driver is not able to monitor them (for example, due to the IRQ line not having been wired up on the system) then any charger interrupt will prevent the system suspending for any meaningful amount of time since nothing will ack them. Avoid this issue by manually acknowledging these interrupts when we suspend the WM831x core device if they are masked. If software is actually using the interrupts then they will be unmasked and this change will have no effect. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/wm831x-core.c | 47 +++++++++++++++++++++++++++++++++++++++++ include/linux/mfd/wm831x/core.h | 5 +++-- 2 files changed, 50 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index da00ca9e0c71..1a968f34d679 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -1494,6 +1494,7 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) case WM8310: parent = WM8310; wm831x->num_gpio = 16; + wm831x->charger_irq_wake = 1; if (rev > 0) { wm831x->has_gpio_ena = 1; wm831x->has_cs_sts = 1; @@ -1505,6 +1506,7 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) case WM8311: parent = WM8311; wm831x->num_gpio = 16; + wm831x->charger_irq_wake = 1; if (rev > 0) { wm831x->has_gpio_ena = 1; wm831x->has_cs_sts = 1; @@ -1516,6 +1518,7 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) case WM8312: parent = WM8312; wm831x->num_gpio = 16; + wm831x->charger_irq_wake = 1; if (rev > 0) { wm831x->has_gpio_ena = 1; wm831x->has_cs_sts = 1; @@ -1654,6 +1657,42 @@ static void wm831x_device_exit(struct wm831x *wm831x) kfree(wm831x); } +static int wm831x_device_suspend(struct wm831x *wm831x) +{ + int reg, mask; + + /* If the charger IRQs are a wake source then make sure we ack + * them even if they're not actively being used (eg, no power + * driver or no IRQ line wired up) then acknowledge the + * interrupts otherwise suspend won't last very long. + */ + if (wm831x->charger_irq_wake) { + reg = wm831x_reg_read(wm831x, WM831X_INTERRUPT_STATUS_2_MASK); + + mask = WM831X_CHG_BATT_HOT_EINT | + WM831X_CHG_BATT_COLD_EINT | + WM831X_CHG_BATT_FAIL_EINT | + WM831X_CHG_OV_EINT | WM831X_CHG_END_EINT | + WM831X_CHG_TO_EINT | WM831X_CHG_MODE_EINT | + WM831X_CHG_START_EINT; + + /* If any of the interrupts are masked read the statuses */ + if (reg & mask) + reg = wm831x_reg_read(wm831x, + WM831X_INTERRUPT_STATUS_2); + + if (reg & mask) { + dev_info(wm831x->dev, + "Acknowledging masked charger IRQs: %x\n", + reg & mask); + wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_2, + reg & mask); + } + } + + return 0; +} + static int wm831x_i2c_read_device(struct wm831x *wm831x, unsigned short reg, int bytes, void *dest) { @@ -1728,6 +1767,13 @@ static int wm831x_i2c_remove(struct i2c_client *i2c) return 0; } +static int wm831x_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg) +{ + struct wm831x *wm831x = i2c_get_clientdata(i2c); + + return wm831x_device_suspend(wm831x); +} + static const struct i2c_device_id wm831x_i2c_id[] = { { "wm8310", WM8310 }, { "wm8311", WM8311 }, @@ -1745,6 +1791,7 @@ static struct i2c_driver wm831x_i2c_driver = { }, .probe = wm831x_i2c_probe, .remove = wm831x_i2c_remove, + .suspend = wm831x_i2c_suspend, .id_table = wm831x_i2c_id, }; diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h index 5915f6e3d9ab..eb5bd4e0e03c 100644 --- a/include/linux/mfd/wm831x/core.h +++ b/include/linux/mfd/wm831x/core.h @@ -256,8 +256,9 @@ struct wm831x { int irq_masks_cache[WM831X_NUM_IRQ_REGS]; /* Cached hardware value */ /* Chip revision based flags */ - unsigned has_gpio_ena:1; /* Has GPIO enable bit */ - unsigned has_cs_sts:1; /* Has current sink status bit */ + unsigned has_gpio_ena:1; /* Has GPIO enable bit */ + unsigned has_cs_sts:1; /* Has current sink status bit */ + unsigned charger_irq_wake:1; /* Are charger IRQs a wake source? */ int num_gpio; -- cgit v1.2.3 From fffba64ca37e8f06020f89e878f0d76a8e121c4e Mon Sep 17 00:00:00 2001 From: Phil Carmody Date: Fri, 16 Apr 2010 15:00:09 +0300 Subject: mfd: Fix error in wm8400 reg cache access check Accessing num_reg elements in the interval [reg .. reg+num_regs) is permitted if (reg+numregs <= array size), so barf when that excluded upper bound is > array size. The prior -1 would give access to one too many elements. Signed-off-by: Phil Carmody Signed-off-by: Samuel Ortiz --- drivers/mfd/wm8400-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c index 865ce013a821..e08aafa663dc 100644 --- a/drivers/mfd/wm8400-core.c +++ b/drivers/mfd/wm8400-core.c @@ -118,7 +118,7 @@ static int wm8400_read(struct wm8400 *wm8400, u8 reg, int num_regs, u16 *dest) { int i, ret = 0; - BUG_ON(reg + num_regs - 1 > ARRAY_SIZE(wm8400->reg_cache)); + BUG_ON(reg + num_regs > ARRAY_SIZE(wm8400->reg_cache)); /* If there are any volatile reads then read back the entire block */ for (i = reg; i < reg + num_regs; i++) @@ -144,7 +144,7 @@ static int wm8400_write(struct wm8400 *wm8400, u8 reg, int num_regs, { int ret, i; - BUG_ON(reg + num_regs - 1 > ARRAY_SIZE(wm8400->reg_cache)); + BUG_ON(reg + num_regs > ARRAY_SIZE(wm8400->reg_cache)); for (i = 0; i < num_regs; i++) { BUG_ON(!reg_data[reg + i].writable); -- cgit v1.2.3 From e47a3bbe4ffd4afe2b24c912598aee7ea1ecf738 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Wed, 21 Apr 2010 21:06:05 +0530 Subject: mfd: Remove incorrect wm8350 kfree The i2c_client received in probe() should not be kfree()'d. Signed-off-by: Rabin Vincent Acked-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/wm8350-i2c.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/wm8350-i2c.c b/drivers/mfd/wm8350-i2c.c index aa3ba0974ee5..7795af4b1fe1 100644 --- a/drivers/mfd/wm8350-i2c.c +++ b/drivers/mfd/wm8350-i2c.c @@ -64,10 +64,8 @@ static int wm8350_i2c_probe(struct i2c_client *i2c, int ret = 0; wm8350 = kzalloc(sizeof(struct wm8350), GFP_KERNEL); - if (wm8350 == NULL) { - kfree(i2c); + if (wm8350 == NULL) return -ENOMEM; - } i2c_set_clientdata(i2c, wm8350); wm8350->dev = &i2c->dev; -- cgit v1.2.3 From 68e488d965a9055c63c0eac4ad1e6568b07e8ee1 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Tue, 27 Apr 2010 14:55:28 -0400 Subject: mfd: Delay to mask tsc irq in max8925 There're two IRQ pins output from MAX8925. One is PMIC interrupt, the other is TSC interrupt. But they're sharing one irq chip. After initializing MAX8925 interrupts, unexpected TSC interrupt may occur and it can't be cleared if touch driver isn't loaded. Now move the operation of masking TSC interrupt behind requesting PMIC interrupt. If touch driver isn't loaded, this interrupt is always masked. Signed-off-by: Haojian Zhuang Signed-off-by: Samuel Ortiz --- drivers/mfd/max8925-core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index 85d63c04749b..f621bcea3d02 100644 --- a/drivers/mfd/max8925-core.c +++ b/drivers/mfd/max8925-core.c @@ -508,7 +508,7 @@ static int max8925_irq_init(struct max8925_chip *chip, int irq, max8925_reg_read(chip->i2c, MAX8925_ON_OFF_IRQ2); max8925_reg_read(chip->rtc, MAX8925_RTC_IRQ); max8925_reg_read(chip->adc, MAX8925_TSC_IRQ); - /* mask all interrupts */ + /* mask all interrupts except for TSC */ max8925_reg_write(chip->rtc, MAX8925_ALARM0_CNTL, 0); max8925_reg_write(chip->rtc, MAX8925_ALARM1_CNTL, 0); max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ1_MASK, 0xff); @@ -516,7 +516,6 @@ static int max8925_irq_init(struct max8925_chip *chip, int irq, max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ1_MASK, 0xff); max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ2_MASK, 0xff); max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, 0xff); - max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, 0xff); mutex_init(&chip->irq_lock); chip->core_irq = irq; @@ -547,7 +546,11 @@ static int max8925_irq_init(struct max8925_chip *chip, int irq, dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret); chip->core_irq = 0; } + tsc_irq: + /* mask TSC interrupt */ + max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, 0x0f); + if (!pdata->tsc_irq) { dev_warn(chip->dev, "No interrupt support on TSC IRQ\n"); return 0; -- cgit v1.2.3 From b4ecd326b789f1029c5d4a5239d9bd12ecac353d Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 10 May 2010 23:39:47 +0200 Subject: mfd: Add Toshiba's TC35892 MFD core The TC35892 I/O Expander provides 24 GPIOs, a keypad controller, timers, and a rotator wheel interface. This patch adds the MFD core. Acked-by: Linus Walleij Signed-off-by: Rabin Vincent Signed-off-by: Samuel Ortiz --- drivers/mfd/Kconfig | 11 ++ drivers/mfd/Makefile | 1 + drivers/mfd/tc35892.c | 347 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/mfd/tc35892.h | 132 +++++++++++++++++ 4 files changed, 491 insertions(+) create mode 100644 drivers/mfd/tc35892.c create mode 100644 include/linux/mfd/tc35892.h (limited to 'drivers') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 40e0a0a7df5b..614fa7b8a054 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -171,6 +171,17 @@ config TWL4030_CODEC select MFD_CORE default n +config MFD_TC35892 + bool "Support Toshiba TC35892" + depends on I2C=y && GENERIC_HARDIRQS + select MFD_CORE + help + Support for the Toshiba TC35892 I/O Expander. + + This driver provides common support for accessing the device, + additional drivers must be enabled in order to use the + functionality of the device. + config MFD_TMIO bool default n diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index abf6f1766dcd..5eb79794d5a5 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o +obj-$(CONFIG_MFD_TC35892) += tc35892.o obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o tmio_core.o diff --git a/drivers/mfd/tc35892.c b/drivers/mfd/tc35892.c new file mode 100644 index 000000000000..715f095dd7a6 --- /dev/null +++ b/drivers/mfd/tc35892.c @@ -0,0 +1,347 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License Terms: GNU General Public License, version 2 + * Author: Hanumath Prasad for ST-Ericsson + * Author: Rabin Vincent for ST-Ericsson + */ + +#include +#include +#include +#include +#include +#include +#include + +/** + * tc35892_reg_read() - read a single TC35892 register + * @tc35892: Device to read from + * @reg: Register to read + */ +int tc35892_reg_read(struct tc35892 *tc35892, u8 reg) +{ + int ret; + + ret = i2c_smbus_read_byte_data(tc35892->i2c, reg); + if (ret < 0) + dev_err(tc35892->dev, "failed to read reg %#x: %d\n", + reg, ret); + + return ret; +} +EXPORT_SYMBOL_GPL(tc35892_reg_read); + +/** + * tc35892_reg_read() - write a single TC35892 register + * @tc35892: Device to write to + * @reg: Register to read + * @data: Value to write + */ +int tc35892_reg_write(struct tc35892 *tc35892, u8 reg, u8 data) +{ + int ret; + + ret = i2c_smbus_write_byte_data(tc35892->i2c, reg, data); + if (ret < 0) + dev_err(tc35892->dev, "failed to write reg %#x: %d\n", + reg, ret); + + return ret; +} +EXPORT_SYMBOL_GPL(tc35892_reg_write); + +/** + * tc35892_block_read() - read multiple TC35892 registers + * @tc35892: Device to read from + * @reg: First register + * @length: Number of registers + * @values: Buffer to write to + */ +int tc35892_block_read(struct tc35892 *tc35892, u8 reg, u8 length, u8 *values) +{ + int ret; + + ret = i2c_smbus_read_i2c_block_data(tc35892->i2c, reg, length, values); + if (ret < 0) + dev_err(tc35892->dev, "failed to read regs %#x: %d\n", + reg, ret); + + return ret; +} +EXPORT_SYMBOL_GPL(tc35892_block_read); + +/** + * tc35892_block_write() - write multiple TC35892 registers + * @tc35892: Device to write to + * @reg: First register + * @length: Number of registers + * @values: Values to write + */ +int tc35892_block_write(struct tc35892 *tc35892, u8 reg, u8 length, + const u8 *values) +{ + int ret; + + ret = i2c_smbus_write_i2c_block_data(tc35892->i2c, reg, length, + values); + if (ret < 0) + dev_err(tc35892->dev, "failed to write regs %#x: %d\n", + reg, ret); + + return ret; +} +EXPORT_SYMBOL_GPL(tc35892_block_write); + +/** + * tc35892_set_bits() - set the value of a bitfield in a TC35892 register + * @tc35892: Device to write to + * @reg: Register to write + * @mask: Mask of bits to set + * @values: Value to set + */ +int tc35892_set_bits(struct tc35892 *tc35892, u8 reg, u8 mask, u8 val) +{ + int ret; + + mutex_lock(&tc35892->lock); + + ret = tc35892_reg_read(tc35892, reg); + if (ret < 0) + goto out; + + ret &= ~mask; + ret |= val; + + ret = tc35892_reg_write(tc35892, reg, ret); + +out: + mutex_unlock(&tc35892->lock); + return ret; +} +EXPORT_SYMBOL_GPL(tc35892_set_bits); + +static struct resource gpio_resources[] = { + { + .start = TC35892_INT_GPIIRQ, + .end = TC35892_INT_GPIIRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct mfd_cell tc35892_devs[] = { + { + .name = "tc35892-gpio", + .num_resources = ARRAY_SIZE(gpio_resources), + .resources = &gpio_resources[0], + }, +}; + +static irqreturn_t tc35892_irq(int irq, void *data) +{ + struct tc35892 *tc35892 = data; + int status; + + status = tc35892_reg_read(tc35892, TC35892_IRQST); + if (status < 0) + return IRQ_NONE; + + while (status) { + int bit = __ffs(status); + + handle_nested_irq(tc35892->irq_base + bit); + status &= ~(1 << bit); + } + + /* + * A dummy read or write (to any register) appears to be necessary to + * have the last interrupt clear (for example, GPIO IC write) take + * effect. + */ + tc35892_reg_read(tc35892, TC35892_IRQST); + + return IRQ_HANDLED; +} + +static void tc35892_irq_dummy(unsigned int irq) +{ + /* No mask/unmask at this level */ +} + +static struct irq_chip tc35892_irq_chip = { + .name = "tc35892", + .mask = tc35892_irq_dummy, + .unmask = tc35892_irq_dummy, +}; + +static int tc35892_irq_init(struct tc35892 *tc35892) +{ + int base = tc35892->irq_base; + int irq; + + for (irq = base; irq < base + TC35892_NR_INTERNAL_IRQS; irq++) { + set_irq_chip_data(irq, tc35892); + set_irq_chip_and_handler(irq, &tc35892_irq_chip, + handle_edge_irq); + set_irq_nested_thread(irq, 1); +#ifdef CONFIG_ARM + set_irq_flags(irq, IRQF_VALID); +#else + set_irq_noprobe(irq); +#endif + } + + return 0; +} + +static void tc35892_irq_remove(struct tc35892 *tc35892) +{ + int base = tc35892->irq_base; + int irq; + + for (irq = base; irq < base + TC35892_NR_INTERNAL_IRQS; irq++) { +#ifdef CONFIG_ARM + set_irq_flags(irq, 0); +#endif + set_irq_chip_and_handler(irq, NULL, NULL); + set_irq_chip_data(irq, NULL); + } +} + +static int tc35892_chip_init(struct tc35892 *tc35892) +{ + int manf, ver, ret; + + manf = tc35892_reg_read(tc35892, TC35892_MANFCODE); + if (manf < 0) + return manf; + + ver = tc35892_reg_read(tc35892, TC35892_VERSION); + if (ver < 0) + return ver; + + if (manf != TC35892_MANFCODE_MAGIC) { + dev_err(tc35892->dev, "unknown manufacturer: %#x\n", manf); + return -EINVAL; + } + + dev_info(tc35892->dev, "manufacturer: %#x, version: %#x\n", manf, ver); + + /* Put everything except the IRQ module into reset */ + ret = tc35892_reg_write(tc35892, TC35892_RSTCTRL, + TC35892_RSTCTRL_TIMRST + | TC35892_RSTCTRL_ROTRST + | TC35892_RSTCTRL_KBDRST + | TC35892_RSTCTRL_GPIRST); + if (ret < 0) + return ret; + + /* Clear the reset interrupt. */ + return tc35892_reg_write(tc35892, TC35892_RSTINTCLR, 0x1); +} + +static int __devinit tc35892_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct tc35892_platform_data *pdata = i2c->dev.platform_data; + struct tc35892 *tc35892; + int ret; + + if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA + | I2C_FUNC_SMBUS_I2C_BLOCK)) + return -EIO; + + tc35892 = kzalloc(sizeof(struct tc35892), GFP_KERNEL); + if (!tc35892) + return -ENOMEM; + + mutex_init(&tc35892->lock); + + tc35892->dev = &i2c->dev; + tc35892->i2c = i2c; + tc35892->pdata = pdata; + tc35892->irq_base = pdata->irq_base; + tc35892->num_gpio = id->driver_data; + + i2c_set_clientdata(i2c, tc35892); + + ret = tc35892_chip_init(tc35892); + if (ret) + goto out_free; + + ret = tc35892_irq_init(tc35892); + if (ret) + goto out_free; + + ret = request_threaded_irq(tc35892->i2c->irq, NULL, tc35892_irq, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + "tc35892", tc35892); + if (ret) { + dev_err(tc35892->dev, "failed to request IRQ: %d\n", ret); + goto out_removeirq; + } + + ret = mfd_add_devices(tc35892->dev, -1, tc35892_devs, + ARRAY_SIZE(tc35892_devs), NULL, + tc35892->irq_base); + if (ret) { + dev_err(tc35892->dev, "failed to add children\n"); + goto out_freeirq; + } + + return 0; + +out_freeirq: + free_irq(tc35892->i2c->irq, tc35892); +out_removeirq: + tc35892_irq_remove(tc35892); +out_free: + i2c_set_clientdata(i2c, NULL); + kfree(tc35892); + return ret; +} + +static int __devexit tc35892_remove(struct i2c_client *client) +{ + struct tc35892 *tc35892 = i2c_get_clientdata(client); + + mfd_remove_devices(tc35892->dev); + + free_irq(tc35892->i2c->irq, tc35892); + tc35892_irq_remove(tc35892); + + i2c_set_clientdata(client, NULL); + kfree(tc35892); + + return 0; +} + +static const struct i2c_device_id tc35892_id[] = { + { "tc35892", 24 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, tc35892_id); + +static struct i2c_driver tc35892_driver = { + .driver.name = "tc35892", + .driver.owner = THIS_MODULE, + .probe = tc35892_probe, + .remove = __devexit_p(tc35892_remove), + .id_table = tc35892_id, +}; + +static int __init tc35892_init(void) +{ + return i2c_add_driver(&tc35892_driver); +} +subsys_initcall(tc35892_init); + +static void __exit tc35892_exit(void) +{ + i2c_del_driver(&tc35892_driver); +} +module_exit(tc35892_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("TC35892 MFD core driver"); +MODULE_AUTHOR("Hanumath Prasad, Rabin Vincent"); diff --git a/include/linux/mfd/tc35892.h b/include/linux/mfd/tc35892.h new file mode 100644 index 000000000000..e47f770d3068 --- /dev/null +++ b/include/linux/mfd/tc35892.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License Terms: GNU General Public License, version 2 + */ + +#ifndef __LINUX_MFD_TC35892_H +#define __LINUX_MFD_TC35892_H + +#include + +#define TC35892_RSTCTRL_IRQRST (1 << 4) +#define TC35892_RSTCTRL_TIMRST (1 << 3) +#define TC35892_RSTCTRL_ROTRST (1 << 2) +#define TC35892_RSTCTRL_KBDRST (1 << 1) +#define TC35892_RSTCTRL_GPIRST (1 << 0) + +#define TC35892_IRQST 0x91 + +#define TC35892_MANFCODE_MAGIC 0x03 +#define TC35892_MANFCODE 0x80 +#define TC35892_VERSION 0x81 +#define TC35892_IOCFG 0xA7 + +#define TC35892_CLKMODE 0x88 +#define TC35892_CLKCFG 0x89 +#define TC35892_CLKEN 0x8A + +#define TC35892_RSTCTRL 0x82 +#define TC35892_EXTRSTN 0x83 +#define TC35892_RSTINTCLR 0x84 + +#define TC35892_GPIOIS0 0xC9 +#define TC35892_GPIOIS1 0xCA +#define TC35892_GPIOIS2 0xCB +#define TC35892_GPIOIBE0 0xCC +#define TC35892_GPIOIBE1 0xCD +#define TC35892_GPIOIBE2 0xCE +#define TC35892_GPIOIEV0 0xCF +#define TC35892_GPIOIEV1 0xD0 +#define TC35892_GPIOIEV2 0xD1 +#define TC35892_GPIOIE0 0xD2 +#define TC35892_GPIOIE1 0xD3 +#define TC35892_GPIOIE2 0xD4 +#define TC35892_GPIORIS0 0xD6 +#define TC35892_GPIORIS1 0xD7 +#define TC35892_GPIORIS2 0xD8 +#define TC35892_GPIOMIS0 0xD9 +#define TC35892_GPIOMIS1 0xDA +#define TC35892_GPIOMIS2 0xDB +#define TC35892_GPIOIC0 0xDC +#define TC35892_GPIOIC1 0xDD +#define TC35892_GPIOIC2 0xDE + +#define TC35892_GPIODATA0 0xC0 +#define TC35892_GPIOMASK0 0xc1 +#define TC35892_GPIODATA1 0xC2 +#define TC35892_GPIOMASK1 0xc3 +#define TC35892_GPIODATA2 0xC4 +#define TC35892_GPIOMASK2 0xC5 + +#define TC35892_GPIODIR0 0xC6 +#define TC35892_GPIODIR1 0xC7 +#define TC35892_GPIODIR2 0xC8 + +#define TC35892_GPIOSYNC0 0xE6 +#define TC35892_GPIOSYNC1 0xE7 +#define TC35892_GPIOSYNC2 0xE8 + +#define TC35892_GPIOWAKE0 0xE9 +#define TC35892_GPIOWAKE1 0xEA +#define TC35892_GPIOWAKE2 0xEB + +#define TC35892_GPIOODM0 0xE0 +#define TC35892_GPIOODE0 0xE1 +#define TC35892_GPIOODM1 0xE2 +#define TC35892_GPIOODE1 0xE3 +#define TC35892_GPIOODM2 0xE4 +#define TC35892_GPIOODE2 0xE5 + +#define TC35892_INT_GPIIRQ 0 +#define TC35892_INT_TI0IRQ 1 +#define TC35892_INT_TI1IRQ 2 +#define TC35892_INT_TI2IRQ 3 +#define TC35892_INT_ROTIRQ 5 +#define TC35892_INT_KBDIRQ 6 +#define TC35892_INT_PORIRQ 7 + +#define TC35892_NR_INTERNAL_IRQS 8 +#define TC35892_INT_GPIO(x) (TC35892_NR_INTERNAL_IRQS + (x)) + +struct tc35892 { + struct mutex lock; + struct device *dev; + struct i2c_client *i2c; + + int irq_base; + int num_gpio; + struct tc35892_platform_data *pdata; +}; + +extern int tc35892_reg_write(struct tc35892 *tc35892, u8 reg, u8 data); +extern int tc35892_reg_read(struct tc35892 *tc35892, u8 reg); +extern int tc35892_block_read(struct tc35892 *tc35892, u8 reg, u8 length, + u8 *values); +extern int tc35892_block_write(struct tc35892 *tc35892, u8 reg, u8 length, + const u8 *values); +extern int tc35892_set_bits(struct tc35892 *tc35892, u8 reg, u8 mask, u8 val); + +/** + * struct tc35892_gpio_platform_data - TC35892 GPIO platform data + * @gpio_base: first gpio number assigned to TC35892. A maximum of + * %TC35892_NR_GPIOS GPIOs will be allocated. + */ +struct tc35892_gpio_platform_data { + int gpio_base; +}; + +/** + * struct tc35892_platform_data - TC35892 platform data + * @irq_base: base IRQ number. %TC35892_NR_IRQS irqs will be used. + * @gpio: GPIO-specific platform data + */ +struct tc35892_platform_data { + int irq_base; + struct tc35892_gpio_platform_data *gpio; +}; + +#define TC35892_NR_GPIOS 24 +#define TC35892_NR_IRQS TC35892_INT_GPIO(TC35892_NR_GPIOS) + +#endif -- cgit v1.2.3 From d88b25be3584138e53076ea3eea3d886c870470e Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Mon, 10 May 2010 23:43:47 +0200 Subject: gpio: Add TC35892 GPIO driver Add a GPIO driver to support the GPIOs on the TC35892 I/O Expander. Acked-by: Linus Walleij Signed-off-by: Rabin Vincent Signed-off-by: Samuel Ortiz --- drivers/gpio/Kconfig | 7 + drivers/gpio/Makefile | 1 + drivers/gpio/tc35892-gpio.c | 381 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 389 insertions(+) create mode 100644 drivers/gpio/tc35892-gpio.c (limited to 'drivers') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 0e9c16b5bbce..1567605ab695 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -195,6 +195,13 @@ config GPIO_PCF857X This driver provides an in-kernel interface to those GPIOs using platform-neutral GPIO calls. +config GPIO_TC35892 + bool "TC35892 GPIOs" + depends on MFD_TC35892 + help + This enables support for the GPIOs found on the TC35892 + I/O Expander. + config GPIO_TWL4030 tristate "TWL4030, TWL5030, and TPS659x0 GPIOs" depends on TWL4030_CORE diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 94a96c51c741..51c3cdd41b5a 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o obj-$(CONFIG_GPIO_PCA953X) += pca953x.o obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o obj-$(CONFIG_GPIO_PL061) += pl061.o +obj-$(CONFIG_GPIO_TC35892) += tc35892-gpio.o obj-$(CONFIG_GPIO_TIMBERDALE) += timbgpio.o obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o obj-$(CONFIG_GPIO_UCB1400) += ucb1400_gpio.o diff --git a/drivers/gpio/tc35892-gpio.c b/drivers/gpio/tc35892-gpio.c new file mode 100644 index 000000000000..1be6288780de --- /dev/null +++ b/drivers/gpio/tc35892-gpio.c @@ -0,0 +1,381 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License Terms: GNU General Public License, version 2 + * Author: Hanumath Prasad for ST-Ericsson + * Author: Rabin Vincent for ST-Ericsson + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * These registers are modified under the irq bus lock and cached to avoid + * unnecessary writes in bus_sync_unlock. + */ +enum { REG_IBE, REG_IEV, REG_IS, REG_IE }; + +#define CACHE_NR_REGS 4 +#define CACHE_NR_BANKS 3 + +struct tc35892_gpio { + struct gpio_chip chip; + struct tc35892 *tc35892; + struct device *dev; + struct mutex irq_lock; + + int irq_base; + + /* Caches of interrupt control registers for bus_lock */ + u8 regs[CACHE_NR_REGS][CACHE_NR_BANKS]; + u8 oldregs[CACHE_NR_REGS][CACHE_NR_BANKS]; +}; + +static inline struct tc35892_gpio *to_tc35892_gpio(struct gpio_chip *chip) +{ + return container_of(chip, struct tc35892_gpio, chip); +} + +static int tc35892_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct tc35892_gpio *tc35892_gpio = to_tc35892_gpio(chip); + struct tc35892 *tc35892 = tc35892_gpio->tc35892; + u8 reg = TC35892_GPIODATA0 + (offset / 8) * 2; + u8 mask = 1 << (offset % 8); + int ret; + + ret = tc35892_reg_read(tc35892, reg); + if (ret < 0) + return ret; + + return ret & mask; +} + +static void tc35892_gpio_set(struct gpio_chip *chip, unsigned offset, int val) +{ + struct tc35892_gpio *tc35892_gpio = to_tc35892_gpio(chip); + struct tc35892 *tc35892 = tc35892_gpio->tc35892; + u8 reg = TC35892_GPIODATA0 + (offset / 8) * 2; + unsigned pos = offset % 8; + u8 data[] = {!!val << pos, 1 << pos}; + + tc35892_block_write(tc35892, reg, ARRAY_SIZE(data), data); +} + +static int tc35892_gpio_direction_output(struct gpio_chip *chip, + unsigned offset, int val) +{ + struct tc35892_gpio *tc35892_gpio = to_tc35892_gpio(chip); + struct tc35892 *tc35892 = tc35892_gpio->tc35892; + u8 reg = TC35892_GPIODIR0 + offset / 8; + unsigned pos = offset % 8; + + tc35892_gpio_set(chip, offset, val); + + return tc35892_set_bits(tc35892, reg, 1 << pos, 1 << pos); +} + +static int tc35892_gpio_direction_input(struct gpio_chip *chip, + unsigned offset) +{ + struct tc35892_gpio *tc35892_gpio = to_tc35892_gpio(chip); + struct tc35892 *tc35892 = tc35892_gpio->tc35892; + u8 reg = TC35892_GPIODIR0 + offset / 8; + unsigned pos = offset % 8; + + return tc35892_set_bits(tc35892, reg, 1 << pos, 0); +} + +static int tc35892_gpio_to_irq(struct gpio_chip *chip, unsigned offset) +{ + struct tc35892_gpio *tc35892_gpio = to_tc35892_gpio(chip); + + return tc35892_gpio->irq_base + offset; +} + +static struct gpio_chip template_chip = { + .label = "tc35892", + .owner = THIS_MODULE, + .direction_input = tc35892_gpio_direction_input, + .get = tc35892_gpio_get, + .direction_output = tc35892_gpio_direction_output, + .set = tc35892_gpio_set, + .to_irq = tc35892_gpio_to_irq, + .can_sleep = 1, +}; + +static int tc35892_gpio_irq_set_type(unsigned int irq, unsigned int type) +{ + struct tc35892_gpio *tc35892_gpio = get_irq_chip_data(irq); + int offset = irq - tc35892_gpio->irq_base; + int regoffset = offset / 8; + int mask = 1 << (offset % 8); + + if (type == IRQ_TYPE_EDGE_BOTH) { + tc35892_gpio->regs[REG_IBE][regoffset] |= mask; + return 0; + } + + tc35892_gpio->regs[REG_IBE][regoffset] &= ~mask; + + if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_LEVEL_HIGH) + tc35892_gpio->regs[REG_IS][regoffset] |= mask; + else + tc35892_gpio->regs[REG_IS][regoffset] &= ~mask; + + if (type == IRQ_TYPE_EDGE_RISING || type == IRQ_TYPE_LEVEL_HIGH) + tc35892_gpio->regs[REG_IEV][regoffset] |= mask; + else + tc35892_gpio->regs[REG_IEV][regoffset] &= ~mask; + + return 0; +} + +static void tc35892_gpio_irq_lock(unsigned int irq) +{ + struct tc35892_gpio *tc35892_gpio = get_irq_chip_data(irq); + + mutex_lock(&tc35892_gpio->irq_lock); +} + +static void tc35892_gpio_irq_sync_unlock(unsigned int irq) +{ + struct tc35892_gpio *tc35892_gpio = get_irq_chip_data(irq); + struct tc35892 *tc35892 = tc35892_gpio->tc35892; + static const u8 regmap[] = { + [REG_IBE] = TC35892_GPIOIBE0, + [REG_IEV] = TC35892_GPIOIEV0, + [REG_IS] = TC35892_GPIOIS0, + [REG_IE] = TC35892_GPIOIE0, + }; + int i, j; + + for (i = 0; i < CACHE_NR_REGS; i++) { + for (j = 0; j < CACHE_NR_BANKS; j++) { + u8 old = tc35892_gpio->oldregs[i][j]; + u8 new = tc35892_gpio->regs[i][j]; + + if (new == old) + continue; + + tc35892_gpio->oldregs[i][j] = new; + tc35892_reg_write(tc35892, regmap[i] + j * 8, new); + } + } + + mutex_unlock(&tc35892_gpio->irq_lock); +} + +static void tc35892_gpio_irq_mask(unsigned int irq) +{ + struct tc35892_gpio *tc35892_gpio = get_irq_chip_data(irq); + int offset = irq - tc35892_gpio->irq_base; + int regoffset = offset / 8; + int mask = 1 << (offset % 8); + + tc35892_gpio->regs[REG_IE][regoffset] &= ~mask; +} + +static void tc35892_gpio_irq_unmask(unsigned int irq) +{ + struct tc35892_gpio *tc35892_gpio = get_irq_chip_data(irq); + int offset = irq - tc35892_gpio->irq_base; + int regoffset = offset / 8; + int mask = 1 << (offset % 8); + + tc35892_gpio->regs[REG_IE][regoffset] |= mask; +} + +static struct irq_chip tc35892_gpio_irq_chip = { + .name = "tc35892-gpio", + .bus_lock = tc35892_gpio_irq_lock, + .bus_sync_unlock = tc35892_gpio_irq_sync_unlock, + .mask = tc35892_gpio_irq_mask, + .unmask = tc35892_gpio_irq_unmask, + .set_type = tc35892_gpio_irq_set_type, +}; + +static irqreturn_t tc35892_gpio_irq(int irq, void *dev) +{ + struct tc35892_gpio *tc35892_gpio = dev; + struct tc35892 *tc35892 = tc35892_gpio->tc35892; + u8 status[CACHE_NR_BANKS]; + int ret; + int i; + + ret = tc35892_block_read(tc35892, TC35892_GPIOMIS0, + ARRAY_SIZE(status), status); + if (ret < 0) + return IRQ_NONE; + + for (i = 0; i < ARRAY_SIZE(status); i++) { + unsigned int stat = status[i]; + if (!stat) + continue; + + while (stat) { + int bit = __ffs(stat); + int line = i * 8 + bit; + + handle_nested_irq(tc35892_gpio->irq_base + line); + stat &= ~(1 << bit); + } + + tc35892_reg_write(tc35892, TC35892_GPIOIC0 + i, status[i]); + } + + return IRQ_HANDLED; +} + +static int tc35892_gpio_irq_init(struct tc35892_gpio *tc35892_gpio) +{ + int base = tc35892_gpio->irq_base; + int irq; + + for (irq = base; irq < base + tc35892_gpio->chip.ngpio; irq++) { + set_irq_chip_data(irq, tc35892_gpio); + set_irq_chip_and_handler(irq, &tc35892_gpio_irq_chip, + handle_simple_irq); + set_irq_nested_thread(irq, 1); +#ifdef CONFIG_ARM + set_irq_flags(irq, IRQF_VALID); +#else + set_irq_noprobe(irq); +#endif + } + + return 0; +} + +static void tc35892_gpio_irq_remove(struct tc35892_gpio *tc35892_gpio) +{ + int base = tc35892_gpio->irq_base; + int irq; + + for (irq = base; irq < base + tc35892_gpio->chip.ngpio; irq++) { +#ifdef CONFIG_ARM + set_irq_flags(irq, 0); +#endif + set_irq_chip_and_handler(irq, NULL, NULL); + set_irq_chip_data(irq, NULL); + } +} + +static int __devinit tc35892_gpio_probe(struct platform_device *pdev) +{ + struct tc35892 *tc35892 = dev_get_drvdata(pdev->dev.parent); + struct tc35892_gpio_platform_data *pdata; + struct tc35892_gpio *tc35892_gpio; + int ret; + int irq; + + pdata = tc35892->pdata->gpio; + if (!pdata) + return -ENODEV; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + tc35892_gpio = kzalloc(sizeof(struct tc35892_gpio), GFP_KERNEL); + if (!tc35892_gpio) + return -ENOMEM; + + mutex_init(&tc35892_gpio->irq_lock); + + tc35892_gpio->dev = &pdev->dev; + tc35892_gpio->tc35892 = tc35892; + + tc35892_gpio->chip = template_chip; + tc35892_gpio->chip.ngpio = tc35892->num_gpio; + tc35892_gpio->chip.dev = &pdev->dev; + tc35892_gpio->chip.base = pdata->gpio_base; + + tc35892_gpio->irq_base = tc35892->irq_base + TC35892_INT_GPIO(0); + + /* Bring the GPIO module out of reset */ + ret = tc35892_set_bits(tc35892, TC35892_RSTCTRL, + TC35892_RSTCTRL_GPIRST, 0); + if (ret < 0) + goto out_free; + + ret = tc35892_gpio_irq_init(tc35892_gpio); + if (ret) + goto out_free; + + ret = request_threaded_irq(irq, NULL, tc35892_gpio_irq, IRQF_ONESHOT, + "tc35892-gpio", tc35892_gpio); + if (ret) { + dev_err(&pdev->dev, "unable to get irq: %d\n", ret); + goto out_removeirq; + } + + ret = gpiochip_add(&tc35892_gpio->chip); + if (ret) { + dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret); + goto out_freeirq; + } + + platform_set_drvdata(pdev, tc35892_gpio); + + return 0; + +out_freeirq: + free_irq(irq, tc35892_gpio); +out_removeirq: + tc35892_gpio_irq_remove(tc35892_gpio); +out_free: + kfree(tc35892_gpio); + return ret; +} + +static int __devexit tc35892_gpio_remove(struct platform_device *pdev) +{ + struct tc35892_gpio *tc35892_gpio = platform_get_drvdata(pdev); + int irq = platform_get_irq(pdev, 0); + int ret; + + ret = gpiochip_remove(&tc35892_gpio->chip); + if (ret < 0) { + dev_err(tc35892_gpio->dev, + "unable to remove gpiochip: %d\n", ret); + return ret; + } + + free_irq(irq, tc35892_gpio); + tc35892_gpio_irq_remove(tc35892_gpio); + + platform_set_drvdata(pdev, NULL); + kfree(tc35892_gpio); + + return 0; +} + +static struct platform_driver tc35892_gpio_driver = { + .driver.name = "tc35892-gpio", + .driver.owner = THIS_MODULE, + .probe = tc35892_gpio_probe, + .remove = __devexit_p(tc35892_gpio_remove), +}; + +static int __init tc35892_gpio_init(void) +{ + return platform_driver_register(&tc35892_gpio_driver); +} +subsys_initcall(tc35892_gpio_init); + +static void __exit tc35892_gpio_exit(void) +{ + platform_driver_unregister(&tc35892_gpio_driver); +} +module_exit(tc35892_gpio_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("TC35892 GPIO driver"); +MODULE_AUTHOR("Hanumath Prasad, Rabin Vincent"); -- cgit v1.2.3 From 812f9e9d424dde9ccb35975c0281edb6f8543735 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sat, 1 May 2010 18:26:07 +0200 Subject: mfd: Renamed ab3100.h to abx500.h The goal here is to make way for a more general interface for the analog baseband chips ab3100 ab3550 ab550 and future chips. This patch have been divided into two parts since both changing name and content of a file is not recommended in git. Signed-off-by: Mattias Wallin Signed-off-by: Linus Walleij Signed-off-by: Samuel Ortiz --- arch/arm/mach-u300/i2c.c | 2 +- drivers/mfd/ab3100-core.c | 2 +- drivers/mfd/ab3100-otp.c | 2 +- drivers/regulator/ab3100.c | 2 +- drivers/rtc/rtc-ab3100.c | 2 +- include/linux/mfd/ab3100.h | 129 --------------------------------------------- include/linux/mfd/abx500.h | 129 +++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 134 insertions(+), 134 deletions(-) delete mode 100644 include/linux/mfd/ab3100.h create mode 100644 include/linux/mfd/abx500.h (limited to 'drivers') diff --git a/arch/arm/mach-u300/i2c.c b/arch/arm/mach-u300/i2c.c index c73ed06b6065..d893ee035c23 100644 --- a/arch/arm/mach-u300/i2c.c +++ b/arch/arm/mach-u300/i2c.c @@ -9,7 +9,7 @@ */ #include #include -#include +#include #include #include #include diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index 16898211cd1a..f8c4a333ff1c 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include /* These are the only registers inside AB3100 used in this main file */ diff --git a/drivers/mfd/ab3100-otp.c b/drivers/mfd/ab3100-otp.c index 2d14655fdebd..7093f1aef1e5 100644 --- a/drivers/mfd/ab3100-otp.c +++ b/drivers/mfd/ab3100-otp.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index 1afd008ca957..04ca7f62c57e 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include /* LDO registers and some handy masking definitions for AB3100 */ #define AB3100_LDO_A 0x40 diff --git a/drivers/rtc/rtc-ab3100.c b/drivers/rtc/rtc-ab3100.c index 4704aac2b5af..b46b85d581b0 100644 --- a/drivers/rtc/rtc-ab3100.c +++ b/drivers/rtc/rtc-ab3100.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include /* Clock rate in Hz */ #define AB3100_RTC_CLOCK_RATE 32768 diff --git a/include/linux/mfd/ab3100.h b/include/linux/mfd/ab3100.h deleted file mode 100644 index 9a881c305a50..000000000000 --- a/include/linux/mfd/ab3100.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2007-2009 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 - * AB3100 core access functions - * Author: Linus Walleij - */ - -#include -#include - -#ifndef MFD_AB3100_H -#define MFD_AB3100_H - -#define ABUNKNOWN 0 -#define AB3000 1 -#define AB3100 2 - -/* - * AB3100, EVENTA1, A2 and A3 event register flags - * these are catenated into a single 32-bit flag in the code - * for event notification broadcasts. - */ -#define AB3100_EVENTA1_ONSWA (0x01<<16) -#define AB3100_EVENTA1_ONSWB (0x02<<16) -#define AB3100_EVENTA1_ONSWC (0x04<<16) -#define AB3100_EVENTA1_DCIO (0x08<<16) -#define AB3100_EVENTA1_OVER_TEMP (0x10<<16) -#define AB3100_EVENTA1_SIM_OFF (0x20<<16) -#define AB3100_EVENTA1_VBUS (0x40<<16) -#define AB3100_EVENTA1_VSET_USB (0x80<<16) - -#define AB3100_EVENTA2_READY_TX (0x01<<8) -#define AB3100_EVENTA2_READY_RX (0x02<<8) -#define AB3100_EVENTA2_OVERRUN_ERROR (0x04<<8) -#define AB3100_EVENTA2_FRAMING_ERROR (0x08<<8) -#define AB3100_EVENTA2_CHARG_OVERCURRENT (0x10<<8) -#define AB3100_EVENTA2_MIDR (0x20<<8) -#define AB3100_EVENTA2_BATTERY_REM (0x40<<8) -#define AB3100_EVENTA2_ALARM (0x80<<8) - -#define AB3100_EVENTA3_ADC_TRIG5 (0x01) -#define AB3100_EVENTA3_ADC_TRIG4 (0x02) -#define AB3100_EVENTA3_ADC_TRIG3 (0x04) -#define AB3100_EVENTA3_ADC_TRIG2 (0x08) -#define AB3100_EVENTA3_ADC_TRIGVBAT (0x10) -#define AB3100_EVENTA3_ADC_TRIGVTX (0x20) -#define AB3100_EVENTA3_ADC_TRIG1 (0x40) -#define AB3100_EVENTA3_ADC_TRIG0 (0x80) - -/* AB3100, STR register flags */ -#define AB3100_STR_ONSWA (0x01) -#define AB3100_STR_ONSWB (0x02) -#define AB3100_STR_ONSWC (0x04) -#define AB3100_STR_DCIO (0x08) -#define AB3100_STR_BOOT_MODE (0x10) -#define AB3100_STR_SIM_OFF (0x20) -#define AB3100_STR_BATT_REMOVAL (0x40) -#define AB3100_STR_VBUS (0x80) - -/* - * AB3100 contains 8 regulators, one external regulator controller - * and a buck converter, further the LDO E and buck converter can - * have separate settings if they are in sleep mode, this is - * modeled as a separate regulator. - */ -#define AB3100_NUM_REGULATORS 10 - -/** - * struct ab3100 - * @access_mutex: lock out concurrent accesses to the AB3100 registers - * @dev: pointer to the containing device - * @i2c_client: I2C client for this chip - * @testreg_client: secondary client for test registers - * @chip_name: name of this chip variant - * @chip_id: 8 bit chip ID for this chip variant - * @event_subscribers: event subscribers are listed here - * @startup_events: a copy of the first reading of the event registers - * @startup_events_read: whether the first events have been read - * - * This struct is PRIVATE and devices using it should NOT - * access ANY fields. It is used as a token for calling the - * AB3100 functions. - */ -struct ab3100 { - struct mutex access_mutex; - struct device *dev; - struct i2c_client *i2c_client; - struct i2c_client *testreg_client; - char chip_name[32]; - u8 chip_id; - struct blocking_notifier_head event_subscribers; - u32 startup_events; - bool startup_events_read; -}; - -/** - * struct ab3100_platform_data - * Data supplied to initialize board connections to the AB3100 - * @reg_constraints: regulator constraints for target board - * the order of these constraints are: LDO A, C, D, E, - * F, G, H, K, EXT and BUCK. - * @reg_initvals: initial values for the regulator registers - * plus two sleep settings for LDO E and the BUCK converter. - * exactly AB3100_NUM_REGULATORS+2 values must be sent in. - * Order: LDO A, C, E, E sleep, F, G, H, K, EXT, BUCK, - * BUCK sleep, LDO D. (LDO D need to be initialized last.) - * @external_voltage: voltage level of the external regulator. - */ -struct ab3100_platform_data { - struct regulator_init_data reg_constraints[AB3100_NUM_REGULATORS]; - u8 reg_initvals[AB3100_NUM_REGULATORS+2]; - int external_voltage; -}; - -int ab3100_set_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 regval); -int ab3100_get_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 *regval); -int ab3100_get_register_page_interruptible(struct ab3100 *ab3100, - u8 first_reg, u8 *regvals, u8 numregs); -int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100, - u8 reg, u8 andmask, u8 ormask); -u8 ab3100_get_chip_type(struct ab3100 *ab3100); -int ab3100_event_register(struct ab3100 *ab3100, - struct notifier_block *nb); -int ab3100_event_unregister(struct ab3100 *ab3100, - struct notifier_block *nb); -int ab3100_event_registers_startup_state_get(struct ab3100 *ab3100, - u32 *fatevent); - -#endif diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h new file mode 100644 index 000000000000..9a881c305a50 --- /dev/null +++ b/include/linux/mfd/abx500.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2007-2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * AB3100 core access functions + * Author: Linus Walleij + */ + +#include +#include + +#ifndef MFD_AB3100_H +#define MFD_AB3100_H + +#define ABUNKNOWN 0 +#define AB3000 1 +#define AB3100 2 + +/* + * AB3100, EVENTA1, A2 and A3 event register flags + * these are catenated into a single 32-bit flag in the code + * for event notification broadcasts. + */ +#define AB3100_EVENTA1_ONSWA (0x01<<16) +#define AB3100_EVENTA1_ONSWB (0x02<<16) +#define AB3100_EVENTA1_ONSWC (0x04<<16) +#define AB3100_EVENTA1_DCIO (0x08<<16) +#define AB3100_EVENTA1_OVER_TEMP (0x10<<16) +#define AB3100_EVENTA1_SIM_OFF (0x20<<16) +#define AB3100_EVENTA1_VBUS (0x40<<16) +#define AB3100_EVENTA1_VSET_USB (0x80<<16) + +#define AB3100_EVENTA2_READY_TX (0x01<<8) +#define AB3100_EVENTA2_READY_RX (0x02<<8) +#define AB3100_EVENTA2_OVERRUN_ERROR (0x04<<8) +#define AB3100_EVENTA2_FRAMING_ERROR (0x08<<8) +#define AB3100_EVENTA2_CHARG_OVERCURRENT (0x10<<8) +#define AB3100_EVENTA2_MIDR (0x20<<8) +#define AB3100_EVENTA2_BATTERY_REM (0x40<<8) +#define AB3100_EVENTA2_ALARM (0x80<<8) + +#define AB3100_EVENTA3_ADC_TRIG5 (0x01) +#define AB3100_EVENTA3_ADC_TRIG4 (0x02) +#define AB3100_EVENTA3_ADC_TRIG3 (0x04) +#define AB3100_EVENTA3_ADC_TRIG2 (0x08) +#define AB3100_EVENTA3_ADC_TRIGVBAT (0x10) +#define AB3100_EVENTA3_ADC_TRIGVTX (0x20) +#define AB3100_EVENTA3_ADC_TRIG1 (0x40) +#define AB3100_EVENTA3_ADC_TRIG0 (0x80) + +/* AB3100, STR register flags */ +#define AB3100_STR_ONSWA (0x01) +#define AB3100_STR_ONSWB (0x02) +#define AB3100_STR_ONSWC (0x04) +#define AB3100_STR_DCIO (0x08) +#define AB3100_STR_BOOT_MODE (0x10) +#define AB3100_STR_SIM_OFF (0x20) +#define AB3100_STR_BATT_REMOVAL (0x40) +#define AB3100_STR_VBUS (0x80) + +/* + * AB3100 contains 8 regulators, one external regulator controller + * and a buck converter, further the LDO E and buck converter can + * have separate settings if they are in sleep mode, this is + * modeled as a separate regulator. + */ +#define AB3100_NUM_REGULATORS 10 + +/** + * struct ab3100 + * @access_mutex: lock out concurrent accesses to the AB3100 registers + * @dev: pointer to the containing device + * @i2c_client: I2C client for this chip + * @testreg_client: secondary client for test registers + * @chip_name: name of this chip variant + * @chip_id: 8 bit chip ID for this chip variant + * @event_subscribers: event subscribers are listed here + * @startup_events: a copy of the first reading of the event registers + * @startup_events_read: whether the first events have been read + * + * This struct is PRIVATE and devices using it should NOT + * access ANY fields. It is used as a token for calling the + * AB3100 functions. + */ +struct ab3100 { + struct mutex access_mutex; + struct device *dev; + struct i2c_client *i2c_client; + struct i2c_client *testreg_client; + char chip_name[32]; + u8 chip_id; + struct blocking_notifier_head event_subscribers; + u32 startup_events; + bool startup_events_read; +}; + +/** + * struct ab3100_platform_data + * Data supplied to initialize board connections to the AB3100 + * @reg_constraints: regulator constraints for target board + * the order of these constraints are: LDO A, C, D, E, + * F, G, H, K, EXT and BUCK. + * @reg_initvals: initial values for the regulator registers + * plus two sleep settings for LDO E and the BUCK converter. + * exactly AB3100_NUM_REGULATORS+2 values must be sent in. + * Order: LDO A, C, E, E sleep, F, G, H, K, EXT, BUCK, + * BUCK sleep, LDO D. (LDO D need to be initialized last.) + * @external_voltage: voltage level of the external regulator. + */ +struct ab3100_platform_data { + struct regulator_init_data reg_constraints[AB3100_NUM_REGULATORS]; + u8 reg_initvals[AB3100_NUM_REGULATORS+2]; + int external_voltage; +}; + +int ab3100_set_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 regval); +int ab3100_get_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 *regval); +int ab3100_get_register_page_interruptible(struct ab3100 *ab3100, + u8 first_reg, u8 *regvals, u8 numregs); +int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100, + u8 reg, u8 andmask, u8 ormask); +u8 ab3100_get_chip_type(struct ab3100 *ab3100); +int ab3100_event_register(struct ab3100 *ab3100, + struct notifier_block *nb); +int ab3100_event_unregister(struct ab3100 *ab3100, + struct notifier_block *nb); +int ab3100_event_registers_startup_state_get(struct ab3100 *ab3100, + u32 *fatevent); + +#endif -- cgit v1.2.3 From fa661258a27aa74aaf741882053d195291cefb75 Mon Sep 17 00:00:00 2001 From: Mattias Wallin Date: Sat, 1 May 2010 18:26:20 +0200 Subject: mfd: AB3100 register access change to abx500 API The interface for the AB3100 is changed to make way for the ABX500 family of chips: AB3550, AB5500 and future ST-Ericsson Analog Baseband chips. The register access functions are moved out to a separate struct abx500_ops. In this way the interface is moved from the implementation and the sub functionality drivers can keep their interface intact when chip infrastructure and communication mechanisms changes. We also define the AB3550 device IDs and the AB3550 platform data struct and convert the catenated 32bit event to an array of 3 x 8bits. Signed-off-by: Mattias Wallin Signed-off-by: Linus Walleij Signed-off-by: Samuel Ortiz --- drivers/mfd/Kconfig | 12 +++- drivers/mfd/Makefile | 1 + drivers/mfd/ab3100-core.c | 95 ++++++++++++++++++--------- drivers/mfd/ab3100-otp.c | 11 ++-- drivers/mfd/abx500-core.c | 157 +++++++++++++++++++++++++++++++++++++++++++++ drivers/regulator/ab3100.c | 33 +++++----- drivers/rtc/rtc-ab3100.c | 39 +++++------ include/linux/mfd/abx500.h | 134 +++++++++++++++++++++++++++++++++----- 8 files changed, 390 insertions(+), 92 deletions(-) create mode 100644 drivers/mfd/abx500-core.c (limited to 'drivers') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 614fa7b8a054..1c3d737ec406 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -374,9 +374,19 @@ config PCF50633_GPIO Say yes here if you want to include support GPIO for pins on the PCF50633 chip. +config ABX500_CORE + bool "ST-Ericsson ABX500 Mixed Signal Circuit register functions" + default y if ARCH_U300 + help + Say yes here if you have the ABX500 Mixed Signal IC family + chips. This core driver expose register access functions. + Functionality specific drivers using these functions can + remain unchanged when IC changes. Binding of the functions to + actual register access is done by the IC core driver. + config AB3100_CORE bool "ST-Ericsson AB3100 Mixed Signal Circuit core functions" - depends on I2C=y + depends on I2C=y && ABX500_CORE default y if ARCH_U300 help Select this to enable the AB3100 Mixed Signal IC core diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 5eb79794d5a5..4b8ad04ff8e2 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -60,6 +60,7 @@ obj-$(CONFIG_MFD_MAX8925) += max8925.o obj-$(CONFIG_MFD_PCF50633) += pcf50633-core.o obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o +obj-$(CONFIG_ABX500_CORE) += abx500-core.o obj-$(CONFIG_AB3100_CORE) += ab3100-core.o obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o obj-$(CONFIG_AB4500_CORE) += ab4500-core.o diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index f8c4a333ff1c..53ebfee548fa 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c @@ -59,24 +59,15 @@ * The AB3100 is usually assigned address 0x48 (7-bit) * The chip is defined in the platform i2c_board_data section. */ - -u8 ab3100_get_chip_type(struct ab3100 *ab3100) +static int ab3100_get_chip_id(struct device *dev) { - u8 chip = ABUNKNOWN; - - switch (ab3100->chip_id & 0xf0) { - case 0xa0: - chip = AB3000; - break; - case 0xc0: - chip = AB3100; - break; - } - return chip; + struct ab3100 *ab3100 = dev_get_drvdata(dev->parent); + + return (int)ab3100->chip_id; } -EXPORT_SYMBOL(ab3100_get_chip_type); -int ab3100_set_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 regval) +static int ab3100_set_register_interruptible(struct ab3100 *ab3100, + u8 reg, u8 regval) { u8 regandval[2] = {reg, regval}; int err; @@ -108,8 +99,14 @@ int ab3100_set_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 regval) mutex_unlock(&ab3100->access_mutex); return err; } -EXPORT_SYMBOL(ab3100_set_register_interruptible); +static int set_register_interruptible(struct device *dev, + u8 bank, u8 reg, u8 value) +{ + struct ab3100 *ab3100 = dev_get_drvdata(dev->parent); + + return ab3100_set_register_interruptible(ab3100, reg, value); +} /* * The test registers exist at an I2C bus address up one @@ -148,8 +145,8 @@ static int ab3100_set_test_register_interruptible(struct ab3100 *ab3100, return err; } - -int ab3100_get_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 *regval) +static int ab3100_get_register_interruptible(struct ab3100 *ab3100, + u8 reg, u8 *regval) { int err; @@ -203,10 +200,16 @@ int ab3100_get_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 *regval) mutex_unlock(&ab3100->access_mutex); return err; } -EXPORT_SYMBOL(ab3100_get_register_interruptible); +static int get_register_interruptible(struct device *dev, u8 bank, u8 reg, + u8 *value) +{ + struct ab3100 *ab3100 = dev_get_drvdata(dev->parent); + + return ab3100_get_register_interruptible(ab3100, reg, value); +} -int ab3100_get_register_page_interruptible(struct ab3100 *ab3100, +static int ab3100_get_register_page_interruptible(struct ab3100 *ab3100, u8 first_reg, u8 *regvals, u8 numregs) { int err; @@ -260,10 +263,17 @@ int ab3100_get_register_page_interruptible(struct ab3100 *ab3100, mutex_unlock(&ab3100->access_mutex); return err; } -EXPORT_SYMBOL(ab3100_get_register_page_interruptible); +static int get_register_page_interruptible(struct device *dev, u8 bank, + u8 first_reg, u8 *regvals, u8 numregs) +{ + struct ab3100 *ab3100 = dev_get_drvdata(dev->parent); + + return ab3100_get_register_page_interruptible(ab3100, + first_reg, regvals, numregs); +} -int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100, +static int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 andmask, u8 ormask) { u8 regandval[2] = {reg, 0}; @@ -331,8 +341,15 @@ int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100, mutex_unlock(&ab3100->access_mutex); return err; } -EXPORT_SYMBOL(ab3100_mask_and_set_register_interruptible); +static int mask_and_set_register_interruptible(struct device *dev, u8 bank, + u8 reg, u8 bitmask, u8 bitvalues) +{ + struct ab3100 *ab3100 = dev_get_drvdata(dev->parent); + + return ab3100_mask_and_set_register_interruptible(ab3100, + reg, bitmask, (bitmask & bitvalues)); +} /* * Register a simple callback for handling any AB3100 events. @@ -357,15 +374,27 @@ int ab3100_event_unregister(struct ab3100 *ab3100, EXPORT_SYMBOL(ab3100_event_unregister); -int ab3100_event_registers_startup_state_get(struct ab3100 *ab3100, - u32 *fatevent) +static int ab3100_event_registers_startup_state_get(struct device *dev, + u8 *event) { + struct ab3100 *ab3100 = dev_get_drvdata(dev->parent); if (!ab3100->startup_events_read) return -EAGAIN; /* Try again later */ - *fatevent = ab3100->startup_events; + memcpy(event, ab3100->startup_events, 3); return 0; } -EXPORT_SYMBOL(ab3100_event_registers_startup_state_get); + +static struct abx500_ops ab3100_ops = { + .get_chip_id = ab3100_get_chip_id, + .set_register = set_register_interruptible, + .get_register = get_register_interruptible, + .get_register_page = get_register_page_interruptible, + .set_register_page = NULL, + .mask_and_set_register = mask_and_set_register_interruptible, + .event_registers_startup_state_get = + ab3100_event_registers_startup_state_get, + .startup_irq_enabled = NULL, +}; /* * This is a threaded interrupt handler so we can make some @@ -390,7 +419,9 @@ static irqreturn_t ab3100_irq_handler(int irq, void *data) event_regs[2]; if (!ab3100->startup_events_read) { - ab3100->startup_events = fatevent; + ab3100->startup_events[0] = event_regs[0]; + ab3100->startup_events[1] = event_regs[1]; + ab3100->startup_events[2] = event_regs[2]; ab3100->startup_events_read = true; } /* @@ -703,7 +734,8 @@ static int __init ab3100_setup(struct ab3100 *ab3100) dev_warn(ab3100->dev, "AB3100 P1E variant detected, " "forcing chip to 32KHz\n"); - err = ab3100_set_test_register_interruptible(ab3100, 0x02, 0x08); + err = ab3100_set_test_register_interruptible(ab3100, + 0x02, 0x08); } exit_no_setup: @@ -898,6 +930,10 @@ static int __init ab3100_probe(struct i2c_client *client, if (err) goto exit_no_irq; + err = abx500_register_ops(&client->dev, &ab3100_ops); + if (err) + goto exit_no_ops; + /* Set parent and a pointer back to the container in device data */ for (i = 0; i < ARRAY_SIZE(ab3100_platform_devs); i++) { ab3100_platform_devs[i]->dev.parent = @@ -915,6 +951,7 @@ static int __init ab3100_probe(struct i2c_client *client, return 0; + exit_no_ops: exit_no_irq: exit_no_setup: i2c_unregister_device(ab3100->testreg_client); diff --git a/drivers/mfd/ab3100-otp.c b/drivers/mfd/ab3100-otp.c index 7093f1aef1e5..63d2b727ddbb 100644 --- a/drivers/mfd/ab3100-otp.c +++ b/drivers/mfd/ab3100-otp.c @@ -30,7 +30,6 @@ /** * struct ab3100_otp * @dev containing device - * @ab3100 a pointer to the parent ab3100 device struct * @locked whether the OTP is locked, after locking, no more bits * can be changed but before locking it is still possible * to change bits from 1->0. @@ -49,7 +48,6 @@ */ struct ab3100_otp { struct device *dev; - struct ab3100 *ab3100; bool locked; u32 freq; bool paf; @@ -63,19 +61,19 @@ struct ab3100_otp { static int __init ab3100_otp_read(struct ab3100_otp *otp) { - struct ab3100 *ab = otp->ab3100; u8 otpval[8]; u8 otpp; int err; - err = ab3100_get_register_interruptible(ab, AB3100_OTPP, &otpp); + err = abx500_get_register_interruptible(otp->dev, 0, + AB3100_OTPP, &otpp); if (err) { dev_err(otp->dev, "unable to read OTPP register\n"); return err; } - err = ab3100_get_register_page_interruptible(ab, AB3100_OTP0, - otpval, 8); + err = abx500_get_register_page_interruptible(otp->dev, 0, + AB3100_OTP0, otpval, 8); if (err) { dev_err(otp->dev, "unable to read OTP register page\n"); return err; @@ -197,7 +195,6 @@ static int __init ab3100_otp_probe(struct platform_device *pdev) otp->dev = &pdev->dev; /* Replace platform data coming in with a local struct */ - otp->ab3100 = platform_get_drvdata(pdev); platform_set_drvdata(pdev, otp); err = ab3100_otp_read(otp); diff --git a/drivers/mfd/abx500-core.c b/drivers/mfd/abx500-core.c new file mode 100644 index 000000000000..3b3b97ec32a7 --- /dev/null +++ b/drivers/mfd/abx500-core.c @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2007-2010 ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + * Register access functions for the ABX500 Mixed Signal IC family. + * Author: Mattias Wallin + */ + +#include +#include +#include +#include + +static LIST_HEAD(abx500_list); + +struct abx500_device_entry { + struct list_head list; + struct abx500_ops ops; + struct device *dev; +}; + +static void lookup_ops(struct device *dev, struct abx500_ops **ops) +{ + struct abx500_device_entry *dev_entry; + + *ops = NULL; + list_for_each_entry(dev_entry, &abx500_list, list) { + if (dev_entry->dev == dev) { + *ops = &dev_entry->ops; + return; + } + } +} + +int abx500_register_ops(struct device *dev, struct abx500_ops *ops) +{ + struct abx500_device_entry *dev_entry; + + dev_entry = kzalloc(sizeof(struct abx500_device_entry), GFP_KERNEL); + if (IS_ERR(dev_entry)) { + dev_err(dev, "register_ops kzalloc failed"); + return -ENOMEM; + } + dev_entry->dev = dev; + memcpy(&dev_entry->ops, ops, sizeof(struct abx500_ops)); + + list_add_tail(&dev_entry->list, &abx500_list); + return 0; +} +EXPORT_SYMBOL(abx500_register_ops); + +void abx500_remove_ops(struct device *dev) +{ + struct abx500_device_entry *dev_entry, *tmp; + + list_for_each_entry_safe(dev_entry, tmp, &abx500_list, list) + { + if (dev_entry->dev == dev) { + list_del(&dev_entry->list); + kfree(dev_entry); + } + } +} +EXPORT_SYMBOL(abx500_remove_ops); + +int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg, + u8 value) +{ + struct abx500_ops *ops; + + lookup_ops(dev->parent, &ops); + if ((ops != NULL) && (ops->set_register != NULL)) + return ops->set_register(dev, bank, reg, value); + else + return -ENOTSUPP; +} +EXPORT_SYMBOL(abx500_set_register_interruptible); + +int abx500_get_register_interruptible(struct device *dev, u8 bank, u8 reg, + u8 *value) +{ + struct abx500_ops *ops; + + lookup_ops(dev->parent, &ops); + if ((ops != NULL) && (ops->get_register != NULL)) + return ops->get_register(dev, bank, reg, value); + else + return -ENOTSUPP; +} +EXPORT_SYMBOL(abx500_get_register_interruptible); + +int abx500_get_register_page_interruptible(struct device *dev, u8 bank, + u8 first_reg, u8 *regvals, u8 numregs) +{ + struct abx500_ops *ops; + + lookup_ops(dev->parent, &ops); + if ((ops != NULL) && (ops->get_register_page != NULL)) + return ops->get_register_page(dev, bank, + first_reg, regvals, numregs); + else + return -ENOTSUPP; +} +EXPORT_SYMBOL(abx500_get_register_page_interruptible); + +int abx500_mask_and_set_register_interruptible(struct device *dev, u8 bank, + u8 reg, u8 bitmask, u8 bitvalues) +{ + struct abx500_ops *ops; + + lookup_ops(dev->parent, &ops); + if ((ops != NULL) && (ops->mask_and_set_register != NULL)) + return ops->mask_and_set_register(dev, bank, + reg, bitmask, bitvalues); + else + return -ENOTSUPP; +} +EXPORT_SYMBOL(abx500_mask_and_set_register_interruptible); + +int abx500_get_chip_id(struct device *dev) +{ + struct abx500_ops *ops; + + lookup_ops(dev->parent, &ops); + if ((ops != NULL) && (ops->get_chip_id != NULL)) + return ops->get_chip_id(dev); + else + return -ENOTSUPP; +} +EXPORT_SYMBOL(abx500_get_chip_id); + +int abx500_event_registers_startup_state_get(struct device *dev, u8 *event) +{ + struct abx500_ops *ops; + + lookup_ops(dev->parent, &ops); + if ((ops != NULL) && (ops->event_registers_startup_state_get != NULL)) + return ops->event_registers_startup_state_get(dev, event); + else + return -ENOTSUPP; +} +EXPORT_SYMBOL(abx500_event_registers_startup_state_get); + +int abx500_startup_irq_enabled(struct device *dev, unsigned int irq) +{ + struct abx500_ops *ops; + + lookup_ops(dev->parent, &ops); + if ((ops != NULL) && (ops->startup_irq_enabled != NULL)) + return ops->startup_irq_enabled(dev, irq); + else + return -ENOTSUPP; +} +EXPORT_SYMBOL(abx500_startup_irq_enabled); + +MODULE_AUTHOR("Mattias Wallin "); +MODULE_DESCRIPTION("ABX500 core driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index 04ca7f62c57e..7b14a67bdca2 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c @@ -41,7 +41,7 @@ * struct ab3100_regulator * A struct passed around the individual regulator functions * @platform_device: platform device holding this regulator - * @ab3100: handle to the AB3100 parent chip + * @dev: handle to the device * @plfdata: AB3100 platform data passed in at probe time * @regreg: regulator register number in the AB3100 * @fixed_voltage: a fixed voltage for this regulator, if this @@ -52,7 +52,7 @@ */ struct ab3100_regulator { struct regulator_dev *rdev; - struct ab3100 *ab3100; + struct device *dev; struct ab3100_platform_data *plfdata; u8 regreg; int fixed_voltage; @@ -183,7 +183,7 @@ static int ab3100_enable_regulator(struct regulator_dev *reg) int err; u8 regval; - err = ab3100_get_register_interruptible(abreg->ab3100, abreg->regreg, + err = abx500_get_register_interruptible(abreg->dev, 0, abreg->regreg, ®val); if (err) { dev_warn(®->dev, "failed to get regid %d value\n", @@ -197,7 +197,7 @@ static int ab3100_enable_regulator(struct regulator_dev *reg) regval |= AB3100_REG_ON_MASK; - err = ab3100_set_register_interruptible(abreg->ab3100, abreg->regreg, + err = abx500_set_register_interruptible(abreg->dev, 0, abreg->regreg, regval); if (err) { dev_warn(®->dev, "failed to set regid %d value\n", @@ -245,14 +245,14 @@ static int ab3100_disable_regulator(struct regulator_dev *reg) if (abreg->regreg == AB3100_LDO_D) { dev_info(®->dev, "disabling LDO D - shut down system\n"); /* Setting LDO D to 0x00 cuts the power to the SoC */ - return ab3100_set_register_interruptible(abreg->ab3100, + return abx500_set_register_interruptible(abreg->dev, 0, AB3100_LDO_D, 0x00U); } /* * All other regulators are handled here */ - err = ab3100_get_register_interruptible(abreg->ab3100, abreg->regreg, + err = abx500_get_register_interruptible(abreg->dev, 0, abreg->regreg, ®val); if (err) { dev_err(®->dev, "unable to get register 0x%x\n", @@ -260,7 +260,7 @@ static int ab3100_disable_regulator(struct regulator_dev *reg) return err; } regval &= ~AB3100_REG_ON_MASK; - return ab3100_set_register_interruptible(abreg->ab3100, abreg->regreg, + return abx500_set_register_interruptible(abreg->dev, 0, abreg->regreg, regval); } @@ -270,7 +270,7 @@ static int ab3100_is_enabled_regulator(struct regulator_dev *reg) u8 regval; int err; - err = ab3100_get_register_interruptible(abreg->ab3100, abreg->regreg, + err = abx500_get_register_interruptible(abreg->dev, 0, abreg->regreg, ®val); if (err) { dev_err(®->dev, "unable to get register 0x%x\n", @@ -305,7 +305,7 @@ static int ab3100_get_voltage_regulator(struct regulator_dev *reg) * For variable types, read out setting and index into * supplied voltage list. */ - err = ab3100_get_register_interruptible(abreg->ab3100, + err = abx500_get_register_interruptible(abreg->dev, 0, abreg->regreg, ®val); if (err) { dev_warn(®->dev, @@ -373,7 +373,7 @@ static int ab3100_set_voltage_regulator(struct regulator_dev *reg, if (bestindex < 0) return bestindex; - err = ab3100_get_register_interruptible(abreg->ab3100, + err = abx500_get_register_interruptible(abreg->dev, 0, abreg->regreg, ®val); if (err) { dev_warn(®->dev, @@ -386,7 +386,7 @@ static int ab3100_set_voltage_regulator(struct regulator_dev *reg, regval &= ~0xE0; regval |= (bestindex << 5); - err = ab3100_set_register_interruptible(abreg->ab3100, + err = abx500_set_register_interruptible(abreg->dev, 0, abreg->regreg, regval); if (err) dev_warn(®->dev, "failed to set regulator register %02x\n", @@ -414,7 +414,7 @@ static int ab3100_set_suspend_voltage_regulator(struct regulator_dev *reg, /* LDO E and BUCK have special suspend voltages you can set */ bestindex = ab3100_get_best_voltage_index(reg, uV, uV); - err = ab3100_get_register_interruptible(abreg->ab3100, + err = abx500_get_register_interruptible(abreg->dev, 0, targetreg, ®val); if (err) { dev_warn(®->dev, @@ -427,7 +427,7 @@ static int ab3100_set_suspend_voltage_regulator(struct regulator_dev *reg, regval &= ~0xE0; regval |= (bestindex << 5); - err = ab3100_set_register_interruptible(abreg->ab3100, + err = abx500_set_register_interruptible(abreg->dev, 0, targetreg, regval); if (err) dev_warn(®->dev, "failed to set regulator register %02x\n", @@ -574,13 +574,12 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { static int __devinit ab3100_regulators_probe(struct platform_device *pdev) { struct ab3100_platform_data *plfdata = pdev->dev.platform_data; - struct ab3100 *ab3100 = platform_get_drvdata(pdev); int err = 0; u8 data; int i; /* Check chip state */ - err = ab3100_get_register_interruptible(ab3100, + err = abx500_get_register_interruptible(&pdev->dev, 0, AB3100_LDO_D, &data); if (err) { dev_err(&pdev->dev, "could not read initial status of LDO_D\n"); @@ -595,7 +594,7 @@ static int __devinit ab3100_regulators_probe(struct platform_device *pdev) /* Set up regulators */ for (i = 0; i < ARRAY_SIZE(ab3100_reg_init_order); i++) { - err = ab3100_set_register_interruptible(ab3100, + err = abx500_set_register_interruptible(&pdev->dev, 0, ab3100_reg_init_order[i], plfdata->reg_initvals[i]); if (err) { @@ -617,7 +616,7 @@ static int __devinit ab3100_regulators_probe(struct platform_device *pdev) * see what it looks like for a certain machine, go * into the machine I2C setup. */ - reg->ab3100 = ab3100; + reg->dev = &pdev->dev; reg->plfdata = plfdata; /* diff --git a/drivers/rtc/rtc-ab3100.c b/drivers/rtc/rtc-ab3100.c index b46b85d581b0..d26780ea254b 100644 --- a/drivers/rtc/rtc-ab3100.c +++ b/drivers/rtc/rtc-ab3100.c @@ -45,7 +45,6 @@ */ static int ab3100_rtc_set_mmss(struct device *dev, unsigned long secs) { - struct ab3100 *ab3100_data = dev_get_drvdata(dev); u8 regs[] = {AB3100_TI0, AB3100_TI1, AB3100_TI2, AB3100_TI3, AB3100_TI4, AB3100_TI5}; unsigned char buf[6]; @@ -61,27 +60,26 @@ static int ab3100_rtc_set_mmss(struct device *dev, unsigned long secs) buf[5] = (fat_time >> 40) & 0xFF; for (i = 0; i < 6; i++) { - err = ab3100_set_register_interruptible(ab3100_data, + err = abx500_set_register_interruptible(dev, 0, regs[i], buf[i]); if (err) return err; } /* Set the flag to mark that the clock is now set */ - return ab3100_mask_and_set_register_interruptible(ab3100_data, + return abx500_mask_and_set_register_interruptible(dev, 0, AB3100_RTC, - 0xFE, 0x01); + 0x01, 0x01); } static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm) { - struct ab3100 *ab3100_data = dev_get_drvdata(dev); unsigned long time; u8 rtcval; int err; - err = ab3100_get_register_interruptible(ab3100_data, + err = abx500_get_register_interruptible(dev, 0, AB3100_RTC, &rtcval); if (err) return err; @@ -94,7 +92,7 @@ static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm) u8 buf[6]; /* Read out time registers */ - err = ab3100_get_register_page_interruptible(ab3100_data, + err = abx500_get_register_page_interruptible(dev, 0, AB3100_TI0, buf, 6); if (err != 0) @@ -114,7 +112,6 @@ static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm) static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) { - struct ab3100 *ab3100_data = dev_get_drvdata(dev); unsigned long time; u64 fat_time; u8 buf[6]; @@ -122,7 +119,7 @@ static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) int err; /* Figure out if alarm is enabled or not */ - err = ab3100_get_register_interruptible(ab3100_data, + err = abx500_get_register_interruptible(dev, 0, AB3100_RTC, &rtcval); if (err) return err; @@ -133,7 +130,7 @@ static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) /* No idea how this could be represented */ alarm->pending = 0; /* Read out alarm registers, only 4 bytes */ - err = ab3100_get_register_page_interruptible(ab3100_data, + err = abx500_get_register_page_interruptible(dev, 0, AB3100_AL0, buf, 4); if (err) return err; @@ -148,7 +145,6 @@ static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) static int ab3100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) { - struct ab3100 *ab3100_data = dev_get_drvdata(dev); u8 regs[] = {AB3100_AL0, AB3100_AL1, AB3100_AL2, AB3100_AL3}; unsigned char buf[4]; unsigned long secs; @@ -165,21 +161,19 @@ static int ab3100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) /* Set the alarm */ for (i = 0; i < 4; i++) { - err = ab3100_set_register_interruptible(ab3100_data, + err = abx500_set_register_interruptible(dev, 0, regs[i], buf[i]); if (err) return err; } /* Then enable the alarm */ - return ab3100_mask_and_set_register_interruptible(ab3100_data, - AB3100_RTC, ~(1 << 2), + return abx500_mask_and_set_register_interruptible(dev, 0, + AB3100_RTC, (1 << 2), alarm->enabled << 2); } static int ab3100_rtc_irq_enable(struct device *dev, unsigned int enabled) { - struct ab3100 *ab3100_data = dev_get_drvdata(dev); - /* * It's not possible to enable/disable the alarm IRQ for this RTC. * It does not actually trigger any IRQ: instead its only function is @@ -188,12 +182,12 @@ static int ab3100_rtc_irq_enable(struct device *dev, unsigned int enabled) * and need to be handled there instead. */ if (enabled) - return ab3100_mask_and_set_register_interruptible(ab3100_data, - AB3100_RTC, ~(1 << 2), + return abx500_mask_and_set_register_interruptible(dev, 0, + AB3100_RTC, (1 << 2), 1 << 2); else - return ab3100_mask_and_set_register_interruptible(ab3100_data, - AB3100_RTC, ~(1 << 2), + return abx500_mask_and_set_register_interruptible(dev, 0, + AB3100_RTC, (1 << 2), 0); } @@ -210,10 +204,9 @@ static int __init ab3100_rtc_probe(struct platform_device *pdev) int err; u8 regval; struct rtc_device *rtc; - struct ab3100 *ab3100_data = platform_get_drvdata(pdev); /* The first RTC register needs special treatment */ - err = ab3100_get_register_interruptible(ab3100_data, + err = abx500_get_register_interruptible(&pdev->dev, 0, AB3100_RTC, ®val); if (err) { dev_err(&pdev->dev, "unable to read RTC register\n"); @@ -231,7 +224,7 @@ static int __init ab3100_rtc_probe(struct platform_device *pdev) * This bit remains until RTC power is lost. */ regval = 1 | RTC_SETTING; - err = ab3100_set_register_interruptible(ab3100_data, + err = abx500_set_register_interruptible(&pdev->dev, 0, AB3100_RTC, regval); /* Ignore any error on this write */ } diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h index 9a881c305a50..390726fcbcb1 100644 --- a/include/linux/mfd/abx500.h +++ b/include/linux/mfd/abx500.h @@ -3,17 +3,37 @@ * License terms: GNU General Public License (GPL) version 2 * AB3100 core access functions * Author: Linus Walleij + * + * ABX500 core access functions. + * The abx500 interface is used for the Analog Baseband chip + * ab3100, ab3550, ab5500 and possibly comming. It is not used for + * ab4500 and ab8500 since they are another family of chip. + * + * Author: Mattias Wallin + * Author: Mattias Nilsson + * Author: Bengt Jonsson + * Author: Rickard Andersson */ #include #include -#ifndef MFD_AB3100_H -#define MFD_AB3100_H +#ifndef MFD_ABX500_H +#define MFD_ABX500_H -#define ABUNKNOWN 0 -#define AB3000 1 -#define AB3100 2 +#define AB3100_P1A 0xc0 +#define AB3100_P1B 0xc1 +#define AB3100_P1C 0xc2 +#define AB3100_P1D 0xc3 +#define AB3100_P1E 0xc4 +#define AB3100_P1F 0xc5 +#define AB3100_P1G 0xc6 +#define AB3100_R2A 0xc7 +#define AB3100_R2B 0xc8 +#define AB3550_P1A 0x10 +#define AB5500_1_0 0x20 +#define AB5500_2_0 0x21 +#define AB5500_2_1 0x22 /* * AB3100, EVENTA1, A2 and A3 event register flags @@ -89,7 +109,7 @@ struct ab3100 { char chip_name[32]; u8 chip_id; struct blocking_notifier_head event_subscribers; - u32 startup_events; + u8 startup_events[3]; bool startup_events_read; }; @@ -112,18 +132,102 @@ struct ab3100_platform_data { int external_voltage; }; -int ab3100_set_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 regval); -int ab3100_get_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 *regval); -int ab3100_get_register_page_interruptible(struct ab3100 *ab3100, - u8 first_reg, u8 *regvals, u8 numregs); -int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100, - u8 reg, u8 andmask, u8 ormask); -u8 ab3100_get_chip_type(struct ab3100 *ab3100); int ab3100_event_register(struct ab3100 *ab3100, struct notifier_block *nb); int ab3100_event_unregister(struct ab3100 *ab3100, struct notifier_block *nb); -int ab3100_event_registers_startup_state_get(struct ab3100 *ab3100, - u32 *fatevent); +/* AB3550, STR register flags */ +#define AB3550_STR_ONSWA (0x01) +#define AB3550_STR_ONSWB (0x02) +#define AB3550_STR_ONSWC (0x04) +#define AB3550_STR_DCIO (0x08) +#define AB3550_STR_BOOT_MODE (0x10) +#define AB3550_STR_SIM_OFF (0x20) +#define AB3550_STR_BATT_REMOVAL (0x40) +#define AB3550_STR_VBUS (0x80) + +/* Interrupt mask registers */ +#define AB3550_IMR1 0x29 +#define AB3550_IMR2 0x2a +#define AB3550_IMR3 0x2b +#define AB3550_IMR4 0x2c +#define AB3550_IMR5 0x2d + +enum ab3550_devid { + AB3550_DEVID_ADC, + AB3550_DEVID_DAC, + AB3550_DEVID_LEDS, + AB3550_DEVID_POWER, + AB3550_DEVID_REGULATORS, + AB3550_DEVID_SIM, + AB3550_DEVID_UART, + AB3550_DEVID_RTC, + AB3550_DEVID_CHARGER, + AB3550_DEVID_FUELGAUGE, + AB3550_DEVID_VIBRATOR, + AB3550_DEVID_CODEC, + AB3550_NUM_DEVICES, +}; + +/** + * struct abx500_init_setting + * Initial value of the registers for driver to use during setup. + */ +struct abx500_init_settings { + u8 bank; + u8 reg; + u8 setting; +}; + +/** + * struct ab3550_platform_data + * Data supplied to initialize board connections to the AB3550 + */ +struct ab3550_platform_data { + struct {unsigned int base; unsigned int count; } irq; + void *dev_data[AB3550_NUM_DEVICES]; + size_t dev_data_sz[AB3550_NUM_DEVICES]; + struct abx500_init_settings *init_settings; + unsigned int init_settings_sz; +}; + +int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg, + u8 value); +int abx500_get_register_interruptible(struct device *dev, u8 bank, u8 reg, + u8 *value); +int abx500_get_register_page_interruptible(struct device *dev, u8 bank, + u8 first_reg, u8 *regvals, u8 numregs); +int abx500_set_register_page_interruptible(struct device *dev, u8 bank, + u8 first_reg, u8 *regvals, u8 numregs); +/** + * abx500_mask_and_set_register_inerruptible() - Modifies selected bits of a + * target register + * + * @dev: The AB sub device. + * @bank: The i2c bank number. + * @bitmask: The bit mask to use. + * @bitvalues: The new bit values. + * + * Updates the value of an AB register: + * value -> ((value & ~bitmask) | (bitvalues & bitmask)) + */ +int abx500_mask_and_set_register_interruptible(struct device *dev, u8 bank, + u8 reg, u8 bitmask, u8 bitvalues); +int abx500_get_chip_id(struct device *dev); +int abx500_event_registers_startup_state_get(struct device *dev, u8 *event); +int abx500_startup_irq_enabled(struct device *dev, unsigned int irq); + +struct abx500_ops { + int (*get_chip_id) (struct device *); + int (*get_register) (struct device *, u8, u8, u8 *); + int (*set_register) (struct device *, u8, u8, u8); + int (*get_register_page) (struct device *, u8, u8, u8 *, u8); + int (*set_register_page) (struct device *, u8, u8, u8 *, u8); + int (*mask_and_set_register) (struct device *, u8, u8, u8, u8); + int (*event_registers_startup_state_get) (struct device *, u8 *); + int (*startup_irq_enabled) (struct device *, unsigned int); +}; + +int abx500_register_ops(struct device *core_dev, struct abx500_ops *ops); #endif -- cgit v1.2.3 From 09bcb3f3369e164bf51b3b566b865f2514b23e8c Mon Sep 17 00:00:00 2001 From: Mattias Wallin Date: Tue, 11 May 2010 00:25:29 +0200 Subject: mfd: AB3550 core driver This adds a core driver for the AB3550 mixed-signal circuit found in the ST-Ericsson U300 platforms. This driver is a singleton proxy for all access to the AB3550 sub functionality drivers which can be added on top of this one: RTC, regulators, battery and system power control, vibrator, LEDs and an ALSA codec. Signed-off-by: Mattias Wallin Signed-off-by: Linus Walleij Signed-off-by: Samuel Ortiz --- drivers/mfd/Kconfig | 14 + drivers/mfd/Makefile | 1 + drivers/mfd/ab3550-core.c | 1401 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1416 insertions(+) create mode 100644 drivers/mfd/ab3550-core.c (limited to 'drivers') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 1c3d737ec406..a20fa230d354 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -423,6 +423,20 @@ config AB4500_CORE read/write functions for the devices to get access to this chip. This chip embeds various other multimedia funtionalities as well. +config AB3550_CORE + bool "ST-Ericsson AB3550 Mixed Signal Circuit core functions" + select MFD_CORE + depends on I2C=y && GENERIC_HARDIRQS && ABX500_CORE + help + Select this to enable the AB3550 Mixed Signal IC core + functionality. This connects to a AB3550 on the I2C bus + and expose a number of symbols needed for dependent devices + to read and write registers and subscribe to events from + this multi-functional IC. This is needed to use other features + of the AB3550 such as battery-backed RTC, charging control, + LEDs, vibrator, system power and temperature, power management + and ALSA sound. + config MFD_TIMBERDALE tristate "Support for the Timberdale FPGA" select MFD_CORE diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 4b8ad04ff8e2..4c684c137d43 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -64,6 +64,7 @@ obj-$(CONFIG_ABX500_CORE) += abx500-core.o obj-$(CONFIG_AB3100_CORE) += ab3100-core.o obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o obj-$(CONFIG_AB4500_CORE) += ab4500-core.o +obj-$(CONFIG_AB3550_CORE) += ab3550-core.o obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o obj-$(CONFIG_PMIC_ADP5520) += adp5520.o obj-$(CONFIG_LPC_SCH) += lpc_sch.o diff --git a/drivers/mfd/ab3550-core.c b/drivers/mfd/ab3550-core.c new file mode 100644 index 000000000000..1060f8e1c40a --- /dev/null +++ b/drivers/mfd/ab3550-core.c @@ -0,0 +1,1401 @@ +/* + * Copyright (C) 2007-2010 ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + * Low-level core for exclusive access to the AB3550 IC on the I2C bus + * and some basic chip-configuration. + * Author: Bengt Jonsson + * Author: Mattias Nilsson + * Author: Mattias Wallin + * Author: Rickard Andersson + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define AB3550_NAME_STRING "ab3550" +#define AB3550_ID_FORMAT_STRING "AB3550 %s" +#define AB3550_NUM_BANKS 2 +#define AB3550_NUM_EVENT_REG 5 + +/* These are the only registers inside AB3550 used in this main file */ + +/* Chip ID register */ +#define AB3550_CID_REG 0x20 + +/* Interrupt event registers */ +#define AB3550_EVENT_BANK 0 +#define AB3550_EVENT_REG 0x22 + +/* Read/write operation values. */ +#define AB3550_PERM_RD (0x01) +#define AB3550_PERM_WR (0x02) + +/* Read/write permissions. */ +#define AB3550_PERM_RO (AB3550_PERM_RD) +#define AB3550_PERM_RW (AB3550_PERM_RD | AB3550_PERM_WR) + +/** + * struct ab3550 + * @access_mutex: lock out concurrent accesses to the AB registers + * @i2c_client: I2C client for this chip + * @chip_name: name of this chip variant + * @chip_id: 8 bit chip ID for this chip variant + * @mask_work: a worker for writing to mask registers + * @event_lock: a lock to protect the event_mask + * @event_mask: a local copy of the mask event registers + * @startup_events: a copy of the first reading of the event registers + * @startup_events_read: whether the first events have been read + */ +struct ab3550 { + struct mutex access_mutex; + struct i2c_client *i2c_client[AB3550_NUM_BANKS]; + char chip_name[32]; + u8 chip_id; + struct work_struct mask_work; + spinlock_t event_lock; + u8 event_mask[AB3550_NUM_EVENT_REG]; + u8 startup_events[AB3550_NUM_EVENT_REG]; + bool startup_events_read; +#ifdef CONFIG_DEBUG_FS + unsigned int debug_bank; + unsigned int debug_address; +#endif +}; + +/** + * struct ab3550_reg_range + * @first: the first address of the range + * @last: the last address of the range + * @perm: access permissions for the range + */ +struct ab3550_reg_range { + u8 first; + u8 last; + u8 perm; +}; + +/** + * struct ab3550_reg_ranges + * @count: the number of ranges in the list + * @range: the list of register ranges + */ +struct ab3550_reg_ranges { + u8 count; + const struct ab3550_reg_range *range; +}; + +/* + * Permissible register ranges for reading and writing per device and bank. + * + * The ranges must be listed in increasing address order, and no overlaps are + * allowed. It is assumed that write permission implies read permission + * (i.e. only RO and RW permissions should be used). Ranges with write + * permission must not be split up. + */ + +#define NO_RANGE {.count = 0, .range = NULL,} + +static struct +ab3550_reg_ranges ab3550_reg_ranges[AB3550_NUM_DEVICES][AB3550_NUM_BANKS] = { + [AB3550_DEVID_DAC] = { + NO_RANGE, + { + .count = 2, + .range = (struct ab3550_reg_range[]) { + { + .first = 0xb0, + .last = 0xba, + .perm = AB3550_PERM_RW, + }, + { + .first = 0xbc, + .last = 0xc3, + .perm = AB3550_PERM_RW, + }, + }, + }, + }, + [AB3550_DEVID_LEDS] = { + NO_RANGE, + { + .count = 2, + .range = (struct ab3550_reg_range[]) { + { + .first = 0x5a, + .last = 0x88, + .perm = AB3550_PERM_RW, + }, + { + .first = 0x8a, + .last = 0xad, + .perm = AB3550_PERM_RW, + }, + } + }, + }, + [AB3550_DEVID_POWER] = { + { + .count = 1, + .range = (struct ab3550_reg_range[]) { + { + .first = 0x21, + .last = 0x21, + .perm = AB3550_PERM_RO, + }, + } + }, + NO_RANGE, + }, + [AB3550_DEVID_REGULATORS] = { + { + .count = 1, + .range = (struct ab3550_reg_range[]) { + { + .first = 0x69, + .last = 0xa3, + .perm = AB3550_PERM_RW, + }, + } + }, + { + .count = 1, + .range = (struct ab3550_reg_range[]) { + { + .first = 0x14, + .last = 0x16, + .perm = AB3550_PERM_RW, + }, + } + }, + }, + [AB3550_DEVID_SIM] = { + { + .count = 1, + .range = (struct ab3550_reg_range[]) { + { + .first = 0x21, + .last = 0x21, + .perm = AB3550_PERM_RO, + }, + } + }, + { + .count = 1, + .range = (struct ab3550_reg_range[]) { + { + .first = 0x14, + .last = 0x17, + .perm = AB3550_PERM_RW, + }, + } + + }, + }, + [AB3550_DEVID_UART] = { + NO_RANGE, + NO_RANGE, + }, + [AB3550_DEVID_RTC] = { + { + .count = 1, + .range = (struct ab3550_reg_range[]) { + { + .first = 0x00, + .last = 0x0c, + .perm = AB3550_PERM_RW, + }, + } + }, + NO_RANGE, + }, + [AB3550_DEVID_CHARGER] = { + { + .count = 2, + .range = (struct ab3550_reg_range[]) { + { + .first = 0x10, + .last = 0x1a, + .perm = AB3550_PERM_RW, + }, + { + .first = 0x21, + .last = 0x21, + .perm = AB3550_PERM_RO, + }, + } + }, + NO_RANGE, + }, + [AB3550_DEVID_ADC] = { + NO_RANGE, + { + .count = 1, + .range = (struct ab3550_reg_range[]) { + { + .first = 0x20, + .last = 0x56, + .perm = AB3550_PERM_RW, + }, + + } + }, + }, + [AB3550_DEVID_FUELGAUGE] = { + { + .count = 1, + .range = (struct ab3550_reg_range[]) { + { + .first = 0x21, + .last = 0x21, + .perm = AB3550_PERM_RO, + }, + } + }, + { + .count = 1, + .range = (struct ab3550_reg_range[]) { + { + .first = 0x00, + .last = 0x0e, + .perm = AB3550_PERM_RW, + }, + } + }, + }, + [AB3550_DEVID_VIBRATOR] = { + NO_RANGE, + { + .count = 1, + .range = (struct ab3550_reg_range[]) { + { + .first = 0x10, + .last = 0x13, + .perm = AB3550_PERM_RW, + }, + + } + }, + }, + [AB3550_DEVID_CODEC] = { + { + .count = 2, + .range = (struct ab3550_reg_range[]) { + { + .first = 0x31, + .last = 0x63, + .perm = AB3550_PERM_RW, + }, + { + .first = 0x65, + .last = 0x68, + .perm = AB3550_PERM_RW, + }, + } + }, + NO_RANGE, + }, +}; + +static struct mfd_cell ab3550_devs[AB3550_NUM_DEVICES] = { + [AB3550_DEVID_DAC] = { + .name = "ab3550-dac", + .id = AB3550_DEVID_DAC, + .num_resources = 0, + }, + [AB3550_DEVID_LEDS] = { + .name = "ab3550-leds", + .id = AB3550_DEVID_LEDS, + }, + [AB3550_DEVID_POWER] = { + .name = "ab3550-power", + .id = AB3550_DEVID_POWER, + }, + [AB3550_DEVID_REGULATORS] = { + .name = "ab3550-regulators", + .id = AB3550_DEVID_REGULATORS, + }, + [AB3550_DEVID_SIM] = { + .name = "ab3550-sim", + .id = AB3550_DEVID_SIM, + }, + [AB3550_DEVID_UART] = { + .name = "ab3550-uart", + .id = AB3550_DEVID_UART, + }, + [AB3550_DEVID_RTC] = { + .name = "ab3550-rtc", + .id = AB3550_DEVID_RTC, + }, + [AB3550_DEVID_CHARGER] = { + .name = "ab3550-charger", + .id = AB3550_DEVID_CHARGER, + }, + [AB3550_DEVID_ADC] = { + .name = "ab3550-adc", + .id = AB3550_DEVID_ADC, + .num_resources = 10, + .resources = (struct resource[]) { + { + .name = "TRIGGER-0", + .flags = IORESOURCE_IRQ, + .start = 16, + .end = 16, + }, + { + .name = "TRIGGER-1", + .flags = IORESOURCE_IRQ, + .start = 17, + .end = 17, + }, + { + .name = "TRIGGER-2", + .flags = IORESOURCE_IRQ, + .start = 18, + .end = 18, + }, + { + .name = "TRIGGER-3", + .flags = IORESOURCE_IRQ, + .start = 19, + .end = 19, + }, + { + .name = "TRIGGER-4", + .flags = IORESOURCE_IRQ, + .start = 20, + .end = 20, + }, + { + .name = "TRIGGER-5", + .flags = IORESOURCE_IRQ, + .start = 21, + .end = 21, + }, + { + .name = "TRIGGER-6", + .flags = IORESOURCE_IRQ, + .start = 22, + .end = 22, + }, + { + .name = "TRIGGER-7", + .flags = IORESOURCE_IRQ, + .start = 23, + .end = 23, + }, + { + .name = "TRIGGER-VBAT-TXON", + .flags = IORESOURCE_IRQ, + .start = 13, + .end = 13, + }, + { + .name = "TRIGGER-VBAT", + .flags = IORESOURCE_IRQ, + .start = 12, + .end = 12, + }, + }, + }, + [AB3550_DEVID_FUELGAUGE] = { + .name = "ab3550-fuelgauge", + .id = AB3550_DEVID_FUELGAUGE, + }, + [AB3550_DEVID_VIBRATOR] = { + .name = "ab3550-vibrator", + .id = AB3550_DEVID_VIBRATOR, + }, + [AB3550_DEVID_CODEC] = { + .name = "ab3550-codec", + .id = AB3550_DEVID_CODEC, + }, +}; + +/* + * I2C transactions with error messages. + */ +static int ab3550_i2c_master_send(struct ab3550 *ab, u8 bank, u8 *data, + u8 count) +{ + int err; + + err = i2c_master_send(ab->i2c_client[bank], data, count); + if (err < 0) { + dev_err(&ab->i2c_client[0]->dev, "send error: %d\n", err); + return err; + } + return 0; +} + +static int ab3550_i2c_master_recv(struct ab3550 *ab, u8 bank, u8 *data, + u8 count) +{ + int err; + + err = i2c_master_recv(ab->i2c_client[bank], data, count); + if (err < 0) { + dev_err(&ab->i2c_client[0]->dev, "receive error: %d\n", err); + return err; + } + return 0; +} + +/* + * Functionality for getting/setting register values. + */ +static int get_register_interruptible(struct ab3550 *ab, u8 bank, u8 reg, + u8 *value) +{ + int err; + + err = mutex_lock_interruptible(&ab->access_mutex); + if (err) + return err; + + err = ab3550_i2c_master_send(ab, bank, ®, 1); + if (!err) + err = ab3550_i2c_master_recv(ab, bank, value, 1); + + mutex_unlock(&ab->access_mutex); + return err; +} + +static int get_register_page_interruptible(struct ab3550 *ab, u8 bank, + u8 first_reg, u8 *regvals, u8 numregs) +{ + int err; + + err = mutex_lock_interruptible(&ab->access_mutex); + if (err) + return err; + + err = ab3550_i2c_master_send(ab, bank, &first_reg, 1); + if (!err) + err = ab3550_i2c_master_recv(ab, bank, regvals, numregs); + + mutex_unlock(&ab->access_mutex); + return err; +} + +static int mask_and_set_register_interruptible(struct ab3550 *ab, u8 bank, + u8 reg, u8 bitmask, u8 bitvalues) +{ + int err = 0; + + if (likely(bitmask)) { + u8 reg_bits[2] = {reg, 0}; + + err = mutex_lock_interruptible(&ab->access_mutex); + if (err) + return err; + + if (bitmask == 0xFF) /* No need to read in this case. */ + reg_bits[1] = bitvalues; + else { /* Read and modify the register value. */ + u8 bits; + + err = ab3550_i2c_master_send(ab, bank, ®, 1); + if (err) + goto unlock_and_return; + err = ab3550_i2c_master_recv(ab, bank, &bits, 1); + if (err) + goto unlock_and_return; + reg_bits[1] = ((~bitmask & bits) | + (bitmask & bitvalues)); + } + /* Write the new value. */ + err = ab3550_i2c_master_send(ab, bank, reg_bits, 2); +unlock_and_return: + mutex_unlock(&ab->access_mutex); + } + return err; +} + +/* + * Read/write permission checking functions. + */ +static bool page_write_allowed(const struct ab3550_reg_ranges *ranges, + u8 first_reg, u8 last_reg) +{ + u8 i; + + if (last_reg < first_reg) + return false; + + for (i = 0; i < ranges->count; i++) { + if (first_reg < ranges->range[i].first) + break; + if ((last_reg <= ranges->range[i].last) && + (ranges->range[i].perm & AB3550_PERM_WR)) + return true; + } + return false; +} + +static bool reg_write_allowed(const struct ab3550_reg_ranges *ranges, u8 reg) +{ + return page_write_allowed(ranges, reg, reg); +} + +static bool page_read_allowed(const struct ab3550_reg_ranges *ranges, + u8 first_reg, u8 last_reg) +{ + u8 i; + + if (last_reg < first_reg) + return false; + /* Find the range (if it exists in the list) that includes first_reg. */ + for (i = 0; i < ranges->count; i++) { + if (first_reg < ranges->range[i].first) + return false; + if (first_reg <= ranges->range[i].last) + break; + } + /* Make sure that the entire range up to and including last_reg is + * readable. This may span several of the ranges in the list. + */ + while ((i < ranges->count) && + (ranges->range[i].perm & AB3550_PERM_RD)) { + if (last_reg <= ranges->range[i].last) + return true; + if ((++i >= ranges->count) || + (ranges->range[i].first != + (ranges->range[i - 1].last + 1))) { + break; + } + } + return false; +} + +static bool reg_read_allowed(const struct ab3550_reg_ranges *ranges, u8 reg) +{ + return page_read_allowed(ranges, reg, reg); +} + +/* + * The exported register access functionality. + */ +int ab3550_get_chip_id(struct device *dev) +{ + struct ab3550 *ab = dev_get_drvdata(dev->parent); + return (int)ab->chip_id; +} + +int ab3550_mask_and_set_register_interruptible(struct device *dev, u8 bank, + u8 reg, u8 bitmask, u8 bitvalues) +{ + struct ab3550 *ab; + struct platform_device *pdev = to_platform_device(dev); + + if ((AB3550_NUM_BANKS <= bank) || + !reg_write_allowed(&ab3550_reg_ranges[pdev->id][bank], reg)) + return -EINVAL; + + ab = dev_get_drvdata(dev->parent); + return mask_and_set_register_interruptible(ab, bank, reg, + bitmask, bitvalues); +} + +int ab3550_set_register_interruptible(struct device *dev, u8 bank, u8 reg, + u8 value) +{ + return ab3550_mask_and_set_register_interruptible(dev, bank, reg, 0xFF, + value); +} + +int ab3550_get_register_interruptible(struct device *dev, u8 bank, u8 reg, + u8 *value) +{ + struct ab3550 *ab; + struct platform_device *pdev = to_platform_device(dev); + + if ((AB3550_NUM_BANKS <= bank) || + !reg_read_allowed(&ab3550_reg_ranges[pdev->id][bank], reg)) + return -EINVAL; + + ab = dev_get_drvdata(dev->parent); + return get_register_interruptible(ab, bank, reg, value); +} + +int ab3550_get_register_page_interruptible(struct device *dev, u8 bank, + u8 first_reg, u8 *regvals, u8 numregs) +{ + struct ab3550 *ab; + struct platform_device *pdev = to_platform_device(dev); + + if ((AB3550_NUM_BANKS <= bank) || + !page_read_allowed(&ab3550_reg_ranges[pdev->id][bank], + first_reg, (first_reg + numregs - 1))) + return -EINVAL; + + ab = dev_get_drvdata(dev->parent); + return get_register_page_interruptible(ab, bank, first_reg, regvals, + numregs); +} + +int ab3550_event_registers_startup_state_get(struct device *dev, u8 *event) +{ + struct ab3550 *ab; + + ab = dev_get_drvdata(dev->parent); + if (!ab->startup_events_read) + return -EAGAIN; /* Try again later */ + + memcpy(event, ab->startup_events, AB3550_NUM_EVENT_REG); + return 0; +} + +int ab3550_startup_irq_enabled(struct device *dev, unsigned int irq) +{ + struct ab3550 *ab; + struct ab3550_platform_data *plf_data; + bool val; + + ab = get_irq_chip_data(irq); + plf_data = ab->i2c_client[0]->dev.platform_data; + irq -= plf_data->irq.base; + val = ((ab->startup_events[irq / 8] & BIT(irq % 8)) != 0); + + return val; +} + +static struct abx500_ops ab3550_ops = { + .get_chip_id = ab3550_get_chip_id, + .get_register = ab3550_get_register_interruptible, + .set_register = ab3550_set_register_interruptible, + .get_register_page = ab3550_get_register_page_interruptible, + .set_register_page = NULL, + .mask_and_set_register = ab3550_mask_and_set_register_interruptible, + .event_registers_startup_state_get = + ab3550_event_registers_startup_state_get, + .startup_irq_enabled = ab3550_startup_irq_enabled, +}; + +static irqreturn_t ab3550_irq_handler(int irq, void *data) +{ + struct ab3550 *ab = data; + int err; + unsigned int i; + u8 e[AB3550_NUM_EVENT_REG]; + u8 *events; + unsigned long flags; + + events = (ab->startup_events_read ? e : ab->startup_events); + + err = get_register_page_interruptible(ab, AB3550_EVENT_BANK, + AB3550_EVENT_REG, events, AB3550_NUM_EVENT_REG); + if (err) + goto err_event_rd; + + if (!ab->startup_events_read) { + dev_info(&ab->i2c_client[0]->dev, + "startup events 0x%x,0x%x,0x%x,0x%x,0x%x\n", + ab->startup_events[0], ab->startup_events[1], + ab->startup_events[2], ab->startup_events[3], + ab->startup_events[4]); + ab->startup_events_read = true; + goto out; + } + + /* The two highest bits in event[4] are not used. */ + events[4] &= 0x3f; + + spin_lock_irqsave(&ab->event_lock, flags); + for (i = 0; i < AB3550_NUM_EVENT_REG; i++) + events[i] &= ~ab->event_mask[i]; + spin_unlock_irqrestore(&ab->event_lock, flags); + + for (i = 0; i < AB3550_NUM_EVENT_REG; i++) { + u8 bit; + u8 event_reg; + + dev_dbg(&ab->i2c_client[0]->dev, "IRQ Event[%d]: 0x%2x\n", + i, events[i]); + + event_reg = events[i]; + for (bit = 0; event_reg; bit++, event_reg /= 2) { + if (event_reg % 2) { + unsigned int irq; + struct ab3550_platform_data *plf_data; + + plf_data = ab->i2c_client[0]->dev.platform_data; + irq = plf_data->irq.base + (i * 8) + bit; + handle_nested_irq(irq); + } + } + } +out: + return IRQ_HANDLED; + +err_event_rd: + dev_dbg(&ab->i2c_client[0]->dev, "error reading event registers\n"); + return IRQ_HANDLED; +} + +#ifdef CONFIG_DEBUG_FS +static struct ab3550_reg_ranges debug_ranges[AB3550_NUM_BANKS] = { + { + .count = 6, + .range = (struct ab3550_reg_range[]) { + { + .first = 0x00, + .last = 0x0e, + }, + { + .first = 0x10, + .last = 0x1a, + }, + { + .first = 0x1e, + .last = 0x4f, + }, + { + .first = 0x51, + .last = 0x63, + }, + { + .first = 0x65, + .last = 0xa3, + }, + { + .first = 0xa5, + .last = 0xa8, + }, + } + }, + { + .count = 8, + .range = (struct ab3550_reg_range[]) { + { + .first = 0x00, + .last = 0x0e, + }, + { + .first = 0x10, + .last = 0x17, + }, + { + .first = 0x1a, + .last = 0x1c, + }, + { + .first = 0x20, + .last = 0x56, + }, + { + .first = 0x5a, + .last = 0x88, + }, + { + .first = 0x8a, + .last = 0xad, + }, + { + .first = 0xb0, + .last = 0xba, + }, + { + .first = 0xbc, + .last = 0xc3, + }, + } + }, +}; + +static int ab3550_registers_print(struct seq_file *s, void *p) +{ + struct ab3550 *ab = s->private; + int bank; + + seq_printf(s, AB3550_NAME_STRING " register values:\n"); + + for (bank = 0; bank < AB3550_NUM_BANKS; bank++) { + unsigned int i; + + seq_printf(s, " bank %d:\n", bank); + for (i = 0; i < debug_ranges[bank].count; i++) { + u8 reg; + + for (reg = debug_ranges[bank].range[i].first; + reg <= debug_ranges[bank].range[i].last; + reg++) { + u8 value; + + get_register_interruptible(ab, bank, reg, + &value); + seq_printf(s, " [%d/0x%02X]: 0x%02X\n", bank, + reg, value); + } + } + } + return 0; +} + +static int ab3550_registers_open(struct inode *inode, struct file *file) +{ + return single_open(file, ab3550_registers_print, inode->i_private); +} + +static const struct file_operations ab3550_registers_fops = { + .open = ab3550_registers_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int ab3550_bank_print(struct seq_file *s, void *p) +{ + struct ab3550 *ab = s->private; + + seq_printf(s, "%d\n", ab->debug_bank); + return 0; +} + +static int ab3550_bank_open(struct inode *inode, struct file *file) +{ + return single_open(file, ab3550_bank_print, inode->i_private); +} + +static ssize_t ab3550_bank_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ab3550 *ab = ((struct seq_file *)(file->private_data))->private; + char buf[32]; + int buf_size; + unsigned long user_bank; + int err; + + /* Get userspace string and assure termination */ + buf_size = min(count, (sizeof(buf) - 1)); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + buf[buf_size] = 0; + + err = strict_strtoul(buf, 0, &user_bank); + if (err) + return -EINVAL; + + if (user_bank >= AB3550_NUM_BANKS) { + dev_err(&ab->i2c_client[0]->dev, + "debugfs error input > number of banks\n"); + return -EINVAL; + } + + ab->debug_bank = user_bank; + + return buf_size; +} + +static int ab3550_address_print(struct seq_file *s, void *p) +{ + struct ab3550 *ab = s->private; + + seq_printf(s, "0x%02X\n", ab->debug_address); + return 0; +} + +static int ab3550_address_open(struct inode *inode, struct file *file) +{ + return single_open(file, ab3550_address_print, inode->i_private); +} + +static ssize_t ab3550_address_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ab3550 *ab = ((struct seq_file *)(file->private_data))->private; + char buf[32]; + int buf_size; + unsigned long user_address; + int err; + + /* Get userspace string and assure termination */ + buf_size = min(count, (sizeof(buf) - 1)); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + buf[buf_size] = 0; + + err = strict_strtoul(buf, 0, &user_address); + if (err) + return -EINVAL; + if (user_address > 0xff) { + dev_err(&ab->i2c_client[0]->dev, + "debugfs error input > 0xff\n"); + return -EINVAL; + } + ab->debug_address = user_address; + return buf_size; +} + +static int ab3550_val_print(struct seq_file *s, void *p) +{ + struct ab3550 *ab = s->private; + int err; + u8 regvalue; + + err = get_register_interruptible(ab, (u8)ab->debug_bank, + (u8)ab->debug_address, ®value); + if (err) + return -EINVAL; + seq_printf(s, "0x%02X\n", regvalue); + + return 0; +} + +static int ab3550_val_open(struct inode *inode, struct file *file) +{ + return single_open(file, ab3550_val_print, inode->i_private); +} + +static ssize_t ab3550_val_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ab3550 *ab = ((struct seq_file *)(file->private_data))->private; + char buf[32]; + int buf_size; + unsigned long user_val; + int err; + u8 regvalue; + + /* Get userspace string and assure termination */ + buf_size = min(count, (sizeof(buf)-1)); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + buf[buf_size] = 0; + + err = strict_strtoul(buf, 0, &user_val); + if (err) + return -EINVAL; + if (user_val > 0xff) { + dev_err(&ab->i2c_client[0]->dev, + "debugfs error input > 0xff\n"); + return -EINVAL; + } + err = mask_and_set_register_interruptible( + ab, (u8)ab->debug_bank, + (u8)ab->debug_address, 0xFF, (u8)user_val); + if (err) + return -EINVAL; + + get_register_interruptible(ab, (u8)ab->debug_bank, + (u8)ab->debug_address, ®value); + if (err) + return -EINVAL; + + return buf_size; +} + +static const struct file_operations ab3550_bank_fops = { + .open = ab3550_bank_open, + .write = ab3550_bank_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static const struct file_operations ab3550_address_fops = { + .open = ab3550_address_open, + .write = ab3550_address_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static const struct file_operations ab3550_val_fops = { + .open = ab3550_val_open, + .write = ab3550_val_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static struct dentry *ab3550_dir; +static struct dentry *ab3550_reg_file; +static struct dentry *ab3550_bank_file; +static struct dentry *ab3550_address_file; +static struct dentry *ab3550_val_file; + +static inline void ab3550_setup_debugfs(struct ab3550 *ab) +{ + ab->debug_bank = 0; + ab->debug_address = 0x00; + + ab3550_dir = debugfs_create_dir(AB3550_NAME_STRING, NULL); + if (!ab3550_dir) + goto exit_no_debugfs; + + ab3550_reg_file = debugfs_create_file("all-registers", + S_IRUGO, ab3550_dir, ab, &ab3550_registers_fops); + if (!ab3550_reg_file) + goto exit_destroy_dir; + + ab3550_bank_file = debugfs_create_file("register-bank", + (S_IRUGO | S_IWUGO), ab3550_dir, ab, &ab3550_bank_fops); + if (!ab3550_bank_file) + goto exit_destroy_reg; + + ab3550_address_file = debugfs_create_file("register-address", + (S_IRUGO | S_IWUGO), ab3550_dir, ab, &ab3550_address_fops); + if (!ab3550_address_file) + goto exit_destroy_bank; + + ab3550_val_file = debugfs_create_file("register-value", + (S_IRUGO | S_IWUGO), ab3550_dir, ab, &ab3550_val_fops); + if (!ab3550_val_file) + goto exit_destroy_address; + + return; + +exit_destroy_address: + debugfs_remove(ab3550_address_file); +exit_destroy_bank: + debugfs_remove(ab3550_bank_file); +exit_destroy_reg: + debugfs_remove(ab3550_reg_file); +exit_destroy_dir: + debugfs_remove(ab3550_dir); +exit_no_debugfs: + dev_err(&ab->i2c_client[0]->dev, "failed to create debugfs entries.\n"); + return; +} + +static inline void ab3550_remove_debugfs(void) +{ + debugfs_remove(ab3550_val_file); + debugfs_remove(ab3550_address_file); + debugfs_remove(ab3550_bank_file); + debugfs_remove(ab3550_reg_file); + debugfs_remove(ab3550_dir); +} + +#else /* !CONFIG_DEBUG_FS */ +static inline void ab3550_setup_debugfs(struct ab3550 *ab) +{ +} +static inline void ab3550_remove_debugfs(void) +{ +} +#endif + +/* + * Basic set-up, datastructure creation/destruction and I2C interface. + * This sets up a default config in the AB3550 chip so that it + * will work as expected. + */ +static int __init ab3550_setup(struct ab3550 *ab) +{ + int err = 0; + int i; + struct ab3550_platform_data *plf_data; + struct abx500_init_settings *settings; + + plf_data = ab->i2c_client[0]->dev.platform_data; + settings = plf_data->init_settings; + + for (i = 0; i < plf_data->init_settings_sz; i++) { + err = mask_and_set_register_interruptible(ab, + settings[i].bank, + settings[i].reg, + 0xFF, settings[i].setting); + if (err) + goto exit_no_setup; + + /* If event mask register update the event mask in ab3550 */ + if ((settings[i].bank == 0) && + (AB3550_IMR1 <= settings[i].reg) && + (settings[i].reg <= AB3550_IMR5)) { + ab->event_mask[settings[i].reg - AB3550_IMR1] = + settings[i].setting; + } + } +exit_no_setup: + return err; +} + +static void ab3550_mask_work(struct work_struct *work) +{ + struct ab3550 *ab = container_of(work, struct ab3550, mask_work); + int i; + unsigned long flags; + u8 mask[AB3550_NUM_EVENT_REG]; + + spin_lock_irqsave(&ab->event_lock, flags); + for (i = 0; i < AB3550_NUM_EVENT_REG; i++) + mask[i] = ab->event_mask[i]; + spin_unlock_irqrestore(&ab->event_lock, flags); + + for (i = 0; i < AB3550_NUM_EVENT_REG; i++) { + int err; + + err = mask_and_set_register_interruptible(ab, 0, + (AB3550_IMR1 + i), ~0, mask[i]); + if (err) + dev_err(&ab->i2c_client[0]->dev, + "ab3550_mask_work failed 0x%x,0x%x\n", + (AB3550_IMR1 + i), mask[i]); + } +} + +static void ab3550_mask(unsigned int irq) +{ + unsigned long flags; + struct ab3550 *ab; + struct ab3550_platform_data *plf_data; + + ab = get_irq_chip_data(irq); + plf_data = ab->i2c_client[0]->dev.platform_data; + irq -= plf_data->irq.base; + + spin_lock_irqsave(&ab->event_lock, flags); + ab->event_mask[irq / 8] |= BIT(irq % 8); + spin_unlock_irqrestore(&ab->event_lock, flags); + + schedule_work(&ab->mask_work); +} + +static void ab3550_unmask(unsigned int irq) +{ + unsigned long flags; + struct ab3550 *ab; + struct ab3550_platform_data *plf_data; + + ab = get_irq_chip_data(irq); + plf_data = ab->i2c_client[0]->dev.platform_data; + irq -= plf_data->irq.base; + + spin_lock_irqsave(&ab->event_lock, flags); + ab->event_mask[irq / 8] &= ~BIT(irq % 8); + spin_unlock_irqrestore(&ab->event_lock, flags); + + schedule_work(&ab->mask_work); +} + +static void noop(unsigned int irq) +{ +} + +static struct irq_chip ab3550_irq_chip = { + .name = "ab3550-core", /* Keep the same name as the request */ + .startup = NULL, /* defaults to enable */ + .shutdown = NULL, /* defaults to disable */ + .enable = NULL, /* defaults to unmask */ + .disable = ab3550_mask, /* No default to mask in chip.c */ + .ack = noop, + .mask = ab3550_mask, + .unmask = ab3550_unmask, + .end = NULL, +}; + +struct ab_family_id { + u8 id; + char *name; +}; + +static const struct ab_family_id ids[] __initdata = { + /* AB3550 */ + { + .id = AB3550_P1A, + .name = "P1A" + }, + /* Terminator */ + { + .id = 0x00, + } +}; + +static int __init ab3550_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct ab3550 *ab; + struct ab3550_platform_data *ab3550_plf_data = + client->dev.platform_data; + int err; + int i; + int num_i2c_clients = 0; + + ab = kzalloc(sizeof(struct ab3550), GFP_KERNEL); + if (!ab) { + dev_err(&client->dev, + "could not allocate " AB3550_NAME_STRING " device\n"); + return -ENOMEM; + } + + /* Initialize data structure */ + mutex_init(&ab->access_mutex); + spin_lock_init(&ab->event_lock); + ab->i2c_client[0] = client; + + i2c_set_clientdata(client, ab); + + /* Read chip ID register */ + err = get_register_interruptible(ab, 0, AB3550_CID_REG, &ab->chip_id); + if (err) { + dev_err(&client->dev, "could not communicate with the analog " + "baseband chip\n"); + goto exit_no_detect; + } + + for (i = 0; ids[i].id != 0x0; i++) { + if (ids[i].id == ab->chip_id) { + snprintf(&ab->chip_name[0], sizeof(ab->chip_name) - 1, + AB3550_ID_FORMAT_STRING, ids[i].name); + break; + } + } + + if (ids[i].id == 0x0) { + dev_err(&client->dev, "unknown analog baseband chip id: 0x%x\n", + ab->chip_id); + dev_err(&client->dev, "driver not started!\n"); + goto exit_no_detect; + } + + dev_info(&client->dev, "detected AB chip: %s\n", &ab->chip_name[0]); + + /* Attach other dummy I2C clients. */ + while (++num_i2c_clients < AB3550_NUM_BANKS) { + ab->i2c_client[num_i2c_clients] = + i2c_new_dummy(client->adapter, + (client->addr + num_i2c_clients)); + if (!ab->i2c_client[num_i2c_clients]) { + err = -ENOMEM; + goto exit_no_dummy_client; + } + strlcpy(ab->i2c_client[num_i2c_clients]->name, id->name, + sizeof(ab->i2c_client[num_i2c_clients]->name)); + } + + err = ab3550_setup(ab); + if (err) + goto exit_no_setup; + + INIT_WORK(&ab->mask_work, ab3550_mask_work); + + for (i = 0; i < ab3550_plf_data->irq.count; i++) { + unsigned int irq; + + irq = ab3550_plf_data->irq.base + i; + set_irq_chip_data(irq, ab); + set_irq_chip_and_handler(irq, &ab3550_irq_chip, + handle_simple_irq); + set_irq_nested_thread(irq, 1); +#ifdef CONFIG_ARM + set_irq_flags(irq, IRQF_VALID); +#else + set_irq_noprobe(irq); +#endif + } + + err = request_threaded_irq(client->irq, NULL, ab3550_irq_handler, + IRQF_ONESHOT, "ab3550-core", ab); + /* This real unpredictable IRQ is of course sampled for entropy */ + rand_initialize_irq(client->irq); + + if (err) + goto exit_no_irq; + + err = abx500_register_ops(&client->dev, &ab3550_ops); + if (err) + goto exit_no_ops; + + /* Set up and register the platform devices. */ + for (i = 0; i < AB3550_NUM_DEVICES; i++) { + ab3550_devs[i].platform_data = ab3550_plf_data->dev_data[i]; + ab3550_devs[i].data_size = ab3550_plf_data->dev_data_sz[i]; + } + + err = mfd_add_devices(&client->dev, 0, ab3550_devs, + ARRAY_SIZE(ab3550_devs), NULL, + ab3550_plf_data->irq.base); + + ab3550_setup_debugfs(ab); + + return 0; + +exit_no_ops: +exit_no_irq: +exit_no_setup: +exit_no_dummy_client: + /* Unregister the dummy i2c clients. */ + while (--num_i2c_clients) + i2c_unregister_device(ab->i2c_client[num_i2c_clients]); +exit_no_detect: + kfree(ab); + return err; +} + +static int __exit ab3550_remove(struct i2c_client *client) +{ + struct ab3550 *ab = i2c_get_clientdata(client); + int num_i2c_clients = AB3550_NUM_BANKS; + + mfd_remove_devices(&client->dev); + ab3550_remove_debugfs(); + + while (--num_i2c_clients) + i2c_unregister_device(ab->i2c_client[num_i2c_clients]); + + /* + * At this point, all subscribers should have unregistered + * their notifiers so deactivate IRQ + */ + free_irq(client->irq, ab); + i2c_set_clientdata(client, NULL); + kfree(ab); + return 0; +} + +static const struct i2c_device_id ab3550_id[] = { + {AB3550_NAME_STRING, 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, ab3550_id); + +static struct i2c_driver ab3550_driver = { + .driver = { + .name = AB3550_NAME_STRING, + .owner = THIS_MODULE, + }, + .id_table = ab3550_id, + .probe = ab3550_probe, + .remove = __exit_p(ab3550_remove), +}; + +static int __init ab3550_i2c_init(void) +{ + return i2c_add_driver(&ab3550_driver); +} + +static void __exit ab3550_i2c_exit(void) +{ + i2c_del_driver(&ab3550_driver); +} + +subsys_initcall(ab3550_i2c_init); +module_exit(ab3550_i2c_exit); + +MODULE_AUTHOR("Mattias Wallin "); +MODULE_DESCRIPTION("AB3550 core driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 38270644cc2f2c1fdf150dcc8c4b96136eb4e1f7 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 11 May 2010 01:07:34 +0200 Subject: mfd: Use menuconfig for quicker config editing Change MFD 'menu' to 'menuconfig' to facilitate easy (one-click) disabling of all MFD drivers. Signed-off-by: Randy Dunlap Signed-off-by: Samuel Ortiz --- drivers/mfd/Kconfig | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index a20fa230d354..b84b7078e909 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -2,8 +2,14 @@ # Multifunction miscellaneous devices # -menu "Multifunction device drivers" +menuconfig MFD_SUPPORT + bool "Multifunction device drivers" depends on HAS_IOMEM + default y + help + Configure MFD device drivers. + +if MFD_SUPPORT config MFD_CORE tristate @@ -475,7 +481,7 @@ config MFD_JANZ_CMODIO host many different types of MODULbus daughterboards, including CAN and GPIO controllers. -endmenu +endif # MFD_SUPPORT menu "Multimedia Capabilities Port drivers" depends on ARCH_SA1100 -- cgit v1.2.3 From e4be3cb72ce40482a9fe19210ad5de8bfc061bb5 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 11 May 2010 13:24:20 -0700 Subject: gpio: rdc321x needs to select MFD_CORE Fix rdc321x-southbridge build: GPIO_RDC321X needs to select MFD_CORE so that the core is built at the same (or higher) tristate level. rdc321x-southbridge.c:(.devinit.text+0x6103): undefined reference to `mfd_add_devices' rdc321x-southbridge.c:(.devexit.text+0xe5f): undefined reference to `mfd_remove_devices' Signed-off-by: Randy Dunlap Cc: Florian Fainelli Signed-off-by: Samuel Ortiz --- drivers/gpio/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 1567605ab695..724038dab4ca 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -292,6 +292,7 @@ config GPIO_TIMBERDALE config GPIO_RDC321X tristate "RDC R-321x GPIO support" depends on PCI && GPIOLIB + select MFD_CORE select MFD_RDC321X help Support for the RDC R321x SoC GPIOs over southbridge -- cgit v1.2.3 From 0aeee5d4f6aa9bd28373907727937b7935d0434c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 12 May 2010 02:10:53 +0200 Subject: mfd: Fix pcf50633 bitfield logic in interrupt handler Those constants are alreay bitfields. Signed-off-by: Lars-Peter Clausen Signed-off-by: Samuel Ortiz --- drivers/mfd/pcf50633-core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 5439282804cc..37618b2be9a2 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -354,18 +354,18 @@ static void pcf50633_irq_worker(struct work_struct *work) if (pcf_int[0] & (PCF50633_INT1_USBINS | PCF50633_INT1_USBREM)) { chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2); if (chgstat & (0x3 << 4)) - pcf_int[0] &= ~(1 << PCF50633_INT1_USBREM); + pcf_int[0] &= ~PCF50633_INT1_USBREM; else - pcf_int[0] &= ~(1 << PCF50633_INT1_USBINS); + pcf_int[0] &= ~PCF50633_INT1_USBINS; } /* Make sure only one of ADPINS or ADPREM is set */ if (pcf_int[0] & (PCF50633_INT1_ADPINS | PCF50633_INT1_ADPREM)) { chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2); if (chgstat & (0x3 << 4)) - pcf_int[0] &= ~(1 << PCF50633_INT1_ADPREM); + pcf_int[0] &= ~PCF50633_INT1_ADPREM; else - pcf_int[0] &= ~(1 << PCF50633_INT1_ADPINS); + pcf_int[0] &= ~PCF50633_INT1_ADPINS; } dev_dbg(pcf->dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x " -- cgit v1.2.3 From 6438a694b670cd188c2fd2f75e0cd6b0ae21bea9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 12 May 2010 02:10:54 +0200 Subject: mfd: pcf50633-adc: Fix potential race in pcf50633_adc_sync_read Currently it's not guaranteed that request struct is not already freed when reading from it. Fix this by moving synced request related fields from the pcf50633_adc_request struct to its own struct and store it on the functions stack. Signed-off-by: Lars-Peter Clausen Signed-off-by: Samuel Ortiz --- drivers/mfd/pcf50633-adc.c | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/pcf50633-adc.c b/drivers/mfd/pcf50633-adc.c index fe8f922f6654..aed0d2a9b032 100644 --- a/drivers/mfd/pcf50633-adc.c +++ b/drivers/mfd/pcf50633-adc.c @@ -30,13 +30,13 @@ struct pcf50633_adc_request { int mux; int avg; - int result; void (*callback)(struct pcf50633 *, void *, int); void *callback_param; +}; - /* Used in case of sync requests */ +struct pcf50633_adc_sync_request { + int result; struct completion completion; - }; #define PCF50633_MAX_ADC_FIFO_DEPTH 8 @@ -109,10 +109,10 @@ adc_enqueue_request(struct pcf50633 *pcf, struct pcf50633_adc_request *req) return 0; } -static void -pcf50633_adc_sync_read_callback(struct pcf50633 *pcf, void *param, int result) +static void pcf50633_adc_sync_read_callback(struct pcf50633 *pcf, void *param, + int result) { - struct pcf50633_adc_request *req = param; + struct pcf50633_adc_sync_request *req = param; req->result = result; complete(&req->completion); @@ -120,28 +120,19 @@ pcf50633_adc_sync_read_callback(struct pcf50633 *pcf, void *param, int result) int pcf50633_adc_sync_read(struct pcf50633 *pcf, int mux, int avg) { - struct pcf50633_adc_request *req; - int err; + struct pcf50633_adc_sync_request req; + int ret; - /* req is freed when the result is ready, in interrupt handler */ - req = kzalloc(sizeof(*req), GFP_KERNEL); - if (!req) - return -ENOMEM; - - req->mux = mux; - req->avg = avg; - req->callback = pcf50633_adc_sync_read_callback; - req->callback_param = req; + init_completion(&req.completion); - init_completion(&req->completion); - err = adc_enqueue_request(pcf, req); - if (err) - return err; + ret = pcf50633_adc_async_read(pcf, mux, avg, + pcf50633_adc_sync_read_callback, &req); + if (ret) + return ret; - wait_for_completion(&req->completion); + wait_for_completion(&req.completion); - /* FIXME by this time req might be already freed */ - return req->result; + return req.result; } EXPORT_SYMBOL_GPL(pcf50633_adc_sync_read); -- cgit v1.2.3 From f7b2a77fe6f7b13b9cbf1909f032adef0be63ce1 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 12 May 2010 02:10:55 +0200 Subject: mfd: Use threaded irq for pcf50633 Use threaded oneshot irq handler instead of normal irq handler and a workqueue. Signed-off-by: Lars-Peter Clausen Signed-off-by: Samuel Ortiz --- drivers/mfd/Makefile | 2 +- drivers/mfd/pcf50633-core.c | 57 +++++++-------------------------------------- 2 files changed, 10 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 4c684c137d43..85934966a593 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -57,7 +57,7 @@ obj-$(CONFIG_PMIC_DA903X) += da903x.o max8925-objs := max8925-core.o max8925-i2c.o obj-$(CONFIG_MFD_MAX8925) += max8925.o -obj-$(CONFIG_MFD_PCF50633) += pcf50633-core.o +obj-$(CONFIG_MFD_PCF50633) += pcf50633-core.o pcf50633-irq.o obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o obj-$(CONFIG_ABX500_CORE) += abx500-core.o diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 37618b2be9a2..b3bef4998744 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -325,14 +325,12 @@ static void pcf50633_irq_call_handler(struct pcf50633 *pcf, int irq) /* Maximum amount of time ONKEY is held before emergency action is taken */ #define PCF50633_ONKEY1S_TIMEOUT 8 -static void pcf50633_irq_worker(struct work_struct *work) +static irqreturn_t pcf50633_irq(int irq, void *data) { - struct pcf50633 *pcf; + struct pcf50633 *pcf = data; int ret, i, j; u8 pcf_int[5], chgstat; - pcf = container_of(work, struct pcf50633, irq_work); - /* Read the 5 INT regs in one transaction */ ret = pcf50633_read_block(pcf, PCF50633_REG_INT1, ARRAY_SIZE(pcf_int), pcf_int); @@ -436,21 +434,7 @@ static void pcf50633_irq_worker(struct work_struct *work) } out: - put_device(pcf->dev); - enable_irq(pcf->irq); -} - -static irqreturn_t pcf50633_irq(int irq, void *data) -{ - struct pcf50633 *pcf = data; - - dev_dbg(pcf->dev, "pcf50633_irq\n"); - - get_device(pcf->dev); - disable_irq_nosync(pcf->irq); - queue_work(pcf->work_queue, &pcf->irq_work); - - return IRQ_HANDLED; + return IRQ_HANDLED } static void @@ -488,9 +472,6 @@ static int pcf50633_suspend(struct i2c_client *client, pm_message_t state) * henceforth */ disable_irq(pcf->irq); - /* Make sure that any running IRQ worker has quit */ - cancel_work_sync(&pcf->irq_work); - /* Save the masks */ ret = pcf50633_read_block(pcf, PCF50633_REG_INT1M, ARRAY_SIZE(pcf->suspend_irq_masks), @@ -531,16 +512,7 @@ static int pcf50633_resume(struct i2c_client *client) if (ret < 0) dev_err(pcf->dev, "Error restoring saved suspend masks\n"); - /* Restore regulators' state */ - - - get_device(pcf->dev); - - /* - * Clear any pending interrupts and set resume reason if any. - * This will leave with enable_irq() - */ - pcf50633_irq_worker(&pcf->irq_work); + enable_irq(pcf->irq); return 0; } @@ -574,22 +546,13 @@ static int __devinit pcf50633_probe(struct i2c_client *client, pcf->dev = &client->dev; pcf->i2c_client = client; pcf->irq = client->irq; - pcf->work_queue = create_singlethread_workqueue("pcf50633"); - - if (!pcf->work_queue) { - dev_err(&client->dev, "Failed to alloc workqueue\n"); - ret = -ENOMEM; - goto err_free; - } - - INIT_WORK(&pcf->irq_work, pcf50633_irq_worker); version = pcf50633_reg_read(pcf, 0); variant = pcf50633_reg_read(pcf, 1); if (version < 0 || variant < 0) { dev_err(pcf->dev, "Unable to probe pcf50633\n"); ret = -ENODEV; - goto err_destroy_workqueue; + goto err_free; } dev_info(pcf->dev, "Probed device version %d variant %d\n", @@ -603,12 +566,13 @@ static int __devinit pcf50633_probe(struct i2c_client *client, pcf50633_reg_write(pcf, PCF50633_REG_INT4M, 0x00); pcf50633_reg_write(pcf, PCF50633_REG_INT5M, 0x00); - ret = request_irq(client->irq, pcf50633_irq, - IRQF_TRIGGER_LOW, "pcf50633", pcf); + ret = request_threaded_irq(client->irq, NULL, pcf50633_irq, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + "pcf50633", pcf); if (ret) { dev_err(pcf->dev, "Failed to request IRQ %d\n", ret); - goto err_destroy_workqueue; + goto err_free; } /* Create sub devices */ @@ -654,8 +618,6 @@ static int __devinit pcf50633_probe(struct i2c_client *client, return 0; -err_destroy_workqueue: - destroy_workqueue(pcf->work_queue); err_free: i2c_set_clientdata(client, NULL); kfree(pcf); @@ -669,7 +631,6 @@ static int __devexit pcf50633_remove(struct i2c_client *client) int i; free_irq(pcf->irq, pcf); - destroy_workqueue(pcf->work_queue); platform_device_unregister(pcf->input_pdev); platform_device_unregister(pcf->rtc_pdev); -- cgit v1.2.3 From 380c09f6489f1fd773a697e9e2a156c083a34fc5 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 12 May 2010 02:10:56 +0200 Subject: mfd: Move pcf50633 irq related functions to its own file. This reduces code clutter a bit and will ease an migration to genirq. Signed-off-by: Lars-Peter Clausen Signed-off-by: Samuel Ortiz --- drivers/mfd/Makefile | 3 +- drivers/mfd/pcf50633-core.c | 303 ++--------------------------------------- drivers/mfd/pcf50633-irq.c | 318 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 330 insertions(+), 294 deletions(-) create mode 100644 drivers/mfd/pcf50633-irq.c (limited to 'drivers') diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 85934966a593..ca1517e948af 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -57,7 +57,8 @@ obj-$(CONFIG_PMIC_DA903X) += da903x.o max8925-objs := max8925-core.o max8925-i2c.o obj-$(CONFIG_MFD_MAX8925) += max8925.o -obj-$(CONFIG_MFD_PCF50633) += pcf50633-core.o pcf50633-irq.o +pcf50633-objs := pcf50633-core.o pcf50633-irq.o +obj-$(CONFIG_MFD_PCF50633) += pcf50633.o obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o obj-$(CONFIG_ABX500_CORE) += abx500-core.o diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index b3bef4998744..704736e6e9b9 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -21,16 +21,16 @@ #include #include #include -#include #include #include -/* Two MBCS registers used during cold start */ -#define PCF50633_REG_MBCS1 0x4b -#define PCF50633_REG_MBCS2 0x4c -#define PCF50633_MBCS1_USBPRES 0x01 -#define PCF50633_MBCS1_ADAPTPRES 0x01 +int pcf50633_irq_init(struct pcf50633 *pcf, int irq); +void pcf50633_irq_free(struct pcf50633 *pcf); +#ifdef CONFIG_PM +int pcf50633_irq_suspend(struct pcf50633 *pcf); +int pcf50633_irq_resume(struct pcf50633 *pcf); +#endif static int __pcf50633_read(struct pcf50633 *pcf, u8 reg, int num, u8 *data) { @@ -215,228 +215,6 @@ static struct attribute_group pcf_attr_group = { .attrs = pcf_sysfs_entries, }; -int pcf50633_register_irq(struct pcf50633 *pcf, int irq, - void (*handler) (int, void *), void *data) -{ - if (irq < 0 || irq >= PCF50633_NUM_IRQ || !handler) - return -EINVAL; - - if (WARN_ON(pcf->irq_handler[irq].handler)) - return -EBUSY; - - mutex_lock(&pcf->lock); - pcf->irq_handler[irq].handler = handler; - pcf->irq_handler[irq].data = data; - mutex_unlock(&pcf->lock); - - return 0; -} -EXPORT_SYMBOL_GPL(pcf50633_register_irq); - -int pcf50633_free_irq(struct pcf50633 *pcf, int irq) -{ - if (irq < 0 || irq >= PCF50633_NUM_IRQ) - return -EINVAL; - - mutex_lock(&pcf->lock); - pcf->irq_handler[irq].handler = NULL; - mutex_unlock(&pcf->lock); - - return 0; -} -EXPORT_SYMBOL_GPL(pcf50633_free_irq); - -static int __pcf50633_irq_mask_set(struct pcf50633 *pcf, int irq, u8 mask) -{ - u8 reg, bits, tmp; - int ret = 0, idx; - - idx = irq >> 3; - reg = PCF50633_REG_INT1M + idx; - bits = 1 << (irq & 0x07); - - mutex_lock(&pcf->lock); - - if (mask) { - ret = __pcf50633_read(pcf, reg, 1, &tmp); - if (ret < 0) - goto out; - - tmp |= bits; - - ret = __pcf50633_write(pcf, reg, 1, &tmp); - if (ret < 0) - goto out; - - pcf->mask_regs[idx] &= ~bits; - pcf->mask_regs[idx] |= bits; - } else { - ret = __pcf50633_read(pcf, reg, 1, &tmp); - if (ret < 0) - goto out; - - tmp &= ~bits; - - ret = __pcf50633_write(pcf, reg, 1, &tmp); - if (ret < 0) - goto out; - - pcf->mask_regs[idx] &= ~bits; - } -out: - mutex_unlock(&pcf->lock); - - return ret; -} - -int pcf50633_irq_mask(struct pcf50633 *pcf, int irq) -{ - dev_dbg(pcf->dev, "Masking IRQ %d\n", irq); - - return __pcf50633_irq_mask_set(pcf, irq, 1); -} -EXPORT_SYMBOL_GPL(pcf50633_irq_mask); - -int pcf50633_irq_unmask(struct pcf50633 *pcf, int irq) -{ - dev_dbg(pcf->dev, "Unmasking IRQ %d\n", irq); - - return __pcf50633_irq_mask_set(pcf, irq, 0); -} -EXPORT_SYMBOL_GPL(pcf50633_irq_unmask); - -int pcf50633_irq_mask_get(struct pcf50633 *pcf, int irq) -{ - u8 reg, bits; - - reg = irq >> 3; - bits = 1 << (irq & 0x07); - - return pcf->mask_regs[reg] & bits; -} -EXPORT_SYMBOL_GPL(pcf50633_irq_mask_get); - -static void pcf50633_irq_call_handler(struct pcf50633 *pcf, int irq) -{ - if (pcf->irq_handler[irq].handler) - pcf->irq_handler[irq].handler(irq, pcf->irq_handler[irq].data); -} - -/* Maximum amount of time ONKEY is held before emergency action is taken */ -#define PCF50633_ONKEY1S_TIMEOUT 8 - -static irqreturn_t pcf50633_irq(int irq, void *data) -{ - struct pcf50633 *pcf = data; - int ret, i, j; - u8 pcf_int[5], chgstat; - - /* Read the 5 INT regs in one transaction */ - ret = pcf50633_read_block(pcf, PCF50633_REG_INT1, - ARRAY_SIZE(pcf_int), pcf_int); - if (ret != ARRAY_SIZE(pcf_int)) { - dev_err(pcf->dev, "Error reading INT registers\n"); - - /* - * If this doesn't ACK the interrupt to the chip, we'll be - * called once again as we're level triggered. - */ - goto out; - } - - /* defeat 8s death from lowsys on A5 */ - pcf50633_reg_write(pcf, PCF50633_REG_OOCSHDWN, 0x04); - - /* We immediately read the usb and adapter status. We thus make sure - * only of USBINS/USBREM IRQ handlers are called */ - if (pcf_int[0] & (PCF50633_INT1_USBINS | PCF50633_INT1_USBREM)) { - chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2); - if (chgstat & (0x3 << 4)) - pcf_int[0] &= ~PCF50633_INT1_USBREM; - else - pcf_int[0] &= ~PCF50633_INT1_USBINS; - } - - /* Make sure only one of ADPINS or ADPREM is set */ - if (pcf_int[0] & (PCF50633_INT1_ADPINS | PCF50633_INT1_ADPREM)) { - chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2); - if (chgstat & (0x3 << 4)) - pcf_int[0] &= ~PCF50633_INT1_ADPREM; - else - pcf_int[0] &= ~PCF50633_INT1_ADPINS; - } - - dev_dbg(pcf->dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x " - "INT4=0x%02x INT5=0x%02x\n", pcf_int[0], - pcf_int[1], pcf_int[2], pcf_int[3], pcf_int[4]); - - /* Some revisions of the chip don't have a 8s standby mode on - * ONKEY1S press. We try to manually do it in such cases. */ - if ((pcf_int[0] & PCF50633_INT1_SECOND) && pcf->onkey1s_held) { - dev_info(pcf->dev, "ONKEY1S held for %d secs\n", - pcf->onkey1s_held); - if (pcf->onkey1s_held++ == PCF50633_ONKEY1S_TIMEOUT) - if (pcf->pdata->force_shutdown) - pcf->pdata->force_shutdown(pcf); - } - - if (pcf_int[2] & PCF50633_INT3_ONKEY1S) { - dev_info(pcf->dev, "ONKEY1S held\n"); - pcf->onkey1s_held = 1 ; - - /* Unmask IRQ_SECOND */ - pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT1M, - PCF50633_INT1_SECOND); - - /* Unmask IRQ_ONKEYR */ - pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT2M, - PCF50633_INT2_ONKEYR); - } - - if ((pcf_int[1] & PCF50633_INT2_ONKEYR) && pcf->onkey1s_held) { - pcf->onkey1s_held = 0; - - /* Mask SECOND and ONKEYR interrupts */ - if (pcf->mask_regs[0] & PCF50633_INT1_SECOND) - pcf50633_reg_set_bit_mask(pcf, - PCF50633_REG_INT1M, - PCF50633_INT1_SECOND, - PCF50633_INT1_SECOND); - - if (pcf->mask_regs[1] & PCF50633_INT2_ONKEYR) - pcf50633_reg_set_bit_mask(pcf, - PCF50633_REG_INT2M, - PCF50633_INT2_ONKEYR, - PCF50633_INT2_ONKEYR); - } - - /* Have we just resumed ? */ - if (pcf->is_suspended) { - pcf->is_suspended = 0; - - /* Set the resume reason filtering out non resumers */ - for (i = 0; i < ARRAY_SIZE(pcf_int); i++) - pcf->resume_reason[i] = pcf_int[i] & - pcf->pdata->resumers[i]; - - /* Make sure we don't pass on any ONKEY events to - * userspace now */ - pcf_int[1] &= ~(PCF50633_INT2_ONKEYR | PCF50633_INT2_ONKEYF); - } - - for (i = 0; i < ARRAY_SIZE(pcf_int); i++) { - /* Unset masked interrupts */ - pcf_int[i] &= ~pcf->mask_regs[i]; - - for (j = 0; j < 8 ; j++) - if (pcf_int[i] & (1 << j)) - pcf50633_irq_call_handler(pcf, (i * 8) + j); - } - -out: - return IRQ_HANDLED -} - static void pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name, struct platform_device **pdev) @@ -463,58 +241,17 @@ pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name, static int pcf50633_suspend(struct i2c_client *client, pm_message_t state) { struct pcf50633 *pcf; - int ret = 0, i; - u8 res[5]; - pcf = i2c_get_clientdata(client); - /* Make sure our interrupt handlers are not called - * henceforth */ - disable_irq(pcf->irq); - - /* Save the masks */ - ret = pcf50633_read_block(pcf, PCF50633_REG_INT1M, - ARRAY_SIZE(pcf->suspend_irq_masks), - pcf->suspend_irq_masks); - if (ret < 0) { - dev_err(pcf->dev, "error saving irq masks\n"); - goto out; - } - - /* Write wakeup irq masks */ - for (i = 0; i < ARRAY_SIZE(res); i++) - res[i] = ~pcf->pdata->resumers[i]; - - ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M, - ARRAY_SIZE(res), &res[0]); - if (ret < 0) { - dev_err(pcf->dev, "error writing wakeup irq masks\n"); - goto out; - } - - pcf->is_suspended = 1; - -out: - return ret; + return pcf50633_irq_suspend(pcf); } static int pcf50633_resume(struct i2c_client *client) { struct pcf50633 *pcf; - int ret; - pcf = i2c_get_clientdata(client); - /* Write the saved mask registers */ - ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M, - ARRAY_SIZE(pcf->suspend_irq_masks), - pcf->suspend_irq_masks); - if (ret < 0) - dev_err(pcf->dev, "Error restoring saved suspend masks\n"); - - enable_irq(pcf->irq); - - return 0; + return pcf50633_irq_resume(pcf); } #else #define pcf50633_suspend NULL @@ -545,7 +282,6 @@ static int __devinit pcf50633_probe(struct i2c_client *client, i2c_set_clientdata(client, pcf); pcf->dev = &client->dev; pcf->i2c_client = client; - pcf->irq = client->irq; version = pcf50633_reg_read(pcf, 0); variant = pcf50633_reg_read(pcf, 1); @@ -558,22 +294,7 @@ static int __devinit pcf50633_probe(struct i2c_client *client, dev_info(pcf->dev, "Probed device version %d variant %d\n", version, variant); - /* Enable all interrupts except RTC SECOND */ - pcf->mask_regs[0] = 0x80; - pcf50633_reg_write(pcf, PCF50633_REG_INT1M, pcf->mask_regs[0]); - pcf50633_reg_write(pcf, PCF50633_REG_INT2M, 0x00); - pcf50633_reg_write(pcf, PCF50633_REG_INT3M, 0x00); - pcf50633_reg_write(pcf, PCF50633_REG_INT4M, 0x00); - pcf50633_reg_write(pcf, PCF50633_REG_INT5M, 0x00); - - ret = request_threaded_irq(client->irq, NULL, pcf50633_irq, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, - "pcf50633", pcf); - - if (ret) { - dev_err(pcf->dev, "Failed to request IRQ %d\n", ret); - goto err_free; - } + pcf50633_irq_init(pcf, client->irq); /* Create sub devices */ pcf50633_client_dev_register(pcf, "pcf50633-input", @@ -605,10 +326,6 @@ static int __devinit pcf50633_probe(struct i2c_client *client, platform_device_add(pdev); } - if (enable_irq_wake(client->irq) < 0) - dev_err(pcf->dev, "IRQ %u cannot be enabled as wake-up source" - "in this hardware revision", client->irq); - ret = sysfs_create_group(&client->dev.kobj, &pcf_attr_group); if (ret) dev_err(pcf->dev, "error creating sysfs entries\n"); @@ -630,7 +347,7 @@ static int __devexit pcf50633_remove(struct i2c_client *client) struct pcf50633 *pcf = i2c_get_clientdata(client); int i; - free_irq(pcf->irq, pcf); + pcf50633_irq_free(pcf); platform_device_unregister(pcf->input_pdev); platform_device_unregister(pcf->rtc_pdev); diff --git a/drivers/mfd/pcf50633-irq.c b/drivers/mfd/pcf50633-irq.c new file mode 100644 index 000000000000..1b0192f1efff --- /dev/null +++ b/drivers/mfd/pcf50633-irq.c @@ -0,0 +1,318 @@ +/* NXP PCF50633 Power Management Unit (PMU) driver + * + * (C) 2006-2008 by Openmoko, Inc. + * Author: Harald Welte + * Balaji Rao + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include + +#include + +/* Two MBCS registers used during cold start */ +#define PCF50633_REG_MBCS1 0x4b +#define PCF50633_REG_MBCS2 0x4c +#define PCF50633_MBCS1_USBPRES 0x01 +#define PCF50633_MBCS1_ADAPTPRES 0x01 + +int pcf50633_register_irq(struct pcf50633 *pcf, int irq, + void (*handler) (int, void *), void *data) +{ + if (irq < 0 || irq >= PCF50633_NUM_IRQ || !handler) + return -EINVAL; + + if (WARN_ON(pcf->irq_handler[irq].handler)) + return -EBUSY; + + mutex_lock(&pcf->lock); + pcf->irq_handler[irq].handler = handler; + pcf->irq_handler[irq].data = data; + mutex_unlock(&pcf->lock); + + return 0; +} +EXPORT_SYMBOL_GPL(pcf50633_register_irq); + +int pcf50633_free_irq(struct pcf50633 *pcf, int irq) +{ + if (irq < 0 || irq >= PCF50633_NUM_IRQ) + return -EINVAL; + + mutex_lock(&pcf->lock); + pcf->irq_handler[irq].handler = NULL; + mutex_unlock(&pcf->lock); + + return 0; +} +EXPORT_SYMBOL_GPL(pcf50633_free_irq); + +static int __pcf50633_irq_mask_set(struct pcf50633 *pcf, int irq, u8 mask) +{ + u8 reg, bit; + int ret = 0, idx; + + idx = irq >> 3; + reg = PCF50633_REG_INT1M + idx; + bit = 1 << (irq & 0x07); + + pcf50633_reg_set_bit_mask(pcf, reg, bit, mask ? bit : 0); + + mutex_lock(&pcf->lock); + + if (mask) + pcf->mask_regs[idx] |= bit; + else + pcf->mask_regs[idx] &= ~bit; + + mutex_unlock(&pcf->lock); + + return ret; +} + +int pcf50633_irq_mask(struct pcf50633 *pcf, int irq) +{ + dev_dbg(pcf->dev, "Masking IRQ %d\n", irq); + + return __pcf50633_irq_mask_set(pcf, irq, 1); +} +EXPORT_SYMBOL_GPL(pcf50633_irq_mask); + +int pcf50633_irq_unmask(struct pcf50633 *pcf, int irq) +{ + dev_dbg(pcf->dev, "Unmasking IRQ %d\n", irq); + + return __pcf50633_irq_mask_set(pcf, irq, 0); +} +EXPORT_SYMBOL_GPL(pcf50633_irq_unmask); + +int pcf50633_irq_mask_get(struct pcf50633 *pcf, int irq) +{ + u8 reg, bits; + + reg = irq >> 3; + bits = 1 << (irq & 0x07); + + return pcf->mask_regs[reg] & bits; +} +EXPORT_SYMBOL_GPL(pcf50633_irq_mask_get); + +static void pcf50633_irq_call_handler(struct pcf50633 *pcf, int irq) +{ + if (pcf->irq_handler[irq].handler) + pcf->irq_handler[irq].handler(irq, pcf->irq_handler[irq].data); +} + +/* Maximum amount of time ONKEY is held before emergency action is taken */ +#define PCF50633_ONKEY1S_TIMEOUT 8 + +static irqreturn_t pcf50633_irq(int irq, void *data) +{ + struct pcf50633 *pcf = data; + int ret, i, j; + u8 pcf_int[5], chgstat; + + /* Read the 5 INT regs in one transaction */ + ret = pcf50633_read_block(pcf, PCF50633_REG_INT1, + ARRAY_SIZE(pcf_int), pcf_int); + if (ret != ARRAY_SIZE(pcf_int)) { + dev_err(pcf->dev, "Error reading INT registers\n"); + + /* + * If this doesn't ACK the interrupt to the chip, we'll be + * called once again as we're level triggered. + */ + goto out; + } + + /* defeat 8s death from lowsys on A5 */ + pcf50633_reg_write(pcf, PCF50633_REG_OOCSHDWN, 0x04); + + /* We immediately read the usb and adapter status. We thus make sure + * only of USBINS/USBREM IRQ handlers are called */ + if (pcf_int[0] & (PCF50633_INT1_USBINS | PCF50633_INT1_USBREM)) { + chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2); + if (chgstat & (0x3 << 4)) + pcf_int[0] &= ~PCF50633_INT1_USBREM; + else + pcf_int[0] &= ~PCF50633_INT1_USBINS; + } + + /* Make sure only one of ADPINS or ADPREM is set */ + if (pcf_int[0] & (PCF50633_INT1_ADPINS | PCF50633_INT1_ADPREM)) { + chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2); + if (chgstat & (0x3 << 4)) + pcf_int[0] &= ~PCF50633_INT1_ADPREM; + else + pcf_int[0] &= ~PCF50633_INT1_ADPINS; + } + + dev_dbg(pcf->dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x " + "INT4=0x%02x INT5=0x%02x\n", pcf_int[0], + pcf_int[1], pcf_int[2], pcf_int[3], pcf_int[4]); + + /* Some revisions of the chip don't have a 8s standby mode on + * ONKEY1S press. We try to manually do it in such cases. */ + if ((pcf_int[0] & PCF50633_INT1_SECOND) && pcf->onkey1s_held) { + dev_info(pcf->dev, "ONKEY1S held for %d secs\n", + pcf->onkey1s_held); + if (pcf->onkey1s_held++ == PCF50633_ONKEY1S_TIMEOUT) + if (pcf->pdata->force_shutdown) + pcf->pdata->force_shutdown(pcf); + } + + if (pcf_int[2] & PCF50633_INT3_ONKEY1S) { + dev_info(pcf->dev, "ONKEY1S held\n"); + pcf->onkey1s_held = 1 ; + + /* Unmask IRQ_SECOND */ + pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT1M, + PCF50633_INT1_SECOND); + + /* Unmask IRQ_ONKEYR */ + pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT2M, + PCF50633_INT2_ONKEYR); + } + + if ((pcf_int[1] & PCF50633_INT2_ONKEYR) && pcf->onkey1s_held) { + pcf->onkey1s_held = 0; + + /* Mask SECOND and ONKEYR interrupts */ + if (pcf->mask_regs[0] & PCF50633_INT1_SECOND) + pcf50633_reg_set_bit_mask(pcf, + PCF50633_REG_INT1M, + PCF50633_INT1_SECOND, + PCF50633_INT1_SECOND); + + if (pcf->mask_regs[1] & PCF50633_INT2_ONKEYR) + pcf50633_reg_set_bit_mask(pcf, + PCF50633_REG_INT2M, + PCF50633_INT2_ONKEYR, + PCF50633_INT2_ONKEYR); + } + + /* Have we just resumed ? */ + if (pcf->is_suspended) { + pcf->is_suspended = 0; + + /* Set the resume reason filtering out non resumers */ + for (i = 0; i < ARRAY_SIZE(pcf_int); i++) + pcf->resume_reason[i] = pcf_int[i] & + pcf->pdata->resumers[i]; + + /* Make sure we don't pass on any ONKEY events to + * userspace now */ + pcf_int[1] &= ~(PCF50633_INT2_ONKEYR | PCF50633_INT2_ONKEYF); + } + + for (i = 0; i < ARRAY_SIZE(pcf_int); i++) { + /* Unset masked interrupts */ + pcf_int[i] &= ~pcf->mask_regs[i]; + + for (j = 0; j < 8 ; j++) + if (pcf_int[i] & (1 << j)) + pcf50633_irq_call_handler(pcf, (i * 8) + j); + } + +out: + return IRQ_HANDLED; +} + +#ifdef CONFIG_PM + +int pcf50633_irq_suspend(struct pcf50633 *pcf) +{ + int ret; + int i; + u8 res[5]; + + + /* Make sure our interrupt handlers are not called + * henceforth */ + disable_irq(pcf->irq); + + /* Save the masks */ + ret = pcf50633_read_block(pcf, PCF50633_REG_INT1M, + ARRAY_SIZE(pcf->suspend_irq_masks), + pcf->suspend_irq_masks); + if (ret < 0) { + dev_err(pcf->dev, "error saving irq masks\n"); + goto out; + } + + /* Write wakeup irq masks */ + for (i = 0; i < ARRAY_SIZE(res); i++) + res[i] = ~pcf->pdata->resumers[i]; + + ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M, + ARRAY_SIZE(res), &res[0]); + if (ret < 0) { + dev_err(pcf->dev, "error writing wakeup irq masks\n"); + goto out; + } + + pcf->is_suspended = 1; + +out: + return ret; +} + +int pcf50633_irq_resume(struct pcf50633 *pcf) +{ + int ret; + + /* Write the saved mask registers */ + ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M, + ARRAY_SIZE(pcf->suspend_irq_masks), + pcf->suspend_irq_masks); + if (ret < 0) + dev_err(pcf->dev, "Error restoring saved suspend masks\n"); + + enable_irq(pcf->irq); + + return ret; +} + +#endif + +int pcf50633_irq_init(struct pcf50633 *pcf, int irq) +{ + int ret; + + pcf->irq = irq; + + /* Enable all interrupts except RTC SECOND */ + pcf->mask_regs[0] = 0x80; + pcf50633_reg_write(pcf, PCF50633_REG_INT1M, pcf->mask_regs[0]); + pcf50633_reg_write(pcf, PCF50633_REG_INT2M, 0x00); + pcf50633_reg_write(pcf, PCF50633_REG_INT3M, 0x00); + pcf50633_reg_write(pcf, PCF50633_REG_INT4M, 0x00); + pcf50633_reg_write(pcf, PCF50633_REG_INT5M, 0x00); + + ret = request_threaded_irq(irq, NULL, pcf50633_irq, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + "pcf50633", pcf); + + if (ret) + dev_err(pcf->dev, "Failed to request IRQ %d\n", ret); + + if (enable_irq_wake(irq) < 0) + dev_err(pcf->dev, "IRQ %u cannot be enabled as wake-up source" + "in this hardware revision", irq); + + return ret; +} + +void pcf50633_irq_free(struct pcf50633 *pcf) +{ + free_irq(pcf->irq, pcf); +} -- cgit v1.2.3 From 8deca39e5caf7a20fc3786548dc9bfb7f0ae14b6 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sat, 15 May 2010 22:58:27 +0200 Subject: mfd: Change rdc321x resources flags to IORESOURCE_IO The rdc321x southbridge PCI device has no MEM PCI resources that we could pass to mfd_add_devices. Since 33254dd5, mfd_add_device checks for the mem_base argument that we set to NULL. Changing the resources passed to our MFD cells from IORESOURCE_MEM to IORESOURCE_IO fixes that. Since we use those resources as offsets to the PCI configuration space base address of the southbridge device this is also more adequate. Signed-off-by: Florian Fainelli Signed-off-by: Samuel Ortiz --- drivers/gpio/rdc321x-gpio.c | 4 ++-- drivers/mfd/rdc321x-southbridge.c | 6 +++--- drivers/watchdog/rdc321x_wdt.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/rdc321x-gpio.c b/drivers/gpio/rdc321x-gpio.c index e344907da5b0..22f31dc50104 100644 --- a/drivers/gpio/rdc321x-gpio.c +++ b/drivers/gpio/rdc321x-gpio.c @@ -147,7 +147,7 @@ static int __devinit rdc321x_gpio_probe(struct platform_device *pdev) return -ENOMEM; } - r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gpio-reg1"); + r = platform_get_resource_byname(pdev, IORESOURCE_IO, "gpio-reg1"); if (!r) { dev_err(&pdev->dev, "failed to get gpio-reg1 resource\n"); err = -ENODEV; @@ -159,7 +159,7 @@ static int __devinit rdc321x_gpio_probe(struct platform_device *pdev) rdc321x_gpio_dev->reg1_ctrl_base = r->start; rdc321x_gpio_dev->reg1_data_base = r->start + 0x4; - r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gpio-reg2"); + r = platform_get_resource_byname(pdev, IORESOURCE_IO, "gpio-reg2"); if (!r) { dev_err(&pdev->dev, "failed to get gpio-reg2 resource\n"); err = -ENODEV; diff --git a/drivers/mfd/rdc321x-southbridge.c b/drivers/mfd/rdc321x-southbridge.c index 256dd560bd48..50922975bda3 100644 --- a/drivers/mfd/rdc321x-southbridge.c +++ b/drivers/mfd/rdc321x-southbridge.c @@ -34,7 +34,7 @@ static struct resource rdc321x_wdt_resource[] = { .name = "wdt-reg", .start = RDC321X_WDT_CTRL, .end = RDC321X_WDT_CTRL + 0x3, - .flags = IORESOURCE_MEM, + .flags = IORESOURCE_IO, } }; @@ -47,12 +47,12 @@ static struct resource rdc321x_gpio_resources[] = { .name = "gpio-reg1", .start = RDC321X_GPIO_CTRL_REG1, .end = RDC321X_GPIO_CTRL_REG1 + 0x7, - .flags = IORESOURCE_MEM, + .flags = IORESOURCE_IO, }, { .name = "gpio-reg2", .start = RDC321X_GPIO_CTRL_REG2, .end = RDC321X_GPIO_CTRL_REG2 + 0x7, - .flags = IORESOURCE_MEM, + .flags = IORESOURCE_IO, } }; diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c index 4733a99955dd..428f8a1583e8 100644 --- a/drivers/watchdog/rdc321x_wdt.c +++ b/drivers/watchdog/rdc321x_wdt.c @@ -237,7 +237,7 @@ static int __devinit rdc321x_wdt_probe(struct platform_device *pdev) return -ENODEV; } - r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wdt-reg"); + r = platform_get_resource_byname(pdev, IORESOURCE_IO, "wdt-reg"); if (!r) { dev_err(&pdev->dev, "failed to get wdt-reg resource\n"); return -ENODEV; -- cgit v1.2.3 From 75907a1153b42100b7a5e960bfe47d208d726309 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 16 May 2010 12:02:18 +0200 Subject: gpio: Fix inverted rdc321x gpio data out registers rdc_gpio_set_value_impl has the gpio data registers 1 and 2 inverted, fix this. Signed-off-by: Bernhard Loos Signed-off-by: Florian Fainelli Signed-off-by: Samuel Ortiz --- drivers/gpio/rdc321x-gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpio/rdc321x-gpio.c b/drivers/gpio/rdc321x-gpio.c index 22f31dc50104..2762698e0204 100644 --- a/drivers/gpio/rdc321x-gpio.c +++ b/drivers/gpio/rdc321x-gpio.c @@ -73,7 +73,7 @@ static void rdc_gpio_set_value_impl(struct gpio_chip *chip, gpch->data_reg[reg] &= ~(1 << (gpio & 0x1f)); pci_write_config_dword(gpch->sb_pdev, - reg ? gpch->reg1_data_base : gpch->reg2_data_base, + reg ? gpch->reg2_data_base : gpch->reg1_data_base, gpch->data_reg[reg]); } -- cgit v1.2.3 From 62579266cf9caca5b999560be2b5ceee42fc4d4d Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Wed, 19 May 2010 11:39:02 +0200 Subject: mfd: New AB8500 driver Add a new driver to support the AB8500 Power Management chip, replacing the current AB4500. The new driver replaces the old one, instead of an incremental modification, because this is a substantial overhaul including: - Split of the driver into -core and -spi portions, to allow another interface layer to be added - Addition of interrupt support - Switch to MFD core API for handling subdevices - Simplification of the APIs to remove a redundant block parameter - Rename of the APIs and macros from ab4500_* to ab8500_* - Rename of the files from ab4500* to ab8500* - Change of the driver name from ab4500 to ab8500 Acked-by: Linus Walleij Acked-by: Srinidhi Kasagar Signed-off-by: Rabin Vincent Signed-off-by: Samuel Ortiz --- arch/arm/mach-ux500/board-mop500.c | 2 +- drivers/mfd/Kconfig | 9 +- drivers/mfd/Makefile | 2 +- drivers/mfd/ab4500-core.c | 209 ----------------- drivers/mfd/ab8500-core.c | 444 +++++++++++++++++++++++++++++++++++++ drivers/mfd/ab8500-spi.c | 133 +++++++++++ include/linux/mfd/ab4500.h | 262 ---------------------- include/linux/mfd/ab8500.h | 128 +++++++++++ 8 files changed, 712 insertions(+), 477 deletions(-) delete mode 100644 drivers/mfd/ab4500-core.c create mode 100644 drivers/mfd/ab8500-core.c create mode 100644 drivers/mfd/ab8500-spi.c delete mode 100644 include/linux/mfd/ab4500.h create mode 100644 include/linux/mfd/ab8500.h (limited to 'drivers') diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 072196c57263..bb8d7b771817 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -50,7 +50,7 @@ struct pl022_config_chip ab4500_chip_info = { static struct spi_board_info u8500_spi_devices[] = { { - .modalias = "ab4500", + .modalias = "ab8500", .controller_data = &ab4500_chip_info, .max_speed_hz = 12000000, .bus_num = 0, diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index b84b7078e909..9da0e504bbe9 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -420,11 +420,12 @@ config EZX_PCAP This enables the PCAP ASIC present on EZX Phones. This is needed for MMC, TouchScreen, Sound, USB, etc.. -config AB4500_CORE - tristate "ST-Ericsson's AB4500 Mixed Signal Power management chip" - depends on SPI +config AB8500_CORE + bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" + depends on SPI=y && GENERIC_HARDIRQS + select MFD_CORE help - Select this option to enable access to AB4500 power management + Select this option to enable access to AB8500 power management chip. This connects to U8500 on the SSP/SPI bus and exports read/write functions for the devices to get access to this chip. This chip embeds various other multimedia funtionalities as well. diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index ca1517e948af..fb503e77dc60 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -64,8 +64,8 @@ obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o obj-$(CONFIG_ABX500_CORE) += abx500-core.o obj-$(CONFIG_AB3100_CORE) += ab3100-core.o obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o -obj-$(CONFIG_AB4500_CORE) += ab4500-core.o obj-$(CONFIG_AB3550_CORE) += ab3550-core.o +obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-spi.o obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o obj-$(CONFIG_PMIC_ADP5520) += adp5520.o obj-$(CONFIG_LPC_SCH) += lpc_sch.o diff --git a/drivers/mfd/ab4500-core.c b/drivers/mfd/ab4500-core.c deleted file mode 100644 index c275daa3ab1a..000000000000 --- a/drivers/mfd/ab4500-core.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (C) 2009 ST-Ericsson - * - * Author: Srinidhi KASAGAR - * - * This program is free software; you can redistribute it - * and/or modify it under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation. - * - * AB4500 is a companion power management chip used with U8500. - * On this platform, this is interfaced with SSP0 controller - * which is a ARM primecell pl022. - * - * At the moment the module just exports read/write features. - * Interrupt management to be added - TODO. - */ -#include -#include -#include -#include -#include -#include -#include - -/* just required if probe fails, we need to - * unregister the device - */ -static struct spi_driver ab4500_driver; - -/* - * This funtion writes to any AB4500 registers using - * SPI protocol & before it writes it packs the data - * in the below 24 bit frame format - * - * *|------------------------------------| - * *| 23|22...18|17.......10|9|8|7......0| - * *| r/w bank adr data | - * * ------------------------------------ - * - * This function shouldn't be called from interrupt - * context - */ -int ab4500_write(struct ab4500 *ab4500, unsigned char block, - unsigned long addr, unsigned char data) -{ - struct spi_transfer xfer; - struct spi_message msg; - int err; - unsigned long spi_data = - block << 18 | addr << 10 | data; - - mutex_lock(&ab4500->lock); - ab4500->tx_buf[0] = spi_data; - ab4500->rx_buf[0] = 0; - - xfer.tx_buf = ab4500->tx_buf; - xfer.rx_buf = NULL; - xfer.len = sizeof(unsigned long); - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - - err = spi_sync(ab4500->spi, &msg); - mutex_unlock(&ab4500->lock); - - return err; -} -EXPORT_SYMBOL(ab4500_write); - -int ab4500_read(struct ab4500 *ab4500, unsigned char block, - unsigned long addr) -{ - struct spi_transfer xfer; - struct spi_message msg; - unsigned long spi_data = - 1 << 23 | block << 18 | addr << 10; - - mutex_lock(&ab4500->lock); - ab4500->tx_buf[0] = spi_data; - ab4500->rx_buf[0] = 0; - - xfer.tx_buf = ab4500->tx_buf; - xfer.rx_buf = ab4500->rx_buf; - xfer.len = sizeof(unsigned long); - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - - spi_sync(ab4500->spi, &msg); - mutex_unlock(&ab4500->lock); - - return ab4500->rx_buf[0]; -} -EXPORT_SYMBOL(ab4500_read); - -/* ref: ab3100 core */ -#define AB4500_DEVICE(devname, devid) \ -static struct platform_device ab4500_##devname##_device = { \ - .name = devid, \ - .id = -1, \ -} - -/* list of childern devices of ab4500 - all are - * not populated here - TODO - */ -AB4500_DEVICE(charger, "ab4500-charger"); -AB4500_DEVICE(audio, "ab4500-audio"); -AB4500_DEVICE(usb, "ab4500-usb"); -AB4500_DEVICE(tvout, "ab4500-tvout"); -AB4500_DEVICE(sim, "ab4500-sim"); -AB4500_DEVICE(gpadc, "ab4500-gpadc"); -AB4500_DEVICE(clkmgt, "ab4500-clkmgt"); -AB4500_DEVICE(misc, "ab4500-misc"); - -static struct platform_device *ab4500_platform_devs[] = { - &ab4500_charger_device, - &ab4500_audio_device, - &ab4500_usb_device, - &ab4500_tvout_device, - &ab4500_sim_device, - &ab4500_gpadc_device, - &ab4500_clkmgt_device, - &ab4500_misc_device, -}; - -static int __init ab4500_probe(struct spi_device *spi) -{ - struct ab4500 *ab4500; - unsigned char revision; - int err = 0; - int i; - - ab4500 = kzalloc(sizeof *ab4500, GFP_KERNEL); - if (!ab4500) { - dev_err(&spi->dev, "could not allocate AB4500\n"); - err = -ENOMEM; - goto not_detect; - } - - ab4500->spi = spi; - spi_set_drvdata(spi, ab4500); - - mutex_init(&ab4500->lock); - - /* read the revision register */ - revision = ab4500_read(ab4500, AB4500_MISC, AB4500_REV_REG); - - /* revision id 0x0 is for early drop, 0x10 is for cut1.0 */ - if (revision == 0x0 || revision == 0x10) - dev_info(&spi->dev, "Detected chip: %s, revision = %x\n", - ab4500_driver.driver.name, revision); - else { - dev_err(&spi->dev, "unknown chip: 0x%x\n", revision); - goto not_detect; - } - - for (i = 0; i < ARRAY_SIZE(ab4500_platform_devs); i++) { - ab4500_platform_devs[i]->dev.parent = - &spi->dev; - platform_set_drvdata(ab4500_platform_devs[i], ab4500); - } - - /* register the ab4500 platform devices */ - platform_add_devices(ab4500_platform_devs, - ARRAY_SIZE(ab4500_platform_devs)); - - return err; - - not_detect: - spi_unregister_driver(&ab4500_driver); - kfree(ab4500); - return err; -} - -static int __devexit ab4500_remove(struct spi_device *spi) -{ - struct ab4500 *ab4500 = - spi_get_drvdata(spi); - - kfree(ab4500); - - return 0; -} - -static struct spi_driver ab4500_driver = { - .driver = { - .name = "ab4500", - .owner = THIS_MODULE, - }, - .probe = ab4500_probe, - .remove = __devexit_p(ab4500_remove) -}; - -static int __devinit ab4500_init(void) -{ - return spi_register_driver(&ab4500_driver); -} - -static void __exit ab4500_exit(void) -{ - spi_unregister_driver(&ab4500_driver); -} - -subsys_initcall(ab4500_init); -module_exit(ab4500_exit); - -MODULE_AUTHOR("Srinidhi KASAGAR + * Author: Rabin Vincent + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Interrupt register offsets + * Bank : 0x0E + */ +#define AB8500_IT_SOURCE1_REG 0x0E00 +#define AB8500_IT_SOURCE2_REG 0x0E01 +#define AB8500_IT_SOURCE3_REG 0x0E02 +#define AB8500_IT_SOURCE4_REG 0x0E03 +#define AB8500_IT_SOURCE5_REG 0x0E04 +#define AB8500_IT_SOURCE6_REG 0x0E05 +#define AB8500_IT_SOURCE7_REG 0x0E06 +#define AB8500_IT_SOURCE8_REG 0x0E07 +#define AB8500_IT_SOURCE19_REG 0x0E12 +#define AB8500_IT_SOURCE20_REG 0x0E13 +#define AB8500_IT_SOURCE21_REG 0x0E14 +#define AB8500_IT_SOURCE22_REG 0x0E15 +#define AB8500_IT_SOURCE23_REG 0x0E16 +#define AB8500_IT_SOURCE24_REG 0x0E17 + +/* + * latch registers + */ +#define AB8500_IT_LATCH1_REG 0x0E20 +#define AB8500_IT_LATCH2_REG 0x0E21 +#define AB8500_IT_LATCH3_REG 0x0E22 +#define AB8500_IT_LATCH4_REG 0x0E23 +#define AB8500_IT_LATCH5_REG 0x0E24 +#define AB8500_IT_LATCH6_REG 0x0E25 +#define AB8500_IT_LATCH7_REG 0x0E26 +#define AB8500_IT_LATCH8_REG 0x0E27 +#define AB8500_IT_LATCH9_REG 0x0E28 +#define AB8500_IT_LATCH10_REG 0x0E29 +#define AB8500_IT_LATCH19_REG 0x0E32 +#define AB8500_IT_LATCH20_REG 0x0E33 +#define AB8500_IT_LATCH21_REG 0x0E34 +#define AB8500_IT_LATCH22_REG 0x0E35 +#define AB8500_IT_LATCH23_REG 0x0E36 +#define AB8500_IT_LATCH24_REG 0x0E37 + +/* + * mask registers + */ + +#define AB8500_IT_MASK1_REG 0x0E40 +#define AB8500_IT_MASK2_REG 0x0E41 +#define AB8500_IT_MASK3_REG 0x0E42 +#define AB8500_IT_MASK4_REG 0x0E43 +#define AB8500_IT_MASK5_REG 0x0E44 +#define AB8500_IT_MASK6_REG 0x0E45 +#define AB8500_IT_MASK7_REG 0x0E46 +#define AB8500_IT_MASK8_REG 0x0E47 +#define AB8500_IT_MASK9_REG 0x0E48 +#define AB8500_IT_MASK10_REG 0x0E49 +#define AB8500_IT_MASK11_REG 0x0E4A +#define AB8500_IT_MASK12_REG 0x0E4B +#define AB8500_IT_MASK13_REG 0x0E4C +#define AB8500_IT_MASK14_REG 0x0E4D +#define AB8500_IT_MASK15_REG 0x0E4E +#define AB8500_IT_MASK16_REG 0x0E4F +#define AB8500_IT_MASK17_REG 0x0E50 +#define AB8500_IT_MASK18_REG 0x0E51 +#define AB8500_IT_MASK19_REG 0x0E52 +#define AB8500_IT_MASK20_REG 0x0E53 +#define AB8500_IT_MASK21_REG 0x0E54 +#define AB8500_IT_MASK22_REG 0x0E55 +#define AB8500_IT_MASK23_REG 0x0E56 +#define AB8500_IT_MASK24_REG 0x0E57 + +#define AB8500_REV_REG 0x1080 + +/* + * Map interrupt numbers to the LATCH and MASK register offsets, Interrupt + * numbers are indexed into this array with (num / 8). + * + * This is one off from the register names, i.e. AB8500_IT_MASK1_REG is at + * offset 0. + */ +static const int ab8500_irq_regoffset[AB8500_NUM_IRQ_REGS] = { + 0, 1, 2, 3, 4, 6, 7, 8, 9, 18, 19, 20, 21, +}; + +static int __ab8500_write(struct ab8500 *ab8500, u16 addr, u8 data) +{ + int ret; + + dev_vdbg(ab8500->dev, "wr: addr %#x <= %#x\n", addr, data); + + ret = ab8500->write(ab8500, addr, data); + if (ret < 0) + dev_err(ab8500->dev, "failed to write reg %#x: %d\n", + addr, ret); + + return ret; +} + +/** + * ab8500_write() - write an AB8500 register + * @ab8500: device to write to + * @addr: address of the register + * @data: value to write + */ +int ab8500_write(struct ab8500 *ab8500, u16 addr, u8 data) +{ + int ret; + + mutex_lock(&ab8500->lock); + ret = __ab8500_write(ab8500, addr, data); + mutex_unlock(&ab8500->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(ab8500_write); + +static int __ab8500_read(struct ab8500 *ab8500, u16 addr) +{ + int ret; + + ret = ab8500->read(ab8500, addr); + if (ret < 0) + dev_err(ab8500->dev, "failed to read reg %#x: %d\n", + addr, ret); + + dev_vdbg(ab8500->dev, "rd: addr %#x => data %#x\n", addr, ret); + + return ret; +} + +/** + * ab8500_read() - read an AB8500 register + * @ab8500: device to read from + * @addr: address of the register + */ +int ab8500_read(struct ab8500 *ab8500, u16 addr) +{ + int ret; + + mutex_lock(&ab8500->lock); + ret = __ab8500_read(ab8500, addr); + mutex_unlock(&ab8500->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(ab8500_read); + +/** + * ab8500_set_bits() - set a bitfield in an AB8500 register + * @ab8500: device to read from + * @addr: address of the register + * @mask: mask of the bitfield to modify + * @data: value to set to the bitfield + */ +int ab8500_set_bits(struct ab8500 *ab8500, u16 addr, u8 mask, u8 data) +{ + int ret; + + mutex_lock(&ab8500->lock); + + ret = __ab8500_read(ab8500, addr); + if (ret < 0) + goto out; + + ret &= ~mask; + ret |= data; + + ret = __ab8500_write(ab8500, addr, ret); + +out: + mutex_unlock(&ab8500->lock); + return ret; +} +EXPORT_SYMBOL_GPL(ab8500_set_bits); + +static void ab8500_irq_lock(unsigned int irq) +{ + struct ab8500 *ab8500 = get_irq_chip_data(irq); + + mutex_lock(&ab8500->irq_lock); +} + +static void ab8500_irq_sync_unlock(unsigned int irq) +{ + struct ab8500 *ab8500 = get_irq_chip_data(irq); + int i; + + for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) { + u8 old = ab8500->oldmask[i]; + u8 new = ab8500->mask[i]; + int reg; + + if (new == old) + continue; + + ab8500->oldmask[i] = new; + + reg = AB8500_IT_MASK1_REG + ab8500_irq_regoffset[i]; + ab8500_write(ab8500, reg, new); + } + + mutex_unlock(&ab8500->irq_lock); +} + +static void ab8500_irq_mask(unsigned int irq) +{ + struct ab8500 *ab8500 = get_irq_chip_data(irq); + int offset = irq - ab8500->irq_base; + int index = offset / 8; + int mask = 1 << (offset % 8); + + ab8500->mask[index] |= mask; +} + +static void ab8500_irq_unmask(unsigned int irq) +{ + struct ab8500 *ab8500 = get_irq_chip_data(irq); + int offset = irq - ab8500->irq_base; + int index = offset / 8; + int mask = 1 << (offset % 8); + + ab8500->mask[index] &= ~mask; +} + +static struct irq_chip ab8500_irq_chip = { + .name = "ab8500", + .bus_lock = ab8500_irq_lock, + .bus_sync_unlock = ab8500_irq_sync_unlock, + .mask = ab8500_irq_mask, + .unmask = ab8500_irq_unmask, +}; + +static irqreturn_t ab8500_irq(int irq, void *dev) +{ + struct ab8500 *ab8500 = dev; + int i; + + dev_vdbg(ab8500->dev, "interrupt\n"); + + for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) { + int regoffset = ab8500_irq_regoffset[i]; + int status; + + status = ab8500_read(ab8500, AB8500_IT_LATCH1_REG + regoffset); + if (status <= 0) + continue; + + do { + int bit = __ffs(status); + int line = i * 8 + bit; + + handle_nested_irq(ab8500->irq_base + line); + status &= ~(1 << bit); + } while (status); + } + + return IRQ_HANDLED; +} + +static int ab8500_irq_init(struct ab8500 *ab8500) +{ + int base = ab8500->irq_base; + int irq; + + for (irq = base; irq < base + AB8500_NR_IRQS; irq++) { + set_irq_chip_data(irq, ab8500); + set_irq_chip_and_handler(irq, &ab8500_irq_chip, + handle_simple_irq); + set_irq_nested_thread(irq, 1); +#ifdef CONFIG_ARM + set_irq_flags(irq, IRQF_VALID); +#else + set_irq_noprobe(irq); +#endif + } + + return 0; +} + +static void ab8500_irq_remove(struct ab8500 *ab8500) +{ + int base = ab8500->irq_base; + int irq; + + for (irq = base; irq < base + AB8500_NR_IRQS; irq++) { +#ifdef CONFIG_ARM + set_irq_flags(irq, 0); +#endif + set_irq_chip_and_handler(irq, NULL, NULL); + set_irq_chip_data(irq, NULL); + } +} + +static struct resource ab8500_gpadc_resources[] = { + { + .name = "HW_CONV_END", + .start = AB8500_INT_GP_HW_ADC_CONV_END, + .end = AB8500_INT_GP_HW_ADC_CONV_END, + .flags = IORESOURCE_IRQ, + }, + { + .name = "SW_CONV_END", + .start = AB8500_INT_GP_SW_ADC_CONV_END, + .end = AB8500_INT_GP_SW_ADC_CONV_END, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource ab8500_rtc_resources[] = { + { + .name = "60S", + .start = AB8500_INT_RTC_60S, + .end = AB8500_INT_RTC_60S, + .flags = IORESOURCE_IRQ, + }, + { + .name = "ALARM", + .start = AB8500_INT_RTC_ALARM, + .end = AB8500_INT_RTC_ALARM, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct mfd_cell ab8500_devs[] = { + { + .name = "ab8500-gpadc", + .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), + .resources = ab8500_gpadc_resources, + }, + { + .name = "ab8500-rtc", + .num_resources = ARRAY_SIZE(ab8500_rtc_resources), + .resources = ab8500_rtc_resources, + }, + { .name = "ab8500-charger", }, + { .name = "ab8500-audio", }, + { .name = "ab8500-usb", }, + { .name = "ab8500-pwm", }, +}; + +int __devinit ab8500_init(struct ab8500 *ab8500) +{ + struct ab8500_platform_data *plat = dev_get_platdata(ab8500->dev); + int ret; + int i; + + if (plat) + ab8500->irq_base = plat->irq_base; + + mutex_init(&ab8500->lock); + mutex_init(&ab8500->irq_lock); + + ret = ab8500_read(ab8500, AB8500_REV_REG); + if (ret < 0) + return ret; + + /* + * 0x0 - Early Drop + * 0x10 - Cut 1.0 + * 0x11 - Cut 1.1 + */ + if (ret == 0x0 || ret == 0x10 || ret == 0x11) { + ab8500->revision = ret; + dev_info(ab8500->dev, "detected chip, revision: %#x\n", ret); + } else { + dev_err(ab8500->dev, "unknown chip, revision: %#x\n", ret); + return -EINVAL; + } + + if (plat && plat->init) + plat->init(ab8500); + + /* Clear and mask all interrupts */ + for (i = 0; i < 10; i++) { + ab8500_read(ab8500, AB8500_IT_LATCH1_REG + i); + ab8500_write(ab8500, AB8500_IT_MASK1_REG + i, 0xff); + } + + for (i = 18; i < 24; i++) { + ab8500_read(ab8500, AB8500_IT_LATCH1_REG + i); + ab8500_write(ab8500, AB8500_IT_MASK1_REG + i, 0xff); + } + + for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) + ab8500->mask[i] = ab8500->oldmask[i] = 0xff; + + if (ab8500->irq_base) { + ret = ab8500_irq_init(ab8500); + if (ret) + return ret; + + ret = request_threaded_irq(ab8500->irq, NULL, ab8500_irq, + IRQF_ONESHOT, "ab8500", ab8500); + if (ret) + goto out_removeirq; + } + + ret = mfd_add_devices(ab8500->dev, -1, ab8500_devs, + ARRAY_SIZE(ab8500_devs), NULL, + ab8500->irq_base); + if (ret) + goto out_freeirq; + + return ret; + +out_freeirq: + if (ab8500->irq_base) { + free_irq(ab8500->irq, ab8500); +out_removeirq: + ab8500_irq_remove(ab8500); + } + return ret; +} + +int __devexit ab8500_exit(struct ab8500 *ab8500) +{ + mfd_remove_devices(ab8500->dev); + if (ab8500->irq_base) { + free_irq(ab8500->irq, ab8500); + ab8500_irq_remove(ab8500); + } + + return 0; +} + +MODULE_AUTHOR("Srinidhi Kasagar, Rabin Vincent"); +MODULE_DESCRIPTION("AB8500 MFD core"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/mfd/ab8500-spi.c b/drivers/mfd/ab8500-spi.c new file mode 100644 index 000000000000..b81d4f768ef6 --- /dev/null +++ b/drivers/mfd/ab8500-spi.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License Terms: GNU General Public License v2 + * Author: Srinidhi Kasagar + */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * This funtion writes to any AB8500 registers using + * SPI protocol & before it writes it packs the data + * in the below 24 bit frame format + * + * *|------------------------------------| + * *| 23|22...18|17.......10|9|8|7......0| + * *| r/w bank adr data | + * * ------------------------------------ + * + * This function shouldn't be called from interrupt + * context + */ +static int ab8500_spi_write(struct ab8500 *ab8500, u16 addr, u8 data) +{ + struct spi_device *spi = container_of(ab8500->dev, struct spi_device, + dev); + unsigned long spi_data = addr << 10 | data; + struct spi_transfer xfer; + struct spi_message msg; + + ab8500->tx_buf[0] = spi_data; + ab8500->rx_buf[0] = 0; + + xfer.tx_buf = ab8500->tx_buf; + xfer.rx_buf = NULL; + xfer.len = sizeof(unsigned long); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + + return spi_sync(spi, &msg); +} + +static int ab8500_spi_read(struct ab8500 *ab8500, u16 addr) +{ + struct spi_device *spi = container_of(ab8500->dev, struct spi_device, + dev); + unsigned long spi_data = 1 << 23 | addr << 10; + struct spi_transfer xfer; + struct spi_message msg; + int ret; + + ab8500->tx_buf[0] = spi_data; + ab8500->rx_buf[0] = 0; + + xfer.tx_buf = ab8500->tx_buf; + xfer.rx_buf = ab8500->rx_buf; + xfer.len = sizeof(unsigned long); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + + ret = spi_sync(spi, &msg); + if (!ret) + ret = ab8500->rx_buf[0]; + + return ret; +} + +static int __devinit ab8500_spi_probe(struct spi_device *spi) +{ + struct ab8500 *ab8500; + int ret; + + ab8500 = kzalloc(sizeof *ab8500, GFP_KERNEL); + if (!ab8500) + return -ENOMEM; + + ab8500->dev = &spi->dev; + ab8500->irq = spi->irq; + + ab8500->read = ab8500_spi_read; + ab8500->write = ab8500_spi_write; + + spi_set_drvdata(spi, ab8500); + + ret = ab8500_init(ab8500); + if (ret) + kfree(ab8500); + + return ret; +} + +static int __devexit ab8500_spi_remove(struct spi_device *spi) +{ + struct ab8500 *ab8500 = spi_get_drvdata(spi); + + ab8500_exit(ab8500); + kfree(ab8500); + + return 0; +} + +static struct spi_driver ab8500_spi_driver = { + .driver = { + .name = "ab8500", + .owner = THIS_MODULE, + }, + .probe = ab8500_spi_probe, + .remove = __devexit_p(ab8500_spi_remove) +}; + +static int __init ab8500_spi_init(void) +{ + return spi_register_driver(&ab8500_spi_driver); +} +subsys_initcall(ab8500_spi_init); + +static void __exit ab8500_spi_exit(void) +{ + spi_unregister_driver(&ab8500_spi_driver); +} +module_exit(ab8500_spi_exit); + +MODULE_AUTHOR("Srinidhi KASAGAR - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, as - * published by the Free Software Foundation. - * - * AB4500 device core funtions, for client access - */ -#ifndef MFD_AB4500_H -#define MFD_AB4500_H - -#include - -/* - * AB4500 bank addresses - */ -#define AB4500_SYS_CTRL1_BLOCK 0x1 -#define AB4500_SYS_CTRL2_BLOCK 0x2 -#define AB4500_REGU_CTRL1 0x3 -#define AB4500_REGU_CTRL2 0x4 -#define AB4500_USB 0x5 -#define AB4500_TVOUT 0x6 -#define AB4500_DBI 0x7 -#define AB4500_ECI_AV_ACC 0x8 -#define AB4500_RESERVED 0x9 -#define AB4500_GPADC 0xA -#define AB4500_CHARGER 0xB -#define AB4500_GAS_GAUGE 0xC -#define AB4500_AUDIO 0xD -#define AB4500_INTERRUPT 0xE -#define AB4500_RTC 0xF -#define AB4500_MISC 0x10 -#define AB4500_DEBUG 0x12 -#define AB4500_PROD_TEST 0x13 -#define AB4500_OTP_EMUL 0x15 - -/* - * System control 1 register offsets. - * Bank = 0x01 - */ -#define AB4500_TURNON_STAT_REG 0x0100 -#define AB4500_RESET_STAT_REG 0x0101 -#define AB4500_PONKEY1_PRESS_STAT_REG 0x0102 - -#define AB4500_FSM_STAT1_REG 0x0140 -#define AB4500_FSM_STAT2_REG 0x0141 -#define AB4500_SYSCLK_REQ_STAT_REG 0x0142 -#define AB4500_USB_STAT1_REG 0x0143 -#define AB4500_USB_STAT2_REG 0x0144 -#define AB4500_STATUS_SPARE1_REG 0x0145 -#define AB4500_STATUS_SPARE2_REG 0x0146 - -#define AB4500_CTRL1_REG 0x0180 -#define AB4500_CTRL2_REG 0x0181 - -/* - * System control 2 register offsets. - * bank = 0x02 - */ -#define AB4500_CTRL3_REG 0x0200 -#define AB4500_MAIN_WDOG_CTRL_REG 0x0201 -#define AB4500_MAIN_WDOG_TIMER_REG 0x0202 -#define AB4500_LOW_BAT_REG 0x0203 -#define AB4500_BATT_OK_REG 0x0204 -#define AB4500_SYSCLK_TIMER_REG 0x0205 -#define AB4500_SMPSCLK_CTRL_REG 0x0206 -#define AB4500_SMPSCLK_SEL1_REG 0x0207 -#define AB4500_SMPSCLK_SEL2_REG 0x0208 -#define AB4500_SMPSCLK_SEL3_REG 0x0209 -#define AB4500_SYSULPCLK_CONF_REG 0x020A -#define AB4500_SYSULPCLK_CTRL1_REG 0x020B -#define AB4500_SYSCLK_CTRL_REG 0x020C -#define AB4500_SYSCLK_REQ1_VALID_REG 0x020D -#define AB4500_SYSCLK_REQ_VALID_REG 0x020E -#define AB4500_SYSCTRL_SPARE_REG 0x020F -#define AB4500_PAD_CONF_REG 0x0210 - -/* - * Regu control1 register offsets - * Bank = 0x03 - */ -#define AB4500_REGU_SERIAL_CTRL1_REG 0x0300 -#define AB4500_REGU_SERIAL_CTRL2_REG 0x0301 -#define AB4500_REGU_SERIAL_CTRL3_REG 0x0302 -#define AB4500_REGU_REQ_CTRL1_REG 0x0303 -#define AB4500_REGU_REQ_CTRL2_REG 0x0304 -#define AB4500_REGU_REQ_CTRL3_REG 0x0305 -#define AB4500_REGU_REQ_CTRL4_REG 0x0306 -#define AB4500_REGU_MISC1_REG 0x0380 -#define AB4500_REGU_OTGSUPPLY_CTRL_REG 0x0381 -#define AB4500_REGU_VUSB_CTRL_REG 0x0382 -#define AB4500_REGU_VAUDIO_SUPPLY_REG 0x0383 -#define AB4500_REGU_CTRL1_SPARE_REG 0x0384 - -/* - * Regu control2 Vmod register offsets - */ -#define AB4500_REGU_VMOD_REGU_REG 0x0440 -#define AB4500_REGU_VMOD_SEL1_REG 0x0441 -#define AB4500_REGU_VMOD_SEL2_REG 0x0442 -#define AB4500_REGU_CTRL_DISCH_REG 0x0443 -#define AB4500_REGU_CTRL_DISCH2_REG 0x0444 - -/* - * USB/ULPI register offsets - * Bank : 0x5 - */ -#define AB4500_USB_LINE_STAT_REG 0x0580 -#define AB4500_USB_LINE_CTRL1_REG 0x0581 -#define AB4500_USB_LINE_CTRL2_REG 0x0582 -#define AB4500_USB_LINE_CTRL3_REG 0x0583 -#define AB4500_USB_LINE_CTRL4_REG 0x0584 -#define AB4500_USB_LINE_CTRL5_REG 0x0585 -#define AB4500_USB_OTG_CTRL_REG 0x0587 -#define AB4500_USB_OTG_STAT_REG 0x0588 -#define AB4500_USB_OTG_STAT_REG 0x0588 -#define AB4500_USB_CTRL_SPARE_REG 0x0589 -#define AB4500_USB_PHY_CTRL_REG 0x058A - -/* - * TVOUT / CTRL register offsets - * Bank : 0x06 - */ -#define AB4500_TVOUT_CTRL_REG 0x0680 - -/* - * DBI register offsets - * Bank : 0x07 - */ -#define AB4500_DBI_REG1_REG 0x0700 -#define AB4500_DBI_REG2_REG 0x0701 - -/* - * ECI regsiter offsets - * Bank : 0x08 - */ -#define AB4500_ECI_CTRL_REG 0x0800 -#define AB4500_ECI_HOOKLEVEL_REG 0x0801 -#define AB4500_ECI_DATAOUT_REG 0x0802 -#define AB4500_ECI_DATAIN_REG 0x0803 - -/* - * AV Connector register offsets - * Bank : 0x08 - */ -#define AB4500_AV_CONN_REG 0x0840 - -/* - * Accessory detection register offsets - * Bank : 0x08 - */ -#define AB4500_ACC_DET_DB1_REG 0x0880 -#define AB4500_ACC_DET_DB2_REG 0x0881 - -/* - * GPADC register offsets - * Bank : 0x0A - */ -#define AB4500_GPADC_CTRL1_REG 0x0A00 -#define AB4500_GPADC_CTRL2_REG 0x0A01 -#define AB4500_GPADC_CTRL3_REG 0x0A02 -#define AB4500_GPADC_AUTO_TIMER_REG 0x0A03 -#define AB4500_GPADC_STAT_REG 0x0A04 -#define AB4500_GPADC_MANDATAL_REG 0x0A05 -#define AB4500_GPADC_MANDATAH_REG 0x0A06 -#define AB4500_GPADC_AUTODATAL_REG 0x0A07 -#define AB4500_GPADC_AUTODATAH_REG 0x0A08 -#define AB4500_GPADC_MUX_CTRL_REG 0x0A09 - -/* - * Charger / status register offfsets - * Bank : 0x0B - */ -#define AB4500_CH_STATUS1_REG 0x0B00 -#define AB4500_CH_STATUS2_REG 0x0B01 -#define AB4500_CH_USBCH_STAT1_REG 0x0B02 -#define AB4500_CH_USBCH_STAT2_REG 0x0B03 -#define AB4500_CH_FSM_STAT_REG 0x0B04 -#define AB4500_CH_STAT_REG 0x0B05 - -/* - * Charger / control register offfsets - * Bank : 0x0B - */ -#define AB4500_CH_VOLT_LVL_REG 0x0B40 - -/* - * Charger / main control register offfsets - * Bank : 0x0B - */ -#define AB4500_MCH_CTRL1 0x0B80 -#define AB4500_MCH_CTRL2 0x0B81 -#define AB4500_MCH_IPT_CURLVL_REG 0x0B82 -#define AB4500_CH_WD_REG 0x0B83 - -/* - * Charger / USB control register offsets - * Bank : 0x0B - */ -#define AB4500_USBCH_CTRL1_REG 0x0BC0 -#define AB4500_USBCH_CTRL2_REG 0x0BC1 -#define AB4500_USBCH_IPT_CRNTLVL_REG 0x0BC2 - -/* - * RTC bank register offsets - * Bank : 0xF - */ -#define AB4500_RTC_SOFF_STAT_REG 0x0F00 -#define AB4500_RTC_CC_CONF_REG 0x0F01 -#define AB4500_RTC_READ_REQ_REG 0x0F02 -#define AB4500_RTC_WATCH_TSECMID_REG 0x0F03 -#define AB4500_RTC_WATCH_TSECHI_REG 0x0F04 -#define AB4500_RTC_WATCH_TMIN_LOW_REG 0x0F05 -#define AB4500_RTC_WATCH_TMIN_MID_REG 0x0F06 -#define AB4500_RTC_WATCH_TMIN_HI_REG 0x0F07 -#define AB4500_RTC_ALRM_MIN_LOW_REG 0x0F08 -#define AB4500_RTC_ALRM_MIN_MID_REG 0x0F09 -#define AB4500_RTC_ALRM_MIN_HI_REG 0x0F0A -#define AB4500_RTC_STAT_REG 0x0F0B -#define AB4500_RTC_BKUP_CHG_REG 0x0F0C -#define AB4500_RTC_FORCE_BKUP_REG 0x0F0D -#define AB4500_RTC_CALIB_REG 0x0F0E -#define AB4500_RTC_SWITCH_STAT_REG 0x0F0F - -/* - * PWM Out generators - * Bank: 0x10 - */ -#define AB4500_PWM_OUT_CTRL1_REG 0x1060 -#define AB4500_PWM_OUT_CTRL2_REG 0x1061 -#define AB4500_PWM_OUT_CTRL3_REG 0x1062 -#define AB4500_PWM_OUT_CTRL4_REG 0x1063 -#define AB4500_PWM_OUT_CTRL5_REG 0x1064 -#define AB4500_PWM_OUT_CTRL6_REG 0x1065 -#define AB4500_PWM_OUT_CTRL7_REG 0x1066 - -#define AB4500_I2C_PAD_CTRL_REG 0x1067 -#define AB4500_REV_REG 0x1080 - -/** - * struct ab4500 - * @spi: spi device structure - * @tx_buf: transmit buffer - * @rx_buf: receive buffer - * @lock: sync primitive - */ -struct ab4500 { - struct spi_device *spi; - unsigned long tx_buf[4]; - unsigned long rx_buf[4]; - struct mutex lock; -}; - -int ab4500_write(struct ab4500 *ab4500, unsigned char block, - unsigned long addr, unsigned char data); -int ab4500_read(struct ab4500 *ab4500, unsigned char block, - unsigned long addr); - -#endif /* MFD_AB4500_H */ diff --git a/include/linux/mfd/ab8500.h b/include/linux/mfd/ab8500.h new file mode 100644 index 000000000000..b63ff3ba3351 --- /dev/null +++ b/include/linux/mfd/ab8500.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License Terms: GNU General Public License v2 + * Author: Srinidhi Kasagar + */ +#ifndef MFD_AB8500_H +#define MFD_AB8500_H + +#include + +/* + * Interrupts + */ + +#define AB8500_INT_MAIN_EXT_CH_NOT_OK 0 +#define AB8500_INT_UN_PLUG_TV_DET 1 +#define AB8500_INT_PLUG_TV_DET 2 +#define AB8500_INT_TEMP_WARM 3 +#define AB8500_INT_PON_KEY2DB_F 4 +#define AB8500_INT_PON_KEY2DB_R 5 +#define AB8500_INT_PON_KEY1DB_F 6 +#define AB8500_INT_PON_KEY1DB_R 7 +#define AB8500_INT_BATT_OVV 8 +#define AB8500_INT_MAIN_CH_UNPLUG_DET 10 +#define AB8500_INT_MAIN_CH_PLUG_DET 11 +#define AB8500_INT_USB_ID_DET_F 12 +#define AB8500_INT_USB_ID_DET_R 13 +#define AB8500_INT_VBUS_DET_F 14 +#define AB8500_INT_VBUS_DET_R 15 +#define AB8500_INT_VBUS_CH_DROP_END 16 +#define AB8500_INT_RTC_60S 17 +#define AB8500_INT_RTC_ALARM 18 +#define AB8500_INT_BAT_CTRL_INDB 20 +#define AB8500_INT_CH_WD_EXP 21 +#define AB8500_INT_VBUS_OVV 22 +#define AB8500_INT_MAIN_CH_DROP_END 23 +#define AB8500_INT_CCN_CONV_ACC 24 +#define AB8500_INT_INT_AUD 25 +#define AB8500_INT_CCEOC 26 +#define AB8500_INT_CC_INT_CALIB 27 +#define AB8500_INT_LOW_BAT_F 28 +#define AB8500_INT_LOW_BAT_R 29 +#define AB8500_INT_BUP_CHG_NOT_OK 30 +#define AB8500_INT_BUP_CHG_OK 31 +#define AB8500_INT_GP_HW_ADC_CONV_END 32 +#define AB8500_INT_ACC_DETECT_1DB_F 33 +#define AB8500_INT_ACC_DETECT_1DB_R 34 +#define AB8500_INT_ACC_DETECT_22DB_F 35 +#define AB8500_INT_ACC_DETECT_22DB_R 36 +#define AB8500_INT_ACC_DETECT_21DB_F 37 +#define AB8500_INT_ACC_DETECT_21DB_R 38 +#define AB8500_INT_GP_SW_ADC_CONV_END 39 +#define AB8500_INT_BTEMP_LOW 72 +#define AB8500_INT_BTEMP_LOW_MEDIUM 73 +#define AB8500_INT_BTEMP_MEDIUM_HIGH 74 +#define AB8500_INT_BTEMP_HIGH 75 +#define AB8500_INT_USB_CHARGER_NOT_OK 81 +#define AB8500_INT_ID_WAKEUP_R 82 +#define AB8500_INT_ID_DET_R1R 84 +#define AB8500_INT_ID_DET_R2R 85 +#define AB8500_INT_ID_DET_R3R 86 +#define AB8500_INT_ID_DET_R4R 87 +#define AB8500_INT_ID_WAKEUP_F 88 +#define AB8500_INT_ID_DET_R1F 90 +#define AB8500_INT_ID_DET_R2F 91 +#define AB8500_INT_ID_DET_R3F 92 +#define AB8500_INT_ID_DET_R4F 93 +#define AB8500_INT_USB_CHG_DET_DONE 94 +#define AB8500_INT_USB_CH_TH_PROT_F 96 +#define AB8500_INT_USB_CH_TH_PROP_R 97 +#define AB8500_INT_MAIN_CH_TH_PROP_F 98 +#define AB8500_INT_MAIN_CH_TH_PROT_R 99 +#define AB8500_INT_USB_CHARGER_NOT_OKF 103 + +#define AB8500_NR_IRQS 104 +#define AB8500_NUM_IRQ_REGS 13 + +/** + * struct ab8500 - ab8500 internal structure + * @dev: parent device + * @lock: read/write operations lock + * @irq_lock: genirq bus lock + * @revision: chip revision + * @irq: irq line + * @write: register write + * @read: register read + * @rx_buf: rx buf for SPI + * @tx_buf: tx buf for SPI + * @mask: cache of IRQ regs for bus lock + * @oldmask: cache of previous IRQ regs for bus lock + */ +struct ab8500 { + struct device *dev; + struct mutex lock; + struct mutex irq_lock; + int revision; + int irq_base; + int irq; + + int (*write) (struct ab8500 *a8500, u16 addr, u8 data); + int (*read) (struct ab8500 *a8500, u16 addr); + + unsigned long tx_buf[4]; + unsigned long rx_buf[4]; + + u8 mask[AB8500_NUM_IRQ_REGS]; + u8 oldmask[AB8500_NUM_IRQ_REGS]; +}; + +/** + * struct ab8500_platform_data - AB8500 platform data + * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used + * @init: board-specific initialization after detection of ab8500 + */ +struct ab8500_platform_data { + int irq_base; + void (*init) (struct ab8500 *); +}; + +extern int ab8500_write(struct ab8500 *a8500, u16 addr, u8 data); +extern int ab8500_read(struct ab8500 *a8500, u16 addr); +extern int ab8500_set_bits(struct ab8500 *a8500, u16 addr, u8 mask, u8 data); + +extern int __devinit ab8500_init(struct ab8500 *ab8500); +extern int __devexit ab8500_exit(struct ab8500 *ab8500); + +#endif /* MFD_AB8500_H */ -- cgit v1.2.3 From 28ade0f217a3a3ff992b01e06e6e425c250a8406 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 21 May 2010 00:50:17 +0200 Subject: mfd: Remove unneeded and dangerous clearing of clientdata Unlike real i2c-devices which get detached from the driver, dummy-devices get truly unregistered. So, there has never been a need to clear the clientdata because the device will go away anyhow. For the occasions fixed here, clearing clientdata was even dangerous as the structure was freed already. Signed-off-by: Wolfram Sang Acked-by: Jean Delvare Signed-off-by: Samuel Ortiz --- drivers/mfd/88pm860x-i2c.c | 1 - drivers/mfd/max8925-i2c.c | 2 -- 2 files changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c index b0bade1881d4..c933b64d1283 100644 --- a/drivers/mfd/88pm860x-i2c.c +++ b/drivers/mfd/88pm860x-i2c.c @@ -200,7 +200,6 @@ static int __devexit pm860x_remove(struct i2c_client *client) pm860x_device_exit(chip); i2c_unregister_device(chip->companion); - i2c_set_clientdata(chip->companion, NULL); i2c_set_clientdata(chip->client, NULL); i2c_set_clientdata(client, NULL); kfree(chip); diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c index d9fd8785da4d..e73f3f5252a8 100644 --- a/drivers/mfd/max8925-i2c.c +++ b/drivers/mfd/max8925-i2c.c @@ -173,8 +173,6 @@ static int __devexit max8925_remove(struct i2c_client *client) max8925_device_exit(chip); i2c_unregister_device(chip->adc); i2c_unregister_device(chip->rtc); - i2c_set_clientdata(chip->adc, NULL); - i2c_set_clientdata(chip->rtc, NULL); i2c_set_clientdata(chip->i2c, NULL); kfree(chip); return 0; -- cgit v1.2.3 From ae9f52f05c8223c8b4e18b042febf7a7bb46332a Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 20 May 2010 10:39:00 +0200 Subject: mfd: Storage class for timberdale should be before const qualifier The C99 specification states in section 6.11.5: The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature. Signed-off-by: Tobias Klauser Signed-off-by: Samuel Ortiz --- drivers/mfd/timberdale.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c index 2d4691acd033..ac5995026c88 100644 --- a/drivers/mfd/timberdale.c +++ b/drivers/mfd/timberdale.c @@ -86,7 +86,7 @@ timberdale_ocores_platform_data = { .num_devices = ARRAY_SIZE(timberdale_i2c_board_info) }; -const static __devinitconst struct resource timberdale_xiic_resources[] = { +static const __devinitconst struct resource timberdale_xiic_resources[] = { { .start = XIICOFFSET, .end = XIICEND, @@ -99,7 +99,7 @@ const static __devinitconst struct resource timberdale_xiic_resources[] = { }, }; -const static __devinitconst struct resource timberdale_ocores_resources[] = { +static const __devinitconst struct resource timberdale_ocores_resources[] = { { .start = OCORESOFFSET, .end = OCORESEND, @@ -148,7 +148,7 @@ static __devinitdata struct xspi_platform_data timberdale_xspi_platform_data = { */ }; -const static __devinitconst struct resource timberdale_spi_resources[] = { +static const __devinitconst struct resource timberdale_spi_resources[] = { { .start = SPIOFFSET, .end = SPIEND, @@ -161,7 +161,7 @@ const static __devinitconst struct resource timberdale_spi_resources[] = { }, }; -const static __devinitconst struct resource timberdale_eth_resources[] = { +static const __devinitconst struct resource timberdale_eth_resources[] = { { .start = ETHOFFSET, .end = ETHEND, @@ -181,7 +181,7 @@ static __devinitdata struct timbgpio_platform_data .irq_base = 200, }; -const static __devinitconst struct resource timberdale_gpio_resources[] = { +static const __devinitconst struct resource timberdale_gpio_resources[] = { { .start = GPIOOFFSET, .end = GPIOEND, @@ -194,7 +194,7 @@ const static __devinitconst struct resource timberdale_gpio_resources[] = { }, }; -const static __devinitconst struct resource timberdale_mlogicore_resources[] = { +static const __devinitconst struct resource timberdale_mlogicore_resources[] = { { .start = MLCOREOFFSET, .end = MLCOREEND, @@ -212,7 +212,7 @@ const static __devinitconst struct resource timberdale_mlogicore_resources[] = { }, }; -const static __devinitconst struct resource timberdale_uart_resources[] = { +static const __devinitconst struct resource timberdale_uart_resources[] = { { .start = UARTOFFSET, .end = UARTEND, @@ -225,7 +225,7 @@ const static __devinitconst struct resource timberdale_uart_resources[] = { }, }; -const static __devinitconst struct resource timberdale_uartlite_resources[] = { +static const __devinitconst struct resource timberdale_uartlite_resources[] = { { .start = UARTLITEOFFSET, .end = UARTLITEEND, @@ -238,7 +238,7 @@ const static __devinitconst struct resource timberdale_uartlite_resources[] = { }, }; -const static __devinitconst struct resource timberdale_radio_resources[] = { +static const __devinitconst struct resource timberdale_radio_resources[] = { { .start = RDSOFFSET, .end = RDSEND, @@ -331,7 +331,7 @@ static __devinitdata struct timb_dma_platform_data timb_dma_platform_data = { } }; -const static __devinitconst struct resource timberdale_dma_resources[] = { +static const __devinitconst struct resource timberdale_dma_resources[] = { { .start = DMAOFFSET, .end = DMAEND, -- cgit v1.2.3 From 191211f50f35deb5b3b80bc7b620cfd4b0a4a2d9 Mon Sep 17 00:00:00 2001 From: Ilkka Koskinen Date: Thu, 20 May 2010 13:04:20 +0300 Subject: mfd: Rename twl5031 sih modules Fix the names of twl5031 specific sih modules to match the documentation. Signed-off-by: Ilkka Koskinen Signed-off-by: Samuel Ortiz --- drivers/mfd/twl4030-irq.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index 202bdd59632d..097f24d8bceb 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c @@ -232,10 +232,11 @@ static const struct sih sih_modules_twl5031[8] = { }, [6] = { /* - * ACI doesn't use the same SIH organization. - * For example, it supports only one interrupt line + * ECI/DBI doesn't use the same SIH organization. + * For example, it supports only one interrupt output line. + * That is, the interrupts are seen on both INT1 and INT2 lines. */ - .name = "aci", + .name = "eci_dbi", .module = TWL5031_MODULE_ACCESSORY, .bits = 9, .bytes_ixr = 2, @@ -247,8 +248,8 @@ static const struct sih sih_modules_twl5031[8] = { }, [7] = { - /* Accessory */ - .name = "acc", + /* Audio accessory */ + .name = "audio", .module = TWL5031_MODULE_ACCESSORY, .control_offset = TWL5031_ACCSIHCTRL, .bits = 2, -- cgit v1.2.3 From 752138df0dc2daaae09379c754caeb08c97905dc Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 22 May 2010 16:57:26 -0400 Subject: cpuidle: make cpuidle_curr_driver static cpuidle_register_driver() sets cpuidle_curr_driver cpuidle_unregister_driver() clears cpuidle_curr_driver We should't expose cpuidle_curr_driver to potential modification except via these interfaces. So make it static and create cpuidle_get_driver() to observe it. Signed-off-by: Len Brown --- drivers/cpuidle/cpuidle.c | 12 +++++++----- drivers/cpuidle/cpuidle.h | 1 - drivers/cpuidle/driver.c | 11 ++++++++++- drivers/cpuidle/sysfs.c | 5 +++-- include/linux/cpuidle.h | 2 ++ 5 files changed, 22 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 12fdd3987a36..199488576a05 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -156,7 +156,7 @@ int cpuidle_enable_device(struct cpuidle_device *dev) if (dev->enabled) return 0; - if (!cpuidle_curr_driver || !cpuidle_curr_governor) + if (!cpuidle_get_driver() || !cpuidle_curr_governor) return -EIO; if (!dev->state_count) return -EINVAL; @@ -207,7 +207,7 @@ void cpuidle_disable_device(struct cpuidle_device *dev) { if (!dev->enabled) return; - if (!cpuidle_curr_driver || !cpuidle_curr_governor) + if (!cpuidle_get_driver() || !cpuidle_curr_governor) return; dev->enabled = 0; @@ -271,10 +271,11 @@ static int __cpuidle_register_device(struct cpuidle_device *dev) { int ret; struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); + struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver(); if (!sys_dev) return -EINVAL; - if (!try_module_get(cpuidle_curr_driver->owner)) + if (!try_module_get(cpuidle_driver->owner)) return -EINVAL; init_completion(&dev->kobj_unregister); @@ -284,7 +285,7 @@ static int __cpuidle_register_device(struct cpuidle_device *dev) per_cpu(cpuidle_devices, dev->cpu) = dev; list_add(&dev->device_list, &cpuidle_detected_devices); if ((ret = cpuidle_add_sysfs(sys_dev))) { - module_put(cpuidle_curr_driver->owner); + module_put(cpuidle_driver->owner); return ret; } @@ -325,6 +326,7 @@ EXPORT_SYMBOL_GPL(cpuidle_register_device); void cpuidle_unregister_device(struct cpuidle_device *dev) { struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); + struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver(); if (dev->registered == 0) return; @@ -340,7 +342,7 @@ void cpuidle_unregister_device(struct cpuidle_device *dev) cpuidle_resume_and_unlock(); - module_put(cpuidle_curr_driver->owner); + module_put(cpuidle_driver->owner); } EXPORT_SYMBOL_GPL(cpuidle_unregister_device); diff --git a/drivers/cpuidle/cpuidle.h b/drivers/cpuidle/cpuidle.h index 9476ba33ee2c..33e50d556f17 100644 --- a/drivers/cpuidle/cpuidle.h +++ b/drivers/cpuidle/cpuidle.h @@ -9,7 +9,6 @@ /* For internal use only */ extern struct cpuidle_governor *cpuidle_curr_governor; -extern struct cpuidle_driver *cpuidle_curr_driver; extern struct list_head cpuidle_governors; extern struct list_head cpuidle_detected_devices; extern struct mutex cpuidle_lock; diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c index 826b5c0aa12b..fd1601e3d125 100644 --- a/drivers/cpuidle/driver.c +++ b/drivers/cpuidle/driver.c @@ -14,7 +14,7 @@ #include "cpuidle.h" -struct cpuidle_driver *cpuidle_curr_driver; +static struct cpuidle_driver *cpuidle_curr_driver; DEFINE_SPINLOCK(cpuidle_driver_lock); /** @@ -39,6 +39,15 @@ int cpuidle_register_driver(struct cpuidle_driver *drv) EXPORT_SYMBOL_GPL(cpuidle_register_driver); +/** + * cpuidle_get_driver - return the current driver + */ +struct cpuidle_driver *cpuidle_get_driver(void) +{ + return cpuidle_curr_driver; +} +EXPORT_SYMBOL_GPL(cpuidle_get_driver); + /** * cpuidle_unregister_driver - unregisters a driver * @drv: the driver diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index 0ba9c8b8ee74..0310ffaec9df 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c @@ -47,10 +47,11 @@ static ssize_t show_current_driver(struct sysdev_class *class, char *buf) { ssize_t ret; + struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver(); spin_lock(&cpuidle_driver_lock); - if (cpuidle_curr_driver) - ret = sprintf(buf, "%s\n", cpuidle_curr_driver->name); + if (cpuidle_driver) + ret = sprintf(buf, "%s\n", cpuidle_driver->name); else ret = sprintf(buf, "none\n"); spin_unlock(&cpuidle_driver_lock); diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index f5e6480dc16f..55215cce5005 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -125,6 +125,7 @@ struct cpuidle_driver { #ifdef CONFIG_CPU_IDLE extern int cpuidle_register_driver(struct cpuidle_driver *drv); +struct cpuidle_driver *cpuidle_get_driver(void); extern void cpuidle_unregister_driver(struct cpuidle_driver *drv); extern int cpuidle_register_device(struct cpuidle_device *dev); extern void cpuidle_unregister_device(struct cpuidle_device *dev); @@ -138,6 +139,7 @@ extern void cpuidle_disable_device(struct cpuidle_device *dev); static inline int cpuidle_register_driver(struct cpuidle_driver *drv) {return -ENODEV; } +static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; } static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { } static inline int cpuidle_register_device(struct cpuidle_device *dev) {return -ENODEV; } -- cgit v1.2.3 From 541adf7cd937b3895c7645406a9b060504df453b Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 22 May 2010 17:03:29 -0400 Subject: ACPI: allow a native cpuidle driver to displace ACPI The ACPI driver would fail probe when it found that another driver had previously registered with cpuidle. But this is a natural situation, as a native hardware cpuidle driver should be able to bind instead of ACPI, and the ACPI processor driver should be able to handle yielding control of C-states while still handling P-states and T-states. Add a KERN_DEBUG line showing when acpi_idle does successfully register. Signed-off-by: Len Brown --- drivers/acpi/processor_driver.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 5675d9747e87..deefa8591746 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -616,7 +616,8 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) acpi_processor_get_limit_info(pr); - acpi_processor_power_init(pr, device); + if (cpuidle_get_driver() == &acpi_idle_driver) + acpi_processor_power_init(pr, device); pr->cdev = thermal_cooling_device_register("Processor", device, &processor_cooling_ops); @@ -920,9 +921,10 @@ static int __init acpi_processor_init(void) if (!acpi_processor_dir) return -ENOMEM; #endif - result = cpuidle_register_driver(&acpi_idle_driver); - if (result < 0) - goto out_proc; + + if (!cpuidle_register_driver(&acpi_idle_driver)) + printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", + acpi_idle_driver.name); result = acpi_bus_register_driver(&acpi_processor_driver); if (result < 0) @@ -941,7 +943,6 @@ static int __init acpi_processor_init(void) out_cpuidle: cpuidle_unregister_driver(&acpi_idle_driver); -out_proc: #ifdef CONFIG_ACPI_PROCFS remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); #endif -- cgit v1.2.3 From a7d27c37533524e23bbdc9ba1d78e3241b7483ea Mon Sep 17 00:00:00 2001 From: Len Brown Date: Mon, 24 May 2010 11:41:00 -0400 Subject: acpi_pad: uses MONITOR/MWAIT, so it doesn't need to clear TS_POLLING api_pad exclusively uses MONITOR/MWAIT to sleep in idle, so it does not need the wakeup IPI during idle sleep that is provoked by clearing TS_POLLING. Signed-off-by: Len Brown Cc: Shaohua Li --- drivers/acpi/acpi_pad.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 62122134693b..7edf053983c5 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -168,13 +168,6 @@ static int power_saving_thread(void *data) do_sleep = 0; - current_thread_info()->status &= ~TS_POLLING; - /* - * TS_POLLING-cleared state must be visible before we test - * NEED_RESCHED: - */ - smp_mb(); - expire_time = jiffies + HZ * (100 - idle_pct) / 100; while (!need_resched()) { @@ -200,8 +193,6 @@ static int power_saving_thread(void *data) } } - current_thread_info()->status |= TS_POLLING; - /* * current sched_rt has threshold for rt task running time. * When a rt task uses 95% CPU time, the rt thread will be -- cgit v1.2.3 From 7ea8085910ef3dd4f3cad6845aaa2b580d39b115 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 26 May 2010 17:53:25 +0200 Subject: drop unused dentry argument to ->fsync Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- Documentation/filesystems/Locking | 2 +- Documentation/filesystems/vfs.txt | 2 +- arch/powerpc/platforms/cell/spufs/file.c | 3 +-- drivers/char/ps3flash.c | 3 +-- drivers/mtd/ubi/cdev.c | 3 +-- drivers/staging/pohmelfs/inode.c | 2 +- drivers/usb/gadget/printer.c | 2 +- drivers/video/fb_defio.c | 2 +- fs/9p/vfs_file.c | 6 ++---- fs/affs/affs.h | 2 +- fs/affs/file.c | 4 ++-- fs/afs/internal.h | 2 +- fs/afs/write.c | 3 ++- fs/bad_inode.c | 3 +-- fs/block_dev.c | 7 +------ fs/btrfs/ctree.h | 2 +- fs/btrfs/file.c | 3 ++- fs/ceph/caps.c | 4 ++-- fs/ceph/dir.c | 5 ++--- fs/ceph/super.h | 2 +- fs/cifs/cifsfs.h | 2 +- fs/cifs/file.c | 4 ++-- fs/coda/coda_int.h | 3 +-- fs/coda/file.c | 4 ++-- fs/ecryptfs/file.c | 2 +- fs/exofs/file.c | 7 +++---- fs/ext2/ext2.h | 2 +- fs/ext2/file.c | 6 +++--- fs/ext3/fsync.c | 4 ++-- fs/ext4/ext4.h | 2 +- fs/ext4/fsync.c | 8 ++++---- fs/fat/fat.h | 3 +-- fs/fat/file.c | 6 +++--- fs/fuse/dir.c | 5 ++--- fs/fuse/file.c | 9 ++++----- fs/fuse/fuse_i.h | 3 +-- fs/gfs2/file.c | 4 ++-- fs/hostfs/hostfs_kern.c | 4 ++-- fs/hpfs/file.c | 4 ++-- fs/hpfs/hpfs_fn.h | 2 +- fs/hppfs/hppfs.c | 2 +- fs/jffs2/file.c | 4 ++-- fs/jffs2/os-linux.h | 2 +- fs/jfs/file.c | 4 ++-- fs/jfs/jfs_inode.h | 2 +- fs/libfs.c | 6 +++--- fs/logfs/file.c | 4 ++-- fs/logfs/logfs.h | 2 +- fs/ncpfs/file.c | 2 +- fs/nfs/dir.c | 6 ++++-- fs/nfs/file.c | 5 +++-- fs/nilfs2/file.c | 4 ++-- fs/nilfs2/nilfs.h | 2 +- fs/ntfs/dir.c | 5 ++--- fs/ntfs/file.c | 9 ++------- fs/ocfs2/file.c | 7 +++---- fs/reiserfs/dir.c | 8 +++----- fs/reiserfs/file.c | 5 ++--- fs/smbfs/file.c | 3 ++- fs/sync.c | 8 +++----- fs/ubifs/file.c | 4 ++-- fs/ubifs/ubifs.h | 2 +- fs/xfs/linux-2.6/xfs_file.c | 10 +++++----- include/linux/buffer_head.h | 2 +- include/linux/ext3_fs.h | 2 +- include/linux/fb.h | 5 +---- include/linux/fs.h | 8 ++++---- include/trace/events/ext4.h | 6 ++++-- ipc/shm.c | 11 ++++------- 69 files changed, 129 insertions(+), 157 deletions(-) (limited to 'drivers') diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 61c98f03baa1..96d4293607ec 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -380,7 +380,7 @@ prototypes: int (*open) (struct inode *, struct file *); int (*flush) (struct file *); int (*release) (struct inode *, struct file *); - int (*fsync) (struct file *, struct dentry *, int datasync); + int (*fsync) (struct file *, int datasync); int (*aio_fsync) (struct kiocb *, int datasync); int (*fasync) (int, struct file *, int); int (*lock) (struct file *, int, struct file_lock *); diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index b66858538df5..d4f5731dcbbb 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -729,7 +729,7 @@ struct file_operations { int (*open) (struct inode *, struct file *); int (*flush) (struct file *); int (*release) (struct inode *, struct file *); - int (*fsync) (struct file *, struct dentry *, int datasync); + int (*fsync) (struct file *, int datasync); int (*aio_fsync) (struct kiocb *, int datasync); int (*fasync) (int, struct file *, int); int (*lock) (struct file *, int, struct file_lock *); diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 5c2808252516..1a40da92154c 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -1849,8 +1849,7 @@ out: return ret; } -static int spufs_mfc_fsync(struct file *file, struct dentry *dentry, - int datasync) +static int spufs_mfc_fsync(struct file *file, int datasync) { return spufs_mfc_flush(file, NULL); } diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c index 606048b72bcf..85c004a518ee 100644 --- a/drivers/char/ps3flash.c +++ b/drivers/char/ps3flash.c @@ -305,8 +305,7 @@ static int ps3flash_flush(struct file *file, fl_owner_t id) return ps3flash_writeback(ps3flash_dev); } -static int ps3flash_fsync(struct file *file, struct dentry *dentry, - int datasync) +static int ps3flash_fsync(struct file *file, int datasync) { return ps3flash_writeback(ps3flash_dev); } diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 72ebb3f06b86..4dfa6b90c21c 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -189,8 +189,7 @@ static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin) return new_offset; } -static int vol_cdev_fsync(struct file *file, struct dentry *dentry, - int datasync) +static int vol_cdev_fsync(struct file *file, int datasync) { struct ubi_volume_desc *desc = file->private_data; struct ubi_device *ubi = desc->vol->ubi; diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c index 9286e863b0e7..e92595eff1b8 100644 --- a/drivers/staging/pohmelfs/inode.c +++ b/drivers/staging/pohmelfs/inode.c @@ -880,7 +880,7 @@ static struct inode *pohmelfs_alloc_inode(struct super_block *sb) /* * We want fsync() to work on POHMELFS. */ -static int pohmelfs_fsync(struct file *file, struct dentry *dentry, int datasync) +static int pohmelfs_fsync(struct file *file, int datasync) { struct inode *inode = file->f_mapping->host; struct writeback_control wbc = { diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 6b8bf8c781c4..43abf55d8c60 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -794,7 +794,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) } static int -printer_fsync(struct file *fd, struct dentry *dentry, int datasync) +printer_fsync(struct file *fd, int datasync) { struct printer_dev *dev = fd->private_data; unsigned long flags; diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c index 1105a591dcc1..073c9b408cf7 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fb_defio.c @@ -66,7 +66,7 @@ static int fb_deferred_io_fault(struct vm_area_struct *vma, return 0; } -int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, int datasync) +int fb_deferred_io_fsync(struct file *file, int datasync) { struct fb_info *info = file->private_data; diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 25b300e1c9d7..2bedc6c94fc2 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -257,15 +257,13 @@ v9fs_file_write(struct file *filp, const char __user * data, return total; } -static int v9fs_file_fsync(struct file *filp, struct dentry *dentry, - int datasync) +static int v9fs_file_fsync(struct file *filp, int datasync) { struct p9_fid *fid; struct p9_wstat wstat; int retval; - P9_DPRINTK(P9_DEBUG_VFS, "filp %p dentry %p datasync %x\n", filp, - dentry, datasync); + P9_DPRINTK(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync); fid = filp->private_data; v9fs_blank_wstat(&wstat); diff --git a/fs/affs/affs.h b/fs/affs/affs.h index 861dae68ac12..f05b6155ccc8 100644 --- a/fs/affs/affs.h +++ b/fs/affs/affs.h @@ -183,7 +183,7 @@ extern int affs_add_entry(struct inode *dir, struct inode *inode, struct dent void affs_free_prealloc(struct inode *inode); extern void affs_truncate(struct inode *); -int affs_file_fsync(struct file *, struct dentry *, int); +int affs_file_fsync(struct file *, int); /* dir.c */ diff --git a/fs/affs/file.c b/fs/affs/file.c index 184e55c1c9ba..322710c3eedf 100644 --- a/fs/affs/file.c +++ b/fs/affs/file.c @@ -916,9 +916,9 @@ affs_truncate(struct inode *inode) affs_free_prealloc(inode); } -int affs_file_fsync(struct file *filp, struct dentry *dentry, int datasync) +int affs_file_fsync(struct file *filp, int datasync) { - struct inode * inode = dentry->d_inode; + struct inode *inode = filp->f_mapping->host; int ret, err; ret = write_inode_now(inode, 0); diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 807f284cc75e..5f679b77ce24 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -740,7 +740,7 @@ extern void afs_pages_written_back(struct afs_vnode *, struct afs_call *); extern ssize_t afs_file_write(struct kiocb *, const struct iovec *, unsigned long, loff_t); extern int afs_writeback_all(struct afs_vnode *); -extern int afs_fsync(struct file *, struct dentry *, int); +extern int afs_fsync(struct file *, int); /*****************************************************************************/ diff --git a/fs/afs/write.c b/fs/afs/write.c index 3bed54a294d4..3dab9e9948d0 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c @@ -701,8 +701,9 @@ int afs_writeback_all(struct afs_vnode *vnode) * - the return status from this call provides a reliable indication of * whether any write errors occurred for this process. */ -int afs_fsync(struct file *file, struct dentry *dentry, int datasync) +int afs_fsync(struct file *file, int datasync) { + struct dentry *dentry = file->f_path.dentry; struct afs_writeback *wb, *xwb; struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode); int ret; diff --git a/fs/bad_inode.c b/fs/bad_inode.c index a05287a23f62..52e59bf4aa5f 100644 --- a/fs/bad_inode.c +++ b/fs/bad_inode.c @@ -93,8 +93,7 @@ static int bad_file_release(struct inode *inode, struct file *filp) return -EIO; } -static int bad_file_fsync(struct file *file, struct dentry *dentry, - int datasync) +static int bad_file_fsync(struct file *file, int datasync) { return -EIO; } diff --git a/fs/block_dev.c b/fs/block_dev.c index 26e5f5026620..d0b37e626a1a 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -358,12 +358,7 @@ static loff_t block_llseek(struct file *file, loff_t offset, int origin) return retval; } -/* - * Filp is never NULL; the only case when ->fsync() is called with - * NULL first argument is nfsd_sync_dir() and that's not a directory. - */ - -int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync) +int blkdev_fsync(struct file *filp, int datasync) { struct inode *bd_inode = filp->f_mapping->host; struct block_device *bdev = I_BDEV(bd_inode); diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index e9bf86415e86..29c20092847e 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2434,7 +2434,7 @@ void btrfs_update_iflags(struct inode *inode); void btrfs_inherit_iflags(struct inode *inode, struct inode *dir); /* file.c */ -int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync); +int btrfs_sync_file(struct file *file, int datasync); int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, int skip_pinned); int btrfs_check_file(struct btrfs_root *root, struct inode *inode); diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 79437c5eeb1e..787b50a16a14 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1101,8 +1101,9 @@ int btrfs_release_file(struct inode *inode, struct file *filp) * important optimization for directories because holding the mutex prevents * new operations on the dir while we write to disk. */ -int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) +int btrfs_sync_file(struct file *file, int datasync) { + struct dentry *dentry = file->f_path.dentry; struct inode *inode = dentry->d_inode; struct btrfs_root *root = BTRFS_I(inode)->root; int ret = 0; diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 0dd0b81e64f7..ae3e3a306445 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1776,9 +1776,9 @@ out: spin_unlock(&ci->i_unsafe_lock); } -int ceph_fsync(struct file *file, struct dentry *dentry, int datasync) +int ceph_fsync(struct file *file, int datasync) { - struct inode *inode = dentry->d_inode; + struct inode *inode = file->f_mapping->host; struct ceph_inode_info *ci = ceph_inode(inode); unsigned flush_tid; int ret; diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 4fd30900eff7..0057f4a07347 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -1107,10 +1107,9 @@ static ssize_t ceph_read_dir(struct file *file, char __user *buf, size_t size, * an fsync() on a dir will wait for any uncommitted directory * operations to commit. */ -static int ceph_dir_fsync(struct file *file, struct dentry *dentry, - int datasync) +static int ceph_dir_fsync(struct file *file, int datasync) { - struct inode *inode = dentry->d_inode; + struct inode *inode = file->f_path.dentry->d_inode; struct ceph_inode_info *ci = ceph_inode(inode); struct list_head *head = &ci->i_unsafe_dirops; struct ceph_mds_request *req; diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 3725c9ee9d08..dd1e7add656b 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -811,7 +811,7 @@ extern void ceph_put_cap(struct ceph_cap *cap); extern void ceph_queue_caps_release(struct inode *inode); extern int ceph_write_inode(struct inode *inode, struct writeback_control *wbc); -extern int ceph_fsync(struct file *file, struct dentry *dentry, int datasync); +extern int ceph_fsync(struct file *file, int datasync); extern void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc, struct ceph_mds_session *session); extern int ceph_get_cap_mds(struct inode *inode); diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 0242ff9cbf41..a7eb65c84b1c 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -84,7 +84,7 @@ extern ssize_t cifs_user_read(struct file *file, char __user *read_data, extern ssize_t cifs_user_write(struct file *file, const char __user *write_data, size_t write_size, loff_t *poffset); extern int cifs_lock(struct file *, int, struct file_lock *); -extern int cifs_fsync(struct file *, struct dentry *, int); +extern int cifs_fsync(struct file *, int); extern int cifs_flush(struct file *, fl_owner_t id); extern int cifs_file_mmap(struct file * , struct vm_area_struct *); extern const struct file_operations cifs_dir_ops; diff --git a/fs/cifs/file.c b/fs/cifs/file.c index a83541ec9713..f1ff785b2292 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1676,7 +1676,7 @@ static int cifs_write_end(struct file *file, struct address_space *mapping, return rc; } -int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) +int cifs_fsync(struct file *file, int datasync) { int xid; int rc = 0; @@ -1688,7 +1688,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) xid = GetXid(); cFYI(1, "Sync file - name: %s datasync: 0x%x", - dentry->d_name.name, datasync); + file->f_path.dentry->d_name.name, datasync); rc = filemap_write_and_wait(inode->i_mapping); if (rc == 0) { diff --git a/fs/coda/coda_int.h b/fs/coda/coda_int.h index d99860a33890..6b443ff43a19 100644 --- a/fs/coda/coda_int.h +++ b/fs/coda/coda_int.h @@ -11,8 +11,7 @@ extern int coda_fake_statfs; void coda_destroy_inodecache(void); int coda_init_inodecache(void); -int coda_fsync(struct file *coda_file, struct dentry *coda_dentry, - int datasync); +int coda_fsync(struct file *coda_file, int datasync); void coda_sysctl_init(void); void coda_sysctl_clean(void); diff --git a/fs/coda/file.c b/fs/coda/file.c index 7196077b1688..ad3cd2abeeb4 100644 --- a/fs/coda/file.c +++ b/fs/coda/file.c @@ -202,10 +202,10 @@ int coda_release(struct inode *coda_inode, struct file *coda_file) return 0; } -int coda_fsync(struct file *coda_file, struct dentry *coda_dentry, int datasync) +int coda_fsync(struct file *coda_file, int datasync) { struct file *host_file; - struct inode *coda_inode = coda_dentry->d_inode; + struct inode *coda_inode = coda_file->f_path.dentry->d_inode; struct coda_file_info *cfi; int err = 0; diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 3bdddbcc785f..e8fcf4e2ed7d 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c @@ -274,7 +274,7 @@ static int ecryptfs_release(struct inode *inode, struct file *file) } static int -ecryptfs_fsync(struct file *file, struct dentry *dentry, int datasync) +ecryptfs_fsync(struct file *file, int datasync) { return vfs_fsync(ecryptfs_file_to_lower(file), datasync); } diff --git a/fs/exofs/file.c b/fs/exofs/file.c index 839b9dc1e70f..fef6899be397 100644 --- a/fs/exofs/file.c +++ b/fs/exofs/file.c @@ -40,12 +40,11 @@ static int exofs_release_file(struct inode *inode, struct file *filp) return 0; } -static int exofs_file_fsync(struct file *filp, struct dentry *dentry, - int datasync) +static int exofs_file_fsync(struct file *filp, int datasync) { int ret; struct address_space *mapping = filp->f_mapping; - struct inode *inode = dentry->d_inode; + struct inode *inode = mapping->host; struct super_block *sb; ret = filemap_write_and_wait(mapping); @@ -66,7 +65,7 @@ static int exofs_file_fsync(struct file *filp, struct dentry *dentry, static int exofs_flush(struct file *file, fl_owner_t id) { - exofs_file_fsync(file, file->f_path.dentry, 1); + exofs_file_fsync(file, 1); /* TODO: Flush the OSD target */ return 0; } diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index 0b038e47ad2f..8e917b686510 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h @@ -155,7 +155,7 @@ extern void ext2_write_super (struct super_block *); extern const struct file_operations ext2_dir_operations; /* file.c */ -extern int ext2_fsync(struct file *file, struct dentry *dentry, int datasync); +extern int ext2_fsync(struct file *file, int datasync); extern const struct inode_operations ext2_file_inode_operations; extern const struct file_operations ext2_file_operations; extern const struct file_operations ext2_xip_file_operations; diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 5d198d0697fb..48bcfc327014 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -40,13 +40,13 @@ static int ext2_release_file (struct inode * inode, struct file * filp) return 0; } -int ext2_fsync(struct file *file, struct dentry *dentry, int datasync) +int ext2_fsync(struct file *file, int datasync) { int ret; - struct super_block *sb = dentry->d_inode->i_sb; + struct super_block *sb = file->f_mapping->host->i_sb; struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; - ret = simple_fsync(file, dentry, datasync); + ret = simple_fsync(file, datasync); if (ret == -EIO || test_and_clear_bit(AS_EIO, &mapping->flags)) { /* We don't really know where the IO error happened... */ ext2_error(sb, __func__, diff --git a/fs/ext3/fsync.c b/fs/ext3/fsync.c index fcf7487734b6..d7e9f74dc3a6 100644 --- a/fs/ext3/fsync.c +++ b/fs/ext3/fsync.c @@ -43,9 +43,9 @@ * inode to disk. */ -int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync) +int ext3_sync_file(struct file *file, int datasync) { - struct inode *inode = dentry->d_inode; + struct inode *inode = file->f_mapping->host; struct ext3_inode_info *ei = EXT3_I(inode); journal_t *journal = EXT3_SB(inode->i_sb)->s_journal; int ret, needs_barrier = 0; diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 60bd31026e7c..19a4de57128a 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1519,7 +1519,7 @@ extern int ext4_htree_store_dirent(struct file *dir_file, __u32 hash, extern void ext4_htree_free_dir_info(struct dir_private_info *p); /* fsync.c */ -extern int ext4_sync_file(struct file *, struct dentry *, int); +extern int ext4_sync_file(struct file *, int); /* hash.c */ extern int ext4fs_dirhash(const char *name, int len, struct diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c index b6a74f991bf4..40f345201737 100644 --- a/fs/ext4/fsync.c +++ b/fs/ext4/fsync.c @@ -71,9 +71,9 @@ static void ext4_sync_parent(struct inode *inode) * i_mutex lock is held when entering and exiting this function */ -int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync) +int ext4_sync_file(struct file *file, int datasync) { - struct inode *inode = dentry->d_inode; + struct inode *inode = file->f_mapping->host; struct ext4_inode_info *ei = EXT4_I(inode); journal_t *journal = EXT4_SB(inode->i_sb)->s_journal; int ret; @@ -81,7 +81,7 @@ int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync) J_ASSERT(ext4_journal_current_handle() == NULL); - trace_ext4_sync_file(file, dentry, datasync); + trace_ext4_sync_file(file, datasync); if (inode->i_sb->s_flags & MS_RDONLY) return 0; @@ -91,7 +91,7 @@ int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync) return ret; if (!journal) { - ret = simple_fsync(file, dentry, datasync); + ret = simple_fsync(file, datasync); if (!ret && !list_empty(&inode->i_dentry)) ext4_sync_parent(inode); return ret; diff --git a/fs/fat/fat.h b/fs/fat/fat.h index 53dba57b49a1..a1c8c4b44fdb 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h @@ -309,8 +309,7 @@ extern int fat_setattr(struct dentry * dentry, struct iattr * attr); extern void fat_truncate(struct inode *inode); extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); -extern int fat_file_fsync(struct file *file, struct dentry *dentry, - int datasync); +extern int fat_file_fsync(struct file *file, int datasync); /* fat/inode.c */ extern void fat_attach(struct inode *inode, loff_t i_pos); diff --git a/fs/fat/file.c b/fs/fat/file.c index a14c2f6a489e..29a576944374 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -149,12 +149,12 @@ static int fat_file_release(struct inode *inode, struct file *filp) return 0; } -int fat_file_fsync(struct file *filp, struct dentry *dentry, int datasync) +int fat_file_fsync(struct file *filp, int datasync) { - struct inode *inode = dentry->d_inode; + struct inode *inode = filp->f_mapping->host; int res, err; - res = simple_fsync(filp, dentry, datasync); + res = simple_fsync(filp, datasync); err = sync_mapping_buffers(MSDOS_SB(inode->i_sb)->fat_inode->i_mapping); return res ? res : err; diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 4787ae6c5c1c..3cdc5f78a406 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -1156,10 +1156,9 @@ static int fuse_dir_release(struct inode *inode, struct file *file) return 0; } -static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync) +static int fuse_dir_fsync(struct file *file, int datasync) { - /* nfsd can call this with no file */ - return file ? fuse_fsync_common(file, de, datasync, 1) : 0; + return fuse_fsync_common(file, datasync, 1); } static bool update_mtime(unsigned ivalid) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index a9f5e137f1d3..b5fd6f9905e4 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -351,10 +351,9 @@ static void fuse_sync_writes(struct inode *inode) fuse_release_nowrite(inode); } -int fuse_fsync_common(struct file *file, struct dentry *de, int datasync, - int isdir) +int fuse_fsync_common(struct file *file, int datasync, int isdir) { - struct inode *inode = de->d_inode; + struct inode *inode = file->f_mapping->host; struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_file *ff = file->private_data; struct fuse_req *req; @@ -403,9 +402,9 @@ int fuse_fsync_common(struct file *file, struct dentry *de, int datasync, return err; } -static int fuse_fsync(struct file *file, struct dentry *de, int datasync) +static int fuse_fsync(struct file *file, int datasync) { - return fuse_fsync_common(file, de, datasync, 0); + return fuse_fsync_common(file, datasync, 0); } void fuse_read_fill(struct fuse_req *req, struct file *file, loff_t pos, diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 01cc462ff45d..2c0d14a86779 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -568,8 +568,7 @@ void fuse_release_common(struct file *file, int opcode); /** * Send FSYNC or FSYNCDIR request */ -int fuse_fsync_common(struct file *file, struct dentry *de, int datasync, - int isdir); +int fuse_fsync_common(struct file *file, int datasync, int isdir); /** * Notify poll wakeup diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index b20bfcc9fa2d..ed9a94f0ef15 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -554,9 +554,9 @@ static int gfs2_close(struct inode *inode, struct file *file) * Returns: errno */ -static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync) +static int gfs2_fsync(struct file *file, int datasync) { - struct inode *inode = dentry->d_inode; + struct inode *inode = file->f_mapping->host; int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC); int ret = 0; diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 3a029d8f4cf1..87ac1891a185 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -411,9 +411,9 @@ int hostfs_file_open(struct inode *ino, struct file *file) return 0; } -int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync) +int hostfs_fsync(struct file *file, int datasync) { - return fsync_file(HOSTFS_I(dentry->d_inode)->fd, datasync); + return fsync_file(HOSTFS_I(file->f_mapping->host)->fd, datasync); } static const struct file_operations hostfs_file_fops = { diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c index 3efabff00367..a9ae9bfa752f 100644 --- a/fs/hpfs/file.c +++ b/fs/hpfs/file.c @@ -19,9 +19,9 @@ static int hpfs_file_release(struct inode *inode, struct file *file) return 0; } -int hpfs_file_fsync(struct file *file, struct dentry *dentry, int datasync) +int hpfs_file_fsync(struct file *file, int datasync) { - /*return file_fsync(file, dentry);*/ + /*return file_fsync(file, datasync);*/ return 0; /* Don't fsync :-) */ } diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h index 97bf738cd5d6..75f9d4324851 100644 --- a/fs/hpfs/hpfs_fn.h +++ b/fs/hpfs/hpfs_fn.h @@ -268,7 +268,7 @@ void hpfs_set_ea(struct inode *, struct fnode *, const char *, /* file.c */ -int hpfs_file_fsync(struct file *, struct dentry *, int); +int hpfs_file_fsync(struct file *, int); extern const struct file_operations hpfs_file_ops; extern const struct inode_operations hpfs_file_iops; extern const struct address_space_operations hpfs_aops; diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c index 2e4dfa8593da..826c3f9d29ac 100644 --- a/fs/hppfs/hppfs.c +++ b/fs/hppfs/hppfs.c @@ -587,7 +587,7 @@ static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir) return err; } -static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync) +static int hppfs_fsync(struct file *file, int datasync) { return 0; } diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index e7291c161a19..813497024437 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c @@ -26,9 +26,9 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, struct page **pagep, void **fsdata); static int jffs2_readpage (struct file *filp, struct page *pg); -int jffs2_fsync(struct file *filp, struct dentry *dentry, int datasync) +int jffs2_fsync(struct file *filp, int datasync) { - struct inode *inode = dentry->d_inode; + struct inode *inode = filp->f_mapping->host; struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); /* Trigger GC to flush any pending writes for this inode */ diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h index 035a767f958b..4791aacf3084 100644 --- a/fs/jffs2/os-linux.h +++ b/fs/jffs2/os-linux.h @@ -158,7 +158,7 @@ extern const struct inode_operations jffs2_dir_inode_operations; extern const struct file_operations jffs2_file_operations; extern const struct inode_operations jffs2_file_inode_operations; extern const struct address_space_operations jffs2_file_address_operations; -int jffs2_fsync(struct file *, struct dentry *, int); +int jffs2_fsync(struct file *, int); int jffs2_do_readpage_unlock (struct inode *inode, struct page *pg); /* ioctl.c */ diff --git a/fs/jfs/file.c b/fs/jfs/file.c index 85d9ec659225..127263cc8657 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c @@ -27,9 +27,9 @@ #include "jfs_acl.h" #include "jfs_debug.h" -int jfs_fsync(struct file *file, struct dentry *dentry, int datasync) +int jfs_fsync(struct file *file, int datasync) { - struct inode *inode = dentry->d_inode; + struct inode *inode = file->f_mapping->host; int rc = 0; if (!(inode->i_state & I_DIRTY) || diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h index 9e6bda30a6e8..11042b1f44b5 100644 --- a/fs/jfs/jfs_inode.h +++ b/fs/jfs/jfs_inode.h @@ -21,7 +21,7 @@ struct fid; extern struct inode *ialloc(struct inode *, umode_t); -extern int jfs_fsync(struct file *, struct dentry *, int); +extern int jfs_fsync(struct file *, int); extern long jfs_ioctl(struct file *, unsigned int, unsigned long); extern long jfs_compat_ioctl(struct file *, unsigned int, unsigned long); extern struct inode *jfs_iget(struct super_block *, unsigned long); diff --git a/fs/libfs.c b/fs/libfs.c index 232bea425b09..e57ea58bda68 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -58,7 +58,7 @@ struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, struct na return NULL; } -int simple_sync_file(struct file * file, struct dentry *dentry, int datasync) +int simple_sync_file(struct file *file, int datasync) { return 0; } @@ -851,13 +851,13 @@ struct dentry *generic_fh_to_parent(struct super_block *sb, struct fid *fid, } EXPORT_SYMBOL_GPL(generic_fh_to_parent); -int simple_fsync(struct file *file, struct dentry *dentry, int datasync) +int simple_fsync(struct file *file, int datasync) { struct writeback_control wbc = { .sync_mode = WB_SYNC_ALL, .nr_to_write = 0, /* metadata-only; caller takes care of data */ }; - struct inode *inode = dentry->d_inode; + struct inode *inode = file->f_mapping->host; int err; int ret; diff --git a/fs/logfs/file.c b/fs/logfs/file.c index 0de524071870..abe1cafbd4c2 100644 --- a/fs/logfs/file.c +++ b/fs/logfs/file.c @@ -219,9 +219,9 @@ int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, } } -int logfs_fsync(struct file *file, struct dentry *dentry, int datasync) +int logfs_fsync(struct file *file, int datasync) { - struct super_block *sb = dentry->d_inode->i_sb; + struct super_block *sb = file->f_mapping->host->i_sb; logfs_write_anchor(sb); return 0; diff --git a/fs/logfs/logfs.h b/fs/logfs/logfs.h index 1a9db84f8d8f..c838c4d72111 100644 --- a/fs/logfs/logfs.h +++ b/fs/logfs/logfs.h @@ -506,7 +506,7 @@ extern const struct address_space_operations logfs_reg_aops; int logfs_readpage(struct file *file, struct page *page); int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); -int logfs_fsync(struct file *file, struct dentry *dentry, int datasync); +int logfs_fsync(struct file *file, int datasync); /* gc.c */ u32 get_best_cand(struct super_block *sb, struct candidate_list *list, u32 *ec); diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c index b93870892892..3639cc5cbdae 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c @@ -22,7 +22,7 @@ #include #include "ncplib_kernel.h" -static int ncp_fsync(struct file *file, struct dentry *dentry, int datasync) +static int ncp_fsync(struct file *file, int datasync) { return 0; } diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index db64854b7b09..782b431ef91c 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -53,7 +53,7 @@ static int nfs_link(struct dentry *, struct inode *, struct dentry *); static int nfs_mknod(struct inode *, struct dentry *, int, dev_t); static int nfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); -static int nfs_fsync_dir(struct file *, struct dentry *, int); +static int nfs_fsync_dir(struct file *, int); static loff_t nfs_llseek_dir(struct file *, loff_t, int); const struct file_operations nfs_dir_operations = { @@ -641,8 +641,10 @@ out: * All directory operations under NFS are synchronous, so fsync() * is a dummy operation. */ -static int nfs_fsync_dir(struct file *filp, struct dentry *dentry, int datasync) +static int nfs_fsync_dir(struct file *filp, int datasync) { + struct dentry *dentry = filp->f_path.dentry; + dfprintk(FILE, "NFS: fsync dir(%s/%s) datasync %d\n", dentry->d_parent->d_name.name, dentry->d_name.name, datasync); diff --git a/fs/nfs/file.c b/fs/nfs/file.c index cac96bcc91e4..36a5e74f51b4 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -53,7 +53,7 @@ static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe, static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov, unsigned long nr_segs, loff_t pos); static int nfs_file_flush(struct file *, fl_owner_t id); -static int nfs_file_fsync(struct file *, struct dentry *dentry, int datasync); +static int nfs_file_fsync(struct file *, int datasync); static int nfs_check_flags(int flags); static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); @@ -322,8 +322,9 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma) * whether any write errors occurred for this process. */ static int -nfs_file_fsync(struct file *file, struct dentry *dentry, int datasync) +nfs_file_fsync(struct file *file, int datasync) { + struct dentry *dentry = file->f_path.dentry; struct nfs_open_context *ctx = nfs_file_open_context(file); struct inode *inode = dentry->d_inode; diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c index 30292df443ce..c9a30d7ff6fc 100644 --- a/fs/nilfs2/file.c +++ b/fs/nilfs2/file.c @@ -27,7 +27,7 @@ #include "nilfs.h" #include "segment.h" -int nilfs_sync_file(struct file *file, struct dentry *dentry, int datasync) +int nilfs_sync_file(struct file *file, int datasync) { /* * Called from fsync() system call @@ -37,7 +37,7 @@ int nilfs_sync_file(struct file *file, struct dentry *dentry, int datasync) * This function should be implemented when the writeback function * will be implemented. */ - struct inode *inode = dentry->d_inode; + struct inode *inode = file->f_mapping->host; int err; if (!nilfs_inode_dirty(inode)) diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h index 8723e5bfd071..47d6d7928122 100644 --- a/fs/nilfs2/nilfs.h +++ b/fs/nilfs2/nilfs.h @@ -228,7 +228,7 @@ extern void nilfs_set_link(struct inode *, struct nilfs_dir_entry *, struct page *, struct inode *); /* file.c */ -extern int nilfs_sync_file(struct file *, struct dentry *, int); +extern int nilfs_sync_file(struct file *, int); /* ioctl.c */ long nilfs_ioctl(struct file *, unsigned int, unsigned long); diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c index fe44d3feee4a..0f48e7c5d9e1 100644 --- a/fs/ntfs/dir.c +++ b/fs/ntfs/dir.c @@ -1527,10 +1527,9 @@ static int ntfs_dir_open(struct inode *vi, struct file *filp) * this problem for now. We do write the $BITMAP attribute if it is present * which is the important one for a directory so things are not too bad. */ -static int ntfs_dir_fsync(struct file *filp, struct dentry *dentry, - int datasync) +static int ntfs_dir_fsync(struct file *filp, int datasync) { - struct inode *bmp_vi, *vi = dentry->d_inode; + struct inode *bmp_vi, *vi = filp->f_mapping->host; int err, ret; ntfs_attr na; diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index a1924a0d2ab0..113ebd9f25a4 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -2133,7 +2133,6 @@ static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, /** * ntfs_file_fsync - sync a file to disk * @filp: file to be synced - * @dentry: dentry describing the file to sync * @datasync: if non-zero only flush user data and not metadata * * Data integrity sync of a file to disk. Used for fsync, fdatasync, and msync @@ -2149,19 +2148,15 @@ static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, * Also, if @datasync is true, we do not wait on the inode to be written out * but we always wait on the page cache pages to be written out. * - * Note: In the past @filp could be NULL so we ignore it as we don't need it - * anyway. - * * Locking: Caller must hold i_mutex on the inode. * * TODO: We should probably also write all attribute/index inodes associated * with this inode but since we have no simple way of getting to them we ignore * this problem for now. */ -static int ntfs_file_fsync(struct file *filp, struct dentry *dentry, - int datasync) +static int ntfs_file_fsync(struct file *filp, int datasync) { - struct inode *vi = dentry->d_inode; + struct inode *vi = filp->f_mapping->host; int err, ret = 0; ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 97e54b9e654b..1c6220a8e072 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -175,13 +175,12 @@ static int ocfs2_dir_release(struct inode *inode, struct file *file) return 0; } -static int ocfs2_sync_file(struct file *file, - struct dentry *dentry, - int datasync) +static int ocfs2_sync_file(struct file *file, int datasync) { int err = 0; journal_t *journal; - struct inode *inode = dentry->d_inode; + struct dentry *dentry = file->f_path.dentry; + struct inode *inode = file->f_mapping->host; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); mlog_entry("(0x%p, 0x%p, %d, '%.*s')\n", file, dentry, datasync, diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index 4455fbe269a3..198dabf1b2bb 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c @@ -14,8 +14,7 @@ extern const struct reiserfs_key MIN_KEY; static int reiserfs_readdir(struct file *, void *, filldir_t); -static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, - int datasync); +static int reiserfs_dir_fsync(struct file *filp, int datasync); const struct file_operations reiserfs_dir_operations = { .llseek = generic_file_llseek, @@ -28,10 +27,9 @@ const struct file_operations reiserfs_dir_operations = { #endif }; -static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, - int datasync) +static int reiserfs_dir_fsync(struct file *filp, int datasync) { - struct inode *inode = dentry->d_inode; + struct inode *inode = filp->f_mapping->host; int err; reiserfs_write_lock(inode->i_sb); err = reiserfs_commit_for_inode(inode); diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 9977df9f3a54..b82cdd8a45dd 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -134,10 +134,9 @@ static void reiserfs_vfs_truncate_file(struct inode *inode) * be removed... */ -static int reiserfs_sync_file(struct file *filp, - struct dentry *dentry, int datasync) +static int reiserfs_sync_file(struct file *filp, int datasync) { - struct inode *inode = dentry->d_inode; + struct inode *inode = filp->f_mapping->host; int err; int barrier_done; diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c index 84ecf0e43f91..8e187a0f94bb 100644 --- a/fs/smbfs/file.c +++ b/fs/smbfs/file.c @@ -28,8 +28,9 @@ #include "proto.h" static int -smb_fsync(struct file *file, struct dentry * dentry, int datasync) +smb_fsync(struct file *file, int datasync) { + struct dentry *dentry = file->f_path.dentry; struct smb_sb_info *server = server_from_dentry(dentry); int result; diff --git a/fs/sync.c b/fs/sync.c index e8cbd415e50a..c9f83f480ec5 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -130,12 +130,10 @@ void emergency_sync(void) /* * Generic function to fsync a file. - * - * filp may be NULL if called via the msync of a vma. */ -int file_fsync(struct file *filp, struct dentry *dentry, int datasync) +int file_fsync(struct file *filp, int datasync) { - struct inode * inode = dentry->d_inode; + struct inode *inode = filp->f_mapping->host; struct super_block * sb; int ret, err; @@ -183,7 +181,7 @@ int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync) * livelocks in fsync_buffers_list(). */ mutex_lock(&mapping->host->i_mutex); - err = file->f_op->fsync(file, file->f_path.dentry, datasync); + err = file->f_op->fsync(file, datasync); if (!ret) ret = err; mutex_unlock(&mapping->host->i_mutex); diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 5692cf72b807..c726da68e6be 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c @@ -1304,9 +1304,9 @@ static void *ubifs_follow_link(struct dentry *dentry, struct nameidata *nd) return NULL; } -int ubifs_fsync(struct file *file, struct dentry *dentry, int datasync) +int ubifs_fsync(struct file *file, int datasync) { - struct inode *inode = dentry->d_inode; + struct inode *inode = file->f_mapping->host; struct ubifs_info *c = inode->i_sb->s_fs_info; int err; diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index bd2542dad014..b0904536cc1c 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -1678,7 +1678,7 @@ const struct ubifs_lprops *ubifs_fast_find_frdi_idx(struct ubifs_info *c); int ubifs_calc_dark(const struct ubifs_info *c, int spc); /* file.c */ -int ubifs_fsync(struct file *file, struct dentry *dentry, int datasync); +int ubifs_fsync(struct file *file, int datasync); int ubifs_setattr(struct dentry *dentry, struct iattr *attr); /* dir.c */ diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index d8fb1b5d6cb5..257a56b127cf 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -100,10 +100,10 @@ xfs_iozero( STATIC int xfs_file_fsync( struct file *file, - struct dentry *dentry, int datasync) { - struct xfs_inode *ip = XFS_I(dentry->d_inode); + struct inode *inode = file->f_mapping->host; + struct xfs_inode *ip = XFS_I(inode); struct xfs_trans *tp; int error = 0; int log_flushed = 0; @@ -140,8 +140,8 @@ xfs_file_fsync( * might gets cleared when the inode gets written out via the AIL * or xfs_iflush_cluster. */ - if (((dentry->d_inode->i_state & I_DIRTY_DATASYNC) || - ((dentry->d_inode->i_state & I_DIRTY_SYNC) && !datasync)) && + if (((inode->i_state & I_DIRTY_DATASYNC) || + ((inode->i_state & I_DIRTY_SYNC) && !datasync)) && ip->i_update_core) { /* * Kick off a transaction to log the inode core to get the @@ -868,7 +868,7 @@ write_retry: mutex_lock(&inode->i_mutex); xfs_ilock(ip, iolock); - error2 = -xfs_file_fsync(file, file->f_path.dentry, + error2 = -xfs_file_fsync(file, (file->f_flags & __O_SYNC) ? 0 : 1); if (!error) error = error2; diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index 16ed0284d780..05e5f5996216 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -224,7 +224,7 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, void block_sync_page(struct page *); sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *); int block_truncate_page(struct address_space *, loff_t, get_block_t *); -int file_fsync(struct file *, struct dentry *, int); +int file_fsync(struct file *, int); int nobh_write_begin(struct file *, struct address_space *, loff_t, unsigned, unsigned, struct page **, void **, get_block_t*); diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h index 5f494b465097..7fc62d4550b2 100644 --- a/include/linux/ext3_fs.h +++ b/include/linux/ext3_fs.h @@ -868,7 +868,7 @@ extern int ext3_htree_store_dirent(struct file *dir_file, __u32 hash, extern void ext3_htree_free_dir_info(struct dir_private_info *p); /* fsync.c */ -extern int ext3_sync_file (struct file *, struct dentry *, int); +extern int ext3_sync_file(struct file *, int); /* hash.c */ extern int ext3fs_dirhash(const char *name, int len, struct diff --git a/include/linux/fb.h b/include/linux/fb.h index f3793ebc241c..907ace3a64c8 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -4,8 +4,6 @@ #include #include -struct dentry; - /* Definitions of frame buffers */ #define FB_MAX 32 /* sufficient for now */ @@ -1017,8 +1015,7 @@ extern void fb_deferred_io_open(struct fb_info *info, struct inode *inode, struct file *file); extern void fb_deferred_io_cleanup(struct fb_info *info); -extern int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, - int datasync); +extern int fb_deferred_io_fsync(struct file *file, int datasync); static inline bool fb_be_math(struct fb_info *info) { diff --git a/include/linux/fs.h b/include/linux/fs.h index 3d9ed8302402..eb39e5eb77f5 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1498,7 +1498,7 @@ struct file_operations { int (*open) (struct inode *, struct file *); int (*flush) (struct file *, fl_owner_t id); int (*release) (struct inode *, struct file *); - int (*fsync) (struct file *, struct dentry *, int datasync); + int (*fsync) (struct file *, int datasync); int (*aio_fsync) (struct kiocb *, int datasync); int (*fasync) (int, struct file *, int); int (*lock) (struct file *, int, struct file_lock *); @@ -2213,7 +2213,7 @@ extern int generic_segment_checks(const struct iovec *iov, /* fs/block_dev.c */ extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos); -extern int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync); +extern int blkdev_fsync(struct file *filp, int datasync); /* fs/splice.c */ extern ssize_t generic_file_splice_read(struct file *, loff_t *, @@ -2348,7 +2348,7 @@ extern int simple_link(struct dentry *, struct inode *, struct dentry *); extern int simple_unlink(struct inode *, struct dentry *); extern int simple_rmdir(struct inode *, struct dentry *); extern int simple_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); -extern int simple_sync_file(struct file *, struct dentry *, int); +extern int simple_sync_file(struct file *, int); extern int simple_empty(struct dentry *); extern int simple_readpage(struct file *file, struct page *page); extern int simple_write_begin(struct file *file, struct address_space *mapping, @@ -2373,7 +2373,7 @@ extern ssize_t simple_read_from_buffer(void __user *to, size_t count, extern ssize_t simple_write_to_buffer(void *to, size_t available, loff_t *ppos, const void __user *from, size_t count); -extern int simple_fsync(struct file *, struct dentry *, int); +extern int simple_fsync(struct file *, int); #ifdef CONFIG_MIGRATION extern int buffer_migrate_page(struct address_space *, diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h index 5d60ad4ebf78..f5b1ba90e952 100644 --- a/include/trace/events/ext4.h +++ b/include/trace/events/ext4.h @@ -606,9 +606,9 @@ TRACE_EVENT(ext4_free_blocks, ); TRACE_EVENT(ext4_sync_file, - TP_PROTO(struct file *file, struct dentry *dentry, int datasync), + TP_PROTO(struct file *file, int datasync), - TP_ARGS(file, dentry, datasync), + TP_ARGS(file, datasync), TP_STRUCT__entry( __field( dev_t, dev ) @@ -618,6 +618,8 @@ TRACE_EVENT(ext4_sync_file, ), TP_fast_assign( + struct dentry *dentry = file->f_path.dentry; + __entry->dev = dentry->d_inode->i_sb->s_dev; __entry->ino = dentry->d_inode->i_ino; __entry->datasync = datasync; diff --git a/ipc/shm.c b/ipc/shm.c index 1a314c89f93c..52ed77eb9713 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -273,16 +273,13 @@ static int shm_release(struct inode *ino, struct file *file) return 0; } -static int shm_fsync(struct file *file, struct dentry *dentry, int datasync) +static int shm_fsync(struct file *file, int datasync) { - int (*fsync) (struct file *, struct dentry *, int datasync); struct shm_file_data *sfd = shm_file_data(file); - int ret = -EINVAL; - fsync = sfd->file->f_op->fsync; - if (fsync) - ret = fsync(sfd->file, sfd->file->f_path.dentry, datasync); - return ret; + if (!sfd->file->f_op->fsync) + return -EINVAL; + return sfd->file->f_op->fsync(sfd->file, datasync); } static unsigned long shm_get_unmapped_area(struct file *file, -- cgit v1.2.3 From b334f2b3b68c35fd86a0cbc90ecee40e63ba2f37 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Sun, 9 May 2010 14:49:52 +0200 Subject: drm/nouveau: allow cursor image and position to survive suspend - This isn't triggered yet on a normal kernel, because it still does a VT switch, but it seemed like a good idea to fix this now. Tested-by: Maxim Levitsky Signed-off-by: Maarten Maathuis Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_crtc.h | 2 ++ drivers/gpu/drm/nouveau/nouveau_drv.c | 29 +++++++++++++++++++++++++++++ drivers/gpu/drm/nouveau/nv04_cursor.c | 1 + drivers/gpu/drm/nouveau/nv50_cursor.c | 1 + 4 files changed, 33 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_crtc.h b/drivers/gpu/drm/nouveau/nouveau_crtc.h index 49fa7b2d257e..cb1ce2a09162 100644 --- a/drivers/gpu/drm/nouveau/nouveau_crtc.h +++ b/drivers/gpu/drm/nouveau/nouveau_crtc.h @@ -40,6 +40,8 @@ struct nouveau_crtc { int sharpness; int last_dpms; + int cursor_saved_x, cursor_saved_y; + struct { int cpp; bool blanked; diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index c6079e36669d..273770432298 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -175,6 +175,13 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) nouveau_bo_unpin(nouveau_fb->nvbo); } + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); + + nouveau_bo_unmap(nv_crtc->cursor.nvbo); + nouveau_bo_unpin(nv_crtc->cursor.nvbo); + } + NV_INFO(dev, "Evicting buffers...\n"); ttm_bo_evict_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); @@ -314,12 +321,34 @@ nouveau_pci_resume(struct pci_dev *pdev) nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM); } + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); + int ret; + + ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM); + if (!ret) + ret = nouveau_bo_map(nv_crtc->cursor.nvbo); + if (ret) + NV_ERROR(dev, "Could not pin/map cursor.\n"); + } + if (dev_priv->card_type < NV_50) { nv04_display_restore(dev); NVLockVgaCrtcs(dev, false); } else nv50_display_init(dev); + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); + + nv_crtc->cursor.set_offset(nv_crtc, + nv_crtc->cursor.nvbo->bo.offset - + dev_priv->vm_vram_base); + + nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x, + nv_crtc->cursor_saved_y); + } + /* Force CLUT to get re-loaded during modeset */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); diff --git a/drivers/gpu/drm/nouveau/nv04_cursor.c b/drivers/gpu/drm/nouveau/nv04_cursor.c index 89a91b9d8b25..aaf3de3bc816 100644 --- a/drivers/gpu/drm/nouveau/nv04_cursor.c +++ b/drivers/gpu/drm/nouveau/nv04_cursor.c @@ -20,6 +20,7 @@ nv04_cursor_hide(struct nouveau_crtc *nv_crtc, bool update) static void nv04_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y) { + nv_crtc->cursor_saved_x = x; nv_crtc->cursor_saved_y = y; NVWriteRAMDAC(nv_crtc->base.dev, nv_crtc->index, NV_PRAMDAC_CU_START_POS, XLATE(y, 0, NV_PRAMDAC_CU_START_POS_Y) | diff --git a/drivers/gpu/drm/nouveau/nv50_cursor.c b/drivers/gpu/drm/nouveau/nv50_cursor.c index 753e723adb3a..03ad7ab14f09 100644 --- a/drivers/gpu/drm/nouveau/nv50_cursor.c +++ b/drivers/gpu/drm/nouveau/nv50_cursor.c @@ -107,6 +107,7 @@ nv50_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y) { struct drm_device *dev = nv_crtc->base.dev; + nv_crtc->cursor_saved_x = x; nv_crtc->cursor_saved_y = y; nv_wr32(dev, NV50_PDISPLAY_CURSOR_USER_POS(nv_crtc->index), ((y & 0xFFFF) << 16) | (x & 0xFFFF)); /* Needed to make the cursor move. */ -- cgit v1.2.3 From 7fc74f17e6c9b4d86371c3a947afc32bd6bc9691 Mon Sep 17 00:00:00 2001 From: Marcin KoÅ›cielnicki Date: Sun, 23 May 2010 11:36:04 +0000 Subject: drm/nouveau: Add getparam for current PTIMER time. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will be useful for computing GPU-CPU latency, including GL_ARB_timer_query extension. Signed-off-by: Marcin KoÅ›cielnicki Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_state.c | 3 +++ include/drm/nouveau_drm.h | 1 + 2 files changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index e632339c323e..a2544ffd02cc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -913,6 +913,9 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, case NOUVEAU_GETPARAM_VM_VRAM_BASE: getparam->value = dev_priv->vm_vram_base; break; + case NOUVEAU_GETPARAM_PTIMER_TIME: + getparam->value = dev_priv->engine.timer.read(dev); + break; case NOUVEAU_GETPARAM_GRAPH_UNITS: /* NV40 and NV50 versions are quite different, but register * address is the same. User is supposed to know the card diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h index a6a9f4af5ebd..fe917dee723a 100644 --- a/include/drm/nouveau_drm.h +++ b/include/drm/nouveau_drm.h @@ -79,6 +79,7 @@ struct drm_nouveau_gpuobj_free { #define NOUVEAU_GETPARAM_CHIPSET_ID 11 #define NOUVEAU_GETPARAM_VM_VRAM_BASE 12 #define NOUVEAU_GETPARAM_GRAPH_UNITS 13 +#define NOUVEAU_GETPARAM_PTIMER_TIME 14 struct drm_nouveau_getparam { uint64_t param; uint64_t value; -- cgit v1.2.3 From d13102c6b4836289138431e3fbfc08e90c925ffd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 25 May 2010 13:47:16 +1000 Subject: drm/nouveau: fix POST detection for certain chipsets We totally fail at detecting un-POSTed chipsets prior to G80. This commit changes the pre-G80 POST detection to read the programmed horizontal total from CRTC 0, and assume the card isn't POSTed if it's 0. NVIDIA use some other heuristics more similar to what we do on G80, but I wasted quite a long time trying to figure out the exact specifics of what they do so we can try this for a bit instead. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bios.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index e7e69ccce5c9..61d932261356 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -6205,6 +6205,30 @@ nouveau_bios_i2c_devices_takedown(struct drm_device *dev) nouveau_i2c_fini(dev, entry); } +static bool +nouveau_bios_posted(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + bool was_locked; + unsigned htotal; + + if (dev_priv->chipset >= NV_50) { + if (NVReadVgaCrtc(dev, 0, 0x00) == 0 && + NVReadVgaCrtc(dev, 0, 0x1a) == 0) + return false; + return true; + } + + was_locked = NVLockVgaCrtcs(dev, false); + htotal = NVReadVgaCrtc(dev, 0, 0x06); + htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8; + htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4; + htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10; + htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11; + NVLockVgaCrtcs(dev, was_locked); + return (htotal != 0); +} + int nouveau_bios_init(struct drm_device *dev) { @@ -6239,9 +6263,7 @@ nouveau_bios_init(struct drm_device *dev) bios->execute = false; /* ... unless card isn't POSTed already */ - if (dev_priv->card_type >= NV_10 && - NVReadVgaCrtc(dev, 0, 0x00) == 0 && - NVReadVgaCrtc(dev, 0, 0x1a) == 0) { + if (!nouveau_bios_posted(dev)) { NV_INFO(dev, "Adaptor not initialised\n"); if (dev_priv->card_type < NV_50) { NV_ERROR(dev, "Unable to POST this chipset\n"); -- cgit v1.2.3 From f50c0b91e7718e7deda46475cfd0ea1413daed04 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 25 May 2010 13:48:07 +1000 Subject: drm/nv40: allow cold-booting of nv4x chipsets Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bios.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 61d932261356..620cbd9767cc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -6265,7 +6265,7 @@ nouveau_bios_init(struct drm_device *dev) /* ... unless card isn't POSTed already */ if (!nouveau_bios_posted(dev)) { NV_INFO(dev, "Adaptor not initialised\n"); - if (dev_priv->card_type < NV_50) { + if (dev_priv->card_type < NV_40) { NV_ERROR(dev, "Unable to POST this chipset\n"); return -ENODEV; } -- cgit v1.2.3 From 73db4bedc5dde97adf59b5b5a07c6cf0ee56e668 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 26 May 2010 10:41:45 +1000 Subject: drm/nouveau: don't execute INIT_GPIO unless we're really running the table This resulted in accidently switching off the eDP panel on certain laptops since the default state in the GPIO table was off. Fixes rh#582621 Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bios.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 620cbd9767cc..b3c7a87e47d9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -2807,7 +2807,10 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry); - nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default); + BIOSLOG(bios, "0x%04X: set gpio 0x%02x, state %d\n", + offset, gpio->tag, gpio->state_default); + if (bios->execute) + nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default); /* The NVIDIA binary driver doesn't appear to actually do * any of this, my VBIOS does however. -- cgit v1.2.3 From 23484874e6bf837704bf1fa61605d33a12b174e3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 28 May 2010 09:39:11 +1000 Subject: drm/nv50: fix duallink_possible calculation for DCB 4.0 cards Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bios.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index b3c7a87e47d9..9f30fb8eafe8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -5536,12 +5536,6 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, entry->bus = (conn >> 16) & 0xf; entry->location = (conn >> 20) & 0x3; entry->or = (conn >> 24) & 0xf; - /* - * Normal entries consist of a single bit, but dual link has the - * next most significant bit set too - */ - entry->duallink_possible = - ((1 << (ffs(entry->or) - 1)) * 3 == entry->or); switch (entry->type) { case OUTPUT_ANALOG: @@ -5625,6 +5619,16 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, break; } + if (dcb->version < 0x40) { + /* Normal entries consist of a single bit, but dual link has + * the next most significant bit set too + */ + entry->duallink_possible = + ((1 << (ffs(entry->or) - 1)) * 3 == entry->or); + } else { + entry->duallink_possible = (entry->sorconf.link == 3); + } + /* unsure what DCB version introduces this, 3.0? */ if (conf & 0x100000) entry->i2c_upper_default = true; -- cgit v1.2.3 From 2c58077541cc6859a9a9046d9c3a4d61bdbd4f18 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 28 May 2010 10:04:05 +1000 Subject: drm/nv50: obey dcb->duallink_possible It was once assumed that all G8x had dual-link TMDS everywhere, this isn't actually the case - especially considering passive DP->DVI converters and some HDMI connectors only support single-link. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_connector.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 7e663a79829f..bfa65629517b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -593,8 +593,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector, break; case OUTPUT_TMDS: if ((dev_priv->card_type >= NV_50 && !nouveau_duallink) || - (dev_priv->card_type < NV_50 && - !nv_encoder->dcb->duallink_possible)) + !nv_encoder->dcb->duallink_possible) max_clock = 165000; else max_clock = 330000; -- cgit v1.2.3 From 26099a74805eaf79f3058cc4097ebaa8cc55122c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 28 May 2010 10:13:16 +1000 Subject: drm/nouveau: fix dual-link displays when plugged into single-link outputs When selecting the native mode for a display we weren't taking into account whether or not it was actually supported on that particular output. This patch modifies our native mode selection to run all modes through mode_valid() first. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_connector.c | 31 ++++++++++++++++------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index bfa65629517b..256e82bd91dd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -431,24 +431,27 @@ nouveau_connector_set_property(struct drm_connector *connector, } static struct drm_display_mode * -nouveau_connector_native_mode(struct nouveau_connector *connector) +nouveau_connector_native_mode(struct drm_connector *connector) { - struct drm_device *dev = connector->base.dev; + struct drm_connector_helper_funcs *helper = connector->helper_private; + struct nouveau_connector *nv_connector = nouveau_connector(connector); + struct drm_device *dev = connector->dev; struct drm_display_mode *mode, *largest = NULL; int high_w = 0, high_h = 0, high_v = 0; - /* Use preferred mode if there is one.. */ - list_for_each_entry(mode, &connector->base.probed_modes, head) { + list_for_each_entry(mode, &nv_connector->base.probed_modes, head) { + if (helper->mode_valid(connector, mode) != MODE_OK) + continue; + + /* Use preferred mode if there is one.. */ if (mode->type & DRM_MODE_TYPE_PREFERRED) { NV_DEBUG_KMS(dev, "native mode from preferred\n"); return drm_mode_duplicate(dev, mode); } - } - /* Otherwise, take the resolution with the largest width, then height, - * then vertical refresh - */ - list_for_each_entry(mode, &connector->base.probed_modes, head) { + /* Otherwise, take the resolution with the largest width, then + * height, then vertical refresh + */ if (mode->hdisplay < high_w) continue; @@ -552,7 +555,7 @@ nouveau_connector_get_modes(struct drm_connector *connector) */ if (!nv_connector->native_mode) nv_connector->native_mode = - nouveau_connector_native_mode(nv_connector); + nouveau_connector_native_mode(connector); if (ret == 0 && nv_connector->native_mode) { struct drm_display_mode *mode; @@ -583,9 +586,9 @@ nouveau_connector_mode_valid(struct drm_connector *connector, switch (nv_encoder->dcb->type) { case OUTPUT_LVDS: - BUG_ON(!nv_connector->native_mode); - if (mode->hdisplay > nv_connector->native_mode->hdisplay || - mode->vdisplay > nv_connector->native_mode->vdisplay) + if (nv_connector->native_mode && + (mode->hdisplay > nv_connector->native_mode->hdisplay || + mode->vdisplay > nv_connector->native_mode->vdisplay)) return MODE_PANEL; min_clock = 0; @@ -727,7 +730,7 @@ nouveau_connector_create_lvds(struct drm_device *dev, if (ret == 0) goto out; nv_connector->detected_encoder = nv_encoder; - nv_connector->native_mode = nouveau_connector_native_mode(nv_connector); + nv_connector->native_mode = nouveau_connector_native_mode(connector); list_for_each_entry_safe(mode, temp, &connector->probed_modes, head) drm_mode_remove(connector, mode); -- cgit v1.2.3 From becd214277ed41dc6f745f5f8db39d84c6c7ffc8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 29 May 2010 03:06:14 +1000 Subject: drm/nv50: use alternate source of SOR_MODE_CTRL for DP hack Fixes module unload+reload on Dell M4500, where the "normal" registers get reset to 0. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_sor.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index b11eaf9c5c7c..812778db76ac 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c @@ -274,7 +274,6 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = { int nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) { - struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_encoder *nv_encoder = NULL; struct drm_encoder *encoder; bool dum; @@ -324,11 +323,7 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) int or = nv_encoder->or, link = !(entry->dpconf.sor.link & 1); uint32_t tmp; - if (dev_priv->chipset < 0x90 || - dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0) - tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(or)); - else - tmp = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(or)); + tmp = nv_rd32(dev, 0x61c700 + (or * 0x800)); switch ((tmp & 0x00000f00) >> 8) { case 8: -- cgit v1.2.3 From 37814fdc950281e9096a8b361a380edae237f486 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Thu, 27 May 2010 13:08:33 +0100 Subject: leds: Kconfig fixes Soekris net5501 is x86 only and cleanup some undeeded dependencies Signed-off-by: Richard Purdie --- drivers/leds/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index f98d17a7108b..81bf25e67ce1 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -21,7 +21,7 @@ comment "LED drivers" config LEDS_88PM860X tristate "LED Support for Marvell 88PM860x PMIC" - depends on LEDS_CLASS && MFD_88PM860X + depends on MFD_88PM860X help This option enables support for on-chip LED drivers found on Marvell Semiconductor 88PM8606 PMIC. @@ -69,8 +69,8 @@ config LEDS_NET48XX config LEDS_NET5501 tristate "LED Support for Soekris net5501 series Error LED" - depends on LEDS_CLASS && LEDS_TRIGGERS - depends on LEDS_GPIO_PLATFORM && GPIO_CS5535 + depends on LEDS_TRIGGERS + depends on X86 && LEDS_GPIO_PLATFORM && GPIO_CS5535 select LEDS_TRIGGER_DEFAULT_ON default n help -- cgit v1.2.3 From 5f8269da9c69dc3851f532af0d53693b521fdb91 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Thu, 27 May 2010 14:04:36 +0100 Subject: leds: Fix leds-gpio openfirmware compile issue Fix a compile issue when openfirmware is enabled from commit 2146325df2c2640059a9e064890c30c6e259b458. Signed-off-by: Richard Purdie --- drivers/leds/leds-gpio.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 26843dd6b859..cc22eeefa10b 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -250,7 +250,6 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev, led.gpio = of_get_gpio_flags(child, 0, &flags); led.active_low = flags & OF_GPIO_ACTIVE_LOW; led.name = of_get_property(child, "label", NULL) ? : child->name; - led.blinking = 0; led.default_trigger = of_get_property(child, "linux,default-trigger", NULL); state = of_get_property(child, "default-state", NULL); -- cgit v1.2.3 From 84e5b9f75b48fe4a1e4ee72698230701439d0805 Mon Sep 17 00:00:00 2001 From: Sarveshwar Bandi Date: Thu, 27 May 2010 16:28:15 -0700 Subject: be2net: Patch removes redundant while statement in loop. Signed-off-by: Sarveshwar Bandi Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index aa065c71ddd8..54b14272f333 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1861,7 +1861,7 @@ static int be_setup(struct be_adapter *adapter) goto if_destroy; } vf++; - } while (vf < num_vfs); + } } else if (!be_physfn(adapter)) { status = be_cmd_mac_addr_query(adapter, mac, MAC_ADDRESS_TYPE_NETWORK, false, adapter->if_handle); -- cgit v1.2.3 From 89dc0be68f4aaa06dba1b5d6ea9ecfe8fa9b7bf0 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 27 May 2010 16:29:05 -0700 Subject: drivers/net/hamradio: Eliminate a NULL pointer dereference At the point of the print, dev is NULL. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r exists@ expression E,E1; identifier f; statement S1,S2,S3; @@ if ((E == NULL && ...) || ...) { ... when != if (...) S1 else S2 when != E = E1 * E->f ... when any return ...; } else S3 // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/net/hamradio/yam.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c index 694132e04af6..4e7d1d0a2340 100644 --- a/drivers/net/hamradio/yam.c +++ b/drivers/net/hamradio/yam.c @@ -1151,8 +1151,7 @@ static int __init yam_init_driver(void) dev = alloc_netdev(sizeof(struct yam_port), name, yam_setup); if (!dev) { - printk(KERN_ERR "yam: cannot allocate net device %s\n", - dev->name); + pr_err("yam: cannot allocate net device\n"); err = -ENOMEM; goto error; } -- cgit v1.2.3 From 17d95640034c4e0f12e5f1c9d1097d8dba6484ea Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 27 May 2010 16:30:03 -0700 Subject: drivers/net: Eliminate a NULL pointer dereference At the point of the print, dev is NULL. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r exists@ expression E,E1; identifier f; statement S1,S2,S3; @@ if ((E == NULL && ...) || ...) { ... when != if (...) S1 else S2 when != E = E1 * E->f ... when any return ...; } else S3 // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/net/3c507.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index 82eaf65d2d85..ea9b7a098c9b 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c @@ -551,8 +551,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id) void __iomem *shmem; if (dev == NULL) { - pr_err("%s: net_interrupt(): irq %d for unknown device.\n", - dev->name, irq); + pr_err("net_interrupt(): irq %d for unknown device.\n", irq); return IRQ_NONE; } -- cgit v1.2.3 From b58ffb41fc09d1ffaca97e5ae801233575be2a7f Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 27 May 2010 16:31:41 -0700 Subject: cnic: Fix context memory init. on 5709. We need to zero context memory on 5709 in the function cnic_init_context(). Without this, iscsid restart on 5709 will not work because of stale data. TX context blocks should not be initialized by cnic_init_context() because of the special remapping on 5709. Update version to 2.1.2. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/cnic.c | 10 +++------- drivers/net/cnic_if.h | 4 ++-- 2 files changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index be90d3598bca..fe925663d39a 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -3367,13 +3367,9 @@ static int cnic_cm_shutdown(struct cnic_dev *dev) static void cnic_init_context(struct cnic_dev *dev, u32 cid) { - struct cnic_local *cp = dev->cnic_priv; u32 cid_addr; int i; - if (CHIP_NUM(cp) == CHIP_NUM_5709) - return; - cid_addr = GET_CID_ADDR(cid); for (i = 0; i < CTX_SIZE; i += 4) @@ -3530,14 +3526,11 @@ static void cnic_init_bnx2_tx_ring(struct cnic_dev *dev) sb_id = cp->status_blk_num; tx_cid = 20; - cnic_init_context(dev, tx_cid); - cnic_init_context(dev, tx_cid + 1); cp->tx_cons_ptr = &s_blk->status_tx_quick_consumer_index2; if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) { struct status_block_msix *sblk = cp->status_blk.bnx2; tx_cid = TX_TSS_CID + sb_id - 1; - cnic_init_context(dev, tx_cid); CNIC_WR(dev, BNX2_TSCH_TSS_CFG, (sb_id << 24) | (TX_TSS_CID << 7)); cp->tx_cons_ptr = &sblk->status_tx_quick_consumer_index; @@ -3556,6 +3549,9 @@ static void cnic_init_bnx2_tx_ring(struct cnic_dev *dev) offset2 = BNX2_L2CTX_TBDR_BHADDR_HI_XI; offset3 = BNX2_L2CTX_TBDR_BHADDR_LO_XI; } else { + cnic_init_context(dev, tx_cid); + cnic_init_context(dev, tx_cid + 1); + offset0 = BNX2_L2CTX_TYPE; offset1 = BNX2_L2CTX_CMD_TYPE; offset2 = BNX2_L2CTX_TBDR_BHADDR_HI; diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h index 110c62072e6f..0c55177db046 100644 --- a/drivers/net/cnic_if.h +++ b/drivers/net/cnic_if.h @@ -12,8 +12,8 @@ #ifndef CNIC_IF_H #define CNIC_IF_H -#define CNIC_MODULE_VERSION "2.1.1" -#define CNIC_MODULE_RELDATE "Feb 22, 2010" +#define CNIC_MODULE_VERSION "2.1.2" +#define CNIC_MODULE_RELDATE "May 26, 2010" #define CNIC_ULP_RDMA 0 #define CNIC_ULP_ISCSI 1 -- cgit v1.2.3 From 5d66ceee78f74ca52661634f6f822a99cf406974 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Fri, 28 May 2010 19:21:11 +0900 Subject: ARM: S5PV210: serial: Fix section mismatch warning Rename the structure to avoid the following warning: WARNING: drivers/serial/built-in.o(.data+0x534): Section mismatch in reference from the variable s5p_serial_drv to the function .devexit.text:s3c24xx_serial_remove() The variable s5p_serial_drv references the function __devexit s3c24xx_serial_remove() If the reference is valid then annotate the variable with __exit* (see linux/init.h) or name the variable: *driver, *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console, Signed-off-by: Marek Szyprowski Signed-off-by: Joonyoung Shim Signed-off-by: Ben Dooks --- drivers/serial/s5pv210.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/s5pv210.c b/drivers/serial/s5pv210.c index 8dc03837617b..4a789e5361a4 100644 --- a/drivers/serial/s5pv210.c +++ b/drivers/serial/s5pv210.c @@ -119,7 +119,7 @@ static int s5p_serial_probe(struct platform_device *pdev) return s3c24xx_serial_probe(pdev, s5p_uart_inf[pdev->id]); } -static struct platform_driver s5p_serial_drv = { +static struct platform_driver s5p_serial_driver = { .probe = s5p_serial_probe, .remove = __devexit_p(s3c24xx_serial_remove), .driver = { @@ -130,19 +130,19 @@ static struct platform_driver s5p_serial_drv = { static int __init s5pv210_serial_console_init(void) { - return s3c24xx_serial_initconsole(&s5p_serial_drv, s5p_uart_inf); + return s3c24xx_serial_initconsole(&s5p_serial_driver, s5p_uart_inf); } console_initcall(s5pv210_serial_console_init); static int __init s5p_serial_init(void) { - return s3c24xx_serial_init(&s5p_serial_drv, *s5p_uart_inf); + return s3c24xx_serial_init(&s5p_serial_driver, *s5p_uart_inf); } static void __exit s5p_serial_exit(void) { - platform_driver_unregister(&s5p_serial_drv); + platform_driver_unregister(&s5p_serial_driver); } module_init(s5p_serial_init); -- cgit v1.2.3 From 418bd0d4dfbff25ffe4365ddd3e7cba8c70ccba8 Mon Sep 17 00:00:00 2001 From: Bryan Wu Date: Fri, 28 May 2010 03:40:39 -0700 Subject: netdev/fec: fix ifconfig eth0 down hang issue BugLink: http://bugs.launchpad.net/bugs/559065 In fec open/close function, we need to use phy_connect and phy_disconnect operation before we start/stop phy. Otherwise it will cause system hang. Only call fec_enet_mii_probe() in open function, because the first open action will cause NULL pointer error. Signed-off-by: Bryan Wu Signed-off-by: David S. Miller --- drivers/net/fec.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 326465ffbb23..ddf7a86cd466 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -681,6 +681,8 @@ static int fec_enet_mii_probe(struct net_device *dev) struct phy_device *phy_dev = NULL; int phy_addr; + fep->phy_dev = NULL; + /* find the first phy */ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { if (fep->mii_bus->phy_map[phy_addr]) { @@ -711,6 +713,11 @@ static int fec_enet_mii_probe(struct net_device *dev) fep->link = 0; fep->full_duplex = 0; + printk(KERN_INFO "%s: Freescale FEC PHY driver [%s] " + "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name, + fep->phy_dev->drv->name, dev_name(&fep->phy_dev->dev), + fep->phy_dev->irq); + return 0; } @@ -756,13 +763,8 @@ static int fec_enet_mii_init(struct platform_device *pdev) if (mdiobus_register(fep->mii_bus)) goto err_out_free_mdio_irq; - if (fec_enet_mii_probe(dev) != 0) - goto err_out_unregister_bus; - return 0; -err_out_unregister_bus: - mdiobus_unregister(fep->mii_bus); err_out_free_mdio_irq: kfree(fep->mii_bus->irq); err_out_free_mdiobus: @@ -915,7 +917,12 @@ fec_enet_open(struct net_device *dev) if (ret) return ret; - /* schedule a link state check */ + /* Probe and connect to PHY when open the interface */ + ret = fec_enet_mii_probe(dev); + if (ret) { + fec_enet_free_buffers(dev); + return ret; + } phy_start(fep->phy_dev); netif_start_queue(dev); fep->opened = 1; @@ -929,10 +936,12 @@ fec_enet_close(struct net_device *dev) /* Don't know what to do yet. */ fep->opened = 0; - phy_stop(fep->phy_dev); netif_stop_queue(dev); fec_stop(dev); + if (fep->phy_dev) + phy_disconnect(fep->phy_dev); + fec_enet_free_buffers(dev); return 0; @@ -1316,11 +1325,6 @@ fec_probe(struct platform_device *pdev) if (ret) goto failed_register; - printk(KERN_INFO "%s: Freescale FEC PHY driver [%s] " - "(mii_bus:phy_addr=%s, irq=%d)\n", ndev->name, - fep->phy_dev->drv->name, dev_name(&fep->phy_dev->dev), - fep->phy_dev->irq); - return 0; failed_register: -- cgit v1.2.3 From 9be8ab2ea81f84c1726d79613c342141f5d19a3b Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Wed, 26 May 2010 11:00:04 -0700 Subject: ath9k: Fix ath_print in xmit for hardware reset. ath_print in xmit.c should say "Reseting hardware" instead of Resetting HAL!(since HAL is being fazed out). dmesg shows: [ 8660.899624] ath: Failed to stop TX DMA in 100 msec after killing last frame [ 8660.899676] ath: Unable to stop TxDMA. Reset HAL! Signed-off-by: Justin P. Mattock Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 3db19172b43b..09cb13c4854c 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1198,7 +1198,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) int r; ath_print(common, ATH_DBG_FATAL, - "Unable to stop TxDMA. Reset HAL!\n"); + "Failed to stop TX DMA. Resetting hardware!\n"); spin_lock_bh(&sc->sc_resetlock); r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false); -- cgit v1.2.3 From 35aed2e6be2feaa227fe5c7a0b7c286c4fe71592 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 27 May 2010 13:18:12 +0100 Subject: drm/i915: Only print an message if there was an error Only report an error if the GPU has actually detected one, otherwise we are just hung. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_irq.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b5dba4795f6f..2479be001e40 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -692,24 +692,13 @@ void i915_destroy_error_state(struct drm_device *dev) i915_error_state_free(dev, error); } -/** - * i915_handle_error - handle an error interrupt - * @dev: drm device - * - * Do some basic checking of regsiter state at error interrupt time and - * dump it to the syslog. Also call i915_capture_error_state() to make - * sure we get a record and make it available in debugfs. Fire a uevent - * so userspace knows something bad happened (should trigger collection - * of a ring dump etc.). - */ -static void i915_handle_error(struct drm_device *dev, bool wedged) +static void i915_report_and_clear_eir(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; u32 eir = I915_READ(EIR); - u32 pipea_stats = I915_READ(PIPEASTAT); - u32 pipeb_stats = I915_READ(PIPEBSTAT); - i915_capture_error_state(dev); + if (!eir) + return; printk(KERN_ERR "render error detected, EIR: 0x%08x\n", eir); @@ -755,6 +744,9 @@ static void i915_handle_error(struct drm_device *dev, bool wedged) } if (eir & I915_ERROR_MEMORY_REFRESH) { + u32 pipea_stats = I915_READ(PIPEASTAT); + u32 pipeb_stats = I915_READ(PIPEBSTAT); + printk(KERN_ERR "memory refresh error\n"); printk(KERN_ERR "PIPEASTAT: 0x%08x\n", pipea_stats); @@ -811,6 +803,24 @@ static void i915_handle_error(struct drm_device *dev, bool wedged) I915_WRITE(EMR, I915_READ(EMR) | eir); I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); } +} + +/** + * i915_handle_error - handle an error interrupt + * @dev: drm device + * + * Do some basic checking of regsiter state at error interrupt time and + * dump it to the syslog. Also call i915_capture_error_state() to make + * sure we get a record and make it available in debugfs. Fire a uevent + * so userspace knows something bad happened (should trigger collection + * of a ring dump etc.). + */ +static void i915_handle_error(struct drm_device *dev, bool wedged) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + i915_capture_error_state(dev); + i915_report_and_clear_eir(dev); if (wedged) { atomic_set(&dev_priv->mm.wedged, 1); -- cgit v1.2.3 From 7c9fd60f9764373414c0a64f500a78635b0a0a7b Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Wed, 26 May 2010 19:06:53 -0700 Subject: ath9k: Fix bug in the way "bf_tx_aborted" of struct ath_buf is used This bug was introduced by the following commit Author: Vasanthakumar Thiagarajan Date: Thu Apr 15 17:38:46 2010 -0400 ath9k: Remove ATH9K_TX_SW_ABORTED and introduce a bool for this purpose Wrong buffer is checked for bf_tx_aborted field in ath_tx_num_badfrms(), this may result in a rate scaling with wrong feedback (number of unacked frames in this case). It is the last one in the chain of buffers for an aggregate frame that should be checked. Also it misses the initialization of this field in the buffer, this may lead to a situation where we stop the sw retransmission of failed subframes associated to this buffer. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 09cb13c4854c..859aa4ab0769 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1728,6 +1728,8 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, } else bf->bf_isnullfunc = false; + bf->bf_tx_aborted = false; + return 0; } @@ -1989,7 +1991,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, int nbad = 0; int isaggr = 0; - if (bf->bf_tx_aborted) + if (bf->bf_lastbf->bf_tx_aborted) return 0; isaggr = bf_isaggr(bf); -- cgit v1.2.3 From 468f0b44ce4b002ca7d9260f802a341854752c02 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 27 May 2010 13:18:13 +0100 Subject: drm/i915: Hold the spinlock whilst resetting unpin_work along error path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Delay taking the mutex until we need to and ensure that we hold the spinlock when resetting unpin_work on the error path. Also defer the debugging print messages until after we have released the spinlock. Signed-off-by: Chris Wilson Cc: Jesse Barnes Cc: Kristian Høgsberg Reviewed-by: Jesse Barnes Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_display.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cfac4dd1d483..1845a068cca5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4667,8 +4667,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, if (work == NULL) return -ENOMEM; - mutex_lock(&dev->struct_mutex); - work->event = event; work->dev = crtc->dev; intel_fb = to_intel_framebuffer(crtc->fb); @@ -4678,10 +4676,10 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, /* We borrow the event spin lock for protecting unpin_work */ spin_lock_irqsave(&dev->event_lock, flags); if (intel_crtc->unpin_work) { - DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); spin_unlock_irqrestore(&dev->event_lock, flags); kfree(work); - mutex_unlock(&dev->struct_mutex); + + DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); return -EBUSY; } intel_crtc->unpin_work = work; @@ -4690,13 +4688,19 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, intel_fb = to_intel_framebuffer(fb); obj = intel_fb->obj; + mutex_lock(&dev->struct_mutex); ret = intel_pin_and_fence_fb_obj(dev, obj); if (ret != 0) { - DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n", - to_intel_bo(obj)); - kfree(work); - intel_crtc->unpin_work = NULL; mutex_unlock(&dev->struct_mutex); + + spin_lock_irqsave(&dev->event_lock, flags); + intel_crtc->unpin_work = NULL; + spin_unlock_irqrestore(&dev->event_lock, flags); + + kfree(work); + + DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n", + to_intel_bo(obj)); return ret; } -- cgit v1.2.3 From c6a6368b32aa4fd145e840c8d8dac6923fae2688 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Thu, 27 May 2010 14:41:20 -0400 Subject: libertas: fix uninitialized variable warning Fixes: drivers/net/wireless/libertas/rx.c: In function process_rxed_802_11_packet: drivers/net/wireless/libertas/rx.c:354: error: radiotap_hdr.flags may be used uninitialized in this function Signed-off-by: Prarit Bhargava Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/rx.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index a115bfa9513a..7a377f5b7662 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c @@ -329,9 +329,8 @@ static int process_rxed_802_11_packet(struct lbs_private *priv, /* create the exported radio header */ /* radiotap header */ - radiotap_hdr.hdr.it_version = 0; - /* XXX must check this value for pad */ - radiotap_hdr.hdr.it_pad = 0; + memset(&radiotap_hdr, 0, sizeof(radiotap_hdr)); + /* XXX must check radiotap_hdr.hdr.it_pad for pad */ radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr)); radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT); radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate); -- cgit v1.2.3 From b118c1e363befe3d74469f4a014ce6353097f08a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 27 May 2010 13:18:14 +0100 Subject: drm/i915: Avoid nesting of domain changes when setting display plane Nesting domain changes will cause confusion when trying to interpret the tracepoints describing the sequence of changes for the object, as well as obscuring the order of operations for the reader of the code. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_gem.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index bf703551343a..1c65f0b591fc 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2914,18 +2914,16 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj) return ret; } + i915_gem_object_flush_cpu_write_domain(obj); + old_write_domain = obj->write_domain; old_read_domains = obj->read_domains; - obj->read_domains &= I915_GEM_DOMAIN_GTT; - - i915_gem_object_flush_cpu_write_domain(obj); - /* It should now be out of any other write domains, and we can update * the domain values for our changes. */ BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0); - obj->read_domains |= I915_GEM_DOMAIN_GTT; + obj->read_domains = I915_GEM_DOMAIN_GTT; obj->write_domain = I915_GEM_DOMAIN_GTT; obj_priv->dirty = 1; -- cgit v1.2.3 From 808b24d6ed8b155aac17007788390ebfde263f30 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 27 May 2010 13:18:15 +0100 Subject: drm/i915: Propagate error from unbinding an unfenceable object. Signed-off-by: Chris Wilson Cc: Jesse Barnes Reviewed-by: Jesse Barnes Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_gem.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1c65f0b591fc..6425c2a4b11f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3307,9 +3307,13 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, obj_priv->tiling_mode != I915_TILING_NONE; /* Check fence reg constraints and rebind if necessary */ - if (need_fence && !i915_gem_object_fence_offset_ok(obj, - obj_priv->tiling_mode)) - i915_gem_object_unbind(obj); + if (need_fence && + !i915_gem_object_fence_offset_ok(obj, + obj_priv->tiling_mode)) { + ret = i915_gem_object_unbind(obj); + if (ret) + return ret; + } /* Choose the GTT offset for our buffer and put it there. */ ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment); -- cgit v1.2.3 From a939406fda8ddc7de69ee9186356d09dc6daaa2c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 27 May 2010 13:18:16 +0100 Subject: drm/i915: Only print "nothing to do" debug message as required. If the FBC is already disabled, then we do not even attempt to disable FBC and so there is no point emitting a debug statement at that point, having already emitted one saying why we are disabling FBC. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_display.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1845a068cca5..e504fdb4ae31 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1248,10 +1248,11 @@ static void intel_update_fbc(struct drm_crtc *crtc, return; out_disable: - DRM_DEBUG_KMS("unsupported config, disabling FBC\n"); /* Multiple disables should be harmless */ - if (intel_fbc_enabled(dev)) + if (intel_fbc_enabled(dev)) { + DRM_DEBUG_KMS("unsupported config, disabling FBC\n"); intel_disable_fbc(dev); + } } static int -- cgit v1.2.3 From a7faf32d00529b9c501e37a31d4bf8acef4f8f59 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 27 May 2010 13:18:17 +0100 Subject: drm/i915: Include pitch in set_base debug statement. Add the pitch that we about to write into the control register along with the base, offset and coordinates that go into the other control registers. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e504fdb4ae31..88a1ab7c05ce 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1396,7 +1396,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, Start = obj_priv->gtt_offset; Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); - DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y); + DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", + Start, Offset, x, y, crtc->fb->pitch); I915_WRITE(dspstride, crtc->fb->pitch); if (IS_I965G(dev)) { I915_WRITE(dspbase, Offset); -- cgit v1.2.3 From ac0c6b5ad3b3b513e1057806d4b7627fcc0ecc27 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 27 May 2010 13:18:18 +0100 Subject: drm/i915: Rebind bo if currently bound with incorrect alignment. Whilst pinning the buffer, check that that its current alignment matches the requested alignment. If it does not, rebind. This should clear up any final render errors whilst resuming, for reference: Bug 27070 - [i915] Page table errors with empty ringbuffer https://bugs.freedesktop.org/show_bug.cgi?id=27070 Bug 15502 - render error detected, EIR: 0x00000010 https://bugzilla.kernel.org/show_bug.cgi?id=15502 Bug 13844 - i915 error: "render error detected" https://bugzilla.kernel.org/show_bug.cgi?id=13844 Signed-off-by: Chris Wilson Cc: stable@kernel.org Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_gem.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6425c2a4b11f..a5ca9599b232 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4164,6 +4164,17 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) BUG_ON(obj_priv->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT); i915_verify_inactive(dev, __FILE__, __LINE__); + + if (obj_priv->gtt_space != NULL) { + if (alignment == 0) + alignment = i915_gem_get_gtt_alignment(obj); + if (obj_priv->gtt_offset & (alignment - 1)) { + ret = i915_gem_object_unbind(obj); + if (ret) + return ret; + } + } + if (obj_priv->gtt_space == NULL) { ret = i915_gem_object_bind_to_gtt(obj, alignment); if (ret) -- cgit v1.2.3 From 3d1cc47037f36004b10681d3436ef0942ebb279b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 27 May 2010 13:18:19 +0100 Subject: drm/i915: Remove spurious warning "Failure to install fence" This particular warning is harmless as we emit during the normal pinning process where the batch buffer requires more fences than is available without eviction. Only if we fail to evict enough fences does this become a problem, so include the requested number of fences in the ultimate *error* message. v2: Remember to compile test even trial patches to remove warnings. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_gem.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index a5ca9599b232..b87945db1021 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3327,9 +3327,6 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, if (need_fence) { ret = i915_gem_object_get_fence_reg(obj); if (ret != 0) { - if (ret != -EBUSY && ret != -ERESTARTSYS) - DRM_ERROR("Failure to install fence: %d\n", - ret); i915_gem_object_unpin(obj); return ret; } @@ -3815,11 +3812,19 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, if (ret != -ENOSPC || pin_tries >= 1) { if (ret != -ERESTARTSYS) { unsigned long long total_size = 0; - for (i = 0; i < args->buffer_count; i++) + int num_fences = 0; + for (i = 0; i < args->buffer_count; i++) { + obj_priv = object_list[i]->driver_private; + total_size += object_list[i]->size; - DRM_ERROR("Failed to pin buffer %d of %d, total %llu bytes: %d\n", + num_fences += + exec_list[i].flags & EXEC_OBJECT_NEEDS_FENCE && + obj_priv->tiling_mode != I915_TILING_NONE; + } + DRM_ERROR("Failed to pin buffer %d of %d, total %llu bytes, %d fences: %d\n", pinned+1, args->buffer_count, - total_size, ret); + total_size, num_fences, + ret); DRM_ERROR("%d objects [%d pinned], " "%d object bytes [%d pinned], " "%d/%d gtt bytes\n", -- cgit v1.2.3 From 85cd4612fdab4e837d7eea048a697c75d0477d3b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 27 May 2010 13:18:20 +0100 Subject: drm/i915: Check error code whilst moving buffer to GTT domain. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_fb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 6f53cf7fbc50..f8c76e64bb77 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -105,7 +105,11 @@ static int intelfb_create(struct intel_fbdev *ifbdev, } /* Flush everything out, we'll be doing GTT only from now on */ - i915_gem_object_set_to_gtt_domain(fbo, 1); + ret = i915_gem_object_set_to_gtt_domain(fbo, 1); + if (ret) { + DRM_ERROR("failed to bind fb: %d.\n", ret); + goto out_unpin; + } info = framebuffer_alloc(0, device); if (!info) { -- cgit v1.2.3 From 654fc6073f68efa3b6c466825749e73e7fbb92cd Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 27 May 2010 13:18:21 +0100 Subject: drm/i915: Reject bind_to_gtt() early if object > aperture If the object is bigger than the entire aperture, reject it early before evicting everything in a vain attempt to find space. v2: Use E2BIG as suggested by Owain G. Ainsworth. Signed-off-by: Chris Wilson Cc: stable@kernel.org Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_gem.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b87945db1021..f84c8e982dcb 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2648,6 +2648,14 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) return -EINVAL; } + /* If the object is bigger than the entire aperture, reject it early + * before evicting everything in a vain attempt to find space. + */ + if (obj->size > dev->gtt_total) { + DRM_ERROR("Attempting to bind an object larger than the aperture\n"); + return -E2BIG; + } + search_free: free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, obj->size, alignment, 0); -- cgit v1.2.3 From da1fdb02d9200ff28b6f3a380d21930335fe5429 Mon Sep 17 00:00:00 2001 From: Christoph Fritz Date: Fri, 28 May 2010 10:45:59 +0200 Subject: ssb: fix NULL ptr deref when pcihost_wrapper is used Ethernet driver b44 does register ssb by it's pcihost_wrapper and doesn't set ssb_chipcommon. A check on this value introduced with commit d53cdbb94a52a920d5420ed64d986c3523a56743 and ea2db495f92ad2cf3301623e60cb95b4062bc484 triggers: BUG: unable to handle kernel NULL pointer dereference at 00000010 IP: [] ssb_is_sprom_available+0x16/0x30 Signed-off-by: Christoph Fritz Signed-off-by: John W. Linville --- drivers/ssb/pci.c | 9 ++++++--- drivers/ssb/sprom.c | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 989e2752cc36..6dcda86be6eb 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -625,9 +625,12 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, ssb_printk(KERN_ERR PFX "No SPROM available!\n"); return -ENODEV; } - - bus->sprom_offset = (bus->chipco.dev->id.revision < 31) ? - SSB_SPROM_BASE1 : SSB_SPROM_BASE31; + if (bus->chipco.dev) { /* can be unavailible! */ + bus->sprom_offset = (bus->chipco.dev->id.revision < 31) ? + SSB_SPROM_BASE1 : SSB_SPROM_BASE31; + } else { + bus->sprom_offset = SSB_SPROM_BASE1; + } buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); if (!buf) diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c index 007bc3a03486..4f7cc8d13277 100644 --- a/drivers/ssb/sprom.c +++ b/drivers/ssb/sprom.c @@ -185,6 +185,7 @@ bool ssb_is_sprom_available(struct ssb_bus *bus) /* this routine differs from specs as we do not access SPROM directly on PCMCIA */ if (bus->bustype == SSB_BUSTYPE_PCI && + bus->chipco.dev && /* can be unavailible! */ bus->chipco.dev->id.revision >= 31) return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM; -- cgit v1.2.3 From 02cf4f9808382af7265cafc33dc86ec5875526aa Mon Sep 17 00:00:00 2001 From: Len Brown Date: Mon, 24 May 2010 14:27:44 -0400 Subject: ACPI: acpi_idle: touch TS_POLLING only in the non-MWAIT case commit d306ebc28649b89877a22158fe0076f06cc46f60 (ACPI: Be in TS_POLLING state during mwait based C-state entry) fixed an important power & performance issue where ACPI c2 and c3 C-states were clearing TS_POLLING even when using MWAIT (ACPI_STATE_FFH). That bug had been causing us to receive redundant scheduling interrups when we had already been woken up by MONITOR/MWAIT. Following up on that... In the MWAIT case, we don't have to subsequently check need_resched(), as that c heck was there for the TS_POLLING-clearing case. Note that not only does the cpuidle calling function already check need_resched() before calling us, the low-level entry into monitor/mwait calls it twice -- guaranteeing that a write to the trigger address can not go un-noticed. Also, in this case, we don't have to set TS_POLLING when we wake, because we never cleared it. Signed-off-by: Len Brown Acked-by: Venkatesh Pallipadi --- drivers/acpi/processor_idle.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 5939e7f7d8e9..a4166e2abb92 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -881,6 +881,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, return(acpi_idle_enter_c1(dev, state)); local_irq_disable(); + if (cx->entry_method != ACPI_CSTATE_FFH) { current_thread_info()->status &= ~TS_POLLING; /* @@ -888,12 +889,12 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, * NEED_RESCHED: */ smp_mb(); - } - if (unlikely(need_resched())) { - current_thread_info()->status |= TS_POLLING; - local_irq_enable(); - return 0; + if (unlikely(need_resched())) { + current_thread_info()->status |= TS_POLLING; + local_irq_enable(); + return 0; + } } /* @@ -918,7 +919,8 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); local_irq_enable(); - current_thread_info()->status |= TS_POLLING; + if (cx->entry_method != ACPI_CSTATE_FFH) + current_thread_info()->status |= TS_POLLING; cx->usage++; @@ -968,6 +970,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, } local_irq_disable(); + if (cx->entry_method != ACPI_CSTATE_FFH) { current_thread_info()->status &= ~TS_POLLING; /* @@ -975,12 +978,12 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, * NEED_RESCHED: */ smp_mb(); - } - if (unlikely(need_resched())) { - current_thread_info()->status |= TS_POLLING; - local_irq_enable(); - return 0; + if (unlikely(need_resched())) { + current_thread_info()->status |= TS_POLLING; + local_irq_enable(); + return 0; + } } acpi_unlazy_tlb(smp_processor_id()); @@ -1032,7 +1035,8 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); local_irq_enable(); - current_thread_info()->status |= TS_POLLING; + if (cx->entry_method != ACPI_CSTATE_FFH) + current_thread_info()->status |= TS_POLLING; cx->usage++; -- cgit v1.2.3 From 68f95ba9e260516411411524c45263b5d53f393c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 27 May 2010 13:18:22 +0100 Subject: drm/i915: Cleanup after failed initialization of ringbuffers The callers expect us to cleanup any partially initialised structures before reporting the error. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_gem.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f84c8e982dcb..42866c01540d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4632,23 +4632,40 @@ i915_gem_init_ringbuffer(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; int ret; + dev_priv->render_ring = render_ring; + if (!I915_NEED_GFX_HWS(dev)) { dev_priv->render_ring.status_page.page_addr = dev_priv->status_page_dmah->vaddr; memset(dev_priv->render_ring.status_page.page_addr, 0, PAGE_SIZE); } + if (HAS_PIPE_CONTROL(dev)) { ret = i915_gem_init_pipe_control(dev); if (ret) return ret; } + ret = intel_init_ring_buffer(dev, &dev_priv->render_ring); - if (!ret && HAS_BSD(dev)) { + if (ret) + goto cleanup_pipe_control; + + if (HAS_BSD(dev)) { dev_priv->bsd_ring = bsd_ring; ret = intel_init_ring_buffer(dev, &dev_priv->bsd_ring); + if (ret) + goto cleanup_render_ring; } + + return 0; + +cleanup_render_ring: + intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); +cleanup_pipe_control: + if (HAS_PIPE_CONTROL(dev)) + i915_gem_cleanup_pipe_control(dev); return ret; } -- cgit v1.2.3 From 9b8c4a0b215e603497daebe8ecbc9b1f0f035808 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 27 May 2010 14:21:01 +0100 Subject: drm/i915: Avoid moving from CPU domain during pwrite We can avoid an early clflush when pwriting if we use the current CPU write domain rather than moving the object to the GTT domain for the purposes of the pwrite. This has the advantage of not flushing the presumably hot data that we want to upload into the bo, and of ascribing the clflush to the execution when profiling. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_gem.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 42866c01540d..4590c78f4283 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -971,7 +971,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, if (obj_priv->phys_obj) ret = i915_gem_phys_pwrite(dev, obj, args, file_priv); else if (obj_priv->tiling_mode == I915_TILING_NONE && - dev->gtt_total != 0) { + dev->gtt_total != 0 && + obj->write_domain != I915_GEM_DOMAIN_CPU) { ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file_priv); if (ret == -EFAULT) { ret = i915_gem_gtt_pwrite_slow(dev, obj, args, -- cgit v1.2.3 From 99a03df57c82ec20848d2634f652c07ac3504b98 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 27 May 2010 14:15:34 +0100 Subject: drm/i915: Use non-atomic kmap for slow copy paths As we do not have a requirement to be atomic and avoid sleeping whilst performing the slow copy for shmem based pread and pwrite, we can use kmap instead, thus simplifying the code. Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_gem.c | 82 +++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4590c78f4283..b8e351274493 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -167,7 +167,7 @@ static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj) obj_priv->tiling_mode != I915_TILING_NONE; } -static inline int +static inline void slow_shmem_copy(struct page *dst_page, int dst_offset, struct page *src_page, @@ -176,25 +176,16 @@ slow_shmem_copy(struct page *dst_page, { char *dst_vaddr, *src_vaddr; - dst_vaddr = kmap_atomic(dst_page, KM_USER0); - if (dst_vaddr == NULL) - return -ENOMEM; - - src_vaddr = kmap_atomic(src_page, KM_USER1); - if (src_vaddr == NULL) { - kunmap_atomic(dst_vaddr, KM_USER0); - return -ENOMEM; - } + dst_vaddr = kmap(dst_page); + src_vaddr = kmap(src_page); memcpy(dst_vaddr + dst_offset, src_vaddr + src_offset, length); - kunmap_atomic(src_vaddr, KM_USER1); - kunmap_atomic(dst_vaddr, KM_USER0); - - return 0; + kunmap(src_page); + kunmap(dst_page); } -static inline int +static inline void slow_shmem_bit17_copy(struct page *gpu_page, int gpu_offset, struct page *cpu_page, @@ -214,15 +205,8 @@ slow_shmem_bit17_copy(struct page *gpu_page, cpu_page, cpu_offset, length); } - gpu_vaddr = kmap_atomic(gpu_page, KM_USER0); - if (gpu_vaddr == NULL) - return -ENOMEM; - - cpu_vaddr = kmap_atomic(cpu_page, KM_USER1); - if (cpu_vaddr == NULL) { - kunmap_atomic(gpu_vaddr, KM_USER0); - return -ENOMEM; - } + gpu_vaddr = kmap(gpu_page); + cpu_vaddr = kmap(cpu_page); /* Copy the data, XORing A6 with A17 (1). The user already knows he's * XORing with the other bits (A9 for Y, A9 and A10 for X) @@ -246,10 +230,8 @@ slow_shmem_bit17_copy(struct page *gpu_page, length -= this_length; } - kunmap_atomic(cpu_vaddr, KM_USER1); - kunmap_atomic(gpu_vaddr, KM_USER0); - - return 0; + kunmap(cpu_page); + kunmap(gpu_page); } /** @@ -425,21 +407,19 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, page_length = PAGE_SIZE - data_page_offset; if (do_bit17_swizzling) { - ret = slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index], - shmem_page_offset, - user_pages[data_page_index], - data_page_offset, - page_length, - 1); - } else { - ret = slow_shmem_copy(user_pages[data_page_index], - data_page_offset, - obj_priv->pages[shmem_page_index], + slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index], shmem_page_offset, - page_length); + user_pages[data_page_index], + data_page_offset, + page_length, + 1); + } else { + slow_shmem_copy(user_pages[data_page_index], + data_page_offset, + obj_priv->pages[shmem_page_index], + shmem_page_offset, + page_length); } - if (ret) - goto fail_put_pages; remain -= page_length; data_ptr += page_length; @@ -900,21 +880,19 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, page_length = PAGE_SIZE - data_page_offset; if (do_bit17_swizzling) { - ret = slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index], - shmem_page_offset, - user_pages[data_page_index], - data_page_offset, - page_length, - 0); - } else { - ret = slow_shmem_copy(obj_priv->pages[shmem_page_index], + slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index], shmem_page_offset, user_pages[data_page_index], data_page_offset, - page_length); + page_length, + 0); + } else { + slow_shmem_copy(obj_priv->pages[shmem_page_index], + shmem_page_offset, + user_pages[data_page_index], + data_page_offset, + page_length); } - if (ret) - goto fail_put_pages; remain -= page_length; data_ptr += page_length; -- cgit v1.2.3 From ab34c226812588de8f341ce48eb32c3fef5155a9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 27 May 2010 14:15:35 +0100 Subject: drm/i915: Fix up address spaces in slow_kernel_write() Since we now get_user_pages() outside of the mutex prior to performing the copy, we kmap() the page inside the copy routine and so need to perform an ordinary memcpy() and not copy_from_user(). Signed-off-by: Chris Wilson Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_gem.c | 42 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b8e351274493..9ded3dae6c87 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -509,25 +509,24 @@ fast_user_write(struct io_mapping *mapping, * page faults */ -static inline int +static inline void slow_kernel_write(struct io_mapping *mapping, loff_t gtt_base, int gtt_offset, struct page *user_page, int user_offset, int length) { - char *src_vaddr, *dst_vaddr; - unsigned long unwritten; + char __iomem *dst_vaddr; + char *src_vaddr; - dst_vaddr = io_mapping_map_atomic_wc(mapping, gtt_base); - src_vaddr = kmap_atomic(user_page, KM_USER1); - unwritten = __copy_from_user_inatomic_nocache(dst_vaddr + gtt_offset, - src_vaddr + user_offset, - length); - kunmap_atomic(src_vaddr, KM_USER1); - io_mapping_unmap_atomic(dst_vaddr); - if (unwritten) - return -EFAULT; - return 0; + dst_vaddr = io_mapping_map_wc(mapping, gtt_base); + src_vaddr = kmap(user_page); + + memcpy_toio(dst_vaddr + gtt_offset, + src_vaddr + user_offset, + length); + + kunmap(user_page); + io_mapping_unmap(dst_vaddr); } static inline int @@ -700,18 +699,11 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, if ((data_page_offset + page_length) > PAGE_SIZE) page_length = PAGE_SIZE - data_page_offset; - ret = slow_kernel_write(dev_priv->mm.gtt_mapping, - gtt_page_base, gtt_page_offset, - user_pages[data_page_index], - data_page_offset, - page_length); - - /* If we get a fault while copying data, then (presumably) our - * source page isn't available. Return the error and we'll - * retry in the slow path. - */ - if (ret) - goto out_unpin_object; + slow_kernel_write(dev_priv->mm.gtt_mapping, + gtt_page_base, gtt_page_offset, + user_pages[data_page_index], + data_page_offset, + page_length); remain -= page_length; offset += page_length; -- cgit v1.2.3 From ca76482e0f4b64942c704fa11c620ffd1bdd8475 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Thu, 27 May 2010 10:26:42 +0800 Subject: drm/i915: Fix PIPE_CONTROL command on Sandybridge Sandybridge(Gen6) has new format for PIPE_CONTROL command, the flush and post-op control are in dword 1 now. This changes command length field for difference between Ironlake and Sandybridge. I tried to test this with noop request and issue PIPE_CONTROL command for each sequence and track notify interrupts, which seems work fine. Hopefully we don't need workaround like on Ironlake for Sandybridge. Signed-off-by: Zhenyu Wang Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_ringbuffer.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index f6b84fe8099a..cea4f1a8709e 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -213,7 +213,7 @@ static int init_render_ring(struct drm_device *dev, #define PIPE_CONTROL_FLUSH(addr) \ do { \ OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ - PIPE_CONTROL_DEPTH_STALL); \ + PIPE_CONTROL_DEPTH_STALL | 2); \ OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT); \ OUT_RING(0); \ OUT_RING(0); \ @@ -236,7 +236,19 @@ render_ring_add_request(struct drm_device *dev, u32 seqno; drm_i915_private_t *dev_priv = dev->dev_private; seqno = intel_ring_get_seqno(dev, ring); - if (HAS_PIPE_CONTROL(dev)) { + + if (IS_GEN6(dev)) { + BEGIN_LP_RING(6); + OUT_RING(GFX_OP_PIPE_CONTROL | 3); + OUT_RING(PIPE_CONTROL_QW_WRITE | + PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH | + PIPE_CONTROL_NOTIFY); + OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); + OUT_RING(seqno); + OUT_RING(0); + OUT_RING(0); + ADVANCE_LP_RING(); + } else if (HAS_PIPE_CONTROL(dev)) { u32 scratch_addr = dev_priv->seqno_gfx_addr + 128; /* -- cgit v1.2.3 From a1786bd270b08834a735e06c3d5430eeb0baf017 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Thu, 27 May 2010 10:26:43 +0800 Subject: drm/i915: Unmask interrupt for render engine on Sandybridge With splitted engines on Sandybridge, each engine has its own interrupt control as well. This unmasks the interrupt to properly enable pipe control notify event for render engine. Signed-off-by: Zhenyu Wang Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_reg.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index af7b10853e33..64b0a3afd92b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -369,6 +369,25 @@ #define BB_ADDR 0x02140 /* 8 bytes */ #define GFX_FLSH_CNTL 0x02170 /* 915+ only */ +/* GEN6 interrupt control */ +#define GEN6_RENDER_HWSTAM 0x2098 +#define GEN6_RENDER_IMR 0x20a8 +#define GEN6_RENDER_CONTEXT_SWITCH_INTERRUPT (1 << 8) +#define GEN6_RENDER_PPGTT_PAGE_FAULT (1 << 7) +#define GEN6_RENDER TIMEOUT_COUNTER_EXPIRED (1 << 6) +#define GEN6_RENDER_L3_PARITY_ERROR (1 << 5) +#define GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT (1 << 4) +#define GEN6_RENDER_COMMAND_PARSER_MASTER_ERROR (1 << 3) +#define GEN6_RENDER_SYNC_STATUS (1 << 2) +#define GEN6_RENDER_DEBUG_INTERRUPT (1 << 1) +#define GEN6_RENDER_USER_INTERRUPT (1 << 0) + +#define GEN6_BLITTER_HWSTAM 0x22098 +#define GEN6_BLITTER_IMR 0x220a8 +#define GEN6_BLITTER_MI_FLUSH_DW_NOTIFY_INTERRUPT (1 << 26) +#define GEN6_BLITTER_COMMAND_PARSER_MASTER_ERROR (1 << 25) +#define GEN6_BLITTER_SYNC_STATUS (1 << 24) +#define GEN6_BLITTER_USER_INTERRUPT (1 << 22) /* * BSD (bit stream decoder instruction and interrupt control register defines * (G4X and Ironlake only) -- cgit v1.2.3 From 2671717265ae6e720a9ba5f13fbec3a718983b65 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Mon, 8 Mar 2010 14:07:30 -0500 Subject: intel_idle: native hardware cpuidle driver for latest Intel processors This EXPERIMENTAL driver supersedes acpi_idle on Intel Atom Processors, Intel Core i3/i5/i7 Processors and associated Intel Xeon processors. It does not support the Intel Core2 processor or earlier. For kernels configured with ACPI, CONFIG_INTEL_IDLE=y allows intel_idle to probe before the ACPI processor driver. Booting with "intel_idle.max_cstate=0" disables intel_idle and the system will fall back on ACPI's "acpi_idle". Typical Linux distributions load ACPI processor module early, making CONFIG_INTEL_IDLE=m not easily useful on ACPI platforms. intel_idle probes all processors at module_init time. Processors that are hot-added later will be limited to using C1 in idle. Signed-off-by: Len Brown --- MAINTAINERS | 7 + drivers/Makefile | 2 +- drivers/acpi/processor_driver.c | 6 +- drivers/idle/Kconfig | 11 + drivers/idle/Makefile | 1 + drivers/idle/intel_idle.c | 461 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 486 insertions(+), 2 deletions(-) create mode 100755 drivers/idle/intel_idle.c (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index d329b053a718..276e79bb462c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2850,6 +2850,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git S: Maintained F: drivers/input/ +INTEL IDLE DRIVER +M: Len Brown +L: linux-pm@lists.linux-foundation.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-idle-2.6.git +S: Supported +F: drivers/idle/intel_idle.c + INTEL FRAMEBUFFER DRIVER (excluding 810 and 815) M: Maik Broemme L: linux-fbdev@vger.kernel.org diff --git a/drivers/Makefile b/drivers/Makefile index f42a03029b7c..91874e048552 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_PCI) += pci/ obj-$(CONFIG_PARISC) += parisc/ obj-$(CONFIG_RAPIDIO) += rapidio/ obj-y += video/ +obj-y += idle/ obj-$(CONFIG_ACPI) += acpi/ obj-$(CONFIG_SFI) += sfi/ # PnP must come after ACPI since it will eventually need to check if acpi @@ -91,7 +92,6 @@ obj-$(CONFIG_EISA) += eisa/ obj-y += lguest/ obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_CPU_IDLE) += cpuidle/ -obj-y += idle/ obj-$(CONFIG_MMC) += mmc/ obj-$(CONFIG_MEMSTICK) += memstick/ obj-$(CONFIG_NEW_LEDS) += leds/ diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index deefa8591746..b1034a9ada4e 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -922,9 +922,13 @@ static int __init acpi_processor_init(void) return -ENOMEM; #endif - if (!cpuidle_register_driver(&acpi_idle_driver)) + if (!cpuidle_register_driver(&acpi_idle_driver)) { printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", acpi_idle_driver.name); + } else { + printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s", + cpuidle_get_driver()->name); + } result = acpi_bus_register_driver(&acpi_processor_driver); if (result < 0) diff --git a/drivers/idle/Kconfig b/drivers/idle/Kconfig index f15e90a453d1..fb5c5186d4aa 100644 --- a/drivers/idle/Kconfig +++ b/drivers/idle/Kconfig @@ -1,3 +1,14 @@ +config INTEL_IDLE + tristate "Cpuidle Driver for Intel Processors" + depends on CPU_IDLE + depends on X86 + depends on CPU_SUP_INTEL + depends on EXPERIMENTAL + help + Enable intel_idle, a cpuidle driver that includes knowledge of + native Intel hardware idle features. The acpi_idle driver + can be configured at the same time, in order to handle + processors intel_idle does not support. menu "Memory power savings" depends on X86_64 diff --git a/drivers/idle/Makefile b/drivers/idle/Makefile index 5f68fc377e21..23d295cf10f2 100644 --- a/drivers/idle/Makefile +++ b/drivers/idle/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_I7300_IDLE) += i7300_idle.o +obj-$(CONFIG_INTEL_IDLE) += intel_idle.o diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c new file mode 100755 index 000000000000..54f0fb4cd5d2 --- /dev/null +++ b/drivers/idle/intel_idle.c @@ -0,0 +1,461 @@ +/* + * intel_idle.c - native hardware idle loop for modern Intel processors + * + * Copyright (c) 2010, Intel Corporation. + * Len Brown + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * intel_idle is a cpuidle driver that loads on specific Intel processors + * in lieu of the legacy ACPI processor_idle driver. The intent is to + * make Linux more efficient on these processors, as intel_idle knows + * more than ACPI, as well as make Linux more immune to ACPI BIOS bugs. + */ + +/* + * Design Assumptions + * + * All CPUs have same idle states as boot CPU + * + * Chipset BM_STS (bus master status) bit is a NOP + * for preventing entry into deep C-stats + */ + +/* + * Known limitations + * + * The driver currently initializes for_each_online_cpu() upon modprobe. + * It it unaware of subsequent processors hot-added to the system. + * This means that if you boot with maxcpus=n and later online + * processors above n, those processors will use C1 only. + * + * ACPI has a .suspend hack to turn off deep c-statees during suspend + * to avoid complications with the lapic timer workaround. + * Have not seen issues with suspend, but may need same workaround here. + * + * There is currently no kernel-based automatic probing/loading mechanism + * if the driver is built as a module. + */ + +/* un-comment DEBUG to enable pr_debug() statements */ +#define DEBUG + +#include +#include +#include +#include /* ktime_get_real() */ +#include +#include + +#define INTEL_IDLE_VERSION "0.4" +#define PREFIX "intel_idle: " + +#define MWAIT_SUBSTATE_MASK (0xf) +#define MWAIT_CSTATE_MASK (0xf) +#define MWAIT_SUBSTATE_SIZE (4) +#define MWAIT_MAX_NUM_CSTATES 8 +#define CPUID_MWAIT_LEAF (5) +#define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1) +#define CPUID5_ECX_INTERRUPT_BREAK (0x2) + +static struct cpuidle_driver intel_idle_driver = { + .name = "intel_idle", + .owner = THIS_MODULE, +}; +/* intel_idle.max_cstate=0 disables driver */ +static int max_cstate = MWAIT_MAX_NUM_CSTATES - 1; +static int power_policy = 7; /* 0 = max perf; 15 = max powersave */ + +static unsigned int substates; +static int (*choose_substate)(int); + +/* Reliable LAPIC Timer States, bit 1 for C1 etc. */ +static unsigned int lapic_timer_reliable_states; + +static struct cpuidle_device *intel_idle_cpuidle_devices; +static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state); + +static struct cpuidle_state *cpuidle_state_table; + +/* + * States are indexed by the cstate number, + * which is also the index into the MWAIT hint array. + * Thus C0 is a dummy. + */ +static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { + { /* MWAIT C0 */ }, + { /* MWAIT C1 */ + .name = "NHM-C1", + .desc = "MWAIT 0x00", + .driver_data = (void *) 0x00, + .flags = CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 3, + .power_usage = 1000, + .target_residency = 6, + .enter = &intel_idle }, + { /* MWAIT C2 */ + .name = "NHM-C3", + .desc = "MWAIT 0x10", + .driver_data = (void *) 0x10, + .flags = CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 20, + .power_usage = 500, + .target_residency = 80, + .enter = &intel_idle }, + { /* MWAIT C3 */ + .name = "NHM-C6", + .desc = "MWAIT 0x20", + .driver_data = (void *) 0x20, + .flags = CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 200, + .power_usage = 350, + .target_residency = 800, + .enter = &intel_idle }, +}; + +static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { + { /* MWAIT C0 */ }, + { /* MWAIT C1 */ + .name = "ATM-C1", + .desc = "MWAIT 0x00", + .driver_data = (void *) 0x00, + .flags = CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 1, + .power_usage = 1000, + .target_residency = 4, + .enter = &intel_idle }, + { /* MWAIT C2 */ + .name = "ATM-C2", + .desc = "MWAIT 0x10", + .driver_data = (void *) 0x10, + .flags = CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 20, + .power_usage = 500, + .target_residency = 80, + .enter = &intel_idle }, + { /* MWAIT C3 */ }, + { /* MWAIT C4 */ + .name = "ATM-C4", + .desc = "MWAIT 0x30", + .driver_data = (void *) 0x30, + .flags = CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 100, + .power_usage = 250, + .target_residency = 400, + .enter = &intel_idle }, + { /* MWAIT C5 */ }, + { /* MWAIT C6 */ + .name = "ATM-C6", + .desc = "MWAIT 0x40", + .driver_data = (void *) 0x40, + .flags = CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 200, + .power_usage = 150, + .target_residency = 800, + .enter = NULL }, /* disabled */ +}; + +/* + * choose_tunable_substate() + * + * Run-time decision on which C-state substate to invoke + * If power_policy = 0, choose shallowest substate (0) + * If power_policy = 15, choose deepest substate + * If power_policy = middle, choose middle substate etc. + */ +static int choose_tunable_substate(int cstate) +{ + unsigned int num_substates; + unsigned int substate_choice; + + power_policy &= 0xF; /* valid range: 0-15 */ + cstate &= 7; /* valid range: 0-7 */ + + num_substates = (substates >> ((cstate) * 4)) & MWAIT_SUBSTATE_MASK; + + if (num_substates <= 1) + return 0; + + substate_choice = ((power_policy + (power_policy + 1) * + (num_substates - 1)) / 16); + + return substate_choice; +} + +/* + * choose_zero_substate() + */ +static int choose_zero_substate(int cstate) +{ + return 0; +} + +/** + * intel_idle + * @dev: cpuidle_device + * @state: cpuidle state + * + */ +static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state) +{ + unsigned long ecx = 1; /* break on interrupt flag */ + unsigned long eax = (unsigned long)cpuidle_get_statedata(state); + unsigned int cstate; + ktime_t kt_before, kt_after; + s64 usec_delta; + int cpu = smp_processor_id(); + + cstate = (((eax) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1; + + eax = eax + (choose_substate)(cstate); + + local_irq_disable(); + + if (!(lapic_timer_reliable_states & (1 << (cstate)))) + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); + + kt_before = ktime_get_real(); + + stop_critical_timings(); +#ifndef MODULE + trace_power_start(POWER_CSTATE, (eax >> 4) + 1); +#endif + if (!need_resched()) { + + __monitor((void *)¤t_thread_info()->flags, 0, 0); + smp_mb(); + if (!need_resched()) + __mwait(eax, ecx); + } + + start_critical_timings(); + + kt_after = ktime_get_real(); + usec_delta = ktime_to_us(ktime_sub(kt_after, kt_before)); + + local_irq_enable(); + + if (!(lapic_timer_reliable_states & (1 << (cstate)))) + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); + + return usec_delta; +} + +/* + * intel_idle_probe() + */ +static int intel_idle_probe(void) +{ + unsigned int eax, ebx, ecx, edx; + + if (max_cstate == 0) { + pr_debug(PREFIX "disabled\n"); + return -EPERM; + } + + if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) + return -ENODEV; + + if (!boot_cpu_has(X86_FEATURE_MWAIT)) + return -ENODEV; + + if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF) + return -ENODEV; + + cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx); + + if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) || + !(ecx & CPUID5_ECX_INTERRUPT_BREAK)) + return -ENODEV; +#ifdef DEBUG + if (substates == 0) /* can over-ride via modparam */ +#endif + substates = edx; + + pr_debug(PREFIX "MWAIT substates: 0x%x\n", substates); + + if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */ + lapic_timer_reliable_states = 0xFFFFFFFF; + + if (boot_cpu_data.x86 != 6) /* family 6 */ + return -ENODEV; + + switch (boot_cpu_data.x86_model) { + + case 0x1A: /* Core i7, Xeon 5500 series */ + case 0x1E: /* Core i7 and i5 Processor - Lynnfield Jasper Forest */ + case 0x1F: /* Core i7 and i5 Processor - Nehalem */ + case 0x2E: /* Nehalem-EX Xeon */ + lapic_timer_reliable_states = (1 << 1); /* C1 */ + + case 0x25: /* Westmere */ + case 0x2C: /* Westmere */ + cpuidle_state_table = nehalem_cstates; + choose_substate = choose_tunable_substate; + break; + + case 0x1C: /* 28 - Atom Processor */ + lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */ + cpuidle_state_table = atom_cstates; + choose_substate = choose_zero_substate; + break; +#ifdef FUTURE_USE + case 0x17: /* 23 - Core 2 Duo */ + lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */ +#endif + + default: + pr_debug(PREFIX "does not run on family %d model %d\n", + boot_cpu_data.x86, boot_cpu_data.x86_model); + return -ENODEV; + } + + pr_debug(PREFIX "v" INTEL_IDLE_VERSION + " model 0x%X\n", boot_cpu_data.x86_model); + + pr_debug(PREFIX "lapic_timer_reliable_states 0x%x\n", + lapic_timer_reliable_states); + return 0; +} + +/* + * intel_idle_cpuidle_devices_uninit() + * unregister, free cpuidle_devices + */ +static void intel_idle_cpuidle_devices_uninit(void) +{ + int i; + struct cpuidle_device *dev; + + for_each_online_cpu(i) { + dev = per_cpu_ptr(intel_idle_cpuidle_devices, i); + cpuidle_unregister_device(dev); + } + + free_percpu(intel_idle_cpuidle_devices); + return; +} +/* + * intel_idle_cpuidle_devices_init() + * allocate, initialize, register cpuidle_devices + */ +static int intel_idle_cpuidle_devices_init(void) +{ + int i, cstate; + struct cpuidle_device *dev; + + intel_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device); + if (intel_idle_cpuidle_devices == NULL) + return -ENOMEM; + + for_each_online_cpu(i) { + dev = per_cpu_ptr(intel_idle_cpuidle_devices, i); + + dev->state_count = 1; + + for (cstate = 1; cstate < MWAIT_MAX_NUM_CSTATES; ++cstate) { + int num_substates; + + if (cstate > max_cstate) { + printk(PREFIX "max_cstate %d reached\n", + max_cstate); + break; + } + + /* does the state exist in CPUID.MWAIT? */ + num_substates = (substates >> ((cstate) * 4)) + & MWAIT_SUBSTATE_MASK; + if (num_substates == 0) + continue; + /* is the state not enabled? */ + if (cpuidle_state_table[cstate].enter == NULL) { + /* does the driver not know about the state? */ + if (*cpuidle_state_table[cstate].name == '\0') + pr_debug(PREFIX "unaware of model 0x%x" + " MWAIT %d please" + " contact lenb@kernel.org", + boot_cpu_data.x86_model, cstate); + continue; + } + + if ((cstate > 2) && + !boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) + mark_tsc_unstable("TSC halts in idle" + " states deeper than C2"); + + dev->states[dev->state_count] = /* structure copy */ + cpuidle_state_table[cstate]; + + dev->state_count += 1; + } + + dev->cpu = i; + if (cpuidle_register_device(dev)) { + pr_debug(PREFIX "cpuidle_register_device %d failed!\n", + i); + intel_idle_cpuidle_devices_uninit(); + return -EIO; + } + } + + return 0; +} + + +static int __init intel_idle_init(void) +{ + int retval; + + retval = intel_idle_probe(); + if (retval) + return retval; + + retval = cpuidle_register_driver(&intel_idle_driver); + if (retval) { + printk(KERN_DEBUG PREFIX "intel_idle yielding to %s", + cpuidle_get_driver()->name); + return retval; + } + + retval = intel_idle_cpuidle_devices_init(); + if (retval) { + cpuidle_unregister_driver(&intel_idle_driver); + return retval; + } + + return 0; +} + +static void __exit intel_idle_exit(void) +{ + intel_idle_cpuidle_devices_uninit(); + cpuidle_unregister_driver(&intel_idle_driver); + + return; +} + +module_init(intel_idle_init); +module_exit(intel_idle_exit); + +module_param(power_policy, int, 0644); +module_param(max_cstate, int, 0444); +#ifdef DEBUG +module_param(substates, int, 0444); +#endif + +MODULE_AUTHOR("Len Brown "); +MODULE_DESCRIPTION("Cpuidle driver for Intel Hardware v" INTEL_IDLE_VERSION); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 2da513f582a96c053aacc2c92873978d2ea7abff Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Thu, 22 Apr 2010 16:48:33 -0700 Subject: ACPI: Minor cleanup eliminating redundant PMTIMER_TICKS to NS conversion acpi_enter_[simple,bm] does idle timing in ns, convert it to timeval, then to us, then to pmtimer_ticks and then back to ns. This patch changes things to idle timing in ns, convert it to us, and then to pmtimer_ticks. Just saves an imul along this path, but makes the code cleaner. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Len Brown --- drivers/acpi/processor_idle.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 63a3d4b8c238..43fe52f9834b 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -859,6 +859,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, struct acpi_processor *pr; struct acpi_processor_cx *cx = cpuidle_get_statedata(state); ktime_t kt1, kt2; + s64 idle_time_ns; s64 idle_time; s64 sleep_ticks = 0; @@ -900,12 +901,14 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, sched_clock_idle_sleep_event(); acpi_idle_do_entry(cx); kt2 = ktime_get_real(); - idle_time = ktime_to_us(ktime_sub(kt2, kt1)); + idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1)); + idle_time = idle_time_ns; + do_div(idle_time, NSEC_PER_USEC); sleep_ticks = us_to_pm_timer_ticks(idle_time); /* Tell the scheduler how much we idled: */ - sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); + sched_clock_idle_wakeup_event(idle_time_ns); local_irq_enable(); current_thread_info()->status |= TS_POLLING; @@ -933,6 +936,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, struct acpi_processor *pr; struct acpi_processor_cx *cx = cpuidle_get_statedata(state); ktime_t kt1, kt2; + s64 idle_time_ns; s64 idle_time; s64 sleep_ticks = 0; @@ -1015,11 +1019,13 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, spin_unlock(&c3_lock); } kt2 = ktime_get_real(); - idle_time = ktime_to_us(ktime_sub(kt2, kt1)); + idle_time_ns = ktime_to_us(ktime_sub(kt2, kt1)); + idle_time = idle_time_ns; + do_div(idle_time, NSEC_PER_USEC); sleep_ticks = us_to_pm_timer_ticks(idle_time); /* Tell the scheduler how much we idled: */ - sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); + sched_clock_idle_wakeup_event(idle_time_ns); local_irq_enable(); current_thread_info()->status |= TS_POLLING; -- cgit v1.2.3 From b6fecaa8685a9922d11db2cd79e76f43c3edc970 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Sat, 27 Feb 2010 17:51:42 +0100 Subject: drivers/acpi/sleep.h: Checkpatch cleanup drivers/acpi/sleep.h:3: WARNING: space prohibited between function name and open parenthesis '(' Signed-off-by: Andrea Gelmini Signed-off-by: Len Brown --- drivers/acpi/sleep.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h index 8a8f3b3382a6..25b8bd149284 100644 --- a/drivers/acpi/sleep.h +++ b/drivers/acpi/sleep.h @@ -1,6 +1,6 @@ extern u8 sleep_states[]; -extern int acpi_suspend (u32 state); +extern int acpi_suspend(u32 state); extern void acpi_enable_wakeup_device_prep(u8 sleep_state); extern void acpi_enable_wakeup_device(u8 sleep_state); -- cgit v1.2.3 From 0dc698b93f3eecdda43b22232131324eb41e510c Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Tue, 18 May 2010 14:39:16 -0700 Subject: ACPI: Don't let acpi_pad needlessly mark TSC unstable acpi pad driver kind of aggressively marks TSC as unstable at init time, on mwait capable and non X86_FEATURE_NONSTOP_TSC systems. This is irrespective of whether pad driver is ever going to be used on the system or deep C-states are supported/used. This will affect every user who just happens to compile in (or get a kernel version which compiles in) acpi pad driver. Move mark_tsc_unstable() out of init to the actual idle invocation path of the pad driver. There is also another bug/missing_feature in the code that it does not support 'always running apic timer' and switches to broadcast mode unconditionally. Shaohua, can you take a look at that please. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Len Brown --- drivers/acpi/acpi_pad.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 62122134693b..f169e516a1af 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -43,6 +43,10 @@ static DEFINE_MUTEX(isolated_cpus_lock); #define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1) #define CPUID5_ECX_INTERRUPT_BREAK (0x2) static unsigned long power_saving_mwait_eax; + +static unsigned char tsc_detected_unstable; +static unsigned char tsc_marked_unstable; + static void power_saving_mwait_init(void) { unsigned int eax, ebx, ecx, edx; @@ -87,8 +91,8 @@ static void power_saving_mwait_init(void) /*FALL THROUGH*/ default: - /* TSC could halt in idle, so notify users */ - mark_tsc_unstable("TSC halts in idle"); + /* TSC could halt in idle */ + tsc_detected_unstable = 1; } #endif } @@ -178,6 +182,11 @@ static int power_saving_thread(void *data) expire_time = jiffies + HZ * (100 - idle_pct) / 100; while (!need_resched()) { + if (tsc_detected_unstable && !tsc_marked_unstable) { + /* TSC could halt in idle, so notify users */ + mark_tsc_unstable("TSC halts in idle"); + tsc_marked_unstable = 1; + } local_irq_disable(); cpu = smp_processor_id(); clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, -- cgit v1.2.3 From cf22f20ade30f8c03955324aaf27b1049e182600 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 29 May 2010 06:50:37 +1000 Subject: drm/radeon: fix the r100/r200 ums block 0 page fix airlied -> brown paper bag. I blame Hi-5 or the Wiggles for lowering my IQ, move the fix inside some brackets instead of breaking everything in site. Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_state.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index 40ab6d9c3736..11ce94c668e7 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c @@ -900,9 +900,10 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, flags |= RADEON_FRONT; } if (flags & (RADEON_DEPTH|RADEON_STENCIL)) { - if (!dev_priv->have_z_offset) + if (!dev_priv->have_z_offset) { printk_once(KERN_ERR "radeon: illegal depth clear request. Buggy mesa detected - please update.\n"); - flags &= ~(RADEON_DEPTH | RADEON_STENCIL); + flags &= ~(RADEON_DEPTH | RADEON_STENCIL); + } } if (flags & (RADEON_FRONT | RADEON_BACK)) { -- cgit v1.2.3 From d5a64513c6a171262082c250592c062e97a2c693 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 9 Apr 2010 01:39:40 +0200 Subject: ACPI / EC / PM: Fix race between EC transactions and system suspend There still is a race that may result in suspending the system in the middle of an EC transaction in progress, which leads to problems (like the kernel thinking that the ACPI global lock is held during resume while in fact it's not). To remove the race condition, modify the ACPI platform suspend and hibernate callbacks so that EC transactions are blocked right after executing the _PTS global control method and are allowed to happen again right after the low-level wakeup. Introduce acpi_pm_freeze() that will disable GPEs, wait until the event queues are empty and block EC transactions. Use it wherever GPEs are disabled in preparation for switching local interrupts off. Introduce acpi_pm_thaw() that will allow EC transactions to happen again and enable runtime GPEs. Use it to balance acpi_pm_freeze() wherever necessary. In addition to that use acpi_ec_resume_transactions_early() to unblock EC transactions as early as reasonably possible during resume. Also unblock EC transactions in acpi_hibernation_finish() and in the analogous suspend routine to make sure that the EC transactions are enabled in all error paths. Fixes https://bugzilla.kernel.org/show_bug.cgi?id=14668 Signed-off-by: Rafael J. Wysocki Reported-and-tested-by: Maxim Levitsky Signed-off-by: Len Brown --- drivers/acpi/ec.c | 10 +++++++++ drivers/acpi/internal.h | 1 + drivers/acpi/sleep.c | 55 ++++++++++++++++++++++++++----------------------- 3 files changed, 40 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index f2234db85da0..2c2b73a2a7c2 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -485,6 +485,16 @@ void acpi_ec_resume_transactions(void) mutex_unlock(&ec->lock); } +void acpi_ec_resume_transactions_early(void) +{ + /* + * Allow transactions to happen again (this function is called from + * atomic context during wakeup, so we don't need to acquire the mutex). + */ + if (first_ec) + clear_bit(EC_FLAGS_FROZEN, &first_ec->flags); +} + static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data) { int result; diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index e28411367239..0ec48c7efa9b 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -51,6 +51,7 @@ int acpi_ec_ecdt_probe(void); int acpi_boot_ec_enable(void); void acpi_ec_suspend_transactions(void); void acpi_ec_resume_transactions(void); +void acpi_ec_resume_transactions_early(void); /*-------------------------------------------------------------------------- Suspend/Resume diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index baa76bbf244a..24741ac65897 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -110,11 +110,13 @@ void __init acpi_old_suspend_ordering(void) } /** - * acpi_pm_disable_gpes - Disable the GPEs. + * acpi_pm_freeze - Disable the GPEs and suspend EC transactions. */ -static int acpi_pm_disable_gpes(void) +static int acpi_pm_freeze(void) { acpi_disable_all_gpes(); + acpi_os_wait_events_complete(NULL); + acpi_ec_suspend_transactions(); return 0; } @@ -142,7 +144,8 @@ static int acpi_pm_prepare(void) int error = __acpi_pm_prepare(); if (!error) - acpi_disable_all_gpes(); + acpi_pm_freeze(); + return error; } @@ -275,6 +278,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state) * acpi_leave_sleep_state will reenable specific GPEs later */ acpi_disable_all_gpes(); + /* Allow EC transactions to happen. */ + acpi_ec_resume_transactions_early(); local_irq_restore(flags); printk(KERN_DEBUG "Back to C!\n"); @@ -286,6 +291,12 @@ static int acpi_suspend_enter(suspend_state_t pm_state) return ACPI_SUCCESS(status) ? 0 : -EFAULT; } +static void acpi_suspend_finish(void) +{ + acpi_ec_resume_transactions(); + acpi_pm_finish(); +} + static int acpi_suspend_state_valid(suspend_state_t pm_state) { u32 acpi_state; @@ -307,7 +318,7 @@ static struct platform_suspend_ops acpi_suspend_ops = { .begin = acpi_suspend_begin, .prepare_late = acpi_pm_prepare, .enter = acpi_suspend_enter, - .wake = acpi_pm_finish, + .wake = acpi_suspend_finish, .end = acpi_pm_end, }; @@ -333,9 +344,9 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state) static struct platform_suspend_ops acpi_suspend_ops_old = { .valid = acpi_suspend_state_valid, .begin = acpi_suspend_begin_old, - .prepare_late = acpi_pm_disable_gpes, + .prepare_late = acpi_pm_freeze, .enter = acpi_suspend_enter, - .wake = acpi_pm_finish, + .wake = acpi_suspend_finish, .end = acpi_pm_end, .recover = acpi_pm_finish, }; @@ -586,6 +597,7 @@ static int acpi_hibernation_enter(void) static void acpi_hibernation_finish(void) { hibernate_nvs_free(); + acpi_ec_resume_transactions(); acpi_pm_finish(); } @@ -606,17 +618,11 @@ static void acpi_hibernation_leave(void) } /* Restore the NVS memory area */ hibernate_nvs_restore(); + /* Allow EC transactions to happen. */ + acpi_ec_resume_transactions_early(); } -static int acpi_pm_pre_restore(void) -{ - acpi_disable_all_gpes(); - acpi_os_wait_events_complete(NULL); - acpi_ec_suspend_transactions(); - return 0; -} - -static void acpi_pm_restore_cleanup(void) +static void acpi_pm_thaw(void) { acpi_ec_resume_transactions(); acpi_enable_all_runtime_gpes(); @@ -630,8 +636,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops = { .prepare = acpi_pm_prepare, .enter = acpi_hibernation_enter, .leave = acpi_hibernation_leave, - .pre_restore = acpi_pm_pre_restore, - .restore_cleanup = acpi_pm_restore_cleanup, + .pre_restore = acpi_pm_freeze, + .restore_cleanup = acpi_pm_thaw, }; /** @@ -663,12 +669,9 @@ static int acpi_hibernation_begin_old(void) static int acpi_hibernation_pre_snapshot_old(void) { - int error = acpi_pm_disable_gpes(); - - if (!error) - hibernate_nvs_save(); - - return error; + acpi_pm_freeze(); + hibernate_nvs_save(); + return 0; } /* @@ -680,11 +683,11 @@ static struct platform_hibernation_ops acpi_hibernation_ops_old = { .end = acpi_pm_end, .pre_snapshot = acpi_hibernation_pre_snapshot_old, .finish = acpi_hibernation_finish, - .prepare = acpi_pm_disable_gpes, + .prepare = acpi_pm_freeze, .enter = acpi_hibernation_enter, .leave = acpi_hibernation_leave, - .pre_restore = acpi_pm_pre_restore, - .restore_cleanup = acpi_pm_restore_cleanup, + .pre_restore = acpi_pm_freeze, + .restore_cleanup = acpi_pm_thaw, .recover = acpi_pm_finish, }; #endif /* CONFIG_HIBERNATION */ -- cgit v1.2.3 From fe955682d2153b35dffcf1673dff0491096a3f0a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 9 Apr 2010 01:40:38 +0200 Subject: ACPI / EC / PM: Fix names of functions that block/unblock EC transactions The names of the functions used for blocking/unblocking EC transactions during suspend/hibernation suggest that the transactions are suspended and resumed by them, while in fact they are disabled and enabled. Rename the functions (and the flag used by them) to better reflect what they really do. Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- drivers/acpi/ec.c | 16 ++++++++-------- drivers/acpi/internal.h | 6 +++--- drivers/acpi/sleep.c | 12 ++++++------ 3 files changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 2c2b73a2a7c2..3f01f065b533 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -79,7 +79,7 @@ enum { EC_FLAGS_GPE_STORM, /* GPE storm detected */ EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and * OpReg are installed */ - EC_FLAGS_FROZEN, /* Transactions are suspended */ + EC_FLAGS_BLOCKED, /* Transactions are blocked */ }; /* If we find an EC via the ECDT, we need to keep a ptr to its context */ @@ -293,7 +293,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) if (t->rdata) memset(t->rdata, 0, t->rlen); mutex_lock(&ec->lock); - if (test_bit(EC_FLAGS_FROZEN, &ec->flags)) { + if (test_bit(EC_FLAGS_BLOCKED, &ec->flags)) { status = -EINVAL; goto unlock; } @@ -459,7 +459,7 @@ int ec_transaction(u8 command, EXPORT_SYMBOL(ec_transaction); -void acpi_ec_suspend_transactions(void) +void acpi_ec_block_transactions(void) { struct acpi_ec *ec = first_ec; @@ -468,11 +468,11 @@ void acpi_ec_suspend_transactions(void) mutex_lock(&ec->lock); /* Prevent transactions from being carried out */ - set_bit(EC_FLAGS_FROZEN, &ec->flags); + set_bit(EC_FLAGS_BLOCKED, &ec->flags); mutex_unlock(&ec->lock); } -void acpi_ec_resume_transactions(void) +void acpi_ec_unblock_transactions(void) { struct acpi_ec *ec = first_ec; @@ -481,18 +481,18 @@ void acpi_ec_resume_transactions(void) mutex_lock(&ec->lock); /* Allow transactions to be carried out again */ - clear_bit(EC_FLAGS_FROZEN, &ec->flags); + clear_bit(EC_FLAGS_BLOCKED, &ec->flags); mutex_unlock(&ec->lock); } -void acpi_ec_resume_transactions_early(void) +void acpi_ec_unblock_transactions_early(void) { /* * Allow transactions to happen again (this function is called from * atomic context during wakeup, so we don't need to acquire the mutex). */ if (first_ec) - clear_bit(EC_FLAGS_FROZEN, &first_ec->flags); + clear_bit(EC_FLAGS_BLOCKED, &first_ec->flags); } static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data) diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 0ec48c7efa9b..f8f190ec066e 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -49,9 +49,9 @@ void acpi_early_processor_set_pdc(void); int acpi_ec_init(void); int acpi_ec_ecdt_probe(void); int acpi_boot_ec_enable(void); -void acpi_ec_suspend_transactions(void); -void acpi_ec_resume_transactions(void); -void acpi_ec_resume_transactions_early(void); +void acpi_ec_block_transactions(void); +void acpi_ec_unblock_transactions(void); +void acpi_ec_unblock_transactions_early(void); /*-------------------------------------------------------------------------- Suspend/Resume diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 24741ac65897..504a55edac49 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -116,7 +116,7 @@ static int acpi_pm_freeze(void) { acpi_disable_all_gpes(); acpi_os_wait_events_complete(NULL); - acpi_ec_suspend_transactions(); + acpi_ec_block_transactions(); return 0; } @@ -279,7 +279,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state) */ acpi_disable_all_gpes(); /* Allow EC transactions to happen. */ - acpi_ec_resume_transactions_early(); + acpi_ec_unblock_transactions_early(); local_irq_restore(flags); printk(KERN_DEBUG "Back to C!\n"); @@ -293,7 +293,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state) static void acpi_suspend_finish(void) { - acpi_ec_resume_transactions(); + acpi_ec_unblock_transactions(); acpi_pm_finish(); } @@ -597,7 +597,7 @@ static int acpi_hibernation_enter(void) static void acpi_hibernation_finish(void) { hibernate_nvs_free(); - acpi_ec_resume_transactions(); + acpi_ec_unblock_transactions(); acpi_pm_finish(); } @@ -619,12 +619,12 @@ static void acpi_hibernation_leave(void) /* Restore the NVS memory area */ hibernate_nvs_restore(); /* Allow EC transactions to happen. */ - acpi_ec_resume_transactions_early(); + acpi_ec_unblock_transactions_early(); } static void acpi_pm_thaw(void) { - acpi_ec_resume_transactions(); + acpi_ec_unblock_transactions(); acpi_enable_all_runtime_gpes(); } -- cgit v1.2.3 From 32f6249ba7d63d5d86dae930d63ca70ec11d59af Mon Sep 17 00:00:00 2001 From: Mark Ware Date: Sat, 29 May 2010 00:16:28 -0700 Subject: fs_enet: Adjust BDs after tx error This patch fixes an occasional transmit lockup in the mac-fcc which occurs after a tx error. The test scenario had the local port set to autoneg and the other end fixed at 100FD, resulting in a large number of late collisions. According to the MPC8280RM 30.10.1.3 (also 8272RM 29.10.1.3), after a tx error occurs, TBPTR may sometimes point beyond BDs still marked as ready. This patch walks back through the BDs and points TBPTR to the earliest one marked as ready. Tested on a custom board with a MPC8280. Signed-off-by: Mark Ware Signed-off-by: David S. Miller --- drivers/net/fs_enet/mac-fcc.c | 49 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c index 714da967fa19..0ae65a2f1ab9 100644 --- a/drivers/net/fs_enet/mac-fcc.c +++ b/drivers/net/fs_enet/mac-fcc.c @@ -504,17 +504,54 @@ static int get_regs_len(struct net_device *dev) } /* Some transmit errors cause the transmitter to shut - * down. We now issue a restart transmit. Since the - * errors close the BD and update the pointers, the restart - * _should_ pick up without having to reset any of our - * pointers either. Also, To workaround 8260 device erratum - * CPM37, we must disable and then re-enable the transmitter - * following a Late Collision, Underrun, or Retry Limit error. + * down. We now issue a restart transmit. + * Also, to workaround 8260 device erratum CPM37, we must + * disable and then re-enable the transmitterfollowing a + * Late Collision, Underrun, or Retry Limit error. + * In addition, tbptr may point beyond BDs beyond still marked + * as ready due to internal pipelining, so we need to look back + * through the BDs and adjust tbptr to point to the last BD + * marked as ready. This may result in some buffers being + * retransmitted. */ static void tx_restart(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); fcc_t __iomem *fccp = fep->fcc.fccp; + const struct fs_platform_info *fpi = fep->fpi; + fcc_enet_t __iomem *ep = fep->fcc.ep; + cbd_t __iomem *curr_tbptr; + cbd_t __iomem *recheck_bd; + cbd_t __iomem *prev_bd; + cbd_t __iomem *last_tx_bd; + + last_tx_bd = fep->tx_bd_base + (fpi->tx_ring * sizeof(cbd_t)); + + /* get the current bd held in TBPTR and scan back from this point */ + recheck_bd = curr_tbptr = (cbd_t __iomem *) + ((R32(ep, fen_genfcc.fcc_tbptr) - fep->ring_mem_addr) + + fep->ring_base); + + prev_bd = (recheck_bd == fep->tx_bd_base) ? last_tx_bd : recheck_bd - 1; + + /* Move through the bds in reverse, look for the earliest buffer + * that is not ready. Adjust TBPTR to the following buffer */ + while ((CBDR_SC(prev_bd) & BD_ENET_TX_READY) != 0) { + /* Go back one buffer */ + recheck_bd = prev_bd; + + /* update the previous buffer */ + prev_bd = (prev_bd == fep->tx_bd_base) ? last_tx_bd : prev_bd - 1; + + /* We should never see all bds marked as ready, check anyway */ + if (recheck_bd == curr_tbptr) + break; + } + /* Now update the TBPTR and dirty flag to the current buffer */ + W32(ep, fen_genfcc.fcc_tbptr, + (uint) (((void *)recheck_bd - fep->ring_base) + + fep->ring_mem_addr)); + fep->dirty_tx = recheck_bd; C32(fccp, fcc_gfmr, FCC_GFMR_ENT); udelay(10); -- cgit v1.2.3 From e72e9f3814cb8c1076d627c29cec90b005838ac3 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 26 May 2010 05:55:10 +0000 Subject: drivers/isdn/hardware/mISDN: Add missing spin_unlock Add a spin_unlock missing on the error path. The return value of write_reg seems to be completely ignored, so it seems that the lock should be released in every case. The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression E1; @@ * spin_lock(E1,...); <+... when != E1 if (...) { ... when != E1 * return ...; } ...+> * spin_unlock(E1,...); // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/isdn/hardware/mISDN/hfcsusb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c index b3b7e2879bac..8700474747e8 100644 --- a/drivers/isdn/hardware/mISDN/hfcsusb.c +++ b/drivers/isdn/hardware/mISDN/hfcsusb.c @@ -97,8 +97,10 @@ static int write_reg(struct hfcsusb *hw, __u8 reg, __u8 val) hw->name, __func__, reg, val); spin_lock(&hw->ctrl_lock); - if (hw->ctrl_cnt >= HFC_CTRL_BUFSIZE) + if (hw->ctrl_cnt >= HFC_CTRL_BUFSIZE) { + spin_unlock(&hw->ctrl_lock); return 1; + } buf = &hw->ctrl_buff[hw->ctrl_in_idx]; buf->hfcs_reg = reg; buf->reg_val = val; -- cgit v1.2.3 From 2892d9c2d925e0d72a7a529852942e2592a970f8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 26 May 2010 04:46:35 +0000 Subject: be2net: add unlock on error path The unlock accidentally got removed from the error path in dd131e76e5: "be2net: Bug fix to avoid disabling bottom half during firmware upgrade." Signed-off-by: Dan Carpenter Acked-by: Sarveshwar Bandi Signed-off-by: David S. Miller --- drivers/net/benet/be_cmds.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 9d11dbf5e4da..a4a9cf762441 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -1429,7 +1429,7 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, wrb = wrb_from_mccq(adapter); if (!wrb) { status = -EBUSY; - goto err; + goto err_unlock; } req = cmd->va; sge = nonembedded_sgl(wrb); @@ -1457,7 +1457,10 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, else status = adapter->flash_status; -err: + return status; + +err_unlock: + spin_unlock_bh(&adapter->mcc_lock); return status; } -- cgit v1.2.3 From c196b02ce60d7b1f9bc62a62c5706d4d58fbfc5a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 26 May 2010 04:47:39 +0000 Subject: be2net: remove superfluous externs This fixes some sparse warnings: drivers/net/benet/be_cmds.c:1503:12: warning: function 'be_cmd_enable_magic_wol' with external linkage has definition drivers/net/benet/be_cmds.c:1668:12: warning: function 'be_cmd_get_seeprom_data' with external linkage has definition Signed-off-by: Dan Carpenter Acked-by: Sarveshwar Bandi Signed-off-by: David S. Miller --- drivers/net/benet/be_cmds.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index a4a9cf762441..9e305d7fb4bd 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -1500,7 +1500,7 @@ err: return status; } -extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, +int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, struct be_dma_mem *nonemb_cmd) { struct be_mcc_wrb *wrb; @@ -1665,7 +1665,7 @@ err: return status; } -extern int be_cmd_get_seeprom_data(struct be_adapter *adapter, +int be_cmd_get_seeprom_data(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd) { struct be_mcc_wrb *wrb; -- cgit v1.2.3 From 97ef6f7449da6ceddf9a90fa8851f607b67283dd Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 28 May 2010 15:08:08 -0700 Subject: rapidio: fix new kernel-doc warnings Fix a bunch of new rapidio kernel-doc warnings: Warning(include/linux/rio.h:123): No description found for parameter 'comp_tag' Warning(include/linux/rio.h:123): No description found for parameter 'phys_efptr' Warning(include/linux/rio.h:123): No description found for parameter 'em_efptr' Warning(include/linux/rio.h:123): No description found for parameter 'pwcback' Warning(include/linux/rio.h:247): No description found for parameter 'set_domain' Warning(include/linux/rio.h:247): No description found for parameter 'get_domain' Warning(drivers/rapidio/rio-scan.c:1133): No description found for parameter 'rdev' Warning(drivers/rapidio/rio-scan.c:1133): Excess function parameter 'port' description in 'rio_init_em' Warning(drivers/rapidio/rio.c:349): No description found for parameter 'rdev' Warning(drivers/rapidio/rio.c:349): Excess function parameter 'mport' description in 'rio_request_inb_pwrite' Warning(drivers/rapidio/rio.c:393): No description found for parameter 'port' Warning(drivers/rapidio/rio.c:393): No description found for parameter 'local' Warning(drivers/rapidio/rio.c:393): No description found for parameter 'destid' Warning(drivers/rapidio/rio.c:393): No description found for parameter 'hopcount' Warning(drivers/rapidio/rio.c:393): Excess function parameter 'rdev' description in 'rio_mport_get_physefb' Warning(drivers/rapidio/rio.c:845): Excess function parameter 'local' description in 'rio_std_route_clr_table' Signed-off-by: Randy Dunlap Cc: Alexandre Bounine Signed-off-by: Linus Torvalds --- drivers/rapidio/rio-scan.c | 2 +- drivers/rapidio/rio.c | 10 ++++++---- include/linux/rio.h | 6 ++++++ 3 files changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index 566432106cc5..8070e074c739 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c @@ -1124,7 +1124,7 @@ static void rio_update_route_tables(struct rio_mport *port) /** * rio_init_em - Initializes RIO Error Management (for switches) - * @port: Master port associated with the RIO network + * @rdev: RIO device * * For each enumerated switch, call device-specific error management * initialization routine (if supplied by the switch driver). diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index 777e099a3d8f..08fa453af974 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c @@ -338,7 +338,7 @@ int rio_release_outb_dbell(struct rio_dev *rdev, struct resource *res) /** * rio_request_inb_pwrite - request inbound port-write message service - * @mport: RIO device to which register inbound port-write callback routine + * @rdev: RIO device to which register inbound port-write callback routine * @pwcback: Callback routine to execute when port-write is received * * Binds a port-write callback function to the RapidIO device. @@ -385,7 +385,10 @@ EXPORT_SYMBOL_GPL(rio_release_inb_pwrite); /** * rio_mport_get_physefb - Helper function that returns register offset * for Physical Layer Extended Features Block. - * @rdev: RIO device + * @port: Master port to issue transaction + * @local: Indicate a local master port or remote device access + * @destid: Destination ID of the device + * @hopcount: Number of switch hops to the device */ u32 rio_mport_get_physefb(struct rio_mport *port, int local, @@ -430,7 +433,7 @@ rio_mport_get_physefb(struct rio_mport *port, int local, /** * rio_get_comptag - Begin or continue searching for a RIO device by component tag - * @comp_tag: RIO component tad to match + * @comp_tag: RIO component tag to match * @from: Previous RIO device found in search, or %NULL for new search * * Iterates through the list of known RIO devices. If a RIO device is @@ -835,7 +838,6 @@ int rio_std_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, * rio_std_route_clr_table - Clear swotch route table using standard registers * defined in RIO specification rev.1.3. * @mport: Master port to issue transaction - * @local: Indicate a local master port or remote device access * @destid: Destination ID of the device * @hopcount: Number of switch hops to the device * @table: routing table ID (global or port-specific) diff --git a/include/linux/rio.h b/include/linux/rio.h index 19b5f227096e..bd6eb0ed34a7 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h @@ -88,11 +88,15 @@ union rio_pw_msg; * @swpinfo: Switch port info * @src_ops: Source operation capabilities * @dst_ops: Destination operation capabilities + * @comp_tag: RIO component tag + * @phys_efptr: RIO device extended features pointer + * @em_efptr: RIO Error Management features pointer * @dma_mask: Mask of bits of RIO address this device implements * @rswitch: Pointer to &struct rio_switch if valid for this device * @driver: Driver claiming this device * @dev: Device model device * @riores: RIO resources this device owns + * @pwcback: port-write callback function for this device * @destid: Network destination ID */ struct rio_dev { @@ -222,6 +226,8 @@ struct rio_net { * @add_entry: Callback for switch-specific route add function * @get_entry: Callback for switch-specific route get function * @clr_table: Callback for switch-specific clear route table function + * @set_domain: Callback for switch-specific domain setting function + * @get_domain: Callback for switch-specific domain get function * @em_init: Callback for switch-specific error management initialization function * @em_handle: Callback for switch-specific error management handler function */ -- cgit v1.2.3 From 487d9fc5016529d7d77dfe35b666fd3a090e2953 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 18 May 2010 14:42:51 +0000 Subject: sh: prepare MMCIF driver header file Update the MMCIF driver to include register information and register access functions in the header file. The MMCIF boot code builds on top of this. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/mmc/host/sh_mmcif.c | 125 +++++++++++++++++-------------------------- include/linux/mmc/sh_mmcif.h | 32 +++++++++++ 2 files changed, 82 insertions(+), 75 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index eb97830c0344..5d3f824bb5a3 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c @@ -30,25 +30,6 @@ #define DRIVER_NAME "sh_mmcif" #define DRIVER_VERSION "2010-04-28" -#define MMCIF_CE_CMD_SET 0x00000000 -#define MMCIF_CE_ARG 0x00000008 -#define MMCIF_CE_ARG_CMD12 0x0000000C -#define MMCIF_CE_CMD_CTRL 0x00000010 -#define MMCIF_CE_BLOCK_SET 0x00000014 -#define MMCIF_CE_CLK_CTRL 0x00000018 -#define MMCIF_CE_BUF_ACC 0x0000001C -#define MMCIF_CE_RESP3 0x00000020 -#define MMCIF_CE_RESP2 0x00000024 -#define MMCIF_CE_RESP1 0x00000028 -#define MMCIF_CE_RESP0 0x0000002C -#define MMCIF_CE_RESP_CMD12 0x00000030 -#define MMCIF_CE_DATA 0x00000034 -#define MMCIF_CE_INT 0x00000040 -#define MMCIF_CE_INT_MASK 0x00000044 -#define MMCIF_CE_HOST_STS1 0x00000048 -#define MMCIF_CE_HOST_STS2 0x0000004C -#define MMCIF_CE_VERSION 0x0000007C - /* CE_CMD_SET */ #define CMD_MASK 0x3f000000 #define CMD_SET_RTYP_NO ((0 << 23) | (0 << 22)) @@ -207,27 +188,17 @@ struct sh_mmcif_host { wait_queue_head_t intr_wait; }; -static inline u32 sh_mmcif_readl(struct sh_mmcif_host *host, unsigned int reg) -{ - return readl(host->addr + reg); -} - -static inline void sh_mmcif_writel(struct sh_mmcif_host *host, - unsigned int reg, u32 val) -{ - writel(val, host->addr + reg); -} static inline void sh_mmcif_bitset(struct sh_mmcif_host *host, unsigned int reg, u32 val) { - writel(val | sh_mmcif_readl(host, reg), host->addr + reg); + writel(val | readl(host->addr + reg), host->addr + reg); } static inline void sh_mmcif_bitclr(struct sh_mmcif_host *host, unsigned int reg, u32 val) { - writel(~val & sh_mmcif_readl(host, reg), host->addr + reg); + writel(~val & readl(host->addr + reg), host->addr + reg); } @@ -253,10 +224,10 @@ static void sh_mmcif_sync_reset(struct sh_mmcif_host *host) { u32 tmp; - tmp = 0x010f0000 & sh_mmcif_readl(host, MMCIF_CE_CLK_CTRL); + tmp = 0x010f0000 & sh_mmcif_readl(host->addr, MMCIF_CE_CLK_CTRL); - sh_mmcif_writel(host, MMCIF_CE_VERSION, SOFT_RST_ON); - sh_mmcif_writel(host, MMCIF_CE_VERSION, SOFT_RST_OFF); + sh_mmcif_writel(host->addr, MMCIF_CE_VERSION, SOFT_RST_ON); + sh_mmcif_writel(host->addr, MMCIF_CE_VERSION, SOFT_RST_OFF); sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, tmp | SRSPTO_256 | SRBSYTO_29 | SRWDTO_29 | SCCSTO_29); /* byte swap on */ @@ -271,12 +242,10 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host) host->sd_error = 0; host->wait_int = 0; - state1 = sh_mmcif_readl(host, MMCIF_CE_HOST_STS1); - state2 = sh_mmcif_readl(host, MMCIF_CE_HOST_STS2); - pr_debug("%s: ERR HOST_STS1 = %08x\n", \ - DRIVER_NAME, sh_mmcif_readl(host, MMCIF_CE_HOST_STS1)); - pr_debug("%s: ERR HOST_STS2 = %08x\n", \ - DRIVER_NAME, sh_mmcif_readl(host, MMCIF_CE_HOST_STS2)); + state1 = sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1); + state2 = sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS2); + pr_debug("%s: ERR HOST_STS1 = %08x\n", DRIVER_NAME, state1); + pr_debug("%s: ERR HOST_STS2 = %08x\n", DRIVER_NAME, state2); if (state1 & STS1_CMDSEQ) { sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, CMD_CTRL_BREAK); @@ -288,7 +257,7 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host) "command sequence timeout err\n"); return -EIO; } - if (!(sh_mmcif_readl(host, MMCIF_CE_HOST_STS1) + if (!(sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1) & STS1_CMDSEQ)) break; mdelay(1); @@ -330,9 +299,9 @@ static int sh_mmcif_single_read(struct sh_mmcif_host *host, host->wait_int = 0; blocksize = (BLOCK_SIZE_MASK & - sh_mmcif_readl(host, MMCIF_CE_BLOCK_SET)) + 3; + sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3; for (i = 0; i < blocksize / 4; i++) - *p++ = sh_mmcif_readl(host, MMCIF_CE_DATA); + *p++ = sh_mmcif_readl(host->addr, MMCIF_CE_DATA); /* buffer read end */ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFRE); @@ -353,7 +322,8 @@ static int sh_mmcif_multi_read(struct sh_mmcif_host *host, long time; u32 blocksize, i, j, sec, *p; - blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host, MMCIF_CE_BLOCK_SET); + blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host->addr, + MMCIF_CE_BLOCK_SET); for (j = 0; j < data->sg_len; j++) { p = sg_virt(data->sg); host->wait_int = 0; @@ -370,7 +340,8 @@ static int sh_mmcif_multi_read(struct sh_mmcif_host *host, host->wait_int = 0; for (i = 0; i < blocksize / 4; i++) - *p++ = sh_mmcif_readl(host, MMCIF_CE_DATA); + *p++ = sh_mmcif_readl(host->addr, + MMCIF_CE_DATA); } if (j < data->sg_len - 1) data->sg++; @@ -397,9 +368,9 @@ static int sh_mmcif_single_write(struct sh_mmcif_host *host, host->wait_int = 0; blocksize = (BLOCK_SIZE_MASK & - sh_mmcif_readl(host, MMCIF_CE_BLOCK_SET)) + 3; + sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3; for (i = 0; i < blocksize / 4; i++) - sh_mmcif_writel(host, MMCIF_CE_DATA, *p++); + sh_mmcif_writel(host->addr, MMCIF_CE_DATA, *p++); /* buffer write end */ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MDTRANE); @@ -421,7 +392,8 @@ static int sh_mmcif_multi_write(struct sh_mmcif_host *host, long time; u32 i, sec, j, blocksize, *p; - blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host, MMCIF_CE_BLOCK_SET); + blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host->addr, + MMCIF_CE_BLOCK_SET); for (j = 0; j < data->sg_len; j++) { p = sg_virt(data->sg); @@ -439,7 +411,8 @@ static int sh_mmcif_multi_write(struct sh_mmcif_host *host, host->wait_int = 0; for (i = 0; i < blocksize / 4; i++) - sh_mmcif_writel(host, MMCIF_CE_DATA, *p++); + sh_mmcif_writel(host->addr, + MMCIF_CE_DATA, *p++); } if (j < data->sg_len - 1) data->sg++; @@ -451,18 +424,18 @@ static void sh_mmcif_get_response(struct sh_mmcif_host *host, struct mmc_command *cmd) { if (cmd->flags & MMC_RSP_136) { - cmd->resp[0] = sh_mmcif_readl(host, MMCIF_CE_RESP3); - cmd->resp[1] = sh_mmcif_readl(host, MMCIF_CE_RESP2); - cmd->resp[2] = sh_mmcif_readl(host, MMCIF_CE_RESP1); - cmd->resp[3] = sh_mmcif_readl(host, MMCIF_CE_RESP0); + cmd->resp[0] = sh_mmcif_readl(host->addr, MMCIF_CE_RESP3); + cmd->resp[1] = sh_mmcif_readl(host->addr, MMCIF_CE_RESP2); + cmd->resp[2] = sh_mmcif_readl(host->addr, MMCIF_CE_RESP1); + cmd->resp[3] = sh_mmcif_readl(host->addr, MMCIF_CE_RESP0); } else - cmd->resp[0] = sh_mmcif_readl(host, MMCIF_CE_RESP0); + cmd->resp[0] = sh_mmcif_readl(host->addr, MMCIF_CE_RESP0); } static void sh_mmcif_get_cmd12response(struct sh_mmcif_host *host, struct mmc_command *cmd) { - cmd->resp[0] = sh_mmcif_readl(host, MMCIF_CE_RESP_CMD12); + cmd->resp[0] = sh_mmcif_readl(host->addr, MMCIF_CE_RESP_CMD12); } static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host, @@ -596,18 +569,19 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host, MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO; if (host->data) { - sh_mmcif_writel(host, MMCIF_CE_BLOCK_SET, 0); - sh_mmcif_writel(host, MMCIF_CE_BLOCK_SET, mrq->data->blksz); + sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, 0); + sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, + mrq->data->blksz); } opc = sh_mmcif_set_cmd(host, mrq, cmd, opc); - sh_mmcif_writel(host, MMCIF_CE_INT, 0xD80430C0); - sh_mmcif_writel(host, MMCIF_CE_INT_MASK, mask); + sh_mmcif_writel(host->addr, MMCIF_CE_INT, 0xD80430C0); + sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, mask); /* set arg */ - sh_mmcif_writel(host, MMCIF_CE_ARG, cmd->arg); + sh_mmcif_writel(host->addr, MMCIF_CE_ARG, cmd->arg); host->wait_int = 0; /* set cmd */ - sh_mmcif_writel(host, MMCIF_CE_CMD_SET, opc); + sh_mmcif_writel(host->addr, MMCIF_CE_CMD_SET, opc); time = wait_event_interruptible_timeout(host->intr_wait, host->wait_int == 1 || host->sd_error == 1, host->timeout); @@ -752,43 +726,44 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) u32 state = 0; int err = 0; - state = sh_mmcif_readl(host, MMCIF_CE_INT); + state = sh_mmcif_readl(host->addr, MMCIF_CE_INT); if (state & INT_RBSYE) { - sh_mmcif_writel(host, MMCIF_CE_INT, ~(INT_RBSYE | INT_CRSPE)); + sh_mmcif_writel(host->addr, MMCIF_CE_INT, + ~(INT_RBSYE | INT_CRSPE)); sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MRBSYE); } else if (state & INT_CRSPE) { - sh_mmcif_writel(host, MMCIF_CE_INT, ~INT_CRSPE); + sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_CRSPE); sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCRSPE); } else if (state & INT_BUFREN) { - sh_mmcif_writel(host, MMCIF_CE_INT, ~INT_BUFREN); + sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_BUFREN); sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); } else if (state & INT_BUFWEN) { - sh_mmcif_writel(host, MMCIF_CE_INT, ~INT_BUFWEN); + sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_BUFWEN); sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); } else if (state & INT_CMD12DRE) { - sh_mmcif_writel(host, MMCIF_CE_INT, + sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~(INT_CMD12DRE | INT_CMD12RBE | INT_CMD12CRE | INT_BUFRE)); sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12DRE); } else if (state & INT_BUFRE) { - sh_mmcif_writel(host, MMCIF_CE_INT, ~INT_BUFRE); + sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_BUFRE); sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFRE); } else if (state & INT_DTRANE) { - sh_mmcif_writel(host, MMCIF_CE_INT, ~INT_DTRANE); + sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_DTRANE); sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MDTRANE); } else if (state & INT_CMD12RBE) { - sh_mmcif_writel(host, MMCIF_CE_INT, + sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~(INT_CMD12RBE | INT_CMD12CRE)); sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE); } else if (state & INT_ERR_STS) { /* err interrupts */ - sh_mmcif_writel(host, MMCIF_CE_INT, ~state); + sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state); sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state); err = 1; } else { pr_debug("%s: Not support int\n", DRIVER_NAME); - sh_mmcif_writel(host, MMCIF_CE_INT, ~state); + sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state); sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state); err = 1; } @@ -894,12 +869,12 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev) goto clean_up2; } - sh_mmcif_writel(host, MMCIF_CE_INT_MASK, MASK_ALL); + sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); sh_mmcif_detect(host->mmc); pr_info("%s: driver version %s\n", DRIVER_NAME, DRIVER_VERSION); pr_debug("%s: chip ver H'%04x\n", DRIVER_NAME, - sh_mmcif_readl(host, MMCIF_CE_VERSION) & 0x0000ffff); + sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff); return ret; clean_up2: @@ -917,7 +892,7 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev) struct sh_mmcif_host *host = platform_get_drvdata(pdev); int irq[2]; - sh_mmcif_writel(host, MMCIF_CE_INT_MASK, MASK_ALL); + sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); irq[0] = platform_get_irq(pdev, 0); irq[1] = platform_get_irq(pdev, 1); diff --git a/include/linux/mmc/sh_mmcif.h b/include/linux/mmc/sh_mmcif.h index aafe832f18aa..e079c6beeb98 100644 --- a/include/linux/mmc/sh_mmcif.h +++ b/include/linux/mmc/sh_mmcif.h @@ -14,6 +14,9 @@ #ifndef __SH_MMCIF_H__ #define __SH_MMCIF_H__ +#include +#include + /* * MMCIF : CE_CLK_CTRL [19:16] * 1000 : Peripheral clock / 512 @@ -36,4 +39,33 @@ struct sh_mmcif_plat_data { u32 ocr; }; +#define MMCIF_CE_CMD_SET 0x00000000 +#define MMCIF_CE_ARG 0x00000008 +#define MMCIF_CE_ARG_CMD12 0x0000000C +#define MMCIF_CE_CMD_CTRL 0x00000010 +#define MMCIF_CE_BLOCK_SET 0x00000014 +#define MMCIF_CE_CLK_CTRL 0x00000018 +#define MMCIF_CE_BUF_ACC 0x0000001C +#define MMCIF_CE_RESP3 0x00000020 +#define MMCIF_CE_RESP2 0x00000024 +#define MMCIF_CE_RESP1 0x00000028 +#define MMCIF_CE_RESP0 0x0000002C +#define MMCIF_CE_RESP_CMD12 0x00000030 +#define MMCIF_CE_DATA 0x00000034 +#define MMCIF_CE_INT 0x00000040 +#define MMCIF_CE_INT_MASK 0x00000044 +#define MMCIF_CE_HOST_STS1 0x00000048 +#define MMCIF_CE_HOST_STS2 0x0000004C +#define MMCIF_CE_VERSION 0x0000007C + +extern inline u32 sh_mmcif_readl(void __iomem *addr, int reg) +{ + return readl(addr + reg); +} + +extern inline void sh_mmcif_writel(void __iomem *addr, int reg, u32 val) +{ + writel(val, addr + reg); +} + #endif /* __SH_MMCIF_H__ */ -- cgit v1.2.3 From bc284f94f84c3d76e49c6f3df9028c503f9589d9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 31 May 2010 05:47:32 -0700 Subject: greth: Fix build after OF device conversions. Signed-off-by: David S. Miller --- drivers/net/greth.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/greth.c b/drivers/net/greth.c index f37a4c143ddd..3a029d02c2b4 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -1607,14 +1607,13 @@ static struct of_device_id greth_of_match[] = { MODULE_DEVICE_TABLE(of, greth_of_match); static struct of_platform_driver greth_of_driver = { - .name = "grlib-greth", - .match_table = greth_of_match, + .driver = { + .name = "grlib-greth", + .owner = THIS_MODULE, + .of_match_table = greth_of_match, + }, .probe = greth_of_probe, .remove = __devexit_p(greth_of_remove), - .driver = { - .owner = THIS_MODULE, - .name = "grlib-greth", - }, }; static int __init greth_init(void) -- cgit v1.2.3 From 829ab5b52b7ee1d92b2373662b82b6f38cae7166 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 31 May 2010 11:57:24 -0700 Subject: Input: s3c2410_ts - fix build error due to ADC Kconfig rename The name of the Kconfig symbol for the ADC has changed as a result of application to more SoCs but the select statement has not been updated, causing linker failures as the ADC core has not been built. Signed-off-by: Mark Brown Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 6703c6b9800a..3b9d5e2105d7 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -156,7 +156,7 @@ config TOUCHSCREEN_FUJITSU config TOUCHSCREEN_S3C2410 tristate "Samsung S3C2410/generic touchscreen input driver" depends on ARCH_S3C2410 || SAMSUNG_DEV_TS - select S3C24XX_ADC + select S3C_ADC help Say Y here if you have the s3c2410 touchscreen. -- cgit v1.2.3 From fbf89f25fc4dc68ba0857aca87e70fa5d2592d81 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 31 May 2010 11:57:24 -0700 Subject: Input: s3c2410_ts - tone down logging The S3C touchscreen driver is logging at LOG_INFO on every stylus up event which spams the console needlessly. Reduce the priority of the message to debug level for some peace and quiet. Signed-off-by: Mark Brown Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/s3c2410_ts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c index ac5d0f9b0cb1..6085d12fd561 100644 --- a/drivers/input/touchscreen/s3c2410_ts.c +++ b/drivers/input/touchscreen/s3c2410_ts.c @@ -173,7 +173,7 @@ static irqreturn_t stylus_irq(int irq, void *dev_id) if (down) s3c_adc_start(ts.client, 0, 1 << ts.shift); else - dev_info(ts.dev, "%s: count=%d\n", __func__, ts.count); + dev_dbg(ts.dev, "%s: count=%d\n", __func__, ts.count); if (ts.features & FEAT_PEN_IRQ) { /* Clear pen down/up interrupt */ -- cgit v1.2.3 From 7e71f8a59e1c9adbbc3b737b4b818c8aa4169d0e Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 28 May 2010 11:21:54 +0200 Subject: drm/vmwgfx: Assume larger framebuffer max size. Signed-off-by: Jakob Bornecrantz Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index bbc7c4c30bc7..642bcd7a1500 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -765,8 +765,9 @@ int vmw_kms_init(struct vmw_private *dev_priv) dev->mode_config.funcs = &vmw_kms_funcs; dev->mode_config.min_width = 1; dev->mode_config.min_height = 1; - dev->mode_config.max_width = dev_priv->fb_max_width; - dev->mode_config.max_height = dev_priv->fb_max_height; + /* assumed largest fb size */ + dev->mode_config.max_width = 8192; + dev->mode_config.max_height = 8192; ret = vmw_kms_init_legacy_display_system(dev_priv); -- cgit v1.2.3 From 6a591a96d7315fbe81acc33e20bab4956d1f02a3 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 28 May 2010 11:21:55 +0200 Subject: drm/vmwgfx: Fix single framebuffer detection. V2: Fix a typo. Signed-off-by: Jakob Bornecrantz Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 90891593bf6c..a348fec22137 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -130,6 +130,7 @@ static int vmw_ldu_del_active(struct vmw_private *vmw_priv, if (list_empty(&ldu->active)) return 0; + /* Must init otherwise list_empty(&ldu->active) will not work. */ list_del_init(&ldu->active); if (--(ld->num_active) == 0) { BUG_ON(!ld->fb); @@ -208,6 +209,8 @@ static int vmw_ldu_crtc_set_config(struct drm_mode_set *set) /* ldu only supports one fb active at the time */ if (dev_priv->ldu_priv->fb && vfb && + !(dev_priv->ldu_priv->num_active == 1 && + !list_empty(&ldu->active)) && dev_priv->ldu_priv->fb != vfb) { DRM_ERROR("Multiple framebuffers not supported\n"); return -EINVAL; -- cgit v1.2.3 From 04e9e94dba3e564ce810cedab88e957dfd681b4a Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 28 May 2010 11:21:56 +0200 Subject: drm/vmwgfx: Make sure to unpin old and pin new framebuffer. Signed-off-by: Jakob Bornecrantz Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index a348fec22137..e1b3cf539b4a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -150,6 +150,15 @@ static int vmw_ldu_add_active(struct vmw_private *vmw_priv, struct vmw_legacy_display_unit *entry; struct list_head *at; + BUG_ON(!ld->num_active && ld->fb); + if (vfb != ld->fb) { + if (ld->fb && ld->fb->unpin) + ld->fb->unpin(ld->fb); + if (vfb->pin) + vfb->pin(vfb); + ld->fb = vfb; + } + if (!list_empty(&ldu->active)) return 0; @@ -162,12 +171,8 @@ static int vmw_ldu_add_active(struct vmw_private *vmw_priv, } list_add(&ldu->active, at); - if (ld->num_active++ == 0) { - BUG_ON(ld->fb); - if (vfb->pin) - vfb->pin(vfb); - ld->fb = vfb; - } + + ld->num_active++; return 0; } -- cgit v1.2.3 From 1925d4565888eb313cc923372da6a08bbfb3a859 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 28 May 2010 11:21:57 +0200 Subject: drm/vmwgfx: Add kernel throttling support. Bump minor. The throttle_us member in the execbuf argument is now honored. If the member is 0, no waiting for lag will occur, which guarantees backwards compatibility with well-behaved clients. Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/Makefile | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 27 ++++- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 9 ++ drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 173 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | 5 +- drivers/gpu/drm/vmwgfx/vmwgfx_irq.c | 17 +++- 6 files changed, 227 insertions(+), 6 deletions(-) create mode 100644 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/Makefile b/drivers/gpu/drm/vmwgfx/Makefile index 1a3cb6816d1c..4505e17df3f5 100644 --- a/drivers/gpu/drm/vmwgfx/Makefile +++ b/drivers/gpu/drm/vmwgfx/Makefile @@ -4,6 +4,6 @@ ccflags-y := -Iinclude/drm vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \ vmwgfx_fb.o vmwgfx_ioctl.o vmwgfx_resource.o vmwgfx_buffer.o \ vmwgfx_fifo.o vmwgfx_irq.o vmwgfx_ldu.o vmwgfx_ttm_glue.o \ - vmwgfx_overlay.o + vmwgfx_overlay.o vmwgfx_fence.o obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 356dc935ec13..9a0a82b41c3e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -41,7 +41,7 @@ #define VMWGFX_DRIVER_DATE "20100209" #define VMWGFX_DRIVER_MAJOR 1 -#define VMWGFX_DRIVER_MINOR 0 +#define VMWGFX_DRIVER_MINOR 1 #define VMWGFX_DRIVER_PATCHLEVEL 0 #define VMWGFX_FILE_PAGE_OFFSET 0x00100000 #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) @@ -102,6 +102,13 @@ struct vmw_surface { struct vmw_cursor_snooper snooper; }; +struct vmw_fence_queue { + struct list_head head; + struct timespec lag; + struct timespec lag_time; + spinlock_t lock; +}; + struct vmw_fifo_state { unsigned long reserved_size; __le32 *dynamic_buffer; @@ -115,6 +122,7 @@ struct vmw_fifo_state { uint32_t capabilities; struct mutex fifo_mutex; struct rw_semaphore rwsem; + struct vmw_fence_queue fence_queue; }; struct vmw_relocation { @@ -441,6 +449,23 @@ extern int vmw_fallback_wait(struct vmw_private *dev_priv, uint32_t sequence, bool interruptible, unsigned long timeout); +extern void vmw_update_sequence(struct vmw_private *dev_priv, + struct vmw_fifo_state *fifo_state); + + +/** + * Rudimentary fence objects currently used only for throttling - + * vmwgfx_fence.c + */ + +extern void vmw_fence_queue_init(struct vmw_fence_queue *queue); +extern void vmw_fence_queue_takedown(struct vmw_fence_queue *queue); +extern int vmw_fence_push(struct vmw_fence_queue *queue, + uint32_t sequence); +extern int vmw_fence_pull(struct vmw_fence_queue *queue, + uint32_t signaled_sequence); +extern int vmw_wait_lag(struct vmw_private *dev_priv, + struct vmw_fence_queue *queue, uint32_t us); /** * Kernel framebuffer - vmwgfx_fb.c diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index dbd36b8910cf..bdd67cf83315 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -669,6 +669,15 @@ int vmw_execbuf_ioctl(struct drm_device *dev, void *data, goto out_err; vmw_apply_relocations(sw_context); + + if (arg->throttle_us) { + ret = vmw_wait_lag(dev_priv, &dev_priv->fifo.fence_queue, + arg->throttle_us); + + if (unlikely(ret != 0)) + goto out_err; + } + vmw_fifo_commit(dev_priv, arg->command_size); ret = vmw_fifo_send_fence(dev_priv, &sequence); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c new file mode 100644 index 000000000000..61eacc1b5ca3 --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c @@ -0,0 +1,173 @@ +/************************************************************************** + * + * Copyright (C) 2010 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "vmwgfx_drv.h" + +struct vmw_fence { + struct list_head head; + uint32_t sequence; + struct timespec submitted; +}; + +void vmw_fence_queue_init(struct vmw_fence_queue *queue) +{ + INIT_LIST_HEAD(&queue->head); + queue->lag = ns_to_timespec(0); + getrawmonotonic(&queue->lag_time); + spin_lock_init(&queue->lock); +} + +void vmw_fence_queue_takedown(struct vmw_fence_queue *queue) +{ + struct vmw_fence *fence, *next; + + spin_lock(&queue->lock); + list_for_each_entry_safe(fence, next, &queue->head, head) { + kfree(fence); + } + spin_unlock(&queue->lock); +} + +int vmw_fence_push(struct vmw_fence_queue *queue, + uint32_t sequence) +{ + struct vmw_fence *fence = kmalloc(sizeof(*fence), GFP_KERNEL); + + if (unlikely(!fence)) + return -ENOMEM; + + fence->sequence = sequence; + getrawmonotonic(&fence->submitted); + spin_lock(&queue->lock); + list_add_tail(&fence->head, &queue->head); + spin_unlock(&queue->lock); + + return 0; +} + +int vmw_fence_pull(struct vmw_fence_queue *queue, + uint32_t signaled_sequence) +{ + struct vmw_fence *fence, *next; + struct timespec now; + bool updated = false; + + spin_lock(&queue->lock); + getrawmonotonic(&now); + + if (list_empty(&queue->head)) { + queue->lag = ns_to_timespec(0); + queue->lag_time = now; + updated = true; + goto out_unlock; + } + + list_for_each_entry_safe(fence, next, &queue->head, head) { + if (signaled_sequence - fence->sequence > (1 << 30)) + continue; + + queue->lag = timespec_sub(now, fence->submitted); + queue->lag_time = now; + updated = true; + list_del(&fence->head); + kfree(fence); + } + +out_unlock: + spin_unlock(&queue->lock); + + return (updated) ? 0 : -EBUSY; +} + +static struct timespec vmw_timespec_add(struct timespec t1, + struct timespec t2) +{ + t1.tv_sec += t2.tv_sec; + t1.tv_nsec += t2.tv_nsec; + if (t1.tv_nsec >= 1000000000L) { + t1.tv_sec += 1; + t1.tv_nsec -= 1000000000L; + } + + return t1; +} + +static struct timespec vmw_fifo_lag(struct vmw_fence_queue *queue) +{ + struct timespec now; + + spin_lock(&queue->lock); + getrawmonotonic(&now); + queue->lag = vmw_timespec_add(queue->lag, + timespec_sub(now, queue->lag_time)); + queue->lag_time = now; + spin_unlock(&queue->lock); + return queue->lag; +} + + +static bool vmw_lag_lt(struct vmw_fence_queue *queue, + uint32_t us) +{ + struct timespec lag, cond; + + cond = ns_to_timespec((s64) us * 1000); + lag = vmw_fifo_lag(queue); + return (timespec_compare(&lag, &cond) < 1); +} + +int vmw_wait_lag(struct vmw_private *dev_priv, + struct vmw_fence_queue *queue, uint32_t us) +{ + struct vmw_fence *fence; + uint32_t sequence; + int ret; + + while (!vmw_lag_lt(queue, us)) { + spin_lock(&queue->lock); + if (list_empty(&queue->head)) + sequence = atomic_read(&dev_priv->fence_seq); + else { + fence = list_first_entry(&queue->head, + struct vmw_fence, head); + sequence = fence->sequence; + } + spin_unlock(&queue->lock); + + ret = vmw_wait_fence(dev_priv, false, sequence, true, + 3*HZ); + + if (unlikely(ret != 0)) + return ret; + + (void) vmw_fence_pull(queue, sequence); + } + return 0; +} + + diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c index 39d43a01d846..a8e5445f94ec 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c @@ -120,7 +120,7 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) atomic_set(&dev_priv->fence_seq, dev_priv->last_read_sequence); iowrite32(dev_priv->last_read_sequence, fifo_mem + SVGA_FIFO_FENCE); - + vmw_fence_queue_init(&fifo->fence_queue); return vmw_fifo_send_fence(dev_priv, &dummy); out_err: vfree(fifo->static_buffer); @@ -159,6 +159,7 @@ void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) dev_priv->enable_state); mutex_unlock(&dev_priv->hw_mutex); + vmw_fence_queue_takedown(&fifo->fence_queue); if (likely(fifo->last_buffer != NULL)) { vfree(fifo->last_buffer); @@ -484,6 +485,8 @@ int vmw_fifo_send_fence(struct vmw_private *dev_priv, uint32_t *sequence) fifo_state->last_buffer_add = true; vmw_fifo_commit(dev_priv, bytes); fifo_state->last_buffer_add = false; + (void) vmw_fence_push(&fifo_state->fence_queue, *sequence); + vmw_update_sequence(dev_priv, fifo_state); out_err: return ret; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c index 4d7cb5393860..e92298a6a383 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c @@ -64,22 +64,33 @@ static bool vmw_fifo_idle(struct vmw_private *dev_priv, uint32_t sequence) return (busy == 0); } +void vmw_update_sequence(struct vmw_private *dev_priv, + struct vmw_fifo_state *fifo_state) +{ + __le32 __iomem *fifo_mem = dev_priv->mmio_virt; + + uint32_t sequence = ioread32(fifo_mem + SVGA_FIFO_FENCE); + + if (dev_priv->last_read_sequence != sequence) { + dev_priv->last_read_sequence = sequence; + vmw_fence_pull(&fifo_state->fence_queue, sequence); + } +} bool vmw_fence_signaled(struct vmw_private *dev_priv, uint32_t sequence) { - __le32 __iomem *fifo_mem = dev_priv->mmio_virt; struct vmw_fifo_state *fifo_state; bool ret; if (likely(dev_priv->last_read_sequence - sequence < VMW_FENCE_WRAP)) return true; - dev_priv->last_read_sequence = ioread32(fifo_mem + SVGA_FIFO_FENCE); + fifo_state = &dev_priv->fifo; + vmw_update_sequence(dev_priv, fifo_state); if (likely(dev_priv->last_read_sequence - sequence < VMW_FENCE_WRAP)) return true; - fifo_state = &dev_priv->fifo; if (!(fifo_state->capabilities & SVGA_FIFO_CAP_FENCE) && vmw_fifo_idle(dev_priv, sequence)) return true; -- cgit v1.2.3 From 1ae1ddd5e99bbc067414ff571ac18d4312b4c8cf Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 28 May 2010 11:21:58 +0200 Subject: drm/vmwgfx: Get connector status from detection function. Also make sure the ldu::active member is properly initialized. Part of fix by Michel Daenzer . Signed-off-by: Jakob Bornecrantz Signed-off-by: Michel Daenzer Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index e1b3cf539b4a..fefef9012c4b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -456,13 +456,11 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) encoder = &ldu->base.encoder; connector = &ldu->base.connector; + INIT_LIST_HEAD(&ldu->active); + drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, DRM_MODE_CONNECTOR_LVDS); - /* Initial status */ - if (unit == 0) - connector->status = connector_status_connected; - else - connector->status = connector_status_disconnected; + connector->status = vmw_ldu_connector_detect(connector); drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs, DRM_MODE_ENCODER_LVDS); @@ -470,8 +468,6 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) encoder->possible_crtcs = (1 << unit); encoder->possible_clones = 0; - INIT_LIST_HEAD(&ldu->active); - drm_crtc_init(dev, crtc, &vmw_legacy_crtc_funcs); drm_connector_attach_property(connector, -- cgit v1.2.3 From d7e1958dbe4a7b81d4cab5fab545a068501b967e Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 28 May 2010 11:21:59 +0200 Subject: drm/vmwgfx: Support older hardware. V2: Fix a couple of typos. Signed-off-by: Jakob Bornecrantz Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 9 ++++ drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 5 +++ drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 81 +++++++++++++----------------------- drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | 18 ++++++++ drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 72 ++++++++++++++------------------ drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 70 +++++++++++++++++++++++++------ 6 files changed, 148 insertions(+), 107 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 0c9c0811f42d..bdd87dc9e7b1 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -318,6 +318,15 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) goto out_err3; } + /* Need mmio memory to check for fifo pitchlock cap. */ + if (!(dev_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) && + !(dev_priv->capabilities & SVGA_CAP_PITCHLOCK) && + !vmw_fifo_have_pitchlock(dev_priv)) { + ret = -ENOSYS; + DRM_ERROR("Hardware has no pitchlock\n"); + goto out_err4; + } + dev_priv->tdev = ttm_object_device_init (dev_priv->mem_global_ref.object, 12); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 9a0a82b41c3e..1341adef408d 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -187,6 +187,7 @@ struct vmw_private { uint32_t vga_red_mask; uint32_t vga_blue_mask; uint32_t vga_green_mask; + uint32_t vga_pitchlock; /* * Framebuffer info. @@ -401,6 +402,7 @@ extern int vmw_fifo_send_fence(struct vmw_private *dev_priv, extern void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason); extern int vmw_fifo_mmap(struct file *filp, struct vm_area_struct *vma); extern bool vmw_fifo_have_3d(struct vmw_private *dev_priv); +extern bool vmw_fifo_have_pitchlock(struct vmw_private *dev_priv); /** * TTM glue - vmwgfx_ttm_glue.c @@ -491,6 +493,9 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf, struct ttm_object_file *tfile, struct ttm_buffer_object *bo, SVGA3dCmdHeader *header); +void vmw_kms_write_svga(struct vmw_private *vmw_priv, + unsigned width, unsigned height, unsigned pitch, + unsigned bbp, unsigned depth); /** * Overlay control - vmwgfx_overlay.c diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 7421aaad8d09..fb66e62b8e2c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c @@ -132,16 +132,14 @@ static int vmw_fb_check_var(struct fb_var_screeninfo *var, return -EINVAL; } - /* without multimon its hard to resize */ - if (!(vmw_priv->capabilities & SVGA_CAP_MULTIMON) && - (var->xres != par->max_width || - var->yres != par->max_height)) { - DRM_ERROR("Tried to resize, but we don't have multimon\n"); + if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) && + (var->xoffset != 0 || var->yoffset != 0)) { + DRM_ERROR("Can not handle panning without display topology\n"); return -EINVAL; } - if (var->xres > par->max_width || - var->yres > par->max_height) { + if ((var->xoffset + var->xres) > par->max_width || + (var->yoffset + var->yres) > par->max_height) { DRM_ERROR("Requested geom can not fit in framebuffer\n"); return -EINVAL; } @@ -154,8 +152,8 @@ static int vmw_fb_set_par(struct fb_info *info) struct vmw_fb_par *par = info->par; struct vmw_private *vmw_priv = par->vmw_priv; - if (vmw_priv->capabilities & SVGA_CAP_MULTIMON) { - vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1); + if (vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) { + vmw_write(vmw_priv, SVGA_REG_ENABLE, 0); vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0); vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true); vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, 0); @@ -164,18 +162,11 @@ static int vmw_fb_set_par(struct fb_info *info) vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, 0); vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); - vmw_write(vmw_priv, SVGA_REG_ENABLE, 1); - vmw_write(vmw_priv, SVGA_REG_WIDTH, par->max_width); - vmw_write(vmw_priv, SVGA_REG_HEIGHT, par->max_height); - vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, par->bpp); - vmw_write(vmw_priv, SVGA_REG_DEPTH, par->depth); - vmw_write(vmw_priv, SVGA_REG_RED_MASK, 0x00ff0000); - vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, 0x0000ff00); - vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, 0x000000ff); + vmw_kms_write_svga(vmw_priv, info->var.xres, info->var.yres, + info->fix.line_length, + par->bpp, par->depth); /* TODO check if pitch and offset changes */ - - vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1); vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0); vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true); vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, info->var.xoffset); @@ -183,13 +174,22 @@ static int vmw_fb_set_par(struct fb_info *info) vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, info->var.xres); vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, info->var.yres); vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); + vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1); + vmw_write(vmw_priv, SVGA_REG_ENABLE, 1); } else { - vmw_write(vmw_priv, SVGA_REG_WIDTH, info->var.xres); - vmw_write(vmw_priv, SVGA_REG_HEIGHT, info->var.yres); + vmw_write(vmw_priv, SVGA_REG_ENABLE, 0); + vmw_kms_write_svga(vmw_priv, info->var.xres, info->var.yres, + info->fix.line_length, + par->bpp, par->depth); + vmw_write(vmw_priv, SVGA_REG_ENABLE, 1); - /* TODO check if pitch and offset changes */ } + /* This is really helpful since if this fails the user + * can probably not see anything on the screen. + */ + WARN_ON(vmw_read(vmw_priv, SVGA_REG_FB_OFFSET) != 0); + return 0; } @@ -416,48 +416,23 @@ int vmw_fb_init(struct vmw_private *vmw_priv) unsigned fb_bbp, fb_depth, fb_offset, fb_pitch, fb_size; int ret; + /* XXX These shouldn't be hardcoded. */ initial_width = 800; initial_height = 600; fb_bbp = 32; fb_depth = 24; - if (vmw_priv->capabilities & SVGA_CAP_MULTIMON) { - fb_width = min(vmw_priv->fb_max_width, (unsigned)2048); - fb_height = min(vmw_priv->fb_max_height, (unsigned)2048); - } else { - fb_width = min(vmw_priv->fb_max_width, initial_width); - fb_height = min(vmw_priv->fb_max_height, initial_height); - } + /* XXX As shouldn't these be as well. */ + fb_width = min(vmw_priv->fb_max_width, (unsigned)2048); + fb_height = min(vmw_priv->fb_max_height, (unsigned)2048); initial_width = min(fb_width, initial_width); initial_height = min(fb_height, initial_height); - vmw_write(vmw_priv, SVGA_REG_WIDTH, fb_width); - vmw_write(vmw_priv, SVGA_REG_HEIGHT, fb_height); - vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, fb_bbp); - vmw_write(vmw_priv, SVGA_REG_DEPTH, fb_depth); - vmw_write(vmw_priv, SVGA_REG_RED_MASK, 0x00ff0000); - vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, 0x0000ff00); - vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, 0x000000ff); - - fb_size = vmw_read(vmw_priv, SVGA_REG_FB_SIZE); + fb_pitch = fb_width * fb_bbp / 8; + fb_size = fb_pitch * fb_height; fb_offset = vmw_read(vmw_priv, SVGA_REG_FB_OFFSET); - fb_pitch = vmw_read(vmw_priv, SVGA_REG_BYTES_PER_LINE); - - DRM_DEBUG("width %u\n", vmw_read(vmw_priv, SVGA_REG_MAX_WIDTH)); - DRM_DEBUG("height %u\n", vmw_read(vmw_priv, SVGA_REG_MAX_HEIGHT)); - DRM_DEBUG("width %u\n", vmw_read(vmw_priv, SVGA_REG_WIDTH)); - DRM_DEBUG("height %u\n", vmw_read(vmw_priv, SVGA_REG_HEIGHT)); - DRM_DEBUG("bpp %u\n", vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL)); - DRM_DEBUG("depth %u\n", vmw_read(vmw_priv, SVGA_REG_DEPTH)); - DRM_DEBUG("bpl %u\n", vmw_read(vmw_priv, SVGA_REG_BYTES_PER_LINE)); - DRM_DEBUG("r mask %08x\n", vmw_read(vmw_priv, SVGA_REG_RED_MASK)); - DRM_DEBUG("g mask %08x\n", vmw_read(vmw_priv, SVGA_REG_GREEN_MASK)); - DRM_DEBUG("b mask %08x\n", vmw_read(vmw_priv, SVGA_REG_BLUE_MASK)); - DRM_DEBUG("fb_offset 0x%08x\n", fb_offset); - DRM_DEBUG("fb_pitch %u\n", fb_pitch); - DRM_DEBUG("fb_size %u kiB\n", fb_size / 1024); info = framebuffer_alloc(sizeof(*par), device); if (!info) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c index a8e5445f94ec..e6a1eb7ea954 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c @@ -34,6 +34,9 @@ bool vmw_fifo_have_3d(struct vmw_private *dev_priv) __le32 __iomem *fifo_mem = dev_priv->mmio_virt; uint32_t fifo_min, hwversion; + if (!(dev_priv->capabilities & SVGA_CAP_EXTENDED_FIFO)) + return false; + fifo_min = ioread32(fifo_mem + SVGA_FIFO_MIN); if (fifo_min <= SVGA_FIFO_3D_HWVERSION * sizeof(unsigned int)) return false; @@ -48,6 +51,21 @@ bool vmw_fifo_have_3d(struct vmw_private *dev_priv) return true; } +bool vmw_fifo_have_pitchlock(struct vmw_private *dev_priv) +{ + __le32 __iomem *fifo_mem = dev_priv->mmio_virt; + uint32_t caps; + + if (!(dev_priv->capabilities & SVGA_CAP_EXTENDED_FIFO)) + return false; + + caps = ioread32(fifo_mem + SVGA_FIFO_CAPABILITIES); + if (caps & SVGA_FIFO_CAP_PITCHLOCK) + return true; + + return false; +} + int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) { __le32 __iomem *fifo_mem = dev_priv->mmio_virt; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 642bcd7a1500..c748207e9e1c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -596,31 +596,11 @@ static int vmw_framebuffer_dmabuf_pin(struct vmw_framebuffer *vfb) vmw_framebuffer_to_vfbd(&vfb->base); int ret; + vmw_overlay_pause_all(dev_priv); ret = vmw_dmabuf_to_start_of_vram(dev_priv, vfbd->buffer); - if (dev_priv->capabilities & SVGA_CAP_MULTIMON) { - vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1); - vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, 0); - vmw_write(dev_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true); - vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_X, 0); - vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_Y, 0); - vmw_write(dev_priv, SVGA_REG_DISPLAY_WIDTH, 0); - vmw_write(dev_priv, SVGA_REG_DISPLAY_HEIGHT, 0); - vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); - - vmw_write(dev_priv, SVGA_REG_ENABLE, 1); - vmw_write(dev_priv, SVGA_REG_WIDTH, vfb->base.width); - vmw_write(dev_priv, SVGA_REG_HEIGHT, vfb->base.height); - vmw_write(dev_priv, SVGA_REG_BITS_PER_PIXEL, vfb->base.bits_per_pixel); - vmw_write(dev_priv, SVGA_REG_DEPTH, vfb->base.depth); - vmw_write(dev_priv, SVGA_REG_RED_MASK, 0x00ff0000); - vmw_write(dev_priv, SVGA_REG_GREEN_MASK, 0x0000ff00); - vmw_write(dev_priv, SVGA_REG_BLUE_MASK, 0x000000ff); - } else - WARN_ON(true); - vmw_overlay_resume_all(dev_priv); return 0; @@ -668,7 +648,7 @@ int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv, /* XXX get the first 3 from the surface info */ vfbd->base.base.bits_per_pixel = 32; - vfbd->base.base.pitch = width * 32 / 4; + vfbd->base.base.pitch = width * vfbd->base.base.bits_per_pixel / 8; vfbd->base.base.depth = 24; vfbd->base.base.width = width; vfbd->base.base.height = height; @@ -827,24 +807,25 @@ out: return ret; } -int vmw_kms_save_vga(struct vmw_private *vmw_priv) +void vmw_kms_write_svga(struct vmw_private *vmw_priv, + unsigned width, unsigned height, unsigned pitch, + unsigned bbp, unsigned depth) { - /* - * setup a single multimon monitor with the size - * of 0x0, this stops the UI from resizing when we - * change the framebuffer size - */ - if (vmw_priv->capabilities & SVGA_CAP_MULTIMON) { - vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1); - vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0); - vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true); - vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, 0); - vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, 0); - vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, 0); - vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, 0); - vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); - } + if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK) + vmw_write(vmw_priv, SVGA_REG_PITCHLOCK, pitch); + else if (vmw_fifo_have_pitchlock(vmw_priv)) + iowrite32(pitch, vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK); + vmw_write(vmw_priv, SVGA_REG_WIDTH, width); + vmw_write(vmw_priv, SVGA_REG_HEIGHT, height); + vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, bbp); + vmw_write(vmw_priv, SVGA_REG_DEPTH, depth); + vmw_write(vmw_priv, SVGA_REG_RED_MASK, 0x00ff0000); + vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, 0x0000ff00); + vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, 0x000000ff); +} +int vmw_kms_save_vga(struct vmw_private *vmw_priv) +{ vmw_priv->vga_width = vmw_read(vmw_priv, SVGA_REG_WIDTH); vmw_priv->vga_height = vmw_read(vmw_priv, SVGA_REG_HEIGHT); vmw_priv->vga_bpp = vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL); @@ -853,6 +834,12 @@ int vmw_kms_save_vga(struct vmw_private *vmw_priv) vmw_priv->vga_red_mask = vmw_read(vmw_priv, SVGA_REG_RED_MASK); vmw_priv->vga_green_mask = vmw_read(vmw_priv, SVGA_REG_GREEN_MASK); vmw_priv->vga_blue_mask = vmw_read(vmw_priv, SVGA_REG_BLUE_MASK); + if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK) + vmw_priv->vga_pitchlock = + vmw_read(vmw_priv, SVGA_REG_PITCHLOCK); + else if (vmw_fifo_have_pitchlock(vmw_priv)) + vmw_priv->vga_pitchlock = + ioread32(vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK); return 0; } @@ -867,9 +854,12 @@ int vmw_kms_restore_vga(struct vmw_private *vmw_priv) vmw_write(vmw_priv, SVGA_REG_RED_MASK, vmw_priv->vga_red_mask); vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, vmw_priv->vga_green_mask); vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, vmw_priv->vga_blue_mask); - - /* TODO check for multimon */ - vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 0); + if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK) + vmw_write(vmw_priv, SVGA_REG_PITCHLOCK, + vmw_priv->vga_pitchlock); + else if (vmw_fifo_have_pitchlock(vmw_priv)) + iowrite32(vmw_priv->vga_pitchlock, + vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK); return 0; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index fefef9012c4b..8fde9bf8be41 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -38,6 +38,7 @@ struct vmw_legacy_display { struct list_head active; unsigned num_active; + unsigned last_num_active; struct vmw_framebuffer *fb; }; @@ -88,12 +89,37 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) { struct vmw_legacy_display *lds = dev_priv->ldu_priv; struct vmw_legacy_display_unit *entry; - struct drm_crtc *crtc; + struct drm_framebuffer *fb = NULL; + struct drm_crtc *crtc = NULL; int i = 0; - /* to stop the screen from changing size on resize */ - vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 0); - for (i = 0; i < lds->num_active; i++) { + /* If there is no display topology the host just assumes + * that the guest will set the same layout as the host. + */ + if (!(dev_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY)) { + int w = 0, h = 0; + list_for_each_entry(entry, &lds->active, active) { + crtc = &entry->base.crtc; + w = max(w, crtc->x + crtc->mode.hdisplay); + h = max(h, crtc->y + crtc->mode.vdisplay); + i++; + } + + if (crtc == NULL) + return 0; + fb = entry->base.crtc.fb; + + vmw_write(dev_priv, SVGA_REG_ENABLE, 0); + vmw_kms_write_svga(dev_priv, w, h, fb->pitch, + fb->bits_per_pixel, fb->depth); + vmw_write(dev_priv, SVGA_REG_ENABLE, 1); + + return 0; + } + + vmw_write(dev_priv, SVGA_REG_ENABLE, 0); + + for (i = 0; i < lds->last_num_active; i++) { vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, i); vmw_write(dev_priv, SVGA_REG_DISPLAY_IS_PRIMARY, !i); vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_X, 0); @@ -103,8 +129,14 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); } - /* Now set the mode */ - vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, lds->num_active); + if (!list_empty(&lds->active)) { + entry = list_entry(lds->active.next, typeof(*entry), active); + fb = entry->base.crtc.fb; + + vmw_kms_write_svga(dev_priv, fb->width, fb->height, fb->pitch, + fb->bits_per_pixel, fb->depth); + } + i = 0; list_for_each_entry(entry, &lds->active, active) { crtc = &entry->base.crtc; @@ -120,6 +152,14 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) i++; } + /* Make sure we always show something. */ + vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, i ? i : 1); + vmw_write(dev_priv, SVGA_REG_ENABLE, 1); + + BUG_ON(i != lds->num_active); + + lds->last_num_active = lds->num_active; + return 0; } @@ -491,18 +531,22 @@ int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) INIT_LIST_HEAD(&dev_priv->ldu_priv->active); dev_priv->ldu_priv->num_active = 0; + dev_priv->ldu_priv->last_num_active = 0; dev_priv->ldu_priv->fb = NULL; drm_mode_create_dirty_info_property(dev_priv->dev); vmw_ldu_init(dev_priv, 0); - vmw_ldu_init(dev_priv, 1); - vmw_ldu_init(dev_priv, 2); - vmw_ldu_init(dev_priv, 3); - vmw_ldu_init(dev_priv, 4); - vmw_ldu_init(dev_priv, 5); - vmw_ldu_init(dev_priv, 6); - vmw_ldu_init(dev_priv, 7); + /* for old hardware without multimon only enable one display */ + if (dev_priv->capabilities & SVGA_CAP_MULTIMON) { + vmw_ldu_init(dev_priv, 1); + vmw_ldu_init(dev_priv, 2); + vmw_ldu_init(dev_priv, 3); + vmw_ldu_init(dev_priv, 4); + vmw_ldu_init(dev_priv, 5); + vmw_ldu_init(dev_priv, 6); + vmw_ldu_init(dev_priv, 7); + } return 0; } -- cgit v1.2.3 From 22ee861c816689b2566290356d54e4a01c9b2e74 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 28 May 2010 11:22:00 +0200 Subject: drm/vmwgfx: Reserve first part of VRAM for framebuffer. The host may be touching this part of VRAM at modesetting, even if we never use it ourselves, since we blit screen updates from 3D surfaces. Make sure no DMA buffers are placed in this part of VRAM. V2: Fix an error check in vmw_surface_dmabuf_pin(). Signed-off-by: Thomas Hellstrom Signed-off-by: Jakob Bornecrantz Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 41 +++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index c748207e9e1c..250282fee9c8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -30,6 +30,8 @@ /* Might need a hrtimer here? */ #define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1) +static int vmw_surface_dmabuf_pin(struct vmw_framebuffer *vfb); +static int vmw_surface_dmabuf_unpin(struct vmw_framebuffer *vfb); void vmw_display_unit_cleanup(struct vmw_display_unit *du) { @@ -326,6 +328,7 @@ int vmw_framebuffer_create_handle(struct drm_framebuffer *fb, struct vmw_framebuffer_surface { struct vmw_framebuffer base; struct vmw_surface *surface; + struct vmw_dma_buffer *buffer; struct delayed_work d_work; struct mutex work_lock; bool present_fs; @@ -500,8 +503,8 @@ int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, vfbs->base.base.depth = 24; vfbs->base.base.width = width; vfbs->base.base.height = height; - vfbs->base.pin = NULL; - vfbs->base.unpin = NULL; + vfbs->base.pin = &vmw_surface_dmabuf_pin; + vfbs->base.unpin = &vmw_surface_dmabuf_unpin; vfbs->surface = surface; mutex_init(&vfbs->work_lock); INIT_DELAYED_WORK(&vfbs->d_work, &vmw_framebuffer_present_fs_callback); @@ -589,6 +592,40 @@ static struct drm_framebuffer_funcs vmw_framebuffer_dmabuf_funcs = { .create_handle = vmw_framebuffer_create_handle, }; +static int vmw_surface_dmabuf_pin(struct vmw_framebuffer *vfb) +{ + struct vmw_private *dev_priv = vmw_priv(vfb->base.dev); + struct vmw_framebuffer_surface *vfbs = + vmw_framebuffer_to_vfbs(&vfb->base); + unsigned long size = vfbs->base.base.pitch * vfbs->base.base.height; + int ret; + + vfbs->buffer = kzalloc(sizeof(*vfbs->buffer), GFP_KERNEL); + if (unlikely(vfbs->buffer == NULL)) + return -ENOMEM; + + vmw_overlay_pause_all(dev_priv); + ret = vmw_dmabuf_init(dev_priv, vfbs->buffer, size, + &vmw_vram_ne_placement, + false, &vmw_dmabuf_bo_free); + vmw_overlay_resume_all(dev_priv); + + return ret; +} + +static int vmw_surface_dmabuf_unpin(struct vmw_framebuffer *vfb) +{ + struct ttm_buffer_object *bo; + struct vmw_framebuffer_surface *vfbs = + vmw_framebuffer_to_vfbs(&vfb->base); + + bo = &vfbs->buffer->base; + ttm_bo_unref(&bo); + vfbs->buffer = NULL; + + return 0; +} + static int vmw_framebuffer_dmabuf_pin(struct vmw_framebuffer *vfb) { struct vmw_private *dev_priv = vmw_priv(vfb->base.dev); -- cgit v1.2.3 From bbfad33663fe8de1cce84ac776664292c46fe7ae Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 28 May 2010 11:22:01 +0200 Subject: drm/vmwgfx: Remove duplicate member from struct vmw_legacy_display_unit. Signed-off-by: Jakob Bornecrantz Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 8fde9bf8be41..b35d7b0fd48d 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -50,8 +50,6 @@ struct vmw_legacy_display_unit { struct vmw_display_unit base; struct list_head active; - - unsigned unit; }; static void vmw_ldu_destroy(struct vmw_legacy_display_unit *ldu) @@ -204,7 +202,7 @@ static int vmw_ldu_add_active(struct vmw_private *vmw_priv, at = &ld->active; list_for_each_entry(entry, &ld->active, active) { - if (entry->unit > ldu->unit) + if (entry->base.unit > ldu->base.unit) break; at = &entry->active; @@ -491,7 +489,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) if (!ldu) return -ENOMEM; - ldu->unit = unit; + ldu->base.unit = unit; crtc = &ldu->base.crtc; encoder = &ldu->base.encoder; connector = &ldu->base.connector; -- cgit v1.2.3 From d451f62a7c567654f74018be9ab8da8089660d3b Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 28 May 2010 11:22:02 +0200 Subject: drm/vmwgfx: Don't use SVGA_REG_ENABLE in modesetting code. We should not use SVGA_REG_ENABLE anywhere but in the fifo setup code, since it controls whether the device is active. Signed-off-by: Jakob Bornecrantz Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 4 ---- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 5 ----- 2 files changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index fb66e62b8e2c..06f431442e92 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c @@ -153,7 +153,6 @@ static int vmw_fb_set_par(struct fb_info *info) struct vmw_private *vmw_priv = par->vmw_priv; if (vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) { - vmw_write(vmw_priv, SVGA_REG_ENABLE, 0); vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0); vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true); vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, 0); @@ -175,13 +174,10 @@ static int vmw_fb_set_par(struct fb_info *info) vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, info->var.yres); vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1); - vmw_write(vmw_priv, SVGA_REG_ENABLE, 1); } else { - vmw_write(vmw_priv, SVGA_REG_ENABLE, 0); vmw_kms_write_svga(vmw_priv, info->var.xres, info->var.yres, info->fix.line_length, par->bpp, par->depth); - vmw_write(vmw_priv, SVGA_REG_ENABLE, 1); } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index b35d7b0fd48d..d98b1b1a8705 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -107,16 +107,12 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) return 0; fb = entry->base.crtc.fb; - vmw_write(dev_priv, SVGA_REG_ENABLE, 0); vmw_kms_write_svga(dev_priv, w, h, fb->pitch, fb->bits_per_pixel, fb->depth); - vmw_write(dev_priv, SVGA_REG_ENABLE, 1); return 0; } - vmw_write(dev_priv, SVGA_REG_ENABLE, 0); - for (i = 0; i < lds->last_num_active; i++) { vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, i); vmw_write(dev_priv, SVGA_REG_DISPLAY_IS_PRIMARY, !i); @@ -152,7 +148,6 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) /* Make sure we always show something. */ vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, i ? i : 1); - vmw_write(dev_priv, SVGA_REG_ENABLE, 1); BUG_ON(i != lds->num_active); -- cgit v1.2.3 From 259600d593181b8a3b1d7fe99d93233b1b113fd0 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 28 May 2010 11:22:03 +0200 Subject: drm/vmwgfx: Some modesetting cleanups and fixes. Signed-off-by: Jakob Bornecrantz Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index d98b1b1a8705..f7094dde18f9 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -113,16 +113,6 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) return 0; } - for (i = 0; i < lds->last_num_active; i++) { - vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, i); - vmw_write(dev_priv, SVGA_REG_DISPLAY_IS_PRIMARY, !i); - vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_X, 0); - vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_Y, 0); - vmw_write(dev_priv, SVGA_REG_DISPLAY_WIDTH, 0); - vmw_write(dev_priv, SVGA_REG_DISPLAY_HEIGHT, 0); - vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); - } - if (!list_empty(&lds->active)) { entry = list_entry(lds->active.next, typeof(*entry), active); fb = entry->base.crtc.fb; @@ -131,6 +121,10 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) fb->bits_per_pixel, fb->depth); } + /* Make sure we always show something. */ + vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, + lds->num_active ? lds->num_active : 1); + i = 0; list_for_each_entry(entry, &lds->active, active) { crtc = &entry->base.crtc; @@ -146,9 +140,6 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) i++; } - /* Make sure we always show something. */ - vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, i ? i : 1); - BUG_ON(i != lds->num_active); lds->last_num_active = lds->num_active; -- cgit v1.2.3 From 792778e8e058471e1909b78d7c5e6ab94962ff8e Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 28 May 2010 11:22:04 +0200 Subject: drm/vmwgfx: Unpause overlay on update. The unpause codepath uses vmw_overlay_update() so we must unset the paused status. Signed-off-by: Jakob Bornecrantz Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c index ad566c85b075..df2036ed18d5 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c @@ -358,6 +358,8 @@ static int vmw_overlay_update_stream(struct vmw_private *dev_priv, if (stream->buf != buf) stream->buf = vmw_dmabuf_reference(buf); stream->saved = *arg; + /* stream is no longer stopped/paused */ + stream->paused = false; return 0; } -- cgit v1.2.3 From 316ab13ae2ad603fd5e3a909524e68d98db1b1b6 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 28 May 2010 11:22:05 +0200 Subject: drm/vmwgfx: Print warnings in kernel log about bo pinning that fails. Signed-off-by: Jakob Bornecrantz Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 4 ++++ drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 2 ++ 2 files changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 06f431442e92..181f47222580 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c @@ -630,6 +630,10 @@ int vmw_dmabuf_to_start_of_vram(struct vmw_private *vmw_priv, goto err_unlock; ret = ttm_bo_validate(bo, &ne_placement, false, false, false); + + /* Could probably bug on */ + WARN_ON(bo->offset != 0); + ttm_bo_unreserve(bo); err_unlock: ttm_write_unlock(&vmw_priv->active_master->lock); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 250282fee9c8..b78dcf001858 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -640,6 +640,8 @@ static int vmw_framebuffer_dmabuf_pin(struct vmw_framebuffer *vfb) vmw_overlay_resume_all(dev_priv); + WARN_ON(ret != 0); + return 0; } -- cgit v1.2.3 From 1ca14e75caae504fdf957cf0c1c4f3aafc886a60 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 28 May 2010 11:22:06 +0200 Subject: drm/vmwgfx: Remove some leftover debug messages. Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index bdd87dc9e7b1..7597323d5a5a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -408,8 +408,6 @@ static int vmw_driver_unload(struct drm_device *dev) { struct vmw_private *dev_priv = vmw_priv(dev); - DRM_INFO(VMWGFX_DRIVER_NAME " unload.\n"); - unregister_pm_notifier(&dev_priv->pm_nb); vmw_fb_close(dev_priv); @@ -555,7 +553,6 @@ static int vmw_master_create(struct drm_device *dev, { struct vmw_master *vmaster; - DRM_INFO("Master create.\n"); vmaster = kzalloc(sizeof(*vmaster), GFP_KERNEL); if (unlikely(vmaster == NULL)) return -ENOMEM; @@ -572,7 +569,6 @@ static void vmw_master_destroy(struct drm_device *dev, { struct vmw_master *vmaster = vmw_master(master); - DRM_INFO("Master destroy.\n"); master->driver_priv = NULL; kfree(vmaster); } @@ -588,8 +584,6 @@ static int vmw_master_set(struct drm_device *dev, struct vmw_master *vmaster = vmw_master(file_priv->master); int ret = 0; - DRM_INFO("Master set.\n"); - if (active) { BUG_ON(active != &dev_priv->fbdev_master); ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile); @@ -631,8 +625,6 @@ static void vmw_master_drop(struct drm_device *dev, struct vmw_master *vmaster = vmw_master(file_priv->master); int ret; - DRM_INFO("Master drop.\n"); - /** * Make sure the master doesn't disappear while we have * it locked. -- cgit v1.2.3 From e8613c0e29d0018a80652e6ae58660c8a75ac74b Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 26 May 2010 16:21:03 +0200 Subject: drm/ttm: Fix cached TTM page allocation. This patch fixes a regression introduced with the pool page allocator in the event that there are no highmem pages (for example x86_64), in which case cached page allocation would fail. Tested with the vmwgfx driver on a 64-bit vm. Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/ttm/ttm_page_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 0d9a42c2394f..b6d152360675 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -671,7 +671,7 @@ int ttm_get_pages(struct list_head *pages, int flags, if (flags & TTM_PAGE_FLAG_DMA32) gfp_flags |= GFP_DMA32; else - gfp_flags |= __GFP_HIGHMEM; + gfp_flags |= GFP_HIGHUSER; for (r = 0; r < count; ++r) { p = alloc_page(gfp_flags); -- cgit v1.2.3 From 4abe4389790d5f02569fbacdf035536ba84c7d44 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 26 May 2010 16:21:04 +0200 Subject: drm/ttm: Fix ttm_page_alloc.c Fix a number of typos misspellings and checkpatch.pl warnings. Replace "[ttm] " with TTM_PFX Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/ttm/ttm_page_alloc.c | 62 +++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index b6d152360675..ef910694bd63 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -77,7 +77,7 @@ struct ttm_page_pool { /** * Limits for the pool. They are handled without locks because only place where * they may change is in sysfs store. They won't have immediate effect anyway - * so forcing serialiazation to access them is pointless. + * so forcing serialization to access them is pointless. */ struct ttm_pool_opts { @@ -165,16 +165,18 @@ static ssize_t ttm_pool_store(struct kobject *kobj, m->options.small = val; else if (attr == &ttm_page_pool_alloc_size) { if (val > NUM_PAGES_TO_ALLOC*8) { - printk(KERN_ERR "[ttm] Setting allocation size to %lu " - "is not allowed. Recomended size is " - "%lu\n", - NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 7), - NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 10)); + printk(KERN_ERR TTM_PFX + "Setting allocation size to %lu " + "is not allowed. Recommended size is " + "%lu\n", + NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 7), + NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 10)); return size; } else if (val > NUM_PAGES_TO_ALLOC) { - printk(KERN_WARNING "[ttm] Setting allocation size to " - "larger than %lu is not recomended.\n", - NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 10)); + printk(KERN_WARNING TTM_PFX + "Setting allocation size to " + "larger than %lu is not recommended.\n", + NUM_PAGES_TO_ALLOC*(PAGE_SIZE >> 10)); } m->options.alloc_size = val; } @@ -277,7 +279,7 @@ static void ttm_pages_put(struct page *pages[], unsigned npages) { unsigned i; if (set_pages_array_wb(pages, npages)) - printk(KERN_ERR "[ttm] Failed to set %d pages to wb!\n", + printk(KERN_ERR TTM_PFX "Failed to set %d pages to wb!\n", npages); for (i = 0; i < npages; ++i) __free_page(pages[i]); @@ -313,7 +315,8 @@ static int ttm_page_pool_free(struct ttm_page_pool *pool, unsigned nr_free) pages_to_free = kmalloc(npages_to_free * sizeof(struct page *), GFP_KERNEL); if (!pages_to_free) { - printk(KERN_ERR "Failed to allocate memory for pool free operation.\n"); + printk(KERN_ERR TTM_PFX + "Failed to allocate memory for pool free operation.\n"); return 0; } @@ -390,7 +393,7 @@ static int ttm_pool_get_num_unused_pages(void) } /** - * Calback for mm to request pool to reduce number of page held. + * Callback for mm to request pool to reduce number of page held. */ static int ttm_pool_mm_shrink(int shrink_pages, gfp_t gfp_mask) { @@ -433,14 +436,16 @@ static int ttm_set_pages_caching(struct page **pages, case tt_uncached: r = set_pages_array_uc(pages, cpages); if (r) - printk(KERN_ERR "[ttm] Failed to set %d pages to uc!\n", - cpages); + printk(KERN_ERR TTM_PFX + "Failed to set %d pages to uc!\n", + cpages); break; case tt_wc: r = set_pages_array_wc(pages, cpages); if (r) - printk(KERN_ERR "[ttm] Failed to set %d pages to wc!\n", - cpages); + printk(KERN_ERR TTM_PFX + "Failed to set %d pages to wc!\n", + cpages); break; default: break; @@ -458,7 +463,7 @@ static void ttm_handle_caching_state_failure(struct list_head *pages, struct page **failed_pages, unsigned cpages) { unsigned i; - /* Failed pages has to be reed */ + /* Failed pages have to be freed */ for (i = 0; i < cpages; ++i) { list_del(&failed_pages[i]->lru); __free_page(failed_pages[i]); @@ -485,7 +490,8 @@ static int ttm_alloc_new_pages(struct list_head *pages, int gfp_flags, caching_array = kmalloc(max_cpages*sizeof(struct page *), GFP_KERNEL); if (!caching_array) { - printk(KERN_ERR "[ttm] unable to allocate table for new pages."); + printk(KERN_ERR TTM_PFX + "Unable to allocate table for new pages."); return -ENOMEM; } @@ -493,12 +499,13 @@ static int ttm_alloc_new_pages(struct list_head *pages, int gfp_flags, p = alloc_page(gfp_flags); if (!p) { - printk(KERN_ERR "[ttm] unable to get page %u\n", i); + printk(KERN_ERR TTM_PFX "Unable to get page %u.\n", i); /* store already allocated pages in the pool after * setting the caching state */ if (cpages) { - r = ttm_set_pages_caching(caching_array, cstate, cpages); + r = ttm_set_pages_caching(caching_array, + cstate, cpages); if (r) ttm_handle_caching_state_failure(pages, ttm_flags, cstate, @@ -590,7 +597,8 @@ static void ttm_page_pool_fill_locked(struct ttm_page_pool *pool, ++pool->nrefills; pool->npages += alloc_size; } else { - printk(KERN_ERR "[ttm] Failed to fill pool (%p).", pool); + printk(KERN_ERR TTM_PFX + "Failed to fill pool (%p).", pool); /* If we have any pages left put them to the pool. */ list_for_each_entry(p, &pool->list, lru) { ++cpages; @@ -677,7 +685,8 @@ int ttm_get_pages(struct list_head *pages, int flags, p = alloc_page(gfp_flags); if (!p) { - printk(KERN_ERR "[ttm] unable to allocate page."); + printk(KERN_ERR TTM_PFX + "Unable to allocate page."); return -ENOMEM; } @@ -709,8 +718,9 @@ int ttm_get_pages(struct list_head *pages, int flags, if (r) { /* If there is any pages in the list put them back to * the pool. */ - printk(KERN_ERR "[ttm] Failed to allocate extra pages " - "for large request."); + printk(KERN_ERR TTM_PFX + "Failed to allocate extra pages " + "for large request."); ttm_put_pages(pages, 0, flags, cstate); return r; } @@ -778,7 +788,7 @@ int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages) if (atomic_add_return(1, &_manager.page_alloc_inited) > 1) return 0; - printk(KERN_INFO "[ttm] Initializing pool allocator.\n"); + printk(KERN_INFO TTM_PFX "Initializing pool allocator.\n"); ttm_page_pool_init_locked(&_manager.wc_pool, GFP_HIGHUSER, "wc"); @@ -813,7 +823,7 @@ void ttm_page_alloc_fini() if (atomic_sub_return(1, &_manager.page_alloc_inited) > 0) return; - printk(KERN_INFO "[ttm] Finilizing pool allocator.\n"); + printk(KERN_INFO TTM_PFX "Finalizing pool allocator.\n"); ttm_pool_mm_shrink_fini(&_manager); for (i = 0; i < NUM_POOLS; ++i) -- cgit v1.2.3 From 8b281db596744a15b2abbfdbf655796c64e172ca Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 31 May 2010 09:04:03 +1000 Subject: drm/nv50: cast IGP memory location to u64 before shifting Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_mem.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 775a7017af64..c1fd42b0dad1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -540,7 +540,8 @@ nouveau_mem_detect(struct drm_device *dev) dev_priv->vram_size = nv_rd32(dev, NV04_FIFO_DATA); dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK; if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) - dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12; + dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10); + dev_priv->vram_sys_base <<= 12; } NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20)); -- cgit v1.2.3 From afeb3e11147adb357603b071d6d7d1f30ea7f19d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 7 Apr 2010 13:55:09 +1000 Subject: drm/nouveau: attempt to get bios from ACPI v3 Some of the laptops with the switchable graphics, seem to not post the secondary GPU at all, and we can't find a copy of the BIOS anywhere except in the ACPI rom retrieval. This adds support for ACPI ROM retrieval to nouveau. Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/nouveau_acpi.c | 59 +++++++++++++++++++++++++++++++++- drivers/gpu/drm/nouveau/nouveau_bios.c | 20 ++++++++++++ drivers/gpu/drm/nouveau/nouveau_drv.h | 5 +++ 3 files changed, 83 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index e13f6af0037a..b3f146a811ca 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -35,6 +35,7 @@ static struct nouveau_dsm_priv { bool dsm_detected; acpi_handle dhandle; acpi_handle dsm_handle; + acpi_handle rom_handle; } nouveau_dsm_priv; static const char nouveau_dsm_muid[] = { @@ -151,12 +152,13 @@ static bool nouveau_dsm_pci_probe(struct pci_dev *pdev) dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); if (!dhandle) return false; + status = acpi_get_handle(dhandle, "_DSM", &nvidia_handle); if (ACPI_FAILURE(status)) { return false; } - ret= nouveau_dsm(nvidia_handle, NOUVEAU_DSM_SUPPORTED, + ret = nouveau_dsm(nvidia_handle, NOUVEAU_DSM_SUPPORTED, NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result); if (ret < 0) return false; @@ -173,6 +175,7 @@ static bool nouveau_dsm_detect(void) struct pci_dev *pdev = NULL; int has_dsm = 0; int vga_count = 0; + while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { vga_count++; @@ -204,3 +207,57 @@ void nouveau_unregister_dsm_handler(void) { vga_switcheroo_unregister_handler(); } + +/* retrieve the ROM in 4k blocks */ +static int nouveau_rom_call(acpi_handle rom_handle, uint8_t *bios, + int offset, int len) +{ + acpi_status status; + union acpi_object rom_arg_elements[2], *obj; + struct acpi_object_list rom_arg; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; + + rom_arg.count = 2; + rom_arg.pointer = &rom_arg_elements[0]; + + rom_arg_elements[0].type = ACPI_TYPE_INTEGER; + rom_arg_elements[0].integer.value = offset; + + rom_arg_elements[1].type = ACPI_TYPE_INTEGER; + rom_arg_elements[1].integer.value = len; + + status = acpi_evaluate_object(rom_handle, NULL, &rom_arg, &buffer); + if (ACPI_FAILURE(status)) { + printk(KERN_INFO "failed to evaluate ROM got %s\n", acpi_format_exception(status)); + return -ENODEV; + } + obj = (union acpi_object *)buffer.pointer; + memcpy(bios+offset, obj->buffer.pointer, len); + kfree(buffer.pointer); + return len; +} + +bool nouveau_acpi_rom_supported(struct pci_dev *pdev) +{ + acpi_status status; + acpi_handle dhandle, rom_handle; + + if (!nouveau_dsm_priv.dsm_detected) + return false; + + dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); + if (!dhandle) + return false; + + status = acpi_get_handle(dhandle, "_ROM", &rom_handle); + if (ACPI_FAILURE(status)) + return false; + + nouveau_dsm_priv.rom_handle = rom_handle; + return true; +} + +int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) +{ + return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len); +} diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index e7e69ccce5c9..745ff3788e9d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -178,6 +178,25 @@ out: pci_disable_rom(dev->pdev); } +static void load_vbios_acpi(struct drm_device *dev, uint8_t *data) +{ + int i; + int ret; + int size = 64 * 1024; + + if (!nouveau_acpi_rom_supported(dev->pdev)) + return; + + for (i = 0; i < (size / ROM_BIOS_PAGE); i++) { + ret = nouveau_acpi_get_bios_chunk(data, + (i * ROM_BIOS_PAGE), + ROM_BIOS_PAGE); + if (ret <= 0) + break; + } + return; +} + struct methods { const char desc[8]; void (*loadbios)(struct drm_device *, uint8_t *); @@ -191,6 +210,7 @@ static struct methods nv04_methods[] = { }; static struct methods nv50_methods[] = { + { "ACPI", load_vbios_acpi, true }, { "PRAMIN", load_vbios_pramin, true }, { "PROM", load_vbios_prom, false }, { "PCIROM", load_vbios_pci, true }, diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 5b134438effe..c69719106489 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -851,12 +851,17 @@ extern int nouveau_dma_init(struct nouveau_channel *); extern int nouveau_dma_wait(struct nouveau_channel *, int slots, int size); /* nouveau_acpi.c */ +#define ROM_BIOS_PAGE 4096 #if defined(CONFIG_ACPI) void nouveau_register_dsm_handler(void); void nouveau_unregister_dsm_handler(void); +int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len); +bool nouveau_acpi_rom_supported(struct pci_dev *pdev); #else static inline void nouveau_register_dsm_handler(void) {} static inline void nouveau_unregister_dsm_handler(void) {} +static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; } +static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; } #endif /* nouveau_backlight.c */ -- cgit v1.2.3 From fc5ea29d72bde1bec230538becf396caad8621b8 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 31 May 2010 17:10:52 +1000 Subject: drm/nouveau: fixup confusion over which handle the DSM is hanging off. This fixes the DSM setup correctly since vga switcheroo. Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/nouveau_acpi.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index b3f146a811ca..d4bcca8a5133 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -34,7 +34,6 @@ static struct nouveau_dsm_priv { bool dsm_detected; acpi_handle dhandle; - acpi_handle dsm_handle; acpi_handle rom_handle; } nouveau_dsm_priv; @@ -108,9 +107,9 @@ static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switchero static int nouveau_dsm_switchto(enum vga_switcheroo_client_id id) { if (id == VGA_SWITCHEROO_IGD) - return nouveau_dsm_switch_mux(nouveau_dsm_priv.dsm_handle, NOUVEAU_DSM_LED_STAMINA); + return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_STAMINA); else - return nouveau_dsm_switch_mux(nouveau_dsm_priv.dsm_handle, NOUVEAU_DSM_LED_SPEED); + return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_SPEED); } static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id, @@ -119,7 +118,7 @@ static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id, if (id == VGA_SWITCHEROO_IGD) return 0; - return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dsm_handle, state); + return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state); } static int nouveau_dsm_init(void) @@ -158,13 +157,12 @@ static bool nouveau_dsm_pci_probe(struct pci_dev *pdev) return false; } - ret = nouveau_dsm(nvidia_handle, NOUVEAU_DSM_SUPPORTED, - NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result); + ret = nouveau_dsm(dhandle, NOUVEAU_DSM_SUPPORTED, + NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result); if (ret < 0) return false; nouveau_dsm_priv.dhandle = dhandle; - nouveau_dsm_priv.dsm_handle = nvidia_handle; return true; } @@ -183,7 +181,7 @@ static bool nouveau_dsm_detect(void) } if (vga_count == 2 && has_dsm) { - acpi_get_name(nouveau_dsm_priv.dsm_handle, ACPI_FULL_PATHNAME, &buffer); + acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME, &buffer); printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n", acpi_method_name); nouveau_dsm_priv.dsm_detected = true; -- cgit v1.2.3 From fbf81762e385d3d45acad057b654d56972acf58c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 1 Jun 2010 09:09:06 +1000 Subject: drm/kms: disable/enable poll around switcheroo on/off Because we aren't in a suspend state the poll will still run when we have switcherooed a card off. Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc_helper.c | 28 ++++++++++++++++++++++------ drivers/gpu/drm/i915/i915_dma.c | 4 +++- drivers/gpu/drm/nouveau/nouveau_state.c | 3 +++ drivers/gpu/drm/radeon/radeon_device.c | 2 ++ include/drm/drm_crtc_helper.h | 3 +++ 5 files changed, 33 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 764401951041..9b2a54117c91 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -860,19 +860,24 @@ static void output_poll_execute(struct slow_work *work) } } -void drm_kms_helper_poll_init(struct drm_device *dev) +void drm_kms_helper_poll_disable(struct drm_device *dev) +{ + if (!dev->mode_config.poll_enabled) + return; + delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work); +} +EXPORT_SYMBOL(drm_kms_helper_poll_disable); + +void drm_kms_helper_poll_enable(struct drm_device *dev) { - struct drm_connector *connector; bool poll = false; + struct drm_connector *connector; int ret; list_for_each_entry(connector, &dev->mode_config.connector_list, head) { if (connector->polled) poll = true; } - slow_work_register_user(THIS_MODULE); - delayed_slow_work_init(&dev->mode_config.output_poll_slow_work, - &output_poll_ops); if (poll) { ret = delayed_slow_work_enqueue(&dev->mode_config.output_poll_slow_work, DRM_OUTPUT_POLL_PERIOD); @@ -880,11 +885,22 @@ void drm_kms_helper_poll_init(struct drm_device *dev) DRM_ERROR("delayed enqueue failed %d\n", ret); } } +EXPORT_SYMBOL(drm_kms_helper_poll_enable); + +void drm_kms_helper_poll_init(struct drm_device *dev) +{ + slow_work_register_user(THIS_MODULE); + delayed_slow_work_init(&dev->mode_config.output_poll_slow_work, + &output_poll_ops); + dev->mode_config.poll_enabled = true; + + drm_kms_helper_poll_enable(dev); +} EXPORT_SYMBOL(drm_kms_helper_poll_init); void drm_kms_helper_poll_fini(struct drm_device *dev) { - delayed_slow_work_cancel(&dev->mode_config.output_poll_slow_work); + drm_kms_helper_poll_disable(dev); slow_work_unregister_user(THIS_MODULE); } EXPORT_SYMBOL(drm_kms_helper_poll_fini); diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 2a6b5de5ae5d..cc6e56a18edd 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1399,12 +1399,14 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_ struct drm_device *dev = pci_get_drvdata(pdev); pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; if (state == VGA_SWITCHEROO_ON) { - printk(KERN_INFO "i915: switched off\n"); + printk(KERN_INFO "i915: switched on\n"); /* i915 resume handler doesn't set to D0 */ pci_set_power_state(dev->pdev, PCI_D0); i915_resume(dev); + drm_kms_helper_poll_enable(dev); } else { printk(KERN_ERR "i915: switched off\n"); + drm_kms_helper_poll_disable(dev); i915_suspend(dev, pmm); } } diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index e632339c323e..5c468a4fef9a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -376,12 +376,15 @@ out_err: static void nouveau_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) { + struct drm_device *dev = pci_get_drvdata(pdev); pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; if (state == VGA_SWITCHEROO_ON) { printk(KERN_ERR "VGA switcheroo: switched nouveau on\n"); nouveau_pci_resume(pdev); + drm_kms_helper_poll_enable(dev); } else { printk(KERN_ERR "VGA switcheroo: switched nouveau off\n"); + drm_kms_helper_poll_disable(dev); nouveau_pci_suspend(pdev, pmm); } } diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index fdc3fdf78acb..db338522191f 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -546,8 +546,10 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero /* don't suspend or resume card normally */ rdev->powered_down = false; radeon_resume_kms(dev); + drm_kms_helper_poll_enable(dev); } else { printk(KERN_INFO "radeon: switched off\n"); + drm_kms_helper_poll_disable(dev); radeon_suspend_kms(dev, pmm); /* don't suspend or resume card normally */ rdev->powered_down = true; diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index dc5873c21e45..1121f7799c6f 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -130,4 +130,7 @@ extern int drm_helper_resume_force_mode(struct drm_device *dev); extern void drm_kms_helper_poll_init(struct drm_device *dev); extern void drm_kms_helper_poll_fini(struct drm_device *dev); extern void drm_helper_hpd_irq_event(struct drm_device *dev); + +extern void drm_kms_helper_poll_disable(struct drm_device *dev); +extern void drm_kms_helper_poll_enable(struct drm_device *dev); #endif -- cgit v1.2.3 From cb5fcbd540b438a5d311bd15dc910841d01ed140 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 28 May 2010 19:01:35 -0400 Subject: drm/radeon/kms/evergreen: add initial CS parser Advanced validation is not implemented yet. The mesa code that uses this will be released soon. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/Makefile | 7 +- drivers/gpu/drm/radeon/evergreen_cs.c | 1356 +++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/evergreen_reg.h | 3 + drivers/gpu/drm/radeon/evergreend.h | 464 ++++++++++ drivers/gpu/drm/radeon/radeon_asic.c | 4 +- drivers/gpu/drm/radeon/radeon_asic.h | 1 + drivers/gpu/drm/radeon/reg_srcs/evergreen | 611 +++++++++++++ 7 files changed, 2443 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/radeon/evergreen_cs.c create mode 100644 drivers/gpu/drm/radeon/reg_srcs/evergreen (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 3c91312dea9a..84b1f2729d43 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile @@ -33,6 +33,9 @@ $(obj)/rs600_reg_safe.h: $(src)/reg_srcs/rs600 $(obj)/mkregtable $(obj)/r600_reg_safe.h: $(src)/reg_srcs/r600 $(obj)/mkregtable $(call if_changed,mkregtable) +$(obj)/evergreen_reg_safe.h: $(src)/reg_srcs/evergreen $(obj)/mkregtable + $(call if_changed,mkregtable) + $(obj)/r100.o: $(obj)/r100_reg_safe.h $(obj)/rn50_reg_safe.h $(obj)/r200.o: $(obj)/r200_reg_safe.h @@ -47,6 +50,8 @@ $(obj)/rs600.o: $(obj)/rs600_reg_safe.h $(obj)/r600_cs.o: $(obj)/r600_reg_safe.h +$(obj)/evergreen_cs.o: $(obj)/evergreen_reg_safe.h + radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \ radeon_irq.o r300_cmdbuf.o r600_cp.o # add KMS driver @@ -60,7 +65,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ - evergreen.o + evergreen.o evergreen_cs.o radeon-$(CONFIG_COMPAT) += radeon_ioc32.o radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c new file mode 100644 index 000000000000..64516b950891 --- /dev/null +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -0,0 +1,1356 @@ +/* + * Copyright 2010 Advanced Micro Devices, Inc. + * Copyright 2008 Red Hat Inc. + * Copyright 2009 Jerome Glisse. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Dave Airlie + * Alex Deucher + * Jerome Glisse + */ +#include "drmP.h" +#include "radeon.h" +#include "evergreend.h" +#include "evergreen_reg_safe.h" + +static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p, + struct radeon_cs_reloc **cs_reloc); + +struct evergreen_cs_track { + u32 group_size; + u32 nbanks; + u32 npipes; + /* value we track */ + u32 nsamples; + u32 cb_color_base_last[12]; + struct radeon_bo *cb_color_bo[12]; + u32 cb_color_bo_offset[12]; + struct radeon_bo *cb_color_fmask_bo[8]; + struct radeon_bo *cb_color_cmask_bo[8]; + u32 cb_color_info[12]; + u32 cb_color_view[12]; + u32 cb_color_pitch_idx[12]; + u32 cb_color_slice_idx[12]; + u32 cb_color_dim_idx[12]; + u32 cb_color_dim[12]; + u32 cb_color_pitch[12]; + u32 cb_color_slice[12]; + u32 cb_color_cmask_slice[8]; + u32 cb_color_fmask_slice[8]; + u32 cb_target_mask; + u32 cb_shader_mask; + u32 vgt_strmout_config; + u32 vgt_strmout_buffer_config; + u32 db_depth_control; + u32 db_depth_view; + u32 db_depth_size; + u32 db_depth_size_idx; + u32 db_z_info; + u32 db_z_idx; + u32 db_z_read_offset; + u32 db_z_write_offset; + struct radeon_bo *db_z_read_bo; + struct radeon_bo *db_z_write_bo; + u32 db_s_info; + u32 db_s_idx; + u32 db_s_read_offset; + u32 db_s_write_offset; + struct radeon_bo *db_s_read_bo; + struct radeon_bo *db_s_write_bo; +}; + +static void evergreen_cs_track_init(struct evergreen_cs_track *track) +{ + int i; + + for (i = 0; i < 8; i++) { + track->cb_color_fmask_bo[i] = NULL; + track->cb_color_cmask_bo[i] = NULL; + track->cb_color_cmask_slice[i] = 0; + track->cb_color_fmask_slice[i] = 0; + } + + for (i = 0; i < 12; i++) { + track->cb_color_base_last[i] = 0; + track->cb_color_bo[i] = NULL; + track->cb_color_bo_offset[i] = 0xFFFFFFFF; + track->cb_color_info[i] = 0; + track->cb_color_view[i] = 0; + track->cb_color_pitch_idx[i] = 0; + track->cb_color_slice_idx[i] = 0; + track->cb_color_dim[i] = 0; + track->cb_color_pitch[i] = 0; + track->cb_color_slice[i] = 0; + track->cb_color_dim[i] = 0; + } + track->cb_target_mask = 0xFFFFFFFF; + track->cb_shader_mask = 0xFFFFFFFF; + + track->db_depth_view = 0xFFFFC000; + track->db_depth_size = 0xFFFFFFFF; + track->db_depth_size_idx = 0; + track->db_depth_control = 0xFFFFFFFF; + track->db_z_info = 0xFFFFFFFF; + track->db_z_idx = 0xFFFFFFFF; + track->db_z_read_offset = 0xFFFFFFFF; + track->db_z_write_offset = 0xFFFFFFFF; + track->db_z_read_bo = NULL; + track->db_z_write_bo = NULL; + track->db_s_info = 0xFFFFFFFF; + track->db_s_idx = 0xFFFFFFFF; + track->db_s_read_offset = 0xFFFFFFFF; + track->db_s_write_offset = 0xFFFFFFFF; + track->db_s_read_bo = NULL; + track->db_s_write_bo = NULL; +} + +static inline int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, int i) +{ + /* XXX fill in */ + return 0; +} + +static int evergreen_cs_track_check(struct radeon_cs_parser *p) +{ + struct evergreen_cs_track *track = p->track; + + /* we don't support stream out buffer yet */ + if (track->vgt_strmout_config || track->vgt_strmout_buffer_config) { + dev_warn(p->dev, "this kernel doesn't support SMX output buffer\n"); + return -EINVAL; + } + + /* XXX fill in */ + return 0; +} + +/** + * evergreen_cs_packet_parse() - parse cp packet and point ib index to next packet + * @parser: parser structure holding parsing context. + * @pkt: where to store packet informations + * + * Assume that chunk_ib_index is properly set. Will return -EINVAL + * if packet is bigger than remaining ib size. or if packets is unknown. + **/ +int evergreen_cs_packet_parse(struct radeon_cs_parser *p, + struct radeon_cs_packet *pkt, + unsigned idx) +{ + struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; + uint32_t header; + + if (idx >= ib_chunk->length_dw) { + DRM_ERROR("Can not parse packet at %d after CS end %d !\n", + idx, ib_chunk->length_dw); + return -EINVAL; + } + header = radeon_get_ib_value(p, idx); + pkt->idx = idx; + pkt->type = CP_PACKET_GET_TYPE(header); + pkt->count = CP_PACKET_GET_COUNT(header); + pkt->one_reg_wr = 0; + switch (pkt->type) { + case PACKET_TYPE0: + pkt->reg = CP_PACKET0_GET_REG(header); + break; + case PACKET_TYPE3: + pkt->opcode = CP_PACKET3_GET_OPCODE(header); + break; + case PACKET_TYPE2: + pkt->count = -1; + break; + default: + DRM_ERROR("Unknown packet type %d at %d !\n", pkt->type, idx); + return -EINVAL; + } + if ((pkt->count + 1 + pkt->idx) >= ib_chunk->length_dw) { + DRM_ERROR("Packet (%d:%d:%d) end after CS buffer (%d) !\n", + pkt->idx, pkt->type, pkt->count, ib_chunk->length_dw); + return -EINVAL; + } + return 0; +} + +/** + * evergreen_cs_packet_next_reloc() - parse next packet which should be reloc packet3 + * @parser: parser structure holding parsing context. + * @data: pointer to relocation data + * @offset_start: starting offset + * @offset_mask: offset mask (to align start offset on) + * @reloc: reloc informations + * + * Check next packet is relocation packet3, do bo validation and compute + * GPU offset using the provided start. + **/ +static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p, + struct radeon_cs_reloc **cs_reloc) +{ + struct radeon_cs_chunk *relocs_chunk; + struct radeon_cs_packet p3reloc; + unsigned idx; + int r; + + if (p->chunk_relocs_idx == -1) { + DRM_ERROR("No relocation chunk !\n"); + return -EINVAL; + } + *cs_reloc = NULL; + relocs_chunk = &p->chunks[p->chunk_relocs_idx]; + r = evergreen_cs_packet_parse(p, &p3reloc, p->idx); + if (r) { + return r; + } + p->idx += p3reloc.count + 2; + if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { + DRM_ERROR("No packet3 for relocation for packet at %d.\n", + p3reloc.idx); + return -EINVAL; + } + idx = radeon_get_ib_value(p, p3reloc.idx + 1); + if (idx >= relocs_chunk->length_dw) { + DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", + idx, relocs_chunk->length_dw); + return -EINVAL; + } + /* FIXME: we assume reloc size is 4 dwords */ + *cs_reloc = p->relocs_ptr[(idx / 4)]; + return 0; +} + +/** + * evergreen_cs_packet_next_is_pkt3_nop() - test if next packet is packet3 nop for reloc + * @parser: parser structure holding parsing context. + * + * Check next packet is relocation packet3, do bo validation and compute + * GPU offset using the provided start. + **/ +static inline int evergreen_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p) +{ + struct radeon_cs_packet p3reloc; + int r; + + r = evergreen_cs_packet_parse(p, &p3reloc, p->idx); + if (r) { + return 0; + } + if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { + return 0; + } + return 1; +} + +/** + * evergreen_cs_packet_next_vline() - parse userspace VLINE packet + * @parser: parser structure holding parsing context. + * + * Userspace sends a special sequence for VLINE waits. + * PACKET0 - VLINE_START_END + value + * PACKET3 - WAIT_REG_MEM poll vline status reg + * RELOC (P3) - crtc_id in reloc. + * + * This function parses this and relocates the VLINE START END + * and WAIT_REG_MEM packets to the correct crtc. + * It also detects a switched off crtc and nulls out the + * wait in that case. + */ +static int evergreen_cs_packet_parse_vline(struct radeon_cs_parser *p) +{ + struct drm_mode_object *obj; + struct drm_crtc *crtc; + struct radeon_crtc *radeon_crtc; + struct radeon_cs_packet p3reloc, wait_reg_mem; + int crtc_id; + int r; + uint32_t header, h_idx, reg, wait_reg_mem_info; + volatile uint32_t *ib; + + ib = p->ib->ptr; + + /* parse the WAIT_REG_MEM */ + r = evergreen_cs_packet_parse(p, &wait_reg_mem, p->idx); + if (r) + return r; + + /* check its a WAIT_REG_MEM */ + if (wait_reg_mem.type != PACKET_TYPE3 || + wait_reg_mem.opcode != PACKET3_WAIT_REG_MEM) { + DRM_ERROR("vline wait missing WAIT_REG_MEM segment\n"); + r = -EINVAL; + return r; + } + + wait_reg_mem_info = radeon_get_ib_value(p, wait_reg_mem.idx + 1); + /* bit 4 is reg (0) or mem (1) */ + if (wait_reg_mem_info & 0x10) { + DRM_ERROR("vline WAIT_REG_MEM waiting on MEM rather than REG\n"); + r = -EINVAL; + return r; + } + /* waiting for value to be equal */ + if ((wait_reg_mem_info & 0x7) != 0x3) { + DRM_ERROR("vline WAIT_REG_MEM function not equal\n"); + r = -EINVAL; + return r; + } + if ((radeon_get_ib_value(p, wait_reg_mem.idx + 2) << 2) != EVERGREEN_VLINE_STATUS) { + DRM_ERROR("vline WAIT_REG_MEM bad reg\n"); + r = -EINVAL; + return r; + } + + if (radeon_get_ib_value(p, wait_reg_mem.idx + 5) != EVERGREEN_VLINE_STAT) { + DRM_ERROR("vline WAIT_REG_MEM bad bit mask\n"); + r = -EINVAL; + return r; + } + + /* jump over the NOP */ + r = evergreen_cs_packet_parse(p, &p3reloc, p->idx + wait_reg_mem.count + 2); + if (r) + return r; + + h_idx = p->idx - 2; + p->idx += wait_reg_mem.count + 2; + p->idx += p3reloc.count + 2; + + header = radeon_get_ib_value(p, h_idx); + crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1); + reg = CP_PACKET0_GET_REG(header); + mutex_lock(&p->rdev->ddev->mode_config.mutex); + obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC); + if (!obj) { + DRM_ERROR("cannot find crtc %d\n", crtc_id); + r = -EINVAL; + goto out; + } + crtc = obj_to_crtc(obj); + radeon_crtc = to_radeon_crtc(crtc); + crtc_id = radeon_crtc->crtc_id; + + if (!crtc->enabled) { + /* if the CRTC isn't enabled - we need to nop out the WAIT_REG_MEM */ + ib[h_idx + 2] = PACKET2(0); + ib[h_idx + 3] = PACKET2(0); + ib[h_idx + 4] = PACKET2(0); + ib[h_idx + 5] = PACKET2(0); + ib[h_idx + 6] = PACKET2(0); + ib[h_idx + 7] = PACKET2(0); + ib[h_idx + 8] = PACKET2(0); + } else { + switch (reg) { + case EVERGREEN_VLINE_START_END: + header &= ~R600_CP_PACKET0_REG_MASK; + header |= (EVERGREEN_VLINE_START_END + radeon_crtc->crtc_offset) >> 2; + ib[h_idx] = header; + ib[h_idx + 4] = (EVERGREEN_VLINE_STATUS + radeon_crtc->crtc_offset) >> 2; + break; + default: + DRM_ERROR("unknown crtc reloc\n"); + r = -EINVAL; + goto out; + } + } +out: + mutex_unlock(&p->rdev->ddev->mode_config.mutex); + return r; +} + +static int evergreen_packet0_check(struct radeon_cs_parser *p, + struct radeon_cs_packet *pkt, + unsigned idx, unsigned reg) +{ + int r; + + switch (reg) { + case EVERGREEN_VLINE_START_END: + r = evergreen_cs_packet_parse_vline(p); + if (r) { + DRM_ERROR("No reloc for ib[%d]=0x%04X\n", + idx, reg); + return r; + } + break; + default: + printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", + reg, idx); + return -EINVAL; + } + return 0; +} + +static int evergreen_cs_parse_packet0(struct radeon_cs_parser *p, + struct radeon_cs_packet *pkt) +{ + unsigned reg, i; + unsigned idx; + int r; + + idx = pkt->idx + 1; + reg = pkt->reg; + for (i = 0; i <= pkt->count; i++, idx++, reg += 4) { + r = evergreen_packet0_check(p, pkt, idx, reg); + if (r) { + return r; + } + } + return 0; +} + +/** + * evergreen_cs_check_reg() - check if register is authorized or not + * @parser: parser structure holding parsing context + * @reg: register we are testing + * @idx: index into the cs buffer + * + * This function will test against evergreen_reg_safe_bm and return 0 + * if register is safe. If register is not flag as safe this function + * will test it against a list of register needind special handling. + */ +static inline int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) +{ + struct evergreen_cs_track *track = (struct evergreen_cs_track *)p->track; + struct radeon_cs_reloc *reloc; + u32 last_reg = ARRAY_SIZE(evergreen_reg_safe_bm); + u32 m, i, tmp, *ib; + int r; + + i = (reg >> 7); + if (i > last_reg) { + dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); + return -EINVAL; + } + m = 1 << ((reg >> 2) & 31); + if (!(evergreen_reg_safe_bm[i] & m)) + return 0; + ib = p->ib->ptr; + switch (reg) { + /* force following reg to 0 in an attemp to disable out buffer + * which will need us to better understand how it works to perform + * security check on it (Jerome) + */ + case SQ_ESGS_RING_SIZE: + case SQ_GSVS_RING_SIZE: + case SQ_ESTMP_RING_SIZE: + case SQ_GSTMP_RING_SIZE: + case SQ_HSTMP_RING_SIZE: + case SQ_LSTMP_RING_SIZE: + case SQ_PSTMP_RING_SIZE: + case SQ_VSTMP_RING_SIZE: + case SQ_ESGS_RING_ITEMSIZE: + case SQ_ESTMP_RING_ITEMSIZE: + case SQ_GSTMP_RING_ITEMSIZE: + case SQ_GSVS_RING_ITEMSIZE: + case SQ_GS_VERT_ITEMSIZE: + case SQ_GS_VERT_ITEMSIZE_1: + case SQ_GS_VERT_ITEMSIZE_2: + case SQ_GS_VERT_ITEMSIZE_3: + case SQ_GSVS_RING_OFFSET_1: + case SQ_GSVS_RING_OFFSET_2: + case SQ_GSVS_RING_OFFSET_3: + case SQ_HSTMP_RING_ITEMSIZE: + case SQ_LSTMP_RING_ITEMSIZE: + case SQ_PSTMP_RING_ITEMSIZE: + case SQ_VSTMP_RING_ITEMSIZE: + case VGT_TF_RING_SIZE: + /* get value to populate the IB don't remove */ + tmp =radeon_get_ib_value(p, idx); + ib[idx] = 0; + break; + case DB_DEPTH_CONTROL: + track->db_depth_control = radeon_get_ib_value(p, idx); + break; + case DB_Z_INFO: + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + dev_warn(p->dev, "bad SET_CONTEXT_REG " + "0x%04X\n", reg); + return -EINVAL; + } + track->db_z_info = radeon_get_ib_value(p, idx); + ib[idx] &= ~Z_ARRAY_MODE(0xf); + track->db_z_info &= ~Z_ARRAY_MODE(0xf); + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { + ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); + track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); + } else { + ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); + track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); + } + break; + case DB_STENCIL_INFO: + track->db_s_info = radeon_get_ib_value(p, idx); + break; + case DB_DEPTH_VIEW: + track->db_depth_view = radeon_get_ib_value(p, idx); + break; + case DB_DEPTH_SIZE: + track->db_depth_size = radeon_get_ib_value(p, idx); + track->db_depth_size_idx = idx; + break; + case DB_Z_READ_BASE: + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + dev_warn(p->dev, "bad SET_CONTEXT_REG " + "0x%04X\n", reg); + return -EINVAL; + } + track->db_z_read_offset = radeon_get_ib_value(p, idx); + ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + track->db_z_read_bo = reloc->robj; + break; + case DB_Z_WRITE_BASE: + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + dev_warn(p->dev, "bad SET_CONTEXT_REG " + "0x%04X\n", reg); + return -EINVAL; + } + track->db_z_write_offset = radeon_get_ib_value(p, idx); + ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + track->db_z_write_bo = reloc->robj; + break; + case DB_STENCIL_READ_BASE: + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + dev_warn(p->dev, "bad SET_CONTEXT_REG " + "0x%04X\n", reg); + return -EINVAL; + } + track->db_s_read_offset = radeon_get_ib_value(p, idx); + ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + track->db_s_read_bo = reloc->robj; + break; + case DB_STENCIL_WRITE_BASE: + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + dev_warn(p->dev, "bad SET_CONTEXT_REG " + "0x%04X\n", reg); + return -EINVAL; + } + track->db_s_write_offset = radeon_get_ib_value(p, idx); + ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + track->db_s_write_bo = reloc->robj; + break; + case VGT_STRMOUT_CONFIG: + track->vgt_strmout_config = radeon_get_ib_value(p, idx); + break; + case VGT_STRMOUT_BUFFER_CONFIG: + track->vgt_strmout_buffer_config = radeon_get_ib_value(p, idx); + break; + case CB_TARGET_MASK: + track->cb_target_mask = radeon_get_ib_value(p, idx); + break; + case CB_SHADER_MASK: + track->cb_shader_mask = radeon_get_ib_value(p, idx); + break; + case PA_SC_AA_CONFIG: + tmp = radeon_get_ib_value(p, idx) & MSAA_NUM_SAMPLES_MASK; + track->nsamples = 1 << tmp; + break; + case CB_COLOR0_VIEW: + case CB_COLOR1_VIEW: + case CB_COLOR2_VIEW: + case CB_COLOR3_VIEW: + case CB_COLOR4_VIEW: + case CB_COLOR5_VIEW: + case CB_COLOR6_VIEW: + case CB_COLOR7_VIEW: + tmp = (reg - CB_COLOR0_VIEW) / 0x3c; + track->cb_color_view[tmp] = radeon_get_ib_value(p, idx); + break; + case CB_COLOR8_VIEW: + case CB_COLOR9_VIEW: + case CB_COLOR10_VIEW: + case CB_COLOR11_VIEW: + tmp = ((reg - CB_COLOR8_VIEW) / 0x1c) + 8; + track->cb_color_view[tmp] = radeon_get_ib_value(p, idx); + break; + case CB_COLOR0_INFO: + case CB_COLOR1_INFO: + case CB_COLOR2_INFO: + case CB_COLOR3_INFO: + case CB_COLOR4_INFO: + case CB_COLOR5_INFO: + case CB_COLOR6_INFO: + case CB_COLOR7_INFO: + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + dev_warn(p->dev, "bad SET_CONTEXT_REG " + "0x%04X\n", reg); + return -EINVAL; + } + tmp = (reg - CB_COLOR0_INFO) / 0x3c; + track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { + ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); + track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); + } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { + ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); + track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); + } + break; + case CB_COLOR8_INFO: + case CB_COLOR9_INFO: + case CB_COLOR10_INFO: + case CB_COLOR11_INFO: + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + dev_warn(p->dev, "bad SET_CONTEXT_REG " + "0x%04X\n", reg); + return -EINVAL; + } + tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8; + track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { + ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); + track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); + } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { + ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); + track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); + } + break; + case CB_COLOR0_PITCH: + case CB_COLOR1_PITCH: + case CB_COLOR2_PITCH: + case CB_COLOR3_PITCH: + case CB_COLOR4_PITCH: + case CB_COLOR5_PITCH: + case CB_COLOR6_PITCH: + case CB_COLOR7_PITCH: + tmp = (reg - CB_COLOR0_PITCH) / 0x3c; + track->cb_color_pitch[tmp] = radeon_get_ib_value(p, idx); + track->cb_color_pitch_idx[tmp] = idx; + break; + case CB_COLOR8_PITCH: + case CB_COLOR9_PITCH: + case CB_COLOR10_PITCH: + case CB_COLOR11_PITCH: + tmp = ((reg - CB_COLOR8_PITCH) / 0x1c) + 8; + track->cb_color_pitch[tmp] = radeon_get_ib_value(p, idx); + track->cb_color_pitch_idx[tmp] = idx; + break; + case CB_COLOR0_SLICE: + case CB_COLOR1_SLICE: + case CB_COLOR2_SLICE: + case CB_COLOR3_SLICE: + case CB_COLOR4_SLICE: + case CB_COLOR5_SLICE: + case CB_COLOR6_SLICE: + case CB_COLOR7_SLICE: + tmp = (reg - CB_COLOR0_SLICE) / 0x3c; + track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx); + track->cb_color_slice_idx[tmp] = idx; + break; + case CB_COLOR8_SLICE: + case CB_COLOR9_SLICE: + case CB_COLOR10_SLICE: + case CB_COLOR11_SLICE: + tmp = ((reg - CB_COLOR8_SLICE) / 0x1c) + 8; + track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx); + track->cb_color_slice_idx[tmp] = idx; + break; + case CB_COLOR0_ATTRIB: + case CB_COLOR1_ATTRIB: + case CB_COLOR2_ATTRIB: + case CB_COLOR3_ATTRIB: + case CB_COLOR4_ATTRIB: + case CB_COLOR5_ATTRIB: + case CB_COLOR6_ATTRIB: + case CB_COLOR7_ATTRIB: + case CB_COLOR8_ATTRIB: + case CB_COLOR9_ATTRIB: + case CB_COLOR10_ATTRIB: + case CB_COLOR11_ATTRIB: + break; + case CB_COLOR0_DIM: + case CB_COLOR1_DIM: + case CB_COLOR2_DIM: + case CB_COLOR3_DIM: + case CB_COLOR4_DIM: + case CB_COLOR5_DIM: + case CB_COLOR6_DIM: + case CB_COLOR7_DIM: + tmp = (reg - CB_COLOR0_DIM) / 0x3c; + track->cb_color_dim[tmp] = radeon_get_ib_value(p, idx); + track->cb_color_dim_idx[tmp] = idx; + break; + case CB_COLOR8_DIM: + case CB_COLOR9_DIM: + case CB_COLOR10_DIM: + case CB_COLOR11_DIM: + tmp = ((reg - CB_COLOR8_DIM) / 0x1c) + 8; + track->cb_color_dim[tmp] = radeon_get_ib_value(p, idx); + track->cb_color_dim_idx[tmp] = idx; + break; + case CB_COLOR0_FMASK: + case CB_COLOR1_FMASK: + case CB_COLOR2_FMASK: + case CB_COLOR3_FMASK: + case CB_COLOR4_FMASK: + case CB_COLOR5_FMASK: + case CB_COLOR6_FMASK: + case CB_COLOR7_FMASK: + tmp = (reg - CB_COLOR0_FMASK) / 0x3c; + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); + return -EINVAL; + } + ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + track->cb_color_fmask_bo[tmp] = reloc->robj; + break; + case CB_COLOR0_CMASK: + case CB_COLOR1_CMASK: + case CB_COLOR2_CMASK: + case CB_COLOR3_CMASK: + case CB_COLOR4_CMASK: + case CB_COLOR5_CMASK: + case CB_COLOR6_CMASK: + case CB_COLOR7_CMASK: + tmp = (reg - CB_COLOR0_CMASK) / 0x3c; + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); + return -EINVAL; + } + ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + track->cb_color_cmask_bo[tmp] = reloc->robj; + break; + case CB_COLOR0_FMASK_SLICE: + case CB_COLOR1_FMASK_SLICE: + case CB_COLOR2_FMASK_SLICE: + case CB_COLOR3_FMASK_SLICE: + case CB_COLOR4_FMASK_SLICE: + case CB_COLOR5_FMASK_SLICE: + case CB_COLOR6_FMASK_SLICE: + case CB_COLOR7_FMASK_SLICE: + tmp = (reg - CB_COLOR0_FMASK_SLICE) / 0x3c; + track->cb_color_fmask_slice[tmp] = radeon_get_ib_value(p, idx); + break; + case CB_COLOR0_CMASK_SLICE: + case CB_COLOR1_CMASK_SLICE: + case CB_COLOR2_CMASK_SLICE: + case CB_COLOR3_CMASK_SLICE: + case CB_COLOR4_CMASK_SLICE: + case CB_COLOR5_CMASK_SLICE: + case CB_COLOR6_CMASK_SLICE: + case CB_COLOR7_CMASK_SLICE: + tmp = (reg - CB_COLOR0_CMASK_SLICE) / 0x3c; + track->cb_color_cmask_slice[tmp] = radeon_get_ib_value(p, idx); + break; + case CB_COLOR0_BASE: + case CB_COLOR1_BASE: + case CB_COLOR2_BASE: + case CB_COLOR3_BASE: + case CB_COLOR4_BASE: + case CB_COLOR5_BASE: + case CB_COLOR6_BASE: + case CB_COLOR7_BASE: + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + dev_warn(p->dev, "bad SET_CONTEXT_REG " + "0x%04X\n", reg); + return -EINVAL; + } + tmp = (reg - CB_COLOR0_BASE) / 0x3c; + track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx); + ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + track->cb_color_base_last[tmp] = ib[idx]; + track->cb_color_bo[tmp] = reloc->robj; + break; + case CB_COLOR8_BASE: + case CB_COLOR9_BASE: + case CB_COLOR10_BASE: + case CB_COLOR11_BASE: + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + dev_warn(p->dev, "bad SET_CONTEXT_REG " + "0x%04X\n", reg); + return -EINVAL; + } + tmp = ((reg - CB_COLOR8_BASE) / 0x1c) + 8; + track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx); + ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + track->cb_color_base_last[tmp] = ib[idx]; + track->cb_color_bo[tmp] = reloc->robj; + break; + case CB_IMMED0_BASE: + case CB_IMMED1_BASE: + case CB_IMMED2_BASE: + case CB_IMMED3_BASE: + case CB_IMMED4_BASE: + case CB_IMMED5_BASE: + case CB_IMMED6_BASE: + case CB_IMMED7_BASE: + case CB_IMMED8_BASE: + case CB_IMMED9_BASE: + case CB_IMMED10_BASE: + case CB_IMMED11_BASE: + case DB_HTILE_DATA_BASE: + case SQ_PGM_START_FS: + case SQ_PGM_START_ES: + case SQ_PGM_START_VS: + case SQ_PGM_START_GS: + case SQ_PGM_START_PS: + case SQ_PGM_START_HS: + case SQ_PGM_START_LS: + case GDS_ADDR_BASE: + case SQ_CONST_MEM_BASE: + case SQ_ALU_CONST_CACHE_GS_0: + case SQ_ALU_CONST_CACHE_GS_1: + case SQ_ALU_CONST_CACHE_GS_2: + case SQ_ALU_CONST_CACHE_GS_3: + case SQ_ALU_CONST_CACHE_GS_4: + case SQ_ALU_CONST_CACHE_GS_5: + case SQ_ALU_CONST_CACHE_GS_6: + case SQ_ALU_CONST_CACHE_GS_7: + case SQ_ALU_CONST_CACHE_GS_8: + case SQ_ALU_CONST_CACHE_GS_9: + case SQ_ALU_CONST_CACHE_GS_10: + case SQ_ALU_CONST_CACHE_GS_11: + case SQ_ALU_CONST_CACHE_GS_12: + case SQ_ALU_CONST_CACHE_GS_13: + case SQ_ALU_CONST_CACHE_GS_14: + case SQ_ALU_CONST_CACHE_GS_15: + case SQ_ALU_CONST_CACHE_PS_0: + case SQ_ALU_CONST_CACHE_PS_1: + case SQ_ALU_CONST_CACHE_PS_2: + case SQ_ALU_CONST_CACHE_PS_3: + case SQ_ALU_CONST_CACHE_PS_4: + case SQ_ALU_CONST_CACHE_PS_5: + case SQ_ALU_CONST_CACHE_PS_6: + case SQ_ALU_CONST_CACHE_PS_7: + case SQ_ALU_CONST_CACHE_PS_8: + case SQ_ALU_CONST_CACHE_PS_9: + case SQ_ALU_CONST_CACHE_PS_10: + case SQ_ALU_CONST_CACHE_PS_11: + case SQ_ALU_CONST_CACHE_PS_12: + case SQ_ALU_CONST_CACHE_PS_13: + case SQ_ALU_CONST_CACHE_PS_14: + case SQ_ALU_CONST_CACHE_PS_15: + case SQ_ALU_CONST_CACHE_VS_0: + case SQ_ALU_CONST_CACHE_VS_1: + case SQ_ALU_CONST_CACHE_VS_2: + case SQ_ALU_CONST_CACHE_VS_3: + case SQ_ALU_CONST_CACHE_VS_4: + case SQ_ALU_CONST_CACHE_VS_5: + case SQ_ALU_CONST_CACHE_VS_6: + case SQ_ALU_CONST_CACHE_VS_7: + case SQ_ALU_CONST_CACHE_VS_8: + case SQ_ALU_CONST_CACHE_VS_9: + case SQ_ALU_CONST_CACHE_VS_10: + case SQ_ALU_CONST_CACHE_VS_11: + case SQ_ALU_CONST_CACHE_VS_12: + case SQ_ALU_CONST_CACHE_VS_13: + case SQ_ALU_CONST_CACHE_VS_14: + case SQ_ALU_CONST_CACHE_VS_15: + case SQ_ALU_CONST_CACHE_HS_0: + case SQ_ALU_CONST_CACHE_HS_1: + case SQ_ALU_CONST_CACHE_HS_2: + case SQ_ALU_CONST_CACHE_HS_3: + case SQ_ALU_CONST_CACHE_HS_4: + case SQ_ALU_CONST_CACHE_HS_5: + case SQ_ALU_CONST_CACHE_HS_6: + case SQ_ALU_CONST_CACHE_HS_7: + case SQ_ALU_CONST_CACHE_HS_8: + case SQ_ALU_CONST_CACHE_HS_9: + case SQ_ALU_CONST_CACHE_HS_10: + case SQ_ALU_CONST_CACHE_HS_11: + case SQ_ALU_CONST_CACHE_HS_12: + case SQ_ALU_CONST_CACHE_HS_13: + case SQ_ALU_CONST_CACHE_HS_14: + case SQ_ALU_CONST_CACHE_HS_15: + case SQ_ALU_CONST_CACHE_LS_0: + case SQ_ALU_CONST_CACHE_LS_1: + case SQ_ALU_CONST_CACHE_LS_2: + case SQ_ALU_CONST_CACHE_LS_3: + case SQ_ALU_CONST_CACHE_LS_4: + case SQ_ALU_CONST_CACHE_LS_5: + case SQ_ALU_CONST_CACHE_LS_6: + case SQ_ALU_CONST_CACHE_LS_7: + case SQ_ALU_CONST_CACHE_LS_8: + case SQ_ALU_CONST_CACHE_LS_9: + case SQ_ALU_CONST_CACHE_LS_10: + case SQ_ALU_CONST_CACHE_LS_11: + case SQ_ALU_CONST_CACHE_LS_12: + case SQ_ALU_CONST_CACHE_LS_13: + case SQ_ALU_CONST_CACHE_LS_14: + case SQ_ALU_CONST_CACHE_LS_15: + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + dev_warn(p->dev, "bad SET_CONTEXT_REG " + "0x%04X\n", reg); + return -EINVAL; + } + ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + break; + default: + dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); + return -EINVAL; + } + return 0; +} + +/** + * evergreen_check_texture_resource() - check if register is authorized or not + * @p: parser structure holding parsing context + * @idx: index into the cs buffer + * @texture: texture's bo structure + * @mipmap: mipmap's bo structure + * + * This function will check that the resource has valid field and that + * the texture and mipmap bo object are big enough to cover this resource. + */ +static inline int evergreen_check_texture_resource(struct radeon_cs_parser *p, u32 idx, + struct radeon_bo *texture, + struct radeon_bo *mipmap) +{ + /* XXX fill in */ + return 0; +} + +static int evergreen_packet3_check(struct radeon_cs_parser *p, + struct radeon_cs_packet *pkt) +{ + struct radeon_cs_reloc *reloc; + struct evergreen_cs_track *track; + volatile u32 *ib; + unsigned idx; + unsigned i; + unsigned start_reg, end_reg, reg; + int r; + u32 idx_value; + + track = (struct evergreen_cs_track *)p->track; + ib = p->ib->ptr; + idx = pkt->idx + 1; + idx_value = radeon_get_ib_value(p, idx); + + switch (pkt->opcode) { + case PACKET3_CONTEXT_CONTROL: + if (pkt->count != 1) { + DRM_ERROR("bad CONTEXT_CONTROL\n"); + return -EINVAL; + } + break; + case PACKET3_INDEX_TYPE: + case PACKET3_NUM_INSTANCES: + case PACKET3_CLEAR_STATE: + if (pkt->count) { + DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES/CLEAR_STATE\n"); + return -EINVAL; + } + break; + case PACKET3_INDEX_BASE: + if (pkt->count != 1) { + DRM_ERROR("bad INDEX_BASE\n"); + return -EINVAL; + } + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + DRM_ERROR("bad INDEX_BASE\n"); + return -EINVAL; + } + ib[idx+0] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff); + ib[idx+1] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; + r = evergreen_cs_track_check(p); + if (r) { + dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); + return r; + } + break; + case PACKET3_DRAW_INDEX: + if (pkt->count != 3) { + DRM_ERROR("bad DRAW_INDEX\n"); + return -EINVAL; + } + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + DRM_ERROR("bad DRAW_INDEX\n"); + return -EINVAL; + } + ib[idx+0] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff); + ib[idx+1] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; + r = evergreen_cs_track_check(p); + if (r) { + dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); + return r; + } + break; + case PACKET3_DRAW_INDEX_2: + if (pkt->count != 4) { + DRM_ERROR("bad DRAW_INDEX_2\n"); + return -EINVAL; + } + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + DRM_ERROR("bad DRAW_INDEX_2\n"); + return -EINVAL; + } + ib[idx+1] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff); + ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; + r = evergreen_cs_track_check(p); + if (r) { + dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); + return r; + } + break; + case PACKET3_DRAW_INDEX_AUTO: + if (pkt->count != 1) { + DRM_ERROR("bad DRAW_INDEX_AUTO\n"); + return -EINVAL; + } + r = evergreen_cs_track_check(p); + if (r) { + dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx); + return r; + } + break; + case PACKET3_DRAW_INDEX_MULTI_AUTO: + if (pkt->count != 2) { + DRM_ERROR("bad DRAW_INDEX_MULTI_AUTO\n"); + return -EINVAL; + } + r = evergreen_cs_track_check(p); + if (r) { + dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx); + return r; + } + break; + case PACKET3_DRAW_INDEX_IMMD: + if (pkt->count < 2) { + DRM_ERROR("bad DRAW_INDEX_IMMD\n"); + return -EINVAL; + } + r = evergreen_cs_track_check(p); + if (r) { + dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); + return r; + } + break; + case PACKET3_DRAW_INDEX_OFFSET: + if (pkt->count != 2) { + DRM_ERROR("bad DRAW_INDEX_OFFSET\n"); + return -EINVAL; + } + r = evergreen_cs_track_check(p); + if (r) { + dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); + return r; + } + break; + case PACKET3_DRAW_INDEX_OFFSET_2: + if (pkt->count != 3) { + DRM_ERROR("bad DRAW_INDEX_OFFSET_2\n"); + return -EINVAL; + } + r = evergreen_cs_track_check(p); + if (r) { + dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); + return r; + } + break; + case PACKET3_WAIT_REG_MEM: + if (pkt->count != 5) { + DRM_ERROR("bad WAIT_REG_MEM\n"); + return -EINVAL; + } + /* bit 4 is reg (0) or mem (1) */ + if (idx_value & 0x10) { + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + DRM_ERROR("bad WAIT_REG_MEM\n"); + return -EINVAL; + } + ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); + ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; + } + break; + case PACKET3_SURFACE_SYNC: + if (pkt->count != 3) { + DRM_ERROR("bad SURFACE_SYNC\n"); + return -EINVAL; + } + /* 0xffffffff/0x0 is flush all cache flag */ + if (radeon_get_ib_value(p, idx + 1) != 0xffffffff || + radeon_get_ib_value(p, idx + 2) != 0) { + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + DRM_ERROR("bad SURFACE_SYNC\n"); + return -EINVAL; + } + ib[idx+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + } + break; + case PACKET3_EVENT_WRITE: + if (pkt->count != 2 && pkt->count != 0) { + DRM_ERROR("bad EVENT_WRITE\n"); + return -EINVAL; + } + if (pkt->count) { + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + DRM_ERROR("bad EVENT_WRITE\n"); + return -EINVAL; + } + ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); + ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; + } + break; + case PACKET3_EVENT_WRITE_EOP: + if (pkt->count != 4) { + DRM_ERROR("bad EVENT_WRITE_EOP\n"); + return -EINVAL; + } + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + DRM_ERROR("bad EVENT_WRITE_EOP\n"); + return -EINVAL; + } + ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); + ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; + break; + case PACKET3_EVENT_WRITE_EOS: + if (pkt->count != 3) { + DRM_ERROR("bad EVENT_WRITE_EOS\n"); + return -EINVAL; + } + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + DRM_ERROR("bad EVENT_WRITE_EOS\n"); + return -EINVAL; + } + ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); + ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; + break; + case PACKET3_SET_CONFIG_REG: + start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_START; + end_reg = 4 * pkt->count + start_reg - 4; + if ((start_reg < PACKET3_SET_CONFIG_REG_START) || + (start_reg >= PACKET3_SET_CONFIG_REG_END) || + (end_reg >= PACKET3_SET_CONFIG_REG_END)) { + DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n"); + return -EINVAL; + } + for (i = 0; i < pkt->count; i++) { + reg = start_reg + (4 * i); + r = evergreen_cs_check_reg(p, reg, idx+1+i); + if (r) + return r; + } + break; + case PACKET3_SET_CONTEXT_REG: + start_reg = (idx_value << 2) + PACKET3_SET_CONTEXT_REG_START; + end_reg = 4 * pkt->count + start_reg - 4; + if ((start_reg < PACKET3_SET_CONTEXT_REG_START) || + (start_reg >= PACKET3_SET_CONTEXT_REG_END) || + (end_reg >= PACKET3_SET_CONTEXT_REG_END)) { + DRM_ERROR("bad PACKET3_SET_CONTEXT_REG\n"); + return -EINVAL; + } + for (i = 0; i < pkt->count; i++) { + reg = start_reg + (4 * i); + r = evergreen_cs_check_reg(p, reg, idx+1+i); + if (r) + return r; + } + break; + case PACKET3_SET_RESOURCE: + if (pkt->count % 8) { + DRM_ERROR("bad SET_RESOURCE\n"); + return -EINVAL; + } + start_reg = (idx_value << 2) + PACKET3_SET_RESOURCE_START; + end_reg = 4 * pkt->count + start_reg - 4; + if ((start_reg < PACKET3_SET_RESOURCE_START) || + (start_reg >= PACKET3_SET_RESOURCE_END) || + (end_reg >= PACKET3_SET_RESOURCE_END)) { + DRM_ERROR("bad SET_RESOURCE\n"); + return -EINVAL; + } + for (i = 0; i < (pkt->count / 8); i++) { + struct radeon_bo *texture, *mipmap; + u32 size, offset; + + switch (G__SQ_CONSTANT_TYPE(radeon_get_ib_value(p, idx+1+(i*8)+7))) { + case SQ_TEX_VTX_VALID_TEXTURE: + /* tex base */ + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + DRM_ERROR("bad SET_RESOURCE (tex)\n"); + return -EINVAL; + } + ib[idx+1+(i*8)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) + ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1); + else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) + ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1); + texture = reloc->robj; + /* tex mip base */ + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + DRM_ERROR("bad SET_RESOURCE (tex)\n"); + return -EINVAL; + } + ib[idx+1+(i*8)+4] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + mipmap = reloc->robj; + r = evergreen_check_texture_resource(p, idx+1+(i*8), + texture, mipmap); + if (r) + return r; + break; + case SQ_TEX_VTX_VALID_BUFFER: + /* vtx base */ + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + DRM_ERROR("bad SET_RESOURCE (vtx)\n"); + return -EINVAL; + } + offset = radeon_get_ib_value(p, idx+1+(i*8)+0); + size = radeon_get_ib_value(p, idx+1+(i*8)+1); + if (p->rdev && (size + offset) > radeon_bo_size(reloc->robj)) { + /* force size to size of the buffer */ + dev_warn(p->dev, "vbo resource seems too big for the bo\n"); + ib[idx+1+(i*8)+1] = radeon_bo_size(reloc->robj); + } + ib[idx+1+(i*8)+0] += (u32)((reloc->lobj.gpu_offset) & 0xffffffff); + ib[idx+1+(i*8)+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; + break; + case SQ_TEX_VTX_INVALID_TEXTURE: + case SQ_TEX_VTX_INVALID_BUFFER: + default: + DRM_ERROR("bad SET_RESOURCE\n"); + return -EINVAL; + } + } + break; + case PACKET3_SET_ALU_CONST: + /* XXX fix me ALU const buffers only */ + break; + case PACKET3_SET_BOOL_CONST: + start_reg = (idx_value << 2) + PACKET3_SET_BOOL_CONST_START; + end_reg = 4 * pkt->count + start_reg - 4; + if ((start_reg < PACKET3_SET_BOOL_CONST_START) || + (start_reg >= PACKET3_SET_BOOL_CONST_END) || + (end_reg >= PACKET3_SET_BOOL_CONST_END)) { + DRM_ERROR("bad SET_BOOL_CONST\n"); + return -EINVAL; + } + break; + case PACKET3_SET_LOOP_CONST: + start_reg = (idx_value << 2) + PACKET3_SET_LOOP_CONST_START; + end_reg = 4 * pkt->count + start_reg - 4; + if ((start_reg < PACKET3_SET_LOOP_CONST_START) || + (start_reg >= PACKET3_SET_LOOP_CONST_END) || + (end_reg >= PACKET3_SET_LOOP_CONST_END)) { + DRM_ERROR("bad SET_LOOP_CONST\n"); + return -EINVAL; + } + break; + case PACKET3_SET_CTL_CONST: + start_reg = (idx_value << 2) + PACKET3_SET_CTL_CONST_START; + end_reg = 4 * pkt->count + start_reg - 4; + if ((start_reg < PACKET3_SET_CTL_CONST_START) || + (start_reg >= PACKET3_SET_CTL_CONST_END) || + (end_reg >= PACKET3_SET_CTL_CONST_END)) { + DRM_ERROR("bad SET_CTL_CONST\n"); + return -EINVAL; + } + break; + case PACKET3_SET_SAMPLER: + if (pkt->count % 3) { + DRM_ERROR("bad SET_SAMPLER\n"); + return -EINVAL; + } + start_reg = (idx_value << 2) + PACKET3_SET_SAMPLER_START; + end_reg = 4 * pkt->count + start_reg - 4; + if ((start_reg < PACKET3_SET_SAMPLER_START) || + (start_reg >= PACKET3_SET_SAMPLER_END) || + (end_reg >= PACKET3_SET_SAMPLER_END)) { + DRM_ERROR("bad SET_SAMPLER\n"); + return -EINVAL; + } + break; + case PACKET3_NOP: + break; + default: + DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode); + return -EINVAL; + } + return 0; +} + +int evergreen_cs_parse(struct radeon_cs_parser *p) +{ + struct radeon_cs_packet pkt; + struct evergreen_cs_track *track; + int r; + + if (p->track == NULL) { + /* initialize tracker, we are in kms */ + track = kzalloc(sizeof(*track), GFP_KERNEL); + if (track == NULL) + return -ENOMEM; + evergreen_cs_track_init(track); + track->npipes = p->rdev->config.evergreen.tiling_npipes; + track->nbanks = p->rdev->config.evergreen.tiling_nbanks; + track->group_size = p->rdev->config.evergreen.tiling_group_size; + p->track = track; + } + do { + r = evergreen_cs_packet_parse(p, &pkt, p->idx); + if (r) { + kfree(p->track); + p->track = NULL; + return r; + } + p->idx += pkt.count + 2; + switch (pkt.type) { + case PACKET_TYPE0: + r = evergreen_cs_parse_packet0(p, &pkt); + break; + case PACKET_TYPE2: + break; + case PACKET_TYPE3: + r = evergreen_packet3_check(p, &pkt); + break; + default: + DRM_ERROR("Unknown packet type %d !\n", pkt.type); + kfree(p->track); + p->track = NULL; + return -EINVAL; + } + if (r) { + kfree(p->track); + p->track = NULL; + return r; + } + } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); +#if 0 + for (r = 0; r < p->ib->length_dw; r++) { + printk(KERN_INFO "%05d 0x%08X\n", r, p->ib->ptr[r]); + mdelay(1); + } +#endif + kfree(p->track); + p->track = NULL; + return 0; +} + diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h index af86af836f13..e028c1cd9d9b 100644 --- a/drivers/gpu/drm/radeon/evergreen_reg.h +++ b/drivers/gpu/drm/radeon/evergreen_reg.h @@ -151,6 +151,9 @@ #define EVERGREEN_DATA_FORMAT 0x6b00 # define EVERGREEN_INTERLEAVE_EN (1 << 0) #define EVERGREEN_DESKTOP_HEIGHT 0x6b04 +#define EVERGREEN_VLINE_START_END 0x6b08 +#define EVERGREEN_VLINE_STATUS 0x6bb8 +# define EVERGREEN_VLINE_STAT (1 << 12) #define EVERGREEN_VIEWPORT_START 0x6d70 #define EVERGREEN_VIEWPORT_SIZE 0x6d74 diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 93e9e17ad54a..79683f6b4452 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -218,6 +218,8 @@ #define CLIP_VTX_REORDER_ENA (1 << 0) #define NUM_CLIP_SEQ(x) ((x) << 1) #define PA_SC_AA_CONFIG 0x28C04 +#define MSAA_NUM_SAMPLES_SHIFT 0 +#define MSAA_NUM_SAMPLES_MASK 0x3 #define PA_SC_CLIPRECT_RULE 0x2820C #define PA_SC_EDGERULE 0x28230 #define PA_SC_FIFO_SIZE 0x8BCC @@ -553,4 +555,466 @@ # define DC_HPDx_RX_INT_TIMER(x) ((x) << 16) # define DC_HPDx_EN (1 << 28) +/* + * PM4 + */ +#define PACKET_TYPE0 0 +#define PACKET_TYPE1 1 +#define PACKET_TYPE2 2 +#define PACKET_TYPE3 3 + +#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) +#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) +#define CP_PACKET0_GET_REG(h) (((h) & 0xFFFF) << 2) +#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) +#define PACKET0(reg, n) ((PACKET_TYPE0 << 30) | \ + (((reg) >> 2) & 0xFFFF) | \ + ((n) & 0x3FFF) << 16) +#define CP_PACKET2 0x80000000 +#define PACKET2_PAD_SHIFT 0 +#define PACKET2_PAD_MASK (0x3fffffff << 0) + +#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v))) + +#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \ + (((op) & 0xFF) << 8) | \ + ((n) & 0x3FFF) << 16) + +/* Packet 3 types */ +#define PACKET3_NOP 0x10 +#define PACKET3_SET_BASE 0x11 +#define PACKET3_CLEAR_STATE 0x12 +#define PACKET3_INDIRECT_BUFFER_SIZE 0x13 +#define PACKET3_DISPATCH_DIRECT 0x15 +#define PACKET3_DISPATCH_INDIRECT 0x16 +#define PACKET3_INDIRECT_BUFFER_END 0x17 +#define PACKET3_SET_PREDICATION 0x20 +#define PACKET3_REG_RMW 0x21 +#define PACKET3_COND_EXEC 0x22 +#define PACKET3_PRED_EXEC 0x23 +#define PACKET3_DRAW_INDIRECT 0x24 +#define PACKET3_DRAW_INDEX_INDIRECT 0x25 +#define PACKET3_INDEX_BASE 0x26 +#define PACKET3_DRAW_INDEX_2 0x27 +#define PACKET3_CONTEXT_CONTROL 0x28 +#define PACKET3_DRAW_INDEX_OFFSET 0x29 +#define PACKET3_INDEX_TYPE 0x2A +#define PACKET3_DRAW_INDEX 0x2B +#define PACKET3_DRAW_INDEX_AUTO 0x2D +#define PACKET3_DRAW_INDEX_IMMD 0x2E +#define PACKET3_NUM_INSTANCES 0x2F +#define PACKET3_DRAW_INDEX_MULTI_AUTO 0x30 +#define PACKET3_STRMOUT_BUFFER_UPDATE 0x34 +#define PACKET3_DRAW_INDEX_OFFSET_2 0x35 +#define PACKET3_DRAW_INDEX_MULTI_ELEMENT 0x36 +#define PACKET3_MEM_SEMAPHORE 0x39 +#define PACKET3_MPEG_INDEX 0x3A +#define PACKET3_WAIT_REG_MEM 0x3C +#define PACKET3_MEM_WRITE 0x3D +#define PACKET3_INDIRECT_BUFFER 0x32 +#define PACKET3_SURFACE_SYNC 0x43 +# define PACKET3_CB0_DEST_BASE_ENA (1 << 6) +# define PACKET3_CB1_DEST_BASE_ENA (1 << 7) +# define PACKET3_CB2_DEST_BASE_ENA (1 << 8) +# define PACKET3_CB3_DEST_BASE_ENA (1 << 9) +# define PACKET3_CB4_DEST_BASE_ENA (1 << 10) +# define PACKET3_CB5_DEST_BASE_ENA (1 << 11) +# define PACKET3_CB6_DEST_BASE_ENA (1 << 12) +# define PACKET3_CB7_DEST_BASE_ENA (1 << 13) +# define PACKET3_DB_DEST_BASE_ENA (1 << 14) +# define PACKET3_CB8_DEST_BASE_ENA (1 << 15) +# define PACKET3_CB9_DEST_BASE_ENA (1 << 16) +# define PACKET3_CB10_DEST_BASE_ENA (1 << 17) +# define PACKET3_CB11_DEST_BASE_ENA (1 << 17) +# define PACKET3_FULL_CACHE_ENA (1 << 20) +# define PACKET3_TC_ACTION_ENA (1 << 23) +# define PACKET3_VC_ACTION_ENA (1 << 24) +# define PACKET3_CB_ACTION_ENA (1 << 25) +# define PACKET3_DB_ACTION_ENA (1 << 26) +# define PACKET3_SH_ACTION_ENA (1 << 27) +# define PACKET3_SMX_ACTION_ENA (1 << 28) +#define PACKET3_ME_INITIALIZE 0x44 +#define PACKET3_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) +#define PACKET3_COND_WRITE 0x45 +#define PACKET3_EVENT_WRITE 0x46 +#define PACKET3_EVENT_WRITE_EOP 0x47 +#define PACKET3_EVENT_WRITE_EOS 0x48 +#define PACKET3_PREAMBLE_CNTL 0x4A +#define PACKET3_RB_OFFSET 0x4B +#define PACKET3_ALU_PS_CONST_BUFFER_COPY 0x4C +#define PACKET3_ALU_VS_CONST_BUFFER_COPY 0x4D +#define PACKET3_ALU_PS_CONST_UPDATE 0x4E +#define PACKET3_ALU_VS_CONST_UPDATE 0x4F +#define PACKET3_ONE_REG_WRITE 0x57 +#define PACKET3_SET_CONFIG_REG 0x68 +#define PACKET3_SET_CONFIG_REG_START 0x00008000 +#define PACKET3_SET_CONFIG_REG_END 0x0000ac00 +#define PACKET3_SET_CONTEXT_REG 0x69 +#define PACKET3_SET_CONTEXT_REG_START 0x00028000 +#define PACKET3_SET_CONTEXT_REG_END 0x00029000 +#define PACKET3_SET_ALU_CONST 0x6A +/* alu const buffers only; no reg file */ +#define PACKET3_SET_BOOL_CONST 0x6B +#define PACKET3_SET_BOOL_CONST_START 0x0003a500 +#define PACKET3_SET_BOOL_CONST_END 0x0003a518 +#define PACKET3_SET_LOOP_CONST 0x6C +#define PACKET3_SET_LOOP_CONST_START 0x0003a200 +#define PACKET3_SET_LOOP_CONST_END 0x0003a500 +#define PACKET3_SET_RESOURCE 0x6D +#define PACKET3_SET_RESOURCE_START 0x00030000 +#define PACKET3_SET_RESOURCE_END 0x00038000 +#define PACKET3_SET_SAMPLER 0x6E +#define PACKET3_SET_SAMPLER_START 0x0003c000 +#define PACKET3_SET_SAMPLER_END 0x0003c600 +#define PACKET3_SET_CTL_CONST 0x6F +#define PACKET3_SET_CTL_CONST_START 0x0003cff0 +#define PACKET3_SET_CTL_CONST_END 0x0003ff0c +#define PACKET3_SET_RESOURCE_OFFSET 0x70 +#define PACKET3_SET_ALU_CONST_VS 0x71 +#define PACKET3_SET_ALU_CONST_DI 0x72 +#define PACKET3_SET_CONTEXT_REG_INDIRECT 0x73 +#define PACKET3_SET_RESOURCE_INDIRECT 0x74 +#define PACKET3_SET_APPEND_CNT 0x75 + +#define SQ_RESOURCE_CONSTANT_WORD7_0 0x3001c +#define S__SQ_CONSTANT_TYPE(x) (((x) & 3) << 30) +#define G__SQ_CONSTANT_TYPE(x) (((x) >> 30) & 3) +#define SQ_TEX_VTX_INVALID_TEXTURE 0x0 +#define SQ_TEX_VTX_INVALID_BUFFER 0x1 +#define SQ_TEX_VTX_VALID_TEXTURE 0x2 +#define SQ_TEX_VTX_VALID_BUFFER 0x3 + +#define SQ_CONST_MEM_BASE 0x8df8 + +#define SQ_ESGS_RING_SIZE 0x8c44 +#define SQ_GSVS_RING_SIZE 0x8c4c +#define SQ_ESTMP_RING_SIZE 0x8c54 +#define SQ_GSTMP_RING_SIZE 0x8c5c +#define SQ_VSTMP_RING_SIZE 0x8c64 +#define SQ_PSTMP_RING_SIZE 0x8c6c +#define SQ_LSTMP_RING_SIZE 0x8e14 +#define SQ_HSTMP_RING_SIZE 0x8e1c +#define VGT_TF_RING_SIZE 0x8988 + +#define SQ_ESGS_RING_ITEMSIZE 0x28900 +#define SQ_GSVS_RING_ITEMSIZE 0x28904 +#define SQ_ESTMP_RING_ITEMSIZE 0x28908 +#define SQ_GSTMP_RING_ITEMSIZE 0x2890c +#define SQ_VSTMP_RING_ITEMSIZE 0x28910 +#define SQ_PSTMP_RING_ITEMSIZE 0x28914 +#define SQ_LSTMP_RING_ITEMSIZE 0x28830 +#define SQ_HSTMP_RING_ITEMSIZE 0x28834 + +#define SQ_GS_VERT_ITEMSIZE 0x2891c +#define SQ_GS_VERT_ITEMSIZE_1 0x28920 +#define SQ_GS_VERT_ITEMSIZE_2 0x28924 +#define SQ_GS_VERT_ITEMSIZE_3 0x28928 +#define SQ_GSVS_RING_OFFSET_1 0x2892c +#define SQ_GSVS_RING_OFFSET_2 0x28930 +#define SQ_GSVS_RING_OFFSET_3 0x28934 + +#define SQ_ALU_CONST_CACHE_PS_0 0x28940 +#define SQ_ALU_CONST_CACHE_PS_1 0x28944 +#define SQ_ALU_CONST_CACHE_PS_2 0x28948 +#define SQ_ALU_CONST_CACHE_PS_3 0x2894c +#define SQ_ALU_CONST_CACHE_PS_4 0x28950 +#define SQ_ALU_CONST_CACHE_PS_5 0x28954 +#define SQ_ALU_CONST_CACHE_PS_6 0x28958 +#define SQ_ALU_CONST_CACHE_PS_7 0x2895c +#define SQ_ALU_CONST_CACHE_PS_8 0x28960 +#define SQ_ALU_CONST_CACHE_PS_9 0x28964 +#define SQ_ALU_CONST_CACHE_PS_10 0x28968 +#define SQ_ALU_CONST_CACHE_PS_11 0x2896c +#define SQ_ALU_CONST_CACHE_PS_12 0x28970 +#define SQ_ALU_CONST_CACHE_PS_13 0x28974 +#define SQ_ALU_CONST_CACHE_PS_14 0x28978 +#define SQ_ALU_CONST_CACHE_PS_15 0x2897c +#define SQ_ALU_CONST_CACHE_VS_0 0x28980 +#define SQ_ALU_CONST_CACHE_VS_1 0x28984 +#define SQ_ALU_CONST_CACHE_VS_2 0x28988 +#define SQ_ALU_CONST_CACHE_VS_3 0x2898c +#define SQ_ALU_CONST_CACHE_VS_4 0x28990 +#define SQ_ALU_CONST_CACHE_VS_5 0x28994 +#define SQ_ALU_CONST_CACHE_VS_6 0x28998 +#define SQ_ALU_CONST_CACHE_VS_7 0x2899c +#define SQ_ALU_CONST_CACHE_VS_8 0x289a0 +#define SQ_ALU_CONST_CACHE_VS_9 0x289a4 +#define SQ_ALU_CONST_CACHE_VS_10 0x289a8 +#define SQ_ALU_CONST_CACHE_VS_11 0x289ac +#define SQ_ALU_CONST_CACHE_VS_12 0x289b0 +#define SQ_ALU_CONST_CACHE_VS_13 0x289b4 +#define SQ_ALU_CONST_CACHE_VS_14 0x289b8 +#define SQ_ALU_CONST_CACHE_VS_15 0x289bc +#define SQ_ALU_CONST_CACHE_GS_0 0x289c0 +#define SQ_ALU_CONST_CACHE_GS_1 0x289c4 +#define SQ_ALU_CONST_CACHE_GS_2 0x289c8 +#define SQ_ALU_CONST_CACHE_GS_3 0x289cc +#define SQ_ALU_CONST_CACHE_GS_4 0x289d0 +#define SQ_ALU_CONST_CACHE_GS_5 0x289d4 +#define SQ_ALU_CONST_CACHE_GS_6 0x289d8 +#define SQ_ALU_CONST_CACHE_GS_7 0x289dc +#define SQ_ALU_CONST_CACHE_GS_8 0x289e0 +#define SQ_ALU_CONST_CACHE_GS_9 0x289e4 +#define SQ_ALU_CONST_CACHE_GS_10 0x289e8 +#define SQ_ALU_CONST_CACHE_GS_11 0x289ec +#define SQ_ALU_CONST_CACHE_GS_12 0x289f0 +#define SQ_ALU_CONST_CACHE_GS_13 0x289f4 +#define SQ_ALU_CONST_CACHE_GS_14 0x289f8 +#define SQ_ALU_CONST_CACHE_GS_15 0x289fc +#define SQ_ALU_CONST_CACHE_HS_0 0x28f00 +#define SQ_ALU_CONST_CACHE_HS_1 0x28f04 +#define SQ_ALU_CONST_CACHE_HS_2 0x28f08 +#define SQ_ALU_CONST_CACHE_HS_3 0x28f0c +#define SQ_ALU_CONST_CACHE_HS_4 0x28f10 +#define SQ_ALU_CONST_CACHE_HS_5 0x28f14 +#define SQ_ALU_CONST_CACHE_HS_6 0x28f18 +#define SQ_ALU_CONST_CACHE_HS_7 0x28f1c +#define SQ_ALU_CONST_CACHE_HS_8 0x28f20 +#define SQ_ALU_CONST_CACHE_HS_9 0x28f24 +#define SQ_ALU_CONST_CACHE_HS_10 0x28f28 +#define SQ_ALU_CONST_CACHE_HS_11 0x28f2c +#define SQ_ALU_CONST_CACHE_HS_12 0x28f30 +#define SQ_ALU_CONST_CACHE_HS_13 0x28f34 +#define SQ_ALU_CONST_CACHE_HS_14 0x28f38 +#define SQ_ALU_CONST_CACHE_HS_15 0x28f3c +#define SQ_ALU_CONST_CACHE_LS_0 0x28f40 +#define SQ_ALU_CONST_CACHE_LS_1 0x28f44 +#define SQ_ALU_CONST_CACHE_LS_2 0x28f48 +#define SQ_ALU_CONST_CACHE_LS_3 0x28f4c +#define SQ_ALU_CONST_CACHE_LS_4 0x28f50 +#define SQ_ALU_CONST_CACHE_LS_5 0x28f54 +#define SQ_ALU_CONST_CACHE_LS_6 0x28f58 +#define SQ_ALU_CONST_CACHE_LS_7 0x28f5c +#define SQ_ALU_CONST_CACHE_LS_8 0x28f60 +#define SQ_ALU_CONST_CACHE_LS_9 0x28f64 +#define SQ_ALU_CONST_CACHE_LS_10 0x28f68 +#define SQ_ALU_CONST_CACHE_LS_11 0x28f6c +#define SQ_ALU_CONST_CACHE_LS_12 0x28f70 +#define SQ_ALU_CONST_CACHE_LS_13 0x28f74 +#define SQ_ALU_CONST_CACHE_LS_14 0x28f78 +#define SQ_ALU_CONST_CACHE_LS_15 0x28f7c + +#define DB_DEPTH_CONTROL 0x28800 +#define DB_DEPTH_VIEW 0x28008 +#define DB_HTILE_DATA_BASE 0x28014 +#define DB_Z_INFO 0x28040 +# define Z_ARRAY_MODE(x) ((x) << 4) +#define DB_STENCIL_INFO 0x28044 +#define DB_Z_READ_BASE 0x28048 +#define DB_STENCIL_READ_BASE 0x2804c +#define DB_Z_WRITE_BASE 0x28050 +#define DB_STENCIL_WRITE_BASE 0x28054 +#define DB_DEPTH_SIZE 0x28058 + +#define SQ_PGM_START_PS 0x28840 +#define SQ_PGM_START_VS 0x2885c +#define SQ_PGM_START_GS 0x28874 +#define SQ_PGM_START_ES 0x2888c +#define SQ_PGM_START_FS 0x288a4 +#define SQ_PGM_START_HS 0x288b8 +#define SQ_PGM_START_LS 0x288d0 + +#define VGT_STRMOUT_CONFIG 0x28b94 +#define VGT_STRMOUT_BUFFER_CONFIG 0x28b98 + +#define CB_TARGET_MASK 0x28238 +#define CB_SHADER_MASK 0x2823c + +#define GDS_ADDR_BASE 0x28720 + +#define CB_IMMED0_BASE 0x28b9c +#define CB_IMMED1_BASE 0x28ba0 +#define CB_IMMED2_BASE 0x28ba4 +#define CB_IMMED3_BASE 0x28ba8 +#define CB_IMMED4_BASE 0x28bac +#define CB_IMMED5_BASE 0x28bb0 +#define CB_IMMED6_BASE 0x28bb4 +#define CB_IMMED7_BASE 0x28bb8 +#define CB_IMMED8_BASE 0x28bbc +#define CB_IMMED9_BASE 0x28bc0 +#define CB_IMMED10_BASE 0x28bc4 +#define CB_IMMED11_BASE 0x28bc8 + +/* all 12 CB blocks have these regs */ +#define CB_COLOR0_BASE 0x28c60 +#define CB_COLOR0_PITCH 0x28c64 +#define CB_COLOR0_SLICE 0x28c68 +#define CB_COLOR0_VIEW 0x28c6c +#define CB_COLOR0_INFO 0x28c70 +# define CB_ARRAY_MODE(x) ((x) << 8) +# define ARRAY_LINEAR_GENERAL 0 +# define ARRAY_LINEAR_ALIGNED 1 +# define ARRAY_1D_TILED_THIN1 2 +# define ARRAY_2D_TILED_THIN1 4 +#define CB_COLOR0_ATTRIB 0x28c74 +#define CB_COLOR0_DIM 0x28c78 +/* only CB0-7 blocks have these regs */ +#define CB_COLOR0_CMASK 0x28c7c +#define CB_COLOR0_CMASK_SLICE 0x28c80 +#define CB_COLOR0_FMASK 0x28c84 +#define CB_COLOR0_FMASK_SLICE 0x28c88 +#define CB_COLOR0_CLEAR_WORD0 0x28c8c +#define CB_COLOR0_CLEAR_WORD1 0x28c90 +#define CB_COLOR0_CLEAR_WORD2 0x28c94 +#define CB_COLOR0_CLEAR_WORD3 0x28c98 + +#define CB_COLOR1_BASE 0x28c9c +#define CB_COLOR2_BASE 0x28cd8 +#define CB_COLOR3_BASE 0x28d14 +#define CB_COLOR4_BASE 0x28d50 +#define CB_COLOR5_BASE 0x28d8c +#define CB_COLOR6_BASE 0x28dc8 +#define CB_COLOR7_BASE 0x28e04 +#define CB_COLOR8_BASE 0x28e40 +#define CB_COLOR9_BASE 0x28e5c +#define CB_COLOR10_BASE 0x28e78 +#define CB_COLOR11_BASE 0x28e94 + +#define CB_COLOR1_PITCH 0x28ca0 +#define CB_COLOR2_PITCH 0x28cdc +#define CB_COLOR3_PITCH 0x28d18 +#define CB_COLOR4_PITCH 0x28d54 +#define CB_COLOR5_PITCH 0x28d90 +#define CB_COLOR6_PITCH 0x28dcc +#define CB_COLOR7_PITCH 0x28e08 +#define CB_COLOR8_PITCH 0x28e44 +#define CB_COLOR9_PITCH 0x28e60 +#define CB_COLOR10_PITCH 0x28e7c +#define CB_COLOR11_PITCH 0x28e98 + +#define CB_COLOR1_SLICE 0x28ca4 +#define CB_COLOR2_SLICE 0x28ce0 +#define CB_COLOR3_SLICE 0x28d1c +#define CB_COLOR4_SLICE 0x28d58 +#define CB_COLOR5_SLICE 0x28d94 +#define CB_COLOR6_SLICE 0x28dd0 +#define CB_COLOR7_SLICE 0x28e0c +#define CB_COLOR8_SLICE 0x28e48 +#define CB_COLOR9_SLICE 0x28e64 +#define CB_COLOR10_SLICE 0x28e80 +#define CB_COLOR11_SLICE 0x28e9c + +#define CB_COLOR1_VIEW 0x28ca8 +#define CB_COLOR2_VIEW 0x28ce4 +#define CB_COLOR3_VIEW 0x28d20 +#define CB_COLOR4_VIEW 0x28d5c +#define CB_COLOR5_VIEW 0x28d98 +#define CB_COLOR6_VIEW 0x28dd4 +#define CB_COLOR7_VIEW 0x28e10 +#define CB_COLOR8_VIEW 0x28e4c +#define CB_COLOR9_VIEW 0x28e68 +#define CB_COLOR10_VIEW 0x28e84 +#define CB_COLOR11_VIEW 0x28ea0 + +#define CB_COLOR1_INFO 0x28cac +#define CB_COLOR2_INFO 0x28ce8 +#define CB_COLOR3_INFO 0x28d24 +#define CB_COLOR4_INFO 0x28d60 +#define CB_COLOR5_INFO 0x28d9c +#define CB_COLOR6_INFO 0x28dd8 +#define CB_COLOR7_INFO 0x28e14 +#define CB_COLOR8_INFO 0x28e50 +#define CB_COLOR9_INFO 0x28e6c +#define CB_COLOR10_INFO 0x28e88 +#define CB_COLOR11_INFO 0x28ea4 + +#define CB_COLOR1_ATTRIB 0x28cb0 +#define CB_COLOR2_ATTRIB 0x28cec +#define CB_COLOR3_ATTRIB 0x28d28 +#define CB_COLOR4_ATTRIB 0x28d64 +#define CB_COLOR5_ATTRIB 0x28da0 +#define CB_COLOR6_ATTRIB 0x28ddc +#define CB_COLOR7_ATTRIB 0x28e18 +#define CB_COLOR8_ATTRIB 0x28e54 +#define CB_COLOR9_ATTRIB 0x28e70 +#define CB_COLOR10_ATTRIB 0x28e8c +#define CB_COLOR11_ATTRIB 0x28ea8 + +#define CB_COLOR1_DIM 0x28cb4 +#define CB_COLOR2_DIM 0x28cf0 +#define CB_COLOR3_DIM 0x28d2c +#define CB_COLOR4_DIM 0x28d68 +#define CB_COLOR5_DIM 0x28da4 +#define CB_COLOR6_DIM 0x28de0 +#define CB_COLOR7_DIM 0x28e1c +#define CB_COLOR8_DIM 0x28e58 +#define CB_COLOR9_DIM 0x28e74 +#define CB_COLOR10_DIM 0x28e90 +#define CB_COLOR11_DIM 0x28eac + +#define CB_COLOR1_CMASK 0x28cb8 +#define CB_COLOR2_CMASK 0x28cf4 +#define CB_COLOR3_CMASK 0x28d30 +#define CB_COLOR4_CMASK 0x28d6c +#define CB_COLOR5_CMASK 0x28da8 +#define CB_COLOR6_CMASK 0x28de4 +#define CB_COLOR7_CMASK 0x28e20 + +#define CB_COLOR1_CMASK_SLICE 0x28cbc +#define CB_COLOR2_CMASK_SLICE 0x28cf8 +#define CB_COLOR3_CMASK_SLICE 0x28d34 +#define CB_COLOR4_CMASK_SLICE 0x28d70 +#define CB_COLOR5_CMASK_SLICE 0x28dac +#define CB_COLOR6_CMASK_SLICE 0x28de8 +#define CB_COLOR7_CMASK_SLICE 0x28e24 + +#define CB_COLOR1_FMASK 0x28cc0 +#define CB_COLOR2_FMASK 0x28cfc +#define CB_COLOR3_FMASK 0x28d38 +#define CB_COLOR4_FMASK 0x28d74 +#define CB_COLOR5_FMASK 0x28db0 +#define CB_COLOR6_FMASK 0x28dec +#define CB_COLOR7_FMASK 0x28e28 + +#define CB_COLOR1_FMASK_SLICE 0x28cc4 +#define CB_COLOR2_FMASK_SLICE 0x28d00 +#define CB_COLOR3_FMASK_SLICE 0x28d3c +#define CB_COLOR4_FMASK_SLICE 0x28d78 +#define CB_COLOR5_FMASK_SLICE 0x28db4 +#define CB_COLOR6_FMASK_SLICE 0x28df0 +#define CB_COLOR7_FMASK_SLICE 0x28e2c + +#define CB_COLOR1_CLEAR_WORD0 0x28cc8 +#define CB_COLOR2_CLEAR_WORD0 0x28d04 +#define CB_COLOR3_CLEAR_WORD0 0x28d40 +#define CB_COLOR4_CLEAR_WORD0 0x28d7c +#define CB_COLOR5_CLEAR_WORD0 0x28db8 +#define CB_COLOR6_CLEAR_WORD0 0x28df4 +#define CB_COLOR7_CLEAR_WORD0 0x28e30 + +#define CB_COLOR1_CLEAR_WORD1 0x28ccc +#define CB_COLOR2_CLEAR_WORD1 0x28d08 +#define CB_COLOR3_CLEAR_WORD1 0x28d44 +#define CB_COLOR4_CLEAR_WORD1 0x28d80 +#define CB_COLOR5_CLEAR_WORD1 0x28dbc +#define CB_COLOR6_CLEAR_WORD1 0x28df8 +#define CB_COLOR7_CLEAR_WORD1 0x28e34 + +#define CB_COLOR1_CLEAR_WORD2 0x28cd0 +#define CB_COLOR2_CLEAR_WORD2 0x28d0c +#define CB_COLOR3_CLEAR_WORD2 0x28d48 +#define CB_COLOR4_CLEAR_WORD2 0x28d84 +#define CB_COLOR5_CLEAR_WORD2 0x28dc0 +#define CB_COLOR6_CLEAR_WORD2 0x28dfc +#define CB_COLOR7_CLEAR_WORD2 0x28e38 + +#define CB_COLOR1_CLEAR_WORD3 0x28cd4 +#define CB_COLOR2_CLEAR_WORD3 0x28d10 +#define CB_COLOR3_CLEAR_WORD3 0x28d4c +#define CB_COLOR4_CLEAR_WORD3 0x28d88 +#define CB_COLOR5_CLEAR_WORD3 0x28dc4 +#define CB_COLOR6_CLEAR_WORD3 0x28e00 +#define CB_COLOR7_CLEAR_WORD3 0x28e3c + +#define SQ_TEX_RESOURCE_WORD0_0 0x30000 +#define SQ_TEX_RESOURCE_WORD1_0 0x30004 +# define TEX_ARRAY_MODE(x) ((x) << 28) +#define SQ_TEX_RESOURCE_WORD2_0 0x30008 +#define SQ_TEX_RESOURCE_WORD3_0 0x3000C +#define SQ_TEX_RESOURCE_WORD4_0 0x30010 +#define SQ_TEX_RESOURCE_WORD5_0 0x30014 +#define SQ_TEX_RESOURCE_WORD6_0 0x30018 +#define SQ_TEX_RESOURCE_WORD7_0 0x3001c + + #endif diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index e57df08d4aeb..87f7e2cc52d4 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -724,8 +724,8 @@ static struct radeon_asic evergreen_asic = { .irq_set = &evergreen_irq_set, .irq_process = &evergreen_irq_process, .get_vblank_counter = &evergreen_get_vblank_counter, - .fence_ring_emit = NULL, - .cs_parse = NULL, + .fence_ring_emit = &r600_fence_ring_emit, + .cs_parse = &evergreen_cs_parse, .copy_blit = NULL, .copy_dma = NULL, .copy = NULL, diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 5c40a3dfaca2..c0bbaa64157a 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -314,6 +314,7 @@ void evergreen_hpd_set_polarity(struct radeon_device *rdev, u32 evergreen_get_vblank_counter(struct radeon_device *rdev, int crtc); int evergreen_irq_set(struct radeon_device *rdev); int evergreen_irq_process(struct radeon_device *rdev); +extern int evergreen_cs_parse(struct radeon_cs_parser *p); extern void evergreen_pm_misc(struct radeon_device *rdev); extern void evergreen_pm_prepare(struct radeon_device *rdev); extern void evergreen_pm_finish(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/reg_srcs/evergreen b/drivers/gpu/drm/radeon/reg_srcs/evergreen new file mode 100644 index 000000000000..b5c757f68d3c --- /dev/null +++ b/drivers/gpu/drm/radeon/reg_srcs/evergreen @@ -0,0 +1,611 @@ +evergreen 0x9400 +0x00008040 WAIT_UNTIL +0x00008044 WAIT_UNTIL_POLL_CNTL +0x00008048 WAIT_UNTIL_POLL_MASK +0x0000804c WAIT_UNTIL_POLL_REFDATA +0x000088B0 VGT_VTX_VECT_EJECT_REG +0x000088C4 VGT_CACHE_INVALIDATION +0x000088D4 VGT_GS_VERTEX_REUSE +0x00008958 VGT_PRIMITIVE_TYPE +0x0000895C VGT_INDEX_TYPE +0x00008970 VGT_NUM_INDICES +0x00008974 VGT_NUM_INSTANCES +0x00008990 VGT_COMPUTE_DIM_X +0x00008994 VGT_COMPUTE_DIM_Y +0x00008998 VGT_COMPUTE_DIM_Z +0x0000899C VGT_COMPUTE_START_X +0x000089A0 VGT_COMPUTE_START_Y +0x000089A4 VGT_COMPUTE_START_Z +0x000089AC VGT_COMPUTE_THREAD_GOURP_SIZE +0x00008A14 PA_CL_ENHANCE +0x00008A60 PA_SC_LINE_STIPPLE_VALUE +0x00008B10 PA_SC_LINE_STIPPLE_STATE +0x00008BF0 PA_SC_ENHANCE +0x00008D8C SQ_DYN_GPR_CNTL_PS_FLUSH_REQ +0x00008C00 SQ_CONFIG +0x00008C04 SQ_GPR_RESOURCE_MGMT_1 +0x00008C08 SQ_GPR_RESOURCE_MGMT_2 +0x00008C0C SQ_GPR_RESOURCE_MGMT_3 +0x00008C10 SQ_GLOBAL_GPR_RESOURCE_MGMT_1 +0x00008C14 SQ_GLOBAL_GPR_RESOURCE_MGMT_2 +0x00008C18 SQ_THREAD_RESOURCE_MGMT +0x00008C1C SQ_THREAD_RESOURCE_MGMT_2 +0x00008C20 SQ_STACK_RESOURCE_MGMT_1 +0x00008C24 SQ_STACK_RESOURCE_MGMT_2 +0x00008C28 SQ_STACK_RESOURCE_MGMT_3 +0x00008DF8 SQ_CONST_MEM_BASE +0x00008E48 SQ_EX_ALLOC_TABLE_SLOTS +0x00009100 SPI_CONFIG_CNTL +0x0000913C SPI_CONFIG_CNTL_1 +0x00009700 VC_CNTL +0x00009714 VC_ENHANCE +0x00009830 DB_DEBUG +0x00009834 DB_DEBUG2 +0x00009838 DB_DEBUG3 +0x0000983C DB_DEBUG4 +0x00009854 DB_WATERMARKS +0x0000A400 TD_PS_BORDER_COLOR_INDEX +0x0000A404 TD_PS_BORDER_COLOR_RED +0x0000A408 TD_PS_BORDER_COLOR_GREEN +0x0000A40C TD_PS_BORDER_COLOR_BLUE +0x0000A410 TD_PS_BORDER_COLOR_ALPHA +0x0000A414 TD_VS_BORDER_COLOR_INDEX +0x0000A418 TD_VS_BORDER_COLOR_RED +0x0000A41C TD_VS_BORDER_COLOR_GREEN +0x0000A420 TD_VS_BORDER_COLOR_BLUE +0x0000A424 TD_VS_BORDER_COLOR_ALPHA +0x0000A428 TD_GS_BORDER_COLOR_INDEX +0x0000A42C TD_GS_BORDER_COLOR_RED +0x0000A430 TD_GS_BORDER_COLOR_GREEN +0x0000A434 TD_GS_BORDER_COLOR_BLUE +0x0000A438 TD_GS_BORDER_COLOR_ALPHA +0x0000A43C TD_HS_BORDER_COLOR_INDEX +0x0000A440 TD_HS_BORDER_COLOR_RED +0x0000A444 TD_HS_BORDER_COLOR_GREEN +0x0000A448 TD_HS_BORDER_COLOR_BLUE +0x0000A44C TD_HS_BORDER_COLOR_ALPHA +0x0000A450 TD_LS_BORDER_COLOR_INDEX +0x0000A454 TD_LS_BORDER_COLOR_RED +0x0000A458 TD_LS_BORDER_COLOR_GREEN +0x0000A45C TD_LS_BORDER_COLOR_BLUE +0x0000A460 TD_LS_BORDER_COLOR_ALPHA +0x0000A464 TD_CS_BORDER_COLOR_INDEX +0x0000A468 TD_CS_BORDER_COLOR_RED +0x0000A46C TD_CS_BORDER_COLOR_GREEN +0x0000A470 TD_CS_BORDER_COLOR_BLUE +0x0000A474 TD_CS_BORDER_COLOR_ALPHA +0x00028000 DB_RENDER_CONTROL +0x00028004 DB_COUNT_CONTROL +0x0002800C DB_RENDER_OVERRIDE +0x00028010 DB_RENDER_OVERRIDE2 +0x00028028 DB_STENCIL_CLEAR +0x0002802C DB_DEPTH_CLEAR +0x00028034 PA_SC_SCREEN_SCISSOR_BR +0x00028030 PA_SC_SCREEN_SCISSOR_TL +0x0002805C DB_DEPTH_SLICE +0x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0 +0x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1 +0x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2 +0x0002814C SQ_ALU_CONST_BUFFER_SIZE_PS_3 +0x00028150 SQ_ALU_CONST_BUFFER_SIZE_PS_4 +0x00028154 SQ_ALU_CONST_BUFFER_SIZE_PS_5 +0x00028158 SQ_ALU_CONST_BUFFER_SIZE_PS_6 +0x0002815C SQ_ALU_CONST_BUFFER_SIZE_PS_7 +0x00028160 SQ_ALU_CONST_BUFFER_SIZE_PS_8 +0x00028164 SQ_ALU_CONST_BUFFER_SIZE_PS_9 +0x00028168 SQ_ALU_CONST_BUFFER_SIZE_PS_10 +0x0002816C SQ_ALU_CONST_BUFFER_SIZE_PS_11 +0x00028170 SQ_ALU_CONST_BUFFER_SIZE_PS_12 +0x00028174 SQ_ALU_CONST_BUFFER_SIZE_PS_13 +0x00028178 SQ_ALU_CONST_BUFFER_SIZE_PS_14 +0x0002817C SQ_ALU_CONST_BUFFER_SIZE_PS_15 +0x00028180 SQ_ALU_CONST_BUFFER_SIZE_VS_0 +0x00028184 SQ_ALU_CONST_BUFFER_SIZE_VS_1 +0x00028188 SQ_ALU_CONST_BUFFER_SIZE_VS_2 +0x0002818C SQ_ALU_CONST_BUFFER_SIZE_VS_3 +0x00028190 SQ_ALU_CONST_BUFFER_SIZE_VS_4 +0x00028194 SQ_ALU_CONST_BUFFER_SIZE_VS_5 +0x00028198 SQ_ALU_CONST_BUFFER_SIZE_VS_6 +0x0002819C SQ_ALU_CONST_BUFFER_SIZE_VS_7 +0x000281A0 SQ_ALU_CONST_BUFFER_SIZE_VS_8 +0x000281A4 SQ_ALU_CONST_BUFFER_SIZE_VS_9 +0x000281A8 SQ_ALU_CONST_BUFFER_SIZE_VS_10 +0x000281AC SQ_ALU_CONST_BUFFER_SIZE_VS_11 +0x000281B0 SQ_ALU_CONST_BUFFER_SIZE_VS_12 +0x000281B4 SQ_ALU_CONST_BUFFER_SIZE_VS_13 +0x000281B8 SQ_ALU_CONST_BUFFER_SIZE_VS_14 +0x000281BC SQ_ALU_CONST_BUFFER_SIZE_VS_15 +0x000281C0 SQ_ALU_CONST_BUFFER_SIZE_GS_0 +0x000281C4 SQ_ALU_CONST_BUFFER_SIZE_GS_1 +0x000281C8 SQ_ALU_CONST_BUFFER_SIZE_GS_2 +0x000281CC SQ_ALU_CONST_BUFFER_SIZE_GS_3 +0x000281D0 SQ_ALU_CONST_BUFFER_SIZE_GS_4 +0x000281D4 SQ_ALU_CONST_BUFFER_SIZE_GS_5 +0x000281D8 SQ_ALU_CONST_BUFFER_SIZE_GS_6 +0x000281DC SQ_ALU_CONST_BUFFER_SIZE_GS_7 +0x000281E0 SQ_ALU_CONST_BUFFER_SIZE_GS_8 +0x000281E4 SQ_ALU_CONST_BUFFER_SIZE_GS_9 +0x000281E8 SQ_ALU_CONST_BUFFER_SIZE_GS_10 +0x000281EC SQ_ALU_CONST_BUFFER_SIZE_GS_11 +0x000281F0 SQ_ALU_CONST_BUFFER_SIZE_GS_12 +0x000281F4 SQ_ALU_CONST_BUFFER_SIZE_GS_13 +0x000281F8 SQ_ALU_CONST_BUFFER_SIZE_GS_14 +0x000281FC SQ_ALU_CONST_BUFFER_SIZE_GS_15 +0x00028200 PA_SC_WINDOW_OFFSET +0x00028204 PA_SC_WINDOW_SCISSOR_TL +0x00028208 PA_SC_WINDOW_SCISSOR_BR +0x0002820C PA_SC_CLIPRECT_RULE +0x00028210 PA_SC_CLIPRECT_0_TL +0x00028214 PA_SC_CLIPRECT_0_BR +0x00028218 PA_SC_CLIPRECT_1_TL +0x0002821C PA_SC_CLIPRECT_1_BR +0x00028220 PA_SC_CLIPRECT_2_TL +0x00028224 PA_SC_CLIPRECT_2_BR +0x00028228 PA_SC_CLIPRECT_3_TL +0x0002822C PA_SC_CLIPRECT_3_BR +0x00028230 PA_SC_EDGERULE +0x00028234 PA_SU_HARDWARE_SCREEN_OFFSET +0x00028240 PA_SC_GENERIC_SCISSOR_TL +0x00028244 PA_SC_GENERIC_SCISSOR_BR +0x00028250 PA_SC_VPORT_SCISSOR_0_TL +0x00028254 PA_SC_VPORT_SCISSOR_0_BR +0x00028258 PA_SC_VPORT_SCISSOR_1_TL +0x0002825C PA_SC_VPORT_SCISSOR_1_BR +0x00028260 PA_SC_VPORT_SCISSOR_2_TL +0x00028264 PA_SC_VPORT_SCISSOR_2_BR +0x00028268 PA_SC_VPORT_SCISSOR_3_TL +0x0002826C PA_SC_VPORT_SCISSOR_3_BR +0x00028270 PA_SC_VPORT_SCISSOR_4_TL +0x00028274 PA_SC_VPORT_SCISSOR_4_BR +0x00028278 PA_SC_VPORT_SCISSOR_5_TL +0x0002827C PA_SC_VPORT_SCISSOR_5_BR +0x00028280 PA_SC_VPORT_SCISSOR_6_TL +0x00028284 PA_SC_VPORT_SCISSOR_6_BR +0x00028288 PA_SC_VPORT_SCISSOR_7_TL +0x0002828C PA_SC_VPORT_SCISSOR_7_BR +0x00028290 PA_SC_VPORT_SCISSOR_8_TL +0x00028294 PA_SC_VPORT_SCISSOR_8_BR +0x00028298 PA_SC_VPORT_SCISSOR_9_TL +0x0002829C PA_SC_VPORT_SCISSOR_9_BR +0x000282A0 PA_SC_VPORT_SCISSOR_10_TL +0x000282A4 PA_SC_VPORT_SCISSOR_10_BR +0x000282A8 PA_SC_VPORT_SCISSOR_11_TL +0x000282AC PA_SC_VPORT_SCISSOR_11_BR +0x000282B0 PA_SC_VPORT_SCISSOR_12_TL +0x000282B4 PA_SC_VPORT_SCISSOR_12_BR +0x000282B8 PA_SC_VPORT_SCISSOR_13_TL +0x000282BC PA_SC_VPORT_SCISSOR_13_BR +0x000282C0 PA_SC_VPORT_SCISSOR_14_TL +0x000282C4 PA_SC_VPORT_SCISSOR_14_BR +0x000282C8 PA_SC_VPORT_SCISSOR_15_TL +0x000282CC PA_SC_VPORT_SCISSOR_15_BR +0x000282D0 PA_SC_VPORT_ZMIN_0 +0x000282D4 PA_SC_VPORT_ZMAX_0 +0x000282D8 PA_SC_VPORT_ZMIN_1 +0x000282DC PA_SC_VPORT_ZMAX_1 +0x000282E0 PA_SC_VPORT_ZMIN_2 +0x000282E4 PA_SC_VPORT_ZMAX_2 +0x000282E8 PA_SC_VPORT_ZMIN_3 +0x000282EC PA_SC_VPORT_ZMAX_3 +0x000282F0 PA_SC_VPORT_ZMIN_4 +0x000282F4 PA_SC_VPORT_ZMAX_4 +0x000282F8 PA_SC_VPORT_ZMIN_5 +0x000282FC PA_SC_VPORT_ZMAX_5 +0x00028300 PA_SC_VPORT_ZMIN_6 +0x00028304 PA_SC_VPORT_ZMAX_6 +0x00028308 PA_SC_VPORT_ZMIN_7 +0x0002830C PA_SC_VPORT_ZMAX_7 +0x00028310 PA_SC_VPORT_ZMIN_8 +0x00028314 PA_SC_VPORT_ZMAX_8 +0x00028318 PA_SC_VPORT_ZMIN_9 +0x0002831C PA_SC_VPORT_ZMAX_9 +0x00028320 PA_SC_VPORT_ZMIN_10 +0x00028324 PA_SC_VPORT_ZMAX_10 +0x00028328 PA_SC_VPORT_ZMIN_11 +0x0002832C PA_SC_VPORT_ZMAX_11 +0x00028330 PA_SC_VPORT_ZMIN_12 +0x00028334 PA_SC_VPORT_ZMAX_12 +0x00028338 PA_SC_VPORT_ZMIN_13 +0x0002833C PA_SC_VPORT_ZMAX_13 +0x00028340 PA_SC_VPORT_ZMIN_14 +0x00028344 PA_SC_VPORT_ZMAX_14 +0x00028348 PA_SC_VPORT_ZMIN_15 +0x0002834C PA_SC_VPORT_ZMAX_15 +0x00028350 SX_MISC +0x00028380 SQ_VTX_SEMANTIC_0 +0x00028384 SQ_VTX_SEMANTIC_1 +0x00028388 SQ_VTX_SEMANTIC_2 +0x0002838C SQ_VTX_SEMANTIC_3 +0x00028390 SQ_VTX_SEMANTIC_4 +0x00028394 SQ_VTX_SEMANTIC_5 +0x00028398 SQ_VTX_SEMANTIC_6 +0x0002839C SQ_VTX_SEMANTIC_7 +0x000283A0 SQ_VTX_SEMANTIC_8 +0x000283A4 SQ_VTX_SEMANTIC_9 +0x000283A8 SQ_VTX_SEMANTIC_10 +0x000283AC SQ_VTX_SEMANTIC_11 +0x000283B0 SQ_VTX_SEMANTIC_12 +0x000283B4 SQ_VTX_SEMANTIC_13 +0x000283B8 SQ_VTX_SEMANTIC_14 +0x000283BC SQ_VTX_SEMANTIC_15 +0x000283C0 SQ_VTX_SEMANTIC_16 +0x000283C4 SQ_VTX_SEMANTIC_17 +0x000283C8 SQ_VTX_SEMANTIC_18 +0x000283CC SQ_VTX_SEMANTIC_19 +0x000283D0 SQ_VTX_SEMANTIC_20 +0x000283D4 SQ_VTX_SEMANTIC_21 +0x000283D8 SQ_VTX_SEMANTIC_22 +0x000283DC SQ_VTX_SEMANTIC_23 +0x000283E0 SQ_VTX_SEMANTIC_24 +0x000283E4 SQ_VTX_SEMANTIC_25 +0x000283E8 SQ_VTX_SEMANTIC_26 +0x000283EC SQ_VTX_SEMANTIC_27 +0x000283F0 SQ_VTX_SEMANTIC_28 +0x000283F4 SQ_VTX_SEMANTIC_29 +0x000283F8 SQ_VTX_SEMANTIC_30 +0x000283FC SQ_VTX_SEMANTIC_31 +0x00028400 VGT_MAX_VTX_INDX +0x00028404 VGT_MIN_VTX_INDX +0x00028408 VGT_INDX_OFFSET +0x0002840C VGT_MULTI_PRIM_IB_RESET_INDX +0x00028410 SX_ALPHA_TEST_CONTROL +0x00028414 CB_BLEND_RED +0x00028418 CB_BLEND_GREEN +0x0002841C CB_BLEND_BLUE +0x00028420 CB_BLEND_ALPHA +0x00028430 DB_STENCILREFMASK +0x00028434 DB_STENCILREFMASK_BF +0x00028438 SX_ALPHA_REF +0x0002843C PA_CL_VPORT_XSCALE_0 +0x00028440 PA_CL_VPORT_XOFFSET_0 +0x00028444 PA_CL_VPORT_YSCALE_0 +0x00028448 PA_CL_VPORT_YOFFSET_0 +0x0002844C PA_CL_VPORT_ZSCALE_0 +0x00028450 PA_CL_VPORT_ZOFFSET_0 +0x00028454 PA_CL_VPORT_XSCALE_1 +0x00028458 PA_CL_VPORT_XOFFSET_1 +0x0002845C PA_CL_VPORT_YSCALE_1 +0x00028460 PA_CL_VPORT_YOFFSET_1 +0x00028464 PA_CL_VPORT_ZSCALE_1 +0x00028468 PA_CL_VPORT_ZOFFSET_1 +0x0002846C PA_CL_VPORT_XSCALE_2 +0x00028470 PA_CL_VPORT_XOFFSET_2 +0x00028474 PA_CL_VPORT_YSCALE_2 +0x00028478 PA_CL_VPORT_YOFFSET_2 +0x0002847C PA_CL_VPORT_ZSCALE_2 +0x00028480 PA_CL_VPORT_ZOFFSET_2 +0x00028484 PA_CL_VPORT_XSCALE_3 +0x00028488 PA_CL_VPORT_XOFFSET_3 +0x0002848C PA_CL_VPORT_YSCALE_3 +0x00028490 PA_CL_VPORT_YOFFSET_3 +0x00028494 PA_CL_VPORT_ZSCALE_3 +0x00028498 PA_CL_VPORT_ZOFFSET_3 +0x0002849C PA_CL_VPORT_XSCALE_4 +0x000284A0 PA_CL_VPORT_XOFFSET_4 +0x000284A4 PA_CL_VPORT_YSCALE_4 +0x000284A8 PA_CL_VPORT_YOFFSET_4 +0x000284AC PA_CL_VPORT_ZSCALE_4 +0x000284B0 PA_CL_VPORT_ZOFFSET_4 +0x000284B4 PA_CL_VPORT_XSCALE_5 +0x000284B8 PA_CL_VPORT_XOFFSET_5 +0x000284BC PA_CL_VPORT_YSCALE_5 +0x000284C0 PA_CL_VPORT_YOFFSET_5 +0x000284C4 PA_CL_VPORT_ZSCALE_5 +0x000284C8 PA_CL_VPORT_ZOFFSET_5 +0x000284CC PA_CL_VPORT_XSCALE_6 +0x000284D0 PA_CL_VPORT_XOFFSET_6 +0x000284D4 PA_CL_VPORT_YSCALE_6 +0x000284D8 PA_CL_VPORT_YOFFSET_6 +0x000284DC PA_CL_VPORT_ZSCALE_6 +0x000284E0 PA_CL_VPORT_ZOFFSET_6 +0x000284E4 PA_CL_VPORT_XSCALE_7 +0x000284E8 PA_CL_VPORT_XOFFSET_7 +0x000284EC PA_CL_VPORT_YSCALE_7 +0x000284F0 PA_CL_VPORT_YOFFSET_7 +0x000284F4 PA_CL_VPORT_ZSCALE_7 +0x000284F8 PA_CL_VPORT_ZOFFSET_7 +0x000284FC PA_CL_VPORT_XSCALE_8 +0x00028500 PA_CL_VPORT_XOFFSET_8 +0x00028504 PA_CL_VPORT_YSCALE_8 +0x00028508 PA_CL_VPORT_YOFFSET_8 +0x0002850C PA_CL_VPORT_ZSCALE_8 +0x00028510 PA_CL_VPORT_ZOFFSET_8 +0x00028514 PA_CL_VPORT_XSCALE_9 +0x00028518 PA_CL_VPORT_XOFFSET_9 +0x0002851C PA_CL_VPORT_YSCALE_9 +0x00028520 PA_CL_VPORT_YOFFSET_9 +0x00028524 PA_CL_VPORT_ZSCALE_9 +0x00028528 PA_CL_VPORT_ZOFFSET_9 +0x0002852C PA_CL_VPORT_XSCALE_10 +0x00028530 PA_CL_VPORT_XOFFSET_10 +0x00028534 PA_CL_VPORT_YSCALE_10 +0x00028538 PA_CL_VPORT_YOFFSET_10 +0x0002853C PA_CL_VPORT_ZSCALE_10 +0x00028540 PA_CL_VPORT_ZOFFSET_10 +0x00028544 PA_CL_VPORT_XSCALE_11 +0x00028548 PA_CL_VPORT_XOFFSET_11 +0x0002854C PA_CL_VPORT_YSCALE_11 +0x00028550 PA_CL_VPORT_YOFFSET_11 +0x00028554 PA_CL_VPORT_ZSCALE_11 +0x00028558 PA_CL_VPORT_ZOFFSET_11 +0x0002855C PA_CL_VPORT_XSCALE_12 +0x00028560 PA_CL_VPORT_XOFFSET_12 +0x00028564 PA_CL_VPORT_YSCALE_12 +0x00028568 PA_CL_VPORT_YOFFSET_12 +0x0002856C PA_CL_VPORT_ZSCALE_12 +0x00028570 PA_CL_VPORT_ZOFFSET_12 +0x00028574 PA_CL_VPORT_XSCALE_13 +0x00028578 PA_CL_VPORT_XOFFSET_13 +0x0002857C PA_CL_VPORT_YSCALE_13 +0x00028580 PA_CL_VPORT_YOFFSET_13 +0x00028584 PA_CL_VPORT_ZSCALE_13 +0x00028588 PA_CL_VPORT_ZOFFSET_13 +0x0002858C PA_CL_VPORT_XSCALE_14 +0x00028590 PA_CL_VPORT_XOFFSET_14 +0x00028594 PA_CL_VPORT_YSCALE_14 +0x00028598 PA_CL_VPORT_YOFFSET_14 +0x0002859C PA_CL_VPORT_ZSCALE_14 +0x000285A0 PA_CL_VPORT_ZOFFSET_14 +0x000285A4 PA_CL_VPORT_XSCALE_15 +0x000285A8 PA_CL_VPORT_XOFFSET_15 +0x000285AC PA_CL_VPORT_YSCALE_15 +0x000285B0 PA_CL_VPORT_YOFFSET_15 +0x000285B4 PA_CL_VPORT_ZSCALE_15 +0x000285B8 PA_CL_VPORT_ZOFFSET_15 +0x000285BC PA_CL_UCP_0_X +0x000285C0 PA_CL_UCP_0_Y +0x000285C4 PA_CL_UCP_0_Z +0x000285C8 PA_CL_UCP_0_W +0x000285CC PA_CL_UCP_1_X +0x000285D0 PA_CL_UCP_1_Y +0x000285D4 PA_CL_UCP_1_Z +0x000285D8 PA_CL_UCP_1_W +0x000285DC PA_CL_UCP_2_X +0x000285E0 PA_CL_UCP_2_Y +0x000285E4 PA_CL_UCP_2_Z +0x000285E8 PA_CL_UCP_2_W +0x000285EC PA_CL_UCP_3_X +0x000285F0 PA_CL_UCP_3_Y +0x000285F4 PA_CL_UCP_3_Z +0x000285F8 PA_CL_UCP_3_W +0x000285FC PA_CL_UCP_4_X +0x00028600 PA_CL_UCP_4_Y +0x00028604 PA_CL_UCP_4_Z +0x00028608 PA_CL_UCP_4_W +0x0002860C PA_CL_UCP_5_X +0x00028610 PA_CL_UCP_5_Y +0x00028614 PA_CL_UCP_5_Z +0x00028618 PA_CL_UCP_5_W +0x0002861C SPI_VS_OUT_ID_0 +0x00028620 SPI_VS_OUT_ID_1 +0x00028624 SPI_VS_OUT_ID_2 +0x00028628 SPI_VS_OUT_ID_3 +0x0002862C SPI_VS_OUT_ID_4 +0x00028630 SPI_VS_OUT_ID_5 +0x00028634 SPI_VS_OUT_ID_6 +0x00028638 SPI_VS_OUT_ID_7 +0x0002863C SPI_VS_OUT_ID_8 +0x00028640 SPI_VS_OUT_ID_9 +0x00028644 SPI_PS_INPUT_CNTL_0 +0x00028648 SPI_PS_INPUT_CNTL_1 +0x0002864C SPI_PS_INPUT_CNTL_2 +0x00028650 SPI_PS_INPUT_CNTL_3 +0x00028654 SPI_PS_INPUT_CNTL_4 +0x00028658 SPI_PS_INPUT_CNTL_5 +0x0002865C SPI_PS_INPUT_CNTL_6 +0x00028660 SPI_PS_INPUT_CNTL_7 +0x00028664 SPI_PS_INPUT_CNTL_8 +0x00028668 SPI_PS_INPUT_CNTL_9 +0x0002866C SPI_PS_INPUT_CNTL_10 +0x00028670 SPI_PS_INPUT_CNTL_11 +0x00028674 SPI_PS_INPUT_CNTL_12 +0x00028678 SPI_PS_INPUT_CNTL_13 +0x0002867C SPI_PS_INPUT_CNTL_14 +0x00028680 SPI_PS_INPUT_CNTL_15 +0x00028684 SPI_PS_INPUT_CNTL_16 +0x00028688 SPI_PS_INPUT_CNTL_17 +0x0002868C SPI_PS_INPUT_CNTL_18 +0x00028690 SPI_PS_INPUT_CNTL_19 +0x00028694 SPI_PS_INPUT_CNTL_20 +0x00028698 SPI_PS_INPUT_CNTL_21 +0x0002869C SPI_PS_INPUT_CNTL_22 +0x000286A0 SPI_PS_INPUT_CNTL_23 +0x000286A4 SPI_PS_INPUT_CNTL_24 +0x000286A8 SPI_PS_INPUT_CNTL_25 +0x000286AC SPI_PS_INPUT_CNTL_26 +0x000286B0 SPI_PS_INPUT_CNTL_27 +0x000286B4 SPI_PS_INPUT_CNTL_28 +0x000286B8 SPI_PS_INPUT_CNTL_29 +0x000286BC SPI_PS_INPUT_CNTL_30 +0x000286C0 SPI_PS_INPUT_CNTL_31 +0x000286C4 SPI_VS_OUT_CONFIG +0x000286C8 SPI_THREAD_GROUPING +0x000286CC SPI_PS_IN_CONTROL_0 +0x000286D0 SPI_PS_IN_CONTROL_1 +0x000286D4 SPI_INTERP_CONTROL_0 +0x000286D8 SPI_INPUT_Z +0x000286DC SPI_FOG_CNTL +0x000286E0 SPI_BARYC_CNTL +0x000286E4 SPI_PS_IN_CONTROL_2 +0x000286E8 SPI_COMPUTE_INPUT_CNTL +0x000286EC SPI_COMPUTE_NUM_THREAD_X +0x000286F0 SPI_COMPUTE_NUM_THREAD_Y +0x000286F4 SPI_COMPUTE_NUM_THREAD_Z +0x000286F8 GDS_ADDR_SIZE +0x00028780 CB_BLEND0_CONTROL +0x00028784 CB_BLEND1_CONTROL +0x00028788 CB_BLEND2_CONTROL +0x0002878C CB_BLEND3_CONTROL +0x00028790 CB_BLEND4_CONTROL +0x00028794 CB_BLEND5_CONTROL +0x00028798 CB_BLEND6_CONTROL +0x0002879C CB_BLEND7_CONTROL +0x000287CC CS_COPY_STATE +0x000287D0 GFX_COPY_STATE +0x000287D4 PA_CL_POINT_X_RAD +0x000287D8 PA_CL_POINT_Y_RAD +0x000287DC PA_CL_POINT_SIZE +0x000287E0 PA_CL_POINT_CULL_RAD +0x00028808 CB_COLOR_CONTROL +0x0002880C DB_SHADER_CONTROL +0x00028810 PA_CL_CLIP_CNTL +0x00028814 PA_SU_SC_MODE_CNTL +0x00028818 PA_CL_VTE_CNTL +0x0002881C PA_CL_VS_OUT_CNTL +0x00028820 PA_CL_NANINF_CNTL +0x00028824 PA_SU_LINE_STIPPLE_CNTL +0x00028828 PA_SU_LINE_STIPPLE_SCALE +0x0002882C PA_SU_PRIM_FILTER_CNTL +0x00028838 SQ_DYN_GPR_RESOURCE_LIMIT_1 +0x00028844 SQ_PGM_RESOURCES_PS +0x00028848 SQ_PGM_RESOURCES_2_PS +0x0002884C SQ_PGM_EXPORTS_PS +0x0002885C SQ_PGM_RESOURCES_VS +0x00028860 SQ_PGM_RESOURCES_2_VS +0x00028878 SQ_PGM_RESOURCES_GS +0x0002887C SQ_PGM_RESOURCES_2_GS +0x00028890 SQ_PGM_RESOURCES_ES +0x00028894 SQ_PGM_RESOURCES_2_ES +0x000288A8 SQ_PGM_RESOURCES_FS +0x000288BC SQ_PGM_RESOURCES_HS +0x000288C0 SQ_PGM_RESOURCES_2_HS +0x000288D0 SQ_PGM_RESOURCES_LS +0x000288D4 SQ_PGM_RESOURCES_2_LS +0x000288E8 SQ_LDS_ALLOC +0x000288EC SQ_LDS_ALLOC_PS +0x000288F0 SQ_VTX_SEMANTIC_CLEAR +0x00028A00 PA_SU_POINT_SIZE +0x00028A04 PA_SU_POINT_MINMAX +0x00028A08 PA_SU_LINE_CNTL +0x00028A0C PA_SC_LINE_STIPPLE +0x00028A10 VGT_OUTPUT_PATH_CNTL +0x00028A14 VGT_HOS_CNTL +0x00028A18 VGT_HOS_MAX_TESS_LEVEL +0x00028A1C VGT_HOS_MIN_TESS_LEVEL +0x00028A20 VGT_HOS_REUSE_DEPTH +0x00028A24 VGT_GROUP_PRIM_TYPE +0x00028A28 VGT_GROUP_FIRST_DECR +0x00028A2C VGT_GROUP_DECR +0x00028A30 VGT_GROUP_VECT_0_CNTL +0x00028A34 VGT_GROUP_VECT_1_CNTL +0x00028A38 VGT_GROUP_VECT_0_FMT_CNTL +0x00028A3C VGT_GROUP_VECT_1_FMT_CNTL +0x00028A40 VGT_GS_MODE +0x00028A48 PA_SC_MODE_CNTL_0 +0x00028A4C PA_SC_MODE_CNTL_1 +0x00028A50 VGT_ENHANCE +0x00028A54 VGT_GS_PER_ES +0x00028A58 VGT_ES_PER_GS +0x00028A5C VGT_GS_PER_VS +0x00028A6C VGT_GS_OUT_PRIM_TYPE +0x00028A84 VGT_PRIMITIVEID_EN +0x00028A94 VGT_MULTI_PRIM_IB_RESET_EN +0x00028AA0 VGT_INSTANCE_STEP_RATE_0 +0x00028AA4 VGT_INSTANCE_STEP_RATE_1 +0x00028AB4 VGT_REUSE_OFF +0x00028AB8 VGT_VTX_CNT_EN +0x00028ABC DB_HTILE_SURFACE +0x00028AC0 DB_SRESULTS_COMPARE_STATE0 +0x00028AC4 DB_SRESULTS_COMPARE_STATE1 +0x00028AC8 DB_PRELOAD_CONTROL +0x00028B38 VGT_GS_MAX_VERT_OUT +0x00028B54 VGT_SHADER_STAGES_EN +0x00028B58 VGT_LS_HS_CONFIG +0x00028B5C VGT_LS_SIZE +0x00028B60 VGT_HS_SIZE +0x00028B64 VGT_LS_HS_ALLOC +0x00028B68 VGT_HS_PATCH_CONST +0x00028B6C VGT_TF_PARAM +0x00028B70 DB_ALPHA_TO_MASK +0x00028B74 VGT_DISPATCH_INITIATOR +0x00028B78 PA_SU_POLY_OFFSET_DB_FMT_CNTL +0x00028B7C PA_SU_POLY_OFFSET_CLAMP +0x00028B80 PA_SU_POLY_OFFSET_FRONT_SCALE +0x00028B84 PA_SU_POLY_OFFSET_FRONT_OFFSET +0x00028B88 PA_SU_POLY_OFFSET_BACK_SCALE +0x00028B8C PA_SU_POLY_OFFSET_BACK_OFFSET +0x00028B74 VGT_GS_INSTANCE_CNT +0x00028C00 PA_SC_LINE_CNTL +0x00028C08 PA_SU_VTX_CNTL +0x00028C0C PA_CL_GB_VERT_CLIP_ADJ +0x00028C10 PA_CL_GB_VERT_DISC_ADJ +0x00028C14 PA_CL_GB_HORZ_CLIP_ADJ +0x00028C18 PA_CL_GB_HORZ_DISC_ADJ +0x00028C1C PA_SC_AA_SAMPLE_LOCS_0 +0x00028C20 PA_SC_AA_SAMPLE_LOCS_1 +0x00028C24 PA_SC_AA_SAMPLE_LOCS_2 +0x00028C28 PA_SC_AA_SAMPLE_LOCS_3 +0x00028C2C PA_SC_AA_SAMPLE_LOCS_4 +0x00028C30 PA_SC_AA_SAMPLE_LOCS_5 +0x00028C34 PA_SC_AA_SAMPLE_LOCS_6 +0x00028C38 PA_SC_AA_SAMPLE_LOCS_7 +0x00028C3C PA_SC_AA_MASK +0x00028C8C CB_COLOR0_CLEAR_WORD0 +0x00028C90 CB_COLOR0_CLEAR_WORD1 +0x00028C94 CB_COLOR0_CLEAR_WORD2 +0x00028C98 CB_COLOR0_CLEAR_WORD3 +0x00028CC8 CB_COLOR1_CLEAR_WORD0 +0x00028CCC CB_COLOR1_CLEAR_WORD1 +0x00028CD0 CB_COLOR1_CLEAR_WORD2 +0x00028CD4 CB_COLOR1_CLEAR_WORD3 +0x00028D04 CB_COLOR2_CLEAR_WORD0 +0x00028D08 CB_COLOR2_CLEAR_WORD1 +0x00028D0C CB_COLOR2_CLEAR_WORD2 +0x00028D10 CB_COLOR2_CLEAR_WORD3 +0x00028D40 CB_COLOR3_CLEAR_WORD0 +0x00028D44 CB_COLOR3_CLEAR_WORD1 +0x00028D48 CB_COLOR3_CLEAR_WORD2 +0x00028D4C CB_COLOR3_CLEAR_WORD3 +0x00028D7C CB_COLOR4_CLEAR_WORD0 +0x00028D80 CB_COLOR4_CLEAR_WORD1 +0x00028D84 CB_COLOR4_CLEAR_WORD2 +0x00028D88 CB_COLOR4_CLEAR_WORD3 +0x00028DB8 CB_COLOR5_CLEAR_WORD0 +0x00028DBC CB_COLOR5_CLEAR_WORD1 +0x00028DC0 CB_COLOR5_CLEAR_WORD2 +0x00028DC4 CB_COLOR5_CLEAR_WORD3 +0x00028DF4 CB_COLOR6_CLEAR_WORD0 +0x00028DF8 CB_COLOR6_CLEAR_WORD1 +0x00028DFC CB_COLOR6_CLEAR_WORD2 +0x00028E00 CB_COLOR6_CLEAR_WORD3 +0x00028E30 CB_COLOR7_CLEAR_WORD0 +0x00028E34 CB_COLOR7_CLEAR_WORD1 +0x00028E38 CB_COLOR7_CLEAR_WORD2 +0x00028E3C CB_COLOR7_CLEAR_WORD3 +0x00028F80 SQ_ALU_CONST_BUFFER_SIZE_HS_0 +0x00028F84 SQ_ALU_CONST_BUFFER_SIZE_HS_1 +0x00028F88 SQ_ALU_CONST_BUFFER_SIZE_HS_2 +0x00028F8C SQ_ALU_CONST_BUFFER_SIZE_HS_3 +0x00028F90 SQ_ALU_CONST_BUFFER_SIZE_HS_4 +0x00028F94 SQ_ALU_CONST_BUFFER_SIZE_HS_5 +0x00028F98 SQ_ALU_CONST_BUFFER_SIZE_HS_6 +0x00028F9C SQ_ALU_CONST_BUFFER_SIZE_HS_7 +0x00028FA0 SQ_ALU_CONST_BUFFER_SIZE_HS_8 +0x00028FA4 SQ_ALU_CONST_BUFFER_SIZE_HS_9 +0x00028FA8 SQ_ALU_CONST_BUFFER_SIZE_HS_10 +0x00028FAC SQ_ALU_CONST_BUFFER_SIZE_HS_11 +0x00028FB0 SQ_ALU_CONST_BUFFER_SIZE_HS_12 +0x00028FB4 SQ_ALU_CONST_BUFFER_SIZE_HS_13 +0x00028FB8 SQ_ALU_CONST_BUFFER_SIZE_HS_14 +0x00028FBC SQ_ALU_CONST_BUFFER_SIZE_HS_15 +0x00028FC0 SQ_ALU_CONST_BUFFER_SIZE_LS_0 +0x00028FC4 SQ_ALU_CONST_BUFFER_SIZE_LS_1 +0x00028FC8 SQ_ALU_CONST_BUFFER_SIZE_LS_2 +0x00028FCC SQ_ALU_CONST_BUFFER_SIZE_LS_3 +0x00028FD0 SQ_ALU_CONST_BUFFER_SIZE_LS_4 +0x00028FD4 SQ_ALU_CONST_BUFFER_SIZE_LS_5 +0x00028FD8 SQ_ALU_CONST_BUFFER_SIZE_LS_6 +0x00028FDC SQ_ALU_CONST_BUFFER_SIZE_LS_7 +0x00028FE0 SQ_ALU_CONST_BUFFER_SIZE_LS_8 +0x00028FE4 SQ_ALU_CONST_BUFFER_SIZE_LS_9 +0x00028FE8 SQ_ALU_CONST_BUFFER_SIZE_LS_10 +0x00028FEC SQ_ALU_CONST_BUFFER_SIZE_LS_11 +0x00028FF0 SQ_ALU_CONST_BUFFER_SIZE_LS_12 +0x00028FF4 SQ_ALU_CONST_BUFFER_SIZE_LS_13 +0x00028FF8 SQ_ALU_CONST_BUFFER_SIZE_LS_14 +0x00028FFC SQ_ALU_CONST_BUFFER_SIZE_LS_15 +0x0003CFF0 SQ_VTX_BASE_VTX_LOC +0x0003CFF4 SQ_VTX_START_INST_LOC +0x0003FF00 SQ_TEX_SAMPLER_CLEAR +0x0003FF04 SQ_TEX_RESOURCE_CLEAR +0x0003FF08 SQ_LOOP_BOOL_CLEAR -- cgit v1.2.3 From 483d67ff0a208b43f0b97fca91d3a142afaba7fa Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 10 May 2010 03:51:02 -0300 Subject: V4L/DVB: bw-qcam: convert to V4L2 Note: due to lack of hardware I was not able to test this conversion. But it is pretty straightforward, so I do not expect any problems. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 2 +- drivers/media/video/bw-qcam.c | 759 +++++++++++++++++++++++------------------- drivers/media/video/bw-qcam.h | 69 ---- 3 files changed, 415 insertions(+), 415 deletions(-) delete mode 100644 drivers/media/video/bw-qcam.h (limited to 'drivers') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index ad9e6f9c22e9..42d198d5a87e 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -646,7 +646,7 @@ config VIDEO_PMS config VIDEO_BWQCAM tristate "Quickcam BW Video For Linux" - depends on PARPORT && VIDEO_V4L1 + depends on PARPORT && VIDEO_V4L2 help Say Y have if you the black and white version of the QuickCam camera. See the next option for the color version. diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index 3c9e754d73a0..935e0c9a9674 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c @@ -66,19 +66,58 @@ OTHER DEALINGS IN THE SOFTWARE. #include #include #include -#include #include #include #include #include #include -#include -#include -#include +#include +#include #include #include - -#include "bw-qcam.h" +#include +#include +#include + +/* One from column A... */ +#define QC_NOTSET 0 +#define QC_UNIDIR 1 +#define QC_BIDIR 2 +#define QC_SERIAL 3 + +/* ... and one from column B */ +#define QC_ANY 0x00 +#define QC_FORCE_UNIDIR 0x10 +#define QC_FORCE_BIDIR 0x20 +#define QC_FORCE_SERIAL 0x30 +/* in the port_mode member */ + +#define QC_MODE_MASK 0x07 +#define QC_FORCE_MASK 0x70 + +#define MAX_HEIGHT 243 +#define MAX_WIDTH 336 + +/* Bit fields for status flags */ +#define QC_PARAM_CHANGE 0x01 /* Camera status change has occurred */ + +struct qcam { + struct v4l2_device v4l2_dev; + struct video_device vdev; + struct pardevice *pdev; + struct parport *pport; + struct mutex lock; + int width, height; + int bpp; + int mode; + int contrast, brightness, whitebal; + int port_mode; + int transfer_scale; + int top, left; + int status; + unsigned int saved_bits; + unsigned long in_use; +}; static unsigned int maxpoll = 250; /* Maximum busy-loop count for qcam I/O */ static unsigned int yieldlines = 4; /* Yield after this many during capture */ @@ -93,22 +132,26 @@ module_param(video_nr, int, 0); * immediately attempt to initialize qcam */ module_param(force_init, int, 0); -static inline int read_lpstatus(struct qcam_device *q) +#define MAX_CAMS 4 +static struct qcam *qcams[MAX_CAMS]; +static unsigned int num_cams; + +static inline int read_lpstatus(struct qcam *q) { return parport_read_status(q->pport); } -static inline int read_lpdata(struct qcam_device *q) +static inline int read_lpdata(struct qcam *q) { return parport_read_data(q->pport); } -static inline void write_lpdata(struct qcam_device *q, int d) +static inline void write_lpdata(struct qcam *q, int d) { parport_write_data(q->pport, d); } -static inline void write_lpcontrol(struct qcam_device *q, int d) +static void write_lpcontrol(struct qcam *q, int d) { if (d & 0x20) { /* Set bidirectional mode to reverse (data in) */ @@ -124,126 +167,11 @@ static inline void write_lpcontrol(struct qcam_device *q, int d) parport_write_control(q->pport, d); } -static int qc_waithand(struct qcam_device *q, int val); -static int qc_command(struct qcam_device *q, int command); -static int qc_readparam(struct qcam_device *q); -static int qc_setscanmode(struct qcam_device *q); -static int qc_readbytes(struct qcam_device *q, char buffer[]); - -static struct video_device qcam_template; - -static int qc_calibrate(struct qcam_device *q) -{ - /* - * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96 - * The white balance is an individiual value for each - * quickcam. - */ - - int value; - int count = 0; - - qc_command(q, 27); /* AutoAdjustOffset */ - qc_command(q, 0); /* Dummy Parameter, ignored by the camera */ - - /* GetOffset (33) will read 255 until autocalibration */ - /* is finished. After that, a value of 1-254 will be */ - /* returned. */ - - do { - qc_command(q, 33); - value = qc_readparam(q); - mdelay(1); - schedule(); - count++; - } while (value == 0xff && count < 2048); - - q->whitebal = value; - return value; -} - -/* Initialize the QuickCam driver control structure. This is where - * defaults are set for people who don't have a config file.*/ - -static struct qcam_device *qcam_init(struct parport *port) -{ - struct qcam_device *q; - - q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL); - if (q == NULL) - return NULL; - - q->pport = port; - q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL, - NULL, 0, NULL); - if (q->pdev == NULL) { - printk(KERN_ERR "bw-qcam: couldn't register for %s.\n", - port->name); - kfree(q); - return NULL; - } - - memcpy(&q->vdev, &qcam_template, sizeof(qcam_template)); - - mutex_init(&q->lock); - - q->port_mode = (QC_ANY | QC_NOTSET); - q->width = 320; - q->height = 240; - q->bpp = 4; - q->transfer_scale = 2; - q->contrast = 192; - q->brightness = 180; - q->whitebal = 105; - q->top = 1; - q->left = 14; - q->mode = -1; - q->status = QC_PARAM_CHANGE; - return q; -} - - -/* qc_command is probably a bit of a misnomer -- it's used to send - * bytes *to* the camera. Generally, these bytes are either commands - * or arguments to commands, so the name fits, but it still bugs me a - * bit. See the documentation for a list of commands. */ - -static int qc_command(struct qcam_device *q, int command) -{ - int n1, n2; - int cmd; - - write_lpdata(q, command); - write_lpcontrol(q, 6); - - n1 = qc_waithand(q, 1); - - write_lpcontrol(q, 0xe); - n2 = qc_waithand(q, 0); - - cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4); - return cmd; -} - -static int qc_readparam(struct qcam_device *q) -{ - int n1, n2; - int cmd; - - write_lpcontrol(q, 6); - n1 = qc_waithand(q, 1); - - write_lpcontrol(q, 0xe); - n2 = qc_waithand(q, 0); - - cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4); - return cmd; -} /* qc_waithand busy-waits for a handshake signal from the QuickCam. * Almost all communication with the camera requires handshaking. */ -static int qc_waithand(struct qcam_device *q, int val) +static int qc_waithand(struct qcam *q, int val) { int status; int runs = 0; @@ -286,7 +214,7 @@ static int qc_waithand(struct qcam_device *q, int val) * (bit 3 of status register). It also returns the last value read, * since this data is useful. */ -static unsigned int qc_waithand2(struct qcam_device *q, int val) +static unsigned int qc_waithand2(struct qcam *q, int val) { unsigned int status; int runs = 0; @@ -309,6 +237,43 @@ static unsigned int qc_waithand2(struct qcam_device *q, int val) return status; } +/* qc_command is probably a bit of a misnomer -- it's used to send + * bytes *to* the camera. Generally, these bytes are either commands + * or arguments to commands, so the name fits, but it still bugs me a + * bit. See the documentation for a list of commands. */ + +static int qc_command(struct qcam *q, int command) +{ + int n1, n2; + int cmd; + + write_lpdata(q, command); + write_lpcontrol(q, 6); + + n1 = qc_waithand(q, 1); + + write_lpcontrol(q, 0xe); + n2 = qc_waithand(q, 0); + + cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4); + return cmd; +} + +static int qc_readparam(struct qcam *q) +{ + int n1, n2; + int cmd; + + write_lpcontrol(q, 6); + n1 = qc_waithand(q, 1); + + write_lpcontrol(q, 0xe); + n2 = qc_waithand(q, 0); + + cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4); + return cmd; +} + /* Try to detect a QuickCam. It appears to flash the upper 4 bits of the status register at 5-10 Hz. This is only used in the autoprobe @@ -317,7 +282,7 @@ static unsigned int qc_waithand2(struct qcam_device *q, int val) almost completely safe, while their method screws up my printer if I plug it in before the camera. */ -static int qc_detect(struct qcam_device *q) +static int qc_detect(struct qcam *q) { int reg, lastreg; int count = 0; @@ -358,41 +323,6 @@ static int qc_detect(struct qcam_device *q) } } - -/* Reset the QuickCam. This uses the same sequence the Windows - * QuickPic program uses. Someone with a bi-directional port should - * check that bi-directional mode is detected right, and then - * implement bi-directional mode in qc_readbyte(). */ - -static void qc_reset(struct qcam_device *q) -{ - switch (q->port_mode & QC_FORCE_MASK) { - case QC_FORCE_UNIDIR: - q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR; - break; - - case QC_FORCE_BIDIR: - q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR; - break; - - case QC_ANY: - write_lpcontrol(q, 0x20); - write_lpdata(q, 0x75); - - if (read_lpdata(q) != 0x75) - q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR; - else - q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR; - break; - } - - write_lpcontrol(q, 0xb); - udelay(250); - write_lpcontrol(q, 0xe); - qc_setscanmode(q); /* in case port_mode changed */ -} - - /* Decide which scan mode to use. There's no real requirement that * the scanmode match the resolution in q->height and q-> width -- the * camera takes the picture at the resolution specified in the @@ -402,7 +332,7 @@ static void qc_reset(struct qcam_device *q) * returned. If the scan is smaller, then the rest of the image * returned contains garbage. */ -static int qc_setscanmode(struct qcam_device *q) +static int qc_setscanmode(struct qcam *q) { int old_mode = q->mode; @@ -442,10 +372,45 @@ static int qc_setscanmode(struct qcam_device *q) } +/* Reset the QuickCam. This uses the same sequence the Windows + * QuickPic program uses. Someone with a bi-directional port should + * check that bi-directional mode is detected right, and then + * implement bi-directional mode in qc_readbyte(). */ + +static void qc_reset(struct qcam *q) +{ + switch (q->port_mode & QC_FORCE_MASK) { + case QC_FORCE_UNIDIR: + q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR; + break; + + case QC_FORCE_BIDIR: + q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR; + break; + + case QC_ANY: + write_lpcontrol(q, 0x20); + write_lpdata(q, 0x75); + + if (read_lpdata(q) != 0x75) + q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR; + else + q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR; + break; + } + + write_lpcontrol(q, 0xb); + udelay(250); + write_lpcontrol(q, 0xe); + qc_setscanmode(q); /* in case port_mode changed */ +} + + + /* Reset the QuickCam and program for brightness, contrast, * white-balance, and resolution. */ -static void qc_set(struct qcam_device *q) +static void qc_set(struct qcam *q) { int val; int val2; @@ -499,7 +464,7 @@ static void qc_set(struct qcam_device *q) the supplied buffer. It returns the number of bytes read, or -1 on error. */ -static inline int qc_readbytes(struct qcam_device *q, char buffer[]) +static inline int qc_readbytes(struct qcam *q, char buffer[]) { int ret = 1; unsigned int hi, lo; @@ -590,7 +555,7 @@ static inline int qc_readbytes(struct qcam_device *q, char buffer[]) * n=2^(bit depth)-1. Ask me for more details if you don't understand * this. */ -static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long len) +static long qc_capture(struct qcam *q, char __user *buf, unsigned long len) { int i, j, k, yield; int bytes; @@ -674,171 +639,206 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le * Video4linux interfacing */ -static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static int qcam_querycap(struct file *file, void *priv, + struct v4l2_capability *vcap) { - struct video_device *dev = video_devdata(file); - struct qcam_device *qcam = (struct qcam_device *)dev; - - switch (cmd) { - case VIDIOCGCAP: - { - struct video_capability *b = arg; - strcpy(b->name, "Quickcam"); - b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES|VID_TYPE_MONOCHROME; - b->channels = 1; - b->audios = 0; - b->maxwidth = 320; - b->maxheight = 240; - b->minwidth = 80; - b->minheight = 60; - return 0; - } - case VIDIOCGCHAN: - { - struct video_channel *v = arg; - if (v->channel != 0) - return -EINVAL; - v->flags = 0; - v->tuners = 0; - /* Good question.. its composite or SVHS so.. */ - v->type = VIDEO_TYPE_CAMERA; - strcpy(v->name, "Camera"); - return 0; - } - case VIDIOCSCHAN: - { - struct video_channel *v = arg; - if (v->channel != 0) - return -EINVAL; - return 0; - } - case VIDIOCGTUNER: - { - struct video_tuner *v = arg; - if (v->tuner) - return -EINVAL; - strcpy(v->name, "Format"); - v->rangelow = 0; - v->rangehigh = 0; - v->flags = 0; - v->mode = VIDEO_MODE_AUTO; - return 0; - } - case VIDIOCSTUNER: - { - struct video_tuner *v = arg; - if (v->tuner) - return -EINVAL; - if (v->mode != VIDEO_MODE_AUTO) - return -EINVAL; - return 0; - } - case VIDIOCGPICT: - { - struct video_picture *p = arg; - p->colour = 0x8000; - p->hue = 0x8000; - p->brightness = qcam->brightness << 8; - p->contrast = qcam->contrast << 8; - p->whiteness = qcam->whitebal << 8; - p->depth = qcam->bpp; - p->palette = VIDEO_PALETTE_GREY; - return 0; - } - case VIDIOCSPICT: - { - struct video_picture *p = arg; - if (p->palette != VIDEO_PALETTE_GREY) - return -EINVAL; - if (p->depth != 4 && p->depth != 6) - return -EINVAL; - - /* - * Now load the camera. - */ - - qcam->brightness = p->brightness >> 8; - qcam->contrast = p->contrast >> 8; - qcam->whitebal = p->whiteness >> 8; - qcam->bpp = p->depth; - - mutex_lock(&qcam->lock); - qc_setscanmode(qcam); - mutex_unlock(&qcam->lock); - qcam->status |= QC_PARAM_CHANGE; + struct qcam *qcam = video_drvdata(file); - return 0; - } - case VIDIOCSWIN: - { - struct video_window *vw = arg; - if (vw->flags) - return -EINVAL; - if (vw->clipcount) - return -EINVAL; - if (vw->height < 60 || vw->height > 240) - return -EINVAL; - if (vw->width < 80 || vw->width > 320) - return -EINVAL; - - qcam->width = 320; - qcam->height = 240; - qcam->transfer_scale = 4; - - if (vw->width >= 160 && vw->height >= 120) - qcam->transfer_scale = 2; - if (vw->width >= 320 && vw->height >= 240) { - qcam->width = 320; - qcam->height = 240; - qcam->transfer_scale = 1; - } - mutex_lock(&qcam->lock); - qc_setscanmode(qcam); - mutex_unlock(&qcam->lock); + strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver)); + strlcpy(vcap->card, "B&W Quickcam", sizeof(vcap->card)); + strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info)); + vcap->version = KERNEL_VERSION(0, 0, 2); + vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; + return 0; +} - /* We must update the camera before we grab. We could - just have changed the grab size */ - qcam->status |= QC_PARAM_CHANGE; +static int qcam_enum_input(struct file *file, void *fh, struct v4l2_input *vin) +{ + if (vin->index > 0) + return -EINVAL; + strlcpy(vin->name, "Camera", sizeof(vin->name)); + vin->type = V4L2_INPUT_TYPE_CAMERA; + vin->audioset = 0; + vin->tuner = 0; + vin->std = 0; + vin->status = 0; + return 0; +} - /* Ok we figured out what to use from our wide choice */ - return 0; - } - case VIDIOCGWIN: - { - struct video_window *vw = arg; +static int qcam_g_input(struct file *file, void *fh, unsigned int *inp) +{ + *inp = 0; + return 0; +} - memset(vw, 0, sizeof(*vw)); - vw->width = qcam->width / qcam->transfer_scale; - vw->height = qcam->height / qcam->transfer_scale; - return 0; - } - case VIDIOCKEY: - return 0; - case VIDIOCCAPTURE: - case VIDIOCGFBUF: - case VIDIOCSFBUF: - case VIDIOCGFREQ: - case VIDIOCSFREQ: - case VIDIOCGAUDIO: - case VIDIOCSAUDIO: - return -EINVAL; +static int qcam_s_input(struct file *file, void *fh, unsigned int inp) +{ + return (inp > 0) ? -EINVAL : 0; +} + +static int qcam_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *qc) +{ + switch (qc->id) { + case V4L2_CID_BRIGHTNESS: + return v4l2_ctrl_query_fill(qc, 0, 255, 1, 180); + case V4L2_CID_CONTRAST: + return v4l2_ctrl_query_fill(qc, 0, 255, 1, 192); + case V4L2_CID_GAMMA: + return v4l2_ctrl_query_fill(qc, 0, 255, 1, 105); + } + return -EINVAL; +} + +static int qcam_g_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct qcam *qcam = video_drvdata(file); + int ret = 0; + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + ctrl->value = qcam->brightness; + break; + case V4L2_CID_CONTRAST: + ctrl->value = qcam->contrast; + break; + case V4L2_CID_GAMMA: + ctrl->value = qcam->whitebal; + break; default: - return -ENOIOCTLCMD; + ret = -EINVAL; + break; } + return ret; +} + +static int qcam_s_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct qcam *qcam = video_drvdata(file); + int ret = 0; + + mutex_lock(&qcam->lock); + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + qcam->brightness = ctrl->value; + break; + case V4L2_CID_CONTRAST: + qcam->contrast = ctrl->value; + break; + case V4L2_CID_GAMMA: + qcam->whitebal = ctrl->value; + break; + default: + ret = -EINVAL; + break; + } + if (ret == 0) { + qc_setscanmode(qcam); + qcam->status |= QC_PARAM_CHANGE; + } + mutex_unlock(&qcam->lock); + return ret; +} + +static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) +{ + struct qcam *qcam = video_drvdata(file); + struct v4l2_pix_format *pix = &fmt->fmt.pix; + + pix->width = qcam->width / qcam->transfer_scale; + pix->height = qcam->height / qcam->transfer_scale; + pix->pixelformat = (qcam->bpp == 4) ? V4L2_PIX_FMT_Y4 : V4L2_PIX_FMT_Y6; + pix->field = V4L2_FIELD_NONE; + pix->bytesperline = qcam->width; + pix->sizeimage = qcam->width * qcam->height; + /* Just a guess */ + pix->colorspace = V4L2_COLORSPACE_SRGB; + return 0; +} + +static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) +{ + struct v4l2_pix_format *pix = &fmt->fmt.pix; + + if (pix->height <= 60 || pix->width <= 80) { + pix->height = 60; + pix->width = 80; + } else if (pix->height <= 120 || pix->width <= 160) { + pix->height = 120; + pix->width = 160; + } else { + pix->height = 240; + pix->width = 320; + } + if (pix->pixelformat != V4L2_PIX_FMT_Y4 && + pix->pixelformat != V4L2_PIX_FMT_Y6) + pix->pixelformat = V4L2_PIX_FMT_Y4; + pix->field = V4L2_FIELD_NONE; + pix->bytesperline = pix->width; + pix->sizeimage = pix->width * pix->height; + /* Just a guess */ + pix->colorspace = V4L2_COLORSPACE_SRGB; + return 0; +} + +static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) +{ + struct qcam *qcam = video_drvdata(file); + struct v4l2_pix_format *pix = &fmt->fmt.pix; + int ret = qcam_try_fmt_vid_cap(file, fh, fmt); + + if (ret) + return ret; + qcam->width = 320; + qcam->height = 240; + if (pix->height == 60) + qcam->transfer_scale = 4; + else if (pix->height == 120) + qcam->transfer_scale = 2; + else + qcam->transfer_scale = 1; + if (pix->pixelformat == V4L2_PIX_FMT_Y6) + qcam->bpp = 6; + else + qcam->bpp = 4; + + mutex_lock(&qcam->lock); + qc_setscanmode(qcam); + /* We must update the camera before we grab. We could + just have changed the grab size */ + qcam->status |= QC_PARAM_CHANGE; + mutex_unlock(&qcam->lock); return 0; } -static long qcam_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) +static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt) { - return video_usercopy(file, cmd, arg, qcam_do_ioctl); + static struct v4l2_fmtdesc formats[] = { + { 0, 0, 0, + "4-Bit Monochrome", V4L2_PIX_FMT_Y4, + { 0, 0, 0, 0 } + }, + { 0, 0, 0, + "6-Bit Monochrome", V4L2_PIX_FMT_Y6, + { 0, 0, 0, 0 } + }, + }; + enum v4l2_buf_type type = fmt->type; + + if (fmt->index > 1) + return -EINVAL; + + *fmt = formats[fmt->index]; + fmt->type = type; + return 0; } static ssize_t qcam_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct video_device *v = video_devdata(file); - struct qcam_device *qcam = (struct qcam_device *)v; + struct qcam *qcam = video_drvdata(file); int len; parport_claim_or_block(qcam->pdev); @@ -858,43 +858,112 @@ static ssize_t qcam_read(struct file *file, char __user *buf, return len; } -static int qcam_exclusive_open(struct file *file) +static const struct v4l2_file_operations qcam_fops = { + .owner = THIS_MODULE, + .ioctl = video_ioctl2, + .read = qcam_read, +}; + +static const struct v4l2_ioctl_ops qcam_ioctl_ops = { + .vidioc_querycap = qcam_querycap, + .vidioc_g_input = qcam_g_input, + .vidioc_s_input = qcam_s_input, + .vidioc_enum_input = qcam_enum_input, + .vidioc_queryctrl = qcam_queryctrl, + .vidioc_g_ctrl = qcam_g_ctrl, + .vidioc_s_ctrl = qcam_s_ctrl, + .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap, +}; + +/* Initialize the QuickCam driver control structure. This is where + * defaults are set for people who don't have a config file.*/ + +static struct qcam *qcam_init(struct parport *port) { - struct video_device *dev = video_devdata(file); - struct qcam_device *qcam = (struct qcam_device *)dev; + struct qcam *qcam; + struct v4l2_device *v4l2_dev; + + qcam = kzalloc(sizeof(struct qcam), GFP_KERNEL); + if (qcam == NULL) + return NULL; + + v4l2_dev = &qcam->v4l2_dev; + strlcpy(v4l2_dev->name, "bw-qcam", sizeof(v4l2_dev->name)); - return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0; + if (v4l2_device_register(NULL, v4l2_dev) < 0) { + v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); + return NULL; + } + + qcam->pport = port; + qcam->pdev = parport_register_device(port, "bw-qcam", NULL, NULL, + NULL, 0, NULL); + if (qcam->pdev == NULL) { + v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name); + kfree(qcam); + return NULL; + } + + strlcpy(qcam->vdev.name, "Connectix QuickCam", sizeof(qcam->vdev.name)); + qcam->vdev.v4l2_dev = v4l2_dev; + qcam->vdev.fops = &qcam_fops; + qcam->vdev.ioctl_ops = &qcam_ioctl_ops; + qcam->vdev.release = video_device_release_empty; + video_set_drvdata(&qcam->vdev, qcam); + + mutex_init(&qcam->lock); + + qcam->port_mode = (QC_ANY | QC_NOTSET); + qcam->width = 320; + qcam->height = 240; + qcam->bpp = 4; + qcam->transfer_scale = 2; + qcam->contrast = 192; + qcam->brightness = 180; + qcam->whitebal = 105; + qcam->top = 1; + qcam->left = 14; + qcam->mode = -1; + qcam->status = QC_PARAM_CHANGE; + return qcam; } -static int qcam_exclusive_release(struct file *file) +static int qc_calibrate(struct qcam *q) { - struct video_device *dev = video_devdata(file); - struct qcam_device *qcam = (struct qcam_device *)dev; + /* + * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96 + * The white balance is an individual value for each + * quickcam. + */ - clear_bit(0, &qcam->in_use); - return 0; -} + int value; + int count = 0; -static const struct v4l2_file_operations qcam_fops = { - .owner = THIS_MODULE, - .open = qcam_exclusive_open, - .release = qcam_exclusive_release, - .ioctl = qcam_ioctl, - .read = qcam_read, -}; -static struct video_device qcam_template = { - .name = "Connectix Quickcam", - .fops = &qcam_fops, - .release = video_device_release_empty, -}; + qc_command(q, 27); /* AutoAdjustOffset */ + qc_command(q, 0); /* Dummy Parameter, ignored by the camera */ -#define MAX_CAMS 4 -static struct qcam_device *qcams[MAX_CAMS]; -static unsigned int num_cams; + /* GetOffset (33) will read 255 until autocalibration */ + /* is finished. After that, a value of 1-254 will be */ + /* returned. */ + + do { + qc_command(q, 33); + value = qc_readparam(q); + mdelay(1); + schedule(); + count++; + } while (value == 0xff && count < 2048); + + q->whitebal = value; + return value; +} static int init_bwqcam(struct parport *port) { - struct qcam_device *qcam; + struct qcam *qcam; if (num_cams == MAX_CAMS) { printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS); @@ -919,7 +988,7 @@ static int init_bwqcam(struct parport *port) parport_release(qcam->pdev); - printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name); + v4l2_info(&qcam->v4l2_dev, "Connectix Quickcam on %s\n", qcam->pport->name); if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { parport_unregister_device(qcam->pdev); @@ -932,7 +1001,7 @@ static int init_bwqcam(struct parport *port) return 0; } -static void close_bwqcam(struct qcam_device *qcam) +static void close_bwqcam(struct qcam *qcam) { video_unregister_device(&qcam->vdev); parport_unregister_device(qcam->pdev); @@ -983,7 +1052,7 @@ static void bwqcam_detach(struct parport *port) { int i; for (i = 0; i < num_cams; i++) { - struct qcam_device *qcam = qcams[i]; + struct qcam *qcam = qcams[i]; if (qcam && qcam->pdev->port == port) { qcams[i] = NULL; close_bwqcam(qcam); diff --git a/drivers/media/video/bw-qcam.h b/drivers/media/video/bw-qcam.h deleted file mode 100644 index 8a60c5de0935..000000000000 --- a/drivers/media/video/bw-qcam.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Video4Linux bw-qcam driver - * - * Derived from code.. - */ - -/****************************************************************** - -Copyright (C) 1996 by Scott Laird - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL SCOTT LAIRD BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -******************************************************************/ - -/* One from column A... */ -#define QC_NOTSET 0 -#define QC_UNIDIR 1 -#define QC_BIDIR 2 -#define QC_SERIAL 3 - -/* ... and one from column B */ -#define QC_ANY 0x00 -#define QC_FORCE_UNIDIR 0x10 -#define QC_FORCE_BIDIR 0x20 -#define QC_FORCE_SERIAL 0x30 -/* in the port_mode member */ - -#define QC_MODE_MASK 0x07 -#define QC_FORCE_MASK 0x70 - -#define MAX_HEIGHT 243 -#define MAX_WIDTH 336 - -/* Bit fields for status flags */ -#define QC_PARAM_CHANGE 0x01 /* Camera status change has occurred */ - -struct qcam_device { - struct video_device vdev; - struct pardevice *pdev; - struct parport *pport; - struct mutex lock; - int width, height; - int bpp; - int mode; - int contrast, brightness, whitebal; - int port_mode; - int transfer_scale; - int top, left; - int status; - unsigned int saved_bits; - unsigned long in_use; -}; -- cgit v1.2.3 From d71964fb9731412ce1f86cd7d9b71f1f94a04b0d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 10 May 2010 03:55:25 -0300 Subject: V4L/DVB: c-qcam: convert to V4L2 Note: due to lack of hardware this conversion is untested. However, it is pretty straightforward so I do not expect any problems. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 2 +- drivers/media/video/c-qcam.c | 634 ++++++++++++++++++++++--------------------- 2 files changed, 331 insertions(+), 305 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 42d198d5a87e..bdbc9d305419 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -656,7 +656,7 @@ config VIDEO_BWQCAM config VIDEO_CQCAM tristate "QuickCam Colour Video For Linux (EXPERIMENTAL)" - depends on EXPERIMENTAL && PARPORT && VIDEO_V4L1 + depends on EXPERIMENTAL && PARPORT && VIDEO_V4L2 help This is the video4linux driver for the colour version of the Connectix QuickCam. If you have one of these cameras, say Y here, diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c index 8f1dd88b32a6..6e4b19698c13 100644 --- a/drivers/media/video/c-qcam.c +++ b/drivers/media/video/c-qcam.c @@ -33,15 +33,17 @@ #include #include #include -#include -#include -#include #include #include - +#include +#include #include +#include +#include +#include -struct qcam_device { +struct qcam { + struct v4l2_device v4l2_dev; struct video_device vdev; struct pardevice *pdev; struct parport *pport; @@ -51,7 +53,6 @@ struct qcam_device { int contrast, brightness, whitebal; int top, left; unsigned int bidirectional; - unsigned long in_use; struct mutex lock; }; @@ -68,33 +69,45 @@ struct qcam_device { #define QC_DECIMATION_2 2 #define QC_DECIMATION_4 4 -#define BANNER "Colour QuickCam for Video4Linux v0.05" +#define BANNER "Colour QuickCam for Video4Linux v0.06" static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 }; static int probe = 2; static int force_rgb; static int video_nr = -1; -static inline void qcam_set_ack(struct qcam_device *qcam, unsigned int i) +/* FIXME: parport=auto would never have worked, surely? --RR */ +MODULE_PARM_DESC(parport, "parport= for port detection method\n" + "probe=<0|1|2> for camera detection method\n" + "force_rgb=<0|1> for RGB data format (default BGR)"); +module_param_array(parport, int, NULL, 0); +module_param(probe, int, 0); +module_param(force_rgb, bool, 0); +module_param(video_nr, int, 0); + +static struct qcam *qcams[MAX_CAMS]; +static unsigned int num_cams; + +static inline void qcam_set_ack(struct qcam *qcam, unsigned int i) { /* note: the QC specs refer to the PCAck pin by voltage, not software level. PC ports have builtin inverters. */ parport_frob_control(qcam->pport, 8, i ? 8 : 0); } -static inline unsigned int qcam_ready1(struct qcam_device *qcam) +static inline unsigned int qcam_ready1(struct qcam *qcam) { return (parport_read_status(qcam->pport) & 0x8) ? 1 : 0; } -static inline unsigned int qcam_ready2(struct qcam_device *qcam) +static inline unsigned int qcam_ready2(struct qcam *qcam) { return (parport_read_data(qcam->pport) & 0x1) ? 1 : 0; } -static unsigned int qcam_await_ready1(struct qcam_device *qcam, - int value) +static unsigned int qcam_await_ready1(struct qcam *qcam, int value) { + struct v4l2_device *v4l2_dev = &qcam->v4l2_dev; unsigned long oldjiffies = jiffies; unsigned int i; @@ -112,14 +125,15 @@ static unsigned int qcam_await_ready1(struct qcam_device *qcam, } /* Probably somebody pulled the plug out. Not much we can do. */ - printk(KERN_ERR "c-qcam: ready1 timeout (%d) %x %x\n", value, + v4l2_err(v4l2_dev, "ready1 timeout (%d) %x %x\n", value, parport_read_status(qcam->pport), parport_read_control(qcam->pport)); return 1; } -static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value) +static unsigned int qcam_await_ready2(struct qcam *qcam, int value) { + struct v4l2_device *v4l2_dev = &qcam->v4l2_dev; unsigned long oldjiffies = jiffies; unsigned int i; @@ -137,14 +151,14 @@ static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value) } /* Probably somebody pulled the plug out. Not much we can do. */ - printk(KERN_ERR "c-qcam: ready2 timeout (%d) %x %x %x\n", value, + v4l2_err(v4l2_dev, "ready2 timeout (%d) %x %x %x\n", value, parport_read_status(qcam->pport), parport_read_control(qcam->pport), parport_read_data(qcam->pport)); return 1; } -static int qcam_read_data(struct qcam_device *qcam) +static int qcam_read_data(struct qcam *qcam) { unsigned int idata; @@ -159,21 +173,22 @@ static int qcam_read_data(struct qcam_device *qcam) return idata; } -static int qcam_write_data(struct qcam_device *qcam, unsigned int data) +static int qcam_write_data(struct qcam *qcam, unsigned int data) { + struct v4l2_device *v4l2_dev = &qcam->v4l2_dev; unsigned int idata; parport_write_data(qcam->pport, data); idata = qcam_read_data(qcam); if (data != idata) { - printk(KERN_WARNING "cqcam: sent %x but received %x\n", data, + v4l2_warn(v4l2_dev, "sent %x but received %x\n", data, idata); return 1; } return 0; } -static inline int qcam_set(struct qcam_device *qcam, unsigned int cmd, unsigned int data) +static inline int qcam_set(struct qcam *qcam, unsigned int cmd, unsigned int data) { if (qcam_write_data(qcam, cmd)) return -1; @@ -182,14 +197,14 @@ static inline int qcam_set(struct qcam_device *qcam, unsigned int cmd, unsigned return 0; } -static inline int qcam_get(struct qcam_device *qcam, unsigned int cmd) +static inline int qcam_get(struct qcam *qcam, unsigned int cmd) { if (qcam_write_data(qcam, cmd)) return -1; return qcam_read_data(qcam); } -static int qc_detect(struct qcam_device *qcam) +static int qc_detect(struct qcam *qcam) { unsigned int stat, ostat, i, count = 0; @@ -246,7 +261,7 @@ static int qc_detect(struct qcam_device *qcam) return 0; } -static void qc_reset(struct qcam_device *qcam) +static void qc_reset(struct qcam *qcam) { parport_write_control(qcam->pport, 0xc); parport_write_control(qcam->pport, 0x8); @@ -258,55 +273,55 @@ static void qc_reset(struct qcam_device *qcam) /* Reset the QuickCam and program for brightness, contrast, * white-balance, and resolution. */ -static void qc_setup(struct qcam_device *q) +static void qc_setup(struct qcam *qcam) { - qc_reset(q); + qc_reset(qcam); /* Set the brightness. */ - qcam_set(q, 11, q->brightness); + qcam_set(qcam, 11, qcam->brightness); /* Set the height and width. These refer to the actual CCD area *before* applying the selected decimation. */ - qcam_set(q, 17, q->ccd_height); - qcam_set(q, 19, q->ccd_width / 2); + qcam_set(qcam, 17, qcam->ccd_height); + qcam_set(qcam, 19, qcam->ccd_width / 2); /* Set top and left. */ - qcam_set(q, 0xd, q->top); - qcam_set(q, 0xf, q->left); + qcam_set(qcam, 0xd, qcam->top); + qcam_set(qcam, 0xf, qcam->left); /* Set contrast and white balance. */ - qcam_set(q, 0x19, q->contrast); - qcam_set(q, 0x1f, q->whitebal); + qcam_set(qcam, 0x19, qcam->contrast); + qcam_set(qcam, 0x1f, qcam->whitebal); /* Set the speed. */ - qcam_set(q, 45, 2); + qcam_set(qcam, 45, 2); } /* Read some bytes from the camera and put them in the buffer. nbytes should be a multiple of 3, because bidirectional mode gives us three bytes at a time. */ -static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, unsigned int nbytes) +static unsigned int qcam_read_bytes(struct qcam *qcam, unsigned char *buf, unsigned int nbytes) { unsigned int bytes = 0; - qcam_set_ack(q, 0); - if (q->bidirectional) { + qcam_set_ack(qcam, 0); + if (qcam->bidirectional) { /* It's a bidirectional port */ while (bytes < nbytes) { unsigned int lo1, hi1, lo2, hi2; unsigned char r, g, b; - if (qcam_await_ready2(q, 1)) + if (qcam_await_ready2(qcam, 1)) return bytes; - lo1 = parport_read_data(q->pport) >> 1; - hi1 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10; - qcam_set_ack(q, 1); - if (qcam_await_ready2(q, 0)) + lo1 = parport_read_data(qcam->pport) >> 1; + hi1 = ((parport_read_status(qcam->pport) >> 3) & 0x1f) ^ 0x10; + qcam_set_ack(qcam, 1); + if (qcam_await_ready2(qcam, 0)) return bytes; - lo2 = parport_read_data(q->pport) >> 1; - hi2 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10; - qcam_set_ack(q, 0); + lo2 = parport_read_data(qcam->pport) >> 1; + hi2 = ((parport_read_status(qcam->pport) >> 3) & 0x1f) ^ 0x10; + qcam_set_ack(qcam, 0); r = lo1 | ((hi1 & 1) << 7); g = ((hi1 & 0x1e) << 3) | ((hi2 & 0x1e) >> 1); b = lo2 | ((hi2 & 1) << 7); @@ -328,14 +343,14 @@ static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, u while (bytes < nbytes) { unsigned int hi, lo; - if (qcam_await_ready1(q, 1)) + if (qcam_await_ready1(qcam, 1)) return bytes; - hi = (parport_read_status(q->pport) & 0xf0); - qcam_set_ack(q, 1); - if (qcam_await_ready1(q, 0)) + hi = (parport_read_status(qcam->pport) & 0xf0); + qcam_set_ack(qcam, 1); + if (qcam_await_ready1(qcam, 0)) return bytes; - lo = (parport_read_status(q->pport) & 0xf0); - qcam_set_ack(q, 0); + lo = (parport_read_status(qcam->pport) & 0xf0); + qcam_set_ack(qcam, 0); /* flip some bits */ rgb[(i = bytes++ % 3)] = (hi | (lo >> 4)) ^ 0x88; if (i >= 2) { @@ -361,10 +376,11 @@ get_fragment: #define BUFSZ 150 -static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long len) +static long qc_capture(struct qcam *qcam, char __user *buf, unsigned long len) { + struct v4l2_device *v4l2_dev = &qcam->v4l2_dev; unsigned lines, pixelsperline, bitsperxfer; - unsigned int is_bi_dir = q->bidirectional; + unsigned int is_bi_dir = qcam->bidirectional; size_t wantlen, outptr = 0; char tmpbuf[BUFSZ]; @@ -373,10 +389,10 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le /* Wait for camera to become ready */ for (;;) { - int i = qcam_get(q, 41); + int i = qcam_get(qcam, 41); if (i == -1) { - qc_setup(q); + qc_setup(qcam); return -EIO; } if ((i & 0x80) == 0) @@ -384,25 +400,25 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le schedule(); } - if (qcam_set(q, 7, (q->mode | (is_bi_dir ? 1 : 0)) + 1)) + if (qcam_set(qcam, 7, (qcam->mode | (is_bi_dir ? 1 : 0)) + 1)) return -EIO; - lines = q->height; - pixelsperline = q->width; + lines = qcam->height; + pixelsperline = qcam->width; bitsperxfer = (is_bi_dir) ? 24 : 8; if (is_bi_dir) { /* Turn the port around */ - parport_data_reverse(q->pport); + parport_data_reverse(qcam->pport); mdelay(3); - qcam_set_ack(q, 0); - if (qcam_await_ready1(q, 1)) { - qc_setup(q); + qcam_set_ack(qcam, 0); + if (qcam_await_ready1(qcam, 1)) { + qc_setup(qcam); return -EIO; } - qcam_set_ack(q, 1); - if (qcam_await_ready1(q, 0)) { - qc_setup(q); + qcam_set_ack(qcam, 1); + if (qcam_await_ready1(qcam, 0)) { + qc_setup(qcam); return -EIO; } } @@ -413,7 +429,7 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le size_t t, s; s = (wantlen > BUFSZ) ? BUFSZ : wantlen; - t = qcam_read_bytes(q, tmpbuf, s); + t = qcam_read_bytes(qcam, tmpbuf, s); if (outptr < len) { size_t sz = len - outptr; @@ -432,10 +448,10 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le len = outptr; if (wantlen) { - printk(KERN_ERR "qcam: short read.\n"); + v4l2_err(v4l2_dev, "short read.\n"); if (is_bi_dir) - parport_data_forward(q->pport); - qc_setup(q); + parport_data_forward(qcam->pport); + qc_setup(qcam); return len; } @@ -443,49 +459,49 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le int l; do { - l = qcam_read_bytes(q, tmpbuf, 3); + l = qcam_read_bytes(qcam, tmpbuf, 3); cond_resched(); } while (l && (tmpbuf[0] == 0x7e || tmpbuf[1] == 0x7e || tmpbuf[2] == 0x7e)); if (force_rgb) { if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf) - printk(KERN_ERR "qcam: bad EOF\n"); + v4l2_err(v4l2_dev, "bad EOF\n"); } else { if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe) - printk(KERN_ERR "qcam: bad EOF\n"); + v4l2_err(v4l2_dev, "bad EOF\n"); } - qcam_set_ack(q, 0); - if (qcam_await_ready1(q, 1)) { - printk(KERN_ERR "qcam: no ack after EOF\n"); - parport_data_forward(q->pport); - qc_setup(q); + qcam_set_ack(qcam, 0); + if (qcam_await_ready1(qcam, 1)) { + v4l2_err(v4l2_dev, "no ack after EOF\n"); + parport_data_forward(qcam->pport); + qc_setup(qcam); return len; } - parport_data_forward(q->pport); + parport_data_forward(qcam->pport); mdelay(3); - qcam_set_ack(q, 1); - if (qcam_await_ready1(q, 0)) { - printk(KERN_ERR "qcam: no ack to port turnaround\n"); - qc_setup(q); + qcam_set_ack(qcam, 1); + if (qcam_await_ready1(qcam, 0)) { + v4l2_err(v4l2_dev, "no ack to port turnaround\n"); + qc_setup(qcam); return len; } } else { int l; do { - l = qcam_read_bytes(q, tmpbuf, 1); + l = qcam_read_bytes(qcam, tmpbuf, 1); cond_resched(); } while (l && tmpbuf[0] == 0x7e); - l = qcam_read_bytes(q, tmpbuf + 1, 2); + l = qcam_read_bytes(qcam, tmpbuf + 1, 2); if (force_rgb) { if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf) - printk(KERN_ERR "qcam: bad EOF\n"); + v4l2_err(v4l2_dev, "bad EOF\n"); } else { if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe) - printk(KERN_ERR "qcam: bad EOF\n"); + v4l2_err(v4l2_dev, "bad EOF\n"); } } - qcam_write_data(q, 0); + qcam_write_data(qcam, 0); return len; } @@ -493,184 +509,202 @@ static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long le * Video4linux interfacing */ -static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static int qcam_querycap(struct file *file, void *priv, + struct v4l2_capability *vcap) { - struct video_device *dev = video_devdata(file); - struct qcam_device *qcam = (struct qcam_device *)dev; + struct qcam *qcam = video_drvdata(file); - switch (cmd) { - case VIDIOCGCAP: - { - struct video_capability *b = arg; + strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver)); + strlcpy(vcap->card, "Color Quickcam", sizeof(vcap->card)); + strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info)); + vcap->version = KERNEL_VERSION(0, 0, 3); + vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; + return 0; +} - strcpy(b->name, "Quickcam"); - b->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; - b->channels = 1; - b->audios = 0; - b->maxwidth = 320; - b->maxheight = 240; - b->minwidth = 80; - b->minheight = 60; - return 0; - } - case VIDIOCGCHAN: - { - struct video_channel *v = arg; - - if (v->channel != 0) - return -EINVAL; - v->flags = 0; - v->tuners = 0; - /* Good question.. its composite or SVHS so.. */ - v->type = VIDEO_TYPE_CAMERA; - strcpy(v->name, "Camera"); - return 0; - } - case VIDIOCSCHAN: - { - struct video_channel *v = arg; +static int qcam_enum_input(struct file *file, void *fh, struct v4l2_input *vin) +{ + if (vin->index > 0) + return -EINVAL; + strlcpy(vin->name, "Camera", sizeof(vin->name)); + vin->type = V4L2_INPUT_TYPE_CAMERA; + vin->audioset = 0; + vin->tuner = 0; + vin->std = 0; + vin->status = 0; + return 0; +} - if (v->channel != 0) - return -EINVAL; - return 0; - } - case VIDIOCGTUNER: - { - struct video_tuner *v = arg; - - if (v->tuner) - return -EINVAL; - memset(v, 0, sizeof(*v)); - strcpy(v->name, "Format"); - v->mode = VIDEO_MODE_AUTO; - return 0; +static int qcam_g_input(struct file *file, void *fh, unsigned int *inp) +{ + *inp = 0; + return 0; +} + +static int qcam_s_input(struct file *file, void *fh, unsigned int inp) +{ + return (inp > 0) ? -EINVAL : 0; +} + +static int qcam_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *qc) +{ + switch (qc->id) { + case V4L2_CID_BRIGHTNESS: + return v4l2_ctrl_query_fill(qc, 0, 255, 1, 240); + case V4L2_CID_CONTRAST: + return v4l2_ctrl_query_fill(qc, 0, 255, 1, 192); + case V4L2_CID_GAMMA: + return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128); } - case VIDIOCSTUNER: - { - struct video_tuner *v = arg; - - if (v->tuner) - return -EINVAL; - if (v->mode != VIDEO_MODE_AUTO) - return -EINVAL; - return 0; + return -EINVAL; +} + +static int qcam_g_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct qcam *qcam = video_drvdata(file); + int ret = 0; + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + ctrl->value = qcam->brightness; + break; + case V4L2_CID_CONTRAST: + ctrl->value = qcam->contrast; + break; + case V4L2_CID_GAMMA: + ctrl->value = qcam->whitebal; + break; + default: + ret = -EINVAL; + break; } - case VIDIOCGPICT: - { - struct video_picture *p = arg; - - p->colour = 0x8000; - p->hue = 0x8000; - p->brightness = qcam->brightness << 8; - p->contrast = qcam->contrast << 8; - p->whiteness = qcam->whitebal << 8; - p->depth = 24; - p->palette = VIDEO_PALETTE_RGB24; - return 0; + return ret; +} + +static int qcam_s_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct qcam *qcam = video_drvdata(file); + int ret = 0; + + mutex_lock(&qcam->lock); + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + qcam->brightness = ctrl->value; + break; + case V4L2_CID_CONTRAST: + qcam->contrast = ctrl->value; + break; + case V4L2_CID_GAMMA: + qcam->whitebal = ctrl->value; + break; + default: + ret = -EINVAL; + break; } - case VIDIOCSPICT: - { - struct video_picture *p = arg; - - /* - * Sanity check args - */ - if (p->depth != 24 || p->palette != VIDEO_PALETTE_RGB24) - return -EINVAL; - - /* - * Now load the camera. - */ - qcam->brightness = p->brightness >> 8; - qcam->contrast = p->contrast >> 8; - qcam->whitebal = p->whiteness >> 8; - - mutex_lock(&qcam->lock); + if (ret == 0) { parport_claim_or_block(qcam->pdev); qc_setup(qcam); parport_release(qcam->pdev); - mutex_unlock(&qcam->lock); - return 0; } - case VIDIOCSWIN: - { - struct video_window *vw = arg; - - if (vw->flags) - return -EINVAL; - if (vw->clipcount) - return -EINVAL; - if (vw->height < 60 || vw->height > 240) - return -EINVAL; - if (vw->width < 80 || vw->width > 320) - return -EINVAL; - - qcam->width = 80; - qcam->height = 60; - qcam->mode = QC_DECIMATION_4; + mutex_unlock(&qcam->lock); + return ret; +} - if (vw->width >= 160 && vw->height >= 120) { - qcam->width = 160; - qcam->height = 120; - qcam->mode = QC_DECIMATION_2; - } - if (vw->width >= 320 && vw->height >= 240) { - qcam->width = 320; - qcam->height = 240; - qcam->mode = QC_DECIMATION_1; - } - qcam->mode |= QC_MILLIONS; -#if 0 - if (vw->width >= 640 && vw->height >= 480) { - qcam->width = 640; - qcam->height = 480; - qcam->mode = QC_BILLIONS | QC_DECIMATION_1; - } -#endif - /* Ok we figured out what to use from our - wide choice */ - mutex_lock(&qcam->lock); - parport_claim_or_block(qcam->pdev); - qc_setup(qcam); - parport_release(qcam->pdev); - mutex_unlock(&qcam->lock); - return 0; - } - case VIDIOCGWIN: - { - struct video_window *vw = arg; - memset(vw, 0, sizeof(*vw)); - vw->width = qcam->width; - vw->height = qcam->height; - return 0; +static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) +{ + struct qcam *qcam = video_drvdata(file); + struct v4l2_pix_format *pix = &fmt->fmt.pix; + + pix->width = qcam->width; + pix->height = qcam->height; + pix->pixelformat = V4L2_PIX_FMT_RGB24; + pix->field = V4L2_FIELD_NONE; + pix->bytesperline = 3 * qcam->width; + pix->sizeimage = 3 * qcam->width * qcam->height; + /* Just a guess */ + pix->colorspace = V4L2_COLORSPACE_SRGB; + return 0; +} + +static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) +{ + struct v4l2_pix_format *pix = &fmt->fmt.pix; + + if (pix->height < 60 || pix->width < 80) { + pix->height = 60; + pix->width = 80; + } else if (pix->height < 120 || pix->width < 160) { + pix->height = 120; + pix->width = 160; + } else { + pix->height = 240; + pix->width = 320; } - case VIDIOCKEY: - return 0; - case VIDIOCCAPTURE: - case VIDIOCGFBUF: - case VIDIOCSFBUF: - case VIDIOCGFREQ: - case VIDIOCSFREQ: - case VIDIOCGAUDIO: - case VIDIOCSAUDIO: - return -EINVAL; + pix->pixelformat = V4L2_PIX_FMT_RGB24; + pix->field = V4L2_FIELD_NONE; + pix->bytesperline = 3 * pix->width; + pix->sizeimage = 3 * pix->width * pix->height; + /* Just a guess */ + pix->colorspace = V4L2_COLORSPACE_SRGB; + return 0; +} + +static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) +{ + struct qcam *qcam = video_drvdata(file); + struct v4l2_pix_format *pix = &fmt->fmt.pix; + int ret = qcam_try_fmt_vid_cap(file, fh, fmt); + + if (ret) + return ret; + switch (pix->height) { + case 60: + qcam->mode = QC_DECIMATION_4; + break; + case 120: + qcam->mode = QC_DECIMATION_2; + break; default: - return -ENOIOCTLCMD; + qcam->mode = QC_DECIMATION_1; + break; } + + mutex_lock(&qcam->lock); + qcam->mode |= QC_MILLIONS; + qcam->height = pix->height; + qcam->width = pix->width; + parport_claim_or_block(qcam->pdev); + qc_setup(qcam); + parport_release(qcam->pdev); + mutex_unlock(&qcam->lock); return 0; } -static long qcam_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) +static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt) { - return video_usercopy(file, cmd, arg, qcam_do_ioctl); + static struct v4l2_fmtdesc formats[] = { + { 0, 0, 0, + "RGB 8:8:8", V4L2_PIX_FMT_RGB24, + { 0, 0, 0, 0 } + }, + }; + enum v4l2_buf_type type = fmt->type; + + if (fmt->index > 0) + return -EINVAL; + + *fmt = formats[fmt->index]; + fmt->type = type; + return 0; } static ssize_t qcam_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct video_device *v = video_devdata(file); - struct qcam_device *qcam = (struct qcam_device *)v; + struct qcam *qcam = video_drvdata(file); int len; mutex_lock(&qcam->lock); @@ -682,81 +716,80 @@ static ssize_t qcam_read(struct file *file, char __user *buf, return len; } -static int qcam_exclusive_open(struct file *file) -{ - struct video_device *dev = video_devdata(file); - struct qcam_device *qcam = (struct qcam_device *)dev; - - return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0; -} - -static int qcam_exclusive_release(struct file *file) -{ - struct video_device *dev = video_devdata(file); - struct qcam_device *qcam = (struct qcam_device *)dev; - - clear_bit(0, &qcam->in_use); - return 0; -} - -/* video device template */ static const struct v4l2_file_operations qcam_fops = { .owner = THIS_MODULE, - .open = qcam_exclusive_open, - .release = qcam_exclusive_release, - .ioctl = qcam_ioctl, + .ioctl = video_ioctl2, .read = qcam_read, }; -static struct video_device qcam_template = { - .name = "Colour QuickCam", - .fops = &qcam_fops, - .release = video_device_release_empty, +static const struct v4l2_ioctl_ops qcam_ioctl_ops = { + .vidioc_querycap = qcam_querycap, + .vidioc_g_input = qcam_g_input, + .vidioc_s_input = qcam_s_input, + .vidioc_enum_input = qcam_enum_input, + .vidioc_queryctrl = qcam_queryctrl, + .vidioc_g_ctrl = qcam_g_ctrl, + .vidioc_s_ctrl = qcam_s_ctrl, + .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap, }; /* Initialize the QuickCam driver control structure. */ -static struct qcam_device *qcam_init(struct parport *port) +static struct qcam *qcam_init(struct parport *port) { - struct qcam_device *q; + struct qcam *qcam; + struct v4l2_device *v4l2_dev; - q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL); - if (q == NULL) + qcam = kzalloc(sizeof(*qcam), GFP_KERNEL); + if (qcam == NULL) return NULL; - q->pport = port; - q->pdev = parport_register_device(port, "c-qcam", NULL, NULL, + v4l2_dev = &qcam->v4l2_dev; + strlcpy(v4l2_dev->name, "c-qcam", sizeof(v4l2_dev->name)); + + if (v4l2_device_register(NULL, v4l2_dev) < 0) { + v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); + return NULL; + } + + qcam->pport = port; + qcam->pdev = parport_register_device(port, "c-qcam", NULL, NULL, NULL, 0, NULL); - q->bidirectional = (q->pport->modes & PARPORT_MODE_TRISTATE) ? 1 : 0; + qcam->bidirectional = (qcam->pport->modes & PARPORT_MODE_TRISTATE) ? 1 : 0; - if (q->pdev == NULL) { - printk(KERN_ERR "c-qcam: couldn't register for %s.\n", - port->name); - kfree(q); + if (qcam->pdev == NULL) { + v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name); + kfree(qcam); return NULL; } - memcpy(&q->vdev, &qcam_template, sizeof(qcam_template)); - - mutex_init(&q->lock); - q->width = q->ccd_width = 320; - q->height = q->ccd_height = 240; - q->mode = QC_MILLIONS | QC_DECIMATION_1; - q->contrast = 192; - q->brightness = 240; - q->whitebal = 128; - q->top = 1; - q->left = 14; - return q; + strlcpy(qcam->vdev.name, "Colour QuickCam", sizeof(qcam->vdev.name)); + qcam->vdev.v4l2_dev = v4l2_dev; + qcam->vdev.fops = &qcam_fops; + qcam->vdev.ioctl_ops = &qcam_ioctl_ops; + qcam->vdev.release = video_device_release_empty; + video_set_drvdata(&qcam->vdev, qcam); + + mutex_init(&qcam->lock); + qcam->width = qcam->ccd_width = 320; + qcam->height = qcam->ccd_height = 240; + qcam->mode = QC_MILLIONS | QC_DECIMATION_1; + qcam->contrast = 192; + qcam->brightness = 240; + qcam->whitebal = 128; + qcam->top = 1; + qcam->left = 14; + return qcam; } -static struct qcam_device *qcams[MAX_CAMS]; -static unsigned int num_cams; - static int init_cqcam(struct parport *port) { - struct qcam_device *qcam; + struct qcam *qcam; + struct v4l2_device *v4l2_dev; if (parport[0] != -1) { /* The user gave specific instructions */ @@ -777,6 +810,8 @@ static int init_cqcam(struct parport *port) if (qcam == NULL) return -ENODEV; + v4l2_dev = &qcam->v4l2_dev; + parport_claim_or_block(qcam->pdev); qc_reset(qcam); @@ -793,14 +828,14 @@ static int init_cqcam(struct parport *port) parport_release(qcam->pdev); if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { - printk(KERN_ERR "Unable to register Colour QuickCam on %s\n", + v4l2_err(v4l2_dev, "Unable to register Colour QuickCam on %s\n", qcam->pport->name); parport_unregister_device(qcam->pdev); kfree(qcam); return -ENODEV; } - printk(KERN_INFO "%s: Colour QuickCam found on %s\n", + v4l2_info(v4l2_dev, "%s: Colour QuickCam found on %s\n", video_device_node_name(&qcam->vdev), qcam->pport->name); qcams[num_cams++] = qcam; @@ -808,7 +843,7 @@ static int init_cqcam(struct parport *port) return 0; } -static void close_cqcam(struct qcam_device *qcam) +static void close_cqcam(struct qcam *qcam) { video_unregister_device(&qcam->vdev); parport_unregister_device(qcam->pdev); @@ -833,7 +868,7 @@ static struct parport_driver cqcam_driver = { static int __init cqcam_init(void) { - printk(BANNER "\n"); + printk(KERN_INFO BANNER "\n"); return parport_register_driver(&cqcam_driver); } @@ -852,14 +887,5 @@ MODULE_AUTHOR("Philip Blundell "); MODULE_DESCRIPTION(BANNER); MODULE_LICENSE("GPL"); -/* FIXME: parport=auto would never have worked, surely? --RR */ -MODULE_PARM_DESC(parport, "parport= for port detection method\n" - "probe=<0|1|2> for camera detection method\n" - "force_rgb=<0|1> for RGB data format (default BGR)"); -module_param_array(parport, int, NULL, 0); -module_param(probe, int, 0); -module_param(force_rgb, bool, 0); -module_param(video_nr, int, 0); - module_init(cqcam_init); module_exit(cqcam_cleanup); -- cgit v1.2.3 From e4425eab6b2da050bae55cffa01e573767a819a1 Mon Sep 17 00:00:00 2001 From: Abylay Ospan Date: Wed, 12 May 2010 04:24:09 -0300 Subject: V4L/DVB: cx23885: Check register errors Fix kernel Oops when number of NetUP Dual DVB-S2-CI cards more than DVB_MAX_ADAPTERS limit. [mchehab@redhat.com: move the return to the proper place] Signed-off-by: Abylay Ospan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-dvb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 9e1460828b2f..0a199d774d9b 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -991,6 +991,8 @@ static int dvb_register(struct cx23885_tsport *port) ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, &dev->pci->dev, adapter_nr, 0, cx23885_dvb_fe_ioctl_override); + if (!ret) + return ret; /* init CI & MAC */ switch (dev->board) { -- cgit v1.2.3 From c641a18969178ac1649e022156c85adb7c889451 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 15 May 2010 00:07:04 -0300 Subject: V4L/DVB: pvrusb2: Fix Gotview hardware support pvrusb2: Fix RF tuner problem with gotview hardware - this bug was introduced when switching over to the subdev model of driver control Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-devattr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c index 6bc16c13ccef..3092abfd66a2 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c @@ -117,6 +117,7 @@ static const struct pvr2_device_desc pvr2_device_24xxx = { static const struct pvr2_device_client_desc pvr2_cli_gotview_2[] = { { .module_id = PVR2_CLIENT_ID_CX25840 }, { .module_id = PVR2_CLIENT_ID_TUNER }, + { .module_id = PVR2_CLIENT_ID_DEMOD }, }; static const struct pvr2_device_desc pvr2_device_gotview_2 = { -- cgit v1.2.3 From 6861800c1512ca8452c5f350a7c0af445ece773b Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 15 May 2010 00:09:47 -0300 Subject: V4L/DVB: pvrusb2: Avoid using stack allocated buffers when performing USB I/O Drivers shouldn't assume that the stack is DMA-safe. [mchehab@redhat.com: fix patch description] Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-hdw.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 301ef197d038..d13232d51823 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -4084,12 +4084,20 @@ void pvr2_hdw_device_reset(struct pvr2_hdw *hdw) void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val) { - char da[1]; + char *da; unsigned int pipe; int ret; if (!hdw->usb_dev) return; + da = kmalloc(16, GFP_KERNEL); + + if (da == NULL) { + pvr2_trace(PVR2_TRACE_ERROR_LEGS, + "Unable to allocate memory to control CPU reset"); + return; + } + pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val); da[0] = val ? 0x01 : 0x00; @@ -4103,6 +4111,8 @@ void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val) "cpureset_assert(%d) error=%d",val,ret); pvr2_hdw_render_useless(hdw); } + + kfree(da); } -- cgit v1.2.3 From 8fd0444817e557568d8bddd77828d9ae0d606e04 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 15 May 2010 00:13:35 -0300 Subject: V4L/DVB: pvrusb2: New feature to mark specific hardware support as experimental This adds a flag in the device attribute structure which can be used to mark support for a particular device as experimental. Any devices flagged in this way, when encountered at run-time, will generate a warning message to the kernel log. Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-devattr.h | 5 +++++ drivers/media/video/pvrusb2/pvrusb2-hdw.c | 13 +++++++++++++ 2 files changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h index e5b9594eb5f6..273c8d4b3853 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h @@ -177,6 +177,11 @@ struct pvr2_device_desc { unsigned int flag_has_composite:1; /* Has composite input */ unsigned int flag_has_svideo:1; /* Has s-video input */ unsigned int flag_fx2_16kb:1; /* 16KB FX2 firmware OK here */ + + /* If this driver is considered experimental, i.e. not all aspects + are working correctly and/or it is untested, mark that fact + with this flag. */ + unsigned int flag_is_experimental:1; }; extern struct usb_device_id pvr2_device_table[]; diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index d13232d51823..2c3f845c3e5c 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -2459,6 +2459,19 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, hdw,hdw_desc->description); pvr2_trace(PVR2_TRACE_INFO, "Hardware description: %s", hdw_desc->description); + if (hdw_desc->flag_is_experimental) { + pvr2_trace(PVR2_TRACE_INFO, "**********"); + pvr2_trace(PVR2_TRACE_INFO, + "WARNING: Support for this device (%s) is" + " experimental.", hdw_desc->description); + pvr2_trace(PVR2_TRACE_INFO, + "Important functionality might not be" + " entirely working."); + pvr2_trace(PVR2_TRACE_INFO, + "Please consider contacting the driver author to" + " help with further stabilization of the driver."); + pvr2_trace(PVR2_TRACE_INFO, "**********"); + } if (!hdw) goto fail; init_timer(&hdw->quiescent_timer); -- cgit v1.2.3 From d72baad3f0e59041d68db7524537046e3a4121a2 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 15 May 2010 00:15:38 -0300 Subject: V4L/DVB: pvrusb2: Fix kernel oops at device unregistration pvrusb2: Fix oops caused by touching deleted memory after unregistration. This bug was introduced when we had started using video_device_node_name() - that function was being called potentially after the underlying structure (referenced by that function) had been deleted. The fix rearranges things slightly so that the function is called before destruction takes place. Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 5ffa0d2b0b0d..aaafa0398fd5 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -883,6 +883,17 @@ static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) { struct pvr2_hdw *hdw = dip->v4lp->channel.mc_head->hdw; enum pvr2_config cfg = dip->config; + char msg[80]; + unsigned int mcnt; + + /* Construct the unregistration message *before* we actually + perform the unregistration step. By doing it this way we don't + have to worry about potentially touching deleted resources. */ + mcnt = scnprintf(msg, sizeof(msg) - 1, + "pvrusb2: unregistered device %s [%s]", + video_device_node_name(&dip->devbase), + pvr2_config_get_name(cfg)); + msg[mcnt] = 0; pvr2_hdw_v4l_store_minor_number(hdw,dip->minor_type,-1); @@ -894,9 +905,7 @@ static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) are gone. */ video_unregister_device(&dip->devbase); - printk(KERN_INFO "pvrusb2: unregistered device %s [%s]\n", - video_device_node_name(&dip->devbase), - pvr2_config_get_name(cfg)); + printk(KERN_INFO "%s\n", msg); } -- cgit v1.2.3 From 28c4a5e6d32410f7c0b8fa9cc52eac424229f10a Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 15 May 2010 00:23:46 -0300 Subject: V4L/DVB: pvrusb2: Fix USB parent device reference count pvrusb2: Correctly reference count pointer to parent USB device when linked from sysfs interface. This is technically a pretty nasty problem, however as far as I know nobody had been getting burned by it (yet). Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-sysfs.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index 71f50565f637..bf478510a3b1 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c @@ -511,6 +511,7 @@ static void pvr2_sysfs_release(struct device *class_dev) static void class_dev_destroy(struct pvr2_sysfs *sfp) { + struct device *dev; if (!sfp->class_dev) return; #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC pvr2_sysfs_tear_down_debugifc(sfp); @@ -542,6 +543,9 @@ static void class_dev_destroy(struct pvr2_sysfs *sfp) } pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev); dev_set_drvdata(sfp->class_dev, NULL); + dev = sfp->class_dev->parent; + sfp->class_dev->parent = NULL; + put_device(dev); device_unregister(sfp->class_dev); sfp->class_dev = NULL; } @@ -631,10 +635,11 @@ static void class_dev_create(struct pvr2_sysfs *sfp, pvr2_sysfs_trace("Creating class_dev id=%p",class_dev); class_dev->class = &class_ptr->class; + dev_set_name(class_dev, "%s", pvr2_hdw_get_device_identifier(sfp->channel.hdw)); - class_dev->parent = &usb_dev->dev; + class_dev->parent = get_device(&usb_dev->dev); sfp->class_dev = class_dev; dev_set_drvdata(class_dev, sfp); @@ -775,7 +780,8 @@ struct pvr2_sysfs_class *pvr2_sysfs_class_create(void) struct pvr2_sysfs_class *clp; clp = kzalloc(sizeof(*clp),GFP_KERNEL); if (!clp) return clp; - pvr2_sysfs_trace("Creating pvr2_sysfs_class id=%p",clp); + pvr2_sysfs_trace("Creating and registering pvr2_sysfs_class id=%p", + clp); clp->class.name = "pvrusb2"; clp->class.class_release = pvr2_sysfs_class_release; clp->class.dev_release = pvr2_sysfs_release; @@ -791,6 +797,7 @@ struct pvr2_sysfs_class *pvr2_sysfs_class_create(void) void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp) { + pvr2_sysfs_trace("Unregistering pvr2_sysfs_class id=%p", clp); class_unregister(&clp->class); } -- cgit v1.2.3 From 7a6ac34848226e315e0d70333bb4ab83190d9f1d Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 15 May 2010 00:28:44 -0300 Subject: V4L/DVB: pvrusb2: Fix minor internal array allocation pvrusb2: Need one extra attribute slot allocated so that worst case still has a trailing null pointer. This wasn't causing visible symptoms; it was found through inspection while investigating other issues. Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index bf478510a3b1..3d7e5aab547f 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c @@ -74,7 +74,7 @@ struct pvr2_sysfs_ctl_item { int ctl_id; struct pvr2_sysfs *chptr; struct pvr2_sysfs_ctl_item *item_next; - struct attribute *attr_gen[7]; + struct attribute *attr_gen[8]; struct attribute_group grp; int created_ok; char name[80]; -- cgit v1.2.3 From e3a5ee73e7223cda78f2770572c5ad01928496d6 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sat, 15 May 2010 00:30:29 -0300 Subject: V4L/DVB: pvrusb2: Fix kernel oops on device tear-down pvrusb2: Delete sysfs class device as the _very_ last step, after we're sure that all driver contexts have gone away first. This is important because it appears that there isn't any protection from a struct device instance reference a deleted struct class instance. The assumption in the kernel code appears to be that the class instance is assumed to be around for the life of the device. So we can't let the class instance go away until all referencing device instances are gone; this is ensured by delaying removal of the class instance until after the driver contexts have all gone away. This bug has been present for a very long time but it didn't apparently become malignant until recently (probably because of other changes in the kernel). Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c index eeacd0f67855..2254194aad57 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-main.c +++ b/drivers/media/video/pvrusb2/pvrusb2-main.c @@ -153,12 +153,12 @@ static void __exit pvr_exit(void) usb_deregister(&pvr_driver); + pvr2_context_global_done(); + #ifdef CONFIG_VIDEO_PVRUSB2_SYSFS pvr2_sysfs_class_destroy(class_ptr); #endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ - pvr2_context_global_done(); - pvr2_trace(PVR2_TRACE_INIT,"pvr_exit complete"); } -- cgit v1.2.3 From 040000ae7d27d9229959f4a4e9d67cf6c93e8ef8 Mon Sep 17 00:00:00 2001 From: Jean-François Moine Date: Fri, 7 May 2010 15:27:44 -0300 Subject: V4L/DVB: gspca - sonixb: Have 0c45:602e handled by sonixb instead of sn9c102 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change fixes the Debian Bug #579332 http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=579332 Signed-off-by: Jean-François Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 2 -- drivers/media/video/sn9c102/sn9c102_devtable.h | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 785eeb4c2014..95354a339e3d 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -1453,9 +1453,7 @@ static const struct usb_device_id device_table[] __devinitconst = { {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)}, {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)}, {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)}, -#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)}, -#endif {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)}, #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)}, diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h index 522ba3f4c285..b6643ca7656a 100644 --- a/drivers/media/video/sn9c102/sn9c102_devtable.h +++ b/drivers/media/video/sn9c102/sn9c102_devtable.h @@ -62,8 +62,8 @@ static const struct usb_device_id sn9c102_id_table[] = { #if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE { SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), }, /* { SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, HV7131R */ -#endif { SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), }, +#endif { SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), }, /* SN9C103 */ { SN9C102_USB_DEVICE(0x0c45, 0x6080, BRIDGE_SN9C103), }, -- cgit v1.2.3 From 6804675e3644361b1d509cac5427bab42a0bc6da Mon Sep 17 00:00:00 2001 From: Jean-François Moine Date: Fri, 7 May 2010 15:35:08 -0300 Subject: V4L/DVB: gspca - sonixj: Add information about some potential JPEG webcams MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jean-François Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index bb923efb75bd..4bb6479dc920 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -3022,16 +3022,18 @@ static const __devinitdata struct usb_device_id device_table[] = { /* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */ /* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */ /* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */ +/* {USB_DEVICE(0x0c45, 0x60ce), BS(SN9C105, SP80708)}, */ {USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)}, /* {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */ /* {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */ +/* {USB_DEVICE(0x0c45, 0x60f2), BS(SN9C105, OV7660)}, */ {USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)}, #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE {USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)}, {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)}, #endif {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)}, /*sn9c128*/ -/* {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, P1030xC)}, */ +/* {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)}, * / GC0305*/ /* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */ {USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)}, /*sn9c128*/ {USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)}, /*sn9c128*/ @@ -3058,6 +3060,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)}, {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)}, {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, /*sn9c120b*/ + /* or GC0305 / GC0307 */ {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/ {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/ {USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)}, /*sn9c120b*/ -- cgit v1.2.3 From c4f95d84b8dedf28adda927561f7e09b1d5ea626 Mon Sep 17 00:00:00 2001 From: Warren Bosworth Focke Date: Fri, 7 May 2010 15:40:04 -0300 Subject: V4L/DVB: gspca - sonixj: Add webcam 0c45:60ce MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Warren Bosworth Focke Signed-off-by: Jean-François Moine Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/gspca.txt | 1 + drivers/media/video/gspca/sonixj.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt index 8f3f5d33327c..f13eb036c439 100644 --- a/Documentation/video4linux/gspca.txt +++ b/Documentation/video4linux/gspca.txt @@ -290,6 +290,7 @@ sonixb 0c45:602e Genius VideoCam Messenger sonixj 0c45:6040 Speed NVC 350K sonixj 0c45:607c Sonix sn9c102p Hv7131R sonixj 0c45:60c0 Sangha Sn535 +sonixj 0c45:60ce USB-PC-Camera-168 (TALK-5067) sonixj 0c45:60ec SN9C105+MO4000 sonixj 0c45:60fb Surfer NoName sonixj 0c45:60fc LG-LIC300 diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 4bb6479dc920..176c5b3d5e6f 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -3022,7 +3022,7 @@ static const __devinitdata struct usb_device_id device_table[] = { /* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */ /* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */ /* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */ -/* {USB_DEVICE(0x0c45, 0x60ce), BS(SN9C105, SP80708)}, */ + {USB_DEVICE(0x0c45, 0x60ce), BS(SN9C105, SP80708)}, {USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)}, /* {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */ /* {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */ -- cgit v1.2.3 From 9d78f46071b2cbc91eaf533e1ea441af36eed06a Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Sun, 16 May 2010 05:08:49 -0300 Subject: V4L/DVB: ngene: Support new device 'Digital Devices DuoFlex S2 miniPCIe' Add subsystem id DD10/DD20 'Digital Devices DuoFlex S2 miniPCIe'. Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ngene/ngene-cards.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c index 692c3e226e83..4692a41ad95b 100644 --- a/drivers/media/dvb/ngene/ngene-cards.c +++ b/drivers/media/dvb/ngene/ngene-cards.c @@ -217,6 +217,19 @@ static struct ngene_info ngene_info_cineS2v5 = { .fw_version = 15, }; +static struct ngene_info ngene_info_duoFlexS2 = { + .type = NGENE_SIDEWINDER, + .name = "Digital Devices DuoFlex S2 miniPCIe", + .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, + .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, + .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, + .fe_config = {&fe_cineS2, &fe_cineS2}, + .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, + .lnb = {0x0a, 0x08}, + .tsf = {3, 3}, + .fw_version = 15, +}; + static struct ngene_info ngene_info_m780 = { .type = NGENE_APP, .name = "Aver M780 ATSC/QAM-B", @@ -256,6 +269,8 @@ static const struct pci_device_id ngene_id_tbl[] __devinitdata = { NGENE_ID(0x18c3, 0xdb01, ngene_info_satixS2), NGENE_ID(0x18c3, 0xdb02, ngene_info_satixS2v2), NGENE_ID(0x18c3, 0xdd00, ngene_info_cineS2v5), + NGENE_ID(0x18c3, 0xdd10, ngene_info_duoFlexS2), + NGENE_ID(0x18c3, 0xdd20, ngene_info_duoFlexS2), NGENE_ID(0x1461, 0x062e, ngene_info_m780), {0} }; -- cgit v1.2.3 From eb05d155bc9f51ff701c09bc9b5e4b4f5a4b4d9f Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Sun, 16 May 2010 05:17:49 -0300 Subject: V4L/DVB: ngene: Do not call demuxer with interrupts disabled It is neither a good idea nor necessary to call the demuxer with interrupts disabled. Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ngene/ngene-core.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c index c8b4dfa0ab5f..46749d6ef1ee 100644 --- a/drivers/media/dvb/ngene/ngene-core.c +++ b/drivers/media/dvb/ngene/ngene-core.c @@ -147,24 +147,24 @@ static void demux_tasklet(unsigned long data) } else { if (chan->HWState == HWSTATE_RUN) { u32 Flags = 0; + IBufferExchange *exch1 = chan->pBufferExchange; + IBufferExchange *exch2 = chan->pBufferExchange2; if (Cur->ngeneBuffer.SR.Flags & 0x01) Flags |= BEF_EVEN_FIELD; if (Cur->ngeneBuffer.SR.Flags & 0x20) Flags |= BEF_OVERFLOW; - if (chan->pBufferExchange) - chan->pBufferExchange(chan, - Cur->Buffer1, - chan-> - Capture1Length, - Cur->ngeneBuffer. - SR.Clock, Flags); - if (chan->pBufferExchange2) - chan->pBufferExchange2(chan, - Cur->Buffer2, - chan-> - Capture2Length, - Cur->ngeneBuffer. - SR.Clock, Flags); + spin_unlock_irq(&chan->state_lock); + if (exch1) + exch1(chan, Cur->Buffer1, + chan->Capture1Length, + Cur->ngeneBuffer.SR.Clock, + Flags); + if (exch2) + exch2(chan, Cur->Buffer2, + chan->Capture2Length, + Cur->ngeneBuffer.SR.Clock, + Flags); + spin_lock_irq(&chan->state_lock); } else if (chan->HWState != HWSTATE_STOP) chan->HWState = HWSTATE_RUN; } -- cgit v1.2.3 From 4387418129895fd9aa2e2f6368ea69e9c4ddd0f2 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Sun, 16 May 2010 05:29:14 -0300 Subject: V4L/DVB: ngene: Implement support for MSI Add MSI support, may be enabled with firmware version 18. Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ngene/ngene-core.c | 33 ++++++++++++++++++++++++++++++++- drivers/media/dvb/ngene/ngene.h | 2 ++ 2 files changed, 34 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c index 46749d6ef1ee..35bed6095b1e 100644 --- a/drivers/media/dvb/ngene/ngene-core.c +++ b/drivers/media/dvb/ngene/ngene-core.c @@ -1299,11 +1299,14 @@ static void ngene_stop(struct ngene *dev) ngwritel(0, NGENE_EVENT); ngwritel(0, NGENE_EVENT_HI); free_irq(dev->pci_dev->irq, dev); + if (dev->msi_enabled) + pci_disable_msi(dev->pci_dev); } static int ngene_start(struct ngene *dev) { int stat; + unsigned long flags; int i; pci_set_master(dev->pci_dev); @@ -1333,6 +1336,28 @@ static int ngene_start(struct ngene *dev) if (stat < 0) goto fail; +#ifdef CONFIG_PCI_MSI + /* enable MSI if kernel and card support it */ + if (dev->card_info->msi_supported) { + ngwritel(0, NGENE_INT_ENABLE); + free_irq(dev->pci_dev->irq, dev); + stat = pci_enable_msi(dev->pci_dev); + if (stat) { + printk(KERN_INFO DEVICE_NAME + ": MSI not available\n"); + flags = IRQF_SHARED; + } else { + flags = 0; + dev->msi_enabled = true; + } + stat = request_irq(dev->pci_dev->irq, irq_handler, + flags, "nGene", dev); + if (stat < 0) + goto fail2; + ngwritel(1, NGENE_INT_ENABLE); + } +#endif + stat = ngene_i2c_init(dev, 0); if (stat < 0) goto fail; @@ -1358,10 +1383,16 @@ static int ngene_start(struct ngene *dev) bconf = BUFFER_CONFIG_3333; stat = ngene_command_config_buf(dev, bconf); } - return stat; + if (!stat) + return stat; + + /* otherwise error: fall through */ fail: ngwritel(0, NGENE_INT_ENABLE); free_irq(dev->pci_dev->irq, dev); +fail2: + if (dev->msi_enabled) + pci_disable_msi(dev->pci_dev); return stat; } diff --git a/drivers/media/dvb/ngene/ngene.h b/drivers/media/dvb/ngene/ngene.h index 676fcbb79026..b951d59e3617 100644 --- a/drivers/media/dvb/ngene/ngene.h +++ b/drivers/media/dvb/ngene/ngene.h @@ -725,6 +725,7 @@ struct ngene { u32 device_version; u32 fw_interface_version; u32 icounts; + bool msi_enabled; u8 *CmdDoneByte; int BootFirmware; @@ -797,6 +798,7 @@ struct ngene_info { #define NGENE_VBOX_V2 7 int fw_version; + bool msi_supported; char *name; int io_type[MAX_STREAM]; -- cgit v1.2.3 From 5a2a1848a7d744a437f96b79a655c13b8090e74d Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Sun, 16 May 2010 06:07:07 -0300 Subject: V4L/DVB: ngene: Make command timeout workaround configurable Make command timeout workaround configurable, activate it for firmware version <= 17. Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ngene/ngene-core.c | 9 ++++----- drivers/media/dvb/ngene/ngene-dvb.c | 14 +++----------- drivers/media/dvb/ngene/ngene.h | 1 + 3 files changed, 8 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c index 35bed6095b1e..2bdcf59829d1 100644 --- a/drivers/media/dvb/ngene/ngene-core.c +++ b/drivers/media/dvb/ngene/ngene-core.c @@ -53,8 +53,6 @@ MODULE_PARM_DESC(debug, "Print debugging information."); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -#define COMMAND_TIMEOUT_WORKAROUND - #define dprintk if (debug) printk #define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr))) @@ -1252,14 +1250,17 @@ static int ngene_load_firm(struct ngene *dev) version = 15; size = 23466; fw_name = "ngene_15.fw"; + dev->cmd_timeout_workaround = true; break; case 16: size = 23498; fw_name = "ngene_16.fw"; + dev->cmd_timeout_workaround = true; break; case 17: size = 24446; fw_name = "ngene_17.fw"; + dev->cmd_timeout_workaround = true; break; } @@ -1410,10 +1411,8 @@ static void release_channel(struct ngene_channel *chan) struct ngene_info *ni = dev->card_info; int io = ni->io_type[chan->number]; -#ifdef COMMAND_TIMEOUT_WORKAROUND - if (chan->running) + if (chan->dev->cmd_timeout_workaround && chan->running) set_transfer(chan, 0); -#endif tasklet_kill(&chan->demux_tasklet); diff --git a/drivers/media/dvb/ngene/ngene-dvb.c b/drivers/media/dvb/ngene/ngene-dvb.c index 96013eb353cd..61a932c1cfff 100644 --- a/drivers/media/dvb/ngene/ngene-dvb.c +++ b/drivers/media/dvb/ngene/ngene-dvb.c @@ -44,8 +44,6 @@ #include "ngene.h" -#define COMMAND_TIMEOUT_WORKAROUND - /****************************************************************************/ /* COMMAND API interface ****************************************************/ @@ -69,9 +67,7 @@ void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) struct ngene_channel *chan = priv; -#ifdef COMMAND_TIMEOUT_WORKAROUND if (chan->users > 0) -#endif dvb_dmx_swfilter(&chan->demux, buf, len); return NULL; } @@ -106,11 +102,8 @@ int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed) struct ngene_channel *chan = dvbdmx->priv; if (chan->users == 0) { -#ifdef COMMAND_TIMEOUT_WORKAROUND - if (!chan->running) -#endif + if (!chan->dev->cmd_timeout_workaround || !chan->running) set_transfer(chan, 1); - /* msleep(10); */ } return ++chan->users; @@ -124,9 +117,8 @@ int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed) if (--chan->users) return chan->users; -#ifndef COMMAND_TIMEOUT_WORKAROUND - set_transfer(chan, 0); -#endif + if (!chan->dev->cmd_timeout_workaround) + set_transfer(chan, 0); return 0; } diff --git a/drivers/media/dvb/ngene/ngene.h b/drivers/media/dvb/ngene/ngene.h index b951d59e3617..8fb4200f83f8 100644 --- a/drivers/media/dvb/ngene/ngene.h +++ b/drivers/media/dvb/ngene/ngene.h @@ -726,6 +726,7 @@ struct ngene { u32 fw_interface_version; u32 icounts; bool msi_enabled; + bool cmd_timeout_workaround; u8 *CmdDoneByte; int BootFirmware; -- cgit v1.2.3 From 478b3a42bdcd8d1cb57c91cabdc8b6164c639e42 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Wed, 19 May 2010 04:15:44 -0300 Subject: V4L/DVB: ngene: MSI cleanup MSI cleanup. Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ngene/ngene-core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c index 2bdcf59829d1..dcf1f45ff07c 100644 --- a/drivers/media/dvb/ngene/ngene-core.c +++ b/drivers/media/dvb/ngene/ngene-core.c @@ -1300,8 +1300,10 @@ static void ngene_stop(struct ngene *dev) ngwritel(0, NGENE_EVENT); ngwritel(0, NGENE_EVENT_HI); free_irq(dev->pci_dev->irq, dev); +#ifdef CONFIG_PCI_MSI if (dev->msi_enabled) pci_disable_msi(dev->pci_dev); +#endif } static int ngene_start(struct ngene *dev) @@ -1339,7 +1341,7 @@ static int ngene_start(struct ngene *dev) #ifdef CONFIG_PCI_MSI /* enable MSI if kernel and card support it */ - if (dev->card_info->msi_supported) { + if (pci_msi_enabled() && dev->card_info->msi_supported) { ngwritel(0, NGENE_INT_ENABLE); free_irq(dev->pci_dev->irq, dev); stat = pci_enable_msi(dev->pci_dev); @@ -1391,9 +1393,11 @@ static int ngene_start(struct ngene *dev) fail: ngwritel(0, NGENE_INT_ENABLE); free_irq(dev->pci_dev->irq, dev); +#ifdef CONFIG_PCI_MSI fail2: if (dev->msi_enabled) pci_disable_msi(dev->pci_dev); +#endif return stat; } -- cgit v1.2.3 From 51ff9ef13366b3752a8ab6229c466fd1bd671d3a Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Wed, 19 May 2010 04:17:18 -0300 Subject: V4L/DVB: ngene: Remove debug message Remove debug message. Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ngene/ngene-core.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c index dcf1f45ff07c..4caeb163a666 100644 --- a/drivers/media/dvb/ngene/ngene-core.c +++ b/drivers/media/dvb/ngene/ngene-core.c @@ -570,11 +570,7 @@ static int ngene_command_stream_control(struct ngene *dev, u8 stream, u16 BsSPI = ((stream & 1) ? 0x9800 : 0x9700); u16 BsSDO = 0x9B00; - /* down(&dev->stream_mutex); */ - while (down_trylock(&dev->stream_mutex)) { - printk(KERN_INFO DEVICE_NAME ": SC locked\n"); - msleep(1); - } + down(&dev->stream_mutex); memset(&com, 0, sizeof(com)); com.cmd.hdr.Opcode = CMD_CONTROL; com.cmd.hdr.Length = sizeof(struct FW_STREAM_CONTROL) - 2; -- cgit v1.2.3 From c463d93f22254f46168b49ad1149d1ec1e904711 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 9 May 2010 09:47:23 -0300 Subject: V4L/DVB: saa7115: add s_mbus_fmt op Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7115.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index 53b6fcde3800..d4cc20859975 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c @@ -1136,6 +1136,15 @@ static int saa711x_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f return 0; } +static int saa711x_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) +{ + if (fmt->code != V4L2_MBUS_FMT_FIXED) + return -EINVAL; + fmt->field = V4L2_FIELD_INTERLACED; + fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; + return saa711x_set_size(sd, fmt->width, fmt->height); +} + static int saa711x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) { if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) @@ -1558,6 +1567,7 @@ static const struct v4l2_subdev_video_ops saa711x_video_ops = { .s_crystal_freq = saa711x_s_crystal_freq, .g_fmt = saa711x_g_fmt, .s_fmt = saa711x_s_fmt, + .s_mbus_fmt = saa711x_s_mbus_fmt, .s_stream = saa711x_s_stream, .querystd = saa711x_querystd, .g_input_status = saa711x_g_input_status, -- cgit v1.2.3 From 96fd004fe40b8e3beff2a6e27ae0411a4d315f1e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 9 May 2010 09:48:50 -0300 Subject: V4L/DVB: cx25840: add support for s_mbus_fmt Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx25840/cx25840-core.c | 96 +++++++++++++++++------------- 1 file changed, 55 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 8b6fb3544376..f0cbc9d066bd 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -1025,59 +1025,72 @@ static int cx25840_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) return 0; } -static int cx25840_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +static int cx25840_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) { struct cx25840_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - struct v4l2_pix_format *pix; int HSC, VSC, Vsrc, Hsrc, filter, Vlines; int is_50Hz = !(state->std & V4L2_STD_525_60); - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - pix = &(fmt->fmt.pix); + if (fmt->code != V4L2_MBUS_FMT_FIXED) + return -EINVAL; - Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4; - Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4; + fmt->field = V4L2_FIELD_INTERLACED; + fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; - Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4; - Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4; + Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4; + Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4; - Vlines = pix->height + (is_50Hz ? 4 : 7); + Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4; + Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4; - if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) || - (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) { - v4l_err(client, "%dx%d is not a valid size!\n", - pix->width, pix->height); - return -ERANGE; - } + Vlines = fmt->height + (is_50Hz ? 4 : 7); - HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20); - VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9)); - VSC &= 0x1fff; + if ((fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) || + (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) { + v4l_err(client, "%dx%d is not a valid size!\n", + fmt->width, fmt->height); + return -ERANGE; + } - if (pix->width >= 385) - filter = 0; - else if (pix->width > 192) - filter = 1; - else if (pix->width > 96) - filter = 2; - else - filter = 3; - - v4l_dbg(1, cx25840_debug, client, "decoder set size %dx%d -> scale %ux%u\n", - pix->width, pix->height, HSC, VSC); - - /* HSCALE=HSC */ - cx25840_write(client, 0x418, HSC & 0xff); - cx25840_write(client, 0x419, (HSC >> 8) & 0xff); - cx25840_write(client, 0x41a, HSC >> 16); - /* VSCALE=VSC */ - cx25840_write(client, 0x41c, VSC & 0xff); - cx25840_write(client, 0x41d, VSC >> 8); - /* VS_INTRLACE=1 VFILT=filter */ - cx25840_write(client, 0x41e, 0x8 | filter); - break; + HSC = (Hsrc * (1 << 20)) / fmt->width - (1 << 20); + VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9)); + VSC &= 0x1fff; + + if (fmt->width >= 385) + filter = 0; + else if (fmt->width > 192) + filter = 1; + else if (fmt->width > 96) + filter = 2; + else + filter = 3; + + v4l_dbg(1, cx25840_debug, client, "decoder set size %dx%d -> scale %ux%u\n", + fmt->width, fmt->height, HSC, VSC); + + /* HSCALE=HSC */ + cx25840_write(client, 0x418, HSC & 0xff); + cx25840_write(client, 0x419, (HSC >> 8) & 0xff); + cx25840_write(client, 0x41a, HSC >> 16); + /* VSCALE=VSC */ + cx25840_write(client, 0x41c, VSC & 0xff); + cx25840_write(client, 0x41d, VSC >> 8); + /* VS_INTRLACE=1 VFILT=filter */ + cx25840_write(client, 0x41e, 0x8 | filter); + return 0; +} + +static int cx25840_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +{ + struct v4l2_mbus_framefmt mbus_fmt; + + switch (fmt->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + mbus_fmt.width = fmt->fmt.pix.width; + mbus_fmt.height = fmt->fmt.pix.height; + mbus_fmt.code = V4L2_MBUS_FMT_FIXED; + return cx25840_s_mbus_fmt(sd, &mbus_fmt); default: return -EINVAL; @@ -1629,6 +1642,7 @@ static const struct v4l2_subdev_video_ops cx25840_video_ops = { .s_routing = cx25840_s_video_routing, .g_fmt = cx25840_g_fmt, .s_fmt = cx25840_s_fmt, + .s_mbus_fmt = cx25840_s_mbus_fmt, .s_stream = cx25840_s_stream, }; -- cgit v1.2.3 From 6c69db9de7a8934bdeb690663fab6fe046203ac4 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 9 May 2010 09:50:34 -0300 Subject: V4L/DVB: saa717x: add support for s_mbus_fmt Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa717x.c | 47 ++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c index d521c648e157..422a3e222afa 100644 --- a/drivers/media/video/saa717x.c +++ b/drivers/media/video/saa717x.c @@ -1199,28 +1199,32 @@ static int saa717x_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register * } #endif -static int saa717x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +static int saa717x_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) { - struct v4l2_pix_format *pix; int prescale, h_scale, v_scale; - pix = &fmt->fmt.pix; v4l2_dbg(1, debug, sd, "decoder set size\n"); + if (fmt->code != V4L2_MBUS_FMT_FIXED) + return -EINVAL; + /* FIXME need better bounds checking here */ - if (pix->width < 1 || pix->width > 1440) + if (fmt->width < 1 || fmt->width > 1440) return -EINVAL; - if (pix->height < 1 || pix->height > 960) + if (fmt->height < 1 || fmt->height > 960) return -EINVAL; + fmt->field = V4L2_FIELD_INTERLACED; + fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; + /* scaling setting */ /* NTSC and interlace only */ - prescale = SAA717X_NTSC_WIDTH / pix->width; + prescale = SAA717X_NTSC_WIDTH / fmt->width; if (prescale == 0) prescale = 1; - h_scale = 1024 * SAA717X_NTSC_WIDTH / prescale / pix->width; + h_scale = 1024 * SAA717X_NTSC_WIDTH / prescale / fmt->width; /* interlace */ - v_scale = 512 * 2 * SAA717X_NTSC_HEIGHT / pix->height; + v_scale = 512 * 2 * SAA717X_NTSC_HEIGHT / fmt->height; /* Horizontal prescaling etc */ set_h_prescale(sd, 0, prescale); @@ -1241,22 +1245,32 @@ static int saa717x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) /* set video output size */ /* video number of pixels at output */ /* TASK A */ - saa717x_write(sd, 0x5C, (u8)(pix->width & 0xFF)); - saa717x_write(sd, 0x5D, (u8)((pix->width >> 8) & 0xFF)); + saa717x_write(sd, 0x5C, (u8)(fmt->width & 0xFF)); + saa717x_write(sd, 0x5D, (u8)((fmt->width >> 8) & 0xFF)); /* TASK B */ - saa717x_write(sd, 0x9C, (u8)(pix->width & 0xFF)); - saa717x_write(sd, 0x9D, (u8)((pix->width >> 8) & 0xFF)); + saa717x_write(sd, 0x9C, (u8)(fmt->width & 0xFF)); + saa717x_write(sd, 0x9D, (u8)((fmt->width >> 8) & 0xFF)); /* video number of lines at output */ /* TASK A */ - saa717x_write(sd, 0x5E, (u8)(pix->height & 0xFF)); - saa717x_write(sd, 0x5F, (u8)((pix->height >> 8) & 0xFF)); + saa717x_write(sd, 0x5E, (u8)(fmt->height & 0xFF)); + saa717x_write(sd, 0x5F, (u8)((fmt->height >> 8) & 0xFF)); /* TASK B */ - saa717x_write(sd, 0x9E, (u8)(pix->height & 0xFF)); - saa717x_write(sd, 0x9F, (u8)((pix->height >> 8) & 0xFF)); + saa717x_write(sd, 0x9E, (u8)(fmt->height & 0xFF)); + saa717x_write(sd, 0x9F, (u8)((fmt->height >> 8) & 0xFF)); return 0; } +static int saa717x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +{ + struct v4l2_mbus_framefmt mbus_fmt; + + mbus_fmt.width = fmt->fmt.pix.width; + mbus_fmt.height = fmt->fmt.pix.height; + mbus_fmt.code = V4L2_MBUS_FMT_FIXED; + return saa717x_s_mbus_fmt(sd, &mbus_fmt); +} + static int saa717x_s_radio(struct v4l2_subdev *sd) { struct saa717x_state *decoder = to_state(sd); @@ -1404,6 +1418,7 @@ static const struct v4l2_subdev_tuner_ops saa717x_tuner_ops = { static const struct v4l2_subdev_video_ops saa717x_video_ops = { .s_routing = saa717x_s_video_routing, .s_fmt = saa717x_s_fmt, + .s_mbus_fmt = saa717x_s_mbus_fmt, .s_stream = saa717x_s_stream, }; -- cgit v1.2.3 From 475977ac3db72c008f5aaa5f19bd991b72f26e42 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 8 May 2010 16:28:51 -0300 Subject: V4L/DVB: ivtv: convert to use s_mbus_fmt Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-controls.c | 10 +++++----- drivers/media/video/ivtv/ivtv-ioctl.c | 6 +++++- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c index b59475bfc243..b588e30cbcf0 100644 --- a/drivers/media/video/ivtv/ivtv-controls.c +++ b/drivers/media/video/ivtv/ivtv-controls.c @@ -267,13 +267,13 @@ int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) if (p.video_encoding != itv->params.video_encoding) { int is_mpeg1 = p.video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1; - struct v4l2_format fmt; + struct v4l2_mbus_framefmt fmt; /* fix videodecoder resolution */ - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - fmt.fmt.pix.width = itv->params.width / (is_mpeg1 ? 2 : 1); - fmt.fmt.pix.height = itv->params.height; - v4l2_subdev_call(itv->sd_video, video, s_fmt, &fmt); + fmt.width = itv->params.width / (is_mpeg1 ? 2 : 1); + fmt.height = itv->params.height; + fmt.code = V4L2_MBUS_FMT_FIXED; + v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &fmt); } err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p); if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt) diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index fa9f0d958f96..11ac2fa33ef7 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -569,6 +569,7 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f struct ivtv_open_id *id = fh; struct ivtv *itv = id->itv; struct cx2341x_mpeg_params *p = &itv->params; + struct v4l2_mbus_framefmt mbus_fmt; int ret = ivtv_try_fmt_vid_cap(file, fh, fmt); int w = fmt->fmt.pix.width; int h = fmt->fmt.pix.height; @@ -586,7 +587,10 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f p->height = h; if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) fmt->fmt.pix.width /= 2; - v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt); + mbus_fmt.width = fmt->fmt.pix.width; + mbus_fmt.height = h; + mbus_fmt.code = V4L2_MBUS_FMT_FIXED; + v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &mbus_fmt); return ivtv_g_fmt_vid_cap(file, fh, fmt); } -- cgit v1.2.3 From e17ad1de031f2d5cade70eb0469a53f17d90d7c2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 9 May 2010 09:54:58 -0300 Subject: V4L/DVB: cx18: add s_mbus_fmt support Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-av-core.c | 126 +++++++++++++++++--------------- 1 file changed, 69 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c index 0e5006b14279..39f484621a45 100644 --- a/drivers/media/video/cx18/cx18-av-core.c +++ b/drivers/media/video/cx18/cx18-av-core.c @@ -1028,80 +1028,91 @@ static int cx18_av_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) return cx18_av_g_sliced_fmt(sd, &fmt->fmt.sliced); } -static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +static int cx18_av_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) { struct cx18_av_state *state = to_cx18_av_state(sd); struct cx18 *cx = v4l2_get_subdevdata(sd); - - struct v4l2_pix_format *pix; int HSC, VSC, Vsrc, Hsrc, filter, Vlines; int is_50Hz = !(state->std & V4L2_STD_525_60); - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - pix = &(fmt->fmt.pix); + if (fmt->code != V4L2_MBUS_FMT_FIXED) + return -EINVAL; - Vsrc = (cx18_av_read(cx, 0x476) & 0x3f) << 4; - Vsrc |= (cx18_av_read(cx, 0x475) & 0xf0) >> 4; + fmt->field = V4L2_FIELD_INTERLACED; + fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; - Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4; - Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4; + Vsrc = (cx18_av_read(cx, 0x476) & 0x3f) << 4; + Vsrc |= (cx18_av_read(cx, 0x475) & 0xf0) >> 4; - /* - * This adjustment reflects the excess of vactive, set in - * cx18_av_std_setup(), above standard values: - * - * 480 + 1 for 60 Hz systems - * 576 + 3 for 50 Hz systems - */ - Vlines = pix->height + (is_50Hz ? 3 : 1); + Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4; + Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4; - /* - * Invalid height and width scaling requests are: - * 1. width less than 1/16 of the source width - * 2. width greater than the source width - * 3. height less than 1/8 of the source height - * 4. height greater than the source height - */ - if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) || - (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) { - CX18_ERR_DEV(sd, "%dx%d is not a valid size!\n", - pix->width, pix->height); - return -ERANGE; - } + /* + * This adjustment reflects the excess of vactive, set in + * cx18_av_std_setup(), above standard values: + * + * 480 + 1 for 60 Hz systems + * 576 + 3 for 50 Hz systems + */ + Vlines = fmt->height + (is_50Hz ? 3 : 1); - HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20); - VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9)); - VSC &= 0x1fff; + /* + * Invalid height and width scaling requests are: + * 1. width less than 1/16 of the source width + * 2. width greater than the source width + * 3. height less than 1/8 of the source height + * 4. height greater than the source height + */ + if ((fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) || + (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) { + CX18_ERR_DEV(sd, "%dx%d is not a valid size!\n", + fmt->width, fmt->height); + return -ERANGE; + } - if (pix->width >= 385) - filter = 0; - else if (pix->width > 192) - filter = 1; - else if (pix->width > 96) - filter = 2; - else - filter = 3; + HSC = (Hsrc * (1 << 20)) / fmt->width - (1 << 20); + VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9)); + VSC &= 0x1fff; - CX18_DEBUG_INFO_DEV(sd, - "decoder set size %dx%d -> scale %ux%u\n", - pix->width, pix->height, HSC, VSC); - - /* HSCALE=HSC */ - cx18_av_write(cx, 0x418, HSC & 0xff); - cx18_av_write(cx, 0x419, (HSC >> 8) & 0xff); - cx18_av_write(cx, 0x41a, HSC >> 16); - /* VSCALE=VSC */ - cx18_av_write(cx, 0x41c, VSC & 0xff); - cx18_av_write(cx, 0x41d, VSC >> 8); - /* VS_INTRLACE=1 VFILT=filter */ - cx18_av_write(cx, 0x41e, 0x8 | filter); - break; + if (fmt->width >= 385) + filter = 0; + else if (fmt->width > 192) + filter = 1; + else if (fmt->width > 96) + filter = 2; + else + filter = 3; + + CX18_DEBUG_INFO_DEV(sd, + "decoder set size %dx%d -> scale %ux%u\n", + fmt->width, fmt->height, HSC, VSC); + + /* HSCALE=HSC */ + cx18_av_write(cx, 0x418, HSC & 0xff); + cx18_av_write(cx, 0x419, (HSC >> 8) & 0xff); + cx18_av_write(cx, 0x41a, HSC >> 16); + /* VSCALE=VSC */ + cx18_av_write(cx, 0x41c, VSC & 0xff); + cx18_av_write(cx, 0x41d, VSC >> 8); + /* VS_INTRLACE=1 VFILT=filter */ + cx18_av_write(cx, 0x41e, 0x8 | filter); + return 0; +} + +static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +{ + struct v4l2_mbus_framefmt mbus_fmt; + + switch (fmt->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + mbus_fmt.width = fmt->fmt.pix.width; + mbus_fmt.height = fmt->fmt.pix.height; + mbus_fmt.code = V4L2_MBUS_FMT_FIXED; + return cx18_av_s_mbus_fmt(sd, &mbus_fmt); default: return -EINVAL; } - return 0; } static int cx18_av_s_stream(struct v4l2_subdev *sd, int enable) @@ -1400,6 +1411,7 @@ static const struct v4l2_subdev_video_ops cx18_av_video_ops = { .s_stream = cx18_av_s_stream, .g_fmt = cx18_av_g_fmt, .s_fmt = cx18_av_s_fmt, + .s_mbus_fmt = cx18_av_s_mbus_fmt, }; static const struct v4l2_subdev_vbi_ops cx18_av_vbi_ops = { -- cgit v1.2.3 From 9e36eabc8a6fb87d9b97057e0d0f5195c475fbdc Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 8 May 2010 16:37:53 -0300 Subject: V4L/DVB: cx18: remove old g/s_fmt from the cx18_av subdev cx18 has now switched over completely to the new mediabus subdev ops. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-av-core.c | 25 ------------------------- drivers/media/video/cx18/cx18-controls.c | 11 +++++------ drivers/media/video/cx18/cx18-ioctl.c | 8 +++++--- 3 files changed, 10 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c index 39f484621a45..54371f6d6b5f 100644 --- a/drivers/media/video/cx18/cx18-av-core.c +++ b/drivers/media/video/cx18/cx18-av-core.c @@ -1021,13 +1021,6 @@ static int cx18_av_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) return -EINVAL; } -static int cx18_av_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) -{ - if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) - return -EINVAL; - return cx18_av_g_sliced_fmt(sd, &fmt->fmt.sliced); -} - static int cx18_av_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) { struct cx18_av_state *state = to_cx18_av_state(sd); @@ -1099,22 +1092,6 @@ static int cx18_av_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt return 0; } -static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) -{ - struct v4l2_mbus_framefmt mbus_fmt; - - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - mbus_fmt.width = fmt->fmt.pix.width; - mbus_fmt.height = fmt->fmt.pix.height; - mbus_fmt.code = V4L2_MBUS_FMT_FIXED; - return cx18_av_s_mbus_fmt(sd, &mbus_fmt); - - default: - return -EINVAL; - } -} - static int cx18_av_s_stream(struct v4l2_subdev *sd, int enable) { struct cx18 *cx = v4l2_get_subdevdata(sd); @@ -1409,8 +1386,6 @@ static const struct v4l2_subdev_audio_ops cx18_av_audio_ops = { static const struct v4l2_subdev_video_ops cx18_av_video_ops = { .s_routing = cx18_av_s_video_routing, .s_stream = cx18_av_s_stream, - .g_fmt = cx18_av_g_fmt, - .s_fmt = cx18_av_s_fmt, .s_mbus_fmt = cx18_av_s_mbus_fmt, }; diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c index 4b4b46544d5a..67043c7b452b 100644 --- a/drivers/media/video/cx18/cx18-controls.c +++ b/drivers/media/video/cx18/cx18-controls.c @@ -297,14 +297,13 @@ int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) if (p.video_encoding != cx->params.video_encoding) { int is_mpeg1 = p.video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1; - struct v4l2_format fmt; + struct v4l2_mbus_framefmt fmt; /* fix videodecoder resolution */ - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - fmt.fmt.pix.width = cx->params.width - / (is_mpeg1 ? 2 : 1); - fmt.fmt.pix.height = cx->params.height; - v4l2_subdev_call(cx->sd_av, video, s_fmt, &fmt); + fmt.width = cx->params.width / (is_mpeg1 ? 2 : 1); + fmt.height = cx->params.height; + fmt.code = V4L2_MBUS_FMT_FIXED; + v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &fmt); } priv.cx = cx; priv.s = &cx->streams[id->type]; diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 2530fc54daaf..b5b221c8a725 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -274,6 +274,7 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh, { struct cx18_open_id *id = fh; struct cx18 *cx = id->cx; + struct v4l2_mbus_framefmt mbus_fmt; int ret; int w, h; @@ -293,9 +294,10 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh, if (atomic_read(&cx->ana_capturing) > 0) return -EBUSY; - cx->params.width = w; - cx->params.height = h; - v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt); + mbus_fmt.width = cx->params.width = w; + mbus_fmt.height = cx->params.height = h; + mbus_fmt.code = V4L2_MBUS_FMT_FIXED; + v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &mbus_fmt); return cx18_g_fmt_vid_cap(file, fh, fmt); } -- cgit v1.2.3 From 60298c99f792bb2fe12137360d448c72234b2d0b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 8 May 2010 16:39:01 -0300 Subject: V4L/DVB: saa7127: remove obsolete g_fmt support Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7127.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c index 87986ad62f86..79fffcf39ba8 100644 --- a/drivers/media/video/saa7127.c +++ b/drivers/media/video/saa7127.c @@ -645,13 +645,6 @@ static int saa7127_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f return 0; } -static int saa7127_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) -{ - if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) - return -EINVAL; - return saa7127_g_sliced_fmt(sd, &fmt->fmt.sliced); -} - static int saa7127_s_vbi_data(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *data) { switch (data->id) { @@ -731,7 +724,6 @@ static const struct v4l2_subdev_core_ops saa7127_core_ops = { }; static const struct v4l2_subdev_video_ops saa7127_video_ops = { - .g_fmt = saa7127_g_fmt, .s_std_output = saa7127_s_std_output, .s_routing = saa7127_s_routing, .s_stream = saa7127_s_stream, -- cgit v1.2.3 From 66e9df07d362b63a594e8663260e0430ba4a17bf Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 8 May 2010 16:40:23 -0300 Subject: V4L/DVB: saa717x: remove obsolete s_fmt op Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa717x.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c index 422a3e222afa..78d69950c00a 100644 --- a/drivers/media/video/saa717x.c +++ b/drivers/media/video/saa717x.c @@ -1261,16 +1261,6 @@ static int saa717x_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt return 0; } -static int saa717x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) -{ - struct v4l2_mbus_framefmt mbus_fmt; - - mbus_fmt.width = fmt->fmt.pix.width; - mbus_fmt.height = fmt->fmt.pix.height; - mbus_fmt.code = V4L2_MBUS_FMT_FIXED; - return saa717x_s_mbus_fmt(sd, &mbus_fmt); -} - static int saa717x_s_radio(struct v4l2_subdev *sd) { struct saa717x_state *decoder = to_state(sd); @@ -1417,7 +1407,6 @@ static const struct v4l2_subdev_tuner_ops saa717x_tuner_ops = { static const struct v4l2_subdev_video_ops saa717x_video_ops = { .s_routing = saa717x_s_video_routing, - .s_fmt = saa717x_s_fmt, .s_mbus_fmt = saa717x_s_mbus_fmt, .s_stream = saa717x_s_stream, }; -- cgit v1.2.3 From 51623ef9aedd8b786a12a4475201827ee85d285c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 9 May 2010 09:39:58 -0300 Subject: V4L/DVB: saa6752hs: add g/s_mbus_fmt support Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa6752hs.c | 64 +++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index 1eabff6b2456..852040b6b5a6 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c @@ -846,24 +846,38 @@ static int saa6752hs_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_control return 0; } -static int saa6752hs_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int saa6752hs_g_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f) { struct saa6752hs_state *h = to_state(sd); if (h->video_format == SAA6752HS_VF_UNKNOWN) h->video_format = SAA6752HS_VF_D1; - f->fmt.pix.width = - v4l2_format_table[h->video_format].fmt.pix.width; - f->fmt.pix.height = - v4l2_format_table[h->video_format].fmt.pix.height; + f->width = v4l2_format_table[h->video_format].fmt.pix.width; + f->height = v4l2_format_table[h->video_format].fmt.pix.height; + f->code = V4L2_MBUS_FMT_FIXED; + f->field = V4L2_FIELD_INTERLACED; + f->colorspace = V4L2_COLORSPACE_SMPTE170M; return 0; } -static int saa6752hs_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int saa6752hs_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +{ + struct v4l2_mbus_framefmt mbus_fmt; + int err = saa6752hs_g_mbus_fmt(sd, &mbus_fmt); + + f->fmt.pix.width = mbus_fmt.width; + f->fmt.pix.height = mbus_fmt.height; + return err; +} + +static int saa6752hs_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f) { struct saa6752hs_state *h = to_state(sd); int dist_352, dist_480, dist_720; + if (f->code != V4L2_MBUS_FMT_FIXED) + return -EINVAL; + /* FIXME: translate and round width/height into EMPRESS subsample type: @@ -876,31 +890,43 @@ static int saa6752hs_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) D1 | 720x576 | 720x480 */ - dist_352 = abs(f->fmt.pix.width - 352); - dist_480 = abs(f->fmt.pix.width - 480); - dist_720 = abs(f->fmt.pix.width - 720); + dist_352 = abs(f->width - 352); + dist_480 = abs(f->width - 480); + dist_720 = abs(f->width - 720); if (dist_720 < dist_480) { - f->fmt.pix.width = 720; - f->fmt.pix.height = 576; + f->width = 720; + f->height = 576; h->video_format = SAA6752HS_VF_D1; } else if (dist_480 < dist_352) { - f->fmt.pix.width = 480; - f->fmt.pix.height = 576; + f->width = 480; + f->height = 576; h->video_format = SAA6752HS_VF_2_3_D1; } else { - f->fmt.pix.width = 352; - if (abs(f->fmt.pix.height - 576) < - abs(f->fmt.pix.height - 288)) { - f->fmt.pix.height = 576; + f->width = 352; + if (abs(f->height - 576) < + abs(f->height - 288)) { + f->height = 576; h->video_format = SAA6752HS_VF_1_2_D1; } else { - f->fmt.pix.height = 288; + f->height = 288; h->video_format = SAA6752HS_VF_SIF; } } + f->field = V4L2_FIELD_INTERLACED; + f->colorspace = V4L2_COLORSPACE_SMPTE170M; return 0; } +static int saa6752hs_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +{ + struct v4l2_mbus_framefmt mbus_fmt; + + mbus_fmt.width = f->fmt.pix.width; + mbus_fmt.height = f->fmt.pix.height; + mbus_fmt.code = V4L2_MBUS_FMT_FIXED; + return saa6752hs_s_mbus_fmt(sd, &mbus_fmt); +} + static int saa6752hs_s_std(struct v4l2_subdev *sd, v4l2_std_id std) { struct saa6752hs_state *h = to_state(sd); @@ -934,6 +960,8 @@ static const struct v4l2_subdev_core_ops saa6752hs_core_ops = { static const struct v4l2_subdev_video_ops saa6752hs_video_ops = { .s_fmt = saa6752hs_s_fmt, .g_fmt = saa6752hs_g_fmt, + .s_mbus_fmt = saa6752hs_s_mbus_fmt, + .g_mbus_fmt = saa6752hs_g_mbus_fmt, }; static const struct v4l2_subdev_ops saa6752hs_ops = { -- cgit v1.2.3 From 31bf95fb5725013fd7d95d6d5b1e45f4c88b1f56 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 9 May 2010 09:41:41 -0300 Subject: V4L/DVB: saa7134: convert to use the new mbus API Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa6752hs.c | 22 ---------------------- drivers/media/video/saa7134/saa7134-empress.c | 9 +++++++-- 2 files changed, 7 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index 852040b6b5a6..40fd31ca7716 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c @@ -860,16 +860,6 @@ static int saa6752hs_g_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefm return 0; } -static int saa6752hs_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) -{ - struct v4l2_mbus_framefmt mbus_fmt; - int err = saa6752hs_g_mbus_fmt(sd, &mbus_fmt); - - f->fmt.pix.width = mbus_fmt.width; - f->fmt.pix.height = mbus_fmt.height; - return err; -} - static int saa6752hs_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f) { struct saa6752hs_state *h = to_state(sd); @@ -917,16 +907,6 @@ static int saa6752hs_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefm return 0; } -static int saa6752hs_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) -{ - struct v4l2_mbus_framefmt mbus_fmt; - - mbus_fmt.width = f->fmt.pix.width; - mbus_fmt.height = f->fmt.pix.height; - mbus_fmt.code = V4L2_MBUS_FMT_FIXED; - return saa6752hs_s_mbus_fmt(sd, &mbus_fmt); -} - static int saa6752hs_s_std(struct v4l2_subdev *sd, v4l2_std_id std) { struct saa6752hs_state *h = to_state(sd); @@ -958,8 +938,6 @@ static const struct v4l2_subdev_core_ops saa6752hs_core_ops = { }; static const struct v4l2_subdev_video_ops saa6752hs_video_ops = { - .s_fmt = saa6752hs_s_fmt, - .g_fmt = saa6752hs_g_fmt, .s_mbus_fmt = saa6752hs_s_mbus_fmt, .g_mbus_fmt = saa6752hs_g_mbus_fmt, }; diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index ea877a50f52d..e763f9fd0133 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -223,9 +223,11 @@ static int empress_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_dev *dev = file->private_data; + struct v4l2_mbus_framefmt mbus_fmt; - saa_call_all(dev, video, g_fmt, f); + saa_call_all(dev, video, g_mbus_fmt, &mbus_fmt); + v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; @@ -236,8 +238,11 @@ static int empress_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_dev *dev = file->private_data; + struct v4l2_mbus_framefmt mbus_fmt; - saa_call_all(dev, video, s_fmt, f); + v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); + saa_call_all(dev, video, s_mbus_fmt, &mbus_fmt); + v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; -- cgit v1.2.3 From fa190ee91fcc3800f2c5d14810dc1b48a4b5d4e5 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 8 May 2010 17:16:18 -0300 Subject: V4L/DVB: pvrusb2: convert to s_mbus_fmt Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-hdw.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 2c3f845c3e5c..70ea578d6266 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -3069,14 +3069,14 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw) } if (hdw->res_hor_dirty || hdw->res_ver_dirty || hdw->force_dirty) { - struct v4l2_format fmt; + struct v4l2_mbus_framefmt fmt; memset(&fmt, 0, sizeof(fmt)); - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - fmt.fmt.pix.width = hdw->res_hor_val; - fmt.fmt.pix.height = hdw->res_ver_val; + fmt.width = hdw->res_hor_val; + fmt.height = hdw->res_ver_val; + fmt.code = V4L2_MBUS_FMT_FIXED; pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_size(%dx%d)", - fmt.fmt.pix.width, fmt.fmt.pix.height); - v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_fmt, &fmt); + fmt.width, fmt.height); + v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_mbus_fmt, &fmt); } if (hdw->srate_dirty || hdw->force_dirty) { -- cgit v1.2.3 From cc99113b8cfb8b9685490db0b9bf0d26c9705ad3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 9 May 2010 10:09:28 -0300 Subject: V4L/DVB: cx23885: convert to s_mbus_fmt Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-video.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 543b854f6a62..4e44dcda3875 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -976,6 +976,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, { struct cx23885_fh *fh = priv; struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; + struct v4l2_mbus_framefmt mbus_fmt; int err; dprintk(2, "%s()\n", __func__); @@ -989,7 +990,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, fh->vidq.field = f->fmt.pix.field; dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width, fh->height, fh->vidq.field); - call_all(dev, video, s_fmt, f); + v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); + call_all(dev, video, s_mbus_fmt, &mbus_fmt); + v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); return 0; } -- cgit v1.2.3 From 112cb4a8a092a6338a0e2309aac134e502f2a489 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 9 May 2010 10:11:01 -0300 Subject: V4L/DVB: cx231xx: convert to s_mbus_fmt Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx231xx/cx231xx-video.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c index 2782709b263f..e76014561aa7 100644 --- a/drivers/media/video/cx231xx/cx231xx-video.c +++ b/drivers/media/video/cx231xx/cx231xx-video.c @@ -993,6 +993,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct cx231xx *dev = fh->dev; int rc; struct cx231xx_fmt *fmt; + struct v4l2_mbus_framefmt mbus_fmt; rc = check_dev(dev); if (rc < 0) @@ -1026,7 +1027,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, dev->format = fmt; get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); - call_all(dev, video, s_fmt, f); + v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); + call_all(dev, video, s_mbus_fmt, &mbus_fmt); + v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); /* Set the correct alternate setting for this resolution */ cx231xx_resolution_set(dev); -- cgit v1.2.3 From c1658cafd1910cbec1b546ecd1f76e8fc99fc513 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 8 May 2010 17:20:00 -0300 Subject: V4L/DVB: cx24850: remove obsolete g/s_fmt ops Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx25840/cx25840-core.c | 31 ------------------------------ 1 file changed, 31 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index f0cbc9d066bd..bb4872b2ceb0 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -1014,17 +1014,6 @@ static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) /* ----------------------------------------------------------------------- */ -static int cx25840_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) -{ - switch (fmt->type) { - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - return cx25840_g_sliced_fmt(sd, &fmt->fmt.sliced); - default: - return -EINVAL; - } - return 0; -} - static int cx25840_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) { struct cx25840_state *state = to_state(sd); @@ -1081,24 +1070,6 @@ static int cx25840_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt return 0; } -static int cx25840_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) -{ - struct v4l2_mbus_framefmt mbus_fmt; - - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - mbus_fmt.width = fmt->fmt.pix.width; - mbus_fmt.height = fmt->fmt.pix.height; - mbus_fmt.code = V4L2_MBUS_FMT_FIXED; - return cx25840_s_mbus_fmt(sd, &mbus_fmt); - - default: - return -EINVAL; - } - - return 0; -} - /* ----------------------------------------------------------------------- */ static void log_video_status(struct i2c_client *client) @@ -1640,8 +1611,6 @@ static const struct v4l2_subdev_audio_ops cx25840_audio_ops = { static const struct v4l2_subdev_video_ops cx25840_video_ops = { .s_routing = cx25840_s_video_routing, - .g_fmt = cx25840_g_fmt, - .s_fmt = cx25840_s_fmt, .s_mbus_fmt = cx25840_s_mbus_fmt, .s_stream = cx25840_s_stream, }; -- cgit v1.2.3 From 029ed3261021c76f0b8538a2f715d89506555676 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 8 May 2010 17:20:35 -0300 Subject: V4L/DVB: saa7115: remove obsolete g/s_fmt ops Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7115.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index d4cc20859975..76da74368680 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c @@ -1117,13 +1117,6 @@ static int saa711x_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f return 0; } -static int saa711x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) -{ - if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) - return -EINVAL; - return saa711x_g_sliced_fmt(sd, &fmt->fmt.sliced); -} - static int saa711x_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt) { saa711x_set_lcr(sd, NULL); @@ -1145,14 +1138,6 @@ static int saa711x_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt return saa711x_set_size(sd, fmt->width, fmt->height); } -static int saa711x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) -{ - if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - return saa711x_set_size(sd, fmt->fmt.pix.width, fmt->fmt.pix.height); -} - /* Decode the sliced VBI data stream as created by the saa7115. The format is described in the saa7115 datasheet in Tables 25 and 26 and in Figure 33. @@ -1565,8 +1550,6 @@ static const struct v4l2_subdev_audio_ops saa711x_audio_ops = { static const struct v4l2_subdev_video_ops saa711x_video_ops = { .s_routing = saa711x_s_routing, .s_crystal_freq = saa711x_s_crystal_freq, - .g_fmt = saa711x_g_fmt, - .s_fmt = saa711x_s_fmt, .s_mbus_fmt = saa711x_s_mbus_fmt, .s_stream = saa711x_s_stream, .querystd = saa711x_querystd, -- cgit v1.2.3 From ea01b11a07961aabbaec58d572b24f3df4b8065c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 9 May 2010 10:19:25 -0300 Subject: V4L/DVB: mt9v011: add enum/try/s_mbus_fmt support Note that this driver is only used by em28xx and that em28xx does not actually call the enum/try/s_fmt ops of mt9v011. So these functions have never been tested. And in fact the driver really implements cropping instead of scaling. So it seems to be doing the wrong thing :-( Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/mt9v011.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/mt9v011.c b/drivers/media/video/mt9v011.c index 72e55be0b4ab..f5e778d5ca9f 100644 --- a/drivers/media/video/mt9v011.c +++ b/drivers/media/video/mt9v011.c @@ -392,27 +392,25 @@ static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) return 0; } -static int mt9v011_enum_fmt(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt) +static int mt9v011_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, + enum v4l2_mbus_pixelcode *code) { - if (fmt->index > 0) + if (index > 0) return -EINVAL; - fmt->flags = 0; - strcpy(fmt->description, "8 bpp Bayer GRGR..BGBG"); - fmt->pixelformat = V4L2_PIX_FMT_SGRBG8; - + *code = V4L2_MBUS_FMT_SGRBG8_1X8; return 0; } -static int mt9v011_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +static int mt9v011_try_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) { - struct v4l2_pix_format *pix = &fmt->fmt.pix; - - if (pix->pixelformat != V4L2_PIX_FMT_SGRBG8) + if (fmt->code != V4L2_MBUS_FMT_SGRBG8_1X8) return -EINVAL; - v4l_bound_align_image(&pix->width, 48, 639, 1, - &pix->height, 32, 480, 1, 0); + v4l_bound_align_image(&fmt->width, 48, 639, 1, + &fmt->height, 32, 480, 1, 0); + fmt->field = V4L2_FIELD_NONE; + fmt->colorspace = V4L2_COLORSPACE_SRGB; return 0; } @@ -455,18 +453,17 @@ static int mt9v011_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) return 0; } -static int mt9v011_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +static int mt9v011_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) { - struct v4l2_pix_format *pix = &fmt->fmt.pix; struct mt9v011 *core = to_mt9v011(sd); int rc; - rc = mt9v011_try_fmt(sd, fmt); + rc = mt9v011_try_mbus_fmt(sd, fmt); if (rc < 0) return -EINVAL; - core->width = pix->width; - core->height = pix->height; + core->width = fmt->width; + core->height = fmt->height; set_res(sd); @@ -549,9 +546,9 @@ static const struct v4l2_subdev_core_ops mt9v011_core_ops = { }; static const struct v4l2_subdev_video_ops mt9v011_video_ops = { - .enum_fmt = mt9v011_enum_fmt, - .try_fmt = mt9v011_try_fmt, - .s_fmt = mt9v011_s_fmt, + .enum_mbus_fmt = mt9v011_enum_mbus_fmt, + .try_mbus_fmt = mt9v011_try_mbus_fmt, + .s_mbus_fmt = mt9v011_s_mbus_fmt, .g_parm = mt9v011_g_parm, .s_parm = mt9v011_s_parm, }; -- cgit v1.2.3 From 468df208e84d1e7c65b0d005dbbf09f5aea92409 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 8 May 2010 17:26:00 -0300 Subject: V4L/DVB: tvp5150: remove obsolete g/s_fmt ops Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tvp5150.c | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index 47f0582d50a5..1654f65cca7c 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c @@ -934,17 +934,6 @@ static int tvp5150_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f return 0; } -static int tvp5150_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) -{ - switch (fmt->type) { - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - return tvp5150_s_sliced_fmt(sd, &fmt->fmt.sliced); - - default: - return -EINVAL; - } -} - static int tvp5150_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi) { int i, mask = 0; @@ -960,13 +949,6 @@ static int tvp5150_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f return 0; } -static int tvp5150_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) -{ - if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) - return -EINVAL; - return tvp5150_g_sliced_fmt(sd, &fmt->fmt.sliced); -} - static int tvp5150_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) { @@ -1054,8 +1036,6 @@ static const struct v4l2_subdev_tuner_ops tvp5150_tuner_ops = { static const struct v4l2_subdev_video_ops tvp5150_video_ops = { .s_routing = tvp5150_s_routing, - .g_fmt = tvp5150_g_fmt, - .s_fmt = tvp5150_s_fmt, }; static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops = { -- cgit v1.2.3 From cf69b808caf8e729949cf20446bec0b9ace033b7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 9 May 2010 07:39:32 -0300 Subject: V4L/DVB: au8522_decoder: g/s_fmt doesn't do anything: remove g/s_fmt is going to disappear, so if it is not doing anything, then just remove it. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/au8522_decoder.c | 26 -------------------------- 1 file changed, 26 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c index 68dba3a4b4da..29cdbfe36852 100644 --- a/drivers/media/dvb/frontends/au8522_decoder.c +++ b/drivers/media/dvb/frontends/au8522_decoder.c @@ -567,30 +567,6 @@ static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) /* ----------------------------------------------------------------------- */ -static int au8522_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) -{ - switch (fmt->type) { - default: - return -EINVAL; - } - return 0; -} - -static int au8522_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) -{ - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - /* Not yet implemented */ - break; - default: - return -EINVAL; - } - - return 0; -} - -/* ----------------------------------------------------------------------- */ - #ifdef CONFIG_VIDEO_ADV_DEBUG static int au8522_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) @@ -772,8 +748,6 @@ static const struct v4l2_subdev_audio_ops au8522_audio_ops = { static const struct v4l2_subdev_video_ops au8522_video_ops = { .s_routing = au8522_s_video_routing, - .g_fmt = au8522_g_fmt, - .s_fmt = au8522_s_fmt, .s_stream = au8522_s_stream, }; -- cgit v1.2.3 From 3805f201934e5384f6e941222dc1968cb638a88c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 8 May 2010 17:55:00 -0300 Subject: V4L/DVB: v4l2-subdev.h: fix enum_mbus_fmt prototype enum_mbus_fmt received an index argument that was defined as an int instead of an unsigned int. This is now fixed. This had the knock-on effect that the index argument in the callback get_formats in soc_camera.h also had to be changed to unsigned int. Signed-off-by: Hans Verkuil Acked-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ak881x.c | 2 +- drivers/media/video/mt9m001.c | 4 ++-- drivers/media/video/mt9m111.c | 4 ++-- drivers/media/video/mt9t031.c | 2 +- drivers/media/video/mt9t112.c | 4 ++-- drivers/media/video/mt9v022.c | 4 ++-- drivers/media/video/mx3_camera.c | 4 ++-- drivers/media/video/ov772x.c | 4 ++-- drivers/media/video/ov9640.c | 4 ++-- drivers/media/video/pxa_camera.c | 4 ++-- drivers/media/video/rj54n1cb0c.c | 4 ++-- drivers/media/video/sh_mobile_ceu_camera.c | 4 ++-- drivers/media/video/soc_camera.c | 3 ++- drivers/media/video/soc_camera_platform.c | 2 +- drivers/media/video/tw9910.c | 2 +- include/media/soc_camera.h | 2 +- include/media/v4l2-subdev.h | 2 +- 17 files changed, 28 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/ak881x.c b/drivers/media/video/ak881x.c index 35390d4717b9..3006a2c80f47 100644 --- a/drivers/media/video/ak881x.c +++ b/drivers/media/video/ak881x.c @@ -141,7 +141,7 @@ static int ak881x_s_mbus_fmt(struct v4l2_subdev *sd, return ak881x_try_g_mbus_fmt(sd, mf); } -static int ak881x_enum_mbus_fmt(struct v4l2_subdev *sd, int index, +static int ak881x_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index, enum v4l2_mbus_pixelcode *code) { if (index) diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index b62c0bd3f8ea..992ab8cb89ae 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c @@ -701,13 +701,13 @@ static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = { #endif }; -static int mt9m001_enum_fmt(struct v4l2_subdev *sd, int index, +static int mt9m001_enum_fmt(struct v4l2_subdev *sd, unsigned int index, enum v4l2_mbus_pixelcode *code) { struct i2c_client *client = sd->priv; struct mt9m001 *mt9m001 = to_mt9m001(client); - if ((unsigned int)index >= mt9m001->num_fmts) + if (index >= mt9m001->num_fmts) return -EINVAL; *code = mt9m001->fmts[index].code; diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index d35f536f9fc3..bac0c5d4070c 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -999,10 +999,10 @@ static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = { #endif }; -static int mt9m111_enum_fmt(struct v4l2_subdev *sd, int index, +static int mt9m111_enum_fmt(struct v4l2_subdev *sd, unsigned int index, enum v4l2_mbus_pixelcode *code) { - if ((unsigned int)index >= ARRAY_SIZE(mt9m111_colour_fmts)) + if (index >= ARRAY_SIZE(mt9m111_colour_fmts)) return -EINVAL; *code = mt9m111_colour_fmts[index].code; diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c index 78b4e091d2d5..f26933a8fd8a 100644 --- a/drivers/media/video/mt9t031.c +++ b/drivers/media/video/mt9t031.c @@ -798,7 +798,7 @@ static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = { #endif }; -static int mt9t031_enum_fmt(struct v4l2_subdev *sd, int index, +static int mt9t031_enum_fmt(struct v4l2_subdev *sd, unsigned int index, enum v4l2_mbus_pixelcode *code) { if (index) diff --git a/drivers/media/video/mt9t112.c b/drivers/media/video/mt9t112.c index 7438f8d775ba..abe5505b9f79 100644 --- a/drivers/media/video/mt9t112.c +++ b/drivers/media/video/mt9t112.c @@ -1017,10 +1017,10 @@ static int mt9t112_try_fmt(struct v4l2_subdev *sd, return 0; } -static int mt9t112_enum_fmt(struct v4l2_subdev *sd, int index, +static int mt9t112_enum_fmt(struct v4l2_subdev *sd, unsigned int index, enum v4l2_mbus_pixelcode *code) { - if ((unsigned int)index >= ARRAY_SIZE(mt9t112_cfmts)) + if (index >= ARRAY_SIZE(mt9t112_cfmts)) return -EINVAL; *code = mt9t112_cfmts[index].code; diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index e5bae4c9393b..c409d05d465a 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c @@ -838,13 +838,13 @@ static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = { #endif }; -static int mt9v022_enum_fmt(struct v4l2_subdev *sd, int index, +static int mt9v022_enum_fmt(struct v4l2_subdev *sd, unsigned int index, enum v4l2_mbus_pixelcode *code) { struct i2c_client *client = sd->priv; struct mt9v022 *mt9v022 = to_mt9v022(client); - if ((unsigned int)index >= mt9v022->num_fmts) + if (index >= mt9v022->num_fmts) return -EINVAL; *code = mt9v022->fmts[index].code; diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index d477e3058002..a9be14c23912 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c @@ -672,7 +672,7 @@ static bool mx3_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt) fmt->packing == SOC_MBUS_PACKING_EXTEND16); } -static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx, +static int mx3_camera_get_formats(struct soc_camera_device *icd, unsigned int idx, struct soc_camera_format_xlate *xlate) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); @@ -689,7 +689,7 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx, fmt = soc_mbus_get_fmtdesc(code); if (!fmt) { dev_err(icd->dev.parent, - "Invalid format code #%d: %d\n", idx, code); + "Invalid format code #%u: %d\n", idx, code); return 0; } diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c index 7f8ece30c77b..86b0186c360c 100644 --- a/drivers/media/video/ov772x.c +++ b/drivers/media/video/ov772x.c @@ -1092,10 +1092,10 @@ static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = { #endif }; -static int ov772x_enum_fmt(struct v4l2_subdev *sd, int index, +static int ov772x_enum_fmt(struct v4l2_subdev *sd, unsigned int index, enum v4l2_mbus_pixelcode *code) { - if ((unsigned int)index >= ARRAY_SIZE(ov772x_cfmts)) + if (index >= ARRAY_SIZE(ov772x_cfmts)) return -EINVAL; *code = ov772x_cfmts[index].code; diff --git a/drivers/media/video/ov9640.c b/drivers/media/video/ov9640.c index 36599a65f548..58811c044c6a 100644 --- a/drivers/media/video/ov9640.c +++ b/drivers/media/video/ov9640.c @@ -614,10 +614,10 @@ static int ov9640_try_fmt(struct v4l2_subdev *sd, return 0; } -static int ov9640_enum_fmt(struct v4l2_subdev *sd, int index, +static int ov9640_enum_fmt(struct v4l2_subdev *sd, unsigned int index, enum v4l2_mbus_pixelcode *code) { - if ((unsigned int)index >= ARRAY_SIZE(ov9640_codes)) + if (index >= ARRAY_SIZE(ov9640_codes)) return -EINVAL; *code = ov9640_codes[index]; diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index 7fe70e718656..fb242f6cfb1f 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c @@ -1247,7 +1247,7 @@ static bool pxa_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt) fmt->packing == SOC_MBUS_PACKING_EXTEND16); } -static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, +static int pxa_camera_get_formats(struct soc_camera_device *icd, unsigned int idx, struct soc_camera_format_xlate *xlate) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); @@ -1264,7 +1264,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, fmt = soc_mbus_get_fmtdesc(code); if (!fmt) { - dev_err(dev, "Invalid format code #%d: %d\n", idx, code); + dev_err(dev, "Invalid format code #%u: %d\n", idx, code); return 0; } diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c index bbd9c11e2c5a..64eb05ce5603 100644 --- a/drivers/media/video/rj54n1cb0c.c +++ b/drivers/media/video/rj54n1cb0c.c @@ -481,10 +481,10 @@ static int reg_write_multiple(struct i2c_client *client, return 0; } -static int rj54n1_enum_fmt(struct v4l2_subdev *sd, int index, +static int rj54n1_enum_fmt(struct v4l2_subdev *sd, unsigned int index, enum v4l2_mbus_pixelcode *code) { - if ((unsigned int)index >= ARRAY_SIZE(rj54n1_colour_fmts)) + if (index >= ARRAY_SIZE(rj54n1_colour_fmts)) return -EINVAL; *code = rj54n1_colour_fmts[index].code; diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 4ac3b482fbb4..961bfa2fea97 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -878,7 +878,7 @@ static bool sh_mobile_ceu_packing_supported(const struct soc_mbus_pixelfmt *fmt) static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect); -static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, +static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int idx, struct soc_camera_format_xlate *xlate) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); @@ -897,7 +897,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, fmt = soc_mbus_get_fmtdesc(code); if (!fmt) { dev_err(icd->dev.parent, - "Invalid format code #%d: %d\n", idx, code); + "Invalid format code #%u: %d\n", idx, code); return -EINVAL; } diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index db1ca0e90d76..475757bfd7ba 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -200,7 +200,8 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); - int i, fmts = 0, raw_fmts = 0, ret; + unsigned int i, fmts = 0, raw_fmts = 0; + int ret; enum v4l2_mbus_pixelcode code; while (!v4l2_subdev_call(sd, video, enum_mbus_fmt, raw_fmts, &code)) diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c index 10b003a8be83..248c986f0989 100644 --- a/drivers/media/video/soc_camera_platform.c +++ b/drivers/media/video/soc_camera_platform.c @@ -71,7 +71,7 @@ static int soc_camera_platform_try_fmt(struct v4l2_subdev *sd, static struct v4l2_subdev_core_ops platform_subdev_core_ops; -static int soc_camera_platform_enum_fmt(struct v4l2_subdev *sd, int index, +static int soc_camera_platform_enum_fmt(struct v4l2_subdev *sd, unsigned int index, enum v4l2_mbus_pixelcode *code) { struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c index 76be733eabfd..2f3b1942e027 100644 --- a/drivers/media/video/tw9910.c +++ b/drivers/media/video/tw9910.c @@ -903,7 +903,7 @@ static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = { #endif }; -static int tw9910_enum_fmt(struct v4l2_subdev *sd, int index, +static int tw9910_enum_fmt(struct v4l2_subdev *sd, unsigned int index, enum v4l2_mbus_pixelcode *code) { if (index) diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index c9a5bbfa6ab5..b8289c2f609b 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -66,7 +66,7 @@ struct soc_camera_host_ops { * .get_formats() fail, .put_formats() will not be called at all, the * failing .get_formats() must then clean up internally. */ - int (*get_formats)(struct soc_camera_device *, int, + int (*get_formats)(struct soc_camera_device *, unsigned int, struct soc_camera_format_xlate *); void (*put_formats)(struct soc_camera_device *); int (*cropcap)(struct soc_camera_device *, struct v4l2_cropcap *); diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index a88889355ae0..02c6f4d11ed3 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -246,7 +246,7 @@ struct v4l2_subdev_video_ops { struct v4l2_dv_timings *timings); int (*g_dv_timings)(struct v4l2_subdev *sd, struct v4l2_dv_timings *timings); - int (*enum_mbus_fmt)(struct v4l2_subdev *sd, int index, + int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index, enum v4l2_mbus_pixelcode *code); int (*g_mbus_fmt)(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt); -- cgit v1.2.3 From 2db4e78f14a5b4741b09d03e6d17610537a9af27 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 9 May 2010 06:30:15 -0300 Subject: V4L/DVB: tvp514x: do NOT change the std as a side effect Several calls (try_fmt, g_parm among others) changed the current standard as a side effect of that call. But the standard may only be changed by s_std. Signed-off-by: Hans Verkuil Reviewed-by: Vaibhav Hiremath Tested-by: Vaibhav Hiremath Acked-by: Vaibhav Hiremath Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tvp514x.c | 53 +++++++++++++------------------------------ 1 file changed, 16 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c index e826114b7fb8..40d84d73edf8 100644 --- a/drivers/media/video/tvp514x.c +++ b/drivers/media/video/tvp514x.c @@ -366,13 +366,13 @@ static int tvp514x_write_regs(struct v4l2_subdev *sd, } /** - * tvp514x_get_current_std() : Get the current standard detected by TVP5146/47 + * tvp514x_query_current_std() : Query the current standard detected by TVP5146/47 * @sd: ptr to v4l2_subdev struct * - * Get current standard detected by TVP5146/47, STD_INVALID if there is no + * Returns the current standard detected by TVP5146/47, STD_INVALID if there is no * standard detected. */ -static enum tvp514x_std tvp514x_get_current_std(struct v4l2_subdev *sd) +static enum tvp514x_std tvp514x_query_current_std(struct v4l2_subdev *sd) { u8 std, std_status; @@ -518,7 +518,7 @@ static int tvp514x_detect(struct v4l2_subdev *sd, * @std_id: standard V4L2 std_id ioctl enum * * Returns the current standard detected by TVP5146/47. If no active input is - * detected, returns -EINVAL + * detected then *std_id is set to 0 and the function returns 0. */ static int tvp514x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id) { @@ -530,10 +530,12 @@ static int tvp514x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id) if (std_id == NULL) return -EINVAL; - /* get the current standard */ - current_std = tvp514x_get_current_std(sd); + *std_id = V4L2_STD_UNKNOWN; + + /* query the current standard */ + current_std = tvp514x_query_current_std(sd); if (current_std == STD_INVALID) - return -EINVAL; + return 0; input_sel = decoder->input; @@ -575,12 +577,11 @@ static int tvp514x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id) /* check whether signal is locked */ sync_lock_status = tvp514x_read_reg(sd, REG_STATUS1); if (lock_mask != (sync_lock_status & lock_mask)) - return -EINVAL; /* No input detected */ + return 0; /* No input detected */ - decoder->current_std = current_std; *std_id = decoder->std_list[current_std].standard.id; - v4l2_dbg(1, debug, sd, "Current STD: %s", + v4l2_dbg(1, debug, sd, "Current STD: %s\n", decoder->std_list[current_std].standard.name); return 0; } @@ -637,7 +638,6 @@ static int tvp514x_s_routing(struct v4l2_subdev *sd, int err; enum tvp514x_input input_sel; enum tvp514x_output output_sel; - enum tvp514x_std current_std = STD_INVALID; u8 sync_lock_status, lock_mask; int try_count = LOCK_RETRY_COUNT; @@ -721,11 +721,6 @@ static int tvp514x_s_routing(struct v4l2_subdev *sd, /* Allow decoder to sync up with new input */ msleep(LOCK_RETRY_DELAY); - /* get the current standard for future reference */ - current_std = tvp514x_get_current_std(sd); - if (current_std == STD_INVALID) - continue; - sync_lock_status = tvp514x_read_reg(sd, REG_STATUS1); if (lock_mask == (sync_lock_status & lock_mask)) @@ -733,15 +728,13 @@ static int tvp514x_s_routing(struct v4l2_subdev *sd, break; } - if ((current_std == STD_INVALID) || (try_count < 0)) + if (try_count < 0) return -EINVAL; - decoder->current_std = current_std; decoder->input = input; decoder->output = output; - v4l2_dbg(1, debug, sd, "Input set to: %d, std : %d", - input_sel, current_std); + v4l2_dbg(1, debug, sd, "Input set to: %d\n", input_sel); return 0; } @@ -1018,11 +1011,8 @@ tvp514x_try_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) pix = &f->fmt.pix; /* Calculate height and width based on current standard */ - current_std = tvp514x_get_current_std(sd); - if (current_std == STD_INVALID) - return -EINVAL; + current_std = decoder->current_std; - decoder->current_std = current_std; pix->width = decoder->std_list[current_std].width; pix->height = decoder->std_list[current_std].height; @@ -1132,15 +1122,8 @@ tvp514x_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a) /* only capture is supported */ return -EINVAL; - memset(a, 0, sizeof(*a)); - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - /* get the current standard */ - current_std = tvp514x_get_current_std(sd); - if (current_std == STD_INVALID) - return -EINVAL; - - decoder->current_std = current_std; + current_std = decoder->current_std; cparm = &a->parm.capture; cparm->capability = V4L2_CAP_TIMEPERFRAME; @@ -1175,11 +1158,7 @@ tvp514x_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a) timeperframe = &a->parm.capture.timeperframe; /* get the current standard */ - current_std = tvp514x_get_current_std(sd); - if (current_std == STD_INVALID) - return -EINVAL; - - decoder->current_std = current_std; + current_std = decoder->current_std; *timeperframe = decoder->std_list[current_std].standard.frameperiod; -- cgit v1.2.3 From a75ffc124611a535aec8f403817d382d106c68d7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 9 May 2010 06:32:47 -0300 Subject: V4L/DVB: tvp514x: make std_list const Signed-off-by: Hans Verkuil Reviewed-by: Vaibhav Hiremath Tested-by: Vaibhav Hiremath Acked-by: Vaibhav Hiremath Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tvp514x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c index 40d84d73edf8..b802da713114 100644 --- a/drivers/media/video/tvp514x.c +++ b/drivers/media/video/tvp514x.c @@ -111,7 +111,7 @@ struct tvp514x_decoder { enum tvp514x_std current_std; int num_stds; - struct tvp514x_std_info *std_list; + const struct tvp514x_std_info *std_list; /* Input and Output Routing parameters */ u32 input; u32 output; @@ -223,7 +223,7 @@ static const struct v4l2_fmtdesc tvp514x_fmt_list[] = { * Currently supports two standards only, need to add support for rest of the * modes, like SECAM, etc... */ -static struct tvp514x_std_info tvp514x_std_list[] = { +static const struct tvp514x_std_info tvp514x_std_list[] = { /* Standard: STD_NTSC_MJ */ [STD_NTSC_MJ] = { .width = NTSC_NUM_ACTIVE_PIXELS, -- cgit v1.2.3 From c2fc80961fc2059c05bf07c92decfffde2a0f9ef Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 9 May 2010 06:37:14 -0300 Subject: V4L/DVB: tvp514x: there is only one supported format, so simplify the code Get rid of unnecessary code since this driver supports only one pixel format. Removing this code will make the transition to the mbus API easier as well. Signed-off-by: Hans Verkuil Reviewed-by: Vaibhav Hiremath Tested-by: Vaibhav Hiremath Acked-by: Vaibhav Hiremath Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tvp514x.c | 45 +++++++++---------------------------------- 1 file changed, 9 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c index b802da713114..cb4284384133 100644 --- a/drivers/media/video/tvp514x.c +++ b/drivers/media/video/tvp514x.c @@ -89,8 +89,6 @@ static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable); * @ver: Chip version * @streaming: TVP5146/47 decoder streaming - enabled or disabled. * @pix: Current pixel format - * @num_fmts: Number of formats - * @fmt_list: Format list * @current_std: Current standard * @num_stds: Number of standards * @std_list: Standards list @@ -106,8 +104,6 @@ struct tvp514x_decoder { int streaming; struct v4l2_pix_format pix; - int num_fmts; - const struct v4l2_fmtdesc *fmt_list; enum tvp514x_std current_std; int num_stds; @@ -960,27 +956,18 @@ tvp514x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) static int tvp514x_enum_fmt_cap(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt) { - struct tvp514x_decoder *decoder = to_decoder(sd); - int index; - - if (fmt == NULL) - return -EINVAL; - - index = fmt->index; - if ((index >= decoder->num_fmts) || (index < 0)) - /* Index out of bound */ + if (fmt == NULL || fmt->index) return -EINVAL; if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) /* only capture is supported */ return -EINVAL; - memcpy(fmt, &decoder->fmt_list[index], - sizeof(struct v4l2_fmtdesc)); - - v4l2_dbg(1, debug, sd, "Current FMT: index - %d (%s)", - decoder->fmt_list[index].index, - decoder->fmt_list[index].description); + /* only one format */ + fmt->flags = 0; + strlcpy(fmt->description, "8-bit UYVY 4:2:2 Format", + sizeof(fmt->description)); + fmt->pixelformat = V4L2_PIX_FMT_UYVY; return 0; } @@ -997,7 +984,6 @@ static int tvp514x_try_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) { struct tvp514x_decoder *decoder = to_decoder(sd); - int ifmt; struct v4l2_pix_format *pix; enum tvp514x_std current_std; @@ -1013,28 +999,18 @@ tvp514x_try_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) /* Calculate height and width based on current standard */ current_std = decoder->current_std; + pix->pixelformat = V4L2_PIX_FMT_UYVY; pix->width = decoder->std_list[current_std].width; pix->height = decoder->std_list[current_std].height; - - for (ifmt = 0; ifmt < decoder->num_fmts; ifmt++) { - if (pix->pixelformat == - decoder->fmt_list[ifmt].pixelformat) - break; - } - if (ifmt == decoder->num_fmts) - /* None of the format matched, select default */ - ifmt = 0; - pix->pixelformat = decoder->fmt_list[ifmt].pixelformat; - pix->field = V4L2_FIELD_INTERLACED; pix->bytesperline = pix->width * 2; pix->sizeimage = pix->bytesperline * pix->height; pix->colorspace = V4L2_COLORSPACE_SMPTE170M; pix->priv = 0; - v4l2_dbg(1, debug, sd, "Try FMT: pixelformat - %s, bytesperline - %d" + v4l2_dbg(1, debug, sd, "Try FMT: bytesperline - %d" "Width - %d, Height - %d", - decoder->fmt_list[ifmt].description, pix->bytesperline, + pix->bytesperline, pix->width, pix->height); return 0; } @@ -1254,9 +1230,6 @@ static const struct v4l2_subdev_ops tvp514x_ops = { static struct tvp514x_decoder tvp514x_dev = { .streaming = 0, - .fmt_list = tvp514x_fmt_list, - .num_fmts = ARRAY_SIZE(tvp514x_fmt_list), - .pix = { /* Default to NTSC 8-bit YUV 422 */ .width = NTSC_NUM_ACTIVE_PIXELS, -- cgit v1.2.3 From 3907b07294a9a87793ca9e0223c7bf66b6108ab0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 9 May 2010 06:39:44 -0300 Subject: V4L/DVB: tvp514x: add missing newlines Signed-off-by: Hans Verkuil Reviewed-by: Vaibhav Hiremath Tested-by: Vaibhav Hiremath Acked-by: Vaibhav Hiremath Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tvp514x.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c index cb4284384133..1b03d0eb20df 100644 --- a/drivers/media/video/tvp514x.c +++ b/drivers/media/video/tvp514x.c @@ -611,7 +611,7 @@ static int tvp514x_s_std(struct v4l2_subdev *sd, v4l2_std_id std_id) decoder->tvp514x_regs[REG_VIDEO_STD].val = decoder->std_list[i].video_std; - v4l2_dbg(1, debug, sd, "Standard set to: %s", + v4l2_dbg(1, debug, sd, "Standard set to: %s\n", decoder->std_list[i].standard.name); return 0; } @@ -783,7 +783,7 @@ tvp514x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl) return err; } - v4l2_dbg(1, debug, sd, "Query Control:%s: Min - %d, Max - %d, Def - %d", + v4l2_dbg(1, debug, sd, "Query Control:%s: Min - %d, Max - %d, Def - %d\n", qctrl->name, qctrl->minimum, qctrl->maximum, qctrl->default_value); @@ -840,7 +840,7 @@ tvp514x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) return -EINVAL; } - v4l2_dbg(1, debug, sd, "Get Control: ID - %d - %d", + v4l2_dbg(1, debug, sd, "Get Control: ID - %d - %d\n", ctrl->id, ctrl->value); return 0; } @@ -940,7 +940,7 @@ tvp514x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) return err; } - v4l2_dbg(1, debug, sd, "Set Control: ID - %d - %d", + v4l2_dbg(1, debug, sd, "Set Control: ID - %d - %d\n", ctrl->id, ctrl->value); return err; @@ -1009,7 +1009,7 @@ tvp514x_try_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) pix->priv = 0; v4l2_dbg(1, debug, sd, "Try FMT: bytesperline - %d" - "Width - %d, Height - %d", + "Width - %d, Height - %d\n", pix->bytesperline, pix->width, pix->height); return 0; @@ -1071,7 +1071,7 @@ tvp514x_g_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) f->fmt.pix = decoder->pix; v4l2_dbg(1, debug, sd, "Current FMT: bytesperline - %d" - "Width - %d, Height - %d", + "Width - %d, Height - %d\n", decoder->pix.bytesperline, decoder->pix.width, decoder->pix.height); return 0; -- cgit v1.2.3 From f1a4435f3efa510760adf6acb87c62653de9a0ee Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 9 May 2010 06:40:18 -0300 Subject: V4L/DVB: tvp514x: remove obsolete fmt_list Signed-off-by: Hans Verkuil Reviewed-by: Vaibhav Hiremath Tested-by: Vaibhav Hiremath Acked-by: Vaibhav Hiremath Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tvp514x.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c index 1b03d0eb20df..bb5df5176377 100644 --- a/drivers/media/video/tvp514x.c +++ b/drivers/media/video/tvp514x.c @@ -198,21 +198,6 @@ static struct tvp514x_reg tvp514x_reg_list_default[] = { {TOK_TERM, 0, 0}, }; -/** - * List of image formats supported by TVP5146/47 decoder - * Currently we are using 8 bit mode only, but can be - * extended to 10/20 bit mode. - */ -static const struct v4l2_fmtdesc tvp514x_fmt_list[] = { - { - .index = 0, - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - .flags = 0, - .description = "8-bit UYVY 4:2:2 Format", - .pixelformat = V4L2_PIX_FMT_UYVY, - }, -}; - /** * Supported standards - * -- cgit v1.2.3 From 283d637bbd7301c9fb2236103b990b9d66099d78 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 9 May 2010 06:44:16 -0300 Subject: V4L/DVB: tvp514x: simplify try/g/s_fmt handling Since there is only one possible format just have all three calls do the same. Signed-off-by: Hans Verkuil Reviewed-by: Vaibhav Hiremath Tested-by: Vaibhav Hiremath Acked-by: Vaibhav Hiremath Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tvp514x.c | 98 ++++--------------------------------------- 1 file changed, 9 insertions(+), 89 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c index bb5df5176377..71c73fa0d68c 100644 --- a/drivers/media/video/tvp514x.c +++ b/drivers/media/video/tvp514x.c @@ -88,7 +88,6 @@ static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable); * @pdata: Board specific * @ver: Chip version * @streaming: TVP5146/47 decoder streaming - enabled or disabled. - * @pix: Current pixel format * @current_std: Current standard * @num_stds: Number of standards * @std_list: Standards list @@ -103,8 +102,6 @@ struct tvp514x_decoder { int ver; int streaming; - struct v4l2_pix_format pix; - enum tvp514x_std current_std; int num_stds; const struct tvp514x_std_info *std_list; @@ -957,16 +954,15 @@ tvp514x_enum_fmt_cap(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt) } /** - * tvp514x_try_fmt_cap() - V4L2 decoder interface handler for try_fmt + * tvp514x_fmt_cap() - V4L2 decoder interface handler for try/s/g_fmt * @sd: pointer to standard V4L2 sub-device structure * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure * - * Implement the VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type. This - * ioctl is used to negotiate the image capture size and pixel format - * without actually making it take effect. + * Implement the VIDIOC_TRY/S/G_FMT ioctl for the CAPTURE buffer type. This + * ioctl is used to negotiate the image capture size and pixel format. */ static int -tvp514x_try_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) +tvp514x_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) { struct tvp514x_decoder *decoder = to_decoder(sd); struct v4l2_pix_format *pix; @@ -976,8 +972,7 @@ tvp514x_try_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) return -EINVAL; if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - /* only capture is supported */ - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + return -EINVAL; pix = &f->fmt.pix; @@ -993,75 +988,13 @@ tvp514x_try_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) pix->colorspace = V4L2_COLORSPACE_SMPTE170M; pix->priv = 0; - v4l2_dbg(1, debug, sd, "Try FMT: bytesperline - %d" + v4l2_dbg(1, debug, sd, "FMT: bytesperline - %d" "Width - %d, Height - %d\n", pix->bytesperline, pix->width, pix->height); return 0; } -/** - * tvp514x_s_fmt_cap() - V4L2 decoder interface handler for s_fmt - * @sd: pointer to standard V4L2 sub-device structure - * @f: pointer to standard V4L2 VIDIOC_S_FMT ioctl structure - * - * If the requested format is supported, configures the HW to use that - * format, returns error code if format not supported or HW can't be - * correctly configured. - */ -static int -tvp514x_s_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) -{ - struct tvp514x_decoder *decoder = to_decoder(sd); - struct v4l2_pix_format *pix; - int rval; - - if (f == NULL) - return -EINVAL; - - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - /* only capture is supported */ - return -EINVAL; - - pix = &f->fmt.pix; - rval = tvp514x_try_fmt_cap(sd, f); - if (rval) - return rval; - - decoder->pix = *pix; - - return rval; -} - -/** - * tvp514x_g_fmt_cap() - V4L2 decoder interface handler for tvp514x_g_fmt_cap - * @sd: pointer to standard V4L2 sub-device structure - * @f: pointer to standard V4L2 v4l2_format structure - * - * Returns the decoder's current pixel format in the v4l2_format - * parameter. - */ -static int -tvp514x_g_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f) -{ - struct tvp514x_decoder *decoder = to_decoder(sd); - - if (f == NULL) - return -EINVAL; - - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - /* only capture is supported */ - return -EINVAL; - - f->fmt.pix = decoder->pix; - - v4l2_dbg(1, debug, sd, "Current FMT: bytesperline - %d" - "Width - %d, Height - %d\n", - decoder->pix.bytesperline, - decoder->pix.width, decoder->pix.height); - return 0; -} - /** * tvp514x_g_parm() - V4L2 decoder interface handler for g_parm * @sd: pointer to standard V4L2 sub-device structure @@ -1199,9 +1132,9 @@ static const struct v4l2_subdev_video_ops tvp514x_video_ops = { .s_routing = tvp514x_s_routing, .querystd = tvp514x_querystd, .enum_fmt = tvp514x_enum_fmt_cap, - .g_fmt = tvp514x_g_fmt_cap, - .try_fmt = tvp514x_try_fmt_cap, - .s_fmt = tvp514x_s_fmt_cap, + .g_fmt = tvp514x_fmt_cap, + .try_fmt = tvp514x_fmt_cap, + .s_fmt = tvp514x_fmt_cap, .g_parm = tvp514x_g_parm, .s_parm = tvp514x_s_parm, .s_stream = tvp514x_s_stream, @@ -1214,19 +1147,6 @@ static const struct v4l2_subdev_ops tvp514x_ops = { static struct tvp514x_decoder tvp514x_dev = { .streaming = 0, - - .pix = { - /* Default to NTSC 8-bit YUV 422 */ - .width = NTSC_NUM_ACTIVE_PIXELS, - .height = NTSC_NUM_ACTIVE_LINES, - .pixelformat = V4L2_PIX_FMT_UYVY, - .field = V4L2_FIELD_INTERLACED, - .bytesperline = NTSC_NUM_ACTIVE_PIXELS * 2, - .sizeimage = - NTSC_NUM_ACTIVE_PIXELS * 2 * NTSC_NUM_ACTIVE_LINES, - .colorspace = V4L2_COLORSPACE_SMPTE170M, - }, - .current_std = STD_NTSC_MJ, .std_list = tvp514x_std_list, .num_stds = ARRAY_SIZE(tvp514x_std_list), -- cgit v1.2.3 From 76952c7e598f68bf12adf307d6a9a0de3b33b985 Mon Sep 17 00:00:00 2001 From: Guy Martin Date: Fri, 7 May 2010 04:09:25 -0300 Subject: V4L/DVB: TT CT-3650 DVB-C support Add support for the DVB-C frontend of the TT CT-3650. DVB-T fe, CI and IR are not implemented. Signed-off-by: Guy Martin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + drivers/media/dvb/dvb-usb/ttusb2.c | 95 ++++++++++++++++++++++++++++++--- 2 files changed, 90 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 085c4e457e0e..b4afe6f8ed19 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -198,6 +198,7 @@ #define USB_PID_AVERMEDIA_A850 0x850a #define USB_PID_AVERMEDIA_A805 0xa805 #define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 +#define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081 #define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058 diff --git a/drivers/media/dvb/dvb-usb/ttusb2.c b/drivers/media/dvb/dvb-usb/ttusb2.c index 20ca9d9ee99b..a6de489a6a39 100644 --- a/drivers/media/dvb/dvb-usb/ttusb2.c +++ b/drivers/media/dvb/dvb-usb/ttusb2.c @@ -29,6 +29,8 @@ #include "tda826x.h" #include "tda10086.h" +#include "tda1002x.h" +#include "tda827x.h" #include "lnbp21.h" /* debug */ @@ -150,7 +152,17 @@ static struct tda10086_config tda10086_config = { .xtal_freq = TDA10086_XTAL_16M, }; -static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap) +static struct tda10023_config tda10023_config = { + .demod_address = 0x0c, + .invert = 0, + .xtal = 16000000, + .pll_m = 11, + .pll_p = 3, + .pll_n = 1, + .deltaf = 0xa511, +}; + +static int ttusb2_frontend_tda10086_attach(struct dvb_usb_adapter *adap) { if (usb_set_interface(adap->dev->udev,0,3) < 0) err("set interface to alts=3 failed"); @@ -163,7 +175,27 @@ static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap) return 0; } -static int ttusb2_tuner_attach(struct dvb_usb_adapter *adap) +static int ttusb2_frontend_tda10023_attach(struct dvb_usb_adapter *adap) +{ + if (usb_set_interface(adap->dev->udev, 0, 3) < 0) + err("set interface to alts=3 failed"); + if ((adap->fe = dvb_attach(tda10023_attach, &tda10023_config, &adap->dev->i2c_adap, 0x48)) == NULL) { + deb_info("TDA10023 attach failed\n"); + return -ENODEV; + } + return 0; +} + +static int ttusb2_tuner_tda827x_attach(struct dvb_usb_adapter *adap) +{ + if (dvb_attach(tda827x_attach, adap->fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL) { + printk(KERN_ERR "%s: No tda827x found!\n", __func__); + return -ENODEV; + } + return 0; +} + +static int ttusb2_tuner_tda826x_attach(struct dvb_usb_adapter *adap) { if (dvb_attach(tda826x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, 0) == NULL) { deb_info("TDA8263 attach failed\n"); @@ -180,6 +212,7 @@ static int ttusb2_tuner_attach(struct dvb_usb_adapter *adap) /* DVB USB Driver stuff */ static struct dvb_usb_device_properties ttusb2_properties; static struct dvb_usb_device_properties ttusb2_properties_s2400; +static struct dvb_usb_device_properties ttusb2_properties_ct3650; static int ttusb2_probe(struct usb_interface *intf, const struct usb_device_id *id) @@ -187,6 +220,8 @@ static int ttusb2_probe(struct usb_interface *intf, if (0 == dvb_usb_device_init(intf, &ttusb2_properties, THIS_MODULE, NULL, adapter_nr) || 0 == dvb_usb_device_init(intf, &ttusb2_properties_s2400, + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &ttusb2_properties_ct3650, THIS_MODULE, NULL, adapter_nr)) return 0; return -ENODEV; @@ -197,6 +232,8 @@ static struct usb_device_id ttusb2_table [] = { { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) }, { USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_CONNECT_S2400) }, + { USB_DEVICE(USB_VID_TECHNOTREND, + USB_PID_TECHNOTREND_CONNECT_CT3650) }, {} /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, ttusb2_table); @@ -214,8 +251,8 @@ static struct dvb_usb_device_properties ttusb2_properties = { { .streaming_ctrl = NULL, // ttusb2_streaming_ctrl, - .frontend_attach = ttusb2_frontend_attach, - .tuner_attach = ttusb2_tuner_attach, + .frontend_attach = ttusb2_frontend_tda10086_attach, + .tuner_attach = ttusb2_tuner_tda826x_attach, /* parameter for the MPEG2-data transfer */ .stream = { @@ -266,8 +303,8 @@ static struct dvb_usb_device_properties ttusb2_properties_s2400 = { { .streaming_ctrl = NULL, - .frontend_attach = ttusb2_frontend_attach, - .tuner_attach = ttusb2_tuner_attach, + .frontend_attach = ttusb2_frontend_tda10086_attach, + .tuner_attach = ttusb2_tuner_tda826x_attach, /* parameter for the MPEG2-data transfer */ .stream = { @@ -301,6 +338,52 @@ static struct dvb_usb_device_properties ttusb2_properties_s2400 = { } }; +static struct dvb_usb_device_properties ttusb2_properties_ct3650 = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .usb_ctrl = CYPRESS_FX2, + + .size_of_priv = sizeof(struct ttusb2_state), + + .num_adapters = 1, + .adapter = { + { + .streaming_ctrl = NULL, + + .frontend_attach = ttusb2_frontend_tda10023_attach, + .tuner_attach = ttusb2_tuner_tda827x_attach, + + /* parameter for the MPEG2-data transfer */ + .stream = { + .type = USB_ISOC, + .count = 5, + .endpoint = 0x02, + .u = { + .isoc = { + .framesperurb = 4, + .framesize = 940, + .interval = 1, + } + } + } + }, + }, + + .power_ctrl = ttusb2_power_ctrl, + .identify_state = ttusb2_identify_state, + + .i2c_algo = &ttusb2_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + + .num_device_descs = 1, + .devices = { + { "Technotrend TT-connect CT-3650", + .warm_ids = { &ttusb2_table[3], NULL }, + }, + } +}; + static struct usb_driver ttusb2_driver = { .name = "dvb_usb_ttusb2", .probe = ttusb2_probe, -- cgit v1.2.3 From e65f8c4e3eef3a0946f8e8fba1fb6aabde734f50 Mon Sep 17 00:00:00 2001 From: Guy Martin Date: Fri, 7 May 2010 04:34:40 -0300 Subject: V4L/DVB: stv6110x: Fix kernel null pointer deref The following OOPS happened when plugging two TT s2-1600: [ 96.521023] saa7146: register extension 'budget dvb'. [ 96.521052] budget dvb 0000:05:00.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16 [ 96.521070] IRQ 16/: IRQF_DISABLED is not guaranteed on shared IRQs [ 96.521076] saa7146: found saa7146 @ mem ffffc90011182c00 (revision 1, irq 16) (0x13c2,0x101c). [ 96.521080] saa7146 (0): dma buffer size 192512 [ 96.521081] DVB: registering new adapter (TT-Budget S2-1600 PCI) [ 96.539929] adapter has MAC addr = 00:d0:5c:cc:b0:a2 [ 96.890149] stv6110x_attach: Attaching STV6110x [ 96.912516] DVB: registering adapter 0 frontend 0 (STV090x Multistandard)... [ 96.912600] budget dvb 0000:05:01.0: PCI INT A -> GSI 17 (level, low) -> IRQ 17 [ 96.912639] IRQ 17/: IRQF_DISABLED is not guaranteed on shared IRQs [ 96.912667] saa7146: found saa7146 @ mem ffffc90011314800 (revision 1, irq 17) (0x13c2,0x101c). [ 96.912673] saa7146 (1): dma buffer size 192512 [ 96.912676] DVB: registering new adapter (TT-Budget S2-1600 PCI) [ 96.930893] adapter has MAC addr = 00:d0:5c:cc:b0:a3 [ 97.233478] BUG: unable to handle kernel NULL pointer dereference at 0000000000000010 [ 97.233647] IP: [] stv6110x_set_mode+0x70/0x80 [stv6110x] [ 97.233753] PGD 3c16f067 PUD 3c383067 PMD 0 [ 97.234147] CPU 0 [ 97.234246] Pid: 5200, comm: modprobe Not tainted 2.6.33.2 #1 P5QSE/P5Q SE [ 97.234317] RIP: 0010:[] [] stv6110x_set_mode+0x70/0x80 [stv6110x] [ 97.234456] RSP: 0018:ffff88003c125c98 EFLAGS: 00010246 [ 97.234461] RAX: ffffffffa029c460 RBX: ffff88003f84d800 RCX: ffff88003a19e140 [ 97.234461] RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000 [ 97.234461] RBP: ffff88003f84d828 R08: 0000000000000002 R09: 0000000000000004 [ 97.234461] R10: 0000000000000003 R11: 0000000000000010 R12: ffff88003f84d800 [ 97.234461] R13: ffff88003f84d828 R14: ffff88003f84d828 R15: 0000000000000001 [ 97.234461] FS: 00007f9f7253e6f0(0000) GS:ffff880001800000(0000) knlGS:0000000000000000 [ 97.234461] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 97.234461] CR2: 0000000000000010 CR3: 000000003c382000 CR4: 00000000000006b0 [ 97.234461] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 97.234461] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 97.234461] Process modprobe (pid: 5200, threadinfo ffff88003c124000, task ffff88003e893ac0) [ 97.234461] ffff88003f84d800 ffff88003f84d828 ffff88003f84d800 ffffffffa0292343 [ 97.234461] <0> ffff88003f84d828 ffff88003ef70ae0 ffffffffa0280800 ffffffffa02934d2 [ 97.234461] <0> ffffffffa0295260 0000000000000000 ffffffffa02948b0 ffff88003df79800 [ 97.234461] [] ? stv090x_sleep+0x33/0x120 [stv090x] [ 97.234461] [] ? stv090x_attach+0x1e2/0x73c [stv090x] [ 97.234461] [] ? dma_generic_alloc_coherent+0xa5/0x160 [ 97.234461] [] ? saa7146_init_one+0x7d5/0x910 [saa7146] [ 97.234461] [] ? local_pci_probe+0x12/0x20 [ 97.234461] [] ? pci_device_probe+0x110/0x120 [ 97.234461] [] ? driver_probe_device+0x98/0x1b0 [ 97.234461] [] ? __driver_attach+0x93/0xa0 [ 97.234461] [] ? __driver_attach+0x0/0xa0 [ 97.234461] [] ? bus_for_each_dev+0x58/0x80 [ 97.234461] [] ? bus_add_driver+0x14d/0x280 [ 97.234461] [] ? budget_init+0x0/0xc [budget] [ 97.234461] [] ? driver_register+0x79/0x170 [ 97.234461] [] ? budget_init+0x0/0xc [budget] [ 97.234461] [] ? __pci_register_driver+0x58/0xe0 [ 97.234461] [] ? budget_init+0x0/0xc [budget] [ 97.234461] [] ? do_one_initcall+0x35/0x190 [ 97.234461] [] ? sys_init_module+0xe7/0x260 [ 97.234461] [] ? system_call_fastpath+0x16/0x1b [ 97.234461] RIP [] stv6110x_set_mode+0x70/0x80 [stv6110x] [ 97.234461] RSP [ 97.240074] ---[ end trace b53ecbbbbef15e99 ]--- Prevents calling stv6110x_set_mode() if fe->tuner_priv is not defined, in order to avoid the above bug. Signed-off-by: Guy Martin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv6110x.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/frontends/stv6110x.c b/drivers/media/dvb/frontends/stv6110x.c index 42591ce1aaad..f36cab12bdc7 100644 --- a/drivers/media/dvb/frontends/stv6110x.c +++ b/drivers/media/dvb/frontends/stv6110x.c @@ -303,7 +303,10 @@ static int stv6110x_set_mode(struct dvb_frontend *fe, enum tuner_mode mode) static int stv6110x_sleep(struct dvb_frontend *fe) { - return stv6110x_set_mode(fe, TUNER_SLEEP); + if (fe->tuner_priv) + return stv6110x_set_mode(fe, TUNER_SLEEP); + + return 0; } static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status) -- cgit v1.2.3 From 9e1d9e7bac5c2bafc3c0c51db88c15f3fbcec83f Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Sat, 8 May 2010 02:23:37 -0300 Subject: V4L/DVB: saa7134: add support for Avermedia M733A This change adds support for Avermedia M733A. The original version for linux 2.6.31 was sent to me from Avermedia, original author is unknown. I ported it to current kernels, expanded and fixed key code handling for RM-K6 remote control, and added an additional pci id also supported. [mchehab@redhat.com: make checkpatch.pl happier] Signed-off-by: Herton Ronaldo Krzesinski Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.saa7134 | 5 +- drivers/media/IR/keymaps/Makefile | 1 + .../media/IR/keymaps/rc-avermedia-m733a-rm-k6.c | 95 ++++++++++++++++++++++ drivers/media/video/saa7134/saa7134-cards.c | 55 +++++++++++++ drivers/media/video/saa7134/saa7134-input.c | 7 ++ drivers/media/video/saa7134/saa7134.h | 1 + include/media/rc-map.h | 1 + 7 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 drivers/media/IR/keymaps/rc-avermedia-m733a-rm-k6.c (limited to 'drivers') diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index 070f2576707e..1387a69ae3aa 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 @@ -176,5 +176,6 @@ 175 -> Leadtek Winfast DTV1000S [107d:6655] 176 -> Beholder BeholdTV 505 RDS [0000:5051] 177 -> Hawell HW-404M7 -179 -> Beholder BeholdTV H7 [5ace:7190] -180 -> Beholder BeholdTV A7 [5ace:7090] +178 -> Beholder BeholdTV H7 [5ace:7190] +179 -> Beholder BeholdTV A7 [5ace:7090] +180 -> Avermedia M733A [1461:4155,1461:4255] diff --git a/drivers/media/IR/keymaps/Makefile b/drivers/media/IR/keymaps/Makefile index ec25258a955f..585f75c3f376 100644 --- a/drivers/media/IR/keymaps/Makefile +++ b/drivers/media/IR/keymaps/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ rc-avermedia-cardbus.o \ rc-avermedia-dvbt.o \ rc-avermedia-m135a-rm-jx.o \ + rc-avermedia-m733a-rm-k6.o \ rc-avertv-303.o \ rc-behold.o \ rc-behold-columbus.o \ diff --git a/drivers/media/IR/keymaps/rc-avermedia-m733a-rm-k6.c b/drivers/media/IR/keymaps/rc-avermedia-m733a-rm-k6.c new file mode 100644 index 000000000000..cf8d45717cb3 --- /dev/null +++ b/drivers/media/IR/keymaps/rc-avermedia-m733a-rm-k6.c @@ -0,0 +1,95 @@ +/* avermedia-m733a-rm-k6.h - Keytable for avermedia_m733a_rm_k6 Remote Controller + * + * Copyright (c) 2010 by Herton Ronaldo Krzesinski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include + +/* + * Avermedia M733A with IR model RM-K6 + * This is the stock remote controller used with Positivo machines with M733A + * Herton Ronaldo Krzesinski + */ + +static struct ir_scancode avermedia_m733a_rm_k6[] = { + { 0x0401, KEY_POWER2 }, + { 0x0406, KEY_MUTE }, + { 0x0408, KEY_MODE }, /* TV/FM */ + + { 0x0409, KEY_1 }, + { 0x040a, KEY_2 }, + { 0x040b, KEY_3 }, + { 0x040c, KEY_4 }, + { 0x040d, KEY_5 }, + { 0x040e, KEY_6 }, + { 0x040f, KEY_7 }, + { 0x0410, KEY_8 }, + { 0x0411, KEY_9 }, + { 0x044c, KEY_DOT }, /* '.' */ + { 0x0412, KEY_0 }, + { 0x0407, KEY_REFRESH }, /* Refresh/Reload */ + + { 0x0413, KEY_AUDIO }, + { 0x0440, KEY_SCREEN }, /* Full Screen toggle */ + { 0x0441, KEY_HOME }, + { 0x0442, KEY_BACK }, + { 0x0447, KEY_UP }, + { 0x0448, KEY_DOWN }, + { 0x0449, KEY_LEFT }, + { 0x044a, KEY_RIGHT }, + { 0x044b, KEY_OK }, + { 0x0404, KEY_VOLUMEUP }, + { 0x0405, KEY_VOLUMEDOWN }, + { 0x0402, KEY_CHANNELUP }, + { 0x0403, KEY_CHANNELDOWN }, + + { 0x0443, KEY_RED }, + { 0x0444, KEY_GREEN }, + { 0x0445, KEY_YELLOW }, + { 0x0446, KEY_BLUE }, + + { 0x0414, KEY_TEXT }, + { 0x0415, KEY_EPG }, + { 0x041a, KEY_TV2 }, /* PIP */ + { 0x041b, KEY_MHP }, /* Snapshot */ + + { 0x0417, KEY_RECORD }, + { 0x0416, KEY_PLAYPAUSE }, + { 0x0418, KEY_STOP }, + { 0x0419, KEY_PAUSE }, + + { 0x041f, KEY_PREVIOUS }, + { 0x041c, KEY_REWIND }, + { 0x041d, KEY_FORWARD }, + { 0x041e, KEY_NEXT }, +}; + +static struct rc_keymap avermedia_m733a_rm_k6_map = { + .map = { + .scan = avermedia_m733a_rm_k6, + .size = ARRAY_SIZE(avermedia_m733a_rm_k6), + .ir_type = IR_TYPE_NEC, + .name = RC_MAP_AVERMEDIA_M733A_RM_K6, + } +}; + +static int __init init_rc_map_avermedia_m733a_rm_k6(void) +{ + return ir_register_map(&avermedia_m733a_rm_k6_map); +} + +static void __exit exit_rc_map_avermedia_m733a_rm_k6(void) +{ + ir_unregister_map(&avermedia_m733a_rm_k6_map); +} + +module_init(init_rc_map_avermedia_m733a_rm_k6) +module_exit(exit_rc_map_avermedia_m733a_rm_k6) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 72700d4e3941..07f6bb8ef9d9 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -3897,6 +3897,40 @@ struct saa7134_board saa7134_boards[] = { .gpio = 0x01, }, }, + [SAA7134_BOARD_AVERMEDIA_M733A] = { + .name = "Avermedia PCI M733A", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_TDA8290, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tuner_config = 0, + .gpiomask = 0x020200000, + .inputs = {{ + .name = name_tv, + .vmux = 1, + .amux = TV, + .tv = 1, + }, { + .name = name_comp1, + .vmux = 3, + .amux = LINE1, + }, { + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + } }, + .radio = { + .name = name_radio, + .amux = TV, + .gpio = 0x00200000, + }, + .mute = { + .name = name_mute, + .amux = TV, + .gpio = 0x01, + }, + }, [SAA7134_BOARD_BEHOLD_401] = { /* Beholder Intl. Ltd. 2008 */ /*Dmitry Belimov */ @@ -5820,6 +5854,18 @@ struct pci_device_id saa7134_pci_tbl[] = { .subvendor = 0x1461, /* Avermedia Technologies Inc */ .subdevice = 0xf11d, .driver_data = SAA7134_BOARD_AVERMEDIA_M135A, + }, { + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x1461, /* Avermedia Technologies Inc */ + .subdevice = 0x4155, + .driver_data = SAA7134_BOARD_AVERMEDIA_M733A, + }, { + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x1461, /* Avermedia Technologies Inc */ + .subdevice = 0x4255, + .driver_data = SAA7134_BOARD_AVERMEDIA_M733A, }, { .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7130, @@ -6786,6 +6832,7 @@ static int saa7134_tda8290_callback(struct saa7134_dev *dev, switch (dev->board) { case SAA7134_BOARD_HAUPPAUGE_HVR1150: case SAA7134_BOARD_HAUPPAUGE_HVR1120: + case SAA7134_BOARD_AVERMEDIA_M733A: /* tda8290 + tda18271 */ ret = saa7134_tda8290_18271_callback(dev, command, arg); break; @@ -7087,6 +7134,14 @@ int saa7134_board_init1(struct saa7134_dev *dev) saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x0000C000, 0x0000C000); saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0000C000, 0x0000C000); break; + case SAA7134_BOARD_AVERMEDIA_M733A: + saa7134_set_gpio(dev, 1, 1); + msleep(10); + saa7134_set_gpio(dev, 1, 0); + msleep(10); + saa7134_set_gpio(dev, 1, 1); + dev->has_remote = SAA7134_REMOTE_GPIO; + break; } return 0; } diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index e5565e2fd426..f9ed8048894d 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -663,6 +663,13 @@ int saa7134_input_init1(struct saa7134_dev *dev) mask_keycode = 0xffff; raw_decode = 1; break; + case SAA7134_BOARD_AVERMEDIA_M733A: + ir_codes = RC_MAP_AVERMEDIA_M733A_RM_K6; + mask_keydown = 0x0040000; + mask_keyup = 0x0040000; + mask_keycode = 0xffff; + raw_decode = 1; + break; case SAA7134_BOARD_AVERMEDIA_777: case SAA7134_BOARD_AVERMEDIA_A16AR: ir_codes = RC_MAP_AVERMEDIA; diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 3962534267be..756a1ca8833d 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -303,6 +303,7 @@ struct saa7134_format { #define SAA7134_BOARD_HAWELL_HW_404M7 177 #define SAA7134_BOARD_BEHOLD_H7 178 #define SAA7134_BOARD_BEHOLD_A7 179 +#define SAA7134_BOARD_AVERMEDIA_M733A 180 #define SAA7134_MAXBOARDS 32 #define SAA7134_INPUT_MAX 8 diff --git a/include/media/rc-map.h b/include/media/rc-map.h index 5833966a7100..6f1f9f76674e 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -56,6 +56,7 @@ void rc_map_init(void); #define RC_MAP_AVERMEDIA_CARDBUS "rc-avermedia-cardbus" #define RC_MAP_AVERMEDIA_DVBT "rc-avermedia-dvbt" #define RC_MAP_AVERMEDIA_M135A_RM_JX "rc-avermedia-m135a-rm-jx" +#define RC_MAP_AVERMEDIA_M733A_RM_K6 "rc-avermedia-m733a-rm-k6" #define RC_MAP_AVERMEDIA "rc-avermedia" #define RC_MAP_AVERTV_303 "rc-avertv-303" #define RC_MAP_BEHOLD_COLUMBUS "rc-behold-columbus" -- cgit v1.2.3 From 0439db75c1fbb28a3b314ae354582e4f180daf52 Mon Sep 17 00:00:00 2001 From: Stefan Ringel Date: Mon, 10 May 2010 13:22:51 -0300 Subject: V4L/DVB: tm6000: add extension module support add module init over tm6000 extension Signed-off-by: Stefan Ringel Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/tm6000/tm6000-alsa.c | 25 +++++++++- drivers/staging/tm6000/tm6000-cards.c | 7 +++ drivers/staging/tm6000/tm6000-core.c | 92 +++++++++++++++++++++++++++++++++++ drivers/staging/tm6000/tm6000.h | 23 ++++++++- 4 files changed, 145 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tm6000/tm6000-alsa.c b/drivers/staging/tm6000/tm6000-alsa.c index bc89f9d28002..ce081cd44ad4 100644 --- a/drivers/staging/tm6000/tm6000-alsa.c +++ b/drivers/staging/tm6000/tm6000-alsa.c @@ -410,5 +410,28 @@ error: snd_card_free(card); return rc; } -EXPORT_SYMBOL_GPL(tm6000_audio_init); +static int tm6000_audio_fini(struct tm6000_core *dev) +{ + return 0; +} + +struct tm6000_ops audio_ops = { + .id = TM6000_AUDIO, + .name = "TM6000 Audio Extension", + .init = tm6000_audio_init, + .fini = tm6000_audio_fini, +}; + +static int __init tm6000_alsa_register(void) +{ + return tm6000_register_extension(&audio_ops); +} + +static void __exit tm6000_alsa_unregister(void) +{ + tm6000_unregister_extension(&audio_ops); +} + +module_init(tm6000_alsa_register); +module_exit(tm6000_alsa_unregister); diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c index 6143e20d139d..ab12291e0b42 100644 --- a/drivers/staging/tm6000/tm6000-cards.c +++ b/drivers/staging/tm6000/tm6000-cards.c @@ -692,6 +692,10 @@ static int tm6000_init_dev(struct tm6000_core *dev) if (rc < 0) goto err; + tm6000_add_into_devlist(dev); + + tm6000_init_extension(dev); + if (dev->caps.has_dvb) { dev->dvb = kzalloc(sizeof(*(dev->dvb)), GFP_KERNEL); if (!dev->dvb) { @@ -931,6 +935,9 @@ static void tm6000_usb_disconnect(struct usb_interface *interface) usb_put_dev(dev->udev); + tm6000_remove_from_devlist(dev); + tm6000_close_extension(dev); + mutex_unlock(&dev->lock); kfree(dev); } diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c index bfbc53bd2912..1259ae550547 100644 --- a/drivers/staging/tm6000/tm6000-core.c +++ b/drivers/staging/tm6000/tm6000-core.c @@ -600,3 +600,95 @@ printk("Original value=%d\n",val); return val; } EXPORT_SYMBOL_GPL(tm6000_set_audio_bitrate); + +static LIST_HEAD(tm6000_devlist); +static DEFINE_MUTEX(tm6000_devlist_mutex); + +/* + * tm6000_realease_resource() + */ + +void tm6000_remove_from_devlist(struct tm6000_core *dev) +{ + mutex_lock(&tm6000_devlist_mutex); + list_del(&dev->devlist); + mutex_unlock(&tm6000_devlist_mutex); +}; + +void tm6000_add_into_devlist(struct tm6000_core *dev) +{ + mutex_lock(&tm6000_devlist_mutex); + list_add_tail(&dev->devlist, &tm6000_devlist); + mutex_unlock(&tm6000_devlist_mutex); +}; + +/* + * Extension interface + */ + +static LIST_HEAD(tm6000_extension_devlist); +static DEFINE_MUTEX(tm6000_extension_devlist_lock); + +int tm6000_register_extension(struct tm6000_ops *ops) +{ + struct tm6000_core *dev = NULL; + + mutex_lock(&tm6000_devlist_mutex); + mutex_lock(&tm6000_extension_devlist_lock); + list_add_tail(&ops->next, &tm6000_extension_devlist); + list_for_each_entry(dev, &tm6000_devlist, devlist) { + if (dev) + ops->init(dev); + } + printk(KERN_INFO "tm6000: Initialized (%s) extension\n", ops->name); + mutex_unlock(&tm6000_extension_devlist_lock); + mutex_unlock(&tm6000_devlist_mutex); + return 0; +} +EXPORT_SYMBOL(tm6000_register_extension); + +void tm6000_unregister_extension(struct tm6000_ops *ops) +{ + struct tm6000_core *dev = NULL; + + mutex_lock(&tm6000_devlist_mutex); + list_for_each_entry(dev, &tm6000_devlist, devlist) { + if (dev) + ops->fini(dev); + } + + mutex_lock(&tm6000_extension_devlist_lock); + printk(KERN_INFO "tm6000: Remove (%s) extension\n", ops->name); + list_del(&ops->next); + mutex_unlock(&tm6000_extension_devlist_lock); + mutex_unlock(&tm6000_devlist_mutex); +} +EXPORT_SYMBOL(tm6000_unregister_extension); + +void tm6000_init_extension(struct tm6000_core *dev) +{ + struct tm6000_ops *ops = NULL; + + mutex_lock(&tm6000_extension_devlist_lock); + if (!list_empty(&tm6000_extension_devlist)) { + list_for_each_entry(ops, &tm6000_extension_devlist, next) { + if (ops->init) + ops->init(dev); + } + } + mutex_unlock(&tm6000_extension_devlist_lock); +} + +void tm6000_close_extension(struct tm6000_core *dev) +{ + struct tm6000_ops *ops = NULL; + + mutex_lock(&tm6000_extension_devlist_lock); + if (!list_empty(&tm6000_extension_devlist)) { + list_for_each_entry(ops, &tm6000_extension_devlist, next) { + if (ops->fini) + ops->fini(dev); + } + } + mutex_unlock(&tm6000_extension_devlist_lock); +} diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h index 6812d6867d57..79ef72a3f431 100644 --- a/drivers/staging/tm6000/tm6000.h +++ b/drivers/staging/tm6000/tm6000.h @@ -168,6 +168,10 @@ struct tm6000_core { struct i2c_adapter i2c_adap; struct i2c_client i2c_client; + + /* extension */ + struct list_head devlist; + /* video for linux */ int users; @@ -203,6 +207,16 @@ struct tm6000_core { spinlock_t slock; }; +#define TM6000_AUDIO 0x10 + +struct tm6000_ops { + struct list_head next; + char *name; + int id; + int (*init)(struct tm6000_core *); + int (*fini)(struct tm6000_core *); +}; + struct tm6000_fh { struct tm6000_core *dev; @@ -246,6 +260,13 @@ int tm6000_v4l2_unregister(struct tm6000_core *dev); int tm6000_v4l2_exit(void); void tm6000_set_fourcc_format(struct tm6000_core *dev); +void tm6000_remove_from_devlist(struct tm6000_core *dev); +void tm6000_add_into_devlist(struct tm6000_core *dev); +int tm6000_register_extension(struct tm6000_ops *ops); +void tm6000_unregister_extension(struct tm6000_ops *ops); +void tm6000_init_extension(struct tm6000_core *dev); +void tm6000_close_extension(struct tm6000_core *dev); + /* In tm6000-stds.c */ void tm6000_get_std_res(struct tm6000_core *dev); int tm6000_set_standard (struct tm6000_core *dev, v4l2_std_id *norm); @@ -275,7 +296,7 @@ unsigned int tm6000_v4l2_poll(struct file *file, int tm6000_queue_init(struct tm6000_core *dev); /* In tm6000-alsa.c */ -int tm6000_audio_init(struct tm6000_core *dev, int idx); +/*int tm6000_audio_init(struct tm6000_core *dev, int idx);*/ /* Debug stuff */ -- cgit v1.2.3 From b9eb39d8f419d76e1d59febe48a6791f1fbb68c4 Mon Sep 17 00:00:00 2001 From: Stefan Ringel Date: Mon, 10 May 2010 13:22:50 -0300 Subject: V4L/DVB: tm6000: Remove an extra ; symbol Signed-off-by: Stefan Ringel Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/tm6000/tm6000-cards.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c index ab12291e0b42..33b134b521be 100644 --- a/drivers/staging/tm6000/tm6000-cards.c +++ b/drivers/staging/tm6000/tm6000-cards.c @@ -563,7 +563,7 @@ static void tm6000_config_tuner(struct tm6000_core *dev) switch (dev->tuner_type) { case TUNER_XC2028: - tun_setup.tuner_callback = tm6000_tuner_callback;; + tun_setup.tuner_callback = tm6000_tuner_callback; break; case TUNER_XC5000: tun_setup.tuner_callback = tm6000_xc5000_callback; -- cgit v1.2.3 From 2a15ac7ad625dc22885446016d730a451df1b7d4 Mon Sep 17 00:00:00 2001 From: Dmitri Belimov Date: Tue, 18 May 2010 04:23:29 -0300 Subject: V4L/DVB: tm6000, reset I2C bus function Add new function for reset I2C bus. Rework some code for use this function. Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/tm6000/tm6000-cards.c | 17 ++--------------- drivers/staging/tm6000/tm6000-core.c | 16 ++++++++++++++++ drivers/staging/tm6000/tm6000.h | 2 ++ 3 files changed, 20 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c index 33b134b521be..22fbd75a551d 100644 --- a/drivers/staging/tm6000/tm6000-cards.c +++ b/drivers/staging/tm6000/tm6000-cards.c @@ -363,13 +363,7 @@ int tm6000_tuner_callback(void *ptr, int component, int command, int arg) tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 0x02, arg); msleep(10); - rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - TM6000_GPIO_CLK, 0); - if (rc < 0) - return rc; - msleep(10); - rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - TM6000_GPIO_CLK, 1); + rc = tm6000_i2c_reset(dev, 10); break; case XC2028_TUNER_RESET: /* Reset codes during load firmware */ @@ -423,14 +417,7 @@ int tm6000_tuner_callback(void *ptr, int component, int command, int arg) break; case 2: - rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - TM6000_GPIO_CLK, 0); - if (rc < 0) - return rc; - msleep(100); - rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - TM6000_GPIO_CLK, 1); - msleep(100); + rc = tm6000_i2c_reset(dev, 100); break; } } diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c index 1259ae550547..65feb8cb421c 100644 --- a/drivers/staging/tm6000/tm6000-core.c +++ b/drivers/staging/tm6000/tm6000-core.c @@ -153,6 +153,22 @@ int tm6000_get_reg32 (struct tm6000_core *dev, u8 req, u16 value, u16 index) return buf[3] | buf[2] << 8 | buf[1] << 16 | buf[0] << 24; } +int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep) +{ + int rc; + + rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_CLK, 0); + if (rc < 0) + return rc; + + msleep(tsleep); + + rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_CLK, 1); + msleep(tsleep); + + return rc; +} + void tm6000_set_fourcc_format(struct tm6000_core *dev) { if (dev->dev_type == TM6010) { diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h index 79ef72a3f431..7bbaf26dea14 100644 --- a/drivers/staging/tm6000/tm6000.h +++ b/drivers/staging/tm6000/tm6000.h @@ -246,6 +246,8 @@ int tm6000_get_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index); int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index); int tm6000_get_reg32(struct tm6000_core *dev, u8 req, u16 value, u16 index); int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index); +int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep); + int tm6000_init (struct tm6000_core *dev); int tm6000_init_analog_mode (struct tm6000_core *dev); -- cgit v1.2.3 From 0f9bdbc2da442a78990579cabc1554446ed784a7 Mon Sep 17 00:00:00 2001 From: Stefan Ringel Date: Wed, 19 May 2010 13:58:24 -0300 Subject: V4L/DVB: tm6000: bugfix incorrect size Signed-off-by: Stefan Ringel Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/tm6000/tm6000-video.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c index f2b7fe4a3581..2adf3cc972d3 100644 --- a/drivers/staging/tm6000/tm6000-video.c +++ b/drivers/staging/tm6000/tm6000-video.c @@ -205,7 +205,11 @@ static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp, c = (header >> 24) & 0xff; /* split the header fields */ - size = (((header & 0x7e) << 1) -1) *4; + size = ((header & 0x7e) << 1); + + if (size > 0) + size -= 4; + block = (header >> 7) & 0xf; field = (header >> 11) & 0x1; line = (header >> 12) & 0x1ff; -- cgit v1.2.3 From 3569417e5a2c20764158961a2f6c514d26136e5f Mon Sep 17 00:00:00 2001 From: Stefan Ringel Date: Wed, 19 May 2010 13:58:25 -0300 Subject: V4L/DVB: tm6000: add vbi message inside the type switch add case line for vbi message Signed-off-by: Stefan Ringel Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/tm6000/tm6000-video.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c index 2adf3cc972d3..02b88b550a47 100644 --- a/drivers/staging/tm6000/tm6000-video.c +++ b/drivers/staging/tm6000/tm6000-video.c @@ -311,10 +311,12 @@ static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp, case TM6000_URB_MSG_PTS: break; case TM6000_URB_MSG_AUDIO: -/* Need some code to process audio */ -printk ("%ld: cmd=%s, size=%d\n", jiffies, + /* Need some code to process audio */ + printk ("%ld: cmd=%s, size=%d\n", jiffies, tm6000_msg_type[cmd],size); break; + case TM6000_URB_MSG_VBI: + break; default: dprintk (dev, V4L2_DEBUG_ISOC, "cmd=%s, size=%d\n", tm6000_msg_type[cmd],size); -- cgit v1.2.3 From 4b6ed9fd0baf34da6912bebee46c36eda0411984 Mon Sep 17 00:00:00 2001 From: Stefan Ringel Date: Wed, 19 May 2010 13:58:26 -0300 Subject: V4L/DVB: tm6000: bugfix video image bugfix: Avoid loosing frames, causing image delays on some of the image lines. [mchehab@redhat.com: Fix compilation breakage by merging with the patch fix] Signed-off-by: Stefan Ringel Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/tm6000/tm6000-video.c | 88 ++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c index 02b88b550a47..8acfebdb5cda 100644 --- a/drivers/staging/tm6000/tm6000-video.c +++ b/drivers/staging/tm6000/tm6000-video.c @@ -339,14 +339,23 @@ static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp, return rc; } -static int copy_streams(u8 *data, u8 *out_p, unsigned long len, - struct urb *urb, struct tm6000_buffer **buf) +static int copy_streams(u8 *data, unsigned long len, + struct urb *urb) { struct tm6000_dmaqueue *dma_q = urb->context; struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq); u8 *ptr=data, *endp=data+len; unsigned long header=0; int rc=0; + struct tm6000_buffer *buf; + char *outp = NULL; + + get_next_buf(dma_q, &buf); + if (buf) + outp = videobuf_to_vmalloc(&buf->vb); + + if (!outp) + return 0; for (ptr=data; ptrisoc_ctl.cmd) { @@ -394,14 +403,14 @@ static int copy_streams(u8 *data, u8 *out_p, unsigned long len, } HEADER: /* Copy or continue last copy */ - rc=copy_packet(urb,header,&ptr,endp,out_p,buf); + rc=copy_packet(urb,header,&ptr,endp,outp,&buf); if (rc<0) { buf=NULL; printk(KERN_ERR "tm6000: buffer underrun at %ld\n", jiffies); return rc; } - if (!*buf) + if (!buf) return 0; } @@ -410,31 +419,40 @@ HEADER: /* * Identify the tm5600/6000 buffer header type and properly handles */ -static int copy_multiplexed(u8 *ptr, u8 *out_p, unsigned long len, - struct urb *urb, struct tm6000_buffer **buf) +static int copy_multiplexed(u8 *ptr, unsigned long len, + struct urb *urb) { struct tm6000_dmaqueue *dma_q = urb->context; struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq); unsigned int pos=dev->isoc_ctl.pos,cpysize; int rc=1; + struct tm6000_buffer *buf; + char *outp = NULL; + + get_next_buf(dma_q, &buf); + if (buf) + outp = videobuf_to_vmalloc(&buf->vb); + + if (!outp) + return 0; while (len>0) { - cpysize=min(len,(*buf)->vb.size-pos); -//printk("Copying %d bytes (max=%lu) from %p to %p[%u]\n",cpysize,(*buf)->vb.size,ptr,out_p,pos); - memcpy(&out_p[pos], ptr, cpysize); + cpysize=min(len,buf->vb.size-pos); + //printk("Copying %d bytes (max=%lu) from %p to %p[%u]\n",cpysize,(*buf)->vb.size,ptr,out_p,pos); + memcpy(&outp[pos], ptr, cpysize); pos+=cpysize; ptr+=cpysize; len-=cpysize; - if (pos >= (*buf)->vb.size) { + if (pos >= buf->vb.size) { pos=0; /* Announces that a new buffer were filled */ - buffer_filled (dev, dma_q, *buf); + buffer_filled (dev, dma_q, buf); dprintk(dev, V4L2_DEBUG_ISOC, "new buffer filled\n"); - get_next_buf (dma_q, buf); - if (!*buf) + get_next_buf (dma_q, &buf); + if (!buf) break; - out_p = videobuf_to_vmalloc(&((*buf)->vb)); - if (!out_p) + outp = videobuf_to_vmalloc(&(buf->vb)); + if (!outp) return rc; pos = 0; } @@ -493,52 +511,36 @@ static inline int tm6000_isoc_copy(struct urb *urb) struct tm6000_dmaqueue *dma_q = urb->context; struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq); struct tm6000_buffer *buf; - int i, len=0, rc=1; - int size; - char *outp = NULL, *p; - unsigned long copied; + int i, len=0, rc=1, status; + char *p; - get_next_buf(dma_q, &buf); - if (buf) - outp = videobuf_to_vmalloc(&buf->vb); - - if (!outp) - return 0; - - size = buf->vb.size; - - copied=0; - - if (urb->status<0) { - print_err_status (dev,-1,urb->status); + if (urb->status < 0) { + print_err_status (dev, -1, urb->status); return 0; } for (i = 0; i < urb->number_of_packets; i++) { - int status = urb->iso_frame_desc[i].status; + status = urb->iso_frame_desc[i].status; if (status<0) { print_err_status (dev,i,status); continue; } - len=urb->iso_frame_desc[i].actual_length; + len = urb->iso_frame_desc[i].actual_length; -// if (len>=TM6000_URB_MSG_LEN) { - p=urb->transfer_buffer + urb->iso_frame_desc[i].offset; + if (len > 0) { + p = urb->transfer_buffer + urb->iso_frame_desc[i].offset; if (!urb->iso_frame_desc[i].status) { - if ((buf->fmt->fourcc)==V4L2_PIX_FMT_TM6000) { - rc=copy_multiplexed(p, outp, len, urb, &buf); + if ((dev->fourcc)==V4L2_PIX_FMT_TM6000) { + rc=copy_multiplexed(p, len, urb); if (rc<=0) return rc; } else { - copy_streams(p, outp, len, urb, &buf); + copy_streams(p, len, urb); } } - copied += len; - if (copied >= size || !buf) - break; -// } + } } return rc; } -- cgit v1.2.3 From 5a4b55e2c256d78fd86679ee00777c393c87c94a Mon Sep 17 00:00:00 2001 From: Stefan Ringel Date: Wed, 19 May 2010 13:58:27 -0300 Subject: V4L/DVB: tm6000: bugfix stabilizing urb data Signed-off-by: Stefan Ringel Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/tm6000/tm6000-video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c index 8acfebdb5cda..56fa371e08c8 100644 --- a/drivers/staging/tm6000/tm6000-video.c +++ b/drivers/staging/tm6000/tm6000-video.c @@ -48,7 +48,7 @@ #define TM6000_MIN_BUF 4 #define TM6000_DEF_BUF 8 -#define TM6000_MAX_ISO_PACKETS 40 /* Max number of ISO packets */ +#define TM6000_MAX_ISO_PACKETS 46 /* Max number of ISO packets */ /* Declare static vars that will be used as parameters */ static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ @@ -620,7 +620,7 @@ static void tm6000_uninit_isoc(struct tm6000_core *dev) static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize) { struct tm6000_dmaqueue *dma_q = &dev->vidq; - int i, j, sb_size, pipe, size, max_packets, num_bufs = 5; + int i, j, sb_size, pipe, size, max_packets, num_bufs = 8; struct urb *urb; /* De-allocates all pending stuff */ -- cgit v1.2.3 From f36cc0342df21fc6820b53cdfba3e98ee5943f46 Mon Sep 17 00:00:00 2001 From: Stefan Ringel Date: Sun, 23 May 2010 15:29:25 -0300 Subject: V4L/DVB: tm6000: Add control to the power led Turn power led off, if device is disconnected Signed-off-by: Stefan Ringel Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/tm6000/tm6000-cards.c | 19 +++++++++++++++++++ drivers/staging/tm6000/tm6000-core.c | 13 +++++++++++++ 2 files changed, 32 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c index 22fbd75a551d..cedd9044022f 100644 --- a/drivers/staging/tm6000/tm6000-cards.c +++ b/drivers/staging/tm6000/tm6000-cards.c @@ -912,6 +912,25 @@ static void tm6000_usb_disconnect(struct usb_interface *interface) } #endif + if (dev->gpio.power_led) { + switch (dev->model) { + case TM6010_BOARD_HAUPPAUGE_900H: + case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE: + case TM6010_BOARD_TWINHAN_TU501: + /* Power led off */ + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, + dev->gpio.power_led, 0x01); + msleep(15); + break; + case TM6010_BOARD_BEHOLD_WANDER: + case TM6010_BOARD_BEHOLD_VOYAGER: + /* Power led off */ + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, + dev->gpio.power_led, 0x00); + msleep(15); + break; + } + } tm6000_v4l2_unregister(dev); tm6000_i2c_unregister(dev); diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c index 65feb8cb421c..27f3f551b545 100644 --- a/drivers/staging/tm6000/tm6000-core.c +++ b/drivers/staging/tm6000/tm6000-core.c @@ -339,6 +339,12 @@ int tm6000_init_analog_mode (struct tm6000_core *dev) tm6000_set_standard (dev, &dev->norm); tm6000_set_audio_bitrate (dev,48000); + /* switch dvb led off */ + if (dev->gpio.dvb_led) { + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, + dev->gpio.dvb_led, 0x01); + } + return 0; } @@ -391,6 +397,13 @@ int tm6000_init_digital_mode (struct tm6000_core *dev) tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00); msleep(100); } + + /* switch dvb led on */ + if (dev->gpio.dvb_led) { + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, + dev->gpio.dvb_led, 0x00); + } + return 0; } -- cgit v1.2.3 From 71d67f739e0b02995c2eb650448f031b76720307 Mon Sep 17 00:00:00 2001 From: Stefan Ringel Date: Sun, 23 May 2010 15:29:24 -0300 Subject: V4L/DVB: tm6000: Properly select the tuners Signed-off-by: Stefan Ringel Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/tm6000/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/tm6000/Kconfig b/drivers/staging/tm6000/Kconfig index 5fe759cc2ee9..3657e33e8817 100644 --- a/drivers/staging/tm6000/Kconfig +++ b/drivers/staging/tm6000/Kconfig @@ -2,7 +2,8 @@ config VIDEO_TM6000 tristate "TV Master TM5600/6000/6010 driver" depends on VIDEO_DEV && I2C && INPUT && USB && EXPERIMENTAL select VIDEO_TUNER - select TUNER_XC2028 + select MEDIA_TUNER_XC2028 + select MEDIA_TUNER_XC5000 select VIDEOBUF_VMALLOC help Support for TM5600/TM6000/TM6010 USB Device -- cgit v1.2.3 From dcf5d3aa081617a4a8aa56b7e24988d600148f50 Mon Sep 17 00:00:00 2001 From: Stefan Ringel Date: Sun, 23 May 2010 15:29:26 -0300 Subject: V4L/DVB: tm6000: set variable dev_mode in function tm6000_start_stream set variable dev_mode in function tm6000_start_stream and check mode Signed-off-by: Stefan Ringel Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/tm6000/tm6000-dvb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/tm6000/tm6000-dvb.c b/drivers/staging/tm6000/tm6000-dvb.c index eafc89c22b6b..e6a802e9c48a 100644 --- a/drivers/staging/tm6000/tm6000-dvb.c +++ b/drivers/staging/tm6000/tm6000-dvb.c @@ -100,7 +100,10 @@ int tm6000_start_stream(struct tm6000_core *dev) printk(KERN_INFO "tm6000: got start stream request %s\n",__FUNCTION__); - tm6000_init_digital_mode(dev); + if (dev->mode != TM6000_MODE_DIGITAL) { + tm6000_init_digital_mode(dev); + dev->mode = TM6000_MODE_DIGITAL; + } dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL); if(dvb->bulk_urb == NULL) { -- cgit v1.2.3 From 7e2d9820c37525da2469147eec897488ec141bcf Mon Sep 17 00:00:00 2001 From: Stefan Ringel Date: Sun, 23 May 2010 15:31:44 -0300 Subject: V4L/DVB: tm6000: add DVB support for tuner xc5000 [mchehab@redhat.com: Fix compilation breakage due to duplicate cfg config delaration without {}] Signed-off-by: Stefan Ringel Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/tm6000/tm6000-dvb.c | 69 ++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tm6000/tm6000-dvb.c b/drivers/staging/tm6000/tm6000-dvb.c index e6a802e9c48a..261e66acbe46 100644 --- a/drivers/staging/tm6000/tm6000-dvb.c +++ b/drivers/staging/tm6000/tm6000-dvb.c @@ -28,6 +28,7 @@ #include #include "tuner-xc2028.h" +#include "xc5000.h" static void inline print_err_status (struct tm6000_core *dev, int packet, int status) @@ -257,27 +258,55 @@ int tm6000_dvb_register(struct tm6000_core *dev) dvb->adapter.priv = dev; if (dvb->frontend) { - struct xc2028_config cfg = { - .i2c_adap = &dev->i2c_adap, - .i2c_addr = dev->tuner_addr, - }; - - dvb->frontend->callback = tm6000_tuner_callback; - ret = dvb_register_frontend(&dvb->adapter, dvb->frontend); - if (ret < 0) { - printk(KERN_ERR - "tm6000: couldn't register frontend\n"); - goto adapter_err; + switch (dev->tuner_type) { + case TUNER_XC2028: { + struct xc2028_config cfg = { + .i2c_adap = &dev->i2c_adap, + .i2c_addr = dev->tuner_addr, + }; + + dvb->frontend->callback = tm6000_tuner_callback; + ret = dvb_register_frontend(&dvb->adapter, dvb->frontend); + if (ret < 0) { + printk(KERN_ERR + "tm6000: couldn't register frontend\n"); + goto adapter_err; + } + + if (!dvb_attach(xc2028_attach, dvb->frontend, &cfg)) { + printk(KERN_ERR "tm6000: couldn't register " + "frontend (xc3028)\n"); + ret = -EINVAL; + goto frontend_err; + } + printk(KERN_INFO "tm6000: XC2028/3028 asked to be " + "attached to frontend!\n"); + break; + } + case TUNER_XC5000: { + struct xc5000_config cfg = { + .i2c_address = dev->tuner_addr, + }; + + dvb->frontend->callback = tm6000_xc5000_callback; + ret = dvb_register_frontend(&dvb->adapter, dvb->frontend); + if (ret < 0) { + printk(KERN_ERR + "tm6000: couldn't register frontend\n"); + goto adapter_err; + } + + if (!dvb_attach(xc5000_attach, dvb->frontend, &dev->i2c_adap, &cfg)) { + printk(KERN_ERR "tm6000: couldn't register " + "frontend (xc5000)\n"); + ret = -EINVAL; + goto frontend_err; + } + printk(KERN_INFO "tm6000: XC5000 asked to be " + "attached to frontend!\n"); + break; + } } - - if (!dvb_attach(xc2028_attach, dvb->frontend, &cfg)) { - printk(KERN_ERR "tm6000: couldn't register " - "frontend (xc3028)\n"); - ret = -EINVAL; - goto frontend_err; - } - printk(KERN_INFO "tm6000: XC2028/3028 asked to be " - "attached to frontend!\n"); } else { printk(KERN_ERR "tm6000: no frontend found\n"); } -- cgit v1.2.3 From 63fc31e8d0757574edb03ed73986be56e70a75c1 Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Mon, 10 May 2010 15:43:31 -0300 Subject: V4L/DVB: saa7134: add RM-K6 remote control support for Avermedia M135A This change adds support for one more remote control type for Avermedia M135A (model RM-K6), shipped with Positivo machines. Signed-off-by: Herton Ronaldo Krzesinski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/IR/keymaps/Makefile | 2 +- .../media/IR/keymaps/rc-avermedia-m135a-rm-jx.c | 90 ------------- drivers/media/IR/keymaps/rc-avermedia-m135a.c | 147 +++++++++++++++++++++ drivers/media/video/saa7134/saa7134-input.c | 2 +- include/media/rc-map.h | 2 +- 5 files changed, 150 insertions(+), 93 deletions(-) delete mode 100644 drivers/media/IR/keymaps/rc-avermedia-m135a-rm-jx.c create mode 100644 drivers/media/IR/keymaps/rc-avermedia-m135a.c (limited to 'drivers') diff --git a/drivers/media/IR/keymaps/Makefile b/drivers/media/IR/keymaps/Makefile index 585f75c3f376..aea649fbcf5a 100644 --- a/drivers/media/IR/keymaps/Makefile +++ b/drivers/media/IR/keymaps/Makefile @@ -6,7 +6,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ rc-avermedia.o \ rc-avermedia-cardbus.o \ rc-avermedia-dvbt.o \ - rc-avermedia-m135a-rm-jx.o \ + rc-avermedia-m135a.o \ rc-avermedia-m733a-rm-k6.o \ rc-avertv-303.o \ rc-behold.o \ diff --git a/drivers/media/IR/keymaps/rc-avermedia-m135a-rm-jx.c b/drivers/media/IR/keymaps/rc-avermedia-m135a-rm-jx.c deleted file mode 100644 index 101e7ea85941..000000000000 --- a/drivers/media/IR/keymaps/rc-avermedia-m135a-rm-jx.c +++ /dev/null @@ -1,90 +0,0 @@ -/* avermedia-m135a-rm-jx.h - Keytable for avermedia_m135a_rm_jx Remote Controller - * - * keymap imported from ir-keymaps.c - * - * Copyright (c) 2010 by Mauro Carvalho Chehab - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include - -/* - * Avermedia M135A with IR model RM-JX - * The same codes exist on both Positivo (BR) and original IR - * Mauro Carvalho Chehab - */ - -static struct ir_scancode avermedia_m135a_rm_jx[] = { - { 0x0200, KEY_POWER2 }, - { 0x022e, KEY_DOT }, /* '.' */ - { 0x0201, KEY_MODE }, /* TV/FM or SOURCE */ - - { 0x0205, KEY_1 }, - { 0x0206, KEY_2 }, - { 0x0207, KEY_3 }, - { 0x0209, KEY_4 }, - { 0x020a, KEY_5 }, - { 0x020b, KEY_6 }, - { 0x020d, KEY_7 }, - { 0x020e, KEY_8 }, - { 0x020f, KEY_9 }, - { 0x0211, KEY_0 }, - - { 0x0213, KEY_RIGHT }, /* -> or L */ - { 0x0212, KEY_LEFT }, /* <- or R */ - - { 0x0217, KEY_SLEEP }, /* Capturar Imagem or Snapshot */ - { 0x0210, KEY_SHUFFLE }, /* Amostra or 16 chan prev */ - - { 0x0303, KEY_CHANNELUP }, - { 0x0302, KEY_CHANNELDOWN }, - { 0x021f, KEY_VOLUMEUP }, - { 0x021e, KEY_VOLUMEDOWN }, - { 0x020c, KEY_ENTER }, /* Full Screen */ - - { 0x0214, KEY_MUTE }, - { 0x0208, KEY_AUDIO }, - - { 0x0203, KEY_TEXT }, /* Teletext */ - { 0x0204, KEY_EPG }, - { 0x022b, KEY_TV2 }, /* TV2 or PIP */ - - { 0x021d, KEY_RED }, - { 0x021c, KEY_YELLOW }, - { 0x0301, KEY_GREEN }, - { 0x0300, KEY_BLUE }, - - { 0x021a, KEY_PLAYPAUSE }, - { 0x0219, KEY_RECORD }, - { 0x0218, KEY_PLAY }, - { 0x021b, KEY_STOP }, -}; - -static struct rc_keymap avermedia_m135a_rm_jx_map = { - .map = { - .scan = avermedia_m135a_rm_jx, - .size = ARRAY_SIZE(avermedia_m135a_rm_jx), - .ir_type = IR_TYPE_NEC, - .name = RC_MAP_AVERMEDIA_M135A_RM_JX, - } -}; - -static int __init init_rc_map_avermedia_m135a_rm_jx(void) -{ - return ir_register_map(&avermedia_m135a_rm_jx_map); -} - -static void __exit exit_rc_map_avermedia_m135a_rm_jx(void) -{ - ir_unregister_map(&avermedia_m135a_rm_jx_map); -} - -module_init(init_rc_map_avermedia_m135a_rm_jx) -module_exit(exit_rc_map_avermedia_m135a_rm_jx) - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/IR/keymaps/rc-avermedia-m135a.c b/drivers/media/IR/keymaps/rc-avermedia-m135a.c new file mode 100644 index 000000000000..e4471fb2ad1e --- /dev/null +++ b/drivers/media/IR/keymaps/rc-avermedia-m135a.c @@ -0,0 +1,147 @@ +/* avermedia-m135a.c - Keytable for Avermedia M135A Remote Controllers + * + * Copyright (c) 2010 by Mauro Carvalho Chehab + * Copyright (c) 2010 by Herton Ronaldo Krzesinski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include + +/* + * Avermedia M135A with RM-JX and RM-K6 remote controls + * + * On Avermedia M135A with IR model RM-JX, the same codes exist on both + * Positivo (BR) and original IR, initial version and remote control codes + * added by Mauro Carvalho Chehab + * + * Positivo also ships Avermedia M135A with model RM-K6, extra control + * codes added by Herton Ronaldo Krzesinski + */ + +static struct ir_scancode avermedia_m135a[] = { + /* RM-JX */ + { 0x0200, KEY_POWER2 }, + { 0x022e, KEY_DOT }, /* '.' */ + { 0x0201, KEY_MODE }, /* TV/FM or SOURCE */ + + { 0x0205, KEY_1 }, + { 0x0206, KEY_2 }, + { 0x0207, KEY_3 }, + { 0x0209, KEY_4 }, + { 0x020a, KEY_5 }, + { 0x020b, KEY_6 }, + { 0x020d, KEY_7 }, + { 0x020e, KEY_8 }, + { 0x020f, KEY_9 }, + { 0x0211, KEY_0 }, + + { 0x0213, KEY_RIGHT }, /* -> or L */ + { 0x0212, KEY_LEFT }, /* <- or R */ + + { 0x0217, KEY_SLEEP }, /* Capturar Imagem or Snapshot */ + { 0x0210, KEY_SHUFFLE }, /* Amostra or 16 chan prev */ + + { 0x0303, KEY_CHANNELUP }, + { 0x0302, KEY_CHANNELDOWN }, + { 0x021f, KEY_VOLUMEUP }, + { 0x021e, KEY_VOLUMEDOWN }, + { 0x020c, KEY_ENTER }, /* Full Screen */ + + { 0x0214, KEY_MUTE }, + { 0x0208, KEY_AUDIO }, + + { 0x0203, KEY_TEXT }, /* Teletext */ + { 0x0204, KEY_EPG }, + { 0x022b, KEY_TV2 }, /* TV2 or PIP */ + + { 0x021d, KEY_RED }, + { 0x021c, KEY_YELLOW }, + { 0x0301, KEY_GREEN }, + { 0x0300, KEY_BLUE }, + + { 0x021a, KEY_PLAYPAUSE }, + { 0x0219, KEY_RECORD }, + { 0x0218, KEY_PLAY }, + { 0x021b, KEY_STOP }, + + /* RM-K6 */ + { 0x0401, KEY_POWER2 }, + { 0x0406, KEY_MUTE }, + { 0x0408, KEY_MODE }, /* TV/FM */ + + { 0x0409, KEY_1 }, + { 0x040a, KEY_2 }, + { 0x040b, KEY_3 }, + { 0x040c, KEY_4 }, + { 0x040d, KEY_5 }, + { 0x040e, KEY_6 }, + { 0x040f, KEY_7 }, + { 0x0410, KEY_8 }, + { 0x0411, KEY_9 }, + { 0x044c, KEY_DOT }, /* '.' */ + { 0x0412, KEY_0 }, + { 0x0407, KEY_REFRESH }, /* Refresh/Reload */ + + { 0x0413, KEY_AUDIO }, + { 0x0440, KEY_SCREEN }, /* Full Screen toggle */ + { 0x0441, KEY_HOME }, + { 0x0442, KEY_BACK }, + { 0x0447, KEY_UP }, + { 0x0448, KEY_DOWN }, + { 0x0449, KEY_LEFT }, + { 0x044a, KEY_RIGHT }, + { 0x044b, KEY_OK }, + { 0x0404, KEY_VOLUMEUP }, + { 0x0405, KEY_VOLUMEDOWN }, + { 0x0402, KEY_CHANNELUP }, + { 0x0403, KEY_CHANNELDOWN }, + + { 0x0443, KEY_RED }, + { 0x0444, KEY_GREEN }, + { 0x0445, KEY_YELLOW }, + { 0x0446, KEY_BLUE }, + + { 0x0414, KEY_TEXT }, + { 0x0415, KEY_EPG }, + { 0x041a, KEY_TV2 }, /* PIP */ + { 0x041b, KEY_MHP }, /* Snapshot */ + + { 0x0417, KEY_RECORD }, + { 0x0416, KEY_PLAYPAUSE }, + { 0x0418, KEY_STOP }, + { 0x0419, KEY_PAUSE }, + + { 0x041f, KEY_PREVIOUS }, + { 0x041c, KEY_REWIND }, + { 0x041d, KEY_FORWARD }, + { 0x041e, KEY_NEXT }, +}; + +static struct rc_keymap avermedia_m135a_map = { + .map = { + .scan = avermedia_m135a, + .size = ARRAY_SIZE(avermedia_m135a), + .ir_type = IR_TYPE_NEC, + .name = RC_MAP_AVERMEDIA_M135A, + } +}; + +static int __init init_rc_map_avermedia_m135a(void) +{ + return ir_register_map(&avermedia_m135a_map); +} + +static void __exit exit_rc_map_avermedia_m135a(void) +{ + ir_unregister_map(&avermedia_m135a_map); +} + +module_init(init_rc_map_avermedia_m135a) +module_exit(exit_rc_map_avermedia_m135a) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mauro Carvalho Chehab "); diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index f9ed8048894d..b36960dd7319 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -657,7 +657,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); break; case SAA7134_BOARD_AVERMEDIA_M135A: - ir_codes = RC_MAP_AVERMEDIA_M135A_RM_JX; + ir_codes = RC_MAP_AVERMEDIA_M135A; mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */ mask_keyup = 0x0040000; mask_keycode = 0xffff; diff --git a/include/media/rc-map.h b/include/media/rc-map.h index 6f1f9f76674e..c78e99a435b6 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -55,7 +55,7 @@ void rc_map_init(void); #define RC_MAP_AVERMEDIA_A16D "rc-avermedia-a16d" #define RC_MAP_AVERMEDIA_CARDBUS "rc-avermedia-cardbus" #define RC_MAP_AVERMEDIA_DVBT "rc-avermedia-dvbt" -#define RC_MAP_AVERMEDIA_M135A_RM_JX "rc-avermedia-m135a-rm-jx" +#define RC_MAP_AVERMEDIA_M135A "rc-avermedia-m135a" #define RC_MAP_AVERMEDIA_M733A_RM_K6 "rc-avermedia-m733a-rm-k6" #define RC_MAP_AVERMEDIA "rc-avermedia" #define RC_MAP_AVERTV_303 "rc-avertv-303" -- cgit v1.2.3 From a49ba1674b0cf507e62d97fbd91ce345a37b11a8 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Wed, 12 May 2010 19:30:02 -0300 Subject: V4L/DVB: Add notification to cxusb_dualdig4_rev2_frontend_attach() error handling Add a notification to the dib7000p_i2c_enumeration() failure path in cxusb_dualdig4_rev2_frontend_attach(). Signed-off-by: Prarit Bhargava Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/cxusb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 0eb490889162..11e9e85dac86 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -1026,8 +1026,10 @@ static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap) cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, - &cxusb_dualdig4_rev2_config) < 0) + &cxusb_dualdig4_rev2_config) < 0) { + printk(KERN_WARNING "Unable to enumerate dib7000p\n"); return -ENODEV; + } adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &cxusb_dualdig4_rev2_config); -- cgit v1.2.3 From 58aac2bff192970a1186c33fbea181efe9464dd2 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 14 May 2010 14:09:57 -0300 Subject: V4L/DVB: [-next] IR: fix ir-nec-decoder build, select BITREVERSE Fix ir-nec-decoder build: it uses bitrev library code, so select BITREVERSE in its Kconfig. ir-nec-decoder.c:(.text+0x1a2517): undefined reference to `byte_rev_table' ir-nec-decoder.c:(.text+0x1a2526): undefined reference to `byte_rev_table' ir-nec-decoder.c:(.text+0x1a2530): undefined reference to `byte_rev_table' ir-nec-decoder.c:(.text+0x1a2539): undefined reference to `byte_rev_table' Signed-off-by: Randy Dunlap Signed-off-by: Mauro Carvalho Chehab --- drivers/media/IR/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig index 195c6cf359f6..b45f3bc4a7b1 100644 --- a/drivers/media/IR/Kconfig +++ b/drivers/media/IR/Kconfig @@ -13,6 +13,7 @@ source "drivers/media/IR/keymaps/Kconfig" config IR_NEC_DECODER tristate "Enable IR raw decoder for the NEC protocol" depends on IR_CORE + select BITREVERSE default y ---help--- -- cgit v1.2.3 From 9947e98a76455cec4a64aef536d375fa37cbfc32 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 15 May 2010 13:45:21 -0300 Subject: V4L/DVB: dw2102: Select tda10023 frontend, not tda10021 Update the Kconfig selections to match the code. Signed-off-by: Ben Hutchings Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index e5f91f16ffa4..cfcbf4f15b2b 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -264,7 +264,7 @@ config DVB_USB_DW2102 select DVB_STB6000 if !DVB_FE_CUSTOMISE select DVB_CX24116 if !DVB_FE_CUSTOMISE select DVB_SI21XX if !DVB_FE_CUSTOMISE - select DVB_TDA10021 if !DVB_FE_CUSTOMISE + select DVB_TDA10023 if !DVB_FE_CUSTOMISE select DVB_MT312 if !DVB_FE_CUSTOMISE select DVB_ZL10039 if !DVB_FE_CUSTOMISE select DVB_DS3000 if !DVB_FE_CUSTOMISE -- cgit v1.2.3 From d46b36e7f927772bb72524dc9f1e384e3cb4a975 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 15 May 2010 13:45:37 -0300 Subject: V4L/DVB: budget: Select correct frontends Update the Kconfig selections to match the code. Signed-off-by: Ben Hutchings Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig index d8d4214fd65f..32a7ec65ec42 100644 --- a/drivers/media/dvb/ttpci/Kconfig +++ b/drivers/media/dvb/ttpci/Kconfig @@ -68,13 +68,14 @@ config DVB_BUDGET select DVB_VES1820 if !DVB_FE_CUSTOMISE select DVB_L64781 if !DVB_FE_CUSTOMISE select DVB_TDA8083 if !DVB_FE_CUSTOMISE - select DVB_TDA10021 if !DVB_FE_CUSTOMISE - select DVB_TDA10023 if !DVB_FE_CUSTOMISE select DVB_S5H1420 if !DVB_FE_CUSTOMISE select DVB_TDA10086 if !DVB_FE_CUSTOMISE select DVB_TDA826X if !DVB_FE_CUSTOMISE select DVB_LNBP21 if !DVB_FE_CUSTOMISE select DVB_TDA1004X if !DVB_FE_CUSTOMISE + select DVB_ISL6423 if !DVB_FE_CUSTOMISE + select DVB_STV090x if !DVB_FE_CUSTOMISE + select DVB_STV6110x if !DVB_FE_CUSTOMISE help Support for simple SAA7146 based DVB cards (so called Budget- or Nova-PCI cards) without onboard MPEG2 decoder, and without -- cgit v1.2.3 From e245b0bd8253fc54dfe3b5e453af0c9841098f87 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 15 May 2010 13:45:58 -0300 Subject: V4L/DVB: dib0700: Select dib0090 frontend Update the Kconfig selections to match the code. Signed-off-by: Ben Hutchings Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index cfcbf4f15b2b..73a6e9dbbe9c 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -76,6 +76,7 @@ config DVB_USB_DIB0700 select DVB_S5H1411 if !DVB_FE_CUSTOMISE select DVB_LGDT3305 if !DVB_FE_CUSTOMISE select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE + select DVB_TUNER_DIB0090 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE -- cgit v1.2.3 From 59fd08afe0f9ae3a3b793fc178a3c3677b1e716c Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 15 May 2010 13:46:16 -0300 Subject: V4L/DVB: m920x: Select simple tuner Update the Kconfig selections to match the code. Signed-off-by: Ben Hutchings Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 73a6e9dbbe9c..553b48ac1919 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -135,6 +135,7 @@ config DVB_USB_M920X select DVB_TDA1004X if !DVB_FE_CUSTOMISE select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE help Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver. Currently, only devices with a product id of -- cgit v1.2.3 From 2ef17c9fc8241e5b08c60ca82345c540bb001876 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 13 May 2010 16:59:15 -0300 Subject: V4L/DVB: drivers/media: Use kzalloc Use kzalloc rather than the combination of kmalloc and memset. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression x,size,flags; statement S; @@ -x = kmalloc(size,flags); +x = kzalloc(size,flags); if (x == NULL) S -memset(x, 0, size); // Signed-off-by: Julia Lawall Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/ds3000.c | 5 +---- drivers/media/video/omap/omap_vout.c | 3 +-- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb/frontends/ds3000.c index 78001e8bcdb7..fc61d9230db8 100644 --- a/drivers/media/dvb/frontends/ds3000.c +++ b/drivers/media/dvb/frontends/ds3000.c @@ -969,15 +969,12 @@ struct dvb_frontend *ds3000_attach(const struct ds3000_config *config, dprintk("%s\n", __func__); /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct ds3000_state), GFP_KERNEL); + state = kzalloc(sizeof(struct ds3000_state), GFP_KERNEL); if (state == NULL) { printk(KERN_ERR "Unable to kmalloc\n"); goto error2; } - /* setup the state */ - memset(state, 0, sizeof(struct ds3000_state)); - state->config = config; state->i2c = i2c; state->prevUCBS2 = 0; diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 4c0ab499228b..e7db0554949a 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -2371,12 +2371,11 @@ static int __init omap_vout_create_video_devices(struct platform_device *pdev) for (k = 0; k < pdev->num_resources; k++) { - vout = kmalloc(sizeof(struct omap_vout_device), GFP_KERNEL); + vout = kzalloc(sizeof(struct omap_vout_device), GFP_KERNEL); if (!vout) { dev_err(&pdev->dev, ": could not allocate memory\n"); return -ENOMEM; } - memset(vout, 0, sizeof(struct omap_vout_device)); vout->vid = k; vid_dev->vouts[k] = vout; -- cgit v1.2.3 From f137f9d0009067289a2fa6c4da9b82084cdd257e Mon Sep 17 00:00:00 2001 From: Hermann Gausterer Date: Tue, 18 May 2010 04:26:17 -0300 Subject: V4L/DVB: Technotrend S2-3200 ships with a TT 1500 remote The Technotrend Budget S2-3200 ships with the Technotrend 1500 bundled remote which is already supported. Just add the right Subsystem Device ID. Signed-off-by: Hermann Gausterer Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/budget-ci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 461714396331..13ac9e3ab121 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c @@ -215,6 +215,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci) break; case 0x1010: case 0x1017: + case 0x1019: case 0x101a: /* for the Technotrend 1500 bundled remote */ ir_codes = RC_MAP_TT_1500; -- cgit v1.2.3 From 806b07c29b711aaf90c81d2a19711607769f8246 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 26 May 2010 10:05:11 -0300 Subject: V4L/DVB: FusionHDTV: Use quick reads for I2C IR device probing IR support on FusionHDTV cards is broken since kernel 2.6.31. One side effect of the switch to the standard binding model for IR I2C devices was to let i2c-core do the probing instead of the ir-kbd-i2c driver. There is a slight difference between the two probe methods: i2c-core uses 0-byte writes, while the ir-kbd-i2c was using 0-byte reads. As some IR I2C devices only support reads, the new probe method fails to detect them. For now, revert to letting the driver do the probe, using 0-byte reads. In the future, i2c-core will be extended to let callers of i2c_new_probed_device() provide a custom probing function. Signed-off-by: Jean Delvare Tested-by: "Timothy D. Lenz" Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-i2c.c | 12 +++++++++++- drivers/media/video/cx88/cx88-i2c.c | 16 +++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c index 4172cb387420..d4746e064516 100644 --- a/drivers/media/video/cx23885/cx23885-i2c.c +++ b/drivers/media/video/cx23885/cx23885-i2c.c @@ -365,7 +365,17 @@ int cx23885_i2c_register(struct cx23885_i2c *bus) memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "ir_video", I2C_NAME_SIZE); - i2c_new_probed_device(&bus->i2c_adap, &info, addr_list); + /* + * We can't call i2c_new_probed_device() because it uses + * quick writes for probing and the IR receiver device only + * replies to reads. + */ + if (i2c_smbus_xfer(&bus->i2c_adap, addr_list[0], 0, + I2C_SMBUS_READ, 0, I2C_SMBUS_QUICK, + NULL) >= 0) { + info.addr = addr_list[0]; + i2c_new_device(&bus->i2c_adap, &info); + } } return bus->i2c_rc; diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index ee1ca39db06a..fb39f1184558 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c @@ -188,10 +188,24 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) 0x18, 0x6b, 0x71, I2C_CLIENT_END }; + const unsigned short *addrp; memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "ir_video", I2C_NAME_SIZE); - i2c_new_probed_device(&core->i2c_adap, &info, addr_list); + /* + * We can't call i2c_new_probed_device() because it uses + * quick writes for probing and at least some R receiver + * devices only reply to reads. + */ + for (addrp = addr_list; *addrp != I2C_CLIENT_END; addrp++) { + if (i2c_smbus_xfer(&core->i2c_adap, *addrp, 0, + I2C_SMBUS_READ, 0, + I2C_SMBUS_QUICK, NULL) >= 0) { + info.addr = *addrp; + i2c_new_device(&core->i2c_adap, &info); + break; + } + } } return core->i2c_rc; } -- cgit v1.2.3 From 1db2c22b2216718d4d9adb4a9450bb3dc70e56d2 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 20 May 2010 18:08:23 -0300 Subject: V4L/DVB: ak881x needs slab.h Add slab.h to fix ak881x build: drivers/media/video/ak881x.c:265:error: implicit declaration of function 'kzalloc' drivers/media/video/ak881x.c:265:warning: assignment makes pointer from integer without a cast drivers/media/video/ak881x.c:283:error: implicit declaration of function 'kfree' Signed-off-by: Randy Dunlap Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ak881x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/video/ak881x.c b/drivers/media/video/ak881x.c index 3006a2c80f47..1573392f74bd 100644 --- a/drivers/media/video/ak881x.c +++ b/drivers/media/video/ak881x.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3 From 7853d408b792f9015072f7c4649bd3a5d4f6ed02 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Sat, 22 May 2010 14:12:06 -0300 Subject: V4L/DVB: ngene: remove unused #include Remove unused #include ('s) in drivers/media/dvb/ngene/ngene-dvb.c drivers/media/dvb/ngene/ngene-i2c.c Signed-off-by: Huang Weiyi Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ngene/ngene-dvb.c | 1 - drivers/media/dvb/ngene/ngene-i2c.c | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/ngene/ngene-dvb.c b/drivers/media/dvb/ngene/ngene-dvb.c index 61a932c1cfff..48f980b21d66 100644 --- a/drivers/media/dvb/ngene/ngene-dvb.c +++ b/drivers/media/dvb/ngene/ngene-dvb.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/dvb/ngene/ngene-i2c.c b/drivers/media/dvb/ngene/ngene-i2c.c index 2ef54ca6badd..477fe0aade86 100644 --- a/drivers/media/dvb/ngene/ngene-i2c.c +++ b/drivers/media/dvb/ngene/ngene-i2c.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From 517521e4651ac106fc2a4f7638c284f60de92bb8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 22 May 2010 16:53:27 -0300 Subject: V4L/DVB: em28xx: remove unneeded null checks The "dev" variable is used as a list cursor in a list_for_each_entry() loop and can never be null here so I removed the check. Signed-off-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-core.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 331e1cac4272..44c63cbd6dda 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -1186,8 +1186,7 @@ int em28xx_register_extension(struct em28xx_ops *ops) mutex_lock(&em28xx_devlist_mutex); list_add_tail(&ops->next, &em28xx_extension_devlist); list_for_each_entry(dev, &em28xx_devlist, devlist) { - if (dev) - ops->init(dev); + ops->init(dev); } printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name); mutex_unlock(&em28xx_devlist_mutex); @@ -1201,10 +1200,8 @@ void em28xx_unregister_extension(struct em28xx_ops *ops) mutex_lock(&em28xx_devlist_mutex); list_for_each_entry(dev, &em28xx_devlist, devlist) { - if (dev) - ops->fini(dev); + ops->fini(dev); } - printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name); list_del(&ops->next); mutex_unlock(&em28xx_devlist_mutex); -- cgit v1.2.3 From f789bf4013e5e003e5d75ec0b8fa280aa66f401f Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Mon, 24 May 2010 12:00:31 -0300 Subject: V4L/DVB: IR/imon: clean up usage of bools There was a mix of 0/1 and false/true. Pick one convention and stick with it (I picked false/true). Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/IR/imon.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/media/IR/imon.c b/drivers/media/IR/imon.c index 5e2045670004..2bae9ba2e40c 100644 --- a/drivers/media/IR/imon.c +++ b/drivers/media/IR/imon.c @@ -385,7 +385,7 @@ static int display_open(struct inode *inode, struct file *file) err("%s: display port is already open", __func__); retval = -EBUSY; } else { - ictx->display_isopen = 1; + ictx->display_isopen = true; file->private_data = ictx; dev_dbg(ictx->dev, "display port opened\n"); } @@ -422,7 +422,7 @@ static int display_close(struct inode *inode, struct file *file) err("%s: display is not open", __func__); retval = -EIO; } else { - ictx->display_isopen = 0; + ictx->display_isopen = false; dev_dbg(ictx->dev, "display port closed\n"); if (!ictx->dev_present_intf0) { /* @@ -491,12 +491,12 @@ static int send_packet(struct imon_context *ictx) } init_completion(&ictx->tx.finished); - ictx->tx.busy = 1; + ictx->tx.busy = true; smp_rmb(); /* ensure later readers know we're busy */ retval = usb_submit_urb(ictx->tx_urb, GFP_KERNEL); if (retval) { - ictx->tx.busy = 0; + ictx->tx.busy = false; smp_rmb(); /* ensure later readers know we're not busy */ err("%s: error submitting urb(%d)", __func__, retval); } else { @@ -682,7 +682,7 @@ static ssize_t store_associate_remote(struct device *d, return -ENODEV; mutex_lock(&ictx->lock); - ictx->rf_isassociating = 1; + ictx->rf_isassociating = true; send_associate_24g(ictx); mutex_unlock(&ictx->lock); @@ -950,7 +950,7 @@ static void usb_tx_callback(struct urb *urb) ictx->tx.status = urb->status; /* notify waiters that write has finished */ - ictx->tx.busy = 0; + ictx->tx.busy = false; smp_rmb(); /* ensure later readers know we're not busy */ complete(&ictx->tx.finished); } @@ -1215,7 +1215,7 @@ static bool imon_mouse_event(struct imon_context *ictx, { char rel_x = 0x00, rel_y = 0x00; u8 right_shift = 1; - bool mouse_input = 1; + bool mouse_input = true; int dir = 0; /* newer iMON device PAD or mouse button */ @@ -1246,7 +1246,7 @@ static bool imon_mouse_event(struct imon_context *ictx, } else if (ictx->kc == KEY_CHANNELDOWN && (buf[2] & 0x40) != 0x40) { dir = -1; } else - mouse_input = 0; + mouse_input = false; if (mouse_input) { dev_dbg(ictx->dev, "sending mouse data via input subsystem\n"); @@ -1450,7 +1450,7 @@ static void imon_incoming_packet(struct imon_context *ictx, unsigned char *buf = urb->transfer_buffer; struct device *dev = ictx->dev; u32 kc; - bool norelease = 0; + bool norelease = false; int i; u64 temp_key; u64 panel_key = 0; @@ -1517,7 +1517,7 @@ static void imon_incoming_packet(struct imon_context *ictx, !(buf[1] & 0x1 || buf[1] >> 2 & 0x1))) { len = 8; imon_pad_to_keys(ictx, buf); - norelease = 1; + norelease = true; } if (debug) { @@ -1580,7 +1580,7 @@ not_input_data: (buf[6] == 0x5E && buf[7] == 0xDF))) { /* DT */ dev_warn(dev, "%s: remote associated refid=%02X\n", __func__, buf[1]); - ictx->rf_isassociating = 0; + ictx->rf_isassociating = false; } } @@ -1790,9 +1790,9 @@ static bool imon_find_endpoints(struct imon_context *ictx, int ifnum = iface_desc->desc.bInterfaceNumber; int num_endpts = iface_desc->desc.bNumEndpoints; int i, ep_dir, ep_type; - bool ir_ep_found = 0; - bool display_ep_found = 0; - bool tx_control = 0; + bool ir_ep_found = false; + bool display_ep_found = false; + bool tx_control = false; /* * Scan the endpoint list and set: @@ -1808,13 +1808,13 @@ static bool imon_find_endpoints(struct imon_context *ictx, ep_type == USB_ENDPOINT_XFER_INT) { rx_endpoint = ep; - ir_ep_found = 1; + ir_ep_found = true; dev_dbg(ictx->dev, "%s: found IR endpoint\n", __func__); } else if (!display_ep_found && ep_dir == USB_DIR_OUT && ep_type == USB_ENDPOINT_XFER_INT) { tx_endpoint = ep; - display_ep_found = 1; + display_ep_found = true; dev_dbg(ictx->dev, "%s: found display endpoint\n", __func__); } } @@ -1835,8 +1835,8 @@ static bool imon_find_endpoints(struct imon_context *ictx, * newer iMON devices that use control urb instead of interrupt */ if (!display_ep_found) { - tx_control = 1; - display_ep_found = 1; + tx_control = true; + display_ep_found = true; dev_dbg(ictx->dev, "%s: device uses control endpoint, not " "interface OUT endpoint\n", __func__); } @@ -1847,7 +1847,7 @@ static bool imon_find_endpoints(struct imon_context *ictx, * and without... :\ */ if (ictx->display_type == IMON_DISPLAY_TYPE_NONE) { - display_ep_found = 0; + display_ep_found = false; dev_dbg(ictx->dev, "%s: device has no display\n", __func__); } @@ -1856,7 +1856,7 @@ static bool imon_find_endpoints(struct imon_context *ictx, * that refers to e.g. /dev/lcd0 (a character device LCD or VFD). */ if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) { - display_ep_found = 0; + display_ep_found = false; dev_dbg(ictx->dev, "%s: iMON Touch device found\n", __func__); } @@ -1905,7 +1905,7 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf) ictx->dev = dev; ictx->usbdev_intf0 = usb_get_dev(interface_to_usbdev(intf)); - ictx->dev_present_intf0 = 1; + ictx->dev_present_intf0 = true; ictx->rx_urb_intf0 = rx_urb; ictx->tx_urb = tx_urb; @@ -1979,7 +1979,7 @@ static struct imon_context *imon_init_intf1(struct usb_interface *intf, } ictx->usbdev_intf1 = usb_get_dev(interface_to_usbdev(intf)); - ictx->dev_present_intf1 = 1; + ictx->dev_present_intf1 = true; ictx->rx_urb_intf1 = rx_urb; ret = -ENODEV; @@ -2297,7 +2297,7 @@ static void __devexit imon_disconnect(struct usb_interface *interface) } if (ifnum == 0) { - ictx->dev_present_intf0 = 0; + ictx->dev_present_intf0 = false; usb_kill_urb(ictx->rx_urb_intf0); input_unregister_device(ictx->idev); if (ictx->display_supported) { @@ -2307,7 +2307,7 @@ static void __devexit imon_disconnect(struct usb_interface *interface) usb_deregister_dev(interface, &imon_vfd_class); } } else { - ictx->dev_present_intf1 = 0; + ictx->dev_present_intf1 = false; usb_kill_urb(ictx->rx_urb_intf1); if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) input_unregister_device(ictx->touch); -- cgit v1.2.3 From bbe4690f6caef2b36c95dd50e59bc3f4e2eaa6ad Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Mon, 24 May 2010 12:02:05 -0300 Subject: V4L/DVB: IR/imon: add auto-config for 0xffdc rf device Add auto-config support for iMON 2.4G LT RF device, based on debug output from Giulio Amodeo in Red Hat bugzilla #572288. Also flips the switch on only setting up the rf associate sysfs attr only if we think we're looking at an RF device, vs. previously, setting up the attr for all 0xffdc devices, so its possible (but a bit unlikely) there's another iMON RF device we'll have to fix up. Nb: should be applied after "IR/imon: clean up usage of bools", or there will be a slight contextual mismatch. Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/IR/imon.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/media/IR/imon.c b/drivers/media/IR/imon.c index 2bae9ba2e40c..4bbd45f4284c 100644 --- a/drivers/media/IR/imon.c +++ b/drivers/media/IR/imon.c @@ -94,6 +94,7 @@ struct imon_context { bool display_supported; /* not all controllers do */ bool display_isopen; /* display port has been opened */ + bool rf_device; /* true if iMON 2.4G LT/DT RF device */ bool rf_isassociating; /* RF remote associating */ bool dev_present_intf0; /* USB device presence, interface 0 */ bool dev_present_intf1; /* USB device presence, interface 1 */ @@ -1465,7 +1466,7 @@ static void imon_incoming_packet(struct imon_context *ictx, idev = ictx->idev; /* filter out junk data on the older 0xffdc imon devices */ - if ((buf[0] == 0xff) && (buf[7] == 0xff)) + if ((buf[0] == 0xff) && (buf[1] == 0xff) && (buf[2] == 0xff)) return; /* Figure out what key was pressed */ @@ -1908,6 +1909,7 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf) ictx->dev_present_intf0 = true; ictx->rx_urb_intf0 = rx_urb; ictx->tx_urb = tx_urb; + ictx->rf_device = false; ictx->vendor = le16_to_cpu(ictx->usbdev_intf0->descriptor.idVendor); ictx->product = le16_to_cpu(ictx->usbdev_intf0->descriptor.idProduct); @@ -2047,6 +2049,12 @@ static void imon_get_ffdc_type(struct imon_context *ictx) dev_info(ictx->dev, "0xffdc iMON Knob, iMON IR"); ictx->display_supported = false; break; + /* iMON 2.4G LT (usb stick), no display, iMON RF */ + case 0x4e: + dev_info(ictx->dev, "0xffdc iMON 2.4G LT, iMON RF"); + ictx->display_supported = false; + ictx->rf_device = true; + break; /* iMON VFD, no IR (does have vol knob tho) */ case 0x35: dev_info(ictx->dev, "0xffdc iMON VFD + knob, no IR"); @@ -2197,15 +2205,6 @@ static int __devinit imon_probe(struct usb_interface *interface, goto fail; } - if (product == 0xffdc) { - /* RF products *also* use 0xffdc... sigh... */ - sysfs_err = sysfs_create_group(&interface->dev.kobj, - &imon_rf_attribute_group); - if (sysfs_err) - err("%s: Could not create RF sysfs entries(%d)", - __func__, sysfs_err); - } - } else { /* this is the secondary interface on the device */ ictx = imon_init_intf1(interface, first_if_ctx); @@ -2233,6 +2232,14 @@ static int __devinit imon_probe(struct usb_interface *interface, imon_set_display_type(ictx, interface); + if (product == 0xffdc && ictx->rf_device) { + sysfs_err = sysfs_create_group(&interface->dev.kobj, + &imon_rf_attribute_group); + if (sysfs_err) + err("%s: Could not create RF sysfs entries(%d)", + __func__, sysfs_err); + } + if (ictx->display_supported) imon_init_display(ictx, interface); } -- cgit v1.2.3 From f0e5481f2f5304ffebd43d97bd5118443fac8d23 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 25 May 2010 06:21:50 -0300 Subject: V4L/DVB: video/saa7134: remove duplicate break The original code had two break statements in a row. Signed-off-by: Dan Carpenter Acked-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-input.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index b36960dd7319..c1240d22028a 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -822,7 +822,6 @@ int saa7134_input_init1(struct saa7134_dev *dev) mask_keyup = 0x020000; polling = 50; /* ms */ break; - break; } if (NULL == ir_codes) { printk("%s: Oops: IR config error [card=%d]\n", -- cgit v1.2.3 From 129c34d8fce443d1c43d32637abbab8433504497 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 26 May 2010 11:58:10 -0300 Subject: V4L/DVB: video/saa7134: change dprintk() to i2cdprintk() The problem is that dprintk() dereferences "dev" which is null here. The i2cdprintk() uses "ir" so that's OK. Also Jean Delvare pointed out a typo in the comment so we may as well fix that. Signed-off-by: Dan Carpenter Acked-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-input.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index c1240d22028a..0b336ca6d55b 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -141,8 +141,8 @@ static int get_key_flydvb_trio(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) struct saa7134_dev *dev = ir->c->adapter->algo_data; if (dev == NULL) { - dprintk("get_key_flydvb_trio: " - "gir->c->adapter->algo_data is NULL!\n"); + i2cdprintk("get_key_flydvb_trio: " + "ir->c->adapter->algo_data is NULL!\n"); return -EIO; } @@ -195,8 +195,8 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key, /* is needed to access GPIO. Used by the saa_readl macro. */ struct saa7134_dev *dev = ir->c->adapter->algo_data; if (dev == NULL) { - dprintk("get_key_msi_tvanywhere_plus: " - "gir->c->adapter->algo_data is NULL!\n"); + i2cdprintk("get_key_msi_tvanywhere_plus: " + "ir->c->adapter->algo_data is NULL!\n"); return -EIO; } -- cgit v1.2.3 From 033608c1f33bcacba8d3a960240a7b2900b1d5ff Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 26 May 2010 14:08:51 -0300 Subject: V4L/DVB: media/IR: nec-decoder needs to select BITREV Fix ir-nec-decoder build: it uses bitrev library code, so select BITREVERSE in its Kconfig. ir-nec-decoder.c:(.text+0x1a2517): undefined reference to `byte_rev_table' ir-nec-decoder.c:(.text+0x1a2526): undefined reference to `byte_rev_table' ir-nec-decoder.c:(.text+0x1a2530): undefined reference to `byte_rev_table' ir-nec-decoder.c:(.text+0x1a2539): undefined reference to `byte_rev_table' Signed-off-by: Randy Dunlap Signed-off-by: Mauro Carvalho Chehab --- drivers/media/IR/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig index b45f3bc4a7b1..d22a8ec523fc 100644 --- a/drivers/media/IR/Kconfig +++ b/drivers/media/IR/Kconfig @@ -23,6 +23,7 @@ config IR_NEC_DECODER config IR_RC5_DECODER tristate "Enable IR raw decoder for the RC-5 protocol" depends on IR_CORE + select BITREVERSE default y ---help--- -- cgit v1.2.3 From 84b14f181a36eea6591779156ef356f8d198bbfd Mon Sep 17 00:00:00 2001 From: "Igor M. Liplianin" Date: Wed, 26 May 2010 23:31:21 -0300 Subject: V4L/DVB: Bug fix: make IR work again for dm1105 It makes IR to work again for dm1105 and, possibly, others. Signed-off-by: Igor M. Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/IR/ir-keytable.c | 17 ++++++++++------- drivers/media/IR/ir-sysfs.c | 7 ++++--- drivers/media/dvb/dm1105/dm1105.c | 2 +- 3 files changed, 15 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index 9374a006f43d..94a8577e72eb 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c @@ -490,11 +490,12 @@ int __ir_input_register(struct input_dev *input_dev, if (rc < 0) goto out_table; - if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) { - rc = ir_raw_event_register(input_dev); - if (rc < 0) - goto out_event; - } + if (ir_dev->props) + if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) { + rc = ir_raw_event_register(input_dev); + if (rc < 0) + goto out_event; + } IR_dprintk(1, "Registered input device on %s for %s remote.\n", driver_name, rc_tab->name); @@ -530,8 +531,10 @@ void ir_input_unregister(struct input_dev *input_dev) IR_dprintk(1, "Freed keycode table\n"); del_timer_sync(&ir_dev->timer_keyup); - if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) - ir_raw_event_unregister(input_dev); + if (ir_dev->props) + if (ir_dev->props->driver_type == RC_DRIVER_IR_RAW) + ir_raw_event_unregister(input_dev); + rc_tab = &ir_dev->rc_tab; rc_tab->size = 0; kfree(rc_tab->scan); diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c index d7da63e16c92..2098dd1488e0 100644 --- a/drivers/media/IR/ir-sysfs.c +++ b/drivers/media/IR/ir-sysfs.c @@ -221,9 +221,10 @@ int ir_register_class(struct input_dev *input_dev) if (unlikely(devno < 0)) return devno; - if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) - ir_dev->dev.type = &rc_dev_type; - else + if (ir_dev->props) { + if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) + ir_dev->dev.type = &rc_dev_type; + } else ir_dev->dev.type = &ir_raw_dev_type; ir_dev->dev.class = &ir_input_class; diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c index b762e561a6d5..bca07c0bcd01 100644 --- a/drivers/media/dvb/dm1105/dm1105.c +++ b/drivers/media/dvb/dm1105/dm1105.c @@ -594,7 +594,7 @@ static irqreturn_t dm1105_irq(int irq, void *dev_id) int __devinit dm1105_ir_init(struct dm1105_dev *dm1105) { struct input_dev *input_dev; - char *ir_codes = NULL; + char *ir_codes = RC_MAP_DM1105_NEC; int err = -ENOMEM; input_dev = input_allocate_device(); -- cgit v1.2.3 From 5c331fc8c19e181bffab46e9d18e1637cdc47170 Mon Sep 17 00:00:00 2001 From: Ang Way Chuang Date: Thu, 27 May 2010 02:02:09 -0300 Subject: V4L/DVB: dvb-core: Fix ULE decapsulation bug Fix ULE decapsulation bug when less than 4 bytes of ULE SNDU is packed into the remaining bytes of a MPEG2-TS frame ULE (Unidirectional Lightweight Encapsulation RFC 4326) decapsulation code has a bug that incorrectly treats ULE SNDU packed into the remaining 2 or 3 bytes of a MPEG2-TS frame as having invalid pointer field on the subsequent MPEG2-TS frame. Signed-off-by: Ang Way Chuang Acked-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-core/dvb_net.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index f6dac2bb0ac6..6c3a8a06ccab 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -351,6 +351,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) const u8 *ts, *ts_end, *from_where = NULL; u8 ts_remain = 0, how_much = 0, new_ts = 1; struct ethhdr *ethh = NULL; + bool error = false; #ifdef ULE_DEBUG /* The code inside ULE_DEBUG keeps a history of the last 100 TS cells processed. */ @@ -460,10 +461,16 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) /* Drop partly decoded SNDU, reset state, resync on PUSI. */ if (priv->ule_skb) { - dev_kfree_skb( priv->ule_skb ); + error = true; + dev_kfree_skb(priv->ule_skb); + } + + if (error || priv->ule_sndu_remain) { dev->stats.rx_errors++; dev->stats.rx_frame_errors++; + error = false; } + reset_ule(priv); priv->need_pusi = 1; continue; @@ -535,6 +542,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) from_where += 2; } + priv->ule_sndu_remain = priv->ule_sndu_len + 2; /* * State of current TS: * ts_remain (remaining bytes in the current TS cell) @@ -544,6 +552,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) */ switch (ts_remain) { case 1: + priv->ule_sndu_remain--; priv->ule_sndu_type = from_where[0] << 8; priv->ule_sndu_type_1 = 1; /* first byte of ule_type is set. */ ts_remain -= 1; from_where += 1; @@ -557,6 +566,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) default: /* complete ULE header is present in current TS. */ /* Extract ULE type field. */ if (priv->ule_sndu_type_1) { + priv->ule_sndu_type_1 = 0; priv->ule_sndu_type |= from_where[0]; from_where += 1; /* points to payload start. */ ts_remain -= 1; -- cgit v1.2.3 From 4202066c6995200b2755a4501ea90f5d4e163e41 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 27 May 2010 09:36:45 -0300 Subject: V4L/DVB: drivers/media: Eliminate a NULL pointer dereference In each case, the print involves dereferencing a value that is NULL or is near NULL. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r exists@ expression E,E1; identifier f; statement S1,S2,S3; @@ if ((E == NULL && ...) || ...) { ... when != if (...) S1 else S2 when != E = E1 * E->f ... when any return ...; } else S3 // Signed-off-by: Julia Lawall Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/firewire/firedtv-1394.c | 2 +- drivers/media/video/hdpvr/hdpvr-video.c | 2 +- drivers/media/video/usbvision/usbvision-video.c | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c index 26333b4f4d3e..b34ca7afb0e6 100644 --- a/drivers/media/dvb/firewire/firedtv-1394.c +++ b/drivers/media/dvb/firewire/firedtv-1394.c @@ -58,7 +58,7 @@ static void rawiso_activity_cb(struct hpsb_iso *iso) num = hpsb_iso_n_ready(iso); if (!fdtv) { - dev_err(fdtv->device, "received at unknown iso channel\n"); + pr_err("received at unknown iso channel\n"); goto out; } diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c index 7cfccfd1b870..c338f3f62e77 100644 --- a/drivers/media/video/hdpvr/hdpvr-video.c +++ b/drivers/media/video/hdpvr/hdpvr-video.c @@ -366,7 +366,7 @@ static int hdpvr_open(struct file *file) dev = (struct hdpvr_device *)video_get_drvdata(video_devdata(file)); if (!dev) { - v4l2_err(&dev->v4l2_dev, "open failing with with ENODEV\n"); + pr_err("open failing with with ENODEV\n"); retval = -ENODEV; goto err; } diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 6248a639ba2d..c2690df33438 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -1671,8 +1671,7 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf) PDEBUG(DBG_PROBE, ""); if (usbvision == NULL) { - dev_err(&usbvision->dev->dev, - "%s: usb_get_intfdata() failed\n", __func__); + pr_err("%s: usb_get_intfdata() failed\n", __func__); return; } -- cgit v1.2.3 From 6afdeaf865b729287e02aafc61d8d013b89996ef Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 23 May 2010 18:53:35 -0300 Subject: V4L/DVB: cx18, cx23885, v4l2 doc, MAINTAINERS: Update Andy Walls' email address A trivial change to update my email address from my dead awalls@radix.net address to my current awalls@md.metrocast.net address. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/v4l/v4l2.xml | 2 +- MAINTAINERS | 4 ++-- drivers/media/video/cx18/cx18-alsa-main.c | 2 +- drivers/media/video/cx18/cx18-alsa-mixer.c | 2 +- drivers/media/video/cx18/cx18-alsa-mixer.h | 2 +- drivers/media/video/cx18/cx18-alsa-pcm.c | 2 +- drivers/media/video/cx18/cx18-alsa-pcm.h | 2 +- drivers/media/video/cx18/cx18-alsa.h | 2 +- drivers/media/video/cx18/cx18-av-audio.c | 2 +- drivers/media/video/cx18/cx18-av-core.c | 2 +- drivers/media/video/cx18/cx18-av-core.h | 2 +- drivers/media/video/cx18/cx18-av-firmware.c | 2 +- drivers/media/video/cx18/cx18-cards.c | 2 +- drivers/media/video/cx18/cx18-cards.h | 2 +- drivers/media/video/cx18/cx18-driver.c | 2 +- drivers/media/video/cx18/cx18-driver.h | 2 +- drivers/media/video/cx18/cx18-dvb.c | 2 +- drivers/media/video/cx18/cx18-fileops.c | 2 +- drivers/media/video/cx18/cx18-firmware.c | 2 +- drivers/media/video/cx18/cx18-gpio.c | 2 +- drivers/media/video/cx18/cx18-gpio.h | 2 +- drivers/media/video/cx18/cx18-i2c.c | 2 +- drivers/media/video/cx18/cx18-io.c | 2 +- drivers/media/video/cx18/cx18-io.h | 4 ++-- drivers/media/video/cx18/cx18-ioctl.c | 2 +- drivers/media/video/cx18/cx18-ioctl.h | 2 +- drivers/media/video/cx18/cx18-irq.c | 2 +- drivers/media/video/cx18/cx18-irq.h | 2 +- drivers/media/video/cx18/cx18-mailbox.c | 2 +- drivers/media/video/cx18/cx18-mailbox.h | 2 +- drivers/media/video/cx18/cx18-queue.c | 2 +- drivers/media/video/cx18/cx18-queue.h | 2 +- drivers/media/video/cx18/cx18-scb.c | 2 +- drivers/media/video/cx18/cx18-scb.h | 2 +- drivers/media/video/cx18/cx18-streams.c | 2 +- drivers/media/video/cx18/cx18-streams.h | 2 +- drivers/media/video/cx23885/cx23885-input.c | 2 +- drivers/media/video/cx23885/cx23885-input.h | 2 +- drivers/media/video/cx23885/cx23885-ioctl.c | 2 +- drivers/media/video/cx23885/cx23885-ioctl.h | 2 +- drivers/media/video/cx23885/cx23885-ir.c | 2 +- drivers/media/video/cx23885/cx23885-ir.h | 2 +- drivers/media/video/cx23885/cx23888-ir.c | 2 +- drivers/media/video/cx23885/cx23888-ir.h | 2 +- 44 files changed, 46 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/Documentation/DocBook/v4l/v4l2.xml b/Documentation/DocBook/v4l/v4l2.xml index 9737243377a3..7c3c098d5d08 100644 --- a/Documentation/DocBook/v4l/v4l2.xml +++ b/Documentation/DocBook/v4l/v4l2.xml @@ -58,7 +58,7 @@ MPEG stream embedded, sliced VBI data format in this specification.
- awalls@radix.net + awalls@md.metrocast.net
diff --git a/MAINTAINERS b/MAINTAINERS index 13608bd2e791..0200b63fb448 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1731,7 +1731,7 @@ S: Maintained F: sound/pci/cs5535audio/ CX18 VIDEO4LINUX DRIVER -M: Andy Walls +M: Andy Walls L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers) L: linux-media@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git @@ -3165,7 +3165,7 @@ F: Documentation/hwmon/it87 F: drivers/hwmon/it87.c IVTV VIDEO4LINUX DRIVER -M: Andy Walls +M: Andy Walls L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers) L: linux-media@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git diff --git a/drivers/media/video/cx18/cx18-alsa-main.c b/drivers/media/video/cx18/cx18-alsa-main.c index b5d7cbf4528a..d50d69da387b 100644 --- a/drivers/media/video/cx18/cx18-alsa-main.c +++ b/drivers/media/video/cx18/cx18-alsa-main.c @@ -1,7 +1,7 @@ /* * ALSA interface to cx18 PCM capture streams * - * Copyright (C) 2009 Andy Walls + * Copyright (C) 2009 Andy Walls * Copyright (C) 2009 Devin Heitmueller * * Portions of this work were sponsored by ONELAN Limited. diff --git a/drivers/media/video/cx18/cx18-alsa-mixer.c b/drivers/media/video/cx18/cx18-alsa-mixer.c index ef21114309fe..341bddc00b77 100644 --- a/drivers/media/video/cx18/cx18-alsa-mixer.c +++ b/drivers/media/video/cx18/cx18-alsa-mixer.c @@ -2,7 +2,7 @@ * ALSA mixer controls for the * ALSA interface to cx18 PCM capture streams * - * Copyright (C) 2009 Andy Walls + * Copyright (C) 2009 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-alsa-mixer.h b/drivers/media/video/cx18/cx18-alsa-mixer.h index 2d418db000fe..ec9238793f6f 100644 --- a/drivers/media/video/cx18/cx18-alsa-mixer.h +++ b/drivers/media/video/cx18/cx18-alsa-mixer.h @@ -2,7 +2,7 @@ * ALSA mixer controls for the * ALSA interface to cx18 PCM capture streams * - * Copyright (C) 2009 Andy Walls + * Copyright (C) 2009 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.c b/drivers/media/video/cx18/cx18-alsa-pcm.c index 2bd312daeb1e..8f55692db36d 100644 --- a/drivers/media/video/cx18/cx18-alsa-pcm.c +++ b/drivers/media/video/cx18/cx18-alsa-pcm.c @@ -2,7 +2,7 @@ * ALSA PCM device for the * ALSA interface to cx18 PCM capture streams * - * Copyright (C) 2009 Andy Walls + * Copyright (C) 2009 Andy Walls * Copyright (C) 2009 Devin Heitmueller * * Portions of this work were sponsored by ONELAN Limited. diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.h b/drivers/media/video/cx18/cx18-alsa-pcm.h index 325662c647a0..d26e51f94577 100644 --- a/drivers/media/video/cx18/cx18-alsa-pcm.h +++ b/drivers/media/video/cx18/cx18-alsa-pcm.h @@ -2,7 +2,7 @@ * ALSA PCM device for the * ALSA interface to cx18 PCM capture streams * - * Copyright (C) 2009 Andy Walls + * Copyright (C) 2009 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-alsa.h b/drivers/media/video/cx18/cx18-alsa.h index 88a1cde7540b..447da374c9e8 100644 --- a/drivers/media/video/cx18/cx18-alsa.h +++ b/drivers/media/video/cx18/cx18-alsa.h @@ -1,7 +1,7 @@ /* * ALSA interface to cx18 PCM capture streams * - * Copyright (C) 2009 Andy Walls + * Copyright (C) 2009 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c index 9e30983f2ff6..43d09a24b262 100644 --- a/drivers/media/video/cx18/cx18-av-audio.c +++ b/drivers/media/video/cx18/cx18-av-audio.c @@ -4,7 +4,7 @@ * Derived from cx25840-audio.c * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c index 54371f6d6b5f..a41951cab276 100644 --- a/drivers/media/video/cx18/cx18-av-core.c +++ b/drivers/media/video/cx18/cx18-av-core.c @@ -4,7 +4,7 @@ * Derived from cx25840-core.c * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h index c106967bdcc3..1956991795e3 100644 --- a/drivers/media/video/cx18/cx18-av-core.h +++ b/drivers/media/video/cx18/cx18-av-core.h @@ -4,7 +4,7 @@ * Derived from cx25840-core.h * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c index b9e8cc5d264a..280aa4d22488 100644 --- a/drivers/media/video/cx18/cx18-av-firmware.c +++ b/drivers/media/video/cx18/cx18-av-firmware.c @@ -2,7 +2,7 @@ * cx18 ADEC firmware functions * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index 74e122b5fc49..6b805afe5d20 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c @@ -4,7 +4,7 @@ * Derived from ivtv-cards.c * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h index 796e517300ac..3e750068f275 100644 --- a/drivers/media/video/cx18/cx18-cards.h +++ b/drivers/media/video/cx18/cx18-cards.h @@ -4,7 +4,7 @@ * Derived from ivtv-cards.c * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index c95a86ba33b0..df60f27337cf 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -4,7 +4,7 @@ * Derived from ivtv-driver.c * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index b9728e8eee40..9bc51a99376b 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -4,7 +4,7 @@ * Derived from ivtv-driver.h * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c index 0ae2c2e1eab5..6d19f040d70f 100644 --- a/drivers/media/video/cx18/cx18-dvb.c +++ b/drivers/media/video/cx18/cx18-dvb.c @@ -2,7 +2,7 @@ * cx18 functions for DVB support * * Copyright (c) 2008 Steven Toth - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c index e12a15020cda..9f23b90732f2 100644 --- a/drivers/media/video/cx18/cx18-fileops.c +++ b/drivers/media/video/cx18/cx18-fileops.c @@ -4,7 +4,7 @@ * Derived from ivtv-fileops.c * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c index 83cd559cc609..1b3fb502e6be 100644 --- a/drivers/media/video/cx18/cx18-firmware.c +++ b/drivers/media/video/cx18/cx18-firmware.c @@ -2,7 +2,7 @@ * cx18 firmware functions * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c index 86a204b5448e..5374aeb0cd22 100644 --- a/drivers/media/video/cx18/cx18-gpio.c +++ b/drivers/media/video/cx18/cx18-gpio.c @@ -4,7 +4,7 @@ * Derived from ivtv-gpio.c * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-gpio.h b/drivers/media/video/cx18/cx18-gpio.h index f9a5ca3566af..4aea2ef88e8d 100644 --- a/drivers/media/video/cx18/cx18-gpio.h +++ b/drivers/media/video/cx18/cx18-gpio.h @@ -4,7 +4,7 @@ * Derived from ivtv-gpio.h * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c index cfa1f289b0f5..809f7d37129c 100644 --- a/drivers/media/video/cx18/cx18-i2c.c +++ b/drivers/media/video/cx18/cx18-i2c.c @@ -4,7 +4,7 @@ * Derived from ivtv-i2c.c * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-io.c b/drivers/media/video/cx18/cx18-io.c index ec5b3d7bcc6b..49b9dbd06248 100644 --- a/drivers/media/video/cx18/cx18-io.c +++ b/drivers/media/video/cx18/cx18-io.c @@ -2,7 +2,7 @@ * cx18 driver PCI memory mapped IO access routines * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-io.h b/drivers/media/video/cx18/cx18-io.h index 2635b3a8cc96..18974d886cf7 100644 --- a/drivers/media/video/cx18/cx18-io.h +++ b/drivers/media/video/cx18/cx18-io.h @@ -2,7 +2,7 @@ * cx18 driver PCI memory mapped IO access routines * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,7 +28,7 @@ /* * Readback and retry of MMIO access for reliability: * The concept was suggested by Steve Toth . - * The implmentation is the fault of Andy Walls . + * The implmentation is the fault of Andy Walls . * * *write* functions are implied to retry the mmio unless suffixed with _noretry * *read* functions never retry the mmio (it never helps to do so) diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index b5b221c8a725..20eaf38ba959 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -4,7 +4,7 @@ * Derived from ivtv-ioctl.c * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-ioctl.h b/drivers/media/video/cx18/cx18-ioctl.h index e2ca0d152116..dcb2559ad520 100644 --- a/drivers/media/video/cx18/cx18-ioctl.h +++ b/drivers/media/video/cx18/cx18-ioctl.h @@ -4,7 +4,7 @@ * Derived from ivtv-ioctl.h * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c index af2f504eda2b..80edfe93a3d8 100644 --- a/drivers/media/video/cx18/cx18-irq.c +++ b/drivers/media/video/cx18/cx18-irq.c @@ -2,7 +2,7 @@ * cx18 interrupt handling * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-irq.h b/drivers/media/video/cx18/cx18-irq.h index 91f0b5278ef9..30e7eaf8cb55 100644 --- a/drivers/media/video/cx18/cx18-irq.h +++ b/drivers/media/video/cx18/cx18-irq.h @@ -2,7 +2,7 @@ * cx18 interrupt handling * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c index 6dcce297752f..956aa190ecca 100644 --- a/drivers/media/video/cx18/cx18-mailbox.c +++ b/drivers/media/video/cx18/cx18-mailbox.c @@ -2,7 +2,7 @@ * cx18 mailbox functions * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h index 33a3491c4537..077952fcbcca 100644 --- a/drivers/media/video/cx18/cx18-mailbox.h +++ b/drivers/media/video/cx18/cx18-mailbox.h @@ -2,7 +2,7 @@ * cx18 mailbox functions * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c index aefc8c8cf3c1..8884537bd62f 100644 --- a/drivers/media/video/cx18/cx18-queue.c +++ b/drivers/media/video/cx18/cx18-queue.c @@ -4,7 +4,7 @@ * Derived from ivtv-queue.c * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h index 88a6d34ad3bb..4201ddc16091 100644 --- a/drivers/media/video/cx18/cx18-queue.h +++ b/drivers/media/video/cx18/cx18-queue.h @@ -4,7 +4,7 @@ * Derived from ivtv-queue.h * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-scb.c b/drivers/media/video/cx18/cx18-scb.c index 34b4d03c55cd..85cc59637e54 100644 --- a/drivers/media/video/cx18/cx18-scb.c +++ b/drivers/media/video/cx18/cx18-scb.c @@ -2,7 +2,7 @@ * cx18 System Control Block initialization * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-scb.h b/drivers/media/video/cx18/cx18-scb.h index 368f23d08709..08877652e321 100644 --- a/drivers/media/video/cx18/cx18-scb.h +++ b/drivers/media/video/cx18/cx18-scb.h @@ -2,7 +2,7 @@ * cx18 System Control Block initialization * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index f5c91261b2db..9045f1ece0eb 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c @@ -4,7 +4,7 @@ * Derived from ivtv-streams.c * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h index 0bff0fa29763..77412bee5963 100644 --- a/drivers/media/video/cx18/cx18-streams.h +++ b/drivers/media/video/cx18/cx18-streams.h @@ -4,7 +4,7 @@ * Derived from ivtv-streams.h * * Copyright (C) 2007 Hans Verkuil - * Copyright (C) 2008 Andy Walls + * Copyright (C) 2008 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c index 8d306d8bb61c..5de6ba98f7a8 100644 --- a/drivers/media/video/cx23885/cx23885-input.c +++ b/drivers/media/video/cx23885/cx23885-input.c @@ -5,7 +5,7 @@ * * Most of this file is * - * Copyright (C) 2009 Andy Walls + * Copyright (C) 2009 Andy Walls * * However, the cx23885_input_{init,fini} functions contained herein are * derived from Linux kernel files linux/media/video/.../...-input.c marked as: diff --git a/drivers/media/video/cx23885/cx23885-input.h b/drivers/media/video/cx23885/cx23885-input.h index 3572cb1ecfc2..75ef15d3f523 100644 --- a/drivers/media/video/cx23885/cx23885-input.h +++ b/drivers/media/video/cx23885/cx23885-input.h @@ -3,7 +3,7 @@ * * Infrared remote control input device * - * Copyright (C) 2009 Andy Walls + * Copyright (C) 2009 Andy Walls * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/drivers/media/video/cx23885/cx23885-ioctl.c b/drivers/media/video/cx23885/cx23885-ioctl.c index dfb4627fb340..44812ca78899 100644 --- a/drivers/media/video/cx23885/cx23885-ioctl.c +++ b/drivers/media/video/cx23885/cx23885-ioctl.c @@ -3,7 +3,7 @@ * * Various common ioctl() support functions * - * Copyright (c) 2009 Andy Walls + * Copyright (c) 2009 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx23885/cx23885-ioctl.h b/drivers/media/video/cx23885/cx23885-ioctl.h index 80b0f4923c6a..315be0ca5a04 100644 --- a/drivers/media/video/cx23885/cx23885-ioctl.h +++ b/drivers/media/video/cx23885/cx23885-ioctl.h @@ -3,7 +3,7 @@ * * Various common ioctl() support functions * - * Copyright (c) 2009 Andy Walls + * Copyright (c) 2009 Andy Walls * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/media/video/cx23885/cx23885-ir.c b/drivers/media/video/cx23885/cx23885-ir.c index 6ae982cc9856..9a677eb080af 100644 --- a/drivers/media/video/cx23885/cx23885-ir.c +++ b/drivers/media/video/cx23885/cx23885-ir.c @@ -3,7 +3,7 @@ * * Infrared device support routines - non-input, non-vl42_subdev routines * - * Copyright (C) 2009 Andy Walls + * Copyright (C) 2009 Andy Walls * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/drivers/media/video/cx23885/cx23885-ir.h b/drivers/media/video/cx23885/cx23885-ir.h index 9b8a6d5d1ef6..0c9d8bda9e28 100644 --- a/drivers/media/video/cx23885/cx23885-ir.h +++ b/drivers/media/video/cx23885/cx23885-ir.h @@ -3,7 +3,7 @@ * * Infrared device support routines - non-input, non-vl42_subdev routines * - * Copyright (C) 2009 Andy Walls + * Copyright (C) 2009 Andy Walls * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c index ad728d767d69..f63d378257a7 100644 --- a/drivers/media/video/cx23885/cx23888-ir.c +++ b/drivers/media/video/cx23885/cx23888-ir.c @@ -3,7 +3,7 @@ * * CX23888 Integrated Consumer Infrared Controller * - * Copyright (C) 2009 Andy Walls + * Copyright (C) 2009 Andy Walls * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/drivers/media/video/cx23885/cx23888-ir.h b/drivers/media/video/cx23885/cx23888-ir.h index 3d446f9eb94b..d2de41caaf1d 100644 --- a/drivers/media/video/cx23885/cx23888-ir.h +++ b/drivers/media/video/cx23885/cx23888-ir.h @@ -3,7 +3,7 @@ * * CX23888 Integrated Consumer Infrared Controller * - * Copyright (C) 2009 Andy Walls + * Copyright (C) 2009 Andy Walls * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License -- cgit v1.2.3 From 064a2485aa45956cf1e8520e716839e9d7555b90 Mon Sep 17 00:00:00 2001 From: Ian Armstrong Date: Sun, 23 May 2010 21:56:33 -0300 Subject: V4L/DVB: cx2341x: Report correct temporal setting for log-status [Andy Walls comment:] This patch from Ian removes the cx2341x module lying about the setting of the temporal filter for the log status ioctl(). Signed-off-by: Ian Armstrong Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx2341x.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c index 022b480918cd..2bf44ef10fec 100644 --- a/drivers/media/video/cx2341x.c +++ b/drivers/media/video/cx2341x.c @@ -1113,7 +1113,6 @@ invalid: void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix) { int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1; - int temporal = p->video_temporal_filter; /* Stream */ printk(KERN_INFO "%s: Stream: %s", @@ -1179,14 +1178,11 @@ void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix) V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE), p->video_spatial_filter); - if (p->width != 720 || p->height != (p->is_50hz ? 576 : 480)) - temporal = 0; - printk(KERN_INFO "%s: Temporal Filter: %s, %d\n", prefix, cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE), - temporal); + p->video_temporal_filter); printk(KERN_INFO "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n", prefix, -- cgit v1.2.3 From 5f39b9f660778c3b095fc380da178d58a040add5 Mon Sep 17 00:00:00 2001 From: Ian Armstrong Date: Sun, 23 May 2010 22:10:30 -0300 Subject: V4L/DVB: ivtvfb : Module load / unload fixes Check firmware state when loading module & if firmware is not responding exit with an error. When module is unloaded, only disable the framebuffer & not all decoder output. Signed-off-by: Ian Armstrong Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtvfb.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index 49e1a283ed36..9ff3425891ed 100644 --- a/drivers/media/video/ivtv/ivtvfb.c +++ b/drivers/media/video/ivtv/ivtvfb.c @@ -1066,7 +1066,11 @@ static int ivtvfb_init_io(struct ivtv *itv) } mutex_unlock(&itv->serialize_lock); - ivtvfb_get_framebuffer(itv, &oi->video_rbase, &oi->video_buffer_size); + if (ivtvfb_get_framebuffer(itv, &oi->video_rbase, + &oi->video_buffer_size) < 0) { + IVTVFB_ERR("Firmware failed to respond\n"); + return -EIO; + } /* The osd buffer size depends on the number of video buffers allocated on the PVR350 itself. For now we'll hardcode the smallest osd buffer @@ -1158,8 +1162,11 @@ static int ivtvfb_init_card(struct ivtv *itv) } /* Find & setup the OSD buffer */ - if ((rc = ivtvfb_init_io(itv))) + rc = ivtvfb_init_io(itv); + if (rc) { + ivtvfb_release_buffers(itv); return rc; + } /* Set the startup video mode information */ if ((rc = ivtvfb_init_vidmode(itv))) { @@ -1210,6 +1217,7 @@ static int ivtvfb_callback_cleanup(struct device *dev, void *p) { struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev); + struct osd_info *oi = itv->osd_info; if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) { @@ -1218,7 +1226,7 @@ static int ivtvfb_callback_cleanup(struct device *dev, void *p) return 0; } IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance); - ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info); + ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info); ivtvfb_release_buffers(itv); itv->osd_video_pbase = 0; } -- cgit v1.2.3 From bd62307b20ff864c48541e46c3ee2bb9cc330f64 Mon Sep 17 00:00:00 2001 From: Ian Armstrong Date: Sun, 23 May 2010 22:19:11 -0300 Subject: V4L/DVB: ivtv: Avoid accidental video standard change For yuv video output, pass fake values to avoid firmware trying to change video standard. Signed-off-by: Ian Armstrong Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-streams.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index de4288cc1889..5441dc205966 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c @@ -618,12 +618,17 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) struct ivtv *itv = s->itv; struct cx2341x_mpeg_params *p = &itv->params; int datatype; + u16 width; + u16 height; if (s->vdev == NULL) return -EINVAL; IVTV_DEBUG_INFO("Setting some initial decoder settings\n"); + width = p->width; + height = p->height; + /* set audio mode to left/stereo for dual/stereo mode. */ ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); @@ -646,7 +651,14 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) 2 = yuv_from_host */ switch (s->type) { case IVTV_DEC_STREAM_TYPE_YUV: - datatype = itv->output_mode == OUT_PASSTHROUGH ? 1 : 2; + if (itv->output_mode == OUT_PASSTHROUGH) { + datatype = 1; + } else { + /* Fake size to avoid switching video standard */ + datatype = 2; + width = 720; + height = itv->is_out_50hz ? 576 : 480; + } IVTV_DEBUG_INFO("Setup DEC YUV Stream data[0] = %d\n", datatype); break; case IVTV_DEC_STREAM_TYPE_MPG: @@ -655,7 +667,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) break; } if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype, - p->width, p->height, p->audio_properties)) { + width, height, p->audio_properties)) { IVTV_DEBUG_WARN("Couldn't initialize decoder source\n"); } return 0; -- cgit v1.2.3 From 666092c679f7d9eb9f5230087f960a487fda721c Mon Sep 17 00:00:00 2001 From: Ian Armstrong Date: Sun, 23 May 2010 22:27:49 -0300 Subject: V4L/DVB: ivtv: Timing tweaks and code re-order to try and improve stability Added small delay on device open & close to allow hardware to settle. Move yuv register restore to before the decoder firmware call to stop playback. Signed-off-by: Ian Armstrong Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-fileops.c | 11 +++++++---- drivers/media/video/ivtv/ivtv-streams.c | 7 +++++++ 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index abf410943cc9..3c2cc270ccd5 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c @@ -823,6 +823,12 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts) IVTV_DEBUG_FILE("close() of %s\n", s->name); + if (id->type == IVTV_DEC_STREAM_TYPE_YUV && + test_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags)) { + /* Restore registers we've changed & clean up any mess */ + ivtv_yuv_close(itv); + } + /* Stop decoding */ if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { IVTV_DEBUG_INFO("close stopping decode\n"); @@ -832,10 +838,7 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts) } clear_bit(IVTV_F_S_APPL_IO, &s->s_flags); clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags); - if (id->type == IVTV_DEC_STREAM_TYPE_YUV && test_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags)) { - /* Restore registers we've changed & clean up any mess we've made */ - ivtv_yuv_close(itv); - } + if (itv->output_mode == OUT_UDMA_YUV && id->yuv_frames) itv->output_mode = OUT_NONE; diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index 5441dc205966..9ecacab4b89b 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c @@ -670,6 +670,10 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) width, height, p->audio_properties)) { IVTV_DEBUG_WARN("Couldn't initialize decoder source\n"); } + + /* Decoder sometimes dies here, so wait a moment */ + ivtv_msleep_timeout(10, 0); + return 0; } @@ -709,6 +713,9 @@ int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset) /* start playback */ ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, gop_offset, 0); + /* Let things settle before we actually start */ + ivtv_msleep_timeout(10, 0); + /* Clear the following Interrupt mask bits for decoding */ ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_DECODE); IVTV_DEBUG_IRQ("IRQ Mask is now: 0x%08x\n", itv->irqmask); -- cgit v1.2.3 From f07ff97b012ff9485618faeadcc9b1e5f72ceefa Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 1 Jun 2010 07:42:03 +0200 Subject: usb/gadget: Replace the old USB audio FU definitions in f_audio.c The USB audio FU definitions were renewed by the commit 65f25da44b51f55e3a74301c25f29263be2bf1ba ALSA: usb-audio: unify constants from specification Signed-off-by: Takashi Iwai --- drivers/usb/gadget/f_audio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c index 43bf44514c41..b91115f84b13 100644 --- a/drivers/usb/gadget/f_audio.c +++ b/drivers/usb/gadget/f_audio.c @@ -101,7 +101,7 @@ static struct uac_feature_unit_descriptor_0 feature_unit_desc = { static struct usb_audio_control mute_control = { .list = LIST_HEAD_INIT(mute_control.list), .name = "Mute Control", - .type = UAC_MUTE_CONTROL, + .type = UAC_FU_MUTE, /* Todo: add real Mute control code */ .set = generic_set_cmd, .get = generic_get_cmd, @@ -110,7 +110,7 @@ static struct usb_audio_control mute_control = { static struct usb_audio_control volume_control = { .list = LIST_HEAD_INIT(volume_control.list), .name = "Volume Control", - .type = UAC_VOLUME_CONTROL, + .type = UAC_FU_VOLUME, /* Todo: add real Volume control code */ .set = generic_set_cmd, .get = generic_get_cmd, -- cgit v1.2.3 From 6bd17eb96ffc9c3b52927913d59da9ced5109c6a Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Mon, 31 May 2010 08:56:03 +0000 Subject: can: mpc5xxx_can.c: Fix build failure Fixes build error caused by the OF device_node pointer being moved into struct device. Signed-off-by: Anatolij Gustschin Cc: Wolfgang Grandegger Cc: Grant Likely Signed-off-by: David S. Miller --- drivers/net/can/mscan/mpc5xxx_can.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c index 8af8442c694a..af753936e835 100644 --- a/drivers/net/can/mscan/mpc5xxx_can.c +++ b/drivers/net/can/mscan/mpc5xxx_can.c @@ -73,7 +73,7 @@ static u32 __devinit mpc52xx_can_get_clock(struct of_device *ofdev, else *mscan_clksrc = MSCAN_CLKSRC_XTAL; - freq = mpc5xxx_get_bus_frequency(ofdev->node); + freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node); if (!freq) return 0; @@ -152,7 +152,7 @@ static u32 __devinit mpc512x_can_get_clock(struct of_device *ofdev, } /* Determine the MSCAN device index from the physical address */ - pval = of_get_property(ofdev->node, "reg", &plen); + pval = of_get_property(ofdev->dev.of_node, "reg", &plen); BUG_ON(!pval || plen < sizeof(*pval)); clockidx = (*pval & 0x80) ? 1 : 0; if (*pval & 0x2000) @@ -168,11 +168,11 @@ static u32 __devinit mpc512x_can_get_clock(struct of_device *ofdev, */ if (clock_name && !strcmp(clock_name, "ip")) { *mscan_clksrc = MSCAN_CLKSRC_IPS; - freq = mpc5xxx_get_bus_frequency(ofdev->node); + freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node); } else { *mscan_clksrc = MSCAN_CLKSRC_BUS; - pval = of_get_property(ofdev->node, + pval = of_get_property(ofdev->dev.of_node, "fsl,mscan-clock-divider", &plen); if (pval && plen == sizeof(*pval)) clockdiv = *pval; @@ -251,7 +251,7 @@ static int __devinit mpc5xxx_can_probe(struct of_device *ofdev, const struct of_device_id *id) { struct mpc5xxx_can_data *data = (struct mpc5xxx_can_data *)id->data; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct net_device *dev; struct mscan_priv *priv; void __iomem *base; -- cgit v1.2.3 From 3ffd05159815d477f971a3259fc758f0c3c7e640 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Tue, 1 Jun 2010 00:19:33 -0700 Subject: be2net: convert hdr.timeout in be_cmd_loopback_test() to le32 The current code fails on ppc as hdr.timeout is not being converted to le32. Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/benet/be_cmds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 9e305d7fb4bd..b9ad799c719f 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -1593,7 +1593,7 @@ int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL, OPCODE_LOWLEVEL_LOOPBACK_TEST, sizeof(*req)); - req->hdr.timeout = 4; + req->hdr.timeout = cpu_to_le32(4); req->pattern = cpu_to_le64(pattern); req->src_port = cpu_to_le32(port_num); -- cgit v1.2.3 From aa989f5e46bb913e1a5966bb7d32eb2d00c1894e Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 31 May 2010 01:10:01 +0000 Subject: virtio-net: pass gfp to add_buf virtio-net bounces buffer allocations off to a thread if it can't allocate buffers from the atomic pool. However, if posting buffers still requires atomic buffers, this is unlikely to succeed. Fix by passing in the proper gfp_t parameter. Signed-off-by: Michael S. Tsirkin Signed-off-by: Rusty Russell Signed-off-by: David S. Miller --- drivers/net/virtio_net.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 78eb3190b9b1..1edb7a61983c 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -340,7 +340,7 @@ static int add_recvbuf_small(struct virtnet_info *vi, gfp_t gfp) skb_to_sgvec(skb, vi->rx_sg + 1, 0, skb->len); - err = virtqueue_add_buf(vi->rvq, vi->rx_sg, 0, 2, skb); + err = virtqueue_add_buf_gfp(vi->rvq, vi->rx_sg, 0, 2, skb, gfp); if (err < 0) dev_kfree_skb(skb); @@ -385,8 +385,8 @@ static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp) /* chain first in list head */ first->private = (unsigned long)list; - err = virtqueue_add_buf(vi->rvq, vi->rx_sg, 0, MAX_SKB_FRAGS + 2, - first); + err = virtqueue_add_buf_gfp(vi->rvq, vi->rx_sg, 0, MAX_SKB_FRAGS + 2, + first, gfp); if (err < 0) give_pages(vi, first); @@ -404,7 +404,7 @@ static int add_recvbuf_mergeable(struct virtnet_info *vi, gfp_t gfp) sg_init_one(vi->rx_sg, page_address(page), PAGE_SIZE); - err = virtqueue_add_buf(vi->rvq, vi->rx_sg, 0, 1, page); + err = virtqueue_add_buf_gfp(vi->rvq, vi->rx_sg, 0, 1, page, gfp); if (err < 0) give_pages(vi, page); -- cgit v1.2.3 From 5ed83663f77ee7404022d046321f69545cd311b8 Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Mon, 31 May 2010 00:24:49 +0000 Subject: ksz884x: convert to netdev_tx_t Convert TX hook to netdev_tx_t type Signed-off-by: Denis Kirjanov Signed-off-by: David S. Miller --- drivers/net/ksz884x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c index c80ca64277b2..4568b6f163eb 100644 --- a/drivers/net/ksz884x.c +++ b/drivers/net/ksz884x.c @@ -4854,7 +4854,7 @@ static inline void copy_old_skb(struct sk_buff *old, struct sk_buff *skb) * * Return 0 if successful; otherwise an error code indicating failure. */ -static int netdev_tx(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev) { struct dev_priv *priv = netdev_priv(dev); struct dev_info *hw_priv = priv->adapter; -- cgit v1.2.3 From 96ed741e15896eea43f7203523db88bc8105c359 Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Mon, 31 May 2010 00:26:21 +0000 Subject: ksz884x: Add missing validate_addr hook Add missing validate_addr hook Signed-off-by: Denis Kirjanov Signed-off-by: David S. Miller --- drivers/net/ksz884x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c index 4568b6f163eb..7805bbf1d53a 100644 --- a/drivers/net/ksz884x.c +++ b/drivers/net/ksz884x.c @@ -6863,6 +6863,7 @@ static const struct net_device_ops netdev_ops = { .ndo_tx_timeout = netdev_tx_timeout, .ndo_change_mtu = netdev_change_mtu, .ndo_set_mac_address = netdev_set_mac_address, + .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = netdev_ioctl, .ndo_set_rx_mode = netdev_set_rx_mode, #ifdef CONFIG_NET_POLL_CONTROLLER -- cgit v1.2.3 From b42d9165e1e3d92e4e3318642463dbe592a12568 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 1 Jun 2010 00:26:06 -0700 Subject: drivers/isdn/hardware/mISDN: Use GFP_ATOMIC when a lock is held The function inittiger is only called from nj_init_card, where a lock is held. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @gfp exists@ identifier fn; position p; @@ fn(...) { ... when != spin_unlock_irqrestore when any GFP_KERNEL@p ... when any } @locked@ identifier gfp.fn; @@ spin_lock_irqsave(...) ... when != spin_unlock_irqrestore fn(...) @depends on locked@ position gfp.p; @@ - GFP_KERNEL@p + GFP_ATOMIC // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/isdn/hardware/mISDN/netjet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c index 0a3553df065f..54ae71a907f9 100644 --- a/drivers/isdn/hardware/mISDN/netjet.c +++ b/drivers/isdn/hardware/mISDN/netjet.c @@ -320,12 +320,12 @@ inittiger(struct tiger_hw *card) return -ENOMEM; } for (i = 0; i < 2; i++) { - card->bc[i].hsbuf = kmalloc(NJ_DMA_TXSIZE, GFP_KERNEL); + card->bc[i].hsbuf = kmalloc(NJ_DMA_TXSIZE, GFP_ATOMIC); if (!card->bc[i].hsbuf) { pr_info("%s: no B%d send buffer\n", card->name, i + 1); return -ENOMEM; } - card->bc[i].hrbuf = kmalloc(NJ_DMA_RXSIZE, GFP_KERNEL); + card->bc[i].hrbuf = kmalloc(NJ_DMA_RXSIZE, GFP_ATOMIC); if (!card->bc[i].hrbuf) { pr_info("%s: no B%d recv buffer\n", card->name, i + 1); return -ENOMEM; -- cgit v1.2.3 From b7c335713ea130d707c22d7f7c57a8eca75ded7e Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Wed, 26 May 2010 15:41:14 +0200 Subject: brd: support discard Support discard requests in brd by zeroing or deleting the underlying backing pages. This is simply to help with testing and documentation nature of brd code. Signed-off-by: Nick Piggin Signed-off-by: Jens Axboe --- drivers/block/brd.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/brd.c b/drivers/block/brd.c index 6081e81d5738..f1bf79d9bc0a 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -133,6 +133,28 @@ static struct page *brd_insert_page(struct brd_device *brd, sector_t sector) return page; } +static void brd_free_page(struct brd_device *brd, sector_t sector) +{ + struct page *page; + pgoff_t idx; + + spin_lock(&brd->brd_lock); + idx = sector >> PAGE_SECTORS_SHIFT; + page = radix_tree_delete(&brd->brd_pages, idx); + spin_unlock(&brd->brd_lock); + if (page) + __free_page(page); +} + +static void brd_zero_page(struct brd_device *brd, sector_t sector) +{ + struct page *page; + + page = brd_lookup_page(brd, sector); + if (page) + clear_highpage(page); +} + /* * Free all backing store pages and radix tree. This must only be called when * there are no other users of the device. @@ -189,6 +211,24 @@ static int copy_to_brd_setup(struct brd_device *brd, sector_t sector, size_t n) return 0; } +static void discard_from_brd(struct brd_device *brd, + sector_t sector, size_t n) +{ + while (n >= PAGE_SIZE) { + /* + * Don't want to actually discard pages here because + * re-allocating the pages can result in writeback + * deadlocks under heavy load. + */ + if (0) + brd_free_page(brd, sector); + else + brd_zero_page(brd, sector); + sector += PAGE_SIZE >> SECTOR_SHIFT; + n -= PAGE_SIZE; + } +} + /* * Copy n bytes from src to the brd starting at sector. Does not sleep. */ @@ -300,6 +340,12 @@ static int brd_make_request(struct request_queue *q, struct bio *bio) get_capacity(bdev->bd_disk)) goto out; + if (unlikely(bio_rw_flagged(bio, BIO_RW_DISCARD))) { + err = 0; + discard_from_brd(brd, sector, bio->bi_size); + goto out; + } + rw = bio_rw(bio); if (rw == READA) rw = READ; @@ -320,7 +366,7 @@ out: } #ifdef CONFIG_BLK_DEV_XIP -static int brd_direct_access (struct block_device *bdev, sector_t sector, +static int brd_direct_access(struct block_device *bdev, sector_t sector, void **kaddr, unsigned long *pfn) { struct brd_device *brd = bdev->bd_disk->private_data; @@ -437,6 +483,11 @@ static struct brd_device *brd_alloc(int i) blk_queue_max_hw_sectors(brd->brd_queue, 1024); blk_queue_bounce_limit(brd->brd_queue, BLK_BOUNCE_ANY); + brd->brd_queue->limits.discard_granularity = PAGE_SIZE; + brd->brd_queue->limits.max_discard_sectors = UINT_MAX; + brd->brd_queue->limits.discard_zeroes_data = 1; + queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, brd->brd_queue); + disk = brd->brd_disk = alloc_disk(1 << part_shift); if (!disk) goto out_free_queue; -- cgit v1.2.3 From 2c8d196759054b632788633b20e39167df36041d Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Tue, 25 May 2010 14:32:03 +0200 Subject: drbd: Revert "drbd: Create new current UUID as late as possible" The late-UUID writing is delayed until the next release. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_int.h | 9 +-------- drivers/block/drbd/drbd_main.c | 34 ++++++---------------------------- drivers/block/drbd/drbd_receiver.c | 11 ----------- 3 files changed, 7 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index e9654c8d5b62..c194348a46ed 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -943,8 +943,7 @@ struct drbd_conf { struct drbd_work resync_work, unplug_work, md_sync_work, - delay_probe_work, - uuid_work; + delay_probe_work; struct timer_list resync_timer; struct timer_list md_sync_timer; struct timer_list delay_probe_timer; @@ -1069,7 +1068,6 @@ struct drbd_conf { struct timeval dps_time; /* delay-probes-start-time */ unsigned int dp_volume_last; /* send_cnt of last delay probe */ int c_sync_rate; /* current resync rate after delay_probe magic */ - atomic_t new_c_uuid; }; static inline struct drbd_conf *minor_to_mdev(unsigned int minor) @@ -2219,8 +2217,6 @@ static inline int __inc_ap_bio_cond(struct drbd_conf *mdev) return 0; if (test_bit(BITMAP_IO, &mdev->flags)) return 0; - if (atomic_read(&mdev->new_c_uuid)) - return 0; return 1; } @@ -2241,9 +2237,6 @@ static inline void inc_ap_bio(struct drbd_conf *mdev, int count) * to avoid races with the reconnect code, * we need to atomic_inc within the spinlock. */ - if (atomic_read(&mdev->new_c_uuid) && atomic_add_unless(&mdev->new_c_uuid, -1, 1)) - drbd_queue_work_front(&mdev->data.work, &mdev->uuid_work); - spin_lock_irq(&mdev->req_lock); while (!__inc_ap_bio_cond(mdev)) { prepare_to_wait(&mdev->misc_wait, &wait, TASK_UNINTERRUPTIBLE); diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index be2d2da9cdba..1fcf2d1bcc39 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -1215,18 +1215,17 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, ns.pdsk == D_OUTDATED)) { if (get_ldev(mdev)) { if ((ns.role == R_PRIMARY || ns.peer == R_PRIMARY) && - mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE && - !atomic_read(&mdev->new_c_uuid)) - atomic_set(&mdev->new_c_uuid, 2); + mdev->ldev->md.uuid[UI_BITMAP] == 0 && ns.disk >= D_UP_TO_DATE) { + drbd_uuid_new_current(mdev); + drbd_send_uuids(mdev); + } put_ldev(mdev); } } if (ns.pdsk < D_INCONSISTENT && get_ldev(mdev)) { - /* Diskless peer becomes primary or got connected do diskless, primary peer. */ - if (ns.peer == R_PRIMARY && mdev->ldev->md.uuid[UI_BITMAP] == 0 && - !atomic_read(&mdev->new_c_uuid)) - atomic_set(&mdev->new_c_uuid, 2); + if (ns.peer == R_PRIMARY && mdev->ldev->md.uuid[UI_BITMAP] == 0) + drbd_uuid_new_current(mdev); /* D_DISKLESS Peer becomes secondary */ if (os.peer == R_PRIMARY && ns.peer == R_SECONDARY) @@ -1350,24 +1349,6 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, drbd_md_sync(mdev); } -static int w_new_current_uuid(struct drbd_conf *mdev, struct drbd_work *w, int cancel) -{ - if (get_ldev(mdev)) { - if (mdev->ldev->md.uuid[UI_BITMAP] == 0) { - drbd_uuid_new_current(mdev); - if (get_net_conf(mdev)) { - drbd_send_uuids(mdev); - put_net_conf(mdev); - } - drbd_md_sync(mdev); - } - put_ldev(mdev); - } - atomic_dec(&mdev->new_c_uuid); - wake_up(&mdev->misc_wait); - - return 1; -} static int drbd_thread_setup(void *arg) { @@ -2708,7 +2689,6 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) atomic_set(&mdev->net_cnt, 0); atomic_set(&mdev->packet_seq, 0); atomic_set(&mdev->pp_in_use, 0); - atomic_set(&mdev->new_c_uuid, 0); mutex_init(&mdev->md_io_mutex); mutex_init(&mdev->data.mutex); @@ -2739,14 +2719,12 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) INIT_LIST_HEAD(&mdev->bm_io_work.w.list); INIT_LIST_HEAD(&mdev->delay_probes); INIT_LIST_HEAD(&mdev->delay_probe_work.list); - INIT_LIST_HEAD(&mdev->uuid_work.list); mdev->resync_work.cb = w_resync_inactive; mdev->unplug_work.cb = w_send_write_hint; mdev->md_sync_work.cb = w_md_sync; mdev->bm_io_work.w.cb = w_bitmap_io; mdev->delay_probe_work.cb = w_delay_probes; - mdev->uuid_work.cb = w_new_current_uuid; init_timer(&mdev->resync_timer); init_timer(&mdev->md_sync_timer); init_timer(&mdev->delay_probe_timer); diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index bc9ab7fb2cc7..a56340dd5710 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -1154,17 +1154,6 @@ int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, unsigned n_bios = 0; unsigned nr_pages = (ds + PAGE_SIZE -1) >> PAGE_SHIFT; - if (atomic_read(&mdev->new_c_uuid)) { - if (atomic_add_unless(&mdev->new_c_uuid, -1, 1)) { - drbd_uuid_new_current(mdev); - drbd_md_sync(mdev); - - atomic_dec(&mdev->new_c_uuid); - wake_up(&mdev->misc_wait); - } - wait_event(mdev->misc_wait, !atomic_read(&mdev->new_c_uuid)); - } - /* In most cases, we will only need one bio. But in case the lower * level restrictions happen to be different at this offset on this * side than those of the sending peer, we may need to submit the -- cgit v1.2.3 From 344fa462e3246bd102059ccc3c59deef416676dd Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Tue, 25 May 2010 14:23:57 +0200 Subject: drbd: improve network latency, TCP_QUICKACK On Thu, Apr 29, 2010 at 04:00:50PM -0400, Eduard.Guzovsky@stratus.com wrote on drbd-dev@lists.linbit.com Subject: [Drbd-dev] DRBD small synchronous writes performance improvements > 1. TCP_QUICKACK option is set incorrectly. The goal was force TCP to > send and ACK as a "one time" event. Instead the code permanently sets > connection in the QUICKACK mode. He is right, we actually want to use an even val with TCP_QUICKACK. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_int.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index c194348a46ed..6d79a76ba597 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1540,7 +1540,7 @@ static inline void drbd_tcp_nodelay(struct socket *sock) static inline void drbd_tcp_quickack(struct socket *sock) { - int __user val = 1; + int __user val = 2; (void) drbd_setsockopt(sock, SOL_TCP, TCP_QUICKACK, (char __user *)&val, sizeof(val)); } -- cgit v1.2.3 From 5dbf1673383f2f1554f0634fdfc390d59dc2c7d6 Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Tue, 25 May 2010 16:18:01 +0200 Subject: drbd: need to set socket bufsize early to take effect quoting tcp(7): On individual connections, the socket buffer size must be set prior to the listen(2) or connect(2) calls in order to have it take effect. This adds a wrapper to do so, and uses it appropriately. Improves performance in certain situations. Note that because we cannot easily determine which socket will be "meta" and wich "data" (bulk) socket, we adjust both sockets. Previously, DRBD only adjusted the bufsizes of the "data" socket. Thanks again to Eduard.Guzovsky@stratus.com. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_receiver.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index a56340dd5710..f9a3e199e715 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -571,6 +571,25 @@ static int drbd_recv(struct drbd_conf *mdev, void *buf, size_t size) return rv; } +/* quoting tcp(7): + * On individual connections, the socket buffer size must be set prior to the + * listen(2) or connect(2) calls in order to have it take effect. + * This is our wrapper to do so. + */ +static void drbd_setbufsize(struct socket *sock, unsigned int snd, + unsigned int rcv) +{ + /* open coded SO_SNDBUF, SO_RCVBUF */ + if (snd) { + sock->sk->sk_sndbuf = snd; + sock->sk->sk_userlocks |= SOCK_SNDBUF_LOCK; + } + if (rcv) { + sock->sk->sk_rcvbuf = rcv; + sock->sk->sk_userlocks |= SOCK_RCVBUF_LOCK; + } +} + static struct socket *drbd_try_connect(struct drbd_conf *mdev) { const char *what; @@ -592,6 +611,8 @@ static struct socket *drbd_try_connect(struct drbd_conf *mdev) sock->sk->sk_rcvtimeo = sock->sk->sk_sndtimeo = mdev->net_conf->try_connect_int*HZ; + drbd_setbufsize(sock, mdev->net_conf->sndbuf_size, + mdev->net_conf->rcvbuf_size); /* explicitly bind to the configured IP as source IP * for the outgoing connections. @@ -670,6 +691,8 @@ static struct socket *drbd_wait_for_connect(struct drbd_conf *mdev) s_listen->sk->sk_reuse = 1; /* SO_REUSEADDR */ s_listen->sk->sk_rcvtimeo = timeo; s_listen->sk->sk_sndtimeo = timeo; + drbd_setbufsize(s_listen, mdev->net_conf->sndbuf_size, + mdev->net_conf->rcvbuf_size); what = "bind before listen"; err = s_listen->ops->bind(s_listen, @@ -856,16 +879,6 @@ retry: sock->sk->sk_priority = TC_PRIO_INTERACTIVE_BULK; msock->sk->sk_priority = TC_PRIO_INTERACTIVE; - if (mdev->net_conf->sndbuf_size) { - sock->sk->sk_sndbuf = mdev->net_conf->sndbuf_size; - sock->sk->sk_userlocks |= SOCK_SNDBUF_LOCK; - } - - if (mdev->net_conf->rcvbuf_size) { - sock->sk->sk_rcvbuf = mdev->net_conf->rcvbuf_size; - sock->sk->sk_userlocks |= SOCK_RCVBUF_LOCK; - } - /* NOT YET ... * sock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10; * sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT; -- cgit v1.2.3 From ba11ad9a3b9dd2dbb9c6686ea9d41a9a77d94327 Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Tue, 25 May 2010 16:26:16 +0200 Subject: drbd: improve usage of MSG_MORE It seems to improve performance if we allow the "p_data" header in its own frame (no MSG_MORE), but sendpage all but the last page with MSG_MORE. This is also in preparation of a later zero copy receive implementation. Suggested by Eduard.Guzovsky@stratus.com on drbd-dev. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_main.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 1fcf2d1bcc39..c978557b4b80 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2272,9 +2272,9 @@ static int we_should_drop_the_connection(struct drbd_conf *mdev, struct socket * * with page_count == 0 or PageSlab. */ static int _drbd_no_send_page(struct drbd_conf *mdev, struct page *page, - int offset, size_t size) + int offset, size_t size, unsigned msg_flags) { - int sent = drbd_send(mdev, mdev->data.socket, kmap(page) + offset, size, 0); + int sent = drbd_send(mdev, mdev->data.socket, kmap(page) + offset, size, msg_flags); kunmap(page); if (sent == size) mdev->send_cnt += size>>9; @@ -2282,7 +2282,7 @@ static int _drbd_no_send_page(struct drbd_conf *mdev, struct page *page, } static int _drbd_send_page(struct drbd_conf *mdev, struct page *page, - int offset, size_t size) + int offset, size_t size, unsigned msg_flags) { mm_segment_t oldfs = get_fs(); int sent, ok; @@ -2295,14 +2295,15 @@ static int _drbd_send_page(struct drbd_conf *mdev, struct page *page, * __page_cache_release a page that would actually still be referenced * by someone, leading to some obscure delayed Oops somewhere else. */ if (disable_sendpage || (page_count(page) < 1) || PageSlab(page)) - return _drbd_no_send_page(mdev, page, offset, size); + return _drbd_no_send_page(mdev, page, offset, size, msg_flags); + msg_flags |= MSG_NOSIGNAL; drbd_update_congested(mdev); set_fs(KERNEL_DS); do { sent = mdev->data.socket->ops->sendpage(mdev->data.socket, page, offset, len, - MSG_NOSIGNAL); + msg_flags); if (sent == -EAGAIN) { if (we_should_drop_the_connection(mdev, mdev->data.socket)) @@ -2331,9 +2332,11 @@ static int _drbd_send_bio(struct drbd_conf *mdev, struct bio *bio) { struct bio_vec *bvec; int i; + /* hint all but last page with MSG_MORE */ __bio_for_each_segment(bvec, bio, i, 0) { if (!_drbd_no_send_page(mdev, bvec->bv_page, - bvec->bv_offset, bvec->bv_len)) + bvec->bv_offset, bvec->bv_len, + i == bio->bi_vcnt -1 ? 0 : MSG_MORE)) return 0; } return 1; @@ -2343,12 +2346,13 @@ static int _drbd_send_zc_bio(struct drbd_conf *mdev, struct bio *bio) { struct bio_vec *bvec; int i; + /* hint all but last page with MSG_MORE */ __bio_for_each_segment(bvec, bio, i, 0) { if (!_drbd_send_page(mdev, bvec->bv_page, - bvec->bv_offset, bvec->bv_len)) + bvec->bv_offset, bvec->bv_len, + i == bio->bi_vcnt -1 ? 0 : MSG_MORE)) return 0; } - return 1; } @@ -2356,9 +2360,11 @@ static int _drbd_send_zc_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e) { struct page *page = e->pages; unsigned len = e->size; + /* hint all but last page with MSG_MORE */ page_chain_for_each(page) { unsigned l = min_t(unsigned, len, PAGE_SIZE); - if (!_drbd_send_page(mdev, page, 0, l)) + if (!_drbd_send_page(mdev, page, 0, l, + page_chain_next(page) ? MSG_MORE : 0)) return 0; len -= l; } @@ -2438,11 +2444,11 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req) p.dp_flags = cpu_to_be32(dp_flags); set_bit(UNPLUG_REMOTE, &mdev->flags); ok = (sizeof(p) == - drbd_send(mdev, mdev->data.socket, &p, sizeof(p), MSG_MORE)); + drbd_send(mdev, mdev->data.socket, &p, sizeof(p), dgs ? MSG_MORE : 0)); if (ok && dgs) { dgb = mdev->int_dig_out; drbd_csum_bio(mdev, mdev->integrity_w_tfm, req->master_bio, dgb); - ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, MSG_MORE); + ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, 0); } if (ok) { if (mdev->net_conf->wire_protocol == DRBD_PROT_A) @@ -2491,11 +2497,11 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd, return 0; ok = sizeof(p) == drbd_send(mdev, mdev->data.socket, &p, - sizeof(p), MSG_MORE); + sizeof(p), dgs ? MSG_MORE : 0); if (ok && dgs) { dgb = mdev->int_dig_out; drbd_csum_ee(mdev, mdev->integrity_w_tfm, e, dgb); - ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, MSG_MORE); + ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, 0); } if (ok) ok = _drbd_send_zc_ee(mdev, e); -- cgit v1.2.3 From 039e1fb65496636778e24c881a5e58ed7c39fbb3 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Sun, 23 May 2010 21:48:13 +0200 Subject: drbd: removed duplicated #includes drbd/drbd_receiver.c: linux/mm.h is included more than once. Signed-off-by: Andrea Gelmini Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_receiver.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index f9a3e199e715..dff48701b84d 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include "drbd_int.h" -- cgit v1.2.3 From 32fa7e91f923d8b2578c42016ff3a94efc9968a2 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Wed, 26 May 2010 17:13:18 +0200 Subject: drbd: Removed the now empty w_io_error() function Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_int.h | 1 - drivers/block/drbd/drbd_req.c | 27 +-------------------------- drivers/block/drbd/drbd_worker.c | 14 -------------- 3 files changed, 1 insertion(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 6d79a76ba597..86605f6d0854 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1474,7 +1474,6 @@ extern int w_e_end_ov_req(struct drbd_conf *, struct drbd_work *, int); extern int w_ov_finished(struct drbd_conf *, struct drbd_work *, int); extern int w_resync_inactive(struct drbd_conf *, struct drbd_work *, int); extern int w_resume_next_sg(struct drbd_conf *, struct drbd_work *, int); -extern int w_io_error(struct drbd_conf *, struct drbd_work *, int); extern int w_send_write_hint(struct drbd_conf *, struct drbd_work *, int); extern int w_make_resync_request(struct drbd_conf *, struct drbd_work *, int); extern int w_send_dblock(struct drbd_conf *, struct drbd_work *, int); diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 3397f11d0ba9..e6c4d579eaba 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -102,32 +102,7 @@ static void _req_is_done(struct drbd_conf *mdev, struct drbd_request *req, const } } - /* if it was a local io error, we want to notify our - * peer about that, and see if we need to - * detach the disk and stuff. - * to avoid allocating some special work - * struct, reuse the request. */ - - /* THINK - * why do we do this not when we detect the error, - * but delay it until it is "done", i.e. possibly - * until the next barrier ack? */ - - if (rw == WRITE && - ((s & RQ_LOCAL_MASK) && !(s & RQ_LOCAL_OK))) { - if (!(req->w.list.next == LIST_POISON1 || - list_empty(&req->w.list))) { - /* DEBUG ASSERT only; if this triggers, we - * probably corrupt the worker list here */ - dev_err(DEV, "req->w.list.next = %p\n", req->w.list.next); - dev_err(DEV, "req->w.list.prev = %p\n", req->w.list.prev); - } - req->w.cb = w_io_error; - drbd_queue_work(&mdev->data.work, &req->w); - /* drbd_req_free() is done in w_io_error */ - } else { - drbd_req_free(req); - } + drbd_req_free(req); } static void queue_barrier(struct drbd_conf *mdev) diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 727ff6339754..a12b447bafbd 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -257,20 +257,6 @@ void drbd_endio_pri(struct bio *bio, int error) complete_master_bio(mdev, &m); } -int w_io_error(struct drbd_conf *mdev, struct drbd_work *w, int cancel) -{ - struct drbd_request *req = container_of(w, struct drbd_request, w); - - /* NOTE: mdev->ldev can be NULL by the time we get here! */ - /* D_ASSERT(mdev->ldev->dc.on_io_error != EP_PASS_ON); */ - - /* the only way this callback is scheduled is from _req_may_be_done, - * when it is done and had a local write error, see comments there */ - drbd_req_free(req); - - return TRUE; -} - int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel) { struct drbd_request *req = container_of(w, struct drbd_request, w); -- cgit v1.2.3 From d255e5ff5fc6cc6c60dd014d1261448a7bbc8134 Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Thu, 27 May 2010 09:45:45 +0200 Subject: drbd: fix hang on local read errors while disconnected "canceled" w_read_retry_remote never completed, if they have been canceled after drbd_disconnect connection teardown cleanup has already run (or we are currently not connected anyways). Fixed by not queueing a remote retry if we already know it won't work (pdsk not uptodate), and cleanup ourselves on "cancel", in case we hit a race with drbd_disconnect. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_req.c | 22 +++++++++++++--------- drivers/block/drbd/drbd_req.h | 1 + drivers/block/drbd/drbd_worker.c | 6 ++---- 3 files changed, 16 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index e6c4d579eaba..8915644af722 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -452,20 +452,21 @@ void __req_mod(struct drbd_request *req, enum drbd_req_event what, dev_alert(DEV, "Local READ failed sec=%llus size=%u\n", (unsigned long long)req->sector, req->size); - /* _req_mod(req,to_be_send); oops, recursion... */ D_ASSERT(!(req->rq_state & RQ_NET_MASK)); - req->rq_state |= RQ_NET_PENDING; - inc_ap_pending(mdev); __drbd_chk_io_error(mdev, FALSE); put_ldev(mdev); - /* NOTE: if we have no connection, - * or know the peer has no good data either, - * then we don't actually need to "queue_for_net_read", - * but we do so anyways, since the drbd_io_error() - * and the potential state change to "Diskless" - * needs to be done from process context */ + /* no point in retrying if there is no good remote data, + * or we have no connection. */ + if (mdev->state.pdsk != D_UP_TO_DATE) { + _req_may_be_done(req, m); + break; + } + + /* _req_mod(req,to_be_send); oops, recursion... */ + req->rq_state |= RQ_NET_PENDING; + inc_ap_pending(mdev); /* fall through: _req_mod(req,queue_for_net_read); */ case queue_for_net_read: @@ -575,6 +576,9 @@ void __req_mod(struct drbd_request *req, enum drbd_req_event what, _req_may_be_done(req, m); break; + case read_retry_remote_canceled: + req->rq_state &= ~RQ_NET_QUEUED; + /* fall through, in case we raced with drbd_disconnect */ case connection_lost_while_pending: /* transfer log cleanup after connection loss */ /* assert something? */ diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h index 16119d7056cc..02d575d24518 100644 --- a/drivers/block/drbd/drbd_req.h +++ b/drivers/block/drbd/drbd_req.h @@ -91,6 +91,7 @@ enum drbd_req_event { send_failed, handed_over_to_network, connection_lost_while_pending, + read_retry_remote_canceled, recv_acked_by_peer, write_acked_by_peer, write_acked_by_peer_and_sis, /* and set_in_sync */ diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index a12b447bafbd..67371fcbc5aa 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -266,10 +266,8 @@ int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel) * to give the disk the chance to relocate that block */ spin_lock_irq(&mdev->req_lock); - if (cancel || - mdev->state.conn < C_CONNECTED || - mdev->state.pdsk <= D_INCONSISTENT) { - _req_mod(req, send_canceled); + if (cancel || mdev->state.pdsk != D_UP_TO_DATE) { + _req_mod(req, read_retry_remote_canceled); spin_unlock_irq(&mdev->req_lock); dev_alert(DEV, "WE ARE LOST. Local IO failure, no peer.\n"); return 1; -- cgit v1.2.3 From 7383506c87237dbd627f0b8b72b50117f25c5ca2 Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Thu, 27 May 2010 11:51:56 +0200 Subject: drbd: use drbd specific ratelimit instead of global printk_ratelimit using the global printk_ratelimit() may mask other messages. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_int.h | 2 +- drivers/block/drbd/drbd_main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 86605f6d0854..485ed8c7d623 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1725,7 +1725,7 @@ static inline void __drbd_chk_io_error_(struct drbd_conf *mdev, int forcedetach, switch (mdev->ldev->dc.on_io_error) { case EP_PASS_ON: if (!forcedetach) { - if (printk_ratelimit()) + if (__ratelimit(&drbd_ratelimit_state)) dev_err(DEV, "Local IO failed in %s." "Passing error on...\n", where); break; diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index c978557b4b80..6b077f93acc6 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -3783,7 +3783,7 @@ _drbd_insert_fault(struct drbd_conf *mdev, unsigned int type) if (ret) { fault_count++; - if (printk_ratelimit()) + if (__ratelimit(&drbd_ratelimit_state)) dev_warn(DEV, "***Simulating %s failure\n", _drbd_fault_str(type)); } -- cgit v1.2.3 From 2a0ab2cd73c26835e635ed4e3868f983519048fb Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Wed, 26 May 2010 17:59:55 +0200 Subject: drbd: Reduce verbosity The "Local READ/WRITE failed" messages are too verbose. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe --- drivers/block/drbd/drbd_req.c | 5 ----- drivers/block/drbd/drbd_worker.c | 4 ---- 2 files changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 8915644af722..654f1ef5cbb0 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -428,9 +428,6 @@ void __req_mod(struct drbd_request *req, enum drbd_req_event what, req->rq_state |= RQ_LOCAL_COMPLETED; req->rq_state &= ~RQ_LOCAL_PENDING; - dev_alert(DEV, "Local WRITE failed sec=%llus size=%u\n", - (unsigned long long)req->sector, req->size); - /* and now: check how to handle local io error. */ __drbd_chk_io_error(mdev, FALSE); _req_may_be_done(req, m); put_ldev(mdev); @@ -450,8 +447,6 @@ void __req_mod(struct drbd_request *req, enum drbd_req_event what, req->rq_state |= RQ_LOCAL_COMPLETED; req->rq_state &= ~RQ_LOCAL_PENDING; - dev_alert(DEV, "Local READ failed sec=%llus size=%u\n", - (unsigned long long)req->sector, req->size); D_ASSERT(!(req->rq_state & RQ_NET_MASK)); __drbd_chk_io_error(mdev, FALSE); diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 67371fcbc5aa..b623ceee2a4a 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -224,9 +224,6 @@ void drbd_endio_pri(struct bio *bio, int error) enum drbd_req_event what; int uptodate = bio_flagged(bio, BIO_UPTODATE); - if (error) - dev_warn(DEV, "p %s: error=%d\n", - bio_data_dir(bio) == WRITE ? "write" : "read", error); if (!error && !uptodate) { dev_warn(DEV, "p %s: setting error to -EIO\n", bio_data_dir(bio) == WRITE ? "write" : "read"); @@ -269,7 +266,6 @@ int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel) if (cancel || mdev->state.pdsk != D_UP_TO_DATE) { _req_mod(req, read_retry_remote_canceled); spin_unlock_irq(&mdev->req_lock); - dev_alert(DEV, "WE ARE LOST. Local IO failure, no peer.\n"); return 1; } spin_unlock_irq(&mdev->req_lock); -- cgit v1.2.3 From 713b686494a577b3c4f4f9f585a4705fc30d51c2 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 1 Jun 2010 12:17:48 +0200 Subject: cciss: call BUG() earlier I moved the range check after the increment. The current code would write past the end of the array once before calling BUG(). Signed-off-by: Dan Carpenter Signed-off-by: Jens Axboe --- drivers/block/cciss_scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index e1d0e2cfec72..3381505c8a6c 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -188,11 +188,11 @@ scsi_cmd_free(ctlr_info_t *h, CommandList_struct *cmd) sa = h->scsi_ctlr; stk = &sa->cmd_stack; + stk->top++; if (stk->top >= CMD_STACK_SIZE) { printk("cciss: scsi_cmd_free called too many times.\n"); BUG(); } - stk->top++; stk->elem[stk->top] = (struct cciss_scsi_cmd_stack_elem_t *) cmd; } -- cgit v1.2.3 From 2e8949f09e3097c629f33323eaf280cf5c88c81a Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 1 Jun 2010 12:51:00 +0100 Subject: intel_scu_ipc: Length fix Commands with data must set the length in the message. Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/platform/x86/intel_scu_ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c index 576c3ed92435..40658e3385b4 100644 --- a/drivers/platform/x86/intel_scu_ipc.c +++ b/drivers/platform/x86/intel_scu_ipc.c @@ -524,7 +524,7 @@ int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen, for (i = 0; i < inlen; i++) ipc_data_writel(*in++, 4 * i); - ipc_command(cmd << 12 | sub); + ipc_command((cmd << 12) | sub | (inlen << 18)); err = busy_loop(); for (i = 0; i < outlen; i++) -- cgit v1.2.3 From e29df91e67428c1a651d18df6ec047fcb30282d3 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 28 May 2010 12:33:15 +0200 Subject: SFI: do not return freed pointer We never actually use the return value of sfi_sysfs_install_table() but it still seems wrong to return a freed pointer. Signed-off-by: Dan Carpenter Signed-off-by: Len Brown --- drivers/sfi/sfi_core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/sfi/sfi_core.c b/drivers/sfi/sfi_core.c index 005195958647..ceba593dc84f 100644 --- a/drivers/sfi/sfi_core.c +++ b/drivers/sfi/sfi_core.c @@ -441,8 +441,10 @@ struct sfi_table_attr __init *sfi_sysfs_install_table(u64 pa) ret = sysfs_create_bin_file(tables_kobj, &tbl_attr->attr); - if (ret) + if (ret) { kfree(tbl_attr); + tbl_attr = NULL; + } sfi_unmap_table(th); return tbl_attr; -- cgit v1.2.3 From 9bc354998f8aa8a83b0cd430e8fcf2cbc3be7367 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 28 May 2010 17:17:37 -0400 Subject: drm/i915: Honor sync polarity from VBT panel timing descriptors I'm actually kind of shocked that it works at all otherwise. Signed-off-by: Adam Jackson Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_bios.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 4c748d8f73d6..96f75d7f6633 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -95,6 +95,16 @@ fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, panel_fixed_mode->clock = dvo_timing->clock * 10; panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED; + if (dvo_timing->hsync_positive) + panel_fixed_mode->flags |= DRM_MODE_FLAG_PHSYNC; + else + panel_fixed_mode->flags |= DRM_MODE_FLAG_NHSYNC; + + if (dvo_timing->vsync_positive) + panel_fixed_mode->flags |= DRM_MODE_FLAG_PVSYNC; + else + panel_fixed_mode->flags |= DRM_MODE_FLAG_NVSYNC; + /* Some VBTs have bogus h/vtotal values */ if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; -- cgit v1.2.3 From e3a815fcd38043b8f1bb526123d8ab6ae01deb77 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Mon, 31 May 2010 13:58:47 +0800 Subject: drm/i915: add HAS_BSD check to i915_getparam This will let userland only try to use the new media decode functionality when the appropriate kernel is present. Signed-off-by: Zou Nan hai Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_dma.c | 3 +++ include/drm/i915_drm.h | 1 + 2 files changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 6577798d3441..84ce95602f00 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -744,6 +744,9 @@ static int i915_getparam(struct drm_device *dev, void *data, /* depends on GEM */ value = dev_priv->has_gem; break; + case I915_PARAM_HAS_BSD: + value = HAS_BSD(dev); + break; default: DRM_DEBUG_DRIVER("Unknown parameter %d\n", param->param); diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index e9168704cabe..7f0028e1010b 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -275,6 +275,7 @@ typedef struct drm_i915_irq_wait { #define I915_PARAM_HAS_OVERLAY 7 #define I915_PARAM_HAS_PAGEFLIPPING 8 #define I915_PARAM_HAS_EXECBUF2 9 +#define I915_PARAM_HAS_BSD 10 typedef struct drm_i915_getparam { int param; -- cgit v1.2.3 From 397f385bdba6cdf7752467a7ae81810340929e44 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 19 May 2010 10:30:49 +0900 Subject: ath5k: wake queues on reset We can wake all queues after a chip reset since everything should be set up and we are ready to transmit. If we don't do that we might end up starting up with stopped queues, not beeing able to transmit. (This started to happen after "ath5k: clean up queue manipulation" but since periodic calibration also stopped and started the queues this effect was hidden most of the time). This way we can also get rid of the superfluous ath5k_reset_wake() function. Signed-off-by: Bruno Randolf Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index cc6d41dec332..2978359c4366 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -222,7 +222,6 @@ static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb); static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, struct ath5k_txq *txq); static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan); -static int ath5k_reset_wake(struct ath5k_softc *sc); static int ath5k_start(struct ieee80211_hw *hw); static void ath5k_stop(struct ieee80211_hw *hw); static int ath5k_add_interface(struct ieee80211_hw *hw, @@ -2770,7 +2769,7 @@ ath5k_tasklet_reset(unsigned long data) { struct ath5k_softc *sc = (void *)data; - ath5k_reset_wake(sc); + ath5k_reset(sc, sc->curchan); } /* @@ -2941,23 +2940,13 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) ath5k_beacon_config(sc); /* intrs are enabled by ath5k_beacon_config */ + ieee80211_wake_queues(sc->hw); + return 0; err: return ret; } -static int -ath5k_reset_wake(struct ath5k_softc *sc) -{ - int ret; - - ret = ath5k_reset(sc, sc->curchan); - if (!ret) - ieee80211_wake_queues(sc->hw); - - return ret; -} - static int ath5k_start(struct ieee80211_hw *hw) { return ath5k_init(hw->priv); -- cgit v1.2.3 From f7a2e30246281944064113dafbafe3eb14cd89e3 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 1 Jun 2010 21:29:40 -0700 Subject: Input: tps6507x-ts - a couple work queue cleanups 1) Use msecs_to_jiffies() instead of calculating by hand. 2) Call cancel_delayed_work_sync() instead of cancel_delayed_work() followed by a separate flush_workqueue(). 3) Remove the "tsc->wq = 0;" Sparse complains about that because tsc->wq is a pointer, not an int. It's not needed because we just free the pointer anyway. Signed-off-by: Dan Carpenter Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/tps6507x-ts.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c index 5de80a1a730b..5b70a1419b4d 100644 --- a/drivers/input/touchscreen/tps6507x-ts.c +++ b/drivers/input/touchscreen/tps6507x-ts.c @@ -221,7 +221,7 @@ done: if (poll) { schd = queue_delayed_work(tsc->wq, &tsc->work, - tsc->poll_period * HZ / 1000); + msecs_to_jiffies(tsc->poll_period)); if (schd) tsc->polling = 1; else { @@ -326,7 +326,7 @@ static int tps6507x_ts_probe(struct platform_device *pdev) goto err2; schd = queue_delayed_work(tsc->wq, &tsc->work, - tsc->poll_period * HZ / 1000); + msecs_to_jiffies(tsc->poll_period)); if (schd) tsc->polling = 1; @@ -339,10 +339,8 @@ static int tps6507x_ts_probe(struct platform_device *pdev) return 0; err2: - cancel_delayed_work(&tsc->work); - flush_workqueue(tsc->wq); + cancel_delayed_work_sync(&tsc->work); destroy_workqueue(tsc->wq); - tsc->wq = 0; input_free_device(input_dev); err1: kfree(tsc); @@ -360,10 +358,8 @@ static int __devexit tps6507x_ts_remove(struct platform_device *pdev) if (!tsc) return 0; - cancel_delayed_work(&tsc->work); - flush_workqueue(tsc->wq); + cancel_delayed_work_sync(&tsc->work); destroy_workqueue(tsc->wq); - tsc->wq = 0; input_free_device(input_dev); -- cgit v1.2.3 From abb24f4846d1537d73605e8576de8359a98e5ced Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 2 Jun 2010 16:26:13 +0900 Subject: usb: gadget: m66592-udc pio to mmio accessor conversion. m66592-udc is erroneously using PIO routines on MMIO registers, which presently blows up for any platform that elects to either override or do away with PIO routines. This managed to work for the common cases since the PIO routines were simply wrapped to their MMIO counterparts. This switches over to using the MMIO routines directly, and enables us to kill off a lot of superfluous casting in the process. Acked-by: Yoshihiro Shimoda Signed-off-by: Paul Mundt --- drivers/usb/gadget/m66592-udc.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/m66592-udc.h b/drivers/usb/gadget/m66592-udc.h index 8b960deed680..c3caf1ac73ce 100644 --- a/drivers/usb/gadget/m66592-udc.h +++ b/drivers/usb/gadget/m66592-udc.h @@ -537,35 +537,35 @@ struct m66592 { /*-------------------------------------------------------------------------*/ static inline u16 m66592_read(struct m66592 *m66592, unsigned long offset) { - return inw((unsigned long)m66592->reg + offset); + return ioread16(m66592->reg + offset); } static inline void m66592_read_fifo(struct m66592 *m66592, unsigned long offset, void *buf, unsigned long len) { - unsigned long fifoaddr = (unsigned long)m66592->reg + offset; + void __iomem *fifoaddr = m66592->reg + offset; if (m66592->pdata->on_chip) { len = (len + 3) / 4; - insl(fifoaddr, buf, len); + ioread32_rep(fifoaddr, buf, len); } else { len = (len + 1) / 2; - insw(fifoaddr, buf, len); + ioread16_rep(fifoaddr, buf, len); } } static inline void m66592_write(struct m66592 *m66592, u16 val, unsigned long offset) { - outw(val, (unsigned long)m66592->reg + offset); + iowrite16(val, m66592->reg + offset); } static inline void m66592_write_fifo(struct m66592 *m66592, unsigned long offset, void *buf, unsigned long len) { - unsigned long fifoaddr = (unsigned long)m66592->reg + offset; + void __iomem *fifoaddr = m66592->reg + offset; if (m66592->pdata->on_chip) { unsigned long count; @@ -573,25 +573,25 @@ static inline void m66592_write_fifo(struct m66592 *m66592, int i; count = len / 4; - outsl(fifoaddr, buf, count); + iowrite32_rep(fifoaddr, buf, count); if (len & 0x00000003) { pb = buf + count * 4; for (i = 0; i < (len & 0x00000003); i++) { if (m66592_read(m66592, M66592_CFBCFG)) /* le */ - outb(pb[i], fifoaddr + (3 - i)); + iowrite8(pb[i], fifoaddr + (3 - i)); else - outb(pb[i], fifoaddr + i); + iowrite8(pb[i], fifoaddr + i); } } } else { unsigned long odd = len & 0x0001; len = len / 2; - outsw(fifoaddr, buf, len); + iowrite16_rep(fifoaddr, buf, len); if (odd) { unsigned char *p = buf + len*2; - outb(*p, fifoaddr); + iowrite8(*p, fifoaddr); } } } -- cgit v1.2.3 From e8b48669de54d390644c77cd26d5c9fccbc1e0a1 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 2 Jun 2010 16:27:12 +0900 Subject: usb: gadget: r8a66597-udc pio to mmio accessor conversion. r8a66597-udc is erroneously using PIO routines on MMIO registers, which presently blows up for any platform that elects to either override or do away with PIO routines. This managed to work for the common cases since the PIO routines were simply wrapped to their MMIO counterparts. This switches over to using the MMIO routines directly, and enables us to kill off a lot of superfluous casting in the process. Acked-by: Yoshihiro Shimoda Signed-off-by: Paul Mundt --- drivers/usb/gadget/r8a66597-udc.c | 4 ++-- drivers/usb/gadget/r8a66597-udc.h | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 888d8f166c0b..70a817842755 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c @@ -1500,7 +1500,7 @@ static int __exit r8a66597_remove(struct platform_device *pdev) struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev); del_timer_sync(&r8a66597->timer); - iounmap((void *)r8a66597->reg); + iounmap(r8a66597->reg); free_irq(platform_get_irq(pdev, 0), r8a66597); r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req); #ifdef CONFIG_HAVE_CLK @@ -1578,7 +1578,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) init_timer(&r8a66597->timer); r8a66597->timer.function = r8a66597_timer; r8a66597->timer.data = (unsigned long)r8a66597; - r8a66597->reg = (unsigned long)reg; + r8a66597->reg = reg; #ifdef CONFIG_HAVE_CLK if (r8a66597->pdata->on_chip) { diff --git a/drivers/usb/gadget/r8a66597-udc.h b/drivers/usb/gadget/r8a66597-udc.h index 9a537aa07968..f763b5190afa 100644 --- a/drivers/usb/gadget/r8a66597-udc.h +++ b/drivers/usb/gadget/r8a66597-udc.h @@ -91,7 +91,7 @@ struct r8a66597_ep { struct r8a66597 { spinlock_t lock; - unsigned long reg; + void __iomem *reg; #ifdef CONFIG_HAVE_CLK struct clk *clk; @@ -127,7 +127,7 @@ struct r8a66597 { static inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset) { - return inw(r8a66597->reg + offset); + return ioread16(r8a66597->reg + offset); } static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597, @@ -135,7 +135,7 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597, unsigned char *buf, int len) { - unsigned long fifoaddr = r8a66597->reg + offset; + void __iomem *fifoaddr = r8a66597->reg + offset; unsigned int data; int i; @@ -144,7 +144,7 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597, /* aligned buf case */ if (len >= 4 && !((unsigned long)buf & 0x03)) { - insl(fifoaddr, buf, len / 4); + ioread32_rep(fifoaddr, buf, len / 4); buf += len & ~0x03; len &= 0x03; } @@ -152,7 +152,7 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597, /* unaligned buf case */ for (i = 0; i < len; i++) { if (!(i & 0x03)) - data = inl(fifoaddr); + data = ioread32(fifoaddr); buf[i] = (data >> ((i & 0x03) * 8)) & 0xff; } @@ -161,7 +161,7 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597, /* aligned buf case */ if (len >= 2 && !((unsigned long)buf & 0x01)) { - insw(fifoaddr, buf, len / 2); + ioread16_rep(fifoaddr, buf, len / 2); buf += len & ~0x01; len &= 0x01; } @@ -169,7 +169,7 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597, /* unaligned buf case */ for (i = 0; i < len; i++) { if (!(i & 0x01)) - data = inw(fifoaddr); + data = ioread16(fifoaddr); buf[i] = (data >> ((i & 0x01) * 8)) & 0xff; } @@ -179,7 +179,7 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597, static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val, unsigned long offset) { - outw(val, r8a66597->reg + offset); + iowrite16(val, r8a66597->reg + offset); } static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, @@ -187,21 +187,21 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, unsigned char *buf, int len) { - unsigned long fifoaddr = r8a66597->reg + offset; + void __iomem *fifoaddr = r8a66597->reg + offset; int adj = 0; int i; if (r8a66597->pdata->on_chip) { /* 32-bit access only if buf is 32-bit aligned */ if (len >= 4 && !((unsigned long)buf & 0x03)) { - outsl(fifoaddr, buf, len / 4); + iowrite32_rep(fifoaddr, buf, len / 4); buf += len & ~0x03; len &= 0x03; } } else { /* 16-bit access only if buf is 16-bit aligned */ if (len >= 2 && !((unsigned long)buf & 0x01)) { - outsw(fifoaddr, buf, len / 2); + iowrite16_rep(fifoaddr, buf, len / 2); buf += len & ~0x01; len &= 0x01; } @@ -216,7 +216,7 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, } for (i = 0; i < len; i++) - outb(buf[i], fifoaddr + adj - (i & adj)); + iowrite8(buf[i], fifoaddr + adj - (i & adj)); } static inline void r8a66597_mdfy(struct r8a66597 *r8a66597, -- cgit v1.2.3 From 1c98347e613bf17ea2f18c9766ce0ab77f65a96d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 2 Jun 2010 16:27:54 +0900 Subject: usb: r8a66597-hcd pio to mmio accessor conversion. r8a66597-hcd is erroneously using PIO routines on MMIO registers, which presently blows up for any platform that elects to either override or do away with PIO routines. This managed to work for the common cases since the PIO routines were simply wrapped to their MMIO counterparts. This switches over to using the MMIO routines directly, and enables us to kill off a lot of superfluous casting in the process. Acked-by: Yoshihiro Shimoda Signed-off-by: Paul Mundt --- drivers/usb/host/r8a66597-hcd.c | 4 ++-- drivers/usb/host/r8a66597.h | 26 +++++++++++++------------- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 6db57ab6079d..1a2bb4ce638f 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -2404,7 +2404,7 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev) del_timer_sync(&r8a66597->rh_timer); usb_remove_hcd(hcd); - iounmap((void *)r8a66597->reg); + iounmap(r8a66597->reg); #ifdef CONFIG_HAVE_CLK if (r8a66597->pdata->on_chip) clk_put(r8a66597->clk); @@ -2496,7 +2496,7 @@ static int __devinit r8a66597_probe(struct platform_device *pdev) init_timer(&r8a66597->rh_timer); r8a66597->rh_timer.function = r8a66597_timer; r8a66597->rh_timer.data = (unsigned long)r8a66597; - r8a66597->reg = (unsigned long)reg; + r8a66597->reg = reg; /* make sure no interrupts are pending */ ret = r8a66597_clock_enable(r8a66597); diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h index 228e3fb23854..95d0f5adfdcf 100644 --- a/drivers/usb/host/r8a66597.h +++ b/drivers/usb/host/r8a66597.h @@ -112,7 +112,7 @@ struct r8a66597_root_hub { struct r8a66597 { spinlock_t lock; - unsigned long reg; + void __iomem *reg; #ifdef CONFIG_HAVE_CLK struct clk *clk; #endif @@ -170,67 +170,67 @@ static inline struct urb *r8a66597_get_urb(struct r8a66597 *r8a66597, static inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset) { - return inw(r8a66597->reg + offset); + return ioread16(r8a66597->reg + offset); } static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597, unsigned long offset, u16 *buf, int len) { - unsigned long fifoaddr = r8a66597->reg + offset; + void __iomem *fifoaddr = r8a66597->reg + offset; unsigned long count; if (r8a66597->pdata->on_chip) { count = len / 4; - insl(fifoaddr, buf, count); + ioread32_rep(fifoaddr, buf, count); if (len & 0x00000003) { - unsigned long tmp = inl(fifoaddr); + unsigned long tmp = ioread32(fifoaddr); memcpy((unsigned char *)buf + count * 4, &tmp, len & 0x03); } } else { len = (len + 1) / 2; - insw(fifoaddr, buf, len); + ioread16_rep(fifoaddr, buf, len); } } static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val, unsigned long offset) { - outw(val, r8a66597->reg + offset); + iowrite16(val, r8a66597->reg + offset); } static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, unsigned long offset, u16 *buf, int len) { - unsigned long fifoaddr = r8a66597->reg + offset; + void __iomem *fifoaddr = r8a66597->reg + offset; unsigned long count; unsigned char *pb; int i; if (r8a66597->pdata->on_chip) { count = len / 4; - outsl(fifoaddr, buf, count); + iowrite32_rep(fifoaddr, buf, count); if (len & 0x00000003) { pb = (unsigned char *)buf + count * 4; for (i = 0; i < (len & 0x00000003); i++) { if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND) - outb(pb[i], fifoaddr + i); + iowrite8(pb[i], fifoaddr + i); else - outb(pb[i], fifoaddr + 3 - i); + iowrite8(pb[i], fifoaddr + 3 - i); } } } else { int odd = len & 0x0001; len = len / 2; - outsw(fifoaddr, buf, len); + ioread16_rep(fifoaddr, buf, len); if (unlikely(odd)) { buf = &buf[len]; - outb((unsigned char)*buf, fifoaddr); + iowrite8((unsigned char)*buf, fifoaddr); } } } -- cgit v1.2.3 From 56960b3602be6fde9f09c7958fa06b26384307cc Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 2 Jun 2010 00:40:06 -0700 Subject: Input: ads7846 - fix compiler warning in ads7846_probe() This patch fixes the follwing warning introduced by commit 067fb2f648543894ce775082c5636f4c32b99e4f ("Input: ads7846 - return error on regulator_get() failure"): drivers/input/touchscreen/ads7846.c: In function 'ads7846_probe': drivers/input/touchscreen/ads7846.c:1167: warning: format '%ld' expects type 'long int', but argument 4 has type 'int' Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ads7846.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 634f6f6b9b13..a9fdf55c0238 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -1164,7 +1164,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) ts->reg = regulator_get(&spi->dev, "vcc"); if (IS_ERR(ts->reg)) { err = PTR_ERR(ts->reg); - dev_err(&spi->dev, "unable to get regulator: %ld\n", err); + dev_err(&spi->dev, "unable to get regulator: %d\n", err); goto err_free_gpio; } -- cgit v1.2.3 From 83aea945c21c646184a494a32ad5524248b60226 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Tue, 1 Jun 2010 05:58:40 +0000 Subject: powerpc/macio: Don't dereference pointer before null check Signed-off-by: Andreas Schwab Signed-off-by: Benjamin Herrenschmidt --- drivers/macintosh/macio_asic.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 97147804a49c..40390ac01309 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -492,8 +492,8 @@ static void macio_pci_add_devices(struct macio_chip *chip) } /* Add media bay devices if any */ - pnode = mbdev->ofdev.dev.of_node; - if (mbdev) + if (mbdev) { + pnode = mbdev->ofdev.dev.of_node; for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) { if (macio_skip_device(np)) continue; @@ -502,10 +502,11 @@ static void macio_pci_add_devices(struct macio_chip *chip) mbdev, root_res) == NULL) of_node_put(np); } + } /* Add serial ports if any */ - pnode = sdev->ofdev.dev.of_node; if (sdev) { + pnode = sdev->ofdev.dev.of_node; for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) { if (macio_skip_device(np)) continue; -- cgit v1.2.3 From 79905ad50bcf025deb81382413719ed600734941 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 1 Jun 2010 19:33:08 +0000 Subject: agp/uninorth: Fix oops caused by flushing too much This fixes a sporadic oops at boot on G5 Power Macs. The table_end variable has the address of the last byte of the table. Adding on PAGE_SIZE means we flush too much, and if the page after the table is not mapped for any reason, the kernel will oops. Instead we add on 1 because flush_dcache_range() interprets its second argument as the first byte past the range to be flushed. Signed-off-by: Paul Mackerras Signed-off-by: Benjamin Herrenschmidt --- drivers/char/agp/uninorth-agp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index 95db71360d24..f845a8f718b3 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c @@ -415,7 +415,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge) bridge->gatt_table_real = (u32 *) table; /* Need to clear out any dirty data still sitting in caches */ flush_dcache_range((unsigned long)table, - (unsigned long)(table_end + PAGE_SIZE)); + (unsigned long)table_end + 1); bridge->gatt_table = vmap(pages, (1 << page_order), 0, PAGE_KERNEL_NCG); if (bridge->gatt_table == NULL) -- cgit v1.2.3 From c2cdf6aba0dfcfb54be646ab630c1bccd180e890 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 2 Jun 2010 17:09:18 +1000 Subject: powerpc/macio: Fix probing of macio devices by using the right of match table Grant patches added an of mach table to struct device_driver. However, while he changed the macio device code to use that, he left the match table pointer in struct macio_driver and didn't update drivers to use the "new" one, thus breaking the probing. This completes the change by moving all drivers to setup the "new" one, removing all traces of the old one, and while at it (since it changes the exact same locations), I also remove two other duplicates from struct driver which are the name and owner fields. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/macio.h | 4 ---- drivers/ata/pata_macio.c | 10 +++++----- drivers/block/swim3.c | 6 ++++-- drivers/ide/pmac.c | 7 +++++-- drivers/macintosh/macio_asic.c | 1 - drivers/macintosh/mediabay.c | 6 ++++-- drivers/macintosh/rack-meter.c | 8 +++++--- drivers/net/bmac.c | 7 +++++-- drivers/net/mace.c | 7 +++++-- drivers/net/wireless/orinoco/airport.c | 7 +++++-- drivers/scsi/mac53c94.c | 7 +++++-- drivers/scsi/mesh.c | 7 +++++-- drivers/serial/pmac_zilog.c | 7 +++++-- sound/aoa/soundbus/i2sbus/core.c | 8 +++++--- 14 files changed, 58 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/arch/powerpc/include/asm/macio.h b/arch/powerpc/include/asm/macio.h index 19a661b4cb98..675e159b5ef4 100644 --- a/arch/powerpc/include/asm/macio.h +++ b/arch/powerpc/include/asm/macio.h @@ -123,10 +123,6 @@ static inline struct pci_dev *macio_get_pci_dev(struct macio_dev *mdev) */ struct macio_driver { - char *name; - struct of_device_id *match_table; - struct module *owner; - int (*probe)(struct macio_dev* dev, const struct of_device_id *match); int (*remove)(struct macio_dev* dev); diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c index 76640ac76888..75b49d01780b 100644 --- a/drivers/ata/pata_macio.c +++ b/drivers/ata/pata_macio.c @@ -1355,8 +1355,11 @@ static struct of_device_id pata_macio_match[] = static struct macio_driver pata_macio_driver = { - .name = "pata-macio", - .match_table = pata_macio_match, + .driver = { + .name = "pata-macio", + .owner = THIS_MODULE, + .of_match_table = pata_macio_match, + }, .probe = pata_macio_attach, .remove = pata_macio_detach, #ifdef CONFIG_PM @@ -1366,9 +1369,6 @@ static struct macio_driver pata_macio_driver = #ifdef CONFIG_PMAC_MEDIABAY .mediabay_event = pata_macio_mb_event, #endif - .driver = { - .owner = THIS_MODULE, - }, }; static const struct pci_device_id pata_macio_pci_match[] = { diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index 52f2d11bc7b9..ed6fb91123ab 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c @@ -1159,8 +1159,10 @@ static struct of_device_id swim3_match[] = static struct macio_driver swim3_driver = { - .name = "swim3", - .match_table = swim3_match, + .driver = { + .name = "swim3", + .of_match_table = swim3_match, + }, .probe = swim3_attach, #if 0 .suspend = swim3_suspend, diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c index 183fa38760d8..ebcf8e470a97 100644 --- a/drivers/ide/pmac.c +++ b/drivers/ide/pmac.c @@ -1400,8 +1400,11 @@ static struct of_device_id pmac_ide_macio_match[] = static struct macio_driver pmac_ide_macio_driver = { - .name = "ide-pmac", - .match_table = pmac_ide_macio_match, + .driver = { + .name = "ide-pmac", + .owner = THIS_MODULE, + .of_match_table = pmac_ide_macio_match, + }, .probe = pmac_ide_macio_attach, .suspend = pmac_ide_macio_suspend, .resume = pmac_ide_macio_resume, diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 40390ac01309..b6e7ddc09d76 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -526,7 +526,6 @@ static void macio_pci_add_devices(struct macio_chip *chip) int macio_register_driver(struct macio_driver *drv) { /* initialize common driver fields */ - drv->driver.name = drv->name; drv->driver.bus = &macio_bus_type; /* register with core */ diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index 288acce76b74..2fd435bc542e 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c @@ -728,8 +728,10 @@ static struct of_device_id media_bay_match[] = static struct macio_driver media_bay_driver = { - .name = "media-bay", - .match_table = media_bay_match, + .driver = { + .name = "media-bay", + .of_match_table = media_bay_match, + }, .probe = media_bay_attach, .suspend = media_bay_suspend, .resume = media_bay_resume diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c index 12946c5f583f..53cce3a5da23 100644 --- a/drivers/macintosh/rack-meter.c +++ b/drivers/macintosh/rack-meter.c @@ -584,9 +584,11 @@ static struct of_device_id rackmeter_match[] = { }; static struct macio_driver rackmeter_driver = { - .name = "rackmeter", - .owner = THIS_MODULE, - .match_table = rackmeter_match, + .driver = { + .name = "rackmeter", + .owner = THIS_MODULE, + .of_match_table = rackmeter_match, + }, .probe = rackmeter_probe, .remove = __devexit_p(rackmeter_remove), .shutdown = rackmeter_shutdown, diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index 39250b2ca886..959add2410bf 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -1654,8 +1654,11 @@ MODULE_DEVICE_TABLE (of, bmac_match); static struct macio_driver bmac_driver = { - .name = "bmac", - .match_table = bmac_match, + .driver = { + .name = "bmac", + .owner = THIS_MODULE, + .of_match_table = bmac_match, + }, .probe = bmac_probe, .remove = bmac_remove, #ifdef CONFIG_PM diff --git a/drivers/net/mace.c b/drivers/net/mace.c index b6855a6476f8..1c5221f79d6f 100644 --- a/drivers/net/mace.c +++ b/drivers/net/mace.c @@ -997,8 +997,11 @@ MODULE_DEVICE_TABLE (of, mace_match); static struct macio_driver mace_driver = { - .name = "mace", - .match_table = mace_match, + .driver = { + .name = "mace", + .owner = THIS_MODULE, + .of_match_table = mace_match, + }, .probe = mace_probe, .remove = mace_remove, }; diff --git a/drivers/net/wireless/orinoco/airport.c b/drivers/net/wireless/orinoco/airport.c index 9bcee10c9308..4a0a0e5265c9 100644 --- a/drivers/net/wireless/orinoco/airport.c +++ b/drivers/net/wireless/orinoco/airport.c @@ -239,8 +239,11 @@ static struct of_device_id airport_match[] = MODULE_DEVICE_TABLE(of, airport_match); static struct macio_driver airport_driver = { - .name = DRIVER_NAME, - .match_table = airport_match, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = airport_match, + }, .probe = airport_attach, .remove = airport_detach, .suspend = airport_suspend, diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index 18735b39b3d3..3ddb4dc62d5d 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c @@ -542,8 +542,11 @@ MODULE_DEVICE_TABLE (of, mac53c94_match); static struct macio_driver mac53c94_driver = { - .name = "mac53c94", - .match_table = mac53c94_match, + .driver = { + .name = "mac53c94", + .owner = THIS_MODULE, + .of_match_table = mac53c94_match, + }, .probe = mac53c94_probe, .remove = mac53c94_remove, }; diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c index a1c97e88068a..1f784fde2510 100644 --- a/drivers/scsi/mesh.c +++ b/drivers/scsi/mesh.c @@ -2036,8 +2036,11 @@ MODULE_DEVICE_TABLE (of, mesh_match); static struct macio_driver mesh_driver = { - .name = "mesh", - .match_table = mesh_match, + .driver = { + .name = "mesh", + .owner = THIS_MODULE, + .of_match_table = mesh_match, + }, .probe = mesh_probe, .remove = mesh_remove, .shutdown = mesh_shutdown, diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index cabbdc7ba583..5b9cde79e4ea 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c @@ -2005,8 +2005,11 @@ static struct of_device_id pmz_match[] = MODULE_DEVICE_TABLE (of, pmz_match); static struct macio_driver pmz_driver = { - .name = "pmac_zilog", - .match_table = pmz_match, + .driver = { + .name = "pmac_zilog", + .owner = THIS_MODULE, + .of_match_table = pmz_match, + }, .probe = pmz_attach, .remove = pmz_detach, .suspend = pmz_suspend, diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c index 678933721735..3ff8cc5f487a 100644 --- a/sound/aoa/soundbus/i2sbus/core.c +++ b/sound/aoa/soundbus/i2sbus/core.c @@ -437,9 +437,11 @@ static int i2sbus_shutdown(struct macio_dev* dev) } static struct macio_driver i2sbus_drv = { - .name = "soundbus-i2s", - .owner = THIS_MODULE, - .match_table = i2sbus_match, + .driver = { + .name = "soundbus-i2s", + .owner = THIS_MODULE, + .of_match_table = i2sbus_match, + }, .probe = i2sbus_probe, .remove = i2sbus_remove, #ifdef CONFIG_PM -- cgit v1.2.3 From 66f49121ffa41a19c59965b31b046d8368fec3c7 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Mon, 31 May 2010 21:45:48 +0000 Subject: clocksource: sh_tmu: compute mult and shift before registration Since commit 98962465ed9e6ea99c38e0af63fe1dcb5a79dc25 ("nohz: Prevent clocksource wrapping during idle"), the CPU of an R2D board never goes to idle. This commit assumes that mult and shift are assigned before the clocksource is registered. As a consequence the safe maximum sleep time is negative and the CPU never goes into idle. This patch fixes the problem by moving mult and shift initialization from sh_tmu_clocksource_enable() to sh_tmu_register_clocksource(). Signed-off-by: Aurelien Jarno Cc: stable@kernel.org Signed-off-by: Paul Mundt --- drivers/clocksource/sh_tmu.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 8e44e14ec4c2..de715901b82a 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -199,16 +199,8 @@ static cycle_t sh_tmu_clocksource_read(struct clocksource *cs) static int sh_tmu_clocksource_enable(struct clocksource *cs) { struct sh_tmu_priv *p = cs_to_sh_tmu(cs); - int ret; - - ret = sh_tmu_enable(p); - if (ret) - return ret; - /* TODO: calculate good shift from rate and counter bit width */ - cs->shift = 10; - cs->mult = clocksource_hz2mult(p->rate, cs->shift); - return 0; + return sh_tmu_enable(p); } static void sh_tmu_clocksource_disable(struct clocksource *cs) @@ -228,6 +220,16 @@ static int sh_tmu_register_clocksource(struct sh_tmu_priv *p, cs->disable = sh_tmu_clocksource_disable; cs->mask = CLOCKSOURCE_MASK(32); cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; + + /* clk_get_rate() needs an enabled clock */ + clk_enable(p->clk); + /* channel will be configured at parent clock / 4 */ + p->rate = clk_get_rate(p->clk) / 4; + clk_disable(p->clk); + /* TODO: calculate good shift from rate and counter bit width */ + cs->shift = 10; + cs->mult = clocksource_hz2mult(p->rate, cs->shift); + dev_info(&p->pdev->dev, "used as clock source\n"); clocksource_register(cs); return 0; -- cgit v1.2.3 From f4d7c3565c1692c54d9152b52090fe73f0029e37 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 2 Jun 2010 17:10:44 +0900 Subject: clocksource: sh_cmt: compute mult and shift before registration Based on the sh_tmu change in 66f49121ffa41a19c59965b31b046d8368fec3c7 ("clocksource: sh_tmu: compute mult and shift before registration"). The same issues impact the sh_cmt driver, so we take the same approach here. Cc: stable@kernel.org Signed-off-by: Paul Mundt --- drivers/clocksource/sh_cmt.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index f6677cb19789..f3d3898898ed 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -412,18 +412,10 @@ static cycle_t sh_cmt_clocksource_read(struct clocksource *cs) static int sh_cmt_clocksource_enable(struct clocksource *cs) { struct sh_cmt_priv *p = cs_to_sh_cmt(cs); - int ret; p->total_cycles = 0; - ret = sh_cmt_start(p, FLAG_CLOCKSOURCE); - if (ret) - return ret; - - /* TODO: calculate good shift from rate and counter bit width */ - cs->shift = 0; - cs->mult = clocksource_hz2mult(p->rate, cs->shift); - return 0; + return sh_cmt_start(p, FLAG_CLOCKSOURCE); } static void sh_cmt_clocksource_disable(struct clocksource *cs) @@ -450,8 +442,20 @@ static int sh_cmt_register_clocksource(struct sh_cmt_priv *p, cs->resume = sh_cmt_clocksource_resume; cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8); cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; + + /* clk_get_rate() needs an enabled clock */ + clk_enable(p->clk); + p->rate = clk_get_rate(p->clk) / (p->width == 16) ? 512 : 8; + clk_disable(p->clk); + + /* TODO: calculate good shift from rate and counter bit width */ + cs->shift = 10; + cs->mult = clocksource_hz2mult(p->rate, cs->shift); + dev_info(&p->pdev->dev, "used as clock source\n"); + clocksource_register(cs); + return 0; } -- cgit v1.2.3 From ac422f9443191e050c16fe99baeb5c3d74934589 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 2 Jun 2010 18:10:00 +0900 Subject: sh: Make intc messages consistent via pr_fmt. Wrapping pr_fmt to the KBUILD_MODNAME prefix seems to be the trendy thing to do these days, so just do that instead of manually tidying up the stragglers. Signed-off-by: Paul Mundt --- drivers/sh/intc.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c index c585574b9aed..e91a23e5ffd8 100644 --- a/drivers/sh/intc.c +++ b/drivers/sh/intc.c @@ -16,6 +16,8 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -855,8 +857,8 @@ static void __init intc_register_irq(struct intc_desc *desc, primary = 1; if (!data[0] && !data[1]) - pr_warning("intc: missing unique irq mask for " - "irq %d (vect 0x%04x)\n", irq, irq2evt(irq)); + pr_warning("missing unique irq mask for irq %d (vect 0x%04x)\n", + irq, irq2evt(irq)); data[0] = data[0] ? data[0] : intc_mask_data(desc, d, enum_id, 1); data[1] = data[1] ? data[1] : intc_prio_data(desc, d, enum_id, 1); @@ -952,7 +954,7 @@ int __init register_intc_controller(struct intc_desc *desc) struct intc_desc_int *d; struct resource *res; - pr_info("intc: Registered controller '%s' with %u IRQs\n", + pr_info("Registered controller '%s' with %u IRQs\n", desc->name, hw->nr_vectors); d = kzalloc(sizeof(*d), GFP_NOWAIT); @@ -1148,7 +1150,7 @@ int register_intc_userimask(unsigned long addr) if (unlikely(!uimask)) return -ENOMEM; - pr_info("intc: userimask support registered for levels 0 -> %d\n", + pr_info("userimask support registered for levels 0 -> %d\n", default_prio_level - 1); return 0; @@ -1286,7 +1288,7 @@ static int __init register_intc_sysdevs(void) } if (error) - pr_err("intc: sysdev registration error\n"); + pr_err("sysdev registration error\n"); return error; } -- cgit v1.2.3 From f048fa9c8686119c3858a463cab6121dced7c0bf Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Tue, 1 Jun 2010 15:05:36 +0000 Subject: bnx2: Fix hang during rmmod bnx2. The regression is caused by: commit 4327ba435a56ada13eedf3eb332e583c7a0586a9 bnx2: Fix netpoll crash. If ->open() and ->close() are called multiple times, the same napi structs will be added to dev->napi_list multiple times, corrupting the dev->napi_list. This causes free_netdev() to hang during rmmod. We fix this by calling netif_napi_del() during ->close(). Also, bnx2_init_napi() must not be in the __devinit section since it is called by ->open(). Signed-off-by: Michael Chan Signed-off-by: Benjamin Li Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 188e356c30a3..949d7a9dcf92 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -247,6 +247,7 @@ static const struct flash_spec flash_5709 = { MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl); static void bnx2_init_napi(struct bnx2 *bp); +static void bnx2_del_napi(struct bnx2 *bp); static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr) { @@ -6270,6 +6271,7 @@ open_err: bnx2_free_skbs(bp); bnx2_free_irq(bp); bnx2_free_mem(bp); + bnx2_del_napi(bp); return rc; } @@ -6537,6 +6539,7 @@ bnx2_close(struct net_device *dev) bnx2_free_irq(bp); bnx2_free_skbs(bp); bnx2_free_mem(bp); + bnx2_del_napi(bp); bp->link_up = 0; netif_carrier_off(bp->dev); bnx2_set_power_state(bp, PCI_D3hot); @@ -8227,7 +8230,16 @@ bnx2_bus_string(struct bnx2 *bp, char *str) return str; } -static void __devinit +static void +bnx2_del_napi(struct bnx2 *bp) +{ + int i; + + for (i = 0; i < bp->irq_nvecs; i++) + netif_napi_del(&bp->bnx2_napi[i].napi); +} + +static void bnx2_init_napi(struct bnx2 *bp) { int i; -- cgit v1.2.3 From 08f382ebb8a9efb898840aa74cf55148c7a98af6 Mon Sep 17 00:00:00 2001 From: Scott Feldman Date: Tue, 1 Jun 2010 08:59:33 +0000 Subject: enic: bug fix: make the set/get netlink VF_PORT support symmetrical To make get/set netlink VF_PORT truly symmetrical, we need to keep track of what items are set and only return those items on get. Previously, the driver wasn't differentiating between a set of attr with a NULL string, for example, and not setting the attr at all. We only want to return the NULL string if the attr was actually set with a NULL string. Otherwise, don't return the attr. Signed-off-by: Scott Feldman Signed-off-by: David S. Miller --- drivers/net/enic/enic.h | 7 ++ drivers/net/enic/enic_main.c | 200 +++++++++++++++++++++---------------------- 2 files changed, 104 insertions(+), 103 deletions(-) (limited to 'drivers') diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index 85f2a2e7030a..45e86d1e5b1b 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -74,7 +74,14 @@ struct enic_msix_entry { void *devid; }; +#define ENIC_SET_APPLIED (1 << 0) +#define ENIC_SET_REQUEST (1 << 1) +#define ENIC_SET_NAME (1 << 2) +#define ENIC_SET_INSTANCE (1 << 3) +#define ENIC_SET_HOST (1 << 4) + struct enic_port_profile { + u32 set; u8 request; char name[PORT_PROFILE_MAX]; u8 instance_uuid[PORT_UUID_MAX]; diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 6586b5c7e4b6..bc7d6b96de3d 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1029,8 +1029,7 @@ static int enic_dev_init_done(struct enic *enic, int *done, int *error) return err; } -static int enic_set_port_profile(struct enic *enic, u8 request, u8 *mac, - char *name, u8 *instance_uuid, u8 *host_uuid) +static int enic_set_port_profile(struct enic *enic, u8 *mac) { struct vic_provinfo *vp; u8 oui[3] = VIC_PROVINFO_CISCO_OUI; @@ -1040,97 +1039,112 @@ static int enic_set_port_profile(struct enic *enic, u8 request, u8 *mac, "%02X%02X-%02X%02X%02X%02X%0X%02X"; int err; - if (!name) - return -EINVAL; + err = enic_vnic_dev_deinit(enic); + if (err) + return err; - if (!is_valid_ether_addr(mac)) - return -EADDRNOTAVAIL; + switch (enic->pp.request) { - vp = vic_provinfo_alloc(GFP_KERNEL, oui, VIC_PROVINFO_LINUX_TYPE); - if (!vp) - return -ENOMEM; + case PORT_REQUEST_ASSOCIATE: - vic_provinfo_add_tlv(vp, - VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR, - strlen(name) + 1, name); - - vic_provinfo_add_tlv(vp, - VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR, - ETH_ALEN, mac); - - if (instance_uuid) { - uuid = instance_uuid; - sprintf(uuid_str, uuid_fmt, - uuid[0], uuid[1], uuid[2], uuid[3], - uuid[4], uuid[5], uuid[6], uuid[7], - uuid[8], uuid[9], uuid[10], uuid[11], - uuid[12], uuid[13], uuid[14], uuid[15]); - vic_provinfo_add_tlv(vp, - VIC_LINUX_PROV_TLV_CLIENT_UUID_STR, - sizeof(uuid_str), uuid_str); - } + if (!(enic->pp.set & ENIC_SET_NAME) || !strlen(enic->pp.name)) + return -EINVAL; - if (host_uuid) { - uuid = host_uuid; - sprintf(uuid_str, uuid_fmt, - uuid[0], uuid[1], uuid[2], uuid[3], - uuid[4], uuid[5], uuid[6], uuid[7], - uuid[8], uuid[9], uuid[10], uuid[11], - uuid[12], uuid[13], uuid[14], uuid[15]); - vic_provinfo_add_tlv(vp, - VIC_LINUX_PROV_TLV_HOST_UUID_STR, - sizeof(uuid_str), uuid_str); - } + if (!is_valid_ether_addr(mac)) + return -EADDRNOTAVAIL; - err = enic_vnic_dev_deinit(enic); - if (err) - goto err_out; + vp = vic_provinfo_alloc(GFP_KERNEL, oui, + VIC_PROVINFO_LINUX_TYPE); + if (!vp) + return -ENOMEM; - memset(&enic->pp, 0, sizeof(enic->pp)); + vic_provinfo_add_tlv(vp, + VIC_LINUX_PROV_TLV_PORT_PROFILE_NAME_STR, + strlen(enic->pp.name) + 1, enic->pp.name); - err = enic_dev_init_prov(enic, vp); - if (err) - goto err_out; + vic_provinfo_add_tlv(vp, + VIC_LINUX_PROV_TLV_CLIENT_MAC_ADDR, + ETH_ALEN, mac); + + if (enic->pp.set & ENIC_SET_INSTANCE) { + uuid = enic->pp.instance_uuid; + sprintf(uuid_str, uuid_fmt, + uuid[0], uuid[1], uuid[2], uuid[3], + uuid[4], uuid[5], uuid[6], uuid[7], + uuid[8], uuid[9], uuid[10], uuid[11], + uuid[12], uuid[13], uuid[14], uuid[15]); + vic_provinfo_add_tlv(vp, + VIC_LINUX_PROV_TLV_CLIENT_UUID_STR, + sizeof(uuid_str), uuid_str); + } - enic->pp.request = request; - memcpy(enic->pp.name, name, PORT_PROFILE_MAX); - if (instance_uuid) - memcpy(enic->pp.instance_uuid, - instance_uuid, PORT_UUID_MAX); - if (host_uuid) - memcpy(enic->pp.host_uuid, - host_uuid, PORT_UUID_MAX); + if (enic->pp.set & ENIC_SET_HOST) { + uuid = enic->pp.host_uuid; + sprintf(uuid_str, uuid_fmt, + uuid[0], uuid[1], uuid[2], uuid[3], + uuid[4], uuid[5], uuid[6], uuid[7], + uuid[8], uuid[9], uuid[10], uuid[11], + uuid[12], uuid[13], uuid[14], uuid[15]); + vic_provinfo_add_tlv(vp, + VIC_LINUX_PROV_TLV_HOST_UUID_STR, + sizeof(uuid_str), uuid_str); + } -err_out: - vic_provinfo_free(vp); + err = enic_dev_init_prov(enic, vp); + vic_provinfo_free(vp); + if (err) + return err; + break; - return err; -} + case PORT_REQUEST_DISASSOCIATE: + break; -static int enic_unset_port_profile(struct enic *enic) -{ - memset(&enic->pp, 0, sizeof(enic->pp)); - return enic_vnic_dev_deinit(enic); + default: + return -EINVAL; + } + + enic->pp.set |= ENIC_SET_APPLIED; + return 0; } static int enic_set_vf_port(struct net_device *netdev, int vf, struct nlattr *port[]) { struct enic *enic = netdev_priv(netdev); - char *name = NULL; - u8 *instance_uuid = NULL; - u8 *host_uuid = NULL; - u8 request = PORT_REQUEST_DISASSOCIATE; + + memset(&enic->pp, 0, sizeof(enic->pp)); + + if (port[IFLA_PORT_REQUEST]) { + enic->pp.set |= ENIC_SET_REQUEST; + enic->pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]); + } + + if (port[IFLA_PORT_PROFILE]) { + enic->pp.set |= ENIC_SET_NAME; + memcpy(enic->pp.name, nla_data(port[IFLA_PORT_PROFILE]), + PORT_PROFILE_MAX); + } + + if (port[IFLA_PORT_INSTANCE_UUID]) { + enic->pp.set |= ENIC_SET_INSTANCE; + memcpy(enic->pp.instance_uuid, + nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX); + } + + if (port[IFLA_PORT_HOST_UUID]) { + enic->pp.set |= ENIC_SET_HOST; + memcpy(enic->pp.host_uuid, + nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX); + } /* don't support VFs, yet */ if (vf != PORT_SELF_VF) return -EOPNOTSUPP; - if (port[IFLA_PORT_REQUEST]) - request = nla_get_u8(port[IFLA_PORT_REQUEST]); + if (!(enic->pp.set & ENIC_SET_REQUEST)) + return -EOPNOTSUPP; - switch (request) { - case PORT_REQUEST_ASSOCIATE: + if (enic->pp.request == PORT_REQUEST_ASSOCIATE) { /* If the interface mac addr hasn't been assigned, * assign a random mac addr before setting port- @@ -1139,30 +1153,9 @@ static int enic_set_vf_port(struct net_device *netdev, int vf, if (is_zero_ether_addr(netdev->dev_addr)) random_ether_addr(netdev->dev_addr); - - if (port[IFLA_PORT_PROFILE]) - name = nla_data(port[IFLA_PORT_PROFILE]); - - if (port[IFLA_PORT_INSTANCE_UUID]) - instance_uuid = - nla_data(port[IFLA_PORT_INSTANCE_UUID]); - - if (port[IFLA_PORT_HOST_UUID]) - host_uuid = nla_data(port[IFLA_PORT_HOST_UUID]); - - return enic_set_port_profile(enic, request, - netdev->dev_addr, name, - instance_uuid, host_uuid); - - case PORT_REQUEST_DISASSOCIATE: - - return enic_unset_port_profile(enic); - - default: - break; } - return -EOPNOTSUPP; + return enic_set_port_profile(enic, netdev->dev_addr); } static int enic_get_vf_port(struct net_device *netdev, int vf, @@ -1172,14 +1165,12 @@ static int enic_get_vf_port(struct net_device *netdev, int vf, int err, error, done; u16 response = PORT_PROFILE_RESPONSE_SUCCESS; - /* don't support VFs, yet */ - if (vf != PORT_SELF_VF) - return -EOPNOTSUPP; + if (!(enic->pp.set & ENIC_SET_APPLIED)) + return -ENODATA; err = enic_dev_init_done(enic, &done, &error); - if (err) - return err; + error = err; switch (error) { case ERR_SUCCESS: @@ -1202,12 +1193,15 @@ static int enic_get_vf_port(struct net_device *netdev, int vf, NLA_PUT_U16(skb, IFLA_PORT_REQUEST, enic->pp.request); NLA_PUT_U16(skb, IFLA_PORT_RESPONSE, response); - NLA_PUT(skb, IFLA_PORT_PROFILE, PORT_PROFILE_MAX, - enic->pp.name); - NLA_PUT(skb, IFLA_PORT_INSTANCE_UUID, PORT_UUID_MAX, - enic->pp.instance_uuid); - NLA_PUT(skb, IFLA_PORT_HOST_UUID, PORT_UUID_MAX, - enic->pp.host_uuid); + if (enic->pp.set & ENIC_SET_NAME) + NLA_PUT(skb, IFLA_PORT_PROFILE, PORT_PROFILE_MAX, + enic->pp.name); + if (enic->pp.set & ENIC_SET_INSTANCE) + NLA_PUT(skb, IFLA_PORT_INSTANCE_UUID, PORT_UUID_MAX, + enic->pp.instance_uuid); + if (enic->pp.set & ENIC_SET_HOST) + NLA_PUT(skb, IFLA_PORT_HOST_UUID, PORT_UUID_MAX, + enic->pp.host_uuid); return 0; -- cgit v1.2.3 From ceb3d2394532540a52ce34f71e67c8d008913f79 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Sat, 29 May 2010 13:23:34 +0000 Subject: korina: fix deadlock on RX FIFO overrun By calling korina_restart(), the IRQ handler tries to disable the interrupt it's currently serving. This leads to a deadlock since disable_irq() waits for any running IRQ handlers to finish before returning. This patch addresses the issue by turning korina_restart() into a workqueue task, which is then scheduled when needed. Reproducing the deadlock is easily done using e.g. GNU netcat to send large amounts of UDP data to the host running this driver. Note that the same problem (and fix) applies to TX FIFO underruns, but apparently these are less easy to trigger. Signed-off-by: Phil Sutter Signed-off-by: David S. Miller --- drivers/net/korina.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 26bf1b76b997..13533f937e05 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -135,6 +135,7 @@ struct korina_private { struct napi_struct napi; struct timer_list media_check_timer; struct mii_if_info mii_if; + struct work_struct restart_task; struct net_device *dev; int phy_addr; }; @@ -890,12 +891,12 @@ static int korina_init(struct net_device *dev) /* * Restart the RC32434 ethernet controller. - * FIXME: check the return status where we call it */ -static int korina_restart(struct net_device *dev) +static void korina_restart_task(struct work_struct *work) { - struct korina_private *lp = netdev_priv(dev); - int ret; + struct korina_private *lp = container_of(work, + struct korina_private, restart_task); + struct net_device *dev = lp->dev; /* * Disable interrupts @@ -916,10 +917,9 @@ static int korina_restart(struct net_device *dev) napi_disable(&lp->napi); - ret = korina_init(dev); - if (ret < 0) { + if (korina_init(dev) < 0) { printk(KERN_ERR "%s: cannot restart device\n", dev->name); - return ret; + return; } korina_multicast_list(dev); @@ -927,8 +927,6 @@ static int korina_restart(struct net_device *dev) enable_irq(lp->ovr_irq); enable_irq(lp->tx_irq); enable_irq(lp->rx_irq); - - return ret; } static void korina_clear_and_restart(struct net_device *dev, u32 value) @@ -937,7 +935,7 @@ static void korina_clear_and_restart(struct net_device *dev, u32 value) netif_stop_queue(dev); writel(value, &lp->eth_regs->ethintfc); - korina_restart(dev); + schedule_work(&lp->restart_task); } /* Ethernet Tx Underflow interrupt */ @@ -962,11 +960,8 @@ static irqreturn_t korina_und_interrupt(int irq, void *dev_id) static void korina_tx_timeout(struct net_device *dev) { struct korina_private *lp = netdev_priv(dev); - unsigned long flags; - spin_lock_irqsave(&lp->lock, flags); - korina_restart(dev); - spin_unlock_irqrestore(&lp->lock, flags); + schedule_work(&lp->restart_task); } /* Ethernet Rx Overflow interrupt */ @@ -1086,6 +1081,8 @@ static int korina_close(struct net_device *dev) napi_disable(&lp->napi); + cancel_work_sync(&lp->restart_task); + free_irq(lp->rx_irq, dev); free_irq(lp->tx_irq, dev); free_irq(lp->ovr_irq, dev); @@ -1198,6 +1195,8 @@ static int korina_probe(struct platform_device *pdev) } setup_timer(&lp->media_check_timer, korina_poll_media, (unsigned long) dev); + INIT_WORK(&lp->restart_task, korina_restart_task); + printk(KERN_INFO "%s: " DRV_NAME "-" DRV_VERSION " " DRV_RELDATE "\n", dev->name); out: -- cgit v1.2.3 From 53ee490ac5836d506ea5830f821045aafa3c196f Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Sat, 29 May 2010 13:23:35 +0000 Subject: korina: use netdev_alloc_skb_ip_align() here, too This patch completes commit 89d71a66c40d629e3b1285def543ab1425558cd5 which missed this spot, as it seems. Signed-off-by: Phil Sutter Signed-off-by: David S. Miller --- drivers/net/korina.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 13533f937e05..3e9b6b7be42e 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -765,10 +765,9 @@ static int korina_alloc_ring(struct net_device *dev) /* Initialize the receive descriptors */ for (i = 0; i < KORINA_NUM_RDS; i++) { - skb = dev_alloc_skb(KORINA_RBSIZE + 2); + skb = netdev_alloc_skb_ip_align(dev, KORINA_RBSIZE); if (!skb) return -ENOMEM; - skb_reserve(skb, 2); lp->rx_skb[i] = skb; lp->rd_ring[i].control = DMA_DESC_IOD | DMA_COUNT(KORINA_RBSIZE); -- cgit v1.2.3 From b1011b375be106e0a312baafc981a26165283efe Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Sat, 29 May 2010 13:23:36 +0000 Subject: korina: count RX DMA OVR as rx_fifo_error This way, RX DMA overruns (actually being caused by overrun of the 512byte input FIFO) show up in ifconfig output. The rx_fifo_errors counter is unused otherwise. Signed-off-by: Phil Sutter Signed-off-by: David S. Miller --- drivers/net/korina.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 3e9b6b7be42e..c7a9bef4dfb0 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -376,7 +376,7 @@ static int korina_rx(struct net_device *dev, int limit) if (devcs & ETH_RX_LE) dev->stats.rx_length_errors++; if (devcs & ETH_RX_OVR) - dev->stats.rx_over_errors++; + dev->stats.rx_fifo_errors++; if (devcs & ETH_RX_CV) dev->stats.rx_frame_errors++; if (devcs & ETH_RX_CES) -- cgit v1.2.3 From e3fe8558c7fc182972c3d947d88744482111f304 Mon Sep 17 00:00:00 2001 From: Eric Bénard Date: Wed, 2 Jun 2010 06:13:34 -0700 Subject: net/fec: fix pm to survive to suspend/resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * in the actual driver, calling fec_stop and fec_enet_init doesn't allow to have a working network interface at resume (where a ifconfig down and up is required to recover the interface) * by using fec_enet_close and fec_enet_open, this patch solves this problem and handle the case where the link changed between suspend and resume * this patch also disable clock at suspend and reenable it at resume Signed-off-by: Eric Bénard Signed-off-by: David S. Miller --- drivers/net/fec.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fec.c b/drivers/net/fec.c index ddf7a86cd466..edfff92a6d8e 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1373,10 +1373,9 @@ fec_suspend(struct platform_device *dev, pm_message_t state) if (ndev) { fep = netdev_priv(ndev); - if (netif_running(ndev)) { - netif_device_detach(ndev); - fec_stop(ndev); - } + if (netif_running(ndev)) + fec_enet_close(ndev); + clk_disable(fep->clk); } return 0; } @@ -1385,12 +1384,13 @@ static int fec_resume(struct platform_device *dev) { struct net_device *ndev = platform_get_drvdata(dev); + struct fec_enet_private *fep; if (ndev) { - if (netif_running(ndev)) { - fec_enet_init(ndev, 0); - netif_device_attach(ndev); - } + fep = netdev_priv(ndev); + clk_enable(fep->clk); + if (netif_running(ndev)) + fec_enet_open(ndev); } return 0; } -- cgit v1.2.3 From cc1fed00c9ba84f38717a6cab84409cd48f340e3 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Wed, 2 Jun 2010 16:01:45 +0300 Subject: mtd/r852: register IRQ as last step Otherwise, if it fires right away, it might access uninitialized spinlock Signed-off-by: Maxim Levitsky Signed-off-by: David Woodhouse --- drivers/mtd/nand/r852.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c index 78a423295474..20a654a94d30 100644 --- a/drivers/mtd/nand/r852.c +++ b/drivers/mtd/nand/r852.c @@ -940,18 +940,19 @@ int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) r852_dma_test(dev); + dev->irq = pci_dev->irq; + spin_lock_init(&dev->irqlock); + + dev->card_detected = 0; + r852_card_update_present(dev); + /*register irq handler*/ error = -ENODEV; if (request_irq(pci_dev->irq, &r852_irq, IRQF_SHARED, DRV_NAME, dev)) goto error10; - dev->irq = pci_dev->irq; - spin_lock_init(&dev->irqlock); - /* kick initial present test */ - dev->card_detected = 0; - r852_card_update_present(dev); queue_delayed_work(dev->card_workqueue, &dev->card_detect_work, 0); -- cgit v1.2.3 From 9489be8ca234c07666e88a4472e4d5f2a2425aa5 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Wed, 2 Jun 2010 16:01:46 +0300 Subject: mtd/r852: Fixes in case of DMA timeout * Don't call complete on dma completion * do a INIT_COMPLETE before using it each time * Report DMA read error via ecc 'correct' I finally managed to make my system do suspend to ram propertly, and I see that if card was inserted during suspend (while system was off), I get dma timeouts on resume. Simple card reinsert solves the issue. This patch solves a crash that would happen otherwise Signed-off-by: Maxim Levitsky Signed-off-by: David Woodhouse --- drivers/mtd/nand/r852.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c index 20a654a94d30..3f219e61df7d 100644 --- a/drivers/mtd/nand/r852.c +++ b/drivers/mtd/nand/r852.c @@ -150,7 +150,6 @@ static void r852_dma_done(struct r852_device *dev, int error) if (dev->phys_dma_addr && dev->phys_dma_addr != dev->phys_bounce_buffer) pci_unmap_single(dev->pci_dev, dev->phys_dma_addr, R852_DMA_LEN, dev->dma_dir ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); - complete(&dev->dma_done); } /* @@ -182,6 +181,7 @@ static void r852_do_dma(struct r852_device *dev, uint8_t *buf, int do_read) /* Set dma direction */ dev->dma_dir = do_read; dev->dma_stage = 1; + INIT_COMPLETION(dev->dma_done); dbg_verbose("doing dma %s ", do_read ? "read" : "write"); @@ -494,6 +494,11 @@ int r852_ecc_correct(struct mtd_info *mtd, uint8_t *dat, if (dev->card_unstable) return 0; + if (dev->dma_error) { + dev->dma_error = 0; + return -1; + } + r852_write_reg(dev, R852_CTL, dev->ctlreg | R852_CTL_ECC_ACCESS); ecc_reg = r852_read_reg_dword(dev, R852_DATALINE); r852_write_reg(dev, R852_CTL, dev->ctlreg); @@ -796,6 +801,7 @@ static irqreturn_t r852_irq(int irq, void *data) if (dma_status & R852_DMA_IRQ_ERROR) { dbg("recieved dma error IRQ"); r852_dma_done(dev, -EIO); + complete(&dev->dma_done); goto out; } @@ -825,8 +831,10 @@ static irqreturn_t r852_irq(int irq, void *data) r852_dma_enable(dev); /* Operation done */ - if (dev->dma_stage == 3) + if (dev->dma_stage == 3) { r852_dma_done(dev, 0); + complete(&dev->dma_done); + } goto out; } @@ -1082,7 +1090,7 @@ int r852_resume(struct device *device) dev->card_detected ? "added" : "removed"); queue_delayed_work(dev->card_workqueue, - &dev->card_detect_work, 1000); + &dev->card_detect_work, msecs_to_jiffies(1000)); return 0; } -- cgit v1.2.3 From ac373f7e2286ed3690e8a93ebf9f6f1ae0c7d4a9 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Wed, 2 Jun 2010 16:01:47 +0300 Subject: mtd/r852: update card detect early. This turns out to be the reason for DMA timeouts on resume, if card was inserted while system was suspended Signed-off-by: Maxim Levitsky Signed-off-by: David Woodhouse --- drivers/mtd/nand/r852.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c index 3f219e61df7d..bcfc851fe550 100644 --- a/drivers/mtd/nand/r852.c +++ b/drivers/mtd/nand/r852.c @@ -712,6 +712,7 @@ void r852_card_detect_work(struct work_struct *work) container_of(work, struct r852_device, card_detect_work.work); r852_card_update_present(dev); + r852_update_card_detect(dev); dev->card_unstable = 0; /* False alarm */ @@ -727,7 +728,6 @@ void r852_card_detect_work(struct work_struct *work) else r852_unregister_nand_device(dev); exit: - /* Update detection logic */ r852_update_card_detect(dev); } -- cgit v1.2.3 From 10389536742cefbedecb67a5b2906f155cf3a1c3 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 30 May 2010 19:43:52 +0200 Subject: firewire: core: check for 1394a compliant IRM, fix inaccessibility of Sony camcorder Per IEEE 1394 clause 8.4.2.3, a contender for the IRM role shall check whether the current IRM complies to 1394a-2000 or later. If not force a compliant node (e.g. itself) to become IRM. This was implemented in the older ieee1394 driver but not yet in firewire-core. An older Sony camcorder (Sony DCR-TRV25) which implements 1394-1995 IRM but neither 1394a-2000 IRM nor BM was now found to cause an interoperability bug: - Camcorder becomes root node when plugged in, hence gets IRM role. - firewire-core successfully contends for BM role, proceeds to perform gap count optimization and resets the bus. - Sony camcorder ignores presence of a BM (against the spec, this is a firmware bug), performs its idea of gap count optimization and resets the bus. - Preceding two steps are repeated endlessly, bus never settles, regular I/O is practically impossible. http://thread.gmane.org/gmane.linux.kernel.firewire.user/3913 This is an interoperability regression from the old to the new drivers. Fix it indirectly by adding the 1394a IRM check. The spec suggests three and a half methods to determine 1394a compliance of a remote IRM; we choose the method of testing the Config_ROM.Bus_Info.generation field. This is data that firewire-core should have readily available at this point, i.e. does not require extra I/O. Reported-by: Clemens Ladisch (missing 1394a check) Reported-by: H. S. (issue with Sony DCR-TRV25) Tested-by: H. S. Cc: # .32.x and newer Signed-off-by: Stefan Richter --- drivers/firewire/core-card.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index 9dcb30466ec0..371713ff0266 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c @@ -231,7 +231,7 @@ void fw_schedule_bm_work(struct fw_card *card, unsigned long delay) static void fw_card_bm_work(struct work_struct *work) { struct fw_card *card = container_of(work, struct fw_card, work.work); - struct fw_device *root_device; + struct fw_device *root_device, *irm_device; struct fw_node *root_node; unsigned long flags; int root_id, new_root_id, irm_id, local_id; @@ -239,6 +239,7 @@ static void fw_card_bm_work(struct work_struct *work) bool do_reset = false; bool root_device_is_running; bool root_device_is_cmc; + bool irm_is_1394_1995_only; spin_lock_irqsave(&card->lock, flags); @@ -248,12 +249,18 @@ static void fw_card_bm_work(struct work_struct *work) } generation = card->generation; + root_node = card->root_node; fw_node_get(root_node); root_device = root_node->data; root_device_is_running = root_device && atomic_read(&root_device->state) == FW_DEVICE_RUNNING; root_device_is_cmc = root_device && root_device->cmc; + + irm_device = card->irm_node->data; + irm_is_1394_1995_only = irm_device && irm_device->config_rom && + (irm_device->config_rom[2] & 0x000000f0) == 0; + root_id = root_node->node_id; irm_id = card->irm_node->node_id; local_id = card->local_node->node_id; @@ -276,8 +283,15 @@ static void fw_card_bm_work(struct work_struct *work) if (!card->irm_node->link_on) { new_root_id = local_id; - fw_notify("IRM has link off, making local node (%02x) root.\n", - new_root_id); + fw_notify("%s, making local node (%02x) root.\n", + "IRM has link off", new_root_id); + goto pick_me; + } + + if (irm_is_1394_1995_only) { + new_root_id = local_id; + fw_notify("%s, making local node (%02x) root.\n", + "IRM is not 1394a compliant", new_root_id); goto pick_me; } @@ -316,8 +330,8 @@ static void fw_card_bm_work(struct work_struct *work) * root, and thus, IRM. */ new_root_id = local_id; - fw_notify("BM lock failed, making local node (%02x) root.\n", - new_root_id); + fw_notify("%s, making local node (%02x) root.\n", + "BM lock failed", new_root_id); goto pick_me; } } else if (card->bm_generation != generation) { -- cgit v1.2.3 From 8b27ff4cf6d15964aa2987aeb58db4dfb1f87a19 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 31 May 2010 16:26:48 +0200 Subject: sata_via: magic vt6421 fix for transmission problems w/ WD drives vt6421 has problems talking to recent WD drives. It causes a lot of transmission errors while high bandwidth transfer as reported in the following bugzilla entry. https://bugzilla.kernel.org/show_bug.cgi?id=15173 Joseph Chan provided the following fix. I don't have any idea what it does but I can verify the issue is gone with the patch applied. Signed-off-by: Tejun Heo Originally-from: Joseph Chan Reported-by: Jorrit Tijben Cc: stable@kernel.org Signed-off-by: Jeff Garzik --- drivers/ata/sata_via.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 101d8c219caf..0ecd0f6aa2c0 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -575,6 +575,19 @@ static void svia_configure(struct pci_dev *pdev) tmp8 |= NATIVE_MODE_ALL; pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8); } + + /* + * vt6421 has problems talking to some drives. The following + * is the magic fix from Joseph Chan . + * Please add proper documentation if possible. + * + * https://bugzilla.kernel.org/show_bug.cgi?id=15173 + */ + if (pdev->device == 0x3249) { + pci_read_config_byte(pdev, 0x52, &tmp8); + tmp8 |= 1 << 2; + pci_write_config_byte(pdev, 0x52, tmp8); + } } static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) -- cgit v1.2.3 From f3faf8fc3fab45c3526efe8c9e99bb23f8723350 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 1 Jun 2010 17:29:21 +0200 Subject: sata_nv: don't diddle with nIEN on mcp55 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On mcp55, nIEN gets stuck once set and liteon blueray rom iHOS104-08 violates ATA specification and fails to set I on D2H Reg FIS if nIEN is set when the command was issued. When the other party is following the spec, both devices can work fine but when the two flaws are put together, they can't talk to each other. mcp55 has its own IRQ masking mechanism and there's no reason to mess with nIEN in the first place. Fix it by dropping nIEN diddling from nv_mcp55_freeze/thaw(). This was originally reported by Cengiz. Although Cengiz hasn't verified the fix yet, I could reproduce this problem and verfiy the fix. Even if Cengiz is experiencing different or additional problems, this patch is needed. Signed-off-by: Tejun Heo Reported-by: Cengiz Günay Cc: stable@kernel.org Signed-off-by: Jeff Garzik --- drivers/ata/sata_nv.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 6fd114784116..21161136cad0 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -1669,7 +1669,6 @@ static void nv_mcp55_freeze(struct ata_port *ap) mask = readl(mmio_base + NV_INT_ENABLE_MCP55); mask &= ~(NV_INT_ALL_MCP55 << shift); writel(mask, mmio_base + NV_INT_ENABLE_MCP55); - ata_sff_freeze(ap); } static void nv_mcp55_thaw(struct ata_port *ap) @@ -1683,7 +1682,6 @@ static void nv_mcp55_thaw(struct ata_port *ap) mask = readl(mmio_base + NV_INT_ENABLE_MCP55); mask |= (NV_INT_MASK_MCP55 << shift); writel(mask, mmio_base + NV_INT_ENABLE_MCP55); - ata_sff_thaw(ap); } static void nv_adma_error_handler(struct ata_port *ap) -- cgit v1.2.3 From ed4e2f801cf1484a68c4b41878353f26e6554c6a Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 29 May 2010 12:47:45 +0200 Subject: libata-sff: trivial corrections to Kconfig help text Signed-off-by: Stefan Richter Signed-off-by: Jeff Garzik --- drivers/ata/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 73f883333a0d..aa85a98d3a4f 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -168,10 +168,10 @@ config ATA_BMDMA default y help This option adds support for SFF ATA controllers with BMDMA - capability. BMDMA stands for bus-master DMA and the - de-facto DMA interface for SFF controllers. + capability. BMDMA stands for bus-master DMA and is the + de facto DMA interface for SFF controllers. - If unuser, say Y. + If unsure, say Y. if ATA_BMDMA -- cgit v1.2.3 From 72ec24bd7725545bc149d80cbd21a7578d9aa206 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 15 May 2010 20:09:32 +0200 Subject: SCSI: implement sd_unlock_native_capacity() Implement sd_unlock_native_capacity() method which calls into hostt->unlock_native_capacity() if implemented. This will be invoked by block layer if partitions extend beyond the end of the device and can be used to implement, for example, on-demand ATA host protected area unlocking. Signed-off-by: Tejun Heo Cc: Ben Hutchings Signed-off-by: Jeff Garzik --- drivers/scsi/sd.c | 22 ++++++++++++++++++++++ include/scsi/scsi_host.h | 8 ++++++++ 2 files changed, 30 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 829cc37abc41..8802e48bc063 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -97,6 +97,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); #endif static int sd_revalidate_disk(struct gendisk *); +static void sd_unlock_native_capacity(struct gendisk *disk); static int sd_probe(struct device *); static int sd_remove(struct device *); static void sd_shutdown(struct device *); @@ -1101,6 +1102,7 @@ static const struct block_device_operations sd_fops = { #endif .media_changed = sd_media_changed, .revalidate_disk = sd_revalidate_disk, + .unlock_native_capacity = sd_unlock_native_capacity, }; static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd) @@ -2120,6 +2122,26 @@ static int sd_revalidate_disk(struct gendisk *disk) return 0; } +/** + * sd_unlock_native_capacity - unlock native capacity + * @disk: struct gendisk to set capacity for + * + * Block layer calls this function if it detects that partitions + * on @disk reach beyond the end of the device. If the SCSI host + * implements ->unlock_native_capacity() method, it's invoked to + * give it a chance to adjust the device capacity. + * + * CONTEXT: + * Defined by block layer. Might sleep. + */ +static void sd_unlock_native_capacity(struct gendisk *disk) +{ + struct scsi_device *sdev = scsi_disk(disk)->device; + + if (sdev->host->hostt->unlock_native_capacity) + sdev->host->hostt->unlock_native_capacity(sdev); +} + /** * sd_format_disk_name - format disk name * @prefix: name prefix - ie. "sd" for SCSI disks diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index c50a97fc76f9..b7bdecb7b76e 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -326,6 +326,14 @@ struct scsi_host_template { int (* bios_param)(struct scsi_device *, struct block_device *, sector_t, int []); + /* + * This function is called when one or more partitions on the + * device reach beyond the end of the device. + * + * Status: OPTIONAL + */ + void (*unlock_native_capacity)(struct scsi_device *); + /* * Can be used to export driver statistics and other infos to the * world outside the kernel ie. userspace and it also provides an -- cgit v1.2.3 From 68939ce5fc17ee9c03ef6e543d4f82bd9f5583d4 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 15 May 2010 20:09:33 +0200 Subject: libata: use the enlarged capacity after late HPA unlock After late HPA unlock, libata kept using the original capacity ignoring the new larger native capacity. Enlarging device on the fly doesn't cause any harm. Use the larger native capacity instead. This will enable on-demand HPA unlocking. Signed-off-by: Tejun Heo Cc: Ben Hutchings Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 06b7e49e039c..1e5d0a36a0a4 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4119,9 +4119,8 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, dev->n_sectors > n_sectors && dev->n_sectors == n_native_sectors) { ata_dev_printk(dev, KERN_WARNING, "new n_sectors matches native, probably " - "late HPA unlock, continuing\n"); - /* keep using the old n_sectors */ - dev->n_sectors = n_sectors; + "late HPA unlock, n_sectors updated\n"); + /* use the larger n_sectors */ return 0; } -- cgit v1.2.3 From d8d9129ea28e2177749627c82962feb26e8d11e9 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 15 May 2010 20:09:34 +0200 Subject: libata: implement on-demand HPA unlocking Implement ata_scsi_unlock_native_capacity() which will be called through SCSI layer when block layer notices that partitions on a device extend beyond the end of the device. It requests EH to unlock HPA, waits for completion and returns the current device capacity. This allows libata to unlock HPA on demand instead of having to decide whether to unlock upfront. Unlocking on demand is safer than unlocking by upfront because some BIOSes write private data to the area beyond HPA limit. This was suggested by Ben Hutchings. Signed-off-by: Tejun Heo Suggested-by: Ben Hutchings Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 1 + drivers/ata/libata-scsi.c | 29 +++++++++++++++++++++++++++++ include/linux/libata.h | 2 ++ 3 files changed, 32 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 1e5d0a36a0a4..ddf8e4862787 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -6668,6 +6668,7 @@ EXPORT_SYMBOL_GPL(ata_dummy_port_info); EXPORT_SYMBOL_GPL(ata_link_next); EXPORT_SYMBOL_GPL(ata_dev_next); EXPORT_SYMBOL_GPL(ata_std_bios_param); +EXPORT_SYMBOL_GPL(ata_scsi_unlock_native_capacity); EXPORT_SYMBOL_GPL(ata_host_init); EXPORT_SYMBOL_GPL(ata_host_alloc); EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo); diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index cfa9dd3d7253..a54273d2c3c6 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -414,6 +414,35 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev, return 0; } +/** + * ata_scsi_unlock_native_capacity - unlock native capacity + * @sdev: SCSI device to adjust device capacity for + * + * This function is called if a partition on @sdev extends beyond + * the end of the device. It requests EH to unlock HPA. + * + * LOCKING: + * Defined by the SCSI layer. Might sleep. + */ +void ata_scsi_unlock_native_capacity(struct scsi_device *sdev) +{ + struct ata_port *ap = ata_shost_to_port(sdev->host); + struct ata_device *dev; + unsigned long flags; + + spin_lock_irqsave(ap->lock, flags); + + dev = ata_scsi_find_dev(ap, sdev); + if (dev && dev->n_sectors < dev->n_native_sectors) { + dev->flags |= ATA_DFLAG_UNLOCK_HPA; + dev->link->eh_info.action |= ATA_EH_RESET; + ata_port_schedule_eh(ap); + } + + spin_unlock_irqrestore(ap->lock, flags); + ata_port_wait_eh(ap); +} + /** * ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl * @ap: target port diff --git a/include/linux/libata.h b/include/linux/libata.h index 3bad2701bfa6..b85f3ff34d7d 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1023,6 +1023,7 @@ extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, extern int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[]); +extern void ata_scsi_unlock_native_capacity(struct scsi_device *sdev); extern int ata_scsi_slave_config(struct scsi_device *sdev); extern void ata_scsi_slave_destroy(struct scsi_device *sdev); extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, @@ -1174,6 +1175,7 @@ extern struct device_attribute *ata_common_sdev_attrs[]; .slave_configure = ata_scsi_slave_config, \ .slave_destroy = ata_scsi_slave_destroy, \ .bios_param = ata_std_bios_param, \ + .unlock_native_capacity = ata_scsi_unlock_native_capacity, \ .sdev_attrs = ata_common_sdev_attrs #define ATA_NCQ_SHT(drv_name) \ -- cgit v1.2.3 From ffabc9a6e8b34151a97fc91fcbef827f07504f75 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 2 Jun 2010 13:35:02 -0600 Subject: of/usb: fix build error due to of_node pointer move Fix driver to use new location of of_node pointer (introduced by commit use new location of of_node pointer (introduced by commit 61c7a080a5a061c976988fd4b844dfb468dda255; of: Always use 'struct device.of_node' to get device node pointer) Signed-off-by: Grant Likely Reported-by: John Linn CC: Greg Kroah-Hartman CC: Alan Stern CC: linux-usb@vger.kernel.org CC: devicetree-discuss@lists.ozlabs.org --- drivers/usb/host/ehci-xilinx-of.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c index 013972bbde57..4899f451add9 100644 --- a/drivers/usb/host/ehci-xilinx-of.c +++ b/drivers/usb/host/ehci-xilinx-of.c @@ -151,7 +151,7 @@ static const struct hc_driver ehci_xilinx_of_hc_driver = { static int __devinit ehci_hcd_xilinx_of_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dn = op->node; + struct device_node *dn = op->dev.of_node; struct usb_hcd *hcd; struct ehci_hcd *ehci; struct resource res; -- cgit v1.2.3 From b53550781b7d51036aea3b3ee63ece3c6c8f4597 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 25 May 2010 23:24:02 -0600 Subject: of/spi: Fix build failure on spi_ppc4xx.c This patch fixes a build error caused by the OF device_node pointer being moved into struct device. Fixes bug introduced by commit 61c7a080a5a061c976988fd4b844dfb468dda255 (of: Always use 'struct device.of_node' to get device node pointer) Signed-off-by: Grant Likely CC: Sean MacLennan CC: spi-devel-general@lists.sourceforge.net CC: devicetree-discuss@lists.ozlabs.org --- drivers/spi/spi_ppc4xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi_ppc4xx.c b/drivers/spi/spi_ppc4xx.c index 19c0b3b34fce..d53466a249d9 100644 --- a/drivers/spi/spi_ppc4xx.c +++ b/drivers/spi/spi_ppc4xx.c @@ -397,7 +397,7 @@ static int __init spi_ppc4xx_of_probe(struct of_device *op, struct spi_master *master; struct spi_bitbang *bbp; struct resource resource; - struct device_node *np = op->node; + struct device_node *np = op->dev.of_node; struct device *dev = &op->dev; struct device_node *opbnp; int ret; -- cgit v1.2.3 From de2b606c24f178038b95a831f21a35a29faa6eab Mon Sep 17 00:00:00 2001 From: Michael Guntsche Date: Wed, 2 Jun 2010 02:25:52 -0600 Subject: watchdog: Fix build failure with OF changes commit 61c7a080a5a061c976988fd4b844dfb468dda255 ( of: Always use 'struct device.of_node' to get device node pointer.) missed drivers/watchdog/mpc8xxx_wdt.c. This patch fixes it Signed-off-by: Michael Guntsche Signed-off-by: Grant Likely --- drivers/watchdog/mpc8xxx_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c index 6622335773bb..4cda64dd309c 100644 --- a/drivers/watchdog/mpc8xxx_wdt.c +++ b/drivers/watchdog/mpc8xxx_wdt.c @@ -189,7 +189,7 @@ static int __devinit mpc8xxx_wdt_probe(struct of_device *ofdev, const struct of_device_id *match) { int ret; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct mpc8xxx_wdt_type *wdt_type = match->data; u32 freq = fsl_get_sys_freq(); bool enabled; -- cgit v1.2.3 From ef7f2e831c3a563505c9bc5b16ef4bcae3cf4b53 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Mon, 31 May 2010 18:34:54 +0200 Subject: of/spi: mpc512x_psc_spi.c: Fix build failures Fixes build errors caused by the: - OF device_node pointer being moved into struct device - removal of the match_table field from struct of_platform_driver Signed-off-by: Anatolij Gustschin Signed-off-by: Grant Likely --- drivers/spi/mpc512x_psc_spi.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/mpc512x_psc_spi.c b/drivers/spi/mpc512x_psc_spi.c index 28a126d2742b..2534b1ec3edd 100644 --- a/drivers/spi/mpc512x_psc_spi.c +++ b/drivers/spi/mpc512x_psc_spi.c @@ -512,29 +512,29 @@ static int __init mpc512x_psc_spi_of_probe(struct of_device *op, u64 regaddr64, size64; s16 id = -1; - regaddr_p = of_get_address(op->node, 0, &size64, NULL); + regaddr_p = of_get_address(op->dev.of_node, 0, &size64, NULL); if (!regaddr_p) { dev_err(&op->dev, "Invalid PSC address\n"); return -EINVAL; } - regaddr64 = of_translate_address(op->node, regaddr_p); + regaddr64 = of_translate_address(op->dev.of_node, regaddr_p); /* get PSC id (0..11, used by port_config) */ if (op->dev.platform_data == NULL) { const u32 *psc_nump; - psc_nump = of_get_property(op->node, "cell-index", NULL); + psc_nump = of_get_property(op->dev.of_node, "cell-index", NULL); if (!psc_nump || *psc_nump > 11) { dev_err(&op->dev, "mpc512x_psc_spi: Device node %s " "has invalid cell-index property\n", - op->node->full_name); + op->dev.of_node->full_name); return -EINVAL; } id = *psc_nump; } return mpc512x_psc_spi_do_probe(&op->dev, (u32) regaddr64, (u32) size64, - irq_of_parse_and_map(op->node, 0), id); + irq_of_parse_and_map(op->dev.of_node, 0), id); } static int __exit mpc512x_psc_spi_of_remove(struct of_device *op) @@ -550,12 +550,12 @@ static struct of_device_id mpc512x_psc_spi_of_match[] = { MODULE_DEVICE_TABLE(of, mpc512x_psc_spi_of_match); static struct of_platform_driver mpc512x_psc_spi_of_driver = { - .match_table = mpc512x_psc_spi_of_match, .probe = mpc512x_psc_spi_of_probe, .remove = __exit_p(mpc512x_psc_spi_of_remove), .driver = { .name = "mpc512x-psc-spi", .owner = THIS_MODULE, + .of_match_table = mpc512x_psc_spi_of_match, }, }; -- cgit v1.2.3 From 14acbbf8bada18f19930d38ce33c3947b2c718e0 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Mon, 31 May 2010 18:37:15 +0200 Subject: of/mtd/nand: mpc5121_nfc.c: Fix build failures Fixes build errors caused by the: - OF device_node pointer being moved into struct device - removal of the match_table field from struct of_platform_driver Signed-off-by: Anatolij Gustschin Signed-off-by: Grant Likely --- drivers/mtd/nand/mpc5121_nfc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c index 3d0867d829cb..0a130dcaa129 100644 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ b/drivers/mtd/nand/mpc5121_nfc.c @@ -650,7 +650,7 @@ static void mpc5121_nfc_free(struct device *dev, struct mtd_info *mtd) static int __devinit mpc5121_nfc_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *rootnode, *dn = op->node; + struct device_node *rootnode, *dn = op->dev.of_node; struct device *dev = &op->dev; struct mpc5121_nfc_prv *prv; struct resource res; @@ -889,12 +889,12 @@ static struct of_device_id mpc5121_nfc_match[] __devinitdata = { }; static struct of_platform_driver mpc5121_nfc_driver = { - .match_table = mpc5121_nfc_match, .probe = mpc5121_nfc_probe, .remove = __devexit_p(mpc5121_nfc_remove), .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = mpc5121_nfc_match, }, }; -- cgit v1.2.3 From b4a75c91b8a6cb80ba7772f69613025ddf75ebc2 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Mon, 31 May 2010 18:39:13 +0200 Subject: of/dma: mpc512x_dma.c: Fix build failures Fixes build errors caused by the: - OF device_node pointer being moved into struct device - removal of the match_table field from struct of_platform_driver Signed-off-by: Anatolij Gustschin Signed-off-by: Grant Likely --- drivers/dma/mpc512x_dma.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 201e6e19c344..14a8c0f1698e 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -630,7 +630,7 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src, static int __devinit mpc_dma_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dn = op->node; + struct device_node *dn = op->dev.of_node; struct device *dev = &op->dev; struct dma_device *dma; struct mpc_dma *mdma; @@ -771,12 +771,12 @@ static struct of_device_id mpc_dma_match[] = { }; static struct of_platform_driver mpc_dma_driver = { - .match_table = mpc_dma_match, .probe = mpc_dma_probe, .remove = __devexit_p(mpc_dma_remove), - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = mpc_dma_match, }, }; -- cgit v1.2.3 From 295bdd9c52e57daf995fe80eff8c53938443fa2f Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 2 Jun 2010 14:06:09 -0600 Subject: of/rtc: rtc-mpc5121.c: Fix build failures Fixes build errors caused by the: - OF device_node pointer being moved into struct device - removal of the match_table field from struct of_platform_driver Signed-off-by: Grant Likely CC: Paul Gortmaker CC: Alessandro Zummo CC: Wolfgang Denk CC: Tejun Heo CC: Anatolij Gustschin CC: rtc-linux@googlegroups.com CC: devicetree-discuss@lists.ozlabs.org --- drivers/rtc/rtc-mpc5121.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index f0dbf9cb8f9c..db5d8c416d26 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c @@ -279,7 +279,7 @@ static int __devinit mpc5121_rtc_probe(struct of_device *op, if (!rtc) return -ENOMEM; - rtc->regs = of_iomap(op->node, 0); + rtc->regs = of_iomap(op->dev.of_node, 0); if (!rtc->regs) { dev_err(&op->dev, "%s: couldn't map io space\n", __func__); err = -ENOSYS; @@ -290,7 +290,7 @@ static int __devinit mpc5121_rtc_probe(struct of_device *op, dev_set_drvdata(&op->dev, rtc); - rtc->irq = irq_of_parse_and_map(op->node, 1); + rtc->irq = irq_of_parse_and_map(op->dev.of_node, 1); err = request_irq(rtc->irq, mpc5121_rtc_handler, IRQF_DISABLED, "mpc5121-rtc", &op->dev); if (err) { @@ -299,7 +299,7 @@ static int __devinit mpc5121_rtc_probe(struct of_device *op, goto out_dispose; } - rtc->irq_periodic = irq_of_parse_and_map(op->node, 0); + rtc->irq_periodic = irq_of_parse_and_map(op->dev.of_node, 0); err = request_irq(rtc->irq_periodic, mpc5121_rtc_handler_upd, IRQF_DISABLED, "mpc5121-rtc_upd", &op->dev); if (err) { @@ -365,9 +365,11 @@ static struct of_device_id mpc5121_rtc_match[] __devinitdata = { }; static struct of_platform_driver mpc5121_rtc_driver = { - .owner = THIS_MODULE, - .name = "mpc5121-rtc", - .match_table = mpc5121_rtc_match, + .driver = { + .name = "mpc5121-rtc", + .owner = THIS_MODULE, + .of_match_table = mpc5121_rtc_match, + }, .probe = mpc5121_rtc_probe, .remove = __devexit_p(mpc5121_rtc_remove), }; -- cgit v1.2.3 From a57ee627499d116f6872a5634ea4f015da0eacd2 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Wed, 2 Jun 2010 11:09:04 -0400 Subject: Fix colors for Mach64 Use the same color-calculating algorithm as in atyfb_imageblit in this driver or in generic cfb_fillrect. This patch fixes bad colors when using an accelerator in 15-bit and 16-bit modes. Signed-off-by: Mikulas Patocka Signed-off-by: Linus Torvalds --- drivers/video/aty/mach64_accel.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/aty/mach64_accel.c b/drivers/video/aty/mach64_accel.c index 51fcc0a2c94a..e45833ce975b 100644 --- a/drivers/video/aty/mach64_accel.c +++ b/drivers/video/aty/mach64_accel.c @@ -242,7 +242,7 @@ void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { struct atyfb_par *par = (struct atyfb_par *) info->par; - u32 color = rect->color, dx = rect->dx, width = rect->width, rotation = 0; + u32 color, dx = rect->dx, width = rect->width, rotation = 0; if (par->asleep) return; @@ -253,8 +253,11 @@ void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) return; } - color |= (rect->color << 8); - color |= (rect->color << 16); + if (info->fix.visual == FB_VISUAL_TRUECOLOR || + info->fix.visual == FB_VISUAL_DIRECTCOLOR) + color = ((u32 *)(info->pseudo_palette))[rect->color]; + else + color = rect->color; if (info->var.bits_per_pixel == 24) { /* In 24 bpp, the engine is in 8 bpp - this requires that all */ -- cgit v1.2.3 From 2005ce3521b7a38f12085e0420f405a8ee06f606 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Thu, 3 Jun 2010 01:38:57 +0200 Subject: of/pcmcia: m8xx_pcmcia.c: Fix build failures Fixes build errors caused by the: - OF device_node pointer being moved into struct device - typo in match_table field in the struct device_driver (which shoud be of_match_table) Signed-off-by: Anatolij Gustschin Signed-off-by: Grant Likely --- drivers/pcmcia/m8xx_pcmcia.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 1a648b90b634..25e5e30a18af 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c @@ -1157,7 +1157,7 @@ static int __init m8xx_probe(struct of_device *ofdev, unsigned int i, m, hwirq; pcmconf8xx_t *pcmcia; int status; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; pcmcia_info("%s\n", version); @@ -1301,7 +1301,7 @@ static struct of_platform_driver m8xx_pcmcia_driver = { .driver = { .name = driver_name, .owner = THIS_MODULE, - .match_table = m8xx_pcmcia_match, + .of_match_table = m8xx_pcmcia_match, }, .probe = m8xx_probe, .remove = m8xx_remove, -- cgit v1.2.3 From d4b8b2c2c0b980fa756267e43e39e5ac3c894857 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Thu, 3 Jun 2010 02:20:44 +0200 Subject: of/video: fix build breakage in FB drivers Fixes build errors in a number of framebuffer drivers caused by the OF device_node pointer being moved into struct device Signed-off-by: Anatolij Gustschin Signed-off-by: Grant Likely --- drivers/video/bw2.c | 2 +- drivers/video/cg14.c | 2 +- drivers/video/cg3.c | 2 +- drivers/video/leo.c | 2 +- drivers/video/mb862xx/mb862xxfb.c | 2 +- drivers/video/p9100.c | 2 +- drivers/video/tcx.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c index 2c371c07f0da..09f1b9b462f4 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/bw2.c @@ -275,7 +275,7 @@ static int __devinit bw2_do_default_mode(struct bw2_par *par, static int __devinit bw2_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct fb_info *info; struct bw2_par *par; int linebytes, err; diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c index d12e05b6e63f..e5dc2241194f 100644 --- a/drivers/video/cg14.c +++ b/drivers/video/cg14.c @@ -465,7 +465,7 @@ static void cg14_unmap_regs(struct of_device *op, struct fb_info *info, static int __devinit cg14_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct fb_info *info; struct cg14_par *par; int is_8mb, linebytes, i, err; diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c index b98f93f7f663..558d73a948a0 100644 --- a/drivers/video/cg3.c +++ b/drivers/video/cg3.c @@ -349,7 +349,7 @@ static int __devinit cg3_do_default_mode(struct cg3_par *par) static int __devinit cg3_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct fb_info *info; struct cg3_par *par; int linebytes, err; diff --git a/drivers/video/leo.c b/drivers/video/leo.c index 3d7895316eaf..9e8bf7d5e249 100644 --- a/drivers/video/leo.c +++ b/drivers/video/leo.c @@ -550,7 +550,7 @@ static void leo_unmap_regs(struct of_device *op, struct fb_info *info, static int __devinit leo_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct fb_info *info; struct leo_par *par; int linebytes, err; diff --git a/drivers/video/mb862xx/mb862xxfb.c b/drivers/video/mb862xx/mb862xxfb.c index 0540de4f5cb4..4e2b8cc3d460 100644 --- a/drivers/video/mb862xx/mb862xxfb.c +++ b/drivers/video/mb862xx/mb862xxfb.c @@ -553,7 +553,7 @@ static int mb862xx_gdc_init(struct mb862xxfb_par *par) static int __devinit of_platform_mb862xx_probe(struct of_device *ofdev, const struct of_device_id *id) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct device *dev = &ofdev->dev; struct mb862xxfb_par *par; struct fb_info *info; diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c index c85dd408a9b8..6552751e81aa 100644 --- a/drivers/video/p9100.c +++ b/drivers/video/p9100.c @@ -251,7 +251,7 @@ static void p9100_init_fix(struct fb_info *info, int linebytes, struct device_no static int __devinit p9100_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct fb_info *info; struct p9100_par *par; int linebytes, err; diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c index ef7a7bd8b503..cc039b33d2d8 100644 --- a/drivers/video/tcx.c +++ b/drivers/video/tcx.c @@ -365,7 +365,7 @@ static void tcx_unmap_regs(struct of_device *op, struct fb_info *info, static int __devinit tcx_probe(struct of_device *op, const struct of_device_id *match) { - struct device_node *dp = op->node; + struct device_node *dp = op->dev.of_node; struct fb_info *info; struct tcx_par *par; int linebytes, i, err; -- cgit v1.2.3 From c8a4d0fd2ac2ce6b3409f51fcf918dcb3617ec97 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Thu, 3 Jun 2010 02:37:17 +0200 Subject: of/mtd: nand: fix build breakage in drivers Fixes build errors in drivers caused by the OF device_node pointer being moved into struct device Signed-off-by: Anatolij Gustschin Signed-off-by: Grant Likely --- drivers/mtd/nand/fsl_upm.c | 17 +++++++++-------- drivers/mtd/nand/socrates_nand.c | 4 ++-- 2 files changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index 00aea6f7d1f1..1312eda57ba6 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c @@ -232,7 +232,7 @@ static int __devinit fun_probe(struct of_device *ofdev, if (!fun) return -ENOMEM; - ret = of_address_to_resource(ofdev->node, 0, &io_res); + ret = of_address_to_resource(ofdev->dev.of_node, 0, &io_res); if (ret) { dev_err(&ofdev->dev, "can't get IO base\n"); goto err1; @@ -244,7 +244,8 @@ static int __devinit fun_probe(struct of_device *ofdev, goto err1; } - prop = of_get_property(ofdev->node, "fsl,upm-addr-offset", &size); + prop = of_get_property(ofdev->dev.of_node, "fsl,upm-addr-offset", + &size); if (!prop || size != sizeof(uint32_t)) { dev_err(&ofdev->dev, "can't get UPM address offset\n"); ret = -EINVAL; @@ -252,7 +253,7 @@ static int __devinit fun_probe(struct of_device *ofdev, } fun->upm_addr_offset = *prop; - prop = of_get_property(ofdev->node, "fsl,upm-cmd-offset", &size); + prop = of_get_property(ofdev->dev.of_node, "fsl,upm-cmd-offset", &size); if (!prop || size != sizeof(uint32_t)) { dev_err(&ofdev->dev, "can't get UPM command offset\n"); ret = -EINVAL; @@ -260,7 +261,7 @@ static int __devinit fun_probe(struct of_device *ofdev, } fun->upm_cmd_offset = *prop; - prop = of_get_property(ofdev->node, + prop = of_get_property(ofdev->dev.of_node, "fsl,upm-addr-line-cs-offsets", &size); if (prop && (size / sizeof(uint32_t)) > 0) { fun->mchip_count = size / sizeof(uint32_t); @@ -276,7 +277,7 @@ static int __devinit fun_probe(struct of_device *ofdev, for (i = 0; i < fun->mchip_count; i++) { fun->rnb_gpio[i] = -1; - rnb_gpio = of_get_gpio(ofdev->node, i); + rnb_gpio = of_get_gpio(ofdev->dev.of_node, i); if (rnb_gpio >= 0) { ret = gpio_request(rnb_gpio, dev_name(&ofdev->dev)); if (ret) { @@ -292,13 +293,13 @@ static int __devinit fun_probe(struct of_device *ofdev, } } - prop = of_get_property(ofdev->node, "chip-delay", NULL); + prop = of_get_property(ofdev->dev.of_node, "chip-delay", NULL); if (prop) fun->chip_delay = *prop; else fun->chip_delay = 50; - prop = of_get_property(ofdev->node, "fsl,upm-wait-flags", &size); + prop = of_get_property(ofdev->dev.of_node, "fsl,upm-wait-flags", &size); if (prop && size == sizeof(uint32_t)) fun->wait_flags = *prop; else @@ -315,7 +316,7 @@ static int __devinit fun_probe(struct of_device *ofdev, fun->dev = &ofdev->dev; fun->last_ctrl = NAND_CLE; - ret = fun_chip_init(fun, ofdev->node, &io_res); + ret = fun_chip_init(fun, ofdev->dev.of_node, &io_res); if (ret) goto err2; diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c index 884852dc7eb4..cc728b12de82 100644 --- a/drivers/mtd/nand/socrates_nand.c +++ b/drivers/mtd/nand/socrates_nand.c @@ -183,7 +183,7 @@ static int __devinit socrates_nand_probe(struct of_device *ofdev, return -ENOMEM; } - host->io_base = of_iomap(ofdev->node, 0); + host->io_base = of_iomap(ofdev->dev.of_node, 0); if (host->io_base == NULL) { printk(KERN_ERR "socrates_nand: ioremap failed\n"); kfree(host); @@ -244,7 +244,7 @@ static int __devinit socrates_nand_probe(struct of_device *ofdev, #ifdef CONFIG_MTD_OF_PARTS if (num_partitions == 0) { num_partitions = of_mtd_parse_partitions(&ofdev->dev, - ofdev->node, + ofdev->dev.of_node, &partitions); if (num_partitions < 0) { res = num_partitions; -- cgit v1.2.3 From 05c02542c20aa00dc9a66f4bfb1a89d1131457f2 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Thu, 3 Jun 2010 02:46:37 +0200 Subject: of/dma: fix build breakage in ppc4xx adma driver Fixes build error caused by the OF device_node pointer being moved into struct device Signed-off-by: Anatolij Gustschin Signed-off-by: Grant Likely --- drivers/dma/ppc4xx/adma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index fa98abe4686f..5a22ca6927e5 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -4394,7 +4394,7 @@ static void ppc440spe_adma_release_irqs(struct ppc440spe_adma_device *adev, static int __devinit ppc440spe_adma_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct resource res; struct ppc440spe_adma_device *adev; struct ppc440spe_adma_chan *chan; @@ -4626,7 +4626,7 @@ out: static int __devexit ppc440spe_adma_remove(struct of_device *ofdev) { struct ppc440spe_adma_device *adev = dev_get_drvdata(&ofdev->dev); - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct resource res; struct dma_chan *chan, *_chan; struct ppc_dma_chan_ref *ref, *_ref; -- cgit v1.2.3 From 7cea8cc4705d25d9c7baee06efd665db27481242 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Thu, 3 Jun 2010 02:53:18 +0200 Subject: of/crypto: crypto4xx_core.c: fix build breakage Fixes build error caused by the OF device_node pointer being moved into struct device Signed-off-by: Anatolij Gustschin Signed-off-by: Grant Likely --- drivers/crypto/amcc/crypto4xx_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c index 9d65b371de64..983530ba04a7 100644 --- a/drivers/crypto/amcc/crypto4xx_core.c +++ b/drivers/crypto/amcc/crypto4xx_core.c @@ -1158,7 +1158,7 @@ static int __init crypto4xx_probe(struct of_device *ofdev, struct device *dev = &ofdev->dev; struct crypto4xx_core_device *core_dev; - rc = of_address_to_resource(ofdev->node, 0, &res); + rc = of_address_to_resource(ofdev->dev.of_node, 0, &res); if (rc) return -ENODEV; @@ -1215,13 +1215,13 @@ static int __init crypto4xx_probe(struct of_device *ofdev, (unsigned long) dev); /* Register for Crypto isr, Crypto Engine IRQ */ - core_dev->irq = irq_of_parse_and_map(ofdev->node, 0); + core_dev->irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); rc = request_irq(core_dev->irq, crypto4xx_ce_interrupt_handler, 0, core_dev->dev->name, dev); if (rc) goto err_request_irq; - core_dev->dev->ce_base = of_iomap(ofdev->node, 0); + core_dev->dev->ce_base = of_iomap(ofdev->dev.of_node, 0); if (!core_dev->dev->ce_base) { dev_err(dev, "failed to of_iomap\n"); goto err_iomap; -- cgit v1.2.3 From 3ed3880230288c3eba1174b865ea7cdfbcb20033 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Thu, 3 Jun 2010 02:59:55 +0200 Subject: of/usb: fsl_qe_udc.c: fix build breakage Fixes build error caused by the OF device_node pointer being moved into struct device Signed-off-by: Anatolij Gustschin Signed-off-by: Grant Likely --- drivers/usb/gadget/fsl_qe_udc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index 2928523268b5..82506ca297d5 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -2400,7 +2400,7 @@ EXPORT_SYMBOL(usb_gadget_unregister_driver); static struct qe_udc __devinit *qe_udc_config(struct of_device *ofdev) { struct qe_udc *udc; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; unsigned int tmp_addr = 0; struct usb_device_para __iomem *usbpram; unsigned int i; @@ -2525,7 +2525,7 @@ static void qe_udc_release(struct device *dev) static int __devinit qe_udc_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct qe_ep *ep; unsigned int ret = 0; unsigned int i; -- cgit v1.2.3 From 4eecb17825a9cd2ea750c177487000fab4c19ea2 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Thu, 3 Jun 2010 03:06:54 +0200 Subject: of/net: fs_enet/mii-bitbang.c: fix build breakage Fixes build error caused by the OF device_node pointer being moved into struct device Signed-off-by: Anatolij Gustschin Signed-off-by: Grant Likely --- drivers/net/fs_enet/mii-bitbang.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c index 0f90685d3d19..3607340f3da7 100644 --- a/drivers/net/fs_enet/mii-bitbang.c +++ b/drivers/net/fs_enet/mii-bitbang.c @@ -169,7 +169,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, new_bus->name = "CPM2 Bitbanged MII", - ret = fs_mii_bitbang_init(new_bus, ofdev->node); + ret = fs_mii_bitbang_init(new_bus, ofdev->dev.of_node); if (ret) goto out_free_bus; @@ -181,7 +181,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, new_bus->parent = &ofdev->dev; dev_set_drvdata(&ofdev->dev, new_bus); - ret = of_mdiobus_register(new_bus, ofdev->node); + ret = of_mdiobus_register(new_bus, ofdev->dev.of_node); if (ret) goto out_free_irqs; -- cgit v1.2.3 From a26f95fed31d917eee616d1cd6360e4ce782e3dc Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Thu, 3 Jun 2010 03:17:42 +0200 Subject: of/edac: fix build breakage in drivers Fixes build errors in EDAC drivers caused by the OF device_node pointer being moved into struct device Signed-off-by: Anatolij Gustschin Signed-off-by: Grant Likely --- drivers/edac/mpc85xx_edac.c | 12 ++++++------ drivers/edac/ppc4xx_edac.c | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index 6c1886b497ff..52ca09bf4726 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c @@ -229,7 +229,7 @@ static int __devinit mpc85xx_pci_err_probe(struct of_device *op, pdata->edac_idx = edac_pci_idx++; - res = of_address_to_resource(op->node, 0, &r); + res = of_address_to_resource(op->dev.of_node, 0, &r); if (res) { printk(KERN_ERR "%s: Unable to get resource for " "PCI err regs\n", __func__); @@ -274,7 +274,7 @@ static int __devinit mpc85xx_pci_err_probe(struct of_device *op, } if (edac_op_state == EDAC_OPSTATE_INT) { - pdata->irq = irq_of_parse_and_map(op->node, 0); + pdata->irq = irq_of_parse_and_map(op->dev.of_node, 0); res = devm_request_irq(&op->dev, pdata->irq, mpc85xx_pci_isr, IRQF_DISABLED, "[EDAC] PCI err", pci); @@ -529,7 +529,7 @@ static int __devinit mpc85xx_l2_err_probe(struct of_device *op, edac_dev->ctl_name = pdata->name; edac_dev->dev_name = pdata->name; - res = of_address_to_resource(op->node, 0, &r); + res = of_address_to_resource(op->dev.of_node, 0, &r); if (res) { printk(KERN_ERR "%s: Unable to get resource for " "L2 err regs\n", __func__); @@ -576,7 +576,7 @@ static int __devinit mpc85xx_l2_err_probe(struct of_device *op, } if (edac_op_state == EDAC_OPSTATE_INT) { - pdata->irq = irq_of_parse_and_map(op->node, 0); + pdata->irq = irq_of_parse_and_map(op->dev.of_node, 0); res = devm_request_irq(&op->dev, pdata->irq, mpc85xx_l2_isr, IRQF_DISABLED, "[EDAC] L2 err", edac_dev); @@ -978,7 +978,7 @@ static int __devinit mpc85xx_mc_err_probe(struct of_device *op, mci->ctl_name = pdata->name; mci->dev_name = pdata->name; - res = of_address_to_resource(op->node, 0, &r); + res = of_address_to_resource(op->dev.of_node, 0, &r); if (res) { printk(KERN_ERR "%s: Unable to get resource for MC err regs\n", __func__); @@ -1052,7 +1052,7 @@ static int __devinit mpc85xx_mc_err_probe(struct of_device *op, out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_SBE, 0x10000); /* register interrupts */ - pdata->irq = irq_of_parse_and_map(op->node, 0); + pdata->irq = irq_of_parse_and_map(op->dev.of_node, 0); res = devm_request_irq(&op->dev, pdata->irq, mpc85xx_mc_isr, IRQF_DISABLED | IRQF_SHARED, diff --git a/drivers/edac/ppc4xx_edac.c b/drivers/edac/ppc4xx_edac.c index 9d6f6783328c..e78839e89a06 100644 --- a/drivers/edac/ppc4xx_edac.c +++ b/drivers/edac/ppc4xx_edac.c @@ -1022,7 +1022,7 @@ ppc4xx_edac_mc_init(struct mem_ctl_info *mci, int status = 0; const u32 memcheck = (mcopt1 & SDRAM_MCOPT1_MCHK_MASK); struct ppc4xx_edac_pdata *pdata = NULL; - const struct device_node *np = op->node; + const struct device_node *np = op->dev.of_node; if (match == NULL) return -EINVAL; @@ -1113,7 +1113,7 @@ ppc4xx_edac_register_irq(struct of_device *op, struct mem_ctl_info *mci) int status = 0; int ded_irq, sec_irq; struct ppc4xx_edac_pdata *pdata = mci->pvt_info; - struct device_node *np = op->node; + struct device_node *np = op->dev.of_node; ded_irq = irq_of_parse_and_map(np, INTMAP_ECCDED_INDEX); sec_irq = irq_of_parse_and_map(np, INTMAP_ECCSEC_INDEX); @@ -1243,7 +1243,7 @@ ppc4xx_edac_probe(struct of_device *op, const struct of_device_id *match) int status = 0; u32 mcopt1, memcheck; dcr_host_t dcr_host; - const struct device_node *np = op->node; + const struct device_node *np = op->dev.of_node; struct mem_ctl_info *mci = NULL; static int ppc4xx_edac_instance; -- cgit v1.2.3 From b74dbf2aed8d8c4f93ac2c44bab5c81f65be62a0 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Thu, 3 Jun 2010 03:30:31 +0200 Subject: of/watchdog: gef_wdt.c: fix build breakage Fixes build error caused by the OF device_node pointer being moved into struct device Signed-off-by: Anatolij Gustschin Signed-off-by: Grant Likely --- drivers/watchdog/gef_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c index ca0f4c6cf5ab..1df284f9c2a1 100644 --- a/drivers/watchdog/gef_wdt.c +++ b/drivers/watchdog/gef_wdt.c @@ -273,7 +273,7 @@ static int __devinit gef_wdt_probe(struct of_device *dev, bus_clk = freq; /* Map devices registers into memory */ - gef_wdt_regs = of_iomap(dev->node, 0); + gef_wdt_regs = of_iomap(dev->dev.of_node, 0); if (gef_wdt_regs == NULL) return -ENOMEM; -- cgit v1.2.3 From 7ac9aa5a1f1b87adb69bcbec2b89e228f074103a Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 27 May 2010 19:25:54 -0400 Subject: drm/radeon/kms/pm: add support for SetVoltage cmd table (V2) - This enables voltage adjustment on r6xx+ and certain r5xx asics. - Voltage drop support is already available for most r1xx-r5xx asics. V2: endian fix for voltage table. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600.c | 6 ++++++ drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_atombios.c | 36 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/rs600.c | 3 ++- 4 files changed, 45 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 44e96a2ae25a..e14f59748e65 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -475,6 +475,12 @@ void r600_pm_init_profile(struct radeon_device *rdev) void r600_pm_misc(struct radeon_device *rdev) { + int requested_index = rdev->pm.requested_power_state_index; + struct radeon_power_state *ps = &rdev->pm.power_state[requested_index]; + struct radeon_voltage *voltage = &ps->clock_info[0].voltage; + + if ((voltage->type == VOLTAGE_SW) && voltage->voltage) + radeon_atom_set_voltage(rdev, voltage->voltage); } diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 669feb689bfc..5f96fe871b3f 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -176,6 +176,7 @@ void radeon_pm_suspend(struct radeon_device *rdev); void radeon_pm_resume(struct radeon_device *rdev); void radeon_combios_get_power_modes(struct radeon_device *rdev); void radeon_atombios_get_power_modes(struct radeon_device *rdev); +void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level); /* * Fences. diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 24ea683f7cf5..24ebb4ea7984 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1998,6 +1998,42 @@ void radeon_atom_set_memory_clock(struct radeon_device *rdev, atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } +union set_voltage { + struct _SET_VOLTAGE_PS_ALLOCATION alloc; + struct _SET_VOLTAGE_PARAMETERS v1; + struct _SET_VOLTAGE_PARAMETERS_V2 v2; +}; + +void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level) +{ + union set_voltage args; + int index = GetIndexIntoMasterTable(COMMAND, SetVoltage); + u8 frev, crev, volt_index = level; + + if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) + return; + + switch (crev) { + case 1: + args.v1.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC; + args.v1.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_ALL_SOURCE; + args.v1.ucVoltageIndex = volt_index; + break; + case 2: + args.v2.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC; + args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE; + args.v2.usVoltageLevel = cpu_to_le16(level); + break; + default: + DRM_ERROR("Unknown table version %d, %d\n", frev, crev); + return; + } + + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); +} + + + void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) { struct radeon_device *rdev = dev->dev_private; diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 79887cac5b54..7bb4c3e52f3b 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -74,7 +74,8 @@ void rs600_pm_misc(struct radeon_device *rdev) if (voltage->delay) udelay(voltage->delay); } - } + } else if (voltage->type == VOLTAGE_VDDC) + radeon_atom_set_voltage(rdev, voltage->vddc_id); dyn_pwrmgt_sclk_length = RREG32_PLL(DYN_PWRMGT_SCLK_LENGTH); dyn_pwrmgt_sclk_length &= ~REDUCED_POWER_SCLK_HILEN(0xf); -- cgit v1.2.3 From 9349d5cc920c10845693f906ebd67f394f1d0d04 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 28 May 2010 19:35:01 -0400 Subject: drm/radeon/kms/pm: enable SetVoltage on r7xx/evergreen I missed these in the r6xx commit. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 5 +++++ drivers/gpu/drm/radeon/rv770.c | 5 +++++ 2 files changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 8c8e4d3cbaa3..0440c0939bdd 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -41,7 +41,12 @@ void evergreen_fini(struct radeon_device *rdev); void evergreen_pm_misc(struct radeon_device *rdev) { + int requested_index = rdev->pm.requested_power_state_index; + struct radeon_power_state *ps = &rdev->pm.power_state[requested_index]; + struct radeon_voltage *voltage = &ps->clock_info[0].voltage; + if ((voltage->type == VOLTAGE_SW) && voltage->voltage) + radeon_atom_set_voltage(rdev, voltage->voltage); } void evergreen_pm_prepare(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 253f24aec031..33952da65340 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -44,7 +44,12 @@ void rv770_fini(struct radeon_device *rdev); void rv770_pm_misc(struct radeon_device *rdev) { + int requested_index = rdev->pm.requested_power_state_index; + struct radeon_power_state *ps = &rdev->pm.power_state[requested_index]; + struct radeon_voltage *voltage = &ps->clock_info[0].voltage; + if ((voltage->type == VOLTAGE_SW) && voltage->voltage) + radeon_atom_set_voltage(rdev, voltage->voltage); } /* -- cgit v1.2.3 From c5e8ce61d64995f4076c6a9b2f8b4b71e0be2e37 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 27 May 2010 17:01:40 -0400 Subject: drm/radeon/kms/pm: patch default power state with default clocks/voltages on r6xx+ The default power state does not always match the default clocks and voltage for a particular card. The information in the firmware info table is correct and should be used in preference to the info the default power state. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_atombios.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 24ebb4ea7984..42bcaf41b8c4 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1755,9 +1755,22 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) rdev->pm.power_state[state_index].misc2 = 0; } } else { + int fw_index = GetIndexIntoMasterTable(DATA, FirmwareInfo); + uint8_t fw_frev, fw_crev; + uint16_t fw_data_offset, vddc = 0; + union firmware_info *firmware_info; + ATOM_PPLIB_THERMALCONTROLLER *controller = &power_info->info_4.sThermalController; + + if (atom_parse_data_header(mode_info->atom_context, fw_index, NULL, + &fw_frev, &fw_crev, &fw_data_offset)) { + firmware_info = + (union firmware_info *)(mode_info->atom_context->bios + + fw_data_offset); + vddc = firmware_info->info_14.usBootUpVDDCVoltage; + } + /* add the i2c bus for thermal/fan chip */ /* no support for internal controller yet */ - ATOM_PPLIB_THERMALCONTROLLER *controller = &power_info->info_4.sThermalController; if (controller->ucType > 0) { if ((controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) || (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) || @@ -1904,6 +1917,16 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) rdev->pm.default_power_state_index = state_index; rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; + /* patch the table values with the default slck/mclk from firmware info */ + for (j = 0; j < mode_index; j++) { + rdev->pm.power_state[state_index].clock_info[j].mclk = + rdev->clock.default_mclk; + rdev->pm.power_state[state_index].clock_info[j].sclk = + rdev->clock.default_sclk; + if (vddc) + rdev->pm.power_state[state_index].clock_info[j].voltage.voltage = + vddc; + } } state_index++; } -- cgit v1.2.3 From 92645879d07a48897fe8888c2e37607aa1189cc9 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 27 May 2010 17:01:41 -0400 Subject: drm/radeon/kms/pm: radeon_set_power_state fixes - wait for vbl for both profile and dynpm - unify profile and dynpm code paths more - call pm_misc before of after clocks to make sure voltage is changed in the proper order. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_pm.c | 75 +++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index a8d162c6f829..02281269a881 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -151,6 +151,7 @@ static void radeon_sync_with_vblank(struct radeon_device *rdev) static void radeon_set_power_state(struct radeon_device *rdev) { u32 sclk, mclk; + bool misc_after = false; if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) && (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index)) @@ -167,55 +168,47 @@ static void radeon_set_power_state(struct radeon_device *rdev) if (mclk > rdev->clock.default_mclk) mclk = rdev->clock.default_mclk; - /* voltage, pcie lanes, etc.*/ - radeon_pm_misc(rdev); + /* upvolt before raising clocks, downvolt after lowering clocks */ + if (sclk < rdev->pm.current_sclk) + misc_after = true; - if (rdev->pm.pm_method == PM_METHOD_DYNPM) { - radeon_sync_with_vblank(rdev); + radeon_sync_with_vblank(rdev); + if (rdev->pm.pm_method == PM_METHOD_DYNPM) { if (!radeon_pm_in_vbl(rdev)) return; + } - radeon_pm_prepare(rdev); - /* set engine clock */ - if (sclk != rdev->pm.current_sclk) { - radeon_pm_debug_check_in_vbl(rdev, false); - radeon_set_engine_clock(rdev, sclk); - radeon_pm_debug_check_in_vbl(rdev, true); - rdev->pm.current_sclk = sclk; - DRM_DEBUG("Setting: e: %d\n", sclk); - } + radeon_pm_prepare(rdev); - /* set memory clock */ - if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { - radeon_pm_debug_check_in_vbl(rdev, false); - radeon_set_memory_clock(rdev, mclk); - radeon_pm_debug_check_in_vbl(rdev, true); - rdev->pm.current_mclk = mclk; - DRM_DEBUG("Setting: m: %d\n", mclk); - } - radeon_pm_finish(rdev); - } else { - /* set engine clock */ - if (sclk != rdev->pm.current_sclk) { - radeon_sync_with_vblank(rdev); - radeon_pm_prepare(rdev); - radeon_set_engine_clock(rdev, sclk); - radeon_pm_finish(rdev); - rdev->pm.current_sclk = sclk; - DRM_DEBUG("Setting: e: %d\n", sclk); - } - /* set memory clock */ - if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { - radeon_sync_with_vblank(rdev); - radeon_pm_prepare(rdev); - radeon_set_memory_clock(rdev, mclk); - radeon_pm_finish(rdev); - rdev->pm.current_mclk = mclk; - DRM_DEBUG("Setting: m: %d\n", mclk); - } + if (!misc_after) + /* voltage, pcie lanes, etc.*/ + radeon_pm_misc(rdev); + + /* set engine clock */ + if (sclk != rdev->pm.current_sclk) { + radeon_pm_debug_check_in_vbl(rdev, false); + radeon_set_engine_clock(rdev, sclk); + radeon_pm_debug_check_in_vbl(rdev, true); + rdev->pm.current_sclk = sclk; + DRM_DEBUG("Setting: e: %d\n", sclk); + } + + /* set memory clock */ + if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { + radeon_pm_debug_check_in_vbl(rdev, false); + radeon_set_memory_clock(rdev, mclk); + radeon_pm_debug_check_in_vbl(rdev, true); + rdev->pm.current_mclk = mclk; + DRM_DEBUG("Setting: m: %d\n", mclk); } + if (misc_after) + /* voltage, pcie lanes, etc.*/ + radeon_pm_misc(rdev); + + radeon_pm_finish(rdev); + rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index; rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index; } else -- cgit v1.2.3 From 84d88f4c92763f519b9e081cdd685a44de14f8c0 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 27 May 2010 17:01:42 -0400 Subject: drm/radeon/kms/pm: voltage fixes - Enable GPIO voltage for non pm modes as well so resetting the default voltage works. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_atombios.c | 9 ++++++--- drivers/gpu/drm/radeon/radeon_combios.c | 7 ++++++- 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 42bcaf41b8c4..4305cd55d0ac 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1538,7 +1538,8 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) rdev->pm.power_state[state_index].pcie_lanes = power_info->info.asPowerPlayInfo[i].ucNumPciELanes; misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo); - if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { + if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || + (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_GPIO; rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = @@ -1605,7 +1606,8 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes; misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo); misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2); - if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { + if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || + (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_GPIO; rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = @@ -1679,7 +1681,8 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes; misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo); misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2); - if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { + if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || + (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_GPIO; rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 7b5e10d3e9c9..102c744eaf5a 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -2454,7 +2454,12 @@ default_mode: rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0]; - rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; + if ((state_index > 0) && + (rdev->pm.power_state[0].clock_info[0].voltage.type = VOLTAGE_GPIO)) + rdev->pm.power_state[state_index].clock_info[0].voltage = + rdev->pm.power_state[0].clock_info[0].voltage; + else + rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; rdev->pm.power_state[state_index].pcie_lanes = 16; rdev->pm.power_state[state_index].flags = 0; rdev->pm.default_power_state_index = state_index; -- cgit v1.2.3 From 2d6e9b91971034103ac51b20fa692258bf6bdd40 Mon Sep 17 00:00:00 2001 From: Tiago Vignatti Date: Mon, 24 May 2010 18:24:30 +0300 Subject: vgaarb: convert pr_devel() to pr_debug() We want to be able to use CONFIG_DYNAMIC_DEBUG in arbiter code, switch the few existing pr_devel() calls to pr_debug(). Also, add one more debug information regarding decoding count. Signed-off-by: Tiago Vignatti Signed-off-by: Dave Airlie --- drivers/gpu/vga/vgaarb.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index 441e38c95a85..290b0ccea63d 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c @@ -155,8 +155,8 @@ static struct vga_device *__vga_tryget(struct vga_device *vgadev, (vgadev->decodes & VGA_RSRC_LEGACY_MEM)) rsrc |= VGA_RSRC_LEGACY_MEM; - pr_devel("%s: %d\n", __func__, rsrc); - pr_devel("%s: owns: %d\n", __func__, vgadev->owns); + pr_debug("%s: %d\n", __func__, rsrc); + pr_debug("%s: owns: %d\n", __func__, vgadev->owns); /* Check what resources we need to acquire */ wants = rsrc & ~vgadev->owns; @@ -268,7 +268,7 @@ static void __vga_put(struct vga_device *vgadev, unsigned int rsrc) { unsigned int old_locks = vgadev->locks; - pr_devel("%s\n", __func__); + pr_debug("%s\n", __func__); /* Update our counters, and account for equivalent legacy resources * if we decode them @@ -575,6 +575,7 @@ static inline void vga_update_device_decodes(struct vga_device *vgadev, else vga_decode_count--; } + pr_debug("vgaarb: decoding count now is: %d\n", vga_decode_count); } void __vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes, bool userspace) @@ -831,7 +832,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf, curr_pos += 5; remaining -= 5; - pr_devel("client 0x%p called 'lock'\n", priv); + pr_debug("client 0x%p called 'lock'\n", priv); if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) { ret_val = -EPROTO; @@ -867,7 +868,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf, curr_pos += 7; remaining -= 7; - pr_devel("client 0x%p called 'unlock'\n", priv); + pr_debug("client 0x%p called 'unlock'\n", priv); if (strncmp(curr_pos, "all", 3) == 0) io_state = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM; @@ -917,7 +918,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf, curr_pos += 8; remaining -= 8; - pr_devel("client 0x%p called 'trylock'\n", priv); + pr_debug("client 0x%p called 'trylock'\n", priv); if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) { ret_val = -EPROTO; @@ -961,7 +962,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf, curr_pos += 7; remaining -= 7; - pr_devel("client 0x%p called 'target'\n", priv); + pr_debug("client 0x%p called 'target'\n", priv); /* if target is default */ if (!strncmp(curr_pos, "default", 7)) pdev = pci_dev_get(vga_default_device()); @@ -971,11 +972,11 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf, ret_val = -EPROTO; goto done; } - pr_devel("vgaarb: %s ==> %x:%x:%x.%x\n", curr_pos, + pr_debug("vgaarb: %s ==> %x:%x:%x.%x\n", curr_pos, domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); pbus = pci_find_bus(domain, bus); - pr_devel("vgaarb: pbus %p\n", pbus); + pr_debug("vgaarb: pbus %p\n", pbus); if (pbus == NULL) { pr_err("vgaarb: invalid PCI domain and/or bus address %x:%x\n", domain, bus); @@ -983,7 +984,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf, goto done; } pdev = pci_get_slot(pbus, devfn); - pr_devel("vgaarb: pdev %p\n", pdev); + pr_debug("vgaarb: pdev %p\n", pdev); if (!pdev) { pr_err("vgaarb: invalid PCI address %x:%x\n", bus, devfn); @@ -993,7 +994,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf, } vgadev = vgadev_find(pdev); - pr_devel("vgaarb: vgadev %p\n", vgadev); + pr_debug("vgaarb: vgadev %p\n", vgadev); if (vgadev == NULL) { pr_err("vgaarb: this pci device is not a vga device\n"); pci_dev_put(pdev); @@ -1029,7 +1030,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf, } else if (strncmp(curr_pos, "decodes ", 8) == 0) { curr_pos += 8; remaining -= 8; - pr_devel("vgaarb: client 0x%p called 'decodes'\n", priv); + pr_debug("vgaarb: client 0x%p called 'decodes'\n", priv); if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) { ret_val = -EPROTO; @@ -1058,7 +1059,7 @@ static unsigned int vga_arb_fpoll(struct file *file, poll_table * wait) { struct vga_arb_private *priv = file->private_data; - pr_devel("%s\n", __func__); + pr_debug("%s\n", __func__); if (priv == NULL) return -ENODEV; @@ -1071,7 +1072,7 @@ static int vga_arb_open(struct inode *inode, struct file *file) struct vga_arb_private *priv; unsigned long flags; - pr_devel("%s\n", __func__); + pr_debug("%s\n", __func__); priv = kmalloc(sizeof(struct vga_arb_private), GFP_KERNEL); if (priv == NULL) @@ -1101,7 +1102,7 @@ static int vga_arb_release(struct inode *inode, struct file *file) unsigned long flags; int i; - pr_devel("%s\n", __func__); + pr_debug("%s\n", __func__); if (priv == NULL) return -ENODEV; @@ -1112,7 +1113,7 @@ static int vga_arb_release(struct inode *inode, struct file *file) uc = &priv->cards[i]; if (uc->pdev == NULL) continue; - pr_devel("uc->io_cnt == %d, uc->mem_cnt == %d\n", + pr_debug("uc->io_cnt == %d, uc->mem_cnt == %d\n", uc->io_cnt, uc->mem_cnt); while (uc->io_cnt--) vga_put(uc->pdev, VGA_RSRC_LEGACY_IO); @@ -1165,7 +1166,7 @@ static int pci_notify(struct notifier_block *nb, unsigned long action, struct pci_dev *pdev = to_pci_dev(dev); bool notify = false; - pr_devel("%s\n", __func__); + pr_debug("%s\n", __func__); /* For now we're only intereted in devices added and removed. I didn't * test this thing here, so someone needs to double check for the -- cgit v1.2.3 From c0db9cbc73338d8e2987a19a02388d67aeec0bfe Mon Sep 17 00:00:00 2001 From: Tiago Vignatti Date: Mon, 24 May 2010 18:24:31 +0300 Subject: vgaarb: use MIT license Signed-off-by: Tiago Vignatti Cc: Henry Zhao Signed-off-by: Dave Airlie --- drivers/gpu/vga/vgaarb.c | 26 +++++++++++++++++++++++--- include/linux/vgaarb.h | 21 +++++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index 290b0ccea63d..b87569e96b16 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c @@ -1,12 +1,32 @@ /* - * vgaarb.c + * vgaarb.c: Implements the VGA arbitration. For details refer to + * Documentation/vgaarbiter.txt + * * * (C) Copyright 2005 Benjamin Herrenschmidt * (C) Copyright 2007 Paulo R. Zanoni * (C) Copyright 2007, 2009 Tiago Vignatti * - * Implements the VGA arbitration. For details refer to - * Documentation/vgaarbiter.txt + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS + * IN THE SOFTWARE. + * */ #include diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h index 2dfaa293ae8c..c9a975976995 100644 --- a/include/linux/vgaarb.h +++ b/include/linux/vgaarb.h @@ -5,6 +5,27 @@ * (C) Copyright 2005 Benjamin Herrenschmidt * (C) Copyright 2007 Paulo R. Zanoni * (C) Copyright 2007, 2009 Tiago Vignatti + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS + * IN THE SOFTWARE. + * */ #ifndef LINUX_VGA_H -- cgit v1.2.3 From 7c4f77801f103c9eb0465bf42313d5e1721d2991 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 1 Jun 2010 11:38:17 +0200 Subject: drm/vmwgfx: Fix vga save / restore with display topology. vga save / restore previously didn't handle the display topology case. Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 15 +++++++++++- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 48 ++++++++++++++++++++++++++++++++----- 2 files changed, 56 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 1341adef408d..e577af5bb3d6 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -47,6 +47,7 @@ #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) #define VMWGFX_MAX_RELOCATIONS 2048 #define VMWGFX_MAX_GMRS 2048 +#define VMWGFX_MAX_DISPLAYS 16 struct vmw_fpriv { struct drm_master *locked_master; @@ -152,6 +153,14 @@ struct vmw_master { struct ttm_lock lock; }; +struct vmw_vga_topology_state { + uint32_t width; + uint32_t height; + uint32_t primary; + uint32_t pos_x; + uint32_t pos_y; +}; + struct vmw_private { struct ttm_bo_device bdev; struct ttm_bo_global_ref bo_global_ref; @@ -179,16 +188,20 @@ struct vmw_private { * VGA registers. */ + struct vmw_vga_topology_state vga_save[VMWGFX_MAX_DISPLAYS]; uint32_t vga_width; uint32_t vga_height; uint32_t vga_depth; uint32_t vga_bpp; uint32_t vga_pseudo; uint32_t vga_red_mask; - uint32_t vga_blue_mask; uint32_t vga_green_mask; + uint32_t vga_blue_mask; + uint32_t vga_bpl; uint32_t vga_pitchlock; + uint32_t num_displays; + /* * Framebuffer info. */ diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index b78dcf001858..648ba044f6f8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -865,30 +865,52 @@ void vmw_kms_write_svga(struct vmw_private *vmw_priv, int vmw_kms_save_vga(struct vmw_private *vmw_priv) { + struct vmw_vga_topology_state *save; + uint32_t i; + vmw_priv->vga_width = vmw_read(vmw_priv, SVGA_REG_WIDTH); vmw_priv->vga_height = vmw_read(vmw_priv, SVGA_REG_HEIGHT); - vmw_priv->vga_bpp = vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL); vmw_priv->vga_depth = vmw_read(vmw_priv, SVGA_REG_DEPTH); + vmw_priv->vga_bpp = vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL); vmw_priv->vga_pseudo = vmw_read(vmw_priv, SVGA_REG_PSEUDOCOLOR); vmw_priv->vga_red_mask = vmw_read(vmw_priv, SVGA_REG_RED_MASK); - vmw_priv->vga_green_mask = vmw_read(vmw_priv, SVGA_REG_GREEN_MASK); vmw_priv->vga_blue_mask = vmw_read(vmw_priv, SVGA_REG_BLUE_MASK); + vmw_priv->vga_green_mask = vmw_read(vmw_priv, SVGA_REG_GREEN_MASK); if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK) vmw_priv->vga_pitchlock = - vmw_read(vmw_priv, SVGA_REG_PITCHLOCK); + vmw_read(vmw_priv, SVGA_REG_PITCHLOCK); else if (vmw_fifo_have_pitchlock(vmw_priv)) - vmw_priv->vga_pitchlock = - ioread32(vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK); + vmw_priv->vga_pitchlock = ioread32(vmw_priv->mmio_virt + + SVGA_FIFO_PITCHLOCK); + + if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY)) + return 0; + vmw_priv->num_displays = vmw_read(vmw_priv, + SVGA_REG_NUM_GUEST_DISPLAYS); + + for (i = 0; i < vmw_priv->num_displays; ++i) { + save = &vmw_priv->vga_save[i]; + vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, i); + save->primary = vmw_read(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY); + save->pos_x = vmw_read(vmw_priv, SVGA_REG_DISPLAY_POSITION_X); + save->pos_y = vmw_read(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y); + save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH); + save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); + } return 0; } int vmw_kms_restore_vga(struct vmw_private *vmw_priv) { + struct vmw_vga_topology_state *save; + uint32_t i; + vmw_write(vmw_priv, SVGA_REG_WIDTH, vmw_priv->vga_width); vmw_write(vmw_priv, SVGA_REG_HEIGHT, vmw_priv->vga_height); - vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, vmw_priv->vga_bpp); vmw_write(vmw_priv, SVGA_REG_DEPTH, vmw_priv->vga_depth); + vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, vmw_priv->vga_bpp); vmw_write(vmw_priv, SVGA_REG_PSEUDOCOLOR, vmw_priv->vga_pseudo); vmw_write(vmw_priv, SVGA_REG_RED_MASK, vmw_priv->vga_red_mask); vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, vmw_priv->vga_green_mask); @@ -900,5 +922,19 @@ int vmw_kms_restore_vga(struct vmw_private *vmw_priv) iowrite32(vmw_priv->vga_pitchlock, vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK); + if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY)) + return 0; + + for (i = 0; i < vmw_priv->num_displays; ++i) { + save = &vmw_priv->vga_save[i]; + vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, i); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, save->primary); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, save->pos_x); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, save->pos_y); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, save->width); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, save->height); + vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); + } + return 0; } -- cgit v1.2.3 From 991b7b44f8cfa1b9beff8c4c2f2ec888b925c2a7 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 1 Jun 2010 11:38:16 +0200 Subject: drm/vmwgfx: Fix framebuffer modesetting Must set SVGA_NUM_REG_GUEST_DISPLAY before setting up the display information. Signed-off-by: Jakob Bornecrantz Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 181f47222580..b0866f04ec76 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c @@ -152,20 +152,12 @@ static int vmw_fb_set_par(struct fb_info *info) struct vmw_fb_par *par = info->par; struct vmw_private *vmw_priv = par->vmw_priv; + vmw_kms_write_svga(vmw_priv, info->var.xres, info->var.yres, + info->fix.line_length, + par->bpp, par->depth); if (vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) { - vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0); - vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true); - vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, 0); - vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, 0); - vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, 0); - vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, 0); - vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); - - vmw_kms_write_svga(vmw_priv, info->var.xres, info->var.yres, - info->fix.line_length, - par->bpp, par->depth); - /* TODO check if pitch and offset changes */ + vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1); vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0); vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true); vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, info->var.xoffset); @@ -173,12 +165,6 @@ static int vmw_fb_set_par(struct fb_info *info) vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, info->var.xres); vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, info->var.yres); vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); - vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1); - } else { - vmw_kms_write_svga(vmw_priv, info->var.xres, info->var.yres, - info->fix.line_length, - par->bpp, par->depth); - } /* This is really helpful since if this fails the user -- cgit v1.2.3 From d8bd19d2aff95e52c7f356cc2fc722584a656065 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 1 Jun 2010 11:54:20 +0200 Subject: drm/vmwgfx: Allow userspace to change default layout. Bump minor. The host may change the layout and, since the change is communicated to the master, the master needs a way to communicate the change to the kernel driver. The minor version number is bumped to advertize the availability of this feature. Signed-off-by: Jakob Bornecrantz Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 7 +++- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 45 ++++++++++++++++++++ drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 83 ++++++++++++++++++++++++++++++++++--- include/drm/vmwgfx_drm.h | 26 ++++++++++++ 6 files changed, 160 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 7597323d5a5a..b793c8c9acb3 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -88,6 +88,9 @@ #define DRM_IOCTL_VMW_FENCE_WAIT \ DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_FENCE_WAIT, \ struct drm_vmw_fence_wait_arg) +#define DRM_IOCTL_VMW_UPDATE_LAYOUT \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_UPDATE_LAYOUT, \ + struct drm_vmw_update_layout_arg) /** @@ -135,7 +138,9 @@ static struct drm_ioctl_desc vmw_ioctls[] = { VMW_IOCTL_DEF(DRM_IOCTL_VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl, DRM_AUTH | DRM_ROOT_ONLY | DRM_MASTER | DRM_UNLOCKED), VMW_IOCTL_DEF(DRM_IOCTL_VMW_FENCE_WAIT, vmw_fence_wait_ioctl, - DRM_AUTH | DRM_UNLOCKED) + DRM_AUTH | DRM_UNLOCKED), + VMW_IOCTL_DEF(DRM_IOCTL_VMW_UPDATE_LAYOUT, vmw_kms_update_layout_ioctl, + DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED) }; static struct pci_device_id vmw_pci_id_list[] = { diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index e577af5bb3d6..eaad52095339 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -41,7 +41,7 @@ #define VMWGFX_DRIVER_DATE "20100209" #define VMWGFX_DRIVER_MAJOR 1 -#define VMWGFX_DRIVER_MINOR 1 +#define VMWGFX_DRIVER_MINOR 2 #define VMWGFX_DRIVER_PATCHLEVEL 0 #define VMWGFX_FILE_PAGE_OFFSET 0x00100000 #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) @@ -509,6 +509,8 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf, void vmw_kms_write_svga(struct vmw_private *vmw_priv, unsigned width, unsigned height, unsigned pitch, unsigned bbp, unsigned depth); +int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); /** * Overlay control - vmwgfx_overlay.c diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 648ba044f6f8..f1d626112415 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -938,3 +938,48 @@ int vmw_kms_restore_vga(struct vmw_private *vmw_priv) return 0; } + +int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct vmw_private *dev_priv = vmw_priv(dev); + struct drm_vmw_update_layout_arg *arg = + (struct drm_vmw_update_layout_arg *)data; + struct vmw_master *vmaster = vmw_master(file_priv->master); + void __user *user_rects; + struct drm_vmw_rect *rects; + unsigned rects_size; + int ret; + + ret = ttm_read_lock(&vmaster->lock, true); + if (unlikely(ret != 0)) + return ret; + + if (!arg->num_outputs) { + struct drm_vmw_rect def_rect = {0, 0, 800, 600}; + vmw_kms_ldu_update_layout(dev_priv, 1, &def_rect); + goto out_unlock; + } + + rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect); + rects = kzalloc(rects_size, GFP_KERNEL); + if (unlikely(!rects)) { + ret = -ENOMEM; + goto out_unlock; + } + + user_rects = (void __user *)(unsigned long)arg->rects; + ret = copy_from_user(rects, user_rects, rects_size); + if (unlikely(ret != 0)) { + DRM_ERROR("Failed to get rects.\n"); + goto out_free; + } + + vmw_kms_ldu_update_layout(dev_priv, arg->num_outputs, rects); + +out_free: + kfree(rects); +out_unlock: + ttm_read_unlock(&vmaster->lock); + return ret; +} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index 8b95249f0531..8a398a0339b6 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h @@ -94,9 +94,11 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); /* - * Legacy display unit functions - vmwgfx_ldu.h + * Legacy display unit functions - vmwgfx_ldu.c */ int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv); int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv); +int vmw_kms_ldu_update_layout(struct vmw_private *dev_priv, unsigned num, + struct drm_vmw_rect *rects); #endif diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index f7094dde18f9..cfaf690a5b2f 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -49,6 +49,11 @@ struct vmw_legacy_display { struct vmw_legacy_display_unit { struct vmw_display_unit base; + unsigned pref_width; + unsigned pref_height; + bool pref_active; + struct drm_display_mode *pref_mode; + struct list_head active; }; @@ -332,8 +337,7 @@ static void vmw_ldu_connector_restore(struct drm_connector *connector) static enum drm_connector_status vmw_ldu_connector_detect(struct drm_connector *connector) { - /* XXX vmwctrl should control connection status */ - if (vmw_connector_to_ldu(connector)->base.unit == 0) + if (vmw_connector_to_ldu(connector)->pref_active) return connector_status_connected; return connector_status_disconnected; } @@ -344,10 +348,9 @@ static struct drm_display_mode vmw_ldu_connector_builtin[] = { 752, 800, 0, 480, 489, 492, 525, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 800x600@60Hz */ - { DRM_MODE("800x600", - DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, - 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, - 0, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, + { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840, + 968, 1056, 0, 600, 601, 605, 628, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1024x768@60Hz */ { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, @@ -419,10 +422,34 @@ static struct drm_display_mode vmw_ldu_connector_builtin[] = { static int vmw_ldu_connector_fill_modes(struct drm_connector *connector, uint32_t max_width, uint32_t max_height) { + struct vmw_legacy_display_unit *ldu = vmw_connector_to_ldu(connector); struct drm_device *dev = connector->dev; struct drm_display_mode *mode = NULL; + struct drm_display_mode prefmode = { DRM_MODE("preferred", + DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) + }; int i; + /* Add preferred mode */ + { + mode = drm_mode_duplicate(dev, &prefmode); + if (!mode) + return 0; + mode->hdisplay = ldu->pref_width; + mode->vdisplay = ldu->pref_height; + mode->vrefresh = drm_mode_vrefresh(mode); + drm_mode_probed_add(connector, mode); + + if (ldu->pref_mode) { + list_del_init(&ldu->pref_mode->head); + drm_mode_destroy(dev, ldu->pref_mode); + } + + ldu->pref_mode = mode; + } + for (i = 0; vmw_ldu_connector_builtin[i].type != 0; i++) { if (vmw_ldu_connector_builtin[i].hdisplay > max_width || vmw_ldu_connector_builtin[i].vdisplay > max_height) @@ -482,6 +509,11 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) INIT_LIST_HEAD(&ldu->active); + ldu->pref_active = (unit == 0); + ldu->pref_width = 800; + ldu->pref_height = 600; + ldu->pref_mode = NULL; + drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, DRM_MODE_CONNECTOR_LVDS); connector->status = vmw_ldu_connector_detect(connector); @@ -546,3 +578,42 @@ int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv) return 0; } + +int vmw_kms_ldu_update_layout(struct vmw_private *dev_priv, unsigned num, + struct drm_vmw_rect *rects) +{ + struct drm_device *dev = dev_priv->dev; + struct vmw_legacy_display_unit *ldu; + struct drm_connector *con; + int i; + + mutex_lock(&dev->mode_config.mutex); + +#if 0 + DRM_INFO("%s: new layout ", __func__); + for (i = 0; i < (int)num; i++) + DRM_INFO("(%i, %i %ux%u) ", rects[i].x, rects[i].y, + rects[i].w, rects[i].h); + DRM_INFO("\n"); +#else + (void)i; +#endif + + list_for_each_entry(con, &dev->mode_config.connector_list, head) { + ldu = vmw_connector_to_ldu(con); + if (num > ldu->base.unit) { + ldu->pref_width = rects[ldu->base.unit].w; + ldu->pref_height = rects[ldu->base.unit].h; + ldu->pref_active = true; + } else { + ldu->pref_width = 800; + ldu->pref_height = 600; + ldu->pref_active = false; + } + con->status = vmw_ldu_connector_detect(con); + } + + mutex_unlock(&dev->mode_config.mutex); + + return 0; +} diff --git a/include/drm/vmwgfx_drm.h b/include/drm/vmwgfx_drm.h index c7645f480d12..4d0842391edc 100644 --- a/include/drm/vmwgfx_drm.h +++ b/include/drm/vmwgfx_drm.h @@ -50,6 +50,8 @@ #define DRM_VMW_EXECBUF 12 #define DRM_VMW_FIFO_DEBUG 13 #define DRM_VMW_FENCE_WAIT 14 +/* guarded by minor version >= 2 */ +#define DRM_VMW_UPDATE_LAYOUT 15 /*************************************************************************/ @@ -585,4 +587,28 @@ struct drm_vmw_stream_arg { * sure that the stream has been stopped. */ +/*************************************************************************/ +/** + * DRM_VMW_UPDATE_LAYOUT - Update layout + * + * Updates the prefered modes and connection status for connectors. The + * command conisits of one drm_vmw_update_layout_arg pointing out a array + * of num_outputs drm_vmw_rect's. + */ + +/** + * struct drm_vmw_update_layout_arg + * + * @num_outputs: number of active + * @rects: pointer to array of drm_vmw_rect + * + * Input argument to the DRM_VMW_UPDATE_LAYOUT Ioctl. + */ + +struct drm_vmw_update_layout_arg { + uint32_t num_outputs; + uint32_t pad64; + uint64_t rects; +}; + #endif -- cgit v1.2.3 From d8dcaa1dc50f5aecd38d34180cd99d6af8566c88 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 2 Jun 2010 12:08:41 -0400 Subject: drm/radeon/kms: make sure display hw is disabled when suspending Disable the display hw when suspending. Should fix bug: https://bugzilla.redhat.com/show_bug.cgi?id=522393 Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_device.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index db338522191f..f10faed21567 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -713,6 +713,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) { struct radeon_device *rdev; struct drm_crtc *crtc; + struct drm_connector *connector; int r; if (dev == NULL || dev->dev_private == NULL) { @@ -725,6 +726,12 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) if (rdev->powered_down) return 0; + + /* turn off display hw */ + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); + } + /* unpin the front buffers */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb); -- cgit v1.2.3 From 5869d2c387e75814334697c9d702d91b7c63a308 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Wed, 2 Jun 2010 18:22:48 +0300 Subject: mtd: Fix NAND submenu Move MTD_NAND_ECC and MTD_NAND_ECC_SMC above NAND memuconfig, to unbreak display in xconfig. This shouldn't change any dependencies. Signed-off-by: Maxim Levitsky Signed-off-by: David Woodhouse --- drivers/mtd/nand/Kconfig | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 98a04b3c9526..ffc3720929f1 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -1,13 +1,3 @@ -menuconfig MTD_NAND - tristate "NAND Device Support" - depends on MTD - select MTD_NAND_IDS - select MTD_NAND_ECC - help - This enables support for accessing all type of NAND flash - devices. For further information see - . - config MTD_NAND_ECC tristate @@ -19,6 +9,17 @@ config MTD_NAND_ECC_SMC Software ECC according to the Smart Media Specification. The original Linux implementation had byte 0 and 1 swapped. + +menuconfig MTD_NAND + tristate "NAND Device Support" + depends on MTD + select MTD_NAND_IDS + select MTD_NAND_ECC + help + This enables support for accessing all type of NAND flash + devices. For further information see + . + if MTD_NAND config MTD_NAND_VERIFY_WRITE -- cgit v1.2.3 From 0f0a8fa735bbde4b0bc3e96e4bb2e5b380a324db Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Thu, 3 Jun 2010 16:53:49 +1000 Subject: crypto: crypto4xx - Fix build breakage Fixes build error caused by the OF device_node pointer being moved into struct device Signed-off-by: Anatolij Gustschin Signed-off-by: Herbert Xu --- drivers/crypto/amcc/crypto4xx_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c index 9d65b371de64..983530ba04a7 100644 --- a/drivers/crypto/amcc/crypto4xx_core.c +++ b/drivers/crypto/amcc/crypto4xx_core.c @@ -1158,7 +1158,7 @@ static int __init crypto4xx_probe(struct of_device *ofdev, struct device *dev = &ofdev->dev; struct crypto4xx_core_device *core_dev; - rc = of_address_to_resource(ofdev->node, 0, &res); + rc = of_address_to_resource(ofdev->dev.of_node, 0, &res); if (rc) return -ENODEV; @@ -1215,13 +1215,13 @@ static int __init crypto4xx_probe(struct of_device *ofdev, (unsigned long) dev); /* Register for Crypto isr, Crypto Engine IRQ */ - core_dev->irq = irq_of_parse_and_map(ofdev->node, 0); + core_dev->irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); rc = request_irq(core_dev->irq, crypto4xx_ce_interrupt_handler, 0, core_dev->dev->name, dev); if (rc) goto err_request_irq; - core_dev->dev->ce_base = of_iomap(ofdev->node, 0); + core_dev->dev->ce_base = of_iomap(ofdev->dev.of_node, 0); if (!core_dev->dev->ce_base) { dev_err(dev, "failed to of_iomap\n"); goto err_iomap; -- cgit v1.2.3 From b3831cb55d383e8eb55d3b56c715fb48459b87c9 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Tue, 25 May 2010 10:45:35 +0100 Subject: xen: avoid allocation causing potential swap activity on the resume path Since the device we are resuming could be the device containing the swap device we should ensure that the allocation cannot cause IO. On resume, this path is triggered when the running system tries to continue using its devices. If it cannot then the resume will fail; to try to avoid this we let it dip into the emergency pools. The majority of these changes were made when linux-2.6.18-xen.hg changeset e8b49cfbdac0 was ported upstream in a144ff09bc52ef3f3684ed23eadc9c7c0e57b3aa but somehow this hunk was dropped. Signed-off-by: Ian Campbell Acked-by: Jeremy Fitzhardinge Cc: Stable Kernel # .32.x --- drivers/xen/xenbus/xenbus_xs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c index eab33f1dbdf7..7b547f53f65e 100644 --- a/drivers/xen/xenbus/xenbus_xs.c +++ b/drivers/xen/xenbus/xenbus_xs.c @@ -499,7 +499,7 @@ int xenbus_printf(struct xenbus_transaction t, #define PRINTF_BUFFER_SIZE 4096 char *printf_buffer; - printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL); + printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_NOIO | __GFP_HIGH); if (printf_buffer == NULL) return -ENOMEM; -- cgit v1.2.3 From 63e4e80218803ff506b3ea4f2349b17916a35730 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 3 Jun 2010 11:33:51 +0200 Subject: i2c: Share the I2C device presence detection code Use the same I2C device presence detection code for legacy and new device detection functions. This is more consistent and makes the code smaller. Signed-off-by: Jean Delvare Cc: Matthieu Castet --- drivers/i2c/i2c-core.c | 80 +++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index e0f833cca3f1..f744f73e3ff5 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1277,6 +1277,41 @@ EXPORT_SYMBOL(i2c_master_recv); * ---------------------------------------------------- */ +/* + * Legacy default probe function, mostly relevant for SMBus. The default + * probe method is a quick write, but it is known to corrupt the 24RF08 + * EEPROMs due to a state machine bug, and could also irreversibly + * write-protect some EEPROMs, so for address ranges 0x30-0x37 and 0x50-0x5f, + * we use a short byte read instead. Also, some bus drivers don't implement + * quick write, so we fallback to a byte read in that case too. + * On x86, there is another special case for FSC hardware monitoring chips, + * which want regular byte reads (address 0x73.) Fortunately, these are the + * only known chips using this I2C address on PC hardware. + * Returns 1 if probe succeeded, 0 if not. + */ +static int i2c_default_probe(struct i2c_adapter *adap, unsigned short addr) +{ + int err; + union i2c_smbus_data dummy; + +#ifdef CONFIG_X86 + if (addr == 0x73 && (adap->class & I2C_CLASS_HWMON) + && i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE_DATA)) + err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0, + I2C_SMBUS_BYTE_DATA, &dummy); + else +#endif + if ((addr & ~0x07) == 0x30 || (addr & ~0x0f) == 0x50 + || !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) + err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0, + I2C_SMBUS_BYTE, &dummy); + else + err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_WRITE, 0, + I2C_SMBUS_QUICK, NULL); + + return err >= 0; +} + static int i2c_detect_address(struct i2c_client *temp_client, struct i2c_driver *driver) { @@ -1297,23 +1332,8 @@ static int i2c_detect_address(struct i2c_client *temp_client, return 0; /* Make sure there is something at this address */ - if (addr == 0x73 && (adapter->class & I2C_CLASS_HWMON)) { - /* Special probe for FSC hwmon chips */ - union i2c_smbus_data dummy; - - if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_READ, 0, - I2C_SMBUS_BYTE_DATA, &dummy) < 0) - return 0; - } else { - if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_WRITE, 0, - I2C_SMBUS_QUICK, NULL) < 0) - return 0; - - /* Prevent 24RF08 corruption */ - if ((addr & ~0x0f) == 0x50) - i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_WRITE, 0, - I2C_SMBUS_QUICK, NULL); - } + if (!i2c_default_probe(adapter, addr)) + return 0; /* Finally call the custom detection function */ memset(&info, 0, sizeof(struct i2c_board_info)); @@ -1420,29 +1440,9 @@ i2c_new_probed_device(struct i2c_adapter *adap, continue; } - /* Test address responsiveness - The default probe method is a quick write, but it is known - to corrupt the 24RF08 EEPROMs due to a state machine bug, - and could also irreversibly write-protect some EEPROMs, so - for address ranges 0x30-0x37 and 0x50-0x5f, we use a byte - read instead. Also, some bus drivers don't implement - quick write, so we fallback to a byte read it that case - too. */ - if ((addr_list[i] & ~0x07) == 0x30 - || (addr_list[i] & ~0x0f) == 0x50 - || !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) { - union i2c_smbus_data data; - - if (i2c_smbus_xfer(adap, addr_list[i], 0, - I2C_SMBUS_READ, 0, - I2C_SMBUS_BYTE, &data) >= 0) - break; - } else { - if (i2c_smbus_xfer(adap, addr_list[i], 0, - I2C_SMBUS_WRITE, 0, - I2C_SMBUS_QUICK, NULL) >= 0) - break; - } + /* Test address responsiveness */ + if (i2c_default_probe(adap, addr_list[i])) + break; } if (addr_list[i] == I2C_CLIENT_END) { -- cgit v1.2.3 From 3a89db5f30576654bf1b0036af9b50ed5ab1b6c5 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 3 Jun 2010 11:33:52 +0200 Subject: i2c: Check for address validity on client registration Do basic address validity checks when a client is being registered. We already had checks in place for devices which are being detected, but not for devices which are simply instantiated. This is a very basic check. We don't want to do strict checking here because some devices are known to infringe the I2C address constraints (e.g. IR receivers at 7-bit address 0x7a while this value is supposedly reserved for 10-bit addresses.) So we assume the caller knows what it is doing. Signed-off-by: Jean Delvare Cc: Matthieu Castet --- drivers/i2c/i2c-core.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index f744f73e3ff5..96f01331544d 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -371,6 +371,22 @@ struct i2c_client *i2c_verify_client(struct device *dev) EXPORT_SYMBOL(i2c_verify_client); +/* This is a permissive address validity check, I2C address map constraints + * are purposedly not enforced, except for the general call address. */ +static int i2c_check_client_addr_validity(const struct i2c_client *client) +{ + if (client->flags & I2C_CLIENT_TEN) { + /* 10-bit address, all values are valid */ + if (client->addr > 0x3ff) + return -EINVAL; + } else { + /* 7-bit address, reject the general call address */ + if (client->addr == 0x00 || client->addr > 0x7f) + return -EINVAL; + } + return 0; +} + /** * i2c_new_device - instantiate an i2c device * @adap: the adapter managing the device @@ -410,6 +426,14 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) strlcpy(client->name, info->type, sizeof(client->name)); + /* Check for address validity */ + status = i2c_check_client_addr_validity(client); + if (status) { + dev_err(&adap->dev, "Invalid %d-bit I2C address 0x%02hx\n", + client->flags & I2C_CLIENT_TEN ? 10 : 7, client->addr); + goto out_err_silent; + } + /* Check for address business */ status = i2c_check_addr(adap, client->addr); if (status) @@ -436,6 +460,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) out_err: dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x " "(%d)\n", client->name, client->addr, status); +out_err_silent: kfree(client); return NULL; } @@ -561,15 +586,9 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr, return -EINVAL; } - if (info.addr < 0x03 || info.addr > 0x77) { - dev_err(dev, "%s: Invalid I2C address 0x%hx\n", "new_device", - info.addr); - return -EINVAL; - } - client = i2c_new_device(adap, &info); if (!client) - return -EEXIST; + return -EINVAL; /* Keep track of the added device */ i2c_lock_adapter(adap); -- cgit v1.2.3 From 656b8761ab21715eb1a35bb078dfd05e901be4ec Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 3 Jun 2010 11:33:53 +0200 Subject: i2c: Document reserved I2C addresses Move strict I2C address validity check to a single function, and document the reserved I2C addresses there. Signed-off-by: Jean Delvare Cc: Hans Verkuil --- drivers/i2c/i2c-core.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 96f01331544d..af5172486fab 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -387,6 +387,27 @@ static int i2c_check_client_addr_validity(const struct i2c_client *client) return 0; } +/* And this is a strict address validity check, used when probing. If a + * device uses a reserved address, then it shouldn't be probed. 7-bit + * addressing is assumed, 10-bit address devices are rare and should be + * explicitly enumerated. */ +static int i2c_check_addr_validity(unsigned short addr) +{ + /* + * Reserved addresses per I2C specification: + * 0x00 General call address / START byte + * 0x01 CBUS address + * 0x02 Reserved for different bus format + * 0x03 Reserved for future purposes + * 0x04-0x07 Hs-mode master code + * 0x78-0x7b 10-bit slave addressing + * 0x7c-0x7f Reserved for future purposes + */ + if (addr < 0x08 || addr > 0x77) + return -EINVAL; + return 0; +} + /** * i2c_new_device - instantiate an i2c device * @adap: the adapter managing the device @@ -1340,10 +1361,11 @@ static int i2c_detect_address(struct i2c_client *temp_client, int err; /* Make sure the address is valid */ - if (addr < 0x03 || addr > 0x77) { + err = i2c_check_addr_validity(addr); + if (err) { dev_warn(&adapter->dev, "Invalid probe address 0x%02x\n", addr); - return -EINVAL; + return err; } /* Skip if already in use */ @@ -1446,7 +1468,7 @@ i2c_new_probed_device(struct i2c_adapter *adap, for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) { /* Check address validity */ - if (addr_list[i] < 0x03 || addr_list[i] > 0x77) { + if (i2c_check_addr_validity(addr_list[i]) < 0) { dev_warn(&adap->dev, "Invalid 7-bit address " "0x%02x\n", addr_list[i]); continue; -- cgit v1.2.3 From 3b5f794b8b647409155cade4eac2825bc49b4a66 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 3 Jun 2010 11:33:55 +0200 Subject: i2c: Rename i2c_check_addr to i2c_check_addr_busy Otherwise it's not clear what it is checking. Also move the function to save a forward declaration. Signed-off-by: Jean Delvare --- drivers/i2c/i2c-core.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index af5172486fab..1cca2631e5b3 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -47,7 +47,6 @@ static DEFINE_MUTEX(core_lock); static DEFINE_IDR(i2c_adapter_idr); static struct device_type i2c_client_type; -static int i2c_check_addr(struct i2c_adapter *adapter, int addr); static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver); /* ------------------------------------------------------------------------- */ @@ -408,6 +407,22 @@ static int i2c_check_addr_validity(unsigned short addr) return 0; } +static int __i2c_check_addr_busy(struct device *dev, void *addrp) +{ + struct i2c_client *client = i2c_verify_client(dev); + int addr = *(int *)addrp; + + if (client && client->addr == addr) + return -EBUSY; + return 0; +} + +static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr) +{ + return device_for_each_child(&adapter->dev, &addr, + __i2c_check_addr_busy); +} + /** * i2c_new_device - instantiate an i2c device * @adap: the adapter managing the device @@ -456,7 +471,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) } /* Check for address business */ - status = i2c_check_addr(adap, client->addr); + status = i2c_check_addr_busy(adap, client->addr); if (status) goto out_err; @@ -1064,21 +1079,6 @@ EXPORT_SYMBOL(i2c_del_driver); /* ------------------------------------------------------------------------- */ -static int __i2c_check_addr(struct device *dev, void *addrp) -{ - struct i2c_client *client = i2c_verify_client(dev); - int addr = *(int *)addrp; - - if (client && client->addr == addr) - return -EBUSY; - return 0; -} - -static int i2c_check_addr(struct i2c_adapter *adapter, int addr) -{ - return device_for_each_child(&adapter->dev, &addr, __i2c_check_addr); -} - /** * i2c_use_client - increments the reference count of the i2c client structure * @client: the client being referenced @@ -1369,7 +1369,7 @@ static int i2c_detect_address(struct i2c_client *temp_client, } /* Skip if already in use */ - if (i2c_check_addr(adapter, addr)) + if (i2c_check_addr_busy(adapter, addr)) return 0; /* Make sure there is something at this address */ @@ -1475,7 +1475,7 @@ i2c_new_probed_device(struct i2c_adapter *adap, } /* Check address availability */ - if (i2c_check_addr(adap, addr_list[i])) { + if (i2c_check_addr_busy(adap, addr_list[i])) { dev_dbg(&adap->dev, "Address 0x%02x already in " "use, not probing\n", addr_list[i]); continue; -- cgit v1.2.3 From 35bfc353dcaecc99c277e3646564f3f785760bde Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 3 Jun 2010 11:33:56 +0200 Subject: i2c/busses: Move two drivers to embedded section And fix a typo while we are here Signed-off-by: Wolfram Sang Signed-off-by: Jean Delvare --- drivers/i2c/busses/Kconfig | 40 ++++++++++++++++++++-------------------- drivers/i2c/busses/Makefile | 6 +++--- 2 files changed, 23 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 87ab0568bb0e..bceafbfa7268 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -475,6 +475,26 @@ config I2C_PASEMI help Supports the PA Semi PWRficient on-chip SMBus interfaces. +config I2C_PCA_PLATFORM + tristate "PCA9564/PCA9665 as platform device" + select I2C_ALGOPCA + default n + help + This driver supports a memory mapped Philips PCA9564/PCA9665 + parallel bus to I2C bus controller. + + This driver can also be built as a module. If so, the module + will be called i2c-pca-platform. + +config I2C_PMCMSP + tristate "PMC MSP I2C TWI Controller" + depends on PMC_MSP + help + This driver supports the PMC TWI controller on MSP devices. + + This driver can also be built as module. If so, the module + will be called i2c-pmcmsp. + config I2C_PNX tristate "I2C bus support for Philips PNX targets" depends on ARCH_PNX4008 @@ -711,26 +731,6 @@ config I2C_PCA_ISA delays when I2C/SMBus chip drivers are loaded (e.g. at boot time). If unsure, say N. -config I2C_PCA_PLATFORM - tristate "PCA9564/PCA9665 as platform device" - select I2C_ALGOPCA - default n - help - This driver supports a memory mapped Philips PCA9564/PCA9665 - parallel bus to I2C bus controller. - - This driver can also be built as a module. If so, the module - will be called i2c-pca-platform. - -config I2C_PMCMSP - tristate "PMC MSP I2C TWI Controller" - depends on PMC_MSP - help - This driver supports the PMC TWI controller on MSP devices. - - This driver can also be built as module. If so, the module - will be called i2c-pmcmsp. - config I2C_SIBYTE tristate "SiByte SMBus interface" depends on SIBYTE_SB1xxx_SOC diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 097236f631e8..936880bd1dc5 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -27,7 +27,7 @@ obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o -# Embebbed system I2C/SMBus host controller drivers +# Embedded system I2C/SMBus host controller drivers obj-$(CONFIG_I2C_AT91) += i2c-at91.o obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o @@ -46,6 +46,8 @@ obj-$(CONFIG_I2C_NOMADIK) += i2c-nomadik.o obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o obj-$(CONFIG_I2C_OMAP) += i2c-omap.o obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o +obj-$(CONFIG_I2C_PCA_PLATFORM) += i2c-pca-platform.o +obj-$(CONFIG_I2C_PMCMSP) += i2c-pmcmsp.o obj-$(CONFIG_I2C_PNX) += i2c-pnx.o obj-$(CONFIG_I2C_PXA) += i2c-pxa.o obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o @@ -68,8 +70,6 @@ obj-$(CONFIG_I2C_TINY_USB) += i2c-tiny-usb.o obj-$(CONFIG_I2C_ACORN) += i2c-acorn.o obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o -obj-$(CONFIG_I2C_PCA_PLATFORM) += i2c-pca-platform.o -obj-$(CONFIG_I2C_PMCMSP) += i2c-pmcmsp.o obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o obj-$(CONFIG_I2C_STUB) += i2c-stub.o obj-$(CONFIG_SCx200_ACB) += scx200_acb.o -- cgit v1.2.3 From fbae3fb1546e199ab0cd185348f8124411a1ca9d Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 3 Jun 2010 11:33:58 +0200 Subject: i2c: Remove all i2c_set_clientdata(client, NULL) in drivers I2C drivers can use the clientdata-pointer to point to private data. As I2C devices are not really unregistered, but merely detached from their driver, it used to be the drivers obligation to clear this pointer during remove() or a failed probe(). As a couple of drivers forgot to do this, it was agreed that it was cleaner if the i2c-core does this clearance when appropriate, as there is no guarantee for the lifetime of the clientdata-pointer after remove() anyhow. This feature was added to the core with commit e4a7b9b04de15f6b63da5ccdd373ffa3057a3681 to fix the faulty drivers. As there is no need anymore to clear the clientdata-pointer, remove all current occurrences in the drivers to simplify the code and prevent confusion. Signed-off-by: Wolfram Sang Acked-by: Mark Brown Acked-by: Greg Kroah-Hartman Acked-by: Richard Purdie Acked-by: Dmitry Torokhov Signed-off-by: Jean Delvare --- drivers/hwmon/adt7411.c | 2 -- drivers/hwmon/asc7621.c | 2 -- drivers/hwmon/f75375s.c | 2 -- drivers/hwmon/g760a.c | 2 -- drivers/hwmon/lm73.c | 1 - drivers/hwmon/lm75.c | 2 -- drivers/hwmon/lm95241.c | 1 - drivers/hwmon/tmp102.c | 2 -- drivers/hwmon/tmp421.c | 2 -- drivers/hwmon/w83781d.c | 2 -- drivers/i2c/i2c-smbus.c | 1 - drivers/input/keyboard/adp5588-keys.c | 1 - drivers/input/keyboard/lm8323.c | 2 -- drivers/input/keyboard/max7359_keypad.c | 1 - drivers/input/keyboard/qt2160.c | 1 - drivers/input/keyboard/tca6416-keypad.c | 2 -- drivers/input/misc/ad714x-i2c.c | 1 - drivers/input/misc/pcf8574_keypad.c | 2 -- drivers/input/mouse/synaptics_i2c.c | 1 - drivers/input/touchscreen/ad7879.c | 5 +---- drivers/input/touchscreen/eeti_ts.c | 2 -- drivers/input/touchscreen/mcs5000_ts.c | 1 - drivers/input/touchscreen/tsc2007.c | 2 -- drivers/leds/leds-bd2802.c | 2 -- drivers/leds/leds-lp3944.c | 1 - drivers/leds/leds-pca9532.c | 5 +---- drivers/leds/leds-pca955x.c | 2 -- drivers/macintosh/therm_adt746x.c | 2 -- drivers/macintosh/windfarm_lm75_sensor.c | 5 +---- drivers/macintosh/windfarm_max6690_sensor.c | 1 - drivers/macintosh/windfarm_smu_sat.c | 1 - drivers/media/radio/si470x/radio-si470x-i2c.c | 1 - drivers/media/video/mt9m001.c | 2 -- drivers/media/video/mt9m111.c | 2 -- drivers/media/video/mt9t031.c | 2 -- drivers/media/video/mt9t112.c | 2 -- drivers/media/video/mt9v022.c | 2 -- drivers/media/video/ov772x.c | 2 -- drivers/media/video/ov9640.c | 2 -- drivers/media/video/rj54n1cb0c.c | 2 -- drivers/media/video/tcm825x.c | 8 +------- drivers/media/video/tw9910.c | 2 -- drivers/mfd/88pm860x-i2c.c | 2 -- drivers/mfd/ab3100-core.c | 2 -- drivers/mfd/ab3550-core.c | 1 - drivers/mfd/adp5520.c | 2 -- drivers/mfd/da903x.c | 2 -- drivers/mfd/max8925-i2c.c | 1 - drivers/mfd/menelaus.c | 2 -- drivers/mfd/pcf50633-core.c | 2 -- drivers/mfd/tc35892.c | 2 -- drivers/mfd/tps65010.c | 1 - drivers/mfd/wm8350-i2c.c | 2 -- drivers/mfd/wm8400-core.c | 2 -- drivers/misc/eeprom/at24.c | 1 - drivers/mtd/maps/pismo.c | 2 -- drivers/power/max17040_battery.c | 2 -- drivers/regulator/lp3971.c | 2 -- drivers/regulator/max1586.c | 1 - drivers/regulator/max8649.c | 2 -- drivers/regulator/max8660.c | 1 - drivers/regulator/tps65023-regulator.c | 3 --- drivers/rtc/rtc-ds1374.c | 2 -- drivers/rtc/rtc-rx8025.c | 2 -- drivers/rtc/rtc-s35390a.c | 2 -- drivers/staging/dream/synaptics_i2c_rmi.c | 2 -- drivers/staging/go7007/wis-saa7113.c | 2 -- drivers/staging/go7007/wis-saa7115.c | 2 -- drivers/staging/go7007/wis-sony-tuner.c | 1 - drivers/staging/go7007/wis-tw2804.c | 1 - drivers/staging/go7007/wis-tw9903.c | 2 -- drivers/staging/iio/adc/max1363_core.c | 2 -- drivers/staging/iio/light/tsl2563.c | 2 -- drivers/video/backlight/adp8860_bl.c | 2 -- drivers/video/backlight/tosa_bl.c | 2 -- 75 files changed, 4 insertions(+), 141 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/adt7411.c b/drivers/hwmon/adt7411.c index 4086c7257f91..f13c843a2964 100644 --- a/drivers/hwmon/adt7411.c +++ b/drivers/hwmon/adt7411.c @@ -316,7 +316,6 @@ static int __devinit adt7411_probe(struct i2c_client *client, exit_remove: sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp); exit_free: - i2c_set_clientdata(client, NULL); kfree(data); return ret; } @@ -327,7 +326,6 @@ static int __devexit adt7411_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp); - i2c_set_clientdata(client, NULL); kfree(data); return 0; } diff --git a/drivers/hwmon/asc7621.c b/drivers/hwmon/asc7621.c index 0f388adc6187..3b973f30b1f6 100644 --- a/drivers/hwmon/asc7621.c +++ b/drivers/hwmon/asc7621.c @@ -1141,7 +1141,6 @@ exit_remove: &(asc7621_params[i].sda.dev_attr)); } - i2c_set_clientdata(client, NULL); kfree(data); return err; } @@ -1196,7 +1195,6 @@ static int asc7621_remove(struct i2c_client *client) &(asc7621_params[i].sda.dev_attr)); } - i2c_set_clientdata(client, NULL); kfree(data); return 0; } diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index bad2cf3ef4a4..0f58ecc5334d 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c @@ -662,7 +662,6 @@ exit_remove: sysfs_remove_group(&client->dev.kobj, &f75375_group); exit_free: kfree(data); - i2c_set_clientdata(client, NULL); return err; } @@ -672,7 +671,6 @@ static int f75375_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &f75375_group); kfree(data); - i2c_set_clientdata(client, NULL); return 0; } diff --git a/drivers/hwmon/g760a.c b/drivers/hwmon/g760a.c index 09ea12e0a551..1f63d1a3af5e 100644 --- a/drivers/hwmon/g760a.c +++ b/drivers/hwmon/g760a.c @@ -236,7 +236,6 @@ error_hwmon_device_register: sysfs_remove_group(&client->dev.kobj, &g760a_group); error_sysfs_create_group: kfree(data); - i2c_set_clientdata(client, NULL); return err; } @@ -247,7 +246,6 @@ static int g760a_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &g760a_group); kfree(data); - i2c_set_clientdata(client, NULL); return 0; } diff --git a/drivers/hwmon/lm73.c b/drivers/hwmon/lm73.c index 4d1b76bc8148..29b9030d42c3 100644 --- a/drivers/hwmon/lm73.c +++ b/drivers/hwmon/lm73.c @@ -136,7 +136,6 @@ static int lm73_remove(struct i2c_client *client) hwmon_device_unregister(hwmon_dev); sysfs_remove_group(&client->dev.kobj, &lm73_group); - i2c_set_clientdata(client, NULL); return 0; } diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index 56463428a419..393f354f92a4 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -192,7 +192,6 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) exit_remove: sysfs_remove_group(&client->dev.kobj, &lm75_group); exit_free: - i2c_set_clientdata(client, NULL); kfree(data); return status; } @@ -204,7 +203,6 @@ static int lm75_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &lm75_group); lm75_write_value(client, LM75_REG_CONF, data->orig_conf); - i2c_set_clientdata(client, NULL); kfree(data); return 0; } diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c index 8fc8eb8cba47..94741d42112d 100644 --- a/drivers/hwmon/lm95241.c +++ b/drivers/hwmon/lm95241.c @@ -399,7 +399,6 @@ static int lm95241_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &lm95241_group); - i2c_set_clientdata(client, NULL); kfree(data); return 0; } diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c index 8013895a1faf..93187c3cb5e7 100644 --- a/drivers/hwmon/tmp102.c +++ b/drivers/hwmon/tmp102.c @@ -224,7 +224,6 @@ fail_remove_sysfs: fail_restore_config: tmp102_write_reg(client, TMP102_CONF_REG, tmp102->config_orig); fail_free: - i2c_set_clientdata(client, NULL); kfree(tmp102); return status; @@ -247,7 +246,6 @@ static int __devexit tmp102_remove(struct i2c_client *client) config | TMP102_CONF_SD); } - i2c_set_clientdata(client, NULL); kfree(tmp102); return 0; diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c index 738c472ece27..6b4165c12092 100644 --- a/drivers/hwmon/tmp421.c +++ b/drivers/hwmon/tmp421.c @@ -295,7 +295,6 @@ exit_remove: sysfs_remove_group(&client->dev.kobj, &tmp421_group); exit_free: - i2c_set_clientdata(client, NULL); kfree(data); return err; @@ -308,7 +307,6 @@ static int tmp421_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &tmp421_group); - i2c_set_clientdata(client, NULL); kfree(data); return 0; diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 32d4adee73db..c84b9b4e6960 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -1197,7 +1197,6 @@ ERROR4: if (data->lm75[1]) i2c_unregister_device(data->lm75[1]); ERROR3: - i2c_set_clientdata(client, NULL); kfree(data); ERROR1: return err; @@ -1219,7 +1218,6 @@ w83781d_remove(struct i2c_client *client) if (data->lm75[1]) i2c_unregister_device(data->lm75[1]); - i2c_set_clientdata(client, NULL); kfree(data); return 0; diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c index a24e0bfe9201..f61ccc1e5ea3 100644 --- a/drivers/i2c/i2c-smbus.c +++ b/drivers/i2c/i2c-smbus.c @@ -173,7 +173,6 @@ static int smbalert_remove(struct i2c_client *ara) cancel_work_sync(&alert->alert); - i2c_set_clientdata(ara, NULL); kfree(alert); return 0; } diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index 4771ab172b59..744600eff222 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c @@ -287,7 +287,6 @@ static int __devexit adp5588_remove(struct i2c_client *client) free_irq(client->irq, kpad); cancel_delayed_work_sync(&kpad->work); input_unregister_device(kpad->input); - i2c_set_clientdata(client, NULL); kfree(kpad); return 0; diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c index bc696931fed7..40b032f0e32c 100644 --- a/drivers/input/keyboard/lm8323.c +++ b/drivers/input/keyboard/lm8323.c @@ -778,8 +778,6 @@ static int __devexit lm8323_remove(struct i2c_client *client) struct lm8323_chip *lm = i2c_get_clientdata(client); int i; - i2c_set_clientdata(client, NULL); - disable_irq_wake(client->irq); free_irq(client->irq, lm); cancel_work_sync(&lm->work); diff --git a/drivers/input/keyboard/max7359_keypad.c b/drivers/input/keyboard/max7359_keypad.c index 7fc8185e5c1b..9091ff5ea808 100644 --- a/drivers/input/keyboard/max7359_keypad.c +++ b/drivers/input/keyboard/max7359_keypad.c @@ -265,7 +265,6 @@ static int __devexit max7359_remove(struct i2c_client *client) free_irq(client->irq, keypad); input_unregister_device(keypad->input_dev); - i2c_set_clientdata(client, NULL); kfree(keypad); return 0; diff --git a/drivers/input/keyboard/qt2160.c b/drivers/input/keyboard/qt2160.c index 31f30087b591..fac695157e8a 100644 --- a/drivers/input/keyboard/qt2160.c +++ b/drivers/input/keyboard/qt2160.c @@ -358,7 +358,6 @@ static int __devexit qt2160_remove(struct i2c_client *client) input_unregister_device(qt2160->input); kfree(qt2160); - i2c_set_clientdata(client, NULL); return 0; } diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c index 493c93f25e2a..00137bebcf97 100644 --- a/drivers/input/keyboard/tca6416-keypad.c +++ b/drivers/input/keyboard/tca6416-keypad.c @@ -316,8 +316,6 @@ static int __devexit tca6416_keypad_remove(struct i2c_client *client) input_unregister_device(chip->input); kfree(chip); - i2c_set_clientdata(client, NULL); - return 0; } diff --git a/drivers/input/misc/ad714x-i2c.c b/drivers/input/misc/ad714x-i2c.c index e9adbe49f6a4..2bef8fa56c94 100644 --- a/drivers/input/misc/ad714x-i2c.c +++ b/drivers/input/misc/ad714x-i2c.c @@ -97,7 +97,6 @@ static int __devexit ad714x_i2c_remove(struct i2c_client *client) struct ad714x_chip *chip = i2c_get_clientdata(client); ad714x_remove(chip); - i2c_set_clientdata(client, NULL); return 0; } diff --git a/drivers/input/misc/pcf8574_keypad.c b/drivers/input/misc/pcf8574_keypad.c index 5c3ac4e0b055..0ac47d2898ec 100644 --- a/drivers/input/misc/pcf8574_keypad.c +++ b/drivers/input/misc/pcf8574_keypad.c @@ -168,8 +168,6 @@ static int __devexit pcf8574_kp_remove(struct i2c_client *client) input_unregister_device(lp->idev); kfree(lp); - i2c_set_clientdata(client, NULL); - return 0; } diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c index 8291e7399ffa..0ae62f0bcb32 100644 --- a/drivers/input/mouse/synaptics_i2c.c +++ b/drivers/input/mouse/synaptics_i2c.c @@ -613,7 +613,6 @@ static int __devexit synaptics_i2c_remove(struct i2c_client *client) free_irq(client->irq, touch); input_unregister_device(touch->input); - i2c_set_clientdata(client, NULL); kfree(touch); return 0; diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c index 794d070c6900..4b32fb4704cd 100644 --- a/drivers/input/touchscreen/ad7879.c +++ b/drivers/input/touchscreen/ad7879.c @@ -812,10 +812,8 @@ static int __devinit ad7879_probe(struct i2c_client *client, ts->bus = client; error = ad7879_construct(client, ts); - if (error) { - i2c_set_clientdata(client, NULL); + if (error) kfree(ts); - } return error; } @@ -825,7 +823,6 @@ static int __devexit ad7879_remove(struct i2c_client *client) struct ad7879 *ts = dev_get_drvdata(&client->dev); ad7879_destroy(client, ts); - i2c_set_clientdata(client, NULL); kfree(ts); return 0; diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c index 75f8b73010fa..7a3a916f84a8 100644 --- a/drivers/input/touchscreen/eeti_ts.c +++ b/drivers/input/touchscreen/eeti_ts.c @@ -238,7 +238,6 @@ err2: input = NULL; /* so we dont try to free it below */ err1: input_free_device(input); - i2c_set_clientdata(client, NULL); kfree(priv); err0: return err; @@ -256,7 +255,6 @@ static int __devexit eeti_ts_remove(struct i2c_client *client) enable_irq(priv->irq); input_unregister_device(priv->input); - i2c_set_clientdata(client, NULL); kfree(priv); return 0; diff --git a/drivers/input/touchscreen/mcs5000_ts.c b/drivers/input/touchscreen/mcs5000_ts.c index ce8ab0269f6f..1fb0c2f06a44 100644 --- a/drivers/input/touchscreen/mcs5000_ts.c +++ b/drivers/input/touchscreen/mcs5000_ts.c @@ -256,7 +256,6 @@ static int __devexit mcs5000_ts_remove(struct i2c_client *client) free_irq(client->irq, data); input_unregister_device(data->input_dev); kfree(data); - i2c_set_clientdata(client, NULL); return 0; } diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c index 769b479fcaa6..be23780e8a3e 100644 --- a/drivers/input/touchscreen/tsc2007.c +++ b/drivers/input/touchscreen/tsc2007.c @@ -347,8 +347,6 @@ static int __devexit tsc2007_remove(struct i2c_client *client) struct tsc2007 *ts = i2c_get_clientdata(client); struct tsc2007_platform_data *pdata = client->dev.platform_data; - i2c_set_clientdata(client, NULL); - tsc2007_free_irq(ts); if (pdata->exit_platform_hw) diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c index 286b501a3573..5dcdf9d69b3a 100644 --- a/drivers/leds/leds-bd2802.c +++ b/drivers/leds/leds-bd2802.c @@ -742,7 +742,6 @@ failed_unregister_dev_file: for (i--; i >= 0; i--) device_remove_file(&led->client->dev, bd2802_attributes[i]); failed_free: - i2c_set_clientdata(client, NULL); kfree(led); return ret; @@ -759,7 +758,6 @@ static int __exit bd2802_remove(struct i2c_client *client) bd2802_disable_adv_conf(led); for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++) device_remove_file(&led->client->dev, bd2802_attributes[i]); - i2c_set_clientdata(client, NULL); kfree(led); return 0; diff --git a/drivers/leds/leds-lp3944.c b/drivers/leds/leds-lp3944.c index 932a58da76c4..9010c054615e 100644 --- a/drivers/leds/leds-lp3944.c +++ b/drivers/leds/leds-lp3944.c @@ -432,7 +432,6 @@ static int __devexit lp3944_remove(struct i2c_client *client) } kfree(data); - i2c_set_clientdata(client, NULL); return 0; } diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c index 6682175fa9f7..43d08756d823 100644 --- a/drivers/leds/leds-pca9532.c +++ b/drivers/leds/leds-pca9532.c @@ -320,10 +320,8 @@ static int pca9532_probe(struct i2c_client *client, mutex_init(&data->update_lock); err = pca9532_configure(client, data, pca9532_pdata); - if (err) { + if (err) kfree(data); - i2c_set_clientdata(client, NULL); - } return err; } @@ -351,7 +349,6 @@ static int pca9532_remove(struct i2c_client *client) } kfree(data); - i2c_set_clientdata(client, NULL); return 0; } diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c index 8ff50f234190..66aa3e8e786f 100644 --- a/drivers/leds/leds-pca955x.c +++ b/drivers/leds/leds-pca955x.c @@ -342,7 +342,6 @@ exit: } kfree(pca955x); - i2c_set_clientdata(client, NULL); return err; } @@ -358,7 +357,6 @@ static int __devexit pca955x_remove(struct i2c_client *client) } kfree(pca955x); - i2c_set_clientdata(client, NULL); return 0; } diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index 16d82f17ae82..c42eeb43042d 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c @@ -182,7 +182,6 @@ remove_thermostat(struct i2c_client *client) thermostat = NULL; - i2c_set_clientdata(client, NULL); kfree(th); return 0; @@ -400,7 +399,6 @@ static int probe_thermostat(struct i2c_client *client, rc = read_reg(th, CONFIG_REG); if (rc < 0) { dev_err(&client->dev, "Thermostat failed to read config!\n"); - i2c_set_clientdata(client, NULL); kfree(th); return -ENODEV; } diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c index d8257d35afde..647c6add2193 100644 --- a/drivers/macintosh/windfarm_lm75_sensor.c +++ b/drivers/macintosh/windfarm_lm75_sensor.c @@ -107,10 +107,8 @@ static int wf_lm75_probe(struct i2c_client *client, i2c_set_clientdata(client, lm); rc = wf_register_sensor(&lm->sens); - if (rc) { - i2c_set_clientdata(client, NULL); + if (rc) kfree(lm); - } return rc; } @@ -216,7 +214,6 @@ static int wf_lm75_remove(struct i2c_client *client) /* release sensor */ wf_unregister_sensor(&lm->sens); - i2c_set_clientdata(client, NULL); return 0; } diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c index b486eb929fde..8204113268f4 100644 --- a/drivers/macintosh/windfarm_max6690_sensor.c +++ b/drivers/macintosh/windfarm_max6690_sensor.c @@ -81,7 +81,6 @@ static int wf_max6690_probe(struct i2c_client *client, rc = wf_register_sensor(&max->sens); if (rc) { - i2c_set_clientdata(client, NULL); kfree(max); } diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c index e20330a28959..65a8ff3e1f8e 100644 --- a/drivers/macintosh/windfarm_smu_sat.c +++ b/drivers/macintosh/windfarm_smu_sat.c @@ -376,7 +376,6 @@ static int wf_sat_remove(struct i2c_client *client) /* XXX TODO */ sat->i2c = NULL; - i2c_set_clientdata(client, NULL); return 0; } diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c index a5844d08d8b7..67a4ec8768a6 100644 --- a/drivers/media/radio/si470x/radio-si470x-i2c.c +++ b/drivers/media/radio/si470x/radio-si470x-i2c.c @@ -482,7 +482,6 @@ static __devexit int si470x_i2c_remove(struct i2c_client *client) cancel_work_sync(&radio->radio_work); video_unregister_device(radio->videodev); kfree(radio); - i2c_set_clientdata(client, NULL); return 0; } diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index b62c0bd3f8ea..e3b9a8ab37f4 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c @@ -785,7 +785,6 @@ static int mt9m001_probe(struct i2c_client *client, ret = mt9m001_video_probe(icd, client); if (ret) { icd->ops = NULL; - i2c_set_clientdata(client, NULL); kfree(mt9m001); } @@ -799,7 +798,6 @@ static int mt9m001_remove(struct i2c_client *client) icd->ops = NULL; mt9m001_video_remove(icd); - i2c_set_clientdata(client, NULL); client->driver = NULL; kfree(mt9m001); diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index d35f536f9fc3..e42162c50f0a 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -1068,7 +1068,6 @@ static int mt9m111_probe(struct i2c_client *client, ret = mt9m111_video_probe(icd, client); if (ret) { icd->ops = NULL; - i2c_set_clientdata(client, NULL); kfree(mt9m111); } @@ -1081,7 +1080,6 @@ static int mt9m111_remove(struct i2c_client *client) struct soc_camera_device *icd = client->dev.platform_data; icd->ops = NULL; - i2c_set_clientdata(client, NULL); client->driver = NULL; kfree(mt9m111); diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c index 78b4e091d2d5..9f5ff2547f19 100644 --- a/drivers/media/video/mt9t031.c +++ b/drivers/media/video/mt9t031.c @@ -883,7 +883,6 @@ static int mt9t031_probe(struct i2c_client *client, if (ret) { if (icd) icd->ops = NULL; - i2c_set_clientdata(client, NULL); kfree(mt9t031); } @@ -897,7 +896,6 @@ static int mt9t031_remove(struct i2c_client *client) if (icd) icd->ops = NULL; - i2c_set_clientdata(client, NULL); client->driver = NULL; kfree(mt9t031); diff --git a/drivers/media/video/mt9t112.c b/drivers/media/video/mt9t112.c index 7438f8d775ba..aa4fce95098f 100644 --- a/drivers/media/video/mt9t112.c +++ b/drivers/media/video/mt9t112.c @@ -1119,7 +1119,6 @@ static int mt9t112_probe(struct i2c_client *client, ret = mt9t112_camera_probe(icd, client); if (ret) { icd->ops = NULL; - i2c_set_clientdata(client, NULL); kfree(priv); } @@ -1132,7 +1131,6 @@ static int mt9t112_remove(struct i2c_client *client) struct soc_camera_device *icd = client->dev.platform_data; icd->ops = NULL; - i2c_set_clientdata(client, NULL); kfree(priv); return 0; } diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index e5bae4c9393b..fb44ff006628 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c @@ -920,7 +920,6 @@ static int mt9v022_probe(struct i2c_client *client, ret = mt9v022_video_probe(icd, client); if (ret) { icd->ops = NULL; - i2c_set_clientdata(client, NULL); kfree(mt9v022); } @@ -934,7 +933,6 @@ static int mt9v022_remove(struct i2c_client *client) icd->ops = NULL; mt9v022_video_remove(icd); - i2c_set_clientdata(client, NULL); client->driver = NULL; kfree(mt9v022); diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c index 7f8ece30c77b..c33acc94b747 100644 --- a/drivers/media/video/ov772x.c +++ b/drivers/media/video/ov772x.c @@ -1159,7 +1159,6 @@ static int ov772x_probe(struct i2c_client *client, ret = ov772x_video_probe(icd, client); if (ret) { icd->ops = NULL; - i2c_set_clientdata(client, NULL); kfree(priv); } @@ -1172,7 +1171,6 @@ static int ov772x_remove(struct i2c_client *client) struct soc_camera_device *icd = client->dev.platform_data; icd->ops = NULL; - i2c_set_clientdata(client, NULL); kfree(priv); return 0; } diff --git a/drivers/media/video/ov9640.c b/drivers/media/video/ov9640.c index 36599a65f548..035e9ecb0c75 100644 --- a/drivers/media/video/ov9640.c +++ b/drivers/media/video/ov9640.c @@ -783,7 +783,6 @@ static int ov9640_probe(struct i2c_client *client, if (ret) { icd->ops = NULL; - i2c_set_clientdata(client, NULL); kfree(priv); } @@ -794,7 +793,6 @@ static int ov9640_remove(struct i2c_client *client) { struct ov9640_priv *priv = i2c_get_clientdata(client); - i2c_set_clientdata(client, NULL); kfree(priv); return 0; } diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c index bbd9c11e2c5a..2c3b58c99e18 100644 --- a/drivers/media/video/rj54n1cb0c.c +++ b/drivers/media/video/rj54n1cb0c.c @@ -1444,7 +1444,6 @@ static int rj54n1_probe(struct i2c_client *client, ret = rj54n1_video_probe(icd, client, rj54n1_priv); if (ret < 0) { icd->ops = NULL; - i2c_set_clientdata(client, NULL); kfree(rj54n1); return ret; } @@ -1461,7 +1460,6 @@ static int rj54n1_remove(struct i2c_client *client) icd->ops = NULL; if (icl->free_bus) icl->free_bus(icl); - i2c_set_clientdata(client, NULL); client->driver = NULL; kfree(rj54n1); diff --git a/drivers/media/video/tcm825x.c b/drivers/media/video/tcm825x.c index b90e9da3167d..54681a535822 100644 --- a/drivers/media/video/tcm825x.c +++ b/drivers/media/video/tcm825x.c @@ -850,7 +850,6 @@ static int tcm825x_probe(struct i2c_client *client, const struct i2c_device_id *did) { struct tcm825x_sensor *sensor = &tcm825x; - int rval; if (i2c_get_clientdata(client)) return -EBUSY; @@ -871,11 +870,7 @@ static int tcm825x_probe(struct i2c_client *client, sensor->pix.height = tcm825x_sizes[QVGA].height; sensor->pix.pixelformat = V4L2_PIX_FMT_RGB565; - rval = v4l2_int_device_register(sensor->v4l2_int_device); - if (rval) - i2c_set_clientdata(client, NULL); - - return rval; + return v4l2_int_device_register(sensor->v4l2_int_device); } static int tcm825x_remove(struct i2c_client *client) @@ -886,7 +881,6 @@ static int tcm825x_remove(struct i2c_client *client) return -ENODEV; /* our client isn't attached */ v4l2_int_device_unregister(sensor->v4l2_int_device); - i2c_set_clientdata(client, NULL); return 0; } diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c index 76be733eabfd..6eb3395def07 100644 --- a/drivers/media/video/tw9910.c +++ b/drivers/media/video/tw9910.c @@ -977,7 +977,6 @@ static int tw9910_probe(struct i2c_client *client, ret = tw9910_video_probe(icd, client); if (ret) { icd->ops = NULL; - i2c_set_clientdata(client, NULL); kfree(priv); } @@ -990,7 +989,6 @@ static int tw9910_remove(struct i2c_client *client) struct soc_camera_device *icd = client->dev.platform_data; icd->ops = NULL; - i2c_set_clientdata(client, NULL); kfree(priv); return 0; } diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c index c933b64d1283..bc02e6b21608 100644 --- a/drivers/mfd/88pm860x-i2c.c +++ b/drivers/mfd/88pm860x-i2c.c @@ -200,8 +200,6 @@ static int __devexit pm860x_remove(struct i2c_client *client) pm860x_device_exit(chip); i2c_unregister_device(chip->companion); - i2c_set_clientdata(chip->client, NULL); - i2c_set_clientdata(client, NULL); kfree(chip); return 0; } diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index 53ebfee548fa..66379b413906 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c @@ -957,7 +957,6 @@ static int __init ab3100_probe(struct i2c_client *client, i2c_unregister_device(ab3100->testreg_client); exit_no_testreg_client: exit_no_detect: - i2c_set_clientdata(client, NULL); kfree(ab3100); return err; } @@ -979,7 +978,6 @@ static int __exit ab3100_remove(struct i2c_client *client) * their notifiers so deactivate IRQ */ free_irq(client->irq, ab3100); - i2c_set_clientdata(client, NULL); kfree(ab3100); return 0; } diff --git a/drivers/mfd/ab3550-core.c b/drivers/mfd/ab3550-core.c index 1060f8e1c40a..f54ab62e7bc6 100644 --- a/drivers/mfd/ab3550-core.c +++ b/drivers/mfd/ab3550-core.c @@ -1362,7 +1362,6 @@ static int __exit ab3550_remove(struct i2c_client *client) * their notifiers so deactivate IRQ */ free_irq(client->irq, ab); - i2c_set_clientdata(client, NULL); kfree(ab); return 0; } diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c index 005532865654..3122139b4300 100644 --- a/drivers/mfd/adp5520.c +++ b/drivers/mfd/adp5520.c @@ -302,7 +302,6 @@ out_free_irq: free_irq(chip->irq, chip); out_free_chip: - i2c_set_clientdata(client, NULL); kfree(chip); return ret; @@ -317,7 +316,6 @@ static int __devexit adp5520_remove(struct i2c_client *client) adp5520_remove_subdevs(chip); adp5520_write(chip->dev, ADP5520_MODE_STATUS, 0); - i2c_set_clientdata(client, NULL); kfree(chip); return 0; } diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c index 3ad915d0589c..c07aece900fb 100644 --- a/drivers/mfd/da903x.c +++ b/drivers/mfd/da903x.c @@ -534,7 +534,6 @@ static int __devinit da903x_probe(struct i2c_client *client, out_free_irq: free_irq(client->irq, chip); out_free_chip: - i2c_set_clientdata(client, NULL); kfree(chip); return ret; } @@ -544,7 +543,6 @@ static int __devexit da903x_remove(struct i2c_client *client) struct da903x_chip *chip = i2c_get_clientdata(client); da903x_remove_subdevs(chip); - i2c_set_clientdata(client, NULL); kfree(chip); return 0; } diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c index e73f3f5252a8..0219115e00c7 100644 --- a/drivers/mfd/max8925-i2c.c +++ b/drivers/mfd/max8925-i2c.c @@ -173,7 +173,6 @@ static int __devexit max8925_remove(struct i2c_client *client) max8925_device_exit(chip); i2c_unregister_device(chip->adc); i2c_unregister_device(chip->rtc); - i2c_set_clientdata(chip->i2c, NULL); kfree(chip); return 0; } diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c index 721948be12c7..a3fb4bcb9889 100644 --- a/drivers/mfd/menelaus.c +++ b/drivers/mfd/menelaus.c @@ -1228,7 +1228,6 @@ fail2: free_irq(client->irq, menelaus); flush_scheduled_work(); fail1: - i2c_set_clientdata(client, NULL); kfree(menelaus); return err; } @@ -1238,7 +1237,6 @@ static int __exit menelaus_remove(struct i2c_client *client) struct menelaus_chip *menelaus = i2c_get_clientdata(client); free_irq(client->irq, menelaus); - i2c_set_clientdata(client, NULL); kfree(menelaus); the_menelaus = NULL; return 0; diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 704736e6e9b9..23e585527285 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -336,7 +336,6 @@ static int __devinit pcf50633_probe(struct i2c_client *client, return 0; err_free: - i2c_set_clientdata(client, NULL); kfree(pcf); return ret; @@ -357,7 +356,6 @@ static int __devexit pcf50633_remove(struct i2c_client *client) for (i = 0; i < PCF50633_NUM_REGULATORS; i++) platform_device_unregister(pcf->regulator_pdev[i]); - i2c_set_clientdata(client, NULL); kfree(pcf); return 0; diff --git a/drivers/mfd/tc35892.c b/drivers/mfd/tc35892.c index 715f095dd7a6..e619e2a55997 100644 --- a/drivers/mfd/tc35892.c +++ b/drivers/mfd/tc35892.c @@ -296,7 +296,6 @@ out_freeirq: out_removeirq: tc35892_irq_remove(tc35892); out_free: - i2c_set_clientdata(i2c, NULL); kfree(tc35892); return ret; } @@ -310,7 +309,6 @@ static int __devexit tc35892_remove(struct i2c_client *client) free_irq(tc35892->i2c->irq, tc35892); tc35892_irq_remove(tc35892); - i2c_set_clientdata(client, NULL); kfree(tc35892); return 0; diff --git a/drivers/mfd/tps65010.c b/drivers/mfd/tps65010.c index 9b22a77f70f5..d0016b67d125 100644 --- a/drivers/mfd/tps65010.c +++ b/drivers/mfd/tps65010.c @@ -530,7 +530,6 @@ static int __exit tps65010_remove(struct i2c_client *client) cancel_delayed_work(&tps->work); flush_scheduled_work(); debugfs_remove(tps->file); - i2c_set_clientdata(client, NULL); kfree(tps); the_tps = NULL; return 0; diff --git a/drivers/mfd/wm8350-i2c.c b/drivers/mfd/wm8350-i2c.c index 7795af4b1fe1..5fe5de166adb 100644 --- a/drivers/mfd/wm8350-i2c.c +++ b/drivers/mfd/wm8350-i2c.c @@ -80,7 +80,6 @@ static int wm8350_i2c_probe(struct i2c_client *i2c, return ret; err: - i2c_set_clientdata(i2c, NULL); kfree(wm8350); return ret; } @@ -90,7 +89,6 @@ static int wm8350_i2c_remove(struct i2c_client *i2c) struct wm8350 *wm8350 = i2c_get_clientdata(i2c); wm8350_device_exit(wm8350); - i2c_set_clientdata(i2c, NULL); kfree(wm8350); return 0; diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c index e08aafa663dc..1bfef4846b07 100644 --- a/drivers/mfd/wm8400-core.c +++ b/drivers/mfd/wm8400-core.c @@ -415,7 +415,6 @@ static int wm8400_i2c_probe(struct i2c_client *i2c, return 0; struct_err: - i2c_set_clientdata(i2c, NULL); kfree(wm8400); err: return ret; @@ -426,7 +425,6 @@ static int wm8400_i2c_remove(struct i2c_client *i2c) struct wm8400 *wm8400 = i2c_get_clientdata(i2c); wm8400_release(wm8400); - i2c_set_clientdata(i2c, NULL); kfree(wm8400); return 0; diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index f7ca3a42b490..559b0b3c16c3 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -643,7 +643,6 @@ static int __devexit at24_remove(struct i2c_client *client) kfree(at24->writebuf); kfree(at24); - i2c_set_clientdata(client, NULL); return 0; } diff --git a/drivers/mtd/maps/pismo.c b/drivers/mtd/maps/pismo.c index eb476b7f8d11..f4ce273e93fd 100644 --- a/drivers/mtd/maps/pismo.c +++ b/drivers/mtd/maps/pismo.c @@ -234,7 +234,6 @@ static int __devexit pismo_remove(struct i2c_client *client) /* FIXME: set_vpp needs saner arguments */ pismo_setvpp_remove_fix(pismo); - i2c_set_clientdata(client, NULL); kfree(pismo); return 0; @@ -286,7 +285,6 @@ static int __devinit pismo_probe(struct i2c_client *client, return 0; exit_free: - i2c_set_clientdata(client, NULL); kfree(pismo); return ret; } diff --git a/drivers/power/max17040_battery.c b/drivers/power/max17040_battery.c index f3e22c9fe20a..2f2f9a6f54fa 100644 --- a/drivers/power/max17040_battery.c +++ b/drivers/power/max17040_battery.c @@ -225,7 +225,6 @@ static int __devinit max17040_probe(struct i2c_client *client, ret = power_supply_register(&client->dev, &chip->battery); if (ret) { dev_err(&client->dev, "failed: power supply register\n"); - i2c_set_clientdata(client, NULL); kfree(chip); return ret; } @@ -245,7 +244,6 @@ static int __devexit max17040_remove(struct i2c_client *client) power_supply_unregister(&chip->battery); cancel_delayed_work(&chip->work); - i2c_set_clientdata(client, NULL); kfree(chip); return 0; } diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c index 671a7d1f1f0e..8ae3732eb24b 100644 --- a/drivers/regulator/lp3971.c +++ b/drivers/regulator/lp3971.c @@ -519,8 +519,6 @@ static int __devexit lp3971_i2c_remove(struct i2c_client *i2c) struct lp3971 *lp3971 = i2c_get_clientdata(i2c); int i; - i2c_set_clientdata(i2c, NULL); - for (i = 0; i < lp3971->num_regulators; i++) regulator_unregister(lp3971->rdev[i]); diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index b3c1afc16889..2b54d9d75f11 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c @@ -244,7 +244,6 @@ static int __devexit max1586_pmic_remove(struct i2c_client *client) for (i = 0; i <= MAX1586_V6; i++) if (rdev[i]) regulator_unregister(rdev[i]); - i2c_set_clientdata(client, NULL); kfree(rdev); return 0; diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index bfc4c5ffdc96..4520ace3f7e7 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c @@ -357,7 +357,6 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, dev_info(info->dev, "Max8649 regulator device is detected.\n"); return 0; out: - i2c_set_clientdata(client, NULL); kfree(info); return ret; } @@ -369,7 +368,6 @@ static int __devexit max8649_regulator_remove(struct i2c_client *client) if (info) { if (info->regulator) regulator_unregister(info->regulator); - i2c_set_clientdata(client, NULL); kfree(info); } diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index 3790b21879ff..d97220efae5a 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c @@ -471,7 +471,6 @@ static int __devexit max8660_remove(struct i2c_client *client) for (i = 0; i < MAX8660_V_END; i++) if (rdev[i]) regulator_unregister(rdev[i]); - i2c_set_clientdata(client, NULL); kfree(rdev); return 0; diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index 8e2f2098b005..f50afc9f287a 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c @@ -538,9 +538,6 @@ static int __devexit tps_65023_remove(struct i2c_client *client) struct tps_pmic *tps = i2c_get_clientdata(client); int i; - /* clear the client data in i2c */ - i2c_set_clientdata(client, NULL); - for (i = 0; i < TPS65023_NUM_REGULATOR; i++) regulator_unregister(tps->rdev[i]); diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 61945734ad00..1f0007fd4431 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c @@ -403,7 +403,6 @@ out_irq: free_irq(client->irq, client); out_free: - i2c_set_clientdata(client, NULL); kfree(ds1374); return ret; } @@ -422,7 +421,6 @@ static int __devexit ds1374_remove(struct i2c_client *client) } rtc_device_unregister(ds1374->rtc); - i2c_set_clientdata(client, NULL); kfree(ds1374); return 0; } diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index b65c82f792d9..789f62f9b47d 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c @@ -632,7 +632,6 @@ errout_reg: rtc_device_unregister(rx8025->rtc); errout_free: - i2c_set_clientdata(client, NULL); kfree(rx8025); errout: @@ -656,7 +655,6 @@ static int __devexit rx8025_remove(struct i2c_client *client) rx8025_sysfs_unregister(&client->dev); rtc_device_unregister(rx8025->rtc); - i2c_set_clientdata(client, NULL); kfree(rx8025); return 0; } diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index def4d396d0b0..f789e002c9b0 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -275,7 +275,6 @@ exit_dummy: if (s35390a->client[i]) i2c_unregister_device(s35390a->client[i]); kfree(s35390a); - i2c_set_clientdata(client, NULL); exit: return err; @@ -292,7 +291,6 @@ static int s35390a_remove(struct i2c_client *client) rtc_device_unregister(s35390a->rtc); kfree(s35390a); - i2c_set_clientdata(client, NULL); return 0; } diff --git a/drivers/staging/dream/synaptics_i2c_rmi.c b/drivers/staging/dream/synaptics_i2c_rmi.c index 1f020dad6234..3320359408a9 100644 --- a/drivers/staging/dream/synaptics_i2c_rmi.c +++ b/drivers/staging/dream/synaptics_i2c_rmi.c @@ -519,7 +519,6 @@ err_input_register_device_failed: err_input_dev_alloc_failed: err_detect_failed: err_power_failed: - i2c_set_clientdata(client, NULL); kfree(ts); err_alloc_data_failed: err_check_functionality_failed: @@ -537,7 +536,6 @@ static int synaptics_ts_remove(struct i2c_client *client) else hrtimer_cancel(&ts->timer); input_unregister_device(ts->input_dev); - i2c_set_clientdata(client, NULL); kfree(ts); return 0; } diff --git a/drivers/staging/go7007/wis-saa7113.c b/drivers/staging/go7007/wis-saa7113.c index bd925457f8b7..72f5c1f56d19 100644 --- a/drivers/staging/go7007/wis-saa7113.c +++ b/drivers/staging/go7007/wis-saa7113.c @@ -289,7 +289,6 @@ static int wis_saa7113_probe(struct i2c_client *client, if (write_regs(client, initial_registers) < 0) { printk(KERN_ERR "wis-saa7113: error initializing SAA7113\n"); - i2c_set_clientdata(client, NULL); kfree(dec); return -ENODEV; } @@ -301,7 +300,6 @@ static int wis_saa7113_remove(struct i2c_client *client) { struct wis_saa7113 *dec = i2c_get_clientdata(client); - i2c_set_clientdata(client, NULL); kfree(dec); return 0; } diff --git a/drivers/staging/go7007/wis-saa7115.c b/drivers/staging/go7007/wis-saa7115.c index b2eb804c1954..cd950b61cf70 100644 --- a/drivers/staging/go7007/wis-saa7115.c +++ b/drivers/staging/go7007/wis-saa7115.c @@ -422,7 +422,6 @@ static int wis_saa7115_probe(struct i2c_client *client, if (write_regs(client, initial_registers) < 0) { printk(KERN_ERR "wis-saa7115: error initializing SAA7115\n"); - i2c_set_clientdata(client, NULL); kfree(dec); return -ENODEV; } @@ -434,7 +433,6 @@ static int wis_saa7115_remove(struct i2c_client *client) { struct wis_saa7115 *dec = i2c_get_clientdata(client); - i2c_set_clientdata(client, NULL); kfree(dec); return 0; } diff --git a/drivers/staging/go7007/wis-sony-tuner.c b/drivers/staging/go7007/wis-sony-tuner.c index b1013291190f..981c9b311b8b 100644 --- a/drivers/staging/go7007/wis-sony-tuner.c +++ b/drivers/staging/go7007/wis-sony-tuner.c @@ -684,7 +684,6 @@ static int wis_sony_tuner_remove(struct i2c_client *client) { struct wis_sony_tuner *t = i2c_get_clientdata(client); - i2c_set_clientdata(client, NULL); kfree(t); return 0; } diff --git a/drivers/staging/go7007/wis-tw2804.c b/drivers/staging/go7007/wis-tw2804.c index 315268d130dd..ee28a99dc388 100644 --- a/drivers/staging/go7007/wis-tw2804.c +++ b/drivers/staging/go7007/wis-tw2804.c @@ -323,7 +323,6 @@ static int wis_tw2804_remove(struct i2c_client *client) { struct wis_tw2804 *dec = i2c_get_clientdata(client); - i2c_set_clientdata(client, NULL); kfree(dec); return 0; } diff --git a/drivers/staging/go7007/wis-tw9903.c b/drivers/staging/go7007/wis-tw9903.c index 2afea09091b9..80d47269b1c0 100644 --- a/drivers/staging/go7007/wis-tw9903.c +++ b/drivers/staging/go7007/wis-tw9903.c @@ -294,7 +294,6 @@ static int wis_tw9903_probe(struct i2c_client *client, if (write_regs(client, initial_registers) < 0) { printk(KERN_ERR "wis-tw9903: error initializing TW9903\n"); - i2c_set_clientdata(client, NULL); kfree(dec); return -ENODEV; } @@ -306,7 +305,6 @@ static int wis_tw9903_remove(struct i2c_client *client) { struct wis_tw9903 *dec = i2c_get_clientdata(client); - i2c_set_clientdata(client, NULL); kfree(dec); return 0; } diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index 20e267448d1f..905f8560d31f 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -1011,7 +1011,6 @@ error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); error_free_st: - i2c_set_clientdata(client, NULL); kfree(st); error_ret: @@ -1030,7 +1029,6 @@ static int max1363_remove(struct i2c_client *client) regulator_disable(st->reg); regulator_put(st->reg); } - i2c_set_clientdata(client, NULL); kfree(st); return 0; diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c index 43aaacff4e74..e4b0a5ef1c1f 100644 --- a/drivers/staging/iio/light/tsl2563.c +++ b/drivers/staging/iio/light/tsl2563.c @@ -694,7 +694,6 @@ static int __devinit tsl2563_probe(struct i2c_client *client, fail2: iio_device_unregister(chip->indio_dev); fail1: - i2c_set_clientdata(client, NULL); kfree(chip); return err; } @@ -705,7 +704,6 @@ static int tsl2563_remove(struct i2c_client *client) iio_device_unregister(chip->indio_dev); - i2c_set_clientdata(client, NULL); kfree(chip); return 0; } diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c index 921ca37398f3..3ec24609151e 100644 --- a/drivers/video/backlight/adp8860_bl.c +++ b/drivers/video/backlight/adp8860_bl.c @@ -756,7 +756,6 @@ out: out1: backlight_device_unregister(bl); out2: - i2c_set_clientdata(client, NULL); kfree(data); return ret; @@ -776,7 +775,6 @@ static int __devexit adp8860_remove(struct i2c_client *client) &adp8860_bl_attr_group); backlight_device_unregister(data->bl); - i2c_set_clientdata(client, NULL); kfree(data); return 0; diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c index e03e60bbfd85..2a04b382ec48 100644 --- a/drivers/video/backlight/tosa_bl.c +++ b/drivers/video/backlight/tosa_bl.c @@ -119,7 +119,6 @@ static int __devinit tosa_bl_probe(struct i2c_client *client, err_reg: data->bl = NULL; - i2c_set_clientdata(client, NULL); err_gpio_dir: gpio_free(TOSA_GPIO_BL_C20MA); err_gpio_bl: @@ -133,7 +132,6 @@ static int __devexit tosa_bl_remove(struct i2c_client *client) backlight_device_unregister(data->bl); data->bl = NULL; - i2c_set_clientdata(client, NULL); gpio_free(TOSA_GPIO_BL_C20MA); -- cgit v1.2.3 From d42a8f464ba14467e5d45dc0eb8f789c82bd0679 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 1 Jun 2010 11:32:43 +0000 Subject: sfc: Get port number from CS_PORT_NUM, not PCI function number A single shared memory region used to communicate with firmware is mapped into both PCI PFs of the SFC9020 and SFL9021. Drivers must be able to identify which port they are addressing in order to use the correct sub-region. Currently we use the PCI function number, but the PCI address may be virtualised. Use the CS_PORT_NUM register field defined for just this purpose. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/net_driver.h | 4 +++- drivers/net/sfc/siena.c | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 2e6fd89f2a72..5fffd9abffde 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -645,6 +645,7 @@ union efx_multicast_hash { * struct efx_nic - an Efx NIC * @name: Device name (net device name or bus id before net device registered) * @pci_dev: The PCI device + * @port_num: Index of this host port within the controller * @type: Controller type attributes * @legacy_irq: IRQ number * @workqueue: Workqueue for port reconfigures and the HW monitor. @@ -728,6 +729,7 @@ union efx_multicast_hash { struct efx_nic { char name[IFNAMSIZ]; struct pci_dev *pci_dev; + unsigned port_num; const struct efx_nic_type *type; int legacy_irq; struct workqueue_struct *workqueue; @@ -830,7 +832,7 @@ static inline const char *efx_dev_name(struct efx_nic *efx) static inline unsigned int efx_port_num(struct efx_nic *efx) { - return PCI_FUNC(efx->pci_dev->devfn); + return efx->port_num; } /** diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index 727b4228e081..7ecd255a7cc0 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -206,6 +206,7 @@ static int siena_probe_nic(struct efx_nic *efx) { struct siena_nic_data *nic_data; bool already_attached = 0; + efx_oword_t reg; int rc; /* Allocate storage for hardware specific data */ @@ -220,6 +221,9 @@ static int siena_probe_nic(struct efx_nic *efx) goto fail1; } + efx_reado(efx, ®, FR_AZ_CS_DEBUG); + efx->port_num = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1; + efx_mcdi_init(efx); /* Recover from a failed assertion before probing */ -- cgit v1.2.3 From 3b21b508ecc9e043839a5337563cfc77f9fcedb9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 2 Jun 2010 13:43:15 +0000 Subject: e1000e: change logical negate to bitwise The bitwise negate is intended here. With the logical negate the condition is always false. Signed-off-by: Dan Carpenter Acked-by: Bruce Allan Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000e/netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 24507f3b8b17..57a7e41da69e 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -2554,7 +2554,7 @@ static void e1000_init_manageability_pt(struct e1000_adapter *adapter) mdef = er32(MDEF(i)); /* Ignore filters with anything other than IPMI ports */ - if (mdef & !(E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664)) + if (mdef & ~(E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664)) continue; /* Enable this decision filter in MANC2H */ -- cgit v1.2.3 From 60a5711db646b87b9530b16cbaf3bd53ac5594a5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 2 Jun 2010 23:56:13 +0000 Subject: isdn/kcapi: return -EFAULT on copy_from_user errors copy_from_user() returns the number of bytes remaining but we should return -EFAULT here. The error code gets returned to the user. Both old_capi_manufacturer() and capi20_manufacturer() had other places that already returned -EFAULT so this won't break anything. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/isdn/capi/kcapi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c index bde3c88b8b27..b054494df846 100644 --- a/drivers/isdn/capi/kcapi.c +++ b/drivers/isdn/capi/kcapi.c @@ -1020,12 +1020,12 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data) if (cmd == AVMB1_ADDCARD) { if ((retval = copy_from_user(&cdef, data, sizeof(avmb1_carddef)))) - return retval; + return -EFAULT; cdef.cardtype = AVM_CARDTYPE_B1; } else { if ((retval = copy_from_user(&cdef, data, sizeof(avmb1_extcarddef)))) - return retval; + return -EFAULT; } cparams.port = cdef.port; cparams.irq = cdef.irq; @@ -1218,7 +1218,7 @@ int capi20_manufacturer(unsigned int cmd, void __user *data) kcapi_carddef cdef; if ((retval = copy_from_user(&cdef, data, sizeof(cdef)))) - return retval; + return -EFAULT; cparams.port = cdef.port; cparams.irq = cdef.irq; -- cgit v1.2.3 From d23380701876dd93d310b2548c51d0f78f25d7aa Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 3 Jun 2010 00:05:35 +0000 Subject: tehuti: return -EFAULT on copy_to_user errors copy_to_user() returns the number of bytes remaining but we want to return a negative error code here. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/tehuti.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index 20ab16192325..737df6032bbc 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c @@ -646,7 +646,7 @@ static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd) error = copy_from_user(data, ifr->ifr_data, sizeof(data)); if (error) { pr_err("cant copy from user\n"); - RET(error); + RET(-EFAULT); } DBG("%d 0x%x 0x%x\n", data[0], data[1], data[2]); } @@ -665,7 +665,7 @@ static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd) data[2]); error = copy_to_user(ifr->ifr_data, data, sizeof(data)); if (error) - RET(error); + RET(-EFAULT); break; case BDX_OP_WRITE: -- cgit v1.2.3 From 9e2d11b926765681f72db0373d2ecbbac28359b3 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Wed, 2 Jun 2010 10:36:53 +0000 Subject: epic100: Test __BIG_ENDIAN instead of (non-existent) CONFIG_BIG_ENDIAN Probably no one has used this driver on big-endian systems, since it was setting up descriptor swapping if CONFIG_BIG_ENDIAN is set, which it never is, since that symbol is not mentioned anywhere else in the kernel source. Switch this test to a check for __BIG_ENDIAN so it has a chance at working. Signed-off-by: Roland Dreier Acked-by: Jeff Garzik Signed-off-by: David S. Miller --- drivers/net/epic100.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index 6838dfc9ef23..4c274657283c 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -87,6 +87,7 @@ static int rx_copybreak; #include #include #include +#include /* These identify the driver base version and may not be removed. */ static char version[] __devinitdata = @@ -230,7 +231,7 @@ static const u16 media2miictl[16] = { * The EPIC100 Rx and Tx buffer descriptors. Note that these * really ARE host-endian; it's not a misannotation. We tell * the card to byteswap them internally on big-endian hosts - - * look for #ifdef CONFIG_BIG_ENDIAN in epic_open(). + * look for #ifdef __BIG_ENDIAN in epic_open(). */ struct epic_tx_desc { @@ -690,7 +691,7 @@ static int epic_open(struct net_device *dev) outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL); /* Tell the chip to byteswap descriptors on big-endian hosts */ -#ifdef CONFIG_BIG_ENDIAN +#ifdef __BIG_ENDIAN outl(0x4432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); inl(ioaddr + GENCTL); outl(0x0432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); @@ -806,7 +807,7 @@ static void epic_restart(struct net_device *dev) for (i = 16; i > 0; i--) outl(0x0008, ioaddr + TEST1); -#ifdef CONFIG_BIG_ENDIAN +#ifdef __BIG_ENDIAN outl(0x0432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); #else outl(0x0412 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); -- cgit v1.2.3 From 3df95ce948dc8ceef07b49003ab944aa047f2a79 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 2 Jun 2010 10:39:56 +0000 Subject: sfc: Store port number in net_device::dev_id This exposes the port number to userland through sysfs. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/net_driver.h | 4 +--- drivers/net/sfc/siena.c | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 5fffd9abffde..4762c91cb587 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -645,7 +645,6 @@ union efx_multicast_hash { * struct efx_nic - an Efx NIC * @name: Device name (net device name or bus id before net device registered) * @pci_dev: The PCI device - * @port_num: Index of this host port within the controller * @type: Controller type attributes * @legacy_irq: IRQ number * @workqueue: Workqueue for port reconfigures and the HW monitor. @@ -729,7 +728,6 @@ union efx_multicast_hash { struct efx_nic { char name[IFNAMSIZ]; struct pci_dev *pci_dev; - unsigned port_num; const struct efx_nic_type *type; int legacy_irq; struct workqueue_struct *workqueue; @@ -832,7 +830,7 @@ static inline const char *efx_dev_name(struct efx_nic *efx) static inline unsigned int efx_port_num(struct efx_nic *efx) { - return efx->port_num; + return efx->net_dev->dev_id; } /** diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index 7ecd255a7cc0..f2b1e6180753 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -222,7 +222,7 @@ static int siena_probe_nic(struct efx_nic *efx) } efx_reado(efx, ®, FR_AZ_CS_DEBUG); - efx->port_num = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1; + efx->net_dev->dev_id = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1; efx_mcdi_init(efx); -- cgit v1.2.3 From a1868dc2878e61778b9d6d8c61d5368e51d68a29 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Wed, 2 Jun 2010 12:44:05 +0000 Subject: ixgbe: return IXGBE_ERR_RAR_INDEX when out of range Based on original patch from Shirley Ma Return IXGBE_ERR_RAR_INDEX when RAR index is out of range, instead of returning IXGBE_SUCCESS. CC: Shirley Ma Signed-off-by: Jeff Kirsher Acked-by: Don Skidmore Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_common.c | 2 ++ drivers/net/ixgbe/ixgbe_type.h | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 1159d9138f05..9595b1bfb8dd 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -1188,6 +1188,7 @@ s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); } else { hw_dbg(hw, "RAR index %d is out of range.\n", index); + return IXGBE_ERR_RAR_INDEX; } return 0; @@ -1219,6 +1220,7 @@ s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index) IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); } else { hw_dbg(hw, "RAR index %d is out of range.\n", index); + return IXGBE_ERR_RAR_INDEX; } /* clear VMDq pool/queue selection for this RAR */ diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 2eb6e151016c..cdd1998f18c7 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -2609,6 +2609,7 @@ struct ixgbe_info { #define IXGBE_ERR_EEPROM_VERSION -24 #define IXGBE_ERR_NO_SPACE -25 #define IXGBE_ERR_OVERTEMP -26 +#define IXGBE_ERR_RAR_INDEX -27 #define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF #endif /* _IXGBE_TYPE_H_ */ -- cgit v1.2.3 From a5b365a652206ca300256974ed9301a7d241a6ed Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 25 May 2010 14:17:54 +0200 Subject: virtio-blk: fix minimum number of S/G elements We need at least one S/G element to operate properly, as does the block layer which increments it to one anyway. We hit this due to a qemu bug which advertises a sg_elements of 0 under some circumstances. Signed-off-by: Christoph Hellwig Signed-off-by: Rusty Russell (tweaked logic) --- drivers/block/virtio_blk.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 83fa09a836ca..258bc2ae2885 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -298,7 +298,9 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX, offsetof(struct virtio_blk_config, seg_max), &sg_elems); - if (err) + + /* We need at least one SG element, whatever they say. */ + if (err || !sg_elems) sg_elems = 1; /* We need an extra sg elements at head and tail. */ -- cgit v1.2.3 From 0047634d3daebca9e99a22eb89167bf77f35cdfa Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Thu, 27 May 2010 13:24:39 +0530 Subject: virtio: console: Fix crash when hot-unplugging a port and read is blocked When removing a port we don't check if a program was blocked for read. This leads to a crash when SIGTERM is sent to the program after hot-unplugging the port. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 8c99bf1b5e9f..e3fb5296cf25 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1099,6 +1099,13 @@ static int remove_port(struct port *port) { struct port_buffer *buf; + if (port->guest_connected) { + port->guest_connected = false; + port->host_connected = false; + wake_up_interruptible(&port->waitqueue); + send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 0); + } + spin_lock_irq(&port->portdev->ports_lock); list_del(&port->list); spin_unlock_irq(&port->portdev->ports_lock); @@ -1120,9 +1127,6 @@ static int remove_port(struct port *port) hvc_remove(port->cons.hvc); #endif } - if (port->guest_connected) - send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 0); - sysfs_remove_group(&port->dev->kobj, &port_attribute_group); device_destroy(pdrvdata.class, port->dev->devt); cdev_del(&port->cdev); -- cgit v1.2.3 From 60e5e0b84045ce0f6ab07a02c7fcd6627b53d2d3 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Thu, 27 May 2010 13:24:40 +0530 Subject: virtio: console: Fix crash when port is unplugged and blocked for write When a program that has a virtio port opened and blocked for a write operation, a port hot-unplug event will later led to a crash when SIGTERM was sent to the program. Fix that. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index e3fb5296cf25..942a9826bd23 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -529,6 +529,10 @@ static bool will_write_block(struct port *port) { bool ret; + if (!port->guest_connected) { + /* Port got hot-unplugged. Let's exit. */ + return false; + } if (!port->host_connected) return true; -- cgit v1.2.3 From 3a4b4aaa546fa3d57b2ea7f41234f7d2e328da3f Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Thu, 3 Jun 2010 22:10:21 -0700 Subject: Input: wacom - add Cintiq 21UX2 and Intuos4 WL Signed-off-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 1 - drivers/input/tablet/wacom_wac.c | 73 ++++++++++++++++++++++++++++++++-------- drivers/input/tablet/wacom_wac.h | 1 + 3 files changed, 60 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 2dc0c07c0469..42ba3691d908 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -507,7 +507,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i goto fail3; } - input_dev->name = wacom_wac->name; input_dev->name = wacom_wac->name; input_dev->dev.parent = &intf->dev; input_dev->open = wacom_open; diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 847fd0135bcf..d564af58175c 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -300,7 +300,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) case 0x823: /* Intuos3 Grip Pen */ case 0x813: /* Intuos3 Classic Pen */ case 0x885: /* Intuos3 Marker Pen */ - case 0x802: /* Intuos4 Grip Pen Eraser */ + case 0x802: /* Intuos4 General Pen */ case 0x804: /* Intuos4 Marker Pen */ case 0x40802: /* Intuos4 Classic Pen */ case 0x022: @@ -335,7 +335,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) case 0x81b: /* Intuos3 Classic Pen Eraser */ case 0x91b: /* Intuos3 Airbrush Eraser */ case 0x80c: /* Intuos4 Marker Pen Eraser */ - case 0x80a: /* Intuos4 Grip Pen Eraser */ + case 0x80a: /* Intuos4 General Pen Eraser */ case 0x4080a: /* Intuos4 Classic Pen Eraser */ case 0x90a: /* Intuos4 Airbrush Eraser */ wacom->tool[idx] = BTN_TOOL_RUBBER; @@ -356,6 +356,11 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) return 1; } + /* older I4 styli don't work with new Cintiqs */ + if (!((wacom->id[idx] >> 20) & 0x01) && + (features->type == WACOM_21UX2)) + return 1; + /* Exit report */ if ((data[1] & 0xfe) == 0x80) { /* @@ -474,21 +479,43 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) input_report_abs(input, ABS_MISC, 0); } } else { - input_report_key(input, BTN_0, (data[5] & 0x01)); - input_report_key(input, BTN_1, (data[5] & 0x02)); - input_report_key(input, BTN_2, (data[5] & 0x04)); - input_report_key(input, BTN_3, (data[5] & 0x08)); - input_report_key(input, BTN_4, (data[6] & 0x01)); - input_report_key(input, BTN_5, (data[6] & 0x02)); - input_report_key(input, BTN_6, (data[6] & 0x04)); - input_report_key(input, BTN_7, (data[6] & 0x08)); - input_report_key(input, BTN_8, (data[5] & 0x10)); - input_report_key(input, BTN_9, (data[6] & 0x10)); + if (features->type == WACOM_21UX2) { + input_report_key(input, BTN_0, (data[5] & 0x01)); + input_report_key(input, BTN_1, (data[6] & 0x01)); + input_report_key(input, BTN_2, (data[6] & 0x02)); + input_report_key(input, BTN_3, (data[6] & 0x04)); + input_report_key(input, BTN_4, (data[6] & 0x08)); + input_report_key(input, BTN_5, (data[6] & 0x10)); + input_report_key(input, BTN_6, (data[6] & 0x20)); + input_report_key(input, BTN_7, (data[6] & 0x40)); + input_report_key(input, BTN_8, (data[6] & 0x80)); + input_report_key(input, BTN_9, (data[7] & 0x01)); + input_report_key(input, BTN_A, (data[8] & 0x01)); + input_report_key(input, BTN_B, (data[8] & 0x02)); + input_report_key(input, BTN_C, (data[8] & 0x04)); + input_report_key(input, BTN_X, (data[8] & 0x08)); + input_report_key(input, BTN_Y, (data[8] & 0x10)); + input_report_key(input, BTN_Z, (data[8] & 0x20)); + input_report_key(input, BTN_BASE, (data[8] & 0x40)); + input_report_key(input, BTN_BASE2, (data[8] & 0x80)); + } else { + input_report_key(input, BTN_0, (data[5] & 0x01)); + input_report_key(input, BTN_1, (data[5] & 0x02)); + input_report_key(input, BTN_2, (data[5] & 0x04)); + input_report_key(input, BTN_3, (data[5] & 0x08)); + input_report_key(input, BTN_4, (data[6] & 0x01)); + input_report_key(input, BTN_5, (data[6] & 0x02)); + input_report_key(input, BTN_6, (data[6] & 0x04)); + input_report_key(input, BTN_7, (data[6] & 0x08)); + input_report_key(input, BTN_8, (data[5] & 0x10)); + input_report_key(input, BTN_9, (data[6] & 0x10)); + } input_report_abs(input, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); input_report_abs(input, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); if ((data[5] & 0x1f) | (data[6] & 0x1f) | (data[1] & 0x1f) | - data[2] | (data[3] & 0x1f) | data[4]) { + data[2] | (data[3] & 0x1f) | data[4] | data[8] | + (data[7] & 0x01)) { input_report_key(input, wacom->tool[1], 1); input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); } else { @@ -640,7 +667,7 @@ static void wacom_tpc_finger_in(struct wacom_wac *wacom, char *data, int idx) if (!idx) input_report_key(input, BTN_TOUCH, 1); input_event(input, EV_MSC, MSC_SERIAL, finger); - input_sync(wacom->input); + input_sync(input); wacom->last_finger = finger; } @@ -826,6 +853,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) case INTUOS4L: case CINTIQ: case WACOM_BEE: + case WACOM_21UX2: sync = wacom_intuos_irq(wacom_wac); break; @@ -921,6 +949,17 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, __set_bit(BTN_STYLUS2, input_dev->keybit); break; + case WACOM_21UX2: + __set_bit(BTN_A, input_dev->keybit); + __set_bit(BTN_B, input_dev->keybit); + __set_bit(BTN_C, input_dev->keybit); + __set_bit(BTN_X, input_dev->keybit); + __set_bit(BTN_Y, input_dev->keybit); + __set_bit(BTN_Z, input_dev->keybit); + __set_bit(BTN_BASE, input_dev->keybit); + __set_bit(BTN_BASE2, input_dev->keybit); + /* fall through */ + case WACOM_BEE: __set_bit(BTN_8, input_dev->keybit); __set_bit(BTN_9, input_dev->keybit); @@ -1105,6 +1144,8 @@ static const struct wacom_features wacom_features_0xBA = { "Wacom Intuos4 8x13", WACOM_PKGLEN_INTUOS, 65024, 40640, 2047, 63, INTUOS4L }; static const struct wacom_features wacom_features_0xBB = { "Wacom Intuos4 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 2047, 63, INTUOS4L }; +static const struct wacom_features wacom_features_0xBC = + { "Wacom Intuos4 WL", WACOM_PKGLEN_INTUOS, 40840, 25400, 2047, 63, INTUOS4 }; static const struct wacom_features wacom_features_0x3F = { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, 63, CINTIQ }; static const struct wacom_features wacom_features_0xC5 = @@ -1113,6 +1154,8 @@ static const struct wacom_features wacom_features_0xC6 = { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, 63, WACOM_BEE }; static const struct wacom_features wacom_features_0xC7 = { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, 0, PL }; +static const struct wacom_features wacom_features_0xCC = + { "Wacom Cintiq 21UX2", WACOM_PKGLEN_INTUOS, 87200, 65600, 2047, 63, WACOM_21UX2 }; static const struct wacom_features wacom_features_0x90 = { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; static const struct wacom_features wacom_features_0x93 = @@ -1185,10 +1228,12 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0xB9) }, { USB_DEVICE_WACOM(0xBA) }, { USB_DEVICE_WACOM(0xBB) }, + { USB_DEVICE_WACOM(0xBC) }, { USB_DEVICE_WACOM(0x3F) }, { USB_DEVICE_WACOM(0xC5) }, { USB_DEVICE_WACOM(0xC6) }, { USB_DEVICE_WACOM(0xC7) }, + { USB_DEVICE_WACOM(0xCC) }, { USB_DEVICE_WACOM(0x90) }, { USB_DEVICE_WACOM(0x93) }, { USB_DEVICE_WACOM(0x9A) }, diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 063f1af3204f..854b92092dfc 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h @@ -50,6 +50,7 @@ enum { INTUOS4S, INTUOS4, INTUOS4L, + WACOM_21UX2, CINTIQ, WACOM_BEE, WACOM_MO, -- cgit v1.2.3 From 157317ba3ec3e5a4d9683b8d24ba40b4f8f3296b Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Wed, 2 Jun 2010 11:04:09 +0800 Subject: ACPI: Fix the incorrect calculation about C-state idle time The C-state idle time is not calculated correctly, which will return the wrong residency time in C-state. It will have the following effects: 1. The system can't choose the deeper C-state when it is idle next time. Of course the system power is increased. E.g. On one server machine about 40W idle power is increased. 2. The powertop shows that it will stay in C0 running state about 95% time although the system is idle at most time. 2.6.35-rc1 regression caused-by: 2da513f582a96c053aacc2c92873978d2ea7abff (ACPI: Minor cleanup eliminating redundant PMTIMER_TICKS to NS conversion) Signed-off-by: Zhao Yakui Reported-by: Yu Zhidong Tested-by: Yu Zhidong Acked-by: Venkatesh Pallipadi Signed-off-by: Len Brown --- drivers/acpi/processor_idle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 2e8c27d48f2b..6b38a6b43ce8 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -1022,7 +1022,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, spin_unlock(&c3_lock); } kt2 = ktime_get_real(); - idle_time_ns = ktime_to_us(ktime_sub(kt2, kt1)); + idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1)); idle_time = idle_time_ns; do_div(idle_time, NSEC_PER_USEC); -- cgit v1.2.3 From bceefad59ab66d1b1a815a1738744ea013da966e Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Wed, 2 Jun 2010 10:01:09 -0700 Subject: ACPI: Eliminate us to pm ticks conversion in common path acpi_enter_[simple|bm] routines does us to pm tick conversion on every idle wakeup and the value is only used in /proc/acpi display. We can store the time in us and convert it into pm ticks before printing instead and avoid the conversion in the common path. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Len Brown --- drivers/acpi/processor_idle.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 6b38a6b43ce8..b1b385692f46 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -80,7 +80,7 @@ module_param(nocst, uint, 0000); static unsigned int latency_factor __read_mostly = 2; module_param(latency_factor, uint, 0644); -static s64 us_to_pm_timer_ticks(s64 t) +static u64 us_to_pm_timer_ticks(s64 t) { return div64_u64(t * PM_TIMER_FREQUENCY, 1000000); } @@ -731,10 +731,10 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) seq_puts(seq, "demotion[--] "); - seq_printf(seq, "latency[%03d] usage[%08d] duration[%020llu]\n", + seq_printf(seq, "latency[%03d] usage[%08d] duration[%020Lu]\n", pr->power.states[i].latency, pr->power.states[i].usage, - (unsigned long long)pr->power.states[i].time); + us_to_pm_timer_ticks(pr->power.states[i].time)); } end: @@ -861,7 +861,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, ktime_t kt1, kt2; s64 idle_time_ns; s64 idle_time; - s64 sleep_ticks = 0; pr = __get_cpu_var(processors); @@ -906,8 +905,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, idle_time = idle_time_ns; do_div(idle_time, NSEC_PER_USEC); - sleep_ticks = us_to_pm_timer_ticks(idle_time); - /* Tell the scheduler how much we idled: */ sched_clock_idle_wakeup_event(idle_time_ns); @@ -918,7 +915,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, cx->usage++; lapic_timer_state_broadcast(pr, cx, 0); - cx->time += sleep_ticks; + cx->time += idle_time; return idle_time; } @@ -940,7 +937,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, ktime_t kt1, kt2; s64 idle_time_ns; s64 idle_time; - s64 sleep_ticks = 0; pr = __get_cpu_var(processors); @@ -1026,7 +1022,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, idle_time = idle_time_ns; do_div(idle_time, NSEC_PER_USEC); - sleep_ticks = us_to_pm_timer_ticks(idle_time); /* Tell the scheduler how much we idled: */ sched_clock_idle_wakeup_event(idle_time_ns); @@ -1037,7 +1032,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, cx->usage++; lapic_timer_state_broadcast(pr, cx, 0); - cx->time += sleep_ticks; + cx->time += idle_time; return idle_time; } -- cgit v1.2.3 From 56bf882230d2266a2e07b7f404dc96d157a65daa Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Fri, 4 Jun 2010 14:47:35 -0400 Subject: Revert "wireless: hostap, fix oops due to early probing interrupt" This reverts commit 15920d8afc87861672e16fa95ae2764b065d6dd3. This patch was discovered to cause some hostap devices to fail to initialized. https://bugzilla.kernel.org/show_bug.cgi?id=16111 Signed-off-by: John W. Linville --- drivers/net/wireless/hostap/hostap_hw.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index d70732819423..ff9b5c882184 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c @@ -2618,15 +2618,6 @@ static irqreturn_t prism2_interrupt(int irq, void *dev_id) int events = 0; u16 ev; - /* Detect early interrupt before driver is fully configued */ - if (!dev->base_addr) { - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: Interrupt, but dev not configured\n", - dev->name); - } - return IRQ_HANDLED; - } - iface = netdev_priv(dev); local = iface->local; -- cgit v1.2.3 From e307139d7ad532761cdbf2a665f3c53c509a2d0e Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Sun, 30 May 2010 00:02:18 +0200 Subject: ath5k: depend on CONFIG_PM_SLEEP for suspend/resume functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When building a kernel with CONFIG_PM=y but neither suspend nor hibernate support, the compiler complains about the static functions ath5k_pci_suspend() and ath5k_pci_resume() not being used: drivers/net/wireless/ath/ath5k/base.c:713:12: warning: ‘ath5k_pci_suspend’ defined but not used drivers/net/wireless/ath/ath5k/base.c:722:12: warning: ‘ath5k_pci_resume’ defined but not used Depending on CONFIG_PM_SLEEP rather than CONFIG_PM fixes the issue. Signed-off-by: Tobias Doerffel Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 2978359c4366..53d95c83b11a 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -195,7 +195,7 @@ static const struct ieee80211_rate ath5k_rates[] = { static int __devinit ath5k_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); static void __devexit ath5k_pci_remove(struct pci_dev *pdev); -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int ath5k_pci_suspend(struct device *dev); static int ath5k_pci_resume(struct device *dev); @@ -203,7 +203,7 @@ static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); #define ATH5K_PM_OPS (&ath5k_pm_ops) #else #define ATH5K_PM_OPS NULL -#endif /* CONFIG_PM */ +#endif /* CONFIG_PM_SLEEP */ static struct pci_driver ath5k_pci_driver = { .name = KBUILD_MODNAME, @@ -708,7 +708,7 @@ ath5k_pci_remove(struct pci_dev *pdev) ieee80211_free_hw(hw); } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int ath5k_pci_suspend(struct device *dev) { struct ieee80211_hw *hw = pci_get_drvdata(to_pci_dev(dev)); @@ -734,7 +734,7 @@ static int ath5k_pci_resume(struct device *dev) ath5k_led_enable(sc); return 0; } -#endif /* CONFIG_PM */ +#endif /* CONFIG_PM_SLEEP */ /***********************\ -- cgit v1.2.3 From 6b5dcccb495b66b3b0b9581cdccfed038e5d68a2 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Fri, 4 Jun 2010 08:14:14 -0400 Subject: ath5k: retain promiscuous setting Commit 56d1de0a21db28e41741cfa0a66e18bc8d920554, "ath5k: clean up filter flags setting" introduced a regression in monitor mode such that the promisc filter flag would get lost. Although we set the promisc flag when it changed, we did not preserve it across subsequent calls to configure_filter. This patch restores the original functionality. Cc: stable@kernel.org Bisected-by: weedy2887@gmail.com Tested-by: weedy2887@gmail.com Tested-by: Rick Farina Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 53d95c83b11a..648972df369d 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -3140,13 +3140,15 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { if (*new_flags & FIF_PROMISC_IN_BSS) { - rfilt |= AR5K_RX_FILTER_PROM; __set_bit(ATH_STAT_PROMISC, sc->status); } else { __clear_bit(ATH_STAT_PROMISC, sc->status); } } + if (test_bit(ATH_STAT_PROMISC, sc->status)) + rfilt |= AR5K_RX_FILTER_PROM; + /* Note, AR5K_RX_FILTER_MCAST is already enabled */ if (*new_flags & FIF_ALLMULTI) { mfilt[0] = ~0; -- cgit v1.2.3 From b41709f1263bb1ad37efc43fea0bb0b670c12e78 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 19 May 2010 22:13:17 +0200 Subject: USB: mos7840: fix null-pointer dereference Fix null-pointer dereference on error path. Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mos7840.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index f8424d1bfc1b..585b7e663740 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -730,7 +730,6 @@ static void mos7840_bulk_in_callback(struct urb *urb) mos7840_port = urb->context; if (!mos7840_port) { dbg("%s", "NULL mos7840_port pointer"); - mos7840_port->read_urb_busy = false; return; } -- cgit v1.2.3 From 0c8a32dff4f9ebed3e067e52e12842d7d7e047a0 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 21 May 2010 04:37:42 -0400 Subject: USB: isp1362: fix inw warning on Blackfin systems The Blackfin code is incorrectly casting the argument to inw() to a pointer. Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp1362.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/isp1362.h b/drivers/usb/host/isp1362.h index 5151516ea1de..d995351f9bed 100644 --- a/drivers/usb/host/isp1362.h +++ b/drivers/usb/host/isp1362.h @@ -65,7 +65,7 @@ static inline void delayed_insw(unsigned int addr, void *buf, int len) unsigned short *bp = (unsigned short *)buf; while (len--) { DUMMY_DELAY_ACCESS; - *bp++ = inw((void *)addr); + *bp++ = inw(addr); } } -- cgit v1.2.3 From 2d62f3eea98354d61f90d6b115eecf9be5f4bdfe Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Mon, 24 May 2010 13:25:15 -0700 Subject: USB: xhci: Wait for controller to be ready after reset. After software resets an xHCI host controller, it must wait for the "Controller Not Ready" (CNR) bit in the status register to be cleared. Software is not supposed to ring any doorbells or write to any registers except the status register until this bit is cleared. Signed-off-by: Sarah Sharp Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 40e0a0c221b8..79ccfe5f8ad0 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -116,6 +116,7 @@ int xhci_reset(struct xhci_hcd *xhci) { u32 command; u32 state; + int ret; state = xhci_readl(xhci, &xhci->op_regs->status); if ((state & STS_HALT) == 0) { @@ -130,7 +131,17 @@ int xhci_reset(struct xhci_hcd *xhci) /* XXX: Why does EHCI set this here? Shouldn't other code do this? */ xhci_to_hcd(xhci)->state = HC_STATE_HALT; - return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000); + ret = handshake(xhci, &xhci->op_regs->command, + CMD_RESET, 0, 250 * 1000); + if (ret) + return ret; + + xhci_dbg(xhci, "Wait for controller to be ready for doorbell rings\n"); + /* + * xHCI cannot write to any doorbells or operational registers other + * than status until the "Controller Not Ready" flag is cleared. + */ + return handshake(xhci, &xhci->op_regs->status, STS_CNR, 0, 250 * 1000); } -- cgit v1.2.3 From ed07453fd356025cc25272629e982f5e4607632c Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Mon, 24 May 2010 13:25:21 -0700 Subject: USB: xhci: Wait for host to start running. When the run bit is set in the xHCI command register, it may take a few microseconds for the host to start running. We cannot ring any doorbells until the host is actually running, so wait until the status register says the host is running. Signed-off-by: Sarah Sharp Reported-by: Shinya Saito Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 79ccfe5f8ad0..8a49c6716b69 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -105,6 +105,33 @@ int xhci_halt(struct xhci_hcd *xhci) STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); } +/* + * Set the run bit and wait for the host to be running. + */ +int xhci_start(struct xhci_hcd *xhci) +{ + u32 temp; + int ret; + + temp = xhci_readl(xhci, &xhci->op_regs->command); + temp |= (CMD_RUN); + xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n", + temp); + xhci_writel(xhci, temp, &xhci->op_regs->command); + + /* + * Wait for the HCHalted Status bit to be 0 to indicate the host is + * running. + */ + ret = handshake(xhci, &xhci->op_regs->status, + STS_HALT, 0, XHCI_MAX_HALT_USEC); + if (ret == -ETIMEDOUT) + xhci_err(xhci, "Host took too long to start, " + "waited %u microseconds.\n", + XHCI_MAX_HALT_USEC); + return ret; +} + /* * Reset a halted HC, and set the internal HC state to HC_STATE_HALT. * @@ -460,13 +487,11 @@ int xhci_run(struct usb_hcd *hcd) if (NUM_TEST_NOOPS > 0) doorbell = xhci_setup_one_noop(xhci); - temp = xhci_readl(xhci, &xhci->op_regs->command); - temp |= (CMD_RUN); - xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n", - temp); - xhci_writel(xhci, temp, &xhci->op_regs->command); - /* Flush PCI posted writes */ - temp = xhci_readl(xhci, &xhci->op_regs->command); + if (xhci_start(xhci)) { + xhci_halt(xhci); + return -ENODEV; + } + xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp); if (doorbell) (*doorbell)(xhci); -- cgit v1.2.3 From 0238634d02dd10b678ebe9ea5d8803483277ee93 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Mon, 24 May 2010 13:25:28 -0700 Subject: USB: xhci: Print NEC firmware version. The NEC xHCI host controller firmware version can be found by putting a vendor-specific command on the command ring and extracting the BCD encoded-version out of the vendor-specific event TRB. The firmware version debug line in dmesg will look like: xhci_hcd 0000:05:00.0: NEC firmware version 30.21 (NEC merged with Renesas Technologies and became Renesas Electronics on April 1, 2010. I have their OK to merge this vendor-specific code.) Signed-off-by: Sarah Sharp Cc: Satoshi Otani Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 2 ++ drivers/usb/host/xhci-ring.c | 31 ++++++++++++++++++++++++++++++- drivers/usb/host/xhci.c | 5 +++++ drivers/usb/host/xhci.h | 12 ++++++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index edffd81fc253..11482b6b9381 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -78,6 +78,8 @@ static int xhci_pci_setup(struct usb_hcd *hcd) xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure" " endpoint cmd after reset endpoint\n"); } + if (pdev->vendor == PCI_VENDOR_ID_NEC) + xhci->quirks |= XHCI_NEC_HOST; /* Make sure the HC is halted. */ retval = xhci_halt(xhci); diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 36c858e5b529..9012098add6b 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1071,6 +1071,15 @@ bandwidth_change: xhci_warn(xhci, "Reset device command completion " "for disabled slot %u\n", slot_id); break; + case TRB_TYPE(TRB_NEC_GET_FW): + if (!(xhci->quirks & XHCI_NEC_HOST)) { + xhci->error_bitmask |= 1 << 6; + break; + } + xhci_dbg(xhci, "NEC firmware version %2x.%02x\n", + NEC_FW_MAJOR(event->status), + NEC_FW_MINOR(event->status)); + break; default: /* Skip over unknown commands on the event ring */ xhci->error_bitmask |= 1 << 6; @@ -1079,6 +1088,17 @@ bandwidth_change: inc_deq(xhci, xhci->cmd_ring, false); } +static void handle_vendor_event(struct xhci_hcd *xhci, + union xhci_trb *event) +{ + u32 trb_type; + + trb_type = TRB_FIELD_TO_TYPE(event->generic.field[3]); + xhci_dbg(xhci, "Vendor specific event TRB type = %u\n", trb_type); + if (trb_type == TRB_NEC_CMD_COMP && (xhci->quirks & XHCI_NEC_HOST)) + handle_cmd_completion(xhci, &event->event_cmd); +} + static void handle_port_status(struct xhci_hcd *xhci, union xhci_trb *event) { @@ -1659,7 +1679,10 @@ void xhci_handle_event(struct xhci_hcd *xhci) update_ptrs = 0; break; default: - xhci->error_bitmask |= 1 << 3; + if ((event->event_cmd.flags & TRB_TYPE_BITMASK) >= TRB_TYPE(48)) + handle_vendor_event(xhci, event); + else + xhci->error_bitmask |= 1 << 3; } /* Any of the above functions may drop and re-acquire the lock, so check * to make sure a watchdog timer didn't mark the host as non-responsive. @@ -2378,6 +2401,12 @@ int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, false); } +int xhci_queue_vendor_command(struct xhci_hcd *xhci, + u32 field1, u32 field2, u32 field3, u32 field4) +{ + return queue_command(xhci, field1, field2, field3, field4, false); +} + /* Queue a reset device command TRB */ int xhci_queue_reset_device(struct xhci_hcd *xhci, u32 slot_id) { diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 8a49c6716b69..27345cd04da0 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -486,6 +486,9 @@ int xhci_run(struct usb_hcd *hcd) if (NUM_TEST_NOOPS > 0) doorbell = xhci_setup_one_noop(xhci); + if (xhci->quirks & XHCI_NEC_HOST) + xhci_queue_vendor_command(xhci, 0, 0, 0, + TRB_TYPE(TRB_NEC_GET_FW)); if (xhci_start(xhci)) { xhci_halt(xhci); @@ -495,6 +498,8 @@ int xhci_run(struct usb_hcd *hcd) xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp); if (doorbell) (*doorbell)(xhci); + if (xhci->quirks & XHCI_NEC_HOST) + xhci_ring_cmd_db(xhci); xhci_dbg(xhci, "Finished xhci_run\n"); return 0; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index dada2fb59261..8b4b7d39f79c 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -925,6 +925,7 @@ union xhci_trb { /* TRB bit mask */ #define TRB_TYPE_BITMASK (0xfc00) #define TRB_TYPE(p) ((p) << 10) +#define TRB_FIELD_TO_TYPE(p) (((p) & TRB_TYPE_BITMASK) >> 10) /* TRB type IDs */ /* bulk, interrupt, isoc scatter/gather, and control data stage */ #define TRB_NORMAL 1 @@ -992,6 +993,14 @@ union xhci_trb { #define TRB_MFINDEX_WRAP 39 /* TRB IDs 40-47 reserved, 48-63 is vendor-defined */ +/* Nec vendor-specific command completion event. */ +#define TRB_NEC_CMD_COMP 48 +/* Get NEC firmware revision. */ +#define TRB_NEC_GET_FW 49 + +#define NEC_FW_MINOR(p) (((p) >> 0) & 0xff) +#define NEC_FW_MAJOR(p) (((p) >> 8) & 0xff) + /* * TRBS_PER_SEGMENT must be a multiple of 4, * since the command ring is 64-byte aligned. @@ -1172,6 +1181,7 @@ struct xhci_hcd { unsigned int quirks; #define XHCI_LINK_TRB_QUIRK (1 << 0) #define XHCI_RESET_EP_QUIRK (1 << 1) +#define XHCI_NEC_HOST (1 << 2) }; /* For testing purposes */ @@ -1379,6 +1389,8 @@ void xhci_set_hc_event_deq(struct xhci_hcd *xhci); int xhci_queue_slot_control(struct xhci_hcd *xhci, u32 trb_type, u32 slot_id); int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, u32 slot_id); +int xhci_queue_vendor_command(struct xhci_hcd *xhci, + u32 field1, u32 field2, u32 field3, u32 field4); int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id, unsigned int ep_index); int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, -- cgit v1.2.3 From 390b166138e95a47bdfde6582a1935f65e5c6547 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Mon, 24 May 2010 17:48:56 +0900 Subject: USB: s3c: Enable soft disconnect during initialization Enable soft disconnect bit the OTG core during initialization. Without this, the host sees that a gadget is connected and tries to enumerate. The soft disconnect should be enabled until the USB gadget driver is registered with this otg driver. Signed-off-by: Thomas Abraham Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/s3c-hsotg.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 1f73b485732d..a6d725dd7335 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -2730,6 +2730,9 @@ static void s3c_hsotg_init(struct s3c_hsotg *hsotg) writel(0, hsotg->regs + S3C_DAINTMSK); + /* Be in disconnected state until gadget is registered */ + __orr32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon); + if (0) { /* post global nak until we're ready */ writel(S3C_DCTL_SGNPInNAK | S3C_DCTL_SGOUTNak, -- cgit v1.2.3 From 0287e43dda1a425da662f879dd27352021b0ca63 Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Tue, 25 May 2010 05:36:49 +0100 Subject: USB: s3c_hsotg: define USB_GADGET_DUALSPEED in Kconfig The s3c_hsotg driver sets usb_gadget->is_dualspeed to 1, yet it doesn't define USB_GADGET_DUALSPEED in Kconfig. This triggers a NULL pointer dereference in the composite driver (which is fixed in another patch). Signed-off-by: Maurus Cuelenaere Signed-off-by: Ben Dooks Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 649c0c5f7158..591ae9fde199 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -295,6 +295,7 @@ config USB_GADGET_S3C_HSOTG boolean "S3C HS/OtG USB Device controller" depends on S3C_DEV_USB_HSOTG select USB_GADGET_S3C_HSOTG_PIO + select USB_GADGET_DUALSPEED help The Samsung S3C64XX USB2.0 high-speed gadget controller integrated into the S3C64XX series SoC. -- cgit v1.2.3 From 0f002d200598918f5058dfcfda3da46f29019765 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 25 May 2010 05:36:50 +0100 Subject: USB: s3c-hsotg: Ensure TX FIFO addresses setup when initialising FIFOs Some versions of the S3C HS OtG block startup with overlapping TX FIFO information, so change the fifo_init code to ensure that known values are set into the FIFO registers at initialisation/reset time. This also ensures that the FIFO RAM pointers are in a known state before use. Signed-off-by: Ben Dooks Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/s3c-hsotg.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index a6d725dd7335..9abf96c5715d 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -297,6 +297,11 @@ static void s3c_hsotg_ctrl_epint(struct s3c_hsotg *hsotg, */ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg) { + unsigned int ep; + unsigned int addr; + unsigned int size; + u32 val; + /* the ryu 2.6.24 release ahs writel(0x1C0, hsotg->regs + S3C_GRXFSIZ); writel(S3C_GNPTXFSIZ_NPTxFStAddr(0x200) | @@ -310,6 +315,26 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg) writel(S3C_GNPTXFSIZ_NPTxFStAddr(2048) | S3C_GNPTXFSIZ_NPTxFDep(0x1C0), hsotg->regs + S3C_GNPTXFSIZ); + + /* arange all the rest of the TX FIFOs, as some versions of this + * block have overlapping default addresses. This also ensures + * that if the settings have been changed, then they are set to + * known values. */ + + /* start at the end of the GNPTXFSIZ, rounded up */ + addr = 2048 + 1024; + size = 768; + + /* currently we allocate TX FIFOs for all possible endpoints, + * and assume that they are all the same size. */ + + for (ep = 0; ep <= 15; ep++) { + val = addr; + val |= size << S3C_DPTXFSIZn_DPTxFSize_SHIFT; + addr += size; + + writel(val, hsotg->regs + S3C_DPTXFSIZn(ep)); + } } /** -- cgit v1.2.3 From 2e0e0777ec2ea1cb5461bded2c09573a9d778622 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 25 May 2010 05:36:51 +0100 Subject: USB: s3c-hsotg: SoftDisconnect minimum 3ms The shortest period SoftDisconnect can be asserted for is 3 milliseconds according to the V210 datasheet, so ensure that we add an msleep() to the registration code to enforce this. Signed-off-by: Ben Dooks Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/s3c-hsotg.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 9abf96c5715d..31d19e1f261d 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -2599,6 +2599,9 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) writel(S3C_DCTL_CGOUTNak | S3C_DCTL_CGNPInNAK, hsotg->regs + S3C_DCTL); + /* must be at-least 3ms to allow bus to see disconnect */ + msleep(3); + /* remove the soft-disconnect and let's go */ __bic32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon); -- cgit v1.2.3 From 1703a6d3c38944731ba23594843a704d828266f3 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 25 May 2010 05:36:52 +0100 Subject: USB: s3c-hsotg: Ensure FIFOs are fully flushed after layout According to the design guide, if the FIFO layout is changed, then the FIFOs must be flushed to ensure all FIFO pointers are correct. Signed-off-by: Ben Dooks Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/s3c-hsotg.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 31d19e1f261d..26193eceb323 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -300,6 +300,7 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg) unsigned int ep; unsigned int addr; unsigned int size; + int timeout; u32 val; /* the ryu 2.6.24 release ahs @@ -335,6 +336,31 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg) writel(val, hsotg->regs + S3C_DPTXFSIZn(ep)); } + + /* according to p428 of the design guide, we need to ensure that + * all fifos are flushed before continuing */ + + writel(S3C_GRSTCTL_TxFNum(0x10) | S3C_GRSTCTL_TxFFlsh | + S3C_GRSTCTL_RxFFlsh, hsotg->regs + S3C_GRSTCTL); + + /* wait until the fifos are both flushed */ + timeout = 100; + while (1) { + val = readl(hsotg->regs + S3C_GRSTCTL); + + if ((val & (S3C_GRSTCTL_TxFFlsh | S3C_GRSTCTL_RxFFlsh)) == 0) + break; + + if (--timeout == 0) { + dev_err(hsotg->dev, + "%s: timeout flushing fifos (GRSTCTL=%08x)\n", + __func__, val); + } + + udelay(1); + } + + dev_dbg(hsotg->dev, "FIFOs reset, timeout at %d\n", timeout); } /** -- cgit v1.2.3 From 6a1a82df91fa0eb1cc76069a9efe5714d087eccd Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 3 Jun 2010 13:55:02 +0200 Subject: USB: ftdi_sio: fix DTR/RTS line modes Call set_mctrl() and clear_mctrl() according to the flow control mode selected. This makes serial communication for FT232 connected devices work when CRTSCTS is not set. This fixes a regression introduced by 4175f3e31 ("tty_port: If we are opened non blocking we still need to raise the carrier"). This patch calls the low-level driver's dtr_rts() function which consequently sets TIOCM_DTR | TIOCM_RTS. A later call to set_termios() without CRTSCTS in cflags, however, does not reset these bits, and so data is not actually sent out on the serial wire. Signed-off-by: Daniel Mack Cc: Johan Hovold Cc: Alan Cox Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 050211afc07e..79dd1ae195e5 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -2005,6 +2005,8 @@ static void ftdi_set_termios(struct tty_struct *tty, "urb failed to set to rts/cts flow control\n"); } + /* raise DTR/RTS */ + set_mctrl(port, TIOCM_DTR | TIOCM_RTS); } else { /* * Xon/Xoff code @@ -2052,6 +2054,8 @@ static void ftdi_set_termios(struct tty_struct *tty, } } + /* lower DTR/RTS */ + clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); } return; } -- cgit v1.2.3 From c2572b78aa0447244a38e555ebb1b3b48a0088a5 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 31 May 2010 08:04:47 +0800 Subject: USB: cdc-acm: fix resource reclaim in error path of acm_probe This patch fixes resource reclaim in error path of acm_probe: 1. In the case of "out of memory (read urbs usb_alloc_urb)\n")", there is no need to call acm_read_buffers_free(acm) here. Fix it by goto alloc_fail6 instead of alloc_fail7. 2. In the case of "out of memory (write urbs usb_alloc_urb)", usb_alloc_urb may fail in any iteration of the for loop. Current implementation does not properly free allocated snd->urb. Fix it by goto alloc_fail8 instead of alloc_fail7. 3. In the case of device_create_file(&intf->dev,&dev_attr_iCountryCodeRelDate) fail, acm->country_codes is kfreed. As a result, device_remove_file for dev_attr_wCountryCodes will not be executed in acm_disconnect. Fix it by calling device_remove_file for dev_attr_wCountryCodes before goto skip_countries. Signed-off-by: Axel Lin Acked-by: Oliver Neukum Cc: stable Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 0c2f14ff9696..61d75507d5d0 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1201,7 +1201,7 @@ made_compressed_probe: if (rcv->urb == NULL) { dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n"); - goto alloc_fail7; + goto alloc_fail6; } rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; @@ -1225,7 +1225,7 @@ made_compressed_probe: if (snd->urb == NULL) { dev_dbg(&intf->dev, "out of memory (write urbs usb_alloc_urb)"); - goto alloc_fail7; + goto alloc_fail8; } if (usb_endpoint_xfer_int(epwrite)) @@ -1264,6 +1264,7 @@ made_compressed_probe: i = device_create_file(&intf->dev, &dev_attr_iCountryCodeRelDate); if (i < 0) { + device_remove_file(&intf->dev, &dev_attr_wCountryCodes); kfree(acm->country_codes); goto skip_countries; } @@ -1300,6 +1301,7 @@ alloc_fail8: usb_free_urb(acm->wb[i].urb); alloc_fail7: acm_read_buffers_free(acm); +alloc_fail6: for (i = 0; i < num_rx_buf; i++) usb_free_urb(acm->ru[i].urb); usb_free_urb(acm->ctrlurb); -- cgit v1.2.3 From 1f23b2d98c11fed43c552a5dbd00c793f81a8736 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 2 Jun 2010 13:53:17 -0600 Subject: usb: fix ehci_hcd build failure when both generic-OF and xilinx is selected This patch fixes the driver to allow both CONFIG_USB_EHCI_HCD_PPC_OF and CONFIG_USB_ECHI_HCD_XILINX to be selected. Signed-off-by: Grant Likely CC: John Linn CC: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index ef3e88f0b3c3..a3ef2a9d9dc2 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1135,7 +1135,7 @@ MODULE_LICENSE ("GPL"); #ifdef CONFIG_XPS_USB_HCD_XILINX #include "ehci-xilinx-of.c" -#define OF_PLATFORM_DRIVER ehci_hcd_xilinx_of_driver +#define XILINX_OF_PLATFORM_DRIVER ehci_hcd_xilinx_of_driver #endif #ifdef CONFIG_PLAT_ORION @@ -1159,7 +1159,8 @@ MODULE_LICENSE ("GPL"); #endif #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ - !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) + !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ + !defined(XILINX_OF_PLATFORM_DRIVER) #error "missing bus glue for ehci-hcd" #endif @@ -1213,10 +1214,20 @@ static int __init ehci_hcd_init(void) if (retval < 0) goto clean3; #endif + +#ifdef XILINX_OF_PLATFORM_DRIVER + retval = of_register_platform_driver(&XILINX_OF_PLATFORM_DRIVER); + if (retval < 0) + goto clean4; +#endif return retval; +#ifdef XILINX_OF_PLATFORM_DRIVER + /* of_unregister_platform_driver(&XILINX_OF_PLATFORM_DRIVER); */ +clean4: +#endif #ifdef OF_PLATFORM_DRIVER - /* of_unregister_platform_driver(&OF_PLATFORM_DRIVER); */ + of_unregister_platform_driver(&OF_PLATFORM_DRIVER); clean3: #endif #ifdef PS3_SYSTEM_BUS_DRIVER @@ -1243,6 +1254,9 @@ module_init(ehci_hcd_init); static void __exit ehci_hcd_cleanup(void) { +#ifdef XILINX_OF_PLATFORM_DRIVER + of_unregister_platform_driver(&XILINX_OF_PLATFORM_DRIVER); +#endif #ifdef OF_PLATFORM_DRIVER of_unregister_platform_driver(&OF_PLATFORM_DRIVER); #endif -- cgit v1.2.3 From 109f34e71b9049a57f6cdf3f1da6bee2b722b259 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 27 May 2010 14:32:09 +0200 Subject: USB: serial: digi_acceleport: Eliminate a NULL pointer dereference If port is NULL, then the call to dev_err will dereference a value that is a small offset from NULL. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r exists@ expression E,E1; identifier f; statement S1,S2,S3; @@ if ((E == NULL && ...) || ...) { ... when != if (...) S1 else S2 when != E = E1 * E->f ... when any return ...; } else S3 // Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/digi_acceleport.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 3edda3ed822a..fd35f73b5721 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -1239,8 +1239,7 @@ static void digi_write_bulk_callback(struct urb *urb) /* port and serial sanity check */ if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) { - dev_err(&port->dev, - "%s: port or port->private is NULL, status=%d\n", + pr_err("%s: port or port->private is NULL, status=%d\n", __func__, status); return; } -- cgit v1.2.3 From c043f1245654a726925529007210e9f786426448 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 4 Jun 2010 14:02:42 -0400 Subject: USB: unbind all interfaces before rebinding them MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch (as1387) fixes a bug introduced during the changeover to the runtime PM framework. When a driver doesn't support resume or reset-resume, and consequently its interfaces need to be unbound and rebound, we have to unbind all the interfaces before trying to rebind any of them. Otherwise the driver's probe method for one interface could try to claim a different interface and fail, because that other interface hasn't been unbound yet. This fixes Bugzilla #15788. The symptom is that some USB sound cards don't work after hibernation. Signed-off-by: Alan Stern Tested-by: François Valenduc Cc: stable [.34] Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index ded550eda5d9..de98a94d1853 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1328,6 +1328,7 @@ int usb_resume(struct device *dev, pm_message_t msg) /* For all other calls, take the device back to full power and * tell the PM core in case it was autosuspended previously. + * Unbind the interfaces that will need rebinding later. */ } else { status = usb_resume_both(udev, msg); @@ -1336,6 +1337,7 @@ int usb_resume(struct device *dev, pm_message_t msg) pm_runtime_set_active(dev); pm_runtime_enable(dev); udev->last_busy = jiffies; + do_unbind_rebind(udev, DO_REBIND); } } -- cgit v1.2.3 From 18c79d76ece432a48c985ea404800f8ee154ada2 Mon Sep 17 00:00:00 2001 From: Abhijeet Dharmapurikar Date: Thu, 20 May 2010 15:20:23 -0700 Subject: msm_serial: fix serial on trout Set the mnd counter based on uartclk. This fixes a problem on 7x30 where the uartclk is 19.2Mhz rather than the usual 4.8Mhz. Trout incorrectly reports uartclk to be running at 19.2Mhz It is actually running at 4.8Mhz. For trout force mnd counter values as if uartclk was fed by tcxo/4. Signed-off-by: Abhijeet Dharmapurikar [dwalker@codeaurora.org: inlined, moved into header, added comments.] Signed-off-by: Daniel Walker Signed-off-by: Greg Kroah-Hartman --- drivers/serial/msm_serial.c | 21 +++-------------- drivers/serial/msm_serial.h | 56 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/msm_serial.c b/drivers/serial/msm_serial.c index ecdc0facf7ee..f8c816e7725d 100644 --- a/drivers/serial/msm_serial.c +++ b/drivers/serial/msm_serial.c @@ -41,19 +41,6 @@ struct msm_port { unsigned int imr; }; -#define UART_TO_MSM(uart_port) ((struct msm_port *) uart_port) - -static inline void msm_write(struct uart_port *port, unsigned int val, - unsigned int off) -{ - __raw_writel(val, port->membase + off); -} - -static inline unsigned int msm_read(struct uart_port *port, unsigned int off) -{ - return __raw_readl(port->membase + off); -} - static void msm_stop_tx(struct uart_port *port) { struct msm_port *msm_port = UART_TO_MSM(port); @@ -320,11 +307,7 @@ static void msm_init_clock(struct uart_port *port) struct msm_port *msm_port = UART_TO_MSM(port); clk_enable(msm_port->clk); - - msm_write(port, 0xC0, UART_MREG); - msm_write(port, 0xB2, UART_NREG); - msm_write(port, 0x7D, UART_DREG); - msm_write(port, 0x1C, UART_MNDREG); + msm_serial_set_mnd_regs(port); } static int msm_startup(struct uart_port *port) @@ -706,6 +689,8 @@ static int __init msm_serial_probe(struct platform_device *pdev) if (unlikely(IS_ERR(msm_port->clk))) return PTR_ERR(msm_port->clk); port->uartclk = clk_get_rate(msm_port->clk); + printk(KERN_INFO "uartclk = %d\n", port->uartclk); + resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (unlikely(!resource)) diff --git a/drivers/serial/msm_serial.h b/drivers/serial/msm_serial.h index 689f1fa0e84e..f6ca9ca79e98 100644 --- a/drivers/serial/msm_serial.h +++ b/drivers/serial/msm_serial.h @@ -114,4 +114,60 @@ #define UART_MISR 0x0010 #define UART_ISR 0x0014 +#define UART_TO_MSM(uart_port) ((struct msm_port *) uart_port) + +static inline +void msm_write(struct uart_port *port, unsigned int val, unsigned int off) +{ + __raw_writel(val, port->membase + off); +} + +static inline +unsigned int msm_read(struct uart_port *port, unsigned int off) +{ + return __raw_readl(port->membase + off); +} + +/* + * Setup the MND registers to use the TCXO clock. + */ +static inline void msm_serial_set_mnd_regs_tcxo(struct uart_port *port) +{ + msm_write(port, 0x06, UART_MREG); + msm_write(port, 0xF1, UART_NREG); + msm_write(port, 0x0F, UART_DREG); + msm_write(port, 0x1A, UART_MNDREG); +} + +/* + * Setup the MND registers to use the TCXO clock divided by 4. + */ +static inline void msm_serial_set_mnd_regs_tcxoby4(struct uart_port *port) +{ + msm_write(port, 0x18, UART_MREG); + msm_write(port, 0xF6, UART_NREG); + msm_write(port, 0x0F, UART_DREG); + msm_write(port, 0x0A, UART_MNDREG); +} + +static inline +void msm_serial_set_mnd_regs_from_uartclk(struct uart_port *port) +{ + if (port->uartclk == 19200000) + msm_serial_set_mnd_regs_tcxo(port); + else + msm_serial_set_mnd_regs_tcxoby4(port); +} + +/* + * TROUT has a specific defect that makes it report it's uartclk + * as 19.2Mhz (TCXO) when it's actually 4.8Mhz (TCXO/4). This special + * cases TROUT to use the right clock. + */ +#ifdef CONFIG_MACH_TROUT +#define msm_serial_set_mnd_regs msm_serial_set_mnd_regs_tcxoby4 +#else +#define msm_serial_set_mnd_regs msm_serial_set_mnd_regs_from_uartclk +#endif + #endif /* __DRIVERS_SERIAL_MSM_SERIAL_H */ -- cgit v1.2.3 From 99ec88f345945208c650b54279dddc8dfd705571 Mon Sep 17 00:00:00 2001 From: Alexander Kurz Date: Thu, 20 May 2010 00:40:08 +0400 Subject: serial_cs: add and sort IDs for serial and modem cards Signed-off-by: Alexander Kurz Signed-off-by: Greg Kroah-Hartman --- drivers/serial/serial_cs.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index dadd686c9801..526307368f8b 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -715,6 +715,8 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021), PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a), PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0104, 0x000a), + PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0d0a), + PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0e0a), PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0xea15), PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0109, 0x0501), PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0138, 0x110a), @@ -724,8 +726,6 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x016c, 0x0081), PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x021b, 0x0101), PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x08a1, 0xc0ab), - PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0d0a), - PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0e0a), PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3288", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x04cd2988, 0x46a52d63), PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3336", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x0143b773, 0x46a52d63), PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "EM1144T", "PCMCIA MODEM", 0xf510db04, 0x856d66c8, 0xbd6c43ef), @@ -768,17 +768,26 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x0276), PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039), PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006), + PCMCIA_DEVICE_MANF_CARD(0x0105, 0x0101), /* TDK DF2814 */ + PCMCIA_DEVICE_MANF_CARD(0x0105, 0x100a), /* Xircom CM-56G */ + PCMCIA_DEVICE_MANF_CARD(0x0105, 0x3e0a), /* TDK DF5660 */ PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a), + PCMCIA_DEVICE_MANF_CARD(0x0107, 0x0002), /* USRobotics 14,400 */ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d50), PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d51), PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d52), PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d53), PCMCIA_DEVICE_MANF_CARD(0x010b, 0xd180), + PCMCIA_DEVICE_MANF_CARD(0x0115, 0x3330), /* USRobotics/SUN 14,400 */ + PCMCIA_DEVICE_MANF_CARD(0x0124, 0x0100), /* Nokia DTP-2 ver II */ + PCMCIA_DEVICE_MANF_CARD(0x0134, 0x5600), /* LASAT COMMUNICATIONS A/S */ PCMCIA_DEVICE_MANF_CARD(0x0137, 0x000e), PCMCIA_DEVICE_MANF_CARD(0x0137, 0x001b), PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0025), PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0045), PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0052), + PCMCIA_DEVICE_MANF_CARD(0x016c, 0x0006), /* Psion 56K+Fax */ + PCMCIA_DEVICE_MANF_CARD(0x0200, 0x0001), /* MultiMobile */ PCMCIA_DEVICE_PROD_ID134("ADV", "TECH", "COMpad-32/85", 0x67459937, 0x916d02ba, 0x8fbe92ae), PCMCIA_DEVICE_PROD_ID124("GATEWAY2000", "CC3144", "PCMCIA MODEM", 0x506bccae, 0xcb3685f1, 0xbd6c43ef), PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef), @@ -792,16 +801,21 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 33600 FAX/DATA MODEM", 0xa3a3062c, 0x5a00ce95), PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc.", "PCM-COM422", 0xd0b78f51, 0x7e2d49ed), PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus", "FURY CARD 14K4", 0x76942813, 0x8b96ce65), + PCMCIA_DEVICE_PROD_ID12("IBM", "ISDN/56K/GSM", 0xb569a6e5, 0xfee5297b), PCMCIA_DEVICE_PROD_ID12("Intelligent", "ANGIA FAX/MODEM", 0xb496e65e, 0xf31602a6), PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400+", 0x816cc815, 0x412729fb), + PCMCIA_DEVICE_PROD_ID12("Intertex", "IX34-PCMCIA", 0xf8a097e3, 0x97880447), PCMCIA_DEVICE_PROD_ID12("IOTech Inc ", "PCMCIA Dual RS-232 Serial Port Card", 0x3bd2d898, 0x92abc92f), PCMCIA_DEVICE_PROD_ID12("MACRONIX", "FAX/MODEM", 0x668388b3, 0x3f9bdf2f), PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT1432LT", 0x5f73be51, 0x0b3e2383), PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT2834LT", 0x5f73be51, 0x4cd7c09e), PCMCIA_DEVICE_PROD_ID12("OEM ", "C288MX ", 0xb572d360, 0xd2385b7a), + PCMCIA_DEVICE_PROD_ID12("Option International", "V34bis GSM/PSTN Data/Fax Modem", 0x9d7cd6f5, 0x5cb8bf41), PCMCIA_DEVICE_PROD_ID12("PCMCIA ", "C336MX ", 0x99bcafe9, 0xaa25bcab), PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f), PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "Dual RS-232 Serial Port PC Card", 0xc4420b35, 0x031a380d), + PCMCIA_DEVICE_PROD_ID12("Telia", "SurfinBird 560P/A+", 0xe2cdd5e, 0xc9314b38), + PCMCIA_DEVICE_PROD_ID1("Smart Serial Port", 0x2d8ce292), PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "cis/PCMLM28.cis"), PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "cis/PCMLM28.cis"), PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"), -- cgit v1.2.3 From ca3e442e8dbbe2551473f36f0e7797b1d3205f5a Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Sun, 23 May 2010 04:40:13 -0400 Subject: serial: bfin_5xx: IRDA is not affected by anomaly 05000230 Anomaly 05000230 (over sampling of the UART STOP bit) applies only when the peripheral is operating in UART mode. So drop the anomaly handling when the UART is in IRDA mode. Signed-off-by: Graf Yang Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/serial/bfin_5xx.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 96f7e7484fee..a78652b21e40 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -869,7 +869,12 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, } baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); - quot = uart_get_divisor(port, baud) - ANOMALY_05000230; + quot = uart_get_divisor(port, baud); + + /* If discipline is not IRDA, apply ANOMALY_05000230 */ + if (termios->c_line != N_IRDA) + quot -= ANOMALY_05000230; + spin_lock_irqsave(&uart->port.lock, flags); UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15); -- cgit v1.2.3 From e59e2bd9e85604ad601ec7dd056baffcd6ad56a0 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Sun, 23 May 2010 04:40:14 -0400 Subject: serial: bfin_5xx: fix typo in IER check This most likely won't cause problems on systems as people don't typically enable GPIO RTS/CTS if they don't actually use it. Signed-off-by: Sonic Zhang Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/serial/bfin_5xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index a78652b21e40..511cbf687877 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -797,7 +797,7 @@ static void bfin_serial_shutdown(struct uart_port *port) gpio_free(uart->rts_pin); #endif #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS - if (UART_GET_IER(uart) && EDSSI) + if (UART_GET_IER(uart) & EDSSI) free_irq(uart->status_irq, uart); #endif } -- cgit v1.2.3 From 328be395a396b1333b56e04571365dc614c96e46 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 25 May 2010 11:37:17 +0200 Subject: TTY/n_gsm: potential double lock In gsm_dlci_data_kick() we call gsm_dlci_data_sweep() with the "gsm->tx_lock" held so we can't lock it again inside gsm_dlci_data_sweep(). I removed that lock from and added one to gsmld_write_wakeup() instead. The sweep function is only called from those two places. Signed-off-by: Dan Carpenter Acked-by: Alan Cox Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/char/n_gsm.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/char/n_gsm.c b/drivers/char/n_gsm.c index c4161d5e053d..e4089c432f15 100644 --- a/drivers/char/n_gsm.c +++ b/drivers/char/n_gsm.c @@ -904,9 +904,7 @@ static void gsm_dlci_data_sweep(struct gsm_mux *gsm) int len; /* Priority ordering: We should do priority with RR of the groups */ int i = 1; - unsigned long flags; - spin_lock_irqsave(&gsm->tx_lock, flags); while (i < NUM_DLCI) { struct gsm_dlci *dlci; @@ -927,7 +925,6 @@ static void gsm_dlci_data_sweep(struct gsm_mux *gsm) if (len == 0) i++; } - spin_unlock_irqrestore(&gsm->tx_lock, flags); } /** @@ -2230,12 +2227,16 @@ static int gsmld_open(struct tty_struct *tty) static void gsmld_write_wakeup(struct tty_struct *tty) { struct gsm_mux *gsm = tty->disc_data; + unsigned long flags; /* Queue poll */ clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); gsm_data_kick(gsm); - if (gsm->tx_bytes < TX_THRESH_LO) + if (gsm->tx_bytes < TX_THRESH_LO) { + spin_lock_irqsave(&gsm->tx_lock, flags); gsm_dlci_data_sweep(gsm); + spin_unlock_irqrestore(&gsm->tx_lock, flags); + } } /** -- cgit v1.2.3 From d8d721f4c005f9a69bd1b5d5c6ba99b7e1d464de Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Tue, 25 May 2010 16:59:55 +0200 Subject: altera_uart: Don't take spinlock in already protected functions Don't take the port spinlock in uart functions where the serial core already takes care of locking/unlocking them. The code would actually lock up on architectures where spinlocks are implemented (not the case on nios2 where this driver is primarily used for now, thus this bug didn't trigger). Also protect calling altera_uart_rx_chars/altera_uart_tx_chars in the interrupt handler by the port spinlock. Thanks to Ian Abbott for pointing these issues out. Cc: Ian Abbott Cc: Thomas Chou Signed-off-by: Tobias Klauser Signed-off-by: Greg Kroah-Hartman --- drivers/serial/altera_uart.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/altera_uart.c b/drivers/serial/altera_uart.c index bcee156d2f2e..b1609cca0ec4 100644 --- a/drivers/serial/altera_uart.c +++ b/drivers/serial/altera_uart.c @@ -89,15 +89,12 @@ static unsigned int altera_uart_tx_empty(struct uart_port *port) static unsigned int altera_uart_get_mctrl(struct uart_port *port) { struct altera_uart *pp = container_of(port, struct altera_uart, port); - unsigned long flags; unsigned int sigs; - spin_lock_irqsave(&port->lock, flags); sigs = (readl(port->membase + ALTERA_UART_STATUS_REG) & ALTERA_UART_STATUS_CTS_MSK) ? TIOCM_CTS : 0; sigs |= (pp->sigs & TIOCM_RTS); - spin_unlock_irqrestore(&port->lock, flags); return sigs; } @@ -105,49 +102,37 @@ static unsigned int altera_uart_get_mctrl(struct uart_port *port) static void altera_uart_set_mctrl(struct uart_port *port, unsigned int sigs) { struct altera_uart *pp = container_of(port, struct altera_uart, port); - unsigned long flags; - spin_lock_irqsave(&port->lock, flags); pp->sigs = sigs; if (sigs & TIOCM_RTS) pp->imr |= ALTERA_UART_CONTROL_RTS_MSK; else pp->imr &= ~ALTERA_UART_CONTROL_RTS_MSK; writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); - spin_unlock_irqrestore(&port->lock, flags); } static void altera_uart_start_tx(struct uart_port *port) { struct altera_uart *pp = container_of(port, struct altera_uart, port); - unsigned long flags; - spin_lock_irqsave(&port->lock, flags); pp->imr |= ALTERA_UART_CONTROL_TRDY_MSK; writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); - spin_unlock_irqrestore(&port->lock, flags); } static void altera_uart_stop_tx(struct uart_port *port) { struct altera_uart *pp = container_of(port, struct altera_uart, port); - unsigned long flags; - spin_lock_irqsave(&port->lock, flags); pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK; writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); - spin_unlock_irqrestore(&port->lock, flags); } static void altera_uart_stop_rx(struct uart_port *port) { struct altera_uart *pp = container_of(port, struct altera_uart, port); - unsigned long flags; - spin_lock_irqsave(&port->lock, flags); pp->imr &= ~ALTERA_UART_CONTROL_RRDY_MSK; writel(pp->imr, port->membase + ALTERA_UART_CONTROL_REG); - spin_unlock_irqrestore(&port->lock, flags); } static void altera_uart_break_ctl(struct uart_port *port, int break_state) @@ -272,10 +257,14 @@ static irqreturn_t altera_uart_interrupt(int irq, void *data) unsigned int isr; isr = readl(port->membase + ALTERA_UART_STATUS_REG) & pp->imr; + + spin_lock(&port->lock); if (isr & ALTERA_UART_STATUS_RRDY_MSK) altera_uart_rx_chars(pp); if (isr & ALTERA_UART_STATUS_TRDY_MSK) altera_uart_tx_chars(pp); + spin_unlock(&port->lock); + return IRQ_RETVAL(isr); } -- cgit v1.2.3 From fadf34f0f05ca5ea02ffcd89544cd372bbdb739b Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Tue, 25 May 2010 17:00:08 +0200 Subject: altera_uart: Simplify altera_uart_console_putc The check for the TRDY flag after writing the character is not needed. Also do a cpu_relax() inside the loop. Pass a struct uart_port to altera_uart_console_putc, so we do not need to get it (and dereference pointers) for every character. Cc: Thomas Chou Signed-off-by: Tobias Klauser Signed-off-by: Greg Kroah-Hartman --- drivers/serial/altera_uart.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/altera_uart.c b/drivers/serial/altera_uart.c index b1609cca0ec4..7d6afc9755d5 100644 --- a/drivers/serial/altera_uart.c +++ b/drivers/serial/altera_uart.c @@ -391,31 +391,24 @@ int __init early_altera_uart_setup(struct altera_uart_platform_uart *platp) return 0; } -static void altera_uart_console_putc(struct console *co, const char c) +static void altera_uart_console_putc(struct uart_port *port, const char c) { - struct uart_port *port = &(altera_uart_ports + co->index)->port; - int i; + while (!(readl(port->membase + ALTERA_UART_STATUS_REG) & + ALTERA_UART_STATUS_TRDY_MSK)) + cpu_relax(); - for (i = 0; i < 0x10000; i++) { - if (readl(port->membase + ALTERA_UART_STATUS_REG) & - ALTERA_UART_STATUS_TRDY_MSK) - break; - } writel(c, port->membase + ALTERA_UART_TXDATA_REG); - for (i = 0; i < 0x10000; i++) { - if (readl(port->membase + ALTERA_UART_STATUS_REG) & - ALTERA_UART_STATUS_TRDY_MSK) - break; - } } static void altera_uart_console_write(struct console *co, const char *s, unsigned int count) { + struct uart_port *port = &(altera_uart_ports + co->index)->port; + for (; count; count--, s++) { - altera_uart_console_putc(co, *s); + altera_uart_console_putc(port, *s); if (*s == '\n') - altera_uart_console_putc(co, '\r'); + altera_uart_console_putc(port, '\r'); } } -- cgit v1.2.3 From 962400e8fd29981a7b166e463dd143b6ac6a3e76 Mon Sep 17 00:00:00 2001 From: Frank Pan Date: Wed, 26 May 2010 15:37:43 +0800 Subject: tty: fix a little bug in scrup, vt.c The code uses vc->vc_cols instead of vc->vc_size_row by mistake, it will cause half of the region which is going to clear remain uncleared. The issue happens in background consoles, so it's hard to observe. Frank Pan Signed-off-by: Frank Pan Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/char/vt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 7cdb6ee569cd..1296c42ed5c6 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -304,7 +304,7 @@ static void scrup(struct vc_data *vc, unsigned int t, unsigned int b, int nr) d = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t); s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * (t + nr)); scr_memmovew(d, s, (b - t - nr) * vc->vc_size_row); - scr_memsetw(d + (b - t - nr) * vc->vc_cols, vc->vc_video_erase_char, + scr_memsetw(d + (b - t - nr) * vc->vc_size_row, vc->vc_video_erase_char, vc->vc_size_row * nr); } -- cgit v1.2.3 From c1bfffa94e0ca951ed450788991c9310adb8e823 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 31 May 2010 15:01:08 +0200 Subject: serial: altera_uart: Proper section for altera_uart_remove altera_uart_remove should be in .devexit.text Signed-off-by: Tobias Klauser Signed-off-by: Greg Kroah-Hartman --- drivers/serial/altera_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/serial/altera_uart.c b/drivers/serial/altera_uart.c index 7d6afc9755d5..0f1189605d21 100644 --- a/drivers/serial/altera_uart.c +++ b/drivers/serial/altera_uart.c @@ -498,7 +498,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) return 0; } -static int altera_uart_remove(struct platform_device *pdev) +static int __devexit altera_uart_remove(struct platform_device *pdev) { struct uart_port *port; int i; -- cgit v1.2.3 From 3fde85df5421eb01f563fef6f111ba73ab0d120e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 4 Jun 2010 12:20:46 +0200 Subject: vt_ioctl: return -EFAULT on copy_from_user errors copy_from_user() returns the number of bytes remaining but we want to return a negative error code here. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/char/vt_ioctl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 6aa10284104a..cb19dbc52136 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c @@ -1303,7 +1303,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, if (!perm) goto eperm; ret = copy_from_user(&ui, up, sizeof(struct unimapinit)); - if (!ret) + if (ret) + ret = -EFAULT; + else con_clear_unimap(vc, &ui); break; } -- cgit v1.2.3 From 66169ad17d9c67a33608830dd83dcef55c85a756 Mon Sep 17 00:00:00 2001 From: Yegor Yefremov Date: Fri, 4 Jun 2010 09:58:18 +0200 Subject: serial: add support for various Titan PCI cards serial: add support for various Titan PCI cards Models: 200I, 400I, 800I, 400EH, 800EH, 800EHB, 100E, 200E, 400E, 800E, 200EI, 200EISI Signed-off-by: Yegor Yefremov Signed-off-by: Greg Kroah-Hartman --- drivers/serial/8250_pci.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'drivers') diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 01c012da4e26..746a44621d91 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c @@ -982,6 +982,18 @@ static int skip_tx_en_setup(struct serial_private *priv, #define PCI_SUBDEVICE_ID_POCTAL422 0x0408 #define PCI_VENDOR_ID_ADVANTECH 0x13fe #define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620 +#define PCI_DEVICE_ID_TITAN_200I 0x8028 +#define PCI_DEVICE_ID_TITAN_400I 0x8048 +#define PCI_DEVICE_ID_TITAN_800I 0x8088 +#define PCI_DEVICE_ID_TITAN_800EH 0xA007 +#define PCI_DEVICE_ID_TITAN_800EHB 0xA008 +#define PCI_DEVICE_ID_TITAN_400EH 0xA009 +#define PCI_DEVICE_ID_TITAN_100E 0xA010 +#define PCI_DEVICE_ID_TITAN_200E 0xA012 +#define PCI_DEVICE_ID_TITAN_400E 0xA013 +#define PCI_DEVICE_ID_TITAN_800E 0xA014 +#define PCI_DEVICE_ID_TITAN_200EI 0xA016 +#define PCI_DEVICE_ID_TITAN_200EISI 0xA017 /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 @@ -1541,6 +1553,10 @@ enum pci_board_num_t { pbn_b3_4_115200, pbn_b3_8_115200, + pbn_b4_bt_2_921600, + pbn_b4_bt_4_921600, + pbn_b4_bt_8_921600, + /* * Board-specific versions. */ @@ -1995,6 +2011,25 @@ static struct pciserial_board pci_boards[] __devinitdata = { .uart_offset = 8, }, + [pbn_b4_bt_2_921600] = { + .flags = FL_BASE4, + .num_ports = 2, + .base_baud = 921600, + .uart_offset = 8, + }, + [pbn_b4_bt_4_921600] = { + .flags = FL_BASE4, + .num_ports = 4, + .base_baud = 921600, + .uart_offset = 8, + }, + [pbn_b4_bt_8_921600] = { + .flags = FL_BASE4, + .num_ports = 8, + .base_baud = 921600, + .uart_offset = 8, + }, + /* * Entries following this are board-specific. */ @@ -3043,6 +3078,42 @@ static struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800L, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b0_bt_8_921600 }, + { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200I, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b4_bt_2_921600 }, + { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400I, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b4_bt_4_921600 }, + { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800I, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b4_bt_8_921600 }, + { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400EH, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b0_4_921600 }, + { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800EH, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b0_4_921600 }, + { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800EHB, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b0_4_921600 }, + { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100E, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_oxsemi_1_4000000 }, + { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200E, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_oxsemi_2_4000000 }, + { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400E, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_oxsemi_4_4000000 }, + { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800E, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_oxsemi_8_4000000 }, + { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EI, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_oxsemi_2_4000000 }, + { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EISI, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_oxsemi_2_4000000 }, { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, -- cgit v1.2.3 From d7636e0b0769e0f4f437ff33168d723f86e7c080 Mon Sep 17 00:00:00 2001 From: "apatard@mandriva.com" Date: Wed, 19 May 2010 10:44:14 +0200 Subject: staging: Add framebuffer driver for XGI chipsets This driver handles XG20, XG21, XG40, XG42 chipsets from XGI. They're also known as Z7,Z9,Z11 chipsets. It's based on the SiS fb driver but has been heavily modified by XGI to support their newer chipsets. Signed-off-by: Arnaud Patard Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/xgifb/Kconfig | 11 + drivers/staging/xgifb/Makefile | 4 + drivers/staging/xgifb/TODO | 15 + drivers/staging/xgifb/XGI.h | 10 + drivers/staging/xgifb/XGI_accel.c | 596 ++ drivers/staging/xgifb/XGI_accel.h | 511 ++ drivers/staging/xgifb/XGI_main.h | 1023 ++++ drivers/staging/xgifb/XGI_main_26.c | 3773 ++++++++++++ drivers/staging/xgifb/XGIfb.h | 215 + drivers/staging/xgifb/osdef.h | 153 + drivers/staging/xgifb/vb_def.h | 1017 ++++ drivers/staging/xgifb/vb_ext.c | 1370 +++++ drivers/staging/xgifb/vb_ext.h | 32 + drivers/staging/xgifb/vb_init.c | 3444 +++++++++++ drivers/staging/xgifb/vb_init.h | 7 + drivers/staging/xgifb/vb_setmode.c | 10736 ++++++++++++++++++++++++++++++++++ drivers/staging/xgifb/vb_setmode.h | 40 + drivers/staging/xgifb/vb_struct.h | 534 ++ drivers/staging/xgifb/vb_table.h | 4406 ++++++++++++++ drivers/staging/xgifb/vb_util.c | 263 + drivers/staging/xgifb/vb_util.h | 15 + drivers/staging/xgifb/vgatypes.h | 325 + 24 files changed, 28503 insertions(+) create mode 100644 drivers/staging/xgifb/Kconfig create mode 100644 drivers/staging/xgifb/Makefile create mode 100644 drivers/staging/xgifb/TODO create mode 100644 drivers/staging/xgifb/XGI.h create mode 100644 drivers/staging/xgifb/XGI_accel.c create mode 100644 drivers/staging/xgifb/XGI_accel.h create mode 100644 drivers/staging/xgifb/XGI_main.h create mode 100644 drivers/staging/xgifb/XGI_main_26.c create mode 100644 drivers/staging/xgifb/XGIfb.h create mode 100644 drivers/staging/xgifb/osdef.h create mode 100644 drivers/staging/xgifb/vb_def.h create mode 100644 drivers/staging/xgifb/vb_ext.c create mode 100644 drivers/staging/xgifb/vb_ext.h create mode 100644 drivers/staging/xgifb/vb_init.c create mode 100644 drivers/staging/xgifb/vb_init.h create mode 100644 drivers/staging/xgifb/vb_setmode.c create mode 100644 drivers/staging/xgifb/vb_setmode.h create mode 100644 drivers/staging/xgifb/vb_struct.h create mode 100644 drivers/staging/xgifb/vb_table.h create mode 100644 drivers/staging/xgifb/vb_util.c create mode 100644 drivers/staging/xgifb/vb_util.h create mode 100644 drivers/staging/xgifb/vgatypes.h (limited to 'drivers') diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index b5c3b3013037..2a1a7c296429 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -141,5 +141,7 @@ source "drivers/staging/ti-st/Kconfig" source "drivers/staging/adis16255/Kconfig" +source "drivers/staging/xgifb/Kconfig" + endif # !STAGING_EXCLUDE_BUILD endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index e330dd5e843d..4a02c0df9ced 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -51,3 +51,4 @@ obj-$(CONFIG_CRYSTALHD) += crystalhd/ obj-$(CONFIG_CXT1E1) += cxt1e1/ obj-$(CONFIG_TI_ST) += ti-st/ obj-$(CONFIG_ADIS16255) += adis16255/ +obj-$(CONFIG_FB_XGI) += xgifb/ diff --git a/drivers/staging/xgifb/Kconfig b/drivers/staging/xgifb/Kconfig new file mode 100644 index 000000000000..bb0ca5974ea0 --- /dev/null +++ b/drivers/staging/xgifb/Kconfig @@ -0,0 +1,11 @@ +config FB_XGI + tristate "XGI display support" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This driver supports notebooks with XGI Z7,Z9,Z11 PCI chips. + Say Y if you have such a graphics card. + To compile this driver as a module, choose M here: the + module will be called xgifb.ko diff --git a/drivers/staging/xgifb/Makefile b/drivers/staging/xgifb/Makefile new file mode 100644 index 000000000000..2a317707de0f --- /dev/null +++ b/drivers/staging/xgifb/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_FB_XGI) += xgifb.o + +xgifb-objs := XGI_main_26.o XGI_accel.o vb_init.o vb_setmode.o vb_util.o vb_ext.o + diff --git a/drivers/staging/xgifb/TODO b/drivers/staging/xgifb/TODO new file mode 100644 index 000000000000..7d71019b84c2 --- /dev/null +++ b/drivers/staging/xgifb/TODO @@ -0,0 +1,15 @@ +This drivers still need a lot of work. I can list all cleanups to do but it's +going to be long. So, I'm writing "cleanups" and not the list. + +Arnaud + +TODO: +- clean ups +- fix build warnings when module +- sort out dup ids with SiS driver +- remove useless/wrong/unused #ifdef/code/... +- fix printk usages +- get rid of non-linux related stuff + +Please send patches to: +Arnaud Patard diff --git a/drivers/staging/xgifb/XGI.h b/drivers/staging/xgifb/XGI.h new file mode 100644 index 000000000000..87803dd032de --- /dev/null +++ b/drivers/staging/xgifb/XGI.h @@ -0,0 +1,10 @@ +#ifndef _XGI_H +#define _XGI_H + +#if 1 +#define TWDEBUG(x) +#else +#define TWDEBUG(x) printk(KERN_INFO x "\n"); +#endif + +#endif diff --git a/drivers/staging/xgifb/XGI_accel.c b/drivers/staging/xgifb/XGI_accel.c new file mode 100644 index 000000000000..86ec3421942f --- /dev/null +++ b/drivers/staging/xgifb/XGI_accel.c @@ -0,0 +1,596 @@ +/* + * XGI 300/630/730/540/315/550/650/740 frame buffer driver + * for Linux kernels 2.4.x and 2.5.x + * + * 2D acceleration part + * + * Based on the X driver's XGI300_accel.c which is + * Copyright Xavier Ducoin + * Copyright 2002 by Thomas Winischhofer, Vienna, Austria + * and XGI310_accel.c which is + * Copyright 2002 by Thomas Winischhofer, Vienna, Austria + * + * Author: Thomas Winischhofer + * (see http://www.winischhofer.net/ + * for more information and updates) + */ + +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +/* +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#include +#else +#include